diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..85605b183 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,14 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto whitespace=trailing-space + +# Explicitly declare text files you want to always be normalized and converted +# to native line endings on checkout. +*.c text +*.h text +*.java text + +# Denote all files that are truly binary and should not be modified. +*.png binary +*.jpg binary +*.ihex binary +*.s37 binary diff --git a/.gitignore b/.gitignore index 2f8a3d89e..00a6e84e9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.png *.log *.elf +*.zip *.d *.ihex *.pyc @@ -24,9 +25,15 @@ *.c128 *.c64 *.cc2538dk +*.zoul +*.jn516x +*.srf06-cc26xx +*.ev-aducrf101mkxz *.report summary *.summary +*.runerr +*.runlog *.faillog *.orig *~ @@ -35,7 +42,9 @@ obj_* symbols.* Makefile.target doc/html +doc/latex patches-* +tools/tunslip tools/tunslip6 build tools/coffee-manager/build/ @@ -52,7 +61,6 @@ tools/cooja/apps/avrora/lib/cooja_avrora.jar tools/cooja/apps/collect-view/cooja-collect-view.jar # sdcc build artifacts -contiki-sensinode.lib contiki-cc2530dk.lib *.ihx *.hex @@ -61,7 +69,6 @@ contiki-cc2530dk.lib *.omf *.cdb *.banks -*.sensinode *.cc2530dk # VC++ build artifacts @@ -73,18 +80,52 @@ contiki-cc2530dk.lib *.dsc #cc65 build artifacts -*.S +*.s *.eth *.dsk -*.2mg +*.po *.atr *.d64 *.d71 *.d81 +# Cooja Build Artifacts +*.cooja + #regression tests artifacts *.testlog +*.log.prog +regression-tests/[0-9][0-9]-*/report +regression-tests/[0-9][0-9]-*/org/ # rl78 build artifacts *.eval-adf7xxxmb4z *.eval-adf7xxxmb4z.srec + +# cscope files +cscope.* + +# vim swap files +*.swp +*.swo + +# x86 UEFI files +cpu/x86/uefi/Makefile.uefi +cpu/x86/uefi/edk2 + +# galileo bsp files +platform/galileo/bsp/libc/Makefile.libc +platform/galileo/bsp/libc/i586-elf/ +platform/galileo/bsp/libc/newlib-2.2.0-1* +platform/galileo/bsp/grub/src/ +platform/galileo/bsp/grub/bin/ + +# galileo build and debug artefacts +*.galileo +*.galileo.dll +*.galileo.efi +LOG_OPENOCD + +# nRF52 build artifacts +*.jlink +*.nrf52dk diff --git a/.gitmodules b/.gitmodules index 7391a785b..eecb69722 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,13 @@ [submodule "tools/cc2538-bsl"] path = tools/cc2538-bsl url = https://github.com/JelmerT/cc2538-bsl.git +[submodule "cpu/cc26xx-cc13xx/lib/cc26xxware"] + path = cpu/cc26xx-cc13xx/lib/cc26xxware + url = https://github.com/g-oikonomou/cc26xxware.git +[submodule "cpu/cc26xx-cc13xx/lib/cc13xxware"] + path = cpu/cc26xx-c../.gitmodulesc13xx/lib/cc13xxware + url = https://github.com/g-oikonomou/cc13xxware.git +[submodule "platform/stm32nucleo-spirit1/stm32cube-lib"] + path = platform/stm32nucleo-spirit1/stm32cube-lib + url = https://github.com/STclab/stm32nucleo-spirit1-lib + diff --git a/.travis.yml b/.travis.yml index 003ccedb8..1a76347bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,42 +2,115 @@ notifications: email: false language: c #NOTE: this will set CC=gcc which might cause trouble before_script: - - "sudo apt-get -qq update" - ## Install these mainline toolchains for all build types - - "sudo apt-get -qq install lib32z1 || true" - - "curl -s \ - http://adamdunkels.github.io/contiki-fork/mspgcc-4.7.0-compiled.tar.bz2 \ - | tar xjf - -C /tmp/ && sudo cp -f -r /tmp/msp430/* /usr/local/ && rm -rf /tmp/msp430 && msp430-gcc --version || true" - - "sudo apt-get -qq install gcc-avr avr-libc || true" - - "sudo apt-get -qq install libc6:i386 libgcc1:i386 gcc-4.6-base:i386 libstdc++5:i386 libstdc++6:i386 || true" + - WGET="travis_retry wget --continue --tries=20 --waitretry=10 --retry-connrefused --no-dns-cache --timeout 300" + - sudo apt-get -qq update - ## Install toolchain for mc1233x, cc2538 and mbxxx in care-free way - - "[ ${BUILD_ARCH:-0} = arm ] && curl -s \ - https://raw.github.com/wiki/malvira/libmc1322x/files/arm-2008q3-66-arm-none-eabi-i686-pc-linux-gnu.tar.bz2 \ - | tar xjf - -C /tmp/ && sudo cp -f -r /tmp/arm-2008q3/* /usr/ && rm -rf /tmp/arm-2008q3 && arm-none-eabi-gcc --version || true" + ## Support building a binary that is identical to the CI + - echo -n "Contiki will be compiled with RELSTR=" ; git --git-dir .git describe --tags --always - ## Install RL78 GCC chain (following the instructions in platform/eval-adf7xxxmb4z/README.md) - - "sudo apt-get install git make gcc libc-dev multiarch-support libncurses5:i386 zlib1g:i386" - - "wget https://dl.dropboxusercontent.com/u/60522916/gnurl78-v13.02-elf_1-2_i386.deb" - - "sudo dpkg -i gnurl78*.deb" + ## Install doxygen + - if [ ${BUILD_CATEGORY:-0} = doxygen ] ; then + sudo add-apt-repository ppa:libreoffice/libreoffice-4-4 -y && sudo apt-get -qq update && + sudo apt-get --no-install-suggests --no-install-recommends -qq install doxygen && + doxygen --version ; + fi + + ## Install msp430 toolchain + - sudo apt-get -qq install lib32z1 + - $WGET http://simonduq.github.io/resources/mspgcc-4.7.2-compiled.tar.bz2 && + tar xjf mspgcc*.tar.bz2 -C /tmp/ && + sudo cp -f -r /tmp/msp430/* /usr/local/ && + rm -rf /tmp/msp430 mspgcc*.tar.bz2 && + msp430-gcc --version + + ## Install avr toolchain + - $WGET http://atiselsts.github.io/resources/avr-gcc-4.9.2-compiled.tar.bz2 && + tar xjf avr-gcc*.tar.bz2 -C /tmp/ && + sudo cp -f -r /tmp/avr-gcc/* /usr/local/ && + rm -rf /tmp/avr-gcc avr-gcc*.tar.bz2 && + avr-gcc --version + + ## Install 32-bit compatibility libraries + - sudo apt-get -qq install libc6:i386 libgcc1:i386 gcc-4.6-base:i386 + libstdc++5:i386 libstdc++6:i386 + + ## Install old APCS ARM toolchain for mc1233x and mbxxx + - if [ ${BUILD_ARCH:-0} = arm-apcs ] ; then + $WGET https://raw.githubusercontent.com/wiki/malvira/libmc1322x/files/arm-2008q3-66-arm-none-eabi-i686-pc-linux-gnu.tar.bz2 && + tar xjf arm-2008q3*.tar.bz2 -C /tmp/ && + sudo cp -f -r /tmp/arm-2008q3/* /usr/ && + rm -rf /tmp/arm-2008q3 arm-2008q3*.tar.bz2 && + sudo apt-get -qq install libconfig-dev uuid-dev libqrencode-dev && + arm-none-eabi-gcc --version ; + fi + + ## Install mainline ARM toolchain and srecord. + - if [ ${BUILD_ARCH:-0} = arm-aapcs ] ; then + sudo apt-get -qq install srecord && + $WGET https://launchpad.net/gcc-arm-embedded/5.0/5-2015-q4-major/+download/gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2 && + tar xjf gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2 -C /tmp/ && + sudo cp -f -r /tmp/gcc-arm-none-eabi-5_2-2015q4/* /usr/local/ && + rm -rf /tmp/gcc-arm-none-eabi-* gcc-arm-none-eabi-*-linux.tar.bz2 && + arm-none-eabi-gcc --version ; + fi + + ## Install RL78 GCC toolchain + - sudo apt-get install libncurses5:i386 zlib1g:i386 + - $WGET http://adamdunkels.github.io/contiki-fork/gnurl78-v13.02-elf_1-2_i386.deb && + sudo dpkg -i gnurl78*.deb ## Install SDCC from a purpose-built bundle - - "[ ${BUILD_ARCH:-0} = 8051 ] && curl -s \ - https://raw.github.com/wiki/g-oikonomou/contiki-sensinode/files/sdcc.tar.gz \ - | tar xzf - -C /tmp/ && sudo cp -f -r /tmp/sdcc/* /usr/local/ && rm -rf /tmp/sdcc && sdcc --version || true" - - "[ ${BUILD_ARCH:-0} = 8051 ] && sudo apt-get -qq install srecord || true" + - if [ ${BUILD_ARCH:-0} = 8051 ] ; then + $WGET https://raw.githubusercontent.com/wiki/g-oikonomou/contiki-sensinode/files/sdcc.tar.gz && + tar xzf sdcc.tar.gz -C /tmp/ && + sudo cp -f -r /tmp/sdcc/* /usr/local/ && + rm -rf /tmp/sdcc sdcc.tar.gz && + sdcc --version && + sudo apt-get -qq install srecord ; + fi ## Clone and build cc65 when testing 6502 ports - - "[ ${BUILD_ARCH:-0} = 6502 ] && git clone \ - https://github.com/cc65/cc65 /tmp/cc65 && \ - make -C /tmp/cc65 bin apple2enh atarixl c64 c128 && sudo make -C /tmp/cc65 avail && \ - export CC65_HOME=/tmp/cc65/ && cc65 --version || true" + - if [ ${BUILD_ARCH:-0} = 6502 ] ; then + git clone https://github.com/cc65/cc65 /tmp/cc65 && + make -C /tmp/cc65 bin apple2enh atarixl c64 c128 && + sudo make -C /tmp/cc65 avail && + cc65 --version ; + fi + + ## Install NXP toolchain + - if [ ${BUILD_ARCH:-0} = jn516x ] ; then + $WGET http://simonduq.github.io/resources/ba-elf-gcc-4.7.4-part1.tar.bz2 && + $WGET http://simonduq.github.io/resources/ba-elf-gcc-4.7.4-part2.tar.bz2 && + $WGET http://simonduq.github.io/resources/jn516x-sdk-4163.tar.bz2 && + mkdir /tmp/jn516x-sdk /tmp/ba-elf-gcc && + tar xjf jn516x-sdk-*.tar.bz2 -C /tmp/jn516x-sdk && + tar xjf ba-elf-gcc-*part1.tar.bz2 -C /tmp/ba-elf-gcc && + tar xjf ba-elf-gcc-*part2.tar.bz2 -C /tmp/ba-elf-gcc && + sudo cp -f -r /tmp/jn516x-sdk /usr/ && + sudo cp -f -r /tmp/ba-elf-gcc /usr/ && + export PATH=/usr/ba-elf-gcc/bin:$PATH && + rm -rf /tmp/ba-elf-gcc* /tmp/jn516x-sdk* && + ba-elf-gcc --version ; + fi + + ## Install mainline ARM toolchain and download nRF52 SDK + - if [ ${BUILD_ARCH:-0} = nrf52dk ] ; then + sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa && + sudo apt-get -qq update && + sudo apt-get -qq install gcc-arm-embedded srecord && + arm-none-eabi-gcc --version && + $WGET https://developer.nordicsemi.com/nRF5_IoT_SDK/nRF5_IoT_SDK_v0.9.x/nrf5_iot_sdk_3288530.zip && + mkdir /tmp/nrf52-sdk && + unzip nrf5_iot_sdk_3288530.zip -d /tmp/nrf52-sdk && + export NRF52_SDK_ROOT=/tmp/nrf52-sdk ; + fi ## Compile cooja.jar only when it's going to be needed - - "[ ${BUILD_CATEGORY:-sim} = sim ] && java -version && ant -q -f tools/cooja/build.xml jar && sudo java -Xshare:dump -version || true" - - ## IMPORTANT: The commands here have to end with `|| true`, - ## because it would make the test fail if BUILD_TYPE test fails + - if [ ${BUILD_CATEGORY:-sim} = sim ] ; then + java -version && + ant -q -f tools/cooja/build.xml jar && + sudo java -Xshare:dump -version ; + fi script: ## regression-tests/Makefile handles most of generic logic @@ -46,9 +119,9 @@ script: after_script: ## Print cooja test logs - "[ ${BUILD_CATEGORY:-sim} = sim ] && tail regression-tests/??-$BUILD_TYPE/*.testlog" - ## Print a basic summary + ## Print a basic summary - "echo 'Summary:'; cat regression-tests/??-$BUILD_TYPE/summary" - - "FAILS=`grep -c -i 'fail' regression-tests/??-$BUILD_TYPE/summary`" + - "FAILS=`grep -c ' FAIL ' regression-tests/??-$BUILD_TYPE/summary`" ## This will detect whether the build should pass or fail - "test $FAILS -eq 0; exit $?" @@ -56,12 +129,17 @@ after_script: env: ## This magically kick-off parallel jobs for each of the for the sets ## of environment variable defined below + - BUILD_TYPE='doxygen' BUILD_CATEGORY='doxygen' - BUILD_TYPE='compile-base' BUILD_CATEGORY='compile' + - BUILD_TYPE='compile-tools' BUILD_CATEGORY='compile' - BUILD_TYPE='collect' - BUILD_TYPE='collect-lossy' - BUILD_TYPE='rpl' + - BUILD_TYPE='rpl-non-storing' + - BUILD_TYPE='large-rpl' - BUILD_TYPE='rime' - BUILD_TYPE='ipv6' + - BUILD_TYPE='ip64' MAKE_TARGETS='cooja' - BUILD_TYPE='hello-world' - BUILD_TYPE='base' # XXX: netperf disabled b/c it's flaky @@ -72,6 +150,11 @@ env: # - BUILD_TYPE='ipv4' - BUILD_TYPE='ipv6-apps' - BUILD_TYPE='compile-8051-ports' BUILD_CATEGORY='compile' BUILD_ARCH='8051' - - BUILD_TYPE='compile-arm-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm' + - BUILD_TYPE='compile-arm-apcs-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm-apcs' - BUILD_TYPE='compile-6502-ports' BUILD_CATEGORY='compile' BUILD_ARCH='6502' + - BUILD_TYPE='compile-arm-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm-aapcs' + - BUILD_TYPE='compile-nxp-ports' BUILD_CATEGORY='compile' BUILD_ARCH='jn516x' + - BUILD_TYPE='compile-nrf52-ports' BUILD_CATEGORY='compile' BUILD_ARCH='nrf52dk' - BUILD_TYPE='slip-radio' MAKE_TARGETS='cooja' + - BUILD_TYPE='llsec' MAKE_TARGETS='cooja' + - BUILD_TYPE='compile-avr' BUILD_CATEGORY='compile' BUILD_ARCH='avr-rss2' diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..8ed3d23a6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,278 @@ +Code Contributions +================== + +Do you have a new cool feature that you'd like to contribute to +Contiki? Or a fix for a bug? Great! The Contiki project loves code +contributions, improvements, and bugfixes, but we require that they +follow a set of guidelines and that they are contributed in a specific +way. + +Additional rules apply for contributions of a new hardware platform. + +General Advice +-------------- + +The chance of getting your pull request accepted increases considerably +if you adhere to the following rules in addition to the aforementioned +formatting and naming standards: + +* Ensure that all contributed files have a valid copyright statement + and an open-source license. +* Do not bundle commits that are unrelated to each other -- create + separate pull requests instead. +* Adhere to ISO C99 in all C language source files. Exceptions are + allowed for those platform-dependent source files that rely on the + extensions of a specific set of compilers. +* Clean up the commit history. "git rebase -i" is useful for this purpose. +* Do not include executable binary files, because they are usually + rejected for security reasons. Instead, provide instructions for how + to compile the file, so that a trusted member of the merge team can + commit it. +* Write a descriptive pull request message. Explain the advantages and + disadvantages of your proposed changes. +* Before starting to work on a major contribution, discuss your idea + with experienced Contiki programmers (e.g., on the contiki-developers + mailing list) to avoid wasting time on things that have no chance of + getting merged into Contiki. + +Source code that goes into the mainline Contiki repository must be of +interest to a large part of the Contiki community. It must be +well-tested and the merge team must have confidence that the code can +be maintained over a longer period. See below for more details +pertaining to platform contributions. + +Contributions that have been made in research projects, and typically +do not get maintained thereafter, are better suited for inclusion in +the Contiki projects repository. + +Structuring Commits +------------------- + +* Write descriptive commit messages. They don't have to be very long, + but you should mention what the commit achieves. Commit messages + like "modified foo/bar.c" are not helpful, should not be used, and + are likely to result in you having to re-write them. +* Please do not add / remove irrelevant new line markers. Don't remove + the new line marker at the EOF. +* Please, make sure that your patch doesn't add lines with trailing + whitespaces. If you run uncrustify as discussed above, this should + get taken care of for you automatically. +* More generally speaking, make sure that each commit in your history + only includes changes necessary to implement whatever it is the + commit is trying to achieve. All changes should be mentioned in the + commit message. + +Code Formatting +--------------- + +We require that all code contributed to the Contiki tree follows the +same code formatting as the existing Contiki code. We are very strict +on this. + +Code must be formatted according to +[contiki/doc/code-style.c](https://github.com/contiki-os/contiki/blob/master/doc/code-style.c). + +The Contiki source tree contains scripts to assist with correct code formatting +and we recommend [Uncrustify](http://uncrustify.sourceforge.net/) as the +preferred auto formatter. Everything is under +[tools/code-style](https://github.com/contiki-os/contiki/tree/master/tools/code-style). + +If you wish, you can format all changed resources in your working tree +automatically if the +[tools/code-style/uncrustify-changed.sh](https://github.com/contiki-os/contiki/blob/master/tools/code-style/uncrustify-changed.sh) +script is added as a [Git pre-commit +hook](http://git-scm.com/book/en/Customizing-Git-Git-Hooks) to your Git +configuration. + +Here are some examples of what you can do: +* To check a file's style without changing the file on disk, you can run this: +`./tools/code-style/uncrustify-check-style.sh ` +This script will only accept a single file as its argument. + +* To auto format a file (and change it on disk) you can run this: +`./tools/code-style/uncrustify-fix-style.sh ` + +* `uncrustify-fix-style.sh` will accept a space-delimited list of files as its argument. Thus, you can auto-format an entire directory by running something like this: +``./tools/code-style/uncrustify-fix-style.sh `find cpu/cc2538 -type f -name "*.[ch]"` `` + +This is _not_ a silver bullet and developer intervention is still required. Below are some examples of code which will get misformatted by uncrustify: +* Math symbol following a cast to a typedef +``` + a = (uint8_t) ~P0_1; /* Cast to a typedef. Space gets added here (incorrect) */ + a = (int)~P0_1; /* Cast to a known type. Space gets removed (correct) */ + a = (uint8_t)P0_1; /* Variable directly after the cast. Space gets removed (correct) */ +``` + +* `while();` will become `while() ;` (space incorrectly added after closing paren) + +* `asm("wfi");` becomes `asm ("wfi");`: A space gets added before the opening paren, because the `asm` keyword stops this from getting interpreted as a normal function call / macro invocation. This is only a problem with `asm`. For instance, `foo("bar");` gets formatted correctly. + +Naming +------ + +We require that all code contributed to the Contiki tree follow the +Contiki source code naming standard: + +* File names are composed of lower-case characters and dashes. Like + this: simple-udp.c +* Variable and function names are composed of lower-case characters + and underscores. Like this: simple_udp_send(); +* Variable and function names that are visible outside of their module + must begin with the name of the module. Like this: + simple_udp_send(), which is in the simple-udp module, declared in + simple-udp.h, and implemented in simple-udp.c. +* C macros are composed of upper-case characters and underscores. Like + this: PROCESS_THREAD(). +* Configuration definitions begin with the module name and CONF_. Like + this: PROCESS_CONF_NUMEVENTS. + +How to Contribute Code +---------------------- + +When your code is formatted according to the Contiki code style and +follows the Contiki naming standard, it is time to send it to the +Contiki maintainers to look at! + +All code contributions to Contiki are submitted as [Github pull +requests](https://help.github.com/articles/using-pull-requests). Pull +requests will be reviewed and accepted according to the guidelines +found in the next section. + +The basic guidelines to to start a Pull-Request: +* Create a new branch for your modifications. This branch should be based on the latest contiki master branch. +* If you already added the commits to another branch you can [cherry-pick](http://git-scm.com/docs/git-cherry-pick) them onto your new branch. +* Push the new branch to github. +* Raise the new Pull Requests on this new branch. Raising a Pull Request for the master branch is almost always a bad idea. +* If changes are requested do not close the pull request but rewrite your history. [Details about rewriting your history](http://git-scm.com/book/en/Git-Tools-Rewriting-History) +* You now force-push the changes to github. The pull-request is automatically updated. + +In Git terminology this is equivalent to: +* Make sure you have the original contiki repo as origin. +```bash +$ git remote -v +contiki-orig https://github.com/contiki-os/contiki.git +``` +* If not add it +```bash +$ git remote add contiki-orig https://github.com/contiki-os/contiki.git +``` +* Make sure you have the latest version of your remotes +```bash +$ git remote update +``` +* Create a new branch "my_new_feature" based on the latest contiki master branch +```bash +$ git checkout contiki-orig/master -b my_new_feature +``` +* Add your work. For example by cherry-picking your changes from another branch. +```bash +$ git cherry-pick +``` +* Push to _your_ github repository +```bash +$ git push origin my_new_feature +``` +* Make a Pull Request for that branch +* Rewrite your history if requested +```bash +$ git rebase -i contiki-orig/master +``` +* As rewriting your history can break things you must force-push the changes. **Warning**: Force-pushing normally is dangerous and you might break things. Make sure you are never force-pushing branches other people are supposed to work with. +```bash +$ git push origin my_new_feature -f +``` +* NOTE: To avoid all the pain of selectively picking commits, rebasing and force-pushing - begin your development with a branch OTHER THAN your master branch, and push changes to that branch after any local commits. + +Pull Request Merging Policy +--------------------------- + +Pull requests (PRs) are reviewed by the [merge team](https://github.com/orgs/contiki-os/people). +Generally, PRs require two "+1" before they can be merged by someone on the merge team. +The since Contiki 3.0, the merging policy is the following: +* The PR receives **one "-1"** from a merge team member (along with specific feedback). The PR is closed. A "-1" must be accompanied with a clear explanation why the PR will not be considered for inclusion. +* The PR receives **two "+1"** from merge team members. The PR is merged. +* The PR was inactive for **two months**. A team member may either: + * Comment "Is there any interest for this PR? Is there any work pending on it? If not I will close it in **one month**." Back to initial state in case of activity, close otherwise. + * Comment "I approve this PR. If nobody disapproves within **one month**, I will merge it." Back to initial state in case of activity, merge otherwise. + +There is an exception to the rule. +Code that requires esoteric expertise such as some applications, platforms or tools can be merged after a single "+1" from its domain expert. + +Travis / Regression testing +--------------------------- + +[Travis](https://travis-ci.org/) is a service that runs regression +tests. If you make a pull-request for Contiki this is automatically +forwarded to Travis and regression tests are run. A box with +information about the state of you pull request should show up after a +minute or two. + +If the test fails it is likely that something is wrong with your +code. Please look carefully at the log. It might also be that some +package on the testing VM was updated and causes the build to fail. If +you are sure that is is not your code causing the tests to fail start +a new issue describing the problem. Also note this in your pull +request. + +You can also register at [Travis](https://travis-ci.org/) for +free. Once you activated your Contiki repository, every push will be +tested at Travis. The configuration is part of the contiki repository +and testing will therefore work out-of-the-box. At Travis you then get +an overview of the state of each of your branches. + +New Platforms +------------- +A new hardware port will be considered for inclusion in mainline Contiki +if it satisfies the following rules: + +* There must be at least one person willing and committed to maintain it. +They may but do not have to be the people who wrote the code. Similarly, +they may but do not have to be affiliated with the hardware manufacturer. +In the first instance, code maintenance would mean keeping the port up to +speed by submitting pull requests as Contiki moves forward. In the longer +term, people who maintain a reasonable level of commitment and who demonstrate +that they know what they're doing may be invited to become repo collaborators. +* The hardware must be commercially available and of interest to a wide audience. +In other words, ports for bespoke hardware built for e.g. a specific project / +a single customer / niche markets are more suitable for a Contiki fork. +* The code must strictly adhere to the Contiki code style, as discussed above. +* The new files must have a clear copyright notice and license header. Contiki's +preferred software license is the +[3-clause BSD](http://opensource.org/licenses/BSD-3-Clause). +Other licenses may also be considered +as long as they are compatible with the 3-clause BSD (e.g. the Apache 2.0 license). +Conversely, code distributed under GPL cannot be considered. The same applies to +bespoke licenses, such as those allowing use or redistribution only together with +certain kinds of hardware. +* The port must demonstrate a certain degree of completeness and maturity. Common sense +applies here. +* The port must be accompanied by examples demonstrating basic functionality. This could +be a set of examples under `examples/` and/or documentation of +which existing examples are meant to work. +* The port must provide compile regression tests by extending the existing travis +integration testing framework. Again, we can't specify explicitly +what those tests should be, but something more interesting than hello-world is expected. +* The work must be documented. The documentation could be README.md files +under the platform / cpu / example dirs or wiki pages. Doxygen comments are +also encouraged. The documentation should include: + * A getting started guide, including a list of tools required to use the platform +(e.g. toolchain, software to program the device), where to get them from and brief notes +how to install them (can simply be a list of links to external guides) + * A list of things which will work off the shelf + * A list of things which are not meant to work, if any + * Additional reading resources (e.g. datasheets, hardware user guides, web resources) + * A ToDo list, if applicable. +* It must be possible to use the port using free software. We do not discourage the +use of commercial software (e.g. support for a commercial toolchain), quite the opposite. +However, we will insist on the existence of a free alternative for everything. + +After the port has been accepted, things meant to work off the shelf should +keep working off the shelf as Contiki moves forward. + +We appreciate that, for many people, contributing to Contiki is a spare time +activity and our expectations from port maintainers take this into +consideration. All we ask from maintainers is to comment on and address +relevant pull requests at a reasonable frequency and to make sure travis keeps +passing. In other words, we just want platforms to stay healthy over time and +to thus avoid becoming very broken / obsolete. + diff --git a/Makefile.include b/Makefile.include index ad20b23bd..f55427cf9 100644 --- a/Makefile.include +++ b/Makefile.include @@ -14,10 +14,6 @@ ifeq ($(TARGET),) endif endif -ifeq ($(UIP_CONF_IPV6),1) - CFLAGS += -DUIP_CONF_IPV6=1 -endif - ifeq ($(DEFINES),) -include Makefile.$(TARGET).defines ifneq ($(DEFINES),) @@ -35,6 +31,13 @@ ifndef HOST_OS endif endif +#More debug information when running in CI +ifdef CI + ifeq ($(CI),true) + V = 1 + endif +endif + usage: @echo "make MAKETARGETS... [TARGET=(TARGET)] [savetarget] [targets]" @@ -60,9 +63,46 @@ CFLAGS += -DCONTIKI=1 -DCONTIKI_TARGET_$(TARGET_UPPERCASE)=1 MODULES += core/sys core/dev core/lib +# Include IPv6, IPv4, and/or Rime + +HAS_STACK = 0 +ifeq ($(CONTIKI_WITH_IPV4),1) + HAS_STACK = 1 + CFLAGS += -DNETSTACK_CONF_WITH_IPV4=1 + MODULES += core/net/ipv4 core/net/ip +endif + +ifeq ($(CONTIKI_WITH_RIME),1) + HAS_STACK = 1 + CFLAGS += -DNETSTACK_CONF_WITH_RIME=1 + MODULES += core/net/rime +endif + +# Make IPv6 the default stack +ifeq ($(HAS_STACK),0) +ifneq ($(CONTIKI_WITH_IPV6),0) +CONTIKI_WITH_IPV6 = 1 +endif +endif + +ifeq ($(CONTIKI_WITH_IPV6),1) + CFLAGS += -DNETSTACK_CONF_WITH_IPV6=1 + ifneq ($(CONTIKI_WITH_RPL),0) + CONTIKI_WITH_RPL = 1 + endif + MODULES += core/net/ipv6 core/net/ip +endif + +ifeq ($(CONTIKI_WITH_RPL),1) + CFLAGS += -DUIP_CONF_IPV6_RPL=1 + MODULES += core/net/rpl +else + CFLAGS += -DUIP_CONF_IPV6_RPL=0 +endif + CONTIKI_SOURCEFILES += $(CONTIKIFILES) -CONTIKIDIRS += ${addprefix $(CONTIKI)/core/,dev lib net net/mac net/rime \ +CONTIKIDIRS += ${addprefix $(CONTIKI)/core/,dev lib net net/llsec net/mac net/rime \ net/rpl sys cfs ctk lib/ctk loader . } oname = ${patsubst %.cpp,%.o,${patsubst %.c,%.o,${patsubst %.S,%.o,$(1)}}} @@ -107,7 +147,6 @@ endif ifdef MODULES UNIQUEMODULES = $(call uniq,$(MODULES)) - MODULESSUBST = ${subst /,-,$(UNIQUEMODULES)} MODULEDIRS = ${wildcard ${addprefix $(CONTIKI)/, $(UNIQUEMODULES)}} MODULES_SOURCES = ${foreach d, $(MODULEDIRS), ${subst ${d}/,,${wildcard $(d)/*.c}}} CONTIKI_SOURCEFILES += $(MODULES_SOURCES) @@ -145,7 +184,7 @@ CONTIKI_CPU_DIRS_CONCAT = ${addprefix $(CONTIKI_CPU)/, \ $(CONTIKI_CPU_DIRS)} SOURCEDIRS = . $(PROJECTDIRS) $(CONTIKI_TARGET_DIRS_CONCAT) \ - $(CONTIKI_CPU_DIRS_CONCAT) $(CONTIKIDIRS) $(APPDS) ${dir $(target_makefile)} + $(CONTIKI_CPU_DIRS_CONCAT) $(CONTIKIDIRS) $(APPDS) $(EXTERNALDIRS) ${dir $(target_makefile)} vpath %.c $(SOURCEDIRS) vpath %.cpp $(SOURCEDIRS) @@ -155,8 +194,10 @@ CFLAGS += ${addprefix -I,$(SOURCEDIRS) $(CONTIKI)} ### Check for a git repo and pass version if found ### git.exe in Windows cmd shells may require no stderr redirection -#RELSTR=${shell git describe --tags} -RELSTR=${shell git --git-dir ${CONTIKI}/.git describe --tags 2>/dev/null} +ifndef RELSTR +RELSTR:=${shell git --git-dir ${CONTIKI}/.git describe --tags --always} +endif + ifneq ($(RELSTR),) CFLAGS += -DCONTIKI_VERSION_STRING=\"Contiki-$(RELSTR)\" endif @@ -186,7 +227,7 @@ clean: -rm -rf $(OBJECTDIR) distclean: clean - -rm -rf $(CONTIKI_PROJECT).$(TARGET) + -rm -f ${addsuffix .$(TARGET),$(CONTIKI_PROJECT)} -include $(CONTIKI)/platform/$(TARGET)/Makefile.customrules-$(TARGET) diff --git a/README.md b/README.md index 53ff3f06a..b838212c8 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ The Contiki Operating System ============================ -[![Build Status](https://secure.travis-ci.org/contiki-os/contiki.png)](http://travis-ci.org/contiki-os/contiki) +[![Build Status](https://travis-ci.org/contiki-os/contiki.svg?branch=master)](https://travis-ci.org/contiki-os/contiki/branches) Contiki is an open source operating system that runs on tiny low-power microcontrollers and makes it possible to develop applications that diff --git a/apps/antelope/lvm.c b/apps/antelope/lvm.c index 4d05cc594..731da1622 100644 --- a/apps/antelope/lvm.c +++ b/apps/antelope/lvm.c @@ -586,7 +586,6 @@ derive_relation(lvm_instance_t *p, derivation_t *local_derivations) node_type_t type; operand_t operand[2]; int i; - int var; int variable_id; operand_value_t *value; derivation_t *derivation; @@ -640,11 +639,9 @@ derive_relation(lvm_instance_t *p, derivation_t *local_derivations) if(operand[1].type == LVM_VARIABLE) { return DERIVATION_ERROR; } - var = 0; variable_id = operand[0].value.id; value = &operand[1].value; } else { - var = 1; variable_id = operand[1].value.id; value = &operand[0].value; } diff --git a/apps/arduino/arduino-process.c b/apps/arduino/arduino-process.c index d5d83482a..8cda5a0ae 100644 --- a/apps/arduino/arduino-process.c +++ b/apps/arduino/arduino-process.c @@ -49,24 +49,99 @@ * */ +#include +#include #include "arduino-process.h" #include "hw_timer.h" #include "adc.h" #include "hw-arduino.h" +#include "contiki.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + + +extern volatile uint8_t mcusleepcycle; +#if PLATFORM_HAS_BUTTON +#include "rest-engine.h" +#include "dev/button-sensor.h" +extern resource_t res_event, res_separate; +#endif /* PLATFORM_HAS_BUTTON */ + +volatile uint8_t mcusleepcycleval; + +/*-------------- enabled sleep mode ----------------------------------------*/ +void +mcu_sleep_init(void) +{ + mcusleepcycleval=mcusleepcycle; +} +void +mcu_sleep_on(void) +{ + mcusleepcycle= mcusleepcycleval; +} +/*--------------- disable sleep mode ---------------------------------------*/ +void +mcu_sleep_off(void) +{ + mcusleepcycle=0; +} +/*---------------- set duty cycle value ------------------------------------*/ +void +mcu_sleep_set(uint8_t value) +{ + mcusleepcycleval= value; + mcusleepcycle = mcusleepcycleval; +} PROCESS(arduino_sketch, "Arduino Sketch Wrapper"); +#ifndef LOOP_INTERVAL +#define LOOP_INTERVAL (1 * CLOCK_SECOND) +#endif + PROCESS_THREAD(arduino_sketch, ev, data) { - PROCESS_BEGIN(); + static struct etimer loop_periodic_timer; - arduino_pwm_timer_init (); + PROCESS_BEGIN(); adc_init (); + mcu_sleep_init (); setup (); + /* Define application-specific events here. */ + etimer_set(&loop_periodic_timer, LOOP_INTERVAL); while (1) { - loop (); - /* Give other processes a chance to run */ - PROCESS_PAUSE(); + PROCESS_WAIT_EVENT(); +#if PLATFORM_HAS_BUTTON + if(ev == sensors_event && data == &button_sensor) { + mcu_sleep_off(); + PRINTF("*******BUTTON*******\n"); + + /* Call the event_handler for this application-specific event. */ + res_event.trigger(); + + /* Also call the separate response example handler. */ + res_separate.resume(); + mcu_sleep_on(); + } +#endif /* PLATFORM_HAS_BUTTON */ + + if(etimer_expired(&loop_periodic_timer)) { + mcu_sleep_off(); + loop (); + mcu_sleep_on(); + etimer_reset(&loop_periodic_timer); + } } PROCESS_END(); } diff --git a/apps/arduino/arduino-process.h b/apps/arduino/arduino-process.h index 23b00ede4..bea6708f8 100644 --- a/apps/arduino/arduino-process.h +++ b/apps/arduino/arduino-process.h @@ -51,6 +51,13 @@ #include "contiki.h" +/*--------------- enable sleep mode ---------------------------------------*/ +void mcu_sleep_on(void); +/*--------------- disable sleep mode ---------------------------------------*/ +void mcu_sleep_off(void); +/*---------------- set sleep value ------------------------------------*/ +void mcu_sleep_set(uint8_t value); + extern void loop (void); extern void setup (void); extern void arduino_init (void); diff --git a/apps/at-master/Makefile.at-master b/apps/at-master/Makefile.at-master new file mode 100644 index 000000000..9ab561a16 --- /dev/null +++ b/apps/at-master/Makefile.at-master @@ -0,0 +1 @@ +at-master_src = at-master.c diff --git a/apps/at-master/at-master.c b/apps/at-master/at-master.c new file mode 100644 index 000000000..c9e0597b6 --- /dev/null +++ b/apps/at-master/at-master.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +#include "contiki.h" +#include "contiki-lib.h" +#include "at-master.h" +#include "cpu.h" +#include "dev/uart.h" +#include "dev/serial-line.h" +#include "dev/sys-ctrl.h" +#include "lib/list.h" +#include "sys/cc.h" + +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +LIST(at_cmd_list); +process_event_t at_cmd_received_event; +/*---------------------------------------------------------------------------*/ +static uint8_t at_uart = 0; +/*---------------------------------------------------------------------------*/ +PROCESS(at_process, "AT process"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(at_process, ev, data) +{ + uint8_t plen; + char *pch, *buf; + struct at_cmd *a; + PROCESS_BEGIN(); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(ev == serial_line_event_message && data != NULL); + buf = (char *)data; + plen = strlen(buf); + for(a = list_head(at_cmd_list); a != NULL; a = list_item_next(a)) { + pch = strstr(buf, a->cmd_header); + if((plen <= a->cmd_max_len) && (pch != NULL)) { + if(strncmp(a->cmd_header, pch, a->cmd_hdr_len) == 0) { + if((a->cmd_hdr_len == plen) || (a->cmd_max_len > a->cmd_hdr_len)) { + a->event_callback(a, plen, (char *)pch); + process_post(a->app_process, at_cmd_received_event, NULL); + break; + } + } + } + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +struct at_cmd * +at_list(void) +{ + return list_head(at_cmd_list); +} +/*---------------------------------------------------------------------------*/ +uint8_t +at_send(char *s, uint8_t len) +{ + uint8_t i = 0; + while(s && *s != 0) { + if(i >= len) { + break; + } + uart_write_byte(at_uart, *s++); + i++; + } + return i; +} +/*---------------------------------------------------------------------------*/ +void +at_init(uint8_t uart_sel) +{ + static uint8_t inited = 0; + if(!inited) { + list_init(at_cmd_list); + at_cmd_received_event = process_alloc_event(); + inited = 1; + + at_uart = uart_sel; + uart_init(at_uart); + uart_set_input(at_uart, serial_line_input_byte); + serial_line_init(); + + process_start(&at_process, NULL); + PRINTF("AT: Started (%u)\n", at_uart); + } +} +/*---------------------------------------------------------------------------*/ +at_status_t +at_register(struct at_cmd *cmd, struct process *app_process, + const char *cmd_hdr, const uint8_t hdr_len, + const uint8_t cmd_max_len, at_event_callback_t event_callback) +{ + if((hdr_len < 1) || (cmd_max_len < 1) || (!strncmp(cmd_hdr, "AT", 2) == 0) || + (event_callback == NULL)) { + PRINTF("AT: Invalid argument\n"); + return AT_STATUS_INVALID_ARGS_ERROR; + } + + memset(cmd, 0, sizeof(struct at_cmd)); + cmd->event_callback = event_callback; + cmd->cmd_header = cmd_hdr; + cmd->cmd_hdr_len = hdr_len; + cmd->cmd_max_len = cmd_max_len; + cmd->app_process = app_process; + list_add(at_cmd_list, cmd); + PRINTF("AT: registered HDR %s LEN %u MAX %u\n", cmd->cmd_header, + cmd->cmd_hdr_len, + cmd->cmd_max_len); + return AT_STATUS_OK; +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/at-master/at-master.h b/apps/at-master/at-master.h new file mode 100644 index 000000000..ad625c0dc --- /dev/null +++ b/apps/at-master/at-master.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +#ifndef AT_MASTER_H_ +#define AT_MASTER_H_ +#include "contiki.h" +/*---------------------------------------------------------------------------*/ +#define AT_DEFAULT_RESPONSE_OK "\r\nOK\r\n" +#define AT_DEFAULT_RESPONSE_ERROR "\r\nERROR\r\n" +/*---------------------------------------------------------------------------*/ +#define AT_RESPONSE(x) at_send((x), (strlen(x))) +/*---------------------------------------------------------------------------*/ +extern process_event_t at_cmd_received_event; +struct at_cmd; +/*---------------------------------------------------------------------------*/ +typedef enum { + AT_STATUS_OK, + AT_STATUS_ERROR, + AT_STATUS_INVALID_ARGS_ERROR, +} at_status_t; +/*---------------------------------------------------------------------------*/ +/** + * \brief AT initialization + * \param uart selects which UART to use + * + * The AT driver invokes this function upon registering a command, this will + * wait for the serial_line_event_message event + */ +void at_init(uint8_t uart); +/*---------------------------------------------------------------------------*/ +/** + * \brief AT initialization + * \param uart selects which UART to use + * + * The AT driver invokes this function upon registering a command, this will + * wait for the serial_line_event_message event + */ +uint8_t at_send(char *s, uint8_t len); +/*---------------------------------------------------------------------------*/ +/** + * \brief AT event callback + * \param cmd A pointer to the AT command placeholder + * \param len Lenght of the received data (including the AT command header) + * \param data A user-defined pointer + * + * The AT event callback function gets called whenever there is an + * event on an incoming AT command + */ +typedef void (*at_event_callback_t)(struct at_cmd *cmd, + uint8_t len, + char *data); +/*---------------------------------------------------------------------------*/ +struct at_cmd { + struct at_cmd *next; + const char *cmd_header; + uint8_t cmd_hdr_len; + uint8_t cmd_max_len; + at_event_callback_t event_callback; + struct process *app_process; +}; +/*---------------------------------------------------------------------------*/ +/** + * \brief Registers the callback to return an AT command + * \param cmd A pointer to the CMD placeholder + * \param cmd_hdr String to compare when an AT command is received + * \param cmd_len Lenght of cmd_hdr + * \param event_callback Callback function to handle the AT command + * \return AT_STATUS_OK or AT_STATUS_INVALID_ARGS_ERROR + * + * Register the commands to search for when a valid AT frame has been received + */ +at_status_t at_register(struct at_cmd *cmd, + struct process *app_process, + const char *cmd_hdr, + const uint8_t cmd_hdr_len, + const uint8_t cmd_max_len, + at_event_callback_t event_callback); +/*---------------------------------------------------------------------------*/ +struct at_cmd *at_list(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Registers the callback to return an AT command + * \param cmd A pointer to the CMD placeholder + * \param cmd_hdr String to compare when an AT command is received + * \param cmd_len Lenght of cmd_hdr + * \param event_callback Callback function to handle the AT command + * \return AT_STATUS_OK or AT_STATUS_INVALID_ARGS_ERROR + * + * Register the commands to search for when a valid AT frame has been received + */ +at_status_t at_register(struct at_cmd *cmd, + struct process *app_process, + const char *cmd_hdr, + const uint8_t cmd_hdr_len, + const uint8_t cmd_max_len, + at_event_callback_t event_callback); +#endif /* AT_MASTER_H_ */ diff --git a/apps/cmdd/cmdd.c b/apps/cmdd/cmdd.c index 6dfebe42f..74bfdb0e8 100644 --- a/apps/cmdd/cmdd.c +++ b/apps/cmdd/cmdd.c @@ -24,7 +24,7 @@ static char send_udp = 0; static const char *prompt = "contiki> "; /*---------------------------------------------------------------------------*/ -static char * CC_FASTCALL +static char * n(uint16_t num, char *ptr) { uint16_t d; diff --git a/apps/codeprop/Makefile.codeprop-tmp b/apps/codeprop/Makefile.codeprop-tmp new file mode 100644 index 000000000..e725df070 --- /dev/null +++ b/apps/codeprop/Makefile.codeprop-tmp @@ -0,0 +1,10 @@ +codeprop-tmp_src = codeprop-tmp.c + +# Enable LARGE MEMORY MODEL supports for WISMOTE and EXP5438 platform +ifeq ($(TARGET),wismote) + TARGET_MEMORY_MODEL = large +endif + +ifeq ($(TARGET),exp5438) + TARGET_MEMORY_MODEL = large +endif diff --git a/apps/codeprop/codeprop-tmp.c b/apps/codeprop/codeprop-tmp.c index 42bf46e42..4f37a78a6 100644 --- a/apps/codeprop/codeprop-tmp.c +++ b/apps/codeprop/codeprop-tmp.c @@ -30,9 +30,6 @@ * */ -/** \addtogroup esb - * @{ */ - /** * * \file @@ -510,4 +507,3 @@ uipcall(void *state) } } /*---------------------------------------------------------------------*/ -/** @} */ diff --git a/apps/codeprop/codeprop.c b/apps/codeprop/codeprop.c index ead410ba7..1eb31243e 100644 --- a/apps/codeprop/codeprop.c +++ b/apps/codeprop/codeprop.c @@ -30,9 +30,6 @@ * */ -/** \addtogroup esb - * @{ */ - /** * * \file @@ -477,4 +474,3 @@ uipcall(void *state) } } /*---------------------------------------------------------------------*/ -/** @} */ diff --git a/apps/deluge/Makefile.deluge b/apps/deluge/Makefile.deluge deleted file mode 100644 index abadf18d0..000000000 --- a/apps/deluge/Makefile.deluge +++ /dev/null @@ -1 +0,0 @@ -deluge_src = deluge.c diff --git a/apps/deluge/deluge.c b/apps/deluge/deluge.c deleted file mode 100644 index e989a2ebe..000000000 --- a/apps/deluge/deluge.c +++ /dev/null @@ -1,698 +0,0 @@ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * An implementation of the Deluge protocol. - * (Hui and Culler: The dynamic behavior of a data - * dissemination protocol for network programming at scale, - * ACM SenSys 2004) - * \author - * Nicolas Tsiftes - */ - -#include "contiki.h" -#include "net/rime/rime.h" -#include "cfs/cfs.h" -#include "loader/elfloader.h" -#include "lib/crc16.h" -#include "lib/random.h" -#include "sys/node-id.h" -#include "deluge.h" - -#if NETSIM -#include "ether.h" -#include -#endif - -#include "dev/leds.h" -#include -#include - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif - -/* Implementation-specific variables. */ -static struct broadcast_conn deluge_broadcast; -static struct unicast_conn deluge_uc; -static struct deluge_object current_object; -static process_event_t deluge_event; - -/* Deluge variables. */ -static int deluge_state; -static int old_summary; -static int neighbor_inconsistency; -static unsigned r_interval; -static unsigned recv_adv; -static int broadcast_profile; - -/* Deluge timers. */ -static struct ctimer rx_timer; -static struct ctimer tx_timer; -static struct ctimer summary_timer; -static struct ctimer profile_timer; - -/* Deluge objects will get an ID that defaults to the current value of - the next_object_id parameter. */ -static deluge_object_id_t next_object_id; - -/* Rime callbacks. */ -static void broadcast_recv(struct broadcast_conn *, const linkaddr_t *); -static void unicast_recv(struct unicast_conn *, const linkaddr_t *); - -static const struct broadcast_callbacks broadcast_call = {broadcast_recv, NULL}; -static const struct unicast_callbacks unicast_call = {unicast_recv, NULL}; - -/* The Deluge process manages the main Deluge timer. */ -PROCESS(deluge_process, "Deluge"); - -static void -transition(int state) -{ - if(state != deluge_state) { - switch(deluge_state) { - case DELUGE_STATE_MAINTAIN: - ctimer_stop(&summary_timer); - ctimer_stop(&profile_timer); - break; - case DELUGE_STATE_RX: - ctimer_stop(&rx_timer); - break; - case DELUGE_STATE_TX: - ctimer_stop(&tx_timer); - break; - } - deluge_state = state; - } -} - -static int -write_page(struct deluge_object *obj, unsigned pagenum, unsigned char *data) -{ - cfs_offset_t offset; - - offset = pagenum * S_PAGE; - - if(cfs_seek(obj->cfs_fd, offset, CFS_SEEK_SET) != offset) { - return -1; - } - return cfs_write(obj->cfs_fd, (char *)data, S_PAGE); -} - -static int -read_page(struct deluge_object *obj, unsigned pagenum, unsigned char *buf) -{ - cfs_offset_t offset; - - offset = pagenum * S_PAGE; - - if(cfs_seek(obj->cfs_fd, offset, CFS_SEEK_SET) != offset) { - return -1; - } - return cfs_read(obj->cfs_fd, (char *)buf, S_PAGE); -} - -static void -init_page(struct deluge_object *obj, int pagenum, int have) -{ - struct deluge_page *page; - unsigned char buf[S_PAGE]; - - page = &obj->pages[pagenum]; - - page->flags = 0; - page->last_request = 0; - page->last_data = 0; - - if(have) { - page->version = obj->version; - page->packet_set = ALL_PACKETS; - page->flags |= PAGE_COMPLETE; - read_page(obj, pagenum, buf); - page->crc = crc16_data(buf, S_PAGE, 0); - } else { - page->version = 0; - page->packet_set = 0; - } -} - -static cfs_offset_t -file_size(const char *file) -{ - int fd; - cfs_offset_t size; - - fd = cfs_open(file, CFS_READ); - if(fd < 0) { - return (cfs_offset_t)-1; - } - - size = cfs_seek(fd, 0, CFS_SEEK_END); - cfs_close(fd); - - return size; -} - -static int -init_object(struct deluge_object *obj, char *filename, unsigned version) -{ - static struct deluge_page *page; - int i; - - obj->cfs_fd = cfs_open(filename, CFS_READ | CFS_WRITE); - if(obj->cfs_fd < 0) { - return -1; - } - - obj->filename = filename; - obj->object_id = next_object_id++; - obj->size = file_size(filename); - obj->version = obj->update_version = version; - obj->current_rx_page = 0; - obj->nrequests = 0; - obj->tx_set = 0; - - obj->pages = malloc(OBJECT_PAGE_COUNT(*obj) * sizeof(*obj->pages)); - if(obj->pages == NULL) { - cfs_close(obj->cfs_fd); - return -1; - } - - for(i = 0; i < OBJECT_PAGE_COUNT(current_object); i++) { - page = ¤t_object.pages[i]; - init_page(¤t_object, i, 1); - } - - memset(obj->current_page, 0, sizeof(obj->current_page)); - - return 0; -} - -static int -highest_available_page(struct deluge_object *obj) -{ - int i; - - for(i = 0; i < OBJECT_PAGE_COUNT(*obj); i++) { - if(!(obj->pages[i].flags & PAGE_COMPLETE)) { - break; - } - } - - return i; -} - -static void -send_request(void *arg) -{ - struct deluge_object *obj; - struct deluge_msg_request request; - - obj = (struct deluge_object *)arg; - - request.cmd = DELUGE_CMD_REQUEST; - request.pagenum = obj->current_rx_page; - request.version = obj->pages[request.pagenum].version; - request.request_set = ~obj->pages[obj->current_rx_page].packet_set; - request.object_id = obj->object_id; - - PRINTF("Sending request for page %d, version %u, request_set %u\n", - request.pagenum, request.version, request.request_set); - packetbuf_copyfrom(&request, sizeof(request)); - unicast_send(&deluge_uc, &obj->summary_from); - - /* Deluge R.2 */ - if(++obj->nrequests == CONST_LAMBDA) { - /* XXX check rate here too. */ - obj->nrequests = 0; - transition(DELUGE_STATE_MAINTAIN); - } else { - ctimer_reset(&rx_timer); - } -} - -static void -advertise_summary(struct deluge_object *obj) -{ - struct deluge_msg_summary summary; - - if(recv_adv >= CONST_K) { - ctimer_stop(&summary_timer); - return; - } - - summary.cmd = DELUGE_CMD_SUMMARY; - summary.version = obj->update_version; - summary.highest_available = highest_available_page(obj); - summary.object_id = obj->object_id; - - PRINTF("Advertising summary for object id %u: version=%u, available=%u\n", - (unsigned)obj->object_id, summary.version, summary.highest_available); - - packetbuf_copyfrom(&summary, sizeof(summary)); - broadcast_send(&deluge_broadcast); -} - -static void -handle_summary(struct deluge_msg_summary *msg, const linkaddr_t *sender) -{ - int highest_available, i; - clock_time_t oldest_request, oldest_data, now; - struct deluge_page *page; - - highest_available = highest_available_page(¤t_object); - - if(msg->version != current_object.version || - msg->highest_available != highest_available) { - neighbor_inconsistency = 1; - } else { - recv_adv++; - } - - if(msg->version < current_object.version) { - old_summary = 1; - broadcast_profile = 1; - } - - /* Deluge M.5 */ - if(msg->version == current_object.update_version && - msg->highest_available > highest_available) { - if(msg->highest_available > OBJECT_PAGE_COUNT(current_object)) { - PRINTF("Error: highest available is above object page count!\n"); - return; - } - - oldest_request = oldest_data = now = clock_time(); - for(i = 0; i < msg->highest_available; i++) { - page = ¤t_object.pages[i]; - if(page->last_request < oldest_request) { - oldest_request = page->last_request; - } - if(page->last_request < oldest_data) { - oldest_data = page->last_data; - } - } - - if(((now - oldest_request) / CLOCK_SECOND) <= 2 * r_interval || - ((now - oldest_data) / CLOCK_SECOND) <= r_interval) { - return; - } - - linkaddr_copy(¤t_object.summary_from, sender); - transition(DELUGE_STATE_RX); - - if(ctimer_expired(&rx_timer)) { - ctimer_set(&rx_timer, - CONST_OMEGA * ESTIMATED_TX_TIME + ((unsigned)random_rand() % T_R), - send_request, ¤t_object); - } - } -} - -static void -send_page(struct deluge_object *obj, unsigned pagenum) -{ - unsigned char buf[S_PAGE]; - struct deluge_msg_packet pkt; - unsigned char *cp; - - pkt.cmd = DELUGE_CMD_PACKET; - pkt.pagenum = pagenum; - pkt.version = obj->pages[pagenum].version; - pkt.packetnum = 0; - pkt.object_id = obj->object_id; - pkt.crc = 0; - - read_page(obj, pagenum, buf); - - /* Divide the page into packets and send them one at a time. */ - for(cp = buf; cp + S_PKT <= (unsigned char *)&buf[S_PAGE]; cp += S_PKT) { - if(obj->tx_set & (1 << pkt.packetnum)) { - pkt.crc = crc16_data(cp, S_PKT, 0); - memcpy(pkt.payload, cp, S_PKT); - packetbuf_copyfrom(&pkt, sizeof(pkt)); - broadcast_send(&deluge_broadcast); - } - pkt.packetnum++; - } - obj->tx_set = 0; -} - -static void -tx_callback(void *arg) -{ - struct deluge_object *obj; - - obj = (struct deluge_object *)arg; - if(obj->current_tx_page >= 0 && obj->tx_set) { - send_page(obj, obj->current_tx_page); - /* Deluge T.2. */ - if(obj->tx_set) { - packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, - PACKETBUF_ATTR_PACKET_TYPE_STREAM); - ctimer_reset(&tx_timer); - } else { - packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, - PACKETBUF_ATTR_PACKET_TYPE_STREAM_END); - obj->current_tx_page = -1; - transition(DELUGE_STATE_MAINTAIN); - } - } -} - -static void -handle_request(struct deluge_msg_request *msg) -{ - int highest_available; - - if(msg->pagenum >= OBJECT_PAGE_COUNT(current_object)) { - return; - } - - if(msg->version != current_object.version) { - neighbor_inconsistency = 1; - } - - highest_available = highest_available_page(¤t_object); - - /* Deluge M.6 */ - if(msg->version == current_object.version && - msg->pagenum <= highest_available) { - current_object.pages[msg->pagenum].last_request = clock_time(); - - /* Deluge T.1 */ - if(msg->pagenum == current_object.current_tx_page) { - current_object.tx_set |= msg->request_set; - } else { - current_object.current_tx_page = msg->pagenum; - current_object.tx_set = msg->request_set; - } - - transition(DELUGE_STATE_TX); - ctimer_set(&tx_timer, CLOCK_SECOND, tx_callback, ¤t_object); - } -} - -static void -handle_packet(struct deluge_msg_packet *msg) -{ - struct deluge_page *page; - uint16_t crc; - struct deluge_msg_packet packet; - - memcpy(&packet, msg, sizeof(packet)); - - PRINTF("Incoming packet for object id %u, version %u, page %u, packet num %u!\n", - (unsigned)packet.object_id, (unsigned)packet.version, - (unsigned)packet.pagenum, (unsigned)packet.packetnum); - - if(packet.pagenum != current_object.current_rx_page) { - return; - } - - if(packet.version != current_object.version) { - neighbor_inconsistency = 1; - } - - page = ¤t_object.pages[packet.pagenum]; - if(packet.version == page->version && !(page->flags & PAGE_COMPLETE)) { - memcpy(¤t_object.current_page[S_PKT * packet.packetnum], - packet.payload, S_PKT); - - crc = crc16_data(packet.payload, S_PKT, 0); - if(packet.crc != crc) { - PRINTF("packet crc: %hu, calculated crc: %hu\n", packet.crc, crc); - return; - } - - page->last_data = clock_time(); - page->packet_set |= (1 << packet.packetnum); - - if(page->packet_set == ALL_PACKETS) { - /* This is the last packet of the requested page; stop streaming. */ - packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, - PACKETBUF_ATTR_PACKET_TYPE_STREAM_END); - - write_page(¤t_object, packet.pagenum, current_object.current_page); - page->version = packet.version; - page->flags = PAGE_COMPLETE; - PRINTF("Page %u completed\n", packet.pagenum); - - current_object.current_rx_page++; - - if(packet.pagenum == OBJECT_PAGE_COUNT(current_object) - 1) { - current_object.version = current_object.update_version; - leds_on(LEDS_RED); - PRINTF("Update completed for object %u, version %u\n", - (unsigned)current_object.object_id, packet.version); - } else if(current_object.current_rx_page < OBJECT_PAGE_COUNT(current_object)) { - if(ctimer_expired(&rx_timer)) { - ctimer_set(&rx_timer, - CONST_OMEGA * ESTIMATED_TX_TIME + (random_rand() % T_R), - send_request, ¤t_object); - } - } - /* Deluge R.3 */ - transition(DELUGE_STATE_MAINTAIN); - } else { - /* More packets to come. Put lower layers in streaming mode. */ - packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, - PACKETBUF_ATTR_PACKET_TYPE_STREAM); - } - } -} - -static void -send_profile(struct deluge_object *obj) -{ - struct deluge_msg_profile *msg; - unsigned char buf[sizeof(*msg) + OBJECT_PAGE_COUNT(*obj)]; - int i; - - if(broadcast_profile && recv_adv < CONST_K) { - broadcast_profile = 0; - - msg = (struct deluge_msg_profile *)buf; - msg->cmd = DELUGE_CMD_PROFILE; - msg->version = obj->version; - msg->npages = OBJECT_PAGE_COUNT(*obj); - msg->object_id = obj->object_id; - for(i = 0; i < msg->npages; i++) { - msg->version_vector[i] = obj->pages[i].version; - } - - packetbuf_copyfrom(buf, sizeof(buf)); - broadcast_send(&deluge_broadcast); - } -} - -static void -handle_profile(struct deluge_msg_profile *msg) -{ - int i; - int npages; - struct deluge_object *obj; - char *p; - - obj = ¤t_object; - if(msg->version <= current_object.update_version) { - return; - } - - PRINTF("Received profile of version %u with a vector of %u pages.\n", - msg->version, msg->npages); - - leds_off(LEDS_RED); - current_object.tx_set = 0; - - npages = OBJECT_PAGE_COUNT(*obj); - obj->size = msg->npages * S_PAGE; - - p = malloc(OBJECT_PAGE_COUNT(*obj) * sizeof(*obj->pages)); - if(p == NULL) { - PRINTF("Failed to reallocate memory for pages!\n"); - return; - } - - memcpy(p, obj->pages, npages * sizeof(*obj->pages)); - free(obj->pages); - obj->pages = (struct deluge_page *)p; - - if(msg->npages < npages) { - npages = msg->npages; - } - - for(i = 0; i < npages; i++) { - if(msg->version_vector[i] > obj->pages[i].version) { - obj->pages[i].packet_set = 0; - obj->pages[i].flags &= ~PAGE_COMPLETE; - obj->pages[i].version = msg->version_vector[i]; - } - } - - for(; i < msg->npages; i++) { - init_page(obj, i, 0); - } - - obj->current_rx_page = highest_available_page(obj); - obj->update_version = msg->version; - - transition(DELUGE_STATE_RX); - - ctimer_set(&rx_timer, - CONST_OMEGA * ESTIMATED_TX_TIME + ((unsigned)random_rand() % T_R), - send_request, obj); -} - -static void -command_dispatcher(const linkaddr_t *sender) -{ - char *msg; - int len; - struct deluge_msg_profile *profile; - - msg = packetbuf_dataptr(); - len = packetbuf_datalen(); - if(len < 1) - return; - - switch(msg[0]) { - case DELUGE_CMD_SUMMARY: - if(len >= sizeof(struct deluge_msg_summary)) - handle_summary((struct deluge_msg_summary *)msg, sender); - break; - case DELUGE_CMD_REQUEST: - if(len >= sizeof(struct deluge_msg_request)) - handle_request((struct deluge_msg_request *)msg); - break; - case DELUGE_CMD_PACKET: - if(len >= sizeof(struct deluge_msg_packet)) - handle_packet((struct deluge_msg_packet *)msg); - break; - case DELUGE_CMD_PROFILE: - profile = (struct deluge_msg_profile *)msg; - if(len >= sizeof(*profile) && - len >= sizeof(*profile) + profile->npages * profile->version_vector[0]) - handle_profile((struct deluge_msg_profile *)msg); - break; - default: - PRINTF("Incoming packet with unknown command: %d\n", msg[0]); - } -} - -static void -unicast_recv(struct unicast_conn *c, const linkaddr_t *sender) -{ - command_dispatcher(sender); -} - -static void -broadcast_recv(struct broadcast_conn *c, const linkaddr_t *sender) -{ - command_dispatcher(sender); -} - -int -deluge_disseminate(char *file, unsigned version) -{ - /* This implementation disseminates at most one object. */ - if(next_object_id > 0 || init_object(¤t_object, file, version) < 0) { - return -1; - } - process_start(&deluge_process, file); - - return 0; -} - -PROCESS_THREAD(deluge_process, ev, data) -{ - static struct etimer et; - static unsigned time_counter; - static unsigned r_rand; - - PROCESS_EXITHANDLER(goto exit); - - PROCESS_BEGIN(); - - deluge_event = process_alloc_event(); - - broadcast_open(&deluge_broadcast, DELUGE_BROADCAST_CHANNEL, &broadcast_call); - unicast_open(&deluge_uc, DELUGE_UNICAST_CHANNEL, &unicast_call); - r_interval = T_LOW; - - PRINTF("Maintaining state for object %s of %d pages\n", - current_object.filename, OBJECT_PAGE_COUNT(current_object)); - - deluge_state = DELUGE_STATE_MAINTAIN; - - for(r_interval = T_LOW;;) { - if(neighbor_inconsistency) { - /* Deluge M.2 */ - r_interval = T_LOW; - neighbor_inconsistency = 0; - } else { - /* Deluge M.3 */ - r_interval = (2 * r_interval >= T_HIGH) ? T_HIGH : 2 * r_interval; - } - - r_rand = r_interval / 2 + ((unsigned)random_rand() % (r_interval / 2)); - recv_adv = 0; - old_summary = 0; - - /* Deluge M.1 */ - ctimer_set(&summary_timer, r_rand * CLOCK_SECOND, - (void *)(void *)advertise_summary, ¤t_object); - - /* Deluge M.4 */ - ctimer_set(&profile_timer, r_rand * CLOCK_SECOND, - (void *)(void *)send_profile, ¤t_object); - - LONG_TIMER(et, time_counter, r_interval); - } - -exit: - unicast_close(&deluge_uc); - broadcast_close(&deluge_broadcast); - if(current_object.cfs_fd >= 0) { - cfs_close(current_object.cfs_fd); - } - if(current_object.pages != NULL) { - free(current_object.pages); - } - - PROCESS_END(); -} diff --git a/apps/deluge/deluge.h b/apps/deluge/deluge.h deleted file mode 100644 index 11bdd0a96..000000000 --- a/apps/deluge/deluge.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Header for Deluge. - * \author - * Nicolas Tsiftes - */ - -#ifndef DELUGE_H -#define DELUGE_H - -#include "net/rime/rime.h" - -PROCESS_NAME(deluge_process); - -#define LONG_TIMER(et, counter, time) \ - do { \ - for (counter = 0; counter < time; counter++) { \ - etimer_set(&et, CLOCK_SECOND); \ - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); \ - } \ - } while (0) - -#define DELUGE_UNICAST_CHANNEL 55 -#define DELUGE_BROADCAST_CHANNEL 56 - -/* All the packets in a page have been received. */ -#define PAGE_COMPLETE 1 -/* All pages up to, and including, this page are complete. */ -#define PAGE_AVAILABLE 1 - -#define S_PKT 64 /* Deluge packet size. */ -#define N_PKT 4 /* Packets per page. */ -#define S_PAGE (S_PKT * N_PKT) /* Fixed page size. */ - -/* Bounds for the round time in seconds. */ -#define T_LOW 2 -#define T_HIGH 64 - -/* Random interval for request transmissions in jiffies. */ -#define T_R (CLOCK_SECOND * 2) - -/* Bound for the number of advertisements. */ -#define CONST_K 1 - -/* The number of pages in this object. */ -#define OBJECT_PAGE_COUNT(obj) (((obj).size + (S_PAGE - 1)) / S_PAGE) - -#define ALL_PACKETS ((1 << N_PKT) - 1) - -#define DELUGE_CMD_SUMMARY 1 -#define DELUGE_CMD_REQUEST 2 -#define DELUGE_CMD_PACKET 3 -#define DELUGE_CMD_PROFILE 4 - -#define DELUGE_STATE_MAINTAIN 1 -#define DELUGE_STATE_RX 2 -#define DELUGE_STATE_TX 3 - -#define CONST_LAMBDA 2 -#define CONST_ALPHA 0.5 - -#define CONST_OMEGA 8 -#define ESTIMATED_TX_TIME (CLOCK_SECOND) - -typedef uint8_t deluge_object_id_t; - -struct deluge_msg_summary { - uint8_t cmd; - uint8_t version; - uint8_t highest_available; - deluge_object_id_t object_id; -}; - -struct deluge_msg_request { - uint8_t cmd; - uint8_t version; - uint8_t pagenum; - uint8_t request_set; - deluge_object_id_t object_id; -}; - -struct deluge_msg_packet { - uint8_t cmd; - uint8_t version; - uint8_t pagenum; - uint8_t packetnum; - uint16_t crc; - deluge_object_id_t object_id; - unsigned char payload[S_PKT]; -}; - -struct deluge_msg_profile { - uint8_t cmd; - uint8_t version; - uint8_t npages; - deluge_object_id_t object_id; - uint8_t version_vector[]; -}; - -struct deluge_object { - char *filename; - uint16_t object_id; - uint16_t size; - uint8_t version; - uint8_t update_version; - struct deluge_page *pages; - uint8_t current_rx_page; - int8_t current_tx_page; - uint8_t nrequests; - uint8_t current_page[S_PAGE]; - uint8_t tx_set; - int cfs_fd; - linkaddr_t summary_from; -}; - -struct deluge_page { - uint32_t packet_set; - uint16_t crc; - clock_time_t last_request; - clock_time_t last_data; - uint8_t flags; - uint8_t version; -}; - -int deluge_disseminate(char *file, unsigned version); - -#endif diff --git a/apps/dhcp/dhcp.c b/apps/dhcp/dhcp.c index 9ac20b102..fd2861811 100644 --- a/apps/dhcp/dhcp.c +++ b/apps/dhcp/dhcp.c @@ -88,7 +88,7 @@ makestrings(void) uip_getdraddr(&addr); makeaddr(&addr, gateway); - addrptr = resolv_getserver(); + addrptr = uip_nameserver_get(0); if(addrptr != NULL) { makeaddr(addrptr, dnsserver); } @@ -97,9 +97,9 @@ makestrings(void) PROCESS_THREAD(dhcp_process, ev, data) { PROCESS_BEGIN(); - + ctk_window_new(&window, 28, 7, "DHCP"); - + CTK_WIDGET_ADD(&window, &getbutton); CTK_WIDGET_ADD(&window, &statuslabel); CTK_WIDGET_ADD(&window, &ipaddrlabel); @@ -110,22 +110,21 @@ PROCESS_THREAD(dhcp_process, ev, data) CTK_WIDGET_ADD(&window, &gatewayentry); CTK_WIDGET_ADD(&window, &dnsserverlabel); CTK_WIDGET_ADD(&window, &dnsserverentry); - + CTK_WIDGET_FOCUS(&window, &getbutton); ctk_window_open(&window); dhcpc_init(uip_lladdr.addr, sizeof(uip_lladdr.addr)); - while(1) { PROCESS_WAIT_EVENT(); - + if(ev == ctk_signal_widget_activate) { if(data == (process_data_t)&getbutton) { dhcpc_request(); set_statustext("Requesting..."); } - } else if(ev == tcpip_event) { + } else if(ev == tcpip_event || ev == PROCESS_EVENT_TIMER) { dhcpc_appcall(ev, data); } else if(ev == PROCESS_EVENT_EXIT || ev == ctk_signal_window_close) { @@ -147,7 +146,7 @@ dhcpc_configured(const struct dhcpc_state *s) uip_sethostaddr(&s->ipaddr); uip_setnetmask(&s->netmask); uip_setdraddr(&s->default_router); - resolv_conf(&s->dnsaddr); + uip_nameserver_update(&s->dnsaddr, UIP_NAMESERVER_INFINITE_LIFETIME); set_statustext("Configured."); process_post(PROCESS_CURRENT(), SHOWCONFIG, NULL); } diff --git a/apps/er-coap-03/Makefile.er-coap-03 b/apps/er-coap-03/Makefile.er-coap-03 deleted file mode 100644 index c308c18d5..000000000 --- a/apps/er-coap-03/Makefile.er-coap-03 +++ /dev/null @@ -1 +0,0 @@ -er-coap-03_src = er-coap-03-engine.c er-coap-03.c er-coap-03-transactions.c er-coap-03-observing.c diff --git a/apps/er-coap-03/er-coap-03-engine.c b/apps/er-coap-03/er-coap-03-engine.c deleted file mode 100644 index 8e21d30d3..000000000 --- a/apps/er-coap-03/er-coap-03-engine.c +++ /dev/null @@ -1,559 +0,0 @@ -/* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP implementation of the REST Engine - * \author - * Matthias Kovatsch - */ - -#include -#include -#include -#include "contiki.h" -#include "contiki-net.h" - -#include "er-coap-03-engine.h" - -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#define PRINTBITS(buf,len) { \ - int i,j=0; \ - for (i=0; i=0; --j) { \ - PRINTF("%c", (((char *)buf)[i] & 1<srcipaddr); - PRINTF(":%u\n Length: %u\n Data: ", uip_ntohs(UIP_UDP_BUF->srcport), uip_datalen() ); - PRINTBITS(uip_appdata, uip_datalen()); - PRINTF("\n"); - - coap_packet_t message[1]; - coap_transaction_t *transaction = NULL; - - error = coap_parse_message(message, uip_appdata, uip_datalen()); - - if (error==NO_ERROR) - { - - /*TODO duplicates suppression, if required */ - - PRINTF(" Parsed: v %u, t %u, oc %u, c %u, tid %u\n", message->version, message->type, message->option_count, message->code, message->tid); - PRINTF(" URL: %.*s\n", message->uri_path_len, message->uri_path); - PRINTF(" Payload: %.*s\n", message->payload_len, message->payload); - - /* Handle requests. */ - if (message->code >= COAP_GET && message->code <= COAP_DELETE) - { - /* Use transaction buffer for response to confirmable request. */ - if ( (transaction = coap_new_transaction(message->tid, &UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport)) ) - { - uint32_t block_num = 0; - uint16_t block_size = REST_MAX_CHUNK_SIZE; - uint32_t block_offset = 0; - int32_t new_offset = 0; - - /* prepare response */ - coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */ - if (message->type==COAP_TYPE_CON) - { - /* Reliable CON requests are answered with an ACK. */ - coap_init_message(response, COAP_TYPE_ACK, OK_200, message->tid); - } - else - { - /* Unreliable NON requests are answered with a NON as well. */ - coap_init_message(response, COAP_TYPE_NON, OK_200, coap_get_tid()); - } - - /* resource handlers must take care of different handling (e.g., TOKEN_OPTION_REQUIRED_240) */ - if (IS_OPTION(message, COAP_OPTION_TOKEN)) - { - coap_set_header_token(response, message->token, message->token_len); - SET_OPTION(response, COAP_OPTION_TOKEN); - } - - /* get offset for blockwise transfers */ - if (coap_get_header_block(message, &block_num, NULL, &block_size, &block_offset)) - { - PRINTF("Blockwise: block request %lu (%u/%u) @ %lu bytes\n", block_num, block_size, REST_MAX_CHUNK_SIZE, block_offset); - block_size = MIN(block_size, REST_MAX_CHUNK_SIZE); - new_offset = block_offset; - } - - /*------------------------------------------*/ - /* call application-specific handler */ - /*------------------------------------------*/ - if (service_cbk) { - service_cbk(message, response, transaction->packet+COAP_MAX_HEADER_SIZE, block_size, &new_offset); - } - /*------------------------------------------*/ - - - /* apply blockwise transfers */ - if ( IS_OPTION(message, COAP_OPTION_BLOCK) ) - { - /* unchanged new_offset indicates that resource is unaware of blockwise transfer */ - if (new_offset==block_offset) - { - PRINTF("Blockwise: unaware resource with payload length %u/%u\n", response->payload_len, block_size); - if (block_offset >= response->payload_len) - { - response->code = BAD_REQUEST_400; - coap_set_payload(response, (uint8_t*)"Block out of scope", 18); - } - else - { - coap_set_header_block(response, block_num, response->payload_len - block_offset > block_size, block_size); - coap_set_payload(response, response->payload+block_offset, MIN(response->payload_len - block_offset, block_size)); - } /* if (valid offset) */ - } - else - { - /* resource provides chunk-wise data */ - PRINTF("Blockwise: blockwise resource, new offset %ld\n", new_offset); - coap_set_header_block(response, block_num, new_offset!=-1 || response->payload_len > block_size, block_size); - if (response->payload_len > block_size) coap_set_payload(response, response->payload, block_size); - } /* if (resource aware of blockwise) */ - } - else if (new_offset!=0) - { - PRINTF("Blockwise: no block option for blockwise resource, using block size %u\n", REST_MAX_CHUNK_SIZE); - - coap_set_header_block(response, 0, new_offset!=-1, REST_MAX_CHUNK_SIZE); - coap_set_payload(response, response->payload, MIN(response->payload_len, REST_MAX_CHUNK_SIZE)); - } /* if (blockwise request) */ - - if ((transaction->packet_len = coap_serialize_message(response, transaction->packet))==0) - { - error = PACKET_SERIALIZATION_ERROR; - } - - } else { - error = MEMORY_ALLOCATION_ERROR; - } - } - else - { - /* Responses */ - coap_transaction_t *t; - - if (message->type==COAP_TYPE_ACK) - { - PRINTF("Received ACK\n"); - } - else if (message->type==COAP_TYPE_RST) - { - PRINTF("Received RST\n"); - /* Cancel possible subscriptions. */ - if (IS_OPTION(message, COAP_OPTION_TOKEN)) - { - PRINTF(" Token 0x%02X%02X\n", message->token[0], message->token[1]); - coap_remove_observer_by_token(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, message->token, message->token_len); - } - } - - if ( (t = coap_get_transaction_by_tid(message->tid)) ) - { - /* Free transaction memory before callback, as it may create a new transaction. */ - restful_response_handler callback = t->callback; - void *callback_data = t->callback_data; - coap_clear_transaction(t); - - /* Check if someone registered for the response */ - if (callback) { - callback(callback_data, message); - } - } /* if (transaction) */ - } - } /* if (parsed correctly) */ - - if (error==NO_ERROR) { - if (transaction) coap_send_transaction(transaction); - } - else - { - PRINTF("ERROR %u: %s\n", error, error_messages[error]); - - /* reuse input buffer */ - coap_init_message(message, COAP_TYPE_ACK, INTERNAL_SERVER_ERROR_500, message->tid); - coap_set_payload(message, (uint8_t *) error_messages[error], strlen(error_messages[error])); - coap_send_message(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, uip_appdata, coap_serialize_message(message, uip_appdata)); - } - } /* if (new data) */ - - return error; -} -/*-----------------------------------------------------------------------------------*/ -void -coap_receiver_init() -{ - process_start(&coap_receiver, NULL); -} -/*-----------------------------------------------------------------------------------*/ -void -coap_set_service_callback(service_callback_t callback) -{ - service_cbk = callback; -} -/*-----------------------------------------------------------------------------------*/ -rest_resource_flags_t -coap_get_rest_method(void *packet) -{ - return (rest_resource_flags_t)(1 << (((coap_packet_t *)packet)->code - 1)); -} -/*-----------------------------------------------------------------------------------*/ -int -coap_set_rest_status(void *packet, unsigned int code) -{ - if (code <= 0xFF) - { - ((coap_packet_t *)packet)->code = (uint8_t) code; - return 1; - } - else - { - return 0; - } -} -/*-----------------------------------------------------------------------------------*/ -/*- Server part ---------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -/* The discover resource should be included when using CoAP. */ -RESOURCE(well_known_core, METHOD_GET, ".well-known/core", ""); -void -well_known_core_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - /* Response might be NULL for non-confirmable requests. */ - if (response) - { - size_t strpos = 0; - size_t bufpos = 0; - resource_t* resource = NULL; - - for (resource = (resource_t*)list_head(rest_get_resources()); resource; resource = resource->next) - { - strpos += snprintf((char *) buffer + bufpos, REST_MAX_CHUNK_SIZE - bufpos + 1, - "%s%s%s", - resource->url, - resource->attributes[0] ? ";" : "", - resource->attributes, - resource->next ? "," : "" ); - - PRINTF("discover: %s\n", resource->url); - - if (strpos <= *offset) - { - /* Discard output before current block */ - PRINTF(" if %d <= %ld B\n", strpos, *offset); - PRINTF(" %s\n", buffer); - bufpos = 0; - } - else /* (strpos > *offset) */ - { - /* output partly in block */ - size_t len = MIN(strpos - *offset, preferred_size); - - PRINTF(" el %d/%d @ %ld B\n", len, preferred_size, *offset); - - /* Block might start in the middle of the output; align with buffer start. */ - if (bufpos == 0) - { - memmove(buffer, buffer+strlen((char *)buffer)-strpos+*offset, len); - } - - bufpos = len; - PRINTF(" %s\n", buffer); - - if (bufpos >= preferred_size) - { - break; - } - } - } - - if (bufpos>0) { - coap_set_payload(response, buffer, bufpos ); - coap_set_header_content_type(response, APPLICATION_LINK_FORMAT); - } - else - { - coap_set_rest_status(response, BAD_REQUEST_400); - coap_set_payload(response, (uint8_t*)"Block out of scope", 18); - } - - if (resource==NULL) { - *offset = -1; - } - else - { - *offset += bufpos; - } - } -} -/*-----------------------------------------------------------------------------------*/ -PROCESS_THREAD(coap_receiver, ev, data) -{ - PROCESS_BEGIN(); - PRINTF("Starting CoAP-03 receiver...\n"); - - rest_activate_resource(&resource_well_known_core); - - coap_register_as_transaction_handler(); - coap_init_connection(SERVER_LISTEN_PORT); - - while(1) { - PROCESS_YIELD(); - - if(ev == tcpip_event) { - handle_incoming_data(); - } else if (ev == PROCESS_EVENT_TIMER) { - /* retransmissions are handled here */ - coap_check_transactions(); - } - } /* while (1) */ - - PROCESS_END(); -} -/*-----------------------------------------------------------------------------------*/ -/*- Client part ---------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -void blocking_request_callback(void *callback_data, void *response) { - struct request_state_t *state = (struct request_state_t *) callback_data; - state->response = (coap_packet_t*) response; - process_poll(state->process); -} -/*-----------------------------------------------------------------------------------*/ -PT_THREAD(coap_blocking_request(struct request_state_t *state, process_event_t ev, - uip_ipaddr_t *remote_ipaddr, uint16_t remote_port, - coap_packet_t *request, - blocking_response_handler request_callback)) { - PT_BEGIN(&state->pt); - - static uint8_t more; - static uint32_t res_block; - static uint8_t block_error; - - state->block_num = 0; - state->response = NULL; - state->process = PROCESS_CURRENT(); - - more = 0; - res_block = 0; - block_error = 0; - - do { - request->tid = coap_get_tid(); - if ((state->transaction = coap_new_transaction(request->tid, remote_ipaddr, remote_port))) - { - state->transaction->callback = blocking_request_callback; - state->transaction->callback_data = state; - - if (state->block_num>0) - { - coap_set_header_block(request, state->block_num, 0, REST_MAX_CHUNK_SIZE); - } - - state->transaction->packet_len = coap_serialize_message(request, state->transaction->packet); - - coap_send_transaction(state->transaction); - PRINTF("Requested #%lu (TID %u)\n", state->block_num, request->tid); - - PT_YIELD_UNTIL(&state->pt, ev == PROCESS_EVENT_POLL); - - if (!state->response) - { - PRINTF("Server not responding\n"); - PT_EXIT(&state->pt); - } - - coap_get_header_block(state->response, &res_block, &more, NULL, NULL); - - PRINTF("Received #%lu%s (%u bytes)\n", res_block, more ? "+" : "", state->response->payload_len); - - if (res_block==state->block_num) - { - request_callback(state->response); - ++(state->block_num); - } - else - { - PRINTF("WRONG BLOCK %lu/%lu\n", res_block, state->block_num); - ++block_error; - } - } - else - { - PRINTF("Could not allocate transaction buffer"); - PT_EXIT(&state->pt); - } - } while (more && block_errorpt); -} -/*-----------------------------------------------------------------------------------*/ -/*- Engine Interface ----------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -const struct rest_implementation coap_rest_implementation = { - "CoAP-03", - - coap_receiver_init, - coap_set_service_callback, - - coap_get_header_uri_path, - coap_set_header_uri_path, - coap_get_rest_method, - coap_set_rest_status, - - coap_get_header_content_type, - coap_set_header_content_type, - NULL, - NULL, - NULL, - coap_get_header_max_age, - coap_set_header_max_age, - coap_set_header_etag, - NULL, - NULL, - coap_get_header_uri_host, - coap_set_header_location, - - coap_get_payload, - coap_set_payload, - - coap_get_header_uri_query, - coap_get_query_variable, - coap_get_post_variable, - - coap_notify_observers, - (restful_post_handler) coap_observe_handler, - - NULL, - NULL, - - { - OK_200, - CREATED_201, - OK_200, - OK_200, - NOT_MODIFIED_304, - - BAD_REQUEST_400, - METHOD_NOT_ALLOWED_405, - BAD_REQUEST_400, - METHOD_NOT_ALLOWED_405, - NOT_FOUND_404, - METHOD_NOT_ALLOWED_405, - UNSUPPORTED_MEDIA_TYPE_415, - BAD_REQUEST_400, - UNSUPPORTED_MEDIA_TYPE_415, - - INTERNAL_SERVER_ERROR_500, - CRITICAL_OPTION_NOT_SUPPORTED, - BAD_GATEWAY_502, - SERVICE_UNAVAILABLE_503, - GATEWAY_TIMEOUT_504, - INTERNAL_SERVER_ERROR_500 - }, - - { - TEXT_PLAIN, - TEXT_XML, - TEXT_CSV, - TEXT_HTML, - IMAGE_GIF, - IMAGE_JPEG, - IMAGE_PNG, - IMAGE_TIFF, - AUDIO_RAW, - VIDEO_RAW, - APPLICATION_LINK_FORMAT, - APPLICATION_XML, - APPLICATION_OCTET_STREAM, - APPLICATION_RDF_XML, - APPLICATION_SOAP_XML, - APPLICATION_ATOM_XML, - APPLICATION_XMPP_XML, - APPLICATION_EXI, - APPLICATION_FASTINFOSET, - APPLICATION_SOAP_FASTINFOSET, - APPLICATION_JSON, - APPLICATION_OCTET_STREAM - } -}; diff --git a/apps/er-coap-03/er-coap-03-observing.c b/apps/er-coap-03/er-coap-03-observing.c deleted file mode 100644 index fe23f5d03..000000000 --- a/apps/er-coap-03/er-coap-03-observing.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP module for observing resources - * \author - * Matthias Kovatsch - */ - -#include -#include - -#include "er-coap-03-observing.h" - -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - - -MEMB(observers_memb, coap_observer_t, COAP_MAX_OBSERVERS); -LIST(observers_list); - -/*-----------------------------------------------------------------------------------*/ -coap_observer_t * -coap_add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token, size_t token_len, const char *url) -{ - coap_observer_t *o = memb_alloc(&observers_memb); - - if (o) - { - o->url = url; - uip_ipaddr_copy(&o->addr, addr); - o->port = port; - o->token_len = token_len; - memcpy(o->token, token, token_len); - - stimer_set(&o->refresh_timer, COAP_OBSERVING_REFRESH_INTERVAL); - - PRINTF("Adding observer for /%s [0x%02X%02X]\n", o->url, o->token[0], o->token[1]); - list_add(observers_list, o); - } - - return o; -} -/*-----------------------------------------------------------------------------------*/ -void -coap_remove_observer(coap_observer_t *o) -{ - PRINTF("Removing observer for /%s [0x%02X%02X]\n", o->url, o->token[0], o->token[1]); - - memb_free(&observers_memb, o); - list_remove(observers_list, o); -} - -int -coap_remove_observer_by_client(uip_ipaddr_t *addr, uint16_t port) -{ - int removed = 0; - coap_observer_t* obs = NULL; - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - PRINTF("Remove check Port %u\n", port); - if (uip_ipaddr_cmp(&obs->addr, addr) && obs->port==port) - { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} -int -coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port, uint8_t *token, size_t token_len) -{ - int removed = 0; - coap_observer_t* obs = NULL; - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - PRINTF("Remove check Token 0x%02X%02X\n", token[0], token[1]); - if (uip_ipaddr_cmp(&obs->addr, addr) && obs->port==port && memcmp(obs->token, token, token_len)==0) - { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} -/*-----------------------------------------------------------------------------------*/ -void -coap_notify_observers(resource_t *resource, int32_t obs_counter, void *notification) -{ - coap_packet_t *const coap_res = (coap_packet_t *) notification; - coap_observer_t* obs = NULL; - uint8_t preferred_type = coap_res->type; - - PRINTF("Observing: Notification from %s\n", resource->url); - - /* Iterate over observers. */ - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - if (obs->url==resource->url) /* using RESOURCE url pointer as handle */ - { - coap_transaction_t *transaction = NULL; - - /*TODO implement special transaction for CON, sharing the same buffer to allow for more observers. */ - - if ( (transaction = coap_new_transaction(coap_get_tid(), &obs->addr, obs->port)) ) - { - PRINTF(" Observer "); - PRINT6ADDR(&obs->addr); - PRINTF(":%u\n", obs->port); - - /* Prepare response */ - coap_res->tid = transaction->tid; - coap_set_header_observe(coap_res, obs_counter); - coap_set_header_token(coap_res, obs->token, obs->token_len); - - /* Use CON to check whether client is still there/interested after COAP_OBSERVING_REFRESH_INTERVAL. */ - if (stimer_expired(&obs->refresh_timer)) - { - PRINTF(" Refreshing with CON\n"); - coap_res->type = COAP_TYPE_CON; - stimer_restart(&obs->refresh_timer); - } - else - { - coap_res->type = preferred_type; - } - - transaction->packet_len = coap_serialize_message(coap_res, transaction->packet); - - coap_send_transaction(transaction); - } - } - } -} -/*-----------------------------------------------------------------------------------*/ -void -coap_observe_handler(resource_t *resource, void *request, void *response) -{ - static char content[26]; - - if (response && ((coap_packet_t *)response)->code<128) /* response without error code */ - { - if (IS_OPTION((coap_packet_t *)request, COAP_OPTION_OBSERVE)) - { - if (IS_OPTION((coap_packet_t *)request, COAP_OPTION_TOKEN)) - { - if (coap_add_observer(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, ((coap_packet_t *)request)->token, ((coap_packet_t *)request)->token_len, resource->url)) - { - coap_set_header_observe(response, 0); - coap_set_payload(response, (uint8_t *)content, snprintf(content, sizeof(content), "Added as observer %u/%u", list_length(observers_list), COAP_MAX_OBSERVERS)); - } - else - { - ((coap_packet_t *)response)->code = SERVICE_UNAVAILABLE_503; - coap_set_payload(response, (uint8_t *)"Too many observers", 18); - } /* if (added observer) */ - } - else /* if (token) */ - { - ((coap_packet_t *)response)->code = TOKEN_OPTION_REQUIRED; - coap_set_payload(response, (uint8_t *)"Observing requires token", 24); - } /* if (token) */ - } - else /* if (observe) */ - { - /* Remove client if it is currently observing. */ - coap_remove_observer_by_client(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport); - } /* if (observe) */ - } -} diff --git a/apps/er-coap-03/er-coap-03-observing.h b/apps/er-coap-03/er-coap-03-observing.h deleted file mode 100644 index b9baad377..000000000 --- a/apps/er-coap-03/er-coap-03-observing.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP module for observing resources - * \author - * Matthias Kovatsch - */ - -#ifndef COAP_OBSERVING_H_ -#define COAP_OBSERVING_H_ - -#include "sys/stimer.h" -#include "er-coap-03.h" -#include "er-coap-03-transactions.h" - -#ifndef COAP_MAX_OBSERVERS -#define COAP_MAX_OBSERVERS 4 -#endif /* COAP_MAX_OBSERVERS */ - -/* Interval in seconds in which NON notifies are changed to CON notifies to check client. */ -#define COAP_OBSERVING_REFRESH_INTERVAL 60 - -#if COAP_MAX_OPEN_TRANSACTIONS - */ - -#include "contiki.h" -#include "contiki-net.h" - -#include "er-coap-03-transactions.h" -#include "er-coap-03-observing.h" - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - - -MEMB(transactions_memb, coap_transaction_t, COAP_MAX_OPEN_TRANSACTIONS); -LIST(transactions_list); - - -static struct process *transaction_handler_process = NULL; - -void -coap_register_as_transaction_handler() -{ - transaction_handler_process = PROCESS_CURRENT(); -} - -coap_transaction_t * -coap_new_transaction(uint16_t tid, uip_ipaddr_t *addr, uint16_t port) -{ - coap_transaction_t *t = memb_alloc(&transactions_memb); - - if (t) - { - t->tid = tid; - t->retrans_counter = 0; - - /* save client address */ - uip_ipaddr_copy(&t->addr, addr); - t->port = port; - } - - return t; -} - -void -coap_send_transaction(coap_transaction_t *t) -{ - PRINTF("Sending transaction %u\n", t->tid); - - coap_send_message(&t->addr, t->port, t->packet, t->packet_len); - - if (COAP_TYPE_CON==((COAP_HEADER_TYPE_MASK & t->packet[0])>>COAP_HEADER_TYPE_POSITION)) - { - if (t->retrans_countertid); - - /*FIXME hack, maybe there is a better way, but avoid posting everything to the process */ - struct process *process_actual = PROCESS_CURRENT(); - process_current = transaction_handler_process; - etimer_set(&t->retrans_timer, CLOCK_SECOND * COAP_RESPONSE_TIMEOUT * (1<<(t->retrans_counter))); - process_current = process_actual; - - list_add(transactions_list, t); /* list itself makes sure same element is not added twice */ - - t = NULL; - } - else - { - /* timeout */ - PRINTF("Timeout\n"); - restful_response_handler callback = t->callback; - void *callback_data = t->callback_data; - - /* handle observers */ - coap_remove_observer_by_client(&t->addr, t->port); - - coap_clear_transaction(t); - - if (callback) { - callback(callback_data, NULL); - } - } - } - else - { - coap_clear_transaction(t); - } -} - -void -coap_clear_transaction(coap_transaction_t *t) -{ - if (t) - { - PRINTF("Freeing transaction %u: %p\n", t->tid, t); - - etimer_stop(&t->retrans_timer); - list_remove(transactions_list, t); - memb_free(&transactions_memb, t); - } -} - -coap_transaction_t * -coap_get_transaction_by_tid(uint16_t tid) -{ - coap_transaction_t *t = NULL; - - for (t = (coap_transaction_t*)list_head(transactions_list); t; t = t->next) - { - if (t->tid==tid) - { - PRINTF("Found transaction for TID %u: %p\n", t->tid, t); - return t; - } - } - return NULL; -} - -void -coap_check_transactions() -{ - coap_transaction_t *t = NULL; - - for (t = (coap_transaction_t*)list_head(transactions_list); t; t = t->next) - { - if (etimer_expired(&t->retrans_timer)) - { - ++(t->retrans_counter); - PRINTF("Retransmitting %u (%u)\n", t->tid, t->retrans_counter); - coap_send_transaction(t); - } - } -} diff --git a/apps/er-coap-03/er-coap-03.c b/apps/er-coap-03/er-coap-03.c deleted file mode 100644 index 8a770282b..000000000 --- a/apps/er-coap-03/er-coap-03.c +++ /dev/null @@ -1,769 +0,0 @@ -/* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * An implementation of the Constrained Application Protocol (draft 03) - * \author - * Matthias Kovatsch - */ - -#ifdef CONTIKI_TARGET_NETSIM - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include -#else - #include "contiki.h" - #include "contiki-net.h" - #include - #include -#endif - -#include "er-coap-03.h" -#include "er-coap-03-transactions.h" - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - - -static struct uip_udp_conn *udp_conn = NULL; -static uint16_t current_tid = 0; - -/*-----------------------------------------------------------------------------------*/ -/*- LOCAL HELP FUNCTIONS ------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -static -uint16_t -log_2(uint16_t value) -{ - uint16_t result = 0; - do { - value = value >> 1; - result++; - } while (value); - - return result ? result - 1 : result; -} -/*-----------------------------------------------------------------------------------*/ -static -uint32_t -bytes_2_uint32(uint8_t *bytes, uint16_t length) -{ - uint32_t var = 0; - int i = 0; - while (i>8; - bytes[i++] = 0xFF & var; - - return i; -} -*/ -/*-----------------------------------------------------------------------------------*/ -static -int -uint32_2_bytes(uint8_t *bytes, uint32_t var) -{ - int i = 0; - if (0xFF000000 & var) bytes[i++] = (0xFF & var>>24); - if (0xFFFF0000 & var) bytes[i++] = (0xFF & var>>16); - if (0xFFFFFF00 & var) bytes[i++] = (0xFF & var>>8); - bytes[i++] = 0xFF & var; - - return i; -} -/*-----------------------------------------------------------------------------------*/ -static -int -coap_get_variable(const char *buffer, size_t length, const char *name, const char **output) -{ - const char *start = NULL; - const char *end = NULL; - const char *value_end = NULL; - size_t name_len = 0; - - /*initialize the output buffer first*/ - *output = 0; - - name_len = strlen(name); - end = buffer + length; - - for (start = buffer; start + name_len < end; ++start){ - if ((start == buffer || start[-1] == '&') && start[name_len] == '=' && - strncmp(name, start, name_len)==0) { - - /* Point start to variable value */ - start += name_len + 1; - - /* Point end to the end of the value */ - value_end = (const char *) memchr(start, '&', end - start); - if (value_end == NULL) { - value_end = end; - } - - *output = start; - - return (value_end - start); - } - } - - return 0; -} -/*-----------------------------------------------------------------------------------*/ -/*- MEASSAGE SENDING ----------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -void -coap_init_connection(uint16_t port) -{ - /* new connection with remote host */ - udp_conn = udp_new(NULL, 0, NULL); - udp_bind(udp_conn, port); - PRINTF("Listening on port %u\n", uip_ntohs(udp_conn->lport)); - - /* Initialize transaction ID. */ - current_tid = random_rand(); -} -/*-----------------------------------------------------------------------------------*/ -uint16_t -coap_get_tid() -{ - ++current_tid; - PRINTF("Get TID %u\n", current_tid); - return current_tid; -} -/*-----------------------------------------------------------------------------------*/ -void -coap_send_message(uip_ipaddr_t *addr, uint16_t port, const uint8_t *data, uint16_t length) -{ - /*configure connection to reply to client*/ - uip_ipaddr_copy(&udp_conn->ripaddr, addr); - udp_conn->rport = port; - - uip_udp_packet_send(udp_conn, data, length); - PRINTF("-sent UDP datagram------\n Length: %u\n -----------------------\n", length); - - /* Restore server connection to allow data from any node */ - memset(&udp_conn->ripaddr, 0, sizeof(udp_conn->ripaddr)); - udp_conn->rport = 0; -} -/*-----------------------------------------------------------------------------------*/ -/*- MEASSAGE PROCESSING -------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -void -coap_init_message(void *packet, coap_message_type_t type, uint8_t code, uint16_t tid) -{ - memset(packet, 0, sizeof(coap_packet_t)); - - ((coap_packet_t *)packet)->type = type; - ((coap_packet_t *)packet)->code = code; - ((coap_packet_t *)packet)->tid = tid; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_serialize_message(void *packet, uint8_t *buffer) -{ - ((coap_packet_t *)packet)->buffer = buffer; - ((coap_packet_t *)packet)->version = 1; - ((coap_packet_t *)packet)->option_count = 0; - - /* serialize options */ - uint8_t *option = ((coap_packet_t *)packet)->buffer + COAP_HEADER_LEN; - size_t option_len = 0; - int index = 0; - - if (IS_OPTION((coap_packet_t *)packet, COAP_OPTION_CONTENT_TYPE)) { - ((coap_header_option_t *)option)->s.delta = 1; - ((coap_header_option_t *)option)->s.length = 1; - *(++option) = ((coap_packet_t *)packet)->content_type; - PRINTF("OPTION %u (type %u, len 1, delta %u): ", ((coap_packet_t *)packet)->option_count, COAP_OPTION_CONTENT_TYPE, COAP_OPTION_CONTENT_TYPE - index); - PRINTF("Content-Type [%u]\n", ((coap_packet_t *)packet)->content_type); - index = COAP_OPTION_CONTENT_TYPE; - option += 1; - ++(((coap_packet_t *)packet)->option_count); - } - if (IS_OPTION((coap_packet_t *)packet, COAP_OPTION_MAX_AGE)) { - option_len = uint32_2_bytes(option+1, ((coap_packet_t *)packet)->max_age); - ((coap_header_option_t *)option)->s.delta = COAP_OPTION_MAX_AGE - index; - ((coap_header_option_t *)option)->s.length = option_len; - PRINTF("OPTION %u (type %u, len %u, delta %u): ", ((coap_packet_t *)packet)->option_count, COAP_OPTION_MAX_AGE, option_len, COAP_OPTION_MAX_AGE - index); - PRINTF("Max-Age [%lu]\n", ((coap_packet_t *)packet)->max_age); - index = COAP_OPTION_MAX_AGE; - option += 1 + option_len; - ++(((coap_packet_t *)packet)->option_count); - } - if (IS_OPTION((coap_packet_t *)packet, COAP_OPTION_ETAG)) { - ((coap_header_option_t *)option)->s.delta = COAP_OPTION_ETAG - index; - ((coap_header_option_t *)option)->s.length = ((coap_packet_t *)packet)->etag_len; - memcpy(++option, ((coap_packet_t *)packet)->etag, ((coap_packet_t *)packet)->etag_len); - PRINTF("OPTION %u (type %u, len %u, delta %u): ", ((coap_packet_t *)packet)->option_count, COAP_OPTION_ETAG, ((coap_packet_t *)packet)->etag_len, COAP_OPTION_ETAG - index); - PRINTF("ETag %u [0x%02X", ((coap_packet_t *)packet)->etag_len, ((coap_packet_t *)packet)->etag[0]); /*FIXME always prints 4 bytes */ - PRINTF("%02X", ((coap_packet_t *)packet)->etag[1]); - PRINTF("%02X", ((coap_packet_t *)packet)->etag[2]); - PRINTF("%02X", ((coap_packet_t *)packet)->etag[3]); - PRINTF("]\n"); - index = COAP_OPTION_ETAG; - option += ((coap_packet_t *)packet)->etag_len; - ++(((coap_packet_t *)packet)->option_count); - } - if (IS_OPTION((coap_packet_t *)packet, COAP_OPTION_URI_HOST)) { - if (((coap_packet_t *)packet)->uri_host_len<15) { - ((coap_header_option_t *)option)->s.delta = COAP_OPTION_URI_HOST - index; - ((coap_header_option_t *)option)->s.length = ((coap_packet_t *)packet)->uri_host_len; - option += 1; - } else { - ((coap_header_option_t *)option)->l.delta = COAP_OPTION_URI_HOST - index; - ((coap_header_option_t *)option)->s.length = 15; - ((coap_header_option_t *)option)->l.length = ((coap_packet_t *)packet)->uri_host_len - 15; - option += 2; - } - memcpy(option, ((coap_packet_t *)packet)->uri_host, ((coap_packet_t *)packet)->uri_host_len); - PRINTF("OPTION %u (type %u, len %u, delta %u): ", ((coap_packet_t *)packet)->option_count, COAP_OPTION_URI_HOST, ((coap_packet_t *)packet)->uri_host_len, COAP_OPTION_URI_HOST - index); - PRINTF("Uri-Auth [%.*s]\n", ((coap_packet_t *)packet)->uri_host_len, ((coap_packet_t *)packet)->uri_host); - index = COAP_OPTION_URI_HOST; - option += ((coap_packet_t *)packet)->uri_host_len; - ++(((coap_packet_t *)packet)->option_count); - } - if (IS_OPTION((coap_packet_t *)packet, COAP_OPTION_LOCATION_PATH)) { - if (((coap_packet_t *)packet)->location_path_len<15) { - ((coap_header_option_t *)option)->s.delta = COAP_OPTION_LOCATION_PATH - index; - ((coap_header_option_t *)option)->s.length = ((coap_packet_t *)packet)->location_path_len; - option += 1; - } else { - ((coap_header_option_t *)option)->l.delta = COAP_OPTION_LOCATION_PATH - index; - ((coap_header_option_t *)option)->s.length = 15; - ((coap_header_option_t *)option)->l.length = ((coap_packet_t *)packet)->location_path_len - 15; - option += 2; - } - memcpy(option, ((coap_packet_t *)packet)->location_path, ((coap_packet_t *)packet)->location_path_len); - PRINTF("OPTION %u (type %u, len %u, delta %u): ", ((coap_packet_t *)packet)->option_count, COAP_OPTION_LOCATION_PATH, ((coap_packet_t *)packet)->location_path_len, COAP_OPTION_LOCATION_PATH - index); - PRINTF("Location [%.*s]\n", ((coap_packet_t *)packet)->location_path_len, ((coap_packet_t *)packet)->location_path); - index = COAP_OPTION_LOCATION_PATH; - option += ((coap_packet_t *)packet)->location_path_len; - ++(((coap_packet_t *)packet)->option_count); - } - if (IS_OPTION((coap_packet_t *)packet, COAP_OPTION_URI_PATH)) { - if (((coap_packet_t *)packet)->uri_path_len<15) { - ((coap_header_option_t *)option)->s.delta = COAP_OPTION_URI_PATH - index; - ((coap_header_option_t *)option)->s.length = ((coap_packet_t *)packet)->uri_path_len; - option += 1; - } else { - ((coap_header_option_t *)option)->l.delta = COAP_OPTION_URI_PATH - index; - ((coap_header_option_t *)option)->s.length = 15; - ((coap_header_option_t *)option)->l.length = ((coap_packet_t *)packet)->uri_path_len - 15; - option += 2; - } - memcpy(option, ((coap_packet_t *)packet)->uri_path, ((coap_packet_t *)packet)->uri_path_len); - PRINTF("OPTION %u (type %u, len %u, delta %u): ", ((coap_packet_t *)packet)->option_count, COAP_OPTION_URI_PATH, ((coap_packet_t *)packet)->uri_path_len, COAP_OPTION_URI_PATH - index); - PRINTF("Uri-Path [%.*s]\n", ((coap_packet_t *)packet)->uri_path_len, ((coap_packet_t *)packet)->uri_path); - index = COAP_OPTION_URI_PATH; - option += ((coap_packet_t *)packet)->uri_path_len; - ++(((coap_packet_t *)packet)->option_count); - } - if (IS_OPTION((coap_packet_t *)packet, COAP_OPTION_OBSERVE)) { - option_len = uint32_2_bytes(option+1, ((coap_packet_t *)packet)->observe); - ((coap_header_option_t *)option)->s.delta = COAP_OPTION_OBSERVE - index; - ((coap_header_option_t *)option)->s.length = option_len; - PRINTF("OPTION %u (type %u, len %u, delta %u): ", ((coap_packet_t *)packet)->option_count, COAP_OPTION_OBSERVE, option_len, COAP_OPTION_OBSERVE - index); - PRINTF("Observe [%lu]\n", ((coap_packet_t *)packet)->observe); - index = COAP_OPTION_OBSERVE; - option += 1 + option_len; - ++(((coap_packet_t *)packet)->option_count); - } - if (IS_OPTION((coap_packet_t *)packet, COAP_OPTION_TOKEN)) { - ((coap_header_option_t *)option)->s.delta = COAP_OPTION_TOKEN - index; - ((coap_header_option_t *)option)->s.length = ((coap_packet_t *)packet)->token_len; - memcpy(++option, ((coap_packet_t *)packet)->token, ((coap_packet_t *)packet)->token_len); - PRINTF("OPTION %u (type %u, len %u, delta %u): ", ((coap_packet_t *)packet)->option_count, COAP_OPTION_TOKEN, ((coap_packet_t *)packet)->token_len, COAP_OPTION_TOKEN - index); - PRINTF("Token %u [0x%02X%02X]\n", ((coap_packet_t *)packet)->token_len, ((coap_packet_t *)packet)->token[0], ((coap_packet_t *)packet)->token[1]); /*FIXME always prints 2 bytes */ - index = COAP_OPTION_TOKEN; - option += ((coap_packet_t *)packet)->token_len; - ++(((coap_packet_t *)packet)->option_count); - } - if (IS_OPTION((coap_packet_t *)packet, COAP_OPTION_BLOCK)) { - uint32_t block = ((coap_packet_t *)packet)->block_num << 4; - if (((coap_packet_t *)packet)->block_more) block |= 0x8; - block |= 0xF & log_2(((coap_packet_t *)packet)->block_size/16); - option_len = uint32_2_bytes(option+1, block); - ((coap_header_option_t *)option)->s.delta = COAP_OPTION_BLOCK - index; - ((coap_header_option_t *)option)->s.length = option_len; - PRINTF("OPTION %u (type %u, len %u, delta %u): ", ((coap_packet_t *)packet)->option_count, COAP_OPTION_BLOCK, option_len, COAP_OPTION_BLOCK - index); - PRINTF("Block [%lu%s (%u B/blk)]\n", ((coap_packet_t *)packet)->block_num, ((coap_packet_t *)packet)->block_more ? "+" : "", ((coap_packet_t *)packet)->block_size); - index = COAP_OPTION_BLOCK; - option += 1 + option_len; - ++(((coap_packet_t *)packet)->option_count); - } - if (IS_OPTION((coap_packet_t *)packet, COAP_OPTION_URI_QUERY)) { - if (((coap_packet_t *)packet)->uri_query_len<15) { - ((coap_header_option_t *)option)->s.delta = COAP_OPTION_URI_QUERY - index; - ((coap_header_option_t *)option)->s.length = ((coap_packet_t *)packet)->uri_query_len; - option += 1; - } else { - ((coap_header_option_t *)option)->l.delta = COAP_OPTION_URI_QUERY - index; - ((coap_header_option_t *)option)->s.length = 15; - ((coap_header_option_t *)option)->l.length = ((coap_packet_t *)packet)->uri_query_len - 15; - option += 2; - } - memcpy(option, ((coap_packet_t *)packet)->uri_query, ((coap_packet_t *)packet)->uri_query_len); - PRINTF("OPTION %u (type %u, len %u, delta %u): ", ((coap_packet_t *)packet)->option_count, COAP_OPTION_URI_QUERY, ((coap_packet_t *)packet)->uri_query_len, COAP_OPTION_URI_QUERY - index); - PRINTF("Uri-Query [%.*s]\n", ((coap_packet_t *)packet)->uri_query_len, ((coap_packet_t *)packet)->uri_query); - index = COAP_OPTION_URI_QUERY; - option += ((coap_packet_t *)packet)->uri_query_len; - ++(((coap_packet_t *)packet)->option_count); - } - - /* pack payload */ - if ((option - ((coap_packet_t *)packet)->buffer)<=COAP_MAX_HEADER_SIZE) - { - memmove(option, ((coap_packet_t *)packet)->payload, ((coap_packet_t *)packet)->payload_len); - } - else - { - /* An error occured. Caller must check for !=0. */ - return 0; - } - - /* set header fields */ - ((coap_packet_t *)packet)->buffer[0] = 0x00; - ((coap_packet_t *)packet)->buffer[0] |= COAP_HEADER_VERSION_MASK & (((coap_packet_t *)packet)->version)<buffer[0] |= COAP_HEADER_TYPE_MASK & (((coap_packet_t *)packet)->type)<buffer[0] |= COAP_HEADER_OPTION_COUNT_MASK & (((coap_packet_t *)packet)->option_count)<buffer[1] = ((coap_packet_t *)packet)->code; - ((coap_packet_t *)packet)->buffer[2] = 0xFF & (((coap_packet_t *)packet)->tid)>>8; - ((coap_packet_t *)packet)->buffer[3] = 0xFF & ((coap_packet_t *)packet)->tid; - - PRINTF("Serialized %u options, header len %u, payload len %u\n", ((coap_packet_t *)packet)->option_count, option - ((coap_packet_t *)packet)->buffer, ((coap_packet_t *)packet)->payload_len); - - return (option - ((coap_packet_t *)packet)->buffer) + ((coap_packet_t *)packet)->payload_len; /* packet length */ -} -/*-----------------------------------------------------------------------------------*/ -error_t -coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) -{ - /* Initialize packet */ - memset(packet, 0, sizeof(coap_packet_t)); - - /* pointer to packet bytes */ - ((coap_packet_t *)packet)->buffer = data; - - /* parse header fields */ - ((coap_packet_t *)packet)->version = (COAP_HEADER_VERSION_MASK & ((coap_packet_t *)packet)->buffer[0])>>COAP_HEADER_VERSION_POSITION; - ((coap_packet_t *)packet)->type = (COAP_HEADER_TYPE_MASK & ((coap_packet_t *)packet)->buffer[0])>>COAP_HEADER_TYPE_POSITION; - ((coap_packet_t *)packet)->option_count = (COAP_HEADER_OPTION_COUNT_MASK & ((coap_packet_t *)packet)->buffer[0])>>COAP_HEADER_OPTION_COUNT_POSITION; - ((coap_packet_t *)packet)->code = ((coap_packet_t *)packet)->buffer[1]; - ((coap_packet_t *)packet)->tid = ((coap_packet_t *)packet)->buffer[2]<<8 | ((coap_packet_t *)packet)->buffer[3]; - - /* parse options */ - ((coap_packet_t *)packet)->options = 0x0000; - coap_header_option_t *current_option = (coap_header_option_t *) (data + COAP_HEADER_LEN); - - if (((coap_packet_t *)packet)->option_count) { - uint8_t option_index = 0; - uint8_t option_type = 0; - - uint16_t option_len = 0; - uint8_t *option_data = NULL; - - uint8_t *last_option = NULL; - - for (option_index=0; option_index < ((coap_packet_t *)packet)->option_count; ++option_index) { - - option_type += current_option->s.delta; - - if (current_option->s.length<15) { - option_len = current_option->s.length; - option_data = ((uint8_t *) current_option) + 1; - } else { - option_len = current_option->l.length + 15; - option_data = ((uint8_t *) current_option) + 2; - } - - PRINTF("OPTION %u (type %u, len %u, delta %u): ", option_index, option_type, option_len, current_option->s.delta); - - SET_OPTION((coap_packet_t *)packet, option_type); - - switch (option_type) { - case COAP_OPTION_CONTENT_TYPE: - ((coap_packet_t *)packet)->content_type = option_data[0]; - PRINTF("Content-Type [%u]\n", ((coap_packet_t *)packet)->content_type); - break; - case COAP_OPTION_MAX_AGE: - ((coap_packet_t *)packet)->max_age = bytes_2_uint32(option_data, option_len); - PRINTF("Max-Age [%lu]\n", ((coap_packet_t *)packet)->max_age); - break; - case COAP_OPTION_ETAG: - ((coap_packet_t *)packet)->etag_len = MIN(COAP_ETAG_LEN, option_len); - memcpy(((coap_packet_t *)packet)->etag, option_data, ((coap_packet_t *)packet)->etag_len); - PRINTF("ETag %u [0x%02X", ((coap_packet_t *)packet)->etag_len, ((coap_packet_t *)packet)->etag[0]); /*FIXME always prints 4 bytes */ - PRINTF("%02X", ((coap_packet_t *)packet)->etag[1]); - PRINTF("%02X", ((coap_packet_t *)packet)->etag[2]); - PRINTF("%02X", ((coap_packet_t *)packet)->etag[3]); - PRINTF("]\n"); - break; - case COAP_OPTION_URI_HOST: - ((coap_packet_t *)packet)->uri_host = (char *) option_data; - ((coap_packet_t *)packet)->uri_host_len = option_len; - PRINTF("Uri-Auth [%.*s]\n", ((coap_packet_t *)packet)->uri_host_len, ((coap_packet_t *)packet)->uri_host); - break; - case COAP_OPTION_LOCATION_PATH: - ((coap_packet_t *)packet)->location_path = (char *) option_data; - ((coap_packet_t *)packet)->location_path_len = option_len; - PRINTF("Location [%.*s]\n", ((coap_packet_t *)packet)->location_path_len, ((coap_packet_t *)packet)->location_path); - break; - case COAP_OPTION_URI_PATH: - ((coap_packet_t *)packet)->uri_path = (char *) option_data; - ((coap_packet_t *)packet)->uri_path_len = option_len; - PRINTF("Uri-Path [%.*s]\n", ((coap_packet_t *)packet)->uri_path_len, ((coap_packet_t *)packet)->uri_path); - break; - case COAP_OPTION_OBSERVE: - ((coap_packet_t *)packet)->observe = bytes_2_uint32(option_data, option_len); - PRINTF("Observe [%lu]\n", ((coap_packet_t *)packet)->observe); - break; - case COAP_OPTION_TOKEN: - ((coap_packet_t *)packet)->token_len = MIN(COAP_TOKEN_LEN, option_len); - memcpy(((coap_packet_t *)packet)->token, option_data, ((coap_packet_t *)packet)->token_len); - PRINTF("Token %u [0x%02X%02X]\n", ((coap_packet_t *)packet)->token_len, ((coap_packet_t *)packet)->token[0], ((coap_packet_t *)packet)->token[1]); /*FIXME always prints 2 bytes */ - break; - case COAP_OPTION_BLOCK: - ((coap_packet_t *)packet)->block_num = bytes_2_uint32(option_data, option_len); - ((coap_packet_t *)packet)->block_more = (((coap_packet_t *)packet)->block_num & 0x08)>>3; - ((coap_packet_t *)packet)->block_size = 16 << (((coap_packet_t *)packet)->block_num & 0x07); - ((coap_packet_t *)packet)->block_offset = (((coap_packet_t *)packet)->block_num & ~0x0F)<<(((coap_packet_t *)packet)->block_num & 0x07); - ((coap_packet_t *)packet)->block_num >>= 4; - PRINTF("Block [%lu%s (%u B/blk)]\n", ((coap_packet_t *)packet)->block_num, ((coap_packet_t *)packet)->block_more ? "+" : "", ((coap_packet_t *)packet)->block_size); - break; - case COAP_OPTION_NOOP: - PRINTF("Noop-Fencepost\n"); - break; - case COAP_OPTION_URI_QUERY: - ((coap_packet_t *)packet)->uri_query = (char *) option_data; - ((coap_packet_t *)packet)->uri_query_len = option_len; - PRINTF("Uri-Query [%.*s]\n", ((coap_packet_t *)packet)->uri_query_len, ((coap_packet_t *)packet)->uri_query); - break; - default: - PRINTF("unknown (%u)\n", option_type); - if (option_type & 1) - { - return UNKNOWN_CRITICAL_OPTION; - } - } - - /* terminate strings where possible */ - if (last_option) { - last_option[0] = 0x00; - } - - last_option = (uint8_t *) current_option; - current_option = (coap_header_option_t *) (option_data+option_len); - } /* for () */ - } /* if (oc) */ - - ((coap_packet_t *)packet)->payload = (uint8_t *) current_option; - ((coap_packet_t *)packet)->payload_len = data_len - (((coap_packet_t *)packet)->payload - data); - - return NO_ERROR; -} -/*-----------------------------------------------------------------------------------*/ -/*- REST FRAMEWORK FUNCTIONS --------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -int -coap_get_query_variable(void *packet, const char *name, const char **output) -{ - if (IS_OPTION((coap_packet_t *)packet, COAP_OPTION_URI_QUERY)) { - return coap_get_variable(((coap_packet_t *)packet)->uri_query, ((coap_packet_t *)packet)->uri_query_len, name, output); - } - return 0; -} - -int -coap_get_post_variable(void *packet, const char *name, const char **output) -{ - if (((coap_packet_t *)packet)->payload_len) { - return coap_get_variable((const char *)((coap_packet_t *)packet)->payload, ((coap_packet_t *)packet)->payload_len, name, output); - } - return 0; -} -/*-----------------------------------------------------------------------------------*/ -/*- HEADER OPTION GETTERS AND SETTERS -----------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -unsigned int -coap_get_header_content_type(void *packet) -{ - return ((coap_packet_t *)packet)->content_type; -} - -int -coap_set_header_content_type(void *packet, unsigned int content_type) -{ - ((coap_packet_t *)packet)->content_type = (coap_content_type_t) content_type; - SET_OPTION((coap_packet_t *)packet, COAP_OPTION_CONTENT_TYPE); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_max_age(void *packet, uint32_t *age) -{ - if (!IS_OPTION((coap_packet_t *)packet, COAP_OPTION_MAX_AGE)) { - *age = COAP_DEFAULT_MAX_AGE; - } else { - *age = ((coap_packet_t *)packet)->max_age; - } - return 1; -} - -int -coap_set_header_max_age(void *packet, uint32_t age) -{ - ((coap_packet_t *)packet)->max_age = age; - SET_OPTION((coap_packet_t *)packet, COAP_OPTION_MAX_AGE); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_etag(void *packet, const uint8_t **etag) -{ - if (!IS_OPTION((coap_packet_t *)packet, COAP_OPTION_ETAG)) return 0; - - *etag = ((coap_packet_t *)packet)->etag; - return ((coap_packet_t *)packet)->etag_len; -} - -int -coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len) -{ - ((coap_packet_t *)packet)->etag_len = MIN(COAP_ETAG_LEN, etag_len); - memcpy(((coap_packet_t *)packet)->etag, etag, ((coap_packet_t *)packet)->etag_len); - - SET_OPTION((coap_packet_t *)packet, COAP_OPTION_ETAG); - return ((coap_packet_t *)packet)->etag_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_uri_host(void *packet, const char **host) -{ - if (!IS_OPTION((coap_packet_t *)packet, COAP_OPTION_URI_HOST)) return 0; - - *host = ((coap_packet_t *)packet)->uri_host; - return ((coap_packet_t *)packet)->uri_host_len; -} - -int -coap_set_header_uri_host(void *packet, const char *host) -{ - ((coap_packet_t *)packet)->uri_host = host; - ((coap_packet_t *)packet)->uri_host_len = strlen(host); - - SET_OPTION((coap_packet_t *)packet, COAP_OPTION_URI_HOST); - return ((coap_packet_t *)packet)->uri_host_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_location(void *packet, const char **location) -{ - if (!IS_OPTION((coap_packet_t *)packet, COAP_OPTION_LOCATION_PATH)) return 0; - - *location = ((coap_packet_t *)packet)->location_path; - return ((coap_packet_t *)packet)->location_path_len; -} - -int -coap_set_header_location(void *packet, const char *location) -{ - while (location[0]=='/') ++location; - - ((coap_packet_t *)packet)->location_path = location; - ((coap_packet_t *)packet)->location_path_len = strlen(location); - - SET_OPTION((coap_packet_t *)packet, COAP_OPTION_LOCATION_PATH); - return ((coap_packet_t *)packet)->location_path_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_uri_path(void *packet, const char **path) -{ - if (!IS_OPTION((coap_packet_t *)packet, COAP_OPTION_URI_PATH)) return 0; - - *path = ((coap_packet_t *)packet)->uri_path; - return ((coap_packet_t *)packet)->uri_path_len; -} - -int -coap_set_header_uri_path(void *packet, const char *path) -{ - while (path[0]=='/') ++path; - - ((coap_packet_t *)packet)->uri_path = path; - ((coap_packet_t *)packet)->uri_path_len = strlen(path); - - SET_OPTION((coap_packet_t *)packet, COAP_OPTION_URI_PATH); - return ((coap_packet_t *)packet)->uri_path_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_observe(void *packet, uint32_t *observe) -{ - if (!IS_OPTION((coap_packet_t *)packet, COAP_OPTION_OBSERVE)) return 0; - - *observe = ((coap_packet_t *)packet)->observe; - return 1; -} - -int -coap_set_header_observe(void *packet, uint32_t observe) -{ - ((coap_packet_t *)packet)->observe = observe; - SET_OPTION((coap_packet_t *)packet, COAP_OPTION_OBSERVE); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_token(void *packet, const uint8_t **token) -{ - if (!IS_OPTION((coap_packet_t *)packet, COAP_OPTION_TOKEN)) return 0; - - *token = ((coap_packet_t *)packet)->token; - return ((coap_packet_t *)packet)->token_len; -} - -int -coap_set_header_token(void *packet, const uint8_t *token, size_t token_len) -{ - ((coap_packet_t *)packet)->token_len = MIN(COAP_TOKEN_LEN, token_len); - memcpy(((coap_packet_t *)packet)->token, token, ((coap_packet_t *)packet)->token_len); - - SET_OPTION((coap_packet_t *)packet, COAP_OPTION_TOKEN); - return ((coap_packet_t *)packet)->token_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_block(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset) -{ - if (!IS_OPTION((coap_packet_t *)packet, COAP_OPTION_BLOCK)) return 0; - - /* pointers may be NULL to get only specific block parameters */ - if (num!=NULL) *num = ((coap_packet_t *)packet)->block_num; - if (more!=NULL) *more = ((coap_packet_t *)packet)->block_more; - if (size!=NULL) *size = ((coap_packet_t *)packet)->block_size; - if (offset!=NULL) *offset = ((coap_packet_t *)packet)->block_offset; - - return 1; -} - -int -coap_set_header_block(void *packet, uint32_t num, uint8_t more, uint16_t size) -{ - if (size<16) return 0; - if (size>2048) return 0; - if (num>0x0FFFFF) return 0; - - ((coap_packet_t *)packet)->block_num = num; - ((coap_packet_t *)packet)->block_more = more; - ((coap_packet_t *)packet)->block_size = size; - - SET_OPTION((coap_packet_t *)packet, COAP_OPTION_BLOCK); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_uri_query(void *packet, const char **query) -{ - if (!IS_OPTION((coap_packet_t *)packet, COAP_OPTION_URI_QUERY)) return 0; - - *query = ((coap_packet_t *)packet)->uri_query; - return ((coap_packet_t *)packet)->uri_query_len; -} - -int -coap_set_header_uri_query(void *packet, const char *query) -{ - while (query[0]=='?') ++query; - - ((coap_packet_t *)packet)->uri_query = query; - ((coap_packet_t *)packet)->uri_query_len = strlen(query); - - SET_OPTION((coap_packet_t *)packet, COAP_OPTION_URI_QUERY); - return ((coap_packet_t *)packet)->uri_query_len; -} -/*-----------------------------------------------------------------------------------*/ -/*- PAYLOAD -------------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -int -coap_get_payload(void *packet, const uint8_t **payload) -{ - if (((coap_packet_t *)packet)->payload) { - *payload = ((coap_packet_t *)packet)->payload; - return ((coap_packet_t *)packet)->payload_len; - } else { - *payload = NULL; - return 0; - } -} - -int -coap_set_payload(void *packet, const void *payload, size_t length) -{ - PRINTF("setting payload (%u/%u)\n", length, REST_MAX_CHUNK_SIZE); - - ((coap_packet_t *)packet)->payload = (uint8_t *) payload; - ((coap_packet_t *)packet)->payload_len = MIN(REST_MAX_CHUNK_SIZE, length); - - return ((coap_packet_t *)packet)->payload_len; -} -/*-----------------------------------------------------------------------------------*/ diff --git a/apps/er-coap-03/er-coap-03.h b/apps/er-coap-03/er-coap-03.h deleted file mode 100644 index fb69bd63a..000000000 --- a/apps/er-coap-03/er-coap-03.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * An implementation of the Constrained Application Protocol (draft 03) - * \author - * Matthias Kovatsch - */ - -#ifndef COAP_03_H_ -#define COAP_03_H_ - -#include /* for size_t */ -#include "contiki-net.h" -#include "erbium.h" - -#define COAP_DEFAULT_PORT 61616 - -#ifndef COAP_SERVER_PORT -#define COAP_SERVER_PORT COAP_DEFAULT_PORT -#endif - -#define COAP_DEFAULT_MAX_AGE 60 -#define COAP_RESPONSE_TIMEOUT 1 -#define COAP_MAX_RETRANSMIT 5 - -#define COAP_HEADER_LEN 4 /* | oc:0xF0 type:0x0C version:0x03 | code | tid:0x00FF | tid:0xFF00 | */ -#define COAP_ETAG_LEN 4 /* The maximum number of bytes for the ETag, which is 4 for coap-03 */ -#define COAP_TOKEN_LEN 2 /* The maximum number of bytes for the ETag, which is 4 for coap-03 */ - -#define COAP_HEADER_VERSION_MASK 0xC0 -#define COAP_HEADER_VERSION_POSITION 6 -#define COAP_HEADER_TYPE_MASK 0x30 -#define COAP_HEADER_TYPE_POSITION 4 -#define COAP_HEADER_OPTION_COUNT_MASK 0x0F -#define COAP_HEADER_OPTION_COUNT_POSITION 0 - -#define COAP_HEADER_OPTION_DELTA_MASK 0xF0 -#define COAP_HEADER_OPTION_SHORT_LENGTH_MASK 0x0F - -/* - * Conservative size limit, as not all options have to be set at the same time. - */ -/* Hdr CoT Age Tag Obs Tok Blo strings */ -#define COAP_MAX_HEADER_SIZE (4 + 2 + 5 + 5 + 5 + 5 + 4 + 0) -#define COAP_MAX_PACKET_SIZE (COAP_MAX_HEADER_SIZE + REST_MAX_CHUNK_SIZE) -/* 0/14 48 for IPv6 (28 for IPv4) */ -#if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN) -#error "UIP_CONF_BUFFER_SIZE too small for REST_MAX_CHUNK_SIZE" -#endif - -/* - * Maximum number of failed request attempts before action - */ -#ifndef COAP_MAX_ATTEMPTS -#define COAP_MAX_ATTEMPTS 4 -#endif /* COAP_MAX_ATTEMPTS */ - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN]) - -#define SET_OPTION(packet, opt) ((packet)->options |= 1<options & 1< - */ - -#include -#include -#include -#include "contiki.h" -#include "contiki-net.h" - -#include "er-coap-07-engine.h" - -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#define PRINTBITS(buf,len) { \ - int i,j=0; \ - for (i=0; i=0; --j) { \ - PRINTF("%c", (((char *)buf)[i] & 1<srcipaddr); - PRINTF(":%u\n Length: %u\n Data: ", uip_ntohs(UIP_UDP_BUF->srcport), uip_datalen() ); - PRINTBITS(uip_appdata, uip_datalen()); - PRINTF("\n"); - - coap_error_code = coap_parse_message(message, uip_appdata, uip_datalen()); - - if (coap_error_code==NO_ERROR) - { - - /*TODO duplicates suppression, if required by application */ - - PRINTF(" Parsed: v %u, t %u, oc %u, c %u, mid %u\n", message->version, message->type, message->option_count, message->code, message->mid); - PRINTF(" URL: %.*s\n", message->uri_path_len, message->uri_path); - PRINTF(" Payload: %.*s\n", message->payload_len, message->payload); - - /* Handle requests. */ - if (message->code >= COAP_GET && message->code <= COAP_DELETE) - { - /* Use transaction buffer for response to confirmable request. */ - if ( (transaction = coap_new_transaction(message->mid, &UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport)) ) - { - uint32_t block_num = 0; - uint16_t block_size = REST_MAX_CHUNK_SIZE; - uint32_t block_offset = 0; - int32_t new_offset = 0; - - /* prepare response */ - if (message->type==COAP_TYPE_CON) - { - /* Reliable CON requests are answered with an ACK. */ - coap_init_message(response, COAP_TYPE_ACK, CONTENT_2_05, message->mid); - } - else - { - /* Unreliable NON requests are answered with a NON as well. */ - coap_init_message(response, COAP_TYPE_NON, CONTENT_2_05, coap_get_mid()); - } - - /* resource handlers must take care of different handling (e.g., TOKEN_OPTION_REQUIRED_240) */ - if (IS_OPTION(message, COAP_OPTION_TOKEN)) - { - coap_set_header_token(response, message->token, message->token_len); - SET_OPTION(response, COAP_OPTION_TOKEN); - } - - /* get offset for blockwise transfers */ - if (coap_get_header_block2(message, &block_num, NULL, &block_size, &block_offset)) - { - PRINTF("Blockwise: block request %lu (%u/%u) @ %lu bytes\n", block_num, block_size, REST_MAX_CHUNK_SIZE, block_offset); - block_size = MIN(block_size, REST_MAX_CHUNK_SIZE); - new_offset = block_offset; - } - - /* Invoke resource handler. */ - if (service_cbk) - { - /* Call REST framework and check if found and allowed. */ - if (service_cbk(message, response, transaction->packet+COAP_MAX_HEADER_SIZE, block_size, &new_offset)) - { - if (coap_error_code==NO_ERROR) - { - /* Apply blockwise transfers. */ - if ( IS_OPTION(message, COAP_OPTION_BLOCK1) && response->codepayload_len, block_size); - if (block_offset >= response->payload_len) - { - PRINTF("handle_incoming_data(): block_offset >= response->payload_len\n"); - - response->code = BAD_OPTION_4_02; - coap_set_payload(response, "BlockOutOfScope", 15); /* a const char str[] and sizeof(str) produces larger code size */ - } - else - { - coap_set_header_block2(response, block_num, response->payload_len - block_offset > block_size, block_size); - coap_set_payload(response, response->payload+block_offset, MIN(response->payload_len - block_offset, block_size)); - } /* if (valid offset) */ - } - else - { - /* resource provides chunk-wise data */ - PRINTF("Blockwise: blockwise resource, new offset %ld\n", new_offset); - coap_set_header_block2(response, block_num, new_offset!=-1 || response->payload_len > block_size, block_size); - if (response->payload_len > block_size) coap_set_payload(response, response->payload, block_size); - } /* if (resource aware of blockwise) */ - } - else if (new_offset!=0) - { - PRINTF("Blockwise: no block option for blockwise resource, using block size %u\n", REST_MAX_CHUNK_SIZE); - - coap_set_header_block2(response, 0, new_offset!=-1, REST_MAX_CHUNK_SIZE); - coap_set_payload(response, response->payload, MIN(response->payload_len, REST_MAX_CHUNK_SIZE)); - } /* if (blockwise request) */ - } /* no errors/hooks */ - } /* successful service callback */ - - /* Serialize response. */ - if (coap_error_code==NO_ERROR) - { - if ((transaction->packet_len = coap_serialize_message(response, transaction->packet))==0) - { - coap_error_code = PACKET_SERIALIZATION_ERROR; - } - } - - } - else - { - coap_error_code = NOT_IMPLEMENTED_5_01; - coap_error_message = "NoServiceCallbck"; // no a to fit 16 bytes - } /* if (service callback) */ - - } else { - coap_error_code = SERVICE_UNAVAILABLE_5_03; - coap_error_message = "NoFreeTraBuffer"; - } /* if (transaction buffer) */ - } - else - { - /* Responses */ - - if (message->type==COAP_TYPE_ACK) - { - PRINTF("Received ACK\n"); - } - else if (message->type==COAP_TYPE_RST) - { - PRINTF("Received RST\n"); - /* Cancel possible subscriptions. */ - coap_remove_observer_by_mid(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, message->mid); - } - - if ( (transaction = coap_get_transaction_by_mid(message->mid)) ) - { - /* Free transaction memory before callback, as it may create a new transaction. */ - restful_response_handler callback = transaction->callback; - void *callback_data = transaction->callback_data; - coap_clear_transaction(transaction); - - /* Check if someone registered for the response */ - if (callback) { - callback(callback_data, message); - } - } /* if (ACKed transaction) */ - transaction = NULL; - - } /* Request or Response */ - - } /* if (parsed correctly) */ - - if (coap_error_code==NO_ERROR) - { - if (transaction) coap_send_transaction(transaction); - } - else if (coap_error_code==MANUAL_RESPONSE) - { - PRINTF("Clearing transaction for manual response"); - coap_clear_transaction(transaction); - } - else - { - PRINTF("ERROR %u: %s\n", coap_error_code, coap_error_message); - coap_clear_transaction(transaction); - - /* Set to sendable error code. */ - if (coap_error_code >= 192) - { - coap_error_code = INTERNAL_SERVER_ERROR_5_00; - } - /* Reuse input buffer for error message. */ - coap_init_message(message, COAP_TYPE_ACK, coap_error_code, message->mid); - coap_set_payload(message, coap_error_message, strlen(coap_error_message)); - coap_send_message(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, uip_appdata, coap_serialize_message(message, uip_appdata)); - } - } /* if (new data) */ - - return coap_error_code; -} -/*----------------------------------------------------------------------------*/ -void -coap_receiver_init() -{ - process_start(&coap_receiver, NULL); -} -/*----------------------------------------------------------------------------*/ -void -coap_set_service_callback(service_callback_t callback) -{ - service_cbk = callback; -} -/*----------------------------------------------------------------------------*/ -rest_resource_flags_t -coap_get_rest_method(void *packet) -{ - return (rest_resource_flags_t)(1 << (((coap_packet_t *)packet)->code - 1)); -} -/*----------------------------------------------------------------------------*/ -/*- Server part --------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ - -/* The discover resource is automatically included for CoAP. */ -RESOURCE(well_known_core, METHOD_GET, ".well-known/core", "ct=40"); -void -well_known_core_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - size_t strpos = 0; /* position in overall string (which is larger than the buffer) */ - size_t bufpos = 0; /* position within buffer (bytes written) */ - size_t tmplen = 0; - resource_t* resource = NULL; - - /* For filtering. */ - const char *filter = NULL; - int len = coap_get_query_variable(request, "rt", &filter); - char *rt = NULL; - - for (resource = (resource_t*)list_head(rest_get_resources()); resource; resource = resource->next) - { - /* Filtering */ - if (len && ((rt=strstr(resource->attributes, "rt=\""))==NULL || memcmp(rt+4, filter, len-1)!=0 || (filter[len-1]!='*' && (filter[len-1]!=rt[3+len] || rt[4+len]!='"')))) - { - continue; - } - - PRINTF("res: /%s (%p)\npos: s%d, o%d, b%d\n", resource->url, resource, strpos, *offset, bufpos); - - if (strpos >= *offset && bufpos < preferred_size) - { - buffer[bufpos++] = '<'; - } - ++strpos; - - if (strpos >= *offset && bufpos < preferred_size) - { - buffer[bufpos++] = '/'; - } - ++strpos; - - tmplen = strlen(resource->url); - if (strpos+tmplen > *offset) - { - bufpos += snprintf((char *) buffer + bufpos, preferred_size - bufpos + 1, - "%s", resource->url + ((*offset-(int32_t)strpos > 0) ? (*offset-(int32_t)strpos) : 0)); - /* minimal-net requires these casts */ - if (bufpos >= preferred_size) - { - break; - } - } - strpos += tmplen; - - if (strpos >= *offset && bufpos < preferred_size) - { - buffer[bufpos++] = '>'; - } - ++strpos; - - if (resource->attributes[0]) - { - if (strpos >= *offset && bufpos < preferred_size) - { - buffer[bufpos++] = ';'; - } - ++strpos; - - tmplen = strlen(resource->attributes); - if (strpos+tmplen > *offset) - { - bufpos += snprintf((char *) buffer + bufpos, preferred_size - bufpos + 1, - "%s", resource->attributes + (*offset-(int32_t)strpos > 0 ? *offset-(int32_t)strpos : 0)); - if (bufpos >= preferred_size) - { - break; - } - } - strpos += tmplen; - } - - if (resource->next) - { - if (strpos >= *offset && bufpos < preferred_size) - { - buffer[bufpos++] = ','; - } - ++strpos; - } - - /* buffer full, but resource not completed yet; or: do not break if resource exactly fills buffer. */ - if (bufpos >= preferred_size && strpos-bufpos > *offset) - { - PRINTF("res: BREAK at %s (%p)\n", resource->url, resource); - break; - } - } - - if (bufpos>0) { - PRINTF("BUF %d: %.*s\n", bufpos, bufpos, (char *) buffer); - - coap_set_payload(response, buffer, bufpos ); - coap_set_header_content_type(response, APPLICATION_LINK_FORMAT); - } - else if (strpos>0) - { - PRINTF("well_known_core_handler(): bufpos<=0\n"); - - coap_set_status_code(response, BAD_OPTION_4_02); - coap_set_payload(response, "BlockOutOfScope", 15); - } - - if (resource==NULL) { - PRINTF("res: DONE\n"); - *offset = -1; - } - else - { - PRINTF("res: MORE at %s (%p)\n", resource->url, resource); - *offset += preferred_size; - } -} -/*----------------------------------------------------------------------------*/ -PROCESS_THREAD(coap_receiver, ev, data) -{ - PROCESS_BEGIN(); - PRINTF("Starting CoAP-07 receiver...\n"); - - rest_activate_resource(&resource_well_known_core); - - coap_register_as_transaction_handler(); - coap_init_connection(SERVER_LISTEN_PORT); - PRINTF("Listening on port %u\n", UIP_HTONS(SERVER_LISTEN_PORT)); - - while(1) { - PROCESS_YIELD(); - - if(ev == tcpip_event) { - coap_receive(); - } else if (ev == PROCESS_EVENT_TIMER) { - /* retransmissions are handled here */ - coap_check_transactions(); - } - } /* while (1) */ - - PROCESS_END(); -} -/*----------------------------------------------------------------------------*/ -/*- Client part --------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -void coap_blocking_request_callback(void *callback_data, void *response) { - struct request_state_t *state = (struct request_state_t *) callback_data; - state->response = (coap_packet_t*) response; - process_poll(state->process); -} -/*----------------------------------------------------------------------------*/ -PT_THREAD(coap_blocking_request(struct request_state_t *state, process_event_t ev, - uip_ipaddr_t *remote_ipaddr, uint16_t remote_port, - coap_packet_t *request, - blocking_response_handler request_callback)) { - PT_BEGIN(&state->pt); - - static uint8_t more; - static uint32_t res_block; - static uint8_t block_error; - - state->block_num = 0; - state->response = NULL; - state->process = PROCESS_CURRENT(); - - more = 0; - res_block = 0; - block_error = 0; - - do { - request->mid = coap_get_mid(); - if ((state->transaction = coap_new_transaction(request->mid, remote_ipaddr, remote_port))) - { - state->transaction->callback = coap_blocking_request_callback; - state->transaction->callback_data = state; - - if (state->block_num>0) - { - coap_set_header_block2(request, state->block_num, 0, REST_MAX_CHUNK_SIZE); - } - - state->transaction->packet_len = coap_serialize_message(request, state->transaction->packet); - - coap_send_transaction(state->transaction); - PRINTF("Requested #%lu (MID %u)\n", state->block_num, request->mid); - - PT_YIELD_UNTIL(&state->pt, ev == PROCESS_EVENT_POLL); - - if (!state->response) - { - PRINTF("Server not responding\n"); - PT_EXIT(&state->pt); - } - - coap_get_header_block2(state->response, &res_block, &more, NULL, NULL); - - PRINTF("Received #%lu%s (%u bytes)\n", res_block, more ? "+" : "", state->response->payload_len); - - if (res_block==state->block_num) - { - request_callback(state->response); - ++(state->block_num); - } - else - { - PRINTF("WRONG BLOCK %lu/%lu\n", res_block, state->block_num); - ++block_error; - } - } - else - { - PRINTF("Could not allocate transaction buffer"); - PT_EXIT(&state->pt); - } - } while (more && block_errorpt); -} -/*----------------------------------------------------------------------------*/ -/*- Engine Interface ---------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -const struct rest_implementation coap_rest_implementation = { - "CoAP-07", - - coap_receiver_init, - coap_set_service_callback, - - coap_get_header_uri_path, - coap_set_header_uri_path, - coap_get_rest_method, - coap_set_status_code, - - coap_get_header_content_type, - coap_set_header_content_type, - coap_get_header_accept, - NULL, - NULL, - coap_get_header_max_age, - coap_set_header_max_age, - coap_set_header_etag, - coap_get_header_if_match, - coap_get_header_if_none_match, - coap_get_header_uri_host, - coap_set_header_location_path, - - coap_get_payload, - coap_set_payload, - - coap_get_header_uri_query, - coap_get_query_variable, - coap_get_post_variable, - - coap_notify_observers, - (restful_post_handler) coap_observe_handler, - - NULL, /* default pre-handler (set separate handler after activation if needed) */ - NULL, /* default post-handler for non-observable resources */ - - { - CONTENT_2_05, - CREATED_2_01, - CHANGED_2_04, - DELETED_2_02, - VALID_2_03, - - BAD_REQUEST_4_00, - UNAUTHORIZED_4_01, - BAD_OPTION_4_02, - FORBIDDEN_4_03, - NOT_FOUND_4_04, - METHOD_NOT_ALLOWED_4_05, - NOT_ACCEPTABLE_4_06, - REQUEST_ENTITY_TOO_LARGE_4_13, - UNSUPPORTED_MEDIA_TYPE_4_15, - - INTERNAL_SERVER_ERROR_5_00, - NOT_IMPLEMENTED_5_01, - BAD_GATEWAY_5_02, - SERVICE_UNAVAILABLE_5_03, - GATEWAY_TIMEOUT_5_04, - PROXYING_NOT_SUPPORTED_5_05 - }, - - { - TEXT_PLAIN, - TEXT_XML, - TEXT_CSV, - TEXT_HTML, - IMAGE_GIF, - IMAGE_JPEG, - IMAGE_PNG, - IMAGE_TIFF, - AUDIO_RAW, - VIDEO_RAW, - APPLICATION_LINK_FORMAT, - APPLICATION_XML, - APPLICATION_OCTET_STREAM, - APPLICATION_RDF_XML, - APPLICATION_SOAP_XML, - APPLICATION_ATOM_XML, - APPLICATION_XMPP_XML, - APPLICATION_EXI, - APPLICATION_FASTINFOSET, - APPLICATION_SOAP_FASTINFOSET, - APPLICATION_JSON, - APPLICATION_X_OBIX_BINARY - } -}; diff --git a/apps/er-coap-07/er-coap-07-engine.h b/apps/er-coap-07/er-coap-07-engine.h deleted file mode 100644 index 9f3f0cbba..000000000 --- a/apps/er-coap-07/er-coap-07-engine.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP implementation of the REST Engine - * \author - * Matthias Kovatsch - */ - -#ifndef COAP_SERVER_H_ -#define COAP_SERVER_H_ - -#if !defined(REST) -#error "Define REST to \"coap_rest_implementation\"" -#endif - -#include "er-coap-07.h" -#include "er-coap-07-transactions.h" -#include "er-coap-07-observing.h" -#include "er-coap-07-separate.h" - -#include "pt.h" - -/* Declare server process */ -PROCESS_NAME(coap_receiver); - -#define SERVER_LISTEN_PORT UIP_HTONS(COAP_SERVER_PORT) - -typedef coap_packet_t rest_request_t; -typedef coap_packet_t rest_response_t; - -extern const struct rest_implementation coap_rest_implementation; - -void coap_receiver_init(void); - -/*-----------------------------------------------------------------------------------*/ -/*- Client part ---------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -struct request_state_t { - struct pt pt; - struct process *process; - coap_transaction_t *transaction; - coap_packet_t *response; - uint32_t block_num; -}; - -typedef void (*blocking_response_handler) (void* response); - -PT_THREAD(coap_blocking_request(struct request_state_t *state, process_event_t ev, - uip_ipaddr_t *remote_ipaddr, uint16_t remote_port, - coap_packet_t *request, - blocking_response_handler request_callback)); - -#define COAP_BLOCKING_REQUEST(server_addr, server_port, request, chunk_handler) \ -{ \ - static struct request_state_t request_state; \ - PT_SPAWN(process_pt, &request_state.pt, \ - coap_blocking_request(&request_state, ev, \ - server_addr, server_port, \ - request, chunk_handler) \ - ); \ -} -/*-----------------------------------------------------------------------------------*/ - -#endif /* COAP_SERVER_H_ */ diff --git a/apps/er-coap-07/er-coap-07-observing.c b/apps/er-coap-07/er-coap-07-observing.c deleted file mode 100644 index af93492f4..000000000 --- a/apps/er-coap-07/er-coap-07-observing.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP module for observing resources - * \author - * Matthias Kovatsch - */ - -#include -#include - -#include "er-coap-07-observing.h" - -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - - -MEMB(observers_memb, coap_observer_t, COAP_MAX_OBSERVERS); -LIST(observers_list); - -/*-----------------------------------------------------------------------------------*/ -coap_observer_t * -coap_add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token, size_t token_len, const char *url) -{ - /* Remove existing observe relationship, if any. */ - coap_remove_observer_by_url(addr, port, url); - - coap_observer_t *o = memb_alloc(&observers_memb); - - if (o) - { - o->url = url; - uip_ipaddr_copy(&o->addr, addr); - o->port = port; - o->token_len = token_len; - memcpy(o->token, token, token_len); - o->last_mid = 0; - - stimer_set(&o->refresh_timer, COAP_OBSERVING_REFRESH_INTERVAL); - - PRINTF("Adding observer for /%s [0x%02X%02X]\n", o->url, o->token[0], o->token[1]); - list_add(observers_list, o); - } - - return o; -} -/*-----------------------------------------------------------------------------------*/ -void -coap_remove_observer(coap_observer_t *o) -{ - PRINTF("Removing observer for /%s [0x%02X%02X]\n", o->url, o->token[0], o->token[1]); - - memb_free(&observers_memb, o); - list_remove(observers_list, o); -} - -int -coap_remove_observer_by_client(uip_ipaddr_t *addr, uint16_t port) -{ - int removed = 0; - coap_observer_t* obs = NULL; - - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - PRINTF("Remove check client "); - PRINT6ADDR(addr); - PRINTF(":%u\n", port); - if (uip_ipaddr_cmp(&obs->addr, addr) && obs->port==port) - { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} - -int -coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port, uint8_t *token, size_t token_len) -{ - int removed = 0; - coap_observer_t* obs = NULL; - - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - PRINTF("Remove check Token 0x%02X%02X\n", token[0], token[1]); - if (uip_ipaddr_cmp(&obs->addr, addr) && obs->port==port && obs->token_len==token_len && memcmp(obs->token, token, token_len)==0) - { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} - -int -coap_remove_observer_by_url(uip_ipaddr_t *addr, uint16_t port, const char *url) -{ - int removed = 0; - coap_observer_t* obs = NULL; - - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - PRINTF("Remove check URL %p\n", url); - if (uip_ipaddr_cmp(&obs->addr, addr) && obs->port==port && (obs->url==url || memcmp(obs->url, url, strlen(obs->url))==0)) - { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} - -int -coap_remove_observer_by_mid(uip_ipaddr_t *addr, uint16_t port, uint16_t mid) -{ - int removed = 0; - coap_observer_t* obs = NULL; - - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - PRINTF("Remove check MID %u\n", mid); - if (uip_ipaddr_cmp(&obs->addr, addr) && obs->port==port && obs->last_mid==mid) - { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} -/*-----------------------------------------------------------------------------------*/ -void -coap_notify_observers(resource_t *resource, int32_t obs_counter, void *notification) -{ - coap_packet_t *const coap_res = (coap_packet_t *) notification; - coap_observer_t* obs = NULL; - uint8_t preferred_type = coap_res->type; - - PRINTF("Observing: Notification from %s\n", resource->url); - - /* Iterate over observers. */ - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - if (obs->url==resource->url) /* using RESOURCE url pointer as handle */ - { - coap_transaction_t *transaction = NULL; - - /*TODO implement special transaction for CON, sharing the same buffer to allow for more observers. */ - - if ( (transaction = coap_new_transaction(coap_get_mid(), &obs->addr, obs->port)) ) - { - PRINTF(" Observer "); - PRINT6ADDR(&obs->addr); - PRINTF(":%u\n", obs->port); - - /* Update last MID for RST matching. */ - obs->last_mid = transaction->mid; - - /* Prepare response */ - coap_res->mid = transaction->mid; - coap_set_header_observe(coap_res, obs_counter); - coap_set_header_token(coap_res, obs->token, obs->token_len); - - /* Use CON to check whether client is still there/interested after COAP_OBSERVING_REFRESH_INTERVAL. */ - if (stimer_expired(&obs->refresh_timer)) - { - PRINTF(" Refreshing with CON\n"); - coap_res->type = COAP_TYPE_CON; - stimer_restart(&obs->refresh_timer); - } - else - { - coap_res->type = preferred_type; - } - - transaction->packet_len = coap_serialize_message(coap_res, transaction->packet); - - coap_send_transaction(transaction); - } - } - } -} -/*-----------------------------------------------------------------------------------*/ -void -coap_observe_handler(resource_t *resource, void *request, void *response) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - coap_packet_t *const coap_res = (coap_packet_t *) response; - - static char content[16]; - - if (coap_req->code==COAP_GET && coap_res->code<128) /* GET request and response without error code */ - { - if (IS_OPTION(coap_req, COAP_OPTION_OBSERVE)) - { - - if (coap_add_observer(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, coap_req->token, coap_req->token_len, resource->url)) - { - coap_set_header_observe(coap_res, 0); - /* - * For demonstration purposes only. A subscription should return the same representation as a normal GET. - * TODO: Comment the following line for any real application. - */ - coap_set_payload(coap_res, content, snprintf(content, sizeof(content), "Added %u/%u", list_length(observers_list), COAP_MAX_OBSERVERS)); - } - else - { - coap_res->code = SERVICE_UNAVAILABLE_5_03; - coap_set_payload(coap_res, "TooManyObservers", 16); - } /* if (added observer) */ - } - else /* if (observe) */ - { - /* Remove client if it is currently observing. */ - coap_remove_observer_by_url(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, resource->url); - } /* if (observe) */ - } -} diff --git a/apps/er-coap-07/er-coap-07-observing.h b/apps/er-coap-07/er-coap-07-observing.h deleted file mode 100644 index 2fecdaf02..000000000 --- a/apps/er-coap-07/er-coap-07-observing.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP module for observing resources - * \author - * Matthias Kovatsch - */ - -#ifndef COAP_OBSERVING_H_ -#define COAP_OBSERVING_H_ - -#include "sys/stimer.h" -#include "er-coap-07.h" -#include "er-coap-07-transactions.h" - -#ifndef COAP_MAX_OBSERVERS -#define COAP_MAX_OBSERVERS 4 -#endif /* COAP_MAX_OBSERVERS */ - -/* Interval in seconds in which NON notifies are changed to CON notifies to check client. */ -#define COAP_OBSERVING_REFRESH_INTERVAL 60 - -#if COAP_MAX_OPEN_TRANSACTIONS - */ - -#include -#include - -#include "er-coap-07-separate.h" -#include "er-coap-07-transactions.h" - -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - -/*----------------------------------------------------------------------------*/ -void -coap_separate_reject() -{ - coap_error_code = SERVICE_UNAVAILABLE_5_03; - coap_error_message = "AlreadyInUse"; -} -/*----------------------------------------------------------------------------*/ -int -coap_separate_accept(void *request, coap_separate_t *separate_store) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - coap_transaction_t *const t = coap_get_transaction_by_mid(coap_req->mid); - - PRINTF("Separate ACCEPT: /%.*s MID %u\n", coap_req->uri_path_len, coap_req->uri_path, coap_req->mid); - if (t) - { - /* Send separate ACK for CON. */ - if (coap_req->type==COAP_TYPE_CON) - { - coap_packet_t ack[1]; - /* ACK with empty code (0) */ - coap_init_message(ack, COAP_TYPE_ACK, 0, coap_req->mid); - /* Serializing into IPBUF: Only overwrites header parts that are already parsed into the request struct. */ - coap_send_message(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, (uip_appdata), coap_serialize_message(ack, uip_appdata)); - } - - /* Store remote address. */ - uip_ipaddr_copy(&separate_store->addr, &t->addr); - separate_store->port = t->port; - - /* Store correct response type. */ - separate_store->type = coap_req->type==COAP_TYPE_CON ? COAP_TYPE_CON : COAP_TYPE_NON; - separate_store->mid = coap_get_mid(); /* if it was a NON, we burned one MID in the engine... */ - - memcpy(separate_store->token, coap_req->token, coap_req->token_len); - separate_store->token_len = coap_req->token_len; - - separate_store->block2_num = coap_req->block2_num; - separate_store->block2_size = coap_req->block2_size; - - /* Signal the engine to skip automatic response and clear transaction by engine. */ - coap_error_code = MANUAL_RESPONSE; - - return 1; - } - else - { - PRINTF("ERROR: Response transaction for separate request not found!\n"); - return 0; - } -} -/*----------------------------------------------------------------------------*/ -void -coap_separate_resume(void *response, coap_separate_t *separate_store, uint8_t code) -{ - coap_init_message(response, separate_store->type, code, separate_store->mid); - if (separate_store->token_len) - { - coap_set_header_token(response, separate_store->token, separate_store->token_len); - } -} diff --git a/apps/er-coap-07/er-coap-07-transactions.c b/apps/er-coap-07/er-coap-07-transactions.c deleted file mode 100644 index 2a11002d4..000000000 --- a/apps/er-coap-07/er-coap-07-transactions.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP module for reliable transport - * \author - * Matthias Kovatsch - */ - -#include "contiki.h" -#include "contiki-net.h" - -#include "er-coap-07-transactions.h" -#include "er-coap-07-observing.h" - -/* - * Modulo mask (+1 and +0.5 for rounding) for a random number to get the tick number for the random - * retransmission time between COAP_RESPONSE_TIMEOUT and COAP_RESPONSE_TIMEOUT*COAP_RESPONSE_RANDOM_FACTOR. - */ -#define COAP_RESPONSE_TIMEOUT_TICKS (CLOCK_SECOND * COAP_RESPONSE_TIMEOUT) -#define COAP_RESPONSE_TIMEOUT_BACKOFF_MASK ((CLOCK_SECOND * COAP_RESPONSE_TIMEOUT * (COAP_RESPONSE_RANDOM_FACTOR - 1)) + 1.5) - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - - -MEMB(transactions_memb, coap_transaction_t, COAP_MAX_OPEN_TRANSACTIONS); -LIST(transactions_list); - - -static struct process *transaction_handler_process = NULL; - -void -coap_register_as_transaction_handler() -{ - transaction_handler_process = PROCESS_CURRENT(); -} - -coap_transaction_t * -coap_new_transaction(uint16_t mid, uip_ipaddr_t *addr, uint16_t port) -{ - coap_transaction_t *t = memb_alloc(&transactions_memb); - - if (t) - { - t->mid = mid; - t->retrans_counter = 0; - - /* save client address */ - uip_ipaddr_copy(&t->addr, addr); - t->port = port; - - list_add(transactions_list, t); /* List itself makes sure same element is not added twice. */ - } - - return t; -} - -void -coap_send_transaction(coap_transaction_t *t) -{ - PRINTF("Sending transaction %u\n", t->mid); - - coap_send_message(&t->addr, t->port, t->packet, t->packet_len); - - if (COAP_TYPE_CON==((COAP_HEADER_TYPE_MASK & t->packet[0])>>COAP_HEADER_TYPE_POSITION)) - { - if (t->retrans_countermid); - - if (t->retrans_counter==0) - { - t->retrans_timer.timer.interval = COAP_RESPONSE_TIMEOUT_TICKS + (random_rand() % (clock_time_t) COAP_RESPONSE_TIMEOUT_BACKOFF_MASK); - PRINTF("Initial interval %f\n", (float)t->retrans_timer.timer.interval/CLOCK_SECOND); - } - else - { - t->retrans_timer.timer.interval <<= 1; /* double */ - PRINTF("Doubled (%u) interval %f\n", t->retrans_counter, (float)t->retrans_timer.timer.interval/CLOCK_SECOND); - } - - /*FIXME - * Hack: Setting timer for responsible process. - * Maybe there is a better way, but avoid posting everything to the process. - */ - struct process *process_actual = PROCESS_CURRENT(); - process_current = transaction_handler_process; - etimer_restart(&t->retrans_timer); /* interval updated above */ - process_current = process_actual; - - t = NULL; - } - else - { - /* Timed out. */ - PRINTF("Timeout\n"); - restful_response_handler callback = t->callback; - void *callback_data = t->callback_data; - - /* handle observers */ - coap_remove_observer_by_client(&t->addr, t->port); - - coap_clear_transaction(t); - - if (callback) { - callback(callback_data, NULL); - } - } - } - else - { - coap_clear_transaction(t); - } -} - -void -coap_clear_transaction(coap_transaction_t *t) -{ - if (t) - { - PRINTF("Freeing transaction %u: %p\n", t->mid, t); - - etimer_stop(&t->retrans_timer); - list_remove(transactions_list, t); - memb_free(&transactions_memb, t); - } -} - -coap_transaction_t * -coap_get_transaction_by_mid(uint16_t mid) -{ - coap_transaction_t *t = NULL; - - for (t = (coap_transaction_t*)list_head(transactions_list); t; t = t->next) - { - if (t->mid==mid) - { - PRINTF("Found transaction for MID %u: %p\n", t->mid, t); - return t; - } - } - return NULL; -} - -void -coap_check_transactions() -{ - coap_transaction_t *t = NULL; - - for (t = (coap_transaction_t*)list_head(transactions_list); t; t = t->next) - { - if (etimer_expired(&t->retrans_timer)) - { - ++(t->retrans_counter); - PRINTF("Retransmitting %u (%u)\n", t->mid, t->retrans_counter); - coap_send_transaction(t); - } - } -} diff --git a/apps/er-coap-07/er-coap-07.c b/apps/er-coap-07/er-coap-07.c deleted file mode 100644 index 4bf995c97..000000000 --- a/apps/er-coap-07/er-coap-07.c +++ /dev/null @@ -1,1205 +0,0 @@ -/* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * An implementation of the Constrained Application Protocol (draft 07) - * \author - * Matthias Kovatsch - */ - -#include "contiki.h" -#include "contiki-net.h" -#include -#include - -#include "er-coap-07.h" -#include "er-coap-07-transactions.h" - - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - -/*-----------------------------------------------------------------------------------*/ -/*- Variables -----------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -static struct uip_udp_conn *udp_conn = NULL; -static uint16_t current_mid = 0; - -coap_status_t coap_error_code = NO_ERROR; -char *coap_error_message = ""; -/*-----------------------------------------------------------------------------------*/ -/*- LOCAL HELP FUNCTIONS ------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -static -uint16_t -coap_log_2(uint16_t value) -{ - uint16_t result = 0; - do { - value = value >> 1; - result++; - } while (value); - - return result ? result - 1 : result; -} -/*-----------------------------------------------------------------------------------*/ -static -uint32_t -coap_parse_int_option(uint8_t *bytes, uint16_t length) -{ - uint32_t var = 0; - int i = 0; - while (i 15) - { - uint8_t delta = COAP_OPTION_FENCE_POST - (*current_number%COAP_OPTION_FENCE_POST); - coap_set_option_header(delta, 0, &buffer[i++]); - *current_number += delta; - - PRINTF("OPTION FENCE POST delta %u\n", delta); - } - return i; -} -/*-----------------------------------------------------------------------------------*/ -static -size_t -coap_serialize_int_option(int number, int current_number, uint8_t *buffer, uint32_t value) -{ - /* Insert fence-posts for large deltas */ - size_t i = coap_insert_option_fence_posts(number, ¤t_number, buffer); - size_t start_i = i; - - uint8_t *option = &buffer[i]; - - if (0xFF000000 & value) buffer[++i] = (uint8_t) (0xFF & value>>24); - if (0xFFFF0000 & value) buffer[++i] = (uint8_t) (0xFF & value>>16); - if (0xFFFFFF00 & value) buffer[++i] = (uint8_t) (0xFF & value>>8); - if (0xFFFFFFFF & value) buffer[++i] = (uint8_t) (0xFF & value); - - i += coap_set_option_header(number - current_number, i-start_i, option); - - PRINTF("OPTION type %u, delta %u, len %u\n", number, number - current_number, i-start_i); - - return i; -} -/*-----------------------------------------------------------------------------------*/ -/* - * Pass the char to split the string at in split_option and receive the number of options in split_option on return. - */ -static -size_t -coap_serialize_array_option(int number, int current_number, uint8_t *buffer, uint8_t *array, size_t length, uint8_t *split_option) -{ - /* Insert fence-posts for large deltas */ - size_t i = coap_insert_option_fence_posts(number, ¤t_number, buffer); - - if (split_option!=NULL) - { - int j; - uint8_t *part_start = array; - uint8_t *part_end = NULL; - size_t temp_length; - - char split_char = *split_option; - *split_option = 0; /* Ensure reflecting the created option count */ - - for (j = 0; j<=length; ++j) - { - if (array[j]==split_char || j==length) - { - part_end = array + j; - temp_length = part_end-part_start; - - i += coap_set_option_header(number - current_number, temp_length, &buffer[i]); - memcpy(&buffer[i], part_start, temp_length); - i += temp_length; - - PRINTF("OPTION type %u, delta %u, len %u, part [%.*s]\n", number, number - current_number, i, temp_length, part_start); - - ++(*split_option); - ++j; /* skip the slash */ - current_number = number; - while( array[j]=='/') ++j; - part_start = array + j; - } - } /* for */ - } - else - { - i += coap_set_option_header(number - current_number, length, &buffer[i]); - memcpy(&buffer[i], array, length); - i += length; - - PRINTF("OPTION type %u, delta %u, len %u\n", number, number - current_number, i); - } - - return i; -} -/*-----------------------------------------------------------------------------------*/ -static -void -coap_merge_multi_option(char **dst, size_t *dst_len, uint8_t *option, size_t option_len, char separator) -{ - /* Merge multiple options. */ - if (*dst_len > 0) - { - /* dst already contains an option: concatenate */ - (*dst)[*dst_len] = separator; - *dst_len += 1; - - /* memmove handles 2-byte option headers */ - memmove((*dst)+(*dst_len), option, option_len); - - *dst_len += option_len; - } - else - { - /* dst is empty: set to option */ - *dst = (char *) option; - *dst_len = option_len; - } -} -/*-----------------------------------------------------------------------------------*/ -static -int -coap_get_variable(const char *buffer, size_t length, const char *name, const char **output) -{ - const char *start = NULL; - const char *end = NULL; - const char *value_end = NULL; - size_t name_len = 0; - - /*initialize the output buffer first*/ - *output = 0; - - name_len = strlen(name); - end = buffer + length; - - for (start = buffer; start + name_len < end; ++start){ - if ((start == buffer || start[-1] == '&') && start[name_len] == '=' && - strncmp(name, start, name_len)==0) { - - /* Point start to variable value */ - start += name_len + 1; - - /* Point end to the end of the value */ - value_end = (const char *) memchr(start, '&', end - start); - if (value_end == NULL) { - value_end = end; - } - - *output = start; - - return (value_end - start); - } - } - - return 0; -} -/*-----------------------------------------------------------------------------------*/ -/*- MEASSAGE SENDING ----------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -void -coap_init_connection(uint16_t port) -{ - /* new connection with remote host */ - udp_conn = udp_new(NULL, 0, NULL); - udp_bind(udp_conn, port); - PRINTF("Listening on port %u\n", uip_ntohs(udp_conn->lport)); - - /* Initialize transaction ID. */ - current_mid = random_rand(); -} -/*-----------------------------------------------------------------------------------*/ -uint16_t -coap_get_mid() -{ - return ++current_mid; -} -/*-----------------------------------------------------------------------------------*/ -/*- MEASSAGE PROCESSING -------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -void -coap_init_message(void *packet, coap_message_type_t type, uint8_t code, uint16_t mid) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - /* Important thing */ - memset(coap_pkt, 0, sizeof(coap_packet_t)); - - coap_pkt->type = type; - coap_pkt->code = code; - coap_pkt->mid = mid; -} -/*-----------------------------------------------------------------------------------*/ -size_t -coap_serialize_message(void *packet, uint8_t *buffer) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - /* Initialize */ - coap_pkt->buffer = buffer; - coap_pkt->version = 1; - coap_pkt->option_count = 0; - - /* serialize options */ - uint8_t *option = coap_pkt->buffer + COAP_HEADER_LEN; - int current_number = 0; - - PRINTF("-Serializing options-\n"); - - if (IS_OPTION(coap_pkt, COAP_OPTION_CONTENT_TYPE)) { - PRINTF("Content-Type [%u]\n", coap_pkt->content_type); - - option += coap_serialize_int_option(COAP_OPTION_CONTENT_TYPE, current_number, option, coap_pkt->content_type); - coap_pkt->option_count += 1; - current_number = COAP_OPTION_CONTENT_TYPE; - } - if (IS_OPTION(coap_pkt, COAP_OPTION_MAX_AGE)) { - PRINTF("Max-Age [%lu]\n", coap_pkt->max_age); - - option += coap_serialize_int_option(COAP_OPTION_MAX_AGE, current_number, option, coap_pkt->max_age); - coap_pkt->option_count += 1; - current_number = COAP_OPTION_MAX_AGE; - } - if (IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI)) { - PRINTF("Proxy-Uri [%.*s]\n", coap_pkt->proxy_uri_len, coap_pkt->proxy_uri); - - int length = coap_pkt->proxy_uri_len; - int j = 0; - while (length>0) - { - option += coap_serialize_array_option(COAP_OPTION_PROXY_URI, current_number, option, (uint8_t *) coap_pkt->proxy_uri + j*270, MIN(270, length), NULL); - coap_pkt->option_count += 1; - current_number = COAP_OPTION_PROXY_URI; - - ++j; - length -= 270; - } - } - if (IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) { - PRINTF("ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->etag_len, - coap_pkt->etag[0], - coap_pkt->etag[1], - coap_pkt->etag[2], - coap_pkt->etag[3], - coap_pkt->etag[4], - coap_pkt->etag[5], - coap_pkt->etag[6], - coap_pkt->etag[7] - ); /*FIXME always prints 8 bytes */ - - option += coap_serialize_array_option(COAP_OPTION_ETAG, current_number, option, coap_pkt->etag, coap_pkt->etag_len, NULL); - coap_pkt->option_count += 1; - current_number = COAP_OPTION_ETAG; - } - if (IS_OPTION(coap_pkt, COAP_OPTION_URI_HOST)) { - PRINTF("Uri-Host [%.*s]\n", coap_pkt->uri_host_len, coap_pkt->uri_host); - - option += coap_serialize_array_option(COAP_OPTION_URI_HOST, current_number, option, (uint8_t *) coap_pkt->uri_host, coap_pkt->uri_host_len, NULL); - coap_pkt->option_count += 1; - current_number = COAP_OPTION_URI_HOST; - } - if (IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH)) { - PRINTF("Location [%.*s]\n", coap_pkt->location_path_len, coap_pkt->location_path); - - uint8_t split_options = '/'; - - option += coap_serialize_array_option(COAP_OPTION_LOCATION_PATH, current_number, option, (uint8_t *) coap_pkt->location_path, coap_pkt->location_path_len, &split_options); - coap_pkt->option_count += split_options; - current_number = COAP_OPTION_LOCATION_PATH; - } - if (IS_OPTION(coap_pkt, COAP_OPTION_URI_PORT)) { - PRINTF("Uri-Port [%u]\n", coap_pkt->uri_port); - - option += coap_serialize_int_option(COAP_OPTION_URI_PORT, current_number, option, coap_pkt->uri_port); - coap_pkt->option_count += 1; - current_number = COAP_OPTION_URI_PORT; - } - if (IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY)) { - PRINTF("Location-Query [%.*s]\n", coap_pkt->location_query_len, coap_pkt->location_query); - - uint8_t split_options = '&'; - - option += coap_serialize_array_option(COAP_OPTION_LOCATION_QUERY, current_number, option, (uint8_t *) coap_pkt->location_query, coap_pkt->location_query_len, &split_options); - coap_pkt->option_count += split_options; - current_number = COAP_OPTION_LOCATION_QUERY; - } - if (IS_OPTION(coap_pkt, COAP_OPTION_URI_PATH)) { - PRINTF("Uri-Path [%.*s]\n", coap_pkt->uri_path_len, coap_pkt->uri_path); - - uint8_t split_options = '/'; - - option += coap_serialize_array_option(COAP_OPTION_URI_PATH, current_number, option, (uint8_t *) coap_pkt->uri_path, coap_pkt->uri_path_len, &split_options); - coap_pkt->option_count += split_options; - current_number = COAP_OPTION_URI_PATH; - } - if (IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) { - PRINTF("Observe [%u]\n", coap_pkt->observe); - - option += coap_serialize_int_option(COAP_OPTION_OBSERVE, current_number, option, coap_pkt->observe); - coap_pkt->option_count += 1; - current_number = COAP_OPTION_OBSERVE; - } - if (IS_OPTION(coap_pkt, COAP_OPTION_TOKEN)) { - PRINTF("Token %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->token_len, - coap_pkt->token[0], - coap_pkt->token[1], - coap_pkt->token[2], - coap_pkt->token[3], - coap_pkt->token[4], - coap_pkt->token[5], - coap_pkt->token[6], - coap_pkt->token[7] - ); /*FIXME always prints 8 bytes */ - - option += coap_serialize_array_option(COAP_OPTION_TOKEN, current_number, option, coap_pkt->token, coap_pkt->token_len, NULL); - coap_pkt->option_count += 1; - current_number = COAP_OPTION_TOKEN; - } - if (IS_OPTION(coap_pkt, COAP_OPTION_ACCEPT)) { - int i; - for (i=0; iaccept_num; ++i) - { - PRINTF("Accept [%u]\n", coap_pkt->accept[i]); - - option += coap_serialize_int_option(COAP_OPTION_ACCEPT, current_number, option, (uint32_t)coap_pkt->accept[i]); - coap_pkt->option_count += 1; - current_number = COAP_OPTION_ACCEPT; - } - } - if (IS_OPTION(coap_pkt, COAP_OPTION_IF_MATCH)) { - PRINTF("If-Match [FIXME]\n"); - - option += coap_serialize_array_option(COAP_OPTION_IF_MATCH, current_number, option, coap_pkt->if_match, coap_pkt->if_match_len, NULL); - coap_pkt->option_count += 1; - current_number = COAP_OPTION_IF_MATCH; - } - if (IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) { - PRINTF("Uri-Query [%.*s]\n", coap_pkt->uri_query_len, coap_pkt->uri_query); - - uint8_t split_options = '&'; - - option += coap_serialize_array_option(COAP_OPTION_URI_QUERY, current_number, option, (uint8_t *) coap_pkt->uri_query, coap_pkt->uri_query_len, &split_options); - coap_pkt->option_count += split_options + (COAP_OPTION_URI_QUERY-current_number)/COAP_OPTION_FENCE_POST; - current_number = COAP_OPTION_URI_QUERY; - } - if (IS_OPTION(coap_pkt, COAP_OPTION_BLOCK2)) - { - PRINTF("Block2 [%lu%s (%u B/blk)]\n", coap_pkt->block2_num, coap_pkt->block2_more ? "+" : "", coap_pkt->block2_size); - - uint32_t block = coap_pkt->block2_num << 4; - if (coap_pkt->block2_more) block |= 0x8; - block |= 0xF & coap_log_2(coap_pkt->block2_size/16); - - PRINTF("Block2 encoded: 0x%lX\n", block); - - option += coap_serialize_int_option(COAP_OPTION_BLOCK2, current_number, option, block); - - coap_pkt->option_count += 1 + (COAP_OPTION_BLOCK2-current_number)/COAP_OPTION_FENCE_POST; - current_number = COAP_OPTION_BLOCK2; - } - if (IS_OPTION(coap_pkt, COAP_OPTION_BLOCK1)) - { - PRINTF("Block1 [%lu%s (%u B/blk)]\n", coap_pkt->block1_num, coap_pkt->block1_more ? "+" : "", coap_pkt->block1_size); - - uint32_t block = coap_pkt->block1_num << 4; - if (coap_pkt->block1_more) block |= 0x8; - block |= 0xF & coap_log_2(coap_pkt->block1_size/16); - - PRINTF("Block1 encoded: 0x%lX\n", block); - - option += coap_serialize_int_option(COAP_OPTION_BLOCK1, current_number, option, block); - - coap_pkt->option_count += 1 + (COAP_OPTION_BLOCK1-current_number)/COAP_OPTION_FENCE_POST; - current_number = COAP_OPTION_BLOCK1; - } - if (IS_OPTION(coap_pkt, COAP_OPTION_IF_NONE_MATCH)) { - PRINTF("If-None-Match\n"); - - option += coap_serialize_int_option(COAP_OPTION_IF_NONE_MATCH, current_number, option, 0); - - coap_pkt->option_count += 1 + (COAP_OPTION_IF_NONE_MATCH-current_number)/COAP_OPTION_FENCE_POST; - current_number = COAP_OPTION_IF_NONE_MATCH; - } - - /* pack payload */ - if ((option - coap_pkt->buffer)<=COAP_MAX_HEADER_SIZE) - { - memmove(option, coap_pkt->payload, coap_pkt->payload_len); - } - else - { - /* An error occured. Caller must check for !=0. */ - coap_pkt->buffer = NULL; - coap_error_message = "Serialized header exceeds COAP_MAX_HEADER_SIZE"; - return 0; - } - - /* set header fields */ - coap_pkt->buffer[0] = 0x00; - coap_pkt->buffer[0] |= COAP_HEADER_VERSION_MASK & (coap_pkt->version)<buffer[0] |= COAP_HEADER_TYPE_MASK & (coap_pkt->type)<buffer[0] |= COAP_HEADER_OPTION_COUNT_MASK & (coap_pkt->option_count)<buffer[1] = coap_pkt->code; - coap_pkt->buffer[2] = 0xFF & (coap_pkt->mid)>>8; - coap_pkt->buffer[3] = 0xFF & coap_pkt->mid; - - PRINTF("-Done %u options, header len %u, payload len %u-\n", coap_pkt->option_count, option - buffer, coap_pkt->payload_len); - - return (option - buffer) + coap_pkt->payload_len; /* packet length */ -} -/*-----------------------------------------------------------------------------------*/ -void -coap_send_message(uip_ipaddr_t *addr, uint16_t port, uint8_t *data, uint16_t length) -{ - /* Configure connection to reply to client */ - uip_ipaddr_copy(&udp_conn->ripaddr, addr); - udp_conn->rport = port; - - uip_udp_packet_send(udp_conn, data, length); - PRINTF("-sent UDP datagram (%u)-\n", length); - - /* Restore server connection to allow data from any node */ - memset(&udp_conn->ripaddr, 0, sizeof(udp_conn->ripaddr)); - udp_conn->rport = 0; -} -/*-----------------------------------------------------------------------------------*/ -coap_status_t -coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - /* Initialize packet */ - memset(coap_pkt, 0, sizeof(coap_packet_t)); - - /* pointer to packet bytes */ - coap_pkt->buffer = data; - - /* parse header fields */ - coap_pkt->version = (COAP_HEADER_VERSION_MASK & coap_pkt->buffer[0])>>COAP_HEADER_VERSION_POSITION; - coap_pkt->type = (COAP_HEADER_TYPE_MASK & coap_pkt->buffer[0])>>COAP_HEADER_TYPE_POSITION; - coap_pkt->option_count = (COAP_HEADER_OPTION_COUNT_MASK & coap_pkt->buffer[0])>>COAP_HEADER_OPTION_COUNT_POSITION; - coap_pkt->code = coap_pkt->buffer[1]; - coap_pkt->mid = coap_pkt->buffer[2]<<8 | coap_pkt->buffer[3]; - - if (coap_pkt->version != 1) - { - coap_error_message = "CoAP version must be 1"; - return BAD_REQUEST_4_00; - } - - /* parse options */ - coap_pkt->options = 0x0000; - uint8_t *current_option = data + COAP_HEADER_LEN; - - if (coap_pkt->option_count) - { - uint8_t option_index = 0; - - uint8_t current_number = 0; - size_t option_len = 0; - - PRINTF("-Parsing %u options-\n", coap_pkt->option_count); - for (option_index=0; option_index < coap_pkt->option_count; ++option_index) { - - current_number += current_option[0]>>4; - - PRINTF("OPTION %u (type %u, delta %u, len %u): ", option_index, current_number, current_option[0]>>4, (0x0F & current_option[0]) < 15 ? (0x0F & current_option[0]) : current_option[1] + 15); - - if ((0x0F & current_option[0]) < 15) { - option_len = 0x0F & current_option[0]; - current_option += 1; - } else { - option_len = current_option[1] + 15; - current_option += 2; - } - - SET_OPTION(coap_pkt, current_number); - - switch (current_number) { - case COAP_OPTION_CONTENT_TYPE: - coap_pkt->content_type = coap_parse_int_option(current_option, option_len); - PRINTF("Content-Type [%u]\n", coap_pkt->content_type); - break; - case COAP_OPTION_MAX_AGE: - coap_pkt->max_age = coap_parse_int_option(current_option, option_len); - PRINTF("Max-Age [%lu]\n", coap_pkt->max_age); - break; - case COAP_OPTION_PROXY_URI: - /*FIXME check for own end-point */ - coap_pkt->proxy_uri = (char *) current_option; - coap_pkt->proxy_uri_len = option_len; - /*TODO length > 270 not implemented (actually not required) */ - PRINTF("Proxy-Uri NOT IMPLEMENTED [%.*s]\n", coap_pkt->proxy_uri_len, coap_pkt->proxy_uri); - coap_error_message = "This is a constrained server (Contiki)"; - return PROXYING_NOT_SUPPORTED_5_05; - break; - case COAP_OPTION_ETAG: - coap_pkt->etag_len = MIN(COAP_ETAG_LEN, option_len); - memcpy(coap_pkt->etag, current_option, coap_pkt->etag_len); - PRINTF("ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->etag_len, - coap_pkt->etag[0], - coap_pkt->etag[1], - coap_pkt->etag[2], - coap_pkt->etag[3], - coap_pkt->etag[4], - coap_pkt->etag[5], - coap_pkt->etag[6], - coap_pkt->etag[7] - ); /*FIXME always prints 8 bytes */ - break; - case COAP_OPTION_URI_HOST: - coap_pkt->uri_host = (char *) current_option; - coap_pkt->uri_host_len = option_len; - PRINTF("Uri-Host [%.*s]\n", coap_pkt->uri_host_len, coap_pkt->uri_host); - break; - case COAP_OPTION_LOCATION_PATH: - /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ - coap_merge_multi_option( (char **) &(coap_pkt->location_path), &(coap_pkt->location_path_len), current_option, option_len, '/'); - PRINTF("Location-Path [%.*s]\n", coap_pkt->location_path_len, coap_pkt->location_path); - break; - case COAP_OPTION_URI_PORT: - coap_pkt->uri_port = coap_parse_int_option(current_option, option_len); - PRINTF("Uri-Port [%u]\n", coap_pkt->uri_port); - break; - case COAP_OPTION_LOCATION_QUERY: - /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ - coap_merge_multi_option( (char **) &(coap_pkt->location_query), &(coap_pkt->location_query_len), current_option, option_len, '&'); - PRINTF("Location-Query [%.*s]\n", coap_pkt->location_query_len, coap_pkt->location_query); - break; - case COAP_OPTION_URI_PATH: - /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ - coap_merge_multi_option( (char **) &(coap_pkt->uri_path), &(coap_pkt->uri_path_len), current_option, option_len, '/'); - PRINTF("Uri-Path [%.*s]\n", coap_pkt->uri_path_len, coap_pkt->uri_path); - break; - case COAP_OPTION_OBSERVE: - coap_pkt->observe = coap_parse_int_option(current_option, option_len); - PRINTF("Observe [%u]\n", coap_pkt->observe); - break; - case COAP_OPTION_TOKEN: - coap_pkt->token_len = MIN(COAP_TOKEN_LEN, option_len); - memcpy(coap_pkt->token, current_option, coap_pkt->token_len); - PRINTF("Token %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->token_len, - coap_pkt->token[0], - coap_pkt->token[1], - coap_pkt->token[2], - coap_pkt->token[3], - coap_pkt->token[4], - coap_pkt->token[5], - coap_pkt->token[6], - coap_pkt->token[7] - ); /*FIXME always prints 8 bytes */ - break; - case COAP_OPTION_ACCEPT: - if (coap_pkt->accept_num < COAP_MAX_ACCEPT_NUM) - { - coap_pkt->accept[coap_pkt->accept_num] = coap_parse_int_option(current_option, option_len); - coap_pkt->accept_num += 1; - PRINTF("Accept [%u]\n", coap_pkt->content_type); - } - break; - case COAP_OPTION_IF_MATCH: - /*FIXME support multiple ETags */ - coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, option_len); - memcpy(coap_pkt->if_match, current_option, coap_pkt->if_match_len); - PRINTF("If-Match %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->if_match_len, - coap_pkt->if_match[0], - coap_pkt->if_match[1], - coap_pkt->if_match[2], - coap_pkt->if_match[3], - coap_pkt->if_match[4], - coap_pkt->if_match[5], - coap_pkt->if_match[6], - coap_pkt->if_match[7] - ); /*FIXME always prints 8 bytes */ - break; - case COAP_OPTION_FENCE_POST: - PRINTF("Fence-Post\n"); - break; - case COAP_OPTION_URI_QUERY: - /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ - coap_merge_multi_option( (char **) &(coap_pkt->uri_query), &(coap_pkt->uri_query_len), current_option, option_len, '&'); - PRINTF("Uri-Query [%.*s]\n", coap_pkt->uri_query_len, coap_pkt->uri_query); - break; - case COAP_OPTION_BLOCK2: - coap_pkt->block2_num = coap_parse_int_option(current_option, option_len); - coap_pkt->block2_more = (coap_pkt->block2_num & 0x08)>>3; - coap_pkt->block2_size = 16 << (coap_pkt->block2_num & 0x07); - coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F)<<(coap_pkt->block2_num & 0x07); - coap_pkt->block2_num >>= 4; - PRINTF("Block2 [%lu%s (%u B/blk)]\n", coap_pkt->block2_num, coap_pkt->block2_more ? "+" : "", coap_pkt->block2_size); - break; - case COAP_OPTION_BLOCK1: - coap_pkt->block1_num = coap_parse_int_option(current_option, option_len); - coap_pkt->block1_more = (coap_pkt->block1_num & 0x08)>>3; - coap_pkt->block1_size = 16 << (coap_pkt->block1_num & 0x07); - coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F)<<(coap_pkt->block1_num & 0x07); - coap_pkt->block1_num >>= 4; - PRINTF("Block1 [%lu%s (%u B/blk)]\n", coap_pkt->block1_num, coap_pkt->block1_more ? "+" : "", coap_pkt->block1_size); - break; - case COAP_OPTION_IF_NONE_MATCH: - coap_pkt->if_none_match = 1; - PRINTF("If-None-Match\n"); - break; - default: - PRINTF("unknown (%u)\n", current_number); - /* Check if critical (odd) */ - if (current_number & 1) - { - coap_error_message = "Unsupported critical option"; - return BAD_OPTION_4_02; - } - } - - current_option += option_len; - } /* for */ - PRINTF("-Done parsing-------\n"); - } /* if (oc) */ - - coap_pkt->payload = current_option; - coap_pkt->payload_len = data_len - (coap_pkt->payload - data); - - /* also for receiving, the Erbium upper bound is REST_MAX_CHUNK_SIZE */ - if (coap_pkt->payload_len > REST_MAX_CHUNK_SIZE) - { - coap_pkt->payload_len = REST_MAX_CHUNK_SIZE; - } - - /* Null-terminate payload */ - coap_pkt->payload[coap_pkt->payload_len] = '\0'; - - return NO_ERROR; -} -/*-----------------------------------------------------------------------------------*/ -/*- REST FRAMEWORK FUNCTIONS --------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -int -coap_get_query_variable(void *packet, const char *name, const char **output) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) { - return coap_get_variable(coap_pkt->uri_query, coap_pkt->uri_query_len, name, output); - } - return 0; -} - -int -coap_get_post_variable(void *packet, const char *name, const char **output) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (coap_pkt->payload_len) { - return coap_get_variable((const char *)coap_pkt->payload, coap_pkt->payload_len, name, output); - } - return 0; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_set_status_code(void *packet, unsigned int code) -{ - if (code <= 0xFF) - { - ((coap_packet_t *)packet)->code = (uint8_t) code; - return 1; - } - else - { - return 0; - } -} -/*-----------------------------------------------------------------------------------*/ -/*- HEADER OPTION GETTERS AND SETTERS -----------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -unsigned int -coap_get_header_content_type(void *packet) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_CONTENT_TYPE)) return -1; - - return coap_pkt->content_type; -} - -int -coap_set_header_content_type(void *packet, unsigned int content_type) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->content_type = (coap_content_type_t) content_type; - SET_OPTION(coap_pkt, COAP_OPTION_CONTENT_TYPE); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_accept(void *packet, const uint16_t **accept) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_ACCEPT)) return 0; - - *accept = coap_pkt->accept; - return coap_pkt->accept_num; -} - -int -coap_set_header_accept(void *packet, uint16_t accept) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (coap_pkt->accept_num < COAP_MAX_ACCEPT_NUM) - { - coap_pkt->accept[coap_pkt->accept_num] = accept; - coap_pkt->accept_num += 1; - - SET_OPTION(coap_pkt, COAP_OPTION_ACCEPT); - } - return coap_pkt->accept_num; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_max_age(void *packet, uint32_t *age) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_MAX_AGE)) { - *age = COAP_DEFAULT_MAX_AGE; - } else { - *age = coap_pkt->max_age; - } - return 1; -} - -int -coap_set_header_max_age(void *packet, uint32_t age) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->max_age = age; - SET_OPTION(coap_pkt, COAP_OPTION_MAX_AGE); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_etag(void *packet, const uint8_t **etag) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) return 0; - - *etag = coap_pkt->etag; - return coap_pkt->etag_len; -} - -int -coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->etag_len = MIN(COAP_ETAG_LEN, etag_len); - memcpy(coap_pkt->etag, etag, coap_pkt->etag_len); - - SET_OPTION(coap_pkt, COAP_OPTION_ETAG); - return coap_pkt->etag_len; -} -/*-----------------------------------------------------------------------------------*/ -/*FIXME support multiple ETags */ -int -coap_get_header_if_match(void *packet, const uint8_t **etag) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_IF_MATCH)) return 0; - - *etag = coap_pkt->if_match; - return coap_pkt->if_match_len; -} - -int -coap_set_header_if_match(void *packet, const uint8_t *etag, size_t etag_len) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, etag_len); - memcpy(coap_pkt->if_match, etag, coap_pkt->if_match_len); - - SET_OPTION(coap_pkt, COAP_OPTION_IF_MATCH); - return coap_pkt->if_match_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_if_none_match(void *packet) -{ - return IS_OPTION((coap_packet_t *)packet, COAP_OPTION_IF_NONE_MATCH) ? 1 : 0; -} - -int -coap_set_header_if_none_match(void *packet) -{ - SET_OPTION((coap_packet_t *)packet, COAP_OPTION_IF_NONE_MATCH); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_token(void *packet, const uint8_t **token) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_TOKEN)) return 0; - - *token = coap_pkt->token; - return coap_pkt->token_len; -} - -int -coap_set_header_token(void *packet, const uint8_t *token, size_t token_len) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->token_len = MIN(COAP_TOKEN_LEN, token_len); - memcpy(coap_pkt->token, token, coap_pkt->token_len); - - SET_OPTION(coap_pkt, COAP_OPTION_TOKEN); - return coap_pkt->token_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_proxy_uri(void *packet, const char **uri) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI)) return 0; - - *uri = coap_pkt->proxy_uri; - return coap_pkt->proxy_uri_len; -} - -int -coap_set_header_proxy_uri(void *packet, const char *uri) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->proxy_uri = uri; - coap_pkt->proxy_uri_len = strlen(uri); - - SET_OPTION(coap_pkt, COAP_OPTION_PROXY_URI); - return coap_pkt->proxy_uri_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_uri_host(void *packet, const char **host) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_HOST)) return 0; - - *host = coap_pkt->uri_host; - return coap_pkt->uri_host_len; -} - -int -coap_set_header_uri_host(void *packet, const char *host) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->uri_host = host; - coap_pkt->uri_host_len = strlen(host); - - SET_OPTION(coap_pkt, COAP_OPTION_URI_HOST); - return coap_pkt->uri_host_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_uri_path(void *packet, const char **path) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_PATH)) return 0; - - *path = coap_pkt->uri_path; - return coap_pkt->uri_path_len; -} - -int -coap_set_header_uri_path(void *packet, const char *path) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - while (path[0]=='/') ++path; - - coap_pkt->uri_path = path; - coap_pkt->uri_path_len = strlen(path); - - SET_OPTION(coap_pkt, COAP_OPTION_URI_PATH); - return coap_pkt->uri_path_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_uri_query(void *packet, const char **query) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) return 0; - - *query = coap_pkt->uri_query; - return coap_pkt->uri_query_len; -} - -int -coap_set_header_uri_query(void *packet, const char *query) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - while (query[0]=='?') ++query; - - coap_pkt->uri_query = query; - coap_pkt->uri_query_len = strlen(query); - - SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); - return coap_pkt->uri_query_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_location_path(void *packet, const char **path) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH)) return 0; - - *path = coap_pkt->location_path; - return coap_pkt->location_path_len; -} - -int -coap_set_header_location_path(void *packet, const char *path) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - char *query; - - while (path[0]=='/') ++path; - - if ((query = strchr(path, '?'))) - { - coap_set_header_location_query(packet, query+1); - coap_pkt->location_path_len = query - path; - } - else - { - coap_pkt->location_path_len = strlen(path); - } - - coap_pkt->location_path = path; - - SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH); - return coap_pkt->location_path_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_location_query(void *packet, const char **query) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY)) return 0; - - *query = coap_pkt->location_query; - return coap_pkt->location_query_len; -} - -int -coap_set_header_location_query(void *packet, const char *query) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - while (query[0]=='?') ++query; - - coap_pkt->location_query = query; - coap_pkt->location_query_len = strlen(query); - - SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY); - return coap_pkt->location_query_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_observe(void *packet, uint32_t *observe) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) return 0; - - *observe = coap_pkt->observe; - return 1; -} - -int -coap_set_header_observe(void *packet, uint32_t observe) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->observe = observe; - SET_OPTION(coap_pkt, COAP_OPTION_OBSERVE); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK2)) return 0; - - /* pointers may be NULL to get only specific block parameters */ - if (num!=NULL) *num = coap_pkt->block2_num; - if (more!=NULL) *more = coap_pkt->block2_more; - if (size!=NULL) *size = coap_pkt->block2_size; - if (offset!=NULL) *offset = coap_pkt->block2_offset; - - return 1; -} - -int -coap_set_header_block2(void *packet, uint32_t num, uint8_t more, uint16_t size) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (size<16) return 0; - if (size>2048) return 0; - if (num>0x0FFFFF) return 0; - - coap_pkt->block2_num = num; - coap_pkt->block2_more = more ? 1 : 0; - coap_pkt->block2_size = size; - - SET_OPTION(coap_pkt, COAP_OPTION_BLOCK2); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK1)) return 0; - - /* pointers may be NULL to get only specific block parameters */ - if (num!=NULL) *num = coap_pkt->block1_num; - if (more!=NULL) *more = coap_pkt->block1_more; - if (size!=NULL) *size = coap_pkt->block1_size; - if (offset!=NULL) *offset = coap_pkt->block1_offset; - - return 1; -} - -int -coap_set_header_block1(void *packet, uint32_t num, uint8_t more, uint16_t size) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (size<16) return 0; - if (size>2048) return 0; - if (num>0x0FFFFF) return 0; - - coap_pkt->block1_num = num; - coap_pkt->block1_more = more; - coap_pkt->block1_size = size; - - SET_OPTION(coap_pkt, COAP_OPTION_BLOCK1); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -/*- PAYLOAD -------------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -int -coap_get_payload(void *packet, const uint8_t **payload) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (coap_pkt->payload) { - *payload = coap_pkt->payload; - return coap_pkt->payload_len; - } else { - *payload = NULL; - return 0; - } -} - -int -coap_set_payload(void *packet, const void *payload, size_t length) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - PRINTF("setting payload (%u/%u)\n", length, REST_MAX_CHUNK_SIZE); - - coap_pkt->payload = (uint8_t *) payload; - coap_pkt->payload_len = MIN(REST_MAX_CHUNK_SIZE, length); - - return coap_pkt->payload_len; -} -/*-----------------------------------------------------------------------------------*/ diff --git a/apps/er-coap-07/er-coap-07.h b/apps/er-coap-07/er-coap-07.h deleted file mode 100644 index 52ad10209..000000000 --- a/apps/er-coap-07/er-coap-07.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * An implementation of the Constrained Application Protocol (draft 07) - * \author - * Matthias Kovatsch - */ - -#ifndef COAP_07_H_ -#define COAP_07_H_ - -#include /* for size_t */ -#include "contiki-net.h" -#include "erbium.h" - -#define COAP_DEFAULT_PORT 5683 - -#ifndef COAP_SERVER_PORT -#define COAP_SERVER_PORT COAP_DEFAULT_PORT -#endif - -#define COAP_DEFAULT_MAX_AGE 60 -#define COAP_RESPONSE_TIMEOUT 2 -#define COAP_RESPONSE_RANDOM_FACTOR 1.5 -#define COAP_MAX_RETRANSMIT 4 - -#define COAP_HEADER_LEN 4 /* | oc:0xF0 type:0x0C version:0x03 | code | mid:0x00FF | mid:0xFF00 | */ -#define COAP_ETAG_LEN 8 /* The maximum number of bytes for the ETag */ -#define COAP_TOKEN_LEN 8 /* The maximum number of bytes for the Token */ -#define COAP_MAX_ACCEPT_NUM 2 /* The maximum number of accept preferences to parse/store */ - -#define COAP_HEADER_VERSION_MASK 0xC0 -#define COAP_HEADER_VERSION_POSITION 6 -#define COAP_HEADER_TYPE_MASK 0x30 -#define COAP_HEADER_TYPE_POSITION 4 -#define COAP_HEADER_OPTION_COUNT_MASK 0x0F -#define COAP_HEADER_OPTION_COUNT_POSITION 0 - -#define COAP_HEADER_OPTION_DELTA_MASK 0xF0 -#define COAP_HEADER_OPTION_SHORT_LENGTH_MASK 0x0F - -/* - * Conservative size limit, as not all options have to be set at the same time. - */ -/* Hdr CoT Age Tag Obs Tok Blo strings */ -#define COAP_MAX_HEADER_SIZE (4 + 3 + 5 + 1+COAP_ETAG_LEN + 3 + 1+COAP_TOKEN_LEN + 4 + 10) /* 50 */ -#define COAP_MAX_PACKET_SIZE (COAP_MAX_HEADER_SIZE + REST_MAX_CHUNK_SIZE) -/* 0/14 48 for IPv6 (28 for IPv4) */ -#if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN) -#error "UIP_CONF_BUFFER_SIZE too small for REST_MAX_CHUNK_SIZE" -#endif - -/* - * Maximum number of failed request attempts before action - */ -#ifndef COAP_MAX_ATTEMPTS -#define COAP_MAX_ATTEMPTS 4 -#endif /* COAP_MAX_ATTEMPTS */ - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN]) - -#define SET_OPTION(packet, opt) ((packet)->options |= 1L<options & 1L< - */ - -#include -#include -#include -#include "contiki.h" -#include "contiki-net.h" - -#include "er-coap-12-engine.h" - -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#define PRINTBITS(buf,len) { \ - int i,j=0; \ - for (i=0; i=0; --j) { \ - PRINTF("%c", (((char *)buf)[i] & 1<srcipaddr); - PRINTF(":%u\n Length: %u\n Data: ", uip_ntohs(UIP_UDP_BUF->srcport), uip_datalen() ); - PRINTBITS(uip_appdata, uip_datalen()); - PRINTF("\n"); - - coap_error_code = coap_parse_message(message, uip_appdata, uip_datalen()); - - if (coap_error_code==NO_ERROR) - { - - /*TODO duplicates suppression, if required by application */ - - PRINTF(" Parsed: v %u, t %u, oc %u, c %u, mid %u\n", message->version, message->type, message->option_count, message->code, message->mid); - PRINTF(" URL: %.*s\n", message->uri_path_len, message->uri_path); - PRINTF(" Payload: %.*s\n", message->payload_len, message->payload); - - /* Handle requests. */ - if (message->code >= COAP_GET && message->code <= COAP_DELETE) - { - /* Use transaction buffer for response to confirmable request. */ - if ( (transaction = coap_new_transaction(message->mid, &UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport)) ) - { - uint32_t block_num = 0; - uint16_t block_size = REST_MAX_CHUNK_SIZE; - uint32_t block_offset = 0; - int32_t new_offset = 0; - - /* prepare response */ - if (message->type==COAP_TYPE_CON) - { - /* Reliable CON requests are answered with an ACK. */ - coap_init_message(response, COAP_TYPE_ACK, CONTENT_2_05, message->mid); - } - else - { - /* Unreliable NON requests are answered with a NON as well. */ - coap_init_message(response, COAP_TYPE_NON, CONTENT_2_05, coap_get_mid()); - } - - /* resource handlers must take care of different handling (e.g., TOKEN_OPTION_REQUIRED_240) */ - if (IS_OPTION(message, COAP_OPTION_TOKEN)) - { - coap_set_header_token(response, message->token, message->token_len); - SET_OPTION(response, COAP_OPTION_TOKEN); - } - - /* get offset for blockwise transfers */ - if (coap_get_header_block2(message, &block_num, NULL, &block_size, &block_offset)) - { - PRINTF("Blockwise: block request %lu (%u/%u) @ %lu bytes\n", block_num, block_size, REST_MAX_CHUNK_SIZE, block_offset); - block_size = MIN(block_size, REST_MAX_CHUNK_SIZE); - new_offset = block_offset; - } - - /* Invoke resource handler. */ - if (service_cbk) - { - /* Call REST framework and check if found and allowed. */ - if (service_cbk(message, response, transaction->packet+COAP_MAX_HEADER_SIZE, block_size, &new_offset)) - { - if (coap_error_code==NO_ERROR) - { - /* Apply blockwise transfers. */ - if ( IS_OPTION(message, COAP_OPTION_BLOCK1) && response->codepayload_len, block_size); - if (block_offset >= response->payload_len) - { - PRINTF("handle_incoming_data(): block_offset >= response->payload_len\n"); - - response->code = BAD_OPTION_4_02; - coap_set_payload(response, "BlockOutOfScope", 15); /* a const char str[] and sizeof(str) produces larger code size */ - } - else - { - coap_set_header_block2(response, block_num, response->payload_len - block_offset > block_size, block_size); - coap_set_payload(response, response->payload+block_offset, MIN(response->payload_len - block_offset, block_size)); - } /* if (valid offset) */ - } - else - { - /* resource provides chunk-wise data */ - PRINTF("Blockwise: blockwise resource, new offset %ld\n", new_offset); - coap_set_header_block2(response, block_num, new_offset!=-1 || response->payload_len > block_size, block_size); - if (response->payload_len > block_size) coap_set_payload(response, response->payload, block_size); - } /* if (resource aware of blockwise) */ - } - else if (new_offset!=0) - { - PRINTF("Blockwise: no block option for blockwise resource, using block size %u\n", REST_MAX_CHUNK_SIZE); - - coap_set_header_block2(response, 0, new_offset!=-1, REST_MAX_CHUNK_SIZE); - coap_set_payload(response, response->payload, MIN(response->payload_len, REST_MAX_CHUNK_SIZE)); - } /* if (blockwise request) */ - } /* no errors/hooks */ - } /* successful service callback */ - - /* Serialize response. */ - if (coap_error_code==NO_ERROR) - { - if ((transaction->packet_len = coap_serialize_message(response, transaction->packet))==0) - { - coap_error_code = PACKET_SERIALIZATION_ERROR; - } - } - - } - else - { - coap_error_code = NOT_IMPLEMENTED_5_01; - coap_error_message = "NoServiceCallbck"; // no a to fit 16 bytes - } /* if (service callback) */ - - } else { - coap_error_code = SERVICE_UNAVAILABLE_5_03; - coap_error_message = "NoFreeTraBuffer"; - } /* if (transaction buffer) */ - } - else - { - /* Responses */ - - if (message->type==COAP_TYPE_ACK) - { - PRINTF("Received ACK\n"); - } - else if (message->type==COAP_TYPE_RST) - { - PRINTF("Received RST\n"); - /* Cancel possible subscriptions. */ - coap_remove_observer_by_mid(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, message->mid); - } - - if ( (transaction = coap_get_transaction_by_mid(message->mid)) ) - { - /* Free transaction memory before callback, as it may create a new transaction. */ - restful_response_handler callback = transaction->callback; - void *callback_data = transaction->callback_data; - coap_clear_transaction(transaction); - - /* Check if someone registered for the response */ - if (callback) { - callback(callback_data, message); - } - } /* if (ACKed transaction) */ - transaction = NULL; - - } /* Request or Response */ - - } /* if (parsed correctly) */ - - if (coap_error_code==NO_ERROR) - { - if (transaction) coap_send_transaction(transaction); - } - else if (coap_error_code==MANUAL_RESPONSE) - { - PRINTF("Clearing transaction for manual response"); - coap_clear_transaction(transaction); - } - else - { - PRINTF("ERROR %u: %s\n", coap_error_code, coap_error_message); - coap_clear_transaction(transaction); - - /* Set to sendable error code. */ - if (coap_error_code >= 192) - { - coap_error_code = INTERNAL_SERVER_ERROR_5_00; - } - /* Reuse input buffer for error message. */ - coap_init_message(message, COAP_TYPE_ACK, coap_error_code, message->mid); - coap_set_payload(message, coap_error_message, strlen(coap_error_message)); - coap_send_message(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, uip_appdata, coap_serialize_message(message, uip_appdata)); - } - } /* if (new data) */ - - return coap_error_code; -} -/*----------------------------------------------------------------------------*/ -void -coap_receiver_init() -{ - process_start(&coap_receiver, NULL); -} -/*----------------------------------------------------------------------------*/ -void -coap_set_service_callback(service_callback_t callback) -{ - service_cbk = callback; -} -/*----------------------------------------------------------------------------*/ -rest_resource_flags_t -coap_get_rest_method(void *packet) -{ - return (rest_resource_flags_t)(1 << (((coap_packet_t *)packet)->code - 1)); -} -/*----------------------------------------------------------------------------*/ -/*- Server part --------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ - -/* The discover resource is automatically included for CoAP. */ -RESOURCE(well_known_core, METHOD_GET, ".well-known/core", "ct=40"); -void -well_known_core_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - size_t strpos = 0; /* position in overall string (which is larger than the buffer) */ - size_t bufpos = 0; /* position within buffer (bytes written) */ - size_t tmplen = 0; - resource_t* resource = NULL; - -#if COAP_LINK_FORMAT_FILTERING - /* For filtering. */ - const char *filter = NULL; - const char *attrib = NULL; - const char *found = NULL; - const char *end = NULL; - char *value = NULL; - char lastchar; - int len = coap_get_header_uri_query(request, &filter); - if (len) - { - value = strchr(filter, '='); - value[0] = '\0'; - ++value; - len -= strlen(filter)+1; - - PRINTF("Filter %s = %.*s\n", filter, len, value); - - if (strcmp(filter,"href")==0 && value[0]=='/') - { - ++value; - --len; - } - - lastchar = value[len-1]; - value[len-1] = '\0'; - } -#endif - - for (resource = (resource_t*)list_head(rest_get_resources()); resource; resource = resource->next) - { -#if COAP_LINK_FORMAT_FILTERING - /* Filtering */ - if (len) - { - if (strcmp(filter,"href")==0) - { - attrib=strstr(resource->url, value); - if (attrib==NULL || (value[-1]=='/' && attrib!=resource->url)) continue; - end = attrib + strlen(attrib); - } - else - { - attrib=strstr(resource->attributes, filter); - if (attrib==NULL || (attrib[strlen(filter)]!='=' && attrib[strlen(filter)]!='"')) continue; - attrib += strlen(filter)+2; - end = strchr(attrib, '"'); - } - - PRINTF("Filter: res has attrib %s (%s)\n", attrib, value); - found = attrib; - while ((found=strstr(found, value))!=NULL) { - if (found > end) - { - found = NULL; - break; - } - if (lastchar==found[len-1] || lastchar=='*') - { - break; - } - ++found; - } - if (found==NULL) - { - continue; - } - PRINTF("Filter: res has prefix %s\n", found); - if (lastchar!='*' && (found[len]!='"' && found[len]!=' ' && found[len]!='\0')) continue; - PRINTF("Filter: res has match\n"); - } -#endif - - PRINTF("res: /%s (%p)\npos: s%d, o%d, b%d\n", resource->url, resource, strpos, *offset, bufpos); - - if (strpos>0) - { - if (strpos >= *offset && bufpos < preferred_size) - { - buffer[bufpos++] = ','; - } - ++strpos; - } - - if (strpos >= *offset && bufpos < preferred_size) - { - buffer[bufpos++] = '<'; - } - ++strpos; - - if (strpos >= *offset && bufpos < preferred_size) - { - buffer[bufpos++] = '/'; - } - ++strpos; - - tmplen = strlen(resource->url); - if (strpos+tmplen > *offset) - { - bufpos += snprintf((char *) buffer + bufpos, preferred_size - bufpos + 1, - "%s", resource->url + ((*offset-(int32_t)strpos > 0) ? (*offset-(int32_t)strpos) : 0)); - /* minimal-net requires these casts */ - if (bufpos >= preferred_size) - { - break; - } - } - strpos += tmplen; - - if (strpos >= *offset && bufpos < preferred_size) - { - buffer[bufpos++] = '>'; - } - ++strpos; - - if (resource->attributes[0]) - { - if (strpos >= *offset && bufpos < preferred_size) - { - buffer[bufpos++] = ';'; - } - ++strpos; - - tmplen = strlen(resource->attributes); - if (strpos+tmplen > *offset) - { - bufpos += snprintf((char *) buffer + bufpos, preferred_size - bufpos + 1, - "%s", resource->attributes + (*offset-(int32_t)strpos > 0 ? *offset-(int32_t)strpos : 0)); - if (bufpos >= preferred_size) - { - break; - } - } - strpos += tmplen; - } - - /* buffer full, but resource not completed yet; or: do not break if resource exactly fills buffer. */ - if (bufpos >= preferred_size && strpos-bufpos > *offset) - { - PRINTF("res: BREAK at %s (%p)\n", resource->url, resource); - break; - } - } - - if (bufpos>0) { - PRINTF("BUF %d: %.*s\n", bufpos, bufpos, (char *) buffer); - - coap_set_payload(response, buffer, bufpos ); - coap_set_header_content_type(response, APPLICATION_LINK_FORMAT); - } - else if (strpos>0) - { - PRINTF("well_known_core_handler(): bufpos<=0\n"); - - coap_set_status_code(response, BAD_OPTION_4_02); - coap_set_payload(response, "BlockOutOfScope", 15); - } - - if (resource==NULL) { - PRINTF("res: DONE\n"); - *offset = -1; - } - else - { - PRINTF("res: MORE at %s (%p)\n", resource->url, resource); - *offset += preferred_size; - } -} -/*----------------------------------------------------------------------------*/ -PROCESS_THREAD(coap_receiver, ev, data) -{ - PROCESS_BEGIN(); - PRINTF("Starting CoAP-12 receiver...\n"); - - rest_activate_resource(&resource_well_known_core); - - coap_register_as_transaction_handler(); - coap_init_connection(SERVER_LISTEN_PORT); - - while(1) { - PROCESS_YIELD(); - - if(ev == tcpip_event) { - coap_receive(); - } else if (ev == PROCESS_EVENT_TIMER) { - /* retransmissions are handled here */ - coap_check_transactions(); - } - } /* while (1) */ - - PROCESS_END(); -} -/*----------------------------------------------------------------------------*/ -/*- Client part --------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -void coap_blocking_request_callback(void *callback_data, void *response) { - struct request_state_t *state = (struct request_state_t *) callback_data; - state->response = (coap_packet_t*) response; - process_poll(state->process); -} -/*----------------------------------------------------------------------------*/ -PT_THREAD(coap_blocking_request(struct request_state_t *state, process_event_t ev, - uip_ipaddr_t *remote_ipaddr, uint16_t remote_port, - coap_packet_t *request, - blocking_response_handler request_callback)) { - PT_BEGIN(&state->pt); - - static uint8_t more; - static uint32_t res_block; - static uint8_t block_error; - - state->block_num = 0; - state->response = NULL; - state->process = PROCESS_CURRENT(); - - more = 0; - res_block = 0; - block_error = 0; - - do { - request->mid = coap_get_mid(); - if ((state->transaction = coap_new_transaction(request->mid, remote_ipaddr, remote_port))) - { - state->transaction->callback = coap_blocking_request_callback; - state->transaction->callback_data = state; - - if (state->block_num>0) - { - coap_set_header_block2(request, state->block_num, 0, REST_MAX_CHUNK_SIZE); - } - - state->transaction->packet_len = coap_serialize_message(request, state->transaction->packet); - - coap_send_transaction(state->transaction); - PRINTF("Requested #%lu (MID %u)\n", state->block_num, request->mid); - - PT_YIELD_UNTIL(&state->pt, ev == PROCESS_EVENT_POLL); - - if (!state->response) - { - PRINTF("Server not responding\n"); - PT_EXIT(&state->pt); - } - - coap_get_header_block2(state->response, &res_block, &more, NULL, NULL); - - PRINTF("Received #%lu%s (%u bytes)\n", res_block, more ? "+" : "", state->response->payload_len); - - if (res_block==state->block_num) - { - request_callback(state->response); - ++(state->block_num); - } - else - { - PRINTF("WRONG BLOCK %lu/%lu\n", res_block, state->block_num); - ++block_error; - } - } - else - { - PRINTF("Could not allocate transaction buffer"); - PT_EXIT(&state->pt); - } - } while (more && block_errorpt); -} -/*----------------------------------------------------------------------------*/ -/*- Engine Interface ---------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -const struct rest_implementation coap_rest_implementation = { - "CoAP-12", - - coap_receiver_init, - coap_set_service_callback, - - coap_get_header_uri_path, - coap_set_header_uri_path, - coap_get_rest_method, - coap_set_status_code, - - coap_get_header_content_type, - coap_set_header_content_type, - coap_get_header_accept, - coap_get_header_size, - coap_set_header_size, - coap_get_header_max_age, - coap_set_header_max_age, - coap_set_header_etag, - coap_get_header_if_match, - coap_get_header_if_none_match, - coap_get_header_uri_host, - coap_set_header_location_path, - - coap_get_payload, - coap_set_payload, - - coap_get_header_uri_query, - coap_get_query_variable, - coap_get_post_variable, - - coap_notify_observers, - (restful_post_handler) coap_observe_handler, - - NULL, /* default pre-handler (set separate handler after activation if needed) */ - NULL, /* default post-handler for non-observable resources */ - - { - CONTENT_2_05, - CREATED_2_01, - CHANGED_2_04, - DELETED_2_02, - VALID_2_03, - BAD_REQUEST_4_00, - UNAUTHORIZED_4_01, - BAD_OPTION_4_02, - FORBIDDEN_4_03, - NOT_FOUND_4_04, - METHOD_NOT_ALLOWED_4_05, - NOT_ACCEPTABLE_4_06, - REQUEST_ENTITY_TOO_LARGE_4_13, - UNSUPPORTED_MEDIA_TYPE_4_15, - INTERNAL_SERVER_ERROR_5_00, - NOT_IMPLEMENTED_5_01, - BAD_GATEWAY_5_02, - SERVICE_UNAVAILABLE_5_03, - GATEWAY_TIMEOUT_5_04, - PROXYING_NOT_SUPPORTED_5_05 - }, - - { - TEXT_PLAIN, - TEXT_XML, - TEXT_CSV, - TEXT_HTML, - IMAGE_GIF, - IMAGE_JPEG, - IMAGE_PNG, - IMAGE_TIFF, - AUDIO_RAW, - VIDEO_RAW, - APPLICATION_LINK_FORMAT, - APPLICATION_XML, - APPLICATION_OCTET_STREAM, - APPLICATION_RDF_XML, - APPLICATION_SOAP_XML, - APPLICATION_ATOM_XML, - APPLICATION_XMPP_XML, - APPLICATION_EXI, - APPLICATION_FASTINFOSET, - APPLICATION_SOAP_FASTINFOSET, - APPLICATION_JSON, - APPLICATION_X_OBIX_BINARY - } -}; diff --git a/apps/er-coap-12/er-coap-12-engine.h b/apps/er-coap-12/er-coap-12-engine.h deleted file mode 100644 index d3e5c8bad..000000000 --- a/apps/er-coap-12/er-coap-12-engine.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2012, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP implementation of the REST Engine - * \author - * Matthias Kovatsch - */ - -#ifndef COAP_SERVER_H_ -#define COAP_SERVER_H_ - -#if !defined(REST) -#error "Define REST to \"coap_rest_implementation\"" -#endif - -#include "er-coap-12.h" -#include "er-coap-12-transactions.h" -#include "er-coap-12-observing.h" -#include "er-coap-12-separate.h" - -#include "pt.h" - -/* Declare server process */ -PROCESS_NAME(coap_receiver); - -#define SERVER_LISTEN_PORT UIP_HTONS(COAP_SERVER_PORT) - -typedef coap_packet_t rest_request_t; -typedef coap_packet_t rest_response_t; - -extern const struct rest_implementation coap_rest_implementation; - -void coap_receiver_init(void); - -/*-----------------------------------------------------------------------------------*/ -/*- Client part ---------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -struct request_state_t { - struct pt pt; - struct process *process; - coap_transaction_t *transaction; - coap_packet_t *response; - uint32_t block_num; -}; - -typedef void (*blocking_response_handler) (void* response); - -PT_THREAD(coap_blocking_request(struct request_state_t *state, process_event_t ev, - uip_ipaddr_t *remote_ipaddr, uint16_t remote_port, - coap_packet_t *request, - blocking_response_handler request_callback)); - -#define COAP_BLOCKING_REQUEST(server_addr, server_port, request, chunk_handler) \ -{ \ - static struct request_state_t request_state; \ - PT_SPAWN(process_pt, &request_state.pt, \ - coap_blocking_request(&request_state, ev, \ - server_addr, server_port, \ - request, chunk_handler) \ - ); \ -} -/*-----------------------------------------------------------------------------------*/ - -#endif /* COAP_SERVER_H_ */ diff --git a/apps/er-coap-12/er-coap-12-observing.c b/apps/er-coap-12/er-coap-12-observing.c deleted file mode 100644 index 323a90fe3..000000000 --- a/apps/er-coap-12/er-coap-12-observing.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP module for observing resources - * \author - * Matthias Kovatsch - */ - -#include -#include - -#include "er-coap-12-observing.h" - -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - - -MEMB(observers_memb, coap_observer_t, COAP_MAX_OBSERVERS); -LIST(observers_list); - -/*-----------------------------------------------------------------------------------*/ -coap_observer_t * -coap_add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token, size_t token_len, const char *url) -{ - /* Remove existing observe relationship, if any. */ - coap_remove_observer_by_url(addr, port, url); - - coap_observer_t *o = memb_alloc(&observers_memb); - - if (o) - { - o->url = url; - uip_ipaddr_copy(&o->addr, addr); - o->port = port; - o->token_len = token_len; - memcpy(o->token, token, token_len); - o->last_mid = 0; - - stimer_set(&o->refresh_timer, COAP_OBSERVING_REFRESH_INTERVAL); - - PRINTF("Adding observer for /%s [0x%02X%02X]\n", o->url, o->token[0], o->token[1]); - list_add(observers_list, o); - } - - return o; -} -/*-----------------------------------------------------------------------------------*/ -void -coap_remove_observer(coap_observer_t *o) -{ - PRINTF("Removing observer for /%s [0x%02X%02X]\n", o->url, o->token[0], o->token[1]); - - memb_free(&observers_memb, o); - list_remove(observers_list, o); -} - -int -coap_remove_observer_by_client(uip_ipaddr_t *addr, uint16_t port) -{ - int removed = 0; - coap_observer_t* obs = NULL; - - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - PRINTF("Remove check client "); - PRINT6ADDR(addr); - PRINTF(":%u\n", port); - if (uip_ipaddr_cmp(&obs->addr, addr) && obs->port==port) - { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} - -int -coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port, uint8_t *token, size_t token_len) -{ - int removed = 0; - coap_observer_t* obs = NULL; - - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - PRINTF("Remove check Token 0x%02X%02X\n", token[0], token[1]); - if (uip_ipaddr_cmp(&obs->addr, addr) && obs->port==port && obs->token_len==token_len && memcmp(obs->token, token, token_len)==0) - { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} - -int -coap_remove_observer_by_url(uip_ipaddr_t *addr, uint16_t port, const char *url) -{ - int removed = 0; - coap_observer_t* obs = NULL; - - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - PRINTF("Remove check URL %p\n", url); - if ((addr==NULL || (uip_ipaddr_cmp(&obs->addr, addr) && obs->port==port)) && (obs->url==url || memcmp(obs->url, url, strlen(obs->url))==0)) - { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} - -int -coap_remove_observer_by_mid(uip_ipaddr_t *addr, uint16_t port, uint16_t mid) -{ - int removed = 0; - coap_observer_t* obs = NULL; - - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - PRINTF("Remove check MID %u\n", mid); - if (uip_ipaddr_cmp(&obs->addr, addr) && obs->port==port && obs->last_mid==mid) - { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} -/*-----------------------------------------------------------------------------------*/ -void -coap_notify_observers(resource_t *resource, int32_t obs_counter, void *notification) -{ - coap_packet_t *const coap_res = (coap_packet_t *) notification; - coap_observer_t* obs = NULL; - uint8_t preferred_type = coap_res->type; - - PRINTF("Observing: Notification from %s\n", resource->url); - - /* Iterate over observers. */ - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - if (obs->url==resource->url) /* using RESOURCE url pointer as handle */ - { - coap_transaction_t *transaction = NULL; - - /*TODO implement special transaction for CON, sharing the same buffer to allow for more observers. */ - - if ( (transaction = coap_new_transaction(coap_get_mid(), &obs->addr, obs->port)) ) - { - PRINTF(" Observer "); - PRINT6ADDR(&obs->addr); - PRINTF(":%u\n", obs->port); - - /* Update last MID for RST matching. */ - obs->last_mid = transaction->mid; - - /* Prepare response */ - coap_res->mid = transaction->mid; - if (obs_counter>=0) coap_set_header_observe(coap_res, obs_counter); - coap_set_header_token(coap_res, obs->token, obs->token_len); - - /* Use CON to check whether client is still there/interested after COAP_OBSERVING_REFRESH_INTERVAL. */ - if (stimer_expired(&obs->refresh_timer)) - { - PRINTF(" Refreshing with CON\n"); - coap_res->type = COAP_TYPE_CON; - stimer_restart(&obs->refresh_timer); - } - else - { - coap_res->type = preferred_type; - } - - transaction->packet_len = coap_serialize_message(coap_res, transaction->packet); - - coap_send_transaction(transaction); - } - } - } -} -/*-----------------------------------------------------------------------------------*/ -void -coap_observe_handler(resource_t *resource, void *request, void *response) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - coap_packet_t *const coap_res = (coap_packet_t *) response; - - static char content[16]; - - if (coap_req->code==COAP_GET && coap_res->code<128) /* GET request and response without error code */ - { - if (IS_OPTION(coap_req, COAP_OPTION_OBSERVE)) - { - - if (coap_add_observer(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, coap_req->token, coap_req->token_len, resource->url)) - { - coap_set_header_observe(coap_res, 0); - /* - * For demonstration purposes only. A subscription should return the same representation as a normal GET. - * TODO: Comment the following line for any real application. - */ - coap_set_payload(coap_res, content, snprintf(content, sizeof(content), "Added %u/%u", list_length(observers_list), COAP_MAX_OBSERVERS)); - } - else - { - coap_res->code = SERVICE_UNAVAILABLE_5_03; - coap_set_payload(coap_res, "TooManyObservers", 16); - } /* if (added observer) */ - } - else /* if (observe) */ - { - /* Remove client if it is currently observing. */ - coap_remove_observer_by_url(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, resource->url); - } /* if (observe) */ - } -} diff --git a/apps/er-coap-12/er-coap-12-observing.h b/apps/er-coap-12/er-coap-12-observing.h deleted file mode 100644 index 78aa64d05..000000000 --- a/apps/er-coap-12/er-coap-12-observing.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2012, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP module for observing resources - * \author - * Matthias Kovatsch - */ - -#ifndef COAP_OBSERVING_H_ -#define COAP_OBSERVING_H_ - -#include "sys/stimer.h" -#include "er-coap-12.h" -#include "er-coap-12-transactions.h" - -#ifndef COAP_MAX_OBSERVERS -#define COAP_MAX_OBSERVERS COAP_MAX_OPEN_TRANSACTIONS-1 -#endif /* COAP_MAX_OBSERVERS */ - -/* Interval in seconds in which NON notifies are changed to CON notifies to check client. */ -#define COAP_OBSERVING_REFRESH_INTERVAL 60 - -#if COAP_MAX_OPEN_TRANSACTIONS - */ - -#include -#include - -#include "er-coap-12-separate.h" -#include "er-coap-12-transactions.h" - -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - -/*----------------------------------------------------------------------------*/ -void -coap_separate_reject() -{ - coap_error_code = SERVICE_UNAVAILABLE_5_03; - coap_error_message = "AlreadyInUse"; -} -/*----------------------------------------------------------------------------*/ -int -coap_separate_accept(void *request, coap_separate_t *separate_store) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - coap_transaction_t *const t = coap_get_transaction_by_mid(coap_req->mid); - - PRINTF("Separate ACCEPT: /%.*s MID %u\n", coap_req->uri_path_len, coap_req->uri_path, coap_req->mid); - if (t) - { - /* Send separate ACK for CON. */ - if (coap_req->type==COAP_TYPE_CON) - { - coap_packet_t ack[1]; - /* ACK with empty code (0) */ - coap_init_message(ack, COAP_TYPE_ACK, 0, coap_req->mid); - /* Serializing into IPBUF: Only overwrites header parts that are already parsed into the request struct. */ - coap_send_message(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, (uip_appdata), coap_serialize_message(ack, uip_appdata)); - } - - /* Store remote address. */ - uip_ipaddr_copy(&separate_store->addr, &t->addr); - separate_store->port = t->port; - - /* Store correct response type. */ - separate_store->type = coap_req->type==COAP_TYPE_CON ? COAP_TYPE_CON : COAP_TYPE_NON; - separate_store->mid = coap_get_mid(); /* if it was a NON, we burned one MID in the engine... */ - - memcpy(separate_store->token, coap_req->token, coap_req->token_len); - separate_store->token_len = coap_req->token_len; - - separate_store->block2_num = coap_req->block2_num; - separate_store->block2_size = coap_req->block2_size; - - /* Signal the engine to skip automatic response and clear transaction by engine. */ - coap_error_code = MANUAL_RESPONSE; - - return 1; - } - else - { - PRINTF("ERROR: Response transaction for separate request not found!\n"); - return 0; - } -} -/*----------------------------------------------------------------------------*/ -void -coap_separate_resume(void *response, coap_separate_t *separate_store, uint8_t code) -{ - coap_init_message(response, separate_store->type, code, separate_store->mid); - if (separate_store->token_len) - { - coap_set_header_token(response, separate_store->token, separate_store->token_len); - } -} diff --git a/apps/er-coap-12/er-coap-12-transactions.c b/apps/er-coap-12/er-coap-12-transactions.c deleted file mode 100644 index 3cd496e65..000000000 --- a/apps/er-coap-12/er-coap-12-transactions.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2012, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP module for reliable transport - * \author - * Matthias Kovatsch - */ - -#include "contiki.h" -#include "contiki-net.h" - -#include "er-coap-12-transactions.h" -#include "er-coap-12-observing.h" - -/* - * Modulo mask (+1 and +0.5 for rounding) for a random number to get the tick number for the random - * retransmission time between COAP_RESPONSE_TIMEOUT and COAP_RESPONSE_TIMEOUT*COAP_RESPONSE_RANDOM_FACTOR. - */ -#define COAP_RESPONSE_TIMEOUT_TICKS (CLOCK_SECOND * COAP_RESPONSE_TIMEOUT) -#define COAP_RESPONSE_TIMEOUT_BACKOFF_MASK ((CLOCK_SECOND * COAP_RESPONSE_TIMEOUT * (COAP_RESPONSE_RANDOM_FACTOR - 1)) + 1.5) - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - - -MEMB(transactions_memb, coap_transaction_t, COAP_MAX_OPEN_TRANSACTIONS); -LIST(transactions_list); - - -static struct process *transaction_handler_process = NULL; - -void -coap_register_as_transaction_handler() -{ - transaction_handler_process = PROCESS_CURRENT(); -} - -coap_transaction_t * -coap_new_transaction(uint16_t mid, uip_ipaddr_t *addr, uint16_t port) -{ - coap_transaction_t *t = memb_alloc(&transactions_memb); - - if (t) - { - t->mid = mid; - t->retrans_counter = 0; - - /* save client address */ - uip_ipaddr_copy(&t->addr, addr); - t->port = port; - - list_add(transactions_list, t); /* List itself makes sure same element is not added twice. */ - } - - return t; -} - -void -coap_send_transaction(coap_transaction_t *t) -{ - PRINTF("Sending transaction %u\n", t->mid); - - coap_send_message(&t->addr, t->port, t->packet, t->packet_len); - - if (COAP_TYPE_CON==((COAP_HEADER_TYPE_MASK & t->packet[0])>>COAP_HEADER_TYPE_POSITION)) - { - if (t->retrans_countermid); - - if (t->retrans_counter==0) - { - t->retrans_timer.timer.interval = COAP_RESPONSE_TIMEOUT_TICKS + (random_rand() % (clock_time_t) COAP_RESPONSE_TIMEOUT_BACKOFF_MASK); - PRINTF("Initial interval %f\n", (float)t->retrans_timer.timer.interval/CLOCK_SECOND); - } - else - { - t->retrans_timer.timer.interval <<= 1; /* double */ - PRINTF("Doubled (%u) interval %f\n", t->retrans_counter, (float)t->retrans_timer.timer.interval/CLOCK_SECOND); - } - - /*FIXME - * Hack: Setting timer for responsible process. - * Maybe there is a better way, but avoid posting everything to the process. - */ - struct process *process_actual = PROCESS_CURRENT(); - process_current = transaction_handler_process; - etimer_restart(&t->retrans_timer); /* interval updated above */ - process_current = process_actual; - - t = NULL; - } - else - { - /* Timed out. */ - PRINTF("Timeout\n"); - restful_response_handler callback = t->callback; - void *callback_data = t->callback_data; - - /* handle observers */ - coap_remove_observer_by_client(&t->addr, t->port); - - coap_clear_transaction(t); - - if (callback) { - callback(callback_data, NULL); - } - } - } - else - { - coap_clear_transaction(t); - } -} - -void -coap_clear_transaction(coap_transaction_t *t) -{ - if (t) - { - PRINTF("Freeing transaction %u: %p\n", t->mid, t); - - etimer_stop(&t->retrans_timer); - list_remove(transactions_list, t); - memb_free(&transactions_memb, t); - } -} - -coap_transaction_t * -coap_get_transaction_by_mid(uint16_t mid) -{ - coap_transaction_t *t = NULL; - - for (t = (coap_transaction_t*)list_head(transactions_list); t; t = t->next) - { - if (t->mid==mid) - { - PRINTF("Found transaction for MID %u: %p\n", t->mid, t); - return t; - } - } - return NULL; -} - -void -coap_check_transactions() -{ - coap_transaction_t *t = NULL; - - for (t = (coap_transaction_t*)list_head(transactions_list); t; t = t->next) - { - if (etimer_expired(&t->retrans_timer)) - { - ++(t->retrans_counter); - PRINTF("Retransmitting %u (%u)\n", t->mid, t->retrans_counter); - coap_send_transaction(t); - } - } -} diff --git a/apps/er-coap-12/er-coap-12.c b/apps/er-coap-12/er-coap-12.c deleted file mode 100644 index 0e68bfa34..000000000 --- a/apps/er-coap-12/er-coap-12.c +++ /dev/null @@ -1,1155 +0,0 @@ -/* - * Copyright (c) 2012, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * An implementation of the Constrained Application Protocol (draft 12) - * \author - * Matthias Kovatsch - */ - -#include "contiki.h" -#include "contiki-net.h" -#include -#include - -#include "er-coap-12.h" -#include "er-coap-12-transactions.h" - - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - -/*-----------------------------------------------------------------------------------*/ -/*- Variables -----------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -static struct uip_udp_conn *udp_conn = NULL; -static uint16_t current_mid = 0; - -coap_status_t coap_error_code = NO_ERROR; -char *coap_error_message = ""; -/*-----------------------------------------------------------------------------------*/ -/*- LOCAL HELP FUNCTIONS ------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -static -uint16_t -coap_log_2(uint16_t value) -{ - uint16_t result = 0; - do { - value = value >> 1; - result++; - } while (value); - - return result ? result - 1 : result; -} -/*-----------------------------------------------------------------------------------*/ -static -uint32_t -coap_parse_int_option(uint8_t *bytes, uint16_t length) -{ - uint32_t var = 0; - int i = 0; - while (i 254) - { - PRINTF("+255"); - buffer[++size] = 0xFF; - length -= 255; - } - PRINTF("+%u\n", length); - buffer[++size] = 0xFF & length; - return ++size; - } -} -/*-----------------------------------------------------------------------------------*/ -static -size_t -coap_insert_option_jump(unsigned int number, unsigned int *current_number, uint8_t *buffer) -{ - unsigned int delta = number-*current_number; - if (delta < 15) - { - return 0; - } - else if (delta < 30) - { - buffer[0] = 0xF1; - *current_number += 15; - - PRINTF("OPTION JUMP 1: 15\n"); - return 1; - } - else if (delta < 2064) - { - buffer[0] = 0xF2; - buffer[1] = ((delta/8)-2); - *current_number += buffer[1]; - - PRINTF("OPTION JUMP 2: %u\n", buffer[1]); - return 2; - } - else /* no upper bound check as delta is 16 bit */ - { - buffer[0] = 0xF3; - delta = ((delta/8)-258); - buffer[1] = delta>>8; - buffer[2] = 0xFF & delta; - *current_number += delta; - - PRINTF("OPTION JUMP 3: %u\n", delta); - return 3; - } -} -/*-----------------------------------------------------------------------------------*/ -static -size_t -coap_serialize_int_option(unsigned int number, unsigned int current_number, uint8_t *buffer, uint32_t value) -{ - /* Insert jumps for large deltas */ - size_t i = coap_insert_option_jump(number, ¤t_number, buffer); - size_t start_i = i; - - uint8_t *option = &buffer[i]; - - if (0xFF000000 & value) buffer[++i] = (uint8_t) (0xFF & value>>24); - if (0xFFFF0000 & value) buffer[++i] = (uint8_t) (0xFF & value>>16); - if (0xFFFFFF00 & value) buffer[++i] = (uint8_t) (0xFF & value>>8); - if (0xFFFFFFFF & value) buffer[++i] = (uint8_t) (0xFF & value); - - i += coap_set_option_header(number - current_number, i-start_i, option); - - PRINTF("OPTION type %u, delta %u, len %u\n", number, number - current_number, i-start_i); - - return i; -} -/*-----------------------------------------------------------------------------------*/ -/* - * Pass the char to split the string at in split_option and receive the number of options in split_option on return. - */ -static -size_t -coap_serialize_array_option(unsigned int number, unsigned int current_number, uint8_t *buffer, uint8_t *array, size_t length, uint8_t *split_option) -{ - /* Insert jumps for large deltas */ - size_t i = coap_insert_option_jump(number, ¤t_number, buffer); - - if (*split_option!='\0') - { - int j; - uint8_t *part_start = array; - uint8_t *part_end = NULL; - size_t temp_length; - - char split_char = *split_option; - *split_option = 0; /* Ensure reflecting the created option count */ - - for (j = 0; j<=length; ++j) - { - if (array[j]==split_char || j==length) - { - part_end = array + j; - temp_length = part_end-part_start; - - i += coap_set_option_header(number - current_number, temp_length, &buffer[i]); - memcpy(&buffer[i], part_start, temp_length); - i += temp_length; - - PRINTF("OPTION type %u, delta %u, len %u, part [%.*s]\n", number, number - current_number, i, temp_length, part_start); - - ++(*split_option); - ++j; /* skip the slash */ - current_number = number; - while( array[j]=='/') ++j; - part_start = array + j; - } - } /* for */ - } - else - { - i += coap_set_option_header(number - current_number, length, &buffer[i]); - memcpy(&buffer[i], array, length); - i += length; - - *split_option = 1; - - PRINTF("OPTION type %u, delta %u, len %u\n", number, number - current_number, length); - } - - return i; -} -/*-----------------------------------------------------------------------------------*/ -static -void -coap_merge_multi_option(char **dst, size_t *dst_len, uint8_t *option, size_t option_len, char separator) -{ - /* Merge multiple options. */ - if (*dst_len > 0) - { - /* dst already contains an option: concatenate */ - (*dst)[*dst_len] = separator; - *dst_len += 1; - - /* memmove handles 2-byte option headers */ - memmove((*dst)+(*dst_len), option, option_len); - - *dst_len += option_len; - } - else - { - /* dst is empty: set to option */ - *dst = (char *) option; - *dst_len = option_len; - } -} -/*-----------------------------------------------------------------------------------*/ -static -int -coap_get_variable(const char *buffer, size_t length, const char *name, const char **output) -{ - const char *start = NULL; - const char *end = NULL; - const char *value_end = NULL; - size_t name_len = 0; - - /*initialize the output buffer first*/ - *output = 0; - - name_len = strlen(name); - end = buffer + length; - - for (start = buffer; start + name_len < end; ++start){ - if ((start == buffer || start[-1] == '&') && start[name_len] == '=' && - strncmp(name, start, name_len)==0) { - - /* Point start to variable value */ - start += name_len + 1; - - /* Point end to the end of the value */ - value_end = (const char *) memchr(start, '&', end - start); - if (value_end == NULL) { - value_end = end; - } - - *output = start; - - return (value_end - start); - } - } - - return 0; -} -/*-----------------------------------------------------------------------------------*/ -/*- MEASSAGE SENDING ----------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -void -coap_init_connection(uint16_t port) -{ - /* new connection with remote host */ - udp_conn = udp_new(NULL, 0, NULL); - udp_bind(udp_conn, port); - PRINTF("Listening on port %u\n", uip_ntohs(udp_conn->lport)); - - /* Initialize transaction ID. */ - current_mid = random_rand(); -} -/*-----------------------------------------------------------------------------------*/ -uint16_t -coap_get_mid() -{ - return ++current_mid; -} -/*-----------------------------------------------------------------------------------*/ -/*- MEASSAGE PROCESSING -------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -void -coap_init_message(void *packet, coap_message_type_t type, uint8_t code, uint16_t mid) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - /* Important thing */ - memset(coap_pkt, 0, sizeof(coap_packet_t)); - - coap_pkt->type = type; - coap_pkt->code = code; - coap_pkt->mid = mid; -} -/*-----------------------------------------------------------------------------------*/ -size_t -coap_serialize_message(void *packet, uint8_t *buffer) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - /* Initialize */ - coap_pkt->buffer = buffer; - coap_pkt->version = 1; - coap_pkt->option_count = 0; - - /* Serialize options */ - uint8_t *option = coap_pkt->buffer + COAP_HEADER_LEN; - unsigned int current_number = 0; - - PRINTF("-Serializing options-\n"); - - /* The options must be serialized in the order of their number */ - COAP_SERIALIZE_BYTE_OPTION( COAP_OPTION_IF_MATCH, if_match, "If-Match") - COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_URI_HOST, uri_host, '\0', "Uri-Host") - COAP_SERIALIZE_BYTE_OPTION( COAP_OPTION_ETAG, etag, "ETag") - COAP_SERIALIZE_INT_OPTION( COAP_OPTION_IF_NONE_MATCH, content_type-coap_pkt->content_type, "If-None-Match") /* hack to get a zero field */ - COAP_SERIALIZE_INT_OPTION( COAP_OPTION_OBSERVE, observe, "Observe") - COAP_SERIALIZE_INT_OPTION( COAP_OPTION_URI_PORT, uri_port, "Uri-Port") - COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_LOCATION_PATH, location_path, '/', "Location-Path") - COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_URI_PATH, uri_path, '/', "Uri-Path") - COAP_SERIALIZE_INT_OPTION( COAP_OPTION_CONTENT_TYPE, content_type, "Content-Format") - COAP_SERIALIZE_INT_OPTION( COAP_OPTION_MAX_AGE, max_age, "Max-Age") - COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_URI_QUERY, uri_query, '&', "Uri-Query") - COAP_SERIALIZE_ACCEPT_OPTION( COAP_OPTION_ACCEPT, accept, "Accept") - COAP_SERIALIZE_BYTE_OPTION( COAP_OPTION_TOKEN, token, "Token") - COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_LOCATION_QUERY, location_query, '&', "Location-Query") - COAP_SERIALIZE_BLOCK_OPTION( COAP_OPTION_BLOCK2, block2, "Block2") - COAP_SERIALIZE_BLOCK_OPTION( COAP_OPTION_BLOCK1, block1, "Block1") - COAP_SERIALIZE_INT_OPTION( COAP_OPTION_SIZE, size, "Size") - COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_PROXY_URI, proxy_uri, '\0', "Proxy-Uri") - - /* Option terminator 0xF0 for 15 and more options */ - if (coap_pkt->option_count>14) - { - coap_pkt->option_count = 15; - *option = 0xF0; - ++option; - } - - /* pack payload */ - if ((option - coap_pkt->buffer)<=COAP_MAX_HEADER_SIZE) - { - memmove(option, coap_pkt->payload, coap_pkt->payload_len); - } - else - { - /* An error occured. Caller must check for !=0. */ - coap_pkt->buffer = NULL; - coap_error_message = "Serialized header exceeds COAP_MAX_HEADER_SIZE"; - return 0; - } - - /* set header fields */ - coap_pkt->buffer[0] = 0x00; - coap_pkt->buffer[0] |= COAP_HEADER_VERSION_MASK & (coap_pkt->version)<buffer[0] |= COAP_HEADER_TYPE_MASK & (coap_pkt->type)<buffer[0] |= COAP_HEADER_OPTION_COUNT_MASK & (coap_pkt->option_count)<buffer[1] = coap_pkt->code; - coap_pkt->buffer[2] = 0xFF & (coap_pkt->mid)>>8; - coap_pkt->buffer[3] = 0xFF & coap_pkt->mid; - - PRINTF("-Done %u options, header len %u, payload len %u-\n", coap_pkt->option_count, option - buffer, coap_pkt->payload_len); - - return (option - buffer) + coap_pkt->payload_len; /* packet length */ -} -/*-----------------------------------------------------------------------------------*/ -void -coap_send_message(uip_ipaddr_t *addr, uint16_t port, uint8_t *data, uint16_t length) -{ - /* Configure connection to reply to client */ - uip_ipaddr_copy(&udp_conn->ripaddr, addr); - udp_conn->rport = port; - - uip_udp_packet_send(udp_conn, data, length); - PRINTF("-sent UDP datagram (%u)-\n", length); - - /* Restore server connection to allow data from any node */ - memset(&udp_conn->ripaddr, 0, sizeof(udp_conn->ripaddr)); - udp_conn->rport = 0; -} -/*-----------------------------------------------------------------------------------*/ -coap_status_t -coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - /* Initialize packet */ - memset(coap_pkt, 0, sizeof(coap_packet_t)); - - /* pointer to packet bytes */ - coap_pkt->buffer = data; - - /* parse header fields */ - coap_pkt->version = (COAP_HEADER_VERSION_MASK & coap_pkt->buffer[0])>>COAP_HEADER_VERSION_POSITION; - coap_pkt->type = (COAP_HEADER_TYPE_MASK & coap_pkt->buffer[0])>>COAP_HEADER_TYPE_POSITION; - coap_pkt->option_count = (COAP_HEADER_OPTION_COUNT_MASK & coap_pkt->buffer[0])>>COAP_HEADER_OPTION_COUNT_POSITION; - coap_pkt->code = coap_pkt->buffer[1]; - coap_pkt->mid = coap_pkt->buffer[2]<<8 | coap_pkt->buffer[3]; - - if (coap_pkt->version != 1) - { - coap_error_message = "CoAP version must be 1"; - return BAD_REQUEST_4_00; - } - - /* parse options */ - memset(coap_pkt->options, 0, sizeof(coap_pkt->options)); - uint8_t *current_option = data + COAP_HEADER_LEN; - - if (coap_pkt->option_count) - { - int option_index = 0; - - unsigned int current_number = 0; - size_t option_len = 0; - - PRINTF("-Parsing %u options-\n", coap_pkt->option_count); - for (option_index=0; option_index < coap_pkt->option_count || coap_pkt->option_count==15; ++option_index) { - - /* Option terminator 0xF0 */ - if (current_option[0]==0xF0) - { - break; - } - /* Option jumps */ - else if (current_option[0]==0xF1) - { - PRINTF("JUMP 1: 15\n"); - current_number += 15; - ++current_option; - } - else if (current_option[0]==0xF2) - { - PRINTF("JUMP 2: %u\n", (current_option[1]+2) * 8); - current_number += (current_option[1]+2) * 8; - current_option += 2; - } - else if (current_option[0]==0xF3) - { - unsigned int jump = (current_option[1]<<8) | current_option[2]; - PRINTF("JUMP 3: %u\n", (jump+258) * 8); - current_number += (jump+258) * 8; - current_option +=3; - } - - current_number += current_option[0]>>4; - - PRINTF("OPTION %u (type %u, delta %u, len %u", option_index, current_number, current_option[0]>>4, (0x0F & current_option[0])); - - if ((0x0F & current_option[0]) < 15) - { - option_len = 0x0F & current_option[0]; - ++current_option; - } - else - { - option_len = 15; - do - { - ++current_option; - option_len += current_option[0]; - PRINTF("+%u", current_option[0]); - } while (current_option[0]==255); - ++current_option; - } - PRINTF("=%u: ", option_len); - - SET_OPTION(coap_pkt, current_number); - - switch (current_number) - { - case COAP_OPTION_CONTENT_TYPE: - coap_pkt->content_type = coap_parse_int_option(current_option, option_len); - PRINTF("Content-Format [%u]\n", coap_pkt->content_type); - break; - case COAP_OPTION_MAX_AGE: - coap_pkt->max_age = coap_parse_int_option(current_option, option_len); - PRINTF("Max-Age [%lu]\n", coap_pkt->max_age); - break; - case COAP_OPTION_PROXY_URI: - /*FIXME check for own end-point */ - coap_pkt->proxy_uri = (char *) current_option; - coap_pkt->proxy_uri_len = option_len; - /*TODO length > 270 not implemented (actually not required) */ - PRINTF("Proxy-Uri NOT IMPLEMENTED [%.*s]\n", coap_pkt->proxy_uri_len, coap_pkt->proxy_uri); - coap_error_message = "This is a constrained server (Contiki)"; - return PROXYING_NOT_SUPPORTED_5_05; - break; - case COAP_OPTION_ETAG: - coap_pkt->etag_len = MIN(COAP_ETAG_LEN, option_len); - memcpy(coap_pkt->etag, current_option, coap_pkt->etag_len); - PRINTF("ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->etag_len, - coap_pkt->etag[0], - coap_pkt->etag[1], - coap_pkt->etag[2], - coap_pkt->etag[3], - coap_pkt->etag[4], - coap_pkt->etag[5], - coap_pkt->etag[6], - coap_pkt->etag[7] - ); /*FIXME always prints 8 bytes */ - break; - case COAP_OPTION_URI_HOST: - coap_pkt->uri_host = (char *) current_option; - coap_pkt->uri_host_len = option_len; - PRINTF("Uri-Host [%.*s]\n", coap_pkt->uri_host_len, coap_pkt->uri_host); - break; - case COAP_OPTION_LOCATION_PATH: - /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ - coap_merge_multi_option( (char **) &(coap_pkt->location_path), &(coap_pkt->location_path_len), current_option, option_len, '/'); - PRINTF("Location-Path [%.*s]\n", coap_pkt->location_path_len, coap_pkt->location_path); - break; - case COAP_OPTION_URI_PORT: - coap_pkt->uri_port = coap_parse_int_option(current_option, option_len); - PRINTF("Uri-Port [%u]\n", coap_pkt->uri_port); - break; - case COAP_OPTION_LOCATION_QUERY: - /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ - coap_merge_multi_option( (char **) &(coap_pkt->location_query), &(coap_pkt->location_query_len), current_option, option_len, '&'); - PRINTF("Location-Query [%.*s]\n", coap_pkt->location_query_len, coap_pkt->location_query); - break; - case COAP_OPTION_URI_PATH: - /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ - coap_merge_multi_option( (char **) &(coap_pkt->uri_path), &(coap_pkt->uri_path_len), current_option, option_len, '/'); - PRINTF("Uri-Path [%.*s]\n", coap_pkt->uri_path_len, coap_pkt->uri_path); - break; - case COAP_OPTION_OBSERVE: - coap_pkt->observe = coap_parse_int_option(current_option, option_len); - PRINTF("Observe [%lu]\n", coap_pkt->observe); - break; - case COAP_OPTION_TOKEN: - coap_pkt->token_len = MIN(COAP_TOKEN_LEN, option_len); - memcpy(coap_pkt->token, current_option, coap_pkt->token_len); - PRINTF("Token %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->token_len, - coap_pkt->token[0], - coap_pkt->token[1], - coap_pkt->token[2], - coap_pkt->token[3], - coap_pkt->token[4], - coap_pkt->token[5], - coap_pkt->token[6], - coap_pkt->token[7] - ); /*FIXME always prints 8 bytes */ - break; - case COAP_OPTION_ACCEPT: - if (coap_pkt->accept_num < COAP_MAX_ACCEPT_NUM) - { - coap_pkt->accept[coap_pkt->accept_num] = coap_parse_int_option(current_option, option_len); - coap_pkt->accept_num += 1; - PRINTF("Accept [%u]\n", coap_pkt->content_type); - } - break; - case COAP_OPTION_IF_MATCH: - /*FIXME support multiple ETags */ - coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, option_len); - memcpy(coap_pkt->if_match, current_option, coap_pkt->if_match_len); - PRINTF("If-Match %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->if_match_len, - coap_pkt->if_match[0], - coap_pkt->if_match[1], - coap_pkt->if_match[2], - coap_pkt->if_match[3], - coap_pkt->if_match[4], - coap_pkt->if_match[5], - coap_pkt->if_match[6], - coap_pkt->if_match[7] - ); /*FIXME always prints 8 bytes */ - break; - case COAP_OPTION_URI_QUERY: - /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ - coap_merge_multi_option( (char **) &(coap_pkt->uri_query), &(coap_pkt->uri_query_len), current_option, option_len, '&'); - PRINTF("Uri-Query [%.*s]\n", coap_pkt->uri_query_len, coap_pkt->uri_query); - break; - case COAP_OPTION_BLOCK2: - coap_pkt->block2_num = coap_parse_int_option(current_option, option_len); - coap_pkt->block2_more = (coap_pkt->block2_num & 0x08)>>3; - coap_pkt->block2_size = 16 << (coap_pkt->block2_num & 0x07); - coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F)<<(coap_pkt->block2_num & 0x07); - coap_pkt->block2_num >>= 4; - PRINTF("Block2 [%lu%s (%u B/blk)]\n", coap_pkt->block2_num, coap_pkt->block2_more ? "+" : "", coap_pkt->block2_size); - break; - case COAP_OPTION_BLOCK1: - coap_pkt->block1_num = coap_parse_int_option(current_option, option_len); - coap_pkt->block1_more = (coap_pkt->block1_num & 0x08)>>3; - coap_pkt->block1_size = 16 << (coap_pkt->block1_num & 0x07); - coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F)<<(coap_pkt->block1_num & 0x07); - coap_pkt->block1_num >>= 4; - PRINTF("Block1 [%lu%s (%u B/blk)]\n", coap_pkt->block1_num, coap_pkt->block1_more ? "+" : "", coap_pkt->block1_size); - break; - case COAP_OPTION_SIZE: - coap_pkt->size = coap_parse_int_option(current_option, option_len); - PRINTF("Size [%lu]\n", coap_pkt->size); - break; - case COAP_OPTION_IF_NONE_MATCH: - coap_pkt->if_none_match = 1; - PRINTF("If-None-Match\n"); - break; - default: - PRINTF("unknown (%u)\n", current_number); - /* Check if critical (odd) */ - if (current_number & 1) - { - coap_error_message = "Unsupported critical option"; - return BAD_OPTION_4_02; - } - } - - current_option += option_len; - } /* for */ - PRINTF("-Done parsing-------\n"); - } /* if (oc) */ - - coap_pkt->payload = current_option; - coap_pkt->payload_len = data_len - (coap_pkt->payload - data); - - /* also for receiving, the Erbium upper bound is REST_MAX_CHUNK_SIZE */ - if (coap_pkt->payload_len > REST_MAX_CHUNK_SIZE) - { - coap_pkt->payload_len = REST_MAX_CHUNK_SIZE; - } - - /* Null-terminate payload */ - coap_pkt->payload[coap_pkt->payload_len] = '\0'; - - return NO_ERROR; -} -/*-----------------------------------------------------------------------------------*/ -/*- REST FRAMEWORK FUNCTIONS --------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -int -coap_get_query_variable(void *packet, const char *name, const char **output) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) { - return coap_get_variable(coap_pkt->uri_query, coap_pkt->uri_query_len, name, output); - } - return 0; -} - -int -coap_get_post_variable(void *packet, const char *name, const char **output) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (coap_pkt->payload_len) { - return coap_get_variable((const char *)coap_pkt->payload, coap_pkt->payload_len, name, output); - } - return 0; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_set_status_code(void *packet, unsigned int code) -{ - if (code <= 0xFF) - { - ((coap_packet_t *)packet)->code = (uint8_t) code; - return 1; - } - else - { - return 0; - } -} -/*-----------------------------------------------------------------------------------*/ -/*- HEADER OPTION GETTERS AND SETTERS -----------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -unsigned int -coap_get_header_content_type(void *packet) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_CONTENT_TYPE)) return -1; - - return coap_pkt->content_type; -} - -int -coap_set_header_content_type(void *packet, unsigned int content_type) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->content_type = (coap_content_type_t) content_type; - SET_OPTION(coap_pkt, COAP_OPTION_CONTENT_TYPE); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_accept(void *packet, const uint16_t **accept) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_ACCEPT)) return 0; - - *accept = coap_pkt->accept; - return coap_pkt->accept_num; -} - -int -coap_set_header_accept(void *packet, uint16_t accept) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (coap_pkt->accept_num < COAP_MAX_ACCEPT_NUM) - { - coap_pkt->accept[coap_pkt->accept_num] = accept; - coap_pkt->accept_num += 1; - - SET_OPTION(coap_pkt, COAP_OPTION_ACCEPT); - } - return coap_pkt->accept_num; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_max_age(void *packet, uint32_t *age) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_MAX_AGE)) { - *age = COAP_DEFAULT_MAX_AGE; - } else { - *age = coap_pkt->max_age; - } - return 1; -} - -int -coap_set_header_max_age(void *packet, uint32_t age) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->max_age = age; - SET_OPTION(coap_pkt, COAP_OPTION_MAX_AGE); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_etag(void *packet, const uint8_t **etag) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) return 0; - - *etag = coap_pkt->etag; - return coap_pkt->etag_len; -} - -int -coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->etag_len = MIN(COAP_ETAG_LEN, etag_len); - memcpy(coap_pkt->etag, etag, coap_pkt->etag_len); - - SET_OPTION(coap_pkt, COAP_OPTION_ETAG); - return coap_pkt->etag_len; -} -/*-----------------------------------------------------------------------------------*/ -/*FIXME support multiple ETags */ -int -coap_get_header_if_match(void *packet, const uint8_t **etag) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_IF_MATCH)) return 0; - - *etag = coap_pkt->if_match; - return coap_pkt->if_match_len; -} - -int -coap_set_header_if_match(void *packet, const uint8_t *etag, size_t etag_len) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, etag_len); - memcpy(coap_pkt->if_match, etag, coap_pkt->if_match_len); - - SET_OPTION(coap_pkt, COAP_OPTION_IF_MATCH); - return coap_pkt->if_match_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_if_none_match(void *packet) -{ - return IS_OPTION((coap_packet_t *)packet, COAP_OPTION_IF_NONE_MATCH) ? 1 : 0; -} - -int -coap_set_header_if_none_match(void *packet) -{ - SET_OPTION((coap_packet_t *)packet, COAP_OPTION_IF_NONE_MATCH); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_token(void *packet, const uint8_t **token) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_TOKEN)) return 0; - - *token = coap_pkt->token; - return coap_pkt->token_len; -} - -int -coap_set_header_token(void *packet, const uint8_t *token, size_t token_len) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->token_len = MIN(COAP_TOKEN_LEN, token_len); - memcpy(coap_pkt->token, token, coap_pkt->token_len); - - SET_OPTION(coap_pkt, COAP_OPTION_TOKEN); - return coap_pkt->token_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_proxy_uri(void *packet, const char **uri) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI)) return 0; - - *uri = coap_pkt->proxy_uri; - return coap_pkt->proxy_uri_len; -} - -int -coap_set_header_proxy_uri(void *packet, const char *uri) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->proxy_uri = uri; - coap_pkt->proxy_uri_len = strlen(uri); - - SET_OPTION(coap_pkt, COAP_OPTION_PROXY_URI); - return coap_pkt->proxy_uri_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_uri_host(void *packet, const char **host) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_HOST)) return 0; - - *host = coap_pkt->uri_host; - return coap_pkt->uri_host_len; -} - -int -coap_set_header_uri_host(void *packet, const char *host) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->uri_host = host; - coap_pkt->uri_host_len = strlen(host); - - SET_OPTION(coap_pkt, COAP_OPTION_URI_HOST); - return coap_pkt->uri_host_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_uri_path(void *packet, const char **path) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_PATH)) return 0; - - *path = coap_pkt->uri_path; - return coap_pkt->uri_path_len; -} - -int -coap_set_header_uri_path(void *packet, const char *path) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - while (path[0]=='/') ++path; - - coap_pkt->uri_path = path; - coap_pkt->uri_path_len = strlen(path); - - SET_OPTION(coap_pkt, COAP_OPTION_URI_PATH); - return coap_pkt->uri_path_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_uri_query(void *packet, const char **query) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) return 0; - - *query = coap_pkt->uri_query; - return coap_pkt->uri_query_len; -} - -int -coap_set_header_uri_query(void *packet, const char *query) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - while (query[0]=='?') ++query; - - coap_pkt->uri_query = query; - coap_pkt->uri_query_len = strlen(query); - - SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); - return coap_pkt->uri_query_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_location_path(void *packet, const char **path) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH)) return 0; - - *path = coap_pkt->location_path; - return coap_pkt->location_path_len; -} - -int -coap_set_header_location_path(void *packet, const char *path) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - char *query; - - while (path[0]=='/') ++path; - - if ((query = strchr(path, '?'))) - { - coap_set_header_location_query(packet, query+1); - coap_pkt->location_path_len = query - path; - } - else - { - coap_pkt->location_path_len = strlen(path); - } - - coap_pkt->location_path = path; - - SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH); - return coap_pkt->location_path_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_location_query(void *packet, const char **query) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY)) return 0; - - *query = coap_pkt->location_query; - return coap_pkt->location_query_len; -} - -int -coap_set_header_location_query(void *packet, const char *query) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - while (query[0]=='?') ++query; - - coap_pkt->location_query = query; - coap_pkt->location_query_len = strlen(query); - - SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY); - return coap_pkt->location_query_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_observe(void *packet, uint32_t *observe) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) return 0; - - *observe = coap_pkt->observe; - return 1; -} - -int -coap_set_header_observe(void *packet, uint32_t observe) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->observe = observe; - SET_OPTION(coap_pkt, COAP_OPTION_OBSERVE); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK2)) return 0; - - /* pointers may be NULL to get only specific block parameters */ - if (num!=NULL) *num = coap_pkt->block2_num; - if (more!=NULL) *more = coap_pkt->block2_more; - if (size!=NULL) *size = coap_pkt->block2_size; - if (offset!=NULL) *offset = coap_pkt->block2_offset; - - return 1; -} - -int -coap_set_header_block2(void *packet, uint32_t num, uint8_t more, uint16_t size) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (size<16) return 0; - if (size>2048) return 0; - if (num>0x0FFFFF) return 0; - - coap_pkt->block2_num = num; - coap_pkt->block2_more = more ? 1 : 0; - coap_pkt->block2_size = size; - - SET_OPTION(coap_pkt, COAP_OPTION_BLOCK2); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK1)) return 0; - - /* pointers may be NULL to get only specific block parameters */ - if (num!=NULL) *num = coap_pkt->block1_num; - if (more!=NULL) *more = coap_pkt->block1_more; - if (size!=NULL) *size = coap_pkt->block1_size; - if (offset!=NULL) *offset = coap_pkt->block1_offset; - - return 1; -} - -int -coap_set_header_block1(void *packet, uint32_t num, uint8_t more, uint16_t size) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (size<16) return 0; - if (size>2048) return 0; - if (num>0x0FFFFF) return 0; - - coap_pkt->block1_num = num; - coap_pkt->block1_more = more; - coap_pkt->block1_size = size; - - SET_OPTION(coap_pkt, COAP_OPTION_BLOCK1); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_size(void *packet, uint32_t *size) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_SIZE)) return 0; - - *size = coap_pkt->size; - return 1; -} - -int -coap_set_header_size(void *packet, uint32_t size) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->size = size; - SET_OPTION(coap_pkt, COAP_OPTION_SIZE); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -/*- PAYLOAD -------------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -int -coap_get_payload(void *packet, const uint8_t **payload) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (coap_pkt->payload) { - *payload = coap_pkt->payload; - return coap_pkt->payload_len; - } else { - *payload = NULL; - return 0; - } -} - -int -coap_set_payload(void *packet, const void *payload, size_t length) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - //PRINTF("setting payload (%u/%u)\n", length, REST_MAX_CHUNK_SIZE); - - coap_pkt->payload = (uint8_t *) payload; - coap_pkt->payload_len = MIN(REST_MAX_CHUNK_SIZE, length); - - return coap_pkt->payload_len; -} -/*-----------------------------------------------------------------------------------*/ diff --git a/apps/er-coap-12/er-coap-12.h b/apps/er-coap-12/er-coap-12.h deleted file mode 100644 index 78a642ba7..000000000 --- a/apps/er-coap-12/er-coap-12.h +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright (c) 2012, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * An implementation of the Constrained Application Protocol (draft 12) - * \author - * Matthias Kovatsch - */ - -#ifndef COAP_12_H_ -#define COAP_12_H_ - -#include /* for size_t */ -#include "contiki-net.h" -#include "erbium.h" - -#define COAP_LINK_FORMAT_FILTERING 1 - -#define COAP_DEFAULT_PORT 5683 - -#ifndef COAP_SERVER_PORT -#define COAP_SERVER_PORT COAP_DEFAULT_PORT -#endif - -#define COAP_DEFAULT_MAX_AGE 60 -#define COAP_RESPONSE_TIMEOUT 2 -#define COAP_RESPONSE_RANDOM_FACTOR 1.5 -#define COAP_MAX_RETRANSMIT 4 - -#define COAP_HEADER_LEN 4 /* | oc:0xF0 type:0x0C version:0x03 | code | mid:0x00FF | mid:0xFF00 | */ -#define COAP_ETAG_LEN 8 /* The maximum number of bytes for the ETag */ -#define COAP_TOKEN_LEN 8 /* The maximum number of bytes for the Token */ -#define COAP_MAX_ACCEPT_NUM 2 /* The maximum number of accept preferences to parse/store */ - -#define COAP_HEADER_VERSION_MASK 0xC0 -#define COAP_HEADER_VERSION_POSITION 6 -#define COAP_HEADER_TYPE_MASK 0x30 -#define COAP_HEADER_TYPE_POSITION 4 -#define COAP_HEADER_OPTION_COUNT_MASK 0x0F -#define COAP_HEADER_OPTION_COUNT_POSITION 0 - -#define COAP_HEADER_OPTION_DELTA_MASK 0xF0 -#define COAP_HEADER_OPTION_SHORT_LENGTH_MASK 0x0F - -/* - * Conservative size limit, as not all options have to be set at the same time. - */ -#ifndef COAP_MAX_HEADER_SIZE -/* Hdr CoT Age Tag Obs Tok Blo strings */ -#define COAP_MAX_HEADER_SIZE (4 + 3 + 5 + 1+COAP_ETAG_LEN + 3 + 1+COAP_TOKEN_LEN + 4 + 30) /* 70 */ -#endif /* COAP_MAX_HEADER_SIZE */ - -#define COAP_MAX_PACKET_SIZE (COAP_MAX_HEADER_SIZE + REST_MAX_CHUNK_SIZE) -/* 0/14 48 for IPv6 (28 for IPv4) */ -#if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN) -#error "UIP_CONF_BUFFER_SIZE too small for REST_MAX_CHUNK_SIZE" -#endif - -/* - * Maximum number of failed request attempts before action - */ -#ifndef COAP_MAX_ATTEMPTS -#define COAP_MAX_ATTEMPTS 4 -#endif /* COAP_MAX_ATTEMPTS */ - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN]) - -/* Bitmap for set options */ -enum { OPTION_MAP_SIZE = sizeof(uint8_t) * 8 }; -#define SET_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] |= 1 << (opt % OPTION_MAP_SIZE)) -#define IS_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] & (1 << (opt % OPTION_MAP_SIZE))) - -#ifndef MIN -#define MIN(a, b) ((a) < (b)? (a) : (b)) -#endif /* MIN */ - -/* CoAP message types */ -typedef enum { - COAP_TYPE_CON, /* confirmables */ - COAP_TYPE_NON, /* non-confirmables */ - COAP_TYPE_ACK, /* acknowledgements */ - COAP_TYPE_RST /* reset */ -} coap_message_type_t; - -/* CoAP request method codes */ -typedef enum { - COAP_GET = 1, - COAP_POST, - COAP_PUT, - COAP_DELETE -} coap_method_t; - -/* CoAP response codes */ -typedef enum { - NO_ERROR = 0, - - CREATED_2_01 = 65, /* CREATED */ - DELETED_2_02 = 66, /* DELETED */ - VALID_2_03 = 67, /* NOT_MODIFIED */ - CHANGED_2_04 = 68, /* CHANGED */ - CONTENT_2_05 = 69, /* OK */ - - BAD_REQUEST_4_00 = 128, /* BAD_REQUEST */ - UNAUTHORIZED_4_01 = 129, /* UNAUTHORIZED */ - BAD_OPTION_4_02 = 130, /* BAD_OPTION */ - FORBIDDEN_4_03 = 131, /* FORBIDDEN */ - NOT_FOUND_4_04 = 132, /* NOT_FOUND */ - METHOD_NOT_ALLOWED_4_05 = 133, /* METHOD_NOT_ALLOWED */ - NOT_ACCEPTABLE_4_06 = 134, /* NOT_ACCEPTABLE */ - PRECONDITION_FAILED_4_12 = 140, /* BAD_REQUEST */ - REQUEST_ENTITY_TOO_LARGE_4_13 = 141, /* REQUEST_ENTITY_TOO_LARGE */ - UNSUPPORTED_MEDIA_TYPE_4_15 = 143, /* UNSUPPORTED_MEDIA_TYPE */ - - INTERNAL_SERVER_ERROR_5_00 = 160, /* INTERNAL_SERVER_ERROR */ - NOT_IMPLEMENTED_5_01 = 161, /* NOT_IMPLEMENTED */ - BAD_GATEWAY_5_02 = 162, /* BAD_GATEWAY */ - SERVICE_UNAVAILABLE_5_03 = 163, /* SERVICE_UNAVAILABLE */ - GATEWAY_TIMEOUT_5_04 = 164, /* GATEWAY_TIMEOUT */ - PROXYING_NOT_SUPPORTED_5_05 = 165, /* PROXYING_NOT_SUPPORTED */ - - /* Erbium errors */ - MEMORY_ALLOCATION_ERROR = 192, - PACKET_SERIALIZATION_ERROR, - - /* Erbium hooks */ - MANUAL_RESPONSE - -} coap_status_t; - -/* CoAP header options */ -typedef enum { - COAP_OPTION_IF_MATCH = 1, /* 0-8 B */ - COAP_OPTION_URI_HOST = 3, /* 1-255 B */ - COAP_OPTION_ETAG = 4, /* 1-8 B */ - COAP_OPTION_IF_NONE_MATCH = 5, /* 0 B */ - COAP_OPTION_OBSERVE = 6, /* 0-3 B */ - COAP_OPTION_URI_PORT = 7, /* 0-2 B */ - COAP_OPTION_LOCATION_PATH = 8, /* 0-255 B */ - COAP_OPTION_URI_PATH = 11, /* 0-255 B */ - COAP_OPTION_CONTENT_TYPE = 12, /* 0-2 B */ - COAP_OPTION_MAX_AGE = 14, /* 0-4 B */ - COAP_OPTION_URI_QUERY = 15, /* 0-270 B */ - COAP_OPTION_ACCEPT = 16, /* 0-2 B */ - COAP_OPTION_TOKEN = 19, /* 1-8 B */ - COAP_OPTION_LOCATION_QUERY = 20, /* 1-270 B */ - COAP_OPTION_BLOCK2 = 23, /* 1-3 B */ - COAP_OPTION_BLOCK1 = 27, /* 1-3 B */ - COAP_OPTION_SIZE = 28, /* 0-4 B */ - COAP_OPTION_PROXY_URI = 35, /* 1-270 B */ -} coap_option_t; - -/* CoAP Content-Types */ -typedef enum { - TEXT_PLAIN = 0, - TEXT_XML = 1, /* Indented types are not in the initial registry. */ - TEXT_CSV = 2, - TEXT_HTML = 3, - IMAGE_GIF = 21, - IMAGE_JPEG = 22, - IMAGE_PNG = 23, - IMAGE_TIFF = 24, - AUDIO_RAW = 25, - VIDEO_RAW = 26, - APPLICATION_LINK_FORMAT = 40, - APPLICATION_XML = 41, - APPLICATION_OCTET_STREAM = 42, - APPLICATION_RDF_XML = 43, - APPLICATION_SOAP_XML = 44, - APPLICATION_ATOM_XML = 45, - APPLICATION_XMPP_XML = 46, - APPLICATION_EXI = 47, - APPLICATION_FASTINFOSET = 48, - APPLICATION_SOAP_FASTINFOSET = 49, - APPLICATION_JSON = 50, - APPLICATION_X_OBIX_BINARY = 51 -} coap_content_type_t; - -/* Parsed message struct */ -typedef struct { - uint8_t *buffer; /* pointer to CoAP header / incoming packet buffer / memory to serialize packet */ - - uint8_t version; - coap_message_type_t type; - uint8_t option_count; - uint8_t code; - uint16_t mid; - - uint8_t options[COAP_OPTION_PROXY_URI / OPTION_MAP_SIZE + 1]; /* Bitmap to check if option is set */ - - coap_content_type_t content_type; /* Parse options once and store; allows setting options in random order */ - uint32_t max_age; - size_t proxy_uri_len; - const char *proxy_uri; - uint8_t etag_len; - uint8_t etag[COAP_ETAG_LEN]; - size_t uri_host_len; - const char *uri_host; - size_t location_path_len; - const char *location_path; - uint16_t uri_port; - size_t location_query_len; - const char *location_query; - size_t uri_path_len; - const char *uri_path; - uint16_t observe; - uint8_t token_len; - uint8_t token[COAP_TOKEN_LEN]; - uint8_t accept_num; - uint16_t accept[COAP_MAX_ACCEPT_NUM]; - uint8_t if_match_len; - uint8_t if_match[COAP_ETAG_LEN]; - uint32_t block2_num; - uint8_t block2_more; - uint16_t block2_size; - uint32_t block2_offset; - uint32_t block1_num; - uint8_t block1_more; - uint16_t block1_size; - uint32_t block1_offset; - uint32_t size; - size_t uri_query_len; - const char *uri_query; - uint8_t if_none_match; - - uint16_t payload_len; - uint8_t *payload; - -} coap_packet_t; - -/* Option format serialization*/ -#define COAP_SERIALIZE_INT_OPTION(number, field, text) \ - if (IS_OPTION(coap_pkt, number)) { \ - PRINTF(text" [%u]\n", coap_pkt->field); \ - option += coap_serialize_int_option(number, current_number, option, coap_pkt->field); \ - coap_pkt->option_count += 1; \ - current_number = number; \ - } -#define COAP_SERIALIZE_BYTE_OPTION(number, field, text) \ - if (IS_OPTION(coap_pkt, number)) { \ - PRINTF(text" %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->field##_len, \ - coap_pkt->field[0], \ - coap_pkt->field[1], \ - coap_pkt->field[2], \ - coap_pkt->field[3], \ - coap_pkt->field[4], \ - coap_pkt->field[5], \ - coap_pkt->field[6], \ - coap_pkt->field[7] \ - ); /*FIXME always prints 8 bytes */ \ - uint8_t split_options = '\0'; \ - option += coap_serialize_array_option(number, current_number, option, coap_pkt->field, coap_pkt->field##_len, &split_options); \ - coap_pkt->option_count += split_options; \ - current_number = number; \ - } -#define COAP_SERIALIZE_STRING_OPTION(number, field, splitter, text) \ - if (IS_OPTION(coap_pkt, number)) { \ - PRINTF(text" [%.*s]\n", coap_pkt->field##_len, coap_pkt->field); \ - uint8_t split_options = splitter; \ - option += coap_serialize_array_option(number, current_number, option, (uint8_t *) coap_pkt->field, coap_pkt->field##_len, &split_options); \ - coap_pkt->option_count += split_options; \ - current_number = number; \ - } -#define COAP_SERIALIZE_ACCEPT_OPTION(number, field, text) \ - if (IS_OPTION(coap_pkt, number)) { \ - int i; \ - for (i=0; ifield##_num; ++i) \ - { \ - PRINTF(text" [%u]\n", coap_pkt->field[i]); \ - option += coap_serialize_int_option(number, current_number, option, coap_pkt->field[i]); \ - coap_pkt->option_count += 1; \ - current_number = number; \ - } \ - } -#define COAP_SERIALIZE_BLOCK_OPTION(number, field, text) \ - if (IS_OPTION(coap_pkt, number)) \ - { \ - PRINTF(text" [%lu%s (%u B/blk)]\n", coap_pkt->field##_num, coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size); \ - uint32_t block = coap_pkt->field##_num << 4; \ - if (coap_pkt->field##_more) block |= 0x8; \ - block |= 0xF & coap_log_2(coap_pkt->field##_size/16); \ - PRINTF(text" encoded: 0x%lX\n", block); \ - option += coap_serialize_int_option(number, current_number, option, block); \ - coap_pkt->option_count += 1; \ - current_number = number; \ - } - -/* To store error code and human-readable payload */ -extern coap_status_t coap_error_code; -extern char *coap_error_message; - -void coap_init_connection(uint16_t port); -uint16_t coap_get_mid(void); - -void coap_init_message(void *packet, coap_message_type_t type, uint8_t code, uint16_t mid); -size_t coap_serialize_message(void *packet, uint8_t *buffer); -void coap_send_message(uip_ipaddr_t *addr, uint16_t port, uint8_t *data, uint16_t length); -coap_status_t coap_parse_message(void *request, uint8_t *data, uint16_t data_len); - -int coap_get_query_variable(void *packet, const char *name, const char **output); -int coap_get_post_variable(void *packet, const char *name, const char **output); - -/*-----------------------------------------------------------------------------------*/ - -int coap_set_status_code(void *packet, unsigned int code); - -unsigned int coap_get_header_content_type(void *packet); -int coap_set_header_content_type(void *packet, unsigned int content_type); - -int coap_get_header_accept(void *packet, const uint16_t **accept); -int coap_set_header_accept(void *packet, uint16_t accept); - -int coap_get_header_max_age(void *packet, uint32_t *age); -int coap_set_header_max_age(void *packet, uint32_t age); - -int coap_get_header_etag(void *packet, const uint8_t **etag); -int coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len); - -int coap_get_header_if_match(void *packet, const uint8_t **etag); -int coap_set_header_if_match(void *packet, const uint8_t *etag, size_t etag_len); - -int coap_get_header_if_none_match(void *packet); -int coap_set_header_if_none_match(void *packet); - -int coap_get_header_token(void *packet, const uint8_t **token); -int coap_set_header_token(void *packet, const uint8_t *token, size_t token_len); - -int coap_get_header_proxy_uri(void *packet, const char **uri); /* In-place string might not be 0-terminated. */ -int coap_set_header_proxy_uri(void *packet, const char *uri); - -int coap_get_header_uri_host(void *packet, const char **host); /* In-place string might not be 0-terminated. */ -int coap_set_header_uri_host(void *packet, const char *host); - -int coap_get_header_uri_path(void *packet, const char **path); /* In-place string might not be 0-terminated. */ -int coap_set_header_uri_path(void *packet, const char *path); - -int coap_get_header_uri_query(void *packet, const char **query); /* In-place string might not be 0-terminated. */ -int coap_set_header_uri_query(void *packet, const char *query); - -int coap_get_header_location_path(void *packet, const char **path); /* In-place string might not be 0-terminated. */ -int coap_set_header_location_path(void *packet, const char *path); /* Also splits optional query into Location-Query option. */ - -int coap_get_header_location_query(void *packet, const char **query); /* In-place string might not be 0-terminated. */ -int coap_set_header_location_query(void *packet, const char *query); - -int coap_get_header_observe(void *packet, uint32_t *observe); -int coap_set_header_observe(void *packet, uint32_t observe); - -int coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset); -int coap_set_header_block2(void *packet, uint32_t num, uint8_t more, uint16_t size); - -int coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset); -int coap_set_header_block1(void *packet, uint32_t num, uint8_t more, uint16_t size); - -int coap_get_header_size(void *packet, uint32_t *size); -int coap_set_header_size(void *packet, uint32_t size); - -int coap_get_payload(void *packet, const uint8_t **payload); -int coap_set_payload(void *packet, const void *payload, size_t length); - -#endif /* COAP_12_H_ */ diff --git a/apps/er-coap-13/Makefile.er-coap-13 b/apps/er-coap-13/Makefile.er-coap-13 deleted file mode 100644 index b3c3ba169..000000000 --- a/apps/er-coap-13/Makefile.er-coap-13 +++ /dev/null @@ -1 +0,0 @@ -er-coap-13_src = er-coap-13.c er-coap-13-engine.c er-coap-13-transactions.c er-coap-13-observing.c er-coap-13-separate.c diff --git a/apps/er-coap-13/er-coap-13-engine.c b/apps/er-coap-13/er-coap-13-engine.c deleted file mode 100644 index 9bde8b7f7..000000000 --- a/apps/er-coap-13/er-coap-13-engine.c +++ /dev/null @@ -1,681 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP implementation of the REST Engine - * \author - * Matthias Kovatsch - */ - -#include -#include -#include -#include "contiki.h" -#include "contiki-net.h" - -#include "er-coap-13-engine.h" - -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#define PRINTBITS(buf,len) { \ - int i,j=0; \ - for (i=0; i=0; --j) { \ - PRINTF("%c", (((char *)buf)[i] & 1<srcipaddr); - PRINTF(":%u\n Length: %u\n Data: ", uip_ntohs(UIP_UDP_BUF->srcport), uip_datalen() ); - PRINTBITS(uip_appdata, uip_datalen()); - PRINTF("\n"); - - coap_error_code = coap_parse_message(message, uip_appdata, uip_datalen()); - - if (coap_error_code==NO_ERROR) - { - - /*TODO duplicates suppression, if required by application */ - - PRINTF(" Parsed: v %u, t %u, tkl %u, c %u, mid %u\n", message->version, message->type, message->token_len, message->code, message->mid); - PRINTF(" URL: %.*s\n", message->uri_path_len, message->uri_path); - PRINTF(" Payload: %.*s\n", message->payload_len, message->payload); - - /* Handle requests. */ - if (message->code >= COAP_GET && message->code <= COAP_DELETE) - { - /* Use transaction buffer for response to confirmable request. */ - if ( (transaction = coap_new_transaction(message->mid, &UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport)) ) - { - uint32_t block_num = 0; - uint16_t block_size = REST_MAX_CHUNK_SIZE; - uint32_t block_offset = 0; - int32_t new_offset = 0; - - /* prepare response */ - if (message->type==COAP_TYPE_CON) - { - /* Reliable CON requests are answered with an ACK. */ - coap_init_message(response, COAP_TYPE_ACK, CONTENT_2_05, message->mid); - } - else - { - /* Unreliable NON requests are answered with a NON as well. */ - coap_init_message(response, COAP_TYPE_NON, CONTENT_2_05, coap_get_mid()); - } - - /* mirror token */ - if (message->token_len) - { - coap_set_header_token(response, message->token, message->token_len); - } - - /* get offset for blockwise transfers */ - if (coap_get_header_block2(message, &block_num, NULL, &block_size, &block_offset)) - { - PRINTF("Blockwise: block request %lu (%u/%u) @ %lu bytes\n", block_num, block_size, REST_MAX_CHUNK_SIZE, block_offset); - block_size = MIN(block_size, REST_MAX_CHUNK_SIZE); - new_offset = block_offset; - } - - /* Invoke resource handler. */ - if (service_cbk) - { - /* Call REST framework and check if found and allowed. */ - if (service_cbk(message, response, transaction->packet+COAP_MAX_HEADER_SIZE, block_size, &new_offset)) - { - if (coap_error_code==NO_ERROR) - { - /* Apply blockwise transfers. */ - if ( IS_OPTION(message, COAP_OPTION_BLOCK1) && response->codepayload_len, block_size); - if (block_offset >= response->payload_len) - { - PRINTF("handle_incoming_data(): block_offset >= response->payload_len\n"); - - response->code = BAD_OPTION_4_02; - coap_set_payload(response, "BlockOutOfScope", 15); /* a const char str[] and sizeof(str) produces larger code size */ - } - else - { - coap_set_header_block2(response, block_num, response->payload_len - block_offset > block_size, block_size); - coap_set_payload(response, response->payload+block_offset, MIN(response->payload_len - block_offset, block_size)); - } /* if (valid offset) */ - } - else - { - /* resource provides chunk-wise data */ - PRINTF("Blockwise: blockwise resource, new offset %ld\n", new_offset); - coap_set_header_block2(response, block_num, new_offset!=-1 || response->payload_len > block_size, block_size); - if (response->payload_len > block_size) coap_set_payload(response, response->payload, block_size); - } /* if (resource aware of blockwise) */ - } - else if (new_offset!=0) - { - PRINTF("Blockwise: no block option for blockwise resource, using block size %u\n", REST_MAX_CHUNK_SIZE); - - coap_set_header_block2(response, 0, new_offset!=-1, REST_MAX_CHUNK_SIZE); - coap_set_payload(response, response->payload, MIN(response->payload_len, REST_MAX_CHUNK_SIZE)); - } /* if (blockwise request) */ - } /* no errors/hooks */ - } /* successful service callback */ - - /* Serialize response. */ - if (coap_error_code==NO_ERROR) - { - if ((transaction->packet_len = coap_serialize_message(response, transaction->packet))==0) - { - coap_error_code = PACKET_SERIALIZATION_ERROR; - } - } - - } - else - { - coap_error_code = NOT_IMPLEMENTED_5_01; - coap_error_message = "NoServiceCallbck"; // no a to fit 16 bytes - } /* if (service callback) */ - - } else { - coap_error_code = SERVICE_UNAVAILABLE_5_03; - coap_error_message = "NoFreeTraBuffer"; - } /* if (transaction buffer) */ - } - else - { - /* Responses */ - if (message->type==COAP_TYPE_CON && message->code==0) - { - PRINTF("Received Ping\n"); - coap_error_code = PING_RESPONSE; - } - else if (message->type==COAP_TYPE_ACK) - { - /* Transactions are closed through lookup below */ - PRINTF("Received ACK\n"); - } - else if (message->type==COAP_TYPE_RST) - { - PRINTF("Received RST\n"); - /* Cancel possible subscriptions. */ - coap_remove_observer_by_mid(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, message->mid); - } - - if ( (transaction = coap_get_transaction_by_mid(message->mid)) ) - { - /* Free transaction memory before callback, as it may create a new transaction. */ - restful_response_handler callback = transaction->callback; - void *callback_data = transaction->callback_data; - coap_clear_transaction(transaction); - - /* Check if someone registered for the response */ - if (callback) { - callback(callback_data, message); - } - } /* if (ACKed transaction) */ - transaction = NULL; - - } /* Request or Response */ - - } /* if (parsed correctly) */ - - if (coap_error_code==NO_ERROR) - { - if (transaction) coap_send_transaction(transaction); - } - else if (coap_error_code==MANUAL_RESPONSE) - { - PRINTF("Clearing transaction for manual response"); - coap_clear_transaction(transaction); - } - else - { - coap_message_type_t reply_type = COAP_TYPE_ACK; - - PRINTF("ERROR %u: %s\n", coap_error_code, coap_error_message); - coap_clear_transaction(transaction); - - /* Set to sendable error code. */ - if (coap_error_code >= 192) - { - coap_error_code = INTERNAL_SERVER_ERROR_5_00; - } - if (coap_error_code == PING_RESPONSE) - { - coap_error_code = 0; - reply_type = COAP_TYPE_RST; - } - /* Reuse input buffer for error message. */ - coap_init_message(message, reply_type, coap_error_code, message->mid); - coap_set_payload(message, coap_error_message, strlen(coap_error_message)); - coap_send_message(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, uip_appdata, coap_serialize_message(message, uip_appdata)); - } - } /* if (new data) */ - - return coap_error_code; -} -/*----------------------------------------------------------------------------*/ -void -coap_receiver_init() -{ - process_start(&coap_receiver, NULL); -} -/*----------------------------------------------------------------------------*/ -void -coap_set_service_callback(service_callback_t callback) -{ - service_cbk = callback; -} -/*----------------------------------------------------------------------------*/ -rest_resource_flags_t -coap_get_rest_method(void *packet) -{ - return (rest_resource_flags_t)(1 << (((coap_packet_t *)packet)->code - 1)); -} -/*----------------------------------------------------------------------------*/ -/*- Server part --------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ - -/* The discover resource is automatically included for CoAP. */ -RESOURCE(well_known_core, METHOD_GET, ".well-known/core", "ct=40"); -void -well_known_core_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - size_t strpos = 0; /* position in overall string (which is larger than the buffer) */ - size_t bufpos = 0; /* position within buffer (bytes written) */ - size_t tmplen = 0; - resource_t* resource = NULL; - -#if COAP_LINK_FORMAT_FILTERING - /* For filtering. */ - const char *filter = NULL; - const char *attrib = NULL; - const char *found = NULL; - const char *end = NULL; - char *value = NULL; - char lastchar = '\0'; - int len = coap_get_header_uri_query(request, &filter); - - if (len) - { - value = strchr(filter, '='); - value[0] = '\0'; - ++value; - len -= strlen(filter)+1; - - PRINTF("Filter %s = %.*s\n", filter, len, value); - - if (strcmp(filter,"href")==0 && value[0]=='/') - { - ++value; - --len; - } - - lastchar = value[len-1]; - value[len-1] = '\0'; - } -#endif - - for (resource = (resource_t*)list_head(rest_get_resources()); resource; resource = resource->next) - { -#if COAP_LINK_FORMAT_FILTERING - /* Filtering */ - if (len) - { - if (strcmp(filter,"href")==0) - { - attrib=strstr(resource->url, value); - if (attrib==NULL || (value[-1]=='/' && attrib!=resource->url)) continue; - end = attrib + strlen(attrib); - } - else - { - attrib=strstr(resource->attributes, filter); - if (attrib==NULL || (attrib[strlen(filter)]!='=' && attrib[strlen(filter)]!='"')) continue; - attrib += strlen(filter)+2; - end = strchr(attrib, '"'); - } - - PRINTF("Filter: res has attrib %s (%s)\n", attrib, value); - found = attrib; - while ((found=strstr(found, value))!=NULL) { - if (found > end) - { - found = NULL; - break; - } - if (lastchar==found[len-1] || lastchar=='*') - { - break; - } - ++found; - } - if (found==NULL) - { - continue; - } - PRINTF("Filter: res has prefix %s\n", found); - if (lastchar!='*' && (found[len]!='"' && found[len]!=' ' && found[len]!='\0')) continue; - PRINTF("Filter: res has match\n"); - } -#endif - - PRINTF("res: /%s (%p)\npos: s%d, o%ld, b%d\n", resource->url, resource, strpos, *offset, bufpos); - - if (strpos>0) - { - if (strpos >= *offset && bufpos < preferred_size) - { - buffer[bufpos++] = ','; - } - ++strpos; - } - - if (strpos >= *offset && bufpos < preferred_size) - { - buffer[bufpos++] = '<'; - } - ++strpos; - - if (strpos >= *offset && bufpos < preferred_size) - { - buffer[bufpos++] = '/'; - } - ++strpos; - - tmplen = strlen(resource->url); - if (strpos+tmplen > *offset) - { - bufpos += snprintf((char *) buffer + bufpos, preferred_size - bufpos + 1, - "%s", resource->url + ((*offset-(int32_t)strpos > 0) ? (*offset-(int32_t)strpos) : 0)); - /* minimal-net requires these casts */ - if (bufpos >= preferred_size) - { - break; - } - } - strpos += tmplen; - - if (strpos >= *offset && bufpos < preferred_size) - { - buffer[bufpos++] = '>'; - } - ++strpos; - - if (resource->attributes[0]) - { - if (strpos >= *offset && bufpos < preferred_size) - { - buffer[bufpos++] = ';'; - } - ++strpos; - - tmplen = strlen(resource->attributes); - if (strpos+tmplen > *offset) - { - bufpos += snprintf((char *) buffer + bufpos, preferred_size - bufpos + 1, - "%s", resource->attributes + (*offset-(int32_t)strpos > 0 ? *offset-(int32_t)strpos : 0)); - if (bufpos >= preferred_size) - { - break; - } - } - strpos += tmplen; - } - - /* buffer full, but resource not completed yet; or: do not break if resource exactly fills buffer. */ - if (bufpos >= preferred_size && strpos-bufpos > *offset) - { - PRINTF("res: BREAK at %s (%p)\n", resource->url, resource); - break; - } - } - - if (bufpos>0) { - PRINTF("BUF %d: %.*s\n", bufpos, bufpos, (char *) buffer); - - coap_set_payload(response, buffer, bufpos ); - coap_set_header_content_type(response, APPLICATION_LINK_FORMAT); - } - else if (strpos>0) - { - PRINTF("well_known_core_handler(): bufpos<=0\n"); - - coap_set_status_code(response, BAD_OPTION_4_02); - coap_set_payload(response, "BlockOutOfScope", 15); - } - - if (resource==NULL) { - PRINTF("res: DONE\n"); - *offset = -1; - } - else - { - PRINTF("res: MORE at %s (%p)\n", resource->url, resource); - *offset += preferred_size; - } -} -/*----------------------------------------------------------------------------*/ -PROCESS_THREAD(coap_receiver, ev, data) -{ - PROCESS_BEGIN(); - PRINTF("Starting CoAP-13 receiver...\n"); - - rest_activate_resource(&resource_well_known_core); - - coap_register_as_transaction_handler(); - coap_init_connection(SERVER_LISTEN_PORT); - - while(1) { - PROCESS_YIELD(); - - if(ev == tcpip_event) { - coap_receive(); - } else if (ev == PROCESS_EVENT_TIMER) { - /* retransmissions are handled here */ - coap_check_transactions(); - } - } /* while (1) */ - - PROCESS_END(); -} -/*----------------------------------------------------------------------------*/ -/*- Client part --------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -void coap_blocking_request_callback(void *callback_data, void *response) { - struct request_state_t *state = (struct request_state_t *) callback_data; - state->response = (coap_packet_t*) response; - process_poll(state->process); -} -/*----------------------------------------------------------------------------*/ -PT_THREAD(coap_blocking_request(struct request_state_t *state, process_event_t ev, - uip_ipaddr_t *remote_ipaddr, uint16_t remote_port, - coap_packet_t *request, - blocking_response_handler request_callback)) { - PT_BEGIN(&state->pt); - - static uint8_t more; - static uint32_t res_block; - static uint8_t block_error; - - state->block_num = 0; - state->response = NULL; - state->process = PROCESS_CURRENT(); - - more = 0; - res_block = 0; - block_error = 0; - - do { - request->mid = coap_get_mid(); - if ((state->transaction = coap_new_transaction(request->mid, remote_ipaddr, remote_port))) - { - state->transaction->callback = coap_blocking_request_callback; - state->transaction->callback_data = state; - - if (state->block_num>0) - { - coap_set_header_block2(request, state->block_num, 0, REST_MAX_CHUNK_SIZE); - } - - state->transaction->packet_len = coap_serialize_message(request, state->transaction->packet); - - coap_send_transaction(state->transaction); - PRINTF("Requested #%lu (MID %u)\n", state->block_num, request->mid); - - PT_YIELD_UNTIL(&state->pt, ev == PROCESS_EVENT_POLL); - - if (!state->response) - { - PRINTF("Server not responding\n"); - PT_EXIT(&state->pt); - } - - coap_get_header_block2(state->response, &res_block, &more, NULL, NULL); - - PRINTF("Received #%lu%s (%u bytes)\n", res_block, more ? "+" : "", state->response->payload_len); - - if (res_block==state->block_num) - { - request_callback(state->response); - ++(state->block_num); - } - else - { - PRINTF("WRONG BLOCK %lu/%lu\n", res_block, state->block_num); - ++block_error; - } - } - else - { - PRINTF("Could not allocate transaction buffer"); - PT_EXIT(&state->pt); - } - } while (more && block_errorpt); -} -/*----------------------------------------------------------------------------*/ -/*- Engine Interface ---------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -const struct rest_implementation coap_rest_implementation = { - "CoAP-13", - - coap_receiver_init, - coap_set_service_callback, - - coap_get_header_uri_path, - coap_set_header_uri_path, - coap_get_rest_method, - coap_set_status_code, - - coap_get_header_content_type, - coap_set_header_content_type, - coap_get_header_accept, - coap_get_header_size, - coap_set_header_size, - coap_get_header_max_age, - coap_set_header_max_age, - coap_set_header_etag, - coap_get_header_if_match, - coap_get_header_if_none_match, - coap_get_header_uri_host, - coap_set_header_location_path, - - coap_get_payload, - coap_set_payload, - - coap_get_header_uri_query, - coap_get_query_variable, - coap_get_post_variable, - - coap_notify_observers, - (restful_post_handler) coap_observe_handler, - - NULL, /* default pre-handler (set separate handler after activation if needed) */ - NULL, /* default post-handler for non-observable resources */ - - { - CONTENT_2_05, - CREATED_2_01, - CHANGED_2_04, - DELETED_2_02, - VALID_2_03, - BAD_REQUEST_4_00, - UNAUTHORIZED_4_01, - BAD_OPTION_4_02, - FORBIDDEN_4_03, - NOT_FOUND_4_04, - METHOD_NOT_ALLOWED_4_05, - NOT_ACCEPTABLE_4_06, - REQUEST_ENTITY_TOO_LARGE_4_13, - UNSUPPORTED_MEDIA_TYPE_4_15, - INTERNAL_SERVER_ERROR_5_00, - NOT_IMPLEMENTED_5_01, - BAD_GATEWAY_5_02, - SERVICE_UNAVAILABLE_5_03, - GATEWAY_TIMEOUT_5_04, - PROXYING_NOT_SUPPORTED_5_05 - }, - - { - TEXT_PLAIN, - TEXT_XML, - TEXT_CSV, - TEXT_HTML, - IMAGE_GIF, - IMAGE_JPEG, - IMAGE_PNG, - IMAGE_TIFF, - AUDIO_RAW, - VIDEO_RAW, - APPLICATION_LINK_FORMAT, - APPLICATION_XML, - APPLICATION_OCTET_STREAM, - APPLICATION_RDF_XML, - APPLICATION_SOAP_XML, - APPLICATION_ATOM_XML, - APPLICATION_XMPP_XML, - APPLICATION_EXI, - APPLICATION_FASTINFOSET, - APPLICATION_SOAP_FASTINFOSET, - APPLICATION_JSON, - APPLICATION_X_OBIX_BINARY - } -}; diff --git a/apps/er-coap-13/er-coap-13-engine.h b/apps/er-coap-13/er-coap-13-engine.h deleted file mode 100644 index 4730a0791..000000000 --- a/apps/er-coap-13/er-coap-13-engine.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP implementation of the REST Engine - * \author - * Matthias Kovatsch - */ - -#ifndef COAP_SERVER_H_ -#define COAP_SERVER_H_ - -#if !defined(REST) -#error "Define REST to \"coap_rest_implementation\"" -#endif - -#include "er-coap-13.h" -#include "er-coap-13-transactions.h" -#include "er-coap-13-observing.h" -#include "er-coap-13-separate.h" - -#include "pt.h" - -/* Declare server process */ -PROCESS_NAME(coap_receiver); - -#define SERVER_LISTEN_PORT UIP_HTONS(COAP_SERVER_PORT) - -typedef coap_packet_t rest_request_t; -typedef coap_packet_t rest_response_t; - -extern const struct rest_implementation coap_rest_implementation; - -void coap_receiver_init(void); - -/*-----------------------------------------------------------------------------------*/ -/*- Client part ---------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -struct request_state_t { - struct pt pt; - struct process *process; - coap_transaction_t *transaction; - coap_packet_t *response; - uint32_t block_num; -}; - -typedef void (*blocking_response_handler) (void* response); - -PT_THREAD(coap_blocking_request(struct request_state_t *state, process_event_t ev, - uip_ipaddr_t *remote_ipaddr, uint16_t remote_port, - coap_packet_t *request, - blocking_response_handler request_callback)); - -#define COAP_BLOCKING_REQUEST(server_addr, server_port, request, chunk_handler) \ -{ \ - static struct request_state_t request_state; \ - PT_SPAWN(process_pt, &request_state.pt, \ - coap_blocking_request(&request_state, ev, \ - server_addr, server_port, \ - request, chunk_handler) \ - ); \ -} -/*-----------------------------------------------------------------------------------*/ - -#endif /* COAP_SERVER_H_ */ diff --git a/apps/er-coap-13/er-coap-13-observing.c b/apps/er-coap-13/er-coap-13-observing.c deleted file mode 100644 index eeb430877..000000000 --- a/apps/er-coap-13/er-coap-13-observing.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * CoAP module for observing resources - * \author - * Matthias Kovatsch - */ - -#include -#include - -#include "er-coap-13-observing.h" - -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - - -MEMB(observers_memb, coap_observer_t, COAP_MAX_OBSERVERS); -LIST(observers_list); - -/*-----------------------------------------------------------------------------------*/ -coap_observer_t * -coap_add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token, size_t token_len, const char *url) -{ - /* Remove existing observe relationship, if any. */ - coap_remove_observer_by_url(addr, port, url); - - coap_observer_t *o = memb_alloc(&observers_memb); - - if (o) - { - o->url = url; - uip_ipaddr_copy(&o->addr, addr); - o->port = port; - o->token_len = token_len; - memcpy(o->token, token, token_len); - o->last_mid = 0; - - stimer_set(&o->refresh_timer, COAP_OBSERVING_REFRESH_INTERVAL); - - PRINTF("Adding observer for /%s [0x%02X%02X]\n", o->url, o->token[0], o->token[1]); - list_add(observers_list, o); - } - - return o; -} -/*-----------------------------------------------------------------------------------*/ -void -coap_remove_observer(coap_observer_t *o) -{ - PRINTF("Removing observer for /%s [0x%02X%02X]\n", o->url, o->token[0], o->token[1]); - - memb_free(&observers_memb, o); - list_remove(observers_list, o); -} - -int -coap_remove_observer_by_client(uip_ipaddr_t *addr, uint16_t port) -{ - int removed = 0; - coap_observer_t* obs = NULL; - - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - PRINTF("Remove check client "); - PRINT6ADDR(addr); - PRINTF(":%u\n", port); - if (uip_ipaddr_cmp(&obs->addr, addr) && obs->port==port) - { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} - -int -coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port, uint8_t *token, size_t token_len) -{ - int removed = 0; - coap_observer_t* obs = NULL; - - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - PRINTF("Remove check Token 0x%02X%02X\n", token[0], token[1]); - if (uip_ipaddr_cmp(&obs->addr, addr) && obs->port==port && obs->token_len==token_len && memcmp(obs->token, token, token_len)==0) - { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} - -int -coap_remove_observer_by_url(uip_ipaddr_t *addr, uint16_t port, const char *url) -{ - int removed = 0; - coap_observer_t* obs = NULL; - - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - PRINTF("Remove check URL %p\n", url); - if ((addr==NULL || (uip_ipaddr_cmp(&obs->addr, addr) && obs->port==port)) && (obs->url==url || memcmp(obs->url, url, strlen(obs->url))==0)) - { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} - -int -coap_remove_observer_by_mid(uip_ipaddr_t *addr, uint16_t port, uint16_t mid) -{ - int removed = 0; - coap_observer_t* obs = NULL; - - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - PRINTF("Remove check MID %u\n", mid); - if (uip_ipaddr_cmp(&obs->addr, addr) && obs->port==port && obs->last_mid==mid) - { - coap_remove_observer(obs); - removed++; - } - } - return removed; -} -/*-----------------------------------------------------------------------------------*/ -void -coap_notify_observers(resource_t *resource, int32_t obs_counter, void *notification) -{ - coap_packet_t *const coap_res = (coap_packet_t *) notification; - coap_observer_t* obs = NULL; - uint8_t preferred_type = coap_res->type; - - PRINTF("Observing: Notification from %s\n", resource->url); - - /* Iterate over observers. */ - for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) - { - if (obs->url==resource->url) /* using RESOURCE url pointer as handle */ - { - coap_transaction_t *transaction = NULL; - - /*TODO implement special transaction for CON, sharing the same buffer to allow for more observers. */ - - if ( (transaction = coap_new_transaction(coap_get_mid(), &obs->addr, obs->port)) ) - { - PRINTF(" Observer "); - PRINT6ADDR(&obs->addr); - PRINTF(":%u\n", obs->port); - - /* Update last MID for RST matching. */ - obs->last_mid = transaction->mid; - - /* Prepare response */ - coap_res->mid = transaction->mid; - if (obs_counter>=0) coap_set_header_observe(coap_res, obs_counter); - coap_set_header_token(coap_res, obs->token, obs->token_len); - - /* Use CON to check whether client is still there/interested after COAP_OBSERVING_REFRESH_INTERVAL. */ - if (stimer_expired(&obs->refresh_timer)) - { - PRINTF(" Refreshing with CON\n"); - coap_res->type = COAP_TYPE_CON; - stimer_restart(&obs->refresh_timer); - } - else - { - coap_res->type = preferred_type; - } - - transaction->packet_len = coap_serialize_message(coap_res, transaction->packet); - - coap_send_transaction(transaction); - } - } - } -} -/*-----------------------------------------------------------------------------------*/ -void -coap_observe_handler(resource_t *resource, void *request, void *response) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - coap_packet_t *const coap_res = (coap_packet_t *) response; - - static char content[16]; - - if (coap_req->code==COAP_GET && coap_res->code<128) /* GET request and response without error code */ - { - if (IS_OPTION(coap_req, COAP_OPTION_OBSERVE)) - { - - if (coap_add_observer(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, coap_req->token, coap_req->token_len, resource->url)) - { - coap_set_header_observe(coap_res, 0); - /* - * For demonstration purposes only. A subscription should return the same representation as a normal GET. - * TODO: Comment the following line for any real application. - */ - coap_set_payload(coap_res, content, snprintf(content, sizeof(content), "Added %u/%u", list_length(observers_list), COAP_MAX_OBSERVERS)); - } - else - { - coap_res->code = SERVICE_UNAVAILABLE_5_03; - coap_set_payload(coap_res, "TooManyObservers", 16); - } /* if (added observer) */ - } - else /* if (observe) */ - { - /* Remove client if it is currently observing. */ - coap_remove_observer_by_url(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, resource->url); - } /* if (observe) */ - } -} diff --git a/apps/er-coap-13/er-coap-13.c b/apps/er-coap-13/er-coap-13.c deleted file mode 100644 index 8bd623c36..000000000 --- a/apps/er-coap-13/er-coap-13.c +++ /dev/null @@ -1,1133 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * An implementation of the Constrained Application Protocol (draft 12) - * \author - * Matthias Kovatsch - */ - -#include "contiki.h" -#include "contiki-net.h" -#include -#include - -#include "er-coap-13.h" -#include "er-coap-13-transactions.h" - - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - -/*-----------------------------------------------------------------------------------*/ -/*- Variables -----------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -static struct uip_udp_conn *udp_conn = NULL; -static uint16_t current_mid = 0; - -coap_status_t coap_error_code = NO_ERROR; -char *coap_error_message = ""; -/*-----------------------------------------------------------------------------------*/ -/*- LOCAL HELP FUNCTIONS ------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -static -uint16_t -coap_log_2(uint16_t value) -{ - uint16_t result = 0; - do { - value = value >> 1; - result++; - } while (value); - - return result ? result - 1 : result; -} -/*-----------------------------------------------------------------------------------*/ -static -uint32_t -coap_parse_int_option(uint8_t *bytes, size_t length) -{ - uint32_t var = 0; - int i = 0; - while (i268) - { - buffer[++written] = (*x-269)>>8; - buffer[++written] = (*x-269); - } - else if (*x>12) - { - buffer[++written] = (*x-13); - } - } - while (x!=&length && (x=&length)); - - PRINTF("WRITTEN %u B opt header\n", written); - - return ++written; -} -/*-----------------------------------------------------------------------------------*/ -static -size_t -coap_serialize_int_option(unsigned int number, unsigned int current_number, uint8_t *buffer, uint32_t value) -{ - size_t i = 0; - - if (0xFF000000 & value) ++i; - if (0xFFFF0000 & value) ++i; - if (0xFFFFFF00 & value) ++i; - if (0xFFFFFFFF & value) ++i; - - PRINTF("OPTION %u (delta %u, len %u)\n", number, number - current_number, i); - - i = coap_set_option_header(number - current_number, i, buffer); - - if (0xFF000000 & value) buffer[i++] = (uint8_t) (value>>24); - if (0xFFFF0000 & value) buffer[i++] = (uint8_t) (value>>16); - if (0xFFFFFF00 & value) buffer[i++] = (uint8_t) (value>>8); - if (0xFFFFFFFF & value) buffer[i++] = (uint8_t) (value); - - return i; -} -/*-----------------------------------------------------------------------------------*/ -static -size_t -coap_serialize_array_option(unsigned int number, unsigned int current_number, uint8_t *buffer, uint8_t *array, size_t length, char split_char) -{ - size_t i = 0; - - if (split_char!='\0') - { - int j; - uint8_t *part_start = array; - uint8_t *part_end = NULL; - size_t temp_length; - - for (j = 0; j<=length; ++j) - { - if (array[j]==split_char || j==length) - { - part_end = array + j; - temp_length = part_end-part_start; - - i += coap_set_option_header(number - current_number, temp_length, &buffer[i]); - memcpy(&buffer[i], part_start, temp_length); - i += temp_length; - - PRINTF("OPTION type %u, delta %u, len %u, part [%.*s]\n", number, number - current_number, i, temp_length, part_start); - - ++j; /* skip the splitter */ - current_number = number; - part_start = array + j; - } - } /* for */ - } - else - { - i += coap_set_option_header(number - current_number, length, &buffer[i]); - memcpy(&buffer[i], array, length); - i += length; - - PRINTF("OPTION type %u, delta %u, len %u\n", number, number - current_number, length); - } - - return i; -} -/*-----------------------------------------------------------------------------------*/ -static -void -coap_merge_multi_option(char **dst, size_t *dst_len, uint8_t *option, size_t option_len, char separator) -{ - /* Merge multiple options. */ - if (*dst_len > 0) - { - /* dst already contains an option: concatenate */ - (*dst)[*dst_len] = separator; - *dst_len += 1; - - /* memmove handles 2-byte option headers */ - memmove((*dst)+(*dst_len), option, option_len); - - *dst_len += option_len; - } - else - { - /* dst is empty: set to option */ - *dst = (char *) option; - *dst_len = option_len; - } -} -/*-----------------------------------------------------------------------------------*/ -static -int -coap_get_variable(const char *buffer, size_t length, const char *name, const char **output) -{ - const char *start = NULL; - const char *end = NULL; - const char *value_end = NULL; - size_t name_len = 0; - - /*initialize the output buffer first*/ - *output = 0; - - name_len = strlen(name); - end = buffer + length; - - for (start = buffer; start + name_len < end; ++start){ - if ((start == buffer || start[-1] == '&') && start[name_len] == '=' && - strncmp(name, start, name_len)==0) { - - /* Point start to variable value */ - start += name_len + 1; - - /* Point end to the end of the value */ - value_end = (const char *) memchr(start, '&', end - start); - if (value_end == NULL) { - value_end = end; - } - - *output = start; - - return (value_end - start); - } - } - - return 0; -} -/*-----------------------------------------------------------------------------------*/ -/*- MEASSAGE SENDING ----------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -void -coap_init_connection(uint16_t port) -{ - /* new connection with remote host */ - udp_conn = udp_new(NULL, 0, NULL); - udp_bind(udp_conn, port); - PRINTF("Listening on port %u\n", uip_ntohs(udp_conn->lport)); - - /* Initialize transaction ID. */ - current_mid = random_rand(); -} -/*-----------------------------------------------------------------------------------*/ -uint16_t -coap_get_mid() -{ - return ++current_mid; -} -/*-----------------------------------------------------------------------------------*/ -/*- MEASSAGE PROCESSING -------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -void -coap_init_message(void *packet, coap_message_type_t type, uint8_t code, uint16_t mid) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - /* Important thing */ - memset(coap_pkt, 0, sizeof(coap_packet_t)); - - coap_pkt->type = type; - coap_pkt->code = code; - coap_pkt->mid = mid; -} -/*-----------------------------------------------------------------------------------*/ -size_t -coap_serialize_message(void *packet, uint8_t *buffer) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - uint8_t *option; - unsigned int current_number = 0; - - /* Initialize */ - coap_pkt->buffer = buffer; - coap_pkt->version = 1; - - PRINTF("-Serializing MID %u to %p, ", coap_pkt->mid, coap_pkt->buffer); - - /* set header fields */ - coap_pkt->buffer[0] = 0x00; - coap_pkt->buffer[0] |= COAP_HEADER_VERSION_MASK & (coap_pkt->version)<buffer[0] |= COAP_HEADER_TYPE_MASK & (coap_pkt->type)<buffer[0] |= COAP_HEADER_TOKEN_LEN_MASK & (coap_pkt->token_len)<buffer[1] = coap_pkt->code; - coap_pkt->buffer[2] = (uint8_t) ((coap_pkt->mid)>>8); - coap_pkt->buffer[3] = (uint8_t) (coap_pkt->mid); - - /* set Token */ - PRINTF("Token (len %u)", coap_pkt->token_len); - option = coap_pkt->buffer + COAP_HEADER_LEN; - for (current_number=0; current_numbertoken_len; ++current_number) - { - PRINTF(" %02X", coap_pkt->token[current_number]); - *option = coap_pkt->token[current_number]; - ++option; - } - PRINTF("-\n"); - - /* Serialize options */ - current_number = 0; - - PRINTF("-Serializing options at %p-\n", option); - - /* The options must be serialized in the order of their number */ - COAP_SERIALIZE_BYTE_OPTION( COAP_OPTION_IF_MATCH, if_match, "If-Match") - COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_URI_HOST, uri_host, '\0', "Uri-Host") - COAP_SERIALIZE_BYTE_OPTION( COAP_OPTION_ETAG, etag, "ETag") - COAP_SERIALIZE_INT_OPTION( COAP_OPTION_IF_NONE_MATCH, content_type-coap_pkt->content_type, "If-None-Match") /* hack to get a zero field */ - COAP_SERIALIZE_INT_OPTION( COAP_OPTION_OBSERVE, observe, "Observe") - COAP_SERIALIZE_INT_OPTION( COAP_OPTION_URI_PORT, uri_port, "Uri-Port") - COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_LOCATION_PATH, location_path, '/', "Location-Path") - COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_URI_PATH, uri_path, '/', "Uri-Path") - COAP_SERIALIZE_INT_OPTION( COAP_OPTION_CONTENT_TYPE, content_type, "Content-Format") - COAP_SERIALIZE_INT_OPTION( COAP_OPTION_MAX_AGE, max_age, "Max-Age") - COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_URI_QUERY, uri_query, '&', "Uri-Query") - COAP_SERIALIZE_ACCEPT_OPTION( COAP_OPTION_ACCEPT, accept, "Accept") - COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_LOCATION_QUERY, location_query, '&', "Location-Query") - COAP_SERIALIZE_BLOCK_OPTION( COAP_OPTION_BLOCK2, block2, "Block2") - COAP_SERIALIZE_BLOCK_OPTION( COAP_OPTION_BLOCK1, block1, "Block1") - COAP_SERIALIZE_INT_OPTION( COAP_OPTION_SIZE, size, "Size") - COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_PROXY_URI, proxy_uri, '\0', "Proxy-Uri") - - PRINTF("-Done serializing at %p----\n", option); - - /* Pack payload */ - if ((option - coap_pkt->buffer)<=COAP_MAX_HEADER_SIZE) - { - /* Payload marker */ - if (coap_pkt->payload_len) - { - *option = 0xFF; - ++option; - } - - memmove(option, coap_pkt->payload, coap_pkt->payload_len); - } - else - { - /* An error occured. Caller must check for !=0. */ - coap_pkt->buffer = NULL; - coap_error_message = "Serialized header exceeds COAP_MAX_HEADER_SIZE"; - return 0; - } - - PRINTF("-Done %u B (header len %u, payload len %u)-\n", coap_pkt->payload_len + option - buffer, option - buffer, coap_pkt->payload_len); - - PRINTF("Dump [0x%02X %02X %02X %02X %02X %02X %02X %02X]\n", - coap_pkt->buffer[0], - coap_pkt->buffer[1], - coap_pkt->buffer[2], - coap_pkt->buffer[3], - coap_pkt->buffer[4], - coap_pkt->buffer[5], - coap_pkt->buffer[6], - coap_pkt->buffer[7] - ); - - return (option - buffer) + coap_pkt->payload_len; /* packet length */ -} -/*-----------------------------------------------------------------------------------*/ -void -coap_send_message(uip_ipaddr_t *addr, uint16_t port, uint8_t *data, uint16_t length) -{ - /* Configure connection to reply to client */ - uip_ipaddr_copy(&udp_conn->ripaddr, addr); - udp_conn->rport = port; - - uip_udp_packet_send(udp_conn, data, length); - PRINTF("-sent UDP datagram (%u)-\n", length); - - /* Restore server connection to allow data from any node */ - memset(&udp_conn->ripaddr, 0, sizeof(udp_conn->ripaddr)); - udp_conn->rport = 0; -} -/*-----------------------------------------------------------------------------------*/ -coap_status_t -coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - /* Initialize packet */ - memset(coap_pkt, 0, sizeof(coap_packet_t)); - - /* pointer to packet bytes */ - coap_pkt->buffer = data; - - /* parse header fields */ - coap_pkt->version = (COAP_HEADER_VERSION_MASK & coap_pkt->buffer[0])>>COAP_HEADER_VERSION_POSITION; - coap_pkt->type = (COAP_HEADER_TYPE_MASK & coap_pkt->buffer[0])>>COAP_HEADER_TYPE_POSITION; - coap_pkt->token_len = MIN(COAP_TOKEN_LEN, (COAP_HEADER_TOKEN_LEN_MASK & coap_pkt->buffer[0])>>COAP_HEADER_TOKEN_LEN_POSITION); - coap_pkt->code = coap_pkt->buffer[1]; - coap_pkt->mid = coap_pkt->buffer[2]<<8 | coap_pkt->buffer[3]; - - if (coap_pkt->version != 1) - { - coap_error_message = "CoAP version must be 1"; - return BAD_REQUEST_4_00; - } - - uint8_t *current_option = data + COAP_HEADER_LEN; - - memcpy(coap_pkt->token, current_option, coap_pkt->token_len); - PRINTF("Token (len %u) [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->token_len, - coap_pkt->token[0], - coap_pkt->token[1], - coap_pkt->token[2], - coap_pkt->token[3], - coap_pkt->token[4], - coap_pkt->token[5], - coap_pkt->token[6], - coap_pkt->token[7] - ); /*FIXME always prints 8 bytes */ - - - /* parse options */ - memset(coap_pkt->options, 0, sizeof(coap_pkt->options)); - current_option += coap_pkt->token_len; - - unsigned int option_number = 0; - unsigned int option_delta = 0; - size_t option_length = 0; - - while (current_option < data+data_len) - { - /* Payload marker 0xFF, currently only checking for 0xF* because rest is reserved */ - if ((current_option[0] & 0xF0)==0xF0) - { - coap_pkt->payload = ++current_option; - coap_pkt->payload_len = data_len - (coap_pkt->payload - data); - - /* also for receiving, the Erbium upper bound is REST_MAX_CHUNK_SIZE */ - if (coap_pkt->payload_len > REST_MAX_CHUNK_SIZE) - { - coap_pkt->payload_len = REST_MAX_CHUNK_SIZE; - } - - /* Null-terminate payload */ - coap_pkt->payload[coap_pkt->payload_len] = '\0'; - - break; - } - - option_delta = current_option[0]>>4; - option_length = current_option[0] & 0x0F; - ++current_option; - - /* avoids code duplication without function overhead */ - unsigned int *x = &option_delta; - do - { - if (*x==13) - { - *x += current_option[0]; - ++current_option; - } - else if (*x==14) - { - *x += 255; - *x += current_option[0]<<8; - ++current_option; - *x += current_option[0]; - ++current_option; - } - } - while (x!=&option_length && (x=&option_length)); - - option_number += option_delta; - - PRINTF("OPTION %u (delta %u, len %u): ", option_number, option_delta, option_length); - - SET_OPTION(coap_pkt, option_number); - - switch (option_number) - { - case COAP_OPTION_CONTENT_TYPE: - coap_pkt->content_type = coap_parse_int_option(current_option, option_length); - PRINTF("Content-Format [%u]\n", coap_pkt->content_type); - break; - case COAP_OPTION_MAX_AGE: - coap_pkt->max_age = coap_parse_int_option(current_option, option_length); - PRINTF("Max-Age [%lu]\n", coap_pkt->max_age); - break; - case COAP_OPTION_ETAG: - coap_pkt->etag_len = MIN(COAP_ETAG_LEN, option_length); - memcpy(coap_pkt->etag, current_option, coap_pkt->etag_len); - PRINTF("ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->etag_len, - coap_pkt->etag[0], - coap_pkt->etag[1], - coap_pkt->etag[2], - coap_pkt->etag[3], - coap_pkt->etag[4], - coap_pkt->etag[5], - coap_pkt->etag[6], - coap_pkt->etag[7] - ); /*FIXME always prints 8 bytes */ - break; - case COAP_OPTION_ACCEPT: - if (coap_pkt->accept_num < COAP_MAX_ACCEPT_NUM) - { - coap_pkt->accept[coap_pkt->accept_num] = coap_parse_int_option(current_option, option_length); - coap_pkt->accept_num += 1; - PRINTF("Accept [%u]\n", coap_pkt->content_type); - } - break; - case COAP_OPTION_IF_MATCH: - /*FIXME support multiple ETags */ - coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, option_length); - memcpy(coap_pkt->if_match, current_option, coap_pkt->if_match_len); - PRINTF("If-Match %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->if_match_len, - coap_pkt->if_match[0], - coap_pkt->if_match[1], - coap_pkt->if_match[2], - coap_pkt->if_match[3], - coap_pkt->if_match[4], - coap_pkt->if_match[5], - coap_pkt->if_match[6], - coap_pkt->if_match[7] - ); /*FIXME always prints 8 bytes */ - break; - case COAP_OPTION_IF_NONE_MATCH: - coap_pkt->if_none_match = 1; - PRINTF("If-None-Match\n"); - break; - - case COAP_OPTION_URI_HOST: - coap_pkt->uri_host = (char *) current_option; - coap_pkt->uri_host_len = option_length; - PRINTF("Uri-Host [%.*s]\n", coap_pkt->uri_host_len, coap_pkt->uri_host); - break; - case COAP_OPTION_URI_PORT: - coap_pkt->uri_port = coap_parse_int_option(current_option, option_length); - PRINTF("Uri-Port [%u]\n", coap_pkt->uri_port); - break; - case COAP_OPTION_URI_PATH: - /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ - coap_merge_multi_option( (char **) &(coap_pkt->uri_path), &(coap_pkt->uri_path_len), current_option, option_length, '/'); - PRINTF("Uri-Path [%.*s]\n", coap_pkt->uri_path_len, coap_pkt->uri_path); - break; - case COAP_OPTION_URI_QUERY: - /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ - coap_merge_multi_option( (char **) &(coap_pkt->uri_query), &(coap_pkt->uri_query_len), current_option, option_length, '&'); - PRINTF("Uri-Query [%.*s]\n", coap_pkt->uri_query_len, coap_pkt->uri_query); - break; - - case COAP_OPTION_LOCATION_PATH: - /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ - coap_merge_multi_option( (char **) &(coap_pkt->location_path), &(coap_pkt->location_path_len), current_option, option_length, '/'); - PRINTF("Location-Path [%.*s]\n", coap_pkt->location_path_len, coap_pkt->location_path); - break; - case COAP_OPTION_LOCATION_QUERY: - /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ - coap_merge_multi_option( (char **) &(coap_pkt->location_query), &(coap_pkt->location_query_len), current_option, option_length, '&'); - PRINTF("Location-Query [%.*s]\n", coap_pkt->location_query_len, coap_pkt->location_query); - break; - - case COAP_OPTION_PROXY_URI: - /*FIXME check for own end-point */ - coap_pkt->proxy_uri = (char *) current_option; - coap_pkt->proxy_uri_len = option_length; - /*TODO length > 270 not implemented (actually not required) */ - PRINTF("Proxy-Uri NOT IMPLEMENTED [%.*s]\n", coap_pkt->proxy_uri_len, coap_pkt->proxy_uri); - coap_error_message = "This is a constrained server (Contiki)"; - return PROXYING_NOT_SUPPORTED_5_05; - break; - - case COAP_OPTION_OBSERVE: - coap_pkt->observe = coap_parse_int_option(current_option, option_length); - PRINTF("Observe [%lu]\n", coap_pkt->observe); - break; - case COAP_OPTION_BLOCK2: - coap_pkt->block2_num = coap_parse_int_option(current_option, option_length); - coap_pkt->block2_more = (coap_pkt->block2_num & 0x08)>>3; - coap_pkt->block2_size = 16 << (coap_pkt->block2_num & 0x07); - coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F)<<(coap_pkt->block2_num & 0x07); - coap_pkt->block2_num >>= 4; - PRINTF("Block2 [%lu%s (%u B/blk)]\n", coap_pkt->block2_num, coap_pkt->block2_more ? "+" : "", coap_pkt->block2_size); - break; - case COAP_OPTION_BLOCK1: - coap_pkt->block1_num = coap_parse_int_option(current_option, option_length); - coap_pkt->block1_more = (coap_pkt->block1_num & 0x08)>>3; - coap_pkt->block1_size = 16 << (coap_pkt->block1_num & 0x07); - coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F)<<(coap_pkt->block1_num & 0x07); - coap_pkt->block1_num >>= 4; - PRINTF("Block1 [%lu%s (%u B/blk)]\n", coap_pkt->block1_num, coap_pkt->block1_more ? "+" : "", coap_pkt->block1_size); - break; - case COAP_OPTION_SIZE: - coap_pkt->size = coap_parse_int_option(current_option, option_length); - PRINTF("Size [%lu]\n", coap_pkt->size); - break; - default: - PRINTF("unknown (%u)\n", option_number); - /* Check if critical (odd) */ - if (option_number & 1) - { - coap_error_message = "Unsupported critical option"; - return BAD_OPTION_4_02; - } - } - - current_option += option_length; - } /* for */ - PRINTF("-Done parsing-------\n"); - - - - return NO_ERROR; -} -/*-----------------------------------------------------------------------------------*/ -/*- REST FRAMEWORK FUNCTIONS --------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -int -coap_get_query_variable(void *packet, const char *name, const char **output) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) { - return coap_get_variable(coap_pkt->uri_query, coap_pkt->uri_query_len, name, output); - } - return 0; -} - -int -coap_get_post_variable(void *packet, const char *name, const char **output) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (coap_pkt->payload_len) { - return coap_get_variable((const char *)coap_pkt->payload, coap_pkt->payload_len, name, output); - } - return 0; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_set_status_code(void *packet, unsigned int code) -{ - if (code <= 0xFF) - { - ((coap_packet_t *)packet)->code = (uint8_t) code; - return 1; - } - else - { - return 0; - } -} -/*-----------------------------------------------------------------------------------*/ -/*- HEADER OPTION GETTERS AND SETTERS -----------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -unsigned int -coap_get_header_content_type(void *packet) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_CONTENT_TYPE)) return -1; - - return coap_pkt->content_type; -} - -int -coap_set_header_content_type(void *packet, unsigned int content_type) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->content_type = (coap_content_type_t) content_type; - SET_OPTION(coap_pkt, COAP_OPTION_CONTENT_TYPE); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_accept(void *packet, const uint16_t **accept) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_ACCEPT)) return 0; - - *accept = coap_pkt->accept; - return coap_pkt->accept_num; -} - -int -coap_set_header_accept(void *packet, uint16_t accept) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (coap_pkt->accept_num < COAP_MAX_ACCEPT_NUM) - { - coap_pkt->accept[coap_pkt->accept_num] = accept; - coap_pkt->accept_num += 1; - - SET_OPTION(coap_pkt, COAP_OPTION_ACCEPT); - } - return coap_pkt->accept_num; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_max_age(void *packet, uint32_t *age) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_MAX_AGE)) { - *age = COAP_DEFAULT_MAX_AGE; - } else { - *age = coap_pkt->max_age; - } - return 1; -} - -int -coap_set_header_max_age(void *packet, uint32_t age) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->max_age = age; - SET_OPTION(coap_pkt, COAP_OPTION_MAX_AGE); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_etag(void *packet, const uint8_t **etag) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) return 0; - - *etag = coap_pkt->etag; - return coap_pkt->etag_len; -} - -int -coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->etag_len = MIN(COAP_ETAG_LEN, etag_len); - memcpy(coap_pkt->etag, etag, coap_pkt->etag_len); - - SET_OPTION(coap_pkt, COAP_OPTION_ETAG); - return coap_pkt->etag_len; -} -/*-----------------------------------------------------------------------------------*/ -/*FIXME support multiple ETags */ -int -coap_get_header_if_match(void *packet, const uint8_t **etag) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_IF_MATCH)) return 0; - - *etag = coap_pkt->if_match; - return coap_pkt->if_match_len; -} - -int -coap_set_header_if_match(void *packet, const uint8_t *etag, size_t etag_len) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, etag_len); - memcpy(coap_pkt->if_match, etag, coap_pkt->if_match_len); - - SET_OPTION(coap_pkt, COAP_OPTION_IF_MATCH); - return coap_pkt->if_match_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_if_none_match(void *packet) -{ - return IS_OPTION((coap_packet_t *)packet, COAP_OPTION_IF_NONE_MATCH) ? 1 : 0; -} - -int -coap_set_header_if_none_match(void *packet) -{ - SET_OPTION((coap_packet_t *)packet, COAP_OPTION_IF_NONE_MATCH); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_token(void *packet, const uint8_t **token) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - *token = coap_pkt->token; - return coap_pkt->token_len; -} - -int -coap_set_header_token(void *packet, const uint8_t *token, size_t token_len) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->token_len = MIN(COAP_TOKEN_LEN, token_len); - memcpy(coap_pkt->token, token, coap_pkt->token_len); - - return coap_pkt->token_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_proxy_uri(void *packet, const char **uri) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI)) return 0; - - *uri = coap_pkt->proxy_uri; - return coap_pkt->proxy_uri_len; -} - -int -coap_set_header_proxy_uri(void *packet, const char *uri) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->proxy_uri = uri; - coap_pkt->proxy_uri_len = strlen(uri); - - SET_OPTION(coap_pkt, COAP_OPTION_PROXY_URI); - return coap_pkt->proxy_uri_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_uri_host(void *packet, const char **host) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_HOST)) return 0; - - *host = coap_pkt->uri_host; - return coap_pkt->uri_host_len; -} - -int -coap_set_header_uri_host(void *packet, const char *host) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->uri_host = host; - coap_pkt->uri_host_len = strlen(host); - - SET_OPTION(coap_pkt, COAP_OPTION_URI_HOST); - return coap_pkt->uri_host_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_uri_path(void *packet, const char **path) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_PATH)) return 0; - - *path = coap_pkt->uri_path; - return coap_pkt->uri_path_len; -} - -int -coap_set_header_uri_path(void *packet, const char *path) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - while (path[0]=='/') ++path; - - coap_pkt->uri_path = path; - coap_pkt->uri_path_len = strlen(path); - - SET_OPTION(coap_pkt, COAP_OPTION_URI_PATH); - return coap_pkt->uri_path_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_uri_query(void *packet, const char **query) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) return 0; - - *query = coap_pkt->uri_query; - return coap_pkt->uri_query_len; -} - -int -coap_set_header_uri_query(void *packet, const char *query) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - while (query[0]=='?') ++query; - - coap_pkt->uri_query = query; - coap_pkt->uri_query_len = strlen(query); - - SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); - return coap_pkt->uri_query_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_location_path(void *packet, const char **path) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH)) return 0; - - *path = coap_pkt->location_path; - return coap_pkt->location_path_len; -} - -int -coap_set_header_location_path(void *packet, const char *path) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - char *query; - - while (path[0]=='/') ++path; - - if ((query = strchr(path, '?'))) - { - coap_set_header_location_query(packet, query+1); - coap_pkt->location_path_len = query - path; - } - else - { - coap_pkt->location_path_len = strlen(path); - } - - coap_pkt->location_path = path; - - SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH); - return coap_pkt->location_path_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_location_query(void *packet, const char **query) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY)) return 0; - - *query = coap_pkt->location_query; - return coap_pkt->location_query_len; -} - -int -coap_set_header_location_query(void *packet, const char *query) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - while (query[0]=='?') ++query; - - coap_pkt->location_query = query; - coap_pkt->location_query_len = strlen(query); - - SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY); - return coap_pkt->location_query_len; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_observe(void *packet, uint32_t *observe) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) return 0; - - *observe = coap_pkt->observe; - return 1; -} - -int -coap_set_header_observe(void *packet, uint32_t observe) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->observe = 0x00FFFFFF & observe; - SET_OPTION(coap_pkt, COAP_OPTION_OBSERVE); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK2)) return 0; - - /* pointers may be NULL to get only specific block parameters */ - if (num!=NULL) *num = coap_pkt->block2_num; - if (more!=NULL) *more = coap_pkt->block2_more; - if (size!=NULL) *size = coap_pkt->block2_size; - if (offset!=NULL) *offset = coap_pkt->block2_offset; - - return 1; -} - -int -coap_set_header_block2(void *packet, uint32_t num, uint8_t more, uint16_t size) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (size<16) return 0; - if (size>2048) return 0; - if (num>0x0FFFFF) return 0; - - coap_pkt->block2_num = num; - coap_pkt->block2_more = more ? 1 : 0; - coap_pkt->block2_size = size; - - SET_OPTION(coap_pkt, COAP_OPTION_BLOCK2); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK1)) return 0; - - /* pointers may be NULL to get only specific block parameters */ - if (num!=NULL) *num = coap_pkt->block1_num; - if (more!=NULL) *more = coap_pkt->block1_more; - if (size!=NULL) *size = coap_pkt->block1_size; - if (offset!=NULL) *offset = coap_pkt->block1_offset; - - return 1; -} - -int -coap_set_header_block1(void *packet, uint32_t num, uint8_t more, uint16_t size) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (size<16) return 0; - if (size>2048) return 0; - if (num>0x0FFFFF) return 0; - - coap_pkt->block1_num = num; - coap_pkt->block1_more = more; - coap_pkt->block1_size = size; - - SET_OPTION(coap_pkt, COAP_OPTION_BLOCK1); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -int -coap_get_header_size(void *packet, uint32_t *size) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (!IS_OPTION(coap_pkt, COAP_OPTION_SIZE)) return 0; - - *size = coap_pkt->size; - return 1; -} - -int -coap_set_header_size(void *packet, uint32_t size) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - coap_pkt->size = size; - SET_OPTION(coap_pkt, COAP_OPTION_SIZE); - return 1; -} -/*-----------------------------------------------------------------------------------*/ -/*- PAYLOAD -------------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -int -coap_get_payload(void *packet, const uint8_t **payload) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - if (coap_pkt->payload) { - *payload = coap_pkt->payload; - return coap_pkt->payload_len; - } else { - *payload = NULL; - return 0; - } -} - -int -coap_set_payload(void *packet, const void *payload, size_t length) -{ - coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - - //PRINTF("setting payload (%u/%u)\n", length, REST_MAX_CHUNK_SIZE); - - coap_pkt->payload = (uint8_t *) payload; - coap_pkt->payload_len = MIN(REST_MAX_CHUNK_SIZE, length); - - return coap_pkt->payload_len; -} -/*-----------------------------------------------------------------------------------*/ diff --git a/apps/er-coap-13/er-coap-13.h b/apps/er-coap-13/er-coap-13.h deleted file mode 100644 index 734361e95..000000000 --- a/apps/er-coap-13/er-coap-13.h +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * An implementation of the Constrained Application Protocol (draft 12) - * \author - * Matthias Kovatsch - */ - -#ifndef COAP_13_H_ -#define COAP_13_H_ - -#include /* for size_t */ -#include "contiki-net.h" -#include "erbium.h" - -#define COAP_LINK_FORMAT_FILTERING 1 - -#define COAP_DEFAULT_PORT 5683 - -#ifndef COAP_SERVER_PORT -#define COAP_SERVER_PORT COAP_DEFAULT_PORT -#endif - -#define COAP_DEFAULT_MAX_AGE 60 -#define COAP_RESPONSE_TIMEOUT 2 -#define COAP_RESPONSE_RANDOM_FACTOR 1.5 -#define COAP_MAX_RETRANSMIT 4 - -#define COAP_HEADER_LEN 4 /* | version:0x03 type:0x0C tkl:0xF0 | code | mid:0x00FF | mid:0xFF00 | */ -#define COAP_ETAG_LEN 8 /* The maximum number of bytes for the ETag */ -#define COAP_TOKEN_LEN 8 /* The maximum number of bytes for the Token */ -#define COAP_MAX_ACCEPT_NUM 2 /* The maximum number of accept preferences to parse/store */ - -#define COAP_HEADER_VERSION_MASK 0xC0 -#define COAP_HEADER_VERSION_POSITION 6 -#define COAP_HEADER_TYPE_MASK 0x30 -#define COAP_HEADER_TYPE_POSITION 4 -#define COAP_HEADER_TOKEN_LEN_MASK 0x0F -#define COAP_HEADER_TOKEN_LEN_POSITION 0 - -#define COAP_HEADER_OPTION_DELTA_MASK 0xF0 -#define COAP_HEADER_OPTION_SHORT_LENGTH_MASK 0x0F - -/* - * Conservative size limit, as not all options have to be set at the same time. - */ -#ifndef COAP_MAX_HEADER_SIZE -/* Hdr CoT Age Tag Obs Tok Blo strings */ -#define COAP_MAX_HEADER_SIZE (4 + 3 + 5 + 1+COAP_ETAG_LEN + 3 + 1+COAP_TOKEN_LEN + 4 + 30) /* 70 */ -#endif /* COAP_MAX_HEADER_SIZE */ - -#define COAP_MAX_PACKET_SIZE (COAP_MAX_HEADER_SIZE + REST_MAX_CHUNK_SIZE) -/* 0/14 48 for IPv6 (28 for IPv4) */ -#if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN) -#error "UIP_CONF_BUFFER_SIZE too small for REST_MAX_CHUNK_SIZE" -#endif - -/* - * Maximum number of failed request attempts before action - */ -#ifndef COAP_MAX_ATTEMPTS -#define COAP_MAX_ATTEMPTS 4 -#endif /* COAP_MAX_ATTEMPTS */ - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN]) - -/* Bitmap for set options */ -enum { OPTION_MAP_SIZE = sizeof(uint8_t) * 8 }; -#define SET_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] |= 1 << (opt % OPTION_MAP_SIZE)) -#define IS_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] & (1 << (opt % OPTION_MAP_SIZE))) - -#ifndef MIN -#define MIN(a, b) ((a) < (b)? (a) : (b)) -#endif /* MIN */ - -/* CoAP message types */ -typedef enum { - COAP_TYPE_CON, /* confirmables */ - COAP_TYPE_NON, /* non-confirmables */ - COAP_TYPE_ACK, /* acknowledgements */ - COAP_TYPE_RST /* reset */ -} coap_message_type_t; - -/* CoAP request method codes */ -typedef enum { - COAP_GET = 1, - COAP_POST, - COAP_PUT, - COAP_DELETE -} coap_method_t; - -/* CoAP response codes */ -typedef enum { - NO_ERROR = 0, - - CREATED_2_01 = 65, /* CREATED */ - DELETED_2_02 = 66, /* DELETED */ - VALID_2_03 = 67, /* NOT_MODIFIED */ - CHANGED_2_04 = 68, /* CHANGED */ - CONTENT_2_05 = 69, /* OK */ - - BAD_REQUEST_4_00 = 128, /* BAD_REQUEST */ - UNAUTHORIZED_4_01 = 129, /* UNAUTHORIZED */ - BAD_OPTION_4_02 = 130, /* BAD_OPTION */ - FORBIDDEN_4_03 = 131, /* FORBIDDEN */ - NOT_FOUND_4_04 = 132, /* NOT_FOUND */ - METHOD_NOT_ALLOWED_4_05 = 133, /* METHOD_NOT_ALLOWED */ - NOT_ACCEPTABLE_4_06 = 134, /* NOT_ACCEPTABLE */ - PRECONDITION_FAILED_4_12 = 140, /* BAD_REQUEST */ - REQUEST_ENTITY_TOO_LARGE_4_13 = 141, /* REQUEST_ENTITY_TOO_LARGE */ - UNSUPPORTED_MEDIA_TYPE_4_15 = 143, /* UNSUPPORTED_MEDIA_TYPE */ - - INTERNAL_SERVER_ERROR_5_00 = 160, /* INTERNAL_SERVER_ERROR */ - NOT_IMPLEMENTED_5_01 = 161, /* NOT_IMPLEMENTED */ - BAD_GATEWAY_5_02 = 162, /* BAD_GATEWAY */ - SERVICE_UNAVAILABLE_5_03 = 163, /* SERVICE_UNAVAILABLE */ - GATEWAY_TIMEOUT_5_04 = 164, /* GATEWAY_TIMEOUT */ - PROXYING_NOT_SUPPORTED_5_05 = 165, /* PROXYING_NOT_SUPPORTED */ - - /* Erbium errors */ - MEMORY_ALLOCATION_ERROR = 192, - PACKET_SERIALIZATION_ERROR, - - /* Erbium hooks */ - MANUAL_RESPONSE, - PING_RESPONSE - -} coap_status_t; - -/* CoAP header options */ -typedef enum { - COAP_OPTION_IF_MATCH = 1, /* 0-8 B */ - COAP_OPTION_URI_HOST = 3, /* 1-255 B */ - COAP_OPTION_ETAG = 4, /* 1-8 B */ - COAP_OPTION_IF_NONE_MATCH = 5, /* 0 B */ - COAP_OPTION_OBSERVE = 6, /* 0-3 B */ - COAP_OPTION_URI_PORT = 7, /* 0-2 B */ - COAP_OPTION_LOCATION_PATH = 8, /* 0-255 B */ - COAP_OPTION_URI_PATH = 11, /* 0-255 B */ - COAP_OPTION_CONTENT_TYPE = 12, /* 0-2 B */ - COAP_OPTION_MAX_AGE = 14, /* 0-4 B */ - COAP_OPTION_URI_QUERY = 15, /* 0-270 B */ - COAP_OPTION_ACCEPT = 16, /* 0-2 B */ - COAP_OPTION_LOCATION_QUERY = 20, /* 1-270 B */ - COAP_OPTION_BLOCK2 = 23, /* 1-3 B */ - COAP_OPTION_BLOCK1 = 27, /* 1-3 B */ - COAP_OPTION_SIZE = 28, /* 0-4 B */ - COAP_OPTION_PROXY_URI = 35, /* 1-270 B */ -} coap_option_t; - -/* CoAP Content-Types */ -typedef enum { - TEXT_PLAIN = 0, - TEXT_XML = 1, /* Indented types are not in the initial registry. */ - TEXT_CSV = 2, - TEXT_HTML = 3, - IMAGE_GIF = 21, - IMAGE_JPEG = 22, - IMAGE_PNG = 23, - IMAGE_TIFF = 24, - AUDIO_RAW = 25, - VIDEO_RAW = 26, - APPLICATION_LINK_FORMAT = 40, - APPLICATION_XML = 41, - APPLICATION_OCTET_STREAM = 42, - APPLICATION_RDF_XML = 43, - APPLICATION_SOAP_XML = 44, - APPLICATION_ATOM_XML = 45, - APPLICATION_XMPP_XML = 46, - APPLICATION_EXI = 47, - APPLICATION_FASTINFOSET = 48, - APPLICATION_SOAP_FASTINFOSET = 49, - APPLICATION_JSON = 50, - APPLICATION_X_OBIX_BINARY = 51 -} coap_content_type_t; - -/* Parsed message struct */ -typedef struct { - uint8_t *buffer; /* pointer to CoAP header / incoming packet buffer / memory to serialize packet */ - - uint8_t version; - coap_message_type_t type; - uint8_t code; - uint16_t mid; - - uint8_t options[COAP_OPTION_PROXY_URI / OPTION_MAP_SIZE + 1]; /* Bitmap to check if option is set */ - - coap_content_type_t content_type; /* Parse options once and store; allows setting options in random order */ - uint32_t max_age; - size_t proxy_uri_len; - const char *proxy_uri; - uint8_t etag_len; - uint8_t etag[COAP_ETAG_LEN]; - size_t uri_host_len; - const char *uri_host; - size_t location_path_len; - const char *location_path; - uint16_t uri_port; - size_t location_query_len; - const char *location_query; - size_t uri_path_len; - const char *uri_path; - uint16_t observe; - uint8_t token_len; - uint8_t token[COAP_TOKEN_LEN]; - uint8_t accept_num; - uint16_t accept[COAP_MAX_ACCEPT_NUM]; - uint8_t if_match_len; - uint8_t if_match[COAP_ETAG_LEN]; - uint32_t block2_num; - uint8_t block2_more; - uint16_t block2_size; - uint32_t block2_offset; - uint32_t block1_num; - uint8_t block1_more; - uint16_t block1_size; - uint32_t block1_offset; - uint32_t size; - size_t uri_query_len; - const char *uri_query; - uint8_t if_none_match; - - uint16_t payload_len; - uint8_t *payload; - -} coap_packet_t; - -/* Option format serialization*/ -#define COAP_SERIALIZE_INT_OPTION(number, field, text) \ - if (IS_OPTION(coap_pkt, number)) { \ - PRINTF(text" [%u]\n", coap_pkt->field); \ - option += coap_serialize_int_option(number, current_number, option, coap_pkt->field); \ - current_number = number; \ - } -#define COAP_SERIALIZE_BYTE_OPTION(number, field, text) \ - if (IS_OPTION(coap_pkt, number)) { \ - PRINTF(text" %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->field##_len, \ - coap_pkt->field[0], \ - coap_pkt->field[1], \ - coap_pkt->field[2], \ - coap_pkt->field[3], \ - coap_pkt->field[4], \ - coap_pkt->field[5], \ - coap_pkt->field[6], \ - coap_pkt->field[7] \ - ); /*FIXME always prints 8 bytes */ \ - option += coap_serialize_array_option(number, current_number, option, coap_pkt->field, coap_pkt->field##_len, '\0'); \ - current_number = number; \ - } -#define COAP_SERIALIZE_STRING_OPTION(number, field, splitter, text) \ - if (IS_OPTION(coap_pkt, number)) { \ - PRINTF(text" [%.*s]\n", coap_pkt->field##_len, coap_pkt->field); \ - option += coap_serialize_array_option(number, current_number, option, (uint8_t *) coap_pkt->field, coap_pkt->field##_len, splitter); \ - current_number = number; \ - } -#define COAP_SERIALIZE_ACCEPT_OPTION(number, field, text) \ - if (IS_OPTION(coap_pkt, number)) { \ - int i; \ - for (i=0; ifield##_num; ++i) \ - { \ - PRINTF(text" [%u]\n", coap_pkt->field[i]); \ - option += coap_serialize_int_option(number, current_number, option, coap_pkt->field[i]); \ - current_number = number; \ - } \ - } -#define COAP_SERIALIZE_BLOCK_OPTION(number, field, text) \ - if (IS_OPTION(coap_pkt, number)) \ - { \ - PRINTF(text" [%lu%s (%u B/blk)]\n", coap_pkt->field##_num, coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size); \ - uint32_t block = coap_pkt->field##_num << 4; \ - if (coap_pkt->field##_more) block |= 0x8; \ - block |= 0xF & coap_log_2(coap_pkt->field##_size/16); \ - PRINTF(text" encoded: 0x%lX\n", block); \ - option += coap_serialize_int_option(number, current_number, option, block); \ - current_number = number; \ - } - -/* To store error code and human-readable payload */ -extern coap_status_t coap_error_code; -extern char *coap_error_message; - -void coap_init_connection(uint16_t port); -uint16_t coap_get_mid(void); - -void coap_init_message(void *packet, coap_message_type_t type, uint8_t code, uint16_t mid); -size_t coap_serialize_message(void *packet, uint8_t *buffer); -void coap_send_message(uip_ipaddr_t *addr, uint16_t port, uint8_t *data, uint16_t length); -coap_status_t coap_parse_message(void *request, uint8_t *data, uint16_t data_len); - -int coap_get_query_variable(void *packet, const char *name, const char **output); -int coap_get_post_variable(void *packet, const char *name, const char **output); - -/*-----------------------------------------------------------------------------------*/ - -int coap_set_status_code(void *packet, unsigned int code); - -unsigned int coap_get_header_content_type(void *packet); -int coap_set_header_content_type(void *packet, unsigned int content_type); - -int coap_get_header_accept(void *packet, const uint16_t **accept); -int coap_set_header_accept(void *packet, uint16_t accept); - -int coap_get_header_max_age(void *packet, uint32_t *age); -int coap_set_header_max_age(void *packet, uint32_t age); - -int coap_get_header_etag(void *packet, const uint8_t **etag); -int coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len); - -int coap_get_header_if_match(void *packet, const uint8_t **etag); -int coap_set_header_if_match(void *packet, const uint8_t *etag, size_t etag_len); - -int coap_get_header_if_none_match(void *packet); -int coap_set_header_if_none_match(void *packet); - -int coap_get_header_token(void *packet, const uint8_t **token); -int coap_set_header_token(void *packet, const uint8_t *token, size_t token_len); - -int coap_get_header_proxy_uri(void *packet, const char **uri); /* In-place string might not be 0-terminated. */ -int coap_set_header_proxy_uri(void *packet, const char *uri); - -int coap_get_header_uri_host(void *packet, const char **host); /* In-place string might not be 0-terminated. */ -int coap_set_header_uri_host(void *packet, const char *host); - -int coap_get_header_uri_path(void *packet, const char **path); /* In-place string might not be 0-terminated. */ -int coap_set_header_uri_path(void *packet, const char *path); - -int coap_get_header_uri_query(void *packet, const char **query); /* In-place string might not be 0-terminated. */ -int coap_set_header_uri_query(void *packet, const char *query); - -int coap_get_header_location_path(void *packet, const char **path); /* In-place string might not be 0-terminated. */ -int coap_set_header_location_path(void *packet, const char *path); /* Also splits optional query into Location-Query option. */ - -int coap_get_header_location_query(void *packet, const char **query); /* In-place string might not be 0-terminated. */ -int coap_set_header_location_query(void *packet, const char *query); - -int coap_get_header_observe(void *packet, uint32_t *observe); -int coap_set_header_observe(void *packet, uint32_t observe); - -int coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset); -int coap_set_header_block2(void *packet, uint32_t num, uint8_t more, uint16_t size); - -int coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset); -int coap_set_header_block1(void *packet, uint32_t num, uint8_t more, uint16_t size); - -int coap_get_header_size(void *packet, uint32_t *size); -int coap_set_header_size(void *packet, uint32_t size); - -int coap_get_payload(void *packet, const uint8_t **payload); -int coap_set_payload(void *packet, const void *payload, size_t length); - -#endif /* COAP_13_H_ */ diff --git a/apps/er-coap/Makefile.er-coap b/apps/er-coap/Makefile.er-coap new file mode 100755 index 000000000..23b70613e --- /dev/null +++ b/apps/er-coap/Makefile.er-coap @@ -0,0 +1,6 @@ +er-coap_src = er-coap.c er-coap-engine.c er-coap-transactions.c \ + er-coap-observe.c er-coap-separate.c er-coap-res-well-known-core.c \ + er-coap-block1.c er-coap-observe-client.c + +# Erbium will implement the REST Engine +CFLAGS += -DREST=coap_rest_implementation diff --git a/apps/er-coap/er-coap-block1.c b/apps/er-coap/er-coap-block1.c new file mode 100644 index 000000000..2f895b5fa --- /dev/null +++ b/apps/er-coap/er-coap-block1.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * CoAP module for block 1 handling + * \author + * Lars Schmertmann + */ + +#include +#include + +#include "er-coap.h" +#include "er-coap-block1.h" + +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +/*----------------------------------------------------------------------------*/ + +/** + * \brief Block 1 support within a coap-ressource + * + * This function will help you to use block 1. If target is null + * error handling and response configuration is active. On return + * value 0, the last block was recived, while on return value 1 + * more blocks will follow. With target, len and maxlen this + * function will assemble the blocks. + * + * You can find an example in: + * examples/er-rest-example/resources/res-b1-sep-b2.c + * + * \param request Request pointer from the handler + * \param response Response pointer from the handler + * \param target Pointer to the buffer where the request payload can be assembled + * \param len Pointer to the variable, where the function stores the actual length + * \param max_len Length of the "target"-Buffer + * + * \return 0 if initialisation was successful + * -1 if initialisation failed + */ +int +coap_block1_handler(void *request, void *response, uint8_t *target, size_t *len, size_t max_len) +{ + const uint8_t *payload = 0; + int pay_len = REST.get_request_payload(request, &payload); + + if(!pay_len || !payload) { + erbium_status_code = REST.status.BAD_REQUEST; + coap_error_message = "NoPayload"; + return -1; + } + + coap_packet_t *packet = (coap_packet_t *)request; + + if(packet->block1_offset + pay_len > max_len) { + erbium_status_code = REST.status.REQUEST_ENTITY_TOO_LARGE; + coap_error_message = "Message to big"; + return -1; + } + + if(target && len) { + memcpy(target + packet->block1_offset, payload, pay_len); + *len = packet->block1_offset + pay_len; + } + + if(IS_OPTION(packet, COAP_OPTION_BLOCK1)) { + PRINTF("Blockwise: block 1 request: Num: %u, More: %u, Size: %u, Offset: %u\n", + packet->block1_num, + packet->block1_more, + packet->block1_size, + packet->block1_offset); + + coap_set_header_block1(response, packet->block1_num, packet->block1_more, packet->block1_size); + if(packet->block1_more) { + coap_set_status_code(response, CONTINUE_2_31); + return 1; + } + } + + return 0; +} diff --git a/apps/er-coap/er-coap-block1.h b/apps/er-coap/er-coap-block1.h new file mode 100644 index 000000000..a6b1de5ab --- /dev/null +++ b/apps/er-coap/er-coap-block1.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * CoAP module for block 1 handling + * \author + * Lars Schmertmann + */ + +#ifndef COAP_BLOCK1_H_ +#define COAP_BLOCK1_H_ + +#include +#include + +int coap_block1_handler(void *request, void *response, uint8_t *target, size_t *len, size_t max_len); + +#endif /* COAP_BLOCK1_H_ */ diff --git a/apps/er-coap-12/er-coap-12-transactions.h b/apps/er-coap/er-coap-conf.h similarity index 54% rename from apps/er-coap-12/er-coap-12-transactions.h rename to apps/er-coap/er-coap-conf.h index b2a748cda..00d13d7c5 100644 --- a/apps/er-coap-12/er-coap-12-transactions.h +++ b/apps/er-coap/er-coap-conf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Institute for Pervasive Computing, ETH Zurich + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,48 +31,44 @@ /** * \file - * CoAP module for reliable transport + * Collection of default configuration values. * \author * Matthias Kovatsch */ -#ifndef COAP_TRANSACTIONS_H_ -#define COAP_TRANSACTIONS_H_ +#ifndef ER_COAP_CONF_H_ +#define ER_COAP_CONF_H_ -#include "er-coap-12.h" +/* Features that can be disabled to achieve smaller memory footprint */ +#define COAP_LINK_FORMAT_FILTERING 0 +#define COAP_PROXY_OPTION_PROCESSING 0 -/* - * The number of concurrent messages that can be stored for retransmission in the transaction layer. - */ +/* Listening port for the CoAP REST Engine */ +#ifndef COAP_SERVER_PORT +#define COAP_SERVER_PORT COAP_DEFAULT_PORT +#endif + +/* The number of concurrent messages that can be stored for retransmission in the transaction layer. */ #ifndef COAP_MAX_OPEN_TRANSACTIONS -#define COAP_MAX_OPEN_TRANSACTIONS 4 +#define COAP_MAX_OPEN_TRANSACTIONS 4 #endif /* COAP_MAX_OPEN_TRANSACTIONS */ -/* container for transactions with message buffer and retransmission info */ -typedef struct coap_transaction { - struct coap_transaction *next; /* for LIST */ +/* Maximum number of failed request attempts before action */ +#ifndef COAP_MAX_ATTEMPTS +#define COAP_MAX_ATTEMPTS 4 +#endif /* COAP_MAX_ATTEMPTS */ - uint16_t mid; - struct etimer retrans_timer; - uint8_t retrans_counter; +/* Conservative size limit, as not all options have to be set at the same time. Check when Proxy-Uri option is used */ +#ifndef COAP_MAX_HEADER_SIZE /* Hdr CoF If-Match Obs Blo strings */ +#define COAP_MAX_HEADER_SIZE (4 + COAP_TOKEN_LEN + 3 + 1 + COAP_ETAG_LEN + 4 + 4 + 30) /* 65 */ +#endif /* COAP_MAX_HEADER_SIZE */ - uip_ipaddr_t addr; - uint16_t port; +/* Number of observer slots (each takes abot xxx bytes) */ +#ifndef COAP_MAX_OBSERVERS +#define COAP_MAX_OBSERVERS COAP_MAX_OPEN_TRANSACTIONS - 1 +#endif /* COAP_MAX_OBSERVERS */ - restful_response_handler callback; - void *callback_data; +/* Interval in notifies in which NON notifies are changed to CON notifies to check client. */ +#define COAP_OBSERVE_REFRESH_INTERVAL 20 - uint16_t packet_len; - uint8_t packet[COAP_MAX_PACKET_SIZE+1]; /* +1 for the terminating '\0' to simply and savely use snprintf(buf, len+1, "", ...) in the resource handler. */ -} coap_transaction_t; - -void coap_register_as_transaction_handler(); - -coap_transaction_t *coap_new_transaction(uint16_t mid, uip_ipaddr_t *addr, uint16_t port); -void coap_send_transaction(coap_transaction_t *t); -void coap_clear_transaction(coap_transaction_t *t); -coap_transaction_t *coap_get_transaction_by_mid(uint16_t mid); - -void coap_check_transactions(); - -#endif /* COAP_TRANSACTIONS_H_ */ +#endif /* ER_COAP_CONF_H_ */ diff --git a/apps/er-coap/er-coap-constants.h b/apps/er-coap/er-coap-constants.h new file mode 100644 index 000000000..cfa73abcf --- /dev/null +++ b/apps/er-coap/er-coap-constants.h @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Collection of constants specified in the CoAP standard. + * \author + * Matthias Kovatsch + */ + +#ifndef ER_COAP_CONSTANTS_H_ +#define ER_COAP_CONSTANTS_H_ + +#define COAP_DEFAULT_PORT 5683 + +#define COAP_DEFAULT_MAX_AGE 60 +#define COAP_RESPONSE_TIMEOUT 3 +#define COAP_RESPONSE_RANDOM_FACTOR 1.5 +#define COAP_MAX_RETRANSMIT 4 + +#define COAP_HEADER_LEN 4 /* | version:0x03 type:0x0C tkl:0xF0 | code | mid:0x00FF | mid:0xFF00 | */ +#define COAP_TOKEN_LEN 8 /* The maximum number of bytes for the Token */ +#define COAP_ETAG_LEN 8 /* The maximum number of bytes for the ETag */ + +#define COAP_HEADER_VERSION_MASK 0xC0 +#define COAP_HEADER_VERSION_POSITION 6 +#define COAP_HEADER_TYPE_MASK 0x30 +#define COAP_HEADER_TYPE_POSITION 4 +#define COAP_HEADER_TOKEN_LEN_MASK 0x0F +#define COAP_HEADER_TOKEN_LEN_POSITION 0 + +#define COAP_HEADER_OPTION_DELTA_MASK 0xF0 +#define COAP_HEADER_OPTION_SHORT_LENGTH_MASK 0x0F + +/* CoAP message types */ +typedef enum { + COAP_TYPE_CON, /* confirmables */ + COAP_TYPE_NON, /* non-confirmables */ + COAP_TYPE_ACK, /* acknowledgements */ + COAP_TYPE_RST /* reset */ +} coap_message_type_t; + +/* CoAP request method codes */ +typedef enum { + COAP_GET = 1, + COAP_POST, + COAP_PUT, + COAP_DELETE +} coap_method_t; + +/* CoAP response codes */ +typedef enum { + NO_ERROR = 0, + + CREATED_2_01 = 65, /* CREATED */ + DELETED_2_02 = 66, /* DELETED */ + VALID_2_03 = 67, /* NOT_MODIFIED */ + CHANGED_2_04 = 68, /* CHANGED */ + CONTENT_2_05 = 69, /* OK */ + CONTINUE_2_31 = 95, /* CONTINUE */ + + BAD_REQUEST_4_00 = 128, /* BAD_REQUEST */ + UNAUTHORIZED_4_01 = 129, /* UNAUTHORIZED */ + BAD_OPTION_4_02 = 130, /* BAD_OPTION */ + FORBIDDEN_4_03 = 131, /* FORBIDDEN */ + NOT_FOUND_4_04 = 132, /* NOT_FOUND */ + METHOD_NOT_ALLOWED_4_05 = 133, /* METHOD_NOT_ALLOWED */ + NOT_ACCEPTABLE_4_06 = 134, /* NOT_ACCEPTABLE */ + PRECONDITION_FAILED_4_12 = 140, /* BAD_REQUEST */ + REQUEST_ENTITY_TOO_LARGE_4_13 = 141, /* REQUEST_ENTITY_TOO_LARGE */ + UNSUPPORTED_MEDIA_TYPE_4_15 = 143, /* UNSUPPORTED_MEDIA_TYPE */ + + INTERNAL_SERVER_ERROR_5_00 = 160, /* INTERNAL_SERVER_ERROR */ + NOT_IMPLEMENTED_5_01 = 161, /* NOT_IMPLEMENTED */ + BAD_GATEWAY_5_02 = 162, /* BAD_GATEWAY */ + SERVICE_UNAVAILABLE_5_03 = 163, /* SERVICE_UNAVAILABLE */ + GATEWAY_TIMEOUT_5_04 = 164, /* GATEWAY_TIMEOUT */ + PROXYING_NOT_SUPPORTED_5_05 = 165, /* PROXYING_NOT_SUPPORTED */ + + /* Erbium errors */ + MEMORY_ALLOCATION_ERROR = 192, + PACKET_SERIALIZATION_ERROR, + + /* Erbium hooks */ + MANUAL_RESPONSE, + PING_RESPONSE +} coap_status_t; + +/* CoAP header option numbers */ +typedef enum { + COAP_OPTION_IF_MATCH = 1, /* 0-8 B */ + COAP_OPTION_URI_HOST = 3, /* 1-255 B */ + COAP_OPTION_ETAG = 4, /* 1-8 B */ + COAP_OPTION_IF_NONE_MATCH = 5, /* 0 B */ + COAP_OPTION_OBSERVE = 6, /* 0-3 B */ + COAP_OPTION_URI_PORT = 7, /* 0-2 B */ + COAP_OPTION_LOCATION_PATH = 8, /* 0-255 B */ + COAP_OPTION_URI_PATH = 11, /* 0-255 B */ + COAP_OPTION_CONTENT_FORMAT = 12, /* 0-2 B */ + COAP_OPTION_MAX_AGE = 14, /* 0-4 B */ + COAP_OPTION_URI_QUERY = 15, /* 0-255 B */ + COAP_OPTION_ACCEPT = 17, /* 0-2 B */ + COAP_OPTION_LOCATION_QUERY = 20, /* 0-255 B */ + COAP_OPTION_BLOCK2 = 23, /* 1-3 B */ + COAP_OPTION_BLOCK1 = 27, /* 1-3 B */ + COAP_OPTION_SIZE2 = 28, /* 0-4 B */ + COAP_OPTION_PROXY_URI = 35, /* 1-1034 B */ + COAP_OPTION_PROXY_SCHEME = 39, /* 1-255 B */ + COAP_OPTION_SIZE1 = 60, /* 0-4 B */ +} coap_option_t; + +/* CoAP Content-Formats */ +typedef enum { + TEXT_PLAIN = 0, + TEXT_XML = 1, + TEXT_CSV = 2, + TEXT_HTML = 3, + IMAGE_GIF = 21, + IMAGE_JPEG = 22, + IMAGE_PNG = 23, + IMAGE_TIFF = 24, + AUDIO_RAW = 25, + VIDEO_RAW = 26, + APPLICATION_LINK_FORMAT = 40, + APPLICATION_XML = 41, + APPLICATION_OCTET_STREAM = 42, + APPLICATION_RDF_XML = 43, + APPLICATION_SOAP_XML = 44, + APPLICATION_ATOM_XML = 45, + APPLICATION_XMPP_XML = 46, + APPLICATION_EXI = 47, + APPLICATION_FASTINFOSET = 48, + APPLICATION_SOAP_FASTINFOSET = 49, + APPLICATION_JSON = 50, + APPLICATION_X_OBIX_BINARY = 51 +} coap_content_format_t; + +#endif /* ER_COAP_CONSTANTS_H_ */ diff --git a/apps/er-coap/er-coap-engine.c b/apps/er-coap/er-coap-engine.c new file mode 100644 index 000000000..2f58eda94 --- /dev/null +++ b/apps/er-coap/er-coap-engine.c @@ -0,0 +1,520 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * CoAP implementation for the REST Engine. + * \author + * Matthias Kovatsch + */ + +#include "sys/cc.h" +#include +#include +#include +#include "er-coap-engine.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +PROCESS(coap_engine, "CoAP Engine"); + +/*---------------------------------------------------------------------------*/ +/*- Variables ---------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +static service_callback_t service_cbk = NULL; + +/*---------------------------------------------------------------------------*/ +/*- Internal API ------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +static int +coap_receive(void) +{ + erbium_status_code = NO_ERROR; + + PRINTF("handle_incoming_data(): received uip_datalen=%u \n", + (uint16_t)uip_datalen()); + + /* static declaration reduces stack peaks and program code size */ + static coap_packet_t message[1]; /* this way the packet can be treated as pointer as usual */ + static coap_packet_t response[1]; + static coap_transaction_t *transaction = NULL; + + if(uip_newdata()) { + + PRINTF("receiving UDP datagram from: "); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF(":%u\n Length: %u\n", uip_ntohs(UIP_UDP_BUF->srcport), + uip_datalen()); + + erbium_status_code = + coap_parse_message(message, uip_appdata, uip_datalen()); + + if(erbium_status_code == NO_ERROR) { + + /*TODO duplicates suppression, if required by application */ + + PRINTF(" Parsed: v %u, t %u, tkl %u, c %u, mid %u\n", message->version, + message->type, message->token_len, message->code, message->mid); + PRINTF(" URL: %.*s\n", message->uri_path_len, message->uri_path); + PRINTF(" Payload: %.*s\n", message->payload_len, message->payload); + + /* handle requests */ + if(message->code >= COAP_GET && message->code <= COAP_DELETE) { + + /* use transaction buffer for response to confirmable request */ + if((transaction = + coap_new_transaction(message->mid, &UIP_IP_BUF->srcipaddr, + UIP_UDP_BUF->srcport))) { + uint32_t block_num = 0; + uint16_t block_size = COAP_MAX_BLOCK_SIZE; + uint32_t block_offset = 0; + int32_t new_offset = 0; + + /* prepare response */ + if(message->type == COAP_TYPE_CON) { + /* reliable CON requests are answered with an ACK */ + coap_init_message(response, COAP_TYPE_ACK, CONTENT_2_05, + message->mid); + } else { + /* unreliable NON requests are answered with a NON as well */ + coap_init_message(response, COAP_TYPE_NON, CONTENT_2_05, + coap_get_mid()); + /* mirror token */ + } if(message->token_len) { + coap_set_token(response, message->token, message->token_len); + /* get offset for blockwise transfers */ + } + if(coap_get_header_block2 + (message, &block_num, NULL, &block_size, &block_offset)) { + PRINTF("Blockwise: block request %lu (%u/%u) @ %lu bytes\n", + block_num, block_size, COAP_MAX_BLOCK_SIZE, block_offset); + block_size = MIN(block_size, COAP_MAX_BLOCK_SIZE); + new_offset = block_offset; + } + + /* invoke resource handler */ + if(service_cbk) { + + /* call REST framework and check if found and allowed */ + if(service_cbk + (message, response, transaction->packet + COAP_MAX_HEADER_SIZE, + block_size, &new_offset)) { + + if(erbium_status_code == NO_ERROR) { + + /* TODO coap_handle_blockwise(request, response, start_offset, end_offset); */ + + /* resource is unaware of Block1 */ + if(IS_OPTION(message, COAP_OPTION_BLOCK1) + && response->code < BAD_REQUEST_4_00 + && !IS_OPTION(response, COAP_OPTION_BLOCK1)) { + PRINTF("Block1 NOT IMPLEMENTED\n"); + + erbium_status_code = NOT_IMPLEMENTED_5_01; + coap_error_message = "NoBlock1Support"; + + /* client requested Block2 transfer */ + } else if(IS_OPTION(message, COAP_OPTION_BLOCK2)) { + + /* unchanged new_offset indicates that resource is unaware of blockwise transfer */ + if(new_offset == block_offset) { + PRINTF + ("Blockwise: unaware resource with payload length %u/%u\n", + response->payload_len, block_size); + if(block_offset >= response->payload_len) { + PRINTF + ("handle_incoming_data(): block_offset >= response->payload_len\n"); + + response->code = BAD_OPTION_4_02; + coap_set_payload(response, "BlockOutOfScope", 15); /* a const char str[] and sizeof(str) produces larger code size */ + } else { + coap_set_header_block2(response, block_num, + response->payload_len - + block_offset > block_size, + block_size); + coap_set_payload(response, + response->payload + block_offset, + MIN(response->payload_len - + block_offset, block_size)); + } /* if(valid offset) */ + + /* resource provides chunk-wise data */ + } else { + PRINTF("Blockwise: blockwise resource, new offset %ld\n", + new_offset); + coap_set_header_block2(response, block_num, + new_offset != -1 + || response->payload_len > + block_size, block_size); + + if(response->payload_len > block_size) { + coap_set_payload(response, response->payload, + block_size); + } + } /* if(resource aware of blockwise) */ + + /* Resource requested Block2 transfer */ + } else if(new_offset != 0) { + PRINTF + ("Blockwise: no block option for blockwise resource, using block size %u\n", + COAP_MAX_BLOCK_SIZE); + + coap_set_header_block2(response, 0, new_offset != -1, + COAP_MAX_BLOCK_SIZE); + coap_set_payload(response, response->payload, + MIN(response->payload_len, + COAP_MAX_BLOCK_SIZE)); + } /* blockwise transfer handling */ + } /* no errors/hooks */ + /* successful service callback */ + /* serialize response */ + } + if(erbium_status_code == NO_ERROR) { + if((transaction->packet_len = coap_serialize_message(response, + transaction-> + packet)) == + 0) { + erbium_status_code = PACKET_SERIALIZATION_ERROR; + } + } + } else { + erbium_status_code = NOT_IMPLEMENTED_5_01; + coap_error_message = "NoServiceCallbck"; /* no 'a' to fit into 16 bytes */ + } /* if(service callback) */ + } else { + erbium_status_code = SERVICE_UNAVAILABLE_5_03; + coap_error_message = "NoFreeTraBuffer"; + } /* if(transaction buffer) */ + + /* handle responses */ + } else { + + if(message->type == COAP_TYPE_CON && message->code == 0) { + PRINTF("Received Ping\n"); + erbium_status_code = PING_RESPONSE; + } else if(message->type == COAP_TYPE_ACK) { + /* transactions are closed through lookup below */ + PRINTF("Received ACK\n"); + } else if(message->type == COAP_TYPE_RST) { + PRINTF("Received RST\n"); + /* cancel possible subscriptions */ + coap_remove_observer_by_mid(&UIP_IP_BUF->srcipaddr, + UIP_UDP_BUF->srcport, message->mid); + } + + if((transaction = coap_get_transaction_by_mid(message->mid))) { + /* free transaction memory before callback, as it may create a new transaction */ + restful_response_handler callback = transaction->callback; + void *callback_data = transaction->callback_data; + + coap_clear_transaction(transaction); + + /* check if someone registered for the response */ + if(callback) { + callback(callback_data, message); + } + } + /* if(ACKed transaction) */ + transaction = NULL; + +#if COAP_OBSERVE_CLIENT + /* if observe notification */ + if((message->type == COAP_TYPE_CON || message->type == COAP_TYPE_NON) + && IS_OPTION(message, COAP_OPTION_OBSERVE)) { + PRINTF("Observe [%u]\n", message->observe); + coap_handle_notification(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, + message); + } +#endif /* COAP_OBSERVE_CLIENT */ + } /* request or response */ + } /* parsed correctly */ + + /* if(parsed correctly) */ + if(erbium_status_code == NO_ERROR) { + if(transaction) { + coap_send_transaction(transaction); + } + } else if(erbium_status_code == MANUAL_RESPONSE) { + PRINTF("Clearing transaction for manual response"); + coap_clear_transaction(transaction); + } else { + coap_message_type_t reply_type = COAP_TYPE_ACK; + + PRINTF("ERROR %u: %s\n", erbium_status_code, coap_error_message); + coap_clear_transaction(transaction); + + if(erbium_status_code == PING_RESPONSE) { + erbium_status_code = 0; + reply_type = COAP_TYPE_RST; + } else if(erbium_status_code >= 192) { + /* set to sendable error code */ + erbium_status_code = INTERNAL_SERVER_ERROR_5_00; + /* reuse input buffer for error message */ + } + coap_init_message(message, reply_type, erbium_status_code, + message->mid); + coap_set_payload(message, coap_error_message, + strlen(coap_error_message)); + coap_send_message(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, + uip_appdata, coap_serialize_message(message, + uip_appdata)); + } + } + + /* if(new data) */ + return erbium_status_code; +} +/*---------------------------------------------------------------------------*/ +void +coap_init_engine(void) +{ + process_start(&coap_engine, NULL); +} +/*---------------------------------------------------------------------------*/ +void +coap_set_service_callback(service_callback_t callback) +{ + service_cbk = callback; +} +/*---------------------------------------------------------------------------*/ +rest_resource_flags_t +coap_get_rest_method(void *packet) +{ + return (rest_resource_flags_t)(1 << + (((coap_packet_t *)packet)->code - 1)); +} +/*---------------------------------------------------------------------------*/ +/*- Server Part -------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +/* the discover resource is automatically included for CoAP */ +extern resource_t res_well_known_core; +#ifdef WITH_DTLS +extern resource_t res_dtls; +#endif + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(coap_engine, ev, data) +{ + PROCESS_BEGIN(); + PRINTF("Starting %s receiver...\n", coap_rest_implementation.name); + + rest_activate_resource(&res_well_known_core, ".well-known/core"); + + coap_register_as_transaction_handler(); + coap_init_connection(SERVER_LISTEN_PORT); + + while(1) { + PROCESS_YIELD(); + + if(ev == tcpip_event) { + coap_receive(); + } else if(ev == PROCESS_EVENT_TIMER) { + /* retransmissions are handled here */ + coap_check_transactions(); + } + } /* while (1) */ + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/*- Client Part -------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +void +coap_blocking_request_callback(void *callback_data, void *response) +{ + struct request_state_t *state = (struct request_state_t *)callback_data; + + state->response = (coap_packet_t *)response; + process_poll(state->process); +} +/*---------------------------------------------------------------------------*/ +PT_THREAD(coap_blocking_request + (struct request_state_t *state, process_event_t ev, + uip_ipaddr_t *remote_ipaddr, uint16_t remote_port, + coap_packet_t *request, + blocking_response_handler request_callback)) +{ + PT_BEGIN(&state->pt); + + static uint8_t more; + static uint32_t res_block; + static uint8_t block_error; + + state->block_num = 0; + state->response = NULL; + state->process = PROCESS_CURRENT(); + + more = 0; + res_block = 0; + block_error = 0; + + do { + request->mid = coap_get_mid(); + if((state->transaction = coap_new_transaction(request->mid, remote_ipaddr, + remote_port))) { + state->transaction->callback = coap_blocking_request_callback; + state->transaction->callback_data = state; + + if(state->block_num > 0) { + coap_set_header_block2(request, state->block_num, 0, + REST_MAX_CHUNK_SIZE); + } + state->transaction->packet_len = coap_serialize_message(request, + state-> + transaction-> + packet); + + coap_send_transaction(state->transaction); + PRINTF("Requested #%lu (MID %u)\n", state->block_num, request->mid); + + PT_YIELD_UNTIL(&state->pt, ev == PROCESS_EVENT_POLL); + + if(!state->response) { + PRINTF("Server not responding\n"); + PT_EXIT(&state->pt); + } + + coap_get_header_block2(state->response, &res_block, &more, NULL, NULL); + + PRINTF("Received #%lu%s (%u bytes)\n", res_block, more ? "+" : "", + state->response->payload_len); + + if(res_block == state->block_num) { + request_callback(state->response); + ++(state->block_num); + } else { + PRINTF("WRONG BLOCK %lu/%lu\n", res_block, state->block_num); + ++block_error; + } + } else { + PRINTF("Could not allocate transaction buffer"); + PT_EXIT(&state->pt); + } + } while(more && block_error < COAP_MAX_ATTEMPTS); + + PT_END(&state->pt); +} +/*---------------------------------------------------------------------------*/ +/*- REST Engine Interface ---------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +const struct rest_implementation coap_rest_implementation = { + "CoAP-18", + + coap_init_engine, + coap_set_service_callback, + + coap_get_header_uri_path, + coap_get_rest_method, + coap_set_status_code, + + coap_get_header_content_format, + coap_set_header_content_format, + coap_get_header_accept, + coap_get_header_size2, + coap_set_header_size2, + coap_get_header_max_age, + coap_set_header_max_age, + coap_set_header_etag, + coap_get_header_if_match, + coap_get_header_if_none_match, + coap_get_header_uri_host, + coap_set_header_location_path, + + coap_get_payload, + coap_set_payload, + + coap_get_header_uri_query, + coap_get_query_variable, + coap_get_post_variable, + + coap_notify_observers, + coap_observe_handler, + + { + CONTENT_2_05, + CREATED_2_01, + CHANGED_2_04, + DELETED_2_02, + VALID_2_03, + BAD_REQUEST_4_00, + UNAUTHORIZED_4_01, + BAD_OPTION_4_02, + FORBIDDEN_4_03, + NOT_FOUND_4_04, + METHOD_NOT_ALLOWED_4_05, + NOT_ACCEPTABLE_4_06, + REQUEST_ENTITY_TOO_LARGE_4_13, + UNSUPPORTED_MEDIA_TYPE_4_15, + INTERNAL_SERVER_ERROR_5_00, + NOT_IMPLEMENTED_5_01, + BAD_GATEWAY_5_02, + SERVICE_UNAVAILABLE_5_03, + GATEWAY_TIMEOUT_5_04, + PROXYING_NOT_SUPPORTED_5_05 + }, + + { + TEXT_PLAIN, + TEXT_XML, + TEXT_CSV, + TEXT_HTML, + IMAGE_GIF, + IMAGE_JPEG, + IMAGE_PNG, + IMAGE_TIFF, + AUDIO_RAW, + VIDEO_RAW, + APPLICATION_LINK_FORMAT, + APPLICATION_XML, + APPLICATION_OCTET_STREAM, + APPLICATION_RDF_XML, + APPLICATION_SOAP_XML, + APPLICATION_ATOM_XML, + APPLICATION_XMPP_XML, + APPLICATION_EXI, + APPLICATION_FASTINFOSET, + APPLICATION_SOAP_FASTINFOSET, + APPLICATION_JSON, + APPLICATION_X_OBIX_BINARY + } +}; +/*---------------------------------------------------------------------------*/ diff --git a/apps/er-coap-03/er-coap-03-engine.h b/apps/er-coap/er-coap-engine.h similarity index 64% rename from apps/er-coap-03/er-coap-03-engine.h rename to apps/er-coap/er-coap-engine.h index 3d8ab7afd..c6c6ae676 100644 --- a/apps/er-coap-03/er-coap-03-engine.h +++ b/apps/er-coap/er-coap-engine.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,61 +31,56 @@ /** * \file - * CoAP implementation of the REST Engine + * CoAP implementation for the REST Engine. * \author * Matthias Kovatsch */ -#ifndef COAP_SERVER_H_ -#define COAP_SERVER_H_ - -#if !defined(REST) -#error "Define REST to \"coap_rest_implementation\"" -#endif - -#include "er-coap-03.h" -#include "er-coap-03-transactions.h" -#include "er-coap-03-observing.h" +#ifndef ER_COAP_ENGINE_H_ +#define ER_COAP_ENGINE_H_ #include "pt.h" - -/* Declare server process */ -PROCESS_NAME(coap_receiver); +#include "er-coap.h" +#include "er-coap-transactions.h" +#include "er-coap-observe.h" +#include "er-coap-separate.h" +#include "er-coap-observe-client.h" #define SERVER_LISTEN_PORT UIP_HTONS(COAP_SERVER_PORT) typedef coap_packet_t rest_request_t; typedef coap_packet_t rest_response_t; -extern const struct rest_implementation coap_rest_implementation; +void coap_init_engine(void); -void coap_receiver_init(void); - -/*-----------------------------------------------------------------------------------*/ -/*- Client part ---------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/*- Client Part -------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ struct request_state_t { - struct pt pt; - struct process *process; - coap_transaction_t *transaction; - coap_packet_t *response; - uint32_t block_num; + struct pt pt; + struct process *process; + coap_transaction_t *transaction; + coap_packet_t *response; + uint32_t block_num; }; -typedef void (*blocking_response_handler) (void* response); +typedef void (*blocking_response_handler)(void *response); -PT_THREAD(coap_blocking_request(struct request_state_t *state, process_event_t ev, - uip_ipaddr_t *remote_ipaddr, uint16_t remote_port, - coap_packet_t *request, - blocking_response_handler request_callback)); +PT_THREAD(coap_blocking_request + (struct request_state_t *state, process_event_t ev, + uip_ipaddr_t *remote_ipaddr, uint16_t remote_port, + coap_packet_t *request, + blocking_response_handler request_callback)); #define COAP_BLOCKING_REQUEST(server_addr, server_port, request, chunk_handler) \ -static struct request_state_t request_state; \ -PT_SPAWN(process_pt, &request_state.pt, \ + { \ + static struct request_state_t request_state; \ + PT_SPAWN(process_pt, &request_state.pt, \ coap_blocking_request(&request_state, ev, \ server_addr, server_port, \ request, chunk_handler) \ - ); -/*-----------------------------------------------------------------------------------*/ + ); \ + } +/*---------------------------------------------------------------------------*/ -#endif /* COAP_SERVER_H_ */ +#endif /* ER_COAP_ENGINE_H_ */ diff --git a/apps/er-coap/er-coap-observe-client.c b/apps/er-coap/er-coap-observe-client.c new file mode 100644 index 000000000..21863200e --- /dev/null +++ b/apps/er-coap/er-coap-observe-client.c @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2014, Daniele Alessandrelli. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/* + * \file + * Extension to Erbium for enabling CoAP observe clients + * \author + * Daniele Alessandrelli + */ + +#include +#include + +#include "er-coap.h" +#include "er-coap-observe-client.h" + +/* Compile this code only if client-side support for CoAP Observe is required */ +#if COAP_OBSERVE_CLIENT + +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:" \ + "%02x%02x:%02x%02x:%02x%02x:%02x%02x]", \ + ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], \ + ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], \ + ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], \ + ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], \ + ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], \ + ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], \ + ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], \ + ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", \ + (lladdr)->addr[0], (lladdr)->addr[1], \ + (lladdr)->addr[2], (lladdr)->addr[3], \ + (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +MEMB(obs_subjects_memb, coap_observee_t, COAP_MAX_OBSERVEES); +LIST(obs_subjects_list); + +/*----------------------------------------------------------------------------*/ +static size_t +get_token(void *packet, const uint8_t **token) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + *token = coap_pkt->token; + + return coap_pkt->token_len; +} +/*----------------------------------------------------------------------------*/ +static int +set_token(void *packet, const uint8_t *token, size_t token_len) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + coap_pkt->token_len = MIN(COAP_TOKEN_LEN, token_len); + memcpy(coap_pkt->token, token, coap_pkt->token_len); + + return coap_pkt->token_len; +} +/*----------------------------------------------------------------------------*/ +coap_observee_t * +coap_obs_add_observee(uip_ipaddr_t *addr, uint16_t port, + const uint8_t *token, size_t token_len, const char *url, + notification_callback_t notification_callback, + void *data) +{ + coap_observee_t *o; + + /* Remove existing observe relationship, if any. */ + coap_obs_remove_observee_by_url(addr, port, url); + o = memb_alloc(&obs_subjects_memb); + if(o) { + o->url = url; + uip_ipaddr_copy(&o->addr, addr); + o->port = port; + o->token_len = token_len; + memcpy(o->token, token, token_len); + /* o->last_mid = 0; */ + o->notification_callback = notification_callback; + o->data = data; + /* stimer_set(&o->refresh_timer, COAP_OBSERVING_REFRESH_INTERVAL); */ + PRINTF("Adding obs_subject for /%s [0x%02X%02X]\n", o->url, o->token[0], + o->token[1]); + list_add(obs_subjects_list, o); + } + + return o; +} +/*----------------------------------------------------------------------------*/ +void +coap_obs_remove_observee(coap_observee_t *o) +{ + PRINTF("Removing obs_subject for /%s [0x%02X%02X]\n", o->url, o->token[0], + o->token[1]); + memb_free(&obs_subjects_memb, o); + list_remove(obs_subjects_list, o); +} +/*----------------------------------------------------------------------------*/ +coap_observee_t * +coap_get_obs_subject_by_token(const uint8_t *token, size_t token_len) +{ + coap_observee_t *obs = NULL; + + for(obs = (coap_observee_t *)list_head(obs_subjects_list); obs; + obs = obs->next) { + PRINTF("Looking for token 0x%02X%02X\n", token[0], token[1]); + if(obs->token_len == token_len + && memcmp(obs->token, token, token_len) == 0) { + return obs; + } + } + + return NULL; +} +/*----------------------------------------------------------------------------*/ +int +coap_obs_remove_observee_by_token(uip_ipaddr_t *addr, uint16_t port, + uint8_t *token, size_t token_len) +{ + int removed = 0; + coap_observee_t *obs = NULL; + + for(obs = (coap_observee_t *)list_head(obs_subjects_list); obs; + obs = obs->next) { + PRINTF("Remove check Token 0x%02X%02X\n", token[0], token[1]); + if(uip_ipaddr_cmp(&obs->addr, addr) + && obs->port == port + && obs->token_len == token_len + && memcmp(obs->token, token, token_len) == 0) { + coap_obs_remove_observee(obs); + removed++; + } + } + return removed; +} +/*----------------------------------------------------------------------------*/ +int +coap_obs_remove_observee_by_url(uip_ipaddr_t *addr, uint16_t port, + const char *url) +{ + int removed = 0; + coap_observee_t *obs = NULL; + + for(obs = (coap_observee_t *)list_head(obs_subjects_list); obs; + obs = obs->next) { + PRINTF("Remove check URL %s\n", url); + if(uip_ipaddr_cmp(&obs->addr, addr) + && obs->port == port + && (obs->url == url || memcmp(obs->url, url, strlen(obs->url)) == 0)) { + coap_obs_remove_observee(obs); + removed++; + } + } + return removed; +} +/*----------------------------------------------------------------------------*/ +static void +simple_reply(coap_message_type_t type, uip_ip6addr_t *addr, uint16_t port, + coap_packet_t *notification) +{ + static coap_packet_t response[1]; + size_t len; + + coap_init_message(response, type, NO_ERROR, notification->mid); + len = coap_serialize_message(response, uip_appdata); + coap_send_message(addr, port, uip_appdata, len); +} +/*----------------------------------------------------------------------------*/ +static coap_notification_flag_t +classify_notification(void *response, int first) +{ + coap_packet_t *pkt; + + pkt = (coap_packet_t *)response; + if(!pkt) { + PRINTF("no response\n"); + return NO_REPLY_FROM_SERVER; + } + PRINTF("server replied\n"); + if(!IS_RESPONSE_CODE_2_XX(pkt)) { + PRINTF("error response code\n"); + return ERROR_RESPONSE_CODE; + } + if(!IS_OPTION(pkt, COAP_OPTION_OBSERVE)) { + PRINTF("server does not support observe\n"); + return OBSERVE_NOT_SUPPORTED; + } + if(first) { + return OBSERVE_OK; + } + return NOTIFICATION_OK; +} +/*----------------------------------------------------------------------------*/ +void +coap_handle_notification(uip_ipaddr_t *addr, uint16_t port, + coap_packet_t *notification) +{ + coap_packet_t *pkt; + const uint8_t *token; + int token_len; + coap_observee_t *obs; + coap_notification_flag_t flag; + uint32_t observe; + + PRINTF("coap_handle_notification()\n"); + pkt = (coap_packet_t *)notification; + token_len = get_token(pkt, &token); + PRINTF("Getting token\n"); + if(0 == token_len) { + PRINTF("Error while handling coap observe notification: " + "no token in message\n"); + return; + } + PRINTF("Getting observee info\n"); + obs = coap_get_obs_subject_by_token(token, token_len); + if(NULL == obs) { + PRINTF("Error while handling coap observe notification: " + "no matching token found\n"); + simple_reply(COAP_TYPE_RST, addr, port, notification); + return; + } + if(notification->type == COAP_TYPE_CON) { + simple_reply(COAP_TYPE_ACK, addr, port, notification); + } + if(obs->notification_callback != NULL) { + flag = classify_notification(notification, 0); + /* TODO: the following mechanism for discarding duplicates is too trivial */ + /* refer to Observe RFC for a better solution */ + if(flag == NOTIFICATION_OK) { + coap_get_header_observe(notification, &observe); + if(observe == obs->last_observe) { + PRINTF("Discarding duplicate\n"); + return; + } + obs->last_observe = observe; + } + obs->notification_callback(obs, notification, flag); + } +} +/*----------------------------------------------------------------------------*/ +static void +handle_obs_registration_response(void *data, void *response) +{ + coap_observee_t *obs; + notification_callback_t notification_callback; + coap_notification_flag_t flag; + + PRINTF("handle_obs_registration_response(): "); + obs = (coap_observee_t *)data; + notification_callback = obs->notification_callback; + flag = classify_notification(response, 1); + if(notification_callback) { + notification_callback(obs, response, flag); + } + if(flag != OBSERVE_OK) { + coap_obs_remove_observee(obs); + } +} +/*----------------------------------------------------------------------------*/ +uint8_t +coap_generate_token(uint8_t **token_ptr) +{ + static uint8_t token = 0; + + token++; + /* FIXME: we should check that this token is not already used */ + *token_ptr = (uint8_t *)&token; + return sizeof(token); +} +/*----------------------------------------------------------------------------*/ +coap_observee_t * +coap_obs_request_registration(uip_ipaddr_t *addr, uint16_t port, char *uri, + notification_callback_t notification_callback, + void *data) +{ + coap_packet_t request[1]; + coap_transaction_t *t; + uint8_t *token; + uint8_t token_len; + coap_observee_t *obs; + + obs = NULL; + coap_init_message(request, COAP_TYPE_CON, COAP_GET, coap_get_mid()); + coap_set_header_uri_path(request, uri); + coap_set_header_observe(request, 0); + token_len = coap_generate_token(&token); + set_token(request, token, token_len); + t = coap_new_transaction(request->mid, addr, port); + if(t) { + obs = coap_obs_add_observee(addr, port, (uint8_t *)token, token_len, uri, + notification_callback, data); + if(obs) { + t->callback = handle_obs_registration_response; + t->callback_data = obs; + t->packet_len = coap_serialize_message(request, t->packet); + coap_send_transaction(t); + } else { + PRINTF("Could not allocate obs_subject resource buffer"); + coap_clear_transaction(t); + } + } else { + PRINTF("Could not allocate transaction buffer"); + } + return obs; +} +#endif /* COAP_OBSERVE_CLIENT */ diff --git a/apps/er-coap/er-coap-observe-client.h b/apps/er-coap/er-coap-observe-client.h new file mode 100644 index 000000000..d0ece32c0 --- /dev/null +++ b/apps/er-coap/er-coap-observe-client.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2014, Daniele Alessandrelli. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/* + * \file + * Extension to Erbium for enabling CoAP observe clients + * \author + * Daniele Alessandrelli + */ + +#ifndef COAP_OBSERVING_CLIENT_H_ +#define COAP_OBSERVING_CLIENT_H_ + +#include "er-coap.h" +#include "er-coap-transactions.h" + +#ifndef COAP_OBSERVE_CLIENT +#define COAP_OBSERVE_CLIENT 0 +#endif + +#ifdef COAP_CONF_MAX_OBSERVEES +#define COAP_MAX_OBSERVEES COAP_CONF_MAX_OBSERVEES +#else +#define COAP_MAX_OBSERVEES 4 +#endif /* COAP_CONF_MAX_OBSERVEES */ + +#if COAP_MAX_OPEN_TRANSACTIONS < COAP_MAX_OBSERVEES +#warning "COAP_MAX_OPEN_TRANSACTIONS smaller than COAP_MAX_OBSERVEES: " \ + "this may be a problem" +#endif + +#define IS_RESPONSE_CODE_2_XX(message) (64 < message->code \ + && message->code < 128) + +/*----------------------------------------------------------------------------*/ +typedef enum { + OBSERVE_OK, + NOTIFICATION_OK, + OBSERVE_NOT_SUPPORTED, + ERROR_RESPONSE_CODE, + NO_REPLY_FROM_SERVER, +} coap_notification_flag_t; + +/*----------------------------------------------------------------------------*/ +typedef struct coap_observee_s coap_observee_t; + +typedef void (*notification_callback_t)(coap_observee_t *subject, + void *notification, + coap_notification_flag_t); + +struct coap_observee_s { + coap_observee_t *next; /* for LIST */ + uip_ipaddr_t addr; + uint16_t port; + const char *url; + uint8_t token_len; + uint8_t token[COAP_TOKEN_LEN]; + void *data; /* generic pointer for storing user data */ + notification_callback_t notification_callback; + uint32_t last_observe; +}; + +/*----------------------------------------------------------------------------*/ +coap_observee_t *coap_obs_add_observee(uip_ipaddr_t *addr, uint16_t port, + const uint8_t *token, size_t token_len, + const char *url, + notification_callback_t + notification_callback, void *data); + +void coap_obs_remove_observee(coap_observee_t *o); + +coap_observee_t *coap_obs_get_observee_by_token(const uint8_t *token, + size_t token_len); + +int coap_obs_remove_observee_by_token(uip_ipaddr_t *addr, uint16_t port, + uint8_t *token, size_t token_len); + +int coap_obs_remove_observee_by_url(uip_ipaddr_t *addr, uint16_t port, + const char *url); + +void coap_handle_notification(uip_ipaddr_t *, uint16_t port, + coap_packet_t *notification); + +coap_observee_t *coap_obs_request_registration(uip_ipaddr_t *addr, + uint16_t port, char *uri, + notification_callback_t + notification_callback, + void *data); +/* TODO: this function may be moved to er-coap.c */ +uint8_t coap_generate_token(uint8_t **token_ptr); + +#endif /* COAP_OBSERVING_CLIENT_H_ */ diff --git a/apps/er-coap/er-coap-observe.c b/apps/er-coap/er-coap-observe.c new file mode 100644 index 000000000..35ab2ff74 --- /dev/null +++ b/apps/er-coap/er-coap-observe.c @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * CoAP module for observing resources (draft-ietf-core-observe-11). + * \author + * Matthias Kovatsch + */ + +#include +#include +#include "er-coap-observe.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +/*---------------------------------------------------------------------------*/ +MEMB(observers_memb, coap_observer_t, COAP_MAX_OBSERVERS); +LIST(observers_list); +/*---------------------------------------------------------------------------*/ +/*- Internal API ------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +static coap_observer_t * +add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token, + size_t token_len, const char *uri, int uri_len) +{ + /* Remove existing observe relationship, if any. */ + coap_remove_observer_by_uri(addr, port, uri); + + coap_observer_t *o = memb_alloc(&observers_memb); + + if(o) { + int max = sizeof(o->url) - 1; + if(max > uri_len) { + max = uri_len; + } + memcpy(o->url, uri, max); + o->url[max] = 0; + uip_ipaddr_copy(&o->addr, addr); + o->port = port; + o->token_len = token_len; + memcpy(o->token, token, token_len); + o->last_mid = 0; + + PRINTF("Adding observer (%u/%u) for /%s [0x%02X%02X]\n", + list_length(observers_list) + 1, COAP_MAX_OBSERVERS, + o->url, o->token[0], o->token[1]); + list_add(observers_list, o); + } + + return o; +} +/*---------------------------------------------------------------------------*/ +/*- Removal -----------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +void +coap_remove_observer(coap_observer_t *o) +{ + PRINTF("Removing observer for /%s [0x%02X%02X]\n", o->url, o->token[0], + o->token[1]); + + memb_free(&observers_memb, o); + list_remove(observers_list, o); +} +/*---------------------------------------------------------------------------*/ +int +coap_remove_observer_by_client(uip_ipaddr_t *addr, uint16_t port) +{ + int removed = 0; + coap_observer_t *obs = NULL; + + for(obs = (coap_observer_t *)list_head(observers_list); obs; + obs = obs->next) { + PRINTF("Remove check client "); + PRINT6ADDR(addr); + PRINTF(":%u\n", port); + if(uip_ipaddr_cmp(&obs->addr, addr) && obs->port == port) { + coap_remove_observer(obs); + removed++; + } + } + return removed; +} +/*---------------------------------------------------------------------------*/ +int +coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port, + uint8_t *token, size_t token_len) +{ + int removed = 0; + coap_observer_t *obs = NULL; + + for(obs = (coap_observer_t *)list_head(observers_list); obs; + obs = obs->next) { + PRINTF("Remove check Token 0x%02X%02X\n", token[0], token[1]); + if(uip_ipaddr_cmp(&obs->addr, addr) && obs->port == port + && obs->token_len == token_len + && memcmp(obs->token, token, token_len) == 0) { + coap_remove_observer(obs); + removed++; + } + } + return removed; +} +/*---------------------------------------------------------------------------*/ +int +coap_remove_observer_by_uri(uip_ipaddr_t *addr, uint16_t port, + const char *uri) +{ + int removed = 0; + coap_observer_t *obs = NULL; + + for(obs = (coap_observer_t *)list_head(observers_list); obs; + obs = obs->next) { + PRINTF("Remove check URL %p\n", uri); + if((addr == NULL + || (uip_ipaddr_cmp(&obs->addr, addr) && obs->port == port)) + && (obs->url == uri || memcmp(obs->url, uri, strlen(obs->url)) == 0)) { + coap_remove_observer(obs); + removed++; + } + } + return removed; +} +/*---------------------------------------------------------------------------*/ +int +coap_remove_observer_by_mid(uip_ipaddr_t *addr, uint16_t port, uint16_t mid) +{ + int removed = 0; + coap_observer_t *obs = NULL; + + for(obs = (coap_observer_t *)list_head(observers_list); obs; + obs = obs->next) { + PRINTF("Remove check MID %u\n", mid); + if(uip_ipaddr_cmp(&obs->addr, addr) && obs->port == port + && obs->last_mid == mid) { + coap_remove_observer(obs); + removed++; + } + } + return removed; +} +/*---------------------------------------------------------------------------*/ +/*- Notification ------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +void +coap_notify_observers(resource_t *resource) +{ + coap_notify_observers_sub(resource, NULL); +} +void +coap_notify_observers_sub(resource_t *resource, const char *subpath) +{ + /* build notification */ + coap_packet_t notification[1]; /* this way the packet can be treated as pointer as usual */ + coap_packet_t request[1]; /* this way the packet can be treated as pointer as usual */ + coap_observer_t *obs = NULL; + int url_len, obs_url_len; + char url[COAP_OBSERVER_URL_LEN]; + + url_len = strlen(resource->url); + strncpy(url, resource->url, COAP_OBSERVER_URL_LEN - 1); + if(url_len < COAP_OBSERVER_URL_LEN - 1 && subpath != NULL) { + strncpy(&url[url_len], subpath, COAP_OBSERVER_URL_LEN - url_len - 1); + } + /* Ensure url is null terminated because strncpy does not guarantee this */ + url[COAP_OBSERVER_URL_LEN - 1] = '\0'; + /* url now contains the notify URL that needs to match the observer */ + PRINTF("Observe: Notification from %s\n", url); + + coap_init_message(notification, COAP_TYPE_NON, CONTENT_2_05, 0); + /* create a "fake" request for the URI */ + coap_init_message(request, COAP_TYPE_CON, COAP_GET, 0); + coap_set_header_uri_path(request, url); + + /* iterate over observers */ + url_len = strlen(url); + for(obs = (coap_observer_t *)list_head(observers_list); obs; + obs = obs->next) { + obs_url_len = strlen(obs->url); + + /* Do a match based on the parent/sub-resource match so that it is + possible to do parent-node observe */ + if((obs_url_len == url_len + || (obs_url_len > url_len + && (resource->flags & HAS_SUB_RESOURCES) + && obs->url[url_len] == '/')) + && strncmp(url, obs->url, url_len) == 0) { + coap_transaction_t *transaction = NULL; + + /*TODO implement special transaction for CON, sharing the same buffer to allow for more observers */ + + if((transaction = coap_new_transaction(coap_get_mid(), &obs->addr, obs->port))) { + if(obs->obs_counter % COAP_OBSERVE_REFRESH_INTERVAL == 0) { + PRINTF(" Force Confirmable for\n"); + notification->type = COAP_TYPE_CON; + } + + PRINTF(" Observer "); + PRINT6ADDR(&obs->addr); + PRINTF(":%u\n", obs->port); + + /* update last MID for RST matching */ + obs->last_mid = transaction->mid; + + /* prepare response */ + notification->mid = transaction->mid; + + resource->get_handler(request, notification, + transaction->packet + COAP_MAX_HEADER_SIZE, + REST_MAX_CHUNK_SIZE, NULL); + + if(notification->code < BAD_REQUEST_4_00) { + coap_set_header_observe(notification, (obs->obs_counter)++); + } + coap_set_token(notification, obs->token, obs->token_len); + + transaction->packet_len = + coap_serialize_message(notification, transaction->packet); + + coap_send_transaction(transaction); + } + } + } +} +/*---------------------------------------------------------------------------*/ +void +coap_observe_handler(resource_t *resource, void *request, void *response) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + coap_packet_t *const coap_res = (coap_packet_t *)response; + coap_observer_t * obs; + + if(coap_req->code == COAP_GET && coap_res->code < 128) { /* GET request and response without error code */ + if(IS_OPTION(coap_req, COAP_OPTION_OBSERVE)) { + if(coap_req->observe == 0) { + obs = add_observer(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, + coap_req->token, coap_req->token_len, + coap_req->uri_path, coap_req->uri_path_len); + if(obs) { + coap_set_header_observe(coap_res, (obs->obs_counter)++); + /* + * Following payload is for demonstration purposes only. + * A subscription should return the same representation as a normal GET. + * Uncomment if you want an information about the avaiable observers. + */ +#if 0 + static char content[16]; + coap_set_payload(coap_res, + content, + snprintf(content, sizeof(content), "Added %u/%u", + list_length(observers_list), + COAP_MAX_OBSERVERS)); +#endif + } else { + coap_res->code = SERVICE_UNAVAILABLE_5_03; + coap_set_payload(coap_res, "TooManyObservers", 16); + } + } else if(coap_req->observe == 1) { + + /* remove client if it is currently observe */ + coap_remove_observer_by_token(&UIP_IP_BUF->srcipaddr, + UIP_UDP_BUF->srcport, coap_req->token, + coap_req->token_len); + } + } + } +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/er-coap-13/er-coap-13-observing.h b/apps/er-coap/er-coap-observe.h similarity index 65% rename from apps/er-coap-13/er-coap-13-observing.h rename to apps/er-coap/er-coap-observe.h index 3b6510a71..4e9644bf0 100644 --- a/apps/er-coap-13/er-coap-13-observing.h +++ b/apps/er-coap/er-coap-observe.h @@ -31,53 +31,58 @@ /** * \file - * CoAP module for observing resources + * CoAP module for observing resources (draft-ietf-core-observe-11). * \author * Matthias Kovatsch */ -#ifndef COAP_OBSERVING_H_ -#define COAP_OBSERVING_H_ +#ifndef COAP_OBSERVE_H_ +#define COAP_OBSERVE_H_ -#include "sys/stimer.h" -#include "er-coap-13.h" -#include "er-coap-13-transactions.h" +#include "er-coap.h" +#include "er-coap-transactions.h" +#include "stimer.h" -#ifndef COAP_MAX_OBSERVERS -#define COAP_MAX_OBSERVERS COAP_MAX_OPEN_TRANSACTIONS-1 -#endif /* COAP_MAX_OBSERVERS */ +#define COAP_OBSERVER_URL_LEN 20 -/* Interval in seconds in which NON notifies are changed to CON notifies to check client. */ -#define COAP_OBSERVING_REFRESH_INTERVAL 60 - -#if COAP_MAX_OPEN_TRANSACTIONS + */ + +#include +#include "er-coap-engine.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +#define ADD_CHAR_IF_POSSIBLE(char) \ + if(strpos >= *offset && bufpos < preferred_size) { \ + buffer[bufpos++] = char; \ + } \ + ++strpos + +#define ADD_STRING_IF_POSSIBLE(string, op) \ + tmplen = strlen(string); \ + if(strpos + tmplen > *offset) { \ + bufpos += snprintf((char *)buffer + bufpos, \ + preferred_size - bufpos + 1, \ + "%s", \ + string \ + + (*offset - (int32_t)strpos > 0 ? \ + *offset - (int32_t)strpos : 0)); \ + if(bufpos op preferred_size) { \ + PRINTF("res: BREAK at %s (%p)\n", string, resource); \ + break; \ + } \ + } \ + strpos += tmplen + +/*---------------------------------------------------------------------------*/ +/*- Resource Handlers -------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +void +well_known_core_get_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + size_t strpos = 0; /* position in overall string (which is larger than the buffer) */ + size_t bufpos = 0; /* position within buffer (bytes written) */ + size_t tmplen = 0; + resource_t *resource = NULL; + +#if COAP_LINK_FORMAT_FILTERING + /* For filtering. */ + const char *filter = NULL; + const char *attrib = NULL; + const char *found = NULL; + const char *end = NULL; + char *value = NULL; + char lastchar = '\0'; + int len = coap_get_header_uri_query(request, &filter); + + if(len) { + value = strchr(filter, '='); + value[0] = '\0'; + ++value; + len -= strlen(filter) + 1; + + PRINTF("Filter %s = %.*s\n", filter, len, value); + + if(strcmp(filter, "href") == 0 && value[0] == '/') { + ++value; + --len; + } + + lastchar = value[len - 1]; + value[len - 1] = '\0'; + } +#endif + + for(resource = (resource_t *)list_head(rest_get_resources()); resource; + resource = resource->next) { +#if COAP_LINK_FORMAT_FILTERING + /* Filtering */ + if(len) { + if(strcmp(filter, "href") == 0) { + attrib = strstr(resource->url, value); + if(attrib == NULL || (value[-1] == '/' && attrib != resource->url)) { + continue; + } + end = attrib + strlen(attrib); + } else if(resource->attributes != NULL) { + attrib = strstr(resource->attributes, filter); + if(attrib == NULL + || (attrib[strlen(filter)] != '=' + && attrib[strlen(filter)] != '"')) { + continue; + } + attrib += strlen(filter) + 2; + end = strchr(attrib, '"'); + } + + PRINTF("Filter: res has attrib %s (%s)\n", attrib, value); + found = attrib; + while((found = strstr(found, value)) != NULL) { + if(found > end) { + found = NULL; + break; + } + if(lastchar == found[len - 1] || lastchar == '*') { + break; + } + ++found; + } + if(found == NULL) { + continue; + } + PRINTF("Filter: res has prefix %s\n", found); + if(lastchar != '*' + && (found[len] != '"' && found[len] != ' ' && found[len] != '\0')) { + continue; + } + PRINTF("Filter: res has match\n"); + } +#endif + + PRINTF("res: /%s (%p)\npos: s%zu, o%ld, b%zu\n", resource->url, resource, + strpos, (long)*offset, bufpos); + + if(strpos > 0) { + ADD_CHAR_IF_POSSIBLE(','); + } + ADD_CHAR_IF_POSSIBLE('<'); + ADD_CHAR_IF_POSSIBLE('/'); + ADD_STRING_IF_POSSIBLE(resource->url, >=); + ADD_CHAR_IF_POSSIBLE('>'); + + if(resource->attributes != NULL && resource->attributes[0]) { + ADD_CHAR_IF_POSSIBLE(';'); + ADD_STRING_IF_POSSIBLE(resource->attributes, >); + } + + /* buffer full, but resource not completed yet; or: do not break if resource exactly fills buffer. */ + if(bufpos > preferred_size && strpos - bufpos > *offset) { + PRINTF("res: BREAK at %s (%p)\n", resource->url, resource); + break; + } + } + + if(bufpos > 0) { + PRINTF("BUF %zu: %.*s\n", bufpos, (int)bufpos, (char *)buffer); + + coap_set_payload(response, buffer, bufpos); + coap_set_header_content_format(response, APPLICATION_LINK_FORMAT); + } else if(strpos > 0) { + PRINTF("well_known_core_handler(): bufpos<=0\n"); + + coap_set_status_code(response, BAD_OPTION_4_02); + coap_set_payload(response, "BlockOutOfScope", 15); + } + + if(resource == NULL) { + PRINTF("res: DONE\n"); + *offset = -1; + } else { + PRINTF("res: MORE at %s (%p)\n", resource->url, resource); + *offset += preferred_size; + } +} +/*---------------------------------------------------------------------------*/ +RESOURCE(res_well_known_core, "ct=40", well_known_core_get_handler, NULL, + NULL, NULL); +/*---------------------------------------------------------------------------*/ diff --git a/apps/er-coap-13/er-coap-13-separate.c b/apps/er-coap/er-coap-separate.c similarity index 55% rename from apps/er-coap-13/er-coap-13-separate.c rename to apps/er-coap/er-coap-separate.c index 85ec4ec0c..5e2242b9c 100644 --- a/apps/er-coap-13/er-coap-13-separate.c +++ b/apps/er-coap/er-coap-separate.c @@ -31,87 +31,119 @@ /** * \file - * CoAP module for separate responses + * CoAP module for separate responses. * \author * Matthias Kovatsch */ +#include "sys/cc.h" #include #include - -#include "er-coap-13-separate.h" -#include "er-coap-13-transactions.h" +#include "er-coap-separate.h" +#include "er-coap-transactions.h" #define DEBUG 0 #if DEBUG +#include #define PRINTF(...) printf(__VA_ARGS__) #define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) #else #define PRINTF(...) #define PRINT6ADDR(addr) #define PRINTLLADDR(addr) #endif -/*----------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/*- Separate Response API ---------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/** + * \brief Reject a request that would require a separate response with an error message + * + * When the server does not have enough resources left to store the information + * for a separate response or otherwise cannot execute the resource handler, + * this function will respond with 5.03 Service Unavailable. The client can + * then retry later. + */ void coap_separate_reject() { - coap_error_code = SERVICE_UNAVAILABLE_5_03; + /* TODO: Accept string pointer for custom error message */ + erbium_status_code = SERVICE_UNAVAILABLE_5_03; coap_error_message = "AlreadyInUse"; } /*----------------------------------------------------------------------------*/ -int +/** + * \brief Initiate a separate response with an empty ACK + * \param request The request to accept + * \param separate_store A pointer to the data structure that will store the + * relevant information for the response + * + * When the server does not have enough resources left to store the information + * for a separate response or otherwise cannot execute the resource handler, + * this function will respond with 5.03 Service Unavailable. The client can + * then retry later. + */ +void coap_separate_accept(void *request, coap_separate_t *separate_store) { - coap_packet_t *const coap_req = (coap_packet_t *) request; + coap_packet_t *const coap_req = (coap_packet_t *)request; coap_transaction_t *const t = coap_get_transaction_by_mid(coap_req->mid); - PRINTF("Separate ACCEPT: /%.*s MID %u\n", coap_req->uri_path_len, coap_req->uri_path, coap_req->mid); - if (t) - { - /* Send separate ACK for CON. */ - if (coap_req->type==COAP_TYPE_CON) - { + PRINTF("Separate ACCEPT: /%.*s MID %u\n", coap_req->uri_path_len, + coap_req->uri_path, coap_req->mid); + if(t) { + /* send separate ACK for CON */ + if(coap_req->type == COAP_TYPE_CON) { coap_packet_t ack[1]; + /* ACK with empty code (0) */ coap_init_message(ack, COAP_TYPE_ACK, 0, coap_req->mid); - /* Serializing into IPBUF: Only overwrites header parts that are already parsed into the request struct. */ - coap_send_message(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, (uip_appdata), coap_serialize_message(ack, uip_appdata)); + /* serializing into IPBUF: Only overwrites header parts that are already parsed into the request struct */ + coap_send_message(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, + (uip_appdata), coap_serialize_message(ack, + uip_appdata)); } - /* Store remote address. */ + /* store remote address */ uip_ipaddr_copy(&separate_store->addr, &t->addr); separate_store->port = t->port; - /* Store correct response type. */ - separate_store->type = coap_req->type==COAP_TYPE_CON ? COAP_TYPE_CON : COAP_TYPE_NON; + /* store correct response type */ + separate_store->type = + coap_req->type == COAP_TYPE_CON ? COAP_TYPE_CON : COAP_TYPE_NON; separate_store->mid = coap_get_mid(); /* if it was a NON, we burned one MID in the engine... */ memcpy(separate_store->token, coap_req->token, coap_req->token_len); separate_store->token_len = coap_req->token_len; + separate_store->block1_num = coap_req->block1_num; + separate_store->block1_size = coap_req->block1_size; + separate_store->block2_num = coap_req->block2_num; - separate_store->block2_size = coap_req->block2_size; + separate_store->block2_size = coap_req->block2_size > 0 ? MIN(COAP_MAX_BLOCK_SIZE, coap_req->block2_size) : COAP_MAX_BLOCK_SIZE; - /* Signal the engine to skip automatic response and clear transaction by engine. */ - coap_error_code = MANUAL_RESPONSE; - - return 1; - } - else - { + /* signal the engine to skip automatic response and clear transaction by engine */ + erbium_status_code = MANUAL_RESPONSE; + } else { PRINTF("ERROR: Response transaction for separate request not found!\n"); - return 0; + erbium_status_code = INTERNAL_SERVER_ERROR_5_00; } } /*----------------------------------------------------------------------------*/ void -coap_separate_resume(void *response, coap_separate_t *separate_store, uint8_t code) +coap_separate_resume(void *response, coap_separate_t *separate_store, + uint8_t code) { - coap_init_message(response, separate_store->type, code, separate_store->mid); - if (separate_store->token_len) - { - coap_set_header_token(response, separate_store->token, separate_store->token_len); + coap_init_message(response, separate_store->type, code, + separate_store->mid); + if(separate_store->token_len) { + coap_set_token(response, separate_store->token, + separate_store->token_len); + } + if(separate_store->block1_size) { + coap_set_header_block1(response, separate_store->block1_num, + 0, separate_store->block1_size); } } +/*---------------------------------------------------------------------------*/ diff --git a/apps/er-coap-13/er-coap-13-separate.h b/apps/er-coap/er-coap-separate.h similarity index 84% rename from apps/er-coap-13/er-coap-13-separate.h rename to apps/er-coap/er-coap-separate.h index d34eea606..33a923240 100644 --- a/apps/er-coap-13/er-coap-13-separate.h +++ b/apps/er-coap/er-coap-separate.h @@ -31,7 +31,7 @@ /** * \file - * CoAP module for separate responses + * CoAP module for separate responses. * \author * Matthias Kovatsch */ @@ -39,7 +39,7 @@ #ifndef COAP_SEPARATE_H_ #define COAP_SEPARATE_H_ -#include "er-coap-13.h" +#include "er-coap.h" typedef struct coap_separate { @@ -52,15 +52,18 @@ typedef struct coap_separate { uint8_t token_len; uint8_t token[COAP_TOKEN_LEN]; - /* separate + blockwise is untested! */ + uint32_t block1_num; + uint16_t block1_size; + uint32_t block2_num; uint16_t block2_size; - } coap_separate_t; -int coap_separate_handler(resource_t *resource, void *request, void *response); -void coap_separate_reject(); -int coap_separate_accept(void *request, coap_separate_t *separate_store); -void coap_separate_resume(void *response, coap_separate_t *separate_store, uint8_t code); +int coap_separate_handler(resource_t *resource, void *request, + void *response); +void coap_separate_reject(void); +void coap_separate_accept(void *request, coap_separate_t *separate_store); +void coap_separate_resume(void *response, coap_separate_t *separate_store, + uint8_t code); #endif /* COAP_SEPARATE_H_ */ diff --git a/apps/er-coap-13/er-coap-13-transactions.c b/apps/er-coap/er-coap-transactions.c similarity index 66% rename from apps/er-coap-13/er-coap-13-transactions.c rename to apps/er-coap/er-coap-transactions.c index 6bdc49fc3..3987b4814 100644 --- a/apps/er-coap-13/er-coap-13-transactions.c +++ b/apps/er-coap/er-coap-transactions.c @@ -38,49 +38,41 @@ #include "contiki.h" #include "contiki-net.h" - -#include "er-coap-13-transactions.h" -#include "er-coap-13-observing.h" - -/* - * Modulo mask (+1 and +0.5 for rounding) for a random number to get the tick number for the random - * retransmission time between COAP_RESPONSE_TIMEOUT and COAP_RESPONSE_TIMEOUT*COAP_RESPONSE_RANDOM_FACTOR. - */ -#define COAP_RESPONSE_TIMEOUT_TICKS (CLOCK_SECOND * COAP_RESPONSE_TIMEOUT) -#define COAP_RESPONSE_TIMEOUT_BACKOFF_MASK ((CLOCK_SECOND * COAP_RESPONSE_TIMEOUT * (COAP_RESPONSE_RANDOM_FACTOR - 1)) + 1.5) +#include "er-coap-transactions.h" +#include "er-coap-observe.h" #define DEBUG 0 #if DEBUG #include #define PRINTF(...) printf(__VA_ARGS__) #define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) #else #define PRINTF(...) #define PRINT6ADDR(addr) #define PRINTLLADDR(addr) #endif - +/*---------------------------------------------------------------------------*/ MEMB(transactions_memb, coap_transaction_t, COAP_MAX_OPEN_TRANSACTIONS); LIST(transactions_list); - static struct process *transaction_handler_process = NULL; +/*---------------------------------------------------------------------------*/ +/*- Internal API ------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ void coap_register_as_transaction_handler() { transaction_handler_process = PROCESS_CURRENT(); } - coap_transaction_t * coap_new_transaction(uint16_t mid, uip_ipaddr_t *addr, uint16_t port) { coap_transaction_t *t = memb_alloc(&transactions_memb); - if (t) - { + if(t) { t->mid = mid; t->retrans_counter = 0; @@ -88,12 +80,12 @@ coap_new_transaction(uint16_t mid, uip_ipaddr_t *addr, uint16_t port) uip_ipaddr_copy(&t->addr, addr); t->port = port; - list_add(transactions_list, t); /* List itself makes sure same element is not added twice. */ + list_add(transactions_list, t); /* list itself makes sure same element is not added twice */ } return t; } - +/*---------------------------------------------------------------------------*/ void coap_send_transaction(coap_transaction_t *t) { @@ -101,38 +93,33 @@ coap_send_transaction(coap_transaction_t *t) coap_send_message(&t->addr, t->port, t->packet, t->packet_len); - if (COAP_TYPE_CON==((COAP_HEADER_TYPE_MASK & t->packet[0])>>COAP_HEADER_TYPE_POSITION)) - { - if (t->retrans_counterpacket[0]) >> COAP_HEADER_TYPE_POSITION)) { + if(t->retrans_counter < COAP_MAX_RETRANSMIT) { + /* not timed out yet */ PRINTF("Keeping transaction %u\n", t->mid); - if (t->retrans_counter==0) - { - t->retrans_timer.timer.interval = COAP_RESPONSE_TIMEOUT_TICKS + (random_rand() % (clock_time_t) COAP_RESPONSE_TIMEOUT_BACKOFF_MASK); - PRINTF("Initial interval %f\n", (float)t->retrans_timer.timer.interval/CLOCK_SECOND); - } - else - { - t->retrans_timer.timer.interval <<= 1; /* double */ - PRINTF("Doubled (%u) interval %f\n", t->retrans_counter, (float)t->retrans_timer.timer.interval/CLOCK_SECOND); + if(t->retrans_counter == 0) { + t->retrans_timer.timer.interval = + COAP_RESPONSE_TIMEOUT_TICKS + (random_rand() + % + (clock_time_t) + COAP_RESPONSE_TIMEOUT_BACKOFF_MASK); + PRINTF("Initial interval %f\n", + (float)t->retrans_timer.timer.interval / CLOCK_SECOND); + } else { + t->retrans_timer.timer.interval <<= 1; /* double */ + PRINTF("Doubled (%u) interval %f\n", t->retrans_counter, + (float)t->retrans_timer.timer.interval / CLOCK_SECOND); } - /*FIXME - * Hack: Setting timer for responsible process. - * Maybe there is a better way, but avoid posting everything to the process. - */ - struct process *process_actual = PROCESS_CURRENT(); - process_current = transaction_handler_process; - etimer_restart(&t->retrans_timer); /* interval updated above */ - process_current = process_actual; + PROCESS_CONTEXT_BEGIN(transaction_handler_process); + etimer_restart(&t->retrans_timer); /* interval updated above */ + PROCESS_CONTEXT_END(transaction_handler_process); t = NULL; - } - else - { - /* Timed out. */ + } else { + /* timed out */ PRINTF("Timeout\n"); restful_response_handler callback = t->callback; void *callback_data = t->callback_data; @@ -142,22 +129,19 @@ coap_send_transaction(coap_transaction_t *t) coap_clear_transaction(t); - if (callback) { + if(callback) { callback(callback_data, NULL); } } - } - else - { + } else { coap_clear_transaction(t); } } - +/*---------------------------------------------------------------------------*/ void coap_clear_transaction(coap_transaction_t *t) { - if (t) - { + if(t) { PRINTF("Freeing transaction %u: %p\n", t->mid, t); etimer_stop(&t->retrans_timer); @@ -165,35 +149,31 @@ coap_clear_transaction(coap_transaction_t *t) memb_free(&transactions_memb, t); } } - coap_transaction_t * coap_get_transaction_by_mid(uint16_t mid) { coap_transaction_t *t = NULL; - for (t = (coap_transaction_t*)list_head(transactions_list); t; t = t->next) - { - if (t->mid==mid) - { + for(t = (coap_transaction_t *)list_head(transactions_list); t; t = t->next) { + if(t->mid == mid) { PRINTF("Found transaction for MID %u: %p\n", t->mid, t); return t; } } return NULL; } - +/*---------------------------------------------------------------------------*/ void coap_check_transactions() { coap_transaction_t *t = NULL; - for (t = (coap_transaction_t*)list_head(transactions_list); t; t = t->next) - { - if (etimer_expired(&t->retrans_timer)) - { + for(t = (coap_transaction_t *)list_head(transactions_list); t; t = t->next) { + if(etimer_expired(&t->retrans_timer)) { ++(t->retrans_counter); PRINTF("Retransmitting %u (%u)\n", t->mid, t->retrans_counter); coap_send_transaction(t); } } } +/*---------------------------------------------------------------------------*/ diff --git a/apps/er-coap-13/er-coap-13-transactions.h b/apps/er-coap/er-coap-transactions.h similarity index 73% rename from apps/er-coap-13/er-coap-13-transactions.h rename to apps/er-coap/er-coap-transactions.h index a127656d6..10697134a 100644 --- a/apps/er-coap-13/er-coap-13-transactions.h +++ b/apps/er-coap/er-coap-transactions.h @@ -39,18 +39,18 @@ #ifndef COAP_TRANSACTIONS_H_ #define COAP_TRANSACTIONS_H_ -#include "er-coap-13.h" +#include "er-coap.h" /* - * The number of concurrent messages that can be stored for retransmission in the transaction layer. + * Modulo mask (thus +1) for a random number to get the tick number for the random + * retransmission time between COAP_RESPONSE_TIMEOUT and COAP_RESPONSE_TIMEOUT*COAP_RESPONSE_RANDOM_FACTOR. */ -#ifndef COAP_MAX_OPEN_TRANSACTIONS -#define COAP_MAX_OPEN_TRANSACTIONS 4 -#endif /* COAP_MAX_OPEN_TRANSACTIONS */ +#define COAP_RESPONSE_TIMEOUT_TICKS (CLOCK_SECOND * COAP_RESPONSE_TIMEOUT) +#define COAP_RESPONSE_TIMEOUT_BACKOFF_MASK (long)((CLOCK_SECOND * COAP_RESPONSE_TIMEOUT * ((float)COAP_RESPONSE_RANDOM_FACTOR - 1.0)) + 0.5) + 1 /* container for transactions with message buffer and retransmission info */ typedef struct coap_transaction { - struct coap_transaction *next; /* for LIST */ + struct coap_transaction *next; /* for LIST */ uint16_t mid; struct etimer retrans_timer; @@ -63,16 +63,18 @@ typedef struct coap_transaction { void *callback_data; uint16_t packet_len; - uint8_t packet[COAP_MAX_PACKET_SIZE+1]; /* +1 for the terminating '\0' to simply and savely use snprintf(buf, len+1, "", ...) in the resource handler. */ + uint8_t packet[COAP_MAX_PACKET_SIZE + 1]; /* +1 for the terminating '\0' which will not be sent + * Use snprintf(buf, len+1, "", ...) to completely fill payload */ } coap_transaction_t; -void coap_register_as_transaction_handler(); +void coap_register_as_transaction_handler(void); -coap_transaction_t *coap_new_transaction(uint16_t mid, uip_ipaddr_t *addr, uint16_t port); +coap_transaction_t *coap_new_transaction(uint16_t mid, uip_ipaddr_t *addr, + uint16_t port); void coap_send_transaction(coap_transaction_t *t); void coap_clear_transaction(coap_transaction_t *t); coap_transaction_t *coap_get_transaction_by_mid(uint16_t mid); -void coap_check_transactions(); +void coap_check_transactions(void); #endif /* COAP_TRANSACTIONS_H_ */ diff --git a/apps/er-coap/er-coap.c b/apps/er-coap/er-coap.c new file mode 100644 index 000000000..597d24a11 --- /dev/null +++ b/apps/er-coap/er-coap.c @@ -0,0 +1,1210 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * An implementation of the Constrained Application Protocol (RFC). + * \author + * Matthias Kovatsch + */ + +#include +#include +#include "contiki.h" +#include "sys/cc.h" +#include "contiki-net.h" + +#include "er-coap.h" +#include "er-coap-transactions.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +/*---------------------------------------------------------------------------*/ +/*- Variables ---------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +static struct uip_udp_conn *udp_conn = NULL; +static uint16_t current_mid = 0; + +coap_status_t erbium_status_code = NO_ERROR; +char *coap_error_message = ""; +/*---------------------------------------------------------------------------*/ +/*- Local helper functions --------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +static uint16_t +coap_log_2(uint16_t value) +{ + uint16_t result = 0; + + do { + value = value >> 1; + result++; + } while(value); + + return result ? result - 1 : result; +} +/*---------------------------------------------------------------------------*/ +static uint32_t +coap_parse_int_option(uint8_t *bytes, size_t length) +{ + uint32_t var = 0; + int i = 0; + + while(i < length) { + var <<= 8; + var |= bytes[i++]; + } + return var; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +coap_option_nibble(unsigned int value) +{ + if(value < 13) { + return value; + } else if(value <= 0xFF + 13) { + return 13; + } else { + return 14; + } +} +/*---------------------------------------------------------------------------*/ +static size_t +coap_set_option_header(unsigned int delta, size_t length, uint8_t *buffer) +{ + size_t written = 0; + + buffer[0] = coap_option_nibble(delta) << 4 | coap_option_nibble(length); + + if(delta > 268) { + buffer[++written] = ((delta - 269) >> 8) & 0xff; + buffer[++written] = (delta - 269) & 0xff; + } else if(delta > 12) { + buffer[++written] = (delta - 13); + } + + if(length > 268) { + buffer[++written] = ((length - 269) >> 8) & 0xff; + buffer[++written] = (length - 269) & 0xff; + } else if(length > 12) { + buffer[++written] = (length - 13); + } + + PRINTF("WRITTEN %zu B opt header\n", 1 + written); + + return ++written; +} +/*---------------------------------------------------------------------------*/ +static size_t +coap_serialize_int_option(unsigned int number, unsigned int current_number, + uint8_t *buffer, uint32_t value) +{ + size_t i = 0; + + if(0xFF000000 & value) { + ++i; + } + if(0xFFFF0000 & value) { + ++i; + } + if(0xFFFFFF00 & value) { + ++i; + } + if(0xFFFFFFFF & value) { + ++i; + } + PRINTF("OPTION %u (delta %u, len %zu)\n", number, number - current_number, + i); + + i = coap_set_option_header(number - current_number, i, buffer); + + if(0xFF000000 & value) { + buffer[i++] = (uint8_t)(value >> 24); + } + if(0xFFFF0000 & value) { + buffer[i++] = (uint8_t)(value >> 16); + } + if(0xFFFFFF00 & value) { + buffer[i++] = (uint8_t)(value >> 8); + } + if(0xFFFFFFFF & value) { + buffer[i++] = (uint8_t)(value); + } + return i; +} +/*---------------------------------------------------------------------------*/ +static size_t +coap_serialize_array_option(unsigned int number, unsigned int current_number, + uint8_t *buffer, uint8_t *array, size_t length, + char split_char) +{ + size_t i = 0; + + PRINTF("ARRAY type %u, len %zu, full [%.*s]\n", number, length, + (int)length, array); + + if(split_char != '\0') { + int j; + uint8_t *part_start = array; + uint8_t *part_end = NULL; + size_t temp_length; + + for(j = 0; j <= length + 1; ++j) { + PRINTF("STEP %u/%zu (%c)\n", j, length, array[j]); + if(array[j] == split_char || j == length) { + part_end = array + j; + temp_length = part_end - part_start; + + i += coap_set_option_header(number - current_number, temp_length, + &buffer[i]); + memcpy(&buffer[i], part_start, temp_length); + i += temp_length; + + PRINTF("OPTION type %u, delta %u, len %zu, part [%.*s]\n", number, + number - current_number, i, (int)temp_length, part_start); + + ++j; /* skip the splitter */ + current_number = number; + part_start = array + j; + } + } /* for */ + } else { + i += coap_set_option_header(number - current_number, length, &buffer[i]); + memcpy(&buffer[i], array, length); + i += length; + + PRINTF("OPTION type %u, delta %u, len %zu\n", number, + number - current_number, length); + } + + return i; +} +/*---------------------------------------------------------------------------*/ +static void +coap_merge_multi_option(char **dst, size_t *dst_len, uint8_t *option, + size_t option_len, char separator) +{ + /* merge multiple options */ + if(*dst_len > 0) { + /* dst already contains an option: concatenate */ + (*dst)[*dst_len] = separator; + *dst_len += 1; + + /* memmove handles 2-byte option headers */ + memmove((*dst) + (*dst_len), option, option_len); + + *dst_len += option_len; + } else { + /* dst is empty: set to option */ + *dst = (char *)option; + *dst_len = option_len; + } +} +/*---------------------------------------------------------------------------*/ +static int +coap_get_variable(const char *buffer, size_t length, const char *name, + const char **output) +{ + const char *start = NULL; + const char *end = NULL; + const char *value_end = NULL; + size_t name_len = 0; + + /*initialize the output buffer first */ + *output = 0; + + name_len = strlen(name); + end = buffer + length; + + for(start = buffer; start + name_len < end; ++start) { + if((start == buffer || start[-1] == '&') && start[name_len] == '=' + && strncmp(name, start, name_len) == 0) { + + /* Point start to variable value */ + start += name_len + 1; + + /* Point end to the end of the value */ + value_end = (const char *)memchr(start, '&', end - start); + if(value_end == NULL) { + value_end = end; + } + *output = start; + + return value_end - start; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +/*- Internal API ------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +void +coap_init_connection(uint16_t port) +{ + /* new connection with remote host */ + udp_conn = udp_new(NULL, 0, NULL); + udp_bind(udp_conn, port); + PRINTF("Listening on port %u\n", uip_ntohs(udp_conn->lport)); + + /* initialize transaction ID */ + current_mid = random_rand(); +} +/*---------------------------------------------------------------------------*/ +uint16_t +coap_get_mid() +{ + return ++current_mid; +} +/*---------------------------------------------------------------------------*/ +void +coap_init_message(void *packet, coap_message_type_t type, uint8_t code, + uint16_t mid) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + /* Important thing */ + memset(coap_pkt, 0, sizeof(coap_packet_t)); + + coap_pkt->type = type; + coap_pkt->code = code; + coap_pkt->mid = mid; +} +/*---------------------------------------------------------------------------*/ +size_t +coap_serialize_message(void *packet, uint8_t *buffer) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + uint8_t *option; + unsigned int current_number = 0; + + /* Initialize */ + coap_pkt->buffer = buffer; + coap_pkt->version = 1; + + PRINTF("-Serializing MID %u to %p, ", coap_pkt->mid, coap_pkt->buffer); + + /* set header fields */ + coap_pkt->buffer[0] = 0x00; + coap_pkt->buffer[0] |= COAP_HEADER_VERSION_MASK + & (coap_pkt->version) << COAP_HEADER_VERSION_POSITION; + coap_pkt->buffer[0] |= COAP_HEADER_TYPE_MASK + & (coap_pkt->type) << COAP_HEADER_TYPE_POSITION; + coap_pkt->buffer[0] |= COAP_HEADER_TOKEN_LEN_MASK + & (coap_pkt->token_len) << COAP_HEADER_TOKEN_LEN_POSITION; + coap_pkt->buffer[1] = coap_pkt->code; + coap_pkt->buffer[2] = (uint8_t)((coap_pkt->mid) >> 8); + coap_pkt->buffer[3] = (uint8_t)(coap_pkt->mid); + + /* empty packet, dont need to do more stuff */ + if(!coap_pkt->code) { + PRINTF("-Done serializing empty message at %p-\n", coap_pkt->buffer); + return 4; + } + + /* set Token */ + PRINTF("Token (len %u)", coap_pkt->token_len); + option = coap_pkt->buffer + COAP_HEADER_LEN; + for(current_number = 0; current_number < coap_pkt->token_len; + ++current_number) { + PRINTF(" %02X", coap_pkt->token[current_number]); + *option = coap_pkt->token[current_number]; + ++option; + } + PRINTF("-\n"); + + /* Serialize options */ + current_number = 0; + + PRINTF("-Serializing options at %p-\n", option); + + /* The options must be serialized in the order of their number */ + COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_IF_MATCH, if_match, "If-Match"); + COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_HOST, uri_host, '\0', + "Uri-Host"); + COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_ETAG, etag, "ETag"); + COAP_SERIALIZE_INT_OPTION(COAP_OPTION_IF_NONE_MATCH, + content_format - + coap_pkt-> + content_format /* hack to get a zero field */, + "If-None-Match"); + COAP_SERIALIZE_INT_OPTION(COAP_OPTION_OBSERVE, observe, "Observe"); + COAP_SERIALIZE_INT_OPTION(COAP_OPTION_URI_PORT, uri_port, "Uri-Port"); + COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_PATH, location_path, '/', + "Location-Path"); + COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_PATH, uri_path, '/', + "Uri-Path"); + PRINTF("Serialize content format: %d\n", coap_pkt->content_format); + COAP_SERIALIZE_INT_OPTION(COAP_OPTION_CONTENT_FORMAT, content_format, + "Content-Format"); + COAP_SERIALIZE_INT_OPTION(COAP_OPTION_MAX_AGE, max_age, "Max-Age"); + COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_QUERY, uri_query, '&', + "Uri-Query"); + COAP_SERIALIZE_INT_OPTION(COAP_OPTION_ACCEPT, accept, "Accept"); + COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_QUERY, location_query, + '&', "Location-Query"); + COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK2, block2, "Block2"); + COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK1, block1, "Block1"); + COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE2, size2, "Size2"); + COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_URI, proxy_uri, '\0', + "Proxy-Uri"); + COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_SCHEME, proxy_scheme, '\0', + "Proxy-Scheme"); + COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE1, size1, "Size1"); + + PRINTF("-Done serializing at %p----\n", option); + + /* Pack payload */ + if((option - coap_pkt->buffer) <= COAP_MAX_HEADER_SIZE) { + /* Payload marker */ + if(coap_pkt->payload_len) { + *option = 0xFF; + ++option; + } + memmove(option, coap_pkt->payload, coap_pkt->payload_len); + } else { + /* an error occurred: caller must check for !=0 */ + coap_pkt->buffer = NULL; + coap_error_message = "Serialized header exceeds COAP_MAX_HEADER_SIZE"; + return 0; + } + + PRINTF("-Done %u B (header len %u, payload len %u)-\n", + (unsigned int)(coap_pkt->payload_len + option - buffer), + (unsigned int)(option - buffer), + (unsigned int)coap_pkt->payload_len); + + PRINTF("Dump [0x%02X %02X %02X %02X %02X %02X %02X %02X]\n", + coap_pkt->buffer[0], + coap_pkt->buffer[1], + coap_pkt->buffer[2], + coap_pkt->buffer[3], + coap_pkt->buffer[4], + coap_pkt->buffer[5], coap_pkt->buffer[6], coap_pkt->buffer[7] + ); + + return (option - buffer) + coap_pkt->payload_len; /* packet length */ +} +/*---------------------------------------------------------------------------*/ +void +coap_send_message(uip_ipaddr_t *addr, uint16_t port, uint8_t *data, + uint16_t length) +{ + /* configure connection to reply to client */ + uip_ipaddr_copy(&udp_conn->ripaddr, addr); + udp_conn->rport = port; + + uip_udp_packet_send(udp_conn, data, length); + + PRINTF("-sent UDP datagram (%u)-\n", length); + + /* restore server socket to allow data from any node */ + memset(&udp_conn->ripaddr, 0, sizeof(udp_conn->ripaddr)); + udp_conn->rport = 0; +} +/*---------------------------------------------------------------------------*/ +coap_status_t +coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + /* initialize packet */ + memset(coap_pkt, 0, sizeof(coap_packet_t)); + + /* pointer to packet bytes */ + coap_pkt->buffer = data; + + /* parse header fields */ + coap_pkt->version = (COAP_HEADER_VERSION_MASK & coap_pkt->buffer[0]) + >> COAP_HEADER_VERSION_POSITION; + coap_pkt->type = (COAP_HEADER_TYPE_MASK & coap_pkt->buffer[0]) + >> COAP_HEADER_TYPE_POSITION; + coap_pkt->token_len = (COAP_HEADER_TOKEN_LEN_MASK & coap_pkt->buffer[0]) + >> COAP_HEADER_TOKEN_LEN_POSITION; + coap_pkt->code = coap_pkt->buffer[1]; + coap_pkt->mid = coap_pkt->buffer[2] << 8 | coap_pkt->buffer[3]; + + if(coap_pkt->version != 1) { + coap_error_message = "CoAP version must be 1"; + return BAD_REQUEST_4_00; + } + + if(coap_pkt->token_len > COAP_TOKEN_LEN) { + coap_error_message = "Token Length must not be more than 8"; + return BAD_REQUEST_4_00; + } + + uint8_t *current_option = data + COAP_HEADER_LEN; + + memcpy(coap_pkt->token, current_option, coap_pkt->token_len); + PRINTF("Token (len %u) [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", + coap_pkt->token_len, coap_pkt->token[0], coap_pkt->token[1], + coap_pkt->token[2], coap_pkt->token[3], coap_pkt->token[4], + coap_pkt->token[5], coap_pkt->token[6], coap_pkt->token[7] + ); /*FIXME always prints 8 bytes */ + + /* parse options */ + memset(coap_pkt->options, 0, sizeof(coap_pkt->options)); + current_option += coap_pkt->token_len; + + unsigned int option_number = 0; + unsigned int option_delta = 0; + size_t option_length = 0; + + while(current_option < data + data_len) { + /* payload marker 0xFF, currently only checking for 0xF* because rest is reserved */ + if((current_option[0] & 0xF0) == 0xF0) { + coap_pkt->payload = ++current_option; + coap_pkt->payload_len = data_len - (coap_pkt->payload - data); + + /* also for receiving, the Erbium upper bound is REST_MAX_CHUNK_SIZE */ + if(coap_pkt->payload_len > REST_MAX_CHUNK_SIZE) { + coap_pkt->payload_len = REST_MAX_CHUNK_SIZE; + /* null-terminate payload */ + } + coap_pkt->payload[coap_pkt->payload_len] = '\0'; + + break; + } + + option_delta = current_option[0] >> 4; + option_length = current_option[0] & 0x0F; + ++current_option; + + if(option_delta == 13) { + option_delta += current_option[0]; + ++current_option; + } else if(option_delta == 14) { + option_delta += 255; + option_delta += current_option[0] << 8; + ++current_option; + option_delta += current_option[0]; + ++current_option; + } + + if(option_length == 13) { + option_length += current_option[0]; + ++current_option; + } else if(option_length == 14) { + option_length += 255; + option_length += current_option[0] << 8; + ++current_option; + option_length += current_option[0]; + ++current_option; + } + + option_number += option_delta; + + PRINTF("OPTION %u (delta %u, len %zu): ", option_number, option_delta, + option_length); + + SET_OPTION(coap_pkt, option_number); + + switch(option_number) { + case COAP_OPTION_CONTENT_FORMAT: + coap_pkt->content_format = coap_parse_int_option(current_option, + option_length); + PRINTF("Content-Format [%u]\n", coap_pkt->content_format); + break; + case COAP_OPTION_MAX_AGE: + coap_pkt->max_age = coap_parse_int_option(current_option, + option_length); + PRINTF("Max-Age [%lu]\n", (unsigned long)coap_pkt->max_age); + break; + case COAP_OPTION_ETAG: + coap_pkt->etag_len = MIN(COAP_ETAG_LEN, option_length); + memcpy(coap_pkt->etag, current_option, coap_pkt->etag_len); + PRINTF("ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", + coap_pkt->etag_len, coap_pkt->etag[0], coap_pkt->etag[1], + coap_pkt->etag[2], coap_pkt->etag[3], coap_pkt->etag[4], + coap_pkt->etag[5], coap_pkt->etag[6], coap_pkt->etag[7] + ); /*FIXME always prints 8 bytes */ + break; + case COAP_OPTION_ACCEPT: + coap_pkt->accept = coap_parse_int_option(current_option, option_length); + PRINTF("Accept [%u]\n", coap_pkt->accept); + break; + case COAP_OPTION_IF_MATCH: + /* TODO support multiple ETags */ + coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, option_length); + memcpy(coap_pkt->if_match, current_option, coap_pkt->if_match_len); + PRINTF("If-Match %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", + coap_pkt->if_match_len, coap_pkt->if_match[0], + coap_pkt->if_match[1], coap_pkt->if_match[2], + coap_pkt->if_match[3], coap_pkt->if_match[4], + coap_pkt->if_match[5], coap_pkt->if_match[6], + coap_pkt->if_match[7] + ); /* FIXME always prints 8 bytes */ + break; + case COAP_OPTION_IF_NONE_MATCH: + coap_pkt->if_none_match = 1; + PRINTF("If-None-Match\n"); + break; + + case COAP_OPTION_PROXY_URI: +#if COAP_PROXY_OPTION_PROCESSING + coap_pkt->proxy_uri = (char *)current_option; + coap_pkt->proxy_uri_len = option_length; +#endif + PRINTF("Proxy-Uri NOT IMPLEMENTED [%.*s]\n", (int)coap_pkt->proxy_uri_len, + coap_pkt->proxy_uri); + coap_error_message = "This is a constrained server (Contiki)"; + return PROXYING_NOT_SUPPORTED_5_05; + break; + case COAP_OPTION_PROXY_SCHEME: +#if COAP_PROXY_OPTION_PROCESSING + coap_pkt->proxy_scheme = (char *)current_option; + coap_pkt->proxy_scheme_len = option_length; +#endif + PRINTF("Proxy-Scheme NOT IMPLEMENTED [%.*s]\n", + (int)coap_pkt->proxy_scheme_len, coap_pkt->proxy_scheme); + coap_error_message = "This is a constrained server (Contiki)"; + return PROXYING_NOT_SUPPORTED_5_05; + break; + + case COAP_OPTION_URI_HOST: + coap_pkt->uri_host = (char *)current_option; + coap_pkt->uri_host_len = option_length; + PRINTF("Uri-Host [%.*s]\n", (int)coap_pkt->uri_host_len, + coap_pkt->uri_host); + break; + case COAP_OPTION_URI_PORT: + coap_pkt->uri_port = coap_parse_int_option(current_option, + option_length); + PRINTF("Uri-Port [%u]\n", coap_pkt->uri_port); + break; + case COAP_OPTION_URI_PATH: + /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ + coap_merge_multi_option((char **)&(coap_pkt->uri_path), + &(coap_pkt->uri_path_len), current_option, + option_length, '/'); + PRINTF("Uri-Path [%.*s]\n", (int)coap_pkt->uri_path_len, coap_pkt->uri_path); + break; + case COAP_OPTION_URI_QUERY: + /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ + coap_merge_multi_option((char **)&(coap_pkt->uri_query), + &(coap_pkt->uri_query_len), current_option, + option_length, '&'); + PRINTF("Uri-Query [%.*s]\n", (int)coap_pkt->uri_query_len, + coap_pkt->uri_query); + break; + + case COAP_OPTION_LOCATION_PATH: + /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ + coap_merge_multi_option((char **)&(coap_pkt->location_path), + &(coap_pkt->location_path_len), current_option, + option_length, '/'); + PRINTF("Location-Path [%.*s]\n", (int)coap_pkt->location_path_len, + coap_pkt->location_path); + break; + case COAP_OPTION_LOCATION_QUERY: + /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ + coap_merge_multi_option((char **)&(coap_pkt->location_query), + &(coap_pkt->location_query_len), current_option, + option_length, '&'); + PRINTF("Location-Query [%.*s]\n", (int)coap_pkt->location_query_len, + coap_pkt->location_query); + break; + + case COAP_OPTION_OBSERVE: + coap_pkt->observe = coap_parse_int_option(current_option, + option_length); + PRINTF("Observe [%lu]\n", (unsigned long)coap_pkt->observe); + break; + case COAP_OPTION_BLOCK2: + coap_pkt->block2_num = coap_parse_int_option(current_option, + option_length); + coap_pkt->block2_more = (coap_pkt->block2_num & 0x08) >> 3; + coap_pkt->block2_size = 16 << (coap_pkt->block2_num & 0x07); + coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F) + << (coap_pkt->block2_num & 0x07); + coap_pkt->block2_num >>= 4; + PRINTF("Block2 [%lu%s (%u B/blk)]\n", + (unsigned long)coap_pkt->block2_num, + coap_pkt->block2_more ? "+" : "", coap_pkt->block2_size); + break; + case COAP_OPTION_BLOCK1: + coap_pkt->block1_num = coap_parse_int_option(current_option, + option_length); + coap_pkt->block1_more = (coap_pkt->block1_num & 0x08) >> 3; + coap_pkt->block1_size = 16 << (coap_pkt->block1_num & 0x07); + coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F) + << (coap_pkt->block1_num & 0x07); + coap_pkt->block1_num >>= 4; + PRINTF("Block1 [%lu%s (%u B/blk)]\n", + (unsigned long)coap_pkt->block1_num, + coap_pkt->block1_more ? "+" : "", coap_pkt->block1_size); + break; + case COAP_OPTION_SIZE2: + coap_pkt->size2 = coap_parse_int_option(current_option, option_length); + PRINTF("Size2 [%lu]\n", (unsigned long)coap_pkt->size2); + break; + case COAP_OPTION_SIZE1: + coap_pkt->size1 = coap_parse_int_option(current_option, option_length); + PRINTF("Size1 [%lu]\n", (unsigned long)coap_pkt->size1); + break; + default: + PRINTF("unknown (%u)\n", option_number); + /* check if critical (odd) */ + if(option_number & 1) { + coap_error_message = "Unsupported critical option"; + return BAD_OPTION_4_02; + } + } + + current_option += option_length; + } /* for */ + PRINTF("-Done parsing-------\n"); + + return NO_ERROR; +} +/*---------------------------------------------------------------------------*/ +/*- REST Engine API ---------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +int +coap_get_query_variable(void *packet, const char *name, const char **output) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) { + return coap_get_variable(coap_pkt->uri_query, coap_pkt->uri_query_len, + name, output); + } + return 0; +} +int +coap_get_post_variable(void *packet, const char *name, const char **output) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(coap_pkt->payload_len) { + return coap_get_variable((const char *)coap_pkt->payload, + coap_pkt->payload_len, name, output); + } + return 0; +} +/*---------------------------------------------------------------------------*/ +int +coap_set_status_code(void *packet, unsigned int code) +{ + if(code <= 0xFF) { + ((coap_packet_t *)packet)->code = (uint8_t)code; + return 1; + } else { + return 0; + } +} +/*---------------------------------------------------------------------------*/ +int +coap_set_token(void *packet, const uint8_t *token, size_t token_len) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + coap_pkt->token_len = MIN(COAP_TOKEN_LEN, token_len); + memcpy(coap_pkt->token, token, coap_pkt->token_len); + + return coap_pkt->token_len; +} +/*---------------------------------------------------------------------------*/ +/*- CoAP REST Implementation API --------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +int +coap_get_header_content_format(void *packet, unsigned int *format) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(!IS_OPTION(coap_pkt, COAP_OPTION_CONTENT_FORMAT)) { + return 0; + } + *format = coap_pkt->content_format; + return 1; +} +int +coap_set_header_content_format(void *packet, unsigned int format) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + coap_pkt->content_format = format; + SET_OPTION(coap_pkt, COAP_OPTION_CONTENT_FORMAT); + return 1; +} +/*---------------------------------------------------------------------------*/ +int +coap_get_header_accept(void *packet, unsigned int *accept) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(!IS_OPTION(coap_pkt, COAP_OPTION_ACCEPT)) { + return 0; + } + *accept = coap_pkt->accept; + return 1; +} +int +coap_set_header_accept(void *packet, unsigned int accept) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + coap_pkt->accept = accept; + SET_OPTION(coap_pkt, COAP_OPTION_ACCEPT); + return 1; +} +/*---------------------------------------------------------------------------*/ +int +coap_get_header_max_age(void *packet, uint32_t *age) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(!IS_OPTION(coap_pkt, COAP_OPTION_MAX_AGE)) { + *age = COAP_DEFAULT_MAX_AGE; + } else { + *age = coap_pkt->max_age; + } return 1; +} +int +coap_set_header_max_age(void *packet, uint32_t age) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + coap_pkt->max_age = age; + SET_OPTION(coap_pkt, COAP_OPTION_MAX_AGE); + return 1; +} +/*---------------------------------------------------------------------------*/ +int +coap_get_header_etag(void *packet, const uint8_t **etag) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(!IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) { + return 0; + } + *etag = coap_pkt->etag; + return coap_pkt->etag_len; +} +int +coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + coap_pkt->etag_len = MIN(COAP_ETAG_LEN, etag_len); + memcpy(coap_pkt->etag, etag, coap_pkt->etag_len); + + SET_OPTION(coap_pkt, COAP_OPTION_ETAG); + return coap_pkt->etag_len; +} +/*---------------------------------------------------------------------------*/ +/*FIXME support multiple ETags */ +int +coap_get_header_if_match(void *packet, const uint8_t **etag) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(!IS_OPTION(coap_pkt, COAP_OPTION_IF_MATCH)) { + return 0; + } + *etag = coap_pkt->if_match; + return coap_pkt->if_match_len; +} +int +coap_set_header_if_match(void *packet, const uint8_t *etag, size_t etag_len) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, etag_len); + memcpy(coap_pkt->if_match, etag, coap_pkt->if_match_len); + + SET_OPTION(coap_pkt, COAP_OPTION_IF_MATCH); + return coap_pkt->if_match_len; +} +/*---------------------------------------------------------------------------*/ +int +coap_get_header_if_none_match(void *packet) +{ + return IS_OPTION((coap_packet_t *)packet, + COAP_OPTION_IF_NONE_MATCH) ? 1 : 0; +} +int +coap_set_header_if_none_match(void *packet) +{ + SET_OPTION((coap_packet_t *)packet, COAP_OPTION_IF_NONE_MATCH); + return 1; +} +/*---------------------------------------------------------------------------*/ +int +coap_get_header_proxy_uri(void *packet, const char **uri) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(!IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI)) { + return 0; + } + *uri = coap_pkt->proxy_uri; + return coap_pkt->proxy_uri_len; +} +int +coap_set_header_proxy_uri(void *packet, const char *uri) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + /*TODO Provide alternative that sets Proxy-Scheme and Uri-* options and provide er-coap-conf define */ + + coap_pkt->proxy_uri = uri; + coap_pkt->proxy_uri_len = strlen(uri); + + SET_OPTION(coap_pkt, COAP_OPTION_PROXY_URI); + return coap_pkt->proxy_uri_len; +} +/*---------------------------------------------------------------------------*/ +int +coap_get_header_uri_host(void *packet, const char **host) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_HOST)) { + return 0; + } + *host = coap_pkt->uri_host; + return coap_pkt->uri_host_len; +} +int +coap_set_header_uri_host(void *packet, const char *host) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + coap_pkt->uri_host = host; + coap_pkt->uri_host_len = strlen(host); + + SET_OPTION(coap_pkt, COAP_OPTION_URI_HOST); + return coap_pkt->uri_host_len; +} +/*---------------------------------------------------------------------------*/ +int +coap_get_header_uri_path(void *packet, const char **path) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_PATH)) { + return 0; + } + *path = coap_pkt->uri_path; + return coap_pkt->uri_path_len; +} +int +coap_set_header_uri_path(void *packet, const char *path) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + while(path[0] == '/') + ++path; + + coap_pkt->uri_path = path; + coap_pkt->uri_path_len = strlen(path); + + SET_OPTION(coap_pkt, COAP_OPTION_URI_PATH); + return coap_pkt->uri_path_len; +} +/*---------------------------------------------------------------------------*/ +int +coap_get_header_uri_query(void *packet, const char **query) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) { + return 0; + } + *query = coap_pkt->uri_query; + return coap_pkt->uri_query_len; +} +int +coap_set_header_uri_query(void *packet, const char *query) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + while(query[0] == '?') + ++query; + + coap_pkt->uri_query = query; + coap_pkt->uri_query_len = strlen(query); + + SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); + return coap_pkt->uri_query_len; +} +/*---------------------------------------------------------------------------*/ +int +coap_get_header_location_path(void *packet, const char **path) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH)) { + return 0; + } + *path = coap_pkt->location_path; + return coap_pkt->location_path_len; +} +int +coap_set_header_location_path(void *packet, const char *path) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + char *query; + + while(path[0] == '/') + ++path; + + if((query = strchr(path, '?'))) { + coap_set_header_location_query(packet, query + 1); + coap_pkt->location_path_len = query - path; + } else { + coap_pkt->location_path_len = strlen(path); + } coap_pkt->location_path = path; + + if(coap_pkt->location_path_len > 0) { + SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH); + } + return coap_pkt->location_path_len; +} +/*---------------------------------------------------------------------------*/ +int +coap_get_header_location_query(void *packet, const char **query) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY)) { + return 0; + } + *query = coap_pkt->location_query; + return coap_pkt->location_query_len; +} +int +coap_set_header_location_query(void *packet, const char *query) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + while(query[0] == '?') + ++query; + + coap_pkt->location_query = query; + coap_pkt->location_query_len = strlen(query); + + SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY); + return coap_pkt->location_query_len; +} +/*---------------------------------------------------------------------------*/ +int +coap_get_header_observe(void *packet, uint32_t *observe) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(!IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) { + return 0; + } + *observe = coap_pkt->observe; + return 1; +} +int +coap_set_header_observe(void *packet, uint32_t observe) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + coap_pkt->observe = observe; + SET_OPTION(coap_pkt, COAP_OPTION_OBSERVE); + return 1; +} +/*---------------------------------------------------------------------------*/ +int +coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more, + uint16_t *size, uint32_t *offset) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK2)) { + return 0; + } + /* pointers may be NULL to get only specific block parameters */ + if(num != NULL) { + *num = coap_pkt->block2_num; + } + if(more != NULL) { + *more = coap_pkt->block2_more; + } + if(size != NULL) { + *size = coap_pkt->block2_size; + } + if(offset != NULL) { + *offset = coap_pkt->block2_offset; + } + return 1; +} +int +coap_set_header_block2(void *packet, uint32_t num, uint8_t more, + uint16_t size) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(size < 16) { + return 0; + } + if(size > 2048) { + return 0; + } + if(num > 0x0FFFFF) { + return 0; + } + coap_pkt->block2_num = num; + coap_pkt->block2_more = more ? 1 : 0; + coap_pkt->block2_size = size; + + SET_OPTION(coap_pkt, COAP_OPTION_BLOCK2); + return 1; +} +/*---------------------------------------------------------------------------*/ +int +coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more, + uint16_t *size, uint32_t *offset) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK1)) { + return 0; + } + /* pointers may be NULL to get only specific block parameters */ + if(num != NULL) { + *num = coap_pkt->block1_num; + } + if(more != NULL) { + *more = coap_pkt->block1_more; + } + if(size != NULL) { + *size = coap_pkt->block1_size; + } + if(offset != NULL) { + *offset = coap_pkt->block1_offset; + } + return 1; +} +int +coap_set_header_block1(void *packet, uint32_t num, uint8_t more, + uint16_t size) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(size < 16) { + return 0; + } + if(size > 2048) { + return 0; + } + if(num > 0x0FFFFF) { + return 0; + } + coap_pkt->block1_num = num; + coap_pkt->block1_more = more; + coap_pkt->block1_size = size; + + SET_OPTION(coap_pkt, COAP_OPTION_BLOCK1); + return 1; +} +/*---------------------------------------------------------------------------*/ +int +coap_get_header_size2(void *packet, uint32_t *size) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(!IS_OPTION(coap_pkt, COAP_OPTION_SIZE2)) { + return 0; + } + *size = coap_pkt->size2; + return 1; +} +int +coap_set_header_size2(void *packet, uint32_t size) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + coap_pkt->size2 = size; + SET_OPTION(coap_pkt, COAP_OPTION_SIZE2); + return 1; +} +/*---------------------------------------------------------------------------*/ +int +coap_get_header_size1(void *packet, uint32_t *size) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(!IS_OPTION(coap_pkt, COAP_OPTION_SIZE1)) { + return 0; + } + *size = coap_pkt->size1; + return 1; +} +int +coap_set_header_size1(void *packet, uint32_t size) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + coap_pkt->size1 = size; + SET_OPTION(coap_pkt, COAP_OPTION_SIZE1); + return 1; +} +/*---------------------------------------------------------------------------*/ +int +coap_get_payload(void *packet, const uint8_t **payload) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + if(coap_pkt->payload) { + *payload = coap_pkt->payload; + return coap_pkt->payload_len; + } else { + *payload = NULL; + return 0; + } +} +int +coap_set_payload(void *packet, const void *payload, size_t length) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *)packet; + + coap_pkt->payload = (uint8_t *)payload; + coap_pkt->payload_len = MIN(REST_MAX_CHUNK_SIZE, length); + + return coap_pkt->payload_len; +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/er-coap/er-coap.h b/apps/er-coap/er-coap.h new file mode 100644 index 000000000..ccac6d76e --- /dev/null +++ b/apps/er-coap/er-coap.h @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * An implementation of the Constrained Application Protocol (RFC). + * \author + * Matthias Kovatsch + */ + +#ifndef ER_COAP_H_ +#define ER_COAP_H_ + +#include /* for size_t */ +#include "contiki-net.h" +#include "er-coap-constants.h" +#include "er-coap-conf.h" + +/* sanity check for configured values */ +#define COAP_MAX_PACKET_SIZE (COAP_MAX_HEADER_SIZE + REST_MAX_CHUNK_SIZE) +#if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_IPH_LEN - UIP_UDPH_LEN) +#error "UIP_CONF_BUFFER_SIZE too small for REST_MAX_CHUNK_SIZE" +#endif + +/* use Erbium CoAP for the REST Engine. Must come before include of rest-engine.h. */ +#define REST coap_rest_implementation +#include "rest-engine.h" + +/* REST_MAX_CHUNK_SIZE can be different from 2^x so we need to get next lower 2^x for COAP_MAX_BLOCK_SIZE */ +#ifndef COAP_MAX_BLOCK_SIZE +#define COAP_MAX_BLOCK_SIZE (REST_MAX_CHUNK_SIZE < 32 ? 16 : \ + (REST_MAX_CHUNK_SIZE < 64 ? 32 : \ + (REST_MAX_CHUNK_SIZE < 128 ? 64 : \ + (REST_MAX_CHUNK_SIZE < 256 ? 128 : \ + (REST_MAX_CHUNK_SIZE < 512 ? 256 : \ + (REST_MAX_CHUNK_SIZE < 1024 ? 512 : \ + (REST_MAX_CHUNK_SIZE < 2048 ? 1024 : 2048))))))) +#endif /* COAP_MAX_BLOCK_SIZE */ + +/* direct access into the buffer */ +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) +#if NETSTACK_CONF_WITH_IPV6 +#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) +#else +#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN]) +#endif + +/* bitmap for set options */ +enum { OPTION_MAP_SIZE = sizeof(uint8_t) * 8 }; + +#define SET_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] |= 1 << (opt % OPTION_MAP_SIZE)) +#define IS_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] & (1 << (opt % OPTION_MAP_SIZE))) + +/* parsed message struct */ +typedef struct { + uint8_t *buffer; /* pointer to CoAP header / incoming packet buffer / memory to serialize packet */ + + uint8_t version; + coap_message_type_t type; + uint8_t code; + uint16_t mid; + + uint8_t token_len; + uint8_t token[COAP_TOKEN_LEN]; + + uint8_t options[COAP_OPTION_SIZE1 / OPTION_MAP_SIZE + 1]; /* bitmap to check if option is set */ + + uint16_t content_format; /* parse options once and store; allows setting options in random order */ + uint32_t max_age; + uint8_t etag_len; + uint8_t etag[COAP_ETAG_LEN]; + size_t proxy_uri_len; + const char *proxy_uri; + size_t proxy_scheme_len; + const char *proxy_scheme; + size_t uri_host_len; + const char *uri_host; + size_t location_path_len; + const char *location_path; + uint16_t uri_port; + size_t location_query_len; + const char *location_query; + size_t uri_path_len; + const char *uri_path; + int32_t observe; + uint16_t accept; + uint8_t if_match_len; + uint8_t if_match[COAP_ETAG_LEN]; + uint32_t block2_num; + uint8_t block2_more; + uint16_t block2_size; + uint32_t block2_offset; + uint32_t block1_num; + uint8_t block1_more; + uint16_t block1_size; + uint32_t block1_offset; + uint32_t size2; + uint32_t size1; + size_t uri_query_len; + const char *uri_query; + uint8_t if_none_match; + + uint16_t payload_len; + uint8_t *payload; +} coap_packet_t; + +/* option format serialization */ +#define COAP_SERIALIZE_INT_OPTION(number, field, text) \ + if(IS_OPTION(coap_pkt, number)) { \ + PRINTF(text " [%u]\n", (unsigned int)coap_pkt->field); \ + option += coap_serialize_int_option(number, current_number, option, coap_pkt->field); \ + current_number = number; \ + } +#define COAP_SERIALIZE_BYTE_OPTION(number, field, text) \ + if(IS_OPTION(coap_pkt, number)) { \ + PRINTF(text " %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", (unsigned int)coap_pkt->field##_len, \ + coap_pkt->field[0], \ + coap_pkt->field[1], \ + coap_pkt->field[2], \ + coap_pkt->field[3], \ + coap_pkt->field[4], \ + coap_pkt->field[5], \ + coap_pkt->field[6], \ + coap_pkt->field[7] \ + ); /* FIXME always prints 8 bytes */ \ + option += coap_serialize_array_option(number, current_number, option, coap_pkt->field, coap_pkt->field##_len, '\0'); \ + current_number = number; \ + } +#define COAP_SERIALIZE_STRING_OPTION(number, field, splitter, text) \ + if(IS_OPTION(coap_pkt, number)) { \ + PRINTF(text " [%.*s]\n", (int)coap_pkt->field##_len, coap_pkt->field); \ + option += coap_serialize_array_option(number, current_number, option, (uint8_t *)coap_pkt->field, coap_pkt->field##_len, splitter); \ + current_number = number; \ + } +#define COAP_SERIALIZE_BLOCK_OPTION(number, field, text) \ + if(IS_OPTION(coap_pkt, number)) \ + { \ + PRINTF(text " [%lu%s (%u B/blk)]\n", (unsigned long)coap_pkt->field##_num, coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size); \ + uint32_t block = coap_pkt->field##_num << 4; \ + if(coap_pkt->field##_more) { block |= 0x8; } \ + block |= 0xF & coap_log_2(coap_pkt->field##_size / 16); \ + PRINTF(text " encoded: 0x%lX\n", (unsigned long)block); \ + option += coap_serialize_int_option(number, current_number, option, block); \ + current_number = number; \ + } + +/* to store error code and human-readable payload */ +extern coap_status_t erbium_status_code; +extern char *coap_error_message; + +void coap_init_connection(uint16_t port); +uint16_t coap_get_mid(void); + +void coap_init_message(void *packet, coap_message_type_t type, uint8_t code, + uint16_t mid); +size_t coap_serialize_message(void *packet, uint8_t *buffer); +void coap_send_message(uip_ipaddr_t *addr, uint16_t port, uint8_t *data, + uint16_t length); +coap_status_t coap_parse_message(void *request, uint8_t *data, + uint16_t data_len); + +int coap_get_query_variable(void *packet, const char *name, + const char **output); +int coap_get_post_variable(void *packet, const char *name, + const char **output); + +/*---------------------------------------------------------------------------*/ + +int coap_set_status_code(void *packet, unsigned int code); + +int coap_set_token(void *packet, const uint8_t *token, size_t token_len); + +int coap_get_header_content_format(void *packet, unsigned int *format); +int coap_set_header_content_format(void *packet, unsigned int format); + +int coap_get_header_accept(void *packet, unsigned int *accept); +int coap_set_header_accept(void *packet, unsigned int accept); + +int coap_get_header_max_age(void *packet, uint32_t *age); +int coap_set_header_max_age(void *packet, uint32_t age); + +int coap_get_header_etag(void *packet, const uint8_t **etag); +int coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len); + +int coap_get_header_if_match(void *packet, const uint8_t **etag); +int coap_set_header_if_match(void *packet, const uint8_t *etag, + size_t etag_len); + +int coap_get_header_if_none_match(void *packet); +int coap_set_header_if_none_match(void *packet); + +int coap_get_header_proxy_uri(void *packet, const char **uri); /* in-place string might not be 0-terminated. */ +int coap_set_header_proxy_uri(void *packet, const char *uri); + +int coap_get_header_proxy_scheme(void *packet, const char **scheme); /* in-place string might not be 0-terminated. */ +int coap_set_header_proxy_scheme(void *packet, const char *scheme); + +int coap_get_header_uri_host(void *packet, const char **host); /* in-place string might not be 0-terminated. */ +int coap_set_header_uri_host(void *packet, const char *host); + +int coap_get_header_uri_path(void *packet, const char **path); /* in-place string might not be 0-terminated. */ +int coap_set_header_uri_path(void *packet, const char *path); + +int coap_get_header_uri_query(void *packet, const char **query); /* in-place string might not be 0-terminated. */ +int coap_set_header_uri_query(void *packet, const char *query); + +int coap_get_header_location_path(void *packet, const char **path); /* in-place string might not be 0-terminated. */ +int coap_set_header_location_path(void *packet, const char *path); /* also splits optional query into Location-Query option. */ + +int coap_get_header_location_query(void *packet, const char **query); /* in-place string might not be 0-terminated. */ +int coap_set_header_location_query(void *packet, const char *query); + +int coap_get_header_observe(void *packet, uint32_t *observe); +int coap_set_header_observe(void *packet, uint32_t observe); + +int coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more, + uint16_t *size, uint32_t *offset); +int coap_set_header_block2(void *packet, uint32_t num, uint8_t more, + uint16_t size); + +int coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more, + uint16_t *size, uint32_t *offset); +int coap_set_header_block1(void *packet, uint32_t num, uint8_t more, + uint16_t size); + +int coap_get_header_size2(void *packet, uint32_t *size); +int coap_set_header_size2(void *packet, uint32_t size); + +int coap_get_header_size1(void *packet, uint32_t *size); +int coap_set_header_size1(void *packet, uint32_t size); + +int coap_get_payload(void *packet, const uint8_t **payload); +int coap_set_payload(void *packet, const void *payload, size_t length); + +#endif /* ER_COAP_H_ */ diff --git a/apps/erbium/Makefile.erbium b/apps/erbium/Makefile.erbium deleted file mode 100644 index 4785008e1..000000000 --- a/apps/erbium/Makefile.erbium +++ /dev/null @@ -1 +0,0 @@ -erbium_src = erbium.c diff --git a/apps/erbium/erbium.c b/apps/erbium/erbium.c deleted file mode 100644 index f624dd594..000000000 --- a/apps/erbium/erbium.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * An abstraction layer for RESTful Web services - * \author - * Matthias Kovatsch - */ - -#include "contiki.h" -#include /*for string operations in match_addresses*/ -#include /*for sprintf in rest_set_header_**/ - -#include "erbium.h" - -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - -PROCESS_NAME(rest_manager_process); - -LIST(restful_services); -LIST(restful_periodic_services); - - -void -rest_init_engine(void) -{ - list_init(restful_services); - - REST.set_service_callback(rest_invoke_restful_service); - - /* Start the RESTful server implementation. */ - REST.init(); - - /*Start rest manager process*/ - process_start(&rest_manager_process, NULL); -} - -void -rest_activate_resource(resource_t* resource) -{ - PRINTF("Activating: %s", resource->url); - - if (!resource->pre_handler) - { - rest_set_pre_handler(resource, REST.default_pre_handler); - } - if (!resource->post_handler) - { - rest_set_post_handler(resource, REST.default_post_handler); - } - - list_add(restful_services, resource); -} - -void -rest_activate_periodic_resource(periodic_resource_t* periodic_resource) -{ - list_add(restful_periodic_services, periodic_resource); - rest_activate_resource(periodic_resource->resource); - - rest_set_post_handler(periodic_resource->resource, REST.subscription_handler); -} - -void -rest_activate_event_resource(resource_t* resource) -{ - rest_activate_resource(resource); - rest_set_post_handler(resource, REST.subscription_handler); -} - -list_t -rest_get_resources(void) -{ - return restful_services; -} - - -void* -rest_get_user_data(resource_t* resource) -{ - return resource->user_data; -} - -void -rest_set_user_data(resource_t* resource, void* user_data) -{ - resource->user_data = user_data; -} - -void -rest_set_pre_handler(resource_t* resource, restful_pre_handler pre_handler) -{ - resource->pre_handler = pre_handler; -} - -void -rest_set_post_handler(resource_t* resource, restful_post_handler post_handler) -{ - resource->post_handler = post_handler; -} - -void -rest_set_special_flags(resource_t* resource, rest_resource_flags_t flags) -{ - resource->flags |= flags; -} - -int -rest_invoke_restful_service(void* request, void* response, uint8_t *buffer, uint16_t buffer_size, int32_t *offset) -{ - uint8_t found = 0; - uint8_t allowed = 0; - - PRINTF("rest_invoke_restful_service url /%.*s -->\n", url_len, url); - - resource_t* resource = NULL; - const char *url = NULL; - - for (resource = (resource_t*)list_head(restful_services); resource; resource = resource->next) - { - /*if the web service handles that kind of requests and urls matches*/ - if ((REST.get_url(request, &url)==strlen(resource->url) || (REST.get_url(request, &url)>strlen(resource->url) && (resource->flags & HAS_SUB_RESOURCES))) - && strncmp(resource->url, url, strlen(resource->url)) == 0) - { - found = 1; - rest_resource_flags_t method = REST.get_method_type(request); - - PRINTF("method %u, resource->flags %u\n", (uint16_t)method, resource->flags); - - if (resource->flags & method) - { - allowed = 1; - - /*call pre handler if it exists*/ - if (!resource->pre_handler || resource->pre_handler(resource, request, response)) - { - /* call handler function*/ - resource->handler(request, response, buffer, buffer_size, offset); - - /*call post handler if it exists*/ - if (resource->post_handler) - { - resource->post_handler(resource, request, response); - } - } - } else { - REST.set_response_status(response, REST.status.METHOD_NOT_ALLOWED); - } - break; - } - } - - if (!found) { - REST.set_response_status(response, REST.status.NOT_FOUND); - } - - return found & allowed; -} -/*-----------------------------------------------------------------------------------*/ - -PROCESS(rest_manager_process, "Rest Process"); - -PROCESS_THREAD(rest_manager_process, ev, data) -{ - PROCESS_BEGIN(); - - PROCESS_PAUSE(); - - /* Initialize the PERIODIC_RESOURCE timers, which will be handled by this process. */ - periodic_resource_t* periodic_resource = NULL; - for (periodic_resource = (periodic_resource_t*) list_head(restful_periodic_services); periodic_resource; periodic_resource = periodic_resource->next) { - if (periodic_resource->period) { - PRINTF("Periodic: Set timer for %s to %lu\n", periodic_resource->resource->url, periodic_resource->period); - etimer_set(&periodic_resource->periodic_timer, periodic_resource->period); - } - } - - while (1) { - PROCESS_WAIT_EVENT(); - if (ev == PROCESS_EVENT_TIMER) { - for (periodic_resource = (periodic_resource_t*)list_head(restful_periodic_services);periodic_resource;periodic_resource = periodic_resource->next) { - if (periodic_resource->period && etimer_expired(&periodic_resource->periodic_timer)) { - - PRINTF("Periodic: etimer expired for /%s (period: %lu)\n", periodic_resource->resource->url, periodic_resource->period); - - /* Call the periodic_handler function if it exists. */ - if (periodic_resource->periodic_handler) { - (periodic_resource->periodic_handler)(periodic_resource->resource); - } - etimer_reset(&periodic_resource->periodic_timer); - } - } - } - } - - PROCESS_END(); -} - diff --git a/apps/erbium/erbium.h b/apps/erbium/erbium.h deleted file mode 100644 index 0fecd960d..000000000 --- a/apps/erbium/erbium.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * An abstraction layer for RESTful Web services - * \author - * Matthias Kovatsch - */ - -#ifndef ERBIUM_H_ -#define ERBIUM_H_ - -/*includes*/ -#include -#include "contiki.h" -#include "contiki-lib.h" - -/* - * The maximum buffer size that is provided for resource responses and must be respected due to the limited IP buffer. - * Larger data must be handled by the resource and will be sent chunk-wise through a TCP stream or CoAP blocks. - */ -#ifndef REST_MAX_CHUNK_SIZE -#define REST_MAX_CHUNK_SIZE 128 -#endif - -#ifndef MIN -#define MIN(a, b) ((a) < (b)? (a) : (b)) -#endif /* MIN */ - -/* REST method types */ -typedef enum { - /* methods to handle */ - METHOD_GET = (1 << 0), - METHOD_POST = (1 << 1), - METHOD_PUT = (1 << 2), - METHOD_DELETE = (1 << 3), - - /* special flags */ - HAS_SUB_RESOURCES = (1<<7) -} rest_resource_flags_t; - -struct resource_s; -struct periodic_resource_s; - -/* Signatures of handler functions. */ -typedef void (*restful_handler) (void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); -typedef int (*restful_pre_handler) (struct resource_s *resource, void* request, void* response); -typedef void (*restful_post_handler) (struct resource_s *resource, void* request, void* response); -typedef void (*restful_periodic_handler) (struct resource_s* resource); -typedef void (*restful_response_handler) (void *data, void* response); - -/* Signature of the rest-engine service function. */ -typedef int (* service_callback_t)(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); - -/** - * The structure of a MAC protocol driver in Contiki. - */ -struct rest_implementation_status -{ - const unsigned int OK; /* CONTENT_2_05, OK_200 */ - const unsigned int CREATED; /* CREATED_2_01, CREATED_201 */ - const unsigned int CHANGED; /* CHANGED_2_04, NO_CONTENT_204 */ - const unsigned int DELETED; /* DELETED_2_02, NO_CONTENT_204 */ - const unsigned int NOT_MODIFIED; /* VALID_2_03, NOT_MODIFIED_304 */ - - const unsigned int BAD_REQUEST; /* BAD_REQUEST_4_00, BAD_REQUEST_400 */ - const unsigned int UNAUTHORIZED; /* UNAUTHORIZED_4_01, UNAUTHORIZED_401 */ - const unsigned int BAD_OPTION; /* BAD_OPTION_4_02, BAD_REQUEST_400 */ - const unsigned int FORBIDDEN; /* FORBIDDEN_4_03, FORBIDDEN_403 */ - const unsigned int NOT_FOUND; /* NOT_FOUND_4_04, NOT_FOUND_404 */ - const unsigned int METHOD_NOT_ALLOWED; /* METHOD_NOT_ALLOWED_4_05, METHOD_NOT_ALLOWED_405 */ - const unsigned int NOT_ACCEPTABLE; /* NOT_ACCEPTABLE_4_06, NOT_ACCEPTABLE_406 */ - const unsigned int REQUEST_ENTITY_TOO_LARGE; /* REQUEST_ENTITY_TOO_LARGE_4_13, REQUEST_ENTITY_TOO_LARGE_413 */ - const unsigned int UNSUPPORTED_MEDIA_TYPE; /* UNSUPPORTED_MEDIA_TYPE_4_15, UNSUPPORTED_MEDIA_TYPE_415 */ - - const unsigned int INTERNAL_SERVER_ERROR; /* INTERNAL_SERVER_ERROR_5_00, INTERNAL_SERVER_ERROR_500 */ - const unsigned int NOT_IMPLEMENTED; /* NOT_IMPLEMENTED_5_01, NOT_IMPLEMENTED_501 */ - const unsigned int BAD_GATEWAY; /* BAD_GATEWAY_5_02, BAD_GATEWAY_502 */ - const unsigned int SERVICE_UNAVAILABLE; /* SERVICE_UNAVAILABLE_5_03, SERVICE_UNAVAILABLE_503 */ - const unsigned int GATEWAY_TIMEOUT; /* GATEWAY_TIMEOUT_5_04, GATEWAY_TIMEOUT_504 */ - const unsigned int PROXYING_NOT_SUPPORTED; /* PROXYING_NOT_SUPPORTED_5_05, INTERNAL_SERVER_ERROR_500 */ -}; -struct rest_implementation_type -{ - unsigned int TEXT_PLAIN; - unsigned int TEXT_XML; - unsigned int TEXT_CSV; - unsigned int TEXT_HTML; - unsigned int IMAGE_GIF; - unsigned int IMAGE_JPEG; - unsigned int IMAGE_PNG; - unsigned int IMAGE_TIFF; - unsigned int AUDIO_RAW; - unsigned int VIDEO_RAW; - unsigned int APPLICATION_LINK_FORMAT; - unsigned int APPLICATION_XML; - unsigned int APPLICATION_OCTET_STREAM; - unsigned int APPLICATION_RDF_XML; - unsigned int APPLICATION_SOAP_XML; - unsigned int APPLICATION_ATOM_XML; - unsigned int APPLICATION_XMPP_XML; - unsigned int APPLICATION_EXI; - unsigned int APPLICATION_FASTINFOSET; - unsigned int APPLICATION_SOAP_FASTINFOSET; - unsigned int APPLICATION_JSON; - unsigned int APPLICATION_X_OBIX_BINARY; -}; - -/* - * Data structure representing a resource in REST. - */ -struct resource_s { - struct resource_s *next; /* for LIST, points to next resource defined */ - rest_resource_flags_t flags; /* handled RESTful methods */ - const char* url; /*handled URL*/ - const char* attributes; /* link-format attributes */ - restful_handler handler; /* handler function */ - restful_pre_handler pre_handler; /* to be called before handler, may perform initializations */ - restful_post_handler post_handler; /* to be called after handler, may perform finalizations (cleanup, etc) */ - void* user_data; /* pointer to user specific data */ - unsigned int benchmark; /* to benchmark resource handler, used for separate response */ -}; -typedef struct resource_s resource_t; - -struct periodic_resource_s { - struct periodic_resource_s *next; /* for LIST, points to next resource defined */ - resource_t *resource; - uint32_t period; - struct etimer periodic_timer; - restful_periodic_handler periodic_handler; -}; -typedef struct periodic_resource_s periodic_resource_t; - -struct rest_implementation { - char *name; - - /** Initialize the REST implementation. */ - void (* init)(void); - - /** Register the RESTful service callback at implementation */ - void (* set_service_callback)(service_callback_t callback); - - /** Get request URI path */ - int (* get_url)(void *request, const char **url); - - int (* set_url)(void *request, const char *url); - - /** Get the method of a request. */ - rest_resource_flags_t (* get_method_type)(void *request); - - /** Set the status code of a response. */ - int (* set_response_status)(void *response, unsigned int code); - - /** Get the content-type of a request. */ - unsigned int (* get_header_content_type)(void *request); - - /** Set the Content-Type of a response. */ - int (* set_header_content_type)(void *response, unsigned int content_type); - - /** Get the Accept types of a request. */ - int (* get_header_accept)(void *request, const uint16_t **accept); - - /** Get the Length option of a request. */ - int (* get_header_length)(void *request, uint32_t *size); - - /** Set the Length option of a response. */ - int (* set_header_length)(void *response, uint32_t size); - - /** Get the Max-Age option of a request. */ - int (* get_header_max_age)(void *request, uint32_t *age); - - /** Set the Max-Age option of a response. */ - int (* set_header_max_age)(void *response, uint32_t age); - - /** Set the ETag option of a response. */ - int (* set_header_etag)(void *response, const uint8_t *etag, size_t length); - - /** Get the If-Match option of a request. */ - int (* get_header_if_match)(void *request, const uint8_t **etag); - - /** Get the If-Match option of a request. */ - int (* get_header_if_none_match)(void *request); - - /** Get the Host option of a request. */ - int (* get_header_host)(void *request, const char **host); - - /** Set the location option of a response. */ - int (* set_header_location)(void *response, const char *location); - - /** Get the payload option of a request. */ - int (* get_request_payload)(void *request, const uint8_t **payload); - - /** Set the payload option of a response. */ - int (* set_response_payload)(void *response, const void *payload, size_t length); - - /** Get the query string of a request. */ - int (* get_query)(void *request, const char **value); - - /** Get the value of a request query key-value pair. */ - int (* get_query_variable)(void *request, const char *name, const char **value); - - /** Get the value of a request POST key-value pair. */ - int (* get_post_variable)(void *request, const char *name, const char **value); - - /** Send the payload to all subscribers of the resource at url. */ - void (* notify_subscribers)(resource_t *resource, int32_t counter, void *notification); - - /** The handler for resource subscriptions. */ - restful_post_handler subscription_handler; - - /** A default pre-handler that is assigned with the RESOURCE macro. */ - restful_pre_handler default_pre_handler; - - /** A default post-handler that is assigned with the RESOURCE macro. */ - restful_post_handler default_post_handler; - - /* REST status codes. */ - const struct rest_implementation_status status; - - /* REST content-types. */ - const struct rest_implementation_type type; -}; - -/* - * Instance of REST implementation - */ -extern const struct rest_implementation REST; - -/* - * Macro to define a Resource - * Resources are statically defined for the sake of efficiency and better memory management. - */ -#define RESOURCE(name, flags, url, attributes) \ -void name##_handler(void *, void *, uint8_t *, uint16_t, int32_t *); \ -resource_t resource_##name = {NULL, flags, url, attributes, name##_handler, NULL, NULL, NULL} - -/* - * Macro to define a sub-resource - * Make sure to define its parent resource beforehand and set 'parent' to that name. - */ -#define SUB_RESOURCE(name, flags, url, attributes, parent) \ -resource_t resource_##name = {NULL, flags, url, attributes, parent##_handler, NULL, NULL, NULL} - -/* - * Macro to define an event resource - * Like periodic resources, event resources have a post_handler that manages a subscriber list. - * Instead of a periodic_handler, an event_callback must be provided. - */ -#define EVENT_RESOURCE(name, flags, url, attributes) \ -void name##_handler(void *, void *, uint8_t *, uint16_t, int32_t *); \ -void name##_event_handler(resource_t*); \ -resource_t resource_##name = {NULL, flags, url, attributes, name##_handler, NULL, NULL, NULL} - -/* - * Macro to define a periodic resource - * The corresponding [name]_periodic_handler() function will be called every period. - * For instance polling a sensor and publishing a changed value to subscribed clients would be done there. - * The subscriber list will be maintained by the post_handler rest_subscription_handler() (see rest-mapping header file). - */ -#define PERIODIC_RESOURCE(name, flags, url, attributes, period) \ -void name##_handler(void *, void *, uint8_t *, uint16_t, int32_t *); \ -resource_t resource_##name = {NULL, flags, url, attributes, name##_handler, NULL, NULL, NULL}; \ -void name##_periodic_handler(resource_t*); \ -periodic_resource_t periodic_resource_##name = {NULL, &resource_##name, period, {{0}}, name##_periodic_handler} - - -/* - * Initializes REST framework and starts HTTP or COAP process - */ -void rest_init_engine(void); - -/* - * Resources wanted to be accessible should be activated with the following code. - */ -void rest_activate_resource(resource_t* resource); -void rest_activate_periodic_resource(periodic_resource_t* periodic_resource); -void rest_activate_event_resource(resource_t* resource); - - -/* - * To be called by HTTP/COAP server as a callback function when a new service request appears. - * This function dispatches the corresponding RESTful service. - */ -int rest_invoke_restful_service(void* request, void* response, uint8_t *buffer, uint16_t buffer_size, int32_t *offset); - -/* - * Returns the resource list - */ -list_t rest_get_resources(void); - -/* - * Getter and setter methods for user specific data. - */ -void* rest_get_user_data(resource_t* resource); -void rest_set_user_data(resource_t* resource, void* user_data); - -/* - * Sets the pre handler function of the Resource. - * If set, this function will be called just before the original handler function. - * Can be used to setup work before resource handling. - */ -void rest_set_pre_handler(resource_t* resource, restful_pre_handler pre_handler); - -/* - * Sets the post handler function of the Resource. - * If set, this function will be called just after the original handler function. - * Can be used to do cleanup (deallocate memory, etc) after resource handling. - */ -void rest_set_post_handler(resource_t* resource, restful_post_handler post_handler); - -/* - * Sets resource flags for special properties, e.g., handling of sub-resources of URI-path. - */ -void rest_set_special_flags(resource_t* resource, rest_resource_flags_t flags); - -#endif /*ERBIUM_H_*/ diff --git a/apps/http-post-auth/http-post-auth.c b/apps/http-post-auth/http-post-auth.c index 71c493836..4bf0cdeae 100644 --- a/apps/http-post-auth/http-post-auth.c +++ b/apps/http-post-auth/http-post-auth.c @@ -162,7 +162,7 @@ http_post_auth(const uint8_t *username_password, const char *msg) PRINTF("message '%s'\n", s->message);*/ /* Spawn process to deal with TCP connection */ - process_start(&http_post_auth_process, (char *)s); + process_start(&http_post_auth_process, (void *)s); return 1; } /*---------------------------------------------------------------------------*/ diff --git a/apps/ipso-objects/Makefile.ipso-objects b/apps/ipso-objects/Makefile.ipso-objects new file mode 100644 index 000000000..8de44f196 --- /dev/null +++ b/apps/ipso-objects/Makefile.ipso-objects @@ -0,0 +1,3 @@ +ipso-objects_src = ipso-temperature.c ipso-button.c ipso-leds-control.c \ + ipso-light-control.c ipso-objects.c +CFLAGS += -DWITH_IPSO=1 diff --git a/apps/ipso-objects/ipso-button.c b/apps/ipso-objects/ipso-button.c new file mode 100644 index 000000000..f40410ea0 --- /dev/null +++ b/apps/ipso-objects/ipso-button.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup ipso-objects + * @{ + */ + +/** + * \file + * Implementation of OMA LWM2M / IPSO button as a digital input + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "contiki.h" +#include "lwm2m-object.h" +#include "lwm2m-engine.h" +#include "er-coap-engine.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#if PLATFORM_HAS_BUTTON +#include "dev/button-sensor.h" + +PROCESS(ipso_button_process, "ipso-button"); +#endif /* PLATFORM_HAS_BUTTON */ + +static int input_state = 0; +static int polarity = 0; +static int32_t counter = 0; +static int32_t edge_selection = 3; +static int32_t debounce_time = 10; +/*---------------------------------------------------------------------------*/ +static int +read_state(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + int value; + if(polarity == 0) { + value = input_state ? 1 : 0; + } else { + value = input_state ? 0 : 1; + } + PRINTF("Read button state (polarity=%d, state=%d): %d\n", + polarity, input_state, value); + return ctx->writer->write_boolean(ctx, outbuf, outsize, value); +} +/*---------------------------------------------------------------------------*/ +static int +reset_counter(lwm2m_context_t *ctx, const uint8_t *arg, size_t len, + uint8_t *outbuf, size_t outlen) +{ + counter = 0; + return 0; +} +/*---------------------------------------------------------------------------*/ +LWM2M_RESOURCES(button_resources, + LWM2M_RESOURCE_CALLBACK(5500, { read_state, NULL, NULL }), + LWM2M_RESOURCE_INTEGER_VAR(5501, &counter), + LWM2M_RESOURCE_BOOLEAN_VAR(5502, &polarity), + LWM2M_RESOURCE_INTEGER_VAR(5503, &debounce_time), + LWM2M_RESOURCE_INTEGER_VAR(5504, &edge_selection), + LWM2M_RESOURCE_CALLBACK(5505, { NULL, NULL, reset_counter }), + LWM2M_RESOURCE_STRING(5751, "Button") + ); +LWM2M_INSTANCES(button_instances, + LWM2M_INSTANCE(0, button_resources)); +LWM2M_OBJECT(button, 3200, button_instances); +/*---------------------------------------------------------------------------*/ +void +ipso_button_init(void) +{ + /* register this device and its handlers - the handlers automatically + sends in the object to handle */ + lwm2m_engine_register_object(&button); + +#if PLATFORM_HAS_BUTTON + process_start(&ipso_button_process, NULL); +#endif /* PLATFORM_HAS_BUTTON */ +} +/*---------------------------------------------------------------------------*/ +#if PLATFORM_HAS_BUTTON +PROCESS_THREAD(ipso_button_process, ev, data) +{ + static struct etimer timer; + int32_t time; + + PROCESS_BEGIN(); + + SENSORS_ACTIVATE(button_sensor); + + while(1) { + PROCESS_WAIT_EVENT(); + + if(ev == sensors_event && data == &button_sensor) { + if(!input_state) { + input_state = 1; + counter++; + if((edge_selection & 2) != 0) { + lwm2m_object_notify_observers(&button, "/0/5500"); + } + lwm2m_object_notify_observers(&button, "/0/5501"); + + time = (debounce_time * CLOCK_SECOND / 1000); + if(time < 1) { + time = 1; + } + etimer_set(&timer, (clock_time_t)time); + } + } else if(ev == PROCESS_EVENT_TIMER && data == &timer) { + if(!input_state) { + /* Button is not in pressed state */ + } else if(button_sensor.value(0) != 0) { + /* Button is still pressed */ + etimer_reset(&timer); + } else { + input_state = 0; + if((edge_selection & 1) != 0) { + lwm2m_object_notify_observers(&button, "/0/5500"); + } + } + } + } + + PROCESS_END(); +} +#endif /* PLATFORM_HAS_BUTTON */ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/ipso-objects/ipso-leds-control.c b/apps/ipso-objects/ipso-leds-control.c new file mode 100644 index 000000000..578dac3d2 --- /dev/null +++ b/apps/ipso-objects/ipso-leds-control.c @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup ipso-objects + * @{ + * + */ + +/** + * \file + * Implementation of OMA LWM2M / IPSO Light Control for LEDs + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "lwm2m-object.h" +#include "lwm2m-engine.h" +#include "er-coap-engine.h" +#include "dev/leds.h" +#include + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#if LEDS_ALL & LEDS_BLUE || LEDS_ALL & LEDS_RED || LEDS_ALL & LEDS_BLUE +#define LEDS_CONTROL_NUMBER (((LEDS_ALL & LEDS_BLUE) ? 1 : 0) + ((LEDS_ALL & LEDS_RED) ? 1 : 0) + ((LEDS_ALL & LEDS_GREEN) ? 1 : 0)) +#else +#define LEDS_CONTROL_NUMBER 1 +#endif + +struct led_state { + unsigned long last_on_time; + uint32_t total_on_time; + uint8_t is_on; + uint8_t led_value; +}; + +static struct led_state states[LEDS_CONTROL_NUMBER]; +static lwm2m_instance_t leds_control_instances[LEDS_CONTROL_NUMBER]; +/*---------------------------------------------------------------------------*/ +static int +read_state(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + uint8_t idx = ctx->object_instance_index; + if(idx >= LEDS_CONTROL_NUMBER) { + return 0; + } + return ctx->writer->write_boolean(ctx, outbuf, outsize, + states[idx].is_on ? 1 : 0); +} +/*---------------------------------------------------------------------------*/ +static int +write_state(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize, + uint8_t *outbuf, size_t outsize) +{ + int value; + size_t len; + + uint8_t idx = ctx->object_instance_index; + if(idx >= LEDS_CONTROL_NUMBER) { + return 0; + } + + len = ctx->reader->read_boolean(ctx, inbuf, insize, &value); + if(len > 0) { + if(value) { + if(!states[idx].is_on) { + states[idx].is_on = 1; + states[idx].last_on_time = clock_seconds(); +#if PLATFORM_HAS_LEDS + leds_on(states[idx].led_value); +#endif /* PLATFORM_HAS_LEDS */ + } + } else if(states[idx].is_on) { + states[idx].total_on_time += clock_seconds() - states[idx].last_on_time; + states[idx].is_on = 0; +#if PLATFORM_HAS_LEDS + leds_off(states[idx].led_value); +#endif /* PLATFORM_HAS_LEDS */ + } + } else { + PRINTF("IPSO leds control - ignored illegal write to on/off\n"); + } + return len; +} +/*---------------------------------------------------------------------------*/ +static char * +get_color(int value) { + switch(value) { + case LEDS_GREEN: + return "Green"; + case LEDS_RED: + return "Red"; + case LEDS_BLUE: + return "Blue"; + } + return "None"; +} + +static int +read_color(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + char *value; + uint8_t idx = ctx->object_instance_index; + if(idx >= LEDS_CONTROL_NUMBER) { + return 0; + } + value = get_color(states[idx].led_value); + return ctx->writer->write_string(ctx, outbuf, outsize, + value, strlen(value)); +} +/*---------------------------------------------------------------------------*/ +static int +read_on_time(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + unsigned long now; + uint8_t idx = ctx->object_instance_index; + if(idx >= LEDS_CONTROL_NUMBER) { + return 0; + } + + if(states[idx].is_on) { + /* Update the on time */ + now = clock_seconds(); + states[idx].total_on_time += now - states[idx].last_on_time; + states[idx].last_on_time = now; + } + return ctx->writer->write_int(ctx, outbuf, outsize, + (int32_t)states[idx].total_on_time); +} +/*---------------------------------------------------------------------------*/ +static int +write_on_time(lwm2m_context_t *ctx, + const uint8_t *inbuf, size_t insize, + uint8_t *outbuf, size_t outsize) +{ + int32_t value; + size_t len; + uint8_t idx = ctx->object_instance_index; + if(idx >= LEDS_CONTROL_NUMBER) { + return 0; + } + + len = ctx->reader->read_int(ctx, inbuf, insize, &value); + if(len > 0 && value == 0) { + PRINTF("IPSO leds control - reset On Time\n"); + states[idx].total_on_time = 0; + if(states[idx].is_on) { + states[idx].last_on_time = clock_seconds(); + } + } else { + PRINTF("IPSO leds control - ignored illegal write to On Time\n"); + } + return len; +} +/*---------------------------------------------------------------------------*/ +LWM2M_RESOURCES(leds_control_resources, + LWM2M_RESOURCE_CALLBACK(5850, { read_state, write_state, NULL }), + LWM2M_RESOURCE_CALLBACK(5706, { read_color, NULL, NULL }), + LWM2M_RESOURCE_CALLBACK(5852, { read_on_time, write_on_time, NULL }) + ); +LWM2M_OBJECT(leds_control, 3311, leds_control_instances); +/*---------------------------------------------------------------------------*/ +static int +bit_no(int bit) +{ + int i; + for(i = 0; i < 8; i++) { + if(LEDS_ALL & (1 << i)) { + if(bit == 0) { + /* matching bit */ + return 1 << i; + } else { + /* matching but used */ + bit--; + } + } + } + return 0; +} + +void +ipso_leds_control_init(void) +{ + lwm2m_instance_t template = LWM2M_INSTANCE(0, leds_control_resources); + int i; + + /* Initialize the instances */ + for(i = 0; i < LEDS_CONTROL_NUMBER; i++) { + leds_control_instances[i] = template; + leds_control_instances[i].id = i; + states[i].led_value = bit_no(i); + } + + /* register this device and its handlers - the handlers automatically + sends in the object to handle */ + lwm2m_engine_register_object(&leds_control); + PRINTF("IPSO leds control initialized with %u instances\n", + LEDS_CONTROL_NUMBER); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/ipso-objects/ipso-light-control.c b/apps/ipso-objects/ipso-light-control.c new file mode 100644 index 000000000..02c4b9be2 --- /dev/null +++ b/apps/ipso-objects/ipso-light-control.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup ipso-objects + * @{ + * + */ + +/** + * \file + * Implementation of OMA LWM2M / IPSO Light Control + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "ipso-objects.h" +#include "lwm2m-object.h" +#include "lwm2m-engine.h" + +#ifdef IPSO_LIGHT_CONTROL +extern const struct ipso_objects_actuator IPSO_LIGHT_CONTROL; +#endif /* IPSO_LIGHT_CONTROL */ +/*---------------------------------------------------------------------------*/ +static unsigned long last_on_time; +static uint32_t total_on_time; +static int dim_level = 0; +static uint8_t is_on = 0; +/*---------------------------------------------------------------------------*/ +static int +read_state(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + return ctx->writer->write_boolean(ctx, outbuf, outsize, is_on ? 1 : 0); +} +/*---------------------------------------------------------------------------*/ +static int +write_state(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize, + uint8_t *outbuf, size_t outsize) +{ + int value; + size_t len; + + len = ctx->reader->read_boolean(ctx, inbuf, insize, &value); + if(len > 0) { + if(value) { + if(!is_on) { + is_on = 1; + last_on_time = clock_seconds(); + } + } else { + if(is_on) { + total_on_time += clock_seconds() - last_on_time; + is_on = 0; + } + } +#ifdef IPSO_LIGHT_CONTROL + if(IPSO_LIGHT_CONTROL.set_on) { + IPSO_LIGHT_CONTROL.set_on(value); + } else if(IPSO_LIGHT_CONTROL.set_dim_level) { + dim_level = value ? 100 : 0; + IPSO_LIGHT_CONTROL.set_dim_level(dim_level); + } +#endif /* IPSO_LIGHT_CONTROL */ + } + return len; +} +/*---------------------------------------------------------------------------*/ +static int +read_dim(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + return ctx->writer->write_int(ctx, outbuf, outsize, dim_level); +} +/*---------------------------------------------------------------------------*/ +static int +write_dim(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize, + uint8_t *outbuf, size_t outsize) +{ + int32_t value; + size_t len; + + len = ctx->reader->read_int(ctx, inbuf, insize, &value); + if(len > 0) { + if(value < 0) { + value = 0; + } else if(value > 100) { + value = 100; + } + + dim_level = value; + if(value > 0) { + if(!is_on) { + is_on = 1; + last_on_time = clock_seconds(); + } + } else { + if(is_on) { + total_on_time += clock_seconds() - last_on_time; + is_on = 0; + } + } +#ifdef IPSO_LIGHT_CONTROL + if(IPSO_LIGHT_CONTROL.set_dim_level) { + IPSO_LIGHT_CONTROL.set_dim_level(dim_level); + } else if(IPSO_LIGHT_CONTROL.set_on) { + IPSO_LIGHT_CONTROL.set_on(is_on); + } +#endif /* IPSO_LIGHT_CONTROL */ + } + return len; +} +/*---------------------------------------------------------------------------*/ +static int +read_on_time(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + unsigned long now; + if(is_on) { + /* Update the on time */ + now = clock_seconds(); + total_on_time += now - last_on_time; + last_on_time = now; + } + return ctx->writer->write_int(ctx, outbuf, outsize, (int32_t)total_on_time); +} +/*---------------------------------------------------------------------------*/ +static int +write_on_time(lwm2m_context_t *ctx, + const uint8_t *inbuf, size_t insize, + uint8_t *outbuf, size_t outsize) +{ + int32_t value; + size_t len; + + len = ctx->reader->read_int(ctx, inbuf, insize, &value); + if(len > 0 && value == 0) { + total_on_time = 0; + if(is_on) { + last_on_time = clock_seconds(); + } + } + return len; +} +/*---------------------------------------------------------------------------*/ +LWM2M_RESOURCES(light_control_resources, + LWM2M_RESOURCE_CALLBACK(5850, { read_state, write_state, NULL }), + LWM2M_RESOURCE_CALLBACK(5851, { read_dim, write_dim, NULL }), + LWM2M_RESOURCE_CALLBACK(5852, { read_on_time, write_on_time, NULL }), + ); +LWM2M_INSTANCES(light_control_instances, + LWM2M_INSTANCE(0, light_control_resources)); +LWM2M_OBJECT(light_control, 3311, light_control_instances); +/*---------------------------------------------------------------------------*/ +void +ipso_light_control_init(void) +{ +#ifdef IPSO_LIGHT_CONTROL + if(IPSO_LIGHT_CONTROL.init) { + IPSO_LIGHT_CONTROL.init(); + } + if(IPSO_LIGHT_CONTROL.is_on) { + is_on = IPSO_LIGHT_CONTROL.is_on(); + } + if(IPSO_LIGHT_CONTROL.get_dim_level) { + dim_level = IPSO_LIGHT_CONTROL.get_dim_level(); + if(dim_level > 0 && IPSO_LIGHT_CONTROL.is_on == NULL) { + is_on = 1; + } + } +#endif /* IPSO_LIGHT_CONTROL */ + last_on_time = clock_seconds(); + + lwm2m_engine_register_object(&light_control); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/ipso-objects/ipso-objects.c b/apps/ipso-objects/ipso-objects.c new file mode 100644 index 000000000..1e8243f94 --- /dev/null +++ b/apps/ipso-objects/ipso-objects.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + */ + +/** + * \file + * Implementation of the IPSO Objects + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "contiki.h" +#include "ipso-objects.h" +/*---------------------------------------------------------------------------*/ +void +ipso_objects_init(void) +{ + /* initialize any relevant object for the IPSO Objects */ +#ifdef IPSO_TEMPERATURE + ipso_temperature_init(); +#endif + +#if PLATFORM_HAS_BUTTON + ipso_button_init(); +#endif + +#ifdef IPSO_LIGHT_CONTROL + ipso_light_control_init(); +#elif PLATFORM_HAS_LEDS + ipso_leds_control_init(); +#endif +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/ipso-objects/ipso-objects.h b/apps/ipso-objects/ipso-objects.h new file mode 100644 index 000000000..13cfecae6 --- /dev/null +++ b/apps/ipso-objects/ipso-objects.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup apps + * @{ + */ + +/** + * \defgroup ipso-objects An implementation of IPSO Objects + * @{ + * + * This application is an implementation of IPSO Objects for + * OMA Lightweight M2M. + */ + +/** + * \file + * Header file for the Contiki IPSO Objects for OMA LWM2M + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef IPSO_OBJECTS_H_ +#define IPSO_OBJECTS_H_ + +#include "contiki-conf.h" + +void ipso_temperature_init(void); +void ipso_button_init(void); +void ipso_light_control_init(void); +void ipso_leds_control_init(void); + +/* the init function to register the IPSO objects */ +void ipso_objects_init(void); + +struct ipso_objects_actuator { + /** + * \brief Initialize the driver. + */ + void (* init)(void); + + /** + * \brief Check if the actuator is on or off. + * + * \return Zero if the actuator is off and non-zero otherwise. + */ + int (* is_on)(void); + + /** + * \brief Set the actuator to on or off. + * + * \param onoroff Zero to set the actuator to off and non-zero otherwise. + * \return Zero if ok and a non-zero error code otherwise. + */ + int (* set_on)(int onoroff); + + /** + * \brief Set the actuator to on or off. + * + * \param onoroff Zero to set the actuator to off and non-zero otherwise. + * \return Zero if ok and a non-zero error code otherwise. + */ + int (* get_dim_level)(void); + + /** + * \brief Set the dim level of the actuator. + * + * \param level The dim level between 0% and 100%. + * \return Zero if ok and a non-zero error code otherwise. + */ + int (* set_dim_level)(int level); +}; + +struct ipso_objects_sensor { + /** + * \brief Initialize the driver. + */ + void (* init)(void); + + /** + * \brief Read the sensor value in 1/1000 units. + * + * \param value A pointer to the variable to hold the sensor value. + * \return Zero if ok and a non-zero error code otherwise. + */ + int (* read_value)(int32_t *value); +}; + +#endif /* IPSO_OBJECTS_H_ */ +/** + * @} + * @} + */ diff --git a/apps/ipso-objects/ipso-temperature.c b/apps/ipso-objects/ipso-temperature.c new file mode 100644 index 000000000..457dfe0f8 --- /dev/null +++ b/apps/ipso-objects/ipso-temperature.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup ipso-objects + * @{ + */ + +/** + * \file + * Implementation of OMA LWM2M / IPSO Temperature + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include +#include "ipso-objects.h" +#include "lwm2m-object.h" +#include "lwm2m-engine.h" +#include "er-coap-engine.h" + +#ifdef IPSO_TEMPERATURE +extern const struct ipso_objects_sensor IPSO_TEMPERATURE; +#endif /* IPSO_TEMPERATURE */ + +#ifndef IPSO_TEMPERATURE_MIN +#define IPSO_TEMPERATURE_MIN (-50 * LWM2M_FLOAT32_FRAC) +#endif + +#ifndef IPSO_TEMPERATURE_MAX +#define IPSO_TEMPERATURE_MAX (80 * LWM2M_FLOAT32_FRAC) +#endif + +static struct ctimer periodic_timer; +static int32_t min_temp; +static int32_t max_temp; +static int read_temp(int32_t *value); +/*---------------------------------------------------------------------------*/ +static int +temp(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + int32_t value; + if(read_temp(&value)) { + return ctx->writer->write_float32fix(ctx, outbuf, outsize, + value, LWM2M_FLOAT32_BITS); + } + return 0; +} +/*---------------------------------------------------------------------------*/ +LWM2M_RESOURCES(temperature_resources, + /* Temperature (Current) */ + LWM2M_RESOURCE_CALLBACK(5700, { temp, NULL, NULL }), + /* Units */ + LWM2M_RESOURCE_STRING(5701, "Cel"), + /* Min Range Value */ + LWM2M_RESOURCE_FLOATFIX(5603, IPSO_TEMPERATURE_MIN), + /* Max Range Value */ + LWM2M_RESOURCE_FLOATFIX(5604, IPSO_TEMPERATURE_MAX), + /* Min Measured Value */ + LWM2M_RESOURCE_FLOATFIX_VAR(5601, &min_temp), + /* Max Measured Value */ + LWM2M_RESOURCE_FLOATFIX_VAR(5602, &max_temp), + ); +LWM2M_INSTANCES(temperature_instances, + LWM2M_INSTANCE(0, temperature_resources)); +LWM2M_OBJECT(temperature, 3303, temperature_instances); +/*---------------------------------------------------------------------------*/ +static int +read_temp(int32_t *value) +{ +#ifdef IPSO_TEMPERATURE + int32_t temp; + if(IPSO_TEMPERATURE.read_value == NULL || + IPSO_TEMPERATURE.read_value(&temp) != 0) { + return 0; + } + + /* Convert milliCelsius to fix float */ + *value = (temp * LWM2M_FLOAT32_FRAC) / 1000; + + if(*value < min_temp) { + min_temp = *value; + lwm2m_object_notify_observers(&temperature, "/0/5601"); + } + if(*value > max_temp) { + max_temp = *value; + lwm2m_object_notify_observers(&temperature, "/0/5602"); + } + return 1; +#else /* IPSO_TEMPERATURE */ + return 0; +#endif /* IPSO_TEMPERATURE */ +} +/*---------------------------------------------------------------------------*/ +static void +handle_periodic_timer(void *ptr) +{ + static int32_t last_value = IPSO_TEMPERATURE_MIN; + int32_t v; + + /* Only notify when the value has changed since last */ + if(read_temp(&v) && v != last_value) { + last_value = v; + lwm2m_object_notify_observers(&temperature, "/0/5700"); + } + ctimer_reset(&periodic_timer); +} +/*---------------------------------------------------------------------------*/ +void +ipso_temperature_init(void) +{ + int32_t v; + min_temp = IPSO_TEMPERATURE_MAX; + max_temp = IPSO_TEMPERATURE_MIN; + +#ifdef IPSO_TEMPERATURE + if(IPSO_TEMPERATURE.init) { + IPSO_TEMPERATURE.init(); + } +#endif /* IPSO_TEMPERATURE */ + + /* register this device and its handlers - the handlers automatically + sends in the object to handle */ + lwm2m_engine_register_object(&temperature); + + /* update temp and min/max + notify any listeners */ + read_temp(&v); + ctimer_set(&periodic_timer, CLOCK_SECOND * 10, handle_periodic_timer, NULL); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/json-resource/generic_resource.c b/apps/json-resource/generic_resource.c index 528ffa368..e968c2f76 100644 --- a/apps/json-resource/generic_resource.c +++ b/apps/json-resource/generic_resource.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Ralf Schlatterbeck Open Source Consulting + * Copyright (c) 2014-15, Ralf Schlatterbeck Open Source Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,8 +46,7 @@ #include #include "contiki.h" #include "jsonparse.h" -/* Only coap 13 for now */ -#include "er-coap-13.h" +#include "er-coap.h" #include "generic_resource.h" /* Error-handling macro */ @@ -106,97 +105,138 @@ json_parse_variable return 0; } -void generic_handler +static const char *get_uri (void *request) +{ + static char buf [MAX_URI_STRING_LENGTH]; + const char *uri; + size_t len = coap_get_header_uri_path (request, &uri); + if (len > sizeof (buf) - 1) { + *buf = '\0'; + } else { + strncpy (buf, uri, len); + buf [len] = '\0'; + } + return buf; +} + +void generic_get_handler ( void *request , void *response , uint8_t *buffer , uint16_t preferred_size , int32_t *offset , char *name - , void (*from_str)(const char *name, const char *s) - , size_t (*to_str)(const char *name, uint8_t is_json, char *buf, size_t bsize) + , int is_str + , size_t (*to_str)(const char *name, const char *uri, char *buf, size_t bsize) + ) +{ + int success = 1; + char temp [MAX_GET_STRING_LENGTH]; + size_t len = 0; + unsigned int accept = -1; + const char *uri = get_uri (request); + + REST.get_header_accept (request, &accept); + if ( accept != -1 + && accept != REST.type.TEXT_PLAIN + && accept != REST.type.APPLICATION_JSON + ) + { + success = 0; + REST.set_response_status (response, REST.status.NOT_ACCEPTABLE); + return; + } + + // TEXT format + if (accept == REST.type.APPLICATION_JSON) { + len += snprintf + ( temp + len + , sizeof (temp) - len + , "{\n \"%s\" : %s" + , name + , is_str ? "\"" : "" + ); + if (len > sizeof (temp)) { + success = 0; + goto out; + } + len += to_str (name, uri, temp + len, sizeof (temp) - len); + if (len > sizeof (temp)) { + success = 0; + goto out; + } + len += snprintf + ( temp + len + , sizeof (temp) - len + , "%s\n}\n" + , is_str ? "\"" : "" + ); + if (len > sizeof (temp)) { + success = 0; + goto out; + } + } else { // TEXT Format + len += to_str (name, uri, temp + len, sizeof (temp) - len); + if (len > sizeof (temp)) { + success = 0; + goto out; + } + len += snprintf (temp + len, sizeof (temp) - len, "\n"); + if (len > sizeof (temp)) { + success = 0; + goto out; + } + } + memcpy (buffer, temp, len); + REST.set_header_content_type (response, accept); + REST.set_response_payload (response, buffer, len); +out : + if (!success) { + REST.set_response_status (response, REST.status.BAD_REQUEST); + } +} + +void generic_put_handler + ( void *request + , void *response + , uint8_t *buffer + , uint16_t preferred_size + , int32_t *offset + , char *name + , int (*from_str)(const char *name, const char *uri, const char *s) ) { int success = 1; char temp [100]; - int i = 0; size_t len = 0; - int n_acc = 0; const uint8_t *bytes = NULL; - const uint16_t *accept = NULL; - uint16_t a_ctype = REST.type.APPLICATION_JSON; - uint16_t c_ctype = REST.get_header_content_type (request); + unsigned int c_ctype; + const char *uri = get_uri (request); + REST.get_header_content_type (request, &c_ctype); - /* Seems like accepted type is currently unsupported? */ - n_acc = REST.get_header_accept (request, &accept); - for (i=0; i sizeof (temp)) { - success = 0; - break; - } - len += snprintf (temp + len, sizeof (temp) - len, "\n"); - if (len > sizeof (temp)) { - success = 0; - break; - } - } else { // jSON Format - len += snprintf - (temp + len, sizeof (temp) - len, "{\n \"%s\" : ", name); - if (len > sizeof (temp)) { - success = 0; - break; - } - len += to_str (name, 1, temp + len, sizeof (temp) - len); - if (len > sizeof (temp)) { - success = 0; - break; - } - len += snprintf (temp + len, sizeof (temp) - len, "\n}\n"); - if (len > sizeof (temp)) { - success = 0; - break; - } - } - memcpy (buffer, temp, len); - REST.set_header_content_type (response, a_ctype); - REST.set_response_payload (response, buffer, len); - break; - case METHOD_PUT: - if (from_str && (len = coap_get_payload(request, &bytes))) { - if (c_ctype == REST.type.TEXT_PLAIN) { - temp [sizeof (temp) - 1] = 0; - strncpy (temp, (const char *)bytes, MIN (len, sizeof (temp) - 1)); - } else { // jSON Format - if (json_parse_variable (bytes, len, name, temp, sizeof (temp)) < 0) { - success = 0; - break; - } - } - from_str (name, temp); - REST.set_response_status(response, REST.status.CHANGED); - } else { + if (from_str && (len = coap_get_payload (request, &bytes))) { + if (c_ctype == REST.type.TEXT_PLAIN) { + int l = MIN (len, sizeof (temp) - 1); + temp [sizeof (temp) - 1] = 0; + strncpy (temp, (const char *)bytes, l); + temp [l] = 0; + } else { // jSON Format + if (json_parse_variable (bytes, len, name, temp, sizeof (temp)) < 0) { success = 0; + goto out; } - break; - default: + } + if (from_str (name, uri, temp) < 0) { success = 0; + } else { + REST.set_response_status (response, REST.status.CHANGED); + } + } else { + success = 0; } +out: if (!success) { - REST.set_response_status(response, REST.status.BAD_REQUEST); + REST.set_response_status (response, REST.status.BAD_REQUEST); } } diff --git a/apps/json-resource/generic_resource.h b/apps/json-resource/generic_resource.h index 850c575e8..2c0e6ca05 100644 --- a/apps/json-resource/generic_resource.h +++ b/apps/json-resource/generic_resource.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Ralf Schlatterbeck Open Source Consulting + * Copyright (c) 2014-15, Ralf Schlatterbeck Open Source Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,6 +50,9 @@ #define STR__(s) #s #define STR_(s) STR__(s) +#define MAX_GET_STRING_LENGTH 100 +#define MAX_URI_STRING_LENGTH 30 + /* * A macro that extends the resource definition and also sets up the * necessary handler function that calls format/parse routines that @@ -60,8 +63,8 @@ * Yes, this *is* a hack. But I hate boilerplate code. */ -#define GENERIC_RESOURCE(name, methods, path, title, unit, fs, ts) \ - void name##_handler \ +#define GENERIC_RESOURCE(name, title, unit, is_str, fs, ts) \ + static void name##_get_handler \ ( void *request \ , void *response \ , uint8_t *buffer \ @@ -69,16 +72,34 @@ , int32_t *offset \ ) \ { \ - generic_handler \ - (request, response, buffer, ps, offset, STR_(name), fs, ts); \ + generic_get_handler \ + (request, response, buffer, ps, offset, STR_(name), is_str, ts); \ + } \ + static void name##_put_handler \ + ( void *request \ + , void *response \ + , uint8_t *buffer \ + , uint16_t ps \ + , int32_t *offset \ + ) \ + { \ + generic_put_handler \ + (request, response, buffer, ps, offset, STR_(name), fs); \ } \ \ - RESOURCE ( name, methods, path \ + RESOURCE ( res_##name \ , "title=\"" STR_(title) "\"" \ ";rt=UCUM:\"" STR_(unit) "\"" \ ";ct=\"0 5\"" \ + , (ts) ? name##_get_handler : NULL \ + , NULL /* POST */ \ + , (fs) ? name##_put_handler : NULL \ + , NULL /* DELETE */ \ ) +/* Ignore constant pointer tests above */ +#pragma GCC diagnostic ignored "-Waddress" + /** * \brief Parse a resource in json format * \param bytes: Input string received via coap @@ -94,11 +115,8 @@ extern int8_t json_parse_variable (const uint8_t *bytes, size_t len, char *name, char *buf, size_t buflen); /** - * \brief Generic coap resource handler + * \brief Generic coap GET resource handler * \param name: The name of the variable in json - * \param from_str: Application method to parse value from string - * and act on it, may be NULL in which case the resource only - * supports GET not PUT * \param to_str: Application method to format value for output; * the function may chose to format differently for coap or text * The other parameters are the same as a normal resource handler @@ -106,21 +124,44 @@ extern int8_t json_parse_variable * * The callback functions get the name of the parameter as a first * argument, this allows to re-use the same function for different - * parameters. The from_str in addition gets the string to parse. + * parameters. * For the to_str function the is_json flag allows to generate a * different string depending on the content-type. In addition it gets a * buffer and the size of the buffer. It needs to return the number of * bytes output, similar to sprintf. */ -extern void generic_handler +extern void generic_get_handler ( void *request , void *response , uint8_t *buffer , uint16_t preferred_size , int32_t *offset , char *name - , void (*from_str)(const char *name, const char *s) - , size_t (*to_str)(const char *name, uint8_t is_json, char *buf, size_t bsize) + , int is_str + , size_t (*to_str)(const char *name, const char *uri, char *buf, size_t bsize) + ); + +/** + * \brief Generic coap PUT resource handler + * \param name: The name of the variable in json + * \param from_str: Application method to parse value from string + * and act on it, may be NULL in which case the resource only + * supports GET not PUT + * The other parameters are the same as a normal resource handler + * This helps avoid boilerplate code for request handlers + * + * The callback functions get the name of the parameter as a first + * argument, this allows to re-use the same function for different + * parameters. The from_str in addition gets the string to parse. + */ +extern void generic_put_handler + ( void *request + , void *response + , uint8_t *buffer + , uint16_t preferred_size + , int32_t *offset + , char *name + , int (*from_str)(const char *name, const char *uri, const char *s) ); /* diff --git a/apps/json/json.h b/apps/json/json.h index a698464a5..e4d7094c6 100644 --- a/apps/json/json.h +++ b/apps/json/json.h @@ -45,6 +45,7 @@ #define JSON_TYPE_PAIR ':' #define JSON_TYPE_PAIR_NAME 'N' /* for N:V pairs */ #define JSON_TYPE_STRING '"' +#define JSON_TYPE_UINT 'U' #define JSON_TYPE_INT 'I' #define JSON_TYPE_NUMBER '0' #define JSON_TYPE_ERROR 0 @@ -56,12 +57,21 @@ #define JSON_TYPE_CALLBACK 'C' +/* integer pointer types */ +#define JSON_TYPE_S8PTR 'b' +#define JSON_TYPE_U8PTR 'B' +#define JSON_TYPE_S16PTR 'w' +#define JSON_TYPE_U16PTR 'W' +#define JSON_TYPE_S32PTR 'd' +#define JSON_TYPE_U32PTR 'D' + enum { JSON_ERROR_OK, JSON_ERROR_SYNTAX, JSON_ERROR_UNEXPECTED_ARRAY, JSON_ERROR_UNEXPECTED_END_OF_ARRAY, JSON_ERROR_UNEXPECTED_OBJECT, + JSON_ERROR_UNEXPECTED_END_OF_OBJECT, JSON_ERROR_UNEXPECTED_STRING }; diff --git a/apps/json/jsonparse.c b/apps/json/jsonparse.c index 8089ae9fb..6277b56c4 100644 --- a/apps/json/jsonparse.c +++ b/apps/json/jsonparse.c @@ -43,6 +43,14 @@ push(struct jsonparse_state *state, char c) return state->depth < JSONPARSE_MAX_DEPTH; } /*--------------------------------------------------------------------*/ +static void +modify(struct jsonparse_state *state, char c) +{ + if(state->depth > 0) { + state->stack[state->depth - 1] = c; + } +} +/*--------------------------------------------------------------------*/ static char pop(struct jsonparse_state *state) { @@ -50,25 +58,31 @@ pop(struct jsonparse_state *state) return JSON_TYPE_ERROR; } state->depth--; + state->vtype = state->stack[state->depth]; return state->stack[state->depth]; } /*--------------------------------------------------------------------*/ /* will pass by the value and store the start and length of the value for atomic types */ /*--------------------------------------------------------------------*/ -static void +static char atomic(struct jsonparse_state *state, char type) { char c; + const char *str; + int len; state->vstart = state->pos; - state->vtype = type; if(type == JSON_TYPE_STRING || type == JSON_TYPE_PAIR_NAME) { while((c = state->json[state->pos++]) && c != '"') { if(c == '\\') { state->pos++; /* skip current char */ } } + if (c != '"') { + state->error = JSON_ERROR_SYNTAX; + return JSON_TYPE_ERROR; + } state->vlen = state->pos - state->vstart - 1; } else if(type == JSON_TYPE_NUMBER) { do { @@ -82,8 +96,31 @@ atomic(struct jsonparse_state *state, char type) /* need to back one step since first char is already gone */ state->vstart--; state->vlen = state->pos - state->vstart; + } else if(type == JSON_TYPE_NULL || type == JSON_TYPE_TRUE || type == JSON_TYPE_FALSE) { + state->vstart--; + switch (type) { + case JSON_TYPE_NULL: str = "null"; break; + case JSON_TYPE_TRUE: str = "true"; break; + case JSON_TYPE_FALSE: str = "false"; break; + default: str = ""; break; + } + + while ((c = state->json[state->pos]) && c != ' ' && c != ',' && c != ']' && c != '}') { + state->pos++; + } + + state->vlen = state->pos - state->vstart; + len = strlen(str); + len = state->vlen > len ? state->vlen : len; + + if (strncmp(str, &state->json[state->vstart], len) != 0) { + state->error = JSON_ERROR_SYNTAX; + return JSON_TYPE_ERROR; + } } - /* no other types for now... */ + + state->vtype = type; + return state->vtype; } /*--------------------------------------------------------------------*/ static void @@ -97,6 +134,17 @@ skip_ws(struct jsonparse_state *state) } } /*--------------------------------------------------------------------*/ +static int +is_atomic(struct jsonparse_state *state) +{ + char v = state->vtype; + if(v == 'N' || v == '"' || v == '0' || v == 'n' || v == 't' || v == 'f') { + return 1; + } else { + return 0; + } +} +/*--------------------------------------------------------------------*/ void jsonparse_setup(struct jsonparse_state *state, const char *json, int len) { @@ -105,6 +153,7 @@ jsonparse_setup(struct jsonparse_state *state, const char *json, int len) state->pos = 0; state->depth = 0; state->error = 0; + state->vtype = 0; state->stack[0] = 0; } /*--------------------------------------------------------------------*/ @@ -113,31 +162,33 @@ jsonparse_next(struct jsonparse_state *state) { char c; char s; + char v; skip_ws(state); c = state->json[state->pos]; s = jsonparse_get_type(state); + v = state->vtype; state->pos++; switch(c) { case '{': - push(state, c); + if((s == 0 && v == 0) || s == '[' || s == ':') { + push(state, c); + } else { + state->error = JSON_ERROR_UNEXPECTED_OBJECT; + return JSON_TYPE_ERROR; + } return c; case '}': - if(s == ':' && state->vtype != 0) { -/* printf("Popping vtype: '%c'\n", state->vtype); */ - pop(state); - s = jsonparse_get_type(state); - } - if(s == '{') { + if((s == ':' && v != ',' && v != 0 ) || (s == '{' && v == 0)) { pop(state); } else { - state->error = JSON_ERROR_SYNTAX; + state->error = JSON_ERROR_UNEXPECTED_END_OF_OBJECT; return JSON_TYPE_ERROR; } return c; case ']': - if(s == '[') { + if(s == '[' && v != ',') { pop(state); } else { state->error = JSON_ERROR_UNEXPECTED_END_OF_ARRAY; @@ -145,41 +196,67 @@ jsonparse_next(struct jsonparse_state *state) } return c; case ':': - push(state, c); - return c; + if(s == '{' && v == 'N') { + modify(state, ':'); + state->vtype = 0; + } else { + state->error = JSON_ERROR_SYNTAX; + return JSON_TYPE_ERROR; + } + return jsonparse_next(state); case ',': - /* if x:y ... , */ - if(s == ':' && state->vtype != 0) { - pop(state); + if(s == ':' && v != 0) { + modify(state, '{'); + state->vtype = c; } else if(s == '[') { - /* ok! */ + state->vtype = c; } else { state->error = JSON_ERROR_SYNTAX; return JSON_TYPE_ERROR; } return c; case '"': - if(s == '{' || s == '[' || s == ':') { - atomic(state, c = (s == '{' ? JSON_TYPE_PAIR_NAME : c)); + if((s == 0 && v == 0) || s == '{' || s == '[' || s == ':') { + return atomic(state, c = (s == '{' ? JSON_TYPE_PAIR_NAME : c)); } else { state->error = JSON_ERROR_UNEXPECTED_STRING; return JSON_TYPE_ERROR; } return c; case '[': - if(s == '{' || s == '[' || s == ':') { + if((s == 0 && v == 0) || s == '[' || s == ':') { push(state, c); } else { state->error = JSON_ERROR_UNEXPECTED_ARRAY; return JSON_TYPE_ERROR; } return c; + case 0: + if(v == 0 || state->depth > 0) { + state->error = JSON_ERROR_SYNTAX; + } + return JSON_TYPE_ERROR; default: - if(s == ':' || s == '[') { - if(c <= '9' && c >= '0') { - atomic(state, JSON_TYPE_NUMBER); - return JSON_TYPE_NUMBER; + if(s == 0 || s == ':' || s == '[') { + if (v != 0 && v != ',') { + state->error = JSON_ERROR_SYNTAX; + return JSON_TYPE_ERROR; } + if(c == '-' || (c <= '9' && c >= '0')) { + return atomic(state, JSON_TYPE_NUMBER); + } else if(c == 'n') { + return atomic(state, JSON_TYPE_NULL); + } else if(c == 't') { + return atomic(state, JSON_TYPE_TRUE); + } else if(c == 'f') { + return atomic(state, JSON_TYPE_FALSE); + } else { + state->error = JSON_ERROR_SYNTAX; + return JSON_TYPE_ERROR; + } + } else if(s == '{') { + state->error = JSON_ERROR_SYNTAX; + return JSON_TYPE_ERROR; } } return 0; @@ -192,16 +269,31 @@ jsonparse_next(struct jsonparse_state *state) int jsonparse_copy_value(struct jsonparse_state *state, char *str, int size) { - int i; + int i, o; + char c; - if(state->vtype == 0) { + if(!is_atomic(state)) { return 0; } - size = size <= state->vlen ? (size - 1) : state->vlen; - for(i = 0; i < size; i++) { - str[i] = state->json[state->vstart + i]; + for(i = 0, o = 0; i < state->vlen && o < size - 1; i++) { + c = state->json[state->vstart + i]; + if(c == '\\') { + i++; + switch(state->json[state->vstart + i]) { + case '"': str[o++] = '"'; break; + case '\\': str[o++] = '\\'; break; + case '/': str[o++] = '/'; break; + case 'b': str[o++] = '\b'; break; + case 'f': str[o++] = '\f'; break; + case 'n': str[o++] = '\n'; break; + case 'r': str[o++] = '\r'; break; + case 't': str[o++] = '\t'; break; + } + continue; + } + str[o++] = c; } - str[i] = 0; + str[o] = 0; return state->vtype; } /*--------------------------------------------------------------------*/ @@ -228,7 +320,7 @@ jsonparse_get_value_as_long(struct jsonparse_state *state) int jsonparse_strcmp_value(struct jsonparse_state *state, const char *str) { - if(state->vtype == 0) { + if(!is_atomic(state)) { return -1; } return strncmp(str, &state->json[state->vstart], state->vlen); diff --git a/apps/json/jsontree.c b/apps/json/jsontree.c index 45f305869..13d7d8604 100644 --- a/apps/json/jsontree.c +++ b/apps/json/jsontree.c @@ -79,16 +79,11 @@ jsontree_write_string(const struct jsontree_context *js_ctx, const char *text) } /*---------------------------------------------------------------------------*/ void -jsontree_write_int(const struct jsontree_context *js_ctx, int value) +jsontree_write_uint(const struct jsontree_context *js_ctx, unsigned int value) { char buf[10]; int l; - if(value < 0) { - js_ctx->putchar('-'); - value = -value; - } - l = sizeof(buf) - 1; do { buf[l--] = '0' + (value % 10); @@ -101,6 +96,17 @@ jsontree_write_int(const struct jsontree_context *js_ctx, int value) } /*---------------------------------------------------------------------------*/ void +jsontree_write_int(const struct jsontree_context *js_ctx, int value) +{ + if(value < 0) { + js_ctx->putchar('-'); + value = -value; + } + + jsontree_write_uint(js_ctx, value); +} +/*---------------------------------------------------------------------------*/ +void jsontree_setup(struct jsontree_context *js_ctx, struct jsontree_value *root, int (* putchar)(int)) { @@ -132,6 +138,9 @@ jsontree_print_next(struct jsontree_context *js_ctx) { struct jsontree_value *v; int index; +#if JSONTREE_PRETTY + int indent; +#endif v = js_ctx->values[js_ctx->depth]; @@ -145,10 +154,19 @@ jsontree_print_next(struct jsontree_context *js_ctx) index = js_ctx->index[js_ctx->depth]; if(index == 0) { js_ctx->putchar(v->type); +#if JSONTREE_PRETTY js_ctx->putchar('\n'); +#endif } if(index >= o->count) { +#if JSONTREE_PRETTY js_ctx->putchar('\n'); + indent = js_ctx->depth; + while (indent--) { + js_ctx->putchar(' '); + js_ctx->putchar(' '); + } +#endif js_ctx->putchar(v->type + 2); /* Default operation: back up one level! */ break; @@ -156,12 +174,26 @@ jsontree_print_next(struct jsontree_context *js_ctx) if(index > 0) { js_ctx->putchar(','); +#if JSONTREE_PRETTY js_ctx->putchar('\n'); +#endif } + +#if JSONTREE_PRETTY + indent = js_ctx->depth + 1; + while (indent--) { + js_ctx->putchar(' '); + js_ctx->putchar(' '); + } +#endif + if(v->type == JSON_TYPE_OBJECT) { jsontree_write_string(js_ctx, ((struct jsontree_object *)o)->pairs[index].name); js_ctx->putchar(':'); +#if JSONTREE_PRETTY + js_ctx->putchar(' '); +#endif ov = ((struct jsontree_object *)o)->pairs[index].value; } else { ov = o->values[index]; @@ -177,6 +209,10 @@ jsontree_print_next(struct jsontree_context *js_ctx) jsontree_write_string(js_ctx, ((struct jsontree_string *)v)->value); /* Default operation: back up one level! */ break; + case JSON_TYPE_UINT: + jsontree_write_uint(js_ctx, ((struct jsontree_uint *)v)->value); + /* Default operation: back up one level! */ + break; case JSON_TYPE_INT: jsontree_write_int(js_ctx, ((struct jsontree_int *)v)->value); /* Default operation: back up one level! */ @@ -198,6 +234,30 @@ jsontree_print_next(struct jsontree_context *js_ctx) } /* Default operation: back up one level! */ break; + case JSON_TYPE_S8PTR: + jsontree_write_int(js_ctx, *((int8_t *)((struct jsontree_ptr *)v)->value)); + /* Default operation: back up one level! */ + break; + case JSON_TYPE_U8PTR: + jsontree_write_uint(js_ctx, *((uint8_t *)((struct jsontree_ptr *)v)->value)); + /* Default operation: back up one level! */ + break; + case JSON_TYPE_S16PTR: + jsontree_write_int(js_ctx, *((int16_t *)((struct jsontree_ptr *)v)->value)); + /* Default operation: back up one level! */ + break; + case JSON_TYPE_U16PTR: + jsontree_write_uint(js_ctx, *((uint16_t *)((struct jsontree_ptr *)v)->value)); + /* Default operation: back up one level! */ + break; + case JSON_TYPE_S32PTR: + jsontree_write_int(js_ctx, *((int32_t *)((struct jsontree_ptr *)v)->value)); + /* Default operation: back up one level! */ + break; + case JSON_TYPE_U32PTR: + jsontree_write_uint(js_ctx, *((uint32_t *)((struct jsontree_ptr *)v)->value)); + /* Default operation: back up one level! */ + break; } default: PRINTF("\nError: Illegal json type:'%c'\n", v->type); diff --git a/apps/json/jsontree.h b/apps/json/jsontree.h index 491e29ac9..a6c349d80 100644 --- a/apps/json/jsontree.h +++ b/apps/json/jsontree.h @@ -49,6 +49,12 @@ #define JSONTREE_MAX_DEPTH 10 #endif /* JSONTREE_CONF_MAX_DEPTH */ +#ifdef JSONTREE_CONF_PRETTY +#define JSONTREE_PRETTY JSONTREE_CONF_PRETTY +#else +#define JSONTREE_PRETTY 0 +#endif /* JSONTREE_CONF_PRETTY */ + struct jsontree_context { struct jsontree_value *values[JSONTREE_MAX_DEPTH]; uint16_t index[JSONTREE_MAX_DEPTH]; @@ -68,6 +74,11 @@ struct jsontree_string { const char *value; }; +struct jsontree_uint { + uint8_t type; + unsigned int value; +}; + struct jsontree_int { uint8_t type; int value; @@ -98,6 +109,11 @@ struct jsontree_array { struct jsontree_value **values; }; +struct jsontree_ptr { + uint8_t type; + const void *value; +}; + #define JSONTREE_STRING(text) {JSON_TYPE_STRING, (text)} #define JSONTREE_PAIR(name, value) {(name), (struct jsontree_value *)(value)} #define JSONTREE_CALLBACK(output, set) {JSON_TYPE_CALLBACK, (output), (set)} @@ -130,6 +146,8 @@ void jsontree_reset(struct jsontree_context *js_ctx); const char *jsontree_path_name(const struct jsontree_context *js_ctx, int depth); +void jsontree_write_uint(const struct jsontree_context *js_ctx, + unsigned int value); void jsontree_write_int(const struct jsontree_context *js_ctx, int value); void jsontree_write_atom(const struct jsontree_context *js_ctx, const char *text); diff --git a/apps/mqtt/Makefile.mqtt b/apps/mqtt/Makefile.mqtt new file mode 100644 index 000000000..06d7bd5ab --- /dev/null +++ b/apps/mqtt/Makefile.mqtt @@ -0,0 +1 @@ +mqtt_src = mqtt.c diff --git a/apps/mqtt/mqtt.c b/apps/mqtt/mqtt.c new file mode 100644 index 000000000..f56df3a16 --- /dev/null +++ b/apps/mqtt/mqtt.c @@ -0,0 +1,1483 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup mqtt-engine + * @{ + */ +/** + * \file + * Implementation of the Contiki MQTT engine + * + * \author + * Texas Instruments + */ +/*---------------------------------------------------------------------------*/ +#include "mqtt.h" +#include "contiki.h" +#include "contiki-net.h" +#include "contiki-lib.h" +#include "lib/random.h" +#include "sys/ctimer.h" +#include "sys/etimer.h" +#include "sys/pt.h" +#include "net/rpl/rpl.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "dev/leds.h" + +#include "tcp-socket.h" + +#include "lib/assert.h" +#include "lib/list.h" +#include "sys/cc.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) PRINTF(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +typedef enum { + MQTT_FHDR_MSG_TYPE_CONNECT = 0x10, + MQTT_FHDR_MSG_TYPE_CONNACK = 0x20, + MQTT_FHDR_MSG_TYPE_PUBLISH = 0x30, + MQTT_FHDR_MSG_TYPE_PUBACK = 0x40, + MQTT_FHDR_MSG_TYPE_PUBREC = 0x50, + MQTT_FHDR_MSG_TYPE_PUBREL = 0x60, + MQTT_FHDR_MSG_TYPE_PUBCOMP = 0x70, + MQTT_FHDR_MSG_TYPE_SUBSCRIBE = 0x80, + MQTT_FHDR_MSG_TYPE_SUBACK = 0x90, + MQTT_FHDR_MSG_TYPE_UNSUBSCRIBE = 0xA0, + MQTT_FHDR_MSG_TYPE_UNSUBACK = 0xB0, + MQTT_FHDR_MSG_TYPE_PINGREQ = 0xC0, + MQTT_FHDR_MSG_TYPE_PINGRESP = 0xD0, + MQTT_FHDR_MSG_TYPE_DISCONNECT = 0xE0, + + MQTT_FHDR_DUP_FLAG = 0x08, + + MQTT_FHDR_QOS_LEVEL_0 = 0x00, + MQTT_FHDR_QOS_LEVEL_1 = 0x02, + MQTT_FHDR_QOS_LEVEL_2 = 0x04, + + MQTT_FHDR_RETAIN_FLAG = 0x01, +} mqtt_fhdr_fields_t; +/*---------------------------------------------------------------------------*/ +typedef enum { + MQTT_VHDR_USERNAME_FLAG = 0x80, + MQTT_VHDR_PASSWORD_FLAG = 0x40, + + MQTT_VHDR_WILL_RETAIN_FLAG = 0x20, + MQTT_VHDR_WILL_QOS_LEVEL_0 = 0x00, + MQTT_VHDR_WILL_QOS_LEVEL_1 = 0x08, + MQTT_VHDR_WILL_QOS_LEVEL_2 = 0x10, + + MQTT_VHDR_WILL_FLAG = 0x04, + MQTT_VHDR_CLEAN_SESSION_FLAG = 0x02, +} mqtt_vhdr_conn_fields_t; +/*---------------------------------------------------------------------------*/ +typedef enum { + MQTT_VHDR_CONN_ACCEPTED, + MQTT_VHDR_CONN_REJECTED_PROTOCOL, + MQTT_VHDR_CONN_REJECTED_IDENTIFIER, + MQTT_VHDR_CONN_REJECTED_UNAVAILABLE, + MQTT_VHDR_CONN_REJECTED_BAD_USER_PASS, + MQTT_VHDR_CONN_REJECTED_UNAUTHORIZED, +} mqtt_vhdr_connack_fields_t; +/*---------------------------------------------------------------------------*/ +#define MQTT_CONNECT_VHDR_FLAGS_SIZE 12 + +#define MQTT_STRING_LEN_SIZE 2 +#define MQTT_MID_SIZE 2 +#define MQTT_QOS_SIZE 1 +/*---------------------------------------------------------------------------*/ +#define RESPONSE_WAIT_TIMEOUT (CLOCK_SECOND * 10) +/*---------------------------------------------------------------------------*/ +#define INCREMENT_MID(conn) (conn)->mid_counter += 2 +#define MQTT_STRING_LENGTH(s) (((s)->length) == 0 ? 0 : (MQTT_STRING_LEN_SIZE + (s)->length)) +/*---------------------------------------------------------------------------*/ +/* Protothread send macros */ +#define PT_MQTT_WRITE_BYTES(conn, data, len) \ + while(write_bytes(conn, data, len)) { \ + PT_WAIT_UNTIL(pt, (conn)->out_buffer_sent); \ + } + +#define PT_MQTT_WRITE_BYTE(conn, data) \ + while(write_byte(conn, data)) { \ + PT_WAIT_UNTIL(pt, (conn)->out_buffer_sent); \ + } +/*---------------------------------------------------------------------------*/ +/* + * Sends the continue send event and wait for that event. + * + * The reason we cannot use PROCESS_PAUSE() is since we would risk loosing any + * events posted during the sending process. + */ +#define PT_MQTT_WAIT_SEND() \ + do { \ + process_post(PROCESS_CURRENT(), mqtt_continue_send_event, NULL); \ + PROCESS_WAIT_EVENT(); \ + if(ev == mqtt_abort_now_event) { \ + conn->state = MQTT_CONN_STATE_ABORT_IMMEDIATE; \ + PT_EXIT(&conn->out_proto_thread); \ + process_post(PROCESS_CURRENT(), ev, data); \ + } else if(ev >= mqtt_event_min && ev <= mqtt_event_max) { \ + process_post(PROCESS_CURRENT(), ev, data); \ + } \ + } while(0) +/*---------------------------------------------------------------------------*/ +static process_event_t mqtt_do_connect_tcp_event; +static process_event_t mqtt_do_connect_mqtt_event; +static process_event_t mqtt_do_disconnect_mqtt_event; +static process_event_t mqtt_do_subscribe_event; +static process_event_t mqtt_do_unsubscribe_event; +static process_event_t mqtt_do_publish_event; +static process_event_t mqtt_do_pingreq_event; +static process_event_t mqtt_continue_send_event; +static process_event_t mqtt_abort_now_event; +process_event_t mqtt_update_event; + +/* + * Min and Max event numbers we want to acknowledge while we're in the process + * of doing something else. continue_send does not count, therefore must be + * allocated last + */ +static process_event_t mqtt_event_min; +static process_event_t mqtt_event_max; +/*---------------------------------------------------------------------------*/ +/* Prototypes */ +static int +tcp_input(struct tcp_socket *s, void *ptr, const uint8_t *input_data_ptr, + int input_data_len); + +static void tcp_event(struct tcp_socket *s, void *ptr, + tcp_socket_event_t event); + +static void reset_packet(struct mqtt_in_packet *packet); +/*---------------------------------------------------------------------------*/ +LIST(mqtt_conn_list); +/*---------------------------------------------------------------------------*/ +PROCESS(mqtt_process, "MQTT process"); +/*---------------------------------------------------------------------------*/ +static void +call_event(struct mqtt_connection *conn, + mqtt_event_t event, + void *data) +{ + conn->event_callback(conn, event, data); + process_post(conn->app_process, mqtt_update_event, NULL); +} +/*---------------------------------------------------------------------------*/ +static void +reset_defaults(struct mqtt_connection *conn) +{ + conn->mid_counter = 1; + PT_INIT(&conn->out_proto_thread); + conn->waiting_for_pingresp = 0; + + reset_packet(&conn->in_packet); + conn->out_buffer_sent = 0; +} +/*---------------------------------------------------------------------------*/ +static void +abort_connection(struct mqtt_connection *conn) +{ + conn->out_buffer_ptr = conn->out_buffer; + conn->out_queue_full = 0; + + /* Reset outgoing packet */ + memset(&conn->out_packet, 0, sizeof(conn->out_packet)); + + tcp_socket_close(&conn->socket); + tcp_socket_unregister(&conn->socket); + + memset(&conn->socket, 0, sizeof(conn->socket)); + + conn->state = MQTT_CONN_STATE_NOT_CONNECTED; +} +/*---------------------------------------------------------------------------*/ +static void +connect_tcp(struct mqtt_connection *conn) +{ + conn->state = MQTT_CONN_STATE_TCP_CONNECTING; + + reset_defaults(conn); + tcp_socket_register(&(conn->socket), + conn, + conn->in_buffer, + MQTT_TCP_INPUT_BUFF_SIZE, + conn->out_buffer, + MQTT_TCP_OUTPUT_BUFF_SIZE, + tcp_input, + tcp_event); + tcp_socket_connect(&(conn->socket), &(conn->server_ip), conn->server_port); +} +/*---------------------------------------------------------------------------*/ +static void +disconnect_tcp(struct mqtt_connection *conn) +{ + conn->state = MQTT_CONN_STATE_DISCONNECTING; + tcp_socket_close(&(conn->socket)); + tcp_socket_unregister(&conn->socket); + + memset(&conn->socket, 0, sizeof(conn->socket)); +} +/*---------------------------------------------------------------------------*/ +static void +send_out_buffer(struct mqtt_connection *conn) +{ + if(conn->out_buffer_ptr - conn->out_buffer == 0) { + conn->out_buffer_sent = 1; + return; + } + conn->out_buffer_sent = 0; + + DBG("MQTT - (send_out_buffer) Space used in buffer: %i\n", + conn->out_buffer_ptr - conn->out_buffer); + + tcp_socket_send(&conn->socket, conn->out_buffer, + conn->out_buffer_ptr - conn->out_buffer); +} +/*---------------------------------------------------------------------------*/ +static void +string_to_mqtt_string(struct mqtt_string *mqtt_string, char *string) +{ + if(mqtt_string == NULL) { + return; + } + mqtt_string->string = string; + + if(string != NULL) { + mqtt_string->length = strlen(string); + } else { + mqtt_string->length = 0; + } +} +/*---------------------------------------------------------------------------*/ +static int +write_byte(struct mqtt_connection *conn, uint8_t data) +{ + DBG("MQTT - (write_byte) buff_size: %i write: '%02X'\n", + &conn->out_buffer[MQTT_TCP_OUTPUT_BUFF_SIZE] - conn->out_buffer_ptr, + data); + + if(&conn->out_buffer[MQTT_TCP_OUTPUT_BUFF_SIZE] - conn->out_buffer_ptr == 0) { + send_out_buffer(conn); + return 1; + } + + *conn->out_buffer_ptr = data; + conn->out_buffer_ptr++; + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +write_bytes(struct mqtt_connection *conn, uint8_t *data, uint16_t len) +{ + uint16_t write_bytes; + write_bytes = + MIN(&conn->out_buffer[MQTT_TCP_OUTPUT_BUFF_SIZE] - conn->out_buffer_ptr, + len - conn->out_write_pos); + + memcpy(conn->out_buffer_ptr, &data[conn->out_write_pos], write_bytes); + conn->out_write_pos += write_bytes; + conn->out_buffer_ptr += write_bytes; + + DBG("MQTT - (write_bytes) len: %u write_pos: %lu\n", len, + conn->out_write_pos); + + if(len - conn->out_write_pos == 0) { + conn->out_write_pos = 0; + return 0; + } else { + send_out_buffer(conn); + return len - conn->out_write_pos; + } +} +/*---------------------------------------------------------------------------*/ +static void +encode_remaining_length(uint8_t *remaining_length, + uint8_t *remaining_length_bytes, + uint32_t length) +{ + uint8_t digit; + + DBG("MQTT - Encoding length %lu\n", length); + + *remaining_length_bytes = 0; + do { + digit = length % 128; + length = length / 128; + if(length > 0) { + digit = digit | 0x80; + } + + remaining_length[*remaining_length_bytes] = digit; + (*remaining_length_bytes)++; + DBG("MQTT - Encode len digit '%u' length '%lu'\n", digit, length); + } while(length > 0 && *remaining_length_bytes < 5); + DBG("MQTT - remaining_length_bytes %u\n", *remaining_length_bytes); +} +/*---------------------------------------------------------------------------*/ +static void +keep_alive_callback(void *ptr) +{ + struct mqtt_connection *conn = ptr; + + DBG("MQTT - (keep_alive_callback) Called!\n"); + + /* The flag is set when the PINGREQ has been sent */ + if(conn->waiting_for_pingresp) { + PRINTF("MQTT - Disconnect due to no PINGRESP from broker.\n"); + disconnect_tcp(conn); + return; + } + + process_post(&mqtt_process, mqtt_do_pingreq_event, conn); +} +/*---------------------------------------------------------------------------*/ +static void +reset_packet(struct mqtt_in_packet *packet) +{ + memset(packet, 0, sizeof(struct mqtt_in_packet)); + packet->remaining_multiplier = 1; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(connect_pt(struct pt *pt, struct mqtt_connection *conn)) +{ + PT_BEGIN(pt); + + DBG("MQTT - Sending CONNECT message...\n"); + + /* Set up FHDR */ + conn->out_packet.fhdr = MQTT_FHDR_MSG_TYPE_CONNECT; + conn->out_packet.remaining_length = 0; + conn->out_packet.remaining_length += MQTT_CONNECT_VHDR_FLAGS_SIZE; + conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->client_id); + conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->credentials.username); + conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->credentials.password); + conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->will.topic); + conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->will.message); + encode_remaining_length(conn->out_packet.remaining_length_enc, + &conn->out_packet.remaining_length_enc_bytes, + conn->out_packet.remaining_length); + if(conn->out_packet.remaining_length_enc_bytes > 4) { + call_event(conn, MQTT_EVENT_PROTOCOL_ERROR, NULL); + PRINTF("MQTT - Error, remaining length > 4 bytes\n"); + PT_EXIT(pt); + } + + /* Write Fixed Header */ + PT_MQTT_WRITE_BYTE(conn, conn->out_packet.fhdr); + PT_MQTT_WRITE_BYTES(conn, + conn->out_packet.remaining_length_enc, + conn->out_packet.remaining_length_enc_bytes); + PT_MQTT_WRITE_BYTE(conn, 0); + PT_MQTT_WRITE_BYTE(conn, 6); + PT_MQTT_WRITE_BYTES(conn, (uint8_t *)MQTT_PROTOCOL_NAME, 6); + PT_MQTT_WRITE_BYTE(conn, MQTT_PROTOCOL_VERSION); + PT_MQTT_WRITE_BYTE(conn, conn->connect_vhdr_flags); + PT_MQTT_WRITE_BYTE(conn, (conn->keep_alive >> 8)); + PT_MQTT_WRITE_BYTE(conn, (conn->keep_alive & 0x00FF)); + PT_MQTT_WRITE_BYTE(conn, conn->client_id.length << 8); + PT_MQTT_WRITE_BYTE(conn, conn->client_id.length & 0x00FF); + PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->client_id.string, + conn->client_id.length); + if(conn->connect_vhdr_flags & MQTT_VHDR_WILL_FLAG) { + PT_MQTT_WRITE_BYTE(conn, conn->will.topic.length << 8); + PT_MQTT_WRITE_BYTE(conn, conn->will.topic.length & 0x00FF); + PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->will.topic.string, + conn->will.topic.length); + PT_MQTT_WRITE_BYTE(conn, conn->will.message.length << 8); + PT_MQTT_WRITE_BYTE(conn, conn->will.message.length & 0x00FF); + PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->will.message.string, + conn->will.message.length); + DBG("MQTT - Setting will topic to '%s' %u bytes and message to '%s' %u bytes\n", + conn->will.topic.string, + conn->will.topic.length, + conn->will.message.string, + conn->will.message.length); + } + if(conn->connect_vhdr_flags & MQTT_VHDR_USERNAME_FLAG) { + PT_MQTT_WRITE_BYTE(conn, conn->credentials.username.length << 8); + PT_MQTT_WRITE_BYTE(conn, conn->credentials.username.length & 0x00FF); + PT_MQTT_WRITE_BYTES(conn, + (uint8_t *)conn->credentials.username.string, + conn->credentials.username.length); + } + if(conn->connect_vhdr_flags & MQTT_VHDR_PASSWORD_FLAG) { + PT_MQTT_WRITE_BYTE(conn, conn->credentials.password.length << 8); + PT_MQTT_WRITE_BYTE(conn, conn->credentials.password.length & 0x00FF); + PT_MQTT_WRITE_BYTES(conn, + (uint8_t *)conn->credentials.password.string, + conn->credentials.password.length); + } + + /* Send out buffer */ + send_out_buffer(conn); + conn->state = MQTT_CONN_STATE_CONNECTING_TO_BROKER; + + timer_set(&conn->t, RESPONSE_WAIT_TIMEOUT); + + /* Wait for CONNACK */ + reset_packet(&conn->in_packet); + PT_WAIT_UNTIL(pt, conn->out_packet.qos_state == MQTT_QOS_STATE_GOT_ACK || + timer_expired(&conn->t)); + if(timer_expired(&conn->t)) { + DBG("Timeout waiting for CONNACK\n"); + /* We stick to the letter of the spec here: Tear the connection down */ + mqtt_disconnect(conn); + } + reset_packet(&conn->in_packet); + + DBG("MQTT - Done sending CONNECT\n"); + +#if DEBUG_MQTT == 1 + DBG("MQTT - CONNECT message sent: \n"); + uint16_t i; + for(i = 0; i < (conn->out_buffer_ptr - conn->out_buffer); i++) { + DBG("%02X ", conn->out_buffer[i]); + } + DBG("\n"); +#endif + + PT_END(pt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(disconnect_pt(struct pt *pt, struct mqtt_connection *conn)) +{ + PT_BEGIN(pt); + + PT_MQTT_WRITE_BYTE(conn, MQTT_FHDR_MSG_TYPE_DISCONNECT); + PT_MQTT_WRITE_BYTE(conn, 0); + + send_out_buffer(conn); + + /* + * Wait a couple of seconds for a TCP ACK. We don't really need the ACK, + * we do want the TCP/IP stack to actually send this disconnect before we + * tear down the session. + */ + timer_set(&conn->t, (CLOCK_SECOND * 2)); + PT_WAIT_UNTIL(pt, conn->out_buffer_sent || timer_expired(&conn->t)); + + PT_END(pt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(subscribe_pt(struct pt *pt, struct mqtt_connection *conn)) +{ + PT_BEGIN(pt); + + DBG("MQTT - Sending subscribe message! topic %s topic_length %i\n", + conn->out_packet.topic, + conn->out_packet.topic_length); + DBG("MQTT - Buffer space is %i \n", + &conn->out_buffer[MQTT_TCP_OUTPUT_BUFF_SIZE] - conn->out_buffer_ptr); + + /* Set up FHDR */ + conn->out_packet.fhdr = MQTT_FHDR_MSG_TYPE_SUBSCRIBE | MQTT_FHDR_QOS_LEVEL_1; + conn->out_packet.remaining_length = MQTT_MID_SIZE + + MQTT_STRING_LEN_SIZE + + conn->out_packet.topic_length + + MQTT_QOS_SIZE; + encode_remaining_length(conn->out_packet.remaining_length_enc, + &conn->out_packet.remaining_length_enc_bytes, + conn->out_packet.remaining_length); + if(conn->out_packet.remaining_length_enc_bytes > 4) { + call_event(conn, MQTT_EVENT_PROTOCOL_ERROR, NULL); + PRINTF("MQTT - Error, remaining length > 4 bytes\n"); + PT_EXIT(pt); + } + + /* Write Fixed Header */ + PT_MQTT_WRITE_BYTE(conn, conn->out_packet.fhdr); + PT_MQTT_WRITE_BYTES(conn, + conn->out_packet.remaining_length_enc, + conn->out_packet.remaining_length_enc_bytes); + /* Write Variable Header */ + PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid << 8)); + PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid & 0x00FF)); + /* Write Payload */ + PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length >> 8)); + PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length & 0x00FF)); + PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->out_packet.topic, + conn->out_packet.topic_length); + PT_MQTT_WRITE_BYTE(conn, conn->out_packet.qos); + + /* Send out buffer */ + send_out_buffer(conn); + timer_set(&conn->t, RESPONSE_WAIT_TIMEOUT); + + /* Wait for SUBACK. */ + reset_packet(&conn->in_packet); + PT_WAIT_UNTIL(pt, conn->out_packet.qos_state == MQTT_QOS_STATE_GOT_ACK || + timer_expired(&conn->t)); + + if(timer_expired(&conn->t)) { + DBG("Timeout waiting for SUBACK\n"); + } + reset_packet(&conn->in_packet); + + /* This is clear after the entire transaction is complete */ + conn->out_queue_full = 0; + + DBG("MQTT - Done in send_subscribe!\n"); + + PT_END(pt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(unsubscribe_pt(struct pt *pt, struct mqtt_connection *conn)) +{ + PT_BEGIN(pt); + + DBG("MQTT - Sending unsubscribe message on topic %s topic_length %i\n", + conn->out_packet.topic, + conn->out_packet.topic_length); + DBG("MQTT - Buffer space is %i \n", + &conn->out_buffer[MQTT_TCP_OUTPUT_BUFF_SIZE] - conn->out_buffer_ptr); + + /* Set up FHDR */ + conn->out_packet.fhdr = MQTT_FHDR_MSG_TYPE_UNSUBSCRIBE | + MQTT_FHDR_QOS_LEVEL_1; + conn->out_packet.remaining_length = MQTT_MID_SIZE + + MQTT_STRING_LEN_SIZE + + conn->out_packet.topic_length; + encode_remaining_length(conn->out_packet.remaining_length_enc, + &conn->out_packet.remaining_length_enc_bytes, + conn->out_packet.remaining_length); + if(conn->out_packet.remaining_length_enc_bytes > 4) { + call_event(conn, MQTT_EVENT_PROTOCOL_ERROR, NULL); + PRINTF("MQTT - Error, remaining length > 4 bytes\n"); + PT_EXIT(pt); + } + + /* Write Fixed Header */ + PT_MQTT_WRITE_BYTE(conn, conn->out_packet.fhdr); + PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->out_packet.remaining_length_enc, + conn->out_packet.remaining_length_enc_bytes); + /* Write Variable Header */ + PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid << 8)); + PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid & 0x00FF)); + /* Write Payload */ + PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length >> 8)); + PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length & 0x00FF)); + PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->out_packet.topic, + conn->out_packet.topic_length); + + /* Send out buffer */ + send_out_buffer(conn); + timer_set(&conn->t, RESPONSE_WAIT_TIMEOUT); + + /* Wait for UNSUBACK */ + reset_packet(&conn->in_packet); + PT_WAIT_UNTIL(pt, conn->out_packet.qos_state == MQTT_QOS_STATE_GOT_ACK || + timer_expired(&conn->t)); + + if(timer_expired(&conn->t)) { + DBG("Timeout waiting for UNSUBACK\n"); + } + + reset_packet(&conn->in_packet); + + /* This is clear after the entire transaction is complete */ + conn->out_queue_full = 0; + + DBG("MQTT - Done writing subscribe message to out buffer!\n"); + + PT_END(pt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(publish_pt(struct pt *pt, struct mqtt_connection *conn)) +{ + PT_BEGIN(pt); + + DBG("MQTT - Sending publish message! topic %s topic_length %i\n", + conn->out_packet.topic, + conn->out_packet.topic_length); + DBG("MQTT - Buffer space is %i \n", + &conn->out_buffer[MQTT_TCP_OUTPUT_BUFF_SIZE] - conn->out_buffer_ptr); + + /* Set up FHDR */ + conn->out_packet.fhdr = MQTT_FHDR_MSG_TYPE_PUBLISH | + conn->out_packet.qos << 1; + if(conn->out_packet.retain == MQTT_RETAIN_ON) { + conn->out_packet.fhdr |= MQTT_FHDR_RETAIN_FLAG; + } + conn->out_packet.remaining_length = MQTT_STRING_LEN_SIZE + + conn->out_packet.topic_length + + conn->out_packet.payload_size; + if(conn->out_packet.qos > MQTT_QOS_LEVEL_0) { + conn->out_packet.remaining_length += MQTT_MID_SIZE; + } + encode_remaining_length(conn->out_packet.remaining_length_enc, + &conn->out_packet.remaining_length_enc_bytes, + conn->out_packet.remaining_length); + if(conn->out_packet.remaining_length_enc_bytes > 4) { + call_event(conn, MQTT_EVENT_PROTOCOL_ERROR, NULL); + PRINTF("MQTT - Error, remaining length > 4 bytes\n"); + PT_EXIT(pt); + } + + /* Write Fixed Header */ + PT_MQTT_WRITE_BYTE(conn, conn->out_packet.fhdr); + PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->out_packet.remaining_length_enc, + conn->out_packet.remaining_length_enc_bytes); + /* Write Variable Header */ + PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length >> 8)); + PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length & 0x00FF)); + PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->out_packet.topic, + conn->out_packet.topic_length); + if(conn->out_packet.qos > MQTT_QOS_LEVEL_0) { + PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid << 8)); + PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid & 0x00FF)); + } + /* Write Payload */ + PT_MQTT_WRITE_BYTES(conn, + conn->out_packet.payload, + conn->out_packet.payload_size); + + send_out_buffer(conn); + timer_set(&conn->t, RESPONSE_WAIT_TIMEOUT); + + /* + * If QoS is zero then wait until the message has been sent, since there is + * no ACK to wait for. + * + * Also notify the app will not be notified via PUBACK or PUBCOMP + */ + if(conn->out_packet.qos == 0) { + process_post(conn->app_process, mqtt_update_event, NULL); + } else if(conn->out_packet.qos == 1) { + /* Wait for PUBACK */ + reset_packet(&conn->in_packet); + PT_WAIT_UNTIL(pt, conn->out_packet.qos_state == MQTT_QOS_STATE_GOT_ACK || + timer_expired(&conn->t)); + if(timer_expired(&conn->t)) { + DBG("Timeout waiting for PUBACK\n"); + } + if(conn->in_packet.mid != conn->out_packet.mid) { + DBG("MQTT - Warning, got PUBACK with none matching MID. Currently there " + "is no support for several concurrent PUBLISH messages.\n"); + } + } else if(conn->out_packet.qos == 2) { + DBG("MQTT - QoS not implemented yet.\n"); + /* Should wait for PUBREC, send PUBREL and then wait for PUBCOMP */ + } + + reset_packet(&conn->in_packet); + + /* This is clear after the entire transaction is complete */ + conn->out_queue_full = 0; + + DBG("MQTT - Publish Enqueued\n"); + + PT_END(pt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(pingreq_pt(struct pt *pt, struct mqtt_connection *conn)) +{ + PT_BEGIN(pt); + + DBG("MQTT - Sending PINGREQ\n"); + + /* Write Fixed Header */ + PT_MQTT_WRITE_BYTE(conn, MQTT_FHDR_MSG_TYPE_PINGREQ); + PT_MQTT_WRITE_BYTE(conn, 0); + + send_out_buffer(conn); + + /* Start timeout for reply. */ + conn->waiting_for_pingresp = 1; + + /* Wait for PINGRESP or timeout */ + reset_packet(&conn->in_packet); + timer_set(&conn->t, RESPONSE_WAIT_TIMEOUT); + + PT_WAIT_UNTIL(pt, conn->in_packet.packet_received || timer_expired(&conn->t)); + + reset_packet(&conn->in_packet); + + conn->waiting_for_pingresp = 0; + + PT_END(pt); +} +/*---------------------------------------------------------------------------*/ +static void +handle_connack(struct mqtt_connection *conn) +{ + DBG("MQTT - Got CONNACK\n"); + + if(conn->in_packet.payload[1] != 0) { + PRINTF("MQTT - Connection refused with Return Code %i\n", + conn->in_packet.payload[1]); + call_event(conn, + MQTT_EVENT_CONNECTION_REFUSED_ERROR, + &conn->in_packet.payload[1]); + } + + conn->out_packet.qos_state = MQTT_QOS_STATE_GOT_ACK; + + ctimer_set(&conn->keep_alive_timer, conn->keep_alive * CLOCK_SECOND, + keep_alive_callback, conn); + + /* Always reset packet before callback since it might be used directly */ + conn->state = MQTT_CONN_STATE_CONNECTED_TO_BROKER; + call_event(conn, MQTT_EVENT_CONNECTED, NULL); +} +/*---------------------------------------------------------------------------*/ +static void +handle_pingresp(struct mqtt_connection *conn) +{ + DBG("MQTT - Got RINGRESP\n"); +} +/*---------------------------------------------------------------------------*/ +static void +handle_suback(struct mqtt_connection *conn) +{ + struct mqtt_suback_event suback_event; + + DBG("MQTT - Got SUBACK\n"); + + /* Only accept SUBACKS with X topic QoS response, assume 1 */ + if(conn->in_packet.remaining_length > MQTT_MID_SIZE + + MQTT_MAX_TOPICS_PER_SUBSCRIBE * MQTT_QOS_SIZE) { + DBG("MQTT - Error, SUBACK with > 1 topic, not supported.\n"); + } + + conn->out_packet.qos_state = MQTT_QOS_STATE_GOT_ACK; + + suback_event.mid = (conn->in_packet.payload[0] << 8) | + (conn->in_packet.payload[1]); + suback_event.qos_level = conn->in_packet.payload[2]; + conn->in_packet.mid = suback_event.mid; + + if(conn->in_packet.mid != conn->out_packet.mid) { + DBG("MQTT - Warning, got SUBACK with none matching MID. Currently there is" + "no support for several concurrent SUBSCRIBE messages.\n"); + } + + /* Always reset packet before callback since it might be used directly */ + call_event(conn, MQTT_EVENT_SUBACK, &suback_event); +} +/*---------------------------------------------------------------------------*/ +static void +handle_unsuback(struct mqtt_connection *conn) +{ + DBG("MQTT - Got UNSUBACK\n"); + + conn->out_packet.qos_state = MQTT_QOS_STATE_GOT_ACK; + conn->in_packet.mid = (conn->in_packet.payload[0] << 8) | + (conn->in_packet.payload[1]); + + if(conn->in_packet.mid != conn->out_packet.mid) { + DBG("MQTT - Warning, got UNSUBACK with none matching MID. Currently there is" + "no support for several concurrent UNSUBSCRIBE messages.\n"); + } + + call_event(conn, MQTT_EVENT_UNSUBACK, &conn->in_packet.mid); +} +/*---------------------------------------------------------------------------*/ +static void +handle_puback(struct mqtt_connection *conn) +{ + DBG("MQTT - Got PUBACK\n"); + + conn->out_packet.qos_state = MQTT_QOS_STATE_GOT_ACK; + conn->in_packet.mid = (conn->in_packet.payload[0] << 8) | + (conn->in_packet.payload[1]); + + call_event(conn, MQTT_EVENT_PUBACK, &conn->in_packet.mid); +} +/*---------------------------------------------------------------------------*/ +static void +handle_publish(struct mqtt_connection *conn) +{ + DBG("MQTT - Got PUBLISH, called once per manageable chunk of message.\n"); + DBG("MQTT - Handling publish on topic '%s'\n", conn->in_publish_msg.topic); + + DBG("MQTT - This chunk is %i bytes\n", conn->in_packet.payload_pos); + + if(((conn->in_packet.fhdr & 0x09) >> 1) > 0) { + PRINTF("MQTT - Error, got incoming PUBLISH with QoS > 0, not supported atm!\n"); + } + + call_event(conn, MQTT_EVENT_PUBLISH, &conn->in_publish_msg); + + if(conn->in_publish_msg.first_chunk == 1) { + conn->in_publish_msg.first_chunk = 0; + } + + /* If this is the last time handle_publish will be called, reset packet. */ + if(conn->in_publish_msg.payload_left == 0) { + + /* Check for QoS and initiate the reply, do not rely on the data in the + * in_packet being untouched. */ + + DBG("MQTT - (handle_publish) resetting packet.\n"); + reset_packet(&conn->in_packet); + } +} +/*---------------------------------------------------------------------------*/ +static void +parse_publish_vhdr(struct mqtt_connection *conn, + uint32_t *pos, + const uint8_t *input_data_ptr, + int input_data_len) +{ + uint16_t copy_bytes; + + /* Read out topic length */ + if(conn->in_packet.topic_len_received == 0) { + conn->in_packet.topic_len = (input_data_ptr[(*pos)++] << 8); + conn->in_packet.byte_counter++; + if(*pos >= input_data_len) { + return; + } + conn->in_packet.topic_len |= input_data_ptr[(*pos)++]; + conn->in_packet.byte_counter++; + conn->in_packet.topic_len_received = 1; + + DBG("MQTT - Read PUBLISH topic len %i\n", conn->in_packet.topic_len); + /* WARNING: Check here if TOPIC fits in payload area, otherwise error */ + } + + /* Read out topic */ + if(conn->in_packet.topic_len_received == 1 && + conn->in_packet.topic_received == 0) { + copy_bytes = MIN(conn->in_packet.topic_len - conn->in_packet.topic_pos, + input_data_len - *pos); + DBG("MQTT - topic_pos: %i copy_bytes: %i", conn->in_packet.topic_pos, + copy_bytes); + memcpy(&conn->in_publish_msg.topic[conn->in_packet.topic_pos], + &input_data_ptr[*pos], + copy_bytes); + (*pos) += copy_bytes; + conn->in_packet.byte_counter += copy_bytes; + conn->in_packet.topic_pos += copy_bytes; + + if(conn->in_packet.topic_len - conn->in_packet.topic_pos == 0) { + DBG("MQTT - Got topic '%s'", conn->in_publish_msg.topic); + conn->in_packet.topic_received = 1; + conn->in_publish_msg.topic[conn->in_packet.topic_pos] = '\0'; + conn->in_publish_msg.payload_length = + conn->in_packet.remaining_length - conn->in_packet.topic_len - 2; + conn->in_publish_msg.payload_left = conn->in_publish_msg.payload_length; + } + + /* Set this once per incomming publish message */ + conn->in_publish_msg.first_chunk = 1; + } +} +/*---------------------------------------------------------------------------*/ +static int +tcp_input(struct tcp_socket *s, + void *ptr, + const uint8_t *input_data_ptr, + int input_data_len) +{ + struct mqtt_connection *conn = ptr; + uint32_t pos = 0; + uint32_t copy_bytes = 0; + uint8_t byte; + + if(input_data_len == 0) { + return 0; + } + + if(conn->in_packet.packet_received) { + reset_packet(&conn->in_packet); + } + + DBG("tcp_input with %i bytes of data:\n", input_data_len); + + /* Read the fixed header field, if we do not have it */ + if(!conn->in_packet.fhdr) { + conn->in_packet.fhdr = input_data_ptr[pos++]; + conn->in_packet.byte_counter++; + + DBG("MQTT - Read VHDR '%02X'\n", conn->in_packet.fhdr); + + if(pos >= input_data_len) { + return 0; + } + } + + /* Read the Remaining Length field, if we do not have it */ + if(!conn->in_packet.has_remaining_length) { + do { + if(pos >= input_data_len) { + return 0; + } + + byte = input_data_ptr[pos++]; + conn->in_packet.byte_counter++; + conn->in_packet.remaining_length_bytes++; + DBG("MQTT - Read Remaining Length byte\n"); + + if(conn->in_packet.byte_counter > 5) { + call_event(conn, MQTT_EVENT_ERROR, NULL); + DBG("Received more then 4 byte 'remaining lenght'."); + return 0; + } + + conn->in_packet.remaining_length += + (byte & 127) * conn->in_packet.remaining_multiplier; + conn->in_packet.remaining_multiplier *= 128; + } while((byte & 128) != 0); + + DBG("MQTT - Finished reading remaining length byte\n"); + conn->in_packet.has_remaining_length = 1; + } + + /* + * Check for unsupported payload length. Will read all incoming data from the + * server in any case and then reset the packet. + * + * TODO: Decide if we, for example, want to disconnect instead. + */ + if((conn->in_packet.remaining_length > MQTT_INPUT_BUFF_SIZE) && + (conn->in_packet.fhdr & 0xF0) != MQTT_FHDR_MSG_TYPE_PUBLISH) { + + PRINTF("MQTT - Error, unsupported payload size for non-PUBLISH message\n"); + + conn->in_packet.byte_counter += input_data_len; + if(conn->in_packet.byte_counter >= + (MQTT_FHDR_SIZE + conn->in_packet.remaining_length)) { + conn->in_packet.packet_received = 1; + } + return 0; + } + + /* + * Supported payload, reads out both VHDR and Payload of all packets. + * + * Note: There will always be at least one byte left to read when we enter + * this loop. + */ + while(conn->in_packet.byte_counter < + (MQTT_FHDR_SIZE + conn->in_packet.remaining_length)) { + + if((conn->in_packet.fhdr & 0xF0) == MQTT_FHDR_MSG_TYPE_PUBLISH && + conn->in_packet.topic_received == 0) { + parse_publish_vhdr(conn, &pos, input_data_ptr, input_data_len); + } + + /* Read in as much as we can into the packet payload */ + copy_bytes = MIN(input_data_len - pos, + MQTT_INPUT_BUFF_SIZE - conn->in_packet.payload_pos); + DBG("- Copied %lu payload bytes\n", copy_bytes); + memcpy(&conn->in_packet.payload[conn->in_packet.payload_pos], + &input_data_ptr[pos], + copy_bytes); + conn->in_packet.byte_counter += copy_bytes; + conn->in_packet.payload_pos += copy_bytes; + pos += copy_bytes; + + uint8_t i; + DBG("MQTT - Copied bytes: \n"); + for(i = 0; i < copy_bytes; i++) { + DBG("%02X ", conn->in_packet.payload[i]); + } + DBG("\n"); + + /* Full buffer, shall only happen to PUBLISH messages. */ + if(MQTT_INPUT_BUFF_SIZE - conn->in_packet.payload_pos == 0) { + conn->in_publish_msg.payload_chunk = conn->in_packet.payload; + conn->in_publish_msg.payload_chunk_length = MQTT_INPUT_BUFF_SIZE; + conn->in_publish_msg.payload_left -= MQTT_INPUT_BUFF_SIZE; + + handle_publish(conn); + + conn->in_publish_msg.payload_chunk = conn->in_packet.payload; + conn->in_packet.payload_pos = 0; + } + + if(pos >= input_data_len && + (conn->in_packet.byte_counter < (MQTT_FHDR_SIZE + conn->in_packet.remaining_length))) { + return 0; + } + } + + /* Debug information */ + DBG("\n"); + /* Take care of input */ + DBG("MQTT - Finished reading packet!\n"); + /* What to return? */ + DBG("MQTT - total data was %i bytes of data. \n", + (MQTT_FHDR_SIZE + conn->in_packet.remaining_length)); + + /* Handle packet here. */ + switch(conn->in_packet.fhdr & 0xF0) { + case MQTT_FHDR_MSG_TYPE_CONNACK: + handle_connack(conn); + break; + case MQTT_FHDR_MSG_TYPE_PUBLISH: + /* This is the only or the last chunk of publish payload */ + conn->in_publish_msg.payload_chunk = conn->in_packet.payload; + conn->in_publish_msg.payload_chunk_length = conn->in_packet.payload_pos; + conn->in_publish_msg.payload_left = 0; + handle_publish(conn); + break; + case MQTT_FHDR_MSG_TYPE_PUBACK: + handle_puback(conn); + break; + case MQTT_FHDR_MSG_TYPE_SUBACK: + handle_suback(conn); + break; + case MQTT_FHDR_MSG_TYPE_UNSUBACK: + handle_unsuback(conn); + break; + case MQTT_FHDR_MSG_TYPE_PINGRESP: + handle_pingresp(conn); + break; + + /* QoS 2 not implemented yet */ + case MQTT_FHDR_MSG_TYPE_PUBREC: + case MQTT_FHDR_MSG_TYPE_PUBREL: + case MQTT_FHDR_MSG_TYPE_PUBCOMP: + call_event(conn, MQTT_EVENT_NOT_IMPLEMENTED_ERROR, NULL); + PRINTF("MQTT - Got unhandled MQTT Message Type '%i'", + (conn->in_packet.fhdr & 0xF0)); + break; + + default: + /* All server-only message */ + PRINTF("MQTT - Got MQTT Message Type '%i'", (conn->in_packet.fhdr & 0xF0)); + break; + } + + conn->in_packet.packet_received = 1; + + return 0; +} +/*---------------------------------------------------------------------------*/ +/* + * Handles TCP events from Simple TCP + */ +static void +tcp_event(struct tcp_socket *s, void *ptr, tcp_socket_event_t event) +{ + struct mqtt_connection *conn = ptr; + + /* Take care of event */ + switch(event) { + + /* Fall through to manage different disconnect event the same way. */ + case TCP_SOCKET_CLOSED: + case TCP_SOCKET_TIMEDOUT: + case TCP_SOCKET_ABORTED: { + + DBG("MQTT - Disconnected by tcp event %d\n", event); + process_post(&mqtt_process, mqtt_abort_now_event, conn); + conn->state = MQTT_CONN_STATE_NOT_CONNECTED; + ctimer_stop(&conn->keep_alive_timer); + call_event(conn, MQTT_EVENT_DISCONNECTED, &event); + abort_connection(conn); + + /* If connecting retry */ + if(conn->auto_reconnect == 1) { + connect_tcp(conn); + } + break; + } + case TCP_SOCKET_CONNECTED: { + conn->state = MQTT_CONN_STATE_TCP_CONNECTED; + conn->out_buffer_sent = 1; + + process_post(&mqtt_process, mqtt_do_connect_mqtt_event, conn); + break; + } + case TCP_SOCKET_DATA_SENT: { + DBG("MQTT - Got TCP_DATA_SENT\n"); + + if(conn->socket.output_data_len == 0) { + conn->out_buffer_sent = 1; + conn->out_buffer_ptr = conn->out_buffer; + } + + ctimer_restart(&conn->keep_alive_timer); + break; + } + + default: { + DBG("MQTT - TCP Event %d is currently not managed by the tcp event callback\n", + event); + } + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(mqtt_process, ev, data) +{ + static struct mqtt_connection *conn; + + PROCESS_BEGIN(); + + while(1) { + PROCESS_WAIT_EVENT(); + + if(ev == mqtt_abort_now_event) { + DBG("MQTT - Abort\n"); + conn = data; + conn->state = MQTT_CONN_STATE_ABORT_IMMEDIATE; + + abort_connection(conn); + } + if(ev == mqtt_do_connect_tcp_event) { + conn = data; + DBG("MQTT - Got mqtt_do_connect_tcp_event!\n"); + connect_tcp(conn); + } + if(ev == mqtt_do_connect_mqtt_event) { + conn = data; + conn->socket.output_data_max_seg = conn->max_segment_size; + DBG("MQTT - Got mqtt_do_connect_mqtt_event!\n"); + + if(conn->out_buffer_sent == 1) { + PT_INIT(&conn->out_proto_thread); + while(connect_pt(&conn->out_proto_thread, conn) < PT_EXITED && + conn->state != MQTT_CONN_STATE_ABORT_IMMEDIATE) { + PT_MQTT_WAIT_SEND(); + } + } + } + if(ev == mqtt_do_disconnect_mqtt_event) { + conn = data; + DBG("MQTT - Got mqtt_do_disconnect_mqtt_event!\n"); + + /* Send MQTT Disconnect if we are connected */ + if(conn->state == MQTT_CONN_STATE_SENDING_MQTT_DISCONNECT) { + if(conn->out_buffer_sent == 1) { + PT_INIT(&conn->out_proto_thread); + while(disconnect_pt(&conn->out_proto_thread, conn) < PT_EXITED && + conn->state != MQTT_CONN_STATE_ABORT_IMMEDIATE) { + PT_MQTT_WAIT_SEND(); + } + abort_connection(conn); + call_event(conn, MQTT_EVENT_DISCONNECTED, &ev); + } else { + process_post(&mqtt_process, mqtt_do_disconnect_mqtt_event, conn); + } + } + } + if(ev == mqtt_do_pingreq_event) { + conn = data; + DBG("MQTT - Got mqtt_do_pingreq_event!\n"); + + if(conn->out_buffer_sent == 1 && + conn->state == MQTT_CONN_STATE_CONNECTED_TO_BROKER) { + PT_INIT(&conn->out_proto_thread); + while(pingreq_pt(&conn->out_proto_thread, conn) < PT_EXITED && + conn->state == MQTT_CONN_STATE_CONNECTED_TO_BROKER) { + PT_MQTT_WAIT_SEND(); + } + } + } + if(ev == mqtt_do_subscribe_event) { + conn = data; + DBG("MQTT - Got mqtt_do_subscribe_mqtt_event!\n"); + + if(conn->out_buffer_sent == 1 && + conn->state == MQTT_CONN_STATE_CONNECTED_TO_BROKER) { + PT_INIT(&conn->out_proto_thread); + while(subscribe_pt(&conn->out_proto_thread, conn) < PT_EXITED && + conn->state == MQTT_CONN_STATE_CONNECTED_TO_BROKER) { + PT_MQTT_WAIT_SEND(); + } + } + } + if(ev == mqtt_do_unsubscribe_event) { + conn = data; + DBG("MQTT - Got mqtt_do_unsubscribe_mqtt_event!\n"); + + if(conn->out_buffer_sent == 1 && + conn->state == MQTT_CONN_STATE_CONNECTED_TO_BROKER) { + PT_INIT(&conn->out_proto_thread); + while(unsubscribe_pt(&conn->out_proto_thread, conn) < PT_EXITED && + conn->state == MQTT_CONN_STATE_CONNECTED_TO_BROKER) { + PT_MQTT_WAIT_SEND(); + } + } + } + if(ev == mqtt_do_publish_event) { + conn = data; + DBG("MQTT - Got mqtt_do_publish_mqtt_event!\n"); + + if(conn->out_buffer_sent == 1 && + conn->state == MQTT_CONN_STATE_CONNECTED_TO_BROKER) { + PT_INIT(&conn->out_proto_thread); + while(publish_pt(&conn->out_proto_thread, conn) < PT_EXITED && + conn->state == MQTT_CONN_STATE_CONNECTED_TO_BROKER) { + PT_MQTT_WAIT_SEND(); + } + } + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +void +mqtt_init(void) +{ + static uint8_t inited = 0; + if(!inited) { + mqtt_do_connect_tcp_event = process_alloc_event(); + mqtt_event_min = mqtt_do_connect_tcp_event; + + mqtt_do_connect_mqtt_event = process_alloc_event(); + mqtt_do_disconnect_mqtt_event = process_alloc_event(); + mqtt_do_subscribe_event = process_alloc_event(); + mqtt_do_unsubscribe_event = process_alloc_event(); + mqtt_do_publish_event = process_alloc_event(); + mqtt_do_pingreq_event = process_alloc_event(); + mqtt_update_event = process_alloc_event(); + mqtt_abort_now_event = process_alloc_event(); + mqtt_event_max = mqtt_abort_now_event; + + mqtt_continue_send_event = process_alloc_event(); + + list_init(mqtt_conn_list); + process_start(&mqtt_process, NULL); + inited = 1; + } +} +/*---------------------------------------------------------------------------*/ +mqtt_status_t +mqtt_register(struct mqtt_connection *conn, struct process *app_process, + char *client_id, mqtt_event_callback_t event_callback, + uint16_t max_segment_size) +{ + if(strlen(client_id) < 1) { + return MQTT_STATUS_INVALID_ARGS_ERROR; + } + + /* Set defaults - Set all to zero to begin with */ + memset(conn, 0, sizeof(struct mqtt_connection)); + string_to_mqtt_string(&conn->client_id, client_id); + conn->event_callback = event_callback; + conn->app_process = app_process; + conn->auto_reconnect = 1; + conn->max_segment_size = max_segment_size; + reset_defaults(conn); + + mqtt_init(); + list_add(mqtt_conn_list, conn); + + DBG("MQTT - Registered successfully\n"); + + return MQTT_STATUS_OK; +} +/*---------------------------------------------------------------------------*/ +/* + * Connect to MQTT broker. + * + * N.B. Non-blocking call. + */ +mqtt_status_t +mqtt_connect(struct mqtt_connection *conn, char *host, uint16_t port, + uint16_t keep_alive) +{ + uip_ip6addr_t ip6addr; + uip_ipaddr_t *ipaddr; + ipaddr = &ip6addr; + + /* Check if we are already trying to connect */ + if(conn->state > MQTT_CONN_STATE_NOT_CONNECTED) { + return MQTT_STATUS_OK; + } + + conn->server_host = host; + conn->keep_alive = keep_alive; + conn->server_port = port; + conn->out_buffer_ptr = conn->out_buffer; + conn->out_packet.qos_state = MQTT_QOS_STATE_NO_ACK; + conn->connect_vhdr_flags |= MQTT_VHDR_CLEAN_SESSION_FLAG; + + /* convert the string IPv6 address to a numeric IPv6 address */ + uiplib_ip6addrconv(host, &ip6addr); + + uip_ipaddr_copy(&(conn->server_ip), ipaddr); + + /* + * Initiate the connection if the IP could be resolved. Otherwise the + * connection will be initiated when the DNS lookup is finished, in the main + * event loop. + */ + process_post(&mqtt_process, mqtt_do_connect_tcp_event, conn); + + return MQTT_STATUS_OK; +} +/*----------------------------------------------------------------------------*/ +void +mqtt_disconnect(struct mqtt_connection *conn) +{ + if(conn->state != MQTT_CONN_STATE_CONNECTED_TO_BROKER) { + return; + } + + conn->state = MQTT_CONN_STATE_SENDING_MQTT_DISCONNECT; + + process_post(&mqtt_process, mqtt_do_disconnect_mqtt_event, conn); +} +/*----------------------------------------------------------------------------*/ +mqtt_status_t +mqtt_subscribe(struct mqtt_connection *conn, uint16_t *mid, char *topic, + mqtt_qos_level_t qos_level) +{ + if(conn->state != MQTT_CONN_STATE_CONNECTED_TO_BROKER) { + return MQTT_STATUS_NOT_CONNECTED_ERROR; + } + + DBG("MQTT - Call to mqtt_subscribe...\n"); + + /* Currently don't have a queue, so only one item at a time */ + if(conn->out_queue_full) { + DBG("MQTT - Not accepted!\n"); + return MQTT_STATUS_OUT_QUEUE_FULL; + } + conn->out_queue_full = 1; + DBG("MQTT - Accepted!\n"); + + conn->out_packet.mid = INCREMENT_MID(conn); + conn->out_packet.topic = topic; + conn->out_packet.topic_length = strlen(topic); + conn->out_packet.qos = qos_level; + conn->out_packet.qos_state = MQTT_QOS_STATE_NO_ACK; + + process_post(&mqtt_process, mqtt_do_subscribe_event, conn); + return MQTT_STATUS_OK; +} +/*----------------------------------------------------------------------------*/ +mqtt_status_t +mqtt_unsubscribe(struct mqtt_connection *conn, uint16_t *mid, char *topic) +{ + if(conn->state != MQTT_CONN_STATE_CONNECTED_TO_BROKER) { + return MQTT_STATUS_NOT_CONNECTED_ERROR; + } + + DBG("MQTT - Call to mqtt_unsubscribe...\n"); + /* Currently don't have a queue, so only one item at a time */ + if(conn->out_queue_full) { + DBG("MQTT - Not accepted!\n"); + return MQTT_STATUS_OUT_QUEUE_FULL; + } + conn->out_queue_full = 1; + DBG("MQTT - Accepted!\n"); + + conn->out_packet.mid = INCREMENT_MID(conn); + conn->out_packet.topic = topic; + conn->out_packet.topic_length = strlen(topic); + conn->out_packet.qos_state = MQTT_QOS_STATE_NO_ACK; + + process_post(&mqtt_process, mqtt_do_unsubscribe_event, conn); + return MQTT_STATUS_OK; +} +/*----------------------------------------------------------------------------*/ +mqtt_status_t +mqtt_publish(struct mqtt_connection *conn, uint16_t *mid, char *topic, + uint8_t *payload, uint32_t payload_size, + mqtt_qos_level_t qos_level, mqtt_retain_t retain) +{ + if(conn->state != MQTT_CONN_STATE_CONNECTED_TO_BROKER) { + return MQTT_STATUS_NOT_CONNECTED_ERROR; + } + + DBG("MQTT - Call to mqtt_publish...\n"); + + /* Currently don't have a queue, so only one item at a time */ + if(conn->out_queue_full) { + DBG("MQTT - Not accepted!\n"); + return MQTT_STATUS_OUT_QUEUE_FULL; + } + conn->out_queue_full = 1; + DBG("MQTT - Accepted!\n"); + + conn->out_packet.mid = INCREMENT_MID(conn); + conn->out_packet.retain = retain; + conn->out_packet.topic = topic; + conn->out_packet.topic_length = strlen(topic); + conn->out_packet.payload = payload; + conn->out_packet.payload_size = payload_size; + conn->out_packet.qos = qos_level; + conn->out_packet.qos_state = MQTT_QOS_STATE_NO_ACK; + + process_post(&mqtt_process, mqtt_do_publish_event, conn); + return MQTT_STATUS_OK; +} +/*----------------------------------------------------------------------------*/ +void +mqtt_set_username_password(struct mqtt_connection *conn, char *username, + char *password) +{ + /* Set strings, NULL string will simply set length to zero */ + string_to_mqtt_string(&conn->credentials.username, username); + string_to_mqtt_string(&conn->credentials.password, password); + + /* Set CONNECT VHDR flags */ + if(username != NULL) { + conn->connect_vhdr_flags |= MQTT_VHDR_USERNAME_FLAG; + } else { + conn->connect_vhdr_flags &= ~MQTT_VHDR_USERNAME_FLAG; + } + if(password != NULL) { + conn->connect_vhdr_flags |= MQTT_VHDR_PASSWORD_FLAG; + } else { + conn->connect_vhdr_flags &= ~MQTT_VHDR_PASSWORD_FLAG; + } +} +/*----------------------------------------------------------------------------*/ +void +mqtt_set_last_will(struct mqtt_connection *conn, char *topic, char *message, + mqtt_qos_level_t qos) +{ + /* Set strings, NULL string will simply set length to zero */ + string_to_mqtt_string(&conn->will.topic, topic); + string_to_mqtt_string(&conn->will.message, message); + + /* Currently not used! */ + conn->will.qos = qos; + + if(topic != NULL) { + conn->connect_vhdr_flags |= MQTT_VHDR_WILL_FLAG | + MQTT_VHDR_WILL_RETAIN_FLAG; + } +} +/*----------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/mqtt/mqtt.h b/apps/mqtt/mqtt.h new file mode 100644 index 000000000..4b27fa30c --- /dev/null +++ b/apps/mqtt/mqtt.h @@ -0,0 +1,509 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup apps + * @{ + * + * \defgroup mqtt-engine An implementation of MQTT v3.1 + * @{ + * + * This application is an engine for MQTT v3.1. It supports QoS Levels 0 and 1. + * + * MQTT is a Client Server publish/subscribe messaging transport protocol. + * It is light weight, open, simple, and designed so as to be easy to implement. + * These characteristics make it ideal for use in many situations, including + * constrained environments such as for communication in Machine to Machine + * (M2M) and Internet of Things (IoT) contexts where a small code footprint is + * required and/or network bandwidth is at a premium. + * + * The protocol runs over TCP/IP, more specifically tcp_socket. + * Its features include: + * + * - Use of the publish/subscribe message pattern which provides + * one-to-many message distribution and decoupling of applications. + * - A messaging transport that is agnostic to the content of the payload. + * Three qualities of service for message delivery: + * -- "At most once" (0), where messages are delivered according to the best + * efforts of the operating environment. Message loss can occur. + * This level could be used, for example, with ambient sensor data where it + * does not matter if an individual reading is lost as the next one will be + * published soon after. + * --"At least once" (1), where messages are assured to arrive but duplicates + * can occur. + * -- "Exactly once" (2), where message are assured to arrive exactly once. + * This level could be used, for example, with billing systems where duplicate + * or lost messages could lead to incorrect charges being applied. This QoS + * level is currently not supported in this implementation. + * + * - A small transport overhead and protocol exchanges minimized to reduce + * network traffic. + * - A mechanism, Last Will, to notify interested parties when an abnormal + * disconnection occurs. + * + * The protocol specification and other useful information can be found + * here: http://mqtt.org + * + */ +/** + * \file + * Header file for the Contiki MQTT engine + * + * \author + * Texas Instruments + */ +/*---------------------------------------------------------------------------*/ +#ifndef MQTT_H_ +#define MQTT_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "contiki-net.h" +#include "contiki-lib.h" +#include "lib/random.h" +#include "sys/ctimer.h" +#include "sys/etimer.h" +#include "net/rpl/rpl.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "dev/leds.h" + +#include "tcp-socket.h" +#include "udp-socket.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +/* Protocol constants */ +#define MQTT_CLIENT_ID_MAX_LEN 23 + +/* Size of the underlying TCP buffers */ +#define MQTT_TCP_INPUT_BUFF_SIZE 512 +#define MQTT_TCP_OUTPUT_BUFF_SIZE 512 + +#define MQTT_INPUT_BUFF_SIZE 512 +#define MQTT_MAX_TOPIC_LENGTH 64 +#define MQTT_MAX_TOPICS_PER_SUBSCRIBE 1 + +#define MQTT_FHDR_SIZE 1 +#define MQTT_MAX_REMAINING_LENGTH_BYTES 4 +#define MQTT_PROTOCOL_VERSION 3 +#define MQTT_PROTOCOL_NAME "MQIsdp" +#define MQTT_TOPIC_MAX_LENGTH 128 +/*---------------------------------------------------------------------------*/ +/* + * Debug configuration, this is similar but not exactly like the Debugging + * System discussion at https://github.com/contiki-os/contiki/wiki. + */ +#define DEBUG_MQTT 0 + +#if DEBUG_MQTT == 1 +#define DBG(...) printf(__VA_ARGS__) +#else +#define DBG(...) +#endif /* DEBUG */ +/*---------------------------------------------------------------------------*/ +extern process_event_t mqtt_update_event; + +/* Forward declaration */ +struct mqtt_connection; + +typedef enum { + MQTT_RETAIN_OFF, + MQTT_RETAIN_ON, +} mqtt_retain_t; + +/** + * \brief MQTT engine events + */ +typedef enum { + MQTT_EVENT_CONNECTED, + MQTT_EVENT_DISCONNECTED, + + MQTT_EVENT_SUBACK, + MQTT_EVENT_UNSUBACK, + MQTT_EVENT_PUBLISH, + MQTT_EVENT_PUBACK, + + /* Errors */ + MQTT_EVENT_ERROR = 0x80, + MQTT_EVENT_PROTOCOL_ERROR, + MQTT_EVENT_CONNECTION_REFUSED_ERROR, + MQTT_EVENT_DNS_ERROR, + MQTT_EVENT_NOT_IMPLEMENTED_ERROR, + /* Add more */ +} mqtt_event_t; + +typedef enum { + MQTT_STATUS_OK, + + MQTT_STATUS_OUT_QUEUE_FULL, + + /* Errors */ + MQTT_STATUS_ERROR = 0x80, + MQTT_STATUS_NOT_CONNECTED_ERROR, + MQTT_STATUS_INVALID_ARGS_ERROR, + MQTT_STATUS_DNS_ERROR, +} mqtt_status_t; + +typedef enum { + MQTT_QOS_LEVEL_0, + MQTT_QOS_LEVEL_1, + MQTT_QOS_LEVEL_2, +} mqtt_qos_level_t; + +typedef enum { + MQTT_QOS_STATE_NO_ACK, + MQTT_QOS_STATE_GOT_ACK, + + /* Expand for QoS 2 */ +} mqtt_qos_state_t; +/*---------------------------------------------------------------------------*/ +/* + * This is the state of the connection itself. + * + * N.B. The order is important because of runtime checks on how far the + * connection has proceeded. + */ +typedef enum { + MQTT_CONN_STATE_ERROR, + MQTT_CONN_STATE_DNS_ERROR, + MQTT_CONN_STATE_DISCONNECTING, + + MQTT_CONN_STATE_NOT_CONNECTED, + MQTT_CONN_STATE_DNS_LOOKUP, + MQTT_CONN_STATE_TCP_CONNECTING, + MQTT_CONN_STATE_TCP_CONNECTED, + MQTT_CONN_STATE_CONNECTING_TO_BROKER, + MQTT_CONN_STATE_CONNECTED_TO_BROKER, + MQTT_CONN_STATE_SENDING_MQTT_DISCONNECT, + MQTT_CONN_STATE_ABORT_IMMEDIATE, +} mqtt_conn_state_t; +/*---------------------------------------------------------------------------*/ +struct mqtt_string { + char *string; + uint16_t length; +}; + +/* + * Note that the pairing mid <-> QoS level only applies one-to-one if we only + * allow the subscription of one topic at a time. Otherwise we will have an + * ordered list of QoS levels corresponding to the order of topics. + * + * This could be part of a union of event data structures. + */ +struct mqtt_suback_event { + uint16_t mid; + mqtt_qos_level_t qos_level; +}; + +/* This is the MQTT message that is exposed to the end user. */ +struct mqtt_message { + uint32_t mid; + char topic[MQTT_MAX_TOPIC_LENGTH + 1]; /* +1 for string termination */ + + uint8_t *payload_chunk; + uint16_t payload_chunk_length; + + uint8_t first_chunk; + uint16_t payload_length; + uint16_t payload_left; +}; + +/* This struct represents a packet received from the MQTT server. */ +struct mqtt_in_packet { + /* Used by the list interface, must be first in the struct. */ + struct mqtt_connection *next; + + /* Total bytes read so far. Compared to the remaining length to to decide when + * we've read the payload. */ + uint32_t byte_counter; + uint8_t packet_received; + + uint8_t fhdr; + uint16_t remaining_length; + uint16_t mid; + + /* Helper variables needed to decode the remaining_length */ + uint8_t remaining_multiplier; + uint8_t has_remaining_length; + uint8_t remaining_length_bytes; + + /* Not the same as payload in the MQTT sense, it also contains the variable + * header. + */ + uint8_t payload_pos; + uint8_t payload[MQTT_INPUT_BUFF_SIZE]; + + /* Message specific data */ + uint16_t topic_len; + uint16_t topic_pos; + uint8_t topic_len_received; + uint8_t topic_received; +}; + +/* This struct represents a packet sent to the MQTT server. */ +struct mqtt_out_packet { + uint8_t fhdr; + uint32_t remaining_length; + uint8_t remaining_length_enc[MQTT_MAX_REMAINING_LENGTH_BYTES]; + uint8_t remaining_length_enc_bytes; + uint16_t mid; + char *topic; + uint16_t topic_length; + uint8_t *payload; + uint32_t payload_size; + mqtt_qos_level_t qos; + mqtt_qos_state_t qos_state; + mqtt_retain_t retain; +}; +/*---------------------------------------------------------------------------*/ +/** + * \brief MQTT event callback function + * \param m A pointer to a MQTT connection + * \param event The event number + * \param data A user-defined pointer + * + * The MQTT socket event callback function gets called whenever there is an + * event on a MQTT connection, such as the connection getting connected + * or closed. + */ +typedef void (*mqtt_event_callback_t)(struct mqtt_connection *m, + mqtt_event_t event, + void *data); + +typedef void (*mqtt_topic_callback_t)(struct mqtt_connection *m, + struct mqtt_message *msg); +/*---------------------------------------------------------------------------*/ +struct mqtt_will { + struct mqtt_string topic; + struct mqtt_string message; + mqtt_qos_level_t qos; +}; + +struct mqtt_credentials { + struct mqtt_string username; + struct mqtt_string password; +}; + +struct mqtt_connection { + /* Used by the list interface, must be first in the struct */ + struct mqtt_connection *next; + struct timer t; + + struct mqtt_string client_id; + + uint8_t connect_vhdr_flags; + uint8_t auto_reconnect; + + uint16_t keep_alive; + struct ctimer keep_alive_timer; + uint8_t waiting_for_pingresp; + + struct mqtt_will will; + struct mqtt_credentials credentials; + + mqtt_conn_state_t state; + mqtt_event_callback_t event_callback; + + /* Internal data */ + uint16_t mid_counter; + + /* Used for communication between MQTT API and APP */ + uint8_t out_queue_full; + struct process *app_process; + + /* Outgoing data related */ + uint8_t *out_buffer_ptr; + uint8_t out_buffer[MQTT_TCP_OUTPUT_BUFF_SIZE]; + uint8_t out_buffer_sent; + struct mqtt_out_packet out_packet; + struct pt out_proto_thread; + uint32_t out_write_pos; + uint16_t max_segment_size; + + /* Incoming data related */ + uint8_t in_buffer[MQTT_TCP_INPUT_BUFF_SIZE]; + struct mqtt_in_packet in_packet; + struct mqtt_message in_publish_msg; + + /* TCP related information */ + char *server_host; + uip_ipaddr_t server_ip; + uint16_t server_port; + struct tcp_socket socket; +}; +/* This is the API exposed to the user. */ +/*---------------------------------------------------------------------------*/ +/** + * \brief Initializes the MQTT engine. + * \param conn A pointer to the MQTT connection. + * \param app_process A pointer to the application process handling the MQTT + * connection. + * \param client_id A pointer to the MQTT client ID. + * \param event_callback Callback function responsible for handling the + * callback from MQTT engine. + * \param max_segment_size The TCP segment size to use for this MQTT/TCP + * connection. + * \return MQTT_STATUS_OK or MQTT_STATUS_INVALID_ARGS_ERROR + * + * This function initializes the MQTT engine and shall be called before any + * other MQTT function. + */ +mqtt_status_t mqtt_register(struct mqtt_connection *conn, + struct process *app_process, + char *client_id, + mqtt_event_callback_t event_callback, + uint16_t max_segment_size); +/*---------------------------------------------------------------------------*/ +/** + * \brief Connects to a MQTT broker. + * \param conn A pointer to the MQTT connection. + * \param host IP address of the broker to connect to. + * \param port Port of the broker to connect to, default is MQTT port is 1883. + * \param keep_alive Keep alive timer in seconds. Used by broker to handle + * client disc. Defines the maximum time interval between two messages + * from the client. Shall be min 1.5 x report interval. + * \return MQTT_STATUS_OK or an error status + * + * This function connects to a MQTT broker. + */ +mqtt_status_t mqtt_connect(struct mqtt_connection *conn, + char *host, + uint16_t port, + uint16_t keep_alive); +/*---------------------------------------------------------------------------*/ +/** + * \brief Disconnects from a MQTT broker. + * \param conn A pointer to the MQTT connection. + * + * This function disconnects from a MQTT broker. + */ +void mqtt_disconnect(struct mqtt_connection *conn); +/*---------------------------------------------------------------------------*/ +/** + * \brief Subscribes to a MQTT topic. + * \param conn A pointer to the MQTT connection. + * \param mid A pointer to message ID. + * \param topic A pointer to the topic to subscribe to. + * \param qos_level Quality Of Service level to use. Currently supports 0, 1. + * \return MQTT_STATUS_OK or some error status + * + * This function subscribes to a topic on a MQTT broker. + */ +mqtt_status_t mqtt_subscribe(struct mqtt_connection *conn, + uint16_t *mid, + char *topic, + mqtt_qos_level_t qos_level); +/*---------------------------------------------------------------------------*/ +/** + * \brief Unsubscribes from a MQTT topic. + * \param conn A pointer to the MQTT connection. + * \param mid A pointer to message ID. + * \param topic A pointer to the topic to unsubscribe from. + * \return MQTT_STATUS_OK or some error status + * + * This function unsubscribes from a topic on a MQTT broker. + */ +mqtt_status_t mqtt_unsubscribe(struct mqtt_connection *conn, + uint16_t *mid, + char *topic); +/*---------------------------------------------------------------------------*/ +/** + * \brief Publish to a MQTT topic. + * \param conn A pointer to the MQTT connection. + * \param mid A pointer to message ID. + * \param topic A pointer to the topic to subscribe to. + * \param payload A pointer to the topic payload. + * \param payload_size Payload size. + * \param qos_level Quality Of Service level to use. Currently supports 0, 1. + * \param retain If the RETAIN flag is set to 1, in a PUBLISH Packet sent by a + * Client to a Server, the Server MUST store the Application Message + * and its QoS, so that it can be delivered to future subscribers whose + * subscriptions match its topic name + * \return MQTT_STATUS_OK or some error status + * + * This function publishes to a topic on a MQTT broker. + */ +mqtt_status_t mqtt_publish(struct mqtt_connection *conn, + uint16_t *mid, + char *topic, + uint8_t *payload, + uint32_t payload_size, + mqtt_qos_level_t qos_level, + mqtt_retain_t retain); +/*---------------------------------------------------------------------------*/ +/** + * \brief Set the user name and password for a MQTT client. + * \param conn A pointer to the MQTT connection. + * \param username A pointer to the user name. + * \param password A pointer to the password. + * + * This function sets clients user name and password to use when connecting to + * a MQTT broker. + */ +void mqtt_set_username_password(struct mqtt_connection *conn, + char *username, + char *password); +/*---------------------------------------------------------------------------*/ +/** + * \brief Set the last will topic and message for a MQTT client. + * \param conn A pointer to the MQTT connection. + * \param topic A pointer to the Last Will topic. + * \param message A pointer to the Last Will message (payload). + * \param qos The desired QoS level. + * + * This function sets clients Last Will topic and message (payload). + * If the Will Flag is set to 1 (using the function) this indicates that, + * if the Connect request is accepted, a Will Message MUST be stored on the + * Server and associated with the Network Connection. The Will Message MUST + * be published when the Network Connection is subsequently closed. + * + * This functionality can be used to get notified that a device has + * disconnected from the broker. + * + */ +void mqtt_set_last_will(struct mqtt_connection *conn, + char *topic, + char *message, + mqtt_qos_level_t qos); + +#define mqtt_connected(conn) \ + ((conn)->state == MQTT_CONN_STATE_CONNECTED_TO_BROKER ? 1 : 0) + +#define mqtt_ready(conn) \ + (!(conn)->out_queue_full && mqtt_connected((conn))) +/*---------------------------------------------------------------------------*/ +#endif /* MQTT_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/apps/netconf/netconf.c b/apps/netconf/netconf.c index 8249d35ec..b7a81fb99 100644 --- a/apps/netconf/netconf.c +++ b/apps/netconf/netconf.c @@ -113,7 +113,7 @@ makestrings(void) makeaddr(&addr, gateway); #if UIP_UDP - addrptr = resolv_getserver(); + addrptr = uip_nameserver_get(0); if(addrptr != NULL) { makeaddr(addrptr, dnsserver); } @@ -152,7 +152,7 @@ apply_tcpipconfig(void) #if UIP_UDP nullterminate(dnsserver); if(uiplib_ipaddrconv(dnsserver, &addr)) { - resolv_conf(&addr); + uip_nameserver_update(&addr, UIP_NAMESERVER_INFINITE_LIFETIME); } #endif /* UIP_UDP */ } diff --git a/apps/oma-lwm2m/Makefile.oma-lwm2m b/apps/oma-lwm2m/Makefile.oma-lwm2m new file mode 100644 index 000000000..000147939 --- /dev/null +++ b/apps/oma-lwm2m/Makefile.oma-lwm2m @@ -0,0 +1,13 @@ +oma-lwm2m_src = \ + lwm2m-object.c \ + lwm2m-engine.c \ + lwm2m-device.c \ + lwm2m-server.c \ + lwm2m-security.c \ + oma-tlv.c \ + oma-tlv-reader.c \ + oma-tlv-writer.c \ + lwm2m-plain-text.c \ + lwm2m-json.c \ + # +CFLAGS += -DHAVE_OMA_LWM2M=1 diff --git a/apps/oma-lwm2m/lwm2m-device.c b/apps/oma-lwm2m/lwm2m-device.c new file mode 100644 index 000000000..a911c7c4a --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-device.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M device + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "lwm2m-object.h" +#include "lwm2m-device.h" +#include "lwm2m-engine.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +static int32_t time_offset = 0; +/*---------------------------------------------------------------------------*/ +static int +read_lwtime(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + return ctx->writer->write_int(ctx, outbuf, outsize, + time_offset + clock_seconds()); +} +/*---------------------------------------------------------------------------*/ +static int +set_lwtime(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize, + uint8_t *outbuf, size_t outsize) +{ + /* assume that this only read one TLV value */ + int32_t lw_time; + size_t len = ctx->reader->read_int(ctx, inbuf, insize, &lw_time); + if(len == 0) { + PRINTF("FAIL: could not read time '%*.s'\n", (int)insize, inbuf); + } else { + PRINTF("Got: time: %*.s => %" PRId32 "\n", (int)insize, inbuf, lw_time); + + time_offset = lw_time - clock_seconds(); + PRINTF("Write time...%" PRId32 " => offset = %" PRId32 "\n", + lw_time, time_offset); + } + /* return the number of bytes read */ + return len; +} +/*---------------------------------------------------------------------------*/ +#ifdef PLATFORM_REBOOT +static struct ctimer reboot_timer; +static void +do_the_reboot(void *ptr) +{ + PLATFORM_REBOOT(); +} +static int +reboot(lwm2m_context_t *ctx, const uint8_t *arg, size_t argsize, + uint8_t *outbuf, size_t outsize) +{ + PRINTF("Device will reboot!\n"); + ctimer_set(&reboot_timer, CLOCK_SECOND / 2, do_the_reboot, NULL); + return 0; +} +#endif /* PLATFORM_REBOOT */ +/*---------------------------------------------------------------------------*/ +#ifdef PLATFORM_FACTORY_DEFAULT +static int +factory_reset(lwm2m_context_t *ctx, const uint8_t *arg, size_t arg_size, + uint8_t *outbuf, size_t outsize) +{ + PRINTF("Device will do factory default!\n"); + PLATFORM_FACTORY_DEFAULT(); + return 0; +} +#endif /* PLATFORM_FACTORY_DEFAULT */ +/*---------------------------------------------------------------------------*/ +LWM2M_RESOURCES(device_resources, +#ifdef LWM2M_DEVICE_MANUFACTURER + LWM2M_RESOURCE_STRING(0, LWM2M_DEVICE_MANUFACTURER), +#endif /* LWM2M_DEVICE_MANUFACTURER */ +#ifdef LWM2M_DEVICE_TYPE + LWM2M_RESOURCE_STRING(17, LWM2M_DEVICE_TYPE), +#endif /* LWM2M_DEVICE_TYPE */ +#ifdef LWM2M_DEVICE_MODEL_NUMBER + LWM2M_RESOURCE_STRING(1, LWM2M_DEVICE_MODEL_NUMBER), +#endif /* LWM2M_DEVICE_MODEL_NUMBER */ +#ifdef LWM2M_DEVICE_SERIAL_NO + LWM2M_RESOURCE_STRING(2, LWM2M_DEVICE_SERIAL_NO), +#endif /* LWM2M_DEVICE_SERIAL_NO */ +#ifdef LWM2M_DEVICE_FIRMWARE_VERSION + LWM2M_RESOURCE_STRING(3, LWM2M_DEVICE_FIRMWARE_VERSION), +#endif /* LWM2M_DEVICE_FIRMWARE_VERSION */ +#ifdef PLATFORM_REBOOT + LWM2M_RESOURCE_CALLBACK(4, { NULL, NULL, reboot }), +#endif /* PLATFORM_REBOOT */ +#ifdef PLATFORM_FACTORY_DEFAULT + LWM2M_RESOURCE_CALLBACK(5, { NULL, NULL, factory_reset }), +#endif /* PLATFORM_FACTORY_DEFAULT */ + /* Current Time */ + LWM2M_RESOURCE_CALLBACK(13, { read_lwtime, set_lwtime, NULL }), + ); +LWM2M_INSTANCES(device_instances, LWM2M_INSTANCE(0, device_resources)); +LWM2M_OBJECT(device, 3, device_instances); +/*---------------------------------------------------------------------------*/ +void +lwm2m_device_init(void) +{ + /** + * Register this device and its handlers - the handlers + * automatically sends in the object to handle. + */ + PRINTF("*** Init lwm2m-device\n"); + lwm2m_engine_register_object(&device); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-device.h b/apps/oma-lwm2m/lwm2m-device.h new file mode 100644 index 000000000..5e80c786a --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-device.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + */ + +/** + * \file + * Header file for the Contiki OMA LWM2M device + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef LWM2M_DEVICE_H_ +#define LWM2M_DEVICE_H_ + +#include "contiki-conf.h" + +#ifndef LWM2M_DEVICE_MODEL_NUMBER +#ifdef BOARD_STRING +#define LWM2M_DEVICE_MODEL_NUMBER BOARD_STRING +#endif /* BOARD_STRING */ +#endif /* LWM2M_DEVICE_MODEL_NUMBER */ + +#ifndef LWM2M_DEVICE_FIRMWARE_VERSION +#define LWM2M_DEVICE_FIRMWARE_VERSION CONTIKI_VERSION_STRING +#endif /* LWM2M_DEVICE_FIRMWARE_VERSION */ + +void lwm2m_device_init(void); + +#endif /* LWM2M_DEVICE_H_ */ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-engine.c b/apps/oma-lwm2m/lwm2m-engine.c new file mode 100644 index 000000000..0fe86bbbb --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-engine.c @@ -0,0 +1,1077 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M engine + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "contiki.h" +#include "lwm2m-engine.h" +#include "lwm2m-object.h" +#include "lwm2m-device.h" +#include "lwm2m-plain-text.h" +#include "lwm2m-json.h" +#include "rest-engine.h" +#include "er-coap-constants.h" +#include "er-coap-engine.h" +#include "oma-tlv.h" +#include "oma-tlv-reader.h" +#include "oma-tlv-writer.h" +#include "net/ipv6/uip-ds6.h" +#include +#include +#include + +#if UIP_CONF_IPV6_RPL +#include "net/rpl/rpl.h" +#endif /* UIP_CONF_IPV6_RPL */ + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +#ifndef LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX +#ifdef LWM2M_DEVICE_MODEL_NUMBER +#define LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX LWM2M_DEVICE_MODEL_NUMBER +#else /* LWM2M_DEVICE_MODEL_NUMBER */ +#define LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX "Contiki-" +#endif /* LWM2M_DEVICE_MODEL_NUMBER */ +#endif /* LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX */ + +#ifdef LWM2M_ENGINE_CONF_MAX_OBJECTS +#define MAX_OBJECTS LWM2M_ENGINE_CONF_MAX_OBJECTS +#else /* LWM2M_ENGINE_CONF_MAX_OBJECTS */ +#define MAX_OBJECTS 10 +#endif /* LWM2M_ENGINE_CONF_MAX_OBJECTS */ + +#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT) +#define BS_REMOTE_PORT UIP_HTONS(5685) + +static const lwm2m_object_t *objects[MAX_OBJECTS]; +static char endpoint[32]; +static char rd_data[128]; /* allocate some data for the RD */ + +PROCESS(lwm2m_rd_client, "LWM2M Engine"); + +static uip_ipaddr_t server_ipaddr; +static uint16_t server_port = REMOTE_PORT; +static uip_ipaddr_t bs_server_ipaddr; +static uint16_t bs_server_port = BS_REMOTE_PORT; + +static uint8_t use_bootstrap = 0; +static uint8_t has_bootstrap_server_info = 0; +static uint8_t use_registration = 0; +static uint8_t has_registration_server_info = 0; +static uint8_t registered = 0; +static uint8_t bootstrapped = 0; /* bootstrap made... */ + +void lwm2m_device_init(void); +void lwm2m_security_init(void); +void lwm2m_server_init(void); + +static const lwm2m_instance_t *get_first_instance_of_object(uint16_t id, lwm2m_context_t *context); +static const lwm2m_instance_t *get_instance(const lwm2m_object_t *object, lwm2m_context_t *context, int depth); +static const lwm2m_resource_t *get_resource(const lwm2m_instance_t *instance, lwm2m_context_t *context); +/*---------------------------------------------------------------------------*/ +static void +client_chunk_handler(void *response) +{ +#if (DEBUG) & DEBUG_PRINT + const uint8_t *chunk; + + int len = coap_get_payload(response, &chunk); + + PRINTF("|%.*s\n", len, (char *)chunk); +#endif /* (DEBUG) & DEBUG_PRINT */ +} +/*---------------------------------------------------------------------------*/ +static int +index_of(const uint8_t *data, int offset, int len, uint8_t c) +{ + if(offset < 0) { + return offset; + } + for(; offset < len; offset++) { + if(data[offset] == c) { + return offset; + } + } + return -1; +} +/*---------------------------------------------------------------------------*/ +static int +has_network_access(void) +{ +#if UIP_CONF_IPV6_RPL + if(rpl_get_any_dag() == NULL) { + return 0; + } +#endif /* UIP_CONF_IPV6_RPL */ + return 1; +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_use_bootstrap_server(int use) +{ + use_bootstrap = use != 0; + if(use_bootstrap) { + process_poll(&lwm2m_rd_client); + } +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_use_registration_server(int use) +{ + use_registration = use != 0; + if(use_registration) { + process_poll(&lwm2m_rd_client); + } +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_register_with_server(const uip_ipaddr_t *server, uint16_t port) +{ + uip_ipaddr_copy(&server_ipaddr, server); + if(port != 0) { + server_port = port; + } else { + server_port = REMOTE_PORT; + } + has_registration_server_info = 1; + registered = 0; + if(use_registration) { + process_poll(&lwm2m_rd_client); + } +} +/*---------------------------------------------------------------------------*/ +static int +update_registration_server(void) +{ + if(has_registration_server_info) { + return 1; + } + +#if UIP_CONF_IPV6_RPL + { + rpl_dag_t *dag; + + /* Use the DAG id as server address if no other has been specified */ + dag = rpl_get_any_dag(); + if(dag != NULL) { + uip_ipaddr_copy(&server_ipaddr, &dag->dag_id); + server_port = REMOTE_PORT; + return 1; + } + } +#endif /* UIP_CONF_IPV6_RPL */ + + return 0; +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_register_with_bootstrap_server(const uip_ipaddr_t *server, + uint16_t port) +{ + uip_ipaddr_copy(&bs_server_ipaddr, server); + if(port != 0) { + bs_server_port = port; + } else { + bs_server_port = BS_REMOTE_PORT; + } + has_bootstrap_server_info = 1; + bootstrapped = 0; + registered = 0; + if(use_bootstrap) { + process_poll(&lwm2m_rd_client); + } +} +/*---------------------------------------------------------------------------*/ +static int +update_bootstrap_server(void) +{ + if(has_bootstrap_server_info) { + return 1; + } + +#if UIP_CONF_IPV6_RPL + { + rpl_dag_t *dag; + + /* Use the DAG id as server address if no other has been specified */ + dag = rpl_get_any_dag(); + if(dag != NULL) { + uip_ipaddr_copy(&bs_server_ipaddr, &dag->dag_id); + bs_server_port = REMOTE_PORT; + return 1; + } + } +#endif /* UIP_CONF_IPV6_RPL */ + + return 0; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(lwm2m_rd_client, ev, data) +{ + static coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ + static struct etimer et; + + PROCESS_BEGIN(); + + printf("RD Client started with endpoint '%s'\n", endpoint); + + etimer_set(&et, 15 * CLOCK_SECOND); + + while(1) { + PROCESS_YIELD(); + + if(etimer_expired(&et)) { + if(!has_network_access()) { + /* Wait until for a network to join */ + } else if(use_bootstrap && bootstrapped == 0) { + if(update_bootstrap_server()) { + /* prepare request, TID is set by COAP_BLOCKING_REQUEST() */ + coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0); + coap_set_header_uri_path(request, "/bs"); + coap_set_header_uri_query(request, endpoint); + + printf("Registering ID with bootstrap server ["); + uip_debug_ipaddr_print(&bs_server_ipaddr); + printf("]:%u as '%s'\n", uip_ntohs(bs_server_port), endpoint); + + COAP_BLOCKING_REQUEST(&bs_server_ipaddr, bs_server_port, request, + client_chunk_handler); + bootstrapped++; + } + } else if(use_bootstrap && bootstrapped == 1) { + lwm2m_context_t context; + const lwm2m_instance_t *instance = NULL; + const lwm2m_resource_t *rsc; + const uint8_t *first; + int len; + + PRINTF("*** Bootstrap - checking for server info...\n"); + + /* get the security object */ + instance = get_first_instance_of_object(LWM2M_OBJECT_SECURITY_ID, &context); + if(instance != NULL) { + /* get the server URI */ + context.resource_id = LWM2M_SECURITY_SERVER_URI; + rsc = get_resource(instance, &context); + first = lwm2m_object_get_resource_string(rsc, &context); + len = lwm2m_object_get_resource_strlen(rsc, &context); + if(first != NULL && len > 0) { + int start, end; + uip_ipaddr_t addr; + int32_t port; + uint8_t secure = 0; + + PRINTF("**** Found security instance using: %.*s\n", len, first); + /* TODO Should verify it is a URI */ + + /* Check if secure */ + secure = strncmp((const char *)first, "coaps:", 6) == 0; + + /* Only IPv6 supported */ + start = index_of(first, 0, len, '['); + end = index_of(first, start, len, ']'); + if(start > 0 && end > start && + uiplib_ipaddrconv((const char *)&first[start], &addr)) { + if(first[end + 1] == ':' && + lwm2m_plain_text_read_int(first + end + 2, len - end - 2, &port)) { + } else if(secure) { + /** + * Secure CoAP should use a different port but for now + * the same port is used. + */ + port = COAP_DEFAULT_PORT; + } else { + port = COAP_DEFAULT_PORT; + } + PRINTF("Server address "); + PRINT6ADDR(&addr); + PRINTF(" port %" PRId32 "%s\n", port, secure ? " (secure)" : ""); + if(secure) { + printf("Secure CoAP requested but not supported - can not bootstrap\n"); + } else { + lwm2m_engine_register_with_server(&addr, + UIP_HTONS((uint16_t)port)); + bootstrapped++; + } + } else { + printf("** failed to parse URI %.*s\n", len, first); + } + } + } + + if(bootstrapped == 1) { + /* Not ready. Lets retry with the bootstrap server again */ + bootstrapped = 0; + } + + } else if(use_registration && !registered && + update_registration_server()) { + int pos; + int len, i, j; + registered = 1; + + /* prepare request, TID is set by COAP_BLOCKING_REQUEST() */ + coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0); + coap_set_header_uri_path(request, "/rd"); + coap_set_header_uri_query(request, endpoint); + + /* generate the rd data */ + pos = 0; + for(i = 0; i < MAX_OBJECTS; i++) { + if(objects[i] != NULL) { + for(j = 0; j < objects[i]->count; j++) { + if(objects[i]->instances[j].flag & LWM2M_INSTANCE_FLAG_USED) { + len = snprintf(&rd_data[pos], sizeof(rd_data) - pos, + "%s<%d/%d>", pos > 0 ? "," : "", + objects[i]->id, objects[i]->instances[j].id); + if(len > 0 && len < sizeof(rd_data) - pos) { + pos += len; + } + } + } + } + } + + coap_set_payload(request, (uint8_t *)rd_data, pos); + + printf("Registering with ["); + uip_debug_ipaddr_print(&server_ipaddr); + printf("]:%u lwm2m endpoint '%s': '%.*s'\n", uip_ntohs(server_port), + endpoint, pos, rd_data); + COAP_BLOCKING_REQUEST(&server_ipaddr, server_port, request, + client_chunk_handler); + } + /* for now only register once... registered = 0; */ + etimer_set(&et, 15 * CLOCK_SECOND); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_init(void) +{ +#ifdef LWM2M_ENGINE_CLIENT_ENDPOINT_NAME + + snprintf(endpoint, sizeof(endpoint) - 1, + "?ep=" LWM2M_ENGINE_CLIENT_ENDPOINT_NAME); + +#else /* LWM2M_ENGINE_CLIENT_ENDPOINT_NAME */ + + int len, i; + uint8_t state; + uip_ipaddr_t *ipaddr; + char client[sizeof(endpoint)]; + + len = strlen(LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX); + /* ensure that this fits with the hex-nums */ + if(len > sizeof(client) - 13) { + len = sizeof(client) - 13; + } + memcpy(client, LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX, len); + + /* pick an IP address that is PREFERRED or TENTATIVE */ + ipaddr = NULL; + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && + (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { + ipaddr = &(uip_ds6_if.addr_list[i]).ipaddr; + break; + } + } + + if(ipaddr != NULL) { + for(i = 0; i < 6; i++) { + /* assume IPv6 for now */ + uint8_t b = ipaddr->u8[10 + i]; + client[len++] = (b >> 4) > 9 ? 'A' - 10 + (b >> 4) : '0' + (b >> 4); + client[len++] = (b & 0xf) > 9 ? 'A' - 10 + (b & 0xf) : '0' + (b & 0xf); + } + } + + /* a zero at end of string */ + client[len] = 0; + /* create endpoint */ + snprintf(endpoint, sizeof(endpoint) - 1, "?ep=%s", client); + +#endif /* LWM2M_ENGINE_CLIENT_ENDPOINT_NAME */ + + rest_init_engine(); + process_start(&lwm2m_rd_client, NULL); +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_register_default_objects(void) +{ + lwm2m_security_init(); + lwm2m_server_init(); + lwm2m_device_init(); +} +/*---------------------------------------------------------------------------*/ +static int +parse_next(const char **path, int *path_len, uint16_t *value) +{ + char c; + *value = 0; + /* printf("parse_next: %p %d\n", *path, *path_len); */ + if(*path_len == 0) { + return 0; + } + while(*path_len > 0) { + c = **path; + (*path)++; + *path_len = *path_len - 1; + if(c >= '0' && c <= '9') { + *value = *value * 10 + (c - '0'); + } else if(c == '/') { + return 1; + } else { + /* error */ + return -4; + } + } + return 1; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_engine_parse_context(const lwm2m_object_t *object, + const char *path, int path_len, + lwm2m_context_t *context) +{ + int ret; + if(context == NULL || object == NULL || path == NULL) { + return 0; + } + memset(context, 0, sizeof(lwm2m_context_t)); + /* get object id */ + ret = 0; + ret += parse_next(&path, &path_len, &context->object_id); + ret += parse_next(&path, &path_len, &context->object_instance_id); + ret += parse_next(&path, &path_len, &context->resource_id); + + /* Set default reader/writer */ + context->reader = &lwm2m_plain_text_reader; + context->writer = &oma_tlv_writer; + + return ret; +} +/*---------------------------------------------------------------------------*/ +const lwm2m_object_t * +lwm2m_engine_get_object(uint16_t id) +{ + int i; + for(i = 0; i < MAX_OBJECTS; i++) { + if(objects[i] != NULL && objects[i]->id == id) { + return objects[i]; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_engine_register_object(const lwm2m_object_t *object) +{ + int i; + int found = 0; + for(i = 0; i < MAX_OBJECTS; i++) { + if(objects[i] == NULL) { + objects[i] = object; + found = 1; + break; + } + } + rest_activate_resource(lwm2m_object_get_coap_resource(object), + (char *)object->path); + return found; +} +/*---------------------------------------------------------------------------*/ +static const lwm2m_instance_t * +get_first_instance_of_object(uint16_t id, lwm2m_context_t *context) +{ + const lwm2m_object_t *object; + int i; + + object = lwm2m_engine_get_object(id); + if(object == NULL) { + /* No object with the specified id found */ + return NULL; + } + + /* Initialize the context */ + memset(context, 0, sizeof(lwm2m_context_t)); + context->object_id = id; + + for(i = 0; i < object->count; i++) { + if(object->instances[i].flag & LWM2M_INSTANCE_FLAG_USED) { + context->object_instance_id = object->instances[i].id; + context->object_instance_index = i; + return &object->instances[i]; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +static const lwm2m_instance_t * +get_instance(const lwm2m_object_t *object, lwm2m_context_t *context, int depth) +{ + int i; + if(depth > 1) { + PRINTF("lwm2m: searching for instance %u\n", context->object_instance_id); + for(i = 0; i < object->count; i++) { + PRINTF(" Instance %d -> %u (used: %d)\n", i, object->instances[i].id, + (object->instances[i].flag & LWM2M_INSTANCE_FLAG_USED) != 0); + if(object->instances[i].id == context->object_instance_id && + object->instances[i].flag & LWM2M_INSTANCE_FLAG_USED) { + context->object_instance_index = i; + return &object->instances[i]; + } + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +static const lwm2m_resource_t * +get_resource(const lwm2m_instance_t *instance, lwm2m_context_t *context) +{ + int i; + if(instance != NULL) { + PRINTF("lwm2m: searching for resource %u\n", context->resource_id); + for(i = 0; i < instance->count; i++) { + PRINTF(" Resource %d -> %u\n", i, instance->resources[i].id); + if(instance->resources[i].id == context->resource_id) { + context->resource_index = i; + return &instance->resources[i]; + } + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +static int +write_rd_link_data(const lwm2m_object_t *object, + const lwm2m_instance_t *instance, + char *buffer, size_t size) +{ + const lwm2m_resource_t *resource; + int len, rdlen, i; + + PRINTF("<%d/%d>", object->id, instance->id); + rdlen = snprintf(buffer, size, "<%d/%d>", + object->id, instance->id); + if(rdlen < 0 || rdlen >= size) { + return -1; + } + + for(i = 0; i < instance->count; i++) { + resource = &instance->resources[i]; + PRINTF(",<%d/%d/%d>", object->id, instance->id, resource->id); + + len = snprintf(&buffer[rdlen], size - rdlen, + ",<%d/%d/%d>", object->id, instance->id, resource->id); + rdlen += len; + if(len < 0 || rdlen >= size) { + return -1; + } + } + return rdlen; +} +/*---------------------------------------------------------------------------*/ +static int +write_rd_json_data(const lwm2m_context_t *context, + const lwm2m_object_t *object, + const lwm2m_instance_t *instance, + char *buffer, size_t size) +{ + const lwm2m_resource_t *resource; + const char *s = ""; + int len, rdlen, i; + + PRINTF("{\"e\":["); + rdlen = snprintf(buffer, size, "{\"e\":["); + if(rdlen < 0 || rdlen >= size) { + return -1; + } + + for(i = 0, len = 0; i < instance->count; i++) { + resource = &instance->resources[i]; + len = 0; + if(lwm2m_object_is_resource_string(resource)) { + const uint8_t *value; + uint16_t slen; + value = lwm2m_object_get_resource_string(resource, context); + slen = lwm2m_object_get_resource_strlen(resource, context); + if(value != NULL) { + PRINTF("%s{\"n\":\"%u\",\"sv\":\"%.*s\"}", s, + resource->id, slen, value); + len = snprintf(&buffer[rdlen], size - rdlen, + "%s{\"n\":\"%u\",\"sv\":\"%.*s\"}", s, + resource->id, slen, value); + } + } else if(lwm2m_object_is_resource_int(resource)) { + int32_t value; + if(lwm2m_object_get_resource_int(resource, context, &value)) { + PRINTF("%s{\"n\":\"%u\",\"v\":%" PRId32 "}", s, + resource->id, value); + len = snprintf(&buffer[rdlen], size - rdlen, + "%s{\"n\":\"%u\",\"v\":%" PRId32 "}", s, + resource->id, value); + } + } else if(lwm2m_object_is_resource_floatfix(resource)) { + int32_t value; + if(lwm2m_object_get_resource_floatfix(resource, context, &value)) { + PRINTF("%s{\"n\":\"%u\",\"v\":%" PRId32 "}", s, resource->id, + value / LWM2M_FLOAT32_FRAC); + len = snprintf(&buffer[rdlen], size - rdlen, + "%s{\"n\":\"%u\",\"v\":", s, resource->id); + rdlen += len; + if(len < 0 || rdlen >= size) { + return -1; + } + + len = lwm2m_plain_text_write_float32fix((uint8_t *)&buffer[rdlen], + size - rdlen, + value, LWM2M_FLOAT32_BITS); + if(len == 0) { + return -1; + } + rdlen += len; + + if(rdlen < size) { + buffer[rdlen] = '}'; + } + len = 1; + } + } else if(lwm2m_object_is_resource_boolean(resource)) { + int value; + if(lwm2m_object_get_resource_boolean(resource, context, &value)) { + PRINTF("%s{\"n\":\"%u\",\"bv\":%s}", s, resource->id, + value ? "true" : "false"); + len = snprintf(&buffer[rdlen], size - rdlen, + "%s{\"n\":\"%u\",\"bv\":%s}", s, resource->id, + value ? "true" : "false"); + } + } + rdlen += len; + if(len < 0 || rdlen >= size) { + return -1; + } + if(len > 0) { + s = ","; + } + } + PRINTF("]}\n"); + len = snprintf(&buffer[rdlen], size - rdlen, "]}"); + rdlen += len; + if(len < 0 || rdlen >= size) { + return -1; + } + + return rdlen; +} +/*---------------------------------------------------------------------------*/ +/** + * @brief Set the writer pointer to the proper writer based on the Accept: header + * + * @param[in] context LWM2M context to operate on + * @param[in] accept Accept type number from CoAP headers + * + * @return The content type of the response if the selected writer is used + */ +static unsigned int +lwm2m_engine_select_writer(lwm2m_context_t *context, unsigned int accept) +{ + switch(accept) { + case LWM2M_TLV: + context->writer = &oma_tlv_writer; + break; + case LWM2M_TEXT_PLAIN: + case TEXT_PLAIN: + context->writer = &lwm2m_plain_text_writer; + break; + case LWM2M_JSON: + case APPLICATION_JSON: + context->writer = &lwm2m_json_writer; + break; + default: + PRINTF("Unknown Accept type %u, using LWM2M plain text\n", accept); + context->writer = &lwm2m_plain_text_writer; + /* Set the response type to plain text */ + accept = LWM2M_TEXT_PLAIN; + break; + } + return accept; +} +/*---------------------------------------------------------------------------*/ +/** + * @brief Set the reader pointer to the proper reader based on the Content-format: header + * + * @param[in] context LWM2M context to operate on + * @param[in] content_format Content-type type number from CoAP headers + */ +static void +lwm2m_engine_select_reader(lwm2m_context_t *context, unsigned int content_format) +{ + switch(content_format) { + case LWM2M_TLV: + context->reader = &oma_tlv_reader; + break; + case LWM2M_TEXT_PLAIN: + case TEXT_PLAIN: + context->reader = &lwm2m_plain_text_reader; + break; + default: + PRINTF("Unknown content type %u, using LWM2M plain text\n", accept); + context->reader = &lwm2m_plain_text_reader; + break; + } +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_handler(const lwm2m_object_t *object, + void *request, void *response, + uint8_t *buffer, uint16_t preferred_size, + int32_t *offset) +{ + int len; + const char *url; + unsigned int format; + unsigned int accept; + unsigned int content_type; + int depth; + lwm2m_context_t context; + rest_resource_flags_t method; + const lwm2m_instance_t *instance; +#if (DEBUG) & DEBUG_PRINT + const char *method_str; +#endif /* (DEBUG) & DEBUG_PRINT */ + + method = REST.get_method_type(request); + + len = REST.get_url(request, &url); + if(!REST.get_header_content_type(request, &format)) { + PRINTF("No format given. Assume text plain...\n"); + format = LWM2M_TEXT_PLAIN; + } else if(format == TEXT_PLAIN) { + /* CoAP content format text plain - assume LWM2M text plain */ + format = LWM2M_TEXT_PLAIN; + } + if(!REST.get_header_accept(request, &accept)) { + PRINTF("No Accept header, using same as Content-format...\n"); + accept = format; + } + + depth = lwm2m_engine_parse_context(object, url, len, &context); + PRINTF("Context: %u/%u/%u found: %d\n", context.object_id, + context.object_instance_id, context.resource_id, depth); + + /* Select reader and writer based on provided Content type and Accept headers */ + lwm2m_engine_select_reader(&context, format); + content_type = lwm2m_engine_select_writer(&context, accept); + +#if (DEBUG) & DEBUG_PRINT + /* for debugging */ + if(method == METHOD_GET) { + method_str = "GET"; + } else if(method == METHOD_POST) { + method_str = "POST"; + } else if(method == METHOD_PUT) { + method_str = "PUT"; + } else if(method == METHOD_DELETE) { + method_str = "DELETE"; + } else { + method_str = "UNKNOWN"; + } + PRINTF("%s Called Path:%.*s Format:%d ID:%d bsize:%u\n", method_str, len, + url, format, object->id, preferred_size); + if(format == LWM2M_TEXT_PLAIN) { + /* a string */ + const uint8_t *data; + int plen = REST.get_request_payload(request, &data); + if(plen > 0) { + PRINTF("Data: '%.*s'\n", plen, (char *)data); + } + } +#endif /* (DEBUG) & DEBUG_PRINT */ + + instance = get_instance(object, &context, depth); + + /* from POST */ + if(depth > 1 && instance == NULL) { + if(method != METHOD_PUT && method != METHOD_POST) { + PRINTF("Error - do not have instance %d\n", context.object_instance_id); + REST.set_response_status(response, NOT_FOUND_4_04); + return; + } else { + const uint8_t *data; + int i, len, plen, pos; + oma_tlv_t tlv; + PRINTF(">>> CREATE ? %d/%d\n", context.object_id, + context.object_instance_id); + + for(i = 0; i < object->count; i++) { + if((object->instances[i].flag & LWM2M_INSTANCE_FLAG_USED) == 0) { + /* allocate this instance */ + object->instances[i].flag |= LWM2M_INSTANCE_FLAG_USED; + object->instances[i].id = context.object_instance_id; + context.object_instance_index = i; + PRINTF("Created instance: %d\n", context.object_instance_id); + REST.set_response_status(response, CREATED_2_01); + instance = &object->instances[i]; + break; + } + } + + if(instance == NULL) { + /* could for some reason not create the instance */ + REST.set_response_status(response, NOT_ACCEPTABLE_4_06); + return; + } + + plen = REST.get_request_payload(request, &data); + if(plen == 0) { + /* do nothing more */ + return; + } + PRINTF("Payload: "); + for(i = 0; i < plen; i++) { + PRINTF("%02x", data[i]); + } + PRINTF("\n"); + + pos = 0; + do { + len = oma_tlv_read(&tlv, (uint8_t *)&data[pos], plen - pos); + PRINTF("Found TLV type=%u id=%u len=%lu\n", + tlv.type, tlv.id, (unsigned long)tlv.length); + /* here we need to do callbacks or write value */ + if(tlv.type == OMA_TLV_TYPE_RESOURCE) { + context.resource_id = tlv.id; + const lwm2m_resource_t *rsc = get_resource(instance, &context); + if(rsc != NULL) { + /* write the value to the resource */ + if(lwm2m_object_is_resource_string(rsc)) { + PRINTF(" new string value for /%d/%d/%d = %.*s\n", + context.object_id, context.object_instance_id, + context.resource_id, (int)tlv.length, tlv.value); + lwm2m_object_set_resource_string(rsc, &context, + tlv.length, tlv.value); + } else if(lwm2m_object_is_resource_int(rsc)) { + PRINTF(" new int value for /%d/%d/%d = %" PRId32 "\n", + context.object_id, context.object_instance_id, + context.resource_id, oma_tlv_get_int32(&tlv)); + lwm2m_object_set_resource_int(rsc, &context, + oma_tlv_get_int32(&tlv)); + } else if(lwm2m_object_is_resource_floatfix(rsc)) { + int32_t value; + if(oma_tlv_float32_to_fix(&tlv, &value, LWM2M_FLOAT32_BITS)) { + PRINTF(" new float value for /%d/%d/%d = %" PRId32 "\n", + context.object_id, context.object_instance_id, + context.resource_id, value >> LWM2M_FLOAT32_BITS); + lwm2m_object_set_resource_floatfix(rsc, &context, value); + } else { + PRINTF(" new float value for /%d/%d/%d: FAILED\n", + context.object_id, context.object_instance_id, + context.resource_id); + } + } else if(lwm2m_object_is_resource_boolean(rsc)) { + PRINTF(" new boolean value for /%d/%d/%d = %" PRId32 "\n", + context.object_id, context.object_instance_id, + context.resource_id, oma_tlv_get_int32(&tlv)); + lwm2m_object_set_resource_boolean(rsc, &context, + oma_tlv_get_int32(&tlv) != 0); + } + } + } + pos = pos + len; + } while(len > 0 && pos < plen); + } + return; + } + + if(depth == 3) { + const lwm2m_resource_t *resource = get_resource(instance, &context); + size_t content_len = 0; + if(resource == NULL) { + PRINTF("Error - do not have resource %d\n", context.resource_id); + REST.set_response_status(response, NOT_FOUND_4_04); + return; + } + /* HANDLE PUT */ + if(method == METHOD_PUT) { + if(lwm2m_object_is_resource_callback(resource)) { + if(resource->value.callback.write != NULL) { + /* pick a reader ??? */ + if(format == LWM2M_TEXT_PLAIN) { + /* a string */ + const uint8_t *data; + int plen = REST.get_request_payload(request, &data); + context.reader = &lwm2m_plain_text_reader; + PRINTF("PUT Callback with data: '%.*s'\n", plen, data); + /* no specific reader for plain text */ + content_len = resource->value.callback.write(&context, data, plen, + buffer, preferred_size); + PRINTF("content_len:%u\n", (unsigned int)content_len); + REST.set_response_status(response, CHANGED_2_04); + } else { + PRINTF("PUT callback with format %d\n", format); + REST.set_response_status(response, NOT_ACCEPTABLE_4_06); + } + } else { + PRINTF("PUT - no write callback\n"); + REST.set_response_status(response, METHOD_NOT_ALLOWED_4_05); + } + } else { + PRINTF("PUT on non-callback resource!\n"); + REST.set_response_status(response, METHOD_NOT_ALLOWED_4_05); + } + /* HANDLE GET */ + } else if(method == METHOD_GET) { + if(lwm2m_object_is_resource_string(resource)) { + const uint8_t *value; + value = lwm2m_object_get_resource_string(resource, &context); + if(value != NULL) { + uint16_t len = lwm2m_object_get_resource_strlen(resource, &context); + PRINTF("Get string value: %.*s\n", (int)len, (char *)value); + content_len = context.writer->write_string(&context, buffer, + preferred_size, (const char *)value, len); + } + } else if(lwm2m_object_is_resource_int(resource)) { + int32_t value; + if(lwm2m_object_get_resource_int(resource, &context, &value)) { + content_len = context.writer->write_int(&context, buffer, preferred_size, value); + } + } else if(lwm2m_object_is_resource_floatfix(resource)) { + int32_t value; + if(lwm2m_object_get_resource_floatfix(resource, &context, &value)) { + /* export FLOATFIX */ + PRINTF("Exporting %d-bit fix as float: %" PRId32 "\n", + LWM2M_FLOAT32_BITS, value); + content_len = context.writer->write_float32fix(&context, buffer, + preferred_size, value, LWM2M_FLOAT32_BITS); + } + } else if(lwm2m_object_is_resource_callback(resource)) { + if(resource->value.callback.read != NULL) { + content_len = resource->value.callback.read(&context, + buffer, preferred_size); + } else { + REST.set_response_status(response, METHOD_NOT_ALLOWED_4_05); + return; + } + } + if(content_len > 0) { + REST.set_response_payload(response, buffer, content_len); + REST.set_header_content_type(response, content_type); + } else { + /* failed to produce output - it is an internal error */ + REST.set_response_status(response, INTERNAL_SERVER_ERROR_5_00); + } + /* Handle POST */ + } else if(method == METHOD_POST) { + if(lwm2m_object_is_resource_callback(resource)) { + if(resource->value.callback.exec != NULL) { + const uint8_t *data; + int plen = REST.get_request_payload(request, &data); + PRINTF("Execute Callback with data: '%.*s'\n", plen, data); + content_len = resource->value.callback.exec(&context, + data, plen, + buffer, preferred_size); + REST.set_response_status(response, CHANGED_2_04); + } else { + PRINTF("Execute callback - no exec callback\n"); + REST.set_response_status(response, METHOD_NOT_ALLOWED_4_05); + } + } else { + PRINTF("Resource post but no callback resource\n"); + REST.set_response_status(response, METHOD_NOT_ALLOWED_4_05); + } + } + } else if(depth == 2) { + /* produce an instance response */ + if(method != METHOD_GET) { + REST.set_response_status(response, METHOD_NOT_ALLOWED_4_05); + } else if(instance == NULL) { + REST.set_response_status(response, NOT_FOUND_4_04); + } else { + int rdlen; + if(accept == APPLICATION_LINK_FORMAT) { + rdlen = write_rd_link_data(object, instance, + (char *)buffer, preferred_size); + } else { + rdlen = write_rd_json_data(&context, object, instance, + (char *)buffer, preferred_size); + } + if(rdlen < 0) { + PRINTF("Failed to generate instance response\n"); + REST.set_response_status(response, SERVICE_UNAVAILABLE_5_03); + return; + } + REST.set_response_payload(response, buffer, rdlen); + if(accept == APPLICATION_LINK_FORMAT) { + REST.set_header_content_type(response, REST.type.APPLICATION_LINK_FORMAT); + } else { + REST.set_header_content_type(response, LWM2M_JSON); + } + } + } +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_delete_handler(const lwm2m_object_t *object, void *request, + void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + int len; + const char *url; + lwm2m_context_t context; + + len = REST.get_url(request, &url); + PRINTF("*** DELETE URI:'%.*s' called... - responding with DELETED.\n", + len, url); + len = lwm2m_engine_parse_context(object, url, len, &context); + PRINTF("Context: %u/%u/%u found: %d\n", context.object_id, + context.object_instance_id, context.resource_id, len); + + REST.set_response_status(response, DELETED_2_02); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-engine.h b/apps/oma-lwm2m/lwm2m-engine.h new file mode 100644 index 000000000..5512a326d --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-engine.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + */ + +/** + * \file + * Header file for the Contiki OMA LWM2M engine + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef LWM2M_ENGINE_H +#define LWM2M_ENGINE_H + +#include "lwm2m-object.h" + +#define LWM2M_FLOAT32_BITS 10 +#define LWM2M_FLOAT32_FRAC (1L << LWM2M_FLOAT32_BITS) + +/* LWM2M / CoAP Content-Formats */ +typedef enum { + LWM2M_TEXT_PLAIN = 1541, + LWM2M_TLV = 1542, + LWM2M_JSON = 1543, + LWM2M_OPAQUE = 1544 +} lwm2m_content_format_t; + +void lwm2m_engine_init(void); +void lwm2m_engine_register_default_objects(void); +void lwm2m_engine_use_bootstrap_server(int use); +void lwm2m_engine_use_registration_server(int use); +void lwm2m_engine_register_with_server(const uip_ipaddr_t *server, uint16_t port); +void lwm2m_engine_register_with_bootstrap_server(const uip_ipaddr_t *server, uint16_t port); + +const lwm2m_object_t *lwm2m_engine_get_object(uint16_t id); + +int lwm2m_engine_register_object(const lwm2m_object_t *object); + +void lwm2m_engine_handler(const lwm2m_object_t *object, + void *request, void *response, + uint8_t *buffer, uint16_t preferred_size, + int32_t *offset); + +void lwm2m_engine_delete_handler(const lwm2m_object_t *object, + void *request, void *response, + uint8_t *buffer, uint16_t preferred_size, + int32_t *offset); + +#endif /* LWM2M_ENGINE_H */ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-json.c b/apps/oma-lwm2m/lwm2m-json.c new file mode 100644 index 000000000..8924ceb8c --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-json.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2016, Eistec AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M JSON writer + * \author + * Joakim Nohlgård + */ + +#include "lwm2m-object.h" +#include "lwm2m-json.h" +#include "lwm2m-plain-text.h" +#include +#include +#include +#include + +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/*---------------------------------------------------------------------------*/ +static size_t +write_boolean(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int value) +{ + int len = snprintf((char *)outbuf, outlen, "{\"e\":[{\"n\":\"%u\",\"bv\":%s}]}\n", ctx->resource_id, value ? "true" : "false"); + if((len < 0) || (len >= outlen)) { + return 0; + } + return len; +} +/*---------------------------------------------------------------------------*/ +static size_t +write_int(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int32_t value) +{ + int len = snprintf((char *)outbuf, outlen, "{\"e\":[{\"n\":\"%u\",\"v\":%" PRId32 "}]}\n", ctx->resource_id, value); + if((len < 0) || (len >= outlen)) { + return 0; + } + return len; +} +/*---------------------------------------------------------------------------*/ +static size_t +write_float32fix(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int32_t value, int bits) +{ + size_t len = 0; + int res; + res = snprintf((char *)outbuf, outlen, "{\"e\":[{\"n\":\"%u\",\"v\":", ctx->resource_id); + if(res <= 0 || res >= outlen) { + return 0; + } + len += res; + outlen -= res; + res = lwm2m_plain_text_write_float32fix(&outbuf[len], outlen, value, bits); + if((res <= 0) || (res >= outlen)) { + return 0; + } + len += res; + outlen -= res; + res = snprintf((char *)&outbuf[len], outlen, "}]}\n"); + if((res <= 0) || (res >= outlen)) { + return 0; + } + len += res; + return len; +} +/*---------------------------------------------------------------------------*/ +static size_t +write_string(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + const char *value, size_t stringlen) +{ + size_t i; + size_t len = 0; + int res; + PRINTF("{\"e\":[{\"n\":\"%u\",\"sv\":\"", ctx->resource_id); + res = snprintf((char *)outbuf, outlen, "{\"e\":[{\"n\":\"%u\",\"sv\":\"", ctx->resource_id); + if(res < 0 || res >= outlen) { + return 0; + } + len += res; + for (i = 0; i < stringlen && len < outlen; ++i) { + /* Escape special characters */ + /* TODO: Handle UTF-8 strings */ + if(value[i] < '\x20') { + PRINTF("\\x%x", value[i]); + res = snprintf((char *)&outbuf[len], outlen - len, "\\x%x", value[i]); + if((res < 0) || (res >= (outlen - len))) { + return 0; + } + len += res; + continue; + } else if(value[i] == '"' || value[i] == '\\') { + PRINTF("\\"); + outbuf[len] = '\\'; + ++len; + if(len >= outlen) { + return 0; + } + } + PRINTF("%c", value[i]); + outbuf[len] = value[i]; + ++len; + if(len >= outlen) { + return 0; + } + } + PRINTF("\"}]}\n"); + res = snprintf((char *)&outbuf[len], outlen - len, "\"}]}\n"); + if((res < 0) || (res >= (outlen - len))) { + return 0; + } + len += res; + return len; +} +/*---------------------------------------------------------------------------*/ +const lwm2m_writer_t lwm2m_json_writer = { + write_int, + write_string, + write_float32fix, + write_boolean +}; +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-json.h b/apps/oma-lwm2m/lwm2m-json.h new file mode 100644 index 000000000..bc1a1e32a --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-json.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016, Eistec AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + */ + +/** + * \file + * Header file for the Contiki OMA LWM2M JSON writer + * \author + * Joakim Nohlgård + */ + +#ifndef LWM2M_JSON_H_ +#define LWM2M_JSON_H_ + +#include "lwm2m-object.h" + +extern const lwm2m_writer_t lwm2m_json_writer; + +#endif /* LWM2M_JSON_H_ */ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-object.c b/apps/oma-lwm2m/lwm2m-object.c new file mode 100644 index 000000000..2f5ddb6ed --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-object.c @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + * + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M object API + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "lwm2m-object.h" +#include +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_is_resource_string(const lwm2m_resource_t *resource) +{ + if(resource == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VALUE || + resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE || + resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY) { + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +const uint8_t * +lwm2m_object_get_resource_string(const lwm2m_resource_t *resource, + const lwm2m_context_t *context) +{ + if(resource == NULL || context == NULL) { + return NULL; + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VALUE) { + return resource->value.string.value; + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE) { + return *(resource->value.stringvar.var); + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.stringvararr.count) { + return resource->value.stringvararr.var + + resource->value.stringvararr.size * context->object_instance_index; + } + return NULL; + } + /* Not a string */ + return NULL; +} +/*---------------------------------------------------------------------------*/ +uint16_t +lwm2m_object_get_resource_strlen(const lwm2m_resource_t *resource, + const lwm2m_context_t *context) +{ + if(resource == NULL || context == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VALUE) { + return resource->value.string.len; + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE) { + return *(resource->value.stringvar.len); + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.stringvararr.count) { + return resource->value.stringvararr.len[context->object_instance_index]; + } + return 0; + } + /* Not a string */ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_set_resource_string(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + uint16_t len, const uint8_t *string) +{ + if(resource == NULL || context == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE) { + if(len > resource->value.stringvar.size) { + /* Too large */ + return 0; + } + memcpy(resource->value.stringvar.var, string, len); + *(resource->value.stringvar.len) = len; + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.stringvararr.count && + len <= resource->value.stringvararr.size) { + memcpy(resource->value.stringvararr.var + + resource->value.stringvararr.size * context->object_instance_index, + string, len); + resource->value.stringvararr.len[context->object_instance_index] = len; + return 1; + } + return 0; + } + /* Not a string variable */ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_is_resource_int(const lwm2m_resource_t *resource) +{ + if(resource == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_INT_VALUE || + resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE || + resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY) { + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_get_resource_int(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int32_t *value) +{ + if(resource == NULL || context == NULL || value == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_INT_VALUE) { + *value = resource->value.integer.value; + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE) { + *value = *(resource->value.integervar.var); + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.integervararr.count) { + *value = resource->value.integervararr.var[context->object_instance_index]; + return 1; + } + return 0; + } + /* Not an integer */ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_set_resource_int(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int32_t value) +{ + if(resource == NULL || context == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE) { + *(resource->value.integervar.var) = value; + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.integervararr.count) { + resource->value.integervararr.var[context->object_instance_index] = + value; + return 1; + } + return 0; + } + /* Not an integer variable */ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_is_resource_floatfix(const lwm2m_resource_t *resource) +{ + if(resource == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VALUE || + resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE || + resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY) { + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_get_resource_floatfix(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int32_t *value) +{ + if(resource == NULL || context == NULL || value == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VALUE) { + *value = resource->value.floatfix.value; + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE) { + *value = *(resource->value.floatfixvar.var); + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.floatfixvararr.count) { + *value = resource->value.floatfixvararr.var[context->object_instance_index]; + return 1; + } + return 0; + } + /* Not an float */ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_set_resource_floatfix(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int32_t value) +{ + if(resource == NULL || context == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE) { + *(resource->value.floatfixvar.var) = value; + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.floatfixvararr.count) { + resource->value.floatfixvararr.var[context->object_instance_index] = + value; + return 1; + } + return 0; + } + /* Not an float variable */ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_is_resource_boolean(const lwm2m_resource_t *resource) +{ + if(resource == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VALUE || + resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE || + resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY) { + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_get_resource_boolean(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int *value) +{ + if(resource == NULL || context == NULL || value == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VALUE) { + *value = resource->value.boolean.value; + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE) { + *value = *(resource->value.booleanvar.var); + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.booleanvararr.count) { + *value = resource->value.booleanvararr.var[context->object_instance_index]; + return 1; + } + return 0; + } + /* Not a boolean */ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_set_resource_boolean(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int value) +{ + if(resource == NULL || context == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE) { + *(resource->value.booleanvar.var) = value; + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.booleanvararr.count) { + resource->value.booleanvararr.var[context->object_instance_index] = + value; + return 1; + } + return 0; + } + /* Not a boolean variable */ + return 0; +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-object.h b/apps/oma-lwm2m/lwm2m-object.h new file mode 100644 index 000000000..5c391cb41 --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-object.h @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup apps + * @{ + */ + +/** + * \defgroup oma-lwm2m An implementation of OMA LWM2M + * @{ + * + * This application is an implementation of OMA Lightweight M2M. + */ + +/** + * \file + * Header file for the Contiki OMA LWM2M object API + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef LWM2M_OBJECT_H_ +#define LWM2M_OBJECT_H_ + +#include "rest-engine.h" +#include "er-coap-observe.h" + +#define LWM2M_OBJECT_SECURITY_ID 0 +#define LWM2M_OBJECT_SERVER_ID 1 +#define LWM2M_OBJECT_ACCESS_CONTROL_ID 2 +#define LWM2M_OBJECT_DEVICE_ID 3 +#define LWM2M_OBJECT_CONNECTIVITY_MONITORING_ID 4 +#define LWM2M_OBJECT_FIRMWARE_ID 5 +#define LWM2M_OBJECT_LOCATION_ID 6 +#define LWM2M_OBJECT_CONNECTIVITY_STATISTICS_ID 7 + +#define LWM2M_SECURITY_SERVER_URI 0 +#define LWM2M_SECURITY_BOOTSTRAP_SERVER 1 +#define LWM2M_SECURITY_MODE 2 +#define LWM2M_SECURITY_CLIENT_PKI 3 +#define LWM2M_SECURITY_SERVER_PKI 4 +#define LWM2M_SECURITY_KEY 5 +#define LWM2M_SECURITY_SHORT_SERVER_ID 10 + +/* Pre-shared key mode */ +#define LWM2M_SECURITY_MODE_PSK 0 +/* Raw Public Key mode */ +#define LWM2M_SECURITY_MODE_RPK 1 +/* Certificate mode */ +#define LWM2M_SECURITY_MODE_CERTIFICATE 2 +/* NoSec mode */ +#define LWM2M_SECURITY_MODE_NOSEC 3 + +#define LWM2M_OBJECT_STR_HELPER(x) (uint8_t *) #x +#define LWM2M_OBJECT_STR(x) LWM2M_OBJECT_STR_HELPER(x) + +#define LWM2M_OBJECT_PATH_STR_HELPER(x) #x +#define LWM2M_OBJECT_PATH_STR(x) LWM2M_OBJECT_PATH_STR_HELPER(x) + +struct lwm2m_reader; +struct lwm2m_writer; +/* Data model for OMA LWM2M objects */ +typedef struct lwm2m_context { + uint16_t object_id; + uint16_t object_instance_id; + uint16_t resource_id; + uint8_t object_instance_index; + uint8_t resource_index; + /* TODO - add uint16_t resource_instance_id */ + + const struct lwm2m_reader *reader; + const struct lwm2m_writer *writer; +} lwm2m_context_t; + +/* LWM2M format writer for the various formats supported */ +typedef struct lwm2m_writer { + size_t (* write_int)(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, int32_t value); + size_t (* write_string)(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, const char *value, size_t strlen); + size_t (* write_float32fix)(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, int32_t value, int bits); + size_t (* write_boolean)(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, int value); +} lwm2m_writer_t; + +typedef struct lwm2m_reader { + size_t (* read_int)(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, int32_t *value); + size_t (* read_string)(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, uint8_t *value, size_t strlen); + size_t (* read_float32fix)(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, int32_t *value, int bits); + size_t (* read_boolean)(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, int *value); +} lwm2m_reader_t; + +typedef struct lwm2m_value_callback { + int (* read)(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen); + int (* write)(lwm2m_context_t *ctx, + const uint8_t *buffer, size_t len, + uint8_t *outbuf, size_t outlen); + int (* exec)(lwm2m_context_t *ctx, const uint8_t *arg, size_t len, + uint8_t *outbuf, size_t outlen); +} lwm2m_value_callback_t; + +#define LWM2M_RESOURCE_TYPE_STR_VALUE 1 +#define LWM2M_RESOURCE_TYPE_STR_VARIABLE 2 +#define LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY 3 +#define LWM2M_RESOURCE_TYPE_INT_VALUE 4 +#define LWM2M_RESOURCE_TYPE_INT_VARIABLE 5 +#define LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY 6 +#define LWM2M_RESOURCE_TYPE_FLOATFIX_VALUE 7 +#define LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE 8 +#define LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY 9 +#define LWM2M_RESOURCE_TYPE_BOOLEAN_VALUE 10 +#define LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE 11 +#define LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY 12 +#define LWM2M_RESOURCE_TYPE_CALLBACK 16 +#define LWM2M_RESOURCE_TYPE_INSTANCES 17 + +typedef struct lwm2m_resource { + uint16_t id; + uint8_t type; /* indicate value type and multi-instance resource */ + union { + struct { + uint16_t len; + const uint8_t *value; + } string; + struct { + uint16_t size; + uint16_t *len; + uint8_t **var; + } stringvar; + struct { + uint16_t count; + uint16_t size; + /* string var array with counting entries */ + uint16_t *len; + uint8_t *var; + } stringvararr; + struct { + int32_t value; + } integer; + struct { + int32_t *var; + } integervar; + struct { + /* used for multiple instances (dynamic) NOTE: this is an index into + the instance so having two instances means that there is need for + allocation of two ints here */ + uint16_t count; + int32_t *var; /* used as an array? */ + } integervararr; + struct { + int32_t value; + } floatfix; + struct { + int32_t *var; + } floatfixvar; + struct { + uint16_t count; + int32_t *var; + } floatfixvararr; + struct { + int value; + } boolean; + struct { + int *var; + } booleanvar; + struct { + uint16_t count; + int *var; + } booleanvararr; + lwm2m_value_callback_t callback; + /* lwm2m_resource *resources[]; TO BE ADDED LATER*/ + } value; +} lwm2m_resource_t; + +#define LWM2M_INSTANCE_FLAG_USED 1 + +typedef struct lwm2m_instance { + uint16_t id; + uint16_t count; + uint16_t flag; + const lwm2m_resource_t *resources; +} lwm2m_instance_t; + +typedef struct lwm2m_object { + uint16_t id; + uint16_t count; + const char *path; + resource_t *coap_resource; + lwm2m_instance_t *instances; +} lwm2m_object_t; + +#define LWM2M_RESOURCES(name, ...) \ + static const lwm2m_resource_t name[] = { __VA_ARGS__ } + +#define LWM2M_RESOURCE_STRING(id, s) \ + { id, LWM2M_RESOURCE_TYPE_STR_VALUE, .value.string.len = sizeof(s) - 1, .value.string.value = (uint8_t *) s } + +#define LWM2M_RESOURCE_STRING_VAR(id, s, l, v) \ + { id, LWM2M_RESOURCE_TYPE_STR_VARIABLE, .value.stringvar.size = (s), .value.stringvar.len = (l), .value.stringvar.var = (v) } + +#define LWM2M_RESOURCE_STRING_VAR_ARR(id, c, s, l, v) \ + { id, LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY, .value.stringvararr.count = c, .value.stringvararr.size = s, .value.stringvararr.len = l, .value.stringvararr.var = (uint8_t *) v } + +#define LWM2M_RESOURCE_INTEGER(id, v) \ + { id, LWM2M_RESOURCE_TYPE_INT_VALUE, .value.integer.value = (v) } + +#define LWM2M_RESOURCE_INTEGER_VAR(id, v) \ + { id, LWM2M_RESOURCE_TYPE_INT_VARIABLE, .value.integervar.var = (v) } + +#define LWM2M_RESOURCE_INTEGER_VAR_ARR(id, c, v) \ + { id, LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY, .value.integervararr.count = (c), .value.integervararr.var = (v) } + +#define LWM2M_RESOURCE_FLOATFIX(id, v) \ + { id, LWM2M_RESOURCE_TYPE_FLOATFIX_VALUE, .value.floatfix.value = (v) } + +#define LWM2M_RESOURCE_FLOATFIX_VAR(id, v) \ + { id, LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE, .value.floatfixvar.var = (v) } + +#define LWM2M_RESOURCE_FLOATFIX_VAR_ARR(id, c, v) \ + { id, LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY, .value.floatfixvararr.count = (c), .value.floatfixvararr.var = (v) } + +#define LWM2M_RESOURCE_BOOLEAN(id, v) \ + { id, LWM2M_RESOURCE_TYPE_BOOLEAN_VALUE, .value.boolean.value = (v) } + +#define LWM2M_RESOURCE_BOOLEAN_VAR(id, v) \ + { id, LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE, .value.booleanvar.var = (v) } + +#define LWM2M_RESOURCE_BOOLEAN_VAR_ARR(id, c, v) \ + { id, LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY, .value.booleanvararr.count = (c), .value.booleanvararr.var = (v) } + +#define LWM2M_RESOURCE_CALLBACK(id, ...) \ + { id, LWM2M_RESOURCE_TYPE_CALLBACK, .value.callback = __VA_ARGS__ } + +#define LWM2M_INSTANCE(id, resources) \ + { id, sizeof(resources)/sizeof(lwm2m_resource_t), LWM2M_INSTANCE_FLAG_USED, resources } + +#define LWM2M_INSTANCE_UNUSED(id, resources) \ + { id, sizeof(resources)/sizeof(lwm2m_resource_t), 0, resources } + +#define LWM2M_INSTANCES(name, ...) \ + static lwm2m_instance_t name[] = { __VA_ARGS__ } + +#define LWM2M_OBJECT(name, id, instances) \ + static void lwm2m_get_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); \ + static void lwm2m_put_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); \ + static void lwm2m_post_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); \ + static void lwm2m_delete_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); \ + static resource_t rest_rsc_##name = { NULL, NULL, HAS_SUB_RESOURCES | IS_OBSERVABLE, NULL, lwm2m_get_h_##name, lwm2m_post_h_##name, lwm2m_put_h_##name, lwm2m_delete_h_##name, { NULL } }; \ + static const lwm2m_object_t name = { id, sizeof(instances)/sizeof(lwm2m_instance_t), LWM2M_OBJECT_PATH_STR(id), &rest_rsc_##name, instances}; \ + static void lwm2m_get_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { \ + lwm2m_engine_handler(&name, request, response, buffer, preferred_size, offset); } \ + static void lwm2m_put_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { \ + lwm2m_engine_handler(&name, request, response, buffer, preferred_size, offset); } \ + static void lwm2m_post_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { \ + lwm2m_engine_handler(&name, request, response, buffer, preferred_size, offset); } \ + static void lwm2m_delete_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { \ + lwm2m_engine_delete_handler(&name, request, response, buffer, preferred_size, offset); } + +/* how do we register attributes in the above resource here ??? */ + +int lwm2m_object_is_resource_string(const lwm2m_resource_t *resource); +int lwm2m_object_is_resource_int(const lwm2m_resource_t *resource); +int lwm2m_object_is_resource_floatfix(const lwm2m_resource_t *resource); +int lwm2m_object_is_resource_boolean(const lwm2m_resource_t *resource); + +static inline int +lwm2m_object_is_resource_callback(const lwm2m_resource_t *resource) +{ + return resource != NULL && resource->type == LWM2M_RESOURCE_TYPE_CALLBACK; +} + +const uint8_t * +lwm2m_object_get_resource_string(const lwm2m_resource_t *resource, + const lwm2m_context_t *context); + +uint16_t +lwm2m_object_get_resource_strlen(const lwm2m_resource_t *resource, + const lwm2m_context_t *context); + +int +lwm2m_object_set_resource_string(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + uint16_t len, const uint8_t *string); + +int +lwm2m_object_get_resource_int(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int32_t *value); + +int +lwm2m_object_set_resource_int(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int32_t value); + +int +lwm2m_object_get_resource_floatfix(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int32_t *value); + +int +lwm2m_object_set_resource_floatfix(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int32_t value); + +int +lwm2m_object_get_resource_boolean(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int *value); + +int +lwm2m_object_set_resource_boolean(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int value); + +static inline resource_t * +lwm2m_object_get_coap_resource(const lwm2m_object_t *object) +{ + return (resource_t *)object->coap_resource; +} + +static inline void +lwm2m_object_notify_observers(const lwm2m_object_t *object, char *path) +{ + coap_notify_observers_sub(lwm2m_object_get_coap_resource(object), path); +} + +#include "lwm2m-engine.h" + +#endif /* LWM2M_OBJECT_H_ */ +/** + * @} + * @} + */ diff --git a/apps/oma-lwm2m/lwm2m-plain-text.c b/apps/oma-lwm2m/lwm2m-plain-text.c new file mode 100644 index 000000000..b2bc5dcbe --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-plain-text.c @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M plain text reader / writer + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "lwm2m-object.h" +#include "lwm2m-plain-text.h" +#include +#include +#include + +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/*---------------------------------------------------------------------------*/ +size_t +lwm2m_plain_text_read_int(const uint8_t *inbuf, size_t len, int32_t *value) +{ + int i, neg = 0; + *value = 0; + for(i = 0; i < len; i++) { + if(inbuf[i] >= '0' && inbuf[i] <= '9') { + *value = *value * 10 + (inbuf[i] - '0'); + } else if(inbuf[i] == '-' && i == 0) { + neg = 1; + } else { + break; + } + } + if(neg) { + *value = -*value; + } + return i; +} +/*---------------------------------------------------------------------------*/ +size_t +lwm2m_plain_text_read_float32fix(const uint8_t *inbuf, size_t len, + int32_t *value, int bits) +{ + int i, dot = 0, neg = 0; + int32_t counter, integerpart, frac; + + integerpart = 0; + counter = 0; + frac = 0; + for(i = 0; i < len; i++) { + if(inbuf[i] >= '0' && inbuf[i] <= '9') { + counter = counter * 10 + (inbuf[i] - '0'); + frac = frac * 10; + } else if(inbuf[i] == '.' && dot == 0) { + integerpart = counter; + counter = 0; + frac = 1; + dot = 1; + } else if(inbuf[i] == '-' && i == 0) { + neg = 1; + } else { + break; + } + } + if(dot == 0) { + integerpart = counter; + counter = 0; + frac = 1; + } + *value = integerpart << bits; + if(frac > 1) { + *value += ((counter << bits) / frac); + } + PRINTF("READ FLOATFIX: \"%.*s\" => int(%ld) frac(%ld) f=%ld Value=%ld\n", + (int)len, (char *)inbuf, + (long)integerpart, + (long)counter, + (long)frac, + (long)*value); + if(neg) { + *value = -*value; + } + return i; +} +/*---------------------------------------------------------------------------*/ +size_t +lwm2m_plain_text_write_float32fix(uint8_t *outbuf, size_t outlen, + int32_t value, int bits) +{ + int64_t v; + unsigned long integer_part; + unsigned long frac_part; + int n, o = 0; + + if(outlen == 0) { + return 0; + } + if(value < 0) { + *outbuf++ = '-'; + outlen--; + o = 1; + value = -value; + } + + integer_part = (unsigned long)(value >> bits); + v = value - (integer_part << bits); + v = (v * 100) >> bits; + frac_part = (unsigned long)v; + + n = snprintf((char *)outbuf, outlen, "%lu.%02lu", integer_part, frac_part); + if(n < 0 || n >= outlen) { + return 0; + } + return n + o; +} +/*---------------------------------------------------------------------------*/ +static size_t +write_boolean(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int value) +{ + if(outlen > 0) { + if(value) { + *outbuf = '1'; + } else { + *outbuf = '0'; + } + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static size_t +write_int(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int32_t value) +{ + int n = snprintf((char *)outbuf, outlen, "%ld", (long)value); + if(n < 0 || n >= outlen) { + return 0; + } + return n; +} +/*---------------------------------------------------------------------------*/ +static size_t +write_float32fix(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int32_t value, int bits) +{ + return lwm2m_plain_text_write_float32fix(outbuf, outlen, value, bits); +} +/*---------------------------------------------------------------------------*/ +static size_t +write_string(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + const char *value, size_t stringlen) +{ + int n = snprintf((char *)outbuf, outlen, "%.*s", (int) stringlen, value); + if(n < 0 || n >= outlen) { + return 0; + } + return n; +} +/*---------------------------------------------------------------------------*/ +const lwm2m_writer_t lwm2m_plain_text_writer = { + write_int, + write_string, + write_float32fix, + write_boolean +}; +/*---------------------------------------------------------------------------*/ +static size_t +read_int(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, + int32_t *value) +{ + return lwm2m_plain_text_read_int(inbuf, len, value); +} +/*---------------------------------------------------------------------------*/ +static size_t +read_string(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, + uint8_t *value, size_t stringlen) +{ + if(stringlen <= len) { + /* The outbuffer can not contain the full string including ending zero */ + return 0; + } + memcpy(value, inbuf, len); + value[len] = '\0'; + return len; +} +/*---------------------------------------------------------------------------*/ +static size_t +read_float32fix(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, + int32_t *value, int bits) +{ + return lwm2m_plain_text_read_float32fix(inbuf, len, value, bits); +} +/*---------------------------------------------------------------------------*/ +static size_t +read_boolean(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, + int *value) +{ + if(len > 0) { + if(*inbuf == '1' || *inbuf == '0') { + *value = *inbuf == '1' ? 1 : 0; + return 1; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +const lwm2m_reader_t lwm2m_plain_text_reader = { + read_int, + read_string, + read_float32fix, + read_boolean +}; +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-plain-text.h b/apps/oma-lwm2m/lwm2m-plain-text.h new file mode 100644 index 000000000..bf12a118c --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-plain-text.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + */ + +/** + * \file + * Header file for the Contiki OMA LWM2M plain text reader / writer + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef LWM2M_PLAIN_TEXT_H_ +#define LWM2M_PLAIN_TEXT_H_ + +#include "lwm2m-object.h" + +extern const lwm2m_reader_t lwm2m_plain_text_reader; +extern const lwm2m_writer_t lwm2m_plain_text_writer; + +size_t lwm2m_plain_text_read_int(const uint8_t *inbuf, size_t len, + int32_t *value); + +size_t lwm2m_plain_text_read_float32fix(const uint8_t *inbuf, size_t len, + int32_t *value, int bits); + +size_t lwm2m_plain_text_write_float32fix(uint8_t *outbuf, size_t outlen, + int32_t value, int bits); + +#endif /* LWM2M_PLAIN_TEXT_H_ */ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-security.c b/apps/oma-lwm2m/lwm2m-security.c new file mode 100644 index 000000000..953279b4d --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-security.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + * + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M security + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include +#include "lwm2m-object.h" +#include "lwm2m-engine.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#ifdef LWM2M_CONF_SERVER_MAX_COUNT +#define MAX_COUNT LWM2M_CONF_SERVER_MAX_COUNT +#else +#define MAX_COUNT 2 +#endif + +/* hoping that we do not get more than 64 bytes... */ +#define MAX_SIZE 64 + +static int32_t bs_arr[MAX_COUNT]; +static int32_t secmode_arr[MAX_COUNT]; +static int32_t sid_arr[MAX_COUNT]; + +static char server_uri[MAX_COUNT][MAX_SIZE]; +static uint16_t su_len[MAX_COUNT]; +static char client_id[MAX_COUNT][MAX_SIZE]; +static uint16_t client_id_len[MAX_COUNT]; +static char server_id[MAX_COUNT][MAX_SIZE]; +static uint16_t server_id_len[MAX_COUNT]; +static char psk_key[MAX_COUNT][MAX_SIZE]; +static uint16_t psk_key_len[MAX_COUNT]; +static lwm2m_instance_t security_instances[MAX_COUNT]; + +LWM2M_RESOURCES(security_resources, + LWM2M_RESOURCE_STRING_VAR_ARR(0, MAX_COUNT, MAX_SIZE, su_len, server_uri), + LWM2M_RESOURCE_INTEGER_VAR_ARR(1, MAX_COUNT, bs_arr), + LWM2M_RESOURCE_INTEGER_VAR_ARR(2, MAX_COUNT, secmode_arr), + LWM2M_RESOURCE_STRING_VAR_ARR(3, MAX_COUNT, MAX_SIZE, client_id_len, client_id), + LWM2M_RESOURCE_STRING_VAR_ARR(4, MAX_COUNT, MAX_SIZE, server_id_len, server_id), + /* TODO This should not be readable! */ + LWM2M_RESOURCE_STRING_VAR_ARR(5, MAX_COUNT, MAX_SIZE, psk_key_len, psk_key), + LWM2M_RESOURCE_INTEGER_VAR_ARR(10, MAX_COUNT, sid_arr) + ); +LWM2M_OBJECT(security, 0, security_instances); +/*---------------------------------------------------------------------------*/ +void +lwm2m_security_init(void) +{ + lwm2m_instance_t template = LWM2M_INSTANCE_UNUSED(0, security_resources); + int i; + + /* Initialize the instances */ + for(i = 0; i < MAX_COUNT; i++) { + security_instances[i] = template; + security_instances[i].id = i; + } + + /** + * Register this device and its handlers - the handlers + * automatically sends in the object to handle. + */ + PRINTF("*** Init lwm2m-security\n"); + lwm2m_engine_register_object(&security); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-server.c b/apps/oma-lwm2m/lwm2m-server.c new file mode 100644 index 000000000..9de678682 --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-server.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + * + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M server + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include +#include "lwm2m-object.h" +#include "lwm2m-engine.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#ifdef LWM2M_CONF_SERVER_MAX_COUNT +#define MAX_COUNT LWM2M_CONF_SERVER_MAX_COUNT +#else +#define MAX_COUNT 2 +#endif + +static int32_t sid_arr[MAX_COUNT]; +static int32_t lifetime_arr[MAX_COUNT]; +static lwm2m_instance_t server_instances[MAX_COUNT]; + +LWM2M_RESOURCES(server_resources, + LWM2M_RESOURCE_INTEGER_VAR_ARR(0, MAX_COUNT, sid_arr), + LWM2M_RESOURCE_INTEGER_VAR_ARR(1, MAX_COUNT, lifetime_arr), + ); +LWM2M_OBJECT(server, 1, server_instances); +/*---------------------------------------------------------------------------*/ +void +lwm2m_server_init(void) +{ + lwm2m_instance_t template = LWM2M_INSTANCE_UNUSED(0, server_resources); + int i; + + /* Initialize the instances */ + for(i = 0; i < MAX_COUNT; i++) { + server_instances[i] = template; + server_instances[i].id = i; + } + + /** + * Register this device and its handlers - the handlers + * automatically sends in the object to handle + */ + PRINTF("*** Init lwm2m-server\n"); + lwm2m_engine_register_object(&server); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/oma-tlv-reader.c b/apps/oma-lwm2m/oma-tlv-reader.c new file mode 100644 index 000000000..58e1dcc54 --- /dev/null +++ b/apps/oma-lwm2m/oma-tlv-reader.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + * + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M TLV reader + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "lwm2m-object.h" +#include "oma-tlv-reader.h" +#include "oma-tlv.h" + +/*---------------------------------------------------------------------------*/ +static size_t +read_int(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, + int32_t *value) +{ + oma_tlv_t tlv; + size_t size; + size = oma_tlv_read(&tlv, inbuf, len); + if(size > 0) { + *value = oma_tlv_get_int32(&tlv); + } + return size; +} +/*---------------------------------------------------------------------------*/ +static size_t +read_string(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, + uint8_t *value, size_t stringlen) +{ + oma_tlv_t tlv; + size_t size; + size = oma_tlv_read(&tlv, inbuf, len); + if(size > 0) { + if(stringlen <= tlv.length) { + /* The outbuffer can not contain the full string including ending zero */ + return 0; + } + memcpy(value, tlv.value, tlv.length); + value[tlv.length] = '\0'; + } + return size; +} +/*---------------------------------------------------------------------------*/ +static size_t +read_float32fix(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, + int32_t *value, int bits) +{ + oma_tlv_t tlv; + size_t size; + size = oma_tlv_read(&tlv, inbuf, len); + if(size > 0) { + oma_tlv_float32_to_fix(&tlv, value, bits); + } + return size; +} +/*---------------------------------------------------------------------------*/ +static size_t +read_boolean(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, + int *value) +{ + oma_tlv_t tlv; + size_t size; + size = oma_tlv_read(&tlv, inbuf, len); + if(size > 0) { + *value = oma_tlv_get_int32(&tlv) != 0; + } + return size; +} +/*---------------------------------------------------------------------------*/ +const lwm2m_reader_t oma_tlv_reader = { + read_int, + read_string, + read_float32fix, + read_boolean +}; +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/oma-tlv-reader.h b/apps/oma-lwm2m/oma-tlv-reader.h new file mode 100644 index 000000000..7e6540c18 --- /dev/null +++ b/apps/oma-lwm2m/oma-tlv-reader.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** \addtogroup oma-lwm2m + * @{ */ + +/** + * \file + * Header file for the Contiki OMA LWM2M TLV reader + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef OMA_TLV_READER_H_ +#define OMA_TLV_READER_H_ + +#include "lwm2m-object.h" + +extern const lwm2m_reader_t oma_tlv_reader; + +#endif /* OMA_TLV_READER_H_ */ +/** @} */ diff --git a/apps/oma-lwm2m/oma-tlv-writer.c b/apps/oma-lwm2m/oma-tlv-writer.c new file mode 100644 index 000000000..2f26a69f6 --- /dev/null +++ b/apps/oma-lwm2m/oma-tlv-writer.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + * + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M TLV writer + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "lwm2m-object.h" +#include "oma-tlv.h" +/*---------------------------------------------------------------------------*/ +static size_t +write_boolean_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int value) +{ + return oma_tlv_write_int32(ctx->resource_id, value != 0 ? 1 : 0, + outbuf, outlen); +} +/*---------------------------------------------------------------------------*/ +static size_t +write_int_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int32_t value) +{ + return oma_tlv_write_int32(ctx->resource_id, value, outbuf, outlen); +} +/*---------------------------------------------------------------------------*/ +static size_t +write_float32fix_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf, + size_t outlen, int32_t value, int bits) +{ + return oma_tlv_write_float32(ctx->resource_id, value, bits, outbuf, outlen); +} +/*---------------------------------------------------------------------------*/ +static size_t +write_string_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + const char *value, size_t stringlen) +{ + oma_tlv_t tlv; + tlv.type = OMA_TLV_TYPE_RESOURCE; + tlv.value = (uint8_t *) value; + tlv.length = (uint32_t) stringlen; + tlv.id = ctx->resource_id; + return oma_tlv_write(&tlv, outbuf, outlen); +} +/*---------------------------------------------------------------------------*/ +const lwm2m_writer_t oma_tlv_writer = { + write_int_tlv, + write_string_tlv, + write_float32fix_tlv, + write_boolean_tlv +}; +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/oma-tlv-writer.h b/apps/oma-lwm2m/oma-tlv-writer.h new file mode 100644 index 000000000..6ae5edd14 --- /dev/null +++ b/apps/oma-lwm2m/oma-tlv-writer.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** \addtogroup oma-lwm2m + * @{ */ + +/** + * \file + * Header file for the Contiki OMA LWM2M TLV writer + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef OMA_TLV_WRITER_H_ +#define OMA_TLV_WRITER_H_ + +#include "lwm2m-object.h" + +extern const lwm2m_writer_t oma_tlv_writer; + +#endif /* OMA_TLV_WRITER_H_ */ +/** @} */ diff --git a/apps/oma-lwm2m/oma-tlv.c b/apps/oma-lwm2m/oma-tlv.c new file mode 100644 index 000000000..c07df31cc --- /dev/null +++ b/apps/oma-lwm2m/oma-tlv.c @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + * + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M TLV + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include +#include +#include "oma-tlv.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/*---------------------------------------------------------------------------*/ +static inline uint8_t +get_len_type(const oma_tlv_t *tlv) +{ + if(tlv->length < 8) { + return 0; + } else if(tlv->length < 256) { + return 1; + } else if(tlv->length < 0x10000) { + return 2; + } else { + return 3; + } +} +/*---------------------------------------------------------------------------*/ +size_t +oma_tlv_read(oma_tlv_t *tlv, const uint8_t *buffer, size_t len) +{ + uint8_t len_type; + uint8_t len_pos = 1; + size_t tlv_len; + + tlv->type = (buffer[0] >> 6) & 3; + len_type = (buffer[0] >> 3) & 3; + len_pos = 1 + (((buffer[0] & (1 << 5)) != 0) ? 2 : 1); + + tlv->id = buffer[1]; + /* if len_pos is larger than two it means that there is more ID to read */ + if(len_pos > 2) { + tlv->id = (tlv->id << 8) + buffer[2]; + } + + if(len_type == 0) { + tlv_len = buffer[0] & 7; + } else { + /* read the length */ + tlv_len = 0; + while(len_type > 0) { + tlv_len = tlv_len << 8 | buffer[len_pos++]; + len_type--; + } + } + /* and read out the data??? */ + tlv->length = tlv_len; + tlv->value = &buffer[len_pos]; + + return len_pos + tlv_len; +} +/*---------------------------------------------------------------------------*/ +size_t +oma_tlv_get_size(const oma_tlv_t *tlv) +{ + size_t size; + /* first hdr + len size */ + size = 1 + get_len_type(tlv); + /* id size */ + size += (tlv->id > 255) ? 2 : 1; + + /* and the length */ + size += tlv->length; + return size; +} +/*---------------------------------------------------------------------------*/ +size_t +oma_tlv_write(const oma_tlv_t *tlv, uint8_t *buffer, size_t len) +{ + int pos; + uint8_t len_type; + + /* len type is the same as number of bytes required for length */ + len_type = get_len_type(tlv); + pos = 1 + len_type; + /* ensure that we do not write too much */ + if(len < tlv->length + pos) { + PRINTF("OMA-TLV: Could not write the TLV - buffer overflow.\n"); + return 0; + } + + /* first type byte in TLV header */ + buffer[0] = (tlv->type << 6) | + (tlv->id > 255 ? (1 << 5) : 0) | + (len_type << 3) | + (len_type == 0 ? tlv->length : 0); + + pos = 1; + /* The ID */ + if(tlv->id > 255) { + buffer[pos++] = (tlv->id >> 8) & 0xff; + } + buffer[pos++] = tlv->id & 0xff; + /* Add length if needed - unrolled loop ? */ + if(len_type > 2) { + buffer[pos++] = (tlv->length >> 16) & 0xff; + } + if(len_type > 1) { + buffer[pos++] = (tlv->length >> 8) & 0xff; + } + if(len_type > 0) { + buffer[pos++] = tlv->length & 0xff; + } + + /* finally add the value */ + memcpy(&buffer[pos], tlv->value, tlv->length); + + if(DEBUG) { + int i; + PRINTF("TLV:"); + for(i = 0; i < pos + tlv->length; i++) { + PRINTF("%02x", buffer[i]); + } + PRINTF("\n"); + } + + return pos + tlv->length; +} +/*---------------------------------------------------------------------------*/ +int32_t +oma_tlv_get_int32(const oma_tlv_t *tlv) +{ + int i; + int32_t value = 0; + /* will probably need to handle MSB as a sign bit? */ + for(i = 0; i < tlv->length; i++) { + value = (value << 8) | tlv->value[i]; + } + return value; +} +/*---------------------------------------------------------------------------*/ +size_t +oma_tlv_write_int32(int16_t id, int32_t value, uint8_t *buffer, size_t len) +{ + oma_tlv_t tlv; + size_t tlvlen = 0; + uint8_t buf[4]; + int i; + PRINTF("Exporting int32 %d %ld ", id, (long)value); + + buf[3] = value & 0xff; + value = value >> 8; + for(i = 1; value > 0 && i < 4; i++) { + buf[3 - i] = value & 0xff; + value = value >> 8; + } + tlvlen = i; + + /* export INT as TLV */ + PRINTF("len: %zu\n", tlvlen); + tlv.type = OMA_TLV_TYPE_RESOURCE; + tlv.length = tlvlen; + tlv.value = &buf[3 - (tlvlen - 1)]; + tlv.id = id; + return oma_tlv_write(&tlv, buffer, len); +} +/*---------------------------------------------------------------------------*/ +/* convert fixpoint 32-bit to a IEEE Float in the byte array*/ +size_t +oma_tlv_write_float32(int16_t id, int32_t value, int bits, + uint8_t *buffer, size_t len) +{ + int i; + int e = 0; + int32_t val = 0; + int32_t v; + uint8_t b[4]; + oma_tlv_t tlv; + + v = value; + if(v < 0) { + v = -v; + } + + while(v > 1) { + val = (val >> 1); + if (v & 1) { + val = val | (1L << 22); + } + v = (v >> 1); + e++; + } + + PRINTF("Sign: %d, Fraction: %06lx 0b", value < 0, (long)val); + for(i = 0; i < 23; i++) { + PRINTF("%d", (int)((val >> (22 - i)) & 1)); + } + PRINTF("\nExp:%d\n", e); + + /* convert to the thing we should have */ + e = e - bits + 127; + + /* is this the right byte order? */ + b[0] = (value < 0 ? 0x80 : 0) | (e >> 1); + b[1] = ((e & 1) << 7) | ((val >> 16) & 0x7f); + b[2] = (val >> 8) & 0xff; + b[3] = val & 0xff; + + /* construct the TLV */ + tlv.type = OMA_TLV_TYPE_RESOURCE; + tlv.length = 4; + tlv.value = b; + tlv.id = id; + + return oma_tlv_write(&tlv, buffer, len); +} +/*---------------------------------------------------------------------------*/ +/* convert float to fixpoint */ +size_t +oma_tlv_float32_to_fix(const oma_tlv_t *tlv, int32_t *value, int bits) +{ + /* TLV needs to be 4 bytes */ + int e, i; + int32_t val; + int sign = (tlv->value[0] & 0x80) != 0; + e = ((tlv->value[0] << 1) & 0xff) | (tlv->value[1] >> 7); + val = (((long)tlv->value[1] & 0x7f) << 16) | (tlv->value[2] << 8) | tlv->value[3]; + + PRINTF("Sign: %d, Fraction: %06lx 0b", val < 0, (long)val); + for(i = 0; i < 23; i++) { + PRINTF("%d", (int)((val >> (22 - i)) & 1)); + } + PRINTF("\nExp:%d => %d\n", e, e - 127); + + e = e - 127 + bits; + + /* e corresponds to the number of times we need to roll the number */ + + PRINTF("Actual e=%d\n", e); + e = e - 23; + PRINTF("E after sub %d\n", e); + val = val | 1L << 23; + if(e > 0) { + val = val << e; + } else { + val = val >> -e; + } + + *value = sign ? -val : val; + return 4; +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/oma-tlv.h b/apps/oma-lwm2m/oma-tlv.h new file mode 100644 index 000000000..1bd5fd94a --- /dev/null +++ b/apps/oma-lwm2m/oma-tlv.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +/** \addtogroup oma-lwm2m + * @{ */ + +/** + * \file + * Header file for the Contiki OMA LWM2M TLV + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef OAM_TLV_H_ +#define OAM_TLV_H_ + +#include "contiki.h" + +enum { + OMA_TLV_TYPE_OBJECT_INSTANCE = 0, + OMA_TLV_TYPE_RESOURCE_INSTANCE = 1, + OMA_TLV_TYPE_MULTI_RESOURCE = 2, + OMA_TLV_TYPE_RESOURCE = 3 +}; +typedef uint8_t oma_tlv_type_t; + +typedef enum { + OMA_TLV_LEN_TYPE_NO_LEN = 0, + OMA_TLV_LEN_TYPE_8BIT_LEN = 1, + OMA_TLV_LEN_TYPE_16BIT_LEN = 2, + OMA_TLV_LEN_TYPE_24BIT_LEN = 3 +} oma_tlv_len_type_t; + +typedef struct { + oma_tlv_type_t type; + uint16_t id; /* can be 8-bit or 16-bit when serialized */ + uint32_t length; + const uint8_t *value; +} oma_tlv_t; + +size_t oma_tlv_get_size(const oma_tlv_t *tlv); + +/* read a TLV from the buffer */ +size_t oma_tlv_read(oma_tlv_t *tlv, const uint8_t *buffer, size_t len); + +/* write a TLV to the buffer */ +size_t oma_tlv_write(const oma_tlv_t *tlv, uint8_t *buffer, size_t len); + +int32_t oma_tlv_get_int32(const oma_tlv_t *tlv); + +/* write a int as a TLV to the buffer */ +size_t oma_tlv_write_int32(int16_t id, int32_t value, uint8_t *buffer, size_t len); + +/* write a float converted from fixpoint as a TLV to the buffer */ +size_t oma_tlv_write_float32(int16_t id, int32_t value, int bits, uint8_t *buffer, size_t len); + +/* convert TLV with float32 to fixpoint */ +size_t oma_tlv_float32_to_fix(const oma_tlv_t *tlv, int32_t *value, int bits); + +#endif /* OAM_TLV_H_ */ +/** @} */ diff --git a/apps/orchestra/Makefile.orchestra b/apps/orchestra/Makefile.orchestra new file mode 100644 index 000000000..8c30a816e --- /dev/null +++ b/apps/orchestra/Makefile.orchestra @@ -0,0 +1 @@ +orchestra_src = orchestra.c orchestra-rule-default-common.c orchestra-rule-eb-per-time-source.c orchestra-rule-unicast-per-neighbor-rpl-storing.c orchestra-rule-unicast-per-neighbor-rpl-ns.c diff --git a/apps/orchestra/README.md b/apps/orchestra/README.md new file mode 100644 index 000000000..3a15b2e71 --- /dev/null +++ b/apps/orchestra/README.md @@ -0,0 +1,51 @@ +# Orchestra + +## Overview + +Orchestra is an autonomous scheduling solution for TSCH, where nodes maintain +their own schedule solely based on their local RPL state. There is no centralized +scheduler nor negociatoin with neighbors, i.e. no traffic overhead. The default +Orchestra rules can be used out-of-box in any RPL network, reducing contention +to a low level. Orchestra is described and evaluated in +[*Orchestra: Robust Mesh Networks Through Autonomously Scheduled TSCH*](http://www.simonduquennoy.net/papers/duquennoy15orchestra.pdf), ACM SenSys'15. + +## Requirements + +Orchestra requires a system running TSCH and RPL. +For sender-based unicast slots (`ORCHESTRA_UNICAST_SENDER_BASED`), it requires +RPL with downwards routing enabled (relies on DAO). + +## Getting Started + +To use Orchestra, add a couple global definitions, e.g in your `project-conf.h` file. + +Disable 6TiSCH minimal schedule: + +`#define TSCH_SCHEDULE_CONF_WITH_6TISCH_MINIMAL 0` + +Enable TSCH link selector (allows Orchestra to assign TSCH links to outgoing packets): + +`#define TSCH_CONF_WITH_LINK_SELECTOR 1` + +Set up the following callbacks: + +``` +#define TSCH_CALLBACK_NEW_TIME_SOURCE orchestra_callback_new_time_source +#define TSCH_CALLBACK_PACKET_READY orchestra_callback_packet_ready +#define NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK orchestra_callback_child_added +#define NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK orchestra_callback_child_removed +``` + +To use Orchestra, fist add it to your makefile `APPS` with `APPS += orchestra`. + +Finally: +* add Orchestra to your makefile `APPS` with `APPS += orchestra`; +* start Orchestra by calling `orchestra_init()` from your application, after +including `#include "orchestra.h"`. + +## Configuration + +Orchestra comes with a number of pre-installed rules, `orchestra-rule-*.c`. +You can define your own by using any of these as a template. +A default Orchestra configuration is described in `orchestra-conf.h`, define your own +`ORCHESTRA_CONF_*` macros to override modify the rule set and change rules configuration. diff --git a/apps/orchestra/orchestra-conf.h b/apps/orchestra/orchestra-conf.h new file mode 100644 index 000000000..d8116ff16 --- /dev/null +++ b/apps/orchestra/orchestra-conf.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2015, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file + * Orchestra configuration + * + * \author Simon Duquennoy + */ + +#ifndef __ORCHESTRA_CONF_H__ +#define __ORCHESTRA_CONF_H__ + +#ifdef ORCHESTRA_CONF_RULES +#define ORCHESTRA_RULES ORCHESTRA_CONF_RULES +#else /* ORCHESTRA_CONF_RULES */ +/* A default configuration with: + * - a sender-based slotframe for EB transmission + * - a sender-based or receiver-based slotframe for unicast to RPL parents and children + * - a common shared slotframe for any other traffic (mostly broadcast) + * */ +#define ORCHESTRA_RULES { &eb_per_time_source, &unicast_per_neighbor_rpl_storing, &default_common } +/* Example configuration for RPL non-storing mode: */ +/* #define ORCHESTRA_RULES { &eb_per_time_source, &unicast_per_neighbor_rpl_ns, &default_common } */ + +#endif /* ORCHESTRA_CONF_RULES */ + +/* Length of the various slotframes. Tune to balance network capacity, + * contention, energy, latency. */ +#ifdef ORCHESTRA_CONF_EBSF_PERIOD +#define ORCHESTRA_EBSF_PERIOD ORCHESTRA_CONF_EBSF_PERIOD +#else /* ORCHESTRA_CONF_EBSF_PERIOD */ +#define ORCHESTRA_EBSF_PERIOD 397 +#endif /* ORCHESTRA_CONF_EBSF_PERIOD */ + +#ifdef ORCHESTRA_CONF_COMMON_SHARED_PERIOD +#define ORCHESTRA_COMMON_SHARED_PERIOD ORCHESTRA_CONF_COMMON_SHARED_PERIOD +#else /* ORCHESTRA_CONF_COMMON_SHARED_PERIOD */ +#define ORCHESTRA_COMMON_SHARED_PERIOD 31 +#endif /* ORCHESTRA_CONF_COMMON_SHARED_PERIOD */ + +#ifdef ORCHESTRA_CONF_UNICAST_PERIOD +#define ORCHESTRA_UNICAST_PERIOD ORCHESTRA_CONF_UNICAST_PERIOD +#else /* ORCHESTRA_CONF_UNICAST_PERIOD */ +#define ORCHESTRA_UNICAST_PERIOD 17 +#endif /* ORCHESTRA_CONF_UNICAST_PERIOD */ + +/* Is the per-neighbor unicast slotframe sender-based (if not, it is receiver-based). + * Note: sender-based works only with RPL storing mode as it relies on DAO and + * routing entries to keep track of children and parents. */ +#ifdef ORCHESTRA_CONF_UNICAST_SENDER_BASED +#define ORCHESTRA_UNICAST_SENDER_BASED ORCHESTRA_CONF_UNICAST_SENDER_BASED +#else /* ORCHESTRA_CONF_UNICAST_SENDER_BASED */ +#define ORCHESTRA_UNICAST_SENDER_BASED 0 +#endif /* ORCHESTRA_CONF_UNICAST_SENDER_BASED */ + +/* The hash function used to assign timeslot to a given node (based on its link-layer address) */ +#ifdef ORCHESTRA_CONF_LINKADDR_HASH +#define ORCHESTRA_LINKADDR_HASH ORCHESTRA_CONF_LINKADDR_HASH +#else /* ORCHESTRA_CONF_LINKADDR_HASH */ +#define ORCHESTRA_LINKADDR_HASH(addr) ((addr != NULL) ? (addr)->u8[LINKADDR_SIZE - 1] : -1) +#endif /* ORCHESTRA_CONF_LINKADDR_HASH */ + +/* The maximum hash */ +#ifdef ORCHESTRA_CONF_MAX_HASH +#define ORCHESTRA_MAX_HASH ORCHESTRA_CONF_MAX_HASH +#else /* ORCHESTRA_CONF_MAX_HASH */ +#define ORCHESTRA_MAX_HASH 0x7fff +#endif /* ORCHESTRA_CONF_MAX_HASH */ + +/* Is the "hash" function collision-free? (e.g. it maps to unique node-ids) */ +#ifdef ORCHESTRA_CONF_COLLISION_FREE_HASH +#define ORCHESTRA_COLLISION_FREE_HASH ORCHESTRA_CONF_COLLISION_FREE_HASH +#else /* ORCHESTRA_CONF_COLLISION_FREE_HASH */ +#define ORCHESTRA_COLLISION_FREE_HASH 0 /* Set to 1 if ORCHESTRA_LINKADDR_HASH returns unique hashes */ +#endif /* ORCHESTRA_CONF_COLLISION_FREE_HASH */ + +#endif /* __ORCHESTRA_CONF_H__ */ diff --git a/apps/orchestra/orchestra-rule-default-common.c b/apps/orchestra/orchestra-rule-default-common.c new file mode 100644 index 000000000..49ac3b496 --- /dev/null +++ b/apps/orchestra/orchestra-rule-default-common.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2015, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \file + * Orchestra: a slotframe with a single shared link, common to all nodes + * in the network, used for unicast and broadcast. + * + * \author Simon Duquennoy + */ + +#include "contiki.h" +#include "orchestra.h" + +static uint16_t slotframe_handle = 0; +static uint16_t channel_offset = 0; + +#if ORCHESTRA_EBSF_PERIOD > 0 +/* There is a slotframe for EBs, use this slotframe for non-EB traffic only */ +#define ORCHESTRA_COMMON_SHARED_TYPE LINK_TYPE_NORMAL +#else +/* There is no slotframe for EBs, use this slotframe both EB and non-EB traffic */ +#define ORCHESTRA_COMMON_SHARED_TYPE LINK_TYPE_ADVERTISING +#endif + +/*---------------------------------------------------------------------------*/ +static int +select_packet(uint16_t *slotframe, uint16_t *timeslot) +{ + /* We are the default slotframe, select anything */ + if(slotframe != NULL) { + *slotframe = slotframe_handle; + } + if(timeslot != NULL) { + *timeslot = 0; + } + return 1; +} +/*---------------------------------------------------------------------------*/ +static void +init(uint16_t sf_handle) +{ + slotframe_handle = sf_handle; + channel_offset = slotframe_handle; + /* Default slotframe: for broadcast or unicast to neighbors we + * do not have a link to */ + struct tsch_slotframe *sf_common = tsch_schedule_add_slotframe(slotframe_handle, ORCHESTRA_COMMON_SHARED_PERIOD); + tsch_schedule_add_link(sf_common, + LINK_OPTION_RX | LINK_OPTION_TX | LINK_OPTION_SHARED, + ORCHESTRA_COMMON_SHARED_TYPE, &tsch_broadcast_address, + 0, channel_offset); +} +/*---------------------------------------------------------------------------*/ +struct orchestra_rule default_common = { + init, + NULL, + select_packet, + NULL, + NULL, +}; diff --git a/apps/orchestra/orchestra-rule-eb-per-time-source.c b/apps/orchestra/orchestra-rule-eb-per-time-source.c new file mode 100644 index 000000000..ed037291b --- /dev/null +++ b/apps/orchestra/orchestra-rule-eb-per-time-source.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2015, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \file + + * Orchestra: a slotframe dedicated to transmission of EBs. + * Nodes transmit at a timeslot defined as hash(MAC) % ORCHESTRA_EBSF_PERIOD + * Nodes listen at a timeslot defined as hash(time_source.MAC) % ORCHESTRA_EBSF_PERIOD + * \author Simon Duquennoy + */ + +#include "contiki.h" +#include "orchestra.h" +#include "net/packetbuf.h" + +static uint16_t slotframe_handle = 0; +static uint16_t channel_offset = 0; +static struct tsch_slotframe *sf_eb; + +/*---------------------------------------------------------------------------*/ +static uint16_t +get_node_timeslot(const linkaddr_t *addr) +{ +#if ORCHESTRA_EBSF_PERIOD > 0 + return ORCHESTRA_LINKADDR_HASH(addr) % ORCHESTRA_EBSF_PERIOD; +#else + return 0xffff; +#endif +} +/*---------------------------------------------------------------------------*/ +static int +select_packet(uint16_t *slotframe, uint16_t *timeslot) +{ + /* Select EBs only */ + if(packetbuf_attr(PACKETBUF_ATTR_FRAME_TYPE) == FRAME802154_BEACONFRAME) { + if(slotframe != NULL) { + *slotframe = slotframe_handle; + } + if(timeslot != NULL) { + *timeslot = get_node_timeslot(&linkaddr_node_addr); + } + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +new_time_source(const struct tsch_neighbor *old, const struct tsch_neighbor *new) +{ + uint16_t old_ts = old != NULL ? get_node_timeslot(&old->addr) : 0xffff; + uint16_t new_ts = new != NULL ? get_node_timeslot(&new->addr) : 0xffff; + + if(new_ts == old_ts) { + return; + } + + if(old_ts != 0xffff) { + /* Stop listening to the old time source's EBs */ + if(old_ts == get_node_timeslot(&linkaddr_node_addr)) { + /* This was the same timeslot as slot. Reset original link options */ + tsch_schedule_add_link(sf_eb, LINK_OPTION_TX, LINK_TYPE_ADVERTISING_ONLY, + &tsch_broadcast_address, old_ts, 0); + } else { + /* Remove slot */ + tsch_schedule_remove_link_by_timeslot(sf_eb, old_ts); + } + } + if(new_ts != 0xffff) { + uint8_t link_options = LINK_OPTION_RX; + if(new_ts == get_node_timeslot(&linkaddr_node_addr)) { + /* This is also our timeslot, add necessary flags */ + link_options |= LINK_OPTION_TX; + } + /* Listen to the time source's EBs */ + tsch_schedule_add_link(sf_eb, link_options, LINK_TYPE_ADVERTISING_ONLY, + &tsch_broadcast_address, new_ts, 0); + } +} +/*---------------------------------------------------------------------------*/ +static void +init(uint16_t sf_handle) +{ + slotframe_handle = sf_handle; + channel_offset = sf_handle; + sf_eb = tsch_schedule_add_slotframe(slotframe_handle, ORCHESTRA_EBSF_PERIOD); + /* EB link: every neighbor uses its own to avoid contention */ + tsch_schedule_add_link(sf_eb, + LINK_OPTION_TX, + LINK_TYPE_ADVERTISING_ONLY, &tsch_broadcast_address, + get_node_timeslot(&linkaddr_node_addr), 0); +} +/*---------------------------------------------------------------------------*/ +struct orchestra_rule eb_per_time_source = { + init, + new_time_source, + select_packet, + NULL, + NULL, +}; diff --git a/apps/orchestra/orchestra-rule-unicast-per-neighbor-rpl-ns.c b/apps/orchestra/orchestra-rule-unicast-per-neighbor-rpl-ns.c new file mode 100644 index 000000000..d72646e1d --- /dev/null +++ b/apps/orchestra/orchestra-rule-unicast-per-neighbor-rpl-ns.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2016, Inria. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \file + * Orchestra: a slotframe dedicated to unicast data transmission. Designed primarily + * for RPL non-storing mode but would work with any mode-of-operation. Does not require + * any knowledge of the children. Works only as received-base, and as follows: + * Nodes listen at a timeslot defined as hash(MAC) % ORCHESTRA_SB_UNICAST_PERIOD + * Nodes transmit at: for any neighbor, hash(nbr.MAC) % ORCHESTRA_SB_UNICAST_PERIOD + * + * \author Simon Duquennoy + */ + +#include "contiki.h" +#include "orchestra.h" +#include "net/ipv6/uip-ds6-route.h" +#include "net/packetbuf.h" + +static uint16_t slotframe_handle = 0; +static uint16_t channel_offset = 0; +static struct tsch_slotframe *sf_unicast; + +/*---------------------------------------------------------------------------*/ +static uint16_t +get_node_timeslot(const linkaddr_t *addr) +{ + if(addr != NULL && ORCHESTRA_UNICAST_PERIOD > 0) { + return ORCHESTRA_LINKADDR_HASH(addr) % ORCHESTRA_UNICAST_PERIOD; + } else { + return 0xffff; + } +} +/*---------------------------------------------------------------------------*/ +static void +child_added(const linkaddr_t *linkaddr) +{ +} +/*---------------------------------------------------------------------------*/ +static void +child_removed(const linkaddr_t *linkaddr) +{ +} +/*---------------------------------------------------------------------------*/ +static int +select_packet(uint16_t *slotframe, uint16_t *timeslot) +{ + /* Select data packets we have a unicast link to */ + const linkaddr_t *dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER); + if(packetbuf_attr(PACKETBUF_ATTR_FRAME_TYPE) == FRAME802154_DATAFRAME + && !linkaddr_cmp(dest, &linkaddr_null)) { + if(slotframe != NULL) { + *slotframe = slotframe_handle; + } + if(timeslot != NULL) { + *timeslot = get_node_timeslot(dest); + } + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +new_time_source(const struct tsch_neighbor *old, const struct tsch_neighbor *new) +{ +} +/*---------------------------------------------------------------------------*/ +static void +init(uint16_t sf_handle) +{ + int i; + uint16_t rx_timeslot; + slotframe_handle = sf_handle; + channel_offset = sf_handle; + /* Slotframe for unicast transmissions */ + sf_unicast = tsch_schedule_add_slotframe(slotframe_handle, ORCHESTRA_UNICAST_PERIOD); + rx_timeslot = get_node_timeslot(&linkaddr_node_addr); + /* Add a Tx link at each available timeslot. Make the link Rx at our own timeslot. */ + for(i = 0; i < ORCHESTRA_UNICAST_PERIOD; i++) { + tsch_schedule_add_link(sf_unicast, + LINK_OPTION_SHARED | LINK_OPTION_TX | ( i == rx_timeslot ? LINK_OPTION_RX : 0 ), + LINK_TYPE_NORMAL, &tsch_broadcast_address, + i, channel_offset); + } +} +/*---------------------------------------------------------------------------*/ +struct orchestra_rule unicast_per_neighbor_rpl_ns = { + init, + new_time_source, + select_packet, + child_added, + child_removed, +}; diff --git a/apps/orchestra/orchestra-rule-unicast-per-neighbor-rpl-storing.c b/apps/orchestra/orchestra-rule-unicast-per-neighbor-rpl-storing.c new file mode 100644 index 000000000..76e039f09 --- /dev/null +++ b/apps/orchestra/orchestra-rule-unicast-per-neighbor-rpl-storing.c @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2015, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \file + * Orchestra: a slotframe dedicated to unicast data transmission. Designed for + * RPL storing mode only, as this is based on the knowledge of the children (and parent). + * If receiver-based: + * Nodes listen at a timeslot defined as hash(MAC) % ORCHESTRA_SB_UNICAST_PERIOD + * Nodes transmit at: for each nbr in RPL children and RPL preferred parent, + * hash(nbr.MAC) % ORCHESTRA_SB_UNICAST_PERIOD + * If sender-based: the opposite + * + * \author Simon Duquennoy + */ + +#include "contiki.h" +#include "orchestra.h" +#include "net/ipv6/uip-ds6-route.h" +#include "net/packetbuf.h" +#include "net/rpl/rpl-conf.h" + +#if ORCHESTRA_UNICAST_SENDER_BASED && ORCHESTRA_COLLISION_FREE_HASH +#define UNICAST_SLOT_SHARED_FLAG ((ORCHESTRA_UNICAST_PERIOD < (ORCHESTRA_MAX_HASH + 1)) ? LINK_OPTION_SHARED : 0) +#else +#define UNICAST_SLOT_SHARED_FLAG LINK_OPTION_SHARED +#endif + +static uint16_t slotframe_handle = 0; +static uint16_t channel_offset = 0; +static struct tsch_slotframe *sf_unicast; + +/*---------------------------------------------------------------------------*/ +static uint16_t +get_node_timeslot(const linkaddr_t *addr) +{ + if(addr != NULL && ORCHESTRA_UNICAST_PERIOD > 0) { + return ORCHESTRA_LINKADDR_HASH(addr) % ORCHESTRA_UNICAST_PERIOD; + } else { + return 0xffff; + } +} +/*---------------------------------------------------------------------------*/ +static int +neighbor_has_uc_link(const linkaddr_t *linkaddr) +{ + if(linkaddr != NULL && !linkaddr_cmp(linkaddr, &linkaddr_null)) { + if((orchestra_parent_knows_us || !ORCHESTRA_UNICAST_SENDER_BASED) + && linkaddr_cmp(&orchestra_parent_linkaddr, linkaddr)) { + return 1; + } + if(nbr_table_get_from_lladdr(nbr_routes, (linkaddr_t *)linkaddr) != NULL) { + return 1; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +add_uc_link(const linkaddr_t *linkaddr) +{ + if(linkaddr != NULL) { + uint16_t timeslot = get_node_timeslot(linkaddr); + uint8_t link_options = ORCHESTRA_UNICAST_SENDER_BASED ? LINK_OPTION_RX : LINK_OPTION_TX | UNICAST_SLOT_SHARED_FLAG; + + if(timeslot == get_node_timeslot(&linkaddr_node_addr)) { + /* This is also our timeslot, add necessary flags */ + link_options |= ORCHESTRA_UNICAST_SENDER_BASED ? LINK_OPTION_TX | UNICAST_SLOT_SHARED_FLAG: LINK_OPTION_RX; + } + + /* Add/update link */ + tsch_schedule_add_link(sf_unicast, link_options, LINK_TYPE_NORMAL, &tsch_broadcast_address, + timeslot, channel_offset); + } +} +/*---------------------------------------------------------------------------*/ +static void +remove_uc_link(const linkaddr_t *linkaddr) +{ + uint16_t timeslot; + struct tsch_link *l; + + if(linkaddr == NULL) { + return; + } + + timeslot = get_node_timeslot(linkaddr); + l = tsch_schedule_get_link_by_timeslot(sf_unicast, timeslot); + if(l == NULL) { + return; + } + /* Does our current parent need this timeslot? */ + if(timeslot == get_node_timeslot(&orchestra_parent_linkaddr)) { + /* Yes, this timeslot is being used, return */ + return; + } + /* Does any other child need this timeslot? + * (lookup all route next hops) */ + nbr_table_item_t *item = nbr_table_head(nbr_routes); + while(item != NULL) { + linkaddr_t *addr = nbr_table_get_lladdr(nbr_routes, item); + if(timeslot == get_node_timeslot(addr)) { + /* Yes, this timeslot is being used, return */ + return; + } + item = nbr_table_next(nbr_routes, item); + } + + /* Do we need this timeslot? */ + if(timeslot == get_node_timeslot(&linkaddr_node_addr)) { + /* This is our link, keep it but update the link options */ + uint8_t link_options = ORCHESTRA_UNICAST_SENDER_BASED ? LINK_OPTION_TX | UNICAST_SLOT_SHARED_FLAG: LINK_OPTION_RX; + tsch_schedule_add_link(sf_unicast, link_options, LINK_TYPE_NORMAL, &tsch_broadcast_address, + timeslot, channel_offset); + } else { + /* Remove link */ + tsch_schedule_remove_link(sf_unicast, l); + } +} +/*---------------------------------------------------------------------------*/ +static void +child_added(const linkaddr_t *linkaddr) +{ + add_uc_link(linkaddr); +} +/*---------------------------------------------------------------------------*/ +static void +child_removed(const linkaddr_t *linkaddr) +{ + remove_uc_link(linkaddr); +} +/*---------------------------------------------------------------------------*/ +static int +select_packet(uint16_t *slotframe, uint16_t *timeslot) +{ + /* Select data packets we have a unicast link to */ + const linkaddr_t *dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER); + if(packetbuf_attr(PACKETBUF_ATTR_FRAME_TYPE) == FRAME802154_DATAFRAME + && neighbor_has_uc_link(dest)) { + if(slotframe != NULL) { + *slotframe = slotframe_handle; + } + if(timeslot != NULL) { + *timeslot = ORCHESTRA_UNICAST_SENDER_BASED ? get_node_timeslot(&linkaddr_node_addr) : get_node_timeslot(dest); + } + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +new_time_source(const struct tsch_neighbor *old, const struct tsch_neighbor *new) +{ + if(new != old) { + const linkaddr_t *old_addr = old != NULL ? &old->addr : NULL; + const linkaddr_t *new_addr = new != NULL ? &new->addr : NULL; + if(new_addr != NULL) { + linkaddr_copy(&orchestra_parent_linkaddr, new_addr); + } else { + linkaddr_copy(&orchestra_parent_linkaddr, &linkaddr_null); + } + remove_uc_link(old_addr); + add_uc_link(new_addr); + } +} +/*---------------------------------------------------------------------------*/ +static void +init(uint16_t sf_handle) +{ + slotframe_handle = sf_handle; + channel_offset = sf_handle; + /* Slotframe for unicast transmissions */ + sf_unicast = tsch_schedule_add_slotframe(slotframe_handle, ORCHESTRA_UNICAST_PERIOD); + uint16_t timeslot = get_node_timeslot(&linkaddr_node_addr); + tsch_schedule_add_link(sf_unicast, + ORCHESTRA_UNICAST_SENDER_BASED ? LINK_OPTION_TX | UNICAST_SLOT_SHARED_FLAG: LINK_OPTION_RX, + LINK_TYPE_NORMAL, &tsch_broadcast_address, + timeslot, channel_offset); +} +/*---------------------------------------------------------------------------*/ +struct orchestra_rule unicast_per_neighbor_rpl_storing = { + init, + new_time_source, + select_packet, + child_added, + child_removed, +}; diff --git a/apps/orchestra/orchestra.c b/apps/orchestra/orchestra.c new file mode 100644 index 000000000..52e47a7ff --- /dev/null +++ b/apps/orchestra/orchestra.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2015, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file + * Orchestra: an autonomous scheduler for TSCH exploiting RPL state. + * See "Orchestra: Robust Mesh Networks Through Autonomously Scheduled TSCH", ACM SenSys'15 + * + * \author Simon Duquennoy + */ + +#include "contiki.h" +#include "orchestra.h" +#include "net/packetbuf.h" +#include "net/ipv6/uip-icmp6.h" +#include "net/rpl/rpl-private.h" +#include "net/rime/rime.h" /* Needed for so-called rime-sniffer */ + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +/* A net-layer sniffer for packets sent and received */ +static void orchestra_packet_received(void); +static void orchestra_packet_sent(int mac_status); +RIME_SNIFFER(orchestra_sniffer, orchestra_packet_received, orchestra_packet_sent); + +/* The current RPL preferred parent's link-layer address */ +linkaddr_t orchestra_parent_linkaddr; +/* Set to one only after getting an ACK for a DAO sent to our preferred parent */ +int orchestra_parent_knows_us = 0; + +/* The set of Orchestra rules in use */ +const struct orchestra_rule *all_rules[] = ORCHESTRA_RULES; +#define NUM_RULES (sizeof(all_rules) / sizeof(struct orchestra_rule *)) + +/*---------------------------------------------------------------------------*/ +static void +orchestra_packet_received(void) +{ +} +/*---------------------------------------------------------------------------*/ +static void +orchestra_packet_sent(int mac_status) +{ + /* Check if our parent just ACKed a DAO */ + if(orchestra_parent_knows_us == 0 + && mac_status == MAC_TX_OK + && packetbuf_attr(PACKETBUF_ATTR_NETWORK_ID) == UIP_PROTO_ICMP6 + && packetbuf_attr(PACKETBUF_ATTR_CHANNEL) == (ICMP6_RPL << 8 | RPL_CODE_DAO)) { + if(!linkaddr_cmp(&orchestra_parent_linkaddr, &linkaddr_null) + && linkaddr_cmp(&orchestra_parent_linkaddr, packetbuf_addr(PACKETBUF_ADDR_RECEIVER))) { + orchestra_parent_knows_us = 1; + } + } +} +/*---------------------------------------------------------------------------*/ +void +orchestra_callback_child_added(const linkaddr_t *addr) +{ + /* Notify all Orchestra rules that a child was added */ + int i; + for(i = 0; i < NUM_RULES; i++) { + if(all_rules[i]->child_added != NULL) { + all_rules[i]->child_added(addr); + } + } +} +/*---------------------------------------------------------------------------*/ +void +orchestra_callback_child_removed(const linkaddr_t *addr) +{ + /* Notify all Orchestra rules that a child was removed */ + int i; + for(i = 0; i < NUM_RULES; i++) { + if(all_rules[i]->child_removed != NULL) { + all_rules[i]->child_removed(addr); + } + } +} +/*---------------------------------------------------------------------------*/ +void +orchestra_callback_packet_ready(void) +{ + int i; + /* By default, use any slotframe, any timeslot */ + uint16_t slotframe = 9; + uint16_t timeslot = 0xffff; + + /* Loop over all rules until finding one able to handle the packet */ + for(i = 0; i < NUM_RULES; i++) { + if(all_rules[i]->select_packet != NULL) { + if(all_rules[i]->select_packet(&slotframe, ×lot)) { + break; + } + } + } + +#if TSCH_WITH_LINK_SELECTOR + packetbuf_set_attr(PACKETBUF_ATTR_TSCH_SLOTFRAME, slotframe); + packetbuf_set_attr(PACKETBUF_ATTR_TSCH_TIMESLOT, timeslot); +#endif +} +/*---------------------------------------------------------------------------*/ +void +orchestra_callback_new_time_source(const struct tsch_neighbor *old, const struct tsch_neighbor *new) +{ + /* Orchestra assumes that the time source is also the RPL parent. + * This is the case if the following is set: + * #define RPL_CALLBACK_PARENT_SWITCH tsch_rpl_callback_parent_switch + * */ + + int i; + if(new != old) { + orchestra_parent_knows_us = 0; + } + for(i = 0; i < NUM_RULES; i++) { + if(all_rules[i]->new_time_source != NULL) { + all_rules[i]->new_time_source(old, new); + } + } +} +/*---------------------------------------------------------------------------*/ +void +orchestra_init(void) +{ + int i; + /* Snoop on packet transmission to know if our parent knows about us + * (i.e. has ACKed at one of our DAOs since we decided to use it as a parent) */ + rime_sniffer_add(&orchestra_sniffer); + linkaddr_copy(&orchestra_parent_linkaddr, &linkaddr_null); + /* Initialize all Orchestra rules */ + for(i = 0; i < NUM_RULES; i++) { + if(all_rules[i]->init != NULL) { + PRINTF("Orchestra: initializing rule %u\n", i); + all_rules[i]->init(i); + } + } + PRINTF("Orchestra: initialization done\n"); +} diff --git a/apps/orchestra/orchestra.h b/apps/orchestra/orchestra.h new file mode 100644 index 000000000..b948a2985 --- /dev/null +++ b/apps/orchestra/orchestra.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2015, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file + * Orchestra header file + * + * \author Simon Duquennoy + */ + +#ifndef __ORCHESTRA_H__ +#define __ORCHESTRA_H__ + +#include "net/mac/tsch/tsch.h" +#include "net/mac/tsch/tsch-conf.h" +#include "net/mac/tsch/tsch-schedule.h" +#include "orchestra-conf.h" + +/* The structure of an Orchestra rule */ +struct orchestra_rule { + void (* init)(uint16_t slotframe_handle); + void (* new_time_source)(const struct tsch_neighbor *old, const struct tsch_neighbor *new); + int (* select_packet)(uint16_t *slotframe, uint16_t *timeslot); + void (* child_added)(const linkaddr_t *addr); + void (* child_removed)(const linkaddr_t *addr); +}; + +struct orchestra_rule eb_per_time_source; +struct orchestra_rule unicast_per_neighbor_rpl_storing; +struct orchestra_rule unicast_per_neighbor_rpl_ns; +struct orchestra_rule default_common; + +extern linkaddr_t orchestra_parent_linkaddr; +extern int orchestra_parent_knows_us; + +/* Call from application to start Orchestra */ +void orchestra_init(void); +/* Callbacks requied for Orchestra to operate */ +/* Set with #define TSCH_CALLBACK_PACKET_READY orchestra_callback_packet_ready */ +void orchestra_callback_packet_ready(void); +/* Set with #define TSCH_CALLBACK_NEW_TIME_SOURCE orchestra_callback_new_time_source */ +void orchestra_callback_new_time_source(const struct tsch_neighbor *old, const struct tsch_neighbor *new); +/* Set with #define NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK orchestra_callback_child_added */ +void orchestra_callback_child_added(const linkaddr_t *addr); +/* Set with #define NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK orchestra_callback_child_removed */ +void orchestra_callback_child_removed(const linkaddr_t *addr); + +#endif /* __ORCHESTRA_H__ */ diff --git a/apps/powertrace/powertrace.c b/apps/powertrace/powertrace.c index d5b0a46ec..6d8f2936f 100644 --- a/apps/powertrace/powertrace.c +++ b/apps/powertrace/powertrace.c @@ -48,15 +48,15 @@ struct powertrace_sniff_stats { struct powertrace_sniff_stats *next; - uint32_t num_input, num_output; - uint32_t input_txtime, input_rxtime; - uint32_t output_txtime, output_rxtime; -#if UIP_CONF_IPV6 + unsigned long num_input, num_output; + unsigned long input_txtime, input_rxtime; + unsigned long output_txtime, output_rxtime; +#if NETSTACK_CONF_WITH_IPV6 uint16_t proto; /* includes proto + possibly flags */ #endif uint16_t channel; - uint32_t last_input_txtime, last_input_rxtime; - uint32_t last_output_txtime, last_output_rxtime; + unsigned long last_input_txtime, last_input_rxtime; + unsigned long last_output_txtime, last_output_rxtime; }; #define INPUT 1 @@ -72,17 +72,17 @@ PROCESS(powertrace_process, "Periodic power output"); void powertrace_print(char *str) { - static uint32_t last_cpu, last_lpm, last_transmit, last_listen; - static uint32_t last_idle_transmit, last_idle_listen; + static unsigned long last_cpu, last_lpm, last_transmit, last_listen; + static unsigned long last_idle_transmit, last_idle_listen; - uint32_t cpu, lpm, transmit, listen; - uint32_t all_cpu, all_lpm, all_transmit, all_listen; - uint32_t idle_transmit, idle_listen; - uint32_t all_idle_transmit, all_idle_listen; + unsigned long cpu, lpm, transmit, listen; + unsigned long all_cpu, all_lpm, all_transmit, all_listen; + unsigned long idle_transmit, idle_listen; + unsigned long all_idle_transmit, all_idle_listen; - static uint32_t seqno; + static unsigned long seqno; - uint32_t time, all_time, radio, all_radio; + unsigned long time, all_time, radio, all_radio; struct powertrace_sniff_stats *s; @@ -135,7 +135,7 @@ powertrace_print(char *str) for(s = list_head(stats_list); s != NULL; s = list_item_next(s)) { -#if ! UIP_CONF_IPV6 +#if ! NETSTACK_CONF_WITH_IPV6 printf("%s %lu SP %d.%d %lu %u %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu (channel %d radio %d.%02d%% / %d.%02d%%)\n", str, clock_time(), linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1], seqno, s->channel, @@ -249,7 +249,7 @@ add_packet_stats(int input_or_output) put it on the list. */ for(s = list_head(stats_list); s != NULL; s = list_item_next(s)) { if(s->channel == packetbuf_attr(PACKETBUF_ATTR_CHANNEL) -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 && s->proto == packetbuf_attr(PACKETBUF_ATTR_NETWORK_ID) #endif ) { @@ -262,7 +262,7 @@ add_packet_stats(int input_or_output) if(s != NULL) { memset(s, 0, sizeof(struct powertrace_sniff_stats)); s->channel = packetbuf_attr(PACKETBUF_ATTR_CHANNEL); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 s->proto = packetbuf_attr(PACKETBUF_ATTR_NETWORK_ID); #endif list_add(stats_list, s); @@ -283,17 +283,12 @@ output_sniffer(int mac_status) add_packet_stats(OUTPUT); } /*---------------------------------------------------------------------------*/ -#if ! UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_RIME static void sniffprint(char *prefix, int seqno) { - const linkaddr_t *sender, *receiver, *esender, *ereceiver; - - sender = packetbuf_addr(PACKETBUF_ADDR_SENDER); - receiver = packetbuf_addr(PACKETBUF_ADDR_RECEIVER); + const linkaddr_t *esender; esender = packetbuf_addr(PACKETBUF_ADDR_ESENDER); - ereceiver = packetbuf_addr(PACKETBUF_ADDR_ERECEIVER); - printf("%lu %s %d %u %d %d %d.%d %u %u\n", clock_time(), @@ -347,7 +342,7 @@ powertrace_printsniff(powertrace_onoff_t onoff) break; } } -#endif +#endif /* NETSTACK_CONF_WITH_RIME */ /*---------------------------------------------------------------------------*/ RIME_SNIFFER(powersniff, input_sniffer, output_sniffer); /*---------------------------------------------------------------------------*/ diff --git a/apps/program-handler/program-handler.c b/apps/program-handler/program-handler.c index 2af8ca5a4..b59df6eea 100644 --- a/apps/program-handler/program-handler.c +++ b/apps/program-handler/program-handler.c @@ -1,33 +1,19 @@ -/** - * \file - * The program handler, used for loading programs and starting the - * screensaver. - * \author Adam Dunkels - * - * The Contiki program handler is responsible for the Contiki menu and - * the desktop icons, as well as for loading programs and displaying a - * dialog with a message telling which program that is loading. - * - * The program handler also is responsible for starting the - * screensaver when the CTK detects that it should be started. - */ - /* * Copyright (c) 2003, Adam Dunkels. - * All rights reserved. + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * 2. 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. + * with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior - * written permission. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -39,13 +25,27 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This file is part of the Contiki desktop OS * * */ +/** + * \file + * The program handler, used for loading programs and starting the + * screensaver. + * \author Adam Dunkels + * + * The Contiki program handler is responsible for the Contiki menu and + * the desktop icons, as well as for loading programs and displaying a + * dialog with a message telling which program that is loading. + * + * The program handler also is responsible for starting the + * screensaver when the CTK detects that it should be started. + */ + #include #include @@ -161,7 +161,7 @@ char program_handler_screensaver[20]; /*-----------------------------------------------------------------------------------*/ void program_handler_add(struct dsc *dsc, char *menuname, - unsigned char desktop) + unsigned char desktop) { contikidsc[contikidsclast++] = dsc; ctk_menuitem_add(&contikimenu, menuname); @@ -228,7 +228,7 @@ program_handler_load(char *name, char *arg) { #ifdef WITH_LOADER_ARCH struct pnarg *pnarg; - + pnarg = pnarg_copy(name, arg); if(pnarg != NULL) { process_post(&program_handler_process, LOADER_EVENT_DISPLAY_NAME, pnarg); @@ -246,6 +246,7 @@ program_handler_load(char *name, char *arg) #else /* WITH_LOADER_ARCH */ #define RUN(prg, process, arg) process_start(process, arg) #endif /* WITH_LOADER_ARCH */ +#if CTK_CONF_SCREENSAVER /*-----------------------------------------------------------------------------------*/ /** * Configures the name of the screensaver to be loaded when @@ -255,7 +256,6 @@ program_handler_load(char *name, char *arg) * should be used. */ /*-----------------------------------------------------------------------------------*/ -#if CTK_CONF_SCREENSAVER void program_handler_setscreensaver(char *name) { @@ -272,17 +272,17 @@ static void make_windows(void) { ctk_window_new(&runwindow, 16, 3, "Run"); - + CTK_WIDGET_ADD(&runwindow, &namelabel); CTK_WIDGET_ADD(&runwindow, &nameentry); CTK_WIDGET_ADD(&runwindow, &loadbutton); - + CTK_WIDGET_FOCUS(&runwindow, &nameentry); - + ctk_dialog_new(&loadingdialog, 25, 1); CTK_WIDGET_ADD(&loadingdialog, &loadingmsg); CTK_WIDGET_ADD(&loadingdialog, &loadingname); - + ctk_dialog_new(&errordialog, 22, 8); CTK_WIDGET_ADD(&errordialog, &errormsg); CTK_WIDGET_ADD(&errordialog, &errorfilelabel); @@ -302,20 +302,20 @@ PROCESS_THREAD(program_handler_process, ev, data) struct dsc **dscp; PROCESS_BEGIN(); - + /* Create the menus */ ctk_menu_add(&contikimenu); #if WITH_LOADER_ARCH runmenuitem = ctk_menuitem_add(&contikimenu, "Run program..."); - + make_windows(); #endif /* WITH_LOADER_ARCH */ #if QUIT_MENU quitmenuitem = ctk_menuitem_add(&contikimenu, "Quit"); #endif /* QUIT_MENU */ - + displayname = NULL; - + #if CTK_CONF_SCREENSAVER program_handler_screensaver[0] = 0; #endif /* CTK_CONF_SCREENSAVER */ @@ -325,106 +325,106 @@ PROCESS_THREAD(program_handler_process, ev, data) if(ev == ctk_signal_button_activate) { #ifdef WITH_LOADER_ARCH if(data == (process_data_t)&loadbutton) { - ctk_window_close(&runwindow); - program_handler_load(name, NULL); + ctk_window_close(&runwindow); + program_handler_load(name, NULL); } else if(data == (process_data_t)&errorokbutton) { - ctk_dialog_close(); + ctk_dialog_close(); } #endif /* WITH_LOADER_ARCH */ #if QUIT_MENU if(data == (process_data_t)&quityesbutton) { - ctk_draw_init(); - exit(EXIT_SUCCESS); + ctk_draw_init(); + exit(EXIT_SUCCESS); } else if(data == (process_data_t)&quitnobutton) { - ctk_dialog_close(); + ctk_dialog_close(); } #endif /* QUIT_MENU */ dscp = &contikidsc[0]; - for(i = 0; i < CTK_MAXMENUITEMS; ++i) { - if(*dscp != NULL + for(i = 0; i < CTK_MAXMENUITEMS; ++i) { + if(*dscp != NULL #if CTK_CONF_ICONS - && data == (process_data_t)(*dscp)->icon + && data == (process_data_t)(*dscp)->icon #endif /* CTK_CONF_ICONS */ - ) { - RUN((*dscp)->prgname, (*dscp)->process, NULL); - break; - } - ++dscp; + ) { + RUN((*dscp)->prgname, (*dscp)->process, NULL); + break; + } + ++dscp; } } else if(ev == ctk_signal_menu_activate) { if((struct ctk_menu *)data == &contikimenu) { #if WITH_LOADER_ARCH - dsc = contikidsc[contikimenu.active]; - if(dsc != NULL) { - RUN(dsc->prgname, dsc->process, NULL); - } else if(contikimenu.active == runmenuitem) { - make_windows(); - ctk_window_close(&runwindow); - ctk_window_open(&runwindow); - CTK_WIDGET_FOCUS(&runwindow, &nameentry); - } + dsc = contikidsc[contikimenu.active]; + if(dsc != NULL) { + RUN(dsc->prgname, dsc->process, NULL); + } else if(contikimenu.active == runmenuitem) { + make_windows(); + ctk_window_close(&runwindow); + ctk_window_open(&runwindow); + CTK_WIDGET_FOCUS(&runwindow, &nameentry); + } #else /* WITH_LOADER_ARCH */ - if(contikidsc[contikimenu.active] != NULL) { - RUN(contikidsc[contikimenu.active]->prgname, - contikidsc[contikimenu.active]->process, - NULL); - } + if(contikidsc[contikimenu.active] != NULL) { + RUN(contikidsc[contikimenu.active]->prgname, + contikidsc[contikimenu.active]->process, + NULL); + } #endif /* WITH_LOADER_ARCH */ #if QUIT_MENU - if(contikimenu.active == quitmenuitem) { - ctk_dialog_new(&quitdialog, 24, 5); - CTK_WIDGET_ADD(&quitdialog, &quitdialoglabel); - CTK_WIDGET_ADD(&quitdialog, &quityesbutton); - CTK_WIDGET_ADD(&quitdialog, &quitnobutton); - CTK_WIDGET_FOCUS(&quitdialog, &quitnobutton); - ctk_dialog_open(&quitdialog); - } + if(contikimenu.active == quitmenuitem) { + ctk_dialog_new(&quitdialog, 24, 5); + CTK_WIDGET_ADD(&quitdialog, &quitdialoglabel); + CTK_WIDGET_ADD(&quitdialog, &quityesbutton); + CTK_WIDGET_ADD(&quitdialog, &quitnobutton); + CTK_WIDGET_FOCUS(&quitdialog, &quitnobutton); + ctk_dialog_open(&quitdialog); + } #endif /* QUIT_MENU */ } #if CTK_CONF_SCREENSAVER } else if(ev == ctk_signal_screensaver_start) { #if WITH_LOADER_ARCH if(program_handler_screensaver[0] != 0) { - program_handler_load(program_handler_screensaver, NULL); + program_handler_load(program_handler_screensaver, NULL); } #endif /* WITH_LOADER_ARCH */ #endif /* CTK_CONF_SCREENSAVER */ } else if(ev == LOADER_EVENT_DISPLAY_NAME) { #if WITH_LOADER_ARCH if(displayname == NULL) { - make_windows(); - - ctk_label_set_text(&loadingname, ((struct pnarg *)data)->name); - ctk_dialog_open(&loadingdialog); - process_post(&program_handler_process, LOADER_EVENT_LOAD, data); - displayname = data; + make_windows(); + + ctk_label_set_text(&loadingname, ((struct pnarg *)data)->name); + ctk_dialog_open(&loadingdialog); + process_post(&program_handler_process, LOADER_EVENT_LOAD, data); + displayname = data; } else { - /* Try again. */ - process_post(&program_handler_process, LOADER_EVENT_DISPLAY_NAME, data); + /* Try again. */ + process_post(&program_handler_process, LOADER_EVENT_DISPLAY_NAME, data); } #endif /* WITH_LOADER_ARCH */ } else if(ev == LOADER_EVENT_LOAD) { #if WITH_LOADER_ARCH if(displayname == data) { - ctk_dialog_close(); - displayname = NULL; - log_message("Loading ", ((struct pnarg *)data)->name); - err = LOADER_LOAD(((struct pnarg *)data)->name, - ((struct pnarg *)data)->arg); - if(err != LOADER_OK) { - make_windows(); - errorfilename[0] = '"'; - strncpy(errorfilename + 1, ((struct pnarg *)data)->name, - sizeof(errorfilename) - 2); - errorfilename[1 + strlen(((struct pnarg *)data)->name)] = '"'; - ctk_label_set_text(&errortype, (char *)errormsgs[err]); - ctk_dialog_open(&errordialog); - log_message((char *)errormsgs[err], errorfilename); - } - pnarg_free(data); + ctk_dialog_close(); + displayname = NULL; + log_message("Loading ", ((struct pnarg *)data)->name); + err = LOADER_LOAD(((struct pnarg *)data)->name, + ((struct pnarg *)data)->arg); + if(err != LOADER_OK) { + make_windows(); + errorfilename[0] = '"'; + strncpy(errorfilename + 1, ((struct pnarg *)data)->name, + sizeof(errorfilename) - 2); + errorfilename[1 + strlen(((struct pnarg *)data)->name)] = '"'; + ctk_label_set_text(&errortype, (char *)errormsgs[err]); + ctk_dialog_open(&errordialog); + log_message((char *)errormsgs[err], errorfilename); + } + pnarg_free(data); } else { - /* Try again. */ - process_post(&program_handler_process, LOADER_EVENT_DISPLAY_NAME, data); + /* Try again. */ + process_post(&program_handler_process, LOADER_EVENT_DISPLAY_NAME, data); } #endif /* WITH_LOADEER_ARCH */ } diff --git a/apps/rest-coap/Makefile.rest-coap b/apps/rest-coap/Makefile.rest-coap deleted file mode 100644 index cd6e332cd..000000000 --- a/apps/rest-coap/Makefile.rest-coap +++ /dev/null @@ -1,4 +0,0 @@ -rest-coap_src = coap-common.c coap-server.c - -APPS += rest-common -include $(CONTIKI)/apps/rest-common/Makefile.rest-common diff --git a/apps/rest-coap/coap-common.c b/apps/rest-coap/coap-common.c deleted file mode 100644 index 0ddff495d..000000000 --- a/apps/rest-coap/coap-common.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * coap-common.c - * - * Created on: Aug 30, 2010 - * Author: dogan - */ - -#ifdef CONTIKI_TARGET_NETSIM - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include -#else - #include "contiki.h" - #include "contiki-net.h" - #include -#endif - -#include "coap-common.h" - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - -void init_packet(coap_packet_t* packet) -{ - packet->ver = 1; - packet->type = 0; - packet->option_count = 0; - packet->code = 0; - packet->tid = 0; - packet->options = NULL; - packet->url = NULL; - packet->url_len = 0; - packet->query = NULL; - packet->query_len = 0; - packet->payload = NULL; - packet->payload_len = 0; -} - -int serialize_packet(coap_packet_t* packet, uint8_t* buffer) -{ - int index = 0; - header_option_t* option = NULL; - uint16_t option_delta = 0; - - buffer[0] = (packet->ver) << COAP_HEADER_VERSION_POSITION; - buffer[0] |= (packet->type) << COAP_HEADER_TYPE_POSITION; - buffer[0] |= packet->option_count; - buffer[1] = packet->code; - uint16_t temp = uip_htons(packet->tid); - memcpy( - (void*)&buffer[2], - (void*)(&temp), - sizeof(packet->tid)); - - index += 4; - - PRINTF("serialize option_count %u\n", packet->option_count); - - /*Options should be sorted beforehand*/ - for (option = packet->options ; option ; option = option->next){ - uint16_t delta = option->option - option_delta; - if ( !delta ){ - PRINTF("WARNING: Delta==Zero\n"); - } - buffer[index] = (delta) << COAP_HEADER_OPTION_DELTA_POSITION; - - PRINTF("option %u len %u option diff %u option_value addr %x option addr %x next option addr %x", option->option, option->len, option->option - option_delta, (unsigned int) option->value, (unsigned int)option, (unsigned int)option->next); - - int i = 0; - for ( ; i < option->len ; i++ ){ - PRINTF(" (%u)", option->value[i]); - } - PRINTF("\n"); - - if (option->len < 0xF){ - buffer[index] |= option->len; - index++; - } else{ - buffer[index] |= (0xF); //1111 - buffer[index + 1] = option->len - (0xF); - index += 2; - } - - memcpy((char*)&buffer[index], option->value, option->len); - index += option->len; - option_delta = option->option; - } - - if(packet->payload){ - memcpy(&buffer[index], packet->payload, packet->payload_len); - index += packet->payload_len; - } - - return index; -} diff --git a/apps/rest-coap/coap-common.h b/apps/rest-coap/coap-common.h deleted file mode 100644 index 835d123f3..000000000 --- a/apps/rest-coap/coap-common.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * coap.h - * - * Created on: Aug 25, 2010 - * Author: dogan - */ - -#ifndef COAP_COMMON_H_ -#define COAP_COMMON_H_ - -#include "contiki-net.h" - -/*COAP method types*/ -typedef enum { - COAP_GET = 1, - COAP_POST, - COAP_PUT, - COAP_DELETE -} coap_method_t; - -typedef enum { - MESSAGE_TYPE_CON, - MESSAGE_TYPE_NON, - MESSAGE_TYPE_ACK, - MESSAGE_TYPE_RST -} message_type; - -typedef enum { - OK_200 = 80, - CREATED_201 = 81, - NOT_MODIFIED_304 = 124, - BAD_REQUEST_400 = 160, - NOT_FOUND_404 = 164, - METHOD_NOT_ALLOWED_405 = 165, - UNSUPPORTED_MADIA_TYPE_415 = 175, - INTERNAL_SERVER_ERROR_500 = 200, - BAD_GATEWAY_502 = 202, - GATEWAY_TIMEOUT_504 = 204 -} status_code_t; - -typedef enum { - Option_Type_Content_Type = 1, - Option_Type_Max_Age = 2, - Option_Type_Etag = 4, - Option_Type_Uri_Authority = 5, - Option_Type_Location = 6, - Option_Type_Uri_Path = 9, - Option_Type_Subscription_Lifetime = 10, - Option_Type_Token = 11, - Option_Type_Block = 13, - Option_Type_Uri_Query = 15 -} option_type; - -typedef enum { - TEXT_PLAIN = 0, - TEXT_XML = 1, - TEXT_CSV = 2, - TEXT_HTML = 3, - IMAGE_GIF = 21, - IMAGE_JPEG = 22, - IMAGE_PNG = 23, - IMAGE_TIFF = 24, - AUDIO_RAW = 25, - VIDEO_RAW = 26, - APPLICATION_LINK_FORMAT = 40, - APPLICATION_XML = 41, - APPLICATION_OCTET_STREAM = 42, - APPLICATION_RDF_XML = 43, - APPLICATION_SOAP_XML = 44, - APPLICATION_ATOM_XML = 45, - APPLICATION_XMPP_XML = 46, - APPLICATION_EXI = 47, - APPLICATION_X_BXML = 48, - APPLICATION_FASTINFOSET = 49, - APPLICATION_SOAP_FASTINFOSET = 50, - APPLICATION_JSON = 51 -} content_type_t; - -#define COAP_HEADER_VERSION_MASK 0xC0 -#define COAP_HEADER_TYPE_MASK 0x30 -#define COAP_HEADER_OPTION_COUNT_MASK 0x0F -#define COAP_HEADER_OPTION_DELTA_MASK 0xF0 -#define COAP_HEADER_OPTION_SHORT_LENGTH_MASK 0x0F - -#define COAP_HEADER_VERSION_POSITION 6 -#define COAP_HEADER_TYPE_POSITION 4 -#define COAP_HEADER_OPTION_DELTA_POSITION 4 - -#define REQUEST_BUFFER_SIZE 200 - -#define DEFAULT_CONTENT_TYPE 0 -#define DEFAULT_MAX_AGE 60 -#define DEFAULT_URI_AUTHORITY "" -#define DEFAULT_URI_PATH "" - -//keep open requests and their xactid - -struct header_option_t -{ - struct header_option_t* next; - uint16_t option; - uint16_t len; - uint8_t* value; -}; -typedef struct header_option_t header_option_t; - -struct block_option_t { - uint32_t number; - uint8_t more; - uint8_t size; -}; -typedef struct block_option_t block_option_t; - -typedef struct -{ - uint8_t ver; //2-bits currently set to 1. - uint8_t type; //2-bits Confirmable (0), Non-Confirmable (1), Acknowledgment (2) or Reset (3) - uint8_t option_count; //4-bits - uint8_t code; //8-bits Method or response code - uint16_t tid; //16-bit unsigned integer - header_option_t* options; - char* url; //put it just as a shortcut or else need to parse options everytime to access it. - uint16_t url_len; - char* query; - uint16_t query_len; - uint16_t payload_len; - uint8_t* payload; - uip_ipaddr_t addr; -} coap_packet_t; - -/*error definitions*/ -typedef enum -{ - NO_ERROR, - - /*Memory errors*/ - MEMORY_ALLOC_ERR, - MEMORY_BOUNDARY_EXCEEDED -} error_t; - -int serialize_packet(coap_packet_t* request, uint8_t* buffer); -void init_packet(coap_packet_t* packet); - -#endif /* COAP_COMMON_H_ */ diff --git a/apps/rest-coap/coap-server.c b/apps/rest-coap/coap-server.c deleted file mode 100644 index 6f20e364c..000000000 --- a/apps/rest-coap/coap-server.c +++ /dev/null @@ -1,545 +0,0 @@ -#include -#include -#include -#include /*for isxdigit*/ -#include "contiki.h" -#include "contiki-net.h" - -#include "buffer.h" -#include "coap-server.h" -#include "rest-util.h" -#include "rest.h" /*added for periodic_resource*/ - -#include "dev/leds.h" - -#if !UIP_CONF_IPV6_RPL && !defined (CONTIKI_TARGET_MINIMAL_NET) -#include "static-routing.h" -#endif - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - -#define MAX_PAYLOAD_LEN 120 -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) -static struct uip_udp_conn *server_conn; - -static uint16_t current_tid; - -static service_callback service_cbk = NULL; - -void -coap_set_service_callback(service_callback callback) -{ - service_cbk = callback; -} - -void -parse_message(coap_packet_t* packet, uint8_t* buf, uint16_t size) -{ - int processed = 0; - int i = 0; - PRINTF("parse_message size %d-->\n",size); - - init_packet(packet); - - packet->ver = (buf[0] & COAP_HEADER_VERSION_MASK) >> COAP_HEADER_VERSION_POSITION; - packet->type = (buf[0] & COAP_HEADER_TYPE_MASK) >> COAP_HEADER_TYPE_POSITION; - packet->option_count = buf[0] & COAP_HEADER_OPTION_COUNT_MASK; - packet->code = buf[1]; - packet->tid = (buf[2] << 8) + buf[3]; - - processed += 4; - - if (packet->option_count) { - int option_index = 0; - uint8_t option_delta; - uint16_t option_len; - uint8_t* option_buf = buf + processed; - packet->options = (header_option_t*)allocate_buffer(sizeof(header_option_t) * packet->option_count); - - if (packet->options) { - header_option_t* current_option = packet->options; - header_option_t* prev_option = NULL; - while(option_index < packet->option_count) { - /*FIXME : put boundary controls*/ - option_delta = (option_buf[i] & COAP_HEADER_OPTION_DELTA_MASK) >> COAP_HEADER_OPTION_DELTA_POSITION; - option_len = (option_buf[i] & COAP_HEADER_OPTION_SHORT_LENGTH_MASK); - i++; - if (option_len == 0xf) { - option_len += option_buf[i]; - i++; - } - - current_option->option = option_delta; - current_option->len = option_len; - current_option->value = option_buf + i; - if (option_index) { - prev_option->next = current_option; - /*This field defines the difference between the option Type of - * this option and the previous option (or zero for the first option)*/ - current_option->option += prev_option->option; - } - - if (current_option->option == Option_Type_Uri_Path) { - packet->url = (char*)current_option->value; - packet->url_len = current_option->len; - } else if (current_option->option == Option_Type_Uri_Query){ - packet->query = (char*)current_option->value; - packet->query_len = current_option->len; - } - - PRINTF("OPTION %d %u %s \n", current_option->option, current_option->len, current_option->value); - - i += option_len; - option_index++; - prev_option = current_option++; - } - current_option->next = NULL; - } else { - PRINTF("MEMORY ERROR\n"); /*FIXME : add control here*/ - return; - } - } - processed += i; - - /**/ - if (processed < size) { - packet->payload = &buf[processed]; - packet->payload_len = size - processed; - } - - /*FIXME url is not decoded - is necessary?*/ - - /*If query is not already provided via Uri_Query option then check URL*/ - if (packet->url && !packet->query) { - if ((packet->query = strchr(packet->url, '?'))) { - uint16_t total_url_len = packet->url_len; - /*set query len and update url len so that it does not include query part now*/ - packet->url_len = packet->query - packet->url; - packet->query++; - packet->query_len = packet->url + total_url_len - packet->query; - - PRINTF("url %s, url_len %u, query %s, query_len %u\n", packet->url, packet->url_len, packet->query, packet->query_len); - } - } - - PRINTF("PACKET ver:%d type:%d oc:%d \ncode:%d tid:%u url:%s len:%u payload:%s pay_len %u\n", (int)packet->ver, (int)packet->type, (int)packet->option_count, (int)packet->code, packet->tid, packet->url, packet->url_len, packet->payload, packet->payload_len); -} - -int -coap_get_query_variable(coap_packet_t* packet, const char *name, char* output, uint16_t output_size) -{ - if (packet->query) { - return get_variable(name, packet->query, packet->query_len, output, output_size, 0); - } - - return 0; -} - -int -coap_get_post_variable(coap_packet_t* packet, const char *name, char* output, uint16_t output_size) -{ - if (packet->payload) { - return get_variable(name, packet->payload, packet->payload_len, output, output_size, 1); - } - - return 0; -} - -static header_option_t* -allocate_header_option(uint16_t variable_len) -{ - PRINTF("sizeof header_option_t %u variable size %u\n", sizeof(header_option_t), variable_len); - uint8_t* buffer = allocate_buffer(sizeof(header_option_t) + variable_len); - if (buffer){ - header_option_t* option = (header_option_t*) buffer; - option->next = NULL; - option->len = 0; - option->value = buffer + sizeof(header_option_t); - return option; - } - - return NULL; -} - -/*FIXME : does not overwrite the same option yet.*/ -int -coap_set_option(coap_packet_t* packet, option_type option_type, uint16_t len, uint8_t* value) -{ - PRINTF("coap_set_option len %u\n", len); - header_option_t* option = allocate_header_option(len); - if (option){ - option->next = NULL; - option->len = len; - option->option = option_type; - memcpy(option->value, value, len); - header_option_t* option_current = packet->options; - header_option_t* prev = NULL; - while (option_current){ - if (option_current->option > option->option){ - break; - } - prev = option_current; - option_current = option_current->next; - } - - if (!prev){ - if (option_current){ - option->next = option_current; - } - packet->options = option; - } else{ - option->next = option_current; - prev->next = option; - } - - packet->option_count++; - - PRINTF("option->len %u option->option %u option->value %x next %x\n", option->len, option->option, (unsigned int) option->value, (unsigned int)option->next); - - int i = 0; - for ( ; i < option->len ; i++ ){ - PRINTF(" (%u)", option->value[i]); - } - PRINTF("\n"); - - return 1; - } - - return 0; -} - -header_option_t* -coap_get_option(coap_packet_t* packet, option_type option_type) -{ - PRINTF("coap_get_option count: %u--> \n", packet->option_count); - int i = 0; - - header_option_t* current_option = packet->options; - for (; i < packet->option_count; current_option = current_option->next, i++) { - PRINTF("Current option: %u\n", current_option->option); - if (current_option->option == option_type){ - return current_option; - } - } - - return NULL; -} - -static void -fill_error_packet(coap_packet_t* packet, int error, uint16_t tid) -{ - packet->ver=1; - packet->option_count=0; - packet->url=NULL; - packet->options=NULL; - switch (error){ - case MEMORY_ALLOC_ERR: - packet->code=INTERNAL_SERVER_ERROR_500; - packet->tid=tid; - packet->type=MESSAGE_TYPE_ACK; - break; - default: - break; - } -} - -static void -init_response(coap_packet_t* request, coap_packet_t* response) -{ - init_packet(response); - if(request->type == MESSAGE_TYPE_CON) { - response->code = OK_200; - response->tid = request->tid; - response->type = MESSAGE_TYPE_ACK; - } -} - -uint16_t -coap_get_payload(coap_packet_t* packet, uint8_t** payload) -{ - if (packet->payload) { - *payload = packet->payload; - return packet->payload_len; - } else { - *payload = NULL; - return 0; - } -} - -int -coap_set_payload(coap_packet_t* packet, uint8_t* payload, uint16_t size) -{ - packet->payload = copy_to_buffer(payload, size); - if (packet->payload) { - packet->payload_len = size; - return 1; - } - - return 0; -} - -int -coap_set_header_content_type(coap_packet_t* packet, content_type_t content_type) -{ - uint16_t len = 1; - - return coap_set_option(packet, Option_Type_Content_Type, len, (uint8_t*) &content_type); -} - -content_type_t -coap_get_header_content_type(coap_packet_t* packet) -{ - header_option_t* option = coap_get_option(packet, Option_Type_Content_Type); - if (option){ - return (uint8_t)(*(option->value)); - } - - return DEFAULT_CONTENT_TYPE; -} - -int -coap_get_header_subscription_lifetime(coap_packet_t* packet, uint32_t* lifetime) -{ - PRINTF("coap_get_header_subscription_lifetime --> \n"); - header_option_t* option = coap_get_option(packet, Option_Type_Subscription_Lifetime); - if (option){ - PRINTF("Subs Found len %u (first byte %u)\n", option->len, (uint16_t)option->value[0]); - - *lifetime = read_int(option->value, option->len); - return 1; - } - - return 0; -} - -int -coap_set_header_subscription_lifetime(coap_packet_t* packet, uint32_t lifetime) -{ - uint8_t temp[4]; - uint16_t len = write_variable_int(temp, lifetime); - - return coap_set_option(packet, Option_Type_Subscription_Lifetime, len, temp); -} - -int -coap_get_header_block(coap_packet_t* packet, block_option_t* block) -{ - uint32_t all_block; - PRINTF("coap_get_header_block --> \n"); - header_option_t* option = coap_get_option(packet, Option_Type_Block); - if (option){ - PRINTF("Block Found len %u (first byte %u)\n", option->len, (uint16_t)option->value[0]); - - all_block = read_int(option->value, option->len); - block->number = all_block >> 4; - block->more = (all_block & 0x8) >> 3; - block->size = (all_block & 0x7); - return 1; - } - - return 0; -} - -int -coap_set_header_block(coap_packet_t* packet, uint32_t number, uint8_t more, uint8_t size) -{ - uint8_t temp[4]; - size = log_2(size/16); - number = number << 4; - number |= (more << 3) & 0x8; - number |= size & 0x7; - - uint16_t len = write_variable_int(temp, number); - PRINTF("number %lu, more %u, size %u block[0] %u block[1] %u block[2] %u block[3] %u\n", - number, (uint16_t)more, (uint16_t)size, (uint16_t)temp[0], (uint16_t)temp[1], (uint16_t)temp[2], (uint16_t)temp[3]); - return coap_set_option(packet, Option_Type_Block, len, temp); -} - - -int -coap_set_header_uri(coap_packet_t* packet, char* uri) -{ - return coap_set_option(packet, Option_Type_Uri_Path, strlen(uri), (uint8_t*) uri); -} - -int -coap_set_header_etag(coap_packet_t* packet, uint8_t* etag, uint8_t size) -{ - return coap_set_option(packet, Option_Type_Etag, size, etag); -} - -void -coap_set_code(coap_packet_t* packet, status_code_t code) -{ - packet->code = (uint8_t)code; -} - -coap_method_t -coap_get_method(coap_packet_t* packet) -{ - return (coap_method_t)packet->code; -} - -void -coap_set_method(coap_packet_t* packet, coap_method_t method) -{ - packet->code = (uint8_t)method; -} - -static void send_request(coap_packet_t* request, struct uip_udp_conn *client_conn) -{ - char buf[MAX_PAYLOAD_LEN]; - int data_size = 0; - - data_size = serialize_packet(request, buf); - - PRINTF("Created a connection with the server "); - PRINT6ADDR(&client_conn->ripaddr); - PRINTF(" local/remote port %u/%u\n", - uip_htons(client_conn->lport), uip_htons(client_conn->rport)); - - PRINTF("Sending to: "); - PRINT6ADDR(&client_conn->ripaddr); - uip_udp_packet_send(client_conn, buf, data_size); -} - -static int -handle_incoming_data(void) -{ - int error=NO_ERROR; - char buf[MAX_PAYLOAD_LEN]; - - PRINTF("uip_datalen received %u \n",(uint16_t)uip_datalen()); - - char* data = (char *)uip_appdata + uip_ext_len; - uint16_t datalen = uip_datalen() - uip_ext_len; - - int data_size = 0; - - if (uip_newdata()) { - ((char *)data)[datalen] = 0; - PRINTF("Server received: '%s' (port:%u) from ", (char *)data, uip_htons(UIP_UDP_BUF->srcport)); - PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("\n"); - - if (init_buffer(COAP_DATA_BUFF_SIZE)) { - coap_packet_t* request = (coap_packet_t*)allocate_buffer(sizeof(coap_packet_t)); - parse_message(request, (uint8_t*)data, datalen); - - uip_ipaddr_copy(&request->addr, &UIP_IP_BUF->srcipaddr); - - if (request->type != MESSAGE_TYPE_ACK) { - coap_packet_t* response = (coap_packet_t*)allocate_buffer(sizeof(coap_packet_t)); - init_response(request, response); - - if (service_cbk) { - service_cbk(request, response); - } - - data_size = serialize_packet(response, buf); - - } - delete_buffer(); - } else { - PRINTF("Memory Alloc Error\n"); - error = MEMORY_ALLOC_ERR; - /*FIXME : Crappy way of accessing TID of the incoming packet, fix it!*/ - coap_packet_t error_packet; - fill_error_packet(&error_packet,error, (data[2] << 8) + data[3]); - data_size = serialize_packet(&error_packet, buf); - } - - uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr); - server_conn->rport = UIP_UDP_BUF->srcport; - - PRINTF("Responding with message size: %d\n",data_size); - uip_udp_packet_send(server_conn, buf, data_size); - /* Restore server connection to allow data from any node */ - memset(&server_conn->ripaddr, 0, sizeof(server_conn->ripaddr)); - server_conn->rport = 0; - } - - return error; -} - -process_event_t resource_changed_event; - -void -resource_changed(struct periodic_resource_t* resource) -{ - process_post(&coap_server, resource_changed_event, (process_data_t)resource); -} - - -/*---------------------------------------------------------------------------*/ - -PROCESS(coap_server, "Coap Server"); -PROCESS_THREAD(coap_server, ev, data) -{ - PROCESS_BEGIN(); - PRINTF("COAP SERVER\n"); - -/* if static routes are used rather than RPL */ -#if !UIP_CONF_IPV6_RPL && !defined (CONTIKI_TARGET_MINIMAL_NET) - set_global_address(); - configure_routing(); -#endif - - current_tid = random_rand(); - - resource_changed_event = process_alloc_event(); - - /* new connection with remote host */ - server_conn = udp_new(NULL, uip_htons(0), NULL); - udp_bind(server_conn, uip_htons(MOTE_SERVER_LISTEN_PORT)); - PRINTF("Local/remote port %u/%u\n", uip_htons(server_conn->lport), uip_htons(server_conn->rport)); - - while(1) { - PROCESS_YIELD(); - - if(ev == tcpip_event) { - handle_incoming_data(); - } else if (ev == resource_changed_event) { - periodic_resource_t* resource = (periodic_resource_t*)data; - PRINTF("resource_changed_event \n"); - - if (init_buffer(COAP_DATA_BUFF_SIZE)) { - coap_packet_t* request = (coap_packet_t*)allocate_buffer(sizeof(coap_packet_t)); - init_packet(request); - coap_set_code(request, COAP_GET); - request->tid = current_tid++; - coap_set_header_subscription_lifetime(request, resource->lifetime); - coap_set_header_uri(request, (char *)resource->resource->url); - if (resource->periodic_request_generator) { - resource->periodic_request_generator(request); - } - - if (!resource->client_conn) { - /*FIXME send port is fixed for now to 61616*/ - resource->client_conn = udp_new(&resource->addr, uip_htons(61616), NULL); - udp_bind(resource->client_conn, uip_htons(MOTE_CLIENT_LISTEN_PORT)); - } - - if (resource->client_conn) { - send_request(request, resource->client_conn); - } - - delete_buffer(); - } - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/apps/rest-coap/coap-server.h b/apps/rest-coap/coap-server.h deleted file mode 100644 index 888d08721..000000000 --- a/apps/rest-coap/coap-server.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef COAPSERVER_H_ -#define COAPSERVER_H_ - -#define COAP_DATA_BUFF_SIZE 300 - -#include "contiki.h" -#include "coap-common.h" - -/*Declare process*/ -PROCESS_NAME(coap_server); - -#define MOTE_SERVER_LISTEN_PORT 61616 -#define MOTE_CLIENT_LISTEN_PORT 61617 - -void parse_message(coap_packet_t* packet, uint8_t* buf, uint16_t size); - -uint16_t coap_get_payload(coap_packet_t* packet, uint8_t** payload); -int coap_set_payload(coap_packet_t* packet, uint8_t* payload, uint16_t size); - -content_type_t coap_get_header_content_type(coap_packet_t* packet); -int coap_set_header_content_type(coap_packet_t* packet, content_type_t content_type); - -int coap_get_header_subscription_lifetime(coap_packet_t* packet, uint32_t* lifetime); -int coap_set_header_subscription_lifetime(coap_packet_t* packet, uint32_t lifetime); - -int coap_get_header_block(coap_packet_t* packet, block_option_t* block); -int coap_set_header_block(coap_packet_t* packet, uint32_t number, uint8_t more, uint8_t size); - -int coap_set_header_uri(coap_packet_t* packet, char* uri); -int coap_set_header_etag(coap_packet_t* packet, uint8_t* etag, uint8_t size); - -void coap_set_code(coap_packet_t* packet, status_code_t code); - -coap_method_t coap_get_method(coap_packet_t* packet); -void coap_set_method(coap_packet_t* packet, coap_method_t method); - -int coap_get_query_variable(coap_packet_t* packet, const char *name, char* output, uint16_t output_size); -int coap_get_post_variable(coap_packet_t* packet, const char *name, char* output, uint16_t output_size); - -header_option_t* coap_get_option(coap_packet_t* packet, option_type option_type); -int coap_set_option(coap_packet_t* packet, option_type option_type, uint16_t len, uint8_t* value); - -/*Type definition of the service callback*/ -typedef int (*service_callback) (coap_packet_t* request, coap_packet_t* response); - -/* - *Setter of the service callback, this callback will be called in case of HTTP request. - */ -void coap_set_service_callback(service_callback callback); - -struct periodic_resource_t; -void resource_changed(struct periodic_resource_t* resource); - -#endif /* COAPSERVER_H_ */ diff --git a/apps/rest-common/Makefile.rest-common b/apps/rest-common/Makefile.rest-common deleted file mode 100644 index 4ce0e5ac3..000000000 --- a/apps/rest-common/Makefile.rest-common +++ /dev/null @@ -1 +0,0 @@ -rest-common_src = rest.c rest-util.c buffer.c static-routing.c diff --git a/apps/rest-common/buffer.c b/apps/rest-common/buffer.c deleted file mode 100644 index df5f616a1..000000000 --- a/apps/rest-common/buffer.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * buffer.c - * - * Created on: Oct 19, 2010 - * Author: dogan - */ - -#include -#include -#include -#include "buffer.h" - -uint8_t* data_buffer; -uint16_t buffer_size; -uint16_t buffer_index; - -void -delete_buffer(void) -{ - if (data_buffer) { - free(data_buffer); - data_buffer = NULL; - buffer_index = 0; - buffer_size = 0; - } -} - -uint8_t* -init_buffer(uint16_t size) -{ - delete_buffer(); - data_buffer = (uint8_t*)malloc(size); - if (data_buffer) { - buffer_size = size; - } - buffer_index = 0; - - return data_buffer; -} - -uint8_t* -allocate_buffer(uint16_t size) -{ - uint8_t* buffer = NULL; - int rem = 0; - /*To get rid of alignment problems, always allocate even size*/ - rem = size % 4; - if (rem) { - size+=(4-rem); - } - if (buffer_index + size < buffer_size) { - buffer = data_buffer + buffer_index; - buffer_index += size; - } - - return buffer; -} - -uint8_t* -copy_to_buffer(void* data, uint16_t len) -{ - uint8_t* buffer = allocate_buffer(len); - if (buffer) { - memcpy(buffer, data, len); - } - - return buffer; -} - -uint8_t* -copy_text_to_buffer(char* text) -{ - uint8_t* buffer = allocate_buffer(strlen(text) + 1); - if (buffer) { - strcpy(buffer, text); - } - - return buffer; -} diff --git a/apps/rest-common/buffer.h b/apps/rest-common/buffer.h deleted file mode 100644 index dd72ac2cf..000000000 --- a/apps/rest-common/buffer.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * buffer.h - * - * Created on: Oct 19, 2010 - * Author: dogan - */ - -#ifndef BUFFER_H_ -#define BUFFER_H_ - -void delete_buffer(void); -uint8_t* init_buffer(uint16_t size); -uint8_t* allocate_buffer(uint16_t size); -uint8_t* copy_to_buffer(void* data, uint16_t len); -uint8_t* copy_text_to_buffer(char* text); - -#endif /* BUFFER_H_ */ diff --git a/apps/rest-common/rest-util.c b/apps/rest-common/rest-util.c deleted file mode 100644 index b7e7f118e..000000000 --- a/apps/rest-common/rest-util.c +++ /dev/null @@ -1,118 +0,0 @@ -#include /*for size_t*/ -#include /*for isxdigit*/ -#include - -#include "contiki-net.h" - -/*Copied from mangoose http server*/ -size_t -decode(const char *src, size_t srclen, char *dst, size_t dstlen, int is_form) -{ - size_t i, j; - int a, b; -#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W') - - for (i = j = 0; i < srclen && j < dstlen - 1; i++, j++) { - if (src[i] == '%' && - isxdigit(* (unsigned char *) (src + i + 1)) && - isxdigit(* (unsigned char *) (src + i + 2))) { - a = tolower(* (unsigned char *) (src + i + 1)); - b = tolower(* (unsigned char *) (src + i + 2)); - dst[j] = ((HEXTOI(a) << 4) | HEXTOI(b)) & 0xff; - i += 2; - } else if (is_form && src[i] == '+') { - dst[j] = ' '; - } else { - dst[j] = src[i]; - } - } - - dst[j] = '\0'; /* Null-terminate the destination */ - - return ( i == srclen ); -} - -/*Copied from mangoose http server*/ -int -get_variable(const char *name, const char *buffer, size_t buflen, char* output, size_t output_len, int decode_type) -{ - const char *start = NULL, *end = NULL, *end_of_value; - size_t var_len = 0; - - /*initialize the output buffer first*/ - *output = 0; - - var_len = strlen(name); - end = buffer + buflen; - - for (start = buffer; start + var_len < end; start++){ - if ((start == buffer || start[-1] == '&') && start[var_len] == '=' && - ! strncmp(name, start, var_len)) { - /* Point p to variable value */ - start += var_len + 1; - - /* Point s to the end of the value */ - end_of_value = (const char *) memchr(start, '&', end - start); - if (end_of_value == NULL) { - end_of_value = end; - } - - return decode(start, end_of_value - start, output, output_len, decode_type); - } - } - - return 0; -} - -uint32_t -read_int(uint8_t *buf, uint8_t size) -{ - uint32_t data = 0; - - if (size >= 1 && size <= 4) { - uint8_t *p = (uint8_t *)&data; - memcpy(p + 4 - size, buf, size); - } - - return uip_ntohl(data); -} - - -int -write_int(uint8_t *buf, uint32_t data, uint8_t size) -{ - int success = 0; - - if (size >= 1 && size <= 4) { - data = uip_htonl(data); - memcpy(buf, ((char*)(&data)) + 4 - size, size); - success = size; - } - - return success; -} - -int -write_variable_int(uint8_t *buf, uint32_t data) -{ - uint8_t size = 4; - if (data <= 0xFF) { - size = 1; - } else if (data <= 0xFFFF) { - size = 2; - } else if (data <= 0xFFFFFF) { - size = 3; - } - return write_int(buf, data, size); -} - -uint16_t log_2(uint16_t value) -{ - uint16_t result = 0; - do { - value = value >> 1; - result++; - } while (value); - - return result ? result - 1 : result; -} diff --git a/apps/rest-common/rest-util.h b/apps/rest-common/rest-util.h deleted file mode 100644 index 421c8b3ea..000000000 --- a/apps/rest-common/rest-util.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * rest-util.h - * - * Created on: Oct 26, 2010 - * Author: dogan - */ - -#ifndef RESTUTIL_H_ -#define RESTUTIL_H_ - -size_t decode(const char *src, size_t srclen, char *dst, size_t dstlen, int is_form); -int get_variable(const char *name, const char *buffer, size_t buflen, char* output, size_t output_len, int decode_type); - -uint32_t read_int(uint8_t *buf, uint8_t size); -int write_int(uint8_t *buf, uint32_t data, uint8_t size); -int write_variable_int(uint8_t *buf, uint32_t data); - -uint16_t log_2(uint16_t value); - -#endif /* RESTUTIL_H_ */ diff --git a/apps/rest-common/rest.c b/apps/rest-common/rest.c deleted file mode 100644 index b28ae1bd5..000000000 --- a/apps/rest-common/rest.c +++ /dev/null @@ -1,333 +0,0 @@ -#include "contiki.h" -#include /*for string operations in match_addresses*/ -#include "rest.h" -#include "buffer.h" - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - -/*FIXME it is possible to define some of the rest functions as MACROs rather than functions full of ifdefs.*/ - -PROCESS_NAME(rest_manager_process); - -LIST(restful_services); -LIST(restful_periodic_services); - -void -rest_init(void) -{ - list_init(restful_services); - -#ifdef WITH_COAP - coap_set_service_callback(rest_invoke_restful_service); -#else /*WITH_COAP*/ - http_set_service_callback(rest_invoke_restful_service); -#endif /*WITH_COAP*/ - - /*Start rest framework process*/ - process_start(&rest_manager_process, NULL); -} - -void -rest_activate_resource(resource_t* resource) -{ - /*add it to the restful web service link list*/ - list_add(restful_services, resource); -} - -void -rest_activate_periodic_resource(periodic_resource_t* periodic_resource) -{ - list_add(restful_periodic_services, periodic_resource); - rest_activate_resource(periodic_resource->resource); -} - -void -rest_set_user_data(resource_t* resource, void* user_data) -{ - resource->user_data = user_data; -} - -void* -rest_get_user_data(resource_t* resource) -{ - return resource->user_data; -} - -void -rest_set_pre_handler(resource_t* resource, restful_pre_handler pre_handler) -{ - resource->pre_handler = pre_handler; -} - -void -rest_set_post_handler(resource_t* resource, restful_post_handler post_handler) -{ - resource->post_handler = post_handler; -} - -list_t -rest_get_resources(void) -{ - return restful_services; -} - -void -rest_set_response_status(RESPONSE* response, status_code_t status) -{ -#ifdef WITH_COAP - coap_set_code(response, status); -#else /*WITH_COAP*/ - http_set_status(response, status); -#endif /*WITH_COAP*/ -} - -#ifdef WITH_COAP -static method_t coap_to_rest_method(coap_method_t method) -{ - return (method_t)(1 << (method - 1)); -} - -static coap_method_t rest_to_coap_method(method_t method) -{ - coap_method_t coap_method = COAP_GET; - switch (method) { - case METHOD_GET: - coap_method = COAP_GET; - break; - case METHOD_POST: - coap_method = COAP_POST; - break; - case METHOD_PUT: - coap_method = COAP_PUT; - break; - case METHOD_DELETE: - coap_method = COAP_DELETE; - break; - default: - break; - } - return coap_method; -} -#endif /*WITH_COAP*/ - -method_t -rest_get_method_type(REQUEST* request) -{ -#ifdef WITH_COAP - return coap_to_rest_method(coap_get_method(request)); -#else - return (method_t)(request->request_type); -#endif -} - -/*Only defined for COAP for now.*/ -#ifdef WITH_COAP -void -rest_set_method_type(REQUEST* request, method_t method) -{ - coap_set_method(request, rest_to_coap_method(method)); -} -#endif /*WITH_COAP*/ - -void -rest_set_response_payload(RESPONSE* response, uint8_t* payload, uint16_t size) -{ -#ifdef WITH_COAP - coap_set_payload(response, payload, size); -#else - http_set_res_payload(response, payload, size); -#endif /*WITH_COAP*/ -} - -/*Only defined for COAP for now.*/ -#ifdef WITH_COAP -void -rest_set_request_payload(REQUEST* request, uint8_t* payload, uint16_t size) -{ - coap_set_payload(request, payload, size); -} -#endif /*WITH_COAP*/ - -int -rest_get_query_variable(REQUEST* request, const char *name, char* output, uint16_t output_size) -{ -#ifdef WITH_COAP - return coap_get_query_variable(request, name, output, output_size); -#else - return http_get_query_variable(request, name, output, output_size); -#endif /*WITH_COAP*/ -} - -int -rest_get_post_variable(REQUEST* request, const char *name, char* output, uint16_t output_size) -{ -#ifdef WITH_COAP - return coap_get_post_variable(request, name, output, output_size); -#else - return http_get_post_variable(request, name, output, output_size); -#endif /*WITH_COAP*/ -} - -content_type_t -rest_get_header_content_type(REQUEST* request) -{ -#ifdef WITH_COAP - return coap_get_header_content_type(request); -#else - return http_get_header_content_type(request); -#endif /*WITH_COAP*/ -} - -int -rest_set_header_content_type(RESPONSE* response, content_type_t content_type) -{ -#ifdef WITH_COAP - return coap_set_header_content_type(response, content_type); -#else - return http_set_res_header(response, HTTP_HEADER_NAME_CONTENT_TYPE, http_get_content_type_string(content_type), 1); -#endif /*WITH_COAP*/ - -} - -int -rest_set_header_etag(RESPONSE* response, uint8_t* etag, uint8_t size) -{ -#ifdef WITH_COAP - return coap_set_header_etag(response, etag, size); -#else - /*FIXME for now etag should be a "/0" ending string for http part*/ - char temp_etag[10]; - memcpy(temp_etag, etag, size); - temp_etag[size] = 0; - return http_set_res_header(response, HTTP_HEADER_NAME_ETAG, temp_etag, 1); -#endif /*WITH_COAP*/ -} - -int -rest_invoke_restful_service(REQUEST* request, RESPONSE* response) -{ - int found = 0; - const char* url = request->url; - uint16_t url_len = request->url_len; - - PRINTF("rest_invoke_restful_service url %s url_len %d -->\n", url, url_len); - - resource_t* resource = NULL; - - for (resource = (resource_t*)list_head(restful_services); resource; resource = resource->next) { - /*if the web service handles that kind of requests and urls matches*/ - if (url && strlen(resource->url) == url_len && strncmp(resource->url, url, url_len) == 0){ - found = 1; - method_t method = rest_get_method_type(request); - - PRINTF("method %u, resource->methods_to_handle %u\n", (uint16_t)method, resource->methods_to_handle); - - if (resource->methods_to_handle & method) { - - /*FIXME Need to move somewhere else*/ - #ifdef WITH_COAP - uint32_t lifetime = 0; - if (coap_get_header_subscription_lifetime(request, &lifetime)) { - PRINTF("Lifetime %lu\n", lifetime); - - periodic_resource_t* periodic_resource = NULL; - for (periodic_resource = (periodic_resource_t*)list_head(restful_periodic_services); - periodic_resource; - periodic_resource = periodic_resource->next) { - if (periodic_resource->resource == resource) { - PRINTF("Periodic Resource Found\n"); - PRINT6ADDR(&request->addr); - periodic_resource->lifetime = lifetime; - stimer_set(periodic_resource->lifetime_timer, lifetime); - uip_ipaddr_copy(&periodic_resource->addr, &request->addr); - } - } - } - #endif /*WITH_COAP*/ - - /*call pre handler if it exists*/ - if (!resource->pre_handler || resource->pre_handler(request, response)) { - /* call handler function*/ - resource->handler(request, response); - - /*call post handler if it exists*/ - if (resource->post_handler) { - resource->post_handler(request, response); - } - } - } else { - rest_set_response_status(response, METHOD_NOT_ALLOWED_405); - } - break; - } - } - - if (!found) { - rest_set_response_status(response, NOT_FOUND_404); - } - - return found; -} - -PROCESS(rest_manager_process, "Rest Process"); - -PROCESS_THREAD(rest_manager_process, ev, data) -{ - PROCESS_BEGIN(); - - /*start the coap or http server*/ - process_start(SERVER_PROCESS, NULL); - - PROCESS_PAUSE(); - - /*Periodic resources are only available to COAP implementation*/ -#if 0 -#ifdef WITH_COAP - periodic_resource_t* periodic_resource = NULL; - for (periodic_resource = (periodic_resource_t*)list_head(restful_periodic_services); periodic_resource; periodic_resource = periodic_resource->next) { - if (periodic_resource->period) { - PRINTF("Set timer for Res: %s to %lu\n", periodic_resource->resource->url, periodic_resource->period); - etimer_set(periodic_resource->handler_cb_timer, periodic_resource->period); - } - } - - while(1) { - PROCESS_WAIT_EVENT(); - if (ev == PROCESS_EVENT_TIMER) { - for (periodic_resource = (periodic_resource_t*)list_head(restful_periodic_services);periodic_resource;periodic_resource = periodic_resource->next) { - if (periodic_resource->period && etimer_expired(periodic_resource->handler_cb_timer)) { - PRINTF("Etimer expired for %s (period:%lu life:%lu)\n", periodic_resource->resource->url, periodic_resource->period, periodic_resource->lifetime); - /*call the periodic handler function if exists*/ - if (periodic_resource->periodic_handler) { - if ((periodic_resource->periodic_handler)(periodic_resource->resource)) { - PRINTF("RES CHANGE\n"); - if (!stimer_expired(periodic_resource->lifetime_timer)) { - PRINTF("TIMER NOT EXPIRED\n"); - resource_changed(periodic_resource); - periodic_resource->lifetime = stimer_remaining(periodic_resource->lifetime_timer); - } else { - periodic_resource->lifetime = 0; - } - } - - PRINTF("%s lifetime %lu (%lu) expired %d\n", periodic_resource->resource->url, stimer_remaining(periodic_resource->lifetime_timer), periodic_resource->lifetime, stimer_expired(periodic_resource->lifetime_timer)); - } - etimer_reset(periodic_resource->handler_cb_timer); - } - } - } - } -#endif /*WITH_COAP*/ -#endif - PROCESS_END(); -} diff --git a/apps/rest-common/rest.h b/apps/rest-common/rest.h deleted file mode 100644 index 2cf2ca7f1..000000000 --- a/apps/rest-common/rest.h +++ /dev/null @@ -1,179 +0,0 @@ -#ifndef REST_H_ -#define REST_H_ - -/*includes*/ -#include "contiki.h" -#include "contiki-lib.h" - -#ifdef WITH_COAP - #include "coap-common.h" -#include "coap-server.h" - #define REQUEST coap_packet_t - #define RESPONSE coap_packet_t - #define SERVER_PROCESS (&coap_server) -#else /*WITH_COAP*/ - /*WITH_HTTP*/ - #include "http-common.h" - #include "http-server.h" - #define REQUEST http_request_t - #define RESPONSE http_response_t - #define SERVER_PROCESS (&http_server) -#endif /*WITH_COAP*/ - -struct resource_t; - -/*REST method types*/ -typedef enum { - METHOD_GET = (1 << 0), - METHOD_POST = (1 << 1), - METHOD_PUT = (1 << 2), - METHOD_DELETE = (1 << 3) -} method_t; - -/*Signature of handler functions*/ -typedef void (*restful_handler) (REQUEST* request, RESPONSE* response); -typedef int (*restful_pre_handler) (REQUEST* request, RESPONSE* response); -typedef void (*restful_post_handler) (REQUEST* request, RESPONSE* response); - -typedef int (*restful_periodic_handler) (struct resource_t* resource); -typedef void (*restful_periodic_request_generator) (REQUEST* request); - -/* - * Data structure representing a resource in REST. - */ -struct resource_t { - struct resource_t *next; /*points to next resource defined*/ - method_t methods_to_handle; /*handled HTTP methods*/ - const char* url; /*handled URL*/ - restful_handler handler; /*handler function*/ - restful_pre_handler pre_handler; /*to be called before handler, may perform initializations*/ - restful_post_handler post_handler; /*to be called after handler, may perform finalizations (cleanup, etc)*/ - void* user_data; /*pointer to user specific data*/ -}; -typedef struct resource_t resource_t; - -struct periodic_resource_t { - struct periodic_resource_t *next; - resource_t *resource; - uint32_t period; - struct etimer* handler_cb_timer; - struct stimer* lifetime_timer; - restful_periodic_handler periodic_handler; - restful_periodic_request_generator periodic_request_generator; - uint32_t lifetime; - uip_ipaddr_t addr; - struct uip_udp_conn *client_conn; -}; -typedef struct periodic_resource_t periodic_resource_t; - -/* - * Macro to define a Resource - * Resources are statically defined for the sake of efficiency and better memory management. - */ -#define RESOURCE(name, methods_to_handle, url) \ -void name##_handler(REQUEST*, RESPONSE*); \ -resource_t resource_##name = {NULL, methods_to_handle, url, name##_handler, NULL, NULL, NULL} - -/* - * Macro to define a Periodic Resource - */ -#define PERIODIC_RESOURCE(name, methods_to_handle, url, period) \ -RESOURCE(name, methods_to_handle, url); \ -int name##_periodic_handler(resource_t*); \ -void name##_periodic_request_generator(REQUEST*); \ -struct etimer handler_cb_timer_##name; \ -struct stimer lifetime_timer_##name; \ -periodic_resource_t periodic_resource_##name = {NULL, &resource_##name, period, &handler_cb_timer_##name, &lifetime_timer_##name, name##_periodic_handler, name##_periodic_request_generator, 0} - - -/* - * Initializes REST framework and starts HTTP or COAP process - */ -void rest_init(void); - -/* - * Resources wanted to be accessible should be activated with the following code. - */ -void rest_activate_resource(resource_t* resource); - -void rest_activate_periodic_resource(periodic_resource_t* periodic_resource); - -/* - * To be called by HTTP/COAP server as a callback function when a new service request appears. - * This function dispatches the corresponding RESTful service. - */ -int rest_invoke_restful_service(REQUEST* request, RESPONSE* response); - -/* - * Returns the resource list - */ -list_t rest_get_resources(void); - -/* - * Returns query variable in the URL. - * Returns true if the variable found, false otherwise. - * Variable is put in the buffer provided. - */ -int rest_get_query_variable(REQUEST* request, const char *name, char* output, uint16_t output_size); - -/* - * Returns variable in the Post Data/Payload. - * Returns true if the variable found, false otherwise. - * Variable is put in the buffer provided. - */ -int rest_get_post_variable(REQUEST* request, const char *name, char* output, uint16_t output_size); - -method_t rest_get_method_type(REQUEST* request); -void rest_set_method_type(REQUEST* request, method_t method); - -/* - * Getter for the request content type - */ -content_type_t rest_get_header_content_type(REQUEST* request); - -/* - * Setter for the response content type - */ -int rest_set_header_content_type(RESPONSE* response, content_type_t content_type); - -/* - * Setter for the response etag header - */ -int rest_set_header_etag(RESPONSE* response, uint8_t* etag, uint8_t size); - -/* - * Setter for the status code (200, 201, etc) of the response. - */ -void rest_set_response_status(RESPONSE* response, status_code_t status); - -/* - * Setter for the payload of the request and response - */ -void rest_set_request_payload(RESPONSE* response, uint8_t* payload, uint16_t size); -void rest_set_response_payload(RESPONSE* response, uint8_t* payload, uint16_t size); - -/* - * Getter method for user specific data. - */ -void* rest_get_user_data(resource_t* resource); - -/* - * Setter method for user specific data. - */ -void rest_set_user_data(resource_t* resource, void* user_data); - -/* - * Sets the pre handler function of the Resource. - * If set, this function will be called just before the original handler function. - * Can be used to setup work before resource handling. - */ -void rest_set_pre_handler(resource_t* resource, restful_pre_handler pre_handler); - -/* - * Sets the post handler function of the Resource. - * If set, this function will be called just after the original handler function. - * Can be used to do cleanup (deallocate memory, etc) after resource handling. - */ -void rest_set_post_handler(resource_t* resource, restful_post_handler post_handler); - -#endif /*REST_H_*/ diff --git a/apps/rest-common/static-routing.c b/apps/rest-common/static-routing.c deleted file mode 100644 index 1d297b2db..000000000 --- a/apps/rest-common/static-routing.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * static-routing.c - * - * Created on: Oct 12, 2010 - * Author: dogan - */ - -#include "static-routing.h" - -#if !defined (CONTIKI_TARGET_MINIMAL_NET) /* Any other targets will be added here (&& ! defined (OTHER))*/ - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - - -#if !UIP_CONF_IPV6_RPL -#include "contiki-net.h" -#include "sys/node-id.h" - -void set_global_address(void) -{ - uip_ipaddr_t ipaddr; - - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); - uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); - uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); -} - -void configure_routing(void) -{ - PRINTF("configure_routing\n"); - - if (node_id < 10) { /*COOJA*/ - /*Go to desktop machine over border router*/ - ADD_ROUTE(DESKTOP_MACHINE_ID, COOJA_BORDER_ROUTER_ID); - } else { /*SKY*/ - if (node_id < 20) { /*First hops (ids between 10-20)*/ - /*Go to desktop machine over border router*/ - ADD_ROUTE(DESKTOP_MACHINE_ID, BORDER_ROUTER_ID); - } - - switch(node_id) { - case 12: - ADD_ROUTE(22, 22); /*Go to next hop over the local address of next hop*/ - break; - case 13: - ADD_ROUTE(23, 23); /*Go to next hop over the local address of next hop*/ - break; - - case 22: - ADD_ROUTE(0, 12); /*Go to desktop machine over the corresponding first hop*/ - break; - case 23: - ADD_ROUTE(0, 13); /*Go to desktop machine over the corresponding first hop*/ - break; - default: - break; - } - } -} -#endif /*!UIP_CONF_IPV6_RPL*/ -#endif /*CONTIKI_TARGET_MINIMAL_NET*/ diff --git a/apps/rest-common/static-routing.h b/apps/rest-common/static-routing.h deleted file mode 100644 index c4b757893..000000000 --- a/apps/rest-common/static-routing.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * static-routing.h - * - * Created on: Oct 12, 2010 - * Author: dogan - */ - -#ifndef STATICROUTING_H_ -#define STATICROUTING_H_ - -#if !defined (CONTIKI_TARGET_MINIMAL_NET) -#define NODE_IP(nodeid,type,ipaddr) NODE_##nodeid##_##type(ipaddr) - -/*desktop machine*/ -#define DESKTOP_MACHINE_ID 0 -#define NODE_0_GLOBAL(ipaddr) uip_ip6addr(ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0x0001) - -/*Cooja Nodes*/ -#define COOJA_BORDER_ROUTER_ID 1 -#define NODE_1_GLOBAL(ipaddr) uip_ip6addr(ipaddr, 0xaaaa, 0, 0, 0, 0x0212, 0x7401, 0x0001, 0x0101) -#define NODE_1_LOCAL(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0212, 0x7401, 0x0001, 0x0101) - -#define NODE_2_GLOBAL(ipaddr) uip_ip6addr(ipaddr, 0xaaaa, 0, 0, 0, 0x0212, 0x7402, 0x0002, 0x0202) -#define NODE_2_LOCAL(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0212, 0x7402, 0x0002, 0x0202) - -#define NODE_3_GLOBAL(ipaddr) uip_ip6addr(ipaddr, 0xaaaa, 0, 0, 0, 0x0212, 0x7403, 0x0003, 0x0303) -#define NODE_3_LOCAL(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0212, 0x7403, 0x0003, 0x0303) - -#define NODE_6_GLOBAL(ipaddr) uip_ip6addr(ipaddr, 0xaaaa, 0, 0, 0, 0x0212, 0x7406, 0x0006, 0x0606) -#define NODE_6_LOCAL(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0212, 0x7406, 0x0006, 0x0606) - -/*real nodes*/ -#define BORDER_ROUTER_ID 11 -#define NODE_11_GLOBAL(ipaddr) uip_ip6addr(ipaddr, 0xaaaa, 0, 0, 0, 0x0212, 0x7400, 0x116e, 0xd5f1) -#define NODE_11_LOCAL(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0212, 0x7400, 0x116e, 0xd5f1) - -#define NODE_12_GLOBAL(ipaddr) uip_ip6addr(ipaddr, 0xaaaa, 0, 0, 0, 0x0212, 0x7400, 0x1160, 0xf95a) -#define NODE_12_LOCAL(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0212, 0x7400, 0x1160, 0xf95a) - -#define NODE_13_GLOBAL(ipaddr) uip_ip6addr(ipaddr, 0xaaaa, 0, 0, 0, 0x0212, 0x7400, 0x117d, 0x3575) -#define NODE_13_LOCAL(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0212, 0x7400, 0x117d, 0x3575) - -#define NODE_22_GLOBAL(ipaddr) uip_ip6addr(ipaddr, 0xaaaa, 0, 0, 0, 0x0212, 0x7400, 0x116e, 0xc0f6) -#define NODE_22_LOCAL(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0212, 0x7400, 0x116e, 0xc0f6) - -#define NODE_23_GLOBAL(ipaddr) uip_ip6addr(ipaddr, 0xaaaa, 0, 0, 0, 0x0212, 0x7400, 0x117d, 0x0d5a) -#define NODE_23_LOCAL(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0212, 0x7400, 0x117d, 0x0d5a) - -#define ADD_ROUTE(node_global,node_local)\ -do{\ - uip_ipaddr_t ipaddr_local, ipaddr_global;\ - NODE_IP(node_global, GLOBAL, &ipaddr_global);\ - NODE_IP(node_local, LOCAL, &ipaddr_local);\ - uip_ds6_route_add(&ipaddr_global, 128, &ipaddr_local);\ -}while(0) - -void set_global_address(void); -void configure_routing(void); - -#endif /*CONTIKI_TARGET_MINIMAL_NET*/ -#endif /* STATICROUTING_H_ */ diff --git a/apps/rest-engine/Makefile.rest-engine b/apps/rest-engine/Makefile.rest-engine new file mode 100755 index 000000000..dcf1e1519 --- /dev/null +++ b/apps/rest-engine/Makefile.rest-engine @@ -0,0 +1 @@ +rest-engine_src = rest-engine.c diff --git a/apps/rest-engine/rest-constants.h b/apps/rest-engine/rest-constants.h new file mode 100644 index 000000000..addc0970b --- /dev/null +++ b/apps/rest-engine/rest-constants.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Constants for the REST Engine (Erbium). + * \author + * Matthias Kovatsch + */ + +#ifndef REST_CONSTANTS_H_ +#define REST_CONSTANTS_H_ + +/** + * Generic status codes that are mapped to either HTTP or CoAP codes. + */ +struct rest_implementation_status { + const unsigned int OK; /* CONTENT_2_05, OK_200 */ + const unsigned int CREATED; /* CREATED_2_01, CREATED_201 */ + const unsigned int CHANGED; /* CHANGED_2_04, NO_CONTENT_204 */ + const unsigned int DELETED; /* DELETED_2_02, NO_CONTENT_204 */ + const unsigned int NOT_MODIFIED; /* VALID_2_03, NOT_MODIFIED_304 */ + + const unsigned int BAD_REQUEST; /* BAD_REQUEST_4_00, BAD_REQUEST_400 */ + const unsigned int UNAUTHORIZED; /* UNAUTHORIZED_4_01, UNAUTHORIZED_401 */ + const unsigned int BAD_OPTION; /* BAD_OPTION_4_02, BAD_REQUEST_400 */ + const unsigned int FORBIDDEN; /* FORBIDDEN_4_03, FORBIDDEN_403 */ + const unsigned int NOT_FOUND; /* NOT_FOUND_4_04, NOT_FOUND_404 */ + const unsigned int METHOD_NOT_ALLOWED; /* METHOD_NOT_ALLOWED_4_05, METHOD_NOT_ALLOWED_405 */ + const unsigned int NOT_ACCEPTABLE; /* NOT_ACCEPTABLE_4_06, NOT_ACCEPTABLE_406 */ + const unsigned int REQUEST_ENTITY_TOO_LARGE; /* REQUEST_ENTITY_TOO_LARGE_4_13, REQUEST_ENTITY_TOO_LARGE_413 */ + const unsigned int UNSUPPORTED_MEDIA_TYPE; /* UNSUPPORTED_MEDIA_TYPE_4_15, UNSUPPORTED_MEDIA_TYPE_415 */ + + const unsigned int INTERNAL_SERVER_ERROR; /* INTERNAL_SERVER_ERROR_5_00, INTERNAL_SERVER_ERROR_500 */ + const unsigned int NOT_IMPLEMENTED; /* NOT_IMPLEMENTED_5_01, NOT_IMPLEMENTED_501 */ + const unsigned int BAD_GATEWAY; /* BAD_GATEWAY_5_02, BAD_GATEWAY_502 */ + const unsigned int SERVICE_UNAVAILABLE; /* SERVICE_UNAVAILABLE_5_03, SERVICE_UNAVAILABLE_503 */ + const unsigned int GATEWAY_TIMEOUT; /* GATEWAY_TIMEOUT_5_04, GATEWAY_TIMEOUT_504 */ + const unsigned int PROXYING_NOT_SUPPORTED; /* PROXYING_NOT_SUPPORTED_5_05, INTERNAL_SERVER_ERROR_500 */ +}; + +/** + * List of Content-Formats which are Internet Media Types plus encoding. + * TODO This should be a constant enum taken from CoAP for both CoAP and HTTP. + */ +struct rest_implementation_type { + unsigned int TEXT_PLAIN; + unsigned int TEXT_XML; + unsigned int TEXT_CSV; + unsigned int TEXT_HTML; + unsigned int IMAGE_GIF; + unsigned int IMAGE_JPEG; + unsigned int IMAGE_PNG; + unsigned int IMAGE_TIFF; + unsigned int AUDIO_RAW; + unsigned int VIDEO_RAW; + unsigned int APPLICATION_LINK_FORMAT; + unsigned int APPLICATION_XML; + unsigned int APPLICATION_OCTET_STREAM; + unsigned int APPLICATION_RDF_XML; + unsigned int APPLICATION_SOAP_XML; + unsigned int APPLICATION_ATOM_XML; + unsigned int APPLICATION_XMPP_XML; + unsigned int APPLICATION_EXI; + unsigned int APPLICATION_FASTINFOSET; + unsigned int APPLICATION_SOAP_FASTINFOSET; + unsigned int APPLICATION_JSON; + unsigned int APPLICATION_X_OBIX_BINARY; +}; + +/** + * Resource flags for allowed methods and special functionalities. + */ +typedef enum { + NO_FLAGS = 0, + + /* methods to handle */ + METHOD_GET = (1 << 0), + METHOD_POST = (1 << 1), + METHOD_PUT = (1 << 2), + METHOD_DELETE = (1 << 3), + + /* special flags */ + HAS_SUB_RESOURCES = (1 << 4), + IS_SEPARATE = (1 << 5), + IS_OBSERVABLE = (1 << 6), + IS_PERIODIC = (1 << 7) +} rest_resource_flags_t; + +#endif /* REST_CONSTANTS_H_ */ diff --git a/apps/rest-engine/rest-engine.c b/apps/rest-engine/rest-engine.c new file mode 100644 index 000000000..67ac232a2 --- /dev/null +++ b/apps/rest-engine/rest-engine.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * An abstraction layer for RESTful Web services (Erbium). + * Inspired by RESTful Contiki by Dogan Yazar. + * \author + * Matthias Kovatsch + */ + +#include +#include +#include "contiki.h" +#include "rest-engine.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +PROCESS(rest_engine_process, "REST Engine"); +/*---------------------------------------------------------------------------*/ +LIST(restful_services); +LIST(restful_periodic_services); +/*---------------------------------------------------------------------------*/ +/*- REST Engine API ---------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/** + * \brief Initializes and starts the REST Engine process + * + * This function must be called by server processes before any resources are + * registered through rest_activate_resource(). + */ +void +rest_init_engine(void) +{ + /* avoid initializing twice */ + static uint8_t initialized = 0; + + if(initialized) { + PRINTF("REST engine process already running - double initialization?\n"); + return; + } + initialized = 1; + + list_init(restful_services); + + REST.set_service_callback(rest_invoke_restful_service); + + /* Start the RESTful server implementation. */ + REST.init(); + + /*Start REST engine process */ + process_start(&rest_engine_process, NULL); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Makes a resource available under the given URI path + * \param resource A pointer to a resource implementation + * \param path The URI path string for this resource + * + * The resource implementation must be imported first using the + * extern keyword. The build system takes care of compiling every + * *.c file in the ./resources/ sub-directory (see example Makefile). + */ +void +rest_activate_resource(resource_t *resource, char *path) +{ + resource->url = path; + list_add(restful_services, resource); + + PRINTF("Activating: %s\n", resource->url); + + /* Only add periodic resources with a periodic_handler and a period > 0. */ + if(resource->flags & IS_PERIODIC && resource->periodic->periodic_handler + && resource->periodic->period) { + PRINTF("Periodic resource: %p (%s)\n", resource->periodic, + resource->periodic->resource->url); + list_add(restful_periodic_services, resource->periodic); + } +} +/*---------------------------------------------------------------------------*/ +/*- Internal API ------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +list_t +rest_get_resources(void) +{ + return restful_services; +} +/*---------------------------------------------------------------------------*/ +int +rest_invoke_restful_service(void *request, void *response, uint8_t *buffer, + uint16_t buffer_size, int32_t *offset) +{ + uint8_t found = 0; + uint8_t allowed = 1; + + resource_t *resource = NULL; + const char *url = NULL; + int url_len, res_url_len; + + url_len = REST.get_url(request, &url); + for(resource = (resource_t *)list_head(restful_services); + resource; resource = resource->next) { + + /* if the web service handles that kind of requests and urls matches */ + res_url_len = strlen(resource->url); + if((url_len == res_url_len + || (url_len > res_url_len + && (resource->flags & HAS_SUB_RESOURCES) + && url[res_url_len] == '/')) + && strncmp(resource->url, url, res_url_len) == 0) { + found = 1; + rest_resource_flags_t method = REST.get_method_type(request); + + PRINTF("/%s, method %u, resource->flags %u\n", resource->url, + (uint16_t)method, resource->flags); + + if((method & METHOD_GET) && resource->get_handler != NULL) { + /* call handler function */ + resource->get_handler(request, response, buffer, buffer_size, offset); + } else if((method & METHOD_POST) && resource->post_handler != NULL) { + /* call handler function */ + resource->post_handler(request, response, buffer, buffer_size, + offset); + } else if((method & METHOD_PUT) && resource->put_handler != NULL) { + /* call handler function */ + resource->put_handler(request, response, buffer, buffer_size, offset); + } else if((method & METHOD_DELETE) && resource->delete_handler != NULL) { + /* call handler function */ + resource->delete_handler(request, response, buffer, buffer_size, + offset); + } else { + allowed = 0; + REST.set_response_status(response, REST.status.METHOD_NOT_ALLOWED); + } + break; + } + } + if(!found) { + REST.set_response_status(response, REST.status.NOT_FOUND); + } else if(allowed) { + /* final handler for special flags */ + if(resource->flags & IS_OBSERVABLE) { + REST.subscription_handler(resource, request, response); + } + } + return found & allowed; +} +/*-----------------------------------------------------------------------------------*/ +PROCESS_THREAD(rest_engine_process, ev, data) +{ + PROCESS_BEGIN(); + + /* pause to let REST server finish adding resources. */ + PROCESS_PAUSE(); + + /* initialize the PERIODIC_RESOURCE timers, which will be handled by this process. */ + periodic_resource_t *periodic_resource = NULL; + + for(periodic_resource = + (periodic_resource_t *)list_head(restful_periodic_services); + periodic_resource; periodic_resource = periodic_resource->next) { + if(periodic_resource->periodic_handler && periodic_resource->period) { + PRINTF("Periodic: Set timer for /%s to %lu\n", + periodic_resource->resource->url, periodic_resource->period); + etimer_set(&periodic_resource->periodic_timer, + periodic_resource->period); + } + } + while(1) { + PROCESS_WAIT_EVENT(); + + if(ev == PROCESS_EVENT_TIMER) { + for(periodic_resource = + (periodic_resource_t *)list_head(restful_periodic_services); + periodic_resource; periodic_resource = periodic_resource->next) { + if(periodic_resource->period + && etimer_expired(&periodic_resource->periodic_timer)) { + + PRINTF("Periodic: etimer expired for /%s (period: %lu)\n", + periodic_resource->resource->url, periodic_resource->period); + + /* Call the periodic_handler function, which was checked during adding to list. */ + (periodic_resource->periodic_handler)(); + + etimer_reset(&periodic_resource->periodic_timer); + } + } + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/rest-engine/rest-engine.h b/apps/rest-engine/rest-engine.h new file mode 100644 index 000000000..41e181c33 --- /dev/null +++ b/apps/rest-engine/rest-engine.h @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * An abstraction layer for RESTful Web services (Erbium). + * Inspired by RESTful Contiki by Dogan Yazar. + * \author + * Matthias Kovatsch + */ + +#ifndef REST_ENGINE_H_ +#define REST_ENGINE_H_ + +#include +#include "contiki.h" +#include "contiki-lib.h" +#include "rest-constants.h" + +/* list of valid REST Enigne implementations */ +#define REGISTERED_ENGINE_ERBIUM coap_rest_implementation +#define REGISTERED_ENGINE_HELIUM http_rest_implementation + +/* sanity check for configured implementation */ +#if !defined(REST) || (REST != REGISTERED_ENGINE_ERBIUM && REST != REGISTERED_ENGINE_HELIUM) +#error "Define a valid REST Engine implementation (REST define)!" +#endif + +/* + * The maximum buffer size that is provided for resource responses and must be respected due to the limited IP buffer. + * Larger data must be handled by the resource and will be sent chunk-wise through a TCP stream or CoAP blocks. + */ +#ifndef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 64 +#endif + +struct resource_s; +struct periodic_resource_s; + +/* signatures of handler functions */ +typedef void (*restful_handler)(void *request, void *response, + uint8_t *buffer, uint16_t preferred_size, + int32_t *offset); +typedef void (*restful_final_handler)(struct resource_s *resource, + void *request, void *response); +typedef void (*restful_periodic_handler)(void); +typedef void (*restful_response_handler)(void *data, void *response); +typedef void (*restful_trigger_handler)(void); + +/* signature of the rest-engine service function */ +typedef int (*service_callback_t)(void *request, void *response, + uint8_t *buffer, uint16_t preferred_size, + int32_t *offset); + +/* data structure representing a resource in REST */ +struct resource_s { + struct resource_s *next; /* for LIST, points to next resource defined */ + const char *url; /*handled URL */ + rest_resource_flags_t flags; /* handled RESTful methods */ + const char *attributes; /* link-format attributes */ + restful_handler get_handler; /* handler function */ + restful_handler post_handler; /* handler function */ + restful_handler put_handler; /* handler function */ + restful_handler delete_handler; /* handler function */ + union { + struct periodic_resource_s *periodic; /* special data depending on flags */ + restful_trigger_handler trigger; + restful_trigger_handler resume; + }; +}; +typedef struct resource_s resource_t; + +struct periodic_resource_s { + struct periodic_resource_s *next; /* for LIST, points to next resource defined */ + const resource_t *resource; + uint32_t period; + struct etimer periodic_timer; + const restful_periodic_handler periodic_handler; +}; +typedef struct periodic_resource_s periodic_resource_t; + +/* + * Macro to define a RESTful resource. + * Resources are statically defined for the sake of efficiency and better memory management. + */ +#define RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler) \ + resource_t name = { NULL, NULL, NO_FLAGS, attributes, get_handler, post_handler, put_handler, delete_handler, { NULL } } + +#define PARENT_RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler) \ + resource_t name = { NULL, NULL, HAS_SUB_RESOURCES, attributes, get_handler, post_handler, put_handler, delete_handler, { NULL } } + +#define SEPARATE_RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler, resume_handler) \ + resource_t name = { NULL, NULL, IS_SEPARATE, attributes, get_handler, post_handler, put_handler, delete_handler, { .resume = resume_handler } } + +#define EVENT_RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler, event_handler) \ + resource_t name = { NULL, NULL, IS_OBSERVABLE, attributes, get_handler, post_handler, put_handler, delete_handler, { .trigger = event_handler } } + +/* + * Macro to define a periodic resource. + * The corresponding [name]_periodic_handler() function will be called every period. + * For instance polling a sensor and publishing a changed value to subscribed clients would be done there. + * The subscriber list will be maintained by the final_handler rest_subscription_handler() (see rest-mapping header file). + */ +#define PERIODIC_RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler, period, periodic_handler) \ + periodic_resource_t periodic_##name; \ + resource_t name = { NULL, NULL, IS_OBSERVABLE | IS_PERIODIC, attributes, get_handler, post_handler, put_handler, delete_handler, { .periodic = &periodic_##name } }; \ + periodic_resource_t periodic_##name = { NULL, &name, period, { { 0 } }, periodic_handler }; + +struct rest_implementation { + char *name; + + /** Initialize the REST implementation. */ + void (*init)(void); + + /** Register the RESTful service callback at implementation. */ + void (*set_service_callback)(service_callback_t callback); + + /** Get request URI path. */ + int (*get_url)(void *request, const char **url); + + /** Get the method of a request. */ + rest_resource_flags_t (*get_method_type)(void *request); + + /** Set the status code of a response. */ + int (*set_response_status)(void *response, unsigned int code); + + /** Get the content-type of a request. */ + int (*get_header_content_type)(void *request, + unsigned int *content_format); + + /** Set the Content-Type of a response. */ + int (*set_header_content_type)(void *response, + unsigned int content_format); + + /** Get the Accept types of a request. */ + int (*get_header_accept)(void *request, unsigned int *accept); + + /** Get the Length option of a request. */ + int (*get_header_length)(void *request, uint32_t *size); + + /** Set the Length option of a response. */ + int (*set_header_length)(void *response, uint32_t size); + + /** Get the Max-Age option of a request. */ + int (*get_header_max_age)(void *request, uint32_t *age); + + /** Set the Max-Age option of a response. */ + int (*set_header_max_age)(void *response, uint32_t age); + + /** Set the ETag option of a response. */ + int (*set_header_etag)(void *response, const uint8_t *etag, + size_t length); + + /** Get the If-Match option of a request. */ + int (*get_header_if_match)(void *request, const uint8_t **etag); + + /** Get the If-Match option of a request. */ + int (*get_header_if_none_match)(void *request); + + /** Get the Host option of a request. */ + int (*get_header_host)(void *request, const char **host); + + /** Set the location option of a response. */ + int (*set_header_location)(void *response, const char *location); + + /** Get the payload option of a request. */ + int (*get_request_payload)(void *request, const uint8_t **payload); + + /** Set the payload option of a response. */ + int (*set_response_payload)(void *response, const void *payload, + size_t length); + + /** Get the query string of a request. */ + int (*get_query)(void *request, const char **value); + + /** Get the value of a request query key-value pair. */ + int (*get_query_variable)(void *request, const char *name, + const char **value); + + /** Get the value of a request POST key-value pair. */ + int (*get_post_variable)(void *request, const char *name, + const char **value); + + /** Send the payload to all subscribers of the resource at url. */ + void (*notify_subscribers)(resource_t *resource); + + /** The handler for resource subscriptions. */ + restful_final_handler subscription_handler; + + /* REST status codes. */ + const struct rest_implementation_status status; + + /* REST content-types. */ + const struct rest_implementation_type type; +}; + +/* instance of REST implementation */ +extern const struct rest_implementation REST; + +/* + * To be called by HTTP/COAP server as a callback function when a new service request appears. + * This function dispatches the corresponding RESTful service. + */ +int rest_invoke_restful_service(void *request, void *response, + uint8_t *buffer, uint16_t buffer_size, + int32_t *offset); +/*---------------------------------------------------------------------------*/ +/** + * \brief Initializes REST framework and starts the HTTP or CoAP process. + */ +void rest_init_engine(void); +/*---------------------------------------------------------------------------*/ +/** + * + * \brief Resources wanted to be accessible should be activated with the following code. + * \param resource + * A RESTful resource defined through the RESOURCE macros. + * \param path + * The local URI path where to provide the resource. + */ +void rest_activate_resource(resource_t *resource, char *path); +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns the list of registered RESTful resources. + * \return The resource list. + */ +list_t rest_get_resources(void); +/*---------------------------------------------------------------------------*/ + +#endif /*REST_ENGINE_H_ */ diff --git a/apps/rest-http/Makefile.rest-http b/apps/rest-http/Makefile.rest-http deleted file mode 100644 index 3d946d2d9..000000000 --- a/apps/rest-http/Makefile.rest-http +++ /dev/null @@ -1,4 +0,0 @@ -rest-http_src = http-common.c http-server.c - -APPS += rest-common -include $(CONTIKI)/apps/rest-common/Makefile.rest-common diff --git a/apps/rest-http/http-common.c b/apps/rest-http/http-common.c deleted file mode 100644 index 0d3deefa3..000000000 --- a/apps/rest-http/http-common.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "http-common.h" - -/*needed for web services giving all path (http://172.16.79.0/services/light1) - * instead relative (/services/light1) in HTTP request. Ex: Restlet lib.*/ -const char* http_string = "http"; - -/*HTTP method strings*/ -const char* http_get_string = "GET"; -const char* http_head_string = "HEAD"; -const char* http_post_string = "POST"; -const char* http_put_string = "PUT"; -const char* http_delete_string = "DELETE"; - -const char* httpv1_1 = "HTTP/1.1"; -const char* line_end = "\r\n"; -const char* contiki = "Contiki"; -const char* close = "close"; - -/*header names*/ -const char* HTTP_HEADER_NAME_CONTENT_TYPE = "Content-Type"; -const char* HTTP_HEADER_NAME_CONTENT_LENGTH = "Content-Length"; -const char* HTTP_HEADER_NAME_LOCATION = "Location"; -const char* HTTP_HEADER_NAME_CONNECTION = "Connection"; -const char* HTTP_HEADER_NAME_SERVER = "Server"; -const char* HTTP_HEADER_NAME_HOST = "Host"; -const char* HTTP_HEADER_NAME_IF_NONE_MATCH = "If-None-Match"; -const char* HTTP_HEADER_NAME_ETAG = "ETag"; - -const char* header_delimiter = ": "; diff --git a/apps/rest-http/http-common.h b/apps/rest-http/http-common.h deleted file mode 100644 index e70115c2b..000000000 --- a/apps/rest-http/http-common.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef HTTPCOMMON_H_ -#define HTTPCOMMON_H_ - -/*includes*/ -#include "contiki.h" -#include "contiki-net.h" - -/*current state of the request, waiting: handling request, output: sending response*/ -#define STATE_WAITING 0 -#define STATE_OUTPUT 1 - -/*definitions of the line ending characters*/ -#define LINE_FEED_CHAR '\n' -#define CARRIAGE_RETURN_CHAR '\r' - -/*needed for web services giving all path (http://172.16.79.0/services/light1) - * instead relative (/services/light1) in HTTP request. Ex: Restlet lib. does it*/ -extern const char* http_string; - -/*HTTP method strings*/ -extern const char* http_get_string; -extern const char* http_head_string; -extern const char* http_post_string; -extern const char* http_put_string; -extern const char* http_delete_string; - -extern const char* httpv1_1; -extern const char* line_end; -extern const char* contiki; -extern const char* close; - -/*header names*/ -extern const char* HTTP_HEADER_NAME_CONTENT_TYPE; -extern const char* HTTP_HEADER_NAME_CONTENT_LENGTH; -extern const char* HTTP_HEADER_NAME_LOCATION; -extern const char* HTTP_HEADER_NAME_CONNECTION; -extern const char* HTTP_HEADER_NAME_SERVER; -extern const char* HTTP_HEADER_NAME_HOST; -extern const char* HTTP_HEADER_NAME_IF_NONE_MATCH; -extern const char* HTTP_HEADER_NAME_ETAG; - -extern const char* header_delimiter; - - -/*Configuration parameters*/ -#define HTTP_PORT 8080 -#define HTTP_DATA_BUFF_SIZE 600 -#define INCOMING_DATA_BUFF_SIZE 102 /*100+2, 100 = max url len, 2 = space char+'\0'*/ - -/*HTTP method types*/ -typedef enum { - HTTP_METHOD_GET = (1 << 0), - HTTP_METHOD_POST = (1 << 1), - HTTP_METHOD_PUT = (1 << 2), - HTTP_METHOD_DELETE = (1 << 3) -} http_method_t; - -//DY : FIXME right now same enum names with COAP with different values. Will this work fine? -typedef enum { - OK_200 = 200, - CREATED_201 = 201, - NOT_MODIFIED_304 = 304, - BAD_REQUEST_400 = 400, - NOT_FOUND_404 = 404, - METHOD_NOT_ALLOWED_405 = 405, - REQUEST_URI_TOO_LONG_414 = 414, - UNSUPPORTED_MADIA_TYPE_415 = 415, - INTERNAL_SERVER_ERROR_500 = 500, - BAD_GATEWAY_502 = 502, - SERVICE_UNAVAILABLE_503 = 503, - GATEWAY_TIMEOUT_504 = 504 -} status_code_t; - -typedef enum { - TEXT_PLAIN, - TEXT_XML, - TEXT_CSV, - TEXT_HTML, - APPLICATION_XML, - APPLICATION_EXI, - APPLICATION_JSON, - APPLICATION_LINK_FORMAT, - APPLICATION_WWW_FORM, - UNKNOWN_CONTENT_TYPE -} content_type_t; - -/*Header type*/ -struct http_header_t { - struct http_header_t* next; - char* name; - char* value; -}; -typedef struct http_header_t http_header_t; - -/*This structure contains information about the HTTP request.*/ -struct http_request_t { - char* url; - uint16_t url_len; - http_method_t request_type; /* GET, POST, etc */ - char* query; - uint16_t query_len; - http_header_t* headers; - uint16_t payload_len; - uint8_t* payload; -}; -typedef struct http_request_t http_request_t; - -/*This structure contains information about the HTTP response.*/ -struct http_response_t { - status_code_t status_code; - char* status_string; - http_header_t* headers; - uint16_t payload_len; - uint8_t* payload; -}; -typedef struct http_response_t http_response_t; - -/*This structure contains information about the TCP Connection.*/ -typedef struct { - struct psock sin, sout; /*Protosockets for incoming and outgoing communication*/ - struct pt outputpt; - char inputbuf[INCOMING_DATA_BUFF_SIZE]; /*to put incoming data in*/ - uint8_t state; - http_request_t request; - http_response_t response; -} connection_state_t; - -/*error definitions*/ -typedef enum { - HTTP_NO_ERROR, - - /*Memory errors*/ - HTTP_MEMORY_ALLOC_ERR, - HTTP_MEMORY_BOUNDARY_EXCEEDED, - - /*specific errors*/ - HTTP_XML_NOT_VALID, - HTTP_SOAP_MESSAGE_NOT_VALID, - HTTP_URL_TOO_LONG, - HTTP_URL_INVALID -} http_error_t; - -#endif /*HTTPCOMMON_H_*/ diff --git a/apps/rest-http/http-server.c b/apps/rest-http/http-server.c deleted file mode 100644 index 256e37904..000000000 --- a/apps/rest-http/http-server.c +++ /dev/null @@ -1,653 +0,0 @@ -#include -#include /*for atoi*/ -#include -#include "contiki.h" - -#include "http-server.h" -#include "buffer.h" -#include "rest-util.h" - -#if !UIP_CONF_IPV6_RPL && !defined (CONTIKI_TARGET_MINIMAL_NET) -#include "static-routing.h" -#endif - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - -static void -init_response(http_response_t* response) -{ - response->status_code = OK_200; - response->status_string = NULL; - response->headers = NULL; - response->payload = NULL; - response->payload_len = 0; -} - -static void -init_request(http_request_t* request) -{ - request->request_type = 0; - request->url = NULL; - request->url_len = 0; - request->query = NULL; - request->query_len = 0; - request->headers = NULL; - request->payload = NULL; - request->payload_len = 0; -} - -/** - * Initializes the connection state by clearing out the data structures - */ -static void -init_connection(connection_state_t* conn_state) -{ - conn_state->state = STATE_WAITING; - - init_request(&conn_state->request); - init_response(&conn_state->response); -} - -void -http_set_status(http_response_t* response, status_code_t status) -{ - response->status_code = status; -} - -static http_header_t* -allocate_header(uint16_t variable_len) -{ - PRINTF("sizeof http_header_t %u variable size %u\n", sizeof(http_header_t), variable_len); - uint8_t* buffer = allocate_buffer(sizeof(http_header_t) + variable_len); - if (buffer) { - http_header_t* option = (http_header_t*) buffer; - option->next = NULL; - option->name = NULL; - option->value = buffer + sizeof(http_header_t); - return option; - } - - return NULL; -} - -int -http_set_res_header(http_response_t* response, const char* name, const char* value, int copy) -{ - PRINTF("http_set_res_header (copy:%d) %s:%s\n", copy, name, value); - uint16_t size = 0; - http_header_t* current_header = NULL; - http_header_t* head = NULL; - - if (copy) { - size += strlen(value) + 1; - } - - current_header = allocate_header(size); - - if (current_header) { - current_header->name = (char*)name; - if (copy) { - strcpy(current_header->value, value); - } else { - current_header->value = (char*)value; - } - - head = response->headers; - response->headers = current_header; - if (head) { - current_header->next = head; - } - - return 1; - } - - return 0; -} - -static const char* is_request_hdr_needed(const char* header_name) -{ - const char* header = NULL; - /*FIXME add needed headers here*/ - if (strcmp(header_name, HTTP_HEADER_NAME_CONTENT_LENGTH) == 0) { - header = HTTP_HEADER_NAME_CONTENT_LENGTH; - } else if (strcmp(header_name, HTTP_HEADER_NAME_CONTENT_TYPE) == 0) { - header = HTTP_HEADER_NAME_CONTENT_TYPE; - } - - return header; -} - -static service_callback service_cbk = NULL; - -void -http_set_service_callback(service_callback callback) -{ - service_cbk = callback; -} - -const char* content_types[] = { - "text/plain", - "text/xml", - "text/csv", - "text/html", - "application/xml", - "application/exi", - "application/json", - "application/link-format", - "application/x-www-form-urlencoded", -}; - -const char* -http_get_content_type_string(content_type_t content_type) -{ - return content_types[content_type]; -} - -char* -get_default_status_string(status_code_t status_code) -{ - char* value = NULL; - switch(status_code) { - case 200: - value = "OK"; - break; - case 201: - value = "Created"; - break; - case 202: - value = "Accepted"; - break; - case 204: - value = "No Content"; - break; - case 304: - value = "Not Modified"; - break; - case 400: - value = "Bad Request" ; - break; - case 404: - value = "Not Found" ; - break; - case 405: - value = "Method Not Allowed" ; - break; - case 406: - value = "Not Acceptable" ; - break; - case 414: - value = "Request-URI Too Long" ; - break; - case 415: - value = "Unsupported Media Type" ; - break; - case 500: - value = "Internal Server Error" ; - break; - case 501: - value = "Not Implemented" ; - break; - case 503: - value = "Service Unavailable" ; - break; - /*FIXME : will be removed later, put to catch the unhandled statuses.*/ - default: - value = "$$BUG$$"; - break; - } - - return value; -} - -int -http_get_query_variable(http_request_t* request, const char *name, char* output, uint16_t output_size) -{ - if (request->query) { - return get_variable(name, request->query, request->query_len, output, output_size, 0); - } - - return 0; -} - -int -http_get_post_variable(http_request_t* request, const char *name, char* output, uint16_t output_size) -{ - if (request->payload) { - return get_variable(name, request->payload, request->payload_len, output, output_size, 1); - } - - return 0; -} - -static int -is_method_handled(connection_state_t* conn_state, const char* method) -{ - /*other method types can be added here if needed*/ - if(strncmp(method, http_get_string, 3) == 0) { - conn_state->request.request_type = HTTP_METHOD_GET; - } else if (strncmp(method, http_post_string, 4) == 0) { - conn_state->request.request_type = HTTP_METHOD_POST; - } else if (strncmp(method, http_put_string, 3) == 0) { - conn_state->request.request_type = HTTP_METHOD_PUT; - } else if (strncmp(method, http_delete_string, 3) == 0) { - conn_state->request.request_type = HTTP_METHOD_DELETE; - } else { - PRINTF("No Method supported : %s\nstate : %d\n", conn_state->inputbuf, conn_state->state); - return 0; - } - - return 1; -} - -static int -parse_url(connection_state_t* conn_state, char* url) -{ - int error = HTTP_NO_ERROR; - int full_url_path = 0; - /*even for default index.html there is / Ex: GET / HTTP/1.1*/ - if (url[0] != '/') { - /*if url is complete (http://...) rather than relative*/ - if (strncmp(url, http_string, 4) != 0 ) { - PRINTF("Url not valid : %s \n",url); - error = HTTP_URL_INVALID; - } else { - full_url_path = 1; - } - } - - if (error == HTTP_NO_ERROR) { - char* url_buffer = url; - if (full_url_path) { - unsigned char num_of_slash = 0; - do { - url_buffer = strchr( ++url_buffer, '/' ); - - PRINTF("Buffer : %s %d\n", url_buffer, num_of_slash); - - } while (url_buffer && ++num_of_slash < 3); - } - - PRINTF("Url found :%s\n", url_buffer); - - /*Get rid of the first slash*/ - if (url_buffer && ++url_buffer) { - conn_state->request.url = (char*) copy_text_to_buffer(url_buffer); - conn_state->request.url_len = strlen(url_buffer); - - if ((conn_state->request.query = strchr(conn_state->request.url, '?'))) { - *(conn_state->request.query++) = 0; - /*update url len - decrease the size of query*/ - conn_state->request.url_len = strlen(conn_state->request.url); - conn_state->request.query_len = strlen(conn_state->request.query); - } - - PRINTF("url %s, url_len %u, query %s, query_len %u\n", conn_state->request.url, conn_state->request.url_len, conn_state->request.query, conn_state->request.query_len); - - /*FIXME url is not decoded - should be done here*/ - } else { - error = HTTP_URL_INVALID; - } - } - - return error; -} - -static int -parse_header(connection_state_t* conn_state, char* inputbuf) -{ - PRINTF("parse_header --->\n"); - const char* header_name = NULL; - - char* delimiter = strchr(inputbuf, ':'); - if (delimiter) { - *delimiter++ = 0; /*after increment delimiter will point space char*/ - - header_name = is_request_hdr_needed(inputbuf); - if (header_name && delimiter) { - char* buffer = delimiter; - - if (buffer[0] == ' ') { - buffer++; - } - - http_header_t* current_header = NULL; - http_header_t* head = NULL; - - current_header = allocate_header(strlen(buffer)); - - if (current_header) { - current_header->name = (char*)header_name; - strcpy(current_header->value, buffer); - } - - head = conn_state->request.headers; - conn_state->request.headers = current_header; - if (head) { - current_header->next = head; - } - - return 1; - } - } - - return 0; -} - -int -http_set_res_payload(http_response_t* response, uint8_t* payload, uint16_t size) -{ - response->payload = copy_to_buffer(payload, size); - if (response->payload) { - response->payload_len = size; - return 1; - } - - return 0; -} - -static const char* -get_header(http_header_t* headers, const char* hdr_name) -{ - for (;headers; headers = headers->next) { - if (strcmp(headers->name, hdr_name) == 0) { - return headers->value; - } - } - - return NULL; -} - -const char* http_get_req_header(http_request_t* request, const char* name) -{ - return get_header(request->headers, name); -} - -content_type_t http_get_header_content_type(http_request_t* request) -{ - const char* content_type_string = http_get_req_header(request, HTTP_HEADER_NAME_CONTENT_TYPE); - if (content_type_string) { - int i = 0; - for(; i < sizeof(content_types)/sizeof(const char*) ; i++) { - if (strcmp(content_types[i], content_type_string)) { - return (content_type_t)i; - } - } - } - - return UNKNOWN_CONTENT_TYPE; -} - -static -PT_THREAD(handle_request(connection_state_t* conn_state)) -{ - static int error; - const char* content_len; - - PSOCK_BEGIN(&(conn_state->sin)); - - content_len = NULL; - - error = HTTP_NO_ERROR; /*always reinit static variables due to protothreads*/ - - PRINTF("Request--->\n"); - - //read method - PSOCK_READTO(&(conn_state->sin), ' '); - - if (!is_method_handled(conn_state, conn_state->inputbuf)) { - /*method not handled*/ - http_set_status(&conn_state->response, SERVICE_UNAVAILABLE_503); - conn_state->state = STATE_OUTPUT; - } else { - /*read until the end of url*/ - PSOCK_READTO(&(conn_state->sin), ' '); - - /*-1 is needed since it also includes space char*/ - if (conn_state->inputbuf[PSOCK_DATALEN(&(conn_state->sin)) - 1] != ' ' ) { - error = HTTP_URL_TOO_LONG; - } - - conn_state->inputbuf[PSOCK_DATALEN(&(conn_state->sin)) - 1] = 0; - - PRINTF("Read URL:%s\n", conn_state->inputbuf); - - if (error == HTTP_NO_ERROR) { - error = parse_url(conn_state, conn_state->inputbuf); - } - - if (error != HTTP_NO_ERROR) { - if (error == HTTP_URL_TOO_LONG) { - http_set_status(&conn_state->response, REQUEST_URI_TOO_LONG_414); - } else { - http_set_status(&conn_state->response, BAD_REQUEST_400); - } - - conn_state->state = STATE_OUTPUT; - } else { - /*read until the end of HTTP version - not used yet*/ - PSOCK_READTO(&(conn_state->sin), LINE_FEED_CHAR); - - PRINTF("After URL:%s\n", conn_state->inputbuf); - - /*FIXME : PSOCK_READTO takes just a single delimiter so I read till the end of line - but now it may not fit in the buffer. If PSOCK_READTO would take two delimiters, - we would have read until : and so it would not be blocked.*/ - - /*Read the headers and store the necessary ones*/ - do { - /*read the next line*/ - PSOCK_READTO(&(conn_state->sin), LINE_FEED_CHAR); - conn_state->inputbuf[ PSOCK_DATALEN(&(conn_state->sin)) - 1] = 0; - - /*if headers finished then stop the infinite loop*/ - if (conn_state->inputbuf[0] == CARRIAGE_RETURN_CHAR || conn_state->inputbuf[0] == 0) { - PRINTF("Finished Headers!\n\n"); - break; - } - - parse_header(conn_state, conn_state->inputbuf); - } - while(1); - - content_len = get_header(conn_state->request.headers, HTTP_HEADER_NAME_CONTENT_LENGTH); - if (content_len) { - conn_state->request.payload_len = atoi(content_len); - - PRINTF("Post Data Size string: %s int: %d\n", content_len, conn_state->request.payload_len); - } - - if (conn_state->request.payload_len) { - static uint16_t read_bytes = 0; - /*init the static variable again*/ - read_bytes = 0; - - conn_state->request.payload = allocate_buffer(conn_state->request.payload_len + 1); - - if (conn_state->request.payload) { - do { - PSOCK_READBUF(&(conn_state->sin)); - /*null terminate the buffer in case it is a string.*/ - conn_state->inputbuf[PSOCK_DATALEN(&(conn_state->sin))] = 0; - - memcpy(conn_state->request.payload + read_bytes, conn_state->inputbuf, PSOCK_DATALEN(&(conn_state->sin))); - - read_bytes += PSOCK_DATALEN(&(conn_state->sin)); - - } while (read_bytes < conn_state->request.payload_len); - - conn_state->request.payload[read_bytes++] = 0; - - PRINTF("PostData => %s \n", conn_state->request.payload); - } else { - error = HTTP_MEMORY_ALLOC_ERR; - } - } - - if (error == HTTP_NO_ERROR) { - if (service_cbk) { - service_cbk(&conn_state->request, &conn_state->response); - } - } else { - PRINTF("Error:%d\n",error); - http_set_status(&conn_state->response, INTERNAL_SERVER_ERROR_500); - } - - conn_state->state = STATE_OUTPUT; - } - } - - PSOCK_END(&(conn_state->sin)); -} - -static -PT_THREAD(send_data(connection_state_t* conn_state)) -{ - uint16_t index; - http_response_t* response; - http_header_t* header; - uint8_t* buffer; - - PSOCK_BEGIN(&(conn_state->sout)); - - PRINTF("send_data -> \n"); - - index = 0; - response = &conn_state->response; - header = response->headers; - buffer = allocate_buffer(200); - - /*FIXME: what is the best solution here to send the data. Right now, if buffer is not allocated, no data is sent!*/ - if (buffer) { - index += sprintf(buffer + index, "%s %d %s%s", httpv1_1, response->status_code, response->status_string, line_end); - for (;header;header = header->next) { - PRINTF("header %u \n", (uint16_t)header); - index += sprintf(buffer + index, "%s%s%s%s", header->name, header_delimiter, header->value, line_end); - } - index += sprintf(buffer + index, "%s", line_end); - - memcpy(buffer + index, response->payload, response->payload_len); - index += response->payload_len; - - PRINTF("Sending Data(size %d): %s \n", index, buffer); - - PSOCK_SEND(&(conn_state->sout), buffer, index); - } else { - PRINTF("BUFF ERROR: send_data!\n"); - } - - PSOCK_END(&(conn_state->sout)); -} - -static -PT_THREAD(handle_response(connection_state_t* conn_state)) -{ - PT_BEGIN(&(conn_state->outputpt)); - - PRINTF("handle_response ->\n"); - - http_set_res_header(&conn_state->response, HTTP_HEADER_NAME_CONNECTION, close, 0); - http_set_res_header(&conn_state->response, HTTP_HEADER_NAME_SERVER, contiki, 0); - - if (!(conn_state->response.status_string)) { - conn_state->response.status_string = - get_default_status_string(conn_state->response.status_code); - } - - PT_WAIT_THREAD(&(conn_state->outputpt), send_data(conn_state)); - - PRINTF("<-- handle_response\n\n\n"); - - PSOCK_CLOSE(&(conn_state->sout)); - - PT_END(&(conn_state->outputpt)); -} - -static void -handle_connection(connection_state_t* conn_state) -{ - if (conn_state->state == STATE_WAITING) { - handle_request(conn_state); - } - - if (conn_state->state == STATE_OUTPUT) { - handle_response(conn_state); - } -} - -PROCESS(http_server, "Httpd Process"); - -PROCESS_THREAD(http_server, ev, data) -{ - connection_state_t *conn_state; - - PROCESS_BEGIN(); - - /* if static routes are used rather than RPL */ -#if !UIP_CONF_IPV6_RPL && !defined (CONTIKI_TARGET_MINIMAL_NET) - set_global_address(); - configure_routing(); -#endif /*!UIP_CONF_IPV6_RPL*/ - - #ifdef CONTIKI_TARGET_SKY - PRINTF("##RF CHANNEL : %d##\n",RF_CHANNEL); - #endif //CONTIKI_TARGET_SKY - - tcp_listen(uip_htons(HTTP_PORT)); - - /* - * We loop for ever, accepting new connections. - */ - while(1) { - PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); - - conn_state = (connection_state_t *)data; - - if(uip_connected()) { - PRINTF("##Connected##\n"); - - if(init_buffer(HTTP_DATA_BUFF_SIZE)) { - conn_state = (connection_state_t*)allocate_buffer(sizeof(connection_state_t)); - - if (conn_state) { - tcp_markconn(uip_conn, conn_state); - - /*initialize connection state*/ - init_connection(conn_state); - - /*-1 is needed to be able to null terminate the strings in the buffer, especially good for debugging (to have null terminated strings)*/ - PSOCK_INIT(&(conn_state->sin), (uint8_t*)conn_state->inputbuf, sizeof(conn_state->inputbuf) - 1); - PSOCK_INIT(&(conn_state->sout), (uint8_t*)conn_state->inputbuf, sizeof(conn_state->inputbuf) - 1); - PT_INIT(&(conn_state->outputpt)); - - handle_connection(conn_state); - } else { - PRINTF("Memory Alloc Error. Aborting!\n"); - uip_abort(); - } - } - } else if (uip_aborted() || uip_closed() || uip_timedout()) { - if (conn_state) { - delete_buffer(); - - /*Following 2 lines are needed since this part of code is somehow executed twice so it tries to free the same region twice. - Potential bug in uip*/ - conn_state = NULL; - tcp_markconn(uip_conn, conn_state); - } - } else { - handle_connection(conn_state); - } - } - - PROCESS_END(); -} diff --git a/apps/rest-http/http-server.h b/apps/rest-http/http-server.h deleted file mode 100644 index f28fee0ea..000000000 --- a/apps/rest-http/http-server.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef HTTPSERVER_H_ -#define HTTPSERVER_H_ - -#include "http-common.h" -#include "rest.h" - -/*Declare process*/ -PROCESS_NAME(http_server); - -/*Type definition of the service callback*/ -typedef int (*service_callback) (http_request_t* request, http_response_t* response); - -/* - *Setter of the service callback, this callback will be called in case of HTTP request. - */ -void http_set_service_callback(service_callback callback); - -/* - * Setter for the status code (200, 201, etc) of the response. - */ -void http_set_status(http_response_t* response, status_code_t status); - -/* - * Adds the header name and value provided to the response. - * Name of the header should be hardcoded since it is accessed from code segment - * (not copied to buffer) whereas value of the header can be copied - * depending on the relevant parameter. This is needed since some values may be - * generated dynamically (ex: e-tag value) - */ -int http_set_res_header(http_response_t* response, const char* name, const char* value, int copy); - -/* - * Returns the value of the header name provided. Return NULL if header does not exist. - */ -const char* http_get_req_header(http_request_t* request, const char* name); - -int http_set_res_payload(http_response_t* response, uint8_t* payload, uint16_t size); - -/* - * Returns query variable in the URL. - * Returns true if the variable found, false otherwise. - * Variable is put in the buffer provided. - */ -int http_get_query_variable(http_request_t* request, const char *name, char* output, uint16_t output_size); - -/* - * Returns variable in the Post Data. - * Returns true if the variable found, false otherwise. - * Variable is put in the buffer provided. - */ -int http_get_post_variable(http_request_t* request, const char *name, char* output, uint16_t output_size); - -/* - * Get the header "Content-Type". - */ -const char* http_get_content_type_string(content_type_t content_type); -content_type_t http_get_header_content_type(http_request_t* request); - -#endif /*HTTPSERVER_H_*/ diff --git a/apps/serial-shell/serial-shell.c b/apps/serial-shell/serial-shell.c index bba7f54f4..96383bdb7 100644 --- a/apps/serial-shell/serial-shell.c +++ b/apps/serial-shell/serial-shell.c @@ -1,8 +1,3 @@ -/** - * \addtogroup shell - * @{ - */ - /* * Copyright (c) 2008, Swedish Institute of Computer Science. * All rights reserved. @@ -41,6 +36,11 @@ * Adam Dunkels */ +/** + * \addtogroup shell + * @{ + */ + #include "contiki.h" #include "shell.h" diff --git a/apps/servreg-hack/servreg-hack.c b/apps/servreg-hack/servreg-hack.c index 3242433c6..d7ccf7dac 100644 --- a/apps/servreg-hack/servreg-hack.c +++ b/apps/servreg-hack/servreg-hack.c @@ -1,6 +1,3 @@ -/** \addtogroup servreghack - * @{ */ - /* * Copyright (c) 2010, Swedish Institute of Computer Science. * All rights reserved. @@ -40,6 +37,9 @@ * Adam Dunkels */ +/** \addtogroup servreghack + * @{ */ + #include "contiki.h" #include "contiki-lib.h" #include "contiki-net.h" @@ -332,14 +332,10 @@ static void parse_incoming_packet(const uint8_t *buf, int len) { int numregs; - int flags; int i; int bufptr; numregs = buf[MSG_NUMREGS_OFFSET]; - flags = buf[MSG_FLAGS_OFFSET]; - - /* printf("parse_incoming_packet Numregs %d flags %d\n", numregs, flags);*/ bufptr = MSG_ADDRS_OFFSET; for(i = 0; i < numregs; ++i) { @@ -379,3 +375,5 @@ PROCESS_THREAD(servreg_hack_process, ev, data) PROCESS_END(); } /*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/apps/servreg-hack/servreg-hack.h b/apps/servreg-hack/servreg-hack.h index 11fc70eec..b24590f90 100644 --- a/apps/servreg-hack/servreg-hack.h +++ b/apps/servreg-hack/servreg-hack.h @@ -1,26 +1,3 @@ -/** \addtogroup apps - * @{ */ - -/** - * \defgroup servreghack A service registration and diseemination hack - * @{ - * - * This application is a quick'n'dirty hack for registering, - * disseminating, and looking up services. A service is identified by - * an 8-bit integer between 1 and 255. Integers below 128 are reserved - * for system services. - * - * A service is registered with the function - * servreg_hack_register(). Registered services will be transmitted to - * all neighbors that run the servreg-hack application. These will in - * turn resend the registration to their neighbors. - * - * Services from neighbors are stored in a local table. Services - * stored in the table can be looked up using a combination of the - * servreg_hack_list() and servreg_hack_item_match() functions. - * - */ - /* * Copyright (c) 2010, Swedish Institute of Computer Science. * All rights reserved. @@ -60,6 +37,29 @@ * Adam Dunkels */ +/** \addtogroup apps + * @{ */ + +/** + * \defgroup servreghack A service registration and diseemination hack + * @{ + * + * This application is a quick'n'dirty hack for registering, + * disseminating, and looking up services. A service is identified by + * an 8-bit integer between 1 and 255. Integers below 128 are reserved + * for system services. + * + * A service is registered with the function + * servreg_hack_register(). Registered services will be transmitted to + * all neighbors that run the servreg-hack application. These will in + * turn resend the registration to their neighbors. + * + * Services from neighbors are stored in a local table. Services + * stored in the table can be looked up using a combination of the + * servreg_hack_list() and servreg_hack_item_match() functions. + * + */ + #ifndef SERVREG_HACK_H #define SERVREG_HACK_H diff --git a/apps/shell/Makefile.shell b/apps/shell/Makefile.shell index 97cd5663f..db1de4d6a 100644 --- a/apps/shell/Makefile.shell +++ b/apps/shell/Makefile.shell @@ -1,19 +1,35 @@ -shell_src = shell.c shell-reboot.c \ - shell-vars.c shell-ps.c shell-rime.c shell-sendtest.c \ +shell_src = shell.c shell-reboot.c shell-vars.c shell-ps.c \ shell-blink.c shell-text.c shell-time.c \ - shell-file.c shell-netfile.c shell-run.c \ - shell-rime-ping.c shell-rime-sniff.c shell-rime-netcmd.c \ - shell-rime-debug.c shell-rime-debug-runicast.c shell-coffee.c \ - shell-wget.c shell-httpd.c shell-irc.c \ + shell-file.c shell-run.c \ + shell-coffee.c \ shell-power.c \ - shell-tcpsend.c shell-udpsend.c shell-ping.c shell-netstat.c \ - shell-rime-sendcmd.c shell-download.c shell-rime-neighbors.c \ - shell-rime-unicast.c \ shell-base64.c \ - shell-netperf.c shell-memdebug.c \ - shell-powertrace.c shell-collect-view.c shell-crc.c + shell-memdebug.c \ + shell-powertrace.c shell-crc.c shell_dsc = shell-dsc.c + +ifeq ($(CONTIKI_WITH_RIME),1) +shell_src += shell-rime.c shell-sendtest.c \ + shell-rime-ping.c shell-rime-sniff.c shell-rime-netcmd.c \ + shell-rime-debug.c shell-rime-debug-runicast.c \ + shell-rime-sendcmd.c shell-download.c shell-rime-neighbors.c \ + shell-rime-unicast.c shell-netperf.c \ + shell-collect-view.c + +APPS += collect-view +include $(CONTIKI)/apps/collect-view/Makefile.collect-view +endif +ifeq ($(CONTIKI_WITH_IPV4),1) + SHELL_WITH_IP = 1 +endif +ifeq ($(CONTIKI_WITH_IPV6),1) + SHELL_WITH_IP = 1 +endif + +ifeq ($(SHELL_WITH_IP),1) +shell_src += shell-wget.c shell-httpd.c shell-irc.c \ + shell-tcpsend.c shell-udpsend.c shell-ping.c shell-netstat.c APPS += webserver include $(CONTIKI)/apps/webserver/Makefile.webserver ifndef PLATFORM_BUILD @@ -38,13 +54,11 @@ ifndef PLATFORM_BUILD override telnet_src = telnet.c endif +endif + APPS += powertrace include $(CONTIKI)/apps/powertrace/Makefile.powertrace - -APPS += collect-view -include $(CONTIKI)/apps/collect-view/Makefile.collect-view - ifeq ($(TARGET),sky) shell_src += shell-sky.c shell-exec.c endif diff --git a/apps/shell/shell-base64.c b/apps/shell/shell-base64.c index ca723748c..30d921d34 100644 --- a/apps/shell/shell-base64.c +++ b/apps/shell/shell-base64.c @@ -86,7 +86,7 @@ base64_decode_char(char c) static int base64_add_char(struct base64_decoder_state *s, char c) { - if(isspace(c)) { + if(isspace((int)c)) { return 0; } diff --git a/apps/shell/shell-crc.c b/apps/shell/shell-crc.c index 315ca18e2..b3234577a 100644 --- a/apps/shell/shell-crc.c +++ b/apps/shell/shell-crc.c @@ -50,6 +50,7 @@ #define HAVE_ALLOCA 0 #else #define HAVE_ALLOCA 1 +#include #endif #define DEBUG 0 diff --git a/apps/shell/shell-download.c b/apps/shell/shell-download.c index 86ad20207..7c2d419e8 100644 --- a/apps/shell/shell-download.c +++ b/apps/shell/shell-download.c @@ -31,9 +31,11 @@ */ /** - * \file Shell command for downloading files from a remote node. + * \file + * + * Shell command for downloading files from a remote node. * Example usage: - * 'download | write \ | write \'. * * \author Luca Mottola , Fredrik Osterlind */ diff --git a/apps/shell/shell-exec.c b/apps/shell/shell-exec.c index 1f5bbf383..8442f22ef 100644 --- a/apps/shell/shell-exec.c +++ b/apps/shell/shell-exec.c @@ -116,11 +116,13 @@ PROCESS_THREAD(shell_exec_process, ev, data) shell_output_str(&exec_command, print, symbol); if(ret == ELFLOADER_OK) { +#if !PROCESS_CONF_NO_PROCESS_NAMES int i; for(i = 0; elfloader_autostart_processes[i] != NULL; ++i) { shell_output_str(&exec_command, "exec: starting process ", elfloader_autostart_processes[i]->name); } +#endif autostart_start(elfloader_autostart_processes); } diff --git a/apps/shell/shell-file.c b/apps/shell/shell-file.c index 07f6f3d5d..4376c68a3 100644 --- a/apps/shell/shell-file.c +++ b/apps/shell/shell-file.c @@ -51,7 +51,7 @@ PROCESS(shell_ls_process, "ls"); SHELL_COMMAND(ls_command, "ls", - "ls: list files", + "ls : list files", &shell_ls_process); PROCESS(shell_append_process, "append"); SHELL_COMMAND(append_command, @@ -82,19 +82,21 @@ PROCESS_THREAD(shell_ls_process, ev, data) char buf[32]; PROCESS_BEGIN(); - if(cfs_opendir(&dir, "/") != 0) { - shell_output_str(&ls_command, "Cannot open directory", ""); - } else { - totsize = 0; - while(cfs_readdir(&dir, &dirent) == 0) { - totsize += dirent.size; - sprintf(buf, "%lu ", (unsigned long)dirent.size); - /* printf("'%s'\n", dirent.name);*/ - shell_output_str(&ls_command, buf, dirent.name); + if(data != NULL) { + if(cfs_opendir(&dir, data) != 0) { + shell_output_str(&ls_command, "Cannot open directory", ""); + } else { + totsize = 0; + while(cfs_readdir(&dir, &dirent) == 0) { + totsize += dirent.size; + sprintf(buf, "%lu ", (unsigned long)dirent.size); + /* printf("'%s'\n", dirent.name);*/ + shell_output_str(&ls_command, buf, dirent.name); + } + cfs_closedir(&dir); + sprintf(buf, "%lu", (unsigned long)totsize); + shell_output_str(&ls_command, "Total size: ", buf); } - cfs_closedir(&dir); - sprintf(buf, "%lu", (unsigned long)totsize); - shell_output_str(&ls_command, "Total size: ", buf); } PROCESS_END(); } diff --git a/apps/shell/shell-memdebug.c b/apps/shell/shell-memdebug.c index 9c6be22a9..e25e5afae 100644 --- a/apps/shell/shell-memdebug.c +++ b/apps/shell/shell-memdebug.c @@ -71,7 +71,7 @@ PROCESS_THREAD(shell_poke_process, ev, data) PROCESS_EXIT(); } - address = (uint8_t *)(int)shell_strtolong(args, &next); + address = (uint8_t *)(uintptr_t)shell_strtolong(args, &next); if(next == args) { shell_output_str(&poke_command, "usage 1", ""); PROCESS_EXIT(); @@ -106,7 +106,7 @@ PROCESS_THREAD(shell_peek_process, ev, data) PROCESS_EXIT(); } - address = (uint8_t *)(int)shell_strtolong(args, &next); + address = (uint8_t *)(uintptr_t)shell_strtolong(args, &next); if(next == args) { shell_output_str(&peek_command, "usage 1", ""); PROCESS_EXIT(); diff --git a/apps/shell/shell-netfile.c b/apps/shell/shell-netfile.c deleted file mode 100644 index 45c303974..000000000 --- a/apps/shell/shell-netfile.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2008, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * A brief description of what this file is. - * \author - * Adam Dunkels - */ - -#include "contiki.h" -#include "shell-netfile.h" -#include "net/rime/rime.h" -#include "net/rime/rudolph0.h" -#include "dev/leds.h" - -#include "cfs/cfs.h" - -#include -#include - -#define FILENAME_LEN 20 - -static struct rudolph0_conn rudolph0_conn; -static char filename[FILENAME_LEN]; -static int receiving_file; -static struct pt recvnetfilept; -/*---------------------------------------------------------------------------*/ -PROCESS(shell_netfile_process, "netfile"); -SHELL_COMMAND(netfile_command, - "netfile", - "netfile: send file to entire network", - &shell_netfile_process); -PROCESS(shell_recvnetfile_process, "recvnetfile"); -SHELL_COMMAND(recvnetfile_command, - "recvnetfile", - "recvnetfile: receive file from network and print to output", - &shell_recvnetfile_process); -/*---------------------------------------------------------------------------*/ -static int -write_chunk_pt(struct rudolph0_conn *c, int offset, int flag, - uint8_t *data, int datalen) -{ - PT_BEGIN(&recvnetfilept); - - PT_WAIT_UNTIL(&recvnetfilept, receiving_file); - leds_on(LEDS_YELLOW); - leds_on(LEDS_RED); - PT_WAIT_UNTIL(&recvnetfilept, flag == RUDOLPH0_FLAG_NEWFILE); - leds_off(LEDS_RED); - - do { - if(datalen > 0) { - shell_output(&recvnetfile_command, data, datalen, "", 0); - /* printf("write_chunk wrote %d bytes at %d\n", datalen, offset);*/ - } - PT_YIELD(&recvnetfilept); - } while(flag != RUDOLPH0_FLAG_LASTCHUNK); - - shell_output(&recvnetfile_command, data, datalen, "", 0); - /* printf("write_chunk wrote %d bytes at %d\n", datalen, offset);*/ - shell_output(&recvnetfile_command, "", 0, "", 0); - leds_off(LEDS_YELLOW); - receiving_file = 0; - process_post(&shell_recvnetfile_process, PROCESS_EVENT_CONTINUE, NULL); - - PT_END(&recvnetfilept); -} -static void -write_chunk(struct rudolph0_conn *c, int offset, int flag, - uint8_t *data, int datalen) -{ - write_chunk_pt(c, offset, flag, data, datalen); -} - -static int -read_chunk(struct rudolph0_conn *c, int offset, uint8_t *to, int maxsize) -{ - int ret; - int fd; - - fd = cfs_open(filename, CFS_READ); - - cfs_seek(fd, offset, CFS_SEEK_SET); - ret = cfs_read(fd, to, maxsize); - /* printf("read_chunk %d bytes at %d, %d\n", ret, offset, (unsigned char)to[0]);*/ - cfs_close(fd); - return ret; -} -CC_CONST_FUNCTION static struct rudolph0_callbacks rudolph0_callbacks = - {/*(void (*)(struct rudolph0_conn *, int, int, uint8_t *, int))*/ - write_chunk, - read_chunk}; -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(shell_netfile_process, ev, data) -{ - int fd; - - PROCESS_BEGIN(); - - if(data != NULL) { - rudolph0_send(&rudolph0_conn, CLOCK_SECOND); - - strncpy(filename, data, FILENAME_LEN); - fd = cfs_open(filename, CFS_READ); - if(fd < 0) { - shell_output_str(&netfile_command, "netfile: could not open file ", filename); - } else { - cfs_close(fd); - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(shell_recvnetfile_process, ev, data) -{ - PROCESS_BEGIN(); - - PT_INIT(&recvnetfilept); - receiving_file = 1; - while(1) { - struct shell_input *input; - - PROCESS_WAIT_EVENT(); - - if(ev == shell_event_input) { - input = data; - if(input->len1 + input->len2 == 0) { - receiving_file = 0; - PROCESS_EXIT(); - } - } else if(receiving_file == 0) { - PROCESS_EXIT(); - } - } - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ -void -shell_netfile_init(void) -{ - receiving_file = 0; - shell_register_command(&netfile_command); - shell_register_command(&recvnetfile_command); - - rudolph0_open(&rudolph0_conn, SHELL_RIME_CHANNEL_NETFILE, - &rudolph0_callbacks); -} -/*---------------------------------------------------------------------------*/ diff --git a/apps/shell/shell-netperf.c b/apps/shell/shell-netperf.c index b4e35ed1a..5776945fc 100644 --- a/apps/shell/shell-netperf.c +++ b/apps/shell/shell-netperf.c @@ -128,8 +128,8 @@ memcpy_misaligned(void *dest, const void *source, int len) int i; uint8_t *destptr; const uint8_t *sourceptr; - if(((int)dest & 1) == 1 || - ((int)source & 1) == 1) { + if(((uintptr_t)dest & 1) == 1 || + ((uintptr_t)source & 1) == 1) { destptr = dest; sourceptr = source; for(i = 0; i < len; ++i) { diff --git a/apps/shell/shell-ping.c b/apps/shell/shell-ping.c index 8f202d162..5f73cc6f2 100644 --- a/apps/shell/shell-ping.c +++ b/apps/shell/shell-ping.c @@ -62,7 +62,7 @@ static unsigned char running; /*---------------------------------------------------------------------------*/ static void send_ping(uip_ipaddr_t *dest_addr) -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 { static uint16_t count; UIP_IP_BUF->vtc = 0x60; @@ -92,7 +92,7 @@ send_ping(uip_ipaddr_t *dest_addr) tcpip_ipv6_output(); } -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ { static uint16_t ipid = 0; static uint16_t seqno = 0; @@ -128,7 +128,7 @@ send_ping(uip_ipaddr_t *dest_addr) tcpip_output(); } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /*---------------------------------------------------------------------------*/ PROCESS_THREAD(shell_ping_process, ev, data) { diff --git a/apps/shell/shell-power.c b/apps/shell/shell-power.c index c4414c9a1..0e5cb0aed 100644 --- a/apps/shell/shell-power.c +++ b/apps/shell/shell-power.c @@ -42,6 +42,7 @@ #include "sys/energest.h" #include +#include "sys/cc.h" struct power_msg { uint16_t len; diff --git a/apps/shell/shell-rime-netcmd.c b/apps/shell/shell-rime-netcmd.c index 08acc2ed1..87927065d 100644 --- a/apps/shell/shell-rime-netcmd.c +++ b/apps/shell/shell-rime-netcmd.c @@ -129,7 +129,7 @@ PROCESS_THREAD(shell_netcmd_process, ev, data) /* Terminate the string with a NUL character. */ msg->netcmd[len] = 0; - msg->crc = crc16_data(msg->netcmd, len, 0); + msg->crc = crc16_data((unsigned char *)msg->netcmd, len, 0); printf("netcmd sending '%s'\n", msg->netcmd); trickle_send(&trickle); } @@ -157,9 +157,9 @@ recv_trickle(struct trickle_conn *c) msg->netcmd[len] = 0; memcpy(&crc, &msg->crc, sizeof(crc)); - if(crc == crc16_data(msg->netcmd, len, 0)) { + if(crc == crc16_data((unsigned char *)msg->netcmd, len, 0)) { /* Start the server process with the incoming command. */ - process_start(&shell_netcmd_server_process, msg->netcmd); + process_start(&shell_netcmd_server_process, (void *)msg->netcmd); } } } diff --git a/apps/shell/shell-rime-sendcmd.c b/apps/shell/shell-rime-sendcmd.c index ac173c2a8..5bbbc4aea 100644 --- a/apps/shell/shell-rime-sendcmd.c +++ b/apps/shell/shell-rime-sendcmd.c @@ -133,7 +133,7 @@ PROCESS_THREAD(shell_sendcmd_process, ev, data) /* Terminate the string with a NUL character. */ msg->sendcmd[len] = 0; - msg->crc = crc16_data(msg->sendcmd, len, 0); + msg->crc = crc16_data((unsigned char *)msg->sendcmd, len, 0); /* printf("sendcmd sending '%s'\n", msg->sendcmd);*/ unicast_send(&uc, &addr); @@ -160,9 +160,9 @@ recv_uc(struct unicast_conn *c, const linkaddr_t *from) msg->sendcmd[len] = 0; memcpy(&crc, &msg->crc, sizeof(crc)); - if(crc == crc16_data(msg->sendcmd, len, 0)) { + if(crc == crc16_data((unsigned char *)msg->sendcmd, len, 0)) { /* Start the server process with the incoming command. */ - process_start(&shell_sendcmd_server_process, msg->sendcmd); + process_start(&shell_sendcmd_server_process, (void *)msg->sendcmd); } } } diff --git a/apps/shell/shell-rime.c b/apps/shell/shell-rime.c index 16061c58d..3e6184ff7 100644 --- a/apps/shell/shell-rime.c +++ b/apps/shell/shell-rime.c @@ -301,7 +301,7 @@ recv_collect(const linkaddr_t *originator, uint8_t seqno, uint8_t hops) /* Copy the collect message header. */ memcpy(&collect_msg, packetbuf_dataptr(), sizeof(collect_msg)); - dataptr = ((struct collect_msg *)packetbuf_dataptr())->data; + dataptr = (char *)((struct collect_msg *)packetbuf_dataptr())->data; #if TIMESYNCH_CONF_ENABLED latency = timesynch_time() - collect_msg.timestamp; @@ -321,7 +321,7 @@ recv_collect(const linkaddr_t *originator, uint8_t seqno, uint8_t hops) if(packetbuf_datalen() >= COLLECT_MSG_HDRSIZE) { len = packetbuf_datalen() - COLLECT_MSG_HDRSIZE; - if(collect_msg.crc == crc16_data(dataptr, len, 0)) { + if(collect_msg.crc == crc16_data((unsigned char *)dataptr, len, 0)) { msg.len = 5 + (packetbuf_datalen() - COLLECT_MSG_HDRSIZE) / 2; linkaddr_copy((linkaddr_t *)&msg.originator, originator); msg.seqno = seqno; diff --git a/apps/shell/shell-sky.c b/apps/shell/shell-sky.c index 65c4859ed..a25b15957 100644 --- a/apps/shell/shell-sky.c +++ b/apps/shell/shell-sky.c @@ -38,6 +38,7 @@ */ #include "contiki.h" +#include "sys/cc.h" #include "shell-sky.h" #include "dev/watchdog.h" @@ -84,8 +85,6 @@ SHELL_COMMAND(rfchannel_command, "rfchannel : change CC2420 radio channel (11 - 26)", &shell_rfchannel_process); /*---------------------------------------------------------------------------*/ -#define MAX(a, b) ((a) > (b)? (a): (b)) -#define MIN(a, b) ((a) < (b)? (a): (b)) struct spectrum { int channel[16]; }; diff --git a/apps/shell/shell-tcpsend.c b/apps/shell/shell-tcpsend.c index 923cda181..7ef93b671 100644 --- a/apps/shell/shell-tcpsend.c +++ b/apps/shell/shell-tcpsend.c @@ -36,13 +36,10 @@ #include #include "contiki.h" +#include "sys/cc.h" #include "shell.h" #include "telnet.h" -#ifndef MIN -#define MIN(a, b) ((a) < (b)? (a) : (b)) -#endif /* MIN */ - /*---------------------------------------------------------------------------*/ PROCESS(shell_tcpsend_process, "tcpsend"); SHELL_COMMAND(tcpsend_command, diff --git a/apps/shell/shell-time.c b/apps/shell/shell-time.c index eb7ceec7c..6947df7ee 100644 --- a/apps/shell/shell-time.c +++ b/apps/shell/shell-time.c @@ -38,6 +38,7 @@ */ #include "contiki.h" +#include "sys/cc.h" #include "shell-time.h" #include "sys/clock.h" @@ -51,11 +52,6 @@ #define MAX_COMMANDLENGTH 64 #define PERIOD_INTERVAL 60 -#ifndef MIN -#define MIN(a, b) ((a) < (b)? (a) : (b)) -#endif /* MIN */ - - /*---------------------------------------------------------------------------*/ PROCESS(shell_time_process, "time"); SHELL_COMMAND(time_command, @@ -162,7 +158,6 @@ PROCESS_THREAD(shell_repeat_server_process, ev, data) static char *command; static struct process *started_process; char command_copy[MAX_COMMANDLENGTH]; - int ret; if(ev == shell_event_input) { goto exit; @@ -176,7 +171,7 @@ PROCESS_THREAD(shell_repeat_server_process, ev, data) data == &shell_repeat_process); { strncpy(command_copy, command, MAX_COMMANDLENGTH); - ret = shell_start_command(command_copy, (int)strlen(command_copy), + shell_start_command(command_copy, (int)strlen(command_copy), &repeat_command, &started_process); if(started_process != NULL && @@ -206,11 +201,10 @@ repeat_print_usage(void) /*---------------------------------------------------------------------------*/ PROCESS_THREAD(shell_repeat_process, ev, data) { - static int reps, period, period_left; + static int reps, period; static char command[MAX_COMMANDLENGTH]; static struct etimer etimer; static int i; - static clock_time_t start_time; const char *args, *next; if(ev == shell_event_input) { @@ -262,11 +256,10 @@ PROCESS_THREAD(shell_repeat_process, ev, data) /* printf("repeats %d period %d command '%s'\n", reps, period, command);*/ - start_time = clock_time(); etimer_set(&etimer, CLOCK_SECOND * period); for(i = 0; reps == 0 || i < reps; ++i) { - process_start(&shell_repeat_server_process, command); + process_start(&shell_repeat_server_process, (void *)command); process_post(&shell_repeat_server_process, PROCESS_EVENT_CONTINUE, &shell_repeat_process); @@ -295,7 +288,6 @@ PROCESS_THREAD(shell_randwait_process, ev, data) static struct etimer etimer; static struct process *started_process; const char *args, *next; - int ret; /* if(ev == shell_event_input) { struct shell_input *input; @@ -343,7 +335,7 @@ PROCESS_THREAD(shell_randwait_process, ev, data) /* printf("Starting '%s' child %p (%s)\n", command, randwait_command.child, */ /* randwait_command.child == NULL? "null": randwait_command.child->command); */ - ret = shell_start_command(command, (int)strlen(command), + shell_start_command(command, (int)strlen(command), randwait_command.child, &started_process); if(started_process != NULL && diff --git a/apps/shell/shell-vars.c b/apps/shell/shell-vars.c index 42948f5aa..14b484923 100644 --- a/apps/shell/shell-vars.c +++ b/apps/shell/shell-vars.c @@ -51,7 +51,7 @@ #define SHELL_VARS_RAM_END SHELL_VARS_CONF_RAM_END #else /* SHELL_VARS_CONF_RAM_BEGIN */ #define SHELL_VARS_RAM_BEGIN 0 -#define SHELL_VARS_RAM_END (unsigned int)-1 +#define SHELL_VARS_RAM_END (uintptr_t)-1 #endif /* SHELL_VARS_CONF_RAM_BEGIN */ /*---------------------------------------------------------------------------*/ @@ -77,8 +77,8 @@ PROCESS_THREAD(shell_vars_process, ev, data) for(i = 0; i < symbols_nelts; ++i) { if(symbols[i].name != NULL && - (unsigned int)symbols[i].value >= SHELL_VARS_RAM_BEGIN && - (unsigned int)symbols[i].value <= SHELL_VARS_RAM_END) { + (uintptr_t)symbols[i].value >= SHELL_VARS_RAM_BEGIN && + (uintptr_t)symbols[i].value <= SHELL_VARS_RAM_END) { shell_output_str(&vars_command, (char *)symbols[i].name, ""); } } @@ -90,7 +90,7 @@ PROCESS_THREAD(shell_var_process, ev, data) { int i; int j; - char numbuf[32]; + char numbuf[40]; PROCESS_BEGIN(); diff --git a/apps/shell/shell.c b/apps/shell/shell.c index fd909c791..b02f45c31 100644 --- a/apps/shell/shell.c +++ b/apps/shell/shell.c @@ -1,8 +1,3 @@ -/** - * \addtogroup shell - * @{ - */ - /* * Copyright (c) 2008, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup shell + * @{ + */ + #include "contiki.h" #include "contiki-lib.h" @@ -298,7 +298,7 @@ start_command(char *commandline, struct shell_command *child) c->child = child; /* printf("shell: start_command starting '%s'\n", c->process->name);*/ /* Start a new process for the command. */ - process_start(c->process, args); + process_start(c->process, (void *)args); } return c; @@ -364,7 +364,7 @@ shell_input(char *commandline, int commandline_len) if(commandline[0] == '~' && commandline[1] == 'K') { - /* process_start(&shell_killall_process, commandline);*/ + /* process_start(&shell_killall_process, (void *)commandline);*/ if(front_process != &shell_process) { process_exit(front_process); } @@ -532,7 +532,7 @@ shell_strtolong(const char *str, const char **retstr) ++strptr; } - for(i = 0; i < 10 && isdigit(strptr[i]); ++i) { + for(i = 0; i < 10 && isdigit((int)strptr[i]); ++i) { num = num * 10 + strptr[i] - '0'; } if(retstr != NULL) { diff --git a/apps/shell/shell.h b/apps/shell/shell.h index 750cee02f..f6e4e1b8d 100644 --- a/apps/shell/shell.h +++ b/apps/shell/shell.h @@ -1,23 +1,3 @@ -/** \addtogroup apps - * @{ */ - -/** - * \defgroup shell The Contiki shell - * @{ - * - * The Contiki shell provides both interactive and batch processing - * for Contiki. - * - * The shell consists of two parts: the shell application and a shell - * back-end. The shell application contains all the logic of the - * shell, whereas the shell back-end provides I/O for the - * shell. Examples of shell back-ends are a serial I/O shell back-end, - * that allows the shell to operate over a serial connection, and a - * telnet server back-end, that allows the shell to operate over a - * TCP/IP telnet connection. - * - */ - /* * Copyright (c) 2008, Swedish Institute of Computer Science. * All rights reserved. @@ -57,6 +37,26 @@ * Adam Dunkels */ +/** \addtogroup apps + * @{ */ + +/** + * \defgroup shell The Contiki shell + * @{ + * + * The Contiki shell provides both interactive and batch processing + * for Contiki. + * + * The shell consists of two parts: the shell application and a shell + * back-end. The shell application contains all the logic of the + * shell, whereas the shell back-end provides I/O for the + * shell. Examples of shell back-ends are a serial I/O shell back-end, + * that allows the shell to operate over a serial connection, and a + * telnet server back-end, that allows the shell to operate over a + * TCP/IP telnet connection. + * + */ + #ifndef SHELL_H_ #define SHELL_H_ @@ -382,7 +382,6 @@ struct shell_input { #include "shell-httpd.h" #include "shell-irc.h" #include "shell-memdebug.h" -#include "shell-netfile.h" #include "shell-netperf.h" #include "shell-netstat.h" #include "shell-ping.h" diff --git a/apps/telnetd/telnetd.c b/apps/telnetd/telnetd.c index 95786442b..7b211f121 100644 --- a/apps/telnetd/telnetd.c +++ b/apps/telnetd/telnetd.c @@ -33,6 +33,7 @@ #include +#include "sys/cc.h" #include "contiki-lib.h" #include "contiki-net.h" #include "lib/petsciiconv.h" @@ -61,6 +62,10 @@ static char telnetd_reject_text[] = "Too many connections, please try again later."; #endif +#ifndef TELNETD_CONF_MAX_IDLE_TIME +#define TELNETD_CONF_MAX_IDLE_TIME (CLOCK_SECOND * 30) +#endif + struct telnetd_state { char buf[TELNETD_CONF_LINELEN + 1]; char bufptr; @@ -73,7 +78,9 @@ struct telnetd_state { #define STATE_DO 4 #define STATE_DONT 5 #define STATE_CLOSE 6 +#if TELNETD_CONF_MAX_IDLE_TIME struct timer silence_timer; +#endif /* TELNETD_CONF_MAX_IDLE_TIME */ }; static struct telnetd_state s; @@ -101,9 +108,6 @@ static struct telnetd_buf buf; static uint8_t connected; -#define MAX_SILENCE_TIME (CLOCK_SECOND * 30) - -#define MIN(a, b) ((a) < (b)? (a): (b)) /*---------------------------------------------------------------------------*/ static void buf_init(struct telnetd_buf *buf) @@ -169,6 +173,8 @@ shell_prompt(char *str) void shell_default_output(const char *str1, int len1, const char *str2, int len2) { + static const char crnl[2] = {ISO_cr, ISO_nl}; + if(len1 > 0 && str1[len1 - 1] == '\n') { --len1; } @@ -183,7 +189,7 @@ shell_default_output(const char *str1, int len1, const char *str2, int len2) #endif /* TELNETD_CONF_GUI */ buf_append(&buf, str1, len1); buf_append(&buf, str2, len2); - buf_append(&buf, "\r\n", 2); + buf_append(&buf, crnl, sizeof(crnl)); } /*---------------------------------------------------------------------------*/ void @@ -359,7 +365,9 @@ telnetd_appcall(void *ts) s.state = STATE_NORMAL; connected = 1; shell_start(); - timer_set(&s.silence_timer, MAX_SILENCE_TIME); +#if TELNETD_CONF_MAX_IDLE_TIME + timer_set(&s.silence_timer, TELNETD_CONF_MAX_IDLE_TIME); +#endif /* TELNETD_CONF_MAX_IDLE_TIME */ ts = (char *)0; } else { uip_send(telnetd_reject_text, strlen(telnetd_reject_text)); @@ -381,11 +389,15 @@ telnetd_appcall(void *ts) connected = 0; } if(uip_acked()) { - timer_set(&s.silence_timer, MAX_SILENCE_TIME); +#if TELNETD_CONF_MAX_IDLE_TIME + timer_set(&s.silence_timer, TELNETD_CONF_MAX_IDLE_TIME); +#endif /* TELNETD_CONF_MAX_IDLE_TIME */ acked(); } if(uip_newdata()) { - timer_set(&s.silence_timer, MAX_SILENCE_TIME); +#if TELNETD_CONF_MAX_IDLE_TIME + timer_set(&s.silence_timer, TELNETD_CONF_MAX_IDLE_TIME); +#endif /* TELNETD_CONF_MAX_IDLE_TIME */ newdata(); } if(uip_rexmit() || @@ -394,16 +406,20 @@ telnetd_appcall(void *ts) uip_connected() || uip_poll()) { senddata(); +#if TELNETD_CONF_MAX_IDLE_TIME if(s.numsent > 0) { - timer_set(&s.silence_timer, MAX_SILENCE_TIME); + timer_set(&s.silence_timer, TELNETD_CONF_MAX_IDLE_TIME); } +#endif /* TELNETD_CONF_MAX_IDLE_TIME */ } +#if TELNETD_CONF_MAX_IDLE_TIME if(uip_poll()) { if(timer_expired(&s.silence_timer)) { uip_close(); tcp_markconn(uip_conn, NULL); } } +#endif /* TELNETD_CONF_MAX_IDLE_TIME */ } } /*---------------------------------------------------------------------------*/ diff --git a/apps/time/Makefile.time b/apps/time/Makefile.time index 1440c805d..e03b8fee6 100644 --- a/apps/time/Makefile.time +++ b/apps/time/Makefile.time @@ -1 +1,2 @@ -time_src = time.c resource_gmtime.c resource_timestamp.c +time_src = time.c resource_gmtime.c resource_timestamp.c \ + resource_timezone.c resource_crontab.c cron.c diff --git a/apps/time/README b/apps/time/README new file mode 100644 index 000000000..1fc14a37a --- /dev/null +++ b/apps/time/README @@ -0,0 +1,20 @@ +Timezones +========= + +The new version supports time zones and daylight saving time (DST). +Currently we support only a single timezone. We use the UNIX timezone +format which is usually specified in an environment variable TZ. + +Note that for timezone information you can have different +representation, either relative to Universal Time Coordinated (UTC) or +to International Atomic Time (TAI), the latter contains leap seconds. +Since most systems today use UTC *and* the clock of a microcontroller +is typically not accurate enough to care about leap seconds, we're using +timezone files relative to UTC. + +Wikipedia has a very good treatment of the public timezone database in +https://en.wikipedia.org/wiki/Tz_database + +The format of timezone strings is described in the Linux manual page +tzset(3). The timezone specification for Europe/Vienna is +CET-1CEST,M3.5.0,M10.5.0/3 diff --git a/apps/time/bitstring.h b/apps/time/bitstring.h new file mode 100644 index 000000000..e83826951 --- /dev/null +++ b/apps/time/bitstring.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 1989 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Paul Vixie. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#)bitstring.h 5.2 (Berkeley) 4/4/90 + */ + +typedef unsigned char bitstr_t; + +/* internal macros */ + /* byte of the bitstring bit is in */ +#define _bit_byte(bit) \ + ((bit) >> 3) + + /* mask for the bit within its byte */ +#define _bit_mask(bit) \ + (1 << ((bit)&0x7)) + +/* external macros */ + /* bytes in a bitstring of nbits bits */ +#define bitstr_size(nbits) \ + ((((nbits) - 1) >> 3) + 1) + + + /* allocate a bitstring on the stack */ +#define bit_decl(name, nbits) \ + (name)[bitstr_size(nbits)] + + /* is bit N of bitstring name set? */ +#define bit_test(name, bit) \ + ((name)[_bit_byte(bit)] & _bit_mask(bit)) + + /* set bit N of bitstring name */ +#define bit_set(name, bit) \ + (name)[_bit_byte(bit)] |= _bit_mask(bit) + + /* clear bit N of bitstring name */ +#define bit_clear(name, bit) \ + (name)[_bit_byte(bit)] &= ~_bit_mask(bit) + + /* clear bits start ... stop in bitstring */ +#define bit_nclear(name, start, stop) { \ + register bitstr_t *_name = name; \ + register int _start = start, _stop = stop; \ + register int _startbyte = _bit_byte(_start); \ + register int _stopbyte = _bit_byte(_stop); \ + if (_startbyte == _stopbyte) { \ + _name[_startbyte] &= ((0xff >> (8 - (_start&0x7))) | \ + (0xff << ((_stop&0x7) + 1))); \ + } else { \ + _name[_startbyte] &= 0xff >> (8 - (_start&0x7)); \ + while (++_startbyte < _stopbyte) \ + _name[_startbyte] = 0; \ + _name[_stopbyte] &= 0xff << ((_stop&0x7) + 1); \ + } \ +} + + /* set bits start ... stop in bitstring */ +#define bit_nset(name, start, stop) { \ + register bitstr_t *_name = name; \ + register int _start = start, _stop = stop; \ + register int _startbyte = _bit_byte(_start); \ + register int _stopbyte = _bit_byte(_stop); \ + if (_startbyte == _stopbyte) { \ + _name[_startbyte] |= ((0xff << (_start&0x7)) & \ + (0xff >> (7 - (_stop&0x7)))); \ + } else { \ + _name[_startbyte] |= 0xff << ((_start)&0x7); \ + while (++_startbyte < _stopbyte) \ + _name[_startbyte] = 0xff; \ + _name[_stopbyte] |= 0xff >> (7 - (_stop&0x7)); \ + } \ +} + + /* find first bit clear in name */ +#define bit_ffc(name, nbits, value) { \ + register bitstr_t *_name = name; \ + register int _byte, _nbits = nbits; \ + register int _stopbyte = _bit_byte(_nbits), _value = -1; \ + for (_byte = 0; _byte <= _stopbyte; ++_byte) \ + if (_name[_byte] != 0xff) { \ + _value = _byte << 3; \ + for (_stopbyte = _name[_byte]; (_stopbyte&0x1); \ + ++_value, _stopbyte >>= 1); \ + break; \ + } \ + *(value) = _value; \ +} + + /* find first bit set in name */ +#define bit_ffs(name, nbits, value) { \ + register bitstr_t *_name = name; \ + register int _byte, _nbits = nbits; \ + register int _stopbyte = _bit_byte(_nbits), _value = -1; \ + for (_byte = 0; _byte <= _stopbyte; ++_byte) \ + if (_name[_byte]) { \ + _value = _byte << 3; \ + for (_stopbyte = _name[_byte]; !(_stopbyte&0x1); \ + ++_value, _stopbyte >>= 1); \ + break; \ + } \ + *(value) = _value; \ +} diff --git a/apps/time/cron.c b/apps/time/cron.c new file mode 100644 index 000000000..22b4132d5 --- /dev/null +++ b/apps/time/cron.c @@ -0,0 +1,488 @@ +/** + * \file + * cron: Cron-like functionality + * \author + * Ralf Schlatterbeck + * + * \brief cron-like command scheduler + * + * Inspired by vixie's cron by Paul Vixie which is + * Copyright 1988,1990,1993,1994 by Paul Vixie + * + * Distribute freely, except: don't remove my name from the source or + * documentation (don't take credit for my work), mark your changes (don't + * get me blamed for your possible bugs), don't alter or remove this + * notice. May be sold if buildable source is provided to buyer. No + * warrantee of any kind, express or implied, is included with this + * software; use at your own risk, responsibility for damages (if any) to + * anyone resulting from the use of this software rests entirely with the + * user. + * + * Changes to make this work on a microcontroller by Ralf Schlatterbeck + * In fact this is mostly a rewrite but keeps central algorithms and + * some data structures of the original. + * The syntax is simplified, we don't support the @ notation (e.g. + * @hourly) and named entities (e.g. weekday names instead of numbers). + * Furthermore we can't send email and don't support environment + * variables. The called commands are functions registered via a + * registration mechanism before runtime. + * Copyright 2016 Ralf Schlatterbeck, distribute with the conditions + * given above. + */ + +#include +#include +#include +#include +#include +#include +#include "contiki.h" +#include "cron.h" +#include "xtime.h" + +#undef DEBUG + +static struct cron_entry cron_entries [MAX_CRON_ENTRIES]; +static struct cron_cmd cron_commands [MAX_CRON_COMMANDS]; +static size_t cron_registered_entries = 0; +static size_t cron_registered_commands = 0; +static struct cron_entry *entry_freelist = NULL; +static struct cron_entry *entry_list = NULL; + +typedef int64_t minute_t; +static xtime_t start_time; +static minute_t cron_clock_time; + +/* Register a new cron command + * A command consists of a name (which must be unique, uniqueness is not + * enforced currently as registrations are done once at initialization + * time), a function to be called and a parameter. + */ +int cron_register_command + (const char *name, void (*function)(void *), void * parameter) +{ + if (cron_registered_commands >= MAX_CRON_COMMANDS) { + return -1; + } + cron_commands [cron_registered_commands].name = name; + cron_commands [cron_registered_commands].function = function; + cron_commands [cron_registered_commands].parameter = parameter; + cron_registered_commands++; + return 0; +} + +/* + * Allocate a new crontab entry. + * This allocates from the freelist and returns NULL if no more entries + * are available. + * Implementation note: If cron_registered_entries is 0 we first + * initialize the entry_freelist and the entry_list. + */ +struct cron_entry *allocate_cron_entry (void) +{ + size_t n; + struct cron_entry *e; + if (cron_registered_entries == 0) { + entry_list = NULL; + entry_freelist = &cron_entries [0]; + for (n=0; n < (MAX_CRON_ENTRIES - 1); n++) { + cron_entries [n].next = &cron_entries [n+1]; + } + cron_entries [MAX_CRON_ENTRIES - 1].next = NULL; + } + if (cron_registered_entries >= MAX_CRON_ENTRIES) { + return NULL; + } + e = entry_freelist; + entry_freelist = e->next; + e->next = entry_list; + entry_list = e; + cron_registered_entries++; + return e; +} + +void free_cron_entry (struct cron_entry *obsolete) +{ + struct cron_entry *e; + assert (cron_registered_entries); + if (entry_list == obsolete) { + entry_list = obsolete->next; + obsolete->next = entry_freelist; + entry_freelist = obsolete; + cron_registered_entries--; + return; + } + for (e=entry_list; e; e=e->next) { + if (e->next == obsolete) { + e->next = obsolete->next; + obsolete->next = entry_freelist; + entry_freelist = obsolete; + cron_registered_entries--; + break; + } + } + assert (e != NULL); +} + +struct cron_entry *get_cron_entry (size_t idx) +{ + if (idx >= MAX_CRON_ENTRIES) { + return NULL; + } + return &cron_entries [idx]; +} + +/* Set the number in bits, return 0 on success -1 on error */ +static int set_element (bitstr_t *bits, int low, int high, int n) +{ + if (n < low || n > high) { + return -1; + } + bit_set (bits, (n - low)); + return 0; +} + +static const char *get_number (int *np, int high, const char *s) +{ + char *endptr; + long l = strtol (s, &endptr, 10); + if (endptr == s || errno == ERANGE || l > high) { + return NULL; + } + *np = l; + return endptr; +} + +static const char *get_range (bitstr_t *bits, int low, int high, const char *s) +{ + int i; + int n1, n2, n3; + + if (*s == '*') { + /* '*' means "first-last" but can be modified by /step */ + n1 = low; + n2 = high; + if (*++s == '\0') { + return NULL; + } + } else { + s = get_number (&n1, high, s); + if (s == NULL || *s == '\0') { + return NULL; + } + if (*s != '-') { + if (set_element (bits, low, high, n1) < 0) { + return NULL; + } + return s; + } else { + if (*++s == '\0') { + return NULL; + } + s = get_number (&n2, high, s); + if (*s == '\0') { + return NULL; + } + } + } + if (*s == '/') { + if (*++s == '\0') { + return NULL; + } + s = get_number (&n3, high, s); + if (*s == '\0') { + return NULL; + } + } else { + n3 = 1; + } + /* Explicit check for sane values */ + if (n1 < low || n1 > high || n2 < low || n2 > high) { + return NULL; + } + for (i=n1; i<=n2; i+=n3) { + if (set_element (bits, low, high, i) < 0) { + return NULL; + } + } + return s; +} + +static const char *get_list (bitstr_t *bits, int low, int high, const char *s) +{ + int done = 0; + bit_nclear (bits, 0, (high - low + 1)); + while (!done) { + s = get_range (bits, low, high, s); + if (NULL == s) { + return NULL; + } + if (*s == ',') { + s++; + } else { + done = 1; + } + } + /* Skip white space */ + while (s && isspace (*s)) { + s++; + } + return s; +} + +/* + * Parse a single crontab entry on a single line. + * We get the line via CoAP. + * Returns 0 if parsed successfully, -1 on error. + * On error the err pointer is set to the error message. + */ +int parse_crontab_line + (const char *line, struct cron_entry *e, const char **err) +{ + size_t n; + const char *s = line; + size_t cmd_len = 0; + + e->flags &= ~VALID; + if (*s == '*') { + e->flags |= MIN_STAR; + } + s = get_list (e->minute, FIRST_MINUTE, LAST_MINUTE, s); + if (NULL == s || *s == '\0') { + *err = "minute"; + return -1; + } + if (*s == '*') { + e->flags |= HR_STAR; + } + s = get_list (e->hour, FIRST_HOUR, LAST_HOUR, s); + if (NULL == s || *s == '\0') { + *err = "hour"; + return -1; + } + if (*s == '*') { + e->flags |= DOM_STAR; + } + s = get_list (e->dom, FIRST_DOM, LAST_DOM, s); + if (NULL == s || *s == '\0') { + *err = "dom"; + return -1; + } + s = get_list (e->month, FIRST_MONTH, LAST_MONTH, s); + if (NULL == s || *s == '\0') { + *err = "month"; + return -1; + } + if (*s == '*') { + e->flags |= DOW_STAR; + } + s = get_list (e->dow, FIRST_DOW, LAST_DOW, s); + if (NULL == s || *s == '\0') { + *err = "dow"; + return -1; + } + /* Make sundays equivalent */ + if (bit_test (e->dow, 0) || bit_test (e->dow, 7)) { + bit_set (e->dow, 0); + bit_set (e->dow, 7); + } + /* strip whitespace at *end* of command + * by getting length without whitespace + */ + for (n=0; s [n]; n++) { + if (!isspace (s [n])) { + cmd_len = n + 1; + } + } + for (n=0; ncmd = &cron_commands [n]; + break; + } + } + if (n == cron_registered_commands) { + *err = "command"; + return -1; + } + e->flags |= VALID; + return 0; +} + +static void set_time (void) +{ + struct xtm *tm; + struct xtimeval tv; + xgettimeofday (&tv, NULL); + start_time = tv.tv_sec; + tm = xlocaltime (&start_time); + /* We adjust the time to GMT so we can catch DST changes */ + cron_clock_time = (start_time + tm->tm_gmtoff) / (xtime_t)SECONDS_PER_MINUTE; +} + +static void find_jobs (minute_t vtime, int do_wild, int do_nonwild) +{ + xtime_t virtual_second = vtime * SECONDS_PER_MINUTE; + struct xtm *tm = xgmtime (&virtual_second); + int minute, hour, dom, month, dow; + struct cron_entry *e; + + /* make 0-based values out of these so we can use them as indicies */ + minute = tm->tm_min -FIRST_MINUTE; + hour = tm->tm_hour -FIRST_HOUR; + dom = tm->tm_mday -FIRST_DOM; + month = tm->tm_mon +1 /* 0..11 -> 1..12 */ -FIRST_MONTH; + dow = tm->tm_wday -FIRST_DOW; + #ifdef DEBUG + printf ("%d %d %d %d %d\n", minute, hour, dom, month, dow); + #endif + + /* the dom/dow situation is odd. '* * 1,15 * Sun' will run on the + * first and fifteenth AND every Sunday; '* * * * Sun' will run *only* + * on Sundays; '* * 1,15 * *' will run *only* the 1st and 15th. this + * is why we keep 'e->dow_star' and 'e->dom_star'. yes, it's bizarre. + * like many bizarre things, it's the standard. + */ + for (e = entry_list; e; e = e->next) { + #ifdef DEBUG + if (e->flags & VALID) { + printf ("Checking entry %s\n", e->cmd->name); + } + printf ("valid: %d\n", (e->flags & VALID)); + printf ("minute: %d\n", (bit_test (e->minute, minute))); + printf ("hour: %d\n", (bit_test (e->hour, hour))); + printf ("month %d\n", (bit_test (e->month, month))); + printf ("dom* %d\n", (e->flags & DOM_STAR)); + printf ("dow* %d\n", (e->flags & DOW_STAR)); + printf ("dow %d\n", (bit_test (e->dow, dow))); + printf ("dom %d\n", (bit_test (e->dom, dom))); + printf ("min* %d\n", (e->flags & MIN_STAR)); + printf ("hr* %d\n", (e->flags & HR_STAR)); + printf ("nonwild %d\n", (do_nonwild)); + #endif + if ( (e->flags & VALID) + && bit_test (e->minute, minute) + && bit_test (e->hour, hour) + && bit_test (e->month, month) + && ( ((e->flags & DOM_STAR) || (e->flags & DOW_STAR)) + ? (bit_test (e->dow, dow) && bit_test (e->dom, dom)) + : (bit_test (e->dow, dow) || bit_test (e->dom, dom)) + ) + ) + { + if ( (do_nonwild && !(e->flags & (MIN_STAR | HR_STAR))) + || (do_wild && (e->flags & (MIN_STAR | HR_STAR))) + ) + { + printf ("Cron: calling \"%s\"\n", e->cmd->name); + e->cmd->function (e->cmd->parameter); + } + } + } +} + +/* + * The cron callback function must be run regularly, at least once per + * minute. + * Implementation: + * Clocks are in minutes since the epoch (time() / 60). + * virtual_time is the time it *would* be if we are called promptly and + * nobody ever changed the clock. It is monotonically increasing... + * unless a timejump happens. + * time_running is the time we were last called. We determine + * initialization by checking time_running for -1. + * cron_clock_time is the current time for this run. + */ +void cron (void) +{ + static minute_t time_running = -1; + static minute_t virtual_time = -1; + minute_t time_diff; + + /* + * ... calculate how the current time differs from + * our virtual clock. Classify the change into one + * of 4 cases + */ + set_time (); + if (time_running == cron_clock_time) { + #ifdef DEBUG + printf ("time not reached\n"); + #endif + return; + } + time_running = cron_clock_time; + time_diff = time_running - virtual_time; + #ifdef DEBUG + printf ("time_diff: %ld\n", (long)time_diff); + #endif + /* shortcut for the most common case */ + if (time_diff == 1) { + virtual_time = time_running; + find_jobs (virtual_time, 1, 1); + } else { + int wakeup_kind = -1; + if (time_diff > -(3*MINUTE_COUNT)) { + wakeup_kind = 0; + } + if (time_diff > 0) { + wakeup_kind = 1; + } + if (time_diff > 5) { + wakeup_kind = 2; + } + if (time_diff > (3*MINUTE_COUNT)) { + wakeup_kind = 3; + } + #ifdef DEBUG + printf ("wakeup_kind: %d\n", wakeup_kind); + #endif + switch (wakeup_kind) { + /* time_diff is a small positive number (wokeup late) + * run jobs for each virtual minute until caught up. + */ + case 1: + do { + virtual_time++; + find_jobs (virtual_time, 1, 1); + } while (virtual_time < time_running); + break; + /* time_diff is a medium-sized positive number, for example + * because we went to DST. Run wildcard jobs once, then run any + * fixed-time jobs that would otherwise be skipped. If we use up + * our minute (possible, if there are a lot of jobs to run) go + * around the loop again so that wildcard jobs have a chance to + * run, and we do our housekeeping. + */ + case 2: + /* run wildcard jobs for current minute */ + find_jobs (time_running, 1, 0); + /* run fixed-time jobs for each minute missed */ + do { + virtual_time++; + find_jobs (virtual_time, 0, 1); + set_time (); + } while ( virtual_time < time_running + && cron_clock_time == time_running + ); + break; + /* time_diff is a small or medium-sized negative num, eg. + * because of DST ending. Just run the wildcard jobs. The + * fixed-time jobs probably have already run, and should not be + * repeated. virtual_time does not change until we are caught up. + */ + case 0: + find_jobs (time_running, 1, 0); + break; + /* Other: time has changed a *lot*, jump virtual time, and run + * everything + */ + default: + virtual_time = time_running; + find_jobs (time_running, 1, 1); + break; + } + } +} diff --git a/apps/time/cron.h b/apps/time/cron.h new file mode 100644 index 000000000..592d42127 --- /dev/null +++ b/apps/time/cron.h @@ -0,0 +1,91 @@ +/* + * Definitions for cron + * Inspired by vixie's cron by Paul Vixie which is + * Copyright 1988,1990,1993,1994 by Paul Vixie + * + * Distribute freely, except: don't remove my name from the source or + * documentation (don't take credit for my work), mark your changes (don't + * get me blamed for your possible bugs), don't alter or remove this + * notice. May be sold if buildable source is provided to buyer. No + * warrantee of any kind, express or implied, is included with this + * software; use at your own risk, responsibility for damages (if any) to + * anyone resulting from the use of this software rests entirely with the + * user. + * Changes to make this work on a microcontroller by Ralf Schlatterbeck + * In fact this is mostly a rewrite but keeps central algorithms of the + * original. + * Copyright 2016 Ralf Schlatterbeck, distribute with the conditions + * given above. + */ + +#ifndef _cron_h_ +#define _cron_h_ + +#include "bitstring.h" + +#define SECONDS_PER_MINUTE 60 + +#define FIRST_MINUTE 0 +#define LAST_MINUTE 59 +#define MINUTE_COUNT (LAST_MINUTE - FIRST_MINUTE + 1) + +#define FIRST_HOUR 0 +#define LAST_HOUR 23 +#define HOUR_COUNT (LAST_HOUR - FIRST_HOUR + 1) + +#define FIRST_DOM 1 +#define LAST_DOM 31 +#define DOM_COUNT (LAST_DOM - FIRST_DOM + 1) + +#define FIRST_MONTH 1 +#define LAST_MONTH 12 +#define MONTH_COUNT (LAST_MONTH - FIRST_MONTH + 1) + +/* note on DOW: 0 and 7 are both Sunday, for compatibility reasons. */ +#define FIRST_DOW 0 +#define LAST_DOW 7 +#define DOW_COUNT (LAST_DOW - FIRST_DOW + 1) + +#ifndef MAX_CRON_ENTRIES +#define MAX_CRON_ENTRIES 5 +#endif + +#ifndef MAX_CRON_COMMANDS +#define MAX_CRON_COMMANDS 5 +#endif + +struct cron_cmd { + const char *name; + void (*function)(void *); + void *parameter; +}; + +struct cron_entry { + struct cron_entry *next; + struct cron_cmd *cmd; + bitstr_t bit_decl(minute, MINUTE_COUNT); + bitstr_t bit_decl(hour, HOUR_COUNT); + bitstr_t bit_decl(dom, DOM_COUNT); + bitstr_t bit_decl(month, MONTH_COUNT); + bitstr_t bit_decl(dow, DOW_COUNT); + int flags; + +#define DOM_STAR 0x01 +#define DOW_STAR 0x02 +#define WHEN_REBOOT 0x04 +#define MIN_STAR 0x08 +#define HR_STAR 0x10 +#define VALID 0x20 +}; + +extern int parse_crontab_line + (const char *line, struct cron_entry *e, const char **err); +extern int cron_register_command + (const char *name, void (*function)(void *), void * parameter); + +extern struct cron_entry *allocate_cron_entry (void); +extern struct cron_entry *get_cron_entry (size_t idx); +extern void free_cron_entry (struct cron_entry *e); +extern void cron (void); + +#endif /* _cron_h_ */ diff --git a/apps/time/resource_crontab.c b/apps/time/resource_crontab.c new file mode 100644 index 000000000..394a1df53 --- /dev/null +++ b/apps/time/resource_crontab.c @@ -0,0 +1,118 @@ +/** + * \file + * Resource for crontab entry + * \author + * Ralf Schlatterbeck + * + * \brief get/put crontab entry + */ + +#include +#include +#include +#include "contiki.h" +#include "time_resource.h" +#include "jsonparse.h" +#include "er-coap.h" +#include "generic_resource.h" +#include "cron.h" + +static size_t get_index_from_uri (const char *uri) +{ + const char *s; + char *endptr; + size_t idx; + if (uri == NULL) { + return MAX_CRON_ENTRIES; + } + if (NULL == (s = strrchr (uri, '/'))) { + return MAX_CRON_ENTRIES; + } + idx = strtoul (s+1, &endptr, 10); + if (s == endptr || *endptr != '\0') { + return MAX_CRON_ENTRIES; + } + return idx; +} + +int crontab_from_string (const char *name, const char *uri, const char *s) +{ + const char *err; + int res; + size_t idx = get_index_from_uri (uri); + if (idx >= MAX_CRON_ENTRIES) { + return -1; + } + res = parse_crontab_line (s, get_cron_entry (idx), &err); + if (res < 0) { + printf ("Error parsing: %s\n", err); + return -1; + } + return 0; +} + +size_t +crontab_to_string (const char *name, const char *uri, char *buf, size_t bsize) +{ + /* FIXME: For now we only return "valid" or "invalid" until someone + * comes up with a clever algorithm to reconstruct a crontab string + * from the cron_entry struct. + */ + size_t idx = get_index_from_uri (uri); + struct cron_entry *e; + if (idx >= MAX_CRON_ENTRIES) { + return MAX_GET_STRING_LENGTH; + } + e = get_cron_entry (idx); + if (e->flags & VALID) { + return snprintf (buf, bsize, "valid"); + } + return snprintf (buf, bsize, "invalid"); +} + +GENERIC_RESOURCE + ( crontab + , crontab-entry + , s + , 1 + , crontab_from_string + , crontab_to_string + ); + +/* Allocate all cron entries and the necessary resources */ +void activate_cron_resources (void) +{ + size_t n; + for (n=0; nurl holds the path + * under which we activate it using rest_activate_resource + */ + if (NULL == (res = malloc (sizeof (*res)))) { + printf ("Error malloc\n"); + break; + } + memcpy (res, &res_crontab, sizeof (*res)); + e = allocate_cron_entry (); + assert (!(e->flags & VALID)); + len = snprintf (name, sizeof (name), "crontab/%u", n); + name [sizeof (name) -1] = '\0'; + assert (len < 15); + if (NULL == (buf = malloc (len + 1))) { + printf ("Error malloc\n"); + break; + } + strcpy (buf, name); + rest_activate_resource (res, buf); + } +} + +/* + * VI settings, see coding style + * ex:ts=8:et:sw=2 + */ + diff --git a/apps/time/resource_gmtime.c b/apps/time/resource_gmtime.c index b16be9794..9aef78efe 100644 --- a/apps/time/resource_gmtime.c +++ b/apps/time/resource_gmtime.c @@ -11,50 +11,46 @@ #include #include #include "contiki.h" -#include "time.h" +#include "xtime.h" #include "time_resource.h" #include "jsonparse.h" -/* Only coap 13 for now */ -#include "er-coap-13.h" +#include "er-coap.h" #include "generic_resource.h" -size_t time_to_string (const char *name, uint8_t is_json, char *buf, size_t bs) +size_t time_to_string (const char *name, const char *uri, char *buf, size_t bs) { - struct timeval tv; - struct tm tm; - struct tm *(*method)(const time_t *, struct tm *) = gmtime_r; + struct xtimeval tv; + struct xtm tm; + struct xtm *(*method)(const xtime_t *, struct xtm *) = xgmtime_r; if (0 == strcmp (name, "localtime")) { - method = localtime_r; + method = xlocaltime_r; } - gettimeofday (&tv, NULL); + xgettimeofday (&tv, NULL); method (&tv.tv_sec, &tm); return snprintf ( buf , bs - , "%s%lu-%02u-%02u %02u:%02u:%02u%s" - , is_json ? "\"" : "" + , "%lu-%02u-%02u %02u:%02u:%02u %s" , 1900 + tm.tm_year , tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec - , is_json ? "\"" : "" + , tm.tm_zone ); } GENERIC_RESOURCE \ ( localtime - , METHOD_GET - , "clock/localtime" , Local time , formatted time + , 1 , NULL , time_to_string ); GENERIC_RESOURCE \ ( utc - , METHOD_GET - , "clock/utc" , UTC , formatted time + , 1 , NULL , time_to_string ); diff --git a/apps/time/resource_timestamp.c b/apps/time/resource_timestamp.c index 1f0885131..aa18a19eb 100644 --- a/apps/time/resource_timestamp.c +++ b/apps/time/resource_timestamp.c @@ -15,41 +15,36 @@ #include #include #include "contiki.h" -#include "time.h" +#include "xtime.h" #include "time_resource.h" #include "jsonparse.h" -/* Only coap 13 for now */ -#include "er-coap-13.h" +#include "er-coap.h" #include "generic_resource.h" -void timestamp_from_string (const char *name, const char *s) +int timestamp_from_string (const char *name, const char *uri, const char *s) { - struct timeval tv; + struct xtimeval tv; // FIXME: Platform has no strtoll (long long)? tv.tv_sec = strtol (s, NULL, 10); - settimeofday (&tv, NULL); + xsettimeofday (&tv, NULL); + return 0; } size_t -timestamp_to_string (const char *name, uint8_t is_json, char *buf, size_t bsize) +timestamp_to_string (const char *name, const char *uri, char *buf, size_t bsize) { - struct timeval tv; - char *fmt = "%ld"; - if (is_json) { - fmt = "\"%ld\""; - } - gettimeofday (&tv, NULL); + struct xtimeval tv; + xgettimeofday (&tv, NULL); // FIXME: Platform doesn't seem to support long long printing // We get empty string - return snprintf (buf, bsize, fmt, (long)tv.tv_sec); + return snprintf (buf, bsize, "%ld", (long)tv.tv_sec); } GENERIC_RESOURCE ( timestamp - , METHOD_GET | METHOD_PUT - , "clock/timestamp" , Time , s + , 1 , timestamp_from_string , timestamp_to_string ); diff --git a/apps/time/resource_timezone.c b/apps/time/resource_timezone.c new file mode 100644 index 000000000..1e06ad0d1 --- /dev/null +++ b/apps/time/resource_timezone.c @@ -0,0 +1,48 @@ +/** + * \file + * Resource for timezone handling + * \author + * Ralf Schlatterbeck + * + * \brief get/put timezone string + */ + +#include +#include +#include +#include "contiki.h" +#include "xtime.h" +#include "time_resource.h" +#include "jsonparse.h" +#include "er-coap.h" +#include "generic_resource.h" + +int timezone_from_string (const char *name, const char *uri, const char *s) +{ + set_tz (s); + return 0; +} + +size_t +timezone_to_string (const char *name, const char *uri, char *buf, size_t bsize) +{ + if (get_tz (buf, bsize) == NULL) { + *buf = '\0'; + } + return strlen (buf); +} + +GENERIC_RESOURCE + ( timezone + , TZ + , s + , 1 + , timezone_from_string + , timezone_to_string + ); + +/* + * VI settings, see coding style + * ex:ts=8:et:sw=2 + */ + diff --git a/apps/time/time.c b/apps/time/time.c index d2f7719c8..654a88de0 100644 --- a/apps/time/time.c +++ b/apps/time/time.c @@ -3,16 +3,41 @@ * * @{ */ -#include #include "contiki.h" +#include +#include +#include +#include +#include #include "contiki-lib.h" -#include "time.h" +#include "xtime.h" +#include "tzparse.h" + +#define SECSPERMIN 60 +#define MINSPERHOUR 60 +#define HOURSPERDAY 24 +#define DAYSPERWEEK 7 +#define DAYSPERNYEAR 365 +#define DAYSPERLYEAR 366 +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY) +#define MONSPERYEAR 12 + +static const int mon_lengths[2][MONSPERYEAR] = +{ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +, { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +}; + +/* + * Static timezone information + */ +static struct tzoffset_info localtime_tzoffset; /* Used for gmtime and localtime, according to manpage on linux the * internal value may be overwritten "by subsequent calls to any of the * date and time functions". */ -static struct tm tm; +static struct xtm tm; /* * Internal variables to manage offset of utc from the contiki clock @@ -23,20 +48,21 @@ static struct tm tm; * The last_seconds is used to check if we had a seconds overflow, * although this happens only every 136 years :-) */ -time_t clock_offset; -uint32_t last_seconds; -int16_t minuteswest; +static xtime_t clock_offset; +static uint32_t last_seconds; + +static xtime_t +transtime (xtime_t janfirst, int year, const struct tzrule *rp, long offset); # define LEAP_YEAR(_year) \ ((_year % 4) == 0 && (_year % 100 != 0 || _year % 400 == 0)) # define YDAYS(_year) (LEAP_YEAR(year) ? 366 : 365) -struct tm * -gmtime_r (const time_t *timep, struct tm *ptm) +struct xtm *xgmtime_r (const xtime_t *timep, struct xtm *ptm) { unsigned int year; int days, month, month_len; - time_t t = *timep; + xtime_t t = *timep; ptm->tm_sec = t % 60; t /= 60; ptm->tm_min = t % 60; @@ -51,14 +77,14 @@ gmtime_r (const time_t *timep, struct tm *ptm) year++; } ptm->tm_year = year - 1900; - days -= YDAYS(year); + days -= YDAYS (year); t -= days; ptm->tm_yday = t; for (month=0; month<12; month++) { if (month == 1) { - month_len = LEAP_YEAR(year) ? 29 : 28; + month_len = LEAP_YEAR (year) ? 29 : 28; } else { @@ -79,49 +105,86 @@ gmtime_r (const time_t *timep, struct tm *ptm) break; } } - ptm->tm_mon = month; - ptm->tm_mday = t + 1; - ptm->tm_isdst = 0; + ptm->tm_mon = month; + ptm->tm_mday = t + 1; + ptm->tm_isdst = 0; + ptm->tm_gmtoff = 0; + ptm->tm_zone = "UTC"; return ptm; } -struct tm * -gmtime (const time_t *timep) +struct xtm *xgmtime (const xtime_t *timep) { - return gmtime_r (timep, &tm); + return xgmtime_r (timep, &tm); } -struct tm * -localtime_r (const time_t *timep, struct tm *ptm) +/* + * Compute is_dst flag of given timestamp + */ +static int is_dst (const xtime_t *timep, const struct tzoffset_info *tzo) { - time_t t = *timep; - t += minuteswest * 60; - return gmtime_r (&t, ptm); + xtime_t janfirst = 0; + xtime_t starttime, endtime; + int year = 1970; + int lastdst = 0; + if (tzo->dstname == NULL) { + return 0; + } + + for (year = 1970; janfirst < *timep; year++) { + starttime = transtime (janfirst, year, &tzo->start, tzo->stdoffset); + endtime = transtime (janfirst, year, &tzo->end, tzo->dstoffset); + if (starttime <= *timep && endtime <= *timep) { + lastdst = (starttime > endtime); + } else if (starttime > *timep && endtime <= *timep) { + return 0; + } else if (starttime <= *timep && endtime > *timep) { + return 1; + } else if (starttime > *timep && endtime > *timep) { + return lastdst; + } + janfirst += YDAYS (year) * SECSPERDAY; + } + return lastdst; } -struct tm * -localtime (const time_t *timep) +struct xtm *xlocaltime_r (const xtime_t *timep, struct xtm *ptm) { - return localtime_r (timep, &tm); + const struct tzoffset_info *tzo = &localtime_tzoffset; + int isdst = 0; + long offset = 0; + xtime_t t = *timep; + + if (tzo->stdname == NULL) { + set_tz (DEFAULT_TIMEZONE); + } + isdst = is_dst (timep, tzo); + offset = isdst ? tzo->dstoffset : tzo->stdoffset; + t -= offset; + xgmtime_r (&t, ptm); + ptm->tm_isdst = isdst; + ptm->tm_gmtoff = -offset; + ptm->tm_zone = isdst ? tzo->dstname : tzo->stdname; + return ptm; +} + +struct xtm *xlocaltime (const xtime_t *timep) +{ + return xlocaltime_r (timep, &tm); } /** * \brief Get time in seconds and microseconds - * gettimeofday will return the clock time as the microseconds part - * while settimeofday will *ignore* the microseconds part (for now). + * xgettimeofday will return the clock time as the microseconds part + * while xsettimeofday will *ignore* the microseconds part (for now). * Note that the contiki clock interface is broken anyway, we can't read * seconds and sub-seconds atomically. We try to work around this by * repeatedly reading seconds, sub-seconds, seconds until first and * second read of seconds match. */ -int -gettimeofday (struct timeval *tv, struct timezone *tz) +int xgettimeofday (struct xtimeval *tv, struct timezone *tz) { uint32_t cs; - if (tz) { - tz->tz_minuteswest = minuteswest; - tz->tz_dsttime = 0; - } if (tv) { int i; /* Limit tries to get the same second twice to two */ @@ -133,21 +196,29 @@ gettimeofday (struct timeval *tv, struct timezone *tz) } last_seconds = cs; tv->tv_sec = cs + clock_offset; - tv->tv_usec = ((time_t)(clock_time () % CLOCK_SECOND)) + tv->tv_usec = ((xtime_t)(clock_time () % CLOCK_SECOND)) * 1000000L / CLOCK_SECOND; if (cs == clock_seconds ()) { break; } } } + if (tz) { + const struct tzoffset_info *tzo = &localtime_tzoffset; + tz->tz_dsttime = is_dst (&tv->tv_sec, tzo); + if (tz->tz_dsttime) { + tz->tz_minuteswest = -tzo->dstoffset / 60; + } else { + tz->tz_minuteswest = -tzo->stdoffset / 60; + } + } return 0; } /** * \brief Set time in seconds, microseconds ignored for now */ -int -settimeofday (const struct timeval *tv, const struct timezone *tz) +int xsettimeofday (const struct xtimeval *tv, const struct timezone *tz) { /* Don't allow setting timezone */ if (tz) { @@ -162,4 +233,615 @@ settimeofday (const struct timeval *tv, const struct timezone *tz) return 0; } +/* + * Save timezone names into reserved string buffer and fill in the names + * into the given tzoffset_info. + * Return -1 on error, 0 for success. + */ +static int save_tznames + ( const char *stdname, const char *dstname + , size_t stdlen, size_t dstlen + , struct tzoffset_info *tzo + ) +{ + size_t len = stdlen; + if (stdname == NULL) { + return -1; + } + if (dstname != NULL) { + len += dstlen; + } + if (len + 2 > sizeof (tzo->namebuf)) { + return -1; + } + tzo->stdname = tzo->namebuf; + strncpy (tzo->namebuf, stdname, stdlen); + tzo->namebuf [stdlen] = '\0'; + if (dstlen) { + strncpy (tzo->namebuf + stdlen + 1, dstname, dstlen); + tzo->namebuf [stdlen + 1 + dstlen] = '\0'; + tzo->dstname = tzo->namebuf + stdlen + 1; + } else { + tzo->dstname = NULL; + } + return 0; +} + +/* + * Utility functions for timezone string parsing (POSIX section 8) + * Code adapted from OpenBSD localtime.c 1.57 2015/12/12 21:25:44 + * which is in the public domain. + */ + +/* + * The DST rules to use if TZ has no rules: + * We default to US rules as of 1999-08-17. + * POSIX 1003.1 section 8.1.1 says that the default DST rules are + * implementation dependent; for historical reasons, US rules are a + * common default. + */ +#ifndef TZDEFRULESTRING +#define TZDEFRULESTRING ",M4.1.0,M10.5.0" +#endif + +/* + * Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the + * year, a rule, and the offset from UTC at the time that rule takes effect, + * calculate the Epoch-relative time that rule takes effect. + */ + +static xtime_t +transtime(xtime_t janfirst, int year, const struct tzrule *rulep, long offset) +{ + int leapyear; + xtime_t value; + int i; + int d, m1, yy0, yy1, yy2, dow; + + value = 0; + leapyear = LEAP_YEAR (year); + switch (rulep->r_type) { + + case JULIAN_DAY: + /* + * Jn - Julian day, 1 == January 1, 60 == March 1 even in leap + * years. + * In non-leap years, or if the day number is 59 or less, just + * add SECSPERDAY times the day number-1 to the time of + * January 1, midnight, to get the day. + */ + value = janfirst + (rulep->r_day - 1) * SECSPERDAY; + if (leapyear && rulep->r_day >= 60) { + value += SECSPERDAY; + } + break; + + case DAY_OF_YEAR: + /* + * n - day of year. + * Just add SECSPERDAY times the day number to the time of + * January 1, midnight, to get the day. + */ + value = janfirst + rulep->r_day * SECSPERDAY; + break; + + case MONTH_NTH_DAY_OF_WEEK: + /* + * Mm.n.d - nth "dth day" of month m. + */ + value = janfirst; + for (i = 0; i < rulep->r_mon - 1; ++i) { + value += mon_lengths [leapyear][i] * SECSPERDAY; + } + + /* + ** Use Zeller's Congruence to get day-of-week of first day of + ** month. + */ + m1 = (rulep->r_mon + 9) % 12 + 1; + yy0 = (rulep->r_mon <= 2) ? (year - 1) : year; + yy1 = yy0 / 100; + yy2 = yy0 % 100; + dow = ((26 * m1 - 2) / 10 + 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; + if (dow < 0) { + dow += DAYSPERWEEK; + } + + /* + ** "dow" is the day-of-week of the first day of the month. Get + ** the day-of-month (zero-origin) of the first "dow" day of the + ** month. + */ + d = rulep->r_day - dow; + if (d < 0) { + d += DAYSPERWEEK; + } + for (i = 1; i < rulep->r_week; ++i) { + if (d + DAYSPERWEEK >= mon_lengths[leapyear][rulep->r_mon - 1]) { + break; + } + d += DAYSPERWEEK; + } + + /* + ** "d" is the day-of-month (zero-origin) of the day we want. + */ + value += d * SECSPERDAY; + break; + } + + /* + ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in + ** question. To get the Epoch-relative time of the specified local + ** time on that day, add the transition time and the current offset + ** from UTC. + */ + return value + rulep->r_time + offset; +} + +/* + * Given a pointer into a time zone string, scan until a character that is not + * a valid character in a zone name is found. Return a pointer to that + * character. + */ + +static const char *getzname (const char *s) +{ + char c; + while ((c = *s) != '\0' && !isdigit(c) && c != ',' && c != '-' && c != '+'){ + ++s; + } + return s; +} + +/* + * Given a pointer into an extended time zone string, scan until the ending + * delimiter of the zone name is located. Return a pointer to the delimiter. + * + * As with getzname above, the legal character set is actually quite + * restricted, with other characters producing undefined results. + * We don't do any checking here; checking is done later in common-case code. + */ + +static const char *getqzname (const char *strp, const int delim) +{ + int c; + while ((c = *strp) != '\0' && c != delim) { + ++strp; + } + return strp; +} + +/* + * Given a pointer into a time zone string, extract a number from that string. + * Check that the number is within a specified range; if it is not, return + * NULL. + * Otherwise, return a pointer to the first character not part of the number. + */ + +static const char *getnum (const char *strp, int *nump, int min, int max) +{ + char c; + int num; + + if (strp == NULL || !isdigit ((c = *strp))) { + return NULL; + } + num = 0; + do { + num = num * 10 + (c - '0'); + if (num > max) { + return NULL; /* illegal value */ + } + c = *++strp; + } while (isdigit (c)); + if (num < min) { + return NULL; /* illegal value */ + } + *nump = num; + return strp; +} + +/* + * Given a pointer into a time zone string, extract a number of seconds, + * in hh[:mm[:ss]] form, from the string. + * If any error occurs, return NULL. + * Otherwise, return a pointer to the first character not part of the number + * of seconds. + */ + +static const char *getsecs (const char *strp, long *secsp) +{ + int num; + + /* + * `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like + * "M10.4.6/26", which does not conform to Posix, + * but which specifies the equivalent of + * ``02:00 on the first Sunday on or after 23 Oct''. + */ + strp = getnum (strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); + if (strp == NULL) { + return NULL; + } + *secsp = num * (long) SECSPERHOUR; + if (*strp == ':') { + ++strp; + strp = getnum (strp, &num, 0, MINSPERHOUR - 1); + if (strp == NULL) { + return NULL; + } + *secsp += num * SECSPERMIN; + if (*strp == ':') { + ++strp; + /* `SECSPERMIN' allows for leap seconds. */ + strp = getnum (strp, &num, 0, SECSPERMIN); + if (strp == NULL) { + return NULL; + } + *secsp += num; + } + } + return strp; +} + +/* + * Given a pointer into a time zone string, extract an offset, in + * [+-]hh[:mm[:ss]] form, from the string. + * If any error occurs, return NULL. + * Otherwise, return a pointer to the first character not part of the time. + */ + +static const char *getoffset (const char *strp, long *offsetp) +{ + int neg = 0; + + if (*strp == '-') { + neg = 1; + ++strp; + } else if (*strp == '+') { + ++strp; + } + strp = getsecs (strp, offsetp); + if (strp == NULL) { + return NULL; /* illegal time */ + } + if (neg) { + *offsetp = -*offsetp; + } + return strp; +} + +/* + * Parse (optionally extended) timezone name. Return pointer to + * (undelimited) timezone name in tzn and length of same in len. + * Return pointer to first character *after* name, NULL on error. + * Factored from original tzparse function. + */ +static const char * +egettzname (const char *strp, size_t *len, const char **tzn) +{ + *tzn = strp; + if (*strp == '<') { + strp++; + *tzn = strp; + strp = getqzname (strp, '>'); + if (*strp != '>') { + return NULL; + } + *len = strp - *tzn; + strp++; + } else { + strp = getzname (strp); + *len = strp - *tzn; + } + return strp; +} + +/* +** Given a pointer into a time zone string, extract a rule in the form +** date[/time]. See POSIX section 8 for the format of "date" and "time". +** If a valid rule is not found, return NULL. +** Otherwise, return a pointer to the first character not part of the rule. +*/ + +static const char *getrule (const char *strp, struct tzrule *rulep) +{ + if (*strp == 'J') { + /* + * Julian day. + */ + rulep->r_type = JULIAN_DAY; + ++strp; + strp = getnum (strp, &rulep->r_day, 1, DAYSPERNYEAR); + } else if (*strp == 'M') { + /* + * Month, week, day. + */ + rulep->r_type = MONTH_NTH_DAY_OF_WEEK; + ++strp; + strp = getnum (strp, &rulep->r_mon, 1, MONSPERYEAR); + if (strp == NULL) { + return NULL; + } + if (*strp++ != '.') { + return NULL; + } + strp = getnum (strp, &rulep->r_week, 1, 5); + if (strp == NULL) { + return NULL; + } + if (*strp++ != '.') { + return NULL; + } + strp = getnum (strp, &rulep->r_day, 0, DAYSPERWEEK - 1); + } else if (isdigit (*strp)) { + /* + * Day of year. + */ + rulep->r_type = DAY_OF_YEAR; + strp = getnum (strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); + } else { + return NULL; /* invalid format */ + } + if (strp == NULL) { + return NULL; + } + if (*strp == '/') { + /* + * Time specified. + */ + ++strp; + strp = getsecs (strp, &rulep->r_time); + } else { + rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ + } + return strp; +} + +/* + * Parse POSIX section 8 TZ string. + * We keep the misnomer "name" for the timezone string. + */ +int tzparse (const char *name, struct tzoffset_info *tzo) +{ + const char *stdname; + const char *dstname; + size_t stdlen; + size_t dstlen; + long stdoffset; + long dstoffset; + + dstname = NULL; + stdname = name; + name = egettzname (name, &stdlen, &stdname); + if (name == NULL || *name == '\0') { + return -1; + } + name = getoffset (name, &stdoffset); + if (name == NULL) { + return -1; + } + if (*name != '\0') { + name = egettzname (name, &dstlen, &dstname); + if (name == NULL) { + return -1; + } + if (*name != '\0' && *name != ',' && *name != ';') { + name = getoffset (name, &dstoffset); + if (name == NULL) { + return -1; + } + } else { + dstoffset = stdoffset - SECSPERHOUR; + } + if (*name == '\0') { + name = TZDEFRULESTRING; + } + if (*name == ',' || *name == ';') { + struct tzrule start; + struct tzrule end; + ++name; + if ((name = getrule (name, &start)) == NULL) { + return -1; + } + if (*name++ != ',') { + return -1; + } + if ((name = getrule (name, &end)) == NULL) { + return -1; + } + if (*name != '\0') { + return -1; + } + if (save_tznames (stdname, dstname, stdlen, dstlen, tzo) != 0) { + return -1; + } + tzo->start = start; + tzo->end = end; + tzo->stdoffset = stdoffset; + tzo->dstoffset = dstoffset; + } else { + return -1; + } + } else { + /* only standard time, no DST */ + if (save_tznames (stdname, NULL, stdlen, 0, tzo) != 0) { + return -1; + } + tzo->stdoffset = stdoffset; + tzo->dstoffset = stdoffset; + } + return 0; +} + +/* + * Provide a single static timezone which is used by localtime et.al. + */ +int set_tz (const char *tzstring) +{ + return tzparse (tzstring, &localtime_tzoffset); +} + +static size_t lensecs (long seconds) +{ + size_t len = 1; + long secs = abs (seconds); + if (seconds < 0) { + len++; + } + if (secs / 3600 > 9) { + len++; + } + if (secs % 3600) { + len += 3; + if (secs % 60) { + len += 3; + } + } + return len; +} + +/* + * Get length of string resulting from serializing rule. + */ +static size_t lenrule (const struct tzrule *rule) +{ + size_t len = 0; + if (rule->r_type == JULIAN_DAY) { + len++; + } + if (rule->r_type == JULIAN_DAY || rule->r_type == DAY_OF_YEAR) { + len++; + if (rule->r_day > 9) { + len++; + if (rule->r_day > 99) { + len++; + } + } + } else if (rule->r_type == MONTH_NTH_DAY_OF_WEEK) { + len++; + len++; + if (rule->r_mon > 9) { + len++; + } + len += 4; /* dots and week/day */ + if (rule->r_time != 7200) { + len++; + len += lensecs (rule->r_time); + } + } + return len; +} + +static int is_extended_name (const char *name) +{ + int i; + for (i=0; name [i]; i++) { + if (isdigit (name [i]) || name [i] == '+' || name [i] == '-') { + return 1; + } + } + return 0; +} + +/* + * Get length of timezone string resulting from serializing tzo. + */ +static size_t len_tz_r (const struct tzoffset_info *tzo) +{ + size_t len = 0; + if (tzo->stdname == NULL) { + return 0; + } + len = strlen (tzo->stdname); + if (is_extended_name (tzo->stdname)) { + len += 2; + } + len += lensecs (tzo->stdoffset); + if (tzo->dstname) { + len += strlen (tzo->dstname); + if (is_extended_name (tzo->dstname)) { + len += 2; + } + if (tzo->dstoffset - tzo->stdoffset != -3600) { + len += lensecs (tzo->dstoffset); + } + len += 2; /* commas */ + len += lenrule (&tzo->start); + len += lenrule (&tzo->end); + } + return len; +} + +size_t len_tz (void) +{ + return len_tz_r (&localtime_tzoffset); +} + +void appendsecs (char *buf, long minutes) +{ + char *p = buf + strlen (buf); + long min = abs (minutes); + if (minutes < 0) { + *p++ = '-'; + } + if (min % 3600 == 0) { + sprintf (p, "%ld", min / 3600); + } else if (min % 60 == 0) { + sprintf (p, "%ld:%ld", min / 3600, (min / 60) % 60); + } else { + sprintf (p, "%ld:%ld:%ld", min / 3600, (min / 60) % 60, min % 60); + } +} + +void appendrule (char *buf, const struct tzrule *rule) +{ + char *p = buf + strlen (buf); + if (rule->r_type == JULIAN_DAY) { + sprintf (p, "J%d", rule->r_day); + } else if (rule->r_type == DAY_OF_YEAR) { + sprintf (p, "%d", rule->r_day); + } else if (rule->r_type == MONTH_NTH_DAY_OF_WEEK) { + sprintf (p, "M%d.%d.%d", rule->r_mon, rule->r_week, rule->r_day); + p = buf + strlen (buf); + if (rule->r_time != 7200) { + *p++ = '/'; + *p = '\0'; + appendsecs (p, rule->r_time); + } + } +} + +const char *get_tz (char *buf, size_t buflen) +{ + const struct tzoffset_info *tzo = &localtime_tzoffset; + + if (tzo->stdname == NULL || len_tz_r (tzo) > buflen) { + return NULL; + } + if (is_extended_name (tzo->stdname)) { + sprintf (buf, "<%s>", tzo->stdname); + } else { + strcpy (buf, tzo->stdname); + } + appendsecs (buf, tzo->stdoffset); + if (tzo->dstname != NULL) { + if (is_extended_name (tzo->dstname)) { + sprintf (buf + strlen (buf), "<%s>", tzo->dstname); + } else { + strcat (buf, tzo->dstname); + } + if (tzo->dstoffset - tzo->stdoffset != -3600) { + appendsecs (buf, tzo->dstoffset); + } + strcat (buf, ","); + appendrule (buf, &tzo->start); + strcat (buf, ","); + appendrule (buf, &tzo->end); + } + return buf; +} + + /** @} */ diff --git a/apps/time/time.h b/apps/time/time.h deleted file mode 100644 index 2ff4a383c..000000000 --- a/apps/time/time.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * \defgroup Time related functions - * - * This rolls the necessary definition for getting/setting time and - * managing local time into one include file, on posix systems this - * lives in at least two include files, time.h and sys/time.h - * - * @{ - */ - -/** - * \file - * Definitions for the time module - * - * \author - * Ralf Schlatterbeck - */ - -#ifndef time_h -#define time_h - - -typedef signed long long time_t; -typedef signed long suseconds_t; - -#ifdef __cplusplus -extern "C" { -#endif - -struct tm { - uint32_t tm_year; /* year */ - uint16_t tm_yday; /* day in the year */ - uint8_t tm_sec; /* seconds */ - uint8_t tm_min; /* minutes */ - uint8_t tm_hour; /* hours */ - uint8_t tm_mday; /* day of the month */ - uint8_t tm_mon; /* month */ - uint8_t tm_wday; /* day of the week */ - uint8_t tm_isdst; /* daylight saving time */ -}; - -struct timeval { - time_t tv_sec; /* seconds */ - suseconds_t tv_usec; /* microseconds */ -}; - -struct timezone { - int16_t tz_minuteswest; /* minutes west of Greenwich */ - int tz_dsttime; /* type of DST correction, unused */ -}; - -struct tm *gmtime (const time_t *timep); -struct tm *gmtime_r (const time_t *timep, struct tm *result); -struct tm *localtime (const time_t *timep); -struct tm *localtime_r (const time_t *timep, struct tm *result); - -int gettimeofday (struct timeval *tv, struct timezone *tz); -int settimeofday (const struct timeval *tv, const struct timezone *tz); - -#ifdef __cplusplus -} -#endif - -#endif // time_h -/** @} */ diff --git a/apps/time/time_resource.h b/apps/time/time_resource.h index 84a970021..078f18963 100644 --- a/apps/time/time_resource.h +++ b/apps/time/time_resource.h @@ -16,12 +16,17 @@ #ifndef time_resource_h #define time_resource_h +#include #include "contiki.h" -#include "erbium.h" +#include "rest-engine.h" -extern resource_t resource_timestamp; -extern resource_t resource_localtime; -extern resource_t resource_utc; +extern resource_t res_timestamp; +extern resource_t res_timezone; +extern resource_t res_crontab; +extern resource_t res_localtime; +extern resource_t res_utc; + +extern void activate_cron_resources (void); #endif // time_resource_h /** @} */ diff --git a/apps/time/tzparse.h b/apps/time/tzparse.h new file mode 100644 index 000000000..104eeb2af --- /dev/null +++ b/apps/time/tzparse.h @@ -0,0 +1,56 @@ +/* + * Timezone parsing + */ + +/** + * \file + * Definitions for timezone parsing + * + * \author + * Ralf Schlatterbeck + */ + +#ifndef tzparse_h +#define tzparse_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Rule for DST switching + */ +struct tzrule { + int r_type; /* type of rule--see below */ + int r_day; /* day number of rule */ + int r_week; /* week number of rule */ + int r_mon; /* month number of rule */ + long r_time; /* transition time of rule */ +}; + +#define JULIAN_DAY 0 /* Jn - Julian day */ +#define DAY_OF_YEAR 1 /* n - day of year */ +#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */ + +/* + * Info about timezone offset handling. + * We get at least a dstname and stdoffset, if no daylight saving is in + * effect, dstname is NULL and no rule is filled in. + */ +struct tzoffset_info { + const char *stdname; + const char *dstname; + long stdoffset; + long dstoffset; + struct tzrule start; + struct tzrule end; + char namebuf [TZ_MAX_CHARS]; +}; + +int tzparse (const char *name, struct tzoffset_info *tzo); + +#ifdef __cplusplus +} +#endif + +#endif // tzparse_h diff --git a/apps/time/xtime.h b/apps/time/xtime.h new file mode 100644 index 000000000..8dcd78e5f --- /dev/null +++ b/apps/time/xtime.h @@ -0,0 +1,94 @@ +/** + * \defgroup Time related functions + * + * This rolls the necessary definition for getting/setting time and + * managing local time into one include file, on posix systems this + * lives in at least two include files, time.h and sys/time.h + * + * @{ + */ + +/** + * \file + * Definitions for the time module + * + * \author + * Ralf Schlatterbeck + */ + +#ifndef xtime_h +#define xtime_h + +/* This is a time.h implementation but to avoid name-clashes with libs + * trying to be helpfull we add the prefix x + */ + +#ifdef LOCAL_COMPILE +#define clock_seconds() 1 +#define clock_time() 1 +#endif + +#define DEFAULT_TIMEZONE "CET-1CEST,M3.5.0,M10.5.0/3" + +typedef signed long long xtime_t; +typedef signed long suseconds_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/* tm_gmtoff and tm_zone are BSD additions */ +struct xtm { + uint32_t tm_year; /* year */ + uint16_t tm_yday; /* day in the year */ + uint8_t tm_sec; /* seconds */ + uint8_t tm_min; /* minutes */ + uint8_t tm_hour; /* hours */ + uint8_t tm_mday; /* day of the month */ + uint8_t tm_mon; /* month */ + uint8_t tm_wday; /* day of the week */ + uint8_t tm_isdst; /* daylight saving time */ + int32_t tm_gmtoff; /* Seconds east of UTC */ + const char *tm_zone; /* Timezone abbreviation */ +}; + +struct xtimeval { + xtime_t tv_sec; /* seconds */ + suseconds_t tv_usec; /* microseconds */ +}; + +struct timezone { + int16_t tz_minuteswest; /* minutes west of Greenwich */ + int tz_dsttime; /* type of DST correction, unused */ +}; + +struct xtm *xgmtime (const xtime_t *timep); +struct xtm *xgmtime_r (const xtime_t *timep, struct xtm *result); +struct xtm *xlocaltime (const xtime_t *timep); +struct xtm *xlocaltime_r (const xtime_t *timep, struct xtm *result); + +int xgettimeofday (struct xtimeval *tv, struct timezone *tz); +int xsettimeofday (const struct xtimeval *tv, const struct timezone *tz); + +/* + * Maximum length of all timezone names, this is much longer in UNIX + * implementations but we have limited space here. Note that the length + * includes a trailing \0 byte for each timezone name. + */ +#ifndef TZ_MAX_CHARS +#define TZ_MAX_CHARS 16 +#endif + +/* Maximum length of buffer to reserve for timezone string */ +#define MAXTZLEN (TZ_MAX_CHARS+9+2*(2+6+1+8)+1) + +int set_tz (const char *tzstring); +const char *get_tz (char *buffer, size_t buflen); +size_t len_tz (void); + +#ifdef __cplusplus +} +#endif + +#endif // xtime_h +/** @} */ diff --git a/apps/webbrowser/html-strings b/apps/webbrowser/html-strings index e56d8f600..e319dc651 100644 --- a/apps/webbrowser/html-strings +++ b/apps/webbrowser/html-strings @@ -9,7 +9,6 @@ html_a "a\0" html_body "body\0" html_br "br\0" html_form "form\0" -html_frame "frame\0" html_h1 "h1\0" html_h2 "h2\0" html_h3 "h3\0" diff --git a/apps/webbrowser/html-strings.c b/apps/webbrowser/html-strings.c index 51fc3f1cd..5743f1a03 100644 --- a/apps/webbrowser/html-strings.c +++ b/apps/webbrowser/html-strings.c @@ -31,9 +31,6 @@ const char html_br[4] = const char html_form[6] = /* "form\0" */ {0x66, 0x6f, 0x72, 0x6d, 00, }; -const char html_frame[7] = -/* "frame\0" */ -{0x66, 0x72, 0x61, 0x6d, 0x65, 00, }; const char html_h1[4] = /* "h1\0" */ {0x68, 0x31, 00, }; diff --git a/apps/webbrowser/html-strings.h b/apps/webbrowser/html-strings.h index cf09c0107..5bcf03978 100644 --- a/apps/webbrowser/html-strings.h +++ b/apps/webbrowser/html-strings.h @@ -9,7 +9,6 @@ extern const char html_a[3]; extern const char html_body[6]; extern const char html_br[4]; extern const char html_form[6]; -extern const char html_frame[7]; extern const char html_h1[4]; extern const char html_h2[4]; extern const char html_h3[4]; diff --git a/apps/webbrowser/htmlparser.c b/apps/webbrowser/htmlparser.c index 725aae433..b0d8cfdc3 100644 --- a/apps/webbrowser/htmlparser.c +++ b/apps/webbrowser/htmlparser.c @@ -119,9 +119,6 @@ G * (
,

, ), the

  • tag (but does not even try to #define ISO_eq 0x3d #define ISO_gt 0x3e -#define ISO_rbrack 0x5b -#define ISO_lbrack 0x5d - #define MINORSTATE_NONE 0 #define MINORSTATE_TEXT 1 /* Parse normal text */ #define MINORSTATE_EXTCHAR 2 /* Check for semi-colon */ @@ -140,7 +137,7 @@ G * (
    ,

    , ), the

  • tag (but does not even try to #define MAJORSTATE_LINK 2 #define MAJORSTATE_FORM 3 #define MAJORSTATE_DISCARD 4 - +#define MAJORSTATE_SCRIPT 5 struct htmlparser_state { @@ -151,7 +148,7 @@ struct htmlparser_state { unsigned char tagattrptr; char tagattrparam[WWW_CONF_MAX_URLLEN + 1]; unsigned char tagattrparamptr; - unsigned char lastchar, quotechar; + unsigned char quotechar; unsigned char majorstate, lastmajorstate; char linkurl[WWW_CONF_MAX_URLLEN + 1]; @@ -196,38 +193,36 @@ static const char *tags[] = { html_br, #define TAG_FORM 10 html_form, -#define TAG_FRAME 11 - html_frame, -#define TAG_H1 12 +#define TAG_H1 11 html_h1, -#define TAG_H2 13 +#define TAG_H2 12 html_h2, -#define TAG_H3 14 +#define TAG_H3 13 html_h3, -#define TAG_H4 15 +#define TAG_H4 14 html_h4, -#define TAG_IMG 16 +#define TAG_IMG 15 html_img, -#define TAG_INPUT 17 +#define TAG_INPUT 16 html_input, -#define TAG_LI 18 +#define TAG_LI 17 html_li, -#define TAG_P 19 +#define TAG_P 18 html_p, -#define TAG_SCRIPT 20 +#define TAG_SCRIPT 19 html_script, -#define TAG_SELECT 21 +#define TAG_SELECT 20 html_select, -#define TAG_STYLE 22 +#define TAG_STYLE 21 html_style, -#define TAG_TR 23 +#define TAG_TR 22 html_tr, -#define TAG_LAST 24 +#define TAG_LAST 23 last, }; /*-----------------------------------------------------------------------------------*/ -static unsigned char CC_FASTCALL +static unsigned char iswhitespace(char c) { return (c == ISO_space || @@ -254,13 +249,13 @@ htmlparser_init(void) { s.majorstate = s.lastmajorstate = MAJORSTATE_DISCARD; s.minorstate = MINORSTATE_TEXT; - s.lastchar = 0; + s.wordlen = 0; #if WWW_CONF_FORMS s.formaction[0] = 0; #endif /* WWW_CONF_FORMS */ } /*-----------------------------------------------------------------------------------*/ -static char CC_FASTCALL +static char lowercase(char c) { /* XXX: This is a *brute force* approach to lower-case @@ -281,7 +276,7 @@ endtagfound(void) s.tagattrparam[s.tagattrparamptr] = 0; } /*-----------------------------------------------------------------------------------*/ -static void CC_FASTCALL +static void switch_majorstate(unsigned char newstate) { if(s.majorstate != newstate) { @@ -291,7 +286,7 @@ switch_majorstate(unsigned char newstate) } } /*-----------------------------------------------------------------------------------*/ -static void CC_FASTCALL +static void add_char(unsigned char c) { if(s.wordlen < WWW_CONF_WEBPAGE_WIDTH - 1 && c < 0x80) { @@ -305,10 +300,10 @@ do_word(void) { if(s.wordlen > 0) { if(s.majorstate == MAJORSTATE_LINK) { - if(s.word[s.wordlen] != ISO_space) { + if(s.word[s.wordlen - 1] != ISO_space) { add_char(ISO_space); } - } else if(s.majorstate == MAJORSTATE_DISCARD) { + } else if(s.majorstate >= MAJORSTATE_DISCARD) { s.wordlen = 0; } else { s.word[s.wordlen] = '\0'; @@ -325,7 +320,7 @@ newline(void) htmlparser_newline(); } /*-----------------------------------------------------------------------------------*/ -static unsigned char CC_FASTCALL +static unsigned char find_tag(char *tag) { static unsigned char first, last, i, tabi; @@ -368,13 +363,19 @@ static void parse_tag(void) { static char *tagattrparam; + static unsigned char tag; static unsigned char size; - static char dummy; - + tag = find_tag(s.tag); + /* If we are inside a . */ + if(s.majorstate == MAJORSTATE_SCRIPT && tag != TAG_SLASHSCRIPT) { + return; + } + PRINTF(("Parsing tag '%s' '%s' '%s'\n", s.tag, s.tagattr, s.tagattrparam)); - switch(find_tag(s.tag)) { + switch(tag) { case TAG_P: case TAG_H1: case TAG_H2: @@ -386,15 +387,18 @@ parse_tag(void) case TAG_TR: case TAG_SLASHDIV: case TAG_SLASHH: - dummy = 0; newline(); break; case TAG_LI: - newline(); - add_char(ISO_asterisk); - add_char(ISO_space); + if(s.tagattr[0] == 0) { + newline(); + add_char(ISO_asterisk); + add_char(ISO_space); + } break; case TAG_SCRIPT: + switch_majorstate(MAJORSTATE_SCRIPT); + break; case TAG_STYLE: case TAG_SELECT: switch_majorstate(MAJORSTATE_DISCARD); @@ -408,18 +412,6 @@ parse_tag(void) case TAG_BODY: s.majorstate = s.lastmajorstate = MAJORSTATE_BODY; break; - case TAG_FRAME: - if(strncmp(s.tagattr, html_src, sizeof(html_src)) == 0 && s.tagattrparam[0] != 0) { - switch_majorstate(MAJORSTATE_BODY); - newline(); - add_char(ISO_rbrack); - do_word(); - htmlparser_link((char *)html_frame, (unsigned char)strlen(html_frame), s.tagattrparam); - PRINTF(("Frame [%s]\n", s.tagattrparam)); - add_char(ISO_lbrack); - newline(); - } - break; case TAG_IMG: if(strncmp(s.tagattr, html_alt, sizeof(html_alt)) == 0 && s.tagattrparam[0] != 0) { add_char(ISO_lt); @@ -529,7 +521,7 @@ parse_tag(void) } } /*-----------------------------------------------------------------------------------*/ -static uint16_t CC_FASTCALL +static uint16_t parse_word(char *data, uint8_t dlen) { static uint8_t i; @@ -572,6 +564,15 @@ parse_word(char *data, uint8_t dlen) } break; case MINORSTATE_TAG: + /* If we are inside a we mustn't mistake a JavaScript + equation with a '<' as a tag. So we check for the very next + character to be a '/' as we're only interested in parsing + the . */ + if(s.majorstate == MAJORSTATE_SCRIPT && data[0] != ISO_slash) { + s.minorstate = MINORSTATE_TEXT; + break; + } + /* We are currently parsing within the name of a tag. We check for the end of a tag (the '>' character) or whitespace (which indicates that we should parse a tag attr argument diff --git a/apps/webbrowser/http-strings b/apps/webbrowser/http-strings index 24ddb4f90..ff6a87545 100644 --- a/apps/webbrowser/http-strings +++ b/apps/webbrowser/http-strings @@ -1,4 +1,5 @@ http_http "http://" +http_https "https://" http_200 "200 " http_301 "301 " http_302 "302 " @@ -10,3 +11,4 @@ http_location "location: " http_host "Host: " http_crnl "\r\n" http_html ".html" +http_redirect "Redirect to " diff --git a/apps/webbrowser/http-strings.c b/apps/webbrowser/http-strings.c index aa4d45ece..72ce2c644 100644 --- a/apps/webbrowser/http-strings.c +++ b/apps/webbrowser/http-strings.c @@ -1,6 +1,9 @@ const char http_http[8] = /* "http://" */ {0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, }; +const char http_https[9] = +/* "https://" */ +{0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, }; const char http_200[5] = /* "200 " */ {0x32, 0x30, 0x30, 0x20, }; @@ -34,3 +37,6 @@ const char http_crnl[3] = const char http_html[6] = /* ".html" */ {0x2e, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_redirect[19] = +/* "Redirect to " */ +{0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, }; diff --git a/apps/webbrowser/http-strings.h b/apps/webbrowser/http-strings.h index 8b9bee66e..184dcf330 100644 --- a/apps/webbrowser/http-strings.h +++ b/apps/webbrowser/http-strings.h @@ -1,4 +1,5 @@ extern const char http_http[8]; +extern const char http_https[9]; extern const char http_200[5]; extern const char http_301[5]; extern const char http_302[5]; @@ -10,3 +11,4 @@ extern const char http_location[11]; extern const char http_host[7]; extern const char http_crnl[3]; extern const char http_html[6]; +extern const char http_redirect[19]; diff --git a/apps/webbrowser/webclient.c b/apps/webbrowser/webclient.c index 08c6ed211..b4487ca26 100644 --- a/apps/webbrowser/webclient.c +++ b/apps/webbrowser/webclient.c @@ -49,7 +49,7 @@ #define HTTPFLAG_NONE 0 #define HTTPFLAG_OK 1 #define HTTPFLAG_MOVED 2 -#define HTTPFLAG_ERROR 3 +#define HTTPFLAG_HTTPS 3 #define ISO_nl 0x0a @@ -63,11 +63,11 @@ struct webclient_state { uint16_t port; char host[40]; - char file[WWW_CONF_MAX_URLLEN]; + char file[WWW_CONF_MAX_URLLEN - 10]; // URL - "http:///" uint16_t getrequestptr; uint16_t getrequestleft; - char httpheaderline[200]; + char httpheaderline[WWW_CONF_MAX_URLLEN + 10]; // URL + "Location: " uint16_t httpheaderlineptr; char mimetype[32]; @@ -200,7 +200,7 @@ window_copy(int curptr, const char *data, unsigned char datalen) len = windowend - windowstart; } - strncpy(windowptr + windowstart, data, len); + strncpy((char *)(windowptr + windowstart), data, len); windowstart += len; return curptr + datalen; @@ -217,7 +217,7 @@ senddata(void) windowstart = s.getrequestptr; curptr = 0; windowend = windowstart + uip_mss(); - windowptr = (char *)uip_appdata - windowstart; + windowptr = (unsigned char *)uip_appdata - windowstart; curptr = window_copy(curptr, http_get, sizeof(http_get) - 1); curptr = window_copy(curptr, s.file, (unsigned char)strlen(s.file)); @@ -327,13 +327,12 @@ parse_headers(uint16_t len) char *cptr; static unsigned char i; - while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) { + while(len > 0) { s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata; uip_appdata = (char *)uip_appdata + 1; --len; if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) { - /* We have an entire HTTP header line in s.httpheaderline, so - we parse it. */ + /* We reached the end of an HTTP header line. */ if(s.httpheaderline[0] == ISO_cr) { /* This was the last header line (i.e., and empty "\r\n"), so we are done with the headers and proceed with the actual @@ -342,46 +341,53 @@ parse_headers(uint16_t len) return len; } - s.httpheaderline[s.httpheaderlineptr - 1] = 0; - /* Check for specific HTTP header fields. */ - if(casecmp(s.httpheaderline, http_content_type, - sizeof(http_content_type) - 1) == 0) { - /* Found Content-type field. */ - cptr = strchr(s.httpheaderline, ';'); - if(cptr != NULL) { - *cptr = 0; - } - strncpy(s.mimetype, s.httpheaderline + - sizeof(http_content_type) - 1, sizeof(s.mimetype)); - } else if(casecmp(s.httpheaderline, http_location, - sizeof(http_location) - 1) == 0) { - cptr = s.httpheaderline + - sizeof(http_location) - 1; - - if(strncmp(cptr, http_http, 7) == 0) { - cptr += 7; - for(i = 0; i < s.httpheaderlineptr - 7; ++i) { - if(*cptr == 0 || - *cptr == '/' || - *cptr == ' ' || - *cptr == ':') { - s.host[i] = 0; - break; - } - s.host[i] = *cptr; - ++cptr; + if(s.httpheaderlineptr < sizeof(s.httpheaderline) - 1) { + /* We have an entire HTTP header line in s.httpheaderline, so + we parse it. */ + s.httpheaderline[s.httpheaderlineptr - 1] = 0; + /* Check for specific HTTP header fields. */ + if(casecmp(s.httpheaderline, http_content_type, + sizeof(http_content_type) - 1) == 0) { + /* Found Content-type field. */ + cptr = strchr(s.httpheaderline, ';'); + if(cptr != NULL) { + *cptr = 0; } - } - strncpy(s.file, cptr, sizeof(s.file)); - /* s.file[s.httpheaderlineptr - i] = 0;*/ - } + strncpy(s.mimetype, s.httpheaderline + + sizeof(http_content_type) - 1, sizeof(s.mimetype)); + } else if(casecmp(s.httpheaderline, http_location, + sizeof(http_location) - 1) == 0) { + cptr = s.httpheaderline + + sizeof(http_location) - 1; + if(strncmp(cptr, http_https, sizeof(http_https) - 1) == 0) { + s.httpflag = HTTPFLAG_HTTPS; + } else if(strncmp(cptr, http_http, 7) == 0) { + cptr += 7; + for(i = 0; i < s.httpheaderlineptr - 7; ++i) { + if(*cptr == 0 || + *cptr == '/' || + *cptr == ' ' || + *cptr == ':') { + s.host[i] = 0; + break; + } + s.host[i] = *cptr; + ++cptr; + } + } + strncpy(s.file, cptr, sizeof(s.file)); + /* s.file[s.httpheaderlineptr - i] = 0;*/ + } + } /* We're done parsing, so we reset the pointer and start the next line. */ s.httpheaderlineptr = 0; } else { - ++s.httpheaderlineptr; + if(s.httpheaderlineptr < sizeof(s.httpheaderline) - 1) { + ++s.httpheaderlineptr; + } } } return len; @@ -403,7 +409,7 @@ newdata(void) } if(len > 0 && s.state == WEBCLIENT_STATE_DATA && - s.httpflag != HTTPFLAG_MOVED) { + s.httpflag == HTTPFLAG_OK) { webclient_datahandler((char *)uip_appdata, len); } } @@ -441,7 +447,6 @@ webclient_appcall(void *state) return; } - /* The acked() and newdata() functions may alter the uip_appdata ptr, so we need to store it in the "dataptr" variable so that we can restore it before the senddata() function is called. */ @@ -474,10 +479,23 @@ webclient_appcall(void *state) if(uip_closed()) { tcp_markconn(uip_conn, NULL); - if(s.httpflag != HTTPFLAG_MOVED) { + /* Client requested close takes precedence over server initiated close. */ + if(s.state == WEBCLIENT_STATE_CLOSE) { + webclient_closed(); + return; + } + switch(s.httpflag) { + case HTTPFLAG_HTTPS: + /* Send some info to the user. */ + webclient_datahandler((char *)http_redirect, sizeof(http_redirect) - 1); + webclient_datahandler(s.file, strlen(s.file)); + webclient_datahandler((char *)http_crnl, sizeof(http_crnl) - 1); + /* FALLTHROUGH */ + case HTTPFLAG_OK: /* Send NULL data to signal EOF. */ webclient_datahandler(NULL, 0); - } else { + break; + case HTTPFLAG_MOVED: /* conn = uip_connect(uip_conn->ripaddr, s.port); if(conn != NULL) { dispatcher_markconn(conn, NULL); @@ -489,6 +507,7 @@ webclient_appcall(void *state) } #endif /* UIP_UDP */ webclient_get(s.host, s.port, s.file); + break; } } } diff --git a/apps/webbrowser/www.c b/apps/webbrowser/www.c index 8e1331c75..f72dfcbfe 100644 --- a/apps/webbrowser/www.c +++ b/apps/webbrowser/www.c @@ -34,12 +34,14 @@ #include #include +#include #include "ctk/ctk.h" #include "ctk/ctk-textentry-cmdline.h" #include "contiki-net.h" #include "lib/petsciiconv.h" #include "sys/arg.h" +#include "sys/log.h" #if WWW_CONF_WITH_WGET #include "program-handler.h" #endif /* WWW_CONF_WITH_WGET */ @@ -50,13 +52,8 @@ #include "www.h" -#if 1 -#define PRINTF(x) -#else -#include -#define PRINTF(x) printf x -#endif - +/* Explicitly declare itoa as it is non-standard and not necessarily in stdlib.h */ +char *itoa(int value, char *str, int base); /* The array that holds the current URL. */ static char url[WWW_CONF_MAX_URLLEN + 1]; @@ -125,7 +122,7 @@ static struct ctk_button wgetyesbutton = #if WWW_CONF_HISTORY_SIZE > 0 /* The char arrays that hold the history of visited URLs. */ static char history[WWW_CONF_HISTORY_SIZE][WWW_CONF_MAX_URLLEN]; -static char history_last; +static unsigned char history_last; #endif /* WWW_CONF_HISTORY_SIZE > 0 */ struct linkattrib { @@ -170,17 +167,19 @@ static struct inputattrib *currptr; #define ISO_nl 0x0a #define ISO_space 0x20 +#define ISO_hash 0x23 #define ISO_ampersand 0x26 -#define ISO_plus 0x2b +#define ISO_plus 0x2b #define ISO_slash 0x2f #define ISO_eq 0x3d -#define ISO_questionmark 0x3f +#define ISO_questionmark 0x3f /* The state of the rendering code. */ static char *webpageptr; static unsigned char x, y; static unsigned char loading; static unsigned short firsty, pagey; +static unsigned char newlines; static unsigned char count; static char receivingmsgs[4][23] = { @@ -194,7 +193,7 @@ PROCESS(www_process, "Web browser"); AUTOSTART_PROCESSES(&www_process); -static void CC_FASTCALL formsubmit(struct formattrib *form); +static void formsubmit(struct inputattrib *trigger); /*-----------------------------------------------------------------------------------*/ /* make_window() @@ -230,7 +229,7 @@ redraw_window(void) ctk_window_redraw(&mainwindow); } /*-----------------------------------------------------------------------------------*/ -static char * CC_FASTCALL +static char * add_pageattrib(unsigned size) { char *ptr; @@ -244,7 +243,7 @@ add_pageattrib(unsigned size) } /*-----------------------------------------------------------------------------------*/ #if WWW_CONF_FORMS -static void CC_FASTCALL +static void add_forminput(struct inputattrib *inputptr) { inputptr->nextptr = NULL; @@ -277,18 +276,30 @@ start_loading(void) loading = 1; x = y = 0; pagey = 0; + newlines = 0; webpageptr = webpage; clear_page(); } /*-----------------------------------------------------------------------------------*/ -static void CC_FASTCALL +static void show_statustext(char *text) { ctk_label_set_text(&statustext, text); CTK_WIDGET_REDRAW(&statustext); } /*-----------------------------------------------------------------------------------*/ +static void +end_page(char *status, void *focus) +{ + show_statustext(status); + petsciiconv_topetscii(webpageptr - x, x); + CTK_WIDGET_FOCUS(&mainwindow, focus); + redraw_window(); + log_message("Page attribs free: ", itoa(pageattribs + sizeof(pageattribs) - pageattribptr, + pageattribs + sizeof(pageattribs) - 5, 10)); +} +/*-----------------------------------------------------------------------------------*/ /* open_url(): * * Called when the URL present in the global "url" variable should be @@ -305,10 +316,13 @@ open_url(void) static uip_ipaddr_t addr; /* Trim off any spaces in the end of the url. */ - urlptr = url + strlen(url) - 1; - while(*urlptr == ' ' && urlptr > url) { - *urlptr = 0; - --urlptr; + urlptr = url + strlen(url); + while(urlptr > url) { + if(*(urlptr - 1) == ' ') { + *--urlptr = 0; + } else { + break; + } } /* Don't even try to go further if the URL is empty. */ @@ -376,7 +390,6 @@ open_url(void) } else { show_statustext("Connecting..."); } - redraw_window(); } /*-----------------------------------------------------------------------------------*/ /* set_link(link): @@ -384,7 +397,7 @@ open_url(void) * Will format a link from the current web pages so that it suits the * open_url() function. */ -static void CC_FASTCALL +static void set_link(char *link) { register char *urlptr; @@ -510,15 +523,17 @@ PROCESS_THREAD(www_process, ev, data) firsty = 0; start_loading(); --history_last; + /* Note: history_last is unsigned ! */ if(history_last > WWW_CONF_HISTORY_SIZE) { history_last = WWW_CONF_HISTORY_SIZE - 1; } memcpy(url, history[(int)history_last], WWW_CONF_MAX_URLLEN); + *history[(int)history_last] = 0; open_url(); CTK_WIDGET_FOCUS(&mainwindow, &backbutton); #endif /* WWW_CONF_HISTORY_SIZE > 0 */ } else if(w == (struct ctk_widget *)&downbutton) { - firsty = pagey + WWW_CONF_WEBPAGE_HEIGHT - 4; + firsty = pagey + WWW_CONF_WEBPAGE_HEIGHT - 2; start_loading(); open_url(); CTK_WIDGET_FOCUS(&mainwindow, &downbutton); @@ -557,9 +572,8 @@ PROCESS_THREAD(www_process, ev, data) #if WWW_CONF_FORMS } else { /* Assume form widget. */ - struct inputattrib *input = (struct inputattrib *) - (((char *)w) - offsetof(struct inputattrib, widget)); - formsubmit(input->formptr); + formsubmit((struct inputattrib *) + (((char *)w) - offsetof(struct inputattrib, widget))); #endif /* WWW_CONF_FORMS */ } } else if(ev == ctk_signal_hyperlink_activate) { @@ -603,7 +617,7 @@ PROCESS_THREAD(www_process, ev, data) * "url" variable and the visible "editurl" (which is shown in the URL * text entry widget in the browser window). */ -static void CC_FASTCALL +static void set_url(char *host, uint16_t port, char *file) { char *urlptr; @@ -654,10 +668,7 @@ webclient_timedout(void) void webclient_closed(void) { - show_statustext("Stopped"); - petsciiconv_topetscii(webpageptr - x, x); - CTK_WIDGET_FOCUS(&mainwindow, &downbutton); - redraw_window(); + end_page("Stopped", &downbutton); } /*-----------------------------------------------------------------------------------*/ /* webclient_connected(): @@ -670,8 +681,6 @@ webclient_connected(void) { start_loading(); - clear_page(); - show_statustext("Request sent..."); set_url(webclient_hostname(), webclient_port(), webclient_filename()); @@ -706,6 +715,7 @@ webclient_datahandler(char *data, uint16_t len) " Would you like to download instead?"); CTK_WIDGET_ADD(&mainwindow, &wgetnobutton); CTK_WIDGET_ADD(&mainwindow, &wgetyesbutton); + CTK_WIDGET_FOCUS(&mainwindow, &wgetyesbutton); redraw_window(); #endif /* CTK_CONF_WINDOWS */ #endif /* WWW_CONF_WITH_WGET || WWW_CONF_WGET_EXEC */ @@ -717,20 +727,19 @@ webclient_datahandler(char *data, uint16_t len) if(data == NULL) { loading = 0; - show_statustext("Done"); - petsciiconv_topetscii(webpageptr - x, x); - CTK_WIDGET_FOCUS(&mainwindow, &urlentry); - redraw_window(); + end_page("Done", &urlentry); } } /*-----------------------------------------------------------------------------------*/ -static void CC_FASTCALL +static void add_pagewidget(char *text, unsigned char size, char *attrib, unsigned char type, unsigned char border) { char *wptr; static unsigned char maxwidth; + newlines = 0; + if(!loading) { return; } @@ -770,49 +779,50 @@ add_pagewidget(char *text, unsigned char size, char *attrib, unsigned char type, wptr[size + border] = ' '; switch(type) { - case CTK_WIDGET_HYPERLINK: { - struct linkattrib *linkptr = - (struct linkattrib *)add_pageattrib(sizeof(struct linkattrib) /* incl 1 attrib char */ + attriblen); - if(linkptr != NULL) { - CTK_HYPERLINK_NEW(&linkptr->hyperlink, x, y + 3, size, wptr, linkptr->url); - strcpy(linkptr->url, attrib); - CTK_WIDGET_SET_FLAG(&linkptr->hyperlink, CTK_WIDGET_FLAG_MONOSPACE); - CTK_WIDGET_ADD(&mainwindow, &linkptr->hyperlink); - } - break; + case CTK_WIDGET_HYPERLINK: { + struct linkattrib *linkptr = + (struct linkattrib *)add_pageattrib(sizeof(struct linkattrib) /* incl 1 attrib char */ + attriblen); + if(linkptr != NULL) { + CTK_HYPERLINK_NEW(&linkptr->hyperlink, x, y + 3, size, wptr, linkptr->url); + strcpy(linkptr->url, attrib); + CTK_WIDGET_SET_FLAG(&linkptr->hyperlink, CTK_WIDGET_FLAG_MONOSPACE); + CTK_WIDGET_ADD(&mainwindow, &linkptr->hyperlink); } + break; + } #if WWW_CONF_FORMS - case CTK_WIDGET_BUTTON: { - struct submitattrib *submitptr = - (struct submitattrib *)add_pageattrib(sizeof(struct submitattrib) /* incl 1 attrib char */ + attriblen); - if(submitptr != NULL) { - CTK_BUTTON_NEW((struct ctk_button *)&submitptr->button, x, y + 3, size, wptr); - add_forminput((struct inputattrib *)submitptr); - submitptr->formptr = formptr; - strcpy(submitptr->name, attrib); - CTK_WIDGET_SET_FLAG(&submitptr->button, CTK_WIDGET_FLAG_MONOSPACE); - CTK_WIDGET_ADD(&mainwindow, &submitptr->button); - } - break; + case CTK_WIDGET_BUTTON: { + struct submitattrib *submitptr = + (struct submitattrib *)add_pageattrib(sizeof(struct submitattrib) /* incl 1 attrib char */ + attriblen); + if(submitptr != NULL) { + CTK_BUTTON_NEW((struct ctk_button *)&submitptr->button, x, y + 3, size, wptr); + add_forminput((struct inputattrib *)submitptr); + submitptr->formptr = formptr; + strcpy(submitptr->name, attrib); + CTK_WIDGET_SET_FLAG(&submitptr->button, CTK_WIDGET_FLAG_MONOSPACE); + CTK_WIDGET_ADD(&mainwindow, &submitptr->button); } - case CTK_WIDGET_TEXTENTRY: { - struct textattrib *textptr = - (struct textattrib *)add_pageattrib(sizeof(struct textattrib) /* incl 1 attrib char */ + attriblen - + (size ? WWW_CONF_MAX_INPUTVALUELEN : strlen(text)) + 1); - if(textptr != NULL) { - CTK_TEXTENTRY_NEW((struct ctk_textentry *)&textptr->textentry, x, y + 3, size, 1, - textptr->name + attriblen + 1, WWW_CONF_MAX_INPUTVALUELEN); - add_forminput((struct inputattrib *)textptr); - textptr->formptr = formptr; - strcpy(textptr->textentry.text, text); - strcpy(textptr->name, attrib); - if(size) { - CTK_WIDGET_SET_FLAG(&textptr->textentry, CTK_WIDGET_FLAG_MONOSPACE); - CTK_WIDGET_ADD(&mainwindow, &textptr->textentry); - } + break; + } + case CTK_WIDGET_TEXTENTRY: { + struct textattrib *textptr = + (struct textattrib *)add_pageattrib(sizeof(struct textattrib) /* incl 1 attrib char */ + attriblen + + (size ? WWW_CONF_MAX_INPUTVALUELEN : strlen(text)) + 1); + if(textptr != NULL) { + CTK_TEXTENTRY_NEW((struct ctk_textentry *)&textptr->textentry, x, y + 3, size, 1, + textptr->name + attriblen + 1, WWW_CONF_MAX_INPUTVALUELEN); + add_forminput((struct inputattrib *)textptr); + textptr->formptr = formptr; + petsciiconv_topetscii(text, strlen(text)); + strcpy(textptr->textentry.text, text); + strcpy(textptr->name, attrib); + if(size) { + CTK_WIDGET_SET_FLAG(&textptr->textentry, CTK_WIDGET_FLAG_MONOSPACE); + CTK_WIDGET_ADD(&mainwindow, &textptr->textentry); } - break; } + break; + } #endif /* WWW_CONF_FORMS */ } } @@ -835,7 +845,13 @@ add_pagewidget(char *text, unsigned char size, char *attrib, unsigned char type, void htmlparser_newline(void) { +#ifdef WITH_PETSCII char *wptr; +#endif /* WITH_PETSCII */ + + if(++newlines > 2) { + return; + } if(pagey < firsty) { ++pagey; @@ -851,8 +867,10 @@ htmlparser_newline(void) ++y; x = 0; +#ifdef WITH_PETSCII wptr = webpageptr - WWW_CONF_WEBPAGE_WIDTH; petsciiconv_topetscii(wptr, WWW_CONF_WEBPAGE_WIDTH); +#endif /* WITH_PETSCII */ if(y == WWW_CONF_WEBPAGE_HEIGHT) { loading = 0; @@ -863,6 +881,8 @@ htmlparser_newline(void) void htmlparser_word(char *word, unsigned char wordlen) { + newlines = 0; + if(loading) { if(wordlen + 1 > WWW_CONF_WEBPAGE_WIDTH - x) { htmlparser_newline(); @@ -886,7 +906,12 @@ htmlparser_word(char *word, unsigned char wordlen) void htmlparser_link(char *text, unsigned char textlen, char *url) { - add_pagewidget(text, textlen, url, CTK_WIDGET_HYPERLINK, 0); + /* No link for https or fragment-only as we would't be able to handle it anyway. */ + if(url[0] == ISO_hash || strncmp(url, http_https, sizeof(http_https) - 1) == 0) { + htmlparser_word(text, textlen); + } else { + add_pagewidget(text, textlen, url, CTK_WIDGET_HYPERLINK, 0); + } } /*-----------------------------------------------------------------------------------*/ #if WWW_CONF_FORMS @@ -917,7 +942,7 @@ htmlparser_inputfield(unsigned char type, unsigned char size, char *text, char * } } /*-----------------------------------------------------------------------------------*/ -static void CC_FASTCALL +static void add_query(char delimiter, char *string) { static char *query; @@ -945,24 +970,37 @@ add_query(char delimiter, char *string) query += length; } /*-----------------------------------------------------------------------------------*/ -static void CC_FASTCALL -formsubmit(struct formattrib *form) +static void +formsubmit(struct inputattrib *trigger) { - struct inputattrib *inputptr; + struct inputattrib *input; + struct formattrib *form = trigger->formptr; char delimiter = ISO_questionmark; set_link(form->action); - for(inputptr = form->nextptr; inputptr != NULL; inputptr = inputptr->nextptr) { + /* No button pressed so prepare to look for default button. */ + if(trigger->widget.type == CTK_WIDGET_TEXTENTRY) { + trigger = NULL; + } + + for(input = form->nextptr; input != NULL; input = input->nextptr) { char *name; char *value; - if(inputptr->widget.type == CTK_WIDGET_BUTTON) { - name = ((struct submitattrib *)inputptr)->name; - value = ((struct submitattrib *)inputptr)->button.text; + if(input->widget.type == CTK_WIDGET_TEXTENTRY) { + name = ((struct textattrib *)input)->name; + value = ((struct textattrib *)input)->textentry.text; } else { - name = ((struct textattrib *)inputptr)->name; - value = ((struct textattrib *)inputptr)->textentry.text; + /* Consider first button as default button. */ + if(trigger == NULL) { + trigger = input; + } + if(input != trigger) { + continue; + } + name = ((struct submitattrib *)input)->name; + value = ((struct submitattrib *)input)->button.text; } add_query(delimiter, name); diff --git a/apps/webbrowser/www.h b/apps/webbrowser/www.h index d7ffd6fd6..2b6e5f33e 100644 --- a/apps/webbrowser/www.h +++ b/apps/webbrowser/www.h @@ -44,7 +44,7 @@ #define WWW_CONF_HISTORY_SIZE 10 #endif #ifndef WWW_CONF_MAX_URLLEN -#define WWW_CONF_MAX_URLLEN 300 +#define WWW_CONF_MAX_URLLEN 255 #endif #ifndef WWW_CONF_PAGEATTRIB_SIZE #define WWW_CONF_PAGEATTRIB_SIZE 2000 diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/index.shtml b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/index.shtml index 3a23b43ed..f2891b8f1 100644 --- a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/index.shtml +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/index.shtml @@ -1,3 +1,3 @@ -
    -%! tictac +
    +%! tictac
    \ No newline at end of file diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/ttt.shtml b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/ttt.shtml index 3a23b43ed..f2891b8f1 100644 --- a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/ttt.shtml +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/ttt.shtml @@ -1,3 +1,3 @@ -
    -%! tictac +
    +%! tictac
    \ No newline at end of file diff --git a/apps/webserver-nano/webserver-nogui.c b/apps/webserver-nano/webserver-nogui.c index fd1cf029a..9b1e1d348 100644 --- a/apps/webserver-nano/webserver-nogui.c +++ b/apps/webserver-nano/webserver-nogui.c @@ -64,7 +64,7 @@ webserver_log_file(uip_ipaddr_t *requester, char *file) { /* Print out IP address of requesting host. */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #if WEBSERVER_CONF_ADDRESSES char buf[48]; uint8_t j; @@ -78,7 +78,7 @@ webserver_log_file(uip_ipaddr_t *requester, char *file) char buf[20]; sprintf(buf, "%d.%d.%d.%d: ", requester->u8[0], requester->u8[1], requester->u8[2], requester->u8[3]); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ //log_message(buf, file); printf("%s%s\n", buf, file); } diff --git a/apps/webserver/http-strings b/apps/webserver/http-strings index 4178cae2f..07d4eac8c 100644 --- a/apps/webserver/http-strings +++ b/apps/webserver/http-strings @@ -1,4 +1,5 @@ http_http "http://" +http_https "https://" http_200 "200 " http_301 "301 " http_302 "302 " @@ -32,4 +33,4 @@ http_gif ".gif" http_jpg ".jpg" http_text ".text" http_txt ".txt" - +http_redirect "Redirect to " diff --git a/apps/webserver/http-strings.c b/apps/webserver/http-strings.c index f1c55e621..40667d24c 100644 --- a/apps/webserver/http-strings.c +++ b/apps/webserver/http-strings.c @@ -1,6 +1,9 @@ const char http_http[8] = /* "http://" */ {0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, }; +const char http_https[9] = +/* "https://" */ +{0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, }; const char http_200[5] = /* "200 " */ {0x32, 0x30, 0x30, 0x20, }; @@ -100,3 +103,6 @@ const char http_text[6] = const char http_txt[5] = /* ".txt" */ {0x2e, 0x74, 0x78, 0x74, }; +const char http_redirect[19] = +/* "Redirect to " */ +{0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, }; diff --git a/apps/webserver/http-strings.h b/apps/webserver/http-strings.h index 01fc8cd9d..58ae13be8 100644 --- a/apps/webserver/http-strings.h +++ b/apps/webserver/http-strings.h @@ -1,4 +1,5 @@ extern const char http_http[8]; +extern const char http_https[9]; extern const char http_200[5]; extern const char http_301[5]; extern const char http_302[5]; @@ -32,3 +33,4 @@ extern const char http_gif[5]; extern const char http_jpg[5]; extern const char http_text[6]; extern const char http_txt[5]; +extern const char http_redirect[19]; diff --git a/apps/webserver/httpd-cgi.c b/apps/webserver/httpd-cgi.c index 909ceb762..d0e7e9532 100644 --- a/apps/webserver/httpd-cgi.c +++ b/apps/webserver/httpd-cgi.c @@ -157,7 +157,7 @@ make_tcp_stats(void *arg) struct httpd_state *s = (struct httpd_state *)arg; conn = &uip_conns[s->u.count]; -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 char buf[48]; httpd_sprint_ip6(conn->ripaddr, buf); return snprintf((char *)uip_appdata, uip_mss(), @@ -184,7 +184,7 @@ make_tcp_stats(void *arg) conn->timer, (uip_outstanding(conn))? '*':' ', (uip_stopped(conn))? '!':' '); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ } /*---------------------------------------------------------------------------*/ static @@ -226,7 +226,7 @@ PT_THREAD(processes(struct httpd_state *s, char *ptr)) } PSOCK_END(&s->sout); } -#if WEBSERVER_CONF_STATUSPAGE && UIP_CONF_IPV6 +#if WEBSERVER_CONF_STATUSPAGE && NETSTACK_CONF_WITH_IPV6 /* These cgi's are invoked by the status.shtml page in /apps/webserver/httpd-fs. * To keep the webserver build small that 160 byte page is not present in the * default httpd-fsdata.c file. Run the PERL script /../../tools/makefsdata from the @@ -357,7 +357,7 @@ httpd_cgi_add(struct httpd_cgi_call *c) } } /*---------------------------------------------------------------------------*/ -#if WEBSERVER_CONF_STATUSPAGE && UIP_CONF_IPV6 +#if WEBSERVER_CONF_STATUSPAGE && NETSTACK_CONF_WITH_IPV6 static const char adrs_name[] HTTPD_STRING_ATTR = "addresses"; static const char nbrs_name[] HTTPD_STRING_ATTR = "neighbors"; static const char rtes_name[] HTTPD_STRING_ATTR = "routes"; @@ -365,7 +365,7 @@ static const char rtes_name[] HTTPD_STRING_ATTR = "routes"; HTTPD_CGI_CALL(file, file_name, file_stats); HTTPD_CGI_CALL(tcp, tcp_name, tcp_stats); HTTPD_CGI_CALL(proc, proc_name, processes); -#if WEBSERVER_CONF_STATUSPAGE && UIP_CONF_IPV6 +#if WEBSERVER_CONF_STATUSPAGE && NETSTACK_CONF_WITH_IPV6 HTTPD_CGI_CALL(adrs, adrs_name, addresses); HTTPD_CGI_CALL(nbrs, nbrs_name, neighbors); HTTPD_CGI_CALL(rtes, rtes_name, routes); @@ -377,7 +377,7 @@ httpd_cgi_init(void) httpd_cgi_add(&file); httpd_cgi_add(&tcp); httpd_cgi_add(&proc); -#if WEBSERVER_CONF_STATUSPAGE && UIP_CONF_IPV6 +#if WEBSERVER_CONF_STATUSPAGE && NETSTACK_CONF_WITH_IPV6 httpd_cgi_add(&adrs); httpd_cgi_add(&nbrs); httpd_cgi_add(&rtes); diff --git a/apps/webserver/httpd.c b/apps/webserver/httpd.c index d9c67e369..b307f60a9 100644 --- a/apps/webserver/httpd.c +++ b/apps/webserver/httpd.c @@ -342,7 +342,7 @@ httpd_init(void) memb_init(&conns); httpd_cgi_init(); } -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /*---------------------------------------------------------------------------*/ uint8_t httpd_sprint_ip6(uip_ip6addr_t addr, char * result) @@ -374,5 +374,5 @@ httpd_sprint_ip6(uip_ip6addr_t addr, char * result) *result=0; return (result - starting); } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /*---------------------------------------------------------------------------*/ diff --git a/apps/webserver/httpd.h b/apps/webserver/httpd.h index 05080b038..20d1ad272 100644 --- a/apps/webserver/httpd.h +++ b/apps/webserver/httpd.h @@ -59,8 +59,8 @@ struct httpd_state { void httpd_init(void); void httpd_appcall(void *state); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 uint8_t httpd_sprint_ip6(uip_ip6addr_t addr, char * result); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #endif /* HTTPD_H_ */ diff --git a/apps/webserver/urlconv.c b/apps/webserver/urlconv.c index 3d5e583df..d4f32f484 100644 --- a/apps/webserver/urlconv.c +++ b/apps/webserver/urlconv.c @@ -80,7 +80,7 @@ urlconv_tofilename(char *dest, char *source, unsigned char maxlen) *dest = ISO_slash; strncpy(dest + 1, wwwroot, wwwrootlen); len = 0; - from = source; to = dest + wwwrootlen; + from = (unsigned char *)source; to = (unsigned char *)dest + wwwrootlen; maxlen -= 2 + wwwrootlen; do { c = *(from++); @@ -139,7 +139,7 @@ urlconv_tofilename(char *dest, char *source, unsigned char maxlen) } } while(c); if(*to == ISO_slash && (len + sizeof(http_index_htm) - 3) < maxlen) { - strcpy(to, http_index_htm); // add index.htm + strcpy((char *)to, http_index_htm); // add index.htm } else { ++to; *to = 0; diff --git a/apps/webserver/webserver-nogui.c b/apps/webserver/webserver-nogui.c index ba2f5c9e5..535a46be6 100644 --- a/apps/webserver/webserver-nogui.c +++ b/apps/webserver/webserver-nogui.c @@ -67,7 +67,7 @@ webserver_log_file(uip_ipaddr_t *requester, char *file) #if LOG_CONF_ENABLED /* Print out IP address of requesting host. */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 char buf[48]; uint8_t j; j=httpd_sprint_ip6((uip_ip6addr_t)*requester, buf); @@ -76,7 +76,7 @@ webserver_log_file(uip_ipaddr_t *requester, char *file) char buf[20]; sprintf(buf, "%d.%d.%d.%d: ", requester->u8[0], requester->u8[1], requester->u8[2], requester->u8[3]); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ log_message(buf, file); #endif /* LOG_CONF_ENABLED */ diff --git a/core/cfs/cfs-coffee.c b/core/cfs/cfs-coffee.c index f4e7a26c1..9aa5726b7 100644 --- a/core/cfs/cfs-coffee.c +++ b/core/cfs/cfs-coffee.c @@ -35,12 +35,12 @@ * Coffee: A file system for a variety of storage types in * memory-constrained devices. * - * For further information, see "Enabling Large-Scale Storage in - * Sensor Networks with the Coffee File System" in the proceedings + * For further information, see "Enabling Large-Scale Storage in + * Sensor Networks with the Coffee File System" in the proceedings * of ACM/IEEE IPSN 2009. * * \author - * Nicolas Tsiftes + * Nicolas Tsiftes */ #include @@ -62,97 +62,96 @@ /* Micro logs enable modifications on storage types that do not support in-place updates. This applies primarily to flash memories. */ #ifndef COFFEE_MICRO_LOGS -#define COFFEE_MICRO_LOGS 1 +#define COFFEE_MICRO_LOGS 1 #endif -/* If the files are expected to be appended to only, this parameter +/* If the files are expected to be appended to only, this parameter can be set to save some code space. */ #ifndef COFFEE_APPEND_ONLY -#define COFFEE_APPEND_ONLY 0 +#define COFFEE_APPEND_ONLY 0 #endif #if COFFEE_MICRO_LOGS && COFFEE_APPEND_ONLY #error "Cannot have COFFEE_APPEND_ONLY set when COFFEE_MICRO_LOGS is set." #endif -/* I/O semantics can be set on file descriptors in order to optimize - file access on certain storage types. */ -#ifndef COFFEE_IO_SEMANTICS -#define COFFEE_IO_SEMANTICS 0 -#endif - /* * Prevent sectors from being erased directly after file removal. * This will level the wear across sectors better, but may lead * to longer garbage collection procedures. */ #ifndef COFFEE_EXTENDED_WEAR_LEVELLING -#define COFFEE_EXTENDED_WEAR_LEVELLING 1 +#define COFFEE_EXTENDED_WEAR_LEVELLING 1 #endif #if COFFEE_START & (COFFEE_SECTOR_SIZE - 1) #error COFFEE_START must point to the first byte in a sector. #endif -#define COFFEE_FD_FREE 0x0 -#define COFFEE_FD_READ 0x1 -#define COFFEE_FD_WRITE 0x2 -#define COFFEE_FD_APPEND 0x4 +/* File descriptor flags. */ +#define COFFEE_FD_FREE 0x0 +#define COFFEE_FD_READ 0x1 +#define COFFEE_FD_WRITE 0x2 +#define COFFEE_FD_APPEND 0x4 -#define COFFEE_FILE_MODIFIED 0x1 +/* File object flags. */ +#define COFFEE_FILE_MODIFIED 0x1 -#define INVALID_PAGE ((coffee_page_t)-1) -#define UNKNOWN_OFFSET ((cfs_offset_t)-1) +/* Internal Coffee markers. */ +#define INVALID_PAGE ((coffee_page_t)-1) +#define UNKNOWN_OFFSET ((cfs_offset_t)-1) -#define REMOVE_LOG 1 -#define CLOSE_FDS 1 -#define ALLOW_GC 1 +/* File removal actions. They can have the same values because + they are passed as separate parameters. */ +#define REMOVE_LOG 1 +#define CLOSE_FDS 1 +#define ALLOW_GC 1 /* "Greedy" garbage collection erases as many sectors as possible. */ -#define GC_GREEDY 0 +#define GC_GREEDY 0 /* "Reluctant" garbage collection stops after erasing one sector. */ -#define GC_RELUCTANT 1 +#define GC_RELUCTANT 1 /* File descriptor macros. */ -#define FD_VALID(fd) \ - ((fd) >= 0 && (fd) < COFFEE_FD_SET_SIZE && \ - coffee_fd_set[(fd)].flags != COFFEE_FD_FREE) -#define FD_READABLE(fd) (coffee_fd_set[(fd)].flags & CFS_READ) -#define FD_WRITABLE(fd) (coffee_fd_set[(fd)].flags & CFS_WRITE) -#define FD_APPENDABLE(fd) (coffee_fd_set[(fd)].flags & CFS_APPEND) +#define FD_VALID(fd) ((fd) >= 0 && (fd) < COFFEE_FD_SET_SIZE && \ + coffee_fd_set[(fd)].flags != COFFEE_FD_FREE) +#define FD_READABLE(fd) (coffee_fd_set[(fd)].flags & CFS_READ) +#define FD_WRITABLE(fd) (coffee_fd_set[(fd)].flags & CFS_WRITE) +#define FD_APPENDABLE(fd) (coffee_fd_set[(fd)].flags & CFS_APPEND) /* File object macros. */ -#define FILE_MODIFIED(file) ((file)->flags & COFFEE_FILE_MODIFIED) -#define FILE_FREE(file) ((file)->max_pages == 0) -#define FILE_UNREFERENCED(file) ((file)->references == 0) +#define FILE_MODIFIED(file) ((file)->flags & COFFEE_FILE_MODIFIED) +#define FILE_FREE(file) ((file)->max_pages == 0) +#define FILE_UNREFERENCED(file) ((file)->references == 0) /* File header flags. */ -#define HDR_FLAG_VALID 0x1 /* Completely written header. */ -#define HDR_FLAG_ALLOCATED 0x2 /* Allocated file. */ -#define HDR_FLAG_OBSOLETE 0x4 /* File marked for GC. */ -#define HDR_FLAG_MODIFIED 0x8 /* Modified file, log exists. */ -#define HDR_FLAG_LOG 0x10 /* Log file. */ -#define HDR_FLAG_ISOLATED 0x20 /* Isolated page. */ +#define HDR_FLAG_VALID 0x01 /* Completely written header. */ +#define HDR_FLAG_ALLOCATED 0x02 /* Allocated file. */ +#define HDR_FLAG_OBSOLETE 0x04 /* File marked for GC. */ +#define HDR_FLAG_MODIFIED 0x08 /* Modified file, log exists. */ +#define HDR_FLAG_LOG 0x10 /* Log file. */ +#define HDR_FLAG_ISOLATED 0x20 /* Isolated page. */ /* File header macros. */ -#define CHECK_FLAG(hdr, flag) ((hdr).flags & (flag)) -#define HDR_VALID(hdr) CHECK_FLAG(hdr, HDR_FLAG_VALID) -#define HDR_ALLOCATED(hdr) CHECK_FLAG(hdr, HDR_FLAG_ALLOCATED) -#define HDR_FREE(hdr) !HDR_ALLOCATED(hdr) -#define HDR_LOG(hdr) CHECK_FLAG(hdr, HDR_FLAG_LOG) -#define HDR_MODIFIED(hdr) CHECK_FLAG(hdr, HDR_FLAG_MODIFIED) -#define HDR_ISOLATED(hdr) CHECK_FLAG(hdr, HDR_FLAG_ISOLATED) -#define HDR_OBSOLETE(hdr) CHECK_FLAG(hdr, HDR_FLAG_OBSOLETE) -#define HDR_ACTIVE(hdr) (HDR_ALLOCATED(hdr) && \ - !HDR_OBSOLETE(hdr) && \ - !HDR_ISOLATED(hdr)) +#define CHECK_FLAG(hdr, flag) ((hdr).flags & (flag)) +#define HDR_VALID(hdr) CHECK_FLAG(hdr, HDR_FLAG_VALID) +#define HDR_ALLOCATED(hdr) CHECK_FLAG(hdr, HDR_FLAG_ALLOCATED) +#define HDR_FREE(hdr) !HDR_ALLOCATED(hdr) +#define HDR_LOG(hdr) CHECK_FLAG(hdr, HDR_FLAG_LOG) +#define HDR_MODIFIED(hdr) CHECK_FLAG(hdr, HDR_FLAG_MODIFIED) +#define HDR_ISOLATED(hdr) CHECK_FLAG(hdr, HDR_FLAG_ISOLATED) +#define HDR_OBSOLETE(hdr) CHECK_FLAG(hdr, HDR_FLAG_OBSOLETE) +#define HDR_ACTIVE(hdr) (HDR_ALLOCATED(hdr) && \ + !HDR_OBSOLETE(hdr) && \ + !HDR_ISOLATED(hdr)) /* Shortcuts derived from the hardware-dependent configuration of Coffee. */ -#define COFFEE_SECTOR_COUNT (unsigned)(COFFEE_SIZE / COFFEE_SECTOR_SIZE) -#define COFFEE_PAGE_COUNT \ - ((coffee_page_t)(COFFEE_SIZE / COFFEE_PAGE_SIZE)) -#define COFFEE_PAGES_PER_SECTOR \ - ((coffee_page_t)(COFFEE_SECTOR_SIZE / COFFEE_PAGE_SIZE)) +#define COFFEE_SECTOR_COUNT \ + (coffee_page_t)(COFFEE_SIZE / COFFEE_SECTOR_SIZE) +#define COFFEE_PAGE_COUNT \ + ((coffee_page_t)(COFFEE_SIZE / COFFEE_PAGE_SIZE)) +#define COFFEE_PAGES_PER_SECTOR \ + ((coffee_page_t)(COFFEE_SECTOR_SIZE / COFFEE_PAGE_SIZE)) /* This structure is used for garbage collection statistics. */ struct sector_status { @@ -176,12 +175,10 @@ struct file_desc { cfs_offset_t offset; struct file *file; uint8_t flags; -#if COFFEE_IO_SEMANTICS uint8_t io_flags; -#endif }; -/* The file header structure mimics the representation of file headers +/* The file header structure mimics the representation of file headers in the physical storage medium. */ struct file_header { coffee_page_t log_page; @@ -196,26 +193,18 @@ struct file_header { /* This is needed because of a buggy compiler. */ struct log_param { cfs_offset_t offset; - const char *buf; + char *buf; uint16_t size; }; /* - * The protected memory consists of structures that should not be - * overwritten during system checkpointing because they may be used by - * the checkpointing implementation. These structures need not be - * protected if checkpointing is not used. + * Variables that keep track of opened files and internal + * optimization information for Coffee. */ -static struct protected_mem_t { - struct file coffee_files[COFFEE_MAX_OPEN_FILES]; - struct file_desc coffee_fd_set[COFFEE_FD_SET_SIZE]; - coffee_page_t next_free; - char gc_wait; -} protected_mem; -static struct file * const coffee_files = protected_mem.coffee_files; -static struct file_desc * const coffee_fd_set = protected_mem.coffee_fd_set; -static coffee_page_t * const next_free = &protected_mem.next_free; -static char * const gc_wait = &protected_mem.gc_wait; +static struct file coffee_files[COFFEE_MAX_OPEN_FILES]; +static struct file_desc coffee_fd_set[COFFEE_FD_SET_SIZE]; +static coffee_page_t next_free; +static char gc_wait; /*---------------------------------------------------------------------------*/ static void @@ -229,11 +218,9 @@ static void read_header(struct file_header *hdr, coffee_page_t page) { COFFEE_READ(hdr, sizeof(*hdr), page * COFFEE_PAGE_SIZE); -#if DEBUG - if(HDR_ACTIVE(*hdr) && !HDR_VALID(*hdr)) { - PRINTF("Invalid header at page %u!\n", (unsigned)page); + if(DEBUG && HDR_ACTIVE(*hdr) && !HDR_VALID(*hdr)) { + PRINTF("Coffee: Invalid header at page %u!\n", (unsigned)page); } -#endif } /*---------------------------------------------------------------------------*/ static cfs_offset_t @@ -243,7 +230,7 @@ absolute_offset(coffee_page_t page, cfs_offset_t offset) } /*---------------------------------------------------------------------------*/ static coffee_page_t -get_sector_status(uint16_t sector, struct sector_status *stats) +get_sector_status(coffee_page_t sector, struct sector_status *stats) { static coffee_page_t skip_pages; static char last_pages_are_active; @@ -256,8 +243,8 @@ get_sector_status(uint16_t sector, struct sector_status *stats) active = obsolete = free = 0; /* - * get_sector_status() is an iterative function using local static - * state. It therefore requires that the caller starts iterating from + * get_sector_status() is an iterative function using local static + * state. It therefore requires that the caller starts iterating from * sector 0 in order to reset the internal state. */ if(sector == 0) { @@ -269,8 +256,8 @@ get_sector_status(uint16_t sector, struct sector_status *stats) sector_end = sector_start + COFFEE_PAGES_PER_SECTOR; /* - * Account for pages belonging to a file starting in a previous - * segment that extends into this segment. If the whole segment is + * Account for pages belonging to a file starting in a previous + * segment that extends into this segment. If the whole segment is * covered, we do not need to continue counting pages in this iteration. */ if(last_pages_are_active) { @@ -289,7 +276,7 @@ get_sector_status(uint16_t sector, struct sector_status *stats) obsolete = skip_pages; } - /* Determine the amount of pages of each type that have not been + /* Determine the amount of pages of each type that have not been accounted for yet in the current sector. */ for(page = sector_start + skip_pages; page < sector_end;) { read_header(&hdr, page); @@ -312,10 +299,10 @@ get_sector_status(uint16_t sector, struct sector_status *stats) /* * Determine the amount of pages in the following sectors that - * should be remembered for the next iteration. This is necessary - * because no page except the first of a file contains information + * should be remembered for the next iteration. This is necessary + * because no file page except the first contains information * about what type of page it is. A side effect of remembering this - * amount is that there is no need to read in the headers of each + * amount is that there is no need to read in the headers of each * of these pages from the storage. */ skip_pages = active + obsolete + free - COFFEE_PAGES_PER_SECTOR; @@ -332,14 +319,14 @@ get_sector_status(uint16_t sector, struct sector_status *stats) stats->free = free; /* - * To avoid unnecessary page isolation, we notify the caller that - * "skip_pages" pages should be isolated only if the current file extent - * ends in the next sector. If the file extent ends in a more distant - * sector, however, the garbage collection can free the next sector - * immediately without requiring page isolation. + * To avoid unnecessary page isolation, we notify the caller that + * "skip_pages" pages should be isolated only if the current file extent + * ends in the next sector. If the file extent ends in a more distant + * sector, however, the garbage collection can free the next sector + * immediately without requiring page isolation. */ return (last_pages_are_active || (skip_pages >= COFFEE_PAGES_PER_SECTOR)) ? - 0 : skip_pages; + 0 : skip_pages; } /*---------------------------------------------------------------------------*/ static void @@ -359,18 +346,17 @@ isolate_pages(coffee_page_t start, coffee_page_t skip_pages) } PRINTF("Coffee: Isolated %u pages starting in sector %d\n", (unsigned)skip_pages, (int)start / COFFEE_PAGES_PER_SECTOR); - } /*---------------------------------------------------------------------------*/ static void collect_garbage(int mode) { - uint16_t sector; + coffee_page_t sector; struct sector_status stats; coffee_page_t first_page, isolation_count; - PRINTF("Coffee: Running the file system garbage collector in %s mode\n", - mode == GC_RELUCTANT ? "reluctant" : "greedy"); + PRINTF("Coffee: Running the garbage collector in %s mode\n", + mode == GC_RELUCTANT ? "reluctant" : "greedy"); /* * The garbage collector erases as many sectors as possible. A sector is * erasable if there are only free or obsolete pages in it. @@ -378,8 +364,8 @@ collect_garbage(int mode) for(sector = 0; sector < COFFEE_SECTOR_COUNT; sector++) { isolation_count = get_sector_status(sector, &stats); PRINTF("Coffee: Sector %u has %u active, %u obsolete, and %u free pages.\n", - sector, (unsigned)stats.active, - (unsigned)stats.obsolete, (unsigned)stats.free); + (unsigned)sector, (unsigned)stats.active, + (unsigned)stats.obsolete, (unsigned)stats.free); if(stats.active > 0) { continue; @@ -388,8 +374,8 @@ collect_garbage(int mode) if((mode == GC_RELUCTANT && stats.free == 0) || (mode == GC_GREEDY && stats.obsolete > 0)) { first_page = sector * COFFEE_PAGES_PER_SECTOR; - if(first_page < *next_free) { - *next_free = first_page; + if(first_page < next_free) { + next_free = first_page; } if(isolation_count > 0) { @@ -410,13 +396,13 @@ static coffee_page_t next_file(coffee_page_t page, struct file_header *hdr) { /* - * The quick-skip algorithm for finding file extents is the most - * essential part of Coffee. The file allocation rules enables this - * algorithm to quickly jump over free areas and allocated extents + * The quick-skip algorithm for finding file extents is the most + * essential part of Coffee. The file allocation rules enable this + * algorithm to quickly jump over free areas and allocated extents * after reading single headers and determining their status. * - * The worst-case performance occurs when we encounter multiple long - * sequences of isolated pages, but such sequences are uncommon and + * The worst-case performance occurs when we encounter multiple long + * sequences of isolated pages, but such sequences are uncommon and * always shorter than a sector. */ if(HDR_FREE(*hdr)) { @@ -424,7 +410,7 @@ next_file(coffee_page_t page, struct file_header *hdr) } else if(HDR_ISOLATED(*hdr)) { return page + 1; } - return page + hdr->max_pages; + return page + hdr->max_pages; } /*---------------------------------------------------------------------------*/ static struct file * @@ -459,10 +445,7 @@ load_file(coffee_page_t start, struct file_header *hdr) file->page = start; file->end = UNKNOWN_OFFSET; file->max_pages = hdr->max_pages; - file->flags = 0; - if(HDR_MODIFIED(*hdr)) { - file->flags |= COFFEE_FILE_MODIFIED; - } + file->flags = HDR_MODIFIED(*hdr) ? COFFEE_FILE_MODIFIED : 0; /* We don't know the amount of records yet. */ file->record_count = -1; @@ -475,7 +458,7 @@ find_file(const char *name) int i; struct file_header hdr; coffee_page_t page; - + /* First check if the file metadata is cached. */ for(i = 0; i < COFFEE_MAX_OPEN_FILES; i++) { if(FILE_FREE(&coffee_files[i])) { @@ -487,7 +470,7 @@ find_file(const char *name) return &coffee_files[i]; } } - + /* Scan the flash memory sequentially otherwise. */ for(page = 0; page < COFFEE_PAGE_COUNT; page = next_file(page, &hdr)) { read_header(&hdr, page); @@ -521,10 +504,10 @@ file_end(coffee_page_t start) COFFEE_READ(buf, sizeof(buf), (start + page) * COFFEE_PAGE_SIZE); for(i = COFFEE_PAGE_SIZE - 1; i >= 0; i--) { if(buf[i] != 0) { - if(page == 0 && i < sizeof(hdr)) { - return 0; - } - return 1 + i + (page * COFFEE_PAGE_SIZE) - sizeof(hdr); + if(page == 0 && i < sizeof(hdr)) { + return 0; + } + return 1 + i + (page * COFFEE_PAGE_SIZE) - sizeof(hdr); } } } @@ -540,11 +523,11 @@ find_contiguous_pages(coffee_page_t amount) struct file_header hdr; start = INVALID_PAGE; - for(page = *next_free; page < COFFEE_PAGE_COUNT;) { + for(page = next_free; page < COFFEE_PAGE_COUNT;) { read_header(&hdr, page); if(HDR_FREE(hdr)) { if(start == INVALID_PAGE) { - start = page; + start = page; if(start + amount >= COFFEE_PAGE_COUNT) { /* We can stop immediately if the remaining pages are not enough. */ break; @@ -556,10 +539,10 @@ find_contiguous_pages(coffee_page_t amount) page = next_file(page, &hdr); if(start + amount <= page) { - if(start == *next_free) { - *next_free = start + amount; - } - return start; + if(start == next_free) { + next_free = start + amount; + } + return start; } } else { start = INVALID_PAGE; @@ -570,8 +553,8 @@ find_contiguous_pages(coffee_page_t amount) } /*---------------------------------------------------------------------------*/ static int -remove_by_page(coffee_page_t page, int remove_log, int close_fds, - int gc_allowed) +remove_by_page(coffee_page_t page, int remove_log, + int close_fds, int gc_allowed) { struct file_header hdr; int i; @@ -590,13 +573,13 @@ remove_by_page(coffee_page_t page, int remove_log, int close_fds, hdr.flags |= HDR_FLAG_OBSOLETE; write_header(&hdr, page); - *gc_wait = 0; + gc_wait = 0; /* Close all file descriptors that reference the removed file. */ if(close_fds) { for(i = 0; i < COFFEE_FD_SET_SIZE; i++) { if(coffee_fd_set[i].file != NULL && coffee_fd_set[i].file->page == page) { - coffee_fd_set[i].flags = COFFEE_FD_FREE; + coffee_fd_set[i].flags = COFFEE_FD_FREE; } } } @@ -609,11 +592,9 @@ remove_by_page(coffee_page_t page, int remove_log, int close_fds, } } -#if !COFFEE_EXTENDED_WEAR_LEVELLING - if(gc_allowed) { + if(!COFFEE_EXTENDED_WEAR_LEVELLING && gc_allowed) { collect_garbage(GC_RELUCTANT); } -#endif return 0; } @@ -622,12 +603,12 @@ static coffee_page_t page_count(cfs_offset_t size) { return (size + sizeof(struct file_header) + COFFEE_PAGE_SIZE - 1) / - COFFEE_PAGE_SIZE; + COFFEE_PAGE_SIZE; } /*---------------------------------------------------------------------------*/ static struct file * reserve(const char *name, coffee_page_t pages, - int allow_duplicates, unsigned flags) + int allow_duplicates, unsigned flags) { struct file_header hdr; coffee_page_t page; @@ -639,13 +620,13 @@ reserve(const char *name, coffee_page_t pages, page = find_contiguous_pages(pages); if(page == INVALID_PAGE) { - if(*gc_wait) { + if(gc_wait) { return NULL; } collect_garbage(GC_GREEDY); page = find_contiguous_pages(pages); if(page == INVALID_PAGE) { - *gc_wait = 1; + gc_wait = 1; return NULL; } } @@ -657,7 +638,7 @@ reserve(const char *name, coffee_page_t pages, write_header(&hdr, page); PRINTF("Coffee: Reserved %u pages starting from %u for file %s\n", - pages, page, name); + (unsigned)pages, (unsigned)page, name); file = load_file(page, &hdr); if(file != NULL) { @@ -670,19 +651,19 @@ reserve(const char *name, coffee_page_t pages, #if COFFEE_MICRO_LOGS static void adjust_log_config(struct file_header *hdr, - uint16_t *log_record_size, uint16_t *log_records) + uint16_t *log_record_size, uint16_t *log_records) { *log_record_size = hdr->log_record_size == 0 ? - COFFEE_PAGE_SIZE : hdr->log_record_size; + COFFEE_PAGE_SIZE : hdr->log_record_size; *log_records = hdr->log_records == 0 ? - COFFEE_LOG_SIZE / *log_record_size : hdr->log_records; + COFFEE_LOG_SIZE / *log_record_size : hdr->log_records; } #endif /* COFFEE_MICRO_LOGS */ /*---------------------------------------------------------------------------*/ #if COFFEE_MICRO_LOGS static uint16_t modify_log_buffer(uint16_t log_record_size, - cfs_offset_t *offset, uint16_t *size) + cfs_offset_t *offset, uint16_t *size) { uint16_t region; @@ -700,7 +681,7 @@ modify_log_buffer(uint16_t log_record_size, #if COFFEE_MICRO_LOGS static int get_record_index(coffee_page_t log_page, uint16_t search_records, - uint16_t region) + uint16_t region) { cfs_offset_t base; uint16_t processed; @@ -709,30 +690,30 @@ get_record_index(coffee_page_t log_page, uint16_t search_records, base = absolute_offset(log_page, sizeof(uint16_t) * search_records); batch_size = search_records > COFFEE_LOG_TABLE_LIMIT ? - COFFEE_LOG_TABLE_LIMIT : search_records; + COFFEE_LOG_TABLE_LIMIT : search_records; processed = 0; match_index = -1; { - uint16_t indices[batch_size]; + uint16_t indices[batch_size]; - while(processed < search_records && match_index < 0) { - if(batch_size + processed > search_records) { - batch_size = search_records - processed; - } - - base -= batch_size * sizeof(indices[0]); - COFFEE_READ(&indices, sizeof(indices[0]) * batch_size, base); - - for(i = batch_size - 1; i >= 0; i--) { - if(indices[i] - 1 == region) { - match_index = search_records - processed - (batch_size - i); - break; + while(processed < search_records && match_index < 0) { + if(batch_size + processed > search_records) { + batch_size = search_records - processed; } - } - processed += batch_size; - } + base -= batch_size * sizeof(indices[0]); + COFFEE_READ(&indices, sizeof(indices[0]) * batch_size, base); + + for(i = batch_size - 1; i >= 0; i--) { + if(indices[i] - 1 == region) { + match_index = search_records - processed - (batch_size - i); + break; + } + } + + processed += batch_size; + } } return match_index; @@ -839,7 +820,7 @@ merge_log(coffee_page_t file_page, int extend) } while(n != 0); for(i = 0; i < COFFEE_FD_SET_SIZE; i++) { - if(coffee_fd_set[i].flags != COFFEE_FD_FREE && + if(coffee_fd_set[i].flags != COFFEE_FD_FREE && coffee_fd_set[i].file->page == file_page) { coffee_fd_set[i].file = new_file; new_file->references++; @@ -852,7 +833,7 @@ merge_log(coffee_page_t file_page, int extend) return -1; } - /* Copy the log configuration and the EOF hint. */ + /* Copy the log configuration. */ read_header(&hdr2, new_file->page); hdr2.log_record_size = hdr.log_record_size; hdr2.log_records = hdr.log_records; @@ -869,7 +850,7 @@ merge_log(coffee_page_t file_page, int extend) #if COFFEE_MICRO_LOGS static int find_next_record(struct file *file, coffee_page_t log_page, - int log_records) + int log_records) { int log_record, preferred_batch_size; @@ -878,7 +859,7 @@ find_next_record(struct file *file, coffee_page_t log_page, } preferred_batch_size = log_records > COFFEE_LOG_TABLE_LIMIT ? - COFFEE_LOG_TABLE_LIMIT : log_records; + COFFEE_LOG_TABLE_LIMIT : log_records; { /* The next log record is unknown at this point; search for it. */ uint16_t indices[preferred_batch_size]; @@ -888,15 +869,15 @@ find_next_record(struct file *file, coffee_page_t log_page, log_record = log_records; for(processed = 0; processed < log_records; processed += batch_size) { batch_size = log_records - processed >= preferred_batch_size ? - preferred_batch_size : log_records - processed; + preferred_batch_size : log_records - processed; COFFEE_READ(&indices, batch_size * sizeof(indices[0]), - absolute_offset(log_page, processed * sizeof(indices[0]))); + absolute_offset(log_page, processed * sizeof(indices[0]))); for(log_record = 0; log_record < batch_size; log_record++) { - if(indices[log_record] == 0) { - log_record += processed; - break; - } + if(indices[log_record] == 0) { + log_record += processed; + break; + } } } } @@ -940,7 +921,7 @@ write_log_page(struct file *file, struct log_param *lp) return -1; } PRINTF("Coffee: Created a log structure for file %s at page %u\n", - hdr.name, (unsigned)log_page); + hdr.name, (unsigned)log_page); hdr.log_page = log_page; log_record = 0; } @@ -953,9 +934,9 @@ write_log_page(struct file *file, struct log_param *lp) lp_out.size = log_record_size; if((lp->offset > 0 || lp->size != log_record_size) && - read_log_page(&hdr, log_record, &lp_out) < 0) { + read_log_page(&hdr, log_record, &lp_out) < 0) { COFFEE_READ(copy_buf, sizeof(copy_buf), - absolute_offset(file->page, offset)); + absolute_offset(file->page, offset)); } memcpy(©_buf[lp->offset], lp->buf, lp->size); @@ -967,11 +948,11 @@ write_log_page(struct file *file, struct log_param *lp) offset = absolute_offset(log_page, 0); ++region; COFFEE_WRITE(®ion, sizeof(region), - offset + log_record * sizeof(region)); + offset + log_record * sizeof(region)); offset += log_records * sizeof(region); COFFEE_WRITE(copy_buf, sizeof(copy_buf), - offset + log_record * log_record_size); + offset + log_record * log_record_size); file->record_count = log_record + 1; } @@ -1006,6 +987,7 @@ cfs_open(const char *name, int flags) fdp = &coffee_fd_set[fd]; fdp->flags = 0; + fdp->io_flags = 0; fdp->file = find_file(name); if(fdp->file == NULL) { @@ -1064,7 +1046,12 @@ cfs_seek(int fd, cfs_offset_t offset, int whence) } if(fdp->file->end < new_offset) { - fdp->file->end = new_offset; + if(FD_WRITABLE(fd)) { + fdp->file->end = new_offset; + } else { + /* Disallow seeking past the end of the file for read only FDs */ + return (cfs_offset_t)-1; + } } return fdp->offset = new_offset; @@ -1107,11 +1094,16 @@ cfs_read(int fd, void *buf, unsigned size) fdp = &coffee_fd_set[fd]; file = fdp->file; - if(fdp->offset + size > file->end) { + + if(fdp->io_flags & CFS_COFFEE_IO_ENSURE_READ_LENGTH) { + while(fdp->offset + size > file->end) { + ((char *)buf)[--size] = '\0'; + } + } else if(fdp->offset + size > file->end) { size = file->end - fdp->offset; } - /* If the file is allocated, read directly in the file. */ + /* If the file is not modified, read directly from the file extent. */ if(!FILE_MODIFIED(file)) { COFFEE_READ(buf, size, absolute_offset(file->page, fdp->offset)); fdp->offset += size; @@ -1122,12 +1114,11 @@ cfs_read(int fd, void *buf, unsigned size) read_header(&hdr, file->page); /* - * Fill the buffer by copying from the log in first hand, or the - * ordinary file if the page has no log record. + * Copy the contents of the most recent log record. If there is + * no log record for the file area to read from, we simply read + * from the original file extent. */ for(bytes_left = size; bytes_left > 0; bytes_left -= r) { - r = -1; - lp.offset = fdp->offset; lp.buf = buf; lp.size = bytes_left; @@ -1167,48 +1158,40 @@ cfs_write(int fd, const void *buf, unsigned size) file = fdp->file; /* Attempt to extend the file if we try to write past the end. */ -#if COFFEE_IO_SEMANTICS if(!(fdp->io_flags & CFS_COFFEE_IO_FIRM_SIZE)) { -#endif - while(size + fdp->offset + sizeof(struct file_header) > - (file->max_pages * COFFEE_PAGE_SIZE)) { - if(merge_log(file->page, 1) < 0) { - return -1; + while(size + fdp->offset + sizeof(struct file_header) > + (file->max_pages * COFFEE_PAGE_SIZE)) { + if(merge_log(file->page, 1) < 0) { + return -1; + } + file = fdp->file; + PRINTF("Extended the file at page %u\n", (unsigned)file->page); } - file = fdp->file; - PRINTF("Extended the file at page %u\n", (unsigned)file->page); } -#if COFFEE_IO_SEMANTICS - } -#endif #if COFFEE_MICRO_LOGS -#if COFFEE_IO_SEMANTICS if(!(fdp->io_flags & CFS_COFFEE_IO_FLASH_AWARE) && (FILE_MODIFIED(file) || fdp->offset < file->end)) { -#else - if(FILE_MODIFIED(file) || fdp->offset < file->end) { -#endif need_dummy_write = 0; for(bytes_left = size; bytes_left > 0;) { lp.offset = fdp->offset; - lp.buf = buf; + lp.buf = (void *)buf; lp.size = bytes_left; i = write_log_page(file, &lp); if(i < 0) { - /* Return -1 if we wrote nothing because the log write failed. */ - if(size == bytes_left) { - return -1; - } - break; + /* Return -1 if we wrote nothing because the log write failed. */ + if(size == bytes_left) { + return -1; + } + break; } else if(i == 0) { /* The file was merged with the log. */ - file = fdp->file; + file = fdp->file; } else { - /* A log record was written. */ - bytes_left -= i; - fdp->offset += i; - buf = (char *)buf + i; + /* A log record was written. */ + bytes_left -= i; + fdp->offset += i; + buf = (char *)buf + i; /* Update the file end for a potential log merge that might occur while writing log records. */ @@ -1230,11 +1213,9 @@ cfs_write(int fd, const void *buf, unsigned size) } } else { #endif /* COFFEE_MICRO_LOGS */ -#if COFFEE_APPEND_ONLY - if(fdp->offset < file->end) { + if(COFFEE_APPEND_ONLY && fdp->offset < file->end) { return -1; } -#endif /* COFFEE_APPEND_ONLY */ COFFEE_WRITE(buf, size, absolute_offset(file->page, fdp->offset)); fdp->offset += size; @@ -1253,10 +1234,10 @@ int cfs_opendir(struct cfs_dir *dir, const char *name) { /* - * Coffee is only guaranteed to support "/" and ".", but it does not - * currently enforce this. + * Coffee is only guaranteed to support the directory names "/" and ".", + * but it does not enforce this currently. */ - memset(dir->dummy_space, 0, sizeof(coffee_page_t)); + memset(dir->state, 0, sizeof(coffee_page_t)); return 0; } /*---------------------------------------------------------------------------*/ @@ -1265,19 +1246,19 @@ cfs_readdir(struct cfs_dir *dir, struct cfs_dirent *record) { struct file_header hdr; coffee_page_t page; + coffee_page_t next_page; - memcpy(&page, dir->dummy_space, sizeof(coffee_page_t)); + memcpy(&page, dir->state, sizeof(coffee_page_t)); while(page < COFFEE_PAGE_COUNT) { read_header(&hdr, page); if(HDR_ACTIVE(hdr) && !HDR_LOG(hdr)) { - coffee_page_t next_page; memcpy(record->name, hdr.name, sizeof(record->name)); record->name[sizeof(record->name) - 1] = '\0'; record->size = file_end(page); next_page = next_file(page, &hdr); - memcpy(dir->dummy_space, &next_page, sizeof(coffee_page_t)); + memcpy(dir->state, &next_page, sizeof(coffee_page_t)); return 0; } page = next_file(page, &hdr); @@ -1300,7 +1281,7 @@ cfs_coffee_reserve(const char *name, cfs_offset_t size) /*---------------------------------------------------------------------------*/ int cfs_coffee_configure_log(const char *filename, unsigned log_size, - unsigned log_record_size) + unsigned log_record_size) { struct file *file; struct file_header hdr; @@ -1345,11 +1326,9 @@ cfs_coffee_set_io_semantics(int fd, unsigned flags) int cfs_coffee_format(void) { - unsigned i; + coffee_page_t i; - PRINTF("Coffee: Formatting %u sectors", COFFEE_SECTOR_COUNT); - - *next_free = 0; + PRINTF("Coffee: Formatting %u sectors", (unsigned)COFFEE_SECTOR_COUNT); for(i = 0; i < COFFEE_SECTOR_COUNT; i++) { COFFEE_ERASE(i); @@ -1357,16 +1336,13 @@ cfs_coffee_format(void) } /* Formatting invalidates the file information. */ - memset(&protected_mem, 0, sizeof(protected_mem)); + memset(&coffee_files, 0, sizeof(coffee_files)); + memset(&coffee_fd_set, 0, sizeof(coffee_fd_set)); + next_free = 0; + gc_wait = 1; PRINTF(" done!\n"); return 0; } /*---------------------------------------------------------------------------*/ -void * -cfs_coffee_get_protected_mem(unsigned *size) -{ - *size = sizeof(protected_mem); - return &protected_mem; -} diff --git a/core/cfs/cfs-coffee.h b/core/cfs/cfs-coffee.h index 4e2fb52d9..96d382980 100644 --- a/core/cfs/cfs-coffee.h +++ b/core/cfs/cfs-coffee.h @@ -1,8 +1,3 @@ -/** - * \addtogroup cfs - * @{ - */ - /* * Copyright (c) 2008, Swedish Institute of Computer Science * All rights reserved. @@ -35,6 +30,11 @@ * */ +/** + * \addtogroup cfs + * @{ + */ + #ifndef CFS_COFFEE_H #define CFS_COFFEE_H @@ -46,15 +46,15 @@ * invoke its own micro logs when file modifications occur. * * This semantical I/O setting is useful when implementing flash storage - * algorithms on top of Coffee. + * algorithms such as database indices on top of Coffee. * * \sa cfs_coffee_set_io_semantics() */ #define CFS_COFFEE_IO_FLASH_AWARE 0x1 /** - * Instruct Coffee not to attempt to extend the file when there is - * an attempt to write past the reserved file size. + * Instruct Coffee not to attempt to extend the file upon a request + * to write past the reserved file size. * * A case when this is necessary is when the file has a firm size limit, * and a safeguard is needed to protect against writes beyond this limit. @@ -63,6 +63,15 @@ */ #define CFS_COFFEE_IO_FIRM_SIZE 0x2 +/** + * Instruct Coffee to set unused bytes in the destination buffer to zero. + * Trailing zeros may cause a wrong file size, this option ensures that + * the corresponding bytes get set, so Coffee does not read unexpected data. + * + * \sa cfs_coffee_set_io_semantics() + */ +#define CFS_COFFEE_IO_ENSURE_READ_LENGTH 0x4 + /** * \file * Header for the Coffee file system. @@ -75,8 +84,8 @@ /** * \brief Reserve space for a file. - * \param name The filename. - * \param size The size of the file. + * \param name The file name. + * \param size The initial size to be reserved for the file. * \return 0 on success, -1 on failure. * * Coffee uses sequential page structures for files. The sequential @@ -88,15 +97,15 @@ int cfs_coffee_reserve(const char *name, cfs_offset_t size); /** * \brief Configure the on-demand log file. - * \param file The filename. - * \param log_size The total log size. + * \param file The file name. + * \param log_size The total log file size. * \param log_entry_size The log entry size. * \return 0 on success, -1 on failure. * * When file data is first modified, Coffee creates a micro log for the - * file. The micro log stores a table of modifications whose - * parameters--the log size and the log entry size--can be modified - * through the cfs_coffee_configure_log function. + * file. The micro log stores a table of modifications whose parameters -- + * the log size and the log entry size -- can be modified through the + * cfs_coffee_configure_log function. */ int cfs_coffee_configure_log(const char *file, unsigned log_size, unsigned log_entry_size); @@ -109,8 +118,8 @@ int cfs_coffee_configure_log(const char *file, unsigned log_size, * * Coffee is used on a wide range of storage types, and the default * I/O file semantics may not be optimal for the access pattern - * of a certain file. Hence, this functions allows programmers to - * switch the /O semantics on a file that is accessed through a + * of a certain file. Hence, this function allows programmers to + * switch the I/O semantics on a file that is accessed through a * particular file descriptor. * */ @@ -123,21 +132,14 @@ int cfs_coffee_set_io_semantics(int fd, unsigned flags); * Coffee formats the underlying storage by setting all bits to zero. * Formatting must be done before using Coffee for the first time in * a mote. + * + * Notice that the erased bits may be set to 1 on the physical storage + * when using flash memory. In this case, Coffee requires that the + * COFFEE_READ and COFFEE_WRITE functions used to access the flash memory + * invert all bits. */ int cfs_coffee_format(void); -/** - * \brief Points out a memory region that may not be altered during - * checkpointing operations that use the file system. - * \param size - * \return A pointer to the protected memory. - * - * This function returns the protected memory pointer and writes its size - * to the given parameter. Mainly used by sensornet checkpointing to protect - * the coffee state during CFS-based checkpointing operations. - */ -void *cfs_coffee_get_protected_mem(unsigned *size); - /** @} */ /** @} */ diff --git a/core/cfs/cfs.h b/core/cfs/cfs.h index 5b22e0931..3e2452c61 100644 --- a/core/cfs/cfs.h +++ b/core/cfs/cfs.h @@ -1,27 +1,3 @@ -/** - * \addtogroup sys - * @{ - */ - -/** - * \defgroup cfs The Contiki file system interface - * - * The Contiki file system interface (CFS) defines an abstract API for - * reading directories and for reading and writing files. The CFS API - * is intentionally simple. The CFS API is modeled after the POSIX - * file API, and slightly simplified. - * - * @{ - */ - -/** - * \file - * CFS header file. - * \author - * Adam Dunkels - * - */ - /* * Copyright (c) 2004, Swedish Institute of Computer Science. * All rights reserved. @@ -55,6 +31,31 @@ * Author: Adam Dunkels * */ + +/** + * \file + * CFS header file. + * \author + * Adam Dunkels + * + */ + +/** + * \addtogroup sys + * @{ + */ + +/** + * \defgroup cfs The Contiki file system interface + * + * The Contiki file system interface (CFS) defines an abstract API for + * reading directories and for reading and writing files. The CFS API + * is intentionally simple. The CFS API is modeled after the POSIX + * file API, and slightly simplified. + * + * @{ + */ + #ifndef CFS_H_ #define CFS_H_ @@ -67,7 +68,9 @@ typedef CFS_CONF_OFFSET_TYPE cfs_offset_t; #endif struct cfs_dir { - char dummy_space[32]; + /* Iteration state, which is implementation-defined and should not be + accessed externally. */ + char state[32]; }; struct cfs_dirent { diff --git a/core/contiki-default-conf.h b/core/contiki-default-conf.h index 37422668a..c26a2b8df 100644 --- a/core/contiki-default-conf.h +++ b/core/contiki-default-conf.h @@ -73,6 +73,11 @@ /* #define NETSTACK_CONF_MAC csma_driver */ #endif /* NETSTACK_CONF_MAC */ +/* NETSTACK_CONF_LLSEC specifies the link layer security driver. */ +#ifndef NETSTACK_CONF_LLSEC +#define NETSTACK_CONF_LLSEC nullsec_driver +#endif /* NETSTACK_CONF_LLSEC */ + /* NETSTACK_CONF_NETWORK specifies the network layer and can be either sicslowpan_driver, for IPv6 networking, or rime_driver, for the custom Rime network stack. */ @@ -111,11 +116,11 @@ * project-specific configuration to save memory. */ -/* UIP_CONF_IPV6 specifies whether or not IPv6 should be used. If IPv6 +/* NETSTACK_CONF_WITH_IPV6 specifies whether or not IPv6 should be used. If IPv6 is not used, IPv4 is used instead. */ -#ifndef UIP_CONF_IPV6 -#define UIP_CONF_IPV6 0 -#endif /* UIP_CONF_IPV6 */ +#ifndef NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_WITH_IPV6 0 +#endif /* NETSTACK_CONF_WITH_IPV6 */ /* UIP_CONF_BUFFER_SIZE specifies how much memory should be reserved for the uIP packet buffer. This sets an upper bound on the largest @@ -136,12 +141,32 @@ #define UIP_CONF_IPV6_RPL 1 #endif /* UIP_CONF_IPV6_RPL */ +/* If RPL is enabled also enable the RPL NBR Policy */ +#if UIP_CONF_IPV6_RPL +#ifndef NBR_TABLE_FIND_REMOVABLE +#define NBR_TABLE_FIND_REMOVABLE rpl_nbr_policy_find_removable +#endif /* NBR_TABLE_FIND_REMOVABLE */ +#endif /* UIP_CONF_IPV6_RPL */ + +/* RPL_CONF_MOP specifies the RPL mode of operation that will be + * advertised by the RPL root. Possible values: RPL_MOP_NO_DOWNWARD_ROUTES, + * RPL_MOP_NON_STORING, RPL_MOP_STORING_NO_MULTICAST, RPL_MOP_STORING_MULTICAST */ +#ifndef RPL_CONF_MOP +#define RPL_CONF_MOP RPL_MOP_STORING_NO_MULTICAST +#endif /* RPL_CONF_MOP */ + /* UIP_CONF_MAX_ROUTES specifies the maximum number of routes that each node will be able to handle. */ #ifndef UIP_CONF_MAX_ROUTES #define UIP_CONF_MAX_ROUTES 20 #endif /* UIP_CONF_MAX_ROUTES */ +/* RPL_NS_CONF_LINK_NUM specifies the maximum number of links a RPL root + * will maintain in non-storing mode. */ +#ifndef RPL_NS_CONF_LINK_NUM +#define RPL_NS_CONF_LINK_NUM 20 +#endif /* RPL_NS_CONF_LINK_NUM */ + /* UIP_CONF_UDP specifies if UDP support should be included or not. Disabling UDP saves memory but breaks a lot of stuff. */ #ifndef UIP_CONF_UDP @@ -180,6 +205,26 @@ #define NBR_TABLE_CONF_MAX_NEIGHBORS 8 #endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */ +/* UIP_CONF_ND6_SEND_RA enables standard IPv6 Router Advertisement. + * We enable it by default when IPv6 is used without RPL. */ +#ifndef UIP_CONF_ND6_SEND_RA +#define UIP_CONF_ND6_SEND_RA (NETSTACK_CONF_WITH_IPV6 && !UIP_CONF_IPV6_RPL) +#endif /* UIP_CONF_ND6_SEND_RA */ + +/* UIP_CONF_ND6_SEND_NA enables standard IPv6 Neighbor Discovery Protocol. + We enable it by default when IPv6 is used without RPL. + With RPL, the neighbor cache (link-local IPv6 <-> MAC address mapping) + is fed whenever receiving DIO and DAO messages. This is always sufficient + for RPL routing, i.e. to send to the preferred parent or any child. + Link-local unicast to other neighbors may, however, not be possible if + we never receive any DIO from them. This may happen if the link from the + neighbor to us is weak, if DIO transmissions are suppressed (Trickle + timer) or if the neighbor chooses not to transmit DIOs because it is + a leaf node or for any reason. */ +#ifndef UIP_CONF_ND6_SEND_NA +#define UIP_CONF_ND6_SEND_NA (NETSTACK_CONF_WITH_IPV6 && !UIP_CONF_IPV6_RPL) +#endif /* UIP_CONF_ND6_SEND_NA */ + /*---------------------------------------------------------------------------*/ /* 6lowpan configuration options. * @@ -188,27 +233,18 @@ * on the target platform, and are therefore platform-specific. */ -/* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS specifies how many times the - MAC layer should resend packets if no link-layer ACK was - received. This only makes sense with the csma_driver - NETSTACK_CONF_MAC. */ -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 4 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ - /* SICSLOWPAN_CONF_FRAG specifies if 6lowpan fragmentation should be used or not. Fragmentation is on by default. */ #ifndef SICSLOWPAN_CONF_FRAG #define SICSLOWPAN_CONF_FRAG 1 #endif /* SICSLOWPAN_CONF_FRAG */ -/* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD specifies the maximum size of - packets before they get fragmented. The default is 127 bytes (the - maximum size of a 802.15.4 frame) - 25 bytes (for the 802.15.4 MAC - layer header). This can be increased for systems with larger packet - sizes. */ +/* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD is the maximum available size for + frame headers, link layer security-related overhead, as well as + 6LoWPAN payload. By default, SICSLOWPAN_CONF_MAC_MAX_PAYLOAD is + 127 bytes (MTU of 802.15.4) - 2 bytes (Footer of 802.15.4). */ #ifndef SICSLOWPAN_CONF_MAC_MAX_PAYLOAD -#define SICSLOWPAN_CONF_MAC_MAX_PAYLOAD (127 - 25) +#define SICSLOWPAN_CONF_MAC_MAX_PAYLOAD (127 - 2) #endif /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */ /* SICSLOWPAN_CONF_COMPRESSION_THRESHOLD sets a lower threshold for diff --git a/core/contiki-net.h b/core/contiki-net.h index d783b35b2..087be23cb 100644 --- a/core/contiki-net.h +++ b/core/contiki-net.h @@ -44,11 +44,12 @@ #include "net/ip/uiplib.h" #include "net/ip/uip-udp-packet.h" #include "net/ip/simple-udp.h" +#include "net/ip/uip-nameserver.h" -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #include "net/ipv6/uip-icmp6.h" #include "net/ipv6/uip-ds6.h" -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #include "net/ip/resolv.h" diff --git a/core/ctk/ctk-draw.h b/core/ctk/ctk-draw.h index ed3c0d493..2f5cb8816 100644 --- a/core/ctk/ctk-draw.h +++ b/core/ctk/ctk-draw.h @@ -1,19 +1,3 @@ -/** - * \addtogroup ctk - * @{ - */ - -/** - * \file - * CTK screen drawing module interface, ctk-draw. - * \author Adam Dunkels - * - * This file contains the interface for the ctk-draw module.The - * ctk-draw module takes care of the actual screen drawing for CTK by - * implementing a handful of functions that are called by CTK. - * - */ - /* * Copyright (c) 2002-2003, Adam Dunkels. * All rights reserved. @@ -48,6 +32,22 @@ * */ +/** + * \addtogroup ctk + * @{ + */ + +/** + * \file + * CTK screen drawing module interface, ctk-draw. + * \author Adam Dunkels + * + * This file contains the interface for the ctk-draw module.The + * ctk-draw module takes care of the actual screen drawing for CTK by + * implementing a handful of functions that are called by CTK. + * + */ + #ifndef CTK_DRAW_H_ #define CTK_DRAW_H_ @@ -201,6 +201,7 @@ void ctk_draw_clear_window(struct ctk_window *window, * drawn, in screen coordinates (line 1 is the first line below the * menus) * + * \param draw_borders The border style */ void ctk_draw_window(struct ctk_window *window, unsigned char focus, @@ -318,7 +319,7 @@ extern unsigned char ctk_draw_windowborder_width, /** * The character used for the Return/Enter key. * - * \define #define CH_ENTER '\n' + * \#define CH_ENTER '\n' */ /** diff --git a/core/ctk/ctk-filedialog.c b/core/ctk/ctk-filedialog.c index 0bafcc4a8..ca4bf523e 100644 --- a/core/ctk/ctk-filedialog.c +++ b/core/ctk/ctk-filedialog.c @@ -155,14 +155,14 @@ ctk_filedialog_eventhandler(struct ctk_filedialog_state *s, } return 1; } else if(ev == ctk_signal_keypress) { - if((ctk_arch_key_t)data == CH_CURS_UP) { + if((char)(size_t)data == CH_CURS_UP) { clearptr(); if(fileptr > 0) { --fileptr; } showptr(); return 1; - } else if((ctk_arch_key_t)data == CH_CURS_DOWN) { + } else if((char)(size_t)data == CH_CURS_DOWN) { clearptr(); if(fileptr < FILES_HEIGHT - 1) { ++fileptr; diff --git a/core/ctk/ctk.c b/core/ctk/ctk.c index 9bba40fe9..699cf0198 100644 --- a/core/ctk/ctk.c +++ b/core/ctk/ctk.c @@ -1,18 +1,3 @@ -/** - * \defgroup ctk CTK graphical user interface - * - * The Contiki Toolkit (CTK) provides the graphical user interface for - * the Contiki system. - * - * @{ - */ - -/** - * \file - * The Contiki Toolkit CTK, the Contiki GUI. - * \author Adam Dunkels - */ - /* * Copyright (c) 2002-2003, Adam Dunkels. * All rights reserved. @@ -47,6 +32,21 @@ * */ +/** + * \file + * The Contiki Toolkit CTK, the Contiki GUI. + * \author Adam Dunkels + */ + +/** + * \defgroup ctk CTK graphical user interface + * + * The Contiki Toolkit (CTK) provides the graphical user interface for + * the Contiki system. + * + * @{ + */ + #include #include "contiki.h" @@ -185,7 +185,7 @@ unsigned short ctk_screensaver_timeout = (5*60); static struct timer timer; #endif /* CTK_CONF_SCREENSAVER */ -static void CC_FASTCALL +static void textentry_input(ctk_arch_key_t c, CC_REGISTER_ARG struct ctk_textentry *t); @@ -555,7 +555,7 @@ ctk_menu_remove(struct ctk_menu *menu) * \param clipy2 The lower bound of the clip interval */ /*---------------------------------------------------------------------------*/ -static void CC_FASTCALL +static void do_redraw_all(unsigned char clipy1, unsigned char clipy2) { #if CTK_CONF_WINDOWS @@ -818,7 +818,7 @@ ctk_menuitem_add(CC_REGISTER_ARG struct ctk_menu *menu, char *name) * \param w The widget that should be redrawn. */ /*---------------------------------------------------------------------------*/ -static void CC_FASTCALL +static void add_redrawwidget(struct ctk_widget *w) { static unsigned char i; @@ -852,7 +852,9 @@ add_redrawwidget(struct ctk_widget *w) static void widget_redraw(struct ctk_widget *widget) { +#if CTK_CONF_WINDOWS struct ctk_window *window; +#endif /* CTK_CONF_WINDOWS */ if(mode != CTK_MODE_NORMAL || widget == NULL) { return; @@ -870,8 +872,8 @@ widget_redraw(struct ctk_widget *widget) if(menus.open == NULL) #endif /* CTK_CONF_MENUS */ { - window = widget->window; #if CTK_CONF_WINDOWS + window = widget->window; if(window == dialog) { ctk_draw_widget(widget, CTK_FOCUS_DIALOG, 0, height); } else if(dialog == NULL && @@ -921,7 +923,7 @@ ctk_widget_redraw(struct ctk_widget *widget) * \param widget The widget to be added. */ /*---------------------------------------------------------------------------*/ -void CC_FASTCALL +void ctk_widget_add(CC_REGISTER_ARG struct ctk_window *window, CC_REGISTER_ARG struct ctk_widget *widget) { @@ -973,7 +975,7 @@ ctk_desktop_height(struct ctk_desktop *d) * \param focus The widget to be focused. */ /*---------------------------------------------------------------------------*/ -static void CC_FASTCALL +static void select_widget(struct ctk_widget *focus) { struct ctk_window *window; @@ -1001,7 +1003,7 @@ select_widget(struct ctk_widget *focus) #define DOWN 1 #define LEFT 2 #define RIGHT 3 -static void CC_FASTCALL +static void switch_focus_widget(unsigned char direction) { #if CTK_CONF_WINDOWS @@ -1126,7 +1128,7 @@ switch_menu_item(unsigned char updown) } #endif /* CTK_CONF_MENUS */ /*---------------------------------------------------------------------------*/ -static unsigned char CC_FASTCALL +static unsigned char activate(CC_REGISTER_ARG struct ctk_widget *w) { if(w->type == CTK_WIDGET_BUTTON) { @@ -1183,7 +1185,7 @@ ctk_textentry_input_null(ctk_arch_key_t c, struct ctk_textentry *t) } #endif /* SDCC */ /*---------------------------------------------------------------------------*/ -static void CC_FASTCALL +static void textentry_input(ctk_arch_key_t c, CC_REGISTER_ARG struct ctk_textentry *t) { register char *cptr, *cptr2; diff --git a/core/ctk/ctk.h b/core/ctk/ctk.h index 5d58a7e56..4aea9458e 100644 --- a/core/ctk/ctk.h +++ b/core/ctk/ctk.h @@ -1,17 +1,3 @@ -/** - * \addtogroup ctk - * @{ - */ - -/** - * \file - * CTK header file. - * \author Adam Dunkels - * - * The CTK header file contains functioin declarations and definitions - * of CTK structures and macros. - */ - /* * Copyright (c) 2002-2003, Adam Dunkels. * All rights reserved. @@ -46,6 +32,20 @@ * */ +/** + * \file + * CTK header file. + * \author Adam Dunkels + * + * The CTK header file contains functioin declarations and definitions + * of CTK structures and macros. + */ + +/** + * \addtogroup ctk + * @{ + */ + #ifndef CTK_H_ #define CTK_H_ @@ -743,8 +743,8 @@ void ctk_icon_add(struct ctk_widget *icon, struct process *p); */ #define CTK_WIDGET_ADD(win, widg) \ ctk_widget_add(win, (struct ctk_widget *)widg) -CCIF void CC_FASTCALL ctk_widget_add(struct ctk_window *window, - struct ctk_widget *widget); +CCIF void ctk_widget_add(struct ctk_window *window, + struct ctk_widget *widget); /** * Set focus to a widget. diff --git a/core/dev/button-sensor.h b/core/dev/button-sensor.h index b05d80db9..34a51d7d5 100644 --- a/core/dev/button-sensor.h +++ b/core/dev/button-sensor.h @@ -35,6 +35,7 @@ #include "lib/sensors.h" extern const struct sensors_sensor button_sensor; +extern const struct sensors_sensor button_sensor2; #define BUTTON_SENSOR "Button" diff --git a/core/dev/eeprom.h b/core/dev/eeprom.h index 8ff90ff1c..0a57117be 100644 --- a/core/dev/eeprom.h +++ b/core/dev/eeprom.h @@ -1,25 +1,3 @@ -/** - * \addtogroup dev - * @{ - */ - -/** - * \defgroup eeprom EEPROM API - * - * The EEPROM API defines a common interface for EEPROM access on - * Contiki platforms. - * - * A platform with EEPROM support must implement this API. - * - * @{ - */ - -/** - * \file - * EEPROM functions. - * \author Adam Dunkels - */ - /* Copyright (c) 2004 Swedish Institute of Computer Science. * All rights reserved. * @@ -50,6 +28,27 @@ * */ +/** + * \file + * EEPROM functions. + * \author Adam Dunkels + */ + +/** + * \addtogroup dev + * @{ + */ + +/** + * \defgroup eeprom EEPROM API + * + * The EEPROM API defines a common interface for EEPROM access on + * Contiki platforms. + * + * A platform with EEPROM support must implement this API. + * + * @{ + */ #ifndef EEPROM_H_ #define EEPROM_H_ diff --git a/core/dev/leds.c b/core/dev/leds.c index 9e9c181e4..c815e100d 100644 --- a/core/dev/leds.c +++ b/core/dev/leds.c @@ -34,54 +34,58 @@ #include "sys/clock.h" #include "sys/energest.h" -static unsigned char leds, invert; +static unsigned char leds; /*---------------------------------------------------------------------------*/ static void -show_leds(unsigned char changed) +show_leds(unsigned char new_leds) { + unsigned char changed; + changed = leds ^ new_leds; + leds = new_leds; + if(changed & LEDS_GREEN) { /* Green did change */ - if((invert ^ leds) & LEDS_GREEN) { + if(leds & LEDS_GREEN) { ENERGEST_ON(ENERGEST_TYPE_LED_GREEN); } else { ENERGEST_OFF(ENERGEST_TYPE_LED_GREEN); } } if(changed & LEDS_YELLOW) { - if((invert ^ leds) & LEDS_YELLOW) { + if(leds & LEDS_YELLOW) { ENERGEST_ON(ENERGEST_TYPE_LED_YELLOW); } else { ENERGEST_OFF(ENERGEST_TYPE_LED_YELLOW); } } if(changed & LEDS_RED) { - if((invert ^ leds) & LEDS_RED) { + if(leds & LEDS_RED) { ENERGEST_ON(ENERGEST_TYPE_LED_RED); } else { ENERGEST_OFF(ENERGEST_TYPE_LED_RED); } } - leds_arch_set(leds ^ invert); + leds_arch_set(leds); } /*---------------------------------------------------------------------------*/ void leds_init(void) { leds_arch_init(); - leds = invert = 0; + leds = 0; } /*---------------------------------------------------------------------------*/ void leds_blink(void) { - /* Blink all leds. */ - unsigned char inv; - inv = ~(leds ^ invert); - leds_invert(inv); + /* Blink all leds that were initially off. */ + unsigned char blink; + blink = ~leds; + leds_toggle(blink); clock_delay(400); - leds_invert(inv); + leds_toggle(blink); } /*---------------------------------------------------------------------------*/ unsigned char @@ -98,31 +102,18 @@ leds_set(unsigned char ledv) void leds_on(unsigned char ledv) { - unsigned char changed; - changed = (~leds) & ledv; - leds |= ledv; - show_leds(changed); + show_leds(leds | ledv); } /*---------------------------------------------------------------------------*/ void leds_off(unsigned char ledv) { - unsigned char changed; - changed = leds & ledv; - leds &= ~ledv; - show_leds(changed); + show_leds(leds & ~ledv); } /*---------------------------------------------------------------------------*/ void leds_toggle(unsigned char ledv) { - leds_invert(ledv); -} -/*---------------------------------------------------------------------------*/ -/* invert the invert register using the leds parameter */ -void -leds_invert(unsigned char ledv) { - invert = invert ^ ledv; - show_leds(ledv); + show_leds(leds ^ ledv); } /*---------------------------------------------------------------------------*/ diff --git a/core/dev/leds.h b/core/dev/leds.h index 7264a8dfe..839852c41 100644 --- a/core/dev/leds.h +++ b/core/dev/leds.h @@ -77,14 +77,13 @@ void leds_blink(void); #endif /* LEDS_CONF_ALL */ /** - * Returns the current status of all leds (respects invert) + * Returns the current status of all leds */ unsigned char leds_get(void); void leds_set(unsigned char leds); void leds_on(unsigned char leds); void leds_off(unsigned char leds); void leds_toggle(unsigned char leds); -void leds_invert(unsigned char leds); /** * Leds implementation diff --git a/core/dev/nullradio.c b/core/dev/nullradio.c index c2b978f2b..7f17d5638 100644 --- a/core/dev/nullradio.c +++ b/core/dev/nullradio.c @@ -28,7 +28,7 @@ send(const void *payload, unsigned short payload_len) } /*---------------------------------------------------------------------------*/ static int -read(void *buf, unsigned short buf_len) +radio_read(void *buf, unsigned short buf_len) { return 0; } @@ -63,17 +63,45 @@ off(void) return 0; } /*---------------------------------------------------------------------------*/ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ const struct radio_driver nullradio_driver = { init, prepare, transmit, send, - read, + radio_read, channel_clear, receiving_packet, pending_packet, on, off, + get_value, + set_value, + get_object, + set_object }; /*---------------------------------------------------------------------------*/ diff --git a/core/dev/radio.h b/core/dev/radio.h index 69eee756e..982acc51d 100644 --- a/core/dev/radio.h +++ b/core/dev/radio.h @@ -1,17 +1,3 @@ -/** - * \addtogroup dev - * @{ - */ - -/** - * \defgroup radio Radio API - * - * The radio API module defines a set of functions that a radio device - * driver must implement. - * - * @{ - */ - /* * Copyright (c) 2005, Swedish Institute of Computer Science. * All rights reserved. @@ -49,18 +35,209 @@ * Header file for the radio API * \author * Adam Dunkels + * Joakim Eriksson + * Niclas Finne + * Nicolas Tsiftes + */ + +/** + * \addtogroup dev + * @{ + */ + +/** + * \defgroup radio Radio API + * + * The radio API module defines a set of functions that a radio device + * driver must implement. + * + * @{ */ #ifndef RADIO_H_ #define RADIO_H_ +#include + +/** + * Each radio has a set of parameters that designate the current + * configuration and state of the radio. Parameters can either have + * values of type radio_value_t, or, when this type is insufficient, a + * generic object that is specified by a memory pointer and the size + * of the object. + * + * The radio_value_t type is set to an integer type that can hold most + * values used to configure the radio, and is therefore the most + * common type used for a parameter. Certain parameters require + * objects of a considerably larger size than radio_value_t, however, + * and in these cases the documentation below for the parameter will + * indicate this. + * + * All radio parameters that can vary during runtime are prefixed by + * "RADIO_PARAM", whereas those "parameters" that are guaranteed to + * remain immutable are prefixed by "RADIO_CONST". Each mutable + * parameter has a set of valid parameter values. When attempting to + * set a parameter to an invalid value, the radio will return + * RADIO_RESULT_INVALID_VALUE. + * + * Some radios support only a subset of the defined radio parameters. + * When trying to set or get such an unsupported parameter, the radio + * will return RADIO_RESULT_NOT_SUPPORTED. + */ + +typedef int radio_value_t; +typedef unsigned radio_param_t; + +enum { + + /* Radio power mode determines if the radio is on + (RADIO_POWER_MODE_ON) or off (RADIO_POWER_MODE_OFF). */ + RADIO_PARAM_POWER_MODE, + + /* + * Channel used for radio communication. The channel depends on the + * communication standard used by the radio. The values can range + * from RADIO_CONST_CHANNEL_MIN to RADIO_CONST_CHANNEL_MAX. + */ + RADIO_PARAM_CHANNEL, + + /* Personal area network identifier, which is used by the address filter. */ + RADIO_PARAM_PAN_ID, + + /* Short address (16 bits) for the radio, which is used by the address + filter. */ + RADIO_PARAM_16BIT_ADDR, + + /* + * Radio receiver mode determines if the radio has address filter + * (RADIO_RX_MODE_ADDRESS_FILTER) and auto-ACK (RADIO_RX_MODE_AUTOACK) + * enabled. This parameter is set as a bit mask. + */ + RADIO_PARAM_RX_MODE, + + /* + * Radio transmission mode determines if the radio has send on CCA + * (RADIO_TX_MODE_SEND_ON_CCA) enabled or not. This parameter is set + * as a bit mask. + */ + RADIO_PARAM_TX_MODE, + + /* + * Transmission power in dBm. The values can range from + * RADIO_CONST_TXPOWER_MIN to RADIO_CONST_TXPOWER_MAX. + * + * Some radios restrict the available values to a subset of this + * range. If an unavailable TXPOWER value is requested to be set, + * the radio may select another TXPOWER close to the requested + * one. When getting the value of this parameter, the actual value + * used by the radio will be returned. + */ + RADIO_PARAM_TXPOWER, + + /* + * Clear channel assessment threshold in dBm. This threshold + * determines the minimum RSSI level at which the radio will assume + * that there is a packet in the air. + * + * The CCA threshold must be set to a level above the noise floor of + * the deployment. Otherwise mechanisms such as send-on-CCA and + * low-power-listening duty cycling protocols may not work + * correctly. Hence, the default value of the system may not be + * optimal for any given deployment. + */ + RADIO_PARAM_CCA_THRESHOLD, + + /* Received signal strength indicator in dBm. */ + RADIO_PARAM_RSSI, + + /* RSSI of the last received packet */ + RADIO_PARAM_LAST_RSSI, + + /* Link quality of the last received packet */ + RADIO_PARAM_LAST_LINK_QUALITY, + + /* + * Long (64 bits) address for the radio, which is used by the address filter. + * The address is specified in network byte order. + * + * Because this parameter value is larger than what fits in radio_value_t, + * it needs to be used with radio.get_object()/set_object(). + */ + RADIO_PARAM_64BIT_ADDR, + + /* Last packet timestamp, of type rtimer_clock_t. + * Because this parameter value mat be larger than what fits in radio_value_t, + * it needs to be used with radio.get_object()/set_object(). */ + RADIO_PARAM_LAST_PACKET_TIMESTAMP, + + /* Constants (read only) */ + + /* The lowest radio channel. */ + RADIO_CONST_CHANNEL_MIN, + /* The highest radio channel. */ + RADIO_CONST_CHANNEL_MAX, + + /* The minimum transmission power in dBm. */ + RADIO_CONST_TXPOWER_MIN, + /* The maximum transmission power in dBm. */ + RADIO_CONST_TXPOWER_MAX +}; + +/* Radio power modes */ +enum { + RADIO_POWER_MODE_OFF, + RADIO_POWER_MODE_ON +}; + +/** + * The radio reception mode controls address filtering and automatic + * transmission of acknowledgements in the radio (if such operations + * are supported by the radio). A single parameter is used to allow + * setting these features simultaneously as an atomic operation. + * + * To enable both address filter and transmissions of automatic + * acknowledgments: + * + * NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE, + * RADIO_RX_MODE_ADDRESS_FILTER | RADIO_RX_MODE_AUTOACK); + */ +#define RADIO_RX_MODE_ADDRESS_FILTER (1 << 0) +#define RADIO_RX_MODE_AUTOACK (1 << 1) +#define RADIO_RX_MODE_POLL_MODE (1 << 2) + +/** + * The radio transmission mode controls whether transmissions should + * be done using clear channel assessment (if supported by the + * radio). If send-on-CCA is enabled, the radio's send function will + * wait for a radio-specific time window for the channel to become + * clear. If this does not happen, the send function will return + * RADIO_TX_COLLISION. + */ +#define RADIO_TX_MODE_SEND_ON_CCA (1 << 0) + +/* Radio return values when setting or getting radio parameters. */ +typedef enum { + RADIO_RESULT_OK, + RADIO_RESULT_NOT_SUPPORTED, + RADIO_RESULT_INVALID_VALUE, + RADIO_RESULT_ERROR +} radio_result_t; + +/* Radio return values for transmissions. */ +enum { + RADIO_TX_OK, + RADIO_TX_ERR, + RADIO_TX_COLLISION, + RADIO_TX_NOACK, +}; + /** * The structure of a device driver for a radio in Contiki. */ struct radio_driver { int (* init)(void); - + /** Prepare the radio with a packet to be sent. */ int (* prepare)(const void *payload, unsigned short payload_len); @@ -88,18 +265,30 @@ struct radio_driver { /** Turn the radio off. */ int (* off)(void); -}; -/* Generic radio return values. */ -enum { - RADIO_TX_OK, - RADIO_TX_ERR, - RADIO_TX_COLLISION, - RADIO_TX_NOACK, + /** Get a radio parameter value. */ + radio_result_t (* get_value)(radio_param_t param, radio_value_t *value); + + /** Set a radio parameter value. */ + radio_result_t (* set_value)(radio_param_t param, radio_value_t value); + + /** + * Get a radio parameter object. The argument 'dest' must point to a + * memory area of at least 'size' bytes, and this memory area will + * contain the parameter object if the function succeeds. + */ + radio_result_t (* get_object)(radio_param_t param, void *dest, size_t size); + + /** + * Set a radio parameter object. The memory area referred to by the + * argument 'src' will not be accessed after the function returns. + */ + radio_result_t (* set_object)(radio_param_t param, const void *src, + size_t size); + }; #endif /* RADIO_H_ */ - /** @} */ /** @} */ diff --git a/core/dev/slip.c b/core/dev/slip.c index e70010b51..451b9ec6c 100644 --- a/core/dev/slip.c +++ b/core/dev/slip.c @@ -96,7 +96,6 @@ slip_set_input_callback(void (*c)(void)) /* slip_send: forward (IPv4) packets with {UIP_FW_NETIF(..., slip_send)} * was used in slip-bridge.c */ -//#if WITH_UIP uint8_t slip_send(void) { @@ -125,7 +124,6 @@ slip_send(void) return UIP_FW_OK; } -//#endif /* WITH_UIP */ /*---------------------------------------------------------------------------*/ uint8_t slip_write(const void *_ptr, int len) @@ -264,7 +262,7 @@ PROCESS_THREAD(slip_process, ev, data) /* Move packet from rxbuf to buffer provided by uIP. */ uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN], UIP_BUFSIZE - UIP_LLH_LEN); -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 if(uip_len == 4 && strncmp((char*)&uip_buf[UIP_LLH_LEN], "?IPA", 4) == 0) { char buf[8]; memcpy(&buf[0], "=IPA", 4); @@ -295,10 +293,10 @@ PROCESS_THREAD(slip_process, ev, data) tcpip_input(); #endif } else { - uip_len = 0; + uip_clear_buf(); SLIP_STATISTICS(slip_ip_drop++); } -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ if(uip_len > 0) { if(input_callback) { input_callback(); @@ -309,7 +307,7 @@ PROCESS_THREAD(slip_process, ev, data) tcpip_input(); #endif } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ } PROCESS_END(); diff --git a/core/dev/spi.h b/core/dev/spi.h index a36be1ca7..5960c411b 100644 --- a/core/dev/spi.h +++ b/core/dev/spi.h @@ -57,35 +57,36 @@ extern unsigned char spi_busy; void spi_init(void); /* Write one character to SPI */ -#define SPI_WRITE(data) \ - do { \ - SPI_WAITFORTx_BEFORE(); \ - SPI_TXBUF = data; \ - SPI_WAITFOREOTx(); \ +#define SPI_WRITE(data) \ + do { \ + SPI_WAITFORTx_BEFORE(); \ + SPI_TXBUF = data; \ + SPI_WAITFOREOTx(); \ } while(0) /* Write one character to SPI - will not wait for end useful for multiple writes with wait after final */ -#define SPI_WRITE_FAST(data) \ - do { \ - SPI_WAITFORTx_BEFORE(); \ - SPI_TXBUF = data; \ - SPI_WAITFORTx_AFTER(); \ +#define SPI_WRITE_FAST(data) \ + do { \ + SPI_WAITFORTx_BEFORE(); \ + SPI_TXBUF = data; \ + SPI_WAITFORTx_AFTER(); \ } while(0) /* Read one character from SPI */ -#define SPI_READ(data) \ - do { \ - SPI_TXBUF = 0; \ - SPI_WAITFOREORx(); \ - data = SPI_RXBUF; \ +#define SPI_READ(data) \ + do { \ + SPI_TXBUF = 0; \ + SPI_WAITFOREORx(); \ + data = SPI_RXBUF; \ } while(0) /* Flush the SPI read register */ +#ifndef SPI_FLUSH #define SPI_FLUSH() \ - do { \ - SPI_RXBUF; \ - } while(0); - + do { \ + SPI_RXBUF; \ + } while(0) +#endif #endif /* SPI_H_ */ diff --git a/core/lib/aes-128.c b/core/lib/aes-128.c new file mode 100644 index 000000000..98e115c3f --- /dev/null +++ b/core/lib/aes-128.c @@ -0,0 +1,183 @@ +/* --COPYRIGHT--,BSD + * Copyright (c) 2011, Texas Instruments Incorporated + * All rights reserved. + * + * 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 Texas Instruments Incorporated 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 OWNER 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. + * --/COPYRIGHT--*/ +/* + * TI_aes_128_encr_only.c + * + * Created on: Nov 3, 2011 + * Author: Eric Peeters + */ + +/** + * \file + * Wrapped AES-128 implementation from Texas Instruments. + * \author + * Konrad Krentz + */ + +#include "lib/aes-128.h" +#include + +static const uint8_t sbox[256] = { +0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, +0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, +0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, +0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, +0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, +0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, +0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, +0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, +0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, +0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, +0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, +0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, +0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, +0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, +0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, +0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; + +static uint8_t round_keys[11][AES_128_KEY_LENGTH]; + +/*---------------------------------------------------------------------------*/ +/* multiplies by 2 in GF(2) */ +static uint8_t +galois_mul2(uint8_t value) +{ + uint8_t xor_val = (value >> 7) * 0x1b; + return ((value << 1) ^ xor_val); +} +/*---------------------------------------------------------------------------*/ +static void +set_key(const uint8_t *key) +{ + uint8_t i; + uint8_t j; + uint8_t rcon; + + rcon = 0x01; + memcpy(round_keys[0], key, AES_128_KEY_LENGTH); + for(i = 1; i <= 10; i++) { + round_keys[i][0] = sbox[round_keys[i - 1][13]] ^ round_keys[i - 1][0] ^ rcon; + round_keys[i][1] = sbox[round_keys[i - 1][14]] ^ round_keys[i - 1][1]; + round_keys[i][2] = sbox[round_keys[i - 1][15]] ^ round_keys[i - 1][2]; + round_keys[i][3] = sbox[round_keys[i - 1][12]] ^ round_keys[i - 1][3]; + for(j = 4; j < AES_128_BLOCK_SIZE; j++) { + round_keys[i][j] = round_keys[i - 1][j] ^ round_keys[i][j - 4]; + } + rcon = galois_mul2(rcon); + } +} +/*---------------------------------------------------------------------------*/ +static void +encrypt(uint8_t *state) +{ + uint8_t buf1, buf2, buf3, buf4, round, i; + + /* round 0 */ + /* AddRoundKey */ + for(i = 0; i < AES_128_BLOCK_SIZE; i++) { + state[i] = state[i] ^ round_keys[0][i]; + } + + for(round = 1; round <= 10; round++) { + /* ByteSub */ + for(i = 0; i < AES_128_BLOCK_SIZE; i++) { + state[i] = sbox[state[i]]; + } + + /* ShiftRow */ + buf1 = state[1]; + state[1] = state[5]; + state[5] = state[9]; + state[9] = state[13]; + state[13] = buf1; + + buf1 = state[2]; + buf2 = state[6]; + state[2] = state[10]; + state[6] = state[14]; + state[10] = buf1; + state[14] = buf2; + + buf1 = state[15]; + state[15] = state[11]; + state[11] = state[7]; + state[7] = state[3]; + state[3] = buf1; + + /* last round skips MixColumn */ + if(round < 10) { + /* MixColumn */ + for(i = 0; i < 4; i++) { + buf4 = (i << 2); + buf1 = state[buf4] ^ state[buf4 + 1] ^ state[buf4 + 2] ^ state[buf4 + 3]; + buf2 = state[buf4]; + buf3 = state[buf4] ^ state[buf4 + 1]; + buf3 = galois_mul2(buf3); + + state[buf4] = state[buf4] ^ buf3 ^ buf1; + + buf3 = state[buf4 + 1] ^ state[buf4 + 2]; + buf3 = galois_mul2(buf3); + state[buf4 + 1] = state[buf4 + 1] ^ buf3 ^ buf1; + + buf3 = state[buf4 + 2] ^ state[buf4 + 3]; + buf3 = galois_mul2(buf3); + state[buf4 + 2] = state[buf4 + 2] ^ buf3 ^ buf1; + + buf3 = state[buf4 + 3] ^ buf2; + buf3 = galois_mul2(buf3); + state[buf4 + 3] = state[buf4 + 3] ^ buf3 ^ buf1; + } + } + + /* AddRoundKey */ + for(i = 0; i < AES_128_BLOCK_SIZE; i++) { + state[i] = state[i] ^ round_keys[round][i]; + } + } +} +/*---------------------------------------------------------------------------*/ +void +aes_128_set_padded_key(uint8_t *key, uint8_t key_len) +{ + uint8_t block[AES_128_BLOCK_SIZE]; + + memset(block, 0, AES_128_BLOCK_SIZE); + memcpy(block, key, key_len); + AES_128.set_key(block); +} +/*---------------------------------------------------------------------------*/ +const struct aes_128_driver aes_128_driver = { + set_key, + encrypt +}; +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/lpm.h b/core/lib/aes-128.h similarity index 66% rename from cpu/cc2430/dev/lpm.h rename to core/lib/aes-128.h index eb1522834..458b93915 100644 --- a/cpu/cc2430/dev/lpm.h +++ b/core/lib/aes-128.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Loughborough University - Computer Science + * Copyright (c) 2013, Hasso-Plattner-Institut. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,31 +27,51 @@ * SUCH DAMAGE. * * This file is part of the Contiki operating system. + * */ /** * \file - * Header file for the cc2430 Low Power Modes (LPM) - * We currently support the following: - * - Set MCU IDLE while in PM0. This is working as intended - * - Drop to PM1. This results in incoming radio packet losses. - * + * AES-128. * \author - * George Oikonomou - + * Konrad Krentz */ -#ifndef LPM_H_ -#define LPM_H_ -#include "contiki-conf.h" +#ifndef AES_128_H_ +#define AES_128_H_ -#define LPM_MODE_NONE 0 /* No LPM - Always on */ -#define LPM_MODE_IDLE 1 /* Set MCU Idle as part of the main loop */ -#define LPM_MODE_PM2 2 /* Drop to PM1 - causes radio packet losses for now */ +#include "contiki.h" -#ifdef LPM_CONF_MODE -#define LPM_MODE LPM_CONF_MODE -#else -#define LPM_MODE LPM_MODE_IDLE -#endif /* LPM_CONF_MODE */ +#define AES_128_BLOCK_SIZE 16 +#define AES_128_KEY_LENGTH 16 -#endif /* LPM_H_ */ +#ifdef AES_128_CONF +#define AES_128 AES_128_CONF +#else /* AES_128_CONF */ +#define AES_128 aes_128_driver +#endif /* AES_128_CONF */ + +/** + * Structure of AES drivers. + */ +struct aes_128_driver { + + /** + * \brief Sets the current key. + */ + void (* set_key)(const uint8_t *key); + + /** + * \brief Encrypts. + */ + void (* encrypt)(uint8_t *plaintext_and_result); +}; + +/** + * \brief Pads the key with zeroes before calling AES_128.set_key + */ +void aes_128_set_padded_key(uint8_t *key, uint8_t key_len); + +extern const struct aes_128_driver AES_128; + +#endif /* AES_128_H_ */ diff --git a/core/lib/assert.h b/core/lib/assert.h index da9fd8f9b..3689a8b1d 100644 --- a/core/lib/assert.h +++ b/core/lib/assert.h @@ -28,9 +28,10 @@ * */ -#ifndef ASSERT_H -#define ASSERT_H +#ifndef ASSERT_H_ +#define ASSERT_H_ +#undef assert #ifdef NDEBUG #define assert(e) ((void)0) #else @@ -44,4 +45,4 @@ void _xassert(const char *, int); #define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1] #endif -#endif /* ASSERT_H */ +#endif /* ASSERT_H_ */ diff --git a/core/lib/ccm-star.c b/core/lib/ccm-star.c new file mode 100644 index 000000000..4cc8723a1 --- /dev/null +++ b/core/lib/ccm-star.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2013, Hasso-Plattner-Institut. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * AES_128-based CCM* implementation. + * \author + * Original: Konrad Krentz + * Generified version: Justin King-Lacroix + */ + +#include "ccm-star.h" +#include "lib/aes-128.h" +#include + +/* see RFC 3610 */ +#define CCM_STAR_AUTH_FLAGS(Adata, M) ((Adata ? (1u << 6) : 0) | (((M - 2u) >> 1) << 3) | 1u) +#define CCM_STAR_ENCRYPTION_FLAGS 1 + +/*---------------------------------------------------------------------------*/ +static void +set_iv(uint8_t *iv, + uint8_t flags, + const uint8_t *nonce, + uint8_t counter) +{ + iv[0] = flags; + memcpy(iv + 1, nonce, CCM_STAR_NONCE_LENGTH); + iv[14] = 0; + iv[15] = counter; +} +/*---------------------------------------------------------------------------*/ +/* XORs the block m[pos] ... m[pos + 15] with K_{counter} */ +static void +ctr_step(const uint8_t *nonce, + uint8_t pos, + uint8_t *m_and_result, + uint8_t m_len, + uint8_t counter) +{ + uint8_t a[AES_128_BLOCK_SIZE]; + uint8_t i; + + set_iv(a, CCM_STAR_ENCRYPTION_FLAGS, nonce, counter); + AES_128.encrypt(a); + + for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) { + m_and_result[pos + i] ^= a[i]; + } +} +/*---------------------------------------------------------------------------*/ +static void +mic(const uint8_t *nonce, + const uint8_t *m, uint8_t m_len, + const uint8_t *a, uint8_t a_len, + uint8_t *result, + uint8_t mic_len) +{ + uint8_t x[AES_128_BLOCK_SIZE]; + uint8_t pos; + uint8_t i; + + set_iv(x, CCM_STAR_AUTH_FLAGS(a_len, mic_len), nonce, m_len); + AES_128.encrypt(x); + + if(a_len) { + x[1] = x[1] ^ a_len; + for(i = 2; (i - 2 < a_len) && (i < AES_128_BLOCK_SIZE); i++) { + x[i] ^= a[i - 2]; + } + + AES_128.encrypt(x); + + pos = 14; + while(pos < a_len) { + for(i = 0; (pos + i < a_len) && (i < AES_128_BLOCK_SIZE); i++) { + x[i] ^= a[pos + i]; + } + pos += AES_128_BLOCK_SIZE; + AES_128.encrypt(x); + } + } + + if(m_len) { + pos = 0; + while(pos < m_len) { + for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) { + x[i] ^= m[pos + i]; + } + pos += AES_128_BLOCK_SIZE; + AES_128.encrypt(x); + } + } + + ctr_step(nonce, 0, x, AES_128_BLOCK_SIZE, 0); + + memcpy(result, x, mic_len); +} +/*---------------------------------------------------------------------------*/ +static void +ctr(const uint8_t *nonce, uint8_t *m, uint8_t m_len) +{ + uint8_t pos; + uint8_t counter; + + pos = 0; + counter = 1; + while(pos < m_len) { + ctr_step(nonce, pos, m, m_len, counter++); + pos += AES_128_BLOCK_SIZE; + } +} +/*---------------------------------------------------------------------------*/ +static void +set_key(const uint8_t *key) +{ + AES_128.set_key(key); +} +/*---------------------------------------------------------------------------*/ +static void +aead(const uint8_t* nonce, + uint8_t* m, uint8_t m_len, + const uint8_t* a, uint8_t a_len, + uint8_t *result, uint8_t mic_len, + int forward) +{ + if(!forward) { + /* decrypt */ + ctr(nonce, m, m_len); + } + + mic(nonce, + m, m_len, + a, a_len, + result, + mic_len); + + if(forward) { + /* encrypt */ + ctr(nonce, m, m_len); + } +} +/*---------------------------------------------------------------------------*/ +const struct ccm_star_driver ccm_star_driver = { + set_key, + aead +}; +/*---------------------------------------------------------------------------*/ diff --git a/core/lib/ccm-star.h b/core/lib/ccm-star.h new file mode 100644 index 000000000..06296fb44 --- /dev/null +++ b/core/lib/ccm-star.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013, Hasso-Plattner-Institut. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * CCM* header file. + * \author + * Original: Konrad Krentz + * Generified version: Justin King-Lacroix + */ +#ifndef CCM_STAR_H_ +#define CCM_STAR_H_ + +#include "contiki.h" + +#ifdef CCM_STAR_CONF +#define CCM_STAR CCM_STAR_CONF +#else /* CCM_STAR_CONF */ +#define CCM_STAR ccm_star_driver +#endif /* CCM_STAR_CONF */ + +#define CCM_STAR_NONCE_LENGTH 13 + +/** + * Structure of CCM* drivers. + */ +struct ccm_star_driver { + + /** + * \brief Sets the key in use. Default implementation calls AES_128.set_key(). + * \param key The key to use. + */ + void (* set_key)(const uint8_t* key); + + /** + * \brief Combines authentication and encryption. + * \param nonce The nonce to use. CCM_STAR_NONCE_LENGTH bytes long. + * \param m message to encrypt or decrypt + * \param a Additional authenticated data + * \param result The generated MIC will be put here + * \param mic_len The size of the MIC to be generated. <= 16. + * \param forward != 0 if used in forward direction. + */ + void (* aead)(const uint8_t* nonce, + uint8_t* m, uint8_t m_len, + const uint8_t* a, uint8_t a_len, + uint8_t *result, uint8_t mic_len, + int forward); +}; + +extern const struct ccm_star_driver CCM_STAR; + +#endif /* CCM_STAR_H_ */ diff --git a/core/lib/crc16.h b/core/lib/crc16.h index ad1f785c8..e243f546e 100644 --- a/core/lib/crc16.h +++ b/core/lib/crc16.h @@ -1,25 +1,3 @@ -/** \addtogroup lib - * @{ */ - -/** - * \defgroup crc16 Cyclic Redundancy Check 16 (CRC16) calculation - * - * The Cyclic Redundancy Check 16 is a hash function that produces a - * checksum that is used to detect errors in transmissions. The CRC16 - * calculation module is an iterative CRC calculator that can be used - * to cumulatively update a CRC checksum for every incoming byte. - * - * @{ - */ - -/** - * \file - * Header file for the CRC16 calculcation - * \author - * Adam Dunkels - * - */ - /* * Copyright (c) 2005, Swedish Institute of Computer Science * All rights reserved. @@ -51,6 +29,29 @@ * This file is part of the Contiki operating system. * */ + +/** + * \file + * Header file for the CRC16 calculcation + * \author + * Adam Dunkels + * + */ + +/** \addtogroup lib + * @{ */ + +/** + * \defgroup crc16 Cyclic Redundancy Check 16 (CRC16) calculation + * + * The Cyclic Redundancy Check 16 is a hash function that produces a + * checksum that is used to detect errors in transmissions. The CRC16 + * calculation module is an iterative CRC calculator that can be used + * to cumulatively update a CRC checksum for every incoming byte. + * + * @{ + */ + #ifndef CRC16_H_ #define CRC16_H_ @@ -76,7 +77,7 @@ unsigned short crc16_add(unsigned char b, unsigned short crc); * \brief Calculate the CRC16 over a data area * \param data Pointer to the data * \param datalen The length of the data - * \param crc The accumulated CRC that is to be updated (or zero). + * \param acc The accumulated CRC that is to be updated (or zero). * \return The CRC16 checksum. * * This function calculates the CRC16 checksum of a data area. diff --git a/core/lib/gcr.c b/core/lib/gcr.c index 1fba2f40b..36ee98ea2 100644 --- a/core/lib/gcr.c +++ b/core/lib/gcr.c @@ -64,13 +64,13 @@ static unsigned char gcr_bits = 0; static unsigned short gcr_val = 0; /* Call before starting encoding or decoding */ -void gcr_init() { +void gcr_init(void) { gcr_val = 0; gcr_bits = 0; } /* Use this to check if encoding / decoding is complete for now */ -unsigned char gcr_finished() { +unsigned char gcr_finished(void) { return gcr_bits == 0; } @@ -100,7 +100,7 @@ void gcr_decode(unsigned char gcr_data) { } /* check if the current decoded stream is correct */ -unsigned char gcr_valid() { +unsigned char gcr_valid(void) { if (gcr_bits >= 10) { unsigned short val = gcr_val & 0x3ff; if ((GCR_decode[val >> 5u] << 4u) == 0xff || diff --git a/core/lib/list.c b/core/lib/list.c index b8d4942d0..401da617e 100644 --- a/core/lib/list.c +++ b/core/lib/list.c @@ -1,16 +1,3 @@ -/** - * \addtogroup list - * @{ - */ - -/** - * \file - * Linked list library implementation. - * - * \author Adam Dunkels - * - */ - /* * Copyright (c) 2004, Swedish Institute of Computer Science. * All rights reserved. @@ -44,6 +31,20 @@ * Author: Adam Dunkels * */ + +/** + * \file + * Linked list library implementation. + * + * \author Adam Dunkels + * + */ + +/** + * \addtogroup list + * @{ + */ + #include "lib/list.h" #define NULL 0 diff --git a/core/lib/list.h b/core/lib/list.h index 48e51401e..0624682a2 100644 --- a/core/lib/list.h +++ b/core/lib/list.h @@ -1,37 +1,3 @@ -/** \addtogroup lib - @{ */ -/** - * \defgroup list Linked list library - * - * The linked list library provides a set of functions for - * manipulating linked lists. - * - * A linked list is made up of elements where the first element \b - * must be a pointer. This pointer is used by the linked list library - * to form lists of the elements. - * - * Lists are declared with the LIST() macro. The declaration specifies - * the name of the list that later is used with all list functions. - * - * Lists can be manipulated by inserting or removing elements from - * either sides of the list (list_push(), list_add(), list_pop(), - * list_chop()). A specified element can also be removed from inside a - * list with list_remove(). The head and tail of a list can be - * extracted using list_head() and list_tail(), respectively. - * - * @{ - */ - -/** - * \file - * Linked list manipulation routines. - * \author Adam Dunkels - * - * - */ - - - /* * Copyright (c) 2004, Swedish Institute of Computer Science. * All rights reserved. @@ -65,6 +31,38 @@ * Author: Adam Dunkels * */ + +/** + * \file + * Linked list manipulation routines. + * \author Adam Dunkels + * + */ + +/** \addtogroup lib + @{ */ +/** + * \defgroup list Linked list library + * + * The linked list library provides a set of functions for + * manipulating linked lists. + * + * A linked list is made up of elements where the first element \b + * must be a pointer. This pointer is used by the linked list library + * to form lists of the elements. + * + * Lists are declared with the LIST() macro. The declaration specifies + * the name of the list that later is used with all list functions. + * + * Lists can be manipulated by inserting or removing elements from + * either sides of the list (list_push(), list_add(), list_pop(), + * list_chop()). A specified element can also be removed from inside a + * list with list_remove(). The head and tail of a list can be + * extracted using list_head() and list_tail(), respectively. + * + * @{ + */ + #ifndef LIST_H_ #define LIST_H_ diff --git a/core/lib/memb.c b/core/lib/memb.c index f07414435..b4056dd9f 100644 --- a/core/lib/memb.c +++ b/core/lib/memb.c @@ -107,5 +107,18 @@ memb_inmemb(struct memb *m, void *ptr) (char *)ptr < (char *)m->mem + (m->num * m->size); } /*---------------------------------------------------------------------------*/ +int +memb_numfree(struct memb *m) +{ + int i; + int num_free = 0; + for(i = 0; i < m->num; ++i) { + if(m->count[i] == 0) { + ++num_free; + } + } + + return num_free; +} /** @} */ diff --git a/core/lib/memb.h b/core/lib/memb.h index f5e654cc1..d66e5a419 100644 --- a/core/lib/memb.h +++ b/core/lib/memb.h @@ -130,6 +130,7 @@ char memb_free(struct memb *m, void *ptr); int memb_inmemb(struct memb *m, void *ptr); +int memb_numfree(struct memb *m); /** @} */ /** @} */ diff --git a/core/lib/mmem.c b/core/lib/mmem.c index a6ff1b59c..20c7390fd 100644 --- a/core/lib/mmem.c +++ b/core/lib/mmem.c @@ -151,8 +151,13 @@ mmem_free(struct mmem *m) void mmem_init(void) { + static int inited = 0; + if(inited) { + return; + } list_init(mmemlist); avail_memory = MMEM_SIZE; + inited = 1; } /*---------------------------------------------------------------------------*/ diff --git a/core/lib/petsciiconv.c b/core/lib/petsciiconv.c index 348ee4f03..a6eda5979 100644 --- a/core/lib/petsciiconv.c +++ b/core/lib/petsciiconv.c @@ -72,16 +72,15 @@ static unsigned char ascii2petscii[128] = { 0x58,0x59,0x5a,0xdb,0xdd,0xdd,0x5e,0xdf, }; -static unsigned int i; -static unsigned char *ptr; - /*-----------------------------------------------------------------------------------*/ void petsciiconv_toascii(char *buf, unsigned int len) { - static char c; + unsigned int i; + char *ptr; + char c; - ptr = (unsigned char*)buf; + ptr = buf; for(i = len; i > 0; --i) { c = *ptr; if(c == 0x0a) { @@ -108,7 +107,10 @@ petsciiconv_toascii(char *buf, unsigned int len) void petsciiconv_topetscii(char *buf, unsigned int len) { - ptr = (unsigned char *)buf; + unsigned int i; + char *ptr; + + ptr = buf; for(i = len; i > 0; --i) { *ptr = ascii2petscii[*ptr & 0x7f]; ++ptr; diff --git a/core/lib/petsciiconv.h b/core/lib/petsciiconv.h index 87e9c916d..ba6b5ef5c 100644 --- a/core/lib/petsciiconv.h +++ b/core/lib/petsciiconv.h @@ -1,18 +1,3 @@ -/** - * \file - * PETSCII/ASCII conversion functions. - * \author Adam Dunkels - * - * The Commodore based Contiki targets all have a special character - * encoding called PETSCII which differs from the ASCII encoding that - * normally is used for representing characters. - * - * \note For targets that do not use PETSCII encoding the C compiler - * define WITH_ASCII should be used to avoid the PETSCII converting - * functions. - * - */ - /* * Copyright (c) 2002, Adam Dunkels. * All rights reserved. @@ -46,6 +31,22 @@ * * */ + +/** + * \file + * PETSCII/ASCII conversion functions. + * \author Adam Dunkels + * + * The Commodore based Contiki targets all have a special character + * encoding called PETSCII which differs from the ASCII encoding that + * normally is used for representing characters. + * + * \note For targets that do not use PETSCII encoding the C compiler + * define WITH_ASCII should be used to avoid the PETSCII converting + * functions. + * + */ + #ifndef PETSCIICONV_H_ #define PETSCIICONV_H_ diff --git a/core/lib/ringbuf.c b/core/lib/ringbuf.c index a10127c17..89bcad514 100644 --- a/core/lib/ringbuf.c +++ b/core/lib/ringbuf.c @@ -38,6 +38,7 @@ */ #include "lib/ringbuf.h" +#include /*---------------------------------------------------------------------------*/ void ringbuf_init(struct ringbuf *r, uint8_t *dataptr, uint8_t size) @@ -63,8 +64,15 @@ ringbuf_put(struct ringbuf *r, uint8_t c) if(((r->put_ptr - r->get_ptr) & r->mask) == r->mask) { return 0; } - r->data[r->put_ptr] = c; - r->put_ptr = (r->put_ptr + 1) & r->mask; + /* + * CC_ACCESS_NOW is used because the compiler is allowed to reorder + * the access to non-volatile variables. + * In this case a reader might read from the moved index/ptr before + * its value (c) is written. Reordering makes little sense, but + * better safe than sorry. + */ + CC_ACCESS_NOW(uint8_t, r->data[r->put_ptr]) = c; + CC_ACCESS_NOW(uint8_t, r->put_ptr) = (r->put_ptr + 1) & r->mask; return 1; } /*---------------------------------------------------------------------------*/ @@ -84,8 +92,17 @@ ringbuf_get(struct ringbuf *r) most platforms, but C does not guarantee this. */ if(((r->put_ptr - r->get_ptr) & r->mask) > 0) { - c = r->data[r->get_ptr]; - r->get_ptr = (r->get_ptr + 1) & r->mask; + /* + * CC_ACCESS_NOW is used because the compiler is allowed to reorder + * the access to non-volatile variables. + * In this case the memory might be freed and overwritten by + * increasing get_ptr before the value was copied to c. + * Opposed to the put-operation this would even make sense, + * because the register used for mask can be reused to save c + * (on some architectures). + */ + c = CC_ACCESS_NOW(uint8_t, r->data[r->get_ptr]); + CC_ACCESS_NOW(uint8_t, r->get_ptr) = (r->get_ptr + 1) & r->mask; return c; } else { return -1; diff --git a/core/lib/ringbuf.h b/core/lib/ringbuf.h index d1445519a..f49acc2eb 100644 --- a/core/lib/ringbuf.h +++ b/core/lib/ringbuf.h @@ -1,16 +1,3 @@ -/** \addtogroup lib - * @{ */ - -/** - * \defgroup ringbuf Ring buffer library - * @{ - * - * The ring buffer library implements ring (circular) buffer where - * bytes can be read and written independently. A ring buffer is - * particularly useful in device drivers where data can come in - * through interrupts. - * - */ /* * Copyright (c) 2008, Swedish Institute of Computer Science. * All rights reserved. @@ -50,6 +37,20 @@ * Adam Dunkels */ +/** \addtogroup lib + * @{ */ + +/** + * \defgroup ringbuf Ring buffer library + * @{ + * + * The ring buffer library implements ring (circular) buffer where + * bytes can be read and written independently. A ring buffer is + * particularly useful in device drivers where data can come in + * through interrupts. + * + */ + #ifndef RINGBUF_H_ #define RINGBUF_H_ diff --git a/core/lib/ringbufindex.c b/core/lib/ringbufindex.c new file mode 100644 index 000000000..0b2149ff7 --- /dev/null +++ b/core/lib/ringbufindex.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * ringbufindex library. Implements basic support for ring buffers + * of any type, as opposed to the core/lib/ringbuf module which + * is only for byte arrays. Simply returns index in the ringbuf + * rather than actual elements. The ringbuf size must be power of two. + * Like the original ringbuf, this module implements atomic put and get. + * \author + * Simon Duquennoy + * based on Contiki's core/lib/ringbuf library by Adam Dunkels + */ + +#include +#include "lib/ringbufindex.h" + +/* Initialize a ring buffer. The size must be a power of two */ +void +ringbufindex_init(struct ringbufindex *r, uint8_t size) +{ + r->mask = size - 1; + r->put_ptr = 0; + r->get_ptr = 0; +} +/* Put one element to the ring buffer */ +int +ringbufindex_put(struct ringbufindex *r) +{ + /* Check if buffer is full. If it is full, return 0 to indicate that + the element was not inserted. + + XXX: there is a potential risk for a race condition here, because + the ->get_ptr field may be written concurrently by the + ringbufindex_get() function. To avoid this, access to ->get_ptr must + be atomic. We use an uint8_t type, which makes access atomic on + most platforms, but C does not guarantee this. + */ + if(((r->put_ptr - r->get_ptr) & r->mask) == r->mask) { + return 0; + } + r->put_ptr = (r->put_ptr + 1) & r->mask; + return 1; +} +/* Check if there is space to put an element. + * Return the index where the next element is to be added */ +int +ringbufindex_peek_put(const struct ringbufindex *r) +{ + /* Check if there are bytes in the buffer. If so, we return the + first one. If there are no bytes left, we return -1. + */ + if(((r->put_ptr - r->get_ptr) & r->mask) == r->mask) { + return -1; + } + return (r->put_ptr + 1) & r->mask; +} +/* Remove the first element and return its index */ +int +ringbufindex_get(struct ringbufindex *r) +{ + int get_ptr; + + /* Check if there are bytes in the buffer. If so, we return the + first one and increase the pointer. If there are no bytes left, we + return -1. + + XXX: there is a potential risk for a race condition here, because + the ->put_ptr field may be written concurrently by the + ringbufindex_put() function. To avoid this, access to ->get_ptr must + be atomic. We use an uint8_t type, which makes access atomic on + most platforms, but C does not guarantee this. + */ + if(((r->put_ptr - r->get_ptr) & r->mask) > 0) { + get_ptr = r->get_ptr; + r->get_ptr = (r->get_ptr + 1) & r->mask; + return get_ptr; + } else { + return -1; + } +} +/* Return the index of the first element + * (which will be removed if calling ringbufindex_peek) */ +int +ringbufindex_peek_get(const struct ringbufindex *r) +{ + /* Check if there are bytes in the buffer. If so, we return the + first one. If there are no bytes left, we return -1. + */ + if(((r->put_ptr - r->get_ptr) & r->mask) > 0) { + return (r->get_ptr + 1) & r->mask; + } else { + return -1; + } +} +/* Return the ring buffer size */ +int +ringbufindex_size(const struct ringbufindex *r) +{ + return r->mask + 1; +} +/* Return the number of elements currently in the ring buffer */ +int +ringbufindex_elements(const struct ringbufindex *r) +{ + return (r->put_ptr - r->get_ptr) & r->mask; +} +/* Is the ring buffer full? */ +int +ringbufindex_full(const struct ringbufindex *r) +{ + return ((r->put_ptr - r->get_ptr) & r->mask) == r->mask; +} +/* Is the ring buffer empty? */ +int +ringbufindex_empty(const struct ringbufindex *r) +{ + return ringbufindex_elements(r) == 0; +} diff --git a/core/lib/ringbufindex.h b/core/lib/ringbufindex.h new file mode 100644 index 000000000..c39f99d18 --- /dev/null +++ b/core/lib/ringbufindex.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Header file for the ringbufindex library + * \author + * Simon Duquennoy + */ + +#ifndef __RINGBUFINDEX_H__ +#define __RINGBUFINDEX_H__ + +#include "contiki-conf.h" + +struct ringbufindex { + uint8_t mask; + /* These must be 8-bit quantities to avoid race conditions. */ + uint8_t put_ptr, get_ptr; +}; + +/* Initialize a ring buffer. The size must be a power of two */ +void ringbufindex_init(struct ringbufindex *r, uint8_t size); +/* Put one element to the ring buffer */ +int ringbufindex_put(struct ringbufindex *r); +/* Check if there is space to put an element. + * Return the index where the next element is to be added */ +int ringbufindex_peek_put(const struct ringbufindex *r); +/* Remove the first element and return its index */ +int ringbufindex_get(struct ringbufindex *r); +/* Return the index of the first element + * (which will be removed if calling ringbufindex_peek) */ +int ringbufindex_peek_get(const struct ringbufindex *r); +/* Return the ring buffer size */ +int ringbufindex_size(const struct ringbufindex *r); +/* Return the number of elements currently in the ring buffer */ +int ringbufindex_elements(const struct ringbufindex *r); +/* Is the ring buffer full? */ +int ringbufindex_full(const struct ringbufindex *r); +/* Is the ring buffer empty? */ +int ringbufindex_empty(const struct ringbufindex *r); + +#endif /* __RINGBUFINDEX_H__ */ diff --git a/core/lib/settings.c b/core/lib/settings.c index b085f7219..1b97b28b5 100644 --- a/core/lib/settings.c +++ b/core/lib/settings.c @@ -65,10 +65,6 @@ #define SETTINGS_BOTTOM_ADDR (SETTINGS_TOP_ADDR + 1 - SETTINGS_MAX_SIZE) #endif -#ifndef MIN -#define MIN(a,b) ((a)<(b)?a:b) -#endif - typedef struct { #if SETTINGS_CONF_SUPPORT_LARGE_VALUES uint8_t size_extra; diff --git a/core/lib/settings.h b/core/lib/settings.h index 79350c54d..bef6d0461 100644 --- a/core/lib/settings.h +++ b/core/lib/settings.h @@ -36,10 +36,14 @@ /** @file settings.h * @brief Settings Manager * @author Robert Quattlebaum + */ + +/** @addtogroup lib + * @{ */ + +/** @defgroup settings_lib Settings Manager * - * ## Overview ## - * - * The settings manager is a EEPROM-based key-value store. Keys + * The settings manager is an EEPROM-based key-value store. Keys * are 16-bit integers and values may be up to 16,383 bytes long. * It is intended to be used to store configuration-related information, * like network settings, radio channels, etc. @@ -64,37 +68,13 @@ * EEPROM. * * Each key-value pair is stored in memory in the following format: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    OrderSize (in bytes)NameDescription
    02key
    -21size_checkOne's-complement of next byte
    -31 or 2sizeThe size of the value, in bytes.
    -4 or -5variablevalue
    + * + * | Order | Size | Name | Description | + * | -------- | -------- | ---------- | ------------------------------- | + * | 0 | 2 | key | | + * | -2 | 1 | size_check | One's-complement of next byte | + * | -3 | 1 or 2 | size | The size of the value, in bytes | + * | -4 or -5 | variable | value | | * * The end of the key-value pairs is denoted by the first invalid entry. * An invalid entry has any of the following attributes: @@ -103,7 +83,7 @@ * of the size byte (or size_low byte). * * The key has a value of 0x0000. * - */ + * @{ */ #include #include @@ -156,9 +136,9 @@ typedef uint16_t settings_length_t; /** Use this when you want to retrieve the last item */ #define SETTINGS_LAST_INDEX 0xFF - +/** Returned when key is invalid. */ #define SETTINGS_INVALID_KEY 0xFFFF - +/** Returned if no (further) element was found. */ #define SETTINGS_INVALID_ITER EEPROM_NULL #ifndef SETTINGS_CONF_SUPPORT_LARGE_VALUES @@ -205,10 +185,10 @@ extern settings_status_t settings_delete(settings_key_t key, uint8_t index); typedef eeprom_addr_t settings_iter_t; -/** Will return extern SETTINGS_INVALID_ITER if the settings store is empty. */ -extern settings_iter_t settings_iter_begin(); +/** Will return \ref SETTINGS_INVALID_ITER if the settings store is empty. */ +extern settings_iter_t settings_iter_begin(void); -/** Will return extern SETTINGS_INVALID_ITER if at the end of settings list. */ +/** Will return \ref SETTINGS_INVALID_ITER if at the end of settings list. */ extern settings_iter_t settings_iter_next(settings_iter_t iter); extern uint8_t settings_iter_is_valid(settings_iter_t iter); @@ -367,3 +347,6 @@ settings_set_uint64(settings_key_t key, uint64_t value) #endif /* !SETTINGS_CONF_SKIP_CONVENIENCE_FUNCS */ #endif /* !defined(CONTIKI_SETTINGS_H_) */ + +/** @} */ +/** @} */ diff --git a/core/lib/trickle-timer.c b/core/lib/trickle-timer.c index 97a620767..fd2d7c537 100644 --- a/core/lib/trickle-timer.c +++ b/core/lib/trickle-timer.c @@ -1,15 +1,3 @@ -/** - * \addtogroup trickle-timer - * @{ - */ - -/** - * \file - * Trickle timer library implementation. - * \author - * George Oikonomou - - */ - /* * Copyright (c) 2012, George Oikonomou - * All rights reserved. @@ -40,6 +28,19 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ + +/** + * \file + * Trickle timer library implementation. + * \author + * George Oikonomou - + */ + +/** + * \addtogroup trickle-timer + * @{ + */ + #include "contiki-conf.h" #include "lib/trickle-timer.h" #include "sys/ctimer.h" @@ -78,7 +79,7 @@ static void double_interval(void *ptr); #if TRICKLE_TIMER_WIDE_RAND /* Returns a 4-byte wide, unsigned random number */ static uint32_t -wide_rand() +wide_rand(void) { return ((uint32_t)random_rand() << 16 | random_rand()); } diff --git a/core/lib/trickle-timer.h b/core/lib/trickle-timer.h index b1cf765bc..bf56cea53 100644 --- a/core/lib/trickle-timer.h +++ b/core/lib/trickle-timer.h @@ -1,3 +1,42 @@ +/* + * Copyright (c) 2012, George Oikonomou - + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ + +/** + * \file + * Trickle timer library header file. + * + * \author + * George Oikonomou - + */ + /** \addtogroup lib * @{ */ @@ -29,45 +68,6 @@ * @{ */ - -/** - * \file - * Trickle timer library header file. - * - * \author - * George Oikonomou - - */ - -/* - * Copyright (c) 2012, George Oikonomou - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the copyright holder 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. - */ #ifndef TRICKLE_TIMER_H_ #define TRICKLE_TIMER_H_ diff --git a/core/loader/dlloader.c b/core/loader/dlloader.c index 88987bbfb..7d3e8320e 100644 --- a/core/loader/dlloader.c +++ b/core/loader/dlloader.c @@ -62,7 +62,7 @@ dlloader_load(char *path, char *arg) /* Start the process. */ printf("Starting '%s'\n", PROCESS_NAME_STRING(*p)); - process_start(*p, arg); + process_start(*p, (void *)arg); return LOADER_OK; } diff --git a/core/loader/elfloader-msp430x.c b/core/loader/elfloader-msp430x.c new file mode 100644 index 000000000..32e1126f3 --- /dev/null +++ b/core/loader/elfloader-msp430x.c @@ -0,0 +1,810 @@ +/* + * Copyright (c) 2015, Indian Institute of Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * MSP430x elfloader. + * \author + * Sumankumar Panchal + * + */ + +#include "contiki.h" +#include "loader/elfloader.h" +#include "loader/elfloader-arch.h" +#include "cfs/cfs.h" +#include "loader/symtab.h" +#include +#include +#include +#include "dev/flash.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) do {} while(0) +#endif + +#define EI_NIDENT 16 + +struct elf32_ehdr { + unsigned char e_ident[EI_NIDENT]; /* ident bytes */ + elf32_half e_type; /* file type */ + elf32_half e_machine; /* target machine */ + elf32_word e_version; /* file version */ + elf32_addr e_entry; /* start address */ + elf32_off e_phoff; /* phdr file offset */ + elf32_off e_shoff; /* shdr file offset */ + elf32_word e_flags; /* file flags */ + elf32_half e_ehsize; /* sizeof ehdr */ + elf32_half e_phentsize; /* sizeof phdr */ + elf32_half e_phnum; /* number phdrs */ + elf32_half e_shentsize; /* sizeof shdr */ + elf32_half e_shnum; /* number shdrs */ + elf32_half e_shstrndx; /* shdr string index */ +}; + +/* Values for e_type. */ +#define ET_NONE 0 /* Unknown type. */ +#define ET_REL 1 /* Relocatable. */ +#define ET_EXEC 2 /* Executable. */ +#define ET_DYN 3 /* Shared object. */ +#define ET_CORE 4 /* Core file. */ + +struct elf32_shdr { + elf32_word sh_name; /* section name */ + elf32_word sh_type; /* SHT_... */ + elf32_word sh_flags; /* SHF_... */ + elf32_addr sh_addr; /* virtual address */ + elf32_off sh_offset; /* file offset */ + elf32_word sh_size; /* section size */ + elf32_word sh_link; /* misc info */ + elf32_word sh_info; /* misc info */ + elf32_word sh_addralign; /* memory alignment */ + elf32_word sh_entsize; /* entry size if table */ +}; + +/* sh_type */ +#define SHT_NULL 0 /* inactive */ +#define SHT_PROGBITS 1 /* program defined information */ +#define SHT_SYMTAB 2 /* symbol table section */ +#define SHT_STRTAB 3 /* string table section */ +#define SHT_RELA 4 /* relocation section with addends*/ +#define SHT_HASH 5 /* symbol hash table section */ +#define SHT_DYNAMIC 6 /* dynamic section */ +#define SHT_NOTE 7 /* note section */ +#define SHT_NOBITS 8 /* no space section */ +#define SHT_REL 9 /* relation section without addends */ +#define SHT_SHLIB 10 /* reserved - purpose unknown */ +#define SHT_DYNSYM 11 /* dynamic symbol table section */ +#define SHT_LOPROC 0x70000000 /* reserved range for processor */ +#define SHT_HIPROC 0x7fffffff /* specific section header types */ +#define SHT_LOUSER 0x80000000 /* reserved range for application */ +#define SHT_HIUSER 0xffffffff /* specific indexes */ + +struct elf32_rel { + elf32_addr r_offset; /* Location to be relocated. */ + elf32_word r_info; /* Relocation type and symbol index. */ +}; + +struct elf32_sym { + elf32_word st_name; /* String table index of name. */ + elf32_addr st_value; /* Symbol value. */ + elf32_word st_size; /* Size of associated object. */ + unsigned char st_info; /* Type and binding information. */ + unsigned char st_other; /* Reserved (not used). */ + elf32_half st_shndx; /* Section index of symbol. */ +}; + +#define ELF32_R_SYM(info) ((info) >> 8) + +struct relevant_section { + unsigned char number; + unsigned int offset; + char *address; +}; + +char elfloader_unknown[30]; /* Name that caused link error. */ + +struct process *const *elfloader_autostart_processes; + +static struct relevant_section bss, data, rodata, rodatafar, text, textfar; + +static const unsigned char elf_magic_header[] = +{ 0x7f, 0x45, 0x4c, 0x46, /* 0x7f, 'E', 'L', 'F' */ + 0x01, /* Only 32-bit objects. */ + 0x01, /* Only LSB data. */ + 0x01, /* Only ELF version 1. */ +}; + +/* relocation type */ +#define R_MSP430_NONE 0 +#define R_MSP430_32 1 +#define R_MSP430_10_PCREL 2 +#define R_MSP430_16 3 +#define R_MSP430_16_PCREL 4 +#define R_MSP430_16_BYTE 5 +#define R_MSP430_16_PCREL_BYTE 6 +#define R_MSP430_2X_PCREL 7 +#define R_MSP430_RL_PCREL 8 +#define R_MSP430X_SRC_BYTE 9 +#define R_MSP430X_SRC 10 +#define R_MSP430X_DST_BYTE 11 +#define R_MSP430X_DST 12 +#define R_MSP430X_DST_2ND_BYTE 13 +#define R_MSP430X_DST_2ND 14 +#define R_MSP430X_PCREL_SRC_BYTE 15 +#define R_MSP430X_PCREL_SRC 16 +#define R_MSP430X_PCREL_DST_BYTE 17 +#define R_MSP430X_PCREL_DST 18 +#define R_MSP430X_PCREL_DST_2ND 19 +#define R_MSP430X_PCREL_DST_2ND_BYTE 20 +#define R_MSP430X_S_BYTE 21 +#define R_MSP430X_S 22 +#define R_MSP430X_D_BYTE 23 +#define R_MSP430X_D 24 +#define R_MSP430X_PCREL_D 25 +#define R_MSP430X_INDXD 26 +#define R_MSP430X_PCREL_INDXD 27 +#define R_MSP430_10 28 + +#define ELF32_R_TYPE(info) ((unsigned char)(info)) + +static uint16_t datamemory_aligned[ELFLOADER_DATAMEMORY_SIZE / 2 + 1]; +static uint8_t *datamemory = (uint8_t *)datamemory_aligned; +#if ELFLOADER_CONF_TEXT_IN_ROM +static const char textmemory[ELFLOADER_TEXTMEMORY_SIZE] = { 0 }; +#else /* ELFLOADER_CONF_TEXT_IN_ROM */ +static char textmemory[ELFLOADER_TEXTMEMORY_SIZE]; +#endif /* ELFLOADER_CONF_TEXT_IN_ROM */ + +/*---------------------------------------------------------------------------*/ +static void +seek_read(int fd, unsigned int offset, char *buf, int len) +{ + cfs_seek(fd, offset, CFS_SEEK_SET); + cfs_read(fd, buf, len); +#if DEBUG + { + int i; + PRINTF("seek_read: Read len %d from offset %d\n", + len, offset); + for(i = 0; i < len; ++i) { + PRINTF("%02x ", buf[i]); + } + printf("\n"); + } +#endif /* DEBUG */ +} +/*---------------------------------------------------------------------------*/ +static void * +find_local_symbol(int fd, const char *symbol, + unsigned int symtab, unsigned short symtabsize, + unsigned int strtab) +{ + struct elf32_sym s; + unsigned int a; + char name[30]; + struct relevant_section *sect; + + for(a = symtab; a < symtab + symtabsize; a += sizeof(s)) { + seek_read(fd, a, (char *)&s, sizeof(s)); + if(s.st_name != 0) { + seek_read(fd, strtab + s.st_name, name, sizeof(name)); + if(strcmp(name, symbol) == 0) { + if(s.st_shndx == bss.number) { + sect = &bss; + } else if(s.st_shndx == data.number) { + sect = &data; + } else if(s.st_shndx == rodatafar.number) { + sect = &rodatafar; + } else if(s.st_shndx == textfar.number) { + sect = &textfar; + } else { + return NULL; + } + return &(sect->address[s.st_value]); + } + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +static int +relocate_section(int fd, + unsigned int section, unsigned short size, + unsigned int sectionaddr, + char *sectionbase, + unsigned int strs, + unsigned int strtab, + unsigned int symtab, unsigned short symtabsize, + unsigned char using_relas) +{ + /* + * sectionbase added; runtime start address of current section + */ + struct elf32_rela rela; /* Now used both for rel and rela data! */ + int rel_size = 0; + struct elf32_sym s; + unsigned int a; + char name[30]; + char *addr; + struct relevant_section *sect; + + /* determine correct relocation entry sizes */ + if(using_relas) { + rel_size = sizeof(struct elf32_rela); + } else { + rel_size = sizeof(struct elf32_rel); + } + + for(a = section; a < section + size; a += rel_size) { + seek_read(fd, a, (char *)&rela, rel_size); + seek_read(fd, + symtab + sizeof(struct elf32_sym) * ELF32_R_SYM(rela.r_info), + (char *)&s, sizeof(s)); + if(s.st_name != 0) { + seek_read(fd, strtab + s.st_name, name, sizeof(name)); + PRINTF("name: %s\n", name); + addr = (char *)symtab_lookup(name); + if(addr == NULL) { + PRINTF("name not found in global: %s\n", name); + addr = find_local_symbol(fd, name, symtab, symtabsize, strtab); + PRINTF("found address %p\n", addr); + } + if(addr == NULL) { + if(s.st_shndx == bss.number) { + sect = &bss; + } else if(s.st_shndx == data.number) { + sect = &data; + } else if(s.st_shndx == rodatafar.number) { + sect = &rodatafar; + } else if(s.st_shndx == textfar.number) { + sect = &textfar; + } else { + PRINTF("elfloader unknown name: '%30s'\n", name); + memcpy(elfloader_unknown, name, sizeof(elfloader_unknown)); + elfloader_unknown[sizeof(elfloader_unknown) - 1] = 0; + return ELFLOADER_SYMBOL_NOT_FOUND; + } + + addr = sect->address; + } + } else { + if(s.st_shndx == bss.number) { + sect = &bss; + } else if(s.st_shndx == data.number) { + sect = &data; + } else if(s.st_shndx == rodatafar.number) { + sect = &rodatafar; + } else if(s.st_shndx == textfar.number) { + sect = &textfar; + } else { + return ELFLOADER_SEGMENT_NOT_FOUND; + } + + addr = sect->address; + } + + if(!using_relas) { + /* copy addend to rela structure */ + seek_read(fd, sectionaddr + rela.r_offset, (char *)&rela.r_addend, 4); + } + + elfloader_arch_relocate(fd, sectionaddr, sectionbase, &rela, addr); + } + + return ELFLOADER_OK; +} +/*---------------------------------------------------------------------------*/ +static void * +find_program_processes(int fd, + unsigned int symtab, unsigned short size, + unsigned int strtab) +{ + struct elf32_sym s; + unsigned int a; + char name[30]; + + for(a = symtab; a < symtab + size; a += sizeof(s)) { + seek_read(fd, a, (char *)&s, sizeof(s)); + + if(s.st_name != 0) { + seek_read(fd, strtab + s.st_name, name, sizeof(name)); + if(strcmp(name, "autostart_processes") == 0) { + return &data.address[s.st_value]; + } + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +void +elfloader_init(void) +{ + elfloader_autostart_processes = NULL; +} +/*---------------------------------------------------------------------------*/ +int +elfloader_load(int fd) +{ + struct elf32_ehdr ehdr; + struct elf32_shdr shdr; + struct elf32_shdr strtable; + unsigned int strs; + unsigned int shdrptr; + unsigned int nameptr; + char name[17]; + + int i; + unsigned short shdrnum, shdrsize; + + unsigned char using_relas = -1; + unsigned short textoff = 0, textfaroff = 0, textsize, textfarsize, + textrelaoff = 0, textrelasize, textfarrelaoff = 0, textfarrelasize; + unsigned short dataoff = 0, datasize, datarelaoff = 0, datarelasize; + unsigned short rodataoff = 0, rodatafaroff = 0, rodatasize, rodatafarsize, + rodatarelaoff = 0, rodatarelasize, rodatafarrelaoff = 0, + rodatafarrelasize; + unsigned short symtaboff = 0, symtabsize; + unsigned short strtaboff = 0, strtabsize; + unsigned short bsssize = 0; + + struct process **process; + int ret; + + elfloader_unknown[0] = 0; + + /* The ELF header is located at the start of the buffer. */ + seek_read(fd, 0, (char *)&ehdr, sizeof(ehdr)); + + /* Make sure that we have a correct and compatible ELF header. */ + if(memcmp(ehdr.e_ident, elf_magic_header, sizeof(elf_magic_header)) != 0) { + PRINTF("ELF header problems\n"); + return ELFLOADER_BAD_ELF_HEADER; + } + + /* Grab the section header. */ + shdrptr = ehdr.e_shoff; + seek_read(fd, shdrptr, (char *)&shdr, sizeof(shdr)); + + /* Get the size and number of entries of the section header. */ + shdrsize = ehdr.e_shentsize; + shdrnum = ehdr.e_shnum; + + PRINTF("Section header: size %d num %d\n", shdrsize, shdrnum); + + /* The string table section: holds the names of the sections. */ + seek_read(fd, ehdr.e_shoff + shdrsize * ehdr.e_shstrndx, + (char *)&strtable, sizeof(strtable)); + + /* + * Get a pointer to the actual table of strings. This table holds + * the names of the sections, not the names of other symbols in the + * file (these are in the sybtam section). + */ + strs = strtable.sh_offset; + + PRINTF("Strtable offset %d\n", strs); + + /* + * Go through all sections and pick out the relevant ones. The + * ".text" and ".far.text" segments holds the actual code from + * the ELF file. The ".data" segment contains initialized data. + * The ".bss" segment holds the size of the unitialized data segment. + * The ".rodata" and ".far.rodata" segments contains constant data. + * The ".rela[a].text" and ".rela[a].far.text" segments contains + * relocation information for the contents of the ".text" and + * ".far.text" segments, respectively. The ".rela[a].rodata" and + * ".rela[a].far.rodata" segments contains relocation information + * for the contents of the ".rodata" and ".far.rodata" segments, + * respectively. The ".rela[a].data" segment contains relocation + * information for the contents of the ".data" segment. The ".symtab" + * segment contains the symbol table for this file. The ".strtab" + * segment points to the actual string names used by the symbol table. + * + * In addition to grabbing pointers to the relevant sections, we + * also save the section number for resolving addresses in the + * relocator code. + */ + + /* + * Initialize the segment sizes to zero so that we can check if + * their sections was found in the file or not. + */ + textsize = textfarsize = textrelasize = textfarrelasize = + datasize = datarelasize = rodatasize = rodatafarsize = + rodatarelasize = rodatafarrelasize = symtabsize = strtabsize = 0; + + bss.number = data.number = rodata.number = rodatafar.number = + text.number = textfar.number = -1; + + shdrptr = ehdr.e_shoff; + for(i = 0; i < shdrnum; ++i) { + seek_read(fd, shdrptr, (char *)&shdr, sizeof(shdr)); + + /* The name of the section is contained in the strings table. */ + nameptr = strs + shdr.sh_name; + seek_read(fd, nameptr, name, sizeof(name)); + PRINTF("Section shdrptr 0x%x, %d + %d type %d\n", + shdrptr, + strs, shdr.sh_name, + (int)shdr.sh_type); + /* + * Match the name of the section with a predefined set of names + * (.text, .far.text, .data, .bss, .rodata, .far.rodata, .rela.text, .rela.far.text, + * .rela.data, .rela.rodata, .rela.far.rodata, .symtab, and .strtab). + */ + + if(shdr.sh_type == SHT_SYMTAB) { + PRINTF("symtab\n"); + symtaboff = shdr.sh_offset; + symtabsize = shdr.sh_size; + } else if(shdr.sh_type == SHT_STRTAB) { + PRINTF("strtab\n"); + strtaboff = shdr.sh_offset; + strtabsize = shdr.sh_size; + } else if(strncmp(name, ".text", 5) == 0) { + textoff = shdr.sh_offset; + textsize = shdr.sh_size; + text.number = i; + text.offset = textoff; + } else if(strncmp(name, ".far.text", 9) == 0) { + textfaroff = shdr.sh_offset; + textfarsize = shdr.sh_size; + textfar.number = i; + textfar.offset = textfaroff; + } else if(strncmp(name, ".rel.text", 9) == 0) { + using_relas = 0; + textrelaoff = shdr.sh_offset; + textrelasize = shdr.sh_size; + } else if(strncmp(name, ".rela.text", 10) == 0) { + using_relas = 1; + textrelaoff = shdr.sh_offset; + textrelasize = shdr.sh_size; + } else if(strncmp(name, ".rela.far.text", 14) == 0) { + using_relas = 1; + textfarrelaoff = shdr.sh_offset; + textfarrelasize = shdr.sh_size; + } else if(strncmp(name, ".data", 5) == 0) { + dataoff = shdr.sh_offset; + datasize = shdr.sh_size; + data.number = i; + data.offset = dataoff; + } else if(strncmp(name, ".rodata", 7) == 0) { + /* read-only data handled the same way as regular text section */ + rodataoff = shdr.sh_offset; + rodatasize = shdr.sh_size; + rodata.number = i; + rodata.offset = rodataoff; + } else if(strncmp(name, ".far.rodata", 11) == 0) { + rodatafaroff = shdr.sh_offset; + rodatafarsize = shdr.sh_size; + rodatafar.number = i; + rodatafar.offset = rodataoff; + } else if(strncmp(name, ".rel.rodata", 11) == 0) { + /* using elf32_rel instead of rela */ + using_relas = 0; + rodatarelaoff = shdr.sh_offset; + rodatarelasize = shdr.sh_size; + } else if(strncmp(name, ".rela.rodata", 12) == 0) { + using_relas = 1; + rodatarelaoff = shdr.sh_offset; + rodatarelasize = shdr.sh_size; + } else if(strncmp(name, ".rela.far.rodata", 16) == 0) { + using_relas = 1; + rodatafarrelaoff = shdr.sh_offset; + rodatafarrelasize = shdr.sh_size; + } else if(strncmp(name, ".rel.data", 9) == 0) { + /* using elf32_rel instead of rela */ + using_relas = 0; + datarelaoff = shdr.sh_offset; + datarelasize = shdr.sh_size; + } else if(strncmp(name, ".rela.data", 10) == 0) { + using_relas = 1; + datarelaoff = shdr.sh_offset; + datarelasize = shdr.sh_size; + } else if(strncmp(name, ".bss", 4) == 0) { + bsssize = shdr.sh_size; + bss.number = i; + bss.offset = 0; + } + + /* Move on to the next section header. */ + shdrptr += shdrsize; + } + if(symtabsize == 0) { + return ELFLOADER_NO_SYMTAB; + } + if(strtabsize == 0) { + return ELFLOADER_NO_STRTAB; + } + if(textfarsize == 0) { + return ELFLOADER_NO_TEXT; + } + + PRINTF("before allocate ram\n"); + bss.address = (char *)elfloader_arch_allocate_ram(bsssize + datasize); + data.address = (char *)bss.address + bsssize; + PRINTF("before allocate rom\n"); + textfar.address = (char *)elfloader_arch_allocate_rom(textfarsize + rodatafarsize); + rodatafar.address = (char *)textfar.address + textfarsize; + + PRINTF("bss base address: bss.address = 0x%08x\n", bss.address); + PRINTF("data base address: data.address = 0x%08x\n", data.address); + PRINTF("textfar base address: textfar.address = 0x%08x\n", textfar.address); + PRINTF("rodatafar base address: rodatafar.address = 0x%08x\n", rodatafar.address); + + /* If we have text segment relocations, we process them. */ + PRINTF("elfloader: relocate textfar\n"); + if(textfarrelasize > 0) { + ret = relocate_section(fd, + textfarrelaoff, textfarrelasize, + textfaroff, + textfar.address, + strs, + strtaboff, + symtaboff, symtabsize, using_relas); + if(ret != ELFLOADER_OK) { + return ret; + } + } + + /* If we have any rodata segment relocations, we process them too. */ + PRINTF("elfloader: relocate rodata\n"); + if(rodatafarrelasize > 0) { + ret = relocate_section(fd, + rodatafarrelaoff, rodatafarrelasize, + rodatafaroff, + rodatafar.address, + strs, + strtaboff, + symtaboff, symtabsize, using_relas); + if(ret != ELFLOADER_OK) { + PRINTF("elfloader: data failed\n"); + return ret; + } + } + + /* If we have any data segment relocations, we process them too. */ + PRINTF("elfloader: relocate data\n"); + if(datarelasize > 0) { + ret = relocate_section(fd, + datarelaoff, datarelasize, + dataoff, + data.address, + strs, + strtaboff, + symtaboff, symtabsize, using_relas); + if(ret != ELFLOADER_OK) { + PRINTF("elfloader: data failed\n"); + return ret; + } + } + + /* Write text and rodata segment into flash and data segment into RAM. */ + elfloader_arch_write_rom(fd, textfaroff, textfarsize, textfar.address); + elfloader_arch_write_rom(fd, rodatafaroff, rodatafarsize, rodatafar.address); + + memset(bss.address, 0, bsssize); + seek_read(fd, dataoff, data.address, datasize); + + PRINTF("elfloader: autostart search\n"); + process = (struct process **)find_local_symbol(fd, "autostart_processes", + symtaboff, symtabsize, strtaboff); + if(process != NULL) { + PRINTF("elfloader: autostart found\n"); + elfloader_autostart_processes = process; + return ELFLOADER_OK; + } else { + PRINTF("elfloader: no autostart\n"); + process = (struct process **)find_program_processes(fd, symtaboff, + symtabsize, strtaboff); + if(process != NULL) { + PRINTF("elfloader: FOUND PRG\n"); + } + return ELFLOADER_NO_STARTPOINT; + } +} +/*---------------------------------------------------------------------------*/ +void * +elfloader_arch_allocate_ram(int size) +{ + return datamemory; +} +/*---------------------------------------------------------------------------*/ +void * +elfloader_arch_allocate_rom(int size) +{ +#if ELFLOADER_CONF_TEXT_IN_ROM + /* Return an 512-byte aligned pointer. */ + return (char *) + ((unsigned long)&textmemory[0] & 0xfffffe00) + + (((unsigned long)&textmemory[0] & 0x1ff) == 0 ? 0 : 0x200); +#else /* ELFLOADER_CONF_TEXT_IN_ROM */ + return textmemory; +#endif /* ELFLOADER_CONF_TEXT_IN_ROM */ +} +/*---------------------------------------------------------------------------*/ +#define READSIZE 32 +void +elfloader_arch_write_rom(int fd, unsigned short textoff, unsigned int size, char *mem) +{ +#if ELFLOADER_CONF_TEXT_IN_ROM + int i; + unsigned int ptr; + unsigned short *flashptr; + + flash_setup(); + + flashptr = (unsigned short *)mem; + + cfs_seek(fd, textoff, CFS_SEEK_SET); + for(ptr = 0; ptr < size; ptr += READSIZE) { + + /* Read data from file into RAM. */ + cfs_read(fd, (unsigned char *)datamemory, READSIZE); + + /* Clear flash page on 512 byte boundary. */ + if((((unsigned short)flashptr) & 0x01ff) == 0) { + flash_clear(flashptr); + } + + /* + * Burn data from RAM into flash ROM. Flash is burned one 16-bit + * word at a time, so we need to be careful when incrementing + * pointers. The flashptr is already a short pointer, so + * incrementing it by one will actually increment the address by + * two. + */ + for(i = 0; i < READSIZE / 2; ++i) { + flash_write(flashptr, ((unsigned short *)datamemory)[i]); + ++flashptr; + } + } + + flash_done(); +#else /* ELFLOADER_CONF_TEXT_IN_ROM */ + cfs_seek(fd, textoff, CFS_SEEK_SET); + cfs_read(fd, (unsigned char *)mem, size); +#endif /* ELFLOADER_CONF_TEXT_IN_ROM */ +} +/*---------------------------------------------------------------------------*/ +/* Relocate an MSP430X ELF section. */ +void +elfloader_arch_relocate(int fd, unsigned int sectionoffset, + char *sectionaddr, + struct elf32_rela *rela, char *addr) +{ + unsigned int type; + unsigned char instr[2]; + + type = ELF32_R_TYPE(rela->r_info); + addr += rela->r_addend; + + switch(type) { + case R_MSP430_16: + case R_MSP430_16_PCREL: + case R_MSP430_16_BYTE: + case R_MSP430_16_PCREL_BYTE: + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430_32: + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_S: + case R_MSP430X_S_BYTE: + /* src(19:16) located at positions 11:8 of opcode */ + /* src(15:0) located just after opcode */ + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_read(fd, instr, 2); + instr[1] = (int)(instr[1]) & 0xf0 | (((long int)addr >> 8) & 0x0f00); + instr[0] = (int)(instr[0]) & 0xff; + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, instr, 2); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_D: + case R_MSP430X_PCREL_D: + case R_MSP430X_D_BYTE: + /* dst(19:16) located at positions 3:0 of opcode */ + /* dst(15:0) located just after opcode */ + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_read(fd, instr, 2); + instr[1] = (int)(instr[1]) & 0xff; + instr[0] = (int)(instr[0]) & 0xf0 | (((long int)addr >> 16) & 0x000f); + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, instr, 2); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_PCREL_SRC_BYTE: + case R_MSP430X_SRC_BYTE: + case R_MSP430X_PCREL_SRC: + case R_MSP430X_SRC: + /* src(19:16) located at positions 10:7 of extension word */ + /* src(15:0) located just after opcode */ + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_read(fd, instr, 2); + /* 4 most-significant bits */ + instr[1] = (int)(instr[1]) & 0xf8 | (((long int)addr >> 9) & 0x0780); + instr[0] = (int)(instr[0]) & 0x7f | (((long int)addr >> 9) & 0x0780); + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, instr, 2); + /* 16 least-significant bits */ + cfs_seek(fd, sectionoffset + rela->r_offset + 0x04, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_DST_BYTE: + case R_MSP430X_PCREL_DST_BYTE: + case R_MSP430X_DST: + case R_MSP430X_PCREL_DST: + /* dst(19:16) located at positions 3:0 of extension word */ + /* dst(15:0) located just after opcode */ + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_read(fd, instr, 2); + instr[1] = (int)(instr[1]) & 0xff; + instr[0] = (int)(instr[0]) & 0xf0 | (((long int)addr >> 16) & 0x000f); + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, instr, 2); + cfs_seek(fd, sectionoffset + rela->r_offset + 0x04, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_DST_2ND: + case R_MSP430X_PCREL_DST_2ND: + case R_MSP430X_DST_2ND_BYTE: + case R_MSP430X_PCREL_DST_2ND_BYTE: + /* dst(19:16) located at positions 3:0 of extension word */ + /* dst(15:0) located after src(15:0) */ + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_read(fd, instr, 2); + instr[1] = (int)(instr[1]) & 0xff; + instr[0] = (int)(instr[0]) & 0xf0 | (((long int)addr >> 16) & 0x000f); + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, instr, 2); + cfs_seek(fd, sectionoffset + rela->r_offset + 0x06, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_INDXD: + case R_MSP430X_PCREL_INDXD: + cfs_seek(fd, sectionoffset + rela->r_offset + 0x02, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + default: + PRINTF("Unknown relocation type!\n"); + break; + } +} +/*---------------------------------------------------------------------------*/ diff --git a/core/loader/elfloader.h b/core/loader/elfloader.h index 6c144c271..9588ac33f 100644 --- a/core/loader/elfloader.h +++ b/core/loader/elfloader.h @@ -1,3 +1,43 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Header file for the Contiki ELF loader. + * \author + * Adam Dunkels + * + */ + /** * \addtogroup loader * @{ @@ -32,45 +72,6 @@ * @{ */ -/** - * \file - * Header file for the Contiki ELF loader. - * \author - * Adam Dunkels - * - */ - -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ #ifndef ELFLOADER_H_ #define ELFLOADER_H_ diff --git a/core/net/http-socket/http-socket.c b/core/net/http-socket/http-socket.c new file mode 100644 index 000000000..b08605213 --- /dev/null +++ b/core/net/http-socket/http-socket.c @@ -0,0 +1,696 @@ +/* + * Copyright (c) 2013, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + */ +#include "contiki-net.h" +#include "ip64-addr.h" +#include "http-socket.h" + +#include +#include + +#define MAX_PATHLEN 80 +#define MAX_HOSTLEN 40 +PROCESS(http_socket_process, "HTTP socket process"); +LIST(socketlist); + +static void removesocket(struct http_socket *s); +/*---------------------------------------------------------------------------*/ +static void +call_callback(struct http_socket *s, http_socket_event_t e, + const uint8_t *data, uint16_t datalen) +{ + if(s->callback != NULL) { + s->callback(s, s->callbackptr, e, + data, datalen); + } +} +/*---------------------------------------------------------------------------*/ +static void +parse_header_init(struct http_socket *s) +{ + PT_INIT(&s->headerpt); +} +/*---------------------------------------------------------------------------*/ +static int +parse_header_byte(struct http_socket *s, char c) +{ + PT_BEGIN(&s->headerpt); + + memset(&s->header, -1, sizeof(s->header)); + + /* Skip the HTTP response */ + while(c != ' ') { + PT_YIELD(&s->headerpt); + } + + /* Skip the space */ + PT_YIELD(&s->headerpt); + /* Read three characters of HTTP status and convert to BCD */ + s->header.status_code = 0; + for(s->header_chars = 0; s->header_chars < 3; s->header_chars++) { + s->header.status_code = s->header.status_code << 4 | (c - '0'); + PT_YIELD(&s->headerpt); + } + + if(s->header.status_code == 0x200 || s->header.status_code == 0x206) { + /* Read headers until data */ + + while(1) { + /* Skip characters until end of line */ + do { + while(c != '\r') { + s->header_chars++; + PT_YIELD(&s->headerpt); + } + s->header_chars++; + PT_YIELD(&s->headerpt); + } while(c != '\n'); + s->header_chars--; + PT_YIELD(&s->headerpt); + + if(s->header_chars == 0) { + /* This was an empty line, i.e. the end of headers */ + break; + } + + /* Start of line */ + s->header_chars = 0; + + /* Read header field */ + while(c != ' ' && c != '\t' && c != ':' && c != '\r' && + s->header_chars < sizeof(s->header_field) - 1) { + s->header_field[s->header_chars++] = c; + PT_YIELD(&s->headerpt); + } + s->header_field[s->header_chars] = '\0'; + /* Skip linear white spaces */ + while(c == ' ' || c == '\t') { + s->header_chars++; + PT_YIELD(&s->headerpt); + } + if(c == ':') { + /* Skip the colon */ + s->header_chars++; + PT_YIELD(&s->headerpt); + /* Skip linear white spaces */ + while(c == ' ' || c == '\t') { + s->header_chars++; + PT_YIELD(&s->headerpt); + } + if(!strcmp(s->header_field, "Content-Length")) { + s->header.content_length = 0; + while(isdigit((int)c)) { + s->header.content_length = s->header.content_length * 10 + c - '0'; + s->header_chars++; + PT_YIELD(&s->headerpt); + } + } else if(!strcmp(s->header_field, "Content-Range")) { + /* Skip the bytes-unit token */ + while(c != ' ' && c != '\t') { + s->header_chars++; + PT_YIELD(&s->headerpt); + } + /* Skip linear white spaces */ + while(c == ' ' || c == '\t') { + s->header_chars++; + PT_YIELD(&s->headerpt); + } + s->header.content_range.first_byte_pos = 0; + while(isdigit((int)c)) { + s->header.content_range.first_byte_pos = + s->header.content_range.first_byte_pos * 10 + c - '0'; + s->header_chars++; + PT_YIELD(&s->headerpt); + } + /* Skip linear white spaces */ + while(c == ' ' || c == '\t') { + s->header_chars++; + PT_YIELD(&s->headerpt); + } + if(c == '-') { + /* Skip the dash */ + s->header_chars++; + PT_YIELD(&s->headerpt); + /* Skip linear white spaces */ + while(c == ' ' || c == '\t') { + s->header_chars++; + PT_YIELD(&s->headerpt); + } + s->header.content_range.last_byte_pos = 0; + while(isdigit((int)c)) { + s->header.content_range.last_byte_pos = + s->header.content_range.last_byte_pos * 10 + c - '0'; + s->header_chars++; + PT_YIELD(&s->headerpt); + } + /* Skip linear white spaces */ + while(c == ' ' || c == '\t') { + s->header_chars++; + PT_YIELD(&s->headerpt); + } + if(c == '/') { + /* Skip the slash */ + s->header_chars++; + PT_YIELD(&s->headerpt); + /* Skip linear white spaces */ + while(c == ' ' || c == '\t') { + s->header_chars++; + PT_YIELD(&s->headerpt); + } + if(c != '*') { + s->header.content_range.instance_length = 0; + while(isdigit((int)c)) { + s->header.content_range.instance_length = + s->header.content_range.instance_length * 10 + c - '0'; + s->header_chars++; + PT_YIELD(&s->headerpt); + } + } + } + } + } + } + } + + /* All headers read, now read data */ + call_callback(s, HTTP_SOCKET_HEADER, (void *)&s->header, sizeof(s->header)); + + /* Should exit the pt here to indicate that all headers have been + read */ + PT_EXIT(&s->headerpt); + } else { + if(s->header.status_code == 0x404) { + printf("File not found\n"); + } else if(s->header.status_code == 0x301 || s->header.status_code == 0x302) { + printf("File moved (not handled)\n"); + } + + call_callback(s, HTTP_SOCKET_ERR, (void *)&s->header, sizeof(s->header)); + tcp_socket_close(&s->s); + removesocket(s); + PT_EXIT(&s->headerpt); + } + + + PT_END(&s->headerpt); +} +/*---------------------------------------------------------------------------*/ +static int +input_pt(struct http_socket *s, + const uint8_t *inputptr, int inputdatalen) +{ + int i; + PT_BEGIN(&s->pt); + + /* Parse the header */ + s->header_received = 0; + do { + for(i = 0; i < inputdatalen; i++) { + if(!PT_SCHEDULE(parse_header_byte(s, inputptr[i]))) { + s->header_received = 1; + break; + } + } + inputdatalen -= i; + inputptr += i; + + if(s->header_received == 0) { + /* If we have not yet received the full header, we wait for the + next packet to arrive. */ + PT_YIELD(&s->pt); + } + } while(s->header_received == 0); + + s->bodylen = 0; + do { + /* Receive the data */ + call_callback(s, HTTP_SOCKET_DATA, inputptr, inputdatalen); + + /* Close the connection if the expected content length has been received */ + if(s->header.content_length >= 0 && s->bodylen < s->header.content_length) { + s->bodylen += inputdatalen; + if(s->bodylen >= s->header.content_length) { + tcp_socket_close(&s->s); + } + } + + PT_YIELD(&s->pt); + } while(inputdatalen > 0); + + PT_END(&s->pt); +} +/*---------------------------------------------------------------------------*/ +static void +start_timeout_timer(struct http_socket *s) +{ + PROCESS_CONTEXT_BEGIN(&http_socket_process); + etimer_set(&s->timeout_timer, HTTP_SOCKET_TIMEOUT); + PROCESS_CONTEXT_END(&http_socket_process); + s->timeout_timer_started = 1; +} +/*---------------------------------------------------------------------------*/ +static int +input(struct tcp_socket *tcps, void *ptr, + const uint8_t *inputptr, int inputdatalen) +{ + struct http_socket *s = ptr; + + input_pt(s, inputptr, inputdatalen); + start_timeout_timer(s); + + return 0; /* all data consumed */ +} +/*---------------------------------------------------------------------------*/ +static int +parse_url(const char *url, char *host, uint16_t *portptr, char *path) +{ + const char *urlptr; + int i; + const char *file; + uint16_t port; + + if(url == NULL) { + printf("null url\n"); + return 0; + } + + /* Don't even try to go further if the URL is empty. */ + if(strlen(url) == 0) { + printf("empty url\n"); + return 0; + } + + /* See if the URL starts with http:// and remove it. Otherwise, we + assume it is an implicit http://. */ + if(strncmp(url, "http://", strlen("http://")) == 0) { + urlptr = url + strlen("http://"); + } else { + urlptr = url; + } + + /* Find host part of the URL. */ + if(*urlptr == '[') { + /* Handle IPv6 addresses - scan for matching ']' */ + urlptr++; + for(i = 0; i < MAX_HOSTLEN; ++i) { + if(*urlptr == ']') { + if(host != NULL) { + host[i] = 0; + } + urlptr++; + break; + } + if(host != NULL) { + host[i] = *urlptr; + } + ++urlptr; + } + } else { + for(i = 0; i < MAX_HOSTLEN; ++i) { + if(*urlptr == 0 || + *urlptr == '/' || + *urlptr == ' ' || + *urlptr == ':') { + if(host != NULL) { + host[i] = 0; + } + break; + } + if(host != NULL) { + host[i] = *urlptr; + } + ++urlptr; + } + } + + /* check if host is null terminated */ + if(!memchr(host, 0, MAX_HOSTLEN)) { + return 0; + } + + /* Find the port. Default is 80. */ + port = 80; + if(*urlptr == ':') { + port = 0; + do { + ++urlptr; + if(*urlptr >= '0' && *urlptr <= '9') { + port = (10 * port) + (*urlptr - '0'); + } + } while(*urlptr >= '0' && + *urlptr <= '9'); + } + if(portptr != NULL) { + *portptr = port; + } + /* Find file part of the URL. */ + while(*urlptr != '/' && *urlptr != 0) { + ++urlptr; + } + if(*urlptr == '/') { + file = urlptr; + } else { + file = "/"; + } + if(path != NULL) { + strncpy(path, file, MAX_PATHLEN); + } + return 1; +} +/*---------------------------------------------------------------------------*/ +static void +removesocket(struct http_socket *s) +{ + etimer_stop(&s->timeout_timer); + s->timeout_timer_started = 0; + list_remove(socketlist, s); +} +/*---------------------------------------------------------------------------*/ +static void +event(struct tcp_socket *tcps, void *ptr, + tcp_socket_event_t e) +{ + struct http_socket *s = ptr; + char host[MAX_HOSTLEN]; + char path[MAX_PATHLEN]; + uint16_t port; + char str[42]; + int len; + + if(e == TCP_SOCKET_CONNECTED) { + printf("Connected\n"); + if(parse_url(s->url, host, &port, path)) { + tcp_socket_send_str(tcps, s->postdata != NULL ? "POST " : "GET "); + if(s->proxy_port != 0) { + /* If we are configured to route through a proxy, we should + provide the full URL as the path. */ + tcp_socket_send_str(tcps, s->url); + } else { + tcp_socket_send_str(tcps, path); + } + tcp_socket_send_str(tcps, " HTTP/1.1\r\n"); + tcp_socket_send_str(tcps, "Connection: close\r\n"); + tcp_socket_send_str(tcps, "Host: "); + /* If we have IPv6 host, add the '[' and the ']' characters + to the host. As in rfc2732. */ + if(memchr(host, ':', MAX_HOSTLEN)) { + tcp_socket_send_str(tcps, "["); + } + tcp_socket_send_str(tcps, host); + if(memchr(host, ':', MAX_HOSTLEN)) { + tcp_socket_send_str(tcps, "]"); + } + tcp_socket_send_str(tcps, "\r\n"); + if(s->postdata != NULL) { + if(s->content_type) { + tcp_socket_send_str(tcps, "Content-Type: "); + tcp_socket_send_str(tcps, s->content_type); + tcp_socket_send_str(tcps, "\r\n"); + } + tcp_socket_send_str(tcps, "Content-Length: "); + sprintf(str, "%u", s->postdatalen); + tcp_socket_send_str(tcps, str); + tcp_socket_send_str(tcps, "\r\n"); + } else if(s->length || s->pos > 0) { + tcp_socket_send_str(tcps, "Range: bytes="); + if(s->length) { + if(s->pos >= 0) { + sprintf(str, "%llu-%llu", s->pos, s->pos + s->length - 1); + } else { + sprintf(str, "-%llu", s->length); + } + } else { + sprintf(str, "%llu-", s->pos); + } + tcp_socket_send_str(tcps, str); + tcp_socket_send_str(tcps, "\r\n"); + } + tcp_socket_send_str(tcps, "\r\n"); + if(s->postdata != NULL && s->postdatalen) { + len = tcp_socket_send(tcps, s->postdata, s->postdatalen); + s->postdata += len; + s->postdatalen -= len; + } + } + parse_header_init(s); + } else if(e == TCP_SOCKET_CLOSED) { + call_callback(s, HTTP_SOCKET_CLOSED, NULL, 0); + removesocket(s); + printf("Closed\n"); + } else if(e == TCP_SOCKET_TIMEDOUT) { + call_callback(s, HTTP_SOCKET_TIMEDOUT, NULL, 0); + removesocket(s); + printf("Timedout\n"); + } else if(e == TCP_SOCKET_ABORTED) { + call_callback(s, HTTP_SOCKET_ABORTED, NULL, 0); + removesocket(s); + printf("Aborted\n"); + } else if(e == TCP_SOCKET_DATA_SENT) { + if(s->postdata != NULL && s->postdatalen) { + len = tcp_socket_send(tcps, s->postdata, s->postdatalen); + s->postdata += len; + s->postdatalen -= len; + } else { + start_timeout_timer(s); + } + } +} +/*---------------------------------------------------------------------------*/ +static int +start_request(struct http_socket *s) +{ + uip_ip4addr_t ip4addr; + uip_ip6addr_t ip6addr; + uip_ip6addr_t *addr; + char host[MAX_HOSTLEN]; + char path[MAX_PATHLEN]; + uint16_t port; + int ret; + + if(parse_url(s->url, host, &port, path)) { + + printf("url %s host %s port %d path %s\n", + s->url, host, port, path); + + /* Check if we are to route the request through a proxy. */ + if(s->proxy_port != 0) { + /* The proxy address should be an IPv6 address. */ + uip_ip6addr_copy(&ip6addr, &s->proxy_addr); + port = s->proxy_port; + } else if(uiplib_ip6addrconv(host, &ip6addr) == 0) { + /* First check if the host is an IP address. */ + if(uiplib_ip4addrconv(host, &ip4addr) != 0) { + ip64_addr_4to6(&ip4addr, &ip6addr); + } else { + /* Try to lookup the hostname. If it fails, we initiate a hostname + lookup. */ + ret = resolv_lookup(host, &addr); + if(ret == RESOLV_STATUS_UNCACHED || + ret == RESOLV_STATUS_EXPIRED) { + resolv_query(host); + puts("Resolving host..."); + return HTTP_SOCKET_OK; + } + if(addr != NULL) { + s->did_tcp_connect = 1; + tcp_socket_connect(&s->s, addr, port); + return HTTP_SOCKET_OK; + } else { + return HTTP_SOCKET_ERR; + } + } + } + tcp_socket_connect(&s->s, &ip6addr, port); + return HTTP_SOCKET_OK; + } else { + return HTTP_SOCKET_ERR; + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(http_socket_process, ev, data) +{ + PROCESS_BEGIN(); + + while(1) { + + PROCESS_WAIT_EVENT(); + + if(ev == resolv_event_found && data != NULL) { + struct http_socket *s; + const char *name = data; + /* Either found a hostname, or not. We need to go through the + list of http sockets and figure out to which connection this + reply corresponds, then either restart the HTTP get, or kill + it (if no hostname was found). */ + for(s = list_head(socketlist); + s != NULL; + s = list_item_next(s)) { + char host[MAX_HOSTLEN]; + if(s->did_tcp_connect) { + /* We already connected, ignored */ + } else if(parse_url(s->url, host, NULL, NULL) && + strcmp(name, host) == 0) { + if(resolv_lookup(name, NULL) == RESOLV_STATUS_CACHED) { + /* Hostname found, restart get. */ + start_request(s); + } else { + /* Hostname not found, kill connection. */ + call_callback(s, HTTP_SOCKET_HOSTNAME_NOT_FOUND, NULL, 0); + removesocket(s); + } + } + } + } else if(ev == PROCESS_EVENT_TIMER) { + struct http_socket *s; + struct etimer *timeout_timer = data; + /* + * A socket time-out has occurred. We need to go through the list of HTTP + * sockets and figure out to which socket this timer event corresponds, + * then close this socket. + */ + for(s = list_head(socketlist); + s != NULL; + s = list_item_next(s)) { + if(timeout_timer == &s->timeout_timer && s->timeout_timer_started) { + tcp_socket_close(&s->s); + break; + } + } + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + static uint8_t inited = 0; + if(inited == 0) { + process_start(&http_socket_process, NULL); + list_init(socketlist); + inited = 1; + } +} +/*---------------------------------------------------------------------------*/ +void +http_socket_init(struct http_socket *s) +{ + init(); + uip_create_unspecified(&s->proxy_addr); + s->proxy_port = 0; +} +/*---------------------------------------------------------------------------*/ +static void +initialize_socket(struct http_socket *s) +{ + s->pos = 0; + s->length = 0; + s->postdata = NULL; + s->postdatalen = 0; + s->timeout_timer_started = 0; + PT_INIT(&s->pt); + tcp_socket_register(&s->s, s, + s->inputbuf, sizeof(s->inputbuf), + s->outputbuf, sizeof(s->outputbuf), + input, event); +} +/*---------------------------------------------------------------------------*/ +int +http_socket_get(struct http_socket *s, + const char *url, + int64_t pos, + uint64_t length, + http_socket_callback_t callback, + void *callbackptr) +{ + initialize_socket(s); + strncpy(s->url, url, sizeof(s->url)); + s->pos = pos; + s->length = length; + s->callback = callback; + s->callbackptr = callbackptr; + + s->did_tcp_connect = 0; + + list_add(socketlist, s); + + return start_request(s); +} +/*---------------------------------------------------------------------------*/ +int +http_socket_post(struct http_socket *s, + const char *url, + const void *postdata, + uint16_t postdatalen, + const char *content_type, + http_socket_callback_t callback, + void *callbackptr) +{ + initialize_socket(s); + strncpy(s->url, url, sizeof(s->url)); + s->postdata = postdata; + s->postdatalen = postdatalen; + s->content_type = content_type; + + s->callback = callback; + s->callbackptr = callbackptr; + + s->did_tcp_connect = 0; + + list_add(socketlist, s); + + return start_request(s); +} +/*---------------------------------------------------------------------------*/ +int +http_socket_close(struct http_socket *socket) +{ + struct http_socket *s; + for(s = list_head(socketlist); + s != NULL; + s = list_item_next(s)) { + if(s == socket) { + tcp_socket_close(&s->s); + removesocket(s); + return 1; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +void +http_socket_set_proxy(struct http_socket *s, + const uip_ipaddr_t *addr, uint16_t port) +{ + uip_ipaddr_copy(&s->proxy_addr, addr); + s->proxy_port = port; +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/http-socket/http-socket.h b/core/net/http-socket/http-socket.h new file mode 100644 index 000000000..5b683e10b --- /dev/null +++ b/core/net/http-socket/http-socket.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + */ +#ifndef HTTP_SOCKET_H +#define HTTP_SOCKET_H + +#include "tcp-socket.h" + +struct http_socket; + +typedef enum { + HTTP_SOCKET_ERR, + HTTP_SOCKET_OK, + HTTP_SOCKET_HEADER, + HTTP_SOCKET_DATA, + HTTP_SOCKET_CLOSED, + HTTP_SOCKET_TIMEDOUT, + HTTP_SOCKET_ABORTED, + HTTP_SOCKET_HOSTNAME_NOT_FOUND, +} http_socket_event_t; + +struct http_socket_header { + uint16_t status_code; + int64_t content_length; + struct { + int64_t first_byte_pos; + int64_t last_byte_pos; + int64_t instance_length; + } content_range; +}; + +typedef void (* http_socket_callback_t)(struct http_socket *s, + void *ptr, + http_socket_event_t ev, + const uint8_t *data, + uint16_t datalen); + +#define MAX(n, m) (((n) < (m)) ? (m) : (n)) + +#define HTTP_SOCKET_INPUTBUFSIZE UIP_TCP_MSS +#define HTTP_SOCKET_OUTPUTBUFSIZE MAX(UIP_TCP_MSS, 128) + +#define HTTP_SOCKET_URLLEN 128 + +#define HTTP_SOCKET_TIMEOUT ((2 * 60 + 30) * CLOCK_SECOND) + +struct http_socket { + struct http_socket *next; + struct tcp_socket s; + uip_ipaddr_t proxy_addr; + uint16_t proxy_port; + int64_t pos; + uint64_t length; + const uint8_t *postdata; + uint16_t postdatalen; + http_socket_callback_t callback; + void *callbackptr; + int did_tcp_connect; + char url[HTTP_SOCKET_URLLEN]; + uint8_t inputbuf[HTTP_SOCKET_INPUTBUFSIZE]; + uint8_t outputbuf[HTTP_SOCKET_OUTPUTBUFSIZE]; + + struct etimer timeout_timer; + uint8_t timeout_timer_started; + struct pt pt, headerpt; + int header_chars; + char header_field[15]; + struct http_socket_header header; + uint8_t header_received; + uint64_t bodylen; + const char *content_type; +}; + +void http_socket_init(struct http_socket *s); + +int http_socket_get(struct http_socket *s, const char *url, + int64_t pos, uint64_t length, + http_socket_callback_t callback, + void *callbackptr); + +int http_socket_post(struct http_socket *s, const char *url, + const void *postdata, + uint16_t postdatalen, + const char *content_type, + http_socket_callback_t callback, + void *callbackptr); + +int http_socket_close(struct http_socket *socket); + +void http_socket_set_proxy(struct http_socket *s, + const uip_ipaddr_t *addr, uint16_t port); + + +#endif /* HTTP_SOCKET_H */ diff --git a/core/net/ip/dhcpc.c b/core/net/ip/dhcpc.c index 46ba826da..08023f1e4 100644 --- a/core/net/ip/dhcpc.c +++ b/core/net/ip/dhcpc.c @@ -300,7 +300,6 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data)) } selecting: - xid++; s.ticks = CLOCK_SECOND; do { while(ev != tcpip_event) { @@ -366,7 +365,6 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data)) } /* renewing: */ - xid++; do { while(ev != tcpip_event) { tcpip_poll_udp(s.conn); diff --git a/core/net/ip/ip64-addr.c b/core/net/ip/ip64-addr.c new file mode 100644 index 000000000..4d1fa378e --- /dev/null +++ b/core/net/ip/ip64-addr.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#include "ip64-addr.h" + +#include +#include + +#define printf(...) +/*---------------------------------------------------------------------------*/ +void +ip64_addr_copy4(uip_ip4addr_t *dest, const uip_ip4addr_t *src) +{ + memcpy(dest, src, sizeof(uip_ip4addr_t)); +} +/*---------------------------------------------------------------------------*/ +void +ip64_addr_copy6(uip_ip6addr_t *dest, const uip_ip6addr_t *src) +{ + memcpy(dest, src, sizeof(uip_ip6addr_t)); +} +/*---------------------------------------------------------------------------*/ +int +ip64_addr_4to6(const uip_ip4addr_t *ipv4addr, + uip_ip6addr_t *ipv6addr) +{ + /* This function converts an IPv4 addresses into an IPv6 + addresses. It returns 0 if it failed to convert the address and + non-zero if it could successfully convert the address. */ + + /* The IPv4 address is encoded as an IPv6-encoded IPv4 address in + the ::ffff:0000/24 prefix.*/ + ipv6addr->u8[0] = 0; + ipv6addr->u8[1] = 0; + ipv6addr->u8[2] = 0; + ipv6addr->u8[3] = 0; + ipv6addr->u8[4] = 0; + ipv6addr->u8[5] = 0; + ipv6addr->u8[6] = 0; + ipv6addr->u8[7] = 0; + ipv6addr->u8[8] = 0; + ipv6addr->u8[9] = 0; + ipv6addr->u8[10] = 0xff; + ipv6addr->u8[11] = 0xff; + ipv6addr->u8[12] = ipv4addr->u8[0]; + ipv6addr->u8[13] = ipv4addr->u8[1]; + ipv6addr->u8[14] = ipv4addr->u8[2]; + ipv6addr->u8[15] = ipv4addr->u8[3]; + printf("ip64_addr_4to6: IPv6-encoded IPv4 address %d.%d.%d.%d\n", + ipv4addr->u8[0], ipv4addr->u8[1], + ipv4addr->u8[2], ipv4addr->u8[3]); + + /* Conversion succeeded, we return non-zero. */ + return 1; +} +/*---------------------------------------------------------------------------*/ +int +ip64_addr_6to4(const uip_ip6addr_t *ipv6addr, + uip_ip4addr_t *ipv4addr) +{ + /* This function converts IPv6 addresses to IPv4 addresses. It + returns 0 if it failed to convert the address and non-zero if it + could successfully convert the address. */ + + /* If the IPv6 address is an IPv6-encoded + IPv4 address (i.e. in the ::ffff:0/8 prefix), we simply use the + IPv4 addresses directly. */ + if(ipv6addr->u8[0] == 0 && + ipv6addr->u8[1] == 0 && + ipv6addr->u8[2] == 0 && + ipv6addr->u8[3] == 0 && + ipv6addr->u8[4] == 0 && + ipv6addr->u8[5] == 0 && + ipv6addr->u8[6] == 0 && + ipv6addr->u8[7] == 0 && + ipv6addr->u8[8] == 0 && + ipv6addr->u8[9] == 0 && + ipv6addr->u8[10] == 0xff && + ipv6addr->u8[11] == 0xff) { + ipv4addr->u8[0] = ipv6addr->u8[12]; + ipv4addr->u8[1] = ipv6addr->u8[13]; + ipv4addr->u8[2] = ipv6addr->u8[14]; + ipv4addr->u8[3] = ipv6addr->u8[15]; + + printf("ip64_addr_6to4: IPv6-encoded IPv4 address %d.%d.%d.%d\n", + ipv4addr->u8[0], ipv4addr->u8[1], + ipv4addr->u8[2], ipv4addr->u8[3]); + + /* Conversion succeeded, we return non-zero. */ + return 1; + } + /* We could not convert the IPv6 address, so we return 0. */ + return 0; +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/ip/ip64-addr.h b/core/net/ip/ip64-addr.h new file mode 100644 index 000000000..3027d846a --- /dev/null +++ b/core/net/ip/ip64-addr.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#ifndef IP64_ADDR_H +#define IP64_ADDR_H + +#include "net/ip/uip.h" + + +/** + * \brief Is IPv4-mapped Address + * + * See https://tools.ietf.org/html/rfc6890#page-14 + */ +#define ip64_addr_is_ipv4_mapped_addr(a) \ + ((((a)->u16[0]) == 0) && \ + (((a)->u16[1]) == 0) && \ + (((a)->u16[2]) == 0) && \ + (((a)->u16[3]) == 0) && \ + (((a)->u16[4]) == 0) && \ + (((a)->u16[5]) == 0xFFFF)) + +void ip64_addr_copy4(uip_ip4addr_t *dest, const uip_ip4addr_t *src); + +void ip64_addr_copy6(uip_ip6addr_t *dest, const uip_ip6addr_t *src); + +int ip64_addr_6to4(const uip_ip6addr_t *ipv6addr, + uip_ip4addr_t *ipv4addr); + +int ip64_addr_4to6(const uip_ip4addr_t *ipv4addr, + uip_ip6addr_t *ipv6addr); + + +#endif /* IP64_ADDR_H */ + diff --git a/core/net/ip/resolv.c b/core/net/ip/resolv.c index 3480c561b..a0b40c32d 100644 --- a/core/net/ip/resolv.c +++ b/core/net/ip/resolv.c @@ -1,34 +1,3 @@ -/** - * \addtogroup uip - * @{ - */ - -/** - * \defgroup uipdns uIP hostname resolver functions - * @{ - * - * The uIP DNS resolver functions are used to lookup a hostname and - * map it to a numerical IP address. It maintains a list of resolved - * hostnames that can be queried with the resolv_lookup() - * function. New hostnames can be resolved using the resolv_query() - * function. - * - * The event resolv_event_found is posted when a hostname has been - * resolved. It is up to the receiving process to determine if the - * correct hostname has been found by calling the resolv_lookup() - * function with the hostname. - */ - -/** - * \file - * DNS host name to IP address resolver. - * \author Adam Dunkels - * \author Robert Quattlebaum - * - * This file implements a DNS host name to IP address resolver, - * as well as an MDNS responder and resolver. - */ - /* * Copyright (c) 2002-2003, Adam Dunkels. * All rights reserved. @@ -62,9 +31,41 @@ * */ +/** + * \file + * DNS host name to IP address resolver. + * \author Adam Dunkels + * \author Robert Quattlebaum + * + * This file implements a DNS host name to IP address resolver, + * as well as an MDNS responder and resolver. + */ + +/** + * \addtogroup uip + * @{ + */ + +/** + * \defgroup uipdns uIP hostname resolver functions + * @{ + * + * The uIP DNS resolver functions are used to lookup a hostname and + * map it to a numerical IP address. It maintains a list of resolved + * hostnames that can be queried with the resolv_lookup() + * function. New hostnames can be resolved using the resolv_query() + * function. + * + * The event resolv_event_found is posted when a hostname has been + * resolved. It is up to the receiving process to determine if the + * correct hostname has been found by calling the resolv_lookup() + * function with the hostname. + */ + #include "net/ip/tcpip.h" #include "net/ip/resolv.h" #include "net/ip/uip-udp-packet.h" +#include "net/ip/uip-nameserver.h" #include "lib/random.h" #ifndef DEBUG @@ -110,6 +111,9 @@ strcasecmp(const char *s1, const char *s2) /* TODO: Add case support! */ return strcmp(s1, s2); } +#else +int strcasecmp(const char *s1, const char *s2); +int strncasecmp(const char *s1, const char *s2, size_t n); #endif /* __SDCC */ #define UIP_UDP_BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN]) @@ -185,7 +189,7 @@ strcasecmp(const char *s1, const char *s2) #define DNS_TYPE_ANY 255 #define DNS_TYPE_NSEC 47 -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #define NATIVE_DNS_TYPE DNS_TYPE_AAAA /* IPv6 */ #else #define NATIVE_DNS_TYPE DNS_TYPE_A /* IPv4 */ @@ -227,20 +231,6 @@ struct dns_hdr { uint16_t numextrarr; }; -#define RESOLV_ENCODE_INDEX(i) (uip_htons(i+1)) -#define RESOLV_DECODE_INDEX(i) (unsigned char)(uip_ntohs(i-1)) - -/** These default values for the DNS server are Google's public DNS: - * - */ -static uip_ipaddr_t resolv_default_dns_server = -#if UIP_CONF_IPV6 - { { 0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88 } }; -#else /* UIP_CONF_IPV6 */ - { { 8, 8, 8, 8 } }; -#endif /* UIP_CONF_IPV6 */ - /** \internal The DNS answer message structure. */ struct dns_answer { /* DNS answer record starts with either a domain name or a pointer @@ -249,7 +239,7 @@ struct dns_answer { uint16_t class; uint16_t ttl[2]; uint16_t len; -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 uint8_t ipaddr[16]; #else uint8_t ipaddr[4]; @@ -264,6 +254,7 @@ struct namemap { #define STATE_DONE 4 uint8_t state; uint8_t tmr; + uint16_t id; uint8_t retries; uint8_t seqno; #if RESOLV_SUPPORTS_RECORD_EXPIRATION @@ -271,6 +262,7 @@ struct namemap { #endif /* RESOLV_SUPPORTS_RECORD_EXPIRATION */ uip_ipaddr_t ipaddr; uint8_t err; + uint8_t server; #if RESOLV_CONF_SUPPORTS_MDNS int is_mdns:1, is_probe:1; #endif @@ -315,13 +307,13 @@ enum { static uint8_t mdns_state; static const uip_ipaddr_t resolv_mdns_addr = -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb } }; #include "net/ipv6/uip-ds6.h" -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ { { 224, 0, 0, 251 } }; -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ static int mdns_needs_host_announce; PROCESS(mdns_probe_process, "mDNS probe"); @@ -405,7 +397,7 @@ dns_name_isequal(const unsigned char *queryptr, const char *name, return 0; } - if(tolower(*name++) != tolower(*queryptr++)) { + if(tolower((unsigned int)*name++) != tolower((unsigned int)*queryptr++)) { return 0; } } @@ -506,14 +498,13 @@ start_name_collision_check(clock_time_t after) static unsigned char * mdns_write_announce_records(unsigned char *queryptr, uint8_t *count) { - -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 uint8_t i; for(i = 0; i < UIP_DS6_ADDR_NB; ++i) { if(uip_ds6_if.addr_list[i].isused #if !RESOLV_CONF_MDNS_INCLUDE_GLOBAL_V6_ADDRS - && uip_is_addr_link_local(&uip_ds6_if.addr_list[i].ipaddr) + && uip_is_addr_linklocal(&uip_ds6_if.addr_list[i].ipaddr) #endif ) { if(!*count) { @@ -543,8 +534,9 @@ mdns_write_announce_records(unsigned char *queryptr, uint8_t *count) ++(*count); } } -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ struct dns_answer *ans; + queryptr = encode_name(queryptr, resolv_hostname); ans = (struct dns_answer *)queryptr; ans->type = UIP_HTONS(NATIVE_DNS_TYPE); @@ -555,7 +547,7 @@ mdns_write_announce_records(unsigned char *queryptr, uint8_t *count) uip_gethostaddr((uip_ipaddr_t *) ans->ipaddr); queryptr = (unsigned char *)ans + sizeof(*ans); ++(*count); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ return queryptr; } /*---------------------------------------------------------------------------*/ @@ -584,17 +576,17 @@ mdns_prep_host_announce_packet(void) 0x00, 0x04, -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 0x00, 0x00, 0x00, 0x08, -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ 0x40, 0x00, 0x00, 0x00, -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ } }; @@ -639,6 +631,21 @@ mdns_prep_host_announce_packet(void) } #endif /* RESOLV_CONF_SUPPORTS_MDNS */ /*---------------------------------------------------------------------------*/ +static char +try_next_server(struct namemap *namemapptr) +{ +#if VERBOSE_DEBUG + printf("server %d\n", namemapptr->server); +#endif + namemapptr->server++; + if(uip_nameserver_get(namemapptr->server) != NULL) { + namemapptr->retries = 0; + return 1; + } + namemapptr->server = 0; + return 0; +} +/*---------------------------------------------------------------------------*/ /** \internal * Runs through the list of names to see if there are any that have * not yet been queried and, if so, sends out a query. @@ -668,16 +675,20 @@ check_entries(void) if(++namemapptr->retries == RESOLV_CONF_MAX_RETRIES) #endif /* RESOLV_CONF_SUPPORTS_MDNS */ { - /* STATE_ERROR basically means "not found". */ - namemapptr->state = STATE_ERROR; + /* Try the next server (if possible) before failing. Otherwise + simply mark the entry as failed. */ + if(try_next_server(namemapptr) == 0) { + /* STATE_ERROR basically means "not found". */ + namemapptr->state = STATE_ERROR; #if RESOLV_SUPPORTS_RECORD_EXPIRATION - /* Keep the "not found" error valid for 30 seconds */ - namemapptr->expiration = clock_seconds() + 30; + /* Keep the "not found" error valid for 30 seconds */ + namemapptr->expiration = clock_seconds() + 30; #endif /* RESOLV_SUPPORTS_RECORD_EXPIRATION */ - resolv_found(namemapptr->name, NULL); - continue; + resolv_found(namemapptr->name, NULL); + continue; + } } namemapptr->tmr = namemapptr->retries * namemapptr->retries * 3; @@ -700,7 +711,8 @@ check_entries(void) } hdr = (struct dns_hdr *)uip_appdata; memset(hdr, 0, sizeof(struct dns_hdr)); - hdr->id = RESOLV_ENCODE_INDEX(i); + hdr->id = random_rand(); + namemapptr->id = hdr->id; #if RESOLV_CONF_SUPPORTS_MDNS if(!namemapptr->is_mdns || namemapptr->is_probe) { hdr->flags1 = DNS_FLAG1_RD; @@ -748,7 +760,9 @@ check_entries(void) } else { uip_udp_packet_sendto(resolv_conn, uip_appdata, (query - (uint8_t *) uip_appdata), - &resolv_default_dns_server, UIP_HTONS(DNS_PORT)); + (const uip_ipaddr_t *) + uip_nameserver_get(namemapptr->server), + UIP_HTONS(DNS_PORT)); PRINTF("resolver: (i=%d) Sent DNS request for \"%s\".\n", i, namemapptr->name); @@ -756,7 +770,8 @@ check_entries(void) #else /* RESOLV_CONF_SUPPORTS_MDNS */ uip_udp_packet_sendto(resolv_conn, uip_appdata, (query - (uint8_t *) uip_appdata), - &resolv_default_dns_server, UIP_HTONS(DNS_PORT)); + uip_nameserver_get(namemapptr->server), + UIP_HTONS(DNS_PORT)); PRINTF("resolver: (i=%d) Sent DNS request for \"%s\".\n", i, namemapptr->name); #endif /* RESOLV_CONF_SUPPORTS_MDNS */ @@ -771,11 +786,11 @@ check_entries(void) static void newdata(void) { - static uint8_t nquestions, nanswers; + uint8_t nquestions, nanswers; - static int8_t i; + int8_t i; - register struct namemap *namemapptr; + register struct namemap *namemapptr = NULL; struct dns_answer *ans; @@ -860,7 +875,7 @@ newdata(void) } return; } else { - static uint8_t nauthrr; + uint8_t nauthrr; PRINTF("resolver: But we are still probing. Waiting...\n"); /* We are still probing. We need to do the mDNS * probe race condition check here and make sure @@ -900,10 +915,13 @@ newdata(void) } else #endif /* RESOLV_CONF_SUPPORTS_MDNS */ { - /* The ID in the DNS header should be our entry into the name table. */ - i = RESOLV_DECODE_INDEX(hdr->id); - - namemapptr = &names[i]; + for(i = 0; i < RESOLV_ENTRIES; ++i) { + namemapptr = &names[i]; + if(namemapptr->state == STATE_ASKING && + namemapptr->id == hdr->id) { + break; + } + } if(i >= RESOLV_ENTRIES || i < 0 || namemapptr->state != STATE_ASKING) { PRINTF("resolver: DNS response has bad ID (%04X) \n", uip_ntohs(hdr->id)); @@ -945,7 +963,7 @@ newdata(void) #endif /* !ARCH_DOESNT_NEED_ALIGNED_STRUCTS */ #if VERBOSE_DEBUG - static char debug_name[40]; + char debug_name[40]; decode_name(queryptr, debug_name, uip_appdata); DEBUG_PRINTF("resolver: Answer %d: \"%s\", type %d, class %d, ttl %d, length %d\n", ++i, debug_name, uip_ntohs(ans->type), @@ -1039,11 +1057,28 @@ newdata(void) uip_ipaddr_copy(&namemapptr->ipaddr, (uip_ipaddr_t *) ans->ipaddr); resolv_found(namemapptr->name, &namemapptr->ipaddr); + break; skip_to_next_answer: queryptr = (unsigned char *)skip_name(queryptr) + 10 + uip_htons(ans->len); --nanswers; } + + /* Got to this point there's no answer, try next nameserver if available + since this one doesn't know the answer */ +#if RESOLV_CONF_SUPPORTS_MDNS + if(nanswers == 0 && UIP_UDP_BUF->srcport != UIP_HTONS(MDNS_PORT) + && hdr->id != 0) +#else + if(nanswers == 0) +#endif + { + if(try_next_server(namemapptr)) { + namemapptr->state = STATE_ASKING; + process_post(&resolv_process, PROCESS_EVENT_TIMER, NULL); + } + } + } /*---------------------------------------------------------------------------*/ #if RESOLV_CONF_SUPPORTS_MDNS @@ -1138,7 +1173,7 @@ PROCESS_THREAD(resolv_process, ev, data) PRINTF("resolver: Supports MDNS.\n"); uip_udp_bind(resolv_conn, UIP_HTONS(MDNS_PORT)); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 uip_ds6_maddr_add(&resolv_mdns_addr); #else /* TODO: Is there anything we need to do here for IPv4 multicast? */ @@ -1197,6 +1232,16 @@ PROCESS_THREAD(resolv_process, ev, data) PROCESS_END(); } /*---------------------------------------------------------------------------*/ +static void +init(void) +{ + static uint8_t initialized = 0; + if(!initialized) { + process_start(&resolv_process, NULL); + initialized = 1; + } +} +/*---------------------------------------------------------------------------*/ #if RESOLV_AUTO_REMOVE_TRAILING_DOTS static const char * remove_trailing_dots(const char *name) { @@ -1224,12 +1269,14 @@ remove_trailing_dots(const char *name) { void resolv_query(const char *name) { - static uint8_t i; + uint8_t i; - static uint8_t lseq, lseqi; + uint8_t lseq, lseqi; register struct namemap *nameptr = 0; + init(); + lseq = lseqi = 0; /* Remove trailing dots, if present. */ @@ -1271,7 +1318,7 @@ resolv_query(const char *name) { size_t name_len = strlen(name); - static const char local_suffix[] = "local"; + const char local_suffix[] = "local"; if((name_len > (sizeof(local_suffix) - 1)) && (0 == strcasecmp(name + name_len - (sizeof(local_suffix) - 1), local_suffix))) { @@ -1303,7 +1350,7 @@ resolv_lookup(const char *name, uip_ipaddr_t ** ipaddr) { resolv_status_t ret = RESOLV_STATUS_UNCACHED; - static uint8_t i; + uint8_t i; struct namemap *nameptr; @@ -1313,12 +1360,12 @@ resolv_lookup(const char *name, uip_ipaddr_t ** ipaddr) #if UIP_CONF_LOOPBACK_INTERFACE if(strcmp(name, "localhost")) { static uip_ipaddr_t loopback = -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }; -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ { { 127, 0, 0, 1 } }; -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ if(ipaddr) { *ipaddr = &loopback; } @@ -1366,7 +1413,8 @@ resolv_lookup(const char *name, uip_ipaddr_t ** ipaddr) #if VERBOSE_DEBUG switch (ret) { - case RESOLV_STATUS_CACHED:{ + case RESOLV_STATUS_CACHED: + if(ipaddr) { PRINTF("resolver: Found \"%s\" in cache.\n", name); const uip_ipaddr_t *addr = *ipaddr; @@ -1390,31 +1438,6 @@ resolv_lookup(const char *name, uip_ipaddr_t ** ipaddr) return ret; } /*---------------------------------------------------------------------------*/ -/** - * Obtain the currently configured DNS server. - * - * \return A pointer to a 4-byte representation of the IP address of - * the currently configured DNS server or NULL if no DNS server has - * been configured. - */ -uip_ipaddr_t * -resolv_getserver(void) -{ - return &resolv_default_dns_server; -} -/*---------------------------------------------------------------------------*/ -/** - * Configure a DNS server. - * - * \param dnsserver A pointer to a 4-byte representation of the IP - * address of the DNS server to be configured. - */ -void -resolv_conf(const uip_ipaddr_t * dnsserver) -{ - uip_ipaddr_copy(&resolv_default_dns_server, dnsserver); -} -/*---------------------------------------------------------------------------*/ /** \internal * Callback function which is called when a hostname is found. * @@ -1425,7 +1448,7 @@ resolv_found(char *name, uip_ipaddr_t * ipaddr) #if RESOLV_CONF_SUPPORTS_MDNS if(strncasecmp(resolv_hostname, name, strlen(resolv_hostname)) == 0 && ipaddr -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 && !uip_ds6_is_my_addr(ipaddr) #else && uip_ipaddr_cmp(&uip_hostaddr, ipaddr) != 0 @@ -1452,7 +1475,7 @@ resolv_found(char *name, uip_ipaddr_t * ipaddr) val >>= 4; append_str[1] = (((val & 0xF) > 9) ? 'a' : '0') + (val & 0xF); strncat(resolv_hostname, append_str, - sizeof(resolv_hostname) - strlen(resolv_hostname)); + sizeof(resolv_hostname) - strlen(resolv_hostname) - 1); /* -1 in order to fit the terminating null byte. */ } /* Re-add the .local suffix */ diff --git a/core/net/ip/resolv.h b/core/net/ip/resolv.h index 6ef6d6ef0..ed24d5bce 100644 --- a/core/net/ip/resolv.h +++ b/core/net/ip/resolv.h @@ -1,9 +1,3 @@ -/** - * \file - * uIP DNS resolver code header file. - * \author Adam Dunkels - */ - /* * Copyright (c) 2002-2003, Adam Dunkels. * All rights reserved. @@ -36,6 +30,13 @@ * * */ + +/** + * \file + * uIP DNS resolver code header file. + * \author Adam Dunkels + */ + #ifndef RESOLV_H_ #define RESOLV_H_ @@ -56,11 +57,6 @@ */ CCIF extern process_event_t resolv_event_found; -/* Functions. */ -CCIF void resolv_conf(const uip_ipaddr_t * dnsserver); - -CCIF uip_ipaddr_t *resolv_getserver(void); - enum { /** Hostname is fresh and usable. This response is cached and will eventually * expire to RESOLV_STATUS_EXPIRED.*/ @@ -94,6 +90,7 @@ enum { typedef uint8_t resolv_status_t; +/* Functions. */ CCIF resolv_status_t resolv_lookup(const char *name, uip_ipaddr_t ** ipaddr); CCIF void resolv_query(const char *name); diff --git a/core/net/ip/simple-udp.c b/core/net/ip/simple-udp.c index 7c847bf5c..692fea19a 100644 --- a/core/net/ip/simple-udp.c +++ b/core/net/ip/simple-udp.c @@ -1,9 +1,3 @@ -/** - * \addtogroup simple-udp - * @{ - */ - - /* * Copyright (c) 2011, Swedish Institute of Computer Science. * All rights reserved. @@ -33,14 +27,21 @@ * SUCH DAMAGE. * * This file is part of the Contiki operating system. - * + */ + +/** * \file - * Header file for the simple-udp module. + * Code for the simple-udp module. * \author * Adam Dunkels * */ +/** + * \addtogroup simple-udp + * @{ + */ + #include "contiki-net.h" #include "net/ip/simple-udp.h" @@ -63,19 +64,6 @@ init_simple_udp(void) } } /*---------------------------------------------------------------------------*/ -/** - * \brief Send a UDP packet - * \param c A pointer to a struct simple_udp_connection - * \param data A pointer to the data to be sent - * \param datalen The length of the data - * - * This function sends a UDP packet. The packet will be - * sent to the IP address and with the UDP ports that were - * specified when the connection wa registered with - * simple_udp_register(). - * - * \sa simple_udp_sendto() - */ int simple_udp_send(struct simple_udp_connection *c, const void *data, uint16_t datalen) @@ -87,20 +75,6 @@ simple_udp_send(struct simple_udp_connection *c, return 0; } /*---------------------------------------------------------------------------*/ -/** - * \brief Send a UDP packet to a specified IP address - * \param c A pointer to a struct simple_udp_connection - * \param data A pointer to the data to be sent - * \param datalen The length of the data - * \param to The IP address of the receiver - * - * This function sends a UDP packet to a specified IP - * address. The packet will be sent with the UDP ports - * that were specified when the connection wa registered - * with simple_udp_register(). - * - * \sa simple_udp_send() - */ int simple_udp_sendto(struct simple_udp_connection *c, const void *data, uint16_t datalen, @@ -113,21 +87,6 @@ simple_udp_sendto(struct simple_udp_connection *c, return 0; } /*---------------------------------------------------------------------------*/ -/** - * \brief Send a UDP packet to a specified IP address and UDP port - * \param c A pointer to a struct simple_udp_connection - * \param data A pointer to the data to be sent - * \param datalen The length of the data - * \param to The IP address of the receiver - * \param port The UDP port of the receiver, in host byte order - * - * This function sends a UDP packet to a specified IP - * address and UDP port. The packet will be sent with the - * UDP ports that were specified when the connection wa - * registered with simple_udp_register(). - * - * \sa simple_udp_sendto() - */ int simple_udp_sendto_port(struct simple_udp_connection *c, const void *data, uint16_t datalen, @@ -141,25 +100,6 @@ simple_udp_sendto_port(struct simple_udp_connection *c, return 0; } /*---------------------------------------------------------------------------*/ -/** - * \brief Register a UDP connection - * \param c A pointer to a struct simple_udp_connection - * \param local_port The local UDP port in host byte order - * \param remote_addr The remote IP address - * \param remote_port The remote UDP port in host byte order - * \param receive_callback A pointer to a function to be called for incoming packets - * \retval 0 If no UDP connection could be allocated - * \retval 1 If the connection was successfully allocated - * - * This function registers a UDP connection and attaches a - * callback function to it. The callback function will be - * called for incoming packets. The local UDP port can be - * set to 0 to indicate that an ephemeral UDP port should - * be allocated. The remote IP address can be NULL, to - * indicate that packets from any IP address should be - * accepted. - * - */ int simple_udp_register(struct simple_udp_connection *c, uint16_t local_port, @@ -179,7 +119,7 @@ simple_udp_register(struct simple_udp_connection *c, PROCESS_CONTEXT_BEGIN(&simple_udp_process); c->udp_conn = udp_new(remote_addr, UIP_HTONS(remote_port), c); - if(c->udp_conn != NULL) { + if(c->udp_conn != NULL && local_port) { udp_bind(c->udp_conn, UIP_HTONS(local_port)); } PROCESS_CONTEXT_END(); diff --git a/core/net/ip/simple-udp.h b/core/net/ip/simple-udp.h index e5a9439d7..c28ce3e2c 100644 --- a/core/net/ip/simple-udp.h +++ b/core/net/ip/simple-udp.h @@ -1,18 +1,3 @@ -/** - * \addtogroup uip - * @{ - */ - - -/** - * \defgroup simple-udp - * - * The default Contiki UDP API is difficult to use. The simple-udp - * module provides a significantly simpler API. - * - * @{ - */ - /* * Copyright (c) 2011, Swedish Institute of Computer Science. * All rights reserved. @@ -42,7 +27,9 @@ * SUCH DAMAGE. * * This file is part of the Contiki operating system. - * + */ + +/** * \file * Header file for the simple-udp module. * \author @@ -50,6 +37,21 @@ * */ +/** + * \addtogroup uip + * @{ + */ + + +/** + * \defgroup simple-udp A simple UDP API + * + * The default Contiki UDP API is difficult to use. The simple-udp + * module provides a significantly simpler API. + * + * @{ + */ + #ifndef SIMPLE_UDP_H #define SIMPLE_UDP_H @@ -57,6 +59,7 @@ struct simple_udp_connection; +/** Simple UDP Callback function type. */ typedef void (* simple_udp_callback)(struct simple_udp_connection *c, const uip_ipaddr_t *source_addr, uint16_t source_port, @@ -64,6 +67,7 @@ typedef void (* simple_udp_callback)(struct simple_udp_connection *c, uint16_t dest_port, const uint8_t *data, uint16_t datalen); +/** Simple UDP connection */ struct simple_udp_connection { struct simple_udp_connection *next; uip_ipaddr_t remote_addr; @@ -73,19 +77,80 @@ struct simple_udp_connection { struct process *client_process; }; +/** + * \brief Register a UDP connection + * \param c A pointer to a struct simple_udp_connection + * \param local_port The local UDP port in host byte order + * \param remote_addr The remote IP address + * \param remote_port The remote UDP port in host byte order + * \param receive_callback A pointer to a function of to be called for incoming packets + * \retval 0 If no UDP connection could be allocated + * \retval 1 If the connection was successfully allocated + * + * This function registers a UDP connection and attaches a + * callback function to it. The callback function will be + * called for incoming packets. The local UDP port can be + * set to 0 to indicate that an ephemeral UDP port should + * be allocated. The remote IP address can be NULL, to + * indicate that packets from any IP address should be + * accepted. + * + */ int simple_udp_register(struct simple_udp_connection *c, uint16_t local_port, uip_ipaddr_t *remote_addr, uint16_t remote_port, simple_udp_callback receive_callback); +/** + * \brief Send a UDP packet + * \param c A pointer to a struct simple_udp_connection + * \param data A pointer to the data to be sent + * \param datalen The length of the data + * + * This function sends a UDP packet. The packet will be + * sent to the IP address and with the UDP ports that were + * specified when the connection was registered with + * simple_udp_register(). + * + * \sa simple_udp_sendto() + */ int simple_udp_send(struct simple_udp_connection *c, const void *data, uint16_t datalen); +/** + * \brief Send a UDP packet to a specified IP address + * \param c A pointer to a struct simple_udp_connection + * \param data A pointer to the data to be sent + * \param datalen The length of the data + * \param to The IP address of the receiver + * + * This function sends a UDP packet to a specified IP + * address. The packet will be sent with the UDP ports + * that were specified when the connection was registered + * with simple_udp_register(). + * + * \sa simple_udp_send() + */ int simple_udp_sendto(struct simple_udp_connection *c, const void *data, uint16_t datalen, const uip_ipaddr_t *to); +/** + * \brief Send a UDP packet to a specified IP address and UDP port + * \param c A pointer to a struct simple_udp_connection + * \param data A pointer to the data to be sent + * \param datalen The length of the data + * \param to The IP address of the receiver + * \param to_port The UDP port of the receiver, in host byte order + * + * This function sends a UDP packet to a specified IP + * address and UDP port. The packet will be sent with the + * UDP ports that were specified when the connection was + * registered with simple_udp_register(). + * + * \sa simple_udp_sendto() + */ int simple_udp_sendto_port(struct simple_udp_connection *c, const void *data, uint16_t datalen, const uip_ipaddr_t *to, uint16_t to_port); diff --git a/core/net/ip/slipdev.c b/core/net/ip/slipdev.c index 670126632..8bc688557 100644 --- a/core/net/ip/slipdev.c +++ b/core/net/ip/slipdev.c @@ -1,28 +1,3 @@ -/** - * \addtogroup uip - * @{ - */ - -/** - * \defgroup slip Serial Line IP (SLIP) protocol - * @{ - * - * The SLIP protocol is a very simple way to transmit IP packets over - * a serial line. It does not provide any framing or error control, - * and is therefore not very widely used today. - * - * This SLIP implementation requires two functions for accessing the - * serial device: slipdev_char_poll() and slipdev_char_put(). These - * must be implemented specifically for the system on which the SLIP - * protocol is to be run. - */ - -/** - * \file - * SLIP protocol implementation - * \author Adam Dunkels - */ - /* * Copyright (c) 2001, Adam Dunkels. * All rights reserved. @@ -56,6 +31,31 @@ * */ +/** + * \file + * SLIP protocol implementation + * \author Adam Dunkels + */ + +/** + * \addtogroup uip + * @{ + */ + +/** + * \defgroup slip Serial Line IP (SLIP) protocol + * @{ + * + * The SLIP protocol is a very simple way to transmit IP packets over + * a serial line. It does not provide any framing or error control, + * and is therefore not very widely used today. + * + * This SLIP implementation requires two functions for accessing the + * serial device: slipdev_char_poll() and slipdev_char_put(). These + * must be implemented specifically for the system on which the SLIP + * protocol is to be run. + */ + /* * This is a generic implementation of the SLIP protocol over an RS232 * (serial) device. @@ -103,7 +103,7 @@ slipdev_send(void) ptr = &uip_buf[UIP_LLH_LEN]; for(i = 0; i < uip_len; ++i) { if(i == UIP_TCPIP_HLEN) { - ptr = uip_appdata; + ptr = (uint8_t *)uip_appdata; } c = *ptr++; switch(c) { diff --git a/core/net/ip/slipdev.h b/core/net/ip/slipdev.h index 105461a59..5486facc6 100644 --- a/core/net/ip/slipdev.h +++ b/core/net/ip/slipdev.h @@ -1,14 +1,3 @@ -/** - * \addtogroup slip - * @{ - */ - -/** - * \file - * SLIP header file. - * \author Adam Dunkels - */ - /* * Copyright (c) 2001, Adam Dunkels. * All rights reserved. @@ -42,6 +31,17 @@ * */ +/** + * \file + * SLIP header file. + * \author Adam Dunkels + */ + +/** + * \addtogroup slip + * @{ + */ + #ifndef SLIPDEV_H_ #define SLIPDEV_H_ diff --git a/core/net/ip/tcp-socket.c b/core/net/ip/tcp-socket.c index f914ae206..eac008cde 100644 --- a/core/net/ip/tcp-socket.c +++ b/core/net/ip/tcp-socket.c @@ -30,6 +30,7 @@ */ #include "contiki.h" +#include "sys/cc.h" #include "contiki-net.h" #include "lib/list.h" @@ -39,7 +40,8 @@ #include #include -#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +static void relisten(struct tcp_socket *s); LIST(socketlist); /*---------------------------------------------------------------------------*/ @@ -56,10 +58,10 @@ call_event(struct tcp_socket *s, tcp_socket_event_t event) static void senddata(struct tcp_socket *s) { - int len; + int len = MIN(s->output_data_max_seg, uip_mss()); - if(s->output_data_len > 0) { - len = MIN(s->output_data_len, uip_mss()); + if(s->output_senddata_len > 0) { + len = MIN(s->output_senddata_len, len); s->output_data_send_nxt = len; uip_send(s->output_data_ptr, len); } @@ -68,21 +70,27 @@ senddata(struct tcp_socket *s) static void acked(struct tcp_socket *s) { - if(s->output_data_len > 0) { + if(s->output_senddata_len > 0) { /* Copy the data in the outputbuf down and update outputbufptr and outputbuf_lastsent */ if(s->output_data_send_nxt > 0) { memcpy(&s->output_data_ptr[0], - &s->output_data_ptr[s->output_data_send_nxt], - s->output_data_maxlen - s->output_data_send_nxt); + &s->output_data_ptr[s->output_data_send_nxt], + s->output_data_maxlen - s->output_data_send_nxt); } if(s->output_data_len < s->output_data_send_nxt) { printf("tcp: acked assertion failed s->output_data_len (%d) < s->output_data_send_nxt (%d)\n", - s->output_data_len, - s->output_data_send_nxt); + s->output_data_len, + s->output_data_send_nxt); + tcp_markconn(uip_conn, NULL); + uip_abort(); + call_event(s, TCP_SOCKET_ABORTED); + relisten(s); + return; } s->output_data_len -= s->output_data_send_nxt; + s->output_senddata_len = s->output_data_len; s->output_data_send_nxt = 0; call_event(s, TCP_SOCKET_DATA_SENT); @@ -134,6 +142,11 @@ appcall(void *state) { struct tcp_socket *s = state; + if(s != NULL && s->c != NULL && s->c != uip_conn) { + /* Safe-guard: this should not happen, as the incoming event relates to + * a previous connection */ + return; + } if(uip_connected()) { /* Check if this connection originated in a local listen socket. We do this by checking the state pointer - if NULL, @@ -148,12 +161,14 @@ appcall(void *state) s->listen_port != 0 && s->listen_port == uip_htons(uip_conn->lport)) { s->flags &= ~TCP_SOCKET_FLAGS_LISTENING; + s->output_data_max_seg = uip_mss(); tcp_markconn(uip_conn, s); call_event(s, TCP_SOCKET_CONNECTED); break; } } } else { + s->output_data_max_seg = uip_mss(); call_event(s, TCP_SOCKET_CONNECTED); } @@ -174,8 +189,10 @@ appcall(void *state) } if(uip_aborted()) { + tcp_markconn(uip_conn, NULL); call_event(s, TCP_SOCKET_ABORTED); relisten(s); + } if(s == NULL) { @@ -201,13 +218,16 @@ appcall(void *state) if(s->output_data_len == 0 && s->flags & TCP_SOCKET_FLAGS_CLOSING) { s->flags &= ~TCP_SOCKET_FLAGS_CLOSING; uip_close(); + s->c = NULL; tcp_markconn(uip_conn, NULL); - call_event(s, TCP_SOCKET_CLOSED); + s->c = NULL; + /*call_event(s, TCP_SOCKET_CLOSED);*/ relisten(s); } if(uip_closed()) { tcp_markconn(uip_conn, NULL); + s->c = NULL; call_event(s, TCP_SOCKET_CLOSED); relisten(s); } @@ -253,6 +273,7 @@ tcp_socket_register(struct tcp_socket *s, void *ptr, s->ptr = ptr; s->input_data_ptr = input_databuf; s->input_data_maxlen = input_databuf_len; + s->output_data_len = 0; s->output_data_ptr = output_databuf; s->output_data_maxlen = output_databuf_len; s->input_callback = input_callback; @@ -266,12 +287,15 @@ tcp_socket_register(struct tcp_socket *s, void *ptr, /*---------------------------------------------------------------------------*/ int tcp_socket_connect(struct tcp_socket *s, - uip_ipaddr_t *ipaddr, - uint16_t port) + const uip_ipaddr_t *ipaddr, + uint16_t port) { if(s == NULL) { return -1; } + if(s->c != NULL) { + tcp_markconn(s->c, NULL); + } PROCESS_CONTEXT_BEGIN(&tcp_socket_process); s->c = tcp_connect(ipaddr, uip_htons(port), s); PROCESS_CONTEXT_END(); @@ -315,7 +339,7 @@ tcp_socket_unlisten(struct tcp_socket *s) /*---------------------------------------------------------------------------*/ int tcp_socket_send(struct tcp_socket *s, - const uint8_t *data, int datalen) + const uint8_t *data, int datalen) { int len; @@ -327,6 +351,11 @@ tcp_socket_send(struct tcp_socket *s, memcpy(&s->output_data_ptr[s->output_data_len], data, len); s->output_data_len += len; + + if(s->output_senddata_len == 0) { + s->output_senddata_len = s->output_data_len; + } + return len; } /*---------------------------------------------------------------------------*/ @@ -363,3 +392,9 @@ tcp_socket_unregister(struct tcp_socket *s) return 1; } /*---------------------------------------------------------------------------*/ +int +tcp_socket_max_sendlen(struct tcp_socket *s) +{ + return s->output_data_maxlen - s->output_data_len; +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/ip/tcp-socket.h b/core/net/ip/tcp-socket.h index aea678049..34cb0d6b7 100644 --- a/core/net/ip/tcp-socket.h +++ b/core/net/ip/tcp-socket.h @@ -32,6 +32,8 @@ #ifndef TCP_SOCKET_H #define TCP_SOCKET_H +#include "uip.h" + struct tcp_socket; typedef enum { @@ -95,6 +97,8 @@ struct tcp_socket { uint16_t output_data_maxlen; uint16_t output_data_len; uint16_t output_data_send_nxt; + uint16_t output_senddata_len; + uint16_t output_data_max_seg; uint8_t flags; uint16_t listen_port; @@ -169,7 +173,7 @@ int tcp_socket_register(struct tcp_socket *s, void *ptr, * */ int tcp_socket_connect(struct tcp_socket *s, - uip_ipaddr_t *ipaddr, + const uip_ipaddr_t *ipaddr, uint16_t port); /** @@ -265,4 +269,19 @@ int tcp_socket_close(struct tcp_socket *s); * */ int tcp_socket_unregister(struct tcp_socket *s); + +/** + * \brief The maximum amount of data that could currently be sent + * \param s A pointer to a TCP socket + * \return The number of bytes available in the output buffer + * + * This function queries the TCP socket and returns the + * number of bytes available in the output buffer. This + * function is used before calling tcp_socket_send() to + * ensure that one application level message can be held + * in the output buffer. + * + */ +int tcp_socket_max_sendlen(struct tcp_socket *s); + #endif /* TCP_SOCKET_H */ diff --git a/core/net/ip/tcpip.c b/core/net/ip/tcpip.c index e6beae7fd..df3f0608d 100644 --- a/core/net/ip/tcpip.c +++ b/core/net/ip/tcpip.c @@ -42,11 +42,16 @@ #include "net/ip/uip-split.h" #include "net/ip/uip-packetqueue.h" -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #include "net/ipv6/uip-nd6.h" #include "net/ipv6/uip-ds6.h" #endif +#if UIP_CONF_IPV6_RPL +#include "net/rpl/rpl.h" +#include "net/rpl/rpl-private.h" +#endif + #include #define DEBUG DEBUG_NONE @@ -80,7 +85,7 @@ process_event_t tcpip_icmp6_event; /* Periodic check of active connections. */ static struct etimer periodic; -#if UIP_CONF_IPV6 && UIP_CONF_IPV6_REASSEMBLY +#if NETSTACK_CONF_WITH_IPV6 && UIP_CONF_IPV6_REASSEMBLY /* Timer for reassembly. */ extern struct etimer uip_reass_timer; #endif @@ -107,7 +112,7 @@ enum { }; /* Called on IP packet output. */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 static uint8_t (* outputfunc)(const uip_lladdr_t *a); @@ -155,7 +160,7 @@ unsigned char tcpip_is_forwarding; /* Forwarding right now? */ PROCESS(tcpip_process, "TCP/IP stack"); /*---------------------------------------------------------------------------*/ -#if UIP_TCP +#if UIP_TCP || UIP_CONF_IP_FORWARD static void start_periodic_tcp_timer(void) { @@ -163,7 +168,7 @@ start_periodic_tcp_timer(void) etimer_restart(&periodic); } } -#endif +#endif /* UIP_TCP || UIP_CONF_IP_FORWARD */ /*---------------------------------------------------------------------------*/ static void check_for_tcp_syn(void) @@ -185,55 +190,41 @@ check_for_tcp_syn(void) static void packet_input(void) { -#if UIP_CONF_IP_FORWARD if(uip_len > 0) { + +#if UIP_CONF_IP_FORWARD tcpip_is_forwarding = 1; - if(uip_fw_forward() == UIP_FW_LOCAL) { + if(uip_fw_forward() != UIP_FW_LOCAL) { tcpip_is_forwarding = 0; - check_for_tcp_syn(); - uip_input(); - if(uip_len > 0) { -#if UIP_CONF_TCP_SPLIT - uip_split_output(); -#else /* UIP_CONF_TCP_SPLIT */ -#if UIP_CONF_IPV6 - tcpip_ipv6_output(); -#else - PRINTF("tcpip packet_input forward output len %d\n", uip_len); - tcpip_output(); -#endif -#endif /* UIP_CONF_TCP_SPLIT */ - } + return; } tcpip_is_forwarding = 0; - } -#else /* UIP_CONF_IP_FORWARD */ - if(uip_len > 0) { +#endif /* UIP_CONF_IP_FORWARD */ + check_for_tcp_syn(); uip_input(); if(uip_len > 0) { #if UIP_CONF_TCP_SPLIT uip_split_output(); #else /* UIP_CONF_TCP_SPLIT */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 tcpip_ipv6_output(); -#else +#else /* NETSTACK_CONF_WITH_IPV6 */ PRINTF("tcpip packet_input output len %d\n", uip_len); tcpip_output(); -#endif +#endif /* NETSTACK_CONF_WITH_IPV6 */ #endif /* UIP_CONF_TCP_SPLIT */ } } -#endif /* UIP_CONF_IP_FORWARD */ } /*---------------------------------------------------------------------------*/ #if UIP_TCP #if UIP_ACTIVE_OPEN struct uip_conn * -tcp_connect(uip_ipaddr_t *ripaddr, uint16_t port, void *appstate) +tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate) { struct uip_conn *c; - + c = uip_connect(ripaddr, port); if(c == NULL) { return NULL; @@ -241,9 +232,9 @@ tcp_connect(uip_ipaddr_t *ripaddr, uint16_t port, void *appstate) c->appstate.p = PROCESS_CURRENT(); c->appstate.state = appstate; - + tcpip_poll_tcp(c); - + return c; } #endif /* UIP_ACTIVE_OPEN */ @@ -251,7 +242,7 @@ tcp_connect(uip_ipaddr_t *ripaddr, uint16_t port, void *appstate) void tcp_unlisten(uint16_t port) { - static unsigned char i; + unsigned char i; struct listenport *l; l = s.listenports; @@ -269,7 +260,7 @@ tcp_unlisten(uint16_t port) void tcp_listen(uint16_t port) { - static unsigned char i; + unsigned char i; struct listenport *l; l = s.listenports; @@ -314,7 +305,7 @@ udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate) { struct uip_udp_conn *c; uip_udp_appstate_t *s; - + c = uip_udp_new(ripaddr, port); if(c == NULL) { return NULL; @@ -333,11 +324,11 @@ udp_broadcast_new(uint16_t port, void *appstate) uip_ipaddr_t addr; struct uip_udp_conn *conn; -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 uip_create_linklocal_allnodes_mcast(&addr); #else uip_ipaddr(&addr, 255,255,255,255); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ conn = udp_new(&addr, port, appstate); if(conn != NULL) { udp_bind(conn, port); @@ -373,157 +364,157 @@ static void eventhandler(process_event_t ev, process_data_t data) { #if UIP_TCP - static unsigned char i; + unsigned char i; register struct listenport *l; #endif /*UIP_TCP*/ struct process *p; switch(ev) { - case PROCESS_EVENT_EXITED: - /* This is the event we get if a process has exited. We go through + case PROCESS_EVENT_EXITED: + /* This is the event we get if a process has exited. We go through the TCP/IP tables to see if this process had any open connections or listening TCP ports. If so, we'll close those connections. */ - p = (struct process *)data; + p = (struct process *)data; #if UIP_TCP - l = s.listenports; - for(i = 0; i < UIP_LISTENPORTS; ++i) { - if(l->p == p) { - uip_unlisten(l->port); - l->port = 0; - l->p = PROCESS_NONE; - } - ++l; + l = s.listenports; + for(i = 0; i < UIP_LISTENPORTS; ++i) { + if(l->p == p) { + uip_unlisten(l->port); + l->port = 0; + l->p = PROCESS_NONE; } - - { - struct uip_conn *cptr; - - for(cptr = &uip_conns[0]; cptr < &uip_conns[UIP_CONNS]; ++cptr) { - if(cptr->appstate.p == p) { - cptr->appstate.p = PROCESS_NONE; - cptr->tcpstateflags = UIP_CLOSED; - } + ++l; + } + + { + struct uip_conn *cptr; + + for(cptr = &uip_conns[0]; cptr < &uip_conns[UIP_CONNS]; ++cptr) { + if(cptr->appstate.p == p) { + cptr->appstate.p = PROCESS_NONE; + cptr->tcpstateflags = UIP_CLOSED; } } + } #endif /* UIP_TCP */ #if UIP_UDP - { - struct uip_udp_conn *cptr; + { + struct uip_udp_conn *cptr; - for(cptr = &uip_udp_conns[0]; - cptr < &uip_udp_conns[UIP_UDP_CONNS]; ++cptr) { - if(cptr->appstate.p == p) { - cptr->lport = 0; - } + for(cptr = &uip_udp_conns[0]; + cptr < &uip_udp_conns[UIP_UDP_CONNS]; ++cptr) { + if(cptr->appstate.p == p) { + cptr->lport = 0; } } + } #endif /* UIP_UDP */ - break; + break; - case PROCESS_EVENT_TIMER: - /* We get this event if one of our timers have expired. */ - { - /* Check the clock so see if we should call the periodic uIP + case PROCESS_EVENT_TIMER: + /* We get this event if one of our timers have expired. */ + { + /* Check the clock so see if we should call the periodic uIP processing. */ - if(data == &periodic && - etimer_expired(&periodic)) { + if(data == &periodic && + etimer_expired(&periodic)) { #if UIP_TCP - for(i = 0; i < UIP_CONNS; ++i) { - if(uip_conn_active(i)) { - /* Only restart the timer if there are active + for(i = 0; i < UIP_CONNS; ++i) { + if(uip_conn_active(i)) { + /* Only restart the timer if there are active connections. */ - etimer_restart(&periodic); - uip_periodic(i); -#if UIP_CONF_IPV6 - tcpip_ipv6_output(); + etimer_restart(&periodic); + uip_periodic(i); +#if NETSTACK_CONF_WITH_IPV6 + tcpip_ipv6_output(); #else - if(uip_len > 0) { - PRINTF("tcpip_output from periodic len %d\n", uip_len); - tcpip_output(); - PRINTF("tcpip_output after periodic len %d\n", uip_len); - } -#endif /* UIP_CONF_IPV6 */ - } + if(uip_len > 0) { + PRINTF("tcpip_output from periodic len %d\n", uip_len); + tcpip_output(); + PRINTF("tcpip_output after periodic len %d\n", uip_len); } +#endif /* NETSTACK_CONF_WITH_IPV6 */ + } + } #endif /* UIP_TCP */ #if UIP_CONF_IP_FORWARD - uip_fw_periodic(); + uip_fw_periodic(); #endif /* UIP_CONF_IP_FORWARD */ - } - -#if UIP_CONF_IPV6 + } + +#if NETSTACK_CONF_WITH_IPV6 #if UIP_CONF_IPV6_REASSEMBLY - /* - * check the timer for reassembly - */ - if(data == &uip_reass_timer && - etimer_expired(&uip_reass_timer)) { - uip_reass_over(); - tcpip_ipv6_output(); - } + /* + * check the timer for reassembly + */ + if(data == &uip_reass_timer && + etimer_expired(&uip_reass_timer)) { + uip_reass_over(); + tcpip_ipv6_output(); + } #endif /* UIP_CONF_IPV6_REASSEMBLY */ - /* - * check the different timers for neighbor discovery and - * stateless autoconfiguration - */ - /*if(data == &uip_ds6_timer_periodic && + /* + * check the different timers for neighbor discovery and + * stateless autoconfiguration + */ + /*if(data == &uip_ds6_timer_periodic && etimer_expired(&uip_ds6_timer_periodic)) { uip_ds6_periodic(); tcpip_ipv6_output(); }*/ #if !UIP_CONF_ROUTER - if(data == &uip_ds6_timer_rs && - etimer_expired(&uip_ds6_timer_rs)) { - uip_ds6_send_rs(); - tcpip_ipv6_output(); - } + if(data == &uip_ds6_timer_rs && + etimer_expired(&uip_ds6_timer_rs)) { + uip_ds6_send_rs(); + tcpip_ipv6_output(); + } #endif /* !UIP_CONF_ROUTER */ - if(data == &uip_ds6_timer_periodic && - etimer_expired(&uip_ds6_timer_periodic)) { - uip_ds6_periodic(); - tcpip_ipv6_output(); - } -#endif /* UIP_CONF_IPV6 */ - } - break; - + if(data == &uip_ds6_timer_periodic && + etimer_expired(&uip_ds6_timer_periodic)) { + uip_ds6_periodic(); + tcpip_ipv6_output(); + } +#endif /* NETSTACK_CONF_WITH_IPV6 */ + } + break; + #if UIP_TCP - case TCP_POLL: - if(data != NULL) { - uip_poll_conn(data); -#if UIP_CONF_IPV6 - tcpip_ipv6_output(); -#else /* UIP_CONF_IPV6 */ - if(uip_len > 0) { - PRINTF("tcpip_output from tcp poll len %d\n", uip_len); - tcpip_output(); - } -#endif /* UIP_CONF_IPV6 */ - /* Start the periodic polling, if it isn't already active. */ - start_periodic_tcp_timer(); + case TCP_POLL: + if(data != NULL) { + uip_poll_conn(data); +#if NETSTACK_CONF_WITH_IPV6 + tcpip_ipv6_output(); +#else /* NETSTACK_CONF_WITH_IPV6 */ + if(uip_len > 0) { + PRINTF("tcpip_output from tcp poll len %d\n", uip_len); + tcpip_output(); } - break; +#endif /* NETSTACK_CONF_WITH_IPV6 */ + /* Start the periodic polling, if it isn't already active. */ + start_periodic_tcp_timer(); + } + break; #endif /* UIP_TCP */ #if UIP_UDP - case UDP_POLL: - if(data != NULL) { - uip_udp_periodic_conn(data); -#if UIP_CONF_IPV6 - tcpip_ipv6_output(); + case UDP_POLL: + if(data != NULL) { + uip_udp_periodic_conn(data); +#if NETSTACK_CONF_WITH_IPV6 + tcpip_ipv6_output(); #else - if(uip_len > 0) { - tcpip_output(); - } -#endif /* UIP_UDP */ + if(uip_len > 0) { + tcpip_output(); } - break; +#endif /* UIP_UDP */ + } + break; #endif /* UIP_UDP */ - case PACKET_INPUT: - packet_input(); - break; + case PACKET_INPUT: + packet_input(); + break; }; } /*---------------------------------------------------------------------------*/ @@ -531,18 +522,15 @@ void tcpip_input(void) { process_post_synch(&tcpip_process, PACKET_INPUT, NULL); - uip_len = 0; -#if UIP_CONF_IPV6 - uip_ext_len = 0; -#endif /*UIP_CONF_IPV6*/ + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 void tcpip_ipv6_output(void) { uip_ds6_nbr_t *nbr = NULL; - uip_ipaddr_t *nexthop; + uip_ipaddr_t *nexthop = NULL; if(uip_len == 0) { return; @@ -550,26 +538,37 @@ tcpip_ipv6_output(void) if(uip_len > UIP_LINK_MTU) { UIP_LOG("tcpip_ipv6_output: Packet to big"); - uip_len = 0; + uip_clear_buf(); return; } if(uip_is_addr_unspecified(&UIP_IP_BUF->destipaddr)){ UIP_LOG("tcpip_ipv6_output: Destination address unspecified"); - uip_len = 0; + uip_clear_buf(); return; } if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) { /* Next hop determination */ + +#if UIP_CONF_IPV6_RPL && RPL_WITH_NON_STORING + uip_ipaddr_t ipaddr; + /* Look for a RPL Source Route */ + if(rpl_srh_get_next_hop(&ipaddr)) { + nexthop = &ipaddr; + } +#endif /* UIP_CONF_IPV6_RPL && RPL_WITH_NON_STORING */ + nbr = NULL; /* We first check if the destination address is on our immediate link. If so, we simply use the destination address as our nexthop address. */ - if(uip_ds6_is_addr_onlink(&UIP_IP_BUF->destipaddr)){ + if(nexthop == NULL && uip_ds6_is_addr_onlink(&UIP_IP_BUF->destipaddr)){ nexthop = &UIP_IP_BUF->destipaddr; - } else { + } + + if(nexthop == NULL) { uip_ds6_route_t *route; /* Check if we have a route to the destination address. */ route = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr); @@ -580,20 +579,29 @@ tcpip_ipv6_output(void) nexthop = uip_ds6_defrt_choose(); if(nexthop == NULL) { #ifdef UIP_FALLBACK_INTERFACE - PRINTF("FALLBACK: removing ext hdrs & setting proto %d %d\n", - uip_ext_len, *((uint8_t *)UIP_IP_BUF + 40)); - if(uip_ext_len > 0) { - extern void remove_ext_hdr(void); - uint8_t proto = *((uint8_t *)UIP_IP_BUF + 40); - remove_ext_hdr(); - /* This should be copied from the ext header... */ - UIP_IP_BUF->proto = proto; - } - UIP_FALLBACK_INTERFACE.output(); + PRINTF("FALLBACK: removing ext hdrs & setting proto %d %d\n", + uip_ext_len, *((uint8_t *)UIP_IP_BUF + 40)); + if(uip_ext_len > 0) { + extern void remove_ext_hdr(void); + uint8_t proto = *((uint8_t *)UIP_IP_BUF + 40); + remove_ext_hdr(); + /* This should be copied from the ext header... */ + UIP_IP_BUF->proto = proto; + } + /* Inform the other end that the destination is not reachable. If it's + * not informed routes might get lost unexpectedly until there's a need + * to send a new packet to the peer */ + if(UIP_FALLBACK_INTERFACE.output() < 0) { + PRINTF("FALLBACK: output error. Reporting DST UNREACH\n"); + uip_icmp6_error_output(ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR, 0); + uip_flags = 0; + tcpip_ipv6_output(); + return; + } #else PRINTF("tcpip_ipv6_output: Destination off-link but no route\n"); #endif /* !UIP_FALLBACK_INTERFACE */ - uip_len = 0; + uip_clear_buf(); return; } @@ -618,7 +626,7 @@ tcpip_ipv6_output(void) rpl_repair_root(instance->instance_id); } -#endif /* UIP_CONF_RPL */ +#endif /* UIP_CONF_IPV6_RPL */ uip_ds6_route_rm(route); /* We don't have a nexthop to send the packet to, so we drop @@ -644,16 +652,17 @@ tcpip_ipv6_output(void) /* End of next hop determination */ #if UIP_CONF_IPV6_RPL - if(rpl_update_header_final(nexthop)) { - uip_len = 0; + if(!rpl_finalize_header(nexthop)) { + uip_clear_buf(); return; } #endif /* UIP_CONF_IPV6_RPL */ nbr = uip_ds6_nbr_lookup(nexthop); if(nbr == NULL) { #if UIP_ND6_SEND_NA - if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE)) == NULL) { - uip_len = 0; + if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE, NBR_TABLE_REASON_IPV6_ND, NULL)) == NULL) { + uip_clear_buf(); + PRINTF("tcpip_ipv6_output: failed to add neighbor to cache\n"); return; } else { #if UIP_CONF_IPV6_QUEUE_PKT @@ -663,13 +672,13 @@ tcpip_ipv6_output(void) uip_packetqueue_set_buflen(&nbr->packethandle, uip_len); } #endif - /* RFC4861, 7.2.2: - * "If the source address of the packet prompting the solicitation is the - * same as one of the addresses assigned to the outgoing interface, that - * address SHOULD be placed in the IP Source Address of the outgoing - * solicitation. Otherwise, any one of the addresses assigned to the - * interface should be used."*/ - if(uip_ds6_is_my_addr(&UIP_IP_BUF->srcipaddr)){ + /* RFC4861, 7.2.2: + * "If the source address of the packet prompting the solicitation is the + * same as one of the addresses assigned to the outgoing interface, that + * address SHOULD be placed in the IP Source Address of the outgoing + * solicitation. Otherwise, any one of the addresses assigned to the + * interface should be used."*/ + if(uip_ds6_is_my_addr(&UIP_IP_BUF->srcipaddr)){ uip_nd6_ns_output(&UIP_IP_BUF->srcipaddr, NULL, &nbr->ipaddr); } else { uip_nd6_ns_output(NULL, NULL, &nbr->ipaddr); @@ -677,7 +686,12 @@ tcpip_ipv6_output(void) stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000); nbr->nscount = 1; + /* Send the first NS try from here (multicast destination IP address). */ } +#else /* UIP_ND6_SEND_NA */ + PRINTF("tcpip_ipv6_output: neighbor not in cache\n"); + uip_len = 0; + return; #endif /* UIP_ND6_SEND_NA */ } else { #if UIP_ND6_SEND_NA @@ -691,7 +705,7 @@ tcpip_ipv6_output(void) uip_packetqueue_set_buflen(&nbr->packethandle, uip_len); } #endif /*UIP_CONF_IPV6_QUEUE_PKT*/ - uip_len = 0; + uip_clear_buf(); return; } /* Send in parallel if we are running NUD (nbc state is either STALE, @@ -721,17 +735,15 @@ tcpip_ipv6_output(void) } #endif /*UIP_CONF_IPV6_QUEUE_PKT*/ - uip_len = 0; + uip_clear_buf(); return; } - return; } /* Multicast IP destination address. */ tcpip_output(NULL); - uip_len = 0; - uip_ext_len = 0; + uip_clear_buf(); } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /*---------------------------------------------------------------------------*/ #if UIP_UDP void @@ -753,7 +765,7 @@ void tcpip_uipcall(void) { uip_udp_appstate_t *ts; - + #if UIP_UDP if(uip_conn != NULL) { ts = &uip_conn->appstate; @@ -765,30 +777,30 @@ tcpip_uipcall(void) #endif /* UIP_UDP */ #if UIP_TCP - { - static unsigned char i; - struct listenport *l; - - /* If this is a connection request for a listening port, we must + { + unsigned char i; + struct listenport *l; + + /* If this is a connection request for a listening port, we must mark the connection with the right process ID. */ - if(uip_connected()) { - l = &s.listenports[0]; - for(i = 0; i < UIP_LISTENPORTS; ++i) { - if(l->port == uip_conn->lport && - l->p != PROCESS_NONE) { - ts->p = l->p; - ts->state = NULL; - break; - } - ++l; - } - - /* Start the periodic polling, if it isn't already active. */ - start_periodic_tcp_timer(); - } - } + if(uip_connected()) { + l = &s.listenports[0]; + for(i = 0; i < UIP_LISTENPORTS; ++i) { + if(l->port == uip_conn->lport && + l->p != PROCESS_NONE) { + ts->p = l->p; + ts->state = NULL; + break; + } + ++l; + } + + /* Start the periodic polling, if it isn't already active. */ + start_periodic_tcp_timer(); + } + } #endif /* UIP_TCP */ - + if(ts->p != NULL) { process_post_synch(ts->p, tcpip_event, ts->state); } @@ -797,16 +809,16 @@ tcpip_uipcall(void) PROCESS_THREAD(tcpip_process, ev, data) { PROCESS_BEGIN(); - + #if UIP_TCP - { - static unsigned char i; - - for(i = 0; i < UIP_LISTENPORTS; ++i) { - s.listenports[i].port = 0; - } - s.p = PROCESS_CURRENT(); - } + { + unsigned char i; + + for(i = 0; i < UIP_LISTENPORTS; ++i) { + s.listenports[i].port = 0; + } + s.p = PROCESS_CURRENT(); + } #endif tcpip_event = process_alloc_event(); @@ -819,8 +831,8 @@ PROCESS_THREAD(tcpip_process, ev, data) #ifdef UIP_FALLBACK_INTERFACE UIP_FALLBACK_INTERFACE.init(); #endif -/* initialize RPL if configured for using RPL */ -#if UIP_CONF_IPV6 && UIP_CONF_IPV6_RPL + /* initialize RPL if configured for using RPL */ +#if NETSTACK_CONF_WITH_IPV6 && UIP_CONF_IPV6_RPL rpl_init(); #endif /* UIP_CONF_IPV6_RPL */ @@ -828,7 +840,7 @@ PROCESS_THREAD(tcpip_process, ev, data) PROCESS_YIELD(); eventhandler(ev, data); } - + PROCESS_END(); } /*---------------------------------------------------------------------------*/ diff --git a/core/net/ip/tcpip.h b/core/net/ip/tcpip.h index dcc1ad19a..8fb2ff526 100644 --- a/core/net/ip/tcpip.h +++ b/core/net/ip/tcpip.h @@ -1,35 +1,3 @@ -/** - * \addtogroup uip - * @{ - */ - -/** - * \defgroup tcpip The Contiki/uIP interface - * @{ - * - * TCP/IP support in Contiki is implemented using the uIP TCP/IP - * stack. For sending and receiving data, Contiki uses the functions - * provided by the uIP module, but Contiki adds a set of functions for - * connection management. The connection management functions make - * sure that the uIP TCP/IP connections are connected to the correct - * process. - * - * Contiki also includes an optional protosocket library that provides - * an API similar to the BSD socket API. - * - * \sa \ref uip "The uIP TCP/IP stack" - * \sa \ref psock "Protosockets library" - * - */ - -/** - * \file - * Header for the Contiki/uIP interface. - * \author Adam Dunkels - * \author Mathilde Durvy (IPv6 related code) - * \author Julien Abeille (IPv6 related code) - */ - /* * Copyright (c) 2004, Swedish Institute of Computer Science. * All rights reserved. @@ -63,6 +31,39 @@ * Author: Adam Dunkels * */ + +/** + * \file + * Header for the Contiki/uIP interface. + * \author Adam Dunkels + * \author Mathilde Durvy (IPv6 related code) + * \author Julien Abeille (IPv6 related code) + */ + +/** + * \addtogroup uip + * @{ + */ + +/** + * \defgroup tcpip The Contiki/uIP interface + * @{ + * + * TCP/IP support in Contiki is implemented using the uIP TCP/IP + * stack. For sending and receiving data, Contiki uses the functions + * provided by the uIP module, but Contiki adds a set of functions for + * connection management. The connection management functions make + * sure that the uIP TCP/IP connections are connected to the correct + * process. + * + * Contiki also includes an optional protosocket library that provides + * an API similar to the BSD socket API. + * + * \sa \ref uip "The uIP TCP/IP stack" + * \sa \ref psock "Protosockets library" + * + */ + #ifndef TCPIP_H_ #define TCPIP_H_ @@ -164,7 +165,7 @@ CCIF void tcp_unlisten(uint16_t port); * memory could not be allocated for the connection. * */ -CCIF struct uip_conn *tcp_connect(uip_ipaddr_t *ripaddr, uint16_t port, +CCIF struct uip_conn *tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate); /** @@ -339,7 +340,7 @@ CCIF void tcpip_input(void); * \brief Output packet to layer 2 * The eventual parameter is the MAC address of the destination. */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 uint8_t tcpip_output(const uip_lladdr_t *); void tcpip_set_outputfunc(uint8_t (* f)(const uip_lladdr_t *)); #else @@ -350,7 +351,7 @@ void tcpip_set_outputfunc(uint8_t (* f)(void)); /** * \brief This function does address resolution and then calls tcpip_output */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 void tcpip_ipv6_output(void); #endif diff --git a/core/net/ip/uip-debug.c b/core/net/ip/uip-debug.c index a9a6d5ed0..7804ba4db 100644 --- a/core/net/ip/uip-debug.c +++ b/core/net/ip/uip-debug.c @@ -30,7 +30,7 @@ /** * \file - * A set of debugging tools + * A set of debugging tools for the IP stack * \author * Nicolas Tsiftes * Niclas Finne @@ -38,48 +38,57 @@ */ #include "net/ip/uip-debug.h" +#include "net/ip/ip64-addr.h" /*---------------------------------------------------------------------------*/ void uip_debug_ipaddr_print(const uip_ipaddr_t *addr) { - if(addr == NULL || addr->u8 == NULL) { - printf("(NULL IP addr)"); - return; - } -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 uint16_t a; unsigned int i; int f; - for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { - a = (addr->u8[i] << 8) + addr->u8[i + 1]; - if(a == 0 && f >= 0) { - if(f++ == 0) { - PRINTA("::"); - } - } else { - if(f > 0) { - f = -1; - } else if(i > 0) { - PRINTA(":"); - } - PRINTA("%x", a); - } +#endif /* NETSTACK_CONF_WITH_IPV6 */ + if(addr == NULL) { + PRINTA("(NULL IP addr)"); + return; } -#else /* UIP_CONF_IPV6 */ +#if NETSTACK_CONF_WITH_IPV6 + if(ip64_addr_is_ipv4_mapped_addr(addr)) { + /* + * Printing IPv4-mapped addresses is done according to RFC 3513 [1] + * + * "An alternative form that is sometimes more + * convenient when dealing with a mixed environment + * of IPv4 and IPv6 nodes is x:x:x:x:x:x:d.d.d.d, + * where the 'x's are the hexadecimal values of the + * six high-order 16-bit pieces of the address, and + * the 'd's are the decimal values of the four + * low-order 8-bit pieces of the address (standard + * IPv4 representation)." + * + * [1] https://tools.ietf.org/html/rfc3513#page-5 + */ + PRINTA("::FFFF:%u.%u.%u.%u", addr->u8[12], addr->u8[13], addr->u8[14], addr->u8[15]); + } else { + for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { + a = (addr->u8[i] << 8) + addr->u8[i + 1]; + if(a == 0 && f >= 0) { + if(f++ == 0) { + PRINTA("::"); + } + } else { + if(f > 0) { + f = -1; + } else if(i > 0) { + PRINTA(":"); + } + PRINTA("%x", a); + } + } + } +#else /* NETSTACK_CONF_WITH_IPV6 */ PRINTA("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]); -#endif /* UIP_CONF_IPV6 */ -} -/*---------------------------------------------------------------------------*/ -void -uip_debug_lladdr_print(const uip_lladdr_t *addr) -{ - unsigned int i; - for(i = 0; i < sizeof(uip_lladdr_t); i++) { - if(i > 0) { - PRINTA(":"); - } - PRINTA("%02x", addr->addr[i]); - } +#endif /* NETSTACK_CONF_WITH_IPV6 */ } /*---------------------------------------------------------------------------*/ diff --git a/core/net/ip/uip-debug.h b/core/net/ip/uip-debug.h index 6ffc1e638..d8e238fe4 100644 --- a/core/net/ip/uip-debug.h +++ b/core/net/ip/uip-debug.h @@ -31,57 +31,27 @@ */ /** * \file - * A set of debugging macros. + * A set of debugging macros for the IP stack * * \author Nicolas Tsiftes * Niclas Finne * Joakim Eriksson + * Simon Duquennoy */ #ifndef UIP_DEBUG_H #define UIP_DEBUG_H +#include "net/net-debug.h" #include "net/ip/uip.h" #include void uip_debug_ipaddr_print(const uip_ipaddr_t *addr); -void uip_debug_lladdr_print(const uip_lladdr_t *addr); - -#define DEBUG_NONE 0 -#define DEBUG_PRINT 1 -#define DEBUG_ANNOTATE 2 -#define DEBUG_FULL DEBUG_ANNOTATE | DEBUG_PRINT - -/* PRINTA will always print if the debug routines are called directly */ -#ifdef __AVR__ -#include -#define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args) -#else -#define PRINTA(...) printf(__VA_ARGS__) -#endif - -#if (DEBUG) & DEBUG_ANNOTATE -#ifdef __AVR__ -#define ANNOTATE(FORMAT,args...) printf_P(PSTR(FORMAT),##args) -#else -#define ANNOTATE(...) printf(__VA_ARGS__) -#endif -#else -#define ANNOTATE(...) -#endif /* (DEBUG) & DEBUG_ANNOTATE */ #if (DEBUG) & DEBUG_PRINT -#ifdef __AVR__ -#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) -#else -#define PRINTF(...) printf(__VA_ARGS__) -#endif #define PRINT6ADDR(addr) uip_debug_ipaddr_print(addr) -#define PRINTLLADDR(lladdr) uip_debug_lladdr_print(lladdr) #else -#define PRINTF(...) #define PRINT6ADDR(addr) -#define PRINTLLADDR(lladdr) #endif /* (DEBUG) & DEBUG_PRINT */ -#endif +#endif /* UIP_DEBUG_H */ diff --git a/core/net/ip/uip-nameserver.c b/core/net/ip/uip-nameserver.c new file mode 100644 index 000000000..6e34346b0 --- /dev/null +++ b/core/net/ip/uip-nameserver.c @@ -0,0 +1,236 @@ +/** + * \addtogroup uip6 + * @{ + */ + +/** + * \file + * uIP Name Server interface + * \author Víctor Ariño + */ + +/* + * Copyright (c) 2014, tado° GmbH. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#include "contiki.h" +#include "contiki-net.h" + +#include "lib/list.h" +#include "lib/memb.h" + +#include +/** \brief Nameserver record */ +typedef struct uip_nameserver_record { + struct uip_nameserver_record *next; + uip_ipaddr_t ip; + uint32_t added; + uint32_t lifetime; +} uip_nameserver_record; + +#if UIP_NAMESERVER_POOL_SIZE > 1 +/** \brief Initialization flag */ +static uint8_t initialized = 0; +#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */ + +/** \name List and memory block + * @{ + */ +#if UIP_NAMESERVER_POOL_SIZE > 1 +LIST(dns); +MEMB(dnsmemb, uip_nameserver_record, UIP_NAMESERVER_POOL_SIZE); +#else /* UIP_NAMESERVER_POOL_SIZE > 1 */ +static uip_ipaddr_t serveraddr; +static uint32_t serverlifetime; +#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */ +/** @} */ + +/** \brief Expiration time in seconds */ +#define DNS_EXPIRATION(r) \ + (((UIP_NAMESERVER_INFINITE_LIFETIME - r->added) <= r->lifetime) ? \ + UIP_NAMESERVER_INFINITE_LIFETIME : r->added + r->lifetime) +/*----------------------------------------------------------------------------*/ +/** + * Initialize the module variables + */ +#if UIP_NAMESERVER_POOL_SIZE > 1 +static CC_INLINE void +init(void) +{ + list_init(dns); + memb_init(&dnsmemb); + initialized = 1; +} +#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */ +/*----------------------------------------------------------------------------*/ +void +uip_nameserver_update(const uip_ipaddr_t *nameserver, uint32_t lifetime) +{ +#if UIP_NAMESERVER_POOL_SIZE > 1 + register uip_nameserver_record *e; + + if(initialized == 0) { + init(); + } + + for(e = list_head(dns); e != NULL; e = list_item_next(e)) { + if(uip_ipaddr_cmp(&e->ip, nameserver)) { + break; + /* RFC6106: In case there's no more space, the new servers should replace + * the the eldest ones */ + } + } + + if(e == NULL) { + if((e = memb_alloc(&dnsmemb)) != NULL) { + list_add(dns, e); + } else { + uip_nameserver_record *p; + for(e = list_head(dns), p = list_head(dns); p != NULL; + p = list_item_next(p)) { + if(DNS_EXPIRATION(p) < DNS_EXPIRATION(e)) { + e = p; + } + } + } + } + + /* RFC6106: In case the entry is existing the expiration time must be + * updated. Otherwise, new entries are added. */ + if(e != NULL) { + if(lifetime == 0) { + memb_free(&dnsmemb, e); + list_remove(dns, e); + } else { + e->added = clock_seconds(); + e->lifetime = lifetime; + uip_ipaddr_copy(&e->ip, nameserver); + } + } +#else /* UIP_NAMESERVER_POOL_SIZE > 1 */ + uip_ipaddr_copy(&serveraddr, nameserver); + serverlifetime = lifetime; +#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */ +} +/*----------------------------------------------------------------------------*/ +#if UIP_NAMESERVER_POOL_SIZE > 1 +/** + * Purge expired records + */ +static void +purge(void) +{ + register uip_nameserver_record *e = NULL; + uint32_t time = clock_seconds(); + for(e = list_head(dns); e != NULL; e = list_item_next(e)) { + if(DNS_EXPIRATION(e) < time) { + list_remove(dns, e); + memb_free(&dnsmemb, e); + e = list_head(dns); + } + } +} +#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */ +/*----------------------------------------------------------------------------*/ +uip_ipaddr_t * +uip_nameserver_get(uint8_t num) +{ +#if UIP_NAMESERVER_POOL_SIZE > 1 + uint8_t i; + uip_nameserver_record *e = NULL; + + if(initialized == 0) { + return NULL; + } + purge(); + for(i = 1, e = list_head(dns); e != NULL && i <= num; + i++, e = list_item_next(e)) { + } + + if(e != NULL) { + return &e->ip; + } + return NULL; +#else /* UIP_NAMESERVER_POOL_SIZE > 1 */ + if(num > 0) { + return NULL; + } + return &serveraddr; +#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */ +} +/*----------------------------------------------------------------------------*/ +uint32_t +uip_nameserver_next_expiration(void) +{ +#if UIP_NAMESERVER_POOL_SIZE > 1 + register uip_nameserver_record *e = NULL; + uint32_t exp = UIP_NAMESERVER_INFINITE_LIFETIME; + uint32_t t; + + if(initialized == 0 || list_length(dns) == 0) { + return 0; + } + purge(); + for(e = list_head(dns); e != NULL; e = list_item_next(e)) { + t = DNS_EXPIRATION(e); + if(t < exp) { + exp = t; + } + } + + return exp; +#else /* UIP_NAMESERVER_POOL_SIZE > 1 */ + return serverlifetime; +#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */ +} +/*----------------------------------------------------------------------------*/ +uint16_t +uip_nameserver_count(void) +{ +#if UIP_NAMESERVER_POOL_SIZE > 1 + if(initialized == 0) { + return 0; + } + return list_length(dns); +#else /* UIP_NAMESERVER_POOL_SIZE > 1 */ +#if NETSTACK_CONF_WITH_IPV6 + if(uip_is_addr_unspecified(&serveraddr)) { +#else /* NETSTACK_CONF_WITH_IPV6 */ + if(uip_ipaddr_cmp(&serveraddr, &uip_all_zeroes_addr)) { +#endif /* NETSTACK_CONF_WITH_IPV6 */ + return 0; + } else { + return 1; + } +#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */ +} +/*----------------------------------------------------------------------------*/ +/** @} */ diff --git a/core/net/ip/uip-nameserver.h b/core/net/ip/uip-nameserver.h new file mode 100644 index 000000000..6acf62290 --- /dev/null +++ b/core/net/ip/uip-nameserver.h @@ -0,0 +1,101 @@ +/** + * \addtogroup uip6 + * @{ + */ + +/** + * \file + * uIP Name Server interface + * \author Víctor Ariño + */ + +/* + * Copyright (c) 2014, tado° GmbH. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#ifndef UIP_NAMESERVER_H_ +#define UIP_NAMESERVER_H_ + +/** + * \name General + * @{ + */ +/** \brief Number of Nameservers to keep */ +#ifndef UIP_CONF_NAMESERVER_POOL_SIZE +#define UIP_NAMESERVER_POOL_SIZE 1 +#else /* UIP_CONF_NAMESERVER_POOL_SIZE */ +#define UIP_NAMESERVER_POOL_SIZE UIP_CONF_NAMESERVER_POOL_SIZE +#endif /* UIP_CONF_NAMESERVER_POOL_SIZE */ +/** \brief Infinite Lifetime indicator */ +#define UIP_NAMESERVER_INFINITE_LIFETIME 0xFFFFFFFF +/** @} */ + +/** + * \name Nameserver maintenance + * @{ + */ +/** + * \brief Insert or update a nameserver into/from the pool + * + * The list is kept according to the RFC6106, which indicates that new entries + * will replace old ones (with lower lifetime) and existing entries will update + * their lifetimes. + * + * \param nameserver Pointer to the nameserver ip address + * \param lifetime Life time of the given address. Minimum is 0, which is + * considered to remove an entry. Maximum is 0xFFFFFFFF which + * is considered infinite. + */ +void uip_nameserver_update(const uip_ipaddr_t *nameserver, uint32_t lifetime); + +/** + * \brief Get a Nameserver ip address given in RA + * + * \param num The number of the nameserver to obtain, starting at 0 and going + * up to the pool size. + */ +uip_ipaddr_t *uip_nameserver_get(uint8_t num); + +/** + * \brief Get next expiration time + * + * The least expiration time is returned + */ +uint32_t uip_nameserver_next_expiration(void); + +/** + * \brief Get the number of recorded name servers + */ +uint16_t uip_nameserver_count(void); +/** @} */ + +#endif /* UIP_NAMESERVER_H_ */ +/** @} */ diff --git a/core/net/ip/uip-split.c b/core/net/ip/uip-split.c index 178d989b0..1150dd337 100644 --- a/core/net/ip/uip-split.c +++ b/core/net/ip/uip-split.c @@ -73,33 +73,33 @@ uip_split_output(void) /* Create the first packet. This is done by altering the length field of the IP header and updating the checksums. */ uip_len = len1 + UIP_TCPIP_HLEN; -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /* For IPv6, the IP length field does not include the IPv6 IP header length. */ BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ BUF->len[0] = uip_len >> 8; BUF->len[1] = uip_len & 0xff; -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /* Recalculate the TCP checksum. */ BUF->tcpchksum = 0; BUF->tcpchksum = ~(uip_tcpchksum()); -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 /* Recalculate the IP checksum. */ BUF->ipchksum = 0; BUF->ipchksum = ~(uip_ipchksum()); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /* Transmit the first packet. */ /* uip_fw_output();*/ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 tcpip_ipv6_output(); #else tcpip_output(); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /* Now, create the second packet. To do this, it is not enough to just alter the length field, but we must also update the TCP @@ -107,15 +107,15 @@ uip_split_output(void) memory. This place is detemined by the length of the first packet (len1). */ uip_len = len2 + UIP_TCPIP_HLEN; -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /* For IPv6, the IP length field does not include the IPv6 IP header length. */ BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ BUF->len[0] = uip_len >> 8; BUF->len[1] = uip_len & 0xff; -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /* uip_appdata += len1;*/ memcpy(uip_appdata, (uint8_t *)uip_appdata + len1, len2); @@ -130,29 +130,29 @@ uip_split_output(void) BUF->tcpchksum = 0; BUF->tcpchksum = ~(uip_tcpchksum()); -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 /* Recalculate the IP checksum. */ BUF->ipchksum = 0; BUF->ipchksum = ~(uip_ipchksum()); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /* Transmit the second packet. */ /* uip_fw_output();*/ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 tcpip_ipv6_output(); #else tcpip_output(); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ return; } #endif /* UIP_TCP */ /* uip_fw_output();*/ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 tcpip_ipv6_output(); #else tcpip_output(); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ } /*-----------------------------------------------------------------------------*/ diff --git a/core/net/ip/uip-udp-packet.c b/core/net/ip/uip-udp-packet.c index b327b652d..aa86435f9 100644 --- a/core/net/ip/uip-udp-packet.c +++ b/core/net/ip/uip-udp-packet.c @@ -51,22 +51,20 @@ void uip_udp_packet_send(struct uip_udp_conn *c, const void *data, int len) { #if UIP_UDP - if(data != NULL) { + if(data != NULL && len <= (UIP_BUFSIZE - (UIP_LLH_LEN + UIP_IPUDPH_LEN))) { uip_udp_conn = c; uip_slen = len; - memcpy(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], data, - len > UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN? - UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN: len); + memmove(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], data, len); uip_process(UIP_UDP_SEND_CONN); -#if UIP_CONF_IPV6_MULTICAST +#if UIP_IPV6_MULTICAST /* Let the multicast engine process the datagram before we send it */ if(uip_is_addr_mcast_routable(&uip_udp_conn->ripaddr)) { UIP_MCAST6.out(); } #endif /* UIP_IPV6_MULTICAST */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 tcpip_ipv6_output(); #else if(uip_len > 0) { diff --git a/core/net/ip/uip.h b/core/net/ip/uip.h index c6a50d699..12d77ff10 100644 --- a/core/net/ip/uip.h +++ b/core/net/ip/uip.h @@ -1,22 +1,3 @@ - -/** - * \addtogroup uip - * @{ - */ - -/** - * \file - * Header file for the uIP TCP/IP stack. - * \author Adam Dunkels - * \author Julien Abeille (IPv6 related code) - * \author Mathilde Durvy (IPv6 related code) - * - * The uIP TCP/IP stack header file contains definitions for a number - * of C macros that are used by uIP programs as well as internal uIP - * structures, TCP/IP header structures and function declarations. - * - */ - /* * Copyright (c) 2001-2003, Adam Dunkels. * All rights reserved. @@ -50,33 +31,45 @@ * */ +/** + * \addtogroup uip + * @{ + */ + +/** + * \file + * Header file for the uIP TCP/IP stack. + * \author Adam Dunkels + * \author Julien Abeille (IPv6 related code) + * \author Mathilde Durvy (IPv6 related code) + * + * The uIP TCP/IP stack header file contains definitions for a number + * of C macros that are used by uIP programs as well as internal uIP + * structures, TCP/IP header structures and function declarations. + * + */ + #ifndef UIP_H_ #define UIP_H_ /* Header sizes. */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #define UIP_IPH_LEN 40 #define UIP_FRAGH_LEN 8 -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_IPH_LEN 20 /* Size of IP header */ -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_UDPH_LEN 8 /* Size of UDP header */ #define UIP_TCPH_LEN 20 /* Size of TCP header */ #define UIP_ICMPH_LEN 4 /* Size of ICMP header */ -#define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN) /* Size of IP + - * UDP - * header */ -#define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN) /* Size of IP + - * TCP - * header */ +#define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN) /* Size of IP + UDP header */ +#define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN) /* Size of IP + TCP header */ #define UIP_TCPIP_HLEN UIP_IPTCPH_LEN -#define UIP_IPICMPH_LEN (UIP_IPH_LEN + UIP_ICMPH_LEN) /* size of ICMP - + IP header */ -#define UIP_LLIPH_LEN (UIP_LLH_LEN + UIP_IPH_LEN) /* size of L2 - + IP header */ -#if UIP_CONF_IPV6 +#define UIP_IPICMPH_LEN (UIP_IPH_LEN + UIP_ICMPH_LEN) /* Size of ICMP + IP header */ +#define UIP_LLIPH_LEN (UIP_LLH_LEN + UIP_IPH_LEN) /* Size of L2 + IP header */ +#if NETSTACK_CONF_WITH_IPV6 /** * The sums below are quite used in ND. When used for uip_buf, we * include link layer length when used for uip_len, we do not, hence @@ -87,30 +80,33 @@ #define uip_l2_l3_icmp_hdr_len (UIP_LLH_LEN + UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN) #define uip_l3_hdr_len (UIP_IPH_LEN + uip_ext_len) #define uip_l3_icmp_hdr_len (UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN) -#endif /*UIP_CONF_IPV6*/ +#endif /*NETSTACK_CONF_WITH_IPV6*/ #include "net/ip/uipopt.h" +/* For memcmp */ +#include + /** * Representation of an IP address. * */ typedef union uip_ip4addr_t { - uint8_t u8[4]; /* Initializer, must come first. */ + uint8_t u8[4]; /* Initializer, must come first. */ uint16_t u16[2]; } uip_ip4addr_t; typedef union uip_ip6addr_t { - uint8_t u8[16]; /* Initializer, must come first. */ + uint8_t u8[16]; /* Initializer, must come first. */ uint16_t u16[8]; } uip_ip6addr_t; -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 typedef uip_ip6addr_t uip_ipaddr_t; -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ typedef uip_ip4addr_t uip_ipaddr_t; -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /*---------------------------------------------------------------------------*/ @@ -140,15 +136,18 @@ typedef struct uip_eth_addr { typedef uip_802154_longaddr uip_lladdr_t; #define UIP_802154_SHORTADDR_LEN 2 #define UIP_802154_LONGADDR_LEN 8 +/** \brief Link layer address length */ #define UIP_LLADDR_LEN UIP_802154_LONGADDR_LEN #else /*UIP_CONF_LL_802154*/ #if UIP_CONF_LL_80211 /** \brief 802.11 address */ typedef uip_80211_addr uip_lladdr_t; +/** \brief Link layer address length */ #define UIP_LLADDR_LEN 6 #else /*UIP_CONF_LL_80211*/ /** \brief Ethernet address */ typedef uip_eth_addr uip_lladdr_t; +/** \brief Link layer address length */ #define UIP_LLADDR_LEN 6 #endif /*UIP_CONF_LL_80211*/ #endif /*UIP_CONF_LL_802154*/ @@ -182,7 +181,7 @@ typedef uip_eth_addr uip_lladdr_t; uip_ipaddr(&addr, 192,168,1,2); uip_sethostaddr(&addr); - + \endcode * \param addr A pointer to an IP address of type uip_ipaddr_t; * @@ -348,7 +347,7 @@ void uip_setipid(uint16_t id); * Periodic processing for a connection identified by its number. * * This function does the necessary periodic processing (timers, - * polling) for a uIP TCP conneciton, and should be called when the + * polling) for a uIP TCP connection, and should be called when the * periodic uIP timer goes off. It should be called for every * connection, regardless of whether they are open of closed. * @@ -391,8 +390,10 @@ void uip_setipid(uint16_t id); uip_process(UIP_TIMER); } while (0) /** + * Macro to determine whether a specific uIP connection is active * - * + * \param conn The connection's number + * \retval 0 Connection closed */ #define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED) @@ -487,7 +488,7 @@ void uip_reass_over(void); /** * The uIP packet buffer. * - * The uip_buf array is used to hold incoming and outgoing + * The uip_aligned_buf array is used to hold incoming and outgoing * packets. The device driver should place incoming data into this * buffer. When sending data, the device driver should read the link * level headers and the TCP/IP headers from this buffer. The size of @@ -517,6 +518,8 @@ typedef union { } uip_buf_t; CCIF extern uip_buf_t uip_aligned_buf; + +/** Macro to access uip_aligned_buf as an array of bytes */ #define uip_buf (uip_aligned_buf.u8) @@ -531,7 +534,7 @@ CCIF extern uip_buf_t uip_aligned_buf; * \defgroup uipappfunc uIP application functions * @{ * - * Functions used by an application running of top of uIP. + * Functions used by an application running on top of uIP. */ /** @@ -594,7 +597,7 @@ void uip_unlisten(uint16_t port); * or NULL if no connection could be allocated. * */ -struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, uint16_t port); +struct uip_conn *uip_connect(const uip_ipaddr_t *ripaddr, uint16_t port); @@ -848,7 +851,7 @@ CCIF void uip_send(const void *data, int len); \code uip_ipaddr_t addr; struct uip_udp_conn *c; - + uip_ipaddr(&addr, 192,168,2,1); c = uip_udp_new(&addr, UIP_HTONS(12345)); if(c != NULL) { @@ -909,7 +912,7 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport); * These functions can be used for converting between different data * formats used by uIP. */ - + /** * Convert an IP address to four bytes separated by commas. * @@ -935,7 +938,7 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport); \code uip_ipaddr_t ipaddr; struct uip_conn *c; - + uip_ipaddr(&ipaddr, 192,168,1,2); c = uip_connect(&ipaddr, UIP_HTONS(80)); \endcode @@ -1024,10 +1027,10 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport); #define uip_ipaddr_copy(dest, src) (*(dest) = *(src)) #endif #ifndef uip_ip4addr_copy -#define uip_ip4addr_copy(dest, src) (*(dest) = *(src)) +#define uip_ip4addr_copy(dest, src) (*((uip_ip4addr_t *)dest) = *((uip_ip4addr_t *)src)) #endif #ifndef uip_ip6addr_copy -#define uip_ip6addr_copy(dest, src) (*(dest) = *(src)) +#define uip_ip6addr_copy(dest, src) (*((uip_ip6addr_t *)dest) = *((uip_ip6addr_t *)src)) #endif /** @@ -1051,14 +1054,14 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport); * \hideinitializer */ #define uip_ip4addr_cmp(addr1, addr2) ((addr1)->u16[0] == (addr2)->u16[0] && \ - (addr1)->u16[1] == (addr2)->u16[1]) + (addr1)->u16[1] == (addr2)->u16[1]) #define uip_ip6addr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0) -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #define uip_ipaddr_cmp(addr1, addr2) uip_ip6addr_cmp(addr1, addr2) -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ #define uip_ipaddr_cmp(addr1, addr2) uip_ip4addr_cmp(addr1, addr2) -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /** * Compare two IP addresses with netmasks @@ -1095,7 +1098,7 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport); -/** +/* * Check if an address is a broadcast address for a network. * * Checks if an address is the broadcast address for a network. The @@ -1320,6 +1323,22 @@ extern uint8_t uip_ext_len; extern uint16_t uip_urglen, uip_surglen; #endif /* UIP_URGDATA > 0 */ +/* + * Clear uIP buffer + * + * This function clears the uIP buffer by reseting the uip_len and + * uip_ext_len pointers. + */ +#if NETSTACK_CONF_WITH_IPV6 +#define uip_clear_buf() { \ + uip_len = 0; \ + uip_ext_len = 0; \ +} +#else /*NETSTACK_CONF_WITH_IPV6*/ +#define uip_clear_buf() { \ + uip_len = 0; \ +} +#endif /*NETSTACK_CONF_WITH_IPV6*/ /** * Representation of a uIP TCP connection. @@ -1333,32 +1352,26 @@ extern uint16_t uip_urglen, uip_surglen; */ struct uip_conn { uip_ipaddr_t ripaddr; /**< The IP address of the remote host. */ - + uint16_t lport; /**< The local TCP port, in network byte order. */ uint16_t rport; /**< The local remote TCP port, in network byte - order. */ - + order. */ + uint8_t rcv_nxt[4]; /**< The sequence number that we expect to - receive next. */ - uint8_t snd_nxt[4]; /**< The sequence number that was last sent by - us. */ + receive next. */ + uint8_t snd_nxt[4]; /**< The sequence number that was last sent by us. */ uint16_t len; /**< Length of the data that was previously sent. */ - uint16_t mss; /**< Current maximum segment size for the - connection. */ - uint16_t initialmss; /**< Initial maximum segment size for the - connection. */ - uint8_t sa; /**< Retransmission time-out calculation state - variable. */ - uint8_t sv; /**< Retransmission time-out calculation state - variable. */ + uint16_t mss; /**< Current maximum segment size for the connection. */ + uint16_t initialmss; /**< Initial maximum segment size for the connection. */ + uint8_t sa; /**< Retransmission time-out calculation state variable. */ + uint8_t sv; /**< Retransmission time-out calculation state variable. */ uint8_t rto; /**< Retransmission time-out. */ uint8_t tcpstateflags; /**< TCP state and flags. */ uint8_t timer; /**< The retransmission timer. */ uint8_t nrtx; /**< The number of retransmissions for the last - segment sent. */ + segment sent. */ - /** The application state. */ - uip_tcp_appstate_t appstate; + uip_tcp_appstate_t appstate; /** The application state. */ }; @@ -1407,7 +1420,13 @@ extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; struct uip_fallback_interface { void (*init)(void); - void (*output)(void); + /** + * \retval >=0 + * in case of success + * \retval <0 + * in case of failure + */ + int (*output)(void); }; #if UIP_CONF_ICMP6 @@ -1436,51 +1455,43 @@ extern struct uip_stats uip_stat; */ struct uip_stats { struct { - uip_stats_t recv; /**< Number of received packets at the IP - layer. */ - uip_stats_t sent; /**< Number of sent packets at the IP - layer. */ - uip_stats_t forwarded;/**< Number of forwarded packets at the IP - layer. */ - uip_stats_t drop; /**< Number of dropped packets at the IP - layer. */ + uip_stats_t recv; /**< Number of received packets at the IP layer. */ + uip_stats_t sent; /**< Number of sent packets at the IP layer. */ + uip_stats_t forwarded;/**< Number of forwarded packets at the IP layer. */ + uip_stats_t drop; /**< Number of dropped packets at the IP layer. */ uip_stats_t vhlerr; /**< Number of packets dropped due to wrong - IP version or header length. */ + IP version or header length. */ uip_stats_t hblenerr; /**< Number of packets dropped due to wrong - IP length, high byte. */ + IP length, high byte. */ uip_stats_t lblenerr; /**< Number of packets dropped due to wrong - IP length, low byte. */ + IP length, low byte. */ uip_stats_t fragerr; /**< Number of packets dropped because they - were IP fragments. */ + were IP fragments. */ uip_stats_t chkerr; /**< Number of packets dropped due to IP - checksum errors. */ + checksum errors. */ uip_stats_t protoerr; /**< Number of packets dropped because they - were neither ICMP, UDP nor TCP. */ + were neither ICMP, UDP nor TCP. */ } ip; /**< IP statistics. */ struct { uip_stats_t recv; /**< Number of received ICMP packets. */ uip_stats_t sent; /**< Number of sent ICMP packets. */ uip_stats_t drop; /**< Number of dropped ICMP packets. */ - uip_stats_t typeerr; /**< Number of ICMP packets with a wrong - type. */ - uip_stats_t chkerr; /**< Number of ICMP packets with a bad - checksum. */ + uip_stats_t typeerr; /**< Number of ICMP packets with a wrong type. */ + uip_stats_t chkerr; /**< Number of ICMP packets with a bad checksum. */ } icmp; /**< ICMP statistics. */ #if UIP_TCP struct { uip_stats_t recv; /**< Number of recived TCP segments. */ uip_stats_t sent; /**< Number of sent TCP segments. */ uip_stats_t drop; /**< Number of dropped TCP segments. */ - uip_stats_t chkerr; /**< Number of TCP segments with a bad - checksum. */ - uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK - number. */ + uip_stats_t chkerr; /**< Number of TCP segments with a bad checksum. */ + uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK number. */ uip_stats_t rst; /**< Number of received TCP RST (reset) segments. */ uip_stats_t rexmit; /**< Number of retransmitted TCP segments. */ uip_stats_t syndrop; /**< Number of dropped SYNs because too few - connections were available. */ + connections were available. */ uip_stats_t synrst; /**< Number of SYNs for closed ports, - triggering a RST. */ + triggering a RST. */ } tcp; /**< TCP statistics. */ #endif #if UIP_UDP @@ -1489,16 +1500,16 @@ struct uip_stats { uip_stats_t recv; /**< Number of recived UDP segments. */ uip_stats_t sent; /**< Number of sent UDP segments. */ uip_stats_t chkerr; /**< Number of UDP segments with a bad - checksum. */ + checksum. */ } udp; /**< UDP statistics. */ #endif /* UIP_UDP */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 struct { uip_stats_t drop; /**< Number of dropped ND6 packets. */ uip_stats_t recv; /**< Number of recived ND6 packets */ uip_stats_t sent; /**< Number of sent ND6 packets */ } nd6; -#endif /*UIP_CONF_IPV6*/ +#endif /*NETSTACK_CONF_WITH_IPV6*/ }; @@ -1526,33 +1537,33 @@ CCIF extern uint8_t uip_flags; functions/macros. */ #define UIP_ACKDATA 1 /* Signifies that the outstanding data was - acked and the application should send - out new data instead of retransmitting - the last data. */ + acked and the application should send + out new data instead of retransmitting + the last data. */ #define UIP_NEWDATA 2 /* Flags the fact that the peer has sent - us new data. */ + us new data. */ #define UIP_REXMIT 4 /* Tells the application to retransmit the - data that was last sent. */ + data that was last sent. */ #define UIP_POLL 8 /* Used for polling the application, to - check if the application has data that - it wants to send. */ + check if the application has data that + it wants to send. */ #define UIP_CLOSE 16 /* The remote host has closed the - connection, thus the connection has - gone away. Or the application signals - that it wants to close the - connection. */ + connection, thus the connection has + gone away. Or the application signals + that it wants to close the + connection. */ #define UIP_ABORT 32 /* The remote host has aborted the - connection, thus the connection has - gone away. Or the application signals - that it wants to abort the - connection. */ + connection, thus the connection has + gone away. Or the application signals + that it wants to abort the + connection. */ #define UIP_CONNECTED 64 /* We have got a connection from a remote host and have set up a new connection for it, or an active connection has been successfully established. */ #define UIP_TIMEDOUT 128 /* The connection has been aborted due to - too many retransmissions. */ + too many retransmissions. */ /** @@ -1569,25 +1580,25 @@ uip_ext_hdr_options_process(); */ * The actual uIP function which does all the work. */ void uip_process(uint8_t flag); - + /* The following flags are passed as an argument to the uip_process() function. They are used to distinguish between the two cases where uip_process() is called. It can be called either because we have incoming data that should be processed, or because the periodic timer has fired. These values are never used directly, but only in the macros defined in this file. */ - + #define UIP_DATA 1 /* Tells uIP that there is incoming - data in the uip_buf buffer. The - length of the data is stored in the - global variable uip_len. */ + data in the uip_buf buffer. The + length of the data is stored in the + global variable uip_len. */ #define UIP_TIMER 2 /* Tells uIP that the periodic timer - has fired. */ + has fired. */ #define UIP_POLL_REQUEST 3 /* Tells uIP that a connection should - be polled. */ + be polled. */ #define UIP_UDP_SEND_CONN 4 /* Tells uIP that a UDP datagram - should be constructed in the - uip_buf buffer. */ + should be constructed in the + uip_buf buffer. */ #if UIP_UDP #define UIP_UDP_TIMER 5 #endif /* UIP_UDP */ @@ -1603,12 +1614,12 @@ void uip_process(uint8_t flag); #define UIP_TIME_WAIT 7 #define UIP_LAST_ACK 8 #define UIP_TS_MASK 15 - + #define UIP_STOPPED 16 /* The TCP and IP headers. */ struct uip_tcpip_hdr { -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /* IPv6 header. */ uint8_t vtc, tcflow; @@ -1616,7 +1627,7 @@ struct uip_tcpip_hdr { uint8_t len[2]; uint8_t proto, ttl; uip_ip6addr_t srcipaddr, destipaddr; -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ /* IPv4 header. */ uint8_t vhl, tos, @@ -1627,8 +1638,8 @@ struct uip_tcpip_hdr { proto; uint16_t ipchksum; uip_ipaddr_t srcipaddr, destipaddr; -#endif /* UIP_CONF_IPV6 */ - +#endif /* NETSTACK_CONF_WITH_IPV6 */ + /* TCP header. */ uint16_t srcport, destport; @@ -1644,7 +1655,7 @@ struct uip_tcpip_hdr { /* The ICMP and IP headers. */ struct uip_icmpip_hdr { -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /* IPv6 header. */ uint8_t vtc, tcf; @@ -1652,7 +1663,7 @@ struct uip_icmpip_hdr { uint8_t len[2]; uint8_t proto, ttl; uip_ip6addr_t srcipaddr, destipaddr; -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ /* IPv4 header. */ uint8_t vhl, tos, @@ -1663,21 +1674,21 @@ struct uip_icmpip_hdr { proto; uint16_t ipchksum; uip_ipaddr_t srcipaddr, destipaddr; -#endif /* UIP_CONF_IPV6 */ - +#endif /* NETSTACK_CONF_WITH_IPV6 */ + /* ICMP header. */ uint8_t type, icode; uint16_t icmpchksum; -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 uint16_t id, seqno; uint8_t payload[1]; -#endif /* !UIP_CONF_IPV6 */ +#endif /* !NETSTACK_CONF_WITH_IPV6 */ }; /* The UDP and IP headers. */ struct uip_udpip_hdr { -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /* IPv6 header. */ uint8_t vtc, tcf; @@ -1685,7 +1696,7 @@ struct uip_udpip_hdr { uint8_t len[2]; uint8_t proto, ttl; uip_ip6addr_t srcipaddr, destipaddr; -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ /* IP header. */ uint8_t vhl, tos, @@ -1696,8 +1707,8 @@ struct uip_udpip_hdr { proto; uint16_t ipchksum; uip_ipaddr_t srcipaddr, destipaddr; -#endif /* UIP_CONF_IPV6 */ - +#endif /* NETSTACK_CONF_WITH_IPV6 */ + /* UDP header. */ uint16_t srcport, destport; @@ -1712,7 +1723,7 @@ struct uip_udpip_hdr { */ /* The IP header */ struct uip_ip_hdr { -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /* IPV6 header */ uint8_t vtc; uint8_t tcflow; @@ -1720,7 +1731,7 @@ struct uip_ip_hdr { uint8_t len[2]; uint8_t proto, ttl; uip_ip6addr_t srcipaddr, destipaddr; -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ /* IPV4 header */ uint8_t vhl, tos, @@ -1731,7 +1742,7 @@ struct uip_ip_hdr { proto; uint16_t ipchksum; uip_ipaddr_t srcipaddr, destipaddr; -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ }; @@ -1790,6 +1801,13 @@ typedef struct uip_routing_hdr { uint8_t seg_left; } uip_routing_hdr; +/* RPL Source Routing Header */ +typedef struct uip_rpl_srh_hdr { + uint8_t cmpr; /* CmprI and CmprE */ + uint8_t pad; + uint8_t reserved[2]; +} uip_rpl_srh_hdr; + /* fragmentation header */ typedef struct uip_frag_hdr { uint8_t next; @@ -1840,9 +1858,9 @@ struct uip_tcp_hdr { struct uip_icmp_hdr { uint8_t type, icode; uint16_t icmpchksum; -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 uint16_t id, seqno; -#endif /* !UIP_CONF_IPV6 */ +#endif /* !NETSTACK_CONF_WITH_IPV6 */ }; @@ -1878,7 +1896,7 @@ struct uip_udp_hdr { #define UIP_PROTO_ICMP6 58 -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /** @{ */ /** \brief extension headers types */ #define UIP_PROTO_HBHO 0 @@ -1915,7 +1933,7 @@ struct uip_udp_hdr { /** @} */ -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #if UIP_FIXEDADDR @@ -1935,7 +1953,7 @@ CCIF extern uip_lladdr_t uip_lladdr; -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /** Length of the link local prefix */ #define UIP_LLPREF_LEN 10 @@ -1994,8 +2012,9 @@ CCIF extern uip_lladdr_t uip_lladdr; (((a)->u8[15]) == 0x02)) /** - * \brief Checks whether the address a is link local. - * a is of type uip_ipaddr_t + * \brief is addr (a) a link local unicast address, see RFC3513 + * i.e. is (a) on prefix FE80::/10 + * a is of type uip_ipaddr_t* */ #define uip_is_addr_linklocal(a) \ ((a)->u8[0] == 0xfe && \ @@ -2032,7 +2051,7 @@ CCIF extern uip_lladdr_t uip_lladdr; (((a)->u8[12]) == 0xFF)) /** - * \briefput in b the solicited node address corresponding to address a + * \brief put in b the solicited node address corresponding to address a * both a and b are of type uip_ipaddr_t* * */ #define uip_create_solicited_node(a, b) \ @@ -2048,15 +2067,6 @@ CCIF extern uip_lladdr_t uip_lladdr; (((b)->u8[13]) = ((a)->u8[13])); \ (((b)->u16[7]) = ((a)->u16[7])) -/** - * \brief is addr (a) a link local unicast address, see RFC3513 - * i.e. is (a) on prefix FE80::/10 - * a is of type uip_ipaddr_t* - */ -#define uip_is_addr_link_local(a) \ - ((((a)->u8[0]) == 0xFE) && \ - (((a)->u8[1]) == 0x80)) - /** * \brief was addr (a) forged based on the mac address m * a type is uip_ipaddr_t @@ -2083,7 +2093,7 @@ CCIF extern uip_lladdr_t uip_lladdr; (((a)->u8[13]) == (m)->addr[3]) && \ (((a)->u8[14]) == (m)->addr[4]) && \ (((a)->u8[15]) == (m)->addr[5])) - + #endif /*UIP_CONF_LL_802154*/ /** @@ -2160,7 +2170,7 @@ CCIF extern uip_lladdr_t uip_lladdr; (((a)->u8[14]) == ((b)->u8[14])) && \ (((a)->u8[15]) == ((b)->u8[15]))) -#endif /*UIP_CONF_IPV6*/ +#endif /*NETSTACK_CONF_WITH_IPV6*/ /** * Calculate the Internet checksum over a buffer. @@ -2170,7 +2180,7 @@ CCIF extern uip_lladdr_t uip_lladdr; * * See RFC1071. * - * \param buf A pointer to the buffer over which the checksum is to be + * \param data A pointer to the buffer over which the checksum is to be * computed. * * \param len The length of the buffer over which the checksum is to @@ -2178,7 +2188,7 @@ CCIF extern uip_lladdr_t uip_lladdr; * * \return The Internet checksum of the buffer. */ -uint16_t uip_chksum(uint16_t *buf, uint16_t len); +uint16_t uip_chksum(uint16_t *data, uint16_t len); /** * Calculate the IP header checksum of the packet header in uip_buf. diff --git a/core/net/ip/uip_arch.h b/core/net/ip/uip_arch.h index b4849bb5d..352a39711 100644 --- a/core/net/ip/uip_arch.h +++ b/core/net/ip/uip_arch.h @@ -1,29 +1,3 @@ -/** - * \addtogroup uip - * {@ - */ - -/** - * \defgroup uiparch Architecture specific uIP functions - * @{ - * - * The functions in the architecture specific module implement the IP - * check sum and 32-bit additions. - * - * The IP checksum calculation is the most computationally expensive - * operation in the TCP/IP stack and it therefore pays off to - * implement this in efficient assembler. The purpose of the uip-arch - * module is to let the checksum functions to be implemented in - * architecture specific assembler. - * - */ - -/** - * \file - * Declarations of architecture specific functions. - * \author Adam Dunkels - */ - /* * Copyright (c) 2001, Adam Dunkels. * All rights reserved. @@ -57,6 +31,32 @@ * */ +/** + * \file + * Declarations of architecture specific functions. + * \author Adam Dunkels + */ + +/** + * \addtogroup uip + * {@ + */ + +/** + * \defgroup uiparch Architecture specific uIP functions + * @{ + * + * The functions in the architecture specific module implement the IP + * check sum and 32-bit additions. + * + * The IP checksum calculation is the most computationally expensive + * operation in the TCP/IP stack and it therefore pays off to + * implement this in efficient assembler. The purpose of the uip-arch + * module is to let the checksum functions to be implemented in + * architecture specific assembler. + * + */ + #ifndef UIP_ARCH_H_ #define UIP_ARCH_H_ @@ -93,7 +93,7 @@ void uip_add32(uint8_t *op32, uint16_t op16); * \note This function is not called in the current version of uIP, * but future versions might make use of it. * - * \param buf A pointer to the buffer over which the checksum is to be + * \param data A pointer to the buffer over which the checksum is to be * computed. * * \param len The length of the buffer over which the checksum is to @@ -101,7 +101,7 @@ void uip_add32(uint8_t *op32, uint16_t op16); * * \return The Internet checksum of the buffer. */ -uint16_t uip_chksum(uint16_t *buf, uint16_t len); +uint16_t uip_chksum(uint16_t *data, uint16_t len); /** * Calculate the IP header checksum of the packet header in uip_buf. diff --git a/core/net/ip/uiplib.c b/core/net/ip/uiplib.c index 44b1b54e1..35a56be4c 100644 --- a/core/net/ip/uiplib.c +++ b/core/net/ip/uiplib.c @@ -41,7 +41,7 @@ #include "net/ip/uip-debug.h" /*-----------------------------------------------------------------------------------*/ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 int uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *ipaddr) { @@ -103,7 +103,7 @@ uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *ipaddr) return 1; } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /*-----------------------------------------------------------------------------------*/ /* Parse a IPv4-address from a string. Returns the number of characters read * for the address. */ diff --git a/core/net/ip/uiplib.h b/core/net/ip/uiplib.h index 5f053df5d..98adec02d 100644 --- a/core/net/ip/uiplib.h +++ b/core/net/ip/uiplib.h @@ -1,11 +1,3 @@ -/** - * \file - * Various uIP library functions. - * \author - * Adam Dunkels - * - */ - /* * Copyright (c) 2002, Adam Dunkels. * All rights reserved. @@ -39,6 +31,15 @@ * * */ + +/** + * \file + * Various uIP library functions. + * \author + * Adam Dunkels + * + */ + #ifndef UIPLIB_H_ #define UIPLIB_H_ @@ -66,11 +67,11 @@ * \retval 0 If the IP address could not be parsed. * \retval Non-zero If the IP address was parsed. */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #define uiplib_ipaddrconv uiplib_ip6addrconv -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ #define uiplib_ipaddrconv uiplib_ip4addrconv -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ CCIF int uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *addr); CCIF int uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *addr); diff --git a/core/net/ip/uipopt.h b/core/net/ip/uipopt.h index abf223647..7a523b254 100644 --- a/core/net/ip/uipopt.h +++ b/core/net/ip/uipopt.h @@ -1,33 +1,3 @@ -/** - * \addtogroup uip - * @{ - */ - -/** - * \defgroup uipopt Configuration options for uIP - * @{ - * - * uIP is configured using the per-project configuration file - * "uipopt.h". This file contains all compile-time options for uIP and - * should be tweaked to match each specific project. The uIP - * distribution contains a documented example "uipopt.h" that can be - * copied and modified for each project. - * - * \note Contiki does not use the uipopt.h file to configure uIP, but - * uses a per-port uip-conf.h file that should be edited instead. - */ - -/** - * \file - * Configuration options for uIP. - * \author Adam Dunkels - * - * This file is used for tweaking various configuration options for - * uIP. You should make a copy of this file into one of your project's - * directories instead of editing this example "uipopt.h" file that - * comes with the uIP distribution. - */ - /* * Copyright (c) 2001-2003, Adam Dunkels. * All rights reserved. @@ -61,6 +31,36 @@ * */ +/** + * \file + * Configuration options for uIP. + * \author Adam Dunkels + * + * This file is used for tweaking various configuration options for + * uIP. You should make a copy of this file into one of your project's + * directories instead of editing this example "uipopt.h" file that + * comes with the uIP distribution. + */ + +/** + * \addtogroup uip + * @{ + */ + +/** + * \defgroup uipopt Configuration options for uIP + * @{ + * + * uIP is configured using the per-project configuration file + * "uipopt.h". This file contains all compile-time options for uIP and + * should be tweaked to match each specific project. The uIP + * distribution contains a documented example "uipopt.h" that can be + * copied and modified for each project. + * + * \note Contiki does not use the uipopt.h file to configure uIP, but + * uses a per-port uip-conf.h file that should be edited instead. + */ + #ifndef UIPOPT_H_ #define UIPOPT_H_ @@ -282,9 +282,9 @@ void uip_log(char *msg); /** The maximum transmission unit at the IP Layer*/ #define UIP_LINK_MTU 1280 -#ifndef UIP_CONF_IPV6 +#ifndef NETSTACK_CONF_WITH_IPV6 /** Do we use IPv6 or not (default: no) */ -#define UIP_CONF_IPV6 0 +#define NETSTACK_CONF_WITH_IPV6 0 #endif #ifndef UIP_CONF_IPV6_QUEUE_PKT @@ -351,7 +351,7 @@ void uip_log(char *msg); #ifdef UIP_CONF_UDP_CHECKSUMS #define UIP_UDP_CHECKSUMS (UIP_CONF_UDP_CHECKSUMS) #else -#define UIP_UDP_CHECKSUMS (UIP_CONF_IPV6) +#define UIP_UDP_CHECKSUMS (NETSTACK_CONF_WITH_IPV6) #endif /** diff --git a/core/net/ip64/README.md b/core/net/ip64/README.md new file mode 100644 index 000000000..8f2607337 --- /dev/null +++ b/core/net/ip64/README.md @@ -0,0 +1,29 @@ +The `ip64` module lets an IPv6 Contiki network be connected to an IPv4 +network without any additional configuration or outside software. The +`ip64` module runs on the RPL root node and translates outgoing IPv6 +packets into IPv4 packets nd incoming IPv4 packets to IPv6 packets. + +The `ip64` module uses stateful NAT64 (RFC6164) to do the packet +translation and DNS64 (RFC6147) to catch DNS requests for IPv6 +addresses, turn them into requests for IPv4 addresses, and turn the +replies into responses for IPv6 addresses. This allows devices on the +inside IPv6 network to connect to named servers on the outside IPv4 +network. + +The `ip64` module hooks into the IPv6 stack via a fallback +interface. Any packet that can not be routed into the local RPL mesh +will be sent over the fallback interface, where `ip64` picks it up, +translates it into an IPv4 packet, and sends it over its outgoing +interface. + +In addition to providing NAT64 and DNS64 services, the `ip64` module +also performs DHCPv4 to request IPv4 address for devices connected to +a medium such as Ethernet. The `ip64` module also performs ARP +processing to communicate over the Ethernet. + +The `ip64` module uses a configuration file called `ip64-conf.h` that +specifies what device to use for the IPv4 network. This file is +intended to be placed in the platform directory. An example +configuration file called `ip64-conf-example.h` is provided in this +directory. + diff --git a/core/net/ip64/ip64-addrmap.c b/core/net/ip64/ip64-addrmap.c new file mode 100644 index 000000000..3a36b2344 --- /dev/null +++ b/core/net/ip64/ip64-addrmap.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#include "ip64-addrmap.h" + +#include "lib/memb.h" +#include "lib/list.h" + +#include "ip64-conf.h" + +#include "lib/random.h" + +#include + +#ifdef IP64_ADDRMAP_CONF_ENTRIES +#define NUM_ENTRIES IP64_ADDRMAP_CONF_ENTRIES +#else /* IP64_ADDRMAP_CONF_ENTRIES */ +#define NUM_ENTRIES 32 +#endif /* IP64_ADDRMAP_CONF_ENTRIES */ + +MEMB(entrymemb, struct ip64_addrmap_entry, NUM_ENTRIES); +LIST(entrylist); + +#define FIRST_MAPPED_PORT 10000 +#define LAST_MAPPED_PORT 20000 +static uint16_t mapped_port = FIRST_MAPPED_PORT; + +#define printf(...) + +/*---------------------------------------------------------------------------*/ +struct ip64_addrmap_entry * +ip64_addrmap_list(void) +{ + return list_head(entrylist); +} +/*---------------------------------------------------------------------------*/ +void +ip64_addrmap_init(void) +{ + memb_init(&entrymemb); + list_init(entrylist); + mapped_port = FIRST_MAPPED_PORT; +} +/*---------------------------------------------------------------------------*/ +static void +check_age(void) +{ + struct ip64_addrmap_entry *m; + + /* Walk through the list of address mappings, throw away the ones + that are too old. */ + m = list_head(entrylist); + while(m != NULL) { + if(timer_expired(&m->timer)) { + list_remove(entrylist, m); + memb_free(&entrymemb, m); + m = list_head(entrylist); + } else { + m = list_item_next(m); + } + } +} +/*---------------------------------------------------------------------------*/ +static int +recycle(void) +{ + /* Find the oldest recyclable mapping and remove it. */ + struct ip64_addrmap_entry *m, *oldest; + + /* Walk through the list of address mappings, throw away the ones + that are too old. */ + + oldest = NULL; + for(m = list_head(entrylist); + m != NULL; + m = list_item_next(m)) { + if(m->flags & FLAGS_RECYCLABLE) { + if(oldest == NULL) { + oldest = m; + } else { + if(timer_remaining(&m->timer) < + timer_remaining(&oldest->timer)) { + oldest = m; + } + } + } + } + + /* If we found an oldest recyclable entry, remove it and return + non-zero. */ + if(oldest != NULL) { + list_remove(entrylist, oldest); + memb_free(&entrymemb, oldest); + return 1; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +struct ip64_addrmap_entry * +ip64_addrmap_lookup(const uip_ip6addr_t *ip6addr, + uint16_t ip6port, + const uip_ip4addr_t *ip4addr, + uint16_t ip4port, + uint8_t protocol) +{ + struct ip64_addrmap_entry *m; + + printf("lookup ip4port %d ip6port %d\n", uip_htons(ip4port), + uip_htons(ip6port)); + check_age(); + for(m = list_head(entrylist); m != NULL; m = list_item_next(m)) { + printf("protocol %d %d, ip4port %d %d, ip6port %d %d, ip4 %d ip6 %d\n", + m->protocol, protocol, + m->ip4port, ip4port, + m->ip6port, ip6port, + uip_ip4addr_cmp(&m->ip4addr, ip4addr), + uip_ip6addr_cmp(&m->ip6addr, ip6addr)); + if(m->protocol == protocol && + m->ip4port == ip4port && + m->ip6port == ip6port && + uip_ip4addr_cmp(&m->ip4addr, ip4addr) && + uip_ip6addr_cmp(&m->ip6addr, ip6addr)) { + m->ip6to4++; + return m; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +struct ip64_addrmap_entry * +ip64_addrmap_lookup_port(uint16_t mapped_port, uint8_t protocol) +{ + struct ip64_addrmap_entry *m; + + check_age(); + for(m = list_head(entrylist); m != NULL; m = list_item_next(m)) { + printf("mapped port %d %d, protocol %d %d\n", + m->mapped_port, mapped_port, + m->protocol, protocol); + if(m->mapped_port == mapped_port && + m->protocol == protocol) { + m->ip4to6++; + return m; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +static void +increase_mapped_port(void) +{ + mapped_port = (random_rand() % (LAST_MAPPED_PORT - FIRST_MAPPED_PORT)) + + FIRST_MAPPED_PORT; +} +/*---------------------------------------------------------------------------*/ +struct ip64_addrmap_entry * +ip64_addrmap_create(const uip_ip6addr_t *ip6addr, + uint16_t ip6port, + const uip_ip4addr_t *ip4addr, + uint16_t ip4port, + uint8_t protocol) +{ + struct ip64_addrmap_entry *m; + + check_age(); + m = memb_alloc(&entrymemb); + if(m == NULL) { + /* We could not allocate an entry, try to recycle one and try to + allocate again. */ + if(recycle()) { + m = memb_alloc(&entrymemb); + } + } + if(m != NULL) { + uip_ip4addr_copy(&m->ip4addr, ip4addr); + m->ip4port = ip4port; + uip_ip6addr_copy(&m->ip6addr, ip6addr); + m->ip6port = ip6port; + m->protocol = protocol; + m->flags = FLAGS_NONE; + m->ip6to4 = 1; + m->ip4to6 = 0; + timer_set(&m->timer, 0); + + /* Pick a new, unused local port. First make sure that the + mapped_port number does not belong to any active connection. If + so, we keep increasing the mapped_port until we're free. */ + { + struct ip64_addrmap_entry *n; + n = list_head(entrylist); + while(n != NULL) { + if(n->mapped_port == mapped_port) { + increase_mapped_port(); + n = list_head(entrylist); + } else { + n = list_item_next(m); + } + } + } + m->mapped_port = mapped_port; + increase_mapped_port(); + + list_add(entrylist, m); + return m; + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +void +ip64_addrmap_set_lifetime(struct ip64_addrmap_entry *e, + clock_time_t time) +{ + if(e != NULL) { + timer_set(&e->timer, time); + } +} +/*---------------------------------------------------------------------------*/ +void +ip64_addrmap_set_recycleble(struct ip64_addrmap_entry *e) +{ + if(e != NULL) { + e->flags |= FLAGS_RECYCLABLE; + } +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/ip64/ip64-addrmap.h b/core/net/ip64/ip64-addrmap.h new file mode 100644 index 000000000..c4a31efcc --- /dev/null +++ b/core/net/ip64/ip64-addrmap.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#ifndef IP64_ADDRMAP_H +#define IP64_ADDRMAP_H + + +#include "sys/timer.h" +#include "net/ip/uip.h" + +struct ip64_addrmap_entry { + struct ip64_addrmap_entry *next; + struct timer timer; + uip_ip6addr_t ip6addr; + uip_ip4addr_t ip4addr; + uint32_t ip6to4, ip4to6; + uint16_t mapped_port; + uint16_t ip6port; + uint16_t ip4port; + uint8_t protocol; + uint8_t flags; +}; + +#define FLAGS_NONE 0 +#define FLAGS_RECYCLABLE 1 + +/** + * Initialize the ip64_addrmap module. + */ +void ip64_addrmap_init(void); + + +/** + * Look up an address mapping from inside the IPv6 network, given the + * IPv6 address/port, the IPv4 address/port, and the protocol. + */ +struct ip64_addrmap_entry *ip64_addrmap_lookup(const uip_ip6addr_t *ip6addr, + uint16_t ip6port, + const uip_ip4addr_t *ip4addr, + uint16_t ip4port, + uint8_t protocol); + +/** + * Look up an address mapping from the outside IPv4 network, given the + * mapped port number and protocol. + */ +struct ip64_addrmap_entry *ip64_addrmap_lookup_port(uint16_t mappedport, + uint8_t protocol); + +/** + * Create a new address mapping from an IPv6 address/port, an IPv4 + * address/port, and a protocol number. + */ +struct ip64_addrmap_entry *ip64_addrmap_create(const uip_ip6addr_t *ip6addr, + uint16_t ip6port, + const uip_ip4addr_t *ip4addr, + uint16_t ip4port, + uint8_t protocol); + +/** + * Set the lifetime of an address mapping. + */ +void ip64_addrmap_set_lifetime(struct ip64_addrmap_entry *e, + clock_time_t lifetime); + +/** + * Mark an address mapping to be recyclable. + */ +void ip64_addrmap_set_recycleble(struct ip64_addrmap_entry *e); + +/** + * Obtain the list of all address mappings. + */ +struct ip64_addrmap_entry *ip64_addrmap_list(void); +#endif /* IP64_ADDRMAP_H */ diff --git a/core/net/ip64/ip64-arp.c b/core/net/ip64/ip64-arp.c new file mode 100644 index 000000000..996773e1d --- /dev/null +++ b/core/net/ip64/ip64-arp.c @@ -0,0 +1,417 @@ +/* + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: uip_arp.c,v 1.8 2010/12/14 22:45:22 dak664 Exp $ + * + */ + +#include "ip64.h" +#include "ip64-eth.h" +#include "ip64-arp.h" + +#include +#include + +#define printf(...) + +struct arp_hdr { + struct ip64_eth_hdr ethhdr; + uint16_t hwtype; + uint16_t protocol; + uint8_t hwlen; + uint8_t protolen; + uint16_t opcode; + struct uip_eth_addr shwaddr; + uip_ip4addr_t sipaddr; + struct uip_eth_addr dhwaddr; + uip_ip4addr_t dipaddr; +}; + +struct ethip_hdr { + struct ip64_eth_hdr ethhdr; + /* IP header. */ + uint8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + uint16_t ipchksum; + uip_ip4addr_t srcipaddr, destipaddr; +}; + +struct ipv4_hdr { + /* IP header. */ + uint8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + uint16_t ipchksum; + uip_ip4addr_t srcipaddr, destipaddr; +}; + +#define ARP_REQUEST 1 +#define ARP_REPLY 2 + +#define ARP_HWTYPE_ETH 1 + +struct arp_entry { + uip_ip4addr_t ipaddr; + struct uip_eth_addr ethaddr; + uint8_t time; +}; + +static const struct ip64_eth_addr broadcast_ethaddr = + {{0xff,0xff,0xff,0xff,0xff,0xff}}; +static const uint16_t broadcast_ipaddr[2] = {0xffff,0xffff}; + +static struct arp_entry arp_table[UIP_ARPTAB_SIZE]; + +static uint8_t arptime; +static uint8_t tmpage; + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +const uip_ipaddr_t uip_all_zeroes_addr; + +/*---------------------------------------------------------------------------*/ +/** + * Initialize the ARP module. + * + */ +/*---------------------------------------------------------------------------*/ +void +ip64_arp_init(void) +{ + int i; + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + memset(&arp_table[i].ipaddr, 0, 4); + } +} +/*---------------------------------------------------------------------------*/ +/** + * Periodic ARP processing function. + * + * This function performs periodic timer processing in the ARP module + * and should be called at regular intervals. The recommended interval + * is 10 seconds between the calls. + * + */ +/*---------------------------------------------------------------------------*/ +void +ip64_arp_timer(void) +{ + struct arp_entry *tabptr; + int i; + + ++arptime; + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + tabptr = &arp_table[i]; + if(uip_ip4addr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr) && + arptime - tabptr->time >= UIP_ARP_MAXAGE) { + memset(&tabptr->ipaddr, 0, 4); + } + } + +} + +/*---------------------------------------------------------------------------*/ +static void +arp_update(uip_ip4addr_t *ipaddr, struct uip_eth_addr *ethaddr) +{ + register struct arp_entry *tabptr = arp_table; + int i, c; + + /* Walk through the ARP mapping table and try to find an entry to + update. If none is found, the IP -> MAC address mapping is + inserted in the ARP table. */ + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + tabptr = &arp_table[i]; + + /* Only check those entries that are actually in use. */ + if(!uip_ip4addr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) { + + /* Check if the source IP address of the incoming packet matches + the IP address in this ARP table entry. */ + if(uip_ip4addr_cmp(ipaddr, &tabptr->ipaddr)) { + + /* An old entry found, update this and return. */ + memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); + tabptr->time = arptime; + + return; + } + } + tabptr++; + } + + /* If we get here, no existing ARP table entry was found, so we + create one. */ + + /* First, we try to find an unused entry in the ARP table. */ + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + tabptr = &arp_table[i]; + if(uip_ip4addr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) { + break; + } + } + + /* If no unused entry is found, we try to find the oldest entry and + throw it away. */ + if(i == UIP_ARPTAB_SIZE) { + tmpage = 0; + c = 0; + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + tabptr = &arp_table[i]; + if(arptime - tabptr->time > tmpage) { + tmpage = arptime - tabptr->time; + c = i; + } + } + i = c; + tabptr = &arp_table[i]; + } + + /* Now, i is the ARP table entry which we will fill with the new + information. */ + uip_ip4addr_copy(&tabptr->ipaddr, ipaddr); + memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); + tabptr->time = arptime; +} +/*---------------------------------------------------------------------------*/ +uint16_t +ip64_arp_arp_input(const uint8_t *packet, uint16_t packet_len) +{ + struct arp_hdr *arphdr = (struct arp_hdr *)packet; + + if(packet_len < sizeof(struct arp_hdr)) { + printf("ip64_arp_arp_input: len too small %d\n", packet_len); + return 0; + } + + switch(arphdr->opcode) { + case UIP_HTONS(ARP_REQUEST): + /* ARP request. If it asked for our address, we send out a + reply. */ + printf("ip64_arp_arp_input: request for %d.%d.%d.%d (we are %d.%d.%d.%d)\n", + arphdr->dipaddr.u8[0], arphdr->dipaddr.u8[1], + arphdr->dipaddr.u8[2], arphdr->dipaddr.u8[3], + ip64_get_hostaddr()->u8[0], ip64_get_hostaddr()->u8[1], + ip64_get_hostaddr()->u8[2], ip64_get_hostaddr()->u8[3]); + if(uip_ip4addr_cmp(&arphdr->dipaddr, ip64_get_hostaddr())) { + /* First, we register the one who made the request in our ARP + table, since it is likely that we will do more communication + with this host in the future. */ + arp_update(&arphdr->sipaddr, &arphdr->shwaddr); + + arphdr->opcode = UIP_HTONS(ARP_REPLY); + + memcpy(arphdr->dhwaddr.addr, arphdr->shwaddr.addr, 6); + memcpy(arphdr->shwaddr.addr, ip64_eth_addr.addr, 6); + memcpy(arphdr->ethhdr.src.addr, ip64_eth_addr.addr, 6); + memcpy(arphdr->ethhdr.dest.addr, arphdr->dhwaddr.addr, 6); + + uip_ip4addr_copy(&arphdr->dipaddr, &arphdr->sipaddr); + uip_ip4addr_copy(&arphdr->sipaddr, ip64_get_hostaddr()); + + arphdr->ethhdr.type = UIP_HTONS(IP64_ETH_TYPE_ARP); + return sizeof(struct arp_hdr); + } + break; + case UIP_HTONS(ARP_REPLY): + /* ARP reply. We insert or update the ARP table if it was meant + for us. */ + if(uip_ip4addr_cmp(&arphdr->dipaddr, ip64_get_hostaddr())) { + arp_update(&arphdr->sipaddr, &arphdr->shwaddr); + } + break; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +int +ip64_arp_check_cache(const uint8_t *nlhdr) +{ + struct ipv4_hdr *ipv4_hdr = (struct ipv4_hdr *)nlhdr; + uip_ip4addr_t broadcast_addr; + struct arp_entry *tabptr = arp_table; + + printf("check cache %d.%d.%d.%d\n", + uip_ipaddr_to_quad(&ipv4_hdr->destipaddr)); + + /* First check if destination is a local broadcast. */ + uip_ipaddr(&broadcast_addr, 255,255,255,255); + if(uip_ip4addr_cmp(&ipv4_hdr->destipaddr, &broadcast_addr)) { + printf("Return 1\n"); + return 1; + } else if(ipv4_hdr->destipaddr.u8[0] == 224) { + /* Multicast. */ + return 1; + } else { + uip_ip4addr_t ipaddr; + int i; + /* Check if the destination address is on the local network. */ + if(!uip_ipaddr_maskcmp(&ipv4_hdr->destipaddr, + ip64_get_hostaddr(), + ip64_get_netmask())) { + /* Destination address was not on the local network, so we need to + use the default router's IP address instead of the destination + address when determining the MAC address. */ + uip_ip4addr_copy(&ipaddr, ip64_get_draddr()); + } else { + /* Else, we use the destination IP address. */ + uip_ip4addr_copy(&ipaddr, &ipv4_hdr->destipaddr); + } + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + if(uip_ip4addr_cmp(&ipaddr, &tabptr->ipaddr)) { + break; + } + tabptr++; + } + + if(i == UIP_ARPTAB_SIZE) { + return 0; + } + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +int +ip64_arp_create_ethhdr(uint8_t *llhdr, const uint8_t *nlhdr) +{ + struct arp_entry *tabptr = arp_table; + struct ipv4_hdr *ipv4_hdr = (struct ipv4_hdr *)nlhdr; + struct ip64_eth_hdr *ethhdr = (struct ip64_eth_hdr *)llhdr; + uip_ip4addr_t broadcast_addr; + + /* Find the destination IP address in the ARP table and construct + the Ethernet header. If the destination IP addres isn't on the + local network, we use the default router's IP address instead. + + If not ARP table entry is found, we overwrite the original IP + packet with an ARP request for the IP address. */ + + /* First check if destination is a local broadcast. */ + uip_ipaddr(&broadcast_addr, 255,255,255,255); + if(uip_ip4addr_cmp(&ipv4_hdr->destipaddr, &broadcast_addr)) { + memcpy(ðhdr->dest.addr, &broadcast_ethaddr.addr, 6); + } else if(ipv4_hdr->destipaddr.u8[0] == 224) { + /* Multicast. */ + ethhdr->dest.addr[0] = 0x01; + ethhdr->dest.addr[1] = 0x00; + ethhdr->dest.addr[2] = 0x5e; + ethhdr->dest.addr[3] = ipv4_hdr->destipaddr.u8[1]; + ethhdr->dest.addr[4] = ipv4_hdr->destipaddr.u8[2]; + ethhdr->dest.addr[5] = ipv4_hdr->destipaddr.u8[3]; + } else { + uip_ip4addr_t ipaddr; + int i; + /* Check if the destination address is on the local network. */ + if(!uip_ipaddr_maskcmp(&ipv4_hdr->destipaddr, + ip64_get_hostaddr(), + ip64_get_netmask())) { + /* Destination address was not on the local network, so we need to + use the default router's IP address instead of the destination + address when determining the MAC address. */ + uip_ip4addr_copy(&ipaddr, ip64_get_draddr()); + } else { + /* Else, we use the destination IP address. */ + uip_ip4addr_copy(&ipaddr, &ipv4_hdr->destipaddr); + } + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + if(uip_ip4addr_cmp(&ipaddr, &tabptr->ipaddr)) { + break; + } + tabptr++; + } + + if(i == UIP_ARPTAB_SIZE) { + return 0; + } + + memcpy(ethhdr->dest.addr, tabptr->ethaddr.addr, 6); + + } + memcpy(ethhdr->src.addr, ip64_eth_addr.addr, 6); + + ethhdr->type = UIP_HTONS(IP64_ETH_TYPE_IP); + return sizeof(struct ip64_eth_hdr); +} +/*---------------------------------------------------------------------------*/ +int +ip64_arp_create_arp_request(uint8_t *llhdr, const uint8_t *nlhdr) +{ + struct ipv4_hdr *ipv4_hdr = (struct ipv4_hdr *)nlhdr; + struct arp_hdr *arp_hdr = (struct arp_hdr *)llhdr; + uip_ip4addr_t ipaddr; + + if(!uip_ipaddr_maskcmp(&ipv4_hdr->destipaddr, + ip64_get_hostaddr(), + ip64_get_netmask())) { + /* Destination address was not on the local network, so we need to + use the default router's IP address instead of the destination + address when determining the MAC address. */ + uip_ip4addr_copy(&ipaddr, ip64_get_draddr()); + } else { + /* Else, we use the destination IP address. */ + uip_ip4addr_copy(&ipaddr, &ipv4_hdr->destipaddr); + } + + memset(arp_hdr->ethhdr.dest.addr, 0xff, 6); + memset(arp_hdr->dhwaddr.addr, 0x00, 6); + memcpy(arp_hdr->ethhdr.src.addr, ip64_eth_addr.addr, 6); + memcpy(arp_hdr->shwaddr.addr, ip64_eth_addr.addr, 6); + + uip_ip4addr_copy(&arp_hdr->dipaddr, &ipaddr); + uip_ip4addr_copy(&arp_hdr->sipaddr, ip64_get_hostaddr()); + arp_hdr->opcode = UIP_HTONS(ARP_REQUEST); + arp_hdr->hwtype = UIP_HTONS(ARP_HWTYPE_ETH); + arp_hdr->protocol = UIP_HTONS(IP64_ETH_TYPE_IP); + arp_hdr->hwlen = 6; + arp_hdr->protolen = 4; + arp_hdr->ethhdr.type = UIP_HTONS(IP64_ETH_TYPE_ARP); + + uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN]; + + return sizeof(struct arp_hdr); +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/ip64/ip64-arp.h b/core/net/ip64/ip64-arp.h new file mode 100644 index 000000000..1da84e519 --- /dev/null +++ b/core/net/ip64/ip64-arp.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: uip_arp.h,v 1.2 2006/08/26 23:58:45 oliverschmidt Exp $ + * + */ + +#ifndef IP64_ARP_H +#define IP64_ARP_H + +#include "net/ip/uip.h" + +#include "ip64-eth.h" + + +/* The uip_arp_init() function must be called before any of the other + ARP functions. */ +void ip64_arp_init(void); + +/* The uip_arp_ipin() function should be called whenever an IP packet + arrives from the Ethernet. This function refreshes the ARP table or + inserts a new mapping if none exists. The function assumes that an + IP packet with an Ethernet header is present in the uip_buf buffer + and that the length of the packet is in the uip_len variable. */ +void ip64_arp_ip_input(const uint8_t *packet, uint16_t packet_len); + +/* The uip_arp_arpin() should be called when an ARP packet is received + by the Ethernet driver. This function also assumes that the + Ethernet frame is present in the uip_buf buffer. When the + uip_arp_arpin() function returns, the contents of the uip_buf + buffer should be sent out on the Ethernet if the uip_len variable + is > 0. */ +uint16_t ip64_arp_arp_input(const uint8_t *packet, uint16_t packet_len); + +/* The uip_arp_out() function should be called when an IP packet + should be sent out on the Ethernet. This function creates an + Ethernet header before the IP header in the uip_buf buffer. The + Ethernet header will have the correct Ethernet MAC destination + address filled in if an ARP table entry for the destination IP + address (or the IP address of the default router) is present. If no + such table entry is found, the IP packet is overwritten with an ARP + request and we rely on TCP to retransmit the packet that was + overwritten. In any case, the uip_len variable holds the length of + the Ethernet frame that should be transmitted. */ +void ip64_arp_ip_output(uint8_t *packet, uint16_t packet_len); + + +int ip64_arp_create_ethhdr(uint8_t *link_header, + const uint8_t *network_header); + +int ip64_arp_create_arp_request(uint8_t *link_header, + const uint8_t *network_header); + +int ip64_arp_check_cache(const uint8_t *nlhdr); + + +#endif /* IP64_ARP_H */ diff --git a/core/net/ip64/ip64-conf-example.h b/core/net/ip64/ip64-conf-example.h new file mode 100644 index 000000000..5c08e7438 --- /dev/null +++ b/core/net/ip64/ip64-conf-example.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#ifndef IP64_CONF_H +#define IP64_CONF_H + +#include "ip64-tap-driver.h" +#include "ip64-eth-interface.h" + +#define IP64_CONF_UIP_FALLBACK_INTERFACE ip64_eth_interface +#define IP64_CONF_INPUT ip64_eth_interface_input + +#define IP64_CONF_ETH_DRIVER ip64_tap_driver + +/* + * In contrast to the mandatory parameters above, IP64_CONF_DHCP is an + * optional configuration parameter. The default value is set in ip64.h + */ +/* #define IP64_CONF_DHCP 1 */ +#endif /* IP64_CONF_H */ diff --git a/core/net/ip64/ip64-dhcpc.c b/core/net/ip64/ip64-dhcpc.c new file mode 100644 index 000000000..1ed3ac249 --- /dev/null +++ b/core/net/ip64/ip64-dhcpc.c @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: dhcpc.c,v 1.9 2010/10/19 18:29:04 adamdunkels Exp $ + */ + +#include +#include + +#include "contiki.h" +#include "contiki-net.h" +#include "ip64-dhcpc.h" + +#include "ip64-addr.h" + +#define STATE_INITIAL 0 +#define STATE_SENDING 1 +#define STATE_OFFER_RECEIVED 2 +#define STATE_CONFIG_RECEIVED 3 + +static struct ip64_dhcpc_state s; + +struct dhcp_msg { + uint8_t op, htype, hlen, hops; + uint8_t xid[4]; + uint16_t secs, flags; + uint8_t ciaddr[4]; + uint8_t yiaddr[4]; + uint8_t siaddr[4]; + uint8_t giaddr[4]; + uint8_t chaddr[16]; + uint8_t sname[64]; + uint8_t file[128]; + uint8_t options[312]; +}; + +#if (UIP_BUFSIZE - UIP_UDPIP_HLEN) < 548 +#error UIP_CONF_BUFFER_SIZE may be too small to accomodate DHCPv4 packets +#error Increase UIP_CONF_BUFFER_SIZE in your project-conf.h, platform-conf.h, or contiki-conf.h +#error A good size is 600 bytes +#endif + +#define BOOTP_BROADCAST 0x8000 + +#define DHCP_REQUEST 1 +#define DHCP_REPLY 2 +#define DHCP_HTYPE_ETHERNET 1 +#define DHCP_HLEN_ETHERNET 6 +#define DHCP_MSG_LEN 236 + +#define IP64_DHCPC_SERVER_PORT 67 +#define IP64_DHCPC_CLIENT_PORT 68 + +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNAK 6 +#define DHCPRELEASE 7 + +#define DHCP_OPTION_SUBNET_MASK 1 +#define DHCP_OPTION_ROUTER 3 +#define DHCP_OPTION_DNS_SERVER 6 +#define DHCP_OPTION_REQ_IPADDR 50 +#define DHCP_OPTION_LEASE_TIME 51 +#define DHCP_OPTION_MSG_TYPE 53 +#define DHCP_OPTION_SERVER_ID 54 +#define DHCP_OPTION_REQ_LIST 55 +#define DHCP_OPTION_END 255 + +static uint32_t xid; +static const uint8_t magic_cookie[4] = {99, 130, 83, 99}; +/*---------------------------------------------------------------------------*/ +static uint8_t * +add_msg_type(uint8_t *optptr, uint8_t type) +{ + *optptr++ = DHCP_OPTION_MSG_TYPE; + *optptr++ = 1; + *optptr++ = type; + return optptr; +} +/*---------------------------------------------------------------------------*/ +static uint8_t * +add_server_id(uint8_t *optptr) +{ + *optptr++ = DHCP_OPTION_SERVER_ID; + *optptr++ = 4; + memcpy(optptr, s.serverid, 4); + return optptr + 4; +} +/*---------------------------------------------------------------------------*/ +static uint8_t * +add_req_ipaddr(uint8_t *optptr) +{ + *optptr++ = DHCP_OPTION_REQ_IPADDR; + *optptr++ = 4; + memcpy(optptr, s.ipaddr.u16, 4); + return optptr + 4; +} +/*---------------------------------------------------------------------------*/ +static uint8_t * +add_req_options(uint8_t *optptr) +{ + *optptr++ = DHCP_OPTION_REQ_LIST; + *optptr++ = 3; + *optptr++ = DHCP_OPTION_SUBNET_MASK; + *optptr++ = DHCP_OPTION_ROUTER; + *optptr++ = DHCP_OPTION_DNS_SERVER; + return optptr; +} +/*---------------------------------------------------------------------------*/ +static uint8_t * +add_end(uint8_t *optptr) +{ + *optptr++ = DHCP_OPTION_END; + return optptr; +} +/*---------------------------------------------------------------------------*/ +static void +create_msg(CC_REGISTER_ARG struct dhcp_msg *m) +{ + m->op = DHCP_REQUEST; + m->htype = DHCP_HTYPE_ETHERNET; + m->hlen = s.mac_len; + m->hops = 0; + memcpy(m->xid, &xid, sizeof(m->xid)); + m->secs = 0; + m->flags = UIP_HTONS(BOOTP_BROADCAST); /* Broadcast bit. */ + /* uip_ipaddr_copy(m->ciaddr, uip_hostaddr);*/ + memcpy(m->ciaddr, uip_hostaddr.u16, sizeof(m->ciaddr)); + memset(m->yiaddr, 0, sizeof(m->yiaddr)); + memset(m->siaddr, 0, sizeof(m->siaddr)); + memset(m->giaddr, 0, sizeof(m->giaddr)); + memcpy(m->chaddr, s.mac_addr, s.mac_len); + memset(&m->chaddr[s.mac_len], 0, sizeof(m->chaddr) - s.mac_len); + + memset(m->sname, 0, sizeof(m->sname)); + strcpy((char *)m->sname, "Thingsquare"); + memset(m->file, 0, sizeof(m->file)); + + + memcpy(m->options, magic_cookie, sizeof(magic_cookie)); +} +/*---------------------------------------------------------------------------*/ +static void +send_discover(void) +{ + uint8_t *end; + struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; + + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPDISCOVER); + end = add_req_options(end); + end = add_end(end); + + uip_send(uip_appdata, (int)(end - (uint8_t *)uip_appdata)); +} +/*---------------------------------------------------------------------------*/ +static void +send_request(void) +{ + uint8_t *end; + struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; + + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPREQUEST); + end = add_server_id(end); + end = add_req_ipaddr(end); + end = add_end(end); + + uip_send(uip_appdata, (int)(end - (uint8_t *)uip_appdata)); +} +/*---------------------------------------------------------------------------*/ +static uint8_t +parse_options(uint8_t *optptr, int len) +{ + uint8_t *end = optptr + len; + uint8_t type = 0; + + while(optptr < end) { + switch(*optptr) { + case DHCP_OPTION_SUBNET_MASK: + memcpy(s.netmask.u16, optptr + 2, 4); + break; + case DHCP_OPTION_ROUTER: + memcpy(s.default_router.u16, optptr + 2, 4); + break; + case DHCP_OPTION_DNS_SERVER: + memcpy(s.dnsaddr.u16, optptr + 2, 4); + break; + case DHCP_OPTION_MSG_TYPE: + type = *(optptr + 2); + break; + case DHCP_OPTION_SERVER_ID: + memcpy(s.serverid, optptr + 2, 4); + break; + case DHCP_OPTION_LEASE_TIME: + memcpy(s.lease_time, optptr + 2, 4); + break; + case DHCP_OPTION_END: + return type; + } + + optptr += optptr[1] + 2; + } + return type; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +parse_msg(void) +{ + struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; + + if(m->op == DHCP_REPLY && + memcmp(m->xid, &xid, sizeof(xid)) == 0 && + memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) { + memcpy(s.ipaddr.u16, m->yiaddr, 4); + return parse_options(&m->options[4], uip_datalen()); + } + return 0; +} +/*---------------------------------------------------------------------------*/ +/* + * Is this a "fresh" reply for me? If it is, return the type. + */ +static int +msg_for_me(void) +{ + struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; + uint8_t *optptr = &m->options[4]; + uint8_t *end = (uint8_t*)uip_appdata + uip_datalen(); + + if(m->op == DHCP_REPLY && + memcmp(m->xid, &xid, sizeof(xid)) == 0 && + memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) { + while(optptr < end) { + if(*optptr == DHCP_OPTION_MSG_TYPE) { + return *(optptr + 2); + } else if (*optptr == DHCP_OPTION_END) { + return -1; + } + optptr += optptr[1] + 2; + } + } + return -1; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_dhcp(process_event_t ev, void *data)) +{ + clock_time_t ticks; + + PT_BEGIN(&s.pt); + + init: + xid++; + s.state = STATE_SENDING; + s.ticks = CLOCK_SECOND * 4; + while(1) { + while(ev != tcpip_event) { + tcpip_poll_udp(s.conn); + PT_YIELD(&s.pt); + } + send_discover(); + etimer_set(&s.etimer, s.ticks); + do { + PT_YIELD(&s.pt); + if(ev == tcpip_event && uip_newdata() && msg_for_me() == DHCPOFFER) { + parse_msg(); + s.state = STATE_OFFER_RECEIVED; + goto selecting; + } + } while(!etimer_expired(&s.etimer)); + + if(s.ticks < CLOCK_SECOND * 60) { + s.ticks *= 2; + } + } + + selecting: + s.ticks = CLOCK_SECOND; + do { + while(ev != tcpip_event) { + tcpip_poll_udp(s.conn); + PT_YIELD(&s.pt); + } + send_request(); + etimer_set(&s.etimer, s.ticks); + do { + PT_YIELD(&s.pt); + if(ev == tcpip_event && uip_newdata() && msg_for_me() == DHCPACK) { + parse_msg(); + s.state = STATE_CONFIG_RECEIVED; + goto bound; + } + } while (!etimer_expired(&s.etimer)); + + if(s.ticks <= CLOCK_SECOND * 10) { + s.ticks += CLOCK_SECOND; + } else { + goto init; + } + } while(s.state != STATE_CONFIG_RECEIVED); + + bound: +#if 0 + printf("Got IP address %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.ipaddr)); + printf("Got netmask %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.netmask)); + printf("Got DNS server %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.dnsaddr)); + printf("Got default router %d.%d.%d.%d\n", + uip_ipaddr_to_quad(&s.default_router)); + printf("Lease expires in %ld seconds\n", + uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1])); +#endif + + ip64_dhcpc_configured(&s); + +#define MAX_TICKS (~((clock_time_t)0) / 2) +#define MAX_TICKS32 (~((uint32_t)0)) +#define IMIN(a, b) ((a) < (b) ? (a) : (b)) + + if((uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]))*CLOCK_SECOND/2 + <= MAX_TICKS32) { + s.ticks = (uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]) + )*CLOCK_SECOND/2; + } else { + s.ticks = MAX_TICKS32; + } + + while(s.ticks > 0) { + ticks = IMIN(s.ticks, MAX_TICKS); + s.ticks -= ticks; + etimer_set(&s.etimer, ticks); + PT_YIELD_UNTIL(&s.pt, etimer_expired(&s.etimer)); + } + + if((uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]))*CLOCK_SECOND/2 + <= MAX_TICKS32) { + s.ticks = (uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]) + )*CLOCK_SECOND/2; + } else { + s.ticks = MAX_TICKS32; + } + + /* renewing: */ + do { + while(ev != tcpip_event) { + tcpip_poll_udp(s.conn); + PT_YIELD(&s.pt); + } + send_request(); + ticks = IMIN(s.ticks / 2, MAX_TICKS); + s.ticks -= ticks; + etimer_set(&s.etimer, ticks); + do { + PT_YIELD(&s.pt); + if(ev == tcpip_event && uip_newdata() && msg_for_me() == DHCPACK) { + parse_msg(); + goto bound; + } + } while(!etimer_expired(&s.etimer)); + } while(s.ticks >= CLOCK_SECOND*3); + + /* rebinding: */ + + /* lease_expired: */ + ip64_dhcpc_unconfigured(&s); + goto init; + + PT_END(&s.pt); +} +/*---------------------------------------------------------------------------*/ +void +ip64_dhcpc_init(const void *mac_addr, int mac_len) +{ + /* Although this is DHCPv4, we explicitly bind the socket to an IPv6 + address so that it can operate over the ip64 bridge. */ + uip_ip6addr_t v6addr; + uip_ip4addr_t v4addr; + struct uip_udp_conn *conn2; + + s.mac_addr = mac_addr; + s.mac_len = mac_len; + + s.state = STATE_INITIAL; + uip_ipaddr(&v4addr, 255,255,255,255); + ip64_addr_4to6(&v4addr, &v6addr); + s.conn = udp_new(&v6addr, UIP_HTONS(IP64_DHCPC_SERVER_PORT), NULL); + conn2 = udp_new(NULL, UIP_HTONS(IP64_DHCPC_SERVER_PORT), NULL); + if(s.conn != NULL) { + udp_bind(s.conn, UIP_HTONS(IP64_DHCPC_CLIENT_PORT)); + } + if(conn2 != NULL) { + udp_bind(conn2, UIP_HTONS(IP64_DHCPC_CLIENT_PORT)); + } + PT_INIT(&s.pt); +} +/*---------------------------------------------------------------------------*/ +void +ip64_dhcpc_appcall(process_event_t ev, void *data) +{ + if(ev == tcpip_event || ev == PROCESS_EVENT_TIMER) { + handle_dhcp(ev, data); + } +} +/*---------------------------------------------------------------------------*/ +void +ip64_dhcpc_request(void) +{ + uip_ipaddr_t ipaddr; + + if(s.state == STATE_INITIAL) { + uip_ipaddr(&ipaddr, 0,0,0,0); + uip_sethostaddr(&ipaddr); + handle_dhcp(PROCESS_EVENT_NONE, NULL); + } +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/ip64/ip64-dhcpc.h b/core/net/ip64/ip64-dhcpc.h new file mode 100644 index 000000000..1bc88daf6 --- /dev/null +++ b/core/net/ip64/ip64-dhcpc.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +#ifndef __IP64_DHCPC_H__ +#define __IP64_DHCPC_H__ + +struct ip64_dhcpc_state { + struct pt pt; + char state; + struct uip_udp_conn *conn; + struct etimer etimer; + uint32_t ticks; + const void *mac_addr; + int mac_len; + + uint8_t serverid[4]; + + uint16_t lease_time[2]; + uip_ipaddr_t ipaddr; + uip_ipaddr_t netmask; + uip_ipaddr_t dnsaddr; + uip_ipaddr_t default_router; +}; + +void ip64_dhcpc_init(const void *mac_addr, int mac_len); +void ip64_dhcpc_request(void); + +void ip64_dhcpc_appcall(process_event_t ev, void *data); + +/* Mandatory callbacks provided by the user. */ +void ip64_dhcpc_configured(const struct ip64_dhcpc_state *s); +void ip64_dhcpc_unconfigured(const struct ip64_dhcpc_state *s); + +#endif /* __IP64_DHCPC_H__ */ diff --git a/core/net/ip64/ip64-dns64.c b/core/net/ip64/ip64-dns64.c new file mode 100644 index 000000000..d9527629a --- /dev/null +++ b/core/net/ip64/ip64-dns64.c @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2014, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + */ + +#include "ip64.h" +#include "ip64-addr.h" +#include "ip64-dns64.h" + +#include + +#define DEBUG 0 + +#if DEBUG +#undef PRINTF +#define PRINTF(...) printf(__VA_ARGS__) +#else /* DEBUG */ +#define PRINTF(...) +#endif /* DEBUG */ + +struct dns_hdr { + uint8_t id[2]; + uint8_t flags1, flags2; +#define DNS_FLAG1_RESPONSE 0x80 +#define DNS_FLAG1_OPCODE_STATUS 0x10 +#define DNS_FLAG1_OPCODE_INVERSE 0x08 +#define DNS_FLAG1_OPCODE_STANDARD 0x00 +#define DNS_FLAG1_AUTHORATIVE 0x04 +#define DNS_FLAG1_TRUNC 0x02 +#define DNS_FLAG1_RD 0x01 +#define DNS_FLAG2_RA 0x80 +#define DNS_FLAG2_ERR_MASK 0x0f +#define DNS_FLAG2_ERR_NONE 0x00 +#define DNS_FLAG2_ERR_NAME 0x03 + uint8_t numquestions[2]; + uint8_t numanswers[2]; + uint8_t numauthrr[2]; + uint8_t numextrarr[2]; +}; + +#define DNS_QUESTION_TYPE0 0 +#define DNS_QUESTION_TYPE1 1 +#define DNS_QUESTION_CLASS0 2 +#define DNS_QUESTION_CLASS1 3 +#define DNS_QUESTION_SIZE 4 + +struct dns_answer { + /* DNS answer record starts with either a domain name or a pointer + * to a name already present somewhere in the packet. */ + uint8_t type[2]; + uint8_t class[2]; + uint8_t ttl[4]; + uint8_t len[2]; + union { + uint8_t ip6[16]; + uint8_t ip4[4]; + } addr; +}; + +#define DNS_TYPE_A 1 +#define DNS_TYPE_AAAA 28 + +#define DNS_CLASS_IN 1 +#define DNS_CLASS_ANY 255 + +/*---------------------------------------------------------------------------*/ +void +ip64_dns64_6to4(const uint8_t *ipv6data, int ipv6datalen, + uint8_t *ipv4data, int ipv4datalen) +{ + int i, j; + int qlen; + uint8_t *qdata; + uint8_t *q; + struct dns_hdr *hdr; + + hdr = (struct dns_hdr *)ipv4data; + PRINTF("ip64_dns64_6to4 id: %02x%02x\n", hdr->id[0], hdr->id[1]); + PRINTF("ip64_dns64_6to4 flags1: 0x%02x\n", hdr->flags1); + PRINTF("ip64_dns64_6to4 flags2: 0x%02x\n", hdr->flags2); + PRINTF("ip64_dns64_6to4 numquestions: 0x%02x\n", ((hdr->numquestions[0] << 8) + hdr->numquestions[1])); + PRINTF("ip64_dns64_6to4 numanswers: 0x%02x\n", ((hdr->numanswers[0] << 8) + hdr->numanswers[1])); + PRINTF("ip64_dns64_6to4 numauthrr: 0x%02x\n", ((hdr->numauthrr[0] << 8) + hdr->numauthrr[1])); + PRINTF("ip64_dns64_6to4 numextrarr: 0x%02x\n", ((hdr->numextrarr[0] << 8) + hdr->numextrarr[1])); + + /* Find the DNS question header by scanning through the question + labels. */ + qdata = ipv4data + sizeof(struct dns_hdr); + for(i = 0; i < ((hdr->numquestions[0] << 8) + hdr->numquestions[1]); i++) { + do { + qlen = *qdata; + qdata++; + for(j = 0; j < qlen; j++) { + qdata++; + if(qdata > ipv4data + ipv4datalen) { + PRINTF("ip64_dns64_6to4: packet ended while parsing\n"); + return; + } + } + } while(qlen != 0); + q = qdata; + if(q[DNS_QUESTION_CLASS0] == 0 && q[DNS_QUESTION_CLASS1] == DNS_CLASS_IN && + q[DNS_QUESTION_TYPE0] == 0 && q[DNS_QUESTION_TYPE1] == DNS_TYPE_AAAA) { + q[DNS_QUESTION_TYPE1] = DNS_TYPE_A; + } + + qdata += DNS_QUESTION_SIZE; + } +} +/*---------------------------------------------------------------------------*/ +int +ip64_dns64_4to6(const uint8_t *ipv4data, int ipv4datalen, + uint8_t *ipv6data, int ipv6datalen) +{ + uint8_t n; + int i, j; + int qlen, len; + const uint8_t *qdata, *adata; + uint8_t *qcopy, *acopy, *lenptr; + uint8_t *q; + struct dns_hdr *hdr; + + hdr = (struct dns_hdr *)ipv4data; + PRINTF("ip64_dns64_4to6 id: %02x%02x\n", hdr->id[0], hdr->id[1]); + PRINTF("ip64_dns64_4to6 flags1: 0x%02x\n", hdr->flags1); + PRINTF("ip64_dns64_4to6 flags2: 0x%02x\n", hdr->flags2); + PRINTF("ip64_dns64_4to6 numquestions: 0x%02x\n", ((hdr->numquestions[0] << 8) + hdr->numquestions[1])); + PRINTF("ip64_dns64_4to6 numanswers: 0x%02x\n", ((hdr->numanswers[0] << 8) + hdr->numanswers[1])); + PRINTF("ip64_dns64_4to6 numauthrr: 0x%02x\n", ((hdr->numauthrr[0] << 8) + hdr->numauthrr[1])); + PRINTF("ip64_dns64_4to6 numextrarr: 0x%02x\n", ((hdr->numextrarr[0] << 8) + hdr->numextrarr[1])); + + /* Find the DNS answer header by scanning through the question + labels. */ + qdata = ipv4data + sizeof(struct dns_hdr); + qcopy = ipv6data + sizeof(struct dns_hdr); + for(i = 0; i < ((hdr->numquestions[0] << 8) + hdr->numquestions[1]); i++) { + do { + qlen = *qdata; + qdata++; + qcopy++; + for(j = 0; j < qlen; j++) { + qdata++; + qcopy++; + if(qdata > ipv4data + ipv4datalen) { + PRINTF("ip64_dns64_4to6: packet ended while parsing\n"); + return ipv6datalen; + } + } + } while(qlen != 0); + q = qcopy; + if(q[DNS_QUESTION_CLASS0] == 0 && q[DNS_QUESTION_CLASS1] == DNS_CLASS_IN && + q[DNS_QUESTION_TYPE0] == 0 && q[DNS_QUESTION_TYPE1] == DNS_TYPE_AAAA) { + q[DNS_QUESTION_TYPE1] = DNS_TYPE_AAAA; + } + + qdata += DNS_QUESTION_SIZE; + qcopy += DNS_QUESTION_SIZE; + } + + adata = qdata; + acopy = qcopy; + + /* Go through the answers section and update the answers. */ + for(i = 0; i < ((hdr->numanswers[0] << 8) + hdr->numanswers[1]); i++) { + + n = *adata; + if(n & 0xc0) { + /* Short-hand name format: 2 bytes */ + *acopy++ = *adata++; + *acopy++ = *adata++; + } else { + /* Name spelled out */ + do { + n = *adata; + adata++; + acopy++; + for(j = 0; j < n; j++) { + *acopy++ = *adata++; + } + } while(n != 0); + } + + if(adata[0] == 0 && adata[1] == DNS_TYPE_A) { + /* Update the type field from A to AAAA */ + *acopy = *adata; + acopy++; + adata++; + *acopy = DNS_TYPE_AAAA; + acopy++; + adata++; + + /* Get the length of the address record. Should be 4. */ + lenptr = &acopy[6]; + len = (adata[6] << 8) + adata[7]; + + /* Copy the class, the TTL, and the data length */ + memcpy(acopy, adata, 2 + 4 + 2); + acopy += 8; + adata += 8; + + if(len == 4) { + uip_ip4addr_t addr; + uip_ipaddr(&addr, adata[0], adata[1], adata[2], adata[3]); + ip64_addr_4to6(&addr, (uip_ip6addr_t *)acopy); + + adata += len; + acopy += 16; + lenptr[0] = 0; + lenptr[1] = 16; + ipv6datalen += 12; + + } else { + memcpy(acopy, adata, len); + acopy += len; + adata += len; + } + } else { + len = (adata[8] << 8) + adata[9]; + + /* Copy the type, class, the TTL, and the data length */ + memcpy(acopy, adata, 2 + 2 + 4 + 2); + acopy += 10; + adata += 10; + + /* Copy the data */ + memcpy(acopy, adata, len); + acopy += len; + adata += len; + } + } + return ipv6datalen; +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/ip64/ip64-dns64.h b/core/net/ip64/ip64-dns64.h new file mode 100644 index 000000000..27eb73127 --- /dev/null +++ b/core/net/ip64/ip64-dns64.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + */ + +#ifndef IP64_DNS64_H_ +#define IP64_DNS64_H_ + +void ip64_dns64_6to4(const uint8_t *ipv6data, int ipv6datalen, + uint8_t *ipv4data, int ipv4datalen); +int ip64_dns64_4to6(const uint8_t *ipv4data, int ipv4datalen, + uint8_t *ipv6data, int ipv6datalen); + +#endif /* IP64_DNS64_H_ */ diff --git a/core/net/ip64/ip64-driver.h b/core/net/ip64/ip64-driver.h new file mode 100644 index 000000000..50b00cfd9 --- /dev/null +++ b/core/net/ip64/ip64-driver.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#ifndef IP64_DRIVER_H +#define IP64_DRIVER_H + +struct ip64_driver { + void (* init)(void); + int (* output)(uint8_t *packet, uint16_t packet_len); +}; + + +#endif /* IP64_DRIVER_H */ diff --git a/core/net/ip64/ip64-eth-interface.c b/core/net/ip64/ip64-eth-interface.c new file mode 100644 index 000000000..437fbe24d --- /dev/null +++ b/core/net/ip64/ip64-eth-interface.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "dev/slip.h" + +#include "ip64.h" +#include "ip64-arp.h" +#include "ip64-eth-interface.h" + +#include + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" +#define printf(...) +/*---------------------------------------------------------------------------*/ +void +ip64_eth_interface_input(uint8_t *packet, uint16_t len) +{ + struct ip64_eth_hdr *ethhdr; + ethhdr = (struct ip64_eth_hdr *)packet; + + if(ethhdr->type == UIP_HTONS(IP64_ETH_TYPE_ARP)) { + len = ip64_arp_arp_input(packet, len); + + if(len > 0) { + IP64_ETH_DRIVER.output(packet, len); + } + } else if(ethhdr->type == UIP_HTONS(IP64_ETH_TYPE_IP) && + len > sizeof(struct ip64_eth_hdr)) { + printf("-------------->\n"); + uip_len = ip64_4to6(&packet[sizeof(struct ip64_eth_hdr)], + len - sizeof(struct ip64_eth_hdr), + &uip_buf[UIP_LLH_LEN]); + if(uip_len > 0) { + printf("ip64_interface_process: converted %d bytes\n", uip_len); + + printf("ip64-interface: input source "); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF(" destination "); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("\n"); + + tcpip_input(); + printf("Done\n"); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + printf("ip64-eth-interface: init\n"); +} +/*---------------------------------------------------------------------------*/ +static int +output(void) +{ + int len, ret; + + printf("ip64-interface: output source "); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF(" destination "); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("\n"); + + printf("<--------------\n"); + len = ip64_6to4(&uip_buf[UIP_LLH_LEN], uip_len, + &ip64_packet_buffer[sizeof(struct ip64_eth_hdr)]); + + printf("ip64-interface: output len %d\n", len); + if(len > 0) { + if(ip64_arp_check_cache(&ip64_packet_buffer[sizeof(struct ip64_eth_hdr)])) { + printf("Create header\n"); + ret = ip64_arp_create_ethhdr(ip64_packet_buffer, + &ip64_packet_buffer[sizeof(struct ip64_eth_hdr)]); + if(ret > 0) { + len += ret; + IP64_ETH_DRIVER.output(ip64_packet_buffer, len); + } + } else { + printf("Create request\n"); + len = ip64_arp_create_arp_request(ip64_packet_buffer, + &ip64_packet_buffer[sizeof(struct ip64_eth_hdr)]); + return IP64_ETH_DRIVER.output(ip64_packet_buffer, len); + } + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +const struct uip_fallback_interface ip64_eth_interface = { + init, + output +}; +/*---------------------------------------------------------------------------*/ diff --git a/core/net/ip64/ip64-eth-interface.h b/core/net/ip64/ip64-eth-interface.h new file mode 100644 index 000000000..21bbd947f --- /dev/null +++ b/core/net/ip64/ip64-eth-interface.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#ifndef IP64_ETH_INTERFACE_H +#define IP64_ETH_INTERFACE_H + +#include "net/ip/uip.h" + +void ip64_eth_interface_input(uint8_t *packet, uint16_t len); + +extern const struct uip_fallback_interface ip64_eth_interface; + +#endif /* IP64_ETH_INTERFACE_H */ diff --git a/core/net/ip64/ip64-eth.c b/core/net/ip64/ip64-eth.c new file mode 100644 index 000000000..0a717c625 --- /dev/null +++ b/core/net/ip64/ip64-eth.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#include "ip64-eth.h" + +#include + +struct ip64_eth_addr ip64_eth_addr; + +/*---------------------------------------------------------------------------*/ +void +ip64_eth_addr_set(struct ip64_eth_addr *addr) +{ + memcpy(&ip64_eth_addr, addr, sizeof(struct ip64_eth_addr)); +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/ip64/ip64-eth.h b/core/net/ip64/ip64-eth.h new file mode 100644 index 000000000..aa9448a86 --- /dev/null +++ b/core/net/ip64/ip64-eth.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#ifndef IP64_ETH_H +#define IP64_ETH_H + +#include "contiki-conf.h" + +/** + * The Ethernet address. + */ +struct ip64_eth_addr { + uint8_t addr[6]; +}; + +extern struct ip64_eth_addr ip64_eth_addr; + +void ip64_eth_addr_set(struct ip64_eth_addr *addr); + +/** + * The Ethernet header. + */ +struct ip64_eth_hdr { + struct ip64_eth_addr dest; + struct ip64_eth_addr src; + uint16_t type; +}; + +#define IP64_ETH_TYPE_ARP 0x0806 +#define IP64_ETH_TYPE_IP 0x0800 +#define IP64_ETH_TYPE_IPV6 0x86dd + + +#endif /* IP64_ETH_H */ diff --git a/core/net/ip64/ip64-interface.h b/core/net/ip64/ip64-interface.h new file mode 100644 index 000000000..574ae1c7f --- /dev/null +++ b/core/net/ip64/ip64-interface.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#ifndef IP64_INTERFACE_H +#define IP64_INTERFACE_H + +struct ip64_interface { + void (* init)(void); + int (* input)(uint8_t *packet, uint16_t packet_len); + int (* output)(uint8_t *packet, uint16_t packet_len); +}; + + +#endif /* IP64_INTERFACE_H */ diff --git a/core/net/ip64/ip64-ipv4-dhcp.c b/core/net/ip64/ip64-ipv4-dhcp.c new file mode 100644 index 000000000..ab8c6a517 --- /dev/null +++ b/core/net/ip64/ip64-ipv4-dhcp.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#include "contiki.h" +#include "contiki-net.h" +#include "ip64-dhcpc.h" + +#include "ip64.h" +#include "ip64-eth.h" +#include "ip64-addr.h" + +#include + +PROCESS(ip64_ipv4_dhcp_process, "IPv4 DHCP"); + +uip_ipaddr_t uip_hostaddr; /* Needed because it is referenced by dhcpc.c */ + + +/*---------------------------------------------------------------------------*/ +void +ip64_ipv4_dhcp_init(void) +{ + printf("Starting DHCPv4\n"); + process_start(&ip64_ipv4_dhcp_process, NULL); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(ip64_ipv4_dhcp_process, ev, data) +{ + PROCESS_BEGIN(); + + ip64_dhcpc_init(&ip64_eth_addr, sizeof(ip64_eth_addr)); + + printf("Inited\n"); + + ip64_dhcpc_request(); + printf("Requested\n"); + while(1) { + PROCESS_WAIT_EVENT(); + + if(ev == tcpip_event || + ev == PROCESS_EVENT_TIMER) { + ip64_dhcpc_appcall(ev, data); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +void +ip64_dhcpc_configured(const struct ip64_dhcpc_state *s) +{ + uip_ip6addr_t ip6dnsaddr; + printf("DHCP Configured with %d.%d.%d.%d\n", + s->ipaddr.u8[0], s->ipaddr.u8[1], + s->ipaddr.u8[2], s->ipaddr.u8[3]); + + ip64_set_hostaddr((uip_ip4addr_t *)&s->ipaddr); + ip64_set_netmask((uip_ip4addr_t *)&s->netmask); + ip64_set_draddr((uip_ip4addr_t *)&s->default_router); + ip64_addr_4to6((uip_ip4addr_t *)&s->dnsaddr, &ip6dnsaddr); + // mdns_conf(&ip6dnsaddr); +} +/*---------------------------------------------------------------------------*/ +void +ip64_dhcpc_unconfigured(const struct ip64_dhcpc_state *s) +{ +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/ip64/ip64-ipv4-dhcp.h b/core/net/ip64/ip64-ipv4-dhcp.h new file mode 100644 index 000000000..295af6854 --- /dev/null +++ b/core/net/ip64/ip64-ipv4-dhcp.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#ifndef IP64_IPV4_DHCP_H +#define IP64_IPV4_DHCP_H + +void ip64_ipv4_dhcp_init(void); + +#endif /* IP64_IPV4_DHCP_H */ diff --git a/core/net/ip64/ip64-null-driver.c b/core/net/ip64/ip64-null-driver.c new file mode 100644 index 000000000..dafef5ea5 --- /dev/null +++ b/core/net/ip64/ip64-null-driver.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#include "contiki-net.h" + +#include "ip64-driver.h" +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ +} +/*---------------------------------------------------------------------------*/ +static int +output(uint8_t *packet, uint16_t len) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +const struct ip64_driver ip64_null_driver = { + init, + output +}; diff --git a/core/net/ip64/ip64-null-driver.h b/core/net/ip64/ip64-null-driver.h new file mode 100644 index 000000000..f77691154 --- /dev/null +++ b/core/net/ip64/ip64-null-driver.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#ifndef IP64_NULL_DRIVER_H +#define IP64_NULL_DRIVER_H + +#include "ip64-driver.h" + +extern const struct ip64_driver ip64_null_driver; + +#endif /* IP64_NULL_DRIVER_H */ diff --git a/core/net/ip64/ip64-slip-interface.c b/core/net/ip64/ip64-slip-interface.c new file mode 100644 index 000000000..f62309cab --- /dev/null +++ b/core/net/ip64/ip64-slip-interface.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "dev/slip.h" + +#include "ip64.h" + +#include +#include + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +static uip_ipaddr_t last_sender; + +/*---------------------------------------------------------------------------*/ +void +ip64_slip_interface_input(uint8_t *packet, uint16_t len) +{ + /* Dummy definition: this function is not actually called, but must + be here to conform to the ip65-interface.h structure. */ +} +/*---------------------------------------------------------------------------*/ +static void +input_callback(void) +{ + /*PRINTF("SIN: %u\n", uip_len);*/ + if(uip_buf[0] == '!') { + PRINTF("Got configuration message of type %c\n", uip_buf[1]); + uip_clear_buf(); +#if 0 + if(uip_buf[1] == 'P') { + uip_ipaddr_t prefix; + /* Here we set a prefix !!! */ + memset(&prefix, 0, 16); + memcpy(&prefix, &uip_buf[2], 8); + PRINTF("Setting prefix "); + PRINT6ADDR(&prefix); + PRINTF("\n"); + set_prefix_64(&prefix); + } +#endif + } else if(uip_buf[0] == '?') { + PRINTF("Got request message of type %c\n", uip_buf[1]); + if(uip_buf[1] == 'M') { + const char *hexchar = "0123456789abcdef"; + int j; + /* this is just a test so far... just to see if it works */ + uip_buf[0] = '!'; + for(j = 0; j < 8; j++) { + uip_buf[2 + j * 2] = hexchar[uip_lladdr.addr[j] >> 4]; + uip_buf[3 + j * 2] = hexchar[uip_lladdr.addr[j] & 15]; + } + uip_len = 18; + slip_send(); + + } + uip_clear_buf(); + } else { + + /* Save the last sender received over SLIP to avoid bouncing the + packet back if no route is found */ + uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr); + + uint16_t len = ip64_4to6(&uip_buf[UIP_LLH_LEN], uip_len, + ip64_packet_buffer); + if(len > 0) { + memcpy(&uip_buf[UIP_LLH_LEN], ip64_packet_buffer, len); + uip_len = len; + /* PRINTF("send len %d\n", len); */ + } else { + uip_clear_buf(); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + PRINTF("ip64-slip-interface: init\n"); + // slip_arch_init(BAUD2UBR(115200)); + process_start(&slip_process, NULL); + slip_set_input_callback(input_callback); +} +/*---------------------------------------------------------------------------*/ +static int +output(void) +{ + int len; + + PRINTF("ip64-slip-interface: output source "); + + /* + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF(" destination "); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("\n"); + */ + if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) { + PRINTF("ip64-interface: output, not sending bounced message\n"); + } else { + len = ip64_6to4(&uip_buf[UIP_LLH_LEN], uip_len, + ip64_packet_buffer); + PRINTF("ip64-interface: output len %d\n", len); + if(len > 0) { + memcpy(&uip_buf[UIP_LLH_LEN], ip64_packet_buffer, len); + uip_len = len; + slip_send(); + return len; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +const struct uip_fallback_interface ip64_slip_interface = { + init, output +}; +/*---------------------------------------------------------------------------*/ + + + diff --git a/core/net/ip64/ip64-slip-interface.h b/core/net/ip64/ip64-slip-interface.h new file mode 100644 index 000000000..c3cf26a2f --- /dev/null +++ b/core/net/ip64/ip64-slip-interface.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#ifndef IP64_SLIP_INTERFACE_H +#define IP64_SLIP_INTERFACE_H + +void ip64_slip_interface_input(uint8_t *packet, uint16_t len); + +extern const struct uip_fallback_interface ip64_slip_interface; + +#endif /* IP64_SLIP_INTERFACE_H */ diff --git a/core/net/ip64/ip64-special-ports.c b/core/net/ip64/ip64-special-ports.c new file mode 100644 index 000000000..cea1571ea --- /dev/null +++ b/core/net/ip64/ip64-special-ports.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + */ +#include "ip64.h" +#include "ip64-special-ports.h" + +#ifndef IP64_SPECIAL_PORTS_CONF_ENABLE +#define EMPTY_DEFINITIONS 1 +#else +#if IP64_SPECIAL_PORTS_CONF_ENABLE == 0 +#define EMPTY_DEFINITIONS 1 +#endif /* IP64_SPECIAL_PORTS_CONF_ENABLE */ +#endif /* IP64_SPECIAL_PORTS_CONF_ENABLE */ + + + +#if EMPTY_DEFINITIONS +/*---------------------------------------------------------------------------*/ +int +ip64_special_ports_translate_incoming(uint16_t incoming_port, + uip_ip6addr_t *newaddr, + uint16_t *newport) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +ip64_special_ports_translate_outgoing(uint16_t incoming_port, + const uip_ip6addr_t *ip6addr, + uint16_t *newport) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +ip64_special_ports_incoming_is_special(uint16_t port) +{ + /* Default is to have no special ports. */ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +ip64_special_ports_outgoing_is_special(uint16_t port) +{ + /* Default is to have no special ports. */ + return 0; +} +/*---------------------------------------------------------------------------*/ +#endif /* EMPTY_DEFINITIONS */ diff --git a/core/net/ip64/ip64-special-ports.h b/core/net/ip64/ip64-special-ports.h new file mode 100644 index 000000000..312a24366 --- /dev/null +++ b/core/net/ip64/ip64-special-ports.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + */ +#ifndef IP64_SPECIAL_PORTS_H +#define IP64_SPECIAL_PORTS_H + +/* The IP64 special ports module allows specific ports on the IP64 + translator to be mapped to specific address in the IPv6 + network. The module provides three function prototypes that must be + implemented by the user. + + The IP64 special ports module must be enabled by + +#define IP64_SPECIAL_PORTS_CONF_ENABLE 1 + + Otherwise, the functions are replaced by empty default definitions + in the ip64-special-ports.c module. + + Port numbers are always in network byte order. */ + + +/* Translate the special port to an IPv6 address for inbound + packets. */ +int ip64_special_ports_translate_incoming(uint16_t incoming_port, + uip_ip6addr_t *newaddr, + uint16_t *newport); +int ip64_special_ports_translate_outgoing(uint16_t incoming_port, + const uip_ip6addr_t *ip6addr, + uint16_t *newport); +/* Check if an incoming (destination) port is special. */ +int ip64_special_ports_incoming_is_special(uint16_t port); + +/* Check if an outgoing (source) port is special. */ +int ip64_special_ports_outgoing_is_special(uint16_t port); + + +#endif /* IP64_SPECIAL_PORTS_H */ diff --git a/core/net/ip64/ip64.c b/core/net/ip64/ip64.c new file mode 100644 index 000000000..07d94db1b --- /dev/null +++ b/core/net/ip64/ip64.c @@ -0,0 +1,912 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ + +/* The ip64 module is a translator between IPv6 and IPv4 packets. The + IPv6 packets come from an IPv6 network and are translated into a + single IPv4 host, as shown in the ASCII graphics below. The IPv6 + network typically is a low-power RF network and the IPv4 network + typically is an Ethernet. + + +----------------+ + | | + | | +------+ + | IPv6 network |---| ip64 |-- IPv4 network + | | +------+ + | | + +----------------+ + + ip64 maps all IPv6 addresses from inside the IPv6 network to its + own IPv4 address. This IPv4 address would typically have been + obtained with DHCP from the IPv4 network, but the exact way this + has been obtained is outside the scope of the ip64 module. The IPv4 + address is given to the ip64 module through the + ip64_set_ipv4_address() function. +*/ + +#include "ip64.h" +#include "ip64-addr.h" +#include "ip64-addrmap.h" +#include "ip64-conf.h" +#include "ip64-special-ports.h" +#include "ip64-eth-interface.h" +#include "ip64-slip-interface.h" +#include "ip64-dns64.h" +#include "net/ipv6/uip-ds6.h" +#include "ip64-ipv4-dhcp.h" +#include "contiki-net.h" + +#include "net/ip/uip-debug.h" + +#include /* for memcpy() */ +#include /* for printf() */ + +#define DEBUG 0 + +#if DEBUG +#undef PRINTF +#define PRINTF(...) printf(__VA_ARGS__) +#else /* DEBUG */ +#define PRINTF(...) +#endif /* DEBUG */ + +struct ipv6_hdr { + uint8_t vtc; + uint8_t tcflow; + uint16_t flow; + uint8_t len[2]; + uint8_t nxthdr, hoplim; + uip_ip6addr_t srcipaddr, destipaddr; +}; + +struct ipv4_hdr { + uint8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + uint16_t ipchksum; + uip_ip4addr_t srcipaddr, destipaddr; +}; + +#define EPHEMERAL_PORTRANGE 1024 + +#define IPV6_HDRLEN 40 +#define IPV4_HDRLEN 20 + +#define IP_PROTO_ICMPV4 1 +#define IP_PROTO_TCP 6 +#define IP_PROTO_UDP 17 +#define IP_PROTO_ICMPV6 58 + +#define ICMP_ECHO_REPLY 0 +#define ICMP_ECHO 8 +#define ICMP6_ECHO_REPLY 129 +#define ICMP6_ECHO 128 + +struct tcp_hdr { + uint16_t srcport; + uint16_t destport; + uint8_t seqno[4]; + uint8_t ackno[4]; + uint8_t tcpoffset; + uint8_t flags; + uint8_t wnd[2]; + uint16_t tcpchksum; + uint8_t urgp[2]; + uint8_t optdata[4]; +}; + +struct udp_hdr { + uint16_t srcport; + uint16_t destport; + uint16_t udplen; + uint16_t udpchksum; +}; + +struct icmpv4_hdr { + uint8_t type, icode; + uint16_t icmpchksum; +}; + +struct icmpv6_hdr { + uint8_t type, icode; + uint16_t icmpchksum; + uint16_t id, seqno; +}; + +#define BUFSIZE UIP_BUFSIZE + +uip_buf_t ip64_packet_buffer_aligned; +uint8_t *ip64_packet_buffer = ip64_packet_buffer_aligned.u8; + +uint16_t ip64_packet_buffer_maxlen = BUFSIZE; + +static uip_ip4addr_t ip64_hostaddr; +static uip_ip4addr_t ip64_netmask; +static uip_ip4addr_t ip64_draddr; + +static uint16_t ipid; +static uint8_t ip64_hostaddr_configured = 0; + +static uip_ip6addr_t ipv6_local_address; +static uint8_t ipv6_local_address_configured = 0; + +static uip_ip4addr_t ipv4_broadcast_addr; + +/* Lifetimes for address mappings. */ +#define SYN_LIFETIME (CLOCK_SECOND * 20) +#define RST_LIFETIME (CLOCK_SECOND * 30) +#define DEFAULT_LIFETIME (CLOCK_SECOND * 60 * 5) + +/* TCP flag defines */ +#define TCP_FIN 0x01 +#define TCP_SYN 0x02 +#define TCP_RST 0x04 + +#define DNS_PORT 53 + +/*---------------------------------------------------------------------------*/ +void +ip64_init(void) +{ + int i; + uint8_t state; + + uip_ipaddr(&ipv4_broadcast_addr, 255,255,255,255); + ip64_hostaddr_configured = 0; + + PRINTF("ip64_init\n"); + IP64_ETH_DRIVER.init(); +#if IP64_DHCP + ip64_ipv4_dhcp_init(); +#endif /* IP64_CONF_DHCP */ + + /* Specify an IPv6 address for local communication to the + host. We'll just pick the first one we find in our list. */ + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + PRINTF("i %d used %d\n", i, uip_ds6_if.addr_list[i].isused); + if(uip_ds6_if.addr_list[i].isused && + (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { + ip64_set_ipv6_address(&uip_ds6_if.addr_list[i].ipaddr); + break; + } + } + +} +/*---------------------------------------------------------------------------*/ +void +ip64_set_hostaddr(const uip_ip4addr_t *hostaddr) +{ + ip64_hostaddr_configured = 1; + ip64_addr_copy4(&ip64_hostaddr, hostaddr); +} +/*---------------------------------------------------------------------------*/ +void +ip64_set_netmask(const uip_ip4addr_t *netmask) +{ + ip64_addr_copy4(&ip64_netmask, netmask); +} +/*---------------------------------------------------------------------------*/ +void +ip64_set_draddr(const uip_ip4addr_t *draddr) +{ + ip64_addr_copy4(&ip64_draddr, draddr); +} +/*---------------------------------------------------------------------------*/ +const uip_ip4addr_t * +ip64_get_hostaddr(void) +{ + return &ip64_hostaddr; +} +/*---------------------------------------------------------------------------*/ +const uip_ip4addr_t * +ip64_get_netmask(void) +{ + return &ip64_netmask; +} +/*---------------------------------------------------------------------------*/ +const uip_ip4addr_t * +ip64_get_draddr(void) +{ + return &ip64_draddr; +} +/*---------------------------------------------------------------------------*/ +void +ip64_set_ipv4_address(const uip_ip4addr_t *addr, const uip_ip4addr_t *netmask) +{ + ip64_set_hostaddr(addr); + ip64_set_netmask(netmask); + + PRINTF("ip64_set_ipv4_address: configuring address %d.%d.%d.%d/%d.%d.%d.%d\n", + ip64_hostaddr.u8[0], ip64_hostaddr.u8[1], + ip64_hostaddr.u8[2], ip64_hostaddr.u8[3], + ip64_netmask.u8[0], ip64_netmask.u8[1], + ip64_netmask.u8[2], ip64_netmask.u8[3]); +} +/*---------------------------------------------------------------------------*/ +void +ip64_set_ipv6_address(const uip_ip6addr_t *addr) +{ + ip64_addr_copy6(&ipv6_local_address, (const uip_ip6addr_t *)addr); + ipv6_local_address_configured = 1; +#if DEBUG + PRINTF("ip64_set_ipv6_address: configuring address "); + uip_debug_ipaddr_print(addr); + PRINTF("\n"); +#endif /* DEBUG */ +} +/*---------------------------------------------------------------------------*/ +static uint16_t +chksum(uint16_t sum, const uint8_t *data, uint16_t len) +{ + uint16_t t; + const uint8_t *dataptr; + const uint8_t *last_byte; + + dataptr = data; + last_byte = data + len - 1; + + while(dataptr < last_byte) { /* At least two more bytes */ + t = (dataptr[0] << 8) + dataptr[1]; + sum += t; + if(sum < t) { + sum++; /* carry */ + } + dataptr += 2; + } + + if(dataptr == last_byte) { + t = (dataptr[0] << 8) + 0; + sum += t; + if(sum < t) { + sum++; /* carry */ + } + } + + /* Return sum in host byte order. */ + return sum; +} +/*---------------------------------------------------------------------------*/ +static uint16_t +ipv4_checksum(struct ipv4_hdr *hdr) +{ + uint16_t sum; + + sum = chksum(0, (uint8_t *)hdr, IPV4_HDRLEN); + return (sum == 0) ? 0xffff : uip_htons(sum); +} +/*---------------------------------------------------------------------------*/ +static uint16_t +ipv4_transport_checksum(const uint8_t *packet, uint16_t len, uint8_t proto) +{ + uint16_t transport_layer_len; + uint16_t sum; + struct ipv4_hdr *v4hdr = (struct ipv4_hdr *)packet; + + transport_layer_len = len - IPV4_HDRLEN; + + /* First sum pseudoheader. */ + + if(proto != IP_PROTO_ICMPV4) { + /* IP protocol and length fields. This addition cannot carry. */ + sum = transport_layer_len + proto; + /* Sum IP source and destination addresses. */ + sum = chksum(sum, (uint8_t *)&v4hdr->srcipaddr, 2 * sizeof(uip_ip4addr_t)); + } else { + /* ping replies' checksums are calculated over the icmp-part only */ + sum = 0; + } + + /* Sum transport layer header and data. */ + sum = chksum(sum, &packet[IPV4_HDRLEN], transport_layer_len); + + return (sum == 0) ? 0xffff : uip_htons(sum); +} +/*---------------------------------------------------------------------------*/ +static uint16_t +ipv6_transport_checksum(const uint8_t *packet, uint16_t len, uint8_t proto) +{ + uint16_t transport_layer_len; + uint16_t sum; + struct ipv6_hdr *v6hdr = (struct ipv6_hdr *)packet; + + transport_layer_len = len - IPV6_HDRLEN; + + /* First sum pseudoheader. */ + + /* IP protocol and length fields. This addition cannot carry. */ + sum = transport_layer_len + proto; + /* Sum IP source and destination addresses. */ + sum = chksum(sum, (uint8_t *)&v6hdr->srcipaddr, sizeof(uip_ip6addr_t)); + sum = chksum(sum, (uint8_t *)&v6hdr->destipaddr, sizeof(uip_ip6addr_t)); + + /* Sum transport layer header and data. */ + sum = chksum(sum, &packet[IPV6_HDRLEN], transport_layer_len); + + return (sum == 0) ? 0xffff : uip_htons(sum); +} +/*---------------------------------------------------------------------------*/ +int +ip64_6to4(const uint8_t *ipv6packet, const uint16_t ipv6packet_len, + uint8_t *resultpacket) +{ + struct ipv4_hdr *v4hdr; + struct ipv6_hdr *v6hdr; + struct udp_hdr *udphdr; + struct tcp_hdr *tcphdr; + struct icmpv4_hdr *icmpv4hdr; + struct icmpv6_hdr *icmpv6hdr; + uint16_t ipv6len, ipv4len; + struct ip64_addrmap_entry *m; + + v6hdr = (struct ipv6_hdr *)ipv6packet; + v4hdr = (struct ipv4_hdr *)resultpacket; + + if((v6hdr->len[0] << 8) + v6hdr->len[1] <= ipv6packet_len) { + ipv6len = (v6hdr->len[0] << 8) + v6hdr->len[1] + IPV6_HDRLEN; + } else { + PRINTF("ip64_6to4: packet smaller than reported in IPv6 header, dropping\n"); + return 0; + } + + /* We copy the data from the IPv6 packet into the IPv4 packet. We do + not modify the data in any way. */ + memcpy(&resultpacket[IPV4_HDRLEN], + &ipv6packet[IPV6_HDRLEN], + ipv6len - IPV6_HDRLEN); + + udphdr = (struct udp_hdr *)&resultpacket[IPV4_HDRLEN]; + tcphdr = (struct tcp_hdr *)&resultpacket[IPV4_HDRLEN]; + icmpv4hdr = (struct icmpv4_hdr *)&resultpacket[IPV4_HDRLEN]; + icmpv6hdr = (struct icmpv6_hdr *)&ipv6packet[IPV6_HDRLEN]; + + /* Translate the IPv6 header into an IPv4 header. */ + + /* First the basics: the IPv4 version, header length, type of + service, and offset fields. Those are the same for all IPv4 + packets we send, regardless of the values found in the IPv6 + packet. */ + v4hdr->vhl = 0x45; + v4hdr->tos = 0; + v4hdr->ipoffset[0] = v4hdr->ipoffset[1] = 0; + + /* We assume that the IPv6 packet has a fixed size header with no + extension headers, and compute the length of the IPv4 packet and + place the resulting value in the IPv4 packet header. */ + ipv4len = ipv6len - IPV6_HDRLEN + IPV4_HDRLEN; + v4hdr->len[0] = ipv4len >> 8; + v4hdr->len[1] = ipv4len & 0xff; + + /* For simplicity, we set a unique IP id for each outgoing IPv4 + packet. */ + ipid++; + v4hdr->ipid[0] = ipid >> 8; + v4hdr->ipid[1] = ipid & 0xff; + + /* Set the IPv4 protocol. We only support TCP, UDP, and ICMP at this + point. While the IPv4 header protocol numbers are the same as the + IPv6 next header numbers, the ICMPv4 and ICMPv6 numbers are + different so we cannot simply copy the contents of the IPv6 next + header field. */ + switch(v6hdr->nxthdr) { + case IP_PROTO_TCP: + PRINTF("ip64_6to4: TCP header\n"); + v4hdr->proto = IP_PROTO_TCP; + + /* Compute and check the TCP checksum - since we're going to + recompute it ourselves, we must ensure that it was correct in + the first place. */ + if(ipv6_transport_checksum(ipv6packet, ipv6len, + IP_PROTO_TCP) != 0xffff) { + PRINTF("Bad TCP checksum, dropping packet\n"); + } + + break; + + case IP_PROTO_UDP: + PRINTF("ip64_6to4: UDP header\n"); + v4hdr->proto = IP_PROTO_UDP; + + /* Check if this is a DNS request. If so, we should rewrite it + with the DNS64 module. */ + if(udphdr->destport == UIP_HTONS(DNS_PORT)) { + ip64_dns64_6to4((uint8_t *)v6hdr + IPV6_HDRLEN + sizeof(struct udp_hdr), + ipv6len - IPV6_HDRLEN - sizeof(struct udp_hdr), + (uint8_t *)udphdr + sizeof(struct udp_hdr), + BUFSIZE - IPV4_HDRLEN - sizeof(struct udp_hdr)); + } + /* Compute and check the UDP checksum - since we're going to + recompute it ourselves, we must ensure that it was correct in + the first place. */ + if(ipv6_transport_checksum(ipv6packet, ipv6len, + IP_PROTO_UDP) != 0xffff) { + PRINTF("Bad UDP checksum, dropping packet\n"); + } + break; + + case IP_PROTO_ICMPV6: + PRINTF("ip64_6to4: ICMPv6 header\n"); + v4hdr->proto = IP_PROTO_ICMPV4; + /* Translate only ECHO_REPLY messages. */ + if(icmpv6hdr->type == ICMP6_ECHO_REPLY) { + icmpv4hdr->type = ICMP_ECHO_REPLY; + } else { + PRINTF("ip64_6to4: ICMPv6 mapping for type %d not implemented.\n", + icmpv6hdr->type); + return 0; + } + break; + + default: + /* We did not recognize the next header, and we do not attempt to + translate something we do not understand, so we return 0 to + indicate that no successful translation could be made. */ + PRINTF("ip64_6to4: Could not convert IPv6 next hop %d to an IPv4 protocol number.\n", + v6hdr->nxthdr); + return 0; + } + + /* We set the IPv4 ttl value to the hoplim number from the IPv6 + header. This means that information about the IPv6 topology is + transported into to the IPv4 network. */ + v4hdr->ttl = v6hdr->hoplim; + + /* We next convert the destination address. We make this conversion + with the ip64_addr_6to4() function. If the conversion + fails, ip64_addr_6to4() returns 0. If so, we also return 0 to + indicate failure. */ + if(ip64_addr_6to4(&v6hdr->destipaddr, + &v4hdr->destipaddr) == 0) { +#if DEBUG + PRINTF("ip64_6to4: Could not convert IPv6 destination address.\n"); + uip_debug_ipaddr_print(&v6hdr->destipaddr); + PRINTF("\n"); +#endif /* DEBUG */ + return 0; + } + + /* We set the source address in the IPv4 packet to be the IPv4 + address that we have been configured with through the + ip64_set_ipv4_address() function. Only let broadcasts through. */ + if(!ip64_hostaddr_configured && + !uip_ip4addr_cmp(&v4hdr->destipaddr, &ipv4_broadcast_addr)) { + PRINTF("ip64_6to4: no IPv4 address configured.\n"); + return 0; + } + ip64_addr_copy4(&v4hdr->srcipaddr, &ip64_hostaddr); + + + /* Next we update the transport layer header. This must be updated + in two ways: the source port number is changed and the transport + layer checksum must be recomputed. The reason why we change the + source port number is so that we can remember what IPv6 address + this packet came from, in case the packet will result in a reply + from the host on the IPv4 network. If a reply would be sent, it + would be sent to the port number that we chose, and we will be + able to map this back to the IPv6 address of the original sender + of the packet. + */ + + /* We check to see if we already have an existing IP address mapping + for this connection. If not, we create a new one. */ + if((v4hdr->proto == IP_PROTO_UDP || v4hdr->proto == IP_PROTO_TCP)) { + + if(ip64_special_ports_outgoing_is_special(uip_ntohs(udphdr->srcport))) { + uint16_t newport; + if(ip64_special_ports_translate_outgoing(uip_ntohs(udphdr->srcport), + &v6hdr->srcipaddr, + &newport)) { + udphdr->srcport = uip_htons(newport); + } + } else if(uip_ntohs(udphdr->srcport) >= EPHEMERAL_PORTRANGE) { + m = ip64_addrmap_lookup(&v6hdr->srcipaddr, + uip_ntohs(udphdr->srcport), + &v4hdr->destipaddr, + uip_ntohs(udphdr->destport), + v4hdr->proto); + if(m == NULL) { + PRINTF("Lookup failed\n"); + m = ip64_addrmap_create(&v6hdr->srcipaddr, + uip_ntohs(udphdr->srcport), + &v4hdr->destipaddr, + uip_ntohs(udphdr->destport), + v4hdr->proto); + if(m == NULL) { + PRINTF("Could not create new map\n"); + return 0; + } else { + PRINTF("Could create new local port %d\n", m->mapped_port); + } + } else { + PRINTF("Lookup: found local port %d (%d)\n", m->mapped_port, + uip_htons(m->mapped_port)); + } + + /* Update the lifetime of the address mapping. We need to be + frugal with address mapping table entries, so we assign + different lifetimes depending on the type of packet we see. + + For TCP connections, we don't want to have a lot of failed + connection attmpts lingering around, so we assign mappings + with TCP SYN segments a short lifetime. If we see a RST + segment, this indicates that the connection might be dead, + and we'll assign a shorter lifetime. + + For UDP packets and for non-SYN/non-RST segments, we assign + the default lifetime. */ + if(v4hdr->proto == IP_PROTO_TCP) { + if((tcphdr->flags & TCP_SYN)) { + ip64_addrmap_set_lifetime(m, SYN_LIFETIME); + } else if((tcphdr->flags & TCP_RST)) { + ip64_addrmap_set_lifetime(m, RST_LIFETIME); + } else { + ip64_addrmap_set_lifetime(m, DEFAULT_LIFETIME); + } + + /* Also check if we see a FIN segment. If so, we'll mark the + address mapping as being candidate for recycling. Same for + RST segments. */ + if((tcphdr->flags & TCP_FIN) || + (tcphdr->flags & TCP_RST)) { + ip64_addrmap_set_recycleble(m); + } + } else { + ip64_addrmap_set_lifetime(m, DEFAULT_LIFETIME); + + /* Treat UDP packets from the IPv6 network to a multicast + address on the IPv4 network differently: since there is + no way for packets from the IPv4 network to go back to + the IPv6 network on these mappings, we'll mark them as + recyclable. */ + if(v4hdr->destipaddr.u8[0] == 224) { + ip64_addrmap_set_recycleble(m); + } + + /* Treat DNS requests differently: since the are one-shot, we + mark them as recyclable. */ + if(udphdr->destport == UIP_HTONS(DNS_PORT)) { + ip64_addrmap_set_recycleble(m); + } + } + + /* Set the source port of the packet to be the mapped port + number. */ + udphdr->srcport = uip_htons(m->mapped_port); + } + } + + /* The IPv4 header is now complete, so we can compute the IPv4 + header checksum. */ + v4hdr->ipchksum = 0; + v4hdr->ipchksum = ~(ipv4_checksum(v4hdr)); + + + + /* The checksum is in different places in the different protocol + headers, so we need to be sure that we update the correct + field. */ + switch(v4hdr->proto) { + case IP_PROTO_TCP: + tcphdr->tcpchksum = 0; + tcphdr->tcpchksum = ~(ipv4_transport_checksum(resultpacket, ipv4len, + IP_PROTO_TCP)); + break; + case IP_PROTO_UDP: + udphdr->udpchksum = 0; + udphdr->udpchksum = ~(ipv4_transport_checksum(resultpacket, ipv4len, + IP_PROTO_UDP)); + if(udphdr->udpchksum == 0) { + udphdr->udpchksum = 0xffff; + } + break; + case IP_PROTO_ICMPV4: + icmpv4hdr->icmpchksum = 0; + icmpv4hdr->icmpchksum = ~(ipv4_transport_checksum(resultpacket, ipv4len, + IP_PROTO_ICMPV4)); + break; + + default: + PRINTF("ip64_6to4: transport protocol %d not implemented\n", v4hdr->proto); + return 0; + } + + /* Finally, we return the length of the resulting IPv4 packet. */ + PRINTF("ip64_6to4: ipv4len %d\n", ipv4len); + return ipv4len; +} +/*---------------------------------------------------------------------------*/ +int +ip64_4to6(const uint8_t *ipv4packet, const uint16_t ipv4packet_len, + uint8_t *resultpacket) +{ + struct ipv4_hdr *v4hdr; + struct ipv6_hdr *v6hdr; + struct udp_hdr *udphdr; + struct tcp_hdr *tcphdr; + struct icmpv4_hdr *icmpv4hdr; + struct icmpv6_hdr *icmpv6hdr; + uint16_t ipv4len, ipv6len, ipv6_packet_len; + struct ip64_addrmap_entry *m; + + v6hdr = (struct ipv6_hdr *)resultpacket; + v4hdr = (struct ipv4_hdr *)ipv4packet; + + if((v4hdr->len[0] << 8) + v4hdr->len[1] <= ipv4packet_len) { + ipv4len = (v4hdr->len[0] << 8) + v4hdr->len[1]; + } else { + PRINTF("ip64_4to6: packet smaller than reported in IPv4 header, dropping\n"); + return 0; + } + + if(ipv4len <= IPV4_HDRLEN) { + return 0; + } + + /* Make sure that the resulting packet fits in the ip64 packet + buffer. If not, we drop it. */ + if(ipv4len - IPV4_HDRLEN + IPV6_HDRLEN > BUFSIZE) { + PRINTF("ip64_4to6: packet too big to fit in buffer, dropping\n"); + return 0; + } + /* We copy the data from the IPv4 packet into the IPv6 packet. */ + memcpy(&resultpacket[IPV6_HDRLEN], + &ipv4packet[IPV4_HDRLEN], + ipv4len - IPV4_HDRLEN); + + udphdr = (struct udp_hdr *)&resultpacket[IPV6_HDRLEN]; + tcphdr = (struct tcp_hdr *)&resultpacket[IPV6_HDRLEN]; + icmpv4hdr = (struct icmpv4_hdr *)&ipv4packet[IPV4_HDRLEN]; + icmpv6hdr = (struct icmpv6_hdr *)&resultpacket[IPV6_HDRLEN]; + + ipv6len = ipv4len - IPV4_HDRLEN + IPV6_HDRLEN; + ipv6_packet_len = ipv6len - IPV6_HDRLEN; + + /* Translate the IPv4 header into an IPv6 header. */ + + /* We first fill in the simple fields: IP header version, traffic + class and flow label, and length fields. */ + v6hdr->vtc = 0x60; + v6hdr->tcflow = 0; + v6hdr->flow = 0; + v6hdr->len[0] = ipv6_packet_len >> 8; + v6hdr->len[1] = ipv6_packet_len & 0xff; + + /* We use the IPv4 TTL field as the IPv6 hop limit field. */ + v6hdr->hoplim = v4hdr->ttl; + + + /* We now translate the IPv4 source and destination addresses to + IPv6 source and destination addresses. We translate the IPv4 + source address into an IPv6-encoded IPv4 address. The IPv4 + destination address will be the address with which we have + previously been configured, through the ip64_set_ipv4_address() + function. We use the mapping table to look up the new IPv6 + destination address. As we assume that the IPv4 packet is a + response to a previously sent IPv6 packet, we should have a + mapping between the (protocol, destport, srcport, srcaddress) + tuple. If not, we'll return 0 to indicate that we failed to + translate the packet. */ + if(ip64_addr_4to6(&v4hdr->srcipaddr, &v6hdr->srcipaddr) == 0) { + PRINTF("ip64_packet_4to6: failed to convert source IP address\n"); + return 0; + } + + /* For the next header field, we simply use the IPv4 protocol + field. We only support UDP and TCP packets. */ + switch(v4hdr->proto) { + case IP_PROTO_UDP: + v6hdr->nxthdr = IP_PROTO_UDP; + /* Check if this is a DNS request. If so, we should rewrite it + with the DNS64 module. */ + if(udphdr->srcport == UIP_HTONS(DNS_PORT)) { + int len; + + len = ip64_dns64_4to6((uint8_t *)v4hdr + IPV4_HDRLEN + sizeof(struct udp_hdr), + ipv4len - IPV4_HDRLEN - sizeof(struct udp_hdr), + (uint8_t *)v6hdr + IPV6_HDRLEN + sizeof(struct udp_hdr), + ipv6_packet_len - sizeof(struct udp_hdr)); + ipv6_packet_len = len + sizeof(struct udp_hdr); + v6hdr->len[0] = ipv6_packet_len >> 8; + v6hdr->len[1] = ipv6_packet_len & 0xff; + ipv6len = ipv6_packet_len + IPV6_HDRLEN; + + } + break; + + case IP_PROTO_TCP: + v6hdr->nxthdr = IP_PROTO_TCP; + break; + + case IP_PROTO_ICMPV4: + /* Allow only ICMPv4 ECHO_REQUESTS (ping packets) through to the + local IPv6 host. */ + if(icmpv4hdr->type == ICMP_ECHO) { + PRINTF("ip64_4to6: translating ICMPv4 ECHO packet\n"); + v6hdr->nxthdr = IP_PROTO_ICMPV6; + icmpv6hdr->type = ICMP6_ECHO; + ip64_addr_copy6(&v6hdr->destipaddr, &ipv6_local_address); + } else { + PRINTF("ip64_packet_4to6: ICMPv4 packet type %d not supported\n", + icmpv4hdr->type); + return 0; + } + break; + + default: + /* For protocol types that we do not support, we return 0 to + indicate that we failed to translate the packet to an IPv6 + packet. */ + PRINTF("ip64_packet_4to6: protocol type %d not supported\n", + v4hdr->proto); + return 0; + } + + /* Translate IPv4 broadcasts to IPv6 all-nodes multicasts. */ + if(uip_ip4addr_cmp(&v4hdr->destipaddr, &ipv4_broadcast_addr) || + (uip_ipaddr_maskcmp(&v4hdr->destipaddr, &ip64_hostaddr, + &ip64_netmask) && + ((v4hdr->destipaddr.u16[0] & (~ip64_netmask.u16[0])) == + (ipv4_broadcast_addr.u16[0] & (~ip64_netmask.u16[0]))) && + ((v4hdr->destipaddr.u16[1] & (~ip64_netmask.u16[1])) == + (ipv4_broadcast_addr.u16[1] & (~ip64_netmask.u16[1]))))) { + uip_create_linklocal_allnodes_mcast(&v6hdr->destipaddr); + } else { + + if(!ip64_hostaddr_configured) { + PRINTF("ip64_packet_4to6: no local IPv4 address configured, dropping incoming packet.\n"); + return 0; + } + + if(!uip_ip4addr_cmp(&v4hdr->destipaddr, &ip64_hostaddr)) { + PRINTF("ip64_packet_4to6: the IPv4 destination address %d.%d.%d.%d did not match our IPv4 address %d.%d.%d.%d\n", + uip_ipaddr_to_quad(&v4hdr->destipaddr), + uip_ipaddr_to_quad(&ip64_hostaddr)); + return 0; + } + + + /* Now we translate the transport layer port numbers. We assume that + the IPv4 packet is a response to a packet that has previously + been translated from IPv6 to IPv4. If this is the case, the tuple + (protocol, destport, srcport, srcaddress) corresponds to an address/port + pair in our mapping table. If we do not find a mapping, we return + 0 to indicate that we could not translate the IPv4 packet to an + IPv6 packet. */ + + /* XXX treat a few ports differently: those ports should be let + through to the local host. For those ports, we set up an address + mapping that ensures that the local port number is retained. */ + + if((v4hdr->proto == IP_PROTO_TCP || v4hdr->proto == IP_PROTO_UDP)) { + if(uip_htons(tcphdr->destport) < EPHEMERAL_PORTRANGE) { + /* This packet should go to the local host. */ + PRINTF("Port is in the non-ephemeral port range %d (%d)\n", + tcphdr->destport, uip_htons(tcphdr->destport)); + ip64_addr_copy6(&v6hdr->destipaddr, &ipv6_local_address); + } else if(ip64_special_ports_incoming_is_special(uip_htons(tcphdr->destport))) { + uip_ip6addr_t newip6addr; + uint16_t newport; + PRINTF("ip64 port %d (%d) is special, treating it differently\n", + tcphdr->destport, uip_htons(tcphdr->destport)); + if(ip64_special_ports_translate_incoming(uip_htons(tcphdr->destport), + &newip6addr, &newport)) { + ip64_addr_copy6(&v6hdr->destipaddr, &newip6addr); + tcphdr->destport = uip_htons(newport); + PRINTF("New port %d (%d)\n", + tcphdr->destport, uip_htons(tcphdr->destport)); + } else { + ip64_addr_copy6(&v6hdr->destipaddr, &ipv6_local_address); + PRINTF("No new port\n"); + } + } else { + /* The TCP or UDP port numbers were not non-ephemeral and not + special, so we map the port number according to the address + mapping table. */ + + m = ip64_addrmap_lookup_port(uip_ntohs(udphdr->destport), + v4hdr->proto); + if(m == NULL) { + PRINTF("Inbound lookup failed\n"); + return 0; + } else { + PRINTF("Inbound lookup did not fail\n"); + } + ip64_addr_copy6(&v6hdr->destipaddr, &m->ip6addr); + udphdr->destport = uip_htons(m->ip6port); + } + } + } + + /* The checksum is in different places in the different protocol + headers, so we need to be sure that we update the correct + field. */ + switch(v6hdr->nxthdr) { + case IP_PROTO_TCP: + tcphdr->tcpchksum = 0; + tcphdr->tcpchksum = ~(ipv6_transport_checksum(resultpacket, + ipv6len, + IP_PROTO_TCP)); + break; + case IP_PROTO_UDP: + udphdr->udpchksum = 0; + udphdr->udpchksum = ~(ipv6_transport_checksum(resultpacket, + ipv6len, + IP_PROTO_UDP)); + if(udphdr->udpchksum == 0) { + udphdr->udpchksum = 0xffff; + } + break; + + case IP_PROTO_ICMPV6: + icmpv6hdr->icmpchksum = 0; + icmpv6hdr->icmpchksum = ~(ipv6_transport_checksum(resultpacket, + ipv6len, + IP_PROTO_ICMPV6)); + break; + default: + PRINTF("ip64_4to6: transport protocol %d not implemented\n", v4hdr->proto); + return 0; + } + + /* Finally, we return the length of the resulting IPv6 packet. */ + PRINTF("ip64_4to6: ipv6len %d\n", ipv6len); + return ipv6len; +} +/*---------------------------------------------------------------------------*/ +int +ip64_hostaddr_is_configured(void) +{ + return ip64_hostaddr_configured; +} +/*---------------------------------------------------------------------------*/ +static void +interface_init(void) +{ + IP64_UIP_FALLBACK_INTERFACE.init(); +} +/*---------------------------------------------------------------------------*/ +static int +interface_output(void) +{ + PRINTF("ip64: interface_output len %d\n", uip_len); + IP64_UIP_FALLBACK_INTERFACE.output(); + + return 0; +} +/*---------------------------------------------------------------------------*/ +const struct uip_fallback_interface ip64_uip_fallback_interface = { + interface_init, interface_output +}; + diff --git a/core/net/ip64/ip64.h b/core/net/ip64/ip64.h new file mode 100644 index 000000000..0837dc988 --- /dev/null +++ b/core/net/ip64/ip64.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#ifndef IP64_H +#define IP64_H + +#include "net/ip/uip.h" + +void ip64_init(void); +int ip64_6to4(const uint8_t *ipv6packet, const uint16_t ipv6len, + uint8_t *resultpacket); +int ip64_4to6(const uint8_t *ipv4packet, const uint16_t ipv4len, + uint8_t *resultpacket); + +void ip64_set_ipv4_address(const uip_ip4addr_t *ipv4addr, + const uip_ip4addr_t *netmask); +void ip64_set_ipv6_address(const uip_ip6addr_t *ipv6addr); + +const uip_ip4addr_t *ip64_get_hostaddr(void); +const uip_ip4addr_t *ip64_get_netmask(void); +const uip_ip4addr_t *ip64_get_draddr(void); + +void ip64_set_hostaddr(const uip_ip4addr_t *hostaddr); +void ip64_set_netmask(const uip_ip4addr_t *netmask); +void ip64_set_draddr(const uip_ip4addr_t *draddr); + +int ip64_hostaddr_is_configured(void); + +extern uint8_t *ip64_packet_buffer; +extern uint16_t ip64_packet_buffer_maxlen; + +#include "ip64-conf.h" + +#ifndef IP64_CONF_ETH_DRIVER +#error IP64_CONF_ETH_DRIVER must be #defined in ip64-conf.h +#else /* IP64_CONF_ETH_DRIVER */ +#define IP64_ETH_DRIVER IP64_CONF_ETH_DRIVER +#endif /* IP64_CONF_ETH_DRIVER */ + +#ifndef IP64_CONF_INPUT +#error IP64_CONF_INPUT must be #defined in ip64-conf.h +#else /* IP64_CONF_INPUT */ +#define IP64_INPUT IP64_CONF_INPUT +#endif /* IP64_CONF_INPUT */ + +#ifndef IP64_CONF_UIP_FALLBACK_INTERFACE +#error IP64_CONF_UIP_FALLBACK_INTERFACE must be #defined in ip64-conf.h +#else /* IP64_CONF_UIP_FALLBACK_INTERFACE */ +#define IP64_UIP_FALLBACK_INTERFACE IP64_CONF_UIP_FALLBACK_INTERFACE +#endif /* IP64_CONF_UIP_FALLBACK_INTERFACE */ + +#ifdef IP64_CONF_DHCP +#define IP64_DHCP IP64_CONF_DHCP +#else /* IP64_CONF_DHCP */ +/* Enable DHCP per default */ +#define IP64_DHCP 1 +#endif /* IP64_CONF_DHCP */ + +#endif /* IP64_H */ + diff --git a/core/net/ipv4/uaodv-rt.c b/core/net/ipv4/uaodv-rt.c index b07d3d636..cad7db73f 100644 --- a/core/net/ipv4/uaodv-rt.c +++ b/core/net/ipv4/uaodv-rt.c @@ -38,7 +38,6 @@ */ -#include #include "net/ipv4/uaodv-rt.h" #include "contiki-net.h" diff --git a/core/net/ipv4/uaodv.c b/core/net/ipv4/uaodv.c index a95b8cf28..230709a61 100644 --- a/core/net/ipv4/uaodv.c +++ b/core/net/ipv4/uaodv.c @@ -39,7 +39,6 @@ #include #include -#include #include "contiki.h" #include "net/ipv4/uaodv-def.h" diff --git a/core/net/ipv4/uip-fw-drv.c b/core/net/ipv4/uip-fw-drv.c index d4f62b945..72a104eed 100644 --- a/core/net/ipv4/uip-fw-drv.c +++ b/core/net/ipv4/uip-fw-drv.c @@ -34,7 +34,7 @@ #include "net/ipv4/uip-fw.h" -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 PROCESS(uip_fw_process, "IP forwarding"); @@ -51,4 +51,4 @@ PROCESS_THREAD(uip_fw_process, ev, data) } /*---------------------------------------------------------------------------*/ -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ diff --git a/core/net/ipv4/uip-fw.c b/core/net/ipv4/uip-fw.c index c152231c0..530a0b7c0 100644 --- a/core/net/ipv4/uip-fw.c +++ b/core/net/ipv4/uip-fw.c @@ -229,7 +229,7 @@ time_exceeded(void) /* We don't send out ICMP errors for ICMP messages (unless they are pings). */ if(ICMPBUF->proto == UIP_PROTO_ICMP && ICMPBUF->type != ICMP_ECHO) { - uip_len = 0; + uip_clear_buf(); return; } /* Copy fields from packet header into payload of this ICMP packet. */ diff --git a/core/net/ipv4/uip-fw.h b/core/net/ipv4/uip-fw.h index 8f86241e6..b1cc76881 100644 --- a/core/net/ipv4/uip-fw.h +++ b/core/net/ipv4/uip-fw.h @@ -1,14 +1,3 @@ -/** - * \addtogroup uipfw - * @{ - */ - -/** - * \file - * uIP packet forwarding header file. - * \author Adam Dunkels - */ - /* * Copyright (c) 2004, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +31,18 @@ * Author: Adam Dunkels * */ + +/** + * \file + * uIP packet forwarding header file. + * \author Adam Dunkels + */ + +/** + * \addtogroup uipfw + * @{ + */ + #ifndef UIP_FW_H_ #define UIP_FW_H_ diff --git a/core/net/ipv4/uip-over-mesh.c b/core/net/ipv4/uip-over-mesh.c index 8fe373238..e6709f1d4 100644 --- a/core/net/ipv4/uip-over-mesh.c +++ b/core/net/ipv4/uip-over-mesh.c @@ -260,8 +260,10 @@ uip_over_mesh_send(void) an underlying power-saving MAC layer knows that it should be waiting for an ACK. */ if(BUF->proto == UIP_PROTO_TCP) { +#if NETSTACK_CONF_WITH_RIME packetbuf_set_attr(PACKETBUF_ATTR_ERELIABLE, 1); packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1); +#endif /* NETSTACK_CONF_WITH_RIME */ /* packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, PACKETBUF_ATTR_PACKET_TYPE_STREAM);*/ } diff --git a/core/net/ipv4/uip.c b/core/net/ipv4/uip.c index aaff1c20f..331cb7562 100644 --- a/core/net/ipv4/uip.c +++ b/core/net/ipv4/uip.c @@ -1,16 +1,3 @@ -#define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/ - -/** - * \addtogroup uip - * @{ - */ - -/** - * \file - * The uIP TCP/IP stack code. - * \author Adam Dunkels - */ - /* * Copyright (c) 2001-2003, Adam Dunkels. * All rights reserved. @@ -44,6 +31,19 @@ * */ +/** + * \file + * The uIP TCP/IP stack code. + * \author Adam Dunkels + */ + +/** + * \addtogroup uip + * @{ + */ + +#define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/ + /* * uIP is a small implementation of the IP, UDP and TCP protocols (as * well as some basic ICMP stuff). The implementation couples the IP, @@ -75,17 +75,10 @@ #include "net/ipv4/uip_arp.h" #include "net/ip/uip_arch.h" -#if !UIP_CONF_IPV6 /* If UIP_CONF_IPV6 is defined, we compile the - uip6.c file instead of this one. Therefore - this #ifndef removes the entire compilation - output of the uip.c file */ - - -#if UIP_CONF_IPV6 #include "net/ipv4/uip-neighbor.h" -#endif /* UIP_CONF_IPV6 */ #include +#include "sys/cc.h" /*---------------------------------------------------------------------------*/ /* Variable definitions. */ @@ -106,12 +99,12 @@ uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask; #endif /* UIP_FIXEDADDR */ const uip_ipaddr_t uip_broadcast_addr = -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }; -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ { { 0xff, 0xff, 0xff, 0xff } }; -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ const uip_ipaddr_t uip_all_zeroes_addr = { { 0x0, /* rest is 0 */ } }; #if UIP_FIXEDETHADDR @@ -322,11 +315,11 @@ upper_layer_chksum(uint8_t proto) uint16_t upper_layer_len; uint16_t sum; -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 upper_layer_len = (((uint16_t)(BUF->len[0]) << 8) + BUF->len[1]); -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ upper_layer_len = (((uint16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN; -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /* First sum pseudoheader. */ @@ -342,14 +335,14 @@ upper_layer_chksum(uint8_t proto) return (sum == 0) ? 0xffff : uip_htons(sum); } /*---------------------------------------------------------------------------*/ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 uint16_t uip_icmp6chksum(void) { return upper_layer_chksum(UIP_PROTO_ICMP6); } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /*---------------------------------------------------------------------------*/ uint16_t uip_tcpchksum(void) @@ -395,7 +388,7 @@ uip_init(void) /*---------------------------------------------------------------------------*/ #if UIP_ACTIVE_OPEN struct uip_conn * -uip_connect(uip_ipaddr_t *ripaddr, uint16_t rport) +uip_connect(const uip_ipaddr_t *ripaddr, uint16_t rport) { register struct uip_conn *conn, *cconn; @@ -443,6 +436,11 @@ uip_connect(uip_ipaddr_t *ripaddr, uint16_t rport) conn->snd_nxt[2] = iss[2]; conn->snd_nxt[3] = iss[3]; + conn->rcv_nxt[0] = 0; + conn->rcv_nxt[1] = 0; + conn->rcv_nxt[2] = 0; + conn->rcv_nxt[3] = 0; + conn->initialmss = conn->mss = UIP_TCP_MSS; conn->len = 1; /* TCP length of the SYN is one. */ @@ -529,7 +527,7 @@ uip_listen(uint16_t port) /*---------------------------------------------------------------------------*/ /* XXX: IP fragment reassembly: not well-tested. */ -#if UIP_REASSEMBLY && !UIP_CONF_IPV6 +#if UIP_REASSEMBLY && !NETSTACK_CONF_WITH_IPV6 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN) static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE]; static uint8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)]; @@ -699,7 +697,7 @@ uip_process(uint8_t flag) } goto drop; - /* Check if we were invoked because of the perodic timer fireing. */ + /* Check if we were invoked because of the periodic timer firing. */ } else if(flag == UIP_TIMER) { #if UIP_REASSEMBLY if(uip_reasstmr != 0) { @@ -716,7 +714,7 @@ uip_process(uint8_t flag) } /* Reset the length variables. */ - uip_len = 0; + uip_clear_buf(); uip_slen = 0; #if UIP_TCP @@ -828,7 +826,7 @@ uip_process(uint8_t flag) /* Start of IP input header processing code. */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /* Check validity of the IP header. */ if((BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */ UIP_STAT(++uip_stat.ip.drop); @@ -836,7 +834,7 @@ uip_process(uint8_t flag) UIP_LOG("ipv6: invalid version."); goto drop; } -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ /* Check validity of the IP header. */ if(BUF->vhl != 0x45) { /* IP version and header length. */ UIP_STAT(++uip_stat.ip.drop); @@ -844,18 +842,18 @@ uip_process(uint8_t flag) UIP_LOG("ip: invalid version or header length."); goto drop; } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /* Check the size of the packet. If the size reported to us in uip_len is smaller the size reported in the IP header, we assume that the packet has been corrupted in transit. If the size of uip_len is larger than the size reported in the IP packet header, the packet has been padded and we set uip_len to the correct - value.. */ + value. */ if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) { uip_len = (BUF->len[0] << 8) + BUF->len[1]; -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 uip_len += 40; /* The length reported in the IPv6 header is the length of the payload that follows the header. However, uIP uses the uip_len variable @@ -865,13 +863,13 @@ uip_process(uint8_t flag) contains the length of the entire packet. But for IPv6 we need to add the size of the IPv6 header (40 bytes). */ -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ } else { UIP_LOG("ip: packet shorter than reported in IP header."); goto drop; } -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 /* Check the fragment flag. */ if((BUF->ipoffset[0] & 0x3f) != 0 || BUF->ipoffset[1] != 0) { @@ -887,13 +885,13 @@ uip_process(uint8_t flag) goto drop; #endif /* UIP_REASSEMBLY */ } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) { /* If we are configured to use ping IP address configuration and - hasn't been assigned an IP address yet, we accept all ICMP + haven't been assigned an IP address yet, we accept all ICMP packets. */ -#if UIP_PINGADDRCONF && !UIP_CONF_IPV6 +#if UIP_PINGADDRCONF && !NETSTACK_CONF_WITH_IPV6 if(BUF->proto == UIP_PROTO_ICMP) { UIP_LOG("ip: possible ping config packet received."); goto icmp_input; @@ -924,12 +922,12 @@ uip_process(uint8_t flag) #endif /* UIP_BROADCAST */ /* Check if the packet is destined for our IP address. */ -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr)) { UIP_STAT(++uip_stat.ip.drop); goto drop; } -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ /* For IPv6, packet reception is a little trickier as we need to make sure that we listen to certain multicast addresses (all hosts multicast address, and the solicited-node multicast @@ -940,10 +938,10 @@ uip_process(uint8_t flag) UIP_STAT(++uip_stat.ip.drop); goto drop; } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ } -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header checksum. */ UIP_STAT(++uip_stat.ip.drop); @@ -951,7 +949,7 @@ uip_process(uint8_t flag) UIP_LOG("ip: bad checksum."); goto drop; } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #if UIP_TCP if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so, @@ -967,7 +965,7 @@ uip_process(uint8_t flag) } #endif /* UIP_UDP */ -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 /* ICMPv4 processing code follows. */ if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from here. */ @@ -1018,7 +1016,7 @@ uip_process(uint8_t flag) goto ip_send_nolen; /* End of IPv4 input header processing code. */ -#else /* !UIP_CONF_IPV6 */ +#else /* !NETSTACK_CONF_WITH_IPV6 */ /* This is IPv6 ICMPv6 processing code. */ DEBUG_PRINTF("icmp6_input: length %d\n", uip_len); @@ -1086,7 +1084,7 @@ uip_process(uint8_t flag) /* End of IPv6 ICMP processing. */ -#endif /* !UIP_CONF_IPV6 */ +#endif /* !NETSTACK_CONF_WITH_IPV6 */ #if UIP_UDP /* UDP input processing. */ @@ -1137,7 +1135,7 @@ uip_process(uint8_t flag) } UIP_LOG("udp: no matching connection found"); UIP_STAT(++uip_stat.udp.drop); -#if UIP_CONF_ICMP_DEST_UNREACH && !UIP_CONF_IPV6 +#if UIP_CONF_ICMP_DEST_UNREACH && !NETSTACK_CONF_WITH_IPV6 /* Copy fields from packet header into payload of this ICMP packet. */ memcpy(&(ICMPBUF->payload[0]), ICMPBUF, UIP_IPH_LEN + 8); @@ -1183,15 +1181,15 @@ uip_process(uint8_t flag) } uip_len = uip_slen + UIP_IPUDPH_LEN; -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /* For IPv6, the IP length field does not include the IPv6 IP header length. */ BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ BUF->len[0] = (uip_len >> 8); BUF->len[1] = (uip_len & 0xff); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ BUF->ttl = uip_udp_conn->ttl; BUF->proto = UIP_PROTO_UDP; @@ -1252,7 +1250,7 @@ uip_process(uint8_t flag) } } - /* If we didn't find and active connection that expected the packet, + /* If we didn't find an active connection that expected the packet, either this packet is an old duplicate, or this is a SYN packet destined for a connection in LISTEN. If the SYN flag isn't set, it is an old packet and we send a RST. */ @@ -1374,10 +1372,10 @@ uip_process(uint8_t flag) uip_connr->len = 1; /* rcv_nxt should be the seqno from the incoming packet + 1. */ - uip_connr->rcv_nxt[3] = BUF->seqno[3]; - uip_connr->rcv_nxt[2] = BUF->seqno[2]; - uip_connr->rcv_nxt[1] = BUF->seqno[1]; uip_connr->rcv_nxt[0] = BUF->seqno[0]; + uip_connr->rcv_nxt[1] = BUF->seqno[1]; + uip_connr->rcv_nxt[2] = BUF->seqno[2]; + uip_connr->rcv_nxt[3] = BUF->seqno[3]; uip_add_rcv_nxt(1); /* Parse the TCP MSS option, if present. */ @@ -1441,7 +1439,7 @@ uip_process(uint8_t flag) uip_flags = 0; /* We do a very naive form of TCP reset processing; we just accept any RST and kill our connection. We should in fact check if the - sequence number of this reset is wihtin our advertised window + sequence number of this reset is within our advertised window before we accept the reset. */ if(BUF->flags & TCP_RST) { uip_connr->tcpstateflags = UIP_CLOSED; @@ -1596,7 +1594,7 @@ uip_process(uint8_t flag) uip_add_rcv_nxt(1); uip_flags = UIP_CONNECTED | UIP_NEWDATA; uip_connr->len = 0; - uip_len = 0; + uip_clear_buf(); uip_slen = 0; UIP_APPCALL(); goto appsend; @@ -1875,8 +1873,6 @@ uip_process(uint8_t flag) BUF->seqno[2] = uip_connr->snd_nxt[2]; BUF->seqno[3] = uip_connr->snd_nxt[3]; - BUF->proto = UIP_PROTO_TCP; - BUF->srcport = uip_connr->lport; BUF->destport = uip_connr->rport; @@ -1893,16 +1889,18 @@ uip_process(uint8_t flag) } tcp_send_noconn: + BUF->proto = UIP_PROTO_TCP; + BUF->ttl = UIP_TTL; -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /* For IPv6, the IP length field does not include the IPv6 IP header length. */ BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ BUF->len[0] = (uip_len >> 8); BUF->len[1] = (uip_len & 0xff); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ BUF->urgp[0] = BUF->urgp[1] = 0; @@ -1912,11 +1910,11 @@ uip_process(uint8_t flag) #endif ip_send_nolen: -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 BUF->vtc = 0x60; BUF->tcflow = 0x00; BUF->flow = 0x00; -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ BUF->vhl = 0x45; BUF->tos = 0; BUF->ipoffset[0] = BUF->ipoffset[1] = 0; @@ -1927,11 +1925,11 @@ uip_process(uint8_t flag) BUF->ipchksum = 0; BUF->ipchksum = ~(uip_ipchksum()); DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum()); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ UIP_STAT(++uip_stat.tcp.sent); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 send: -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len, (BUF->len[0] << 8) | BUF->len[1]); @@ -1941,7 +1939,7 @@ uip_process(uint8_t flag) return; drop: - uip_len = 0; + uip_clear_buf(); uip_flags = 0; return; } @@ -1962,7 +1960,6 @@ void uip_send(const void *data, int len) { int copylen; -#define MIN(a,b) ((a) < (b)? (a): (b)) copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN - (int)((char *)uip_sappdata - (char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN])); if(copylen > 0) { @@ -1973,6 +1970,4 @@ uip_send(const void *data, int len) } } /*---------------------------------------------------------------------------*/ -#endif /* UIP_CONF_IPV6 */ - /** @}*/ diff --git a/core/net/ipv4/uip_arp.c b/core/net/ipv4/uip_arp.c index 87145f598..10015295e 100644 --- a/core/net/ipv4/uip_arp.c +++ b/core/net/ipv4/uip_arp.c @@ -1,29 +1,3 @@ -/** - * \addtogroup uip - * @{ - */ - -/** - * \defgroup uiparp uIP Address Resolution Protocol - * @{ - * - * The Address Resolution Protocol ARP is used for mapping between IP - * addresses and link level addresses such as the Ethernet MAC - * addresses. ARP uses broadcast queries to ask for the link level - * address of a known IP address and the host which is configured with - * the IP address for which the query was meant, will respond with its - * link level address. - * - * \note This ARP implementation only supports Ethernet. - */ - -/** - * \file - * Implementation of the ARP Address Resolution Protocol. - * \author Adam Dunkels - * - */ - /* * Copyright (c) 2001-2003, Adam Dunkels. * All rights reserved. @@ -57,7 +31,32 @@ * */ +/** + * \file + * Implementation of the ARP Address Resolution Protocol. + * \author Adam Dunkels + * + */ +/** + * \addtogroup uip + * @{ + */ + +/** + * \defgroup uiparp uIP Address Resolution Protocol + * @{ + * + * The Address Resolution Protocol ARP is used for mapping between IP + * addresses and link level addresses such as the Ethernet MAC + * addresses. ARP uses broadcast queries to ask for the link level + * address of a known IP address and the host which is configured with + * the IP address for which the query was meant, will respond with its + * link level address. + * + * \note This ARP implementation only supports Ethernet. + */ + #include "net/ipv4/uip_arp.h" #include @@ -285,10 +284,10 @@ uip_arp_arpin(void) { if(uip_len < sizeof(struct arp_hdr)) { - uip_len = 0; + uip_clear_buf(); return; } - uip_len = 0; + uip_clear_buf(); switch(BUF->opcode) { case UIP_HTONS(ARP_REQUEST): diff --git a/core/net/ipv4/uip_arp.h b/core/net/ipv4/uip_arp.h index 16892bf14..af9e51567 100644 --- a/core/net/ipv4/uip_arp.h +++ b/core/net/ipv4/uip_arp.h @@ -1,20 +1,3 @@ -/** - * \addtogroup uip - * @{ - */ - -/** - * \addtogroup uiparp - * @{ - */ - -/** - * \file - * Macros and definitions for the ARP module. - * \author Adam Dunkels - */ - - /* * Copyright (c) 2001-2003, Adam Dunkels. * All rights reserved. @@ -48,6 +31,22 @@ * */ +/** + * \file + * Macros and definitions for the ARP module. + * \author Adam Dunkels + */ + +/** + * \addtogroup uip + * @{ + */ + +/** + * \addtogroup uiparp + * @{ + */ + #ifndef UIP_ARP_H_ #define UIP_ARP_H_ diff --git a/core/net/ipv6/multicast/README.md b/core/net/ipv6/multicast/README.md index 2108b92f2..7a33fca0f 100644 --- a/core/net/ipv6/multicast/README.md +++ b/core/net/ipv6/multicast/README.md @@ -98,7 +98,7 @@ In order to extend multicast with a new engine, perform the following steps: - Open `uip-mcast6.h` and add a section in the `#if` spree. This aims to configure the uIPv6 core. More specifically, you need to: * Specify if you want to put RPL in MOP3 by defining - `RPL_CONF_MULTICAST`: 1: MOP 3, 0: non-multicast MOP + `RPL_WITH_MULTICAST`: 1: MOP 3, 0: non-multicast MOP * Define your engine details #define UIP_MCAST6 foo_driver diff --git a/core/net/ipv6/multicast/esmrf.c b/core/net/ipv6/multicast/esmrf.c new file mode 100644 index 000000000..284853a9c --- /dev/null +++ b/core/net/ipv6/multicast/esmrf.c @@ -0,0 +1,406 @@ +/* + * Copyright (c) 2010, Loughborough University - Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * This file shows the implementations of the Enhanced Stateless + * Multicast RPL Forwarding (ESMRF) + * + * It will only work in RPL networks in MOP 3 "Storing with Multicast" + * + * \author + * Khaled Qorany kqorany2@gmail.com + */ + +#include "contiki.h" +#include "contiki-net.h" +#include "net/ipv6/multicast/uip-mcast6.h" +#include "net/ipv6/multicast/uip-mcast6-route.h" +#include "net/ipv6/multicast/uip-mcast6-stats.h" +#include "net/ipv6/multicast/esmrf.h" +#include "net/rpl/rpl.h" +#include "net/ip/uip.h" +#include "net/netstack.h" +#include + +extern uint16_t uip_slen; + +#define DEBUG NONE +#include "net/ip/uip-debug.h" + +#define ESMRF_VERBOSE NONE + +#if DEBUG && ESMRF_VERBOSE +#define VERBOSE_PRINTF(...) PRINTF(__VA_ARGS__) +#define VERBOSE_PRINT_SEED(s) PRINT_SEED(s) +#else +#define VERBOSE_PRINTF(...) +#define VERBOSE_PRINT_SEED(...) +#endif + +/*---------------------------------------------------------------------------*/ +/* Maintain Stats */ +#if UIP_MCAST6_STATS +static struct esmrf_stats stats; + +#define ESMRF_STATS_ADD(x) stats.x++ +#define ESMRF_STATS_INIT() do { memset(&stats, 0, sizeof(stats)); } while(0) +#else /* UIP_MCAST6_STATS */ +#define ESMRF_STATS_ADD(x) +#define ESMRF_STATS_INIT() +#endif +/*---------------------------------------------------------------------------*/ +/* Macros */ +/*---------------------------------------------------------------------------*/ +/* CCI */ +#define ESMRF_FWD_DELAY() NETSTACK_RDC.channel_check_interval() +/* Number of slots in the next 500ms */ +#define ESMRF_INTERVAL_COUNT ((CLOCK_SECOND >> 2) / fwd_delay) +/*---------------------------------------------------------------------------*/ +/* Internal Data */ +/*---------------------------------------------------------------------------*/ +static struct ctimer mcast_periodic; +static uint8_t mcast_len; +static uip_buf_t mcast_buf; +static uint8_t fwd_delay; +static uint8_t fwd_spread; +static struct uip_udp_conn *c; +static uip_ipaddr_t src_ip; +static uip_ipaddr_t des_ip; +/*---------------------------------------------------------------------------*/ +/* uIPv6 Pointers */ +/*---------------------------------------------------------------------------*/ +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) +#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) +#define UIP_ICMP_PAYLOAD ((unsigned char *)&uip_buf[uip_l2_l3_icmp_hdr_len]) +#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN]) +/*---------------------------------------------------------------------------*/ +/* Local function prototypes */ +/*---------------------------------------------------------------------------*/ +static void icmp_input(void); +static void icmp_output(void); +static void mcast_fwd(void *p); +int remove_ext_hdr(void); +/*---------------------------------------------------------------------------*/ +/* Internal Data Structures */ +/*---------------------------------------------------------------------------*/ +struct multicast_on_behalf{ /* ICMP message of multicast_on_behalf */ + uint16_t mcast_port; + uip_ipaddr_t mcast_ip; + uint8_t mcast_payload[UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN]; +}; +#define UIP_ICMP_MOB 18 /* Size of multicast_on_behalf ICMP header */ +/*---------------------------------------------------------------------------*/ +/* Temporary Stores */ +/*---------------------------------------------------------------------------*/ +static struct multicast_on_behalf *locmobptr; +static int loclen; +/*---------------------------------------------------------------------------*/ +/* ESMRF ICMPv6 handler declaration */ +UIP_ICMP6_HANDLER(esmrf_icmp_handler, ICMP6_ESMRF, + UIP_ICMP6_HANDLER_CODE_ANY, icmp_input); +/*---------------------------------------------------------------------------*/ +static void +icmp_output() +{ + uint16_t payload_len=0; + rpl_dag_t *dag_t; + + struct multicast_on_behalf *mob; + mob = (struct multicast_on_behalf *)UIP_ICMP_PAYLOAD; + memcpy(&mob->mcast_payload, &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], uip_slen); + + UIP_IP_BUF->vtc = 0x60; + UIP_IP_BUF->tcflow = 0; + UIP_IP_BUF->flow = 0; + UIP_IP_BUF->proto = UIP_PROTO_ICMP6; + UIP_IP_BUF->ttl = ESMRF_IP_HOP_LIMIT; + + mob->mcast_port = (uint16_t) uip_udp_conn->rport; + uip_ipaddr_copy(&mob->mcast_ip, &UIP_IP_BUF->destipaddr); + + payload_len = UIP_ICMP_MOB + uip_slen; + + dag_t = rpl_get_any_dag(); + uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &dag_t->dag_id); + uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); + + VERBOSE_PRINTF("ESMRF: ICMPv6 Out - Hdr @ %p, payload @ %p to: ", UIP_ICMP_BUF, mob); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("\n"); + + UIP_IP_BUF->len[0] = (UIP_ICMPH_LEN + payload_len) >> 8; + UIP_IP_BUF->len[1] = (UIP_ICMPH_LEN + payload_len) & 0xff; + + UIP_ICMP_BUF->type = ICMP6_ESMRF; + UIP_ICMP_BUF->icode = ESMRF_ICMP_CODE; + + UIP_ICMP_BUF->icmpchksum = 0; + UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); + + uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + payload_len; + + VERBOSE_PRINTF("ESMRF: ICMPv6 Out - %u bytes, uip_len %u bytes, uip_ext_len %u bytes\n", + payload_len, uip_len, uip_ext_len); + + tcpip_ipv6_output(); + ESMRF_STATS_ADD(icmp_out); + return; +} +/*---------------------------------------------------------------------------*/ +static void +icmp_input() +{ +#if UIP_CONF_IPV6_CHECKS + if(UIP_ICMP_BUF->icode != ESMRF_ICMP_CODE) { + PRINTF("ESMRF: ICMPv6 In, bad ICMP code\n"); + ESMRF_STATS_ADD(icmp_bad); + return; + } + if(UIP_IP_BUF->ttl <= 1) { + PRINTF("ESMRF: ICMPv6 In, bad TTL\n"); + ESMRF_STATS_ADD(icmp_bad); + return; + } +#endif + + remove_ext_hdr(); + + PRINTF("ESMRF: ICMPv6 In from "); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF(" len %u, ext %u\n", uip_len, uip_ext_len); + + ESMRF_STATS_ADD(icmp_in); + + VERBOSE_PRINTF("ESMRF: ICMPv6 In, parse from %p to %p\n", + UIP_ICMP_PAYLOAD, + (uint8_t *)UIP_ICMP_PAYLOAD + uip_len - + uip_l2_l3_icmp_hdr_len); + + + locmobptr = (struct multicast_on_behalf *) UIP_ICMP_PAYLOAD; + loclen = uip_len - (uip_l2_l3_icmp_hdr_len + UIP_ICMP_MOB); + + uip_ipaddr_copy(&src_ip, &UIP_IP_BUF->srcipaddr); + uip_ipaddr_copy(&des_ip, &UIP_IP_BUF->destipaddr); + + /* Extract the original multicast message */ + uip_ipaddr_copy(&c->ripaddr, &locmobptr->mcast_ip); + c->rport = locmobptr->mcast_port; + uip_slen = loclen; + uip_udp_conn=c; + memcpy(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], locmobptr->mcast_payload, + loclen > UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN? + UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN: loclen); + + uip_process(UIP_UDP_SEND_CONN); + + memcpy(&mcast_buf, uip_buf, uip_len); + mcast_len = uip_len; + /* pass the packet to our uip_process to check if it is allowed to + * accept this packet or not */ + uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &src_ip); + uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &des_ip); + UIP_UDP_BUF->udpchksum = 0; + + uip_process(UIP_DATA); + + memcpy(uip_buf, &mcast_buf, mcast_len); + uip_len = mcast_len; + /* Return the IP of the original Multicast sender */ + uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &src_ip); + UIP_UDP_BUF->udpchksum = 0; + /* If we have an entry in the multicast routing table, something with + * a higher RPL rank (somewhere down the tree) is a group member */ + if(uip_mcast6_route_lookup(&UIP_IP_BUF->destipaddr)) { + PRINTF("ESMRF: Forward this packet\n"); + /* If we enter here, we will definitely forward */ + tcpip_ipv6_output(); + } + uip_clear_buf(); +} +/*---------------------------------------------------------------------------*/ +static void +mcast_fwd(void *p) +{ + memcpy(uip_buf, &mcast_buf, mcast_len); + uip_len = mcast_len; + UIP_IP_BUF->ttl--; + tcpip_output(NULL); + uip_clear_buf(); +} +/*---------------------------------------------------------------------------*/ +static uint8_t +in() +{ + rpl_dag_t *d; /* Our DODAG */ + uip_ipaddr_t *parent_ipaddr; /* Our pref. parent's IPv6 address */ + const uip_lladdr_t *parent_lladdr; /* Our pref. parent's LL address */ + + /* + * Fetch a pointer to the LL address of our preferred parent + * + * ToDo: This rpl_get_any_dag() call is a dirty replacement of the previous + * rpl_get_dag(RPL_DEFAULT_INSTANCE); + * so that things can compile with the new RPL code. This needs updated to + * read instance ID from the RPL HBHO and use the correct parent accordingly + */ + d = rpl_get_any_dag(); + if(!d) { + PRINTF("ESMRF: No DODAG\n"); + UIP_MCAST6_STATS_ADD(mcast_dropped); + return UIP_MCAST6_DROP; + } + + /* Retrieve our preferred parent's LL address */ + parent_ipaddr = rpl_get_parent_ipaddr(d->preferred_parent); + parent_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(parent_ipaddr); + + if(parent_lladdr == NULL) { + PRINTF("ESMRF: NO Parent exist \n"); + UIP_MCAST6_STATS_ADD(mcast_dropped); + return UIP_MCAST6_DROP; + } + + /* + * We accept a datagram if it arrived from our preferred parent, discard + * otherwise. + */ + if(memcmp(parent_lladdr, packetbuf_addr(PACKETBUF_ADDR_SENDER), + UIP_LLADDR_LEN)) { + PRINTF("ESMRF: Routable in but ESMRF ignored it\n"); + UIP_MCAST6_STATS_ADD(mcast_dropped); + return UIP_MCAST6_DROP; + } + + if(UIP_IP_BUF->ttl <= 1) { + UIP_MCAST6_STATS_ADD(mcast_dropped); + return UIP_MCAST6_DROP; + } + + UIP_MCAST6_STATS_ADD(mcast_in_all); + UIP_MCAST6_STATS_ADD(mcast_in_unique); + + /* If we have an entry in the mcast routing table, something with + * a higher RPL rank (somewhere down the tree) is a group member */ + if(uip_mcast6_route_lookup(&UIP_IP_BUF->destipaddr)) { + /* If we enter here, we will definitely forward */ + UIP_MCAST6_STATS_ADD(mcast_fwd); + + /* + * Add a delay (D) of at least ESMRF_FWD_DELAY() to compensate for how + * contikimac handles broadcasts. We can't start our TX before the sender + * has finished its own. + */ + fwd_delay = ESMRF_FWD_DELAY(); + + /* Finalise D: D = min(ESMRF_FWD_DELAY(), ESMRF_MIN_FWD_DELAY) */ +#if ESMRF_MIN_FWD_DELAY + if(fwd_delay < ESMRF_MIN_FWD_DELAY) { + fwd_delay = ESMRF_MIN_FWD_DELAY; + } +#endif + + if(fwd_delay == 0) { + /* No delay required, send it, do it now, why wait? */ + UIP_IP_BUF->ttl--; + tcpip_output(NULL); + UIP_IP_BUF->ttl++; /* Restore before potential upstack delivery */ + } else { + /* Randomise final delay in [D , D*Spread], step D */ + fwd_spread = ESMRF_INTERVAL_COUNT; + if(fwd_spread > ESMRF_MAX_SPREAD) { + fwd_spread = ESMRF_MAX_SPREAD; + } + if(fwd_spread) { + fwd_delay = fwd_delay * (1 + ((random_rand() >> 11) % fwd_spread)); + } + + memcpy(&mcast_buf, uip_buf, uip_len); + mcast_len = uip_len; + ctimer_set(&mcast_periodic, fwd_delay, mcast_fwd, NULL); + } + PRINTF("ESMRF: %u bytes: fwd in %u [%u]\n", + uip_len, fwd_delay, fwd_spread); + } + + /* Done with this packet unless we are a member of the mcast group */ + if(!uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr)) { + PRINTF("ESMRF: Not a group member. No further processing\n"); + return UIP_MCAST6_DROP; + } else { + PRINTF("ESMRF: Ours. Deliver to upper layers\n"); + UIP_MCAST6_STATS_ADD(mcast_in_ours); + return UIP_MCAST6_ACCEPT; + } +} +/*---------------------------------------------------------------------------*/ +static void +init() +{ + UIP_MCAST6_STATS_INIT(NULL); + uip_mcast6_route_init(); + /* Register the ICMPv6 input handler */ + uip_icmp6_register_input_handler(&esmrf_icmp_handler); + c = udp_new(NULL, 0, NULL); +} +/*---------------------------------------------------------------------------*/ +static void +out(void) +{ + rpl_dag_t *dag_t; + dag_t = rpl_get_any_dag(); + if (!dag_t){ + PRINTF("ESMRF: There is no DODAG\n"); + return; + } + if(dag_t->rank == 256){ + PRINTF("ESMRF: I am the Root, thus send the multicast packet normally. \n"); + return; + } + else{ + PRINTF("ESMRF: I am not the Root\n"); + PRINTF("Send multicast-on-befalf message (ICMPv6) instead to "); + PRINT6ADDR(&dag_t->dag_id); + PRINTF("\n"); + icmp_output(); + uip_slen=0; + return; + } +} +/*---------------------------------------------------------------------------*/ +const struct uip_mcast6_driver esmrf_driver = { + "ESMRF", + init, + out, + in, +}; +/*---------------------------------------------------------------------------*/ diff --git a/core/net/ipv6/multicast/esmrf.h b/core/net/ipv6/multicast/esmrf.h new file mode 100644 index 000000000..4a12a38cf --- /dev/null +++ b/core/net/ipv6/multicast/esmrf.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2011, Loughborough University - Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Header file for the Enhanced Stateless Multicast RPL Forwarding (ESMRF) + * + * \author + * Khaled Qorany kqorany2@gmail.com + */ + +#ifndef ESMRF_H_ +#define ESMRF_H_ + +#include "contiki-conf.h" + +#include +/*---------------------------------------------------------------------------*/ +/* Protocol Constants */ +/*---------------------------------------------------------------------------*/ +#define ESMRF_ICMP_CODE 0 /* ICMPv6 code field */ +#define ESMRF_IP_HOP_LIMIT 0xFF /* Hop limit for ICMP messages */ +/*---------------------------------------------------------------------------*/ +/* Configuration */ +/*---------------------------------------------------------------------------*/ +/* Fmin */ +#ifdef ESMRF_CONF_MIN_FWD_DELAY +#define ESMRF_MIN_FWD_DELAY ESMRF_CONF_MIN_FWD_DELAY +#else +#define ESMRF_MIN_FWD_DELAY 4 +#endif + +/* Max Spread */ +#ifdef ESMRF_CONF_MAX_SPREAD +#define ESMRF_MAX_SPREAD ESMRF_CONF_MAX_SPREAD +#else +#define ESMRF_MAX_SPREAD 4 +#endif +/*---------------------------------------------------------------------------*/ +/* Stats datatype */ +/*---------------------------------------------------------------------------*/ +struct esmrf_stats { + uint16_t mcast_in_unique; + uint16_t mcast_in_all; /* At layer 3 */ + uint16_t mcast_in_ours; /* Unique and we are a group member */ + uint16_t mcast_fwd; /* Forwarded by us but we are not the seed */ + uint16_t mcast_out; /* We are the seed */ + uint16_t mcast_bad; + uint16_t mcast_dropped; + uint16_t icmp_out; + uint16_t icmp_in; + uint16_t icmp_bad; +}; + +#endif /* ESMRF_H_ */ diff --git a/core/net/ipv6/multicast/roll-tm.c b/core/net/ipv6/multicast/roll-tm.c index 1fcde5e44..a569063f9 100644 --- a/core/net/ipv6/multicast/roll-tm.c +++ b/core/net/ipv6/multicast/roll-tm.c @@ -29,20 +29,15 @@ * This file is part of the Contiki operating system. */ +/** + * \addtogroup roll-tm + * @{ + */ /** * \file - * This file implements IPv6 MCAST forwarding according to the - * algorithm described in the "MCAST Forwarding Using Trickle" - * internet draft. - * - * The current version of the draft can always be found in - * http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast - * - * This implementation is based on the draft version stored in - * ROLL_TM_VER - * + * Implementation of the ROLL TM multicast engine * \author - * George Oikonomou - + * George Oikonomou - */ #include "contiki.h" @@ -67,7 +62,6 @@ #define VERBOSE_PRINT_SEED(...) #endif -#if UIP_CONF_IPV6 /*---------------------------------------------------------------------------*/ /* Data Representation */ /*---------------------------------------------------------------------------*/ @@ -1106,33 +1100,33 @@ icmp_input() uint16_t val; #if UIP_CONF_IPV6_CHECKS - if(!uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)) { + if(!uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr)) { PRINTF("ROLL TM: ICMPv6 In, bad source "); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF(" to "); PRINT6ADDR(&UIP_IP_BUF->destipaddr); PRINTF("\n"); ROLL_TM_STATS_ADD(icmp_bad); - return; + goto discard; } if(!uip_is_addr_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr) && !uip_is_addr_linklocal_allrouters_mcast(&UIP_IP_BUF->destipaddr)) { PRINTF("ROLL TM: ICMPv6 In, bad destination\n"); ROLL_TM_STATS_ADD(icmp_bad); - return; + goto discard; } if(UIP_ICMP_BUF->icode != ROLL_TM_ICMP_CODE) { PRINTF("ROLL TM: ICMPv6 In, bad ICMP code\n"); ROLL_TM_STATS_ADD(icmp_bad); - return; + goto discard; } if(UIP_IP_BUF->ttl != ROLL_TM_IP_HOP_LIMIT) { PRINTF("ROLL TM: ICMPv6 In, bad TTL\n"); ROLL_TM_STATS_ADD(icmp_bad); - return; + goto discard; } #endif @@ -1317,6 +1311,9 @@ drop: t[1].c++; } +discard: + + uip_len = 0; return; } /*---------------------------------------------------------------------------*/ @@ -1386,8 +1383,7 @@ out() drop: uip_slen = 0; - uip_len = 0; - uip_ext_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ static uint8_t @@ -1441,6 +1437,9 @@ init() return; } /*---------------------------------------------------------------------------*/ +/** + * \brief The ROLL TM engine driver + */ const struct uip_mcast6_driver roll_tm_driver = { "ROLL TM", init, @@ -1448,5 +1447,4 @@ const struct uip_mcast6_driver roll_tm_driver = { in, }; /*---------------------------------------------------------------------------*/ - -#endif /* UIP_CONF_IPV6 */ +/** @} */ diff --git a/core/net/ipv6/multicast/roll-tm.h b/core/net/ipv6/multicast/roll-tm.h index 97dabb552..fce300f95 100644 --- a/core/net/ipv6/multicast/roll-tm.h +++ b/core/net/ipv6/multicast/roll-tm.h @@ -29,25 +29,34 @@ * This file is part of the Contiki operating system. */ +/** + * \addtogroup uip6-multicast + * @{ + */ +/** + * \defgroup roll-tm ROLL Trickle Multicast + * + * IPv6 multicast according to the algorithm in the + * "MCAST Forwarding Using Trickle" internet draft. + * + * The current version of the draft can always be found in + * http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast + * + * This implementation is based on the draft version stored in + * ROLL_TM_VER. + * + * In draft v2, the document was renamed to + * "Multicast Protocol for Low power and Lossy Networks (MPL)" + * Due to very significant changes between draft versions 1 and 2, + * MPL will be implemented as a separate engine and this file here + * will provide legacy support for Draft v1. + * @{ + */ /** * \file - * Header file for IPv6 multicast according to the algorithm in the - * "MCAST Forwarding Using Trickle" internet draft. - * - * The current version of the draft can always be found in - * http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast - * - * This implementation is based on the draft version stored in - * ROLL_TM_VER. - * - * In draft v2, the document was renamed to - * "Multicast Protocol for Low power and Lossy Networks (MPL)" - * Due to very significant changes between draft versions 1 and 2, - * MPL will be implemented as a separate engine and this file here - * will provide legacy support for Draft v1. - * + * Header file for the implementation of the ROLL-TM multicast engine * \author - * George Oikonomou - + * George Oikonomou - */ #ifndef ROLL_TM_H_ @@ -60,9 +69,9 @@ /*---------------------------------------------------------------------------*/ /* Protocol Constants */ /*---------------------------------------------------------------------------*/ -#define ROLL_TM_VER 1 /* Supported Draft Version */ -#define ROLL_TM_ICMP_CODE 0 /* ICMPv6 code field */ -#define ROLL_TM_IP_HOP_LIMIT 0xFF /* Hop limit for ICMP messages */ +#define ROLL_TM_VER 1 /**< Supported Draft Version */ +#define ROLL_TM_ICMP_CODE 0 /**< ROLL TM ICMPv6 code field */ +#define ROLL_TM_IP_HOP_LIMIT 0xFF /**< Hop limit for ICMP messages */ #define ROLL_TM_INFINITE_REDUNDANCY 0xFF #define ROLL_TM_DGRAM_OUT 0 #define ROLL_TM_DGRAM_IN 1 @@ -81,8 +90,8 @@ * settles down, the code compensates the offsets. * * We consider 125, 250ms etc because they are nice divisors of 1 sec - * (quotient is power of two). For some machines (e.g sky/msp430, - * sensinode/cc243x), this is also a nice number of clock ticks + * (quotient is power of two). For some machines (e.g sky/msp430), + * this is also a nice number of clock ticks * * After experimentation, the values of Imin leading to best performance are: * ContikiMAC: Imin=64 (500ms) @@ -153,7 +162,7 @@ /*---------------------------------------------------------------------------*/ /* Configuration */ /*---------------------------------------------------------------------------*/ -/* +/** * Number of Sliding Windows * In essence: How many unique sources of simultaneous multicast traffic do we * want to support for our lowpan @@ -166,7 +175,7 @@ #define ROLL_TM_WINS 2 #endif /*---------------------------------------------------------------------------*/ -/* +/** * Maximum Number of Buffered Multicast Messages * This buffer is shared across all Seed IDs, therefore a new very active Seed * may eventually occupy all slots. It would make little sense (if any) to @@ -178,7 +187,7 @@ #define ROLL_TM_BUFF_NUM 6 #endif /*---------------------------------------------------------------------------*/ -/* +/** * Use Short Seed IDs [short: 2, long: 16 (default)] * It can be argued that we should (and it would be easy to) support both at * the same time but the draft doesn't list this as a MUST so we opt for @@ -190,7 +199,7 @@ #define ROLL_TM_SHORT_SEEDS 0 #endif /*---------------------------------------------------------------------------*/ -/* +/** * Destination address for our ICMPv6 advertisements. The draft gives us a * choice between LL all-nodes or LL all-routers * @@ -202,7 +211,7 @@ #define ROLL_TM_DEST_ALL_NODES 0 #endif /*---------------------------------------------------------------------------*/ -/* +/** * M param for our outgoing messages * By default, we set the M bit (conservative). Define this as 0 to clear the * M bit in our outgoing messages (aggressive) @@ -215,10 +224,21 @@ /*---------------------------------------------------------------------------*/ /* Stats datatype */ /*---------------------------------------------------------------------------*/ +/** + * \brief Multicast stats extension for the ROLL TM engine + */ struct roll_tm_stats { + /** Number of received ICMP datagrams */ UIP_MCAST6_STATS_DATATYPE icmp_in; + + /** Number of ICMP datagrams sent */ UIP_MCAST6_STATS_DATATYPE icmp_out; + + /** Number of malformed ICMP datagrams seen by us */ UIP_MCAST6_STATS_DATATYPE icmp_bad; }; - +/*---------------------------------------------------------------------------*/ #endif /* ROLL_TM_H_ */ +/*---------------------------------------------------------------------------*/ +/** @} */ +/** @} */ diff --git a/core/net/ipv6/multicast/smrf.c b/core/net/ipv6/multicast/smrf.c index 8a80a4142..d62547ef6 100644 --- a/core/net/ipv6/multicast/smrf.c +++ b/core/net/ipv6/multicast/smrf.c @@ -29,14 +29,16 @@ * This file is part of the Contiki operating system. */ +/** + * \addtogroup smrf-multicast + * @{ + */ /** * \file - * This file implements 'Stateless Multicast RPL Forwarding' (SMRF) - * - * It will only work in RPL networks in MOP 3 "Storing with Multicast" + * This file implements 'Stateless Multicast RPL Forwarding' (SMRF) * * \author - * George Oikonomou - + * George Oikonomou - */ #include "contiki.h" @@ -52,7 +54,6 @@ #define DEBUG DEBUG_NONE #include "net/ip/uip-debug.h" -#if UIP_CONF_IPV6 /*---------------------------------------------------------------------------*/ /* Macros */ /*---------------------------------------------------------------------------*/ @@ -80,7 +81,7 @@ mcast_fwd(void *p) uip_len = mcast_len; UIP_IP_BUF->ttl--; tcpip_output(NULL); - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ static uint8_t @@ -200,6 +201,9 @@ out() return; } /*---------------------------------------------------------------------------*/ +/** + * \brief The SMRF engine driver + */ const struct uip_mcast6_driver smrf_driver = { "SMRF", init, @@ -207,5 +211,4 @@ const struct uip_mcast6_driver smrf_driver = { in, }; /*---------------------------------------------------------------------------*/ - -#endif /* UIP_CONF_IPV6 */ +/** @} */ diff --git a/core/net/ipv6/multicast/smrf.h b/core/net/ipv6/multicast/smrf.h index d19fd6de8..51dcf216e 100644 --- a/core/net/ipv6/multicast/smrf.h +++ b/core/net/ipv6/multicast/smrf.h @@ -29,12 +29,22 @@ * This file is part of the Contiki operating system. */ +/** + * \addtogroup uip6-multicast + * @{ + */ +/** + * \defgroup smrf-multicast 'Stateless Multicast RPL Forwarding' (SMRF) + * + * SMRF will only work in RPL networks in MOP 3 "Storing with Multicast" + * @{ + */ /** * \file - * Header file for 'Stateless Multicast RPL Forwarding' (SMRF) + * Header file for the SMRF forwarding engine * * \author - * George Oikonomou - + * George Oikonomou - */ #ifndef SMRF_H_ @@ -71,5 +81,8 @@ struct smrf_stats { uint16_t mcast_bad; uint16_t mcast_dropped; }; - +/*---------------------------------------------------------------------------*/ #endif /* SMRF_H_ */ +/*---------------------------------------------------------------------------*/ +/** @} */ +/** @} */ diff --git a/core/net/ipv6/multicast/uip-mcast6-engines.h b/core/net/ipv6/multicast/uip-mcast6-engines.h index cea3c9ecc..511029d2f 100644 --- a/core/net/ipv6/multicast/uip-mcast6-engines.h +++ b/core/net/ipv6/multicast/uip-mcast6-engines.h @@ -29,22 +29,28 @@ * This file is part of the Contiki operating system. */ +/** + * \addtogroup uip6-multicast + * @{ + */ /** * \file - * Header file with definition of multicast engine constants + * Header file with definition of multicast engine constants * - * When writing a new engine, add it here with a unique number and - * then modify uip-mcast6.h accordingly + * When writing a new engine, add it here with a unique number and + * then modify uip-mcast6.h accordingly * * \author - * George Oikonomou - + * George Oikonomou - */ #ifndef UIP_MCAST6_ENGINES_H_ #define UIP_MCAST6_ENGINES_H_ -#define UIP_MCAST6_ENGINE_NONE 0 /* Selecting this disables mcast */ -#define UIP_MCAST6_ENGINE_SMRF 1 -#define UIP_MCAST6_ENGINE_ROLL_TM 2 +#define UIP_MCAST6_ENGINE_NONE 0 /**< Selecting this disables mcast */ +#define UIP_MCAST6_ENGINE_SMRF 1 /**< The SMRF engine */ +#define UIP_MCAST6_ENGINE_ROLL_TM 2 /**< The ROLL TM engine */ +#define UIP_MCAST6_ENGINE_ESMRF 3 /**< The ESMRF engine */ #endif /* UIP_MCAST6_ENGINES_H_ */ +/** @} */ diff --git a/core/net/ipv6/multicast/uip-mcast6-route.c b/core/net/ipv6/multicast/uip-mcast6-route.c index f99a92818..f6b9737fc 100644 --- a/core/net/ipv6/multicast/uip-mcast6-route.c +++ b/core/net/ipv6/multicast/uip-mcast6-route.c @@ -28,12 +28,16 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ +/** + * \addtogroup uip6-multicast + * @{ + */ /** * \file - * Multicast routing table manipulation + * Multicast routing table manipulation * * \author - * George Oikonomou - + * George Oikonomou - */ #include "contiki.h" @@ -45,7 +49,6 @@ #include #include -#if UIP_CONF_IPV6 /*---------------------------------------------------------------------------*/ /* Size of the multicast routing table */ #ifdef UIP_MCAST6_ROUTE_CONF_ROUTES @@ -129,5 +132,4 @@ uip_mcast6_route_init() list_init(mcast_route_list); } /*---------------------------------------------------------------------------*/ - -#endif /* UIP_CONF_IPV6 */ +/** @} */ diff --git a/core/net/ipv6/multicast/uip-mcast6-route.h b/core/net/ipv6/multicast/uip-mcast6-route.h index ef5d43f77..95e808676 100644 --- a/core/net/ipv6/multicast/uip-mcast6-route.h +++ b/core/net/ipv6/multicast/uip-mcast6-route.h @@ -28,12 +28,16 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ +/** + * \addtogroup uip6-multicast + * @{ + */ /** * \file - * Multicast routing table manipulation + * Header file for multicast routing table manipulation * * \author - * George Oikonomou - + * George Oikonomou - */ #ifndef UIP_MCAST6_ROUTE_H_ #define UIP_MCAST6_ROUTE_H_ @@ -45,18 +49,48 @@ /*---------------------------------------------------------------------------*/ /** \brief An entry in the multicast routing table */ typedef struct uip_mcast6_route { - struct uip_mcast6_route *next; - uip_ipaddr_t group; - uint32_t lifetime; /* seconds */ - void *dag; /* Pointer to an rpl_dag_t struct */ + struct uip_mcast6_route *next; /**< Routes are arranged in a linked list */ + uip_ipaddr_t group; /**< The multicast group */ + uint32_t lifetime; /**< Entry lifetime seconds */ + void *dag; /**< Pointer to an rpl_dag_t struct */ } uip_mcast6_route_t; /*---------------------------------------------------------------------------*/ /** \name Multicast Routing Table Manipulation */ /** @{ */ + +/** + * \brief Lookup a multicast route + * \param group A pointer to the multicast group to be searched for + * \return A pointer to the new routing entry, or NULL if the route could not + * be found + */ uip_mcast6_route_t *uip_mcast6_route_lookup(uip_ipaddr_t *group); + +/** + * \brief Add a multicast route + * \param group A pointer to the multicast group to be added + * \return A pointer to the new route, or NULL if the route could not be added + */ uip_mcast6_route_t *uip_mcast6_route_add(uip_ipaddr_t *group); -void uip_mcast6_route_rm(uip_mcast6_route_t *defrt); + +/** + * \brief Remove a multicast route + * \param route A pointer to the route to be removed + */ +void uip_mcast6_route_rm(uip_mcast6_route_t *route); + +/** + * \brief Retrieve the count of multicast routes + * \return The number of multicast routes + */ int uip_mcast6_route_count(void); + +/** + * \brief Retrieve a pointer to the start of the multicast routes list + * \return A pointer to the start of the multicast routes + * + * If the multicast routes list is empty, this function will return NULL + */ uip_mcast6_route_t *uip_mcast6_route_list_head(void); /*---------------------------------------------------------------------------*/ /** @@ -73,3 +107,4 @@ void uip_mcast6_route_init(void); /** @} */ #endif /* UIP_MCAST6_ROUTE_H_ */ +/** @} */ diff --git a/core/net/ipv6/multicast/uip-mcast6-stats.c b/core/net/ipv6/multicast/uip-mcast6-stats.c index ed23747f1..d617358ba 100644 --- a/core/net/ipv6/multicast/uip-mcast6-stats.c +++ b/core/net/ipv6/multicast/uip-mcast6-stats.c @@ -27,12 +27,16 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ +/** + * \addtogroup uip6-multicast + * @{ + */ /** * \file - * IPv6 multicast forwarding stats maintenance + * IPv6 multicast forwarding stats maintenance * * \author - * George Oikonomou - + * George Oikonomou - */ #include "net/ipv6/multicast/uip-mcast6-stats.h" @@ -47,3 +51,4 @@ uip_mcast6_stats_init(void *stats) uip_mcast6_stats.engine_stats = stats; } /*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/core/net/ipv6/multicast/uip-mcast6-stats.h b/core/net/ipv6/multicast/uip-mcast6-stats.h index 1e3775934..263758b66 100644 --- a/core/net/ipv6/multicast/uip-mcast6-stats.h +++ b/core/net/ipv6/multicast/uip-mcast6-stats.h @@ -27,12 +27,16 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ +/** + * \addtogroup uip6-multicast + * @{ + */ /** * \file - * Header file for IPv6 multicast forwarding stats maintenance + * Header file for IPv6 multicast forwarding stats maintenance * * \author - * George Oikonomou - + * George Oikonomou - */ #ifndef UIP_MCAST6_STATS_H_ #define UIP_MCAST6_STATS_H_ @@ -56,15 +60,35 @@ /*---------------------------------------------------------------------------*/ /* Stats datatype */ /*---------------------------------------------------------------------------*/ +/** + * \brief A data structure used to maintain multicast stats + * + * Each engine can extend this structure via the engine_stats field + */ typedef struct uip_mcast6_stats { + /** Count of unique datagrams received */ UIP_MCAST6_STATS_DATATYPE mcast_in_unique; - UIP_MCAST6_STATS_DATATYPE mcast_in_all; /* At layer 3 */ - UIP_MCAST6_STATS_DATATYPE mcast_in_ours; /* Unique and we are a group member */ - UIP_MCAST6_STATS_DATATYPE mcast_fwd; /* Forwarded by us but we are not the seed */ - UIP_MCAST6_STATS_DATATYPE mcast_out; /* We are the seed */ + + /** Count of all datagrams received */ + UIP_MCAST6_STATS_DATATYPE mcast_in_all; + + /** Count of datagrams received for a group that we have joined */ + UIP_MCAST6_STATS_DATATYPE mcast_in_ours; + + /** Count of datagrams forwarded by us but we are not the seed */ + UIP_MCAST6_STATS_DATATYPE mcast_fwd; + + /** Count of multicast datagrams originated by us */ + UIP_MCAST6_STATS_DATATYPE mcast_out; + + /** Count of malformed multicast datagrams seen by us */ UIP_MCAST6_STATS_DATATYPE mcast_bad; + + /** Count of multicast datagrams correclty formed but dropped by us */ UIP_MCAST6_STATS_DATATYPE mcast_dropped; - void *engine_stats; /* Opaque pointer to an engine's additional stats */ + + /** Opaque pointer to an engine's additional stats */ + void *engine_stats; } uip_mcast6_stats_t; /*---------------------------------------------------------------------------*/ /* Access macros */ @@ -89,3 +113,5 @@ extern uip_mcast6_stats_t uip_mcast6_stats; void uip_mcast6_stats_init(void *stats); /*---------------------------------------------------------------------------*/ #endif /* UIP_MCAST6_STATS_H_ */ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/core/net/ipv6/multicast/uip-mcast6.h b/core/net/ipv6/multicast/uip-mcast6.h index 9bd2b2b2d..211f1128b 100644 --- a/core/net/ipv6/multicast/uip-mcast6.h +++ b/core/net/ipv6/multicast/uip-mcast6.h @@ -30,9 +30,11 @@ */ /** - * \file - * This header file contains configuration directives for uIPv6 - * multicast support. + * \addtogroup uip6 + * @{ + */ +/** + * \defgroup uip6-multicast IPv6 Multicast Forwarding * * We currently support 2 engines: * - 'Stateless Multicast RPL Forwarding' (SMRF) @@ -42,6 +44,14 @@ * in the internet draft: * http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast * + * @{ + */ + +/** + * \file + * This header file contains configuration directives for uIPv6 + * multicast support. + * * \author * George Oikonomou - */ @@ -53,6 +63,7 @@ #include "net/ipv6/multicast/uip-mcast6-engines.h" #include "net/ipv6/multicast/uip-mcast6-route.h" #include "net/ipv6/multicast/smrf.h" +#include "net/ipv6/multicast/esmrf.h" #include "net/ipv6/multicast/roll-tm.h" #include @@ -83,7 +94,11 @@ * Multicast API. Similar to NETSTACK, each engine must define a driver and * populate the fields with suitable function pointers */ +/** + * \brief The data structure used to represent a multicast engine + */ struct uip_mcast6_driver { + /** The driver's name */ char *name; /** Initialize the multicast engine */ @@ -110,6 +125,7 @@ struct uip_mcast6_driver { * * \return 0: Drop, 1: Deliver * + * * When a datagram with a multicast destination address is received, * the forwarding logic in core is bypassed. Instead, we let the * multicast engine handle forwarding internally if and as necessary. @@ -132,17 +148,23 @@ struct uip_mcast6_driver { #if UIP_MCAST6_ENGINE /* Enable Multicast hooks in the uip6 core */ -#define UIP_CONF_IPV6_MULTICAST 1 +#define UIP_IPV6_MULTICAST 1 #if UIP_MCAST6_ENGINE == UIP_MCAST6_ENGINE_ROLL_TM -#define RPL_CONF_MULTICAST 0 /* Not used by trickle */ +#define RPL_WITH_MULTICAST 0 /* Not used by trickle */ #define UIP_CONF_IPV6_ROLL_TM 1 /* ROLL Trickle ICMP type support */ #define UIP_MCAST6 roll_tm_driver + #elif UIP_MCAST6_ENGINE == UIP_MCAST6_ENGINE_SMRF -#define RPL_CONF_MULTICAST 1 +#define RPL_WITH_MULTICAST 1 #define UIP_MCAST6 smrf_driver + +#elif UIP_MCAST6_ENGINE == UIP_MCAST6_ENGINE_ESMRF +#define RPL_CONF_MULTICAST 1 +#define UIP_MCAST6 esmrf_driver + #else #error "Multicast Enabled with an Unknown Engine." #error "Check the value of UIP_MCAST6_CONF_ENGINE in conf files." @@ -153,10 +175,12 @@ extern const struct uip_mcast6_driver UIP_MCAST6; /*---------------------------------------------------------------------------*/ /* Configuration Checks */ /*---------------------------------------------------------------------------*/ -#if RPL_CONF_MULTICAST && (!UIP_CONF_IPV6_RPL) +#if RPL_WITH_MULTICAST && (!UIP_CONF_IPV6_RPL) #error "The selected Multicast mode requires UIP_CONF_IPV6_RPL != 0" #error "Check the value of UIP_CONF_IPV6_RPL in conf files." #endif /*---------------------------------------------------------------------------*/ - #endif /* UIP_MCAST6_H_ */ +/*---------------------------------------------------------------------------*/ +/** @} */ +/** @} */ diff --git a/core/net/ipv6/sicslowpan.c b/core/net/ipv6/sicslowpan.c index cd55c7b51..8c174b228 100644 --- a/core/net/ipv6/sicslowpan.c +++ b/core/net/ipv6/sicslowpan.c @@ -1,7 +1,3 @@ -/** - * \addtogroup sicslowpan - * @{ - */ /* * Copyright (c) 2008, Swedish Institute of Computer Science. * All rights reserved. @@ -33,6 +29,7 @@ * This file is part of the Contiki operating system. * */ + /** * \file * 6lowpan implementation (RFC4944 and draft-ietf-6lowpan-hc-06) @@ -46,13 +43,18 @@ * \author Joel Hoglund */ +/** + * \addtogroup sicslowpan + * @{ + */ + /** * FOR HC-06 COMPLIANCE TODO: * -Add compression options to UDP, currently only supports * both ports compressed or both ports elided - * + * * -Verify TC/FL compression works - * + * * -Add stateless multicast option */ @@ -60,6 +62,7 @@ #include "contiki.h" #include "dev/watchdog.h" +#include "net/link-stats.h" #include "net/ip/tcpip.h" #include "net/ip/uip.h" #include "net/ipv6/uip-ds6.h" @@ -67,8 +70,6 @@ #include "net/ipv6/sicslowpan.h" #include "net/netstack.h" -#if UIP_CONF_IPV6 - #include #define DEBUG DEBUG_NONE @@ -79,15 +80,9 @@ uint8_t p; #include #define PRINTFI(...) PRINTF(__VA_ARGS__) #define PRINTFO(...) PRINTF(__VA_ARGS__) -#define PRINTPACKETBUF() PRINTF("packetbuf buffer: "); for(p = 0; p < packetbuf_datalen(); p++){PRINTF("%.2X", *(packetbuf_ptr + p));} PRINTF("\n") -#define PRINTUIPBUF() PRINTF("UIP buffer: "); for(p = 0; p < uip_len; p++){PRINTF("%.2X", uip_buf[p]);}PRINTF("\n") -#define PRINTSICSLOWPANBUF() PRINTF("SICSLOWPAN buffer: "); for(p = 0; p < sicslowpan_len; p++){PRINTF("%.2X", sicslowpan_buf[p]);}PRINTF("\n") #else #define PRINTFI(...) #define PRINTFO(...) -#define PRINTPACKETBUF() -#define PRINTUIPBUF() -#define PRINTSICSLOWPANBUF() #endif /* DEBUG == 1*/ #if UIP_LOGGING @@ -98,12 +93,6 @@ void uip_log(char *msg); #define UIP_LOG(m) #endif /* UIP_LOGGING == 1 */ -#ifdef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_MAX_MAC_TRANSMISSIONS SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#else -#define SICSLOWPAN_MAX_MAC_TRANSMISSIONS 4 -#endif - #ifndef SICSLOWPAN_COMPRESSION #ifdef SICSLOWPAN_CONF_COMPRESSION #define SICSLOWPAN_COMPRESSION SICSLOWPAN_CONF_COMPRESSION @@ -145,8 +134,10 @@ void uip_log(char *msg); /** \name Pointers in the sicslowpan and uip buffer * @{ */ -#define SICSLOWPAN_IP_BUF ((struct uip_ip_hdr *)&sicslowpan_buf[UIP_LLH_LEN]) -#define SICSLOWPAN_UDP_BUF ((struct uip_udp_hdr *)&sicslowpan_buf[UIP_LLIPH_LEN]) + +/* NOTE: In the multiple-reassembly context there is only room for the header / first fragment */ +#define SICSLOWPAN_IP_BUF(buf) ((struct uip_ip_hdr *)buf) +#define SICSLOWPAN_UDP_BUF(buf) ((struct uip_udp_hdr *)&buf[UIP_IPH_LEN]) #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN]) @@ -155,30 +146,35 @@ void uip_log(char *msg); /** @} */ -/** \brief Size of the 802.15.4 payload (127byte - 25 for MAC header) */ +/** \brief Maximum available size for frame headers, + link layer security-related overhead, as well as + 6LoWPAN payload. */ #ifdef SICSLOWPAN_CONF_MAC_MAX_PAYLOAD #define MAC_MAX_PAYLOAD SICSLOWPAN_CONF_MAC_MAX_PAYLOAD #else /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */ -#define MAC_MAX_PAYLOAD 102 +#define MAC_MAX_PAYLOAD (127 - 2) #endif /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */ -/** \brief Some MAC layers need a minimum payload, which is - configurable through the SICSLOWPAN_CONF_MIN_MAC_PAYLOAD - option. */ +/** \brief Some MAC layers need a minimum payload, which is configurable + through the SICSLOWPAN_CONF_COMPRESSION_THRESHOLD option. */ #ifdef SICSLOWPAN_CONF_COMPRESSION_THRESHOLD #define COMPRESSION_THRESHOLD SICSLOWPAN_CONF_COMPRESSION_THRESHOLD #else #define COMPRESSION_THRESHOLD 0 #endif +/** \brief Fixed size of a frame header. This value is + * used in case framer returns an error or if SICSLOWPAN_USE_FIXED_HDRLEN + * is defined. + */ +#ifndef SICSLOWPAN_FIXED_HDRLEN +#define SICSLOWPAN_FIXED_HDRLEN 21 +#endif + /** \name General variables * @{ */ -#ifdef SICSLOWPAN_NH_COMPRESSOR -/** A pointer to the additional compressor */ -extern struct sicslowpan_nh_compressor SICSLOWPAN_NH_COMPRESSOR; -#endif /** * A pointer to the packetbuf buffer. @@ -214,50 +210,232 @@ static uint8_t uncomp_hdr_len; static int last_tx_status; /** @} */ + +static int last_rssi; + +/* ----------------------------------------------------------------- */ +/* Support for reassembling multiple packets */ +/* ----------------------------------------------------------------- */ + #if SICSLOWPAN_CONF_FRAG -/** \name Fragmentation related variables - * @{ - */ - -static uint16_t sicslowpan_len; - -/** - * The buffer used for the 6lowpan reassembly. - * This buffer contains only the IPv6 packet (no MAC header, 6lowpan, etc). - * It has a fix size as we do not use dynamic memory allocation. - */ -static uip_buf_t sicslowpan_aligned_buf; -#define sicslowpan_buf (sicslowpan_aligned_buf.u8) +static uint16_t my_tag; /** The total length of the IPv6 packet in the sicslowpan_buf. */ -/** - * length of the ip packet already sent / received. - * It includes IP and transport headers. - */ -static uint16_t processed_ip_in_len; +/* This needs to be defined in NBR / Nodes depending on available RAM */ +/* and expected reassembly requirements */ +#ifdef SICSLOWPAN_CONF_FRAGMENT_BUFFERS +#define SICSLOWPAN_FRAGMENT_BUFFERS SICSLOWPAN_CONF_FRAGMENT_BUFFERS +#else +#define SICSLOWPAN_FRAGMENT_BUFFERS 12 +#endif -/** Datagram tag to be put in the fragments I send. */ -static uint16_t my_tag; +/* REASS_CONTEXTS corresponds to the number of simultaneous + * reassemblies that can be made. NOTE: the first buffer for each + * reassembly is stored in the context since it can be larger than the + * rest of the fragments due to header compression. + **/ +#ifdef SICSLOWPAN_CONF_REASS_CONTEXTS +#define SICSLOWPAN_REASS_CONTEXTS SICSLOWPAN_CONF_REASS_CONTEXTS +#else +#define SICSLOWPAN_REASS_CONTEXTS 2 +#endif -/** When reassembling, the tag in the fragments being merged. */ -static uint16_t reass_tag; +/* The size of each fragment (IP payload) for the 6lowpan fragmentation */ +#ifdef SICSLOWPAN_CONF_FRAGMENT_SIZE +#define SICSLOWPAN_FRAGMENT_SIZE SICSLOWPAN_CONF_FRAGMENT_SIZE +#else +#define SICSLOWPAN_FRAGMENT_SIZE 110 +#endif -/** When reassembling, the source address of the fragments being merged */ -linkaddr_t frag_sender; +/* Assuming that the worst growth for uncompression is 38 bytes */ +#define SICSLOWPAN_FIRST_FRAGMENT_SIZE (SICSLOWPAN_FRAGMENT_SIZE + 38) -/** Reassembly %process %timer. */ -static struct timer reass_timer; +/* all information needed for reassembly */ +struct sicslowpan_frag_info { + /** When reassembling, the source address of the fragments being merged */ + linkaddr_t sender; + /** The destination address of the fragments being merged */ + linkaddr_t receiver; + /** When reassembling, the tag in the fragments being merged. */ + uint16_t tag; + /** Total length of the fragmented packet */ + uint16_t len; + /** Current length of reassembled fragments */ + uint16_t reassembled_len; + /** Reassembly %process %timer. */ + struct timer reass_timer; -/** @} */ -#else /* SICSLOWPAN_CONF_FRAG */ -/** The buffer used for the 6lowpan processing is uip_buf. - We do not use any additional buffer.*/ -#define sicslowpan_buf uip_buf -#define sicslowpan_len uip_len + /** Fragment size of first fragment */ + uint16_t first_frag_len; + /** First fragment - needs a larger buffer since the size is uncompressed size + and we need to know total size to know when we have received last fragment. */ + uint8_t first_frag[SICSLOWPAN_FIRST_FRAGMENT_SIZE]; +}; + +static struct sicslowpan_frag_info frag_info[SICSLOWPAN_REASS_CONTEXTS]; + +struct sicslowpan_frag_buf { + /* the index of the frag_info */ + uint8_t index; + /* Fragment offset */ + uint8_t offset; + /* Length of this fragment (if zero this buffer is not allocated) */ + uint8_t len; + uint8_t data[SICSLOWPAN_FRAGMENT_SIZE]; +}; + +static struct sicslowpan_frag_buf frag_buf[SICSLOWPAN_FRAGMENT_BUFFERS]; + +/*---------------------------------------------------------------------------*/ +static int +clear_fragments(uint8_t frag_info_index) +{ + int i, clear_count; + clear_count = 0; + frag_info[frag_info_index].len = 0; + for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) { + if(frag_buf[i].len > 0 && frag_buf[i].index == frag_info_index) { + /* deallocate the buffer */ + frag_buf[i].len = 0; + clear_count++; + } + } + return clear_count; +} +/*---------------------------------------------------------------------------*/ +static int +timeout_fragments(int not_context) +{ + int i; + int count = 0; + for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) { + if(frag_info[i].len > 0 && i != not_context && + timer_expired(&frag_info[i].reass_timer)) { + /* This context can be freed */ + count += clear_fragments(i); + } + } + return count; +} +/*---------------------------------------------------------------------------*/ +static int +store_fragment(uint8_t index, uint8_t offset) +{ + int i; + for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) { + if(frag_buf[i].len == 0) { + /* copy over the data from packetbuf into the fragment buffer and store offset and len */ + frag_buf[i].offset = offset; /* frag offset */ + frag_buf[i].len = packetbuf_datalen() - packetbuf_hdr_len; + frag_buf[i].index = index; + memcpy(frag_buf[i].data, packetbuf_ptr + packetbuf_hdr_len, + packetbuf_datalen() - packetbuf_hdr_len); + + PRINTF("Fragsize: %d\n", frag_buf[i].len); + /* return the length of the stored fragment */ + return frag_buf[i].len; + } + } + /* failed */ + return -1; +} +/*---------------------------------------------------------------------------*/ +/* add a new fragment to the buffer */ +static int8_t +add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset) +{ + int i; + int len; + int8_t found = -1; + + if(offset == 0) { + /* This is a first fragment - check if we can add this */ + for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) { + /* clear all fragment info with expired timer to free all fragment buffers */ + if(frag_info[i].len > 0 && timer_expired(&frag_info[i].reass_timer)) { + clear_fragments(i); + } + + /* We use len as indication on used or not used */ + if(found < 0 && frag_info[i].len == 0) { + /* We remember the first free fragment info but must continue + the loop to free any other expired fragment buffers. */ + found = i; + } + } + + if(found < 0) { + PRINTF("*** Failed to store new fragment session - tag: %d\n", tag); + return -1; + } + + /* Found a free fragment info to store data in */ + frag_info[found].len = frag_size; + frag_info[found].tag = tag; + linkaddr_copy(&frag_info[found].sender, + packetbuf_addr(PACKETBUF_ADDR_SENDER)); + timer_set(&frag_info[found].reass_timer, SICSLOWPAN_REASS_MAXAGE * CLOCK_SECOND / 16); + /* first fragment can not be stored immediately but is moved into + the buffer while uncompressing */ + return found; + } + + /* This is a N-fragment - should find the info */ + for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) { + if(frag_info[i].tag == tag && frag_info[i].len > 0 && + linkaddr_cmp(&frag_info[i].sender, packetbuf_addr(PACKETBUF_ADDR_SENDER))) { + /* Tag and Sender match - this must be the correct info to store in */ + found = i; + break; + } + } + + if(found < 0) { + /* no entry found for storing the new fragment */ + PRINTF("*** Failed to store N-fragment - could not find session - tag: %d offset: %d\n", tag, offset); + return -1; + } + + /* i is the index of the reassembly context */ + len = store_fragment(i, offset); + if(len < 0 && timeout_fragments(i) > 0) { + len = store_fragment(i, offset); + } + if(len > 0) { + frag_info[i].reassembled_len += len; + return i; + } else { + /* should we also clear all fragments since we failed to store + this fragment? */ + PRINTF("*** Failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag); + return -1; + } +} +/*---------------------------------------------------------------------------*/ +/* Copy all the fragments that are associated with a specific context + into uip */ +static void +copy_frags2uip(int context) +{ + int i; + + /* Copy from the fragment context info buffer first */ + memcpy((uint8_t *)UIP_IP_BUF, (uint8_t *)frag_info[context].first_frag, + frag_info[context].first_frag_len); + for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) { + /* And also copy all matching fragments */ + if(frag_buf[i].len > 0 && frag_buf[i].index == context) { + memcpy((uint8_t *)UIP_IP_BUF + (uint16_t)(frag_buf[i].offset << 3), + (uint8_t *)frag_buf[i].data, frag_buf[i].len); + } + } + /* deallocate all the fragments for this context */ + clear_fragments(context); +} #endif /* SICSLOWPAN_CONF_FRAG */ -static int last_rssi; +/* -------------------------------------------------------------------------- */ /*-------------------------------------------------------------------------*/ /* Rime Sniffer support for one single listener to enable powertrace of IP */ @@ -277,7 +455,7 @@ rime_sniffer_remove(struct rime_sniffer *s) } static void -set_packet_attrs() +set_packet_attrs(void) { int c = 0; /* set protocol in NETWORK_ID */ @@ -315,7 +493,7 @@ set_packet_attrs() /** Addresses contexts for IPHC. */ #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 -static struct sicslowpan_addr_context +static struct sicslowpan_addr_context addr_contexts[SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS]; #endif @@ -355,7 +533,7 @@ const uint8_t llprefix[] = {0xfe, 0x80}; static const uint8_t ttl_values[] = {0, 1, 64, 255}; /*--------------------------------------------------------------------*/ -/** \name HC06 related functions +/** \name IPHC related functions * @{ */ /*--------------------------------------------------------------------*/ /** \brief find the context corresponding to prefix ipaddr */ @@ -379,7 +557,7 @@ addr_context_lookup_by_prefix(uip_ipaddr_t *ipaddr) static struct sicslowpan_addr_context* addr_context_lookup_by_number(uint8_t number) { -/* Remove code to avoid warnings and save flash if no context is used */ +/* Remove code to avoid warnings and save flash if no context is used */ #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 int i; for(i = 0; i < SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS; i++) { @@ -461,8 +639,8 @@ uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t const prefix[], * uip_buf buffer. * * - * HC-06 (draft-ietf-6lowpan-hc, version 6)\n - * http://tools.ietf.org/html/draft-ietf-6lowpan-hc-06 + * IPHC (RFC 6282)\n + * http://tools.ietf.org/html/ * * \note We do not support ISA100_UDP header compression * @@ -488,7 +666,7 @@ uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t const prefix[], * dest */ static void -compress_hdr_hc06(linkaddr_t *link_destaddr) +compress_hdr_iphc(linkaddr_t *link_destaddr) { uint8_t tmp, iphc0, iphc1; #if DEBUG @@ -538,11 +716,12 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) * We have to process both in the same time as the offset of traffic class * depends on the presence of version and flow label */ - - /* hc06 format of tc is ECN | DSCP , original is DSCP | ECN */ + + /* IPHC format of tc is ECN | DSCP , original is DSCP | ECN */ + tmp = (UIP_IP_BUF->vtc << 4) | (UIP_IP_BUF->tcflow >> 4); tmp = ((tmp & 0x03) << 6) | (tmp >> 2); - + if(((UIP_IP_BUF->tcflow & 0x0F) == 0) && (UIP_IP_BUF->flow == 0)) { /* flow label can be compressed */ @@ -583,11 +762,7 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) iphc0 |= SICSLOWPAN_IPHC_NH_C; } #endif /*UIP_CONF_UDP*/ -#ifdef SICSLOWPAN_NH_COMPRESSOR - if(SICSLOWPAN_NH_COMPRESSOR.is_compressable(UIP_IP_BUF->proto)) { - iphc0 |= SICSLOWPAN_IPHC_NH_C; - } -#endif + if ((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) { *hc06_ptr = UIP_IP_BUF->proto; hc06_ptr += 1; @@ -625,7 +800,7 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) != NULL) { /* elide the prefix - indicate by CID and set context + SAC */ PRINTF("IPHC: compressing src with context - setting CID & SAC ctx: %d\n", - context->number); + context->number); iphc1 |= SICSLOWPAN_IPHC_CID | SICSLOWPAN_IPHC_SAC; PACKETBUF_IPHC_BUF[2] |= context->number << 4; /* compession compare with this nodes address (source) */ @@ -633,10 +808,10 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT, &UIP_IP_BUF->srcipaddr, &uip_lladdr); /* No context found for this address */ - } else if(uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr) && - UIP_IP_BUF->destipaddr.u16[1] == 0 && - UIP_IP_BUF->destipaddr.u16[2] == 0 && - UIP_IP_BUF->destipaddr.u16[3] == 0) { + } else if(uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr) && + UIP_IP_BUF->destipaddr.u16[1] == 0 && + UIP_IP_BUF->destipaddr.u16[2] == 0 && + UIP_IP_BUF->destipaddr.u16[3] == 0) { iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT, &UIP_IP_BUF->srcipaddr, &uip_lladdr); } else { @@ -682,12 +857,13 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) /* compession compare with link adress (destination) */ iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT, - &UIP_IP_BUF->destipaddr, (uip_lladdr_t *)link_destaddr); + &UIP_IP_BUF->destipaddr, + (uip_lladdr_t *)link_destaddr); /* No context found for this address */ - } else if(uip_is_addr_link_local(&UIP_IP_BUF->destipaddr) && - UIP_IP_BUF->destipaddr.u16[1] == 0 && - UIP_IP_BUF->destipaddr.u16[2] == 0 && - UIP_IP_BUF->destipaddr.u16[3] == 0) { + } else if(uip_is_addr_linklocal(&UIP_IP_BUF->destipaddr) && + UIP_IP_BUF->destipaddr.u16[1] == 0 && + UIP_IP_BUF->destipaddr.u16[2] == 0 && + UIP_IP_BUF->destipaddr.u16[3] == 0) { iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT, &UIP_IP_BUF->destipaddr, (uip_lladdr_t *)link_destaddr); } else { @@ -704,7 +880,7 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) /* UDP header compression */ if(UIP_IP_BUF->proto == UIP_PROTO_UDP) { PRINTF("IPHC: Uncompressed UDP ports on send side: %x, %x\n", - UIP_HTONS(UIP_UDP_BUF->srcport), UIP_HTONS(UIP_UDP_BUF->destport)); + UIP_HTONS(UIP_UDP_BUF->srcport), UIP_HTONS(UIP_UDP_BUF->destport)); /* Mask out the last 4 bits can be used as a mask */ if(((UIP_HTONS(UIP_UDP_BUF->srcport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN) && ((UIP_HTONS(UIP_UDP_BUF->destport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN)) { @@ -712,10 +888,10 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) *hc06_ptr = SICSLOWPAN_NHC_UDP_CS_P_11; PRINTF("IPHC: remove 12 b of both source & dest with prefix 0xFOB\n"); *(hc06_ptr + 1) = - (uint8_t)((UIP_HTONS(UIP_UDP_BUF->srcport) - - SICSLOWPAN_UDP_4_BIT_PORT_MIN) << 4) + - (uint8_t)((UIP_HTONS(UIP_UDP_BUF->destport) - - SICSLOWPAN_UDP_4_BIT_PORT_MIN)); + (uint8_t)((UIP_HTONS(UIP_UDP_BUF->srcport) - + SICSLOWPAN_UDP_4_BIT_PORT_MIN) << 4) + + (uint8_t)((UIP_HTONS(UIP_UDP_BUF->destport) - + SICSLOWPAN_UDP_4_BIT_PORT_MIN)); hc06_ptr += 2; } else if((UIP_HTONS(UIP_UDP_BUF->destport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) { /* we can compress 8 bits of dest, leave source. */ @@ -723,16 +899,16 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) PRINTF("IPHC: leave source, remove 8 bits of dest with prefix 0xF0\n"); memcpy(hc06_ptr + 1, &UIP_UDP_BUF->srcport, 2); *(hc06_ptr + 3) = - (uint8_t)((UIP_HTONS(UIP_UDP_BUF->destport) - - SICSLOWPAN_UDP_8_BIT_PORT_MIN)); + (uint8_t)((UIP_HTONS(UIP_UDP_BUF->destport) - + SICSLOWPAN_UDP_8_BIT_PORT_MIN)); hc06_ptr += 4; } else if((UIP_HTONS(UIP_UDP_BUF->srcport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) { /* we can compress 8 bits of src, leave dest. Copy compressed port */ *hc06_ptr = SICSLOWPAN_NHC_UDP_CS_P_10; PRINTF("IPHC: remove 8 bits of source with prefix 0xF0, leave dest. hch: %i\n", *hc06_ptr); *(hc06_ptr + 1) = - (uint8_t)((UIP_HTONS(UIP_UDP_BUF->srcport) - - SICSLOWPAN_UDP_8_BIT_PORT_MIN)); + (uint8_t)((UIP_HTONS(UIP_UDP_BUF->srcport) - + SICSLOWPAN_UDP_8_BIT_PORT_MIN)); memcpy(hc06_ptr + 2, &UIP_UDP_BUF->destport, 2); hc06_ptr += 4; } else { @@ -751,11 +927,6 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) } #endif /*UIP_CONF_UDP*/ -#ifdef SICSLOWPAN_NH_COMPRESSOR - /* if nothing to compress just return zero */ - hc06_ptr += SICSLOWPAN_NH_COMPRESSOR.compress(hc06_ptr, &uncomp_hdr_len); -#endif - /* before the packetbuf_hdr_len operation */ PACKETBUF_IPHC_BUF[0] = iphc0; PACKETBUF_IPHC_BUF[1] = iphc1; @@ -766,22 +937,23 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) /*--------------------------------------------------------------------*/ /** - * \brief Uncompress HC06 (i.e., IPHC and LOWPAN_UDP) headers and put + * \brief Uncompress IPHC (i.e., IPHC and LOWPAN_UDP) headers and put * them in sicslowpan_buf * * This function is called by the input function when the dispatch is - * HC06. + * IPHC. * We %process the packet in the packetbuf buffer, uncompress the header * fields, and copy the result in the sicslowpan buffer. * At the end of the decompression, packetbuf_hdr_len and uncompressed_hdr_len * are set to the appropriate values * + * \param buf Pointer to the buffer to uncompress the packet into. * \param ip_len Equal to 0 if the packet is not a fragment (IP length * is then inferred from the L2 length), non 0 if the packet is a 1st * fragment. */ static void -uncompress_hdr_hc06(uint16_t ip_len) +uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len) { uint8_t tmp, iphc0, iphc1; /* at least two byte will be used for the encoding */ @@ -801,22 +973,22 @@ uncompress_hdr_hc06(uint16_t ip_len) /* Flow label are carried inline */ if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) { /* Traffic class is carried inline */ - memcpy(&SICSLOWPAN_IP_BUF->tcflow, hc06_ptr + 1, 3); + memcpy(&SICSLOWPAN_IP_BUF(buf)->tcflow, hc06_ptr + 1, 3); tmp = *hc06_ptr; hc06_ptr += 4; - /* hc06 format of tc is ECN | DSCP , original is DSCP | ECN */ + /* IPHC format of tc is ECN | DSCP , original is DSCP | ECN */ /* set version, pick highest DSCP bits and set in vtc */ - SICSLOWPAN_IP_BUF->vtc = 0x60 | ((tmp >> 2) & 0x0f); + SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((tmp >> 2) & 0x0f); /* ECN rolled down two steps + lowest DSCP bits at top two bits */ - SICSLOWPAN_IP_BUF->tcflow = ((tmp >> 2) & 0x30) | (tmp << 6) | - (SICSLOWPAN_IP_BUF->tcflow & 0x0f); + SICSLOWPAN_IP_BUF(buf)->tcflow = ((tmp >> 2) & 0x30) | (tmp << 6) | + (SICSLOWPAN_IP_BUF(buf)->tcflow & 0x0f); } else { /* Traffic class is compressed (set version and no TC)*/ - SICSLOWPAN_IP_BUF->vtc = 0x60; + SICSLOWPAN_IP_BUF(buf)->vtc = 0x60; /* highest flow label bits + ECN bits */ - SICSLOWPAN_IP_BUF->tcflow = (*hc06_ptr & 0x0F) | - ((*hc06_ptr >> 2) & 0x30); - memcpy(&SICSLOWPAN_IP_BUF->flow, hc06_ptr + 1, 2); + SICSLOWPAN_IP_BUF(buf)->tcflow = (*hc06_ptr & 0x0F) | + ((*hc06_ptr >> 2) & 0x30); + memcpy(&SICSLOWPAN_IP_BUF(buf)->flow, hc06_ptr + 1, 2); hc06_ptr += 3; } } else { @@ -824,31 +996,31 @@ uncompress_hdr_hc06(uint16_t ip_len) /* Version and flow label are compressed */ if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) { /* Traffic class is inline */ - SICSLOWPAN_IP_BUF->vtc = 0x60 | ((*hc06_ptr >> 2) & 0x0f); - SICSLOWPAN_IP_BUF->tcflow = ((*hc06_ptr << 6) & 0xC0) | ((*hc06_ptr >> 2) & 0x30); - SICSLOWPAN_IP_BUF->flow = 0; + SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((*hc06_ptr >> 2) & 0x0f); + SICSLOWPAN_IP_BUF(buf)->tcflow = ((*hc06_ptr << 6) & 0xC0) | ((*hc06_ptr >> 2) & 0x30); + SICSLOWPAN_IP_BUF(buf)->flow = 0; hc06_ptr += 1; } else { /* Traffic class is compressed */ - SICSLOWPAN_IP_BUF->vtc = 0x60; - SICSLOWPAN_IP_BUF->tcflow = 0; - SICSLOWPAN_IP_BUF->flow = 0; + SICSLOWPAN_IP_BUF(buf)->vtc = 0x60; + SICSLOWPAN_IP_BUF(buf)->tcflow = 0; + SICSLOWPAN_IP_BUF(buf)->flow = 0; } } /* Next Header */ if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) { /* Next header is carried inline */ - SICSLOWPAN_IP_BUF->proto = *hc06_ptr; - PRINTF("IPHC: next header inline: %d\n", SICSLOWPAN_IP_BUF->proto); + SICSLOWPAN_IP_BUF(buf)->proto = *hc06_ptr; + PRINTF("IPHC: next header inline: %d\n", SICSLOWPAN_IP_BUF(buf)->proto); hc06_ptr += 1; } /* Hop limit */ if((iphc0 & 0x03) != SICSLOWPAN_IPHC_TTL_I) { - SICSLOWPAN_IP_BUF->ttl = ttl_values[iphc0 & 0x03]; + SICSLOWPAN_IP_BUF(buf)->ttl = ttl_values[iphc0 & 0x03]; } else { - SICSLOWPAN_IP_BUF->ttl = *hc06_ptr; + SICSLOWPAN_IP_BUF(buf)->ttl = *hc06_ptr; hc06_ptr += 1; } @@ -869,12 +1041,12 @@ uncompress_hdr_hc06(uint16_t ip_len) } } /* if tmp == 0 we do not have a context and therefore no prefix */ - uncompress_addr(&SICSLOWPAN_IP_BUF->srcipaddr, + uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr, tmp != 0 ? context->prefix : NULL, unc_ctxconf[tmp], (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); } else { /* no compression and link local */ - uncompress_addr(&SICSLOWPAN_IP_BUF->srcipaddr, llprefix, unc_llconf[tmp], + uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr, llprefix, unc_llconf[tmp], (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); } @@ -899,28 +1071,27 @@ uncompress_hdr_hc06(uint16_t ip_len) hc06_ptr++; } - uncompress_addr(&SICSLOWPAN_IP_BUF->destipaddr, prefix, + uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, prefix, unc_mxconf[tmp], NULL); } } else { /* no multicast */ /* Context based */ if(iphc1 & SICSLOWPAN_IPHC_DAC) { - uint8_t dci = (iphc1 & SICSLOWPAN_IPHC_CID) ? - PACKETBUF_IPHC_BUF[2] & 0x0f : 0; + uint8_t dci = (iphc1 & SICSLOWPAN_IPHC_CID) ? PACKETBUF_IPHC_BUF[2] & 0x0f : 0; context = addr_context_lookup_by_number(dci); /* all valid cases below need the context! */ if(context == NULL) { - PRINTF("sicslowpan uncompress_hdr: error context not found\n"); - return; + PRINTF("sicslowpan uncompress_hdr: error context not found\n"); + return; } - uncompress_addr(&SICSLOWPAN_IP_BUF->destipaddr, context->prefix, + uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, context->prefix, unc_ctxconf[tmp], (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); } else { /* not context based => link local M = 0, DAC = 0 - same as SAC */ - uncompress_addr(&SICSLOWPAN_IP_BUF->destipaddr, llprefix, + uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, llprefix, unc_llconf[tmp], (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); } @@ -932,88 +1103,84 @@ uncompress_hdr_hc06(uint16_t ip_len) /* The next header is compressed, NHC is following */ if((*hc06_ptr & SICSLOWPAN_NHC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) { uint8_t checksum_compressed; - SICSLOWPAN_IP_BUF->proto = UIP_PROTO_UDP; + SICSLOWPAN_IP_BUF(buf)->proto = UIP_PROTO_UDP; checksum_compressed = *hc06_ptr & SICSLOWPAN_NHC_UDP_CHECKSUMC; PRINTF("IPHC: Incoming header value: %i\n", *hc06_ptr); switch(*hc06_ptr & SICSLOWPAN_NHC_UDP_CS_P_11) { case SICSLOWPAN_NHC_UDP_CS_P_00: /* 1 byte for NHC, 4 byte for ports, 2 bytes chksum */ - memcpy(&SICSLOWPAN_UDP_BUF->srcport, hc06_ptr + 1, 2); - memcpy(&SICSLOWPAN_UDP_BUF->destport, hc06_ptr + 3, 2); + memcpy(&SICSLOWPAN_UDP_BUF(buf)->srcport, hc06_ptr + 1, 2); + memcpy(&SICSLOWPAN_UDP_BUF(buf)->destport, hc06_ptr + 3, 2); PRINTF("IPHC: Uncompressed UDP ports (ptr+5): %x, %x\n", - UIP_HTONS(SICSLOWPAN_UDP_BUF->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF->destport)); + UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport), + UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport)); hc06_ptr += 5; break; case SICSLOWPAN_NHC_UDP_CS_P_01: /* 1 byte for NHC + source 16bit inline, dest = 0xF0 + 8 bit inline */ PRINTF("IPHC: Decompressing destination\n"); - memcpy(&SICSLOWPAN_UDP_BUF->srcport, hc06_ptr + 1, 2); - SICSLOWPAN_UDP_BUF->destport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(hc06_ptr + 3))); + memcpy(&SICSLOWPAN_UDP_BUF(buf)->srcport, hc06_ptr + 1, 2); + SICSLOWPAN_UDP_BUF(buf)->destport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(hc06_ptr + 3))); PRINTF("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n", - UIP_HTONS(SICSLOWPAN_UDP_BUF->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF->destport)); + UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport)); hc06_ptr += 4; break; case SICSLOWPAN_NHC_UDP_CS_P_10: /* 1 byte for NHC + source = 0xF0 + 8bit inline, dest = 16 bit inline*/ PRINTF("IPHC: Decompressing source\n"); - SICSLOWPAN_UDP_BUF->srcport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + + SICSLOWPAN_UDP_BUF(buf)->srcport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(hc06_ptr + 1))); - memcpy(&SICSLOWPAN_UDP_BUF->destport, hc06_ptr + 2, 2); + memcpy(&SICSLOWPAN_UDP_BUF(buf)->destport, hc06_ptr + 2, 2); PRINTF("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n", - UIP_HTONS(SICSLOWPAN_UDP_BUF->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF->destport)); + UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport)); hc06_ptr += 4; break; case SICSLOWPAN_NHC_UDP_CS_P_11: /* 1 byte for NHC, 1 byte for ports */ - SICSLOWPAN_UDP_BUF->srcport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN + + SICSLOWPAN_UDP_BUF(buf)->srcport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN + (*(hc06_ptr + 1) >> 4)); - SICSLOWPAN_UDP_BUF->destport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN + + SICSLOWPAN_UDP_BUF(buf)->destport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN + ((*(hc06_ptr + 1)) & 0x0F)); PRINTF("IPHC: Uncompressed UDP ports (ptr+2): %x, %x\n", - UIP_HTONS(SICSLOWPAN_UDP_BUF->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF->destport)); + UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport)); hc06_ptr += 2; break; default: - PRINTF("sicslowpan uncompress_hdr: error unsupported UDP compression\n"); - return; + PRINTF("sicslowpan uncompress_hdr: error unsupported UDP compression\n"); + return; } if(!checksum_compressed) { /* has_checksum, default */ - memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, hc06_ptr, 2); + memcpy(&SICSLOWPAN_UDP_BUF(buf)->udpchksum, hc06_ptr, 2); hc06_ptr += 2; PRINTF("IPHC: sicslowpan uncompress_hdr: checksum included\n"); } else { - PRINTF("IPHC: sicslowpan uncompress_hdr: checksum *NOT* included\n"); + PRINTF("IPHC: sicslowpan uncompress_hdr: checksum *NOT* included\n"); } uncomp_hdr_len += UIP_UDPH_LEN; } -#ifdef SICSLOWPAN_NH_COMPRESSOR - else { - hc06_ptr += SICSLOWPAN_NH_COMPRESSOR.uncompress(hc06_ptr, sicslowpan_buf, &uncomp_hdr_len); - } -#endif } packetbuf_hdr_len = hc06_ptr - packetbuf_ptr; - + /* IP length field. */ if(ip_len == 0) { int len = packetbuf_datalen() - packetbuf_hdr_len + uncomp_hdr_len - UIP_IPH_LEN; /* This is not a fragmented packet */ - SICSLOWPAN_IP_BUF->len[0] = len >> 8; - SICSLOWPAN_IP_BUF->len[1] = len & 0x00FF; + SICSLOWPAN_IP_BUF(buf)->len[0] = len >> 8; + SICSLOWPAN_IP_BUF(buf)->len[1] = len & 0x00FF; } else { /* This is a 1st fragment */ - SICSLOWPAN_IP_BUF->len[0] = (ip_len - UIP_IPH_LEN) >> 8; - SICSLOWPAN_IP_BUF->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF; + SICSLOWPAN_IP_BUF(buf)->len[0] = (ip_len - UIP_IPH_LEN) >> 8; + SICSLOWPAN_IP_BUF(buf)->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF; } - + /* length field in UDP header */ - if(SICSLOWPAN_IP_BUF->proto == UIP_PROTO_UDP) { - memcpy(&SICSLOWPAN_UDP_BUF->udplen, &SICSLOWPAN_IP_BUF->len[0], 2); + if(SICSLOWPAN_IP_BUF(buf)->proto == UIP_PROTO_UDP) { + memcpy(&SICSLOWPAN_UDP_BUF(buf)->udplen, &SICSLOWPAN_IP_BUF(buf)->len[0], 2); } return; @@ -1021,254 +1188,6 @@ uncompress_hdr_hc06(uint16_t ip_len) /** @} */ #endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 */ - -#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 -/*--------------------------------------------------------------------*/ -/** \name HC1 compression and uncompression functions - * @{ */ -/*--------------------------------------------------------------------*/ -/** - * \brief Compress IP/UDP header using HC1 and HC_UDP - * - * This function is called by the 6lowpan code to create a compressed - * 6lowpan packet in the packetbuf buffer from a full IPv6 packet in the - * uip_buf buffer. - * - * - * If we can compress everything, we use HC1 dispatch, if not we use - * IPv6 dispatch.\n - * We can compress everything if: - * - IP version is - * - Flow label and traffic class are 0 - * - Both src and dest ip addresses are link local - * - Both src and dest interface ID are recoverable from lower layer - * header - * - Next header is either ICMP, UDP or TCP - * Moreover, if next header is UDP, we try to compress it using HC_UDP. - * This is feasible is both ports are between F0B0 and F0B0 + 15\n\n - * - * Resulting header structure: - * - For ICMP, TCP, non compressed UDP\n - * HC1 encoding = 11111010 (UDP) 11111110 (TCP) 11111100 (ICMP)\n - * \verbatim - * 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | LoWPAN HC1 Dsp | HC1 encoding | IPv6 Hop limit| L4 hdr + data| - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | ... - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * \endverbatim - * - * - For compressed UDP - * HC1 encoding = 11111011, HC_UDP encoding = 11100000\n - * \verbatim - * 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | LoWPAN HC1 Dsp| HC1 encoding | HC_UDP encod.| IPv6 Hop limit| - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | src p.| dst p.| UDP checksum | L4 data... - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * \endverbatim - * - * \param link_destaddr L2 destination address, needed to compress the - * IP destination field - */ -static void -compress_hdr_hc1(linkaddr_t *link_destaddr) -{ - /* - * Check if all the assumptions for full compression - * are valid : - */ - if(UIP_IP_BUF->vtc != 0x60 || - UIP_IP_BUF->tcflow != 0 || - UIP_IP_BUF->flow != 0 || - !uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr) || - !uip_is_addr_mac_addr_based(&UIP_IP_BUF->srcipaddr, &uip_lladdr) || - !uip_is_addr_link_local(&UIP_IP_BUF->destipaddr) || - !uip_is_addr_mac_addr_based(&UIP_IP_BUF->destipaddr, - (uip_lladdr_t *)link_destaddr) || - (UIP_IP_BUF->proto != UIP_PROTO_ICMP6 && - UIP_IP_BUF->proto != UIP_PROTO_UDP && - UIP_IP_BUF->proto != UIP_PROTO_TCP)) - { - /* - * IPV6 DISPATCH - * Something cannot be compressed, use IPV6 DISPATCH, - * compress nothing, copy IPv6 header in packetbuf buffer - */ - *packetbuf_ptr = SICSLOWPAN_DISPATCH_IPV6; - packetbuf_hdr_len += SICSLOWPAN_IPV6_HDR_LEN; - memcpy(packetbuf_ptr + packetbuf_hdr_len, UIP_IP_BUF, UIP_IPH_LEN); - packetbuf_hdr_len += UIP_IPH_LEN; - uncomp_hdr_len += UIP_IPH_LEN; - } else { - /* - * HC1 DISPATCH - * maximum compresssion: - * All fields in the IP header but Hop Limit are elided - * If next header is UDP, we compress UDP header using HC2 - */ - PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH] = SICSLOWPAN_DISPATCH_HC1; - uncomp_hdr_len += UIP_IPH_LEN; - switch(UIP_IP_BUF->proto) { - case UIP_PROTO_ICMP6: - /* HC1 encoding and ttl */ - PACKETBUF_HC1_PTR[PACKETBUF_HC1_ENCODING] = 0xFC; - PACKETBUF_HC1_PTR[PACKETBUF_HC1_TTL] = UIP_IP_BUF->ttl; - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - break; -#if UIP_CONF_TCP - case UIP_PROTO_TCP: - /* HC1 encoding and ttl */ - PACKETBUF_HC1_PTR[PACKETBUF_HC1_ENCODING] = 0xFE; - PACKETBUF_HC1_PTR[PACKETBUF_HC1_TTL] = UIP_IP_BUF->ttl; - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - break; -#endif /* UIP_CONF_TCP */ -#if UIP_CONF_UDP - case UIP_PROTO_UDP: - /* - * try to compress UDP header (we do only full compression). - * This is feasible if both src and dest ports are between - * SICSLOWPAN_UDP_PORT_MIN and SICSLOWPAN_UDP_PORT_MIN + 15 - */ - PRINTF("local/remote port %u/%u\n",UIP_UDP_BUF->srcport,UIP_UDP_BUF->destport); - if(UIP_HTONS(UIP_UDP_BUF->srcport) >= SICSLOWPAN_UDP_PORT_MIN && - UIP_HTONS(UIP_UDP_BUF->srcport) < SICSLOWPAN_UDP_PORT_MAX && - UIP_HTONS(UIP_UDP_BUF->destport) >= SICSLOWPAN_UDP_PORT_MIN && - UIP_HTONS(UIP_UDP_BUF->destport) < SICSLOWPAN_UDP_PORT_MAX) { - /* HC1 encoding */ - PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_HC1_ENCODING] = 0xFB; - - /* HC_UDP encoding, ttl, src and dest ports, checksum */ - PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_UDP_ENCODING] = 0xE0; - PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_TTL] = UIP_IP_BUF->ttl; - - PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_PORTS] = - (uint8_t)((UIP_HTONS(UIP_UDP_BUF->srcport) - - SICSLOWPAN_UDP_PORT_MIN) << 4) + - (uint8_t)((UIP_HTONS(UIP_UDP_BUF->destport) - SICSLOWPAN_UDP_PORT_MIN)); - memcpy(&PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_CHKSUM], &UIP_UDP_BUF->udpchksum, 2); - packetbuf_hdr_len += SICSLOWPAN_HC1_HC_UDP_HDR_LEN; - uncomp_hdr_len += UIP_UDPH_LEN; - } else { - /* HC1 encoding and ttl */ - PACKETBUF_HC1_PTR[PACKETBUF_HC1_ENCODING] = 0xFA; - PACKETBUF_HC1_PTR[PACKETBUF_HC1_TTL] = UIP_IP_BUF->ttl; - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - } - break; -#endif /*UIP_CONF_UDP*/ - } - } - return; -} - -/*--------------------------------------------------------------------*/ -/** - * \brief Uncompress HC1 (and HC_UDP) headers and put them in - * sicslowpan_buf - * - * This function is called by the input function when the dispatch is - * HC1. - * We %process the packet in the packetbuf buffer, uncompress the header - * fields, and copy the result in the sicslowpan buffer. - * At the end of the decompression, packetbuf_hdr_len and uncompressed_hdr_len - * are set to the appropriate values - * - * \param ip_len Equal to 0 if the packet is not a fragment (IP length - * is then inferred from the L2 length), non 0 if the packet is a 1st - * fragment. - */ -static void -uncompress_hdr_hc1(uint16_t ip_len) -{ - /* version, traffic class, flow label */ - SICSLOWPAN_IP_BUF->vtc = 0x60; - SICSLOWPAN_IP_BUF->tcflow = 0; - SICSLOWPAN_IP_BUF->flow = 0; - - /* src and dest ip addresses */ - uip_ip6addr(&SICSLOWPAN_IP_BUF->srcipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0); - uip_ds6_set_addr_iid(&SICSLOWPAN_IP_BUF->srcipaddr, - (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); - uip_ip6addr(&SICSLOWPAN_IP_BUF->destipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0); - uip_ds6_set_addr_iid(&SICSLOWPAN_IP_BUF->destipaddr, - (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); - - uncomp_hdr_len += UIP_IPH_LEN; - - /* Next header field */ - switch(PACKETBUF_HC1_PTR[PACKETBUF_HC1_ENCODING] & 0x06) { - case SICSLOWPAN_HC1_NH_ICMP6: - SICSLOWPAN_IP_BUF->proto = UIP_PROTO_ICMP6; - SICSLOWPAN_IP_BUF->ttl = PACKETBUF_HC1_PTR[PACKETBUF_HC1_TTL]; - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - break; -#if UIP_CONF_TCP - case SICSLOWPAN_HC1_NH_TCP: - SICSLOWPAN_IP_BUF->proto = UIP_PROTO_TCP; - SICSLOWPAN_IP_BUF->ttl = PACKETBUF_HC1_PTR[PACKETBUF_HC1_TTL]; - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - break; -#endif/* UIP_CONF_TCP */ -#if UIP_CONF_UDP - case SICSLOWPAN_HC1_NH_UDP: - SICSLOWPAN_IP_BUF->proto = UIP_PROTO_UDP; - if(PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_HC1_ENCODING] & 0x01) { - /* UDP header is compressed with HC_UDP */ - if(PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_UDP_ENCODING] != - SICSLOWPAN_HC_UDP_ALL_C) { - PRINTF("sicslowpan (uncompress_hdr), packet not supported"); - return; - } - /* IP TTL */ - SICSLOWPAN_IP_BUF->ttl = PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_TTL]; - /* UDP ports, len, checksum */ - SICSLOWPAN_UDP_BUF->srcport = - UIP_HTONS(SICSLOWPAN_UDP_PORT_MIN + - (PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_PORTS] >> 4)); - SICSLOWPAN_UDP_BUF->destport = - UIP_HTONS(SICSLOWPAN_UDP_PORT_MIN + - (PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_PORTS] & 0x0F)); - memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, &PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_CHKSUM], 2); - uncomp_hdr_len += UIP_UDPH_LEN; - packetbuf_hdr_len += SICSLOWPAN_HC1_HC_UDP_HDR_LEN; - } else { - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - } - break; -#endif/* UIP_CONF_UDP */ - default: - /* this shouldn't happen, drop */ - return; - } - - /* IP length field. */ - if(ip_len == 0) { - int len = packetbuf_datalen() - packetbuf_hdr_len + uncomp_hdr_len - UIP_IPH_LEN; - /* This is not a fragmented packet */ - SICSLOWPAN_IP_BUF->len[0] = len >> 8; - SICSLOWPAN_IP_BUF->len[1] = len & 0x00FF; - } else { - /* This is a 1st fragment */ - SICSLOWPAN_IP_BUF->len[0] = (ip_len - UIP_IPH_LEN) >> 8; - SICSLOWPAN_IP_BUF->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF; - } - /* length field in UDP header */ - if(SICSLOWPAN_IP_BUF->proto == UIP_PROTO_UDP) { - memcpy(&SICSLOWPAN_UDP_BUF->udplen, &SICSLOWPAN_IP_BUF->len[0], 2); - } - return; -} -/** @} */ -#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 */ - - - /*--------------------------------------------------------------------*/ /** \name IPv6 dispatch "compression" function * @{ */ @@ -1334,14 +1253,9 @@ send_packet(linkaddr_t *dest) packetbuf_set_addr(PACKETBUF_ADDR_SENDER,(void*)&uip_lladdr); #endif - /* Force acknowledge from sender (test hardware autoacks) */ -#if SICSLOWPAN_CONF_ACK_ALL - packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1); -#endif - /* Provide a callback function to receive the result of a packet transmission. */ - NETSTACK_MAC.send(&packet_sent, NULL); + NETSTACK_LLSEC.send(&packet_sent, NULL); /* If we are sending multiple packets in a row, we need to let the watchdog know that we are still alive. */ @@ -1361,13 +1275,11 @@ static uint8_t output(const uip_lladdr_t *localdest) { int framer_hdrlen; + int max_payload; /* The MAC address of the destination of the packet */ linkaddr_t dest; - /* Number of bytes processed. */ - uint16_t processed_ip_out_len; - /* init */ uncomp_hdr_len = 0; packetbuf_hdr_len = 0; @@ -1376,15 +1288,13 @@ output(const uip_lladdr_t *localdest) packetbuf_clear(); packetbuf_ptr = packetbuf_dataptr(); - packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, - SICSLOWPAN_MAX_MAC_TRANSMISSIONS); - if(callback) { /* call the attribution when the callback comes, but set attributes here ! */ set_packet_attrs(); } +#if PACKETBUF_WITH_PACKET_TYPE #define TCP_FIN 0x01 #define TCP_ACK 0x10 #define TCP_CTL 0x3f @@ -1399,6 +1309,7 @@ output(const uip_lladdr_t *localdest) packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, PACKETBUF_ATTR_PACKET_TYPE_STREAM_END); } +#endif /* * The destination address will be tagged to each outbound @@ -1410,19 +1321,16 @@ output(const uip_lladdr_t *localdest) } else { linkaddr_copy(&dest, (const linkaddr_t *)localdest); } - + PRINTFO("sicslowpan output: sending packet len %d\n", uip_len); if(uip_len >= COMPRESSION_THRESHOLD) { /* Try to compress the headers */ -#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 - compress_hdr_hc1(&dest); -#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 */ #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 compress_hdr_ipv6(&dest); #endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 */ #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 - compress_hdr_hc06(&dest); + compress_hdr_iphc(&dest); #endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 */ } else { compress_hdr_ipv6(&dest); @@ -1432,42 +1340,50 @@ output(const uip_lladdr_t *localdest) /* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_RDC. * We calculate it here only to make a better decision of whether the outgoing packet * needs to be fragmented or not. */ -#define USE_FRAMER_HDRLEN 1 -#if USE_FRAMER_HDRLEN - packetbuf_clear(); +#ifndef SICSLOWPAN_USE_FIXED_HDRLEN packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest); - framer_hdrlen = NETSTACK_FRAMER.create(); + framer_hdrlen = NETSTACK_FRAMER.length(); if(framer_hdrlen < 0) { /* Framing failed, we assume the maximum header length */ - framer_hdrlen = 21; + framer_hdrlen = SICSLOWPAN_FIXED_HDRLEN; } - packetbuf_clear(); - - /* We must set the max transmissions attribute again after clearing - the buffer. */ - packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, - SICSLOWPAN_MAX_MAC_TRANSMISSIONS); #else /* USE_FRAMER_HDRLEN */ - framer_hdrlen = 21; + framer_hdrlen = SICSLOWPAN_FIXED_HDRLEN; #endif /* USE_FRAMER_HDRLEN */ - if((int)uip_len - (int)uncomp_hdr_len > (int)MAC_MAX_PAYLOAD - framer_hdrlen - (int)packetbuf_hdr_len) { + max_payload = MAC_MAX_PAYLOAD - framer_hdrlen; + if((int)uip_len - (int)uncomp_hdr_len > max_payload - (int)packetbuf_hdr_len) { #if SICSLOWPAN_CONF_FRAG + /* Number of bytes processed. */ + uint16_t processed_ip_out_len; + struct queuebuf *q; + uint16_t frag_tag; + /* * The outbound IPv6 packet is too large to fit into a single 15.4 * packet, so we fragment it into multiple packets and send them. * The first fragment contains frag1 dispatch, then - * IPv6/HC1/HC06/HC_UDP dispatchs/headers. + * IPv6/IPHC/HC_UDP dispatchs/headers. * The following fragments contain only the fragn dispatch. */ + int estimated_fragments = ((int)uip_len) / (max_payload - SICSLOWPAN_FRAGN_HDR_LEN) + 1; + int freebuf = queuebuf_numfree() - 1; + PRINTFO("uip_len: %d, fragments: %d, free bufs: %d\n", uip_len, estimated_fragments, freebuf); + if(freebuf < estimated_fragments) { + PRINTFO("Dropping packet, not enough free bufs\n"); + return 0; + } PRINTFO("Fragmentation sending packet len %d\n", uip_len); /* Create 1st Fragment */ PRINTFO("sicslowpan output: 1rst fragment "); - /* move HC1/HC06/IPv6 header */ + /* Reset last tx status to ok in case the fragment transmissions are deferred */ + last_tx_status = MAC_TX_OK; + + /* move IPHC/IPv6 header */ memmove(packetbuf_ptr + SICSLOWPAN_FRAG1_HDR_LEN, packetbuf_ptr, packetbuf_hdr_len); /* @@ -1478,14 +1394,13 @@ output(const uip_lladdr_t *localdest) /* uip_htons((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len); */ SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE, ((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len)); -/* PACKETBUF_FRAG_BUF->tag = uip_htons(my_tag); */ - SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, my_tag); - my_tag++; + frag_tag = my_tag++; + SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, frag_tag); /* Copy payload and send */ packetbuf_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN; - packetbuf_payload_len = (MAC_MAX_PAYLOAD - framer_hdrlen - packetbuf_hdr_len) & 0xfffffff8; - PRINTFO("(len %d, tag %d)\n", packetbuf_payload_len, my_tag); + packetbuf_payload_len = (max_payload - packetbuf_hdr_len) & 0xfffffff8; + PRINTFO("(len %d, tag %d)\n", packetbuf_payload_len, frag_tag); memcpy(packetbuf_ptr + packetbuf_hdr_len, (uint8_t *)UIP_IP_BUF + uncomp_hdr_len, packetbuf_payload_len); packetbuf_set_datalen(packetbuf_payload_len + packetbuf_hdr_len); @@ -1509,7 +1424,7 @@ output(const uip_lladdr_t *localdest) /* set processed_ip_out_len to what we already sent from the IP payload*/ processed_ip_out_len = packetbuf_payload_len + uncomp_hdr_len; - + /* * Create following fragments * Datagram tag is already in the buffer, we need to set the @@ -1520,18 +1435,18 @@ output(const uip_lladdr_t *localdest) /* uip_htons((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len); */ SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE, ((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len)); - packetbuf_payload_len = (MAC_MAX_PAYLOAD - framer_hdrlen - packetbuf_hdr_len) & 0xfffffff8; + packetbuf_payload_len = (max_payload - packetbuf_hdr_len) & 0xfffffff8; while(processed_ip_out_len < uip_len) { PRINTFO("sicslowpan output: fragment "); PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3; - + /* Copy payload and send */ if(uip_len - processed_ip_out_len < packetbuf_payload_len) { /* last fragment */ packetbuf_payload_len = uip_len - processed_ip_out_len; } PRINTFO("(offset %d, len %d, tag %d)\n", - processed_ip_out_len >> 3, packetbuf_payload_len, my_tag); + processed_ip_out_len >> 3, packetbuf_payload_len, frag_tag); memcpy(packetbuf_ptr + packetbuf_hdr_len, (uint8_t *)UIP_IP_BUF + processed_ip_out_len, packetbuf_payload_len); packetbuf_set_datalen(packetbuf_payload_len + packetbuf_hdr_len); @@ -1574,7 +1489,6 @@ output(const uip_lladdr_t *localdest) /*--------------------------------------------------------------------*/ /** \brief Process a received 6lowpan packet. - * \param r The MAC layer * * The 6lowpan packet is put in packetbuf by the MAC. If its a frag1 or * a non-fragmented packet we first uncompress the IP header. The @@ -1592,13 +1506,20 @@ input(void) uint16_t frag_size = 0; /* offset of the fragment in the IP packet */ uint8_t frag_offset = 0; - uint8_t is_fragment = 0; + uint8_t *buffer; + #if SICSLOWPAN_CONF_FRAG + uint8_t is_fragment = 0; + int8_t frag_context = 0; + /* tag of the fragment */ uint16_t frag_tag = 0; uint8_t first_fragment = 0, last_fragment = 0; #endif /*SICSLOWPAN_CONF_FRAG*/ + /* Update link statistics */ + link_stats_input_callback(packetbuf_addr(PACKETBUF_ADDR_SENDER)); + /* init */ uncomp_hdr_len = 0; packetbuf_hdr_len = 0; @@ -1606,15 +1527,15 @@ input(void) /* The MAC puts the 15.4 payload inside the packetbuf data buffer */ packetbuf_ptr = packetbuf_dataptr(); + /* This is default uip_buf since we assume that this is not fragmented */ + buffer = (uint8_t *)UIP_IP_BUF; + /* Save the RSSI of the incoming packet in case the upper layer will want to query us for it later. */ last_rssi = (signed short)packetbuf_attr(PACKETBUF_ATTR_RSSI); + #if SICSLOWPAN_CONF_FRAG - /* if reassembly timed out, cancel it */ - if(timer_expired(&reass_timer)) { - sicslowpan_len = 0; - processed_ip_in_len = 0; - } + /* * Since we don't support the mesh and broadcast header, the first header * we look for is the fragmentation header @@ -1633,6 +1554,16 @@ input(void) /* printf("frag1 %d %d\n", reass_tag, frag_tag);*/ first_fragment = 1; is_fragment = 1; + + /* Add the fragment to the fragmentation context */ + frag_context = add_fragment(frag_tag, frag_size, frag_offset); + + if(frag_context == -1) { + return; + } + + buffer = frag_info[frag_context].first_frag; + break; case SICSLOWPAN_DISPATCH_FRAGN: /* @@ -1649,10 +1580,22 @@ input(void) /* If this is the last fragment, we may shave off any extrenous bytes at the end. We must be liberal in what we accept. */ - PRINTFI("last_fragment?: processed_ip_in_len %d packetbuf_payload_len %d frag_size %d\n", - processed_ip_in_len, packetbuf_datalen() - packetbuf_hdr_len, frag_size); + PRINTFI("last_fragment?: packetbuf_payload_len %d frag_size %d\n", + packetbuf_datalen() - packetbuf_hdr_len, frag_size); - if(processed_ip_in_len + packetbuf_datalen() - packetbuf_hdr_len >= frag_size) { + /* Add the fragment to the fragmentation context (this will also + copy the payload) */ + frag_context = add_fragment(frag_tag, frag_size, frag_offset); + + if(frag_context == -1) { + return; + } + + /* Ok - add_fragment will store the fragment automatically - so + we should not store more */ + buffer = NULL; + + if(frag_info[frag_context].reassembled_len >= frag_size) { last_fragment = 1; } is_fragment = 1; @@ -1661,65 +1604,7 @@ input(void) break; } - /* We are currently reassembling a packet, but have just received the first - * fragment of another packet. We can either ignore it and hope to receive - * the rest of the under-reassembly packet fragments, or we can discard the - * previous packet altogether, and start reassembling the new packet. - * - * We discard the previous packet, and start reassembling the new packet. - * This lessens the negative impacts of too high SICSLOWPAN_REASS_MAXAGE. - */ -#define PRIORITIZE_NEW_PACKETS 1 -#if PRIORITIZE_NEW_PACKETS - - if(!is_fragment) { - /* Prioritize non-fragment packets too. */ - sicslowpan_len = 0; - processed_ip_in_len = 0; - } else if(processed_ip_in_len > 0 && first_fragment - && !linkaddr_cmp(&frag_sender, packetbuf_addr(PACKETBUF_ADDR_SENDER))) { - sicslowpan_len = 0; - processed_ip_in_len = 0; - } -#endif /* PRIORITIZE_NEW_PACKETS */ - - if(processed_ip_in_len > 0) { - /* reassembly is ongoing */ - /* printf("frag %d %d\n", reass_tag, frag_tag);*/ - if((frag_size > 0 && - (frag_size != sicslowpan_len || - reass_tag != frag_tag || - !linkaddr_cmp(&frag_sender, packetbuf_addr(PACKETBUF_ADDR_SENDER)))) || - frag_size == 0) { - /* - * the packet is a fragment that does not belong to the packet - * being reassembled or the packet is not a fragment. - */ - PRINTFI("sicslowpan input: Dropping 6lowpan packet that is not a fragment of the packet currently being reassembled\n"); - return; - } - } else { - /* - * reassembly is off - * start it if we received a fragment - */ - if((frag_size > 0) && (frag_size <= UIP_BUFSIZE)) { - /* We are currently not reassembling a packet, but have received a packet fragment - * that is not the first one. */ - if(is_fragment && !first_fragment) { - return; - } - - sicslowpan_len = frag_size; - reass_tag = frag_tag; - timer_set(&reass_timer, SICSLOWPAN_REASS_MAXAGE * CLOCK_SECOND / 16); - PRINTFI("sicslowpan input: INIT FRAGMENTATION (len %d, tag %d)\n", - sicslowpan_len, reass_tag); - linkaddr_copy(&frag_sender, packetbuf_addr(PACKETBUF_ADDR_SENDER)); - } - } - - if(packetbuf_hdr_len == SICSLOWPAN_FRAGN_HDR_LEN) { + if(is_fragment && !first_fragment) { /* this is a FRAGN, skip the header compression dispatch section */ goto copypayload; } @@ -1729,22 +1614,16 @@ input(void) #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 if((PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH] & 0xe0) == SICSLOWPAN_DISPATCH_IPHC) { PRINTFI("sicslowpan input: IPHC\n"); - uncompress_hdr_hc06(frag_size); + uncompress_hdr_iphc(buffer, frag_size); } else #endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 */ switch(PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH]) { -#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 - case SICSLOWPAN_DISPATCH_HC1: - PRINTFI("sicslowpan input: HC1\n"); - uncompress_hdr_hc1(frag_size); - break; -#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 */ case SICSLOWPAN_DISPATCH_IPV6: PRINTFI("sicslowpan input: IPV6\n"); packetbuf_hdr_len += SICSLOWPAN_IPV6_HDR_LEN; /* Put uncompressed IP header in sicslowpan_buf. */ - memcpy(SICSLOWPAN_IP_BUF, packetbuf_ptr + packetbuf_hdr_len, UIP_IPH_LEN); + memcpy(buffer, packetbuf_ptr + packetbuf_hdr_len, UIP_IPH_LEN); /* Update uncomp_hdr_len and packetbuf_hdr_len. */ packetbuf_hdr_len += UIP_IPH_LEN; @@ -1756,8 +1635,8 @@ input(void) PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH]); return; } - - + + #if SICSLOWPAN_CONF_FRAG copypayload: #endif /*SICSLOWPAN_CONF_FRAG*/ @@ -1778,61 +1657,62 @@ input(void) { int req_size = UIP_LLH_LEN + uncomp_hdr_len + (uint16_t)(frag_offset << 3) + packetbuf_payload_len; - if(req_size > sizeof(sicslowpan_buf)) { + if(req_size > sizeof(uip_buf)) { PRINTF( - "SICSLOWPAN: packet dropped, minimum required SICSLOWPAN_IP_BUF size: %d+%d+%d+%d=%d (current size: %d)\n", + "SICSLOWPAN: packet dropped, minimum required IP_BUF size: %d+%d+%d+%d=%d (current size: %u)\n", UIP_LLH_LEN, uncomp_hdr_len, (uint16_t)(frag_offset << 3), - packetbuf_payload_len, req_size, sizeof(sicslowpan_buf)); + packetbuf_payload_len, req_size, (unsigned)sizeof(uip_buf)); return; } } - memcpy((uint8_t *)SICSLOWPAN_IP_BUF + uncomp_hdr_len + (uint16_t)(frag_offset << 3), packetbuf_ptr + packetbuf_hdr_len, packetbuf_payload_len); - + /* copy the payload if buffer is non-null - which is only the case with first fragment + or packets that are non fragmented */ + if(buffer != NULL) { + memcpy((uint8_t *)buffer + uncomp_hdr_len, packetbuf_ptr + packetbuf_hdr_len, packetbuf_payload_len); + } + /* update processed_ip_in_len if fragment, sicslowpan_len otherwise */ #if SICSLOWPAN_CONF_FRAG if(frag_size > 0) { /* Add the size of the header only for the first fragment. */ if(first_fragment != 0) { - processed_ip_in_len += uncomp_hdr_len; + frag_info[frag_context].reassembled_len = uncomp_hdr_len + packetbuf_payload_len; + frag_info[frag_context].first_frag_len = uncomp_hdr_len + packetbuf_payload_len; } /* For the last fragment, we are OK if there is extrenous bytes at the end of the packet. */ if(last_fragment != 0) { - processed_ip_in_len = frag_size; - } else { - processed_ip_in_len += packetbuf_payload_len; + frag_info[frag_context].reassembled_len = frag_size; + /* copy to uip */ + copy_frags2uip(frag_context); } - PRINTF("processed_ip_in_len %d, packetbuf_payload_len %d\n", processed_ip_in_len, packetbuf_payload_len); - - } else { -#endif /* SICSLOWPAN_CONF_FRAG */ - sicslowpan_len = packetbuf_payload_len + uncomp_hdr_len; -#if SICSLOWPAN_CONF_FRAG } /* * If we have a full IP packet in sicslowpan_buf, deliver it to * the IP stack */ - PRINTF("sicslowpan_init processed_ip_in_len %d, sicslowpan_len %d\n", - processed_ip_in_len, sicslowpan_len); - if(processed_ip_in_len == 0 || (processed_ip_in_len == sicslowpan_len)) { - PRINTFI("sicslowpan input: IP packet ready (length %d)\n", - sicslowpan_len); - memcpy((uint8_t *)UIP_IP_BUF, (uint8_t *)SICSLOWPAN_IP_BUF, sicslowpan_len); - uip_len = sicslowpan_len; - sicslowpan_len = 0; - processed_ip_in_len = 0; + if(!is_fragment || last_fragment) { + /* packet is in uip already - just set length */ + if(is_fragment != 0 && last_fragment != 0) { + uip_len = frag_size; + } else { + uip_len = packetbuf_payload_len + uncomp_hdr_len; + } +#else + uip_len = packetbuf_payload_len + uncomp_hdr_len; #endif /* SICSLOWPAN_CONF_FRAG */ + PRINTFI("sicslowpan input: IP packet ready (length %d)\n", + uip_len); #if DEBUG { uint16_t ndx; - PRINTF("after decompression %u:", SICSLOWPAN_IP_BUF->len[1]); - for (ndx = 0; ndx < SICSLOWPAN_IP_BUF->len[1] + 40; ndx++) { - uint8_t data = ((uint8_t *) (SICSLOWPAN_IP_BUF))[ndx]; + PRINTF("after decompression %u:", UIP_IP_BUF->len[1]); + for (ndx = 0; ndx < UIP_IP_BUF->len[1] + 40; ndx++) { + uint8_t data = ((uint8_t *) (UIP_IP_BUF))[ndx]; PRINTF("%02x", data); } PRINTF("\n"); @@ -1862,6 +1742,7 @@ sicslowpan_init(void) * Set out output function as the function to be called from uIP to * send a packet. */ + tcpip_set_outputfunc(output); #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 @@ -1870,14 +1751,14 @@ sicslowpan_init(void) * The platform contiki-conf.h file can override this using e.g. * #define SICSLOWPAN_CONF_ADDR_CONTEXT_0 {addr_contexts[0].prefix[0]=0xbb;addr_contexts[0].prefix[1]=0xbb;} */ -#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 +#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 addr_contexts[0].used = 1; addr_contexts[0].number = 0; #ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_0 - SICSLOWPAN_CONF_ADDR_CONTEXT_0; + SICSLOWPAN_CONF_ADDR_CONTEXT_0; #else - addr_contexts[0].prefix[0] = 0xaa; - addr_contexts[0].prefix[1] = 0xaa; + addr_contexts[0].prefix[0] = UIP_DS6_DEFAULT_PREFIX_0; + addr_contexts[0].prefix[1] = UIP_DS6_DEFAULT_PREFIX_1; #endif #endif /* SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 */ @@ -1886,23 +1767,22 @@ sicslowpan_init(void) int i; for(i = 1; i < SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS; i++) { #ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_1 - if (i==1) { - addr_contexts[1].used = 1; - addr_contexts[1].number = 1; - SICSLOWPAN_CONF_ADDR_CONTEXT_1; + if (i==1) { + addr_contexts[1].used = 1; + addr_contexts[1].number = 1; + SICSLOWPAN_CONF_ADDR_CONTEXT_1; #ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_2 } else if (i==2) { - addr_contexts[2].used = 1; - addr_contexts[2].number = 2; - SICSLOWPAN_CONF_ADDR_CONTEXT_2; + addr_contexts[2].used = 1; + addr_contexts[2].number = 2; + SICSLOWPAN_CONF_ADDR_CONTEXT_2; #endif } else { addr_contexts[i].used = 0; - } + } #else addr_contexts[i].used = 0; #endif /* SICSLOWPAN_CONF_ADDR_CONTEXT_1 */ - } } #endif /* SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 1 */ @@ -1923,4 +1803,4 @@ const struct network_driver sicslowpan_driver = { }; /*--------------------------------------------------------------------*/ /** @} */ -#endif /* UIP_CONF_IPV6 */ + diff --git a/core/net/ipv6/sicslowpan.h b/core/net/ipv6/sicslowpan.h index 84f1265c6..4dcb2ae11 100644 --- a/core/net/ipv6/sicslowpan.h +++ b/core/net/ipv6/sicslowpan.h @@ -1,8 +1,3 @@ -/** - * \addtogroup sicslowpan - * @{ - */ - /* * Copyright (c) 2008, Swedish Institute of Computer Science. * All rights reserved. @@ -34,6 +29,7 @@ * This file is part of the Contiki operating system. * */ + /** * \file * Header file for the 6lowpan implementation @@ -45,6 +41,11 @@ * \author Julien Abeille */ +/** + * \addtogroup sicslowpan + * @{ + */ + #ifndef SICSLOWPAN_H_ #define SICSLOWPAN_H_ @@ -233,7 +234,7 @@ struct sicslowpan_addr_context { * \brief check whether we can compress the IID in * address 'a' to 16 bits. * This is used for unicast addresses only, and is true - * if the address is on the format ::0000:00ff:fe00:XXXX + * if the address is on the format \::0000:00ff:fe00:XXXX * NOTE: we currently assume 64-bits prefixes */ #define sicslowpan_is_iid_16_bit_compressable(a) \ diff --git a/core/net/ipv6/uip-ds6-nbr.c b/core/net/ipv6/uip-ds6-nbr.c index a4f42b3b9..3ccebddd1 100644 --- a/core/net/ipv6/uip-ds6-nbr.c +++ b/core/net/ipv6/uip-ds6-nbr.c @@ -1,8 +1,3 @@ -/** - * \addtogroup uip6 - * @{ - */ - /* * Copyright (c) 2013, Swedish Institute of Computer Science. * All rights reserved. @@ -34,9 +29,14 @@ * */ +/** + * \addtogroup uip6 + * @{ + */ + /** * \file - * IPv6 Neighbor cache (link-layer/IPv6 address mapping) + * IPv6 Neighbor cache (link-layer/IPv6 address mapping) * \author Mathilde Durvy * \author Julien Abeille * \author Simon Duquennoy @@ -47,6 +47,7 @@ #include #include #include "lib/list.h" +#include "net/link-stats.h" #include "net/linkaddr.h" #include "net/packetbuf.h" #include "net/ipv6/uip-ds6-nbr.h" @@ -74,25 +75,32 @@ NBR_TABLE_GLOBAL(uip_ds6_nbr_t, ds6_neighbors); void uip_ds6_neighbors_init(void) { + link_stats_init(); nbr_table_register(ds6_neighbors, (nbr_table_callback *)uip_ds6_nbr_rm); } /*---------------------------------------------------------------------------*/ uip_ds6_nbr_t * uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr, - uint8_t isrouter, uint8_t state) + uint8_t isrouter, uint8_t state, nbr_table_reason_t reason, + void *data) { - uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr); + uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr + , reason, data); if(nbr) { uip_ipaddr_copy(&nbr->ipaddr, ipaddr); +#if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER nbr->isrouter = isrouter; +#endif /* UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER */ nbr->state = state; - #if UIP_CONF_IPV6_QUEUE_PKT +#if UIP_CONF_IPV6_QUEUE_PKT uip_packetqueue_new(&nbr->packethandle); - #endif /* UIP_CONF_IPV6_QUEUE_PKT */ +#endif /* UIP_CONF_IPV6_QUEUE_PKT */ +#if UIP_ND6_SEND_NA /* timers are set separately, for now we put them in expired state */ stimer_set(&nbr->reachable, 0); stimer_set(&nbr->sendns, 0); nbr->nscount = 0; +#endif /* UIP_ND6_SEND_NA */ PRINTF("Adding neighbor with ip addr "); PRINT6ADDR(ipaddr); PRINTF(" link addr "); @@ -111,7 +119,7 @@ uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr, } /*---------------------------------------------------------------------------*/ -void +int uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr) { if(nbr != NULL) { @@ -119,9 +127,9 @@ uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr) uip_packetqueue_free(&nbr->packethandle); #endif /* UIP_CONF_IPV6_QUEUE_PKT */ NEIGHBOR_STATE_CHANGED(nbr); - nbr_table_remove(ds6_neighbors, nbr); + return nbr_table_remove(ds6_neighbors, nbr); } - return; + return 0; } /*---------------------------------------------------------------------------*/ @@ -198,15 +206,31 @@ uip_ds6_link_neighbor_callback(int status, int numtx) return; } + /* Update neighbor link statistics */ + link_stats_packet_sent(dest, status, numtx); + /* Call upper-layer callback (e.g. RPL) */ LINK_NEIGHBOR_CALLBACK(dest, status, numtx); #if UIP_DS6_LL_NUD + /* From RFC4861, page 72, last paragraph of section 7.3.3: + * + * "In some cases, link-specific information may indicate that a path to + * a neighbor has failed (e.g., the resetting of a virtual circuit). In + * such cases, link-specific information may be used to purge Neighbor + * Cache entries before the Neighbor Unreachability Detection would do + * so. However, link-specific information MUST NOT be used to confirm + * the reachability of a neighbor; such information does not provide + * end-to-end confirmation between neighboring IP layers." + * + * However, we assume that receiving a link layer ack ensures the delivery + * of the transmitted packed to the IP stack of the neighbour. This is a + * fair assumption and allows battery powered nodes save some battery by + * not re-testing the state of a neighbour periodically if it + * acknowledges link packets. */ if(status == MAC_TX_OK) { uip_ds6_nbr_t *nbr; nbr = uip_ds6_nbr_ll_lookup((uip_lladdr_t *)dest); - if(nbr != NULL && - (nbr->state == NBR_STALE || nbr->state == NBR_DELAY || - nbr->state == NBR_PROBE)) { + if(nbr != NULL && nbr->state != NBR_INCOMPLETE) { nbr->state = NBR_REACHABLE; stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000); PRINTF("uip-ds6-neighbor : received a link layer ACK : "); @@ -217,23 +241,45 @@ uip_ds6_link_neighbor_callback(int status, int numtx) #endif /* UIP_DS6_LL_NUD */ } +#if UIP_ND6_SEND_NA /*---------------------------------------------------------------------------*/ +/** Periodic processing on neighbors */ void uip_ds6_neighbor_periodic(void) { - /* Periodic processing on neighbors */ uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors); while(nbr != NULL) { switch(nbr->state) { case NBR_REACHABLE: if(stimer_expired(&nbr->reachable)) { +#if UIP_CONF_IPV6_RPL + /* when a neighbor leave its REACHABLE state and is a default router, + instead of going to STALE state it enters DELAY state in order to + force a NUD on it. Otherwise, if there is no upward traffic, the + node never knows if the default router is still reachable. This + mimics the 6LoWPAN-ND behavior. + */ + if(uip_ds6_defrt_lookup(&nbr->ipaddr) != NULL) { + PRINTF("REACHABLE: defrt moving to DELAY ("); + PRINT6ADDR(&nbr->ipaddr); + PRINTF(")\n"); + nbr->state = NBR_DELAY; + stimer_set(&nbr->reachable, UIP_ND6_DELAY_FIRST_PROBE_TIME); + nbr->nscount = 0; + } else { + PRINTF("REACHABLE: moving to STALE ("); + PRINT6ADDR(&nbr->ipaddr); + PRINTF(")\n"); + nbr->state = NBR_STALE; + } +#else /* UIP_CONF_IPV6_RPL */ PRINTF("REACHABLE: moving to STALE ("); PRINT6ADDR(&nbr->ipaddr); PRINTF(")\n"); nbr->state = NBR_STALE; +#endif /* UIP_CONF_IPV6_RPL */ } break; -#if UIP_ND6_SEND_NA case NBR_INCOMPLETE: if(nbr->nscount >= UIP_ND6_MAX_MULTICAST_SOLICIT) { uip_ds6_nbr_rm(nbr); @@ -269,7 +315,6 @@ uip_ds6_neighbor_periodic(void) stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000); } break; -#endif /* UIP_ND6_SEND_NA */ default: break; } @@ -295,5 +340,6 @@ uip_ds6_get_least_lifetime_neighbor(void) } return nbr_expiring; } +#endif /* UIP_ND6_SEND_NA */ /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/core/net/ipv6/uip-ds6-nbr.h b/core/net/ipv6/uip-ds6-nbr.h index cd9bb7545..40a17d1e2 100644 --- a/core/net/ipv6/uip-ds6-nbr.h +++ b/core/net/ipv6/uip-ds6-nbr.h @@ -1,8 +1,3 @@ -/** - * \addtogroup uip6 - * @{ - */ - /* * Copyright (c) 2013, Swedish Institute of Computer Science. * All rights reserved. @@ -34,9 +29,14 @@ * */ +/** + * \addtogroup uip6 + * @{ + */ + /** * \file - * IPv6 Neighbor cache (link-layer/IPv6 address mapping) + * IPv6 Neighbor cache (link-layer/IPv6 address mapping) * \author Mathilde Durvy * \author Julien Abeille * \author Simon Duquennoy @@ -69,11 +69,13 @@ NBR_TABLE_DECLARE(ds6_neighbors); /** \brief An entry in the nbr cache */ typedef struct uip_ds6_nbr { uip_ipaddr_t ipaddr; + uint8_t isrouter; + uint8_t state; +#if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA struct stimer reachable; struct stimer sendns; uint8_t nscount; - uint8_t isrouter; - uint8_t state; +#endif /* UIP_ND6_SEND_NA || UIP_ND6_SEND_RA */ #if UIP_CONF_IPV6_QUEUE_PKT struct uip_packetqueue_handle packethandle; #define UIP_DS6_NBR_PACKET_LIFETIME CLOCK_SECOND * 4 @@ -83,9 +85,11 @@ typedef struct uip_ds6_nbr { void uip_ds6_neighbors_init(void); /** \brief Neighbor Cache basic routines */ -uip_ds6_nbr_t *uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr, - uint8_t isrouter, uint8_t state); -void uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr); +uip_ds6_nbr_t *uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, + const uip_lladdr_t *lladdr, + uint8_t isrouter, uint8_t state, + nbr_table_reason_t reason, void *data); +int uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr); const uip_lladdr_t *uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr); const uip_ipaddr_t *uip_ds6_nbr_get_ipaddr(const uip_ds6_nbr_t *nbr); uip_ds6_nbr_t *uip_ds6_nbr_lookup(const uip_ipaddr_t *ipaddr); @@ -98,12 +102,12 @@ int uip_ds6_nbr_num(void); /** * \brief - * This searches inside the neighbor table for the neighbor that is about to - * expire the next. + * This searches inside the neighbor table for the neighbor that is about to + * expire the next. * * \return - * A reference to the neighbor about to expire the next or NULL if - * table is empty. + * A reference to the neighbor about to expire the next or NULL if + * table is empty. */ uip_ds6_nbr_t *uip_ds6_get_least_lifetime_neighbor(void); diff --git a/core/net/ipv6/uip-ds6-route.c b/core/net/ipv6/uip-ds6-route.c index 779488f43..bb7b7b18e 100644 --- a/core/net/ipv6/uip-ds6-route.c +++ b/core/net/ipv6/uip-ds6-route.c @@ -29,6 +29,15 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. * */ +/** + * \addtogroup uip6 + * @{ + */ + +/** + * \file + * Routing table manipulation + */ #include "net/ipv6/uip-ds6.h" #include "net/ip/uip.h" @@ -36,16 +45,25 @@ #include "lib/memb.h" #include "net/nbr-table.h" -#if UIP_CONF_IPV6 - #include +/* A configurable function called after adding a new neighbor as next hop */ +#ifdef NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK +void NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK(const linkaddr_t *addr); +#endif /* NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK */ + +/* A configurable function called after removing a next hop neighbor */ +#ifdef NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK +void NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK(const linkaddr_t *addr); +#endif /* NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK */ + +#if (UIP_CONF_MAX_ROUTES != 0) /* The nbr_routes holds a neighbor table to be able to maintain information about what routes go through what neighbor. This neighbor table is registered with the central nbr-table repository so that it will be maintained along with the rest of the neighbor tables in the system. */ -NBR_TABLE(struct uip_ds6_route_neighbor_routes, nbr_routes); +NBR_TABLE_GLOBAL(struct uip_ds6_route_neighbor_routes, nbr_routes); MEMB(neighborroutememb, struct uip_ds6_route_neighbor_route, UIP_DS6_ROUTE_NB); /* Each route is repressented by a uip_ds6_route_t structure and @@ -54,6 +72,11 @@ MEMB(neighborroutememb, struct uip_ds6_route_neighbor_route, UIP_DS6_ROUTE_NB); LIST(routelist); MEMB(routememb, uip_ds6_route_t, UIP_DS6_ROUTE_NB); +static int num_routes = 0; +static void rm_routelist_callback(nbr_table_item_t *ptr); + +#endif /* (UIP_CONF_MAX_ROUTES != 0) */ + /* Default routes are held on the defaultrouterlist and their structures are allocated from the defaultroutermemb memory block.*/ LIST(defaultrouterlist); @@ -63,13 +86,10 @@ MEMB(defaultroutermemb, uip_ds6_defrt_t, UIP_DS6_DEFRT_NB); LIST(notificationlist); #endif -static int num_routes = 0; - #undef DEBUG #define DEBUG DEBUG_NONE #include "net/ip/uip-debug.h" -static void rm_routelist_callback(nbr_table_item_t *ptr); /*---------------------------------------------------------------------------*/ #if DEBUG != DEBUG_NONE static void @@ -139,10 +159,12 @@ uip_ds6_notification_rm(struct uip_ds6_notification *n) void uip_ds6_route_init(void) { +#if (UIP_CONF_MAX_ROUTES != 0) memb_init(&routememb); list_init(routelist); nbr_table_register(nbr_routes, (nbr_table_callback *)rm_routelist_callback); +#endif /* (UIP_CONF_MAX_ROUTES != 0) */ memb_init(&defaultroutermemb); list_init(defaultrouterlist); @@ -151,6 +173,7 @@ uip_ds6_route_init(void) list_init(notificationlist); #endif } +#if (UIP_CONF_MAX_ROUTES != 0) /*---------------------------------------------------------------------------*/ static uip_lladdr_t * uip_ds6_route_nexthop_lladdr(uip_ds6_route_t *route) @@ -162,42 +185,75 @@ uip_ds6_route_nexthop_lladdr(uip_ds6_route_t *route) return NULL; } } +#endif /* (UIP_CONF_MAX_ROUTES != 0) */ /*---------------------------------------------------------------------------*/ uip_ipaddr_t * uip_ds6_route_nexthop(uip_ds6_route_t *route) { +#if (UIP_CONF_MAX_ROUTES != 0) if(route != NULL) { return uip_ds6_nbr_ipaddr_from_lladdr(uip_ds6_route_nexthop_lladdr(route)); } else { return NULL; } +#else /* (UIP_CONF_MAX_ROUTES != 0) */ + return NULL; +#endif /* (UIP_CONF_MAX_ROUTES != 0) */ } /*---------------------------------------------------------------------------*/ uip_ds6_route_t * uip_ds6_route_head(void) { +#if (UIP_CONF_MAX_ROUTES != 0) return list_head(routelist); +#else /* (UIP_CONF_MAX_ROUTES != 0) */ + return NULL; +#endif /* (UIP_CONF_MAX_ROUTES != 0) */ } /*---------------------------------------------------------------------------*/ uip_ds6_route_t * uip_ds6_route_next(uip_ds6_route_t *r) { +#if (UIP_CONF_MAX_ROUTES != 0) if(r != NULL) { uip_ds6_route_t *n = list_item_next(r); return n; } +#endif /* (UIP_CONF_MAX_ROUTES != 0) */ return NULL; } /*---------------------------------------------------------------------------*/ int +uip_ds6_route_is_nexthop(const uip_ipaddr_t *ipaddr) +{ +#if (UIP_CONF_MAX_ROUTES != 0) + const uip_lladdr_t *lladdr; + lladdr = uip_ds6_nbr_lladdr_from_ipaddr(ipaddr); + + if(lladdr == NULL) { + return 0; + } + + return nbr_table_get_from_lladdr(nbr_routes, (linkaddr_t *)lladdr) != NULL; +#else /* (UIP_CONF_MAX_ROUTES != 0) */ + return 0; +#endif /* (UIP_CONF_MAX_ROUTES != 0) */ +} +/*---------------------------------------------------------------------------*/ +int uip_ds6_route_num_routes(void) { +#if (UIP_CONF_MAX_ROUTES != 0) return num_routes; +#else /* (UIP_CONF_MAX_ROUTES != 0) */ + return 0; +#endif /* (UIP_CONF_MAX_ROUTES != 0) */ } /*---------------------------------------------------------------------------*/ uip_ds6_route_t * uip_ds6_route_lookup(uip_ipaddr_t *addr) { +#if (UIP_CONF_MAX_ROUTES != 0) uip_ds6_route_t *r; uip_ds6_route_t *found_route; uint8_t longestmatch; @@ -216,6 +272,10 @@ uip_ds6_route_lookup(uip_ipaddr_t *addr) uip_ipaddr_prefixcmp(addr, &r->ipaddr, r->length)) { longestmatch = r->length; found_route = r; + /* check if total match - e.g. all 128 bits do match */ + if(longestmatch == 128) { + break; + } } } @@ -229,22 +289,27 @@ uip_ds6_route_lookup(uip_ipaddr_t *addr) PRINTF("uip-ds6-route: No route found\n"); } - if(found_route != NULL) { - /* If we found a route, we put it at the end of the routeslist + if(found_route != NULL && found_route != list_head(routelist)) { + /* If we found a route, we put it at the start of the routeslist list. The list is ordered by how recently we looked them up: - the least recently used route will be at the start of the - list. */ + the least recently used route will be at the end of the + list - for fast lookups (assuming multiple packets to the same node). */ + list_remove(routelist, found_route); - list_add(routelist, found_route); + list_push(routelist, found_route); } return found_route; +#else /* (UIP_CONF_MAX_ROUTES != 0) */ + return NULL; +#endif /* (UIP_CONF_MAX_ROUTES != 0) */ } /*---------------------------------------------------------------------------*/ uip_ds6_route_t * uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, uip_ipaddr_t *nexthop) { +#if (UIP_CONF_MAX_ROUTES != 0) uip_ds6_route_t *r; struct uip_ds6_route_neighbor_route *nbrr; @@ -262,25 +327,39 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, } /* First make sure that we don't add a route twice. If we find an - existing route for our destination, we'll just update the old - one. */ + existing route for our destination, we'll delete the old + one first. */ r = uip_ds6_route_lookup(ipaddr); if(r != NULL) { - PRINTF("uip_ds6_route_add: old route already found, updating this one instead: "); + uip_ipaddr_t *current_nexthop; + current_nexthop = uip_ds6_route_nexthop(r); + if(current_nexthop != NULL && uip_ipaddr_cmp(nexthop, current_nexthop)) { + /* no need to update route - already correct! */ + return r; + } + PRINTF("uip_ds6_route_add: old route for "); PRINT6ADDR(ipaddr); - PRINTF("\n"); - } else { + PRINTF(" found, deleting it\n"); + + uip_ds6_route_rm(r); + } + { struct uip_ds6_route_neighbor_routes *routes; /* If there is no routing entry, create one. We first need to check if we have room for this route. If not, we remove the least recently used one we have. */ if(uip_ds6_route_num_routes() == UIP_DS6_ROUTE_NB) { + uip_ds6_route_t *oldest; + oldest = NULL; +#if UIP_DS6_ROUTE_REMOVE_LEAST_RECENTLY_USED /* Removing the oldest route entry from the route table. The least recently used route is the first route on the list. */ - uip_ds6_route_t *oldest; - - oldest = uip_ds6_route_head(); + oldest = list_tail(routelist); +#endif + if(oldest == NULL) { + return NULL; + } PRINTF("uip_ds6_route_add: dropping route to "); PRINT6ADDR(&oldest->ipaddr); PRINTF("\n"); @@ -306,7 +385,8 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, initialize this pointer with the list of routing entries that are attached to this neighbor. */ routes = nbr_table_add_lladdr(nbr_routes, - (linkaddr_t *)nexthop_lladdr); + (linkaddr_t *)nexthop_lladdr, + NBR_TABLE_REASON_ROUTE, NULL); if(routes == NULL) { /* This should not happen, as we explicitly deallocated one route table entry above. */ @@ -314,6 +394,9 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, return NULL; } LIST_STRUCT_INIT(routes, route_list); +#ifdef NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK + NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK((const linkaddr_t *)nexthop_lladdr); +#endif } /* Allocate a routing entry and populate it. */ @@ -326,7 +409,9 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, return NULL; } - list_add(routelist, r); + /* add new routes first - assuming that there is a reason to add this + and that there is a packet coming soon. */ + list_push(routelist, r); nbrr = memb_alloc(&neighborroutememb); if(nbrr == NULL) { @@ -344,6 +429,9 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, num_routes++; PRINTF("uip_ds6_route_add num %d\n", num_routes); + + /* lock this entry so that nexthop is not removed */ + nbr_table_lock(nbr_routes, routes); } uip_ipaddr_copy(&(r->ipaddr), ipaddr); @@ -368,12 +456,17 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ return r; + +#else /* (UIP_CONF_MAX_ROUTES != 0) */ + return NULL; +#endif /* (UIP_CONF_MAX_ROUTES != 0) */ } /*---------------------------------------------------------------------------*/ void uip_ds6_route_rm(uip_ds6_route_t *route) { +#if (UIP_CONF_MAX_ROUTES != 0) struct uip_ds6_route_neighbor_route *neighbor_route; #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); @@ -384,7 +477,7 @@ uip_ds6_route_rm(uip_ds6_route_t *route) PRINT6ADDR(&route->ipaddr); PRINTF("\n"); - /* Remove the neighbor from the route list */ + /* Remove the route from the route list */ list_remove(routelist, route); /* Find the corresponding neighbor_route and remove it. */ @@ -400,9 +493,19 @@ uip_ds6_route_rm(uip_ds6_route_t *route) list_remove(route->neighbor_routes->route_list, neighbor_route); if(list_head(route->neighbor_routes->route_list) == NULL) { /* If this was the only route using this neighbor, remove the - neibhor from the table */ + neighbor from the table - this implicitly unlocks nexthop */ +#if (DEBUG) & DEBUG_ANNOTATE + uip_ipaddr_t *nexthop = uip_ds6_route_nexthop(route); + if(nexthop != NULL) { + ANNOTATE("#L %u 0\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]); + } +#endif /* (DEBUG) & DEBUG_ANNOTATE */ PRINTF("uip_ds6_route_rm: removing neighbor too\n"); nbr_table_remove(nbr_routes, route->neighbor_routes->route_list); +#ifdef NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK + NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK( + (const linkaddr_t *)nbr_table_get_lladdr(nbr_routes, route->neighbor_routes->route_list)); +#endif } memb_free(&routememb, route); memb_free(&neighborroutememb, neighbor_route); @@ -414,33 +517,17 @@ uip_ds6_route_rm(uip_ds6_route_t *route) #if UIP_DS6_NOTIFICATIONS call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM, &route->ipaddr, uip_ds6_route_nexthop(route)); -#endif -#if 0 //(DEBUG & DEBUG_ANNOTATE) == DEBUG_ANNOTATE - /* we need to check if this was the last route towards "nexthop" */ - /* if so - remove that link (annotation) */ - uip_ds6_route_t *r; - for(r = uip_ds6_route_head(); - r != NULL; - r = uip_ds6_route_next(r)) { - uip_ipaddr_t *nextr, *nextroute; - nextr = uip_ds6_route_nexthop(r); - nextroute = uip_ds6_route_nexthop(route); - if(nextr != NULL && - nextroute != NULL && - uip_ipaddr_cmp(nextr, nextroute)) { - /* we found another link using the specific nexthop, so keep the #L */ - return; - } - } - ANNOTATE("#L %u 0\n", uip_ds6_route_nexthop(route)->u8[sizeof(uip_ipaddr_t) - 1]); #endif } #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ + +#endif /* (UIP_CONF_MAX_ROUTES != 0) */ return; } +#if (UIP_CONF_MAX_ROUTES != 0) /*---------------------------------------------------------------------------*/ static void rm_routelist(struct uip_ds6_route_neighbor_routes *routes) @@ -468,10 +555,12 @@ rm_routelist_callback(nbr_table_item_t *ptr) { rm_routelist((struct uip_ds6_route_neighbor_routes *)ptr); } +#endif /* (UIP_CONF_MAX_ROUTES != 0) */ /*---------------------------------------------------------------------------*/ void uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop) { +#if (UIP_CONF_MAX_ROUTES != 0) /* Get routing entry list of this neighbor */ const uip_lladdr_t *nexthop_lladdr; struct uip_ds6_route_neighbor_routes *routes; @@ -480,6 +569,7 @@ uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop) routes = nbr_table_get_from_lladdr(nbr_routes, (linkaddr_t *)nexthop_lladdr); rm_routelist(routes); +#endif /* (UIP_CONF_MAX_ROUTES != 0) */ } /*---------------------------------------------------------------------------*/ uip_ds6_defrt_t * @@ -622,5 +712,4 @@ uip_ds6_defrt_periodic(void) } } /*---------------------------------------------------------------------------*/ - -#endif /* UIP_CONF_IPV6 */ +/** @} */ diff --git a/core/net/ipv6/uip-ds6-route.h b/core/net/ipv6/uip-ds6-route.h index 9603d6cde..6855fc2cd 100644 --- a/core/net/ipv6/uip-ds6-route.h +++ b/core/net/ipv6/uip-ds6-route.h @@ -29,16 +29,28 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. * */ +/** + * \addtogroup uip6 + * @{ + */ +/** + * \file + * Header file for routing table manipulation + */ #ifndef UIP_DS6_ROUTE_H #define UIP_DS6_ROUTE_H +#include "net/ip/uip.h" +#include "net/nbr-table.h" #include "sys/stimer.h" #include "lib/list.h" +NBR_TABLE_DECLARE(nbr_routes); + void uip_ds6_route_init(void); #ifndef UIP_CONF_UIP_DS6_NOTIFICATIONS -#define UIP_DS6_NOTIFICATIONS 1 +#define UIP_DS6_NOTIFICATIONS (UIP_CONF_MAX_ROUTES != 0) #else #define UIP_DS6_NOTIFICATIONS UIP_CONF_UIP_DS6_NOTIFICATIONS #endif @@ -85,11 +97,48 @@ void uip_ds6_notification_rm(struct uip_ds6_notification *n); #ifndef UIP_DS6_ROUTE_STATE_TYPE #define UIP_DS6_ROUTE_STATE_TYPE rpl_route_entry_t /* Needed for the extended route entry state when using ContikiRPL */ +#define RPL_ROUTE_ENTRY_NOPATH_RECEIVED 0x01 +#define RPL_ROUTE_ENTRY_DAO_PENDING 0x02 +#define RPL_ROUTE_ENTRY_DAO_NACK 0x04 + +#define RPL_ROUTE_IS_NOPATH_RECEIVED(route) \ + (((route)->state.state_flags & RPL_ROUTE_ENTRY_NOPATH_RECEIVED) != 0) +#define RPL_ROUTE_SET_NOPATH_RECEIVED(route) do { \ + (route)->state.state_flags |= RPL_ROUTE_ENTRY_NOPATH_RECEIVED; \ + } while(0) +#define RPL_ROUTE_CLEAR_NOPATH_RECEIVED(route) do { \ + (route)->state.state_flags &= ~RPL_ROUTE_ENTRY_NOPATH_RECEIVED; \ + } while(0) + +#define RPL_ROUTE_IS_DAO_PENDING(route) \ + ((route->state.state_flags & RPL_ROUTE_ENTRY_DAO_PENDING) != 0) +#define RPL_ROUTE_SET_DAO_PENDING(route) do { \ + (route)->state.state_flags |= RPL_ROUTE_ENTRY_DAO_PENDING; \ + } while(0) +#define RPL_ROUTE_CLEAR_DAO_PENDING(route) do { \ + (route)->state.state_flags &= ~RPL_ROUTE_ENTRY_DAO_PENDING; \ + } while(0) + +#define RPL_ROUTE_IS_DAO_NACKED(route) \ + ((route->state.state_flags & RPL_ROUTE_ENTRY_DAO_NACK) != 0) +#define RPL_ROUTE_SET_DAO_NACKED(route) do { \ + (route)->state.state_flags |= RPL_ROUTE_ENTRY_DAO_NACK; \ + } while(0) +#define RPL_ROUTE_CLEAR_DAO_NACKED(route) do { \ + (route)->state.state_flags &= ~RPL_ROUTE_ENTRY_DAO_NACK; \ + } while(0) + +#define RPL_ROUTE_CLEAR_DAO(route) do { \ + (route)->state.state_flags &= ~(RPL_ROUTE_ENTRY_DAO_NACK|RPL_ROUTE_ENTRY_DAO_PENDING); \ + } while(0) + +struct rpl_dag; typedef struct rpl_route_entry { uint32_t lifetime; - void *dag; - uint8_t learned_from; - uint8_t nopath_received; + struct rpl_dag *dag; + uint8_t dao_seqno_out; + uint8_t dao_seqno_in; + uint8_t state_flags; } rpl_route_entry_t; #endif /* UIP_DS6_ROUTE_STATE_TYPE */ @@ -154,7 +203,8 @@ uip_ipaddr_t *uip_ds6_route_nexthop(uip_ds6_route_t *); int uip_ds6_route_num_routes(void); uip_ds6_route_t *uip_ds6_route_head(void); uip_ds6_route_t *uip_ds6_route_next(uip_ds6_route_t *); - +int uip_ds6_route_is_nexthop(const uip_ipaddr_t *ipaddr); /** @} */ #endif /* UIP_DS6_ROUTE_H */ +/** @} */ diff --git a/core/net/ipv6/uip-ds6.c b/core/net/ipv6/uip-ds6.c index 4a191caf9..9b690ab8c 100644 --- a/core/net/ipv6/uip-ds6.c +++ b/core/net/ipv6/uip-ds6.c @@ -1,16 +1,3 @@ -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * IPv6 data structures handling functions. - * Comprises part of the Neighbor discovery (RFC 4861) - * and auto configuration (RFC 4862) state machines. - * \author Mathilde Durvy - * \author Julien Abeille - */ /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -40,36 +27,50 @@ * SUCH DAMAGE. * */ + +/** + * \addtogroup uip6 + * @{ + */ + +/** + * \file + * IPv6 data structure manipulation. + * Comprises part of the Neighbor discovery (RFC 4861) + * and auto configuration (RFC 4862) state machines. + * \author Mathilde Durvy + * \author Julien Abeille + */ + #include #include #include #include "lib/random.h" #include "net/ipv6/uip-nd6.h" #include "net/ipv6/uip-ds6.h" +#include "net/ipv6/multicast/uip-mcast6.h" #include "net/ip/uip-packetqueue.h" -#if UIP_CONF_IPV6 - #define DEBUG DEBUG_NONE #include "net/ip/uip-debug.h" -struct etimer uip_ds6_timer_periodic; /** \brief Timer for maintenance of data structures */ +struct etimer uip_ds6_timer_periodic; /**< Timer for maintenance of data structures */ #if UIP_CONF_ROUTER -struct stimer uip_ds6_timer_ra; /** \brief RA timer, to schedule RA sending */ +struct stimer uip_ds6_timer_ra; /**< RA timer, to schedule RA sending */ #if UIP_ND6_SEND_RA -static uint8_t racount; /** \brief number of RA already sent */ -static uint16_t rand_time; /** \brief random time value for timers */ +static uint8_t racount; /**< number of RA already sent */ +static uint16_t rand_time; /**< random time value for timers */ #endif #else /* UIP_CONF_ROUTER */ -struct etimer uip_ds6_timer_rs; /** \brief RS timer, to schedule RS sending */ -static uint8_t rscount; /** \brief number of rs already sent */ +struct etimer uip_ds6_timer_rs; /**< RS timer, to schedule RS sending */ +static uint8_t rscount; /**< number of rs already sent */ #endif /* UIP_CONF_ROUTER */ /** \name "DS6" Data structures */ /** @{ */ -uip_ds6_netif_t uip_ds6_if; /** \brief The single interface */ -uip_ds6_prefix_t uip_ds6_prefix_list[UIP_DS6_PREFIX_NB]; /** \brief Prefix list */ +uip_ds6_netif_t uip_ds6_if; /**< The single interface */ +uip_ds6_prefix_t uip_ds6_prefix_list[UIP_DS6_PREFIX_NB]; /**< Prefix list */ /* Used by Cooja to enable extraction of addresses from memory.*/ uint8_t uip_ds6_addr_size; @@ -83,7 +84,9 @@ static uip_ipaddr_t loc_fipaddr; /* Pointers used in this file */ static uip_ds6_addr_t *locaddr; static uip_ds6_maddr_t *locmaddr; +#if UIP_DS6_AADDR_NB static uip_ds6_aaddr_t *locaaddr; +#endif /* UIP_DS6_AADDR_NB */ static uip_ds6_prefix_t *locprefix; /*---------------------------------------------------------------------------*/ @@ -184,14 +187,16 @@ uip_ds6_periodic(void) } #endif /* !UIP_CONF_ROUTER */ +#if UIP_ND6_SEND_NA uip_ds6_neighbor_periodic(); +#endif /* UIP_ND6_SEND_RA */ -#if UIP_CONF_ROUTER & UIP_ND6_SEND_RA +#if UIP_CONF_ROUTER && UIP_ND6_SEND_RA /* Periodic RA sending */ if(stimer_expired(&uip_ds6_timer_ra) && (uip_len == 0)) { uip_ds6_send_ra_periodic(); } -#endif /* UIP_CONF_ROUTER & UIP_ND6_SEND_RA */ +#endif /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */ etimer_reset(&uip_ds6_timer_periodic); return; } @@ -274,7 +279,8 @@ uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen, } PRINTF("Adding prefix "); PRINT6ADDR(&locprefix->ipaddr); - PRINTF("length %u, vlifetime%lu\n", ipaddrlen, interval); + PRINTF("length %u, vlifetime %lu\n", ipaddrlen, interval); + return locprefix; } return NULL; } @@ -294,9 +300,9 @@ uip_ds6_prefix_t * uip_ds6_prefix_lookup(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen) { if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_prefix_list, - UIP_DS6_PREFIX_NB, sizeof(uip_ds6_prefix_t), - ipaddr, ipaddrlen, - (uip_ds6_element_t **)&locprefix) == FOUND) { + UIP_DS6_PREFIX_NB, sizeof(uip_ds6_prefix_t), + ipaddr, ipaddrlen, + (uip_ds6_element_t **)&locprefix) == FOUND) { return locprefix; } return NULL; @@ -388,7 +394,7 @@ uip_ds6_get_link_local(int8_t state) for(locaddr = uip_ds6_if.addr_list; locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { if(locaddr->isused && (state == -1 || locaddr->state == state) - && (uip_is_addr_link_local(&locaddr->ipaddr))) { + && (uip_is_addr_linklocal(&locaddr->ipaddr))) { return locaddr; } } @@ -407,7 +413,7 @@ uip_ds6_get_global(int8_t state) for(locaddr = uip_ds6_if.addr_list; locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { if(locaddr->isused && (state == -1 || locaddr->state == state) - && !(uip_is_addr_link_local(&locaddr->ipaddr))) { + && !(uip_is_addr_linklocal(&locaddr->ipaddr))) { return locaddr; } } @@ -457,6 +463,7 @@ uip_ds6_maddr_lookup(const uip_ipaddr_t *ipaddr) uip_ds6_aaddr_t * uip_ds6_aaddr_add(uip_ipaddr_t *ipaddr) { +#if UIP_DS6_AADDR_NB if(uip_ds6_list_loop ((uip_ds6_element_t *)uip_ds6_if.aaddr_list, UIP_DS6_AADDR_NB, sizeof(uip_ds6_aaddr_t), ipaddr, 128, @@ -465,6 +472,7 @@ uip_ds6_aaddr_add(uip_ipaddr_t *ipaddr) uip_ipaddr_copy(&locaaddr->ipaddr, ipaddr); return locaaddr; } +#endif /* UIP_DS6_AADDR_NB */ return NULL; } @@ -482,11 +490,13 @@ uip_ds6_aaddr_rm(uip_ds6_aaddr_t *aaddr) uip_ds6_aaddr_t * uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr) { +#if UIP_DS6_AADDR_NB if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_if.aaddr_list, - UIP_DS6_AADDR_NB, sizeof(uip_ds6_aaddr_t), ipaddr, 128, - (uip_ds6_element_t **)&locaaddr) == FOUND) { + UIP_DS6_AADDR_NB, sizeof(uip_ds6_aaddr_t), ipaddr, 128, + (uip_ds6_element_t **)&locaaddr) == FOUND) { return locaaddr; } +#endif /* UIP_DS6_AADDR_NB */ return NULL; } @@ -498,13 +508,13 @@ uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst) uint8_t n = 0; uip_ds6_addr_t *matchaddr = NULL; - if(!uip_is_addr_link_local(dst) && !uip_is_addr_mcast(dst)) { + if(!uip_is_addr_linklocal(dst) && !uip_is_addr_mcast(dst)) { /* find longest match */ for(locaddr = uip_ds6_if.addr_list; locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { /* Only preferred global (not link-local) addresses */ if(locaddr->isused && locaddr->state == ADDR_PREFERRED && - !uip_is_addr_link_local(&locaddr->ipaddr)) { + !uip_is_addr_linklocal(&locaddr->ipaddr)) { n = get_match_length(dst, &locaddr->ipaddr); if(n >= best) { best = n; @@ -591,7 +601,7 @@ uip_ds6_dad(uip_ds6_addr_t *addr) * If we arrive here it means DAD succeeded, otherwise the dad process * would have been interrupted in ds6_dad_ns/na_input */ - PRINTF("DAD succeeded, ipaddr:"); + PRINTF("DAD succeeded, ipaddr: "); PRINT6ADDR(&addr->ipaddr); PRINTF("\n"); @@ -607,7 +617,7 @@ uip_ds6_dad(uip_ds6_addr_t *addr) int uip_ds6_dad_failed(uip_ds6_addr_t *addr) { - if(uip_is_addr_link_local(&addr->ipaddr)) { + if(uip_is_addr_linklocal(&addr->ipaddr)) { PRINTF("Contiki shutdown, DAD for link local address failed\n"); return 0; } @@ -702,6 +712,5 @@ uip_ds6_compute_reachable_time(void) UIP_ND6_MIN_RANDOM_FACTOR(uip_ds6_if.base_reachable_time)); } /*---------------------------------------------------------------------------*/ -#endif /* UIP_CONF_IPV6 */ /** @}*/ diff --git a/core/net/ipv6/uip-ds6.h b/core/net/ipv6/uip-ds6.h index 45ec3c7a0..294eb230c 100644 --- a/core/net/ipv6/uip-ds6.h +++ b/core/net/ipv6/uip-ds6.h @@ -5,7 +5,7 @@ /** * \file - * Network interface and stateless autoconfiguration (RFC 4862) + * Header file for IPv6-related data structures * \author Mathilde Durvy * \author Julien Abeille * @@ -67,6 +67,36 @@ #endif #define UIP_DS6_DEFRT_NB UIP_DS6_DEFRT_NBS + UIP_DS6_DEFRT_NBU +/* Default prefix */ +#ifdef UIP_CONF_DS6_DEFAULT_PREFIX +#define UIP_DS6_DEFAULT_PREFIX UIP_CONF_DS6_DEFAULT_PREFIX +#else +/* From RFC4193, section 3.1: + * | 7 bits |1| 40 bits | 16 bits | 64 bits | + * +--------+-+------------+-----------+----------------------------+ + * | Prefix |L| Global ID | Subnet ID | Interface ID | + * +--------+-+------------+-----------+----------------------------+ + * Prefix FC00::/7 prefix to identify Local IPv6 unicast + * addresses. + * L Set to 1 if the prefix is locally assigned. + * Set to 0 may be defined in the future. See + * Section 3.2 for additional information. + * Global ID 40-bit global identifier used to create a + * globally unique prefix. See Section 3.2 for + * additional information. + * + * We set prefix to 0xfc00 and set the local bit, resulting in 0xfd00. + * For high probability of network uniqueness, Global ID must be generated + * pseudo-randomly. As this is a hard-coded default prefix, we simply use + * a Global ID of 0. For real deployments, make sure to install a pseudo-random + * Global ID, e.g. in a RPL network, by configuring it at the root. + */ +#define UIP_DS6_DEFAULT_PREFIX 0xfd00 +#endif /* UIP_CONF_DS6_DEFAULT_PREFIX */ + +#define UIP_DS6_DEFAULT_PREFIX_0 ((UIP_DS6_DEFAULT_PREFIX >> 8) & 0xff) +#define UIP_DS6_DEFAULT_PREFIX_1 (UIP_DS6_DEFAULT_PREFIX & 0xff) + /* Prefix list */ #define UIP_DS6_PREFIX_NBS 1 #ifndef UIP_CONF_DS6_PREFIX_NBU @@ -131,7 +161,13 @@ #define ADDR_MANUAL 3 /** \brief General DS6 definitions */ -#define UIP_DS6_PERIOD (CLOCK_SECOND/10) /** Period for uip-ds6 periodic task*/ +/** Period for uip-ds6 periodic task*/ +#ifndef UIP_DS6_CONF_PERIOD +#define UIP_DS6_PERIOD (CLOCK_SECOND/10) +#else +#define UIP_DS6_PERIOD UIP_DS6_CONF_PERIOD +#endif + #define FOUND 0 #define FREESPACE 1 #define NOSPACE 2 @@ -210,9 +246,15 @@ typedef struct uip_ds6_netif { uint32_t reachable_time; /* in msec */ uint32_t retrans_timer; /* in msec */ uint8_t maxdadns; +#if UIP_DS6_ADDR_NB uip_ds6_addr_t addr_list[UIP_DS6_ADDR_NB]; +#endif /* UIP_DS6_ADDR_NB */ +#if UIP_DS6_AADDR_NB uip_ds6_aaddr_t aaddr_list[UIP_DS6_AADDR_NB]; +#endif /* UIP_DS6_AADDR_NB */ +#if UIP_DS6_MADDR_NB uip_ds6_maddr_t maddr_list[UIP_DS6_MADDR_NB]; +#endif /* UIP_DS6_MADDR_NB */ } uip_ds6_netif_t; /** \brief Generic type for a DS6, to use a common loop though all DS */ @@ -270,6 +312,7 @@ uint8_t uip_ds6_is_addr_onlink(uip_ipaddr_t *ipaddr); /** \name Unicast address list basic routines */ /** @{ */ +/** \brief Add a unicast address to the interface */ uip_ds6_addr_t *uip_ds6_addr_add(uip_ipaddr_t *ipaddr, unsigned long vlifetime, uint8_t type); void uip_ds6_addr_rm(uip_ds6_addr_t *addr); diff --git a/core/net/ipv6/uip-icmp6.c b/core/net/ipv6/uip-icmp6.c index 05fe8c9c6..d246a4d58 100644 --- a/core/net/ipv6/uip-icmp6.c +++ b/core/net/ipv6/uip-icmp6.c @@ -1,15 +1,3 @@ -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * ICMPv6 echo request and error messages (RFC 4443) - * \author Julien Abeille - * \author Mathilde Durvy - */ - /* * Copyright (c) 2001-2003, Adam Dunkels. * All rights reserved. @@ -42,6 +30,18 @@ * */ +/** + * \addtogroup uip6 + * @{ + */ + +/** + * \file + * ICMPv6 (RFC 4443) implementation, with message and error handling + * \author Julien Abeille + * \author Mathilde Durvy + */ + #include #include "net/ipv6/uip-ds6.h" #include "net/ipv6/uip-icmp6.h" @@ -68,8 +68,6 @@ #include "rpl/rpl.h" #endif /* UIP_CONF_IPV6_RPL */ -#if UIP_CONF_IPV6 - /** \brief temporary IP address */ static uip_ipaddr_t tmp_ipaddr; @@ -122,17 +120,14 @@ uip_icmp6_register_input_handler(uip_icmp6_input_handler_t *handler) static void echo_request_input(void) { -#if UIP_CONF_IPV6_RPL - uint8_t temp_ext_len; -#endif /* UIP_CONF_IPV6_RPL */ /* * we send an echo reply. It is trivial if there was no extension * headers in the request otherwise we need to remove the extension * headers and change a few fields */ - PRINTF("Received Echo Request from"); + PRINTF("Received Echo Request from "); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("to"); + PRINTF(" to "); PRINT6ADDR(&UIP_IP_BUF->destipaddr); PRINTF("\n"); @@ -149,44 +144,27 @@ echo_request_input(void) } if(uip_ext_len > 0) { -#if UIP_CONF_IPV6_RPL - if((temp_ext_len = rpl_invert_header())) { - /* If there were other extension headers*/ - UIP_FIRST_EXT_BUF->next = UIP_PROTO_ICMP6; - if (uip_ext_len != temp_ext_len) { - uip_len -= (uip_ext_len - temp_ext_len); - UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); - UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); - /* move the echo request payload (starting after the icmp header) - * to the new location in the reply. - * The shift is equal to the length of the remaining extension headers present - * Note: UIP_ICMP_BUF still points to the echo request at this stage - */ - memmove((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN - (uip_ext_len - temp_ext_len), - (uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN, - (uip_len - UIP_IPH_LEN - temp_ext_len - UIP_ICMPH_LEN)); - } - uip_ext_len = temp_ext_len; - } else { -#endif /* UIP_CONF_IPV6_RPL */ - /* If there were extension headers*/ - UIP_IP_BUF->proto = UIP_PROTO_ICMP6; - uip_len -= uip_ext_len; - UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); - UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); - /* move the echo request payload (starting after the icmp header) - * to the new location in the reply. - * The shift is equal to the length of the extension headers present - * Note: UIP_ICMP_BUF still points to the echo request at this stage - */ - memmove((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN - uip_ext_len, - (uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN, - (uip_len - UIP_IPH_LEN - UIP_ICMPH_LEN)); - uip_ext_len = 0; -#if UIP_CONF_IPV6_RPL - } -#endif /* UIP_CONF_IPV6_RPL */ + /* Remove extension headers if any */ + UIP_IP_BUF->proto = UIP_PROTO_ICMP6; + uip_len -= uip_ext_len; + UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); + UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); + /* move the echo request payload (starting after the icmp header) + * to the new location in the reply. + * The shift is equal to the length of the extension headers present + * Note: UIP_ICMP_BUF still points to the echo request at this stage + */ + memmove((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN - uip_ext_len, + (uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN, + (uip_len - UIP_IPH_LEN - UIP_ICMPH_LEN)); + uip_ext_len = 0; } + + /* Insert RPL extension headers */ +#if UIP_CONF_IPV6_RPL + rpl_insert_header(); +#endif /* UIP_CONF_IPV6_RPL */ + /* Below is important for the correctness of UIP_ICMP_BUF and the * checksum */ @@ -197,9 +175,9 @@ echo_request_input(void) UIP_ICMP_BUF->icmpchksum = 0; UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); - PRINTF("Sending Echo Reply to"); + PRINTF("Sending Echo Reply to "); PRINT6ADDR(&UIP_IP_BUF->destipaddr); - PRINTF("from"); + PRINTF(" from "); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF("\n"); UIP_STAT(++uip_stat.icmp.sent); @@ -208,23 +186,22 @@ echo_request_input(void) /*---------------------------------------------------------------------------*/ void uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) { - - /* check if originating packet is not an ICMP error*/ - if (uip_ext_len) { - if(UIP_EXT_BUF->next == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type < 128){ - uip_len = 0; + /* check if originating packet is not an ICMP error */ + if(uip_ext_len) { + if(UIP_EXT_BUF->next == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type < 128) { + uip_clear_buf(); return; } } else { - if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type < 128){ - uip_len = 0; + if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type < 128) { + uip_clear_buf(); return; } } #if UIP_CONF_IPV6_RPL - uip_ext_len = rpl_invert_header(); -#else /* UIP_CONF_IPV6_RPL */ + rpl_remove_header(); +#else uip_ext_len = 0; #endif /* UIP_CONF_IPV6_RPL */ @@ -233,8 +210,9 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) { uip_len += UIP_IPICMPH_LEN + UIP_ICMP6_ERROR_LEN; - if(uip_len > UIP_LINK_MTU) + if(uip_len > UIP_LINK_MTU) { uip_len = UIP_LINK_MTU; + } memmove((uint8_t *)UIP_ICMP6_ERROR_BUF + uip_ext_len + UIP_ICMP6_ERROR_LEN, (void *)UIP_IP_BUF, uip_len - UIP_IPICMPH_LEN - uip_ext_len - UIP_ICMP6_ERROR_LEN); @@ -252,7 +230,7 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) { /* the source should not be unspecified nor multicast, the check for multicast is done in uip_process */ if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)){ - uip_len = 0; + uip_clear_buf(); return; } @@ -262,7 +240,7 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) { if(type == ICMP6_PARAM_PROB && code == ICMP6_PARAMPROB_OPTION){ uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &tmp_ipaddr); } else { - uip_len = 0; + uip_clear_buf(); return; } } else { @@ -282,11 +260,15 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) { UIP_ICMP_BUF->icmpchksum = 0; UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); +#if UIP_CONF_IPV6_RPL + rpl_insert_header(); +#endif /* UIP_CONF_IPV6_RPL */ + UIP_STAT(++uip_stat.icmp.sent); - PRINTF("Sending ICMPv6 ERROR message type %d code %d to", type, code); + PRINTF("Sending ICMPv6 ERROR message type %d code %d to ", type, code); PRINT6ADDR(&UIP_IP_BUF->destipaddr); - PRINTF("from"); + PRINTF(" from "); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF("\n"); return; @@ -315,6 +297,13 @@ uip_icmp6_send(const uip_ipaddr_t *dest, int type, int code, int payload_len) UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + payload_len; + + UIP_STAT(++uip_stat.icmp.sent); + UIP_STAT(++uip_stat.ip.sent); + +#if UIP_CONF_IPV6_RPL + rpl_insert_header(); +#endif /* UIP_CONF_IPV6_RPL */ tcpip_ipv6_output(); } /*---------------------------------------------------------------------------*/ @@ -323,53 +312,31 @@ echo_reply_input(void) { int ttl; uip_ipaddr_t sender; -#if UIP_CONF_IPV6_RPL - uint8_t temp_ext_len; -#endif /* UIP_CONF_IPV6_RPL */ + + PRINTF("Received Echo Reply from "); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF(" to "); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("\n"); uip_ipaddr_copy(&sender, &UIP_IP_BUF->srcipaddr); ttl = UIP_IP_BUF->ttl; if(uip_ext_len > 0) { -#if UIP_CONF_IPV6_RPL - if((temp_ext_len = rpl_invert_header())) { - /* If there were other extension headers*/ - UIP_FIRST_EXT_BUF->next = UIP_PROTO_ICMP6; - if (uip_ext_len != temp_ext_len) { - uip_len -= (uip_ext_len - temp_ext_len); - UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); - UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); - /* move the echo reply payload (starting after the icmp - * header) to the new location in the reply. The shift is - * equal to the length of the remaining extension headers - * present Note: UIP_ICMP_BUF still points to the echo reply - * at this stage - */ - memmove((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN - (uip_ext_len - temp_ext_len), - (uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN, - (uip_len - UIP_IPH_LEN - temp_ext_len - UIP_ICMPH_LEN)); - } - uip_ext_len = temp_ext_len; - uip_len -= uip_ext_len; - } else { -#endif /* UIP_CONF_IPV6_RPL */ - /* If there were extension headers*/ - UIP_IP_BUF->proto = UIP_PROTO_ICMP6; - uip_len -= uip_ext_len; - UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); - UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); - /* move the echo reply payload (starting after the icmp header) - * to the new location in the reply. The shift is equal to the - * length of the extension headers present Note: UIP_ICMP_BUF - * still points to the echo request at this stage - */ - memmove((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN - uip_ext_len, - (uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN, - (uip_len - UIP_IPH_LEN - UIP_ICMPH_LEN)); - uip_ext_len = 0; -#if UIP_CONF_IPV6_RPL - } -#endif /* UIP_CONF_IPV6_RPL */ + /* Remove extension headers if any */ + UIP_IP_BUF->proto = UIP_PROTO_ICMP6; + uip_len -= uip_ext_len; + UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); + UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); + /* move the echo reply payload (starting after the icmp header) + * to the new location in the reply. The shift is equal to the + * length of the extension headers present Note: UIP_ICMP_BUF + * still points to the echo request at this stage + */ + memmove((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN - uip_ext_len, + (uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN, + (uip_len - UIP_IPH_LEN - UIP_ICMPH_LEN)); + uip_ext_len = 0; } /* Call all registered applications to let them know an echo reply @@ -387,7 +354,7 @@ echo_reply_input(void) } } - uip_len = 0; + uip_clear_buf(); return; } /*---------------------------------------------------------------------------*/ @@ -421,4 +388,3 @@ uip_icmp6_init() } /*---------------------------------------------------------------------------*/ /** @} */ -#endif /* UIP_CONF_IPV6 */ diff --git a/core/net/ipv6/uip-icmp6.h b/core/net/ipv6/uip-icmp6.h index 53dfc2315..2fd1c8fbf 100644 --- a/core/net/ipv6/uip-icmp6.h +++ b/core/net/ipv6/uip-icmp6.h @@ -1,15 +1,3 @@ -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * ICMPv6 echo request and error messages (RFC 4443) - * \author Julien Abeille - * \author Mathilde Durvy - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +30,17 @@ * */ +/** + * \addtogroup uip6 + * @{ + */ + +/** + * \file + * Header file for ICMPv6 message and error handing (RFC 4443) + * \author Julien Abeille + * \author Mathilde Durvy + */ #ifndef ICMP6_H_ #define ICMP6_H_ @@ -70,6 +69,7 @@ #define ICMP6_PRIV_EXP_200 200 /**< Private Experimentation */ #define ICMP6_PRIV_EXP_201 201 /**< Private Experimentation */ #define ICMP6_ROLL_TM ICMP6_PRIV_EXP_200 /**< ROLL Trickle Multicast */ +#define ICMP6_ESMRF ICMP6_PRIV_EXP_201 /**< ESMRF Multicast */ /** @} */ @@ -113,7 +113,7 @@ typedef struct uip_icmp6_error{ * \brief Send an icmpv6 error message * \param type type of the error message * \param code of the error message - * \param type 32 bit parameter of the error message, semantic depends on error + * \param param 32 bit parameter of the error message, semantic depends on error */ void uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param); diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index f2e601fed..218507228 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -1,15 +1,3 @@ -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * Neighbor discovery (RFC 4861) - * \author Mathilde Durvy - * \author Julien Abeille - */ - /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. @@ -68,13 +56,25 @@ * */ +/** + * \addtogroup uip6 + * @{ + */ + +/** + * \file + * Neighbor discovery (RFC 4861) + * \author Mathilde Durvy + * \author Julien Abeille + */ + #include #include "net/ipv6/uip-icmp6.h" #include "net/ipv6/uip-nd6.h" #include "net/ipv6/uip-ds6.h" +#include "net/ip/uip-nameserver.h" #include "lib/random.h" -#if UIP_CONF_IPV6 /*------------------------------------------------------------------*/ #define DEBUG 0 #include "net/ip/uip-debug.h" @@ -93,7 +93,7 @@ void uip_log(char *msg); /** \name Pointers to the header structures. * All pointers except UIP_IP_BUF depend on uip_ext_len, which at * packet reception, is the total length of the extension headers. - * + * * The pointer to ND6 options header also depends on nd6_opt_offset, * which we set in each function. * @@ -113,21 +113,39 @@ void uip_log(char *msg); #define UIP_ND6_OPT_HDR_BUF ((uip_nd6_opt_hdr *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset]) #define UIP_ND6_OPT_PREFIX_BUF ((uip_nd6_opt_prefix_info *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset]) #define UIP_ND6_OPT_MTU_BUF ((uip_nd6_opt_mtu *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset]) +#define UIP_ND6_OPT_RDNSS_BUF ((uip_nd6_opt_dns *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset]) /** @} */ +#if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER static uint8_t nd6_opt_offset; /** Offset from the end of the icmpv6 header to the option in uip_buf*/ static uint8_t *nd6_opt_llao; /** Pointer to llao option in uip_buf */ +static uip_ds6_nbr_t *nbr; /** Pointer to a nbr cache entry*/ +static uip_ds6_defrt_t *defrt; /** Pointer to a router list entry */ +static uip_ds6_addr_t *addr; /** Pointer to an interface address */ +#endif /* UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER */ #if !UIP_CONF_ROUTER // TBD see if we move it to ra_input static uip_nd6_opt_prefix_info *nd6_opt_prefix_info; /** Pointer to prefix information option in uip_buf */ static uip_ipaddr_t ipaddr; +#endif +#if (!UIP_CONF_ROUTER || UIP_ND6_SEND_RA) static uip_ds6_prefix_t *prefix; /** Pointer to a prefix list entry */ #endif -static uip_ds6_nbr_t *nbr; /** Pointer to a nbr cache entry*/ -static uip_ds6_defrt_t *defrt; /** Pointer to a router list entry */ -static uip_ds6_addr_t *addr; /** Pointer to an interface address */ + +#if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER /*------------------------------------------------------------------*/ -/* create a llao */ +/* Copy link-layer address from LLAO option to a word-aligned uip_lladdr_t */ +static int +extract_lladdr_from_llao_aligned(uip_lladdr_t *dest) { + if(dest != NULL && nd6_opt_llao != NULL) { + memcpy(dest, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN); + return 1; + } + return 0; +} +#endif /* UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER */ +/*------------------------------------------------------------------*/ +/* create a llao */ static void create_llao(uint8_t *llao, uint8_t type) { llao[UIP_ND6_OPT_TYPE_OFFSET] = type; @@ -140,7 +158,7 @@ create_llao(uint8_t *llao, uint8_t type) { /*------------------------------------------------------------------*/ - +#if UIP_ND6_SEND_NA static void ns_input(void) { @@ -149,7 +167,7 @@ ns_input(void) PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF(" to "); PRINT6ADDR(&UIP_IP_BUF->destipaddr); - PRINTF(" with target address"); + PRINTF(" with target address "); PRINT6ADDR((uip_ipaddr_t *) (&UIP_ND6_NS_BUF->tgtipaddr)); PRINTF("\n"); UIP_STAT(++uip_stat.nd6.recv); @@ -183,17 +201,23 @@ ns_input(void) goto discard; } else { #endif /*UIP_CONF_IPV6_CHECKS */ + uip_lladdr_t lladdr_aligned; + extract_lladdr_from_llao_aligned(&lladdr_aligned); nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); if(nbr == NULL) { - uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, - (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - 0, NBR_STALE); + uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, + 0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL); } else { - uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); + const uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(nbr); + if(lladdr == NULL) { + goto discard; + } if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - lladdr, UIP_LLADDR_LEN) != 0) { - memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - UIP_LLADDR_LEN); + lladdr, UIP_LLADDR_LEN) != 0) { + if(nbr_table_update_lladdr((const linkaddr_t *)lladdr, (const linkaddr_t *)&lladdr_aligned, 1) == 0) { + /* failed to update the lladdr */ + goto discard; + } nbr->state = NBR_STALE; } else { if(nbr->state == NBR_INCOMPLETE) { @@ -317,10 +341,10 @@ create_na: return; discard: - uip_len = 0; + uip_clear_buf(); return; } - +#endif /* UIP_ND6_SEND_NA */ /*------------------------------------------------------------------*/ @@ -346,7 +370,7 @@ uip_nd6_ns_output(uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt) UIP_IP_BUF->len[0] = 0; /* length will not be more than 255 */ /* * check if we add a SLLAO option: for DAD, MUST NOT, for NUD, MAY - * (here yes), for Address resolution , MUST + * (here yes), for Address resolution , MUST */ if(!(uip_ds6_is_my_addr(tgt))) { if(src != NULL) { @@ -356,14 +380,14 @@ uip_nd6_ns_output(uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt) } if (uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) { PRINTF("Dropping NS due to no suitable source address\n"); - uip_len = 0; + uip_clear_buf(); return; } UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN; create_llao(&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_NS_LEN], - UIP_ND6_OPT_SLLAO); + UIP_ND6_OPT_SLLAO); uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN; @@ -377,15 +401,16 @@ uip_nd6_ns_output(uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt) UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); UIP_STAT(++uip_stat.nd6.sent); - PRINTF("Sending NS to"); + PRINTF("Sending NS to "); PRINT6ADDR(&UIP_IP_BUF->destipaddr); - PRINTF("from"); + PRINTF(" from "); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("with target address"); + PRINTF(" with target address "); PRINT6ADDR(tgt); PRINTF("\n"); return; } +#if UIP_ND6_SEND_NA /*------------------------------------------------------------------*/ /** * Neighbor Advertisement Processing @@ -411,19 +436,20 @@ na_input(void) uint8_t is_router; uint8_t is_solicited; uint8_t is_override; + uip_lladdr_t lladdr_aligned; - PRINTF("Received NA from"); + PRINTF("Received NA from "); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("to"); + PRINTF(" to "); PRINT6ADDR(&UIP_IP_BUF->destipaddr); - PRINTF("with target address"); + PRINTF(" with target address "); PRINT6ADDR((uip_ipaddr_t *) (&UIP_ND6_NA_BUF->tgtipaddr)); PRINTF("\n"); UIP_STAT(++uip_stat.nd6.recv); - /* + /* * booleans. the three last one are not 0 or 1 but 0 or 0x80, 0x40, 0x20 - * but it works. Be careful though, do not use tests such as is_router == 1 + * but it works. Be careful though, do not use tests such as is_router == 1 */ is_llchange = 0; is_router = ((UIP_ND6_NA_BUF->flagsreserved & UIP_ND6_NA_FLAG_ROUTER)); @@ -473,23 +499,29 @@ na_input(void) PRINTF("NA received is bad\n"); goto discard; } else { - uip_lladdr_t *lladdr; + const uip_lladdr_t *lladdr; nbr = uip_ds6_nbr_lookup(&UIP_ND6_NA_BUF->tgtipaddr); - lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); if(nbr == NULL) { goto discard; } - if(nd6_opt_llao != 0) { + lladdr = uip_ds6_nbr_get_ll(nbr); + if(lladdr == NULL) { + goto discard; + } + if(nd6_opt_llao != NULL) { is_llchange = - memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], (void *)lladdr, + memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], lladdr, UIP_LLADDR_LEN); } if(nbr->state == NBR_INCOMPLETE) { - if(nd6_opt_llao == NULL) { + if(nd6_opt_llao == NULL || !extract_lladdr_from_llao_aligned(&lladdr_aligned)) { goto discard; } - memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - UIP_LLADDR_LEN); + if(nbr_table_update_lladdr((const linkaddr_t *)lladdr, (const linkaddr_t *)&lladdr_aligned, 1) == 0) { + /* failed to update the lladdr */ + goto discard; + } + if(is_solicited) { nbr->state = NBR_REACHABLE; nbr->nscount = 0; @@ -501,27 +533,29 @@ na_input(void) nbr->state = NBR_STALE; } nbr->isrouter = is_router; - } else { + } else { /* NBR is not INCOMPLETE */ if(!is_override && is_llchange) { if(nbr->state == NBR_REACHABLE) { nbr->state = NBR_STALE; } goto discard; } else { - if(is_override || (!is_override && nd6_opt_llao != 0 && !is_llchange) - || nd6_opt_llao == 0) { - if(nd6_opt_llao != 0) { - memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - UIP_LLADDR_LEN); + /** + * If this is an cache override, or same lladdr, or no llao - + * do updates of nbr states. + */ + if(is_override || !is_llchange || nd6_opt_llao == NULL) { + if(nd6_opt_llao != NULL && is_llchange) { + if(!extract_lladdr_from_llao_aligned(&lladdr_aligned) || + nbr_table_update_lladdr((const linkaddr_t *) lladdr, (const linkaddr_t *) &lladdr_aligned, 1) == 0) { + /* failed to update the lladdr */ + goto discard; + } } if(is_solicited) { nbr->state = NBR_REACHABLE; /* reachable time is stored in ms */ stimer_set(&(nbr->reachable), uip_ds6_if.reachable_time / 1000); - } else { - if(nd6_opt_llao != 0 && is_llchange) { - nbr->state = NBR_STALE; - } } } } @@ -548,14 +582,14 @@ na_input(void) uip_packetqueue_free(&nbr->packethandle); return; } - + #endif /*UIP_CONF_IPV6_QUEUE_PKT */ discard: - uip_len = 0; + uip_clear_buf(); return; } - +#endif /* UIP_ND6_SEND_NA */ #if UIP_CONF_ROUTER #if UIP_ND6_SEND_RA @@ -564,9 +598,9 @@ static void rs_input(void) { - PRINTF("Received RS from"); + PRINTF("Received RS from "); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("to"); + PRINTF(" to "); PRINT6ADDR(&UIP_IP_BUF->destipaddr); PRINTF("\n"); UIP_STAT(++uip_stat.nd6.recv); @@ -574,7 +608,7 @@ rs_input(void) #if UIP_CONF_IPV6_CHECKS /* - * Check hop limit / icmp code + * Check hop limit / icmp code * target address must not be multicast * if the NA is solicited, dest must not be multicast */ @@ -614,18 +648,24 @@ rs_input(void) goto discard; } else { #endif /*UIP_CONF_IPV6_CHECKS */ + uip_lladdr_t lladdr_aligned; + extract_lladdr_from_llao_aligned(&lladdr_aligned); if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) { /* we need to add the neighbor */ - uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, - (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE); + uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, + 0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL); } else { /* If LL address changed, set neighbor state to stale */ + const uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(nbr); + if(lladdr == NULL) { + goto discard; + } if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - uip_ds6_nbr_get_ll(nbr), UIP_LLADDR_LEN) != 0) { + lladdr, UIP_LLADDR_LEN) != 0) { uip_ds6_nbr_t nbr_data = *nbr; uip_ds6_nbr_rm(nbr); - nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, - (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE); + nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, + 0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL); nbr->reachable = nbr_data.reachable; nbr->sendns = nbr_data.sendns; nbr->nscount = nbr_data.nscount; @@ -641,7 +681,7 @@ rs_input(void) uip_ds6_send_ra_sollicited(); discard: - uip_len = 0; + uip_clear_buf(); return; } @@ -682,7 +722,6 @@ uip_nd6_ra_output(uip_ipaddr_t * dest) nd6_opt_offset = UIP_ND6_RA_LEN; -#if !UIP_CONF_ROUTER /* Prefix list */ for(prefix = uip_ds6_prefix_list; prefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; prefix++) { @@ -699,7 +738,6 @@ uip_nd6_ra_output(uip_ipaddr_t * dest) uip_len += UIP_ND6_OPT_PREFIX_INFO_LEN; } } -#endif /* !UIP_CONF_ROUTER */ /* Source link-layer option */ create_llao((uint8_t *)UIP_ND6_OPT_HDR_BUF, UIP_ND6_OPT_SLLAO); @@ -716,6 +754,29 @@ uip_nd6_ra_output(uip_ipaddr_t * dest) uip_len += UIP_ND6_OPT_MTU_LEN; nd6_opt_offset += UIP_ND6_OPT_MTU_LEN; + +#if UIP_ND6_RA_RDNSS + if(uip_nameserver_count() > 0) { + uint8_t i = 0; + uip_ipaddr_t *ip = &UIP_ND6_OPT_RDNSS_BUF->ip; + uip_ipaddr_t *dns = NULL; + UIP_ND6_OPT_RDNSS_BUF->type = UIP_ND6_OPT_RDNSS; + UIP_ND6_OPT_RDNSS_BUF->reserved = 0; + UIP_ND6_OPT_RDNSS_BUF->lifetime = uip_nameserver_next_expiration(); + if(UIP_ND6_OPT_RDNSS_BUF->lifetime != UIP_NAMESERVER_INFINITE_LIFETIME) { + UIP_ND6_OPT_RDNSS_BUF->lifetime -= clock_seconds(); + } + while((dns = uip_nameserver_get(i)) != NULL) { + uip_ipaddr_copy(ip++, dns); + i++; + } + UIP_ND6_OPT_RDNSS_BUF->len = UIP_ND6_OPT_RDNSS_LEN + (i << 1); + PRINTF("%d nameservers reported\n", i); + uip_len += UIP_ND6_OPT_RDNSS_BUF->len << 3; + nd6_opt_offset += UIP_ND6_OPT_RDNSS_BUF->len << 3; + } +#endif /* UIP_ND6_RA_RDNSS */ + UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); @@ -724,9 +785,9 @@ uip_nd6_ra_output(uip_ipaddr_t * dest) UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); UIP_STAT(++uip_stat.nd6.sent); - PRINTF("Sending RA to"); + PRINTF("Sending RA to "); PRINT6ADDR(&UIP_IP_BUF->destipaddr); - PRINTF("from"); + PRINTF(" from "); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF("\n"); return; @@ -759,22 +820,22 @@ uip_nd6_rs_output(void) UIP_ICMPH_LEN + UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN; create_llao(&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_RS_LEN], - UIP_ND6_OPT_SLLAO); + UIP_ND6_OPT_SLLAO); } UIP_ICMP_BUF->icmpchksum = 0; UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); UIP_STAT(++uip_stat.nd6.sent); - PRINTF("Sendin RS to"); + PRINTF("Sendin RS to "); PRINT6ADDR(&UIP_IP_BUF->destipaddr); - PRINTF("from"); + PRINTF(" from "); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF("\n"); return; } /*---------------------------------------------------------------------------*/ -/* +/** * Process a Router Advertisement * * - Possible actions when receiving a RA: add router to router list, @@ -786,16 +847,18 @@ uip_nd6_rs_output(void) void ra_input(void) { - PRINTF("Received RA from"); + uip_lladdr_t lladdr_aligned; + + PRINTF("Received RA from "); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("to"); + PRINTF(" to "); PRINT6ADDR(&UIP_IP_BUF->destipaddr); PRINTF("\n"); UIP_STAT(++uip_stat.nd6.recv); #if UIP_CONF_IPV6_CHECKS if((UIP_IP_BUF->ttl != UIP_ND6_HOP_LIMIT) || - (!uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)) || + (!uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr)) || (UIP_ICMP_BUF->icode != 0)) { PRINTF("RA received is bad"); goto discard; @@ -830,19 +893,28 @@ ra_input(void) PRINTF("Processing SLLAO option in RA\n"); nd6_opt_llao = (uint8_t *) UIP_ND6_OPT_HDR_BUF; nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); + if(!extract_lladdr_from_llao_aligned(&lladdr_aligned)) { + /* failed to extract llao - discard packet */ + goto discard; + } if(nbr == NULL) { - nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, - (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - 1, NBR_STALE); + nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, + 1, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL); } else { + const uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(nbr); + if(lladdr == NULL) { + goto discard; + } if(nbr->state == NBR_INCOMPLETE) { nbr->state = NBR_STALE; } - uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(nbr); if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - lladdr, UIP_LLADDR_LEN) != 0) { - memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - UIP_LLADDR_LEN); + lladdr, UIP_LLADDR_LEN) != 0) { + /* change of link layer address */ + if(nbr_table_update_lladdr((const linkaddr_t *)lladdr, (const linkaddr_t *)&lladdr_aligned, 1) == 0) { + /* failed to update the lladdr */ + goto discard; + } nbr->state = NBR_STALE; } nbr->isrouter = 1; @@ -858,7 +930,7 @@ ra_input(void) nd6_opt_prefix_info = (uip_nd6_opt_prefix_info *) UIP_ND6_OPT_HDR_BUF; if((uip_ntohl(nd6_opt_prefix_info->validlt) >= uip_ntohl(nd6_opt_prefix_info->preferredlt)) - && (!uip_is_addr_link_local(&nd6_opt_prefix_info->prefix))) { + && (!uip_is_addr_linklocal(&nd6_opt_prefix_info->prefix))) { /* on-link flag related processing */ if(nd6_opt_prefix_info->flagsreserved1 & UIP_ND6_RA_FLAG_ONLINK) { prefix = @@ -885,9 +957,9 @@ ra_input(void) prefix->isinfinite = 1; break; default: - PRINTF("Updating timer of prefix"); + PRINTF("Updating timer of prefix "); PRINT6ADDR(&prefix->ipaddr); - PRINTF("new value %lu\n", uip_ntohl(nd6_opt_prefix_info->validlt)); + PRINTF(" new value %lu\n", uip_ntohl(nd6_opt_prefix_info->validlt)); stimer_set(&prefix->vlifetime, uip_ntohl(nd6_opt_prefix_info->validlt)); prefix->isinfinite = 0; @@ -900,7 +972,7 @@ ra_input(void) if((nd6_opt_prefix_info->flagsreserved1 & UIP_ND6_RA_FLAG_AUTONOMOUS) && (nd6_opt_prefix_info->validlt != 0) && (nd6_opt_prefix_info->preflen == UIP_DEFAULT_PREFIX_LEN)) { - + uip_ipaddr_copy(&ipaddr, &nd6_opt_prefix_info->prefix); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); addr = uip_ds6_addr_lookup(&ipaddr); @@ -910,9 +982,9 @@ ra_input(void) if((uip_ntohl(nd6_opt_prefix_info->validlt) > 2 * 60 * 60) || (uip_ntohl(nd6_opt_prefix_info->validlt) > stimer_remaining(&addr->vlifetime))) { - PRINTF("Updating timer of address"); + PRINTF("Updating timer of address "); PRINT6ADDR(&addr->ipaddr); - PRINTF("new value %lu\n", + PRINTF(" new value %lu\n", uip_ntohl(nd6_opt_prefix_info->validlt)); stimer_set(&addr->vlifetime, uip_ntohl(nd6_opt_prefix_info->validlt)); @@ -920,7 +992,7 @@ ra_input(void) stimer_set(&addr->vlifetime, 2 * 60 * 60); PRINTF("Updating timer of address "); PRINT6ADDR(&addr->ipaddr); - PRINTF("new value %lu\n", (unsigned long)(2 * 60 * 60)); + PRINTF(" new value %lu\n", (unsigned long)(2 * 60 * 60)); } addr->isinfinite = 0; } else { @@ -939,6 +1011,23 @@ ra_input(void) /* End of autonomous flag related processing */ } break; +#if UIP_ND6_RA_RDNSS + case UIP_ND6_OPT_RDNSS: + if(UIP_ND6_RA_BUF->flags_reserved & (UIP_ND6_O_FLAG << 6)) { + PRINTF("Processing RDNSS option\n"); + uint8_t naddr = (UIP_ND6_OPT_RDNSS_BUF->len - 1) / 2; + uip_ipaddr_t *ip = (uip_ipaddr_t *)(&UIP_ND6_OPT_RDNSS_BUF->ip); + PRINTF("got %d nameservers\n", naddr); + while(naddr-- > 0) { + PRINTF(" nameserver: "); + PRINT6ADDR(ip); + PRINTF(" lifetime: %lx\n", uip_ntohl(UIP_ND6_OPT_RDNSS_BUF->lifetime)); + uip_nameserver_update(ip, uip_ntohl(UIP_ND6_OPT_RDNSS_BUF->lifetime)); + ip++; + } + } + break; +#endif /* UIP_ND6_RA_RDNSS */ default: PRINTF("ND option not supported in RA"); break; @@ -984,7 +1073,7 @@ ra_input(void) #endif /*UIP_CONF_IPV6_QUEUE_PKT */ discard: - uip_len = 0; + uip_clear_buf(); return; } #endif /* !UIP_CONF_ROUTER */ @@ -1036,4 +1125,3 @@ uip_nd6_init() } /*---------------------------------------------------------------------------*/ /** @} */ -#endif /* UIP_CONF_IPV6 */ diff --git a/core/net/ipv6/uip-nd6.h b/core/net/ipv6/uip-nd6.h index b3ee3a1d5..559afe5f4 100644 --- a/core/net/ipv6/uip-nd6.h +++ b/core/net/ipv6/uip-nd6.h @@ -1,15 +1,3 @@ -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * Neighbor discovery (RFC 4861) - * \author Julien Abeille - * \author Mathilde Durvy - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +30,18 @@ * */ +/** + * \addtogroup uip6 + * @{ + */ + +/** + * \file + * Header file for IPv6 Neighbor discovery (RFC 4861) + * \author Julien Abeille + * \author Mathilde Durvy + */ + #ifndef UIP_ND6_H_ #define UIP_ND6_H_ @@ -59,9 +59,12 @@ /** \name RFC 4861 Host constant */ /** @{ */ +/** \brief Maximum router solicitation delay */ #define UIP_ND6_MAX_RTR_SOLICITATION_DELAY 1 +/** \brief Router solicitation interval */ #define UIP_ND6_RTR_SOLICITATION_INTERVAL 4 -#define UIP_ND6_MAX_RTR_SOLICITATIONS 3 +/** \brief Maximum router solicitations */ +#define UIP_ND6_MAX_RTR_SOLICITATIONS 3 /** @} */ /** \name RFC 4861 Router constants */ @@ -76,15 +79,27 @@ #else #define UIP_ND6_SEND_NA UIP_CONF_ND6_SEND_NA #endif +#ifndef UIP_CONF_ND6_MAX_RA_INTERVAL #define UIP_ND6_MAX_RA_INTERVAL 600 +#else +#define UIP_ND6_MAX_RA_INTERVAL UIP_CONF_ND6_MAX_RA_INTERVAL +#endif +#ifndef UIP_CONF_ND6_MIN_RA_INTERVAL #define UIP_ND6_MIN_RA_INTERVAL (UIP_ND6_MAX_RA_INTERVAL / 3) +#else +#define UIP_ND6_MIN_RA_INTERVAL UIP_CONF_ND6_MIN_RA_INTERVAL +#endif #define UIP_ND6_M_FLAG 0 -#define UIP_ND6_O_FLAG 0 +#define UIP_ND6_O_FLAG (UIP_ND6_RA_RDNSS || UIP_ND6_RA_DNSSL) #define UIP_ND6_ROUTER_LIFETIME 3 * UIP_ND6_MAX_RA_INTERVAL #define UIP_ND6_MAX_INITIAL_RA_INTERVAL 16 /*seconds*/ #define UIP_ND6_MAX_INITIAL_RAS 3 /*transmissions*/ +#ifndef UIP_CONF_ND6_MIN_DELAY_BETWEEN_RAS #define UIP_ND6_MIN_DELAY_BETWEEN_RAS 3 /*seconds*/ +#else +#define UIP_ND6_MIN_DELAY_BETWEEN_RAS UIP_CONF_ND6_MIN_DELAY_BETWEEN_RAS +#endif //#define UIP_ND6_MAX_RA_DELAY_TIME 0.5 /*seconds*/ #define UIP_ND6_MAX_RA_DELAY_TIME_MS 500 /*milli seconds*/ /** @} */ @@ -116,9 +131,9 @@ #endif #ifdef UIP_CONF_ND6_RETRANS_TIMER -#define UIP_ND6_RETRANS_TIMER UIP_CONF_ND6_RETRANS_TIMER +#define UIP_ND6_RETRANS_TIMER UIP_CONF_ND6_RETRANS_TIMER #else -#define UIP_ND6_RETRANS_TIMER 1000 +#define UIP_ND6_RETRANS_TIMER 1000 #endif #define UIP_ND6_DELAY_FIRST_PROBE_TIME 5 @@ -127,6 +142,23 @@ /** @} */ +/** \name RFC 6106 RA DNS Options Constants */ +/** @{ */ +#ifndef UIP_CONF_ND6_RA_RDNSS +#define UIP_ND6_RA_RDNSS 0 +#else +#define UIP_ND6_RA_RDNSS UIP_CONF_ND6_RA_RDNSS +#endif + +#ifndef UIP_CONF_ND6_RA_DNSSL +#define UIP_ND6_RA_DNSSL 0 +#else +#error Not implemented +#define UIP_ND6_RA_DNSSL UIP_CONF_ND6_RA_DNSSL +#endif +/** @} */ + + /** \name ND6 option types */ /** @{ */ #define UIP_ND6_OPT_SLLAO 1 @@ -134,6 +166,8 @@ #define UIP_ND6_OPT_PREFIX_INFO 3 #define UIP_ND6_OPT_REDIRECTED_HDR 4 #define UIP_ND6_OPT_MTU 5 +#define UIP_ND6_OPT_RDNSS 25 +#define UIP_ND6_OPT_DNSSL 31 /** @} */ /** \name ND6 option types */ @@ -156,6 +190,8 @@ #define UIP_ND6_OPT_HDR_LEN 2 #define UIP_ND6_OPT_PREFIX_INFO_LEN 32 #define UIP_ND6_OPT_MTU_LEN 8 +#define UIP_ND6_OPT_RDNSS_LEN 1 +#define UIP_ND6_OPT_DNSSL_LEN 1 /* Length of TLLAO and SLLAO options, it is L2 dependant */ @@ -278,6 +314,15 @@ typedef struct uip_nd6_opt_mtu { uint32_t mtu; } uip_nd6_opt_mtu; +/** \brief ND option RDNSS */ +typedef struct uip_nd6_opt_dns { + uint8_t type; + uint8_t len; + uint16_t reserved; + uint32_t lifetime; + uip_ipaddr_t ip; +} uip_nd6_opt_dns; + /** \struct Redirected header option */ typedef struct uip_nd6_opt_redirected_hdr { uint8_t type; diff --git a/core/net/ipv6/uip6.c b/core/net/ipv6/uip6.c index 746b31ab2..94f4dfcf9 100644 --- a/core/net/ipv6/uip6.c +++ b/core/net/ipv6/uip6.c @@ -1,16 +1,3 @@ -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * The uIP TCP/IPv6 stack code. - * - * \author Adam Dunkels - * \author Julien Abeille (IPv6 related code) - * \author Mathilde Durvy (IPv6 related code) - */ /* * Copyright (c) 2001-2003, Adam Dunkels. * All rights reserved. @@ -44,6 +31,20 @@ * */ +/** + * \addtogroup uip6 + * @{ + */ + +/** + * \file + * The uIP TCP/IPv6 stack code. + * + * \author Adam Dunkels + * \author Julien Abeille (IPv6 related code) + * \author Mathilde Durvy (IPv6 related code) + */ + /* * uIP is a small implementation of the IP, UDP and TCP protocols (as * well as some basic ICMP stuff). The implementation couples the IP, @@ -70,6 +71,7 @@ * the packet back to the peer. */ +#include "sys/cc.h" #include "net/ip/uip.h" #include "net/ip/uipopt.h" #include "net/ipv6/uip-icmp6.h" @@ -77,9 +79,13 @@ #include "net/ipv6/uip-ds6.h" #include "net/ipv6/multicast/uip-mcast6.h" +#if UIP_CONF_IPV6_RPL +#include "rpl/rpl.h" +#include "rpl/rpl-private.h" +#endif + #include -#if UIP_CONF_IPV6 /*---------------------------------------------------------------------------*/ /* For Debug, logging, statistics */ /*---------------------------------------------------------------------------*/ @@ -87,10 +93,6 @@ #define DEBUG DEBUG_NONE #include "net/ip/uip-debug.h" -#if UIP_CONF_IPV6_RPL -#include "rpl/rpl.h" -#endif /* UIP_CONF_IPV6_RPL */ - #if UIP_LOGGING == 1 #include void uip_log(char *msg); @@ -102,10 +104,13 @@ void uip_log(char *msg); #if UIP_STATISTICS == 1 struct uip_stats uip_stat; #endif /* UIP_STATISTICS == 1 */ - + /*---------------------------------------------------------------------------*/ -/** @{ \name Layer 2 variables */ +/** + * \name Layer 2 variables + * @{ + */ /*---------------------------------------------------------------------------*/ /** Host L2 address */ #if UIP_CONF_LL_802154 @@ -116,7 +121,10 @@ uip_lladdr_t uip_lladdr = {{0x00,0x06,0x98,0x00,0x02,0x32}}; /** @} */ /*---------------------------------------------------------------------------*/ -/** @{ \name Layer 3 variables */ +/** + * \name Layer 3 variables + * @{ + */ /*---------------------------------------------------------------------------*/ /** * \brief Type of the next header in IPv6 header or extension headers @@ -141,8 +149,9 @@ uint8_t uip_ext_opt_offset = 0; /*---------------------------------------------------------------------------*/ /* Buffers */ /*---------------------------------------------------------------------------*/ -/** \name Buffer defines - * @{ +/** + * \name Buffer defines + * @{ */ #define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0]) #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) @@ -161,8 +170,9 @@ uint8_t uip_ext_opt_offset = 0; #endif /* UIP_CONF_IPV6_RPL */ #define UIP_ICMP6_ERROR_BUF ((struct uip_icmp6_error *)&uip_buf[uip_l2_l3_icmp_hdr_len]) /** @} */ -/** \name Buffer variables - * @{ +/** + * \name Buffer variables + * @{ */ /** Packet buffer for incoming and outgoing packets */ #ifndef UIP_CONF_EXTERNAL_BUFFER @@ -185,7 +195,10 @@ uint16_t uip_len, uip_slen; /** @} */ /*---------------------------------------------------------------------------*/ -/** @{ \name General variables */ +/** + * \name General variables + * @{ + */ /*---------------------------------------------------------------------------*/ /* The uip_flags variable is used for communication between the TCP/IP stack @@ -195,11 +208,6 @@ uint8_t uip_flags; /* uip_conn always points to the current connection (set to NULL for UDP). */ struct uip_conn *uip_conn; -/* Temporary variables. */ -#if (UIP_TCP || UIP_UDP) -static uint8_t c; -#endif - #if UIP_ACTIVE_OPEN || UIP_UDP /* Keeps track of the last port used for a new connection. */ static uint16_t lastport; @@ -209,7 +217,8 @@ static uint16_t lastport; /*---------------------------------------------------------------------------*/ /* TCP */ /*---------------------------------------------------------------------------*/ -/** \name TCP defines +/** + * \name TCP defines *@{ */ /* Structures and definitions. */ @@ -227,7 +236,8 @@ static uint16_t lastport; #define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */ /** @} */ -/** \name TCP variables +/** + * \name TCP variables *@{ */ #if UIP_TCP @@ -242,13 +252,14 @@ static uint8_t iss[4]; /* Temporary variables. */ uint8_t uip_acc32[4]; -static uint8_t opt; -static uint16_t tmp16; #endif /* UIP_TCP */ /** @} */ /*---------------------------------------------------------------------------*/ -/** @{ \name UDP variables */ +/** + * \name UDP variables + * @{ + */ /*---------------------------------------------------------------------------*/ #if UIP_UDP struct uip_udp_conn *uip_udp_conn; @@ -257,7 +268,10 @@ struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; /** @} */ /*---------------------------------------------------------------------------*/ -/** @{ \name ICMPv6 variables */ +/** + * \name ICMPv6 variables + * @{ + */ /*---------------------------------------------------------------------------*/ #if UIP_CONF_ICMP6 /** single possible icmpv6 "connection" */ @@ -268,7 +282,10 @@ struct uip_icmp6_conn uip_icmp6_conns; /*---------------------------------------------------------------------------*/ /* Functions */ /*---------------------------------------------------------------------------*/ -#if (!UIP_ARCH_ADD32 && UIP_TCP) +#if UIP_TCP +#if UIP_ARCH_ADD32 +void uip_add32(uint8_t *op32, uint16_t op16); +#else /* UIP_ARCH_ADD32 */ void uip_add32(uint8_t *op32, uint16_t op16) { @@ -276,15 +293,15 @@ uip_add32(uint8_t *op32, uint16_t op16) uip_acc32[2] = op32[2] + (op16 >> 8); uip_acc32[1] = op32[1]; uip_acc32[0] = op32[0]; - + if(uip_acc32[2] < (op16 >> 8)) { ++uip_acc32[1]; if(uip_acc32[1] == 0) { ++uip_acc32[0]; } } - - + + if(uip_acc32[3] < (op16 & 0xff)) { ++uip_acc32[2]; if(uip_acc32[2] == 0) { @@ -295,8 +312,8 @@ uip_add32(uint8_t *op32, uint16_t op16) } } } - -#endif /* UIP_ARCH_ADD32 && UIP_TCP */ +#endif /* UIP_ARCH_ADD32 */ +#endif /* UIP_TCP */ #if ! UIP_ARCH_CHKSUM /*---------------------------------------------------------------------------*/ @@ -309,7 +326,7 @@ chksum(uint16_t sum, const uint8_t *data, uint16_t len) dataptr = data; last_byte = data + len - 1; - + while(dataptr < last_byte) { /* At least two more bytes */ t = (dataptr[0] << 8) + dataptr[1]; sum += t; @@ -318,7 +335,7 @@ chksum(uint16_t sum, const uint8_t *data, uint16_t len) } dataptr += 2; } - + if(dataptr == last_byte) { t = (dataptr[0] << 8) + 0; sum += t; @@ -363,11 +380,11 @@ upper_layer_chksum(uint8_t proto) */ volatile uint16_t upper_layer_len; uint16_t sum; - + upper_layer_len = (((uint16_t)(UIP_IP_BUF->len[0]) << 8) + UIP_IP_BUF->len[1] - uip_ext_len); - + PRINTF("Upper layer checksum len: %d from: %d\n", upper_layer_len, - UIP_IPH_LEN + UIP_LLH_LEN + uip_ext_len); + UIP_IPH_LEN + UIP_LLH_LEN + uip_ext_len); /* First sum pseudoheader. */ /* IP protocol and length fields. This addition cannot carry. */ @@ -378,7 +395,7 @@ upper_layer_chksum(uint8_t proto) /* Sum TCP header and data. */ sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN + uip_ext_len], upper_layer_len); - + return (sum == 0) ? 0xffff : uip_htons(sum); } /*---------------------------------------------------------------------------*/ @@ -386,7 +403,7 @@ uint16_t uip_icmp6chksum(void) { return upper_layer_chksum(UIP_PROTO_ICMP6); - + } /*---------------------------------------------------------------------------*/ #if UIP_TCP @@ -409,7 +426,8 @@ uip_udpchksum(void) void uip_init(void) { - + int c; + uip_ds6_init(); uip_icmp6_init(); uip_nd6_init(); @@ -433,19 +451,20 @@ uip_init(void) } #endif /* UIP_UDP */ -#if UIP_CONF_IPV6_MULTICAST +#if UIP_IPV6_MULTICAST UIP_MCAST6.init(); #endif } /*---------------------------------------------------------------------------*/ #if UIP_TCP && UIP_ACTIVE_OPEN struct uip_conn * -uip_connect(uip_ipaddr_t *ripaddr, uint16_t rport) +uip_connect(const uip_ipaddr_t *ripaddr, uint16_t rport) { register struct uip_conn *conn, *cconn; - + int c; + /* Find an unused local port. */ - again: + again: ++lastport; if(lastport >= 32000) { @@ -480,7 +499,7 @@ uip_connect(uip_ipaddr_t *ripaddr, uint16_t rport) if(conn == 0) { return 0; } - + conn->tcpstateflags = UIP_SYN_SENT; conn->snd_nxt[0] = iss[0]; @@ -494,7 +513,7 @@ uip_connect(uip_ipaddr_t *ripaddr, uint16_t rport) conn->rcv_nxt[3] = 0; conn->initialmss = conn->mss = UIP_TCP_MSS; - + conn->len = 1; /* TCP length of the SYN is one. */ conn->nrtx = 0; conn->timer = 1; /* Send the SYN next time around. */ @@ -504,7 +523,7 @@ uip_connect(uip_ipaddr_t *ripaddr, uint16_t rport) conn->lport = uip_htons(lastport); conn->rport = rport; uip_ipaddr_copy(&conn->ripaddr, ripaddr); - + return conn; } #endif /* UIP_TCP && UIP_ACTIVE_OPEN */ @@ -515,15 +534,14 @@ remove_ext_hdr(void) /* Remove ext header before TCP/UDP processing. */ if(uip_ext_len > 0) { PRINTF("Cutting ext-header before processing (extlen: %d, uiplen: %d)\n", - uip_ext_len, uip_len); + uip_ext_len, uip_len); if(uip_len < UIP_IPH_LEN + uip_ext_len) { PRINTF("ERROR: uip_len too short compared to ext len\n"); - uip_ext_len = 0; - uip_len = 0; + uip_clear_buf(); return; } memmove(((uint8_t *)UIP_TCP_BUF), (uint8_t *)UIP_TCP_BUF + uip_ext_len, - uip_len - UIP_IPH_LEN - uip_ext_len); + uip_len - UIP_IPH_LEN - uip_ext_len); uip_len -= uip_ext_len; @@ -538,16 +556,17 @@ remove_ext_hdr(void) struct uip_udp_conn * uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport) { + int c; register struct uip_udp_conn *conn; - + /* Find an unused local port. */ - again: + again: ++lastport; if(lastport >= 32000) { lastport = 4096; } - + for(c = 0; c < UIP_UDP_CONNS; ++c) { if(uip_udp_conns[c].lport == uip_htons(lastport)) { goto again; @@ -565,7 +584,7 @@ uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport) if(conn == 0) { return 0; } - + conn->lport = UIP_HTONS(lastport); conn->rport = rport; if(ripaddr == NULL) { @@ -574,7 +593,7 @@ uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport) uip_ipaddr_copy(&conn->ripaddr, ripaddr); } conn->ttl = uip_ds6_if.cur_hop_limit; - + return conn; } #endif /* UIP_UDP */ @@ -583,6 +602,7 @@ uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport) void uip_unlisten(uint16_t port) { + int c; for(c = 0; c < UIP_LISTENPORTS; ++c) { if(uip_listenports[c] == port) { uip_listenports[c] = 0; @@ -594,6 +614,7 @@ uip_unlisten(uint16_t port) void uip_listen(uint16_t port) { + int c; for(c = 0; c < UIP_LISTENPORTS; ++c) { if(uip_listenports[c] == 0) { uip_listenports[c] = port; @@ -632,7 +653,7 @@ static uint8_t uip_reassflags; */ -struct etimer uip_reass_timer; /* timer for reassembly */ +struct etimer uip_reass_timer; /**< Timer for reassembly */ uint8_t uip_reass_on; /* equal to 1 if we are currently reassembling a packet */ static uint32_t uip_id; /* For every packet that is to be fragmented, the source @@ -646,7 +667,7 @@ uip_reass(void) uint16_t offset=0; uint16_t len; uint16_t i; - + /* If ip_reasstmr is zero, no packet is present in the buffer */ /* We first write the unfragmentable part of IP header into the reassembly buffer. The reset the other reassembly variables. */ @@ -688,9 +709,9 @@ uip_reass(void) PRINTF("dest "); PRINT6ADDR(&FBUF->destipaddr); PRINTF("next %d\n", UIP_IP_BUF->proto); - + } - + /* If the offset or the offset + fragment length overflows the reassembly buffer, we discard the entire packet. */ if(offset > UIP_REASS_BUFSIZE || @@ -722,12 +743,12 @@ uip_reass(void) return uip_len; } } - + /* Copy the fragment into the reassembly buffer, at the right offset. */ memcpy((uint8_t *)FBUF + UIP_IPH_LEN + uip_ext_len + offset, (uint8_t *)UIP_FRAG_BUF + UIP_FRAGH_LEN, len); - + /* Update the bitmap. */ if(offset >> 6 == (offset + len) >> 6) { uip_reassbitmap[offset >> 6] |= @@ -738,18 +759,18 @@ uip_reass(void) bytes in the endpoints and fill the stuff inbetween with 0xff. */ uip_reassbitmap[offset >> 6] |= bitmap_bits[(offset >> 3) & 7]; - + for(i = (1 + (offset >> 6)); i < ((offset + len) >> 6); ++i) { uip_reassbitmap[i] = 0xff; } uip_reassbitmap[(offset + len) >> 6] |= ~bitmap_bits[((offset + len) >> 3) & 7]; } - + /* Finally, we check if we have a full packet in the buffer. We do this by checking if we have the last fragment and if all bits in the bitmap are set. */ - + if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) { /* Check all bytes up to and including all but the last byte in the bitmap. */ @@ -765,7 +786,7 @@ uip_reass(void) return 0; } - /* If we have come this far, we have a full packet in the + /* If we have come this far, we have a full packet in the buffer, so we copy it to uip_buf. We also reset the timer. */ uip_reass_on = 0; etimer_stop(&uip_reass_timer); @@ -776,9 +797,9 @@ uip_reass(void) UIP_IP_BUF->len[1] = ((uip_reasslen - UIP_IPH_LEN) & 0xff); PRINTF("REASSEMBLED PAQUET %d (%d)\n", uip_reasslen, (UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]); - + return uip_reasslen; - + } } else { PRINTF("Already reassembling another paquet\n"); @@ -789,7 +810,7 @@ uip_reass(void) void uip_reass_over(void) { - /* to late, we abandon the reassembly of the packet */ + /* to late, we abandon the reassembly of the packet */ uip_reass_on = 0; etimer_stop(&uip_reass_timer); @@ -805,12 +826,11 @@ uip_reass_over(void) * any RFC, we decided not to include it as it reduces the size of * the packet. */ - uip_len = 0; - uip_ext_len = 0; + uip_clear_buf(); memcpy(UIP_IP_BUF, FBUF, UIP_IPH_LEN); /* copy the header for src and dest address*/ uip_icmp6_error_output(ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_REASSEMBLY, 0); - + UIP_STAT(++uip_stat.ip.sent); uip_flags = 0; } @@ -838,77 +858,77 @@ uip_add_rcv_nxt(uint16_t n) static uint8_t ext_hdr_options_process(void) { - /* - * Length field in the extension header: length of the header in units of - * 8 bytes, excluding the first 8 bytes - * length field in an option : the length of data in the option - */ + /* + * Length field in the extension header: length of the header in units of + * 8 bytes, excluding the first 8 bytes + * length field in an option : the length of data in the option + */ uip_ext_opt_offset = 2; while(uip_ext_opt_offset < ((UIP_EXT_BUF->len << 3) + 8)) { switch(UIP_EXT_HDR_OPT_BUF->type) { - /* - * for now we do not support any options except padding ones - * PAD1 does not make sense as the header must be 8bytes aligned, - * hence we can only have + /* + * for now we do not support any options except padding ones + * PAD1 does not make sense as the header must be 8bytes aligned, + * hence we can only have + */ + case UIP_EXT_HDR_OPT_PAD1: + PRINTF("Processing PAD1 option\n"); + uip_ext_opt_offset += 1; + break; + case UIP_EXT_HDR_OPT_PADN: + PRINTF("Processing PADN option\n"); + uip_ext_opt_offset += UIP_EXT_HDR_OPT_PADN_BUF->opt_len + 2; + break; + case UIP_EXT_HDR_OPT_RPL: + /* Fixes situation when a node that is not using RPL + * joins a network which does. The received packages will include the + * RPL header and processed by the "default" case of the switch + * (0x63 & 0xC0 = 0x40). Hence, the packet is discarded as the header + * is considered invalid. + * Using this fix, the header is ignored, and the next header (if + * present) is processed. */ - case UIP_EXT_HDR_OPT_PAD1: - PRINTF("Processing PAD1 option\n"); - uip_ext_opt_offset += 1; - break; - case UIP_EXT_HDR_OPT_PADN: - PRINTF("Processing PADN option\n"); - uip_ext_opt_offset += UIP_EXT_HDR_OPT_PADN_BUF->opt_len + 2; - break; - case UIP_EXT_HDR_OPT_RPL: - /* Fixes situation when a node that is not using RPL - * joins a network which does. The received packages will include the - * RPL header and processed by the "default" case of the switch - * (0x63 & 0xC0 = 0x40). Hence, the packet is discarded as the header - * is considered invalid. - * Using this fix, the header is ignored, and the next header (if - * present) is processed. - */ #if UIP_CONF_IPV6_RPL - PRINTF("Processing RPL option\n"); - if(rpl_verify_header(uip_ext_opt_offset)) { - PRINTF("RPL Option Error: Dropping Packet\n"); + PRINTF("Processing RPL option\n"); + if(rpl_verify_hbh_header(uip_ext_opt_offset)) { + PRINTF("RPL Option Error: Dropping Packet\n"); + return 1; + } +#endif /* UIP_CONF_IPV6_RPL */ + uip_ext_opt_offset += (UIP_EXT_HDR_OPT_BUF->len) + 2; + return 0; + default: + /* + * check the two highest order bits of the option + * - 00 skip over this option and continue processing the header. + * - 01 discard the packet. + * - 10 discard the packet and, regardless of whether or not the + * packet's Destination Address was a multicast address, send an + * ICMP Parameter Problem, Code 2, message to the packet's + * Source Address, pointing to the unrecognized Option Type. + * - 11 discard the packet and, only if the packet's Destination + * Address was not a multicast address, send an ICMP Parameter + * Problem, Code 2, message to the packet's Source Address, + * pointing to the unrecognized Option Type. + */ + PRINTF("MSB %x\n", UIP_EXT_HDR_OPT_BUF->type); + switch(UIP_EXT_HDR_OPT_BUF->type & 0xC0) { + case 0: + break; + case 0x40: + return 1; + case 0xC0: + if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) { return 1; } -#endif /* UIP_CONF_IPV6_RPL */ - uip_ext_opt_offset += (UIP_EXT_HDR_OPT_BUF->len) + 2; - return 0; - default: - /* - * check the two highest order bits of the option - * - 00 skip over this option and continue processing the header. - * - 01 discard the packet. - * - 10 discard the packet and, regardless of whether or not the - * packet's Destination Address was a multicast address, send an - * ICMP Parameter Problem, Code 2, message to the packet's - * Source Address, pointing to the unrecognized Option Type. - * - 11 discard the packet and, only if the packet's Destination - * Address was not a multicast address, send an ICMP Parameter - * Problem, Code 2, message to the packet's Source Address, - * pointing to the unrecognized Option Type. - */ - PRINTF("MSB %x\n", UIP_EXT_HDR_OPT_BUF->type); - switch(UIP_EXT_HDR_OPT_BUF->type & 0xC0) { - case 0: - break; - case 0x40: - return 1; - case 0xC0: - if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) { - return 1; - } - case 0x80: - uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, - (uint32_t)UIP_IPH_LEN + uip_ext_len + uip_ext_opt_offset); - return 2; - } - /* in the cases were we did not discard, update ext_opt* */ - uip_ext_opt_offset += UIP_EXT_HDR_OPT_BUF->len + 2; - break; + case 0x80: + uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, + (uint32_t)UIP_IPH_LEN + uip_ext_len + uip_ext_opt_offset); + return 2; + } + /* in the cases were we did not discard, update ext_opt* */ + uip_ext_opt_offset += UIP_EXT_HDR_OPT_BUF->len + 2; + break; } } return 0; @@ -920,6 +940,9 @@ void uip_process(uint8_t flag) { #if UIP_TCP + int c; + uint16_t tmp16; + uint8_t opt; register struct uip_conn *uip_connr = uip_conn; #endif /* UIP_TCP */ #if UIP_UDP @@ -928,7 +951,7 @@ uip_process(uint8_t flag) } #endif /* UIP_UDP */ uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN]; - + /* Check if we were invoked because of a poll request for a particular connection. */ if(flag == UIP_POLL_REQUEST) { @@ -951,9 +974,9 @@ uip_process(uint8_t flag) } else if(flag == UIP_TIMER) { /* Reset the length variables. */ #if UIP_TCP - uip_len = 0; + uip_clear_buf(); uip_slen = 0; - + /* Increase the initial sequence number. */ if(++iss[3] == 0) { if(++iss[2] == 0) { @@ -962,7 +985,7 @@ uip_process(uint8_t flag) } } } - + /* * Check if the connection is in a state in which we simply wait * for the connection to time out. If so, we increase the @@ -988,7 +1011,7 @@ uip_process(uint8_t flag) uip_connr->tcpstateflags == UIP_SYN_RCVD) && uip_connr->nrtx == UIP_MAXSYNRTX)) { uip_connr->tcpstateflags = UIP_CLOSED; - + /* * We call UIP_APPCALL() with uip_flags set to * UIP_TIMEDOUT to inform the application that the @@ -996,18 +1019,18 @@ uip_process(uint8_t flag) */ uip_flags = UIP_TIMEDOUT; UIP_APPCALL(); - + /* We also send a reset packet to the remote host. */ UIP_TCP_BUF->flags = TCP_RST | TCP_ACK; goto tcp_send_nodata; } - + /* Exponential backoff. */ uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4? 4: uip_connr->nrtx); ++(uip_connr->nrtx); - + /* * Ok, so we need to retransmit. We do this differently * depending on which state we are in. In ESTABLISHED, we @@ -1018,33 +1041,33 @@ uip_process(uint8_t flag) */ UIP_STAT(++uip_stat.tcp.rexmit); switch(uip_connr->tcpstateflags & UIP_TS_MASK) { - case UIP_SYN_RCVD: - /* In the SYN_RCVD state, we should retransmit our SYNACK. */ - goto tcp_send_synack; - + case UIP_SYN_RCVD: + /* In the SYN_RCVD state, we should retransmit our SYNACK. */ + goto tcp_send_synack; + #if UIP_ACTIVE_OPEN - case UIP_SYN_SENT: - /* In the SYN_SENT state, we retransmit out SYN. */ - UIP_TCP_BUF->flags = 0; - goto tcp_send_syn; + case UIP_SYN_SENT: + /* In the SYN_SENT state, we retransmit out SYN. */ + UIP_TCP_BUF->flags = 0; + goto tcp_send_syn; #endif /* UIP_ACTIVE_OPEN */ - - case UIP_ESTABLISHED: - /* - * In the ESTABLISHED state, we call upon the application - * to do the actual retransmit after which we jump into - * the code for sending out the packet (the apprexmit - * label). - */ - uip_flags = UIP_REXMIT; - UIP_APPCALL(); - goto apprexmit; - - case UIP_FIN_WAIT_1: - case UIP_CLOSING: - case UIP_LAST_ACK: - /* In all these states we should retransmit a FINACK. */ - goto tcp_send_finack; + + case UIP_ESTABLISHED: + /* + * In the ESTABLISHED state, we call upon the application + * to do the actual retransmit after which we jump into + * the code for sending out the packet (the apprexmit + * label). + */ + uip_flags = UIP_REXMIT; + UIP_APPCALL(); + goto apprexmit; + + case UIP_FIN_WAIT_1: + case UIP_CLOSING: + case UIP_LAST_ACK: + /* In all these states we should retransmit a FINACK. */ + goto tcp_send_finack; } } } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) { @@ -1075,12 +1098,12 @@ uip_process(uint8_t flag) } #endif /* UIP_UDP */ - + /* This is where the input processing starts. */ UIP_STAT(++uip_stat.ip.recv); - + /* Start of IP input header processing code. */ - + /* Check validity of the IP header. */ if((UIP_IP_BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */ UIP_STAT(++uip_stat.ip.drop); @@ -1096,7 +1119,7 @@ uip_process(uint8_t flag) * the packet has been padded and we set uip_len to the correct * value.. */ - + if((UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] <= uip_len) { uip_len = (UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] + UIP_IPH_LEN; /* @@ -1114,7 +1137,7 @@ uip_process(uint8_t flag) UIP_LOG("ip: packet shorter than reported in IP header."); goto drop; } - + PRINTF("IPv6 packet received from "); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF(" to "); @@ -1141,20 +1164,20 @@ uip_process(uint8_t flag) uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO; #endif /* UIP_CONF_IPV6_CHECKS */ switch(ext_hdr_options_process()) { - case 0: - /* continue */ - uip_next_hdr = &UIP_EXT_BUF->next; - uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; - break; - case 1: - PRINTF("Dropping packet after extension header processing\n"); - /* silently discard */ - goto drop; - case 2: - PRINTF("Sending error message after extension header processing\n"); - /* send icmp error message (created in ext_hdr_options_process) - * and discard*/ - goto send; + case 0: + /* continue */ + uip_next_hdr = &UIP_EXT_BUF->next; + uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; + break; + case 1: + PRINTF("Dropping packet after extension header processing\n"); + /* silently discard */ + goto drop; + case 2: + PRINTF("Sending error message after extension header processing\n"); + /* send icmp error message (created in ext_hdr_options_process) + * and discard*/ + goto send; } } @@ -1169,7 +1192,7 @@ uip_process(uint8_t flag) * All multicast engines must hook in here. After this function returns, we * expect UIP_BUF to be unmodified */ -#if UIP_CONF_IPV6_MULTICAST +#if UIP_IPV6_MULTICAST if(uip_is_addr_mcast_routable(&UIP_IP_BUF->destipaddr)) { if(UIP_MCAST6.in() == UIP_MCAST6_ACCEPT) { /* Deliver up the stack */ @@ -1179,14 +1202,14 @@ uip_process(uint8_t flag) goto drop; } } -#endif /* UIP_IPV6_CONF_MULTICAST */ +#endif /* UIP_IPV6_MULTICAST */ /* TBD Some Parameter problem messages */ if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) && !uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr)) { if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr) && - !uip_is_addr_link_local(&UIP_IP_BUF->destipaddr) && - !uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr) && + !uip_is_addr_linklocal(&UIP_IP_BUF->destipaddr) && + !uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr) && !uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr) && !uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) { @@ -1206,7 +1229,11 @@ uip_process(uint8_t flag) } #if UIP_CONF_IPV6_RPL - rpl_update_header_empty(); + if(!rpl_update_header()) { + /* Packet can not be forwarded */ + PRINTF("RPL header update error\n"); + goto drop; + } #endif /* UIP_CONF_IPV6_RPL */ UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1; @@ -1216,7 +1243,7 @@ uip_process(uint8_t flag) UIP_STAT(++uip_stat.ip.forwarded); goto send; } else { - if((uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)) && + if((uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr)) && (!uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) && (!uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) && (!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) && @@ -1249,51 +1276,51 @@ uip_process(uint8_t flag) uip_ext_bitmap = 0; #endif /* UIP_CONF_ROUTER */ -#if UIP_CONF_IPV6_MULTICAST +#if UIP_IPV6_MULTICAST process: #endif while(1) { switch(*uip_next_hdr){ #if UIP_TCP - case UIP_PROTO_TCP: - /* TCP, for both IPv4 and IPv6 */ - goto tcp_input; + case UIP_PROTO_TCP: + /* TCP, for both IPv4 and IPv6 */ + goto tcp_input; #endif /* UIP_TCP */ #if UIP_UDP - case UIP_PROTO_UDP: - /* UDP, for both IPv4 and IPv6 */ - goto udp_input; + case UIP_PROTO_UDP: + /* UDP, for both IPv4 and IPv6 */ + goto udp_input; #endif /* UIP_UDP */ - case UIP_PROTO_ICMP6: - /* ICMPv6 */ - goto icmp6_input; - case UIP_PROTO_HBHO: - PRINTF("Processing hbh header\n"); - /* Hop by hop option header */ + case UIP_PROTO_ICMP6: + /* ICMPv6 */ + goto icmp6_input; + case UIP_PROTO_HBHO: + PRINTF("Processing hbh header\n"); + /* Hop by hop option header */ #if UIP_CONF_IPV6_CHECKS - /* Hop by hop option header. If we saw one HBH already, drop */ - if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_HBHO) { - goto bad_hdr; - } else { - uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO; - } + /* Hop by hop option header. If we saw one HBH already, drop */ + if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_HBHO) { + goto bad_hdr; + } else { + uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO; + } #endif /*UIP_CONF_IPV6_CHECKS*/ - switch(ext_hdr_options_process()) { - case 0: - /*continue*/ - uip_next_hdr = &UIP_EXT_BUF->next; - uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; - break; - case 1: - /*silently discard*/ - goto drop; - case 2: - /* send icmp error message (created in ext_hdr_options_process) - * and discard*/ - goto send; - } + switch(ext_hdr_options_process()) { + case 0: + /*continue*/ + uip_next_hdr = &UIP_EXT_BUF->next; + uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; break; + case 1: + /*silently discard*/ + goto drop; + case 2: + /* send icmp error message (created in ext_hdr_options_process) + * and discard*/ + goto send; + } + break; case UIP_PROTO_DESTO: #if UIP_CONF_IPV6_CHECKS /* Destination option header. if we saw two already, drop */ @@ -1309,76 +1336,81 @@ uip_process(uint8_t flag) } #endif /*UIP_CONF_IPV6_CHECKS*/ switch(ext_hdr_options_process()) { - case 0: - /*continue*/ - uip_next_hdr = &UIP_EXT_BUF->next; - uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; - break; - case 1: - /*silently discard*/ - goto drop; - case 2: - /* send icmp error message (created in ext_hdr_options_process) - * and discard*/ - goto send; - } - break; - case UIP_PROTO_ROUTING: -#if UIP_CONF_IPV6_CHECKS - /* Routing header. If we saw one already, drop */ - if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_ROUTING) { - goto bad_hdr; - } else { - uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_ROUTING; - } -#endif /*UIP_CONF_IPV6_CHECKS*/ - /* - * Routing Header length field is in units of 8 bytes, excluding - * As per RFC2460 section 4.4, if routing type is unrecognized: - * if segments left = 0, ignore the header - * if segments left > 0, discard packet and send icmp error pointing - * to the routing type - */ - - PRINTF("Processing Routing header\n"); - if(UIP_ROUTING_BUF->seg_left > 0) { - uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, UIP_IPH_LEN + uip_ext_len + 2); - UIP_STAT(++uip_stat.ip.drop); - UIP_LOG("ip6: unrecognized routing type"); - goto send; - } - uip_next_hdr = &UIP_EXT_BUF->next; - uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; - break; - case UIP_PROTO_FRAG: - /* Fragmentation header:call the reassembly function, then leave */ -#if UIP_CONF_IPV6_REASSEMBLY - PRINTF("Processing frag header\n"); - uip_len = uip_reass(); - if(uip_len == 0) { + case 0: + /*continue*/ + uip_next_hdr = &UIP_EXT_BUF->next; + uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; + break; + case 1: + /*silently discard*/ goto drop; - } - if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG){ - /* we are not done with reassembly, this is an error message */ + case 2: + /* send icmp error message (created in ext_hdr_options_process) + * and discard*/ goto send; } - /*packet is reassembled, reset the next hdr to the beginning - of the IP header and restart the parsing of the reassembled pkt*/ - PRINTF("Processing reassembled packet\n"); - uip_ext_len = 0; - uip_ext_bitmap = 0; - uip_next_hdr = &UIP_IP_BUF->proto; break; + case UIP_PROTO_ROUTING: +#if UIP_CONF_IPV6_CHECKS + /* Routing header. If we saw one already, drop */ + if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_ROUTING) { + goto bad_hdr; + } else { + uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_ROUTING; + } +#endif /*UIP_CONF_IPV6_CHECKS*/ + /* + * Routing Header length field is in units of 8 bytes, excluding + * As per RFC2460 section 4.4, if routing type is unrecognized: + * if segments left = 0, ignore the header + * if segments left > 0, discard packet and send icmp error pointing + * to the routing type + */ + + PRINTF("Processing Routing header\n"); + if(UIP_ROUTING_BUF->seg_left > 0) { +#if UIP_CONF_IPV6_RPL && RPL_WITH_NON_STORING + if(rpl_process_srh_header()) { + goto send; /* Proceed to forwarding */ + } +#endif /* UIP_CONF_IPV6_RPL && RPL_WITH_NON_STORING */ + uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, UIP_IPH_LEN + uip_ext_len + 2); + UIP_STAT(++uip_stat.ip.drop); + UIP_LOG("ip6: unrecognized routing type"); + goto send; + } + uip_next_hdr = &UIP_EXT_BUF->next; + uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; + break; + case UIP_PROTO_FRAG: + /* Fragmentation header:call the reassembly function, then leave */ +#if UIP_CONF_IPV6_REASSEMBLY + PRINTF("Processing frag header\n"); + uip_len = uip_reass(); + if(uip_len == 0) { + goto drop; + } + if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG){ + /* we are not done with reassembly, this is an error message */ + goto send; + } + /*packet is reassembled, reset the next hdr to the beginning + of the IP header and restart the parsing of the reassembled pkt*/ + PRINTF("Processing reassembled packet\n"); + uip_ext_len = 0; + uip_ext_bitmap = 0; + uip_next_hdr = &UIP_IP_BUF->proto; + break; #else /* UIP_CONF_IPV6_REASSEMBLY */ - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.fragerr); - UIP_LOG("ip: fragment dropped."); - goto drop; + UIP_STAT(++uip_stat.ip.drop); + UIP_STAT(++uip_stat.ip.fragerr); + UIP_LOG("ip: fragment dropped."); + goto drop; #endif /* UIP_CONF_IPV6_REASSEMBLY */ - case UIP_PROTO_NONE: - goto drop; - default: - goto bad_hdr; + case UIP_PROTO_NONE: + goto drop; + default: + goto bad_hdr; } } bad_hdr: @@ -1392,7 +1424,7 @@ uip_process(uint8_t flag) UIP_LOG("ip6: unrecognized header"); goto send; /* End of headers processing */ - + icmp6_input: /* This is IPv6 ICMPv6 processing code. */ PRINTF("icmp6_input: length %d type: %d \n", uip_len, UIP_ICMP_BUF->type); @@ -1403,7 +1435,7 @@ uip_process(uint8_t flag) UIP_STAT(++uip_stat.icmp.drop); UIP_STAT(++uip_stat.icmp.chkerr); UIP_LOG("icmpv6: bad checksum."); - PRINTF("icmpv6: bad checksum."); + PRINTF("icmpv6: bad checksum.\n"); goto drop; } #endif /*UIP_CONF_IPV6_CHECKS*/ @@ -1432,32 +1464,31 @@ uip_process(uint8_t flag) UIP_STAT(++uip_stat.icmp.drop); UIP_STAT(++uip_stat.icmp.typeerr); UIP_LOG("icmp6: unknown ICMPv6 message."); - uip_len = 0; + uip_clear_buf(); } - + if(uip_len > 0) { goto send; } else { goto drop; } /* End of IPv6 ICMP processing. */ - + #if UIP_UDP /* UDP input processing. */ - udp_input: + udp_input: remove_ext_hdr(); + UIP_IP_BUF->proto = UIP_PROTO_UDP; PRINTF("Receiving UDP packet\n"); - + /* UDP processing is really just a hack. We don't do anything to the UDP/IP headers, but let the UDP application do all the hard work. If the application sets uip_slen, it has a packet to send. */ #if UIP_UDP_CHECKSUMS - uip_len = uip_len - UIP_IPUDPH_LEN; - uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN]; /* XXX hack: UDP/IPv6 receivers should drop packets with UDP checksum 0. Here, we explicitly receive UDP packets with checksum 0. This is to be able to debug code that for one reason or @@ -1470,8 +1501,6 @@ uip_process(uint8_t flag) uip_udpchksum()); goto drop; } -#else /* UIP_UDP_CHECKSUMS */ - uip_len = uip_len - UIP_IPUDPH_LEN; #endif /* UIP_UDP_CHECKSUMS */ /* Make sure that the UDP destination port number is not zero. */ @@ -1503,24 +1532,22 @@ uip_process(uint8_t flag) PRINTF("udp: no matching connection found\n"); UIP_STAT(++uip_stat.udp.drop); -#if UIP_UDP_SEND_UNREACH_NOPORT uip_icmp6_error_output(ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0); goto send; -#else - goto drop; -#endif - udp_found: + udp_found: PRINTF("In udp_found\n"); UIP_STAT(++uip_stat.udp.recv); - + + uip_len = uip_len - UIP_IPUDPH_LEN; + uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN]; uip_conn = NULL; uip_flags = UIP_NEWDATA; uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN]; uip_slen = 0; UIP_UDP_APPCALL(); - udp_send: + udp_send: PRINTF("In udp_send\n"); if(uip_slen == 0) { @@ -1547,10 +1574,6 @@ uip_process(uint8_t flag) uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN]; -#if UIP_CONF_IPV6_RPL - rpl_insert_header(); -#endif /* UIP_CONF_IPV6_RPL */ - #if UIP_UDP_CHECKSUMS /* Calculate UDP checksum. */ UIP_UDP_BUF->udpchksum = ~(uip_udpchksum()); @@ -1558,20 +1581,26 @@ uip_process(uint8_t flag) UIP_UDP_BUF->udpchksum = 0xffff; } #endif /* UIP_UDP_CHECKSUMS */ + +#if UIP_CONF_IPV6_RPL + rpl_insert_header(); +#endif /* UIP_CONF_IPV6_RPL */ + UIP_STAT(++uip_stat.udp.sent); goto ip_send_nolen; #endif /* UIP_UDP */ #if UIP_TCP /* TCP input processing. */ - tcp_input: + tcp_input: remove_ext_hdr(); + UIP_IP_BUF->proto = UIP_PROTO_TCP; UIP_STAT(++uip_stat.tcp.recv); PRINTF("Receiving TCP packet\n"); /* Start of TCP input header processing code. */ - + if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP checksum. */ UIP_STAT(++uip_stat.tcp.drop); @@ -1606,7 +1635,7 @@ uip_process(uint8_t flag) if((UIP_TCP_BUF->flags & TCP_CTL) != TCP_SYN) { goto reset; } - + tmp16 = UIP_TCP_BUF->destport; /* Next, check listening connections. */ for(c = 0; c < UIP_LISTENPORTS; ++c) { @@ -1614,11 +1643,11 @@ uip_process(uint8_t flag) goto found_listen; } } - + /* No matching connection found, so we send a RST packet. */ UIP_STAT(++uip_stat.tcp.synrst); - reset: + reset: PRINTF("In reset\n"); /* We do not send resets in response to resets. */ if(UIP_TCP_BUF->flags & TCP_RST) { @@ -1626,7 +1655,7 @@ uip_process(uint8_t flag) } UIP_STAT(++uip_stat.tcp.rst); - + UIP_TCP_BUF->flags = TCP_RST | TCP_ACK; uip_len = UIP_IPTCPH_LEN; UIP_TCP_BUF->tcpoffset = 5 << 4; @@ -1635,15 +1664,15 @@ uip_process(uint8_t flag) c = UIP_TCP_BUF->seqno[3]; UIP_TCP_BUF->seqno[3] = UIP_TCP_BUF->ackno[3]; UIP_TCP_BUF->ackno[3] = c; - + c = UIP_TCP_BUF->seqno[2]; UIP_TCP_BUF->seqno[2] = UIP_TCP_BUF->ackno[2]; UIP_TCP_BUF->ackno[2] = c; - + c = UIP_TCP_BUF->seqno[1]; UIP_TCP_BUF->seqno[1] = UIP_TCP_BUF->ackno[1]; UIP_TCP_BUF->ackno[1] = c; - + c = UIP_TCP_BUF->seqno[0]; UIP_TCP_BUF->seqno[0] = UIP_TCP_BUF->ackno[0]; UIP_TCP_BUF->ackno[0] = c; @@ -1658,12 +1687,12 @@ uip_process(uint8_t flag) } } } - + /* Swap port numbers. */ tmp16 = UIP_TCP_BUF->srcport; UIP_TCP_BUF->srcport = UIP_TCP_BUF->destport; UIP_TCP_BUF->destport = tmp16; - + /* Swap IP addresses. */ uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr); uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); @@ -1673,7 +1702,7 @@ uip_process(uint8_t flag) /* This label will be jumped to if we matched the incoming packet with a connection in LISTEN. In that case, we should create a new connection and send a SYNACK in return. */ - found_listen: + found_listen: PRINTF("In found listen\n"); /* First we check if there are any connections avaliable. Unused connections are kept in the same table as used connections, but @@ -1704,7 +1733,7 @@ uip_process(uint8_t flag) goto drop; } uip_conn = uip_connr; - + /* Fill in the necessary fields for the new connection. */ uip_connr->rto = uip_connr->timer = UIP_RTO; uip_connr->sa = 0; @@ -1722,10 +1751,10 @@ uip_process(uint8_t flag) uip_connr->len = 1; /* rcv_nxt should be the seqno from the incoming packet + 1. */ - uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3]; - uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2]; - uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1]; uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0]; + uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1]; + uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2]; + uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3]; uip_add_rcv_nxt(1); /* Parse the TCP MSS option, if present. */ @@ -1745,7 +1774,7 @@ uip_process(uint8_t flag) (uint16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c]; uip_connr->initialmss = uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; - + /* And we are done processing options. */ break; } else { @@ -1760,19 +1789,19 @@ uip_process(uint8_t flag) } } } - + /* Our response will be a SYNACK. */ #if UIP_ACTIVE_OPEN - tcp_send_synack: + tcp_send_synack: UIP_TCP_BUF->flags = TCP_ACK; - - tcp_send_syn: + + tcp_send_syn: UIP_TCP_BUF->flags |= TCP_SYN; #else /* UIP_ACTIVE_OPEN */ - tcp_send_synack: + tcp_send_synack: UIP_TCP_BUF->flags = TCP_SYN | TCP_ACK; #endif /* UIP_ACTIVE_OPEN */ - + /* We send out the TCP Maximum Segment Size option with our SYNACK. */ UIP_TCP_BUF->optdata[0] = TCP_OPT_MSS; @@ -1784,7 +1813,7 @@ uip_process(uint8_t flag) goto tcp_send; /* This label will be jumped to if we found an active connection. */ - found: + found: PRINTF("In found\n"); uip_conn = uip_connr; uip_flags = 0; @@ -1813,9 +1842,9 @@ uip_process(uint8_t flag) receive a SYN, in which case we should retransmit our SYNACK (which is done futher down). */ if(!((((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && - ((UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) || + ((UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) || (((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) && - ((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN)))) { + ((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN)))) { if((uip_len > 0 || ((UIP_TCP_BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) && (UIP_TCP_BUF->seqno[0] != uip_connr->rcv_nxt[0] || UIP_TCP_BUF->seqno[1] != uip_connr->rcv_nxt[1] || @@ -1849,7 +1878,7 @@ uip_process(uint8_t flag) uip_connr->snd_nxt[1] = uip_acc32[1]; uip_connr->snd_nxt[2] = uip_acc32[2]; uip_connr->snd_nxt[3] = uip_acc32[3]; - + /* Do RTT estimation, unless we have done retransmissions. */ if(uip_connr->nrtx == 0) { signed char m; @@ -1873,101 +1902,101 @@ uip_process(uint8_t flag) /* Reset length of outstanding data. */ uip_connr->len = 0; } - + } /* Do different things depending on in what state the connection is. */ switch(uip_connr->tcpstateflags & UIP_TS_MASK) { - /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not + /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not implemented, since we force the application to close when the peer sends a FIN (hence the application goes directly from ESTABLISHED to LAST_ACK). */ - case UIP_SYN_RCVD: - /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and + case UIP_SYN_RCVD: + /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and we are waiting for an ACK that acknowledges the data we sent out the last time. Therefore, we want to have the UIP_ACKDATA flag set. If so, we enter the ESTABLISHED state. */ - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_ESTABLISHED; - uip_flags = UIP_CONNECTED; - uip_connr->len = 0; - if(uip_len > 0) { - uip_flags |= UIP_NEWDATA; - uip_add_rcv_nxt(uip_len); - } - uip_slen = 0; - UIP_APPCALL(); - goto appsend; + if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_ESTABLISHED; + uip_flags = UIP_CONNECTED; + uip_connr->len = 0; + if(uip_len > 0) { + uip_flags |= UIP_NEWDATA; + uip_add_rcv_nxt(uip_len); } - /* We need to retransmit the SYNACK */ - if((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN) { - goto tcp_send_synack; - } - goto drop; + uip_slen = 0; + UIP_APPCALL(); + goto appsend; + } + /* We need to retransmit the SYNACK */ + if((UIP_TCP_BUF->flags & TCP_CTL) == TCP_SYN) { + goto tcp_send_synack; + } + goto drop; #if UIP_ACTIVE_OPEN - case UIP_SYN_SENT: - /* In SYN_SENT, we wait for a SYNACK that is sent in response to + case UIP_SYN_SENT: + /* In SYN_SENT, we wait for a SYNACK that is sent in response to our SYN. The rcv_nxt is set to sequence number in the SYNACK plus one, and we send an ACK. We move into the ESTABLISHED state. */ - if((uip_flags & UIP_ACKDATA) && - (UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) { + if((uip_flags & UIP_ACKDATA) && + (UIP_TCP_BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) { - /* Parse the TCP MSS option, if present. */ - if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) { - for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) { - opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c]; - if(opt == TCP_OPT_END) { - /* End of options. */ - break; - } else if(opt == TCP_OPT_NOOP) { - ++c; - /* NOP option. */ - } else if(opt == TCP_OPT_MSS && - uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { - /* An MSS option with the right option length. */ - tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | + /* Parse the TCP MSS option, if present. */ + if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) { + for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) { + opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c]; + if(opt == TCP_OPT_END) { + /* End of options. */ + break; + } else if(opt == TCP_OPT_NOOP) { + ++c; + /* NOP option. */ + } else if(opt == TCP_OPT_MSS && + uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { + /* An MSS option with the right option length. */ + tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c]; - uip_connr->initialmss = + uip_connr->initialmss = uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; - /* And we are done processing options. */ - break; - } else { - /* All other options have a length field, so that we easily + /* And we are done processing options. */ + break; + } else { + /* All other options have a length field, so that we easily can skip past them. */ - if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { - /* If the length field is zero, the options are malformed + if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { + /* If the length field is zero, the options are malformed and we don't process them further. */ - break; - } - c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; + break; } + c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; } } - uip_connr->tcpstateflags = UIP_ESTABLISHED; - uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0]; - uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1]; - uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2]; - uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3]; - uip_add_rcv_nxt(1); - uip_flags = UIP_CONNECTED | UIP_NEWDATA; - uip_connr->len = 0; - uip_len = 0; - uip_slen = 0; - UIP_APPCALL(); - goto appsend; } - /* Inform the application that the connection failed */ - uip_flags = UIP_ABORT; + uip_connr->tcpstateflags = UIP_ESTABLISHED; + uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0]; + uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1]; + uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2]; + uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3]; + uip_add_rcv_nxt(1); + uip_flags = UIP_CONNECTED | UIP_NEWDATA; + uip_connr->len = 0; + uip_clear_buf(); + uip_slen = 0; UIP_APPCALL(); - /* The connection is closed after we send the RST */ - uip_conn->tcpstateflags = UIP_CLOSED; - goto reset; + goto appsend; + } + /* Inform the application that the connection failed */ + uip_flags = UIP_ABORT; + UIP_APPCALL(); + /* The connection is closed after we send the RST */ + uip_conn->tcpstateflags = UIP_CLOSED; + goto reset; #endif /* UIP_ACTIVE_OPEN */ - - case UIP_ESTABLISHED: - /* In the ESTABLISHED state, we call upon the application to feed + + case UIP_ESTABLISHED: + /* In the ESTABLISHED state, we call upon the application to feed data into the uip_buf. If the UIP_ACKDATA flag is set, the application should put new data into the buffer, otherwise we are retransmitting an old segment, and the application should put that @@ -1978,56 +2007,56 @@ uip_process(uint8_t flag) state. We require that there is no outstanding data; otherwise the sequence numbers will be screwed up. */ - if(UIP_TCP_BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) { - if(uip_outstanding(uip_connr)) { - goto drop; - } - uip_add_rcv_nxt(1 + uip_len); - uip_flags |= UIP_CLOSE; - if(uip_len > 0) { - uip_flags |= UIP_NEWDATA; - } - UIP_APPCALL(); - uip_connr->len = 1; - uip_connr->tcpstateflags = UIP_LAST_ACK; - uip_connr->nrtx = 0; + if(UIP_TCP_BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) { + if(uip_outstanding(uip_connr)) { + goto drop; + } + uip_add_rcv_nxt(1 + uip_len); + uip_flags |= UIP_CLOSE; + if(uip_len > 0) { + uip_flags |= UIP_NEWDATA; + } + UIP_APPCALL(); + uip_connr->len = 1; + uip_connr->tcpstateflags = UIP_LAST_ACK; + uip_connr->nrtx = 0; tcp_send_finack: - UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK; - goto tcp_send_nodata; - } + UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK; + goto tcp_send_nodata; + } - /* Check the URG flag. If this is set, the segment carries urgent + /* Check the URG flag. If this is set, the segment carries urgent data that we must pass to the application. */ - if((UIP_TCP_BUF->flags & TCP_URG) != 0) { + if((UIP_TCP_BUF->flags & TCP_URG) != 0) { #if UIP_URGDATA > 0 - uip_urglen = (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]; - if(uip_urglen > uip_len) { - /* There is more urgent data in the next segment to come. */ - uip_urglen = uip_len; - } - uip_add_rcv_nxt(uip_urglen); - uip_len -= uip_urglen; - uip_urgdata = uip_appdata; - uip_appdata += uip_urglen; - } else { - uip_urglen = 0; -#else /* UIP_URGDATA > 0 */ - uip_appdata = ((char *)uip_appdata) + ((UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]); - uip_len -= (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]; -#endif /* UIP_URGDATA > 0 */ + uip_urglen = (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]; + if(uip_urglen > uip_len) { + /* There is more urgent data in the next segment to come. */ + uip_urglen = uip_len; } + uip_add_rcv_nxt(uip_urglen); + uip_len -= uip_urglen; + uip_urgdata = uip_appdata; + uip_appdata += uip_urglen; + } else { + uip_urglen = 0; +#else /* UIP_URGDATA > 0 */ + uip_appdata = ((char *)uip_appdata) + ((UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]); + uip_len -= (UIP_TCP_BUF->urgp[0] << 8) | UIP_TCP_BUF->urgp[1]; +#endif /* UIP_URGDATA > 0 */ + } - /* If uip_len > 0 we have TCP data in the packet, and we flag this + /* If uip_len > 0 we have TCP data in the packet, and we flag this by setting the UIP_NEWDATA flag and update the sequence number we acknowledge. If the application has stopped the dataflow using uip_stop(), we must not accept any data packets from the remote host. */ - if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) { - uip_flags |= UIP_NEWDATA; - uip_add_rcv_nxt(uip_len); - } + if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) { + uip_flags |= UIP_NEWDATA; + uip_add_rcv_nxt(uip_len); + } - /* Check if the available buffer space advertised by the other end + /* Check if the available buffer space advertised by the other end is smaller than the initial MSS for this connection. If so, we set the current MSS to the window size to ensure that the application does not send more data than the other end can @@ -2038,15 +2067,15 @@ uip_process(uint8_t flag) of data. This data will not be acknowledged by the receiver, and the application will retransmit it. This is called the "persistent timer" and uses the retransmission mechanim. - */ - tmp16 = ((uint16_t)UIP_TCP_BUF->wnd[0] << 8) + (uint16_t)UIP_TCP_BUF->wnd[1]; - if(tmp16 > uip_connr->initialmss || - tmp16 == 0) { - tmp16 = uip_connr->initialmss; - } - uip_connr->mss = tmp16; + */ + tmp16 = ((uint16_t)UIP_TCP_BUF->wnd[0] << 8) + (uint16_t)UIP_TCP_BUF->wnd[1]; + if(tmp16 > uip_connr->initialmss || + tmp16 == 0) { + tmp16 = uip_connr->initialmss; + } + uip_connr->mss = tmp16; - /* If this packet constitutes an ACK for outstanding data (flagged + /* If this packet constitutes an ACK for outstanding data (flagged by the UIP_ACKDATA flag, we should call the application since it might want to send more data. If the incoming packet had data from the peer (as flagged by the UIP_NEWDATA flag), the @@ -2062,180 +2091,178 @@ uip_process(uint8_t flag) put into the uip_appdata and the length of the data should be put into uip_len. If the application don't have any data to send, uip_len must be set to 0. */ - if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) { - uip_slen = 0; - UIP_APPCALL(); + if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) { + uip_slen = 0; + UIP_APPCALL(); appsend: - - if(uip_flags & UIP_ABORT) { - uip_slen = 0; - uip_connr->tcpstateflags = UIP_CLOSED; - UIP_TCP_BUF->flags = TCP_RST | TCP_ACK; - goto tcp_send_nodata; - } - if(uip_flags & UIP_CLOSE) { - uip_slen = 0; - uip_connr->len = 1; - uip_connr->tcpstateflags = UIP_FIN_WAIT_1; - uip_connr->nrtx = 0; - UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK; - goto tcp_send_nodata; - } + if(uip_flags & UIP_ABORT) { + uip_slen = 0; + uip_connr->tcpstateflags = UIP_CLOSED; + UIP_TCP_BUF->flags = TCP_RST | TCP_ACK; + goto tcp_send_nodata; + } - /* If uip_slen > 0, the application has data to be sent. */ - if(uip_slen > 0) { + if(uip_flags & UIP_CLOSE) { + uip_slen = 0; + uip_connr->len = 1; + uip_connr->tcpstateflags = UIP_FIN_WAIT_1; + uip_connr->nrtx = 0; + UIP_TCP_BUF->flags = TCP_FIN | TCP_ACK; + goto tcp_send_nodata; + } - /* If the connection has acknowledged data, the contents of + /* If uip_slen > 0, the application has data to be sent. */ + if(uip_slen > 0) { + + /* If the connection has acknowledged data, the contents of the ->len variable should be discarded. */ - if((uip_flags & UIP_ACKDATA) != 0) { - uip_connr->len = 0; - } + if((uip_flags & UIP_ACKDATA) != 0) { + uip_connr->len = 0; + } - /* If the ->len variable is non-zero the connection has + /* If the ->len variable is non-zero the connection has already data in transit and cannot send anymore right now. */ - if(uip_connr->len == 0) { + if(uip_connr->len == 0) { - /* The application cannot send more than what is allowed by + /* The application cannot send more than what is allowed by the mss (the minumum of the MSS and the available window). */ - if(uip_slen > uip_connr->mss) { - uip_slen = uip_connr->mss; - } + if(uip_slen > uip_connr->mss) { + uip_slen = uip_connr->mss; + } - /* Remember how much data we send out now so that we know + /* Remember how much data we send out now so that we know when everything has been acknowledged. */ - uip_connr->len = uip_slen; - } else { + uip_connr->len = uip_slen; + } else { - /* If the application already had unacknowledged data, we + /* If the application already had unacknowledged data, we make sure that the application does not send (i.e., retransmit) out more than it previously sent out. */ - uip_slen = uip_connr->len; - } + uip_slen = uip_connr->len; } - uip_connr->nrtx = 0; + } + uip_connr->nrtx = 0; apprexmit: - uip_appdata = uip_sappdata; - - /* If the application has data to be sent, or if the incoming + uip_appdata = uip_sappdata; + + /* If the application has data to be sent, or if the incoming packet had new data in it, we must send out a packet. */ - if(uip_slen > 0 && uip_connr->len > 0) { - /* Add the length of the IP and TCP headers. */ - uip_len = uip_connr->len + UIP_TCPIP_HLEN; - /* We always set the ACK flag in response packets. */ - UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH; - /* Send the packet. */ - goto tcp_send_noopts; - } - /* If there is no data to send, just send out a pure ACK if + if(uip_slen > 0 && uip_connr->len > 0) { + /* Add the length of the IP and TCP headers. */ + uip_len = uip_connr->len + UIP_TCPIP_HLEN; + /* We always set the ACK flag in response packets. */ + UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH; + /* Send the packet. */ + goto tcp_send_noopts; + } + /* If there is no data to send, just send out a pure ACK if there is newdata. */ - if(uip_flags & UIP_NEWDATA) { - uip_len = UIP_TCPIP_HLEN; - UIP_TCP_BUF->flags = TCP_ACK; - goto tcp_send_noopts; - } + if(uip_flags & UIP_NEWDATA) { + uip_len = UIP_TCPIP_HLEN; + UIP_TCP_BUF->flags = TCP_ACK; + goto tcp_send_noopts; } - goto drop; - case UIP_LAST_ACK: - /* We can close this connection if the peer has acknowledged our + } + goto drop; + case UIP_LAST_ACK: + /* We can close this connection if the peer has acknowledged our FIN. This is indicated by the UIP_ACKDATA flag. */ - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_CLOSED; - uip_flags = UIP_CLOSE; - UIP_APPCALL(); - } - break; - - case UIP_FIN_WAIT_1: - /* The application has closed the connection, but the remote host + if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_CLOSED; + uip_flags = UIP_CLOSE; + UIP_APPCALL(); + } + break; + + case UIP_FIN_WAIT_1: + /* The application has closed the connection, but the remote host hasn't closed its end yet. Thus we do nothing but wait for a FIN from the other side. */ - if(uip_len > 0) { - uip_add_rcv_nxt(uip_len); - } - if(UIP_TCP_BUF->flags & TCP_FIN) { - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; - uip_connr->len = 0; - } else { - uip_connr->tcpstateflags = UIP_CLOSING; - } - uip_add_rcv_nxt(1); - uip_flags = UIP_CLOSE; - UIP_APPCALL(); - goto tcp_send_ack; - } else if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_FIN_WAIT_2; - uip_connr->len = 0; - goto drop; - } - if(uip_len > 0) { - goto tcp_send_ack; - } - goto drop; - - case UIP_FIN_WAIT_2: - if(uip_len > 0) { - uip_add_rcv_nxt(uip_len); - } - if(UIP_TCP_BUF->flags & TCP_FIN) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; - uip_add_rcv_nxt(1); - uip_flags = UIP_CLOSE; - UIP_APPCALL(); - goto tcp_send_ack; - } - if(uip_len > 0) { - goto tcp_send_ack; - } - goto drop; - - case UIP_TIME_WAIT: - goto tcp_send_ack; - - case UIP_CLOSING: + if(uip_len > 0) { + uip_add_rcv_nxt(uip_len); + } + if(UIP_TCP_BUF->flags & TCP_FIN) { if(uip_flags & UIP_ACKDATA) { uip_connr->tcpstateflags = UIP_TIME_WAIT; uip_connr->timer = 0; + uip_connr->len = 0; + } else { + uip_connr->tcpstateflags = UIP_CLOSING; } + uip_add_rcv_nxt(1); + uip_flags = UIP_CLOSE; + UIP_APPCALL(); + goto tcp_send_ack; + } else if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_FIN_WAIT_2; + uip_connr->len = 0; + goto drop; + } + if(uip_len > 0) { + goto tcp_send_ack; + } + goto drop; + + case UIP_FIN_WAIT_2: + if(uip_len > 0) { + uip_add_rcv_nxt(uip_len); + } + if(UIP_TCP_BUF->flags & TCP_FIN) { + uip_connr->tcpstateflags = UIP_TIME_WAIT; + uip_connr->timer = 0; + uip_add_rcv_nxt(1); + uip_flags = UIP_CLOSE; + UIP_APPCALL(); + goto tcp_send_ack; + } + if(uip_len > 0) { + goto tcp_send_ack; + } + goto drop; + + case UIP_TIME_WAIT: + goto tcp_send_ack; + + case UIP_CLOSING: + if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_TIME_WAIT; + uip_connr->timer = 0; + } } goto drop; - + /* We jump here when we are ready to send the packet, and just want to set the appropriate TCP sequence numbers in the TCP header. */ - tcp_send_ack: + tcp_send_ack: UIP_TCP_BUF->flags = TCP_ACK; - tcp_send_nodata: + tcp_send_nodata: uip_len = UIP_IPTCPH_LEN; - tcp_send_noopts: + tcp_send_noopts: UIP_TCP_BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4; /* We're done with the input processing. We are now ready to send a reply. Our job is to fill in all the fields of the TCP and IP headers before calculating the checksum and finally send the packet. */ - tcp_send: + tcp_send: PRINTF("In tcp_send\n"); - + UIP_TCP_BUF->ackno[0] = uip_connr->rcv_nxt[0]; UIP_TCP_BUF->ackno[1] = uip_connr->rcv_nxt[1]; UIP_TCP_BUF->ackno[2] = uip_connr->rcv_nxt[2]; UIP_TCP_BUF->ackno[3] = uip_connr->rcv_nxt[3]; - + UIP_TCP_BUF->seqno[0] = uip_connr->snd_nxt[0]; UIP_TCP_BUF->seqno[1] = uip_connr->snd_nxt[1]; UIP_TCP_BUF->seqno[2] = uip_connr->snd_nxt[2]; UIP_TCP_BUF->seqno[3] = uip_connr->snd_nxt[3]; - UIP_IP_BUF->proto = UIP_PROTO_TCP; - UIP_TCP_BUF->srcport = uip_connr->lport; UIP_TCP_BUF->destport = uip_connr->rport; @@ -2256,13 +2283,15 @@ uip_process(uint8_t flag) UIP_TCP_BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff); } - tcp_send_noconn: + tcp_send_noconn: + UIP_IP_BUF->proto = UIP_PROTO_TCP; + UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit; UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); UIP_TCP_BUF->urgp[0] = UIP_TCP_BUF->urgp[1] = 0; - + /* Calculate TCP checksum. */ UIP_TCP_BUF->tcpchksum = 0; UIP_TCP_BUF->tcpchksum = ~(uip_tcpchksum()); @@ -2270,23 +2299,22 @@ uip_process(uint8_t flag) #endif /* UIP_TCP */ #if UIP_UDP - ip_send_nolen: + ip_send_nolen: #endif UIP_IP_BUF->vtc = 0x60; UIP_IP_BUF->tcflow = 0x00; UIP_IP_BUF->flow = 0x00; - send: + send: PRINTF("Sending packet with length %d (%d)\n", uip_len, - (UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]); - + (UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]); + UIP_STAT(++uip_stat.ip.sent); /* Return and let the caller do the actual transmission. */ uip_flags = 0; return; - drop: - uip_len = 0; - uip_ext_len = 0; + drop: + uip_clear_buf(); uip_ext_bitmap = 0; uip_flags = 0; return; @@ -2308,12 +2336,11 @@ void uip_send(const void *data, int len) { int copylen; -#define MIN(a,b) ((a) < (b)? (a): (b)) if(uip_sappdata != NULL) { copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN - - (int)((char *)uip_sappdata - - (char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN])); + (int)((char *)uip_sappdata - + (char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN])); } else { copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN); } @@ -2322,7 +2349,7 @@ uip_send(const void *data, int len) if(data != uip_sappdata) { if(uip_sappdata == NULL) { memcpy((char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN], - (data), uip_slen); + (data), uip_slen); } else { memcpy(uip_sappdata, (data), uip_slen); } @@ -2331,4 +2358,3 @@ uip_send(const void *data, int len) } /*---------------------------------------------------------------------------*/ /** @} */ -#endif /* UIP_CONF_IPV6 */ diff --git a/core/net/link-stats.c b/core/net/link-stats.c new file mode 100644 index 000000000..a2f99e729 --- /dev/null +++ b/core/net/link-stats.c @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + * Authors: Simon Duquennoy + */ + +#include "contiki.h" +#include "sys/clock.h" +#include "net/packetbuf.h" +#include "net/nbr-table.h" +#include "net/link-stats.h" +#include + +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/* Half time for the freshness counter, in minutes */ +#define FRESHNESS_HALF_LIFE 20 +/* Statistics are fresh if the freshness counter is FRESHNESS_TARGET or more */ +#define FRESHNESS_TARGET 4 +/* Maximum value for the freshness counter */ +#define FRESHNESS_MAX 16 +/* Statistics with no update in FRESHNESS_EXPIRATION_TIMEOUT is not fresh */ +#define FRESHNESS_EXPIRATION_TIME (10 * 60 * CLOCK_SECOND) + +/* EWMA (exponential moving average) used to maintain statistics over time */ +#define EWMA_SCALE 100 +#define EWMA_ALPHA 15 +#define EWMA_BOOTSTRAP_ALPHA 30 + +/* ETX fixed point divisor. 128 is the value used by RPL (RFC 6551 and RFC 6719) */ +#define ETX_DIVISOR LINK_STATS_ETX_DIVISOR +/* Number of Tx used to update the ETX EWMA in case of no-ACK */ +#define ETX_NOACK_PENALTY 10 +/* Initial ETX value */ +#define ETX_INIT 2 + +/* Per-neighbor link statistics table */ +NBR_TABLE(struct link_stats, link_stats); + +/* Called every FRESHNESS_HALF_LIFE minutes */ +struct ctimer periodic_timer; + +/* Used to initialize ETX before any transmission occurs. In order to + * infer the initial ETX from the RSSI of previously received packets, use: */ +/* #define LINK_STATS_CONF_INIT_ETX(stats) guess_etx_from_rssi(stats) */ + +#ifdef LINK_STATS_CONF_INIT_ETX +#define LINK_STATS_INIT_ETX(stats) LINK_STATS_CONF_INIT_ETX(stats) +#else /* LINK_STATS_INIT_ETX */ +#define LINK_STATS_INIT_ETX(stats) (ETX_INIT * ETX_DIVISOR) +#endif /* LINK_STATS_INIT_ETX */ + +/*---------------------------------------------------------------------------*/ +/* Returns the neighbor's link stats */ +const struct link_stats * +link_stats_from_lladdr(const linkaddr_t *lladdr) +{ + return nbr_table_get_from_lladdr(link_stats, lladdr); +} +/*---------------------------------------------------------------------------*/ +/* Are the statistics fresh? */ +int +link_stats_is_fresh(const struct link_stats *stats) +{ + return (stats != NULL) + && clock_time() - stats->last_tx_time < FRESHNESS_EXPIRATION_TIME + && stats->freshness >= FRESHNESS_TARGET; +} +/*---------------------------------------------------------------------------*/ +uint16_t +guess_etx_from_rssi(const struct link_stats *stats) +{ + if(stats != NULL) { + if(stats->rssi == 0) { + return ETX_INIT * ETX_DIVISOR; + } else { + /* A rough estimate of PRR from RSSI, as a linear function where: + * RSSI >= -60 results in PRR of 1 + * RSSI <= -90 results in PRR of 0 + * prr = (bounded_rssi - RSSI_LOW) / (RSSI_DIFF) + * etx = ETX_DIVOSOR / ((bounded_rssi - RSSI_LOW) / RSSI_DIFF) + * etx = (RSSI_DIFF * ETX_DIVOSOR) / (bounded_rssi - RSSI_LOW) + * */ +#define ETX_INIT_MAX 3 +#define RSSI_HIGH -60 +#define RSSI_LOW -90 +#define RSSI_DIFF (RSSI_HIGH - RSSI_LOW) + uint16_t etx; + int16_t bounded_rssi = stats->rssi; + bounded_rssi = MIN(bounded_rssi, RSSI_HIGH); + bounded_rssi = MAX(bounded_rssi, RSSI_LOW + 1); + etx = RSSI_DIFF * ETX_DIVISOR / (bounded_rssi - RSSI_LOW); + return MIN(etx, ETX_INIT_MAX * ETX_DIVISOR); + } + } + return 0xffff; +} +/*---------------------------------------------------------------------------*/ +/* Packet sent callback. Updates stats for transmissions to lladdr */ +void +link_stats_packet_sent(const linkaddr_t *lladdr, int status, int numtx) +{ + struct link_stats *stats; + uint16_t packet_etx; + uint8_t ewma_alpha; + + if(status != MAC_TX_OK && status != MAC_TX_NOACK) { + /* Do not penalize the ETX when collisions or transmission errors occur. */ + return; + } + + stats = nbr_table_get_from_lladdr(link_stats, lladdr); + if(stats == NULL) { + /* Add the neighbor */ + stats = nbr_table_add_lladdr(link_stats, lladdr, NBR_TABLE_REASON_LINK_STATS, NULL); + if(stats != NULL) { + stats->etx = LINK_STATS_INIT_ETX(stats); + } else { + return; /* No space left, return */ + } + } + + /* Update last timestamp and freshness */ + stats->last_tx_time = clock_time(); + stats->freshness = MIN(stats->freshness + numtx, FRESHNESS_MAX); + + /* ETX used for this update */ + packet_etx = ((status == MAC_TX_NOACK) ? ETX_NOACK_PENALTY : numtx) * ETX_DIVISOR; + /* ETX alpha used for this update */ + ewma_alpha = link_stats_is_fresh(stats) ? EWMA_ALPHA : EWMA_BOOTSTRAP_ALPHA; + + /* Compute EWMA and update ETX */ + stats->etx = ((uint32_t)stats->etx * (EWMA_SCALE - ewma_alpha) + + (uint32_t)packet_etx * ewma_alpha) / EWMA_SCALE; +} +/*---------------------------------------------------------------------------*/ +/* Packet input callback. Updates statistics for receptions on a given link */ +void +link_stats_input_callback(const linkaddr_t *lladdr) +{ + struct link_stats *stats; + int16_t packet_rssi = packetbuf_attr(PACKETBUF_ATTR_RSSI); + + stats = nbr_table_get_from_lladdr(link_stats, lladdr); + if(stats == NULL) { + /* Add the neighbor */ + stats = nbr_table_add_lladdr(link_stats, lladdr, NBR_TABLE_REASON_LINK_STATS, NULL); + if(stats != NULL) { + /* Initialize */ + stats->rssi = packet_rssi; + stats->etx = LINK_STATS_INIT_ETX(stats); + } + return; + } + + /* Update RSSI EWMA */ + stats->rssi = ((int32_t)stats->rssi * (EWMA_SCALE - EWMA_ALPHA) + + (int32_t)packet_rssi * EWMA_ALPHA) / EWMA_SCALE; +} +/*---------------------------------------------------------------------------*/ +/* Periodic timer called every FRESHNESS_HALF_LIFE minutes */ +static void +periodic(void *ptr) +{ + /* Age (by halving) freshness counter of all neighbors */ + struct link_stats *stats; + ctimer_reset(&periodic_timer); + for(stats = nbr_table_head(link_stats); stats != NULL; stats = nbr_table_next(link_stats, stats)) { + stats->freshness >>= 1; + } +} +/*---------------------------------------------------------------------------*/ +/* Initializes link-stats module */ +void +link_stats_init(void) +{ + nbr_table_register(link_stats, NULL); + ctimer_set(&periodic_timer, 60 * CLOCK_SECOND * FRESHNESS_HALF_LIFE, + periodic, NULL); +} diff --git a/core/net/link-stats.h b/core/net/link-stats.h new file mode 100644 index 000000000..d28a1c1a4 --- /dev/null +++ b/core/net/link-stats.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + * Authors: Simon Duquennoy + */ + +#ifndef LINK_STATS_H_ +#define LINK_STATS_H_ + +#include "core/net/linkaddr.h" + +/* ETX fixed point divisor. 128 is the value used by RPL (RFC 6551 and RFC 6719) */ +#ifdef LINK_STATS_CONF_ETX_DIVISOR +#define LINK_STATS_ETX_DIVISOR LINK_STATS_CONF_ETX_DIVISOR +#else /* LINK_STATS_CONF_ETX_DIVISOR */ +#define LINK_STATS_ETX_DIVISOR 128 +#endif /* LINK_STATS_CONF_ETX_DIVISOR */ + +/* All statistics of a given link */ +struct link_stats { + uint16_t etx; /* ETX using ETX_DIVISOR as fixed point divisor */ + int16_t rssi; /* RSSI (received signal strength) */ + uint8_t freshness; /* Freshness of the statistics */ + clock_time_t last_tx_time; /* Last Tx timestamp */ +}; + +/* Returns the neighbor's link statistics */ +const struct link_stats *link_stats_from_lladdr(const linkaddr_t *lladdr); +/* Are the statistics fresh? */ +int link_stats_is_fresh(const struct link_stats *stats); + +/* Initializes link-stats module */ +void link_stats_init(void); +/* Packet sent callback. Updates statistics for transmissions on a given link */ +void link_stats_packet_sent(const linkaddr_t *lladdr, int status, int numtx); +/* Packet input callback. Updates statistics for receptions on a given link */ +void link_stats_input_callback(const linkaddr_t *lladdr); + +#endif /* LINK_STATS_H_ */ diff --git a/core/net/linkaddr.c b/core/net/linkaddr.c index ebe5a5108..51b8b19ef 100644 --- a/core/net/linkaddr.c +++ b/core/net/linkaddr.c @@ -1,8 +1,3 @@ -/** - * \addtogroup linkaddr - * @{ - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup linkaddr + * @{ + */ + #include "net/linkaddr.h" #include diff --git a/core/net/linkaddr.h b/core/net/linkaddr.h index cbfc43a95..e2a4bfc4f 100644 --- a/core/net/linkaddr.h +++ b/core/net/linkaddr.h @@ -1,17 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup linkaddr Rime addresses - * @{ - * - * The linkaddr module is an abstract representation of addresses in - * Rime. - * - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -51,6 +37,20 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup linkaddr Rime addresses + * @{ + * + * The linkaddr module is an abstract representation of addresses in + * Rime. + * + */ + #ifndef LINKADDR_H_ #define LINKADDR_H_ @@ -64,8 +64,15 @@ typedef union { unsigned char u8[LINKADDR_SIZE]; +#if LINKADDR_SIZE == 2 + uint16_t u16; +#endif /* LINKADDR_SIZE == 2 */ } linkaddr_t; +typedef union { + uint8_t u8[8]; + uint16_t u16[4]; +} linkaddr_extended_t; /** * \brief Copy a Rime address diff --git a/core/net/llsec/README.md b/core/net/llsec/README.md new file mode 100644 index 000000000..a5ac5854e --- /dev/null +++ b/core/net/llsec/README.md @@ -0,0 +1,5 @@ +Link layer security is implemented as a new netstack layer, which is located in between the MAC and the NETWORK layer. The interface of LLSEC drivers is defined in [llsec.h](llsec.h). Additionally, LLSEC drivers may define a special [FRAMER](../mac/framer.h), which calls the actual FRAMER underneath. By default, the LLSEC driver `nullsec` is used, which does nothing. + +# TODO + +* Most main files do not call LLSEC.init, yet \ No newline at end of file diff --git a/core/net/llsec/anti-replay.c b/core/net/llsec/anti-replay.c new file mode 100644 index 000000000..a59f6b4c8 --- /dev/null +++ b/core/net/llsec/anti-replay.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2014, Hasso-Plattner-Institut. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Protects against replay attacks by comparing with the last + * unicast or broadcast frame counter of the sender. + * \author + * Konrad Krentz + */ + +/** + * \addtogroup llsec802154 + * @{ + */ + +#include "net/llsec/anti-replay.h" +#include "net/packetbuf.h" +#include "net/llsec/llsec802154.h" + +#if LLSEC802154_USES_FRAME_COUNTER + +/* This node's current frame counter value */ +static uint32_t counter; + +/*---------------------------------------------------------------------------*/ +void +anti_replay_set_counter(void) +{ + frame802154_frame_counter_t reordered_counter; + + ++counter; + reordered_counter.u32 = LLSEC802154_HTONL(counter); + + packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, reordered_counter.u16[0]); + packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, reordered_counter.u16[1]); +} +/*---------------------------------------------------------------------------*/ +uint32_t +anti_replay_get_counter(void) +{ + frame802154_frame_counter_t disordered_counter; + + disordered_counter.u16[0] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1); + disordered_counter.u16[1] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3); + + return LLSEC802154_HTONL(disordered_counter.u32); +} +/*---------------------------------------------------------------------------*/ +void +anti_replay_init_info(struct anti_replay_info *info) +{ + info->last_broadcast_counter + = info->last_unicast_counter + = anti_replay_get_counter(); +} +/*---------------------------------------------------------------------------*/ +int +anti_replay_was_replayed(struct anti_replay_info *info) +{ + uint32_t received_counter; + + received_counter = anti_replay_get_counter(); + + if(packetbuf_holds_broadcast()) { + /* broadcast */ + if(received_counter <= info->last_broadcast_counter) { + return 1; + } else { + info->last_broadcast_counter = received_counter; + return 0; + } + } else { + /* unicast */ + if(received_counter <= info->last_unicast_counter) { + return 1; + } else { + info->last_unicast_counter = received_counter; + return 0; + } + } +} +/*---------------------------------------------------------------------------*/ +#endif /* LLSEC802154_USES_FRAME_COUNTER */ + +/** @} */ diff --git a/core/net/llsec/anti-replay.h b/core/net/llsec/anti-replay.h new file mode 100644 index 000000000..9211a6e7a --- /dev/null +++ b/core/net/llsec/anti-replay.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014, Hasso-Plattner-Institut. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Interface to anti-replay mechanisms. + * \author + * Konrad Krentz + */ + +/** + * \addtogroup llsec802154 + * @{ + */ + +#ifndef ANTI_REPLAY_H +#define ANTI_REPLAY_H + +#include "contiki.h" + +struct anti_replay_info { + uint32_t last_broadcast_counter; + uint32_t last_unicast_counter; +}; + +/** + * \brief Sets the frame counter packetbuf attributes. + */ +void anti_replay_set_counter(void); + +/** + * \brief Gets the frame counter from packetbuf. + */ +uint32_t anti_replay_get_counter(void); + +/** + * \brief Initializes the anti-replay information about the sender + * \param info Anti-replay information about the sender + */ +void anti_replay_init_info(struct anti_replay_info *info); + +/** + * \brief Checks if received frame was replayed + * \param info Anti-replay information about the sender + * \retval 0 <-> received frame was not replayed + */ +int anti_replay_was_replayed(struct anti_replay_info *info); + +#endif /* ANTI_REPLAY_H */ + +/** @} */ diff --git a/core/net/llsec/ccm-star-packetbuf.c b/core/net/llsec/ccm-star-packetbuf.c new file mode 100644 index 000000000..d5d077301 --- /dev/null +++ b/core/net/llsec/ccm-star-packetbuf.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013, Hasso-Plattner-Institut. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * CCM* convenience functions for LLSEC use + * \author + * Justin King-Lacroix + * Konrad Krentz + */ + +#include "llsec/ccm-star-packetbuf.h" +#include "net/linkaddr.h" +#include "net/packetbuf.h" +#include "net/llsec/llsec802154.h" +#include + +#if LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER + +/*---------------------------------------------------------------------------*/ +static const uint8_t * +get_extended_address(const linkaddr_t *addr) +#if LINKADDR_SIZE == 2 +{ + /* workaround for short addresses: derive EUI64 as in RFC 6282 */ + static linkaddr_extended_t template = { { 0x00 , 0x00 , 0x00 , + 0xFF , 0xFE , 0x00 , 0x00 , 0x00 } }; + + template.u16[3] = LLSEC802154_HTONS(addr->u16); + + return template.u8; +} +#else /* LINKADDR_SIZE == 2 */ +{ + return addr->u8; +} +#endif /* LINKADDR_SIZE == 2 */ +/*---------------------------------------------------------------------------*/ +void +ccm_star_packetbuf_set_nonce(uint8_t *nonce, int forward) +{ + const linkaddr_t *source_addr; + + source_addr = forward ? &linkaddr_node_addr : packetbuf_addr(PACKETBUF_ADDR_SENDER); + memcpy(nonce, get_extended_address(source_addr), 8); + nonce[8] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 8; + nonce[9] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) & 0xff; + nonce[10] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) >> 8; + nonce[11] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) & 0xff; + nonce[12] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL); +} +/*---------------------------------------------------------------------------*/ +#endif /* LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER */ diff --git a/core/net/llsec/ccm-star-packetbuf.h b/core/net/llsec/ccm-star-packetbuf.h new file mode 100644 index 000000000..dcbe6c4db --- /dev/null +++ b/core/net/llsec/ccm-star-packetbuf.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013, Hasso-Plattner-Institut. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * CCM* convenience functions for MAC security + * \author + * Justin King-Lacroix + * Konrad Krentz + */ + +#ifndef CCM_STAR_PACKETBUF_H_ +#define CCM_STAR_PACKETBUF_H_ + +#include "lib/ccm-star.h" + +void ccm_star_packetbuf_set_nonce(uint8_t *nonce, int forward); + +#endif /* CCM_STAR_PACKETBUF_H_ */ diff --git a/core/net/llsec/llsec.h b/core/net/llsec/llsec.h new file mode 100644 index 000000000..b0d983cc3 --- /dev/null +++ b/core/net/llsec/llsec.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, Hasso-Plattner-Institut. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Link layer security header file. + * \author + * Konrad Krentz + */ + +/** + * \ingroup net + * \defgroup llsec Link Layer Security + * + * Layer for implementing link layer security. + * + * NETSTACK_LLSEC sits in between NETSTACK_MAC and NETSTACK_NETWORK + * protocols. All NETSTACK_MAC protocols invoke NETSTACK_LLSEC.input() + * for incoming packets. Likewise, all NETSTACK_NETWORK protocols + * invoke NETSTACK_LLSEC.send(...) for outgoing packets. + * + * @{ + */ + +#ifndef LLSEC_H_ +#define LLSEC_H_ + +#include "net/mac/mac.h" + +/** + * The structure of a link layer security driver. + */ +struct llsec_driver { + char *name; + + /** Inits link layer security. */ + void (* init)(void); + + /** Secures outgoing frames before passing them to NETSTACK_MAC. */ + void (* send)(mac_callback_t sent_callback, void *ptr); + + /** + * Decrypts incoming frames; + * filters out injected or replayed frames. + */ + void (* input)(void); +}; + +#endif /* LLSEC_H_ */ + +/** @} */ diff --git a/core/net/llsec/llsec802154.h b/core/net/llsec/llsec802154.h new file mode 100644 index 000000000..acbba1f9d --- /dev/null +++ b/core/net/llsec/llsec802154.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013, Hasso-Plattner-Institut. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Common functionality of 802.15.4-compliant llsec_drivers. + * \author + * Konrad Krentz + */ + +/** + * \addtogroup llsec + * @{ + */ + +/** + * \defgroup llsec802154 Link Layer Security Common Functionality + * + * Common functionality of 802.15.4-compliant llsec_drivers. + * + * @{ + */ + +#ifndef LLSEC802154_H_ +#define LLSEC802154_H_ + +#include "net/mac/frame802154.h" +#include "net/ip/uip.h" + +#ifdef LLSEC802154_CONF_ENABLED +#define LLSEC802154_ENABLED LLSEC802154_CONF_ENABLED +#else /* LLSEC802154_CONF_ENABLED */ +#define LLSEC802154_ENABLED 0 +#endif /* LLSEC802154_CONF_ENABLED */ + +#define LLSEC802154_MIC_LEN(sec_lvl) (2 << (sec_lvl & 3)) + +#ifdef LLSEC802154_CONF_USES_EXPLICIT_KEYS +#define LLSEC802154_USES_EXPLICIT_KEYS LLSEC802154_CONF_USES_EXPLICIT_KEYS +#else /* LLSEC802154_CONF_USES_EXPLICIT_KEYS */ +#define LLSEC802154_USES_EXPLICIT_KEYS 0 +#endif /* LLSEC802154_CONF_USES_EXPLICIT_KEYS */ + +#ifdef LLSEC802154_CONF_USES_FRAME_COUNTER +#define LLSEC802154_USES_FRAME_COUNTER LLSEC802154_CONF_USES_FRAME_COUNTER +#else /* LLSEC802154_CONF_USES_FRAME_COUNTER */ +#define LLSEC802154_USES_FRAME_COUNTER LLSEC802154_ENABLED +#endif /* LLSEC802154_CONF_USES_FRAME_COUNTER */ + +#ifdef LLSEC802154_CONF_USES_AUX_HEADER +#define LLSEC802154_USES_AUX_HEADER LLSEC802154_CONF_USES_AUX_HEADER +#else /* LLSEC802154_CONF_USES_AUX_HEADER */ +#define LLSEC802154_USES_AUX_HEADER LLSEC802154_ENABLED +#endif /* LLSEC802154_CONF_USES_AUX_HEADER */ + +#if UIP_BYTE_ORDER == UIP_LITTLE_ENDIAN +#define LLSEC802154_HTONS(n) (n) +#define LLSEC802154_HTONL(n) (n) +#else /* UIP_CONF_BYTE_ORDER == UIP_LITTLE_ENDIAN */ +#define LLSEC802154_HTONS(n) (uint16_t)((((uint16_t) (n)) << 8) | (((uint16_t) (n)) >> 8)) +#define LLSEC802154_HTONL(n) (((uint32_t)UIP_HTONS(n) << 16) | UIP_HTONS((uint32_t)(n) >> 16)) +#endif /* UIP_CONF_BYTE_ORDER == UIP_LITTLE_ENDIAN */ + +#endif /* LLSEC802154_H_ */ + +/** @} */ +/** @} */ diff --git a/core/net/llsec/noncoresec/README.md b/core/net/llsec/noncoresec/README.md new file mode 100644 index 000000000..00ca46f15 --- /dev/null +++ b/core/net/llsec/noncoresec/README.md @@ -0,0 +1,21 @@ +`noncoresec` is a noncompromise-resilient 802.15.4 security implementation, which uses a network-wide key. Add these lines to your `project_conf.h` to enable `noncoresec`: + +```c +#undef LLSEC802154_CONF_ENABLED +#define LLSEC802154_CONF_ENABLED 1 +#undef NETSTACK_CONF_FRAMER +#define NETSTACK_CONF_FRAMER noncoresec_framer +#undef NETSTACK_CONF_LLSEC +#define NETSTACK_CONF_LLSEC noncoresec_driver +#undef NONCORESEC_CONF_SEC_LVL +#define NONCORESEC_CONF_SEC_LVL 1 +``` +`NONCORESEC_CONF_SEC_LVL` defines the length of MICs and whether encryption is enabled or not. + +Setting the network-wide key works as follows: +```c +#define NONCORESEC_CONF_KEY { 0x00 , 0x01 , 0x02 , 0x03 , \ + 0x04 , 0x05 , 0x06 , 0x07 , \ + 0x08 , 0x09 , 0x0A , 0x0B , \ + 0x0C , 0x0D , 0x0E , 0x0F } +``` diff --git a/core/net/llsec/noncoresec/noncoresec.c b/core/net/llsec/noncoresec/noncoresec.c new file mode 100644 index 000000000..f9d442651 --- /dev/null +++ b/core/net/llsec/noncoresec/noncoresec.c @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2014, Hasso-Plattner-Institut. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * 802.15.4 security implementation, which uses a network-wide key + * \author + * Konrad Krentz + */ + +/** + * \addtogroup noncoresec + * @{ + */ + +#include "net/llsec/noncoresec/noncoresec.h" +#include "net/llsec/anti-replay.h" +#include "net/llsec/llsec802154.h" +#include "net/llsec/ccm-star-packetbuf.h" +#include "net/mac/frame802154.h" +#include "net/netstack.h" +#include "net/packetbuf.h" +#include "net/nbr-table.h" +#include "net/linkaddr.h" +#include "lib/ccm-star.h" +#include + +#ifdef NONCORESEC_CONF_DECORATED_FRAMER +#define DECORATED_FRAMER NONCORESEC_CONF_DECORATED_FRAMER +#else /* NONCORESEC_CONF_DECORATED_FRAMER */ +#define DECORATED_FRAMER framer_802154 +#endif /* NONCORESEC_CONF_DECORATED_FRAMER */ + +extern const struct framer DECORATED_FRAMER; + +#ifdef NONCORESEC_CONF_SEC_LVL +#define SEC_LVL NONCORESEC_CONF_SEC_LVL +#else /* NONCORESEC_CONF_SEC_LVL */ +#define SEC_LVL 2 +#endif /* NONCORESEC_CONF_SEC_LVL */ + +#define WITH_ENCRYPTION (SEC_LVL & (1 << 2)) +#define MIC_LEN LLSEC802154_MIC_LEN(SEC_LVL) + +#ifdef NONCORESEC_CONF_KEY +#define NONCORESEC_KEY NONCORESEC_CONF_KEY +#else /* NONCORESEC_CONF_KEY */ +#define NONCORESEC_KEY { 0x00 , 0x01 , 0x02 , 0x03 , \ + 0x04 , 0x05 , 0x06 , 0x07 , \ + 0x08 , 0x09 , 0x0A , 0x0B , \ + 0x0C , 0x0D , 0x0E , 0x0F } +#endif /* NONCORESEC_CONF_KEY */ + +#define SECURITY_HEADER_LENGTH 5 + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else /* DEBUG */ +#define PRINTF(...) +#endif /* DEBUG */ + +#if LLSEC802154_USES_AUX_HEADER && SEC_LVL && LLSEC802154_USES_FRAME_COUNTER + +/* network-wide CCM* key */ +static uint8_t key[16] = NONCORESEC_KEY; +NBR_TABLE(struct anti_replay_info, anti_replay_table); + +/*---------------------------------------------------------------------------*/ +static int +aead(uint8_t hdrlen, int forward) +{ + uint8_t totlen; + uint8_t nonce[CCM_STAR_NONCE_LENGTH]; + uint8_t *m; + uint8_t m_len; + uint8_t *a; + uint8_t a_len; + uint8_t *result; + uint8_t generated_mic[MIC_LEN]; + uint8_t *mic; + + ccm_star_packetbuf_set_nonce(nonce, forward); + totlen = packetbuf_totlen(); + a = packetbuf_hdrptr(); +#if WITH_ENCRYPTION + a_len = hdrlen; + m = a + a_len; + m_len = totlen - hdrlen; +#else /* WITH_ENCRYPTION */ + a_len = totlen; + m = NULL; + m_len = 0; +#endif /* WITH_ENCRYPTION */ + + mic = a + totlen; + result = forward ? mic : generated_mic; + + CCM_STAR.aead(nonce, + m, m_len, + a, a_len, + result, MIC_LEN, + forward); + + if(forward) { + packetbuf_set_datalen(packetbuf_datalen() + MIC_LEN); + return 1; + } else { + return (memcmp(generated_mic, mic, MIC_LEN) == 0); + } +} +/*---------------------------------------------------------------------------*/ +static void +add_security_header(void) +{ + packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME); + packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, SEC_LVL); +} +/*---------------------------------------------------------------------------*/ +static void +send(mac_callback_t sent, void *ptr) +{ + add_security_header(); + anti_replay_set_counter(); + NETSTACK_MAC.send(sent, ptr); +} +/*---------------------------------------------------------------------------*/ +static int +create(void) +{ + int result; + + result = DECORATED_FRAMER.create(); + if(result == FRAMER_FAILED) { + return result; + } + + aead(result, 1); + + return result; +} +/*---------------------------------------------------------------------------*/ +static int +parse(void) +{ + int result; + const linkaddr_t *sender; + struct anti_replay_info* info; + + result = DECORATED_FRAMER.parse(); + if(result == FRAMER_FAILED) { + return result; + } + + if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) != SEC_LVL) { + PRINTF("noncoresec: received frame with wrong security level\n"); + return FRAMER_FAILED; + } + sender = packetbuf_addr(PACKETBUF_ADDR_SENDER); + if(linkaddr_cmp(sender, &linkaddr_node_addr)) { + PRINTF("noncoresec: frame from ourselves\n"); + return FRAMER_FAILED; + } + + packetbuf_set_datalen(packetbuf_datalen() - MIC_LEN); + + if(!aead(result, 0)) { + PRINTF("noncoresec: received unauthentic frame %lu\n", + anti_replay_get_counter()); + return FRAMER_FAILED; + } + + info = nbr_table_get_from_lladdr(anti_replay_table, sender); + if(!info) { + info = nbr_table_add_lladdr(anti_replay_table, sender, NBR_TABLE_REASON_LLSEC, NULL); + if(!info) { + PRINTF("noncoresec: could not get nbr_table_item\n"); + return FRAMER_FAILED; + } + + /* + * Locking avoids replay attacks due to removed neighbor table items. + * Unfortunately, an attacker can mount a memory-based DoS attack + * on this by replaying broadcast frames from other network parts. + * However, this is not an issue as long as the network size does not + * exceed NBR_TABLE_MAX_NEIGHBORS. + * + * To avoid locking, we could swap anti-replay information + * to external flash. Locking is also unnecessary when using + * pairwise session keys, as done in coresec. + */ + if(!nbr_table_lock(anti_replay_table, info)) { + nbr_table_remove(anti_replay_table, info); + PRINTF("noncoresec: could not lock\n"); + return FRAMER_FAILED; + } + + anti_replay_init_info(info); + } else { + if(anti_replay_was_replayed(info)) { + PRINTF("noncoresec: received replayed frame %lu\n", + anti_replay_get_counter()); + return FRAMER_FAILED; + } + } + + return result; +} +/*---------------------------------------------------------------------------*/ +static void +input(void) +{ + NETSTACK_NETWORK.input(); +} +/*---------------------------------------------------------------------------*/ +static int +length(void) +{ + add_security_header(); + return DECORATED_FRAMER.length() + MIC_LEN; +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + CCM_STAR.set_key(key); + nbr_table_register(anti_replay_table, NULL); +} +/*---------------------------------------------------------------------------*/ +const struct llsec_driver noncoresec_driver = { + "noncoresec", + init, + send, + input +}; +/*---------------------------------------------------------------------------*/ +const struct framer noncoresec_framer = { + length, + create, + parse +}; +/*---------------------------------------------------------------------------*/ +#endif /* LLSEC802154_USES_AUX_HEADER && SEC_LVL && LLSEC802154_USES_FRAME_COUNTER */ + +/** @} */ diff --git a/core/net/llsec/noncoresec/noncoresec.h b/core/net/llsec/noncoresec/noncoresec.h new file mode 100644 index 000000000..c5fe3d43f --- /dev/null +++ b/core/net/llsec/noncoresec/noncoresec.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014, Hasso-Plattner-Institut. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * 802.15.4 security implementation, which uses a network-wide key + * \author + * Konrad Krentz + */ + +/** + * \addtogroup llsec + * @{ + */ + +/** + * \defgroup noncoresec LLSEC driver using a network-wide key (NONCORESEC) + * + * Noncompromise-resilient 802.15.4 security + * + * @{ + */ + +#ifndef NONCORESEC_H_ +#define NONCORESEC_H_ + +#include "net/llsec/llsec.h" + +extern const struct llsec_driver noncoresec_driver; +extern const struct framer noncoresec_framer; + +#endif /* NONCORESEC_H_ */ + +/** @} */ +/** @} */ diff --git a/core/net/llsec/nullsec.c b/core/net/llsec/nullsec.c new file mode 100644 index 000000000..e4bd4ca2d --- /dev/null +++ b/core/net/llsec/nullsec.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013, Hasso-Plattner-Institut. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Insecure link layer security driver. + * \author + * Konrad Krentz + */ + +/** + * \addtogroup nullsec + * @{ + */ + +#include "net/llsec/nullsec.h" +#include "net/mac/frame802154.h" +#include "net/netstack.h" +#include "net/packetbuf.h" + +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + +} +/*---------------------------------------------------------------------------*/ +static void +send(mac_callback_t sent, void *ptr) +{ + packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME); + NETSTACK_MAC.send(sent, ptr); +} +/*---------------------------------------------------------------------------*/ +static void +input(void) +{ + NETSTACK_NETWORK.input(); +} +/*---------------------------------------------------------------------------*/ +const struct llsec_driver nullsec_driver = { + "nullsec", + init, + send, + input +}; +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/examples/sensinode/sensors/sensors-example.h b/core/net/llsec/nullsec.h similarity index 77% rename from examples/sensinode/sensors/sensors-example.h rename to core/net/llsec/nullsec.h index 432d25073..30488e5d4 100644 --- a/examples/sensinode/sensors/sensors-example.h +++ b/core/net/llsec/nullsec.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Loughborough University - Computer Science + * Copyright (c) 2013, Hasso-Plattner-Institut. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,27 +27,37 @@ * SUCH DAMAGE. * * This file is part of the Contiki operating system. + * */ /** * \file - * Header file for the sensors example. Must be included by the - * sensing node as well as the monitor node. - * + * Insecure link layer security driver. * \author - * George Oikonomou - + * Konrad Krentz */ -#ifndef SENSORSTEST_H_ -#define SENSORSTEST_H_ +/** + * \addtogroup llsec + * @{ + */ -#define BATTERY_RIME_CHANNEL 222 +/** + * \defgroup nullsec LLSEC driver with zero security (NULLSEC) + * + * Insecure link layer security driver. + * + * @{ + */ -/* This is what our PDU looks like */ -struct sensor_data { - int vdd; - int bat; -}; +#ifndef NULLSEC_H_ +#define NULLSEC_H_ +#include "net/llsec/llsec.h" -#endif /* SENSORSTEST_H_ */ +extern const struct llsec_driver nullsec_driver; + +#endif /* NULLSEC_H_ */ + +/** @} */ +/** @} */ diff --git a/core/net/mac/contikimac/contikimac-framer.c b/core/net/mac/contikimac/contikimac-framer.c new file mode 100644 index 000000000..b25aa2e45 --- /dev/null +++ b/core/net/mac/contikimac/contikimac-framer.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Creates and parses the ContikiMAC header. + * \author + * Konrad Krentz + */ + +#include "net/mac/contikimac/contikimac-framer.h" +#include "net/packetbuf.h" +#include "net/netstack.h" +#include + +#define CONTIKIMAC_ID 0x00 + +/* SHORTEST_PACKET_SIZE is the shortest packet that ContikiMAC + allows. Packets have to be a certain size to be able to be detected + by two consecutive CCA checks, and here is where we define this + shortest size. + Padded packets will have the wrong ipv6 checksum unless CONTIKIMAC_HEADER + is used (on both sides) and the receiver will ignore them. + With no header, reduce to transmit a proper multicast RPL DIS. */ +#ifdef CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE +#define SHORTEST_PACKET_SIZE CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE +#else /* CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE */ +#define SHORTEST_PACKET_SIZE 43 +#endif /* CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE */ + +#ifdef CONTIKIMAC_FRAMER_CONF_DECORATED_FRAMER +#define DECORATED_FRAMER CONTIKIMAC_FRAMER_CONF_DECORATED_FRAMER +#else /* CONTIKIMAC_FRAMER_CONF_DECORATED_FRAMER */ +#define DECORATED_FRAMER framer_802154 +#endif /* CONTIKIMAC_FRAMER_CONF_DECORATED_FRAMER */ + +extern const struct framer DECORATED_FRAMER; + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +static void pad(void); + +/* 2-byte header for recovering padded packets. + Wireshark will not understand such packets at present. */ +struct hdr { + uint8_t id; + uint8_t len; +}; + +/*---------------------------------------------------------------------------*/ +static int +hdr_length(void) +{ + return DECORATED_FRAMER.length() + sizeof(struct hdr); +} +/*---------------------------------------------------------------------------*/ +static int +create(void) +{ + struct hdr *chdr; + int hdr_len; + + if(packetbuf_hdralloc(sizeof(struct hdr)) == 0) { + PRINTF("contikimac-framer: too large header\n"); + return FRAMER_FAILED; + } + chdr = packetbuf_hdrptr(); + chdr->id = CONTIKIMAC_ID; + chdr->len = packetbuf_datalen(); + pad(); + + hdr_len = DECORATED_FRAMER.create(); + if(hdr_len < 0) { + PRINTF("contikimac-framer: decorated framer failed\n"); + return FRAMER_FAILED; + } + + packetbuf_compact(); + + return hdr_len + sizeof(struct hdr); +} +/*---------------------------------------------------------------------------*/ +static void +pad(void) +{ + int transmit_len; + uint8_t *ptr; + uint8_t zeroes_count; + + transmit_len = packetbuf_totlen() + hdr_length(); + if(transmit_len < SHORTEST_PACKET_SIZE) { + /* Padding required */ + zeroes_count = SHORTEST_PACKET_SIZE - transmit_len; + ptr = packetbuf_dataptr(); + memset(ptr + packetbuf_datalen(), 0, zeroes_count); + packetbuf_set_datalen(packetbuf_datalen() + zeroes_count); + } +} +/*---------------------------------------------------------------------------*/ +static int +parse(void) +{ + int hdr_len; + struct hdr *chdr; + + hdr_len = DECORATED_FRAMER.parse(); + if(hdr_len < 0) { + return FRAMER_FAILED; + } + + chdr = packetbuf_dataptr(); + if(chdr->id != CONTIKIMAC_ID) { + PRINTF("contikimac-framer: CONTIKIMAC_ID is missing\n"); + return FRAMER_FAILED; + } + + if(!packetbuf_hdrreduce(sizeof(struct hdr))) { + PRINTF("contikimac-framer: packetbuf_hdrreduce failed\n"); + return FRAMER_FAILED; + } + + packetbuf_set_datalen(chdr->len); + + return hdr_len + sizeof(struct hdr); +} +/*---------------------------------------------------------------------------*/ +const struct framer contikimac_framer = { + hdr_length, + create, + parse +}; +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/bus.h b/core/net/mac/contikimac/contikimac-framer.h similarity index 81% rename from cpu/cc2430/dev/bus.h rename to core/net/mac/contikimac/contikimac-framer.h index aa15cf0bd..ea9429997 100644 --- a/cpu/cc2430/dev/bus.h +++ b/core/net/mac/contikimac/contikimac-framer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Swedish Institute of Computer Science. + * Copyright (c) 2010, Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,22 +32,16 @@ /** * \file - * A brief description of what this file is. + * Creates and parses the ContikiMAC header. * \author - * Adam Dunkels + * Konrad Krentz */ +#ifndef CONTIKIMAC_FRAMER_H_ +#define CONTIKIMAC_FRAMER_H_ -#ifndef BUS_H_ -#define BUS_H_ +#include "net/mac/framer.h" -#include "cc2430_sfr.h" -#include "8051def.h" -#include "contiki-conf.h" +extern const struct framer contikimac_framer; -#define inline - -void bus_init(void); -void clock_ISR( void ) __interrupt (ST_VECTOR); - -#endif /* BUS_H_ */ +#endif /* CONTIKIMAC_FRAMER_H_ */ diff --git a/core/net/mac/contikimac/contikimac.c b/core/net/mac/contikimac/contikimac.c index 7c27d7fb5..47e2b5733 100644 --- a/core/net/mac/contikimac/contikimac.c +++ b/core/net/mac/contikimac/contikimac.c @@ -61,13 +61,6 @@ #else /* CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION */ #define WITH_PHASE_OPTIMIZATION 1 #endif /* CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION */ -/* Two byte header added to allow recovery of padded short packets */ -/* Wireshark will not understand such packets at present */ -#ifdef CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER -#define WITH_CONTIKIMAC_HEADER CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER -#else -#define WITH_CONTIKIMAC_HEADER 1 -#endif /* More aggressive radio sleeping when channel is busy with other traffic */ #ifndef WITH_FAST_SLEEP #define WITH_FAST_SLEEP 1 @@ -90,15 +83,6 @@ #define WITH_PHASE_OPTIMIZATION 0 #endif -#if WITH_CONTIKIMAC_HEADER -#define CONTIKIMAC_ID 0x00 - -struct hdr { - uint8_t id; - uint8_t len; -}; -#endif /* WITH_CONTIKIMAC_HEADER */ - /* CYCLE_TIME for channel cca checks, in rtimer ticks. */ #ifdef CONTIKIMAC_CONF_CYCLE_TIME #define CYCLE_TIME (CONTIKIMAC_CONF_CYCLE_TIME) @@ -122,7 +106,11 @@ static int we_are_receiving_burst = 0; /* INTER_PACKET_DEADLINE is the maximum time a receiver waits for the next packet of a burst when FRAME_PENDING is set. */ +#ifdef CONTIKIMAC_CONF_INTER_PACKET_DEADLINE +#define INTER_PACKET_DEADLINE CONTIKIMAC_CONF_INTER_PACKET_DEADLINE +#else #define INTER_PACKET_DEADLINE CLOCK_SECOND / 32 +#endif /* ContikiMAC performs periodic channel checks. Each channel check consists of two or more CCA checks. CCA_COUNT_MAX is the number of @@ -152,11 +140,15 @@ static int we_are_receiving_burst = 0; /* CCA_SLEEP_TIME is the time between two successive CCA checks. */ /* Add 1 when rtimer ticks are coarse */ +#ifdef CONTIKIMAC_CONF_CCA_SLEEP_TIME +#define CCA_SLEEP_TIME CONTIKIMAC_CONF_CCA_SLEEP_TIME +#else #if RTIMER_ARCH_SECOND > 8000 #define CCA_SLEEP_TIME RTIMER_ARCH_SECOND / 2000 #else #define CCA_SLEEP_TIME (RTIMER_ARCH_SECOND / 2000) + 1 -#endif +#endif /* RTIMER_ARCH_SECOND > 8000 */ +#endif /* CONTIKIMAC_CONF_CCA_SLEEP_TIME */ /* CHECK_TIME is the total time it takes to perform CCA_COUNT_MAX CCAs. */ @@ -169,17 +161,30 @@ static int we_are_receiving_burst = 0; /* LISTEN_TIME_AFTER_PACKET_DETECTED is the time that we keep checking for activity after a potential packet has been detected by a CCA check. */ +#ifdef CONTIKIMAC_CONF_LISTEN_TIME_AFTER_PACKET_DETECTED +#define LISTEN_TIME_AFTER_PACKET_DETECTED CONTIKIMAC_CONF_LISTEN_TIME_AFTER_PACKET_DETECTED +#else #define LISTEN_TIME_AFTER_PACKET_DETECTED RTIMER_ARCH_SECOND / 80 +#endif /* MAX_SILENCE_PERIODS is the maximum amount of periods (a period is CCA_CHECK_TIME + CCA_SLEEP_TIME) that we allow to be silent before we turn of the radio. */ +#ifdef CONTIKIMAC_CONF_MAX_SILENCE_PERIODS +#define MAX_SILENCE_PERIODS CONTIKIMAC_CONF_MAX_SILENCE_PERIODS +#else #define MAX_SILENCE_PERIODS 5 +#endif /* MAX_NONACTIVITY_PERIODS is the maximum number of periods we allow the radio to be turned on without any packet being received, when WITH_FAST_SLEEP is enabled. */ +#ifdef CONTIKIMAC_CONF_MAX_NONACTIVITY_PERIODS +#define MAX_NONACTIVITY_PERIODS CONTIKIMAC_CONF_MAX_NONACTIVITY_PERIODS +#else #define MAX_NONACTIVITY_PERIODS 10 +#endif + @@ -189,7 +194,11 @@ static int we_are_receiving_burst = 0; /* GUARD_TIME is the time before the expected phase of a neighbor that a transmitted should begin transmitting packets. */ +#ifdef CONTIKIMAC_CONF_GUARD_TIME +#define GUARD_TIME CONTIKIMAC_CONF_GUARD_TIME +#else #define GUARD_TIME 10 * CHECK_TIME + CHECK_TIME_TX +#endif /* INTER_PACKET_INTERVAL is the interval between two successive packet transmissions */ #ifdef CONTIKIMAC_CONF_INTER_PACKET_INTERVAL @@ -209,22 +218,17 @@ static int we_are_receiving_burst = 0; /* MAX_PHASE_STROBE_TIME is the time that we transmit repeated packets to a neighbor for which we have a phase lock. */ -#define MAX_PHASE_STROBE_TIME RTIMER_ARCH_SECOND / 60 - - -/* SHORTEST_PACKET_SIZE is the shortest packet that ContikiMAC - allows. Packets have to be a certain size to be able to be detected - by two consecutive CCA checks, and here is where we define this - shortest size. - Padded packets will have the wrong ipv6 checksum unless CONTIKIMAC_HEADER - is used (on both sides) and the receiver will ignore them. - With no header, reduce to transmit a proper multicast RPL DIS. */ -#ifdef CONTIKIMAC_CONF_SHORTEST_PACKET_SIZE -#define SHORTEST_PACKET_SIZE CONTIKIMAC_CONF_SHORTEST_PACKET_SIZE +#ifdef CONTIKIMAC_CONF_MAX_PHASE_STROBE_TIME +#define MAX_PHASE_STROBE_TIME CONTIKIMAC_CONF_MAX_PHASE_STROBE_TIME #else -#define SHORTEST_PACKET_SIZE 43 +#define MAX_PHASE_STROBE_TIME RTIMER_ARCH_SECOND / 60 #endif +#ifdef CONTIKIMAC_CONF_SEND_SW_ACK +#define CONTIKIMAC_SEND_SW_ACK CONTIKIMAC_CONF_SEND_SW_ACK +#else +#define CONTIKIMAC_SEND_SW_ACK 0 +#endif #define ACK_LEN 3 @@ -260,10 +264,6 @@ static struct compower_activity current_packet; #define DEFAULT_STREAM_TIME (4 * CYCLE_TIME) -#ifndef MIN -#define MIN(a, b) ((a) < (b)? (a) : (b)) -#endif /* MIN */ - #if CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT static struct timer broadcast_rate_timer; static int broadcast_rate_counter; @@ -290,20 +290,24 @@ off(void) } /*---------------------------------------------------------------------------*/ static volatile rtimer_clock_t cycle_start; +static void powercycle_wrapper(struct rtimer *t, void *ptr); static char powercycle(struct rtimer *t, void *ptr); static void schedule_powercycle(struct rtimer *t, rtimer_clock_t time) { int r; + rtimer_clock_t now; if(contikimac_is_on) { - if(RTIMER_CLOCK_LT(RTIMER_TIME(t) + time, RTIMER_NOW() + 2)) { - time = RTIMER_NOW() - RTIMER_TIME(t) + 2; + time += RTIMER_TIME(t); + now = RTIMER_NOW(); + if(RTIMER_CLOCK_LT(time, now + RTIMER_GUARD_TIME)) { + time = now + RTIMER_GUARD_TIME; } - r = rtimer_set(t, RTIMER_TIME(t) + time, 1, - (void (*)(struct rtimer *, void *))powercycle, NULL); + r = rtimer_set(t, time, 1, powercycle_wrapper, NULL); + if(r != RTIMER_OK) { PRINTF("schedule_powercycle: could not set rtimer\n"); } @@ -314,15 +318,16 @@ static void schedule_powercycle_fixed(struct rtimer *t, rtimer_clock_t fixed_time) { int r; + rtimer_clock_t now; if(contikimac_is_on) { - if(RTIMER_CLOCK_LT(fixed_time, RTIMER_NOW() + 1)) { - fixed_time = RTIMER_NOW() + 1; + now = RTIMER_NOW(); + if(RTIMER_CLOCK_LT(fixed_time, now + RTIMER_GUARD_TIME)) { + fixed_time = now + RTIMER_GUARD_TIME; } - r = rtimer_set(t, fixed_time, 1, - (void (*)(struct rtimer *, void *))powercycle, NULL); + r = rtimer_set(t, fixed_time, 1, powercycle_wrapper, NULL); if(r != RTIMER_OK) { PRINTF("schedule_powercycle: could not set rtimer\n"); } @@ -354,6 +359,14 @@ powercycle_turn_radio_on(void) } } /*---------------------------------------------------------------------------*/ +volatile uint8_t mcusleepcycle=16; + +static void +powercycle_wrapper(struct rtimer *t, void *ptr) +{ + powercycle(t, ptr); +} +/*---------------------------------------------------------------------------*/ static char powercycle(struct rtimer *t, void *ptr) { @@ -479,12 +492,14 @@ powercycle(struct rtimer *t, void *ptr) be blocked until a packet is detected */ #if RDC_CONF_MCU_SLEEP static uint8_t sleepcycle; - if((sleepcycle++ < 16) && !we_are_sending && !radio_is_on) { + if((sleepcycle++ < mcusleepcycle) && !we_are_sending && !radio_is_on) { rtimer_arch_sleep(CYCLE_TIME - (RTIMER_NOW() - cycle_start)); } else { sleepcycle = 0; +#ifndef RDC_CONF_PT_YIELD_OFF schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start); PT_YIELD(&pt); +#endif } #else schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start); @@ -523,23 +538,22 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, int is_receiver_awake) { rtimer_clock_t t0; - rtimer_clock_t encounter_time = 0; - int strobes; - uint8_t got_strobe_ack = 0; - int hdrlen, len; - uint8_t is_broadcast = 0; #if WITH_PHASE_OPTIMIZATION + rtimer_clock_t encounter_time = 0; uint8_t is_known_receiver = 0; #endif + int strobes; + uint8_t got_strobe_ack = 0; + uint8_t is_broadcast = 0; uint8_t collisions; int transmit_len; int ret; uint8_t contikimac_was_on; +#if !RDC_CONF_HARDWARE_ACK + int len; uint8_t seqno; -#if WITH_CONTIKIMAC_HEADER - struct hdr *chdr; -#endif /* WITH_CONTIKIMAC_HEADER */ - +#endif + /* Exit if RDC and radio were explicitly turned off */ if(!contikimac_is_on && !contikimac_keep_radio_on) { PRINTF("contikimac: radio is turned off\n"); @@ -555,7 +569,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, /* If NETSTACK_CONF_BRIDGE_MODE is set, assume PACKETBUF_ADDR_SENDER is already set. */ packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &linkaddr_node_addr); #endif - if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) { + if(packetbuf_holds_broadcast()) { is_broadcast = 1; PRINTDEBUG("contikimac: send broadcast\n"); @@ -563,7 +577,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, return MAC_TX_COLLISION; } } else { -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 PRINTDEBUG("contikimac: send unicast to %02x%02x:%02x%02x:%02x%02x:%02x%02x\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1], @@ -573,71 +587,24 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[5], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[6], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[7]); -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ PRINTDEBUG("contikimac: send unicast to %u.%u\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1]); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ } - packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); -#if WITH_CONTIKIMAC_HEADER - hdrlen = packetbuf_totlen(); - if(packetbuf_hdralloc(sizeof(struct hdr)) == 0) { - /* Failed to allocate space for contikimac header */ - PRINTF("contikimac: send failed, too large header\n"); - return MAC_TX_ERR_FATAL; + if(!packetbuf_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED)) { + packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); + if(NETSTACK_FRAMER.create() < 0) { + PRINTF("contikimac: framer failed\n"); + return MAC_TX_ERR_FATAL; + } } - chdr = packetbuf_hdrptr(); - chdr->id = CONTIKIMAC_ID; - chdr->len = hdrlen; - /* Create the MAC header for the data packet. */ - hdrlen = NETSTACK_FRAMER.create(); - if(hdrlen < 0) { - /* Failed to send */ - PRINTF("contikimac: send failed, too large header\n"); - packetbuf_hdr_remove(sizeof(struct hdr)); - return MAC_TX_ERR_FATAL; - } - hdrlen += sizeof(struct hdr); -#else - /* Create the MAC header for the data packet. */ - hdrlen = NETSTACK_FRAMER.create(); - if(hdrlen < 0) { - /* Failed to send */ - PRINTF("contikimac: send failed, too large header\n"); - return MAC_TX_ERR_FATAL; - } -#endif - - /* Make sure that the packet is longer or equal to the shortest - packet length. */ transmit_len = packetbuf_totlen(); - if(transmit_len < SHORTEST_PACKET_SIZE) { - /* Pad with zeroes */ - uint8_t *ptr; - ptr = packetbuf_dataptr(); - memset(ptr + packetbuf_datalen(), 0, SHORTEST_PACKET_SIZE - packetbuf_totlen()); - - PRINTF("contikimac: shorter than shortest (%d)\n", packetbuf_totlen()); - transmit_len = SHORTEST_PACKET_SIZE; - } - - - packetbuf_compact(); - -#ifdef NETSTACK_ENCRYPT - NETSTACK_ENCRYPT(); -#endif /* NETSTACK_ENCRYPT */ - - transmit_len = packetbuf_totlen(); - NETSTACK_RADIO.prepare(packetbuf_hdrptr(), transmit_len); - - /* Remove the MAC-layer header since it will be recreated next time around. */ - packetbuf_hdr_remove(hdrlen); - + if(!is_broadcast && !is_receiver_awake) { #if WITH_PHASE_OPTIMIZATION ret = phase_wait(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), @@ -726,11 +693,11 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, or rx cycle */ on(); } + seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO); #endif watchdog_periodic(); t0 = RTIMER_NOW(); - seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO); for(strobes = 0, collisions = 0; got_strobe_ack == 0 && collisions == 0 && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + STROBE_TIME); strobes++) { @@ -745,15 +712,20 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, } #endif /* WITH_PHASE_OPTIMIZATION */ +#if !RDC_CONF_HARDWARE_ACK len = 0; +#endif { rtimer_clock_t wt; - rtimer_clock_t txtime; - int ret; - - txtime = RTIMER_NOW(); - ret = NETSTACK_RADIO.transmit(transmit_len); +#if WITH_PHASE_OPTIMIZATION + rtimer_clock_t txtime = RTIMER_NOW(); +#endif +#if RDC_CONF_HARDWARE_ACK + int ret = NETSTACK_RADIO.transmit(transmit_len); +#else + NETSTACK_RADIO.transmit(transmit_len); +#endif #if RDC_CONF_HARDWARE_ACK /* For radios that block in the transmit routine and detect the @@ -761,7 +733,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, if(ret == RADIO_TX_OK) { if(!is_broadcast) { got_strobe_ack = 1; +#if WITH_PHASE_OPTIMIZATION encounter_time = txtime; +#endif break; } } else if (ret == RADIO_TX_NOACK) { @@ -786,7 +760,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, len = NETSTACK_RADIO.read(ackbuf, ACK_LEN); if(len == ACK_LEN && seqno == ackbuf[ACK_LEN - 1]) { got_strobe_ack = 1; +#if WITH_PHASE_OPTIMIZATION encounter_time = txtime; +#endif break; } else { PRINTF("contikimac: collisions while sending\n"); @@ -863,32 +839,57 @@ qsend_packet(mac_callback_t sent, void *ptr) static void qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list) { - struct rdc_buf_list *curr = buf_list; + struct rdc_buf_list *curr; struct rdc_buf_list *next; int ret; int is_receiver_awake; + int pending; - if(curr == NULL) { + if(buf_list == NULL) { return; } /* Do not send during reception of a burst */ if(we_are_receiving_burst) { /* Prepare the packetbuf for callback */ - queuebuf_to_packetbuf(curr->buf); + queuebuf_to_packetbuf(buf_list->buf); /* Return COLLISION so the MAC may try again later */ mac_call_sent_callback(sent, ptr, MAC_TX_COLLISION, 1); return; } + + /* Create and secure frames in advance */ + curr = buf_list; + do { + next = list_item_next(curr); + queuebuf_to_packetbuf(curr->buf); + if(!packetbuf_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED)) { + /* create and secure this frame */ + if(next != NULL) { + packetbuf_set_attr(PACKETBUF_ATTR_PENDING, 1); + } + packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); + if(NETSTACK_FRAMER.create() < 0) { + PRINTF("contikimac: framer failed\n"); + mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1); + return; + } + + packetbuf_set_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED, 1); + queuebuf_update_from_packetbuf(curr->buf); + } + curr = next; + } while(next != NULL); + /* The receiver needs to be awoken before we send */ is_receiver_awake = 0; + curr = buf_list; do { /* A loop sending a burst of packets from buf_list */ next = list_item_next(curr); /* Prepare the packetbuf */ queuebuf_to_packetbuf(curr->buf); - if(next != NULL) { - packetbuf_set_attr(PACKETBUF_ATTR_PENDING, 1); - } + + pending = packetbuf_attr(PACKETBUF_ATTR_PENDING); /* Send the current packet */ ret = send_packet(sent, ptr, curr, is_receiver_awake); @@ -906,7 +907,7 @@ qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list) /* The transmission failed, we stop the burst */ next = NULL; } - } while(next != NULL); + } while((next != NULL) && pending); } /*---------------------------------------------------------------------------*/ /* Timer callback triggered when receiving a burst, after having @@ -923,35 +924,34 @@ static void input_packet(void) { static struct ctimer ct; + int duplicate = 0; + +#if CONTIKIMAC_SEND_SW_ACK + int original_datalen; + uint8_t *original_dataptr; + + original_datalen = packetbuf_datalen(); + original_dataptr = packetbuf_dataptr(); +#endif + if(!we_are_receiving_burst) { off(); } + if(packetbuf_datalen() == ACK_LEN) { + /* Ignore ack packets */ + PRINTF("ContikiMAC: ignored ack\n"); + return; + } + /* printf("cycle_start 0x%02x 0x%02x\n", cycle_start, cycle_start % CYCLE_TIME);*/ -#ifdef NETSTACK_DECRYPT - NETSTACK_DECRYPT(); -#endif /* NETSTACK_DECRYPT */ - if(packetbuf_totlen() > 0 && NETSTACK_FRAMER.parse() >= 0) { - -#if WITH_CONTIKIMAC_HEADER - struct hdr *chdr; - chdr = packetbuf_dataptr(); - if(chdr->id != CONTIKIMAC_ID) { - PRINTF("contikimac: failed to parse hdr (%u)\n", packetbuf_totlen()); - return; - } - packetbuf_hdrreduce(sizeof(struct hdr)); - packetbuf_set_datalen(chdr->len); -#endif /* WITH_CONTIKIMAC_HEADER */ - if(packetbuf_datalen() > 0 && packetbuf_totlen() > 0 && (linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_node_addr) || - linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), - &linkaddr_null))) { + packetbuf_holds_broadcast())) { /* This is a regular packet that is destined to us or to the broadcast address. */ @@ -967,13 +967,16 @@ input_packet(void) ctimer_stop(&ct); } +#if RDC_WITH_DUPLICATE_DETECTION /* Check for duplicate packet. */ - if(mac_sequence_is_duplicate()) { + duplicate = mac_sequence_is_duplicate(); + if(duplicate) { /* Drop the packet. */ - /* printf("Drop duplicate ContikiMAC layer packet\n");*/ - return; + PRINTF("contikimac: Drop duplicate\n"); + } else { + mac_sequence_register_seqno(); } - mac_sequence_register_seqno(); +#endif /* RDC_WITH_DUPLICATE_DETECTION */ #if CONTIKIMAC_CONF_COMPOWER /* Accumulate the power consumption for the packet reception. */ @@ -990,7 +993,30 @@ input_packet(void) #endif /* CONTIKIMAC_CONF_COMPOWER */ PRINTDEBUG("contikimac: data (%u)\n", packetbuf_datalen()); - NETSTACK_MAC.input(); + +#if CONTIKIMAC_SEND_SW_ACK + { + frame802154_t info154; + frame802154_parse(original_dataptr, original_datalen, &info154); + if(info154.fcf.frame_type == FRAME802154_DATAFRAME && + info154.fcf.ack_required != 0 && + linkaddr_cmp((linkaddr_t *)&info154.dest_addr, + &linkaddr_node_addr)) { + uint8_t ackdata[ACK_LEN] = {0, 0, 0}; + + we_are_sending = 1; + ackdata[0] = FRAME802154_ACKFRAME; + ackdata[1] = 0; + ackdata[2] = info154.seq; + NETSTACK_RADIO.send(ackdata, ACK_LEN); + we_are_sending = 0; + } + } +#endif /* CONTIKIMAC_SEND_SW_ACK */ + + if(!duplicate) { + NETSTACK_MAC.input(); + } return; } else { PRINTDEBUG("contikimac: data not for us\n"); @@ -1006,8 +1032,7 @@ init(void) radio_is_on = 0; PT_INIT(&pt); - rtimer_set(&rt, RTIMER_NOW() + CYCLE_TIME, 1, - (void (*)(struct rtimer *, void *))powercycle, NULL); + rtimer_set(&rt, RTIMER_NOW() + CYCLE_TIME, 1, powercycle_wrapper, NULL); contikimac_is_on = 1; @@ -1023,8 +1048,7 @@ turn_on(void) if(contikimac_is_on == 0) { contikimac_is_on = 1; contikimac_keep_radio_on = 0; - rtimer_set(&rt, RTIMER_NOW() + CYCLE_TIME, 1, - (void (*)(struct rtimer *, void *))powercycle, NULL); + rtimer_set(&rt, RTIMER_NOW() + CYCLE_TIME, 1, powercycle_wrapper, NULL); } return 1; } diff --git a/core/net/mac/csma.c b/core/net/mac/csma.c index c07f5887a..eea86b4e8 100644 --- a/core/net/mac/csma.c +++ b/core/net/mac/csma.c @@ -63,26 +63,35 @@ #define PRINTF(...) #endif /* DEBUG */ -#ifndef CSMA_MAX_BACKOFF_EXPONENT -#ifdef CSMA_CONF_MAX_BACKOFF_EXPONENT -#define CSMA_MAX_BACKOFF_EXPONENT CSMA_CONF_MAX_BACKOFF_EXPONENT -#else -#define CSMA_MAX_BACKOFF_EXPONENT 3 -#endif /* CSMA_CONF_MAX_BACKOFF_EXPONENT */ -#endif /* CSMA_MAX_BACKOFF_EXPONENT */ +/* Constants of the IEEE 802.15.4 standard */ -#ifndef CSMA_MAX_MAC_TRANSMISSIONS -#ifdef CSMA_CONF_MAX_MAC_TRANSMISSIONS -#define CSMA_MAX_MAC_TRANSMISSIONS CSMA_CONF_MAX_MAC_TRANSMISSIONS +/* macMinBE: Initial backoff exponent. Range 0--CSMA_MAX_BE */ +#ifdef CSMA_CONF_MIN_BE +#define CSMA_MIN_BE CSMA_CONF_MIN_BE #else -#define CSMA_MAX_MAC_TRANSMISSIONS 3 -#endif /* CSMA_CONF_MAX_MAC_TRANSMISSIONS */ -#endif /* CSMA_MAX_MAC_TRANSMISSIONS */ +#define CSMA_MIN_BE 0 +#endif -#if CSMA_MAX_MAC_TRANSMISSIONS < 1 -#error CSMA_CONF_MAX_MAC_TRANSMISSIONS must be at least 1. -#error Change CSMA_CONF_MAX_MAC_TRANSMISSIONS in contiki-conf.h or in your Makefile. -#endif /* CSMA_CONF_MAX_MAC_TRANSMISSIONS < 1 */ +/* macMaxBE: Maximum backoff exponent. Range 3--8 */ +#ifdef CSMA_CONF_MAX_BE +#define CSMA_MAX_BE CSMA_CONF_MAX_BE +#else +#define CSMA_MAX_BE 4 +#endif + +/* macMaxCSMABackoffs: Maximum number of backoffs in case of channel busy/collision. Range 0--5 */ +#ifdef CSMA_CONF_MAX_BACKOFF +#define CSMA_MAX_BACKOFF CSMA_CONF_MAX_BACKOFF +#else +#define CSMA_MAX_BACKOFF 5 +#endif + +/* macMaxFrameRetries: Maximum number of re-transmissions attampts. Range 0--7 */ +#ifdef CSMA_CONF_MAX_FRAME_RETRIES +#define CSMA_MAX_MAX_FRAME_RETRIES CSMA_CONF_MAX_FRAME_RETRIES +#else +#define CSMA_MAX_MAX_FRAME_RETRIES 7 +#endif /* Packet metadata */ struct qbuf_metadata { @@ -97,7 +106,7 @@ struct neighbor_queue { linkaddr_t addr; struct ctimer transmit_timer; uint8_t transmissions; - uint8_t collisions, deferrals; + uint8_t collisions; LIST_STRUCT(queued_packet_list); }; @@ -108,6 +117,13 @@ struct neighbor_queue { #define CSMA_MAX_NEIGHBOR_QUEUES 2 #endif /* CSMA_CONF_MAX_NEIGHBOR_QUEUES */ +/* The maximum number of pending packet per neighbor */ +#ifdef CSMA_CONF_MAX_PACKET_PER_NEIGHBOR +#define CSMA_MAX_PACKET_PER_NEIGHBOR CSMA_CONF_MAX_PACKET_PER_NEIGHBOR +#else +#define CSMA_MAX_PACKET_PER_NEIGHBOR MAX_QUEUED_PACKETS +#endif /* CSMA_CONF_MAX_PACKET_PER_NEIGHBOR */ + #define MAX_QUEUED_PACKETS QUEUEBUF_NUM MEMB(neighbor_memb, struct neighbor_queue, CSMA_MAX_NEIGHBOR_QUEUES); MEMB(packet_memb, struct rdc_buf_list, MAX_QUEUED_PACKETS); @@ -116,7 +132,6 @@ LIST(neighbor_list); static void packet_sent(void *ptr, int status, int num_transmissions); static void transmit_packet_list(void *ptr); - /*---------------------------------------------------------------------------*/ static struct neighbor_queue * neighbor_queue_from_addr(const linkaddr_t *addr) @@ -132,18 +147,18 @@ neighbor_queue_from_addr(const linkaddr_t *addr) } /*---------------------------------------------------------------------------*/ static clock_time_t -default_timebase(void) +backoff_period(void) { clock_time_t time; /* The retransmission time must be proportional to the channel check interval of the underlying radio duty cycling layer. */ time = NETSTACK_RDC.channel_check_interval(); - /* If the radio duty cycle has no channel check interval (i.e., it - does not turn the radio off), we make the retransmission time - proportional to the configured MAC channel check rate. */ + /* If the radio duty cycle has no channel check interval, we use + * the default in IEEE 802.15.4: aUnitBackoffPeriod which is + * 20 symbols i.e. 320 usec. That is, 1/3125 second. */ if(time == 0) { - time = CLOCK_SECOND / NETSTACK_RDC_CHANNEL_CHECK_RATE; + time = MAX(CLOCK_SECOND / 3125, 1); } return time; } @@ -164,7 +179,27 @@ transmit_packet_list(void *ptr) } /*---------------------------------------------------------------------------*/ static void -free_packet(struct neighbor_queue *n, struct rdc_buf_list *p) +schedule_transmission(struct neighbor_queue *n) +{ + clock_time_t delay; + int backoff_exponent; /* BE in IEEE 802.15.4 */ + + backoff_exponent = MIN(n->collisions, CSMA_MAX_BE); + + /* Compute max delay as per IEEE 802.15.4: 2^BE-1 backoff periods */ + delay = ((1 << backoff_exponent) - 1) * backoff_period(); + if(delay > 0) { + /* Pick a time for next transmission */ + delay = random_rand() % delay; + } + + PRINTF("csma: scheduling transmission in %u ticks, NB=%u, BE=%u\n", + (unsigned)delay, n->collisions, backoff_exponent); + ctimer_set(&n->transmit_timer, delay, transmit_packet_list, n); +} +/*---------------------------------------------------------------------------*/ +static void +free_packet(struct neighbor_queue *n, struct rdc_buf_list *p, int status) { if(p != NULL) { /* Remove packet from list and deallocate */ @@ -173,16 +208,14 @@ free_packet(struct neighbor_queue *n, struct rdc_buf_list *p) queuebuf_free(p->buf); memb_free(&metadata_memb, p->ptr); memb_free(&packet_memb, p); - PRINTF("csma: free_queued_packet, queue length %d\n", - list_length(n->queued_packet_list)); + PRINTF("csma: free_queued_packet, queue length %d, free packets %d\n", + list_length(n->queued_packet_list), memb_numfree(&packet_memb)); if(list_head(n->queued_packet_list) != NULL) { /* There is a next packet. We reset current tx information */ n->transmissions = 0; - n->collisions = 0; - n->deferrals = 0; - /* Set a timer for next transmissions */ - ctimer_set(&n->transmit_timer, default_timebase(), - transmit_packet_list, n); + n->collisions = CSMA_MIN_BE; + /* Schedule next transmissions */ + schedule_transmission(n); } else { /* This was the last packet in the queue, we free the neighbor */ ctimer_stop(&n->transmit_timer); @@ -193,34 +226,103 @@ free_packet(struct neighbor_queue *n, struct rdc_buf_list *p) } /*---------------------------------------------------------------------------*/ static void +tx_done(int status, struct rdc_buf_list *q, struct neighbor_queue *n) +{ + mac_callback_t sent; + struct qbuf_metadata *metadata; + void *cptr; + + metadata = (struct qbuf_metadata *)q->ptr; + sent = metadata->sent; + cptr = metadata->cptr; + + switch(status) { + case MAC_TX_OK: + PRINTF("csma: rexmit ok %d\n", n->transmissions); + break; + case MAC_TX_COLLISION: + case MAC_TX_NOACK: + PRINTF("csma: drop with status %d after %d transmissions, %d collisions\n", + status, n->transmissions, n->collisions); + break; + default: + PRINTF("csma: rexmit failed %d: %d\n", n->transmissions, status); + break; + } + + free_packet(n, q, status); + mac_call_sent_callback(sent, cptr, status, n->transmissions); +} +/*---------------------------------------------------------------------------*/ +static void +rexmit(struct rdc_buf_list *q, struct neighbor_queue *n) +{ + schedule_transmission(n); + /* This is needed to correctly attribute energy that we spent + transmitting this packet. */ + queuebuf_update_attr_from_packetbuf(q->buf); +} +/*---------------------------------------------------------------------------*/ +static void +collision(struct rdc_buf_list *q, struct neighbor_queue *n, + int num_transmissions) +{ + struct qbuf_metadata *metadata; + + metadata = (struct qbuf_metadata *)q->ptr; + + n->collisions += num_transmissions; + + if(n->collisions > CSMA_MAX_BACKOFF) { + n->collisions = CSMA_MIN_BE; + /* Increment to indicate a next retry */ + n->transmissions++; + } + + if(n->transmissions >= metadata->max_transmissions) { + tx_done(MAC_TX_COLLISION, q, n); + } else { + PRINTF("csma: rexmit collision %d\n", n->transmissions); + rexmit(q, n); + } +} +/*---------------------------------------------------------------------------*/ +static void +noack(struct rdc_buf_list *q, struct neighbor_queue *n, int num_transmissions) +{ + struct qbuf_metadata *metadata; + + metadata = (struct qbuf_metadata *)q->ptr; + + n->collisions = CSMA_MIN_BE; + n->transmissions += num_transmissions; + + if(n->transmissions >= metadata->max_transmissions) { + tx_done(MAC_TX_NOACK, q, n); + } else { + PRINTF("csma: rexmit noack %d\n", n->transmissions); + rexmit(q, n); + } +} +/*---------------------------------------------------------------------------*/ +static void +tx_ok(struct rdc_buf_list *q, struct neighbor_queue *n, int num_transmissions) +{ + n->collisions = CSMA_MIN_BE; + n->transmissions += num_transmissions; + tx_done(MAC_TX_OK, q, n); +} +/*---------------------------------------------------------------------------*/ +static void packet_sent(void *ptr, int status, int num_transmissions) { struct neighbor_queue *n; struct rdc_buf_list *q; - struct qbuf_metadata *metadata; - clock_time_t time = 0; - mac_callback_t sent; - void *cptr; - int num_tx; - int backoff_exponent; - int backoff_transmissions; n = ptr; if(n == NULL) { return; } - switch(status) { - case MAC_TX_OK: - case MAC_TX_NOACK: - n->transmissions += num_transmissions; - break; - case MAC_TX_COLLISION: - n->collisions += num_transmissions; - break; - case MAC_TX_DEFERRED: - n->deferrals += num_transmissions; - break; - } /* Find out what packet this callback refers to */ for(q = list_head(n->queued_packet_list); @@ -231,74 +333,30 @@ packet_sent(void *ptr, int status, int num_transmissions) } } - if(q != NULL) { - metadata = (struct qbuf_metadata *)q->ptr; + if(q == NULL) { + PRINTF("csma: seqno %d not found\n", + packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO)); + return; + } else if(q->ptr == NULL) { + PRINTF("csma: no metadata\n"); + return; + } - if(metadata != NULL) { - sent = metadata->sent; - cptr = metadata->cptr; - num_tx = n->transmissions; - if(status == MAC_TX_COLLISION || - status == MAC_TX_NOACK) { - - /* If the transmission was not performed because of a - collision or noack, we must retransmit the packet. */ - - switch(status) { - case MAC_TX_COLLISION: - PRINTF("csma: rexmit collision %d\n", n->transmissions); - break; - case MAC_TX_NOACK: - PRINTF("csma: rexmit noack %d\n", n->transmissions); - break; - default: - PRINTF("csma: rexmit err %d, %d\n", status, n->transmissions); - } - - /* The retransmission time must be proportional to the channel - check interval of the underlying radio duty cycling layer. */ - time = default_timebase(); - - /* The retransmission time uses a truncated exponential backoff - * so that the interval between the transmissions increase with - * each retransmit. */ - backoff_exponent = num_tx; - - /* Truncate the exponent if needed. */ - if(backoff_exponent > CSMA_MAX_BACKOFF_EXPONENT) { - backoff_exponent = CSMA_MAX_BACKOFF_EXPONENT; - } - - /* Proceed to exponentiation. */ - backoff_transmissions = 1 << backoff_exponent; - - /* Pick a time for next transmission, within the interval: - * [time, time + 2^backoff_exponent * time[ */ - time = time + (random_rand() % (backoff_transmissions * time)); - - if(n->transmissions < metadata->max_transmissions) { - PRINTF("csma: retransmitting with time %lu %p\n", time, q); - ctimer_set(&n->transmit_timer, time, - transmit_packet_list, n); - /* This is needed to correctly attribute energy that we spent - transmitting this packet. */ - queuebuf_update_attr_from_packetbuf(q->buf); - } else { - PRINTF("csma: drop with status %d after %d transmissions, %d collisions\n", - status, n->transmissions, n->collisions); - free_packet(n, q); - mac_call_sent_callback(sent, cptr, status, num_tx); - } - } else { - if(status == MAC_TX_OK) { - PRINTF("csma: rexmit ok %d\n", n->transmissions); - } else { - PRINTF("csma: rexmit failed %d: %d\n", n->transmissions, status); - } - free_packet(n, q); - mac_call_sent_callback(sent, cptr, status, num_tx); - } - } + switch(status) { + case MAC_TX_OK: + tx_ok(q, n, num_transmissions); + break; + case MAC_TX_NOACK: + noack(q, n, num_transmissions); + break; + case MAC_TX_COLLISION: + collision(q, n, num_transmissions); + break; + case MAC_TX_DEFERRED: + break; + default: + tx_done(status, q, n); + break; } } /*---------------------------------------------------------------------------*/ @@ -333,8 +391,7 @@ send_packet(mac_callback_t sent, void *ptr) /* Init neighbor entry */ linkaddr_copy(&n->addr, addr); n->transmissions = 0; - n->collisions = 0; - n->deferrals = 0; + n->collisions = CSMA_MIN_BE; /* Init packet list for this neighbor */ LIST_STRUCT_INIT(n, queued_packet_list); /* Add neighbor to the list */ @@ -344,47 +401,55 @@ send_packet(mac_callback_t sent, void *ptr) if(n != NULL) { /* Add packet to the neighbor's queue */ - q = memb_alloc(&packet_memb); - if(q != NULL) { - q->ptr = memb_alloc(&metadata_memb); - if(q->ptr != NULL) { - q->buf = queuebuf_new_from_packetbuf(); - if(q->buf != NULL) { - struct qbuf_metadata *metadata = (struct qbuf_metadata *)q->ptr; - /* Neighbor and packet successfully allocated */ - if(packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS) == 0) { - /* Use default configuration for max transmissions */ - metadata->max_transmissions = CSMA_MAX_MAC_TRANSMISSIONS; - } else { - metadata->max_transmissions = - packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS); - } - metadata->sent = sent; - metadata->cptr = ptr; + if(list_length(n->queued_packet_list) < CSMA_MAX_PACKET_PER_NEIGHBOR) { + q = memb_alloc(&packet_memb); + if(q != NULL) { + q->ptr = memb_alloc(&metadata_memb); + if(q->ptr != NULL) { + q->buf = queuebuf_new_from_packetbuf(); + if(q->buf != NULL) { + struct qbuf_metadata *metadata = (struct qbuf_metadata *)q->ptr; + /* Neighbor and packet successfully allocated */ + if(packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS) == 0) { + /* Use default configuration for max transmissions */ + metadata->max_transmissions = CSMA_MAX_MAX_FRAME_RETRIES + 1; + } else { + metadata->max_transmissions = + packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS); + } + metadata->sent = sent; + metadata->cptr = ptr; +#if PACKETBUF_WITH_PACKET_TYPE + if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == + PACKETBUF_ATTR_PACKET_TYPE_ACK) { + list_push(n->queued_packet_list, q); + } else +#endif + { + list_add(n->queued_packet_list, q); + } - if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == - PACKETBUF_ATTR_PACKET_TYPE_ACK) { - list_push(n->queued_packet_list, q); - } else { - list_add(n->queued_packet_list, q); - } - - /* If q is the first packet in the neighbor's queue, send asap */ - if(list_head(n->queued_packet_list) == q) { - ctimer_set(&n->transmit_timer, 0, transmit_packet_list, n); - } - return; - } - memb_free(&metadata_memb, q->ptr); - PRINTF("csma: could not allocate queuebuf, dropping packet\n"); + PRINTF("csma: send_packet, queue length %d, free packets %d\n", + list_length(n->queued_packet_list), memb_numfree(&packet_memb)); + /* If q is the first packet in the neighbor's queue, send asap */ + if(list_head(n->queued_packet_list) == q) { + schedule_transmission(n); + } + return; + } + memb_free(&metadata_memb, q->ptr); + PRINTF("csma: could not allocate queuebuf, dropping packet\n"); + } + memb_free(&packet_memb, q); + PRINTF("csma: could not allocate queuebuf, dropping packet\n"); } - memb_free(&packet_memb, q); - PRINTF("csma: could not allocate queuebuf, dropping packet\n"); - } - /* The packet allocation failed. Remove and free neighbor entry if empty. */ - if(list_length(n->queued_packet_list) == 0) { - list_remove(neighbor_list, n); - memb_free(&neighbor_memb, n); + /* The packet allocation failed. Remove and free neighbor entry if empty. */ + if(list_length(n->queued_packet_list) == 0) { + list_remove(neighbor_list, n); + memb_free(&neighbor_memb, n); + } + } else { + PRINTF("csma: Neighbor queue full\n"); } PRINTF("csma: could not allocate packet, dropping packet\n"); } else { @@ -396,7 +461,7 @@ send_packet(mac_callback_t sent, void *ptr) static void input_packet(void) { - NETSTACK_NETWORK.input(); + NETSTACK_LLSEC.input(); } /*---------------------------------------------------------------------------*/ static int diff --git a/core/net/mac/cxmac/cxmac.c b/core/net/mac/cxmac/cxmac.c index 7bb55f227..e07fde3d9 100644 --- a/core/net/mac/cxmac/cxmac.c +++ b/core/net/mac/cxmac/cxmac.c @@ -52,6 +52,7 @@ #include "sys/rtimer.h" #include "contiki-conf.h" +#include "sys/cc.h" #ifdef EXPERIMENT_SETUP #include "experiment-setup.h" @@ -215,10 +216,6 @@ static linkaddr_t is_streaming_to, is_streaming_to_too; static rtimer_clock_t stream_until; #define DEFAULT_STREAM_TIME (RTIMER_ARCH_SECOND) -#ifndef MIN -#define MIN(a, b) ((a) < (b)? (a) : (b)) -#endif /* MIN */ - /*---------------------------------------------------------------------------*/ static void on(void) @@ -433,11 +430,11 @@ send_packet(void) /* If NETSTACK_CONF_BRIDGE_MODE is set, assume PACKETBUF_ADDR_SENDER is already set. */ packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &linkaddr_node_addr); #endif - if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) { + if(packetbuf_holds_broadcast()) { is_broadcast = 1; PRINTDEBUG("cxmac: send broadcast\n"); } else { -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 PRINTDEBUG("cxmac: send unicast to %02x%02x:%02x%02x:%02x%02x:%02x%02x\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1], @@ -451,10 +448,8 @@ send_packet(void) PRINTDEBUG("cxmac: send unicast to %u.%u\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0], packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1]); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ } -/* is_reliable = packetbuf_attr(PACKETBUF_ATTR_RELIABLE) || - packetbuf_attr(PACKETBUF_ATTR_ERELIABLE);*/ len = NETSTACK_FRAMER.create(); strobe_len = len + sizeof(struct cxmac_hdr); if(len < 0 || strobe_len > (int)sizeof(strobe)) { @@ -475,7 +470,7 @@ send_packet(void) return MAC_TX_ERR; } -#if WITH_STREAMING +#if WITH_STREAMING && PACKETBUF_WITH_PACKET_TYPE if(is_streaming == 1 && (linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &is_streaming_to) || @@ -519,7 +514,7 @@ send_packet(void) wait = ((rtimer_clock_t)(e->time - now)) % (DEFAULT_PERIOD); expected = now + wait - 2 * DEFAULT_ON_TIME; -#if WITH_ACK_OPTIMIZATION +#if WITH_ACK_OPTIMIZATION && PACKETBUF_WITH_PACKET_TYPE /* Wait until the receiver is expected to be awake */ if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) != PACKETBUF_ATTR_PACKET_TYPE_ACK && @@ -624,10 +619,16 @@ send_packet(void) /* If we have received the strobe ACK, and we are sending a packet that will need an upper layer ACK (as signified by the PACKETBUF_ATTR_RELIABLE packet attribute), we keep the radio on. */ - if(got_strobe_ack && (packetbuf_attr(PACKETBUF_ATTR_RELIABLE) || - packetbuf_attr(PACKETBUF_ATTR_ERELIABLE) || + if(got_strobe_ack && ( +#if NETSTACK_CONF_WITH_RIME + packetbuf_attr(PACKETBUF_ATTR_RELIABLE) || + packetbuf_attr(PACKETBUF_ATTR_ERELIABLE) || +#endif /* NETSTACK_CONF_WITH_RIME */ +#if PACKETBUF_WITH_PACKET_TYPE packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == - PACKETBUF_ATTR_PACKET_TYPE_STREAM)) { + PACKETBUF_ATTR_PACKET_TYPE_STREAM || +#endif + 0)) { on(); /* Wait for ACK packet */ waiting_for_packet = 1; } else { diff --git a/core/net/mac/frame802154.c b/core/net/mac/frame802154.c index fa7a46962..77727ab47 100644 --- a/core/net/mac/frame802154.c +++ b/core/net/mac/frame802154.c @@ -44,15 +44,12 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * -*/ + */ /* * \brief This file is where the main functions that relate to frame * manipulation will reside. -*/ -/** - * \addtogroup frame802154 - * @{ -*/ + */ + /** * \file * \brief 802.15.4 frame creation and parsing functions @@ -61,15 +58,29 @@ * frame. */ +/** + * \addtogroup frame802154 + * @{ + */ + #include "sys/cc.h" #include "net/mac/frame802154.h" +#include "net/llsec/llsec802154.h" +#include "net/linkaddr.h" #include +/** \brief The 16-bit identifier of the PAN on which the device is + * operating. If this value is 0xffff, the device is not + * associated. + */ +static uint16_t mac_pan_id = IEEE802154_PANID; + /** * \brief Structure that contains the lengths of the various addressing and security fields * in the 802.15.4 header. This structure is used in \ref frame802154_create() */ typedef struct { + uint8_t seqno_len; /**< Length (in bytes) of sequence number field */ uint8_t dest_pid_len; /**< Length (in bytes) of destination PAN ID field */ uint8_t dest_addr_len; /**< Length (in bytes) of destination address field */ uint8_t src_pid_len; /**< Length (in bytes) of source PAN ID field */ @@ -91,57 +102,238 @@ addr_len(uint8_t mode) } } /*----------------------------------------------------------------------------*/ +#if LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_EXPLICIT_KEYS +static uint8_t +get_key_id_len(uint8_t key_id_mode) +{ + switch(key_id_mode) { + case FRAME802154_1_BYTE_KEY_ID_MODE: + return 1; + case FRAME802154_5_BYTE_KEY_ID_MODE: + return 5; + case FRAME802154_9_BYTE_KEY_ID_MODE: + return 9; + default: + return 0; + } +} +#endif /* LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_EXPLICIT_KEYS */ +/*---------------------------------------------------------------------------*/ +/* Get current PAN ID */ +uint16_t +frame802154_get_pan_id(void) +{ + return mac_pan_id; +} +/*---------------------------------------------------------------------------*/ +/* Set current PAN ID */ +void +frame802154_set_pan_id(uint16_t pan_id) +{ + mac_pan_id = pan_id; +} +/*----------------------------------------------------------------------------*/ +/* Tells whether a given Frame Control Field indicates a frame with + * source PANID and/or destination PANID */ +void +frame802154_has_panid(frame802154_fcf_t *fcf, int *has_src_pan_id, int *has_dest_pan_id) +{ + int src_pan_id = 0; + int dest_pan_id = 0; + + if(fcf == NULL) { + return; + } + + if(fcf->frame_version == FRAME802154_IEEE802154E_2012) { + if(!fcf->panid_compression) { + /* Compressed PAN ID == no PAN ID at all */ + if(fcf->dest_addr_mode == fcf->dest_addr_mode) { + /* No address or both addresses: include destination PAN ID */ + dest_pan_id = 1; + } else if(fcf->dest_addr_mode) { + /* Only dest address, include dest PAN ID */ + dest_pan_id = 1; + } else if(fcf->src_addr_mode) { + /* Only src address, include src PAN ID */ + src_pan_id = 1; + } + } + if(fcf->dest_addr_mode == 0 && fcf->dest_addr_mode == 1) { + /* No address included, include dest PAN ID conditionally */ + if(!fcf->panid_compression) { + dest_pan_id = 1; + } + } + /* Remove the following rule the day rows 2 and 3 from table 2a are fixed: */ + if(fcf->dest_addr_mode == 0 && fcf->dest_addr_mode == 0) { + /* Not meaningful, we include a PAN ID iff the compress flag is set, but + * this is what the standard currently stipulates */ + dest_pan_id = fcf->panid_compression; + } + } else { + /* No PAN ID in ACK */ + if(fcf->frame_type != FRAME802154_ACKFRAME) { + if(!fcf->panid_compression && fcf->src_addr_mode & 3) { + /* If compressed, don't inclue source PAN ID */ + src_pan_id = 1; + } + if(fcf->dest_addr_mode & 3) { + dest_pan_id = 1; + } + } + } + + if(has_src_pan_id != NULL) { + *has_src_pan_id = src_pan_id; + } + if(has_dest_pan_id != NULL) { + *has_dest_pan_id = dest_pan_id; + } +} +/*---------------------------------------------------------------------------*/ +/* Check if the destination PAN ID, if any, matches ours */ +int +frame802154_check_dest_panid(frame802154_t *frame) +{ + int has_dest_panid; + + if(frame == NULL) { + return 0; + } + frame802154_has_panid(&frame->fcf, NULL, &has_dest_panid); + if(has_dest_panid + && frame->dest_pid != frame802154_get_pan_id() + && frame->dest_pid != FRAME802154_BROADCASTPANDID) { + /* Packet to another PAN */ + return 0; + } + return 1; +} +/*---------------------------------------------------------------------------*/ +/* Check is the address is a broadcast address, whatever its size */ +int +frame802154_is_broadcast_addr(uint8_t mode, uint8_t *addr) +{ + int i = mode == FRAME802154_SHORTADDRMODE ? 2 : 8; + while(i-- > 0) { + if(addr[i] != 0xff) { + return 0; + } + } + return 1; +} +/*---------------------------------------------------------------------------*/ +/* Check and extract source and destination linkaddr from frame */ +int +frame802154_extract_linkaddr(frame802154_t *frame, + linkaddr_t *source_address, linkaddr_t *dest_address) +{ + int src_addr_len; + int dest_addr_len; + + if(frame == NULL) { + return 0; + } + /* Check and extract source address */ + src_addr_len = frame->fcf.src_addr_mode ? + ((frame->fcf.src_addr_mode == FRAME802154_SHORTADDRMODE) ? 2 : 8) : 0; + if(src_addr_len == 0 || frame802154_is_broadcast_addr(frame->fcf.src_addr_mode, frame->src_addr)) { + /* Broadcast address */ + if(source_address != NULL) { + linkaddr_copy(source_address, &linkaddr_null); + } + } else { + /* Unicast address */ + if(src_addr_len != LINKADDR_SIZE) { + /* Destination address has a size we can not handle */ + return 0; + } + if(source_address != NULL) { + linkaddr_copy(source_address, (linkaddr_t *)frame->src_addr); + } + } + + /* Check and extract destination address */ + dest_addr_len = frame->fcf.dest_addr_mode ? + ((frame->fcf.dest_addr_mode == FRAME802154_SHORTADDRMODE) ? 2 : 8) : 0; + if(dest_addr_len == 0 || frame802154_is_broadcast_addr(frame->fcf.dest_addr_mode, frame->dest_addr)) { + /* Broadcast address */ + if(dest_address != NULL) { + linkaddr_copy(dest_address, &linkaddr_null); + } + } else { + /* Unicast address */ + if(dest_addr_len != LINKADDR_SIZE) { + /* Destination address has a size we can not handle */ + return 0; + } + if(dest_address != NULL) { + linkaddr_copy(dest_address, (linkaddr_t *)frame->dest_addr); + } + } + + return 1; +} +/*----------------------------------------------------------------------------*/ static void field_len(frame802154_t *p, field_length_t *flen) { + int has_src_panid; + int has_dest_panid; + /* init flen to zeros */ memset(flen, 0, sizeof(field_length_t)); /* Determine lengths of each field based on fcf and other args */ - if(p->fcf.dest_addr_mode & 3) { - flen->dest_pid_len = 2; + if((p->fcf.sequence_number_suppression & 1) == 0) { + flen->seqno_len = 1; } - if(p->fcf.src_addr_mode & 3) { + + /* IEEE802.15.4e changes the meaning of PAN ID Compression (see Table 2a). + * In this case, we leave the decision whether to compress PAN ID or not + * up to the caller. */ + if(p->fcf.frame_version < FRAME802154_IEEE802154E_2012) { + /* Set PAN ID compression bit if src pan id matches dest pan id. */ + if(p->fcf.dest_addr_mode & 3 && p->fcf.src_addr_mode & 3 && + p->src_pid == p->dest_pid) { + p->fcf.panid_compression = 1; + } else { + p->fcf.panid_compression = 0; + } + } + + frame802154_has_panid(&p->fcf, &has_src_panid, &has_dest_panid); + + if(has_src_panid) { flen->src_pid_len = 2; } - /* Set PAN ID compression bit if src pan id matches dest pan id. */ - if(p->fcf.dest_addr_mode & 3 && p->fcf.src_addr_mode & 3 && - p->src_pid == p->dest_pid) { - p->fcf.panid_compression = 1; - - /* compressed header, only do dest pid */ - flen->src_pid_len = 0; - } else { - p->fcf.panid_compression = 0; + if(has_dest_panid) { + flen->dest_pid_len = 2; } /* determine address lengths */ flen->dest_addr_len = addr_len(p->fcf.dest_addr_mode & 3); flen->src_addr_len = addr_len(p->fcf.src_addr_mode & 3); +#if LLSEC802154_USES_AUX_HEADER /* Aux security header */ if(p->fcf.security_enabled & 1) { - /* TODO Aux security header not yet implemented */ -#if 0 - switch(p->aux_hdr.security_control.key_id_mode) { - case 0: - flen->aux_sec_len = 5; /* minimum value */ - break; - case 1: - flen->aux_sec_len = 6; - break; - case 2: - flen->aux_sec_len = 10; - break; - case 3: - flen->aux_sec_len = 14; - break; - default: - break; + flen->aux_sec_len = 1; /* FCF + possibly frame counter and key ID */ + if(p->aux_hdr.security_control.frame_counter_suppression == 0) { + if(p->aux_hdr.security_control.frame_counter_size == 1) { + flen->aux_sec_len += 5; + } else { + flen->aux_sec_len += 4; + } } -#endif +#if LLSEC802154_USES_EXPLICIT_KEYS + flen->aux_sec_len += get_key_id_len(p->aux_hdr.security_control.key_id_mode); +#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ + ; } +#endif /* LLSEC802154_USES_AUX_HEADER */ } /*----------------------------------------------------------------------------*/ /** @@ -152,14 +344,14 @@ field_len(frame802154_t *p, field_length_t *flen) * frame to send. * * \return The length of the frame header. -*/ + */ int frame802154_hdrlen(frame802154_t *p) { field_length_t flen; field_len(p, &flen); - return 3 + flen.dest_pid_len + flen.dest_addr_len + - flen.src_pid_len + flen.src_addr_len + flen.aux_sec_len; + return 2 + flen.seqno_len + flen.dest_pid_len + flen.dest_addr_len + + flen.src_pid_len + flen.src_addr_len + flen.aux_sec_len; } /*----------------------------------------------------------------------------*/ /** @@ -171,70 +363,91 @@ frame802154_hdrlen(frame802154_t *p) * * \param buf Pointer to the buffer to use for the frame. * - * \param buf_len The length of the buffer to use for the frame. - * - * \return The length of the frame header or 0 if there was - * insufficient space in the buffer for the frame headers. -*/ + * \return The length of the frame header + */ int -frame802154_create(frame802154_t *p, uint8_t *buf, int buf_len) +frame802154_create(frame802154_t *p, uint8_t *buf) { int c; field_length_t flen; - uint8_t *tx_frame_buffer; uint8_t pos; +#if LLSEC802154_USES_EXPLICIT_KEYS + uint8_t key_id_mode; +#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ field_len(p, &flen); - if(3 + flen.dest_pid_len + flen.dest_addr_len + - flen.src_pid_len + flen.src_addr_len + flen.aux_sec_len > buf_len) { - /* Too little space for headers. */ - return 0; - } - /* OK, now we have field lengths. Time to actually construct */ - /* the outgoing frame, and store it in tx_frame_buffer */ - tx_frame_buffer = buf; - tx_frame_buffer[0] = (p->fcf.frame_type & 7) | + /* the outgoing frame, and store it in buf */ + buf[0] = (p->fcf.frame_type & 7) | ((p->fcf.security_enabled & 1) << 3) | ((p->fcf.frame_pending & 1) << 4) | ((p->fcf.ack_required & 1) << 5) | ((p->fcf.panid_compression & 1) << 6); - tx_frame_buffer[1] = ((p->fcf.dest_addr_mode & 3) << 2) | + buf[1] = ((p->fcf.sequence_number_suppression & 1)) | + ((p->fcf.ie_list_present & 1)) << 1 | + ((p->fcf.dest_addr_mode & 3) << 2) | ((p->fcf.frame_version & 3) << 4) | ((p->fcf.src_addr_mode & 3) << 6); - /* sequence number */ - tx_frame_buffer[2] = p->seq; - pos = 3; + pos = 2; + + /* Sequence number */ + if(flen.seqno_len == 1) { + buf[pos++] = p->seq; + } /* Destination PAN ID */ if(flen.dest_pid_len == 2) { - tx_frame_buffer[pos++] = p->dest_pid & 0xff; - tx_frame_buffer[pos++] = (p->dest_pid >> 8) & 0xff; + buf[pos++] = p->dest_pid & 0xff; + buf[pos++] = (p->dest_pid >> 8) & 0xff; } /* Destination address */ for(c = flen.dest_addr_len; c > 0; c--) { - tx_frame_buffer[pos++] = p->dest_addr[c - 1]; + buf[pos++] = p->dest_addr[c - 1]; } /* Source PAN ID */ if(flen.src_pid_len == 2) { - tx_frame_buffer[pos++] = p->src_pid & 0xff; - tx_frame_buffer[pos++] = (p->src_pid >> 8) & 0xff; + buf[pos++] = p->src_pid & 0xff; + buf[pos++] = (p->src_pid >> 8) & 0xff; } /* Source address */ for(c = flen.src_addr_len; c > 0; c--) { - tx_frame_buffer[pos++] = p->src_addr[c - 1]; + buf[pos++] = p->src_addr[c - 1]; } - +#if LLSEC802154_USES_AUX_HEADER /* Aux header */ if(flen.aux_sec_len) { - /* TODO Aux security header not yet implemented */ -/* pos += flen.aux_sec_len; */ + buf[pos++] = p->aux_hdr.security_control.security_level +#if LLSEC802154_USES_EXPLICIT_KEYS + | (p->aux_hdr.security_control.key_id_mode << 3) +#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ + | (p->aux_hdr.security_control.frame_counter_suppression << 5) + | (p->aux_hdr.security_control.frame_counter_size << 6) + ; + if(p->aux_hdr.security_control.frame_counter_suppression == 0) { + /* We support only 4-byte counters */ + memcpy(buf + pos, p->aux_hdr.frame_counter.u8, 4); + pos += 4; + if(p->aux_hdr.security_control.frame_counter_size == 1) { + pos++; + } + } + +#if LLSEC802154_USES_EXPLICIT_KEYS + key_id_mode = p->aux_hdr.security_control.key_id_mode; + if(key_id_mode) { + c = (key_id_mode - 1) * 4; + memcpy(buf + pos, p->aux_hdr.key_source.u8, c); + pos += c; + buf[pos++] = p->aux_hdr.key_index; + } +#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ } +#endif /* LLSEC802154_USES_AUX_HEADER */ return (int)pos; } @@ -254,8 +467,13 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf) uint8_t *p; frame802154_fcf_t fcf; int c; + int has_src_panid; + int has_dest_panid; +#if LLSEC802154_USES_EXPLICIT_KEYS + uint8_t key_id_mode; +#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ - if(len < 3) { + if(len < 2) { return 0; } @@ -268,20 +486,32 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf) fcf.ack_required = (p[0] >> 5) & 1; fcf.panid_compression = (p[0] >> 6) & 1; + fcf.sequence_number_suppression = p[1] & 1; + fcf.ie_list_present = (p[1] >> 1) & 1; fcf.dest_addr_mode = (p[1] >> 2) & 3; fcf.frame_version = (p[1] >> 4) & 3; fcf.src_addr_mode = (p[1] >> 6) & 3; /* copy fcf and seqNum */ memcpy(&pf->fcf, &fcf, sizeof(frame802154_fcf_t)); - pf->seq = p[2]; - p += 3; /* Skip first three bytes */ + p += 2; /* Skip first two bytes */ + + if(fcf.sequence_number_suppression == 0) { + pf->seq = p[0]; + p++; + } + + frame802154_has_panid(&fcf, &has_src_panid, &has_dest_panid); /* Destination address, if any */ if(fcf.dest_addr_mode) { - /* Destination PAN */ - pf->dest_pid = p[0] + (p[1] << 8); - p += 2; + if(has_dest_panid) { + /* Destination PAN */ + pf->dest_pid = p[0] + (p[1] << 8); + p += 2; + } else { + pf->dest_pid = 0; + } /* Destination address */ /* l = addr_len(fcf.dest_addr_mode); */ @@ -308,9 +538,12 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf) /* Source address, if any */ if(fcf.src_addr_mode) { /* Source PAN */ - if(!fcf.panid_compression) { + if(has_src_panid) { pf->src_pid = p[0] + (p[1] << 8); p += 2; + if(!has_dest_panid) { + pf->dest_pid = pf->src_pid; + } } else { pf->src_pid = pf->dest_pid; } @@ -337,10 +570,36 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf) pf->src_pid = 0; } +#if LLSEC802154_USES_AUX_HEADER if(fcf.security_enabled) { - /* TODO aux security header, not yet implemented */ -/* return 0; */ + pf->aux_hdr.security_control.security_level = p[0] & 7; +#if LLSEC802154_USES_EXPLICIT_KEYS + pf->aux_hdr.security_control.key_id_mode = (p[0] >> 3) & 3; +#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ + pf->aux_hdr.security_control.frame_counter_suppression = p[0] >> 5; + pf->aux_hdr.security_control.frame_counter_size = p[0] >> 6; + p += 1; + + if(pf->aux_hdr.security_control.frame_counter_suppression == 0) { + memcpy(pf->aux_hdr.frame_counter.u8, p, 4); + p += 4; + if(pf->aux_hdr.security_control.frame_counter_size == 1) { + p ++; + } + } + +#if LLSEC802154_USES_EXPLICIT_KEYS + key_id_mode = pf->aux_hdr.security_control.key_id_mode; + if(key_id_mode) { + c = (key_id_mode - 1) * 4; + memcpy(pf->aux_hdr.key_source.u8, p, c); + p += c; + pf->aux_hdr.key_index = p[0]; + p += 1; + } +#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ } +#endif /* LLSEC802154_USES_AUX_HEADER */ /* header length */ c = p - data; diff --git a/core/net/mac/frame802154.h b/core/net/mac/frame802154.h index 87358f6d9..defb64b53 100644 --- a/core/net/mac/frame802154.h +++ b/core/net/mac/frame802154.h @@ -41,10 +41,15 @@ * 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. -*/ + */ /** - * \addtogroup frame802154 + * \addtogroup net + * @{ + */ + +/** + * \defgroup frame802154 802.15.4 frame creation and parsing * @{ */ /** @@ -54,8 +59,7 @@ * This file converts to and from a structure to a packed 802.15.4 * frame. * -*/ - + */ /* Includes */ #ifndef FRAME_802154_H @@ -66,9 +70,21 @@ #ifdef IEEE802154_CONF_PANID #define IEEE802154_PANID IEEE802154_CONF_PANID -#else +#else /* IEEE802154_CONF_PANID */ #define IEEE802154_PANID 0xABCD -#endif +#endif /* IEEE802154_CONF_PANID */ + +#ifdef FRAME802154_CONF_VERSION +#define FRAME802154_VERSION FRAME802154_CONF_VERSION +#else /* FRAME802154_CONF_VERSION */ +#define FRAME802154_VERSION FRAME802154_IEEE802154_2006 +#endif /* FRAME802154_CONF_VERSION */ + +#ifdef FRAME802154_CONF_SUPPR_SEQNO +#define FRAME802154_SUPPR_SEQNO FRAME802154_CONF_SUPPR_SEQNO +#else /* FRAME802154_CONF_SUPPR_SEQNO */ +#define FRAME802154_SUPPR_SEQNO 0 +#endif /* FRAME802154_CONF_SUPPR_SEQNO */ /* Macros & Defines */ @@ -93,12 +109,23 @@ #define FRAME802154_BROADCASTADDR (0xFFFF) #define FRAME802154_BROADCASTPANDID (0xFFFF) -#define FRAME802154_IEEE802154_2003 (0x00) -#define FRAME802154_IEEE802154_2006 (0x01) +#define FRAME802154_IEEE802154_2003 (0x00) +#define FRAME802154_IEEE802154_2006 (0x01) +#define FRAME802154_IEEE802154E_2012 (0x02) -#define FRAME802154_SECURITY_LEVEL_NONE (0) -#define FRAME802154_SECURITY_LEVEL_128 (3) +#define FRAME802154_SECURITY_LEVEL_NONE (0) +#define FRAME802154_SECURITY_LEVEL_MIC_32 (1) +#define FRAME802154_SECURITY_LEVEL_MIC_64 (2) +#define FRAME802154_SECURITY_LEVEL_MIC_128 (3) +#define FRAME802154_SECURITY_LEVEL_ENC (4) +#define FRAME802154_SECURITY_LEVEL_ENC_MIC_32 (5) +#define FRAME802154_SECURITY_LEVEL_ENC_MIC_64 (6) +#define FRAME802154_SECURITY_LEVEL_ENC_MIC_128 (7) +#define FRAME802154_IMPLICIT_KEY (0) +#define FRAME802154_1_BYTE_KEY_ID_MODE (1) +#define FRAME802154_5_BYTE_KEY_ID_MODE (2) +#define FRAME802154_9_BYTE_KEY_ID_MODE (3) /** * @brief The IEEE 802.15.4 frame has a number of constant/fixed fields that @@ -111,7 +138,7 @@ * 3. Addressing fields - 4 - 20 bytes - Variable * 4. Aux security header - 0 - 14 bytes - Variable * 5. CRC - 2 bytes - Fixed -*/ + */ /** * \brief Defines the bitfields of the frame control field (FCF). @@ -122,7 +149,9 @@ typedef struct { uint8_t frame_pending; /**< 1 bit. True if sender has more data to send */ uint8_t ack_required; /**< 1 bit. Is an ack frame required? */ uint8_t panid_compression; /**< 1 bit. Is this a compressed header? */ - /* uint8_t reserved; */ /**< 3 bit. Unused bits */ + /* uint8_t reserved; */ /**< 1 bit. Unused bit */ + uint8_t sequence_number_suppression; /**< 1 bit. Does the header omit sequence number?, see 802.15.4e */ + uint8_t ie_list_present; /**< 1 bit. Does the header contain Information Elements?, see 802.15.4e */ uint8_t dest_addr_mode; /**< 2 bit. Destination address mode, see 802.15.4 */ uint8_t frame_version; /**< 2 bit. 802.15.4 frame version */ uint8_t src_addr_mode; /**< 2 bit. Source address mode, see 802.15.4 */ @@ -132,14 +161,28 @@ typedef struct { typedef struct { uint8_t security_level; /**< 3 bit. security level */ uint8_t key_id_mode; /**< 2 bit. Key identifier mode */ + uint8_t frame_counter_suppression; /**< 1 bit. Frame counter suppression */ + uint8_t frame_counter_size; /**< 1 bit. Frame counter size (0: 4 bytes, 1: 5 bytes) */ uint8_t reserved; /**< 3 bit. Reserved bits */ } frame802154_scf_t; +typedef union { + uint32_t u32; + uint16_t u16[2]; + uint8_t u8[4]; +} frame802154_frame_counter_t; + +typedef union { + uint16_t u16[4]; + uint8_t u8[8]; +} frame802154_key_source_t; + /** \brief 802.15.4 Aux security header */ typedef struct { - frame802154_scf_t security_control; /**< Security control bitfield */ - uint32_t frame_counter; /**< Frame counter, used for security */ - uint8_t key[9]; /**< The key itself, or an index to the key */ + frame802154_scf_t security_control; /**< Security control bitfield */ + frame802154_frame_counter_t frame_counter; /**< Frame counter, used for security */ + frame802154_key_source_t key_source; /**< Key Source subfield */ + uint8_t key_index; /**< Key Index subfield */ } frame802154_aux_hdr_t; /** \brief Parameters used by the frame802154_create() function. These @@ -147,23 +190,41 @@ typedef struct { * specification for details. */ typedef struct { - frame802154_fcf_t fcf; /**< Frame control field */ - uint8_t seq; /**< Sequence number */ - uint16_t dest_pid; /**< Destination PAN ID */ - uint8_t dest_addr[8]; /**< Destination address */ - uint16_t src_pid; /**< Source PAN ID */ - uint8_t src_addr[8]; /**< Source address */ - frame802154_aux_hdr_t aux_hdr; /**< Aux security header */ - uint8_t *payload; /**< Pointer to 802.15.4 frame payload */ - int payload_len; /**< Length of payload field */ + /* The fields dest_addr and src_addr must come first to ensure they are aligned to the + * CPU word size. Needed as they are accessed directly as linkaddr_t*. Note we cannot use + * the type linkaddr_t directly here, as we always need 8 bytes, not LINKADDR_SIZE bytes. */ + uint8_t dest_addr[8]; /**< Destination address */ + uint8_t src_addr[8]; /**< Source address */ + frame802154_fcf_t fcf; /**< Frame control field */ + uint8_t seq; /**< Sequence number */ + uint16_t dest_pid; /**< Destination PAN ID */ + uint16_t src_pid; /**< Source PAN ID */ + frame802154_aux_hdr_t aux_hdr; /**< Aux security header */ + uint8_t *payload; /**< Pointer to 802.15.4 payload */ + int payload_len; /**< Length of payload field */ } frame802154_t; /* Prototypes */ int frame802154_hdrlen(frame802154_t *p); -int frame802154_create(frame802154_t *p, uint8_t *buf, int buf_len); +int frame802154_create(frame802154_t *p, uint8_t *buf); int frame802154_parse(uint8_t *data, int length, frame802154_t *pf); +/* Get current PAN ID */ +uint16_t frame802154_get_pan_id(void); +/* Set current PAN ID */ +void frame802154_set_pan_id(uint16_t pan_id); +/* Tells whether a given Frame Control Field indicates a frame with + * source PANID and/or destination PANID */ +void frame802154_has_panid(frame802154_fcf_t *fcf, int *has_src_pan_id, int *has_dest_pan_id); +/* Check if the destination PAN ID, if any, matches ours */ +int frame802154_check_dest_panid(frame802154_t *frame); +/* Check is the address is a broadcast address, whatever its size */ +int frame802154_is_broadcast_addr(uint8_t mode, uint8_t *addr); +/* Check and extract source and destination linkaddr from frame */ +int frame802154_extract_linkaddr(frame802154_t *frame, linkaddr_t *source_address, linkaddr_t *dest_address); + /** @} */ #endif /* FRAME_802154_H */ /** @} */ +/** @} */ diff --git a/core/net/mac/frame802154e-ie.c b/core/net/mac/frame802154e-ie.c new file mode 100644 index 000000000..db0118889 --- /dev/null +++ b/core/net/mac/frame802154e-ie.c @@ -0,0 +1,585 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * IEEE 802.15.4e Information Element (IE) creation and parsing. + * \author + * Simon Duquennoy + */ + +#include +#include "net/mac/frame802154e-ie.h" + +#define DEBUG DEBUG_NONE +#include "net/net-debug.h" + +/* c.f. IEEE 802.15.4e Table 4b */ +enum ieee802154e_header_ie_id { + HEADER_IE_LE_CSL = 0x1a, + HEADER_IE_LE_RIT, + HEADER_IE_DSME_PAN_DESCRIPTOR, + HEADER_IE_RZ_TIME, + HEADER_IE_ACK_NACK_TIME_CORRECTION, + HEADER_IE_GACK, + HEADER_IE_LOW_LATENCY_NETWORK_INFO, + HEADER_IE_LIST_TERMINATION_1 = 0x7e, + HEADER_IE_LIST_TERMINATION_2 = 0x7f, +}; + +/* c.f. IEEE 802.15.4e Table 4c */ +enum ieee802154e_payload_ie_id { + PAYLOAD_IE_ESDU = 0, + PAYLOAD_IE_MLME, + PAYLOAD_IE_LIST_TERMINATION = 0xf, +}; + +/* c.f. IEEE 802.15.4e Table 4d */ +enum ieee802154e_mlme_short_subie_id { + MLME_SHORT_IE_TSCH_SYNCHRONIZATION = 0x1a, + MLME_SHORT_IE_TSCH_SLOFTRAME_AND_LINK, + MLME_SHORT_IE_TSCH_TIMESLOT, + MLME_SHORT_IE_TSCH_HOPPING_TIMING, + MLME_SHORT_IE_TSCH_EB_FILTER, + MLME_SHORT_IE_TSCH_MAC_METRICS_1, + MLME_SHORT_IE_TSCH_MAC_METRICS_2, +}; + +/* c.f. IEEE 802.15.4e Table 4e */ +enum ieee802154e_mlme_long_subie_id { + MLME_LONG_IE_TSCH_CHANNEL_HOPPING_SEQUENCE = 0x9, +}; + +#define WRITE16(buf, val) \ + do { ((uint8_t *)(buf))[0] = (val) & 0xff; \ + ((uint8_t *)(buf))[1] = ((val) >> 8) & 0xff; } while(0); + +#define READ16(buf, var) \ + (var) = ((uint8_t *)(buf))[0] | ((uint8_t *)(buf))[1] << 8 + +/* Create a header IE 2-byte descriptor */ +static void +create_header_ie_descriptor(uint8_t *buf, uint8_t element_id, int ie_len) +{ + uint16_t ie_desc; + /* Header IE descriptor: b0-6: len, b7-14: element id:, b15: type: 0 */ + ie_desc = (ie_len & 0x7f) + ((element_id & 0xff) << 7); + WRITE16(buf, ie_desc); +} + +/* Create a payload IE 2-byte descriptor */ +static void +create_payload_ie_descriptor(uint8_t *buf, uint8_t group_id, int ie_len) +{ + uint16_t ie_desc; + /* MLME Long IE descriptor: b0-10: len, b11-14: group id:, b15: type: 1 */ + ie_desc = (ie_len & 0x07ff) + ((group_id & 0x0f) << 11) + (1 << 15); + WRITE16(buf, ie_desc); +} + +/* Create a MLME short IE 2-byte descriptor */ +static void +create_mlme_short_ie_descriptor(uint8_t *buf, uint8_t sub_id, int ie_len) +{ + uint16_t ie_desc; + /* MLME Short IE descriptor: b0-7: len, b8-14: sub id:, b15: type: 0 */ + ie_desc = (ie_len & 0xff) + ((sub_id & 0x7f) << 8); + WRITE16(buf, ie_desc); +} + +/* Create a MLME long IE 2-byte descriptor */ +static void +create_mlme_long_ie_descriptor(uint8_t *buf, uint8_t sub_id, int ie_len) +{ + uint16_t ie_desc; + /* MLME Long IE descriptor: b0-10: len, b11-14: sub id:, b15: type: 1 */ + ie_desc = (ie_len & 0x07ff) + ((sub_id & 0x0f) << 11) + (1 << 15); + WRITE16(buf, ie_desc); +} + +/* Header IE. ACK/NACK time correction. Used in enhanced ACKs */ +int +frame80215e_create_ie_header_ack_nack_time_correction(uint8_t *buf, int len, + struct ieee802154_ies *ies) +{ + int ie_len = 2; + if(len >= 2 + ie_len && ies != NULL) { + int16_t drift_us; + uint16_t time_sync_field; + drift_us = ies->ie_time_correction; + time_sync_field = drift_us & 0x0fff; + if(ies->ie_is_nack) { + time_sync_field |= 0x8000; + } + WRITE16(buf+2, time_sync_field); + create_header_ie_descriptor(buf, HEADER_IE_ACK_NACK_TIME_CORRECTION, ie_len); + return 2 + ie_len; + } else { + return -1; + } +} + +/* Header IE. List termination 1 (Signals the end of the Header IEs when + * followed by payload IEs) */ +int +frame80215e_create_ie_header_list_termination_1(uint8_t *buf, int len, + struct ieee802154_ies *ies) +{ + int ie_len = 0; + if(len >= 2 + ie_len && ies != NULL) { + create_header_ie_descriptor(buf, HEADER_IE_LIST_TERMINATION_1, 0); + return 2 + ie_len; + } else { + return -1; + } +} + +/* Header IE. List termination 2 (Signals the end of the Header IEs when + * followed by an unformatted payload) */ +int +frame80215e_create_ie_header_list_termination_2(uint8_t *buf, int len, + struct ieee802154_ies *ies) +{ + int ie_len = 0; + if(len >= 2 + ie_len && ies != NULL) { + create_header_ie_descriptor(buf, HEADER_IE_LIST_TERMINATION_2, 0); + return 2 + ie_len; + } else { + return -1; + } +} + +/* Payload IE. List termination */ +int +frame80215e_create_ie_payload_list_termination(uint8_t *buf, int len, + struct ieee802154_ies *ies) +{ + int ie_len = 0; + if(len >= 2 + ie_len && ies != NULL) { + create_payload_ie_descriptor(buf, PAYLOAD_IE_LIST_TERMINATION, 0); + return 2 + ie_len; + } else { + return -1; + } +} + +/* Payload IE. MLME. Used to nest sub-IEs */ +int +frame80215e_create_ie_mlme(uint8_t *buf, int len, + struct ieee802154_ies *ies) +{ + int ie_len = 0; + if(len >= 2 + ie_len && ies != NULL) { + /* The length of the outer MLME IE is the total length of sub-IEs */ + create_payload_ie_descriptor(buf, PAYLOAD_IE_MLME, ies->ie_mlme_len); + return 2 + ie_len; + } else { + return -1; + } +} + +/* MLME sub-IE. TSCH synchronization. Used in EBs: ASN and join priority */ +int +frame80215e_create_ie_tsch_synchronization(uint8_t *buf, int len, + struct ieee802154_ies *ies) +{ + int ie_len = 6; + if(len >= 2 + ie_len && ies != NULL) { + buf[2] = ies->ie_asn.ls4b; + buf[3] = ies->ie_asn.ls4b >> 8; + buf[4] = ies->ie_asn.ls4b >> 16; + buf[5] = ies->ie_asn.ls4b >> 24; + buf[6] = ies->ie_asn.ms1b; + buf[7] = ies->ie_join_priority; + create_mlme_short_ie_descriptor(buf, MLME_SHORT_IE_TSCH_SYNCHRONIZATION, ie_len); + return 2 + ie_len; + } else { + return -1; + } +} + +/* MLME sub-IE. TSCH slotframe and link. Used in EBs: initial schedule */ +int +frame80215e_create_ie_tsch_slotframe_and_link(uint8_t *buf, int len, + struct ieee802154_ies *ies) +{ + if(ies != NULL) { + int i; + int num_slotframes = ies->ie_tsch_slotframe_and_link.num_slotframes; + int num_links = ies->ie_tsch_slotframe_and_link.num_links; + int ie_len = 1 + num_slotframes * (4 + 5 * num_links); + if(num_slotframes > 1 || num_links > FRAME802154E_IE_MAX_LINKS + || len < 2 + ie_len) { + /* We support only 0 or 1 slotframe in this IE and a predefined maximum number of links */ + return -1; + } + /* Insert IE */ + buf[2] = num_slotframes; + /* Insert slotframe */ + if(num_slotframes == 1) { + buf[2 + 1] = ies->ie_tsch_slotframe_and_link.slotframe_handle; + WRITE16(buf + 2 + 2, ies->ie_tsch_slotframe_and_link.slotframe_size); + buf[2 + 4] = num_links; + /* Loop over links */ + for(i = 0; i < num_links; i++) { + /* Insert links */ + WRITE16(buf + 2 + 5 + i * 5, ies->ie_tsch_slotframe_and_link.links[i].timeslot); + WRITE16(buf + 2 + 5 + i * 5 + 2, ies->ie_tsch_slotframe_and_link.links[i].channel_offset); + buf[2 + 5 + i * 5 + 4] = ies->ie_tsch_slotframe_and_link.links[i].link_options; + } + } + create_mlme_short_ie_descriptor(buf, MLME_SHORT_IE_TSCH_SLOFTRAME_AND_LINK, ie_len); + return 2 + ie_len; + } else { + return -1; + } +} + +/* MLME sub-IE. TSCH timeslot. Used in EBs: timeslot template (timing) */ +int +frame80215e_create_ie_tsch_timeslot(uint8_t *buf, int len, + struct ieee802154_ies *ies) +{ + int ie_len; + if(ies == NULL) { + return -1; + } + /* Only ID if ID == 0, else full timing description */ + ie_len = ies->ie_tsch_timeslot_id == 0 ? 1 : 25; + if(len >= 2 + ie_len) { + buf[2] = ies->ie_tsch_timeslot_id; + if(ies->ie_tsch_timeslot_id != 0) { + int i; + for(i = 0; i < tsch_ts_elements_count; i++) { + WRITE16(buf + 3 + 2 * i, ies->ie_tsch_timeslot[i]); + } + } + create_mlme_short_ie_descriptor(buf, MLME_SHORT_IE_TSCH_TIMESLOT, ie_len); + return 2 + ie_len; + } else { + return -1; + } +} + +/* MLME sub-IE. TSCH channel hopping sequence. Used in EBs: hopping sequence */ +int +frame80215e_create_ie_tsch_channel_hopping_sequence(uint8_t *buf, int len, + struct ieee802154_ies *ies) +{ + int ie_len; + if(ies == NULL || ies->ie_hopping_sequence_len > sizeof(ies->ie_hopping_sequence_list)) { + return -1; + } + ie_len = ies->ie_channel_hopping_sequence_id == 0 ? 1 : 12 + ies->ie_hopping_sequence_len; + if(len >= 2 + ie_len && ies != NULL) { + buf[2] = ies->ie_channel_hopping_sequence_id; + buf[3] = 0; /* channel page */ + WRITE16(buf + 4, 0); /* number of channels */ + WRITE16(buf + 6, 0); /* phy configuration */ + WRITE16(buf + 8, 0); + /* Extended bitmap. Size: 0 */ + WRITE16(buf + 10, ies->ie_hopping_sequence_len); /* sequence len */ + memcpy(buf + 12, ies->ie_hopping_sequence_list, ies->ie_hopping_sequence_len); /* sequence list */ + WRITE16(buf + 12 + ies->ie_hopping_sequence_len, 0); /* current hop */ + create_mlme_long_ie_descriptor(buf, MLME_LONG_IE_TSCH_CHANNEL_HOPPING_SEQUENCE, ie_len); + return 2 + ie_len; + } else { + return -1; + } +} + +/* Parse a header IE */ +static int +frame802154e_parse_header_ie(const uint8_t *buf, int len, + uint8_t element_id, struct ieee802154_ies *ies) +{ + switch(element_id) { + case HEADER_IE_ACK_NACK_TIME_CORRECTION: + if(len == 2) { + if(ies != NULL) { + /* If the originator was a time source neighbor, the receiver adjust + * its own clock by incorporating the received drift correction */ + uint16_t time_sync_field = 0; + int16_t drift_us = 0; + /* Extract drift correction from Sync-IE, cast from 12 to 16-bit, + * and convert it to RTIMER ticks. + * See page 88 in IEEE Std 802.15.4e-2012. */ + READ16(buf, time_sync_field); + /* First extract NACK */ + ies->ie_is_nack = (time_sync_field & (uint16_t)0x8000) ? 1 : 0; + /* Then cast from 12 to 16 bit signed */ + if(time_sync_field & 0x0800) { /* Negative integer */ + drift_us = time_sync_field | 0xf000; + } else { /* Positive integer */ + drift_us = time_sync_field & 0x0fff; + } + /* Convert to RTIMER ticks */ + ies->ie_time_correction = drift_us; + } + return len; + } + break; + } + return -1; +} + +/* Parse a MLME short IE */ +static int +frame802154e_parse_mlme_short_ie(const uint8_t *buf, int len, + uint8_t sub_id, struct ieee802154_ies *ies) +{ + switch(sub_id) { + case MLME_SHORT_IE_TSCH_SLOFTRAME_AND_LINK: + if(len >= 1) { + int i; + int num_slotframes = buf[0]; + int num_links = buf[4]; + if(num_slotframes == 0) { + return len; + } + if(num_slotframes <= 1 && num_links <= FRAME802154E_IE_MAX_LINKS + && len == 1 + num_slotframes * (4 + 5 * num_links)) { + if(ies != NULL) { + /* We support only 0 or 1 slotframe in this IE and a predefined maximum number of links */ + ies->ie_tsch_slotframe_and_link.num_slotframes = buf[0]; + ies->ie_tsch_slotframe_and_link.slotframe_handle = buf[1]; + READ16(buf + 2, ies->ie_tsch_slotframe_and_link.slotframe_size); + ies->ie_tsch_slotframe_and_link.num_links = buf[4]; + for(i = 0; i < num_links; i++) { + READ16(buf + 5 + i * 5, ies->ie_tsch_slotframe_and_link.links[i].timeslot); + READ16(buf + 5 + i * 5 + 2, ies->ie_tsch_slotframe_and_link.links[i].channel_offset); + ies->ie_tsch_slotframe_and_link.links[i].link_options = buf[5 + i * 5 + 4]; + } + } + return len; + } + } + break; + case MLME_SHORT_IE_TSCH_SYNCHRONIZATION: + if(len == 6) { + if(ies != NULL) { + ies->ie_asn.ls4b = (uint32_t)buf[0]; + ies->ie_asn.ls4b |= (uint32_t)buf[1] << 8; + ies->ie_asn.ls4b |= (uint32_t)buf[2] << 16; + ies->ie_asn.ls4b |= (uint32_t)buf[3] << 24; + ies->ie_asn.ms1b = (uint8_t)buf[4]; + ies->ie_join_priority = (uint8_t)buf[5]; + } + return len; + } + break; + case MLME_SHORT_IE_TSCH_TIMESLOT: + if(len == 1 || len == 25) { + if(ies != NULL) { + ies->ie_tsch_timeslot_id = buf[0]; + if(len == 25) { + int i; + for(i = 0; i < tsch_ts_elements_count; i++) { + READ16(buf+1+2*i, ies->ie_tsch_timeslot[i]); + } + } + } + return len; + } + break; + } + return -1; +} + +/* Parse a MLME long IE */ +static int +frame802154e_parse_mlme_long_ie(const uint8_t *buf, int len, + uint8_t sub_id, struct ieee802154_ies *ies) +{ + switch(sub_id) { + case MLME_LONG_IE_TSCH_CHANNEL_HOPPING_SEQUENCE: + if(len > 0) { + if(ies != NULL) { + ies->ie_channel_hopping_sequence_id = buf[0]; + if(len > 1) { + READ16(buf+8, ies->ie_hopping_sequence_len); /* sequence len */ + if(ies->ie_hopping_sequence_len <= sizeof(ies->ie_hopping_sequence_list) + && len == 12 + ies->ie_hopping_sequence_len) { + memcpy(ies->ie_hopping_sequence_list, buf+10, ies->ie_hopping_sequence_len); /* sequence list */ + } + } + } + return len; + } + break; + } + return -1; +} + +/* Parse all IEEE 802.15.4e Information Elements (IE) from a frame */ +int +frame802154e_parse_information_elements(const uint8_t *buf, uint8_t buf_size, + struct ieee802154_ies *ies) +{ + const uint8_t *start = buf; + uint16_t ie_desc; + uint8_t type; + uint8_t id; + uint16_t len = 0; + int nested_mlme_len = 0; + enum {PARSING_HEADER_IE, PARSING_PAYLOAD_IE, PARSING_MLME_SUBIE} parsing_state; + + if(ies == NULL) { + return -1; + } + + /* Always look for a header IE first (at least "list termination 1") */ + parsing_state = PARSING_HEADER_IE; + ies->ie_payload_ie_offset = 0; + + /* Loop over all IEs */ + while(buf_size > 0) { + if(buf_size < 2) { /* Not enough space for IE descriptor */ + return -1; + } + READ16(buf, ie_desc); + buf_size -= 2; + buf += 2; + type = ie_desc & 0x8000 ? 1 : 0; /* b15 */ + PRINTF("frame802154e: ie type %u, current state %u\n", type, parsing_state); + + switch(parsing_state) { + case PARSING_HEADER_IE: + if(type != 0) { + PRINTF("frame802154e: wrong type %04x\n", ie_desc); + return -1; + } + /* Header IE: 2 bytes descriptor, c.f. fig 48n in IEEE 802.15.4e */ + len = ie_desc & 0x007f; /* b0-b6 */ + id = (ie_desc & 0x7f80) >> 7; /* b7-b14 */ + PRINTF("frame802154e: header ie len %u id %x\n", len, id); + switch(id) { + case HEADER_IE_LIST_TERMINATION_1: + if(len == 0) { + /* End of payload IE list, now expect payload IEs */ + parsing_state = PARSING_PAYLOAD_IE; + ies->ie_payload_ie_offset = buf - start; /* Save IE header len */ + PRINTF("frame802154e: list termination 1, look for payload IEs\n"); + } else { + PRINTF("frame802154e: list termination 1, wrong len %u\n", len); + return -1; + } + break; + case HEADER_IE_LIST_TERMINATION_2: + /* End of IE parsing */ + if(len == 0) { + ies->ie_payload_ie_offset = buf - start; /* Save IE header len */ + PRINTF("frame802154e: list termination 2\n"); + return buf + len - start; + } else { + PRINTF("frame802154e: list termination 2, wrong len %u\n", len); + return -1; + } + default: + if(len > buf_size || frame802154e_parse_header_ie(buf, len, id, ies) == -1) { + PRINTF("frame802154e: failed to parse\n"); + return -1; + } + break; + } + break; + case PARSING_PAYLOAD_IE: + if(type != 1) { + PRINTF("frame802154e: wrong type %04x\n", ie_desc); + return -1; + } + /* Payload IE: 2 bytes descriptor, c.f. fig 48o in IEEE 802.15.4e */ + len = ie_desc & 0x7ff; /* b0-b10 */ + id = (ie_desc & 0x7800) >> 11; /* b11-b14 */ + PRINTF("frame802154e: payload ie len %u id %x\n", len, id); + switch(id) { + case PAYLOAD_IE_MLME: + /* Now expect 'len' bytes of MLME sub-IEs */ + parsing_state = PARSING_MLME_SUBIE; + nested_mlme_len = len; + len = 0; /* Reset len as we want to read subIEs and not jump over them */ + PRINTF("frame802154e: entering MLME ie with len %u\n", nested_mlme_len); + break; + case PAYLOAD_IE_LIST_TERMINATION: + PRINTF("frame802154e: payload ie list termination %u\n", len); + return (len == 0) ? buf + len - start : -1; + default: + PRINTF("frame802154e: non-supported payload ie\n"); + return -1; + } + break; + case PARSING_MLME_SUBIE: + /* MLME sub-IE: 2 bytes descriptor, c.f. fig 48q in IEEE 802.15.4e */ + /* type == 0 means short sub-IE, type == 1 means long sub-IE */ + if(type == 0) { + /* Short sub-IE, c.f. fig 48r in IEEE 802.15.4e */ + len = ie_desc & 0x00ff; /* b0-b7 */ + id = (ie_desc & 0x7f00) >> 8; /* b8-b14 */ + PRINTF("frame802154e: short mlme ie len %u id %x\n", len, id); + if(len > buf_size || frame802154e_parse_mlme_short_ie(buf, len, id, ies) == -1) { + PRINTF("frame802154e: failed to parse ie\n"); + return -1; + } + } else { + /* Long sub-IE, c.f. fig 48s in IEEE 802.15.4e */ + len = ie_desc & 0x7ff; /* b0-b10 */ + id = (ie_desc & 0x7800) >> 11; /* b11-b14 */ + PRINTF("frame802154e: long mlme ie len %u id %x\n", len, id); + if(len > buf_size || frame802154e_parse_mlme_long_ie(buf, len, id, ies) == -1) { + PRINTF("frame802154e: failed to parse ie\n"); + return -1; + } + } + /* Update remaining nested MLME len */ + nested_mlme_len -= 2 + len; + if(nested_mlme_len < 0) { + PRINTF("frame802154e: found more sub-IEs than initially advertised\n"); + /* We found more sub-IEs than initially advertised */ + return -1; + } + if(nested_mlme_len == 0) { + PRINTF("frame802154e: end of MLME IE parsing\n"); + /* End of IE parsing, look for another payload IE */ + parsing_state = PARSING_PAYLOAD_IE; + } + break; + } + buf += len; + buf_size -= len; + } + + if(parsing_state == PARSING_HEADER_IE) { + ies->ie_payload_ie_offset = buf - start; /* Save IE header len */ + } + + return buf - start; +} diff --git a/core/net/mac/frame802154e-ie.h b/core/net/mac/frame802154e-ie.h new file mode 100644 index 000000000..d6747557c --- /dev/null +++ b/core/net/mac/frame802154e-ie.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * IEEE 802.15.4e Information Element (IE) creation and parsing. + * \author + * Simon Duquennoy + */ + +#ifndef FRAME_802154E_H +#define FRAME_802154E_H + +#include "contiki.h" +/* We need definitions from tsch-private.h for TSCH-specific information elements */ +#include "net/mac/tsch/tsch-private.h" + +#define FRAME802154E_IE_MAX_LINKS 4 + +/* Structures used for the Slotframe and Links information element */ +struct tsch_slotframe_and_links_link { + uint16_t timeslot; + uint16_t channel_offset; + uint8_t link_options; +}; +struct tsch_slotframe_and_links { + uint8_t num_slotframes; /* We support only 0 or 1 slotframe in this IE */ + uint8_t slotframe_handle; + uint16_t slotframe_size; + uint8_t num_links; + struct tsch_slotframe_and_links_link links[FRAME802154E_IE_MAX_LINKS]; +}; + +/* The information elements that we currently support */ +struct ieee802154_ies { + /* Header IEs */ + int16_t ie_time_correction; + uint8_t ie_is_nack; + /* Payload MLME */ + uint8_t ie_payload_ie_offset; + uint16_t ie_mlme_len; + /* Payload Short MLME IEs */ + uint8_t ie_tsch_synchronization_offset; + struct asn_t ie_asn; + uint8_t ie_join_priority; + uint8_t ie_tsch_timeslot_id; + uint16_t ie_tsch_timeslot[tsch_ts_elements_count]; + struct tsch_slotframe_and_links ie_tsch_slotframe_and_link; + /* Payload Long MLME IEs */ + uint8_t ie_channel_hopping_sequence_id; + /* We include and parse only the sequence len and list and omit unused fields */ + uint16_t ie_hopping_sequence_len; + uint8_t ie_hopping_sequence_list[TSCH_HOPPING_SEQUENCE_MAX_LEN]; +}; + +/** Insert various Information Elements **/ +/* Header IE. ACK/NACK time correction. Used in enhanced ACKs */ +int frame80215e_create_ie_header_ack_nack_time_correction(uint8_t *buf, int len, + struct ieee802154_ies *ies); +/* Header IE. List termination 1 (Signals the end of the Header IEs when + * followed by payload IEs) */ +int frame80215e_create_ie_header_list_termination_1(uint8_t *buf, int len, + struct ieee802154_ies *ies); +/* Header IE. List termination 2 (Signals the end of the Header IEs when + * followed by an unformatted payload) */ +int frame80215e_create_ie_header_list_termination_2(uint8_t *buf, int len, + struct ieee802154_ies *ies); +/* Payload IE. List termination */ +int frame80215e_create_ie_payload_list_termination(uint8_t *buf, int len, + struct ieee802154_ies *ies); +/* Payload IE. MLME. Used to nest sub-IEs */ +int frame80215e_create_ie_mlme(uint8_t *buf, int len, + struct ieee802154_ies *ies); +/* MLME sub-IE. TSCH synchronization. Used in EBs: ASN and join priority */ +int frame80215e_create_ie_tsch_synchronization(uint8_t *buf, int len, + struct ieee802154_ies *ies); +/* MLME sub-IE. TSCH slotframe and link. Used in EBs: initial schedule */ +int frame80215e_create_ie_tsch_slotframe_and_link(uint8_t *buf, int len, + struct ieee802154_ies *ies); +/* MLME sub-IE. TSCH timeslot. Used in EBs: timeslot template (timing) */ +int frame80215e_create_ie_tsch_timeslot(uint8_t *buf, int len, + struct ieee802154_ies *ies); +/* MLME sub-IE. TSCH channel hopping sequence. Used in EBs: hopping sequence */ +int frame80215e_create_ie_tsch_channel_hopping_sequence(uint8_t *buf, int len, + struct ieee802154_ies *ies); + +/* Parse all Information Elements of a frame */ +int frame802154e_parse_information_elements(const uint8_t *buf, uint8_t buf_size, + struct ieee802154_ies *ies); + +#endif /* FRAME_802154E_H */ diff --git a/core/net/mac/framer-802154.c b/core/net/mac/framer-802154.c index ecffdd23d..7e524afb1 100644 --- a/core/net/mac/framer-802154.c +++ b/core/net/mac/framer-802154.c @@ -38,6 +38,7 @@ #include "net/mac/framer-802154.h" #include "net/mac/frame802154.h" +#include "net/llsec/llsec802154.h" #include "net/packetbuf.h" #include "lib/random.h" #include @@ -61,46 +62,16 @@ static uint8_t mac_dsn; static uint8_t initialized = 0; -/** \brief The 16-bit identifier of the PAN on which the device is - * sending to. If this value is 0xffff, the device is not - * associated. - */ -static uint16_t mac_dst_pan_id = IEEE802154_PANID; - -/** \brief The 16-bit identifier of the PAN on which the device is - * operating. If this value is 0xffff, the device is not - * associated. - */ -static uint16_t mac_src_pan_id = IEEE802154_PANID; - -/*---------------------------------------------------------------------------*/ -void framer_802154_set_panid(uint16_t panid){ - mac_dst_pan_id = panid; - mac_src_pan_id = panid; -} -/*---------------------------------------------------------------------------*/ -uint16_t framer_802154_get_panid(){ - return mac_dst_pan_id; -} - /*---------------------------------------------------------------------------*/ static int -is_broadcast_addr(uint8_t mode, uint8_t *addr) -{ - int i = mode == FRAME802154_SHORTADDRMODE ? 2 : 8; - while(i-- > 0) { - if(addr[i] != 0xff) { - return 0; - } - } - return 1; -} -/*---------------------------------------------------------------------------*/ -static int -create(void) +create_frame(int type, int do_create) { frame802154_t params; - int len; + int hdr_len; + + if(frame802154_get_pan_id() == 0xffff) { + return -1; + } /* init to zeros */ memset(¶ms, 0, sizeof(params)); @@ -111,56 +82,82 @@ create(void) } /* Build the FCF. */ - params.fcf.frame_type = FRAME802154_DATAFRAME; - params.fcf.security_enabled = 0; + params.fcf.frame_type = packetbuf_attr(PACKETBUF_ATTR_FRAME_TYPE); params.fcf.frame_pending = packetbuf_attr(PACKETBUF_ATTR_PENDING); - if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) { + if(packetbuf_holds_broadcast()) { params.fcf.ack_required = 0; } else { params.fcf.ack_required = packetbuf_attr(PACKETBUF_ATTR_MAC_ACK); } + /* We do not compress PAN ID in outgoing frames, i.e. include one PAN ID (dest by default) + * There is one exception, seemingly a typo in Table 2a: rows 2 and 3: when there is no + * source nor destination address, we have dest PAN ID iff compression is *set*. */ params.fcf.panid_compression = 0; + params.fcf.sequence_number_suppression = FRAME802154_SUPPR_SEQNO; - /* Insert IEEE 802.15.4 (2003) version bit. */ - params.fcf.frame_version = FRAME802154_IEEE802154_2003; + /* Insert IEEE 802.15.4 version bits. */ + params.fcf.frame_version = FRAME802154_VERSION; + +#if LLSEC802154_USES_AUX_HEADER + if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL)) { + params.fcf.security_enabled = 1; + } + /* Setting security-related attributes */ + params.aux_hdr.security_control.security_level = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL); +#if LLSEC802154_USES_FRAME_COUNTER + params.aux_hdr.frame_counter.u16[0] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1); + params.aux_hdr.frame_counter.u16[1] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3); +#else /* LLSEC802154_USES_FRAME_COUNTER */ + params.aux_hdr.security_control.frame_counter_suppression = 1; + params.aux_hdr.security_control.frame_counter_size = 1; +#endif /* LLSEC802154_USES_FRAME_COUNTER */ +#if LLSEC802154_USES_EXPLICIT_KEYS + params.aux_hdr.security_control.key_id_mode = packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE); + params.aux_hdr.key_index = packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX); + params.aux_hdr.key_source.u16[0] = packetbuf_attr(PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1); +#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ +#endif /* LLSEC802154_USES_AUX_HEADER */ /* Increment and set the data sequence number. */ - if(packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO)) { + if(!do_create) { + /* Only length calculation - no sequence number is needed and + should not be consumed. */ + + } else if(packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO)) { params.seq = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO); + } else { + /* Ensure that the sequence number 0 is not used as it would bypass the above check. */ + if(mac_dsn == 0) { + mac_dsn++; + } params.seq = mac_dsn++; packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, params.seq); } -/* params.seq = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID); */ /* Complete the addressing fields. */ /** \todo For phase 1 the addresses are all long. We'll need a mechanism in the rime attributes to tell the mac to use long or short for phase 2. - */ - if(sizeof(linkaddr_t) == 2) { + */ + if(LINKADDR_SIZE == 2) { /* Use short address mode if linkaddr size is short. */ params.fcf.src_addr_mode = FRAME802154_SHORTADDRMODE; } else { params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE; } - params.dest_pid = mac_dst_pan_id; + params.dest_pid = frame802154_get_pan_id(); - /* - * If the output address is NULL in the Rime buf, then it is broadcast - * on the 802.15.4 network. - */ - if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) { + if(packetbuf_holds_broadcast()) { /* Broadcast requires short address mode. */ params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; params.dest_addr[0] = 0xFF; params.dest_addr[1] = 0xFF; - } else { linkaddr_copy((linkaddr_t *)¶ms.dest_addr, packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); /* Use short address mode if linkaddr size is small */ - if(sizeof(linkaddr_t) == 2) { + if(LINKADDR_SIZE == 2) { params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; } else { params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE; @@ -168,7 +165,7 @@ create(void) } /* Set the source PAN ID to the global variable. */ - params.src_pid = mac_src_pan_id; + params.src_pid = frame802154_get_pan_id(); /* * Set up the source address using only the long address mode for @@ -178,54 +175,97 @@ create(void) params.payload = packetbuf_dataptr(); params.payload_len = packetbuf_datalen(); - len = frame802154_hdrlen(¶ms); - if(packetbuf_hdralloc(len)) { - frame802154_create(¶ms, packetbuf_hdrptr(), len); + hdr_len = frame802154_hdrlen(¶ms); + if(!do_create) { + /* Only calculate header length */ + return hdr_len; + } else if(packetbuf_hdralloc(hdr_len)) { + frame802154_create(¶ms, packetbuf_hdrptr()); PRINTF("15.4-OUT: %2X", params.fcf.frame_type); PRINTADDR(params.dest_addr); - PRINTF("%d %u (%u)\n", len, packetbuf_datalen(), packetbuf_totlen()); - return len; + PRINTF("%d %u (%u)\n", hdr_len, packetbuf_datalen(), packetbuf_totlen()); + + return hdr_len; } else { - PRINTF("15.4-OUT: too large header: %u\n", len); + PRINTF("15.4-OUT: too large header: %u\n", hdr_len); return FRAMER_FAILED; } } /*---------------------------------------------------------------------------*/ static int +hdr_length(void) +{ + return create_frame(FRAME802154_DATAFRAME, 0); +} +/*---------------------------------------------------------------------------*/ +static int +create(void) +{ + return create_frame(FRAME802154_DATAFRAME, 1); +} +/*---------------------------------------------------------------------------*/ +static int parse(void) { frame802154_t frame; - int len; - len = packetbuf_datalen(); - if(frame802154_parse(packetbuf_dataptr(), len, &frame) && - packetbuf_hdrreduce(len - frame.payload_len)) { + int hdr_len; + + hdr_len = frame802154_parse(packetbuf_dataptr(), packetbuf_datalen(), &frame); + + if(hdr_len && packetbuf_hdrreduce(hdr_len)) { + packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, frame.fcf.frame_type); + if(frame.fcf.dest_addr_mode) { - if(frame.dest_pid != mac_src_pan_id && + if(frame.dest_pid != frame802154_get_pan_id() && frame.dest_pid != FRAME802154_BROADCASTPANDID) { /* Packet to another PAN */ PRINTF("15.4: for another pan %u\n", frame.dest_pid); return FRAMER_FAILED; } - if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { + if(!frame802154_is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr); } } packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr); packetbuf_set_attr(PACKETBUF_ATTR_PENDING, frame.fcf.frame_pending); - /* packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, frame.fcf.ack_required);*/ + if(frame.fcf.sequence_number_suppression == 0) { + packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, frame.seq); + } else { + packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, 0xffff); + } +#if NETSTACK_CONF_WITH_RIME packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, frame.seq); +#endif + +#if LLSEC802154_USES_AUX_HEADER + if(frame.fcf.security_enabled) { + packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, frame.aux_hdr.security_control.security_level); +#if LLSEC802154_USES_FRAME_COUNTER + packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, frame.aux_hdr.frame_counter.u16[0]); + packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, frame.aux_hdr.frame_counter.u16[1]); +#endif /* LLSEC802154_USES_FRAME_COUNTER */ +#if LLSEC802154_USES_EXPLICIT_KEYS + packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, frame.aux_hdr.security_control.key_id_mode); + packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, frame.aux_hdr.key_index); + packetbuf_set_attr(PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1, frame.aux_hdr.key_source.u16[0]); +#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ + } +#endif /* LLSEC802154_USES_AUX_HEADER */ PRINTF("15.4-IN: %2X", frame.fcf.frame_type); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); - PRINTF("%u (%u)\n", packetbuf_datalen(), len); + PRINTF("%d %u (%u)\n", hdr_len, packetbuf_datalen(), packetbuf_totlen()); - return len - frame.payload_len; + return hdr_len; } return FRAMER_FAILED; } /*---------------------------------------------------------------------------*/ const struct framer framer_802154 = { - create, parse + hdr_length, + create, + parse }; +/*---------------------------------------------------------------------------*/ diff --git a/core/net/mac/framer-802154.h b/core/net/mac/framer-802154.h index 3cbb52446..fe4fced80 100644 --- a/core/net/mac/framer-802154.h +++ b/core/net/mac/framer-802154.h @@ -39,12 +39,8 @@ #ifndef FRAMER_802154_H_ #define FRAMER_802154_H_ -#include #include "net/mac/framer.h" extern const struct framer framer_802154; -void framer_802154_set_panid(uint16_t panid); -uint16_t framer_802154_get_panid(); - -#endif /* __FRAMER_802154_H__ */ +#endif /* FRAMER_802154_H_ */ diff --git a/core/net/mac/framer-nullmac.c b/core/net/mac/framer-nullmac.c index b0af4b456..cc79051f1 100644 --- a/core/net/mac/framer-nullmac.c +++ b/core/net/mac/framer-nullmac.c @@ -55,6 +55,12 @@ struct nullmac_hdr { linkaddr_t sender; }; +/*---------------------------------------------------------------------------*/ +static int +hdr_length(void) +{ + return sizeof(struct nullmac_hdr); +} /*---------------------------------------------------------------------------*/ static int create(void) @@ -91,5 +97,7 @@ parse(void) } /*---------------------------------------------------------------------------*/ const struct framer framer_nullmac = { - create, parse + hdr_length, + create, + parse }; diff --git a/core/net/mac/framer.h b/core/net/mac/framer.h index 3204dc0c9..5ed419292 100644 --- a/core/net/mac/framer.h +++ b/core/net/mac/framer.h @@ -45,6 +45,7 @@ struct framer { + int (* length)(void); int (* create)(void); int (* parse)(void); diff --git a/core/net/mac/mac-sequence.c b/core/net/mac/mac-sequence.c index 638dece13..40ac3c28a 100644 --- a/core/net/mac/mac-sequence.c +++ b/core/net/mac/mac-sequence.c @@ -74,7 +74,7 @@ mac_sequence_is_duplicate(void) for(i = 0; i < MAX_SEQNOS; ++i) { if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER), &received_seqnos[i].sender)) { - if(packetbuf_attr(PACKETBUF_ATTR_PACKET_ID) == received_seqnos[i].seqno) { + if(packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO) == received_seqnos[i].seqno) { /* Duplicate packet. */ return 1; } @@ -102,7 +102,7 @@ mac_sequence_register_seqno(void) for(j = i - 1; j > 0; --j) { memcpy(&received_seqnos[j], &received_seqnos[j - 1], sizeof(struct seqno)); } - received_seqnos[0].seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID); + received_seqnos[0].seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO); linkaddr_copy(&received_seqnos[0].sender, packetbuf_addr(PACKETBUF_ADDR_SENDER)); } diff --git a/platform/iris/dev/sensors/battery-sensor.c b/core/net/mac/nordc.c similarity index 66% rename from platform/iris/dev/sensors/battery-sensor.c rename to core/net/mac/nordc.c index bd0d4e40a..bb41335ff 100644 --- a/platform/iris/dev/sensors/battery-sensor.c +++ b/core/net/mac/nordc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, University of Colombo School of Computing. + * Copyright (c) 2014, SICS Swedish ICT. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,77 +27,68 @@ * SUCH DAMAGE. * * This file is part of the Contiki operating system. + * */ /** * \file - * Battery sensor driver. + * This RDC layer does nothing. It is meant for use with MAC + * layers that do not use a RDC at all, such as TSCH. * \author - * Kasun Hewage + * Simon Duquennoy + * */ -#include -#include "dev/battery-sensor.h" -#include "dev/adc.h" +#include "net/mac/rdc.h" +#include "net/netstack.h" - -#define BAT_MONITOR_PORT PORTF -#define BAT_MONITOR_PIN_MASK _BV(1) -#define BAT_MONITOR_PORT_DDR DDRF -#define BAT_MONITOR_ADC_CHANNEL 30 - -const struct sensors_sensor battery_sensor; -static uint8_t active; /*---------------------------------------------------------------------------*/ static void -activate(void) +send_packet(mac_callback_t sent, void *ptr) { - /* This assumes that some other sensor system already did setup the ADC */ - adc_init(); - - /* Enable battery sensor. */ - BAT_MONITOR_PORT |= BAT_MONITOR_PIN_MASK; - BAT_MONITOR_PORT_DDR |= BAT_MONITOR_PIN_MASK; - - active = 1; } /*---------------------------------------------------------------------------*/ static void -deactivate(void) +send_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list) +{ +} +/*---------------------------------------------------------------------------*/ +static void +packet_input(void) { - active = 0; } /*---------------------------------------------------------------------------*/ static int -value(int type) +on(void) { - return get_adc(BAT_MONITOR_ADC_CHANNEL); -} -/*---------------------------------------------------------------------------*/ -static int -configure(int type, int c) -{ - switch(type) { - case SENSORS_ACTIVE: - if (c) { - activate(); - } else { - deactivate(); - } - } return 0; } /*---------------------------------------------------------------------------*/ static int -status(int type) +off(int keep_radio_on) { - switch (type) { - case SENSORS_ACTIVE: - case SENSORS_READY: - return active; - } return 0; } /*---------------------------------------------------------------------------*/ -SENSORS_SENSOR(battery_sensor, BATTERY_SENSOR, - value, configure, status); +static unsigned short +channel_check_interval(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ +} +/*---------------------------------------------------------------------------*/ +const struct rdc_driver nordc_driver = { + "nordc", + init, + send_packet, + send_list, + packet_input, + on, + off, + channel_check_interval, +}; +/*---------------------------------------------------------------------------*/ diff --git a/core/net/mac/nullmac.c b/core/net/mac/nullmac.c index f65fedfdb..4e542651a 100644 --- a/core/net/mac/nullmac.c +++ b/core/net/mac/nullmac.c @@ -54,7 +54,7 @@ send_packet(mac_callback_t sent, void *ptr) static void packet_input(void) { - NETSTACK_NETWORK.input(); + NETSTACK_LLSEC.input(); } /*---------------------------------------------------------------------------*/ static int diff --git a/core/net/mac/nullrdc.c b/core/net/mac/nullrdc.c index c30b1ba1f..5cec23a3d 100644 --- a/core/net/mac/nullrdc.c +++ b/core/net/mac/nullrdc.c @@ -48,6 +48,7 @@ #if CONTIKI_TARGET_COOJA #include "lib/simEnvChange.h" +#include "sys/cooja_mt.h" #endif /* CONTIKI_TARGET_COOJA */ #define DEBUG 0 @@ -125,11 +126,6 @@ send_one_packet(mac_callback_t sent, void *ptr) PRINTF("nullrdc: send failed, too large header\n"); ret = MAC_TX_ERR_FATAL; } else { - -#ifdef NETSTACK_ENCRYPT - NETSTACK_ENCRYPT(); -#endif /* NETSTACK_ENCRYPT */ - #if NULLRDC_802154_AUTOACK int is_broadcast; uint8_t dsn; @@ -137,8 +133,7 @@ send_one_packet(mac_callback_t sent, void *ptr) NETSTACK_RADIO.prepare(packetbuf_hdrptr(), packetbuf_totlen()); - is_broadcast = linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), - &linkaddr_null); + is_broadcast = packetbuf_holds_broadcast(); if(NETSTACK_RADIO.receiving_packet() || (!is_broadcast && NETSTACK_RADIO.pending_packet())) { @@ -277,9 +272,6 @@ packet_input(void) original_datalen = packetbuf_datalen(); original_dataptr = packetbuf_dataptr(); #endif -#ifdef NETSTACK_DECRYPT - NETSTACK_DECRYPT(); -#endif /* NETSTACK_DECRYPT */ #if NULLRDC_802154_AUTOACK if(packetbuf_datalen() == ACK_LEN) { @@ -292,25 +284,26 @@ packet_input(void) #if NULLRDC_ADDRESS_FILTER } else if(!linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_node_addr) && - !linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), - &linkaddr_null)) { + !packetbuf_holds_broadcast()) { PRINTF("nullrdc: not for us\n"); #endif /* NULLRDC_ADDRESS_FILTER */ } else { int duplicate = 0; #if NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW +#if RDC_WITH_DUPLICATE_DETECTION /* Check for duplicate packet. */ duplicate = mac_sequence_is_duplicate(); if(duplicate) { /* Drop the packet. */ PRINTF("nullrdc: drop duplicate link layer packet %u\n", - packetbuf_attr(PACKETBUF_ATTR_PACKET_ID)); + packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO)); } else { mac_sequence_register_seqno(); } +#endif /* RDC_WITH_DUPLICATE_DETECTION */ #endif /* NULLRDC_802154_AUTOACK */ - + #if NULLRDC_SEND_802154_ACK { frame802154_t info154; diff --git a/core/net/mac/phase.c b/core/net/mac/phase.c index 9176061b7..d7ded2428 100644 --- a/core/net/mac/phase.c +++ b/core/net/mac/phase.c @@ -122,7 +122,7 @@ phase_update(const linkaddr_t *neighbor, rtimer_clock_t time, } else { /* No matching phase was found, so we allocate a new one. */ if(mac_status == MAC_TX_OK && e == NULL) { - e = nbr_table_add_lladdr(nbr_phase, neighbor); + e = nbr_table_add_lladdr(nbr_phase, neighbor, NBR_TABLE_REASON_MAC, NULL); if(e) { e->time = time; #if PHASE_DRIFT_CORRECT @@ -217,7 +217,13 @@ phase_wait(const linkaddr_t *neighbor, rtimer_clock_t cycle_time, p = memb_alloc(&queued_packets_memb); if(p != NULL) { if(buf_list == NULL) { + packetbuf_set_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED, 1); p->q = queuebuf_new_from_packetbuf(); + if(p->q == NULL) { + /* memory allocation failed */ + memb_free(&queued_packets_memb, p); + return PHASE_UNKNOWN; + } } p->mac_callback = mac_callback; p->mac_callback_ptr = mac_callback_ptr; diff --git a/core/net/mac/rdc.h b/core/net/mac/rdc.h index 9a47605b7..8ac34e444 100644 --- a/core/net/mac/rdc.h +++ b/core/net/mac/rdc.h @@ -43,6 +43,17 @@ #include "contiki-conf.h" #include "net/mac/mac.h" +#include "net/llsec/llsec802154.h" + +#ifdef RDC_CONF_WITH_DUPLICATE_DETECTION +#define RDC_WITH_DUPLICATE_DETECTION RDC_CONF_WITH_DUPLICATE_DETECTION +#else /* RDC_CONF_WITH_DUPLICATE_DETECTION */ +/* As frames can be spoofed, the RDC layer should not discard a + frame because it has seen its sequence number already. Replay + protection should be implemented at the LLSEC layer where the + authenticity of frames is verified. */ +#define RDC_WITH_DUPLICATE_DETECTION !LLSEC802154_ENABLED +#endif /* RDC_CONF_WITH_DUPLICATE_DETECTION */ /* List of packets to be sent by RDC layer */ struct rdc_buf_list { diff --git a/core/net/mac/sicslowmac/sicslowmac.c b/core/net/mac/sicslowmac/sicslowmac.c index 2c7562f29..09d77ae17 100644 --- a/core/net/mac/sicslowmac/sicslowmac.c +++ b/core/net/mac/sicslowmac/sicslowmac.c @@ -106,7 +106,9 @@ send_packet(mac_callback_t sent, void *ptr) params.fcf.frame_type = FRAME802154_DATAFRAME; params.fcf.security_enabled = 0; params.fcf.frame_pending = 0; +#if NETSTACK_CONF_WITH_RIME params.fcf.ack_required = packetbuf_attr(PACKETBUF_ATTR_RELIABLE); +#endif params.fcf.panid_compression = 0; /* Insert IEEE 802.15.4 (2003) version bit. */ @@ -123,11 +125,7 @@ send_packet(mac_callback_t sent, void *ptr) params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE; params.dest_pid = mac_dst_pan_id; - /* - * If the output address is NULL in the Rime buf, then it is broadcast - * on the 802.15.4 network. - */ - if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) { + if(packetbuf_holds_broadcast()) { /* Broadcast requires short address mode. */ params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; params.dest_addr[0] = 0xFF; @@ -157,7 +155,7 @@ send_packet(mac_callback_t sent, void *ptr) len = frame802154_hdrlen(¶ms); if(packetbuf_hdralloc(len)) { int ret; - frame802154_create(¶ms, packetbuf_hdrptr(), len); + frame802154_create(¶ms, packetbuf_hdrptr()); PRINTF("6MAC-UT: %2X", params.fcf.frame_type); PRINTADDR(params.dest_addr); diff --git a/core/net/mac/tsch/Makefile.tsch b/core/net/mac/tsch/Makefile.tsch new file mode 100644 index 000000000..e19ff8b13 --- /dev/null +++ b/core/net/mac/tsch/Makefile.tsch @@ -0,0 +1 @@ +CONTIKI_SOURCEFILES += tsch.c tsch-slot-operation.c tsch-queue.c tsch-packet.c tsch-schedule.c tsch-log.c tsch-rpl.c tsch-adaptive-timesync.c diff --git a/core/net/mac/tsch/README.md b/core/net/mac/tsch/README.md new file mode 100644 index 000000000..0b7c54ef3 --- /dev/null +++ b/core/net/mac/tsch/README.md @@ -0,0 +1,204 @@ +# IEEE 802.15.4e TSCH (TimeSlotted Channel Hopping) + +## Overview + +TSCH is a MAC layer of the [IEEE 802.15.4e-2012 amendment][ieee802.15.4e-2012], +currently being integrated as part of the new IEEE 802.15.4-2015. +[6TiSCH][ietf-6tisch-wg] is an IETF Working Group focused on IPv6 over TSCH. +This is a Contiki implementation of TSCH and the 6TiSCH so-called "minimal configuration", +which defines how to run a basic RPL+TSCH network. + +It was developped by: +* Simon Duquennoy, SICS, simonduq@sics.se, github user: [simonduq](https://github.com/simonduq) +* Beshr Al Nahas, SICS (now Chalmers University), beshr@chalmers.se, github user: [beshrns](https://github.com/beshrns) + +You can find an extensive evaluation of this implementation in our paper [*Orchestra: Robust Mesh Networks Through Autonomously Scheduled TSCH*](http://www.simonduquennoy.net/papers/duquennoy15orchestra.pdf), ACM SenSys'15. + +## Features + +This implementation includes: + * Standard IEEE 802.15.4e-2012 frame version 2 + * Standard TSCH joining procedure with Enhanced Beacons with the following Information Elements: + * TSCH synchronization (join priority and ASN) + * TSCH slotframe and link (basic schedule) + * TSCH timeslot (timeslot timing template) + * TSCH channel hopping sequence (hopping sequence template) + * Standard TSCH link selection and slot operation (10ms slots by default) + * Standard TSCH synchronization, including with ACK/NACK time correction Information Element + * Standard TSCH queues and CSMA-CA mechanism + * Standard TSCH security + * Standard 6TiSCH TSCH-RPL interaction (6TiSCH Minimal Configuration and Minimal Schedule) + * A scheduling API to add/remove slotframes and links + * A system for logging from TSCH timeslot operation interrupt, with postponed printout + * Orchestra: an autonomous scheduler for TSCH+RPL networks + +It has been tested on the following platforms: + * NXP JN516x (`jn516x`, tested on hardware) + * Tmote Sky (`sky`, tested on hardware and in cooja) + * Zolertia Z1 (`z1`, tested in cooja only) + * CC2538DK (`cc2538dk`, tested on hardware) + * Zolertia Zoul (`zoul`, tested on hardware) + * CC2650 (`srf06-cc26xx`, tested on hardware) + +This implementation was present at the ETSI Plugtest +event in Prague in July 2015, and did successfully inter-operate with all +four implementations it was tested against. + +We have designed this implementation with IPv6 and RPL in mind, but the code is fully independent +from upper layers (with the exception of the optional `tsch-rpl.[ch]`), and has been +also tested with Rime (currently only with 64-bit link-layer addresses). + +## Code structure + +The IEEE 802.15.4e-2012 frame format is implemented in: +* `core/net/mac/frame802154.[ch]`: handling of frame version 2 +* `core/net/mac/frame802154-ie.[ch]`: handling of Information Elements + +TSCH is implemented in: +* `core/net/mac/tsch/tsch.[ch]`: TSCH management (association, keep-alive), processes handling pending +outgoing and incoming packets, and interface with Contiki's upper layers as a MAC driver. TSCH does not +require a RDC (nordc is recommended). +* `tsch-slot-operation.[ch]`: TSCH low-level slot operation, fully interrupt-driven. Node wake up at every active +slot (according to the slotframes and links installed), transmit or receive frames and ACKs. Received packets are +stored in a ringbuf for latter upper-layer processing. Outgoing packets that are dequeued (because acknowledged +or dropped) are stored in another ringbuf for upper-layer processing. +* `tsch-asn.h`: TSCH macros for Absolute Slot Number (ASN) handling. +* `tsch-packet.[ch]`: TSCH Enhanced ACK (EACK) and enhanced Beacon (EB) creation and parsing. +* `tsch-queue.[ch]`: TSCH per-neighbor queue, neighbor state, and CSMA-CA. +* `tsch-schedule.[ch]`: TSCH slotframe and link handling, and API for slotframe and link installation/removal. +* `tsch-security.[ch]`: TSCH security, i.e. securing frames and ACKs from interrupt with ASN as part of the Nonce. +Implements the 6TiSCH minimal configuration K1-K2 keys pair. +* `tsch-rpl.[ch]`: used for TSCH+RPL networks, to align TSCH and RPL states (preferred parent -> time source, +rank -> join priority) as defined in the 6TiSCH minimal configuration. +* `tsch-log.[ch]`: logging system for TSCH, including delayed messages for logging from slot operation interrupt. + +Orchestra is implemented in: +* `apps/orchestra`: see `apps/orchestra/README.md` for more information. + +## Using TSCH + +A simple TSCH+RPL example is included under `examples/ipv6/rpl-tsch`. +To use TSCH, first make sure your platform supports it. +Currently, `jn516x`, `sky`, `z1`, `cc2538dk`, `zoul` and `srf06-cc26xx` are the supported platforms. +To add your own, we refer the reader to the next section. + +To add TSCH to your application, first include the TSCH module from your makefile with: + +`MODULES += core/net/mac/tsch` + +Then, enable TSCH from your project conf with the following: + +``` +/* Netstack layers */ +#undef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC tschmac_driver +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nordc_driver +#undef NETSTACK_CONF_FRAMER +#define NETSTACK_CONF_FRAMER framer_802154 + +/* IEEE802.15.4 frame version */ +#undef FRAME802154_CONF_VERSION +#define FRAME802154_CONF_VERSION FRAME802154_IEEE802154E_2012 +``` + +If you are running with RPL, it is recommended to enable the `tsch-rpl` module with: + +``` +/* TSCH and RPL callbacks */ +#define RPL_CALLBACK_PARENT_SWITCH tsch_rpl_callback_parent_switch +#define RPL_CALLBACK_NEW_DIO_INTERVAL tsch_rpl_callback_new_dio_interval +#define TSCH_CALLBACK_JOINING_NETWORK tsch_rpl_callback_joining_network +#define TSCH_CALLBACK_LEAVING_NETWORK tsch_rpl_callback_leaving_network +``` + +On CC2420-based platforms, enable SFD timestamps with: + +``` +/* Disable DCO calibration (uses timerB) */ +#undef DCOSYNCH_CONF_ENABLED +#define DCOSYNCH_CONF_ENABLED 0 + +/* Enable SFD timestamps (uses timerB) */ +#undef CC2420_CONF_SFD_TIMESTAMPS +#define CC2420_CONF_SFD_TIMESTAMPS 1 +``` + +To configure TSCH, see the macros in `.h` files under `core/net/mac/tsch/` and redefine your own in your `project-conf.h`. + +## Using TSCH with Security + +To include TSCH standard-compliant security, set the following: +``` +/* Enable security */ +#undef LLSEC802154_CONF_ENABLED +#define LLSEC802154_CONF_ENABLED 1 +/* TSCH uses explicit keys to identify k1 and k2 */ +#undef LLSEC802154_CONF_USES_EXPLICIT_KEYS +#define LLSEC802154_CONF_USES_EXPLICIT_KEYS 1 +/* TSCH uses the ASN rather than frame counter to construct the Nonce */ +#undef LLSEC802154_CONF_USES_FRAME_COUNTER +#define LLSEC802154_CONF_USES_FRAME_COUNTER 0 +``` + +The keys can be configured in `net/mac/tsch/tsch-security.h`. +Nodes handle security level and keys dynamically, i.e. as specified by the incoming frame header rather that compile-time defined. + +By default, when including security, the PAN coordinator will transmit secured EBs. +Use `tsch_set_pan_secured` to explicitly ask the coordinator to secure EBs or not. + +When associating, nodes with security included can join both secured or non-secured networks. +Set `TSCH_CONF_JOIN_SECURED_ONLY` to force joining secured networks only. +Likewise, set `TSCH_JOIN_MY_PANID_ONLY` to force joining networks with a specific PANID only. + +## TSCH Scheduling + +By default (see `TSCH_SCHEDULE_WITH_6TISCH_MINIMAL`), our implementation runs a 6TiSCH minimal schedule, which emulates an always-on link on top of TSCH. +The schedule consists in a single shared slot for all transmissions and receptions, in a slotframe of length `TSCH_SCHEDULE_DEFAULT_LENGTH`. + +As an alternative, we provide Orchestra (under `apps/orchestra`), an autonomous scheduling solution for TSCH where nodes maintain their own schedule locally, solely based on their local RPL state. +Orchestra can be simply enabled and should work out-of-the-box with its default settings as long as RPL is also enabled. +See `apps/orchestra/README.md` for more information. + +Finally, one can also implement his own scheduler, centralized or distributed, based on the scheduling API provides in `core/net/mac/tsch/tsch-schedule.h`. + +## Porting TSCH to a new platform + +Porting TSCH to a new platform requires a few new features in the radio driver, a number of timing-related configuration paramters. +The easiest is probably to start from one of the existing port: `jn516x`, `sky`, `z1`, `cc2538dk`, `zoul`, `srf06-cc26xx`. + +### Radio features required for TSCH + +The main new feature required for TSCH is the so-called *poll mode*, a new Rx mode for Contiki radio drivers. +In poll mode, radio interrupts are disabled, and the radio driver never calls upper layers. +Instead, TSCH will poll the driver for incoming packets, from interrupt, exactly when it expects one. + +TSCH will check when initializing (in `tsch_init`) that the radio driver supports all required features, namely: +* get and set Rx mode (`RADIO_PARAM_RX_MODE`) as follows: + * enable address filtering with `RADIO_RX_MODE_ADDRESS_FILTER` + * disable auto-ack with `RADIO_RX_MODE_AUTOACK` + * enable poll mode with `RADIO_RX_MODE_POLL_MODE` +* get and set Tx mode (`RADIO_PARAM_TX_MODE`) as follows: + * disable CCA-before-sending with `RADIO_TX_MODE_SEND_ON_CCA` +* set radio channel with `RADIO_PARAM_CHANNEL` +* get last packet timestamp with `RADIO_PARAM_LAST_PACKET_TIMESTAMP` +* optionally: get last packet RSSI with `RADIO_PARAM_LAST_RSSI` +* optionally: get last packet LQI with `RADIO_PARAM_LAST_LQI` + +### Timing macros required for TSCH + +The following macros must be provided: +* `US_TO_RTIMERTICKS(US)`: converts micro-seconds to rtimer ticks +* `RTIMERTICKS_TO_US(T)`: converts rtimer ticks to micro-seconds +* `RADIO_DELAY_BEFORE_TX`: the delay between radio Tx request and SFD sent, in rtimer ticks +* `RADIO_DELAY_BEFORE_RX`: the delay between radio Rx request and start listening, in rtimer ticks +* optionally, `TSCH_CONF_DEFAULT_TIMESLOT_LENGTH`: the default TSCH timeslot length, useful i.e. for platforms +too slow for the default 10ms timeslots. + +## Additional documentation + +1. [IEEE 802.15.4e-2012 ammendment][ieee802.15.4e-2012] +2. [IETF 6TiSCH Working Group][ietf-6tisch-wg] + +[ieee802.15.4e-2012]: http://standards.ieee.org/getieee802/download/802.15.4e-2012.pdf +[ietf-6tisch-wg]: https://datatracker.ietf.org/wg/6tisch diff --git a/core/net/mac/tsch/tsch-adaptive-timesync.c b/core/net/mac/tsch/tsch-adaptive-timesync.c new file mode 100644 index 000000000..08d4df2ee --- /dev/null +++ b/core/net/mac/tsch/tsch-adaptive-timesync.c @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * TSCH adaptive time synchronization + * \author + * Atis Elsts + * + */ + +#include "tsch-adaptive-timesync.h" +#include "tsch-log.h" +#include + +#if TSCH_ADAPTIVE_TIMESYNC + +/* Estimated drift of the time-source neighbor. Can be negative. + * Units used: ppm multiplied by 256. */ +static int32_t drift_ppm; +/* Ticks compensated locally since the last timesync time */ +static int32_t compensated_ticks; +/* Number of already recorded timesync history entries */ +static uint8_t timesync_entry_count; +/* Since last learning of the drift; may be more than time since last timesync */ +static uint32_t asn_since_last_learning; + +/* Units in which drift is stored: ppm * 256 */ +#define TSCH_DRIFT_UNIT (1000L * 1000 * 256) + +/*---------------------------------------------------------------------------*/ +/* Add a value to a moving average estimator */ +static int32_t +timesync_entry_add(int32_t val, uint32_t time_delta) +{ +#define NUM_TIMESYNC_ENTRIES 8 + static int32_t buffer[NUM_TIMESYNC_ENTRIES]; + static uint8_t pos; + int i; + if(timesync_entry_count == 0) { + pos = 0; + } + buffer[pos] = val; + if(timesync_entry_count < NUM_TIMESYNC_ENTRIES) { + timesync_entry_count++; + } + pos = (pos + 1) % NUM_TIMESYNC_ENTRIES; + + val = 0; + for(i = 0; i < timesync_entry_count; ++i) { + val += buffer[i]; + } + return val / timesync_entry_count; +} +/*---------------------------------------------------------------------------*/ +/* Learn the neighbor drift rate at ppm */ +static void +timesync_learn_drift_ticks(uint32_t time_delta_asn, int32_t drift_ticks) +{ + /* should fit in a 32-bit integer */ + int32_t time_delta_ticks = time_delta_asn * tsch_timing[tsch_ts_timeslot_length]; + int32_t real_drift_ticks = drift_ticks + compensated_ticks; + int32_t last_drift_ppm = (int32_t)((int64_t)real_drift_ticks * TSCH_DRIFT_UNIT / time_delta_ticks); + + drift_ppm = timesync_entry_add(last_drift_ppm, time_delta_ticks); + + TSCH_LOG_ADD(tsch_log_message, + snprintf(log->message, sizeof(log->message), + "drift %ld", drift_ppm / 256)); +} +/*---------------------------------------------------------------------------*/ +/* Either reset or update the neighbor's drift */ +void +tsch_timesync_update(struct tsch_neighbor *n, uint16_t time_delta_asn, int32_t drift_correction) +{ + /* Account the drift if either this is a new timesource, + * or the timedelta is not too small, as smaller timedelta + * means proportionally larger measurement error. */ + if(last_timesource_neighbor != n) { + last_timesource_neighbor = n; + drift_ppm = 0; + timesync_entry_count = 0; + compensated_ticks = 0; + asn_since_last_learning = 0; + } else { + asn_since_last_learning += time_delta_asn; + if(asn_since_last_learning >= 4 * TSCH_SLOTS_PER_SECOND) { + timesync_learn_drift_ticks(asn_since_last_learning, drift_correction); + compensated_ticks = 0; + asn_since_last_learning = 0; + } else { + /* Too small timedelta, do not recalculate the drift to avoid introducing error. instead account for the corrected ticks */ + compensated_ticks += drift_correction; + } + } +} +/*---------------------------------------------------------------------------*/ +/* Error-accumulation free compensation algorithm */ +static int32_t +compensate_internal(uint32_t time_delta_usec, int32_t drift_ppm, int32_t *remainder, int16_t *tick_conversion_error) +{ + int64_t d = (int64_t)time_delta_usec * drift_ppm + *remainder; + int32_t amount = d / TSCH_DRIFT_UNIT; + int32_t amount_ticks; + + *remainder = (int32_t)(d - amount * TSCH_DRIFT_UNIT); + + amount += *tick_conversion_error; + amount_ticks = US_TO_RTIMERTICKS(amount); + *tick_conversion_error = amount - RTIMERTICKS_TO_US(amount_ticks); + + if(ABS(amount_ticks) > RTIMER_ARCH_SECOND / 128) { + TSCH_LOG_ADD(tsch_log_message, + snprintf(log->message, sizeof(log->message), + "!too big compensation %ld delta %ld", amount_ticks, time_delta_usec)); + amount_ticks = (amount_ticks > 0 ? RTIMER_ARCH_SECOND : -RTIMER_ARCH_SECOND) / 128; + } + + return amount_ticks; +} +/*---------------------------------------------------------------------------*/ +/* Do the compensation step before scheduling a new timeslot */ +int32_t +tsch_timesync_adaptive_compensate(rtimer_clock_t time_delta_ticks) +{ + int32_t result = 0; + uint32_t time_delta_usec = RTIMERTICKS_TO_US_64(time_delta_ticks); + + /* compensate, but not if the neighbor is not known */ + if(drift_ppm && last_timesource_neighbor != NULL) { + static int32_t remainder; + static int16_t tick_conversion_error; + result = compensate_internal(time_delta_usec, drift_ppm, + &remainder, &tick_conversion_error); + compensated_ticks += result; + } + + if(TSCH_BASE_DRIFT_PPM) { + static int32_t base_drift_remainder; + static int16_t base_drift_tick_conversion_error; + result += compensate_internal(time_delta_usec, 256L * TSCH_BASE_DRIFT_PPM, + &base_drift_remainder, &base_drift_tick_conversion_error); + } + + return result; +} +/*---------------------------------------------------------------------------*/ +#else /* TSCH_ADAPTIVE_TIMESYNC */ +/*---------------------------------------------------------------------------*/ +void +tsch_timesync_update(struct tsch_neighbor *n, uint16_t time_delta_asn, int32_t drift_correction) +{ +} +/*---------------------------------------------------------------------------*/ +int32_t +tsch_timesync_adaptive_compensate(rtimer_clock_t delta_ticks) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +#endif /* TSCH_ADAPTIVE_TIMESYNC */ diff --git a/core/net/mac/tsch/tsch-adaptive-timesync.h b/core/net/mac/tsch/tsch-adaptive-timesync.h new file mode 100644 index 000000000..d043ca021 --- /dev/null +++ b/core/net/mac/tsch/tsch-adaptive-timesync.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#ifndef __TSCH_ADAPTIVE_TIMESYNC_H__ +#define __TSCH_ADAPTIVE_TIMESYNC_H__ + +/********** Includes **********/ + +#include "contiki.h" +#include "net/mac/tsch/tsch-private.h" + +/******** Configuration *******/ + +/* Use SFD timestamp for synchronization? By default we merely rely on rtimer and busy wait + * until SFD is high, which we found to provide greater accuracy on JN516x and CC2420. + * Note: for association, however, we always use SFD timestamp to know the time of arrival + * of the EB (because we do not busy-wait for the whole scanning process) + * */ +#ifdef TSCH_CONF_RESYNC_WITH_SFD_TIMESTAMPS +#define TSCH_RESYNC_WITH_SFD_TIMESTAMPS TSCH_CONF_RESYNC_WITH_SFD_TIMESTAMPS +#else +#define TSCH_RESYNC_WITH_SFD_TIMESTAMPS 0 +#endif + +/* If enabled, remove jitter due to measurement errors */ +#ifdef TSCH_CONF_TIMESYNC_REMOVE_JITTER +#define TSCH_TIMESYNC_REMOVE_JITTER TSCH_CONF_TIMESYNC_REMOVE_JITTER +#else +#define TSCH_TIMESYNC_REMOVE_JITTER TSCH_RESYNC_WITH_SFD_TIMESTAMPS +#endif + +/* The jitter to remove in ticks. + * This should be the sum of measurement errors on Tx and Rx nodes. + * */ +#define TSCH_TIMESYNC_MEASUREMENT_ERROR US_TO_RTIMERTICKS(32) + +/* Base drift value. + * Used to compensate locally know inaccuracies, such as + * the effect of having a binary 32.768 kHz timer as the TSCH time base. */ +#ifdef TSCH_CONF_BASE_DRIFT_PPM +#define TSCH_BASE_DRIFT_PPM TSCH_CONF_BASE_DRIFT_PPM +#else +#define TSCH_BASE_DRIFT_PPM 0 +#endif + +/* The approximate number of slots per second */ +#define TSCH_SLOTS_PER_SECOND (1000000 / TSCH_DEFAULT_TS_TIMESLOT_LENGTH) + +/***** External Variables *****/ + +/* The neighbor last used as our time source */ +extern struct tsch_neighbor *last_timesource_neighbor; + +/********** Functions *********/ + +void tsch_timesync_update(struct tsch_neighbor *n, uint16_t time_delta_asn, int32_t drift_correction); + +int32_t tsch_timesync_adaptive_compensate(rtimer_clock_t delta_ticks); + +#endif /* __TSCH_ADAPTIVE_TIMESYNC_H__ */ diff --git a/core/net/mac/tsch/tsch-asn.h b/core/net/mac/tsch/tsch-asn.h new file mode 100644 index 000000000..53f7582d4 --- /dev/null +++ b/core/net/mac/tsch/tsch-asn.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * TSCH 5-Byte Absolute Slot Number (ASN) management + * \author + * Simon Duquennoy + * + */ + +#ifndef __TSCH_ASN_H__ +#define __TSCH_ASN_H__ + +/************ Types ***********/ + +/* The ASN is an absolute slot number over 5 bytes. */ +struct asn_t { + uint32_t ls4b; /* least significant 4 bytes */ + uint8_t ms1b; /* most significant 1 byte */ +}; + +/* For quick modulo operation on ASN */ +struct asn_divisor_t { + uint16_t val; /* Divisor value */ + uint16_t asn_ms1b_remainder; /* Remainder of the operation 0x100000000 / val */ +}; + +/************ Macros **********/ + +/* Initialize ASN */ +#define ASN_INIT(asn, ms1b_, ls4b_) do { \ + (asn).ms1b = (ms1b_); \ + (asn).ls4b = (ls4b_); \ +} while(0); + +/* Increment an ASN by inc (32 bits) */ +#define ASN_INC(asn, inc) do { \ + uint32_t new_ls4b = (asn).ls4b + (inc); \ + if(new_ls4b < (asn).ls4b) { (asn).ms1b++; } \ + (asn).ls4b = new_ls4b; \ +} while(0); + +/* Decrement an ASN by inc (32 bits) */ +#define ASN_DEC(asn, dec) do { \ + uint32_t new_ls4b = (asn).ls4b - (dec); \ + if(new_ls4b > (asn).ls4b) { (asn).ms1b--; } \ + (asn).ls4b = new_ls4b; \ +} while(0); + +/* Returns the 32-bit diff between asn1 and asn2 */ +#define ASN_DIFF(asn1, asn2) \ + ((asn1).ls4b - (asn2).ls4b) + +/* Initialize a struct asn_divisor_t */ +#define ASN_DIVISOR_INIT(div, val_) do { \ + (div).val = (val_); \ + (div).asn_ms1b_remainder = ((0xffffffff % (val_)) + 1) % (val_); \ +} while(0); + +/* Returns the result (16 bits) of a modulo operation on ASN, + * with divisor being a struct asn_divisor_t */ +#define ASN_MOD(asn, div) \ + ((uint16_t)((asn).ls4b % (div).val) \ + + (uint16_t)((asn).ms1b * (div).asn_ms1b_remainder % (div).val)) \ + % (div).val + +#endif /* __TSCH_ASN_H__ */ diff --git a/core/net/mac/tsch/tsch-conf.h b/core/net/mac/tsch/tsch-conf.h new file mode 100644 index 000000000..d8d58f0ff --- /dev/null +++ b/core/net/mac/tsch/tsch-conf.h @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * TSCH configuration + * \author + * Simon Duquennoy + */ + +#ifndef __TSCH_CONF_H__ +#define __TSCH_CONF_H__ + +/********** Includes **********/ + +#include "contiki.h" + +/******** Configuration *******/ + +/* Default IEEE 802.15.4e hopping sequences, obtained from https://gist.github.com/twatteyne/2e22ee3c1a802b685695 */ +/* 16 channels, sequence length 16 */ +#define TSCH_HOPPING_SEQUENCE_16_16 (uint8_t[]){ 16, 17, 23, 18, 26, 15, 25, 22, 19, 11, 12, 13, 24, 14, 20, 21 } +/* 4 channels, sequence length 16 */ +#define TSCH_HOPPING_SEQUENCE_4_16 (uint8_t[]){ 20, 26, 25, 26, 15, 15, 25, 20, 26, 15, 26, 25, 20, 15, 20, 25 } +/* 4 channels, sequence length 4 */ +#define TSCH_HOPPING_SEQUENCE_4_4 (uint8_t[]){ 15, 25, 26, 20 } +/* 2 channels, sequence length 2 */ +#define TSCH_HOPPING_SEQUENCE_2_2 (uint8_t[]){ 20, 25 } +/* 1 channel, sequence length 1 */ +#define TSCH_HOPPING_SEQUENCE_1_1 (uint8_t[]){ 20 } + +/* Default hopping sequence, used in case hopping sequence ID == 0 */ +#ifdef TSCH_CONF_DEFAULT_HOPPING_SEQUENCE +#define TSCH_DEFAULT_HOPPING_SEQUENCE TSCH_CONF_DEFAULT_HOPPING_SEQUENCE +#else +#define TSCH_DEFAULT_HOPPING_SEQUENCE TSCH_HOPPING_SEQUENCE_4_4 +#endif + +/* Hopping sequence used for joining (scan channels) */ +#ifdef TSCH_CONF_JOIN_HOPPING_SEQUENCE +#define TSCH_JOIN_HOPPING_SEQUENCE TSCH_CONF_JOIN_HOPPING_SEQUENCE +#else +#define TSCH_JOIN_HOPPING_SEQUENCE TSCH_DEFAULT_HOPPING_SEQUENCE +#endif + +/* Maximum length of the TSCH channel hopping sequence. Must be greater or + * equal to the length of TSCH_DEFAULT_HOPPING_SEQUENCE. */ +#ifdef TSCH_CONF_HOPPING_SEQUENCE_MAX_LEN +#define TSCH_HOPPING_SEQUENCE_MAX_LEN TSCH_CONF_HOPPING_SEQUENCE_MAX_LEN +#else +#define TSCH_HOPPING_SEQUENCE_MAX_LEN 16 +#endif + +/* Timeslot timing */ + +#ifndef TSCH_CONF_DEFAULT_TIMESLOT_LENGTH +#define TSCH_CONF_DEFAULT_TIMESLOT_LENGTH 10000 +#endif /* TSCH_CONF_DEFAULT_TIMESLOT_LENGTH */ + +/* Configurable Rx guard time is micro-seconds */ +#ifndef TSCH_CONF_RX_WAIT +#define TSCH_CONF_RX_WAIT 2200 +#endif /* TSCH_CONF_RX_WAIT */ + +/* The default timeslot timing in the standard is a guard time of + * 2200 us, a Tx offset of 2120 us and a Rx offset of 1120 us. + * As a result, the listening device has a guard time not centered + * on the expected Tx time. This is to be fixed in the next iteration + * of the standard. This can be enabled with: + * #define TSCH_DEFAULT_TS_TX_OFFSET 2120 + * #define TSCH_DEFAULT_TS_RX_OFFSET 1120 + * #define TSCH_DEFAULT_TS_RX_WAIT 2200 + * + * Instead, we align the Rx guard time on expected Tx time. The Rx + * guard time is user-configurable with TSCH_CONF_RX_WAIT. + + * (TS_TX_OFFSET - (TS_RX_WAIT / 2)) instead */ + +#if TSCH_CONF_DEFAULT_TIMESLOT_LENGTH == 10000 +/* Default timeslot timing as per IEEE 802.15.4e */ + +#define TSCH_DEFAULT_TS_CCA_OFFSET 1800 +#define TSCH_DEFAULT_TS_CCA 128 +#define TSCH_DEFAULT_TS_TX_OFFSET 2120 +#define TSCH_DEFAULT_TS_RX_OFFSET (TSCH_DEFAULT_TS_TX_OFFSET - (TSCH_CONF_RX_WAIT / 2)) +#define TSCH_DEFAULT_TS_RX_ACK_DELAY 800 +#define TSCH_DEFAULT_TS_TX_ACK_DELAY 1000 +#define TSCH_DEFAULT_TS_RX_WAIT TSCH_CONF_RX_WAIT +#define TSCH_DEFAULT_TS_ACK_WAIT 400 +#define TSCH_DEFAULT_TS_RX_TX 192 +#define TSCH_DEFAULT_TS_MAX_ACK 2400 +#define TSCH_DEFAULT_TS_MAX_TX 4256 +#define TSCH_DEFAULT_TS_TIMESLOT_LENGTH 10000 + +#elif TSCH_CONF_DEFAULT_TIMESLOT_LENGTH == 15000 +/* Default timeslot timing for platforms requiring 15ms slots */ + +#define TSCH_DEFAULT_TS_CCA_OFFSET 1800 +#define TSCH_DEFAULT_TS_CCA 128 +#define TSCH_DEFAULT_TS_TX_OFFSET 4000 +#define TSCH_DEFAULT_TS_RX_OFFSET (TSCH_DEFAULT_TS_TX_OFFSET - (TSCH_CONF_RX_WAIT / 2)) +#define TSCH_DEFAULT_TS_RX_ACK_DELAY 3600 +#define TSCH_DEFAULT_TS_TX_ACK_DELAY 4000 +#define TSCH_DEFAULT_TS_RX_WAIT TSCH_CONF_RX_WAIT +#define TSCH_DEFAULT_TS_ACK_WAIT 800 +#define TSCH_DEFAULT_TS_RX_TX 2072 +#define TSCH_DEFAULT_TS_MAX_ACK 2400 +#define TSCH_DEFAULT_TS_MAX_TX 4256 +#define TSCH_DEFAULT_TS_TIMESLOT_LENGTH 15000 + +#elif TSCH_CONF_DEFAULT_TIMESLOT_LENGTH == 65000U +/* 65ms timeslot, i.e. nearly the max length allowed by standard (16-bit unsigned in micro-seconds). + * Useful for running link-layer security on sky or z1 in Cooja, where only S/W security is supported. + * Note: this slot timing would require a total of 120ms. If a slot overlaps with the next active slot, + * the latter will be skipped. + * This configuration is mostly a work-around to test link-layer security in Cooja, it is recommended + * to use it with a 6TiSCH minimal schedule of length >= 2. */ + +#define TSCH_DEFAULT_TS_CCA_OFFSET 1800 +#define TSCH_DEFAULT_TS_CCA 128 +#define TSCH_DEFAULT_TS_TX_OFFSET 52000 +#define TSCH_DEFAULT_TS_RX_OFFSET (TSCH_DEFAULT_TS_TX_OFFSET - (TSCH_CONF_RX_WAIT / 2)) +#define TSCH_DEFAULT_TS_RX_ACK_DELAY 58600 +#define TSCH_DEFAULT_TS_TX_ACK_DELAY 59000 +#define TSCH_DEFAULT_TS_RX_WAIT TSCH_CONF_RX_WAIT +#define TSCH_DEFAULT_TS_ACK_WAIT 800 +#define TSCH_DEFAULT_TS_RX_TX 2072 +#define TSCH_DEFAULT_TS_MAX_ACK 2400 +#define TSCH_DEFAULT_TS_MAX_TX 4256 +#define TSCH_DEFAULT_TS_TIMESLOT_LENGTH 65000 + +#else +#error "TSCH: Unsupported default timeslot length" +#endif + +/* A custom feature allowing upper layers to assign packets to + * a specific slotframe and link */ +#ifdef TSCH_CONF_WITH_LINK_SELECTOR +#define TSCH_WITH_LINK_SELECTOR TSCH_CONF_WITH_LINK_SELECTOR +#else /* TSCH_CONF_WITH_LINK_SELECTOR */ +#define TSCH_WITH_LINK_SELECTOR 0 +#endif /* TSCH_CONF_WITH_LINK_SELECTOR */ + +/* Estimate the drift of the time-source neighbor and compensate for it? */ +#ifdef TSCH_CONF_ADAPTIVE_TIMESYNC +#define TSCH_ADAPTIVE_TIMESYNC TSCH_CONF_ADAPTIVE_TIMESYNC +#else +#define TSCH_ADAPTIVE_TIMESYNC 0 +#endif + +/* HW frame filtering enabled */ +#ifdef TSCH_CONF_HW_FRAME_FILTERING +#define TSCH_HW_FRAME_FILTERING TSCH_CONF_HW_FRAME_FILTERING +#else /* TSCH_CONF_HW_FRAME_FILTERING */ +#define TSCH_HW_FRAME_FILTERING 1 +#endif /* TSCH_CONF_HW_FRAME_FILTERING */ + +/* Keep radio always on within TSCH timeslot (1) or turn it off between packet and ACK? (0) */ +#ifdef TSCH_CONF_RADIO_ON_DURING_TIMESLOT +#define TSCH_RADIO_ON_DURING_TIMESLOT TSCH_CONF_RADIO_ON_DURING_TIMESLOT +#else +#define TSCH_RADIO_ON_DURING_TIMESLOT 0 +#endif + +/* How long to scan each channel in the scanning phase */ +#ifdef TSCH_CONF_CHANNEL_SCAN_DURATION +#define TSCH_CHANNEL_SCAN_DURATION TSCH_CONF_CHANNEL_SCAN_DURATION +#else +#define TSCH_CHANNEL_SCAN_DURATION CLOCK_SECOND +#endif + +#endif /* __TSCH_CONF_H__ */ diff --git a/core/net/mac/tsch/tsch-log.c b/core/net/mac/tsch/tsch-log.c new file mode 100644 index 000000000..8ab23215b --- /dev/null +++ b/core/net/mac/tsch/tsch-log.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Log functions for TSCH, meant for logging from interrupt + * during a timeslot operation. Saves ASN, slot and link information + * and adds the log to a ringbuf for later printout. + * \author + * Simon Duquennoy + * + */ + +#include "contiki.h" +#include +#include "net/mac/tsch/tsch.h" +#include "net/mac/tsch/tsch-queue.h" +#include "net/mac/tsch/tsch-private.h" +#include "net/mac/tsch/tsch-log.h" +#include "net/mac/tsch/tsch-packet.h" +#include "net/mac/tsch/tsch-schedule.h" +#include "net/mac/tsch/tsch-slot-operation.h" +#include "lib/ringbufindex.h" + +#if TSCH_LOG_LEVEL >= 1 +#define DEBUG DEBUG_PRINT +#else /* TSCH_LOG_LEVEL */ +#define DEBUG DEBUG_NONE +#endif /* TSCH_LOG_LEVEL */ +#include "net/net-debug.h" + +#if TSCH_LOG_LEVEL >= 2 /* Skip this file for log levels 0 or 1 */ + +PROCESS_NAME(tsch_pending_events_process); + +/* Check if TSCH_LOG_QUEUE_LEN is a power of two */ +#if (TSCH_LOG_QUEUE_LEN & (TSCH_LOG_QUEUE_LEN - 1)) != 0 +#error TSCH_LOG_QUEUE_LEN must be power of two +#endif +static struct ringbufindex log_ringbuf; +static struct tsch_log_t log_array[TSCH_LOG_QUEUE_LEN]; +static int log_dropped = 0; + +/*---------------------------------------------------------------------------*/ +/* Process pending log messages */ +void +tsch_log_process_pending(void) +{ + static int last_log_dropped = 0; + int16_t log_index; + /* Loop on accessing (without removing) a pending input packet */ + if(log_dropped != last_log_dropped) { + printf("TSCH:! logs dropped %u\n", log_dropped); + last_log_dropped = log_dropped; + } + while((log_index = ringbufindex_peek_get(&log_ringbuf)) != -1) { + struct tsch_log_t *log = &log_array[log_index]; + if(log->link == NULL) { + printf("TSCH: {asn-%x.%lx link-NULL} ", log->asn.ms1b, log->asn.ls4b); + } else { + struct tsch_slotframe *sf = tsch_schedule_get_slotframe_by_handle(log->link->slotframe_handle); + printf("TSCH: {asn-%x.%lx link-%u-%u-%u-%u ch-%u} ", + log->asn.ms1b, log->asn.ls4b, + log->link->slotframe_handle, sf ? sf->size.val : 0, log->link->timeslot, log->link->channel_offset, + tsch_calculate_channel(&log->asn, log->link->channel_offset)); + } + switch(log->type) { + case tsch_log_tx: + printf("%s-%u-%u %u tx %d, st %d-%d", + log->tx.dest == 0 ? "bc" : "uc", log->tx.is_data, log->tx.sec_level, + log->tx.datalen, + log->tx.dest, + log->tx.mac_tx_status, log->tx.num_tx); + if(log->tx.drift_used) { + printf(", dr %d", log->tx.drift); + } + printf("\n"); + break; + case tsch_log_rx: + printf("%s-%u-%u %u rx %d", + log->rx.is_unicast == 0 ? "bc" : "uc", log->rx.is_data, log->rx.sec_level, + log->rx.datalen, + log->rx.src); + if(log->rx.drift_used) { + printf(", dr %d", log->rx.drift); + } + printf(", edr %d\n", (int)log->rx.estimated_drift); + break; + case tsch_log_message: + printf("%s\n", log->message); + break; + } + /* Remove input from ringbuf */ + ringbufindex_get(&log_ringbuf); + } +} +/*---------------------------------------------------------------------------*/ +/* Prepare addition of a new log. + * Returns pointer to log structure if success, NULL otherwise */ +struct tsch_log_t * +tsch_log_prepare_add(void) +{ + int log_index = ringbufindex_peek_put(&log_ringbuf); + if(log_index != -1) { + struct tsch_log_t *log = &log_array[log_index]; + log->asn = current_asn; + log->link = current_link; + return log; + } else { + log_dropped++; + return NULL; + } +} +/*---------------------------------------------------------------------------*/ +/* Actually add the previously prepared log */ +void +tsch_log_commit(void) +{ + ringbufindex_put(&log_ringbuf); + process_poll(&tsch_pending_events_process); +} +/*---------------------------------------------------------------------------*/ +/* Initialize log module */ +void +tsch_log_init(void) +{ + ringbufindex_init(&log_ringbuf, TSCH_LOG_QUEUE_LEN); +} + +#endif /* TSCH_LOG_LEVEL */ diff --git a/core/net/mac/tsch/tsch-log.h b/core/net/mac/tsch/tsch-log.h new file mode 100644 index 000000000..9b8032577 --- /dev/null +++ b/core/net/mac/tsch/tsch-log.h @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#ifndef __TSCH_LOG_H__ +#define __TSCH_LOG_H__ + +/********** Includes **********/ + +#include "contiki.h" +#include "sys/rtimer.h" +#include "net/mac/tsch/tsch-private.h" + +/******** Configuration *******/ + +/* The length of the log queue, i.e. maximum number postponed log messages */ +#ifdef TSCH_LOG_CONF_QUEUE_LEN +#define TSCH_LOG_QUEUE_LEN TSCH_LOG_CONF_QUEUE_LEN +#else /* TSCH_LOG_CONF_QUEUE_LEN */ +#define TSCH_LOG_QUEUE_LEN 8 +#endif /* TSCH_LOG_CONF_QUEUE_LEN */ + +/* Returns an integer ID from a link-layer address */ +#ifdef TSCH_LOG_CONF_ID_FROM_LINKADDR +#define TSCH_LOG_ID_FROM_LINKADDR(addr) TSCH_LOG_CONF_ID_FROM_LINKADDR(addr) +#else /* TSCH_LOG_ID_FROM_LINKADDR */ +#define TSCH_LOG_ID_FROM_LINKADDR(addr) ((addr) ? (addr)->u8[LINKADDR_SIZE - 1] : 0) +#endif /* TSCH_LOG_ID_FROM_LINKADDR */ + +/* TSCH log levels: + * 0: no log + * 1: basic PRINTF enabled + * 2: basic PRINTF enabled and tsch-log module enabled */ +#ifdef TSCH_LOG_CONF_LEVEL +#define TSCH_LOG_LEVEL TSCH_LOG_CONF_LEVEL +#else /* TSCH_LOG_CONF_LEVEL */ +#define TSCH_LOG_LEVEL 2 +#endif /* TSCH_LOG_CONF_LEVEL */ + +#if TSCH_LOG_LEVEL < 2 /* For log level 0 or 1, the logging functions do nothing */ + +#define tsch_log_init() +#define tsch_log_process_pending() +#define TSCH_LOG_ADD(log_type, init_code) + +#else /* TSCH_LOG_LEVEL */ + +/************ Types ***********/ + +/* Structure for a log. Union of different types of logs */ +struct tsch_log_t { + enum { tsch_log_tx, + tsch_log_rx, + tsch_log_message + } type; + struct asn_t asn; + struct tsch_link *link; + union { + char message[48]; + struct { + int mac_tx_status; + int dest; + int drift; + uint8_t num_tx; + uint8_t datalen; + uint8_t is_data; + uint8_t sec_level; + uint8_t drift_used; + } tx; + struct { + int src; + int drift; + int estimated_drift; + uint8_t datalen; + uint8_t is_unicast; + uint8_t is_data; + uint8_t sec_level; + uint8_t drift_used; + } rx; + }; +}; + +/********** Functions *********/ + +/* Prepare addition of a new log. + * Returns pointer to log structure if success, NULL otherwise */ +struct tsch_log_t *tsch_log_prepare_add(void); +/* Actually add the previously prepared log */ +void tsch_log_commit(void); +/* Initialize log module */ +void tsch_log_init(void); +/* Process pending log messages */ +void tsch_log_process_pending(void); + +/************ Macros **********/ + +/* Use this macro to add a log to the queue (will be printed out + * later, after leaving interrupt context) */ +#define TSCH_LOG_ADD(log_type, init_code) do { \ + struct tsch_log_t *log = tsch_log_prepare_add(); \ + if(log != NULL) { \ + log->type = (log_type); \ + init_code; \ + tsch_log_commit(); \ + } \ +} while(0); + +#endif /* TSCH_LOG_LEVEL */ + +#endif /* __TSCH_LOG_H__ */ diff --git a/core/net/mac/tsch/tsch-packet.c b/core/net/mac/tsch/tsch-packet.c new file mode 100644 index 000000000..17601d054 --- /dev/null +++ b/core/net/mac/tsch/tsch-packet.c @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * TSCH packet format management + * \author + * Simon Duquennoy + * Beshr Al Nahas + */ + +#include "contiki.h" +#include "net/packetbuf.h" +#include "net/mac/tsch/tsch.h" +#include "net/mac/tsch/tsch-packet.h" +#include "net/mac/tsch/tsch-private.h" +#include "net/mac/tsch/tsch-schedule.h" +#include "net/mac/tsch/tsch-security.h" +#include "net/mac/tsch/tsch-log.h" +#include "net/mac/frame802154.h" +#include "net/mac/framer-802154.h" +#include "net/netstack.h" +#include "net/llsec/anti-replay.h" +#include "lib/ccm-star.h" +#include "lib/aes-128.h" +#include +#include + +#if TSCH_LOG_LEVEL >= 1 +#define DEBUG DEBUG_PRINT +#else /* TSCH_LOG_LEVEL */ +#define DEBUG DEBUG_NONE +#endif /* TSCH_LOG_LEVEL */ +#include "net/net-debug.h" + +/*---------------------------------------------------------------------------*/ +/* Construct enhanced ACK packet and return ACK length */ +int +tsch_packet_create_eack(uint8_t *buf, int buf_size, + linkaddr_t *dest_addr, uint8_t seqno, int16_t drift, int nack) +{ + int ret; + uint8_t curr_len = 0; + frame802154_t p; + struct ieee802154_ies ies; + + memset(&p, 0, sizeof(p)); + p.fcf.frame_type = FRAME802154_ACKFRAME; + p.fcf.frame_version = FRAME802154_IEEE802154E_2012; + p.fcf.ie_list_present = 1; + /* Compression unset. According to IEEE802.15.4e-2012: + * - if no address is present: elide PAN ID + * - if at least one address is present: include exactly one PAN ID (dest by default) */ + p.fcf.panid_compression = 0; + p.dest_pid = IEEE802154_PANID; + p.seq = seqno; +#if TSCH_PACKET_EACK_WITH_DEST_ADDR + if(dest_addr != NULL) { + p.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE; + linkaddr_copy((linkaddr_t *)&p.dest_addr, dest_addr); + } +#endif +#if TSCH_PACKET_EACK_WITH_SRC_ADDR + p.fcf.src_addr_mode = FRAME802154_LONGADDRMODE; + p.src_pid = IEEE802154_PANID; + linkaddr_copy((linkaddr_t *)&p.src_addr, &linkaddr_node_addr); +#endif +#if LLSEC802154_ENABLED + if(tsch_is_pan_secured) { + p.fcf.security_enabled = 1; + p.aux_hdr.security_control.security_level = TSCH_SECURITY_KEY_SEC_LEVEL_ACK; + p.aux_hdr.security_control.key_id_mode = FRAME802154_1_BYTE_KEY_ID_MODE; + p.aux_hdr.security_control.frame_counter_suppression = 1; + p.aux_hdr.security_control.frame_counter_size = 1; + p.aux_hdr.key_index = TSCH_SECURITY_KEY_INDEX_ACK; + } +#endif /* LLSEC802154_ENABLED */ + + if((curr_len = frame802154_create(&p, buf)) == 0) { + return 0; + } + + /* Append IE timesync */ + memset(&ies, 0, sizeof(ies)); + ies.ie_time_correction = drift; + ies.ie_is_nack = nack; + + if((ret = frame80215e_create_ie_header_ack_nack_time_correction(buf+curr_len, buf_size-curr_len, &ies)) == -1) { + return -1; + } + curr_len += ret; + + return curr_len; +} +/*---------------------------------------------------------------------------*/ +/* Parse enhanced ACK packet, extract drift and nack */ +int +tsch_packet_parse_eack(const uint8_t *buf, int buf_size, + uint8_t seqno, frame802154_t *frame, struct ieee802154_ies *ies, uint8_t *hdr_len) +{ + uint8_t curr_len = 0; + int ret; + linkaddr_t dest; + + if(frame == NULL || buf_size < 0) { + return 0; + } + /* Parse 802.15.4-2006 frame, i.e. all fields before Information Elements */ + if((ret = frame802154_parse((uint8_t *)buf, buf_size, frame)) < 3) { + return 0; + } + if(hdr_len != NULL) { + *hdr_len = ret; + } + curr_len += ret; + + /* Check seqno */ + if(seqno != frame->seq) { + return 0; + } + + /* Check destination PAN ID */ + if(frame802154_check_dest_panid(frame) == 0) { + return 0; + } + + /* Check destination address (if any) */ + if(frame802154_extract_linkaddr(frame, NULL, &dest) == 0 || + (!linkaddr_cmp(&dest, &linkaddr_node_addr) + && !linkaddr_cmp(&dest, &linkaddr_null))) { + return 0; + } + + if(ies != NULL) { + memset(ies, 0, sizeof(struct ieee802154_ies)); + } + + if(frame->fcf.ie_list_present) { + int mic_len = 0; +#if LLSEC802154_ENABLED + /* Check if there is space for the security MIC (if any) */ + mic_len = tsch_security_mic_len(frame); + if(buf_size < curr_len + mic_len) { + return 0; + } +#endif /* LLSEC802154_ENABLED */ + /* Parse information elements. We need to substract the MIC length, as the exact payload len is needed while parsing */ + if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) { + return 0; + } + curr_len += ret; + } + + if(hdr_len != NULL) { + *hdr_len += ies->ie_payload_ie_offset; + } + + return curr_len; +} +/*---------------------------------------------------------------------------*/ +/* Create an EB packet */ +int +tsch_packet_create_eb(uint8_t *buf, int buf_size, uint8_t seqno, + uint8_t *hdr_len, uint8_t *tsch_sync_ie_offset) +{ + int ret = 0; + uint8_t curr_len = 0; + uint8_t mlme_ie_offset; + + frame802154_t p; + struct ieee802154_ies ies; + + if(buf_size < TSCH_PACKET_MAX_LEN) { + return 0; + } + + /* Create 802.15.4 header */ + memset(&p, 0, sizeof(p)); + p.fcf.frame_type = FRAME802154_BEACONFRAME; + p.fcf.ie_list_present = 1; + p.fcf.frame_version = FRAME802154_IEEE802154E_2012; + p.fcf.src_addr_mode = FRAME802154_LONGADDRMODE; + p.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; + p.seq = seqno; + p.fcf.sequence_number_suppression = FRAME802154_SUPPR_SEQNO; + /* It is important not to compress PAN ID, as this would result in not including either + * source nor destination PAN ID, leaving potential joining devices unaware of the PAN ID. */ + p.fcf.panid_compression = 0; + + p.src_pid = frame802154_get_pan_id(); + p.dest_pid = frame802154_get_pan_id(); + linkaddr_copy((linkaddr_t *)&p.src_addr, &linkaddr_node_addr); + p.dest_addr[0] = 0xff; + p.dest_addr[1] = 0xff; + +#if LLSEC802154_ENABLED + if(tsch_is_pan_secured) { + p.fcf.security_enabled = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0; + p.aux_hdr.security_control.security_level = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL); + p.aux_hdr.security_control.key_id_mode = packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE); + p.aux_hdr.security_control.frame_counter_suppression = 1; + p.aux_hdr.security_control.frame_counter_size = 1; + p.aux_hdr.key_index = packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX); + } +#endif /* LLSEC802154_ENABLED */ + + if((curr_len = frame802154_create(&p, buf)) == 0) { + return 0; + } + + /* Prepare Information Elements for inclusion in the EB */ + memset(&ies, 0, sizeof(ies)); + + /* Add TSCH timeslot timing IE. */ +#if TSCH_PACKET_EB_WITH_TIMESLOT_TIMING + { + int i; + ies.ie_tsch_timeslot_id = 1; + for(i = 0; i < tsch_ts_elements_count; i++) { + ies.ie_tsch_timeslot[i] = RTIMERTICKS_TO_US(tsch_timing[i]); + } + } +#endif /* TSCH_PACKET_EB_WITH_TIMESLOT_TIMING */ + + /* Add TSCH hopping sequence IE */ +#if TSCH_PACKET_EB_WITH_HOPPING_SEQUENCE + if(tsch_hopping_sequence_length.val <= sizeof(ies.ie_hopping_sequence_list)) { + ies.ie_channel_hopping_sequence_id = 1; + ies.ie_hopping_sequence_len = tsch_hopping_sequence_length.val; + memcpy(ies.ie_hopping_sequence_list, tsch_hopping_sequence, ies.ie_hopping_sequence_len); + } +#endif /* TSCH_PACKET_EB_WITH_HOPPING_SEQUENCE */ + + /* Add Slotframe and Link IE */ +#if TSCH_PACKET_EB_WITH_SLOTFRAME_AND_LINK + { + /* Send slotframe 0 with link at timeslot 0 */ + struct tsch_slotframe *sf0 = tsch_schedule_get_slotframe_by_handle(0); + struct tsch_link *link0 = tsch_schedule_get_link_by_timeslot(sf0, 0); + if(sf0 && link0) { + ies.ie_tsch_slotframe_and_link.num_slotframes = 1; + ies.ie_tsch_slotframe_and_link.slotframe_handle = sf0->handle; + ies.ie_tsch_slotframe_and_link.slotframe_size = sf0->size.val; + ies.ie_tsch_slotframe_and_link.num_links = 1; + ies.ie_tsch_slotframe_and_link.links[0].timeslot = link0->timeslot; + ies.ie_tsch_slotframe_and_link.links[0].channel_offset = link0->channel_offset; + ies.ie_tsch_slotframe_and_link.links[0].link_options = link0->link_options; + } + } +#endif /* TSCH_PACKET_EB_WITH_SLOTFRAME_AND_LINK */ + + /* First add header-IE termination IE to stipulate that next come payload IEs */ + if((ret = frame80215e_create_ie_header_list_termination_1(buf + curr_len, buf_size - curr_len, &ies)) == -1) { + return -1; + } + curr_len += ret; + + /* We start payload IEs, save offset */ + if(hdr_len != NULL) { + *hdr_len = curr_len; + } + + /* Save offset of the MLME IE descriptor, we need to know the total length + * before writing it */ + mlme_ie_offset = curr_len; + curr_len += 2; /* Space needed for MLME descriptor */ + + /* Save the offset of the TSCH Synchronization IE, needed to update ASN and join priority before sending */ + if(tsch_sync_ie_offset != NULL) { + *tsch_sync_ie_offset = curr_len; + } + if((ret = frame80215e_create_ie_tsch_synchronization(buf + curr_len, buf_size - curr_len, &ies)) == -1) { + return -1; + } + curr_len += ret; + + if((ret = frame80215e_create_ie_tsch_timeslot(buf + curr_len, buf_size - curr_len, &ies)) == -1) { + return -1; + } + curr_len += ret; + + if((ret = frame80215e_create_ie_tsch_channel_hopping_sequence(buf + curr_len, buf_size - curr_len, &ies)) == -1) { + return -1; + } + curr_len += ret; + + if((ret = frame80215e_create_ie_tsch_slotframe_and_link(buf + curr_len, buf_size - curr_len, &ies)) == -1) { + return -1; + } + curr_len += ret; + + ies.ie_mlme_len = curr_len - mlme_ie_offset - 2; + if((ret = frame80215e_create_ie_mlme(buf + mlme_ie_offset, buf_size - mlme_ie_offset, &ies)) == -1) { + return -1; + } + + /* Payload IE list termination: optional */ + /* + if((ret = frame80215e_create_ie_payload_list_termination(buf + curr_len, buf_size - curr_len, &ies)) == -1) { + return -1; + } + curr_len += ret; + */ + + return curr_len; +} +/*---------------------------------------------------------------------------*/ +/* Update ASN in EB packet */ +int +tsch_packet_update_eb(uint8_t *buf, int buf_size, uint8_t tsch_sync_ie_offset) +{ + struct ieee802154_ies ies; + ies.ie_asn = current_asn; + ies.ie_join_priority = tsch_join_priority; + frame80215e_create_ie_tsch_synchronization(buf+tsch_sync_ie_offset, buf_size-tsch_sync_ie_offset, &ies); + return 1; +} +/*---------------------------------------------------------------------------*/ +/* Parse a IEEE 802.15.4e TSCH Enhanced Beacon (EB) */ +int +tsch_packet_parse_eb(const uint8_t *buf, int buf_size, + frame802154_t *frame, struct ieee802154_ies *ies, uint8_t *hdr_len, int frame_without_mic) +{ + uint8_t curr_len = 0; + int ret; + + if(frame == NULL || buf_size < 0) { + return 0; + } + + /* Parse 802.15.4-2006 frame, i.e. all fields before Information Elements */ + if((ret = frame802154_parse((uint8_t *)buf, buf_size, frame)) == 0) { + PRINTF("TSCH:! parse_eb: failed to parse frame\n"); + return 0; + } + + if(frame->fcf.frame_version < FRAME802154_IEEE802154E_2012 + || frame->fcf.frame_type != FRAME802154_BEACONFRAME) { + PRINTF("TSCH:! parse_eb: frame is not a valid TSCH beacon. Frame version %u, type %u, FCF %02x %02x\n", + frame->fcf.frame_version, frame->fcf.frame_type, buf[0], buf[1]); + PRINTF("TSCH:! parse_eb: frame was from 0x%x/", frame->src_pid); + PRINTLLADDR((const uip_lladdr_t *)&frame->src_addr); + PRINTF(" to 0x%x/", frame->dest_pid); + PRINTLLADDR((const uip_lladdr_t *)&frame->dest_addr); + PRINTF("\n"); + return 0; + } + + if(hdr_len != NULL) { + *hdr_len = ret; + } + curr_len += ret; + + if(ies != NULL) { + memset(ies, 0, sizeof(struct ieee802154_ies)); + ies->ie_join_priority = 0xff; /* Use max value in case the Beacon does not include a join priority */ + } + if(frame->fcf.ie_list_present) { + /* Calculate space needed for the security MIC, if any, before attempting to parse IEs */ + int mic_len = 0; +#if LLSEC802154_ENABLED + if(!frame_without_mic) { + mic_len = tsch_security_mic_len(frame); + if(buf_size < curr_len + mic_len) { + return 0; + } + } +#endif /* LLSEC802154_ENABLED */ + + /* Parse information elements. We need to substract the MIC length, as the exact payload len is needed while parsing */ + if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) { + PRINTF("TSCH:! parse_eb: failed to parse IEs\n"); + return 0; + } + curr_len += ret; + } + + if(hdr_len != NULL) { + *hdr_len += ies->ie_payload_ie_offset; + } + + return curr_len; +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/mac/tsch/tsch-packet.h b/core/net/mac/tsch/tsch-packet.h new file mode 100644 index 000000000..c48bd479b --- /dev/null +++ b/core/net/mac/tsch/tsch-packet.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#ifndef __TSCH_PACKET_H__ +#define __TSCH_PACKET_H__ + +/********** Includes **********/ + +#include "contiki.h" +#include "net/packetbuf.h" +#include "net/mac/tsch/tsch-private.h" +#include "net/mac/frame802154.h" +#include "net/mac/frame802154e-ie.h" + +/******** Configuration *******/ + +/* TSCH EB: include timeslot timing Information Element? */ +#ifdef TSCH_PACKET_CONF_EB_WITH_TIMESLOT_TIMING +#define TSCH_PACKET_EB_WITH_TIMESLOT_TIMING TSCH_PACKET_CONF_EB_WITH_TIMESLOT_TIMING +#else +#define TSCH_PACKET_EB_WITH_TIMESLOT_TIMING 0 +#endif + +/* TSCH EB: include hopping sequence Information Element? */ +#ifdef TSCH_PACKET_CONF_EB_WITH_HOPPING_SEQUENCE +#define TSCH_PACKET_EB_WITH_HOPPING_SEQUENCE TSCH_PACKET_CONF_EB_WITH_HOPPING_SEQUENCE +#else +#define TSCH_PACKET_EB_WITH_HOPPING_SEQUENCE 0 +#endif + +/* TSCH EB: include slotframe and link Information Element? */ +#ifdef TSCH_PACKET_CONF_EB_WITH_SLOTFRAME_AND_LINK +#define TSCH_PACKET_EB_WITH_SLOTFRAME_AND_LINK TSCH_PACKET_CONF_EB_WITH_SLOTFRAME_AND_LINK +#else +#define TSCH_PACKET_EB_WITH_SLOTFRAME_AND_LINK 0 +#endif + +/* Include source address in ACK? */ +#ifdef TSCH_PACKET_CONF_EACK_WITH_SRC_ADDR +#define TSCH_PACKET_EACK_WITH_SRC_ADDR TSCH_PACKET_CONF_EACK_WITH_SRC_ADDR +#else +#define TSCH_PACKET_EACK_WITH_SRC_ADDR 0 +#endif + +/* Include destination address in ACK? */ +#ifdef TSCH_PACKET_CONF_EACK_WITH_DEST_ADDR +#define TSCH_PACKET_EACK_WITH_DEST_ADDR TSCH_PACKET_CONF_EACK_WITH_DEST_ADDR +#else +#define TSCH_PACKET_EACK_WITH_DEST_ADDR 1 /* Include destination address +by default, useful in case of duplicate seqno */ +#endif + +/********** Constants *********/ + +/* Max TSCH packet lenght */ +#define TSCH_PACKET_MAX_LEN MIN(127,PACKETBUF_SIZE) + +/********** Functions *********/ + +/* Construct enhanced ACK packet and return ACK length */ +int tsch_packet_create_eack(uint8_t *buf, int buf_size, + linkaddr_t *dest_addr, uint8_t seqno, int16_t drift, int nack); +/* Parse enhanced ACK packet, extract drift and nack */ +int tsch_packet_parse_eack(const uint8_t *buf, int buf_size, + uint8_t seqno, frame802154_t *frame, struct ieee802154_ies *ies, uint8_t *hdr_len); +/* Create an EB packet */ +int tsch_packet_create_eb(uint8_t *buf, int buf_size, + uint8_t seqno, uint8_t *hdr_len, uint8_t *tsch_sync_ie_ptr); +/* Update ASN in EB packet */ +int tsch_packet_update_eb(uint8_t *buf, int buf_size, uint8_t tsch_sync_ie_offset); +/* Parse EB and extract ASN and join priority */ +int tsch_packet_parse_eb(const uint8_t *buf, int buf_size, + frame802154_t *frame, struct ieee802154_ies *ies, + uint8_t *hdrlen, int frame_without_mic); + +#endif /* __TSCH_PACKET_H__ */ diff --git a/core/net/mac/tsch/tsch-private.h b/core/net/mac/tsch/tsch-private.h new file mode 100644 index 000000000..4a26abff3 --- /dev/null +++ b/core/net/mac/tsch/tsch-private.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Private TSCH definitions + * (meant for use by TSCH implementation files only) + * \author + * Simon Duquennoy + * Beshr Al Nahas + */ + +#ifndef __TSCH_PRIVATE_H__ +#define __TSCH_PRIVATE_H__ + +/********** Includes **********/ + +#include "contiki.h" +#include "net/linkaddr.h" +#include "net/mac/tsch/tsch-asn.h" +#include "net/mac/tsch/tsch-conf.h" + +/************ Types ***********/ + +/* TSCH timeslot timing elements. Used to index timeslot timing + * of different units, such as rtimer tick or micro-second */ +enum tsch_timeslot_timing_elements { + tsch_ts_cca_offset, + tsch_ts_cca, + tsch_ts_tx_offset, + tsch_ts_rx_offset, + tsch_ts_rx_ack_delay, + tsch_ts_tx_ack_delay, + tsch_ts_rx_wait, + tsch_ts_ack_wait, + tsch_ts_rx_tx, + tsch_ts_max_ack, + tsch_ts_max_tx, + tsch_ts_timeslot_length, + tsch_ts_elements_count, /* Not a timing element */ +}; + +/***** External Variables *****/ + +/* 802.15.4 broadcast MAC address */ +extern const linkaddr_t tsch_broadcast_address; +/* The address we use to identify EB queue */ +extern const linkaddr_t tsch_eb_address; +/* The current Absolute Slot Number (ASN) */ +extern struct asn_t current_asn; +extern uint8_t tsch_join_priority; +extern struct tsch_link *current_link; +/* TSCH channel hopping sequence */ +extern uint8_t tsch_hopping_sequence[TSCH_HOPPING_SEQUENCE_MAX_LEN]; +extern struct asn_divisor_t tsch_hopping_sequence_length; +/* TSCH timeslot timing (in rtimer ticks) */ +extern rtimer_clock_t tsch_timing[tsch_ts_elements_count]; + +/* TSCH processes */ +PROCESS_NAME(tsch_process); +PROCESS_NAME(tsch_send_eb_process); +PROCESS_NAME(tsch_pending_events_process); + +/********** Functions *********/ + +/* Set TSCH to send a keepalive message after TSCH_KEEPALIVE_TIMEOUT */ +void tsch_schedule_keepalive(void); +/* Leave the TSCH network */ +void tsch_disassociate(void); + +/************ Macros **********/ + +/* Calculate packet tx/rx duration in rtimer ticks based on sent + * packet len in bytes with 802.15.4 250kbps data rate. + * One byte = 32us. Add two bytes for CRC and one for len field */ +#define TSCH_PACKET_DURATION(len) US_TO_RTIMERTICKS(32 * ((len) + 3)) + +/* Convert rtimer ticks to clock and vice versa */ +#define TSCH_CLOCK_TO_TICKS(c) (((c) * RTIMER_SECOND) / CLOCK_SECOND) +#define TSCH_CLOCK_TO_SLOTS(c, timeslot_length) (TSCH_CLOCK_TO_TICKS(c) / timeslot_length) + +/* Wait for a condition with timeout t0+offset. */ +#define BUSYWAIT_UNTIL_ABS(cond, t0, offset) \ + while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), (t0) + (offset))) ; + +#endif /* __TSCH_PRIVATE_H__ */ diff --git a/core/net/mac/tsch/tsch-queue.c b/core/net/mac/tsch/tsch-queue.c new file mode 100644 index 000000000..e3f60f45c --- /dev/null +++ b/core/net/mac/tsch/tsch-queue.c @@ -0,0 +1,470 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Per-neighbor packet queues for TSCH MAC. + * The list of neighbors uses the TSCH lock, but per-neighbor packet array are lock-free. + * Read-only operation on neighbor and packets are allowed from interrupts and outside of them. + * *Other operations are allowed outside of interrupt only.* + * \author + * Simon Duquennoy + * Beshr Al Nahas + * Domenico De Guglielmo + */ + +#include "contiki.h" +#include "lib/list.h" +#include "lib/memb.h" +#include "lib/random.h" +#include "net/queuebuf.h" +#include "net/mac/rdc.h" +#include "net/mac/tsch/tsch.h" +#include "net/mac/tsch/tsch-private.h" +#include "net/mac/tsch/tsch-queue.h" +#include "net/mac/tsch/tsch-schedule.h" +#include "net/mac/tsch/tsch-slot-operation.h" +#include "net/mac/tsch/tsch-log.h" +#include + +#if TSCH_LOG_LEVEL >= 1 +#define DEBUG DEBUG_PRINT +#else /* TSCH_LOG_LEVEL */ +#define DEBUG DEBUG_NONE +#endif /* TSCH_LOG_LEVEL */ +#include "net/net-debug.h" + +/* Check if TSCH_QUEUE_NUM_PER_NEIGHBOR is power of two */ +#if (TSCH_QUEUE_NUM_PER_NEIGHBOR & (TSCH_QUEUE_NUM_PER_NEIGHBOR - 1)) != 0 +#error TSCH_QUEUE_NUM_PER_NEIGHBOR must be power of two +#endif + +/* We have as many packets are there are queuebuf in the system */ +MEMB(packet_memb, struct tsch_packet, QUEUEBUF_NUM); +MEMB(neighbor_memb, struct tsch_neighbor, TSCH_QUEUE_MAX_NEIGHBOR_QUEUES); +LIST(neighbor_list); + +/* Broadcast and EB virtual neighbors */ +struct tsch_neighbor *n_broadcast; +struct tsch_neighbor *n_eb; + +/*---------------------------------------------------------------------------*/ +/* Add a TSCH neighbor */ +struct tsch_neighbor * +tsch_queue_add_nbr(const linkaddr_t *addr) +{ + struct tsch_neighbor *n = NULL; + /* If we have an entry for this neighbor already, we simply update it */ + n = tsch_queue_get_nbr(addr); + if(n == NULL) { + if(tsch_get_lock()) { + /* Allocate a neighbor */ + n = memb_alloc(&neighbor_memb); + if(n != NULL) { + /* Initialize neighbor entry */ + memset(n, 0, sizeof(struct tsch_neighbor)); + ringbufindex_init(&n->tx_ringbuf, TSCH_QUEUE_NUM_PER_NEIGHBOR); + linkaddr_copy(&n->addr, addr); + n->is_broadcast = linkaddr_cmp(addr, &tsch_eb_address) + || linkaddr_cmp(addr, &tsch_broadcast_address); + tsch_queue_backoff_reset(n); + /* Add neighbor to the list */ + list_add(neighbor_list, n); + } + tsch_release_lock(); + } + } + return n; +} +/*---------------------------------------------------------------------------*/ +/* Get a TSCH neighbor */ +struct tsch_neighbor * +tsch_queue_get_nbr(const linkaddr_t *addr) +{ + if(!tsch_is_locked()) { + struct tsch_neighbor *n = list_head(neighbor_list); + while(n != NULL) { + if(linkaddr_cmp(&n->addr, addr)) { + return n; + } + n = list_item_next(n); + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +/* Get a TSCH time source (we currently assume there is only one) */ +struct tsch_neighbor * +tsch_queue_get_time_source(void) +{ + if(!tsch_is_locked()) { + struct tsch_neighbor *curr_nbr = list_head(neighbor_list); + while(curr_nbr != NULL) { + if(curr_nbr->is_time_source) { + return curr_nbr; + } + curr_nbr = list_item_next(curr_nbr); + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +/* Update TSCH time source */ +int +tsch_queue_update_time_source(const linkaddr_t *new_addr) +{ + if(!tsch_is_locked()) { + if(!tsch_is_coordinator) { + struct tsch_neighbor *old_time_src = tsch_queue_get_time_source(); + struct tsch_neighbor *new_time_src = NULL; + + if(new_addr != NULL) { + /* Get/add neighbor, return 0 in case of failure */ + new_time_src = tsch_queue_add_nbr(new_addr); + if(new_time_src == NULL) { + return 0; + } + } + + if(new_time_src != old_time_src) { + PRINTF("TSCH: update time source: %u -> %u\n", + TSCH_LOG_ID_FROM_LINKADDR(old_time_src ? &old_time_src->addr : NULL), + TSCH_LOG_ID_FROM_LINKADDR(new_time_src ? &new_time_src->addr : NULL)); + + /* Update time source */ + if(new_time_src != NULL) { + new_time_src->is_time_source = 1; + } + + if(old_time_src != NULL) { + old_time_src->is_time_source = 0; + } + +#ifdef TSCH_CALLBACK_NEW_TIME_SOURCE + TSCH_CALLBACK_NEW_TIME_SOURCE(old_time_src, new_time_src); +#endif + } + + return 1; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +/* Flush a neighbor queue */ +static void +tsch_queue_flush_nbr_queue(struct tsch_neighbor *n) +{ + while(!tsch_queue_is_empty(n)) { + struct tsch_packet *p = tsch_queue_remove_packet_from_queue(n); + if(p != NULL) { + /* Set return status for packet_sent callback */ + p->ret = MAC_TX_ERR; + PRINTF("TSCH-queue:! flushing packet\n"); + /* Call packet_sent callback */ + mac_call_sent_callback(p->sent, p->ptr, p->ret, p->transmissions); + /* Free packet queuebuf */ + tsch_queue_free_packet(p); + } + } +} +/*---------------------------------------------------------------------------*/ +/* Remove TSCH neighbor queue */ +static void +tsch_queue_remove_nbr(struct tsch_neighbor *n) +{ + if(n != NULL) { + if(tsch_get_lock()) { + + /* Remove neighbor from list */ + list_remove(neighbor_list, n); + + tsch_release_lock(); + + /* Flush queue */ + tsch_queue_flush_nbr_queue(n); + + /* Free neighbor */ + memb_free(&neighbor_memb, n); + } + } +} +/*---------------------------------------------------------------------------*/ +/* Add packet to neighbor queue. Use same lockfree implementation as ringbuf.c (put is atomic) */ +struct tsch_packet * +tsch_queue_add_packet(const linkaddr_t *addr, mac_callback_t sent, void *ptr) +{ + struct tsch_neighbor *n = NULL; + int16_t put_index = -1; + struct tsch_packet *p = NULL; + if(!tsch_is_locked()) { + n = tsch_queue_add_nbr(addr); + if(n != NULL) { + put_index = ringbufindex_peek_put(&n->tx_ringbuf); + if(put_index != -1) { + p = memb_alloc(&packet_memb); + if(p != NULL) { + /* Enqueue packet */ +#ifdef TSCH_CALLBACK_PACKET_READY + TSCH_CALLBACK_PACKET_READY(); +#endif + p->qb = queuebuf_new_from_packetbuf(); + if(p->qb != NULL) { + p->sent = sent; + p->ptr = ptr; + p->ret = MAC_TX_DEFERRED; + p->transmissions = 0; + /* Add to ringbuf (actual add committed through atomic operation) */ + n->tx_array[put_index] = p; + ringbufindex_put(&n->tx_ringbuf); + return p; + } else { + memb_free(&packet_memb, p); + } + } + } + } + } + PRINTF("TSCH-queue:! add packet failed: %u %p %d %p %p\n", tsch_is_locked(), n, put_index, p, p ? p->qb : NULL); + return 0; +} +/*---------------------------------------------------------------------------*/ +/* Returns the number of packets currently in the queue */ +int +tsch_queue_packet_count(const linkaddr_t *addr) +{ + struct tsch_neighbor *n = NULL; + if(!tsch_is_locked()) { + n = tsch_queue_add_nbr(addr); + if(n != NULL) { + return ringbufindex_elements(&n->tx_ringbuf); + } + } + return -1; +} +/*---------------------------------------------------------------------------*/ +/* Remove first packet from a neighbor queue */ +struct tsch_packet * +tsch_queue_remove_packet_from_queue(struct tsch_neighbor *n) +{ + if(!tsch_is_locked()) { + if(n != NULL) { + /* Get and remove packet from ringbuf (remove committed through an atomic operation */ + int16_t get_index = ringbufindex_get(&n->tx_ringbuf); + if(get_index != -1) { + return n->tx_array[get_index]; + } else { + return NULL; + } + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +/* Free a packet */ +void +tsch_queue_free_packet(struct tsch_packet *p) +{ + if(p != NULL) { + queuebuf_free(p->qb); + memb_free(&packet_memb, p); + } +} +/*---------------------------------------------------------------------------*/ +/* Flush all neighbor queues */ +void +tsch_queue_reset(void) +{ + /* Deallocate unneeded neighbors */ + if(!tsch_is_locked()) { + struct tsch_neighbor *n = list_head(neighbor_list); + while(n != NULL) { + struct tsch_neighbor *next_n = list_item_next(n); + /* Flush queue */ + tsch_queue_flush_nbr_queue(n); + /* Reset backoff exponent */ + tsch_queue_backoff_reset(n); + n = next_n; + } + } +} +/*---------------------------------------------------------------------------*/ +/* Deallocate neighbors with empty queue */ +void +tsch_queue_free_unused_neighbors(void) +{ + /* Deallocate unneeded neighbors */ + if(!tsch_is_locked()) { + struct tsch_neighbor *n = list_head(neighbor_list); + while(n != NULL) { + struct tsch_neighbor *next_n = list_item_next(n); + /* Queue is empty, no tx link to this neighbor: deallocate. + * Always keep time source and virtual broadcast neighbors. */ + if(!n->is_broadcast && !n->is_time_source && !n->tx_links_count + && tsch_queue_is_empty(n)) { + tsch_queue_remove_nbr(n); + } + n = next_n; + } + } +} +/*---------------------------------------------------------------------------*/ +/* Is the neighbor queue empty? */ +int +tsch_queue_is_empty(const struct tsch_neighbor *n) +{ + return !tsch_is_locked() && n != NULL && ringbufindex_empty(&n->tx_ringbuf); +} +/*---------------------------------------------------------------------------*/ +/* Returns the first packet from a neighbor queue */ +struct tsch_packet * +tsch_queue_get_packet_for_nbr(const struct tsch_neighbor *n, struct tsch_link *link) +{ + if(!tsch_is_locked()) { + int is_shared_link = link != NULL && link->link_options & LINK_OPTION_SHARED; + if(n != NULL) { + int16_t get_index = ringbufindex_peek_get(&n->tx_ringbuf); + if(get_index != -1 && + !(is_shared_link && !tsch_queue_backoff_expired(n))) { /* If this is a shared link, + make sure the backoff has expired */ +#if TSCH_WITH_LINK_SELECTOR + int packet_attr_slotframe = queuebuf_attr(n->tx_array[get_index]->qb, PACKETBUF_ATTR_TSCH_SLOTFRAME); + int packet_attr_timeslot = queuebuf_attr(n->tx_array[get_index]->qb, PACKETBUF_ATTR_TSCH_TIMESLOT); + if(packet_attr_slotframe != 0xffff && packet_attr_slotframe != link->slotframe_handle) { + return NULL; + } + if(packet_attr_timeslot != 0xffff && packet_attr_timeslot != link->timeslot) { + return NULL; + } +#endif + return n->tx_array[get_index]; + } + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +/* Returns the head packet from a neighbor queue (from neighbor address) */ +struct tsch_packet * +tsch_queue_get_packet_for_dest_addr(const linkaddr_t *addr, struct tsch_link *link) +{ + if(!tsch_is_locked()) { + return tsch_queue_get_packet_for_nbr(tsch_queue_get_nbr(addr), link); + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +/* Returns the head packet of any neighbor queue with zero backoff counter. + * Writes pointer to the neighbor in *n */ +struct tsch_packet * +tsch_queue_get_unicast_packet_for_any(struct tsch_neighbor **n, struct tsch_link *link) +{ + if(!tsch_is_locked()) { + struct tsch_neighbor *curr_nbr = list_head(neighbor_list); + struct tsch_packet *p = NULL; + while(curr_nbr != NULL) { + if(!curr_nbr->is_broadcast && curr_nbr->tx_links_count == 0) { + /* Only look up for non-broadcast neighbors we do not have a tx link to */ + p = tsch_queue_get_packet_for_nbr(curr_nbr, link); + if(p != NULL) { + if(n != NULL) { + *n = curr_nbr; + } + return p; + } + } + curr_nbr = list_item_next(curr_nbr); + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +/* May the neighbor transmit over a shared link? */ +int +tsch_queue_backoff_expired(const struct tsch_neighbor *n) +{ + return n->backoff_window == 0; +} +/*---------------------------------------------------------------------------*/ +/* Reset neighbor backoff */ +void +tsch_queue_backoff_reset(struct tsch_neighbor *n) +{ + n->backoff_window = 0; + n->backoff_exponent = TSCH_MAC_MIN_BE; +} +/*---------------------------------------------------------------------------*/ +/* Increment backoff exponent, pick a new window */ +void +tsch_queue_backoff_inc(struct tsch_neighbor *n) +{ + /* Increment exponent */ + n->backoff_exponent = MIN(n->backoff_exponent + 1, TSCH_MAC_MAX_BE); + /* Pick a window (number of shared slots to skip). Ignore least significant + * few bits, which, on some embedded implementations of rand (e.g. msp430-libc), + * are known to have poor pseudo-random properties. */ + n->backoff_window = (random_rand() >> 6) % (1 << n->backoff_exponent); + /* Add one to the window as we will decrement it at the end of the current slot + * through tsch_queue_update_all_backoff_windows */ + n->backoff_window++; +} +/*---------------------------------------------------------------------------*/ +/* Decrement backoff window for all queues directed at dest_addr */ +void +tsch_queue_update_all_backoff_windows(const linkaddr_t *dest_addr) +{ + if(!tsch_is_locked()) { + int is_broadcast = linkaddr_cmp(dest_addr, &tsch_broadcast_address); + struct tsch_neighbor *n = list_head(neighbor_list); + while(n != NULL) { + if(n->backoff_window != 0 /* Is the queue in backoff state? */ + && ((n->tx_links_count == 0 && is_broadcast) + || (n->tx_links_count > 0 && linkaddr_cmp(dest_addr, &n->addr)))) { + n->backoff_window--; + } + n = list_item_next(n); + } + } +} +/*---------------------------------------------------------------------------*/ +/* Initialize TSCH queue module */ +void +tsch_queue_init(void) +{ + list_init(neighbor_list); + memb_init(&neighbor_memb); + memb_init(&packet_memb); + /* Add virtual EB and the broadcast neighbors */ + n_eb = tsch_queue_add_nbr(&tsch_eb_address); + n_broadcast = tsch_queue_add_nbr(&tsch_broadcast_address); +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/mac/tsch/tsch-queue.h b/core/net/mac/tsch/tsch-queue.h new file mode 100644 index 000000000..676619a3a --- /dev/null +++ b/core/net/mac/tsch/tsch-queue.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#ifndef __TSCH_QUEUE_H__ +#define __TSCH_QUEUE_H__ + +/********** Includes **********/ + +#include "contiki.h" +#include "lib/ringbufindex.h" +#include "net/linkaddr.h" +#include "net/mac/tsch/tsch-schedule.h" +#include "net/mac/mac.h" + +/******** Configuration *******/ + +/* The maximum number of outgoing packets towards each neighbor + * Must be power of two to enable atomic ringbuf operations. + * Note: the total number of outgoing packets in the system (for + * all neighbors) is defined via QUEUEBUF_CONF_NUM */ +#ifdef TSCH_QUEUE_CONF_NUM_PER_NEIGHBOR +#define TSCH_QUEUE_NUM_PER_NEIGHBOR TSCH_QUEUE_CONF_NUM_PER_NEIGHBOR +#else +/* By default, round QUEUEBUF_CONF_NUM to next power of two + * (in the range [4;256]) */ +#if QUEUEBUF_CONF_NUM <= 4 +#define TSCH_QUEUE_NUM_PER_NEIGHBOR 4 +#elif QUEUEBUF_CONF_NUM <= 8 +#define TSCH_QUEUE_NUM_PER_NEIGHBOR 8 +#elif QUEUEBUF_CONF_NUM <= 16 +#define TSCH_QUEUE_NUM_PER_NEIGHBOR 16 +#elif QUEUEBUF_CONF_NUM <= 32 +#define TSCH_QUEUE_NUM_PER_NEIGHBOR 32 +#elif QUEUEBUF_CONF_NUM <= 64 +#define TSCH_QUEUE_NUM_PER_NEIGHBOR 64 +#elif QUEUEBUF_CONF_NUM <= 128 +#define TSCH_QUEUE_NUM_PER_NEIGHBOR 128 +#else +#define TSCH_QUEUE_NUM_PER_NEIGHBOR 256 +#endif +#endif + +/* The number of neighbor queues. There are two queues allocated at all times: + * one for EBs, one for broadcasts. Other queues are for unicast to neighbors */ +#ifdef TSCH_QUEUE_CONF_MAX_NEIGHBOR_QUEUES +#define TSCH_QUEUE_MAX_NEIGHBOR_QUEUES TSCH_QUEUE_CONF_MAX_NEIGHBOR_QUEUES +#else +#define TSCH_QUEUE_MAX_NEIGHBOR_QUEUES ((NBR_TABLE_CONF_MAX_NEIGHBORS) + 2) +#endif + +/* TSCH CSMA-CA parameters, see IEEE 802.15.4e-2012 */ +/* Min backoff exponent */ +#ifdef TSCH_CONF_MAC_MIN_BE +#define TSCH_MAC_MIN_BE TSCH_CONF_MAC_MIN_BE +#else +#define TSCH_MAC_MIN_BE 1 +#endif +/* Max backoff exponent */ +#ifdef TSCH_CONF_MAC_MAX_BE +#define TSCH_MAC_MAX_BE TSCH_CONF_MAC_MAX_BE +#else +#define TSCH_MAC_MAX_BE 7 +#endif +/* Max number of re-transmissions */ +#ifdef TSCH_CONF_MAC_MAX_FRAME_RETRIES +#define TSCH_MAC_MAX_FRAME_RETRIES TSCH_CONF_MAC_MAX_FRAME_RETRIES +#else +#define TSCH_MAC_MAX_FRAME_RETRIES 8 +#endif + +/*********** Callbacks *********/ + +/* Called by TSCH when switching time source */ +#ifdef TSCH_CALLBACK_NEW_TIME_SOURCE +struct tsch_neighbor; +void TSCH_CALLBACK_NEW_TIME_SOURCE(const struct tsch_neighbor *old, const struct tsch_neighbor *new); +#endif + +/* Called by TSCH every time a packet is ready to be added to the send queue */ +#ifdef TSCH_CALLBACK_PACKET_READY +void TSCH_CALLBACK_PACKET_READY(void); +#endif + +/************ Types ***********/ + +/* TSCH packet information */ +struct tsch_packet { + struct queuebuf *qb; /* pointer to the queuebuf to be sent */ + mac_callback_t sent; /* callback for this packet */ + void *ptr; /* MAC callback parameter */ + uint8_t transmissions; /* #transmissions performed for this packet */ + uint8_t ret; /* status -- MAC return code */ + uint8_t header_len; /* length of header and header IEs (needed for link-layer security) */ + uint8_t tsch_sync_ie_offset; /* Offset within the frame used for quick update of EB ASN and join priority */ +}; + +/* TSCH neighbor information */ +struct tsch_neighbor { + /* Neighbors are stored as a list: "next" must be the first field */ + struct tsch_neighbor *next; + linkaddr_t addr; /* MAC address of the neighbor */ + uint8_t is_broadcast; /* is this neighbor a virtual neighbor used for broadcast (of data packets or EBs) */ + uint8_t is_time_source; /* is this neighbor a time source? */ + uint8_t backoff_exponent; /* CSMA backoff exponent */ + uint8_t backoff_window; /* CSMA backoff window (number of slots to skip) */ + uint8_t last_backoff_window; /* Last CSMA backoff window */ + uint8_t tx_links_count; /* How many links do we have to this neighbor? */ + uint8_t dedicated_tx_links_count; /* How many dedicated links do we have to this neighbor? */ + /* Array for the ringbuf. Contains pointers to packets. + * Its size must be a power of two to allow for atomic put */ + struct tsch_packet *tx_array[TSCH_QUEUE_NUM_PER_NEIGHBOR]; + /* Circular buffer of pointers to packet. */ + struct ringbufindex tx_ringbuf; +}; + +/***** External Variables *****/ + +/* Broadcast and EB virtual neighbors */ +extern struct tsch_neighbor *n_broadcast; +extern struct tsch_neighbor *n_eb; + +/********** Functions *********/ + +/* Add a TSCH neighbor */ +struct tsch_neighbor *tsch_queue_add_nbr(const linkaddr_t *addr); +/* Get a TSCH neighbor */ +struct tsch_neighbor *tsch_queue_get_nbr(const linkaddr_t *addr); +/* Get a TSCH time source (we currently assume there is only one) */ +struct tsch_neighbor *tsch_queue_get_time_source(void); +/* Update TSCH time source */ +int tsch_queue_update_time_source(const linkaddr_t *new_addr); +/* Add packet to neighbor queue. Use same lockfree implementation as ringbuf.c (put is atomic) */ +struct tsch_packet *tsch_queue_add_packet(const linkaddr_t *addr, mac_callback_t sent, void *ptr); +/* Returns the number of packets currently a given neighbor queue */ +int tsch_queue_packet_count(const linkaddr_t *addr); +/* Remove first packet from a neighbor queue. The packet is stored in a separate + * dequeued packet list, for later processing. Return the packet. */ +struct tsch_packet *tsch_queue_remove_packet_from_queue(struct tsch_neighbor *n); +/* Free a packet */ +void tsch_queue_free_packet(struct tsch_packet *p); +/* Reset neighbor queues */ +void tsch_queue_reset(void); +/* Deallocate neighbors with empty queue */ +void tsch_queue_free_unused_neighbors(void); +/* Is the neighbor queue empty? */ +int tsch_queue_is_empty(const struct tsch_neighbor *n); +/* Returns the first packet from a neighbor queue */ +struct tsch_packet *tsch_queue_get_packet_for_nbr(const struct tsch_neighbor *n, struct tsch_link *link); +/* Returns the head packet from a neighbor queue (from neighbor address) */ +struct tsch_packet *tsch_queue_get_packet_for_dest_addr(const linkaddr_t *addr, struct tsch_link *link); +/* Returns the head packet of any neighbor queue with zero backoff counter. + * Writes pointer to the neighbor in *n */ +struct tsch_packet *tsch_queue_get_unicast_packet_for_any(struct tsch_neighbor **n, struct tsch_link *link); +/* May the neighbor transmit over a share link? */ +int tsch_queue_backoff_expired(const struct tsch_neighbor *n); +/* Reset neighbor backoff */ +void tsch_queue_backoff_reset(struct tsch_neighbor *n); +/* Increment backoff exponent, pick a new window */ +void tsch_queue_backoff_inc(struct tsch_neighbor *n); +/* Decrement backoff window for all queues directed at dest_addr */ +void tsch_queue_update_all_backoff_windows(const linkaddr_t *dest_addr); +/* Initialize TSCH queue module */ +void tsch_queue_init(void); + +#endif /* __TSCH_QUEUE_H__ */ diff --git a/core/net/mac/tsch/tsch-rpl.c b/core/net/mac/tsch/tsch-rpl.c new file mode 100644 index 000000000..4558c4366 --- /dev/null +++ b/core/net/mac/tsch/tsch-rpl.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file + * Interaction between TSCH and RPL + * + * \author Simon Duquennoy + */ + +#if UIP_CONF_IPV6_RPL + +#include "contiki.h" +#include "net/rpl/rpl.h" +#include "net/rpl/rpl-private.h" +#include "net/mac/tsch/tsch.h" +#include "net/mac/tsch/tsch-private.h" +#include "net/mac/tsch/tsch-schedule.h" +#include "net/mac/tsch/tsch-log.h" +#include "tsch-rpl.h" + +#if TSCH_LOG_LEVEL >= 1 +#define DEBUG DEBUG_PRINT +#else /* TSCH_LOG_LEVEL */ +#define DEBUG DEBUG_NONE +#endif /* TSCH_LOG_LEVEL */ +#include "net/net-debug.h" + +/*---------------------------------------------------------------------------*/ +/* To use, set #define TSCH_CALLBACK_JOINING_NETWORK tsch_rpl_callback_joining_network */ +void +tsch_rpl_callback_joining_network(void) +{ +} +/*---------------------------------------------------------------------------*/ +/* Upon leaving a TSCH network, perform a local repair + * (cleanup neighbor state, reset Trickle timer etc) + * To use, set #define TSCH_CALLBACK_LEAVING_NETWORK tsch_rpl_callback_leaving_network */ +void +tsch_rpl_callback_leaving_network(void) +{ + rpl_dag_t *dag = rpl_get_any_dag(); + if(dag != NULL) { + rpl_local_repair(dag->instance); + } +} +/*---------------------------------------------------------------------------*/ +/* Set TSCH EB period based on current RPL DIO period. + * To use, set #define RPL_CALLBACK_NEW_DIO_INTERVAL tsch_rpl_callback_new_dio_interval */ +void +tsch_rpl_callback_new_dio_interval(uint8_t dio_interval) +{ + /* Transmit EBs only if we have a valid rank as per 6TiSCH minimal */ + rpl_dag_t *dag = rpl_get_any_dag(); + if(dag != NULL && dag->rank != INFINITE_RANK) { + /* If we are root set TSCH as coordinator */ + if(dag->rank == ROOT_RANK(dag->instance)) { + tsch_set_coordinator(1); + } + /* Set EB period */ + tsch_set_eb_period(TSCH_EB_PERIOD); + /* Set join priority based on RPL rank */ + tsch_set_join_priority(DAG_RANK(dag->rank, dag->instance) - 1); + } else { + tsch_set_eb_period(0); + } +} +/*---------------------------------------------------------------------------*/ +/* Set TSCH time source based on current RPL preferred parent. + * To use, set #define RPL_CALLBACK_PARENT_SWITCH tsch_rpl_callback_parent_switch */ +void +tsch_rpl_callback_parent_switch(rpl_parent_t *old, rpl_parent_t *new) +{ + if(tsch_is_associated == 1) { + tsch_queue_update_time_source( + (const linkaddr_t *)uip_ds6_nbr_lladdr_from_ipaddr( + rpl_get_parent_ipaddr(new))); + } +} +#endif /* UIP_CONF_IPV6_RPL */ diff --git a/core/net/mac/tsch/tsch-rpl.h b/core/net/mac/tsch/tsch-rpl.h new file mode 100644 index 000000000..43d7b0d2a --- /dev/null +++ b/core/net/mac/tsch/tsch-rpl.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + + +#ifndef __TSCH_RPL_H__ +#define __TSCH_RPL_H__ + +/********** Includes **********/ + +#include "net/rpl/rpl.h" +#include "net/mac/tsch/tsch-queue.h" + +/********** Functions *********/ + +/* To use, set #define TSCH_CALLBACK_JOINING_NETWORK tsch_rpl_callback_joining_network */ +void tsch_rpl_callback_joining_network(void); +/* Upon leaving a TSCH network, perform a local repair + * (cleanup neighbor state, reset Trickle timer etc) + * To use, set #define TSCH_CALLBACK_LEAVING_NETWORK tsch_rpl_callback_leaving_network */ +void tsch_rpl_callback_leaving_network(void); +/* Set TSCH EB period based on current RPL DIO period. + * To use, set #define RPL_CALLBACK_PARENT_SWITCH tsch_rpl_callback_new_dio_interval */ +void tsch_rpl_callback_new_dio_interval(uint8_t dio_interval); +/* Set TSCH time source based on current RPL preferred parent. + * To use, set #define RPL_CALLBACK_PARENT_SWITCH tsch_rpl_callback_parent_switch */ +void tsch_rpl_callback_parent_switch(rpl_parent_t *old, rpl_parent_t *new); + +#endif /* __TSCH_RPL_H__ */ diff --git a/core/net/mac/tsch/tsch-schedule.c b/core/net/mac/tsch/tsch-schedule.c new file mode 100644 index 000000000..0a61b5f12 --- /dev/null +++ b/core/net/mac/tsch/tsch-schedule.c @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * IEEE 802.15.4 TSCH MAC schedule manager. + * \author + * Simon Duquennoy + * Beshr Al Nahas + */ + +#include "contiki.h" +#include "dev/leds.h" +#include "lib/memb.h" +#include "net/nbr-table.h" +#include "net/packetbuf.h" +#include "net/queuebuf.h" +#include "net/mac/tsch/tsch.h" +#include "net/mac/tsch/tsch-queue.h" +#include "net/mac/tsch/tsch-private.h" +#include "net/mac/tsch/tsch-packet.h" +#include "net/mac/tsch/tsch-schedule.h" +#include "net/mac/tsch/tsch-log.h" +#include "net/mac/frame802154.h" +#include "sys/process.h" +#include "sys/rtimer.h" +#include + +#if TSCH_LOG_LEVEL >= 1 +#define DEBUG DEBUG_PRINT +#else /* TSCH_LOG_LEVEL */ +#define DEBUG DEBUG_NONE +#endif /* TSCH_LOG_LEVEL */ +#include "net/net-debug.h" + +/* Pre-allocated space for links */ +MEMB(link_memb, struct tsch_link, TSCH_SCHEDULE_MAX_LINKS); +/* Pre-allocated space for slotframes */ +MEMB(slotframe_memb, struct tsch_slotframe, TSCH_SCHEDULE_MAX_SLOTFRAMES); +/* List of slotframes (each slotframe holds its own list of links) */ +LIST(slotframe_list); + +/* Adds and returns a slotframe (NULL if failure) */ +struct tsch_slotframe * +tsch_schedule_add_slotframe(uint16_t handle, uint16_t size) +{ + if(size == 0) { + return NULL; + } + + if(tsch_schedule_get_slotframe_by_handle(handle)) { + /* A slotframe with this handle already exists */ + return NULL; + } + + if(tsch_get_lock()) { + struct tsch_slotframe *sf = memb_alloc(&slotframe_memb); + if(sf != NULL) { + /* Initialize the slotframe */ + sf->handle = handle; + ASN_DIVISOR_INIT(sf->size, size); + LIST_STRUCT_INIT(sf, links_list); + /* Add the slotframe to the global list */ + list_add(slotframe_list, sf); + } + PRINTF("TSCH-schedule: add_slotframe %u %u\n", + handle, size); + tsch_release_lock(); + return sf; + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +/* Removes all slotframes, resulting in an empty schedule */ +int +tsch_schedule_remove_all_slotframes(void) +{ + struct tsch_slotframe *sf; + while((sf = list_head(slotframe_list))) { + if(tsch_schedule_remove_slotframe(sf) == 0) { + return 0; + } + } + return 1; +} +/*---------------------------------------------------------------------------*/ +/* Removes a slotframe Return 1 if success, 0 if failure */ +int +tsch_schedule_remove_slotframe(struct tsch_slotframe *slotframe) +{ + if(slotframe != NULL) { + /* Remove all links belonging to this slotframe */ + struct tsch_link *l; + while((l = list_head(slotframe->links_list))) { + tsch_schedule_remove_link(slotframe, l); + } + + /* Now that the slotframe has no links, remove it. */ + if(tsch_get_lock()) { + PRINTF("TSCH-schedule: remove slotframe %u %u\n", slotframe->handle, slotframe->size.val); + memb_free(&slotframe_memb, slotframe); + list_remove(slotframe_list, slotframe); + tsch_release_lock(); + return 1; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +/* Looks for a slotframe from a handle */ +struct tsch_slotframe * +tsch_schedule_get_slotframe_by_handle(uint16_t handle) +{ + if(!tsch_is_locked()) { + struct tsch_slotframe *sf = list_head(slotframe_list); + while(sf != NULL) { + if(sf->handle == handle) { + return sf; + } + sf = list_item_next(sf); + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +/* Looks for a link from a handle */ +struct tsch_link * +tsch_schedule_get_link_by_handle(uint16_t handle) +{ + if(!tsch_is_locked()) { + struct tsch_slotframe *sf = list_head(slotframe_list); + while(sf != NULL) { + struct tsch_link *l = list_head(sf->links_list); + /* Loop over all items. Assume there is max one link per timeslot */ + while(l != NULL) { + if(l->handle == handle) { + return l; + } + l = list_item_next(l); + } + sf = list_item_next(sf); + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +/* Adds a link to a slotframe, return a pointer to it (NULL if failure) */ +struct tsch_link * +tsch_schedule_add_link(struct tsch_slotframe *slotframe, + uint8_t link_options, enum link_type link_type, const linkaddr_t *address, + uint16_t timeslot, uint16_t channel_offset) +{ + struct tsch_link *l = NULL; + if(slotframe != NULL) { + /* We currently support only one link per timeslot in a given slotframe. */ + /* Start with removing the link currently installed at this timeslot (needed + * to keep neighbor state in sync with link options etc.) */ + tsch_schedule_remove_link_by_timeslot(slotframe, timeslot); + if(!tsch_get_lock()) { + PRINTF("TSCH-schedule:! add_link memb_alloc couldn't take lock\n"); + } else { + l = memb_alloc(&link_memb); + if(l == NULL) { + PRINTF("TSCH-schedule:! add_link memb_alloc failed\n"); + tsch_release_lock(); + } else { + static int current_link_handle = 0; + struct tsch_neighbor *n; + /* Add the link to the slotframe */ + list_add(slotframe->links_list, l); + /* Initialize link */ + l->handle = current_link_handle++; + l->link_options = link_options; + l->link_type = link_type; + l->slotframe_handle = slotframe->handle; + l->timeslot = timeslot; + l->channel_offset = channel_offset; + l->data = NULL; + if(address == NULL) { + address = &linkaddr_null; + } + linkaddr_copy(&l->addr, address); + + PRINTF("TSCH-schedule: add_link %u %u %u %u %u %u\n", + slotframe->handle, link_options, link_type, timeslot, channel_offset, TSCH_LOG_ID_FROM_LINKADDR(address)); + + /* Release the lock before we update the neighbor (will take the lock) */ + tsch_release_lock(); + + if(l->link_options & LINK_OPTION_TX) { + n = tsch_queue_add_nbr(&l->addr); + /* We have a tx link to this neighbor, update counters */ + if(n != NULL) { + n->tx_links_count++; + if(!(l->link_options & LINK_OPTION_SHARED)) { + n->dedicated_tx_links_count++; + } + } + } + } + } + } + return l; +} +/*---------------------------------------------------------------------------*/ +/* Removes a link from slotframe. Return 1 if success, 0 if failure */ +int +tsch_schedule_remove_link(struct tsch_slotframe *slotframe, struct tsch_link *l) +{ + if(slotframe != NULL && l != NULL && l->slotframe_handle == slotframe->handle) { + if(tsch_get_lock()) { + uint8_t link_options; + linkaddr_t addr; + + /* Save link option and addr in local variables as we need them + * after freeing the link */ + link_options = l->link_options; + linkaddr_copy(&addr, &l->addr); + + /* The link to be removed is scheduled as next, set it to NULL + * to abort the next link operation */ + if(l == current_link) { + current_link = NULL; + } + PRINTF("TSCH-schedule: remove_link %u %u %u %u %u\n", + slotframe->handle, l->link_options, l->timeslot, l->channel_offset, + TSCH_LOG_ID_FROM_LINKADDR(&l->addr)); + + list_remove(slotframe->links_list, l); + memb_free(&link_memb, l); + + /* Release the lock before we update the neighbor (will take the lock) */ + tsch_release_lock(); + + /* This was a tx link to this neighbor, update counters */ + if(link_options & LINK_OPTION_TX) { + struct tsch_neighbor *n = tsch_queue_add_nbr(&addr); + if(n != NULL) { + n->tx_links_count--; + if(!(link_options & LINK_OPTION_SHARED)) { + n->dedicated_tx_links_count--; + } + } + } + + return 1; + } else { + PRINTF("TSCH-schedule:! remove_link memb_alloc couldn't take lock\n"); + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +/* Removes a link from slotframe and timeslot. Return a 1 if success, 0 if failure */ +int +tsch_schedule_remove_link_by_timeslot(struct tsch_slotframe *slotframe, uint16_t timeslot) +{ + return slotframe != NULL && + tsch_schedule_remove_link(slotframe, tsch_schedule_get_link_by_timeslot(slotframe, timeslot)); +} +/*---------------------------------------------------------------------------*/ +/* Looks within a slotframe for a link with a given timeslot */ +struct tsch_link * +tsch_schedule_get_link_by_timeslot(struct tsch_slotframe *slotframe, uint16_t timeslot) +{ + if(!tsch_is_locked()) { + if(slotframe != NULL) { + struct tsch_link *l = list_head(slotframe->links_list); + /* Loop over all items. Assume there is max one link per timeslot */ + while(l != NULL) { + if(l->timeslot == timeslot) { + return l; + } + l = list_item_next(l); + } + return l; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +/* Returns the next active link after a given ASN, and a backup link (for the same ASN, with Rx flag) */ +struct tsch_link * +tsch_schedule_get_next_active_link(struct asn_t *asn, uint16_t *time_offset, + struct tsch_link **backup_link) +{ + uint16_t time_to_curr_best = 0; + struct tsch_link *curr_best = NULL; + struct tsch_link *curr_backup = NULL; /* Keep a back link in case the current link + turns out useless when the time comes. For instance, for a Tx-only link, if there is + no outgoing packet in queue. In that case, run the backup link instead. The backup link + must have Rx flag set. */ + if(!tsch_is_locked()) { + struct tsch_slotframe *sf = list_head(slotframe_list); + /* For each slotframe, look for the earliest occurring link */ + while(sf != NULL) { + /* Get timeslot from ASN, given the slotframe length */ + uint16_t timeslot = ASN_MOD(*asn, sf->size); + struct tsch_link *l = list_head(sf->links_list); + while(l != NULL) { + uint16_t time_to_timeslot = + l->timeslot > timeslot ? + l->timeslot - timeslot : + sf->size.val + l->timeslot - timeslot; + if(curr_best == NULL || time_to_timeslot < time_to_curr_best) { + time_to_curr_best = time_to_timeslot; + curr_best = l; + curr_backup = NULL; + } else if(time_to_timeslot == time_to_curr_best) { + struct tsch_link *new_best = NULL; + /* Two links are overlapping, we need to select one of them. + * By standard: prioritize Tx links first, second by lowest handle */ + if((curr_best->link_options & LINK_OPTION_TX) == (l->link_options & LINK_OPTION_TX)) { + /* Both or neither links have Tx, select the one with lowest handle */ + if(l->slotframe_handle < curr_best->slotframe_handle) { + new_best = l; + } + } else { + /* Select the link that has the Tx option */ + if(l->link_options & LINK_OPTION_TX) { + new_best = l; + } + } + + /* Maintain backup_link */ + if(curr_backup == NULL) { + /* Check if 'l' best can be used as backup */ + if(new_best != l && (l->link_options & LINK_OPTION_RX)) { /* Does 'l' have Rx flag? */ + curr_backup = l; + } + /* Check if curr_best can be used as backup */ + if(new_best != curr_best && (curr_best->link_options & LINK_OPTION_RX)) { /* Does curr_best have Rx flag? */ + curr_backup = curr_best; + } + } + + /* Maintain curr_best */ + if(new_best != NULL) { + curr_best = new_best; + } + } + + l = list_item_next(l); + } + sf = list_item_next(sf); + } + if(time_offset != NULL) { + *time_offset = time_to_curr_best; + } + } + if(backup_link != NULL) { + *backup_link = curr_backup; + } + return curr_best; +} +/*---------------------------------------------------------------------------*/ +/* Module initialization, call only once at startup. Returns 1 is success, 0 if failure. */ +int +tsch_schedule_init(void) +{ + if(tsch_get_lock()) { + memb_init(&link_memb); + memb_init(&slotframe_memb); + list_init(slotframe_list); + tsch_release_lock(); + return 1; + } else { + return 0; + } +} +/*---------------------------------------------------------------------------*/ +/* Create a 6TiSCH minimal schedule */ +void +tsch_schedule_create_minimal(void) +{ + struct tsch_slotframe *sf_min; + /* First, empty current schedule */ + tsch_schedule_remove_all_slotframes(); + /* Build 6TiSCH minimal schedule. + * We pick a slotframe length of TSCH_SCHEDULE_DEFAULT_LENGTH */ + sf_min = tsch_schedule_add_slotframe(0, TSCH_SCHEDULE_DEFAULT_LENGTH); + /* Add a single Tx|Rx|Shared slot using broadcast address (i.e. usable for unicast and broadcast). + * We set the link type to advertising, which is not compliant with 6TiSCH minimal schedule + * but is required according to 802.15.4e if also used for EB transmission. + * Timeslot: 0, channel offset: 0. */ + tsch_schedule_add_link(sf_min, + LINK_OPTION_RX | LINK_OPTION_TX | LINK_OPTION_SHARED | LINK_OPTION_TIME_KEEPING, + LINK_TYPE_ADVERTISING, &tsch_broadcast_address, + 0, 0); +} +/*---------------------------------------------------------------------------*/ +/* Prints out the current schedule (all slotframes and links) */ +void +tsch_schedule_print(void) +{ + if(!tsch_is_locked()) { + struct tsch_slotframe *sf = list_head(slotframe_list); + + printf("Schedule: slotframe list\n"); + + while(sf != NULL) { + struct tsch_link *l = list_head(sf->links_list); + + printf("[Slotframe] Handle %u, size %u\n", sf->handle, sf->size.val); + printf("List of links:\n"); + + while(l != NULL) { + printf("[Link] Options %02x, type %u, timeslot %u, channel offset %u, address %u\n", + l->link_options, l->link_type, l->timeslot, l->channel_offset, l->addr.u8[7]); + l = list_item_next(l); + } + + sf = list_item_next(sf); + } + + printf("Schedule: end of slotframe list\n"); + } +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/mac/tsch/tsch-schedule.h b/core/net/mac/tsch/tsch-schedule.h new file mode 100644 index 000000000..7b8af2801 --- /dev/null +++ b/core/net/mac/tsch/tsch-schedule.h @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#ifndef __TSCH_SCHEDULE_H__ +#define __TSCH_SCHEDULE_H__ + +/********** Includes **********/ + +#include "contiki.h" +#include "lib/list.h" +#include "net/mac/tsch/tsch-private.h" +#include "net/mac/tsch/tsch-queue.h" +#include "net/mac/tsch/tsch-slot-operation.h" +#include "net/linkaddr.h" + +/******** Configuration *******/ + +/* Initializes TSCH with a 6TiSCH minimal schedule */ +#ifdef TSCH_SCHEDULE_CONF_WITH_6TISCH_MINIMAL +#define TSCH_SCHEDULE_WITH_6TISCH_MINIMAL TSCH_SCHEDULE_CONF_WITH_6TISCH_MINIMAL +#else +#define TSCH_SCHEDULE_WITH_6TISCH_MINIMAL 1 +#endif + +/* 6TiSCH Minimal schedule slotframe length */ +#ifdef TSCH_SCHEDULE_CONF_DEFAULT_LENGTH +#define TSCH_SCHEDULE_DEFAULT_LENGTH TSCH_SCHEDULE_CONF_DEFAULT_LENGTH +#else +#define TSCH_SCHEDULE_DEFAULT_LENGTH 7 +#endif + +/* Max number of TSCH slotframes */ +#ifdef TSCH_SCHEDULE_CONF_MAX_SLOTFRAMES +#define TSCH_SCHEDULE_MAX_SLOTFRAMES TSCH_SCHEDULE_CONF_MAX_SLOTFRAMES +#else +#define TSCH_SCHEDULE_MAX_SLOTFRAMES 4 +#endif + +/* Max number of links */ +#ifdef TSCH_SCHEDULE_CONF_MAX_LINKS +#define TSCH_SCHEDULE_MAX_LINKS TSCH_SCHEDULE_CONF_MAX_LINKS +#else +#define TSCH_SCHEDULE_MAX_LINKS 32 +#endif + +/********** Constants *********/ + +/* Link options */ +#define LINK_OPTION_TX 1 +#define LINK_OPTION_RX 2 +#define LINK_OPTION_SHARED 4 +#define LINK_OPTION_TIME_KEEPING 8 + +/************ Types ***********/ + +/* 802.15.4e link types. + * LINK_TYPE_ADVERTISING_ONLY is an extra one: for EB-only links. */ +enum link_type { LINK_TYPE_NORMAL, LINK_TYPE_ADVERTISING, LINK_TYPE_ADVERTISING_ONLY }; + +struct tsch_link { + /* Links are stored as a list: "next" must be the first field */ + struct tsch_link *next; + /* Unique identifier */ + uint16_t handle; + /* MAC address of neighbor */ + linkaddr_t addr; + /* Slotframe identifier */ + uint16_t slotframe_handle; + /* Identifier of Slotframe to which this link belongs + * Unused. */ + /* uint8_t handle; */ + /* Timeslot for this link */ + uint16_t timeslot; + /* Channel offset for this link */ + uint16_t channel_offset; + /* A bit string that defines + * b0 = Transmit, b1 = Receive, b2 = Shared, b3 = Timekeeping, b4 = reserved */ + uint8_t link_options; + /* Type of link. NORMAL = 0. ADVERTISING = 1, and indicates + the link may be used to send an Enhanced beacon. */ + enum link_type link_type; + /* Any other data for upper layers */ + void *data; +}; + +struct tsch_slotframe { + /* Slotframes are stored as a list: "next" must be the first field */ + struct tsch_slotframe *next; + /* Unique identifier */ + uint16_t handle; + /* Number of timeslots in the slotframe. + * Stored as struct asn_divisor_t because we often need ASN%size */ + struct asn_divisor_t size; + /* List of links belonging to this slotframe */ + LIST_STRUCT(links_list); +}; + +/********** Functions *********/ + +/* Module initialization, call only once at startup. Returns 1 is success, 0 if failure. */ +int tsch_schedule_init(void); +/* Create a 6TiSCH minimal schedule */ +void tsch_schedule_create_minimal(void); +/* Prints out the current schedule (all slotframes and links) */ +void tsch_schedule_print(void); + +/* Adds and returns a slotframe (NULL if failure) */ +struct tsch_slotframe *tsch_schedule_add_slotframe(uint16_t handle, uint16_t size); +/* Looks for a slotframe from a handle */ +struct tsch_slotframe *tsch_schedule_get_slotframe_by_handle(uint16_t handle); +/* Removes a slotframe Return 1 if success, 0 if failure */ +int tsch_schedule_remove_slotframe(struct tsch_slotframe *slotframe); +/* Removes all slotframes, resulting in an empty schedule */ +int tsch_schedule_remove_all_slotframes(void); + +/* Returns next slotframe */ +struct tsch_slotframe *tsch_schedule_slotframes_next(struct tsch_slotframe *sf); +/* Adds a link to a slotframe, return a pointer to it (NULL if failure) */ +struct tsch_link *tsch_schedule_add_link(struct tsch_slotframe *slotframe, + uint8_t link_options, enum link_type link_type, const linkaddr_t *address, + uint16_t timeslot, uint16_t channel_offset); +/* Looks for a link from a handle */ +struct tsch_link *tsch_schedule_get_link_by_handle(uint16_t handle); +/* Looks within a slotframe for a link with a given timeslot */ +struct tsch_link *tsch_schedule_get_link_by_timeslot(struct tsch_slotframe *slotframe, uint16_t timeslot); +/* Removes a link. Return 1 if success, 0 if failure */ +int tsch_schedule_remove_link(struct tsch_slotframe *slotframe, struct tsch_link *l); +/* Removes a link from slotframe and timeslot. Return a 1 if success, 0 if failure */ +int tsch_schedule_remove_link_by_timeslot(struct tsch_slotframe *slotframe, uint16_t timeslot); + +/* Returns the next active link after a given ASN, and a backup link (for the same ASN, with Rx flag) */ +struct tsch_link * tsch_schedule_get_next_active_link(struct asn_t *asn, uint16_t *time_offset, + struct tsch_link **backup_link); + +#endif /* __TSCH_SCHEDULE_H__ */ diff --git a/core/net/mac/tsch/tsch-security.c b/core/net/mac/tsch/tsch-security.c new file mode 100644 index 000000000..6d862e19e --- /dev/null +++ b/core/net/mac/tsch/tsch-security.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * TSCH security + * \author + * Simon Duquennoy + */ + +#include "contiki.h" +#include "net/mac/tsch/tsch.h" +#include "net/mac/tsch/tsch-packet.h" +#include "net/mac/tsch/tsch-private.h" +#include "net/mac/tsch/tsch-schedule.h" +#include "net/mac/tsch/tsch-security.h" +#include "net/mac/tsch/tsch-log.h" +#include "net/mac/frame802154.h" +#include "net/mac/framer-802154.h" +#include "net/netstack.h" +#include "net/packetbuf.h" +#include "lib/ccm-star.h" +#include "lib/aes-128.h" +#include +#include + +#if TSCH_LOG_LEVEL >= 1 +#define DEBUG DEBUG_PRINT +#else /* TSCH_LOG_LEVEL */ +#define DEBUG DEBUG_NONE +#endif /* TSCH_LOG_LEVEL */ +#include "net/net-debug.h" + +/* The two keys K1 and K2 from 6TiSCH minimal configuration + * K1: well-known, used for EBs + * K2: secret, used for data and ACK + * */ +static aes_key keys[] = { + TSCH_SECURITY_K1, + TSCH_SECURITY_K2 +}; +#define N_KEYS (sizeof(keys) / sizeof(aes_key)) + +/*---------------------------------------------------------------------------*/ +static void +tsch_security_init_nonce(uint8_t *nonce, + const linkaddr_t *sender, struct asn_t *asn) +{ + memcpy(nonce, sender, 8); + nonce[8] = asn->ms1b; + nonce[9] = (asn->ls4b >> 24) & 0xff; + nonce[10] = (asn->ls4b >> 16) & 0xff; + nonce[11] = (asn->ls4b >> 8) & 0xff; + nonce[12] = (asn->ls4b) & 0xff; +} +/*---------------------------------------------------------------------------*/ +static int +tsch_security_check_level(const frame802154_t *frame) +{ + uint8_t required_security_level; + uint8_t required_key_index; + + /* Sanity check */ + if(frame == NULL) { + return 0; + } + + /* Non-secured frame, ok iff we are not in a secured PAN + * (i.e. scanning or associated to a non-secured PAN) */ + if(frame->fcf.security_enabled == 0) { + return !(tsch_is_associated == 1 && tsch_is_pan_secured == 1); + } + + /* The frame is secured, that we are not in an unsecured PAN */ + if(tsch_is_associated == 1 && tsch_is_pan_secured == 0) { + return 0; + } + + /* The frame is secured, check its security level */ + switch(frame->fcf.frame_type) { + case FRAME802154_BEACONFRAME: + required_security_level = TSCH_SECURITY_KEY_SEC_LEVEL_EB; + required_key_index = TSCH_SECURITY_KEY_INDEX_EB; + break; + case FRAME802154_ACKFRAME: + required_security_level = TSCH_SECURITY_KEY_SEC_LEVEL_ACK; + required_key_index = TSCH_SECURITY_KEY_INDEX_ACK; + break; + default: + required_security_level = TSCH_SECURITY_KEY_SEC_LEVEL_OTHER; + required_key_index = TSCH_SECURITY_KEY_INDEX_OTHER; + break; + } + return frame->aux_hdr.security_control.security_level == required_security_level + && frame->aux_hdr.key_index == required_key_index; +} +/*---------------------------------------------------------------------------*/ +int +tsch_security_mic_len(const frame802154_t *frame) +{ + if(frame != NULL && frame->fcf.security_enabled) { + return 2 << (frame->aux_hdr.security_control.security_level & 0x03); + } else { + return 0; + } +} +/*---------------------------------------------------------------------------*/ +int +tsch_security_secure_frame(uint8_t *hdr, uint8_t *outbuf, + int hdrlen, int datalen, struct asn_t *asn) +{ + frame802154_t frame; + uint8_t key_index = 0; + uint8_t security_level = 0; + uint8_t with_encryption; + uint8_t mic_len; + uint8_t nonce[16]; + + uint8_t a_len; + uint8_t m_len; + + if(hdr == NULL || outbuf == NULL || hdrlen < 0 || datalen < 0) { + return 0; + } + + /* Parse the frame header to extract security settings */ + if(frame802154_parse(hdr, hdrlen + datalen, &frame) < 3) { + return 0; + } + + if(!frame.fcf.security_enabled) { + /* Security is not enabled for this frame, we're done */ + return 1; + } + + /* Read security key index */ + key_index = frame.aux_hdr.key_index; + security_level = frame.aux_hdr.security_control.security_level; + with_encryption = (security_level & 0x4) ? 1 : 0; + mic_len = tsch_security_mic_len(&frame); + + if(key_index == 0 || key_index > N_KEYS) { + return 0; + } + + tsch_security_init_nonce(nonce, &linkaddr_node_addr, asn); + + if(with_encryption) { + a_len = hdrlen; + m_len = datalen; + } else { + a_len = hdrlen + datalen; + m_len = 0; + } + + /* Copy source data to output */ + if(hdr != outbuf) { + memcpy(outbuf, hdr, a_len + m_len); + } + + CCM_STAR.set_key(keys[key_index - 1]); + + CCM_STAR.aead(nonce, + outbuf + a_len, m_len, + outbuf, a_len, + outbuf + hdrlen + datalen, mic_len, 1 + ); + + return mic_len; +} +/*---------------------------------------------------------------------------*/ +int +tsch_security_parse_frame(const uint8_t *hdr, int hdrlen, int datalen, + const frame802154_t *frame, const linkaddr_t *sender, struct asn_t *asn) +{ + uint8_t generated_mic[16]; + uint8_t key_index = 0; + uint8_t security_level = 0; + uint8_t with_encryption; + uint8_t mic_len; + uint8_t nonce[16]; + uint8_t a_len; + uint8_t m_len; + + if(frame == NULL || hdr == NULL || hdrlen < 0 || datalen < 0) { + return 0; + } + + if(!tsch_security_check_level(frame)) { + /* Wrong security level */ + return 0; + } + + /* No security: nothing more to check */ + if(!frame->fcf.security_enabled) { + return 1; + } + + key_index = frame->aux_hdr.key_index; + security_level = frame->aux_hdr.security_control.security_level; + with_encryption = (security_level & 0x4) ? 1 : 0; + mic_len = tsch_security_mic_len(frame); + + /* Check if key_index is in supported range */ + if(key_index == 0 || key_index > N_KEYS) { + return 0; + } + + tsch_security_init_nonce(nonce, sender, asn); + + if(with_encryption) { + a_len = hdrlen; + m_len = datalen; + } else { + a_len = hdrlen + datalen; + m_len = 0; + } + + CCM_STAR.set_key(keys[key_index - 1]); + + CCM_STAR.aead(nonce, + (uint8_t *)hdr + a_len, m_len, + (uint8_t *)hdr, a_len, + generated_mic, mic_len, 0 + ); + + if(mic_len > 0 && memcmp(generated_mic, hdr + hdrlen + datalen, mic_len) != 0) { + return 0; + } else { + return 1; + } +} diff --git a/core/net/mac/tsch/tsch-security.h b/core/net/mac/tsch/tsch-security.h new file mode 100644 index 000000000..42f18e8d9 --- /dev/null +++ b/core/net/mac/tsch/tsch-security.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#ifndef __TSCH_SECURITY_H__ +#define __TSCH_SECURITY_H__ + +/********** Includes **********/ + +#include "contiki.h" +#include "net/mac/tsch/tsch-asn.h" +#include "net/mac/tsch/tsch-private.h" +#include "net/mac/frame802154.h" +#include "net/llsec/llsec802154.h" +#include "net/mac/frame802154e-ie.h" + +/******** Configuration *******/ + +/* To enable TSCH security: + * - set LLSEC802154_CONF_ENABLED + * - set LLSEC802154_CONF_USES_EXPLICIT_KEYS + * - unset LLSEC802154_CONF_USES_FRAME_COUNTER + * */ + +#if LLSEC802154_ENABLED && !LLSEC802154_USES_EXPLICIT_KEYS +#error LLSEC802154_ENABLED set but LLSEC802154_USES_EXPLICIT_KEYS unset +#endif /* LLSEC802154_ENABLED */ +#if LLSEC802154_ENABLED && LLSEC802154_USES_FRAME_COUNTER +#error LLSEC802154_ENABLED set but LLSEC802154_USES_FRAME_COUNTER set +#endif /* LLSEC802154_ENABLED */ + +/* K1, defined in 6TiSCH minimal, is well-known (offers no security) and used for EBs only */ +#ifdef TSCH_SECURITY_CONF_K1 +#define TSCH_SECURITY_K1 TSCH_SECURITY_CONF_K1 +#else /* TSCH_SECURITY_CONF_K1 */ +#define TSCH_SECURITY_K1 { 0x36, 0x54, 0x69, 0x53, 0x43, 0x48, 0x20, 0x6D, 0x69, 0x6E, 0x69, 0x6D, 0x61, 0x6C, 0x31, 0x35 } +#endif /* TSCH_SECURITY_CONF_K1 */ + +/* K2, defined in 6TiSCH minimal, is used for all but EB traffic */ +#ifdef TSCH_SECURITY_CONF_K2 +#define TSCH_SECURITY_K2 TSCH_SECURITY_CONF_K2 +#else /* TSCH_SECURITY_CONF_K2 */ +#define TSCH_SECURITY_K2 { 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, 0xca, 0xfe, 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, 0xca, 0xfe } +#endif /* TSCH_SECURITY_CONF_K2 */ + +/* Key used for EBs */ +#ifdef TSCH_SECURITY_CONF_KEY_INDEX_EB +#define TSCH_SECURITY_KEY_INDEX_EB TSCH_SECURITY_CONF_KEY_INDEX_EB +#else +#define TSCH_SECURITY_KEY_INDEX_EB 1 /* Use K1 as per 6TiSCH minimal */ +#endif + +/* Security level for EBs */ +#ifdef TSCH_SECURITY_CONF_SEC_LEVEL_EB +#define TSCH_SECURITY_KEY_SEC_LEVEL_EB TSCH_SECURITY_CONF_SEC_LEVEL_EB +#else +#define TSCH_SECURITY_KEY_SEC_LEVEL_EB 1 /* MIC-32, as per 6TiSCH minimal */ +#endif + +/* Key used for ACK */ +#ifdef TSCH_SECURITY_CONF_KEY_INDEX_ACK +#define TSCH_SECURITY_KEY_INDEX_ACK TSCH_SECURITY_CONF_KEY_INDEX_ACK +#else +#define TSCH_SECURITY_KEY_INDEX_ACK 2 /* Use K2 as per 6TiSCH minimal */ +#endif + +/* Security level for ACKs */ +#ifdef TSCH_SECURITY_CONF_SEC_LEVEL_ACK +#define TSCH_SECURITY_KEY_SEC_LEVEL_ACK TSCH_SECURITY_CONF_SEC_LEVEL_ACK +#else +#define TSCH_SECURITY_KEY_SEC_LEVEL_ACK 5 /* Encryption + MIC-32, as per 6TiSCH minimal */ +#endif + +/* Key used for Other (Data, Cmd) */ +#ifdef TSCH_SECURITY_CONF_KEY_INDEX_OTHER +#define TSCH_SECURITY_KEY_INDEX_OTHER TSCH_SECURITY_CONF_KEY_INDEX_OTHER +#else +#define TSCH_SECURITY_KEY_INDEX_OTHER 2 /* Use K2 as per 6TiSCH minimal */ +#endif + +/* Security level for Other (Data, Cmd) */ +#ifdef TSCH_SECURITY_CONF_SEC_LEVEL_OTHER +#define TSCH_SECURITY_KEY_SEC_LEVEL_OTHER TSCH_SECURITY_CONF_SEC_LEVEL_OTHER +#else +#define TSCH_SECURITY_KEY_SEC_LEVEL_OTHER 5 /* Encryption + MIC-32, as per 6TiSCH minimal */ +#endif + +/************ Types ***********/ + +typedef uint8_t aes_key[16]; + +/********** Functions *********/ + +int tsch_security_mic_len(const frame802154_t *frame); +int tsch_security_secure_frame(uint8_t *hdr, uint8_t *outbuf, + int hdrlen, int datalen, struct asn_t *asn); +int tsch_security_parse_frame(const uint8_t *hdr, int hdrlen, int datalen, + const frame802154_t *frame, const linkaddr_t *sender, struct asn_t *asn); + +#endif /* __TSCH_SECURITY_H__ */ diff --git a/core/net/mac/tsch/tsch-slot-operation.c b/core/net/mac/tsch/tsch-slot-operation.c new file mode 100644 index 000000000..be83da4ab --- /dev/null +++ b/core/net/mac/tsch/tsch-slot-operation.c @@ -0,0 +1,1075 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * TSCH slot operation implementation, running from interrupt. + * \author + * Simon Duquennoy + * Beshr Al Nahas + * Atis Elsts + * + */ + +#include "contiki.h" +#include "dev/radio.h" +#include "net/netstack.h" +#include "net/packetbuf.h" +#include "net/queuebuf.h" +#include "net/mac/framer-802154.h" +#include "net/mac/tsch/tsch.h" +#include "net/mac/tsch/tsch-slot-operation.h" +#include "net/mac/tsch/tsch-queue.h" +#include "net/mac/tsch/tsch-private.h" +#include "net/mac/tsch/tsch-log.h" +#include "net/mac/tsch/tsch-packet.h" +#include "net/mac/tsch/tsch-security.h" +#include "net/mac/tsch/tsch-adaptive-timesync.h" + +#if TSCH_LOG_LEVEL >= 1 +#define DEBUG DEBUG_PRINT +#else /* TSCH_LOG_LEVEL */ +#define DEBUG DEBUG_NONE +#endif /* TSCH_LOG_LEVEL */ +#include "net/net-debug.h" + +/* TSCH debug macros, i.e. to set LEDs or GPIOs on various TSCH + * timeslot events */ +#ifndef TSCH_DEBUG_INIT +#define TSCH_DEBUG_INIT() +#endif +#ifndef TSCH_DEBUG_INTERRUPT +#define TSCH_DEBUG_INTERRUPT() +#endif +#ifndef TSCH_DEBUG_RX_EVENT +#define TSCH_DEBUG_RX_EVENT() +#endif +#ifndef TSCH_DEBUG_TX_EVENT +#define TSCH_DEBUG_TX_EVENT() +#endif +#ifndef TSCH_DEBUG_SLOT_START +#define TSCH_DEBUG_SLOT_START() +#endif +#ifndef TSCH_DEBUG_SLOT_END +#define TSCH_DEBUG_SLOT_END() +#endif + +/* Check if TSCH_MAX_INCOMING_PACKETS is power of two */ +#if (TSCH_MAX_INCOMING_PACKETS & (TSCH_MAX_INCOMING_PACKETS - 1)) != 0 +#error TSCH_MAX_INCOMING_PACKETS must be power of two +#endif + +/* Check if TSCH_DEQUEUED_ARRAY_SIZE is power of two and greater or equal to QUEUEBUF_NUM */ +#if TSCH_DEQUEUED_ARRAY_SIZE < QUEUEBUF_NUM +#error TSCH_DEQUEUED_ARRAY_SIZE must be greater or equal to QUEUEBUF_NUM +#endif +#if (TSCH_DEQUEUED_ARRAY_SIZE & (TSCH_DEQUEUED_ARRAY_SIZE - 1)) != 0 +#error TSCH_DEQUEUED_ARRAY_SIZE must be power of two +#endif + +/* Truncate received drift correction information to maximum half + * of the guard time (one fourth of TSCH_DEFAULT_TS_RX_WAIT) */ +#define SYNC_IE_BOUND ((int32_t)US_TO_RTIMERTICKS(TSCH_DEFAULT_TS_RX_WAIT / 4)) + +/* By default: check that rtimer runs at >=32kHz and use a guard time of 10us */ +#if RTIMER_SECOND < (32 * 1024) +#error "TSCH: RTIMER_SECOND < (32 * 1024)" +#endif +#if RTIMER_SECOND >= 200000 +#define RTIMER_GUARD (RTIMER_SECOND / 100000) +#else +#define RTIMER_GUARD 2u +#endif + +enum tsch_radio_state_on_cmd { + TSCH_RADIO_CMD_ON_START_OF_TIMESLOT, + TSCH_RADIO_CMD_ON_WITHIN_TIMESLOT, + TSCH_RADIO_CMD_ON_FORCE, +}; + +enum tsch_radio_state_off_cmd { + TSCH_RADIO_CMD_OFF_END_OF_TIMESLOT, + TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT, + TSCH_RADIO_CMD_OFF_FORCE, +}; + +/* A ringbuf storing outgoing packets after they were dequeued. + * Will be processed layer by tsch_tx_process_pending */ +struct ringbufindex dequeued_ringbuf; +struct tsch_packet *dequeued_array[TSCH_DEQUEUED_ARRAY_SIZE]; +/* A ringbuf storing incoming packets. + * Will be processed layer by tsch_rx_process_pending */ +struct ringbufindex input_ringbuf; +struct input_packet input_array[TSCH_MAX_INCOMING_PACKETS]; + +/* Last time we received Sync-IE (ACK or data packet from a time source) */ +static struct asn_t last_sync_asn; + +/* A global lock for manipulating data structures safely from outside of interrupt */ +static volatile int tsch_locked = 0; +/* As long as this is set, skip all slot operation */ +static volatile int tsch_lock_requested = 0; + +/* Last estimated drift in RTIMER ticks + * (Sky: 1 tick = 30.517578125 usec exactly) */ +static int32_t drift_correction = 0; +/* Is drift correction used? (Can be true even if drift_correction == 0) */ +static uint8_t is_drift_correction_used; + +/* The neighbor last used as our time source */ +struct tsch_neighbor *last_timesource_neighbor = NULL; + +/* Used from tsch_slot_operation and sub-protothreads */ +static rtimer_clock_t volatile current_slot_start; + +/* Are we currently inside a slot? */ +static volatile int tsch_in_slot_operation = 0; + +/* Info about the link, packet and neighbor of + * the current (or next) slot */ +struct tsch_link *current_link = NULL; +/* A backup link with Rx flag, overlapping with current_link. + * If the current link is Tx-only and the Tx queue + * is empty while executing the link, fallback to the backup link. */ +static struct tsch_link *backup_link = NULL; +static struct tsch_packet *current_packet = NULL; +static struct tsch_neighbor *current_neighbor = NULL; + +/* Protothread for association */ +PT_THREAD(tsch_scan(struct pt *pt)); +/* Protothread for slot operation, called from rtimer interrupt + * and scheduled from tsch_schedule_slot_operation */ +static PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr)); +static struct pt slot_operation_pt; +/* Sub-protothreads of tsch_slot_operation */ +static PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)); +static PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)); + +/*---------------------------------------------------------------------------*/ +/* TSCH locking system. TSCH is locked during slot operations */ + +/* Is TSCH locked? */ +int +tsch_is_locked(void) +{ + return tsch_locked; +} + +/* Lock TSCH (no slot operation) */ +int +tsch_get_lock(void) +{ + if(!tsch_locked) { + rtimer_clock_t busy_wait_time; + int busy_wait = 0; /* Flag used for logging purposes */ + /* Make sure no new slot operation will start */ + tsch_lock_requested = 1; + /* Wait for the end of current slot operation. */ + if(tsch_in_slot_operation) { + busy_wait = 1; + busy_wait_time = RTIMER_NOW(); + while(tsch_in_slot_operation); + busy_wait_time = RTIMER_NOW() - busy_wait_time; + } + if(!tsch_locked) { + /* Take the lock if it is free */ + tsch_locked = 1; + tsch_lock_requested = 0; + if(busy_wait) { + /* Issue a log whenever we had to busy wait until getting the lock */ + TSCH_LOG_ADD(tsch_log_message, + snprintf(log->message, sizeof(log->message), + "!get lock delay %u", (unsigned)busy_wait_time); + ); + } + return 1; + } + } + TSCH_LOG_ADD(tsch_log_message, + snprintf(log->message, sizeof(log->message), + "!failed to lock"); + ); + return 0; +} + +/* Release TSCH lock */ +void +tsch_release_lock(void) +{ + tsch_locked = 0; +} + +/*---------------------------------------------------------------------------*/ +/* Channel hopping utility functions */ + +/* Return channel from ASN and channel offset */ +uint8_t +tsch_calculate_channel(struct asn_t *asn, uint8_t channel_offset) +{ + uint16_t index_of_0 = ASN_MOD(*asn, tsch_hopping_sequence_length); + uint16_t index_of_offset = (index_of_0 + channel_offset) % tsch_hopping_sequence_length.val; + return tsch_hopping_sequence[index_of_offset]; +} + +/*---------------------------------------------------------------------------*/ +/* Timing utility functions */ + +/* Checks if the current time has passed a ref time + offset. Assumes + * a single overflow and ref time prior to now. */ +static uint8_t +check_timer_miss(rtimer_clock_t ref_time, rtimer_clock_t offset, rtimer_clock_t now) +{ + rtimer_clock_t target = ref_time + offset; + int now_has_overflowed = now < ref_time; + int target_has_overflowed = target < ref_time; + + if(now_has_overflowed == target_has_overflowed) { + /* Both or none have overflowed, just compare now to the target */ + return target <= now; + } else { + /* Either now or target of overflowed. + * If it is now, then it has passed the target. + * If it is target, then we haven't reached it yet. + * */ + return now_has_overflowed; + } +} +/*---------------------------------------------------------------------------*/ +/* Schedule a wakeup at a specified offset from a reference time. + * Provides basic protection against missed deadlines and timer overflows + * A return value of zero signals a missed deadline: no rtimer was scheduled. */ +static uint8_t +tsch_schedule_slot_operation(struct rtimer *tm, rtimer_clock_t ref_time, rtimer_clock_t offset, const char *str) +{ + rtimer_clock_t now = RTIMER_NOW(); + int r; + /* Subtract RTIMER_GUARD before checking for deadline miss + * because we can not schedule rtimer less than RTIMER_GUARD in the future */ + int missed = check_timer_miss(ref_time, offset - RTIMER_GUARD, now); + + if(missed) { + TSCH_LOG_ADD(tsch_log_message, + snprintf(log->message, sizeof(log->message), + "!dl-miss %s %d %d", + str, (int)(now-ref_time), (int)offset); + ); + + return 0; + } + ref_time += offset; + r = rtimer_set(tm, ref_time, 1, (void (*)(struct rtimer *, void *))tsch_slot_operation, NULL); + if(r != RTIMER_OK) { + return 0; + } + return 1; +} +/*---------------------------------------------------------------------------*/ +/* Schedule slot operation conditionally, and YIELD if success only. + * Always attempt to schedule RTIMER_GUARD before the target to make sure to wake up + * ahead of time and then busy wait to exactly hit the target. */ +#define TSCH_SCHEDULE_AND_YIELD(pt, tm, ref_time, offset, str) \ + do { \ + if(tsch_schedule_slot_operation(tm, ref_time, offset - RTIMER_GUARD, str)) { \ + PT_YIELD(pt); \ + } \ + BUSYWAIT_UNTIL_ABS(0, ref_time, offset); \ + } while(0); +/*---------------------------------------------------------------------------*/ +/* Get EB, broadcast or unicast packet to be sent, and target neighbor. */ +static struct tsch_packet * +get_packet_and_neighbor_for_link(struct tsch_link *link, struct tsch_neighbor **target_neighbor) +{ + struct tsch_packet *p = NULL; + struct tsch_neighbor *n = NULL; + + /* Is this a Tx link? */ + if(link->link_options & LINK_OPTION_TX) { + /* is it for advertisement of EB? */ + if(link->link_type == LINK_TYPE_ADVERTISING || link->link_type == LINK_TYPE_ADVERTISING_ONLY) { + /* fetch EB packets */ + n = n_eb; + p = tsch_queue_get_packet_for_nbr(n, link); + } + if(link->link_type != LINK_TYPE_ADVERTISING_ONLY) { + /* NORMAL link or no EB to send, pick a data packet */ + if(p == NULL) { + /* Get neighbor queue associated to the link and get packet from it */ + n = tsch_queue_get_nbr(&link->addr); + p = tsch_queue_get_packet_for_nbr(n, link); + /* if it is a broadcast slot and there were no broadcast packets, pick any unicast packet */ + if(p == NULL && n == n_broadcast) { + p = tsch_queue_get_unicast_packet_for_any(&n, link); + } + } + } + } + /* return nbr (by reference) */ + if(target_neighbor != NULL) { + *target_neighbor = n; + } + + return p; +} +/*---------------------------------------------------------------------------*/ +/* Post TX: Update neighbor state after a transmission */ +static int +update_neighbor_state(struct tsch_neighbor *n, struct tsch_packet *p, + struct tsch_link *link, uint8_t mac_tx_status) +{ + int in_queue = 1; + int is_shared_link = link->link_options & LINK_OPTION_SHARED; + int is_unicast = !n->is_broadcast; + + if(mac_tx_status == MAC_TX_OK) { + /* Successful transmission */ + tsch_queue_remove_packet_from_queue(n); + in_queue = 0; + + /* Update CSMA state in the unicast case */ + if(is_unicast) { + if(is_shared_link || tsch_queue_is_empty(n)) { + /* If this is a shared link, reset backoff on success. + * Otherwise, do so only is the queue is empty */ + tsch_queue_backoff_reset(n); + } + } + } else { + /* Failed transmission */ + if(p->transmissions >= TSCH_MAC_MAX_FRAME_RETRIES + 1) { + /* Drop packet */ + tsch_queue_remove_packet_from_queue(n); + in_queue = 0; + } + /* Update CSMA state in the unicast case */ + if(is_unicast) { + /* Failures on dedicated (== non-shared) leave the backoff + * window nor exponent unchanged */ + if(is_shared_link) { + /* Shared link: increment backoff exponent, pick a new window */ + tsch_queue_backoff_inc(n); + } + } + } + + return in_queue; +} +/*---------------------------------------------------------------------------*/ +/** + * This function turns on the radio. Its semantics is dependent on + * the value of TSCH_RADIO_ON_DURING_TIMESLOT constant: + * - if enabled, the radio is turned on at the start of the slot + * - if disabled, the radio is turned on within the slot, + * directly before the packet Rx guard time and ACK Rx guard time. + */ +static void +tsch_radio_on(enum tsch_radio_state_on_cmd command) +{ + int do_it = 0; + switch(command) { + case TSCH_RADIO_CMD_ON_START_OF_TIMESLOT: + if(TSCH_RADIO_ON_DURING_TIMESLOT) { + do_it = 1; + } + break; + case TSCH_RADIO_CMD_ON_WITHIN_TIMESLOT: + if(!TSCH_RADIO_ON_DURING_TIMESLOT) { + do_it = 1; + } + break; + case TSCH_RADIO_CMD_ON_FORCE: + do_it = 1; + break; + } + if(do_it) { + NETSTACK_RADIO.on(); + } +} +/*---------------------------------------------------------------------------*/ +/** + * This function turns off the radio. In the same way as for tsch_radio_on(), + * it depends on the value of TSCH_RADIO_ON_DURING_TIMESLOT constant: + * - if enabled, the radio is turned off at the end of the slot + * - if disabled, the radio is turned off within the slot, + * directly after Tx'ing or Rx'ing a packet or Tx'ing an ACK. + */ +static void +tsch_radio_off(enum tsch_radio_state_off_cmd command) +{ + int do_it = 0; + switch(command) { + case TSCH_RADIO_CMD_OFF_END_OF_TIMESLOT: + if(TSCH_RADIO_ON_DURING_TIMESLOT) { + do_it = 1; + } + break; + case TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT: + if(!TSCH_RADIO_ON_DURING_TIMESLOT) { + do_it = 1; + } + break; + case TSCH_RADIO_CMD_OFF_FORCE: + do_it = 1; + break; + } + if(do_it) { + NETSTACK_RADIO.off(); + } +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) +{ + /** + * TX slot: + * 1. Copy packet to radio buffer + * 2. Perform CCA if enabled + * 3. Sleep until it is time to transmit + * 4. Wait for ACK if it is a unicast packet + * 5. Extract drift if we received an E-ACK from a time source neighbor + * 6. Update CSMA parameters according to TX status + * 7. Schedule mac_call_sent_callback + **/ + + /* tx status */ + static uint8_t mac_tx_status; + /* is the packet in its neighbor's queue? */ + uint8_t in_queue; + static int dequeued_index; + static int packet_ready = 1; + + PT_BEGIN(pt); + + TSCH_DEBUG_TX_EVENT(); + + /* First check if we have space to store a newly dequeued packet (in case of + * successful Tx or Drop) */ + dequeued_index = ringbufindex_peek_put(&dequeued_ringbuf); + if(dequeued_index != -1) { + if(current_packet == NULL || current_packet->qb == NULL) { + mac_tx_status = MAC_TX_ERR_FATAL; + } else { + /* packet payload */ + static void *packet; +#if LLSEC802154_ENABLED + /* encrypted payload */ + static uint8_t encrypted_packet[TSCH_PACKET_MAX_LEN]; +#endif /* LLSEC802154_ENABLED */ + /* packet payload length */ + static uint8_t packet_len; + /* packet seqno */ + static uint8_t seqno; + /* is this a broadcast packet? (wait for ack?) */ + static uint8_t is_broadcast; + static rtimer_clock_t tx_start_time; + +#if CCA_ENABLED + static uint8_t cca_status; +#endif + + /* get payload */ + packet = queuebuf_dataptr(current_packet->qb); + packet_len = queuebuf_datalen(current_packet->qb); + /* is this a broadcast packet? (wait for ack?) */ + is_broadcast = current_neighbor->is_broadcast; + /* read seqno from payload */ + seqno = ((uint8_t *)(packet))[2]; + /* if this is an EB, then update its Sync-IE */ + if(current_neighbor == n_eb) { + packet_ready = tsch_packet_update_eb(packet, packet_len, current_packet->tsch_sync_ie_offset); + } else { + packet_ready = 1; + } + +#if LLSEC802154_ENABLED + if(tsch_is_pan_secured) { + /* If we are going to encrypt, we need to generate the output in a separate buffer and keep + * the original untouched. This is to allow for future retransmissions. */ + int with_encryption = queuebuf_attr(current_packet->qb, PACKETBUF_ATTR_SECURITY_LEVEL) & 0x4; + packet_len += tsch_security_secure_frame(packet, with_encryption ? encrypted_packet : packet, current_packet->header_len, + packet_len - current_packet->header_len, ¤t_asn); + if(with_encryption) { + packet = encrypted_packet; + } + } +#endif /* LLSEC802154_ENABLED */ + + /* prepare packet to send: copy to radio buffer */ + if(packet_ready && NETSTACK_RADIO.prepare(packet, packet_len) == 0) { /* 0 means success */ + static rtimer_clock_t tx_duration; + +#if CCA_ENABLED + cca_status = 1; + /* delay before CCA */ + TSCH_SCHEDULE_AND_YIELD(pt, t, current_slot_start, TS_CCA_OFFSET, "cca"); + TSCH_DEBUG_TX_EVENT(); + tsch_radio_on(TSCH_RADIO_CMD_ON_WITHIN_TIMESLOT); + /* CCA */ + BUSYWAIT_UNTIL_ABS(!(cca_status |= NETSTACK_RADIO.channel_clear()), + current_slot_start, TS_CCA_OFFSET + TS_CCA); + TSCH_DEBUG_TX_EVENT(); + /* there is not enough time to turn radio off */ + /* NETSTACK_RADIO.off(); */ + if(cca_status == 0) { + mac_tx_status = MAC_TX_COLLISION; + } else +#endif /* CCA_ENABLED */ + { + /* delay before TX */ + TSCH_SCHEDULE_AND_YIELD(pt, t, current_slot_start, tsch_timing[tsch_ts_tx_offset] - RADIO_DELAY_BEFORE_TX, "TxBeforeTx"); + TSCH_DEBUG_TX_EVENT(); + /* send packet already in radio tx buffer */ + mac_tx_status = NETSTACK_RADIO.transmit(packet_len); + /* Save tx timestamp */ + tx_start_time = current_slot_start + tsch_timing[tsch_ts_tx_offset]; + /* calculate TX duration based on sent packet len */ + tx_duration = TSCH_PACKET_DURATION(packet_len); + /* limit tx_time to its max value */ + tx_duration = MIN(tx_duration, tsch_timing[tsch_ts_max_tx]); + /* turn tadio off -- will turn on again to wait for ACK if needed */ + tsch_radio_off(TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT); + + if(mac_tx_status == RADIO_TX_OK) { + if(!is_broadcast) { + uint8_t ackbuf[TSCH_PACKET_MAX_LEN]; + int ack_len; + rtimer_clock_t ack_start_time; + int is_time_source; + struct ieee802154_ies ack_ies; + uint8_t ack_hdrlen; + frame802154_t frame; + +#if TSCH_HW_FRAME_FILTERING + radio_value_t radio_rx_mode; + /* Entering promiscuous mode so that the radio accepts the enhanced ACK */ + NETSTACK_RADIO.get_value(RADIO_PARAM_RX_MODE, &radio_rx_mode); + NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE, radio_rx_mode & (~RADIO_RX_MODE_ADDRESS_FILTER)); +#endif /* TSCH_HW_FRAME_FILTERING */ + /* Unicast: wait for ack after tx: sleep until ack time */ + TSCH_SCHEDULE_AND_YIELD(pt, t, current_slot_start, + tsch_timing[tsch_ts_tx_offset] + tx_duration + tsch_timing[tsch_ts_rx_ack_delay] - RADIO_DELAY_BEFORE_RX, "TxBeforeAck"); + TSCH_DEBUG_TX_EVENT(); + tsch_radio_on(TSCH_RADIO_CMD_ON_WITHIN_TIMESLOT); + /* Wait for ACK to come */ + BUSYWAIT_UNTIL_ABS(NETSTACK_RADIO.receiving_packet(), + tx_start_time, tx_duration + tsch_timing[tsch_ts_rx_ack_delay] + tsch_timing[tsch_ts_ack_wait]); + TSCH_DEBUG_TX_EVENT(); + + ack_start_time = RTIMER_NOW() - RADIO_DELAY_BEFORE_DETECT; + + /* Wait for ACK to finish */ + BUSYWAIT_UNTIL_ABS(!NETSTACK_RADIO.receiving_packet(), + ack_start_time, tsch_timing[tsch_ts_max_ack]); + TSCH_DEBUG_TX_EVENT(); + tsch_radio_off(TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT); + +#if TSCH_HW_FRAME_FILTERING + /* Leaving promiscuous mode */ + NETSTACK_RADIO.get_value(RADIO_PARAM_RX_MODE, &radio_rx_mode); + NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE, radio_rx_mode | RADIO_RX_MODE_ADDRESS_FILTER); +#endif /* TSCH_HW_FRAME_FILTERING */ + + /* Read ack frame */ + ack_len = NETSTACK_RADIO.read((void *)ackbuf, sizeof(ackbuf)); + + is_time_source = 0; + /* The radio driver should return 0 if no valid packets are in the rx buffer */ + if(ack_len > 0) { + is_time_source = current_neighbor != NULL && current_neighbor->is_time_source; + if(tsch_packet_parse_eack(ackbuf, ack_len, seqno, + &frame, &ack_ies, &ack_hdrlen) == 0) { + ack_len = 0; + } + +#if LLSEC802154_ENABLED + if(ack_len != 0) { + if(!tsch_security_parse_frame(ackbuf, ack_hdrlen, ack_len - ack_hdrlen - tsch_security_mic_len(&frame), + &frame, ¤t_neighbor->addr, ¤t_asn)) { + TSCH_LOG_ADD(tsch_log_message, + snprintf(log->message, sizeof(log->message), + "!failed to authenticate ACK")); + ack_len = 0; + } + } else { + TSCH_LOG_ADD(tsch_log_message, + snprintf(log->message, sizeof(log->message), + "!failed to parse ACK")); + } +#endif /* LLSEC802154_ENABLED */ + } + + if(ack_len != 0) { + if(is_time_source) { + int32_t eack_time_correction = US_TO_RTIMERTICKS(ack_ies.ie_time_correction); + int32_t since_last_timesync = ASN_DIFF(current_asn, last_sync_asn); + if(eack_time_correction > SYNC_IE_BOUND) { + drift_correction = SYNC_IE_BOUND; + } else if(eack_time_correction < -SYNC_IE_BOUND) { + drift_correction = -SYNC_IE_BOUND; + } else { + drift_correction = eack_time_correction; + } + if(drift_correction != eack_time_correction) { + TSCH_LOG_ADD(tsch_log_message, + snprintf(log->message, sizeof(log->message), + "!truncated dr %d %d", (int)eack_time_correction, (int)drift_correction); + ); + } + is_drift_correction_used = 1; + tsch_timesync_update(current_neighbor, since_last_timesync, drift_correction); + /* Keep track of sync time */ + last_sync_asn = current_asn; + tsch_schedule_keepalive(); + } + mac_tx_status = MAC_TX_OK; + } else { + mac_tx_status = MAC_TX_NOACK; + } + } else { + mac_tx_status = MAC_TX_OK; + } + } else { + mac_tx_status = MAC_TX_ERR; + } + } + } + } + + tsch_radio_off(TSCH_RADIO_CMD_OFF_END_OF_TIMESLOT); + + current_packet->transmissions++; + current_packet->ret = mac_tx_status; + + /* Post TX: Update neighbor state */ + in_queue = update_neighbor_state(current_neighbor, current_packet, current_link, mac_tx_status); + + /* The packet was dequeued, add it to dequeued_ringbuf for later processing */ + if(in_queue == 0) { + dequeued_array[dequeued_index] = current_packet; + ringbufindex_put(&dequeued_ringbuf); + } + + /* Log every tx attempt */ + TSCH_LOG_ADD(tsch_log_tx, + log->tx.mac_tx_status = mac_tx_status; + log->tx.num_tx = current_packet->transmissions; + log->tx.datalen = queuebuf_datalen(current_packet->qb); + log->tx.drift = drift_correction; + log->tx.drift_used = is_drift_correction_used; + log->tx.is_data = ((((uint8_t *)(queuebuf_dataptr(current_packet->qb)))[0]) & 7) == FRAME802154_DATAFRAME; +#if LLSEC802154_ENABLED + log->tx.sec_level = queuebuf_attr(current_packet->qb, PACKETBUF_ATTR_SECURITY_LEVEL); +#else /* LLSEC802154_ENABLED */ + log->tx.sec_level = 0; +#endif /* LLSEC802154_ENABLED */ + log->tx.dest = TSCH_LOG_ID_FROM_LINKADDR(queuebuf_addr(current_packet->qb, PACKETBUF_ADDR_RECEIVER)); + ); + + /* Poll process for later processing of packet sent events and logs */ + process_poll(&tsch_pending_events_process); + } + + TSCH_DEBUG_TX_EVENT(); + + PT_END(pt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) +{ + /** + * RX slot: + * 1. Check if it is used for TIME_KEEPING + * 2. Sleep and wake up just before expected RX time (with a guard time: TS_LONG_GT) + * 3. Check for radio activity for the guard time: TS_LONG_GT + * 4. Prepare and send ACK if needed + * 5. Drift calculated in the ACK callback registered with the radio driver. Use it if receiving from a time source neighbor. + **/ + + struct tsch_neighbor *n; + static linkaddr_t source_address; + static linkaddr_t destination_address; + static int16_t input_index; + static int input_queue_drop = 0; + + PT_BEGIN(pt); + + TSCH_DEBUG_RX_EVENT(); + + input_index = ringbufindex_peek_put(&input_ringbuf); + if(input_index == -1) { + input_queue_drop++; + } else { + static struct input_packet *current_input; + /* Estimated drift based on RX time */ + static int32_t estimated_drift; + /* Rx timestamps */ + static rtimer_clock_t rx_start_time; + static rtimer_clock_t expected_rx_time; + static rtimer_clock_t packet_duration; + uint8_t packet_seen; + + expected_rx_time = current_slot_start + tsch_timing[tsch_ts_tx_offset]; + /* Default start time: expected Rx time */ + rx_start_time = expected_rx_time; + + current_input = &input_array[input_index]; + + /* Wait before starting to listen */ + TSCH_SCHEDULE_AND_YIELD(pt, t, current_slot_start, tsch_timing[tsch_ts_rx_offset] - RADIO_DELAY_BEFORE_RX, "RxBeforeListen"); + TSCH_DEBUG_RX_EVENT(); + + /* Start radio for at least guard time */ + tsch_radio_on(TSCH_RADIO_CMD_ON_WITHIN_TIMESLOT); + packet_seen = NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet(); + if(!packet_seen) { + /* Check if receiving within guard time */ + BUSYWAIT_UNTIL_ABS((packet_seen = NETSTACK_RADIO.receiving_packet()), + current_slot_start, tsch_timing[tsch_ts_rx_offset] + tsch_timing[tsch_ts_rx_wait]); + } + if(!packet_seen) { + /* no packets on air */ + tsch_radio_off(TSCH_RADIO_CMD_OFF_FORCE); + } else { + TSCH_DEBUG_RX_EVENT(); + /* Save packet timestamp */ + rx_start_time = RTIMER_NOW() - RADIO_DELAY_BEFORE_DETECT; + + /* Wait until packet is received, turn radio off */ + BUSYWAIT_UNTIL_ABS(!NETSTACK_RADIO.receiving_packet(), + current_slot_start, tsch_timing[tsch_ts_rx_offset] + tsch_timing[tsch_ts_rx_wait] + tsch_timing[tsch_ts_max_tx]); + TSCH_DEBUG_RX_EVENT(); + tsch_radio_off(TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT); + + if(NETSTACK_RADIO.pending_packet()) { + static int frame_valid; + static int header_len; + static frame802154_t frame; + radio_value_t radio_last_rssi; + + /* Read packet */ + current_input->len = NETSTACK_RADIO.read((void *)current_input->payload, TSCH_PACKET_MAX_LEN); + NETSTACK_RADIO.get_value(RADIO_PARAM_LAST_RSSI, &radio_last_rssi); + current_input->rx_asn = current_asn; + current_input->rssi = (signed)radio_last_rssi; + header_len = frame802154_parse((uint8_t *)current_input->payload, current_input->len, &frame); + frame_valid = header_len > 0 && + frame802154_check_dest_panid(&frame) && + frame802154_extract_linkaddr(&frame, &source_address, &destination_address); + +#if TSCH_RESYNC_WITH_SFD_TIMESTAMPS + /* At the end of the reception, get an more accurate estimate of SFD arrival time */ + NETSTACK_RADIO.get_object(RADIO_PARAM_LAST_PACKET_TIMESTAMP, &rx_start_time, sizeof(rtimer_clock_t)); +#endif + + packet_duration = TSCH_PACKET_DURATION(current_input->len); + +#if LLSEC802154_ENABLED + /* Decrypt and verify incoming frame */ + if(frame_valid) { + if(tsch_security_parse_frame( + current_input->payload, header_len, current_input->len - header_len - tsch_security_mic_len(&frame), + &frame, &source_address, ¤t_asn)) { + current_input->len -= tsch_security_mic_len(&frame); + } else { + TSCH_LOG_ADD(tsch_log_message, + snprintf(log->message, sizeof(log->message), + "!failed to authenticate frame %u", current_input->len)); + frame_valid = 0; + } + } else { + TSCH_LOG_ADD(tsch_log_message, + snprintf(log->message, sizeof(log->message), + "!failed to parse frame %u %u", header_len, current_input->len)); + frame_valid = 0; + } +#endif /* LLSEC802154_ENABLED */ + + if(frame_valid) { + if(linkaddr_cmp(&destination_address, &linkaddr_node_addr) + || linkaddr_cmp(&destination_address, &linkaddr_null)) { + int do_nack = 0; + estimated_drift = RTIMER_CLOCK_DIFF(expected_rx_time, rx_start_time); + +#if TSCH_TIMESYNC_REMOVE_JITTER + /* remove jitter due to measurement errors */ + if(ABS(estimated_drift) <= TSCH_TIMESYNC_MEASUREMENT_ERROR) { + estimated_drift = 0; + } else if(estimated_drift > 0) { + estimated_drift -= TSCH_TIMESYNC_MEASUREMENT_ERROR; + } else { + estimated_drift += TSCH_TIMESYNC_MEASUREMENT_ERROR; + } +#endif + +#ifdef TSCH_CALLBACK_DO_NACK + if(frame.fcf.ack_required) { + do_nack = TSCH_CALLBACK_DO_NACK(current_link, + &source_address, &destination_address); + } +#endif + + if(frame.fcf.ack_required) { + static uint8_t ack_buf[TSCH_PACKET_MAX_LEN]; + static int ack_len; + + /* Build ACK frame */ + ack_len = tsch_packet_create_eack(ack_buf, sizeof(ack_buf), + &source_address, frame.seq, (int16_t)RTIMERTICKS_TO_US(estimated_drift), do_nack); + +#if LLSEC802154_ENABLED + if(tsch_is_pan_secured) { + /* Secure ACK frame. There is only header and header IEs, therefore data len == 0. */ + ack_len += tsch_security_secure_frame(ack_buf, ack_buf, ack_len, 0, ¤t_asn); + } +#endif /* LLSEC802154_ENABLED */ + + /* Copy to radio buffer */ + NETSTACK_RADIO.prepare((const void *)ack_buf, ack_len); + + /* Wait for time to ACK and transmit ACK */ + TSCH_SCHEDULE_AND_YIELD(pt, t, rx_start_time, + packet_duration + tsch_timing[tsch_ts_tx_ack_delay] - RADIO_DELAY_BEFORE_TX, "RxBeforeAck"); + TSCH_DEBUG_RX_EVENT(); + NETSTACK_RADIO.transmit(ack_len); + tsch_radio_off(TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT); + } + + /* If the sender is a time source, proceed to clock drift compensation */ + n = tsch_queue_get_nbr(&source_address); + if(n != NULL && n->is_time_source) { + int32_t since_last_timesync = ASN_DIFF(current_asn, last_sync_asn); + /* Keep track of last sync time */ + last_sync_asn = current_asn; + /* Save estimated drift */ + drift_correction = -estimated_drift; + is_drift_correction_used = 1; + tsch_timesync_update(n, since_last_timesync, -estimated_drift); + tsch_schedule_keepalive(); + } + + /* Add current input to ringbuf */ + ringbufindex_put(&input_ringbuf); + + /* Log every reception */ + TSCH_LOG_ADD(tsch_log_rx, + log->rx.src = TSCH_LOG_ID_FROM_LINKADDR((linkaddr_t*)&frame.src_addr); + log->rx.is_unicast = frame.fcf.ack_required; + log->rx.datalen = current_input->len; + log->rx.drift = drift_correction; + log->rx.drift_used = is_drift_correction_used; + log->rx.is_data = frame.fcf.frame_type == FRAME802154_DATAFRAME; + log->rx.sec_level = frame.aux_hdr.security_control.security_level; + log->rx.estimated_drift = estimated_drift; + ); + } + + /* Poll process for processing of pending input and logs */ + process_poll(&tsch_pending_events_process); + } + } + + tsch_radio_off(TSCH_RADIO_CMD_OFF_END_OF_TIMESLOT); + } + + if(input_queue_drop != 0) { + TSCH_LOG_ADD(tsch_log_message, + snprintf(log->message, sizeof(log->message), + "!queue full skipped %u", input_queue_drop); + ); + input_queue_drop = 0; + } + } + + TSCH_DEBUG_RX_EVENT(); + + PT_END(pt); +} +/*---------------------------------------------------------------------------*/ +/* Protothread for slot operation, called from rtimer interrupt + * and scheduled from tsch_schedule_slot_operation */ +static +PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr)) +{ + TSCH_DEBUG_INTERRUPT(); + PT_BEGIN(&slot_operation_pt); + + /* Loop over all active slots */ + while(tsch_is_associated) { + + if(current_link == NULL || tsch_lock_requested) { /* Skip slot operation if there is no link + or if there is a pending request for getting the lock */ + /* Issue a log whenever skipping a slot */ + TSCH_LOG_ADD(tsch_log_message, + snprintf(log->message, sizeof(log->message), + "!skipped slot %u %u %u", + tsch_locked, + tsch_lock_requested, + current_link == NULL); + ); + + } else { + uint8_t current_channel; + int is_active_slot; + TSCH_DEBUG_SLOT_START(); + tsch_in_slot_operation = 1; + /* Reset drift correction */ + drift_correction = 0; + is_drift_correction_used = 0; + /* Get a packet ready to be sent */ + current_packet = get_packet_and_neighbor_for_link(current_link, ¤t_neighbor); + /* There is no packet to send, and this link does not have Rx flag. Instead of doing + * nothing, switch to the backup link (has Rx flag) if any. */ + if(current_packet == NULL && !(current_link->link_options & LINK_OPTION_RX) && backup_link != NULL) { + current_link = backup_link; + current_packet = get_packet_and_neighbor_for_link(current_link, ¤t_neighbor); + } + is_active_slot = current_packet != NULL || (current_link->link_options & LINK_OPTION_RX); + if(is_active_slot) { + /* Hop channel */ + current_channel = tsch_calculate_channel(¤t_asn, current_link->channel_offset); + NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, current_channel); + /* Turn the radio on already here if configured so; necessary for radios with slow startup */ + tsch_radio_on(TSCH_RADIO_CMD_ON_START_OF_TIMESLOT); + /* Decide whether it is a TX/RX/IDLE or OFF slot */ + /* Actual slot operation */ + if(current_packet != NULL) { + /* We have something to transmit, do the following: + * 1. send + * 2. update_backoff_state(current_neighbor) + * 3. post tx callback + **/ + static struct pt slot_tx_pt; + PT_SPAWN(&slot_operation_pt, &slot_tx_pt, tsch_tx_slot(&slot_tx_pt, t)); + } else { + /* Listen */ + static struct pt slot_rx_pt; + PT_SPAWN(&slot_operation_pt, &slot_rx_pt, tsch_rx_slot(&slot_rx_pt, t)); + } + } + TSCH_DEBUG_SLOT_END(); + } + + /* End of slot operation, schedule next slot or resynchronize */ + + /* Do we need to resynchronize? i.e., wait for EB again */ + if(!tsch_is_coordinator && (ASN_DIFF(current_asn, last_sync_asn) > + (100 * TSCH_CLOCK_TO_SLOTS(TSCH_DESYNC_THRESHOLD / 100, tsch_timing[tsch_ts_timeslot_length])))) { + TSCH_LOG_ADD(tsch_log_message, + snprintf(log->message, sizeof(log->message), + "! leaving the network, last sync %u", + (unsigned)ASN_DIFF(current_asn, last_sync_asn)); + ); + last_timesource_neighbor = NULL; + tsch_disassociate(); + } else { + /* backup of drift correction for printing debug messages */ + /* int32_t drift_correction_backup = drift_correction; */ + uint16_t timeslot_diff = 0; + rtimer_clock_t prev_slot_start; + /* Time to next wake up */ + rtimer_clock_t time_to_next_active_slot; + /* Schedule next wakeup skipping slots if missed deadline */ + do { + if(current_link != NULL + && current_link->link_options & LINK_OPTION_TX + && current_link->link_options & LINK_OPTION_SHARED) { + /* Decrement the backoff window for all neighbors able to transmit over + * this Tx, Shared link. */ + tsch_queue_update_all_backoff_windows(¤t_link->addr); + } + + /* Get next active link */ + current_link = tsch_schedule_get_next_active_link(¤t_asn, ×lot_diff, &backup_link); + if(current_link == NULL) { + /* There is no next link. Fall back to default + * behavior: wake up at the next slot. */ + timeslot_diff = 1; + } + /* Update ASN */ + ASN_INC(current_asn, timeslot_diff); + /* Time to next wake up */ + time_to_next_active_slot = timeslot_diff * tsch_timing[tsch_ts_timeslot_length] + drift_correction; + drift_correction = 0; + is_drift_correction_used = 0; + /* Update current slot start */ + prev_slot_start = current_slot_start; + current_slot_start += time_to_next_active_slot; + current_slot_start += tsch_timesync_adaptive_compensate(time_to_next_active_slot); + } while(!tsch_schedule_slot_operation(t, prev_slot_start, time_to_next_active_slot, "main")); + } + + tsch_in_slot_operation = 0; + PT_YIELD(&slot_operation_pt); + } + + PT_END(&slot_operation_pt); +} +/*---------------------------------------------------------------------------*/ +/* Set global time before starting slot operation, + * with a rtimer time and an ASN */ +void +tsch_slot_operation_start(void) +{ + static struct rtimer slot_operation_timer; + rtimer_clock_t time_to_next_active_slot; + rtimer_clock_t prev_slot_start; + TSCH_DEBUG_INIT(); + do { + uint16_t timeslot_diff; + /* Get next active link */ + current_link = tsch_schedule_get_next_active_link(¤t_asn, ×lot_diff, &backup_link); + if(current_link == NULL) { + /* There is no next link. Fall back to default + * behavior: wake up at the next slot. */ + timeslot_diff = 1; + } + /* Update ASN */ + ASN_INC(current_asn, timeslot_diff); + /* Time to next wake up */ + time_to_next_active_slot = timeslot_diff * tsch_timing[tsch_ts_timeslot_length]; + /* Update current slot start */ + prev_slot_start = current_slot_start; + current_slot_start += time_to_next_active_slot; + } while(!tsch_schedule_slot_operation(&slot_operation_timer, prev_slot_start, time_to_next_active_slot, "association")); +} +/*---------------------------------------------------------------------------*/ +/* Start actual slot operation */ +void +tsch_slot_operation_sync(rtimer_clock_t next_slot_start, + struct asn_t *next_slot_asn) +{ + current_slot_start = next_slot_start; + current_asn = *next_slot_asn; + last_sync_asn = current_asn; + current_link = NULL; +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/mac/tsch/tsch-slot-operation.h b/core/net/mac/tsch/tsch-slot-operation.h new file mode 100644 index 000000000..f74778c00 --- /dev/null +++ b/core/net/mac/tsch/tsch-slot-operation.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#ifndef __TSCH_SLOT_OPERATION_H__ +#define __TSCH_SLOT_OPERATION_H__ + +/********** Includes **********/ + +#include "contiki.h" +#include "lib/ringbufindex.h" +#include "net/mac/tsch/tsch-packet.h" +#include "net/mac/tsch/tsch-private.h" + +/******** Configuration *******/ + +/* Size of the ring buffer storing dequeued outgoing packets (only an array of pointers). + * Must be power of two, and greater or equal to QUEUEBUF_NUM */ +#ifdef TSCH_CONF_DEQUEUED_ARRAY_SIZE +#define TSCH_DEQUEUED_ARRAY_SIZE TSCH_CONF_DEQUEUED_ARRAY_SIZE +#else +/* By default, round QUEUEBUF_CONF_NUM to next power of two + * (in the range [4;256]) */ +#if QUEUEBUF_CONF_NUM <= 4 +#define TSCH_DEQUEUED_ARRAY_SIZE 4 +#elif QUEUEBUF_CONF_NUM <= 8 +#define TSCH_DEQUEUED_ARRAY_SIZE 8 +#elif QUEUEBUF_CONF_NUM <= 16 +#define TSCH_DEQUEUED_ARRAY_SIZE 16 +#elif QUEUEBUF_CONF_NUM <= 32 +#define TSCH_DEQUEUED_ARRAY_SIZE 32 +#elif QUEUEBUF_CONF_NUM <= 64 +#define TSCH_DEQUEUED_ARRAY_SIZE 64 +#elif QUEUEBUF_CONF_NUM <= 128 +#define TSCH_DEQUEUED_ARRAY_SIZE 128 +#else +#define TSCH_DEQUEUED_ARRAY_SIZE 256 +#endif +#endif + +/* Size of the ring buffer storing incoming packets. + * Must be power of two */ +#ifdef TSCH_CONF_MAX_INCOMING_PACKETS +#define TSCH_MAX_INCOMING_PACKETS TSCH_CONF_MAX_INCOMING_PACKETS +#else +#define TSCH_MAX_INCOMING_PACKETS 4 +#endif + +/*********** Callbacks *********/ + +/* Called by TSCH form interrupt after receiving a frame, enabled upper-layer to decide + * whether to ACK or NACK */ +#ifdef TSCH_CALLBACK_DO_NACK +int TSCH_CALLBACK_DO_NACK(struct tsch_link *link, linkaddr_t *src, linkaddr_t *dst); +#endif + +/************ Types ***********/ + +/* Stores data about an incoming packet */ +struct input_packet { + uint8_t payload[TSCH_PACKET_MAX_LEN]; /* Packet payload */ + struct asn_t rx_asn; /* ASN when the packet was received */ + int len; /* Packet len */ + uint16_t rssi; /* RSSI for this packet */ +}; + +/***** External Variables *****/ + +/* A ringbuf storing outgoing packets after they were dequeued. + * Will be processed layer by tsch_tx_process_pending */ +extern struct ringbufindex dequeued_ringbuf; +extern struct tsch_packet *dequeued_array[TSCH_DEQUEUED_ARRAY_SIZE]; +/* A ringbuf storing incoming packets. + * Will be processed layer by tsch_rx_process_pending */ +extern struct ringbufindex input_ringbuf; +extern struct input_packet input_array[TSCH_MAX_INCOMING_PACKETS]; + +/********** Functions *********/ + +/* Returns a 802.15.4 channel from an ASN and channel offset */ +uint8_t tsch_calculate_channel(struct asn_t *asn, uint8_t channel_offset); +/* Is TSCH locked? */ +int tsch_is_locked(void); +/* Lock TSCH (no link operation) */ +int tsch_get_lock(void); +/* Release TSCH lock */ +void tsch_release_lock(void); +/* Set global time before starting slot operation, + * with a rtimer time and an ASN */ +void tsch_slot_operation_sync(rtimer_clock_t next_slot_start, + struct asn_t *next_slot_asn); +/* Start actual slot operation */ +void tsch_slot_operation_start(void); + +#endif /* __TSCH_SLOT_OPERATION_H__ */ diff --git a/core/net/mac/tsch/tsch.c b/core/net/mac/tsch/tsch.c new file mode 100644 index 000000000..292744ecc --- /dev/null +++ b/core/net/mac/tsch/tsch.c @@ -0,0 +1,1034 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * IEEE 802.15.4 TSCH MAC implementation. + * Does not use any RDC layer. Should be used with nordc. + * \author + * Simon Duquennoy + * Beshr Al Nahas + * + */ + +#include "contiki.h" +#include "dev/radio.h" +#include "net/netstack.h" +#include "net/packetbuf.h" +#include "net/queuebuf.h" +#include "net/mac/framer-802154.h" +#include "net/mac/tsch/tsch.h" +#include "net/mac/tsch/tsch-slot-operation.h" +#include "net/mac/tsch/tsch-queue.h" +#include "net/mac/tsch/tsch-private.h" +#include "net/mac/tsch/tsch-log.h" +#include "net/mac/tsch/tsch-packet.h" +#include "net/mac/tsch/tsch-security.h" +#include "lib/random.h" + +#if FRAME802154_VERSION < FRAME802154_IEEE802154E_2012 +#error TSCH: FRAME802154_VERSION must be at least FRAME802154_IEEE802154E_2012 +#endif + +#if TSCH_LOG_LEVEL >= 1 +#define DEBUG DEBUG_PRINT +#else /* TSCH_LOG_LEVEL */ +#define DEBUG DEBUG_NONE +#endif /* TSCH_LOG_LEVEL */ +#include "net/net-debug.h" + +/* Use to collect link statistics even on Keep-Alive, even though they were + * not sent from an upper layer and don't have a valid packet_sent callback */ +#ifndef TSCH_LINK_NEIGHBOR_CALLBACK +void uip_ds6_link_neighbor_callback(int status, int numtx); +#define TSCH_LINK_NEIGHBOR_CALLBACK(dest, status, num) uip_ds6_link_neighbor_callback(status, num) +#endif /* TSCH_LINK_NEIGHBOR_CALLBACK */ + +/* 802.15.4 duplicate frame detection */ +struct seqno { + linkaddr_t sender; + uint8_t seqno; +}; + +/* Size of the sequence number history */ +#ifdef NETSTACK_CONF_MAC_SEQNO_HISTORY +#define MAX_SEQNOS NETSTACK_CONF_MAC_SEQNO_HISTORY +#else /* NETSTACK_CONF_MAC_SEQNO_HISTORY */ +#define MAX_SEQNOS 8 +#endif /* NETSTACK_CONF_MAC_SEQNO_HISTORY */ + +/* Seqno history */ +static struct seqno received_seqnos[MAX_SEQNOS]; + +/* Let TSCH select a time source with no help of an upper layer. + * We do so using statistics from incoming EBs */ +#if TSCH_AUTOSELECT_TIME_SOURCE +int best_neighbor_eb_count; +struct eb_stat { + int rx_count; + int jp; +}; +NBR_TABLE(struct eb_stat, eb_stats); +#endif /* TSCH_AUTOSELECT_TIME_SOURCE */ + +/* TSCH channel hopping sequence */ +uint8_t tsch_hopping_sequence[TSCH_HOPPING_SEQUENCE_MAX_LEN]; +struct asn_divisor_t tsch_hopping_sequence_length; + +/* Default TSCH timeslot timing (in micro-second) */ +static const uint16_t tsch_default_timing_us[tsch_ts_elements_count] = { + TSCH_DEFAULT_TS_CCA_OFFSET, + TSCH_DEFAULT_TS_CCA, + TSCH_DEFAULT_TS_TX_OFFSET, + TSCH_DEFAULT_TS_RX_OFFSET, + TSCH_DEFAULT_TS_RX_ACK_DELAY, + TSCH_DEFAULT_TS_TX_ACK_DELAY, + TSCH_DEFAULT_TS_RX_WAIT, + TSCH_DEFAULT_TS_ACK_WAIT, + TSCH_DEFAULT_TS_RX_TX, + TSCH_DEFAULT_TS_MAX_ACK, + TSCH_DEFAULT_TS_MAX_TX, + TSCH_DEFAULT_TS_TIMESLOT_LENGTH, +}; +/* TSCH timeslot timing (in rtimer ticks) */ +rtimer_clock_t tsch_timing[tsch_ts_elements_count]; + +#if LINKADDR_SIZE == 8 +/* 802.15.4 broadcast MAC address */ +const linkaddr_t tsch_broadcast_address = { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }; +/* Address used for the EB virtual neighbor queue */ +const linkaddr_t tsch_eb_address = { { 0, 0, 0, 0, 0, 0, 0, 0 } }; +#else /* LINKADDR_SIZE == 8 */ +const linkaddr_t tsch_broadcast_address = { { 0xff, 0xff } }; +const linkaddr_t tsch_eb_address = { { 0, 0 } }; +#endif /* LINKADDR_SIZE == 8 */ + +/* Is TSCH started? */ +int tsch_is_started = 0; +/* Has TSCH initialization failed? */ +int tsch_is_initialized = 0; +/* Are we coordinator of the TSCH network? */ +int tsch_is_coordinator = 0; +/* Are we associated to a TSCH network? */ +int tsch_is_associated = 0; +/* Is the PAN running link-layer security? */ +int tsch_is_pan_secured = LLSEC802154_ENABLED; +/* The current Absolute Slot Number (ASN) */ +struct asn_t current_asn; +/* Device rank or join priority: + * For PAN coordinator: 0 -- lower is better */ +uint8_t tsch_join_priority; +/* The current TSCH sequence number, used for both data and EBs */ +static uint8_t tsch_packet_seqno = 0; +/* Current period for EB output */ +static clock_time_t tsch_current_eb_period; + +/* timer for sending keepalive messages */ +static struct ctimer keepalive_timer; + +/* TSCH processes and protothreads */ +PT_THREAD(tsch_scan(struct pt *pt)); +PROCESS(tsch_process, "TSCH: main process"); +PROCESS(tsch_send_eb_process, "TSCH: send EB process"); +PROCESS(tsch_pending_events_process, "TSCH: pending events process"); + +/* Other function prototypes */ +static void packet_input(void); + +/* Getters and setters */ + +/*---------------------------------------------------------------------------*/ +void +tsch_set_coordinator(int enable) +{ + tsch_is_coordinator = enable; + tsch_set_eb_period(TSCH_EB_PERIOD); +} +/*---------------------------------------------------------------------------*/ +void +tsch_set_pan_secured(int enable) +{ + tsch_is_pan_secured = LLSEC802154_ENABLED && enable; +} +/*---------------------------------------------------------------------------*/ +void +tsch_set_join_priority(uint8_t jp) +{ + tsch_join_priority = jp; +} +/*---------------------------------------------------------------------------*/ +void +tsch_set_eb_period(uint32_t period) +{ + tsch_current_eb_period = period; +} +/*---------------------------------------------------------------------------*/ +static void +tsch_reset(void) +{ + int i; + frame802154_set_pan_id(0xffff); + /* First make sure pending packet callbacks are sent etc */ + process_post_synch(&tsch_pending_events_process, PROCESS_EVENT_POLL, NULL); + /* Reset neighbor queues */ + tsch_queue_reset(); + /* Remove unused neighbors */ + tsch_queue_free_unused_neighbors(); + tsch_queue_update_time_source(NULL); + /* Initialize global variables */ + tsch_join_priority = 0xff; + ASN_INIT(current_asn, 0, 0); + current_link = NULL; + /* Reset timeslot timing to defaults */ + for(i = 0; i < tsch_ts_elements_count; i++) { + tsch_timing[i] = US_TO_RTIMERTICKS(tsch_default_timing_us[i]); + } +#ifdef TSCH_CALLBACK_LEAVING_NETWORK + TSCH_CALLBACK_LEAVING_NETWORK(); +#endif +#if TSCH_AUTOSELECT_TIME_SOURCE + best_neighbor_eb_count = 0; + nbr_table_register(eb_stats, NULL); + tsch_set_eb_period(TSCH_EB_PERIOD); +#endif +} + +/* TSCH keep-alive functions */ + +/*---------------------------------------------------------------------------*/ +/* Tx callback for keepalive messages */ +static void +keepalive_packet_sent(void *ptr, int status, int transmissions) +{ +#ifdef TSCH_LINK_NEIGHBOR_CALLBACK + TSCH_LINK_NEIGHBOR_CALLBACK(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), status, transmissions); +#endif + PRINTF("TSCH: KA sent to %u, st %d-%d\n", + TSCH_LOG_ID_FROM_LINKADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)), status, transmissions); + tsch_schedule_keepalive(); +} +/*---------------------------------------------------------------------------*/ +/* Prepare and send a keepalive message */ +static void +keepalive_send() +{ + if(tsch_is_associated) { + struct tsch_neighbor *n = tsch_queue_get_time_source(); + /* Simply send an empty packet */ + packetbuf_clear(); + packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &n->addr); + NETSTACK_LLSEC.send(keepalive_packet_sent, NULL); + PRINTF("TSCH: sending KA to %u\n", + TSCH_LOG_ID_FROM_LINKADDR(&n->addr)); + } +} +/*---------------------------------------------------------------------------*/ +/* Set ctimer to send a keepalive message after expiration of TSCH_KEEPALIVE_TIMEOUT */ +void +tsch_schedule_keepalive() +{ + /* Pick a delay in the range [TSCH_KEEPALIVE_TIMEOUT*0.9, TSCH_KEEPALIVE_TIMEOUT[ */ + if(!tsch_is_coordinator && tsch_is_associated) { + unsigned long delay = (TSCH_KEEPALIVE_TIMEOUT - TSCH_KEEPALIVE_TIMEOUT / 10) + + random_rand() % (TSCH_KEEPALIVE_TIMEOUT / 10); + ctimer_set(&keepalive_timer, delay, keepalive_send, NULL); + } +} +/*---------------------------------------------------------------------------*/ +static void +eb_input(struct input_packet *current_input) +{ + /* PRINTF("TSCH: EB received\n"); */ + frame802154_t frame; + /* Verify incoming EB (does its ASN match our Rx time?), + * and update our join priority. */ + struct ieee802154_ies eb_ies; + + if(tsch_packet_parse_eb(current_input->payload, current_input->len, + &frame, &eb_ies, NULL, 1)) { + /* PAN ID check and authentication done at rx time */ + +#if TSCH_AUTOSELECT_TIME_SOURCE + if(!tsch_is_coordinator) { + /* Maintain EB received counter for every neighbor */ + struct eb_stat *stat = (struct eb_stat *)nbr_table_get_from_lladdr(eb_stats, &frame.src_addr); + if(stat == NULL) { + stat = (struct eb_stat *)nbr_table_add_lladdr(eb_stats, &frame.src_addr); + } + if(stat != NULL) { + stat->rx_count++; + stat->jp = eb_ies.join_priority; + best_neighbor_eb_count = MAX(best_neighbor_eb_count, stat->rx_count); + } + /* Select best time source */ + struct eb_stat *best_stat = NULL; + stat = nbr_table_head(eb_stats); + while(stat != NULL) { + /* Is neighbor eligible as a time source? */ + if(stat->rx_count > best_neighbor_eb_count / 2) { + if(best_stat == NULL || + stat->jp < best_stat->jp) { + best_stat = stat; + } + } + stat = nbr_table_next(eb_stats, stat); + } + /* Update time source */ + if(best_stat != NULL) { + tsch_queue_update_time_source(nbr_table_get_lladdr(eb_stats, best_stat)); + tsch_join_priority = best_stat->jp + 1; + } + } +#endif + + struct tsch_neighbor *n = tsch_queue_get_time_source(); + /* Did the EB come from our time source? */ + if(n != NULL && linkaddr_cmp((linkaddr_t *)&frame.src_addr, &n->addr)) { + /* Check for ASN drift */ + int32_t asn_diff = ASN_DIFF(current_input->rx_asn, eb_ies.ie_asn); + if(asn_diff != 0) { + /* We disagree with our time source's ASN -- leave the network */ + PRINTF("TSCH:! ASN drifted by %ld, leaving the network\n", asn_diff); + tsch_disassociate(); + } + + if(eb_ies.ie_join_priority >= TSCH_MAX_JOIN_PRIORITY) { + /* Join priority unacceptable. Leave network. */ + PRINTF("TSCH:! EB JP too high %u, leaving the network\n", + eb_ies.ie_join_priority); + tsch_disassociate(); + } else { +#if TSCH_AUTOSELECT_TIME_SOURCE + /* Update join priority */ + if(tsch_join_priority != eb_ies.ie_join_priority + 1) { + PRINTF("TSCH: update JP from EB %u -> %u\n", + tsch_join_priority, eb_ies.ie_join_priority + 1); + tsch_join_priority = eb_ies.ie_join_priority + 1; + } +#endif /* TSCH_AUTOSELECT_TIME_SOURCE */ + } + } + } +} + +/*---------------------------------------------------------------------------*/ +/* Process pending input packet(s) */ +static void +tsch_rx_process_pending() +{ + int16_t input_index; + /* Loop on accessing (without removing) a pending input packet */ + while((input_index = ringbufindex_peek_get(&input_ringbuf)) != -1) { + struct input_packet *current_input = &input_array[input_index]; + frame802154_t frame; + uint8_t ret = frame802154_parse(current_input->payload, current_input->len, &frame); + int is_data = ret && frame.fcf.frame_type == FRAME802154_DATAFRAME; + int is_eb = ret + && frame.fcf.frame_version == FRAME802154_IEEE802154E_2012 + && frame.fcf.frame_type == FRAME802154_BEACONFRAME; + + if(is_data) { + /* Skip EBs and other control messages */ + /* Copy to packetbuf for processing */ + packetbuf_copyfrom(current_input->payload, current_input->len); + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, current_input->rssi); + } + + /* Remove input from ringbuf */ + ringbufindex_get(&input_ringbuf); + + if(is_data) { + /* Pass to upper layers */ + packet_input(); + } else if(is_eb) { + eb_input(current_input); + } + } +} + +/*---------------------------------------------------------------------------*/ +/* Pass sent packets to upper layer */ +static void +tsch_tx_process_pending() +{ + int16_t dequeued_index; + /* Loop on accessing (without removing) a pending input packet */ + while((dequeued_index = ringbufindex_peek_get(&dequeued_ringbuf)) != -1) { + struct tsch_packet *p = dequeued_array[dequeued_index]; + /* Put packet into packetbuf for packet_sent callback */ + queuebuf_to_packetbuf(p->qb); + /* Call packet_sent callback */ + mac_call_sent_callback(p->sent, p->ptr, p->ret, p->transmissions); + /* Free packet queuebuf */ + tsch_queue_free_packet(p); + /* Free all unused neighbors */ + tsch_queue_free_unused_neighbors(); + /* Remove dequeued packet from ringbuf */ + ringbufindex_get(&dequeued_ringbuf); + } +} +/*---------------------------------------------------------------------------*/ +/* Setup TSCH as a coordinator */ +static void +tsch_start_coordinator(void) +{ + frame802154_set_pan_id(IEEE802154_PANID); + /* Initialize hopping sequence as default */ + memcpy(tsch_hopping_sequence, TSCH_DEFAULT_HOPPING_SEQUENCE, sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE)); + ASN_DIVISOR_INIT(tsch_hopping_sequence_length, sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE)); +#if TSCH_SCHEDULE_WITH_6TISCH_MINIMAL + tsch_schedule_create_minimal(); +#endif + + tsch_is_associated = 1; + tsch_join_priority = 0; + + PRINTF("TSCH: starting as coordinator, PAN ID %x, asn-%x.%lx\n", + frame802154_get_pan_id(), current_asn.ms1b, current_asn.ls4b); + + /* Start slot operation */ + tsch_slot_operation_sync(RTIMER_NOW(), ¤t_asn); +} +/*---------------------------------------------------------------------------*/ +/* Leave the TSCH network */ +void +tsch_disassociate(void) +{ + if(tsch_is_associated == 1) { + tsch_is_associated = 0; + process_post(&tsch_process, PROCESS_EVENT_POLL, NULL); + PRINTF("TSCH: leaving the network\n"); + } +} +/*---------------------------------------------------------------------------*/ +/* Attempt to associate to a network form an incoming EB */ +static int +tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp) +{ + frame802154_t frame; + struct ieee802154_ies ies; + uint8_t hdrlen; + int i; + + if(input_eb == NULL || tsch_packet_parse_eb(input_eb->payload, input_eb->len, + &frame, &ies, &hdrlen, 0) == 0) { + PRINTF("TSCH:! failed to parse EB (len %u)\n", input_eb->len); + return 0; + } + + current_asn = ies.ie_asn; + tsch_join_priority = ies.ie_join_priority + 1; + +#if TSCH_JOIN_SECURED_ONLY + if(frame.fcf.security_enabled == 0) { + PRINTF("TSCH:! parse_eb: EB is not secured\n"); + return 0; + } +#endif /* TSCH_JOIN_SECURED_ONLY */ + +#if LLSEC802154_ENABLED + if(!tsch_security_parse_frame(input_eb->payload, hdrlen, + input_eb->len - hdrlen - tsch_security_mic_len(&frame), + &frame, (linkaddr_t*)&frame.src_addr, ¤t_asn)) { + PRINTF("TSCH:! parse_eb: failed to authenticate\n"); + return 0; + } +#endif /* LLSEC802154_ENABLED */ + +#if !LLSEC802154_ENABLED + if(frame.fcf.security_enabled == 1) { + PRINTF("TSCH:! parse_eb: we do not support security, but EB is secured\n"); + return 0; + } +#endif /* !LLSEC802154_ENABLED */ + +#if TSCH_JOIN_MY_PANID_ONLY + /* Check if the EB comes from the PAN ID we expect */ + if(frame.src_pid != IEEE802154_PANID) { + PRINTF("TSCH:! parse_eb: PAN ID %x != %x\n", frame.src_pid, IEEE802154_PANID); + return 0; + } +#endif /* TSCH_JOIN_MY_PANID_ONLY */ + + /* There was no join priority (or 0xff) in the EB, do not join */ + if(ies.ie_join_priority == 0xff) { + PRINTF("TSCH:! parse_eb: no join priority\n"); + return 0; + } + + /* TSCH timeslot timing */ + for(i = 0; i < tsch_ts_elements_count; i++) { + if(ies.ie_tsch_timeslot_id == 0) { + tsch_timing[i] = US_TO_RTIMERTICKS(tsch_default_timing_us[i]); + } else { + tsch_timing[i] = US_TO_RTIMERTICKS(ies.ie_tsch_timeslot[i]); + } + } + + /* TSCH hopping sequence */ + if(ies.ie_channel_hopping_sequence_id == 0) { + memcpy(tsch_hopping_sequence, TSCH_DEFAULT_HOPPING_SEQUENCE, sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE)); + ASN_DIVISOR_INIT(tsch_hopping_sequence_length, sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE)); + } else { + if(ies.ie_hopping_sequence_len <= sizeof(tsch_hopping_sequence)) { + memcpy(tsch_hopping_sequence, ies.ie_hopping_sequence_list, ies.ie_hopping_sequence_len); + ASN_DIVISOR_INIT(tsch_hopping_sequence_length, ies.ie_hopping_sequence_len); + } else { + PRINTF("TSCH:! parse_eb: hopping sequence too long (%u)\n", ies.ie_hopping_sequence_len); + return 0; + } + } + +#if TSCH_CHECK_TIME_AT_ASSOCIATION > 0 + /* Divide by 4k and multiply again to avoid integer overflow */ + uint32_t expected_asn = 4096 * TSCH_CLOCK_TO_SLOTS(clock_time() / 4096, tsch_timing_timeslot_length); /* Expected ASN based on our current time*/ + int32_t asn_threshold = TSCH_CHECK_TIME_AT_ASSOCIATION * 60ul * TSCH_CLOCK_TO_SLOTS(CLOCK_SECOND, tsch_timing_timeslot_length); + int32_t asn_diff = (int32_t)current_asn.ls4b - expected_asn; + if(asn_diff > asn_threshold) { + PRINTF("TSCH:! EB ASN rejected %lx %lx %ld\n", + current_asn.ls4b, expected_asn, asn_diff); + return 0; + } +#endif + +#if TSCH_INIT_SCHEDULE_FROM_EB + /* Create schedule */ + if(ies.ie_tsch_slotframe_and_link.num_slotframes == 0) { +#if TSCH_SCHEDULE_WITH_6TISCH_MINIMAL + PRINTF("TSCH: parse_eb: no schedule, setting up minimal schedule\n"); + tsch_schedule_create_minimal(); +#else + PRINTF("TSCH: parse_eb: no schedule\n"); +#endif + } else { + /* First, empty current schedule */ + tsch_schedule_remove_all_slotframes(); + /* We support only 0 or 1 slotframe in this IE */ + int num_links = ies.ie_tsch_slotframe_and_link.num_links; + if(num_links <= FRAME802154E_IE_MAX_LINKS) { + int i; + struct tsch_slotframe *sf = tsch_schedule_add_slotframe( + ies.ie_tsch_slotframe_and_link.slotframe_handle, + ies.ie_tsch_slotframe_and_link.slotframe_size); + for(i = 0; i < num_links; i++) { + tsch_schedule_add_link(sf, + ies.ie_tsch_slotframe_and_link.links[i].link_options, + LINK_TYPE_ADVERTISING, &tsch_broadcast_address, + ies.ie_tsch_slotframe_and_link.links[i].timeslot, ies.ie_tsch_slotframe_and_link.links[i].channel_offset); + } + } else { + PRINTF("TSCH:! parse_eb: too many links in schedule (%u)\n", num_links); + return 0; + } + } +#endif /* TSCH_INIT_SCHEDULE_FROM_EB */ + + if(tsch_join_priority < TSCH_MAX_JOIN_PRIORITY) { + struct tsch_neighbor *n; + + /* Add coordinator to list of neighbors, lock the entry */ + n = tsch_queue_add_nbr((linkaddr_t *)&frame.src_addr); + + if(n != NULL) { + tsch_queue_update_time_source((linkaddr_t *)&frame.src_addr); + +#ifdef TSCH_CALLBACK_JOINING_NETWORK + TSCH_CALLBACK_JOINING_NETWORK(); +#endif + + /* Set PANID */ + frame802154_set_pan_id(frame.src_pid); + + /* Synchronize on EB */ + tsch_slot_operation_sync(timestamp - tsch_timing[tsch_ts_tx_offset], ¤t_asn); + + /* Update global flags */ + tsch_is_associated = 1; + tsch_is_pan_secured = frame.fcf.security_enabled; + + /* Association done, schedule keepalive messages */ + tsch_schedule_keepalive(); + + PRINTF("TSCH: association done, sec %u, PAN ID %x, asn-%x.%lx, jp %u, timeslot id %u, hopping id %u, slotframe len %u with %u links, from ", + tsch_is_pan_secured, + frame.src_pid, + current_asn.ms1b, current_asn.ls4b, tsch_join_priority, + ies.ie_tsch_timeslot_id, + ies.ie_channel_hopping_sequence_id, + ies.ie_tsch_slotframe_and_link.slotframe_size, + ies.ie_tsch_slotframe_and_link.num_links); + PRINTLLADDR((const uip_lladdr_t *)&frame.src_addr); + PRINTF("\n"); + + return 1; + } + } + PRINTF("TSCH:! did not associate.\n"); + return 0; +} + +/* Processes and protothreads used by TSCH */ + +/*---------------------------------------------------------------------------*/ +/* Scanning protothread, called by tsch_process: + * Listen to different channels, and when receiving an EB, + * attempt to associate. + */ +PT_THREAD(tsch_scan(struct pt *pt)) +{ + PT_BEGIN(pt); + + static struct input_packet input_eb; + static struct etimer scan_timer; + /* Time when we started scanning on current_channel */ + static clock_time_t current_channel_since; + + ASN_INIT(current_asn, 0, 0); + + etimer_set(&scan_timer, CLOCK_SECOND / TSCH_ASSOCIATION_POLL_FREQUENCY); + current_channel_since = clock_time(); + + while(!tsch_is_associated && !tsch_is_coordinator) { + /* Hop to any channel offset */ + static uint8_t current_channel = 0; + + /* We are not coordinator, try to associate */ + rtimer_clock_t t0; + int is_packet_pending = 0; + clock_time_t now_time = clock_time(); + + /* Switch to a (new) channel for scanning */ + if(current_channel == 0 || now_time - current_channel_since > TSCH_CHANNEL_SCAN_DURATION) { + /* Pick a channel at random in TSCH_JOIN_HOPPING_SEQUENCE */ + uint8_t scan_channel = TSCH_JOIN_HOPPING_SEQUENCE[ + random_rand() % sizeof(TSCH_JOIN_HOPPING_SEQUENCE)]; + if(current_channel != scan_channel) { + NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, scan_channel); + current_channel = scan_channel; + PRINTF("TSCH: scanning on channel %u\n", scan_channel); + } + current_channel_since = now_time; + } + + /* Turn radio on and wait for EB */ + NETSTACK_RADIO.on(); + + is_packet_pending = NETSTACK_RADIO.pending_packet(); + if(!is_packet_pending && NETSTACK_RADIO.receiving_packet()) { + /* If we are currently receiving a packet, wait until end of reception */ + t0 = RTIMER_NOW(); + BUSYWAIT_UNTIL_ABS((is_packet_pending = NETSTACK_RADIO.pending_packet()), t0, RTIMER_SECOND / 100); + } + + if(is_packet_pending) { + /* Read packet */ + input_eb.len = NETSTACK_RADIO.read(input_eb.payload, TSCH_PACKET_MAX_LEN); + + /* Save packet timestamp */ + NETSTACK_RADIO.get_object(RADIO_PARAM_LAST_PACKET_TIMESTAMP, &t0, sizeof(rtimer_clock_t)); + + /* Parse EB and attempt to associate */ + PRINTF("TSCH: association: received packet (%u bytes) on channel %u\n", input_eb.len, current_channel); + + tsch_associate(&input_eb, t0); + } + + if(tsch_is_associated) { + /* End of association, turn the radio off */ + NETSTACK_RADIO.off(); + } else if(!tsch_is_coordinator) { + /* Go back to scanning */ + etimer_reset(&scan_timer); + PT_WAIT_UNTIL(pt, etimer_expired(&scan_timer)); + } + } + + PT_END(pt); +} + +/*---------------------------------------------------------------------------*/ +/* The main TSCH process */ +PROCESS_THREAD(tsch_process, ev, data) +{ + static struct pt scan_pt; + + PROCESS_BEGIN(); + + while(1) { + + while(!tsch_is_associated) { + if(tsch_is_coordinator) { + /* We are coordinator, start operating now */ + tsch_start_coordinator(); + } else { + /* Start scanning, will attempt to join when receiving an EB */ + PROCESS_PT_SPAWN(&scan_pt, tsch_scan(&scan_pt)); + } + } + + /* We are part of a TSCH network, start slot operation */ + tsch_slot_operation_start(); + + /* Yield our main process. Slot operation will re-schedule itself + * as long as we are associated */ + PROCESS_YIELD_UNTIL(!tsch_is_associated); + + /* Will need to re-synchronize */ + tsch_reset(); + } + + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +/* A periodic process to send TSCH Enhanced Beacons (EB) */ +PROCESS_THREAD(tsch_send_eb_process, ev, data) +{ + static struct etimer eb_timer; + + PROCESS_BEGIN(); + + /* Wait until association */ + etimer_set(&eb_timer, CLOCK_SECOND / 10); + while(!tsch_is_associated) { + PROCESS_WAIT_UNTIL(etimer_expired(&eb_timer)); + etimer_reset(&eb_timer); + } + + /* Set an initial delay except for coordinator, which should send an EB asap */ + if(!tsch_is_coordinator) { + etimer_set(&eb_timer, random_rand() % TSCH_EB_PERIOD); + PROCESS_WAIT_UNTIL(etimer_expired(&eb_timer)); + } + + while(1) { + unsigned long delay; + + if(tsch_is_associated && tsch_current_eb_period > 0) { + /* Enqueue EB only if there isn't already one in queue */ + if(tsch_queue_packet_count(&tsch_eb_address) == 0) { + int eb_len; + uint8_t hdr_len = 0; + uint8_t tsch_sync_ie_offset; + /* Prepare the EB packet and schedule it to be sent */ + packetbuf_clear(); + /* We don't use seqno 0 */ + if(++tsch_packet_seqno == 0) { + tsch_packet_seqno++; + } + packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_BEACONFRAME); + packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, tsch_packet_seqno); +#if LLSEC802154_ENABLED + if(tsch_is_pan_secured) { + /* Set security level, key id and index */ + packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, TSCH_SECURITY_KEY_SEC_LEVEL_EB); + packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, FRAME802154_1_BYTE_KEY_ID_MODE); /* Use 1-byte key index */ + packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, TSCH_SECURITY_KEY_INDEX_EB); + } +#endif /* LLSEC802154_ENABLED */ + eb_len = tsch_packet_create_eb(packetbuf_dataptr(), PACKETBUF_SIZE, + tsch_packet_seqno, &hdr_len, &tsch_sync_ie_offset); + if(eb_len != 0) { + struct tsch_packet *p; + packetbuf_set_datalen(eb_len); + /* Enqueue EB packet */ + if(!(p = tsch_queue_add_packet(&tsch_eb_address, NULL, NULL))) { + PRINTF("TSCH:! could not enqueue EB packet\n"); + } else { + PRINTF("TSCH: enqueue EB packet %u %u\n", eb_len, hdr_len); + p->tsch_sync_ie_offset = tsch_sync_ie_offset; + p->header_len = hdr_len; + } + } + } + } + if(tsch_current_eb_period > 0) { + /* Next EB transmission with a random delay + * within [tsch_current_eb_period*0.75, tsch_current_eb_period[ */ + delay = (tsch_current_eb_period - tsch_current_eb_period / 4) + + random_rand() % (tsch_current_eb_period / 4); + } else { + delay = TSCH_EB_PERIOD; + } + etimer_set(&eb_timer, delay); + PROCESS_WAIT_UNTIL(etimer_expired(&eb_timer)); + } + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +/* A process that is polled from interrupt and calls tx/rx input + * callbacks, outputs pending logs. */ +PROCESS_THREAD(tsch_pending_events_process, ev, data) +{ + PROCESS_BEGIN(); + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + tsch_rx_process_pending(); + tsch_tx_process_pending(); + tsch_log_process_pending(); + } + PROCESS_END(); +} + +/* Functions from the Contiki MAC layer driver interface */ + +/*---------------------------------------------------------------------------*/ +static void +tsch_init(void) +{ + radio_value_t radio_rx_mode; + radio_value_t radio_tx_mode; + rtimer_clock_t t; + + /* Radio Rx mode */ + if(NETSTACK_RADIO.get_value(RADIO_PARAM_RX_MODE, &radio_rx_mode) != RADIO_RESULT_OK) { + printf("TSCH:! radio does not support getting RADIO_PARAM_RX_MODE. Abort init.\n"); + return; + } + /* Disable radio in frame filtering */ + radio_rx_mode &= ~RADIO_RX_MODE_ADDRESS_FILTER; + /* Unset autoack */ + radio_rx_mode &= ~RADIO_RX_MODE_AUTOACK; + /* Set radio in poll mode */ + radio_rx_mode |= RADIO_RX_MODE_POLL_MODE; + if(NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE, radio_rx_mode) != RADIO_RESULT_OK) { + printf("TSCH:! radio does not support setting required RADIO_PARAM_RX_MODE. Abort init.\n"); + return; + } + + /* Radio Tx mode */ + if(NETSTACK_RADIO.get_value(RADIO_PARAM_TX_MODE, &radio_tx_mode) != RADIO_RESULT_OK) { + printf("TSCH:! radio does not support getting RADIO_PARAM_TX_MODE. Abort init.\n"); + return; + } + /* Unset CCA */ + radio_tx_mode &= ~RADIO_TX_MODE_SEND_ON_CCA; + if(NETSTACK_RADIO.set_value(RADIO_PARAM_TX_MODE, radio_tx_mode) != RADIO_RESULT_OK) { + printf("TSCH:! radio does not support setting required RADIO_PARAM_TX_MODE. Abort init.\n"); + return; + } + /* Test setting channel */ + if(NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, TSCH_DEFAULT_HOPPING_SEQUENCE[0]) != RADIO_RESULT_OK) { + printf("TSCH:! radio does not support setting channel. Abort init.\n"); + return; + } + /* Test getting timestamp */ + if(NETSTACK_RADIO.get_object(RADIO_PARAM_LAST_PACKET_TIMESTAMP, &t, sizeof(rtimer_clock_t)) != RADIO_RESULT_OK) { + printf("TSCH:! radio does not support getting last packet timestamp. Abort init.\n"); + return; + } + /* Check max hopping sequence length vs default sequence length */ + if(TSCH_HOPPING_SEQUENCE_MAX_LEN < sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE)) { + printf("TSCH:! TSCH_HOPPING_SEQUENCE_MAX_LEN < sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE). Abort init.\n"); + } + + /* Init TSCH sub-modules */ + tsch_reset(); + tsch_queue_init(); + tsch_schedule_init(); + tsch_log_init(); + ringbufindex_init(&input_ringbuf, TSCH_MAX_INCOMING_PACKETS); + ringbufindex_init(&dequeued_ringbuf, TSCH_DEQUEUED_ARRAY_SIZE); + + tsch_is_initialized = 1; + +#if TSCH_AUTOSTART + /* Start TSCH operation. + * If TSCH_AUTOSTART is not set, one needs to call NETSTACK_MAC.on() to start TSCH. */ + NETSTACK_MAC.on(); +#endif /* TSCH_AUTOSTART */ +} +/*---------------------------------------------------------------------------*/ +/* Function send for TSCH-MAC, puts the packet in packetbuf in the MAC queue */ +static void +send_packet(mac_callback_t sent, void *ptr) +{ + int ret = MAC_TX_DEFERRED; + int packet_count_before; + int hdr_len = 0; + const linkaddr_t *addr = packetbuf_addr(PACKETBUF_ADDR_RECEIVER); + + if(!tsch_is_associated) { + if(!tsch_is_initialized) { + PRINTF("TSCH:! not initialized (see earlier logs), drop outgoing packet\n"); + } else { + PRINTF("TSCH:! not associated, drop outgoing packet\n"); + } + ret = MAC_TX_ERR; + mac_call_sent_callback(sent, ptr, ret, 1); + return; + } + + /* PACKETBUF_ATTR_MAC_SEQNO cannot be zero, due to a pecuilarity + in framer-802154.c. */ + if(++tsch_packet_seqno == 0) { + tsch_packet_seqno++; + } + + /* Ask for ACK if we are sending anything other than broadcast */ + if(!linkaddr_cmp(addr, &linkaddr_null)) { + packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); + } else { + /* Broadcast packets shall be added to broadcast queue + * The broadcast address in Contiki is linkaddr_null which is equal + * to tsch_eb_address */ + addr = &tsch_broadcast_address; + } + + packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME); + packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, tsch_packet_seqno); + +#if LLSEC802154_ENABLED + if(tsch_is_pan_secured) { + /* Set security level, key id and index */ + packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, TSCH_SECURITY_KEY_SEC_LEVEL_OTHER); + packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, FRAME802154_1_BYTE_KEY_ID_MODE); /* Use 1-byte key index */ + packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, TSCH_SECURITY_KEY_INDEX_OTHER); + } +#endif /* LLSEC802154_ENABLED */ + + packet_count_before = tsch_queue_packet_count(addr); + + if((hdr_len = NETSTACK_FRAMER.create()) < 0) { + PRINTF("TSCH:! can't send packet due to framer error\n"); + ret = MAC_TX_ERR; + } else { + struct tsch_packet *p; + /* Enqueue packet */ + p = tsch_queue_add_packet(addr, sent, ptr); + if(p == NULL) { + PRINTF("TSCH:! can't send packet !tsch_queue_add_packet\n"); + ret = MAC_TX_ERR; + } else { + p->header_len = hdr_len; + PRINTF("TSCH: send packet to %u with seqno %u, queue %u %u, len %u %u\n", + TSCH_LOG_ID_FROM_LINKADDR(addr), tsch_packet_seqno, + packet_count_before, + tsch_queue_packet_count(addr), + p->header_len, + queuebuf_datalen(p->qb)); + (void)packet_count_before; /* Discard "variable set but unused" warning in case of TSCH_LOG_LEVEL of 0 */ + } + } + if(ret != MAC_TX_DEFERRED) { + mac_call_sent_callback(sent, ptr, ret, 1); + } +} +/*---------------------------------------------------------------------------*/ +static void +packet_input(void) +{ + int frame_parsed = 1; + + frame_parsed = NETSTACK_FRAMER.parse(); + + if(frame_parsed < 0) { + PRINTF("TSCH:! failed to parse %u\n", packetbuf_datalen()); + } else { + int duplicate = 0; + + /* Seqno of 0xffff means no seqno */ + if(packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO) != 0xffff) { + /* Check for duplicate packet by comparing the sequence number + of the incoming packet with the last few ones we saw. */ + int i; + for(i = 0; i < MAX_SEQNOS; ++i) { + if(packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO) == received_seqnos[i].seqno && + linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER), + &received_seqnos[i].sender)) { + /* Drop the packet. */ + PRINTF("TSCH:! drop dup ll from %u seqno %u\n", + TSCH_LOG_ID_FROM_LINKADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)), + packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO)); + duplicate = 1; + } + } + if(!duplicate) { + for(i = MAX_SEQNOS - 1; i > 0; --i) { + memcpy(&received_seqnos[i], &received_seqnos[i - 1], + sizeof(struct seqno)); + } + received_seqnos[0].seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO); + linkaddr_copy(&received_seqnos[0].sender, + packetbuf_addr(PACKETBUF_ADDR_SENDER)); + } + } + + if(!duplicate) { + PRINTF("TSCH: received from %u with seqno %u\n", + TSCH_LOG_ID_FROM_LINKADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)), + packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO)); + NETSTACK_LLSEC.input(); + } + } +} +/*---------------------------------------------------------------------------*/ +static int +turn_on(void) +{ + if(tsch_is_initialized == 1 && tsch_is_started == 0) { + tsch_is_started = 1; + /* Process tx/rx callback and log messages whenever polled */ + process_start(&tsch_pending_events_process, NULL); + /* periodically send TSCH EBs */ + process_start(&tsch_send_eb_process, NULL); + /* try to associate to a network or start one if setup as coordinator */ + process_start(&tsch_process, NULL); + PRINTF("TSCH: starting as %s\n", tsch_is_coordinator ? "coordinator" : "node"); + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +turn_off(int keep_radio_on) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +static unsigned short +channel_check_interval(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +const struct mac_driver tschmac_driver = { + "TSCH", + tsch_init, + send_packet, + packet_input, + turn_on, + turn_off, + channel_check_interval, +}; +/*---------------------------------------------------------------------------*/ diff --git a/core/net/mac/tsch/tsch.h b/core/net/mac/tsch/tsch.h new file mode 100644 index 000000000..d548df9d5 --- /dev/null +++ b/core/net/mac/tsch/tsch.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#ifndef __TSCH_H__ +#define __TSCH_H__ + +/********** Includes **********/ + +#include "contiki.h" +#include "net/mac/mac.h" +#include "net/mac/tsch/tsch-security.h" + +/******** Configuration *******/ + +/* Max time before sending a unicast keep-alive message to the time source */ +#ifdef TSCH_CONF_KEEPALIVE_TIMEOUT +#define TSCH_KEEPALIVE_TIMEOUT TSCH_CONF_KEEPALIVE_TIMEOUT +#else +/* Time to desynch assuming a drift of 40 PPM (80 PPM between two nodes) and guard time of +/-1ms: 12.5s. */ +#define TSCH_KEEPALIVE_TIMEOUT (12 * CLOCK_SECOND) +#endif + +/* Max time without synchronization before leaving the PAN */ +#ifdef TSCH_CONF_DESYNC_THRESHOLD +#define TSCH_DESYNC_THRESHOLD TSCH_CONF_DESYNC_THRESHOLD +#else +#define TSCH_DESYNC_THRESHOLD (4 * TSCH_KEEPALIVE_TIMEOUT) +#endif + +/* Period between two consecutive EBs */ +#ifdef TSCH_CONF_EB_PERIOD +#define TSCH_EB_PERIOD TSCH_CONF_EB_PERIOD +#else +#define TSCH_EB_PERIOD (4 * CLOCK_SECOND) +#endif + +/* Max acceptable join priority */ +#ifdef TSCH_CONF_MAX_JOIN_PRIORITY +#define TSCH_MAX_JOIN_PRIORITY TSCH_CONF_MAX_JOIN_PRIORITY +#else +#define TSCH_MAX_JOIN_PRIORITY 32 +#endif + +/* Start TSCH automatically after init? If not, the upper layers + * must call NETSTACK_MAC.on() to start it. Useful when the + * application needs to control when the nodes are to start + * scanning or advertising.*/ +#ifdef TSCH_CONF_AUTOSTART +#define TSCH_AUTOSTART TSCH_CONF_AUTOSTART +#else +#define TSCH_AUTOSTART 1 +#endif + +/* Join only secured networks? (discard EBs with security disabled) */ +#ifdef TSCH_CONF_JOIN_SECURED_ONLY +#define TSCH_JOIN_SECURED_ONLY TSCH_CONF_JOIN_SECURED_ONLY +#else +/* By default, set if LLSEC802154_ENABLED is also non-zero */ +#define TSCH_JOIN_SECURED_ONLY LLSEC802154_ENABLED +#endif + +/* By default, join any PAN ID. Otherwise, wait for an EB from IEEE802154_PANID */ +#ifdef TSCH_CONF_JOIN_MY_PANID_ONLY +#define TSCH_JOIN_MY_PANID_ONLY TSCH_CONF_JOIN_MY_PANID_ONLY +#else +#define TSCH_JOIN_MY_PANID_ONLY 0 +#endif + +/* The radio polling frequency (in Hz) during association process */ +#ifdef TSCH_CONF_ASSOCIATION_POLL_FREQUENCY +#define TSCH_ASSOCIATION_POLL_FREQUENCY TSCH_CONF_ASSOCIATION_POLL_FREQUENCY +#else +#define TSCH_ASSOCIATION_POLL_FREQUENCY 100 +#endif + +/* When associating, check ASN against our own uptime (time in minutes).. + * Useful to force joining only with nodes started roughly at the same time. + * Set to the max number of minutes acceptable. */ +#ifdef TSCH_CONF_CHECK_TIME_AT_ASSOCIATION +#define TSCH_CHECK_TIME_AT_ASSOCIATION TSCH_CONF_CHECK_TIME_AT_ASSOCIATION +#else +#define TSCH_CHECK_TIME_AT_ASSOCIATION 0 +#endif + +/* By default: initialize schedule from EB when associating, using the + * slotframe and links Information Element */ +#ifdef TSCH_CONF_INIT_SCHEDULE_FROM_EB +#define TSCH_INIT_SCHEDULE_FROM_EB TSCH_CONF_INIT_SCHEDULE_FROM_EB +#else +#define TSCH_INIT_SCHEDULE_FROM_EB 1 +#endif + +/* An ad-hoc mechanism to have TSCH select its time source without the + * help of an upper-layer, simply by collecting statistics on received + * EBs and their join priority. Disabled by default as we recomment + * mapping the time source on the RPL preferred parent + * (via tsch_rpl_callback_parent_switch) */ +#ifdef TSCH_CONF_AUTOSELECT_TIME_SOURCE +#define TSCH_AUTOSELECT_TIME_SOURCE TSCH_CONF_AUTOSELECT_TIME_SOURCE +#else +#define TSCH_AUTOSELECT_TIME_SOURCE 0 +#endif /* TSCH_CONF_EB_AUTOSELECT */ + +/*********** Callbacks *********/ + +/* Called by TSCH when joining a network */ +#ifdef TSCH_CALLBACK_JOINING_NETWORK +void TSCH_CALLBACK_JOINING_NETWORK(); +#endif + +/* Called by TSCH when leaving a network */ +#ifdef TSCH_CALLBACK_LEAVING_NETWORK +void TSCH_CALLBACK_LEAVING_NETWORK(); +#endif + +/***** External Variables *****/ + +/* Are we coordinator of the TSCH network? */ +extern int tsch_is_coordinator; +/* Are we associated to a TSCH network? */ +extern int tsch_is_associated; +/* Is the PAN running link-layer security? */ +extern int tsch_is_pan_secured; +/* The TSCH MAC driver */ +extern const struct mac_driver tschmac_driver; + +/********** Functions *********/ + +/* The the TSCH join priority */ +void tsch_set_join_priority(uint8_t jp); +/* The the period at which EBs are sent */ +void tsch_set_eb_period(uint32_t period); +/* Set the node as PAN coordinator */ +void tsch_set_coordinator(int enable); +/* Set the pan as secured or not */ +void tsch_set_pan_secured(int enable); + +#endif /* __TSCH_H__ */ diff --git a/core/net/nbr-table.c b/core/net/nbr-table.c index 4c9fab4fb..4893a99ca 100644 --- a/core/net/nbr-table.c +++ b/core/net/nbr-table.c @@ -40,6 +40,27 @@ #include "lib/list.h" #include "net/nbr-table.h" +#define DEBUG 0 +#if DEBUG +#include +#include "sys/ctimer.h" +static void handle_periodic_timer(void *ptr); +static struct ctimer periodic_timer; +static uint8_t initialized = 0; +static void print_table(); +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/* This is the callback function that will be called when there is a + * nbr-policy active + **/ +#ifdef NBR_TABLE_FIND_REMOVABLE +const linkaddr_t *NBR_TABLE_FIND_REMOVABLE(nbr_table_reason_t reason, void *data); +#endif /* NBR_TABLE_FIND_REMOVABLE */ + + /* List of link-layer addresses of the neighbors, used as key in the tables */ typedef struct nbr_table_key { struct nbr_table_key *next; @@ -143,6 +164,7 @@ static int nbr_set_bit(uint8_t *bitmap, nbr_table_t *table, nbr_table_item_t *item, int value) { int item_index = index_from_item(table, item); + if(table != NULL && item_index != -1) { if(value) { bitmap[item_index] |= 1 << table->index; @@ -156,8 +178,27 @@ nbr_set_bit(uint8_t *bitmap, nbr_table_t *table, nbr_table_item_t *item, int val return 0; } /*---------------------------------------------------------------------------*/ +static void +remove_key(nbr_table_key_t *least_used_key) +{ + int i; + for(i = 0; i < MAX_NUM_TABLES; i++) { + if(all_tables[i] != NULL && all_tables[i]->callback != NULL) { + /* Call table callback for each table that uses this item */ + nbr_table_item_t *removed_item = item_from_key(all_tables[i], least_used_key); + if(nbr_get_bit(used_map, all_tables[i], removed_item) == 1) { + all_tables[i]->callback(removed_item); + } + } + } + /* Empty used map */ + used_map[index_from_key(least_used_key)] = 0; + /* Remove neighbor from list */ + list_remove(nbr_table_keys, least_used_key); +} +/*---------------------------------------------------------------------------*/ static nbr_table_key_t * -nbr_table_allocate(void) +nbr_table_allocate(nbr_table_reason_t reason, void *data) { nbr_table_key_t *key; int least_used_count = 0; @@ -166,59 +207,72 @@ nbr_table_allocate(void) key = memb_alloc(&neighbor_addr_mem); if(key != NULL) { return key; - } else { /* No more space, try to free a neighbor. - * The replacement policy is the following: remove neighbor that is: - * (1) not locked - * (2) used by fewest tables - * (3) oldest (the list is ordered by insertion time) - * */ - /* Get item from first key */ - key = list_head(nbr_table_keys); - while(key != NULL) { - int item_index = index_from_key(key); - int locked = locked_map[item_index]; - /* Never delete a locked item */ - if(!locked) { - int used = used_map[item_index]; - int used_count = 0; - /* Count how many tables are using this item */ - while(used != 0) { - if((used & 1) == 1) { - used_count++; - } - used >>= 1; - } - /* Find least used item */ - if(least_used_key == NULL || used_count < least_used_count) { - least_used_key = key; - least_used_count = used_count; - if(used_count == 0) { /* We won't find any least used item */ - break; - } - } + } else { +#ifdef NBR_TABLE_FIND_REMOVABLE + const linkaddr_t *lladdr; + lladdr = NBR_TABLE_FIND_REMOVABLE(reason, data); + if(lladdr == NULL) { + /* Nothing found that can be deleted - return NULL to indicate failure */ + PRINTF("*** Not removing entry to allocate new\n"); + return NULL; + } else { + /* used least_used_key to indicate what is the least useful entry */ + int index; + int locked = 0; + if((index = index_from_lladdr(lladdr)) != -1) { + least_used_key = key_from_index(index); + locked = locked_map[index]; + } + /* Allow delete of locked item? */ + if(least_used_key != NULL && locked) { + PRINTF("Deleting locked item!\n"); + locked_map[index] = 0; } - key = list_item_next(key); } +#endif /* NBR_TABLE_FIND_REMOVABLE */ + + if(least_used_key == NULL) { + /* No more space, try to free a neighbor. + * The replacement policy is the following: remove neighbor that is: + * (1) not locked + * (2) used by fewest tables + * (3) oldest (the list is ordered by insertion time) + * */ + /* Get item from first key */ + key = list_head(nbr_table_keys); + while(key != NULL) { + int item_index = index_from_key(key); + int locked = locked_map[item_index]; + /* Never delete a locked item */ + if(!locked) { + int used = used_map[item_index]; + int used_count = 0; + /* Count how many tables are using this item */ + while(used != 0) { + if((used & 1) == 1) { + used_count++; + } + used >>= 1; + } + /* Find least used item */ + if(least_used_key == NULL || used_count < least_used_count) { + least_used_key = key; + least_used_count = used_count; + if(used_count == 0) { /* We won't find any least used item */ + break; + } + } + } + key = list_item_next(key); + } + } + if(least_used_key == NULL) { /* We haven't found any unlocked item, allocation fails */ return NULL; } else { /* Reuse least used item */ - int i; - for(i = 0; icallback != NULL) { - /* Call table callback for each table that uses this item */ - nbr_table_item_t *removed_item = item_from_key(all_tables[i], least_used_key); - if(nbr_get_bit(used_map, all_tables[i], removed_item) == 1) { - all_tables[i]->callback(removed_item); - } - } - } - /* Empty used map */ - used_map[index_from_key(least_used_key)] = 0; - /* Remove neighbor from list */ - list_remove(nbr_table_keys, least_used_key); - /* Return associated key */ + remove_key(least_used_key); return least_used_key; } } @@ -229,6 +283,13 @@ nbr_table_allocate(void) int nbr_table_register(nbr_table_t *table, nbr_table_callback *callback) { +#if DEBUG + if(!initialized) { + initialized = 1; + /* schedule a debug printout per minute */ + ctimer_set(&periodic_timer, CLOCK_SECOND * 60, handle_periodic_timer, NULL); + } +#endif if(num_tables < MAX_NUM_TABLES) { table->index = num_tables++; table->callback = callback; @@ -269,7 +330,7 @@ nbr_table_next(nbr_table_t *table, nbr_table_item_t *item) /*---------------------------------------------------------------------------*/ /* Add a neighbor indexed with its link-layer address */ nbr_table_item_t * -nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr) +nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr, nbr_table_reason_t reason, void *data) { int index; nbr_table_item_t *item; @@ -283,7 +344,7 @@ nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr) if((index = index_from_lladdr(lladdr)) == -1) { /* Neighbor not yet in table, let's try to allocate one */ - key = nbr_table_allocate(); + key = nbr_table_allocate(reason, data); /* No space available for new entry */ if(key == NULL) { @@ -307,6 +368,9 @@ nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr) memset(item, 0, table->item_size); nbr_set_bit(used_map, table, item, 1); +#if DEBUG + print_table(); +#endif return item; } /*---------------------------------------------------------------------------*/ @@ -331,6 +395,10 @@ nbr_table_remove(nbr_table_t *table, void *item) int nbr_table_lock(nbr_table_t *table, void *item) { +#if DEBUG + int i = index_from_item(table, item); + PRINTF("*** Lock %d\n", i); +#endif return nbr_set_bit(locked_map, table, item, 1); } /*---------------------------------------------------------------------------*/ @@ -338,6 +406,10 @@ nbr_table_lock(nbr_table_t *table, void *item) int nbr_table_unlock(nbr_table_t *table, void *item) { +#if DEBUG + int i = index_from_item(table, item); + PRINTF("*** Unlock %d\n", i); +#endif return nbr_set_bit(locked_map, table, item, 0); } /*---------------------------------------------------------------------------*/ @@ -348,3 +420,64 @@ nbr_table_get_lladdr(nbr_table_t *table, const void *item) nbr_table_key_t *key = key_from_item(table, item); return key != NULL ? &key->lladdr : NULL; } +/*---------------------------------------------------------------------------*/ +/* Update link-layer address of an item */ +int +nbr_table_update_lladdr(const linkaddr_t *old_addr, const linkaddr_t *new_addr, + int remove_if_duplicate) +{ + int index; + int new_index; + nbr_table_key_t *key; + index = index_from_lladdr(old_addr); + if(index == -1) { + /* Failure to change since there is nothing to change. */ + return 0; + } + if((new_index = index_from_lladdr(new_addr)) != -1) { + /* check if it is a change or not - do not remove / fail if same */ + if(new_index == index) { + return 1; + } + /* This new entry already exists - failure! - remove if requested. */ + if(remove_if_duplicate) { + remove_key(key_from_index(index)); + } + return 0; + } + key = key_from_index(index); + /** + * Copy the new lladdr into the key - since we know that there is no + * conflicting entry. + */ + memcpy(&key->lladdr, new_addr, sizeof(linkaddr_t)); + return 1; +} +/*---------------------------------------------------------------------------*/ +#if DEBUG +static void +print_table() +{ + int i, j; + /* Printout all neighbors and which tables they are used in */ + PRINTF("NBR TABLE:\n"); + for(i = 0; i < NBR_TABLE_MAX_NEIGHBORS; i++) { + if(used_map[i] > 0) { + PRINTF(" %02d %02d",i , key_from_index(i)->lladdr.u8[LINKADDR_SIZE - 1]); + for(j = 0; j < num_tables; j++) { + PRINTF(" [%d:%d]", (used_map[i] & (1 << j)) != 0, + (locked_map[i] & (1 << j)) != 0); + } + PRINTF("\n"); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +handle_periodic_timer(void *ptr) +{ + print_table(); + ctimer_reset(&periodic_timer); +} +#endif + diff --git a/core/net/nbr-table.h b/core/net/nbr-table.h index 516901fe3..320ef2e5f 100644 --- a/core/net/nbr-table.h +++ b/core/net/nbr-table.h @@ -75,6 +75,18 @@ typedef struct nbr_table { /** \brief Declaration of non-static neighbor tables */ #define NBR_TABLE_DECLARE(name) extern nbr_table_t *name +typedef enum { + NBR_TABLE_REASON_UNDEFINED, + NBR_TABLE_REASON_RPL_DIO, + NBR_TABLE_REASON_RPL_DAO, + NBR_TABLE_REASON_RPL_DIS, + NBR_TABLE_REASON_ROUTE, + NBR_TABLE_REASON_IPV6_ND, + NBR_TABLE_REASON_MAC, + NBR_TABLE_REASON_LLSEC, + NBR_TABLE_REASON_LINK_STATS, +} nbr_table_reason_t; + /** \name Neighbor tables: register and loop through table elements */ /** @{ */ int nbr_table_register(nbr_table_t *table, nbr_table_callback *callback); @@ -84,7 +96,7 @@ nbr_table_item_t *nbr_table_next(nbr_table_t *table, nbr_table_item_t *item); /** \name Neighbor tables: add and get data */ /** @{ */ -nbr_table_item_t *nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr); +nbr_table_item_t *nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr, nbr_table_reason_t reason, void *data); nbr_table_item_t *nbr_table_get_from_lladdr(nbr_table_t *table, const linkaddr_t *lladdr); /** @} */ @@ -98,6 +110,7 @@ int nbr_table_unlock(nbr_table_t *table, nbr_table_item_t *item); /** \name Neighbor tables: address manipulation */ /** @{ */ linkaddr_t *nbr_table_get_lladdr(nbr_table_t *table, const nbr_table_item_t *item); +int nbr_table_update_lladdr(const linkaddr_t *old_addr, const linkaddr_t *new_addr, int remove_if_duplicate); /** @} */ #endif /* NBR_TABLE_H_ */ diff --git a/core/net/net-debug.c b/core/net/net-debug.c new file mode 100644 index 000000000..8dd630666 --- /dev/null +++ b/core/net/net-debug.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file + * A set of debugging tools for the IP stack + * \author + * Nicolas Tsiftes + * Niclas Finne + * Joakim Eriksson + * Simon Duquennoy + */ + +#include "net/net-debug.h" + +/*---------------------------------------------------------------------------*/ +void +net_debug_lladdr_print(const uip_lladdr_t *addr) +{ + if(addr == NULL) { + PRINTA("(NULL LL addr)"); + return; + } else { +#if NETSTACK_CONF_WITH_RIME + /* Rime uses traditionally a %u.%u format */ + PRINTA("%u.%u", addr->addr[0], addr->addr[1]); +#else /* NETSTACK_CONF_WITH_RIME */ + unsigned int i; + for(i = 0; i < LINKADDR_SIZE; i++) { + if(i > 0) { + PRINTA(":"); + } + PRINTA("%02x", addr->addr[i]); + } +#endif /* NETSTACK_CONF_WITH_RIME */ + } +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/net-debug.h b/core/net/net-debug.h new file mode 100644 index 000000000..a4c6a3313 --- /dev/null +++ b/core/net/net-debug.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/** + * \file + * A set of debugging macros for the netstack + * + * \author Nicolas Tsiftes + * Niclas Finne + * Joakim Eriksson + * Simon Duquennoy + */ + +#ifndef NET_DEBUG_H +#define NET_DEBUG_H + +#include "net/ip/uip.h" +#include "net/linkaddr.h" +#include + +void net_debug_lladdr_print(const uip_lladdr_t *addr); + +#define DEBUG_NONE 0 +#define DEBUG_PRINT 1 +#define DEBUG_ANNOTATE 2 +#define DEBUG_FULL DEBUG_ANNOTATE | DEBUG_PRINT + +/* PRINTA will always print if the debug routines are called directly */ +#ifdef __AVR__ +#include +#define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTA(...) printf(__VA_ARGS__) +#endif + +#if (DEBUG) & DEBUG_ANNOTATE +#ifdef __AVR__ +#define ANNOTATE(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define ANNOTATE(...) printf(__VA_ARGS__) +#endif +#else +#define ANNOTATE(...) +#endif /* (DEBUG) & DEBUG_ANNOTATE */ + +#if (DEBUG) & DEBUG_PRINT +#ifdef __AVR__ +#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTF(...) printf(__VA_ARGS__) +#endif +#define PRINTLLADDR(lladdr) net_debug_lladdr_print(lladdr) +#else +#define PRINTF(...) +#define PRINTLLADDR(lladdr) +#endif /* (DEBUG) & DEBUG_PRINT */ + +#endif /* NET_DEBUG_H */ diff --git a/core/net/netstack.c b/core/net/netstack.c index c7dc8336c..e13184c19 100644 --- a/core/net/netstack.c +++ b/core/net/netstack.c @@ -44,11 +44,8 @@ netstack_init(void) { NETSTACK_RADIO.init(); NETSTACK_RDC.init(); + NETSTACK_LLSEC.init(); NETSTACK_MAC.init(); NETSTACK_NETWORK.init(); - -#ifdef NETSTACK_ENCRYPTION_INIT - NETSTACK_ENCRYPTION_INIT(); -#endif /* NETSTACK_ENCRYPTION_INIT */ } /*---------------------------------------------------------------------------*/ diff --git a/core/net/netstack.h b/core/net/netstack.h index aa5f7be1e..4bb252c8f 100644 --- a/core/net/netstack.h +++ b/core/net/netstack.h @@ -28,6 +28,7 @@ * * This file is part of the Contiki operating system. * + * $Id: netstack.h,v 1.6 2010/10/03 20:37:32 adamdunkels Exp $ */ /** @@ -50,6 +51,14 @@ #endif /* NETSTACK_CONF_NETWORK */ #endif /* NETSTACK_NETWORK */ +#ifndef NETSTACK_LLSEC +#ifdef NETSTACK_CONF_LLSEC +#define NETSTACK_LLSEC NETSTACK_CONF_LLSEC +#else /* NETSTACK_CONF_LLSEC */ +#define NETSTACK_LLSEC nullsec_driver +#endif /* NETSTACK_CONF_LLSEC */ +#endif /* NETSTACK_LLSEC */ + #ifndef NETSTACK_MAC #ifdef NETSTACK_CONF_MAC #define NETSTACK_MAC NETSTACK_CONF_MAC @@ -96,6 +105,7 @@ #endif /* NETSTACK_CONF_FRAMER */ #endif /* NETSTACK_FRAMER */ +#include "net/llsec/llsec.h" #include "net/mac/mac.h" #include "net/mac/rdc.h" #include "net/mac/framer.h" @@ -115,6 +125,7 @@ struct network_driver { }; extern const struct network_driver NETSTACK_NETWORK; +extern const struct llsec_driver NETSTACK_LLSEC; extern const struct rdc_driver NETSTACK_RDC; extern const struct mac_driver NETSTACK_MAC; extern const struct radio_driver NETSTACK_RADIO; diff --git a/core/net/packetbuf.c b/core/net/packetbuf.c index 94e8a4966..4869263cf 100644 --- a/core/net/packetbuf.c +++ b/core/net/packetbuf.c @@ -1,8 +1,3 @@ -/** - * \addtogroup packetbuf - * @{ - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -42,28 +37,32 @@ * Adam Dunkels */ +/** + * \addtogroup packetbuf + * @{ + */ + #include #include "contiki-net.h" #include "net/packetbuf.h" #include "net/rime/rime.h" +#include "sys/cc.h" struct packetbuf_attr packetbuf_attrs[PACKETBUF_NUM_ATTRS]; struct packetbuf_addr packetbuf_addrs[PACKETBUF_NUM_ADDRS]; static uint16_t buflen, bufptr; -static uint8_t hdrptr; +static uint8_t hdrlen; /* The declarations below ensure that the packet buffer is aligned on - an even 16-bit boundary. On some platforms (most notably the - msp430), having apotentially misaligned packet buffer may lead to - problems when accessing 16-bit values. */ -static uint16_t packetbuf_aligned[(PACKETBUF_SIZE + PACKETBUF_HDR_SIZE) / 2 + 1]; + an even 32-bit boundary. On some platforms (most notably the + msp430 or OpenRISC), having a potentially misaligned packet buffer may lead to + problems when accessing words. */ +static uint32_t packetbuf_aligned[(PACKETBUF_SIZE + 3) / 4]; static uint8_t *packetbuf = (uint8_t *)packetbuf_aligned; -static uint8_t *packetbufptr; - #define DEBUG 0 #if DEBUG #include @@ -77,26 +76,19 @@ void packetbuf_clear(void) { buflen = bufptr = 0; - hdrptr = PACKETBUF_HDR_SIZE; + hdrlen = 0; - packetbufptr = &packetbuf[PACKETBUF_HDR_SIZE]; packetbuf_attr_clear(); } /*---------------------------------------------------------------------------*/ -void -packetbuf_clear_hdr(void) -{ - hdrptr = PACKETBUF_HDR_SIZE; -} -/*---------------------------------------------------------------------------*/ int packetbuf_copyfrom(const void *from, uint16_t len) { uint16_t l; packetbuf_clear(); - l = len > PACKETBUF_SIZE? PACKETBUF_SIZE: len; - memcpy(packetbufptr, from, l); + l = MIN(PACKETBUF_SIZE, len); + memcpy(packetbuf, from, l); buflen = l; return l; } @@ -104,84 +96,43 @@ packetbuf_copyfrom(const void *from, uint16_t len) void packetbuf_compact(void) { - int i, len; + int16_t i; - if(packetbuf_is_reference()) { - memcpy(&packetbuf[PACKETBUF_HDR_SIZE], packetbuf_reference_ptr(), - packetbuf_datalen()); - } else if(bufptr > 0) { - len = packetbuf_datalen() + PACKETBUF_HDR_SIZE; - for(i = PACKETBUF_HDR_SIZE; i < len; i++) { - packetbuf[i] = packetbuf[bufptr + i]; + if(bufptr) { + /* shift data to the left */ + for(i = 0; i < buflen; i++) { + packetbuf[hdrlen + i] = packetbuf[packetbuf_hdrlen() + i]; } - bufptr = 0; } } /*---------------------------------------------------------------------------*/ int -packetbuf_copyto_hdr(uint8_t *to) -{ -#if DEBUG_LEVEL > 0 - { - int i; - PRINTF("packetbuf_write_hdr: header:\n"); - for(i = hdrptr; i < PACKETBUF_HDR_SIZE; ++i) { - PRINTF("0x%02x, ", packetbuf[i]); - } - PRINTF("\n"); - } -#endif /* DEBUG_LEVEL */ - memcpy(to, packetbuf + hdrptr, PACKETBUF_HDR_SIZE - hdrptr); - return PACKETBUF_HDR_SIZE - hdrptr; -} -/*---------------------------------------------------------------------------*/ -int packetbuf_copyto(void *to) { -#if DEBUG_LEVEL > 0 - { - int i; - char buffer[1000]; - char *bufferptr = buffer; - - bufferptr[0] = 0; - for(i = hdrptr; i < PACKETBUF_HDR_SIZE; ++i) { - bufferptr += sprintf(bufferptr, "0x%02x, ", packetbuf[i]); - } - PRINTF("packetbuf_write: header: %s\n", buffer); - bufferptr = buffer; - bufferptr[0] = 0; - for(i = bufptr; i < buflen + bufptr; ++i) { - bufferptr += sprintf(bufferptr, "0x%02x, ", packetbufptr[i]); - } - PRINTF("packetbuf_write: data: %s\n", buffer); - } -#endif /* DEBUG_LEVEL */ - if(PACKETBUF_HDR_SIZE - hdrptr + buflen > PACKETBUF_SIZE) { - /* Too large packet */ + if(hdrlen + buflen > PACKETBUF_SIZE) { return 0; } - memcpy(to, packetbuf + hdrptr, PACKETBUF_HDR_SIZE - hdrptr); - memcpy((uint8_t *)to + PACKETBUF_HDR_SIZE - hdrptr, packetbufptr + bufptr, - buflen); - return PACKETBUF_HDR_SIZE - hdrptr + buflen; + memcpy(to, packetbuf_hdrptr(), hdrlen); + memcpy((uint8_t *)to + hdrlen, packetbuf_dataptr(), buflen); + return hdrlen + buflen; } /*---------------------------------------------------------------------------*/ int packetbuf_hdralloc(int size) { - if(hdrptr >= size && packetbuf_totlen() + size <= PACKETBUF_SIZE) { - hdrptr -= size; - return 1; + int16_t i; + + if(size + packetbuf_totlen() > PACKETBUF_SIZE) { + return 0; } - return 0; -} -/*---------------------------------------------------------------------------*/ -void -packetbuf_hdr_remove(int size) -{ - hdrptr += size; + + /* shift data to the right */ + for(i = packetbuf_totlen() - 1; i >= 0; i--) { + packetbuf[i + size] = packetbuf[i]; + } + hdrlen += size; + return 1; } /*---------------------------------------------------------------------------*/ int @@ -206,33 +157,13 @@ packetbuf_set_datalen(uint16_t len) void * packetbuf_dataptr(void) { - return (void *)(&packetbuf[bufptr + PACKETBUF_HDR_SIZE]); + return packetbuf + packetbuf_hdrlen(); } /*---------------------------------------------------------------------------*/ void * packetbuf_hdrptr(void) { - return (void *)(&packetbuf[hdrptr]); -} -/*---------------------------------------------------------------------------*/ -void -packetbuf_reference(void *ptr, uint16_t len) -{ - packetbuf_clear(); - packetbufptr = ptr; - buflen = len; -} -/*---------------------------------------------------------------------------*/ -int -packetbuf_is_reference(void) -{ - return packetbufptr != &packetbuf[PACKETBUF_HDR_SIZE]; -} -/*---------------------------------------------------------------------------*/ -void * -packetbuf_reference_ptr(void) -{ - return packetbufptr; + return packetbuf; } /*---------------------------------------------------------------------------*/ uint16_t @@ -244,7 +175,7 @@ packetbuf_datalen(void) uint8_t packetbuf_hdrlen(void) { - return PACKETBUF_HDR_SIZE - hdrptr; + return bufptr + hdrlen; } /*---------------------------------------------------------------------------*/ uint16_t @@ -257,9 +188,7 @@ void packetbuf_attr_clear(void) { int i; - for(i = 0; i < PACKETBUF_NUM_ATTRS; ++i) { - packetbuf_attrs[i].val = 0; - } + memset(packetbuf_attrs, 0, sizeof(packetbuf_attrs)); for(i = 0; i < PACKETBUF_NUM_ADDRS; ++i) { linkaddr_copy(&packetbuf_addrs[i].addr, &linkaddr_null); } @@ -285,7 +214,6 @@ packetbuf_attr_copyfrom(struct packetbuf_attr *attrs, int packetbuf_set_attr(uint8_t type, const packetbuf_attr_t val) { -/* packetbuf_attrs[type].type = type; */ packetbuf_attrs[type].val = val; return 1; } @@ -299,7 +227,6 @@ packetbuf_attr(uint8_t type) int packetbuf_set_addr(uint8_t type, const linkaddr_t *addr) { -/* packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].type = type; */ linkaddr_copy(&packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].addr, addr); return 1; } @@ -311,4 +238,11 @@ packetbuf_addr(uint8_t type) } /*---------------------------------------------------------------------------*/ #endif /* PACKETBUF_CONF_ATTRS_INLINE */ +int +packetbuf_holds_broadcast(void) +{ + return linkaddr_cmp(&packetbuf_addrs[PACKETBUF_ADDR_RECEIVER - PACKETBUF_ADDR_FIRST].addr, &linkaddr_null); +} +/*---------------------------------------------------------------------------*/ + /** @} */ diff --git a/core/net/packetbuf.h b/core/net/packetbuf.h index fe2c1dae3..6f5d4b740 100644 --- a/core/net/packetbuf.h +++ b/core/net/packetbuf.h @@ -1,15 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup packetbuf Rime buffer management - * @{ - * - * The packetbuf module does Rime's buffer management. - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -49,11 +37,25 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup packetbuf Rime buffer management + * @{ + * + * The packetbuf module does Rime's buffer management. + */ + #ifndef PACKETBUF_H_ #define PACKETBUF_H_ #include "contiki-conf.h" #include "net/linkaddr.h" +#include "net/llsec/llsec802154.h" +#include "net/mac/tsch/tsch-conf.h" /** * \brief The size of the packetbuf, in bytes @@ -64,13 +66,10 @@ #define PACKETBUF_SIZE 128 #endif -/** - * \brief The size of the packetbuf header, in bytes - */ -#ifdef PACKETBUF_CONF_HDR_SIZE -#define PACKETBUF_HDR_SIZE PACKETBUF_CONF_HDR_SIZE +#ifdef PACKETBUF_CONF_WITH_PACKET_TYPE +#define PACKETBUF_WITH_PACKET_TYPE PACKETBUF_CONF_WITH_PACKET_TYPE #else -#define PACKETBUF_HDR_SIZE 48 +#define PACKETBUF_WITH_PACKET_TYPE NETSTACK_CONF_WITH_RIME #endif /** @@ -84,21 +83,6 @@ */ void packetbuf_clear(void); -/** - * \brief Clear and reset the header of the packetbuf - * - * This function clears the header of the packetbuf and - * resets all the internal state pointers pertaining to - * the header (header size, header pointer, but not - * external data pointer). It is used before after sending - * a packet in the packetbuf, to be able to reuse the - * packet buffer for a later retransmission. - * - */ -void packetbuf_clear_hdr(void); - -void packetbuf_hdr_remove(int bytes); - /** * \brief Get a pointer to the data in the packetbuf * \return Pointer to the packetbuf data @@ -107,15 +91,6 @@ void packetbuf_hdr_remove(int bytes); * the packetbuf. The data is either stored in the packetbuf, * or referenced to an external location. * - * For outbound packets, the packetbuf consists of two - * parts: header and data. The header is accessed with the - * packetbuf_hdrptr() function. - * - * For incoming packets, both the packet header and the - * packet data is stored in the data portion of the - * packetbuf. Thus this function is used to get a pointer to - * the header for incoming packets. - * */ void *packetbuf_dataptr(void); @@ -123,24 +98,13 @@ void *packetbuf_dataptr(void); * \brief Get a pointer to the header in the packetbuf, for outbound packets * \return Pointer to the packetbuf header * - * For outbound packets, the packetbuf consists of two - * parts: header and data. This function is used to get a - * pointer to the header in the packetbuf. The header is - * stored in the packetbuf. - * */ void *packetbuf_hdrptr(void); /** - * \brief Get the length of the header in the packetbuf, for outbound packets + * \brief Get the length of the header in the packetbuf * \return Length of the header in the packetbuf * - * For outbound packets, the packetbuf consists of two - * parts: header and data. This function is used to get - * the length of the header in the packetbuf. The header is - * stored in the packetbuf and accessed via the - * packetbuf_hdrptr() function. - * */ uint8_t packetbuf_hdrlen(void); @@ -149,17 +113,6 @@ uint8_t packetbuf_hdrlen(void); * \brief Get the length of the data in the packetbuf * \return Length of the data in the packetbuf * - * For outbound packets, the packetbuf consists of two - * parts: header and data. This function is used to get - * the length of the data in the packetbuf. The data is - * stored in the packetbuf and accessed via the - * packetbuf_dataptr() function. - * - * For incoming packets, both the packet header and the - * packet data is stored in the data portion of the - * packetbuf. This function is then used to get the total - * length of the packet - both header and data. - * */ uint16_t packetbuf_datalen(void); @@ -173,59 +126,15 @@ uint16_t packetbuf_totlen(void); /** * \brief Set the length of the data in the packetbuf * \param len The length of the data - * - * For outbound packets, the packetbuf consists of two - * parts: header and data. This function is used to set - * the length of the data in the packetbuf. */ void packetbuf_set_datalen(uint16_t len); -/** - * \brief Point the packetbuf to external data - * \param ptr A pointer to the external data - * \param len The length of the external data - * - * For outbound packets, the packetbuf consists of two - * parts: header and data. This function is used to make - * the packetbuf point to external data. The function also - * specifies the length of the external data that the - * packetbuf references. - */ -void packetbuf_reference(void *ptr, uint16_t len); - -/** - * \brief Check if the packetbuf references external data - * \retval Non-zero if the packetbuf references external data, zero otherwise. - * - * For outbound packets, the packetbuf consists of two - * parts: header and data. This function is used to check - * if the packetbuf points to external data that has - * previously been referenced with packetbuf_reference(). - * - */ -int packetbuf_is_reference(void); - -/** - * \brief Get a pointer to external data referenced by the packetbuf - * \retval A pointer to the external data - * - * For outbound packets, the packetbuf consists of two - * parts: header and data. The data may point to external - * data that has previously been referenced with - * packetbuf_reference(). This function is used to get a - * pointer to the external data. - * - */ -void *packetbuf_reference_ptr(void); - /** * \brief Compact the packetbuf * * This function compacts the packetbuf by copying the data * portion of the packetbuf so that becomes consecutive to - * the header. It also copies external data that has - * previously been referenced with packetbuf_reference() - * into the packetbuf. + * the header. * * This function is called by the Rime code before a * packet is to be sent by a device driver. This assures @@ -256,35 +165,17 @@ int packetbuf_copyfrom(const void *from, uint16_t len); * * This function copies the packetbuf to an external * buffer. Both the data portion and the header portion of - * the packetbuf is copied. If the packetbuf referenced - * external data (referenced with packetbuf_reference()) the - * external data is copied. + * the packetbuf is copied. * * The external buffer to which the packetbuf is to be * copied must be able to accomodate at least - * (PACKETBUF_SIZE + PACKETBUF_HDR_SIZE) bytes. The number of + * PACKETBUF_SIZE bytes. The number of * bytes that was copied to the external buffer is * returned. * */ int packetbuf_copyto(void *to); -/** - * \brief Copy the header portion of the packetbuf to an external buffer - * \param to A pointer to the buffer to which the data is to be copied - * \retval The number of bytes that was copied to the external buffer - * - * This function copies the header portion of the packetbuf - * to an external buffer. - * - * The external buffer to which the packetbuf is to be - * copied must be able to accomodate at least - * PACKETBUF_HDR_SIZE bytes. The number of bytes that was - * copied to the external buffer is returned. - * - */ -int packetbuf_copyto_hdr(uint8_t *to); - /** * \brief Extend the header of the packetbuf, for outbound packets * \param size The number of bytes the header should be extended @@ -318,11 +209,9 @@ int packetbuf_hdrreduce(int size); typedef uint16_t packetbuf_attr_t; struct packetbuf_attr { -/* uint8_t type; */ packetbuf_attr_t val; }; struct packetbuf_addr { -/* uint8_t type; */ linkaddr_t addr; }; @@ -347,33 +236,63 @@ enum { PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, PACKETBUF_ATTR_MAC_SEQNO, PACKETBUF_ATTR_MAC_ACK, - + PACKETBUF_ATTR_IS_CREATED_AND_SECURED, +#if TSCH_WITH_LINK_SELECTOR + PACKETBUF_ATTR_TSCH_SLOTFRAME, + PACKETBUF_ATTR_TSCH_TIMESLOT, +#endif /* TSCH_WITH_LINK_SELECTOR */ + /* Scope 1 attributes: used between two neighbors only. */ - PACKETBUF_ATTR_RELIABLE, - PACKETBUF_ATTR_PACKET_ID, +#if PACKETBUF_WITH_PACKET_TYPE PACKETBUF_ATTR_PACKET_TYPE, +#endif +#if NETSTACK_CONF_WITH_RIME + PACKETBUF_ATTR_PACKET_ID, + PACKETBUF_ATTR_RELIABLE, PACKETBUF_ATTR_REXMIT, PACKETBUF_ATTR_MAX_REXMIT, PACKETBUF_ATTR_NUM_REXMIT, +#endif /* NETSTACK_CONF_WITH_RIME */ PACKETBUF_ATTR_PENDING, + PACKETBUF_ATTR_FRAME_TYPE, +#if LLSEC802154_USES_AUX_HEADER + PACKETBUF_ATTR_SECURITY_LEVEL, +#endif /* LLSEC802154_USES_AUX_HEADER */ +#if LLSEC802154_USES_FRAME_COUNTER + PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, + PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, +#endif /* LLSEC802154_USES_FRAME_COUNTER */ +#if LLSEC802154_USES_EXPLICIT_KEYS + PACKETBUF_ATTR_KEY_ID_MODE, + PACKETBUF_ATTR_KEY_INDEX, + PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1, +#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ /* Scope 2 attributes: used between end-to-end nodes. */ +#if NETSTACK_CONF_WITH_RIME PACKETBUF_ATTR_HOPS, PACKETBUF_ATTR_TTL, PACKETBUF_ATTR_EPACKET_ID, PACKETBUF_ATTR_EPACKET_TYPE, PACKETBUF_ATTR_ERELIABLE, +#endif /* NETSTACK_CONF_WITH_RIME */ /* These must be last */ PACKETBUF_ADDR_SENDER, PACKETBUF_ADDR_RECEIVER, +#if NETSTACK_CONF_WITH_RIME PACKETBUF_ADDR_ESENDER, PACKETBUF_ADDR_ERECEIVER, - +#endif /* NETSTACK_CONF_WITH_RIME */ + PACKETBUF_ATTR_MAX }; +#if NETSTACK_CONF_WITH_RIME #define PACKETBUF_NUM_ADDRS 4 +#else /* NETSTACK_CONF_WITH_RIME */ +#define PACKETBUF_NUM_ADDRS 2 +#endif /* NETSTACK_CONF_WITH_RIME */ #define PACKETBUF_NUM_ATTRS (PACKETBUF_ATTR_MAX - PACKETBUF_NUM_ADDRS) #define PACKETBUF_ADDR_FIRST PACKETBUF_ADDR_SENDER @@ -384,15 +303,9 @@ enum { extern struct packetbuf_attr packetbuf_attrs[]; extern struct packetbuf_addr packetbuf_addrs[]; -static int packetbuf_set_attr(uint8_t type, const packetbuf_attr_t val); -static packetbuf_attr_t packetbuf_attr(uint8_t type); -static int packetbuf_set_addr(uint8_t type, const linkaddr_t *addr); -static const linkaddr_t *packetbuf_addr(uint8_t type); - static inline int packetbuf_set_attr(uint8_t type, const packetbuf_attr_t val) { -/* packetbuf_attrs[type].type = type; */ packetbuf_attrs[type].val = val; return 1; } @@ -405,7 +318,6 @@ packetbuf_attr(uint8_t type) static inline int packetbuf_set_addr(uint8_t type, const linkaddr_t *addr) { -/* packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].type = type; */ linkaddr_copy(&packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].addr, addr); return 1; } @@ -422,6 +334,12 @@ int packetbuf_set_addr(uint8_t type, const linkaddr_t *addr); const linkaddr_t *packetbuf_addr(uint8_t type); #endif /* PACKETBUF_CONF_ATTRS_INLINE */ +/** + * \brief Checks whether the current packet is a broadcast. + * \retval 0 iff current packet is not a broadcast + */ +int packetbuf_holds_broadcast(void); + void packetbuf_attr_clear(void); void packetbuf_attr_copyto(struct packetbuf_attr *attrs, @@ -434,7 +352,7 @@ void packetbuf_attr_copyfrom(struct packetbuf_attr *attrs, #define PACKETBUF_ATTR_BIT 1 #define PACKETBUF_ATTR_BYTE 8 -#define PACKETBUF_ADDRSIZE (sizeof(linkaddr_t) * PACKETBUF_ATTR_BYTE) +#define PACKETBUF_ADDRSIZE (LINKADDR_SIZE * PACKETBUF_ATTR_BYTE) struct packetbuf_attrlist { uint8_t type; diff --git a/core/net/queuebuf.c b/core/net/queuebuf.c index 8cb8708b3..8a9ebfe8a 100644 --- a/core/net/queuebuf.c +++ b/core/net/queuebuf.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rimequeuebuf - * @{ - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -42,19 +37,19 @@ * Adam Dunkels */ +/** + * \addtogroup rimequeuebuf + * @{ + */ + #include "contiki-net.h" + #if WITH_SWAP #include "cfs/cfs.h" #endif #include /* for memcpy() */ -#ifdef QUEUEBUF_CONF_REF_NUM -#define QUEUEBUF_REF_NUM QUEUEBUF_CONF_REF_NUM -#else -#define QUEUEBUF_REF_NUM 2 -#endif - /* Structure pointing to a buffer either stored in RAM or swapped in CFS */ struct queuebuf { @@ -77,21 +72,13 @@ struct queuebuf { /* The actual queuebuf data */ struct queuebuf_data { - uint16_t len; uint8_t data[PACKETBUF_SIZE]; + uint16_t len; struct packetbuf_attr attrs[PACKETBUF_NUM_ATTRS]; struct packetbuf_addr addrs[PACKETBUF_NUM_ADDRS]; }; -struct queuebuf_ref { - uint16_t len; - uint8_t *ref; - uint8_t hdr[PACKETBUF_HDR_SIZE]; - uint8_t hdrlen; -}; - MEMB(bufmem, struct queuebuf, QUEUEBUF_NUM); -MEMB(refbufmem, struct queuebuf_ref, QUEUEBUF_REF_NUM); MEMB(buframmem, struct queuebuf_data, QUEUEBUFRAM_NUM); #if WITH_SWAP @@ -144,7 +131,7 @@ LIST(queuebuf_list); #endif /* QUEUEBUF_CONF_STATS */ #if QUEUEBUF_STATS -uint8_t queuebuf_len, queuebuf_ref_len, queuebuf_max_len; +uint8_t queuebuf_len, queuebuf_max_len; #endif /* QUEUEBUF_STATS */ #if WITH_SWAP @@ -301,12 +288,17 @@ queuebuf_init(void) #endif memb_init(&buframmem); memb_init(&bufmem); - memb_init(&refbufmem); #if QUEUEBUF_STATS - queuebuf_max_len = QUEUEBUF_NUM; + queuebuf_max_len = 0; #endif /* QUEUEBUF_STATS */ } /*---------------------------------------------------------------------------*/ +int +queuebuf_numfree(void) +{ + return memb_numfree(&bufmem); +} +/*---------------------------------------------------------------------------*/ #if QUEUEBUF_DEBUG struct queuebuf * queuebuf_new_from_packetbuf_debug(const char *file, int line) @@ -316,80 +308,62 @@ queuebuf_new_from_packetbuf(void) #endif /* QUEUEBUF_DEBUG */ { struct queuebuf *buf; - struct queuebuf_ref *rbuf; - if(packetbuf_is_reference()) { - rbuf = memb_alloc(&refbufmem); - if(rbuf != NULL) { -#if QUEUEBUF_STATS - ++queuebuf_ref_len; -#endif /* QUEUEBUF_STATS */ - rbuf->len = packetbuf_datalen(); - rbuf->ref = packetbuf_reference_ptr(); - rbuf->hdrlen = packetbuf_copyto_hdr(rbuf->hdr); - } else { - PRINTF("queuebuf_new_from_packetbuf: could not allocate a reference queuebuf\n"); - } - return (struct queuebuf *)rbuf; - } else { - struct queuebuf_data *buframptr; - buf = memb_alloc(&bufmem); - if(buf != NULL) { + struct queuebuf_data *buframptr; + buf = memb_alloc(&bufmem); + if(buf != NULL) { #if QUEUEBUF_DEBUG - list_add(queuebuf_list, buf); - buf->file = file; - buf->line = line; - buf->time = clock_time(); + list_add(queuebuf_list, buf); + buf->file = file; + buf->line = line; + buf->time = clock_time(); #endif /* QUEUEBUF_DEBUG */ - buf->ram_ptr = memb_alloc(&buframmem); + buf->ram_ptr = memb_alloc(&buframmem); #if WITH_SWAP - /* If the allocation failed, store the qbuf in swap files */ - if(buf->ram_ptr != NULL) { - buf->location = IN_RAM; - buframptr = buf->ram_ptr; - } else { - buf->location = IN_CFS; - buf->swap_id = -1; - tmpdata_qbuf = buf; - buframptr = &tmpdata; - } + /* If the allocation failed, store the qbuf in swap files */ + if(buf->ram_ptr != NULL) { + buf->location = IN_RAM; + buframptr = buf->ram_ptr; + } else { + buf->location = IN_CFS; + buf->swap_id = -1; + tmpdata_qbuf = buf; + buframptr = &tmpdata; + } #else - if(buf->ram_ptr == NULL) { - PRINTF("queuebuf_new_from_packetbuf: could not queuebuf data\n"); + if(buf->ram_ptr == NULL) { + PRINTF("queuebuf_new_from_packetbuf: could not queuebuf data\n"); + memb_free(&bufmem, buf); + return NULL; + } + buframptr = buf->ram_ptr; +#endif + + buframptr->len = packetbuf_copyto(buframptr->data); + packetbuf_attr_copyto(buframptr->attrs, buframptr->addrs); + +#if WITH_SWAP + if(buf->location == IN_CFS) { + if(queuebuf_flush_tmpdata() == -1) { + /* We were unable to write the data in the swap */ + memb_free(&bufmem, buf); return NULL; } - buframptr = buf->ram_ptr; -#endif - - buframptr->len = packetbuf_copyto(buframptr->data); - packetbuf_attr_copyto(buframptr->attrs, buframptr->addrs); - -#if WITH_SWAP - if(buf->location == IN_CFS) { - if(queuebuf_flush_tmpdata() == -1) { - /* We were unable to write the data in the swap */ - memb_free(&bufmem, buf); - return NULL; - } - } + } #endif #if QUEUEBUF_STATS - ++queuebuf_len; - PRINTF("queuebuf len %d\n", queuebuf_len); - printf("#A q=%d\n", queuebuf_len); - if(queuebuf_len == queuebuf_max_len + 1) { - memb_free(&bufmem, buf); - queuebuf_len--; - return NULL; - } + ++queuebuf_len; + PRINTF("#A q=%d\n", queuebuf_len); + if(queuebuf_len > queuebuf_max_len) { + queuebuf_max_len = queuebuf_len; + } #endif /* QUEUEBUF_STATS */ - } else { - PRINTF("queuebuf_new_from_packetbuf: could not allocate a queuebuf\n"); - } - return buf; + } else { + PRINTF("queuebuf_new_from_packetbuf: could not allocate a queuebuf\n"); } + return buf; } /*---------------------------------------------------------------------------*/ void @@ -405,6 +379,19 @@ queuebuf_update_attr_from_packetbuf(struct queuebuf *buf) } /*---------------------------------------------------------------------------*/ void +queuebuf_update_from_packetbuf(struct queuebuf *buf) +{ + struct queuebuf_data *buframptr = queuebuf_load_to_ram(buf); + packetbuf_attr_copyto(buframptr->attrs, buframptr->addrs); + buframptr->len = packetbuf_copyto(buframptr->data); +#if WITH_SWAP + if(buf->location == IN_CFS) { + queuebuf_flush_tmpdata(); + } +#endif +} +/*---------------------------------------------------------------------------*/ +void queuebuf_free(struct queuebuf *buf) { if(memb_inmemb(&bufmem, buf)) { @@ -420,47 +407,30 @@ queuebuf_free(struct queuebuf *buf) memb_free(&bufmem, buf); #if QUEUEBUF_STATS --queuebuf_len; - printf("#A q=%d\n", queuebuf_len); + PRINTF("#A q=%d\n", queuebuf_len); #endif /* QUEUEBUF_STATS */ #if QUEUEBUF_DEBUG list_remove(queuebuf_list, buf); #endif /* QUEUEBUF_DEBUG */ - } else if(memb_inmemb(&refbufmem, buf)) { - memb_free(&refbufmem, buf); -#if QUEUEBUF_STATS - --queuebuf_ref_len; -#endif /* QUEUEBUF_STATS */ } } /*---------------------------------------------------------------------------*/ void queuebuf_to_packetbuf(struct queuebuf *b) { - struct queuebuf_ref *r; if(memb_inmemb(&bufmem, b)) { struct queuebuf_data *buframptr = queuebuf_load_to_ram(b); packetbuf_copyfrom(buframptr->data, buframptr->len); packetbuf_attr_copyfrom(buframptr->attrs, buframptr->addrs); - } else if(memb_inmemb(&refbufmem, b)) { - r = (struct queuebuf_ref *)b; - packetbuf_clear(); - packetbuf_copyfrom(r->ref, r->len); - packetbuf_hdralloc(r->hdrlen); - memcpy(packetbuf_hdrptr(), r->hdr, r->hdrlen); } } /*---------------------------------------------------------------------------*/ void * queuebuf_dataptr(struct queuebuf *b) { - struct queuebuf_ref *r; - if(memb_inmemb(&bufmem, b)) { struct queuebuf_data *buframptr = queuebuf_load_to_ram(b); return buframptr->data; - } else if(memb_inmemb(&refbufmem, b)) { - r = (struct queuebuf_ref *)b; - return r->ref; } return NULL; } diff --git a/core/net/queuebuf.h b/core/net/queuebuf.h index a1727342d..89e9aba29 100644 --- a/core/net/queuebuf.h +++ b/core/net/queuebuf.h @@ -1,16 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rimequeuebuf Rime queue buffer management - * @{ - * - * The queuebuf module handles buffers that are queued. - * - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -50,6 +37,19 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimequeuebuf Rime queue buffer management + * @{ + * + * The queuebuf module handles buffers that are queued. + * + */ + #ifndef QUEUEBUF_H_ #define QUEUEBUF_H_ @@ -96,6 +96,7 @@ struct queuebuf *queuebuf_new_from_packetbuf_debug(const char *file, int line); struct queuebuf *queuebuf_new_from_packetbuf(void); #endif /* QUEUEBUF_DEBUG */ void queuebuf_update_attr_from_packetbuf(struct queuebuf *b); +void queuebuf_update_from_packetbuf(struct queuebuf *b); void queuebuf_to_packetbuf(struct queuebuf *b); void queuebuf_free(struct queuebuf *b); @@ -108,7 +109,9 @@ packetbuf_attr_t queuebuf_attr(struct queuebuf *b, uint8_t type); void queuebuf_debug_print(void); -#endif /* QUEUEBUF_H_ */ +int queuebuf_numfree(void); + +#endif /* __QUEUEBUF_H__ */ /** @} */ /** @} */ diff --git a/core/net/rime/abc.c b/core/net/rime/abc.c index e0e40f0e1..338b6a045 100644 --- a/core/net/rime/abc.c +++ b/core/net/rime/abc.c @@ -1,9 +1,3 @@ -/** - * \addtogroup rimeabc - * @{ - */ - - /* * Copyright (c) 2004, Swedish Institute of Computer Science. * All rights reserved. @@ -45,6 +39,11 @@ * Adam Dunkels */ +/** + * \addtogroup rimeabc + * @{ + */ + #include "contiki-net.h" #include "net/rime/rime.h" diff --git a/core/net/rime/abc.h b/core/net/rime/abc.h index 19eebe053..b1f7f8f29 100644 --- a/core/net/rime/abc.h +++ b/core/net/rime/abc.h @@ -1,21 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rimeabc Anonymous best-effort local area broadcast - * @{ - * - * The abc module sends packets to all local area neighbors. The abc - * module adds no headers to outgoing packets. - * - * \section channels Channels - * - * The abc module uses 1 channel. - * - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -47,6 +29,7 @@ * This file is part of the Contiki operating system. * */ + /** * \file * Header file for the Rime module Anonymous BroadCast (abc) @@ -54,6 +37,24 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimeabc Anonymous best-effort local area broadcast + * @{ + * + * The abc module sends packets to all local area neighbors. The abc + * module adds no headers to outgoing packets. + * + * \section abc-channels Channels + * + * The abc module uses 1 channel. + * + */ + #ifndef ABC_H_ #define ABC_H_ diff --git a/core/net/rime/announcement.c b/core/net/rime/announcement.c index d4e4b57e2..f00c80649 100644 --- a/core/net/rime/announcement.c +++ b/core/net/rime/announcement.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rimeannouncement - * @{ - */ - /* * Copyright (c) 2008, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup rimeannouncement + * @{ + */ + #include "net/rime/announcement.h" #include "lib/list.h" #include "sys/cc.h" diff --git a/core/net/rime/announcement.h b/core/net/rime/announcement.h index e59d964f5..802d1da84 100644 --- a/core/net/rime/announcement.h +++ b/core/net/rime/announcement.h @@ -1,29 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rimeannouncement Announcements - * @{ - * - * The Announcement primitive does local area announcements. An - * announcement is an (ID, value) tuple that is disseminated to local - * area neighbors. An application or protocol can explicitly listen to - * announcements from neighbors. When an announcement is heard, a - * callback is invoked. - * - * Announcements can be used for a variety of network mechanisms such - * as neighbor discovery, node-level service discovery, or routing - * metric dissemination. - * - * Application programs and protocols register announcements with the - * announcement module. An announcement back-end, implemented by the - * system, takes care of sending out announcements over the radio, as - * well as collecting announcements heard from neighbors. - * - */ - /* * Copyright (c) 2008, Swedish Institute of Computer Science. * All rights reserved. @@ -63,6 +37,32 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimeannouncement Announcements + * @{ + * + * The Announcement primitive does local area announcements. An + * announcement is an (ID, value) tuple that is disseminated to local + * area neighbors. An application or protocol can explicitly listen to + * announcements from neighbors. When an announcement is heard, a + * callback is invoked. + * + * Announcements can be used for a variety of network mechanisms such + * as neighbor discovery, node-level service discovery, or routing + * metric dissemination. + * + * Application programs and protocols register announcements with the + * announcement module. An announcement back-end, implemented by the + * system, takes care of sending out announcements over the radio, as + * well as collecting announcements heard from neighbors. + * + */ + #ifndef ANNOUNCEMENT_H_ #define ANNOUNCEMENT_H_ @@ -131,6 +131,7 @@ void announcement_remove(struct announcement *a); * \brief Set the value of an announcement * \param a A pointer to a struct announcement that has * previously been registered + * \param value The new value * * This function sets the value of an announcement that * has previously been registered with diff --git a/core/net/rime/broadcast-announcement.c b/core/net/rime/broadcast-announcement.c index a728ce145..945d0a78d 100644 --- a/core/net/rime/broadcast-announcement.c +++ b/core/net/rime/broadcast-announcement.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rimeexamples - * @{ - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -35,6 +30,11 @@ * */ +/** + * \addtogroup rimebroadcastannouncement + * @{ + */ + /** * \file * An example announcement back-end, based on the broadcast primitive @@ -92,8 +92,6 @@ static struct broadcast_announcement_state { #define PRINTF(...) #endif -#define MIN(a, b) ((a)<(b)?(a):(b)) - /*---------------------------------------------------------------------------*/ static void send_adv(void *ptr) diff --git a/core/net/rime/broadcast-announcement.h b/core/net/rime/broadcast-announcement.h index 2e450b348..0cca9d85c 100644 --- a/core/net/rime/broadcast-announcement.h +++ b/core/net/rime/broadcast-announcement.h @@ -1,22 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rimebroadcastannouncement - * @{ - * - * The broadcast announcement module implements a periodic explicit - * announcement. THe module announces the announcements that have been - * registered with the \ref rimeannouncement "announcement module". - * - * \section channels Channels - * - * The broadcast announcement module uses 1 channel. - * - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -56,6 +37,25 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimebroadcastannouncement Broadcast announcement + * @{ + * + * The broadcast announcement module implements a periodic explicit + * announcement. THe module announces the announcements that have been + * registered with the \ref rimeannouncement "announcement module". + * + * \section bcast-announce-channels Channels + * + * The broadcast announcement module uses 1 channel. + * + */ + #ifndef BROADCAST_ANNOUNCEMENT_H_ #define BROADCAST_ANNOUNCEMENT_H_ diff --git a/core/net/rime/broadcast.c b/core/net/rime/broadcast.c index 463346dce..f4073fb7c 100644 --- a/core/net/rime/broadcast.c +++ b/core/net/rime/broadcast.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rimebroadcast - * @{ - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -35,6 +30,11 @@ * */ +/** + * \addtogroup rimeibc + * @{ + */ + /** * \file * Identified best-effort local area broadcast (broadcast) diff --git a/core/net/rime/broadcast.h b/core/net/rime/broadcast.h index eb264d46b..4a4c885d7 100644 --- a/core/net/rime/broadcast.h +++ b/core/net/rime/broadcast.h @@ -1,28 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rimeibc Best-effort local area broadcast - * @{ - * - * The broadcast module sends packets to all local area neighbors with an a - * header that identifies the sender. - * - * The broadcast module sends a packet to all local neighbors. The - * module adds the single-hop sender address as a packet attribute to - * outgoing packets. All Rime primitives that need the identity of - * the sender in the outgoing packets use the broadcast primitive, - * either directly or indirectly through any of the other - * communication primitives that are based on the broadcast primitive. - * - * \section channels Channels - * - * The broadcast module uses 1 channel. - * - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -62,6 +37,31 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimeibc Best-effort local area broadcast + * @{ + * + * The broadcast module sends packets to all local area neighbors with an a + * header that identifies the sender. + * + * The broadcast module sends a packet to all local neighbors. The + * module adds the single-hop sender address as a packet attribute to + * outgoing packets. All Rime primitives that need the identity of + * the sender in the outgoing packets use the broadcast primitive, + * either directly or indirectly through any of the other + * communication primitives that are based on the broadcast primitive. + * + * \section broadcast-channels Channels + * + * The broadcast module uses 1 channel. + * + */ + #ifndef BROADCAST_H_ #define BROADCAST_H_ diff --git a/core/net/rime/chameleon-bitopt.c b/core/net/rime/chameleon-bitopt.c index 151fde2b1..78bb58ebc 100644 --- a/core/net/rime/chameleon-bitopt.c +++ b/core/net/rime/chameleon-bitopt.c @@ -57,6 +57,8 @@ struct bitopt_hdr { uint8_t channel[2]; }; +#define BITOPT_HDR_SIZE 2 + static const uint8_t bitmask[9] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; @@ -69,7 +71,28 @@ static const uint8_t bitmask[9] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, #endif /*---------------------------------------------------------------------------*/ -uint8_t CC_INLINE +/* For get_bits/set_bits functions in this file to work correctly, + * the values contained in packetbuf_attr_t variables (uint16_t internally) + * must be in little endian byte order. + */ +/* Write little endian 16 bit value */ +static void CC_INLINE +le16_write(void *ptr, uint16_t v) +{ + uint8_t *p = (uint8_t *)ptr; + p[0] = v & 0xff; + p[1] = v >> 8; +} +/*---------------------------------------------------------------------------*/ +/* Read little endian 16 bit value */ +static uint16_t CC_INLINE +le16_read(const void *ptr) +{ + const uint8_t *p = (const uint8_t *)ptr; + return ((uint16_t)p[1] << 8) | p[0]; +} +/*---------------------------------------------------------------------------*/ +static uint8_t CC_INLINE get_bits_in_byte(uint8_t *from, int bitpos, int vallen) { uint16_t shifted_val; @@ -243,7 +266,7 @@ pack_header(struct channel *c) all attributes that are used on this channel. */ hdrbytesize = c->hdrsize / 8 + ((c->hdrsize & 7) == 0? 0: 1); - if(packetbuf_hdralloc(hdrbytesize + sizeof(struct bitopt_hdr)) == 0) { + if(packetbuf_hdralloc(hdrbytesize + BITOPT_HDR_SIZE) == 0) { PRINTF("chameleon-bitopt: insufficient space for headers\n"); return 0; } @@ -251,7 +274,7 @@ pack_header(struct channel *c) hdr->channel[0] = c->channelno & 0xff; hdr->channel[1] = (c->channelno >> 8) & 0xff; - hdrptr = ((uint8_t *)packetbuf_hdrptr()) + sizeof(struct bitopt_hdr); + hdrptr = ((uint8_t *)packetbuf_hdrptr()) + BITOPT_HDR_SIZE; memset(hdrptr, 0, hdrbytesize); byteptr = bitptr = 0; @@ -279,10 +302,10 @@ pack_header(struct channel *c) ((uint8_t *)packetbuf_addr(a->type))[0], ((uint8_t *)packetbuf_addr(a->type))[1]); } else { - packetbuf_attr_t val; - val = packetbuf_attr(a->type); - set_bits(&hdrptr[byteptr], bitptr & 7, - (uint8_t *)&val, len); + uint8_t buffer[2]; + packetbuf_attr_t val = packetbuf_attr(a->type); + le16_write(buffer, val); + set_bits(&hdrptr[byteptr], bitptr & 7, buffer, len); PRINTF("value %d\n", /*linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1],*/ val); @@ -309,7 +332,7 @@ unpack_header(void) /* The packet has a header that tells us what channel the packet is for. */ hdr = (struct bitopt_hdr *)packetbuf_dataptr(); - if(packetbuf_hdrreduce(sizeof(struct bitopt_hdr)) == 0) { + if(packetbuf_hdrreduce(BITOPT_HDR_SIZE) == 0) { PRINTF("chameleon-bitopt: too short packet\n"); return NULL; } @@ -349,9 +372,10 @@ unpack_header(void) a->type, addr.u8[0], addr.u8[1]); packetbuf_set_addr(a->type, &addr); } else { - packetbuf_attr_t val = 0; - get_bits((uint8_t *)&val, &hdrptr[byteptr], bitptr & 7, len); - + packetbuf_attr_t val; + uint8_t buffer[2] = {0}; + get_bits(buffer, &hdrptr[byteptr], bitptr & 7, len); + val = le16_read(buffer); packetbuf_set_attr(a->type, val); PRINTF("%d.%d: unpack_header type %d, val %d\n", linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1], diff --git a/core/net/rime/chameleon-raw.c b/core/net/rime/chameleon-raw.c old mode 100644 new mode 100755 index 8efcf8a1f..16b17fb5d --- a/core/net/rime/chameleon-raw.c +++ b/core/net/rime/chameleon-raw.c @@ -205,10 +205,7 @@ hdrsize(const struct packetbuf_attrlist *a) continue; } #endif /* CHAMELEON_WITH_MAC_LINK_ADDRESSES */ - len = a->len; - if(len < 8) { - len = 8; - } + len = (a->len & 0xf8) + ((a->len & 7) ? 8: 0); size += len; } return size / 8; diff --git a/core/net/rime/collect-link-estimate.c b/core/net/rime/collect-link-estimate.c index 92a722a58..4cf97cbf5 100644 --- a/core/net/rime/collect-link-estimate.c +++ b/core/net/rime/collect-link-estimate.c @@ -1,7 +1,3 @@ -/** - * \addtogroup rimelinkestimate - * @{ - */ /* * Copyright (c) 2010, Swedish Institute of Computer Science. * All rights reserved. @@ -41,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup rimelinkestimate + * @{ + */ + #include "net/rime/collect.h" #include "net/rime/collect-link-estimate.h" diff --git a/core/net/rime/collect-link-estimate.h b/core/net/rime/collect-link-estimate.h index c7b0cc73b..d833770e1 100644 --- a/core/net/rime/collect-link-estimate.h +++ b/core/net/rime/collect-link-estimate.h @@ -1,17 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ -/** - * \defgroup rimelinkestimate Link estimate management - * - * The link estimate module is used for computing estimations of link - * quality. It computes a quality index for links, based on - * information about how many times a packet has been transmitted, as - * well as information about incoming packets. The link estimate - * module exposes an interface that provides functions that are called - * for incoming and outgoing packets. - */ /* * Copyright (c) 2010, Swedish Institute of Computer Science. * All rights reserved. @@ -51,6 +37,22 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimelinkestimate Link estimate management + * + * The link estimate module is used for computing estimations of link + * quality. It computes a quality index for links, based on + * information about how many times a packet has been transmitted, as + * well as information about incoming packets. The link estimate + * module exposes an interface that provides functions that are called + * for incoming and outgoing packets. + */ + #ifndef COLLECT_LINK_ESTIMATE_H #define COLLECT_LINK_ESTIMATE_H diff --git a/core/net/rime/collect-neighbor.c b/core/net/rime/collect-neighbor.c index ecd5e2967..b033d3e05 100644 --- a/core/net/rime/collect-neighbor.c +++ b/core/net/rime/collect-neighbor.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rimecollect_neighbor - * @{ - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup rimeneighbor + * @{ + */ + #include #include diff --git a/core/net/rime/collect-neighbor.h b/core/net/rime/collect-neighbor.h index 056819325..804420a32 100644 --- a/core/net/rime/collect-neighbor.h +++ b/core/net/rime/collect-neighbor.h @@ -1,14 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ -/** - * \defgroup rimeneighbor Collect neighbor management - * @{ - * - * The neighbor module manages the neighbor table that is used by the - * Collect module. - */ /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -48,6 +37,19 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimeneighbor Collect neighbor management + * @{ + * + * The neighbor module manages the neighbor table that is used by the + * Collect module. + */ + #ifndef COLLECT_NEIGHBOR_H_ #define COLLECT_NEIGHBOR_H_ diff --git a/core/net/rime/collect.c b/core/net/rime/collect.c index 5cffa59f1..cdd2557c3 100644 --- a/core/net/rime/collect.c +++ b/core/net/rime/collect.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rimecollect - * @{ - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -42,14 +37,18 @@ * Adam Dunkels */ +/** + * \addtogroup rimecollect + * @{ + */ + #include "contiki.h" #include "net/netstack.h" #include "net/rime/rime.h" #include "net/rime/collect.h" #include "net/rime/collect-neighbor.h" #include "net/rime/collect-link-estimate.h" - -#include "net/packetqueue.h" +#include "net/rime/packetqueue.h" #include "dev/radio-sensor.h" @@ -951,14 +950,18 @@ node_packet_received(struct unicast_conn *c, const linkaddr_t *from) if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == PACKETBUF_ATTR_PACKET_TYPE_DATA) { linkaddr_t ack_to; +#if DEBUG uint8_t packet_seqno; +#endif stats.datarecv++; /* Remember to whom we should send the ACK, since we reuse the packet buffer and its attributes when sending the ACK. */ linkaddr_copy(&ack_to, packetbuf_addr(PACKETBUF_ADDR_SENDER)); +#if DEBUG packet_seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID); +#endif /* If the queue is more than half filled, we add the CONGESTED flag to our outgoing acks. */ diff --git a/core/net/rime/collect.h b/core/net/rime/collect.h index f9e21a129..d731a531b 100644 --- a/core/net/rime/collect.h +++ b/core/net/rime/collect.h @@ -1,22 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rimecollect Tree-based hop-by-hop reliable data collection - * @{ - * - * The collect module implements a hop-by-hop reliable data collection - * mechanism. - * - * \section channels Channels - * - * The collect module uses 2 channels; one for neighbor discovery and one - * for data packets. - * - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -56,6 +37,25 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimecollect Tree-based hop-by-hop reliable data collection + * @{ + * + * The collect module implements a hop-by-hop reliable data collection + * mechanism. + * + * \section collect-channels Channels + * + * The collect module uses 2 channels; one for neighbor discovery and one + * for data packets. + * + */ + #ifndef COLLECT_H_ #define COLLECT_H_ @@ -63,7 +63,7 @@ #include "net/rime/runicast.h" #include "net/rime/neighbor-discovery.h" #include "net/rime/collect-neighbor.h" -#include "net/packetqueue.h" +#include "net/rime/packetqueue.h" #include "sys/ctimer.h" #include "lib/list.h" diff --git a/core/net/rime/ipolite.c b/core/net/rime/ipolite.c index 0ea19b160..11fbd6b17 100644 --- a/core/net/rime/ipolite.c +++ b/core/net/rime/ipolite.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rimeipolite - * @{ - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -42,20 +37,18 @@ * Adam Dunkels */ +/** + * \addtogroup rimeipolite + * @{ + */ + +#include "sys/cc.h" #include "net/rime/rime.h" #include "net/rime/ipolite.h" #include "lib/random.h" #include -#ifndef MAX -#define MAX(a, b) ((a) > (b)? (a) : (b)) -#endif /* MAX */ - -#ifndef MIN -#define MIN(a, b) ((a) < (b)? (a) : (b)) -#endif /* MIN */ - #define DEBUG 0 #if DEBUG #include @@ -148,6 +141,8 @@ ipolite_send(struct ipolite_conn *c, clock_time_t interval, uint8_t hdrsize) PRINTF("%d.%d: ipolite_send: cancel old send\n", linkaddr_node_addr.u8[0],linkaddr_node_addr.u8[1]); queuebuf_free(c->q); + c->q = NULL; + ctimer_stop(&c->t); } c->dups = 0; c->hdrsize = hdrsize; diff --git a/core/net/rime/ipolite.h b/core/net/rime/ipolite.h index 2297eeb75..e1fa683b3 100644 --- a/core/net/rime/ipolite.h +++ b/core/net/rime/ipolite.h @@ -1,3 +1,42 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Header file for Ipolite best effort local Broadcast (ipolite) + * \author + * Adam Dunkels + */ + /** * \addtogroup rime * @{ @@ -45,51 +84,12 @@ * The polite broadcast module does not add any packet attributes to * outgoing packets apart from those added by the upper layer. * - * \section channels Channels + * \section ipolite-channels Channels * * The ipolite module uses 1 channel. * */ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Header file for Ipolite best effort local Broadcast (ipolite) - * \author - * Adam Dunkels - */ - #ifndef IPOLITE_H_ #define IPOLITE_H_ diff --git a/core/net/rime/mesh.c b/core/net/rime/mesh.c index 4fd70d485..25ea280dd 100644 --- a/core/net/rime/mesh.c +++ b/core/net/rime/mesh.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rimemesh - * @{ - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup rimemesh + * @{ + */ + #include "contiki.h" #include "net/rime/rime.h" #include "net/rime/route.h" diff --git a/core/net/rime/mesh.h b/core/net/rime/mesh.h index fbda4584a..40aaf5bd1 100644 --- a/core/net/rime/mesh.h +++ b/core/net/rime/mesh.h @@ -1,24 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rimemesh Mesh routing - * @{ - * - * The mesh module sends packets using multi-hop routing to a specified - * receiver somewhere in the network. - * - * - * \section channels Channels - * - * The mesh module uses 3 channel; one for the multi-hop forwarding - * (\ref rimemultihop "multihop") and two for the route disovery (\ref - * routediscovery "route-discovery"). - * - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -58,6 +37,27 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimemesh Mesh routing + * @{ + * + * The mesh module sends packets using multi-hop routing to a specified + * receiver somewhere in the network. + * + * + * \section mesh-channels Channels + * + * The mesh module uses 3 channel; one for the multi-hop forwarding + * (\ref rimemultihop "multihop") and two for the route disovery (\ref + * routediscovery "route-discovery"). + * + */ + #ifndef MESH_H_ #define MESH_H_ diff --git a/core/net/rime/multihop.c b/core/net/rime/multihop.c index 00773d150..5837c41df 100644 --- a/core/net/rime/multihop.c +++ b/core/net/rime/multihop.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rimemh - * @{ - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + #include "contiki.h" #include "net/rime/rime.h" #include "net/rime/multihop.h" diff --git a/core/net/rime/multihop.h b/core/net/rime/multihop.h index e951de9a9..a577a3339 100644 --- a/core/net/rime/multihop.h +++ b/core/net/rime/multihop.h @@ -1,33 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rimemultihop Best-effort multihop forwarding - * @{ - * - * The multihop module implements a multihop forwarding mechanism. Routes - * must have already been setup with the route_add() function. Setting - * up routes is done with another Rime module such as the \ref - * routediscovery "route-discovery module". - * - * The multihop sends a packet to an identified node in the network by - * using multi-hop forwarding at each node in the network. The - * application or protocol that uses the multihop primitive supplies a - * routing function for selecting the next-hop neighbor. If the - * multihop primitive is requested to send a packet for which no - * suitable next hop neighbor is found, the caller is immediately - * notified of this and may choose to initiate a route discovery - * process. - * - * - * \section channels Channels - * - * The multihop module uses 1 channel. - * - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -67,6 +37,36 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimemultihop Best-effort multihop forwarding + * @{ + * + * The multihop module implements a multihop forwarding mechanism. Routes + * must have already been setup with the route_add() function. Setting + * up routes is done with another Rime module such as the \ref + * routediscovery "route-discovery module". + * + * The multihop sends a packet to an identified node in the network by + * using multi-hop forwarding at each node in the network. The + * application or protocol that uses the multihop primitive supplies a + * routing function for selecting the next-hop neighbor. If the + * multihop primitive is requested to send a packet for which no + * suitable next hop neighbor is found, the caller is immediately + * notified of this and may choose to initiate a route discovery + * process. + * + * + * \section multihop-channels Channels + * + * The multihop module uses 1 channel. + * + */ + #ifndef MULTIHOP_H_ #define MULTIHOP_H_ diff --git a/core/net/rime/neighbor-discovery.c b/core/net/rime/neighbor-discovery.c index a2d00586e..fe2f52288 100644 --- a/core/net/rime/neighbor-discovery.c +++ b/core/net/rime/neighbor-discovery.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rimeneighbordiscovery - * @{ - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup rimeneighbordiscovery + * @{ + */ + #include "contiki.h" #include "net/rime/rime.h" diff --git a/core/net/rime/neighbor-discovery.h b/core/net/rime/neighbor-discovery.h index 5e4c6dd78..337a9c15a 100644 --- a/core/net/rime/neighbor-discovery.h +++ b/core/net/rime/neighbor-discovery.h @@ -1,22 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rimeneighbordiscovery Neighbor discovery - * @{ - * - * The neighbor-discovery module implements a periodic neighbor - * discovery mechanism. A callback is invoked for every incoming - * neighbor discovery message. - * - * \section channels Channels - * - * The neighbor-discovery module uses 1 channel. - * - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -56,6 +37,25 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimeneighbordiscovery Neighbor discovery + * @{ + * + * The neighbor-discovery module implements a periodic neighbor + * discovery mechanism. A callback is invoked for every incoming + * neighbor discovery message. + * + * \section neighbor-discovery-channels Channels + * + * The neighbor-discovery module uses 1 channel. + * + */ + #ifndef NEIGHBOR_DISCOVERY_H_ #define NEIGHBOR_DISCOVERY_H_ diff --git a/core/net/rime/netflood.c b/core/net/rime/netflood.c index fedcd8eef..a8eff282d 100644 --- a/core/net/rime/netflood.c +++ b/core/net/rime/netflood.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rimenetflood - * @{ - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup rimenetflood + * @{ + */ + #include "net/rime/netflood.h" #include diff --git a/core/net/rime/netflood.h b/core/net/rime/netflood.h index 357d4408b..d21593cf2 100644 --- a/core/net/rime/netflood.h +++ b/core/net/rime/netflood.h @@ -1,37 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rimenetflood Best-effort network flooding - * @{ - * - * The netflood module does best-effort flooding. - * - * The netflood primitive sends a single packet to all nodes in the - * network. The netflood primitive uses polite broadcasts at every hop - * to reduce the number of redundant transmissions. The netflood - * primitive does not perform retransmissions of flooded packets and - * packets are not tagged with version numbers. Instead, the netflood - * primitive sets the end-to-end sender and end-to-end packet ID - * attributes on the packets it sends. A forwarding node saves the - * end-to-end sender and packet ID of the last packet it forwards and - * does not forward a packet if it has the same end-to-end sender and - * packet ID as the last packet. This reduces the risk of routing - * loops, but does not eliminate them entirely as the netflood - * primitive saves the attributes of the latest packet seen only. - * Therefore, the netflood primitive also uses the time to live - * attribute, which is decreased by one before forwarding a packet. - * If the time to live reaches zero, the primitive does not forward - * the packet. -* - * \section channels Channels - * - * The netflood module uses 1 channel. - * - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -71,6 +37,40 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimenetflood Best-effort network flooding + * @{ + * + * The netflood module does best-effort flooding. + * + * The netflood primitive sends a single packet to all nodes in the + * network. The netflood primitive uses polite broadcasts at every hop + * to reduce the number of redundant transmissions. The netflood + * primitive does not perform retransmissions of flooded packets and + * packets are not tagged with version numbers. Instead, the netflood + * primitive sets the end-to-end sender and end-to-end packet ID + * attributes on the packets it sends. A forwarding node saves the + * end-to-end sender and packet ID of the last packet it forwards and + * does not forward a packet if it has the same end-to-end sender and + * packet ID as the last packet. This reduces the risk of routing + * loops, but does not eliminate them entirely as the netflood + * primitive saves the attributes of the latest packet seen only. + * Therefore, the netflood primitive also uses the time to live + * attribute, which is decreased by one before forwarding a packet. + * If the time to live reaches zero, the primitive does not forward + * the packet. + * + * \section netflood-channels Channels + * + * The netflood module uses 1 channel. + * + */ + #ifndef NETFLOOD_H_ #define NETFLOOD_H_ diff --git a/core/net/packetqueue.c b/core/net/rime/packetqueue.c similarity index 99% rename from core/net/packetqueue.c rename to core/net/rime/packetqueue.c index 1cf1c694f..2f4d36755 100644 --- a/core/net/packetqueue.c +++ b/core/net/rime/packetqueue.c @@ -1,7 +1,3 @@ -/** - * \addtogroup packetqueue - * @{ - */ /* * Copyright (c) 2009, Swedish Institute of Computer Science. * All rights reserved. @@ -41,8 +37,13 @@ * Adam Dunkels */ +/** + * \addtogroup packetqueue + * @{ + */ + #include "sys/ctimer.h" -#include "net/packetqueue.h" +#include "net/rime/packetqueue.h" /*---------------------------------------------------------------------------*/ void diff --git a/core/net/packetqueue.h b/core/net/rime/packetqueue.h similarity index 99% rename from core/net/packetqueue.h rename to core/net/rime/packetqueue.h index 941313dc8..5956d67e8 100644 --- a/core/net/packetqueue.h +++ b/core/net/rime/packetqueue.h @@ -1,16 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup packetqueue Packet queue - * @{ - * - * The packetqueue module handles a list of queued packets. - * - */ - /* * Copyright (c) 2009, Swedish Institute of Computer Science. * All rights reserved. @@ -50,6 +37,19 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup packetqueue Packet queue + * @{ + * + * The packetqueue module handles a list of queued packets. + * + */ + #ifndef PACKETQUEUE_H_ #define PACKETQUEUE_H_ @@ -78,7 +78,7 @@ struct packetqueue { * This structure holds the state of a packet queue. It is * an opaque structure with no user-visible elements. The * function packetqueue_queuebuf() is used to extract a - * \ref queuebuf "queubuf" from the item. The function + * "queubuf" from the item. The function * packetqueue_ptr() is used to extract the opaque pointer * that was registered with the * packetqueue_enqueue_packetbuf() function. diff --git a/core/net/rime/polite-announcement.c b/core/net/rime/polite-announcement.c index ee165394c..d678931d8 100644 --- a/core/net/rime/polite-announcement.c +++ b/core/net/rime/polite-announcement.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rimeexamples - * @{ - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -42,8 +37,13 @@ * Adam Dunkels */ -#include "contiki.h" +/** + * \addtogroup rimepoliteannouncement + * @{ + */ +#include "contiki.h" +#include "sys/cc.h" #include "lib/list.h" #include "net/rime/rime.h" #include "net/rime/announcement.h" @@ -90,8 +90,6 @@ static struct polite_announcement_state { #define PRINTF(...) #endif -#define MIN(a, b) ((a)<(b)?(a):(b)) - /*---------------------------------------------------------------------------*/ static void send_adv(clock_time_t interval) diff --git a/core/net/rime/polite-announcement.h b/core/net/rime/polite-announcement.h index a79f1c560..76b4a12ec 100644 --- a/core/net/rime/polite-announcement.h +++ b/core/net/rime/polite-announcement.h @@ -1,22 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rimepoliteannouncement - * @{ - * - * The polite announcement module implements a periodic explicit - * announcement. THe module announces the announcements that have been - * registered with the \ref rimeannouncement "announcement module". - * - * \section channels Channels - * - * The polite announcement module uses 1 channel. - * - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -56,6 +37,25 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimepoliteannouncement Polite announcement + * @{ + * + * The polite announcement module implements a periodic explicit + * announcement. THe module announces the announcements that have been + * registered with the \ref rimeannouncement "announcement module". + * + * \section polite-announcement-channels Channels + * + * The polite announcement module uses 1 channel. + * + */ + #ifndef POLITE_ANNOUNCEMENT_H_ #define POLITE_ANNOUNCEMENT_H_ diff --git a/core/net/rime/polite.c b/core/net/rime/polite.c index 2d8ea44bc..6d0afed9b 100644 --- a/core/net/rime/polite.c +++ b/core/net/rime/polite.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rimepolite - * @{ - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -42,21 +37,18 @@ * Adam Dunkels */ +/** + * \addtogroup rimepolite + * @{ + */ + +#include "sys/cc.h" #include "net/rime/rime.h" #include "net/rime/polite.h" #include "lib/random.h" #include -#ifndef MAX -#define MAX(a,b) ((a) > (b)? (a) : (b)) -#endif /* MAX */ - -#ifndef MIN -#define MIN(a, b) ((a) < (b)? (a) : (b)) -#endif /* MIN */ - - /*---------------------------------------------------------------------------*/ static void recv(struct abc_conn *abc) diff --git a/core/net/rime/polite.h b/core/net/rime/polite.h index e521c3e6c..59c424608 100644 --- a/core/net/rime/polite.h +++ b/core/net/rime/polite.h @@ -1,3 +1,42 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Header file for Polite Anonymous best effort local Broadcast (polite) + * \author + * Adam Dunkels + */ + /** * \addtogroup rime * @{ @@ -45,51 +84,12 @@ * The polite broadcast module does not add any packet attributes to * outgoing packets apart from those added by the upper layer. * - * \section channels Channels + * \section polite-channels Channels * * The polite module uses 1 channel. * */ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Header file for Polite Anonymous best effort local Broadcast (polite) - * \author - * Adam Dunkels - */ - #ifndef POLITE_H_ #define POLITE_H_ diff --git a/core/net/rime/rime.c b/core/net/rime/rime.c index 8a45e8177..e4b2e524d 100644 --- a/core/net/rime/rime.c +++ b/core/net/rime/rime.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + #define DEBUG 0 #if DEBUG #include @@ -180,7 +180,7 @@ rime_output(struct channel *c) if(chameleon_create(c)) { packetbuf_compact(); - NETSTACK_MAC.send(packet_sent, c); + NETSTACK_LLSEC.send(packet_sent, c); return 1; } return 0; diff --git a/core/net/rime/rime.h b/core/net/rime/rime.h index 14d79ee49..dbabe0a26 100644 --- a/core/net/rime/rime.h +++ b/core/net/rime/rime.h @@ -1,8 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + #ifndef RIME_H_ #define RIME_H_ diff --git a/core/net/rime/rmh.c b/core/net/rime/rmh.c index 9cfc06a5f..cc5614a61 100644 --- a/core/net/rime/rmh.c +++ b/core/net/rime/rmh.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rimermh - * @{ - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup rimermh + * @{ + */ + #include "contiki.h" #include "net/rime/rime.h" #include "net/rime/rmh.h" diff --git a/core/net/rime/rmh.h b/core/net/rime/rmh.h index 9e76f36f8..14faac14d 100644 --- a/core/net/rime/rmh.h +++ b/core/net/rime/rmh.h @@ -1,28 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rimermh Best-effort multihop forwarding - * @{ - * - * The rmh module implements a multihop forwarding mechanism. Routes - * must have already been setup with the route_add() function. Setting - * up routes is done with another Rime module such as the \ref - * routediscovery "route-discovery module". - * - * The hop-by-hop reliable multi-hop unciast primitive is similar to - * the best-effot multi-hop unicast primitive except that it uses the - * reliable single-hop primitive for the communication between two - * single-hop neighbors. - * - * \section channels Channels - * - * The rmh module uses 1 channel. - * - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -62,6 +37,31 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimermh Reliable multihop forwarding + * @{ + * + * The rmh module implements a multihop forwarding mechanism. Routes + * must have already been setup with the route_add() function. Setting + * up routes is done with another Rime module such as the \ref + * routediscovery "route-discovery module". + * + * The hop-by-hop reliable multi-hop unciast primitive is similar to + * the best-effot multi-hop unicast primitive except that it uses the + * reliable single-hop primitive for the communication between two + * single-hop neighbors. + * + * \section rmh-channels Channels + * + * The rmh module uses 1 channel. + * + */ + #ifndef RMH_H_ #define RMH_H_ diff --git a/core/net/rime/route-discovery.c b/core/net/rime/route-discovery.c index 7e212568b..4ab2ee138 100644 --- a/core/net/rime/route-discovery.c +++ b/core/net/rime/route-discovery.c @@ -1,8 +1,3 @@ -/** - * \addtogroup routediscovery - * @{ - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup routediscovery + * @{ + */ + #include "contiki.h" #include "net/rime/rime.h" #include "net/rime/route.h" @@ -271,14 +271,24 @@ static const struct unicast_callbacks rrep_callbacks = {rrep_packet_received}; static const struct netflood_callbacks rreq_callbacks = {rreq_packet_received, NULL, NULL}; /*---------------------------------------------------------------------------*/ void +route_discovery_explicit_open(struct route_discovery_conn *c, + clock_time_t time, + uint16_t netflood_channel, + uint16_t unicast_channel, + const struct route_discovery_callbacks *callbacks) +{ + netflood_open(&c->rreqconn, time, netflood_channel, &rreq_callbacks); + unicast_open(&c->rrepconn, unicast_channel, &rrep_callbacks); + c->cb = callbacks; +} +/*---------------------------------------------------------------------------*/ +void route_discovery_open(struct route_discovery_conn *c, clock_time_t time, uint16_t channels, const struct route_discovery_callbacks *callbacks) { - netflood_open(&c->rreqconn, time, channels + 0, &rreq_callbacks); - unicast_open(&c->rrepconn, channels + 1, &rrep_callbacks); - c->cb = callbacks; + route_discovery_explicit_open(c, time, channels + 0, channels + 1, callbacks); } /*---------------------------------------------------------------------------*/ void diff --git a/core/net/rime/route-discovery.h b/core/net/rime/route-discovery.h index a483a18cc..09ce984c2 100644 --- a/core/net/rime/route-discovery.h +++ b/core/net/rime/route-discovery.h @@ -1,20 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup routediscovery Rime route discovery protocol - * @{ - * - * The route-discovery module does route discovery for Rime. - * - * \section channels Channels - * - * The ibc module uses 2 channels; one for the flooded route request - * packets and one for the unicast route replies. - * - */ /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -54,6 +37,23 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup routediscovery Rime route discovery protocol + * @{ + * + * The route-discovery module does route discovery for Rime. + * + * \section route-discovery-channels Channels + * + * The ibc module uses 2 channels; one for the flooded route request + * packets and one for the unicast route replies. + * + */ #ifndef ROUTE_DISCOVERY_H_ #define ROUTE_DISCOVERY_H_ @@ -83,6 +83,10 @@ struct route_discovery_conn { void route_discovery_open(struct route_discovery_conn *c, clock_time_t time, uint16_t channels, const struct route_discovery_callbacks *callbacks); +void route_discovery_explicit_open(struct route_discovery_conn *c, clock_time_t time, + uint16_t netflood_channel, + uint16_t unicast_channel, + const struct route_discovery_callbacks *callbacks); int route_discovery_discover(struct route_discovery_conn *c, const linkaddr_t *dest, clock_time_t timeout); diff --git a/core/net/rime/route.c b/core/net/rime/route.c index ec9079718..dee9ab837 100644 --- a/core/net/rime/route.c +++ b/core/net/rime/route.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rimeroute - * @{ - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup rimeroute + * @{ + */ + #include #include "lib/list.h" @@ -121,7 +121,7 @@ int route_add(const linkaddr_t *dest, const linkaddr_t *nexthop, uint8_t cost, uint8_t seqno) { - struct route_entry *e; + struct route_entry *e, *oldest = NULL; /* Avoid inserting duplicate entries. */ e = route_lookup(dest); @@ -131,8 +131,14 @@ route_add(const linkaddr_t *dest, const linkaddr_t *nexthop, /* Allocate a new entry or reuse the oldest entry with highest cost. */ e = memb_alloc(&route_mem); if(e == NULL) { - /* Remove oldest entry. XXX */ - e = list_chop(route_table); + /* Remove oldest entry. */ + for(e = list_head(route_table); e != NULL; e = list_item_next(e)) { + if(oldest == NULL || e->time >= oldest->time) { + oldest = e; + } + } + e = oldest; + list_remove(route_table, e); PRINTF("route_add: removing entry to %d.%d with nexthop %d.%d and cost %d\n", e->dest.u8[0], e->dest.u8[1], e->nexthop.u8[0], e->nexthop.u8[1], diff --git a/core/net/rime/route.h b/core/net/rime/route.h index 5f4cee70b..d8b35ce7a 100644 --- a/core/net/rime/route.h +++ b/core/net/rime/route.h @@ -1,14 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ -/** - * \defgroup rimeroute Rime route table - * @{ - * - * The route module handles the route table in Rime. - */ - /* * Copyright (c) 2005, Swedish Institute of Computer Science. * All rights reserved. @@ -48,6 +37,18 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimeroute Rime route table + * @{ + * + * The route module handles the route table in Rime. + */ + #ifndef ROUTE_H_ #define ROUTE_H_ diff --git a/core/net/rime/rudolph0.c b/core/net/rime/rudolph0.c deleted file mode 100644 index d1f7d876f..000000000 --- a/core/net/rime/rudolph0.c +++ /dev/null @@ -1,242 +0,0 @@ -/** - * \addtogroup rudolph0 - * @{ - */ - -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Rudolph0: a simple block data flooding protocol - * \author - * Adam Dunkels - */ - -#include /* for offsetof */ - -#include "net/rime/rime.h" -#include "net/rime/rudolph0.h" - -#define STEADY_TIME CLOCK_SECOND * 2 - -#define DEFAULT_SEND_INTERVAL CLOCK_SECOND / 2 -enum { - TYPE_DATA, - TYPE_NACK, -}; - -enum { - STATE_RECEIVER, - STATE_SENDER, -}; - -#define VERSION_LT(a, b) ((signed char)((a) - (b)) < 0) - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif - -/*---------------------------------------------------------------------------*/ -static void -read_new_datapacket(struct rudolph0_conn *c) -{ - int len = 0; - - if(c->cb->read_chunk) { - len = c->cb->read_chunk(c, c->current.h.chunk * RUDOLPH0_DATASIZE, - c->current.data, RUDOLPH0_DATASIZE); - } - c->current.datalen = len; - - PRINTF("read_new_datapacket len %d\n", len); -} -/*---------------------------------------------------------------------------*/ -static void -send_nack(struct rudolph0_conn *c) -{ - struct rudolph0_hdr *hdr; - packetbuf_clear(); - packetbuf_hdralloc(sizeof(struct rudolph0_hdr)); - hdr = packetbuf_hdrptr(); - - hdr->type = TYPE_NACK; - hdr->version = c->current.h.version; - hdr->chunk = c->current.h.chunk; - - PRINTF("Sending nack for %d:%d\n", hdr->version, hdr->chunk); - polite_send(&c->nackc, c->send_interval / 2, sizeof(struct rudolph0_hdr)); -} -/*---------------------------------------------------------------------------*/ -static void -sent(struct stbroadcast_conn *stbroadcast) -{ - struct rudolph0_conn *c = (struct rudolph0_conn *)stbroadcast; - - if(c->current.datalen == RUDOLPH0_DATASIZE) { - c->current.h.chunk++; - PRINTF("Sending data chunk %d next time\n", c->current.h.chunk); - read_new_datapacket(c); - } else { - stbroadcast_set_timer(&c->c, STEADY_TIME); - PRINTF("Steady: Sending the same data chunk next time datalen %d, %d\n", - c->current.datalen, RUDOLPH0_DATASIZE); - } -} -/*---------------------------------------------------------------------------*/ -static void -recv(struct stbroadcast_conn *stbroadcast) -{ - struct rudolph0_conn *c = (struct rudolph0_conn *)stbroadcast; - struct rudolph0_datapacket *p = packetbuf_dataptr(); - - if(p->h.type == TYPE_DATA) { - if(c->current.h.version != p->h.version) { - PRINTF("rudolph0 new version %d\n", p->h.version); - c->current.h.version = p->h.version; - c->current.h.chunk = 0; - c->cb->write_chunk(c, 0, RUDOLPH0_FLAG_NEWFILE, p->data, 0); - if(p->h.chunk != 0) { - send_nack(c); - } else { - c->cb->write_chunk(c, 0, RUDOLPH0_FLAG_NONE, p->data, p->datalen); - c->current.h.chunk++; - } - } else if(p->h.version == c->current.h.version) { - if(p->h.chunk == c->current.h.chunk) { - PRINTF("received chunk %d\n", p->h.chunk); - if(p->datalen < RUDOLPH0_DATASIZE) { - c->cb->write_chunk(c, c->current.h.chunk * RUDOLPH0_DATASIZE, - RUDOLPH0_FLAG_LASTCHUNK, p->data, p->datalen); - } else { - c->cb->write_chunk(c, c->current.h.chunk * RUDOLPH0_DATASIZE, - RUDOLPH0_FLAG_NONE, p->data, p->datalen); - } - c->current.h.chunk++; - - } else if(p->h.chunk > c->current.h.chunk) { - PRINTF("received chunk %d > %d, sending NACK\n", p->h.chunk, c->current.h.chunk); - send_nack(c); - } - } else { /* p->h.version < c->current.h.version */ - /* Ignore packets with old version */ - } - } -} -/*---------------------------------------------------------------------------*/ -static void -recv_nack(struct polite_conn *polite) -{ - struct rudolph0_conn *c = (struct rudolph0_conn *) - ((char *)polite - offsetof(struct rudolph0_conn, - nackc)); - struct rudolph0_datapacket *p = packetbuf_dataptr(); - - if(p->h.type == TYPE_NACK && c->state == STATE_SENDER) { - if(p->h.version == c->current.h.version) { - PRINTF("Reseting chunk to %d\n", p->h.chunk); - c->current.h.chunk = p->h.chunk; - } else { - PRINTF("Wrong version, reseting chunk to 0\n"); - c->current.h.chunk = 0; - } - read_new_datapacket(c); - stbroadcast_set_timer(&c->c, c->send_interval); - } -} -/*---------------------------------------------------------------------------*/ -static const struct polite_callbacks polite = { recv_nack, 0, 0 }; -static const struct stbroadcast_callbacks stbroadcast = { recv, sent }; -/*---------------------------------------------------------------------------*/ -void -rudolph0_open(struct rudolph0_conn *c, uint16_t channel, - const struct rudolph0_callbacks *cb) -{ - stbroadcast_open(&c->c, channel, &stbroadcast); - polite_open(&c->nackc, channel + 1, &polite); - c->cb = cb; - c->current.h.version = 0; - c->state = STATE_RECEIVER; - c->send_interval = DEFAULT_SEND_INTERVAL; -} -/*---------------------------------------------------------------------------*/ -void -rudolph0_close(struct rudolph0_conn *c) -{ - stbroadcast_close(&c->c); - polite_close(&c->nackc); -} -/*---------------------------------------------------------------------------*/ -void -rudolph0_send(struct rudolph0_conn *c, clock_time_t send_interval) -{ - c->state = STATE_SENDER; - c->current.h.version++; - c->current.h.version++; - c->current.h.chunk = 0; - c->current.h.type = TYPE_DATA; - read_new_datapacket(c); - packetbuf_reference(&c->current, sizeof(struct rudolph0_datapacket)); - c->send_interval = send_interval; - stbroadcast_send_stubborn(&c->c, c->send_interval); -} -/*---------------------------------------------------------------------------*/ -void -rudolph0_force_restart(struct rudolph0_conn *c) -{ - c->current.h.chunk = 0; - send_nack(c); -} -/*---------------------------------------------------------------------------*/ -void -rudolph0_stop(struct rudolph0_conn *c) -{ - stbroadcast_cancel(&c->c); -} -/*---------------------------------------------------------------------------*/ -int -rudolph0_version(struct rudolph0_conn *c) -{ - return c->current.h.version; -} -/*---------------------------------------------------------------------------*/ -void -rudolph0_set_version(struct rudolph0_conn *c, int version) -{ - c->current.h.version = version; -} -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/core/net/rime/rudolph0.h b/core/net/rime/rudolph0.h deleted file mode 100644 index 9b62e4f4f..000000000 --- a/core/net/rime/rudolph0.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rudolph0 Single-hop reliable bulk data transfer - * @{ - * - * The rudolph0 module implements a single-hop reliable bulk data - * transfer mechanism. - * - * \section channels Channels - * - * The rudolph0 module uses 2 channels; one for data packets and one - * for NACK and repair packets. - * - */ - -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Header file for the single-hop reliable bulk data transfer module - * \author - * Adam Dunkels - */ - -#ifndef RUDOLPH0_H_ -#define RUDOLPH0_H_ - -#include "net/rime/stbroadcast.h" -#include "net/rime/polite.h" - -struct rudolph0_conn; - -enum { - RUDOLPH0_FLAG_NONE, - RUDOLPH0_FLAG_NEWFILE, - RUDOLPH0_FLAG_LASTCHUNK, -}; - -struct rudolph0_callbacks { - void (* write_chunk)(struct rudolph0_conn *c, int offset, int flag, - uint8_t *data, int len); - int (* read_chunk)(struct rudolph0_conn *c, int offset, uint8_t *to, - int maxsize); -}; - -#ifdef RUDOLPH0_CONF_DATASIZE -#define RUDOLPH0_DATASIZE RUDOLPH0_CONF_DATASIZE -#else -#define RUDOLPH0_DATASIZE 64 -#endif - -struct rudolph0_hdr { - uint8_t type; - uint8_t version; - uint16_t chunk; -}; - -struct rudolph0_datapacket { - struct rudolph0_hdr h; - uint8_t datalen; - uint8_t data[RUDOLPH0_DATASIZE]; -}; - -struct rudolph0_conn { - struct stbroadcast_conn c; - struct polite_conn nackc; - const struct rudolph0_callbacks *cb; - clock_time_t send_interval; - uint8_t state; - struct rudolph0_datapacket current; -}; - -void rudolph0_open(struct rudolph0_conn *c, uint16_t channel, - const struct rudolph0_callbacks *cb); -void rudolph0_close(struct rudolph0_conn *c); -void rudolph0_send(struct rudolph0_conn *c, clock_time_t interval); -void rudolph0_stop(struct rudolph0_conn *c); - -/* Force the sender to restart sending the file from the start. */ -void rudolph0_force_restart(struct rudolph0_conn *c); - -void rudolph0_set_version(struct rudolph0_conn *c, int version); -int rudolph0_version(struct rudolph0_conn *c); - -#endif /* RUDOLPH0_H_ */ -/** @} */ -/** @} */ - diff --git a/core/net/rime/rudolph1.c b/core/net/rime/rudolph1.c index daba3c236..b1cbc8441 100644 --- a/core/net/rime/rudolph1.c +++ b/core/net/rime/rudolph1.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rudolph1 - * @{ - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup rudolph1 + * @{ + */ + #include #include /* for offsetof */ diff --git a/core/net/rime/rudolph1.h b/core/net/rime/rudolph1.h index a9e54ae70..399a0a84e 100644 --- a/core/net/rime/rudolph1.h +++ b/core/net/rime/rudolph1.h @@ -1,22 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rudolph1 Multi-hop reliable bulk data transfer - * @{ - * - * The rudolph1 module implements a multi-hop reliable bulk data - * transfer mechanism. - * - * \section channels Channels - * - * The rudolph1 module uses 2 channels; one for data transmissions and - * one for NACKs and repair packets. - * - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -56,6 +37,25 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rudolph1 Multi-hop reliable bulk data transfer (rudolph1) + * @{ + * + * The rudolph1 module implements a multi-hop reliable bulk data + * transfer mechanism. + * + * \section rudolph1-channels Channels + * + * The rudolph1 module uses 2 channels; one for data transmissions and + * one for NACKs and repair packets. + * + */ + #ifndef RUDOLPH1_H_ #define RUDOLPH1_H_ diff --git a/core/net/rime/rudolph2.c b/core/net/rime/rudolph2.c index 593fea3fc..e8cfac35e 100644 --- a/core/net/rime/rudolph2.c +++ b/core/net/rime/rudolph2.c @@ -1,14 +1,3 @@ -/* XXX todo: add timeout so that hops_from_sink is reset to MAX - after a while. */ - -/* XXX todo: use a ctimer to drive peridodic transmission: the current - way does not work if a queuebuf cannot be allocated. */ - -/** - * \addtogroup rudolph2 - * @{ - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -48,6 +37,17 @@ * Adam Dunkels */ +/** + * \addtogroup rudolph2 + * @{ + */ + +/* XXX todo: add timeout so that hops_from_sink is reset to MAX + after a while. */ + +/* XXX todo: use a ctimer to drive peridodic transmission: the current + way does not work if a queuebuf cannot be allocated. */ + #include #include /* for offsetof */ diff --git a/core/net/rime/rudolph2.h b/core/net/rime/rudolph2.h index 7307b573d..e1d43e8fa 100644 --- a/core/net/rime/rudolph2.h +++ b/core/net/rime/rudolph2.h @@ -1,22 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rudolph2 Single-hop reliable bulk data transfer - * @{ - * - * The rudolph2 module implements a single-hop reliable bulk data - * transfer mechanism. - * - * \section channels Channels - * - * The rudolph2 module uses 2 channels; one for data packets and one - * for NACK and repair packets. - * - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -56,6 +37,25 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rudolph2 Single-hop reliable bulk data transfer (rudolph2) + * @{ + * + * The rudolph2 module implements a single-hop reliable bulk data + * transfer mechanism. + * + * \section rudolph2-channels Channels + * + * The rudolph2 module uses 2 channels; one for data packets and one + * for NACK and repair packets. + * + */ + #ifndef RUDOLPH2_H_ #define RUDOLPH2_H_ diff --git a/core/net/rime/runicast.c b/core/net/rime/runicast.c index 89d9ca0fe..4dc1abeec 100644 --- a/core/net/rime/runicast.c +++ b/core/net/rime/runicast.c @@ -1,9 +1,3 @@ -/** - * \addtogroup rimerunicast - * @{ - */ - - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -43,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup rimerunicast + * @{ + */ + #include "net/rime/runicast.h" #include "net/rime/rime.h" #include diff --git a/core/net/rime/runicast.h b/core/net/rime/runicast.h index 61084764a..a7e199435 100644 --- a/core/net/rime/runicast.h +++ b/core/net/rime/runicast.h @@ -1,41 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rimerunicast Single-hop reliable unicast - * @{ - * - * The reliable single-hop unicast primitive (runicast) reliably sends - * a packet to a single-hop neighbor. The runicast primitive uses - * acknowledgements and retransmissions to ensure that the neighbor - * successfully receives the packet. When the receiver has - * acknowledged the packet, the ruc module notifies the sending - * application via a callback. The ruc primitive uses the stubborn - * single-hop unicast primitive to do retransmissions. Thus, the ruc - * primitive does not have to manage the details of setting up timers - * and doing retransmissions, but can concentrate on dealing with - * acknowledgements. - * - * The runicast primitive adds two packet attributes: the single-hop - * packet type and the single-hop packet ID. The runicast primitive - * uses the packet ID attribute as a sequence number for matching - * acknowledgement packets to the corresponding data packets. - * - * The application or protocol that uses the runicast primitive can - * specify the maximum number of transmissions that the ruc module - * should attempt before the packet times out. If a packet times out, - * the application or protocol that sent the packet is notified with a - * callback. - * - * - * \section channels Channels - * - * The runicast module uses 1 channel. - * - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -75,6 +37,44 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimerunicast Single-hop reliable unicast + * @{ + * + * The reliable single-hop unicast primitive (runicast) reliably sends + * a packet to a single-hop neighbor. The runicast primitive uses + * acknowledgements and retransmissions to ensure that the neighbor + * successfully receives the packet. When the receiver has + * acknowledged the packet, the ruc module notifies the sending + * application via a callback. The ruc primitive uses the stubborn + * single-hop unicast primitive to do retransmissions. Thus, the ruc + * primitive does not have to manage the details of setting up timers + * and doing retransmissions, but can concentrate on dealing with + * acknowledgements. + * + * The runicast primitive adds two packet attributes: the single-hop + * packet type and the single-hop packet ID. The runicast primitive + * uses the packet ID attribute as a sequence number for matching + * acknowledgement packets to the corresponding data packets. + * + * The application or protocol that uses the runicast primitive can + * specify the maximum number of transmissions that the ruc module + * should attempt before the packet times out. If a packet times out, + * the application or protocol that sent the packet is notified with a + * callback. + * + * + * \section runicast-channels Channels + * + * The runicast module uses 1 channel. + * + */ + #ifndef RUNICAST_H_ #define RUNICAST_H_ diff --git a/core/net/rime/stbroadcast.c b/core/net/rime/stbroadcast.c index 970d69bc3..7f10813c1 100644 --- a/core/net/rime/stbroadcast.c +++ b/core/net/rime/stbroadcast.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rimestbroadcast - * @{ - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -43,6 +38,11 @@ * Adam Dunkels */ +/** + * \addtogroup rimestbroadcast + * @{ + */ + #include "net/rime/stbroadcast.h" #include "net/rime/rime.h" #include diff --git a/core/net/rime/stbroadcast.h b/core/net/rime/stbroadcast.h index 6d7f175ee..0b656827e 100644 --- a/core/net/rime/stbroadcast.h +++ b/core/net/rime/stbroadcast.h @@ -1,23 +1,3 @@ -/** - * \addtogroup rime - * @{ -*/ - -/** - * \defgroup rimestbroadcast Stubborn best-effort local area broadcast - * @{ - * - * The stbroadcast module provides stubborn anonymous best-effort local area - * broadcast. A message sent with the stbroadcast module is repeated until - * either the message is canceled or a new message is sent. Messages - * sent with the stbroadcast module are not identified with a sender ID. - * - * \section channels Channels - * - * The stbroadcast module uses 1 channel. - * - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -57,6 +37,26 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ +*/ + +/** + * \defgroup rimestbroadcast Stubborn best-effort local area broadcast + * @{ + * + * The stbroadcast module provides stubborn anonymous best-effort local area + * broadcast. A message sent with the stbroadcast module is repeated until + * either the message is canceled or a new message is sent. Messages + * sent with the stbroadcast module are not identified with a sender ID. + * + * \section stbroadcast-channels Channels + * + * The stbroadcast module uses 1 channel. + * + */ + #ifndef STBROADCAST_H_ #define STBROADCAST_H_ diff --git a/core/net/rime/stunicast.c b/core/net/rime/stunicast.c index 5c7f22eb8..d7e1e8231 100644 --- a/core/net/rime/stunicast.c +++ b/core/net/rime/stunicast.c @@ -1,8 +1,3 @@ -/** - * \addtogroup rimestunicast - * @{ - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup rimestunicast + * @{ + */ + #include "net/rime/stunicast.h" #include "net/rime/rime.h" #include @@ -112,10 +112,10 @@ send(void *ptr) PRINTF("%d.%d: stunicast: resend to %d.%d\n", linkaddr_node_addr.u8[0],linkaddr_node_addr.u8[1], c->receiver.u8[0], c->receiver.u8[1]); - if(c->buf) { - queuebuf_to_packetbuf(c->buf); - unicast_send(&c->c, &c->receiver); - stunicast_set_timer(c, CLOCK_SECOND); + if(c->buf) { + queuebuf_to_packetbuf(c->buf); + unicast_send(&c->c, &c->receiver); + ctimer_restart(&c->t); } /* if(c->u->sent != NULL) { c->u->sent(c); diff --git a/core/net/rime/stunicast.h b/core/net/rime/stunicast.h index afe6157ec..6e02d88ff 100644 --- a/core/net/rime/stunicast.h +++ b/core/net/rime/stunicast.h @@ -1,35 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rimestunicast Stubborn unicast - * @{ - * - * The stubborn single-hop unicast primitive (stunicast) repeatedly - * sends a packet to a single-hop neighbor using the unicast - * primitive. The stunicast primitive sends and resends the packet - * until an upper layer primitive or protocol cancels the - * transmission. While it is possible for applications and protocols - * that use Rime to use the stubborn single-hop unicast primitive - * directly, the stunicast primitive is primarily used by the reliable - * single-hop unicast (runicast) primitive. - * - * Before the stunicast primitive sends a packet, it allocates a queue - * buffer, to which the application data and packet attributes is - * copied, and sets a timer. When the timer expires, the stunicast - * primitive copies the queue buffer to the Rime buffer and sends the - * packet using the unicast primitive. The stunicast primitive sets the - * number of retransmissions for a packet as a packet attribute on - * outgoing packets. - * - * \section channels Channels - * - * The stunicast module uses 1 channel. - * - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -69,6 +37,38 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimestunicast Stubborn unicast + * @{ + * + * The stubborn single-hop unicast primitive (stunicast) repeatedly + * sends a packet to a single-hop neighbor using the unicast + * primitive. The stunicast primitive sends and resends the packet + * until an upper layer primitive or protocol cancels the + * transmission. While it is possible for applications and protocols + * that use Rime to use the stubborn single-hop unicast primitive + * directly, the stunicast primitive is primarily used by the reliable + * single-hop unicast (runicast) primitive. + * + * Before the stunicast primitive sends a packet, it allocates a queue + * buffer, to which the application data and packet attributes is + * copied, and sets a timer. When the timer expires, the stunicast + * primitive copies the queue buffer to the Rime buffer and sends the + * packet using the unicast primitive. The stunicast primitive sets the + * number of retransmissions for a packet as a packet attribute on + * outgoing packets. + * + * \section stunicast-channels Channels + * + * The stunicast module uses 1 channel. + * + */ + #ifndef STUNICAST_H_ #define STUNICAST_H_ diff --git a/core/net/rime/timesynch.c b/core/net/rime/timesynch.c index a7835e133..d9ff03c2d 100644 --- a/core/net/rime/timesynch.c +++ b/core/net/rime/timesynch.c @@ -1,9 +1,3 @@ -/** - * \addtogroup timesynch - * @{ - */ - - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -43,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup timesynch + * @{ + */ + #include "contiki.h" #include "lib/random.h" #include "net/rime/rime.h" diff --git a/core/net/rime/timesynch.h b/core/net/rime/timesynch.h index a17af5064..7e7f83df1 100644 --- a/core/net/rime/timesynch.h +++ b/core/net/rime/timesynch.h @@ -1,30 +1,3 @@ -/** - * \addtogroup sys - * @{ - */ - -/** - * \defgroup timesynch Implicit network time synchronization - * @{ - * - * This crude and simple network time synchronization module - * synchronizes clocks of all nodes in a network. The time - * synchronization is implicit in that no explicit time - * synchronization messages are sent: the module relies on the - * underlying network device driver to timestamp all radio messages, - * both outgoing and incoming. The code currently only works on the - * Tmote Sky platform and the cc2420 driver. - * - * Every node has an authority level, which is included in every - * outgoing packet. If a message is received from a node with higher - * authority (lower authority number), the node adjusts its clock - * towards the clock of the sending node. - * - * The timesynch module is implemented as a meta-MAC protocol, so that - * the module is invoked for every incoming packet. - * - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -64,6 +37,33 @@ * Adam Dunkels */ +/** + * \addtogroup sys + * @{ + */ + +/** + * \defgroup timesynch Implicit network time synchronization + * @{ + * + * This crude and simple network time synchronization module + * synchronizes clocks of all nodes in a network. The time + * synchronization is implicit in that no explicit time + * synchronization messages are sent: the module relies on the + * underlying network device driver to timestamp all radio messages, + * both outgoing and incoming. The code currently only works on the + * Tmote Sky platform and the cc2420 driver. + * + * Every node has an authority level, which is included in every + * outgoing packet. If a message is received from a node with higher + * authority (lower authority number), the node adjusts its clock + * towards the clock of the sending node. + * + * The timesynch module is implemented as a meta-MAC protocol, so that + * the module is invoked for every incoming packet. + * + */ + #ifndef TIMESYNCH_H_ #define TIMESYNCH_H_ diff --git a/core/net/rime/trickle.c b/core/net/rime/trickle.c index 3a9bf4158..c72d01ab8 100644 --- a/core/net/rime/trickle.c +++ b/core/net/rime/trickle.c @@ -1,8 +1,3 @@ -/** - * \addtogroup trickle - * @{ - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup trickle + * @{ + */ + #include "net/rime/trickle.h" #include "lib/random.h" diff --git a/core/net/rime/trickle.h b/core/net/rime/trickle.h index 4dc0fdd0f..1521024b7 100644 --- a/core/net/rime/trickle.h +++ b/core/net/rime/trickle.h @@ -1,20 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup trickle Reliable single-source multi-hop flooding - * @{ - * - * The trickle module sends a single packet to all nodes on the network. - * - * \section channels Channels - * - * The trickle module uses 1 channel. - * - */ - /* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. @@ -54,6 +37,23 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup trickle Reliable single-source multi-hop flooding + * @{ + * + * The trickle module sends a single packet to all nodes on the network. + * + * \section trickle-channels Channels + * + * The trickle module uses 1 channel. + * + */ + #ifndef TRICKLE_H_ #define TRICKLE_H_ diff --git a/core/net/rime/unicast.c b/core/net/rime/unicast.c index fa2493a31..14242db08 100644 --- a/core/net/rime/unicast.c +++ b/core/net/rime/unicast.c @@ -1,9 +1,3 @@ - -/** - * \addtogroup rimeuc - * @{ - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -43,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup rimeuc + * @{ + */ + #include "net/rime/rime.h" #include "net/rime/unicast.h" #include diff --git a/core/net/rime/unicast.h b/core/net/rime/unicast.h index b1c069d0e..3cb5bb148 100644 --- a/core/net/rime/unicast.h +++ b/core/net/rime/unicast.h @@ -1,25 +1,3 @@ -/** - * \addtogroup rime - * @{ - */ - -/** - * \defgroup rimeuc Single-hop unicast - * @{ - * - * The unicast module sends a packet to an identified single-hop - * neighbor. The unicast primitive uses the broadcast primitive and - * adds the single-hop receiver address attribute to the outgoing - * packets. For incoming packets, the unicast module inspects the - * single-hop receiver address attribute and discards the packet if - * the address does not match the address of the node. - * - * \section channels Channels - * - * The unicast module uses 1 channel. - * - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -59,6 +37,28 @@ * Adam Dunkels */ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimeuc Single-hop unicast + * @{ + * + * The unicast module sends a packet to an identified single-hop + * neighbor. The unicast primitive uses the broadcast primitive and + * adds the single-hop receiver address attribute to the outgoing + * packets. For incoming packets, the unicast module inspects the + * single-hop receiver address attribute and discards the packet if + * the address does not match the address of the node. + * + * \section unicast-channels Channels + * + * The unicast module uses 1 channel. + * + */ + #ifndef UNICAST_H_ #define UNICAST_H_ diff --git a/core/net/rpl/rpl-conf.h b/core/net/rpl/rpl-conf.h index ad3cb1861..97ab8f49d 100644 --- a/core/net/rpl/rpl-conf.h +++ b/core/net/rpl/rpl-conf.h @@ -45,31 +45,52 @@ #define RPL_CONF_STATS 0 #endif /* RPL_CONF_STATS */ -/* - * Select routing metric supported at runtime. This must be a valid - * DAG Metric Container Object Type (see below). Currently, we only - * support RPL_DAG_MC_ETX and RPL_DAG_MC_ENERGY. - * When MRHOF (RFC6719) is used with ETX, no metric container must - * be used; instead the rank carries ETX directly. +/* + * The objective function (OF) used by a RPL root is configurable through + * the RPL_CONF_OF_OCP parameter. This is defined as the objective code + * point (OCP) of the OF, RPL_OCP_OF0 or RPL_OCP_MRHOF. This flag is of + * no relevance to non-root nodes, which run the OF advertised in the + * instance they join. + * Make sure the selected of is inRPL_SUPPORTED_OFS. */ +#ifdef RPL_CONF_OF_OCP +#define RPL_OF_OCP RPL_CONF_OF_OCP +#else /* RPL_CONF_OF_OCP */ +#define RPL_OF_OCP RPL_OCP_MRHOF +#endif /* RPL_CONF_OF_OCP */ + +/* + * The set of objective functions supported at runtime. Nodes are only + * able to join instances that advertise an OF in this set. To include + * both OF0 and MRHOF, use {&rpl_of0, &rpl_mrhof}. + */ +#ifdef RPL_CONF_SUPPORTED_OFS +#define RPL_SUPPORTED_OFS RPL_CONF_SUPPORTED_OFS +#else /* RPL_CONF_SUPPORTED_OFS */ +#define RPL_SUPPORTED_OFS {&rpl_mrhof} +#endif /* RPL_CONF_SUPPORTED_OFS */ + +/* + * Enable/disable RPL Metric Containers (MC). The actual MC in use + * for a given DODAG is decided at runtime, when joining. Note that + * OF0 (RFC6552) operates without MC, and so does MRHOF (RFC6719) when + * used with ETX as a metric (the rank is the metric). We disable MC + * by default, but note it must be enabled to support joining a DODAG + * that requires MC (e.g., MRHOF with a metric other than ETX). + */ +#ifdef RPL_CONF_WITH_MC +#define RPL_WITH_MC RPL_CONF_WITH_MC +#else /* RPL_CONF_WITH_MC */ +#define RPL_WITH_MC 0 +#endif /* RPL_CONF_WITH_MC */ + +/* The MC advertised in DIOs and propagating from the root */ #ifdef RPL_CONF_DAG_MC #define RPL_DAG_MC RPL_CONF_DAG_MC #else #define RPL_DAG_MC RPL_DAG_MC_NONE #endif /* RPL_CONF_DAG_MC */ -/* - * The objective function used by RPL is configurable through the - * RPL_CONF_OF parameter. This should be defined to be the name of an - * rpl_of object linked into the system image, e.g., rpl_of0. - */ -#ifdef RPL_CONF_OF -#define RPL_OF RPL_CONF_OF -#else -/* ETX is the default objective function. */ -#define RPL_OF rpl_mrhof -#endif /* RPL_CONF_OF */ - /* This value decides which DAG instance we should participate in by default. */ #ifdef RPL_CONF_DEFAULT_INSTANCE #define RPL_DEFAULT_INSTANCE RPL_CONF_DEFAULT_INSTANCE @@ -105,6 +126,34 @@ #define RPL_MAX_DAG_PER_INSTANCE 2 #endif /* RPL_CONF_MAX_DAG_PER_INSTANCE */ +/* + * RPL Default route lifetime + * The RPL route lifetime is used for the downward routes and for the default + * route. In a high density network with DIO suppression activated it may happen + * that a node will never send a DIO once the DIO interval becomes high as it + * has heard DIO from many neighbors already. As the default route to the + * preferred parent has a lifetime reset by receiving DIO from the parent, it + * means that the default route can be destroyed after a while. Setting the + * default route with infinite lifetime secures the upstream route. + */ +#ifdef RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME +#define RPL_DEFAULT_ROUTE_INFINITE_LIFETIME RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME +#else +#define RPL_DEFAULT_ROUTE_INFINITE_LIFETIME 1 +#endif /* RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME */ + +/* + * Maximum lifetime of a DAG + * When a DODAG is not updated since RPL_CONF_DAG_LIFETIME times the DODAG + * maximum DIO interval the DODAG is removed from the list of DODAGS of the + * related instance, except if it is the currently joined DODAG. + */ +#ifdef RPL_CONF_DAG_LIFETIME +#define RPL_DAG_LIFETIME RPL_CONF_DAG_LIFETIME +#else +#define RPL_DAG_LIFETIME 3 +#endif /* RPL_CONF_DAG_LIFETIME */ + /* * */ @@ -158,21 +207,12 @@ #define RPL_DIO_REDUNDANCY 10 #endif -/* - * Initial metric attributed to a link when the ETX is unknown - */ -#ifndef RPL_CONF_INIT_LINK_METRIC -#define RPL_INIT_LINK_METRIC 5 -#else -#define RPL_INIT_LINK_METRIC RPL_CONF_INIT_LINK_METRIC -#endif - /* * Default route lifetime unit. This is the granularity of time * used in RPL lifetime values, in seconds. */ #ifndef RPL_CONF_DEFAULT_LIFETIME_UNIT -#define RPL_DEFAULT_LIFETIME_UNIT 0xffff +#define RPL_DEFAULT_LIFETIME_UNIT 60 #else #define RPL_DEFAULT_LIFETIME_UNIT RPL_CONF_DEFAULT_LIFETIME_UNIT #endif @@ -181,9 +221,121 @@ * Default route lifetime as a multiple of the lifetime unit. */ #ifndef RPL_CONF_DEFAULT_LIFETIME -#define RPL_DEFAULT_LIFETIME 0xff +#define RPL_DEFAULT_LIFETIME 30 #else #define RPL_DEFAULT_LIFETIME RPL_CONF_DEFAULT_LIFETIME #endif +/* + * DAG preference field + */ +#ifdef RPL_CONF_PREFERENCE +#define RPL_PREFERENCE RPL_CONF_PREFERENCE +#else +#define RPL_PREFERENCE 0 +#endif + +/* + * RPL DAO ACK support. When enabled, DAO ACK will be sent and requested. + * This will also enable retransmission of DAO when no ack is received. + * */ +#ifdef RPL_CONF_WITH_DAO_ACK +#define RPL_WITH_DAO_ACK RPL_CONF_WITH_DAO_ACK +#else +#define RPL_WITH_DAO_ACK 0 +#endif /* RPL_CONF_WITH_DAO_ACK */ + +/* + * RPL REPAIR ON DAO NACK. When enabled, DAO NACK will trigger a local + * repair in order to quickly find a new parent to send DAO's to. + * NOTE: this is too agressive in some cases so use with care. + * */ +#ifdef RPL_CONF_RPL_REPAIR_ON_DAO_NACK +#define RPL_REPAIR_ON_DAO_NACK RPL_CONF_RPL_REPAIR_ON_DAO_NACK +#else +#define RPL_REPAIR_ON_DAO_NACK 0 +#endif /* RPL_CONF_RPL_REPAIR_ON_DAO_NACK */ + +/* + * Setting the DIO_REFRESH_DAO_ROUTES will make the RPL root always + * increase the DTSN (Destination Advertisement Trigger Sequence Number) + * when sending multicast DIO. This is to get all children to re-register + * their DAO route. This is needed when DAO-ACK is not enabled to add + * reliability to route maintenance. + * */ +#ifdef RPL_CONF_DIO_REFRESH_DAO_ROUTES +#define RPL_DIO_REFRESH_DAO_ROUTES RPL_CONF_DIO_REFRESH_DAO_ROUTES +#else +#define RPL_DIO_REFRESH_DAO_ROUTES 1 +#endif /* RPL_CONF_DIO_REFRESH_DAO_ROUTES */ + +/* + * RPL probing. When enabled, probes will be sent periodically to keep + * parent link estimates up to date. + */ +#ifdef RPL_CONF_WITH_PROBING +#define RPL_WITH_PROBING RPL_CONF_WITH_PROBING +#else +#define RPL_WITH_PROBING 1 +#endif + +/* + * RPL probing interval. + */ +#ifdef RPL_CONF_PROBING_INTERVAL +#define RPL_PROBING_INTERVAL RPL_CONF_PROBING_INTERVAL +#else +#define RPL_PROBING_INTERVAL (120 * CLOCK_SECOND) +#endif + +/* + * Function used to select the next parent to be probed. + */ +#ifdef RPL_CONF_PROBING_SELECT_FUNC +#define RPL_PROBING_SELECT_FUNC RPL_CONF_PROBING_SELECT_FUNC +#else +#define RPL_PROBING_SELECT_FUNC get_probing_target +#endif + +/* + * Function used to send RPL probes. + * To probe with DIO, use: + * #define RPL_CONF_PROBING_SEND_FUNC(instance, addr) dio_output((instance), (addr)) + * To probe with DIS, use: + * #define RPL_CONF_PROBING_SEND_FUNC(instance, addr) dis_output((addr)) + * Any other custom probing function is also acceptable. + */ +#ifdef RPL_CONF_PROBING_SEND_FUNC +#define RPL_PROBING_SEND_FUNC RPL_CONF_PROBING_SEND_FUNC +#else +#define RPL_PROBING_SEND_FUNC(instance, addr) dio_output((instance), (addr)) +#endif + +/* + * Function used to calculate next RPL probing interval + */ +#ifdef RPL_CONF_PROBING_DELAY_FUNC +#define RPL_PROBING_DELAY_FUNC RPL_CONF_PROBING_DELAY_FUNC +#else +#define RPL_PROBING_DELAY_FUNC get_probing_delay +#endif + +/* + * Interval of DIS transmission + */ +#ifdef RPL_CONF_DIS_INTERVAL +#define RPL_DIS_INTERVAL RPL_CONF_DIS_INTERVAL +#else +#define RPL_DIS_INTERVAL 60 +#endif + +/* + * Added delay of first DIS transmission after boot + */ +#ifdef RPL_CONF_DIS_START_DELAY +#define RPL_DIS_START_DELAY RPL_CONF_DIS_START_DELAY +#else +#define RPL_DIS_START_DELAY 5 +#endif + #endif /* RPL_CONF_H */ diff --git a/core/net/rpl/rpl-dag-root.c b/core/net/rpl/rpl-dag-root.c new file mode 100644 index 000000000..57a10ef80 --- /dev/null +++ b/core/net/rpl/rpl-dag-root.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2012-2014, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + */ + +#include "contiki.h" +#include "contiki-net.h" + +#include "net/rpl/rpl.h" +#include "net/rpl/rpl-private.h" +#include "net/rpl/rpl-dag-root.h" + +#include + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +#define RPL_DAG_GRACE_PERIOD (CLOCK_SECOND * 20 * 1) + +#if (UIP_CONF_MAX_ROUTES != 0) +static struct uip_ds6_notification n; +#endif /* (UIP_CONF_MAX_ROUTES != 0) */ +static uint8_t to_become_root; +static struct ctimer c; +/*---------------------------------------------------------------------------*/ +static const uip_ipaddr_t * +dag_root(void) +{ + rpl_dag_t *dag; + + dag = rpl_get_any_dag(); + if(dag != NULL) { + return &dag->dag_id; + } + + return NULL; +} +/*---------------------------------------------------------------------------*/ +static const uip_ipaddr_t * +get_global_address(void) +{ + int i; + uint8_t state; + uip_ipaddr_t *ipaddr = NULL; + + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && + state == ADDR_PREFERRED && + !uip_is_addr_linklocal(&uip_ds6_if.addr_list[i].ipaddr)) { + ipaddr = &uip_ds6_if.addr_list[i].ipaddr; + } + } + return ipaddr; +} +/*---------------------------------------------------------------------------*/ +static void +create_dag_callback(void *ptr) +{ + const uip_ipaddr_t *root, *ipaddr; + + root = dag_root(); + ipaddr = get_global_address(); + + if(root == NULL || uip_ipaddr_cmp(root, ipaddr)) { + /* The RPL network we are joining is one that we created, so we + become root. */ + if(to_become_root) { + rpl_dag_root_init_dag_immediately(); + to_become_root = 0; + } + } else { + rpl_dag_t *dag; + + dag = rpl_get_any_dag(); +#if DEBUG + printf("Found a network we did not create\n"); + printf("version %d grounded %d preference %d used %d joined %d rank %d\n", + dag->version, dag->grounded, + dag->preference, dag->used, + dag->joined, dag->rank); +#endif /* DEBUG */ + + /* We found a RPL network that we did not create so we just join + it without becoming root. But if the network has an infinite + rank, we assume the network has broken, and we become the new + root of the network. */ + + if(dag->rank == INFINITE_RANK) { + if(to_become_root) { + rpl_dag_root_init_dag_immediately(); + to_become_root = 0; + } + } + + /* Try again after the grace period */ + ctimer_set(&c, RPL_DAG_GRACE_PERIOD, create_dag_callback, NULL); + } +} +#if (UIP_CONF_MAX_ROUTES != 0) +/*---------------------------------------------------------------------------*/ +static void +route_callback(int event, uip_ipaddr_t *route, uip_ipaddr_t *ipaddr, + int numroutes) +{ + if(event == UIP_DS6_NOTIFICATION_DEFRT_ADD) { + if(route != NULL && ipaddr != NULL && + !uip_is_addr_unspecified(route) && + !uip_is_addr_unspecified(ipaddr)) { + if(to_become_root) { + ctimer_set(&c, 0, create_dag_callback, NULL); + } + } + } +} +#endif /* (UIP_CONF_MAX_ROUTES != 0) */ +/*---------------------------------------------------------------------------*/ +static uip_ipaddr_t * +set_global_address(void) +{ + static uip_ipaddr_t ipaddr; + int i; + uint8_t state; + + /* Assign a unique local address (RFC4193, + http://tools.ietf.org/html/rfc4193). */ + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); + uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); + + printf("IPv6 addresses: "); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && + (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { + uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr); + printf("\n"); + } + } + + return &ipaddr; +} +/*---------------------------------------------------------------------------*/ +void +rpl_dag_root_init(void) +{ + static uint8_t initialized = 0; + + if(!initialized) { + to_become_root = 0; + set_global_address(); +#if (UIP_CONF_MAX_ROUTES != 0) + uip_ds6_notification_add(&n, route_callback); +#endif /* (UIP_CONF_MAX_ROUTES != 0) */ + initialized = 1; + } +} +/*---------------------------------------------------------------------------*/ +int +rpl_dag_root_init_dag_immediately(void) +{ + struct uip_ds6_addr *root_if; + int i; + uint8_t state; + uip_ipaddr_t *ipaddr = NULL; + + rpl_dag_root_init(); + + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && + state == ADDR_PREFERRED && + !uip_is_addr_linklocal(&uip_ds6_if.addr_list[i].ipaddr)) { + ipaddr = &uip_ds6_if.addr_list[i].ipaddr; + } + } + + if(ipaddr != NULL) { + root_if = uip_ds6_addr_lookup(ipaddr); + if(root_if != NULL) { + rpl_dag_t *dag; + uip_ipaddr_t prefix; + + rpl_set_root(RPL_DEFAULT_INSTANCE, ipaddr); + dag = rpl_get_any_dag(); + + /* If there are routes in this dag, we remove them all as we are + from now on the new dag root and the old routes are wrong */ + if(RPL_IS_STORING(dag->instance)) { + rpl_remove_routes(dag); + } + if(dag->instance != NULL && + dag->instance->def_route != NULL) { + uip_ds6_defrt_rm(dag->instance->def_route); + dag->instance->def_route = NULL; + } + + uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); + rpl_set_prefix(dag, &prefix, 64); + PRINTF("rpl_dag_root_init_dag: created a new RPL dag\n"); + return 0; + } else { + PRINTF("rpl_dag_root_init_dag: failed to create a new RPL DAG\n"); + return -1; + } + } else { + PRINTF("rpl_dag_root_init_dag: failed to create a new RPL DAG, no preferred IP address found\n"); + return -2; + } +} +/*---------------------------------------------------------------------------*/ +void +rpl_dag_root_init_dag(void) +{ + rpl_dag_root_init(); + + ctimer_set(&c, RPL_DAG_GRACE_PERIOD, create_dag_callback, NULL); + to_become_root = 1; + + /* Send a DIS packet to request RPL info from neighbors. */ + dis_output(NULL); +} +/*---------------------------------------------------------------------------*/ +int +rpl_dag_root_is_root(void) +{ + rpl_instance_t *instance; + + instance = rpl_get_default_instance(); + + if(instance == NULL) { + return 0; + } + + if(instance->current_dag && + instance->current_dag->rank == ROOT_RANK(instance)) { + return 1; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/rpl/rpl-dag-root.h b/core/net/rpl/rpl-dag-root.h new file mode 100644 index 000000000..b421841b7 --- /dev/null +++ b/core/net/rpl/rpl-dag-root.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2012-2014, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + */ + +#ifndef RPL_DAG_ROOT_H_ +#define RPL_DAG_ROOT_H_ + +void rpl_dag_root_init(void); +void rpl_dag_root_init_dag(void); +int rpl_dag_root_init_dag_immediately(void); + +int rpl_dag_root_is_root(void); + +#endif /* RPL_DAG_ROOT_H_ */ diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index bf8424afb..4e9af23f7 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -1,7 +1,3 @@ -/** - * \addtogroup uip6 - * @{ - */ /* * Copyright (c) 2010, Swedish Institute of Computer Science. * All rights reserved. @@ -33,6 +29,7 @@ * This file is part of the Contiki operating system. * */ + /** * \file * Logic for Directed Acyclic Graphs in RPL. @@ -41,11 +38,17 @@ * Contributors: George Oikonomou (multicast) */ +/** + * \addtogroup uip6 + * @{ + */ #include "contiki.h" +#include "net/link-stats.h" #include "net/rpl/rpl-private.h" #include "net/ip/uip.h" #include "net/ipv6/uip-nd6.h" +#include "net/ipv6/uip-ds6-nbr.h" #include "net/nbr-table.h" #include "net/ipv6/multicast/uip-mcast6.h" #include "lib/list.h" @@ -58,10 +61,14 @@ #define DEBUG DEBUG_NONE #include "net/ip/uip-debug.h" -#if UIP_CONF_IPV6 +/* A configurable function called after every RPL parent switch */ +#ifdef RPL_CALLBACK_PARENT_SWITCH +void RPL_CALLBACK_PARENT_SWITCH(rpl_parent_t *old, rpl_parent_t *new); +#endif /* RPL_CALLBACK_PARENT_SWITCH */ + /*---------------------------------------------------------------------------*/ -extern rpl_of_t RPL_OF; -static rpl_of_t * const objective_functions[] = {&RPL_OF}; +extern rpl_of_t rpl_of0, rpl_mrhof; +static rpl_of_t * const objective_functions[] = RPL_SUPPORTED_OFS; /*---------------------------------------------------------------------------*/ /* RPL definitions. */ @@ -74,11 +81,53 @@ static rpl_of_t * const objective_functions[] = {&RPL_OF}; /*---------------------------------------------------------------------------*/ /* Per-parent RPL information */ -NBR_TABLE(rpl_parent_t, rpl_parents); +NBR_TABLE_GLOBAL(rpl_parent_t, rpl_parents); /*---------------------------------------------------------------------------*/ /* Allocate instance table. */ rpl_instance_t instance_table[RPL_MAX_INSTANCES]; rpl_instance_t *default_instance; + +/*---------------------------------------------------------------------------*/ +void +rpl_print_neighbor_list(void) +{ + if(default_instance != NULL && default_instance->current_dag != NULL && + default_instance->of != NULL) { + int curr_dio_interval = default_instance->dio_intcurrent; + int curr_rank = default_instance->current_dag->rank; + rpl_parent_t *p = nbr_table_head(rpl_parents); + clock_time_t clock_now = clock_time(); + + printf("RPL: MOP %u OCP %u rank %u dioint %u, nbr count %u\n", + default_instance->mop, default_instance->of->ocp, curr_rank, curr_dio_interval, uip_ds6_nbr_num()); + while(p != NULL) { + const struct link_stats *stats = rpl_get_parent_link_stats(p); + printf("RPL: nbr %3u %5u, %5u => %5u -- %2u %c%c (last tx %u min ago)\n", + rpl_get_parent_ipaddr(p)->u8[15], + p->rank, + rpl_get_parent_link_metric(p), + rpl_rank_via_parent(p), + stats != NULL ? stats->freshness : 0, + link_stats_is_fresh(stats) ? 'f' : ' ', + p == default_instance->current_dag->preferred_parent ? 'p' : ' ', + (unsigned)((clock_now - stats->last_tx_time) / (60 * CLOCK_SECOND)) + ); + p = nbr_table_next(rpl_parents, p); + } + printf("RPL: end of list\n"); + } +} +/*---------------------------------------------------------------------------*/ +uip_ds6_nbr_t * +rpl_get_nbr(rpl_parent_t *parent) +{ + const linkaddr_t *lladdr = rpl_get_parent_lladdr(parent); + if(lladdr != NULL) { + return nbr_table_get_from_lladdr(ds6_neighbors, lladdr); + } else { + return NULL; + } +} /*---------------------------------------------------------------------------*/ static void nbr_callback(void *ptr) @@ -92,6 +141,13 @@ rpl_dag_init(void) nbr_table_register(rpl_parents, (nbr_table_callback *)nbr_callback); } /*---------------------------------------------------------------------------*/ +rpl_parent_t * +rpl_get_parent(uip_lladdr_t *addr) +{ + rpl_parent_t *p = nbr_table_get_from_lladdr(rpl_parents, (linkaddr_t *)addr); + return p; +} +/*---------------------------------------------------------------------------*/ rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr) { @@ -99,28 +155,78 @@ rpl_get_parent_rank(uip_lladdr_t *addr) if(p != NULL) { return p->rank; } else { - return 0; + return INFINITE_RANK; } } /*---------------------------------------------------------------------------*/ uint16_t -rpl_get_parent_link_metric(const uip_lladdr_t *addr) +rpl_get_parent_link_metric(rpl_parent_t *p) { - rpl_parent_t *p = nbr_table_get_from_lladdr(rpl_parents, (const linkaddr_t *)addr); - if(p != NULL) { - return p->link_metric; - } else { - return 0; + if(p != NULL && p->dag != NULL) { + rpl_instance_t *instance = p->dag->instance; + if(instance != NULL && instance->of != NULL && instance->of->parent_link_metric != NULL) { + return instance->of->parent_link_metric(p); + } } + return 0xffff; +} +/*---------------------------------------------------------------------------*/ +rpl_rank_t +rpl_rank_via_parent(rpl_parent_t *p) +{ + if(p != NULL && p->dag != NULL) { + rpl_instance_t *instance = p->dag->instance; + if(instance != NULL && instance->of != NULL && instance->of->rank_via_parent != NULL) { + return instance->of->rank_via_parent(p); + } + } + return INFINITE_RANK; +} +/*---------------------------------------------------------------------------*/ +const linkaddr_t * +rpl_get_parent_lladdr(rpl_parent_t *p) +{ + return nbr_table_get_lladdr(rpl_parents, p); } /*---------------------------------------------------------------------------*/ uip_ipaddr_t * rpl_get_parent_ipaddr(rpl_parent_t *p) { - linkaddr_t *lladdr = nbr_table_get_lladdr(rpl_parents, p); + const linkaddr_t *lladdr = rpl_get_parent_lladdr(p); return uip_ds6_nbr_ipaddr_from_lladdr((uip_lladdr_t *)lladdr); } /*---------------------------------------------------------------------------*/ +const struct link_stats * +rpl_get_parent_link_stats(rpl_parent_t *p) +{ + const linkaddr_t *lladdr = rpl_get_parent_lladdr(p); + return link_stats_from_lladdr(lladdr); +} +/*---------------------------------------------------------------------------*/ +int +rpl_parent_is_fresh(rpl_parent_t *p) +{ + const struct link_stats *stats = rpl_get_parent_link_stats(p); + return link_stats_is_fresh(stats); +} +/*---------------------------------------------------------------------------*/ +int +rpl_parent_is_reachable(rpl_parent_t *p) { + if(p == NULL || p->dag == NULL || p->dag->instance == NULL || p->dag->instance->of == NULL) { + return 0; + } else { +#ifndef UIP_CONF_ND6_SEND_NA + uip_ds6_nbr_t *nbr = rpl_get_nbr(p); + /* Exclude links to a neighbor that is not reachable at a NUD level */ + if(nbr == NULL || nbr->state != NBR_REACHABLE) { + return 0; + } +#endif /* UIP_CONF_ND6_SEND_NA */ + /* If we don't have fresh link information, assume the parent is reachable. */ + return !rpl_parent_is_fresh(p) || p->dag->instance->of->parent_has_usable_link(p); + } +} +/*---------------------------------------------------------------------------*/ static void rpl_set_preferred_parent(rpl_dag_t *dag, rpl_parent_t *p) { @@ -139,6 +245,10 @@ rpl_set_preferred_parent(rpl_dag_t *dag, rpl_parent_t *p) } PRINTF("\n"); +#ifdef RPL_CALLBACK_PARENT_SWITCH + RPL_CALLBACK_PARENT_SWITCH(dag->preferred_parent, p); +#endif /* RPL_CALLBACK_PARENT_SWITCH */ + /* Always keep the preferred parent locked, so it remains in the * neighbor table. */ nbr_table_unlock(rpl_parents, dag->preferred_parent); @@ -246,17 +356,27 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id) rpl_dag_t *dag; rpl_instance_t *instance; uint8_t version; + int i; version = RPL_LOLLIPOP_INIT; - dag = get_dag(instance_id, dag_id); - if(dag != NULL) { - version = dag->version; - RPL_LOLLIPOP_INCREMENT(version); - PRINTF("RPL: Dropping a joined DAG when setting this node as root"); - if(dag == dag->instance->current_dag) { - dag->instance->current_dag = NULL; + instance = rpl_get_instance(instance_id); + if(instance != NULL) { + for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; ++i) { + dag = &instance->dag_table[i]; + if(dag->used) { + if(uip_ipaddr_cmp(&dag->dag_id, dag_id)) { + version = dag->version; + RPL_LOLLIPOP_INCREMENT(version); + } + if(dag == dag->instance->current_dag) { + PRINTF("RPL: Dropping a joined DAG when setting this node as root"); + dag->instance->current_dag = NULL; + } else { + PRINTF("RPL: Dropping a DAG when setting this node as root"); + } + rpl_free_dag(dag); + } } - rpl_free_dag(dag); } dag = rpl_alloc_dag(instance_id, dag_id); @@ -270,8 +390,14 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id) dag->version = version; dag->joined = 1; dag->grounded = RPL_GROUNDED; + dag->preference = RPL_PREFERENCE; instance->mop = RPL_MOP_DEFAULT; - instance->of = &RPL_OF; + instance->of = rpl_find_of(RPL_OF_OCP); + if(instance->of == NULL) { + PRINTF("RPL: OF with OCP %u not supported\n", RPL_OF_OCP); + return NULL; + } + rpl_set_preferred_parent(dag, NULL); memcpy(&dag->dag_id, dag_id, sizeof(dag->dag_id)); @@ -292,7 +418,9 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id) if(instance->current_dag != dag && instance->current_dag != NULL) { /* Remove routes installed by DAOs. */ - rpl_remove_routes(instance->current_dag); + if(RPL_IS_STORING(instance)) { + rpl_remove_routes(instance->current_dag); + } instance->current_dag->joined = 0; } @@ -324,6 +452,7 @@ rpl_repair_root(uint8_t instance_id) PRINTF("RPL: rpl_repair_root triggered but not root\n"); return 0; } + RPL_STAT(rpl_stats.root_repairs++); RPL_LOLLIPOP_INCREMENT(instance->current_dag->version); RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); @@ -421,8 +550,7 @@ rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from) PRINT6ADDR(from); PRINTF("\n"); instance->def_route = uip_ds6_defrt_add(from, - RPL_LIFETIME(instance, - instance->default_lifetime)); + RPL_DEFAULT_ROUTE_INFINITE_LIFETIME ? 0 : RPL_LIFETIME(instance, instance->default_lifetime)); if(instance->def_route == NULL) { return 0; } @@ -449,6 +577,9 @@ rpl_alloc_instance(uint8_t instance_id) instance->instance_id = instance_id; instance->def_route = NULL; instance->used = 1; +#if RPL_WITH_PROBING + rpl_schedule_probing(instance); +#endif /* RPL_WITH_PROBING */ return instance; } } @@ -482,7 +613,6 @@ rpl_alloc_dag(uint8_t instance_id, uip_ipaddr_t *dag_id) } RPL_STAT(rpl_stats.mem_overflows++); - rpl_free_instance(instance); return NULL; } /*---------------------------------------------------------------------------*/ @@ -492,6 +622,12 @@ rpl_set_default_instance(rpl_instance_t *instance) default_instance = instance; } /*---------------------------------------------------------------------------*/ +rpl_instance_t * +rpl_get_default_instance(void) +{ + return default_instance; +} +/*---------------------------------------------------------------------------*/ void rpl_free_instance(rpl_instance_t *instance) { @@ -509,8 +645,12 @@ rpl_free_instance(rpl_instance_t *instance) rpl_set_default_route(instance, NULL); +#if RPL_WITH_PROBING + ctimer_stop(&instance->probing_timer); +#endif /* RPL_WITH_PROBING */ ctimer_stop(&instance->dio_timer); ctimer_stop(&instance->dao_timer); + ctimer_stop(&instance->dao_lifetime_timer); if(default_instance == instance) { default_instance = NULL; @@ -529,7 +669,9 @@ rpl_free_dag(rpl_dag_t *dag) dag->joined = 0; /* Remove routes installed by DAOs. */ - rpl_remove_routes(dag); + if(RPL_IS_STORING(dag->instance)) { + rpl_remove_routes(dag); + } /* Remove autoconfigured address */ if((dag->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS)) { @@ -553,18 +695,18 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr) PRINT6ADDR(addr); PRINTF("\n"); if(lladdr != NULL) { - /* Add parent in rpl_parents */ - p = nbr_table_add_lladdr(rpl_parents, (linkaddr_t *)lladdr); + /* Add parent in rpl_parents - again this is due to DIO */ + p = nbr_table_add_lladdr(rpl_parents, (linkaddr_t *)lladdr, + NBR_TABLE_REASON_RPL_DIO, dio); if(p == NULL) { PRINTF("RPL: rpl_add_parent p NULL\n"); } else { p->dag = dag; p->rank = dio->rank; p->dtsn = dio->dtsn; - p->link_metric = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR; -#if RPL_DAG_MC != RPL_DAG_MC_NONE +#if RPL_WITH_MC memcpy(&p->mc, &dio->mc, sizeof(p->mc)); -#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ +#endif /* RPL_WITH_MC */ } } @@ -649,7 +791,9 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p) if(instance->current_dag != best_dag) { /* Remove routes installed by DAOs. */ - rpl_remove_routes(instance->current_dag); + if(RPL_IS_STORING(instance)) { + rpl_remove_routes(instance->current_dag); + } PRINTF("RPL: New preferred DAG: "); PRINT6ADDR(&best_dag->dag_id); @@ -668,13 +812,17 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p) instance->of->update_metric_container(instance); /* Update the DAG rank. */ - best_dag->rank = instance->of->calculate_rank(best_dag->preferred_parent, 0); + best_dag->rank = rpl_rank_via_parent(best_dag->preferred_parent); if(last_parent == NULL || best_dag->rank < best_dag->min_rank) { + /* This is a slight departure from RFC6550: if we had no preferred parent before, + * reset min_rank. This helps recovering from temporary bad link conditions. */ best_dag->min_rank = best_dag->rank; - } else if(!acceptable_rank(best_dag, best_dag->rank)) { + } + + if(!acceptable_rank(best_dag, best_dag->rank)) { PRINTF("RPL: New rank unacceptable!\n"); rpl_set_preferred_parent(instance->current_dag, NULL); - if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES && last_parent != NULL) { + if(RPL_IS_STORING(instance) && last_parent != NULL) { /* Send a No-Path DAO to the removed preferred parent. */ dao_output(last_parent, RPL_ZERO_LIFETIME); } @@ -686,16 +834,17 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p) PRINTF("RPL: Changed preferred parent, rank changed from %u to %u\n", (unsigned)old_rank, best_dag->rank); RPL_STAT(rpl_stats.parent_switch++); - if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) { - if(last_parent != NULL) { - /* Send a No-Path DAO to the removed preferred parent. */ - dao_output(last_parent, RPL_ZERO_LIFETIME); - } - /* The DAO parent set changed - schedule a DAO transmission. */ - RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); - rpl_schedule_dao(instance); + if(RPL_IS_STORING(instance) && last_parent != NULL) { + /* Send a No-Path DAO to the removed preferred parent. */ + dao_output(last_parent, RPL_ZERO_LIFETIME); } + /* The DAO parent set changed - schedule a DAO transmission. */ + RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); + rpl_schedule_dao(instance); rpl_reset_dio_timer(instance); +#if DEBUG + rpl_print_neighbor_list(); +#endif } else if(best_dag->rank != old_rank) { PRINTF("RPL: Preferred parent update, rank changed from %u to %u\n", (unsigned)old_rank, best_dag->rank); @@ -704,22 +853,42 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p) } /*---------------------------------------------------------------------------*/ static rpl_parent_t * -best_parent(rpl_dag_t *dag) +best_parent(rpl_dag_t *dag, int fresh_only) { - rpl_parent_t *p, *best; + rpl_parent_t *p; + rpl_of_t *of; + rpl_parent_t *best = NULL; - best = NULL; + if(dag == NULL || dag->instance == NULL || dag->instance->of == NULL) { + return NULL; + } - p = nbr_table_head(rpl_parents); - while(p != NULL) { - if(p->rank == INFINITE_RANK) { - /* ignore this neighbor */ - } else if(best == NULL) { - best = p; - } else { - best = dag->instance->of->best_parent(best, p); + of = dag->instance->of; + /* Search for the best parent according to the OF */ + for(p = nbr_table_head(rpl_parents); p != NULL; p = nbr_table_next(rpl_parents, p)) { + + /* Exclude parents from other DAGs or announcing an infinite rank */ + if(p->dag != dag || p->rank == INFINITE_RANK) { + continue; } - p = nbr_table_next(rpl_parents, p); + + if(fresh_only && !rpl_parent_is_fresh(p)) { + /* Filter out non-fresh parents if fresh_only is set */ + continue; + } + +#ifndef UIP_CONF_ND6_SEND_NA + { + uip_ds6_nbr_t *nbr = rpl_get_nbr(p); + /* Exclude links to a neighbor that is not reachable at a NUD level */ + if(nbr == NULL || nbr->state != NBR_REACHABLE) { + continue; + } + } +#endif /* UIP_CONF_ND6_SEND_NA */ + + /* Now we have an acceptable parent, check if it is the new best */ + best = of->best_parent(best, p); } return best; @@ -728,13 +897,37 @@ best_parent(rpl_dag_t *dag) rpl_parent_t * rpl_select_parent(rpl_dag_t *dag) { - rpl_parent_t *best = best_parent(dag); + /* Look for best parent (regardless of freshness) */ + rpl_parent_t *best = best_parent(dag, 0); if(best != NULL) { - rpl_set_preferred_parent(dag, best); +#if RPL_WITH_PROBING + if(rpl_parent_is_fresh(best)) { + rpl_set_preferred_parent(dag, best); + } else { + /* The best is not fresh. Look for the best fresh now. */ + rpl_parent_t *best_fresh = best_parent(dag, 1); + if(best_fresh == NULL) { + /* No fresh parent around, use best (non-fresh) */ + rpl_set_preferred_parent(dag, best); + } else { + /* Use best fresh */ + rpl_set_preferred_parent(dag, best_fresh); + } + /* Probe the best parent shortly in order to get a fresh estimate */ + dag->instance->urgent_probing_target = best; + rpl_schedule_probing(dag->instance); +#else /* RPL_WITH_PROBING */ + rpl_set_preferred_parent(dag, best); + dag->rank = rpl_rank_via_parent(dag->preferred_parent); +#endif /* RPL_WITH_PROBING */ + } + } else { + rpl_set_preferred_parent(dag, NULL); } - return best; + dag->rank = rpl_rank_via_parent(dag->preferred_parent); + return dag->preferred_parent; } /*---------------------------------------------------------------------------*/ void @@ -756,7 +949,6 @@ rpl_nullify_parent(rpl_parent_t *parent) /* This function can be called when the preferred parent is NULL, so we need to handle this condition in order to trigger uip_ds6_defrt_rm. */ if(parent == dag->preferred_parent || dag->preferred_parent == NULL) { - rpl_set_preferred_parent(dag, NULL); dag->rank = INFINITE_RANK; if(dag->joined) { if(dag->instance->def_route != NULL) { @@ -766,7 +958,13 @@ rpl_nullify_parent(rpl_parent_t *parent) uip_ds6_defrt_rm(dag->instance->def_route); dag->instance->def_route = NULL; } - dao_output(parent, RPL_ZERO_LIFETIME); + /* Send No-Path DAO only when nullifying preferred parent */ + if(parent == dag->preferred_parent) { + if(RPL_IS_STORING(dag->instance)) { + dao_output(parent, RPL_ZERO_LIFETIME); + } + rpl_set_preferred_parent(dag, NULL); + } } } @@ -790,8 +988,10 @@ rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent) dag_src->instance->def_route = NULL; } } else if(dag_src->joined) { - /* Remove uIPv6 routes that have this parent as the next hop. */ - rpl_remove_routes_by_nexthop(rpl_get_parent_ipaddr(parent), dag_src); + if(RPL_IS_STORING(dag_src->instance)) { + /* Remove uIPv6 routes that have this parent as the next hop. */ + rpl_remove_routes_by_nexthop(rpl_get_parent_ipaddr(parent), dag_src); + } } PRINTF("RPL: Moving parent "); @@ -801,6 +1001,37 @@ rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent) parent->dag = dag_dst; } /*---------------------------------------------------------------------------*/ +int +rpl_has_downward_route(void) +{ + int i; + for(i = 0; i < RPL_MAX_INSTANCES; ++i) { + if(instance_table[i].used && instance_table[i].has_downward_route) { + return 1; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +rpl_dag_t * +rpl_get_dag(const uip_ipaddr_t *addr) +{ + int i, j; + + for(i = 0; i < RPL_MAX_INSTANCES; ++i) { + if(instance_table[i].used) { + for(j = 0; j < RPL_MAX_DAG_PER_INSTANCE; ++j) { + if(instance_table[i].dag_table[j].joined + && uip_ipaddr_prefixcmp(&instance_table[i].dag_table[j].dag_id, addr, + instance_table[i].dag_table[j].prefix_info.length)) { + return &instance_table[i].dag_table[j]; + } + } + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ rpl_dag_t * rpl_get_any_dag(void) { @@ -851,6 +1082,21 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio) rpl_parent_t *p; rpl_of_t *of; + if((!RPL_WITH_NON_STORING && dio->mop == RPL_MOP_NON_STORING) + || (!RPL_WITH_STORING && (dio->mop == RPL_MOP_STORING_NO_MULTICAST + || dio->mop == RPL_MOP_STORING_MULTICAST))) { + PRINTF("RPL: DIO advertising a non-supported MOP %u\n", dio->mop); + } + + /* Determine the objective function by using the + objective code point of the DIO. */ + of = rpl_find_of(dio->ocp); + if(of == NULL) { + PRINTF("RPL: DIO for DAG instance %u does not specify a supported OF: %u\n", + dio->instance_id, dio->ocp); + return; + } + dag = rpl_alloc_dag(dio->instance_id, &dio->dag_id); if(dag == NULL) { PRINTF("RPL: Failed to allocate a DAG object!\n"); @@ -871,17 +1117,6 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio) p->dtsn = dio->dtsn; PRINTF("succeeded\n"); - /* Determine the objective function by using the - objective code point of the DIO. */ - of = rpl_find_of(dio->ocp); - if(of == NULL) { - PRINTF("RPL: DIO for DAG instance %u does not specify a supported OF\n", - dio->instance_id); - rpl_remove_parent(p); - instance->used = 0; - return; - } - /* Autoconfigure an address if this node does not already have an address with this prefix. */ if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) { @@ -895,6 +1130,10 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio) instance->of = of; instance->mop = dio->mop; + instance->mc.type = dio->mc.type; + instance->mc.flags = dio->mc.flags; + instance->mc.aggr = dio->mc.aggr; + instance->mc.prec = dio->mc.prec; instance->current_dag = dag; instance->dtsn_out = RPL_LOLLIPOP_INIT; @@ -914,7 +1153,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio) rpl_set_preferred_parent(dag, p); instance->of->update_metric_container(instance); - dag->rank = instance->of->calculate_rank(p, 0); + dag->rank = rpl_rank_via_parent(p); /* So far this is the lowest rank we are aware of. */ dag->min_rank = dag->rank; @@ -937,10 +1176,13 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio) } else { PRINTF("RPL: The DIO does not meet the prerequisites for sending a DAO\n"); } + + instance->of->reset(dag); } +#if RPL_MAX_DAG_PER_INSTANCE > 1 /*---------------------------------------------------------------------------*/ -void +rpl_dag_t * rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio) { rpl_instance_t *instance; @@ -951,7 +1193,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio) dag = rpl_alloc_dag(dio->instance_id, &dio->dag_id); if(dag == NULL) { PRINTF("RPL: Failed to allocate a DAG object!\n"); - return; + return NULL; } instance = dag->instance; @@ -965,7 +1207,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio) if(p == NULL) { PRINTF("failed\n"); dag->used = 0; - return; + return NULL; } PRINTF("succeeded\n"); } else { @@ -974,6 +1216,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio) rpl_move_parent(previous_dag, dag, p); } } + p->rank = dio->rank; /* Determine the objective function by using the objective code point of the DIO. */ @@ -991,7 +1234,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio) dio->instance_id); rpl_remove_parent(p); dag->used = 0; - return; + return NULL; } dag->used = 1; @@ -1005,7 +1248,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio) memcpy(&dag->prefix_info, &dio->prefix_info, sizeof(rpl_prefix_t)); rpl_set_preferred_parent(dag, p); - dag->rank = instance->of->calculate_rank(p, 0); + dag->rank = rpl_rank_via_parent(p); dag->min_rank = dag->rank; /* So far this is the lowest rank we know of. */ PRINTF("RPL: Joined DAG with instance ID %u, rank %hu, DAG ID ", @@ -1017,7 +1260,10 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio) rpl_process_parent_event(instance, p); p->dtsn = dio->dtsn; + + return dag; } +#endif /* RPL_MAX_DAG_PER_INSTANCE > 1 */ /*---------------------------------------------------------------------------*/ static void @@ -1027,6 +1273,14 @@ global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio) remove_parents(dag, 0); dag->version = dio->version; + + /* copy parts of the configuration so that it propagates in the network */ + dag->instance->dio_intdoubl = dio->dag_intdoubl; + dag->instance->dio_intmin = dio->dag_intmin; + dag->instance->dio_redundancy = dio->dag_redund; + dag->instance->default_lifetime = dio->default_lifetime; + dag->instance->lifetime_unit = dio->lifetime_unit; + dag->instance->of->reset(dag); dag->min_rank = INFINITE_RANK; RPL_LOLLIPOP_INCREMENT(dag->instance->dtsn_out); @@ -1036,7 +1290,7 @@ global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio) PRINTF("RPL: Failed to add a parent during the global repair\n"); dag->rank = INFINITE_RANK; } else { - dag->rank = dag->instance->of->calculate_rank(p, 0); + dag->rank = rpl_rank_via_parent(p); dag->min_rank = dag->rank; PRINTF("RPL: rpl_process_parent_event global repair\n"); rpl_process_parent_event(dag->instance, p); @@ -1047,6 +1301,7 @@ global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio) RPL_STAT(rpl_stats.global_repairs++); } + /*---------------------------------------------------------------------------*/ void rpl_local_repair(rpl_instance_t *instance) @@ -1065,7 +1320,12 @@ rpl_local_repair(rpl_instance_t *instance) } } + /* no downward route anymore */ + instance->has_downward_route = 0; + rpl_reset_dio_timer(instance); + /* Request refresh of DAO registrations next DIO */ + RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); RPL_STAT(rpl_stats.local_repairs++); } @@ -1082,8 +1342,8 @@ rpl_recalculate_ranks(void) */ p = nbr_table_head(rpl_parents); while(p != NULL) { - if(p->dag != NULL && p->dag->instance && p->updated) { - p->updated = 0; + if(p->dag != NULL && p->dag->instance && (p->flags & RPL_PARENT_FLAG_UPDATED)) { + p->flags &= ~RPL_PARENT_FLAG_UPDATED; PRINTF("RPL: rpl_process_parent_event recalculate_ranks\n"); if(!rpl_process_parent_event(p->dag->instance, p)) { PRINTF("RPL: A parent was dropped\n"); @@ -1097,6 +1357,7 @@ int rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p) { int return_value; + rpl_parent_t *last_parent = instance->current_dag->preferred_parent; #if DEBUG rpl_rank_t old_rank; @@ -1105,10 +1366,20 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p) return_value = 1; + if(RPL_IS_STORING(instance) + && uip_ds6_route_is_nexthop(rpl_get_parent_ipaddr(p)) + && !rpl_parent_is_reachable(p) && instance->mop > RPL_MOP_NON_STORING) { + PRINTF("RPL: Unacceptable link %u, removing routes via: ", rpl_get_parent_link_metric(p)); + PRINT6ADDR(rpl_get_parent_ipaddr(p)); + PRINTF("\n"); + rpl_remove_routes_by_nexthop(rpl_get_parent_ipaddr(p), p->dag); + } + if(!acceptable_rank(p->dag, p->rank)) { /* The candidate parent is no longer valid: the rank increase resulting from the choice of it as a parent would be too high. */ - PRINTF("RPL: Unacceptable rank %u\n", (unsigned)p->rank); + PRINTF("RPL: Unacceptable rank %u (Current min %u, MaxRankInc %u)\n", (unsigned)p->rank, + p->dag->min_rank, p->dag->instance->max_rankinc); rpl_nullify_parent(p); if(p != instance->current_dag->preferred_parent) { return 0; @@ -1118,10 +1389,12 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p) } if(rpl_select_dag(instance, p) == NULL) { - /* No suitable parent; trigger a local repair. */ - PRINTF("RPL: No parents found in any DAG\n"); - rpl_local_repair(instance); - return 0; + if(last_parent != NULL) { + /* No suitable parent anymore; trigger a local repair. */ + PRINTF("RPL: No parents found in any DAG\n"); + rpl_local_repair(instance); + return 0; + } } #if DEBUG @@ -1142,6 +1415,19 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p) return return_value; } /*---------------------------------------------------------------------------*/ +static int +add_nbr_from_dio(uip_ipaddr_t *from, rpl_dio_t *dio) +{ + /* add this to the neighbor cache if not already there */ + if(rpl_icmp6_update_nbr_table(from, NBR_TABLE_REASON_RPL_DIO, dio) == NULL) { + PRINTF("RPL: Out of memory, dropping DIO from "); + PRINT6ADDR(from); + PRINTF("\n"); + return 0; + } + return 1; +} +/*---------------------------------------------------------------------------*/ void rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) { @@ -1149,7 +1435,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) rpl_dag_t *dag, *previous_dag; rpl_parent_t *p; -#if RPL_CONF_MULTICAST +#if RPL_WITH_MULTICAST /* If the root is advertising MOP 2 but we support MOP 3 we can still join * In that scenario, we suppress DAOs for multicast targets */ if(dio->mop < RPL_MOP_STORING_NO_MULTICAST) { @@ -1166,19 +1452,19 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) if(dag != NULL && instance != NULL) { if(lollipop_greater_than(dio->version, dag->version)) { if(dag->rank == ROOT_RANK(instance)) { - PRINTF("RPL: Root received inconsistent DIO version number\n"); - dag->version = dio->version; - RPL_LOLLIPOP_INCREMENT(dag->version); - rpl_reset_dio_timer(instance); + PRINTF("RPL: Root received inconsistent DIO version number (current: %u, received: %u)\n", dag->version, dio->version); + dag->version = dio->version; + RPL_LOLLIPOP_INCREMENT(dag->version); + rpl_reset_dio_timer(instance); } else { PRINTF("RPL: Global repair\n"); if(dio->prefix_info.length != 0) { if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) { - PRINTF("RPL : Prefix announced in DIO\n"); + PRINTF("RPL: Prefix announced in DIO\n"); rpl_set_prefix(dag, &dio->prefix_info.prefix, dio->prefix_info.length); } } - global_repair(from, dag, dio); + global_repair(from, dag, dio); } return; } @@ -1194,8 +1480,12 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) } if(instance == NULL) { - PRINTF("RPL: New instance detected: Joining...\n"); - rpl_join_instance(from, dio); + PRINTF("RPL: New instance detected (ID=%u): Joining...\n", dio->instance_id); + if(add_nbr_from_dio(from, dio)) { + rpl_join_instance(from, dio); + } else { + PRINTF("RPL: Not joining since could not add parent\n"); + } return; } @@ -1205,9 +1495,21 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) } if(dag == NULL) { +#if RPL_MAX_DAG_PER_INSTANCE > 1 PRINTF("RPL: Adding new DAG to known instance.\n"); - rpl_add_dag(from, dio); + if(!add_nbr_from_dio(from, dio)) { + PRINTF("RPL: Could not add new DAG, could not add parent\n"); + return; + } + dag = rpl_add_dag(from, dio); + if(dag == NULL) { + PRINTF("RPL: Failed to add DAG.\n"); + return; + } +#else /* RPL_MAX_DAG_PER_INSTANCE > 1 */ + PRINTF("RPL: Only one instance supported.\n"); return; +#endif /* RPL_MAX_DAG_PER_INSTANCE > 1 */ } @@ -1215,18 +1517,21 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) PRINTF("RPL: Ignoring DIO with too low rank: %u\n", (unsigned)dio->rank); return; - } else if(dio->rank == INFINITE_RANK && dag->joined) { - rpl_reset_dio_timer(instance); } /* Prefix Information Option treated to add new prefix */ if(dio->prefix_info.length != 0) { if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) { - PRINTF("RPL : Prefix announced in DIO\n"); + PRINTF("RPL: Prefix announced in DIO\n"); rpl_set_prefix(dag, &dio->prefix_info.prefix, dio->prefix_info.length); } } + if(!add_nbr_from_dio(from, dio)) { + PRINTF("RPL: Could not add parent based on DIO\n"); + return; + } + if(dag->rank == ROOT_RANK(instance)) { if(dio->rank != INFINITE_RANK) { instance->dio_counter++; @@ -1234,6 +1539,12 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) return; } + /* The DIO comes from a valid DAG, we can refresh its lifetime */ + dag->lifetime = (1UL << (instance->dio_intmin + instance->dio_intdoubl)) / 1000; + PRINTF("Set dag "); + PRINT6ADDR(&dag->dag_id); + PRINTF(" lifetime to %ld\n", dag->lifetime); + /* * At this point, we know that this DIO pertains to a DAG that * we are already part of. We consider the sender of the DIO to be @@ -1268,23 +1579,30 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) if(dag->joined) { instance->dio_counter++; } - } else { - p->rank=dio->rank; } } + p->rank = dio->rank; + + if(dio->rank == INFINITE_RANK && p == dag->preferred_parent) { + /* Our preferred parent advertised an infinite rank, reset DIO timer */ + rpl_reset_dio_timer(instance); + } + + /* Parent info has been updated, trigger rank recalculation */ + p->flags |= RPL_PARENT_FLAG_UPDATED; PRINTF("RPL: preferred DAG "); PRINT6ADDR(&instance->current_dag->dag_id); PRINTF(", rank %u, min_rank %u, ", instance->current_dag->rank, instance->current_dag->min_rank); - PRINTF("parent rank %u, parent etx %u, link metric %u, instance etx %u\n", - p->rank, -1/*p->mc.obj.etx*/, p->link_metric, instance->mc.obj.etx); + PRINTF("parent rank %u, link metric %u\n", + p->rank, rpl_get_parent_link_metric(p)); /* We have allocated a candidate parent; process the DIO further. */ -#if RPL_DAG_MC != RPL_DAG_MC_NONE +#if RPL_WITH_MC memcpy(&p->mc, &dio->mc, sizeof(p->mc)); -#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ +#endif /* RPL_WITH_MC */ if(rpl_process_parent_event(instance, p) == 0) { PRINTF("RPL: The candidate parent is rejected\n"); return; @@ -1298,16 +1616,9 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) } /* We received a new DIO from our preferred parent. * Call uip_ds6_defrt_add to set a fresh value for the lifetime counter */ - uip_ds6_defrt_add(from, RPL_LIFETIME(instance, instance->default_lifetime)); + uip_ds6_defrt_add(from, RPL_DEFAULT_ROUTE_INFINITE_LIFETIME ? 0 : RPL_LIFETIME(instance, instance->default_lifetime)); } p->dtsn = dio->dtsn; } /*---------------------------------------------------------------------------*/ -void -rpl_lock_parent(rpl_parent_t *p) -{ - nbr_table_lock(rpl_parents, p); -} -/*---------------------------------------------------------------------------*/ -#endif /* UIP_CONF_IPV6 */ /** @} */ diff --git a/core/net/rpl/rpl-ext-header.c b/core/net/rpl/rpl-ext-header.c index 4913e2aee..b6d17d4a9 100644 --- a/core/net/rpl/rpl-ext-header.c +++ b/core/net/rpl/rpl-ext-header.c @@ -1,7 +1,3 @@ -/** - * \addtogroup uip6 - * @{ - */ /* * Copyright (c) 2009, Swedish Institute of Computer Science. * All rights reserved. @@ -32,6 +28,7 @@ * * This file is part of the Contiki operating system. */ + /** * \file * Management of extension headers for ContikiRPL. @@ -42,10 +39,17 @@ * Nicolas Tsiftes . */ +/** + * \addtogroup uip6 + * @{ + */ + #include "net/ip/uip.h" #include "net/ip/tcpip.h" #include "net/ipv6/uip-ds6.h" #include "net/rpl/rpl-private.h" +#include "net/rpl/rpl-ns.h" +#include "net/packetbuf.h" #define DEBUG DEBUG_NONE #include "net/ip/uip-debug.h" @@ -58,18 +62,31 @@ #define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len]) #define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len]) #define UIP_HBHO_NEXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len + RPL_HOP_BY_HOP_LEN]) +#define UIP_RH_BUF ((struct uip_routing_hdr *)&uip_buf[uip_l2_l3_hdr_len]) +#define UIP_RPL_SRH_BUF ((struct uip_rpl_srh_hdr *)&uip_buf[uip_l2_l3_hdr_len + RPL_RH_LEN]) #define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset]) #define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset]) #define UIP_EXT_HDR_OPT_RPL_BUF ((struct uip_ext_hdr_opt_rpl *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset]) /*---------------------------------------------------------------------------*/ -#if UIP_CONF_IPV6 int -rpl_verify_header(int uip_ext_opt_offset) +rpl_verify_hbh_header(int uip_ext_opt_offset) { rpl_instance_t *instance; int down; + uint16_t sender_rank; uint8_t sender_closer; uip_ds6_route_t *route; + rpl_parent_t *sender = NULL; + + if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)) { + PRINTF("RPL: Hop-by-hop extension header has wrong size\n"); + return 1; + } + + if(UIP_EXT_HDR_OPT_RPL_BUF->opt_type != UIP_EXT_HDR_OPT_RPL) { + PRINTF("RPL: Non RPL Hop-by-hop option\n"); + return 1; + } if(UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) { PRINTF("RPL: Bad header option! (wrong length)\n"); @@ -86,25 +103,20 @@ rpl_verify_header(int uip_ext_opt_offset) if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_FWD_ERR) { PRINTF("RPL: Forward error!\n"); /* We should try to repair it by removing the neighbor that caused - the packet to be forwareded in the first place. We drop any - routes that go through the neighbor that sent the packet to - us. */ - route = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr); - if(route != NULL) { - uip_ds6_route_rm(route); - - /* If we are the root and just needed to remove a DAO route, - chances are that the network needs to be repaired. The - rpl_repair_root() function will cause a global repair if we - happen to be the root node of the dag. */ - PRINTF("RPL: initiate global repair\n"); - rpl_repair_root(instance->instance_id); + the packet to be forwareded in the first place. We drop any + routes that go through the neighbor that sent the packet to + us. */ + if(RPL_IS_STORING(instance)) { + route = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr); + if(route != NULL) { + uip_ds6_route_rm(route); + } } - - /* Remove the forwarding error flag and return 0 to let the packet - be forwarded again. */ - UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_FWD_ERR; - return 0; + RPL_STAT(rpl_stats.forward_errors++); + /* Trigger DAO retransmission */ + rpl_reset_dio_timer(instance); + /* drop the packet as it is not routable */ + return 1; } if(!instance->current_dag->joined) { @@ -117,64 +129,360 @@ rpl_verify_header(int uip_ext_opt_offset) down = 1; } - sender_closer = UIP_EXT_HDR_OPT_RPL_BUF->senderrank < instance->current_dag->rank; + sender_rank = UIP_HTONS(UIP_EXT_HDR_OPT_RPL_BUF->senderrank); + sender = nbr_table_get_from_lladdr(rpl_parents, packetbuf_addr(PACKETBUF_ADDR_SENDER)); + + if(sender != NULL && (UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_RANK_ERR)) { + /* A rank error was signalled, attempt to repair it by updating + * the sender's rank from ext header */ + sender->rank = sender_rank; + if(RPL_IS_NON_STORING(instance)) { + /* Select DAG and preferred parent only in non-storing mode. In storing mode, + * a parent switch would result in an immediate No-path DAO transmission, dropping + * current incoming packet. */ + rpl_select_dag(instance, sender); + } + } + + sender_closer = sender_rank < instance->current_dag->rank; PRINTF("RPL: Packet going %s, sender closer %d (%d < %d)\n", down == 1 ? "down" : "up", - sender_closer, - UIP_EXT_HDR_OPT_RPL_BUF->senderrank, - instance->current_dag->rank - ); + sender_closer, + sender_rank, + instance->current_dag->rank + ); if((down && !sender_closer) || (!down && sender_closer)) { PRINTF("RPL: Loop detected - senderrank: %d my-rank: %d sender_closer: %d\n", - UIP_EXT_HDR_OPT_RPL_BUF->senderrank, instance->current_dag->rank, + sender_rank, instance->current_dag->rank, sender_closer); + /* Attempt to repair the loop by sending a unicast DIO back to the sender + * so that it gets a fresh update of our rank. */ + if(sender != NULL) { + instance->unicast_dio_target = sender; + rpl_schedule_unicast_dio_immediately(instance); + } if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_RANK_ERR) { + RPL_STAT(rpl_stats.loop_errors++); PRINTF("RPL: Rank error signalled in RPL option!\n"); - /* We should try to repair it, not implemented for the moment */ + /* Packet must be dropped and dio trickle timer reset, see RFC6550 - 11.2.2.2 */ rpl_reset_dio_timer(instance); - /* Forward the packet anyway. */ - return 0; + return 1; } PRINTF("RPL: Single error tolerated\n"); + RPL_STAT(rpl_stats.loop_warnings++); UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_RANK_ERR; return 0; } PRINTF("RPL: Rank OK\n"); - return 0; } /*---------------------------------------------------------------------------*/ -static void -set_rpl_opt(unsigned uip_ext_opt_offset) +#if RPL_WITH_NON_STORING +int +rpl_srh_get_next_hop(uip_ipaddr_t *ipaddr) { - uint8_t temp_len; + uint8_t *uip_next_hdr; + int last_uip_ext_len = uip_ext_len; + rpl_dag_t *dag; + rpl_ns_node_t *dest_node; + rpl_ns_node_t *root_node; - memmove(UIP_HBHO_NEXT_BUF, UIP_EXT_BUF, uip_len - UIP_IPH_LEN); - memset(UIP_HBHO_BUF, 0, RPL_HOP_BY_HOP_LEN); - UIP_HBHO_BUF->next = UIP_IP_BUF->proto; - UIP_IP_BUF->proto = UIP_PROTO_HBHO; - UIP_HBHO_BUF->len = RPL_HOP_BY_HOP_LEN - 8; - UIP_EXT_HDR_OPT_RPL_BUF->opt_type = UIP_EXT_HDR_OPT_RPL; - UIP_EXT_HDR_OPT_RPL_BUF->opt_len = RPL_HDR_OPT_LEN; - UIP_EXT_HDR_OPT_RPL_BUF->flags = 0; - UIP_EXT_HDR_OPT_RPL_BUF->instance = 0; - UIP_EXT_HDR_OPT_RPL_BUF->senderrank = 0; - uip_len += RPL_HOP_BY_HOP_LEN; + uip_ext_len = 0; + uip_next_hdr = &UIP_IP_BUF->proto; + + /* Look for routing header */ + while(uip_next_hdr != NULL && *uip_next_hdr != UIP_PROTO_ROUTING) { + switch(*uip_next_hdr) { + case UIP_PROTO_TCP: + case UIP_PROTO_UDP: + case UIP_PROTO_ICMP6: + case UIP_PROTO_NONE: + uip_next_hdr = NULL; + break; + case UIP_PROTO_HBHO: + case UIP_PROTO_DESTO: + case UIP_PROTO_FRAG: + /* Move to next header */ + if(uip_next_hdr != &UIP_IP_BUF->proto) { + uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; + } + uip_next_hdr = &UIP_EXT_BUF->next; + break; + default: + break; + } + } + + dag = rpl_get_dag(&UIP_IP_BUF->destipaddr); + root_node = rpl_ns_get_node(dag, &dag->dag_id); + dest_node = rpl_ns_get_node(dag, &UIP_IP_BUF->destipaddr); + + if((uip_next_hdr != NULL && *uip_next_hdr == UIP_PROTO_ROUTING + && UIP_RH_BUF->routing_type == RPL_RH_TYPE_SRH) || + (dest_node != NULL && root_node != NULL && + dest_node->parent == root_node)) { + /* Routing header found or the packet destined for a direct child of the root. + * The next hop should be already copied as the IPv6 destination + * address, via rpl_process_srh_header. We turn this address into a link-local to enable + * forwarding to next hop */ + uip_ipaddr_copy(ipaddr, &UIP_IP_BUF->destipaddr); + uip_create_linklocal_prefix(ipaddr); + uip_ext_len = last_uip_ext_len; + return 1; + } + + uip_ext_len = last_uip_ext_len; + return 0; +} +/*---------------------------------------------------------------------------*/ +int +rpl_process_srh_header(void) +{ + uint8_t *uip_next_hdr; + int last_uip_ext_len = uip_ext_len; + + uip_ext_len = 0; + uip_next_hdr = &UIP_IP_BUF->proto; + + /* Look for routing header */ + while(uip_next_hdr != NULL && *uip_next_hdr != UIP_PROTO_ROUTING) { + switch(*uip_next_hdr) { + case UIP_PROTO_TCP: + case UIP_PROTO_UDP: + case UIP_PROTO_ICMP6: + case UIP_PROTO_NONE: + uip_next_hdr = NULL; + break; + case UIP_PROTO_HBHO: + case UIP_PROTO_DESTO: + case UIP_PROTO_FRAG: + /* Move to next header */ + if(uip_next_hdr != &UIP_IP_BUF->proto) { + uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; + } + uip_next_hdr = &UIP_EXT_BUF->next; + break; + default: + break; + } + } + + if(uip_next_hdr != NULL && *uip_next_hdr == UIP_PROTO_ROUTING + && UIP_RH_BUF->routing_type == RPL_RH_TYPE_SRH) { + /* SRH found, now look for next hop */ + uint8_t cmpri, cmpre; + uint8_t ext_len; + uint8_t padding; + uint8_t path_len; + uint8_t segments_left; + uip_ipaddr_t current_dest_addr; + + segments_left = UIP_RH_BUF->seg_left; + ext_len = (UIP_RH_BUF->len * 8) + 8; + cmpri = UIP_RPL_SRH_BUF->cmpr >> 4; + cmpre = UIP_RPL_SRH_BUF->cmpr & 0x0f; + padding = UIP_RPL_SRH_BUF->pad >> 4; + path_len = ((ext_len - padding - RPL_RH_LEN - RPL_SRH_LEN - (16 - cmpre)) / (16 - cmpri)) + 1; + (void)path_len; + + PRINTF("RPL: read SRH, path len %u, segments left %u, Cmpri %u, Cmpre %u, ext len %u (padding %u)\n", + path_len, segments_left, cmpri, cmpre, ext_len, padding); + + if(segments_left == 0) { + /* We are the final destination, do nothing */ + } else { + uint8_t i = path_len - segments_left; /* The index of the next address to be visited */ + uint8_t *addr_ptr = ((uint8_t *)UIP_RH_BUF) + RPL_RH_LEN + RPL_SRH_LEN + (i * (16 - cmpri)); + uint8_t cmpr = segments_left == 1 ? cmpre : cmpri; + + /* As per RFC6554: swap the IPv6 destination address and address[i] */ + + /* First, copy the current IPv6 destination address */ + uip_ipaddr_copy(¤t_dest_addr, &UIP_IP_BUF->destipaddr); + /* Second, update the IPv6 destination address with addresses[i] */ + memcpy(((uint8_t *)&UIP_IP_BUF->destipaddr) + cmpr, addr_ptr, 16 - cmpr); + /* Third, write current_dest_addr to addresses[i] */ + memcpy(addr_ptr, ((uint8_t *)¤t_dest_addr) + cmpr, 16 - cmpr); + + /* Update segments left field */ + UIP_RH_BUF->seg_left--; + + PRINTF("RPL: SRH next hop "); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("\n"); + } + uip_ext_len = last_uip_ext_len; + return 1; + } + + uip_ext_len = last_uip_ext_len; + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +count_matching_bytes(const void *p1, const void *p2, size_t n) +{ + int i = 0; + for(i = 0; i < n; i++) { + if(((uint8_t *)p1)[i] != ((uint8_t *)p2)[i]) { + return i; + } + } + return n; +} +/*---------------------------------------------------------------------------*/ +static int +insert_srh_header(void) +{ + /* Implementation of RFC6554 */ + uint8_t temp_len; + uint8_t path_len; + uint8_t ext_len; + uint8_t cmpri, cmpre; /* ComprI and ComprE fields of the RPL Source Routing Header */ + uint8_t *hop_ptr; + uint8_t padding; + rpl_ns_node_t *dest_node; + rpl_ns_node_t *root_node; + rpl_ns_node_t *node; + rpl_dag_t *dag; + uip_ipaddr_t node_addr; + + PRINTF("RPL: SRH creating source routing header with destination "); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF(" \n"); + + /* Construct source route. We do not do this recursively to keep the runtime stack usage constant. */ + + /* Get link of the destination and root */ + dag = rpl_get_dag(&UIP_IP_BUF->destipaddr); + + if(dag == NULL) { + PRINTF("RPL: SRH DAG not found\n"); + return 0; + } + + dest_node = rpl_ns_get_node(dag, &UIP_IP_BUF->destipaddr); + if(dest_node == NULL) { + /* The destination is not found, skip SRH insertion */ + return 1; + } + + root_node = rpl_ns_get_node(dag, &dag->dag_id); + if(root_node == NULL) { + PRINTF("RPL: SRH root node not found\n"); + return 0; + } + + if(!rpl_ns_is_node_reachable(dag, &UIP_IP_BUF->destipaddr)) { + PRINTF("RPL: SRH no path found to destination\n"); + return 0; + } + + /* Compute path length and compression factors (we use cmpri == cmpre) */ + path_len = 0; + node = dest_node->parent; + /* For simplicity, we use cmpri = cmpre */ + cmpri = 15; + cmpre = 15; + + if(node == root_node) { + PRINTF("RPL: SRH no need to insert SRH\n"); + return 0; + } + + while(node != NULL && node != root_node) { + + rpl_ns_get_node_global_addr(&node_addr, node); + + /* How many bytes in common between all nodes in the path? */ + cmpri = MIN(cmpri, count_matching_bytes(&node_addr, &UIP_IP_BUF->destipaddr, 16)); + cmpre = cmpri; + + PRINTF("RPL: SRH Hop "); + PRINT6ADDR(&node_addr); + PRINTF("\n"); + node = node->parent; + path_len++; + } + + /* Extension header length: fixed headers + (n-1) * (16-ComprI) + (16-ComprE)*/ + ext_len = RPL_RH_LEN + RPL_SRH_LEN + + (path_len - 1) * (16 - cmpre) + + (16 - cmpri); + + padding = ext_len % 8 == 0 ? 0 : (8 - (ext_len % 8)); + ext_len += padding; + + PRINTF("RPL: SRH Path len: %u, ComprI %u, ComprE %u, ext len %u (padding %u)\n", + path_len, cmpri, cmpre, ext_len, padding); + + /* Check if there is enough space to store the extension header */ + if(uip_len + ext_len > UIP_BUFSIZE) { + PRINTF("RPL: Packet too long: impossible to add source routing header (%u bytes)\n", ext_len); + return 1; + } + + /* Move existing ext headers and payload uip_ext_len further */ + memmove(uip_buf + uip_l2_l3_hdr_len + ext_len, + uip_buf + uip_l2_l3_hdr_len, uip_len - UIP_IPH_LEN); + memset(uip_buf + uip_l2_l3_hdr_len, 0, ext_len); + + /* Insert source routing header */ + UIP_RH_BUF->next = UIP_IP_BUF->proto; + UIP_IP_BUF->proto = UIP_PROTO_ROUTING; + + /* Initialize IPv6 Routing Header */ + UIP_RH_BUF->len = (ext_len - 8) / 8; + UIP_RH_BUF->routing_type = RPL_RH_TYPE_SRH; + UIP_RH_BUF->seg_left = path_len; + + /* Initialize RPL Source Routing Header */ + UIP_RPL_SRH_BUF->cmpr = (cmpri << 4) + cmpre; + UIP_RPL_SRH_BUF->pad = padding << 4; + + /* Initialize addresses field (the actual source route). + * From last to first. */ + node = dest_node; + hop_ptr = ((uint8_t *)UIP_RH_BUF) + ext_len - padding; /* Pointer where to write the next hop compressed address */ + + while(node != NULL && node->parent != root_node) { + rpl_ns_get_node_global_addr(&node_addr, node); + + hop_ptr -= (16 - cmpri); + memcpy(hop_ptr, ((uint8_t*)&node_addr) + cmpri, 16 - cmpri); + + node = node->parent; + } + + /* The next hop (i.e. node whose parent is the root) is placed as the current IPv6 destination */ + rpl_ns_get_node_global_addr(&node_addr, node); + uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &node_addr); + + /* In-place update of IPv6 length field */ temp_len = UIP_IP_BUF->len[1]; - UIP_IP_BUF->len[1] += UIP_HBHO_BUF->len + 8; + UIP_IP_BUF->len[1] += ext_len; if(UIP_IP_BUF->len[1] < temp_len) { UIP_IP_BUF->len[0]++; } + + uip_ext_len += ext_len; + uip_len += ext_len; + + return 1; } +#else /* RPL_WITH_NON_STORING */ +int insert_srh_header(void); +#endif /* RPL_WITH_NON_STORING */ /*---------------------------------------------------------------------------*/ -void -rpl_update_header_empty(void) +static int +update_hbh_header(void) { rpl_instance_t *instance; int uip_ext_opt_offset; int last_uip_ext_len; + rpl_parent_t *parent; last_uip_ext_len = uip_ext_len; uip_ext_len = 0; @@ -184,70 +492,129 @@ rpl_update_header_empty(void) switch(UIP_IP_BUF->proto) { case UIP_PROTO_HBHO: - if(UIP_HBHO_BUF->len != RPL_HOP_BY_HOP_LEN - 8) { - PRINTF("RPL: Non RPL Hop-by-hop options support not implemented\n"); + if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)) { + PRINTF("RPL: Hop-by-hop extension header has wrong size\n"); uip_ext_len = last_uip_ext_len; - return; + return 1; + } + if(UIP_EXT_HDR_OPT_RPL_BUF->opt_type != UIP_EXT_HDR_OPT_RPL) { + PRINTF("RPL: Non RPL Hop-by-hop option support not implemented\n"); + uip_ext_len = last_uip_ext_len; + return 1; + } + if(UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) { + PRINTF("RPL: RPL Hop-by-hop option has wrong length\n"); + uip_ext_len = last_uip_ext_len; + return 1; } instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance); if(instance == NULL || !instance->used || !instance->current_dag->joined) { PRINTF("RPL: Unable to add hop-by-hop extension header: incorrect instance\n"); - return; + return 1; } break; default: - PRINTF("RPL: No hop-by-hop option found, creating it\n"); - if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE) { - PRINTF("RPL: Packet too long: impossible to add hop-by-hop option\n"); - uip_ext_len = last_uip_ext_len; - return; - } - set_rpl_opt(uip_ext_opt_offset); - uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN; - return; + PRINTF("RPL: No hop-by-hop option found\n"); + return 1; } switch(UIP_EXT_HDR_OPT_BUF->type) { case UIP_EXT_HDR_OPT_RPL: PRINTF("RPL: Updating RPL option\n"); - UIP_EXT_HDR_OPT_RPL_BUF->senderrank = instance->current_dag->rank; + UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(instance->current_dag->rank); - /* Check the direction of the down flag, as per Section 11.2.2.3, - which states that if a packet is going down it should in - general not go back up again. If this happens, a - RPL_HDR_OPT_FWD_ERR should be flagged. */ - if((UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN)) { - if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) { - UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_FWD_ERR; - PRINTF("RPL forwarding error\n"); - } - } else { - /* Set the down extension flag correctly as described in Section - 11.2 of RFC6550. If the packet progresses along a DAO route, - the down flag should be set. */ - if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) { - /* No route was found, so this packet will go towards the RPL - root. If so, we should not set the down flag. */ - UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_DOWN; - PRINTF("RPL option going up\n"); + if(RPL_IS_STORING(instance)) { /* In non-storing mode, downwards traffic does not have the HBH option */ + /* Check the direction of the down flag, as per Section 11.2.2.3, + which states that if a packet is going down it should in + general not go back up again. If this happens, a + RPL_HDR_OPT_FWD_ERR should be flagged. */ + if((UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN)) { + if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) { + UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_FWD_ERR; + PRINTF("RPL forwarding error\n"); + /* We should send back the packet to the originating parent, + but it is not feasible yet, so we send a No-Path DAO instead */ + PRINTF("RPL generate No-Path DAO\n"); + parent = rpl_get_parent((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); + if(parent != NULL) { + dao_output_target(parent, &UIP_IP_BUF->destipaddr, RPL_ZERO_LIFETIME); + } + /* Drop packet */ + return 0; + } } else { - /* A DAO route was found so we set the down flag. */ - UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_DOWN; - PRINTF("RPL option going down\n"); + /* Set the down extension flag correctly as described in Section + 11.2 of RFC6550. If the packet progresses along a DAO route, + the down flag should be set. */ + if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) { + /* No route was found, so this packet will go towards the RPL + root. If so, we should not set the down flag. */ + UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_DOWN; + PRINTF("RPL option going up\n"); + } else { + /* A DAO route was found so we set the down flag. */ + UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_DOWN; + PRINTF("RPL option going down\n"); + } } } uip_ext_len = last_uip_ext_len; - return; + return 1; default: PRINTF("RPL: Multi Hop-by-hop options not implemented\n"); uip_ext_len = last_uip_ext_len; - return; + return 1; } } /*---------------------------------------------------------------------------*/ +static int +insert_hbh_header(void) +{ + int uip_ext_opt_offset; + int last_uip_ext_len; + uint8_t temp_len; + + last_uip_ext_len = uip_ext_len; + uip_ext_len = 0; + uip_ext_opt_offset = 2; + + /* Insert hop-by-hop header */ + PRINTF("RPL: Creating hop-by-hop option\n"); + if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE) { + PRINTF("RPL: Packet too long: impossible to add hop-by-hop option\n"); + uip_ext_len = last_uip_ext_len; + return 0; + } + + /* Move existing ext headers and payload UIP_EXT_BUF further */ + memmove(UIP_HBHO_NEXT_BUF, UIP_EXT_BUF, uip_len - UIP_IPH_LEN); + memset(UIP_HBHO_BUF, 0, RPL_HOP_BY_HOP_LEN); + + /* Update IP and HBH protocol and fields */ + UIP_HBHO_BUF->next = UIP_IP_BUF->proto; + UIP_IP_BUF->proto = UIP_PROTO_HBHO; + + /* Initialize HBH option */ + UIP_HBHO_BUF->len = (RPL_HOP_BY_HOP_LEN - 8) / 8; + UIP_EXT_HDR_OPT_RPL_BUF->opt_type = UIP_EXT_HDR_OPT_RPL; + UIP_EXT_HDR_OPT_RPL_BUF->opt_len = RPL_HDR_OPT_LEN; + UIP_EXT_HDR_OPT_RPL_BUF->flags = 0; + UIP_EXT_HDR_OPT_RPL_BUF->instance = 0; + UIP_EXT_HDR_OPT_RPL_BUF->senderrank = 0; + uip_len += RPL_HOP_BY_HOP_LEN; + temp_len = UIP_IP_BUF->len[1]; + UIP_IP_BUF->len[1] += RPL_HOP_BY_HOP_LEN; + if(UIP_IP_BUF->len[1] < temp_len) { + UIP_IP_BUF->len[0]++; + } + + uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN; + return 1; +} +/*---------------------------------------------------------------------------*/ int -rpl_update_header_final(uip_ipaddr_t *addr) +rpl_finalize_header(uip_ipaddr_t *addr) { rpl_parent_t *parent; int uip_ext_opt_offset; @@ -258,10 +625,10 @@ rpl_update_header_final(uip_ipaddr_t *addr) uip_ext_opt_offset = 2; if(UIP_IP_BUF->proto == UIP_PROTO_HBHO) { - if(UIP_HBHO_BUF->len != RPL_HOP_BY_HOP_LEN - 8) { + if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)) { PRINTF("RPL: Non RPL Hop-by-hop options support not implemented\n"); uip_ext_len = last_uip_ext_len; - return 0; + return 1; } if(UIP_EXT_HDR_OPT_BUF->type == UIP_EXT_HDR_OPT_RPL) { @@ -269,93 +636,111 @@ rpl_update_header_final(uip_ipaddr_t *addr) PRINTF("RPL: Updating RPL option\n"); if(default_instance == NULL || !default_instance->used || !default_instance->current_dag->joined) { PRINTF("RPL: Unable to add hop-by-hop extension header: incorrect default instance\n"); - return 1; + return 0; } parent = rpl_find_parent(default_instance->current_dag, addr); if(parent == NULL || parent != parent->dag->preferred_parent) { UIP_EXT_HDR_OPT_RPL_BUF->flags = RPL_HDR_OPT_DOWN; } UIP_EXT_HDR_OPT_RPL_BUF->instance = default_instance->instance_id; - UIP_EXT_HDR_OPT_RPL_BUF->senderrank = default_instance->current_dag->rank; - uip_ext_len = last_uip_ext_len; + UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(default_instance->current_dag->rank); } } } - return 0; + return 1; } /*---------------------------------------------------------------------------*/ void rpl_remove_header(void) { uint8_t temp_len; + uint8_t rpl_ext_hdr_len; + uint8_t *uip_next_hdr; uip_ext_len = 0; + uip_next_hdr = &UIP_IP_BUF->proto; - PRINTF("RPL: Verifying the presence of the RPL header option\n"); - switch(UIP_IP_BUF->proto){ - case UIP_PROTO_HBHO: - PRINTF("RPL: Removing the RPL header option\n"); - UIP_IP_BUF->proto = UIP_HBHO_BUF->next; - temp_len = UIP_IP_BUF->len[1]; - uip_len -= UIP_HBHO_BUF->len + 8; - UIP_IP_BUF->len[1] -= UIP_HBHO_BUF->len + 8; - if(UIP_IP_BUF->len[1] > temp_len) { - UIP_IP_BUF->len[0]--; + PRINTF("RPL: Verifying the presence of RPL extension headers\n"); + + /* Look for hop-by-hop and routing headers */ + while(uip_next_hdr != NULL) { + switch(*uip_next_hdr) { + case UIP_PROTO_TCP: + case UIP_PROTO_UDP: + case UIP_PROTO_ICMP6: + case UIP_PROTO_NONE: + return; + case UIP_PROTO_HBHO: + case UIP_PROTO_ROUTING: + /* Remove hop-by-hop and routing headers */ + *uip_next_hdr = UIP_EXT_BUF->next; + rpl_ext_hdr_len = (UIP_EXT_BUF->len * 8) + 8; + temp_len = UIP_IP_BUF->len[1]; + uip_len -= rpl_ext_hdr_len; + UIP_IP_BUF->len[1] -= rpl_ext_hdr_len; + if(UIP_IP_BUF->len[1] > temp_len) { + UIP_IP_BUF->len[0]--; + } + PRINTF("RPL: Removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len); + memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN); + break; + default: + /* Move to next header */ + if(uip_next_hdr != &UIP_IP_BUF->proto) { + uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; + } + uip_next_hdr = &UIP_EXT_BUF->next; + break; } - memmove(UIP_EXT_BUF, UIP_HBHO_NEXT_BUF, uip_len - UIP_IPH_LEN); - break; - default: - PRINTF("RPL: No hop-by-hop Option found\n"); - } -} -/*---------------------------------------------------------------------------*/ -uint8_t -rpl_invert_header(void) -{ - uint8_t uip_ext_opt_offset; - uint8_t last_uip_ext_len; - - last_uip_ext_len = uip_ext_len; - uip_ext_len = 0; - uip_ext_opt_offset = 2; - - PRINTF("RPL: Verifying the presence of the RPL header option\n"); - switch(UIP_IP_BUF->proto) { - case UIP_PROTO_HBHO: - break; - default: - PRINTF("RPL: No hop-by-hop Option found\n"); - uip_ext_len = last_uip_ext_len; - return 0; - } - - switch (UIP_EXT_HDR_OPT_BUF->type) { - case UIP_EXT_HDR_OPT_RPL: - PRINTF("RPL: Updating RPL option (switching direction)\n"); - UIP_EXT_HDR_OPT_RPL_BUF->flags &= RPL_HDR_OPT_DOWN; - UIP_EXT_HDR_OPT_RPL_BUF->flags ^= RPL_HDR_OPT_DOWN; - UIP_EXT_HDR_OPT_RPL_BUF->senderrank = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance)->current_dag->rank; - uip_ext_len = last_uip_ext_len; - return RPL_HOP_BY_HOP_LEN; - default: - PRINTF("RPL: Multi Hop-by-hop options not implemented\n"); - uip_ext_len = last_uip_ext_len; - return 0; } } /*---------------------------------------------------------------------------*/ void rpl_insert_header(void) { - uint8_t uip_ext_opt_offset; - if(default_instance != NULL) { - uip_ext_opt_offset = 2; - if(UIP_EXT_HDR_OPT_BUF->type == UIP_EXT_HDR_OPT_RPL) { - rpl_update_header_empty(); + if(default_instance == NULL || default_instance->current_dag == NULL + || uip_is_addr_linklocal(&UIP_IP_BUF->destipaddr) || uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) { + return; + } + + if(RPL_IS_STORING(default_instance)) { + insert_hbh_header(); + } + + if(RPL_IS_NON_STORING(default_instance)) { + if(default_instance->current_dag != NULL) { + if(default_instance->current_dag->rank == ROOT_RANK(default_instance)) { + insert_srh_header(); + } else { + insert_hbh_header(); + } } } } /*---------------------------------------------------------------------------*/ -#endif /* UIP_CONF_IPV6 */ +int +rpl_update_header(void) +{ + if(default_instance == NULL) { + return 0; + } + + if(default_instance->current_dag != NULL) { + if(default_instance->current_dag->rank == ROOT_RANK(default_instance)) { + /* At the root, remove headers if any, and insert SRH or HBH + * (SRH is inserted only if the destination is in the DODAG) */ + rpl_remove_header(); + if(RPL_IS_NON_STORING(default_instance)) { + return insert_srh_header(); + } else { + return insert_hbh_header(); + } + } else { + return update_hbh_header(); + } + } else { + return 0; + } +} /** @}*/ diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 170c2cd11..5fac66d7c 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -1,7 +1,3 @@ -/** - * \addtogroup uip6 - * @{ - */ /* * Copyright (c) 2010, Swedish Institute of Computer Science. * All rights reserved. @@ -33,6 +29,7 @@ * This file is part of the Contiki operating system. * */ + /** * \file * ICMP6 I/O for RPL control messages. @@ -43,14 +40,21 @@ * George Oikonomou (multicast) */ +/** + * \addtogroup uip6 + * @{ + */ + #include "net/ip/tcpip.h" #include "net/ip/uip.h" #include "net/ipv6/uip-ds6.h" #include "net/ipv6/uip-nd6.h" #include "net/ipv6/uip-icmp6.h" #include "net/rpl/rpl-private.h" +#include "net/rpl/rpl-ns.h" #include "net/packetbuf.h" #include "net/ipv6/multicast/uip-mcast6.h" +#include "random.h" #include #include @@ -59,11 +63,10 @@ #include "net/ip/uip-debug.h" -#if UIP_CONF_IPV6 /*---------------------------------------------------------------------------*/ #define RPL_DIO_GROUNDED 0x80 #define RPL_DIO_MOP_SHIFT 3 -#define RPL_DIO_MOP_MASK 0x3c +#define RPL_DIO_MOP_MASK 0x38 #define RPL_DIO_PREFERENCE_MASK 0x07 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) @@ -75,6 +78,9 @@ static void dio_input(void); static void dao_input(void); static void dao_ack_input(void); +static void dao_output_target_seq(rpl_parent_t *parent, uip_ipaddr_t *prefix, + uint8_t lifetime, uint8_t seq_no); + /* some debug callbacks useful when debugging RPL networks */ #ifdef RPL_DEBUG_DIO_INPUT void RPL_DEBUG_DIO_INPUT(uip_ipaddr_t *, rpl_dio_t *); @@ -86,9 +92,7 @@ void RPL_DEBUG_DAO_OUTPUT(rpl_parent_t *); static uint8_t dao_sequence = RPL_LOLLIPOP_INIT; -extern rpl_of_t RPL_OF; - -#if RPL_CONF_MULTICAST +#if RPL_WITH_MULTICAST static uip_mcast6_route_t *mcast_group; #endif /*---------------------------------------------------------------------------*/ @@ -98,6 +102,40 @@ UIP_ICMP6_HANDLER(dio_handler, ICMP6_RPL, RPL_CODE_DIO, dio_input); UIP_ICMP6_HANDLER(dao_handler, ICMP6_RPL, RPL_CODE_DAO, dao_input); UIP_ICMP6_HANDLER(dao_ack_handler, ICMP6_RPL, RPL_CODE_DAO_ACK, dao_ack_input); /*---------------------------------------------------------------------------*/ + +#if RPL_WITH_DAO_ACK +static uip_ds6_route_t * +find_route_entry_by_dao_ack(uint8_t seq) +{ + uip_ds6_route_t *re; + re = uip_ds6_route_head(); + while(re != NULL) { + if(re->state.dao_seqno_out == seq && RPL_ROUTE_IS_DAO_PENDING(re)) { + /* found it! */ + return re; + } + re = uip_ds6_route_next(re); + } + return NULL; +} +#endif /* RPL_WITH_DAO_ACK */ + +#if RPL_WITH_STORING +/* prepare for forwarding of DAO */ +static uint8_t +prepare_for_dao_fwd(uint8_t sequence, uip_ds6_route_t *rep) +{ + /* not pending - or pending but not a retransmission */ + RPL_LOLLIPOP_INCREMENT(dao_sequence); + + /* set DAO pending and sequence numbers */ + rep->state.dao_seqno_in = sequence; + rep->state.dao_seqno_out = dao_sequence; + RPL_ROUTE_SET_DAO_PENDING(rep); + return dao_sequence; +} +#endif /* RPL_WITH_STORING */ +/*---------------------------------------------------------------------------*/ static int get_global_addr(uip_ipaddr_t *addr) { @@ -108,7 +146,7 @@ get_global_addr(uip_ipaddr_t *addr) state = uip_ds6_if.addr_list[i].state; if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { - if(!uip_is_addr_link_local(&uip_ds6_if.addr_list[i].ipaddr)) { + if(!uip_is_addr_linklocal(&uip_ds6_if.addr_list[i].ipaddr)) { memcpy(addr, &uip_ds6_if.addr_list[i].ipaddr, sizeof(uip_ipaddr_t)); return 1; } @@ -146,6 +184,34 @@ set16(uint8_t *buffer, int pos, uint16_t value) buffer[pos++] = value & 0xff; } /*---------------------------------------------------------------------------*/ +uip_ds6_nbr_t * +rpl_icmp6_update_nbr_table(uip_ipaddr_t *from, nbr_table_reason_t reason, void *data) +{ + uip_ds6_nbr_t *nbr; + + if((nbr = uip_ds6_nbr_lookup(from)) == NULL) { + if((nbr = uip_ds6_nbr_add(from, (uip_lladdr_t *) + packetbuf_addr(PACKETBUF_ADDR_SENDER), + 0, NBR_REACHABLE, reason, data)) != NULL) { + PRINTF("RPL: Neighbor added to neighbor cache "); + PRINT6ADDR(from); + PRINTF(", "); + PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); + PRINTF("\n"); + } + } + + if(nbr != NULL) { +#if UIP_ND6_SEND_NA + /* set reachable timer if we added or found the nbr entry - and update + neighbor entry to reachable to avoid sending NS/NA, etc. */ + stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000); + nbr->state = NBR_REACHABLE; +#endif /* UIP_ND6_SEND_NA */ + } + return nbr; + } +/*---------------------------------------------------------------------------*/ static void dis_input(void) { @@ -169,12 +235,23 @@ dis_input(void) rpl_reset_dio_timer(instance); } else { #endif /* !RPL_LEAF_ONLY */ - PRINTF("RPL: Unicast DIS, reply to sender\n"); - dio_output(instance, &UIP_IP_BUF->srcipaddr); + /* Check if this neighbor should be added according to the policy. */ + if(rpl_icmp6_update_nbr_table(&UIP_IP_BUF->srcipaddr, + NBR_TABLE_REASON_RPL_DIS, NULL) == NULL) { + PRINTF("RPL: Out of Memory, not sending unicast DIO, DIS from "); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF(", "); + PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); + PRINTF("\n"); + } else { + PRINTF("RPL: Unicast DIS, reply to sender\n"); + dio_output(instance, &UIP_IP_BUF->srcipaddr); + } + /* } */ } } } - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ void @@ -217,7 +294,6 @@ dio_input(void) int i; int len; uip_ipaddr_t from; - uip_ds6_nbr_t *nbr; memset(&dio, 0, sizeof(dio)); @@ -227,7 +303,7 @@ dio_input(void) dio.dag_redund = RPL_DIO_REDUNDANCY; dio.dag_min_hoprankinc = RPL_MIN_HOPRANKINC; dio.dag_max_rankinc = RPL_MAX_RANKINC; - dio.ocp = RPL_OF.ocp; + dio.ocp = RPL_OF_OCP; dio.default_lifetime = RPL_DEFAULT_LIFETIME; dio.lifetime_unit = RPL_DEFAULT_LIFETIME_UNIT; @@ -238,29 +314,6 @@ dio_input(void) PRINT6ADDR(&from); PRINTF("\n"); - if((nbr = uip_ds6_nbr_lookup(&from)) == NULL) { - if((nbr = uip_ds6_nbr_add(&from, (uip_lladdr_t *) - packetbuf_addr(PACKETBUF_ADDR_SENDER), - 0, NBR_REACHABLE)) != NULL) { - /* set reachable timer */ - stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000); - PRINTF("RPL: Neighbor added to neighbor cache "); - PRINT6ADDR(&from); - PRINTF(", "); - PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); - PRINTF("\n"); - } else { - PRINTF("RPL: Out of memory, dropping DIO from "); - PRINT6ADDR(&from); - PRINTF(", "); - PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); - PRINTF("\n"); - return; - } - } else { - PRINTF("RPL: Neighbor already in neighbor cache\n"); - } - buffer_length = uip_len - uip_l3_icmp_hdr_len; /* Process the DIO base option. */ @@ -305,7 +358,7 @@ dio_input(void) if(len + i > buffer_length) { PRINTF("RPL: Invalid DIO packet\n"); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } PRINTF("RPL: DIO option %u, length: %u\n", subopt_type, len - 2); @@ -315,7 +368,7 @@ dio_input(void) if(len < 6) { PRINTF("RPL: Invalid DAG MC, len = %d\n", len); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } dio.mc.type = buffer[i + 2]; dio.mc.flags = buffer[i + 3] << 1; @@ -341,14 +394,14 @@ dio_input(void) dio.mc.obj.energy.energy_est = buffer[i + 7]; } else { PRINTF("RPL: Unhandled DAG MC type: %u\n", (unsigned)dio.mc.type); - return; + goto discard; } break; case RPL_OPTION_ROUTE_INFO: if(len < 9) { PRINTF("RPL: Invalid destination prefix option, len = %d\n", len); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } /* The flags field includes the preference value. */ @@ -364,7 +417,7 @@ dio_input(void) } else { PRINTF("RPL: Invalid route info option, len = %d\n", len); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } break; @@ -372,7 +425,7 @@ dio_input(void) if(len != 16) { PRINTF("RPL: Invalid DAG configuration option, len = %d\n", len); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } /* Path control field not yet implemented - at i + 2 */ @@ -394,7 +447,7 @@ dio_input(void) if(len != 32) { PRINTF("RPL: Invalid DAG prefix info, len != 32\n"); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } dio.prefix_info.length = buffer[i + 2]; dio.prefix_info.flags = buffer[i + 3]; @@ -417,7 +470,8 @@ dio_input(void) rpl_process_dio(&from, &dio); - uip_len = 0; + discard: + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ void @@ -425,6 +479,7 @@ dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr) { unsigned char *buffer; int pos; + int is_root; rpl_dag_t *dag = instance->current_dag; #if !RPL_LEAF_ONLY uip_ipaddr_t addr; @@ -445,6 +500,7 @@ dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr) buffer = UIP_ICMP_PAYLOAD; buffer[pos++] = instance->instance_id; buffer[pos++] = dag->version; + is_root = (dag->rank == ROOT_RANK(instance)); #if RPL_LEAF_ONLY PRINTF("RPL: LEAF ONLY DIO rank set to INFINITE_RANK\n"); @@ -465,8 +521,12 @@ dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr) buffer[pos++] = instance->dtsn_out; - /* always request new DAO to refresh route */ - RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); + if(RPL_DIO_REFRESH_DAO_ROUTES && is_root && uc_addr == NULL) { + /* Request new DAO to refresh route. We do not do this for unicast DIO + * in order to avoid DAO messages after a DIS-DIO update, + * or upon unicast DIO probing. */ + RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); + } /* reserved 2 bytes */ buffer[pos++] = 0; /* flags */ @@ -571,8 +631,9 @@ dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr) } /*---------------------------------------------------------------------------*/ static void -dao_input(void) +dao_input_storing(void) { +#if RPL_WITH_STORING uip_ipaddr_t dao_sender_addr; rpl_dag_t *dag; rpl_instance_t *instance; @@ -596,17 +657,13 @@ dao_input(void) int learned_from; rpl_parent_t *parent; uip_ds6_nbr_t *nbr; + int is_root; prefixlen = 0; parent = NULL; uip_ipaddr_copy(&dao_sender_addr, &UIP_IP_BUF->srcipaddr); - /* Destination Advertisement Object */ - PRINTF("RPL: Received a DAO from "); - PRINT6ADDR(&dao_sender_addr); - PRINTF("\n"); - buffer = UIP_ICMP_PAYLOAD; buffer_length = uip_len - uip_l3_icmp_hdr_len; @@ -614,11 +671,6 @@ dao_input(void) instance_id = buffer[pos++]; instance = rpl_get_instance(instance_id); - if(instance == NULL) { - PRINTF("RPL: Ignoring a DAO for an unknown RPL instance(%u)\n", - instance_id); - return; - } lifetime = instance->default_lifetime; @@ -628,6 +680,8 @@ dao_input(void) sequence = buffer[pos++]; dag = instance->current_dag; + is_root = (dag->rank == ROOT_RANK(instance)); + /* Is the DAG ID present? */ if(flags & RPL_DAO_D_FLAG) { if(memcmp(&dag->dag_id, &buffer[pos], sizeof(dag->dag_id))) { @@ -640,8 +694,12 @@ dao_input(void) learned_from = uip_is_addr_mcast(&dao_sender_addr) ? RPL_ROUTE_FROM_MULTICAST_DAO : RPL_ROUTE_FROM_UNICAST_DAO; - PRINTF("RPL: DAO from %s\n", - learned_from == RPL_ROUTE_FROM_UNICAST_DAO? "unicast": "multicast"); + /* Destination Advertisement Object */ + PRINTF("RPL: Received a (%s) DAO with sequence number %u from ", + learned_from == RPL_ROUTE_FROM_UNICAST_DAO? "unicast": "multicast", sequence); + PRINT6ADDR(&dao_sender_addr); + PRINTF("\n"); + if(learned_from == RPL_ROUTE_FROM_UNICAST_DAO) { /* Check whether this is a DAO forwarding loop. */ parent = rpl_find_parent(dag, &dao_sender_addr); @@ -652,7 +710,7 @@ dao_input(void) PRINTF("RPL: Loop detected when receiving a unicast DAO from a node with a lower rank! (%u < %u)\n", DAG_RANK(parent->rank, instance), DAG_RANK(dag->rank, instance)); parent->rank = INFINITE_RANK; - parent->updated = 1; + parent->flags |= RPL_PARENT_FLAG_UPDATED; return; } @@ -660,7 +718,7 @@ dao_input(void) if(parent != NULL && parent == dag->preferred_parent) { PRINTF("RPL: Loop detected when receiving a unicast DAO from our parent\n"); parent->rank = INFINITE_RANK; - parent->updated = 1; + parent->flags |= RPL_PARENT_FLAG_UPDATED; return; } } @@ -697,7 +755,7 @@ dao_input(void) PRINT6ADDR(&prefix); PRINTF("\n"); -#if RPL_CONF_MULTICAST +#if RPL_WITH_MULTICAST if(uip_is_addr_mcast_global(&prefix)) { mcast_group = uip_mcast6_route_add(&prefix); if(mcast_group) { @@ -714,90 +772,319 @@ dao_input(void) PRINTF("RPL: No-Path DAO received\n"); /* No-Path DAO received; invoke the route purging routine. */ if(rep != NULL && - rep->state.nopath_received == 0 && + !RPL_ROUTE_IS_NOPATH_RECEIVED(rep) && rep->length == prefixlen && uip_ds6_route_nexthop(rep) != NULL && uip_ipaddr_cmp(uip_ds6_route_nexthop(rep), &dao_sender_addr)) { PRINTF("RPL: Setting expiration timer for prefix "); PRINT6ADDR(&prefix); PRINTF("\n"); - rep->state.nopath_received = 1; - rep->state.lifetime = DAO_EXPIRATION_TIMEOUT; + RPL_ROUTE_SET_NOPATH_RECEIVED(rep); + rep->state.lifetime = RPL_NOPATH_REMOVAL_DELAY; - /* We forward the incoming no-path DAO to our parent, if we have + /* We forward the incoming No-Path DAO to our parent, if we have one. */ if(dag->preferred_parent != NULL && rpl_get_parent_ipaddr(dag->preferred_parent) != NULL) { - PRINTF("RPL: Forwarding no-path DAO to parent "); + uint8_t out_seq; + out_seq = prepare_for_dao_fwd(sequence, rep); + + PRINTF("RPL: Forwarding No-path DAO to parent - out_seq:%d", + out_seq); PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent)); PRINTF("\n"); + + buffer = UIP_ICMP_PAYLOAD; + buffer[3] = out_seq; /* add an outgoing seq no before fwd */ uip_icmp6_send(rpl_get_parent_ipaddr(dag->preferred_parent), ICMP6_RPL, RPL_CODE_DAO, buffer_length); } - if(flags & RPL_DAO_K_FLAG) { - dao_ack_output(instance, &dao_sender_addr, sequence); - } + } + /* independent if we remove or not - ACK the request */ + if(flags & RPL_DAO_K_FLAG) { + /* indicate that we accepted the no-path DAO */ + uip_clear_buf(); + dao_ack_output(instance, &dao_sender_addr, sequence, + RPL_DAO_ACK_UNCONDITIONAL_ACCEPT); } return; } - PRINTF("RPL: adding DAO route\n"); + PRINTF("RPL: Adding DAO route\n"); - if((nbr = uip_ds6_nbr_lookup(&dao_sender_addr)) == NULL) { - if((nbr = uip_ds6_nbr_add(&dao_sender_addr, - (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER), - 0, NBR_REACHABLE)) != NULL) { - /* set reachable timer */ - stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000); - PRINTF("RPL: Neighbor added to neighbor cache "); - PRINT6ADDR(&dao_sender_addr); - PRINTF(", "); - PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); - PRINTF("\n"); - } else { - PRINTF("RPL: Out of Memory, dropping DAO from "); - PRINT6ADDR(&dao_sender_addr); - PRINTF(", "); - PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); - PRINTF("\n"); - return; + /* Update and add neighbor - if no room - fail. */ + if((nbr = rpl_icmp6_update_nbr_table(&dao_sender_addr, NBR_TABLE_REASON_RPL_DAO, instance)) == NULL) { + PRINTF("RPL: Out of Memory, dropping DAO from "); + PRINT6ADDR(&dao_sender_addr); + PRINTF(", "); + PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); + PRINTF("\n"); + if(flags & RPL_DAO_K_FLAG) { + /* signal the failure to add the node */ + dao_ack_output(instance, &dao_sender_addr, sequence, + is_root ? RPL_DAO_ACK_UNABLE_TO_ADD_ROUTE_AT_ROOT : + RPL_DAO_ACK_UNABLE_TO_ACCEPT); } - } else { - PRINTF("RPL: Neighbor already in neighbor cache\n"); + return; } - rpl_lock_parent(parent); - rep = rpl_add_route(dag, &prefix, prefixlen, &dao_sender_addr); if(rep == NULL) { RPL_STAT(rpl_stats.mem_overflows++); PRINTF("RPL: Could not add a route after receiving a DAO\n"); + if(flags & RPL_DAO_K_FLAG) { + /* signal the failure to add the node */ + dao_ack_output(instance, &dao_sender_addr, sequence, + is_root ? RPL_DAO_ACK_UNABLE_TO_ADD_ROUTE_AT_ROOT : + RPL_DAO_ACK_UNABLE_TO_ACCEPT); + } return; } + /* set lifetime and clear NOPATH bit */ rep->state.lifetime = RPL_LIFETIME(instance, lifetime); - rep->state.learned_from = learned_from; + RPL_ROUTE_CLEAR_NOPATH_RECEIVED(rep); -#if RPL_CONF_MULTICAST +#if RPL_WITH_MULTICAST fwd_dao: #endif if(learned_from == RPL_ROUTE_FROM_UNICAST_DAO) { + int should_ack = 0; + + if(flags & RPL_DAO_K_FLAG) { + /* + * check if this route is already installed and we can ack now! + * not pending - and same seq-no means that we can ack. + * (e.g. the route is installed already so it will not take any + * more room that it already takes - so should be ok!) + */ + if((!RPL_ROUTE_IS_DAO_PENDING(rep) && + rep->state.dao_seqno_in == sequence) || + dag->rank == ROOT_RANK(instance)) { + should_ack = 1; + } + } + if(dag->preferred_parent != NULL && rpl_get_parent_ipaddr(dag->preferred_parent) != NULL) { + uint8_t out_seq = 0; + /* if this is pending and we get the same seq no it is a retrans */ + if(RPL_ROUTE_IS_DAO_PENDING(rep) && + rep->state.dao_seqno_in == sequence) { + /* keep the same seq-no as before for parent also */ + out_seq = rep->state.dao_seqno_out; + } else { + out_seq = prepare_for_dao_fwd(sequence, rep); + } + PRINTF("RPL: Forwarding DAO to parent "); PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent)); - PRINTF("\n"); + PRINTF(" in seq: %d out seq: %d\n", sequence, out_seq); + + buffer = UIP_ICMP_PAYLOAD; + buffer[3] = out_seq; /* add an outgoing seq no before fwd */ uip_icmp6_send(rpl_get_parent_ipaddr(dag->preferred_parent), ICMP6_RPL, RPL_CODE_DAO, buffer_length); } - if(flags & RPL_DAO_K_FLAG) { - dao_ack_output(instance, &dao_sender_addr, sequence); + if(should_ack) { + PRINTF("RPL: Sending DAO ACK\n"); + uip_clear_buf(); + dao_ack_output(instance, &dao_sender_addr, sequence, + RPL_DAO_ACK_UNCONDITIONAL_ACCEPT); } } - uip_len = 0; +#endif /* RPL_WITH_STORING */ } /*---------------------------------------------------------------------------*/ +static void +dao_input_nonstoring(void) +{ +#if RPL_WITH_NON_STORING + uip_ipaddr_t dao_sender_addr; + uip_ipaddr_t dao_parent_addr; + rpl_dag_t *dag; + rpl_instance_t *instance; + unsigned char *buffer; + uint16_t sequence; + uint8_t instance_id; + uint8_t lifetime; + uint8_t prefixlen; + uint8_t flags; + uint8_t subopt_type; + uip_ipaddr_t prefix; + uint8_t buffer_length; + int pos; + int len; + int i; + + prefixlen = 0; + + uip_ipaddr_copy(&dao_sender_addr, &UIP_IP_BUF->srcipaddr); + memset(&dao_parent_addr, 0, 16); + + buffer = UIP_ICMP_PAYLOAD; + buffer_length = uip_len - uip_l3_icmp_hdr_len; + + pos = 0; + instance_id = buffer[pos++]; + instance = rpl_get_instance(instance_id); + lifetime = instance->default_lifetime; + + flags = buffer[pos++]; + /* reserved */ + pos++; + sequence = buffer[pos++]; + + dag = instance->current_dag; + /* Is the DAG ID present? */ + if(flags & RPL_DAO_D_FLAG) { + if(memcmp(&dag->dag_id, &buffer[pos], sizeof(dag->dag_id))) { + PRINTF("RPL: Ignoring a DAO for a DAG different from ours\n"); + return; + } + pos += 16; + } + + /* Check if there are any RPL options present. */ + for(i = pos; i < buffer_length; i += len) { + subopt_type = buffer[i]; + if(subopt_type == RPL_OPTION_PAD1) { + len = 1; + } else { + /* The option consists of a two-byte header and a payload. */ + len = 2 + buffer[i + 1]; + } + + switch(subopt_type) { + case RPL_OPTION_TARGET: + /* Handle the target option. */ + prefixlen = buffer[i + 3]; + memset(&prefix, 0, sizeof(prefix)); + memcpy(&prefix, buffer + i + 4, (prefixlen + 7) / CHAR_BIT); + break; + case RPL_OPTION_TRANSIT: + /* The path sequence and control are ignored. */ + /* pathcontrol = buffer[i + 3]; + pathsequence = buffer[i + 4];*/ + lifetime = buffer[i + 5]; + if(len >= 20) { + memcpy(&dao_parent_addr, buffer + i + 6, 16); + } + break; + } + } + + PRINTF("RPL: DAO lifetime: %u, prefix length: %u prefix: ", + (unsigned)lifetime, (unsigned)prefixlen); + PRINT6ADDR(&prefix); + PRINTF(", parent: "); + PRINT6ADDR(&dao_parent_addr); + PRINTF(" \n"); + + if(lifetime == RPL_ZERO_LIFETIME) { + PRINTF("RPL: No-Path DAO received\n"); + rpl_ns_expire_parent(dag, &prefix, &dao_parent_addr); + } else { + if(rpl_ns_update_node(dag, &prefix, &dao_parent_addr, RPL_LIFETIME(instance, lifetime)) == NULL) { + PRINTF("RPL: failed to add link\n"); + return; + } + } + + if(flags & RPL_DAO_K_FLAG) { + PRINTF("RPL: Sending DAO ACK\n"); + uip_clear_buf(); + dao_ack_output(instance, &dao_sender_addr, sequence, + RPL_DAO_ACK_UNCONDITIONAL_ACCEPT); + } +#endif /* RPL_WITH_NON_STORING */ +} +/*---------------------------------------------------------------------------*/ +static void +dao_input(void) +{ + rpl_instance_t *instance; + uint8_t instance_id; + + /* Destination Advertisement Object */ + PRINTF("RPL: Received a DAO from "); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF("\n"); + + instance_id = UIP_ICMP_PAYLOAD[0]; + instance = rpl_get_instance(instance_id); + if(instance == NULL) { + PRINTF("RPL: Ignoring a DAO for an unknown RPL instance(%u)\n", + instance_id); + goto discard; + } + + if(RPL_IS_STORING(instance)) { + dao_input_storing(); + } else if(RPL_IS_NON_STORING(instance)) { + dao_input_nonstoring(); + } + + discard: + uip_clear_buf(); +} +/*---------------------------------------------------------------------------*/ +#if RPL_WITH_DAO_ACK +static void +handle_dao_retransmission(void *ptr) +{ + rpl_parent_t *parent; + uip_ipaddr_t prefix; + rpl_instance_t *instance; + + parent = ptr; + if(parent == NULL || parent->dag == NULL || parent->dag->instance == NULL) { + return; + } + instance = parent->dag->instance; + + if(instance->my_dao_transmissions >= RPL_DAO_MAX_RETRANSMISSIONS) { + /* No more retransmissions - give up. */ + if(instance->lifetime_unit == 0xffff && instance->default_lifetime == 0xff) { + /* + * ContikiRPL was previously using infinite lifetime for routes + * and no DAO_ACK configured. This probably means that the root + * and possibly other nodes might be running an old version that + * does not support DAO ack. Assume that everything is ok for + * now and let the normal repair mechanisms detect any problems. + */ + return; + } + + if(RPL_IS_STORING(instance) && instance->of->dao_ack_callback) { + /* Inform the objective function about the timeout. */ + instance->of->dao_ack_callback(parent, RPL_DAO_ACK_TIMEOUT); + } + + /* Perform local repair and hope to find another parent. */ + rpl_local_repair(instance); + return; + } + + PRINTF("RPL: will retransmit DAO - seq:%d trans:%d\n", instance->my_dao_seqno, + instance->my_dao_transmissions); + + if(get_global_addr(&prefix) == 0) { + return; + } + + ctimer_set(&instance->dao_retransmit_timer, + RPL_DAO_RETRANSMISSION_TIMEOUT / 2 + + (random_rand() % (RPL_DAO_RETRANSMISSION_TIMEOUT / 2)), + handle_dao_retransmission, parent); + + instance->my_dao_transmissions++; + dao_output_target_seq(parent, &prefix, + instance->default_lifetime, instance->my_dao_seqno); +} +#endif /* RPL_WITH_DAO_ACK */ +/*---------------------------------------------------------------------------*/ void dao_output(rpl_parent_t *parent, uint8_t lifetime) { @@ -809,18 +1096,51 @@ dao_output(rpl_parent_t *parent, uint8_t lifetime) return; } + if(parent == NULL || parent->dag == NULL || parent->dag->instance == NULL) { + return; + } + + RPL_LOLLIPOP_INCREMENT(dao_sequence); +#if RPL_WITH_DAO_ACK + /* set up the state since this will be the first transmission of DAO */ + /* retransmissions will call directly to dao_output_target_seq */ + /* keep track of my own sending of DAO for handling ack and loss of ack */ + if(lifetime != RPL_ZERO_LIFETIME) { + rpl_instance_t *instance; + instance = parent->dag->instance; + + instance->my_dao_seqno = dao_sequence; + instance->my_dao_transmissions = 1; + ctimer_set(&instance->dao_retransmit_timer, RPL_DAO_RETRANSMISSION_TIMEOUT, + handle_dao_retransmission, parent); + } +#else + /* We know that we have tried to register so now we are assuming + that we have a down-link - unless this is a zero lifetime one */ + parent->dag->instance->has_downward_route = lifetime != RPL_ZERO_LIFETIME; +#endif /* RPL_WITH_DAO_ACK */ + /* Sending a DAO with own prefix as target */ dao_output_target(parent, &prefix, lifetime); } /*---------------------------------------------------------------------------*/ void dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime) +{ + dao_output_target_seq(parent, prefix, lifetime, dao_sequence); +} +/*---------------------------------------------------------------------------*/ +static void +dao_output_target_seq(rpl_parent_t *parent, uip_ipaddr_t *prefix, + uint8_t lifetime, uint8_t seq_no) { rpl_dag_t *dag; rpl_instance_t *instance; unsigned char *buffer; uint8_t prefixlen; int pos; + uip_ipaddr_t *parent_ipaddr = NULL; + uip_ipaddr_t *dest_ipaddr = NULL; /* Destination Advertisement Object */ @@ -834,6 +1154,12 @@ dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime) return; } + parent_ipaddr = rpl_get_parent_ipaddr(parent); + if(parent_ipaddr == NULL) { + PRINTF("RPL dao_output_target error parent IP address NULL\n"); + return; + } + dag = parent->dag; if(dag == NULL) { PRINTF("RPL dao_output_target error dag NULL\n"); @@ -855,8 +1181,6 @@ dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime) #endif buffer = UIP_ICMP_PAYLOAD; - - RPL_LOLLIPOP_INCREMENT(dao_sequence); pos = 0; buffer[pos++] = instance->instance_id; @@ -864,12 +1188,14 @@ dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime) #if RPL_DAO_SPECIFY_DAG buffer[pos] |= RPL_DAO_D_FLAG; #endif /* RPL_DAO_SPECIFY_DAG */ -#if RPL_CONF_DAO_ACK - buffer[pos] |= RPL_DAO_K_FLAG; -#endif /* RPL_CONF_DAO_ACK */ +#if RPL_WITH_DAO_ACK + if(lifetime != RPL_ZERO_LIFETIME) { + buffer[pos] |= RPL_DAO_K_FLAG; + } +#endif /* RPL_WITH_DAO_ACK */ ++pos; buffer[pos++] = 0; /* reserved */ - buffer[pos++] = dao_sequence; + buffer[pos++] = seq_no; #if RPL_DAO_SPECIFY_DAG memcpy(buffer + pos, &dag->dag_id, sizeof(dag->dag_id)); pos+=sizeof(dag->dag_id); @@ -886,65 +1212,154 @@ dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime) /* Create a transit information sub-option. */ buffer[pos++] = RPL_OPTION_TRANSIT; - buffer[pos++] = 4; + buffer[pos++] = (instance->mop != RPL_MOP_NON_STORING) ? 4 : 20; buffer[pos++] = 0; /* flags - ignored */ buffer[pos++] = 0; /* path control - ignored */ buffer[pos++] = 0; /* path seq - ignored */ buffer[pos++] = lifetime; - PRINTF("RPL: Sending DAO with prefix "); + if(instance->mop != RPL_MOP_NON_STORING) { + /* Send DAO to parent */ + dest_ipaddr = parent_ipaddr; + } else { + /* Include parent global IP address */ + memcpy(buffer + pos, &parent->dag->dag_id, 8); /* Prefix */ + pos += 8; + memcpy(buffer + pos, ((const unsigned char *)parent_ipaddr) + 8, 8); /* Interface identifier */ + pos += 8; + /* Send DAO to root */ + dest_ipaddr = &parent->dag->dag_id; + } + + PRINTF("RPL: Sending a %sDAO with sequence number %u, lifetime %u, prefix ", + lifetime == RPL_ZERO_LIFETIME ? "No-Path " : "", seq_no, lifetime); + PRINT6ADDR(prefix); PRINTF(" to "); - PRINT6ADDR(rpl_get_parent_ipaddr(parent)); + PRINT6ADDR(dest_ipaddr); + PRINTF(" , parent "); + PRINT6ADDR(parent_ipaddr); PRINTF("\n"); - if(rpl_get_parent_ipaddr(parent) != NULL) { - uip_icmp6_send(rpl_get_parent_ipaddr(parent), ICMP6_RPL, RPL_CODE_DAO, pos); + if(dest_ipaddr != NULL) { + uip_icmp6_send(dest_ipaddr, ICMP6_RPL, RPL_CODE_DAO, pos); } } /*---------------------------------------------------------------------------*/ static void dao_ack_input(void) { -#if DEBUG - unsigned char *buffer; - uint8_t buffer_length; +#if RPL_WITH_DAO_ACK + + uint8_t *buffer; uint8_t instance_id; uint8_t sequence; uint8_t status; + rpl_instance_t *instance; + rpl_parent_t *parent; buffer = UIP_ICMP_PAYLOAD; - buffer_length = uip_len - uip_l3_icmp_hdr_len; instance_id = buffer[0]; sequence = buffer[2]; status = buffer[3]; - PRINTF("RPL: Received a DAO ACK with sequence number %d and status %d from ", - sequence, status); + instance = rpl_get_instance(instance_id); + if(instance == NULL) { + uip_clear_buf(); + return; + } + + if(RPL_IS_STORING(instance)) { + parent = rpl_find_parent(instance->current_dag, &UIP_IP_BUF->srcipaddr); + if(parent == NULL) { + /* not a known instance - drop the packet and ignore */ + uip_clear_buf(); + return; + } + } else { + parent = NULL; + } + + PRINTF("RPL: Received a DAO %s with sequence number %d (%d) and status %d from ", + status < 128 ? "ACK" : "NACK", + sequence, instance->my_dao_seqno, status); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF("\n"); -#endif /* DEBUG */ - uip_len = 0; + + if(sequence == instance->my_dao_seqno) { + instance->has_downward_route = status < 128; + + /* always stop the retransmit timer when the ACK arrived */ + ctimer_stop(&instance->dao_retransmit_timer); + + /* Inform objective function on status of the DAO ACK */ + if(RPL_IS_STORING(instance) && instance->of->dao_ack_callback) { + instance->of->dao_ack_callback(parent, status); + } + +#if RPL_REPAIR_ON_DAO_NACK + if(status >= RPL_DAO_ACK_UNABLE_TO_ACCEPT) { + /* + * Failed the DAO transmission - need to remove the default route. + * Trigger a local repair since we can not get our DAO in. + */ + rpl_local_repair(instance); + } +#endif + + } else if(RPL_IS_STORING(instance)) { + /* this DAO ACK should be forwarded to another recently registered route */ + uip_ds6_route_t *re; + uip_ipaddr_t *nexthop; + if((re = find_route_entry_by_dao_ack(sequence)) != NULL) { + /* pick the recorded seq no from that node and forward DAO ACK - and + clear the pending flag*/ + RPL_ROUTE_CLEAR_DAO_PENDING(re); + + nexthop = uip_ds6_route_nexthop(re); + if(nexthop == NULL) { + PRINTF("RPL: No next hop to fwd DAO ACK to\n"); + } else { + PRINTF("RPL: Fwd DAO ACK to:"); + PRINT6ADDR(nexthop); + PRINTF("\n"); + buffer[2] = re->state.dao_seqno_in; + uip_icmp6_send(nexthop, ICMP6_RPL, RPL_CODE_DAO_ACK, 4); + } + + if(status >= RPL_DAO_ACK_UNABLE_TO_ACCEPT) { + /* this node did not get in to the routing tables above... - remove */ + uip_ds6_route_rm(re); + } + } else { + PRINTF("RPL: No route entry found to forward DAO ACK (seqno %u)\n", sequence); + } + } +#endif /* RPL_WITH_DAO_ACK */ + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ void -dao_ack_output(rpl_instance_t *instance, uip_ipaddr_t *dest, uint8_t sequence) +dao_ack_output(rpl_instance_t *instance, uip_ipaddr_t *dest, uint8_t sequence, + uint8_t status) { +#if RPL_WITH_DAO_ACK unsigned char *buffer; - PRINTF("RPL: Sending a DAO ACK with sequence number %d to ", sequence); + PRINTF("RPL: Sending a DAO %s with sequence number %d to ", status < 128 ? "ACK" : "NACK", sequence); PRINT6ADDR(dest); - PRINTF("\n"); + PRINTF(" with status %d\n", status); buffer = UIP_ICMP_PAYLOAD; buffer[0] = instance->instance_id; buffer[1] = 0; buffer[2] = sequence; - buffer[3] = 0; + buffer[3] = status; uip_icmp6_send(dest, ICMP6_RPL, RPL_CODE_DAO_ACK, 4); +#endif /* RPL_WITH_DAO_ACK */ } /*---------------------------------------------------------------------------*/ void @@ -956,6 +1371,5 @@ rpl_icmp6_register_handlers() uip_icmp6_register_input_handler(&dao_ack_handler); } /*---------------------------------------------------------------------------*/ -#endif /* UIP_CONF_IPV6 */ /** @}*/ diff --git a/core/net/rpl/rpl-mrhof.c b/core/net/rpl/rpl-mrhof.c index 547955278..c51ac8694 100644 --- a/core/net/rpl/rpl-mrhof.c +++ b/core/net/rpl/rpl-mrhof.c @@ -1,7 +1,3 @@ -/** - * \addtogroup uip6 - * @{ - */ /* * Copyright (c) 2010, Swedish Institute of Computer Science. * All rights reserved. @@ -33,9 +29,10 @@ * This file is part of the Contiki operating system. * */ + /** * \file - * The Minimum Rank with Hysteresis Objective Function (MRHOF) + * The Minimum Rank with Hysteresis Objective Function (MRHOF), RFC6719 * * This implementation uses the estimated number of * transmissions (ETX) as the additive routing metric, @@ -44,125 +41,192 @@ * \author Joakim Eriksson , Nicolas Tsiftes */ +/** + * \addtogroup uip6 + * @{ + */ + +#include "net/rpl/rpl.h" #include "net/rpl/rpl-private.h" #include "net/nbr-table.h" +#include "net/link-stats.h" #define DEBUG DEBUG_NONE #include "net/ip/uip-debug.h" -static void reset(rpl_dag_t *); -static void neighbor_link_callback(rpl_parent_t *, int, int); -static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *); -static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *); -static rpl_rank_t calculate_rank(rpl_parent_t *, rpl_rank_t); -static void update_metric_container(rpl_instance_t *); +/* RFC6551 and RFC6719 do not mandate the use of a specific formula to + * compute the ETX value. This MRHOF implementation relies on the value + * computed by the link-stats module. It has an optional feature, + * RPL_MRHOF_CONF_SQUARED_ETX, that consists in squaring this value. + * This basically penalizes bad links while preserving the semantics of ETX + * (1 = perfect link, more = worse link). As a result, MRHOF will favor + * good links over short paths. Recommended when reliability is a priority. + * Without this feature, a hop with 50% PRR (ETX=2) is equivalent to two + * perfect hops with 100% PRR (ETX=1+1=2). With this feature, the former + * path obtains ETX=2*2=4 and the former ETX=1*1+1*1=2. */ +#ifdef RPL_MRHOF_CONF_SQUARED_ETX +#define RPL_MRHOF_SQUARED_ETX RPL_MRHOF_CONF_SQUARED_ETX +#else /* RPL_MRHOF_CONF_SQUARED_ETX */ +#define RPL_MRHOF_SQUARED_ETX 0 +#endif /* RPL_MRHOF_CONF_SQUARED_ETX */ -rpl_of_t rpl_mrhof = { - reset, - neighbor_link_callback, - best_parent, - best_dag, - calculate_rank, - update_metric_container, - 1 -}; - -/* Constants for the ETX moving average */ -#define ETX_SCALE 100 -#define ETX_ALPHA 90 - -/* Reject parents that have a higher link metric than the following. */ -#define MAX_LINK_METRIC 10 +#if !RPL_MRHOF_SQUARED_ETX +/* Configuration parameters of RFC6719. Reject parents that have a higher + * link metric than the following. The default value is 512 but we use 1024. */ +#define MAX_LINK_METRIC 1024 /* Eq ETX of 8 */ +/* Hysteresis of MRHOF: the rank must differ more than PARENT_SWITCH_THRESHOLD_DIV + * in order to switch preferred parent. Default in RFC6719: 192, eq ETX of 1.5. + * We use a more aggressive setting: 96, eq ETX of 0.75. + */ +#define PARENT_SWITCH_THRESHOLD 96 /* Eq ETX of 0.75 */ +#else /* !RPL_MRHOF_SQUARED_ETX */ +#define MAX_LINK_METRIC 2048 /* Eq ETX of 4 */ +#define PARENT_SWITCH_THRESHOLD 160 /* Eq ETX of 1.25 (results in a churn comparable +to the threshold of 96 in the non-squared case) */ +#endif /* !RPL_MRHOF_SQUARED_ETX */ /* Reject parents that have a higher path cost than the following. */ -#define MAX_PATH_COST 100 - -/* - * The rank must differ more than 1/PARENT_SWITCH_THRESHOLD_DIV in order - * to switch preferred parent. - */ -#define PARENT_SWITCH_THRESHOLD_DIV 2 - -typedef uint16_t rpl_path_metric_t; - -static rpl_path_metric_t -calculate_path_metric(rpl_parent_t *p) -{ - if(p == NULL) { - return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR; - } - -#if RPL_DAG_MC == RPL_DAG_MC_NONE - return p->rank + (uint16_t)p->link_metric; -#elif RPL_DAG_MC == RPL_DAG_MC_ETX - return p->mc.obj.etx + (uint16_t)p->link_metric; -#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY - return p->mc.obj.energy.energy_est + (uint16_t)p->link_metric; -#else -#error "Unsupported RPL_DAG_MC configured. See rpl.h." -#endif /* RPL_DAG_MC */ -} +#define MAX_PATH_COST 32768 /* Eq path ETX of 256 */ +/*---------------------------------------------------------------------------*/ static void reset(rpl_dag_t *dag) { PRINTF("RPL: Reset MRHOF\n"); } - +/*---------------------------------------------------------------------------*/ +#if RPL_WITH_DAO_ACK static void -neighbor_link_callback(rpl_parent_t *p, int status, int numtx) +dao_ack_callback(rpl_parent_t *p, int status) { - uint16_t recorded_etx = p->link_metric; - uint16_t packet_etx = numtx * RPL_DAG_MC_ETX_DIVISOR; - uint16_t new_etx; - - /* Do not penalize the ETX when collisions or transmission errors occur. */ - if(status == MAC_TX_OK || status == MAC_TX_NOACK) { - if(status == MAC_TX_NOACK) { - packet_etx = MAX_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR; - } - - new_etx = ((uint32_t)recorded_etx * ETX_ALPHA + - (uint32_t)packet_etx * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE; - - PRINTF("RPL: ETX changed from %u to %u (packet ETX = %u)\n", - (unsigned)(recorded_etx / RPL_DAG_MC_ETX_DIVISOR), - (unsigned)(new_etx / RPL_DAG_MC_ETX_DIVISOR), - (unsigned)(packet_etx / RPL_DAG_MC_ETX_DIVISOR)); - p->link_metric = new_etx; + if(status == RPL_DAO_ACK_UNABLE_TO_ADD_ROUTE_AT_ROOT) { + return; + } + /* here we need to handle failed DAO's and other stuff */ + PRINTF("RPL: MRHOF - DAO ACK received with status: %d\n", status); + if(status >= RPL_DAO_ACK_UNABLE_TO_ACCEPT) { + /* punish the ETX as if this was 10 packets lost */ + link_stats_packet_sent(rpl_get_parent_lladdr(p), MAC_TX_OK, 10); + } else if(status == RPL_DAO_ACK_TIMEOUT) { /* timeout = no ack */ + /* punish the total lack of ACK with a similar punishment */ + link_stats_packet_sent(rpl_get_parent_lladdr(p), MAC_TX_OK, 10); } } +#endif /* RPL_WITH_DAO_ACK */ +/*---------------------------------------------------------------------------*/ +static uint16_t +parent_link_metric(rpl_parent_t *p) +{ + const struct link_stats *stats = rpl_get_parent_link_stats(p); + if(stats != NULL) { +#if RPL_MRHOF_SQUARED_ETX + uint32_t squared_etx = ((uint32_t)stats->etx * stats->etx) / LINK_STATS_ETX_DIVISOR; + return (uint16_t)MIN(squared_etx, 0xffff); +#else /* RPL_MRHOF_SQUARED_ETX */ + return stats->etx; +#endif /* RPL_MRHOF_SQUARED_ETX */ + } + return 0xffff; +} +/*---------------------------------------------------------------------------*/ +static uint16_t +parent_path_cost(rpl_parent_t *p) +{ + uint16_t base; + if(p == NULL || p->dag == NULL || p->dag->instance == NULL) { + return 0xffff; + } + +#if RPL_WITH_MC + /* Handle the different MC types */ + switch(p->dag->instance->mc.type) { + case RPL_DAG_MC_ETX: + base = p->mc.obj.etx; + break; + case RPL_DAG_MC_ENERGY: + base = p->mc.obj.energy.energy_est << 8; + break; + default: + base = p->rank; + break; + } +#else /* RPL_WITH_MC */ + base = p->rank; +#endif /* RPL_WITH_MC */ + + /* path cost upper bound: 0xffff */ + return MIN((uint32_t)base + parent_link_metric(p), 0xffff); +} +/*---------------------------------------------------------------------------*/ static rpl_rank_t -calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank) +rank_via_parent(rpl_parent_t *p) { - rpl_rank_t new_rank; - rpl_rank_t rank_increase; + uint16_t min_hoprankinc; + uint16_t path_cost; - if(p == NULL) { - if(base_rank == 0) { - return INFINITE_RANK; - } - rank_increase = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR; - } else { - rank_increase = p->link_metric; - if(base_rank == 0) { - base_rank = p->rank; - } + if(p == NULL || p->dag == NULL || p->dag->instance == NULL) { + return INFINITE_RANK; } - if(INFINITE_RANK - base_rank < rank_increase) { - /* Reached the maximum rank. */ - new_rank = INFINITE_RANK; - } else { - /* Calculate the rank based on the new rank information from DIO or - stored otherwise. */ - new_rank = base_rank + rank_increase; - } + min_hoprankinc = p->dag->instance->min_hoprankinc; + path_cost = parent_path_cost(p); - return new_rank; + /* Rank lower-bound: parent rank + min_hoprankinc */ + return MAX(MIN((uint32_t)p->rank + min_hoprankinc, 0xffff), path_cost); } +/*---------------------------------------------------------------------------*/ +static int +parent_is_acceptable(rpl_parent_t *p) +{ + uint16_t link_metric = parent_link_metric(p); + uint16_t path_cost = parent_path_cost(p); + /* Exclude links with too high link metrics or path cost (RFC6719, 3.2.2) */ + return link_metric <= MAX_LINK_METRIC && path_cost <= MAX_PATH_COST; +} +/*---------------------------------------------------------------------------*/ +static int +parent_has_usable_link(rpl_parent_t *p) +{ + uint16_t link_metric = parent_link_metric(p); + /* Exclude links with too high link metrics */ + return link_metric <= MAX_LINK_METRIC; +} +/*---------------------------------------------------------------------------*/ +static rpl_parent_t * +best_parent(rpl_parent_t *p1, rpl_parent_t *p2) +{ + rpl_dag_t *dag; + uint16_t p1_cost; + uint16_t p2_cost; + int p1_is_acceptable; + int p2_is_acceptable; + p1_is_acceptable = p1 != NULL && parent_is_acceptable(p1); + p2_is_acceptable = p2 != NULL && parent_is_acceptable(p2); + + if(!p1_is_acceptable) { + return p2_is_acceptable ? p2 : NULL; + } + if(!p2_is_acceptable) { + return p1_is_acceptable ? p1 : NULL; + } + + dag = p1->dag; /* Both parents are in the same DAG. */ + p1_cost = parent_path_cost(p1); + p2_cost = parent_path_cost(p2); + + /* Maintain stability of the preferred parent in case of similar ranks. */ + if(p1 == dag->preferred_parent || p2 == dag->preferred_parent) { + if(p1_cost < p2_cost + PARENT_SWITCH_THRESHOLD && + p1_cost > p2_cost - PARENT_SWITCH_THRESHOLD) { + return dag->preferred_parent; + } + } + + return p1_cost < p2_cost ? p1 : p2; +} +/*---------------------------------------------------------------------------*/ static rpl_dag_t * best_dag(rpl_dag_t *d1, rpl_dag_t *d2) { @@ -176,93 +240,77 @@ best_dag(rpl_dag_t *d1, rpl_dag_t *d2) return d1->rank < d2->rank ? d1 : d2; } - -static rpl_parent_t * -best_parent(rpl_parent_t *p1, rpl_parent_t *p2) -{ - rpl_dag_t *dag; - rpl_path_metric_t min_diff; - rpl_path_metric_t p1_metric; - rpl_path_metric_t p2_metric; - - dag = p1->dag; /* Both parents are in the same DAG. */ - - min_diff = RPL_DAG_MC_ETX_DIVISOR / - PARENT_SWITCH_THRESHOLD_DIV; - - p1_metric = calculate_path_metric(p1); - p2_metric = calculate_path_metric(p2); - - /* Maintain stability of the preferred parent in case of similar ranks. */ - if(p1 == dag->preferred_parent || p2 == dag->preferred_parent) { - if(p1_metric < p2_metric + min_diff && - p1_metric > p2_metric - min_diff) { - PRINTF("RPL: MRHOF hysteresis: %u <= %u <= %u\n", - p2_metric - min_diff, - p1_metric, - p2_metric + min_diff); - return dag->preferred_parent; - } - } - - return p1_metric < p2_metric ? p1 : p2; -} - -#if RPL_DAG_MC == RPL_DAG_MC_NONE +/*---------------------------------------------------------------------------*/ +#if !RPL_WITH_MC static void update_metric_container(rpl_instance_t *instance) { - instance->mc.type = RPL_DAG_MC; + instance->mc.type = RPL_DAG_MC_NONE; } -#else +#else /* RPL_WITH_MC */ static void update_metric_container(rpl_instance_t *instance) { - rpl_path_metric_t path_metric; rpl_dag_t *dag; -#if RPL_DAG_MC == RPL_DAG_MC_ENERGY + uint16_t path_cost; uint8_t type; -#endif - - instance->mc.type = RPL_DAG_MC; - instance->mc.flags = RPL_DAG_MC_FLAG_P; - instance->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE; - instance->mc.prec = 0; dag = instance->current_dag; - - if (!dag->joined) { + if(dag == NULL || !dag->joined) { PRINTF("RPL: Cannot update the metric container when not joined\n"); return; } if(dag->rank == ROOT_RANK(instance)) { - path_metric = 0; + /* Configure MC at root only, other nodes are auto-configured when joining */ + instance->mc.type = RPL_DAG_MC; + instance->mc.flags = 0; + instance->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE; + instance->mc.prec = 0; + path_cost = dag->rank; } else { - path_metric = calculate_path_metric(dag->preferred_parent); + path_cost = parent_path_cost(dag->preferred_parent); } -#if RPL_DAG_MC == RPL_DAG_MC_ETX - instance->mc.length = sizeof(instance->mc.obj.etx); - instance->mc.obj.etx = path_metric; - - PRINTF("RPL: My path ETX to the root is %u.%u\n", - instance->mc.obj.etx / RPL_DAG_MC_ETX_DIVISOR, - (instance->mc.obj.etx % RPL_DAG_MC_ETX_DIVISOR * 100) / - RPL_DAG_MC_ETX_DIVISOR); -#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY - instance->mc.length = sizeof(instance->mc.obj.energy); - - if(dag->rank == ROOT_RANK(instance)) { - type = RPL_DAG_MC_ENERGY_TYPE_MAINS; - } else { - type = RPL_DAG_MC_ENERGY_TYPE_BATTERY; + /* Handle the different MC types */ + switch(instance->mc.type) { + case RPL_DAG_MC_NONE: + break; + case RPL_DAG_MC_ETX: + instance->mc.length = sizeof(instance->mc.obj.etx); + instance->mc.obj.etx = path_cost; + break; + case RPL_DAG_MC_ENERGY: + instance->mc.length = sizeof(instance->mc.obj.energy); + if(dag->rank == ROOT_RANK(instance)) { + type = RPL_DAG_MC_ENERGY_TYPE_MAINS; + } else { + type = RPL_DAG_MC_ENERGY_TYPE_BATTERY; + } + instance->mc.obj.energy.flags = type << RPL_DAG_MC_ENERGY_TYPE; + /* Energy_est is only one byte, use the least significant byte of the path metric. */ + instance->mc.obj.energy.energy_est = path_cost >> 8; + break; + default: + PRINTF("RPL: MRHOF, non-supported MC %u\n", instance->mc.type); + break; } - - instance->mc.obj.energy.flags = type << RPL_DAG_MC_ENERGY_TYPE; - instance->mc.obj.energy.energy_est = path_metric; -#endif /* RPL_DAG_MC == RPL_DAG_MC_ETX */ } -#endif /* RPL_DAG_MC == RPL_DAG_MC_NONE */ +#endif /* RPL_WITH_MC */ +/*---------------------------------------------------------------------------*/ +rpl_of_t rpl_mrhof = { + reset, +#if RPL_WITH_DAO_ACK + dao_ack_callback, +#endif + parent_link_metric, + parent_has_usable_link, + parent_path_cost, + rank_via_parent, + best_parent, + best_dag, + update_metric_container, + RPL_OCP_MRHOF +}; /** @}*/ diff --git a/core/net/rpl/rpl-nbr-policy.c b/core/net/rpl/rpl-nbr-policy.c new file mode 100644 index 000000000..0af5a9041 --- /dev/null +++ b/core/net/rpl/rpl-nbr-policy.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2014-2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. 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 HOLDERS 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. + * + */ +/** + * \addtogroup uip6 + * @{ + */ + + +/** + * \file + * + * Default RPL NBR policy + * decides when to add a new discovered node to the nbr table from RPL. + * + * \author Joakim Eriksson + * Contributors: Niclas Finne , Oriol Piñol , + * + */ + +#include "net/rpl/rpl-private.h" +#include "net/nbr-table.h" +#include "net/ipv6/uip-ds6-nbr.h" +#include "net/ipv6/uip-ds6-route.h" + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +/* + * Policy for neighbor adds + * - one node is locked (default route) + * - max X children (nexthops) + * - max Y "best parents" + * => at least MAX_NBRS - (Y + X + 1) free slots for other. + * + * NOTE: this policy assumes that all neighbors end up being IPv6 + * neighbors and are not only MAC neighbors. + */ +#define MAX_CHILDREN (NBR_TABLE_MAX_NEIGHBORS - 2) +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) + +static int num_parents; /* any node that are possible parents */ +static int num_children; /* all children that we have as nexthop */ +static int num_free; +static linkaddr_t *worst_rank_nbr; /* the parent that has the worst rank */ +static rpl_rank_t worst_rank; +/*---------------------------------------------------------------------------*/ +#if DEBUG == DEBUG_FULL +/* + * This create a periodic call of the update_nbr function that will print + * useful debugging information when in DEBUG_FULL mode + */ +static void update_nbr(void); +static struct ctimer periodic_timer; +static int timer_init = 0; +static void +handle_periodic_timer(void *ptr) +{ + update_nbr(); + ctimer_restart(&periodic_timer); +} +#endif /* DEBUG == DEBUG_FULL */ +/*---------------------------------------------------------------------------*/ +static void +update_nbr(void) +{ + uip_ds6_nbr_t *nbr; + rpl_parent_t *parent; + int num_used; + int is_used; + rpl_rank_t rank; + +#if DEBUG == DEBUG_FULL + if(!timer_init) { + timer_init = 1; + ctimer_set(&periodic_timer, 60 * CLOCK_SECOND, + &handle_periodic_timer, NULL); + } +#endif /* DEBUG == DEBUG_FULL */ + + worst_rank = 0; + worst_rank_nbr = NULL; + num_used = 0; + num_parents = 0; + num_children = 0; + + nbr = nbr_table_head(ds6_neighbors); + while(nbr != NULL) { + linkaddr_t *lladdr = nbr_table_get_lladdr(ds6_neighbors, nbr); + is_used = 0; + + /* + * Check if this neighbor is used as nexthop and therefor being a + * RPL child. + */ + + if(uip_ds6_route_is_nexthop(&nbr->ipaddr) != 0) { + is_used++; + num_children++; + } + + parent = rpl_get_parent((uip_lladdr_t *)lladdr); + if(parent != NULL) { + num_parents++; + + if(parent->dag != NULL && parent->dag->preferred_parent == parent) { + /* + * This is the preferred parent for the DAG and must not be removed + * Note: this assumes that only RPL adds default routes. + */ + } else if(is_used == 0 && worst_rank < INFINITE_RANK && + parent->rank > 0 && + parent->dag != NULL && + parent->dag->instance != NULL && + (rank = parent->dag->instance->of->rank_via_parent(parent)) > worst_rank) { + /* This is the worst-rank neighbor - this is a good candidate for removal */ + worst_rank = rank; + worst_rank_nbr = lladdr; + } + /* add to is_used after evaluation of is_used above */ + is_used++; + } + + if(is_used == 0) { + /* This neighbor is neither parent or child and can be safely removed */ + worst_rank_nbr = lladdr; + worst_rank = INFINITE_RANK; + } else if(is_used > 1) { + PRINTF("NBR-POLICY: *** Neighbor is both child and candidate parent: "); + PRINTLLADDR((uip_lladdr_t *)lladdr); + PRINTF("\n"); + } + + nbr = nbr_table_next(ds6_neighbors, nbr); + num_used++; + } + /* how many more IP neighbors can be have? */ + num_free = NBR_TABLE_MAX_NEIGHBORS - num_used; + + PRINTF("NBR-POLICY: Free: %d, Children: %d, Parents: %d Routes: %d\n", + num_free, num_children, num_parents, uip_ds6_route_num_routes()); +} +/*---------------------------------------------------------------------------*/ +/* Called whenever we get a unicast DIS - e.g. someone that already + have this node in its table - since it is a unicast */ +const linkaddr_t * +find_removable_dis(uip_ipaddr_t *from) +{ + + update_nbr(); + if(num_free > 0) { + /* there are free entries (e.g. unsused by RPL and ND6) but since it is + used by other modules we can not pick these entries for removal. */ + PRINTF("Num-free > 0 = %d - Other for RPL/ND6 unused NBR entry exists .", + num_free); + } + if(num_children < MAX_CHILDREN) { + return worst_rank_nbr; + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +const linkaddr_t * +find_removable_dio(uip_ipaddr_t *from, rpl_dio_t *dio) +{ + rpl_instance_t *instance; + + update_nbr(); + + instance = rpl_get_instance(dio->instance_id); + if(instance == NULL || instance->current_dag == NULL) { + PRINTF("Did not find instance id: %d\n", dio->instance_id); + return NULL; + } + + /* Add the new neighbor only if it is better than the worst parent. */ + if(dio->rank + instance->min_hoprankinc < worst_rank - instance->min_hoprankinc / 2) { + /* Found *great* neighbor - add! */ + PRINTF("Found better neighbor %d < %d - add to cache...\n", + rank, worst_rank); + + return worst_rank_nbr; + } + + PRINTF("Found worse neighbor with new %d and old %d - NOT add to cache.\n", + rank, worst_rank); + return NULL; +} +/*---------------------------------------------------------------------------*/ +const linkaddr_t * +find_removable_dao(uip_ipaddr_t *from, rpl_instance_t *instance) +{ + int max = MAX_CHILDREN; + update_nbr(); + + if(instance != NULL) { + /* No need to reserve space for parents for RPL ROOT */ + if(instance->current_dag->rank == ROOT_RANK(instance)) { + max = NBR_TABLE_MAX_NEIGHBORS; + } + } + + /* Check if this DAO sender is not yet neighbor and there is already too + many children. */ + if(num_children >= max) { + PRINTF("Can not add another child - already at max.\n"); + return NULL; + } + /* remove the worst ranked nbr */ + return worst_rank_nbr; +} +/*---------------------------------------------------------------------------*/ +const linkaddr_t * +rpl_nbr_policy_find_removable(nbr_table_reason_t reason,void * data) +{ + /* When we get the DIO/DAO/DIS we know that UIP contains the + incoming packet */ + switch(reason) { + case NBR_TABLE_REASON_RPL_DIO: + return find_removable_dio(&UIP_IP_BUF->srcipaddr, data); + case NBR_TABLE_REASON_RPL_DAO: + return find_removable_dao(&UIP_IP_BUF->srcipaddr, data); + case NBR_TABLE_REASON_RPL_DIS: + return find_removable_dis(&UIP_IP_BUF->srcipaddr); + default: + return NULL; + } +} +/*---------------------------------------------------------------------------*/ +/** @}*/ diff --git a/core/net/rpl/rpl-ns.c b/core/net/rpl/rpl-ns.c new file mode 100644 index 000000000..68969cef4 --- /dev/null +++ b/core/net/rpl/rpl-ns.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2016, Inria. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * RPL non-storing mode specific functions. Includes support for + * source routing. + * + * \author Simon Duquennoy + */ + +#include "net/rpl/rpl-conf.h" + +#include "net/ip/uip.h" +#include "net/ip/tcpip.h" +#include "net/ipv6/uip-ds6.h" +#include "net/ipv6/uip-icmp6.h" +#include "net/rpl/rpl-private.h" +#include "net/rpl/rpl-ns.h" +#include "lib/list.h" +#include "lib/memb.h" + +#if RPL_WITH_NON_STORING + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +#include +#include + +/* Total number of nodes */ +static int num_nodes; + +/* Every known node in the network */ +LIST(nodelist); +MEMB(nodememb, rpl_ns_node_t, RPL_NS_LINK_NUM); + +/*---------------------------------------------------------------------------*/ +int +rpl_ns_num_nodes(void) +{ + return num_nodes; +} +/*---------------------------------------------------------------------------*/ +static int +node_matches_address(const rpl_dag_t *dag, const rpl_ns_node_t *node, const uip_ipaddr_t *addr) +{ + return addr != NULL + && node != NULL + && dag != NULL + && dag == node->dag + && !memcmp(addr, &node->dag->dag_id, 8) + && !memcmp(((const unsigned char *)addr) + 8, node->link_identifier, 8); +} +/*---------------------------------------------------------------------------*/ +rpl_ns_node_t * +rpl_ns_get_node(const rpl_dag_t *dag, const uip_ipaddr_t *addr) +{ + rpl_ns_node_t *l; + for(l = list_head(nodelist); l != NULL; l = list_item_next(l)) { + /* Compare prefix and node identifier */ + if(node_matches_address(dag, l, addr)) { + return l; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +int +rpl_ns_is_node_reachable(const rpl_dag_t *dag, const uip_ipaddr_t *addr) +{ + int max_depth = RPL_NS_LINK_NUM; + rpl_ns_node_t *node = rpl_ns_get_node(dag, addr); + rpl_ns_node_t *root_node = rpl_ns_get_node(dag, dag != NULL ? &dag->dag_id : NULL); + while(node != NULL && node != root_node && max_depth > 0) { + node = node->parent; + max_depth--; + } + return node != NULL && node == root_node; +} +/*---------------------------------------------------------------------------*/ +void +rpl_ns_expire_parent(rpl_dag_t *dag, const uip_ipaddr_t *child, const uip_ipaddr_t *parent) +{ + rpl_ns_node_t *l = rpl_ns_get_node(dag, child); + /* Check if parent matches */ + if(l != NULL && node_matches_address(dag, l->parent, parent)) { + l->lifetime = RPL_NOPATH_REMOVAL_DELAY; + } +} +/*---------------------------------------------------------------------------*/ +rpl_ns_node_t * +rpl_ns_update_node(rpl_dag_t *dag, const uip_ipaddr_t *child, const uip_ipaddr_t *parent, uint32_t lifetime) +{ + rpl_ns_node_t *child_node = rpl_ns_get_node(dag, child); + rpl_ns_node_t *parent_node = rpl_ns_get_node(dag, parent); + rpl_ns_node_t *old_parent_node; + + if(parent != NULL) { + /* No node for the parent, add one with infinite lifetime */ + if(parent_node == NULL) { + parent_node = rpl_ns_update_node(dag, parent, NULL, 0xffffffff); + if(parent_node == NULL) { + return NULL; + } + } + } + + /* No node for this child, add one */ + if(child_node == NULL) { + child_node = memb_alloc(&nodememb); + /* No space left, abort */ + if(child_node == NULL) { + return NULL; + } + child_node->parent = NULL; + list_add(nodelist, child_node); + num_nodes++; + } + + /* Initialize node */ + child_node->dag = dag; + child_node->lifetime = lifetime; + memcpy(child_node->link_identifier, ((const unsigned char *)child) + 8, 8); + + /* Is the node reachable before the update? */ + if(rpl_ns_is_node_reachable(dag, child)) { + old_parent_node = child_node->parent; + /* Update node */ + child_node->parent = parent_node; + /* Has the node become unreachable? May happen if we create a loop. */ + if(!rpl_ns_is_node_reachable(dag, child)) { + /* The new parent makes the node unreachable, restore old parent. + * We will take the update next time, with chances we know more of + * the topology and the loop is gone. */ + child_node->parent = old_parent_node; + } + } else { + child_node->parent = parent_node; + } + + return child_node; +} +/*---------------------------------------------------------------------------*/ +void +rpl_ns_init(void) +{ + num_nodes = 0; + memb_init(&nodememb); + list_init(nodelist); +} +/*---------------------------------------------------------------------------*/ +rpl_ns_node_t * +rpl_ns_node_head(void) +{ + return list_head(nodelist); +} +/*---------------------------------------------------------------------------*/ +rpl_ns_node_t * +rpl_ns_node_next(rpl_ns_node_t *item) +{ + return list_item_next(item); +} +/*---------------------------------------------------------------------------*/ +void +rpl_ns_get_node_global_addr(uip_ipaddr_t *addr, rpl_ns_node_t *node) +{ + if(addr != NULL && node != NULL && node->dag != NULL) { + memcpy(addr, &node->dag->dag_id, 8); + memcpy(((unsigned char *)addr) + 8, &node->link_identifier, 8); + } +} +/*---------------------------------------------------------------------------*/ +void +rpl_ns_periodic(void) +{ + rpl_ns_node_t *l; + /* First pass, decrement lifetime for all nodes with non-infinite lifetime */ + for(l = list_head(nodelist); l != NULL; l = list_item_next(l)) { + /* Don't touch infinite lifetime nodes */ + if(l->lifetime != 0xffffffff && l->lifetime > 0) { + l->lifetime--; + } + } + /* Second pass, for all expire nodes, deallocate them iff no child points to them */ + for(l = list_head(nodelist); l != NULL; l = list_item_next(l)) { + if(l->lifetime == 0) { + rpl_ns_node_t *l2; + for(l2 = list_head(nodelist); l2 != NULL; l2 = list_item_next(l2)) { + if(l2->parent == l) { + break; + } + } + /* No child found, deallocate node */ + list_remove(nodelist, l); + memb_free(&nodememb, l); + num_nodes--; + } + } +} + +#endif /* RPL_WITH_NON_STORING */ diff --git a/core/net/rpl/rpl-ns.h b/core/net/rpl/rpl-ns.h new file mode 100644 index 000000000..66f911f77 --- /dev/null +++ b/core/net/rpl/rpl-ns.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016, Inria. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * RPL non-storing mode specific functions. Includes support for + * source routing. + * + * \author Simon Duquennoy + */ + + +#ifndef RPL_NS_H +#define RPL_NS_H + +#include "rpl-conf.h" + +#ifdef RPL_NS_CONF_LINK_NUM +#define RPL_NS_LINK_NUM RPL_NS_CONF_LINK_NUM +#else /* RPL_NS_CONF_LINK_NUM */ +#define RPL_NS_LINK_NUM 32 +#endif /* RPL_NS_CONF_LINK_NUM */ + +typedef struct rpl_ns_node { + struct rpl_ns_node *next; + uint32_t lifetime; + rpl_dag_t *dag; + /* Store only IPv6 link identifiers as all nodes in the DAG share the same prefix */ + unsigned char link_identifier[8]; + struct rpl_ns_node *parent; +} rpl_ns_node_t; + +int rpl_ns_num_nodes(void); +void rpl_ns_expire_parent(rpl_dag_t *dag, const uip_ipaddr_t *child, const uip_ipaddr_t *parent); +rpl_ns_node_t *rpl_ns_update_node(rpl_dag_t *dag, const uip_ipaddr_t *child, const uip_ipaddr_t *parent, uint32_t lifetime); +void rpl_ns_init(void); +rpl_ns_node_t *rpl_ns_node_head(void); +rpl_ns_node_t *rpl_ns_node_next(rpl_ns_node_t *item); +rpl_ns_node_t *rpl_ns_get_node(const rpl_dag_t *dag, const uip_ipaddr_t *addr); +int rpl_ns_is_node_reachable(const rpl_dag_t *dag, const uip_ipaddr_t *addr); +void rpl_ns_get_node_global_addr(uip_ipaddr_t *addr, rpl_ns_node_t *node); +void rpl_ns_periodic(); + +#endif /* RPL_NS_H */ diff --git a/core/net/rpl/rpl-of0.c b/core/net/rpl/rpl-of0.c index dc0bae47f..d0bfd1296 100644 --- a/core/net/rpl/rpl-of0.c +++ b/core/net/rpl/rpl-of0.c @@ -1,7 +1,3 @@ -/** - * \addtogroup uip6 - * @{ - */ /* * Copyright (c) 2010, Swedish Institute of Computer Science. * All rights reserved. @@ -31,133 +27,212 @@ * SUCH DAMAGE. * * This file is part of the Contiki operating system. + * */ + /** * \file - * An implementation of RPL's objective function 0. + * An implementation of RPL's objective function 0, RFC6552 * * \author Joakim Eriksson , Nicolas Tsiftes */ +/** + * \addtogroup uip6 + * @{ + */ + +#include "net/rpl/rpl.h" #include "net/rpl/rpl-private.h" +#include "net/nbr-table.h" +#include "net/link-stats.h" #define DEBUG DEBUG_NONE #include "net/ip/uip-debug.h" -static void reset(rpl_dag_t *); -static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *); -static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *); -static rpl_rank_t calculate_rank(rpl_parent_t *, rpl_rank_t); -static void update_metric_container(rpl_instance_t *); +/* Constants from RFC6552. We use the default values. */ +#define RANK_STRETCH 0 /* Must be in the range [0;5] */ +#define RANK_FACTOR 1 /* Must be in the range [1;4] */ -rpl_of_t rpl_of0 = { - reset, - NULL, - best_parent, - best_dag, - calculate_rank, - update_metric_container, - 0 -}; +#define MIN_STEP_OF_RANK 1 +#define MAX_STEP_OF_RANK 9 -#define DEFAULT_RANK_INCREMENT RPL_MIN_HOPRANKINC +/* OF0 computes rank increase as follows: + * rank_increase = (RANK_FACTOR * STEP_OF_RANK + RANK_STRETCH) * min_hop_rank_increase + * STEP_OF_RANK is an implementation-specific scalar value in the range [1;9]. + * RFC6552 provides a default value of 3 but recommends to use a dynamic link metric + * such as ETX. + * */ -#define MIN_DIFFERENCE (RPL_MIN_HOPRANKINC + RPL_MIN_HOPRANKINC / 2) +#define RPL_OF0_FIXED_SR 0 +#define RPL_OF0_ETX_BASED_SR 1 +/* Select RPL_OF0_FIXED_SR or RPL_OF0_ETX_BASED_SR */ +#ifdef RPL_OF0_CONF_SR +#define RPL_OF0_SR RPL_OF0_CONF_SR +#else /* RPL_OF0_CONF_SR */ +#define RPL_OF0_SR RPL_OF0_ETX_BASED_SR +#endif /* RPL_OF0_CONF_SR */ +#if RPL_OF0_FIXED_SR +#define STEP_OF_RANK(p) (3) +#endif /* RPL_OF0_FIXED_SR */ + +#if RPL_OF0_ETX_BASED_SR +/* Numbers suggested by P. Thubert for in the 6TiSCH WG. Anything that maps ETX to + * a step between 1 and 9 works. */ +#define STEP_OF_RANK(p) (((3 * parent_link_metric(p)) / LINK_STATS_ETX_DIVISOR) - 2) +#endif /* RPL_OF0_ETX_BASED_SR */ + +/*---------------------------------------------------------------------------*/ static void reset(rpl_dag_t *dag) { - PRINTF("RPL: Resetting OF0\n"); + PRINTF("RPL: Reset OF0\n"); } - -static rpl_rank_t -calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank) +/*---------------------------------------------------------------------------*/ +#if RPL_WITH_DAO_ACK +static void +dao_ack_callback(rpl_parent_t *p, int status) { - rpl_rank_t increment; - if(base_rank == 0) { - if(p == NULL) { - return INFINITE_RANK; - } - base_rank = p->rank; + if(status == RPL_DAO_ACK_UNABLE_TO_ADD_ROUTE_AT_ROOT) { + return; } - - increment = p != NULL ? - p->dag->instance->min_hoprankinc : - DEFAULT_RANK_INCREMENT; - - if((rpl_rank_t)(base_rank + increment) < base_rank) { - PRINTF("RPL: OF0 rank %d incremented to infinite rank due to wrapping\n", - base_rank); + /* here we need to handle failed DAO's and other stuff */ + PRINTF("RPL: OF0 - DAO ACK received with status: %d\n", status); + if(status >= RPL_DAO_ACK_UNABLE_TO_ACCEPT) { + /* punish the ETX as if this was 10 packets lost */ + link_stats_packet_sent(rpl_get_parent_lladdr(p), MAC_TX_OK, 10); + } else if(status == RPL_DAO_ACK_TIMEOUT) { /* timeout = no ack */ + /* punish the total lack of ACK with a similar punishment */ + link_stats_packet_sent(rpl_get_parent_lladdr(p), MAC_TX_OK, 10); + } +} +#endif /* RPL_WITH_DAO_ACK */ +/*---------------------------------------------------------------------------*/ +static uint16_t +parent_link_metric(rpl_parent_t *p) +{ + /* OF0 operates without metric container; the only metric we have is ETX */ + const struct link_stats *stats = rpl_get_parent_link_stats(p); + return stats != NULL ? stats->etx : 0xffff; +} +/*---------------------------------------------------------------------------*/ +static uint16_t +parent_rank_increase(rpl_parent_t *p) +{ + uint16_t min_hoprankinc; + if(p == NULL || p->dag == NULL || p->dag->instance == NULL) { return INFINITE_RANK; } - return base_rank + increment; - + min_hoprankinc = p->dag->instance->min_hoprankinc; + return (RANK_FACTOR * STEP_OF_RANK(p) + RANK_STRETCH) * min_hoprankinc; } - -static rpl_dag_t * -best_dag(rpl_dag_t *d1, rpl_dag_t *d2) +/*---------------------------------------------------------------------------*/ +static uint16_t +parent_path_cost(rpl_parent_t *p) { - if(d1->grounded) { - if (!d2->grounded) { - return d1; - } - } else if(d2->grounded) { - return d2; + if(p == NULL) { + return 0xffff; } - - if(d1->preference < d2->preference) { - return d2; + /* path cost upper bound: 0xffff */ + return MIN((uint32_t)p->rank + parent_link_metric(p), 0xffff); +} +/*---------------------------------------------------------------------------*/ +static rpl_rank_t +rank_via_parent(rpl_parent_t *p) +{ + if(p == NULL) { + return INFINITE_RANK; } else { - if(d1->preference > d2->preference) { - return d1; - } - } - - if(d2->rank < d1->rank) { - return d2; - } else { - return d1; + return MIN((uint32_t)p->rank + parent_rank_increase(p), INFINITE_RANK); } } - +/*---------------------------------------------------------------------------*/ +static int +parent_is_acceptable(rpl_parent_t *p) +{ + return STEP_OF_RANK(p) >= MIN_STEP_OF_RANK + && STEP_OF_RANK(p) <= MAX_STEP_OF_RANK; +} +/*---------------------------------------------------------------------------*/ +static int +parent_has_usable_link(rpl_parent_t *p) +{ + return parent_is_acceptable(p); +} +/*---------------------------------------------------------------------------*/ static rpl_parent_t * best_parent(rpl_parent_t *p1, rpl_parent_t *p2) { - rpl_rank_t r1, r2; rpl_dag_t *dag; + uint16_t p1_cost; + uint16_t p2_cost; + int p1_is_acceptable; + int p2_is_acceptable; - PRINTF("RPL: Comparing parent "); - PRINT6ADDR(rpl_get_parent_ipaddr(p1)); - PRINTF(" (confidence %d, rank %d) with parent ", - p1->link_metric, p1->rank); - PRINT6ADDR(rpl_get_parent_ipaddr(p2)); - PRINTF(" (confidence %d, rank %d)\n", - p2->link_metric, p2->rank); + p1_is_acceptable = p1 != NULL && parent_is_acceptable(p1); + p2_is_acceptable = p2 != NULL && parent_is_acceptable(p2); + if(!p1_is_acceptable) { + return p2_is_acceptable ? p2 : NULL; + } + if(!p2_is_acceptable) { + return p1_is_acceptable ? p1 : NULL; + } - r1 = DAG_RANK(p1->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC + - p1->link_metric; - r2 = DAG_RANK(p2->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC + - p2->link_metric; - /* Compare two parents by looking both and their rank and at the ETX - for that parent. We choose the parent that has the most - favourable combination. */ + dag = p1->dag; /* Both parents are in the same DAG. */ + p1_cost = parent_path_cost(p1); + p2_cost = parent_path_cost(p2); - dag = (rpl_dag_t *)p1->dag; /* Both parents must be in the same DAG. */ - if(r1 < r2 + MIN_DIFFERENCE && - r1 > r2 - MIN_DIFFERENCE) { - return dag->preferred_parent; - } else if(r1 < r2) { - return p1; + /* Paths costs coarse-grained (multiple of min_hoprankinc), we operate without hysteresis */ + if(p1_cost != p2_cost) { + /* Pick parent with lowest path cost */ + return p1_cost < p2_cost ? p1 : p2; } else { - return p2; + /* We have a tie! */ + /* Stik to current preferred parent if possible */ + if(p1 == dag->preferred_parent || p2 == dag->preferred_parent) { + return dag->preferred_parent; + } + /* None of the nodes is the current preferred parent, + * choose parent with best link metric */ + return parent_link_metric(p1) < parent_link_metric(p2) ? p1 : p2; } } +/*---------------------------------------------------------------------------*/ +static rpl_dag_t * +best_dag(rpl_dag_t *d1, rpl_dag_t *d2) +{ + if(d1->grounded != d2->grounded) { + return d1->grounded ? d1 : d2; + } + if(d1->preference != d2->preference) { + return d1->preference > d2->preference ? d1 : d2; + } + + return d1->rank < d2->rank ? d1 : d2; +} +/*---------------------------------------------------------------------------*/ static void update_metric_container(rpl_instance_t *instance) { instance->mc.type = RPL_DAG_MC_NONE; } +/*---------------------------------------------------------------------------*/ +rpl_of_t rpl_of0 = { + reset, +#if RPL_WITH_DAO_ACK + dao_ack_callback, +#endif + parent_link_metric, + parent_has_usable_link, + parent_path_cost, + rank_via_parent, + best_parent, + best_dag, + update_metric_container, + RPL_OCP_OF0 +}; /** @}*/ diff --git a/core/net/rpl/rpl-private.h b/core/net/rpl/rpl-private.h index 8f2455b29..bb7af2a04 100644 --- a/core/net/rpl/rpl-private.h +++ b/core/net/rpl/rpl-private.h @@ -44,6 +44,8 @@ #include "sys/clock.h" #include "sys/ctimer.h" #include "net/ipv6/uip-ds6.h" +#include "net/ipv6/uip-ds6-route.h" +#include "net/rpl/rpl-ns.h" #include "net/ipv6/multicast/uip-mcast6.h" /*---------------------------------------------------------------------------*/ @@ -90,10 +92,21 @@ #define RPL_DAO_K_FLAG 0x80 /* DAO ACK requested */ #define RPL_DAO_D_FLAG 0x40 /* DODAG ID present */ + +#define RPL_DAO_ACK_UNCONDITIONAL_ACCEPT 0 +#define RPL_DAO_ACK_ACCEPT 1 /* 1 - 127 is OK but not good */ +#define RPL_DAO_ACK_UNABLE_TO_ACCEPT 128 /* >127 is fail */ +#define RPL_DAO_ACK_UNABLE_TO_ADD_ROUTE_AT_ROOT 255 /* root can not accept */ + +#define RPL_DAO_ACK_TIMEOUT -1 + /*---------------------------------------------------------------------------*/ /* RPL IPv6 extension header option. */ #define RPL_HDR_OPT_LEN 4 #define RPL_HOP_BY_HOP_LEN (RPL_HDR_OPT_LEN + 2 + 2) +#define RPL_RH_LEN 4 +#define RPL_SRH_LEN 4 +#define RPL_RH_TYPE_SRH 3 #define RPL_HDR_OPT_DOWN 0x80 #define RPL_HDR_OPT_DOWN_SHIFT 7 #define RPL_HDR_OPT_RANK_ERR 0x40 @@ -103,12 +116,31 @@ /*---------------------------------------------------------------------------*/ /* Default values for RPL constants and variables. */ -/* The default value for the DAO timer. */ -#ifdef RPL_CONF_DAO_LATENCY -#define RPL_DAO_LATENCY RPL_CONF_DAO_LATENCY -#else /* RPL_CONF_DAO_LATENCY */ -#define RPL_DAO_LATENCY (CLOCK_SECOND * 4) -#endif /* RPL_DAO_LATENCY */ +/* DAO transmissions are always delayed by RPL_DAO_DELAY +/- RPL_DAO_DELAY/2 */ +#ifdef RPL_CONF_DAO_DELAY +#define RPL_DAO_DELAY RPL_CONF_DAO_DELAY +#else /* RPL_CONF_DAO_DELAY */ +#define RPL_DAO_DELAY (CLOCK_SECOND * 4) +#endif /* RPL_CONF_DAO_DELAY */ + +/* Delay between reception of a no-path DAO and actual route removal */ +#ifdef RPL_CONF_NOPATH_REMOVAL_DELAY +#define RPL_NOPATH_REMOVAL_DELAY RPL_CONF_NOPATH_REMOVAL_DELAY +#else /* RPL_CONF_NOPATH_REMOVAL_DELAY */ +#define RPL_NOPATH_REMOVAL_DELAY 60 +#endif /* RPL_CONF_NOPATH_REMOVAL_DELAY */ + +#ifdef RPL_CONF_DAO_MAX_RETRANSMISSIONS +#define RPL_DAO_MAX_RETRANSMISSIONS RPL_CONF_DAO_MAX_RETRANSMISSIONS +#else +#define RPL_DAO_MAX_RETRANSMISSIONS 5 +#endif /* RPL_CONF_DAO_MAX_RETRANSMISSIONS */ + +#ifdef RPL_CONF_DAO_RETRANSMISSION_TIMEOUT +#define RPL_DAO_RETRANSMISSION_TIMEOUT RPL_CONF_DAO_RETRANSMISSION_TIMEOUT +#else +#define RPL_DAO_RETRANSMISSION_TIMEOUT (5 * CLOCK_SECOND) +#endif /* RPL_CONF_DAO_RETRANSMISSION_TIMEOUT */ /* Special value indicating immediate removal. */ #define RPL_ZERO_LIFETIME 0 @@ -117,11 +149,28 @@ ((unsigned long)(instance)->lifetime_unit * (lifetime)) #ifndef RPL_CONF_MIN_HOPRANKINC +/* RFC6550 defines the default MIN_HOPRANKINC as 256. + * However, we use MRHOF as a default Objective Function (RFC6719), + * which recommends setting MIN_HOPRANKINC with care, in particular + * when used with ETX as a metric. ETX is computed as a fixed point + * real with a divisor of 128 (RFC6719, RFC6551). We choose to also + * use 128 for RPL_MIN_HOPRANKINC, resulting in a rank equal to the + * ETX path cost. Larger values may also be desirable, as discussed + * in section 6.1 of RFC6719. */ +#if RPL_OF_OCP == RPL_OCP_MRHOF +#define RPL_MIN_HOPRANKINC 128 +#else /* RPL_OF_OCP == RPL_OCP_MRHOF */ #define RPL_MIN_HOPRANKINC 256 -#else +#endif /* RPL_OF_OCP == RPL_OCP_MRHOF */ +#else /* RPL_CONF_MIN_HOPRANKINC */ #define RPL_MIN_HOPRANKINC RPL_CONF_MIN_HOPRANKINC -#endif +#endif /* RPL_CONF_MIN_HOPRANKINC */ + +#ifndef RPL_CONF_MAX_RANKINC #define RPL_MAX_RANKINC (7 * RPL_MIN_HOPRANKINC) +#else /* RPL_CONF_MAX_RANKINC */ +#define RPL_MAX_RANKINC RPL_CONF_MAX_RANKINC +#endif /* RPL_CONF_MAX_RANKINC */ #define DAG_RANK(fixpt_rank, instance) \ ((fixpt_rank) / (instance)->min_hoprankinc) @@ -134,32 +183,6 @@ #define INFINITE_RANK 0xffff -/* Represents 2^n ms. */ -/* Default value according to the specification is 3 which - means 8 milliseconds, but that is an unreasonable value if - using power-saving / duty-cycling */ -#ifdef RPL_CONF_DIO_INTERVAL_MIN -#define RPL_DIO_INTERVAL_MIN RPL_CONF_DIO_INTERVAL_MIN -#else -#define RPL_DIO_INTERVAL_MIN 12 -#endif - -/* Maximum amount of timer doublings. */ -#ifdef RPL_CONF_DIO_INTERVAL_DOUBLINGS -#define RPL_DIO_INTERVAL_DOUBLINGS RPL_CONF_DIO_INTERVAL_DOUBLINGS -#else -#define RPL_DIO_INTERVAL_DOUBLINGS 8 -#endif - -/* Default DIO redundancy. */ -#ifdef RPL_CONF_DIO_REDUNDANCY -#define RPL_DIO_REDUNDANCY RPL_CONF_DIO_REDUNDANCY -#else -#define RPL_DIO_REDUNDANCY 10 -#endif - -/* Expire DAOs from neighbors that do not respond in this time. (seconds) */ -#define DAO_EXPIRATION_TIMEOUT 60 /*---------------------------------------------------------------------------*/ #define RPL_INSTANCE_LOCAL_FLAG 0x80 #define RPL_INSTANCE_D_FLAG 0x40 @@ -176,18 +199,56 @@ #define RPL_MOP_STORING_NO_MULTICAST 2 #define RPL_MOP_STORING_MULTICAST 3 +/* RPL Mode of operation */ #ifdef RPL_CONF_MOP #define RPL_MOP_DEFAULT RPL_CONF_MOP #else /* RPL_CONF_MOP */ -#if RPL_CONF_MULTICAST +#if RPL_WITH_MULTICAST #define RPL_MOP_DEFAULT RPL_MOP_STORING_MULTICAST #else #define RPL_MOP_DEFAULT RPL_MOP_STORING_NO_MULTICAST -#endif /* UIP_IPV6_MULTICAST_RPL */ +#endif /* RPL_WITH_MULTICAST */ #endif /* RPL_CONF_MOP */ +/* + * Embed support for storing mode + */ +#ifdef RPL_CONF_WITH_STORING +#define RPL_WITH_STORING RPL_CONF_WITH_STORING +#else /* RPL_CONF_WITH_STORING */ +/* By default: embed support for non-storing if and only if the configured MOP is not non-storing */ +#define RPL_WITH_STORING (RPL_MOP_DEFAULT != RPL_MOP_NON_STORING) +#endif /* RPL_CONF_WITH_STORING */ + +/* + * Embed support for non-storing mode + */ +#ifdef RPL_CONF_WITH_NON_STORING +#define RPL_WITH_NON_STORING RPL_CONF_WITH_NON_STORING +#else /* RPL_CONF_WITH_NON_STORING */ +/* By default: embed support for non-storing if and only if the configured MOP is non-storing */ +#define RPL_WITH_NON_STORING (RPL_MOP_DEFAULT == RPL_MOP_NON_STORING) +#endif /* RPL_CONF_WITH_NON_STORING */ + +#if RPL_WITH_STORING && (UIP_DS6_ROUTE_NB == 0) +#error "RPL with storing mode included but #routes == 0. Set UIP_CONF_MAX_ROUTES accordingly." +#if !RPL_WITH_NON_STORING && (RPL_NS_LINK_NUM > 0) +#error "You might also want to set RPL_NS_CONF_LINK_NUM to 0." +#endif +#endif + +#if RPL_WITH_NON_STORING && (RPL_NS_LINK_NUM == 0) +#error "RPL with non-storing mode included but #links == 0. Set RPL_NS_CONF_LINK_NUM accordingly." +#if !RPL_WITH_STORING && (UIP_DS6_ROUTE_NB > 0) +#error "You might also want to set UIP_CONF_MAX_ROUTES to 0." +#endif +#endif + +#define RPL_IS_STORING(instance) (RPL_WITH_STORING && ((instance) != NULL) && ((instance)->mop > RPL_MOP_NON_STORING)) +#define RPL_IS_NON_STORING(instance) (RPL_WITH_NON_STORING && ((instance) != NULL) && ((instance)->mop == RPL_MOP_NON_STORING)) + /* Emit a pre-processor error if the user configured multicast with bad MOP */ -#if RPL_CONF_MULTICAST && (RPL_MOP_DEFAULT != RPL_MOP_STORING_MULTICAST) +#if RPL_WITH_MULTICAST && (RPL_MOP_DEFAULT != RPL_MOP_STORING_MULTICAST) #error "RPL Multicast requires RPL_MOP_DEFAULT==3. Check contiki-conf.h" #endif @@ -198,21 +259,9 @@ #define RPL_MCAST_LIFETIME 3 #endif -/* - * The ETX in the metric container is expressed as a fixed-point value - * whose integer part can be obtained by dividing the value by - * RPL_DAG_MC_ETX_DIVISOR. - */ -#define RPL_DAG_MC_ETX_DIVISOR 256 - /* DIS related */ #define RPL_DIS_SEND 1 -#ifdef RPL_DIS_INTERVAL_CONF -#define RPL_DIS_INTERVAL RPL_DIS_INTERVAL_CONF -#else -#define RPL_DIS_INTERVAL 60 -#endif -#define RPL_DIS_START_DELAY 5 + /*---------------------------------------------------------------------------*/ /* Lollipop counters */ @@ -265,11 +314,17 @@ struct rpl_stats { uint16_t malformed_msgs; uint16_t resets; uint16_t parent_switch; + uint16_t forward_errors; + uint16_t loop_errors; + uint16_t loop_warnings; + uint16_t root_repairs; }; typedef struct rpl_stats rpl_stats_t; extern rpl_stats_t rpl_stats; #endif + + /*---------------------------------------------------------------------------*/ /* RPL macros. */ @@ -288,8 +343,10 @@ void dis_output(uip_ipaddr_t *addr); void dio_output(rpl_instance_t *, uip_ipaddr_t *uc_addr); void dao_output(rpl_parent_t *, uint8_t lifetime); void dao_output_target(rpl_parent_t *, uip_ipaddr_t *, uint8_t lifetime); -void dao_ack_output(rpl_instance_t *, uip_ipaddr_t *, uint8_t); +void dao_ack_output(rpl_instance_t *, uip_ipaddr_t *, uint8_t, uint8_t); void rpl_icmp6_register_handlers(void); +uip_ds6_nbr_t *rpl_icmp6_update_nbr_table(uip_ipaddr_t *from, + nbr_table_reason_t r, void *data); /* RPL logic functions. */ void rpl_join_dag(uip_ipaddr_t *from, rpl_dio_t *dio); @@ -303,6 +360,7 @@ rpl_dag_t *rpl_alloc_dag(uint8_t, uip_ipaddr_t *); rpl_instance_t *rpl_alloc_instance(uint8_t); void rpl_free_dag(rpl_dag_t *); void rpl_free_instance(rpl_instance_t *); +void rpl_purge_dags(void); /* DAG parent management function. */ rpl_parent_t *rpl_add_parent(rpl_dag_t *, rpl_dio_t *dio, uip_ipaddr_t *); @@ -322,16 +380,15 @@ uip_ds6_route_t *rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len, uip_ipaddr_t *next_hop); void rpl_purge_routes(void); -/* Lock a parent in the neighbor cache. */ -void rpl_lock_parent(rpl_parent_t *p); - /* Objective function. */ rpl_of_t *rpl_find_of(rpl_ocp_t); /* Timer functions. */ void rpl_schedule_dao(rpl_instance_t *); void rpl_schedule_dao_immediately(rpl_instance_t *); +void rpl_schedule_unicast_dio_immediately(rpl_instance_t *instance); void rpl_cancel_dao(rpl_instance_t *instance); +void rpl_schedule_probing(rpl_instance_t *instance); void rpl_reset_dio_timer(rpl_instance_t *); void rpl_reset_periodic_timer(void); @@ -339,4 +396,7 @@ void rpl_reset_periodic_timer(void); /* Route poisoning. */ void rpl_poison_routes(rpl_dag_t *, rpl_parent_t *); + +rpl_instance_t *rpl_get_default_instance(void); + #endif /* RPL_PRIVATE_H */ diff --git a/core/net/rpl/rpl-timers.c b/core/net/rpl/rpl-timers.c index d8dc68c3f..05384fc14 100644 --- a/core/net/rpl/rpl-timers.c +++ b/core/net/rpl/rpl-timers.c @@ -1,7 +1,3 @@ -/** - * \addtogroup uip6 - * @{ - */ /* * Copyright (c) 2010, Swedish Institute of Computer Science. * All rights reserved. @@ -32,6 +28,7 @@ * * This file is part of the Contiki operating system. */ + /** * \file * RPL timer management. @@ -39,17 +36,35 @@ * \author Joakim Eriksson , Nicolas Tsiftes */ +/** + * \addtogroup uip6 + * @{ + */ + #include "contiki-conf.h" #include "net/rpl/rpl-private.h" +#include "net/rpl/rpl-ns.h" +#include "net/link-stats.h" #include "net/ipv6/multicast/uip-mcast6.h" #include "lib/random.h" #include "sys/ctimer.h" -#if UIP_CONF_IPV6 - #define DEBUG DEBUG_NONE #include "net/ip/uip-debug.h" +/* A configurable function called after update of the RPL DIO interval */ +#ifdef RPL_CALLBACK_NEW_DIO_INTERVAL +void RPL_CALLBACK_NEW_DIO_INTERVAL(uint8_t dio_interval); +#endif /* RPL_CALLBACK_NEW_DIO_INTERVAL */ + +#ifdef RPL_PROBING_SELECT_FUNC +rpl_parent_t *RPL_PROBING_SELECT_FUNC(rpl_dag_t *dag); +#endif /* RPL_PROBING_SELECT_FUNC */ + +#ifdef RPL_PROBING_DELAY_FUNC +clock_time_t RPL_PROBING_DELAY_FUNC(rpl_dag_t *dag); +#endif /* RPL_PROBING_DELAY_FUNC */ + /*---------------------------------------------------------------------------*/ static struct ctimer periodic_timer; @@ -66,13 +81,23 @@ static uint8_t dio_send_ok; static void handle_periodic_timer(void *ptr) { - rpl_purge_routes(); + rpl_dag_t *dag = rpl_get_any_dag(); + + rpl_purge_dags(); + if(dag != NULL) { + if(RPL_IS_STORING(dag->instance)) { + rpl_purge_routes(); + } + if(RPL_IS_NON_STORING(dag->instance)) { + rpl_ns_periodic(); + } + } rpl_recalculate_ranks(); /* handle DIS */ #if RPL_DIS_SEND next_dis++; - if(rpl_get_any_dag() == NULL && next_dis >= RPL_DIS_INTERVAL) { + if(dag == NULL && next_dis >= RPL_DIS_INTERVAL) { next_dis = 0; dis_output(NULL); } @@ -123,6 +148,10 @@ new_dio_interval(rpl_instance_t *instance) /* schedule the timer */ PRINTF("RPL: Scheduling DIO timer %lu ticks in future (Interval)\n", ticks); ctimer_set(&instance->dio_timer, ticks, &handle_dio_timer, instance); + +#ifdef RPL_CALLBACK_NEW_DIO_INTERVAL + RPL_CALLBACK_NEW_DIO_INTERVAL(instance->dio_intcurrent); +#endif /* RPL_CALLBACK_NEW_DIO_INTERVAL */ } /*---------------------------------------------------------------------------*/ static void @@ -145,13 +174,13 @@ handle_dio_timer(void *ptr) if(instance->dio_send) { /* send DIO if counter is less than desired redundancy */ - if(instance->dio_counter < instance->dio_redundancy) { + if(instance->dio_redundancy != 0 && instance->dio_counter < instance->dio_redundancy) { #if RPL_CONF_STATS instance->dio_totsend++; #endif /* RPL_CONF_STATS */ dio_output(instance, NULL); } else { - PRINTF("RPL: Supressing DIO transmission (%d >= %d)\n", + PRINTF("RPL: Suppressing DIO transmission (%d >= %d)\n", instance->dio_counter, instance->dio_redundancy); } instance->dio_send = 0; @@ -166,6 +195,10 @@ handle_dio_timer(void *ptr) } new_dio_interval(instance); } + +#if DEBUG + rpl_print_neighbor_list(); +#endif } /*---------------------------------------------------------------------------*/ void @@ -210,6 +243,8 @@ set_dao_lifetime_timer(rpl_instance_t *instance) expiration_time = (clock_time_t)instance->default_lifetime * (clock_time_t)instance->lifetime_unit * CLOCK_SECOND / 2; + /* make the time for the re registration be betwen 1/2 - 3/4 of lifetime */ + expiration_time = expiration_time + (random_rand() % (expiration_time / 2)); PRINTF("RPL: Scheduling DAO lifetime timer %u ticks in the future\n", (unsigned)expiration_time); ctimer_set(&instance->dao_lifetime_timer, expiration_time, @@ -221,7 +256,7 @@ static void handle_dao_timer(void *ptr) { rpl_instance_t *instance; -#if RPL_CONF_MULTICAST +#if RPL_WITH_MULTICAST uip_mcast6_route_t *mcast_route; uint8_t i; #endif @@ -240,7 +275,7 @@ handle_dao_timer(void *ptr) /* Set the route lifetime to the default value. */ dao_output(instance->current_dag->preferred_parent, instance->default_lifetime); -#if RPL_CONF_MULTICAST +#if RPL_WITH_MULTICAST /* Send DAOs for multicast prefixes only if the instance is in MOP 3 */ if(instance->mop == RPL_MOP_STORING_MULTICAST) { /* Send a DAO for own multicast addresses */ @@ -307,7 +342,7 @@ schedule_dao(rpl_instance_t *instance, clock_time_t latency) void rpl_schedule_dao(rpl_instance_t *instance) { - schedule_dao(instance, RPL_DAO_LATENCY); + schedule_dao(instance, RPL_DAO_DELAY); } /*---------------------------------------------------------------------------*/ void @@ -323,6 +358,140 @@ rpl_cancel_dao(rpl_instance_t *instance) ctimer_stop(&instance->dao_lifetime_timer); } /*---------------------------------------------------------------------------*/ -#endif /* UIP_CONF_IPV6 */ +static void +handle_unicast_dio_timer(void *ptr) +{ + rpl_instance_t *instance = (rpl_instance_t *)ptr; + uip_ipaddr_t *target_ipaddr = rpl_get_parent_ipaddr(instance->unicast_dio_target); + if(target_ipaddr != NULL) { + dio_output(instance, target_ipaddr); + } +} +/*---------------------------------------------------------------------------*/ +void +rpl_schedule_unicast_dio_immediately(rpl_instance_t *instance) +{ + ctimer_set(&instance->unicast_dio_timer, 0, + handle_unicast_dio_timer, instance); +} +/*---------------------------------------------------------------------------*/ +#if RPL_WITH_PROBING +clock_time_t +get_probing_delay(rpl_dag_t *dag) +{ + if(dag != NULL && dag->instance != NULL + && dag->instance->urgent_probing_target != NULL) { + /* Urgent probing needed (to find out if a neighbor may become preferred parent) */ + return random_rand() % (CLOCK_SECOND * 10); + } else { + /* Else, use normal probing interval */ + return ((RPL_PROBING_INTERVAL) / 2) + random_rand() % (RPL_PROBING_INTERVAL); + } +} +/*---------------------------------------------------------------------------*/ +rpl_parent_t * +get_probing_target(rpl_dag_t *dag) +{ + /* Returns the next probing target. The current implementation probes the urgent + * probing target if any, or the preferred parent if its link statistics need refresh. + * Otherwise, it picks at random between: + * (1) selecting the best parent with non-fresh link statistics + * (2) selecting the least recently updated parent + */ + + rpl_parent_t *p; + rpl_parent_t *probing_target = NULL; + rpl_rank_t probing_target_rank = INFINITE_RANK; + clock_time_t probing_target_age = 0; + clock_time_t clock_now = clock_time(); + + if(dag == NULL || + dag->instance == NULL) { + return NULL; + } + + /* There is an urgent probing target */ + if(dag->instance->urgent_probing_target != NULL) { + return dag->instance->urgent_probing_target; + } + + /* The preferred parent needs probing */ + if(dag->preferred_parent != NULL && !rpl_parent_is_fresh(dag->preferred_parent)) { + return dag->preferred_parent; + } + + /* With 50% probability: probe best non-fresh parent */ + if(random_rand() % 2 == 0) { + p = nbr_table_head(rpl_parents); + while(p != NULL) { + if(p->dag == dag && !rpl_parent_is_fresh(p)) { + /* p is in our dag and needs probing */ + rpl_rank_t p_rank = rpl_rank_via_parent(p); + if(probing_target == NULL + || p_rank < probing_target_rank) { + probing_target = p; + probing_target_rank = p_rank; + } + } + p = nbr_table_next(rpl_parents, p); + } + } + + /* If we still do not have a probing target: pick the least recently updated parent */ + if(probing_target == NULL) { + p = nbr_table_head(rpl_parents); + while(p != NULL) { + const struct link_stats *stats =rpl_get_parent_link_stats(p); + if(p->dag == dag && stats != NULL) { + if(probing_target == NULL + || clock_now - stats->last_tx_time > probing_target_age) { + probing_target = p; + probing_target_age = clock_now - stats->last_tx_time; + } + } + p = nbr_table_next(rpl_parents, p); + } + } + + return probing_target; +} +/*---------------------------------------------------------------------------*/ +static void +handle_probing_timer(void *ptr) +{ + rpl_instance_t *instance = (rpl_instance_t *)ptr; + rpl_parent_t *probing_target = RPL_PROBING_SELECT_FUNC(instance->current_dag); + uip_ipaddr_t *target_ipaddr = rpl_get_parent_ipaddr(probing_target); + + /* Perform probing */ + if(target_ipaddr != NULL) { + const struct link_stats *stats = rpl_get_parent_link_stats(probing_target); + (void)stats; + PRINTF("RPL: probing %u %s last tx %u min ago\n", + rpl_get_parent_lladdr(probing_target)->u8[7], + instance->urgent_probing_target != NULL ? "(urgent)" : "", + probing_target != NULL ? + (unsigned)((clock_time() - stats->last_tx_time) / (60 * CLOCK_SECOND)) : 0 + ); + /* Send probe, e.g. unicast DIO or DIS */ + RPL_PROBING_SEND_FUNC(instance, target_ipaddr); + instance->urgent_probing_target = NULL; + } + + /* Schedule next probing */ + rpl_schedule_probing(instance); + +#if DEBUG + rpl_print_neighbor_list(); +#endif +} +/*---------------------------------------------------------------------------*/ +void +rpl_schedule_probing(rpl_instance_t *instance) +{ + ctimer_set(&instance->probing_timer, RPL_PROBING_DELAY_FUNC(instance->current_dag), + handle_probing_timer, instance); +} +#endif /* RPL_WITH_PROBING */ /** @}*/ diff --git a/core/net/rpl/rpl.c b/core/net/rpl/rpl.c index bf1c3bb42..92ea2b309 100644 --- a/core/net/rpl/rpl.c +++ b/core/net/rpl/rpl.c @@ -1,7 +1,3 @@ -/** - * \addtogroup uip6 - * @{ - */ /* * Copyright (c) 2009, Swedish Institute of Computer Science. * All rights reserved. @@ -32,6 +28,7 @@ * * This file is part of the Contiki operating system. */ + /** * \file * ContikiRPL, an implementation of RPL: IPv6 Routing Protocol @@ -40,11 +37,17 @@ * \author Joakim Eriksson , Nicolas Tsiftes */ +/** + * \addtogroup uip6 + * @{ + */ + #include "net/ip/uip.h" #include "net/ip/tcpip.h" #include "net/ipv6/uip-ds6.h" #include "net/ipv6/uip-icmp6.h" #include "net/rpl/rpl-private.h" +#include "net/rpl/rpl-ns.h" #include "net/ipv6/multicast/uip-mcast6.h" #define DEBUG DEBUG_NONE @@ -53,8 +56,6 @@ #include #include -#if UIP_CONF_IPV6 - #if RPL_CONF_STATS rpl_stats_t rpl_stats; #endif @@ -76,9 +77,9 @@ rpl_set_mode(enum rpl_mode m) switching to. */ if(m == RPL_MODE_MESH) { - /* If we switcht to mesh mode, we should send out a DAO message to + /* If we switch to mesh mode, we should send out a DAO message to inform our parent that we now are reachable. Before we do this, - we must set the mode variable, since DAOs will not be send if + we must set the mode variable, since DAOs will not be sent if we are in feather mode. */ PRINTF("RPL: switching to mesh mode\n"); mode = m; @@ -89,11 +90,17 @@ rpl_set_mode(enum rpl_mode m) } else if(m == RPL_MODE_FEATHER) { PRINTF("RPL: switching to feather mode\n"); - mode = m; if(default_instance != NULL) { + PRINTF("rpl_set_mode: RPL sending DAO with zero lifetime\n"); + if(default_instance->current_dag != NULL) { + dao_output(default_instance->current_dag->preferred_parent, RPL_ZERO_LIFETIME); + } rpl_cancel_dao(default_instance); + } else { + PRINTF("rpl_set_mode: no default instance\n"); } + mode = m; } else { mode = m; } @@ -107,7 +114,7 @@ rpl_purge_routes(void) uip_ds6_route_t *r; uip_ipaddr_t prefix; rpl_dag_t *dag; -#if RPL_CONF_MULTICAST +#if RPL_WITH_MULTICAST uip_mcast6_route_t *mcast_route; #endif @@ -152,7 +159,7 @@ rpl_purge_routes(void) } } -#if RPL_CONF_MULTICAST +#if RPL_WITH_MULTICAST mcast_route = uip_mcast6_route_list_head(); while(mcast_route != NULL) { @@ -171,7 +178,7 @@ void rpl_remove_routes(rpl_dag_t *dag) { uip_ds6_route_t *r; -#if RPL_CONF_MULTICAST +#if RPL_WITH_MULTICAST uip_mcast6_route_t *mcast_route; #endif @@ -186,7 +193,7 @@ rpl_remove_routes(rpl_dag_t *dag) } } -#if RPL_CONF_MULTICAST +#if RPL_WITH_MULTICAST mcast_route = uip_mcast6_route_list_head(); while(mcast_route != NULL) { @@ -209,12 +216,10 @@ rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag) while(r != NULL) { if(uip_ipaddr_cmp(uip_ds6_route_nexthop(r), nexthop) && - r->state.dag == dag) { - uip_ds6_route_rm(r); - r = uip_ds6_route_head(); - } else { - r = uip_ds6_route_next(r); + r->state.dag == dag) { + r->state.lifetime = 0; } + r = uip_ds6_route_next(r); } ANNOTATE("#L %u 0\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]); } @@ -232,7 +237,8 @@ rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len, rep->state.dag = dag; rep->state.lifetime = RPL_LIFETIME(dag->instance, dag->instance->default_lifetime); - rep->state.learned_from = RPL_ROUTE_FROM_INTERNAL; + /* always clear state flags for the no-path received when adding/refreshing */ + RPL_ROUTE_CLEAR_NOPATH_RECEIVED(rep); PRINTF("RPL: Added a route to "); PRINT6ADDR(prefix); @@ -260,10 +266,7 @@ rpl_link_neighbor_callback(const linkaddr_t *addr, int status, int numtx) if(parent != NULL) { /* Trigger DAG rank recalculation. */ PRINTF("RPL: rpl_link_neighbor_callback triggering update\n"); - parent->updated = 1; - if(instance->of->neighbor_link_callback != NULL) { - instance->of->neighbor_link_callback(parent, status, numtx); - } + parent->flags |= RPL_PARENT_FLAG_UPDATED; } } } @@ -276,9 +279,13 @@ rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr) rpl_instance_t *instance; rpl_instance_t *end; - PRINTF("RPL: Removing neighbor "); + PRINTF("RPL: Neighbor state changed for "); PRINT6ADDR(&nbr->ipaddr); - PRINTF("\n"); +#if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA + PRINTF(", nscount=%u, state=%u\n", nbr->nscount, nbr->state); +#else /* UIP_ND6_SEND_NA || UIP_ND6_SEND_RA */ + PRINTF(", state=%u\n", nbr->state); +#endif /* UIP_ND6_SEND_NA || UIP_ND6_SEND_RA */ for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) { if(instance->used == 1 ) { p = rpl_find_parent_any_dag(instance, &nbr->ipaddr); @@ -286,7 +293,35 @@ rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr) p->rank = INFINITE_RANK; /* Trigger DAG rank recalculation. */ PRINTF("RPL: rpl_ipv6_neighbor_callback infinite rank\n"); - p->updated = 1; + p->flags |= RPL_PARENT_FLAG_UPDATED; + } + } + } +} +/*---------------------------------------------------------------------------*/ +void +rpl_purge_dags(void) +{ + rpl_instance_t *instance; + rpl_instance_t *end; + int i; + + for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; + instance < end; ++instance) { + if(instance->used) { + for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; i++) { + if(instance->dag_table[i].used) { + if(instance->dag_table[i].lifetime == 0) { + if(!instance->dag_table[i].joined) { + PRINTF("Removing dag "); + PRINT6ADDR(&instance->dag_table[i].dag_id); + PRINTF("\n"); + rpl_free_dag(&instance->dag_table[i]); + } + } else { + instance->dag_table[i].lifetime--; + } + } } } } @@ -311,9 +346,10 @@ rpl_init(void) memset(&rpl_stats, 0, sizeof(rpl_stats)); #endif - RPL_OF.reset(NULL); +#if RPL_WITH_NON_STORING + rpl_ns_init(); +#endif /* RPL_WITH_NON_STORING */ } /*---------------------------------------------------------------------------*/ -#endif /* UIP_CONF_IPV6 */ /** @}*/ diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index 76134e44e..26ee71edc 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -49,8 +49,8 @@ typedef uint16_t rpl_rank_t; typedef uint16_t rpl_ocp_t; /*---------------------------------------------------------------------------*/ -/* DAG Metric Container Object Types, to be confirmed by IANA. */ -#define RPL_DAG_MC_NONE 0 /* Local identifier for empty MC */ +/* IANA Routing Metric/Constraint Type as defined in RFC6551 */ +#define RPL_DAG_MC_NONE 0 /* Local identifier for empty MC */ #define RPL_DAG_MC_NSA 1 /* Node State and Attributes */ #define RPL_DAG_MC_ENERGY 2 /* Node Energy */ #define RPL_DAG_MC_HOPCOUNT 3 /* Hop Count */ @@ -60,27 +60,31 @@ typedef uint16_t rpl_ocp_t; #define RPL_DAG_MC_ETX 7 /* Expected Transmission Count */ #define RPL_DAG_MC_LC 8 /* Link Color */ -/* DAG Metric Container flags. */ -#define RPL_DAG_MC_FLAG_P 0x8 -#define RPL_DAG_MC_FLAG_C 0x4 -#define RPL_DAG_MC_FLAG_O 0x2 -#define RPL_DAG_MC_FLAG_R 0x1 +/* IANA Routing Metric/Constraint Common Header Flag field as defined in RFC6551 (bit indexes) */ +#define RPL_DAG_MC_FLAG_P 5 +#define RPL_DAG_MC_FLAG_C 6 +#define RPL_DAG_MC_FLAG_O 7 +#define RPL_DAG_MC_FLAG_R 8 -/* DAG Metric Container aggregation mode. */ +/* IANA Routing Metric/Constraint Common Header A Field as defined in RFC6551 */ #define RPL_DAG_MC_AGGR_ADDITIVE 0 #define RPL_DAG_MC_AGGR_MAXIMUM 1 #define RPL_DAG_MC_AGGR_MINIMUM 2 #define RPL_DAG_MC_AGGR_MULTIPLICATIVE 3 -/* The bit index within the flags field of - the rpl_metric_object_energy structure. */ -#define RPL_DAG_MC_ENERGY_INCLUDED 3 -#define RPL_DAG_MC_ENERGY_TYPE 1 -#define RPL_DAG_MC_ENERGY_ESTIMATION 0 +/* The bit index within the flags field of the rpl_metric_object_energy structure. */ +#define RPL_DAG_MC_ENERGY_INCLUDED 3 +#define RPL_DAG_MC_ENERGY_TYPE 1 +#define RPL_DAG_MC_ENERGY_ESTIMATION 0 -#define RPL_DAG_MC_ENERGY_TYPE_MAINS 0 -#define RPL_DAG_MC_ENERGY_TYPE_BATTERY 1 -#define RPL_DAG_MC_ENERGY_TYPE_SCAVENGING 2 +/* IANA Node Type Field as defined in RFC6551 */ +#define RPL_DAG_MC_ENERGY_TYPE_MAINS 0 +#define RPL_DAG_MC_ENERGY_TYPE_BATTERY 1 +#define RPL_DAG_MC_ENERGY_TYPE_SCAVENGING 2 + +/* IANA Objective Code Point as defined in RFC6550 */ +#define RPL_OCP_OF0 0 +#define RPL_OCP_MRHOF 1 struct rpl_metric_object_energy { uint8_t flags; @@ -104,16 +108,17 @@ typedef struct rpl_metric_container rpl_metric_container_t; struct rpl_instance; struct rpl_dag; /*---------------------------------------------------------------------------*/ +#define RPL_PARENT_FLAG_UPDATED 0x1 +#define RPL_PARENT_FLAG_LINK_METRIC_VALID 0x2 + struct rpl_parent { - struct rpl_parent *next; struct rpl_dag *dag; -#if RPL_DAG_MC != RPL_DAG_MC_NONE +#if RPL_WITH_MC rpl_metric_container_t mc; -#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ +#endif /* RPL_WITH_MC */ rpl_rank_t rank; - uint16_t link_metric; uint8_t dtsn; - uint8_t updated; + uint8_t flags; }; typedef struct rpl_parent rpl_parent_t; /*---------------------------------------------------------------------------*/ @@ -140,6 +145,7 @@ struct rpl_dag { rpl_rank_t rank; struct rpl_instance *instance; rpl_prefix_t prefix_info; + uint32_t lifetime; }; typedef struct rpl_dag rpl_dag_t; typedef struct rpl_instance rpl_instance_t; @@ -152,11 +158,25 @@ typedef struct rpl_instance rpl_instance_t; * Resets the objective function state for a specific DAG. This function is * called when doing a global repair on the DAG. * - * neighbor_link_callback(parent, known, etx) + * parent_link_metric(parent) * - * Receives link-layer neighbor information. The parameter "known" is set - * either to 0 or 1. The "etx" parameter specifies the current - * ETX(estimated transmissions) for the neighbor. + * Returns the link metric of a parent + * + * parent_has_usable_link(parent) + * + * Returns 1 iff we have a usable link to this parent + * + * parent_path_cost(parent) + * + * Returns the path cost of a parent + * + * rank_via_parent(parent) + * + * Returns our rank if we select a given parent as preferred parent + * + * parent_is_acceptable + * + * Returns 1 if a parent is usable as preferred parent, 0 otherwise * * best_parent(parent1, parent2) * @@ -166,32 +186,34 @@ typedef struct rpl_instance rpl_instance_t; * * Compares two DAGs and returns the best one, according to the OF. * - * calculate_rank(parent, base_rank) - * - * Calculates a rank value using the parent rank and a base rank. - * If "parent" is NULL, the objective function selects a default increment - * that is adds to the "base_rank". Otherwise, the OF uses information known - * about "parent" to select an increment to the "base_rank". - * * update_metric_container(dag) * * Updates the metric container for outgoing DIOs in a certain DAG. - * If the objective function of the DAG does not use metric containers, + * If the objective function of the DAG does not use metric containers, * the function should set the object type to RPL_DAG_MC_NONE. + * + * dao_ack_callback(parent, status) + * + * A callback on the result of the DAO ACK. Similar to the neighbor link + * callback. A failed DAO_ACK (NACK) can be used for switching to another + * parent via changed link metric or other mechanisms. */ struct rpl_of { void (*reset)(struct rpl_dag *); - void (*neighbor_link_callback)(rpl_parent_t *, int, int); +#if RPL_WITH_DAO_ACK + void (*dao_ack_callback)(rpl_parent_t *, int status); +#endif + uint16_t (*parent_link_metric)(rpl_parent_t *); + int (*parent_has_usable_link)(rpl_parent_t *); + uint16_t (*parent_path_cost)(rpl_parent_t *); + rpl_rank_t (*rank_via_parent)(rpl_parent_t *); rpl_parent_t *(*best_parent)(rpl_parent_t *, rpl_parent_t *); rpl_dag_t *(*best_dag)(rpl_dag_t *, rpl_dag_t *); - rpl_rank_t (*calculate_rank)(rpl_parent_t *, rpl_rank_t); void (*update_metric_container)( rpl_instance_t *); rpl_ocp_t ocp; }; typedef struct rpl_of rpl_of_t; -/* Declare the selected objective function. */ -extern rpl_of_t RPL_OF; /*---------------------------------------------------------------------------*/ /* Instance */ struct rpl_instance { @@ -213,6 +235,11 @@ struct rpl_instance { uint8_t dio_intcurrent; uint8_t dio_send; /* for keeping track of which mode the timer is in */ uint8_t dio_counter; + /* my last registered DAO that I might be waiting for ACK on */ + uint8_t my_dao_seqno; + uint8_t my_dao_transmissions; + /* this is intended to keep track if this instance have a route downward */ + uint8_t has_downward_route; rpl_rank_t max_rankinc; rpl_rank_t min_hoprankinc; uint16_t lifetime_unit; /* lifetime in seconds = l_u * d_l */ @@ -222,32 +249,53 @@ struct rpl_instance { uint16_t dio_totrecv; #endif /* RPL_CONF_STATS */ clock_time_t dio_next_delay; /* delay for completion of dio interval */ +#if RPL_WITH_PROBING + struct ctimer probing_timer; + rpl_parent_t *urgent_probing_target; +#endif /* RPL_WITH_PROBING */ struct ctimer dio_timer; struct ctimer dao_timer; struct ctimer dao_lifetime_timer; + struct ctimer unicast_dio_timer; + rpl_parent_t *unicast_dio_target; +#if RPL_WITH_DAO_ACK + struct ctimer dao_retransmit_timer; +#endif /* RPL_WITH_DAO_ACK */ }; /*---------------------------------------------------------------------------*/ /* Public RPL functions. */ void rpl_init(void); void uip_rpl_input(void); -rpl_dag_t *rpl_set_root(uint8_t instance_id, uip_ipaddr_t * dag_id); +rpl_dag_t *rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id); int rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, unsigned len); int rpl_repair_root(uint8_t instance_id); int rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from); +rpl_dag_t *rpl_get_dag(const uip_ipaddr_t *addr); rpl_dag_t *rpl_get_any_dag(void); rpl_instance_t *rpl_get_instance(uint8_t instance_id); -void rpl_update_header_empty(void); -int rpl_update_header_final(uip_ipaddr_t *addr); -int rpl_verify_header(int); +int rpl_update_header(void); +int rpl_finalize_header(uip_ipaddr_t *addr); +int rpl_verify_hbh_header(int); void rpl_insert_header(void); void rpl_remove_header(void); -uint8_t rpl_invert_header(void); +const struct link_stats *rpl_get_parent_link_stats(rpl_parent_t *p); +int rpl_parent_is_fresh(rpl_parent_t *p); +int rpl_parent_is_reachable(rpl_parent_t *p); +uint16_t rpl_get_parent_link_metric(rpl_parent_t *p); +rpl_rank_t rpl_rank_via_parent(rpl_parent_t *p); +const linkaddr_t *rpl_get_parent_lladdr(rpl_parent_t *p); uip_ipaddr_t *rpl_get_parent_ipaddr(rpl_parent_t *nbr); +rpl_parent_t *rpl_get_parent(uip_lladdr_t *addr); rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr); -uint16_t rpl_get_parent_link_metric(const uip_lladdr_t *addr); void rpl_dag_init(void); +uip_ds6_nbr_t *rpl_get_nbr(rpl_parent_t *parent); +void rpl_print_neighbor_list(void); +int rpl_process_srh_header(void); +int rpl_srh_get_next_hop(uip_ipaddr_t *ipaddr); +/* Per-parent RPL information */ +NBR_TABLE_DECLARE(rpl_parents); /** * RPL modes @@ -280,5 +328,13 @@ enum rpl_mode rpl_set_mode(enum rpl_mode mode); */ enum rpl_mode rpl_get_mode(void); + +/** + * Get the RPL's best guess on if we have downward route or not. + * + * \retval 1 if we have a downward route from RPL Root, 0 if not. + */ +int rpl_has_downward_route(void); + /*---------------------------------------------------------------------------*/ #endif /* RPL_H */ diff --git a/core/sys/arg.c b/core/sys/arg.c index 080dea9bb..090034380 100644 --- a/core/sys/arg.c +++ b/core/sys/arg.c @@ -1,34 +1,3 @@ -/** - * \file - * Argument buffer for passing arguments when starting processes - * \author Adam Dunkels - */ - -/** - * \addtogroup sys - * @{ - */ - -/** - * \defgroup arg Argument buffer - * @{ - * - * The argument buffer can be used when passing an argument from an - * exiting process to a process that has not been created yet. Since - * the exiting process will have exited when the new process is - * started, the argument cannot be passed in any of the processes' - * addres spaces. In such situations, the argument buffer can be used. - * - * The argument buffer is statically allocated in memory and is - * globally accessible to all processes. - * - * An argument buffer is allocated with the arg_alloc() function and - * deallocated with the arg_free() function. The arg_free() function - * is designed so that it can take any pointer, not just an argument - * buffer pointer. If the pointer to arg_free() is not an argument - * buffer, the function does nothing. - */ - /* * Copyright (c) 2003, Adam Dunkels. * All rights reserved. @@ -63,6 +32,37 @@ * */ +/** + * \file + * Argument buffer for passing arguments when starting processes + * \author Adam Dunkels + */ + +/** + * \addtogroup sys + * @{ + */ + +/** + * \defgroup arg Argument buffer + * @{ + * + * The argument buffer can be used when passing an argument from an + * exiting process to a process that has not been created yet. Since + * the exiting process will have exited when the new process is + * started, the argument cannot be passed in any of the processes' + * addres spaces. In such situations, the argument buffer can be used. + * + * The argument buffer is statically allocated in memory and is + * globally accessible to all processes. + * + * An argument buffer is allocated with the arg_alloc() function and + * deallocated with the arg_free() function. The arg_free() function + * is designed so that it can take any pointer, not just an argument + * buffer pointer. If the pointer to arg_free() is not an argument + * buffer, the function does nothing. + */ + #include "contiki.h" #include "sys/arg.h" diff --git a/core/sys/cc-gcc.h b/core/sys/cc-gcc.h new file mode 100644 index 000000000..e96716327 --- /dev/null +++ b/core/sys/cc-gcc.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015, Scanimetrics - http://www.scanimetrics.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +#ifndef _CC_GCC_H_ +#define _CC_GCC_H_ +#ifdef __GNUC__ + +#ifndef CC_CONF_INLINE +/* use __inline__ in case "inline" is not available for any reason */ +#define CC_CONF_INLINE __inline__ +#endif + +#define CC_CONF_ALIGN(n) __attribute__((__aligned__(n))) + +#endif /* __GNUC__ */ +#endif /* _CC_GCC_H_ */ diff --git a/core/sys/cc.h b/core/sys/cc.h index 2fd9c2208..55567a954 100644 --- a/core/sys/cc.h +++ b/core/sys/cc.h @@ -1,13 +1,3 @@ -/** - * \file - * Default definitions of C compiler quirk work-arounds. - * \author Adam Dunkels - * - * This file is used for making use of extra functionality of some C - * compilers used for Contiki, and defining work-arounds for various - * quirks and problems with some other C compilers. - */ - /* * Copyright (c) 2003, Adam Dunkels. * All rights reserved. @@ -41,10 +31,22 @@ * * */ + +/** + * \file + * Default definitions of C compiler quirk work-arounds. + * \author Adam Dunkels + * + * This file is used for making use of extra functionality of some C + * compilers used for Contiki, and defining work-arounds for various + * quirks and problems with some other C compilers. + */ + #ifndef CC_H_ #define CC_H_ #include "contiki-conf.h" +#include "sys/cc-gcc.h" /** * Configure if the C compiler supports the "register" keyword for @@ -66,24 +68,14 @@ #define CC_FUNCTION_POINTER_ARGS 0 #endif /* CC_CONF_FUNCTION_POINTER_ARGS */ -/** - * Configure if the C compiler supports fastcall function - * declarations. - */ -#ifdef CC_CONF_FASTCALL -#define CC_FASTCALL CC_CONF_FASTCALL -#else /* CC_CONF_FASTCALL */ -#define CC_FASTCALL -#endif /* CC_CONF_FASTCALL */ - /** * Configure if the C compiler have problems with const function pointers */ #ifdef CC_CONF_CONST_FUNCTION_BUG #define CC_CONST_FUNCTION -#else /* CC_CONF_FASTCALL */ +#else /* CC_CONF_CONST_FUNCTION_BUG */ #define CC_CONST_FUNCTION const -#endif /* CC_CONF_FASTCALL */ +#endif /* CC_CONF_CONST_FUNCTION_BUG */ /** * Configure work-around for unsigned char bugs with sdcc. @@ -109,6 +101,10 @@ #define CC_INLINE #endif /* CC_CONF_INLINE */ +#ifdef CC_CONF_ALIGN +#define CC_ALIGN(n) CC_CONF_ALIGN(n) +#endif /* CC_CONF_INLINE */ + /** * Configure if the C compiler supports the assignment of struct value. */ @@ -122,18 +118,48 @@ #define CC_NO_VA_ARGS CC_CONF_VA_ARGS #endif +/** \def CC_ACCESS_NOW(x) + * This macro ensures that the access to a non-volatile variable can + * not be reordered or optimized by the compiler. + * See also https://lwn.net/Articles/508991/ - In Linux the macro is + * called ACCESS_ONCE + * The type must be passed, because the typeof-operator is a gcc + * extension + */ + +#define CC_ACCESS_NOW(type, variable) (*(volatile type *)&(variable)) + #ifndef NULL #define NULL 0 #endif /* NULL */ +#ifndef MAX +#define MAX(n, m) (((n) < (m)) ? (m) : (n)) +#endif + +#ifndef MIN +#define MIN(n, m) (((n) < (m)) ? (n) : (m)) +#endif + +#ifndef ABS +#define ABS(n) (((n) < 0) ? -(n) : (n)) +#endif + + #define CC_CONCAT2(s1, s2) s1##s2 /** - * A C preprocessing macro for concatenating to - * strings. + * A C preprocessing macro for concatenating two preprocessor tokens. * * We need use two macros (CC_CONCAT and CC_CONCAT2) in order to allow - * concatenation of two #defined macros. + * concatenation of two \#defined macros. */ #define CC_CONCAT(s1, s2) CC_CONCAT2(s1, s2) +#define CC_CONCAT_EXT_2(s1, s2) CC_CONCAT2(s1, s2) + +/** + * A C preprocessing macro for concatenating three preprocessor tokens. + */ +#define CC_CONCAT3(s1, s2, s3) s1##s2##s3 +#define CC_CONCAT_EXT_3(s1, s2, s3) CC_CONCAT3(s1, s2, s3) #endif /* CC_H_ */ diff --git a/core/sys/clock.h b/core/sys/clock.h index bbf5988ee..4cbfdb223 100644 --- a/core/sys/clock.h +++ b/core/sys/clock.h @@ -1,37 +1,3 @@ -/** \addtogroup sys - * @{ - */ - -/** - * \defgroup clock Clock library - * - * The clock library is the interface between Contiki and the platform - * specific clock functionality. The clock library defines a macro, - * CLOCK_SECOND, to convert seconds into the tick resolution of the platform. - * Typically this is 1-10 milliseconds, e.g. 4*CLOCK_SECOND could be 512. - * A 16 bit counter would thus overflow every 1-10 minutes. - * Platforms use the tick interrupt to maintain a long term count - * of seconds since startup. - * - * Platforms may also implement rtimers for greater time resolution - * and for real-time interrupts, These use a corresponding RTIMER_SECOND. - * - * \note These timers do not necessarily have a common divisor or are phase locked. - * One may be crystal controlled and the other may not. Low power operation - * or sleep will often use one for wake and disable the other, then give - * it a tick correction after wakeup. - * - * \note The clock library need in many cases not be used - * directly. Rather, the \ref timer "timer library", \ref etimer - * "event timers", or \ref trimer "rtimer library" should be used. - * - * \sa \ref timer "Timer library" - * \sa \ref etimer "Event timers" - * \sa \ref rtimer "Realtime library" - * - * @{ - */ - /* * Copyright (c) 2004, Swedish Institute of Computer Science. * All rights reserved. @@ -65,6 +31,41 @@ * Author: Adam Dunkels * */ + +/** \addtogroup sys + * @{ + */ + +/** + * \defgroup clock Clock library + * + * The clock library is the interface between Contiki and the platform + * specific clock functionality. The clock library defines a macro, + * CLOCK_SECOND, to convert seconds into the tick resolution of the platform. + * Typically this is 1-10 milliseconds, e.g. 4*CLOCK_SECOND could be 512. + * A 16 bit counter would thus overflow every 1-10 minutes. + * Platforms use the tick interrupt to maintain a long term count + * of seconds since startup. + * + * Platforms may also implement rtimers for greater time resolution + * and for real-time interrupts, These use a corresponding RTIMER_SECOND. + * + * \note These timers do not necessarily have a common divisor or are phase locked. + * One may be crystal controlled and the other may not. Low power operation + * or sleep will often use one for wake and disable the other, then give + * it a tick correction after wakeup. + * + * \note The clock library need in many cases not be used + * directly. Rather, the \ref timer "timer library", \ref etimer + * "event timers", or \ref rtimer "rtimer library" should be used. + * + * \sa \ref timer "Timer library" + * \sa \ref etimer "Event timers" + * \sa \ref rtimer "Realtime library" + * + * @{ + */ + #ifndef CLOCK_H_ #define CLOCK_H_ diff --git a/core/sys/compower.c b/core/sys/compower.c index b920c3e70..02a0f3c4c 100644 --- a/core/sys/compower.c +++ b/core/sys/compower.c @@ -1,8 +1,3 @@ -/** - * \addtogroup compower - * @{ - */ - /* * Copyright (c) 2009, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup compower + * @{ + */ + #include "contiki-conf.h" #include "sys/energest.h" #include "sys/compower.h" diff --git a/core/sys/compower.h b/core/sys/compower.h index 202065eb3..03d984193 100644 --- a/core/sys/compower.h +++ b/core/sys/compower.h @@ -1,17 +1,3 @@ -/** \addtogroup sys - * @{ */ - -/** - * \defgroup compower Communication power accounting - * @{ - * - * The compower module accumulates power consumption information and - * attributes it to communication activities. Examples of - * communication activities are packet transmission, packet reception, - * and idle listening. - * - */ - /* * Copyright (c) 2009, Swedish Institute of Computer Science. * All rights reserved. @@ -51,6 +37,20 @@ * Adam Dunkels */ +/** \addtogroup sys + * @{ */ + +/** + * \defgroup compower Communication power accounting + * @{ + * + * The compower module accumulates power consumption information and + * attributes it to communication activities. Examples of + * communication activities are packet transmission, packet reception, + * and idle listening. + * + */ + #ifndef COMPOWER_H_ #define COMPOWER_H_ diff --git a/core/sys/ctimer.c b/core/sys/ctimer.c index e6090a9a8..66698a8e6 100644 --- a/core/sys/ctimer.c +++ b/core/sys/ctimer.c @@ -1,8 +1,3 @@ -/** - * \addtogroup ctimer - * @{ - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup ctimer + * @{ + */ + #include "sys/ctimer.h" #include "contiki.h" #include "lib/list.h" @@ -98,9 +98,16 @@ ctimer_init(void) void ctimer_set(struct ctimer *c, clock_time_t t, void (*f)(void *), void *ptr) +{ + ctimer_set_with_process(c, t, f, ptr, PROCESS_CURRENT()); +} +/*---------------------------------------------------------------------------*/ +void +ctimer_set_with_process(struct ctimer *c, clock_time_t t, + void (*f)(void *), void *ptr, struct process *p) { PRINTF("ctimer_set %p %u\n", c, (unsigned)t); - c->p = PROCESS_CURRENT(); + c->p = p; c->f = f; c->ptr = ptr; if(initialized) { @@ -111,7 +118,6 @@ ctimer_set(struct ctimer *c, clock_time_t t, c->etimer.timer.interval = t; } - list_remove(ctimer_list, c); list_add(ctimer_list, c); } /*---------------------------------------------------------------------------*/ @@ -124,7 +130,6 @@ ctimer_reset(struct ctimer *c) PROCESS_CONTEXT_END(&ctimer_process); } - list_remove(ctimer_list, c); list_add(ctimer_list, c); } /*---------------------------------------------------------------------------*/ @@ -137,7 +142,6 @@ ctimer_restart(struct ctimer *c) PROCESS_CONTEXT_END(&ctimer_process); } - list_remove(ctimer_list, c); list_add(ctimer_list, c); } /*---------------------------------------------------------------------------*/ diff --git a/core/sys/ctimer.h b/core/sys/ctimer.h index 27311ddfb..dabf43d8a 100644 --- a/core/sys/ctimer.h +++ b/core/sys/ctimer.h @@ -1,17 +1,3 @@ -/** - * \addtogroup sys - * @{ - */ - -/** - * \defgroup ctimer Callback timer - * @{ - * - * The ctimer module provides a timer mechanism that calls a specified - * C function when a ctimer expires. - * - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -51,6 +37,20 @@ * Adam Dunkels */ +/** + * \addtogroup sys + * @{ + */ + +/** + * \defgroup ctimer Callback timer + * @{ + * + * The ctimer module provides a timer mechanism that calls a specified + * C function when a ctimer expires. + * + */ + #ifndef CTIMER_H_ #define CTIMER_H_ @@ -109,10 +109,28 @@ void ctimer_restart(struct ctimer *c); * sometime in the future. When the callback timer expires, * the callback function f will be called with ptr as argument. * + * This essentially does ctimer_set_process(c, t, f, ptr, PROCESS_CURRENT()); + * */ void ctimer_set(struct ctimer *c, clock_time_t t, void (*f)(void *), void *ptr); +/** + * \brief Set a callback timer. + * \param c A pointer to the callback timer. + * \param t The interval before the timer expires. + * \param f A function to be called when the timer expires. + * \param ptr An opaque pointer that will be supplied as an argument to the callback function. + * \param p A pointer to the process the timer belongs to + * + * This function is used to set a callback timer for a time + * sometime in the future. When the callback timer expires, + * the callback function f will be called with ptr as argument. + * + */ +void ctimer_set_with_process(struct ctimer *c, clock_time_t t, + void (*f)(void *), void *ptr, struct process *p); + /** * \brief Stop a pending callback timer. * \param c A pointer to the pending callback timer. diff --git a/core/sys/dsc.h b/core/sys/dsc.h index 5c3994741..b8b70433e 100644 --- a/core/sys/dsc.h +++ b/core/sys/dsc.h @@ -1,30 +1,3 @@ -/** - * \file - * Declaration of the DSC program description structure. - * \author Adam Dunkels - * - */ - -/** - * \addtogroup loader - * @{ - */ - -/** - * \page dsc The program description structure - * - * The Contiki DSC structure is used for describing programs. It - * includes a string describing the program, the name of the program - * file on disk (or a pointer to the programs initialization function - * for systems without disk support), a bitmap icon and a text version - * of the same icon. - * - * The DSC is saved into a file which can be loaded by programs such - * as the "Directory" application which reads all DSC files on disk - * and presents the icons and descriptions in a window. - * - */ - /* * Copyright (c) 2003, Adam Dunkels. * All rights reserved. @@ -58,6 +31,34 @@ * * */ + +/** + * \file + * Declaration of the DSC program description structure. + * \author Adam Dunkels + * + */ + +/** + * \addtogroup loader + * @{ + */ + +/** + * \page dsc The program description structure + * + * The Contiki DSC structure is used for describing programs. It + * includes a string describing the program, the name of the program + * file on disk (or a pointer to the programs initialization function + * for systems without disk support), a bitmap icon and a text version + * of the same icon. + * + * The DSC is saved into a file which can be loaded by programs such + * as the "Directory" application which reads all DSC files on disk + * and presents the icons and descriptions in a window. + * + */ + #ifndef DSC_H_ #define DSC_H_ @@ -104,7 +105,7 @@ struct dsc { * * \param prgname The name of the program on disk. * - * \param initfunc A pointer to the initialization function of the + * \param process A pointer to the initialization function of the * program. * * \param icon A pointer to the CTK icon. diff --git a/core/sys/energest.h b/core/sys/energest.h index 6d43aaa11..a8f445b65 100644 --- a/core/sys/energest.h +++ b/core/sys/energest.h @@ -105,6 +105,21 @@ extern energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVI energest_current_time[type]); \ energest_current_mode[type] = 0; \ } while(0) + +#define ENERGEST_SWITCH(type_off, type_on) do { \ + rtimer_clock_t energest_local_variable_now = RTIMER_NOW(); \ + if(energest_current_mode[type_off] != 0) { \ + if (energest_local_variable_now < energest_current_time[type_off]) { \ + energest_total_time[type_off].current += RTIMER_ARCH_SECOND; \ + } \ + energest_total_time[type_off].current += (rtimer_clock_t)(energest_local_variable_now - \ + energest_current_time[type_off]); \ + energest_current_mode[type_off] = 0; \ + } \ + energest_current_time[type_on] = energest_local_variable_now; \ + energest_current_mode[type_on] = 1; \ + } while(0) + #else #define ENERGEST_OFF(type) if(energest_current_mode[type] != 0) do { \ energest_total_time[type].current += (rtimer_clock_t)(RTIMER_NOW() - \ @@ -117,13 +132,24 @@ extern energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVI energest_current_time[type]); \ energest_current_mode[type] = 0; \ } while(0) -#endif +#define ENERGEST_SWITCH(type_off, type_on) do { \ + rtimer_clock_t energest_local_variable_now = RTIMER_NOW(); \ + if(energest_current_mode[type_off] != 0) { \ + energest_total_time[type_off].current += (rtimer_clock_t)(energest_local_variable_now - \ + energest_current_time[type_off]); \ + energest_current_mode[type_off] = 0; \ + } \ + energest_current_time[type_on] = energest_local_variable_now; \ + energest_current_mode[type_on] = 1; \ + } while(0) +#endif #else /* ENERGEST_CONF_ON */ #define ENERGEST_ON(type) do { } while(0) #define ENERGEST_OFF(type) do { } while(0) #define ENERGEST_OFF_LEVEL(type,level) do { } while(0) +#define ENERGEST_SWITCH(type_off, type_on) do { } while(0) #endif /* ENERGEST_CONF_ON */ #endif /* ENERGEST_H_ */ diff --git a/core/sys/etimer.c b/core/sys/etimer.c index 34917aa93..17ac74285 100644 --- a/core/sys/etimer.c +++ b/core/sys/etimer.c @@ -1,15 +1,3 @@ -/** - * \addtogroup etimer - * @{ - */ - -/** - * \file - * Event timer library implementation. - * \author - * Adam Dunkels - */ - /* * Copyright (c) 2004, Swedish Institute of Computer Science. * All rights reserved. @@ -44,6 +32,18 @@ * */ +/** + * \addtogroup etimer + * @{ + */ + +/** + * \file + * Event timer library implementation. + * \author + * Adam Dunkels + */ + #include "contiki-conf.h" #include "sys/etimer.h" @@ -181,6 +181,14 @@ etimer_set(struct etimer *et, clock_time_t interval) } /*---------------------------------------------------------------------------*/ void +etimer_reset_with_new_interval(struct etimer *et, clock_time_t interval) +{ + timer_reset(&et->timer); + et->timer.interval = interval; + add_timer(et); +} +/*---------------------------------------------------------------------------*/ +void etimer_reset(struct etimer *et) { timer_reset(&et->timer); diff --git a/core/sys/etimer.h b/core/sys/etimer.h index 10452dc2a..ebbcfc7fd 100644 --- a/core/sys/etimer.h +++ b/core/sys/etimer.h @@ -1,31 +1,3 @@ -/** \addtogroup sys - * @{ */ - -/** - * \defgroup etimer Event timers - * - * Event timers provides a way to generate timed events. An event - * timer will post an event to the process that set the timer when the - * event timer expires. - * - * An event timer is declared as a \c struct \c etimer and all access - * to the event timer is made by a pointer to the declared event - * timer. - * - * \sa \ref timer "Simple timer library" - * \sa \ref clock "Clock library" (used by the timer library) - * - * @{ - */ - - -/** - * \file - * Event timer header file. - * \author - * Adam Dunkels - */ - /* * Copyright (c) 2004, Swedish Institute of Computer Science. * All rights reserved. @@ -59,6 +31,34 @@ * Author: Adam Dunkels * */ + +/** + * \file + * Event timer header file. + * \author + * Adam Dunkels + */ + +/** \addtogroup sys + * @{ */ + +/** + * \defgroup etimer Event timers + * + * Event timers provides a way to generate timed events. An event + * timer will post an event to the process that set the timer when the + * event timer expires. + * + * An event timer is declared as a \c struct \c etimer and all access + * to the event timer is made by a pointer to the declared event + * timer. + * + * \sa \ref timer "Simple timer library" + * \sa \ref clock "Clock library" (used by the timer library) + * + * @{ + */ + #ifndef ETIMER_H_ #define ETIMER_H_ @@ -114,6 +114,19 @@ CCIF void etimer_set(struct etimer *et, clock_time_t interval); */ CCIF void etimer_reset(struct etimer *et); +/** + * \brief Reset an event timer with a new interval. + * \param et A pointer to the event timer. + * \param interval The interval before the timer expires. + * + * This function very similar to etimer_reset. Opposed to + * etimer_reset it is possible to change the timout. + * This allows accurate, non-periodic timers without drift. + * + * \sa etimer_reset() + */ +void etimer_reset_with_new_interval(struct etimer *et, clock_time_t interval); + /** * \brief Restart an event timer from the current point in time * \param et A pointer to the event timer. diff --git a/core/sys/lc.h b/core/sys/lc.h index 3f57d879c..6062a21e2 100644 --- a/core/sys/lc.h +++ b/core/sys/lc.h @@ -51,7 +51,7 @@ */ /** - * \file lc.h + * \file core/sys/lc.h * Local continuations * \author * Adam Dunkels diff --git a/core/sys/loader.h b/core/sys/loader.h index e54629aff..7d2e264c6 100644 --- a/core/sys/loader.h +++ b/core/sys/loader.h @@ -1,23 +1,3 @@ -/** \addtogroup sys - * @{ - */ - -/** - * \defgroup loader The Contiki program loader - * - * The Contiki program loader is an abstract interface for loading and - * starting programs. - * - * @{ - */ - -/** - * \file - * Default definitions and error values for the Contiki program loader. - * \author Adam Dunkels - * - */ - /* * Copyright (c) 2003, Adam Dunkels. * All rights reserved. @@ -51,6 +31,27 @@ * * */ + +/** + * \file + * Default definitions and error values for the Contiki program loader. + * \author Adam Dunkels + * + */ + +/** \addtogroup sys + * @{ + */ + +/** + * \defgroup loader The Contiki program loader + * + * The Contiki program loader is an abstract interface for loading and + * starting programs. + * + * @{ + */ + #ifndef LOADER_H_ #define LOADER_H_ diff --git a/core/sys/mt.c b/core/sys/mt.c index cfa8a39a5..430440fe8 100644 --- a/core/sys/mt.c +++ b/core/sys/mt.c @@ -46,10 +46,6 @@ #include "sys/mt.h" #include "sys/cc.h" -#define MT_STATE_READY 1 -#define MT_STATE_RUNNING 2 -#define MT_STATE_EXITED 5 - static struct mt_thread *current; /*--------------------------------------------------------------------------*/ diff --git a/core/sys/mt.h b/core/sys/mt.h index 0e67dee0d..f6296e24a 100644 --- a/core/sys/mt.h +++ b/core/sys/mt.h @@ -84,6 +84,9 @@ #include "contiki.h" +#define MT_STATE_READY 1 +#define MT_STATE_RUNNING 2 +#define MT_STATE_EXITED 5 /** * An opaque structure that is used for holding the state of a thread. diff --git a/core/sys/process.c b/core/sys/process.c index 8a7496d75..f98057cd3 100644 --- a/core/sys/process.c +++ b/core/sys/process.c @@ -96,7 +96,7 @@ process_alloc_event(void) } /*---------------------------------------------------------------------------*/ void -process_start(struct process *p, const char *arg) +process_start(struct process *p, process_data_t data) { struct process *q; @@ -117,7 +117,7 @@ process_start(struct process *p, const char *arg) PRINTF("process: starting '%s'\n", PROCESS_NAME_STRING(p)); /* Post a synchronous initialization event to the process. */ - process_post_synch(p, PROCESS_EVENT_INIT, (process_data_t)arg); + process_post_synch(p, PROCESS_EVENT_INIT, data); } /*---------------------------------------------------------------------------*/ static void @@ -245,10 +245,10 @@ do_poll(void) static void do_event(void) { - static process_event_t ev; - static process_data_t data; - static struct process *receiver; - static struct process *p; + process_event_t ev; + process_data_t data; + struct process *receiver; + struct process *p; /* * If there are any events in the queue, take the first one and walk @@ -267,7 +267,7 @@ do_event(void) receiver = events[fevent].p; /* Since we have seen the new event, we move pointer upwards - and decrese the number of events. */ + and decrease the number of events. */ fevent = (fevent + 1) % PROCESS_CONF_NUMEVENTS; --nevents; @@ -321,7 +321,7 @@ process_nevents(void) int process_post(struct process *p, process_event_t ev, process_data_t data) { - static process_num_events_t snum; + process_num_events_t snum; if(PROCESS_CURRENT() == NULL) { PRINTF("process_post: NULL process posts event %d to process '%s', nevents %d\n", @@ -337,7 +337,7 @@ process_post(struct process *p, process_event_t ev, process_data_t data) if(p == PROCESS_BROADCAST) { printf("soft panic: event queue is full when broadcast event %d was posted from %s\n", ev, PROCESS_NAME_STRING(process_current)); } else { - printf("soft panic: event queue is full when event %d was posted to %s frpm %s\n", ev, PROCESS_NAME_STRING(p), PROCESS_NAME_STRING(process_current)); + printf("soft panic: event queue is full when event %d was posted to %s from %s\n", ev, PROCESS_NAME_STRING(p), PROCESS_NAME_STRING(process_current)); } #endif /* DEBUG */ return PROCESS_ERR_FULL; diff --git a/core/sys/process.h b/core/sys/process.h index 7063ee024..2d15ca89c 100644 --- a/core/sys/process.h +++ b/core/sys/process.h @@ -335,11 +335,11 @@ struct process { * * \param p A pointer to a process structure. * - * \param arg An argument pointer that can be passed to the new + * \param data An argument pointer that can be passed to the new * process * */ -CCIF void process_start(struct process *p, const char *arg); +CCIF void process_start(struct process *p, process_data_t data); /** * Post an asynchronous event. @@ -362,7 +362,7 @@ CCIF void process_start(struct process *p, const char *arg); * \retval PROCESS_ERR_FULL The event queue was full and the event could * not be posted. */ -CCIF int process_post(struct process *p, process_event_t ev, void* data); +CCIF int process_post(struct process *p, process_event_t ev, process_data_t data); /** * Post a synchronous event to a process. @@ -375,7 +375,7 @@ CCIF int process_post(struct process *p, process_event_t ev, void* data); * with the event. */ CCIF void process_post_synch(struct process *p, - process_event_t ev, void* data); + process_event_t ev, process_data_t data); /** * \brief Cause a process to exit diff --git a/core/sys/pt-sem.h b/core/sys/pt-sem.h index 75d66452a..27effa57a 100644 --- a/core/sys/pt-sem.h +++ b/core/sys/pt-sem.h @@ -162,9 +162,11 @@ PT_THREAD(driver_thread(struct pt *pt)) #include "sys/pt.h" struct pt_sem { - unsigned int count; + unsigned int head, tail; }; +#define PT_SEM_COUNT(s) ((s)->head - (s)->tail) + /** * Initialize a semaphore * @@ -179,7 +181,11 @@ struct pt_sem { * \param c (unsigned int) The initial count of the semaphore. * \hideinitializer */ -#define PT_SEM_INIT(s, c) (s)->count = c +#define PT_SEM_INIT(s, c) \ + do { \ + (s)->tail = 0; \ + (s)->head = (c); \ + } while(0) /** * Wait for a semaphore @@ -199,8 +205,8 @@ struct pt_sem { */ #define PT_SEM_WAIT(pt, s) \ do { \ - PT_WAIT_UNTIL(pt, (s)->count > 0); \ - --(s)->count; \ + PT_WAIT_UNTIL(pt, PT_SEM_COUNT(s) > 0); \ + ++(s)->tail; \ } while(0) /** @@ -218,7 +224,7 @@ struct pt_sem { * * \hideinitializer */ -#define PT_SEM_SIGNAL(pt, s) ++(s)->count +#define PT_SEM_SIGNAL(pt, s) (++(s)->head) #endif /* PT_SEM_H_ */ diff --git a/core/sys/rtimer.c b/core/sys/rtimer.c index 282c8d86b..cf96a17bf 100644 --- a/core/sys/rtimer.c +++ b/core/sys/rtimer.c @@ -1,17 +1,3 @@ -/** - * \addtogroup rt - * @{ - */ - -/** - * \file - * Implementation of the architecture-agnostic parts of the real-time timer module. - * \author - * Adam Dunkels - * - */ - - /* * Copyright (c) 2005, Swedish Institute of Computer Science * All rights reserved. @@ -44,6 +30,19 @@ * */ +/** + * \file + * Implementation of the architecture-agnostic parts of the real-time timer module. + * \author + * Adam Dunkels + * + */ + +/** + * \addtogroup rt + * @{ + */ + #include "sys/rtimer.h" #include "contiki.h" diff --git a/core/sys/rtimer.h b/core/sys/rtimer.h index 7f393947d..a89ed8299 100644 --- a/core/sys/rtimer.h +++ b/core/sys/rtimer.h @@ -1,23 +1,3 @@ -/** \addtogroup sys - * @{ */ - -/** - * \defgroup rt Real-time task scheduling - * - * The real-time module handles the scheduling and execution of - * real-time tasks (with predictable execution times). - * - * @{ - */ - -/** - * \file - * Header file for the real-time timer module. - * \author - * Adam Dunkels - * - */ - /* * Copyright (c) 2005, Swedish Institute of Computer Science * All rights reserved. @@ -49,15 +29,38 @@ * This file is part of the Contiki operating system. * */ + +/** + * \file + * Header file for the real-time timer module. + * \author + * Adam Dunkels + * + */ + +/** \addtogroup sys + * @{ */ + +/** + * \defgroup rt Real-time task scheduling + * + * The real-time module handles the scheduling and execution of + * real-time tasks (with predictable execution times). + * + * @{ + */ + #ifndef RTIMER_H_ #define RTIMER_H_ #include "contiki-conf.h" -#ifndef RTIMER_CLOCK_LT +#ifndef RTIMER_CLOCK_DIFF typedef unsigned short rtimer_clock_t; -#define RTIMER_CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) -#endif /* RTIMER_CLOCK_LT */ +#define RTIMER_CLOCK_DIFF(a,b) ((signed short)((a)-(b))) +#endif /* RTIMER_CLOCK_DIFF */ + +#define RTIMER_CLOCK_LT(a, b) (RTIMER_CLOCK_DIFF((a),(b)) < 0) #include "rtimer-arch.h" @@ -150,6 +153,16 @@ void rtimer_arch_schedule(rtimer_clock_t t); #define RTIMER_SECOND RTIMER_ARCH_SECOND +/* RTIMER_GUARD_TIME is the minimum amount of rtimer ticks between + the current time and the future time when a rtimer is scheduled. + Necessary to avoid accidentally scheduling a rtimer in the past + on platforms with fast rtimer ticks. Should be >= 2. */ +#ifdef RTIMER_CONF_GUARD_TIME +#define RTIMER_GUARD_TIME RTIMER_CONF_GUARD_TIME +#else /* RTIMER_CONF_GUARD_TIME */ +#define RTIMER_GUARD_TIME (RTIMER_ARCH_SECOND >> 14) +#endif /* RTIMER_CONF_GUARD_TIME */ + #endif /* RTIMER_H_ */ /** @} */ diff --git a/core/sys/stimer.c b/core/sys/stimer.c index 0e13651d8..86545f59e 100644 --- a/core/sys/stimer.c +++ b/core/sys/stimer.c @@ -1,15 +1,3 @@ -/** - * \addtogroup stimer - * @{ - */ - -/** - * \file - * Timer of seconds library implementation. - * \author - * Adam Dunkels , Nicolas Tsiftes - */ - /* * Copyright (c) 2004, 2008, Swedish Institute of Computer Science. * All rights reserved. @@ -44,6 +32,18 @@ * */ +/** + * \file + * Timer of seconds library implementation. + * \author + * Adam Dunkels , Nicolas Tsiftes + */ + +/** + * \addtogroup stimer + * @{ + */ + #include "contiki-conf.h" #include "sys/clock.h" #include "sys/stimer.h" diff --git a/core/sys/stimer.h b/core/sys/stimer.h index 3615fc58c..6ef7db5de 100644 --- a/core/sys/stimer.h +++ b/core/sys/stimer.h @@ -1,37 +1,3 @@ -/** \addtogroup sys - * @{ */ - -/** - * \defgroup stimer Seconds timer library - * - * The stimer library provides functions for setting, resetting and - * restarting timers, and for checking if a timer has expired. An - * application must "manually" check if its timers have expired; this - * is not done automatically. - * - * A timer is declared as a \c struct \c stimer and all access to the - * timer is made by a pointer to the declared timer. - * - * \note The stimer library is not able to post events when a timer - * expires. The \ref etimer "Event timers" should be used for this - * purpose. - * - * \note The stimer library uses the \ref clock "Clock library" to - * measure time. Intervals should be specified in the seconds. - * - * \sa \ref etimer "Event timers" - * - * @{ - */ - - -/** - * \file - * Second timer library header file. - * \author - * Adam Dunkels , Nicolas Tsiftes - */ - /* * Copyright (c) 2004, 2008, Swedish Institute of Computer Science. * All rights reserved. @@ -65,6 +31,40 @@ * Author: Adam Dunkels , Nicolas Tsiftes * */ + +/** + * \file + * Second timer library header file. + * \author + * Adam Dunkels , Nicolas Tsiftes + */ + +/** \addtogroup sys + * @{ */ + +/** + * \defgroup stimer Seconds timer library + * + * The stimer library provides functions for setting, resetting and + * restarting timers, and for checking if a timer has expired. An + * application must "manually" check if its timers have expired; this + * is not done automatically. + * + * A timer is declared as a \c struct \c stimer and all access to the + * timer is made by a pointer to the declared timer. + * + * \note The stimer library is not able to post events when a timer + * expires. The \ref etimer "Event timers" should be used for this + * purpose. + * + * \note The stimer library uses the \ref clock "Clock library" to + * measure time. Intervals should be specified in the seconds. + * + * \sa \ref etimer "Event timers" + * + * @{ + */ + #ifndef STIMER_H_ #define STIMER_H_ diff --git a/core/sys/timer.c b/core/sys/timer.c index d13b61f98..6fe64119b 100644 --- a/core/sys/timer.c +++ b/core/sys/timer.c @@ -1,15 +1,3 @@ -/** - * \addtogroup timer - * @{ - */ - -/** - * \file - * Timer library implementation. - * \author - * Adam Dunkels - */ - /* * Copyright (c) 2004, Swedish Institute of Computer Science. * All rights reserved. @@ -44,6 +32,18 @@ * */ +/** + * \file + * Timer library implementation. + * \author + * Adam Dunkels + */ + +/** + * \addtogroup timer + * @{ + */ + #include "contiki-conf.h" #include "sys/clock.h" #include "sys/timer.h" @@ -76,8 +76,9 @@ timer_set(struct timer *t, clock_time_t interval) * function will cause the timer to be stable over time, unlike the * timer_restart() function. * - * \param t A pointer to the timer. + * \note Must not be executed before timer expired * + * \param t A pointer to the timer. * \sa timer_restart() */ void diff --git a/core/sys/timer.h b/core/sys/timer.h index 06a25524c..969137507 100644 --- a/core/sys/timer.h +++ b/core/sys/timer.h @@ -1,42 +1,3 @@ -/** \addtogroup sys - * @{ */ - -/** - * \defgroup timer Timer library - * - * The Contiki kernel does not provide support for timed - * events. Rather, an application that wants to use timers needs to - * explicitly use the timer library. - * - * The timer library provides functions for setting, resetting and - * restarting timers, and for checking if a timer has expired. An - * application must "manually" check if its timers have expired; this - * is not done automatically. - * - * A timer is declared as a \c struct \c timer and all access to the - * timer is made by a pointer to the declared timer. - * - * \note The timer library is not able to post events when a timer - * expires. The \ref etimer "Event timers" should be used for this - * purpose. - * - * \note The timer library uses the \ref clock "Clock library" to - * measure time. Intervals should be specified in the format used by - * the clock library. - * - * \sa \ref etimer "Event timers" - * - * @{ - */ - - -/** - * \file - * Timer library header file. - * \author - * Adam Dunkels - */ - /* * Copyright (c) 2004, Swedish Institute of Computer Science. * All rights reserved. @@ -70,6 +31,45 @@ * Author: Adam Dunkels * */ + +/** + * \file + * Timer library header file. + * \author + * Adam Dunkels + */ + +/** \addtogroup sys + * @{ */ + +/** + * \defgroup timer Timer library + * + * The Contiki kernel does not provide support for timed + * events. Rather, an application that wants to use timers needs to + * explicitly use the timer library. + * + * The timer library provides functions for setting, resetting and + * restarting timers, and for checking if a timer has expired. An + * application must "manually" check if its timers have expired; this + * is not done automatically. + * + * A timer is declared as a \c struct \c timer and all access to the + * timer is made by a pointer to the declared timer. + * + * \note The timer library is not able to post events when a timer + * expires. The \ref etimer "Event timers" should be used for this + * purpose. + * + * \note The timer library uses the \ref clock "Clock library" to + * measure time. Intervals should be specified in the format used by + * the clock library. + * + * \sa \ref etimer "Event timers" + * + * @{ + */ + #ifndef TIMER_H_ #define TIMER_H_ diff --git a/cpu/6502/6502def.h b/cpu/6502/6502def.h index 1d7b5c440..2da81b02e 100644 --- a/cpu/6502/6502def.h +++ b/cpu/6502/6502def.h @@ -51,7 +51,6 @@ typedef uint32_t u32_t; typedef int32_t s32_t; #define CC_CONF_REGISTER_ARGS 1 -#define CC_CONF_FASTCALL __fastcall__ #define ARCH_DOESNT_NEED_ALIGNED_STRUCTS 1 @@ -61,7 +60,7 @@ typedef int32_t s32_t; #define HAVE_SNPRINTF #define snprintf(buf, len, ...) sprintf(buf, __VA_ARGS__) -#define CLOCK_CONF_SECOND 2 +#define CLOCK_CONF_SECOND 4 typedef unsigned short clock_time_t; typedef unsigned short uip_stats_t; @@ -72,7 +71,6 @@ typedef unsigned short uip_stats_t; #define UIP_CONF_LLH_LEN 14 #define RESOLV_CONF_SUPPORTS_MDNS 0 #define RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION 0 -#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 1 #define LOADER_CONF_ARCH "lib/unload.h" @@ -85,7 +83,7 @@ typedef unsigned short uip_stats_t; #if CONNECTIONS #define UIP_CONF_MAX_CONNECTIONS CONNECTIONS #else /* CONNECTIONS */ -#define UIP_CONF_MAX_CONNECTIONS 10 +#define UIP_CONF_MAX_CONNECTIONS 2 #endif /* CONNECTIONS */ #if WITH_LOGGING diff --git a/cpu/6502/Makefile.6502 b/cpu/6502/Makefile.6502 index 7ef11fe21..07e8e3af6 100644 --- a/cpu/6502/Makefile.6502 +++ b/cpu/6502/Makefile.6502 @@ -31,12 +31,6 @@ # Author: Oliver Schmidt # -ifndef CC65_HOME - ${error CC65_HOME not defined! You must specify where cc65 resides} -endif - -all: cs8900a.eth lan91c96.eth w5100.eth - .SUFFIXES: CONTIKI_TARGET_DIRS = . lib sys @@ -47,15 +41,18 @@ CONTIKI_CPU_SOURCEFILES += log.c error.c unload.c config.c ctk-mouse.c \ clock.c mtarch.c mtarch-asm.S lc-asm.S \ uip_arch.c ethernet-drv.c ethernet.c +ETHERNET_SOURCEFILES = cs8900a.S lan91c96.S w5100.S + CONTIKI_SOURCEFILES += $(CTK) ctk-conio.c petsciiconv.c cfs-posix-dir.c \ - $(CONTIKI_TARGET_SOURCEFILES) $(CONTIKI_CPU_SOURCEFILES) + $(CONTIKI_TARGET_SOURCEFILES) $(CONTIKI_CPU_SOURCEFILES) \ + $(ETHERNET_SOURCEFILES) -MODULES += core/ctk core/net/ip core/net/ipv4 core/net/ipv6 +MODULES += core/ctk -ifdef ETHERNET - CONTIKI_SOURCEFILES += $(ETHERNET)-eth.S - CFLAGS += -DETHERNET=$(ETHERNET) -endif +# Set target-specific variable values +${addprefix $(OBJECTDIR)/,${call oname, $(ETHERNET_SOURCEFILES)}}: ASFLAGS += -D DYN_DRV=0 + +all: $(ETHERNET_SOURCEFILES:.S=.eth) AS = ca65 CC = cl65 @@ -69,3 +66,5 @@ ASFLAGS = -t $(TARGET) CFLAGS += -t $(TARGET) -Or -W -unused-param LDFLAGS = -t $(TARGET) -m contiki-$(TARGET).map -D __STACKSIZE__=0x200 AROPTS = a + +CC65_TARGET_DIR := $(shell $(CC) --print-target-path)/$(TARGET) diff --git a/cpu/6502/Makefile.customrules-6502 b/cpu/6502/Makefile.customrules-6502 index 80b22294e..e0953362d 100644 --- a/cpu/6502/Makefile.customrules-6502 +++ b/cpu/6502/Makefile.customrules-6502 @@ -6,18 +6,17 @@ $(OBJECTDIR)/%.o: %.c | $(OBJECTDIR) CUSTOM_RULE_C_TO_CO = 1 %.co: %.c $(TRACE_CC) - $(Q)$(CC) -c -o $@ $(CFLAGS) -DAUTOSTART_ENABLE --create-dep $(@:.o=.d) $< + $(Q)$(CC) -c -o $@ $(CFLAGS) -DAUTOSTART_ENABLE $< CUSTOM_RULE_LINK = 1 %.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a $(TRACE_LD) $(Q)$(LD) -o $@ $(LDFLAGS) -u _main $^ $(TARGET).lib -%.eth: $(OBJECTDIR)/%.o +%.o: %.S + $(TRACE_AS) + $(Q)$(AS) $(ASFLAGS) -o $@ $< + +%.eth: %.o $(TRACE_LD) $(Q)$(LD) -o $@ -t module -m $@.map $< - -ifdef ETHERNET -$(ETHERNET)-eth.S: $(ETHERNET).eth - co65 -o $@ --code-label _$(ETHERNET) $< -endif diff --git a/cpu/6502/README.md b/cpu/6502/README.md index 93f4b5276..601aee288 100644 --- a/cpu/6502/README.md +++ b/cpu/6502/README.md @@ -37,9 +37,14 @@ high-level configuration macros may be set: - Purpose: Set the Maximum Transfer Unit size. - CONNECTIONS - - Default: 10 + - Default: 2 - Purpose: Set the maximum number of concurrent TCP connections. +- ETHERNET + - Default: N/A + - Purpose: Link Ethernet driver statically instead of loading it dynamically + using the network configuration file. + - WITH_LOGGING - Default: 0 - Purpose: Have log_message() and UIP_LOG() write messages to the screen. @@ -61,9 +66,13 @@ high-level configuration macros may be set: - Default: 0 - Purpose: Enable UDP support and initialize resolver process on startup. +- WITH_80COL + - Default: 0 + - Purpose: Enable 80 column screen. + - WITH_GUI - Default: 0 - - Purpose: Initialize the the CTK process on startup. + - Purpose: Initialize the CTK process on startup. - WITH_MOUSE - Default: 0 diff --git a/cpu/6502/ethconfig/Makefile b/cpu/6502/ethconfig/Makefile index 7a0df8d8f..9fff9eee6 100644 --- a/cpu/6502/ethconfig/Makefile +++ b/cpu/6502/ethconfig/Makefile @@ -2,4 +2,5 @@ CONTIKI_PROJECT = ethconfig all: $(CONTIKI_PROJECT) CONTIKI = ../../.. +CONTIKI_WITH_IPV4 = 1 include $(CONTIKI)/Makefile.include diff --git a/cpu/6502/ipconfig/Makefile b/cpu/6502/ipconfig/Makefile index a946180a2..751061ad0 100644 --- a/cpu/6502/ipconfig/Makefile +++ b/cpu/6502/ipconfig/Makefile @@ -2,4 +2,5 @@ CONTIKI_PROJECT = ipconfig all: $(CONTIKI_PROJECT) CONTIKI = ../../.. +CONTIKI_WITH_IPV4 = 1 include $(CONTIKI)/Makefile.include diff --git a/cpu/6502/ipconfig/ipconfig.c b/cpu/6502/ipconfig/ipconfig.c index d21994032..7c7584b67 100644 --- a/cpu/6502/ipconfig/ipconfig.c +++ b/cpu/6502/ipconfig/ipconfig.c @@ -117,7 +117,7 @@ makestrings(void) makeaddr(&addr, gateway); #if WITH_DNS - addrptr = resolv_getserver(); + addrptr = uip_nameserver_get(0); if(addrptr != NULL) { makeaddr(addrptr, dnsserver); } @@ -177,9 +177,9 @@ app_quit(void) PROCESS_THREAD(ipconfig_process, ev, data) { PROCESS_BEGIN(); - + ctk_window_new(&window, 29, 14, "IP config"); - + CTK_WIDGET_ADD(&window, &requestbutton); CTK_WIDGET_ADD(&window, &statuslabel); CTK_WIDGET_ADD(&window, &ipaddrlabel); @@ -208,11 +208,11 @@ PROCESS_THREAD(ipconfig_process, ev, data) while(1) { PROCESS_WAIT_EVENT(); - + if(ev == PROCESS_EVENT_MSG) { makestrings(); ctk_window_redraw(&window); - } else if(ev == tcpip_event) { + } else if(ev == tcpip_event || ev == PROCESS_EVENT_TIMER) { dhcpc_appcall(ev, data); } else if(ev == ctk_signal_button_activate) { if(data == (process_data_t)&requestbutton) { @@ -245,7 +245,7 @@ dhcpc_configured(const struct dhcpc_state *s) uip_setnetmask(&s->netmask); uip_setdraddr(&s->default_router); #if WITH_DNS - resolv_conf(&s->dnsaddr); + uip_nameserver_update(&s->dnsaddr, UIP_NAMESERVER_INFINITE_LIFETIME); #endif /* WITH_DNS */ set_statustext("Configured."); @@ -261,7 +261,7 @@ dhcpc_unconfigured(const struct dhcpc_state *s) uip_setnetmask(&nulladdr); uip_setdraddr(&nulladdr); #if WITH_DNS - resolv_conf(&nulladdr); + uip_nameserver_update(&nulladdr, UIP_NAMESERVER_INFINITE_LIFETIME); #endif /* WITH_DNS */ set_statustext("Unconfigured."); diff --git a/cpu/6502/lib/config.c b/cpu/6502/lib/config.c index 08677a682..7a013bd0b 100644 --- a/cpu/6502/lib/config.c +++ b/cpu/6502/lib/config.c @@ -43,7 +43,7 @@ /*-----------------------------------------------------------------------------------*/ #if LOG_CONF_ENABLED -static char * CC_FASTCALL +static char * ipaddrtoa(uip_ipaddr_t *ipaddr, char *buffer) { char *ptr = buffer; @@ -59,7 +59,7 @@ ipaddrtoa(uip_ipaddr_t *ipaddr, char *buffer) } #endif /* LOG_CONF_ENABLED */ /*-----------------------------------------------------------------------------------*/ -struct ethernet_config * CC_FASTCALL +struct ethernet_config * config_read(char *filename) { static struct { @@ -105,7 +105,7 @@ config_read(char *filename) uip_setnetmask(&config.netmask); uip_setdraddr(&config.draddr); #if WITH_DNS - resolv_conf(&config.resolvaddr); + uip_nameserver_update(&config.resolvaddr, UIP_NAMESERVER_INFINITE_LIFETIME); #endif /* WITH_DNS */ return &config.ethernetcfg; diff --git a/cpu/6502/lib/config.h b/cpu/6502/lib/config.h index 8f7f971be..11bc03463 100644 --- a/cpu/6502/lib/config.h +++ b/cpu/6502/lib/config.h @@ -35,6 +35,6 @@ #ifndef CONFIG_H_ #define CONFIG_H_ -struct ethernet_config * CC_FASTCALL config_read(char *filename); +struct ethernet_config * config_read(char *filename); #endif /* CONFIG_H_ */ diff --git a/cpu/6502/lib/pfs.h b/cpu/6502/lib/pfs.h index 25c62e8bf..73102ce55 100644 --- a/cpu/6502/lib/pfs.h +++ b/cpu/6502/lib/pfs.h @@ -27,7 +27,7 @@ * SUCH DAMAGE. * * This file is part of the Contiki operating system. - * + * * Author: Oliver Schmidt * */ @@ -35,11 +35,13 @@ #ifndef PFS_H_ #define PFS_H_ -int __fastcall__ pfs_open(const char* name, int flags); -void __fastcall__ pfs_close(int fd); -int __fastcall__ pfs_read(int fd, void* buf, unsigned int len); -int __fastcall__ pfs_write(int fd, void* buf, unsigned int len); -int __fastcall__ pfs_seek(int fd, int offset, int whence); -int __fastcall__ pfs_remove(const char *name); +#include + +int __fastcall__ pfs_open(const char *name, int flags); +void __fastcall__ pfs_close(int fd); +int __fastcall__ pfs_read(int fd, void *buf, unsigned int len); +int __fastcall__ pfs_write(int fd, const void *buf, unsigned int len); +off_t __fastcall__ pfs_seek(int fd, off_t offset, int whence); +int __fastcall__ pfs_remove(const char *name); #endif /* PFS_H_ */ diff --git a/cpu/6502/net/cs8900a.S b/cpu/6502/net/cs8900a.S index fc4d5d1ca..e650f28c2 100644 --- a/cpu/6502/net/cs8900a.S +++ b/cpu/6502/net/cs8900a.S @@ -32,7 +32,8 @@ ; ;--------------------------------------------------------------------- - .segment "JUMPTABLE" + .macpack module + module_header _cs8900a ; Driver signature .byte $65, $74, $68 ; "eth" @@ -47,21 +48,32 @@ bufaddr:.res 2 ; Address bufsize:.res 2 ; Size ; Jump table. - .addr init - .addr poll - .addr send - .addr exit + jmp init + jmp poll + jmp send + jmp exit ;--------------------------------------------------------------------- - .zeropage + .if DYN_DRV + .zeropage sp: .res 2 ; Stack pointer (Do not trash !) reg: .res 2 ; Address of rxtxreg ptr: .res 2 ; Indirect addressing pointer len: .res 2 ; Frame length cnt: .res 2 ; Frame length counter + .else + + .include "zeropage.inc" +reg := ptr1 ; Address of rxtxreg +ptr := ptr2 ; Indirect addressing pointer +len := ptr3 ; Frame length +cnt := ptr4 ; Frame length counter + + .endif + ;--------------------------------------------------------------------- .rodata @@ -73,17 +85,20 @@ fixup: .byte fixup02-fixup01, fixup03-fixup02, fixup04-fixup03 .byte fixup14-fixup13, fixup15-fixup14, fixup16-fixup15 .byte fixup17-fixup16, fixup18-fixup17, fixup19-fixup18 .byte fixup20-fixup19, fixup21-fixup20, fixup22-fixup21 + .byte fixup23-fixup22, fixup24-fixup23, fixup25-fixup24 + .byte fixup26-fixup25 fixups = * - fixup ;--------------------------------------------------------------------- -rxtxreg := $FF00 ; High byte patched at runtime -txcmd := $FF04 ; High byte patched at runtime -txlen := $FF06 ; High byte patched at runtime -isq := $FF08 ; High byte patched at runtime -packetpp := $FF0A ; High byte patched at runtime -ppdata := $FF0C ; High byte patched at runtime +; 3 most significant nibbles are fixed up at runtime +rxtxreg := $FFF0 +txcmd := $FFF4 +txlen := $FFF6 +isq := $FFF8 +packetpp := $FFFA +ppdata := $FFFC .data @@ -103,8 +118,9 @@ init: ldy #$00 ; Fixup address at location -: lda reg - eor (ptr),y ; Use XOR to support C64 RR-Net +: lda (ptr),y + and #$0F + eor reg ; Use XOR to support C64 RR-Net sta (ptr),y iny lda reg+1 @@ -131,6 +147,29 @@ fixup01:lda isq+1 ora #$01 ; Set clockport bit fixup02:sta isq+1 + ; Check EISA registration number of Crystal Semiconductor + ; PACKETPP = $0000, PPDATA == $630E ? + lda #$00 + tax + jsr packetpp_ax + lda #$63^$0E +fixup03:eor ppdata +fixup04:eor ppdata+1 + beq :+ + sec + rts + + ; Initiate a chip-wide reset + ; PACKETPP = $0114, PPDATA = $0040 +: lda #$14 + jsr packetpp_a1 + ldy #$40 +fixup05:sty ppdata +: jsr packetpp_a1 +fixup06:ldy ppdata + and #$40 + bne :- + ; Accept valid unicast + broadcast frames ; PACKETPP = $0104, PPDATA = $0D05 lda #$04 @@ -161,6 +200,8 @@ fixup02:sta isq+1 lda #$D3 ldx #$00 jsr ppdata_ax + txa + clc rts ;--------------------------------------------------------------------- @@ -171,27 +212,22 @@ poll: ; PACKETPP = $0124, PPDATA & $0D00 ? lda #$24 jsr packetpp_a1 -fixup03:lda ppdata+1 +fixup07:lda ppdata+1 and #$0D - bne :+ - - ; No frame ready - tax - rts + beq :+ ; Process the incoming frame ; -------------------------- ; Read receiver event and discard it ; RXTXREG -: -fixup04:ldx rxtxreg+1 -fixup05:lda rxtxreg +fixup08:ldx rxtxreg+1 +fixup09:lda rxtxreg ; Read frame length ; cnt = len = RXTXREG -fixup06:ldx rxtxreg+1 -fixup07:lda rxtxreg +fixup10:ldx rxtxreg+1 +fixup11:lda rxtxreg sta len stx len+1 sta cnt @@ -205,23 +241,24 @@ fixup07:lda rxtxreg cmp cnt lda bufsize+1 sbc cnt+1 - bcs :+ + bcs :++ ; Yes, skip frame jsr skipframe ; No frame ready lda #$00 - tax +: tax + sec rts ; Read bytes into buffer : jsr adjustptr : -fixup08:lda rxtxreg +fixup12:lda rxtxreg sta (ptr),y iny -fixup09:lda rxtxreg+1 +fixup13:lda rxtxreg+1 sta (ptr),y iny bne :- @@ -232,6 +269,7 @@ fixup09:lda rxtxreg+1 ; Return frame length lda len ldx len+1 + clc rts ;--------------------------------------------------------------------- @@ -244,12 +282,12 @@ send: ; Transmit command lda #$C9 ldx #$00 -fixup10:sta txcmd -fixup11:stx txcmd+1 +fixup14:sta txcmd +fixup15:stx txcmd+1 lda cnt ldx cnt+1 -fixup12:sta txlen -fixup13:stx txlen+1 +fixup16:sta txlen +fixup17:stx txlen+1 ; Adjust odd frame length jsr adjustcnt @@ -261,7 +299,7 @@ fixup13:stx txlen+1 ; PACKETPP = $0138, PPDATA & $0100 ? : lda #$38 jsr packetpp_a1 -fixup14:lda ppdata+1 +fixup18:lda ppdata+1 and #$01 bne :+ @@ -271,6 +309,7 @@ fixup14:lda ppdata+1 ; And try again dey bne :- + sec rts ; Send the frame @@ -279,15 +318,16 @@ fixup14:lda ppdata+1 ; Write bytes from buffer : jsr adjustptr : lda (ptr),y -fixup15:sta rxtxreg +fixup19:sta rxtxreg iny lda (ptr),y -fixup16:sta rxtxreg+1 +fixup20:sta rxtxreg+1 iny bne :- inc ptr+1 dex bpl :- + clc rts ;--------------------------------------------------------------------- @@ -299,15 +339,16 @@ exit: packetpp_a1: ldx #$01 -fixup17:sta packetpp -fixup18:stx packetpp+1 +packetpp_ax: +fixup21:sta packetpp +fixup22:stx packetpp+1 rts ;--------------------------------------------------------------------- ppdata_ax: -fixup19:sta ppdata -fixup20:stx ppdata+1 +fixup23:sta ppdata +fixup24:stx ppdata+1 rts ;--------------------------------------------------------------------- @@ -316,9 +357,9 @@ skipframe: ; PACKETPP = $0102, PPDATA = PPDATA | $0040 lda #$02 jsr packetpp_a1 -fixup21:lda ppdata +fixup25:lda ppdata ora #$40 -fixup22:sta ppdata +fixup26:sta ppdata rts ;--------------------------------------------------------------------- diff --git a/cpu/6502/net/ethernet-drv.c b/cpu/6502/net/ethernet-drv.c index e12122001..d5e2b80fa 100644 --- a/cpu/6502/net/ethernet-drv.c +++ b/cpu/6502/net/ethernet-drv.c @@ -59,12 +59,12 @@ pollhandler(void) uip_len = ethernet_poll(); if(uip_len > 0) { -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) { uip_neighbor_add(&IPBUF->srcipaddr, &BUF->src); tcpip_input(); } else -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) { uip_len -= sizeof(struct uip_eth_hdr); tcpip_input(); diff --git a/cpu/6502/net/ethernet.c b/cpu/6502/net/ethernet.c index c5eedc888..2817b5d3c 100644 --- a/cpu/6502/net/ethernet.c +++ b/cpu/6502/net/ethernet.c @@ -47,14 +47,18 @@ struct { struct uip_eth_addr ethernet_address; uint8_t *buffer; uint16_t buffer_size; - void __fastcall__ (* init)(uint16_t reg); + char jmp_init; + char __fastcall__ (* init)(uint16_t reg); + char jmp_poll; uint16_t (* poll)(void); + char jmp_send; void __fastcall__ (* send)(uint16_t len); + char jmp_exit; void (* exit)(void); } *module; /*---------------------------------------------------------------------------*/ -void CC_FASTCALL +void ethernet_init(struct ethernet_config *config) { static const char signature[4] = {0x65, 0x74, 0x68, 0x01}; @@ -97,7 +101,10 @@ ethernet_init(struct ethernet_config *config) module->buffer = uip_buf; module->buffer_size = UIP_BUFSIZE; - module->init(config->addr); + if(module->init(config->addr)) { + log_message(config->name, ": No hardware"); + error_exit(); + } uip_setethaddr(module->ethernet_address); } diff --git a/cpu/6502/net/ethernet.h b/cpu/6502/net/ethernet.h index d99f06451..ce06f6e7a 100644 --- a/cpu/6502/net/ethernet.h +++ b/cpu/6502/net/ethernet.h @@ -35,7 +35,7 @@ #ifndef ETHERNET_H_ #define ETHERNET_H_ -void CC_FASTCALL ethernet_init(struct ethernet_config *config); +void ethernet_init(struct ethernet_config *config); uint16_t ethernet_poll(void); void ethernet_send(void); void ethernet_exit(void); diff --git a/cpu/6502/net/lan91c96.S b/cpu/6502/net/lan91c96.S index d034b9788..ea0c80098 100644 --- a/cpu/6502/net/lan91c96.S +++ b/cpu/6502/net/lan91c96.S @@ -33,7 +33,8 @@ ; ;--------------------------------------------------------------------- - .segment "JUMPTABLE" + .macpack module + module_header _lan91c96 ; Driver signature .byte $65, $74, $68 ; "eth" @@ -48,20 +49,30 @@ bufaddr:.res 2 ; Address bufsize:.res 2 ; Size ; Jump table. - .addr init - .addr poll - .addr send - .addr exit + jmp init + jmp poll + jmp send + jmp exit ;--------------------------------------------------------------------- - .zeropage + .if DYN_DRV -sp: .res 2 ; Stack pointer (Do not trash !) + .zeropage +sp: .res 2 ; Stack pointer (Do not trash !) reg: .res 2 ; Address of register base ptr: .res 2 ; Indirect addressing pointer len: .res 2 ; Frame length + .else + + .include "zeropage.inc" +reg := ptr1 ; Address of register base +ptr := ptr2 ; Indirect addressing pointer +len := ptr3 ; Frame length + + .endif + ;--------------------------------------------------------------------- .rodata @@ -78,46 +89,47 @@ fixup: .byte fixup02-fixup01, fixup03-fixup02, fixup04-fixup03 .byte fixup29-fixup28, fixup30-fixup29, fixup31-fixup30 .byte fixup32-fixup31, fixup33-fixup32, fixup34-fixup33 .byte fixup35-fixup34, fixup36-fixup35, fixup37-fixup36 - .byte fixup38-fixup37 + .byte fixup38-fixup37, fixup39-fixup38 fixups = * - fixup ;--------------------------------------------------------------------- -ethbsr := $FF0E ; Bank select register R/W (2B) +; 3 most significant nibbles are fixed up at runtime +ethbsr := $FFFE ; Bank select register R/W (2B) ; Register bank 0 -ethtcr := $FF00 ; Transmition control register R/W (2B) -ethephsr := $FF02 ; EPH status register R/O (2B) -ethrcr := $FF04 ; Receive control register R/W (2B) -ethecr := $FF06 ; Counter register R/O (2B) -ethmir := $FF08 ; Memory information register R/O (2B) -ethmcr := $FF0A ; Memory Config. reg. +0 R/W +1 R/O (2B) +ethtcr := $FFF0 ; Transmition control register R/W (2B) +ethephsr := $FFF2 ; EPH status register R/O (2B) +ethrcr := $FFF4 ; Receive control register R/W (2B) +ethecr := $FFF6 ; Counter register R/O (2B) +ethmir := $FFF8 ; Memory information register R/O (2B) +ethmcr := $FFFA ; Memory Config. reg. +0 R/W +1 R/O (2B) ; Register bank 1 -ethcr := $FF00 ; Configuration register R/W (2B) -ethbar := $FF02 ; Base address register R/W (2B) -ethiar := $FF04 ; Individual address register R/W (6B) -ethgpr := $FF0A ; General address register R/W (2B) -ethctr := $FF0C ; Control register R/W (2B) +ethcr := $FFF0 ; Configuration register R/W (2B) +ethbar := $FFF2 ; Base address register R/W (2B) +ethiar := $FFF4 ; Individual address register R/W (6B) +ethgpr := $FFFA ; General address register R/W (2B) +ethctr := $FFFC ; Control register R/W (2B) ; Register bank 2 -ethmmucr := $FF00 ; MMU command register W/O (1B) -ethautotx := $FF01 ; AUTO TX start register R/W (1B) -ethpnr := $FF02 ; Packet number register R/W (1B) -etharr := $FF03 ; Allocation result register R/O (1B) -ethfifo := $FF04 ; FIFO ports register R/O (2B) -ethptr := $FF06 ; Pointer register R/W (2B) -ethdata := $FF08 ; Data register R/W (4B) -ethist := $FF0C ; Interrupt status register R/O (1B) -ethack := $FF0C ; Interrupt acknowledge register W/O (1B) -ethmsk := $FF0D ; Interrupt mask register R/W (1B) +ethmmucr := $FFF0 ; MMU command register W/O (1B) +ethautotx := $FFF1 ; AUTO TX start register R/W (1B) +ethpnr := $FFF2 ; Packet number register R/W (1B) +etharr := $FFF3 ; Allocation result register R/O (1B) +ethfifo := $FFF4 ; FIFO ports register R/O (2B) +ethptr := $FFF6 ; Pointer register R/W (2B) +ethdata := $FFF8 ; Data register R/W (4B) +ethist := $FFFC ; Interrupt status register R/O (1B) +ethack := $FFFC ; Interrupt acknowledge register W/O (1B) +ethmsk := $FFFD ; Interrupt mask register R/W (1B) ; Register bank 3 -ethmt := $FF00 ; Multicast table R/W (8B) -ethmgmt := $FF08 ; Management interface R/W (2B) -ethrev := $FF0A ; Revision register R/W (2B) -ethercv := $FF0C ; Early RCV register R/W (2B) +ethmt := $FFF0 ; Multicast table R/W (8B) +ethmgmt := $FFF8 ; Management interface R/W (2B) +ethrev := $FFFA ; Revision register R/W (2B) +ethercv := $FFFC ; Early RCV register R/W (2B) .data @@ -137,8 +149,9 @@ init: ldy #$00 ; Fixup address at location -: lda reg - ora (ptr),y +: lda (ptr),y + and #$0F + ora reg sta (ptr),y iny lda reg+1 @@ -157,16 +170,24 @@ init: inc ptr+1 bcs :- ; Always + ; Check bank select register upper byte to always read as $33 +: ldy #$00 +fixup01:sty ethbsr+1 +fixup02:lda ethbsr+1 + cmp #$33 + beq :+ + sec + rts + ; Reset ETH card -: lda #$00 ; Bank 0 -fixup01:sta ethbsr +: ; Bank 0 +fixup03:sty ethbsr lda #%10000000 ; Software reset -fixup02:sta ethrcr+1 +fixup04:sta ethrcr+1 - ldy #$00 -fixup03:sty ethrcr -fixup04:sty ethrcr+1 +fixup05:sty ethrcr +fixup06:sty ethrcr+1 ; Delay : cmp ($FF,x) ; 6 cycles @@ -178,57 +199,55 @@ fixup04:sty ethrcr+1 ; Enable transmit and receive lda #%10000001 ; Enable transmit TXENA, PAD_EN ldx #%00000011 ; Enable receive, strip CRC ??? -fixup05:sta ethtcr -fixup06:stx ethrcr+1 +fixup07:sta ethtcr +fixup08:stx ethrcr+1 lda #$01 ; Bank 1 -fixup07:sta ethbsr +fixup09:sta ethbsr -fixup08:lda ethcr+1 +fixup10:lda ethcr+1 ora #%00010000 ; No wait (IOCHRDY) -fixup09:sta ethcr+1 +fixup11:sta ethcr+1 lda #%00001001 ; Auto release -fixup10:sta ethctr+1 +fixup12:sta ethctr+1 ; Set MAC address ldy #$00 : lda mac,y -fixup11:sta ethiar,y +fixup13:sta ethiar,y iny cpy #$06 bcc :- ; Set interrupt mask lda #$02 ; Bank 2 -fixup12:sta ethbsr +fixup14:sta ethbsr lda #%00000000 ; No interrupts -fixup13:sta ethmsk +fixup15:sta ethmsk + tax + clc rts ;--------------------------------------------------------------------- poll: -fixup14:lda ethist +fixup16:lda ethist and #%00000001 ; RCV INT - bne :+ - - ; No packet available - tax - rts + beq :+ ; Process the incoming packet ; --------------------------- -: lda #$00 + lda #$00 ldx #%11100000 ; RCV, AUTO INCR., READ -fixup15:sta ethptr -fixup16:stx ethptr+1 +fixup17:sta ethptr +fixup18:stx ethptr+1 ; Last word contains 'last data byte' and $60 or 'fill byte' and $40 -fixup17:lda ethdata ; Status word -fixup18:lda ethdata ; Need high byte only +fixup19:lda ethdata ; Status word +fixup20:lda ethdata ; Need high byte only ; Move ODDFRM bit into carry: ; - Even packet length -> carry clear -> subtract 6 bytes @@ -240,10 +259,10 @@ fixup18:lda ethdata ; Need high byte only lsr ; The packet contains 3 extra words -fixup19:lda ethdata ; Total number of bytes +fixup21:lda ethdata ; Total number of bytes sbc #$05 ; Actually 5 or 6 depending on carry sta len -fixup20:lda ethdata +fixup22:lda ethdata sbc #$00 sta len+1 @@ -252,22 +271,21 @@ fixup20:lda ethdata cmp len lda bufsize+1 sbc len+1 - bcs :+ + bcs :++ ; Yes, skip packet - ; Remove and release RX packet from the FIFO - lda #%10000000 -fixup21:sta ethmmucr + jsr releasepacket ; No packet available lda #$00 - tax +: tax + sec rts ; Read bytes into buffer : jsr adjustptr : -fixup22:lda ethdata +fixup23:lda ethdata sta (ptr),y iny bne :- @@ -276,12 +294,12 @@ fixup22:lda ethdata bpl :- ; Remove and release RX packet from the FIFO - lda #%10000000 -fixup23:sta ethmmucr + jsr releasepacket ; Return packet length lda len ldx len+1 + clc rts ;--------------------------------------------------------------------- @@ -305,12 +323,13 @@ fixup25:lda ethist and #%00001000 ; ALLOC INT bne :+ - ; Shouldn't we do something here to actively free memory, - ; maybe removing and releasing an RX packet from the FIFO ??? + ; No space avaliable, skip a received frame + jsr releasepacket ; And try again dey bne :- + sec rts ; Acknowledge interrupt, is it necessary ??? @@ -377,6 +396,7 @@ fixup37:sta ethdata ; Control byte ; Add packet to FIFO lda #%11000000 ; ENQUEUE PACKET - transmit packet fixup38:sta ethmmucr + clc rts ;--------------------------------------------------------------------- @@ -386,6 +406,14 @@ exit: ;--------------------------------------------------------------------- +releasepacket: + ; Remove and release RX packet from the FIFO + lda #%10000000 +fixup39:sta ethmmucr + rts + +;--------------------------------------------------------------------- + adjustptr: lda len ldx len+1 diff --git a/cpu/6502/net/w5100.S b/cpu/6502/net/w5100.S index 3952c1121..3d8160170 100644 --- a/cpu/6502/net/w5100.S +++ b/cpu/6502/net/w5100.S @@ -32,7 +32,8 @@ ; ;--------------------------------------------------------------------- - .segment "JUMPTABLE" + .macpack module + module_header _w5100 ; Driver signature .byte $65, $74, $68 ; "eth" @@ -47,15 +48,16 @@ bufaddr:.res 2 ; Address bufsize:.res 2 ; Size ; Jump table. - .addr init - .addr poll - .addr send - .addr exit + jmp init + jmp poll + jmp send + jmp exit ;--------------------------------------------------------------------- - .zeropage + .if DYN_DRV + .zeropage sp: .res 2 ; Stack pointer (Do not trash !) reg: .res 2 ; Pointer Register content ptr: .res 2 ; Indirect addressing pointer @@ -67,6 +69,21 @@ bas: .res 1 ; Socket 0 Base Address (hibyte) lim: .res 1 ; Socket 0 memory limit (hibyte) tmp: .res 1 ; Temporary value + .else + + .include "zeropage.inc" +reg := ptr1 ; Pointer Register content +ptr := ptr2 ; Indirect addressing pointer +len := ptr3 ; Data length +cnt := ptr4 ; Data length counter +adv := sreg ; Data pointer advancement +dir := tmp1 ; Transfer direction +bas := tmp2 ; Socket 0 Base Address (hibyte) +lim := tmp3 ; Socket 0 memory limit (hibyte) +tmp := tmp4 ; Temporary value + + .endif + ;--------------------------------------------------------------------- .rodata @@ -79,15 +96,18 @@ fixup: .byte fixup02-fixup01, fixup03-fixup02, fixup04-fixup03 .byte fixup17-fixup16, fixup18-fixup17, fixup19-fixup18 .byte fixup20-fixup19, fixup21-fixup20, fixup22-fixup21 .byte fixup23-fixup22, fixup24-fixup23, fixup25-fixup24 - .byte fixup26-fixup25 + .byte fixup26-fixup25, fixup27-fixup26, fixup28-fixup27 + .byte fixup29-fixup28, fixup30-fixup29, fixup31-fixup30 + .byte fixup32-fixup31 fixups = * - fixup ;--------------------------------------------------------------------- -mode := $FF00 ; High byte patched at runtime -addr := $FF01 ; High byte patched at runtime -data := $FF03 ; High byte patched at runtime +; 14 most significant bits are fixed up at runtime +mode := $FFFC|0 +addr := $FFFC|1 +data := $FFFC|3 .data @@ -107,8 +127,9 @@ init: ldy #$00 ; Fixup address at location -: lda reg - ora (ptr),y +: lda (ptr),y + and #$03 + ora reg sta (ptr),y iny lda reg+1 @@ -127,44 +148,84 @@ init: inc ptr+1 bcs :- ; Always - ; S/W Reset -: lda #$80 -fixup01:sta mode + ; Indirect Bus I/F mode, Address Auto-Increment : -fixup02:lda mode +fixup01:lda mode + ora #$03 +fixup02:sta mode + + ; Retry Time-value Register: = 2000 ? + ldx #$00 ; Hibyte + ldy #$17 ; Lobyte + jsr set_addr + lda #$07^$D0 +fixup03:eor data +fixup04:eor data + beq :+ + sec + rts + + ; Check for W5100 shared access + ; RX Memory Size Register: Assign 4+2+1+1KB to socket 0 to 3 ? +: ; ldx #$00 ; Hibyte + ldy #$1A ; Lobyte + jsr set_addr +fixup05:lda data + cmp #$06 + beq :+++ + + ; S/W Reset + lda #$80 +fixup06:sta mode +: +fixup07:lda mode bmi :- ; Indirect Bus I/F mode, Address Auto-Increment, Ping Block lda #$13 -fixup03:sta mode +fixup08:sta mode ; Source Hardware Address Register: MAC Address ldx #$00 ; Hibyte ldy #$09 ; Lobyte jsr set_addr : lda mac,x -fixup04:sta data +fixup09:sta data inx cpx #$06 bcc :- - ; RX Memory Size Register: Assign 8KB to socket 0 - ; TX Memory Size Register: Assign 8KB to socket 0 + ; RX Memory Size Register: Assign 4KB each to socket 0 and 1 + ; TX Memory Size Register: Assign 4KB each to socket 0 and 1 ldx #$00 ; Hibyte ldy #$1A ; Lobyte jsr set_addr - lda #$03 -fixup05:sta data -fixup06:sta data + lda #$0A +fixup10:sta data +fixup11:sta data + + ; MAC Address: Source Hardware Address Register +: ; ldx #$00 ; Hibyte + ldy #$09 ; Lobyte + jsr set_addr +: +fixup12:lda data + sta mac,x + inx + cpx #$06 + bcc :- ; Socket 0 Mode Register: MACRAW, MAC Filter ; Socket 0 Command Register: OPEN ldy #$00 jsr set_addrsocket0 lda #$44 -fixup07:sta data +fixup13:sta data lda #$01 -fixup08:sta data +fixup14:sta data + tya + tax + clc rts ;--------------------------------------------------------------------- @@ -173,19 +234,20 @@ poll: ; Check for completion of previous command ; Socket 0 Command Register: = 0 ? jsr set_addrcmdreg0 -fixup09:lda data +fixup15:lda data beq :++ ; No data available lda #$00 : tax + sec rts ; Socket 0 RX Received Size Register: != 0 ? : ldy #$26 ; Socket RX Received Size Register jsr set_addrsocket0 -fixup10:lda data ; Hibyte -fixup11:ora data ; Lobyte +fixup16:lda data ; Hibyte +fixup17:ora data ; Lobyte beq :-- ; Process the incoming data @@ -202,8 +264,8 @@ fixup11:ora data ; Lobyte ; Calculate and set physical address jsr set_addrphysical - ; Move physical address shadow to $E000-$FFFF - ora #>$8000 + ; Move physical address shadow to $F000-$FFFF + ora #>$F000 tax ; Read MAC raw 2byte packet size header @@ -251,17 +313,18 @@ common: jsr set_addrsocket0 tax lda reg+1 adc adv+1 -fixup12:sta data ; Hibyte -fixup13:stx data ; Lobyte +fixup18:sta data ; Hibyte +fixup19:stx data ; Lobyte ; Set command register tya ; Restore command jsr set_addrcmdreg0 -fixup14:sta data +fixup20:sta data ; Return data length (will be ignored for send) lda len ldx len+1 + clc rts ;--------------------------------------------------------------------- @@ -283,14 +346,14 @@ send: ; Wait for completion of previous command ; Socket 0 Command Register: = 0 ? : jsr set_addrcmdreg0 -fixup15:lda data +fixup21:lda data bne :- ; Socket 0 TX Free Size Register: < length ? : ldy #$20 ; Socket TX Free Size Register jsr set_addrsocket0 -fixup16:lda data ; Hibyte -fixup17:ldx data ; Lobyte +fixup22:lda data ; Hibyte +fixup23:ldx data ; Lobyte cpx len sbc len+1 bcc :- @@ -320,16 +383,16 @@ exit: ;--------------------------------------------------------------------- set_addrphysical: -fixup18:lda data ; Hibyte -fixup19:ldy data ; Lobyte +fixup24:lda data ; Hibyte +fixup25:ldy data ; Lobyte sty reg sta reg+1 - and #>$1FFF ; Socket Mask Address (hibyte) + and #>$0FFF ; Socket Mask Address (hibyte) ora bas ; Socket Base Address (hibyte) tax set_addr: -fixup20:stx addr ; Hibyte -fixup21:sty addr+1 ; Lobyte +fixup26:stx addr ; Hibyte +fixup27:sty addr+1 ; Lobyte rts set_addrcmdreg0: @@ -344,7 +407,7 @@ set_addrbase: beq set_addr ; Always get_datacheckaddr: -fixup22:lda data +fixup28:lda data iny ; Physical address shadow (lobyte) bne :+ inx ; Physical address shadow (hibyte) @@ -357,7 +420,7 @@ set_parameters: ; Setup variables in zero page sta bas ; Socket Base Address clc - adc #>$2000 ; Socket memory size + adc #>$1000 ; Socket memory size sta lim ; Socket memory limit stx dir ; Transfer direction @@ -385,10 +448,10 @@ mov_data: ; R/W without address wraparound possible because ; highest R/W address > actual R/W address ? ; sec -fixup23:sbc addr+1 ; Lobyte +fixup29:sbc addr+1 ; Lobyte tay txa -fixup24:sbc addr ; Hibyte +fixup30:sbc addr ; Hibyte tax tya bcs :+ @@ -449,7 +512,7 @@ rw_data:eor #$FF ; Two's complement part 1 ; Read data : -fixup25:lda data +fixup31:lda data sta (ptr),y iny bne :- @@ -460,7 +523,7 @@ fixup25:lda data ; Write data : lda (ptr),y -fixup26:sta data +fixup32:sta data iny bne :- inc ptr+1 diff --git a/cpu/6502/sys/clock.c b/cpu/6502/sys/clock.c index c23e14f65..33d2da865 100644 --- a/cpu/6502/sys/clock.c +++ b/cpu/6502/sys/clock.c @@ -45,11 +45,8 @@ clock_time(void) * of overhead for cc65 targets. * On the other hand we want to avoid wrapping around frequently so the idea * is to reduce the clock resolution to the bare minimum. This is defined by - * the TCP/IP stack using a 1/2 second periodic timer. So CLOCK_CONF_SECOND - * needs to be defined at least as 2. - * The value 2 works out especially nicely as it allows us to implement the - * clock frequency devider below purely in (32 bit) integer arithmetic based - * on the educated guess of CLK_TCK being an even value. */ + * the DNS resolver using a 1/4 second timer. So CLOCK_CONF_SECOND needs to + * be defined at least as 4. */ return clock() / (CLK_TCK / CLOCK_CONF_SECOND); } /*---------------------------------------------------------------------------*/ diff --git a/cpu/arm/aducrf101/Common/ADuCRF101.h b/cpu/arm/aducrf101/Common/ADuCRF101.h new file mode 100644 index 000000000..1e28f5cfb --- /dev/null +++ b/cpu/arm/aducrf101/Common/ADuCRF101.h @@ -0,0 +1,9875 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ + +/****************************************************************************************************//** + * @file ADuCRF101.h + * + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File for + * default ADUCRF101 Device Series + * + * @version V1.0 + * @date Thursday January 10 2013 15:30 + * + *******************************************************************************************************/ + + + +/** @addtogroup ADUCRF101 + * @{ + */ + +#ifndef __ADUCRF101_H__ +#define __ADUCRF101_H__ + +#ifndef __NO_MMR_STRUCTS__ +// The new style CMSIS structure definitions for MMRs clash with +// the old style defs. If the old style are required for compilation +// then set __NO_MMR_STRUCTS__ to 0x1 +#define __NO_MMR_STRUCTS__ 0x0 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/* ------------------------- Interrupt Number Definition ------------------------ */ + +typedef enum { +/* ------------------- Cortex-M3 Processor Exceptions Numbers ------------------- */ + Reset_IRQn = -15, /*!< 1 Reset Vector, invoked on Power up and warm reset */ + NonMaskableInt_IRQn = -14, /*!< 2 Non maskable Interrupt, cannot be stopped or preempted */ + HardFault_IRQn = -13, /*!< 3 Hard Fault, all classes of Fault */ + MemoryManagement_IRQn = -12, /*!< 4 Memory Management, MPU mismatch, including Access Violation and No Match */ + BusFault_IRQn = -11, /*!< 5 Bus Fault, Pre-Fetch-, Memory Access Fault, other address/memory related Fault */ + UsageFault_IRQn = -10, /*!< 6 Usage Fault, i.e. Undef Instruction, Illegal State Transition */ + SVCall_IRQn = -5, /*!< 11 System Service Call via SVC instruction */ + DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor */ + PendSV_IRQn = -2, /*!< 14 Pendable request for system service */ + SysTick_IRQn = -1, /*!< 15 System Tick Timer */ +// -------------------------- ADUCRF101 Specific Interrupt Numbers ------------------------------ + WUT_IRQn = 0, /*!< 0 WUT */ + EINT0_IRQn = 1, /*!< 1 EINT0 */ + EINT1_IRQn = 2, /*!< 2 EINT1 */ + EINT2_IRQn = 3, /*!< 3 EINT2 */ + EINT3_IRQn = 4, /*!< 4 EINT3 */ + EINT4_IRQn = 5, /*!< 5 EINT4 */ + EINT5_IRQn = 6, /*!< 6 EINT5 */ + EINT6_IRQn = 7, /*!< 7 EINT6 */ + EINT7_IRQn = 8, /*!< 8 EINT7 */ + EINT8_IRQn = 9, /*!< 9 EINT8 */ + UHFTRX_IRQn = 9, /*!< 9 UHFTRX */ + WDT_IRQn = 10, /*!< 10 WDT */ + TIMER0_IRQn = 12, /*!< 12 TIMER0 */ + TIMER1_IRQn = 13, /*!< 13 TIMER1 */ + ADC0_IRQn = 14, /*!< 14 ADC0 */ + FLASH_IRQn = 15, /*!< 15 FLASH */ + UART_IRQn = 16, /*!< 16 UART */ + SPI0_IRQn = 17, /*!< 17 SPI0 */ + SPI1_IRQn = 18, /*!< 18 SPI1 */ + I2CS_IRQn = 19, /*!< 19 I2CS */ + I2CM_IRQn = 20, /*!< 20 I2CM */ + DMA_ERR_IRQn = 23, /*!< 23 DMA_ERR */ + DMA_SPI1_TX_IRQn = 24, /*!< 24 DMA_SPI1_TX */ + DMA_SPI1_RX_IRQn = 25, /*!< 25 DMA_SPI1_RX */ + DMA_UART_TX_IRQn = 26, /*!< 26 DMA_UART_TX */ + DMA_UART_RX_IRQn = 27, /*!< 27 DMA_UART_RX */ + DMA_I2CS_TX_IRQn = 28, /*!< 28 DMA_I2CS_TX */ + DMA_I2CS_RX_IRQn = 29, /*!< 29 DMA_I2CS_RX */ + DMA_I2CM_TX_IRQn = 30, /*!< 30 DMA_I2CM_TX */ + DMA_I2CM_RX_IRQn = 31, /*!< 31 DMA_I2CM_RX */ + DMA_ADC0_IRQn = 35, /*!< 35 DMA_ADC0 */ + DMA_SPI0_TX_IRQn = 36, /*!< 36 DMA_SPI0_TX */ + DMA_SPI0_RX_IRQn = 37, /*!< 37 DMA_SPI0_RX */ + PWM_TRIP_IRQn = 38, /*!< 38 PWM_TRIP */ + PWM_PAIR0_IRQn = 39, /*!< 39 PWM_PAIR0 */ + PWM_PAIR1_IRQn = 40, /*!< 40 PWM_PAIR1 */ + PWM_PAIR2_IRQn = 41, /*!< 41 PWM_PAIR2 */ + PWM_PAIR3_IRQn = 42 /*!< 42 PWM_PAIR3 */ +} IRQn_Type; + + +/** @addtogroup Configuration_of_CMSIS + * @{ + */ + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* ----------------Configuration of the cm3 Processor and Core Peripherals---------------- */ + +#define __CM3_REV 0x0200 /*!< Cortex-M3 Core Revision */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +/** @} */ /* End of group Configuration_of_CMSIS */ + +#include /*!< Cortex-M3 processor and core peripherals */ +#include "system_ADuCRF101.h" /*!< ADUCRF101 System */ + + +/* ================================================================================ */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================ */ + + +/** @addtogroup Device_Peripheral_Registers + * @{ + */ + + +/* ------------------- Start of section using anonymous unions ------------------ */ +#if defined(__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined(__ICCARM__) + #pragma language=extended +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined(__TMS470__) +/* anonymous unions are enabled by default */ +#elif defined(__TASKING__) + #pragma warning 586 +#else + #warning Not supported compiler type +#endif + + + + +/* TCON[EVENTEN] - Enable event bit. */ +#define TCON_EVENTEN_MSK (0x1 << 12 ) +#define TCON_EVENTEN (0x1 << 12 ) +#define TCON_EVENTEN_DIS (0x0 << 12 ) /* DIS. Cleared by user. */ +#define TCON_EVENTEN_EN (0x1 << 12 ) /* EN. Enable time capture of an event. */ + +/* TCON[EVENT] - Event select bits. Settings not described are reserved and should not be used. */ +#define TCON_EVENT_MSK (0xF << 8 ) + +/* TCON[RLD] - Reload control bit for periodic mode. */ +#define TCON_RLD_MSK (0x1 << 7 ) +#define TCON_RLD (0x1 << 7 ) +#define TCON_RLD_DIS (0x0 << 7 ) /* DIS. Reload on a time out. */ +#define TCON_RLD_EN (0x1 << 7 ) /* EN. Reload the counter on a write to T0CLRI. */ + +/* TCON[CLK] - Clock select. */ +#define TCON_CLK_MSK (0x3 << 5 ) +#define TCON_CLK_UCLK (0x0 << 5 ) /* UCLK. Undivided system clock. */ +#define TCON_CLK_PCLK (0x1 << 5 ) /* PCLK. Peripheral clock. */ +#define TCON_CLK_LFOSC (0x2 << 5 ) /* LFOSC. 32 kHz internal oscillator. */ +#define TCON_CLK_LFXTAL (0x3 << 5 ) /* LFXTAL. 32 kHz external crystal. */ + +/* TCON[ENABLE] - Timer enable bit. */ +#define TCON_ENABLE_MSK (0x1 << 4 ) +#define TCON_ENABLE (0x1 << 4 ) +#define TCON_ENABLE_DIS (0x0 << 4 ) /* DIS. Disable the timer. Clearing this bit resets the timer, including the T0VAL register. */ +#define TCON_ENABLE_EN (0x1 << 4 ) /* EN. Enable the timer. The timer starts counting from its initial value, 0 if count-up mode or 0xFFFF if count-down mode. */ + +/* TCON[MOD] - Timer mode. */ +#define TCON_MOD_MSK (0x1 << 3 ) +#define TCON_MOD (0x1 << 3 ) +#define TCON_MOD_FREERUN (0x0 << 3 ) /* FREERUN. Operate in free running mode. */ +#define TCON_MOD_PERIODIC (0x1 << 3 ) /* PERIODIC. Operate in periodic mode. */ + +/* TCON[UP] - Count down/up. */ +#define TCON_UP_MSK (0x1 << 2 ) +#define TCON_UP (0x1 << 2 ) +#define TCON_UP_DIS (0x0 << 2 ) /* DIS. Timer to count down. */ +#define TCON_UP_EN (0x1 << 2 ) /* EN. Timer to count up. */ + +/* TCON[PRE] - Prescaler. */ +#define TCON_PRE_MSK (0x3 << 0 ) +#define TCON_PRE_DIV1 (0x0 << 0 ) /* DIV1. Source clock/1.If the selected clock source is UCLK or PCLK this setting results in a prescaler of 4. */ +#define TCON_PRE_DIV16 (0x1 << 0 ) /* DIV16. Source clock/16. */ +#define TCON_PRE_DIV256 (0x2 << 0 ) /* DIV256. Source clock/256. */ +#define TCON_PRE_DIV32768 (0x3 << 0 ) /* DIV32768. Source clock/32768. */ + +/* TCLRI[CAP] - Clear captured event interrupt. */ +#define TCLRI_CAP_MSK (0x1 << 1 ) +#define TCLRI_CAP (0x1 << 1 ) +#define TCLRI_CAP_CLR (0x1 << 1 ) /* CLR. Clear a captured event interrupt. This bit always reads 0. */ + +/* TCLRI[TMOUT] - Clear timeout interrupt. */ +#define TCLRI_TMOUT_MSK (0x1 << 0 ) +#define TCLRI_TMOUT (0x1 << 0 ) +#define TCLRI_TMOUT_CLR (0x1 << 0 ) /* CLR. Clear a timeout interrupt. This bit always reads 0. */ + +/* TSTA[CLRI] - T0CLRI write sync in progress.. */ +#define TSTA_CLRI_MSK (0x1 << 7 ) +#define TSTA_CLRI (0x1 << 7 ) +#define TSTA_CLRI_CLR (0x0 << 7 ) /* CLR. Cleared when the interrupt is cleared in the timer clock domain. */ +#define TSTA_CLRI_SET (0x1 << 7 ) /* SET. Set automatically when the T0CLRI value is being updated in the timer clock domain, indicating that the timer’s configuration is not yet valid. */ + +/* TSTA[CON] - T0CON write sync in progress. */ +#define TSTA_CON_MSK (0x1 << 6 ) +#define TSTA_CON (0x1 << 6 ) +#define TSTA_CON_CLR (0x0 << 6 ) /* CLR. Timer ready to receive commands to T0CON. The previous change of T0CON has been synchronized in the timer clock domain. */ +#define TSTA_CON_SET (0x1 << 6 ) /* SET. Timer not ready to receive commands to T0CON. Previous change of the T0CON value has not been synchronized in the timer clock domain. */ + +/* TSTA[CAP] - Capture event pending. */ +#define TSTA_CAP_MSK (0x1 << 1 ) +#define TSTA_CAP (0x1 << 1 ) +#define TSTA_CAP_CLR (0x0 << 1 ) /* CLR. No capture event is pending. */ +#define TSTA_CAP_SET (0x1 << 1 ) /* SET. Capture event is pending. */ + +/* TSTA[TMOUT] - Time out event occurred. */ +#define TSTA_TMOUT_MSK (0x1 << 0 ) +#define TSTA_TMOUT (0x1 << 0 ) +#define TSTA_TMOUT_CLR (0x0 << 0 ) /* CLR. No timeout event has occurred. */ +#define TSTA_TMOUT_SET (0x1 << 0 ) /* SET. Timeout event has occurred. For count-up mode, this is when the counter reaches full scale. For count-down mode, this is when the counter reaches 0. */ + +/* GPCON[CON7] - Configuration bits for Px.7 (not available for port 1). */ +#define GPCON_CON7_MSK (0x3 << 14 ) + +/* GPCON[CON6] - Configuration bits for Px.6 (not available for port 1). */ +#define GPCON_CON6_MSK (0x3 << 12 ) + +/* GPCON[CON5] - Configuration bits for Px.5. */ +#define GPCON_CON5_MSK (0x3 << 10 ) + +/* GPCON[CON4] - Configuration bits for Px.4. */ +#define GPCON_CON4_MSK (0x3 << 8 ) + +/* GPCON[CON3] - Configuration bits for Px.3. */ +#define GPCON_CON3_MSK (0x3 << 6 ) + +/* GPCON[CON2] - Configuration bits for Px.2. */ +#define GPCON_CON2_MSK (0x3 << 4 ) + +/* GPCON[CON1] - Configuration bits for Px.1. */ +#define GPCON_CON1_MSK (0x3 << 2 ) + +/* GPCON[CON0] - Configuration bits for Px.0. */ +#define GPCON_CON0_MSK (0x3 << 0 ) + +/* GPOEN[OEN7] - Port pin direction. */ +#define GPOEN_OEN7_MSK (0x1 << 7 ) +#define GPOEN_OEN7 (0x1 << 7 ) +#define GPOEN_OEN7_IN (0x0 << 7 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GPOEN_OEN7_OUT (0x1 << 7 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GPOEN[OEN6] - Port pin direction. */ +#define GPOEN_OEN6_MSK (0x1 << 6 ) +#define GPOEN_OEN6 (0x1 << 6 ) +#define GPOEN_OEN6_IN (0x0 << 6 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GPOEN_OEN6_OUT (0x1 << 6 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GPOEN[OEN5] - Port pin direction. */ +#define GPOEN_OEN5_MSK (0x1 << 5 ) +#define GPOEN_OEN5 (0x1 << 5 ) +#define GPOEN_OEN5_IN (0x0 << 5 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GPOEN_OEN5_OUT (0x1 << 5 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GPOEN[OEN4] - Port pin direction. */ +#define GPOEN_OEN4_MSK (0x1 << 4 ) +#define GPOEN_OEN4 (0x1 << 4 ) +#define GPOEN_OEN4_IN (0x0 << 4 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GPOEN_OEN4_OUT (0x1 << 4 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GPOEN[OEN3] - Port pin direction. */ +#define GPOEN_OEN3_MSK (0x1 << 3 ) +#define GPOEN_OEN3 (0x1 << 3 ) +#define GPOEN_OEN3_IN (0x0 << 3 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GPOEN_OEN3_OUT (0x1 << 3 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GPOEN[OEN2] - Port pin direction. */ +#define GPOEN_OEN2_MSK (0x1 << 2 ) +#define GPOEN_OEN2 (0x1 << 2 ) +#define GPOEN_OEN2_IN (0x0 << 2 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GPOEN_OEN2_OUT (0x1 << 2 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GPOEN[OEN1] - Port pin direction. */ +#define GPOEN_OEN1_MSK (0x1 << 1 ) +#define GPOEN_OEN1 (0x1 << 1 ) +#define GPOEN_OEN1_IN (0x0 << 1 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GPOEN_OEN1_OUT (0x1 << 1 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GPOEN[OEN0] - Port pin direction. */ +#define GPOEN_OEN0_MSK (0x1 << 0 ) +#define GPOEN_OEN0 (0x1 << 0 ) +#define GPOEN_OEN0_IN (0x0 << 0 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GPOEN_OEN0_OUT (0x1 << 0 ) /* OUT. Enables the output on corresponding port pin.. */ + +/* GPIN[IN7] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GPIN_IN7_MSK (0x1 << 7 ) +#define GPIN_IN7 (0x1 << 7 ) +#define GPIN_IN7_LOW (0x0 << 7 ) /* LOW */ +#define GPIN_IN7_HIGH (0x1 << 7 ) /* HIGH */ + +/* GPIN[IN6] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GPIN_IN6_MSK (0x1 << 6 ) +#define GPIN_IN6 (0x1 << 6 ) +#define GPIN_IN6_LOW (0x0 << 6 ) /* LOW */ +#define GPIN_IN6_HIGH (0x1 << 6 ) /* HIGH */ + +/* GPIN[IN5] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GPIN_IN5_MSK (0x1 << 5 ) +#define GPIN_IN5 (0x1 << 5 ) +#define GPIN_IN5_LOW (0x0 << 5 ) /* LOW */ +#define GPIN_IN5_HIGH (0x1 << 5 ) /* HIGH */ + +/* GPIN[IN4] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GPIN_IN4_MSK (0x1 << 4 ) +#define GPIN_IN4 (0x1 << 4 ) +#define GPIN_IN4_LOW (0x0 << 4 ) /* LOW */ +#define GPIN_IN4_HIGH (0x1 << 4 ) /* HIGH */ + +/* GPIN[IN3] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GPIN_IN3_MSK (0x1 << 3 ) +#define GPIN_IN3 (0x1 << 3 ) +#define GPIN_IN3_LOW (0x0 << 3 ) /* LOW */ +#define GPIN_IN3_HIGH (0x1 << 3 ) /* HIGH */ + +/* GPIN[IN2] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GPIN_IN2_MSK (0x1 << 2 ) +#define GPIN_IN2 (0x1 << 2 ) +#define GPIN_IN2_LOW (0x0 << 2 ) /* LOW */ +#define GPIN_IN2_HIGH (0x1 << 2 ) /* HIGH */ + +/* GPIN[IN1] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GPIN_IN1_MSK (0x1 << 1 ) +#define GPIN_IN1 (0x1 << 1 ) +#define GPIN_IN1_LOW (0x0 << 1 ) /* LOW */ +#define GPIN_IN1_HIGH (0x1 << 1 ) /* HIGH */ + +/* GPIN[IN0] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GPIN_IN0_MSK (0x1 << 0 ) +#define GPIN_IN0 (0x1 << 0 ) +#define GPIN_IN0_LOW (0x0 << 0 ) /* LOW */ +#define GPIN_IN0_HIGH (0x1 << 0 ) /* HIGH */ + +/* GPOUT[OUT7] - Data out register. */ +#define GPOUT_OUT7_MSK (0x1 << 7 ) +#define GPOUT_OUT7 (0x1 << 7 ) +#define GPOUT_OUT7_LOW (0x0 << 7 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GPOUT_OUT7_HIGH (0x1 << 7 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GPOUT[OUT6] - Data out register. */ +#define GPOUT_OUT6_MSK (0x1 << 6 ) +#define GPOUT_OUT6 (0x1 << 6 ) +#define GPOUT_OUT6_LOW (0x0 << 6 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GPOUT_OUT6_HIGH (0x1 << 6 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GPOUT[OUT5] - Data out register. */ +#define GPOUT_OUT5_MSK (0x1 << 5 ) +#define GPOUT_OUT5 (0x1 << 5 ) +#define GPOUT_OUT5_LOW (0x0 << 5 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GPOUT_OUT5_HIGH (0x1 << 5 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GPOUT[OUT4] - Data out register. */ +#define GPOUT_OUT4_MSK (0x1 << 4 ) +#define GPOUT_OUT4 (0x1 << 4 ) +#define GPOUT_OUT4_LOW (0x0 << 4 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GPOUT_OUT4_HIGH (0x1 << 4 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GPOUT[OUT3] - Data out register. */ +#define GPOUT_OUT3_MSK (0x1 << 3 ) +#define GPOUT_OUT3 (0x1 << 3 ) +#define GPOUT_OUT3_LOW (0x0 << 3 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GPOUT_OUT3_HIGH (0x1 << 3 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GPOUT[OUT2] - Data out register. */ +#define GPOUT_OUT2_MSK (0x1 << 2 ) +#define GPOUT_OUT2 (0x1 << 2 ) +#define GPOUT_OUT2_LOW (0x0 << 2 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GPOUT_OUT2_HIGH (0x1 << 2 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GPOUT[OUT1] - Data out register. */ +#define GPOUT_OUT1_MSK (0x1 << 1 ) +#define GPOUT_OUT1 (0x1 << 1 ) +#define GPOUT_OUT1_LOW (0x0 << 1 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GPOUT_OUT1_HIGH (0x1 << 1 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GPOUT[OUT0] - Data out register. */ +#define GPOUT_OUT0_MSK (0x1 << 0 ) +#define GPOUT_OUT0 (0x1 << 0 ) +#define GPOUT_OUT0_LOW (0x0 << 0 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GPOUT_OUT0_HIGH (0x1 << 0 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GPSET[SET7] - Set output high for corresponding port pin. */ +#define GPSET_SET7_MSK (0x1 << 7 ) +#define GPSET_SET7 (0x1 << 7 ) +#define GPSET_SET7_SET (0x1 << 7 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GPSET[SET6] - Set output high for corresponding port pin. */ +#define GPSET_SET6_MSK (0x1 << 6 ) +#define GPSET_SET6 (0x1 << 6 ) +#define GPSET_SET6_SET (0x1 << 6 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GPSET[SET5] - Set output high for corresponding port pin. */ +#define GPSET_SET5_MSK (0x1 << 5 ) +#define GPSET_SET5 (0x1 << 5 ) +#define GPSET_SET5_SET (0x1 << 5 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GPSET[SET4] - Set output high for corresponding port pin. */ +#define GPSET_SET4_MSK (0x1 << 4 ) +#define GPSET_SET4 (0x1 << 4 ) +#define GPSET_SET4_SET (0x1 << 4 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GPSET[SET3] - Set output high for corresponding port pin. */ +#define GPSET_SET3_MSK (0x1 << 3 ) +#define GPSET_SET3 (0x1 << 3 ) +#define GPSET_SET3_SET (0x1 << 3 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GPSET[SET2] - Set output high for corresponding port pin. */ +#define GPSET_SET2_MSK (0x1 << 2 ) +#define GPSET_SET2 (0x1 << 2 ) +#define GPSET_SET2_SET (0x1 << 2 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GPSET[SET1] - Set output high for corresponding port pin. */ +#define GPSET_SET1_MSK (0x1 << 1 ) +#define GPSET_SET1 (0x1 << 1 ) +#define GPSET_SET1_SET (0x1 << 1 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GPSET[SET0] - Set output high for corresponding port pin. */ +#define GPSET_SET0_MSK (0x1 << 0 ) +#define GPSET_SET0 (0x1 << 0 ) +#define GPSET_SET0_SET (0x1 << 0 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GPCLR[CLR7] - Set by user code to drive the corresponding GPIO low. */ +#define GPCLR_CLR7_MSK (0x1 << 7 ) +#define GPCLR_CLR7 (0x1 << 7 ) +#define GPCLR_CLR7_CLR (0x1 << 7 ) /* CLR */ + +/* GPCLR[CLR6] - Set by user code to drive the corresponding GPIO low. */ +#define GPCLR_CLR6_MSK (0x1 << 6 ) +#define GPCLR_CLR6 (0x1 << 6 ) +#define GPCLR_CLR6_CLR (0x1 << 6 ) /* CLR */ + +/* GPCLR[CLR5] - Set by user code to drive the corresponding GPIO low. */ +#define GPCLR_CLR5_MSK (0x1 << 5 ) +#define GPCLR_CLR5 (0x1 << 5 ) +#define GPCLR_CLR5_CLR (0x1 << 5 ) /* CLR */ + +/* GPCLR[CLR4] - Set by user code to drive the corresponding GPIO low. */ +#define GPCLR_CLR4_MSK (0x1 << 4 ) +#define GPCLR_CLR4 (0x1 << 4 ) +#define GPCLR_CLR4_CLR (0x1 << 4 ) /* CLR */ + +/* GPCLR[CLR3] - Set by user code to drive the corresponding GPIO low. */ +#define GPCLR_CLR3_MSK (0x1 << 3 ) +#define GPCLR_CLR3 (0x1 << 3 ) +#define GPCLR_CLR3_CLR (0x1 << 3 ) /* CLR */ + +/* GPCLR[CLR2] - Set by user code to drive the corresponding GPIO low. */ +#define GPCLR_CLR2_MSK (0x1 << 2 ) +#define GPCLR_CLR2 (0x1 << 2 ) +#define GPCLR_CLR2_CLR (0x1 << 2 ) /* CLR */ + +/* GPCLR[CLR1] - Set by user code to drive the corresponding GPIO low. */ +#define GPCLR_CLR1_MSK (0x1 << 1 ) +#define GPCLR_CLR1 (0x1 << 1 ) +#define GPCLR_CLR1_CLR (0x1 << 1 ) /* CLR */ + +/* GPCLR[CLR0] - Set by user code to drive the corresponding GPIO low. */ +#define GPCLR_CLR0_MSK (0x1 << 0 ) +#define GPCLR_CLR0 (0x1 << 0 ) +#define GPCLR_CLR0_CLR (0x1 << 0 ) /* CLR */ + +/* GPTGL[TGL7] - Toggle for corresponding port pin. */ +#define GPTGL_TGL7_MSK (0x1 << 7 ) +#define GPTGL_TGL7 (0x1 << 7 ) +#define GPTGL_TGL7_TGL (0x1 << 7 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GPTGL[TGL6] - Toggle for corresponding port pin. */ +#define GPTGL_TGL6_MSK (0x1 << 6 ) +#define GPTGL_TGL6 (0x1 << 6 ) +#define GPTGL_TGL6_TGL (0x1 << 6 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GPTGL[TGL5] - Toggle for corresponding port pin. */ +#define GPTGL_TGL5_MSK (0x1 << 5 ) +#define GPTGL_TGL5 (0x1 << 5 ) +#define GPTGL_TGL5_TGL (0x1 << 5 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GPTGL[TGL4] - Toggle for corresponding port pin. */ +#define GPTGL_TGL4_MSK (0x1 << 4 ) +#define GPTGL_TGL4 (0x1 << 4 ) +#define GPTGL_TGL4_TGL (0x1 << 4 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GPTGL[TGL3] - Toggle for corresponding port pin. */ +#define GPTGL_TGL3_MSK (0x1 << 3 ) +#define GPTGL_TGL3 (0x1 << 3 ) +#define GPTGL_TGL3_TGL (0x1 << 3 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GPTGL[TGL2] - Toggle for corresponding port pin. */ +#define GPTGL_TGL2_MSK (0x1 << 2 ) +#define GPTGL_TGL2 (0x1 << 2 ) +#define GPTGL_TGL2_TGL (0x1 << 2 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GPTGL[TGL1] - Toggle for corresponding port pin. */ +#define GPTGL_TGL1_MSK (0x1 << 1 ) +#define GPTGL_TGL1 (0x1 << 1 ) +#define GPTGL_TGL1_TGL (0x1 << 1 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GPTGL[TGL0] - Toggle for corresponding port pin. */ +#define GPTGL_TGL0_MSK (0x1 << 0 ) +#define GPTGL_TGL0 (0x1 << 0 ) +#define GPTGL_TGL0_TGL (0x1 << 0 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* CLK[T1] - T1 clocks enable bit. */ +#define CLK_T1_MSK (0x1 << 11 ) +#define CLK_T1 (0x1 << 11 ) +#define CLK_T1_DIS (0x0 << 11 ) /* DIS. Disable T1 clocks. */ +#define CLK_T1_EN (0x1 << 11 ) /* EN. Enable T1 clocks. */ + +/* CLK[T0] - T0 clocks enable bit. */ +#define CLK_T0_MSK (0x1 << 10 ) +#define CLK_T0 (0x1 << 10 ) +#define CLK_T0_DIS (0x0 << 10 ) /* DIS. Disable T0 clocks. */ +#define CLK_T0_EN (0x1 << 10 ) /* EN. Enable T0 clocks. */ + +/* CLK[PWM] - PWM clocks enable bit. */ +#define CLK_PWM_MSK (0x1 << 9 ) +#define CLK_PWM (0x1 << 9 ) +#define CLK_PWM_DIS (0x0 << 9 ) /* DIS. Disable PWM clocks. */ +#define CLK_PWM_EN (0x1 << 9 ) /* EN. Enable PWM clocks. */ + +/* CLK[I2C] - I2C clocks enable bit. */ +#define CLK_I2C_MSK (0x1 << 8 ) +#define CLK_I2C (0x1 << 8 ) +#define CLK_I2C_DIS (0x0 << 8 ) /* DIS. Disable I2C clocks. */ +#define CLK_I2C_EN (0x1 << 8 ) /* EN. Enable I2C clocks. */ + +/* CLK[COM] - UART clocks enable bit. */ +#define CLK_COM_MSK (0x1 << 7 ) +#define CLK_COM (0x1 << 7 ) +#define CLK_COM_DIS (0x0 << 7 ) /* DIS. Disable UART clocks. */ +#define CLK_COM_EN (0x1 << 7 ) /* EN. Enable UART clocks. */ + +/* CLK[SPI1] - SPI1 clocks enable bit. */ +#define CLK_SPI1_MSK (0x1 << 6 ) +#define CLK_SPI1 (0x1 << 6 ) +#define CLK_SPI1_DIS (0x0 << 6 ) /* DIS. Disable SPI1 clocks. */ +#define CLK_SPI1_EN (0x1 << 6 ) /* EN. Enable SPI1 clocks. */ + +/* CLK[SPI0] - SPI0 clocks enable bit. */ +#define CLK_SPI0_MSK (0x1 << 5 ) +#define CLK_SPI0 (0x1 << 5 ) +#define CLK_SPI0_DIS (0x0 << 5 ) /* DIS. Disable SPI0 clocks. */ +#define CLK_SPI0_EN (0x1 << 5 ) /* EN. Enable SPI0 clocks. */ + +/* CLK[T2] - T2 clocks enable bit. */ +#define CLK_T2_MSK (0x1 << 4 ) +#define CLK_T2 (0x1 << 4 ) +#define CLK_T2_DIS (0x0 << 4 ) /* DIS. Disable T2 clocks. */ +#define CLK_T2_EN (0x1 << 4 ) /* EN. Enable T2 clocks. */ + +/* CLK[ADC] - ADC clocks enable bit. */ +#define CLK_ADC_MSK (0x1 << 3 ) +#define CLK_ADC (0x1 << 3 ) +#define CLK_ADC_DIS (0x0 << 3 ) /* DIS. Disable ADC clocks. */ +#define CLK_ADC_EN (0x1 << 3 ) /* EN. Enable ADC clocks. */ + +/* CLK[SRAM] - SRAM clocks enable bit. */ +#define CLK_SRAM_MSK (0x1 << 2 ) +#define CLK_SRAM (0x1 << 2 ) +#define CLK_SRAM_DIS (0x0 << 2 ) /* DIS. Disable SRAM memory clocks. */ +#define CLK_SRAM_EN (0x1 << 2 ) /* EN. Enable SRAM memory clocks. */ + +/* CLK[FEE] - Flash clocks enable bit. */ +#define CLK_FEE_MSK (0x1 << 1 ) +#define CLK_FEE (0x1 << 1 ) +#define CLK_FEE_DIS (0x0 << 1 ) /* DIS. Disable Flash memory clocks. */ +#define CLK_FEE_EN (0x1 << 1 ) /* EN. Enable Flash memory clocks. */ + +/* CLK[DMA] - DMA clock enable bit. */ +#define CLK_DMA_MSK (0x1 << 0 ) +#define CLK_DMA (0x1 << 0 ) +#define CLK_DMA_DIS (0x0 << 0 ) /* DIS. Disable DMA clock. */ +#define CLK_DMA_EN (0x1 << 0 ) /* EN. Enable DMA clock. */ + +/* SPIDIV[BCRST] - Configures the behavior of SPI communication after an abrupt deassertion of CS. This bit should be set in slave and master mode. */ +#define SPIDIV_BCRST_MSK (0x1 << 7 ) +#define SPIDIV_BCRST (0x1 << 7 ) +#define SPIDIV_BCRST_DIS (0x0 << 7 ) /* DIS. Resumes communication from where it stopped when the CS is deasserted. The rest of the bits are then received/ transmitted when CS returns low. User code should ignore the CSERR interrupt. */ +#define SPIDIV_BCRST_EN (0x1 << 7 ) /* EN. Enabled for a clean restart of SPI transfer after a CSERR condition. User code must also clear the SPI enable bit in SPI0CON during the CSERR interrupt. */ + +/* SPIDIV[DIV] - Factor used to divide UCLK in the generation of the master mode serial clock. */ +#define SPIDIV_DIV_MSK (0x3F << 0 ) + +/* SPICON[MOD] - IRQ mode bits. When TIM is set these bits configure when the Tx/Rx interrupts occur in a transfer. For a DMA Rx transfer, these bits should be 00. */ +#define SPICON_MOD_MSK (0x3 << 14 ) +#define SPICON_MOD_TX1RX1 (0x0 << 14 ) /* TX1RX1. Tx/Rx interrupt occurs when 1 byte has been transmitted/received from/into the FIFO. */ +#define SPICON_MOD_TX2RX2 (0x1 << 14 ) /* TX2RX2. Tx/Rx interrupt occurs when 2 bytes have been transmitted/received from/into the FIFO. */ +#define SPICON_MOD_TX3RX3 (0x2 << 14 ) /* TX3RX3. Tx/Rx interrupt occurs when 3 bytes have been transmitted/received from/into the FIFO. */ +#define SPICON_MOD_TX4RX4 (0x3 << 14 ) /* TX4RX4. Tx/Rx interrupt occurs when 4 bytes have been transmitted/received from/into the FIFO. */ + +/* SPICON[TFLUSH] - Tx FIFO flush enable bit. */ +#define SPICON_TFLUSH_MSK (0x1 << 13 ) +#define SPICON_TFLUSH (0x1 << 13 ) +#define SPICON_TFLUSH_DIS (0x0 << 13 ) /* DIS. Disable Tx FIFO flushing. */ +#define SPICON_TFLUSH_EN (0x1 << 13 ) /* EN. Flush the Tx FIFO. This bit does not clear itself and should be toggled if a single flush is required. If this bit is left high, then either the last transmitted value or 0x00 is transmitted depending on the ZEN bit (SPI0CON[7]). Any writes to the Tx FIFO are ignored while this bit is set. */ + +/* SPICON[RFLUSH] - Rx FIFO flush enable bit. */ +#define SPICON_RFLUSH_MSK (0x1 << 12 ) +#define SPICON_RFLUSH (0x1 << 12 ) +#define SPICON_RFLUSH_DIS (0x0 << 12 ) /* DIS. Disable Rx FIFO flushing. */ +#define SPICON_RFLUSH_EN (0x1 << 12 ) /* EN. If this bit is set, all incoming data is ignored and no interrupts are generated. If set and TIM = 0 (SPI0CON[6]), a read of the Rx FIFO initiates a transfer. */ + +/* SPICON[CON] - Continuous transfer enable bit. */ +#define SPICON_CON_MSK (0x1 << 11 ) +#define SPICON_CON (0x1 << 11 ) +#define SPICON_CON_DIS (0x0 << 11 ) /* DIS. Disable continuous transfer. Each transfer consists of a single 8-bit serial transfer. If valid data exists in the SPIxTX register, then a new transfer is initiated after a stall period of one serial clock cycle. The CS line is deactivated for this one serial clock cycle. */ +#define SPICON_CON_EN (0x1 << 11 ) /* EN. Enable continuous transfer. In master mode, the transfer continues until no valid data is available in the Tx register. CS is asserted and remains asserted for the duration of each 8-bit serial transfer until Tx is empty. */ + +/* SPICON[LOOPBACK] - Loopback enable bit. */ +#define SPICON_LOOPBACK_MSK (0x1 << 10 ) +#define SPICON_LOOPBACK (0x1 << 10 ) +#define SPICON_LOOPBACK_DIS (0x0 << 10 ) /* DIS. Normal mode. */ +#define SPICON_LOOPBACK_EN (0x1 << 10 ) /* EN. Connect MISO to MOSI, thus, data transmitted from Tx register is looped back to the Rx register. SPI must be configured in master mode. */ + +/* SPICON[SOEN] - Slave output enable bit. */ +#define SPICON_SOEN_MSK (0x1 << 9 ) +#define SPICON_SOEN (0x1 << 9 ) +#define SPICON_SOEN_DIS (0x0 << 9 ) /* DIS. Disable the output driver on the MISO pin. The MISO pin is open-circuit when this bit is clear. */ +#define SPICON_SOEN_EN (0x1 << 9 ) /* EN. MISO operates as normal. */ + +/* SPICON[RXOF] - RX overflow overwrite enable bit. */ +#define SPICON_RXOF_MSK (0x1 << 8 ) +#define SPICON_RXOF (0x1 << 8 ) +#define SPICON_RXOF_DIS (0x0 << 8 ) /* DIS. The new serial byte received is discarded when there is no space left in the FIFO */ +#define SPICON_RXOF_EN (0x1 << 8 ) /* EN. The valid data in the Rx register is overwritten by the new serial byte received when there is no space left in the FIFO. */ + +/* SPICON[ZEN] - Transmit underrun: Transmit 0s when the Tx FIFO is empty */ +#define SPICON_ZEN_MSK (0x1 << 7 ) +#define SPICON_ZEN (0x1 << 7 ) +#define SPICON_ZEN_DIS (0x0 << 7 ) /* DIS. The last byte from the previous transmission is shifted out when a transfer is initiated with no valid data in the FIFO. */ +#define SPICON_ZEN_EN (0x1 << 7 ) /* EN. Transmit 0x00 when a transfer is initiated with no valid data in the FIFO. */ + +/* SPICON[TIM] - Transfer and interrupt mode bit. */ +#define SPICON_TIM_MSK (0x1 << 6 ) +#define SPICON_TIM (0x1 << 6 ) +#define SPICON_TIM_TXWR (0x1 << 6 ) /* TXWR. Initiate transfer with a write to the SPIxTX register. Interrupt only occurs when Tx is empty. */ +#define SPICON_TIM_RXRD (0x0 << 6 ) /* RXRD. Initiate transfer with a read of the SPIxRX register. The read must be done while the SPI interface is idle. Interrupt only occurs when Rx is full. */ + +/* SPICON[LSB] - LSB first transfer enable bit. */ +#define SPICON_LSB_MSK (0x1 << 5 ) +#define SPICON_LSB (0x1 << 5 ) +#define SPICON_LSB_DIS (0x0 << 5 ) /* DIS. MSB is transmitted first. */ +#define SPICON_LSB_EN (0x1 << 5 ) /* EN. LSB is transmitted first. */ + +/* SPICON[WOM] - Wired OR enable bit. */ +#define SPICON_WOM_MSK (0x1 << 4 ) +#define SPICON_WOM (0x1 << 4 ) +#define SPICON_WOM_DIS (0x0 << 4 ) /* DIS. Normal driver output operation. */ +#define SPICON_WOM_EN (0x1 << 4 ) /* EN. Enable open circuit data output for multimaster/multislave configuration. */ + +/* SPICON[CPOL] - Serial clock polarity mode bit. */ +#define SPICON_CPOL_MSK (0x1 << 3 ) +#define SPICON_CPOL (0x1 << 3 ) +#define SPICON_CPOL_LOW (0x0 << 3 ) /* LOW. Serial clock idles low. */ +#define SPICON_CPOL_HIGH (0x1 << 3 ) /* HIGH. Serial clock idles high. */ + +/* SPICON[CPHA] - Serial clock phase mode bit. */ +#define SPICON_CPHA_MSK (0x1 << 2 ) +#define SPICON_CPHA (0x1 << 2 ) +#define SPICON_CPHA_SAMPLELEADING (0x0 << 2 ) /* SAMPLELEADING. Serial clock pulses at the middle of the first data bit transfer. */ +#define SPICON_CPHA_SAMPLETRAILING (0x1 << 2 ) /* SAMPLETRAILING. Serial clock pulses at the start of the first data bit. */ + +/* SPICON[MASEN] - Master mode enable bit. */ +#define SPICON_MASEN_MSK (0x1 << 1 ) +#define SPICON_MASEN (0x1 << 1 ) +#define SPICON_MASEN_DIS (0x0 << 1 ) /* DIS. Configure in slave mode. */ +#define SPICON_MASEN_EN (0x1 << 1 ) /* EN. Configure in master mode. */ + +/* SPICON[ENABLE] - SPI enable bit. */ +#define SPICON_ENABLE_MSK (0x1 << 0 ) +#define SPICON_ENABLE (0x1 << 0 ) +#define SPICON_ENABLE_DIS (0x0 << 0 ) /* DIS. Disable the SPI. Clearing this bit will also reset all the FIFO related logic to enable a clean start. */ +#define SPICON_ENABLE_EN (0x1 << 0 ) /* EN. Enable the SPI. */ + +/* SPIDMA[IENRXDMA] - Receive DMA request enable bit. */ +#define SPIDMA_IENRXDMA_MSK (0x1 << 2 ) +#define SPIDMA_IENRXDMA (0x1 << 2 ) +#define SPIDMA_IENRXDMA_DIS (0x0 << 2 ) /* DIS. Disable Rx DMA requests. */ +#define SPIDMA_IENRXDMA_EN (0x1 << 2 ) /* EN. Enable Rx DMA requests. */ + +/* SPIDMA[IENTXDMA] - Transmit DMA request enable bit. */ +#define SPIDMA_IENTXDMA_MSK (0x1 << 1 ) +#define SPIDMA_IENTXDMA (0x1 << 1 ) +#define SPIDMA_IENTXDMA_DIS (0x0 << 1 ) /* DIS. Disable Tx DMA requests. */ +#define SPIDMA_IENTXDMA_EN (0x1 << 1 ) /* EN. Enable Tx DMA requests. */ + +/* SPIDMA[ENABLE] - DMA data transfer enable bit. */ +#define SPIDMA_ENABLE_MSK (0x1 << 0 ) +#define SPIDMA_ENABLE (0x1 << 0 ) +#define SPIDMA_ENABLE_DIS (0x0 << 0 ) /* DIS. Disable DMA transfer. This bit needs to be cleared to prevent extra DMA request to the µDMA controller. */ +#define SPIDMA_ENABLE_EN (0x1 << 0 ) /* EN. Enable a DMA transfer. Starts the transfer of a master configured to initiate transfer on transmit. */ + +/* SPISTA[CSERR] - CS error status bit. This bit generates an interrupt when detecting an abrupt CS desassertion before the full byte of data is transmitted completely. */ +#define SPISTA_CSERR_MSK (0x1 << 12 ) +#define SPISTA_CSERR (0x1 << 12 ) +#define SPISTA_CSERR_CLR (0x0 << 12 ) /* CLR: Cleared when no CS error is detected. Cleared to 0 on a read of SPI0STA register. */ +#define SPISTA_CSERR_SET (0x1 << 12 ) /* SET: Set when the CS line is deasserted abruptly. */ + +/* SPISTA[RXS] - Rx FIFO excess bytes present. */ +#define SPISTA_RXS_MSK (0x1 << 11 ) +#define SPISTA_RXS (0x1 << 11 ) +#define SPISTA_RXS_CLR (0x0 << 11 ) /* CLR. When the number of bytes in the FIFO is equal or less than the number in SPI0CON[15:14]. This bit is not cleared on a read of SPI0STA register. */ +#define SPISTA_RXS_SET (0x1 << 11 ) /* SET. When there are more bytes in the Rx FIFO than configured in MOD (SPI0CON[15:14]). For example if MOD = TX1RX1, RXS is set when there are 2 or more bytes in the Rx FIFO. This bit does not dependent on SPI0CON[6] and does not cause an interrupt. */ + +/* SPISTA[RXFSTA] - Rx FIFO status bits, indicates how many valid bytes are in the Rx FIFO. */ +#define SPISTA_RXFSTA_MSK (0x7 << 8 ) +#define SPISTA_RXFSTA_EMPTY (0x0 << 8 ) /* EMPTY. When Rx FIFO is empty. */ +#define SPISTA_RXFSTA_ONEBYTE (0x1 << 8 ) /* ONEBYTE. When 1 valid byte is in the FIFO. */ +#define SPISTA_RXFSTA_TWOBYTES (0x2 << 8 ) /* TWOBYTES. When 2 valid bytes are in the FIFO. */ +#define SPISTA_RXFSTA_THREEBYTES (0x3 << 8 ) /* THREEBYTES. When 3 valid bytes are in the FIFO. */ +#define SPISTA_RXFSTA_FOURBYTES (0x4 << 8 ) /* FOURBYTES. When 4 valid bytes are in the FIFO. */ + +/* SPISTA[RXOF] - Rx FIFO overflow status bit. This bit generates an interrupt. */ +#define SPISTA_RXOF_MSK (0x1 << 7 ) +#define SPISTA_RXOF (0x1 << 7 ) +#define SPISTA_RXOF_CLR (0x0 << 7 ) /* CLR. Cleared to 0 on a read of SPI0STA register. */ +#define SPISTA_RXOF_SET (0x1 << 7 ) /* SET. Set when the Rx FIFO is already full when new data is loaded to the FIFO. This bit generates an interrupt except when RFLUSH is set. (SPI0CON[12]). */ + +/* SPISTA[RX] - Rx interrupt status bit. This bit generates an interrupt, except when DMA transfer is enabled. */ +#define SPISTA_RX_MSK (0x1 << 6 ) +#define SPISTA_RX (0x1 << 6 ) +#define SPISTA_RX_CLR (0x0 << 6 ) /* CLR. Cleared to 0 on a read of SPI0STA register. */ +#define SPISTA_RX_SET (0x1 << 6 ) /* SET. Set when a receive interrupt occurs. This bit is set when TIM (SPI0CON[6]) is cleared and the required number of bytes have been received. */ + +/* SPISTA[TX] - Tx interrupt status bit. This bit generates an interrupt, except when DMA transfer is enabled. */ +#define SPISTA_TX_MSK (0x1 << 5 ) +#define SPISTA_TX (0x1 << 5 ) +#define SPISTA_TX_CLR (0x0 << 5 ) /* CLR. Cleared to 0 on a read of SPI0STA register. */ +#define SPISTA_TX_SET (0x1 << 5 ) /* SET. Set when a transmit interrupt occurs. This bit is set when TIM (SPI0CON[6]) set and the required number of bytes have been transmitted. */ + +/* SPISTA[TXUR] - Tx FIFO Underrun. This bit generates an interrupt. */ +#define SPISTA_TXUR_MSK (0x1 << 4 ) +#define SPISTA_TXUR (0x1 << 4 ) +#define SPISTA_TXUR_CLR (0x0 << 4 ) /* CLR. Cleared to 0 on a read of SPI0STA register. */ +#define SPISTA_TXUR_SET (0x1 << 4 ) /* SET. Set when a transmit is initiated without any valid data in the Tx FIFO. This bit generates an interrupt except when TFLUSH is set in SPI0CON. */ + +/* SPISTA[TXFSTA] - Tx FIFO status bits, indicates how many valid bytes are in the Tx FIFO. */ +#define SPISTA_TXFSTA_MSK (0x7 << 1 ) +#define SPISTA_TXFSTA_EMPTY (0x0 << 1 ) /* EMPTY. Tx FIFO is empty. */ +#define SPISTA_TXFSTA_ONEBYTE (0x1 << 1 ) /* ONEBYTE. 1 valid byte is in the FIFO. */ +#define SPISTA_TXFSTA_TWOBYTES (0x2 << 1 ) /* TWOBYTES. 2 valid bytes are in the FIFO. */ +#define SPISTA_TXFSTA_THREEBYTES (0x3 << 1 ) /* THREEBYTES. 3 valid bytes are in the FIFO. */ +#define SPISTA_TXFSTA_FOURBYTES (0x4 << 1 ) /* FOURBYTES . 4 valid bytes are in the FIFO. */ + +/* SPISTA[IRQ] - Interrupt status bit. */ +#define SPISTA_IRQ_MSK (0x1 << 0 ) +#define SPISTA_IRQ (0x1 << 0 ) +#define SPISTA_IRQ_CLR (0x0 << 0 ) /* CLR. Cleared to 0 on a read of SPI0STA register. */ +#define SPISTA_IRQ_SET (0x1 << 0 ) /* SET. Set to 1 when an SPI0 based interrupt occurs. */ + +/* SPIDIV[BCRST] - Configures the behavior of SPI communication after an abrupt deassertion of CS. This bit should be set in slave and master mode. */ +#define SPIDIV_BCRST_MSK (0x1 << 7 ) +#define SPIDIV_BCRST (0x1 << 7 ) +#define SPIDIV_BCRST_DIS (0x0 << 7 ) /* DIS. Resumes communication from where it stopped when the CS is deasserted. The rest of the bits are then received/ transmitted when CS returns low. User code should ignore the CSERR interrupt. */ +#define SPIDIV_BCRST_EN (0x1 << 7 ) /* EN. Enabled for a clean restart of SPI transfer after a CSERR condition. User code must also clear the SPI enable bit in SPI0CON during the CSERR interrupt. */ + +/* SPIDIV[DIV] - Factor used to divide UCLK in the generation of the master mode serial clock. */ +#define SPIDIV_DIV_MSK (0x3F << 0 ) +// ------------------------------------------------------------------------------------------------ +// ----- ADC0 ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Analog to Digital Converter (pADI_ADC0) + */ + +#if (__NO_MMR_STRUCTS__==0) +typedef struct { /*!< pADI_ADC0 Structure */ + __IO uint16_t ADCCFG; /*!< ADC Configuration Register */ + __I uint16_t RESERVED0; + __IO uint8_t ADCCON; /*!< ADC Control Register */ + __I uint8_t RESERVED1[3]; + __IO uint8_t ADCSTA; /*!< ADC Status Register */ + __I uint8_t RESERVED2[3]; + __IO uint16_t ADCDAT; /*!< ADC Data Register */ + __I uint16_t RESERVED3; + __IO uint16_t ADCGN; /*!< ADC Gain Register */ + __I uint16_t RESERVED4; + __IO uint16_t ADCOF; /*!< ADC Offset Register */ +} ADI_ADC_TypeDef; +#else // (__NO_MMR_STRUCTS__==0) +#define ADCCFG (*(volatile unsigned short int *) 0x40050000) +#define ADCCON (*(volatile unsigned char *) 0x40050004) +#define ADCSTA (*(volatile unsigned char *) 0x40050008) +#define ADCDAT (*(volatile unsigned short int *) 0x4005000C) +#define ADCGN (*(volatile unsigned short int *) 0x40050010) +#define ADCOF (*(volatile unsigned short int *) 0x40050014) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for ADCCFG*/ +#define ADCCFG_RVAL 0xA00 + +/* ADCCFG[REF] - Reference select */ +#define ADCCFG_REF_BBA (*(volatile unsigned long *) 0x42A00034) +#define ADCCFG_REF_MSK (0x1 << 13 ) +#define ADCCFG_REF (0x1 << 13 ) +#define ADCCFG_REF_INTERNAL125V (0x0 << 13 ) /* INTERNAL125V. Select the internal 1.25 V reference as the ADC reference. */ +#define ADCCFG_REF_LVDD (0x1 << 13 ) /* LVDD. Select the 1.8V regulator output (LVDD1) as the ADC reference. */ + +/* ADCCFG[CLK] - ADC clock frequency */ +#define ADCCFG_CLK_MSK (0x7 << 10 ) +#define ADCCFG_CLK_FCORE (0x0 << 10 ) /* FCORE. */ +#define ADCCFG_CLK_FCOREDIV2 (0x1 << 10 ) /* FCOREDIV2. */ +#define ADCCFG_CLK_FCOREDIV4 (0x2 << 10 ) /* FCOREDIV4. */ +#define ADCCFG_CLK_FCOREDIV8 (0x3 << 10 ) /* FCOREDIV8. */ +#define ADCCFG_CLK_FCOREDIV16 (0x4 << 10 ) /* FCOREDIV16. */ +#define ADCCFG_CLK_FCOREDIV32 (0x5 << 10 ) /* FCOREDIV32. */ + +/* ADCCFG[ACQ] - Acquisition clocks */ +#define ADCCFG_ACQ_MSK (0x3 << 8 ) +#define ADCCFG_ACQ_2 (0x0 << 8 ) /* 2. */ +#define ADCCFG_ACQ_4 (0x1 << 8 ) /* 4. */ +#define ADCCFG_ACQ_8 (0x2 << 8 ) /* 8. */ +#define ADCCFG_ACQ_16 (0x3 << 8 ) /* 16. */ + +/* ADCCFG[CHSEL] - Channel select */ +#define ADCCFG_CHSEL_MSK (0xF << 0 ) +#define ADCCFG_CHSEL_ADC0 (0x0 << 0 ) /* ADC0. Single ended ADC0 input. */ +#define ADCCFG_CHSEL_ADC1 (0x1 << 0 ) /* ADC1. Single ended ADC1 input. */ +#define ADCCFG_CHSEL_ADC2 (0x2 << 0 ) /* ADC2. Single ended ADC2 input. */ +#define ADCCFG_CHSEL_ADC3 (0x3 << 0 ) /* ADC3. Single ended ADC3 input. */ +#define ADCCFG_CHSEL_ADC4 (0x4 << 0 ) /* ADC4. Single ended ADC4 input. */ +#define ADCCFG_CHSEL_ADC5 (0x5 << 0 ) /* ADC5. Single ended ADC5 input. */ +#define ADCCFG_CHSEL_DIFF0 (0x6 << 0 ) /* DIFF0. Differential ADC0 - ADC1 inputs. */ +#define ADCCFG_CHSEL_DIFF1 (0x7 << 0 ) /* DIFF1. Differential ADC2 - ADC3 inputs. */ +#define ADCCFG_CHSEL_DIFF2 (0x8 << 0 ) /* DIFF2. Differential ADC4 - ADC5 inputs. */ +#define ADCCFG_CHSEL_TEMP (0x9 << 0 ) /* TEMP. Internal temperature sensor. */ +#define ADCCFG_CHSEL_VBATDIV4 (0xA << 0 ) /* VBATDIV4. Internal supply divided by 4. */ +#define ADCCFG_CHSEL_LVDDDIV2 (0xB << 0 ) /* LVDDDIV2. Internal 1.8V regulator output (LVDD1) divided by 2. */ +#define ADCCFG_CHSEL_VREF (0xC << 0 ) /* VREF. Internal ADC reference input for gain calibration. */ +#define ADCCFG_CHSEL_AGND (0xD << 0 ) /* AGND. Internal ADC ground input for offset calibration. */ + +/* Reset Value for ADCCON*/ +#define ADCCON_RVAL 0x90 + +/* ADCCON[REFBUF] - Reference buffer enable bit. */ +#define ADCCON_REFBUF_BBA (*(volatile unsigned long *) 0x42A0009C) +#define ADCCON_REFBUF_MSK (0x1 << 7 ) +#define ADCCON_REFBUF (0x1 << 7 ) +#define ADCCON_REFBUF_EN (0x0 << 7 ) /* EN. Turn on the reference buffer. The reference buffer takes 5 ms to settle and consumes approximately 210 μA. */ +#define ADCCON_REFBUF_DIS (0x1 << 7 ) /* DIS. Turn off the reference buffer. The internal reference buffer must be turned off if using an external reference. */ + +/* ADCCON[DMA] - DMA transfer enable bit. */ +#define ADCCON_DMA_BBA (*(volatile unsigned long *) 0x42A00098) +#define ADCCON_DMA_MSK (0x1 << 6 ) +#define ADCCON_DMA (0x1 << 6 ) +#define ADCCON_DMA_DIS (0x0 << 6 ) /* DIS. Disable DMA transfer. */ +#define ADCCON_DMA_EN (0x1 << 6 ) /* EN. Enable DMA transfer. */ + +/* ADCCON[IEN] - Interrupt enable. */ +#define ADCCON_IEN_BBA (*(volatile unsigned long *) 0x42A00094) +#define ADCCON_IEN_MSK (0x1 << 5 ) +#define ADCCON_IEN (0x1 << 5 ) +#define ADCCON_IEN_DIS (0x0 << 5 ) /* DIS. Disable the ADC interrupt. */ +#define ADCCON_IEN_EN (0x1 << 5 ) /* EN. Enable the ADC interrupt. An interrupt is generated when new data is available. */ + +/* ADCCON[ENABLE] - ADC enable. */ +#define ADCCON_ENABLE_BBA (*(volatile unsigned long *) 0x42A00090) +#define ADCCON_ENABLE_MSK (0x1 << 4 ) +#define ADCCON_ENABLE (0x1 << 4 ) +#define ADCCON_ENABLE_EN (0x0 << 4 ) /* EN. Enable the ADC. */ +#define ADCCON_ENABLE_DIS (0x1 << 4 ) /* DIS. Disable the ADC. */ + +/* ADCCON[MOD] - Conversion mode. */ +#define ADCCON_MOD_MSK (0x7 << 1 ) +#define ADCCON_MOD_SOFT (0x0 << 1 ) /* SOFT. Software trigger, used in conjunction with the START bit. */ +#define ADCCON_MOD_CONT (0x1 << 1 ) /* CONT. Continuous convert mode. */ +#define ADCCON_MOD_T0OVF (0x3 << 1 ) /* T0OVF. Timer0 overflow. */ +#define ADCCON_MOD_T1OVF (0x4 << 1 ) /* T1OVF. Timer1 overflow. */ +#define ADCCON_MOD_GPIO (0x5 << 1 ) /* GPIO. ADC conversion triggered by P0.3 input. */ + +/* ADCCON[START] - ADC conversion start. */ +#define ADCCON_START_BBA (*(volatile unsigned long *) 0x42A00080) +#define ADCCON_START_MSK (0x1 << 0 ) +#define ADCCON_START (0x1 << 0 ) +#define ADCCON_START_DIS (0x0 << 0 ) /* DIS. Has no effect. */ +#define ADCCON_START_EN (0x1 << 0 ) /* EN. Start conversion when SOFT conversion mode is selected. This bit does not clear after a single software conversion. */ + +/* Reset Value for ADCSTA*/ +#define ADCSTA_RVAL 0x0 + +/* ADCSTA[READY] - ADC Ready bit */ +#define ADCSTA_READY_BBA (*(volatile unsigned long *) 0x42A00100) +#define ADCSTA_READY_MSK (0x1 << 0 ) +#define ADCSTA_READY (0x1 << 0 ) +#define ADCSTA_READY_CLR (0x0 << 0 ) /* CLR. Cleared automatically when ADCDAT is read. */ +#define ADCSTA_READY_EN (0x1 << 0 ) /* EN. Set by the ADC when a conversion is complete. This bit generates an interrupt if enabled (IEN set in ADCCON). */ + +/* Reset Value for ADCDAT*/ +#define ADCDAT_RVAL 0x0 + +/* ADCDAT[VALUE] - ADC result */ +#define ADCDAT_VALUE_MSK (0xFFF << 2 ) + +/* ADCDAT[Value_Reserved] - ADC result / Reserved */ +#define ADCDAT_Value_Reserved_MSK (0x3 << 0 ) + +/* Reset Value for ADCGN*/ +#define ADCGN_RVAL 0x0 + +/* ADCGN[VALUE] - Gain */ +#define ADCGN_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for ADCOF*/ +#define ADCOF_RVAL 0x0 + +/* ADCOF[VALUE] - Offset */ +#define ADCOF_VALUE_MSK (0xFFFF << 0 ) +// ------------------------------------------------------------------------------------------------ +// ----- CLKCTL ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Clock Control (pADI_CLKCTL) + */ + +#if (__NO_MMR_STRUCTS__==0) +typedef struct { /*!< pADI_CLKCTL Structure */ + __IO uint16_t CLKCON; /*!< System Clocking Architecture Control Register */ + __I uint16_t RESERVED0[519]; + __IO uint8_t XOSCCON; /*!< Crystal Oscillator Control Register */ + __I uint8_t RESERVED1[111]; + __IO uint16_t CLKACT; /*!< Clock in Active Mode Enable Register */ + __I uint16_t RESERVED2; + __IO uint16_t CLKPD; /*!< Clock in Power-Down Mode Enable Register */ +} ADI_CLKCTL_TypeDef; +#else // (__NO_MMR_STRUCTS__==0) +#define CLKCON (*(volatile unsigned short int *) 0x40002000) +#define XOSCCON (*(volatile unsigned char *) 0x40002410) +#define CLKACT (*(volatile unsigned short int *) 0x40002480) +#define CLKPD (*(volatile unsigned short int *) 0x40002484) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for CLKCON*/ +#define CLKCON_RVAL 0x0 + +/* CLKCON[CLKOUT] - GPIO output clock multiplexer select bits. */ +#define CLKCON_CLKOUT_MSK (0x7 << 5 ) +#define CLKCON_CLKOUT_UCLKCG (0x0 << 5 ) /* UCLKCG. */ +#define CLKCON_CLKOUT_UCLK (0x1 << 5 ) /* UCLK. */ +#define CLKCON_CLKOUT_PCLK (0x2 << 5 ) /* PCLK. */ +#define CLKCON_CLKOUT_HFOSC (0x5 << 5 ) /* HFOSC. */ +#define CLKCON_CLKOUT_LFOSC (0x6 << 5 ) /* LFOSC. */ +#define CLKCON_CLKOUT_LFXTAL (0x7 << 5 ) /* LFXTAL. */ + +/* CLKCON[CLKMUX] - Digital subsystem clock source select bits. */ +#define CLKCON_CLKMUX_MSK (0x3 << 3 ) +#define CLKCON_CLKMUX_HFOSC (0x0 << 3 ) /* HFOSC. 16MHz internal oscillator. */ +#define CLKCON_CLKMUX_LFXTAL (0x1 << 3 ) /* LFXTAL. 32.768kHz external crystal. */ +#define CLKCON_CLKMUX_LFOSC (0x2 << 3 ) /* LFOSC. 32.768kHz internal oscillator. */ +#define CLKCON_CLKMUX_ECLKIN (0x3 << 3 ) /* ECLKIN. External clock on P0.5. */ + +/* CLKCON[CD] - Clock divide bits. */ +#define CLKCON_CD_MSK (0x7 << 0 ) +#define CLKCON_CD_DIV1 (0x0 << 0 ) /* DIV1. */ +#define CLKCON_CD_DIV2 (0x1 << 0 ) /* DIV2. */ +#define CLKCON_CD_DIV4 (0x2 << 0 ) /* DIV4. */ +#define CLKCON_CD_DIV8 (0x3 << 0 ) /* DIV8. */ +#define CLKCON_CD_DIV16 (0x4 << 0 ) /* DIV16. */ +#define CLKCON_CD_DIV32 (0x5 << 0 ) /* DIV32. */ +#define CLKCON_CD_DIV64 (0x6 << 0 ) /* DIV64. */ +#define CLKCON_CD_DIV128 (0x7 << 0 ) /* DIV128. */ + +/* Reset Value for XOSCCON*/ +#define XOSCCON_RVAL 0x0 + +/* XOSCCON[ENABLE] - Crystal oscillator circuit enable bit. */ +#define XOSCCON_ENABLE_BBA (*(volatile unsigned long *) 0x42048200) +#define XOSCCON_ENABLE_MSK (0x1 << 0 ) +#define XOSCCON_ENABLE (0x1 << 0 ) +#define XOSCCON_ENABLE_DIS (0x0 << 0 ) /* DIS. Disables the watch crystal circuitry.(LFXTAL) */ +#define XOSCCON_ENABLE_EN (0x1 << 0 ) /* EN. Enables the watch crystal circuitry.(LFXTAL) */ + +/* Reset Value for CLKACT*/ +#define CLKACT_RVAL 0x3FFF + +/* CLKACT[T1] - T1 clocks enable bit. */ +#define CLKACT_T1_BBA (*(volatile unsigned long *) 0x4204902C) +#define CLKACT_T1_MSK (0x1 << 11 ) +#define CLKACT_T1 (0x1 << 11 ) +#define CLKACT_T1_DIS (0x0 << 11 ) /* DIS. Disable T1 clocks. */ +#define CLKACT_T1_EN (0x1 << 11 ) /* EN. Enable T1 clocks. */ + +/* CLKACT[T0] - T0 clocks enable bit. */ +#define CLKACT_T0_BBA (*(volatile unsigned long *) 0x42049028) +#define CLKACT_T0_MSK (0x1 << 10 ) +#define CLKACT_T0 (0x1 << 10 ) +#define CLKACT_T0_DIS (0x0 << 10 ) /* DIS. Disable T0 clocks. */ +#define CLKACT_T0_EN (0x1 << 10 ) /* EN. Enable T0 clocks. */ + +/* CLKACT[PWM] - PWM clocks enable bit. */ +#define CLKACT_PWM_BBA (*(volatile unsigned long *) 0x42049024) +#define CLKACT_PWM_MSK (0x1 << 9 ) +#define CLKACT_PWM (0x1 << 9 ) +#define CLKACT_PWM_DIS (0x0 << 9 ) /* DIS. Disable PWM clocks. */ +#define CLKACT_PWM_EN (0x1 << 9 ) /* EN. Enable PWM clocks. */ + +/* CLKACT[I2C] - I2C clocks enable bit. */ +#define CLKACT_I2C_BBA (*(volatile unsigned long *) 0x42049020) +#define CLKACT_I2C_MSK (0x1 << 8 ) +#define CLKACT_I2C (0x1 << 8 ) +#define CLKACT_I2C_DIS (0x0 << 8 ) /* DIS. Disable I2C clocks. */ +#define CLKACT_I2C_EN (0x1 << 8 ) /* EN. Enable I2C clocks. */ + +/* CLKACT[COM] - UART clocks enable bit. */ +#define CLKACT_COM_BBA (*(volatile unsigned long *) 0x4204901C) +#define CLKACT_COM_MSK (0x1 << 7 ) +#define CLKACT_COM (0x1 << 7 ) +#define CLKACT_COM_DIS (0x0 << 7 ) /* DIS. Disable UART clocks. */ +#define CLKACT_COM_EN (0x1 << 7 ) /* EN. Enable UART clocks. */ + +/* CLKACT[SPI1] - SPI1 clocks enable bit. */ +#define CLKACT_SPI1_BBA (*(volatile unsigned long *) 0x42049018) +#define CLKACT_SPI1_MSK (0x1 << 6 ) +#define CLKACT_SPI1 (0x1 << 6 ) +#define CLKACT_SPI1_DIS (0x0 << 6 ) /* DIS. Disable SPI1 clocks. */ +#define CLKACT_SPI1_EN (0x1 << 6 ) /* EN. Enable SPI1 clocks. */ + +/* CLKACT[SPI0] - SPI0 clocks enable bit. */ +#define CLKACT_SPI0_BBA (*(volatile unsigned long *) 0x42049014) +#define CLKACT_SPI0_MSK (0x1 << 5 ) +#define CLKACT_SPI0 (0x1 << 5 ) +#define CLKACT_SPI0_DIS (0x0 << 5 ) /* DIS. Disable SPI0 clocks. */ +#define CLKACT_SPI0_EN (0x1 << 5 ) /* EN. Enable SPI0 clocks. */ + +/* CLKACT[T2] - T2 clocks enable bit. */ +#define CLKACT_T2_BBA (*(volatile unsigned long *) 0x42049010) +#define CLKACT_T2_MSK (0x1 << 4 ) +#define CLKACT_T2 (0x1 << 4 ) +#define CLKACT_T2_DIS (0x0 << 4 ) /* DIS. Disable T2 clocks. */ +#define CLKACT_T2_EN (0x1 << 4 ) /* EN. Enable T2 clocks. */ + +/* CLKACT[ADC] - ADC clocks enable bit. */ +#define CLKACT_ADC_BBA (*(volatile unsigned long *) 0x4204900C) +#define CLKACT_ADC_MSK (0x1 << 3 ) +#define CLKACT_ADC (0x1 << 3 ) +#define CLKACT_ADC_DIS (0x0 << 3 ) /* DIS. Disable ADC clocks. */ +#define CLKACT_ADC_EN (0x1 << 3 ) /* EN. Enable ADC clocks. */ + +/* CLKACT[SRAM] - SRAM clocks enable bit. */ +#define CLKACT_SRAM_BBA (*(volatile unsigned long *) 0x42049008) +#define CLKACT_SRAM_MSK (0x1 << 2 ) +#define CLKACT_SRAM (0x1 << 2 ) +#define CLKACT_SRAM_DIS (0x0 << 2 ) /* DIS. Disable SRAM memory clocks. */ +#define CLKACT_SRAM_EN (0x1 << 2 ) /* EN. Enable SRAM memory clocks. */ + +/* CLKACT[FEE] - Flash clocks enable bit. */ +#define CLKACT_FEE_BBA (*(volatile unsigned long *) 0x42049004) +#define CLKACT_FEE_MSK (0x1 << 1 ) +#define CLKACT_FEE (0x1 << 1 ) +#define CLKACT_FEE_DIS (0x0 << 1 ) /* DIS. Disable Flash memory clocks. */ +#define CLKACT_FEE_EN (0x1 << 1 ) /* EN. Enable Flash memory clocks. */ + +/* CLKACT[DMA] - DMA clock enable bit. */ +#define CLKACT_DMA_BBA (*(volatile unsigned long *) 0x42049000) +#define CLKACT_DMA_MSK (0x1 << 0 ) +#define CLKACT_DMA (0x1 << 0 ) +#define CLKACT_DMA_DIS (0x0 << 0 ) /* DIS.Disable DMA clock. */ +#define CLKACT_DMA_EN (0x1 << 0 ) /* EN. Enable DMA clock. */ + +/* Reset Value for CLKPD*/ +#define CLKPD_RVAL 0x3FFF + +/* CLKPD[T1] - T1 clocks enable bit. */ +#define CLKPD_T1_BBA (*(volatile unsigned long *) 0x420490AC) +#define CLKPD_T1_MSK (0x1 << 11 ) +#define CLKPD_T1 (0x1 << 11 ) +#define CLKPD_T1_DIS (0x0 << 11 ) /* DIS. Disable T1 clocks. */ +#define CLKPD_T1_EN (0x1 << 11 ) /* EN. Enable T1 clocks. */ + +/* CLKPD[T0] - T0 clocks enable bit. */ +#define CLKPD_T0_BBA (*(volatile unsigned long *) 0x420490A8) +#define CLKPD_T0_MSK (0x1 << 10 ) +#define CLKPD_T0 (0x1 << 10 ) +#define CLKPD_T0_DIS (0x0 << 10 ) /* DIS. Disable T0 clocks. */ +#define CLKPD_T0_EN (0x1 << 10 ) /* EN. Enable T0 clocks. */ + +/* CLKPD[PWM] - PWM clocks enable bit. */ +#define CLKPD_PWM_BBA (*(volatile unsigned long *) 0x420490A4) +#define CLKPD_PWM_MSK (0x1 << 9 ) +#define CLKPD_PWM (0x1 << 9 ) +#define CLKPD_PWM_DIS (0x0 << 9 ) /* DIS. Disable PWM clocks. */ +#define CLKPD_PWM_EN (0x1 << 9 ) /* EN. Enable PWM clocks. */ + +/* CLKPD[I2C] - I2C clocks enable bit. */ +#define CLKPD_I2C_BBA (*(volatile unsigned long *) 0x420490A0) +#define CLKPD_I2C_MSK (0x1 << 8 ) +#define CLKPD_I2C (0x1 << 8 ) +#define CLKPD_I2C_DIS (0x0 << 8 ) /* DIS. Disable I2C clocks. */ +#define CLKPD_I2C_EN (0x1 << 8 ) /* EN. Enable I2C clocks. */ + +/* CLKPD[COM] - UART clocks enable bit. */ +#define CLKPD_COM_BBA (*(volatile unsigned long *) 0x4204909C) +#define CLKPD_COM_MSK (0x1 << 7 ) +#define CLKPD_COM (0x1 << 7 ) +#define CLKPD_COM_DIS (0x0 << 7 ) /* DIS. Disable UART clocks. */ +#define CLKPD_COM_EN (0x1 << 7 ) /* EN. Enable UART clocks. */ + +/* CLKPD[SPI1] - SPI1 clocks enable bit. */ +#define CLKPD_SPI1_BBA (*(volatile unsigned long *) 0x42049098) +#define CLKPD_SPI1_MSK (0x1 << 6 ) +#define CLKPD_SPI1 (0x1 << 6 ) +#define CLKPD_SPI1_DIS (0x0 << 6 ) /* DIS. Disable SPI1 clocks. */ +#define CLKPD_SPI1_EN (0x1 << 6 ) /* EN. Enable SPI1 clocks. */ + +/* CLKPD[SPI0] - SPI0 clocks enable bit. */ +#define CLKPD_SPI0_BBA (*(volatile unsigned long *) 0x42049094) +#define CLKPD_SPI0_MSK (0x1 << 5 ) +#define CLKPD_SPI0 (0x1 << 5 ) +#define CLKPD_SPI0_DIS (0x0 << 5 ) /* DIS. Disable SPI0 clocks. */ +#define CLKPD_SPI0_EN (0x1 << 5 ) /* EN. Enable SPI0 clocks. */ + +/* CLKPD[T2] - T2 clocks enable bit. */ +#define CLKPD_T2_BBA (*(volatile unsigned long *) 0x42049090) +#define CLKPD_T2_MSK (0x1 << 4 ) +#define CLKPD_T2 (0x1 << 4 ) +#define CLKPD_T2_DIS (0x0 << 4 ) /* DIS. Disable T2 clocks. */ +#define CLKPD_T2_EN (0x1 << 4 ) /* EN. Enable T2 clocks. */ + +/* CLKPD[ADC] - ADC clocks enable bit. */ +#define CLKPD_ADC_BBA (*(volatile unsigned long *) 0x4204908C) +#define CLKPD_ADC_MSK (0x1 << 3 ) +#define CLKPD_ADC (0x1 << 3 ) +#define CLKPD_ADC_DIS (0x0 << 3 ) /* DIS. Disable ADC clocks. */ +#define CLKPD_ADC_EN (0x1 << 3 ) /* EN. Enable ADC clocks. */ + +/* CLKPD[SRAM] - SRAM clocks enable bit. */ +#define CLKPD_SRAM_BBA (*(volatile unsigned long *) 0x42049088) +#define CLKPD_SRAM_MSK (0x1 << 2 ) +#define CLKPD_SRAM (0x1 << 2 ) +#define CLKPD_SRAM_DIS (0x0 << 2 ) /* DIS. Disable SRAM memory clocks. */ +#define CLKPD_SRAM_EN (0x1 << 2 ) /* EN. Enable SRAM memory clocks. */ + +/* CLKPD[FEE] - Flash clocks enable bit. */ +#define CLKPD_FEE_BBA (*(volatile unsigned long *) 0x42049084) +#define CLKPD_FEE_MSK (0x1 << 1 ) +#define CLKPD_FEE (0x1 << 1 ) +#define CLKPD_FEE_DIS (0x0 << 1 ) /* DIS. Disable Flash memory clocks. */ +#define CLKPD_FEE_EN (0x1 << 1 ) /* EN. Enable Flash memory clocks. */ + +/* CLKPD[DMA] - DMA clock enable bit. */ +#define CLKPD_DMA_BBA (*(volatile unsigned long *) 0x42049080) +#define CLKPD_DMA_MSK (0x1 << 0 ) +#define CLKPD_DMA (0x1 << 0 ) +#define CLKPD_DMA_DIS (0x0 << 0 ) /* DIS. Disable DMA clock. */ +#define CLKPD_DMA_EN (0x1 << 0 ) /* EN. Enable DMA clock. */ +// ------------------------------------------------------------------------------------------------ +// ----- DMA ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Direct Memory Access (pADI_DMA) + */ + +#if (__NO_MMR_STRUCTS__==0) +typedef struct { /*!< pADI_DMA Structure */ + __IO uint32_t DMASTA; /*!< Status Register */ + __IO uint32_t DMACFG; /*!< Configuration Register */ + __IO uint32_t DMAPDBPTR; /*!< Primary Control Database Pointer Register */ + __IO uint32_t DMAADBPTR; /*!< Alternate Control Database Pointer Register */ + __I uint32_t RESERVED0; + __IO uint32_t DMASWREQ; /*!< Channel Software Request Register */ + __I uint32_t RESERVED1[2]; + __IO uint32_t DMARMSKSET; /*!< Channel Request Mask Set Register */ + __IO uint32_t DMARMSKCLR; /*!< Channel Request Mask Clear Register */ + __IO uint32_t DMAENSET; /*!< Channel Enable Set Register */ + __IO uint32_t DMAENCLR; /*!< Channel Enable Clear Register */ + __IO uint32_t DMAALTSET; /*!< Channel Primary-Alternate Set Register */ + __IO uint32_t DMAALTCLR; /*!< Channel Primary-Alternate Clear Register */ + __IO uint32_t DMAPRISET; /*!< Channel Priority Set Register */ + __IO uint32_t DMAPRICLR; /*!< Channel Priority Clear Register */ + __I uint32_t RESERVED2[3]; + __IO uint32_t DMAERRCLR; /*!< Bus Error Clear Register */ +} ADI_DMA_TypeDef; +#else // (__NO_MMR_STRUCTS__==0) +#define DMASTA (*(volatile unsigned long *) 0x40010000) +#define DMACFG (*(volatile unsigned long *) 0x40010004) +#define DMAPDBPTR (*(volatile unsigned long *) 0x40010008) +#define DMAADBPTR (*(volatile unsigned long *) 0x4001000C) +#define DMASWREQ (*(volatile unsigned long *) 0x40010014) +#define DMARMSKSET (*(volatile unsigned long *) 0x40010020) +#define DMARMSKCLR (*(volatile unsigned long *) 0x40010024) +#define DMAENSET (*(volatile unsigned long *) 0x40010028) +#define DMAENCLR (*(volatile unsigned long *) 0x4001002C) +#define DMAALTSET (*(volatile unsigned long *) 0x40010030) +#define DMAALTCLR (*(volatile unsigned long *) 0x40010034) +#define DMAPRISET (*(volatile unsigned long *) 0x40010038) +#define DMAPRICLR (*(volatile unsigned long *) 0x4001003C) +#define DMAERRCLR (*(volatile unsigned long *) 0x4001004C) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for DMASTA*/ +#define DMASTA_RVAL 0xD0000 + +/* DMASTA[CHNLSMINUS1] - Number of available DMA channels minus 1. For example, if there are 14 channels available, the register reads back 0xD for these bits. */ +#define DMASTA_CHNLSMINUS1_MSK (0x1F << 16 ) +#define DMASTA_CHNLSMINUS1_FOURTEENCHNLS (0xD << 16 ) /* FOURTEENCHNLS - Controller configured to use 14 DMA channels. */ + +/* DMASTA[STATE] - Current state of DMA controller state machine. Provides insight into the operation performed by the DMA at the time this register is read. */ +#define DMASTA_STATE_MSK (0xF << 4 ) +#define DMASTA_STATE_IDLE (0x0 << 4 ) /* IDL. Idle. */ +#define DMASTA_STATE_RDCHNLDATA (0x1 << 4 ) /* RDCHNLDATA. Reading channel controller data. */ +#define DMASTA_STATE_RDSRCENDPTR (0x2 << 4 ) /* RDSRCENDPTR. Reading source data end pointer. */ +#define DMASTA_STATE_RDDSTENDPTR (0x3 << 4 ) /* RDDSTENDPTR. Reading destination end pointer. */ +#define DMASTA_STATE_RDSRCDATA (0x4 << 4 ) /* RDSRCDATA. Reading source data. */ +#define DMASTA_STATE_WRDSTDATA (0x5 << 4 ) /* WRDSTDATA. Writing destination data. */ +#define DMASTA_STATE_WAITDMAREQCLR (0x6 << 4 ) /* WAITDMAREQCLR. Waiting for DMA request to clear. */ +#define DMASTA_STATE_WRCHNLDATA (0x7 << 4 ) /* WRCHNLDATA. Writing channel controller data. */ +#define DMASTA_STATE_STALLED (0x8 << 4 ) /* STALLED. Stalled. */ +#define DMASTA_STATE_DONE (0x9 << 4 ) /* DONE. Done. */ +#define DMASTA_STATE_SCATRGATHR (0xA << 4 ) /* SCATRGATHR. Peripheral scatter-gather transition. */ + +/* DMASTA[ENABLE] - Enable status of the controller. */ +#define DMASTA_ENABLE_BBA (*(volatile unsigned long *) 0x42200000) +#define DMASTA_ENABLE_MSK (0x1 << 0 ) +#define DMASTA_ENABLE (0x1 << 0 ) +#define DMASTA_ENABLE_CLR (0x0 << 0 ) /* CLR. Controller is disabled. */ +#define DMASTA_ENABLE_SET (0x1 << 0 ) /* SET. Controller is enabled. */ + +/* Reset Value for DMACFG*/ +#define DMACFG_RVAL 0x0 + +/* DMACFG[ENABLE] - Controller enable. */ +#define DMACFG_ENABLE_BBA (*(volatile unsigned long *) 0x42200080) +#define DMACFG_ENABLE_MSK (0x1 << 0 ) +#define DMACFG_ENABLE (0x1 << 0 ) +#define DMACFG_ENABLE_DIS (0x0 << 0 ) /* DIS. Controller is disabled. */ +#define DMACFG_ENABLE_EN (0x1 << 0 ) /* EN. Controller is enabled. */ + +/* Reset Value for DMAPDBPTR*/ +#define DMAPDBPTR_RVAL 0x0 + +/* DMAPDBPTR[CTRLBASEPTR] - Pointer to the base address of the primary data structure. 5 + log (2)M LSBs are reserved and must be written 0. M is the number of channels. */ +#define DMAPDBPTR_CTRLBASEPTR_MSK (0xFFFFFFFF << 0 ) + +/* Reset Value for DMAADBPTR*/ +#define DMAADBPTR_RVAL 0x100 + +/* DMAADBPTR[ALTCBPTR] - Base address of the alternate data structure. */ +#define DMAADBPTR_ALTCBPTR_MSK (0xFFFFFFFF << 0 ) + +/* Reset Value for DMASWREQ*/ +#define DMASWREQ_RVAL 0x0 + +/* DMASWREQ[SPI0RX] - DMA SPI0 RX. */ +#define DMASWREQ_SPI0RX_BBA (*(volatile unsigned long *) 0x422002B4) +#define DMASWREQ_SPI0RX_MSK (0x1 << 13 ) +#define DMASWREQ_SPI0RX (0x1 << 13 ) +#define DMASWREQ_SPI0RX_DIS (0x0 << 13 ) /* DIS. Does not create a DMA request for SPI0RX. */ +#define DMASWREQ_SPI0RX_EN (0x1 << 13 ) /* EN. Generates a DMA request for SPI0RX. */ + +/* DMASWREQ[SPI0TX] - DMA SPI0 TX. */ +#define DMASWREQ_SPI0TX_BBA (*(volatile unsigned long *) 0x422002B0) +#define DMASWREQ_SPI0TX_MSK (0x1 << 12 ) +#define DMASWREQ_SPI0TX (0x1 << 12 ) +#define DMASWREQ_SPI0TX_DIS (0x0 << 12 ) /* DIS. Does not create a DMA request for SPI0TX. */ +#define DMASWREQ_SPI0TX_EN (0x1 << 12 ) /* EN. Generates a DMA request for SPI0TX. */ + +/* DMASWREQ[ADC] - DMA ADC. */ +#define DMASWREQ_ADC_BBA (*(volatile unsigned long *) 0x422002AC) +#define DMASWREQ_ADC_MSK (0x1 << 11 ) +#define DMASWREQ_ADC (0x1 << 11 ) +#define DMASWREQ_ADC_DIS (0x0 << 11 ) /* DIS. Does not create a DMA request for ADC. */ +#define DMASWREQ_ADC_EN (0x1 << 11 ) /* EN. Generates a DMA request for ADC. */ + +/* DMASWREQ[I2CMRX] - DMA I2C Master RX. */ +#define DMASWREQ_I2CMRX_BBA (*(volatile unsigned long *) 0x4220029C) +#define DMASWREQ_I2CMRX_MSK (0x1 << 7 ) +#define DMASWREQ_I2CMRX (0x1 << 7 ) +#define DMASWREQ_I2CMRX_DIS (0x0 << 7 ) /* DIS. Does not create a DMA request for I2CMRX. */ +#define DMASWREQ_I2CMRX_EN (0x1 << 7 ) /* EN. Generates a DMA request for I2CMRX. */ + +/* DMASWREQ[I2CMTX] - DMA I2C Master TX. */ +#define DMASWREQ_I2CMTX_BBA (*(volatile unsigned long *) 0x42200298) +#define DMASWREQ_I2CMTX_MSK (0x1 << 6 ) +#define DMASWREQ_I2CMTX (0x1 << 6 ) +#define DMASWREQ_I2CMTX_DIS (0x0 << 6 ) /* DIS. Does not create a DMA request for I2CMTX. */ +#define DMASWREQ_I2CMTX_EN (0x1 << 6 ) /* EN. Generates a DMA request for I2CMTX. */ + +/* DMASWREQ[I2CSRX] - DMA I2C Slave RX. */ +#define DMASWREQ_I2CSRX_BBA (*(volatile unsigned long *) 0x42200294) +#define DMASWREQ_I2CSRX_MSK (0x1 << 5 ) +#define DMASWREQ_I2CSRX (0x1 << 5 ) +#define DMASWREQ_I2CSRX_DIS (0x0 << 5 ) /* DIS. Does not create a DMA request for I2CSRX. */ +#define DMASWREQ_I2CSRX_EN (0x1 << 5 ) /* EN. Generates a DMA request for I2CSRX. */ + +/* DMASWREQ[I2CSTX] - DMA I2C Slave TX. */ +#define DMASWREQ_I2CSTX_BBA (*(volatile unsigned long *) 0x42200290) +#define DMASWREQ_I2CSTX_MSK (0x1 << 4 ) +#define DMASWREQ_I2CSTX (0x1 << 4 ) +#define DMASWREQ_I2CSTX_DIS (0x0 << 4 ) /* DIS. Does not create a DMA request for I2CSTX. */ +#define DMASWREQ_I2CSTX_EN (0x1 << 4 ) /* EN. Generates a DMA request for I2CSTX. */ + +/* DMASWREQ[UARTRX] - DMA UART RX. */ +#define DMASWREQ_UARTRX_BBA (*(volatile unsigned long *) 0x4220028C) +#define DMASWREQ_UARTRX_MSK (0x1 << 3 ) +#define DMASWREQ_UARTRX (0x1 << 3 ) +#define DMASWREQ_UARTRX_DIS (0x0 << 3 ) /* DIS. Does not create a DMA request for UARTRX. */ +#define DMASWREQ_UARTRX_EN (0x1 << 3 ) /* EN. Generates a DMA request for UARTRX. */ + +/* DMASWREQ[UARTTX] - DMA UART TX. */ +#define DMASWREQ_UARTTX_BBA (*(volatile unsigned long *) 0x42200288) +#define DMASWREQ_UARTTX_MSK (0x1 << 2 ) +#define DMASWREQ_UARTTX (0x1 << 2 ) +#define DMASWREQ_UARTTX_DIS (0x0 << 2 ) /* DIS. Does not create a DMA request for UARTTX. */ +#define DMASWREQ_UARTTX_EN (0x1 << 2 ) /* EN. Generates a DMA request for UARTTX. */ + +/* DMASWREQ[SPI1RX] - DMA SPI 1 RX. */ +#define DMASWREQ_SPI1RX_BBA (*(volatile unsigned long *) 0x42200284) +#define DMASWREQ_SPI1RX_MSK (0x1 << 1 ) +#define DMASWREQ_SPI1RX (0x1 << 1 ) +#define DMASWREQ_SPI1RX_DIS (0x0 << 1 ) /* DIS. Does not create a DMA request for SPI1RX. */ +#define DMASWREQ_SPI1RX_EN (0x1 << 1 ) /* EN. Generates a DMA request for SPI1RX. */ + +/* DMASWREQ[SPI1TX] - DMA SPI 1 TX. */ +#define DMASWREQ_SPI1TX_BBA (*(volatile unsigned long *) 0x42200280) +#define DMASWREQ_SPI1TX_MSK (0x1 << 0 ) +#define DMASWREQ_SPI1TX (0x1 << 0 ) +#define DMASWREQ_SPI1TX_DIS (0x0 << 0 ) /* DIS. Does not create a DMA request for SPI1TX. */ +#define DMASWREQ_SPI1TX_EN (0x1 << 0 ) /* EN. Generates a DMA request for SPI1TX. */ + +/* Reset Value for DMARMSKSET*/ +#define DMARMSKSET_RVAL 0x0 + +/* DMARMSKSET[SPI0RX] - DMA SPI0 RX. */ +#define DMARMSKSET_SPI0RX_BBA (*(volatile unsigned long *) 0x42200434) +#define DMARMSKSET_SPI0RX_MSK (0x1 << 13 ) +#define DMARMSKSET_SPI0RX (0x1 << 13 ) +#define DMARMSKSET_SPI0RX_DIS (0x0 << 13 ) /* DIS. When read: Requests are enabled for SPI0RX. When written: No effect. Use the DMARMSKCLR register to enable DMA requests. */ +#define DMARMSKSET_SPI0RX_EN (0x1 << 13 ) /* EN. When read: Requests are disabled for SPI0RX. When written: Disables peripheral associated with SPI0RX from generating DMA requests. */ + +/* DMARMSKSET[SPI0TX] - DMA SPI0 TX. */ +#define DMARMSKSET_SPI0TX_BBA (*(volatile unsigned long *) 0x42200430) +#define DMARMSKSET_SPI0TX_MSK (0x1 << 12 ) +#define DMARMSKSET_SPI0TX (0x1 << 12 ) +#define DMARMSKSET_SPI0TX_DIS (0x0 << 12 ) /* DIS. When read: Requests are enabled for SPI0TX. When written: No effect. Use the DMARMSKCLR register to enable DMA requests. */ +#define DMARMSKSET_SPI0TX_EN (0x1 << 12 ) /* EN. When read: Requests are disabled for SPI0TX. When written: Disables peripheral associated with SPI0TX from generating DMA requests. */ + +/* DMARMSKSET[ADC] - DMA ADC. */ +#define DMARMSKSET_ADC_BBA (*(volatile unsigned long *) 0x4220042C) +#define DMARMSKSET_ADC_MSK (0x1 << 11 ) +#define DMARMSKSET_ADC (0x1 << 11 ) +#define DMARMSKSET_ADC_DIS (0x0 << 11 ) /* DIS. When read: Requests are enabled for ADC. When written: No effect. Use the DMARMSKCLR register to enable DMA requests. */ +#define DMARMSKSET_ADC_EN (0x1 << 11 ) /* EN. When read: Requests are disabled for ADC. When written: Disables peripheral associated with ADC from generating DMA requests. */ + +/* DMARMSKSET[I2CMRX] - DMA I2C Master RX. */ +#define DMARMSKSET_I2CMRX_BBA (*(volatile unsigned long *) 0x4220041C) +#define DMARMSKSET_I2CMRX_MSK (0x1 << 7 ) +#define DMARMSKSET_I2CMRX (0x1 << 7 ) +#define DMARMSKSET_I2CMRX_DIS (0x0 << 7 ) /* DIS. When read: Requests are enabled for I2CMRX. When written: No effect. Use the DMARMSKCLR register to enable DMA requests. */ +#define DMARMSKSET_I2CMRX_EN (0x1 << 7 ) /* EN. When read: Requests are disabled for I2CMRX. When written: Disables peripheral associated with I2CMRX from generating DMA requests. */ + +/* DMARMSKSET[I2CMTX] - DMA I2C Master TX. */ +#define DMARMSKSET_I2CMTX_BBA (*(volatile unsigned long *) 0x42200418) +#define DMARMSKSET_I2CMTX_MSK (0x1 << 6 ) +#define DMARMSKSET_I2CMTX (0x1 << 6 ) +#define DMARMSKSET_I2CMTX_DIS (0x0 << 6 ) /* DIS. When read: Requests are enabled for I2CMTX. When written: No effect. Use the DMARMSKCLR register to enable DMA requests. */ +#define DMARMSKSET_I2CMTX_EN (0x1 << 6 ) /* EN. When read: Requests are disabled for I2CMTX. When written: Disables peripheral associated with I2CMTX from generating DMA requests. */ + +/* DMARMSKSET[I2CSRX] - DMA I2C Slave RX. */ +#define DMARMSKSET_I2CSRX_BBA (*(volatile unsigned long *) 0x42200414) +#define DMARMSKSET_I2CSRX_MSK (0x1 << 5 ) +#define DMARMSKSET_I2CSRX (0x1 << 5 ) +#define DMARMSKSET_I2CSRX_DIS (0x0 << 5 ) /* DIS. When read: Requests are enabled for I2CSRX. When written: No effect. Use the DMARMSKCLR register to enable DMA requests. */ +#define DMARMSKSET_I2CSRX_EN (0x1 << 5 ) /* EN. When read: Requests are disabled for I2CSRX. When written: Disables peripheral associated with I2CSRX from generating DMA requests. */ + +/* DMARMSKSET[I2CSTX] - DMA I2C Slave TX. */ +#define DMARMSKSET_I2CSTX_BBA (*(volatile unsigned long *) 0x42200410) +#define DMARMSKSET_I2CSTX_MSK (0x1 << 4 ) +#define DMARMSKSET_I2CSTX (0x1 << 4 ) +#define DMARMSKSET_I2CSTX_DIS (0x0 << 4 ) /* DIS. When read: Requests are enabled forI2CSTX. When written: No effect. Use the DMARMSKCLR register to enable DMA requests. */ +#define DMARMSKSET_I2CSTX_EN (0x1 << 4 ) /* EN. When read: Requests are disabled for I2CSTX. When written: Disables peripheral associated with I2CSTX from generating DMA requests. */ + +/* DMARMSKSET[UARTRX] - DMA UART RX. */ +#define DMARMSKSET_UARTRX_BBA (*(volatile unsigned long *) 0x4220040C) +#define DMARMSKSET_UARTRX_MSK (0x1 << 3 ) +#define DMARMSKSET_UARTRX (0x1 << 3 ) +#define DMARMSKSET_UARTRX_DIS (0x0 << 3 ) /* DIS. When read: Requests are enabled for UARTRX. When written: No effect. Use the DMARMSKCLR register to enable DMA requests. */ +#define DMARMSKSET_UARTRX_EN (0x1 << 3 ) /* EN. When read: Requests are disabled for UARTRX. When written: Disables peripheral associated with UARTRX from generating DMA requests. */ + +/* DMARMSKSET[UARTTX] - DMA UART TX. */ +#define DMARMSKSET_UARTTX_BBA (*(volatile unsigned long *) 0x42200408) +#define DMARMSKSET_UARTTX_MSK (0x1 << 2 ) +#define DMARMSKSET_UARTTX (0x1 << 2 ) +#define DMARMSKSET_UARTTX_DIS (0x0 << 2 ) /* DIS. When read: Requests are enabled for UARTTX. When written: No effect. Use the DMARMSKCLR register to enable DMA requests. */ +#define DMARMSKSET_UARTTX_EN (0x1 << 2 ) /* EN. When read: Requests are disabled for UARTTX. When written: Disables peripheral associated with UARTTX from generating DMA requests. */ + +/* DMARMSKSET[SPI1RX] - DMA SPI 1 RX. */ +#define DMARMSKSET_SPI1RX_BBA (*(volatile unsigned long *) 0x42200404) +#define DMARMSKSET_SPI1RX_MSK (0x1 << 1 ) +#define DMARMSKSET_SPI1RX (0x1 << 1 ) +#define DMARMSKSET_SPI1RX_DIS (0x0 << 1 ) /* DIS. When read: Requests are enabled for SPI1RX. When written: No effect. Use the DMARMSKCLR register to enable DMA requests. */ +#define DMARMSKSET_SPI1RX_EN (0x1 << 1 ) /* EN. When read: Requests are disabled for SPI1RX. When written: Disables peripheral associated with SPI1RX from generating DMA requests. */ + +/* DMARMSKSET[SPI1TX] - DMA SPI 1 TX. */ +#define DMARMSKSET_SPI1TX_BBA (*(volatile unsigned long *) 0x42200400) +#define DMARMSKSET_SPI1TX_MSK (0x1 << 0 ) +#define DMARMSKSET_SPI1TX (0x1 << 0 ) +#define DMARMSKSET_SPI1TX_DIS (0x0 << 0 ) /* DIS. When read: Requests are enabled for SPI1TX. When written: No effect. Use the DMARMSKCLR register to enable DMA requests. */ +#define DMARMSKSET_SPI1TX_EN (0x1 << 0 ) /* EN. When read: Requests are disabled for SPI1TX When written: Disables peripheral associated with SPI1TX from generating DMA requests. */ + +/* Reset Value for DMARMSKCLR*/ +#define DMARMSKCLR_RVAL 0x0 + +/* DMARMSKCLR[SPI0RX] - DMA SPI0 RX. */ +#define DMARMSKCLR_SPI0RX_BBA (*(volatile unsigned long *) 0x422004B4) +#define DMARMSKCLR_SPI0RX_MSK (0x1 << 13 ) +#define DMARMSKCLR_SPI0RX (0x1 << 13 ) +#define DMARMSKCLR_SPI0RX_DIS (0x0 << 13 ) /* DIS. No effect. Use the DMARMSKSET register to disable DMA requests. */ +#define DMARMSKCLR_SPI0RX_EN (0x1 << 13 ) /* EN. Enables peripheral associated with SPI0RX to generate DMA requests. */ + +/* DMARMSKCLR[SPI0TX] - DMA SPI0 TX. */ +#define DMARMSKCLR_SPI0TX_BBA (*(volatile unsigned long *) 0x422004B0) +#define DMARMSKCLR_SPI0TX_MSK (0x1 << 12 ) +#define DMARMSKCLR_SPI0TX (0x1 << 12 ) +#define DMARMSKCLR_SPI0TX_DIS (0x0 << 12 ) /* DIS. No effect. Use the DMARMSKSET register to disable DMA requests. */ +#define DMARMSKCLR_SPI0TX_EN (0x1 << 12 ) /* EN. Enables peripheral associated with SPI0TX to generate DMA requests. */ + +/* DMARMSKCLR[ADC] - DMA ADC. */ +#define DMARMSKCLR_ADC_BBA (*(volatile unsigned long *) 0x422004AC) +#define DMARMSKCLR_ADC_MSK (0x1 << 11 ) +#define DMARMSKCLR_ADC (0x1 << 11 ) +#define DMARMSKCLR_ADC_DIS (0x0 << 11 ) /* DIS. No effect. Use the DMARMSKSET register to disable DMA requests. */ +#define DMARMSKCLR_ADC_EN (0x1 << 11 ) /* EN. Enables peripheral associated with ADC to generate DMA requests. */ + +/* DMARMSKCLR[I2CMRX] - DMA I2C Master RX. */ +#define DMARMSKCLR_I2CMRX_BBA (*(volatile unsigned long *) 0x4220049C) +#define DMARMSKCLR_I2CMRX_MSK (0x1 << 7 ) +#define DMARMSKCLR_I2CMRX (0x1 << 7 ) +#define DMARMSKCLR_I2CMRX_DIS (0x0 << 7 ) /* DIS. No effect. Use the DMARMSKSET register to disable DMA requests. */ +#define DMARMSKCLR_I2CMRX_EN (0x1 << 7 ) /* EN. Enables peripheral associated with I2CMRX to generate DMA requests. */ + +/* DMARMSKCLR[I2CMTX] - DMA I2C Master TX. */ +#define DMARMSKCLR_I2CMTX_BBA (*(volatile unsigned long *) 0x42200498) +#define DMARMSKCLR_I2CMTX_MSK (0x1 << 6 ) +#define DMARMSKCLR_I2CMTX (0x1 << 6 ) +#define DMARMSKCLR_I2CMTX_DIS (0x0 << 6 ) /* DIS. No effect. Use the DMARMSKSET register to disable DMA requests. */ +#define DMARMSKCLR_I2CMTX_EN (0x1 << 6 ) /* EN. Enables peripheral associated with I2CMTX to generate DMA requests. */ + +/* DMARMSKCLR[I2CSRX] - DMA I2C Slave RX. */ +#define DMARMSKCLR_I2CSRX_BBA (*(volatile unsigned long *) 0x42200494) +#define DMARMSKCLR_I2CSRX_MSK (0x1 << 5 ) +#define DMARMSKCLR_I2CSRX (0x1 << 5 ) +#define DMARMSKCLR_I2CSRX_DIS (0x0 << 5 ) /* DIS. No effect. Use the DMARMSKSET register to disable DMA requests. */ +#define DMARMSKCLR_I2CSRX_EN (0x1 << 5 ) /* EN. Enables peripheral associated with I2CSRX to generate DMA requests. */ + +/* DMARMSKCLR[I2CSTX] - DMA I2C Slave TX. */ +#define DMARMSKCLR_I2CSTX_BBA (*(volatile unsigned long *) 0x42200490) +#define DMARMSKCLR_I2CSTX_MSK (0x1 << 4 ) +#define DMARMSKCLR_I2CSTX (0x1 << 4 ) +#define DMARMSKCLR_I2CSTX_DIS (0x0 << 4 ) /* DIS. No effect. Use the DMARMSKSET register to disable DMA requests. */ +#define DMARMSKCLR_I2CSTX_EN (0x1 << 4 ) /* EN. Enables peripheral associated with I2CSTX to generate DMA requests. */ + +/* DMARMSKCLR[UARTRX] - DMA UART RX. */ +#define DMARMSKCLR_UARTRX_BBA (*(volatile unsigned long *) 0x4220048C) +#define DMARMSKCLR_UARTRX_MSK (0x1 << 3 ) +#define DMARMSKCLR_UARTRX (0x1 << 3 ) +#define DMARMSKCLR_UARTRX_DIS (0x0 << 3 ) /* DIS. No effect. Use the DMARMSKSET register to disable DMA requests. */ +#define DMARMSKCLR_UARTRX_EN (0x1 << 3 ) /* EN. Enables peripheral associated with UARTRX to generate DMA requests. */ + +/* DMARMSKCLR[UARTTX] - DMA UART TX. */ +#define DMARMSKCLR_UARTTX_BBA (*(volatile unsigned long *) 0x42200488) +#define DMARMSKCLR_UARTTX_MSK (0x1 << 2 ) +#define DMARMSKCLR_UARTTX (0x1 << 2 ) +#define DMARMSKCLR_UARTTX_DIS (0x0 << 2 ) /* DIS. No effect. Use the DMARMSKSET register to disable DMA requests. */ +#define DMARMSKCLR_UARTTX_EN (0x1 << 2 ) /* EN. Enables peripheral associated with UARTTX to generate DMA requests. */ + +/* DMARMSKCLR[SPI1RX] - DMA SPI 1 RX. */ +#define DMARMSKCLR_SPI1RX_BBA (*(volatile unsigned long *) 0x42200484) +#define DMARMSKCLR_SPI1RX_MSK (0x1 << 1 ) +#define DMARMSKCLR_SPI1RX (0x1 << 1 ) +#define DMARMSKCLR_SPI1RX_DIS (0x0 << 1 ) /* DIS. No effect. Use the DMARMSKSET register to disable DMA requests. */ +#define DMARMSKCLR_SPI1RX_EN (0x1 << 1 ) /* EN. Enables peripheral associated with SPI1RX to generate DMA requests. */ + +/* DMARMSKCLR[SPI1TX] - DMA SPI 1 TX. */ +#define DMARMSKCLR_SPI1TX_BBA (*(volatile unsigned long *) 0x42200480) +#define DMARMSKCLR_SPI1TX_MSK (0x1 << 0 ) +#define DMARMSKCLR_SPI1TX (0x1 << 0 ) +#define DMARMSKCLR_SPI1TX_DIS (0x0 << 0 ) /* DIS. No effect. Use the DMARMSKSET register to disable DMA requests. */ +#define DMARMSKCLR_SPI1TX_EN (0x1 << 0 ) /* EN. Enables peripheral associated with SPI1TX to generate DMA requests. */ + +/* Reset Value for DMAENSET*/ +#define DMAENSET_RVAL 0x0 + +/* DMAENSET[SPI0RX] - DMA SPI0 RX */ +#define DMAENSET_SPI0RX_BBA (*(volatile unsigned long *) 0x42200534) +#define DMAENSET_SPI0RX_MSK (0x1 << 13 ) +#define DMAENSET_SPI0RX (0x1 << 13 ) +#define DMAENSET_SPI0RX_DIS (0x0 << 13 ) /* DIS. No effect. Use the DMAENCLR register to disable the channel. */ +#define DMAENSET_SPI0RX_EN (0x1 << 13 ) /* EN. Enables SPI0RX. */ + +/* DMAENSET[SPI0TX] - DMA SPI0 TX. */ +#define DMAENSET_SPI0TX_BBA (*(volatile unsigned long *) 0x42200530) +#define DMAENSET_SPI0TX_MSK (0x1 << 12 ) +#define DMAENSET_SPI0TX (0x1 << 12 ) +#define DMAENSET_SPI0TX_DIS (0x0 << 12 ) /* DIS. No effect. Use the DMAENCLR register to disable the channel. */ +#define DMAENSET_SPI0TX_EN (0x1 << 12 ) /* EN. Enables SPI0TX. */ + +/* DMAENSET[ADC] - DMA ADC. */ +#define DMAENSET_ADC_BBA (*(volatile unsigned long *) 0x4220052C) +#define DMAENSET_ADC_MSK (0x1 << 11 ) +#define DMAENSET_ADC (0x1 << 11 ) +#define DMAENSET_ADC_DIS (0x0 << 11 ) /* DIS. No effect. Use the DMAENCLR register to disable the channel. */ +#define DMAENSET_ADC_EN (0x1 << 11 ) /* EN. Enables ADC. */ + +/* DMAENSET[I2CMRX] - DMA I2C Master RX. */ +#define DMAENSET_I2CMRX_BBA (*(volatile unsigned long *) 0x4220051C) +#define DMAENSET_I2CMRX_MSK (0x1 << 7 ) +#define DMAENSET_I2CMRX (0x1 << 7 ) +#define DMAENSET_I2CMRX_DIS (0x0 << 7 ) /* DIS. No effect. Use the DMAENCLR register to disable the channel. */ +#define DMAENSET_I2CMRX_EN (0x1 << 7 ) /* EN. . Enables I2CMRX. */ + +/* DMAENSET[I2CMTX] - DMA I2C Master TX. */ +#define DMAENSET_I2CMTX_BBA (*(volatile unsigned long *) 0x42200518) +#define DMAENSET_I2CMTX_MSK (0x1 << 6 ) +#define DMAENSET_I2CMTX (0x1 << 6 ) +#define DMAENSET_I2CMTX_DIS (0x0 << 6 ) /* DIS. No effect. Use the DMAENCLR register to disable the channel. */ +#define DMAENSET_I2CMTX_EN (0x1 << 6 ) /* EN. . Enables I2CMTX. */ + +/* DMAENSET[I2CSRX] - DMA I2C Slave RX. */ +#define DMAENSET_I2CSRX_BBA (*(volatile unsigned long *) 0x42200514) +#define DMAENSET_I2CSRX_MSK (0x1 << 5 ) +#define DMAENSET_I2CSRX (0x1 << 5 ) +#define DMAENSET_I2CSRX_DIS (0x0 << 5 ) /* DIS. No effect. Use the DMAENCLR register to disable the channel. */ +#define DMAENSET_I2CSRX_EN (0x1 << 5 ) /* EN. Enables I2CSRX. */ + +/* DMAENSET[I2CSTX] - DMA I2C Slave TX. */ +#define DMAENSET_I2CSTX_BBA (*(volatile unsigned long *) 0x42200510) +#define DMAENSET_I2CSTX_MSK (0x1 << 4 ) +#define DMAENSET_I2CSTX (0x1 << 4 ) +#define DMAENSET_I2CSTX_DIS (0x0 << 4 ) /* DIS. No effect. Use the DMAENCLR register to disable the channel. */ +#define DMAENSET_I2CSTX_EN (0x1 << 4 ) /* EN. Enables I2CSTX. */ + +/* DMAENSET[UARTRX] - DMA UART RX. */ +#define DMAENSET_UARTRX_BBA (*(volatile unsigned long *) 0x4220050C) +#define DMAENSET_UARTRX_MSK (0x1 << 3 ) +#define DMAENSET_UARTRX (0x1 << 3 ) +#define DMAENSET_UARTRX_DIS (0x0 << 3 ) /* DIS. No effect. Use the DMAENCLR register to disable the channel. */ +#define DMAENSET_UARTRX_EN (0x1 << 3 ) /* EN. Enables UARTRX. */ + +/* DMAENSET[UARTTX] - DMA UART TX. */ +#define DMAENSET_UARTTX_BBA (*(volatile unsigned long *) 0x42200508) +#define DMAENSET_UARTTX_MSK (0x1 << 2 ) +#define DMAENSET_UARTTX (0x1 << 2 ) +#define DMAENSET_UARTTX_DIS (0x0 << 2 ) /* DIS. No effect. Use the DMAENCLR register to disable the channel. */ +#define DMAENSET_UARTTX_EN (0x1 << 2 ) /* EN. Enables UARTTX. */ + +/* DMAENSET[SPI1RX] - DMA SPI 1 RX. */ +#define DMAENSET_SPI1RX_BBA (*(volatile unsigned long *) 0x42200504) +#define DMAENSET_SPI1RX_MSK (0x1 << 1 ) +#define DMAENSET_SPI1RX (0x1 << 1 ) +#define DMAENSET_SPI1RX_DIS (0x0 << 1 ) /* DIS. No effect. Use the DMAENCLR register to disable the channel. */ +#define DMAENSET_SPI1RX_EN (0x1 << 1 ) /* EN. Enables SPI1RX. */ + +/* DMAENSET[SPI1TX] - DMA SPI 1 TX. */ +#define DMAENSET_SPI1TX_BBA (*(volatile unsigned long *) 0x42200500) +#define DMAENSET_SPI1TX_MSK (0x1 << 0 ) +#define DMAENSET_SPI1TX (0x1 << 0 ) +#define DMAENSET_SPI1TX_DIS (0x0 << 0 ) /* DIS. No effect. Use the DMAENCLR register to disable the channel. */ +#define DMAENSET_SPI1TX_EN (0x1 << 0 ) /* EN. Enables SPI1TX. */ + +/* Reset Value for DMAENCLR*/ +#define DMAENCLR_RVAL 0x0 + +/* DMAENCLR[SPI0RX] - DMA SPI0 RX */ +#define DMAENCLR_SPI0RX_BBA (*(volatile unsigned long *) 0x422005B4) +#define DMAENCLR_SPI0RX_MSK (0x1 << 13 ) +#define DMAENCLR_SPI0RX (0x1 << 13 ) +#define DMAENCLR_SPI0RX_DIS (0x0 << 13 ) /* DIS. No effect. Use the DMAENSET register to enable the channel. */ +#define DMAENCLR_SPI0RX_EN (0x1 << 13 ) /* EN. Disables SPI0RX. */ + +/* DMAENCLR[SPI0TX] - DMA SPI0 TX */ +#define DMAENCLR_SPI0TX_BBA (*(volatile unsigned long *) 0x422005B0) +#define DMAENCLR_SPI0TX_MSK (0x1 << 12 ) +#define DMAENCLR_SPI0TX (0x1 << 12 ) +#define DMAENCLR_SPI0TX_DIS (0x0 << 12 ) /* DIS. No effect. Use the DMAENSET register to enable the channel. */ +#define DMAENCLR_SPI0TX_EN (0x1 << 12 ) /* EN. Disables SPI0TX. */ + +/* DMAENCLR[ADC] - DMA ADC. */ +#define DMAENCLR_ADC_BBA (*(volatile unsigned long *) 0x422005AC) +#define DMAENCLR_ADC_MSK (0x1 << 11 ) +#define DMAENCLR_ADC (0x1 << 11 ) +#define DMAENCLR_ADC_DIS (0x0 << 11 ) /* DIS. No effect. Use the DMAENSET register to enable the channel. */ +#define DMAENCLR_ADC_EN (0x1 << 11 ) /* EN. Disables ADC. */ + +/* DMAENCLR[I2CMRX] - DMA I2C Master RX. */ +#define DMAENCLR_I2CMRX_BBA (*(volatile unsigned long *) 0x4220059C) +#define DMAENCLR_I2CMRX_MSK (0x1 << 7 ) +#define DMAENCLR_I2CMRX (0x1 << 7 ) +#define DMAENCLR_I2CMRX_DIS (0x0 << 7 ) /* DIS. No effect. Use the DMAENSET register to enable the channel. */ +#define DMAENCLR_I2CMRX_EN (0x1 << 7 ) /* EN. Disables I2CMRX. */ + +/* DMAENCLR[I2CMTX] - DMA I2C Master TX. */ +#define DMAENCLR_I2CMTX_BBA (*(volatile unsigned long *) 0x42200598) +#define DMAENCLR_I2CMTX_MSK (0x1 << 6 ) +#define DMAENCLR_I2CMTX (0x1 << 6 ) +#define DMAENCLR_I2CMTX_DIS (0x0 << 6 ) /* DIS. No effect. Use the DMAENSET register to enable the channel. */ +#define DMAENCLR_I2CMTX_EN (0x1 << 6 ) /* EN. Disables I2CMTX. */ + +/* DMAENCLR[I2CSRX] - DMA I2C Slave RX. */ +#define DMAENCLR_I2CSRX_BBA (*(volatile unsigned long *) 0x42200594) +#define DMAENCLR_I2CSRX_MSK (0x1 << 5 ) +#define DMAENCLR_I2CSRX (0x1 << 5 ) +#define DMAENCLR_I2CSRX_DIS (0x0 << 5 ) /* DIS. No effect. Use the DMAENSET register to enable the channel. */ +#define DMAENCLR_I2CSRX_EN (0x1 << 5 ) /* EN. Disables I2CSRX. */ + +/* DMAENCLR[I2CSTX] - DMA I2C Slave TX. */ +#define DMAENCLR_I2CSTX_BBA (*(volatile unsigned long *) 0x42200590) +#define DMAENCLR_I2CSTX_MSK (0x1 << 4 ) +#define DMAENCLR_I2CSTX (0x1 << 4 ) +#define DMAENCLR_I2CSTX_DIS (0x0 << 4 ) /* DIS. No effect. Use the DMAENSET register to enable the channel. */ +#define DMAENCLR_I2CSTX_EN (0x1 << 4 ) /* EN. Disables I2CSTX. */ + +/* DMAENCLR[UARTRX] - DMA UART RX. */ +#define DMAENCLR_UARTRX_BBA (*(volatile unsigned long *) 0x4220058C) +#define DMAENCLR_UARTRX_MSK (0x1 << 3 ) +#define DMAENCLR_UARTRX (0x1 << 3 ) +#define DMAENCLR_UARTRX_DIS (0x0 << 3 ) /* DIS. No effect. Use the DMAENSET register to enable the channel. */ +#define DMAENCLR_UARTRX_EN (0x1 << 3 ) /* EN. Disables UARTRX. */ + +/* DMAENCLR[UARTTX] - DMA UART TX. */ +#define DMAENCLR_UARTTX_BBA (*(volatile unsigned long *) 0x42200588) +#define DMAENCLR_UARTTX_MSK (0x1 << 2 ) +#define DMAENCLR_UARTTX (0x1 << 2 ) +#define DMAENCLR_UARTTX_DIS (0x0 << 2 ) /* DIS. No effect. Use the DMAENSET register to enable the channel. */ +#define DMAENCLR_UARTTX_EN (0x1 << 2 ) /* EN. Disables UARTTX. */ + +/* DMAENCLR[SPI1RX] - DMA SPI 1 RX. */ +#define DMAENCLR_SPI1RX_BBA (*(volatile unsigned long *) 0x42200584) +#define DMAENCLR_SPI1RX_MSK (0x1 << 1 ) +#define DMAENCLR_SPI1RX (0x1 << 1 ) +#define DMAENCLR_SPI1RX_DIS (0x0 << 1 ) /* DIS. No effect. Use the DMAENSET register to enable the channel. */ +#define DMAENCLR_SPI1RX_EN (0x1 << 1 ) /* EN. Disables SPI1RX. */ + +/* DMAENCLR[SPI1TX] - DMA SPI 1 TX. */ +#define DMAENCLR_SPI1TX_BBA (*(volatile unsigned long *) 0x42200580) +#define DMAENCLR_SPI1TX_MSK (0x1 << 0 ) +#define DMAENCLR_SPI1TX (0x1 << 0 ) +#define DMAENCLR_SPI1TX_DIS (0x0 << 0 ) /* DIS. No effect. Use the DMAENSET register to enable the channel. */ +#define DMAENCLR_SPI1TX_EN (0x1 << 0 ) /* EN. Disables SPI1TX. */ + +/* Reset Value for DMAALTSET*/ +#define DMAALTSET_RVAL 0x0 + +/* DMAALTSET[SPI0RX] - DMA SPI0 RX. */ +#define DMAALTSET_SPI0RX_BBA (*(volatile unsigned long *) 0x42200634) +#define DMAALTSET_SPI0RX_MSK (0x1 << 13 ) +#define DMAALTSET_SPI0RX (0x1 << 13 ) +#define DMAALTSET_SPI0RX_DIS (0x0 << 13 ) /* DIS. When read: DMA SPI0RX is using the primary data structure. When written: No effect. Use the DMAALTCLR register to set SPI0RX to 0. */ +#define DMAALTSET_SPI0RX_EN (0x1 << 13 ) /* EN. When read: DMA SPI0RX is using the alternate data structure. When written: Selects the alternate data structure for SPI0RX. */ + +/* DMAALTSET[SPI0TX] - DMA SPI0 TX. */ +#define DMAALTSET_SPI0TX_BBA (*(volatile unsigned long *) 0x42200630) +#define DMAALTSET_SPI0TX_MSK (0x1 << 12 ) +#define DMAALTSET_SPI0TX (0x1 << 12 ) +#define DMAALTSET_SPI0TX_DIS (0x0 << 12 ) /* DIS. When read: DMA SPI0TX is using the primary data structure. When written: No effect. Use the DMAALTCLR register to set SPI0TX to 0. */ +#define DMAALTSET_SPI0TX_EN (0x1 << 12 ) /* EN. When read: DMA SPI0TX is using the alternate data structure. When written: Selects the alternate data structure for SPI0TX. */ + +/* DMAALTSET[ADC] - DMA ADC. */ +#define DMAALTSET_ADC_BBA (*(volatile unsigned long *) 0x4220062C) +#define DMAALTSET_ADC_MSK (0x1 << 11 ) +#define DMAALTSET_ADC (0x1 << 11 ) +#define DMAALTSET_ADC_DIS (0x0 << 11 ) /* DIS. When read: DMA ADC is using the primary data structure. When written: No effect. Use the DMAALTCLR register to set ADC to 0. */ +#define DMAALTSET_ADC_EN (0x1 << 11 ) /* EN. When read: DMA ADC is using the alternate data structure. When written: Selects the alternate data structure for ADC. */ + +/* DMAALTSET[I2CMRX] - DMA I2C Master RX. */ +#define DMAALTSET_I2CMRX_BBA (*(volatile unsigned long *) 0x4220061C) +#define DMAALTSET_I2CMRX_MSK (0x1 << 7 ) +#define DMAALTSET_I2CMRX (0x1 << 7 ) +#define DMAALTSET_I2CMRX_DIS (0x0 << 7 ) /* DIS. When read: DMA I2CMRX is using the primary data structure. When written: No effect. Use the DMAALTCLR register to set I2CMRX to 0. */ +#define DMAALTSET_I2CMRX_EN (0x1 << 7 ) /* EN. When read: DMA I2CMRX is using the alternate data structure. When written: Selects the alternate data structure for I2CMRX. */ + +/* DMAALTSET[I2CMTX] - DMA I2C Master TX. */ +#define DMAALTSET_I2CMTX_BBA (*(volatile unsigned long *) 0x42200618) +#define DMAALTSET_I2CMTX_MSK (0x1 << 6 ) +#define DMAALTSET_I2CMTX (0x1 << 6 ) +#define DMAALTSET_I2CMTX_DIS (0x0 << 6 ) /* DIS. When read: DMA I2CMTX is using the primary data structure. When written: No effect. Use the DMAALTCLR register to set I2CMTX to 0. */ +#define DMAALTSET_I2CMTX_EN (0x1 << 6 ) /* EN. When read: DMA I2CMTX is using the alternate data structure. When written: Selects the alternate data structure forI2CMTX. */ + +/* DMAALTSET[I2CSRX] - DMA I2C Slave RX. */ +#define DMAALTSET_I2CSRX_BBA (*(volatile unsigned long *) 0x42200614) +#define DMAALTSET_I2CSRX_MSK (0x1 << 5 ) +#define DMAALTSET_I2CSRX (0x1 << 5 ) +#define DMAALTSET_I2CSRX_DIS (0x0 << 5 ) /* DIS. When read: DMA I2CSRX is using the primary data structure. When written: No effect. Use the DMAALTCLR register to set I2CSRX to 0. */ +#define DMAALTSET_I2CSRX_EN (0x1 << 5 ) /* EN. When read: DMA I2CSRX is using the alternate data structure. When written: Selects the alternate data structure for I2CSRX. */ + +/* DMAALTSET[I2CSTX] - DMA I2C Slave TX. */ +#define DMAALTSET_I2CSTX_BBA (*(volatile unsigned long *) 0x42200610) +#define DMAALTSET_I2CSTX_MSK (0x1 << 4 ) +#define DMAALTSET_I2CSTX (0x1 << 4 ) +#define DMAALTSET_I2CSTX_DIS (0x0 << 4 ) /* DIS. When read: DMA I2CSTX is using the primary data structure. When written: No effect. Use the DMAALTCLR register to set I2CSTX to 0. */ +#define DMAALTSET_I2CSTX_EN (0x1 << 4 ) /* EN. When read: DMA I2CSTX is using the alternate data structure. When written: Selects the alternate data structure for I2CSTX. */ + +/* DMAALTSET[UARTRX] - DMA UART RX. */ +#define DMAALTSET_UARTRX_BBA (*(volatile unsigned long *) 0x4220060C) +#define DMAALTSET_UARTRX_MSK (0x1 << 3 ) +#define DMAALTSET_UARTRX (0x1 << 3 ) +#define DMAALTSET_UARTRX_DIS (0x0 << 3 ) /* DIS. When read: DMA UARTRX is using the primary data structure. When written: No effect. Use the DMAALTCLR register to set UARTRX to 0. */ +#define DMAALTSET_UARTRX_EN (0x1 << 3 ) /* EN. When read: DMA UARTRX is using the alternate data structure. When written: Selects the alternate data structure for UARTRX. */ + +/* DMAALTSET[UARTTX] - DMA UART TX. */ +#define DMAALTSET_UARTTX_BBA (*(volatile unsigned long *) 0x42200608) +#define DMAALTSET_UARTTX_MSK (0x1 << 2 ) +#define DMAALTSET_UARTTX (0x1 << 2 ) +#define DMAALTSET_UARTTX_DIS (0x0 << 2 ) /* DIS. When read: DMA UARTTX is using the primary data structure. When written: No effect. Use the DMAALTCLR register to set UARTTX to 0. */ +#define DMAALTSET_UARTTX_EN (0x1 << 2 ) /* EN. When read: DMA UARTTX is using the alternate data structure. When written: Selects the alternate data structure for UARTTX. */ + +/* DMAALTSET[SPI1RX] - DMA SPI 1 RX. */ +#define DMAALTSET_SPI1RX_BBA (*(volatile unsigned long *) 0x42200604) +#define DMAALTSET_SPI1RX_MSK (0x1 << 1 ) +#define DMAALTSET_SPI1RX (0x1 << 1 ) +#define DMAALTSET_SPI1RX_DIS (0x0 << 1 ) /* DIS. When read: DMA SPI1RX is using the primary data structure. When written: No effect. Use the DMAALTCLR register to set SPI1RX to 0. */ +#define DMAALTSET_SPI1RX_EN (0x1 << 1 ) /* EN. When read: DMA SPI1RX is using the alternate data structure. When written: Selects the alternate data structure for SPI1RX. */ + +/* DMAALTSET[SPI1TX] - DMA SPI 1 TX. */ +#define DMAALTSET_SPI1TX_BBA (*(volatile unsigned long *) 0x42200600) +#define DMAALTSET_SPI1TX_MSK (0x1 << 0 ) +#define DMAALTSET_SPI1TX (0x1 << 0 ) +#define DMAALTSET_SPI1TX_DIS (0x0 << 0 ) /* DIS. When read: DMA SPI1TX is using the primary data structure. When written: No effect. Use the DMAALTCLR register to set SPI1TX to 0. */ +#define DMAALTSET_SPI1TX_EN (0x1 << 0 ) /* EN. When read: DMA SPI1TX is using the alternate data structure. When written: Selects the alternate data structure for SPI1TX. */ + +/* Reset Value for DMAALTCLR*/ +#define DMAALTCLR_RVAL 0x0 + +/* DMAALTCLR[SPI0RX] - DMA SPI0 RX. */ +#define DMAALTCLR_SPI0RX_BBA (*(volatile unsigned long *) 0x422006B4) +#define DMAALTCLR_SPI0RX_MSK (0x1 << 13 ) +#define DMAALTCLR_SPI0RX (0x1 << 13 ) +#define DMAALTCLR_SPI0RX_DIS (0x0 << 13 ) /* DIS. No effect. Use the DMAALTSET register to select the alternate data structure. */ +#define DMAALTCLR_SPI0RX_EN (0x1 << 13 ) /* EN. Selects the primary data structure for SPI0RX. */ + +/* DMAALTCLR[SPI0TX] - DMA SPI0 TX. */ +#define DMAALTCLR_SPI0TX_BBA (*(volatile unsigned long *) 0x422006B0) +#define DMAALTCLR_SPI0TX_MSK (0x1 << 12 ) +#define DMAALTCLR_SPI0TX (0x1 << 12 ) +#define DMAALTCLR_SPI0TX_DIS (0x0 << 12 ) /* DIS. No effect. Use the DMAALTSET register to select the alternate data structure. */ +#define DMAALTCLR_SPI0TX_EN (0x1 << 12 ) /* EN. Selects the primary data structure for SPI0TX. */ + +/* DMAALTCLR[ADC] - DMA ADC. */ +#define DMAALTCLR_ADC_BBA (*(volatile unsigned long *) 0x422006AC) +#define DMAALTCLR_ADC_MSK (0x1 << 11 ) +#define DMAALTCLR_ADC (0x1 << 11 ) +#define DMAALTCLR_ADC_DIS (0x0 << 11 ) /* DIS. No effect. Use the DMAALTSET register to select the alternate data structure. */ +#define DMAALTCLR_ADC_EN (0x1 << 11 ) /* EN. Selects the primary data structure for ADC. */ + +/* DMAALTCLR[I2CMRX] - DMA I2C Master RX. */ +#define DMAALTCLR_I2CMRX_BBA (*(volatile unsigned long *) 0x4220069C) +#define DMAALTCLR_I2CMRX_MSK (0x1 << 7 ) +#define DMAALTCLR_I2CMRX (0x1 << 7 ) +#define DMAALTCLR_I2CMRX_DIS (0x0 << 7 ) /* DIS. No effect. Use the DMAALTSET register to select the alternate data structure. */ +#define DMAALTCLR_I2CMRX_EN (0x1 << 7 ) /* EN. Selects the primary data structure for I2CMRX. */ + +/* DMAALTCLR[I2CMTX] - DMA I2C Master TX. */ +#define DMAALTCLR_I2CMTX_BBA (*(volatile unsigned long *) 0x42200698) +#define DMAALTCLR_I2CMTX_MSK (0x1 << 6 ) +#define DMAALTCLR_I2CMTX (0x1 << 6 ) +#define DMAALTCLR_I2CMTX_DIS (0x0 << 6 ) /* DIS. No effect. Use the DMAALTSET register to select the alternate data structure. */ +#define DMAALTCLR_I2CMTX_EN (0x1 << 6 ) /* EN. Selects the primary data structure for I2CMTX. */ + +/* DMAALTCLR[I2CSRX] - DMA I2C Slave RX. */ +#define DMAALTCLR_I2CSRX_BBA (*(volatile unsigned long *) 0x42200694) +#define DMAALTCLR_I2CSRX_MSK (0x1 << 5 ) +#define DMAALTCLR_I2CSRX (0x1 << 5 ) +#define DMAALTCLR_I2CSRX_DIS (0x0 << 5 ) /* DIS. No effect. Use the DMAALTSET register to select the alternate data structure. */ +#define DMAALTCLR_I2CSRX_EN (0x1 << 5 ) /* EN. Selects the primary data structure for I2CSRX. */ + +/* DMAALTCLR[I2CSTX] - DMA I2C Slave TX. */ +#define DMAALTCLR_I2CSTX_BBA (*(volatile unsigned long *) 0x42200690) +#define DMAALTCLR_I2CSTX_MSK (0x1 << 4 ) +#define DMAALTCLR_I2CSTX (0x1 << 4 ) +#define DMAALTCLR_I2CSTX_DIS (0x0 << 4 ) /* DIS. No effect. Use the DMAALTSET register to select the alternate data structure. */ +#define DMAALTCLR_I2CSTX_EN (0x1 << 4 ) /* EN. Selects the primary data structure for I2CSTX. */ + +/* DMAALTCLR[UARTRX] - DMA UART RX. */ +#define DMAALTCLR_UARTRX_BBA (*(volatile unsigned long *) 0x4220068C) +#define DMAALTCLR_UARTRX_MSK (0x1 << 3 ) +#define DMAALTCLR_UARTRX (0x1 << 3 ) +#define DMAALTCLR_UARTRX_DIS (0x0 << 3 ) /* DIS. No effect. Use the DMAALTSET register to select the alternate data structure. */ +#define DMAALTCLR_UARTRX_EN (0x1 << 3 ) /* EN. Selects the primary data structure for UARTRX. */ + +/* DMAALTCLR[UARTTX] - DMA UART TX. */ +#define DMAALTCLR_UARTTX_BBA (*(volatile unsigned long *) 0x42200688) +#define DMAALTCLR_UARTTX_MSK (0x1 << 2 ) +#define DMAALTCLR_UARTTX (0x1 << 2 ) +#define DMAALTCLR_UARTTX_DIS (0x0 << 2 ) /* DIS. No effect. Use the DMAALTSET register to select the alternate data structure. */ +#define DMAALTCLR_UARTTX_EN (0x1 << 2 ) /* EN. Selects the primary data structure for UARTTX. */ + +/* DMAALTCLR[SPI1RX] - DMA SPI 1 RX. */ +#define DMAALTCLR_SPI1RX_BBA (*(volatile unsigned long *) 0x42200684) +#define DMAALTCLR_SPI1RX_MSK (0x1 << 1 ) +#define DMAALTCLR_SPI1RX (0x1 << 1 ) +#define DMAALTCLR_SPI1RX_DIS (0x0 << 1 ) /* DIS. No effect. Use the DMAALTSET register to select the alternate data structure. */ +#define DMAALTCLR_SPI1RX_EN (0x1 << 1 ) /* EN. Selects the primary data structure for SPI1RX. */ + +/* DMAALTCLR[SPI1TX] - DMA SPI 1 TX. */ +#define DMAALTCLR_SPI1TX_BBA (*(volatile unsigned long *) 0x42200680) +#define DMAALTCLR_SPI1TX_MSK (0x1 << 0 ) +#define DMAALTCLR_SPI1TX (0x1 << 0 ) +#define DMAALTCLR_SPI1TX_DIS (0x0 << 0 ) /* DIS. No effect. Use the DMAALTSET register to select the alternate data structure. */ +#define DMAALTCLR_SPI1TX_EN (0x1 << 0 ) /* EN. Selects the primary data structure for SPI1TX. */ + +/* Reset Value for DMAPRISET*/ +#define DMAPRISET_RVAL 0x0 + +/* DMAPRISET[SPI0RX] - DMA SPI0 RX. */ +#define DMAPRISET_SPI0RX_BBA (*(volatile unsigned long *) 0x42200734) +#define DMAPRISET_SPI0RX_MSK (0x1 << 13 ) +#define DMAPRISET_SPI0RX (0x1 << 13 ) +#define DMAPRISET_SPI0RX_DIS (0x0 << 13 ) /* DIS. When read: DMA SPI0RX is using the default priority level. When written: No effect. Use the DMAPRICLR register to set SPI0RX to the default priority level. */ +#define DMAPRISET_SPI0RX_EN (0x1 << 13 ) /* EN. When read: DMA SPI0RX is using a high priority level. When written: SPI0RX uses the high priority level. */ + +/* DMAPRISET[SPI0TX] - DMA SPI0 TX. */ +#define DMAPRISET_SPI0TX_BBA (*(volatile unsigned long *) 0x42200730) +#define DMAPRISET_SPI0TX_MSK (0x1 << 12 ) +#define DMAPRISET_SPI0TX (0x1 << 12 ) +#define DMAPRISET_SPI0TX_DIS (0x0 << 12 ) /* DIS. When read: DMA SPI0TX is using the default priority level. When written: No effect. Use the DMAPRICLR register to set SPI0TX to the default priority level. */ +#define DMAPRISET_SPI0TX_EN (0x1 << 12 ) /* EN. When read: DMA SPI0TX is using a high priority level. When written: SPI0TX uses the high priority level. */ + +/* DMAPRISET[ADC] - DMA ADC. */ +#define DMAPRISET_ADC_BBA (*(volatile unsigned long *) 0x4220072C) +#define DMAPRISET_ADC_MSK (0x1 << 11 ) +#define DMAPRISET_ADC (0x1 << 11 ) +#define DMAPRISET_ADC_DIS (0x0 << 11 ) /* DIS. When read: DMA ADC is using the default priority level. When written: No effect. Use the DMAPRICLR register to set ADC to the default priority level. */ +#define DMAPRISET_ADC_EN (0x1 << 11 ) /* EN. When read: DMA ADCs using a high priority level. When written: ADC uses the high priority level. */ + +/* DMAPRISET[I2CMRX] - DMA I2C Master RX. */ +#define DMAPRISET_I2CMRX_BBA (*(volatile unsigned long *) 0x4220071C) +#define DMAPRISET_I2CMRX_MSK (0x1 << 7 ) +#define DMAPRISET_I2CMRX (0x1 << 7 ) +#define DMAPRISET_I2CMRX_DIS (0x0 << 7 ) /* DIS. When read: DMA I2CMRX is using the default priority level. When written: No effect. Use the DMAPRICLR register to set I2CMRX to the default priority level. */ +#define DMAPRISET_I2CMRX_EN (0x1 << 7 ) /* EN. When read: DMA I2CMRX is using a high priority level. When written: I2CMRX uses the high priority level. */ + +/* DMAPRISET[I2CMTX] - DMA I2C Master TX. */ +#define DMAPRISET_I2CMTX_BBA (*(volatile unsigned long *) 0x42200718) +#define DMAPRISET_I2CMTX_MSK (0x1 << 6 ) +#define DMAPRISET_I2CMTX (0x1 << 6 ) +#define DMAPRISET_I2CMTX_DIS (0x0 << 6 ) /* DIS. When read: DMA I2CMTX is using the default priority level. When written: No effect. Use the DMAPRICLR register to set I2CMTX to the default priority level. */ +#define DMAPRISET_I2CMTX_EN (0x1 << 6 ) /* EN. When read: DMA I2CMTX is using a high priority level. When written: I2CMTX uses the high priority level. */ + +/* DMAPRISET[I2CSRX] - DMA I2C Slave RX. */ +#define DMAPRISET_I2CSRX_BBA (*(volatile unsigned long *) 0x42200714) +#define DMAPRISET_I2CSRX_MSK (0x1 << 5 ) +#define DMAPRISET_I2CSRX (0x1 << 5 ) +#define DMAPRISET_I2CSRX_DIS (0x0 << 5 ) /* DIS. When read: DMA I2CSRX is using the default priority level. When written: No effect. Use the DMAPRICLR register to set I2CSRX to the default priority level. */ +#define DMAPRISET_I2CSRX_EN (0x1 << 5 ) /* EN. When read: DMA I2CSRX is using a high priority level. When written: I2CSRX uses the high priority level. */ + +/* DMAPRISET[I2CSTX] - DMA I2C Slave TX. */ +#define DMAPRISET_I2CSTX_BBA (*(volatile unsigned long *) 0x42200710) +#define DMAPRISET_I2CSTX_MSK (0x1 << 4 ) +#define DMAPRISET_I2CSTX (0x1 << 4 ) +#define DMAPRISET_I2CSTX_DIS (0x0 << 4 ) /* DIS. When read: DMA I2CSTX is using the default priority level. When written: No effect. Use the DMAPRICLR register to set I2CSTX to the default priority level. */ +#define DMAPRISET_I2CSTX_EN (0x1 << 4 ) /* EN. When read: DMA I2CSTX is using a high priority level. When written: I2CSTX uses the high priority level. */ + +/* DMAPRISET[UARTRX] - DMA UART RX. */ +#define DMAPRISET_UARTRX_BBA (*(volatile unsigned long *) 0x4220070C) +#define DMAPRISET_UARTRX_MSK (0x1 << 3 ) +#define DMAPRISET_UARTRX (0x1 << 3 ) +#define DMAPRISET_UARTRX_DIS (0x0 << 3 ) /* DIS. When read: DMA UARTRX is using the default priority level. When written: No effect. Use the DMAPRICLR register to set UARTRX to the default priority level. */ +#define DMAPRISET_UARTRX_EN (0x1 << 3 ) /* EN. When read: DMA UARTRX is using a high priority level. When written: UARTRX uses the high priority level. */ + +/* DMAPRISET[UARTTX] - DMA UART TX. */ +#define DMAPRISET_UARTTX_BBA (*(volatile unsigned long *) 0x42200708) +#define DMAPRISET_UARTTX_MSK (0x1 << 2 ) +#define DMAPRISET_UARTTX (0x1 << 2 ) +#define DMAPRISET_UARTTX_DIS (0x0 << 2 ) /* DIS. When read: DMA UARTTX is using the default priority level. When written: No effect. Use the DMAPRICLR register to set UARTTX to the default priority level. */ +#define DMAPRISET_UARTTX_EN (0x1 << 2 ) /* EN. When read: DMA UARTTX is using a high priority level. When written: UARTTX uses the high priority level. */ + +/* DMAPRISET[SPI1RX] - DMA SPI 1 RX. */ +#define DMAPRISET_SPI1RX_BBA (*(volatile unsigned long *) 0x42200704) +#define DMAPRISET_SPI1RX_MSK (0x1 << 1 ) +#define DMAPRISET_SPI1RX (0x1 << 1 ) +#define DMAPRISET_SPI1RX_DIS (0x0 << 1 ) /* DIS. When read: DMA SPI1RX is using the default priority level. When written: No effect. Use the DMAPRICLR register to set SPI1RX to the default priority level. */ +#define DMAPRISET_SPI1RX_EN (0x1 << 1 ) /* EN. When read: DMA SPI1RX is using a high priority level. When written: SPI1RX uses the high priority level. */ + +/* DMAPRISET[SPI1TX] - DMA SPI 1 TX. */ +#define DMAPRISET_SPI1TX_BBA (*(volatile unsigned long *) 0x42200700) +#define DMAPRISET_SPI1TX_MSK (0x1 << 0 ) +#define DMAPRISET_SPI1TX (0x1 << 0 ) +#define DMAPRISET_SPI1TX_DIS (0x0 << 0 ) /* DIS. When read: DMA SPI1TX is using the default priority level. When written: No effect. Use the DMAPRICLR register to set SPI1TX to the default priority level. */ +#define DMAPRISET_SPI1TX_EN (0x1 << 0 ) /* EN. When read: DMA SPI1TX is using a high priority level. When written: SPI1TX uses the high priority level. */ + +/* Reset Value for DMAPRICLR*/ +#define DMAPRICLR_RVAL 0x0 + +/* DMAPRICLR[SPI0RX] - DMA SPI0 RX. */ +#define DMAPRICLR_SPI0RX_BBA (*(volatile unsigned long *) 0x422007B4) +#define DMAPRICLR_SPI0RX_MSK (0x1 << 13 ) +#define DMAPRICLR_SPI0RX (0x1 << 13 ) +#define DMAPRICLR_SPI0RX_DIS (0x0 << 13 ) /* DIS. No effect. Use the DMAPRISET register to set SPI0RX to the high priority level. */ +#define DMAPRICLR_SPI0RX_EN (0x1 << 13 ) /* EN. SPI0RX uses the default priority level. */ + +/* DMAPRICLR[SPI0TX] - DMA SPI0 TX. */ +#define DMAPRICLR_SPI0TX_BBA (*(volatile unsigned long *) 0x422007B0) +#define DMAPRICLR_SPI0TX_MSK (0x1 << 12 ) +#define DMAPRICLR_SPI0TX (0x1 << 12 ) +#define DMAPRICLR_SPI0TX_DIS (0x0 << 12 ) /* DIS. No effect. Use the DMAPRISET register to set SPI0TX to the high priority level. */ +#define DMAPRICLR_SPI0TX_EN (0x1 << 12 ) /* EN. SPI0TX uses the default priority level. */ + +/* DMAPRICLR[ADC] - DMA ADC. */ +#define DMAPRICLR_ADC_BBA (*(volatile unsigned long *) 0x422007AC) +#define DMAPRICLR_ADC_MSK (0x1 << 11 ) +#define DMAPRICLR_ADC (0x1 << 11 ) +#define DMAPRICLR_ADC_DIS (0x0 << 11 ) /* DIS. No effect. Use the DMAPRISET register to set ADC to the high priority level. */ +#define DMAPRICLR_ADC_EN (0x1 << 11 ) /* EN. ADC uses the default priority level. */ + +/* DMAPRICLR[I2CMRX] - DMA I2C Master RX. */ +#define DMAPRICLR_I2CMRX_BBA (*(volatile unsigned long *) 0x4220079C) +#define DMAPRICLR_I2CMRX_MSK (0x1 << 7 ) +#define DMAPRICLR_I2CMRX (0x1 << 7 ) +#define DMAPRICLR_I2CMRX_DIS (0x0 << 7 ) /* DIS. No effect. Use the DMAPRISET register to set I2CMRX to the high priority level. */ +#define DMAPRICLR_I2CMRX_EN (0x1 << 7 ) /* EN. I2CMRX uses the default priority level. */ + +/* DMAPRICLR[I2CMTX] - DMA I2C Master TX. */ +#define DMAPRICLR_I2CMTX_BBA (*(volatile unsigned long *) 0x42200798) +#define DMAPRICLR_I2CMTX_MSK (0x1 << 6 ) +#define DMAPRICLR_I2CMTX (0x1 << 6 ) +#define DMAPRICLR_I2CMTX_DIS (0x0 << 6 ) /* DIS. No effect. Use the DMAPRISET register to set I2CMTX to the high priority level. */ +#define DMAPRICLR_I2CMTX_EN (0x1 << 6 ) /* EN. I2CMTX uses the default priority level. */ + +/* DMAPRICLR[I2CSRX] - DMA I2C Slave RX. */ +#define DMAPRICLR_I2CSRX_BBA (*(volatile unsigned long *) 0x42200794) +#define DMAPRICLR_I2CSRX_MSK (0x1 << 5 ) +#define DMAPRICLR_I2CSRX (0x1 << 5 ) +#define DMAPRICLR_I2CSRX_DIS (0x0 << 5 ) /* DIS. No effect. Use the DMAPRISET register to set I2CSRX to the high priority level. */ +#define DMAPRICLR_I2CSRX_EN (0x1 << 5 ) /* EN. I2CSRX uses the default priority level. */ + +/* DMAPRICLR[I2CSTX] - DMA I2C Slave TX. */ +#define DMAPRICLR_I2CSTX_BBA (*(volatile unsigned long *) 0x42200790) +#define DMAPRICLR_I2CSTX_MSK (0x1 << 4 ) +#define DMAPRICLR_I2CSTX (0x1 << 4 ) +#define DMAPRICLR_I2CSTX_DIS (0x0 << 4 ) /* DIS. No effect. Use the DMAPRISET register to set I2CSTX to the high priority level. */ +#define DMAPRICLR_I2CSTX_EN (0x1 << 4 ) /* EN. I2CSTX uses the default priority level. */ + +/* DMAPRICLR[UARTRX] - DMA UART RX. */ +#define DMAPRICLR_UARTRX_BBA (*(volatile unsigned long *) 0x4220078C) +#define DMAPRICLR_UARTRX_MSK (0x1 << 3 ) +#define DMAPRICLR_UARTRX (0x1 << 3 ) +#define DMAPRICLR_UARTRX_DIS (0x0 << 3 ) /* DIS. No effect. Use the DMAPRISET register to set UARTRX to the high priority level. */ +#define DMAPRICLR_UARTRX_EN (0x1 << 3 ) /* EN. UARTRX uses the default priority level. */ + +/* DMAPRICLR[UARTTX] - DMA UART TX. */ +#define DMAPRICLR_UARTTX_BBA (*(volatile unsigned long *) 0x42200788) +#define DMAPRICLR_UARTTX_MSK (0x1 << 2 ) +#define DMAPRICLR_UARTTX (0x1 << 2 ) +#define DMAPRICLR_UARTTX_DIS (0x0 << 2 ) /* DIS. No effect. Use the DMAPRISET register to set UARTTX to the high priority level. */ +#define DMAPRICLR_UARTTX_EN (0x1 << 2 ) /* EN. UARTTX uses the default priority level. */ + +/* DMAPRICLR[SPI1RX] - DMA SPI 1 RX. */ +#define DMAPRICLR_SPI1RX_BBA (*(volatile unsigned long *) 0x42200784) +#define DMAPRICLR_SPI1RX_MSK (0x1 << 1 ) +#define DMAPRICLR_SPI1RX (0x1 << 1 ) +#define DMAPRICLR_SPI1RX_DIS (0x0 << 1 ) /* DIS. No effect. Use the DMAPRISET register to set SPI1RX to the high priority level. */ +#define DMAPRICLR_SPI1RX_EN (0x1 << 1 ) /* EN. SPI1RX uses the default priority level. */ + +/* DMAPRICLR[SPI1TX] - DMA SPI 1 TX. */ +#define DMAPRICLR_SPI1TX_BBA (*(volatile unsigned long *) 0x42200780) +#define DMAPRICLR_SPI1TX_MSK (0x1 << 0 ) +#define DMAPRICLR_SPI1TX (0x1 << 0 ) +#define DMAPRICLR_SPI1TX_DIS (0x0 << 0 ) /* DIS. No effect. Use the DMAPRISET register to set SPI1TX to the high priority level. */ +#define DMAPRICLR_SPI1TX_EN (0x1 << 0 ) /* EN. SPI1TX uses the default priority level. */ + +/* Reset Value for DMAERRCLR*/ +#define DMAERRCLR_RVAL 0x0 + +/* DMAERRCLR[ERROR] - DMA Bus Error status. */ +#define DMAERRCLR_ERROR_BBA (*(volatile unsigned long *) 0x42200980) +#define DMAERRCLR_ERROR_MSK (0x1 << 0 ) +#define DMAERRCLR_ERROR (0x1 << 0 ) +#define DMAERRCLR_ERROR_DIS (0x0 << 0 ) /* DIS. When Read: No bus error occurred. When Written: No effect. */ +#define DMAERRCLR_ERROR_EN (0x1 << 0 ) /* EN. When Read: A bus error is pending. When Written: Bit is cleared. */ +// ------------------------------------------------------------------------------------------------ +// ----- FEE ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Flash Controller (pADI_FEE) + */ + +#if (__NO_MMR_STRUCTS__==0) +typedef struct { /*!< pADI_FEE Structure */ + __IO uint16_t FEESTA; /*!< Status Register */ + __I uint16_t RESERVED0; + __IO uint16_t FEECON0; /*!< Command Control Register */ + __I uint16_t RESERVED1; + __IO uint16_t FEECMD; /*!< Command Register */ + __I uint16_t RESERVED2[3]; + __IO uint16_t FEEADR0L; /*!< Address 0 LSB */ + __I uint16_t RESERVED3; + __IO uint16_t FEEADR0H; /*!< Address 0 MSB */ + __I uint16_t RESERVED4; + __IO uint16_t FEEADR1L; /*!< Address1 LSB */ + __I uint16_t RESERVED5; + __IO uint16_t FEEADR1H; /*!< Address1 MSB */ + __I uint16_t RESERVED6; + __IO uint16_t FEEKEY; /*!< Key Register */ + __I uint16_t RESERVED7[3]; + __IO uint16_t FEEPROL; /*!< Write Protection Register LSB */ + __I uint16_t RESERVED8; + __IO uint16_t FEEPROH; /*!< Write Protection Register MSB */ + __I uint16_t RESERVED9; + __IO uint16_t FEESIGL; /*!< Signature LSB */ + __I uint16_t RESERVED10; + __IO uint16_t FEESIGH; /*!< Signature MSB */ + __I uint16_t RESERVED11; + __IO uint16_t FEECON1; /*!< User Setup Register */ + __I uint16_t RESERVED12[7]; + __IO uint16_t FEEADRAL; /*!< Abort Address Register LSB */ + __I uint16_t RESERVED13; + __IO uint16_t FEEADRAH; /*!< Abort Address Register MSB */ + __I uint16_t RESERVED14[21]; + __IO uint16_t FEEAEN0; /*!< Interrupt Abort Register (Interrupt 15 to Interrupt 0) */ + __I uint16_t RESERVED15; + __IO uint16_t FEEAEN1; /*!< Interrupt Abort Register (Interrupt 31 to Interrupt 16) */ + __I uint16_t RESERVED16; + __IO uint16_t FEEAEN2; /*!< Interrupt Abort Register (Interrupt 42 to Interrupt 32) */ +} ADI_FEE_TypeDef; +#else // (__NO_MMR_STRUCTS__==0) +#define FEESTA (*(volatile unsigned short int *) 0x40002800) +#define FEECON0 (*(volatile unsigned short int *) 0x40002804) +#define FEECMD (*(volatile unsigned short int *) 0x40002808) +#define FEEADR0L (*(volatile unsigned short int *) 0x40002810) +#define FEEADR0H (*(volatile unsigned short int *) 0x40002814) +#define FEEADR1L (*(volatile unsigned short int *) 0x40002818) +#define FEEADR1H (*(volatile unsigned short int *) 0x4000281C) +#define FEEKEY (*(volatile unsigned short int *) 0x40002820) +#define FEEPROL (*(volatile unsigned short int *) 0x40002828) +#define FEEPROH (*(volatile unsigned short int *) 0x4000282C) +#define FEESIGL (*(volatile unsigned short int *) 0x40002830) +#define FEESIGH (*(volatile unsigned short int *) 0x40002834) +#define FEECON1 (*(volatile unsigned short int *) 0x40002838) +#define FEEADRAL (*(volatile unsigned short int *) 0x40002848) +#define FEEADRAH (*(volatile unsigned short int *) 0x4000284C) +#define FEEAEN0 (*(volatile unsigned short int *) 0x40002878) +#define FEEAEN1 (*(volatile unsigned short int *) 0x4000287C) +#define FEEAEN2 (*(volatile unsigned short int *) 0x40002880) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for FEESTA*/ +#define FEESTA_RVAL 0x0 + +/* FEESTA[SIGNERR] - Kernel space signature check on reset error */ +#define FEESTA_SIGNERR_BBA (*(volatile unsigned long *) 0x42050018) +#define FEESTA_SIGNERR_MSK (0x1 << 6 ) +#define FEESTA_SIGNERR (0x1 << 6 ) +#define FEESTA_SIGNERR_CLR (0x0 << 6 ) /* CLR. Cleared, if the signature check of the kernel passes. */ +#define FEESTA_SIGNERR_SET (0x1 << 6 ) /* SET. Set, if the signature check of the kernel fails. User code does not execute. */ + +/* FEESTA[CMDRES] - These two bits indicate the status of a command on completion or the status of a write. If multiple commands are executed or there are multiple writes via the AHB bus without a read of the status register, then the first error encountered is stored. */ +#define FEESTA_CMDRES_MSK (0x3 << 4 ) +#define FEESTA_CMDRES_SUCCESS (0x0 << 4 ) /* SUCCESS. Indicates a successful completion of a command or a write. Also cleared after a read of FEESTA. */ +#define FEESTA_CMDRES_PROTECTED (0x1 << 4 ) /* PROTECTED. Indicates an attempted erase of a protected location. */ +#define FEESTA_CMDRES_VERIFYERR (0x2 << 4 ) /* VERIFYERR. Indicates a read verify error. After an erase the controller reads the corresponding word(s) to verify that the transaction completed successfully. If data read is not all 'F's this is the resulting status. If the Sign command is executed and the resulting signature does not match the data in the upper 4 bytes of the upper page in a block then this is the resulting status. */ +#define FEESTA_CMDRES_ABORT (0x3 << 4 ) /* ABORT. Indicates that a command or a write was aborted by an abort command or a system interrupt has caused an abort. */ + +/* FEESTA[WRDONE] - Write complete. */ +#define FEESTA_WRDONE_BBA (*(volatile unsigned long *) 0x4205000C) +#define FEESTA_WRDONE_MSK (0x1 << 3 ) +#define FEESTA_WRDONE (0x1 << 3 ) +#define FEESTA_WRDONE_CLR (0x0 << 3 ) /* CLR. Cleared after a read of FEESTA. */ +#define FEESTA_WRDONE_SET (0x1 << 3 ) /* SET. Set when a write completes. If there are multiple writes or a burst write, this status bit asserts after the first long word written and stays asserted until read. If there is a burst write to flash, then this bit asserts after every long word written, assuming that user code read FEESTA after every long word written. */ + +/* FEESTA[CMDDONE] - Command complete. */ +#define FEESTA_CMDDONE_BBA (*(volatile unsigned long *) 0x42050008) +#define FEESTA_CMDDONE_MSK (0x1 << 2 ) +#define FEESTA_CMDDONE (0x1 << 2 ) +#define FEESTA_CMDDONE_CLR (0x0 << 2 ) /* CLR. Cleared after a read of FEESTA. */ +#define FEESTA_CMDDONE_SET (0x1 << 2 ) /* SET. Set when a command completes. If there are multiple commands, this status bit asserts after the first command completes and stays asserted until read. */ + +/* FEESTA[WRBUSY] - Write busy. */ +#define FEESTA_WRBUSY_BBA (*(volatile unsigned long *) 0x42050004) +#define FEESTA_WRBUSY_MSK (0x1 << 1 ) +#define FEESTA_WRBUSY (0x1 << 1 ) +#define FEESTA_WRBUSY_CLR (0x0 << 1 ) /* CLR. Cleared after a read of FEESTA. */ +#define FEESTA_WRBUSY_SET (0x1 << 1 ) /* SET. Set when the flash block is executing a write. */ + +/* FEESTA[CMDBUSY] - Command busy. */ +#define FEESTA_CMDBUSY_BBA (*(volatile unsigned long *) 0x42050000) +#define FEESTA_CMDBUSY_MSK (0x1 << 0 ) +#define FEESTA_CMDBUSY (0x1 << 0 ) +#define FEESTA_CMDBUSY_CLR (0x0 << 0 ) /* CLR. Cleared after a read of FEESTA. */ +#define FEESTA_CMDBUSY_SET (0x1 << 0 ) /* SET. Set when the flash block is executing any command entered via the command register. */ + +/* Reset Value for FEECON0*/ +#define FEECON0_RVAL 0x0 + +/* FEECON0[WREN] - Write enable bit. */ +#define FEECON0_WREN_BBA (*(volatile unsigned long *) 0x42050088) +#define FEECON0_WREN_MSK (0x1 << 2 ) +#define FEECON0_WREN (0x1 << 2 ) +#define FEECON0_WREN_DIS (0x0 << 2 ) /* DIS. Disables Flash writes. A flash write when this bit is 0 results in a hard fault system exception error and the write does not take place. */ +#define FEECON0_WREN_EN (0x1 << 2 ) /* EN. Enables Flash writes. */ + +/* FEECON0[IENERR] - Error interrupt enable bit. */ +#define FEECON0_IENERR_BBA (*(volatile unsigned long *) 0x42050084) +#define FEECON0_IENERR_MSK (0x1 << 1 ) +#define FEECON0_IENERR (0x1 << 1 ) +#define FEECON0_IENERR_DIS (0x0 << 1 ) /* DIS. Disables the Flash error interrupt. */ +#define FEECON0_IENERR_EN (0x1 << 1 ) /* EN. An interrupt is generated when a command or flash write completes with an error status. */ + +/* FEECON0[IENCMD] - Command complete interrupt enable bit. */ +#define FEECON0_IENCMD_BBA (*(volatile unsigned long *) 0x42050080) +#define FEECON0_IENCMD_MSK (0x1 << 0 ) +#define FEECON0_IENCMD (0x1 << 0 ) +#define FEECON0_IENCMD_DIS (0x0 << 0 ) /* DIS. Disables the Flash command complete interrupt. */ +#define FEECON0_IENCMD_EN (0x1 << 0 ) /* EN. An interrupt is generated when a command or flash write completes. */ + +/* Reset Value for FEECMD*/ +#define FEECMD_RVAL 0x0 + +/* FEECMD[CMD] - Commands supported by the flash controller. */ +#define FEECMD_CMD_MSK (0xF << 0 ) +#define FEECMD_CMD_IDLE (0x0 << 0 ) /* IDLE. No command executed. */ +#define FEECMD_CMD_ERASEPAGE (0x1 << 0 ) /* ERASEPAGE. Write the address of the page to be erased to FEEADR0L/H, then write this code to the FEECMD register and the flash will erase the page. When the erase has completed, the flash reads every location in the page to verify that all words in the page are erased. If there is a read verify error, this is indicated in FEESTA. To erase multiple pages, wait until a previous page erase has completed. Check the status, and then issue a command to start the next page erase. Before entering this command, 0xF456 followed by 0xF123 must be written to the key register. */ +#define FEECMD_CMD_SIGN (0x2 << 0 ) /* SIGN. Use this command to generate a signature for a block of data. The signature is generated on a page-by-page basis. To generate a signature, the address of the first page of the block is entered in FEEADR0L/FEEADR0H. The address of the last page is written to FEEADR1L/FEEADR1H. Then write this code to the FEECMD register. When the command has completed, the signature is available for reading in FEESIGL/FEESIGH. The last four bytes of the last page in a block is reserved for storing the signature. Before entering this command, 0xF456 followed 0xF123 must be written to the key register. */ +#define FEECMD_CMD_MASSERASE (0x3 << 0 ) /* MASSERASE. Erase all of user space. To enable this operation, 0xF456 followed by 0xF123 must first be written to FEEKEY (this is to prevent accidental erases). When the mass erase has completed, the controller reads every location to verify that all locations are 0xFFFFFFFF. If there is a read verify error this is indicated in FEESTA. */ +#define FEECMD_CMD_ABORT (0x4 << 0 ) /* ABORT. If this command is issued, then any command currently in progress is stopped. The status indicates command completed with an error status in FEESTA[5:4]. Note that this is the only command that can be issued while another command is already in progress. This command can also be used to stop a write that may be in progress. If a write is aborted, the address of the location being written can be read via the FEEADRAL/FEEADRAH register. While the flash controller is writing one longword, another longword write may be in the pipeline from the Cortex-M3 or DMA engine (depending on how the software implements writes). Therefore, both writes may need to be aborted. If a write or erase is aborted, then the flash timing is violated and it is not possible to determine if the write or erase completed successfully. To enable this operation, 0xF456 followed by 0xF123 must first be written to FEEKEY (this is to prevent accidental aborts). */ + +/* Reset Value for FEEADR0L*/ +#define FEEADR0L_RVAL 0x0 + +/* FEEADR0L[VALUE] - Used in conjunction with FEEADR0H, to indicate the page to be erased, or the start of a section to be signed. The address of a memory location inside the page should be stored in FEEADR0L/H, bits[15:0] in FEEADR0L, and bits[17:16] in FEEADR0H. The 9 LSBs of the address are ignored. */ +#define FEEADR0L_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for FEEADR0H*/ +#define FEEADR0H_RVAL 0x0 + +/* FEEADR0H[VALUE] - Used in conjunction with FEEADR0L, to indicate the page to be erased, or the start of a section to be signed. The address of a memory location inside the page should be stored in FEEADR0L/H, bits[15:0] in FEEADR0L, and bits[17:16] in FEEADR0H. */ +#define FEEADR0H_VALUE_MSK (0x3 << 0 ) + +/* Reset Value for FEEADR1L*/ +#define FEEADR1L_RVAL 0x0 + +/* FEEADR1L[VALUE] - Used in conjunction with FEEADR1H, to identify the last page used by the Sign command. The address of a memory location inside the page should be stored in FEEADR1L/H, bits[15:0] in FEEADR1L, and bits[17:16] in FEEADR1H. The 9 LSBs of the address are ignored. */ +#define FEEADR1L_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for FEEADR1H*/ +#define FEEADR1H_RVAL 0x0 + +/* FEEADR1H[VALUE] - Used in conjunction with FEEADR1L, to identify the last page used by the Sign command. The address of a memory location inside the page should be stored in FEEADR1L/H, bits[15:0] in FEEADR1L, and bits[17:16] in FEEADR1H. */ +#define FEEADR1H_VALUE_MSK (0x3 << 0 ) + +/* Reset Value for FEEKEY*/ +#define FEEKEY_RVAL 0x0 + +/* FEEKEY[VALUE] - Enter 0xF456 followed by 0xF123. Returns 0x0 if read. */ +#define FEEKEY_VALUE_MSK (0xFFFF << 0 ) +#define FEEKEY_VALUE_USERKEY1 (0xF456 << 0 ) /* USERKEY1 */ +#define FEEKEY_VALUE_USERKEY2 (0xF123 << 0 ) /* USERKEY2 */ + +/* Reset Value for FEEPROL*/ +#define FEEPROL_RVAL 0xFFFF + +/* FEEPROL[VALUE] - Lower 16 bits of the write protection. This register is read only if the write protection in flash has been programmed, i.e. FEEPROH/L have previously been configured to protect pages. */ +#define FEEPROL_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for FEEPROH*/ +#define FEEPROH_RVAL 0xFFFF + +/* FEEPROH[VALUE] - Upper 16 bits of the write protection. This register is read only if the write protection in flash has been programmed, i.e. FEEPROH/L have previously been configured to protect pages. */ +#define FEEPROH_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for FEESIGL*/ +#define FEESIGL_RVAL 0xFFFF + +/* FEESIGL[VALUE] - Lower 16 bits of the signature. Signature[15:0]. */ +#define FEESIGL_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for FEESIGH*/ +#define FEESIGH_RVAL 0xFFFF + +/* FEESIGH[VALUE] - Upper eight bits of the signature. Signature[23:16]. */ +#define FEESIGH_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for FEECON1*/ +#define FEECON1_RVAL 0x1 + +/* FEECON1[DBG] - Serial Wire debug enable. */ +#define FEECON1_DBG_BBA (*(volatile unsigned long *) 0x42050700) +#define FEECON1_DBG_MSK (0x1 << 0 ) +#define FEECON1_DBG (0x1 << 0 ) +#define FEECON1_DBG_DIS (0x0 << 0 ) /* DIS. Disable access via the serial wire debug interface. */ +#define FEECON1_DBG_EN (0x1 << 0 ) /* EN. Enable access via the serial wire debug interface. */ + +/* Reset Value for FEEADRAL*/ +#define FEEADRAL_RVAL 0x800 + +/* FEEADRAL[VALUE] - Lower 16 bits of the FEEADRA register. If a write is aborted then this will contain the address of the location been written when the write was aborted. */ +#define FEEADRAL_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for FEEADRAH*/ +#define FEEADRAH_RVAL 0x2 + +/* FEEADRAH[VALUE] - Upper 16 bits of the FEEADRA register. */ +#define FEEADRAH_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for FEEAEN0*/ +#define FEEAEN0_RVAL 0x0 + +/* FEEAEN0[FEE] - Flash controller interrupt abort enable bit */ +#define FEEAEN0_FEE_BBA (*(volatile unsigned long *) 0x42050F3C) +#define FEEAEN0_FEE_MSK (0x1 << 15 ) +#define FEEAEN0_FEE (0x1 << 15 ) +#define FEEAEN0_FEE_DIS (0x0 << 15 ) /* DIS. Flash controller interrupt abort disabled. */ +#define FEEAEN0_FEE_EN (0x1 << 15 ) /* EN. Flash controller interrupt abort enabled. */ + +/* FEEAEN0[ADC] - ADC interrupt abort enable bit */ +#define FEEAEN0_ADC_BBA (*(volatile unsigned long *) 0x42050F38) +#define FEEAEN0_ADC_MSK (0x1 << 14 ) +#define FEEAEN0_ADC (0x1 << 14 ) +#define FEEAEN0_ADC_DIS (0x0 << 14 ) /* DIS. ADC interrupt abort disabled. */ +#define FEEAEN0_ADC_EN (0x1 << 14 ) /* EN. ADC interrupt abort enabled. */ + +/* FEEAEN0[T1] - Timer1 interrupt abort enable bit */ +#define FEEAEN0_T1_BBA (*(volatile unsigned long *) 0x42050F34) +#define FEEAEN0_T1_MSK (0x1 << 13 ) +#define FEEAEN0_T1 (0x1 << 13 ) +#define FEEAEN0_T1_DIS (0x0 << 13 ) /* DIS. Timer1 interrupt abort disabled. */ +#define FEEAEN0_T1_EN (0x1 << 13 ) /* EN. Timer1 interrupt abort enabled. */ + +/* FEEAEN0[T0] - Timer0 interrupt abort enable bit */ +#define FEEAEN0_T0_BBA (*(volatile unsigned long *) 0x42050F30) +#define FEEAEN0_T0_MSK (0x1 << 12 ) +#define FEEAEN0_T0 (0x1 << 12 ) +#define FEEAEN0_T0_DIS (0x0 << 12 ) /* DIS. Timer0 interrupt abort disabled. */ +#define FEEAEN0_T0_EN (0x1 << 12 ) /* EN. Timer0 interrupt abort enabled. */ + +/* FEEAEN0[T3] - Timer3 interrupt abort enable bit */ +#define FEEAEN0_T3_BBA (*(volatile unsigned long *) 0x42050F28) +#define FEEAEN0_T3_MSK (0x1 << 10 ) +#define FEEAEN0_T3 (0x1 << 10 ) +#define FEEAEN0_T3_DIS (0x0 << 10 ) /* DIS. Timer3 interrupt abort disabled. */ +#define FEEAEN0_T3_EN (0x1 << 10 ) /* EN. Timer3 interrupt abort enabled. */ + +/* FEEAEN0[EXTINT8] - External interrupt 8 abort enable bit */ +#define FEEAEN0_EXTINT8_BBA (*(volatile unsigned long *) 0x42050F24) +#define FEEAEN0_EXTINT8_MSK (0x1 << 9 ) +#define FEEAEN0_EXTINT8 (0x1 << 9 ) +#define FEEAEN0_EXTINT8_DIS (0x0 << 9 ) /* DIS. External interrupt 8 abort disabled. */ +#define FEEAEN0_EXTINT8_EN (0x1 << 9 ) /* EN. External interrupt 8 abort enabled. */ + +/* FEEAEN0[EXTINT7] - External interrupt 7 abort enable bit */ +#define FEEAEN0_EXTINT7_BBA (*(volatile unsigned long *) 0x42050F20) +#define FEEAEN0_EXTINT7_MSK (0x1 << 8 ) +#define FEEAEN0_EXTINT7 (0x1 << 8 ) +#define FEEAEN0_EXTINT7_DIS (0x0 << 8 ) /* DIS. External interrupt 7 abort disabled. */ +#define FEEAEN0_EXTINT7_EN (0x1 << 8 ) /* EN. External interrupt 7 abort enabled. */ + +/* FEEAEN0[EXTINT6] - External interrupt 6 abort enable bit */ +#define FEEAEN0_EXTINT6_BBA (*(volatile unsigned long *) 0x42050F1C) +#define FEEAEN0_EXTINT6_MSK (0x1 << 7 ) +#define FEEAEN0_EXTINT6 (0x1 << 7 ) +#define FEEAEN0_EXTINT6_DIS (0x0 << 7 ) /* DIS. External interrupt 6 abort disabled. */ +#define FEEAEN0_EXTINT6_EN (0x1 << 7 ) /* EN. External interrupt 6 abort enabled. */ + +/* FEEAEN0[EXTINT5] - External interrupt 5 abort enable bit */ +#define FEEAEN0_EXTINT5_BBA (*(volatile unsigned long *) 0x42050F18) +#define FEEAEN0_EXTINT5_MSK (0x1 << 6 ) +#define FEEAEN0_EXTINT5 (0x1 << 6 ) +#define FEEAEN0_EXTINT5_DIS (0x0 << 6 ) /* DIS. External interrupt 5 abort disabled. */ +#define FEEAEN0_EXTINT5_EN (0x1 << 6 ) /* EN. External interrupt 5 abort enabled. */ + +/* FEEAEN0[EXTINT4] - External interrupt 4 abort enable bit */ +#define FEEAEN0_EXTINT4_BBA (*(volatile unsigned long *) 0x42050F14) +#define FEEAEN0_EXTINT4_MSK (0x1 << 5 ) +#define FEEAEN0_EXTINT4 (0x1 << 5 ) +#define FEEAEN0_EXTINT4_DIS (0x0 << 5 ) /* DIS. External interrupt 4 abort disabled. */ +#define FEEAEN0_EXTINT4_EN (0x1 << 5 ) /* EN. External interrupt 4 abort enabled. */ + +/* FEEAEN0[EXTINT3] - External interrupt 3 abort enable bit */ +#define FEEAEN0_EXTINT3_BBA (*(volatile unsigned long *) 0x42050F10) +#define FEEAEN0_EXTINT3_MSK (0x1 << 4 ) +#define FEEAEN0_EXTINT3 (0x1 << 4 ) +#define FEEAEN0_EXTINT3_DIS (0x0 << 4 ) /* DIS. External interrupt 3 abort disabled. */ +#define FEEAEN0_EXTINT3_EN (0x1 << 4 ) /* EN. External interrupt 3 abort enabled. */ + +/* FEEAEN0[EXTINT2] - External interrupt 2 abort enable bit */ +#define FEEAEN0_EXTINT2_BBA (*(volatile unsigned long *) 0x42050F0C) +#define FEEAEN0_EXTINT2_MSK (0x1 << 3 ) +#define FEEAEN0_EXTINT2 (0x1 << 3 ) +#define FEEAEN0_EXTINT2_DIS (0x0 << 3 ) /* DIS. External interrupt 2 abort disabled. */ +#define FEEAEN0_EXTINT2_EN (0x1 << 3 ) /* EN. External interrupt 2 abort enabled. */ + +/* FEEAEN0[EXTINT1] - External interrupt 1 abort enable bit */ +#define FEEAEN0_EXTINT1_BBA (*(volatile unsigned long *) 0x42050F08) +#define FEEAEN0_EXTINT1_MSK (0x1 << 2 ) +#define FEEAEN0_EXTINT1 (0x1 << 2 ) +#define FEEAEN0_EXTINT1_DIS (0x0 << 2 ) /* DIS. External interrupt 1 abort disabled. */ +#define FEEAEN0_EXTINT1_EN (0x1 << 2 ) /* EN. External interrupt 1 abort enabled. */ + +/* FEEAEN0[EXTINT0] - External interrupt 0 abort enable bit */ +#define FEEAEN0_EXTINT0_BBA (*(volatile unsigned long *) 0x42050F04) +#define FEEAEN0_EXTINT0_MSK (0x1 << 1 ) +#define FEEAEN0_EXTINT0 (0x1 << 1 ) +#define FEEAEN0_EXTINT0_DIS (0x0 << 1 ) /* DIS. External interrupt 0 abort disabled. */ +#define FEEAEN0_EXTINT0_EN (0x1 << 1 ) /* EN. External interrupt 0 abort enabled. */ + +/* FEEAEN0[T2] - Timer2 interrupt abort enable bit */ +#define FEEAEN0_T2_BBA (*(volatile unsigned long *) 0x42050F00) +#define FEEAEN0_T2_MSK (0x1 << 0 ) +#define FEEAEN0_T2 (0x1 << 0 ) +#define FEEAEN0_T2_DIS (0x0 << 0 ) /* DIS. Timer2 interrupt abort disabled. */ +#define FEEAEN0_T2_EN (0x1 << 0 ) /* EN. Timer2 interrupt abort enabled */ + +/* Reset Value for FEEAEN1*/ +#define FEEAEN1_RVAL 0x0 + +/* FEEAEN1[DMAI2CMRX] - I2C master RX DMA interrupt abort enable bit */ +#define FEEAEN1_DMAI2CMRX_BBA (*(volatile unsigned long *) 0x42050FBC) +#define FEEAEN1_DMAI2CMRX_MSK (0x1 << 15 ) +#define FEEAEN1_DMAI2CMRX (0x1 << 15 ) +#define FEEAEN1_DMAI2CMRX_DIS (0x0 << 15 ) /* DIS. I2C master RX DMA interrupt abort disabled. */ +#define FEEAEN1_DMAI2CMRX_EN (0x1 << 15 ) /* EN. I2C master RX DMA interrupt abort enabled. */ + +/* FEEAEN1[DMAI2CMTX] - I2C master TX DMA interrupt abort enable bit */ +#define FEEAEN1_DMAI2CMTX_BBA (*(volatile unsigned long *) 0x42050FB8) +#define FEEAEN1_DMAI2CMTX_MSK (0x1 << 14 ) +#define FEEAEN1_DMAI2CMTX (0x1 << 14 ) +#define FEEAEN1_DMAI2CMTX_DIS (0x0 << 14 ) /* DIS. I2C master TX DMA interrupt abort disabled. */ +#define FEEAEN1_DMAI2CMTX_EN (0x1 << 14 ) /* EN. I2C master TX DMA interrupt abort enabled. */ + +/* FEEAEN1[DMAI2CSRX] - I2C slave RX DMA interrupt abort enable bit */ +#define FEEAEN1_DMAI2CSRX_BBA (*(volatile unsigned long *) 0x42050FB4) +#define FEEAEN1_DMAI2CSRX_MSK (0x1 << 13 ) +#define FEEAEN1_DMAI2CSRX (0x1 << 13 ) +#define FEEAEN1_DMAI2CSRX_DIS (0x0 << 13 ) /* DIS. I2C slave RX DMA interrupt abort disabled. */ +#define FEEAEN1_DMAI2CSRX_EN (0x1 << 13 ) /* EN. I2C slave RX DMA interrupt abort enabled. */ + +/* FEEAEN1[DMAI2CSTX] - I2C slave TX DMA interrupt abort enable bit */ +#define FEEAEN1_DMAI2CSTX_BBA (*(volatile unsigned long *) 0x42050FB0) +#define FEEAEN1_DMAI2CSTX_MSK (0x1 << 12 ) +#define FEEAEN1_DMAI2CSTX (0x1 << 12 ) +#define FEEAEN1_DMAI2CSTX_DIS (0x0 << 12 ) /* DIS. I2C slave TX DMA interrupt abort disabled. */ +#define FEEAEN1_DMAI2CSTX_EN (0x1 << 12 ) /* EN. I2C slave TX DMA interrupt abort enabled. */ + +/* FEEAEN1[DMAUARTRX] - UARTRX DMA interrupt abort enable bit */ +#define FEEAEN1_DMAUARTRX_BBA (*(volatile unsigned long *) 0x42050FAC) +#define FEEAEN1_DMAUARTRX_MSK (0x1 << 11 ) +#define FEEAEN1_DMAUARTRX (0x1 << 11 ) +#define FEEAEN1_DMAUARTRX_DIS (0x0 << 11 ) /* DIS. UARTRX DMA interrupt abort disabled. */ +#define FEEAEN1_DMAUARTRX_EN (0x1 << 11 ) /* EN. UARTRX DMA interrupt abort enabled. */ + +/* FEEAEN1[DMAUARTTX] - UARTTX DMA interrupt abort enable bit */ +#define FEEAEN1_DMAUARTTX_BBA (*(volatile unsigned long *) 0x42050FA8) +#define FEEAEN1_DMAUARTTX_MSK (0x1 << 10 ) +#define FEEAEN1_DMAUARTTX (0x1 << 10 ) +#define FEEAEN1_DMAUARTTX_DIS (0x0 << 10 ) /* DIS. UARTTX DMA interrupt abort disabled. */ +#define FEEAEN1_DMAUARTTX_EN (0x1 << 10 ) /* EN. UARTTX DMA interrupt abort enabled. */ + +/* FEEAEN1[DMASPI1RX] - SPI1RX DMA interrupt abort enable bit */ +#define FEEAEN1_DMASPI1RX_BBA (*(volatile unsigned long *) 0x42050FA4) +#define FEEAEN1_DMASPI1RX_MSK (0x1 << 9 ) +#define FEEAEN1_DMASPI1RX (0x1 << 9 ) +#define FEEAEN1_DMASPI1RX_DIS (0x0 << 9 ) /* DIS. SPI1RX DMA interrupt abort disabled. */ +#define FEEAEN1_DMASPI1RX_EN (0x1 << 9 ) /* EN. SPI1RX DMA interrupt abort enabled. */ + +/* FEEAEN1[DMASPI1TX] - SPI1TX DMA interrupt abort enable bit */ +#define FEEAEN1_DMASPI1TX_BBA (*(volatile unsigned long *) 0x42050FA0) +#define FEEAEN1_DMASPI1TX_MSK (0x1 << 8 ) +#define FEEAEN1_DMASPI1TX (0x1 << 8 ) +#define FEEAEN1_DMASPI1TX_DIS (0x0 << 8 ) /* DIS. SPI1TX DMA interrupt abort disabled. */ +#define FEEAEN1_DMASPI1TX_EN (0x1 << 8 ) /* EN. SPI1TX DMA interrupt abort enabled. */ + +/* FEEAEN1[DMAERROR] - DMA error interrupt abort enable bit */ +#define FEEAEN1_DMAERROR_BBA (*(volatile unsigned long *) 0x42050F9C) +#define FEEAEN1_DMAERROR_MSK (0x1 << 7 ) +#define FEEAEN1_DMAERROR (0x1 << 7 ) +#define FEEAEN1_DMAERROR_DIS (0x0 << 7 ) /* DIS. DMA error interrupt abort disabled. */ +#define FEEAEN1_DMAERROR_EN (0x1 << 7 ) /* EN. DMA error interrupt abort enabled. */ + +/* FEEAEN1[I2CM] - I2C master interrupt abort enable bit */ +#define FEEAEN1_I2CM_BBA (*(volatile unsigned long *) 0x42050F90) +#define FEEAEN1_I2CM_MSK (0x1 << 4 ) +#define FEEAEN1_I2CM (0x1 << 4 ) +#define FEEAEN1_I2CM_DIS (0x0 << 4 ) /* DIS. I2C slave interrupt abort disabled. */ +#define FEEAEN1_I2CM_EN (0x1 << 4 ) /* EN. I2C master interrupt abort enabled. */ + +/* FEEAEN1[I2CS] - I2C slave interrupt abort enable bit */ +#define FEEAEN1_I2CS_BBA (*(volatile unsigned long *) 0x42050F8C) +#define FEEAEN1_I2CS_MSK (0x1 << 3 ) +#define FEEAEN1_I2CS (0x1 << 3 ) +#define FEEAEN1_I2CS_DIS (0x0 << 3 ) /* DIS. I2C slave interrupt abort disabled. */ +#define FEEAEN1_I2CS_EN (0x1 << 3 ) /* EN. I2C slave interrupt abort enabled. */ + +/* FEEAEN1[SPI1] - SPI1 interrupt abort enable bit */ +#define FEEAEN1_SPI1_BBA (*(volatile unsigned long *) 0x42050F88) +#define FEEAEN1_SPI1_MSK (0x1 << 2 ) +#define FEEAEN1_SPI1 (0x1 << 2 ) +#define FEEAEN1_SPI1_DIS (0x0 << 2 ) /* DIS. SPI1 interrupt abort disabled. */ +#define FEEAEN1_SPI1_EN (0x1 << 2 ) /* EN. SPI1 interrupt abort enabled. */ + +/* FEEAEN1[SPI0] - SPI0 interrupt abort enable bit */ +#define FEEAEN1_SPI0_BBA (*(volatile unsigned long *) 0x42050F84) +#define FEEAEN1_SPI0_MSK (0x1 << 1 ) +#define FEEAEN1_SPI0 (0x1 << 1 ) +#define FEEAEN1_SPI0_DIS (0x0 << 1 ) /* DIS. SPI0 interrupt abort disabled. */ +#define FEEAEN1_SPI0_EN (0x1 << 1 ) /* EN. SPI0 interrupt abort enabled. */ + +/* FEEAEN1[UART] - UART interrupt abort enable bit */ +#define FEEAEN1_UART_BBA (*(volatile unsigned long *) 0x42050F80) +#define FEEAEN1_UART_MSK (0x1 << 0 ) +#define FEEAEN1_UART (0x1 << 0 ) +#define FEEAEN1_UART_DIS (0x0 << 0 ) /* DIS. UART interrupt abort disabled. */ +#define FEEAEN1_UART_EN (0x1 << 0 ) /* EN. UART interrupt abort enabled. */ + +/* Reset Value for FEEAEN2*/ +#define FEEAEN2_RVAL 0x0 + +/* FEEAEN2[PWM3] - PWM3 interrupt abort enable bit */ +#define FEEAEN2_PWM3_BBA (*(volatile unsigned long *) 0x42051028) +#define FEEAEN2_PWM3_MSK (0x1 << 10 ) +#define FEEAEN2_PWM3 (0x1 << 10 ) +#define FEEAEN2_PWM3_DIS (0x0 << 10 ) /* DIS. PWM3 interrupt abort disabled. */ +#define FEEAEN2_PWM3_EN (0x1 << 10 ) /* EN. PWM3 interrupt abort enabled. */ + +/* FEEAEN2[PWM2] - PWM2 interrupt abort enable bit */ +#define FEEAEN2_PWM2_BBA (*(volatile unsigned long *) 0x42051024) +#define FEEAEN2_PWM2_MSK (0x1 << 9 ) +#define FEEAEN2_PWM2 (0x1 << 9 ) +#define FEEAEN2_PWM2_DIS (0x0 << 9 ) /* DIS. PWM2 interrupt abort disabled. */ +#define FEEAEN2_PWM2_EN (0x1 << 9 ) /* EN. PWM2 interrupt abort enabled. */ + +/* FEEAEN2[PWM1] - PWM1 interrupt abort enable bit */ +#define FEEAEN2_PWM1_BBA (*(volatile unsigned long *) 0x42051020) +#define FEEAEN2_PWM1_MSK (0x1 << 8 ) +#define FEEAEN2_PWM1 (0x1 << 8 ) +#define FEEAEN2_PWM1_DIS (0x0 << 8 ) /* DIS. PWM1 interrupt abort disabled. */ +#define FEEAEN2_PWM1_EN (0x1 << 8 ) /* EN. PWM1 interrupt abort enabled. */ + +/* FEEAEN2[PWM0] - PWM0 interrupt abort enable bit */ +#define FEEAEN2_PWM0_BBA (*(volatile unsigned long *) 0x4205101C) +#define FEEAEN2_PWM0_MSK (0x1 << 7 ) +#define FEEAEN2_PWM0 (0x1 << 7 ) +#define FEEAEN2_PWM0_DIS (0x0 << 7 ) /* DIS. PWM0 interrupt abort disabled. */ +#define FEEAEN2_PWM0_EN (0x1 << 7 ) /* EN. PWM0 interrupt abort enabled. */ + +/* FEEAEN2[PWMTRIP] - PWMTRIP interrupt abort enable bit */ +#define FEEAEN2_PWMTRIP_BBA (*(volatile unsigned long *) 0x42051018) +#define FEEAEN2_PWMTRIP_MSK (0x1 << 6 ) +#define FEEAEN2_PWMTRIP (0x1 << 6 ) +#define FEEAEN2_PWMTRIP_DIS (0x0 << 6 ) /* DIS. PWMTRIP interrupt abort disabled. */ +#define FEEAEN2_PWMTRIP_EN (0x1 << 6 ) /* EN. PWMTRIP interrupt abort enabled. */ + +/* FEEAEN2[DMASPI0RX] - SPI0RX DMA interrupt abort enable bit */ +#define FEEAEN2_DMASPI0RX_BBA (*(volatile unsigned long *) 0x42051014) +#define FEEAEN2_DMASPI0RX_MSK (0x1 << 5 ) +#define FEEAEN2_DMASPI0RX (0x1 << 5 ) +#define FEEAEN2_DMASPI0RX_DIS (0x0 << 5 ) /* DIS. SPI0RX DMA interrupt abort disabled. */ +#define FEEAEN2_DMASPI0RX_EN (0x1 << 5 ) /* EN. SPI0RX DMA interrupt abort enabled. */ + +/* FEEAEN2[DMASPI0TX] - SPI0TX DMA interrupt abort enable bit */ +#define FEEAEN2_DMASPI0TX_BBA (*(volatile unsigned long *) 0x42051010) +#define FEEAEN2_DMASPI0TX_MSK (0x1 << 4 ) +#define FEEAEN2_DMASPI0TX (0x1 << 4 ) +#define FEEAEN2_DMASPI0TX_DIS (0x0 << 4 ) /* DIS. SPI0TX DMA interrupt abort disabled. */ +#define FEEAEN2_DMASPI0TX_EN (0x1 << 4 ) /* EN. SPI0TX DMA interrupt abort enabled. */ + +/* FEEAEN2[DMAADC] - ADC DMA interrupt abort enable bit */ +#define FEEAEN2_DMAADC_BBA (*(volatile unsigned long *) 0x4205100C) +#define FEEAEN2_DMAADC_MSK (0x1 << 3 ) +#define FEEAEN2_DMAADC (0x1 << 3 ) +#define FEEAEN2_DMAADC_DIS (0x0 << 3 ) /* DIS. ADC DMA interrupt abort disabled. */ +#define FEEAEN2_DMAADC_EN (0x1 << 3 ) /* EN. ADC DMA interrupt abort enabled. */ +// ------------------------------------------------------------------------------------------------ +// ----- GPIO0 ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief General Purpose Input Output (pADI_GP0) + */ + +#if (__NO_MMR_STRUCTS__==0) +typedef struct { /*!< pADI_GP0 Structure */ + __IO uint16_t GPCON; /*!< GPIO Port 0 Configuration */ + __I uint16_t RESERVED0; + __IO uint8_t GPOEN; /*!< GPIO Port 0 Output Enable */ + __I uint8_t RESERVED1[3]; + __IO uint8_t GPPUL; /*!< GPIO Port 0 Pull Up Enable */ + __I uint8_t RESERVED2[3]; + __IO uint8_t GPOCE; /*!< GPIO Port 0 Tri State */ + __I uint8_t RESERVED3[7]; + __IO uint8_t GPIN; /*!< GPIO Port 0 Data Input */ + __I uint8_t RESERVED4[3]; + __IO uint8_t GPOUT; /*!< GPIO Port 0 Data Out */ + __I uint8_t RESERVED5[3]; + __IO uint8_t GPSET; /*!< GPIO Port 0 Data Out Set */ + __I uint8_t RESERVED6[3]; + __IO uint8_t GPCLR; /*!< GPIO Port 0 Data Out Clear */ + __I uint8_t RESERVED7[3]; + __IO uint8_t GPTGL; /*!< GPIO Port 0 Pin Toggle */ +} ADI_GPIO_TypeDef; +#else // (__NO_MMR_STRUCTS__==0) +#define GP0CON (*(volatile unsigned short int *) 0x40006000) +#define GP0OEN (*(volatile unsigned char *) 0x40006004) +#define GP0PUL (*(volatile unsigned char *) 0x40006008) +#define GP0OCE (*(volatile unsigned char *) 0x4000600C) +#define GP0IN (*(volatile unsigned char *) 0x40006014) +#define GP0OUT (*(volatile unsigned char *) 0x40006018) +#define GP0SET (*(volatile unsigned char *) 0x4000601C) +#define GP0CLR (*(volatile unsigned char *) 0x40006020) +#define GP0TGL (*(volatile unsigned char *) 0x40006024) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for GP0CON*/ +#define GP0CON_RVAL 0x0 + +/* GP0CON[CON7] - Configuration bits for Px.7 (not available for port 1). */ +#define GP0CON_CON7_MSK (0x3 << 14 ) +#define GP0CON_CON7_GPIOIRQ3 (0x0 << 14 ) /* GPIOIRQ3. GPIO/IRQ3. */ +#define GP0CON_CON7_SPI1CS4 (0x1 << 14 ) /* SPI1CS4. SPI1 CS4 (SPI1). */ +#define GP0CON_CON7_UARTCTS (0x2 << 14 ) /* UARTCTS. UART CTS. */ + +/* GP0CON[CON6] - Configuration bits for Px.6 (not available for port 1). */ +#define GP0CON_CON6_MSK (0x3 << 12 ) +#define GP0CON_CON6_GPIOIRQ2 (0x0 << 12 ) /* GPIOIRQ2. GPIO/IRQ2. */ +#define GP0CON_CON6_SPI1CS3 (0x1 << 12 ) /* SPI1CS3. SPI1 CS3 (SPI1). */ +#define GP0CON_CON6_UARTRTS (0x2 << 12 ) /* UARTRTS. UART RTS. */ +#define GP0CON_CON6_PWM0 (0x3 << 12 ) /* PWM0. PWM0. */ + +/* GP0CON[CON5] - Configuration bits for Px.5. */ +#define GP0CON_CON5_MSK (0x3 << 10 ) +#define GP0CON_CON5_GPIO (0x0 << 10 ) /* GPIO. GPIO. */ +#define GP0CON_CON5_SPI1CS2 (0x1 << 10 ) /* SPI1CS2. SPI1 CS2 (SPI1). */ +#define GP0CON_CON5_ECLKIN (0x2 << 10 ) /* ECLKIN. ECLKIN. */ + +/* GP0CON[CON4] - Configuration bits for Px.4. */ +#define GP0CON_CON4_MSK (0x3 << 8 ) +#define GP0CON_CON4_GPIO (0x0 << 8 ) /* GPIO. GPIO */ +#define GP0CON_CON4_SPI1CS1 (0x1 << 8 ) /* SPI1CS1. SPI1 CS1 (SPI1). */ +#define GP0CON_CON4_ECLKOUT (0x2 << 8 ) /* ECLKOUT. ECLK OUT. */ + +/* GP0CON[CON3] - Configuration bits for Px.3. */ +#define GP0CON_CON3_MSK (0x3 << 6 ) +#define GP0CON_CON3_GPIOIRQ1 (0x0 << 6 ) /* GPIOIRQ1. GPIO/IRQ1. */ +#define GP0CON_CON3_SPI1CS0 (0x1 << 6 ) /* SPI1CS0. SPI1 CS0 (SPI1). */ +#define GP0CON_CON3_ADCCONVST (0x2 << 6 ) /* ADCCONVST. ADCCONVST. */ +#define GP0CON_CON3_PWM1 (0x3 << 6 ) /* PWM1. PWM1. */ + +/* GP0CON[CON2] - Configuration bits for Px.2. */ +#define GP0CON_CON2_MSK (0x3 << 4 ) +#define GP0CON_CON2_GPIO (0x0 << 4 ) /* GPIO. GPIO */ +#define GP0CON_CON2_SPI1MOSI (0x1 << 4 ) /* SPI1MOSI. SPI MOSI (SPI1). */ +#define GP0CON_CON2_PWM0 (0x3 << 4 ) /* PWM0. PWM0 */ + +/* GP0CON[CON1] - Configuration bits for Px.1. */ +#define GP0CON_CON1_MSK (0x3 << 2 ) +#define GP0CON_CON1_GPIO (0x0 << 2 ) /* GPIO. GPIO. */ +#define GP0CON_CON1_SPI1SCLK (0x1 << 2 ) /* SPI1SCLK. SPI SCLK (SPI1). */ + +/* GP0CON[CON0] - Configuration bits for Px.0. */ +#define GP0CON_CON0_MSK (0x3 << 0 ) +#define GP0CON_CON0_GPIO (0x0 << 0 ) /* GPIO. GPIO */ +#define GP0CON_CON0_SPI1MISO (0x1 << 0 ) /* SPI1MISO. SPI MISO (SPI1) */ + +/* Reset Value for GP0OEN*/ +#define GP0OEN_RVAL 0x0 + +/* GP0OEN[OEN7] - Port pin direction. */ +#define GP0OEN_OEN7_BBA (*(volatile unsigned long *) 0x420C009C) +#define GP0OEN_OEN7_MSK (0x1 << 7 ) +#define GP0OEN_OEN7 (0x1 << 7 ) +#define GP0OEN_OEN7_IN (0x0 << 7 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP0OEN_OEN7_OUT (0x1 << 7 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP0OEN[OEN6] - Port pin direction. */ +#define GP0OEN_OEN6_BBA (*(volatile unsigned long *) 0x420C0098) +#define GP0OEN_OEN6_MSK (0x1 << 6 ) +#define GP0OEN_OEN6 (0x1 << 6 ) +#define GP0OEN_OEN6_IN (0x0 << 6 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP0OEN_OEN6_OUT (0x1 << 6 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP0OEN[OEN5] - Port pin direction. */ +#define GP0OEN_OEN5_BBA (*(volatile unsigned long *) 0x420C0094) +#define GP0OEN_OEN5_MSK (0x1 << 5 ) +#define GP0OEN_OEN5 (0x1 << 5 ) +#define GP0OEN_OEN5_IN (0x0 << 5 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP0OEN_OEN5_OUT (0x1 << 5 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP0OEN[OEN4] - Port pin direction. */ +#define GP0OEN_OEN4_BBA (*(volatile unsigned long *) 0x420C0090) +#define GP0OEN_OEN4_MSK (0x1 << 4 ) +#define GP0OEN_OEN4 (0x1 << 4 ) +#define GP0OEN_OEN4_IN (0x0 << 4 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP0OEN_OEN4_OUT (0x1 << 4 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP0OEN[OEN3] - Port pin direction. */ +#define GP0OEN_OEN3_BBA (*(volatile unsigned long *) 0x420C008C) +#define GP0OEN_OEN3_MSK (0x1 << 3 ) +#define GP0OEN_OEN3 (0x1 << 3 ) +#define GP0OEN_OEN3_IN (0x0 << 3 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP0OEN_OEN3_OUT (0x1 << 3 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP0OEN[OEN2] - Port pin direction. */ +#define GP0OEN_OEN2_BBA (*(volatile unsigned long *) 0x420C0088) +#define GP0OEN_OEN2_MSK (0x1 << 2 ) +#define GP0OEN_OEN2 (0x1 << 2 ) +#define GP0OEN_OEN2_IN (0x0 << 2 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP0OEN_OEN2_OUT (0x1 << 2 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP0OEN[OEN1] - Port pin direction. */ +#define GP0OEN_OEN1_BBA (*(volatile unsigned long *) 0x420C0084) +#define GP0OEN_OEN1_MSK (0x1 << 1 ) +#define GP0OEN_OEN1 (0x1 << 1 ) +#define GP0OEN_OEN1_IN (0x0 << 1 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP0OEN_OEN1_OUT (0x1 << 1 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP0OEN[OEN0] - Port pin direction. */ +#define GP0OEN_OEN0_BBA (*(volatile unsigned long *) 0x420C0080) +#define GP0OEN_OEN0_MSK (0x1 << 0 ) +#define GP0OEN_OEN0 (0x1 << 0 ) +#define GP0OEN_OEN0_IN (0x0 << 0 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP0OEN_OEN0_OUT (0x1 << 0 ) /* OUT. Enables the output on corresponding port pin.. */ + +/* Reset Value for GP0PUL*/ +#define GP0PUL_RVAL 0xFF + +/* GP0PUL[PUL7] - Pull Up Enable for port pin. */ +#define GP0PUL_PUL7_BBA (*(volatile unsigned long *) 0x420C011C) +#define GP0PUL_PUL7_MSK (0x1 << 7 ) +#define GP0PUL_PUL7 (0x1 << 7 ) +#define GP0PUL_PUL7_DIS (0x0 << 7 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP0PUL_PUL7_EN (0x1 << 7 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP0PUL[PUL6] - Pull Up Enable for port pin. */ +#define GP0PUL_PUL6_BBA (*(volatile unsigned long *) 0x420C0118) +#define GP0PUL_PUL6_MSK (0x1 << 6 ) +#define GP0PUL_PUL6 (0x1 << 6 ) +#define GP0PUL_PUL6_DIS (0x0 << 6 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP0PUL_PUL6_EN (0x1 << 6 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP0PUL[PUL5] - Pull Up Enable for port pin. */ +#define GP0PUL_PUL5_BBA (*(volatile unsigned long *) 0x420C0114) +#define GP0PUL_PUL5_MSK (0x1 << 5 ) +#define GP0PUL_PUL5 (0x1 << 5 ) +#define GP0PUL_PUL5_DIS (0x0 << 5 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP0PUL_PUL5_EN (0x1 << 5 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP0PUL[PUL4] - Pull Up Enable for port pin. */ +#define GP0PUL_PUL4_BBA (*(volatile unsigned long *) 0x420C0110) +#define GP0PUL_PUL4_MSK (0x1 << 4 ) +#define GP0PUL_PUL4 (0x1 << 4 ) +#define GP0PUL_PUL4_DIS (0x0 << 4 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP0PUL_PUL4_EN (0x1 << 4 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP0PUL[PUL3] - Pull Up Enable for port pin. */ +#define GP0PUL_PUL3_BBA (*(volatile unsigned long *) 0x420C010C) +#define GP0PUL_PUL3_MSK (0x1 << 3 ) +#define GP0PUL_PUL3 (0x1 << 3 ) +#define GP0PUL_PUL3_DIS (0x0 << 3 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP0PUL_PUL3_EN (0x1 << 3 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP0PUL[PUL2] - Pull Up Enable for port pin. */ +#define GP0PUL_PUL2_BBA (*(volatile unsigned long *) 0x420C0108) +#define GP0PUL_PUL2_MSK (0x1 << 2 ) +#define GP0PUL_PUL2 (0x1 << 2 ) +#define GP0PUL_PUL2_DIS (0x0 << 2 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP0PUL_PUL2_EN (0x1 << 2 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP0PUL[PUL1] - Pull Up Enable for port pin. */ +#define GP0PUL_PUL1_BBA (*(volatile unsigned long *) 0x420C0104) +#define GP0PUL_PUL1_MSK (0x1 << 1 ) +#define GP0PUL_PUL1 (0x1 << 1 ) +#define GP0PUL_PUL1_DIS (0x0 << 1 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP0PUL_PUL1_EN (0x1 << 1 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP0PUL[PUL0] - Pull Up Enable for port pin. */ +#define GP0PUL_PUL0_BBA (*(volatile unsigned long *) 0x420C0100) +#define GP0PUL_PUL0_MSK (0x1 << 0 ) +#define GP0PUL_PUL0 (0x1 << 0 ) +#define GP0PUL_PUL0_DIS (0x0 << 0 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP0PUL_PUL0_EN (0x1 << 0 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* Reset Value for GP0OCE*/ +#define GP0OCE_RVAL 0x0 + +/* GP0OCE[OCE7] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP0OCE_OCE7_BBA (*(volatile unsigned long *) 0x420C019C) +#define GP0OCE_OCE7_MSK (0x1 << 7 ) +#define GP0OCE_OCE7 (0x1 << 7 ) +#define GP0OCE_OCE7_DIS (0x0 << 7 ) /* DIS */ +#define GP0OCE_OCE7_EN (0x1 << 7 ) /* EN */ + +/* GP0OCE[OCE6] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP0OCE_OCE6_BBA (*(volatile unsigned long *) 0x420C0198) +#define GP0OCE_OCE6_MSK (0x1 << 6 ) +#define GP0OCE_OCE6 (0x1 << 6 ) +#define GP0OCE_OCE6_DIS (0x0 << 6 ) /* DIS */ +#define GP0OCE_OCE6_EN (0x1 << 6 ) /* EN */ + +/* GP0OCE[OCE5] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP0OCE_OCE5_BBA (*(volatile unsigned long *) 0x420C0194) +#define GP0OCE_OCE5_MSK (0x1 << 5 ) +#define GP0OCE_OCE5 (0x1 << 5 ) +#define GP0OCE_OCE5_DIS (0x0 << 5 ) /* DIS */ +#define GP0OCE_OCE5_EN (0x1 << 5 ) /* EN */ + +/* GP0OCE[OCE4] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP0OCE_OCE4_BBA (*(volatile unsigned long *) 0x420C0190) +#define GP0OCE_OCE4_MSK (0x1 << 4 ) +#define GP0OCE_OCE4 (0x1 << 4 ) +#define GP0OCE_OCE4_DIS (0x0 << 4 ) /* DIS */ +#define GP0OCE_OCE4_EN (0x1 << 4 ) /* EN */ + +/* GP0OCE[OCE3] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP0OCE_OCE3_BBA (*(volatile unsigned long *) 0x420C018C) +#define GP0OCE_OCE3_MSK (0x1 << 3 ) +#define GP0OCE_OCE3 (0x1 << 3 ) +#define GP0OCE_OCE3_DIS (0x0 << 3 ) /* DIS */ +#define GP0OCE_OCE3_EN (0x1 << 3 ) /* EN */ + +/* GP0OCE[OCE2] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP0OCE_OCE2_BBA (*(volatile unsigned long *) 0x420C0188) +#define GP0OCE_OCE2_MSK (0x1 << 2 ) +#define GP0OCE_OCE2 (0x1 << 2 ) +#define GP0OCE_OCE2_DIS (0x0 << 2 ) /* DIS */ +#define GP0OCE_OCE2_EN (0x1 << 2 ) /* EN */ + +/* GP0OCE[OCE1] - Output enable. Sets the GPIO pads oncorresponding port to open circuit mode. */ +#define GP0OCE_OCE1_BBA (*(volatile unsigned long *) 0x420C0184) +#define GP0OCE_OCE1_MSK (0x1 << 1 ) +#define GP0OCE_OCE1 (0x1 << 1 ) +#define GP0OCE_OCE1_DIS (0x0 << 1 ) /* DIS */ +#define GP0OCE_OCE1_EN (0x1 << 1 ) /* EN */ + +/* GP0OCE[OCE0] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP0OCE_OCE0_BBA (*(volatile unsigned long *) 0x420C0180) +#define GP0OCE_OCE0_MSK (0x1 << 0 ) +#define GP0OCE_OCE0 (0x1 << 0 ) +#define GP0OCE_OCE0_DIS (0x0 << 0 ) /* DIS */ +#define GP0OCE_OCE0_EN (0x1 << 0 ) /* EN */ + +/* Reset Value for GP0IN*/ +#define GP0IN_RVAL 0xFF + +/* GP0IN[IN7] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP0IN_IN7_BBA (*(volatile unsigned long *) 0x420C029C) +#define GP0IN_IN7_MSK (0x1 << 7 ) +#define GP0IN_IN7 (0x1 << 7 ) +#define GP0IN_IN7_LOW (0x0 << 7 ) /* LOW */ +#define GP0IN_IN7_HIGH (0x1 << 7 ) /* HIGH */ + +/* GP0IN[IN6] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP0IN_IN6_BBA (*(volatile unsigned long *) 0x420C0298) +#define GP0IN_IN6_MSK (0x1 << 6 ) +#define GP0IN_IN6 (0x1 << 6 ) +#define GP0IN_IN6_LOW (0x0 << 6 ) /* LOW */ +#define GP0IN_IN6_HIGH (0x1 << 6 ) /* HIGH */ + +/* GP0IN[IN5] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP0IN_IN5_BBA (*(volatile unsigned long *) 0x420C0294) +#define GP0IN_IN5_MSK (0x1 << 5 ) +#define GP0IN_IN5 (0x1 << 5 ) +#define GP0IN_IN5_LOW (0x0 << 5 ) /* LOW */ +#define GP0IN_IN5_HIGH (0x1 << 5 ) /* HIGH */ + +/* GP0IN[IN4] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP0IN_IN4_BBA (*(volatile unsigned long *) 0x420C0290) +#define GP0IN_IN4_MSK (0x1 << 4 ) +#define GP0IN_IN4 (0x1 << 4 ) +#define GP0IN_IN4_LOW (0x0 << 4 ) /* LOW */ +#define GP0IN_IN4_HIGH (0x1 << 4 ) /* HIGH */ + +/* GP0IN[IN3] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP0IN_IN3_BBA (*(volatile unsigned long *) 0x420C028C) +#define GP0IN_IN3_MSK (0x1 << 3 ) +#define GP0IN_IN3 (0x1 << 3 ) +#define GP0IN_IN3_LOW (0x0 << 3 ) /* LOW */ +#define GP0IN_IN3_HIGH (0x1 << 3 ) /* HIGH */ + +/* GP0IN[IN2] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP0IN_IN2_BBA (*(volatile unsigned long *) 0x420C0288) +#define GP0IN_IN2_MSK (0x1 << 2 ) +#define GP0IN_IN2 (0x1 << 2 ) +#define GP0IN_IN2_LOW (0x0 << 2 ) /* LOW */ +#define GP0IN_IN2_HIGH (0x1 << 2 ) /* HIGH */ + +/* GP0IN[IN1] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP0IN_IN1_BBA (*(volatile unsigned long *) 0x420C0284) +#define GP0IN_IN1_MSK (0x1 << 1 ) +#define GP0IN_IN1 (0x1 << 1 ) +#define GP0IN_IN1_LOW (0x0 << 1 ) /* LOW */ +#define GP0IN_IN1_HIGH (0x1 << 1 ) /* HIGH */ + +/* GP0IN[IN0] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP0IN_IN0_BBA (*(volatile unsigned long *) 0x420C0280) +#define GP0IN_IN0_MSK (0x1 << 0 ) +#define GP0IN_IN0 (0x1 << 0 ) +#define GP0IN_IN0_LOW (0x0 << 0 ) /* LOW */ +#define GP0IN_IN0_HIGH (0x1 << 0 ) /* HIGH */ + +/* Reset Value for GP0OUT*/ +#define GP0OUT_RVAL 0x0 + +/* GP0OUT[OUT7] - Data out register. */ +#define GP0OUT_OUT7_BBA (*(volatile unsigned long *) 0x420C031C) +#define GP0OUT_OUT7_MSK (0x1 << 7 ) +#define GP0OUT_OUT7 (0x1 << 7 ) +#define GP0OUT_OUT7_LOW (0x0 << 7 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP0OUT_OUT7_HIGH (0x1 << 7 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP0OUT[OUT6] - Data out register. */ +#define GP0OUT_OUT6_BBA (*(volatile unsigned long *) 0x420C0318) +#define GP0OUT_OUT6_MSK (0x1 << 6 ) +#define GP0OUT_OUT6 (0x1 << 6 ) +#define GP0OUT_OUT6_LOW (0x0 << 6 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP0OUT_OUT6_HIGH (0x1 << 6 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP0OUT[OUT5] - Data out register. */ +#define GP0OUT_OUT5_BBA (*(volatile unsigned long *) 0x420C0314) +#define GP0OUT_OUT5_MSK (0x1 << 5 ) +#define GP0OUT_OUT5 (0x1 << 5 ) +#define GP0OUT_OUT5_LOW (0x0 << 5 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP0OUT_OUT5_HIGH (0x1 << 5 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP0OUT[OUT4] - Data out register. */ +#define GP0OUT_OUT4_BBA (*(volatile unsigned long *) 0x420C0310) +#define GP0OUT_OUT4_MSK (0x1 << 4 ) +#define GP0OUT_OUT4 (0x1 << 4 ) +#define GP0OUT_OUT4_LOW (0x0 << 4 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP0OUT_OUT4_HIGH (0x1 << 4 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP0OUT[OUT3] - Data out register. */ +#define GP0OUT_OUT3_BBA (*(volatile unsigned long *) 0x420C030C) +#define GP0OUT_OUT3_MSK (0x1 << 3 ) +#define GP0OUT_OUT3 (0x1 << 3 ) +#define GP0OUT_OUT3_LOW (0x0 << 3 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP0OUT_OUT3_HIGH (0x1 << 3 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP0OUT[OUT2] - Data out register. */ +#define GP0OUT_OUT2_BBA (*(volatile unsigned long *) 0x420C0308) +#define GP0OUT_OUT2_MSK (0x1 << 2 ) +#define GP0OUT_OUT2 (0x1 << 2 ) +#define GP0OUT_OUT2_LOW (0x0 << 2 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP0OUT_OUT2_HIGH (0x1 << 2 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP0OUT[OUT1] - Data out register. */ +#define GP0OUT_OUT1_BBA (*(volatile unsigned long *) 0x420C0304) +#define GP0OUT_OUT1_MSK (0x1 << 1 ) +#define GP0OUT_OUT1 (0x1 << 1 ) +#define GP0OUT_OUT1_LOW (0x0 << 1 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP0OUT_OUT1_HIGH (0x1 << 1 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP0OUT[OUT0] - Data out register. */ +#define GP0OUT_OUT0_BBA (*(volatile unsigned long *) 0x420C0300) +#define GP0OUT_OUT0_MSK (0x1 << 0 ) +#define GP0OUT_OUT0 (0x1 << 0 ) +#define GP0OUT_OUT0_LOW (0x0 << 0 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP0OUT_OUT0_HIGH (0x1 << 0 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* Reset Value for GP0SET*/ +#define GP0SET_RVAL 0x0 + +/* GP0SET[SET7] - Set output high for corresponding port pin. */ +#define GP0SET_SET7_BBA (*(volatile unsigned long *) 0x420C039C) +#define GP0SET_SET7_MSK (0x1 << 7 ) +#define GP0SET_SET7 (0x1 << 7 ) +#define GP0SET_SET7_SET (0x1 << 7 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP0SET[SET6] - Set output high for corresponding port pin. */ +#define GP0SET_SET6_BBA (*(volatile unsigned long *) 0x420C0398) +#define GP0SET_SET6_MSK (0x1 << 6 ) +#define GP0SET_SET6 (0x1 << 6 ) +#define GP0SET_SET6_SET (0x1 << 6 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP0SET[SET5] - Set output high for corresponding port pin. */ +#define GP0SET_SET5_BBA (*(volatile unsigned long *) 0x420C0394) +#define GP0SET_SET5_MSK (0x1 << 5 ) +#define GP0SET_SET5 (0x1 << 5 ) +#define GP0SET_SET5_SET (0x1 << 5 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP0SET[SET4] - Set output high for corresponding port pin. */ +#define GP0SET_SET4_BBA (*(volatile unsigned long *) 0x420C0390) +#define GP0SET_SET4_MSK (0x1 << 4 ) +#define GP0SET_SET4 (0x1 << 4 ) +#define GP0SET_SET4_SET (0x1 << 4 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP0SET[SET3] - Set output high for corresponding port pin. */ +#define GP0SET_SET3_BBA (*(volatile unsigned long *) 0x420C038C) +#define GP0SET_SET3_MSK (0x1 << 3 ) +#define GP0SET_SET3 (0x1 << 3 ) +#define GP0SET_SET3_SET (0x1 << 3 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP0SET[SET2] - Set output high for corresponding port pin. */ +#define GP0SET_SET2_BBA (*(volatile unsigned long *) 0x420C0388) +#define GP0SET_SET2_MSK (0x1 << 2 ) +#define GP0SET_SET2 (0x1 << 2 ) +#define GP0SET_SET2_SET (0x1 << 2 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP0SET[SET1] - Set output high for corresponding port pin. */ +#define GP0SET_SET1_BBA (*(volatile unsigned long *) 0x420C0384) +#define GP0SET_SET1_MSK (0x1 << 1 ) +#define GP0SET_SET1 (0x1 << 1 ) +#define GP0SET_SET1_SET (0x1 << 1 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP0SET[SET0] - Set output high for corresponding port pin. */ +#define GP0SET_SET0_BBA (*(volatile unsigned long *) 0x420C0380) +#define GP0SET_SET0_MSK (0x1 << 0 ) +#define GP0SET_SET0 (0x1 << 0 ) +#define GP0SET_SET0_SET (0x1 << 0 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* Reset Value for GP0CLR*/ +#define GP0CLR_RVAL 0x0 + +/* GP0CLR[CLR7] - Set by user code to drive the corresponding GPIO low. */ +#define GP0CLR_CLR7_BBA (*(volatile unsigned long *) 0x420C041C) +#define GP0CLR_CLR7_MSK (0x1 << 7 ) +#define GP0CLR_CLR7 (0x1 << 7 ) +#define GP0CLR_CLR7_CLR (0x1 << 7 ) /* CLR */ + +/* GP0CLR[CLR6] - Set by user code to drive the corresponding GPIO low. */ +#define GP0CLR_CLR6_BBA (*(volatile unsigned long *) 0x420C0418) +#define GP0CLR_CLR6_MSK (0x1 << 6 ) +#define GP0CLR_CLR6 (0x1 << 6 ) +#define GP0CLR_CLR6_CLR (0x1 << 6 ) /* CLR */ + +/* GP0CLR[CLR5] - Set by user code to drive the corresponding GPIO low. */ +#define GP0CLR_CLR5_BBA (*(volatile unsigned long *) 0x420C0414) +#define GP0CLR_CLR5_MSK (0x1 << 5 ) +#define GP0CLR_CLR5 (0x1 << 5 ) +#define GP0CLR_CLR5_CLR (0x1 << 5 ) /* CLR */ + +/* GP0CLR[CLR4] - Set by user code to drive the corresponding GPIO low. */ +#define GP0CLR_CLR4_BBA (*(volatile unsigned long *) 0x420C0410) +#define GP0CLR_CLR4_MSK (0x1 << 4 ) +#define GP0CLR_CLR4 (0x1 << 4 ) +#define GP0CLR_CLR4_CLR (0x1 << 4 ) /* CLR */ + +/* GP0CLR[CLR3] - Set by user code to drive the corresponding GPIO low. */ +#define GP0CLR_CLR3_BBA (*(volatile unsigned long *) 0x420C040C) +#define GP0CLR_CLR3_MSK (0x1 << 3 ) +#define GP0CLR_CLR3 (0x1 << 3 ) +#define GP0CLR_CLR3_CLR (0x1 << 3 ) /* CLR */ + +/* GP0CLR[CLR2] - Set by user code to drive the corresponding GPIO low. */ +#define GP0CLR_CLR2_BBA (*(volatile unsigned long *) 0x420C0408) +#define GP0CLR_CLR2_MSK (0x1 << 2 ) +#define GP0CLR_CLR2 (0x1 << 2 ) +#define GP0CLR_CLR2_CLR (0x1 << 2 ) /* CLR */ + +/* GP0CLR[CLR1] - Set by user code to drive the corresponding GPIO low. */ +#define GP0CLR_CLR1_BBA (*(volatile unsigned long *) 0x420C0404) +#define GP0CLR_CLR1_MSK (0x1 << 1 ) +#define GP0CLR_CLR1 (0x1 << 1 ) +#define GP0CLR_CLR1_CLR (0x1 << 1 ) /* CLR */ + +/* GP0CLR[CLR0] - Set by user code to drive the corresponding GPIO low. */ +#define GP0CLR_CLR0_BBA (*(volatile unsigned long *) 0x420C0400) +#define GP0CLR_CLR0_MSK (0x1 << 0 ) +#define GP0CLR_CLR0 (0x1 << 0 ) +#define GP0CLR_CLR0_CLR (0x1 << 0 ) /* CLR */ + +/* Reset Value for GP0TGL*/ +#define GP0TGL_RVAL 0x0 + +/* GP0TGL[TGL7] - Toggle for corresponding port pin. */ +#define GP0TGL_TGL7_BBA (*(volatile unsigned long *) 0x420C049C) +#define GP0TGL_TGL7_MSK (0x1 << 7 ) +#define GP0TGL_TGL7 (0x1 << 7 ) +#define GP0TGL_TGL7_TGL (0x1 << 7 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP0TGL[TGL6] - Toggle for corresponding port pin. */ +#define GP0TGL_TGL6_BBA (*(volatile unsigned long *) 0x420C0498) +#define GP0TGL_TGL6_MSK (0x1 << 6 ) +#define GP0TGL_TGL6 (0x1 << 6 ) +#define GP0TGL_TGL6_TGL (0x1 << 6 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP0TGL[TGL5] - Toggle for corresponding port pin. */ +#define GP0TGL_TGL5_BBA (*(volatile unsigned long *) 0x420C0494) +#define GP0TGL_TGL5_MSK (0x1 << 5 ) +#define GP0TGL_TGL5 (0x1 << 5 ) +#define GP0TGL_TGL5_TGL (0x1 << 5 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP0TGL[TGL4] - Toggle for corresponding port pin. */ +#define GP0TGL_TGL4_BBA (*(volatile unsigned long *) 0x420C0490) +#define GP0TGL_TGL4_MSK (0x1 << 4 ) +#define GP0TGL_TGL4 (0x1 << 4 ) +#define GP0TGL_TGL4_TGL (0x1 << 4 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP0TGL[TGL3] - Toggle for corresponding port pin. */ +#define GP0TGL_TGL3_BBA (*(volatile unsigned long *) 0x420C048C) +#define GP0TGL_TGL3_MSK (0x1 << 3 ) +#define GP0TGL_TGL3 (0x1 << 3 ) +#define GP0TGL_TGL3_TGL (0x1 << 3 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP0TGL[TGL2] - Toggle for corresponding port pin. */ +#define GP0TGL_TGL2_BBA (*(volatile unsigned long *) 0x420C0488) +#define GP0TGL_TGL2_MSK (0x1 << 2 ) +#define GP0TGL_TGL2 (0x1 << 2 ) +#define GP0TGL_TGL2_TGL (0x1 << 2 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP0TGL[TGL1] - Toggle for corresponding port pin. */ +#define GP0TGL_TGL1_BBA (*(volatile unsigned long *) 0x420C0484) +#define GP0TGL_TGL1_MSK (0x1 << 1 ) +#define GP0TGL_TGL1 (0x1 << 1 ) +#define GP0TGL_TGL1_TGL (0x1 << 1 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP0TGL[TGL0] - Toggle for corresponding port pin. */ +#define GP0TGL_TGL0_BBA (*(volatile unsigned long *) 0x420C0480) +#define GP0TGL_TGL0_MSK (0x1 << 0 ) +#define GP0TGL_TGL0 (0x1 << 0 ) +#define GP0TGL_TGL0_TGL (0x1 << 0 ) /* TGL. Set by user code to invert the corresponding GPIO. */ +#if (__NO_MMR_STRUCTS__==1) + +#define GP1CON (*(volatile unsigned short int *) 0x40006030) +#define GP1OEN (*(volatile unsigned char *) 0x40006034) +#define GP1PUL (*(volatile unsigned char *) 0x40006038) +#define GP1OCE (*(volatile unsigned char *) 0x4000603C) +#define GP1IN (*(volatile unsigned char *) 0x40006044) +#define GP1OUT (*(volatile unsigned char *) 0x40006048) +#define GP1SET (*(volatile unsigned char *) 0x4000604C) +#define GP1CLR (*(volatile unsigned char *) 0x40006050) +#define GP1TGL (*(volatile unsigned char *) 0x40006054) +#endif // (__NO_MMR_STRUCTS__==1) + +/* Reset Value for GP1CON*/ +#define GP1CON_RVAL 0x0 + +/* GP1CON[CON6] - Configuration bits for P1.6 */ +#define GP1CON_CON6_MSK (0x3 << 12 ) +#define GP1CON_CON6_GPIO (0x0 << 12 ) /* GPIO */ +#define GP1CON_CON6_ADCCONVST (0x1 << 12 ) /* ADCCONVST */ +#define GP1CON_CON6_PWMSYNC (0x3 << 12 ) /* PWMSYNC */ + +/* GP1CON[CON5] - Configuration bits for P1.5 */ +#define GP1CON_CON5_MSK (0x3 << 10 ) +#define GP1CON_CON5_GPIOIRQ6 (0x0 << 10 ) /* GPIOIRQ6 */ +#define GP1CON_CON5_I2C0SDA (0x1 << 10 ) /* I2C0SDA */ +#define GP1CON_CON5_PWM7 (0x2 << 10 ) /* PWM7 */ + +/* GP1CON[CON4] - Configuration bits for P1.4 */ +#define GP1CON_CON4_MSK (0x3 << 8 ) +#define GP1CON_CON4_GPIOIRQ5 (0x0 << 8 ) /* GPIOIRQ5 */ +#define GP1CON_CON4_I2C0SCL (0x1 << 8 ) /* I2C0SCL */ +#define GP1CON_CON4_PWM6 (0x2 << 8 ) /* PWM6 */ + +/* GP1CON[CON3] - Configuration bits for P1.3 */ +#define GP1CON_CON3_MSK (0x3 << 6 ) +#define GP1CON_CON3_GPIO (0x1 << 6 ) /* GPIO */ +#define GP1CON_CON3_PWM5 (0x3 << 6 ) /* PWM5 */ + +/* GP1CON[CON2] - Configuration bits for P1.2 */ +#define GP1CON_CON2_MSK (0x3 << 4 ) +#define GP1CON_CON2_GPIO (0x1 << 4 ) /* GPIO */ +#define GP1CON_CON2_PWM4 (0x3 << 4 ) /* PWM4 */ + +/* GP1CON[CON1] - Configuration bits for P1.1 */ +#define GP1CON_CON1_MSK (0x3 << 2 ) +#define GP1CON_CON1_PORB (0x0 << 2 ) /* PORB */ +#define GP1CON_CON1_GPIO (0x1 << 2 ) /* GPIO */ +#define GP1CON_CON1_UART0TXD (0x2 << 2 ) /* UART0TXD */ +#define GP1CON_CON1_PWM3 (0x3 << 2 ) /* PWM3 */ + +/* GP1CON[CON0] - Configuration bits for P1.0 */ +#define GP1CON_CON0_MSK (0x3 << 0 ) +#define GP1CON_CON0_GPIOIRQ4 (0x0 << 0 ) /* GPIOIRQ4 */ +#define GP1CON_CON0_UART0RXD (0x1 << 0 ) /* UART0RXD */ +#define GP1CON_CON0_SPI1MOSI (0x2 << 0 ) /* SPI1MOSI */ +#define GP1CON_CON0_PWM2 (0x3 << 0 ) /* PWM2 */ + +/* Reset Value for GP1OEN*/ +#define GP1OEN_RVAL 0x0 + +/* GP1OEN[OEN6] - Port pin direction. */ +#define GP1OEN_OEN6_BBA (*(volatile unsigned long *) 0x420C0698) +#define GP1OEN_OEN6_MSK (0x1 << 6 ) +#define GP1OEN_OEN6 (0x1 << 6 ) +#define GP1OEN_OEN6_IN (0x0 << 6 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP1OEN_OEN6_OUT (0x1 << 6 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP1OEN[OEN5] - Port pin direction. */ +#define GP1OEN_OEN5_BBA (*(volatile unsigned long *) 0x420C0694) +#define GP1OEN_OEN5_MSK (0x1 << 5 ) +#define GP1OEN_OEN5 (0x1 << 5 ) +#define GP1OEN_OEN5_IN (0x0 << 5 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP1OEN_OEN5_OUT (0x1 << 5 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP1OEN[OEN4] - Port pin direction. */ +#define GP1OEN_OEN4_BBA (*(volatile unsigned long *) 0x420C0690) +#define GP1OEN_OEN4_MSK (0x1 << 4 ) +#define GP1OEN_OEN4 (0x1 << 4 ) +#define GP1OEN_OEN4_IN (0x0 << 4 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP1OEN_OEN4_OUT (0x1 << 4 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP1OEN[OEN3] - Port pin direction. */ +#define GP1OEN_OEN3_BBA (*(volatile unsigned long *) 0x420C068C) +#define GP1OEN_OEN3_MSK (0x1 << 3 ) +#define GP1OEN_OEN3 (0x1 << 3 ) +#define GP1OEN_OEN3_IN (0x0 << 3 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP1OEN_OEN3_OUT (0x1 << 3 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP1OEN[OEN2] - Port pin direction. */ +#define GP1OEN_OEN2_BBA (*(volatile unsigned long *) 0x420C0688) +#define GP1OEN_OEN2_MSK (0x1 << 2 ) +#define GP1OEN_OEN2 (0x1 << 2 ) +#define GP1OEN_OEN2_IN (0x0 << 2 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP1OEN_OEN2_OUT (0x1 << 2 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP1OEN[OEN1] - Port pin direction. */ +#define GP1OEN_OEN1_BBA (*(volatile unsigned long *) 0x420C0684) +#define GP1OEN_OEN1_MSK (0x1 << 1 ) +#define GP1OEN_OEN1 (0x1 << 1 ) +#define GP1OEN_OEN1_IN (0x0 << 1 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP1OEN_OEN1_OUT (0x1 << 1 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP1OEN[OEN0] - Port pin direction. */ +#define GP1OEN_OEN0_BBA (*(volatile unsigned long *) 0x420C0680) +#define GP1OEN_OEN0_MSK (0x1 << 0 ) +#define GP1OEN_OEN0 (0x1 << 0 ) +#define GP1OEN_OEN0_IN (0x0 << 0 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP1OEN_OEN0_OUT (0x1 << 0 ) /* OUT. Enables the output on corresponding port pin.. */ + +/* Reset Value for GP1PUL*/ +#define GP1PUL_RVAL 0x7F + +/* GP1PUL[PUL6] - Pull Up Enable for port pin. */ +#define GP1PUL_PUL6_BBA (*(volatile unsigned long *) 0x420C0718) +#define GP1PUL_PUL6_MSK (0x1 << 6 ) +#define GP1PUL_PUL6 (0x1 << 6 ) +#define GP1PUL_PUL6_DIS (0x0 << 6 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP1PUL_PUL6_EN (0x1 << 6 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP1PUL[PUL5] - Pull Up Enable for port pin. */ +#define GP1PUL_PUL5_BBA (*(volatile unsigned long *) 0x420C0714) +#define GP1PUL_PUL5_MSK (0x1 << 5 ) +#define GP1PUL_PUL5 (0x1 << 5 ) +#define GP1PUL_PUL5_DIS (0x0 << 5 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP1PUL_PUL5_EN (0x1 << 5 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP1PUL[PUL4] - Pull Up Enable for port pin. */ +#define GP1PUL_PUL4_BBA (*(volatile unsigned long *) 0x420C0710) +#define GP1PUL_PUL4_MSK (0x1 << 4 ) +#define GP1PUL_PUL4 (0x1 << 4 ) +#define GP1PUL_PUL4_DIS (0x0 << 4 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP1PUL_PUL4_EN (0x1 << 4 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP1PUL[PUL3] - Pull Up Enable for port pin. */ +#define GP1PUL_PUL3_BBA (*(volatile unsigned long *) 0x420C070C) +#define GP1PUL_PUL3_MSK (0x1 << 3 ) +#define GP1PUL_PUL3 (0x1 << 3 ) +#define GP1PUL_PUL3_DIS (0x0 << 3 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP1PUL_PUL3_EN (0x1 << 3 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP1PUL[PUL2] - Pull Up Enable for port pin. */ +#define GP1PUL_PUL2_BBA (*(volatile unsigned long *) 0x420C0708) +#define GP1PUL_PUL2_MSK (0x1 << 2 ) +#define GP1PUL_PUL2 (0x1 << 2 ) +#define GP1PUL_PUL2_DIS (0x0 << 2 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP1PUL_PUL2_EN (0x1 << 2 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP1PUL[PUL1] - Pull Up Enable for port pin. */ +#define GP1PUL_PUL1_BBA (*(volatile unsigned long *) 0x420C0704) +#define GP1PUL_PUL1_MSK (0x1 << 1 ) +#define GP1PUL_PUL1 (0x1 << 1 ) +#define GP1PUL_PUL1_DIS (0x0 << 1 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP1PUL_PUL1_EN (0x1 << 1 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP1PUL[PUL0] - Pull Up Enable for port pin. */ +#define GP1PUL_PUL0_BBA (*(volatile unsigned long *) 0x420C0700) +#define GP1PUL_PUL0_MSK (0x1 << 0 ) +#define GP1PUL_PUL0 (0x1 << 0 ) +#define GP1PUL_PUL0_DIS (0x0 << 0 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP1PUL_PUL0_EN (0x1 << 0 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* Reset Value for GP1OCE*/ +#define GP1OCE_RVAL 0x0 + +/* GP1OCE[OCE6] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP1OCE_OCE6_BBA (*(volatile unsigned long *) 0x420C0798) +#define GP1OCE_OCE6_MSK (0x1 << 6 ) +#define GP1OCE_OCE6 (0x1 << 6 ) +#define GP1OCE_OCE6_DIS (0x0 << 6 ) /* DIS */ +#define GP1OCE_OCE6_EN (0x1 << 6 ) /* EN */ + +/* GP1OCE[OCE5] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP1OCE_OCE5_BBA (*(volatile unsigned long *) 0x420C0794) +#define GP1OCE_OCE5_MSK (0x1 << 5 ) +#define GP1OCE_OCE5 (0x1 << 5 ) +#define GP1OCE_OCE5_DIS (0x0 << 5 ) /* DIS */ +#define GP1OCE_OCE5_EN (0x1 << 5 ) /* EN */ + +/* GP1OCE[OCE4] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP1OCE_OCE4_BBA (*(volatile unsigned long *) 0x420C0790) +#define GP1OCE_OCE4_MSK (0x1 << 4 ) +#define GP1OCE_OCE4 (0x1 << 4 ) +#define GP1OCE_OCE4_DIS (0x0 << 4 ) /* DIS */ +#define GP1OCE_OCE4_EN (0x1 << 4 ) /* EN */ + +/* GP1OCE[OCE3] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP1OCE_OCE3_BBA (*(volatile unsigned long *) 0x420C078C) +#define GP1OCE_OCE3_MSK (0x1 << 3 ) +#define GP1OCE_OCE3 (0x1 << 3 ) +#define GP1OCE_OCE3_DIS (0x0 << 3 ) /* DIS */ +#define GP1OCE_OCE3_EN (0x1 << 3 ) /* EN */ + +/* GP1OCE[OCE2] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP1OCE_OCE2_BBA (*(volatile unsigned long *) 0x420C0788) +#define GP1OCE_OCE2_MSK (0x1 << 2 ) +#define GP1OCE_OCE2 (0x1 << 2 ) +#define GP1OCE_OCE2_DIS (0x0 << 2 ) /* DIS */ +#define GP1OCE_OCE2_EN (0x1 << 2 ) /* EN */ + +/* GP1OCE[OCE1] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP1OCE_OCE1_BBA (*(volatile unsigned long *) 0x420C0784) +#define GP1OCE_OCE1_MSK (0x1 << 1 ) +#define GP1OCE_OCE1 (0x1 << 1 ) +#define GP1OCE_OCE1_DIS (0x0 << 1 ) /* DIS */ +#define GP1OCE_OCE1_EN (0x1 << 1 ) /* EN */ + +/* GP1OCE[OCE0] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP1OCE_OCE0_BBA (*(volatile unsigned long *) 0x420C0780) +#define GP1OCE_OCE0_MSK (0x1 << 0 ) +#define GP1OCE_OCE0 (0x1 << 0 ) +#define GP1OCE_OCE0_DIS (0x0 << 0 ) /* DIS */ +#define GP1OCE_OCE0_EN (0x1 << 0 ) /* EN */ + +/* Reset Value for GP1IN*/ +#define GP1IN_RVAL 0x7F + +/* GP1IN[IN6] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP1IN_IN6_BBA (*(volatile unsigned long *) 0x420C0898) +#define GP1IN_IN6_MSK (0x1 << 6 ) +#define GP1IN_IN6 (0x1 << 6 ) +#define GP1IN_IN6_LOW (0x0 << 6 ) /* LOW */ +#define GP1IN_IN6_HIGH (0x1 << 6 ) /* HIGH */ + +/* GP1IN[IN5] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP1IN_IN5_BBA (*(volatile unsigned long *) 0x420C0894) +#define GP1IN_IN5_MSK (0x1 << 5 ) +#define GP1IN_IN5 (0x1 << 5 ) +#define GP1IN_IN5_LOW (0x0 << 5 ) /* LOW */ +#define GP1IN_IN5_HIGH (0x1 << 5 ) /* HIGH */ + +/* GP1IN[IN4] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP1IN_IN4_BBA (*(volatile unsigned long *) 0x420C0890) +#define GP1IN_IN4_MSK (0x1 << 4 ) +#define GP1IN_IN4 (0x1 << 4 ) +#define GP1IN_IN4_LOW (0x0 << 4 ) /* LOW */ +#define GP1IN_IN4_HIGH (0x1 << 4 ) /* HIGH */ + +/* GP1IN[IN3] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP1IN_IN3_BBA (*(volatile unsigned long *) 0x420C088C) +#define GP1IN_IN3_MSK (0x1 << 3 ) +#define GP1IN_IN3 (0x1 << 3 ) +#define GP1IN_IN3_LOW (0x0 << 3 ) /* LOW */ +#define GP1IN_IN3_HIGH (0x1 << 3 ) /* HIGH */ + +/* GP1IN[IN2] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP1IN_IN2_BBA (*(volatile unsigned long *) 0x420C0888) +#define GP1IN_IN2_MSK (0x1 << 2 ) +#define GP1IN_IN2 (0x1 << 2 ) +#define GP1IN_IN2_LOW (0x0 << 2 ) /* LOW */ +#define GP1IN_IN2_HIGH (0x1 << 2 ) /* HIGH */ + +/* GP1IN[IN1] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP1IN_IN1_BBA (*(volatile unsigned long *) 0x420C0884) +#define GP1IN_IN1_MSK (0x1 << 1 ) +#define GP1IN_IN1 (0x1 << 1 ) +#define GP1IN_IN1_LOW (0x0 << 1 ) /* LOW */ +#define GP1IN_IN1_HIGH (0x1 << 1 ) /* HIGH */ + +/* GP1IN[IN0] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP1IN_IN0_BBA (*(volatile unsigned long *) 0x420C0880) +#define GP1IN_IN0_MSK (0x1 << 0 ) +#define GP1IN_IN0 (0x1 << 0 ) +#define GP1IN_IN0_LOW (0x0 << 0 ) /* LOW */ +#define GP1IN_IN0_HIGH (0x1 << 0 ) /* HIGH */ + +/* Reset Value for GP1OUT*/ +#define GP1OUT_RVAL 0x0 + +/* GP1OUT[OUT6] - Output for port pin. */ +#define GP1OUT_OUT6_BBA (*(volatile unsigned long *) 0x420C0918) +#define GP1OUT_OUT6_MSK (0x1 << 6 ) +#define GP1OUT_OUT6 (0x1 << 6 ) +#define GP1OUT_OUT6_LOW (0x0 << 6 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP1OUT_OUT6_HIGH (0x1 << 6 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP1OUT[OUT5] - Output for port pin. */ +#define GP1OUT_OUT5_BBA (*(volatile unsigned long *) 0x420C0914) +#define GP1OUT_OUT5_MSK (0x1 << 5 ) +#define GP1OUT_OUT5 (0x1 << 5 ) +#define GP1OUT_OUT5_LOW (0x0 << 5 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP1OUT_OUT5_HIGH (0x1 << 5 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP1OUT[OUT4] - Output for port pin. */ +#define GP1OUT_OUT4_BBA (*(volatile unsigned long *) 0x420C0910) +#define GP1OUT_OUT4_MSK (0x1 << 4 ) +#define GP1OUT_OUT4 (0x1 << 4 ) +#define GP1OUT_OUT4_LOW (0x0 << 4 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP1OUT_OUT4_HIGH (0x1 << 4 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP1OUT[OUT3] - Output for port pin. */ +#define GP1OUT_OUT3_BBA (*(volatile unsigned long *) 0x420C090C) +#define GP1OUT_OUT3_MSK (0x1 << 3 ) +#define GP1OUT_OUT3 (0x1 << 3 ) +#define GP1OUT_OUT3_LOW (0x0 << 3 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP1OUT_OUT3_HIGH (0x1 << 3 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP1OUT[OUT2] - Output for port pin. */ +#define GP1OUT_OUT2_BBA (*(volatile unsigned long *) 0x420C0908) +#define GP1OUT_OUT2_MSK (0x1 << 2 ) +#define GP1OUT_OUT2 (0x1 << 2 ) +#define GP1OUT_OUT2_LOW (0x0 << 2 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP1OUT_OUT2_HIGH (0x1 << 2 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP1OUT[OUT1] - Output for port pin. */ +#define GP1OUT_OUT1_BBA (*(volatile unsigned long *) 0x420C0904) +#define GP1OUT_OUT1_MSK (0x1 << 1 ) +#define GP1OUT_OUT1 (0x1 << 1 ) +#define GP1OUT_OUT1_LOW (0x0 << 1 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP1OUT_OUT1_HIGH (0x1 << 1 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP1OUT[OUT0] - Output for port pin. */ +#define GP1OUT_OUT0_BBA (*(volatile unsigned long *) 0x420C0900) +#define GP1OUT_OUT0_MSK (0x1 << 0 ) +#define GP1OUT_OUT0 (0x1 << 0 ) +#define GP1OUT_OUT0_LOW (0x0 << 0 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP1OUT_OUT0_HIGH (0x1 << 0 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* Reset Value for GP1SET*/ +#define GP1SET_RVAL 0x0 + +/* GP1SET[SET6] - Set output high for corresponding port pin. */ +#define GP1SET_SET6_BBA (*(volatile unsigned long *) 0x420C0998) +#define GP1SET_SET6_MSK (0x1 << 6 ) +#define GP1SET_SET6 (0x1 << 6 ) +#define GP1SET_SET6_SET (0x1 << 6 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP1SET[SET5] - Set output high for corresponding port pin. */ +#define GP1SET_SET5_BBA (*(volatile unsigned long *) 0x420C0994) +#define GP1SET_SET5_MSK (0x1 << 5 ) +#define GP1SET_SET5 (0x1 << 5 ) +#define GP1SET_SET5_SET (0x1 << 5 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP1SET[SET4] - Set output high for corresponding port pin. */ +#define GP1SET_SET4_BBA (*(volatile unsigned long *) 0x420C0990) +#define GP1SET_SET4_MSK (0x1 << 4 ) +#define GP1SET_SET4 (0x1 << 4 ) +#define GP1SET_SET4_SET (0x1 << 4 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP1SET[SET3] - Set output high for corresponding port pin. */ +#define GP1SET_SET3_BBA (*(volatile unsigned long *) 0x420C098C) +#define GP1SET_SET3_MSK (0x1 << 3 ) +#define GP1SET_SET3 (0x1 << 3 ) +#define GP1SET_SET3_SET (0x1 << 3 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP1SET[SET2] - Set output high for corresponding port pin. */ +#define GP1SET_SET2_BBA (*(volatile unsigned long *) 0x420C0988) +#define GP1SET_SET2_MSK (0x1 << 2 ) +#define GP1SET_SET2 (0x1 << 2 ) +#define GP1SET_SET2_SET (0x1 << 2 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP1SET[SET1] - Set output high for corresponding port pin. */ +#define GP1SET_SET1_BBA (*(volatile unsigned long *) 0x420C0984) +#define GP1SET_SET1_MSK (0x1 << 1 ) +#define GP1SET_SET1 (0x1 << 1 ) +#define GP1SET_SET1_SET (0x1 << 1 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP1SET[SET0] - Set output high for corresponding port pin. */ +#define GP1SET_SET0_BBA (*(volatile unsigned long *) 0x420C0980) +#define GP1SET_SET0_MSK (0x1 << 0 ) +#define GP1SET_SET0 (0x1 << 0 ) +#define GP1SET_SET0_SET (0x1 << 0 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* Reset Value for GP1CLR*/ +#define GP1CLR_RVAL 0x0 + +/* GP1CLR[CLR6] - Set by user code to drive the corresponding GPIO low. */ +#define GP1CLR_CLR6_BBA (*(volatile unsigned long *) 0x420C0A18) +#define GP1CLR_CLR6_MSK (0x1 << 6 ) +#define GP1CLR_CLR6 (0x1 << 6 ) +#define GP1CLR_CLR6_CLR (0x1 << 6 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP1CLR[CLR5] - Set by user code to drive the corresponding GPIO low. */ +#define GP1CLR_CLR5_BBA (*(volatile unsigned long *) 0x420C0A14) +#define GP1CLR_CLR5_MSK (0x1 << 5 ) +#define GP1CLR_CLR5 (0x1 << 5 ) +#define GP1CLR_CLR5_CLR (0x1 << 5 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP1CLR[CLR4] - Set by user code to drive the corresponding GPIO low. */ +#define GP1CLR_CLR4_BBA (*(volatile unsigned long *) 0x420C0A10) +#define GP1CLR_CLR4_MSK (0x1 << 4 ) +#define GP1CLR_CLR4 (0x1 << 4 ) +#define GP1CLR_CLR4_CLR (0x1 << 4 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP1CLR[CLR3] - Set by user code to drive the corresponding GPIO low. */ +#define GP1CLR_CLR3_BBA (*(volatile unsigned long *) 0x420C0A0C) +#define GP1CLR_CLR3_MSK (0x1 << 3 ) +#define GP1CLR_CLR3 (0x1 << 3 ) +#define GP1CLR_CLR3_CLR (0x1 << 3 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP1CLR[CLR2] - Set by user code to drive the corresponding GPIO low. */ +#define GP1CLR_CLR2_BBA (*(volatile unsigned long *) 0x420C0A08) +#define GP1CLR_CLR2_MSK (0x1 << 2 ) +#define GP1CLR_CLR2 (0x1 << 2 ) +#define GP1CLR_CLR2_CLR (0x1 << 2 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP1CLR[CLR1] - Set by user code to drive the corresponding GPIO low. */ +#define GP1CLR_CLR1_BBA (*(volatile unsigned long *) 0x420C0A04) +#define GP1CLR_CLR1_MSK (0x1 << 1 ) +#define GP1CLR_CLR1 (0x1 << 1 ) +#define GP1CLR_CLR1_CLR (0x1 << 1 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP1CLR[CLR0] - Set by user code to drive the corresponding GPIO low. */ +#define GP1CLR_CLR0_BBA (*(volatile unsigned long *) 0x420C0A00) +#define GP1CLR_CLR0_MSK (0x1 << 0 ) +#define GP1CLR_CLR0 (0x1 << 0 ) +#define GP1CLR_CLR0_CLR (0x1 << 0 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* Reset Value for GP1TGL*/ +#define GP1TGL_RVAL 0x0 + +/* GP1TGL[TGL6] - Toggle for corresponding port pin. */ +#define GP1TGL_TGL6_BBA (*(volatile unsigned long *) 0x420C0A98) +#define GP1TGL_TGL6_MSK (0x1 << 6 ) +#define GP1TGL_TGL6 (0x1 << 6 ) +#define GP1TGL_TGL6_TGL (0x1 << 6 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP1TGL[TGL5] - Toggle for corresponding port pin. */ +#define GP1TGL_TGL5_BBA (*(volatile unsigned long *) 0x420C0A94) +#define GP1TGL_TGL5_MSK (0x1 << 5 ) +#define GP1TGL_TGL5 (0x1 << 5 ) +#define GP1TGL_TGL5_TGL (0x1 << 5 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP1TGL[TGL4] - Toggle for corresponding port pin. */ +#define GP1TGL_TGL4_BBA (*(volatile unsigned long *) 0x420C0A90) +#define GP1TGL_TGL4_MSK (0x1 << 4 ) +#define GP1TGL_TGL4 (0x1 << 4 ) +#define GP1TGL_TGL4_TGL (0x1 << 4 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP1TGL[TGL3] - Toggle for corresponding port pin. */ +#define GP1TGL_TGL3_BBA (*(volatile unsigned long *) 0x420C0A8C) +#define GP1TGL_TGL3_MSK (0x1 << 3 ) +#define GP1TGL_TGL3 (0x1 << 3 ) +#define GP1TGL_TGL3_TGL (0x1 << 3 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP1TGL[TGL2] - Toggle for corresponding port pin. */ +#define GP1TGL_TGL2_BBA (*(volatile unsigned long *) 0x420C0A88) +#define GP1TGL_TGL2_MSK (0x1 << 2 ) +#define GP1TGL_TGL2 (0x1 << 2 ) +#define GP1TGL_TGL2_TGL (0x1 << 2 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP1TGL[TGL1] - Toggle for corresponding port pin. */ +#define GP1TGL_TGL1_BBA (*(volatile unsigned long *) 0x420C0A84) +#define GP1TGL_TGL1_MSK (0x1 << 1 ) +#define GP1TGL_TGL1 (0x1 << 1 ) +#define GP1TGL_TGL1_TGL (0x1 << 1 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP1TGL[TGL0] - Toggle for corresponding port pin. */ +#define GP1TGL_TGL0_BBA (*(volatile unsigned long *) 0x420C0A80) +#define GP1TGL_TGL0_MSK (0x1 << 0 ) +#define GP1TGL_TGL0 (0x1 << 0 ) +#define GP1TGL_TGL0_TGL (0x1 << 0 ) /* TGL. Set by user code to invert the corresponding GPIO. */ +#if (__NO_MMR_STRUCTS__==1) + +#define GP2CON (*(volatile unsigned short int *) 0x40006060) +#define GP2OEN (*(volatile unsigned char *) 0x40006064) +#define GP2PUL (*(volatile unsigned char *) 0x40006068) +#define GP2OCE (*(volatile unsigned char *) 0x4000606C) +#define GP2IN (*(volatile unsigned char *) 0x40006074) +#define GP2OUT (*(volatile unsigned char *) 0x40006078) +#define GP2SET (*(volatile unsigned char *) 0x4000607C) +#define GP2CLR (*(volatile unsigned char *) 0x40006080) +#define GP2TGL (*(volatile unsigned char *) 0x40006084) +#endif // (__NO_MMR_STRUCTS__==1) + +/* Reset Value for GP2CON*/ +#define GP2CON_RVAL 0x0 + +/* GP2CON[CON7] - Configuration bits for P2.7 */ +#define GP2CON_CON7_MSK (0x3 << 14 ) +#define GP2CON_CON7_GPIOIRQ7 (0x0 << 14 ) /* GPIOIRQ7 */ + +/* GP2CON[CON6] - Configuration bits for P2.6 */ +#define GP2CON_CON6_MSK (0x3 << 12 ) +#define GP2CON_CON6_GPIO (0x1 << 12 ) /* GPIO */ + +/* GP2CON[CON5] - Configuration bits for P2.5 */ +#define GP2CON_CON5_MSK (0x3 << 10 ) +#define GP2CON_CON5_GPIO (0x2 << 10 ) /* GPIO */ +#define GP2CON_CON5_RF32KHZCLK (0x3 << 10 ) /* RF32KHZCLK */ + +/* GP2CON[CON4] - Configuration bits for P2.4 */ +#define GP2CON_CON4_MSK (0x3 << 8 ) +#define GP2CON_CON4_IRQ8 (0x0 << 8 ) /* IRQ8 */ +#define GP2CON_CON4_GPIO (0x1 << 8 ) /* GPIO */ + +/* GP2CON[CON3] - Configuration bits for P2.3 */ +#define GP2CON_CON3_MSK (0x3 << 6 ) +#define GP2CON_CON3_SPI0CS (0x0 << 6 ) /* SPI0CS */ +#define GP2CON_CON3_GPIO (0x1 << 6 ) /* GPIO */ + +/* GP2CON[CON2] - Configuration bits for P2.2 */ +#define GP2CON_CON2_MSK (0x3 << 4 ) +#define GP2CON_CON2_SPI0MOSI (0x0 << 4 ) /* SPI0MOSI */ +#define GP2CON_CON2_GPIO (0x1 << 4 ) /* GPIO */ + +/* GP2CON[CON1] - Configuration bits for P2.1 */ +#define GP2CON_CON1_MSK (0x3 << 2 ) +#define GP2CON_CON1_SPI0SCLK (0x0 << 2 ) /* SPI0SCLK */ +#define GP2CON_CON1_GPIO (0x1 << 2 ) /* GPIO */ + +/* GP2CON[CON0] - Configuration bits for P2.0 */ +#define GP2CON_CON0_MSK (0x3 << 0 ) +#define GP2CON_CON0_SPI0MISO (0x0 << 0 ) /* SPI0MISO */ +#define GP2CON_CON0_GPIO (0x1 << 0 ) /* GPIO */ + +/* Reset Value for GP2OEN*/ +#define GP2OEN_RVAL 0x0 + +/* GP2OEN[OEN7] - Port pin direction. */ +#define GP2OEN_OEN7_BBA (*(volatile unsigned long *) 0x420C0C9C) +#define GP2OEN_OEN7_MSK (0x1 << 7 ) +#define GP2OEN_OEN7 (0x1 << 7 ) +#define GP2OEN_OEN7_IN (0x0 << 7 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP2OEN_OEN7_OUT (0x1 << 7 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP2OEN[OEN6] - Port pin direction. */ +#define GP2OEN_OEN6_BBA (*(volatile unsigned long *) 0x420C0C98) +#define GP2OEN_OEN6_MSK (0x1 << 6 ) +#define GP2OEN_OEN6 (0x1 << 6 ) +#define GP2OEN_OEN6_IN (0x0 << 6 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP2OEN_OEN6_OUT (0x1 << 6 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP2OEN[OEN5] - Port pin direction. */ +#define GP2OEN_OEN5_BBA (*(volatile unsigned long *) 0x420C0C94) +#define GP2OEN_OEN5_MSK (0x1 << 5 ) +#define GP2OEN_OEN5 (0x1 << 5 ) +#define GP2OEN_OEN5_IN (0x0 << 5 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP2OEN_OEN5_OUT (0x1 << 5 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP2OEN[OEN4] - Port pin direction. */ +#define GP2OEN_OEN4_BBA (*(volatile unsigned long *) 0x420C0C90) +#define GP2OEN_OEN4_MSK (0x1 << 4 ) +#define GP2OEN_OEN4 (0x1 << 4 ) +#define GP2OEN_OEN4_IN (0x0 << 4 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP2OEN_OEN4_OUT (0x1 << 4 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP2OEN[OEN3] - Port pin direction. */ +#define GP2OEN_OEN3_BBA (*(volatile unsigned long *) 0x420C0C8C) +#define GP2OEN_OEN3_MSK (0x1 << 3 ) +#define GP2OEN_OEN3 (0x1 << 3 ) +#define GP2OEN_OEN3_IN (0x0 << 3 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP2OEN_OEN3_OUT (0x1 << 3 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP2OEN[OEN2] - Port pin direction. */ +#define GP2OEN_OEN2_BBA (*(volatile unsigned long *) 0x420C0C88) +#define GP2OEN_OEN2_MSK (0x1 << 2 ) +#define GP2OEN_OEN2 (0x1 << 2 ) +#define GP2OEN_OEN2_IN (0x0 << 2 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP2OEN_OEN2_OUT (0x1 << 2 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP2OEN[OEN1] - Port pin direction. */ +#define GP2OEN_OEN1_BBA (*(volatile unsigned long *) 0x420C0C84) +#define GP2OEN_OEN1_MSK (0x1 << 1 ) +#define GP2OEN_OEN1 (0x1 << 1 ) +#define GP2OEN_OEN1_IN (0x0 << 1 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP2OEN_OEN1_OUT (0x1 << 1 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP2OEN[OEN0] - Port pin direction. */ +#define GP2OEN_OEN0_BBA (*(volatile unsigned long *) 0x420C0C80) +#define GP2OEN_OEN0_MSK (0x1 << 0 ) +#define GP2OEN_OEN0 (0x1 << 0 ) +#define GP2OEN_OEN0_IN (0x0 << 0 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP2OEN_OEN0_OUT (0x1 << 0 ) /* OUT. Enables the output on corresponding port pin. */ + +/* Reset Value for GP2PUL*/ +#define GP2PUL_RVAL 0xFF + +/* GP2PUL[PUL7] - Pull Up Enable for port pin. */ +#define GP2PUL_PUL7_BBA (*(volatile unsigned long *) 0x420C0D1C) +#define GP2PUL_PUL7_MSK (0x1 << 7 ) +#define GP2PUL_PUL7 (0x1 << 7 ) +#define GP2PUL_PUL7_DIS (0x0 << 7 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP2PUL_PUL7_EN (0x1 << 7 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP2PUL[PUL6] - Pull Up Enable for port pin. */ +#define GP2PUL_PUL6_BBA (*(volatile unsigned long *) 0x420C0D18) +#define GP2PUL_PUL6_MSK (0x1 << 6 ) +#define GP2PUL_PUL6 (0x1 << 6 ) +#define GP2PUL_PUL6_DIS (0x0 << 6 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP2PUL_PUL6_EN (0x1 << 6 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP2PUL[PUL5] - Pull Up Enable for port pin. */ +#define GP2PUL_PUL5_BBA (*(volatile unsigned long *) 0x420C0D14) +#define GP2PUL_PUL5_MSK (0x1 << 5 ) +#define GP2PUL_PUL5 (0x1 << 5 ) +#define GP2PUL_PUL5_DIS (0x0 << 5 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP2PUL_PUL5_EN (0x1 << 5 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP2PUL[PUL4] - Pull Up Enable for port pin. */ +#define GP2PUL_PUL4_BBA (*(volatile unsigned long *) 0x420C0D10) +#define GP2PUL_PUL4_MSK (0x1 << 4 ) +#define GP2PUL_PUL4 (0x1 << 4 ) +#define GP2PUL_PUL4_DIS (0x0 << 4 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP2PUL_PUL4_EN (0x1 << 4 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP2PUL[PUL3] - Pull Up Enable for port pin. */ +#define GP2PUL_PUL3_BBA (*(volatile unsigned long *) 0x420C0D0C) +#define GP2PUL_PUL3_MSK (0x1 << 3 ) +#define GP2PUL_PUL3 (0x1 << 3 ) +#define GP2PUL_PUL3_DIS (0x0 << 3 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP2PUL_PUL3_EN (0x1 << 3 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP2PUL[PUL2] - Pull Up Enable for port pin. */ +#define GP2PUL_PUL2_BBA (*(volatile unsigned long *) 0x420C0D08) +#define GP2PUL_PUL2_MSK (0x1 << 2 ) +#define GP2PUL_PUL2 (0x1 << 2 ) +#define GP2PUL_PUL2_DIS (0x0 << 2 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP2PUL_PUL2_EN (0x1 << 2 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP2PUL[PUL1] - Pull Up Enable for port pin. */ +#define GP2PUL_PUL1_BBA (*(volatile unsigned long *) 0x420C0D04) +#define GP2PUL_PUL1_MSK (0x1 << 1 ) +#define GP2PUL_PUL1 (0x1 << 1 ) +#define GP2PUL_PUL1_DIS (0x0 << 1 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP2PUL_PUL1_EN (0x1 << 1 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP2PUL[PUL0] - Pull Up Enable for port pin. */ +#define GP2PUL_PUL0_BBA (*(volatile unsigned long *) 0x420C0D00) +#define GP2PUL_PUL0_MSK (0x1 << 0 ) +#define GP2PUL_PUL0 (0x1 << 0 ) +#define GP2PUL_PUL0_DIS (0x0 << 0 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP2PUL_PUL0_EN (0x1 << 0 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* Reset Value for GP2OCE*/ +#define GP2OCE_RVAL 0x0 + +/* GP2OCE[OCE7] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP2OCE_OCE7_BBA (*(volatile unsigned long *) 0x420C0D9C) +#define GP2OCE_OCE7_MSK (0x1 << 7 ) +#define GP2OCE_OCE7 (0x1 << 7 ) +#define GP2OCE_OCE7_DIS (0x0 << 7 ) /* DIS */ +#define GP2OCE_OCE7_EN (0x1 << 7 ) /* EN */ + +/* GP2OCE[OCE6] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP2OCE_OCE6_BBA (*(volatile unsigned long *) 0x420C0D98) +#define GP2OCE_OCE6_MSK (0x1 << 6 ) +#define GP2OCE_OCE6 (0x1 << 6 ) +#define GP2OCE_OCE6_DIS (0x0 << 6 ) /* DIS */ +#define GP2OCE_OCE6_EN (0x1 << 6 ) /* EN */ + +/* GP2OCE[OCE5] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP2OCE_OCE5_BBA (*(volatile unsigned long *) 0x420C0D94) +#define GP2OCE_OCE5_MSK (0x1 << 5 ) +#define GP2OCE_OCE5 (0x1 << 5 ) +#define GP2OCE_OCE5_DIS (0x0 << 5 ) /* DIS */ +#define GP2OCE_OCE5_EN (0x1 << 5 ) /* EN */ + +/* GP2OCE[OCE4] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP2OCE_OCE4_BBA (*(volatile unsigned long *) 0x420C0D90) +#define GP2OCE_OCE4_MSK (0x1 << 4 ) +#define GP2OCE_OCE4 (0x1 << 4 ) +#define GP2OCE_OCE4_DIS (0x0 << 4 ) /* DIS */ +#define GP2OCE_OCE4_EN (0x1 << 4 ) /* EN */ + +/* GP2OCE[OCE3] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP2OCE_OCE3_BBA (*(volatile unsigned long *) 0x420C0D8C) +#define GP2OCE_OCE3_MSK (0x1 << 3 ) +#define GP2OCE_OCE3 (0x1 << 3 ) +#define GP2OCE_OCE3_DIS (0x0 << 3 ) /* DIS */ +#define GP2OCE_OCE3_EN (0x1 << 3 ) /* EN */ + +/* GP2OCE[OCE2] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP2OCE_OCE2_BBA (*(volatile unsigned long *) 0x420C0D88) +#define GP2OCE_OCE2_MSK (0x1 << 2 ) +#define GP2OCE_OCE2 (0x1 << 2 ) +#define GP2OCE_OCE2_DIS (0x0 << 2 ) /* DIS */ +#define GP2OCE_OCE2_EN (0x1 << 2 ) /* EN */ + +/* GP2OCE[OCE1] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP2OCE_OCE1_BBA (*(volatile unsigned long *) 0x420C0D84) +#define GP2OCE_OCE1_MSK (0x1 << 1 ) +#define GP2OCE_OCE1 (0x1 << 1 ) +#define GP2OCE_OCE1_DIS (0x0 << 1 ) /* DIS */ +#define GP2OCE_OCE1_EN (0x1 << 1 ) /* EN */ + +/* GP2OCE[OCE0] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP2OCE_OCE0_BBA (*(volatile unsigned long *) 0x420C0D80) +#define GP2OCE_OCE0_MSK (0x1 << 0 ) +#define GP2OCE_OCE0 (0x1 << 0 ) +#define GP2OCE_OCE0_DIS (0x0 << 0 ) /* DIS */ +#define GP2OCE_OCE0_EN (0x1 << 0 ) /* EN */ + +/* Reset Value for GP2IN*/ +#define GP2IN_RVAL 0xFF + +/* GP2IN[IN7] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP2IN_IN7_BBA (*(volatile unsigned long *) 0x420C0E9C) +#define GP2IN_IN7_MSK (0x1 << 7 ) +#define GP2IN_IN7 (0x1 << 7 ) +#define GP2IN_IN7_LOW (0x0 << 7 ) /* LOW */ +#define GP2IN_IN7_HIGH (0x1 << 7 ) /* HIGH */ + +/* GP2IN[IN6] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP2IN_IN6_BBA (*(volatile unsigned long *) 0x420C0E98) +#define GP2IN_IN6_MSK (0x1 << 6 ) +#define GP2IN_IN6 (0x1 << 6 ) +#define GP2IN_IN6_LOW (0x0 << 6 ) /* LOW */ +#define GP2IN_IN6_HIGH (0x1 << 6 ) /* HIGH */ + +/* GP2IN[IN5] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP2IN_IN5_BBA (*(volatile unsigned long *) 0x420C0E94) +#define GP2IN_IN5_MSK (0x1 << 5 ) +#define GP2IN_IN5 (0x1 << 5 ) +#define GP2IN_IN5_LOW (0x0 << 5 ) /* LOW */ +#define GP2IN_IN5_HIGH (0x1 << 5 ) /* HIGH */ + +/* GP2IN[IN4] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP2IN_IN4_BBA (*(volatile unsigned long *) 0x420C0E90) +#define GP2IN_IN4_MSK (0x1 << 4 ) +#define GP2IN_IN4 (0x1 << 4 ) +#define GP2IN_IN4_LOW (0x0 << 4 ) /* LOW */ +#define GP2IN_IN4_HIGH (0x1 << 4 ) /* HIGH */ + +/* GP2IN[IN3] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP2IN_IN3_BBA (*(volatile unsigned long *) 0x420C0E8C) +#define GP2IN_IN3_MSK (0x1 << 3 ) +#define GP2IN_IN3 (0x1 << 3 ) +#define GP2IN_IN3_LOW (0x0 << 3 ) /* LOW */ +#define GP2IN_IN3_HIGH (0x1 << 3 ) /* HIGH */ + +/* GP2IN[IN2] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP2IN_IN2_BBA (*(volatile unsigned long *) 0x420C0E88) +#define GP2IN_IN2_MSK (0x1 << 2 ) +#define GP2IN_IN2 (0x1 << 2 ) +#define GP2IN_IN2_LOW (0x0 << 2 ) /* LOW */ +#define GP2IN_IN2_HIGH (0x1 << 2 ) /* HIGH */ + +/* GP2IN[IN1] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP2IN_IN1_BBA (*(volatile unsigned long *) 0x420C0E84) +#define GP2IN_IN1_MSK (0x1 << 1 ) +#define GP2IN_IN1 (0x1 << 1 ) +#define GP2IN_IN1_LOW (0x0 << 1 ) /* LOW */ +#define GP2IN_IN1_HIGH (0x1 << 1 ) /* HIGH */ + +/* GP2IN[IN0] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP2IN_IN0_BBA (*(volatile unsigned long *) 0x420C0E80) +#define GP2IN_IN0_MSK (0x1 << 0 ) +#define GP2IN_IN0 (0x1 << 0 ) +#define GP2IN_IN0_LOW (0x0 << 0 ) /* LOW */ +#define GP2IN_IN0_HIGH (0x1 << 0 ) /* HIGH */ + +/* Reset Value for GP2OUT*/ +#define GP2OUT_RVAL 0x0 + +/* GP2OUT[OUT7] - Output for port pin. */ +#define GP2OUT_OUT7_BBA (*(volatile unsigned long *) 0x420C0F1C) +#define GP2OUT_OUT7_MSK (0x1 << 7 ) +#define GP2OUT_OUT7 (0x1 << 7 ) +#define GP2OUT_OUT7_LOW (0x0 << 7 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP2OUT_OUT7_HIGH (0x1 << 7 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP2OUT[OUT6] - Output for port pin. */ +#define GP2OUT_OUT6_BBA (*(volatile unsigned long *) 0x420C0F18) +#define GP2OUT_OUT6_MSK (0x1 << 6 ) +#define GP2OUT_OUT6 (0x1 << 6 ) +#define GP2OUT_OUT6_LOW (0x0 << 6 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP2OUT_OUT6_HIGH (0x1 << 6 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP2OUT[OUT5] - Output for port pin. */ +#define GP2OUT_OUT5_BBA (*(volatile unsigned long *) 0x420C0F14) +#define GP2OUT_OUT5_MSK (0x1 << 5 ) +#define GP2OUT_OUT5 (0x1 << 5 ) +#define GP2OUT_OUT5_LOW (0x0 << 5 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP2OUT_OUT5_HIGH (0x1 << 5 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP2OUT[OUT4] - Output for port pin. */ +#define GP2OUT_OUT4_BBA (*(volatile unsigned long *) 0x420C0F10) +#define GP2OUT_OUT4_MSK (0x1 << 4 ) +#define GP2OUT_OUT4 (0x1 << 4 ) +#define GP2OUT_OUT4_LOW (0x0 << 4 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP2OUT_OUT4_HIGH (0x1 << 4 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP2OUT[OUT3] - Output for port pin. */ +#define GP2OUT_OUT3_BBA (*(volatile unsigned long *) 0x420C0F0C) +#define GP2OUT_OUT3_MSK (0x1 << 3 ) +#define GP2OUT_OUT3 (0x1 << 3 ) +#define GP2OUT_OUT3_LOW (0x0 << 3 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP2OUT_OUT3_HIGH (0x1 << 3 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP2OUT[OUT2] - Output for port pin. */ +#define GP2OUT_OUT2_BBA (*(volatile unsigned long *) 0x420C0F08) +#define GP2OUT_OUT2_MSK (0x1 << 2 ) +#define GP2OUT_OUT2 (0x1 << 2 ) +#define GP2OUT_OUT2_LOW (0x0 << 2 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP2OUT_OUT2_HIGH (0x1 << 2 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP2OUT[OUT1] - Output for port pin. */ +#define GP2OUT_OUT1_BBA (*(volatile unsigned long *) 0x420C0F04) +#define GP2OUT_OUT1_MSK (0x1 << 1 ) +#define GP2OUT_OUT1 (0x1 << 1 ) +#define GP2OUT_OUT1_LOW (0x0 << 1 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP2OUT_OUT1_HIGH (0x1 << 1 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP2OUT[OUT0] - Output for port pin. */ +#define GP2OUT_OUT0_BBA (*(volatile unsigned long *) 0x420C0F00) +#define GP2OUT_OUT0_MSK (0x1 << 0 ) +#define GP2OUT_OUT0 (0x1 << 0 ) +#define GP2OUT_OUT0_LOW (0x0 << 0 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP2OUT_OUT0_HIGH (0x1 << 0 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* Reset Value for GP2SET*/ +#define GP2SET_RVAL 0x0 + +/* GP2SET[SET7] - Set output high for corresponding port pin. */ +#define GP2SET_SET7_BBA (*(volatile unsigned long *) 0x420C0F9C) +#define GP2SET_SET7_MSK (0x1 << 7 ) +#define GP2SET_SET7 (0x1 << 7 ) +#define GP2SET_SET7_SET (0x1 << 7 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP2SET[SET6] - Set output high for corresponding port pin. */ +#define GP2SET_SET6_BBA (*(volatile unsigned long *) 0x420C0F98) +#define GP2SET_SET6_MSK (0x1 << 6 ) +#define GP2SET_SET6 (0x1 << 6 ) +#define GP2SET_SET6_SET (0x1 << 6 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP2SET[SET5] - Set output high for corresponding port pin. */ +#define GP2SET_SET5_BBA (*(volatile unsigned long *) 0x420C0F94) +#define GP2SET_SET5_MSK (0x1 << 5 ) +#define GP2SET_SET5 (0x1 << 5 ) +#define GP2SET_SET5_SET (0x1 << 5 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP2SET[SET4] - Set output high for corresponding port pin. */ +#define GP2SET_SET4_BBA (*(volatile unsigned long *) 0x420C0F90) +#define GP2SET_SET4_MSK (0x1 << 4 ) +#define GP2SET_SET4 (0x1 << 4 ) +#define GP2SET_SET4_SET (0x1 << 4 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP2SET[SET3] - Set output high for corresponding port pin. */ +#define GP2SET_SET3_BBA (*(volatile unsigned long *) 0x420C0F8C) +#define GP2SET_SET3_MSK (0x1 << 3 ) +#define GP2SET_SET3 (0x1 << 3 ) +#define GP2SET_SET3_SET (0x1 << 3 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP2SET[SET2] - Set output high for corresponding port pin. */ +#define GP2SET_SET2_BBA (*(volatile unsigned long *) 0x420C0F88) +#define GP2SET_SET2_MSK (0x1 << 2 ) +#define GP2SET_SET2 (0x1 << 2 ) +#define GP2SET_SET2_SET (0x1 << 2 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP2SET[SET1] - Set output high for corresponding port pin. */ +#define GP2SET_SET1_BBA (*(volatile unsigned long *) 0x420C0F84) +#define GP2SET_SET1_MSK (0x1 << 1 ) +#define GP2SET_SET1 (0x1 << 1 ) +#define GP2SET_SET1_SET (0x1 << 1 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP2SET[SET0] - Set output high for corresponding port pin. */ +#define GP2SET_SET0_BBA (*(volatile unsigned long *) 0x420C0F80) +#define GP2SET_SET0_MSK (0x1 << 0 ) +#define GP2SET_SET0 (0x1 << 0 ) +#define GP2SET_SET0_SET (0x1 << 0 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* Reset Value for GP2CLR*/ +#define GP2CLR_RVAL 0x0 + +/* GP2CLR[CLR7] - Set by user code to drive the corresponding GPIO low. */ +#define GP2CLR_CLR7_BBA (*(volatile unsigned long *) 0x420C101C) +#define GP2CLR_CLR7_MSK (0x1 << 7 ) +#define GP2CLR_CLR7 (0x1 << 7 ) +#define GP2CLR_CLR7_CLR (0x1 << 7 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP2CLR[CLR6] - Set by user code to drive the corresponding GPIO low. */ +#define GP2CLR_CLR6_BBA (*(volatile unsigned long *) 0x420C1018) +#define GP2CLR_CLR6_MSK (0x1 << 6 ) +#define GP2CLR_CLR6 (0x1 << 6 ) +#define GP2CLR_CLR6_CLR (0x1 << 6 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP2CLR[CLR5] - Set by user code to drive the corresponding GPIO low. */ +#define GP2CLR_CLR5_BBA (*(volatile unsigned long *) 0x420C1014) +#define GP2CLR_CLR5_MSK (0x1 << 5 ) +#define GP2CLR_CLR5 (0x1 << 5 ) +#define GP2CLR_CLR5_CLR (0x1 << 5 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP2CLR[CLR4] - Set by user code to drive the corresponding GPIO low. */ +#define GP2CLR_CLR4_BBA (*(volatile unsigned long *) 0x420C1010) +#define GP2CLR_CLR4_MSK (0x1 << 4 ) +#define GP2CLR_CLR4 (0x1 << 4 ) +#define GP2CLR_CLR4_CLR (0x1 << 4 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP2CLR[CLR3] - Set by user code to drive the corresponding GPIO low. */ +#define GP2CLR_CLR3_BBA (*(volatile unsigned long *) 0x420C100C) +#define GP2CLR_CLR3_MSK (0x1 << 3 ) +#define GP2CLR_CLR3 (0x1 << 3 ) +#define GP2CLR_CLR3_CLR (0x1 << 3 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP2CLR[CLR2] - Set by user code to drive the corresponding GPIO low. */ +#define GP2CLR_CLR2_BBA (*(volatile unsigned long *) 0x420C1008) +#define GP2CLR_CLR2_MSK (0x1 << 2 ) +#define GP2CLR_CLR2 (0x1 << 2 ) +#define GP2CLR_CLR2_CLR (0x1 << 2 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP2CLR[CLR1] - Set by user code to drive the corresponding GPIO low. */ +#define GP2CLR_CLR1_BBA (*(volatile unsigned long *) 0x420C1004) +#define GP2CLR_CLR1_MSK (0x1 << 1 ) +#define GP2CLR_CLR1 (0x1 << 1 ) +#define GP2CLR_CLR1_CLR (0x1 << 1 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP2CLR[CLR0] - Set by user code to drive the corresponding GPIO low. */ +#define GP2CLR_CLR0_BBA (*(volatile unsigned long *) 0x420C1000) +#define GP2CLR_CLR0_MSK (0x1 << 0 ) +#define GP2CLR_CLR0 (0x1 << 0 ) +#define GP2CLR_CLR0_CLR (0x1 << 0 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* Reset Value for GP2TGL*/ +#define GP2TGL_RVAL 0x0 + +/* GP2TGL[TGL7] - Toggle for corresponding port pin. */ +#define GP2TGL_TGL7_BBA (*(volatile unsigned long *) 0x420C109C) +#define GP2TGL_TGL7_MSK (0x1 << 7 ) +#define GP2TGL_TGL7 (0x1 << 7 ) +#define GP2TGL_TGL7_TGL (0x1 << 7 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP2TGL[TGL6] - Toggle for corresponding port pin. */ +#define GP2TGL_TGL6_BBA (*(volatile unsigned long *) 0x420C1098) +#define GP2TGL_TGL6_MSK (0x1 << 6 ) +#define GP2TGL_TGL6 (0x1 << 6 ) +#define GP2TGL_TGL6_TGL (0x1 << 6 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP2TGL[TGL5] - Toggle for corresponding port pin. */ +#define GP2TGL_TGL5_BBA (*(volatile unsigned long *) 0x420C1094) +#define GP2TGL_TGL5_MSK (0x1 << 5 ) +#define GP2TGL_TGL5 (0x1 << 5 ) +#define GP2TGL_TGL5_TGL (0x1 << 5 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP2TGL[TGL4] - Toggle for corresponding port pin. */ +#define GP2TGL_TGL4_BBA (*(volatile unsigned long *) 0x420C1090) +#define GP2TGL_TGL4_MSK (0x1 << 4 ) +#define GP2TGL_TGL4 (0x1 << 4 ) +#define GP2TGL_TGL4_TGL (0x1 << 4 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP2TGL[TGL3] - Toggle for corresponding port pin. */ +#define GP2TGL_TGL3_BBA (*(volatile unsigned long *) 0x420C108C) +#define GP2TGL_TGL3_MSK (0x1 << 3 ) +#define GP2TGL_TGL3 (0x1 << 3 ) +#define GP2TGL_TGL3_TGL (0x1 << 3 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP2TGL[TGL2] - Toggle for corresponding port pin. */ +#define GP2TGL_TGL2_BBA (*(volatile unsigned long *) 0x420C1088) +#define GP2TGL_TGL2_MSK (0x1 << 2 ) +#define GP2TGL_TGL2 (0x1 << 2 ) +#define GP2TGL_TGL2_TGL (0x1 << 2 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP2TGL[TGL1] - Toggle for corresponding port pin. */ +#define GP2TGL_TGL1_BBA (*(volatile unsigned long *) 0x420C1084) +#define GP2TGL_TGL1_MSK (0x1 << 1 ) +#define GP2TGL_TGL1 (0x1 << 1 ) +#define GP2TGL_TGL1_TGL (0x1 << 1 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP2TGL[TGL0] - Toggle for corresponding port pin. */ +#define GP2TGL_TGL0_BBA (*(volatile unsigned long *) 0x420C1080) +#define GP2TGL_TGL0_MSK (0x1 << 0 ) +#define GP2TGL_TGL0 (0x1 << 0 ) +#define GP2TGL_TGL0_TGL (0x1 << 0 ) /* TGL. Set by user code to invert the corresponding GPIO. */ +#if (__NO_MMR_STRUCTS__==1) + +#define GP3CON (*(volatile unsigned short int *) 0x40006090) +#define GP3OEN (*(volatile unsigned char *) 0x40006094) +#define GP3PUL (*(volatile unsigned char *) 0x40006098) +#define GP3OCE (*(volatile unsigned char *) 0x4000609C) +#define GP3IN (*(volatile unsigned char *) 0x400060A4) +#define GP3OUT (*(volatile unsigned char *) 0x400060A8) +#define GP3SET (*(volatile unsigned char *) 0x400060AC) +#define GP3CLR (*(volatile unsigned char *) 0x400060B0) +#define GP3TGL (*(volatile unsigned char *) 0x400060B4) +#endif // (__NO_MMR_STRUCTS__==1) + +/* Reset Value for GP3CON*/ +#define GP3CON_RVAL 0x0 + +/* GP3CON[CON7] - Configuration bits for P3.7 */ +#define GP3CON_CON7_MSK (0x3 << 14 ) +#define GP3CON_CON7_GPIOIRQ0 (0x1 << 14 ) /* GPIOIRQ0 */ + +/* GP3CON[CON6] - Configuration bits for P3.6 */ +#define GP3CON_CON6_MSK (0x3 << 12 ) +#define GP3CON_CON6_GPIO (0x1 << 12 ) /* GPIO */ + +/* GP3CON[CON5] - Configuration bits for P3.5 */ +#define GP3CON_CON5_MSK (0x3 << 10 ) +#define GP3CON_CON5_GPIO (0x1 << 10 ) /* GPIO */ +#define GP3CON_CON5_SPI0MOSI (0x3 << 10 ) /* SPI0MOSI */ + +/* GP3CON[CON4] - Configuration bits for P3.4 */ +#define GP3CON_CON4_MSK (0x3 << 8 ) +#define GP3CON_CON4_GPIO (0x1 << 8 ) /* GPIO */ + +/* GP3CON[CON3] - Configuration bits for P3.3 */ +#define GP3CON_CON3_MSK (0x3 << 6 ) +#define GP3CON_CON3_GPIO (0x1 << 6 ) /* GPIO */ +#define GP3CON_CON3_PWMTRIP (0x2 << 6 ) /* PWMTRIP */ +#define GP3CON_CON3_SPI0SCLK (0x3 << 6 ) /* SPI0SCLK */ + +/* GP3CON[CON2] - Configuration bits for P3.2 */ +#define GP3CON_CON2_MSK (0x3 << 4 ) +#define GP3CON_CON2_GPIO (0x1 << 4 ) /* GPIO */ +#define GP3CON_CON2_PWMSYNC (0x2 << 4 ) /* PWMSYNC */ +#define GP3CON_CON2_SPI0MISO (0x3 << 4 ) /* SPI0MISO */ + +/* GP3CON[CON1] - Configuration bits for P3.1 */ +#define GP3CON_CON1_MSK (0x3 << 2 ) +#define GP3CON_CON1_GPIO (0x0 << 2 ) /* GPIO */ + +/* GP3CON[CON0] - Configuration bits for P3.0 */ +#define GP3CON_CON0_MSK (0x3 << 0 ) +#define GP3CON_CON0_GPIO (0x0 << 0 ) /* GPIO */ +#define GP3CON_CON0_PWMTRIP (0x3 << 0 ) /* PWMTRIP */ + +/* Reset Value for GP3OEN*/ +#define GP3OEN_RVAL 0x0 + +/* GP3OEN[OEN7] - Port pin direction. */ +#define GP3OEN_OEN7_BBA (*(volatile unsigned long *) 0x420C129C) +#define GP3OEN_OEN7_MSK (0x1 << 7 ) +#define GP3OEN_OEN7 (0x1 << 7 ) +#define GP3OEN_OEN7_IN (0x0 << 7 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP3OEN_OEN7_OUT (0x1 << 7 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP3OEN[OEN6] - Port pin direction. */ +#define GP3OEN_OEN6_BBA (*(volatile unsigned long *) 0x420C1298) +#define GP3OEN_OEN6_MSK (0x1 << 6 ) +#define GP3OEN_OEN6 (0x1 << 6 ) +#define GP3OEN_OEN6_IN (0x0 << 6 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP3OEN_OEN6_OUT (0x1 << 6 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP3OEN[OEN5] - Port pin direction. */ +#define GP3OEN_OEN5_BBA (*(volatile unsigned long *) 0x420C1294) +#define GP3OEN_OEN5_MSK (0x1 << 5 ) +#define GP3OEN_OEN5 (0x1 << 5 ) +#define GP3OEN_OEN5_IN (0x0 << 5 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP3OEN_OEN5_OUT (0x1 << 5 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP3OEN[OEN4] - Port pin direction. */ +#define GP3OEN_OEN4_BBA (*(volatile unsigned long *) 0x420C1290) +#define GP3OEN_OEN4_MSK (0x1 << 4 ) +#define GP3OEN_OEN4 (0x1 << 4 ) +#define GP3OEN_OEN4_IN (0x0 << 4 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP3OEN_OEN4_OUT (0x1 << 4 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP3OEN[OEN3] - Port pin direction. */ +#define GP3OEN_OEN3_BBA (*(volatile unsigned long *) 0x420C128C) +#define GP3OEN_OEN3_MSK (0x1 << 3 ) +#define GP3OEN_OEN3 (0x1 << 3 ) +#define GP3OEN_OEN3_IN (0x0 << 3 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP3OEN_OEN3_OUT (0x1 << 3 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP3OEN[OEN2] - Port pin direction. */ +#define GP3OEN_OEN2_BBA (*(volatile unsigned long *) 0x420C1288) +#define GP3OEN_OEN2_MSK (0x1 << 2 ) +#define GP3OEN_OEN2 (0x1 << 2 ) +#define GP3OEN_OEN2_IN (0x0 << 2 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP3OEN_OEN2_OUT (0x1 << 2 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP3OEN[OEN1] - Port pin direction. */ +#define GP3OEN_OEN1_BBA (*(volatile unsigned long *) 0x420C1284) +#define GP3OEN_OEN1_MSK (0x1 << 1 ) +#define GP3OEN_OEN1 (0x1 << 1 ) +#define GP3OEN_OEN1_IN (0x0 << 1 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP3OEN_OEN1_OUT (0x1 << 1 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP3OEN[OEN0] - Port pin direction. */ +#define GP3OEN_OEN0_BBA (*(volatile unsigned long *) 0x420C1280) +#define GP3OEN_OEN0_MSK (0x1 << 0 ) +#define GP3OEN_OEN0 (0x1 << 0 ) +#define GP3OEN_OEN0_IN (0x0 << 0 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP3OEN_OEN0_OUT (0x1 << 0 ) /* OUT. Enables the output on corresponding port pin. */ + +/* Reset Value for GP3PUL*/ +#define GP3PUL_RVAL 0xFF + +/* GP3PUL[PUL7] - Pull Up Enable for port pin. */ +#define GP3PUL_PUL7_BBA (*(volatile unsigned long *) 0x420C131C) +#define GP3PUL_PUL7_MSK (0x1 << 7 ) +#define GP3PUL_PUL7 (0x1 << 7 ) +#define GP3PUL_PUL7_DIS (0x0 << 7 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP3PUL_PUL7_EN (0x1 << 7 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP3PUL[PUL6] - Pull Up Enable for port pin. */ +#define GP3PUL_PUL6_BBA (*(volatile unsigned long *) 0x420C1318) +#define GP3PUL_PUL6_MSK (0x1 << 6 ) +#define GP3PUL_PUL6 (0x1 << 6 ) +#define GP3PUL_PUL6_DIS (0x0 << 6 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP3PUL_PUL6_EN (0x1 << 6 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP3PUL[PUL5] - Pull Up Enable for port pin. */ +#define GP3PUL_PUL5_BBA (*(volatile unsigned long *) 0x420C1314) +#define GP3PUL_PUL5_MSK (0x1 << 5 ) +#define GP3PUL_PUL5 (0x1 << 5 ) +#define GP3PUL_PUL5_DIS (0x0 << 5 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP3PUL_PUL5_EN (0x1 << 5 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP3PUL[PUL4] - Pull Up Enable for port pin. */ +#define GP3PUL_PUL4_BBA (*(volatile unsigned long *) 0x420C1310) +#define GP3PUL_PUL4_MSK (0x1 << 4 ) +#define GP3PUL_PUL4 (0x1 << 4 ) +#define GP3PUL_PUL4_DIS (0x0 << 4 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP3PUL_PUL4_EN (0x1 << 4 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP3PUL[PUL3] - Pull Up Enable for port pin. */ +#define GP3PUL_PUL3_BBA (*(volatile unsigned long *) 0x420C130C) +#define GP3PUL_PUL3_MSK (0x1 << 3 ) +#define GP3PUL_PUL3 (0x1 << 3 ) +#define GP3PUL_PUL3_DIS (0x0 << 3 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP3PUL_PUL3_EN (0x1 << 3 ) /* EN. Enables the internal pull up oncorresponding port pin. */ + +/* GP3PUL[PUL2] - Pull Up Enable for port pin. */ +#define GP3PUL_PUL2_BBA (*(volatile unsigned long *) 0x420C1308) +#define GP3PUL_PUL2_MSK (0x1 << 2 ) +#define GP3PUL_PUL2 (0x1 << 2 ) +#define GP3PUL_PUL2_DIS (0x0 << 2 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP3PUL_PUL2_EN (0x1 << 2 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP3PUL[PUL1] - Pull Up Enable for port pin. */ +#define GP3PUL_PUL1_BBA (*(volatile unsigned long *) 0x420C1304) +#define GP3PUL_PUL1_MSK (0x1 << 1 ) +#define GP3PUL_PUL1 (0x1 << 1 ) +#define GP3PUL_PUL1_DIS (0x0 << 1 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP3PUL_PUL1_EN (0x1 << 1 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP3PUL[PUL0] - Pull Up Enable for port pin. */ +#define GP3PUL_PUL0_BBA (*(volatile unsigned long *) 0x420C1300) +#define GP3PUL_PUL0_MSK (0x1 << 0 ) +#define GP3PUL_PUL0 (0x1 << 0 ) +#define GP3PUL_PUL0_DIS (0x0 << 0 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP3PUL_PUL0_EN (0x1 << 0 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* Reset Value for GP3OCE*/ +#define GP3OCE_RVAL 0x0 + +/* GP3OCE[OCE7] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP3OCE_OCE7_BBA (*(volatile unsigned long *) 0x420C139C) +#define GP3OCE_OCE7_MSK (0x1 << 7 ) +#define GP3OCE_OCE7 (0x1 << 7 ) +#define GP3OCE_OCE7_DIS (0x0 << 7 ) /* DIS */ +#define GP3OCE_OCE7_EN (0x1 << 7 ) /* EN */ + +/* GP3OCE[OCE6] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP3OCE_OCE6_BBA (*(volatile unsigned long *) 0x420C1398) +#define GP3OCE_OCE6_MSK (0x1 << 6 ) +#define GP3OCE_OCE6 (0x1 << 6 ) +#define GP3OCE_OCE6_DIS (0x0 << 6 ) /* DIS */ +#define GP3OCE_OCE6_EN (0x1 << 6 ) /* EN */ + +/* GP3OCE[OCE5] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP3OCE_OCE5_BBA (*(volatile unsigned long *) 0x420C1394) +#define GP3OCE_OCE5_MSK (0x1 << 5 ) +#define GP3OCE_OCE5 (0x1 << 5 ) +#define GP3OCE_OCE5_DIS (0x0 << 5 ) /* DIS */ +#define GP3OCE_OCE5_EN (0x1 << 5 ) /* EN */ + +/* GP3OCE[OCE4] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP3OCE_OCE4_BBA (*(volatile unsigned long *) 0x420C1390) +#define GP3OCE_OCE4_MSK (0x1 << 4 ) +#define GP3OCE_OCE4 (0x1 << 4 ) +#define GP3OCE_OCE4_DIS (0x0 << 4 ) /* DIS */ +#define GP3OCE_OCE4_EN (0x1 << 4 ) /* EN */ + +/* GP3OCE[OCE3] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP3OCE_OCE3_BBA (*(volatile unsigned long *) 0x420C138C) +#define GP3OCE_OCE3_MSK (0x1 << 3 ) +#define GP3OCE_OCE3 (0x1 << 3 ) +#define GP3OCE_OCE3_DIS (0x0 << 3 ) /* DIS */ +#define GP3OCE_OCE3_EN (0x1 << 3 ) /* EN */ + +/* GP3OCE[OCE2] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP3OCE_OCE2_BBA (*(volatile unsigned long *) 0x420C1388) +#define GP3OCE_OCE2_MSK (0x1 << 2 ) +#define GP3OCE_OCE2 (0x1 << 2 ) +#define GP3OCE_OCE2_DIS (0x0 << 2 ) /* DIS */ +#define GP3OCE_OCE2_EN (0x1 << 2 ) /* EN */ + +/* GP3OCE[OCE1] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP3OCE_OCE1_BBA (*(volatile unsigned long *) 0x420C1384) +#define GP3OCE_OCE1_MSK (0x1 << 1 ) +#define GP3OCE_OCE1 (0x1 << 1 ) +#define GP3OCE_OCE1_DIS (0x0 << 1 ) /* DIS */ +#define GP3OCE_OCE1_EN (0x1 << 1 ) /* EN */ + +/* GP3OCE[OCE0] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP3OCE_OCE0_BBA (*(volatile unsigned long *) 0x420C1380) +#define GP3OCE_OCE0_MSK (0x1 << 0 ) +#define GP3OCE_OCE0 (0x1 << 0 ) +#define GP3OCE_OCE0_DIS (0x0 << 0 ) /* DIS */ +#define GP3OCE_OCE0_EN (0x1 << 0 ) /* EN */ + +/* Reset Value for GP3IN*/ +#define GP3IN_RVAL 0xFF + +/* GP3IN[IN7] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP3IN_IN7_BBA (*(volatile unsigned long *) 0x420C149C) +#define GP3IN_IN7_MSK (0x1 << 7 ) +#define GP3IN_IN7 (0x1 << 7 ) +#define GP3IN_IN7_LOW (0x0 << 7 ) /* LOW */ +#define GP3IN_IN7_HIGH (0x1 << 7 ) /* HIGH */ + +/* GP3IN[IN6] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP3IN_IN6_BBA (*(volatile unsigned long *) 0x420C1498) +#define GP3IN_IN6_MSK (0x1 << 6 ) +#define GP3IN_IN6 (0x1 << 6 ) +#define GP3IN_IN6_LOW (0x0 << 6 ) /* LOW */ +#define GP3IN_IN6_HIGH (0x1 << 6 ) /* HIGH */ + +/* GP3IN[IN5] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP3IN_IN5_BBA (*(volatile unsigned long *) 0x420C1494) +#define GP3IN_IN5_MSK (0x1 << 5 ) +#define GP3IN_IN5 (0x1 << 5 ) +#define GP3IN_IN5_LOW (0x0 << 5 ) /* LOW */ +#define GP3IN_IN5_HIGH (0x1 << 5 ) /* HIGH */ + +/* GP3IN[IN4] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP3IN_IN4_BBA (*(volatile unsigned long *) 0x420C1490) +#define GP3IN_IN4_MSK (0x1 << 4 ) +#define GP3IN_IN4 (0x1 << 4 ) +#define GP3IN_IN4_LOW (0x0 << 4 ) /* LOW */ +#define GP3IN_IN4_HIGH (0x1 << 4 ) /* HIGH */ + +/* GP3IN[IN3] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP3IN_IN3_BBA (*(volatile unsigned long *) 0x420C148C) +#define GP3IN_IN3_MSK (0x1 << 3 ) +#define GP3IN_IN3 (0x1 << 3 ) +#define GP3IN_IN3_LOW (0x0 << 3 ) /* LOW */ +#define GP3IN_IN3_HIGH (0x1 << 3 ) /* HIGH */ + +/* GP3IN[IN2] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP3IN_IN2_BBA (*(volatile unsigned long *) 0x420C1488) +#define GP3IN_IN2_MSK (0x1 << 2 ) +#define GP3IN_IN2 (0x1 << 2 ) +#define GP3IN_IN2_LOW (0x0 << 2 ) /* LOW */ +#define GP3IN_IN2_HIGH (0x1 << 2 ) /* HIGH */ + +/* GP3IN[IN1] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP3IN_IN1_BBA (*(volatile unsigned long *) 0x420C1484) +#define GP3IN_IN1_MSK (0x1 << 1 ) +#define GP3IN_IN1 (0x1 << 1 ) +#define GP3IN_IN1_LOW (0x0 << 1 ) /* LOW */ +#define GP3IN_IN1_HIGH (0x1 << 1 ) /* HIGH */ + +/* GP3IN[IN0] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP3IN_IN0_BBA (*(volatile unsigned long *) 0x420C1480) +#define GP3IN_IN0_MSK (0x1 << 0 ) +#define GP3IN_IN0 (0x1 << 0 ) +#define GP3IN_IN0_LOW (0x0 << 0 ) /* LOW */ +#define GP3IN_IN0_HIGH (0x1 << 0 ) /* HIGH */ + +/* Reset Value for GP3OUT*/ +#define GP3OUT_RVAL 0x0 + +/* GP3OUT[OUT7] - Output for port pin. */ +#define GP3OUT_OUT7_BBA (*(volatile unsigned long *) 0x420C151C) +#define GP3OUT_OUT7_MSK (0x1 << 7 ) +#define GP3OUT_OUT7 (0x1 << 7 ) +#define GP3OUT_OUT7_LOW (0x0 << 7 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP3OUT_OUT7_HIGH (0x1 << 7 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP3OUT[OUT6] - Output for port pin. */ +#define GP3OUT_OUT6_BBA (*(volatile unsigned long *) 0x420C1518) +#define GP3OUT_OUT6_MSK (0x1 << 6 ) +#define GP3OUT_OUT6 (0x1 << 6 ) +#define GP3OUT_OUT6_LOW (0x0 << 6 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP3OUT_OUT6_HIGH (0x1 << 6 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP3OUT[OUT5] - Output for port pin. */ +#define GP3OUT_OUT5_BBA (*(volatile unsigned long *) 0x420C1514) +#define GP3OUT_OUT5_MSK (0x1 << 5 ) +#define GP3OUT_OUT5 (0x1 << 5 ) +#define GP3OUT_OUT5_LOW (0x0 << 5 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP3OUT_OUT5_HIGH (0x1 << 5 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP3OUT[OUT4] - Output for port pin. */ +#define GP3OUT_OUT4_BBA (*(volatile unsigned long *) 0x420C1510) +#define GP3OUT_OUT4_MSK (0x1 << 4 ) +#define GP3OUT_OUT4 (0x1 << 4 ) +#define GP3OUT_OUT4_LOW (0x0 << 4 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP3OUT_OUT4_HIGH (0x1 << 4 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP3OUT[OUT3] - Output for port pin. */ +#define GP3OUT_OUT3_BBA (*(volatile unsigned long *) 0x420C150C) +#define GP3OUT_OUT3_MSK (0x1 << 3 ) +#define GP3OUT_OUT3 (0x1 << 3 ) +#define GP3OUT_OUT3_LOW (0x0 << 3 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP3OUT_OUT3_HIGH (0x1 << 3 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP3OUT[OUT2] - Output for port pin. */ +#define GP3OUT_OUT2_BBA (*(volatile unsigned long *) 0x420C1508) +#define GP3OUT_OUT2_MSK (0x1 << 2 ) +#define GP3OUT_OUT2 (0x1 << 2 ) +#define GP3OUT_OUT2_LOW (0x0 << 2 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP3OUT_OUT2_HIGH (0x1 << 2 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP3OUT[OUT1] - Output for port pin. */ +#define GP3OUT_OUT1_BBA (*(volatile unsigned long *) 0x420C1504) +#define GP3OUT_OUT1_MSK (0x1 << 1 ) +#define GP3OUT_OUT1 (0x1 << 1 ) +#define GP3OUT_OUT1_LOW (0x0 << 1 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP3OUT_OUT1_HIGH (0x1 << 1 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP3OUT[OUT0] - Output for port pin. */ +#define GP3OUT_OUT0_BBA (*(volatile unsigned long *) 0x420C1500) +#define GP3OUT_OUT0_MSK (0x1 << 0 ) +#define GP3OUT_OUT0 (0x1 << 0 ) +#define GP3OUT_OUT0_LOW (0x0 << 0 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP3OUT_OUT0_HIGH (0x1 << 0 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* Reset Value for GP3SET*/ +#define GP3SET_RVAL 0x0 + +/* GP3SET[SET7] - Set output high for corresponding port pin. */ +#define GP3SET_SET7_BBA (*(volatile unsigned long *) 0x420C159C) +#define GP3SET_SET7_MSK (0x1 << 7 ) +#define GP3SET_SET7 (0x1 << 7 ) +#define GP3SET_SET7_SET (0x1 << 7 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP3SET[SET6] - Set output high for corresponding port pin. */ +#define GP3SET_SET6_BBA (*(volatile unsigned long *) 0x420C1598) +#define GP3SET_SET6_MSK (0x1 << 6 ) +#define GP3SET_SET6 (0x1 << 6 ) +#define GP3SET_SET6_SET (0x1 << 6 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP3SET[SET5] - Set output high for corresponding port pin. */ +#define GP3SET_SET5_BBA (*(volatile unsigned long *) 0x420C1594) +#define GP3SET_SET5_MSK (0x1 << 5 ) +#define GP3SET_SET5 (0x1 << 5 ) +#define GP3SET_SET5_SET (0x1 << 5 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP3SET[SET4] - Set output high for corresponding port pin. */ +#define GP3SET_SET4_BBA (*(volatile unsigned long *) 0x420C1590) +#define GP3SET_SET4_MSK (0x1 << 4 ) +#define GP3SET_SET4 (0x1 << 4 ) +#define GP3SET_SET4_SET (0x1 << 4 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP3SET[SET3] - Set output high for corresponding port pin. */ +#define GP3SET_SET3_BBA (*(volatile unsigned long *) 0x420C158C) +#define GP3SET_SET3_MSK (0x1 << 3 ) +#define GP3SET_SET3 (0x1 << 3 ) +#define GP3SET_SET3_SET (0x1 << 3 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP3SET[SET2] - Set output high for corresponding port pin. */ +#define GP3SET_SET2_BBA (*(volatile unsigned long *) 0x420C1588) +#define GP3SET_SET2_MSK (0x1 << 2 ) +#define GP3SET_SET2 (0x1 << 2 ) +#define GP3SET_SET2_SET (0x1 << 2 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP3SET[SET1] - Set output high for corresponding port pin. */ +#define GP3SET_SET1_BBA (*(volatile unsigned long *) 0x420C1584) +#define GP3SET_SET1_MSK (0x1 << 1 ) +#define GP3SET_SET1 (0x1 << 1 ) +#define GP3SET_SET1_SET (0x1 << 1 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP3SET[SET0] - Set output high for corresponding port pin. */ +#define GP3SET_SET0_BBA (*(volatile unsigned long *) 0x420C1580) +#define GP3SET_SET0_MSK (0x1 << 0 ) +#define GP3SET_SET0 (0x1 << 0 ) +#define GP3SET_SET0_SET (0x1 << 0 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* Reset Value for GP3CLR*/ +#define GP3CLR_RVAL 0x0 + +/* GP3CLR[CLR7] - Set by user code to drive the corresponding GPIO low. */ +#define GP3CLR_CLR7_BBA (*(volatile unsigned long *) 0x420C161C) +#define GP3CLR_CLR7_MSK (0x1 << 7 ) +#define GP3CLR_CLR7 (0x1 << 7 ) +#define GP3CLR_CLR7_CLR (0x1 << 7 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP3CLR[CLR6] - Set by user code to drive the corresponding GPIO low. */ +#define GP3CLR_CLR6_BBA (*(volatile unsigned long *) 0x420C1618) +#define GP3CLR_CLR6_MSK (0x1 << 6 ) +#define GP3CLR_CLR6 (0x1 << 6 ) +#define GP3CLR_CLR6_CLR (0x1 << 6 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP3CLR[CLR5] - Set by user code to drive the corresponding GPIO low. */ +#define GP3CLR_CLR5_BBA (*(volatile unsigned long *) 0x420C1614) +#define GP3CLR_CLR5_MSK (0x1 << 5 ) +#define GP3CLR_CLR5 (0x1 << 5 ) +#define GP3CLR_CLR5_CLR (0x1 << 5 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP3CLR[CLR4] - Set by user code to drive the corresponding GPIO low. */ +#define GP3CLR_CLR4_BBA (*(volatile unsigned long *) 0x420C1610) +#define GP3CLR_CLR4_MSK (0x1 << 4 ) +#define GP3CLR_CLR4 (0x1 << 4 ) +#define GP3CLR_CLR4_CLR (0x1 << 4 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP3CLR[CLR3] - Set by user code to drive the corresponding GPIO low. */ +#define GP3CLR_CLR3_BBA (*(volatile unsigned long *) 0x420C160C) +#define GP3CLR_CLR3_MSK (0x1 << 3 ) +#define GP3CLR_CLR3 (0x1 << 3 ) +#define GP3CLR_CLR3_CLR (0x1 << 3 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP3CLR[CLR2] - Set by user code to drive the corresponding GPIO low. */ +#define GP3CLR_CLR2_BBA (*(volatile unsigned long *) 0x420C1608) +#define GP3CLR_CLR2_MSK (0x1 << 2 ) +#define GP3CLR_CLR2 (0x1 << 2 ) +#define GP3CLR_CLR2_CLR (0x1 << 2 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP3CLR[CLR1] - Set by user code to drive the corresponding GPIO low. */ +#define GP3CLR_CLR1_BBA (*(volatile unsigned long *) 0x420C1604) +#define GP3CLR_CLR1_MSK (0x1 << 1 ) +#define GP3CLR_CLR1 (0x1 << 1 ) +#define GP3CLR_CLR1_CLR (0x1 << 1 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP3CLR[CLR0] - Set by user code to drive the corresponding GPIO low. */ +#define GP3CLR_CLR0_BBA (*(volatile unsigned long *) 0x420C1600) +#define GP3CLR_CLR0_MSK (0x1 << 0 ) +#define GP3CLR_CLR0 (0x1 << 0 ) +#define GP3CLR_CLR0_CLR (0x1 << 0 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* Reset Value for GP3TGL*/ +#define GP3TGL_RVAL 0x0 + +/* GP3TGL[TGL7] - Toggle for corresponding port pin. */ +#define GP3TGL_TGL7_BBA (*(volatile unsigned long *) 0x420C169C) +#define GP3TGL_TGL7_MSK (0x1 << 7 ) +#define GP3TGL_TGL7 (0x1 << 7 ) +#define GP3TGL_TGL7_TGL (0x1 << 7 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP3TGL[TGL6] - Toggle for corresponding port pin. */ +#define GP3TGL_TGL6_BBA (*(volatile unsigned long *) 0x420C1698) +#define GP3TGL_TGL6_MSK (0x1 << 6 ) +#define GP3TGL_TGL6 (0x1 << 6 ) +#define GP3TGL_TGL6_TGL (0x1 << 6 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP3TGL[TGL5] - Toggle for corresponding port pin. */ +#define GP3TGL_TGL5_BBA (*(volatile unsigned long *) 0x420C1694) +#define GP3TGL_TGL5_MSK (0x1 << 5 ) +#define GP3TGL_TGL5 (0x1 << 5 ) +#define GP3TGL_TGL5_TGL (0x1 << 5 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP3TGL[TGL4] - Toggle for corresponding port pin. */ +#define GP3TGL_TGL4_BBA (*(volatile unsigned long *) 0x420C1690) +#define GP3TGL_TGL4_MSK (0x1 << 4 ) +#define GP3TGL_TGL4 (0x1 << 4 ) +#define GP3TGL_TGL4_TGL (0x1 << 4 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP3TGL[TGL3] - Toggle for corresponding port pin. */ +#define GP3TGL_TGL3_BBA (*(volatile unsigned long *) 0x420C168C) +#define GP3TGL_TGL3_MSK (0x1 << 3 ) +#define GP3TGL_TGL3 (0x1 << 3 ) +#define GP3TGL_TGL3_TGL (0x1 << 3 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP3TGL[TGL2] - Toggle for corresponding port pin. */ +#define GP3TGL_TGL2_BBA (*(volatile unsigned long *) 0x420C1688) +#define GP3TGL_TGL2_MSK (0x1 << 2 ) +#define GP3TGL_TGL2 (0x1 << 2 ) +#define GP3TGL_TGL2_TGL (0x1 << 2 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP3TGL[TGL1] - Toggle for corresponding port pin. */ +#define GP3TGL_TGL1_BBA (*(volatile unsigned long *) 0x420C1684) +#define GP3TGL_TGL1_MSK (0x1 << 1 ) +#define GP3TGL_TGL1 (0x1 << 1 ) +#define GP3TGL_TGL1_TGL (0x1 << 1 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP3TGL[TGL0] - Toggle for corresponding port pin. */ +#define GP3TGL_TGL0_BBA (*(volatile unsigned long *) 0x420C1680) +#define GP3TGL_TGL0_MSK (0x1 << 0 ) +#define GP3TGL_TGL0 (0x1 << 0 ) +#define GP3TGL_TGL0_TGL (0x1 << 0 ) /* TGL. Set by user code to invert the corresponding GPIO. */ +#if (__NO_MMR_STRUCTS__==1) + +#define GP4CON (*(volatile unsigned short int *) 0x400060C0) +#define GP4OEN (*(volatile unsigned char *) 0x400060C4) +#define GP4PUL (*(volatile unsigned char *) 0x400060C8) +#define GP4OCE (*(volatile unsigned char *) 0x400060CC) +#define GP4IN (*(volatile unsigned char *) 0x400060D4) +#define GP4OUT (*(volatile unsigned char *) 0x400060D8) +#define GP4SET (*(volatile unsigned char *) 0x400060DC) +#define GP4CLR (*(volatile unsigned char *) 0x400060E0) +#define GP4TGL (*(volatile unsigned char *) 0x400060E4) +#endif // (__NO_MMR_STRUCTS__==1) + +/* Reset Value for GP4CON*/ +#define GP4CON_RVAL 0x0 + +/* GP4CON[CON7] - Configuration bits for P4.7 */ +#define GP4CON_CON7_MSK (0x3 << 14 ) +#define GP4CON_CON7_GPIO (0x1 << 14 ) /* GPIO */ +#define GP4CON_CON7_PWM7 (0x2 << 14 ) /* PWM7 */ + +/* GP4CON[CON6] - Configuration bits for P4.6 */ +#define GP4CON_CON6_MSK (0x3 << 12 ) +#define GP4CON_CON6_GPIO (0x1 << 12 ) /* GPIO */ +#define GP4CON_CON6_PWM6 (0x2 << 12 ) /* PWM6 */ + +/* GP4CON[CON5] - Configuration bits for P4.5 */ +#define GP4CON_CON5_MSK (0x3 << 10 ) +#define GP4CON_CON5_GPIO (0x1 << 10 ) /* GPIO */ +#define GP4CON_CON5_PWM5 (0x2 << 10 ) /* PWM5 */ + +/* GP4CON[CON4] - Configuration bits for P4.4 */ +#define GP4CON_CON4_MSK (0x3 << 8 ) +#define GP4CON_CON4_GPIO (0x1 << 8 ) /* GPIO */ +#define GP4CON_CON4_PWM4 (0x2 << 8 ) /* PWM4 */ + +/* GP4CON[CON3] - Configuration bits for P4.3 */ +#define GP4CON_CON3_MSK (0x3 << 6 ) +#define GP4CON_CON3_GPIO (0x1 << 6 ) /* GPIO */ +#define GP4CON_CON3_PWM3 (0x2 << 6 ) /* PWM3 */ + +/* GP4CON[CON2] - Configuration bits for P4.2 */ +#define GP4CON_CON2_MSK (0x3 << 4 ) +#define GP4CON_CON2_GPIO (0x1 << 4 ) /* GPIO */ +#define GP4CON_CON2_PWM2 (0x2 << 4 ) /* PWM2 */ +#define GP4CON_CON2_SPI0CS (0x3 << 4 ) /* SPI0CS */ + +/* GP4CON[CON1] - Configuration bits for P4.1 */ +#define GP4CON_CON1_MSK (0x3 << 2 ) +#define GP4CON_CON1_GPIO (0x1 << 2 ) /* GPIO */ +#define GP4CON_CON1_PWM1 (0x2 << 2 ) /* PWM1 */ + +/* GP4CON[CON0] - Configuration bits for P4.0 */ +#define GP4CON_CON0_MSK (0x3 << 0 ) +#define GP4CON_CON0_GPIO (0x1 << 0 ) /* GPIO */ +#define GP4CON_CON0_PWM0 (0x2 << 0 ) /* PWM0 */ + +/* Reset Value for GP4OEN*/ +#define GP4OEN_RVAL 0x0 + +/* GP4OEN[OEN7] - Port pin direction. */ +#define GP4OEN_OEN7_BBA (*(volatile unsigned long *) 0x420C189C) +#define GP4OEN_OEN7_MSK (0x1 << 7 ) +#define GP4OEN_OEN7 (0x1 << 7 ) +#define GP4OEN_OEN7_IN (0x0 << 7 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP4OEN_OEN7_OUT (0x1 << 7 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP4OEN[OEN6] - Port pin direction. */ +#define GP4OEN_OEN6_BBA (*(volatile unsigned long *) 0x420C1898) +#define GP4OEN_OEN6_MSK (0x1 << 6 ) +#define GP4OEN_OEN6 (0x1 << 6 ) +#define GP4OEN_OEN6_IN (0x0 << 6 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP4OEN_OEN6_OUT (0x1 << 6 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP4OEN[OEN5] - Port pin direction. */ +#define GP4OEN_OEN5_BBA (*(volatile unsigned long *) 0x420C1894) +#define GP4OEN_OEN5_MSK (0x1 << 5 ) +#define GP4OEN_OEN5 (0x1 << 5 ) +#define GP4OEN_OEN5_IN (0x0 << 5 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP4OEN_OEN5_OUT (0x1 << 5 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP4OEN[OEN4] - Port pin direction. */ +#define GP4OEN_OEN4_BBA (*(volatile unsigned long *) 0x420C1890) +#define GP4OEN_OEN4_MSK (0x1 << 4 ) +#define GP4OEN_OEN4 (0x1 << 4 ) +#define GP4OEN_OEN4_IN (0x0 << 4 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP4OEN_OEN4_OUT (0x1 << 4 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP4OEN[OEN3] - Port pin direction. */ +#define GP4OEN_OEN3_BBA (*(volatile unsigned long *) 0x420C188C) +#define GP4OEN_OEN3_MSK (0x1 << 3 ) +#define GP4OEN_OEN3 (0x1 << 3 ) +#define GP4OEN_OEN3_IN (0x0 << 3 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP4OEN_OEN3_OUT (0x1 << 3 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP4OEN[OEN2] - Port pin direction. */ +#define GP4OEN_OEN2_BBA (*(volatile unsigned long *) 0x420C1888) +#define GP4OEN_OEN2_MSK (0x1 << 2 ) +#define GP4OEN_OEN2 (0x1 << 2 ) +#define GP4OEN_OEN2_IN (0x0 << 2 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP4OEN_OEN2_OUT (0x1 << 2 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP4OEN[OEN1] - Port pin direction. */ +#define GP4OEN_OEN1_BBA (*(volatile unsigned long *) 0x420C1884) +#define GP4OEN_OEN1_MSK (0x1 << 1 ) +#define GP4OEN_OEN1 (0x1 << 1 ) +#define GP4OEN_OEN1_IN (0x0 << 1 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP4OEN_OEN1_OUT (0x1 << 1 ) /* OUT. Enables the output on corresponding port pin. */ + +/* GP4OEN[OEN0] - Port pin direction. */ +#define GP4OEN_OEN0_BBA (*(volatile unsigned long *) 0x420C1880) +#define GP4OEN_OEN0_MSK (0x1 << 0 ) +#define GP4OEN_OEN0 (0x1 << 0 ) +#define GP4OEN_OEN0_IN (0x0 << 0 ) /* IN. Configures pin as an input. Disables the output on corresponding port pin. */ +#define GP4OEN_OEN0_OUT (0x1 << 0 ) /* OUT. Enables the output on corresponding port pin. */ + +/* Reset Value for GP4PUL*/ +#define GP4PUL_RVAL 0xFF + +/* GP4PUL[PUL7] - Pull Up Enable for port pin. */ +#define GP4PUL_PUL7_BBA (*(volatile unsigned long *) 0x420C191C) +#define GP4PUL_PUL7_MSK (0x1 << 7 ) +#define GP4PUL_PUL7 (0x1 << 7 ) +#define GP4PUL_PUL7_DIS (0x0 << 7 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP4PUL_PUL7_EN (0x1 << 7 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP4PUL[PUL6] - Pull Up Enable for port pin. */ +#define GP4PUL_PUL6_BBA (*(volatile unsigned long *) 0x420C1918) +#define GP4PUL_PUL6_MSK (0x1 << 6 ) +#define GP4PUL_PUL6 (0x1 << 6 ) +#define GP4PUL_PUL6_DIS (0x0 << 6 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP4PUL_PUL6_EN (0x1 << 6 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP4PUL[PUL5] - Pull Up Enable for port pin. */ +#define GP4PUL_PUL5_BBA (*(volatile unsigned long *) 0x420C1914) +#define GP4PUL_PUL5_MSK (0x1 << 5 ) +#define GP4PUL_PUL5 (0x1 << 5 ) +#define GP4PUL_PUL5_DIS (0x0 << 5 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP4PUL_PUL5_EN (0x1 << 5 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP4PUL[PUL4] - Pull Up Enable for port pin. */ +#define GP4PUL_PUL4_BBA (*(volatile unsigned long *) 0x420C1910) +#define GP4PUL_PUL4_MSK (0x1 << 4 ) +#define GP4PUL_PUL4 (0x1 << 4 ) +#define GP4PUL_PUL4_DIS (0x0 << 4 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP4PUL_PUL4_EN (0x1 << 4 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP4PUL[PUL3] - Pull Up Enable for port pin. */ +#define GP4PUL_PUL3_BBA (*(volatile unsigned long *) 0x420C190C) +#define GP4PUL_PUL3_MSK (0x1 << 3 ) +#define GP4PUL_PUL3 (0x1 << 3 ) +#define GP4PUL_PUL3_DIS (0x0 << 3 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP4PUL_PUL3_EN (0x1 << 3 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP4PUL[PUL2] - Pull Up Enable for port pin. */ +#define GP4PUL_PUL2_BBA (*(volatile unsigned long *) 0x420C1908) +#define GP4PUL_PUL2_MSK (0x1 << 2 ) +#define GP4PUL_PUL2 (0x1 << 2 ) +#define GP4PUL_PUL2_DIS (0x0 << 2 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP4PUL_PUL2_EN (0x1 << 2 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP4PUL[PUL1] - Pull Up Enable for port pin. */ +#define GP4PUL_PUL1_BBA (*(volatile unsigned long *) 0x420C1904) +#define GP4PUL_PUL1_MSK (0x1 << 1 ) +#define GP4PUL_PUL1 (0x1 << 1 ) +#define GP4PUL_PUL1_DIS (0x0 << 1 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP4PUL_PUL1_EN (0x1 << 1 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* GP4PUL[PUL0] - Pull Up Enable for port pin. */ +#define GP4PUL_PUL0_BBA (*(volatile unsigned long *) 0x420C1900) +#define GP4PUL_PUL0_MSK (0x1 << 0 ) +#define GP4PUL_PUL0 (0x1 << 0 ) +#define GP4PUL_PUL0_DIS (0x0 << 0 ) /* DIS. Disables the internal pull up on corresponding port pin. */ +#define GP4PUL_PUL0_EN (0x1 << 0 ) /* EN. Enables the internal pull up on corresponding port pin. */ + +/* Reset Value for GP4OCE*/ +#define GP4OCE_RVAL 0x0 + +/* GP4OCE[OCE7] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP4OCE_OCE7_BBA (*(volatile unsigned long *) 0x420C199C) +#define GP4OCE_OCE7_MSK (0x1 << 7 ) +#define GP4OCE_OCE7 (0x1 << 7 ) +#define GP4OCE_OCE7_DIS (0x0 << 7 ) /* DIS */ +#define GP4OCE_OCE7_EN (0x1 << 7 ) /* EN */ + +/* GP4OCE[OCE6] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP4OCE_OCE6_BBA (*(volatile unsigned long *) 0x420C1998) +#define GP4OCE_OCE6_MSK (0x1 << 6 ) +#define GP4OCE_OCE6 (0x1 << 6 ) +#define GP4OCE_OCE6_DIS (0x0 << 6 ) /* DIS */ +#define GP4OCE_OCE6_EN (0x1 << 6 ) /* EN */ + +/* GP4OCE[OCE5] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP4OCE_OCE5_BBA (*(volatile unsigned long *) 0x420C1994) +#define GP4OCE_OCE5_MSK (0x1 << 5 ) +#define GP4OCE_OCE5 (0x1 << 5 ) +#define GP4OCE_OCE5_DIS (0x0 << 5 ) /* DIS */ +#define GP4OCE_OCE5_EN (0x1 << 5 ) /* EN */ + +/* GP4OCE[OCE4] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP4OCE_OCE4_BBA (*(volatile unsigned long *) 0x420C1990) +#define GP4OCE_OCE4_MSK (0x1 << 4 ) +#define GP4OCE_OCE4 (0x1 << 4 ) +#define GP4OCE_OCE4_DIS (0x0 << 4 ) /* DIS */ +#define GP4OCE_OCE4_EN (0x1 << 4 ) /* EN */ + +/* GP4OCE[OCE3] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP4OCE_OCE3_BBA (*(volatile unsigned long *) 0x420C198C) +#define GP4OCE_OCE3_MSK (0x1 << 3 ) +#define GP4OCE_OCE3 (0x1 << 3 ) +#define GP4OCE_OCE3_DIS (0x0 << 3 ) /* DIS */ +#define GP4OCE_OCE3_EN (0x1 << 3 ) /* EN */ + +/* GP4OCE[OCE2] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP4OCE_OCE2_BBA (*(volatile unsigned long *) 0x420C1988) +#define GP4OCE_OCE2_MSK (0x1 << 2 ) +#define GP4OCE_OCE2 (0x1 << 2 ) +#define GP4OCE_OCE2_DIS (0x0 << 2 ) /* DIS */ +#define GP4OCE_OCE2_EN (0x1 << 2 ) /* EN */ + +/* GP4OCE[OCE1] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP4OCE_OCE1_BBA (*(volatile unsigned long *) 0x420C1984) +#define GP4OCE_OCE1_MSK (0x1 << 1 ) +#define GP4OCE_OCE1 (0x1 << 1 ) +#define GP4OCE_OCE1_DIS (0x0 << 1 ) /* DIS */ +#define GP4OCE_OCE1_EN (0x1 << 1 ) /* EN */ + +/* GP4OCE[OCE0] - Output enable. Sets the GPIO pads on corresponding port to open circuit mode. */ +#define GP4OCE_OCE0_BBA (*(volatile unsigned long *) 0x420C1980) +#define GP4OCE_OCE0_MSK (0x1 << 0 ) +#define GP4OCE_OCE0 (0x1 << 0 ) +#define GP4OCE_OCE0_DIS (0x0 << 0 ) /* DIS */ +#define GP4OCE_OCE0_EN (0x1 << 0 ) /* EN */ + +/* Reset Value for GP4IN*/ +#define GP4IN_RVAL 0xFF + +/* GP4IN[IN7] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP4IN_IN7_BBA (*(volatile unsigned long *) 0x420C1A9C) +#define GP4IN_IN7_MSK (0x1 << 7 ) +#define GP4IN_IN7 (0x1 << 7 ) +#define GP4IN_IN7_LOW (0x0 << 7 ) /* LOW */ +#define GP4IN_IN7_HIGH (0x1 << 7 ) /* HIGH */ + +/* GP4IN[IN6] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP4IN_IN6_BBA (*(volatile unsigned long *) 0x420C1A98) +#define GP4IN_IN6_MSK (0x1 << 6 ) +#define GP4IN_IN6 (0x1 << 6 ) +#define GP4IN_IN6_LOW (0x0 << 6 ) /* LOW */ +#define GP4IN_IN6_HIGH (0x1 << 6 ) /* HIGH */ + +/* GP4IN[IN5] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP4IN_IN5_BBA (*(volatile unsigned long *) 0x420C1A94) +#define GP4IN_IN5_MSK (0x1 << 5 ) +#define GP4IN_IN5 (0x1 << 5 ) +#define GP4IN_IN5_LOW (0x0 << 5 ) /* LOW */ +#define GP4IN_IN5_HIGH (0x1 << 5 ) /* HIGH */ + +/* GP4IN[IN4] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP4IN_IN4_BBA (*(volatile unsigned long *) 0x420C1A90) +#define GP4IN_IN4_MSK (0x1 << 4 ) +#define GP4IN_IN4 (0x1 << 4 ) +#define GP4IN_IN4_LOW (0x0 << 4 ) /* LOW */ +#define GP4IN_IN4_HIGH (0x1 << 4 ) /* HIGH */ + +/* GP4IN[IN3] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP4IN_IN3_BBA (*(volatile unsigned long *) 0x420C1A8C) +#define GP4IN_IN3_MSK (0x1 << 3 ) +#define GP4IN_IN3 (0x1 << 3 ) +#define GP4IN_IN3_LOW (0x0 << 3 ) /* LOW */ +#define GP4IN_IN3_HIGH (0x1 << 3 ) /* HIGH */ + +/* GP4IN[IN2] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP4IN_IN2_BBA (*(volatile unsigned long *) 0x420C1A88) +#define GP4IN_IN2_MSK (0x1 << 2 ) +#define GP4IN_IN2 (0x1 << 2 ) +#define GP4IN_IN2_LOW (0x0 << 2 ) /* LOW */ +#define GP4IN_IN2_HIGH (0x1 << 2 ) /* HIGH */ + +/* GP4IN[IN1] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP4IN_IN1_BBA (*(volatile unsigned long *) 0x420C1A84) +#define GP4IN_IN1_MSK (0x1 << 1 ) +#define GP4IN_IN1 (0x1 << 1 ) +#define GP4IN_IN1_LOW (0x0 << 1 ) /* LOW */ +#define GP4IN_IN1_HIGH (0x1 << 1 ) /* HIGH */ + +/* GP4IN[IN0] - Reflects the level on the corresponding GPIO pins except when in configured in open circuit. */ +#define GP4IN_IN0_BBA (*(volatile unsigned long *) 0x420C1A80) +#define GP4IN_IN0_MSK (0x1 << 0 ) +#define GP4IN_IN0 (0x1 << 0 ) +#define GP4IN_IN0_LOW (0x0 << 0 ) /* LOW */ +#define GP4IN_IN0_HIGH (0x1 << 0 ) /* HIGH */ + +/* Reset Value for GP4OUT*/ +#define GP4OUT_RVAL 0x0 + +/* GP4OUT[OUT7] - Output for port pin. */ +#define GP4OUT_OUT7_BBA (*(volatile unsigned long *) 0x420C1B1C) +#define GP4OUT_OUT7_MSK (0x1 << 7 ) +#define GP4OUT_OUT7 (0x1 << 7 ) +#define GP4OUT_OUT7_LOW (0x0 << 7 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP4OUT_OUT7_HIGH (0x1 << 7 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP4OUT[OUT6] - Output for port pin. */ +#define GP4OUT_OUT6_BBA (*(volatile unsigned long *) 0x420C1B18) +#define GP4OUT_OUT6_MSK (0x1 << 6 ) +#define GP4OUT_OUT6 (0x1 << 6 ) +#define GP4OUT_OUT6_LOW (0x0 << 6 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP4OUT_OUT6_HIGH (0x1 << 6 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP4OUT[OUT5] - Output for port pin. */ +#define GP4OUT_OUT5_BBA (*(volatile unsigned long *) 0x420C1B14) +#define GP4OUT_OUT5_MSK (0x1 << 5 ) +#define GP4OUT_OUT5 (0x1 << 5 ) +#define GP4OUT_OUT5_LOW (0x0 << 5 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP4OUT_OUT5_HIGH (0x1 << 5 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP4OUT[OUT4] - Output for port pin. */ +#define GP4OUT_OUT4_BBA (*(volatile unsigned long *) 0x420C1B10) +#define GP4OUT_OUT4_MSK (0x1 << 4 ) +#define GP4OUT_OUT4 (0x1 << 4 ) +#define GP4OUT_OUT4_LOW (0x0 << 4 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP4OUT_OUT4_HIGH (0x1 << 4 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP4OUT[OUT3] - Output for port pin. */ +#define GP4OUT_OUT3_BBA (*(volatile unsigned long *) 0x420C1B0C) +#define GP4OUT_OUT3_MSK (0x1 << 3 ) +#define GP4OUT_OUT3 (0x1 << 3 ) +#define GP4OUT_OUT3_LOW (0x0 << 3 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP4OUT_OUT3_HIGH (0x1 << 3 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP4OUT[OUT2] - Output for port pin. */ +#define GP4OUT_OUT2_BBA (*(volatile unsigned long *) 0x420C1B08) +#define GP4OUT_OUT2_MSK (0x1 << 2 ) +#define GP4OUT_OUT2 (0x1 << 2 ) +#define GP4OUT_OUT2_LOW (0x0 << 2 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP4OUT_OUT2_HIGH (0x1 << 2 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP4OUT[OUT1] - Output for port pin. */ +#define GP4OUT_OUT1_BBA (*(volatile unsigned long *) 0x420C1B04) +#define GP4OUT_OUT1_MSK (0x1 << 1 ) +#define GP4OUT_OUT1 (0x1 << 1 ) +#define GP4OUT_OUT1_LOW (0x0 << 1 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP4OUT_OUT1_HIGH (0x1 << 1 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* GP4OUT[OUT0] - Output for port pin. */ +#define GP4OUT_OUT0_BBA (*(volatile unsigned long *) 0x420C1B00) +#define GP4OUT_OUT0_MSK (0x1 << 0 ) +#define GP4OUT_OUT0 (0x1 << 0 ) +#define GP4OUT_OUT0_LOW (0x0 << 0 ) /* LOW. Cleared by user to drive the corresponding GPIO low. */ +#define GP4OUT_OUT0_HIGH (0x1 << 0 ) /* HIGH. Set by user code to drive the corresponding GPIO high. */ + +/* Reset Value for GP4SET*/ +#define GP4SET_RVAL 0x0 + +/* GP4SET[SET7] - Set output high for corresponding port pin. */ +#define GP4SET_SET7_BBA (*(volatile unsigned long *) 0x420C1B9C) +#define GP4SET_SET7_MSK (0x1 << 7 ) +#define GP4SET_SET7 (0x1 << 7 ) +#define GP4SET_SET7_SET (0x1 << 7 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP4SET[SET6] - Set output high for corresponding port pin. */ +#define GP4SET_SET6_BBA (*(volatile unsigned long *) 0x420C1B98) +#define GP4SET_SET6_MSK (0x1 << 6 ) +#define GP4SET_SET6 (0x1 << 6 ) +#define GP4SET_SET6_SET (0x1 << 6 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP4SET[SET5] - Set output high for corresponding port pin. */ +#define GP4SET_SET5_BBA (*(volatile unsigned long *) 0x420C1B94) +#define GP4SET_SET5_MSK (0x1 << 5 ) +#define GP4SET_SET5 (0x1 << 5 ) +#define GP4SET_SET5_SET (0x1 << 5 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP4SET[SET4] - Set output high for corresponding port pin. */ +#define GP4SET_SET4_BBA (*(volatile unsigned long *) 0x420C1B90) +#define GP4SET_SET4_MSK (0x1 << 4 ) +#define GP4SET_SET4 (0x1 << 4 ) +#define GP4SET_SET4_SET (0x1 << 4 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP4SET[SET3] - Set output high for corresponding port pin. */ +#define GP4SET_SET3_BBA (*(volatile unsigned long *) 0x420C1B8C) +#define GP4SET_SET3_MSK (0x1 << 3 ) +#define GP4SET_SET3 (0x1 << 3 ) +#define GP4SET_SET3_SET (0x1 << 3 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP4SET[SET2] - Set output high for corresponding port pin. */ +#define GP4SET_SET2_BBA (*(volatile unsigned long *) 0x420C1B88) +#define GP4SET_SET2_MSK (0x1 << 2 ) +#define GP4SET_SET2 (0x1 << 2 ) +#define GP4SET_SET2_SET (0x1 << 2 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP4SET[SET1] - Set output high for corresponding port pin. */ +#define GP4SET_SET1_BBA (*(volatile unsigned long *) 0x420C1B84) +#define GP4SET_SET1_MSK (0x1 << 1 ) +#define GP4SET_SET1 (0x1 << 1 ) +#define GP4SET_SET1_SET (0x1 << 1 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* GP4SET[SET0] - Set output high for corresponding port pin. */ +#define GP4SET_SET0_BBA (*(volatile unsigned long *) 0x420C1B80) +#define GP4SET_SET0_MSK (0x1 << 0 ) +#define GP4SET_SET0 (0x1 << 0 ) +#define GP4SET_SET0_SET (0x1 << 0 ) /* SET. Set by user code to drive the corresponding GPIO high. */ + +/* Reset Value for GP4CLR*/ +#define GP4CLR_RVAL 0x0 + +/* GP4CLR[CLR7] - Set by user code to drive the corresponding GPIO low. */ +#define GP4CLR_CLR7_BBA (*(volatile unsigned long *) 0x420C1C1C) +#define GP4CLR_CLR7_MSK (0x1 << 7 ) +#define GP4CLR_CLR7 (0x1 << 7 ) +#define GP4CLR_CLR7_CLR (0x1 << 7 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP4CLR[CLR6] - Set by user code to drive the corresponding GPIO low. */ +#define GP4CLR_CLR6_BBA (*(volatile unsigned long *) 0x420C1C18) +#define GP4CLR_CLR6_MSK (0x1 << 6 ) +#define GP4CLR_CLR6 (0x1 << 6 ) +#define GP4CLR_CLR6_CLR (0x1 << 6 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP4CLR[CLR5] - Set by user code to drive the corresponding GPIO low. */ +#define GP4CLR_CLR5_BBA (*(volatile unsigned long *) 0x420C1C14) +#define GP4CLR_CLR5_MSK (0x1 << 5 ) +#define GP4CLR_CLR5 (0x1 << 5 ) +#define GP4CLR_CLR5_CLR (0x1 << 5 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP4CLR[CLR4] - Set by user code to drive the corresponding GPIO low. */ +#define GP4CLR_CLR4_BBA (*(volatile unsigned long *) 0x420C1C10) +#define GP4CLR_CLR4_MSK (0x1 << 4 ) +#define GP4CLR_CLR4 (0x1 << 4 ) +#define GP4CLR_CLR4_CLR (0x1 << 4 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP4CLR[CLR3] - Set by user code to drive the corresponding GPIO low. */ +#define GP4CLR_CLR3_BBA (*(volatile unsigned long *) 0x420C1C0C) +#define GP4CLR_CLR3_MSK (0x1 << 3 ) +#define GP4CLR_CLR3 (0x1 << 3 ) +#define GP4CLR_CLR3_CLR (0x1 << 3 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP4CLR[CLR2] - Set by user code to drive the corresponding GPIO low. */ +#define GP4CLR_CLR2_BBA (*(volatile unsigned long *) 0x420C1C08) +#define GP4CLR_CLR2_MSK (0x1 << 2 ) +#define GP4CLR_CLR2 (0x1 << 2 ) +#define GP4CLR_CLR2_CLR (0x1 << 2 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP4CLR[CLR1] - Set by user code to drive the corresponding GPIO low. */ +#define GP4CLR_CLR1_BBA (*(volatile unsigned long *) 0x420C1C04) +#define GP4CLR_CLR1_MSK (0x1 << 1 ) +#define GP4CLR_CLR1 (0x1 << 1 ) +#define GP4CLR_CLR1_CLR (0x1 << 1 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* GP4CLR[CLR0] - Set by user code to drive the corresponding GPIO low. */ +#define GP4CLR_CLR0_BBA (*(volatile unsigned long *) 0x420C1C00) +#define GP4CLR_CLR0_MSK (0x1 << 0 ) +#define GP4CLR_CLR0 (0x1 << 0 ) +#define GP4CLR_CLR0_CLR (0x1 << 0 ) /* CLR. Set by user code to drive the corresponding GPIO low. */ + +/* Reset Value for GP4TGL*/ +#define GP4TGL_RVAL 0x0 + +/* GP4TGL[TGL7] - Toggle for corresponding port pin. */ +#define GP4TGL_TGL7_BBA (*(volatile unsigned long *) 0x420C1C9C) +#define GP4TGL_TGL7_MSK (0x1 << 7 ) +#define GP4TGL_TGL7 (0x1 << 7 ) +#define GP4TGL_TGL7_TGL (0x1 << 7 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP4TGL[TGL6] - Toggle for corresponding port pin. */ +#define GP4TGL_TGL6_BBA (*(volatile unsigned long *) 0x420C1C98) +#define GP4TGL_TGL6_MSK (0x1 << 6 ) +#define GP4TGL_TGL6 (0x1 << 6 ) +#define GP4TGL_TGL6_TGL (0x1 << 6 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP4TGL[TGL5] - Toggle for corresponding port pin. */ +#define GP4TGL_TGL5_BBA (*(volatile unsigned long *) 0x420C1C94) +#define GP4TGL_TGL5_MSK (0x1 << 5 ) +#define GP4TGL_TGL5 (0x1 << 5 ) +#define GP4TGL_TGL5_TGL (0x1 << 5 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP4TGL[TGL4] - Toggle for corresponding port pin. */ +#define GP4TGL_TGL4_BBA (*(volatile unsigned long *) 0x420C1C90) +#define GP4TGL_TGL4_MSK (0x1 << 4 ) +#define GP4TGL_TGL4 (0x1 << 4 ) +#define GP4TGL_TGL4_TGL (0x1 << 4 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP4TGL[TGL3] - Toggle for corresponding port pin. */ +#define GP4TGL_TGL3_BBA (*(volatile unsigned long *) 0x420C1C8C) +#define GP4TGL_TGL3_MSK (0x1 << 3 ) +#define GP4TGL_TGL3 (0x1 << 3 ) +#define GP4TGL_TGL3_TGL (0x1 << 3 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP4TGL[TGL2] - Toggle for corresponding port pin. */ +#define GP4TGL_TGL2_BBA (*(volatile unsigned long *) 0x420C1C88) +#define GP4TGL_TGL2_MSK (0x1 << 2 ) +#define GP4TGL_TGL2 (0x1 << 2 ) +#define GP4TGL_TGL2_TGL (0x1 << 2 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP4TGL[TGL1] - Toggle for corresponding port pin. */ +#define GP4TGL_TGL1_BBA (*(volatile unsigned long *) 0x420C1C84) +#define GP4TGL_TGL1_MSK (0x1 << 1 ) +#define GP4TGL_TGL1 (0x1 << 1 ) +#define GP4TGL_TGL1_TGL (0x1 << 1 ) /* TGL. Set by user code to invert the corresponding GPIO. */ + +/* GP4TGL[TGL0] - Toggle for corresponding port pin. */ +#define GP4TGL_TGL0_BBA (*(volatile unsigned long *) 0x420C1C80) +#define GP4TGL_TGL0_MSK (0x1 << 0 ) +#define GP4TGL_TGL0 (0x1 << 0 ) +#define GP4TGL_TGL0_TGL (0x1 << 0 ) /* TGL. Set by user code to invert the corresponding GPIO. */ +// ------------------------------------------------------------------------------------------------ +// ----- GPIOCMN ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief General Purpose Input Output (pADI_GPIOCMN) + */ + +#if (__NO_MMR_STRUCTS__==0) +typedef struct { /*!< pADI_GPIOCMN Structure */ + __IO uint8_t GPDWN; /*!< GPIO P3.4 Pull Down Control */ +} ADI_GPIOCMN_TypeDef; +#else // (__NO_MMR_STRUCTS__==0) +#define GPDWN (*(volatile unsigned char *) 0x400060F0) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for GPDWN*/ +#define GPDWN_RVAL 0x1 + +/* GPDWN[DWN1] - Pull down resistor control bit */ +#define GPDWN_DWN1_BBA (*(volatile unsigned long *) 0x420C1E04) +#define GPDWN_DWN1_MSK (0x1 << 1 ) +#define GPDWN_DWN1 (0x1 << 1 ) +#define GPDWN_DWN1_EN (0x0 << 1 ) /* EN to enable the pull down resistor on P3.4 by software. The hardware only enables this pull down automatically at power up. */ +#define GPDWN_DWN1_DIS (0x1 << 1 ) /* DIS to disable the pull down resistor on P3.4. Disabled automatically by hardware if GP3PUL[4] =1 or if GP3OEN[4]=1. */ +// ------------------------------------------------------------------------------------------------ +// ----- MISC ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief General Purpose Input Output (pADI_MISC) + */ + +#if (__NO_MMR_STRUCTS__==0) +typedef struct { /*!< pADI_MISC Structure */ + __I uint32_t RESERVED0; + __IO uint16_t RFTST; /*!< Internal Radio Test Mode Access */ + __I uint16_t RESERVED1[5]; + __IO uint8_t SWACT; /*!< Serial Wire Activity Register */ +} ADI_MISC_TypeDef; +#else // (__NO_MMR_STRUCTS__==0) +#define RFTST (*(volatile unsigned short int *) 0x40008824) +#define SWACT (*(volatile unsigned char *) 0x40008830) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for RFTST*/ +#define RFTST_RVAL 0x0 + +/* RFTST[DIR] - Controls the pin direction in RF test mode. */ +#define RFTST_DIR_MSK (0x7FF << 5 ) + +/* RFTST[AN1] - Enable RF Analog test 2 mode. */ +#define RFTST_AN1_BBA (*(volatile unsigned long *) 0x4211048C) +#define RFTST_AN1_MSK (0x1 << 3 ) +#define RFTST_AN1 (0x1 << 3 ) +#define RFTST_AN1_DIS (0x0 << 3 ) /* DIS */ +#define RFTST_AN1_EN (0x1 << 3 ) /* EN */ + +/* RFTST[AN0] - Enable RF Analog test mode. */ +#define RFTST_AN0_BBA (*(volatile unsigned long *) 0x42110488) +#define RFTST_AN0_MSK (0x1 << 2 ) +#define RFTST_AN0 (0x1 << 2 ) +#define RFTST_AN0_DIS (0x0 << 2 ) /* DIS */ +#define RFTST_AN0_EN (0x1 << 2 ) /* EN */ + +/* RFTST[SPI0] - Enable the internal SPI0 signals to P0.0, P0.1, P0.2 and P0.3. */ +#define RFTST_SPI0_BBA (*(volatile unsigned long *) 0x42110484) +#define RFTST_SPI0_MSK (0x1 << 1 ) +#define RFTST_SPI0 (0x1 << 1 ) +#define RFTST_SPI0_DIS (0x0 << 1 ) /* DIS */ +#define RFTST_SPI0_EN (0x1 << 1 ) /* EN */ + +/* RFTST[GPX] - Connect the internal GPIOs GP0-GP5 of the RF transceiver to external GPIOs P0.6, P0.7, P1.0, P1.1, P1.4, P1.5. */ +#define RFTST_GPX_BBA (*(volatile unsigned long *) 0x42110480) +#define RFTST_GPX_MSK (0x1 << 0 ) +#define RFTST_GPX (0x1 << 0 ) +#define RFTST_GPX_DIS (0x0 << 0 ) /* DIS */ +#define RFTST_GPX_EN (0x1 << 0 ) /* EN */ + +/* Reset Value for SWACT*/ +#define SWACT_RVAL 0x0 + +/* SWACT[ACT] - Serial Wire Activity */ +#define SWACT_ACT_BBA (*(volatile unsigned long *) 0x42110600) +#define SWACT_ACT_MSK (0x1 << 0 ) +#define SWACT_ACT (0x1 << 0 ) +#define SWACT_ACT_DIS (0x0 << 0 ) /* DIS */ +#define SWACT_ACT_EN (0x1 << 0 ) /* EN */ +// ------------------------------------------------------------------------------------------------ +// ----- I2C ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief I2C (pADI_I2C) + */ + +#if (__NO_MMR_STRUCTS__==0) +typedef struct { /*!< pADI_I2C Structure */ + __IO uint16_t I2CMCON; /*!< Master Control Register */ + __I uint16_t RESERVED0; + __IO uint16_t I2CMSTA; /*!< Master Status Register */ + __I uint16_t RESERVED1; + __IO uint16_t I2CMRX; /*!< Master Receive Data Register */ + __I uint16_t RESERVED2; + __IO uint16_t I2CMTX; /*!< Master Transmit Data Register */ + __I uint16_t RESERVED3; + __IO uint16_t I2CMRXCNT; /*!< Master Receive Data Count Register */ + __I uint16_t RESERVED4; + __IO uint16_t I2CMCRXCNT; /*!< Master Current Receive Data Count Register */ + __I uint16_t RESERVED5; + __IO uint8_t I2CADR0; /*!< First Master Address Byte Register */ + __I uint8_t RESERVED6[3]; + __IO uint8_t I2CADR1; /*!< Second Master Address Byte Register */ + __I uint8_t RESERVED7[7]; + __IO uint16_t I2CDIV; /*!< Serial Clock Period Divisor Register */ + __I uint16_t RESERVED8; + __IO uint16_t I2CSCON; /*!< Slave Control Register */ + __I uint16_t RESERVED9; + __IO uint16_t I2CSSTA; /*!< Slave I2C Status, Error and Interrupt Register */ + __I uint16_t RESERVED10; + __IO uint16_t I2CSRX; /*!< Slave Receive Data Register */ + __I uint16_t RESERVED11; + __IO uint16_t I2CSTX; /*!< Slave Transmit Data Register */ + __I uint16_t RESERVED12; + __IO uint16_t I2CALT; /*!< Hardware General Call ID Register */ + __I uint16_t RESERVED13; + __IO uint16_t I2CID0; /*!< First Slave Address Device ID */ + __I uint16_t RESERVED14; + __IO uint16_t I2CID1; /*!< Second Slave Address Device ID */ + __I uint16_t RESERVED15; + __IO uint16_t I2CID2; /*!< Third Slave Address Device ID */ + __I uint16_t RESERVED16; + __IO uint16_t I2CID3; /*!< Fourth Slave Address Device ID */ + __I uint16_t RESERVED17; + __IO uint16_t I2CFSTA; /*!< Master and Slave Rx/Tx FIFO Status Register */ +} ADI_I2C_TypeDef; +#else // (__NO_MMR_STRUCTS__==0) +#define I2CMCON (*(volatile unsigned short int *) 0x40003000) +#define I2CMSTA (*(volatile unsigned short int *) 0x40003004) +#define I2CMRX (*(volatile unsigned short int *) 0x40003008) +#define I2CMTX (*(volatile unsigned short int *) 0x4000300C) +#define I2CMRXCNT (*(volatile unsigned short int *) 0x40003010) +#define I2CMCRXCNT (*(volatile unsigned short int *) 0x40003014) +#define I2CADR0 (*(volatile unsigned char *) 0x40003018) +#define I2CADR1 (*(volatile unsigned char *) 0x4000301C) +#define I2CDIV (*(volatile unsigned short int *) 0x40003024) +#define I2CSCON (*(volatile unsigned short int *) 0x40003028) +#define I2CSSTA (*(volatile unsigned short int *) 0x4000302C) +#define I2CSRX (*(volatile unsigned short int *) 0x40003030) +#define I2CSTX (*(volatile unsigned short int *) 0x40003034) +#define I2CALT (*(volatile unsigned short int *) 0x40003038) +#define I2CID0 (*(volatile unsigned short int *) 0x4000303C) +#define I2CID1 (*(volatile unsigned short int *) 0x40003040) +#define I2CID2 (*(volatile unsigned short int *) 0x40003044) +#define I2CID3 (*(volatile unsigned short int *) 0x40003048) +#define I2CFSTA (*(volatile unsigned short int *) 0x4000304C) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for I2CMCON*/ +#define I2CMCON_RVAL 0x0 + +/* I2CMCON[TXDMA] - Enable master Tx DMA request. */ +#define I2CMCON_TXDMA_BBA (*(volatile unsigned long *) 0x4206002C) +#define I2CMCON_TXDMA_MSK (0x1 << 11 ) +#define I2CMCON_TXDMA (0x1 << 11 ) +#define I2CMCON_TXDMA_DIS (0x0 << 11 ) /* DIS. Disable Tx DMA mode. */ +#define I2CMCON_TXDMA_EN (0x1 << 11 ) /* EN. Enable I2C master DMA requests. */ + +/* I2CMCON[RXDMA] - Enable master Rx DMA request. */ +#define I2CMCON_RXDMA_BBA (*(volatile unsigned long *) 0x42060028) +#define I2CMCON_RXDMA_MSK (0x1 << 10 ) +#define I2CMCON_RXDMA (0x1 << 10 ) +#define I2CMCON_RXDMA_DIS (0x0 << 10 ) /* DIS. Disable Rx DMA mode. */ +#define I2CMCON_RXDMA_EN (0x1 << 10 ) /* EN. Enable I2C master DMA requests. */ + +/* I2CMCON[IENCMP] - Transaction completed (or stop detected) interrupt enable. */ +#define I2CMCON_IENCMP_BBA (*(volatile unsigned long *) 0x42060020) +#define I2CMCON_IENCMP_MSK (0x1 << 8 ) +#define I2CMCON_IENCMP (0x1 << 8 ) +#define I2CMCON_IENCMP_DIS (0x0 << 8 ) /* DIS. Interrupt disabled. */ +#define I2CMCON_IENCMP_EN (0x1 << 8 ) /* EN. Interrupt enabled. A master I2C interrupt is generated when a STOP is detected. Enables TCOMP to geneerate an interrupt. */ + +/* I2CMCON[IENNACK] - NACK received interrupt enable. */ +#define I2CMCON_IENNACK_BBA (*(volatile unsigned long *) 0x4206001C) +#define I2CMCON_IENNACK_MSK (0x1 << 7 ) +#define I2CMCON_IENNACK (0x1 << 7 ) +#define I2CMCON_IENNACK_DIS (0x0 << 7 ) /* DIS. Interrupt disabled. */ +#define I2CMCON_IENNACK_EN (0x1 << 7 ) /* EN, enables NACKADDR(I2CMSTA[4]) and NACKDATA (I2CMSTA[7]) to generate an interrupt. */ + +/* I2CMCON[IENALOST] - Arbitration lost interrupt enable. */ +#define I2CMCON_IENALOST_BBA (*(volatile unsigned long *) 0x42060018) +#define I2CMCON_IENALOST_MSK (0x1 << 6 ) +#define I2CMCON_IENALOST (0x1 << 6 ) +#define I2CMCON_IENALOST_DIS (0x0 << 6 ) /* DIS. Interrupt disabled. */ +#define I2CMCON_IENALOST_EN (0x1 << 6 ) /* EN. Interrupt enabled. A master I2C interrupt is generated if the master looses arbitration.Enables ALOST to generate an interrupt. */ + +/* I2CMCON[IENTX] - Transmit request interrupt enable. */ +#define I2CMCON_IENTX_BBA (*(volatile unsigned long *) 0x42060014) +#define I2CMCON_IENTX_MSK (0x1 << 5 ) +#define I2CMCON_IENTX (0x1 << 5 ) +#define I2CMCON_IENTX_DIS (0x0 << 5 ) /* DIS. Interrupt disabled. */ +#define I2CMCON_IENTX_EN (0x1 << 5 ) /* EN. Interrupt enabled. A master I2C interrupt is generated when the Tx FIFO is not full and the direction bit is 0. */ + +/* I2CMCON[IENRX] - Receive request interrupt enable. */ +#define I2CMCON_IENRX_BBA (*(volatile unsigned long *) 0x42060010) +#define I2CMCON_IENRX_MSK (0x1 << 4 ) +#define I2CMCON_IENRX (0x1 << 4 ) +#define I2CMCON_IENRX_DIS (0x0 << 4 ) /* DIS. Interrupt disabled. */ +#define I2CMCON_IENRX_EN (0x1 << 4 ) /* EN. Interrupt enabled. A master I2C interrupt is generated when data is in the receive FIFO. */ + +/* I2CMCON[STRETCH] - Stretch I2CSCL enable. */ +#define I2CMCON_STRETCH_BBA (*(volatile unsigned long *) 0x4206000C) +#define I2CMCON_STRETCH_MSK (0x1 << 3 ) +#define I2CMCON_STRETCH (0x1 << 3 ) +#define I2CMCON_STRETCH_DIS (0x0 << 3 ) /* DIS. Disable */ +#define I2CMCON_STRETCH_EN (0x1 << 3 ) /* EN. Setting this bit instructs the device that if I2CSCL is 0, hold it at 0. Or if I2CSCL is 1, then when it next goes to 0, hold it at 0. */ + +/* I2CMCON[LOOPBACK] - Internal loop back enable. */ +#define I2CMCON_LOOPBACK_BBA (*(volatile unsigned long *) 0x42060008) +#define I2CMCON_LOOPBACK_MSK (0x1 << 2 ) +#define I2CMCON_LOOPBACK (0x1 << 2 ) +#define I2CMCON_LOOPBACK_DIS (0x0 << 2 ) /* DIS. Disable. */ +#define I2CMCON_LOOPBACK_EN (0x1 << 2 ) /* EN. I2CSCL and I2CSDA out of the device are muxed onto their corresponding inputs. Note that is also possible for the master to loop back a transfer to the slave as long as the device address corresponds, that is, external loopback. */ + +/* I2CMCON[COMPETE] - Start back-off disable. */ +#define I2CMCON_COMPETE_BBA (*(volatile unsigned long *) 0x42060004) +#define I2CMCON_COMPETE_MSK (0x1 << 1 ) +#define I2CMCON_COMPETE (0x1 << 1 ) +#define I2CMCON_COMPETE_DIS (0x0 << 1 ) /* DIS. Disable. */ +#define I2CMCON_COMPETE_EN (0x1 << 1 ) /* EN. Enables the device to compete for ownership even if another device is currently driving a start condition. */ + +/* I2CMCON[MAS] - Master enable bit. */ +#define I2CMCON_MAS_BBA (*(volatile unsigned long *) 0x42060000) +#define I2CMCON_MAS_MSK (0x1 << 0 ) +#define I2CMCON_MAS (0x1 << 0 ) +#define I2CMCON_MAS_DIS (0x0 << 0 ) /* DIS. The master is disabled. The master state machine is reset.The master should be disabled when not in use. This bit should not be cleared until a transaction has completed. TCOMP in I2CMSTA indicates when a transaction is complete. */ +#define I2CMCON_MAS_EN (0x1 << 0 ) /* EN. Enable master. */ + +/* Reset Value for I2CMSTA*/ +#define I2CMSTA_RVAL 0x0 + +/* I2CMSTA[TXUR] - Master transmit FIFO underrun. */ +#define I2CMSTA_TXUR_BBA (*(volatile unsigned long *) 0x420600B0) +#define I2CMSTA_TXUR_MSK (0x1 << 12 ) +#define I2CMSTA_TXUR (0x1 << 12 ) +#define I2CMSTA_TXUR_CLR (0x0 << 12 ) /* CLR. Cleared. */ +#define I2CMSTA_TXUR_SET (0x1 << 12 ) /* SET. Set when the I2C master ends the transaction due to a Tx FIFO empty condition. This bit is only set when IENTX (I2CSCON[5]) is set. */ + +/* I2CMSTA[MSTOP] - STOP driven by the I2C master. */ +#define I2CMSTA_MSTOP_BBA (*(volatile unsigned long *) 0x420600AC) +#define I2CMSTA_MSTOP_MSK (0x1 << 11 ) +#define I2CMSTA_MSTOP (0x1 << 11 ) +#define I2CMSTA_MSTOP_CLR (0x0 << 11 ) /* CLR. Cleared. */ +#define I2CMSTA_MSTOP_SET (0x1 << 11 ) /* SET. Set when the I2C master drives a stop condition on the I2C bus, therefore indicating a transaction completion, Tx underrun, Rx overflow, or a NACK by the slave. It is different from TCOMP because it is not set when the stop condition occurs due to any other master on the I2C bus. This bit does not generate an interrupt. See the TCOMP description for available interrupts related to the stop condition. */ + +/* I2CMSTA[LINEBUSY] - Line is busy. */ +#define I2CMSTA_LINEBUSY_BBA (*(volatile unsigned long *) 0x420600A8) +#define I2CMSTA_LINEBUSY_MSK (0x1 << 10 ) +#define I2CMSTA_LINEBUSY (0x1 << 10 ) +#define I2CMSTA_LINEBUSY_CLR (0x0 << 10 ) /* CLR. Cleared when a stop is detected on the I2C bus. */ +#define I2CMSTA_LINEBUSY_SET (0x1 << 10 ) /* SET. Set when a start is detected on the I2C bus. */ + +/* I2CMSTA[RXOF] - Receive FIFO overflow. */ +#define I2CMSTA_RXOF_BBA (*(volatile unsigned long *) 0x420600A4) +#define I2CMSTA_RXOF_MSK (0x1 << 9 ) +#define I2CMSTA_RXOF (0x1 << 9 ) +#define I2CMSTA_RXOF_CLR (0x0 << 9 ) /* CLR. CLeared. */ +#define I2CMSTA_RXOF_SET (0x1 << 9 ) /* SET. Set when a byte is written to the receive FIFO when the FIFO is already full. */ + +/* I2CMSTA[TCOMP] - Transaction completed (or stop detected). (Can drive an interrupt). */ +#define I2CMSTA_TCOMP_BBA (*(volatile unsigned long *) 0x420600A0) +#define I2CMSTA_TCOMP_MSK (0x1 << 8 ) +#define I2CMSTA_TCOMP (0x1 << 8 ) +#define I2CMSTA_TCOMP_CLR (0x0 << 8 ) /* CLR. Cleared. */ +#define I2CMSTA_TCOMP_SET (0x1 << 8 ) /* SET. Set when a STOP condition is detected on the I2C bus. If IENCMP is 1, an interrupt is generated when this bit asserts. This bit only asserts if the master is enabled (MASEN = 1). This bit should be used to determine when it is safe to disable the master. It can also be used to wait for another master's transaction to complete on the I2C bus when this master loses arbitration. */ + +/* I2CMSTA[NACKDATA] - NACK received in response to data write. (Can drive an interrupt). */ +#define I2CMSTA_NACKDATA_BBA (*(volatile unsigned long *) 0x4206009C) +#define I2CMSTA_NACKDATA_MSK (0x1 << 7 ) +#define I2CMSTA_NACKDATA (0x1 << 7 ) +#define I2CMSTA_NACKDATA_CLR (0x0 << 7 ) /* CLR. Cleared on a read of the I2CMSTA register. */ +#define I2CMSTA_NACKDATA_SET (0x1 << 7 ) /* SET. Set when a NACK is received in response to a data write transfer. If IENNACK is 1, an interrupt is generated when this bit asserts. */ + +/* I2CMSTA[BUSY] - Master busy. */ +#define I2CMSTA_BUSY_BBA (*(volatile unsigned long *) 0x42060098) +#define I2CMSTA_BUSY_MSK (0x1 << 6 ) +#define I2CMSTA_BUSY (0x1 << 6 ) +#define I2CMSTA_BUSY_CLR (0x0 << 6 ) /* CLR. Cleared if the state machine is idle or another device has control of the I2C bus. */ +#define I2CMSTA_BUSY_SET (0x1 << 6 ) /* SET. Set when the master state machine is servicing a transaction. */ + +/* I2CMSTA[ALOST] - Arbitration lost. (Can drive an interrupt). */ +#define I2CMSTA_ALOST_BBA (*(volatile unsigned long *) 0x42060094) +#define I2CMSTA_ALOST_MSK (0x1 << 5 ) +#define I2CMSTA_ALOST (0x1 << 5 ) +#define I2CMSTA_ALOST_CLR (0x0 << 5 ) /* CLR. Cleared on a read of the I2CMSTA register. */ +#define I2CMSTA_ALOST_SET (0x1 << 5 ) /* SET. Set if the master looses arbitration. If IENALOST is 1, an interrupt is generated when this bit asserts. */ + +/* I2CMSTA[NACKADDR] - NACK received in response to an address. (Can drive an interrupt). */ +#define I2CMSTA_NACKADDR_BBA (*(volatile unsigned long *) 0x42060090) +#define I2CMSTA_NACKADDR_MSK (0x1 << 4 ) +#define I2CMSTA_NACKADDR (0x1 << 4 ) +#define I2CMSTA_NACKADDR_CLR (0x0 << 4 ) /* CLR. Cleared on a read of the I2CMSTA register. */ +#define I2CMSTA_NACKADDR_SET (0x1 << 4 ) /* SET. Set if a NACK received in response to an address. If IENNACK is 1, an interrupt is generated when this bit asserts. */ + +/* I2CMSTA[RXREQ] - Receive Request. (Can drive an interrupt). */ +#define I2CMSTA_RXREQ_BBA (*(volatile unsigned long *) 0x4206008C) +#define I2CMSTA_RXREQ_MSK (0x1 << 3 ) +#define I2CMSTA_RXREQ (0x1 << 3 ) +#define I2CMSTA_RXREQ_CLR (0x0 << 3 ) /* CLR. Cleared. */ +#define I2CMSTA_RXREQ_SET (0x1 << 3 ) /* SET. Set when there is data in the receive FIFO. If IENRX is 1, an interrupt is generated when this bit asserts. */ + +/* I2CMSTA[TXREQ] - Transmit Request. (Can drive an interrupt). */ +#define I2CMSTA_TXREQ_BBA (*(volatile unsigned long *) 0x42060088) +#define I2CMSTA_TXREQ_MSK (0x1 << 2 ) +#define I2CMSTA_TXREQ (0x1 << 2 ) +#define I2CMSTA_TXREQ_CLR (0x0 << 2 ) /* CLR. Cleared when the transmit FIFO underrun condition is not met. */ +#define I2CMSTA_TXREQ_SET (0x1 << 2 ) /* SET. Set when the direction bit is 0 and the transmit FIFO is either empty or not full. If IENTX is 1, an interrupt is generated when this bit asserts. */ + +/* I2CMSTA[TXFSTA] - Transmit FIFO Status. */ +#define I2CMSTA_TXFSTA_MSK (0x3 << 0 ) +#define I2CMSTA_TXFSTA_EMPTY (0x0 << 0 ) /* EMPTY. FIFO empty. */ +#define I2CMSTA_TXFSTA_ONEBYTE (0x2 << 0 ) /* ONEBYTE. 1 byte in FIFO. */ +#define I2CMSTA_TXFSTA_FULL (0x3 << 0 ) /* FULL. FIFO full. */ + +/* Reset Value for I2CMRX*/ +#define I2CMRX_RVAL 0x0 + +/* I2CMRX[VALUE] - Receive register. This register allows access to the receive data FIFO. The FIFO can hold two bytes. */ +#define I2CMRX_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for I2CMTX*/ +#define I2CMTX_RVAL 0x0 + +/* I2CMTX[VALUE] - Transmit register. This register allows access to the transmit data FIFO. The FIFO can hold two bytes. */ +#define I2CMTX_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for I2CMRXCNT*/ +#define I2CMRXCNT_RVAL 0x0 + +/* I2CMRXCNT[EXTEND] - Extended read: Use this bit if greater than 256 bytes are required on a read. For example: To receive 412 bytes, write 0x100 (EXTEND = 1) to this register (I2CMRXCNT). Wait for the first byte to be received, then check the I2CMCRXCNT register for every byte received thereafter. When I2CMCRXCNT returns to 0, 256 bytes have been received. Then, write 0x09C (412 - 256 = 156 decimal (equal to 0x9C) – with the EXTEND bit set to 0) to this register (I2CMRXCNT). */ +#define I2CMRXCNT_EXTEND_BBA (*(volatile unsigned long *) 0x42060220) +#define I2CMRXCNT_EXTEND_MSK (0x1 << 8 ) +#define I2CMRXCNT_EXTEND (0x1 << 8 ) +#define I2CMRXCNT_EXTEND_DIS (0x0 << 8 ) /* DIS */ +#define I2CMRXCNT_EXTEND_EN (0x1 << 8 ) /* EN */ + +/* I2CMRXCNT[COUNT] - Receive count. Program the number of bytes required minus one to this register. If just one byte is required write 0 to this register. If greater than 256 bytes are required, then use EXTEND. */ +#define I2CMRXCNT_COUNT_MSK (0xFF << 0 ) + +/* Reset Value for I2CMCRXCNT*/ +#define I2CMCRXCNT_RVAL 0x0 + +/* I2CMCRXCNT[VALUE] - Current receive count. This register gives the total number of bytes received so far. If 256 bytes are requested, then this register reads 0 when the transaction has completed. */ +#define I2CMCRXCNT_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for I2CADR0*/ +#define I2CADR0_RVAL 0x0 + +/* I2CADR0[VALUE] - Address byte. If a 7-bit address is required, then I2CADR0[7:1] is programmed with the address and I2CADR0[0] is programmed with the direction (read or write). If a 10-bit address is required then I2CADR0[7:3] is programmed with '11110', I2CADR0[2:1] is programmed with the two MSBs of the address, and, again, I2CADR0[0] is programmed with the direction bit (read or write). */ +#define I2CADR0_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for I2CADR1*/ +#define I2CADR1_RVAL 0x0 + +/* I2CADR1[VALUE] - Address byte. This register is only required when addressing a slave with 10-bit addressing. I2CADR1[7:0] is programmed with the lower eight bits of the address. */ +#define I2CADR1_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for I2CDIV*/ +#define I2CDIV_RVAL 0x1F1F + +/* I2CDIV[HIGH] - Serial clock high time. This register controls the clock high time. See the serial clock generation section for more details. */ +#define I2CDIV_HIGH_MSK (0xFF << 8 ) + +/* I2CDIV[LOW] - Serial clock low time. This register controls the clock low time. See the serial clock generation section for more details. */ +#define I2CDIV_LOW_MSK (0xFF << 0 ) + +/* Reset Value for I2CSCON*/ +#define I2CSCON_RVAL 0x0 + +/* I2CSCON[TXDMA] - Enable slave Tx DMA request. */ +#define I2CSCON_TXDMA_BBA (*(volatile unsigned long *) 0x42060538) +#define I2CSCON_TXDMA_MSK (0x1 << 14 ) +#define I2CSCON_TXDMA (0x1 << 14 ) +#define I2CSCON_TXDMA_DIS (0x0 << 14 ) /* DIS. Disable DMA mode. */ +#define I2CSCON_TXDMA_EN (0x1 << 14 ) /* EN. Enable I2C slave DMA requests. */ + +/* I2CSCON[RXDMA] - Enable slave Rx DMA request. */ +#define I2CSCON_RXDMA_BBA (*(volatile unsigned long *) 0x42060534) +#define I2CSCON_RXDMA_MSK (0x1 << 13 ) +#define I2CSCON_RXDMA (0x1 << 13 ) +#define I2CSCON_RXDMA_DIS (0x0 << 13 ) /* DIS. Disable DMA mode. */ +#define I2CSCON_RXDMA_EN (0x1 << 13 ) /* EN. Enable I2C slave DMA requests. */ + +/* I2CSCON[IENREPST] - Repeated start interrupt enable. */ +#define I2CSCON_IENREPST_BBA (*(volatile unsigned long *) 0x42060530) +#define I2CSCON_IENREPST_MSK (0x1 << 12 ) +#define I2CSCON_IENREPST (0x1 << 12 ) +#define I2CSCON_IENREPST_DIS (0x0 << 12 ) /* DIS. Disable an interrupt when the REPSTART status bit asserts. */ +#define I2CSCON_IENREPST_EN (0x1 << 12 ) /* EN. Generate an interrupt when the REPSTART status bit asserts. */ + +/* I2CSCON[IENTX] - Transmit request interrupt enable. */ +#define I2CSCON_IENTX_BBA (*(volatile unsigned long *) 0x42060528) +#define I2CSCON_IENTX_MSK (0x1 << 10 ) +#define I2CSCON_IENTX (0x1 << 10 ) +#define I2CSCON_IENTX_DIS (0x0 << 10 ) /* DIS. Disable transmit request interrupt. */ +#define I2CSCON_IENTX_EN (0x1 << 10 ) /* EN. Enable transmit request interrupt. */ + +/* I2CSCON[IENRX] - Receive request interrupt enable. */ +#define I2CSCON_IENRX_BBA (*(volatile unsigned long *) 0x42060524) +#define I2CSCON_IENRX_MSK (0x1 << 9 ) +#define I2CSCON_IENRX (0x1 << 9 ) +#define I2CSCON_IENRX_DIS (0x0 << 9 ) /* DIS. Disable receive request interrupt. */ +#define I2CSCON_IENRX_EN (0x1 << 9 ) /* EN. Enable receive request interrupt. */ + +/* I2CSCON[IENSTOP] - Stop condition detected interrupt enable. */ +#define I2CSCON_IENSTOP_BBA (*(volatile unsigned long *) 0x42060520) +#define I2CSCON_IENSTOP_MSK (0x1 << 8 ) +#define I2CSCON_IENSTOP (0x1 << 8 ) +#define I2CSCON_IENSTOP_DIS (0x0 << 8 ) /* DIS. Disable stop condition detect interrupt. */ +#define I2CSCON_IENSTOP_EN (0x1 << 8 ) /* EN. Enable stop condition detect interrupt. Enables STOP (I2CSSTA[10]) to generate an interrupt */ + +/* I2CSCON[NACK] - NACK next communication. */ +#define I2CSCON_NACK_BBA (*(volatile unsigned long *) 0x4206051C) +#define I2CSCON_NACK_MSK (0x1 << 7 ) +#define I2CSCON_NACK (0x1 << 7 ) +#define I2CSCON_NACK_DIS (0x0 << 7 ) /* DIS. Disable. */ +#define I2CSCON_NACK_EN (0x1 << 7 ) /* EN. Allow the next communication to be NACK'ed. This can be used for example if during a 24xx I2C serial eeprom style access, an attempt was made to write to a read only or nonexisting location in system memory. That is the indirect address in a 24xx I2C serial eeprom style write pointed to an unwritable memory location. */ + +/* I2CSCON[STRETCH] - Stretch I2CSCL enable. */ +#define I2CSCON_STRETCH_BBA (*(volatile unsigned long *) 0x42060518) +#define I2CSCON_STRETCH_MSK (0x1 << 6 ) +#define I2CSCON_STRETCH (0x1 << 6 ) +#define I2CSCON_STRETCH_DIS (0x0 << 6 ) /* DIS. Disable. */ +#define I2CSCON_STRETCH_EN (0x1 << 6 ) /* EN. Tell the device that, if I2CSCL is 0, hold it at 0. Or if I2CSCL is 1, then when it next goes to 0 hold it at 0. */ + +/* I2CSCON[EARLYTXR] - Early transmit request mode. */ +#define I2CSCON_EARLYTXR_BBA (*(volatile unsigned long *) 0x42060514) +#define I2CSCON_EARLYTXR_MSK (0x1 << 5 ) +#define I2CSCON_EARLYTXR (0x1 << 5 ) +#define I2CSCON_EARLYTXR_DIS (0x0 << 5 ) /* DIS. Disable. */ +#define I2CSCON_EARLYTXR_EN (0x1 << 5 ) /* EN. Enable a transmit request just after the positive edge of the direction bit (READ/WRITE) I2CSCL clock pulse. */ + +/* I2CSCON[GCSB] - General call status bit clear. */ +#define I2CSCON_GCSB_BBA (*(volatile unsigned long *) 0x42060510) +#define I2CSCON_GCSB_MSK (0x1 << 4 ) +#define I2CSCON_GCSB (0x1 << 4 ) +#define I2CSCON_GCSB_CLR (0x1 << 4 ) /* CLR. Clear the General Call status and General Call ID bits. The General Call status and General Call ID bits are not reset by anything other than a write to this bit or a full reset. */ + +/* I2CSCON[HGC] - Hardware general call enable. */ +#define I2CSCON_HGC_BBA (*(volatile unsigned long *) 0x4206050C) +#define I2CSCON_HGC_MSK (0x1 << 3 ) +#define I2CSCON_HGC (0x1 << 3 ) +#define I2CSCON_HGC_DIS (0x0 << 3 ) /* DIS. Disable. */ +#define I2CSCON_HGC_EN (0x1 << 3 ) /* EN. When this bit and the General Call enable bit are set the device after receiving a general call, Address 0x00 and a data byte checks the contents of the I2CALT against the receive shift register. If they match, the device has received a hardware general call. This is used if a device needs urgent attention from a master device without knowing which master it needs to turn to. This is a broadcast message to all master devices in the bus. The device that requires attention embeds its own address into the message. The LSB of the I2CALT register should always be written to a 1. */ + +/* I2CSCON[GC] - General call enable. */ +#define I2CSCON_GC_BBA (*(volatile unsigned long *) 0x42060508) +#define I2CSCON_GC_MSK (0x1 << 2 ) +#define I2CSCON_GC (0x1 << 2 ) +#define I2CSCON_GC_DIS (0x0 << 2 ) /* DIS. Disable. */ +#define I2CSCON_GC_EN (0x1 << 2 ) /* EN. Enable the I2C slave to ACK an I2C general call, Address 0x00 (write). */ + +/* I2CSCON[ADR10] - Enable 10 bit addressing. */ +#define I2CSCON_ADR10_BBA (*(volatile unsigned long *) 0x42060504) +#define I2CSCON_ADR10_MSK (0x1 << 1 ) +#define I2CSCON_ADR10 (0x1 << 1 ) +#define I2CSCON_ADR10_DIS (0x0 << 1 ) /* DIS. If this bit is clear, the slave can support four slave addresses, programmed in Registers I2CID0 to I2CID3. */ +#define I2CSCON_ADR10_EN (0x1 << 1 ) /* EN. Enable 10-bit addressing. One 10-bit address is supported by the slave and is stored in I2CID0 and I2CID1, where I2CID0 contains the first byte of the address and the upper five bits must be programmed to 11110' I2CID2 and I2CID3 can be programmed with 7-bit addresses at the same time. */ + +/* I2CSCON[SLV] - Slave enable. */ +#define I2CSCON_SLV_BBA (*(volatile unsigned long *) 0x42060500) +#define I2CSCON_SLV_MSK (0x1 << 0 ) +#define I2CSCON_SLV (0x1 << 0 ) +#define I2CSCON_SLV_DIS (0x0 << 0 ) /* DIS. Disable the slave and all slave state machine flops are held in reset. */ +#define I2CSCON_SLV_EN (0x1 << 0 ) /* EN. Enable slave. */ + +/* Reset Value for I2CSSTA*/ +#define I2CSSTA_RVAL 0x1 + +/* I2CSSTA[START] - Start and matching address. */ +#define I2CSSTA_START_BBA (*(volatile unsigned long *) 0x420605B8) +#define I2CSSTA_START_MSK (0x1 << 14 ) +#define I2CSSTA_START (0x1 << 14 ) +#define I2CSSTA_START_CLR (0x0 << 14 ) /* CLR. Cleared on receipt of either a stop or start condition. */ +#define I2CSSTA_START_SET (0x1 << 14 ) /* SET. Set if a start is detected on I2CSCL/I2CSDA and one of the following is true: The device address is matched. A general call (GC = 0000_0000) code is received and GC is enabled. A high speed (HS = 0000_1XXX) code is received. A start byte (0000_0001) is received. */ + +/* I2CSSTA[REPSTART] - Repeated start and matching address. (Can drive an interrupt). */ +#define I2CSSTA_REPSTART_BBA (*(volatile unsigned long *) 0x420605B4) +#define I2CSSTA_REPSTART_MSK (0x1 << 13 ) +#define I2CSSTA_REPSTART (0x1 << 13 ) +#define I2CSSTA_REPSTART_CLR (0x0 << 13 ) /* CLR. Cleared when read or on receipt of a stop condition. */ +#define I2CSSTA_REPSTART_SET (0x1 << 13 ) /* SET. Set if START (I2CSSTA[14]) is already asserted and then a repeated start is detected. */ + +/* I2CSSTA[IDMAT] - Device ID matched. */ +#define I2CSSTA_IDMAT_MSK (0x3 << 11 ) + +/* I2CSSTA[STOP] - Stop after start and matching address. (Can drive an interrupt). */ +#define I2CSSTA_STOP_BBA (*(volatile unsigned long *) 0x420605A8) +#define I2CSSTA_STOP_MSK (0x1 << 10 ) +#define I2CSSTA_STOP (0x1 << 10 ) +#define I2CSSTA_STOP_CLR (0x0 << 10 ) /* CLR. Cleared by a read of the status register. */ +#define I2CSSTA_STOP_SET (0x1 << 10 ) /* SET. Set if the slave device received a stop condition after a previous start condition and a matching address. */ + +/* I2CSSTA[GCID] - General call ID. Cleared when the GCSBCLR (I2CSCON[4]) is written to 1. These status bits are not cleared by a general call reset. */ +#define I2CSSTA_GCID_MSK (0x3 << 8 ) + +/* I2CSSTA[GCINT] - General call interrupt. (Always drives an interrupt). */ +#define I2CSSTA_GCINT_BBA (*(volatile unsigned long *) 0x4206059C) +#define I2CSSTA_GCINT_MSK (0x1 << 7 ) +#define I2CSSTA_GCINT (0x1 << 7 ) +#define I2CSSTA_GCINT_CLR (0x0 << 7 ) /* CLR. To clear this bit, write 1 to the I2CSCON[4]. If it was a general call reset, all registers are at their default values. If it was a hardware general call, the Rx FIFO holds the second byte of the general call and this can be compared with the ALT register. */ +#define I2CSSTA_GCINT_SET (0x1 << 7 ) /* SET. Set if the slave device receives a general call of any type. */ + +/* I2CSSTA[BUSY] - Slave busy. */ +#define I2CSSTA_BUSY_BBA (*(volatile unsigned long *) 0x42060598) +#define I2CSSTA_BUSY_MSK (0x1 << 6 ) +#define I2CSSTA_BUSY (0x1 << 6 ) +#define I2CSSTA_BUSY_CLR (0x0 << 6 ) /* CLR. Cleared by hardware on any of the following conditions: The address does not match an ID register, the slave device receives a I2C stop condition or if a repeated start address doesn’t match. */ +#define I2CSSTA_BUSY_SET (0x1 << 6 ) /* SET. Set if the slave device receives an I2C start condition. */ + +/* I2CSSTA[NOACK] - NACK generated by the slave. */ +#define I2CSSTA_NOACK_BBA (*(volatile unsigned long *) 0x42060594) +#define I2CSSTA_NOACK_MSK (0x1 << 5 ) +#define I2CSSTA_NOACK (0x1 << 5 ) +#define I2CSSTA_NOACK_CLR (0x0 << 5 ) /* CLR. Cleared on a read of the I2CSSTA register. */ +#define I2CSSTA_NOACK_SET (0x1 << 5 ) /* SET. Set to indicate that the slave responded to its device address with a NACK. Set under any of the following conditions: If there was no data to transmit and sequence was a slave read, the device address is NACK'ed or if the NACK bit was set in the slave control register and the device was addressed. */ + +/* I2CSSTA[RXOF] - Receive FIFO overflow. */ +#define I2CSSTA_RXOF_BBA (*(volatile unsigned long *) 0x42060590) +#define I2CSSTA_RXOF_MSK (0x1 << 4 ) +#define I2CSSTA_RXOF (0x1 << 4 ) +#define I2CSSTA_RXOF_CLR (0x0 << 4 ) /* CLR. Cleared. */ +#define I2CSSTA_RXOF_SET (0x1 << 4 ) /* SET. Set when a byte is written to the receive FIFO when the FIFO is already full. */ + +/* I2CSSTA[RXREQ] - Receive request. (Can drive an interrupt). */ +#define I2CSSTA_RXREQ_BBA (*(volatile unsigned long *) 0x4206058C) +#define I2CSSTA_RXREQ_MSK (0x1 << 3 ) +#define I2CSSTA_RXREQ (0x1 << 3 ) +#define I2CSSTA_RXREQ_CLR (0x0 << 3 ) /* CLR. Cleared when the receive FIFO is read or flushed. */ +#define I2CSSTA_RXREQ_SET (0x1 << 3 ) /* SET. Set when the receive FIFO is not empty. Set on the falling edge of the I2CSCL clock pulse that clocks in the last data bit of a byte. */ + +/* I2CSSTA[TXREQ] - Transmit request. (Can drive an interrupt). */ +#define I2CSSTA_TXREQ_BBA (*(volatile unsigned long *) 0x42060588) +#define I2CSSTA_TXREQ_MSK (0x1 << 2 ) +#define I2CSSTA_TXREQ (0x1 << 2 ) +#define I2CSSTA_TXREQ_CLR (0x0 << 2 ) /* CLR. This bit is cleared on a read of the I2CSSTA register. */ +#define I2CSSTA_TXREQ_SET (0x1 << 2 ) /* SET. If EARLYTXR = 0, TXREQ is set when the direction bit for a transfer is received high. Thereafter, as long as the transmit FIFO is not full, this bit remains asserted. Initially, it is asserted on the negative edge of the SCL pulse that clocks in the direction bit (if the device address matched also). If EARLYTXR = 1, TXREQ is set when the direction bit for a transfer is received high. Thereafter, as long as the transmit FIFO is not full, this bit will remain asserted. Initially, it is asserted after the positive edge of the SCL pulse that clocks in the direction bit (if the device address matched also). */ + +/* I2CSSTA[TXUR] - Transmit FIFO underflow. */ +#define I2CSSTA_TXUR_BBA (*(volatile unsigned long *) 0x42060584) +#define I2CSSTA_TXUR_MSK (0x1 << 1 ) +#define I2CSSTA_TXUR (0x1 << 1 ) +#define I2CSSTA_TXUR_CLR (0x0 << 1 ) /* CLR. Cleared. */ +#define I2CSSTA_TXUR_SET (0x1 << 1 ) /* SET. Set to 1 if a master requests data from the device and the Tx FIFO is empty for the rising edge of SCL. */ + +/* I2CSSTA[TXFSEREQ] - Tx FIFO status. */ +#define I2CSSTA_TXFSEREQ_BBA (*(volatile unsigned long *) 0x42060580) +#define I2CSSTA_TXFSEREQ_MSK (0x1 << 0 ) +#define I2CSSTA_TXFSEREQ (0x1 << 0 ) +#define I2CSSTA_TXFSEREQ_CLR (0x0 << 0 ) /* CLR. Cleared. */ +#define I2CSSTA_TXFSEREQ_SET (0x1 << 0 ) /* SET. Set whenever the slave Tx FIFO is empty. */ + +/* Reset Value for I2CSRX*/ +#define I2CSRX_RVAL 0x0 + +/* I2CSRX[VALUE] - Receive register. */ +#define I2CSRX_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for I2CSTX*/ +#define I2CSTX_RVAL 0x0 + +/* I2CSTX[VALUE] - Transmit register. */ +#define I2CSTX_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for I2CALT*/ +#define I2CALT_RVAL 0x0 + +/* I2CALT[VALUE] - ALT register.This register is used in conjunction with HGC (I2CSCON[3]) to match a master generating a hardware general call. It is used in the case where a master device cannot be programmed with a slave’s address and, instead, the slave must recognize the master’s address. */ +#define I2CALT_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for I2CID0*/ +#define I2CID0_RVAL 0x0 + +/* I2CID0[VALUE] - Slave ID. */ +#define I2CID0_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for I2CID1*/ +#define I2CID1_RVAL 0x0 + +/* I2CID1[VALUE] - Slave ID. */ +#define I2CID1_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for I2CID2*/ +#define I2CID2_RVAL 0x0 + +/* I2CID2[VALUE] - Slave ID. */ +#define I2CID2_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for I2CID3*/ +#define I2CID3_RVAL 0x0 + +/* I2CID3[VALUE] - Slave ID. */ +#define I2CID3_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for I2CFSTA*/ +#define I2CFSTA_RVAL 0x0 + +/* I2CFSTA[MFLUSH] - Master Transmit FIFO Flush. */ +#define I2CFSTA_MFLUSH_BBA (*(volatile unsigned long *) 0x420609A4) +#define I2CFSTA_MFLUSH_MSK (0x1 << 9 ) +#define I2CFSTA_MFLUSH (0x1 << 9 ) +#define I2CFSTA_MFLUSH_DIS (0x0 << 9 ) /* DIS. For normal FIFO operation. */ +#define I2CFSTA_MFLUSH_EN (0x1 << 9 ) /* EN. FIFO flush enabled, to keep the FIFO empty. */ + +/* I2CFSTA[SFLUSH] - Slave Transmit FIFO Flush. */ +#define I2CFSTA_SFLUSH_BBA (*(volatile unsigned long *) 0x420609A0) +#define I2CFSTA_SFLUSH_MSK (0x1 << 8 ) +#define I2CFSTA_SFLUSH (0x1 << 8 ) +#define I2CFSTA_SFLUSH_DIS (0x0 << 8 ) /* DIS. For normal FIFO operation. */ +#define I2CFSTA_SFLUSH_EN (0x1 << 8 ) /* EN. FIFO flush enabled, to keep the FIFO empty. */ + +/* I2CFSTA[MRXFSTA] - Master Receive FIFO status. */ +#define I2CFSTA_MRXFSTA_MSK (0x3 << 6 ) +#define I2CFSTA_MRXFSTA_EMPTY (0x0 << 6 ) /* EMPTY */ +#define I2CFSTA_MRXFSTA_ONEBYTE (0x1 << 6 ) /* ONEBYTE */ +#define I2CFSTA_MRXFSTA_TWOBYTES (0x2 << 6 ) /* TWOBYTES */ + +/* I2CFSTA[MTXFSTA] - Master Transmit FIFO status. */ +#define I2CFSTA_MTXFSTA_MSK (0x3 << 4 ) +#define I2CFSTA_MTXFSTA_EMPTY (0x0 << 4 ) /* EMPTY */ +#define I2CFSTA_MTXFSTA_ONEBYTE (0x1 << 4 ) /* ONEBYTE */ +#define I2CFSTA_MTXFSTA_TWOBYTES (0x2 << 4 ) /* TWOBYTES */ + +/* I2CFSTA[SRXFSTA] - Slave Receive FIFO status. */ +#define I2CFSTA_SRXFSTA_MSK (0x3 << 2 ) +#define I2CFSTA_SRXFSTA_EMPTY (0x0 << 2 ) /* EMPTY */ +#define I2CFSTA_SRXFSTA_ONEBYTE (0x1 << 2 ) /* ONEBYTE */ +#define I2CFSTA_SRXFSTA_TWOBYTES (0x2 << 2 ) /* TWOBYTES */ + +/* I2CFSTA[STXFSTA] - Slave Transmit FIFO status. */ +#define I2CFSTA_STXFSTA_MSK (0x3 << 0 ) +#define I2CFSTA_STXFSTA_EMPTY (0x0 << 0 ) /* EMPTY */ +#define I2CFSTA_STXFSTA_ONEBYTE (0x1 << 0 ) /* ONEBYTE */ +#define I2CFSTA_STXFSTA_TWOBYTES (0x2 << 0 ) /* TWOBYTES */ +// ------------------------------------------------------------------------------------------------ +// ----- INTERRUPT ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Interrupts (pADI_INTERRUPT) + */ + +#if (__NO_MMR_STRUCTS__==0) +typedef struct { /*!< pADI_INTERRUPT Structure */ + __IO uint16_t EI0CFG; /*!< External Interrupt Configuration Register 0 */ + __I uint16_t RESERVED0; + __IO uint16_t EI1CFG; /*!< External Interrupt Configuration Register 1 */ + __I uint16_t RESERVED1; + __IO uint16_t EI2CFG; /*!< External Interrupt Configuration Register 2 */ + __I uint16_t RESERVED2[3]; + __IO uint16_t EICLR; /*!< External Interrupts Clear Register */ + __I uint16_t RESERVED3; + __IO uint8_t NMICLR; /*!< NMI Clear Register */ +} ADI_INTERRUPT_TypeDef; +#else // (__NO_MMR_STRUCTS__==0) +#define EI0CFG (*(volatile unsigned short int *) 0x40002420) +#define EI1CFG (*(volatile unsigned short int *) 0x40002424) +#define EI2CFG (*(volatile unsigned short int *) 0x40002428) +#define EICLR (*(volatile unsigned short int *) 0x40002430) +#define NMICLR (*(volatile unsigned char *) 0x40002434) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for EI0CFG*/ +#define EI0CFG_RVAL 0x0 + +/* EI0CFG[IRQ3EN] - External interrupt 3 enable bit. */ +#define EI0CFG_IRQ3EN_BBA (*(volatile unsigned long *) 0x4204843C) +#define EI0CFG_IRQ3EN_MSK (0x1 << 15 ) +#define EI0CFG_IRQ3EN (0x1 << 15 ) +#define EI0CFG_IRQ3EN_DIS (0x0 << 15 ) /* DIS. External interrupt 3 disabled. */ +#define EI0CFG_IRQ3EN_EN (0x1 << 15 ) /* EN. External Interrupt 3 enabled. */ + +/* EI0CFG[IRQ3MDE] - External interrupt 3 detection mode. */ +#define EI0CFG_IRQ3MDE_MSK (0x7 << 12 ) +#define EI0CFG_IRQ3MDE_RISE (0x0 << 12 ) /* RISE. Rising edge. */ +#define EI0CFG_IRQ3MDE_FALL (0x1 << 12 ) /* FALL. Falling edge. */ +#define EI0CFG_IRQ3MDE_RISEORFALL (0x2 << 12 ) /* RISEORFALL. Rising or falling edge. */ +#define EI0CFG_IRQ3MDE_HIGHLEVEL (0x3 << 12 ) /* HIGHLEVEL. High level. */ +#define EI0CFG_IRQ3MDE_LOWLEVEL (0x4 << 12 ) /* LOWLEVEL. Low level. */ + +/* EI0CFG[IRQ2EN] - External interrupt 2 enable bit. */ +#define EI0CFG_IRQ2EN_BBA (*(volatile unsigned long *) 0x4204842C) +#define EI0CFG_IRQ2EN_MSK (0x1 << 11 ) +#define EI0CFG_IRQ2EN (0x1 << 11 ) +#define EI0CFG_IRQ2EN_DIS (0x0 << 11 ) /* DIS. External interrupt 2 disabled. */ +#define EI0CFG_IRQ2EN_EN (0x1 << 11 ) /* EN. External Interrupt 2 enabled. */ + +/* EI0CFG[IRQ2MDE] - External interrupt 2 detection mode. */ +#define EI0CFG_IRQ2MDE_MSK (0x7 << 8 ) +#define EI0CFG_IRQ2MDE_RISE (0x0 << 8 ) /* RISE. Rising edge. */ +#define EI0CFG_IRQ2MDE_FALL (0x1 << 8 ) /* FALL. Falling edge. */ +#define EI0CFG_IRQ2MDE_RISEORFALL (0x2 << 8 ) /* RISEORFALL. Rising or falling edge. */ +#define EI0CFG_IRQ2MDE_HIGHLEVEL (0x3 << 8 ) /* HIGHLEVEL. High level. */ +#define EI0CFG_IRQ2MDE_LOWLEVEL (0x4 << 8 ) /* LOWLEVEL. Low level. */ + +/* EI0CFG[IRQ1EN] - External interrupt 1 enable bit. */ +#define EI0CFG_IRQ1EN_BBA (*(volatile unsigned long *) 0x4204841C) +#define EI0CFG_IRQ1EN_MSK (0x1 << 7 ) +#define EI0CFG_IRQ1EN (0x1 << 7 ) +#define EI0CFG_IRQ1EN_DIS (0x0 << 7 ) /* DIS. External interrupt 1 disabled. */ +#define EI0CFG_IRQ1EN_EN (0x1 << 7 ) /* EN. External Interrupt 1 enabled. */ + +/* EI0CFG[IRQ1MDE] - External interrupt 1 detection mode. */ +#define EI0CFG_IRQ1MDE_MSK (0x7 << 4 ) +#define EI0CFG_IRQ1MDE_RISE (0x0 << 4 ) /* RISE. Rising edge. */ +#define EI0CFG_IRQ1MDE_FALL (0x1 << 4 ) /* FALL. Falling edge. */ +#define EI0CFG_IRQ1MDE_RISEORFALL (0x2 << 4 ) /* RISEORFALL. Rising or falling edge. */ +#define EI0CFG_IRQ1MDE_HIGHLEVEL (0x3 << 4 ) /* HIGHLEVEL. High level. */ +#define EI0CFG_IRQ1MDE_LOWLEVEL (0x4 << 4 ) /* LOWLEVEL. Low level. */ + +/* EI0CFG[IRQ0EN] - RF transceiver clock IRQ enable bit. */ +#define EI0CFG_IRQ0EN_BBA (*(volatile unsigned long *) 0x4204840C) +#define EI0CFG_IRQ0EN_MSK (0x1 << 3 ) +#define EI0CFG_IRQ0EN (0x1 << 3 ) +#define EI0CFG_IRQ0EN_DIS (0x0 << 3 ) /* DIS. RF transceiver clock IRQ disabled. */ +#define EI0CFG_IRQ0EN_EN (0x1 << 3 ) /* EN. RF transceiver clock IRQ enabled. */ + +/* EI0CFG[IRQ0MDE] - RF transceiver clock detection mode. */ +#define EI0CFG_IRQ0MDE_MSK (0x7 << 0 ) +#define EI0CFG_IRQ0MDE_RISE (0x0 << 0 ) /* RISE. Rising edge. */ +#define EI0CFG_IRQ0MDE_FALL (0x1 << 0 ) /* FALL. Falling edge. */ +#define EI0CFG_IRQ0MDE_RISEORFALL (0x2 << 0 ) /* RISEORFALL. Rising or falling edge. */ +#define EI0CFG_IRQ0MDE_HIGHLEVEL (0x3 << 0 ) /* HIGHLEVEL. High level. */ +#define EI0CFG_IRQ0MDE_LOWLEVEL (0x4 << 0 ) /* LOWLEVEL. Low level. */ + +/* Reset Value for EI1CFG*/ +#define EI1CFG_RVAL 0x0 + +/* EI1CFG[IRQ7EN] - External interrupt 7 enable bit. */ +#define EI1CFG_IRQ7EN_BBA (*(volatile unsigned long *) 0x420484BC) +#define EI1CFG_IRQ7EN_MSK (0x1 << 15 ) +#define EI1CFG_IRQ7EN (0x1 << 15 ) +#define EI1CFG_IRQ7EN_DIS (0x0 << 15 ) /* DIS. External interrupt 7 disabled. */ +#define EI1CFG_IRQ7EN_EN (0x1 << 15 ) /* EN. External interrupt 7 enabled. */ + +/* EI1CFG[IRQ7MDE] - External interrupt 7 detection mode. */ +#define EI1CFG_IRQ7MDE_MSK (0x7 << 12 ) +#define EI1CFG_IRQ7MDE_RISE (0x0 << 12 ) /* RISE. Rising edge. */ +#define EI1CFG_IRQ7MDE_FALL (0x1 << 12 ) /* FALL. Falling edge. */ +#define EI1CFG_IRQ7MDE_RISEORFALL (0x2 << 12 ) /* RISEORFALL. Rising or falling edge. */ +#define EI1CFG_IRQ7MDE_HIGHLEVEL (0x3 << 12 ) /* HIGHLEVEL. High level. */ +#define EI1CFG_IRQ7MDE_LOWLEVEL (0x4 << 12 ) /* LOWLEVEL. Low level. */ + +/* EI1CFG[IRQ6EN] - External interrupt 6 enable bit. */ +#define EI1CFG_IRQ6EN_BBA (*(volatile unsigned long *) 0x420484AC) +#define EI1CFG_IRQ6EN_MSK (0x1 << 11 ) +#define EI1CFG_IRQ6EN (0x1 << 11 ) +#define EI1CFG_IRQ6EN_DIS (0x0 << 11 ) /* DIS. External interrupt 6 disabled. */ +#define EI1CFG_IRQ6EN_EN (0x1 << 11 ) /* EN. External Interrupt 6 enabled. */ + +/* EI1CFG[IRQ6MDE] - External interrupt 6 detection mode. */ +#define EI1CFG_IRQ6MDE_MSK (0x7 << 8 ) +#define EI1CFG_IRQ6MDE_RISE (0x0 << 8 ) /* RISE. Rising edge. */ +#define EI1CFG_IRQ6MDE_FALL (0x1 << 8 ) /* FALL. Falling edge. */ +#define EI1CFG_IRQ6MDE_RISEORFALL (0x2 << 8 ) /* RISEORFALL. Rising or falling edge. */ +#define EI1CFG_IRQ6MDE_HIGHLEVEL (0x3 << 8 ) /* HIGHLEVEL. High level. */ +#define EI1CFG_IRQ6MDE_LOWLEVEL (0x4 << 8 ) /* LOWLEVEL. Low Level. */ + +/* EI1CFG[IRQ5EN] - External interrupt 5 enable bit. */ +#define EI1CFG_IRQ5EN_BBA (*(volatile unsigned long *) 0x4204849C) +#define EI1CFG_IRQ5EN_MSK (0x1 << 7 ) +#define EI1CFG_IRQ5EN (0x1 << 7 ) +#define EI1CFG_IRQ5EN_DIS (0x0 << 7 ) /* DIS. External interrupt 5 disabled. */ +#define EI1CFG_IRQ5EN_EN (0x1 << 7 ) /* EN. External Interrupt 5 enabled. */ + +/* EI1CFG[IRQ5MDE] - External interrupt 5 detection mode. */ +#define EI1CFG_IRQ5MDE_MSK (0x7 << 4 ) +#define EI1CFG_IRQ5MDE_RISE (0x0 << 4 ) /* RISE. Rising edge. */ +#define EI1CFG_IRQ5MDE_FALL (0x1 << 4 ) /* FALL. Falling edge. */ +#define EI1CFG_IRQ5MDE_RISEORFALL (0x2 << 4 ) /* RISEORFALL. Rising or falling edge. */ +#define EI1CFG_IRQ5MDE_HIGHLEVEL (0x3 << 4 ) /* HIGHLEVEL. High level. */ +#define EI1CFG_IRQ5MDE_LOWLEVEL (0x4 << 4 ) /* LOWLEVEL. Low Level. */ + +/* EI1CFG[IRQ4EN] - External interrupt 4 enable bit. */ +#define EI1CFG_IRQ4EN_BBA (*(volatile unsigned long *) 0x4204848C) +#define EI1CFG_IRQ4EN_MSK (0x1 << 3 ) +#define EI1CFG_IRQ4EN (0x1 << 3 ) +#define EI1CFG_IRQ4EN_DIS (0x0 << 3 ) /* DIS. External interrupt 4 disabled. */ +#define EI1CFG_IRQ4EN_EN (0x1 << 3 ) /* EN. External Interrupt 4 enabled. */ + +/* EI1CFG[IRQ4MDE] - External interrupt 4 detection mode. */ +#define EI1CFG_IRQ4MDE_MSK (0x7 << 0 ) +#define EI1CFG_IRQ4MDE_RISE (0x0 << 0 ) /* RISE. Rising edge. */ +#define EI1CFG_IRQ4MDE_FALL (0x1 << 0 ) /* FALL. Falling edge. */ +#define EI1CFG_IRQ4MDE_RISEORFALL (0x2 << 0 ) /* RISEORFALL. Rising or falling edge. */ +#define EI1CFG_IRQ4MDE_HIGHLEVEL (0x3 << 0 ) /* HIGHLEVEL. High level. */ +#define EI1CFG_IRQ4MDE_LOWLEVEL (0x4 << 0 ) /* LOWLEVEL. Low Level. */ + +/* Reset Value for EI2CFG*/ +#define EI2CFG_RVAL 0x0 + +/* EI2CFG[IRQ8EN] - RF transceiver IRQ enable bit. */ +#define EI2CFG_IRQ8EN_BBA (*(volatile unsigned long *) 0x4204850C) +#define EI2CFG_IRQ8EN_MSK (0x1 << 3 ) +#define EI2CFG_IRQ8EN (0x1 << 3 ) +#define EI2CFG_IRQ8EN_DIS (0x0 << 3 ) /* DIS. RF transceiver IRQ disabled. */ +#define EI2CFG_IRQ8EN_EN (0x1 << 3 ) /* EN. RF transceiver IRQ enabled. */ + +/* EI2CFG[IRQ8MDE] - RF transceiver IRQ detection mode. */ +#define EI2CFG_IRQ8MDE_MSK (0x7 << 0 ) +#define EI2CFG_IRQ8MDE_RISE (0x0 << 0 ) /* RISE. Rising edge. */ +#define EI2CFG_IRQ8MDE_FALL (0x1 << 0 ) /* FALL. Falling edge. */ +#define EI2CFG_IRQ8MDE_RISEORFALL (0x2 << 0 ) /* RISEORFALL. Rising or falling edge. */ +#define EI2CFG_IRQ8MDE_HIGHLEVEL (0x3 << 0 ) /* HIGHLEVEL. High level. */ +#define EI2CFG_IRQ8MDE_LOWLEVEL (0x4 << 0 ) /* LOWLEVEL. Low level. */ + +/* Reset Value for EICLR*/ +#define EICLR_RVAL 0x0 + +/* EICLR[IRQ8] - External interrupt 8 (RF transceiver) clear bit. */ +#define EICLR_IRQ8_BBA (*(volatile unsigned long *) 0x42048620) +#define EICLR_IRQ8_MSK (0x1 << 8 ) +#define EICLR_IRQ8 (0x1 << 8 ) +#define EICLR_IRQ8_CLR (0x1 << 8 ) /* CLR. Clear an internal interrupt flag. */ + +/* EICLR[IRQ7] - External interrupt 7 clear bit. */ +#define EICLR_IRQ7_BBA (*(volatile unsigned long *) 0x4204861C) +#define EICLR_IRQ7_MSK (0x1 << 7 ) +#define EICLR_IRQ7 (0x1 << 7 ) +#define EICLR_IRQ7_CLR (0x1 << 7 ) /* CLR. Clear an internal interrupt flag. */ + +/* EICLR[IRQ6] - External interrupt 6 clear bit. */ +#define EICLR_IRQ6_BBA (*(volatile unsigned long *) 0x42048618) +#define EICLR_IRQ6_MSK (0x1 << 6 ) +#define EICLR_IRQ6 (0x1 << 6 ) +#define EICLR_IRQ6_CLR (0x1 << 6 ) /* CLR. Clear an internal interrupt flag. */ + +/* EICLR[IRQ5] - External interrupt 5 clear bit. */ +#define EICLR_IRQ5_BBA (*(volatile unsigned long *) 0x42048614) +#define EICLR_IRQ5_MSK (0x1 << 5 ) +#define EICLR_IRQ5 (0x1 << 5 ) +#define EICLR_IRQ5_CLR (0x1 << 5 ) /* CLR. Clear an internal interrupt flag. */ + +/* EICLR[IRQ4] - External interrupt 4 clear bit. */ +#define EICLR_IRQ4_BBA (*(volatile unsigned long *) 0x42048610) +#define EICLR_IRQ4_MSK (0x1 << 4 ) +#define EICLR_IRQ4 (0x1 << 4 ) +#define EICLR_IRQ4_CLR (0x1 << 4 ) /* CLR. Clear an internal interrupt flag. */ + +/* EICLR[IRQ3] - External interrupt 3 clear bit. */ +#define EICLR_IRQ3_BBA (*(volatile unsigned long *) 0x4204860C) +#define EICLR_IRQ3_MSK (0x1 << 3 ) +#define EICLR_IRQ3 (0x1 << 3 ) +#define EICLR_IRQ3_CLR (0x1 << 3 ) /* CLR. Clear an internal interrupt flag. */ + +/* EICLR[IRQ2] - External interrupt 2 clear bit. */ +#define EICLR_IRQ2_BBA (*(volatile unsigned long *) 0x42048608) +#define EICLR_IRQ2_MSK (0x1 << 2 ) +#define EICLR_IRQ2 (0x1 << 2 ) +#define EICLR_IRQ2_CLR (0x1 << 2 ) /* CLR. Clear an internal interrupt flag. */ + +/* EICLR[IRQ1] - External interrupt 1 clear bit. */ +#define EICLR_IRQ1_BBA (*(volatile unsigned long *) 0x42048604) +#define EICLR_IRQ1_MSK (0x1 << 1 ) +#define EICLR_IRQ1 (0x1 << 1 ) +#define EICLR_IRQ1_CLR (0x1 << 1 ) /* CLR. Clear an internal interrupt flag. */ + +/* EICLR[IRQ0] - External interrupt 0 clear bit. */ +#define EICLR_IRQ0_BBA (*(volatile unsigned long *) 0x42048600) +#define EICLR_IRQ0_MSK (0x1 << 0 ) +#define EICLR_IRQ0 (0x1 << 0 ) +#define EICLR_IRQ0_CLR (0x1 << 0 ) /* CLR. Clear an internal interrupt flag. */ + +/* Reset Value for NMICLR*/ +#define NMICLR_RVAL 0x0 + +/* NMICLR[CLEAR] - NMI clear bit. */ +#define NMICLR_CLEAR_BBA (*(volatile unsigned long *) 0x42048680) +#define NMICLR_CLEAR_MSK (0x1 << 0 ) +#define NMICLR_CLEAR (0x1 << 0 ) +#define NMICLR_CLEAR_EN (0x1 << 0 ) /* EN. Clear an internal interrupt flag when the NMI interrupt is set. */ +// ------------------------------------------------------------------------------------------------ +// ----- NVIC ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Nested Vectored Interrupt Controller (pADI_NVIC) + */ + +#if (__NO_MMR_STRUCTS__==0) +#else // (__NO_MMR_STRUCTS__==0) +#define ICTR (*(volatile unsigned long *) 0xE000E004) +#define STCSR (*(volatile unsigned long *) 0xE000E010) +#define STRVR (*(volatile unsigned long *) 0xE000E014) +#define STCVR (*(volatile unsigned long *) 0xE000E018) +#define STCR (*(volatile unsigned long *) 0xE000E01C) +#define ISER0 (*(volatile unsigned long *) 0xE000E100) +#define ISER1 (*(volatile unsigned long *) 0xE000E104) +#define ICER0 (*(volatile unsigned long *) 0xE000E180) +#define ICER1 (*(volatile unsigned long *) 0xE000E184) +#define ISPR0 (*(volatile unsigned long *) 0xE000E200) +#define ISPR1 (*(volatile unsigned long *) 0xE000E204) +#define ICPR0 (*(volatile unsigned long *) 0xE000E280) +#define ICPR1 (*(volatile unsigned long *) 0xE000E284) +#define IABR0 (*(volatile unsigned long *) 0xE000E300) +#define IABR1 (*(volatile unsigned long *) 0xE000E304) +#define IPR0 (*(volatile unsigned long *) 0xE000E400) +#define IPR1 (*(volatile unsigned long *) 0xE000E404) +#define IPR2 (*(volatile unsigned long *) 0xE000E408) +#define IPR3 (*(volatile unsigned long *) 0xE000E40C) +#define IPR4 (*(volatile unsigned long *) 0xE000E410) +#define IPR5 (*(volatile unsigned long *) 0xE000E414) +#define IPR6 (*(volatile unsigned long *) 0xE000E418) +#define IPR7 (*(volatile unsigned long *) 0xE000E41C) +#define IPR8 (*(volatile unsigned long *) 0xE000E420) +#define IPR9 (*(volatile unsigned long *) 0xE000E424) +#define IPR10 (*(volatile unsigned long *) 0xE000E428) +#define CPUID (*(volatile unsigned long *) 0xE000ED00) +#define ICSR (*(volatile unsigned long *) 0xE000ED04) +#define VTOR (*(volatile unsigned long *) 0xE000ED08) +#define AIRCR (*(volatile unsigned long *) 0xE000ED0C) +#define SCR (*(volatile unsigned long *) 0xE000ED10) +#define CCR (*(volatile unsigned long *) 0xE000ED14) +#define SHPR1 (*(volatile unsigned long *) 0xE000ED18) +#define SHPR2 (*(volatile unsigned long *) 0xE000ED1C) +#define SHPR3 (*(volatile unsigned long *) 0xE000ED20) +#define SHCSR (*(volatile unsigned long *) 0xE000ED24) +#define CFSR (*(volatile unsigned long *) 0xE000ED28) +#define HFSR (*(volatile unsigned long *) 0xE000ED2C) +#define MMFAR (*(volatile unsigned long *) 0xE000ED34) +#define BFAR (*(volatile unsigned long *) 0xE000ED38) +#define STIR (*(volatile unsigned long *) 0xE000EF00) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for ICTR*/ +#define ICTR_RVAL 0x1 + +/* ICTR[INTLINESNUM] - Total number of interrupt lines in groups of 32 */ +#define ICTR_INTLINESNUM_MSK (0xF << 0 ) + +/* Reset Value for STCSR*/ +#define STCSR_RVAL 0x0 + +/* STCSR[COUNTFLAG] - Returns 1 if timer counted to 0 since last time this register was read */ +#define STCSR_COUNTFLAG_MSK (0x1 << 16 ) +#define STCSR_COUNTFLAG (0x1 << 16 ) +#define STCSR_COUNTFLAG_DIS (0x0 << 16 ) /* DIS */ +#define STCSR_COUNTFLAG_EN (0x1 << 16 ) /* EN */ + +/* STCSR[CLKSOURCE] - clock source used for SysTick */ +#define STCSR_CLKSOURCE_MSK (0x1 << 2 ) +#define STCSR_CLKSOURCE (0x1 << 2 ) +#define STCSR_CLKSOURCE_DIS (0x0 << 2 ) /* DIS */ +#define STCSR_CLKSOURCE_EN (0x1 << 2 ) /* EN */ + +/* STCSR[TICKINT] - If 1, counting down to 0 will cause the SysTick exception to pended. */ +#define STCSR_TICKINT_MSK (0x1 << 1 ) +#define STCSR_TICKINT (0x1 << 1 ) +#define STCSR_TICKINT_DIS (0x0 << 1 ) /* DIS */ +#define STCSR_TICKINT_EN (0x1 << 1 ) /* EN */ + +/* STCSR[ENABLE] - Enable bit */ +#define STCSR_ENABLE_MSK (0x1 << 0 ) +#define STCSR_ENABLE (0x1 << 0 ) +#define STCSR_ENABLE_DIS (0x0 << 0 ) /* DIS */ +#define STCSR_ENABLE_EN (0x1 << 0 ) /* EN */ + +/* Reset Value for STRVR*/ +#define STRVR_RVAL 0x0 + +/* STRVR[RELOAD] - Value to load into the Current Value register when the counter reaches 0 */ +#define STRVR_RELOAD_MSK (0xFFFFFF << 0 ) + +/* Reset Value for STCVR*/ +#define STCVR_RVAL 0x0 + +/* STCVR[CURRENT] - Current counter value */ +#define STCVR_CURRENT_MSK (0xFFFFFFFF << 0 ) + +/* Reset Value for STCR*/ +#define STCR_RVAL 0x0 + +/* STCR[NOREF] - If reads as 1, the Reference clock is not provided */ +#define STCR_NOREF_MSK (0x1 << 31 ) +#define STCR_NOREF (0x1 << 31 ) +#define STCR_NOREF_DIS (0x0 << 31 ) /* DIS */ +#define STCR_NOREF_EN (0x1 << 31 ) /* EN */ + +/* STCR[SKEW] - If reads as 1, the calibration value for 10ms is inexact */ +#define STCR_SKEW_MSK (0x1 << 30 ) +#define STCR_SKEW (0x1 << 30 ) +#define STCR_SKEW_DIS (0x0 << 30 ) /* DIS */ +#define STCR_SKEW_EN (0x1 << 30 ) /* EN */ + +/* STCR[TENMS] - An optional Reload value to be used for 10ms (100Hz) timing */ +#define STCR_TENMS_MSK (0xFFFFFF << 0 ) + +/* Reset Value for ISER0*/ +#define ISER0_RVAL 0x0 + +/* ISER0[DMAI2CMRX] - */ +#define ISER0_DMAI2CMRX_MSK (0x1 << 30 ) +#define ISER0_DMAI2CMRX (0x1 << 30 ) +#define ISER0_DMAI2CMRX_DIS (0x0 << 30 ) /* DIS */ +#define ISER0_DMAI2CMRX_EN (0x1 << 30 ) /* EN */ + +/* ISER0[DMAI2CMTX] - */ +#define ISER0_DMAI2CMTX_MSK (0x1 << 29 ) +#define ISER0_DMAI2CMTX (0x1 << 29 ) +#define ISER0_DMAI2CMTX_DIS (0x0 << 29 ) /* DIS */ +#define ISER0_DMAI2CMTX_EN (0x1 << 29 ) /* EN */ + +/* ISER0[DMAI2CSRX] - */ +#define ISER0_DMAI2CSRX_MSK (0x1 << 28 ) +#define ISER0_DMAI2CSRX (0x1 << 28 ) +#define ISER0_DMAI2CSRX_DIS (0x0 << 28 ) /* DIS */ +#define ISER0_DMAI2CSRX_EN (0x1 << 28 ) /* EN */ + +/* ISER0[DMAI2CSTX] - */ +#define ISER0_DMAI2CSTX_MSK (0x1 << 27 ) +#define ISER0_DMAI2CSTX (0x1 << 27 ) +#define ISER0_DMAI2CSTX_DIS (0x0 << 27 ) /* DIS */ +#define ISER0_DMAI2CSTX_EN (0x1 << 27 ) /* EN */ + +/* ISER0[DMAUARTRX] - */ +#define ISER0_DMAUARTRX_MSK (0x1 << 26 ) +#define ISER0_DMAUARTRX (0x1 << 26 ) +#define ISER0_DMAUARTRX_DIS (0x0 << 26 ) /* DIS */ +#define ISER0_DMAUARTRX_EN (0x1 << 26 ) /* EN */ + +/* ISER0[DMAUARTTX] - */ +#define ISER0_DMAUARTTX_MSK (0x1 << 25 ) +#define ISER0_DMAUARTTX (0x1 << 25 ) +#define ISER0_DMAUARTTX_DIS (0x0 << 25 ) /* DIS */ +#define ISER0_DMAUARTTX_EN (0x1 << 25 ) /* EN */ + +/* ISER0[DMASPI1RX] - */ +#define ISER0_DMASPI1RX_MSK (0x1 << 24 ) +#define ISER0_DMASPI1RX (0x1 << 24 ) +#define ISER0_DMASPI1RX_DIS (0x0 << 24 ) /* DIS */ +#define ISER0_DMASPI1RX_EN (0x1 << 24 ) /* EN */ + +/* ISER0[DMASPI1TX] - */ +#define ISER0_DMASPI1TX_MSK (0x1 << 23 ) +#define ISER0_DMASPI1TX (0x1 << 23 ) +#define ISER0_DMASPI1TX_DIS (0x0 << 23 ) /* DIS */ +#define ISER0_DMASPI1TX_EN (0x1 << 23 ) /* EN */ + +/* ISER0[DMAERROR] - */ +#define ISER0_DMAERROR_MSK (0x1 << 22 ) +#define ISER0_DMAERROR (0x1 << 22 ) +#define ISER0_DMAERROR_DIS (0x0 << 22 ) /* DIS */ +#define ISER0_DMAERROR_EN (0x1 << 22 ) /* EN */ + +/* ISER0[I2CM] - */ +#define ISER0_I2CM_MSK (0x1 << 20 ) +#define ISER0_I2CM (0x1 << 20 ) +#define ISER0_I2CM_DIS (0x0 << 20 ) /* DIS */ +#define ISER0_I2CM_EN (0x1 << 20 ) /* EN */ + +/* ISER0[I2CS] - */ +#define ISER0_I2CS_MSK (0x1 << 19 ) +#define ISER0_I2CS (0x1 << 19 ) +#define ISER0_I2CS_DIS (0x0 << 19 ) /* DIS */ +#define ISER0_I2CS_EN (0x1 << 19 ) /* EN */ + +/* ISER0[SPI1] - */ +#define ISER0_SPI1_MSK (0x1 << 18 ) +#define ISER0_SPI1 (0x1 << 18 ) +#define ISER0_SPI1_DIS (0x0 << 18 ) /* DIS */ +#define ISER0_SPI1_EN (0x1 << 18 ) /* EN */ + +/* ISER0[SPI0] - */ +#define ISER0_SPI0_MSK (0x1 << 17 ) +#define ISER0_SPI0 (0x1 << 17 ) +#define ISER0_SPI0_DIS (0x0 << 17 ) /* DIS */ +#define ISER0_SPI0_EN (0x1 << 17 ) /* EN */ + +/* ISER0[UART] - */ +#define ISER0_UART_MSK (0x1 << 16 ) +#define ISER0_UART (0x1 << 16 ) +#define ISER0_UART_DIS (0x0 << 16 ) /* DIS */ +#define ISER0_UART_EN (0x1 << 16 ) /* EN */ + +/* ISER0[FEE] - */ +#define ISER0_FEE_MSK (0x1 << 15 ) +#define ISER0_FEE (0x1 << 15 ) +#define ISER0_FEE_DIS (0x0 << 15 ) /* DIS */ +#define ISER0_FEE_EN (0x1 << 15 ) /* EN */ + +/* ISER0[ADC] - */ +#define ISER0_ADC_MSK (0x1 << 14 ) +#define ISER0_ADC (0x1 << 14 ) +#define ISER0_ADC_DIS (0x0 << 14 ) /* DIS */ +#define ISER0_ADC_EN (0x1 << 14 ) /* EN */ + +/* ISER0[T1] - */ +#define ISER0_T1_MSK (0x1 << 13 ) +#define ISER0_T1 (0x1 << 13 ) +#define ISER0_T1_DIS (0x0 << 13 ) /* DIS */ +#define ISER0_T1_EN (0x1 << 13 ) /* EN */ + +/* ISER0[T0] - */ +#define ISER0_T0_MSK (0x1 << 12 ) +#define ISER0_T0 (0x1 << 12 ) +#define ISER0_T0_DIS (0x0 << 12 ) /* DIS */ +#define ISER0_T0_EN (0x1 << 12 ) /* EN */ + +/* ISER0[T3] - */ +#define ISER0_T3_MSK (0x1 << 10 ) +#define ISER0_T3 (0x1 << 10 ) +#define ISER0_T3_DIS (0x0 << 10 ) /* DIS */ +#define ISER0_T3_EN (0x1 << 10 ) /* EN */ + +/* ISER0[EXTINT8] - */ +#define ISER0_EXTINT8_MSK (0x1 << 9 ) +#define ISER0_EXTINT8 (0x1 << 9 ) +#define ISER0_EXTINT8_DIS (0x0 << 9 ) /* DIS */ +#define ISER0_EXTINT8_EN (0x1 << 9 ) /* EN */ + +/* ISER0[EXTINT7] - */ +#define ISER0_EXTINT7_MSK (0x1 << 8 ) +#define ISER0_EXTINT7 (0x1 << 8 ) +#define ISER0_EXTINT7_DIS (0x0 << 8 ) /* DIS */ +#define ISER0_EXTINT7_EN (0x1 << 8 ) /* EN */ + +/* ISER0[EXTINT6] - */ +#define ISER0_EXTINT6_MSK (0x1 << 7 ) +#define ISER0_EXTINT6 (0x1 << 7 ) +#define ISER0_EXTINT6_DIS (0x0 << 7 ) /* DIS */ +#define ISER0_EXTINT6_EN (0x1 << 7 ) /* EN */ + +/* ISER0[EXTINT5] - */ +#define ISER0_EXTINT5_MSK (0x1 << 6 ) +#define ISER0_EXTINT5 (0x1 << 6 ) +#define ISER0_EXTINT5_DIS (0x0 << 6 ) /* DIS */ +#define ISER0_EXTINT5_EN (0x1 << 6 ) /* EN */ + +/* ISER0[EXTINT4] - */ +#define ISER0_EXTINT4_MSK (0x1 << 5 ) +#define ISER0_EXTINT4 (0x1 << 5 ) +#define ISER0_EXTINT4_DIS (0x0 << 5 ) /* DIS */ +#define ISER0_EXTINT4_EN (0x1 << 5 ) /* EN */ + +/* ISER0[EXTINT3] - */ +#define ISER0_EXTINT3_MSK (0x1 << 4 ) +#define ISER0_EXTINT3 (0x1 << 4 ) +#define ISER0_EXTINT3_DIS (0x0 << 4 ) /* DIS */ +#define ISER0_EXTINT3_EN (0x1 << 4 ) /* EN */ + +/* ISER0[EXTINT2] - */ +#define ISER0_EXTINT2_MSK (0x1 << 3 ) +#define ISER0_EXTINT2 (0x1 << 3 ) +#define ISER0_EXTINT2_DIS (0x0 << 3 ) /* DIS */ +#define ISER0_EXTINT2_EN (0x1 << 3 ) /* EN */ + +/* ISER0[EXTINT1] - */ +#define ISER0_EXTINT1_MSK (0x1 << 2 ) +#define ISER0_EXTINT1 (0x1 << 2 ) +#define ISER0_EXTINT1_DIS (0x0 << 2 ) /* DIS */ +#define ISER0_EXTINT1_EN (0x1 << 2 ) /* EN */ + +/* ISER0[EXTINT0] - */ +#define ISER0_EXTINT0_MSK (0x1 << 1 ) +#define ISER0_EXTINT0 (0x1 << 1 ) +#define ISER0_EXTINT0_DIS (0x0 << 1 ) /* DIS */ +#define ISER0_EXTINT0_EN (0x1 << 1 ) /* EN */ + +/* ISER0[T2] - */ +#define ISER0_T2_MSK (0x1 << 0 ) +#define ISER0_T2 (0x1 << 0 ) +#define ISER0_T2_DIS (0x0 << 0 ) /* DIS */ +#define ISER0_T2_EN (0x1 << 0 ) /* EN */ + +/* Reset Value for ISER1*/ +#define ISER1_RVAL 0x0 + +/* ISER1[PWM3] - */ +#define ISER1_PWM3_MSK (0x1 << 9 ) +#define ISER1_PWM3 (0x1 << 9 ) +#define ISER1_PWM3_DIS (0x0 << 9 ) /* DIS */ +#define ISER1_PWM3_EN (0x1 << 9 ) /* EN */ + +/* ISER1[PWM2] - */ +#define ISER1_PWM2_MSK (0x1 << 8 ) +#define ISER1_PWM2 (0x1 << 8 ) +#define ISER1_PWM2_DIS (0x0 << 8 ) /* DIS */ +#define ISER1_PWM2_EN (0x1 << 8 ) /* EN */ + +/* ISER1[PWM1] - */ +#define ISER1_PWM1_MSK (0x1 << 7 ) +#define ISER1_PWM1 (0x1 << 7 ) +#define ISER1_PWM1_DIS (0x0 << 7 ) /* DIS */ +#define ISER1_PWM1_EN (0x1 << 7 ) /* EN */ + +/* ISER1[PWM0] - */ +#define ISER1_PWM0_MSK (0x1 << 6 ) +#define ISER1_PWM0 (0x1 << 6 ) +#define ISER1_PWM0_DIS (0x0 << 6 ) /* DIS */ +#define ISER1_PWM0_EN (0x1 << 6 ) /* EN */ + +/* ISER1[PWMTRIP] - */ +#define ISER1_PWMTRIP_MSK (0x1 << 5 ) +#define ISER1_PWMTRIP (0x1 << 5 ) +#define ISER1_PWMTRIP_DIS (0x0 << 5 ) /* DIS */ +#define ISER1_PWMTRIP_EN (0x1 << 5 ) /* EN */ + +/* ISER1[DMASPI0RX] - */ +#define ISER1_DMASPI0RX_MSK (0x1 << 4 ) +#define ISER1_DMASPI0RX (0x1 << 4 ) +#define ISER1_DMASPI0RX_DIS (0x0 << 4 ) /* DIS */ +#define ISER1_DMASPI0RX_EN (0x1 << 4 ) /* EN */ + +/* ISER1[DMASPI0TX] - */ +#define ISER1_DMASPI0TX_MSK (0x1 << 3 ) +#define ISER1_DMASPI0TX (0x1 << 3 ) +#define ISER1_DMASPI0TX_DIS (0x0 << 3 ) /* DIS */ +#define ISER1_DMASPI0TX_EN (0x1 << 3 ) /* EN */ + +/* ISER1[DMAADC] - */ +#define ISER1_DMAADC_MSK (0x1 << 2 ) +#define ISER1_DMAADC (0x1 << 2 ) +#define ISER1_DMAADC_DIS (0x0 << 2 ) /* DIS */ +#define ISER1_DMAADC_EN (0x1 << 2 ) /* EN */ + +/* Reset Value for ICER0*/ +#define ICER0_RVAL 0x0 + +/* ICER0[DMAI2CMRX] - */ +#define ICER0_DMAI2CMRX_MSK (0x1 << 30 ) +#define ICER0_DMAI2CMRX (0x1 << 30 ) +#define ICER0_DMAI2CMRX_DIS (0x0 << 30 ) /* DIS */ +#define ICER0_DMAI2CMRX_EN (0x1 << 30 ) /* EN */ + +/* ICER0[DMAI2CMTX] - */ +#define ICER0_DMAI2CMTX_MSK (0x1 << 29 ) +#define ICER0_DMAI2CMTX (0x1 << 29 ) +#define ICER0_DMAI2CMTX_DIS (0x0 << 29 ) /* DIS */ +#define ICER0_DMAI2CMTX_EN (0x1 << 29 ) /* EN */ + +/* ICER0[DMAI2CSRX] - */ +#define ICER0_DMAI2CSRX_MSK (0x1 << 28 ) +#define ICER0_DMAI2CSRX (0x1 << 28 ) +#define ICER0_DMAI2CSRX_DIS (0x0 << 28 ) /* DIS */ +#define ICER0_DMAI2CSRX_EN (0x1 << 28 ) /* EN */ + +/* ICER0[DMAI2CSTX] - */ +#define ICER0_DMAI2CSTX_MSK (0x1 << 27 ) +#define ICER0_DMAI2CSTX (0x1 << 27 ) +#define ICER0_DMAI2CSTX_DIS (0x0 << 27 ) /* DIS */ +#define ICER0_DMAI2CSTX_EN (0x1 << 27 ) /* EN */ + +/* ICER0[DMAUARTRX] - */ +#define ICER0_DMAUARTRX_MSK (0x1 << 26 ) +#define ICER0_DMAUARTRX (0x1 << 26 ) +#define ICER0_DMAUARTRX_DIS (0x0 << 26 ) /* DIS */ +#define ICER0_DMAUARTRX_EN (0x1 << 26 ) /* EN */ + +/* ICER0[DMAUARTTX] - */ +#define ICER0_DMAUARTTX_MSK (0x1 << 25 ) +#define ICER0_DMAUARTTX (0x1 << 25 ) +#define ICER0_DMAUARTTX_DIS (0x0 << 25 ) /* DIS */ +#define ICER0_DMAUARTTX_EN (0x1 << 25 ) /* EN */ + +/* ICER0[DMASPI1RX] - */ +#define ICER0_DMASPI1RX_MSK (0x1 << 24 ) +#define ICER0_DMASPI1RX (0x1 << 24 ) +#define ICER0_DMASPI1RX_DIS (0x0 << 24 ) /* DIS */ +#define ICER0_DMASPI1RX_EN (0x1 << 24 ) /* EN */ + +/* ICER0[DMASPI1TX] - */ +#define ICER0_DMASPI1TX_MSK (0x1 << 23 ) +#define ICER0_DMASPI1TX (0x1 << 23 ) +#define ICER0_DMASPI1TX_DIS (0x0 << 23 ) /* DIS */ +#define ICER0_DMASPI1TX_EN (0x1 << 23 ) /* EN */ + +/* ICER0[DMAERROR] - */ +#define ICER0_DMAERROR_MSK (0x1 << 22 ) +#define ICER0_DMAERROR (0x1 << 22 ) +#define ICER0_DMAERROR_DIS (0x0 << 22 ) /* DIS */ +#define ICER0_DMAERROR_EN (0x1 << 22 ) /* EN */ + +/* ICER0[I2CM] - */ +#define ICER0_I2CM_MSK (0x1 << 20 ) +#define ICER0_I2CM (0x1 << 20 ) +#define ICER0_I2CM_DIS (0x0 << 20 ) /* DIS */ +#define ICER0_I2CM_EN (0x1 << 20 ) /* EN */ + +/* ICER0[I2CS] - */ +#define ICER0_I2CS_MSK (0x1 << 19 ) +#define ICER0_I2CS (0x1 << 19 ) +#define ICER0_I2CS_DIS (0x0 << 19 ) /* DIS */ +#define ICER0_I2CS_EN (0x1 << 19 ) /* EN */ + +/* ICER0[SPI1] - */ +#define ICER0_SPI1_MSK (0x1 << 18 ) +#define ICER0_SPI1 (0x1 << 18 ) +#define ICER0_SPI1_DIS (0x0 << 18 ) /* DIS */ +#define ICER0_SPI1_EN (0x1 << 18 ) /* EN */ + +/* ICER0[SPI0] - */ +#define ICER0_SPI0_MSK (0x1 << 17 ) +#define ICER0_SPI0 (0x1 << 17 ) +#define ICER0_SPI0_DIS (0x0 << 17 ) /* DIS */ +#define ICER0_SPI0_EN (0x1 << 17 ) /* EN */ + +/* ICER0[UART] - */ +#define ICER0_UART_MSK (0x1 << 16 ) +#define ICER0_UART (0x1 << 16 ) +#define ICER0_UART_DIS (0x0 << 16 ) /* DIS */ +#define ICER0_UART_EN (0x1 << 16 ) /* EN */ + +/* ICER0[FEE] - */ +#define ICER0_FEE_MSK (0x1 << 15 ) +#define ICER0_FEE (0x1 << 15 ) +#define ICER0_FEE_DIS (0x0 << 15 ) /* DIS */ +#define ICER0_FEE_EN (0x1 << 15 ) /* EN */ + +/* ICER0[ADC] - */ +#define ICER0_ADC_MSK (0x1 << 14 ) +#define ICER0_ADC (0x1 << 14 ) +#define ICER0_ADC_DIS (0x0 << 14 ) /* DIS */ +#define ICER0_ADC_EN (0x1 << 14 ) /* EN */ + +/* ICER0[T1] - */ +#define ICER0_T1_MSK (0x1 << 13 ) +#define ICER0_T1 (0x1 << 13 ) +#define ICER0_T1_DIS (0x0 << 13 ) /* DIS */ +#define ICER0_T1_EN (0x1 << 13 ) /* EN */ + +/* ICER0[T0] - */ +#define ICER0_T0_MSK (0x1 << 12 ) +#define ICER0_T0 (0x1 << 12 ) +#define ICER0_T0_DIS (0x0 << 12 ) /* DIS */ +#define ICER0_T0_EN (0x1 << 12 ) /* EN */ + +/* ICER0[T3] - */ +#define ICER0_T3_MSK (0x1 << 10 ) +#define ICER0_T3 (0x1 << 10 ) +#define ICER0_T3_DIS (0x0 << 10 ) /* DIS */ +#define ICER0_T3_EN (0x1 << 10 ) /* EN */ + +/* ICER0[EXTINT8] - */ +#define ICER0_EXTINT8_MSK (0x1 << 9 ) +#define ICER0_EXTINT8 (0x1 << 9 ) +#define ICER0_EXTINT8_DIS (0x0 << 9 ) /* DIS */ +#define ICER0_EXTINT8_EN (0x1 << 9 ) /* EN */ + +/* ICER0[EXTINT7] - */ +#define ICER0_EXTINT7_MSK (0x1 << 8 ) +#define ICER0_EXTINT7 (0x1 << 8 ) +#define ICER0_EXTINT7_DIS (0x0 << 8 ) /* DIS */ +#define ICER0_EXTINT7_EN (0x1 << 8 ) /* EN */ + +/* ICER0[EXTINT6] - */ +#define ICER0_EXTINT6_MSK (0x1 << 7 ) +#define ICER0_EXTINT6 (0x1 << 7 ) +#define ICER0_EXTINT6_DIS (0x0 << 7 ) /* DIS */ +#define ICER0_EXTINT6_EN (0x1 << 7 ) /* EN */ + +/* ICER0[EXTINT5] - */ +#define ICER0_EXTINT5_MSK (0x1 << 6 ) +#define ICER0_EXTINT5 (0x1 << 6 ) +#define ICER0_EXTINT5_DIS (0x0 << 6 ) /* DIS */ +#define ICER0_EXTINT5_EN (0x1 << 6 ) /* EN */ + +/* ICER0[EXTINT4] - */ +#define ICER0_EXTINT4_MSK (0x1 << 5 ) +#define ICER0_EXTINT4 (0x1 << 5 ) +#define ICER0_EXTINT4_DIS (0x0 << 5 ) /* DIS */ +#define ICER0_EXTINT4_EN (0x1 << 5 ) /* EN */ + +/* ICER0[EXTINT3] - */ +#define ICER0_EXTINT3_MSK (0x1 << 4 ) +#define ICER0_EXTINT3 (0x1 << 4 ) +#define ICER0_EXTINT3_DIS (0x0 << 4 ) /* DIS */ +#define ICER0_EXTINT3_EN (0x1 << 4 ) /* EN */ + +/* ICER0[EXTINT2] - */ +#define ICER0_EXTINT2_MSK (0x1 << 3 ) +#define ICER0_EXTINT2 (0x1 << 3 ) +#define ICER0_EXTINT2_DIS (0x0 << 3 ) /* DIS */ +#define ICER0_EXTINT2_EN (0x1 << 3 ) /* EN */ + +/* ICER0[EXTINT1] - */ +#define ICER0_EXTINT1_MSK (0x1 << 2 ) +#define ICER0_EXTINT1 (0x1 << 2 ) +#define ICER0_EXTINT1_DIS (0x0 << 2 ) /* DIS */ +#define ICER0_EXTINT1_EN (0x1 << 2 ) /* EN */ + +/* ICER0[EXTINT0] - */ +#define ICER0_EXTINT0_MSK (0x1 << 1 ) +#define ICER0_EXTINT0 (0x1 << 1 ) +#define ICER0_EXTINT0_DIS (0x0 << 1 ) /* DIS */ +#define ICER0_EXTINT0_EN (0x1 << 1 ) /* EN */ + +/* ICER0[T2] - */ +#define ICER0_T2_MSK (0x1 << 0 ) +#define ICER0_T2 (0x1 << 0 ) +#define ICER0_T2_DIS (0x0 << 0 ) /* DIS */ +#define ICER0_T2_EN (0x1 << 0 ) /* EN */ + +/* Reset Value for ICER1*/ +#define ICER1_RVAL 0x0 + +/* ICER1[PWM3] - */ +#define ICER1_PWM3_MSK (0x1 << 9 ) +#define ICER1_PWM3 (0x1 << 9 ) +#define ICER1_PWM3_DIS (0x0 << 9 ) /* DIS */ +#define ICER1_PWM3_EN (0x1 << 9 ) /* EN */ + +/* ICER1[PWM2] - */ +#define ICER1_PWM2_MSK (0x1 << 8 ) +#define ICER1_PWM2 (0x1 << 8 ) +#define ICER1_PWM2_DIS (0x0 << 8 ) /* DIS */ +#define ICER1_PWM2_EN (0x1 << 8 ) /* EN */ + +/* ICER1[PWM1] - */ +#define ICER1_PWM1_MSK (0x1 << 7 ) +#define ICER1_PWM1 (0x1 << 7 ) +#define ICER1_PWM1_DIS (0x0 << 7 ) /* DIS */ +#define ICER1_PWM1_EN (0x1 << 7 ) /* EN */ + +/* ICER1[PWM0] - */ +#define ICER1_PWM0_MSK (0x1 << 6 ) +#define ICER1_PWM0 (0x1 << 6 ) +#define ICER1_PWM0_DIS (0x0 << 6 ) /* DIS */ +#define ICER1_PWM0_EN (0x1 << 6 ) /* EN */ + +/* ICER1[PWMTRIP] - */ +#define ICER1_PWMTRIP_MSK (0x1 << 5 ) +#define ICER1_PWMTRIP (0x1 << 5 ) +#define ICER1_PWMTRIP_DIS (0x0 << 5 ) /* DIS */ +#define ICER1_PWMTRIP_EN (0x1 << 5 ) /* EN */ + +/* ICER1[DMASPI0RX] - */ +#define ICER1_DMASPI0RX_MSK (0x1 << 4 ) +#define ICER1_DMASPI0RX (0x1 << 4 ) +#define ICER1_DMASPI0RX_DIS (0x0 << 4 ) /* DIS */ +#define ICER1_DMASPI0RX_EN (0x1 << 4 ) /* EN */ + +/* ICER1[DMASPI0TX] - */ +#define ICER1_DMASPI0TX_MSK (0x1 << 3 ) +#define ICER1_DMASPI0TX (0x1 << 3 ) +#define ICER1_DMASPI0TX_DIS (0x0 << 3 ) /* DIS */ +#define ICER1_DMASPI0TX_EN (0x1 << 3 ) /* EN */ + +/* ICER1[DMAADC] - */ +#define ICER1_DMAADC_MSK (0x1 << 2 ) +#define ICER1_DMAADC (0x1 << 2 ) +#define ICER1_DMAADC_DIS (0x0 << 2 ) /* DIS */ +#define ICER1_DMAADC_EN (0x1 << 2 ) /* EN */ + +/* Reset Value for ISPR0*/ +#define ISPR0_RVAL 0x0 + +/* ISPR0[DMAI2CMRX] - */ +#define ISPR0_DMAI2CMRX_MSK (0x1 << 30 ) +#define ISPR0_DMAI2CMRX (0x1 << 30 ) +#define ISPR0_DMAI2CMRX_DIS (0x0 << 30 ) /* DIS */ +#define ISPR0_DMAI2CMRX_EN (0x1 << 30 ) /* EN */ + +/* ISPR0[DMAI2CMTX] - */ +#define ISPR0_DMAI2CMTX_MSK (0x1 << 29 ) +#define ISPR0_DMAI2CMTX (0x1 << 29 ) +#define ISPR0_DMAI2CMTX_DIS (0x0 << 29 ) /* DIS */ +#define ISPR0_DMAI2CMTX_EN (0x1 << 29 ) /* EN */ + +/* ISPR0[DMAI2CSRX] - */ +#define ISPR0_DMAI2CSRX_MSK (0x1 << 28 ) +#define ISPR0_DMAI2CSRX (0x1 << 28 ) +#define ISPR0_DMAI2CSRX_DIS (0x0 << 28 ) /* DIS */ +#define ISPR0_DMAI2CSRX_EN (0x1 << 28 ) /* EN */ + +/* ISPR0[DMAI2CSTX] - */ +#define ISPR0_DMAI2CSTX_MSK (0x1 << 27 ) +#define ISPR0_DMAI2CSTX (0x1 << 27 ) +#define ISPR0_DMAI2CSTX_DIS (0x0 << 27 ) /* DIS */ +#define ISPR0_DMAI2CSTX_EN (0x1 << 27 ) /* EN */ + +/* ISPR0[DMAUARTRX] - */ +#define ISPR0_DMAUARTRX_MSK (0x1 << 26 ) +#define ISPR0_DMAUARTRX (0x1 << 26 ) +#define ISPR0_DMAUARTRX_DIS (0x0 << 26 ) /* DIS */ +#define ISPR0_DMAUARTRX_EN (0x1 << 26 ) /* EN */ + +/* ISPR0[DMAUARTTX] - */ +#define ISPR0_DMAUARTTX_MSK (0x1 << 25 ) +#define ISPR0_DMAUARTTX (0x1 << 25 ) +#define ISPR0_DMAUARTTX_DIS (0x0 << 25 ) /* DIS */ +#define ISPR0_DMAUARTTX_EN (0x1 << 25 ) /* EN */ + +/* ISPR0[DMASPI1RX] - */ +#define ISPR0_DMASPI1RX_MSK (0x1 << 24 ) +#define ISPR0_DMASPI1RX (0x1 << 24 ) +#define ISPR0_DMASPI1RX_DIS (0x0 << 24 ) /* DIS */ +#define ISPR0_DMASPI1RX_EN (0x1 << 24 ) /* EN */ + +/* ISPR0[DMASPI1TX] - */ +#define ISPR0_DMASPI1TX_MSK (0x1 << 23 ) +#define ISPR0_DMASPI1TX (0x1 << 23 ) +#define ISPR0_DMASPI1TX_DIS (0x0 << 23 ) /* DIS */ +#define ISPR0_DMASPI1TX_EN (0x1 << 23 ) /* EN */ + +/* ISPR0[DMAERROR] - */ +#define ISPR0_DMAERROR_MSK (0x1 << 22 ) +#define ISPR0_DMAERROR (0x1 << 22 ) +#define ISPR0_DMAERROR_DIS (0x0 << 22 ) /* DIS */ +#define ISPR0_DMAERROR_EN (0x1 << 22 ) /* EN */ + +/* ISPR0[I2CM] - */ +#define ISPR0_I2CM_MSK (0x1 << 20 ) +#define ISPR0_I2CM (0x1 << 20 ) +#define ISPR0_I2CM_DIS (0x0 << 20 ) /* DIS */ +#define ISPR0_I2CM_EN (0x1 << 20 ) /* EN */ + +/* ISPR0[I2CS] - */ +#define ISPR0_I2CS_MSK (0x1 << 19 ) +#define ISPR0_I2CS (0x1 << 19 ) +#define ISPR0_I2CS_DIS (0x0 << 19 ) /* DIS */ +#define ISPR0_I2CS_EN (0x1 << 19 ) /* EN */ + +/* ISPR0[SPI1] - */ +#define ISPR0_SPI1_MSK (0x1 << 18 ) +#define ISPR0_SPI1 (0x1 << 18 ) +#define ISPR0_SPI1_DIS (0x0 << 18 ) /* DIS */ +#define ISPR0_SPI1_EN (0x1 << 18 ) /* EN */ + +/* ISPR0[SPI0] - */ +#define ISPR0_SPI0_MSK (0x1 << 17 ) +#define ISPR0_SPI0 (0x1 << 17 ) +#define ISPR0_SPI0_DIS (0x0 << 17 ) /* DIS */ +#define ISPR0_SPI0_EN (0x1 << 17 ) /* EN */ + +/* ISPR0[UART] - */ +#define ISPR0_UART_MSK (0x1 << 16 ) +#define ISPR0_UART (0x1 << 16 ) +#define ISPR0_UART_DIS (0x0 << 16 ) /* DIS */ +#define ISPR0_UART_EN (0x1 << 16 ) /* EN */ + +/* ISPR0[FEE] - */ +#define ISPR0_FEE_MSK (0x1 << 15 ) +#define ISPR0_FEE (0x1 << 15 ) +#define ISPR0_FEE_DIS (0x0 << 15 ) /* DIS */ +#define ISPR0_FEE_EN (0x1 << 15 ) /* EN */ + +/* ISPR0[ADC] - */ +#define ISPR0_ADC_MSK (0x1 << 14 ) +#define ISPR0_ADC (0x1 << 14 ) +#define ISPR0_ADC_DIS (0x0 << 14 ) /* DIS */ +#define ISPR0_ADC_EN (0x1 << 14 ) /* EN */ + +/* ISPR0[T1] - */ +#define ISPR0_T1_MSK (0x1 << 13 ) +#define ISPR0_T1 (0x1 << 13 ) +#define ISPR0_T1_DIS (0x0 << 13 ) /* DIS */ +#define ISPR0_T1_EN (0x1 << 13 ) /* EN */ + +/* ISPR0[T0] - */ +#define ISPR0_T0_MSK (0x1 << 12 ) +#define ISPR0_T0 (0x1 << 12 ) +#define ISPR0_T0_DIS (0x0 << 12 ) /* DIS */ +#define ISPR0_T0_EN (0x1 << 12 ) /* EN */ + +/* ISPR0[T3] - */ +#define ISPR0_T3_MSK (0x1 << 10 ) +#define ISPR0_T3 (0x1 << 10 ) +#define ISPR0_T3_DIS (0x0 << 10 ) /* DIS */ +#define ISPR0_T3_EN (0x1 << 10 ) /* EN */ + +/* ISPR0[EXTINT8] - */ +#define ISPR0_EXTINT8_MSK (0x1 << 9 ) +#define ISPR0_EXTINT8 (0x1 << 9 ) +#define ISPR0_EXTINT8_DIS (0x0 << 9 ) /* DIS */ +#define ISPR0_EXTINT8_EN (0x1 << 9 ) /* EN */ + +/* ISPR0[EXTINT7] - */ +#define ISPR0_EXTINT7_MSK (0x1 << 8 ) +#define ISPR0_EXTINT7 (0x1 << 8 ) +#define ISPR0_EXTINT7_DIS (0x0 << 8 ) /* DIS */ +#define ISPR0_EXTINT7_EN (0x1 << 8 ) /* EN */ + +/* ISPR0[EXTINT6] - */ +#define ISPR0_EXTINT6_MSK (0x1 << 7 ) +#define ISPR0_EXTINT6 (0x1 << 7 ) +#define ISPR0_EXTINT6_DIS (0x0 << 7 ) /* DIS */ +#define ISPR0_EXTINT6_EN (0x1 << 7 ) /* EN */ + +/* ISPR0[EXTINT5] - */ +#define ISPR0_EXTINT5_MSK (0x1 << 6 ) +#define ISPR0_EXTINT5 (0x1 << 6 ) +#define ISPR0_EXTINT5_DIS (0x0 << 6 ) /* DIS */ +#define ISPR0_EXTINT5_EN (0x1 << 6 ) /* EN */ + +/* ISPR0[EXTINT4] - */ +#define ISPR0_EXTINT4_MSK (0x1 << 5 ) +#define ISPR0_EXTINT4 (0x1 << 5 ) +#define ISPR0_EXTINT4_DIS (0x0 << 5 ) /* DIS */ +#define ISPR0_EXTINT4_EN (0x1 << 5 ) /* EN */ + +/* ISPR0[EXTINT3] - */ +#define ISPR0_EXTINT3_MSK (0x1 << 4 ) +#define ISPR0_EXTINT3 (0x1 << 4 ) +#define ISPR0_EXTINT3_DIS (0x0 << 4 ) /* DIS */ +#define ISPR0_EXTINT3_EN (0x1 << 4 ) /* EN */ + +/* ISPR0[EXTINT2] - */ +#define ISPR0_EXTINT2_MSK (0x1 << 3 ) +#define ISPR0_EXTINT2 (0x1 << 3 ) +#define ISPR0_EXTINT2_DIS (0x0 << 3 ) /* DIS */ +#define ISPR0_EXTINT2_EN (0x1 << 3 ) /* EN */ + +/* ISPR0[EXTINT1] - */ +#define ISPR0_EXTINT1_MSK (0x1 << 2 ) +#define ISPR0_EXTINT1 (0x1 << 2 ) +#define ISPR0_EXTINT1_DIS (0x0 << 2 ) /* DIS */ +#define ISPR0_EXTINT1_EN (0x1 << 2 ) /* EN */ + +/* ISPR0[EXTINT0] - */ +#define ISPR0_EXTINT0_MSK (0x1 << 1 ) +#define ISPR0_EXTINT0 (0x1 << 1 ) +#define ISPR0_EXTINT0_DIS (0x0 << 1 ) /* DIS */ +#define ISPR0_EXTINT0_EN (0x1 << 1 ) /* EN */ + +/* ISPR0[T2] - */ +#define ISPR0_T2_MSK (0x1 << 0 ) +#define ISPR0_T2 (0x1 << 0 ) +#define ISPR0_T2_DIS (0x0 << 0 ) /* DIS */ +#define ISPR0_T2_EN (0x1 << 0 ) /* EN */ + +/* Reset Value for ISPR1*/ +#define ISPR1_RVAL 0x0 + +/* ISPR1[PWM3] - */ +#define ISPR1_PWM3_MSK (0x1 << 9 ) +#define ISPR1_PWM3 (0x1 << 9 ) +#define ISPR1_PWM3_DIS (0x0 << 9 ) /* DIS */ +#define ISPR1_PWM3_EN (0x1 << 9 ) /* EN */ + +/* ISPR1[PWM2] - */ +#define ISPR1_PWM2_MSK (0x1 << 8 ) +#define ISPR1_PWM2 (0x1 << 8 ) +#define ISPR1_PWM2_DIS (0x0 << 8 ) /* DIS */ +#define ISPR1_PWM2_EN (0x1 << 8 ) /* EN */ + +/* ISPR1[PWM1] - */ +#define ISPR1_PWM1_MSK (0x1 << 7 ) +#define ISPR1_PWM1 (0x1 << 7 ) +#define ISPR1_PWM1_DIS (0x0 << 7 ) /* DIS */ +#define ISPR1_PWM1_EN (0x1 << 7 ) /* EN */ + +/* ISPR1[PWM0] - */ +#define ISPR1_PWM0_MSK (0x1 << 6 ) +#define ISPR1_PWM0 (0x1 << 6 ) +#define ISPR1_PWM0_DIS (0x0 << 6 ) /* DIS */ +#define ISPR1_PWM0_EN (0x1 << 6 ) /* EN */ + +/* ISPR1[PWMTRIP] - */ +#define ISPR1_PWMTRIP_MSK (0x1 << 5 ) +#define ISPR1_PWMTRIP (0x1 << 5 ) +#define ISPR1_PWMTRIP_DIS (0x0 << 5 ) /* DIS */ +#define ISPR1_PWMTRIP_EN (0x1 << 5 ) /* EN */ + +/* ISPR1[DMASPI0RX] - */ +#define ISPR1_DMASPI0RX_MSK (0x1 << 4 ) +#define ISPR1_DMASPI0RX (0x1 << 4 ) +#define ISPR1_DMASPI0RX_DIS (0x0 << 4 ) /* DIS */ +#define ISPR1_DMASPI0RX_EN (0x1 << 4 ) /* EN */ + +/* ISPR1[DMASPI0TX] - */ +#define ISPR1_DMASPI0TX_MSK (0x1 << 3 ) +#define ISPR1_DMASPI0TX (0x1 << 3 ) +#define ISPR1_DMASPI0TX_DIS (0x0 << 3 ) /* DIS */ +#define ISPR1_DMASPI0TX_EN (0x1 << 3 ) /* EN */ + +/* ISPR1[DMAADC] - */ +#define ISPR1_DMAADC_MSK (0x1 << 2 ) +#define ISPR1_DMAADC (0x1 << 2 ) +#define ISPR1_DMAADC_DIS (0x0 << 2 ) /* DIS */ +#define ISPR1_DMAADC_EN (0x1 << 2 ) /* EN */ + +/* Reset Value for ICPR0*/ +#define ICPR0_RVAL 0x0 + +/* ICPR0[DMAI2CMRX] - */ +#define ICPR0_DMAI2CMRX_MSK (0x1 << 30 ) +#define ICPR0_DMAI2CMRX (0x1 << 30 ) +#define ICPR0_DMAI2CMRX_DIS (0x0 << 30 ) /* DIS */ +#define ICPR0_DMAI2CMRX_EN (0x1 << 30 ) /* EN */ + +/* ICPR0[DMAI2CMTX] - */ +#define ICPR0_DMAI2CMTX_MSK (0x1 << 29 ) +#define ICPR0_DMAI2CMTX (0x1 << 29 ) +#define ICPR0_DMAI2CMTX_DIS (0x0 << 29 ) /* DIS */ +#define ICPR0_DMAI2CMTX_EN (0x1 << 29 ) /* EN */ + +/* ICPR0[DMAI2CSRX] - */ +#define ICPR0_DMAI2CSRX_MSK (0x1 << 28 ) +#define ICPR0_DMAI2CSRX (0x1 << 28 ) +#define ICPR0_DMAI2CSRX_DIS (0x0 << 28 ) /* DIS */ +#define ICPR0_DMAI2CSRX_EN (0x1 << 28 ) /* EN */ + +/* ICPR0[DMAI2CSTX] - */ +#define ICPR0_DMAI2CSTX_MSK (0x1 << 27 ) +#define ICPR0_DMAI2CSTX (0x1 << 27 ) +#define ICPR0_DMAI2CSTX_DIS (0x0 << 27 ) /* DIS */ +#define ICPR0_DMAI2CSTX_EN (0x1 << 27 ) /* EN */ + +/* ICPR0[DMAUARTRX] - */ +#define ICPR0_DMAUARTRX_MSK (0x1 << 26 ) +#define ICPR0_DMAUARTRX (0x1 << 26 ) +#define ICPR0_DMAUARTRX_DIS (0x0 << 26 ) /* DIS */ +#define ICPR0_DMAUARTRX_EN (0x1 << 26 ) /* EN */ + +/* ICPR0[DMAUARTTX] - */ +#define ICPR0_DMAUARTTX_MSK (0x1 << 25 ) +#define ICPR0_DMAUARTTX (0x1 << 25 ) +#define ICPR0_DMAUARTTX_DIS (0x0 << 25 ) /* DIS */ +#define ICPR0_DMAUARTTX_EN (0x1 << 25 ) /* EN */ + +/* ICPR0[DMASPI1RX] - */ +#define ICPR0_DMASPI1RX_MSK (0x1 << 24 ) +#define ICPR0_DMASPI1RX (0x1 << 24 ) +#define ICPR0_DMASPI1RX_DIS (0x0 << 24 ) /* DIS */ +#define ICPR0_DMASPI1RX_EN (0x1 << 24 ) /* EN */ + +/* ICPR0[DMASPI1TX] - */ +#define ICPR0_DMASPI1TX_MSK (0x1 << 23 ) +#define ICPR0_DMASPI1TX (0x1 << 23 ) +#define ICPR0_DMASPI1TX_DIS (0x0 << 23 ) /* DIS */ +#define ICPR0_DMASPI1TX_EN (0x1 << 23 ) /* EN */ + +/* ICPR0[DMAERROR] - */ +#define ICPR0_DMAERROR_MSK (0x1 << 22 ) +#define ICPR0_DMAERROR (0x1 << 22 ) +#define ICPR0_DMAERROR_DIS (0x0 << 22 ) /* DIS */ +#define ICPR0_DMAERROR_EN (0x1 << 22 ) /* EN */ + +/* ICPR0[I2CM] - */ +#define ICPR0_I2CM_MSK (0x1 << 20 ) +#define ICPR0_I2CM (0x1 << 20 ) +#define ICPR0_I2CM_DIS (0x0 << 20 ) /* DIS */ +#define ICPR0_I2CM_EN (0x1 << 20 ) /* EN */ + +/* ICPR0[I2CS] - */ +#define ICPR0_I2CS_MSK (0x1 << 19 ) +#define ICPR0_I2CS (0x1 << 19 ) +#define ICPR0_I2CS_DIS (0x0 << 19 ) /* DIS */ +#define ICPR0_I2CS_EN (0x1 << 19 ) /* EN */ + +/* ICPR0[SPI1] - */ +#define ICPR0_SPI1_MSK (0x1 << 18 ) +#define ICPR0_SPI1 (0x1 << 18 ) +#define ICPR0_SPI1_DIS (0x0 << 18 ) /* DIS */ +#define ICPR0_SPI1_EN (0x1 << 18 ) /* EN */ + +/* ICPR0[SPI0] - */ +#define ICPR0_SPI0_MSK (0x1 << 17 ) +#define ICPR0_SPI0 (0x1 << 17 ) +#define ICPR0_SPI0_DIS (0x0 << 17 ) /* DIS */ +#define ICPR0_SPI0_EN (0x1 << 17 ) /* EN */ + +/* ICPR0[UART] - */ +#define ICPR0_UART_MSK (0x1 << 16 ) +#define ICPR0_UART (0x1 << 16 ) +#define ICPR0_UART_DIS (0x0 << 16 ) /* DIS */ +#define ICPR0_UART_EN (0x1 << 16 ) /* EN */ + +/* ICPR0[FEE] - */ +#define ICPR0_FEE_MSK (0x1 << 15 ) +#define ICPR0_FEE (0x1 << 15 ) +#define ICPR0_FEE_DIS (0x0 << 15 ) /* DIS */ +#define ICPR0_FEE_EN (0x1 << 15 ) /* EN */ + +/* ICPR0[ADC] - */ +#define ICPR0_ADC_MSK (0x1 << 14 ) +#define ICPR0_ADC (0x1 << 14 ) +#define ICPR0_ADC_DIS (0x0 << 14 ) /* DIS */ +#define ICPR0_ADC_EN (0x1 << 14 ) /* EN */ + +/* ICPR0[T1] - */ +#define ICPR0_T1_MSK (0x1 << 13 ) +#define ICPR0_T1 (0x1 << 13 ) +#define ICPR0_T1_DIS (0x0 << 13 ) /* DIS */ +#define ICPR0_T1_EN (0x1 << 13 ) /* EN */ + +/* ICPR0[T0] - */ +#define ICPR0_T0_MSK (0x1 << 12 ) +#define ICPR0_T0 (0x1 << 12 ) +#define ICPR0_T0_DIS (0x0 << 12 ) /* DIS */ +#define ICPR0_T0_EN (0x1 << 12 ) /* EN */ + +/* ICPR0[T3] - */ +#define ICPR0_T3_MSK (0x1 << 10 ) +#define ICPR0_T3 (0x1 << 10 ) +#define ICPR0_T3_DIS (0x0 << 10 ) /* DIS */ +#define ICPR0_T3_EN (0x1 << 10 ) /* EN */ + +/* ICPR0[EXTINT8] - */ +#define ICPR0_EXTINT8_MSK (0x1 << 9 ) +#define ICPR0_EXTINT8 (0x1 << 9 ) +#define ICPR0_EXTINT8_DIS (0x0 << 9 ) /* DIS */ +#define ICPR0_EXTINT8_EN (0x1 << 9 ) /* EN */ + +/* ICPR0[EXTINT7] - */ +#define ICPR0_EXTINT7_MSK (0x1 << 8 ) +#define ICPR0_EXTINT7 (0x1 << 8 ) +#define ICPR0_EXTINT7_DIS (0x0 << 8 ) /* DIS */ +#define ICPR0_EXTINT7_EN (0x1 << 8 ) /* EN */ + +/* ICPR0[EXTINT6] - */ +#define ICPR0_EXTINT6_MSK (0x1 << 7 ) +#define ICPR0_EXTINT6 (0x1 << 7 ) +#define ICPR0_EXTINT6_DIS (0x0 << 7 ) /* DIS */ +#define ICPR0_EXTINT6_EN (0x1 << 7 ) /* EN */ + +/* ICPR0[EXTINT5] - */ +#define ICPR0_EXTINT5_MSK (0x1 << 6 ) +#define ICPR0_EXTINT5 (0x1 << 6 ) +#define ICPR0_EXTINT5_DIS (0x0 << 6 ) /* DIS */ +#define ICPR0_EXTINT5_EN (0x1 << 6 ) /* EN */ + +/* ICPR0[EXTINT4] - */ +#define ICPR0_EXTINT4_MSK (0x1 << 5 ) +#define ICPR0_EXTINT4 (0x1 << 5 ) +#define ICPR0_EXTINT4_DIS (0x0 << 5 ) /* DIS */ +#define ICPR0_EXTINT4_EN (0x1 << 5 ) /* EN */ + +/* ICPR0[EXTINT3] - */ +#define ICPR0_EXTINT3_MSK (0x1 << 4 ) +#define ICPR0_EXTINT3 (0x1 << 4 ) +#define ICPR0_EXTINT3_DIS (0x0 << 4 ) /* DIS */ +#define ICPR0_EXTINT3_EN (0x1 << 4 ) /* EN */ + +/* ICPR0[EXTINT2] - */ +#define ICPR0_EXTINT2_MSK (0x1 << 3 ) +#define ICPR0_EXTINT2 (0x1 << 3 ) +#define ICPR0_EXTINT2_DIS (0x0 << 3 ) /* DIS */ +#define ICPR0_EXTINT2_EN (0x1 << 3 ) /* EN */ + +/* ICPR0[EXTINT1] - */ +#define ICPR0_EXTINT1_MSK (0x1 << 2 ) +#define ICPR0_EXTINT1 (0x1 << 2 ) +#define ICPR0_EXTINT1_DIS (0x0 << 2 ) /* DIS */ +#define ICPR0_EXTINT1_EN (0x1 << 2 ) /* EN */ + +/* ICPR0[EXTINT0] - */ +#define ICPR0_EXTINT0_MSK (0x1 << 1 ) +#define ICPR0_EXTINT0 (0x1 << 1 ) +#define ICPR0_EXTINT0_DIS (0x0 << 1 ) /* DIS */ +#define ICPR0_EXTINT0_EN (0x1 << 1 ) /* EN */ + +/* ICPR0[T2] - */ +#define ICPR0_T2_MSK (0x1 << 0 ) +#define ICPR0_T2 (0x1 << 0 ) +#define ICPR0_T2_DIS (0x0 << 0 ) /* DIS */ +#define ICPR0_T2_EN (0x1 << 0 ) /* EN */ + +/* Reset Value for ICPR1*/ +#define ICPR1_RVAL 0x0 + +/* ICPR1[PWM3] - */ +#define ICPR1_PWM3_MSK (0x1 << 9 ) +#define ICPR1_PWM3 (0x1 << 9 ) +#define ICPR1_PWM3_DIS (0x0 << 9 ) /* DIS */ +#define ICPR1_PWM3_EN (0x1 << 9 ) /* EN */ + +/* ICPR1[PWM2] - */ +#define ICPR1_PWM2_MSK (0x1 << 8 ) +#define ICPR1_PWM2 (0x1 << 8 ) +#define ICPR1_PWM2_DIS (0x0 << 8 ) /* DIS */ +#define ICPR1_PWM2_EN (0x1 << 8 ) /* EN */ + +/* ICPR1[PWM1] - */ +#define ICPR1_PWM1_MSK (0x1 << 7 ) +#define ICPR1_PWM1 (0x1 << 7 ) +#define ICPR1_PWM1_DIS (0x0 << 7 ) /* DIS */ +#define ICPR1_PWM1_EN (0x1 << 7 ) /* EN */ + +/* ICPR1[PWM0] - */ +#define ICPR1_PWM0_MSK (0x1 << 6 ) +#define ICPR1_PWM0 (0x1 << 6 ) +#define ICPR1_PWM0_DIS (0x0 << 6 ) /* DIS */ +#define ICPR1_PWM0_EN (0x1 << 6 ) /* EN */ + +/* ICPR1[PWMTRIP] - */ +#define ICPR1_PWMTRIP_MSK (0x1 << 5 ) +#define ICPR1_PWMTRIP (0x1 << 5 ) +#define ICPR1_PWMTRIP_DIS (0x0 << 5 ) /* DIS */ +#define ICPR1_PWMTRIP_EN (0x1 << 5 ) /* EN */ + +/* ICPR1[DMASPI0RX] - */ +#define ICPR1_DMASPI0RX_MSK (0x1 << 4 ) +#define ICPR1_DMASPI0RX (0x1 << 4 ) +#define ICPR1_DMASPI0RX_DIS (0x0 << 4 ) /* DIS */ +#define ICPR1_DMASPI0RX_EN (0x1 << 4 ) /* EN */ + +/* ICPR1[DMASPI0TX] - */ +#define ICPR1_DMASPI0TX_MSK (0x1 << 3 ) +#define ICPR1_DMASPI0TX (0x1 << 3 ) +#define ICPR1_DMASPI0TX_DIS (0x0 << 3 ) /* DIS */ +#define ICPR1_DMASPI0TX_EN (0x1 << 3 ) /* EN */ + +/* ICPR1[DMAADC] - */ +#define ICPR1_DMAADC_MSK (0x1 << 2 ) +#define ICPR1_DMAADC (0x1 << 2 ) +#define ICPR1_DMAADC_DIS (0x0 << 2 ) /* DIS */ +#define ICPR1_DMAADC_EN (0x1 << 2 ) /* EN */ + +/* Reset Value for IABR0*/ +#define IABR0_RVAL 0x0 + +/* IABR0[DMAI2CMRX] - */ +#define IABR0_DMAI2CMRX_MSK (0x1 << 30 ) +#define IABR0_DMAI2CMRX (0x1 << 30 ) +#define IABR0_DMAI2CMRX_DIS (0x0 << 30 ) /* DIS */ +#define IABR0_DMAI2CMRX_EN (0x1 << 30 ) /* EN */ + +/* IABR0[DMAI2CMTX] - */ +#define IABR0_DMAI2CMTX_MSK (0x1 << 29 ) +#define IABR0_DMAI2CMTX (0x1 << 29 ) +#define IABR0_DMAI2CMTX_DIS (0x0 << 29 ) /* DIS */ +#define IABR0_DMAI2CMTX_EN (0x1 << 29 ) /* EN */ + +/* IABR0[DMAI2CSRX] - */ +#define IABR0_DMAI2CSRX_MSK (0x1 << 28 ) +#define IABR0_DMAI2CSRX (0x1 << 28 ) +#define IABR0_DMAI2CSRX_DIS (0x0 << 28 ) /* DIS */ +#define IABR0_DMAI2CSRX_EN (0x1 << 28 ) /* EN */ + +/* IABR0[DMAI2CSTX] - */ +#define IABR0_DMAI2CSTX_MSK (0x1 << 27 ) +#define IABR0_DMAI2CSTX (0x1 << 27 ) +#define IABR0_DMAI2CSTX_DIS (0x0 << 27 ) /* DIS */ +#define IABR0_DMAI2CSTX_EN (0x1 << 27 ) /* EN */ + +/* IABR0[DMAUARTRX] - */ +#define IABR0_DMAUARTRX_MSK (0x1 << 26 ) +#define IABR0_DMAUARTRX (0x1 << 26 ) +#define IABR0_DMAUARTRX_DIS (0x0 << 26 ) /* DIS */ +#define IABR0_DMAUARTRX_EN (0x1 << 26 ) /* EN */ + +/* IABR0[DMAUARTTX] - */ +#define IABR0_DMAUARTTX_MSK (0x1 << 25 ) +#define IABR0_DMAUARTTX (0x1 << 25 ) +#define IABR0_DMAUARTTX_DIS (0x0 << 25 ) /* DIS */ +#define IABR0_DMAUARTTX_EN (0x1 << 25 ) /* EN */ + +/* IABR0[DMASPI1RX] - */ +#define IABR0_DMASPI1RX_MSK (0x1 << 24 ) +#define IABR0_DMASPI1RX (0x1 << 24 ) +#define IABR0_DMASPI1RX_DIS (0x0 << 24 ) /* DIS */ +#define IABR0_DMASPI1RX_EN (0x1 << 24 ) /* EN */ + +/* IABR0[DMASPI1TX] - */ +#define IABR0_DMASPI1TX_MSK (0x1 << 23 ) +#define IABR0_DMASPI1TX (0x1 << 23 ) +#define IABR0_DMASPI1TX_DIS (0x0 << 23 ) /* DIS */ +#define IABR0_DMASPI1TX_EN (0x1 << 23 ) /* EN */ + +/* IABR0[DMAERROR] - */ +#define IABR0_DMAERROR_MSK (0x1 << 22 ) +#define IABR0_DMAERROR (0x1 << 22 ) +#define IABR0_DMAERROR_DIS (0x0 << 22 ) /* DIS */ +#define IABR0_DMAERROR_EN (0x1 << 22 ) /* EN */ + +/* IABR0[I2CM] - */ +#define IABR0_I2CM_MSK (0x1 << 20 ) +#define IABR0_I2CM (0x1 << 20 ) +#define IABR0_I2CM_DIS (0x0 << 20 ) /* DIS */ +#define IABR0_I2CM_EN (0x1 << 20 ) /* EN */ + +/* IABR0[I2CS] - */ +#define IABR0_I2CS_MSK (0x1 << 19 ) +#define IABR0_I2CS (0x1 << 19 ) +#define IABR0_I2CS_DIS (0x0 << 19 ) /* DIS */ +#define IABR0_I2CS_EN (0x1 << 19 ) /* EN */ + +/* IABR0[SPI1] - */ +#define IABR0_SPI1_MSK (0x1 << 18 ) +#define IABR0_SPI1 (0x1 << 18 ) +#define IABR0_SPI1_DIS (0x0 << 18 ) /* DIS */ +#define IABR0_SPI1_EN (0x1 << 18 ) /* EN */ + +/* IABR0[SPI0] - */ +#define IABR0_SPI0_MSK (0x1 << 17 ) +#define IABR0_SPI0 (0x1 << 17 ) +#define IABR0_SPI0_DIS (0x0 << 17 ) /* DIS */ +#define IABR0_SPI0_EN (0x1 << 17 ) /* EN */ + +/* IABR0[UART] - */ +#define IABR0_UART_MSK (0x1 << 16 ) +#define IABR0_UART (0x1 << 16 ) +#define IABR0_UART_DIS (0x0 << 16 ) /* DIS */ +#define IABR0_UART_EN (0x1 << 16 ) /* EN */ + +/* IABR0[FEE] - */ +#define IABR0_FEE_MSK (0x1 << 15 ) +#define IABR0_FEE (0x1 << 15 ) +#define IABR0_FEE_DIS (0x0 << 15 ) /* DIS */ +#define IABR0_FEE_EN (0x1 << 15 ) /* EN */ + +/* IABR0[ADC] - */ +#define IABR0_ADC_MSK (0x1 << 14 ) +#define IABR0_ADC (0x1 << 14 ) +#define IABR0_ADC_DIS (0x0 << 14 ) /* DIS */ +#define IABR0_ADC_EN (0x1 << 14 ) /* EN */ + +/* IABR0[T1] - */ +#define IABR0_T1_MSK (0x1 << 13 ) +#define IABR0_T1 (0x1 << 13 ) +#define IABR0_T1_DIS (0x0 << 13 ) /* DIS */ +#define IABR0_T1_EN (0x1 << 13 ) /* EN */ + +/* IABR0[T0] - */ +#define IABR0_T0_MSK (0x1 << 12 ) +#define IABR0_T0 (0x1 << 12 ) +#define IABR0_T0_DIS (0x0 << 12 ) /* DIS */ +#define IABR0_T0_EN (0x1 << 12 ) /* EN */ + +/* IABR0[T3] - */ +#define IABR0_T3_MSK (0x1 << 10 ) +#define IABR0_T3 (0x1 << 10 ) +#define IABR0_T3_DIS (0x0 << 10 ) /* DIS */ +#define IABR0_T3_EN (0x1 << 10 ) /* EN */ + +/* IABR0[EXTINT8] - */ +#define IABR0_EXTINT8_MSK (0x1 << 9 ) +#define IABR0_EXTINT8 (0x1 << 9 ) +#define IABR0_EXTINT8_DIS (0x0 << 9 ) /* DIS */ +#define IABR0_EXTINT8_EN (0x1 << 9 ) /* EN */ + +/* IABR0[EXTINT7] - */ +#define IABR0_EXTINT7_MSK (0x1 << 8 ) +#define IABR0_EXTINT7 (0x1 << 8 ) +#define IABR0_EXTINT7_DIS (0x0 << 8 ) /* DIS */ +#define IABR0_EXTINT7_EN (0x1 << 8 ) /* EN */ + +/* IABR0[EXTINT6] - */ +#define IABR0_EXTINT6_MSK (0x1 << 7 ) +#define IABR0_EXTINT6 (0x1 << 7 ) +#define IABR0_EXTINT6_DIS (0x0 << 7 ) /* DIS */ +#define IABR0_EXTINT6_EN (0x1 << 7 ) /* EN */ + +/* IABR0[EXTINT5] - */ +#define IABR0_EXTINT5_MSK (0x1 << 6 ) +#define IABR0_EXTINT5 (0x1 << 6 ) +#define IABR0_EXTINT5_DIS (0x0 << 6 ) /* DIS */ +#define IABR0_EXTINT5_EN (0x1 << 6 ) /* EN */ + +/* IABR0[EXTINT4] - */ +#define IABR0_EXTINT4_MSK (0x1 << 5 ) +#define IABR0_EXTINT4 (0x1 << 5 ) +#define IABR0_EXTINT4_DIS (0x0 << 5 ) /* DIS */ +#define IABR0_EXTINT4_EN (0x1 << 5 ) /* EN */ + +/* IABR0[EXTINT3] - */ +#define IABR0_EXTINT3_MSK (0x1 << 4 ) +#define IABR0_EXTINT3 (0x1 << 4 ) +#define IABR0_EXTINT3_DIS (0x0 << 4 ) /* DIS */ +#define IABR0_EXTINT3_EN (0x1 << 4 ) /* EN */ + +/* IABR0[EXTINT2] - */ +#define IABR0_EXTINT2_MSK (0x1 << 3 ) +#define IABR0_EXTINT2 (0x1 << 3 ) +#define IABR0_EXTINT2_DIS (0x0 << 3 ) /* DIS */ +#define IABR0_EXTINT2_EN (0x1 << 3 ) /* EN */ + +/* IABR0[EXTINT1] - */ +#define IABR0_EXTINT1_MSK (0x1 << 2 ) +#define IABR0_EXTINT1 (0x1 << 2 ) +#define IABR0_EXTINT1_DIS (0x0 << 2 ) /* DIS */ +#define IABR0_EXTINT1_EN (0x1 << 2 ) /* EN */ + +/* IABR0[EXTINT0] - */ +#define IABR0_EXTINT0_MSK (0x1 << 1 ) +#define IABR0_EXTINT0 (0x1 << 1 ) +#define IABR0_EXTINT0_DIS (0x0 << 1 ) /* DIS */ +#define IABR0_EXTINT0_EN (0x1 << 1 ) /* EN */ + +/* IABR0[T2] - */ +#define IABR0_T2_MSK (0x1 << 0 ) +#define IABR0_T2 (0x1 << 0 ) +#define IABR0_T2_DIS (0x0 << 0 ) /* DIS */ +#define IABR0_T2_EN (0x1 << 0 ) /* EN */ + +/* Reset Value for IABR1*/ +#define IABR1_RVAL 0x0 + +/* IABR1[PWM3] - */ +#define IABR1_PWM3_MSK (0x1 << 9 ) +#define IABR1_PWM3 (0x1 << 9 ) +#define IABR1_PWM3_DIS (0x0 << 9 ) /* DIS */ +#define IABR1_PWM3_EN (0x1 << 9 ) /* EN */ + +/* IABR1[PWM2] - */ +#define IABR1_PWM2_MSK (0x1 << 8 ) +#define IABR1_PWM2 (0x1 << 8 ) +#define IABR1_PWM2_DIS (0x0 << 8 ) /* DIS */ +#define IABR1_PWM2_EN (0x1 << 8 ) /* EN */ + +/* IABR1[PWM1] - */ +#define IABR1_PWM1_MSK (0x1 << 7 ) +#define IABR1_PWM1 (0x1 << 7 ) +#define IABR1_PWM1_DIS (0x0 << 7 ) /* DIS */ +#define IABR1_PWM1_EN (0x1 << 7 ) /* EN */ + +/* IABR1[PWM0] - */ +#define IABR1_PWM0_MSK (0x1 << 6 ) +#define IABR1_PWM0 (0x1 << 6 ) +#define IABR1_PWM0_DIS (0x0 << 6 ) /* DIS */ +#define IABR1_PWM0_EN (0x1 << 6 ) /* EN */ + +/* IABR1[PWMTRIP] - */ +#define IABR1_PWMTRIP_MSK (0x1 << 5 ) +#define IABR1_PWMTRIP (0x1 << 5 ) +#define IABR1_PWMTRIP_DIS (0x0 << 5 ) /* DIS */ +#define IABR1_PWMTRIP_EN (0x1 << 5 ) /* EN */ + +/* IABR1[DMASPI0RX] - */ +#define IABR1_DMASPI0RX_MSK (0x1 << 4 ) +#define IABR1_DMASPI0RX (0x1 << 4 ) +#define IABR1_DMASPI0RX_DIS (0x0 << 4 ) /* DIS */ +#define IABR1_DMASPI0RX_EN (0x1 << 4 ) /* EN */ + +/* IABR1[DMASPI0TX] - */ +#define IABR1_DMASPI0TX_MSK (0x1 << 3 ) +#define IABR1_DMASPI0TX (0x1 << 3 ) +#define IABR1_DMASPI0TX_DIS (0x0 << 3 ) /* DIS */ +#define IABR1_DMASPI0TX_EN (0x1 << 3 ) /* EN */ + +/* IABR1[DMAADC] - */ +#define IABR1_DMAADC_MSK (0x1 << 2 ) +#define IABR1_DMAADC (0x1 << 2 ) +#define IABR1_DMAADC_DIS (0x0 << 2 ) /* DIS */ +#define IABR1_DMAADC_EN (0x1 << 2 ) /* EN */ + +/* Reset Value for IPR0*/ +#define IPR0_RVAL 0x0 + +/* IPR0[EXTINT2] - */ +#define IPR0_EXTINT2_MSK (0xFF << 24 ) + +/* IPR0[EXTINT1] - */ +#define IPR0_EXTINT1_MSK (0xFF << 16 ) + +/* IPR0[EXTINT0] - Priority of interrupt number 1 */ +#define IPR0_EXTINT0_MSK (0xFF << 8 ) + +/* IPR0[T2] - Priority of interrupt number 0 */ +#define IPR0_T2_MSK (0xFF << 0 ) + +/* Reset Value for IPR1*/ +#define IPR1_RVAL 0x0 + +/* IPR1[EXTINT6] - */ +#define IPR1_EXTINT6_MSK (0xFF << 24 ) + +/* IPR1[EXTINT5] - */ +#define IPR1_EXTINT5_MSK (0xFF << 16 ) + +/* IPR1[EXTINT4] - */ +#define IPR1_EXTINT4_MSK (0xFF << 8 ) + +/* IPR1[EXTINT3] - */ +#define IPR1_EXTINT3_MSK (0xFF << 0 ) + +/* Reset Value for IPR2*/ +#define IPR2_RVAL 0x0 + +/* IPR2[T3] - */ +#define IPR2_T3_MSK (0xFF << 16 ) + +/* IPR2[EXTINT8] - */ +#define IPR2_EXTINT8_MSK (0xFF << 8 ) + +/* IPR2[EXTINT7] - */ +#define IPR2_EXTINT7_MSK (0xFF << 0 ) + +/* Reset Value for IPR3*/ +#define IPR3_RVAL 0x0 + +/* IPR3[FEE] - */ +#define IPR3_FEE_MSK (0xFF << 24 ) + +/* IPR3[ADC] - */ +#define IPR3_ADC_MSK (0xFF << 16 ) + +/* IPR3[T1] - */ +#define IPR3_T1_MSK (0xFF << 8 ) + +/* IPR3[T0] - */ +#define IPR3_T0_MSK (0xFF << 0 ) + +/* Reset Value for IPR4*/ +#define IPR4_RVAL 0x0 + +/* IPR4[I2CS] - */ +#define IPR4_I2CS_MSK (0xFF << 24 ) + +/* IPR4[SPI1] - */ +#define IPR4_SPI1_MSK (0xFF << 16 ) + +/* IPR4[SPI0] - */ +#define IPR4_SPI0_MSK (0xFF << 8 ) + +/* IPR4[UART] - */ +#define IPR4_UART_MSK (0xFF << 0 ) + +/* Reset Value for IPR5*/ +#define IPR5_RVAL 0x0 + +/* IPR5[DMASPI1TX] - */ +#define IPR5_DMASPI1TX_MSK (0xFF << 24 ) + +/* IPR5[DMAERROR] - */ +#define IPR5_DMAERROR_MSK (0xFF << 16 ) + +/* IPR5[I2CM] - I2CM */ +#define IPR5_I2CM_MSK (0xFF << 0 ) + +/* Reset Value for IPR6*/ +#define IPR6_RVAL 0x0 + +/* IPR6[DMAI2CSTX] - */ +#define IPR6_DMAI2CSTX_MSK (0xFF << 24 ) + +/* IPR6[DMAUARTRX] - */ +#define IPR6_DMAUARTRX_MSK (0xFF << 16 ) + +/* IPR6[DMAUARTTX] - */ +#define IPR6_DMAUARTTX_MSK (0xFF << 8 ) + +/* IPR6[DMASPI1RX] - */ +#define IPR6_DMASPI1RX_MSK (0xFF << 0 ) + +/* Reset Value for IPR7*/ +#define IPR7_RVAL 0x0 + +/* IPR7[DMAI2CMRX] - */ +#define IPR7_DMAI2CMRX_MSK (0xFF << 16 ) + +/* IPR7[DMAI2CMTX] - */ +#define IPR7_DMAI2CMTX_MSK (0xFF << 8 ) + +/* IPR7[DMAI2CSRX] - */ +#define IPR7_DMAI2CSRX_MSK (0xFF << 0 ) + +/* Reset Value for IPR8*/ +#define IPR8_RVAL 0x0 + +/* IPR8[DMASPI0TX] - */ +#define IPR8_DMASPI0TX_MSK (0xFF << 24 ) + +/* IPR8[DMAADC] - */ +#define IPR8_DMAADC_MSK (0xFF << 16 ) + +/* Reset Value for IPR9*/ +#define IPR9_RVAL 0x0 + +/* IPR9[PWM1] - */ +#define IPR9_PWM1_MSK (0xFF << 24 ) + +/* IPR9[PWM0] - */ +#define IPR9_PWM0_MSK (0xFF << 16 ) + +/* IPR9[PWMTRIP] - */ +#define IPR9_PWMTRIP_MSK (0xFF << 8 ) + +/* IPR9[DMASPI0RX] - */ +#define IPR9_DMASPI0RX_MSK (0xFF << 0 ) + +/* Reset Value for IPR10*/ +#define IPR10_RVAL 0x0 + +/* IPR10[PWM3] - */ +#define IPR10_PWM3_MSK (0xFF << 8 ) + +/* IPR10[PWM2] - */ +#define IPR10_PWM2_MSK (0xFF << 0 ) + +/* Reset Value for CPUID*/ +#define CPUID_RVAL 0x412FC230 + +/* CPUID[IMPLEMENTER] - Indicates implementor */ +#define CPUID_IMPLEMENTER_MSK (0xFF << 24 ) + +/* CPUID[VARIANT] - Indicates processor revision */ +#define CPUID_VARIANT_MSK (0xF << 20 ) + +/* CPUID[PARTNO] - Indicates part number */ +#define CPUID_PARTNO_MSK (0xFFF << 4 ) + +/* CPUID[REVISION] - Indicates patch release */ +#define CPUID_REVISION_MSK (0xF << 0 ) + +/* Reset Value for ICSR*/ +#define ICSR_RVAL 0x0 + +/* ICSR[NMIPENDSET] - Setting this bit will activate an NMI */ +#define ICSR_NMIPENDSET_MSK (0x1 << 31 ) +#define ICSR_NMIPENDSET (0x1 << 31 ) +#define ICSR_NMIPENDSET_DIS (0x0 << 31 ) /* DIS */ +#define ICSR_NMIPENDSET_EN (0x1 << 31 ) /* EN */ + +/* ICSR[PENDSVSET] - Set a pending PendSV interrupt */ +#define ICSR_PENDSVSET_MSK (0x1 << 28 ) +#define ICSR_PENDSVSET (0x1 << 28 ) +#define ICSR_PENDSVSET_DIS (0x0 << 28 ) /* DIS */ +#define ICSR_PENDSVSET_EN (0x1 << 28 ) /* EN */ + +/* ICSR[PENDSVCLR] - Clear a pending PendSV interrupt */ +#define ICSR_PENDSVCLR_MSK (0x1 << 27 ) +#define ICSR_PENDSVCLR (0x1 << 27 ) +#define ICSR_PENDSVCLR_DIS (0x0 << 27 ) /* DIS */ +#define ICSR_PENDSVCLR_EN (0x1 << 27 ) /* EN */ + +/* ICSR[PENDSTSET] - Set a pending SysTick. Reads back with current state */ +#define ICSR_PENDSTSET_MSK (0x1 << 26 ) +#define ICSR_PENDSTSET (0x1 << 26 ) +#define ICSR_PENDSTSET_DIS (0x0 << 26 ) /* DIS */ +#define ICSR_PENDSTSET_EN (0x1 << 26 ) /* EN */ + +/* ICSR[PENDSTCLR] - Clear a pending SysTick */ +#define ICSR_PENDSTCLR_MSK (0x1 << 25 ) +#define ICSR_PENDSTCLR (0x1 << 25 ) +#define ICSR_PENDSTCLR_DIS (0x0 << 25 ) /* DIS */ +#define ICSR_PENDSTCLR_EN (0x1 << 25 ) /* EN */ + +/* ICSR[ISRPREEMPT] - If set, a pending exception will be serviced on exit from the debug halt state */ +#define ICSR_ISRPREEMPT_MSK (0x1 << 23 ) +#define ICSR_ISRPREEMPT (0x1 << 23 ) +#define ICSR_ISRPREEMPT_DIS (0x0 << 23 ) /* DIS */ +#define ICSR_ISRPREEMPT_EN (0x1 << 23 ) /* EN */ + +/* ICSR[ISRPENDING] - Indicates if an external configurable is pending */ +#define ICSR_ISRPENDING_MSK (0x1 << 22 ) +#define ICSR_ISRPENDING (0x1 << 22 ) +#define ICSR_ISRPENDING_DIS (0x0 << 22 ) /* DIS */ +#define ICSR_ISRPENDING_EN (0x1 << 22 ) /* EN */ + +/* ICSR[VECTPENDING] - Indicates the exception number for the highest priority pending exception */ +#define ICSR_VECTPENDING_MSK (0x1FF << 12 ) + +/* ICSR[RETTOBASE] - */ +#define ICSR_RETTOBASE_MSK (0x1 << 11 ) +#define ICSR_RETTOBASE (0x1 << 11 ) +#define ICSR_RETTOBASE_DIS (0x0 << 11 ) /* DIS */ +#define ICSR_RETTOBASE_EN (0x1 << 11 ) /* EN */ + +/* ICSR[VECTACTIVE] - Thread mode, or exception number */ +#define ICSR_VECTACTIVE_MSK (0x1FF << 0 ) + +/* Reset Value for VTOR*/ +#define VTOR_RVAL 0x0 + +/* VTOR[TBLBASE] - */ +#define VTOR_TBLBASE_MSK (0x1 << 29 ) +#define VTOR_TBLBASE (0x1 << 29 ) +#define VTOR_TBLBASE_DIS (0x0 << 29 ) /* DIS */ +#define VTOR_TBLBASE_EN (0x1 << 29 ) /* EN */ + +/* VTOR[TBLOFF] - */ +#define VTOR_TBLOFF_MSK (0x3FFFFF << 7 ) + +/* Reset Value for AIRCR*/ +#define AIRCR_RVAL 0xFA050000 + +/* AIRCR[VECTKEYSTAT] - Reads as 0xFA05 */ +#define AIRCR_VECTKEYSTAT_MSK (0xFFFF << 16 ) + +/* AIRCR[ENDIANESS] - This bit is static or configured by a hardware input on reset */ +#define AIRCR_ENDIANESS_MSK (0x1 << 15 ) +#define AIRCR_ENDIANESS (0x1 << 15 ) +#define AIRCR_ENDIANESS_DIS (0x0 << 15 ) /* DIS */ +#define AIRCR_ENDIANESS_EN (0x1 << 15 ) /* EN */ + +/* AIRCR[PRIGROUP] - Priority grouping position */ +#define AIRCR_PRIGROUP_MSK (0x7 << 8 ) + +/* AIRCR[SYSRESETREQ] - System Reset Request */ +#define AIRCR_SYSRESETREQ_MSK (0x1 << 2 ) +#define AIRCR_SYSRESETREQ (0x1 << 2 ) +#define AIRCR_SYSRESETREQ_DIS (0x0 << 2 ) /* DIS */ +#define AIRCR_SYSRESETREQ_EN (0x1 << 2 ) /* EN */ + +/* AIRCR[VECTCLRACTIVE] - Clears all active state information for fixed and configurable exceptions */ +#define AIRCR_VECTCLRACTIVE_MSK (0x1 << 1 ) +#define AIRCR_VECTCLRACTIVE (0x1 << 1 ) +#define AIRCR_VECTCLRACTIVE_DIS (0x0 << 1 ) /* DIS */ +#define AIRCR_VECTCLRACTIVE_EN (0x1 << 1 ) /* EN */ + +/* AIRCR[VECTRESET] - Local system reset */ +#define AIRCR_VECTRESET_MSK (0x1 << 0 ) +#define AIRCR_VECTRESET (0x1 << 0 ) +#define AIRCR_VECTRESET_DIS (0x0 << 0 ) /* DIS */ +#define AIRCR_VECTRESET_EN (0x1 << 0 ) /* EN */ + +/* Reset Value for SCR*/ +#define SCR_RVAL 0x0 + +/* SCR[SEVONPEND] - */ +#define SCR_SEVONPEND_MSK (0x1 << 4 ) +#define SCR_SEVONPEND (0x1 << 4 ) +#define SCR_SEVONPEND_DIS (0x0 << 4 ) /* DIS */ +#define SCR_SEVONPEND_EN (0x1 << 4 ) /* EN */ + +/* SCR[SLEEPDEEP] - Sleep deep bit */ +#define SCR_SLEEPDEEP_MSK (0x1 << 2 ) +#define SCR_SLEEPDEEP (0x1 << 2 ) +#define SCR_SLEEPDEEP_DIS (0x0 << 2 ) /* DIS */ +#define SCR_SLEEPDEEP_EN (0x1 << 2 ) /* EN */ + +/* SCR[SLEEPONEXIT] - Sleep on exit when returning from handler mode to thread mode */ +#define SCR_SLEEPONEXIT_MSK (0x1 << 1 ) +#define SCR_SLEEPONEXIT (0x1 << 1 ) +#define SCR_SLEEPONEXIT_DIS (0x0 << 1 ) /* DIS */ +#define SCR_SLEEPONEXIT_EN (0x1 << 1 ) /* EN */ + +/* Reset Value for CCR*/ +#define CCR_RVAL 0x200 + +/* CCR[STKALIGN] - */ +#define CCR_STKALIGN_MSK (0x1 << 9 ) +#define CCR_STKALIGN (0x1 << 9 ) +#define CCR_STKALIGN_DIS (0x0 << 9 ) /* DIS */ +#define CCR_STKALIGN_EN (0x1 << 9 ) /* EN */ + +/* CCR[BFHFNMIGN] - */ +#define CCR_BFHFNMIGN_MSK (0x1 << 8 ) +#define CCR_BFHFNMIGN (0x1 << 8 ) +#define CCR_BFHFNMIGN_DIS (0x0 << 8 ) /* DIS */ +#define CCR_BFHFNMIGN_EN (0x1 << 8 ) /* EN */ + +/* CCR[DIV0TRP] - */ +#define CCR_DIV0TRP_MSK (0x1 << 4 ) +#define CCR_DIV0TRP (0x1 << 4 ) +#define CCR_DIV0TRP_DIS (0x0 << 4 ) /* DIS */ +#define CCR_DIV0TRP_EN (0x1 << 4 ) /* EN */ + +/* CCR[UNALIGNTRP] - */ +#define CCR_UNALIGNTRP_MSK (0x1 << 3 ) +#define CCR_UNALIGNTRP (0x1 << 3 ) +#define CCR_UNALIGNTRP_DIS (0x0 << 3 ) /* DIS */ +#define CCR_UNALIGNTRP_EN (0x1 << 3 ) /* EN */ + +/* CCR[USERSETMPEND] - */ +#define CCR_USERSETMPEND_MSK (0x1 << 1 ) +#define CCR_USERSETMPEND (0x1 << 1 ) +#define CCR_USERSETMPEND_DIS (0x0 << 1 ) /* DIS */ +#define CCR_USERSETMPEND_EN (0x1 << 1 ) /* EN */ + +/* CCR[NONBASETHRDENA] - */ +#define CCR_NONBASETHRDENA_MSK (0x1 << 0 ) +#define CCR_NONBASETHRDENA (0x1 << 0 ) +#define CCR_NONBASETHRDENA_DIS (0x0 << 0 ) /* DIS */ +#define CCR_NONBASETHRDENA_EN (0x1 << 0 ) /* EN */ + +/* Reset Value for SHPR1*/ +#define SHPR1_RVAL 0x0 + +/* SHPR1[PRI7] - Priority of system handler 7 - reserved */ +#define SHPR1_PRI7_MSK (0xFF << 24 ) + +/* SHPR1[PRI6] - Priority of system handler 6 - UsageFault */ +#define SHPR1_PRI6_MSK (0xFF << 16 ) + +/* SHPR1[PRI5] - Priority of system handler 5 - BusFault */ +#define SHPR1_PRI5_MSK (0xFF << 8 ) + +/* SHPR1[PRI4] - Priority of system handler 4 - MemManage */ +#define SHPR1_PRI4_MSK (0xFF << 0 ) + +/* Reset Value for SHPR2*/ +#define SHPR2_RVAL 0x0 + +/* SHPR2[PRI11] - Priority of system handler 11 - SVCall */ +#define SHPR2_PRI11_MSK (0xFF << 24 ) + +/* SHPR2[PRI10] - Priority of system handler 10 - reserved */ +#define SHPR2_PRI10_MSK (0xFF << 16 ) + +/* SHPR2[PRI9] - Priority of system handler 9 - reserved */ +#define SHPR2_PRI9_MSK (0xFF << 8 ) + +/* SHPR2[PRI8] - Priority of system handler 8 - reserved */ +#define SHPR2_PRI8_MSK (0xFF << 0 ) + +/* Reset Value for SHPR3*/ +#define SHPR3_RVAL 0x0 + +/* SHPR3[PRI15] - Priority of system handler 15 - SysTick */ +#define SHPR3_PRI15_MSK (0xFF << 24 ) + +/* SHPR3[PRI14] - Priority of system handler 14 - PendSV */ +#define SHPR3_PRI14_MSK (0xFF << 16 ) + +/* SHPR3[PRI13] - Priority of system handler 13 - reserved */ +#define SHPR3_PRI13_MSK (0xFF << 8 ) + +/* SHPR3[PRI12] - Priority of system handler 12 - DebugMonitor */ +#define SHPR3_PRI12_MSK (0xFF << 0 ) + +/* Reset Value for SHCSR*/ +#define SHCSR_RVAL 0x0 + +/* SHCSR[USGFAULTENA] - Enable for UsageFault */ +#define SHCSR_USGFAULTENA_MSK (0x1 << 18 ) +#define SHCSR_USGFAULTENA (0x1 << 18 ) +#define SHCSR_USGFAULTENA_DIS (0x0 << 18 ) /* DIS */ +#define SHCSR_USGFAULTENA_EN (0x1 << 18 ) /* EN */ + +/* SHCSR[BUSFAULTENA] - Enable for BusFault. */ +#define SHCSR_BUSFAULTENA_MSK (0x1 << 17 ) +#define SHCSR_BUSFAULTENA (0x1 << 17 ) +#define SHCSR_BUSFAULTENA_DIS (0x0 << 17 ) /* DIS */ +#define SHCSR_BUSFAULTENA_EN (0x1 << 17 ) /* EN */ + +/* SHCSR[MEMFAULTENA] - Enable for MemManage fault. */ +#define SHCSR_MEMFAULTENA_MSK (0x1 << 16 ) +#define SHCSR_MEMFAULTENA (0x1 << 16 ) +#define SHCSR_MEMFAULTENA_DIS (0x0 << 16 ) /* DIS */ +#define SHCSR_MEMFAULTENA_EN (0x1 << 16 ) /* EN */ + +/* SHCSR[SVCALLPENDED] - Reads as 1 if SVCall is Pending */ +#define SHCSR_SVCALLPENDED_MSK (0x1 << 15 ) +#define SHCSR_SVCALLPENDED (0x1 << 15 ) +#define SHCSR_SVCALLPENDED_DIS (0x0 << 15 ) /* DIS */ +#define SHCSR_SVCALLPENDED_EN (0x1 << 15 ) /* EN */ + +/* SHCSR[BUSFAULTPENDED] - Reads as 1 if BusFault is Pending */ +#define SHCSR_BUSFAULTPENDED_MSK (0x1 << 14 ) +#define SHCSR_BUSFAULTPENDED (0x1 << 14 ) +#define SHCSR_BUSFAULTPENDED_DIS (0x0 << 14 ) /* DIS */ +#define SHCSR_BUSFAULTPENDED_EN (0x1 << 14 ) /* EN */ + +/* SHCSR[MEMFAULTPENDED] - Reads as 1 if MemManage is Pending */ +#define SHCSR_MEMFAULTPENDED_MSK (0x1 << 13 ) +#define SHCSR_MEMFAULTPENDED (0x1 << 13 ) +#define SHCSR_MEMFAULTPENDED_DIS (0x0 << 13 ) /* DIS */ +#define SHCSR_MEMFAULTPENDED_EN (0x1 << 13 ) /* EN */ + +/* SHCSR[USGFAULTPENDED] - Reads as 1 if UsageFault is Pending */ +#define SHCSR_USGFAULTPENDED_MSK (0x1 << 12 ) +#define SHCSR_USGFAULTPENDED (0x1 << 12 ) +#define SHCSR_USGFAULTPENDED_DIS (0x0 << 12 ) /* DIS */ +#define SHCSR_USGFAULTPENDED_EN (0x1 << 12 ) /* EN */ + +/* SHCSR[SYSTICKACT] - Reads as 1 if SysTick is Active */ +#define SHCSR_SYSTICKACT_MSK (0x1 << 11 ) +#define SHCSR_SYSTICKACT (0x1 << 11 ) +#define SHCSR_SYSTICKACT_DIS (0x0 << 11 ) /* DIS */ +#define SHCSR_SYSTICKACT_EN (0x1 << 11 ) /* EN */ + +/* SHCSR[PENDSVACT] - Reads as 1 if PendSV is Active */ +#define SHCSR_PENDSVACT_MSK (0x1 << 10 ) +#define SHCSR_PENDSVACT (0x1 << 10 ) +#define SHCSR_PENDSVACT_DIS (0x0 << 10 ) /* DIS */ +#define SHCSR_PENDSVACT_EN (0x1 << 10 ) /* EN */ + +/* SHCSR[MONITORACT] - Reads as 1 if the Monitor is Active */ +#define SHCSR_MONITORACT_MSK (0x1 << 8 ) +#define SHCSR_MONITORACT (0x1 << 8 ) +#define SHCSR_MONITORACT_DIS (0x0 << 8 ) /* DIS */ +#define SHCSR_MONITORACT_EN (0x1 << 8 ) /* EN */ + +/* SHCSR[SVCALLACT] - Reads as 1 if SVCall is Active */ +#define SHCSR_SVCALLACT_MSK (0x1 << 7 ) +#define SHCSR_SVCALLACT (0x1 << 7 ) +#define SHCSR_SVCALLACT_DIS (0x0 << 7 ) /* DIS */ +#define SHCSR_SVCALLACT_EN (0x1 << 7 ) /* EN */ + +/* SHCSR[USGFAULTACT] - Reads as 1 if UsageFault is Active. */ +#define SHCSR_USGFAULTACT_MSK (0x1 << 3 ) +#define SHCSR_USGFAULTACT (0x1 << 3 ) +#define SHCSR_USGFAULTACT_DIS (0x0 << 3 ) /* DIS */ +#define SHCSR_USGFAULTACT_EN (0x1 << 3 ) /* EN */ + +/* SHCSR[BUSFAULTACT] - Reads as 1 if BusFault is Active. */ +#define SHCSR_BUSFAULTACT_MSK (0x1 << 1 ) +#define SHCSR_BUSFAULTACT (0x1 << 1 ) +#define SHCSR_BUSFAULTACT_DIS (0x0 << 1 ) /* DIS */ +#define SHCSR_BUSFAULTACT_EN (0x1 << 1 ) /* EN */ + +/* SHCSR[MEMFAULTACT] - Reads as 1 if MemManage is Active */ +#define SHCSR_MEMFAULTACT_MSK (0x1 << 0 ) +#define SHCSR_MEMFAULTACT (0x1 << 0 ) +#define SHCSR_MEMFAULTACT_DIS (0x0 << 0 ) /* DIS */ +#define SHCSR_MEMFAULTACT_EN (0x1 << 0 ) /* EN */ + +/* Reset Value for CFSR*/ +#define CFSR_RVAL 0x0 + +/* CFSR[DIVBYZERO] - Divide by zero error */ +#define CFSR_DIVBYZERO_MSK (0x1 << 25 ) +#define CFSR_DIVBYZERO (0x1 << 25 ) +#define CFSR_DIVBYZERO_DIS (0x0 << 25 ) /* DIS */ +#define CFSR_DIVBYZERO_EN (0x1 << 25 ) /* EN */ + +/* CFSR[UNALIGNED] - Unaligned access error */ +#define CFSR_UNALIGNED_MSK (0x1 << 24 ) +#define CFSR_UNALIGNED (0x1 << 24 ) +#define CFSR_UNALIGNED_DIS (0x0 << 24 ) /* DIS */ +#define CFSR_UNALIGNED_EN (0x1 << 24 ) /* EN */ + +/* CFSR[NOCP] - Coprocessor access error */ +#define CFSR_NOCP_MSK (0x1 << 19 ) +#define CFSR_NOCP (0x1 << 19 ) +#define CFSR_NOCP_DIS (0x0 << 19 ) /* DIS */ +#define CFSR_NOCP_EN (0x1 << 19 ) /* EN */ + +/* CFSR[INVPC] - Integrity check error on EXC_RETURN */ +#define CFSR_INVPC_MSK (0x1 << 18 ) +#define CFSR_INVPC (0x1 << 18 ) +#define CFSR_INVPC_DIS (0x0 << 18 ) /* DIS */ +#define CFSR_INVPC_EN (0x1 << 18 ) /* EN */ + +/* CFSR[INVSTATE] - Invalid EPSR.T bit or illegal EPSR.IT bits for executing */ +#define CFSR_INVSTATE_MSK (0x1 << 17 ) +#define CFSR_INVSTATE (0x1 << 17 ) +#define CFSR_INVSTATE_DIS (0x0 << 17 ) /* DIS */ +#define CFSR_INVSTATE_EN (0x1 << 17 ) /* EN */ + +/* CFSR[UNDEFINSTR] - Undefined instruction executed */ +#define CFSR_UNDEFINSTR_MSK (0x1 << 16 ) +#define CFSR_UNDEFINSTR (0x1 << 16 ) +#define CFSR_UNDEFINSTR_DIS (0x0 << 16 ) /* DIS */ +#define CFSR_UNDEFINSTR_EN (0x1 << 16 ) /* EN */ + +/* CFSR[BFARVALID] - This bit is set if the BFAR register has valid contents */ +#define CFSR_BFARVALID_MSK (0x1 << 15 ) +#define CFSR_BFARVALID (0x1 << 15 ) +#define CFSR_BFARVALID_DIS (0x0 << 15 ) /* DIS */ +#define CFSR_BFARVALID_EN (0x1 << 15 ) /* EN */ + +/* CFSR[STKERR] - This bit indicates a derived bus fault has occurred on exception entry */ +#define CFSR_STKERR_MSK (0x1 << 12 ) +#define CFSR_STKERR (0x1 << 12 ) +#define CFSR_STKERR_DIS (0x0 << 12 ) /* DIS */ +#define CFSR_STKERR_EN (0x1 << 12 ) /* EN */ + +/* CFSR[UNSTKERR] - This bit indicates a derived bus fault has occurred on exception return */ +#define CFSR_UNSTKERR_MSK (0x1 << 11 ) +#define CFSR_UNSTKERR (0x1 << 11 ) +#define CFSR_UNSTKERR_DIS (0x0 << 11 ) /* DIS */ +#define CFSR_UNSTKERR_EN (0x1 << 11 ) /* EN */ + +/* CFSR[IMPRECISERR] - Imprecise data access error */ +#define CFSR_IMPRECISERR_MSK (0x1 << 10 ) +#define CFSR_IMPRECISERR (0x1 << 10 ) +#define CFSR_IMPRECISERR_DIS (0x0 << 10 ) /* DIS */ +#define CFSR_IMPRECISERR_EN (0x1 << 10 ) /* EN */ + +/* CFSR[PRECISERR] - Precise data access error. The BFAR is written with the faulting address */ +#define CFSR_PRECISERR_MSK (0x1 << 9 ) +#define CFSR_PRECISERR (0x1 << 9 ) +#define CFSR_PRECISERR_DIS (0x0 << 9 ) /* DIS */ +#define CFSR_PRECISERR_EN (0x1 << 9 ) /* EN */ + +/* CFSR[IBUSERR] - This bit indicates a bus fault on an instruction prefetch */ +#define CFSR_IBUSERR_MSK (0x1 << 8 ) +#define CFSR_IBUSERR (0x1 << 8 ) +#define CFSR_IBUSERR_DIS (0x0 << 8 ) /* DIS */ +#define CFSR_IBUSERR_EN (0x1 << 8 ) /* EN */ + +/* CFSR[MMARVALID] - This bit is set if the MMAR register has valid contents. */ +#define CFSR_MMARVALID_MSK (0x1 << 7 ) +#define CFSR_MMARVALID (0x1 << 7 ) +#define CFSR_MMARVALID_DIS (0x0 << 7 ) /* DIS */ +#define CFSR_MMARVALID_EN (0x1 << 7 ) /* EN */ + +/* CFSR[MSTKERR] - A derived MemManage fault has occurred on exception entry */ +#define CFSR_MSTKERR_MSK (0x1 << 4 ) +#define CFSR_MSTKERR (0x1 << 4 ) +#define CFSR_MSTKERR_DIS (0x0 << 4 ) /* DIS */ +#define CFSR_MSTKERR_EN (0x1 << 4 ) /* EN */ + +/* CFSR[MUNSTKERR] - A derived MemManage fault has occurred on exception return */ +#define CFSR_MUNSTKERR_MSK (0x1 << 3 ) +#define CFSR_MUNSTKERR (0x1 << 3 ) +#define CFSR_MUNSTKERR_DIS (0x0 << 3 ) /* DIS */ +#define CFSR_MUNSTKERR_EN (0x1 << 3 ) /* EN */ + +/* CFSR[DACCVIOL] - Data access violation. The MMAR is set to the data address which the load store tried to access. */ +#define CFSR_DACCVIOL_MSK (0x1 << 1 ) +#define CFSR_DACCVIOL (0x1 << 1 ) +#define CFSR_DACCVIOL_DIS (0x0 << 1 ) /* DIS */ +#define CFSR_DACCVIOL_EN (0x1 << 1 ) /* EN */ + +/* CFSR[IACCVIOL] - violation on an instruction fetch. */ +#define CFSR_IACCVIOL_MSK (0x1 << 0 ) +#define CFSR_IACCVIOL (0x1 << 0 ) +#define CFSR_IACCVIOL_DIS (0x0 << 0 ) /* DIS */ +#define CFSR_IACCVIOL_EN (0x1 << 0 ) /* EN */ + +/* Reset Value for HFSR*/ +#define HFSR_RVAL 0x0 + +/* HFSR[DEBUGEVT] - Debug event, and the Debug Fault Status Register has been updated. */ +#define HFSR_DEBUGEVT_MSK (0x1 << 31 ) +#define HFSR_DEBUGEVT (0x1 << 31 ) +#define HFSR_DEBUGEVT_DIS (0x0 << 31 ) /* DIS */ +#define HFSR_DEBUGEVT_EN (0x1 << 31 ) /* EN */ + +/* HFSR[FORCED] - Configurable fault cannot be activated due to priority or it was disabled. Priority escalated to a HardFault. */ +#define HFSR_FORCED_MSK (0x1 << 30 ) +#define HFSR_FORCED (0x1 << 30 ) +#define HFSR_FORCED_DIS (0x0 << 30 ) /* DIS */ +#define HFSR_FORCED_EN (0x1 << 30 ) /* EN */ + +/* HFSR[VECTTBL] - Fault was due to vector table read on exception processing */ +#define HFSR_VECTTBL_MSK (0x1 << 1 ) +#define HFSR_VECTTBL (0x1 << 1 ) +#define HFSR_VECTTBL_DIS (0x0 << 1 ) /* DIS */ +#define HFSR_VECTTBL_EN (0x1 << 1 ) /* EN */ + +/* Reset Value for MMFAR*/ +#define MMFAR_RVAL 0x0 + +/* MMFAR[ADDRESS] - Data address MPU faulted. */ +#define MMFAR_ADDRESS_MSK (0xFFFFFFFF << 0 ) + +/* Reset Value for BFAR*/ +#define BFAR_RVAL 0x0 + +/* BFAR[ADDRESS] - Updated on precise data access faults */ +#define BFAR_ADDRESS_MSK (0xFFFFFFFF << 0 ) + +/* Reset Value for STIR*/ +#define STIR_RVAL 0x0 + +/* STIR[INTID] - The value written in this field is the interrupt to be triggered. */ +#define STIR_INTID_MSK (0x3FF << 0 ) +// ------------------------------------------------------------------------------------------------ +// ----- PWRCTL ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Power Management Unit (pADI_PWRCTL) + */ + +#if (__NO_MMR_STRUCTS__==0) +typedef struct { /*!< pADI_PWRCTL Structure */ + __IO uint16_t PWRMOD; /*!< Power Modes Register */ + __I uint16_t RESERVED0; + __IO uint16_t PWRKEY; /*!< Key Protection for the PWRMOD Register. */ + __I uint16_t RESERVED1; + __IO uint8_t PSMCON; /*!< Power Supply Monitor Control and Status */ + __I uint8_t RESERVED2[111]; + __IO uint8_t SRAMRET; /*!< SRAM Retention Register */ + __I uint8_t RESERVED3[3]; + __IO uint8_t SHUTDOWN; /*!< Shutdown Acknowledge Register */ +} ADI_PWRCTL_TypeDef; +#else // (__NO_MMR_STRUCTS__==0) +#define PWRMOD (*(volatile unsigned short int *) 0x40002400) +#define PWRKEY (*(volatile unsigned short int *) 0x40002404) +#define PSMCON (*(volatile unsigned char *) 0x40002408) +#define SRAMRET (*(volatile unsigned char *) 0x40002478) +#define SHUTDOWN (*(volatile unsigned char *) 0x4000247C) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for PWRMOD*/ +#define PWRMOD_RVAL 0x100 + +/* PWRMOD[WICENACK] - WIC Acknowledge, for cortex M3 deep sleep mode */ +#define PWRMOD_WICENACK_BBA (*(volatile unsigned long *) 0x4204800C) +#define PWRMOD_WICENACK_MSK (0x1 << 3 ) +#define PWRMOD_WICENACK (0x1 << 3 ) +#define PWRMOD_WICENACK_CLR (0x0 << 3 ) /* CLR. Cleared automatically by hardware when the cortex M3 processor is not ready to enter deep sleep mode including if serial wire activity is detected. */ +#define PWRMOD_WICENACK_SET (0x1 << 3 ) /* SET. Set automatically by the cortex M3 processor when ready to enter sleep deep mode. */ + +/* PWRMOD[MOD] - Low Power Mode */ +#define PWRMOD_MOD_MSK (0x7 << 0 ) +#define PWRMOD_MOD_FLEXI (0x0 << 0 ) /* FLEXI. */ +#define PWRMOD_MOD_HIBERNATE (0x5 << 0 ) /* HIBERNATE. */ +#define PWRMOD_MOD_SHUTDOWN (0x6 << 0 ) /* SHUTDOWN. */ + +/* Reset Value for PWRKEY*/ +#define PWRKEY_RVAL 0x0 + +/* PWRKEY[VALUE] - */ +#define PWRKEY_VALUE_MSK (0xFFFF << 0 ) +#define PWRKEY_VALUE_KEY1 (0x4859 << 0 ) /* KEY1 */ +#define PWRKEY_VALUE_KEY2 (0xF27B << 0 ) /* KEY2 */ + +/* Reset Value for PSMCON*/ +#define PSMCON_RVAL 0x3 + +/* PSMCON[PD] - Power Supply Monitor power down bit. */ +#define PSMCON_PD_BBA (*(volatile unsigned long *) 0x42048104) +#define PSMCON_PD_MSK (0x1 << 1 ) +#define PSMCON_PD (0x1 << 1 ) +#define PSMCON_PD_DIS (0x0 << 1 ) /* DIS. Power up the PSM. */ +#define PSMCON_PD_EN (0x1 << 1 ) /* EN. Power down the PSM. */ + +/* Reset Value for SRAMRET*/ +#define SRAMRET_RVAL 0x1 + +/* SRAMRET[RETAIN] - SRAM retention enable bit */ +#define SRAMRET_RETAIN_BBA (*(volatile unsigned long *) 0x42048F00) +#define SRAMRET_RETAIN_MSK (0x1 << 0 ) +#define SRAMRET_RETAIN (0x1 << 0 ) +#define SRAMRET_RETAIN_DIS (0x0 << 0 ) /* DIS. To retain contents of the bottom 8 kB of SRAM only */ +#define SRAMRET_RETAIN_EN (0x1 << 0 ) /* EN. To retain contents of the entire 16 kB of SRAM */ + +/* Reset Value for SHUTDOWN*/ +#define SHUTDOWN_RVAL 0x0 + +/* SHUTDOWN[EINT8] - External Interrupt 8 detected during SHUTDOWN mode */ +#define SHUTDOWN_EINT8_BBA (*(volatile unsigned long *) 0x42048F88) +#define SHUTDOWN_EINT8_MSK (0x1 << 2 ) +#define SHUTDOWN_EINT8 (0x1 << 2 ) +#define SHUTDOWN_EINT8_CLR (0x0 << 2 ) /* CLR. Cleared automatically by hardware when clearing IRQ8 in EICLR. */ +#define SHUTDOWN_EINT8_SET (0x1 << 2 ) /* SET Indicates the interrupt was detected */ + +/* SHUTDOWN[EINT1] - External Interrupt 1 detected during SHUTDOWN mode */ +#define SHUTDOWN_EINT1_BBA (*(volatile unsigned long *) 0x42048F84) +#define SHUTDOWN_EINT1_MSK (0x1 << 1 ) +#define SHUTDOWN_EINT1 (0x1 << 1 ) +#define SHUTDOWN_EINT1_CLR (0x0 << 1 ) /* CLR. Cleared automatically by hardware when clearing IRQ1 in EICLR. */ +#define SHUTDOWN_EINT1_SET (0x1 << 1 ) /* SET Indicates the interrupt was detected */ + +/* SHUTDOWN[EINT0] - External Interrupt 0 detected during SHUTDOWN mode */ +#define SHUTDOWN_EINT0_BBA (*(volatile unsigned long *) 0x42048F80) +#define SHUTDOWN_EINT0_MSK (0x1 << 0 ) +#define SHUTDOWN_EINT0 (0x1 << 0 ) +#define SHUTDOWN_EINT0_CLR (0x0 << 0 ) /* CLR. Cleared automatically by hardware when clearing IRQ0 in EICLR. */ +#define SHUTDOWN_EINT0_SET (0x1 << 0 ) /* SET Indicates the interrupt was detected */ +// ------------------------------------------------------------------------------------------------ +// ----- PWM ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Pulse Width Modulation (pADI_PWM) + */ + +#if (__NO_MMR_STRUCTS__==0) +typedef struct { /*!< pADI_PWM Structure */ + __IO uint16_t PWMCON0; /*!< PWM Control Register */ + __I uint16_t RESERVED0; + __IO uint8_t PWMCON1; /*!< Trip Control Register */ + __I uint8_t RESERVED1[3]; + __IO uint16_t PWMCLRI; /*!< PWM Interrupt Clear */ + __I uint16_t RESERVED2[3]; + __IO uint16_t PWM0COM0; /*!< Compare Register 0 for Pair 0 */ + __I uint16_t RESERVED3; + __IO uint16_t PWM0COM1; /*!< Compare Register 1 for Pair 0 */ + __I uint16_t RESERVED4; + __IO uint16_t PWM0COM2; /*!< Compare Register 2 for Pair 0 */ + __I uint16_t RESERVED5; + __IO uint16_t PWM0LEN; /*!< Period Value Register for Pair 0 */ + __I uint16_t RESERVED6; + __IO uint16_t PWM1COM0; /*!< Compare Register 0 for Pair 1 */ + __I uint16_t RESERVED7; + __IO uint16_t PWM1COM1; /*!< Compare Register 1 for Pair 1 */ + __I uint16_t RESERVED8; + __IO uint16_t PWM1COM2; /*!< Compare Register 2 for Pair 1 */ + __I uint16_t RESERVED9; + __IO uint16_t PWM1LEN; /*!< Period Value Register for Pair 1 */ + __I uint16_t RESERVED10; + __IO uint16_t PWM2COM0; /*!< Compare Register 0 for Pair 2 */ + __I uint16_t RESERVED11; + __IO uint16_t PWM2COM1; /*!< Compare Register 1 for Pair 2 */ + __I uint16_t RESERVED12; + __IO uint16_t PWM2COM2; /*!< Compare Register 2 for Pair 2 */ + __I uint16_t RESERVED13; + __IO uint16_t PWM2LEN; /*!< Period Value Register for Pair 2 */ + __I uint16_t RESERVED14; + __IO uint16_t PWM3COM0; /*!< Compare Register 0 for Pair 3 */ + __I uint16_t RESERVED15; + __IO uint16_t PWM3COM1; /*!< Compare Register 1 for Pair 3 */ + __I uint16_t RESERVED16; + __IO uint16_t PWM3COM2; /*!< Compare Register 2 for Pair 3 */ + __I uint16_t RESERVED17; + __IO uint16_t PWM3LEN; /*!< Period Value Register for Pair 3 */ +} ADI_PWM_TypeDef; +#else // (__NO_MMR_STRUCTS__==0) +#define PWMCON0 (*(volatile unsigned short int *) 0x40001000) +#define PWMCON1 (*(volatile unsigned char *) 0x40001004) +#define PWMCLRI (*(volatile unsigned short int *) 0x40001008) +#define PWM0COM0 (*(volatile unsigned short int *) 0x40001010) +#define PWM0COM1 (*(volatile unsigned short int *) 0x40001014) +#define PWM0COM2 (*(volatile unsigned short int *) 0x40001018) +#define PWM0LEN (*(volatile unsigned short int *) 0x4000101C) +#define PWM1COM0 (*(volatile unsigned short int *) 0x40001020) +#define PWM1COM1 (*(volatile unsigned short int *) 0x40001024) +#define PWM1COM2 (*(volatile unsigned short int *) 0x40001028) +#define PWM1LEN (*(volatile unsigned short int *) 0x4000102C) +#define PWM2COM0 (*(volatile unsigned short int *) 0x40001030) +#define PWM2COM1 (*(volatile unsigned short int *) 0x40001034) +#define PWM2COM2 (*(volatile unsigned short int *) 0x40001038) +#define PWM2LEN (*(volatile unsigned short int *) 0x4000103C) +#define PWM3COM0 (*(volatile unsigned short int *) 0x40001040) +#define PWM3COM1 (*(volatile unsigned short int *) 0x40001044) +#define PWM3COM2 (*(volatile unsigned short int *) 0x40001048) +#define PWM3LEN (*(volatile unsigned short int *) 0x4000104C) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for PWMCON0*/ +#define PWMCON0_RVAL 0x12 + +/* PWMCON0[SYNC] - PWM Synchronization. */ +#define PWMCON0_SYNC_BBA (*(volatile unsigned long *) 0x4202003C) +#define PWMCON0_SYNC_MSK (0x1 << 15 ) +#define PWMCON0_SYNC (0x1 << 15 ) +#define PWMCON0_SYNC_DIS (0x0 << 15 ) /* DIS. Ignore transitions on the PWMSYNC pin. */ +#define PWMCON0_SYNC_EN (0x1 << 15 ) /* EN. All PWM counters are reset on the next clock edge after the detection of a falling edge on the PWMSYNC pin. */ + +/* PWMCON0[PWM7INV] - Inversion of PWM output. Available in standard mode only. */ +#define PWMCON0_PWM7INV_BBA (*(volatile unsigned long *) 0x42020038) +#define PWMCON0_PWM7INV_MSK (0x1 << 14 ) +#define PWMCON0_PWM7INV (0x1 << 14 ) +#define PWMCON0_PWM7INV_DIS (0x0 << 14 ) /* DIS. PWM7 is normal. */ +#define PWMCON0_PWM7INV_EN (0x1 << 14 ) /* EN. Invert PWM7. */ + +/* PWMCON0[PWM5INV] - Inversion of PWM output. Available in standard mode only. */ +#define PWMCON0_PWM5INV_BBA (*(volatile unsigned long *) 0x42020034) +#define PWMCON0_PWM5INV_MSK (0x1 << 13 ) +#define PWMCON0_PWM5INV (0x1 << 13 ) +#define PWMCON0_PWM5INV_DIS (0x0 << 13 ) /* DIS. PWM5 is normal. */ +#define PWMCON0_PWM5INV_EN (0x1 << 13 ) /* EN. Invert PWM5. */ + +/* PWMCON0[PWM3INV] - Inversion of PWM output. Available in standard mode only. */ +#define PWMCON0_PWM3INV_BBA (*(volatile unsigned long *) 0x42020030) +#define PWMCON0_PWM3INV_MSK (0x1 << 12 ) +#define PWMCON0_PWM3INV (0x1 << 12 ) +#define PWMCON0_PWM3INV_DIS (0x0 << 12 ) /* DIS. PWM3 is normal. */ +#define PWMCON0_PWM3INV_EN (0x1 << 12 ) /* EN. Invert PWM3. */ + +/* PWMCON0[PWM1INV] - Inversion of PWM output. Available in standard mode only. */ +#define PWMCON0_PWM1INV_BBA (*(volatile unsigned long *) 0x4202002C) +#define PWMCON0_PWM1INV_MSK (0x1 << 11 ) +#define PWMCON0_PWM1INV (0x1 << 11 ) +#define PWMCON0_PWM1INV_DIS (0x0 << 11 ) /* DIS. PWM1 is normal. */ +#define PWMCON0_PWM1INV_EN (0x1 << 11 ) /* EN. Invert PWM1. */ + +/* PWMCON0[PWMIEN] - Enable PWM interrupts. */ +#define PWMCON0_PWMIEN_BBA (*(volatile unsigned long *) 0x42020028) +#define PWMCON0_PWMIEN_MSK (0x1 << 10 ) +#define PWMCON0_PWMIEN (0x1 << 10 ) +#define PWMCON0_PWMIEN_DIS (0x0 << 10 ) /* DIS. Disable PWM interrupts. */ +#define PWMCON0_PWMIEN_EN (0x1 << 10 ) /* EN. Enable PWM interrupts. */ + +/* PWMCON0[ENA] - Enable PWM outputs. Available in H-Bridge mode only. */ +#define PWMCON0_ENA_BBA (*(volatile unsigned long *) 0x42020024) +#define PWMCON0_ENA_MSK (0x1 << 9 ) +#define PWMCON0_ENA (0x1 << 9 ) +#define PWMCON0_ENA_DIS (0x0 << 9 ) /* DIS. Disable PWM outputs. */ +#define PWMCON0_ENA_EN (0x1 << 9 ) /* EN. Enable PWM outputs. */ + +/* PWMCON0[PWMCP] - PWM Clock Prescaler. Sets UCLK divider. */ +#define PWMCON0_PWMCP_MSK (0x7 << 6 ) +#define PWMCON0_PWMCP_UCLKDIV2 (0x0 << 6 ) /* UCLK/2. */ +#define PWMCON0_PWMCP_UCLKDIV4 (0x1 << 6 ) /* UCLK/4. */ +#define PWMCON0_PWMCP_UCLKDIV8 (0x2 << 6 ) /* UCLK/8. */ +#define PWMCON0_PWMCP_UCLKDIV16 (0x3 << 6 ) /* UCLK/16. */ +#define PWMCON0_PWMCP_UCLKDIV32 (0x4 << 6 ) /* UCLK/32. */ +#define PWMCON0_PWMCP_UCLKDIV64 (0x5 << 6 ) /* UCLK/64. */ +#define PWMCON0_PWMCP_UCLKDIV128 (0x6 << 6 ) /* UCLK/128. */ +#define PWMCON0_PWMCP_UCLKDIV256 (0x7 << 6 ) /* UCLK/256. */ + +/* PWMCON0[POINV] - Invert all PWM outputs. Available in H-Bridge mode only. */ +#define PWMCON0_POINV_BBA (*(volatile unsigned long *) 0x42020014) +#define PWMCON0_POINV_MSK (0x1 << 5 ) +#define PWMCON0_POINV (0x1 << 5 ) +#define PWMCON0_POINV_DIS (0x0 << 5 ) /* DIS. PWM outputs as normal. */ +#define PWMCON0_POINV_EN (0x1 << 5 ) /* EN. Invert all PWM outputs. */ + +/* PWMCON0[HOFF] - High Side Off. Available in H-Bridge mode only. */ +#define PWMCON0_HOFF_BBA (*(volatile unsigned long *) 0x42020010) +#define PWMCON0_HOFF_MSK (0x1 << 4 ) +#define PWMCON0_HOFF (0x1 << 4 ) +#define PWMCON0_HOFF_DIS (0x0 << 4 ) /* DIS. PWM outputs as normal. */ +#define PWMCON0_HOFF_EN (0x1 << 4 ) /* EN. Force PWM0 and PWM2 outputs high and PWM1 and PWM3 low. */ + +/* PWMCON0[LCOMP] - Load Compare Registers. */ +#define PWMCON0_LCOMP_BBA (*(volatile unsigned long *) 0x4202000C) +#define PWMCON0_LCOMP_MSK (0x1 << 3 ) +#define PWMCON0_LCOMP (0x1 << 3 ) +#define PWMCON0_LCOMP_DIS (0x0 << 3 ) /* DIS. Use the values previously stored in the internal compare registers. */ +#define PWMCON0_LCOMP_EN (0x1 << 3 ) /* EN. Load the internal compare registers with the values in PWMxCOMx on the next transition of the PWM timer from 0x00 to 0x01. */ + +/* PWMCON0[DIR] - Direction Control. Available in H-Bridge mode only. */ +#define PWMCON0_DIR_BBA (*(volatile unsigned long *) 0x42020008) +#define PWMCON0_DIR_MSK (0x1 << 2 ) +#define PWMCON0_DIR (0x1 << 2 ) +#define PWMCON0_DIR_DIS (0x0 << 2 ) /* DIS. Enable PWM2 and PWM3 as the output signals while PWM0 and PWM1 are held low. */ +#define PWMCON0_DIR_EN (0x1 << 2 ) /* EN. Enable PWM0 and PWM1 as the output signals while PWM2 and PWM3 are held low. */ + +/* PWMCON0[HMODE] - Enable H-Bridge Mode. */ +#define PWMCON0_HMODE_BBA (*(volatile unsigned long *) 0x42020004) +#define PWMCON0_HMODE_MSK (0x1 << 1 ) +#define PWMCON0_HMODE (0x1 << 1 ) +#define PWMCON0_HMODE_DIS (0x0 << 1 ) /* DIS. The PWM operates in standard mode. */ +#define PWMCON0_HMODE_EN (0x1 << 1 ) /* EN. The PWM is configured in H-Bridge mode. */ + +/* PWMCON0[PWMEN] - Enable all PWM outputs. */ +#define PWMCON0_PWMEN_BBA (*(volatile unsigned long *) 0x42020000) +#define PWMCON0_PWMEN_MSK (0x1 << 0 ) +#define PWMCON0_PWMEN (0x1 << 0 ) +#define PWMCON0_PWMEN_DIS (0x0 << 0 ) /* DIS. Disables all PWM outputs. */ +#define PWMCON0_PWMEN_EN (0x1 << 0 ) /* EN. Enables all PWM outputs. */ + +/* Reset Value for PWMCON1*/ +#define PWMCON1_RVAL 0x0 + +/* PWMCON1[TRIPEN] - Enable PWM trip functionality. */ +#define PWMCON1_TRIPEN_BBA (*(volatile unsigned long *) 0x42020098) +#define PWMCON1_TRIPEN_MSK (0x1 << 6 ) +#define PWMCON1_TRIPEN (0x1 << 6 ) +#define PWMCON1_TRIPEN_DIS (0x0 << 6 ) /* DIS. Disable PWM trip functionality. */ +#define PWMCON1_TRIPEN_EN (0x1 << 6 ) /* EN. Enable PWM trip functionality. */ + +/* Reset Value for PWMCLRI*/ +#define PWMCLRI_RVAL 0x0 + +/* PWMCLRI[TRIP] - Clear the latched trip interrupt. This bit always reads 0. */ +#define PWMCLRI_TRIP_BBA (*(volatile unsigned long *) 0x42020110) +#define PWMCLRI_TRIP_MSK (0x1 << 4 ) +#define PWMCLRI_TRIP (0x1 << 4 ) +#define PWMCLRI_TRIP_EN (0x1 << 4 ) /* EN. Clear the latched PWMTRIP interrupt. */ + +/* PWMCLRI[IRQPWM3] - Clear the latched PWM3 interrupt. This bit always reads 0. */ +#define PWMCLRI_IRQPWM3_BBA (*(volatile unsigned long *) 0x4202010C) +#define PWMCLRI_IRQPWM3_MSK (0x1 << 3 ) +#define PWMCLRI_IRQPWM3 (0x1 << 3 ) +#define PWMCLRI_IRQPWM3_EN (0x1 << 3 ) /* EN. Clear the latched IRQPWM3 interrupt. */ + +/* PWMCLRI[IRQPWM2] - Clear the latched PWM2 interrupt. This bit always reads 0. */ +#define PWMCLRI_IRQPWM2_BBA (*(volatile unsigned long *) 0x42020108) +#define PWMCLRI_IRQPWM2_MSK (0x1 << 2 ) +#define PWMCLRI_IRQPWM2 (0x1 << 2 ) +#define PWMCLRI_IRQPWM2_EN (0x1 << 2 ) /* EN. Clear the latched IRQPWM2 interrupt. */ + +/* PWMCLRI[IRQPWM1] - Clear the latched PWM1 interrupt. This bit always reads 0. */ +#define PWMCLRI_IRQPWM1_BBA (*(volatile unsigned long *) 0x42020104) +#define PWMCLRI_IRQPWM1_MSK (0x1 << 1 ) +#define PWMCLRI_IRQPWM1 (0x1 << 1 ) +#define PWMCLRI_IRQPWM1_EN (0x1 << 1 ) /* EN. Clear the latched IRQPWM1 interrupt. */ + +/* PWMCLRI[IRQPWM0] - Clear the latched PWM0 interrupt. This bit always reads 0. */ +#define PWMCLRI_IRQPWM0_BBA (*(volatile unsigned long *) 0x42020100) +#define PWMCLRI_IRQPWM0_MSK (0x1 << 0 ) +#define PWMCLRI_IRQPWM0 (0x1 << 0 ) +#define PWMCLRI_IRQPWM0_EN (0x1 << 0 ) /* EN. Clear the latched IRQPWM0 interrupt. */ + +/* Reset Value for PWM0COM0*/ +#define PWM0COM0_RVAL 0x0 + +/* PWM0COM0[VALUE] - */ +#define PWM0COM0_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for PWM0COM1*/ +#define PWM0COM1_RVAL 0x0 + +/* PWM0COM1[VALUE] - */ +#define PWM0COM1_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for PWM0COM2*/ +#define PWM0COM2_RVAL 0x0 + +/* PWM0COM2[VALUE] - */ +#define PWM0COM2_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for PWM0LEN*/ +#define PWM0LEN_RVAL 0x0 + +/* PWM0LEN[VALUE] - */ +#define PWM0LEN_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for PWM1COM0*/ +#define PWM1COM0_RVAL 0x0 + +/* PWM1COM0[VALUE] - */ +#define PWM1COM0_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for PWM1COM1*/ +#define PWM1COM1_RVAL 0x0 + +/* PWM1COM1[VALUE] - */ +#define PWM1COM1_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for PWM1COM2*/ +#define PWM1COM2_RVAL 0x0 + +/* PWM1COM2[VALUE] - */ +#define PWM1COM2_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for PWM1LEN*/ +#define PWM1LEN_RVAL 0x0 + +/* PWM1LEN[VALUE] - */ +#define PWM1LEN_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for PWM2COM0*/ +#define PWM2COM0_RVAL 0x0 + +/* PWM2COM0[VALUE] - */ +#define PWM2COM0_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for PWM2COM1*/ +#define PWM2COM1_RVAL 0x0 + +/* PWM2COM1[VALUE] - */ +#define PWM2COM1_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for PWM2COM2*/ +#define PWM2COM2_RVAL 0x0 + +/* PWM2COM2[VALUE] - */ +#define PWM2COM2_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for PWM2LEN*/ +#define PWM2LEN_RVAL 0x0 + +/* PWM2LEN[VALUE] - */ +#define PWM2LEN_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for PWM3COM0*/ +#define PWM3COM0_RVAL 0x0 + +/* PWM3COM0[VALUE] - */ +#define PWM3COM0_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for PWM3COM1*/ +#define PWM3COM1_RVAL 0x0 + +/* PWM3COM1[VALUE] - */ +#define PWM3COM1_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for PWM3COM2*/ +#define PWM3COM2_RVAL 0x0 + +/* PWM3COM2[VALUE] - */ +#define PWM3COM2_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for PWM3LEN*/ +#define PWM3LEN_RVAL 0x0 + +/* PWM3LEN[VALUE] - */ +#define PWM3LEN_VALUE_MSK (0xFFFF << 0 ) +// ------------------------------------------------------------------------------------------------ +// ----- RESET ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Reset (pADI_RESET) + */ + +#if (__NO_MMR_STRUCTS__==0) +typedef struct { /*!< pADI_RESET Structure */ + + union { + __IO uint8_t RSTSTA; /*!< Reset Status */ + __IO uint8_t RSTCLR; /*!< Reset Status Clear */ + } ; +} ADI_RESET_TypeDef; +#else // (__NO_MMR_STRUCTS__==0) +#define RSTSTA (*(volatile unsigned char *) 0x40002440) +#define RSTCLR (*(volatile unsigned char *) 0x40002440) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for RSTSTA*/ +#define RSTSTA_RVAL 0x3 + +/* RSTSTA[SWRST] - Software reset status bit */ +#define RSTSTA_SWRST_BBA (*(volatile unsigned long *) 0x42048810) +#define RSTSTA_SWRST_MSK (0x1 << 4 ) +#define RSTSTA_SWRST (0x1 << 4 ) +#define RSTSTA_SWRST_CLR (0x0 << 4 ) /* CLR. Indicates that no software reset has occurred. */ +#define RSTSTA_SWRST_SET (0x1 << 4 ) /* SET. Indicates that a software reset has occurred. */ + +/* RSTSTA[WDRST] - Watchdog reset status bit */ +#define RSTSTA_WDRST_BBA (*(volatile unsigned long *) 0x4204880C) +#define RSTSTA_WDRST_MSK (0x1 << 3 ) +#define RSTSTA_WDRST (0x1 << 3 ) +#define RSTSTA_WDRST_CLR (0x0 << 3 ) /* CLR. Indicates that no watchdog reset has occurred. */ +#define RSTSTA_WDRST_SET (0x1 << 3 ) /* SET. Indicates that a Watchdog Reset has occurred. */ + +/* RSTSTA[EXTRST] - External reset status bit */ +#define RSTSTA_EXTRST_BBA (*(volatile unsigned long *) 0x42048808) +#define RSTSTA_EXTRST_MSK (0x1 << 2 ) +#define RSTSTA_EXTRST (0x1 << 2 ) +#define RSTSTA_EXTRST_CLR (0x0 << 2 ) /* CLR. Indicates that no external reset has occurred. */ +#define RSTSTA_EXTRST_SET (0x1 << 2 ) /* SET. Indicates an external reset has occurred. */ + +/* RSTSTA[PORHV] - Power-on reset status bit HV */ +#define RSTSTA_PORHV_BBA (*(volatile unsigned long *) 0x42048804) +#define RSTSTA_PORHV_MSK (0x1 << 1 ) +#define RSTSTA_PORHV (0x1 << 1 ) +#define RSTSTA_PORHV_CLR (0x0 << 1 ) /* CLR. Indicates a POR or wake up from SHUTDOWN has not occurred. */ +#define RSTSTA_PORHV_SET (0x1 << 1 ) /* SET. This bit indicates that the AVDD supply has dropped below the POR trip point, causing a Power On Reset. It is also set when waking up from SHUTDOWN mode. */ + +/* RSTSTA[PORLV] - Power-on reset status bit LV */ +#define RSTSTA_PORLV_BBA (*(volatile unsigned long *) 0x42048800) +#define RSTSTA_PORLV_MSK (0x1 << 0 ) +#define RSTSTA_PORLV (0x1 << 0 ) +#define RSTSTA_PORLV_CLR (0x0 << 0 ) /* CLR. Indicates a POR or wake up from SHUTDOWN has not occurred. */ +#define RSTSTA_PORLV_SET (0x1 << 0 ) /* SET. This bit indicates that the AVDD supply has dropped below the POR trip point, causing a Power On Reset. It is also set when waking up from SHUTDOWN mode. */ + +/* Reset Value for RSTCLR*/ +#define RSTCLR_RVAL 0x3 + +/* RSTCLR[SWRST] - Software reset clear status bit */ +#define RSTCLR_SWRST_BBA (*(volatile unsigned long *) 0x42048810) +#define RSTCLR_SWRST_MSK (0x1 << 4 ) +#define RSTCLR_SWRST (0x1 << 4 ) +#define RSTCLR_SWRST_DIS (0x0 << 4 ) /* DIS. Has no effect. */ +#define RSTCLR_SWRST_EN (0x1 << 4 ) /* EN. Clears the SWRST status bit in RSTSTA. */ + +/* RSTCLR[WDRST] - Watchdog reset clear status bit */ +#define RSTCLR_WDRST_BBA (*(volatile unsigned long *) 0x4204880C) +#define RSTCLR_WDRST_MSK (0x1 << 3 ) +#define RSTCLR_WDRST (0x1 << 3 ) +#define RSTCLR_WDRST_DIS (0x0 << 3 ) /* DIS. Has no effect. */ +#define RSTCLR_WDRST_EN (0x1 << 3 ) /* EN. Clears the WDRST status bit in RSTSTA. */ + +/* RSTCLR[EXTRST] - External reset clear status bit */ +#define RSTCLR_EXTRST_BBA (*(volatile unsigned long *) 0x42048808) +#define RSTCLR_EXTRST_MSK (0x1 << 2 ) +#define RSTCLR_EXTRST (0x1 << 2 ) +#define RSTCLR_EXTRST_DIS (0x0 << 2 ) /* DIS. Has no effect. */ +#define RSTCLR_EXTRST_EN (0x1 << 2 ) /* EN. Clears the EXTRST status bit in RSTSTA. */ + +/* RSTCLR[PORHV] - Power on reset clear status bit */ +#define RSTCLR_PORHV_BBA (*(volatile unsigned long *) 0x42048804) +#define RSTCLR_PORHV_MSK (0x1 << 1 ) +#define RSTCLR_PORHV (0x1 << 1 ) +#define RSTCLR_PORHV_DIS (0x0 << 1 ) /* DIS. Has no effect. */ +#define RSTCLR_PORHV_EN (0x1 << 1 ) /* EN. Clears PORLV status bit in RSTSTA. */ + +/* RSTCLR[PORLV] - Power-on reset clear status bit LV */ +#define RSTCLR_PORLV_BBA (*(volatile unsigned long *) 0x42048800) +#define RSTCLR_PORLV_MSK (0x1 << 0 ) +#define RSTCLR_PORLV (0x1 << 0 ) +#define RSTCLR_PORLV_DIS (0x0 << 0 ) /* DIS. Has no effect. */ +#define RSTCLR_PORLV_EN (0x1 << 0 ) /* EN. Clears the PORLV status bit in RSTSTA. */ +// ------------------------------------------------------------------------------------------------ +// ----- SPI0 ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Serial Peripheral Interface (pADI_SPI0) + */ + +#if (__NO_MMR_STRUCTS__==0) +typedef struct { /*!< pADI_SPI0 Structure */ + __IO uint16_t SPISTA; /*!< SPI0 Status Register */ + __I uint16_t RESERVED0; + __IO uint8_t SPIRX; /*!< SPI0 Receive Register */ + __I uint8_t RESERVED1[3]; + __IO uint8_t SPITX; /*!< SPI0 Transmit Register */ + __I uint8_t RESERVED2[3]; + __IO uint16_t SPIDIV; /*!< SPI0 Bit Rate Selection Register */ + __I uint16_t RESERVED3; + __IO uint16_t SPICON; /*!< SPI0 Configuration Register */ + __I uint16_t RESERVED4; + __IO uint16_t SPIDMA; /*!< SPI0 DMA Enable Register */ + __I uint16_t RESERVED5; + __IO uint16_t SPICNT; /*!< SPI0 DMA Master Received Byte Count Register */ +} ADI_SPI_TypeDef; +#else // (__NO_MMR_STRUCTS__==0) +#define SPI0STA (*(volatile unsigned short int *) 0x40004000) +#define SPI0RX (*(volatile unsigned char *) 0x40004004) +#define SPI0TX (*(volatile unsigned char *) 0x40004008) +#define SPI0DIV (*(volatile unsigned short int *) 0x4000400C) +#define SPI0CON (*(volatile unsigned short int *) 0x40004010) +#define SPI0DMA (*(volatile unsigned short int *) 0x40004014) +#define SPI0CNT (*(volatile unsigned short int *) 0x40004018) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for SPI0STA*/ +#define SPI0STA_RVAL 0x0 + +/* SPI0STA[CSERR] - CS error status bit. This bit generates an interrupt when detecting an abrupt CS desassertion before the full byte of data is transmitted completely. */ +#define SPI0STA_CSERR_BBA (*(volatile unsigned long *) 0x42080030) +#define SPI0STA_CSERR_MSK (0x1 << 12 ) +#define SPI0STA_CSERR (0x1 << 12 ) +#define SPI0STA_CSERR_CLR (0x0 << 12 ) /* CLR: Cleared when no CS error is detected. Cleared to 0 on a read of SPI0STA register. */ +#define SPI0STA_CSERR_SET (0x1 << 12 ) /* SET: Set when the CS line is deasserted abruptly. */ + +/* SPI0STA[RXS] - Rx FIFO excess bytes present. */ +#define SPI0STA_RXS_BBA (*(volatile unsigned long *) 0x4208002C) +#define SPI0STA_RXS_MSK (0x1 << 11 ) +#define SPI0STA_RXS (0x1 << 11 ) +#define SPI0STA_RXS_CLR (0x0 << 11 ) /* CLR. When the number of bytes in the FIFO is equal or less than the number in SPI0CON[15:14]. This bit is not cleared on a read of SPI0STA register. */ +#define SPI0STA_RXS_SET (0x1 << 11 ) /* SET. When there are more bytes in the Rx FIFO than configured in MOD (SPI0CON[15:14]). For example if MOD = TX1RX1, RXS is set when there are 2 or more bytes in the Rx FIFO. This bit does not dependent on SPI0CON[6] and does not cause an interrupt. */ + +/* SPI0STA[RXFSTA] - Rx FIFO status bits, indicates how many valid bytes are in the Rx FIFO. */ +#define SPI0STA_RXFSTA_MSK (0x7 << 8 ) +#define SPI0STA_RXFSTA_EMPTY (0x0 << 8 ) /* EMPTY. When Rx FIFO is empty. */ +#define SPI0STA_RXFSTA_ONEBYTE (0x1 << 8 ) /* ONEBYTE. When 1 valid byte is in the FIFO. */ +#define SPI0STA_RXFSTA_TWOBYTES (0x2 << 8 ) /* TWOBYTES. When 2 valid bytes are in the FIFO. */ +#define SPI0STA_RXFSTA_THREEBYTES (0x3 << 8 ) /* THREEBYTES. When 3 valid bytes are in the FIFO. */ +#define SPI0STA_RXFSTA_FOURBYTES (0x4 << 8 ) /* FOURBYTES. When 4 valid bytes are in the FIFO. */ + +/* SPI0STA[RXOF] - Rx FIFO overflow status bit. This bit generates an interrupt. */ +#define SPI0STA_RXOF_BBA (*(volatile unsigned long *) 0x4208001C) +#define SPI0STA_RXOF_MSK (0x1 << 7 ) +#define SPI0STA_RXOF (0x1 << 7 ) +#define SPI0STA_RXOF_CLR (0x0 << 7 ) /* CLR. Cleared to 0 on a read of SPI0STA register. */ +#define SPI0STA_RXOF_SET (0x1 << 7 ) /* SET. Set when the Rx FIFO is already full when new data is loaded to the FIFO. This bit generates an interrupt except when RFLUSH is set. (SPI0CON[12]). */ + +/* SPI0STA[RX] - Rx interrupt status bit. This bit generates an interrupt, except when DMA transfer is enabled. */ +#define SPI0STA_RX_BBA (*(volatile unsigned long *) 0x42080018) +#define SPI0STA_RX_MSK (0x1 << 6 ) +#define SPI0STA_RX (0x1 << 6 ) +#define SPI0STA_RX_CLR (0x0 << 6 ) /* CLR. Cleared to 0 on a read of SPI0STA register. */ +#define SPI0STA_RX_SET (0x1 << 6 ) /* SET. Set when a receive interrupt occurs. This bit is set when TIM (SPI0CON[6]) is cleared and the required number of bytes have been received. */ + +/* SPI0STA[TX] - Tx interrupt status bit. This bit generates an interrupt, except when DMA transfer is enabled. */ +#define SPI0STA_TX_BBA (*(volatile unsigned long *) 0x42080014) +#define SPI0STA_TX_MSK (0x1 << 5 ) +#define SPI0STA_TX (0x1 << 5 ) +#define SPI0STA_TX_CLR (0x0 << 5 ) /* CLR. Cleared to 0 on a read of SPI0STA register. */ +#define SPI0STA_TX_SET (0x1 << 5 ) /* SET. Set when a transmit interrupt occurs. This bit is set when TIM (SPI0CON[6]) set and the required number of bytes have been transmitted. */ + +/* SPI0STA[TXUR] - Tx FIFO Underrun. This bit generates an interrupt. */ +#define SPI0STA_TXUR_BBA (*(volatile unsigned long *) 0x42080010) +#define SPI0STA_TXUR_MSK (0x1 << 4 ) +#define SPI0STA_TXUR (0x1 << 4 ) +#define SPI0STA_TXUR_CLR (0x0 << 4 ) /* CLR. Cleared to 0 on a read of SPI0STA register. */ +#define SPI0STA_TXUR_SET (0x1 << 4 ) /* SET. Set when a transmit is initiated without any valid data in the Tx FIFO. This bit generates an interrupt except when TFLUSH is set in SPI0CON. */ + +/* SPI0STA[TXFSTA] - Tx FIFO status bits, indicates how many valid bytes are in the Tx FIFO. */ +#define SPI0STA_TXFSTA_MSK (0x7 << 1 ) +#define SPI0STA_TXFSTA_EMPTY (0x0 << 1 ) /* EMPTY. Tx FIFO is empty. */ +#define SPI0STA_TXFSTA_ONEBYTE (0x1 << 1 ) /* ONEBYTE. 1 valid byte is in the FIFO. */ +#define SPI0STA_TXFSTA_TWOBYTES (0x2 << 1 ) /* TWOBYTES. 2 valid bytes are in the FIFO. */ +#define SPI0STA_TXFSTA_THREEBYTES (0x3 << 1 ) /* THREEBYTES. 3 valid bytes are in the FIFO. */ +#define SPI0STA_TXFSTA_FOURBYTES (0x4 << 1 ) /* FOURBYTES . 4 valid bytes are in the FIFO. */ + +/* SPI0STA[IRQ] - Interrupt status bit. */ +#define SPI0STA_IRQ_BBA (*(volatile unsigned long *) 0x42080000) +#define SPI0STA_IRQ_MSK (0x1 << 0 ) +#define SPI0STA_IRQ (0x1 << 0 ) +#define SPI0STA_IRQ_CLR (0x0 << 0 ) /* CLR. Cleared to 0 on a read of SPI0STA register. */ +#define SPI0STA_IRQ_SET (0x1 << 0 ) /* SET. Set to 1 when an SPI0 based interrupt occurs. */ + +/* Reset Value for SPI0RX*/ +#define SPI0RX_RVAL 0x0 + +/* SPI0RX[VALUE] - 8-bit receive register. A read of the RX FIFO returns the next byte to be read from the FIFO. A read of the FIFO when it is empty returns zero. */ +#define SPI0RX_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for SPI0TX*/ +#define SPI0TX_RVAL 0x0 + +/* SPI0TX[VALUE] - 8-bit transmit register. A write to the Tx FIFO address space writes data to the next available location in the Tx FIFO. If the FIFO is full, the oldest byte of data in the FIFO is overwritten. A read from this address location return zero. */ +#define SPI0TX_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for SPI0DIV*/ +#define SPI0DIV_RVAL 0x0 + +/* SPI0DIV[BCRST] - Configures the behavior of SPI communication after an abrupt deassertion of CS. This bit should be set in slave and master mode. */ +#define SPI0DIV_BCRST_BBA (*(volatile unsigned long *) 0x4208019C) +#define SPI0DIV_BCRST_MSK (0x1 << 7 ) +#define SPI0DIV_BCRST (0x1 << 7 ) +#define SPI0DIV_BCRST_DIS (0x0 << 7 ) /* DIS. Resumes communication from where it stopped when the CS is deasserted. The rest of the bits are then received/ transmitted when CS returns low. User code should ignore the CSERR interrupt. */ +#define SPI0DIV_BCRST_EN (0x1 << 7 ) /* EN. Enabled for a clean restart of SPI transfer after a CSERR condition. User code must also clear the SPI enable bit in SPI0CON during the CSERR interrupt. */ + +/* SPI0DIV[DIV] - Factor used to divide UCLK in the generation of the master mode serial clock. */ +#define SPI0DIV_DIV_MSK (0x3F << 0 ) + +/* Reset Value for SPI0CON*/ +#define SPI0CON_RVAL 0x0 + +/* SPI0CON[MOD] - IRQ mode bits. When TIM is set these bits configure when the Tx/Rx interrupts occur in a transfer. For a DMA Rx transfer, these bits should be 00. */ +#define SPI0CON_MOD_MSK (0x3 << 14 ) +#define SPI0CON_MOD_TX1RX1 (0x0 << 14 ) /* TX1RX1. Tx/Rx interrupt occurs when 1 byte has been transmitted/received from/into the FIFO. */ +#define SPI0CON_MOD_TX2RX2 (0x1 << 14 ) /* TX2RX2. Tx/Rx interrupt occurs when 2 bytes have been transmitted/received from/into the FIFO. */ +#define SPI0CON_MOD_TX3RX3 (0x2 << 14 ) /* TX3RX3. Tx/Rx interrupt occurs when 3 bytes have been transmitted/received from/into the FIFO. */ +#define SPI0CON_MOD_TX4RX4 (0x3 << 14 ) /* TX4RX4. Tx/Rx interrupt occurs when 4 bytes have been transmitted/received from/into the FIFO. */ + +/* SPI0CON[TFLUSH] - Tx FIFO flush enable bit. */ +#define SPI0CON_TFLUSH_BBA (*(volatile unsigned long *) 0x42080234) +#define SPI0CON_TFLUSH_MSK (0x1 << 13 ) +#define SPI0CON_TFLUSH (0x1 << 13 ) +#define SPI0CON_TFLUSH_DIS (0x0 << 13 ) /* DIS. Disable Tx FIFO flushing. */ +#define SPI0CON_TFLUSH_EN (0x1 << 13 ) /* EN. Flush the Tx FIFO. This bit does not clear itself and should be toggled if a single flush is required. If this bit is left high, then either the last transmitted value or 0x00 is transmitted depending on the ZEN bit (SPI0CON[7]). Any writes to the Tx FIFO are ignored while this bit is set. */ + +/* SPI0CON[RFLUSH] - Rx FIFO flush enable bit. */ +#define SPI0CON_RFLUSH_BBA (*(volatile unsigned long *) 0x42080230) +#define SPI0CON_RFLUSH_MSK (0x1 << 12 ) +#define SPI0CON_RFLUSH (0x1 << 12 ) +#define SPI0CON_RFLUSH_DIS (0x0 << 12 ) /* DIS. Disable Rx FIFO flushing. */ +#define SPI0CON_RFLUSH_EN (0x1 << 12 ) /* EN. If this bit is set, all incoming data is ignored and no interrupts are generated. If set and TIM = 0 (SPI0CON[6]), a read of the Rx FIFO initiates a transfer. */ + +/* SPI0CON[CON] - Continuous transfer enable bit. */ +#define SPI0CON_CON_BBA (*(volatile unsigned long *) 0x4208022C) +#define SPI0CON_CON_MSK (0x1 << 11 ) +#define SPI0CON_CON (0x1 << 11 ) +#define SPI0CON_CON_DIS (0x0 << 11 ) /* DIS. Disable continuous transfer. Each transfer consists of a single 8-bit serial transfer. If valid data exists in the SPIxTX register, then a new transfer is initiated after a stall period of one serial clock cycle. The CS line is deactivated for this one serial clock cycle. */ +#define SPI0CON_CON_EN (0x1 << 11 ) /* EN. Enable continuous transfer. In master mode, the transfer continues until no valid data is available in the Tx register. CS is asserted and remains asserted for the duration of each 8-bit serial transfer until Tx is empty. */ + +/* SPI0CON[LOOPBACK] - Loopback enable bit. */ +#define SPI0CON_LOOPBACK_BBA (*(volatile unsigned long *) 0x42080228) +#define SPI0CON_LOOPBACK_MSK (0x1 << 10 ) +#define SPI0CON_LOOPBACK (0x1 << 10 ) +#define SPI0CON_LOOPBACK_DIS (0x0 << 10 ) /* DIS. Normal mode. */ +#define SPI0CON_LOOPBACK_EN (0x1 << 10 ) /* EN. Connect MISO to MOSI, thus, data transmitted from Tx register is looped back to the Rx register. SPI must be configured in master mode. */ + +/* SPI0CON[SOEN] - Slave output enable bit. */ +#define SPI0CON_SOEN_BBA (*(volatile unsigned long *) 0x42080224) +#define SPI0CON_SOEN_MSK (0x1 << 9 ) +#define SPI0CON_SOEN (0x1 << 9 ) +#define SPI0CON_SOEN_DIS (0x0 << 9 ) /* DIS. Disable the output driver on the MISO pin. The MISO pin is open-circuit when this bit is clear. */ +#define SPI0CON_SOEN_EN (0x1 << 9 ) /* EN. MISO operates as normal. */ + +/* SPI0CON[RXOF] - RX overflow overwrite enable bit. */ +#define SPI0CON_RXOF_BBA (*(volatile unsigned long *) 0x42080220) +#define SPI0CON_RXOF_MSK (0x1 << 8 ) +#define SPI0CON_RXOF (0x1 << 8 ) +#define SPI0CON_RXOF_DIS (0x0 << 8 ) /* DIS. The new serial byte received is discarded when there is no space left in the FIFO */ +#define SPI0CON_RXOF_EN (0x1 << 8 ) /* EN. The valid data in the Rx register is overwritten by the new serial byte received when there is no space left in the FIFO. */ + +/* SPI0CON[ZEN] - Transmit underrun: Transmit 0s when the Tx FIFO is empty */ +#define SPI0CON_ZEN_BBA (*(volatile unsigned long *) 0x4208021C) +#define SPI0CON_ZEN_MSK (0x1 << 7 ) +#define SPI0CON_ZEN (0x1 << 7 ) +#define SPI0CON_ZEN_DIS (0x0 << 7 ) /* DIS. The last byte from the previous transmission is shifted out when a transfer is initiated with no valid data in the FIFO. */ +#define SPI0CON_ZEN_EN (0x1 << 7 ) /* EN. Transmit 0x00 when a transfer is initiated with no valid data in the FIFO. */ + +/* SPI0CON[TIM] - Transfer and interrupt mode bit. */ +#define SPI0CON_TIM_BBA (*(volatile unsigned long *) 0x42080218) +#define SPI0CON_TIM_MSK (0x1 << 6 ) +#define SPI0CON_TIM (0x1 << 6 ) +#define SPI0CON_TIM_TXWR (0x1 << 6 ) /* TXWR. Initiate transfer with a write to the SPIxTX register. Interrupt only occurs when Tx is empty. */ +#define SPI0CON_TIM_RXRD (0x0 << 6 ) /* RXRD. Initiate transfer with a read of the SPIxRX register. The read must be done while the SPI interface is idle. Interrupt only occurs when Rx is full. */ + +/* SPI0CON[LSB] - LSB first transfer enable bit. */ +#define SPI0CON_LSB_BBA (*(volatile unsigned long *) 0x42080214) +#define SPI0CON_LSB_MSK (0x1 << 5 ) +#define SPI0CON_LSB (0x1 << 5 ) +#define SPI0CON_LSB_DIS (0x0 << 5 ) /* DIS. MSB is transmitted first. */ +#define SPI0CON_LSB_EN (0x1 << 5 ) /* EN. LSB is transmitted first. */ + +/* SPI0CON[WOM] - Wired OR enable bit. */ +#define SPI0CON_WOM_BBA (*(volatile unsigned long *) 0x42080210) +#define SPI0CON_WOM_MSK (0x1 << 4 ) +#define SPI0CON_WOM (0x1 << 4 ) +#define SPI0CON_WOM_DIS (0x0 << 4 ) /* DIS. Normal driver output operation. */ +#define SPI0CON_WOM_EN (0x1 << 4 ) /* EN. Enable open circuit data output for multimaster/multislave configuration. */ + +/* SPI0CON[CPOL] - Serial clock polarity mode bit. */ +#define SPI0CON_CPOL_BBA (*(volatile unsigned long *) 0x4208020C) +#define SPI0CON_CPOL_MSK (0x1 << 3 ) +#define SPI0CON_CPOL (0x1 << 3 ) +#define SPI0CON_CPOL_LOW (0x0 << 3 ) /* LOW. Serial clock idles low. */ +#define SPI0CON_CPOL_HIGH (0x1 << 3 ) /* HIGH. Serial clock idles high. */ + +/* SPI0CON[CPHA] - Serial clock phase mode bit. */ +#define SPI0CON_CPHA_BBA (*(volatile unsigned long *) 0x42080208) +#define SPI0CON_CPHA_MSK (0x1 << 2 ) +#define SPI0CON_CPHA (0x1 << 2 ) +#define SPI0CON_CPHA_SAMPLELEADING (0x0 << 2 ) /* SAMPLELEADING. Serial clock pulses at the middle of the first data bit transfer. */ +#define SPI0CON_CPHA_SAMPLETRAILING (0x1 << 2 ) /* SAMPLETRAILING. Serial clock pulses at the start of the first data bit. */ + +/* SPI0CON[MASEN] - Master mode enable bit. */ +#define SPI0CON_MASEN_BBA (*(volatile unsigned long *) 0x42080204) +#define SPI0CON_MASEN_MSK (0x1 << 1 ) +#define SPI0CON_MASEN (0x1 << 1 ) +#define SPI0CON_MASEN_DIS (0x0 << 1 ) /* DIS. Configure in slave mode. */ +#define SPI0CON_MASEN_EN (0x1 << 1 ) /* EN. Configure in master mode. */ + +/* SPI0CON[ENABLE] - SPI enable bit. */ +#define SPI0CON_ENABLE_BBA (*(volatile unsigned long *) 0x42080200) +#define SPI0CON_ENABLE_MSK (0x1 << 0 ) +#define SPI0CON_ENABLE (0x1 << 0 ) +#define SPI0CON_ENABLE_DIS (0x0 << 0 ) /* DIS. Disable the SPI. Clearing this bit will also reset all the FIFO related logic to enable a clean start. */ +#define SPI0CON_ENABLE_EN (0x1 << 0 ) /* EN. Enable the SPI. */ + +/* Reset Value for SPI0DMA*/ +#define SPI0DMA_RVAL 0x0 + +/* SPI0DMA[IENRXDMA] - Receive DMA request enable bit. */ +#define SPI0DMA_IENRXDMA_BBA (*(volatile unsigned long *) 0x42080288) +#define SPI0DMA_IENRXDMA_MSK (0x1 << 2 ) +#define SPI0DMA_IENRXDMA (0x1 << 2 ) +#define SPI0DMA_IENRXDMA_DIS (0x0 << 2 ) /* DIS. Disable Rx DMA requests. */ +#define SPI0DMA_IENRXDMA_EN (0x1 << 2 ) /* EN. Enable Rx DMA requests. */ + +/* SPI0DMA[IENTXDMA] - Transmit DMA request enable bit. */ +#define SPI0DMA_IENTXDMA_BBA (*(volatile unsigned long *) 0x42080284) +#define SPI0DMA_IENTXDMA_MSK (0x1 << 1 ) +#define SPI0DMA_IENTXDMA (0x1 << 1 ) +#define SPI0DMA_IENTXDMA_DIS (0x0 << 1 ) /* DIS. Disable Tx DMA requests. */ +#define SPI0DMA_IENTXDMA_EN (0x1 << 1 ) /* EN. Enable Tx DMA requests. */ + +/* SPI0DMA[ENABLE] - DMA data transfer enable bit. */ +#define SPI0DMA_ENABLE_BBA (*(volatile unsigned long *) 0x42080280) +#define SPI0DMA_ENABLE_MSK (0x1 << 0 ) +#define SPI0DMA_ENABLE (0x1 << 0 ) +#define SPI0DMA_ENABLE_DIS (0x0 << 0 ) /* DIS. Disable DMA transfer. This bit needs to be cleared to prevent extra DMA request to the µDMA controller. */ +#define SPI0DMA_ENABLE_EN (0x1 << 0 ) /* EN. Enable a DMA transfer. Starts the transfer of a master configured to initiate transfer on transmit. */ + +/* Reset Value for SPI0CNT*/ +#define SPI0CNT_RVAL 0x0 + +/* SPI0CNT[VALUE] - Number of bytes requested by the SPI master during DMA transfer, when configured to initiate a transfer on a read of SPI0RX. This register is only used in DMA, master, Rx mode. */ +#define SPI0CNT_VALUE_MSK (0xFF << 0 ) +#if (__NO_MMR_STRUCTS__==1) + +#define SPI1STA (*(volatile unsigned short int *) 0x40004400) +#define SPI1RX (*(volatile unsigned char *) 0x40004404) +#define SPI1TX (*(volatile unsigned char *) 0x40004408) +#define SPI1DIV (*(volatile unsigned short int *) 0x4000440C) +#define SPI1CON (*(volatile unsigned short int *) 0x40004410) +#define SPI1DMA (*(volatile unsigned short int *) 0x40004414) +#define SPI1CNT (*(volatile unsigned short int *) 0x40004418) +#endif // (__NO_MMR_STRUCTS__==1) + +/* Reset Value for SPI1STA*/ +#define SPI1STA_RVAL 0x0 + +/* SPI1STA[CSERR] - CS error status bit. This bit generates an interrupt when detecting an abrupt CS desassertion before the full byte of data is transmitted completely. */ +#define SPI1STA_CSERR_BBA (*(volatile unsigned long *) 0x42088030) +#define SPI1STA_CSERR_MSK (0x1 << 12 ) +#define SPI1STA_CSERR (0x1 << 12 ) +#define SPI1STA_CSERR_CLR (0x0 << 12 ) /* CLR: Cleared when no CS error is detected. Cleared to 0 on a read of SPI1STA register. */ +#define SPI1STA_CSERR_SET (0x1 << 12 ) /* SET. Set when the CS line is deasserted abruptly. */ + +/* SPI1STA[RXS] - Rx FIFO excess bytes present. */ +#define SPI1STA_RXS_BBA (*(volatile unsigned long *) 0x4208802C) +#define SPI1STA_RXS_MSK (0x1 << 11 ) +#define SPI1STA_RXS (0x1 << 11 ) +#define SPI1STA_RXS_CLR (0x0 << 11 ) /* CLR. When the number of bytes in the FIFO is equal or less than the number in SPI0CON[15:14]. This bit is not cleared on a read of SPI0STA register. */ +#define SPI1STA_RXS_SET (0x1 << 11 ) /* SET. When there are more bytes in the Rx FIFO than configured in MOD (SPI1CON[15:14]). For example if MOD = TX1RX1, RXS is set when there are 2 or more bytes in the Rx FIFO. This bit does not dependent on SPI1CON[6] and does not cause an interrupt. */ + +/* SPI1STA[RXFSTA] - Rx FIFO status bits, indicates how many valid bytes are in the Rx FIFO. */ +#define SPI1STA_RXFSTA_MSK (0x7 << 8 ) +#define SPI1STA_RXFSTA_EMPTY (0x0 << 8 ) /* EMPTY. When Rx FIFO is empty. */ +#define SPI1STA_RXFSTA_ONEBYTE (0x1 << 8 ) /* ONEBYTE. When 1 valid byte is in the FIFO. */ +#define SPI1STA_RXFSTA_TWOBYTES (0x2 << 8 ) /* TWOBYTES. When 2 valid bytes are in the FIFO. */ +#define SPI1STA_RXFSTA_THREEBYTES (0x3 << 8 ) /* THREEBYTES. When 3 valid bytes are in the FIFO. */ +#define SPI1STA_RXFSTA_FOURBYTES (0x4 << 8 ) /* FOURBYTES. When 4 valid bytes are in the FIFO. */ + +/* SPI1STA[RXOF] - Rx FIFO overflow status bit. This bit generates an interrupt. */ +#define SPI1STA_RXOF_BBA (*(volatile unsigned long *) 0x4208801C) +#define SPI1STA_RXOF_MSK (0x1 << 7 ) +#define SPI1STA_RXOF (0x1 << 7 ) +#define SPI1STA_RXOF_CLR (0x0 << 7 ) /* CLR.Cleared to 0 on a read of SPI1STA register. */ +#define SPI1STA_RXOF_SET (0x1 << 7 ) /* SET. Set when the Rx FIFO is already full when new data is loaded to the FIFO. This bit generates an interrupt except when RFLUSH is set. (SPI1CON[12]). */ + +/* SPI1STA[RX] - Rx interrupt status bit. This bit generates an interrupt, except when DMA transfer is enabled. */ +#define SPI1STA_RX_BBA (*(volatile unsigned long *) 0x42088018) +#define SPI1STA_RX_MSK (0x1 << 6 ) +#define SPI1STA_RX (0x1 << 6 ) +#define SPI1STA_RX_CLR (0x0 << 6 ) /* CLR. Cleared to 0 on a read of SPI1STA register. */ +#define SPI1STA_RX_SET (0x1 << 6 ) /* SET. Set when a receive interrupt occurs. This bit is set when TIM (SPI1CON[6]) is cleared and the required number of bytes have been received. */ + +/* SPI1STA[TX] - Tx interrupt status bit. This bit generates an interrupt, except when DMA transfer is enabled. */ +#define SPI1STA_TX_BBA (*(volatile unsigned long *) 0x42088014) +#define SPI1STA_TX_MSK (0x1 << 5 ) +#define SPI1STA_TX (0x1 << 5 ) +#define SPI1STA_TX_CLR (0x0 << 5 ) /* CLR. Cleared to 0 on a read of SPI1STA register. */ +#define SPI1STA_TX_SET (0x1 << 5 ) /* SET. Set when a transmit interrupt occurs. This bit is set when TIM (SPI1CON[6]) is set and the required number of bytes have been transmitted. */ + +/* SPI1STA[TXUR] - Tx FIFO Underrun. This bit generates an interrupt. */ +#define SPI1STA_TXUR_BBA (*(volatile unsigned long *) 0x42088010) +#define SPI1STA_TXUR_MSK (0x1 << 4 ) +#define SPI1STA_TXUR (0x1 << 4 ) +#define SPI1STA_TXUR_CLR (0x0 << 4 ) /* CLR. Cleared to 0 on a read of SPI1STA register. */ +#define SPI1STA_TXUR_SET (0x1 << 4 ) /* SET. Set when a transmit is initiated without any valid data in the Tx FIFO. This bit generates an interrupt except when TFLUSH is set in SPI1CON. */ + +/* SPI1STA[TXFSTA] - Tx FIFO status bits, indicates how many valid bytes are in the Tx FIFO. */ +#define SPI1STA_TXFSTA_MSK (0x7 << 1 ) +#define SPI1STA_TXFSTA_EMPTY (0x0 << 1 ) /* EMPTY. When Tx FIFO is empty. */ +#define SPI1STA_TXFSTA_ONEBYTE (0x1 << 1 ) /* ONEBYTE. 1 valid byte is in the FIFO. */ +#define SPI1STA_TXFSTA_TWOBYTES (0x2 << 1 ) /* TWOBYTES. 2 valid bytes are in the FIFO. */ +#define SPI1STA_TXFSTA_THREEBYTES (0x3 << 1 ) /* THREEBYTES. 3 valid bytes are in the FIFO. */ +#define SPI1STA_TXFSTA_FOURBYTES (0x4 << 1 ) /* FOURBYTES. 4 valid bytes are in the FIFO. */ + +/* SPI1STA[IRQ] - Interrupt status bit. */ +#define SPI1STA_IRQ_BBA (*(volatile unsigned long *) 0x42088000) +#define SPI1STA_IRQ_MSK (0x1 << 0 ) +#define SPI1STA_IRQ (0x1 << 0 ) +#define SPI1STA_IRQ_CLR (0x0 << 0 ) /* CLR. Cleared to 0 on a read of SPI1STA register. */ +#define SPI1STA_IRQ_SET (0x1 << 0 ) /* SET. Set to 1 when an SPI1 based interrupt occurs. */ + +/* Reset Value for SPI1RX*/ +#define SPI1RX_RVAL 0x0 + +/* SPI1RX[VALUE] - 8-bit receive register. A read of the RX FIFO returns the next byte to be read from the FIFO. A read of the FIFO when it is empty returns zero. */ +#define SPI1RX_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for SPI1TX*/ +#define SPI1TX_RVAL 0x0 + +/* SPI1TX[VALUE] - 8-bit transmit register. A write to the Tx FIFO address space writes data to the next available location in the Tx FIFO. If the FIFO is full, the oldest byte of data in the FIFO is overwritten. A read from this address location return zero. */ +#define SPI1TX_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for SPI1DIV*/ +#define SPI1DIV_RVAL 0x0 + +/* SPI1DIV[BCRST] - Configures the behavior of SPI communication after an abrupt deassertion of CS. This bit should be set in slave and master mode. */ +#define SPI1DIV_BCRST_BBA (*(volatile unsigned long *) 0x4208819C) +#define SPI1DIV_BCRST_MSK (0x1 << 7 ) +#define SPI1DIV_BCRST (0x1 << 7 ) +#define SPI1DIV_BCRST_DIS (0x0 << 7 ) /* DIS. Resumes communication from where it stopped when the CS is deasserted. The rest of the bits are then received/ transmitted when CS returns low. User code should ignore the CSERR interrupt. */ +#define SPI1DIV_BCRST_EN (0x1 << 7 ) /* EN. Enabled for a clean restart of SPI transfer after a CSERR condition. User code must also clear the SPI enable bit in SPI1CON during the CSERR interrupt. */ + +/* SPI1DIV[DIV] - Factor used to divide UCLK in the generation of the master mode serial clock. */ +#define SPI1DIV_DIV_MSK (0x3F << 0 ) + +/* Reset Value for SPI1CON*/ +#define SPI1CON_RVAL 0x0 + +/* SPI1CON[MOD] - IRQ mode bits. When TIM is set these bits configure when the Tx/Rx interrupts occur in a transfer. For a DMA Rx transfer, these bits should be 00. */ +#define SPI1CON_MOD_MSK (0x3 << 14 ) +#define SPI1CON_MOD_TX1RX1 (0x0 << 14 ) /* TX1RX1. Tx/Rx interrupt occurs when 1 byte has been transmitted/received from/into the FIFO. */ +#define SPI1CON_MOD_TX2RX2 (0x1 << 14 ) /* TX2RX2. Tx/Rx interrupt occurs when 2 bytes have been transmitted/received from/into the FIFO. */ +#define SPI1CON_MOD_TX3RX3 (0x2 << 14 ) /* TX3RX3. Tx/Rx interrupt occurs when 3 bytes have been transmitted/received from/into the FIFO. */ +#define SPI1CON_MOD_TX4RX4 (0x3 << 14 ) /* TX4RX4. Tx/Rx interrupt occurs when 4 bytes have been transmitted/received from/into the FIFO. */ + +/* SPI1CON[TFLUSH] - Tx FIFO flush enable bit. */ +#define SPI1CON_TFLUSH_BBA (*(volatile unsigned long *) 0x42088234) +#define SPI1CON_TFLUSH_MSK (0x1 << 13 ) +#define SPI1CON_TFLUSH (0x1 << 13 ) +#define SPI1CON_TFLUSH_DIS (0x0 << 13 ) /* DIS. Disable Tx FIFO flushing. */ +#define SPI1CON_TFLUSH_EN (0x1 << 13 ) /* EN. Flush the Tx FIFO. This bit does not clear itself and should be toggled if a single flush is required. If this bit is left high, then either the last transmitted value or 0x00 is transmitted depending on the ZEN bit (SPI1CON[7]). Any writes to the Tx FIFO are ignored while this bit is set. */ + +/* SPI1CON[RFLUSH] - Rx FIFO flush enable bit. */ +#define SPI1CON_RFLUSH_BBA (*(volatile unsigned long *) 0x42088230) +#define SPI1CON_RFLUSH_MSK (0x1 << 12 ) +#define SPI1CON_RFLUSH (0x1 << 12 ) +#define SPI1CON_RFLUSH_DIS (0x0 << 12 ) /* DIS. Disable Rx FIFO flushing. */ +#define SPI1CON_RFLUSH_EN (0x1 << 12 ) /* EN. If this bit is set, all incoming data is ignored and no interrupts are generated. If set and TIM = 0 (SPI1CON[6]), a read of the Rx FIFO initiates a transfer. */ + +/* SPI1CON[CON] - Continuous transfer enable bit. */ +#define SPI1CON_CON_BBA (*(volatile unsigned long *) 0x4208822C) +#define SPI1CON_CON_MSK (0x1 << 11 ) +#define SPI1CON_CON (0x1 << 11 ) +#define SPI1CON_CON_DIS (0x0 << 11 ) /* DIS. Disable continuous transfer. Each transfer consists of a single 8-bit serial transfer. If valid data exists in the SPIxTX register, then a new transfer is initiated after a stall period of one serial clock cycle. The CS line is deactivated for this one serial clock cycle. */ +#define SPI1CON_CON_EN (0x1 << 11 ) /* EN. Enable continuous transfer. In master mode, the transfer continues until no valid data is available in the Tx register. CS is asserted and remains asserted for the duration of each 8-bit serial transfer until Tx is empty. */ + +/* SPI1CON[LOOPBACK] - Loopback enable bit. */ +#define SPI1CON_LOOPBACK_BBA (*(volatile unsigned long *) 0x42088228) +#define SPI1CON_LOOPBACK_MSK (0x1 << 10 ) +#define SPI1CON_LOOPBACK (0x1 << 10 ) +#define SPI1CON_LOOPBACK_DIS (0x0 << 10 ) /* DIS. Normal mode. */ +#define SPI1CON_LOOPBACK_EN (0x1 << 10 ) /* EN. Connect MISO to MOSI, thus, data transmitted from Tx register is looped back to the Rx register. SPI must be configured in master mode. */ + +/* SPI1CON[SOEN] - Slave output enable bit. */ +#define SPI1CON_SOEN_BBA (*(volatile unsigned long *) 0x42088224) +#define SPI1CON_SOEN_MSK (0x1 << 9 ) +#define SPI1CON_SOEN (0x1 << 9 ) +#define SPI1CON_SOEN_DIS (0x0 << 9 ) /* DIS. Disable the output driver on the MISO pin. The MISO pin is open-circuit when this bit is clear. */ +#define SPI1CON_SOEN_EN (0x1 << 9 ) /* EN. MISO operates as normal. */ + +/* SPI1CON[RXOF] - RX overflow overwrite enable bit. */ +#define SPI1CON_RXOF_BBA (*(volatile unsigned long *) 0x42088220) +#define SPI1CON_RXOF_MSK (0x1 << 8 ) +#define SPI1CON_RXOF (0x1 << 8 ) +#define SPI1CON_RXOF_DIS (0x0 << 8 ) /* DIS. The new serial byte received is discarded when there is no space left in the FIFO */ +#define SPI1CON_RXOF_EN (0x1 << 8 ) /* EN. The valid data in the Rx register is overwritten by the new serial byte received when there is no space left in the FIFO. */ + +/* SPI1CON[ZEN] - TX underrun: Transmit 0s when Tx FIFO is empty. */ +#define SPI1CON_ZEN_BBA (*(volatile unsigned long *) 0x4208821C) +#define SPI1CON_ZEN_MSK (0x1 << 7 ) +#define SPI1CON_ZEN (0x1 << 7 ) +#define SPI1CON_ZEN_DIS (0x0 << 7 ) /* DIS. The last byte from the previous transmission is shifted out when a transfer is initiated with no valid data in the FIFO. */ +#define SPI1CON_ZEN_EN (0x1 << 7 ) /* EN. Transmit 0x00 when a transfer is initiated with no valid data in the FIFO. */ + +/* SPI1CON[TIM] - Transfer and interrupt mode bit. */ +#define SPI1CON_TIM_BBA (*(volatile unsigned long *) 0x42088218) +#define SPI1CON_TIM_MSK (0x1 << 6 ) +#define SPI1CON_TIM (0x1 << 6 ) +#define SPI1CON_TIM_TXWR (0x1 << 6 ) /* TXWR. Initiate transfer with a write to the SPIxTX register. Interrupt only occurs when Tx is empty. */ +#define SPI1CON_TIM_RXRD (0x0 << 6 ) /* RXRD. Initiate transfer with a read of the SPIxRX register. The read must be done while the SPI interface is idle. Interrupt only occurs when Rx is full. */ + +/* SPI1CON[LSB] - LSB first transfer enable bit. */ +#define SPI1CON_LSB_BBA (*(volatile unsigned long *) 0x42088214) +#define SPI1CON_LSB_MSK (0x1 << 5 ) +#define SPI1CON_LSB (0x1 << 5 ) +#define SPI1CON_LSB_DIS (0x0 << 5 ) /* DIS. MSB is transmitted first. */ +#define SPI1CON_LSB_EN (0x1 << 5 ) /* EN. LSB is transmitted first. */ + +/* SPI1CON[WOM] - Wired OR enable bit. */ +#define SPI1CON_WOM_BBA (*(volatile unsigned long *) 0x42088210) +#define SPI1CON_WOM_MSK (0x1 << 4 ) +#define SPI1CON_WOM (0x1 << 4 ) +#define SPI1CON_WOM_DIS (0x0 << 4 ) /* DIS. Normal driver output operation. */ +#define SPI1CON_WOM_EN (0x1 << 4 ) /* EN. Enable open circuit data output for multimaster/multislave configuration. */ + +/* SPI1CON[CPOL] - Serial clock polarity mode bit. */ +#define SPI1CON_CPOL_BBA (*(volatile unsigned long *) 0x4208820C) +#define SPI1CON_CPOL_MSK (0x1 << 3 ) +#define SPI1CON_CPOL (0x1 << 3 ) +#define SPI1CON_CPOL_LOW (0x0 << 3 ) /* LOW. Serial clock idles low. */ +#define SPI1CON_CPOL_HIGH (0x1 << 3 ) /* HIGH. Serial clock idles high. */ + +/* SPI1CON[CPHA] - Serial clock phase mode bit. */ +#define SPI1CON_CPHA_BBA (*(volatile unsigned long *) 0x42088208) +#define SPI1CON_CPHA_MSK (0x1 << 2 ) +#define SPI1CON_CPHA (0x1 << 2 ) +#define SPI1CON_CPHA_SAMPLELEADING (0x0 << 2 ) /* SAMPLELEADING. Serial clock pulses at the middle of the first data bit transfer. */ +#define SPI1CON_CPHA_SAMPLETRAILING (0x1 << 2 ) /* SAMPLETRAILING. Serial clock pulses at the start of the first data bit. */ + +/* SPI1CON[MASEN] - Master mode enable bit. */ +#define SPI1CON_MASEN_BBA (*(volatile unsigned long *) 0x42088204) +#define SPI1CON_MASEN_MSK (0x1 << 1 ) +#define SPI1CON_MASEN (0x1 << 1 ) +#define SPI1CON_MASEN_DIS (0x0 << 1 ) /* DIS. Configure in slave mode. */ +#define SPI1CON_MASEN_EN (0x1 << 1 ) /* EN. Configure in master mode. */ + +/* SPI1CON[ENABLE] - SPI enable bit. */ +#define SPI1CON_ENABLE_BBA (*(volatile unsigned long *) 0x42088200) +#define SPI1CON_ENABLE_MSK (0x1 << 0 ) +#define SPI1CON_ENABLE (0x1 << 0 ) +#define SPI1CON_ENABLE_DIS (0x0 << 0 ) /* DIS. Disable the SPI. Clearing this bit will also reset all the FIFO related logic to enable a clean start. */ +#define SPI1CON_ENABLE_EN (0x1 << 0 ) /* EN. Enable the SPI. */ + +/* Reset Value for SPI1DMA*/ +#define SPI1DMA_RVAL 0x0 + +/* SPI1DMA[IENRXDMA] - Receive DMA request enable bit. */ +#define SPI1DMA_IENRXDMA_BBA (*(volatile unsigned long *) 0x42088288) +#define SPI1DMA_IENRXDMA_MSK (0x1 << 2 ) +#define SPI1DMA_IENRXDMA (0x1 << 2 ) +#define SPI1DMA_IENRXDMA_DIS (0x0 << 2 ) /* DIS. Disable Rx DMA requests. */ +#define SPI1DMA_IENRXDMA_EN (0x1 << 2 ) /* EN. Enable Rx DMA requests. */ + +/* SPI1DMA[IENTXDMA] - Transmit DMA request enable bit. */ +#define SPI1DMA_IENTXDMA_BBA (*(volatile unsigned long *) 0x42088284) +#define SPI1DMA_IENTXDMA_MSK (0x1 << 1 ) +#define SPI1DMA_IENTXDMA (0x1 << 1 ) +#define SPI1DMA_IENTXDMA_DIS (0x0 << 1 ) /* DIS. Disable Tx DMA requests. */ +#define SPI1DMA_IENTXDMA_EN (0x1 << 1 ) /* EN. Enable Tx DMA requests. */ + +/* SPI1DMA[ENABLE] - DMA data transfer enable bit. */ +#define SPI1DMA_ENABLE_BBA (*(volatile unsigned long *) 0x42088280) +#define SPI1DMA_ENABLE_MSK (0x1 << 0 ) +#define SPI1DMA_ENABLE (0x1 << 0 ) +#define SPI1DMA_ENABLE_DIS (0x0 << 0 ) /* DIS. Disable DMA transfer. This bit needs to be cleared to prevent extra DMA request to the µDMA controller. */ +#define SPI1DMA_ENABLE_EN (0x1 << 0 ) /* EN. Enable a DMA transfer. Starts the transfer of a master configured to initiate transfer on transmit. */ + +/* Reset Value for SPI1CNT*/ +#define SPI1CNT_RVAL 0x0 + +/* SPI1CNT[VALUE] - Number of bytes requested by the SPI master during DMA transfer, when configured to initiate a transfer on a read of SPI0RX. This register is only used in DMA, master, Rx mode.. */ +#define SPI1CNT_VALUE_MSK (0xFF << 0 ) +// ------------------------------------------------------------------------------------------------ +// ----- T0 ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Timer 0 (pADI_TM0) + */ + +#if (__NO_MMR_STRUCTS__==0) +typedef struct { /*!< pADI_TM0 Structure */ + __IO uint16_t LD; /*!< 16-bit Load Value */ + __I uint16_t RESERVED0; + __IO uint16_t VAL; /*!< 16-bit Timer Value */ + __I uint16_t RESERVED1; + __IO uint16_t CON; /*!< Control Register */ + __I uint16_t RESERVED2; + __IO uint16_t CLRI; /*!< Clear Interrupt Register */ + __I uint16_t RESERVED3; + __IO uint16_t CAP; /*!< Capture Register */ + __I uint16_t RESERVED4[5]; + __IO uint16_t STA; /*!< Status Register */ +} ADI_TIMER_TypeDef; +#else // (__NO_MMR_STRUCTS__==0) +#define T0LD (*(volatile unsigned short int *) 0x40000000) +#define T0VAL (*(volatile unsigned short int *) 0x40000004) +#define T0CON (*(volatile unsigned short int *) 0x40000008) +#define T0CLRI (*(volatile unsigned short int *) 0x4000000C) +#define T0CAP (*(volatile unsigned short int *) 0x40000010) +#define T0STA (*(volatile unsigned short int *) 0x4000001C) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for T0LD*/ +#define T0LD_RVAL 0x0 + +/* T0LD[VALUE] - Load value. */ +#define T0LD_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T0VAL*/ +#define T0VAL_RVAL 0x0 + +/* T0VAL[VALUE] - Current counter value. */ +#define T0VAL_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T0CON*/ +#define T0CON_RVAL 0xA + +/* T0CON[EVENTEN] - Enable event bit. */ +#define T0CON_EVENTEN_BBA (*(volatile unsigned long *) 0x42000130) +#define T0CON_EVENTEN_MSK (0x1 << 12 ) +#define T0CON_EVENTEN (0x1 << 12 ) +#define T0CON_EVENTEN_DIS (0x0 << 12 ) /* DIS. Cleared by user. */ +#define T0CON_EVENTEN_EN (0x1 << 12 ) /* EN. Enable time capture of an event. */ + +/* T0CON[EVENT] - Event select bits. Settings not described are reserved and should not be used. */ +#define T0CON_EVENT_MSK (0xF << 8 ) +#define T0CON_EVENT_T2 (0x0 << 8 ) /* T2. Wakeup Timer. */ +#define T0CON_EVENT_EXT0 (0x1 << 8 ) /* EXT0. External interrupt 0. */ +#define T0CON_EVENT_EXT1 (0x2 << 8 ) /* EXT1. External interrupt 1. */ +#define T0CON_EVENT_EXT2 (0x3 << 8 ) /* EXT2. External interrupt 2. */ +#define T0CON_EVENT_EXT3 (0x4 << 8 ) /* EXT3. External interrupt 3. */ +#define T0CON_EVENT_EXT4 (0x5 << 8 ) /* EXT4. External interrupt 4. */ +#define T0CON_EVENT_EXT5 (0x6 << 8 ) /* EXT5. External interrupt 5. */ +#define T0CON_EVENT_EXT6 (0x7 << 8 ) /* EXT6. External interrupt 6. */ +#define T0CON_EVENT_EXT7 (0x8 << 8 ) /* EXT7. External interrupt 7. */ +#define T0CON_EVENT_EXT8 (0x9 << 8 ) /* EXT8. External interrupt 8. */ +#define T0CON_EVENT_T3 (0xA << 8 ) /* T3. Watchdog timer. */ +#define T0CON_EVENT_T1 (0xC << 8 ) /* T1. Timer 1. */ +#define T0CON_EVENT_ADC (0xD << 8 ) /* ADC. Analog to Digital Converter. */ +#define T0CON_EVENT_FEE (0xE << 8 ) /* FEE. Flash Controller. */ +#define T0CON_EVENT_COM (0xF << 8 ) /* COM. UART Peripheral. */ + +/* T0CON[RLD] - Reload control bit for periodic mode. */ +#define T0CON_RLD_BBA (*(volatile unsigned long *) 0x4200011C) +#define T0CON_RLD_MSK (0x1 << 7 ) +#define T0CON_RLD (0x1 << 7 ) +#define T0CON_RLD_DIS (0x0 << 7 ) /* DIS. Reload on a time out. */ +#define T0CON_RLD_EN (0x1 << 7 ) /* EN. Reload the counter on a write to T0CLRI. */ + +/* T0CON[CLK] - Clock select. */ +#define T0CON_CLK_MSK (0x3 << 5 ) +#define T0CON_CLK_UCLK (0x0 << 5 ) /* UCLK. Undivided system clock. */ +#define T0CON_CLK_PCLK (0x1 << 5 ) /* PCLK. Peripheral clock. */ +#define T0CON_CLK_LFOSC (0x2 << 5 ) /* LFOSC. 32 kHz internal oscillator. */ +#define T0CON_CLK_LFXTAL (0x3 << 5 ) /* LFXTAL. 32 kHz external crystal. */ + +/* T0CON[ENABLE] - Timer enable bit. */ +#define T0CON_ENABLE_BBA (*(volatile unsigned long *) 0x42000110) +#define T0CON_ENABLE_MSK (0x1 << 4 ) +#define T0CON_ENABLE (0x1 << 4 ) +#define T0CON_ENABLE_DIS (0x0 << 4 ) /* DIS. Disable the timer. Clearing this bit resets the timer, including the T0VAL register. */ +#define T0CON_ENABLE_EN (0x1 << 4 ) /* EN. Enable the timer. The timer starts counting from its initial value, 0 if count-up mode or 0xFFFF if count-down mode. */ + +/* T0CON[MOD] - Timer mode. */ +#define T0CON_MOD_BBA (*(volatile unsigned long *) 0x4200010C) +#define T0CON_MOD_MSK (0x1 << 3 ) +#define T0CON_MOD (0x1 << 3 ) +#define T0CON_MOD_FREERUN (0x0 << 3 ) /* FREERUN. Operate in free running mode. */ +#define T0CON_MOD_PERIODIC (0x1 << 3 ) /* PERIODIC. Operate in periodic mode. */ + +/* T0CON[UP] - Count down/up. */ +#define T0CON_UP_BBA (*(volatile unsigned long *) 0x42000108) +#define T0CON_UP_MSK (0x1 << 2 ) +#define T0CON_UP (0x1 << 2 ) +#define T0CON_UP_DIS (0x0 << 2 ) /* DIS. Timer to count down. */ +#define T0CON_UP_EN (0x1 << 2 ) /* EN. Timer to count up. */ + +/* T0CON[PRE] - Prescaler. */ +#define T0CON_PRE_MSK (0x3 << 0 ) +#define T0CON_PRE_DIV1 (0x0 << 0 ) /* DIV1. Source clock/1.If the selected clock source is UCLK or PCLK this setting results in a prescaler of 4. */ +#define T0CON_PRE_DIV16 (0x1 << 0 ) /* DIV16. Source clock/16. */ +#define T0CON_PRE_DIV256 (0x2 << 0 ) /* DIV256. Source clock/256. */ +#define T0CON_PRE_DIV32768 (0x3 << 0 ) /* DIV32768. Source clock/32768. */ + +/* Reset Value for T0CLRI*/ +#define T0CLRI_RVAL 0x0 + +/* T0CLRI[CAP] - Clear captured event interrupt. */ +#define T0CLRI_CAP_BBA (*(volatile unsigned long *) 0x42000184) +#define T0CLRI_CAP_MSK (0x1 << 1 ) +#define T0CLRI_CAP (0x1 << 1 ) +#define T0CLRI_CAP_CLR (0x1 << 1 ) /* CLR. Clear a captured event interrupt. This bit always reads 0. */ + +/* T0CLRI[TMOUT] - Clear timeout interrupt. */ +#define T0CLRI_TMOUT_BBA (*(volatile unsigned long *) 0x42000180) +#define T0CLRI_TMOUT_MSK (0x1 << 0 ) +#define T0CLRI_TMOUT (0x1 << 0 ) +#define T0CLRI_TMOUT_CLR (0x1 << 0 ) /* CLR. Clear a timeout interrupt. This bit always reads 0. */ + +/* Reset Value for T0CAP*/ +#define T0CAP_RVAL 0x0 + +/* T0CAP[VALUE] - Capture value. */ +#define T0CAP_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T0STA*/ +#define T0STA_RVAL 0x0 + +/* T0STA[CLRI] - T0CLRI write sync in progress.. */ +#define T0STA_CLRI_BBA (*(volatile unsigned long *) 0x4200039C) +#define T0STA_CLRI_MSK (0x1 << 7 ) +#define T0STA_CLRI (0x1 << 7 ) +#define T0STA_CLRI_CLR (0x0 << 7 ) /* CLR. Cleared when the interrupt is cleared in the timer clock domain. */ +#define T0STA_CLRI_SET (0x1 << 7 ) /* SET. Set automatically when the T0CLRI value is being updated in the timer clock domain, indicating that the timer’s configuration is not yet valid. */ + +/* T0STA[CON] - T0CON write sync in progress. */ +#define T0STA_CON_BBA (*(volatile unsigned long *) 0x42000398) +#define T0STA_CON_MSK (0x1 << 6 ) +#define T0STA_CON (0x1 << 6 ) +#define T0STA_CON_CLR (0x0 << 6 ) /* CLR. Timer ready to receive commands to T0CON. The previous change of T0CON has been synchronized in the timer clock domain. */ +#define T0STA_CON_SET (0x1 << 6 ) /* SET. Timer not ready to receive commands to T0CON. Previous change of the T0CON value has not been synchronized in the timer clock domain. */ + +/* T0STA[CAP] - Capture event pending. */ +#define T0STA_CAP_BBA (*(volatile unsigned long *) 0x42000384) +#define T0STA_CAP_MSK (0x1 << 1 ) +#define T0STA_CAP (0x1 << 1 ) +#define T0STA_CAP_CLR (0x0 << 1 ) /* CLR. No capture event is pending. */ +#define T0STA_CAP_SET (0x1 << 1 ) /* SET. Capture event is pending. */ + +/* T0STA[TMOUT] - Time out event occurred. */ +#define T0STA_TMOUT_BBA (*(volatile unsigned long *) 0x42000380) +#define T0STA_TMOUT_MSK (0x1 << 0 ) +#define T0STA_TMOUT (0x1 << 0 ) +#define T0STA_TMOUT_CLR (0x0 << 0 ) /* CLR. No timeout event has occurred. */ +#define T0STA_TMOUT_SET (0x1 << 0 ) /* SET. Timeout event has occurred. For count-up mode, this is when the counter reaches full scale. For count-down mode, this is when the counter reaches 0. */ +#if (__NO_MMR_STRUCTS__==1) + +#define T1LD (*(volatile unsigned short int *) 0x40000400) +#define T1VAL (*(volatile unsigned short int *) 0x40000404) +#define T1CON (*(volatile unsigned short int *) 0x40000408) +#define T1CLRI (*(volatile unsigned short int *) 0x4000040C) +#define T1CAP (*(volatile unsigned short int *) 0x40000410) +#define T1STA (*(volatile unsigned short int *) 0x4000041C) +#endif // (__NO_MMR_STRUCTS__==1) + +/* Reset Value for T1LD*/ +#define T1LD_RVAL 0x0 + +/* T1LD[VALUE] - Load value. */ +#define T1LD_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T1VAL*/ +#define T1VAL_RVAL 0x0 + +/* T1VAL[VALUE] - Current counter value. */ +#define T1VAL_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T1CON*/ +#define T1CON_RVAL 0xA + +/* T1CON[EVENTEN] - Enable event bit. */ +#define T1CON_EVENTEN_BBA (*(volatile unsigned long *) 0x42008130) +#define T1CON_EVENTEN_MSK (0x1 << 12 ) +#define T1CON_EVENTEN (0x1 << 12 ) +#define T1CON_EVENTEN_DIS (0x0 << 12 ) /* DIS. Cleared by user. */ +#define T1CON_EVENTEN_EN (0x1 << 12 ) /* EN. Enable time capture of an event. */ + +/* T1CON[EVENT] - Event select bits. Settings not described are reserved and should not be used. */ +#define T1CON_EVENT_MSK (0xF << 8 ) +#define T1CON_EVENT_T0 (0x0 << 8 ) /* T0. Timer 0. */ +#define T1CON_EVENT_SPI0 (0x1 << 8 ) /* SPI0. SPI0 Peripheral. */ +#define T1CON_EVENT_SPI1 (0x2 << 8 ) /* SPI1. SPI1 Peripheral. */ +#define T1CON_EVENT_I2CS (0x3 << 8 ) /* I2CS. I2C slave peripheral. */ +#define T1CON_EVENT_I2CM (0x4 << 8 ) /* I2CM. I2C master peripheral. */ +#define T1CON_EVENT_DMAERR (0x6 << 8 ) /* DMAERR. DMA error */ +#define T1CON_EVENT_DMADONE (0x7 << 8 ) /* DMADONE. Completion of transfer on any of the DMA channel. */ +#define T1CON_EVENT_EXT1 (0x8 << 8 ) /* EXT1. External interrupt 1. */ +#define T1CON_EVENT_EXT2 (0x9 << 8 ) /* EXT2. External interrupt 2. */ +#define T1CON_EVENT_EXT3 (0xA << 8 ) /* EXT3. External interrupt 3. */ +#define T1CON_EVENT_PWMTRIP (0xB << 8 ) /* PWMTRIP. */ +#define T1CON_EVENT_PWM0 (0xC << 8 ) /* PWM0. PWM pair 0. */ +#define T1CON_EVENT_PWM1 (0xD << 8 ) /* PWM1. PWM pair 1. */ +#define T1CON_EVENT_PWM2 (0xE << 8 ) /* PWM2. PWM pair 2. */ +#define T1CON_EVENT_PWM3 (0xF << 8 ) /* PWM3. PWM pair 3. */ + +/* T1CON[RLD] - Reload control bit for periodic mode. */ +#define T1CON_RLD_BBA (*(volatile unsigned long *) 0x4200811C) +#define T1CON_RLD_MSK (0x1 << 7 ) +#define T1CON_RLD (0x1 << 7 ) +#define T1CON_RLD_DIS (0x0 << 7 ) /* DIS. Reload on a time out. */ +#define T1CON_RLD_EN (0x1 << 7 ) /* EN. Reload the counter on a write to T1CLRI. */ + +/* T1CON[CLK] - Clock select. */ +#define T1CON_CLK_MSK (0x3 << 5 ) +#define T1CON_CLK_UCLK (0x0 << 5 ) /* UCLK. Undivided system clock. */ +#define T1CON_CLK_PCLK (0x1 << 5 ) /* PCLK. Peripheral clock. */ +#define T1CON_CLK_LFOSC (0x2 << 5 ) /* LFOSC. 32 kHz internal oscillator. */ +#define T1CON_CLK_LFXTAL (0x3 << 5 ) /* LFXTAL. 32 kHz external crystal. */ + +/* T1CON[ENABLE] - Timer enable bit. */ +#define T1CON_ENABLE_BBA (*(volatile unsigned long *) 0x42008110) +#define T1CON_ENABLE_MSK (0x1 << 4 ) +#define T1CON_ENABLE (0x1 << 4 ) +#define T1CON_ENABLE_DIS (0x0 << 4 ) /* DIS. Disable the timer. Clearing this bit resets the timer, including the T1VAL register. */ +#define T1CON_ENABLE_EN (0x1 << 4 ) /* EN. Enable the timer. The timer starts counting from its initial value, 0 if count-up mode or 0xFFFF if count-down mode. */ + +/* T1CON[MOD] - Timer mode. */ +#define T1CON_MOD_BBA (*(volatile unsigned long *) 0x4200810C) +#define T1CON_MOD_MSK (0x1 << 3 ) +#define T1CON_MOD (0x1 << 3 ) +#define T1CON_MOD_FREERUN (0x0 << 3 ) /* FREERUN. Operate in free running mode. */ +#define T1CON_MOD_PERIODIC (0x1 << 3 ) /* PERIODIC. Operate in periodic mode. */ + +/* T1CON[UP] - Count down/up. */ +#define T1CON_UP_BBA (*(volatile unsigned long *) 0x42008108) +#define T1CON_UP_MSK (0x1 << 2 ) +#define T1CON_UP (0x1 << 2 ) +#define T1CON_UP_DIS (0x0 << 2 ) /* DIS. Timer to count down. */ +#define T1CON_UP_EN (0x1 << 2 ) /* EN. Timer to count up. */ + +/* T1CON[PRE] - Prescaler. */ +#define T1CON_PRE_MSK (0x3 << 0 ) +#define T1CON_PRE_DIV1 (0x0 << 0 ) /* DIV1. Source clock/1.If the selected clock source is UCLK or PCLK this setting results in a prescaler of 4. */ +#define T1CON_PRE_DIV16 (0x1 << 0 ) /* DIV16. Source clock/16. */ +#define T1CON_PRE_DIV256 (0x2 << 0 ) /* DIV256. Source clock/256. */ +#define T1CON_PRE_DIV32768 (0x3 << 0 ) /* DIV32768. Source clock/32768. */ + +/* Reset Value for T1CLRI*/ +#define T1CLRI_RVAL 0x0 + +/* T1CLRI[CAP] - Clear captured event interrupt. */ +#define T1CLRI_CAP_BBA (*(volatile unsigned long *) 0x42008184) +#define T1CLRI_CAP_MSK (0x1 << 1 ) +#define T1CLRI_CAP (0x1 << 1 ) +#define T1CLRI_CAP_CLR (0x1 << 1 ) /* CLR. Clear a captured event interrupt. This bit always reads 0. */ + +/* T1CLRI[TMOUT] - Clear timeout interrupt. */ +#define T1CLRI_TMOUT_BBA (*(volatile unsigned long *) 0x42008180) +#define T1CLRI_TMOUT_MSK (0x1 << 0 ) +#define T1CLRI_TMOUT (0x1 << 0 ) +#define T1CLRI_TMOUT_CLR (0x1 << 0 ) /* CLR. Clear a timeout interrupt. This bit always reads 0. */ + +/* Reset Value for T1CAP*/ +#define T1CAP_RVAL 0x0 + +/* T1CAP[VALUE] - Capture value. */ +#define T1CAP_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T1STA*/ +#define T1STA_RVAL 0x0 + +/* T1STA[CLRI] - T1CLRI write sync in progress. */ +#define T1STA_CLRI_BBA (*(volatile unsigned long *) 0x4200839C) +#define T1STA_CLRI_MSK (0x1 << 7 ) +#define T1STA_CLRI (0x1 << 7 ) +#define T1STA_CLRI_CLR (0x0 << 7 ) /* CLR. Cleared when the interrupt is cleared in the timer clock domain. */ +#define T1STA_CLRI_SET (0x1 << 7 ) /* SET. Set automatically when the T1CLRI value is being updated in the timer clock domain, indicating that the timer’s configuration is not yet valid. */ + +/* T1STA[CON] - T1CON write sync in progress. */ +#define T1STA_CON_BBA (*(volatile unsigned long *) 0x42008398) +#define T1STA_CON_MSK (0x1 << 6 ) +#define T1STA_CON (0x1 << 6 ) +#define T1STA_CON_CLR (0x0 << 6 ) /* CLR. Timer ready to receive commands to T1CON. The previous change of T1CON has been synchronized in the timer clock domain. */ +#define T1STA_CON_SET (0x1 << 6 ) /* SET. Timer not ready to receive commands to T1CON. Previous change of the T1CON value has not been synchronized in the timer clock domain. */ + +/* T1STA[CAP] - Capture event pending. */ +#define T1STA_CAP_BBA (*(volatile unsigned long *) 0x42008384) +#define T1STA_CAP_MSK (0x1 << 1 ) +#define T1STA_CAP (0x1 << 1 ) +#define T1STA_CAP_CLR (0x0 << 1 ) /* CLR. No capture event is pending. */ +#define T1STA_CAP_SET (0x1 << 1 ) /* SET. Capture event is pending. */ + +/* T1STA[TMOUT] - Time out event occurred. */ +#define T1STA_TMOUT_BBA (*(volatile unsigned long *) 0x42008380) +#define T1STA_TMOUT_MSK (0x1 << 0 ) +#define T1STA_TMOUT (0x1 << 0 ) +#define T1STA_TMOUT_CLR (0x0 << 0 ) /* CLR. No timeout event has occurred. */ +#define T1STA_TMOUT_SET (0x1 << 0 ) /* SET. Timeout event has occurred. For count-up mode, this is when the counter reaches full scale. For count-down mode, this is when the counter reaches 0. */ +// ------------------------------------------------------------------------------------------------ +// ----- UART ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief UART (pADI_UART) + */ + +#if (__NO_MMR_STRUCTS__==0) +typedef struct { /*!< pADI_UART Structure */ + + union { + __IO uint8_t COMTX; /*!< Transmit Holding Register */ + __IO uint8_t COMRX; /*!< Receive Buffer Register */ + } ; + __I uint8_t RESERVED0[3]; + __IO uint8_t COMIEN; /*!< Interrupt Enable Register */ + __I uint8_t RESERVED1[3]; + __IO uint8_t COMIIR; /*!< Interrupt Identification Register */ + __I uint8_t RESERVED2[3]; + __IO uint8_t COMLCR; /*!< Line Control Register */ + __I uint8_t RESERVED3[3]; + __IO uint8_t COMMCR; /*!< Module Control Register */ + __I uint8_t RESERVED4[3]; + __IO uint8_t COMLSR; /*!< Line Status Register */ + __I uint8_t RESERVED5[3]; + __IO uint8_t COMMSR; /*!< Modem Status Register */ + __I uint8_t RESERVED6[11]; + __IO uint16_t COMFBR; /*!< Fractional Baud Rate Register. */ + __I uint16_t RESERVED7; + __IO uint16_t COMDIV; /*!< Baud Rate Divider Register */ +} ADI_UART_TypeDef; +#else // (__NO_MMR_STRUCTS__==0) +#define COMTX (*(volatile unsigned char *) 0x40005000) +#define COMRX (*(volatile unsigned char *) 0x40005000) +#define COMIEN (*(volatile unsigned char *) 0x40005004) +#define COMIIR (*(volatile unsigned char *) 0x40005008) +#define COMLCR (*(volatile unsigned char *) 0x4000500C) +#define COMMCR (*(volatile unsigned char *) 0x40005010) +#define COMLSR (*(volatile unsigned char *) 0x40005014) +#define COMMSR (*(volatile unsigned char *) 0x40005018) +#define COMFBR (*(volatile unsigned short int *) 0x40005024) +#define COMDIV (*(volatile unsigned short int *) 0x40005028) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for COMTX*/ +#define COMTX_RVAL 0x0 + +/* COMTX[VALUE] - Transmit Holding Register */ +#define COMTX_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for COMRX*/ +#define COMRX_RVAL 0x0 + +/* COMRX[VALUE] - Receive Buffer Register */ +#define COMRX_VALUE_MSK (0xFF << 0 ) + +/* Reset Value for COMIEN*/ +#define COMIEN_RVAL 0x0 + +/* COMIEN[EDMAR] - DMA requests in transmit mode */ +#define COMIEN_EDMAR_BBA (*(volatile unsigned long *) 0x420A0094) +#define COMIEN_EDMAR_MSK (0x1 << 5 ) +#define COMIEN_EDMAR (0x1 << 5 ) +#define COMIEN_EDMAR_DIS (0x0 << 5 ) /* DIS. Disable. */ +#define COMIEN_EDMAR_EN (0x1 << 5 ) /* EN. Enable. */ + +/* COMIEN[EDMAT] - DMA requests in receive mode */ +#define COMIEN_EDMAT_BBA (*(volatile unsigned long *) 0x420A0090) +#define COMIEN_EDMAT_MSK (0x1 << 4 ) +#define COMIEN_EDMAT (0x1 << 4 ) +#define COMIEN_EDMAT_DIS (0x0 << 4 ) /* DIS. Disable. */ +#define COMIEN_EDMAT_EN (0x1 << 4 ) /* EN. Enable. */ + +/* COMIEN[EDSSI] - Modem status interrupt */ +#define COMIEN_EDSSI_BBA (*(volatile unsigned long *) 0x420A008C) +#define COMIEN_EDSSI_MSK (0x1 << 3 ) +#define COMIEN_EDSSI (0x1 << 3 ) +#define COMIEN_EDSSI_DIS (0x0 << 3 ) /* DIS. Disable. */ +#define COMIEN_EDSSI_EN (0x1 << 3 ) /* EN. Enable. */ + +/* COMIEN[ELSI] - Rx status interrupt */ +#define COMIEN_ELSI_BBA (*(volatile unsigned long *) 0x420A0088) +#define COMIEN_ELSI_MSK (0x1 << 2 ) +#define COMIEN_ELSI (0x1 << 2 ) +#define COMIEN_ELSI_DIS (0x0 << 2 ) /* DIS. Disable. */ +#define COMIEN_ELSI_EN (0x1 << 2 ) /* EN. Enable. */ + +/* COMIEN[ETBEI] - Transmit buffer empty interrupt */ +#define COMIEN_ETBEI_BBA (*(volatile unsigned long *) 0x420A0084) +#define COMIEN_ETBEI_MSK (0x1 << 1 ) +#define COMIEN_ETBEI (0x1 << 1 ) +#define COMIEN_ETBEI_DIS (0x0 << 1 ) /* DIS. Disable. */ +#define COMIEN_ETBEI_EN (0x1 << 1 ) /* EN. Enable the transmit interrupt. An interrupt is generated when the COMTX register is empty. Note that if the COMTX is already empty when enabling this bit, an interrupt is generated immediately. */ + +/* COMIEN[ERBFI] - Receive buffer full interrupt */ +#define COMIEN_ERBFI_BBA (*(volatile unsigned long *) 0x420A0080) +#define COMIEN_ERBFI_MSK (0x1 << 0 ) +#define COMIEN_ERBFI (0x1 << 0 ) +#define COMIEN_ERBFI_DIS (0x0 << 0 ) /* DIS. Disable. */ +#define COMIEN_ERBFI_EN (0x1 << 0 ) /* EN. Enable the receive interrupt. An interrupt is generated when the COMRX register is loaded with the received data. Note that if the COMRX is already full when enabling this bit, an interrupt is generated immediately. */ + +/* Reset Value for COMIIR*/ +#define COMIIR_RVAL 0x1 + +/* COMIIR[STA] - Status bits. */ +#define COMIIR_STA_MSK (0x3 << 1 ) +#define COMIIR_STA_MODEMSTATUS (0x0 << 1 ) /* MODEMSTATUS. Modem status interrupt. */ +#define COMIIR_STA_TXBUFEMPTY (0x1 << 1 ) /* TXBUFEMPTY. Transmit buffer empty interrupt. */ +#define COMIIR_STA_RXBUFFULL (0x2 << 1 ) /* RXBUFFULL. Receive buffer full interrupt. Read COMRX register to clear. */ +#define COMIIR_STA_RXLINESTATUS (0x3 << 1 ) /* RXLINESTATUS. Receive line status interrupt. Read COMLSR register to clear. */ + +/* COMIIR[NINT] - Interrupt flag. */ +#define COMIIR_NINT_BBA (*(volatile unsigned long *) 0x420A0100) +#define COMIIR_NINT_MSK (0x1 << 0 ) +#define COMIIR_NINT (0x1 << 0 ) +#define COMIIR_NINT_CLR (0x0 << 0 ) /* CLR. Indicates any of the following: receive buffer full, transmit buffer empty, line status, or modem status interrupt occurred. */ +#define COMIIR_NINT_SET (0x1 << 0 ) /* SET. There is no interrupt (default). */ + +/* Reset Value for COMLCR*/ +#define COMLCR_RVAL 0x0 + +/* COMLCR[BRK] - Set Break. */ +#define COMLCR_BRK_BBA (*(volatile unsigned long *) 0x420A0198) +#define COMLCR_BRK_MSK (0x1 << 6 ) +#define COMLCR_BRK (0x1 << 6 ) +#define COMLCR_BRK_DIS (0x0 << 6 ) /* DIS to operate in normal mode. */ +#define COMLCR_BRK_EN (0x1 << 6 ) /* EN to force TxD to 0. */ + +/* COMLCR[SP] - Stick Parity. */ +#define COMLCR_SP_BBA (*(volatile unsigned long *) 0x420A0194) +#define COMLCR_SP_MSK (0x1 << 5 ) +#define COMLCR_SP (0x1 << 5 ) +#define COMLCR_SP_DIS (0x0 << 5 ) /* DIS. Parity is not forced based on EPS and PEN values. */ +#define COMLCR_SP_EN (0x1 << 5 ) /* EN. Force parity to defined values based on EPS and PEN values. EPS = 1 and PEN = 1, parity forced to 1 EPS = 0 and PEN = 1, parity forced to 0 EPS = X and PEN = 0, no parity transmitted. */ + +/* COMLCR[EPS] - Even Parity Select Bit. */ +#define COMLCR_EPS_BBA (*(volatile unsigned long *) 0x420A0190) +#define COMLCR_EPS_MSK (0x1 << 4 ) +#define COMLCR_EPS (0x1 << 4 ) +#define COMLCR_EPS_DIS (0x0 << 4 ) /* DIS. Odd parity. */ +#define COMLCR_EPS_EN (0x1 << 4 ) /* EN. Even parity. */ + +/* COMLCR[PEN] - Parity Enable Bit. */ +#define COMLCR_PEN_BBA (*(volatile unsigned long *) 0x420A018C) +#define COMLCR_PEN_MSK (0x1 << 3 ) +#define COMLCR_PEN (0x1 << 3 ) +#define COMLCR_PEN_DIS (0x0 << 3 ) /* DIS. No parity transmission or checking. */ +#define COMLCR_PEN_EN (0x1 << 3 ) /* EN. Transmit and check the parity bit. */ + +/* COMLCR[STOP] - Stop Bit. */ +#define COMLCR_STOP_BBA (*(volatile unsigned long *) 0x420A0188) +#define COMLCR_STOP_MSK (0x1 << 2 ) +#define COMLCR_STOP (0x1 << 2 ) +#define COMLCR_STOP_DIS (0x0 << 2 ) /* DIS. Generate one stop bit in the transmitted data. */ +#define COMLCR_STOP_EN (0x1 << 2 ) /* EN. Transmit 1.5 stop bits if the word length is 5 bits, or 2 stop bits if the word length is 6, 7, or 8 bits. The receiver checks the first stop bit only, regardless of the number of stop bits selected. */ + +/* COMLCR[WLS] - Word Length Select Bits. */ +#define COMLCR_WLS_MSK (0x3 << 0 ) +#define COMLCR_WLS_5BITS (0x0 << 0 ) /* 5BITS. 5 bits. */ +#define COMLCR_WLS_6BITS (0x1 << 0 ) /* 6BITS. 6 bits. */ +#define COMLCR_WLS_7BITS (0x2 << 0 ) /* 7BITS. 7 bits. */ +#define COMLCR_WLS_8BITS (0x3 << 0 ) /* 8BITS. 8 bits. */ + +/* Reset Value for COMMCR*/ +#define COMMCR_RVAL 0x0 + +/* COMMCR[LOOPBACK] - Loop Back. */ +#define COMMCR_LOOPBACK_BBA (*(volatile unsigned long *) 0x420A0210) +#define COMMCR_LOOPBACK_MSK (0x1 << 4 ) +#define COMMCR_LOOPBACK (0x1 << 4 ) +#define COMMCR_LOOPBACK_DIS (0x0 << 4 ) /* DIS. Normal mode. */ +#define COMMCR_LOOPBACK_EN (0x1 << 4 ) /* EN. Enable loopback mode. */ + +/* COMMCR[RTS] - Request To Send output control bit. */ +#define COMMCR_RTS_BBA (*(volatile unsigned long *) 0x420A0204) +#define COMMCR_RTS_MSK (0x1 << 1 ) +#define COMMCR_RTS (0x1 << 1 ) +#define COMMCR_RTS_DIS (0x0 << 1 ) /* DIS. Force the RTS output to 1. */ +#define COMMCR_RTS_EN (0x1 << 1 ) /* EN. Force the RTS output to 0. */ + +/* Reset Value for COMLSR*/ +#define COMLSR_RVAL 0x60 + +/* COMLSR[TEMT] - COMTX and Shift Register Empty Status Bit. */ +#define COMLSR_TEMT_BBA (*(volatile unsigned long *) 0x420A0298) +#define COMLSR_TEMT_MSK (0x1 << 6 ) +#define COMLSR_TEMT (0x1 << 6 ) +#define COMLSR_TEMT_CLR (0x0 << 6 ) /* CLR. Cleared when writing to COMTX. */ +#define COMLSR_TEMT_SET (0x1 << 6 ) /* SET. If COMTX and the shift register are empty, this bit indicates that the data has been transmitted, that is, it is no longer present in the shift register (default). */ + +/* COMLSR[THRE] - COMTX Empty Status Bit. */ +#define COMLSR_THRE_BBA (*(volatile unsigned long *) 0x420A0294) +#define COMLSR_THRE_MSK (0x1 << 5 ) +#define COMLSR_THRE (0x1 << 5 ) +#define COMLSR_THRE_CLR (0x0 << 5 ) /* CLR. Cleared when writing to COMTX. */ +#define COMLSR_THRE_SET (0x1 << 5 ) /* SET. If COMTX is empty, COMTX can be written as soon as this bit is set. The previous data may not have been transmitted yet and can still be present in the shift register (default). */ + +/* COMLSR[BI] - Break Indicator. */ +#define COMLSR_BI_BBA (*(volatile unsigned long *) 0x420A0290) +#define COMLSR_BI_MSK (0x1 << 4 ) +#define COMLSR_BI (0x1 << 4 ) +#define COMLSR_BI_CLR (0x0 << 4 ) /* CLR. Cleared automatically. */ +#define COMLSR_BI_SET (0x1 << 4 ) /* SET. Set when UART RXD is held low for more than the maximum word length. */ + +/* COMLSR[FE] - Framing Error. */ +#define COMLSR_FE_BBA (*(volatile unsigned long *) 0x420A028C) +#define COMLSR_FE_MSK (0x1 << 3 ) +#define COMLSR_FE (0x1 << 3 ) +#define COMLSR_FE_CLR (0x0 << 3 ) /* CLR. Cleared automatically. */ +#define COMLSR_FE_SET (0x1 << 3 ) /* SET. Set when the stop bit is invalid. */ + +/* COMLSR[PE] - Parity Error. */ +#define COMLSR_PE_BBA (*(volatile unsigned long *) 0x420A0288) +#define COMLSR_PE_MSK (0x1 << 2 ) +#define COMLSR_PE (0x1 << 2 ) +#define COMLSR_PE_CLR (0x0 << 2 ) /* CLR. Cleared automatically. */ +#define COMLSR_PE_SET (0x1 << 2 ) /* SET. Set when a parity error occurs. */ + +/* COMLSR[OE] - Overrun Error. */ +#define COMLSR_OE_BBA (*(volatile unsigned long *) 0x420A0284) +#define COMLSR_OE_MSK (0x1 << 1 ) +#define COMLSR_OE (0x1 << 1 ) +#define COMLSR_OE_CLR (0x0 << 1 ) /* CLR. Cleared automatically. */ +#define COMLSR_OE_SET (0x1 << 1 ) /* SET. Set automatically if data is overwritten before being read. */ + +/* COMLSR[DR] - Data Ready. */ +#define COMLSR_DR_BBA (*(volatile unsigned long *) 0x420A0280) +#define COMLSR_DR_MSK (0x1 << 0 ) +#define COMLSR_DR (0x1 << 0 ) +#define COMLSR_DR_CLR (0x0 << 0 ) /* CLR. Cleared by reading COMRX. */ +#define COMLSR_DR_SET (0x1 << 0 ) /* SET. Set automatically when COMRX is full. */ + +/* Reset Value for COMMSR*/ +#define COMMSR_RVAL 0x0 + +/* COMMSR[CTS] - Clear To Send signal status bit. */ +#define COMMSR_CTS_BBA (*(volatile unsigned long *) 0x420A0310) +#define COMMSR_CTS_MSK (0x1 << 4 ) +#define COMMSR_CTS (0x1 << 4 ) +#define COMMSR_CTS_CLR (0x0 << 4 ) /* CLR. Cleared to 0 when CTS input is logic high. */ +#define COMMSR_CTS_SET (0x1 << 4 ) /* SET. Set to 1 when CTS input is logic low. */ + +/* COMMSR[DCTS] - Delta CTS */ +#define COMMSR_DCTS_BBA (*(volatile unsigned long *) 0x420A0300) +#define COMMSR_DCTS_MSK (0x1 << 0 ) +#define COMMSR_DCTS (0x1 << 0 ) +#define COMMSR_DCTS_DIS (0x0 << 0 ) /* DIS. Cleared automatically by reading COMMSR. */ +#define COMMSR_DCTS_EN (0x1 << 0 ) /* EN. Set automatically if CTS changed state since COMMSR last read. */ + +/* Reset Value for COMFBR*/ +#define COMFBR_RVAL 0x0 + +/* COMFBR[ENABLE] - Fractional baud rate generator enable bit. Used for more accurate baud rate generation. */ +#define COMFBR_ENABLE_BBA (*(volatile unsigned long *) 0x420A04BC) +#define COMFBR_ENABLE_MSK (0x1 << 15 ) +#define COMFBR_ENABLE (0x1 << 15 ) +#define COMFBR_ENABLE_DIS (0x0 << 15 ) /* DIS. Disable. */ +#define COMFBR_ENABLE_EN (0x1 << 15 ) /* EN. Enable. */ + +/* COMFBR[DIVM] - Fractional baud rate M divide bits (1 to 3). These bits should not be set to 0. */ +#define COMFBR_DIVM_MSK (0x3 << 11 ) + +/* COMFBR[DIVN] - Fractional baud rate N divide bits (0 to 2047). */ +#define COMFBR_DIVN_MSK (0x7FF << 0 ) + +/* Reset Value for COMDIV*/ +#define COMDIV_RVAL 0x1 + +/* COMDIV[VALUE] - Sets the baud rate. The COMDIV register should not be 0. */ +#define COMDIV_VALUE_MSK (0xFFFF << 0 ) +// ------------------------------------------------------------------------------------------------ +// ----- WUT ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief WakeUp Timer (pADI_WUT) + */ + +#if (__NO_MMR_STRUCTS__==0) +typedef struct { /*!< pADI_WUT Structure */ + __IO uint16_t T2VAL0; /*!< Current Wake-Up Timer Value LSB */ + __I uint16_t RESERVED0; + __IO uint16_t T2VAL1; /*!< Current Wake-Up Timer Value MSB */ + __I uint16_t RESERVED1; + __IO uint16_t T2CON; /*!< Control Register */ + __I uint16_t RESERVED2; + __IO uint16_t T2INC; /*!< 12-bit Interval Register for Wake-Up Field A */ + __I uint16_t RESERVED3; + __IO uint16_t T2WUFB0; /*!< Wake-Up Field B LSB */ + __I uint16_t RESERVED4; + __IO uint16_t T2WUFB1; /*!< Wake-Up Field B MSB */ + __I uint16_t RESERVED5; + __IO uint16_t T2WUFC0; /*!< Wake-Up Field C LSB */ + __I uint16_t RESERVED6; + __IO uint16_t T2WUFC1; /*!< Wake-Up Field C MSB */ + __I uint16_t RESERVED7; + __IO uint16_t T2WUFD0; /*!< Wake-UpField D LSB */ + __I uint16_t RESERVED8; + __IO uint16_t T2WUFD1; /*!< Wake-Up Field D MSB */ + __I uint16_t RESERVED9; + __IO uint16_t T2IEN; /*!< Interrupt Enable */ + __I uint16_t RESERVED10; + __IO uint16_t T2STA; /*!< Status */ + __I uint16_t RESERVED11; + __IO uint16_t T2CLRI; /*!< Clear Interrupts */ + __I uint16_t RESERVED12[5]; + __IO uint16_t T2WUFA0; /*!< Wake-Up Field A LSB */ + __I uint16_t RESERVED13; + __IO uint16_t T2WUFA1; /*!< Wake-Up Field A MSB */ +} ADI_WUT_TypeDef; +#else // (__NO_MMR_STRUCTS__==0) +#define T2VAL0 (*(volatile unsigned short int *) 0x40002500) +#define T2VAL1 (*(volatile unsigned short int *) 0x40002504) +#define T2CON (*(volatile unsigned short int *) 0x40002508) +#define T2INC (*(volatile unsigned short int *) 0x4000250C) +#define T2WUFB0 (*(volatile unsigned short int *) 0x40002510) +#define T2WUFB1 (*(volatile unsigned short int *) 0x40002514) +#define T2WUFC0 (*(volatile unsigned short int *) 0x40002518) +#define T2WUFC1 (*(volatile unsigned short int *) 0x4000251C) +#define T2WUFD0 (*(volatile unsigned short int *) 0x40002520) +#define T2WUFD1 (*(volatile unsigned short int *) 0x40002524) +#define T2IEN (*(volatile unsigned short int *) 0x40002528) +#define T2STA (*(volatile unsigned short int *) 0x4000252C) +#define T2CLRI (*(volatile unsigned short int *) 0x40002530) +#define T2WUFA0 (*(volatile unsigned short int *) 0x4000253C) +#define T2WUFA1 (*(volatile unsigned short int *) 0x40002540) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for T2VAL0*/ +#define T2VAL0_RVAL 0x0 + +/* T2VAL0[VALUE] - Current Wake-Up timer value (bits 15 to 0). */ +#define T2VAL0_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T2VAL1*/ +#define T2VAL1_RVAL 0x0 + +/* T2VAL1[VALUE] - Current Wake-Up timer value (bits 31 to 16). */ +#define T2VAL1_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T2CON*/ +#define T2CON_RVAL 0x40 + +/* T2CON[STOPINC] - Allows the user to update the interval register safely. */ +#define T2CON_STOPINC_BBA (*(volatile unsigned long *) 0x4204A12C) +#define T2CON_STOPINC_MSK (0x1 << 11 ) +#define T2CON_STOPINC (0x1 << 11 ) +#define T2CON_STOPINC_DIS (0x0 << 11 ) /* DIS. Allows the wake-up field A to be updated by hardware. */ +#define T2CON_STOPINC_EN (0x1 << 11 ) /* EN. Prevents wake-up field A being automatically updated by hardware.This allows user software to update the T2INC register value. */ + +/* T2CON[CLK] - Clock select. */ +#define T2CON_CLK_MSK (0x3 << 9 ) +#define T2CON_CLK_PCLK (0x0 << 9 ) /* PCLK. Peripheral clock. */ +#define T2CON_CLK_LFXTAL (0x1 << 9 ) /* LFXTAL. 32 kHz external crystal. */ +#define T2CON_CLK_LFOSC (0x2 << 9 ) /* LFOSC. 32 kHz internal oscillator. */ +#define T2CON_CLK_EXTCLK (0x3 << 9 ) /* EXTCLK. External clock applied on P0.5. */ + +/* T2CON[WUEN] - Wake-up enable bits for time field values. */ +#define T2CON_WUEN_BBA (*(volatile unsigned long *) 0x4204A120) +#define T2CON_WUEN_MSK (0x1 << 8 ) +#define T2CON_WUEN (0x1 << 8 ) +#define T2CON_WUEN_DIS (0x0 << 8 ) /* DIS. Disable asynchronous Wake-Up timer. Interrupt conditions will not wake-up the part from sleep mode. */ +#define T2CON_WUEN_EN (0x1 << 8 ) /* EN. Enable asynchronous Wake-Up timer even when the core clock is off. Once the timer value equals any of the interrupt enabled compare field, a wake-up signal is generated. */ + +/* T2CON[ENABLE] - Timer enable bit. */ +#define T2CON_ENABLE_BBA (*(volatile unsigned long *) 0x4204A11C) +#define T2CON_ENABLE_MSK (0x1 << 7 ) +#define T2CON_ENABLE (0x1 << 7 ) +#define T2CON_ENABLE_DIS (0x0 << 7 ) /* DIS. Disable the timer. */ +#define T2CON_ENABLE_EN (0x1 << 7 ) /* EN. Enable the timer. When enabled wait for T2STA[8] to clear before continuing. */ + +/* T2CON[MOD] - Timer free run enable. */ +#define T2CON_MOD_BBA (*(volatile unsigned long *) 0x4204A118) +#define T2CON_MOD_MSK (0x1 << 6 ) +#define T2CON_MOD (0x1 << 6 ) +#define T2CON_MOD_PERIODIC (0x0 << 6 ) /* PERIODIC. Operate in periodic mode. Counts up to the value in T2WUFD */ +#define T2CON_MOD_FREERUN (0x1 << 6 ) /* FREERUN. Operate in free running mode (default). Counts from 0 to FFFF FFFF and starts again at 0. */ + +/* T2CON[FREEZE] - Freeze enable bit. */ +#define T2CON_FREEZE_BBA (*(volatile unsigned long *) 0x4204A10C) +#define T2CON_FREEZE_MSK (0x1 << 3 ) +#define T2CON_FREEZE (0x1 << 3 ) +#define T2CON_FREEZE_DIS (0x0 << 3 ) /* DIS. Disable this feature. */ +#define T2CON_FREEZE_EN (0x1 << 3 ) /* EN. Enable the freeze of the high 16 bits after the lower bits have been read from T2VAL0. This ensures that the software reads an atomic shot of the timer. The entire T2VAL register unfreezes after the high bits (T2VAL1) have been read. */ + +/* T2CON[PRE] - Prescaler. */ +#define T2CON_PRE_MSK (0x3 << 0 ) +#define T2CON_PRE_DIV1 (0x0 << 0 ) /* DIV1. Source clock/1. If the selected clock source is PCLK this setting results in a prescaler of 4. */ +#define T2CON_PRE_DIV16 (0x1 << 0 ) /* DIV16. Source clock/16. */ +#define T2CON_PRE_DIV256 (0x2 << 0 ) /* DIV256. Source clock/256. */ +#define T2CON_PRE_DIV32768 (0x3 << 0 ) /* DIV32768. Source clock/32768. */ + +/* Reset Value for T2INC*/ +#define T2INC_RVAL 0xC8 + +/* T2INC[VALUE] - Wake-up interval */ +#define T2INC_VALUE_MSK (0xFFF << 0 ) + +/* Reset Value for T2WUFB0*/ +#define T2WUFB0_RVAL 0x1FFF + +/* T2WUFB0[VALUE] - Lower 16 bits of Wake-Up Field B */ +#define T2WUFB0_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T2WUFB1*/ +#define T2WUFB1_RVAL 0x0 + +/* T2WUFB1[VALUE] - Upper 16 bits of Wake-Up Field B */ +#define T2WUFB1_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T2WUFC0*/ +#define T2WUFC0_RVAL 0x2FFF + +/* T2WUFC0[VALUE] - Lower 16 bits of Wake-Up Field C */ +#define T2WUFC0_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T2WUFC1*/ +#define T2WUFC1_RVAL 0x0 + +/* T2WUFC1[VALUE] - Upper 16 bits of Wake-Up Field C */ +#define T2WUFC1_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T2WUFD0*/ +#define T2WUFD0_RVAL 0x3FFF + +/* T2WUFD0[VALUE] - Lower 16 bits of Wake-Up Field D */ +#define T2WUFD0_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T2WUFD1*/ +#define T2WUFD1_RVAL 0x0 + +/* T2WUFD1[VALUE] - Upper 16 bits of Wake-Up Field D */ +#define T2WUFD1_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T2IEN*/ +#define T2IEN_RVAL 0x0 + +/* T2IEN[ROLL] - Interrupt enable bit when the counter rolls over. Only occurs in free running mode. */ +#define T2IEN_ROLL_BBA (*(volatile unsigned long *) 0x4204A510) +#define T2IEN_ROLL_MSK (0x1 << 4 ) +#define T2IEN_ROLL (0x1 << 4 ) +#define T2IEN_ROLL_DIS (0x0 << 4 ) /* DIS. Disable the roll over interrupt. */ +#define T2IEN_ROLL_EN (0x1 << 4 ) /* EN. Generate an interrupt when Timer2 rolls over. */ + +/* T2IEN[WUFD] - T2WUFD interrupt enable */ +#define T2IEN_WUFD_BBA (*(volatile unsigned long *) 0x4204A50C) +#define T2IEN_WUFD_MSK (0x1 << 3 ) +#define T2IEN_WUFD (0x1 << 3 ) +#define T2IEN_WUFD_DIS (0x0 << 3 ) /* DIS. Disable T2WUFD interrupt. */ +#define T2IEN_WUFD_EN (0x1 << 3 ) /* EN. Generate an interrupt when T2VAL reaches T2WUFD. */ + +/* T2IEN[WUFC] - T2WUFC interrupt enable */ +#define T2IEN_WUFC_BBA (*(volatile unsigned long *) 0x4204A508) +#define T2IEN_WUFC_MSK (0x1 << 2 ) +#define T2IEN_WUFC (0x1 << 2 ) +#define T2IEN_WUFC_DIS (0x0 << 2 ) /* DIS. Disable T2WUFC interrupt. */ +#define T2IEN_WUFC_EN (0x1 << 2 ) /* EN. Generate an interrupt when T2VAL reaches T2WUFC. */ + +/* T2IEN[WUFB] - T2WUFB interrupt enable */ +#define T2IEN_WUFB_BBA (*(volatile unsigned long *) 0x4204A504) +#define T2IEN_WUFB_MSK (0x1 << 1 ) +#define T2IEN_WUFB (0x1 << 1 ) +#define T2IEN_WUFB_DIS (0x0 << 1 ) /* DIS. Disable T2WUFB interrupt. */ +#define T2IEN_WUFB_EN (0x1 << 1 ) /* EN. Generate an interrupt when T2VAL reaches T2WUFB. */ + +/* T2IEN[WUFA] - T2WUFA interrupt enable */ +#define T2IEN_WUFA_BBA (*(volatile unsigned long *) 0x4204A500) +#define T2IEN_WUFA_MSK (0x1 << 0 ) +#define T2IEN_WUFA (0x1 << 0 ) +#define T2IEN_WUFA_DIS (0x0 << 0 ) /* DIS. Disable T2WUFA interrupt. */ +#define T2IEN_WUFA_EN (0x1 << 0 ) /* EN. Generate an interrupt when T2VAL reaches T2WUFA. */ + +/* Reset Value for T2STA*/ +#define T2STA_RVAL 0x0 + +/* T2STA[CON] - Indicates when a change in the enable bit is synchronized to the 32 kHz clock domain (Done automatically) */ +#define T2STA_CON_BBA (*(volatile unsigned long *) 0x4204A5A0) +#define T2STA_CON_MSK (0x1 << 8 ) +#define T2STA_CON (0x1 << 8 ) +#define T2STA_CON_CLR (0x0 << 8 ) /* CLR. It returns low when the change in the Enable bit has been synchronised to the 32 kHz clock domain. */ +#define T2STA_CON_SET (0x1 << 8 ) /* SET. This bit is set high when the Enable bit (bit 5) in the Control register is set or cleared and it is not synchronised to tthe 32 kHz clock. */ + +/* T2STA[FREEZE] - Status of T2VAL freeze */ +#define T2STA_FREEZE_BBA (*(volatile unsigned long *) 0x4204A59C) +#define T2STA_FREEZE_MSK (0x1 << 7 ) +#define T2STA_FREEZE (0x1 << 7 ) +#define T2STA_FREEZE_CLR (0x0 << 7 ) /* CLR. Reset low when T2VAL1 is read, indicating T2VAL is unfrozen. */ +#define T2STA_FREEZE_SET (0x1 << 7 ) /* SET. Set high when the T2VAL0 is read, indicating T2VAL is frozen. */ + +/* T2STA[ROLL] - Interrupt status bit for instances when counter rolls over. Only occurs in free running mode. */ +#define T2STA_ROLL_BBA (*(volatile unsigned long *) 0x4204A590) +#define T2STA_ROLL_MSK (0x1 << 4 ) +#define T2STA_ROLL (0x1 << 4 ) +#define T2STA_ROLL_CLR (0x0 << 4 ) /* CLR. Indicate that the timer has not rolled over. */ +#define T2STA_ROLL_SET (0x1 << 4 ) /* SET. Set high when enabled in the interrupt enable register and the T2VALS counter register is equal to all 1s */ + +/* T2STA[WUFD] - T2WUFD interrupt flag */ +#define T2STA_WUFD_BBA (*(volatile unsigned long *) 0x4204A58C) +#define T2STA_WUFD_MSK (0x1 << 3 ) +#define T2STA_WUFD (0x1 << 3 ) +#define T2STA_WUFD_CLR (0x0 << 3 ) /* CLR. Cleared after a write to the corresponding bit in T2CLRI. */ +#define T2STA_WUFD_SET (0x1 << 3 ) /* SET. Indicates that a comparator interrupt has occurred. */ + +/* T2STA[WUFC] - T2WUFC interrupt flag */ +#define T2STA_WUFC_BBA (*(volatile unsigned long *) 0x4204A588) +#define T2STA_WUFC_MSK (0x1 << 2 ) +#define T2STA_WUFC (0x1 << 2 ) +#define T2STA_WUFC_CLR (0x0 << 2 ) /* CLR. Cleared after a write to the corresponding bit in T2CLRI. */ +#define T2STA_WUFC_SET (0x1 << 2 ) /* SET. Indicates that a comparator interrupt has occurred. */ + +/* T2STA[WUFB] - T2WUFB interrupt flag */ +#define T2STA_WUFB_BBA (*(volatile unsigned long *) 0x4204A584) +#define T2STA_WUFB_MSK (0x1 << 1 ) +#define T2STA_WUFB (0x1 << 1 ) +#define T2STA_WUFB_CLR (0x0 << 1 ) /* CLR. Cleared after a write to the corresponding bit in T2CLRI. */ +#define T2STA_WUFB_SET (0x1 << 1 ) /* SET. Indicates that a comparator interrupt has occurred. */ + +/* T2STA[WUFA] - T2WUFA interrupt flag */ +#define T2STA_WUFA_BBA (*(volatile unsigned long *) 0x4204A580) +#define T2STA_WUFA_MSK (0x1 << 0 ) +#define T2STA_WUFA (0x1 << 0 ) +#define T2STA_WUFA_CLR (0x0 << 0 ) /* CLR. Cleared after a write to the corresponding bit in T2CLRI. */ +#define T2STA_WUFA_SET (0x1 << 0 ) /* SET. Indicates that a comparator interrupt has occurred. */ + +/* Reset Value for T2CLRI*/ +#define T2CLRI_RVAL 0x0 + +/* T2CLRI[ROLL] - Clear interrupt on Rollover. Only occurs in free running mode. */ +#define T2CLRI_ROLL_BBA (*(volatile unsigned long *) 0x4204A610) +#define T2CLRI_ROLL_MSK (0x1 << 4 ) +#define T2CLRI_ROLL (0x1 << 4 ) +#define T2CLRI_ROLL_CLR (0x1 << 4 ) /* CLR. Interrupt clear bit for when counter rolls over. */ + +/* T2CLRI[WUFD] - T2WUFD interrupt flag. Cleared automatically after synchronization. */ +#define T2CLRI_WUFD_BBA (*(volatile unsigned long *) 0x4204A60C) +#define T2CLRI_WUFD_MSK (0x1 << 3 ) +#define T2CLRI_WUFD (0x1 << 3 ) +#define T2CLRI_WUFD_CLR (0x1 << 3 ) /* CLR. Clear the T2WUFD interrupt flag. */ + +/* T2CLRI[WUFC] - T2WUFC interrupt flag. Cleared automatically after synchronization. */ +#define T2CLRI_WUFC_BBA (*(volatile unsigned long *) 0x4204A608) +#define T2CLRI_WUFC_MSK (0x1 << 2 ) +#define T2CLRI_WUFC (0x1 << 2 ) +#define T2CLRI_WUFC_CLR (0x1 << 2 ) /* CLR. Clear the T2WUFC interrupt flag. */ + +/* T2CLRI[WUFB] - T2WUFB interrupt flag. Cleared automatically after synchronization. */ +#define T2CLRI_WUFB_BBA (*(volatile unsigned long *) 0x4204A604) +#define T2CLRI_WUFB_MSK (0x1 << 1 ) +#define T2CLRI_WUFB (0x1 << 1 ) +#define T2CLRI_WUFB_CLR (0x1 << 1 ) /* CLR. Clear the T2WUFB interrupt flag. */ + +/* T2CLRI[WUFA] - T2WUFA interrupt flag. Cleared automatically after synchronization. */ +#define T2CLRI_WUFA_BBA (*(volatile unsigned long *) 0x4204A600) +#define T2CLRI_WUFA_MSK (0x1 << 0 ) +#define T2CLRI_WUFA (0x1 << 0 ) +#define T2CLRI_WUFA_CLR (0x1 << 0 ) /* CLR. Clear the T2WUFA interrupt flag. */ + +/* Reset Value for T2WUFA0*/ +#define T2WUFA0_RVAL 0x1900 + +/* T2WUFA0[VALUE] - Lower 16 bits of Compare Register A */ +#define T2WUFA0_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T2WUFA1*/ +#define T2WUFA1_RVAL 0x0 + +/* T2WUFA1[VALUE] - Upper 16 bits of Compare Register A */ +#define T2WUFA1_VALUE_MSK (0xFFFF << 0 ) +// ------------------------------------------------------------------------------------------------ +// ----- WDT ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Watchdog Timer (pADI_WDT) + */ + +#if (__NO_MMR_STRUCTS__==0) +typedef struct { /*!< pADI_WDT Structure */ + __IO uint16_t T3LD; /*!< 16-bit Load Value */ + __I uint16_t RESERVED0; + __IO uint16_t T3VAL; /*!< 16-bit Timer Value */ + __I uint16_t RESERVED1; + __IO uint16_t T3CON; /*!< Control Register */ + __I uint16_t RESERVED2; + __IO uint16_t T3CLRI; /*!< Clear Interrupt Register */ + __I uint16_t RESERVED3[5]; + __IO uint16_t T3STA; /*!< Status Register */ +} ADI_WDT_TypeDef; +#else // (__NO_MMR_STRUCTS__==0) +#define T3LD (*(volatile unsigned short int *) 0x40002580) +#define T3VAL (*(volatile unsigned short int *) 0x40002584) +#define T3CON (*(volatile unsigned short int *) 0x40002588) +#define T3CLRI (*(volatile unsigned short int *) 0x4000258C) +#define T3STA (*(volatile unsigned short int *) 0x40002598) +#endif // (__NO_MMR_STRUCTS__==0) + +/* Reset Value for T3LD*/ +#define T3LD_RVAL 0x1000 + +/* T3LD[VALUE] - Load value. */ +#define T3LD_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T3VAL*/ +#define T3VAL_RVAL 0x1000 + +/* T3VAL[VALUE] - Current counter value. */ +#define T3VAL_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T3CON*/ +#define T3CON_RVAL 0xE9 + +/* T3CON[MOD] - Timer Mode */ +#define T3CON_MOD_BBA (*(volatile unsigned long *) 0x4204B118) +#define T3CON_MOD_MSK (0x1 << 6 ) +#define T3CON_MOD (0x1 << 6 ) +#define T3CON_MOD_Reserved (0x0 << 6 ) /* Reserved */ +#define T3CON_MOD_PERIODIC (0x1 << 6 ) /* PERIODIC: Operate in periodic mode. */ + +/* T3CON[ENABLE] - Timer enable bit. */ +#define T3CON_ENABLE_BBA (*(volatile unsigned long *) 0x4204B114) +#define T3CON_ENABLE_MSK (0x1 << 5 ) +#define T3CON_ENABLE (0x1 << 5 ) +#define T3CON_ENABLE_DIS (0x0 << 5 ) /* DIS. Disable the timer. Clearing this bit resets the timer, including the T0VAL register. */ +#define T3CON_ENABLE_EN (0x1 << 5 ) /* EN. Enable the timer. The timer starts counting from its initial value. */ + +/* T3CON[PRE] - Prescaler. */ +#define T3CON_PRE_MSK (0x3 << 2 ) +#define T3CON_PRE_DIV1 (0x0 << 2 ) /* DIV1. Source clock/1. */ +#define T3CON_PRE_DIV16 (0x1 << 2 ) /* DIV16. Source clock/16. */ +#define T3CON_PRE_DIV256 (0x2 << 2 ) /* DIV256. Source clock/256. */ +#define T3CON_PRE_DIV4096 (0x3 << 2 ) /* DIV4096. Source clock/4096. */ + +/* T3CON[IRQ] - Timer interrupt. */ +#define T3CON_IRQ_BBA (*(volatile unsigned long *) 0x4204B104) +#define T3CON_IRQ_MSK (0x1 << 1 ) +#define T3CON_IRQ (0x1 << 1 ) +#define T3CON_IRQ_DIS (0x0 << 1 ) /* DIS. Generate a reset on a timeout. */ +#define T3CON_IRQ_EN (0x1 << 1 ) /* EN. Generate an interrupt when the timer times out. This feature is available in active mode only and can be used to debug the watchdog timeout events. */ + +/* T3CON[PD] - Stop count in hibernate mode. */ +#define T3CON_PD_BBA (*(volatile unsigned long *) 0x4204B100) +#define T3CON_PD_MSK (0x1 << 0 ) +#define T3CON_PD (0x1 << 0 ) +#define T3CON_PD_DIS (0x0 << 0 ) /* DIS. The timer continues to count when in hibernate mode. */ +#define T3CON_PD_EN (0x1 << 0 ) /* EN. The timer stops counting when in hibernate mode. */ + +/* Reset Value for T3CLRI*/ +#define T3CLRI_RVAL 0x0 + +/* T3CLRI[VALUE] - Clear watchdog. */ +#define T3CLRI_VALUE_MSK (0xFFFF << 0 ) + +/* Reset Value for T3STA*/ +#define T3STA_RVAL 0x20 + +/* T3STA[LOCK] - Lock status bit. */ +#define T3STA_LOCK_BBA (*(volatile unsigned long *) 0x4204B310) +#define T3STA_LOCK_MSK (0x1 << 4 ) +#define T3STA_LOCK (0x1 << 4 ) +#define T3STA_LOCK_CLR (0x0 << 4 ) /* CLR. Cleared after any reset and until user code sets T3CON[5]. */ +#define T3STA_LOCK_SET (0x1 << 4 ) /* SET. Set automatically in hardware when user code sets T3CON[5]. */ + +/* T3STA[CON] - T3CON write sync in progress. */ +#define T3STA_CON_BBA (*(volatile unsigned long *) 0x4204B30C) +#define T3STA_CON_MSK (0x1 << 3 ) +#define T3STA_CON (0x1 << 3 ) +#define T3STA_CON_CLR (0x0 << 3 ) /* CLR. Timer ready to receive commands to T3CON. The previous change of T3CON has been synchronized in the timer clock domain. */ +#define T3STA_CON_SET (0x1 << 3 ) /* SET. Timer not ready to receive commands to T3CON. Previous change of the T3CON value has not been synchronized in the timer clock domain. */ + +/* T3STA[LD] - T3LD write sync in progress. */ +#define T3STA_LD_BBA (*(volatile unsigned long *) 0x4204B308) +#define T3STA_LD_MSK (0x1 << 2 ) +#define T3STA_LD (0x1 << 2 ) +#define T3STA_LD_CLR (0x0 << 2 ) /* CLR. The previous change of T3LD has been synchronized in the timer clock domain. */ +#define T3STA_LD_SET (0x1 << 2 ) /* SET. Previous change of the T3LD value has not been synchronized in the timer clock domain. */ + +/* T3STA[CLRI] - T3CLRI write sync in progress. */ +#define T3STA_CLRI_BBA (*(volatile unsigned long *) 0x4204B304) +#define T3STA_CLRI_MSK (0x1 << 1 ) +#define T3STA_CLRI (0x1 << 1 ) +#define T3STA_CLRI_CLR (0x0 << 1 ) /* CLR. Cleared when the interrupt is cleared in the timer clock domain. */ +#define T3STA_CLRI_SET (0x1 << 1 ) /* SET. Set automatically when the T3CLRI value is being updated in the timer clock domain, indicating that the timer’s configuration is not yet valid. */ + +/* T3STA[IRQ] - Interrupt pending. */ +#define T3STA_IRQ_BBA (*(volatile unsigned long *) 0x4204B300) +#define T3STA_IRQ_MSK (0x1 << 0 ) +#define T3STA_IRQ (0x1 << 0 ) +#define T3STA_IRQ_CLR (0x0 << 0 ) /* CLR. No timeout event has occurred. */ +#define T3STA_IRQ_SET (0x1 << 0 ) /* SET. A timeout event has occurred. */ + + +/* -------------------- End of section using anonymous unions ------------------- */ +#if defined(__CC_ARM) + #pragma pop +#elif defined(__ICCARM__) + /* leave anonymous unions enabled */ +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined(__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined(__TASKING__) + #pragma warning restore +#else + #warning Not supported compiler type +#endif +/******************************************** +** Miscellaneous Definitions ** +*********************************************/ + +//iEiNr in EiCfg() +#define EXTINT0 0x0 +#define EXTINT1 0x1 +#define EXTINT2 0x2 +#define EXTINT3 0x3 +#define EXTINT4 0x4 +#define EXTINT5 0x5 +#define EXTINT6 0x6 +#define EXTINT7 0x7 +#define EXTINT8 0x8 + +//iEnable in EiCfg() +#define INT_DIS 0x0 +#define INT_EN 0x1 + +//iMode in EiCfg() +#define INT_RISE 0x0 +#define INT_FALL 0x1 +#define INT_EDGES 0x2 +#define INT_HIGH 0x3 +#define INT_LOW 0x4 + +//Bit values. +#define BIT0 1 +#define BIT1 2 +#define BIT2 4 +#define BIT3 8 +#define BIT4 0x10 +#define BIT5 0x20 +#define BIT6 0x40 +#define BIT7 0x80 + + +/* ================================================================================ */ +/* ================ Peripheral memory map ================ */ +/* ================================================================================ */ + +#define ADI_ADC0_ADDR 0x40050000UL +#define ADI_CLKCTL_ADDR 0x40002000UL +#define ADI_DMA_ADDR 0x40010000UL +#define ADI_FEE_ADDR 0x40002800UL +#define ADI_GP0_ADDR 0x40006000UL +#define ADI_GP1_ADDR 0x40006030UL +#define ADI_GP2_ADDR 0x40006060UL +#define ADI_GP3_ADDR 0x40006090UL +#define ADI_GP4_ADDR 0x400060C0UL +#define ADI_GPIOCMN_ADDR 0x400060F0UL +#define ADI_MISC_ADDR 0x40008820UL +#define ADI_I2C_ADDR 0x40003000UL +#define ADI_INTERRUPT_ADDR 0x40002420UL +#define ADI_IDENT_ADDR 0x40002020UL +#define ADI_NVIC_ADDR 0xE000E000UL +#define ADI_PWRCTL_ADDR 0x40002400UL +#define ADI_PWM_ADDR 0x40001000UL +#define ADI_RESET_ADDR 0x40002440UL +#define ADI_SPI0_ADDR 0x40004000UL +#define ADI_SPI1_ADDR 0x40004400UL +#define ADI_TM0_ADDR 0x40000000UL +#define ADI_TM1_ADDR 0x40000400UL +#define ADI_UART_ADDR 0x40005000UL +#define ADI_WUT_ADDR 0x40002500UL +#define ADI_WDT_ADDR 0x40002580UL + + +/* ================================================================================ */ +/* ================ Peripheral declaration ================ */ +/* ================================================================================ */ + +#define pADI_ADC0 ((ADI_ADC_TypeDef *)ADI_ADC0_ADDR) +#define pADI_CLKCTL ((ADI_CLKCTL_TypeDef *)ADI_CLKCTL_ADDR) +#define pADI_DMA ((ADI_DMA_TypeDef *)ADI_DMA_ADDR) +#define pADI_FEE ((ADI_FEE_TypeDef *)ADI_FEE_ADDR) +#define pADI_GP0 ((ADI_GPIO_TypeDef *)ADI_GP0_ADDR) +#define pADI_GP1 ((ADI_GPIO_TypeDef *)ADI_GP1_ADDR) +#define pADI_GP2 ((ADI_GPIO_TypeDef *)ADI_GP2_ADDR) +#define pADI_GP3 ((ADI_GPIO_TypeDef *)ADI_GP3_ADDR) +#define pADI_GP4 ((ADI_GPIO_TypeDef *)ADI_GP4_ADDR) +#define pADI_GPIOCMN ((ADI_GPIOCMN_TypeDef *)ADI_GPIOCMN_ADDR) +#define pADI_MISC ((ADI_MISC_TypeDef *)ADI_MISC_ADDR) +#define pADI_I2C ((ADI_I2C_TypeDef *)ADI_I2C_ADDR) +#define pADI_INTERRUPT ((ADI_INTERRUPT_TypeDef *)ADI_INTERRUPT_ADDR) +#define pADI_PWRCTL ((ADI_PWRCTL_TypeDef *)ADI_PWRCTL_ADDR) +#define pADI_PWM ((ADI_PWM_TypeDef *)ADI_PWM_ADDR) +#define pADI_RESET ((ADI_RESET_TypeDef *)ADI_RESET_ADDR) +#define pADI_SPI0 ((ADI_SPI_TypeDef *)ADI_SPI0_ADDR) +#define pADI_SPI1 ((ADI_SPI_TypeDef *)ADI_SPI1_ADDR) +#define pADI_TM0 ((ADI_TIMER_TypeDef *)ADI_TM0_ADDR) +#define pADI_TM1 ((ADI_TIMER_TypeDef *)ADI_TM1_ADDR) +#define pADI_UART ((ADI_UART_TypeDef *)ADI_UART_ADDR) +#define pADI_WUT ((ADI_WUT_TypeDef *)ADI_WUT_ADDR) +#define pADI_WDT ((ADI_WDT_TypeDef *)ADI_WDT_ADDR) + +/** @} */ /* End of group Device_Peripheral_Registers *//** @} */ /* End of group ADUCRF101 */ +/** @} */ /* End of group CMSIS */ + +#ifdef __cplusplus +} +#endif + + +#endif // __ADUCRF101_H__ + diff --git a/cpu/arm/aducrf101/Common/GCC/ADuCRF101.ld b/cpu/arm/aducrf101/Common/GCC/ADuCRF101.ld new file mode 100644 index 000000000..a6effb701 --- /dev/null +++ b/cpu/arm/aducrf101/Common/GCC/ADuCRF101.ld @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) + +ENTRY(Reset_Handler) + +MEMORY +{ + flash (rx) : org = 0x00000000, len = 128k + ram (rwx) : org = 0x20000000, len = 16k +} + +SECTIONS +{ + .vectors : { + __vectors_start = .; + KEEP(*(.vectors)) + . = ALIGN(4); + } >flash + + .text : { + . = ALIGN(4); + *(.text) + *(.text.*) + etext = .; + } >flash + + .ARM.ex : { + *(.ARM.extab* .gnu.linkonce.armextab.*) + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } >flash + + .rodata : { + . = ALIGN(4); + *(.rodata) + *(.rodata.*) + . = ALIGN(4); + __rodata_end = .; + } >flash + + .data : { + /* Initialized data is placed in flash, and will get + copied to RAM by crt0.S */ + . = ALIGN(4); + __data_flash_start = LOADADDR(.data); + __data_start = .; + *(.data) + *(.data.*) + + /* Code that goes into RAM also ends up here, and + gets copied along with the data section. */ + *(.ramtext*) + + __data_end = .; + edata = .; + } > ram AT > flash + + .bss : { + . = ALIGN(8); + __bss_start = .; + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(4); + __bss_end = .; + end = .; + } > ram + + /* Heap grows up from "end" (after bss), and stack grows down from + the end of RAM. */ + . = ORIGIN(ram) + LENGTH(ram); + stack_end = .; +} diff --git a/cpu/arm/aducrf101/Common/GCC/crt0.S b/cpu/arm/aducrf101/Common/GCC/crt0.S new file mode 100644 index 000000000..04b868448 --- /dev/null +++ b/cpu/arm/aducrf101/Common/GCC/crt0.S @@ -0,0 +1,173 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ + +.equ SCB_VTOR, 0xE000ED08 + +/* Vector table */ + .macro handler name + .long \name\() + .weak \name\() + .set \name\(), unhandled_vector + .endm + + .macro handler_reserved + .long 0 + .endm + + .section .vectors, "a", %progbits +vectors: + .long stack_end + .long Reset_Handler + + /* Cortex-M3 core interrupts */ + handler NMI_Handler + handler HardFault_Handler + handler MemManage_Handler + handler BusFault_Handler + handler UsageFault_Handler + handler_reserved + handler_reserved + handler_reserved + handler_reserved + handler SVC_Handler + handler DebugMon_Handler + handler_reserved + handler PendSV_Handler + handler SysTick_Handler + + /* ADuCRF101 external interrupts */ + handler WakeUp_Int_Handler + handler Ext_Int0_Handler + handler Ext_Int1_Handler + handler Ext_Int2_Handler + handler Ext_Int3_Handler + handler Ext_Int4_Handler + handler Ext_Int5_Handler + handler Ext_Int6_Handler + handler Ext_Int7_Handler + handler Ext_Int8_Handler + handler WDog_Tmr_Int_Handler + handler_reserved + handler GP_Tmr0_Int_Handler + handler GP_Tmr1_Int_Handler + handler ADC0_Int_Handler + handler Flsh_Int_Handler + handler UART_Int_Handler + handler SPI0_Int_Handler + handler SPI1_Int_Handler + handler I2C0_Slave_Int_Handler + handler I2C0_Master_Int_Handler + handler_reserved + handler_reserved + handler DMA_Err_Int_Handler + handler DMA_SPI1_TX_Int_Handler + handler DMA_SPI1_RX_Int_Handler + handler DMA_UART_TX_Int_Handler + handler DMA_UART_RX_Int_Handler + handler DMA_I2C0_STX_Int_Handler + handler DMA_I2C0_SRX_Int_Handler + handler DMA_I2C0_MTX_Int_Handler + handler DMA_I2C0_MRX_Int_Handler + handler_reserved + handler_reserved + handler_reserved + handler DMA_ADC_Int_Handler + handler DMA_SPI0_TX_Int_Handler + handler DMA_SPI0_RX_Int_Handler + handler PWMTrip_Int_Handler + handler PWM0_Int_Handler + handler PWM1_Int_Handler + handler PWM2_Int_Handler + handler PWM3_Int_Handler + +/* Reset handler */ + .section .text + .syntax unified + .code 16 + .global Reset_Handler + .thumb_func +Reset_Handler: + /* Set up some basics, in case we came here from a call + rather than system reset. */ + + /* Disable interrupts */ + cpsid i + + /* Privileged mode, main stack, no floating point */ + mov r0, #0 + msr control, r0 + isb + + /* Point vector table to the right place */ + ldr r0, =__vectors_start + ldr r1, =SCB_VTOR + str r0, [r1] + + /* Load initial stack pointer */ + ldr r0, =stack_end + mov sp, r0 + isb + + /* Clear BSS */ + mov r0, #0 + ldr r1, =__bss_start + ldr r2, =__bss_end +zero_bss_loop: + cmp r1, r2 + it lt + strlt r0, [r1], #4 + blt zero_bss_loop + + /* Copy initialized data from flash to RAM */ + ldr r0, =__data_flash_start + ldr r1, =__data_start + ldr r2, =__data_end +copy_data_loop: + ldr r3, [r0], #4 + cmp r1, r2 + it lt + strlt r3, [r1], #4 + blt copy_data_loop + + /* We can run C code now */ + bl main + + /* If main returned, just loop */ + b . + +/* Handler for otherwise unhandled vectors */ + .section .text,"ax",%progbits + .thumb_func +unhandled_vector: + b unhandled_vector diff --git a/cpu/arm/aducrf101/Common/IAR/ADUCRF101.icf b/cpu/arm/aducrf101/Common/IAR/ADUCRF101.icf new file mode 100644 index 000000000..9ebe02a5a --- /dev/null +++ b/cpu/arm/aducrf101/Common/IAR/ADUCRF101.icf @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x0001FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x20003FFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; +do not initialize { section .mainstackarea }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; +place at address mem:0x1FC { readonly section .PageZeroCheckSum }; +place at address mem:0x1FFEC { readonly section .sigprot }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; diff --git a/cpu/arm/aducrf101/Common/IAR/Retarget.c b/cpu/arm/aducrf101/Common/IAR/Retarget.c new file mode 100644 index 000000000..0006d5a05 --- /dev/null +++ b/cpu/arm/aducrf101/Common/IAR/Retarget.c @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + Module : Retarget.c + Description : uart interface + Date : December 2012 + Version : v2.00 + Changelog : v1.00 Initial + v2.00 use of UrtLib functions +*/ +#include +#include "UrtLib.h" +#include +#include +#include + +#define CR 0x0D + + + +/*************************************************************************/ +/* size_t __read(int handle,unsigned char *buf,size_t bufSize) */ +/* Write data to a stream */ +/* Needed for retargetting the IAR DLIB library for the ADUCRF101 */ +/*************************************************************************/ +size_t __read(int handle,unsigned char *buf,size_t bufSize) +{ + size_t i; + for (i=0x0; iCOMLSR & COMLSR_DR))); + buf[i] = pADI_UART->COMRX; + } + return i; +} + +/*************************************************************************/ +/* __write(int handle,const unsigned char *buf,size_t bufSize) */ +/* Read data from a stream */ +/* Needed for retargetting the IAR DLIB library for the ADUCRF101 */ +/*************************************************************************/ +size_t __write(int handle,const unsigned char *buf,size_t bufSize) +{ + size_t i; + for (i=0x0; i +#include +#include + +#pragma import(__use_no_semihosting_swi) + + #define CR 0x0D +struct __FILE { int handle; /* Add whatever you need here */ }; +FILE __stdout; +FILE __stdin; + + +// Re-targetting the Realview library functions +/* + * writes the character specified by c (converted to an unsigned char) to + * the output stream pointed to by stream, at the position indicated by the + * asociated file position indicator (if defined), and advances the + * indicator appropriately. If the file position indicator is not defined, + * the character is appended to the output stream. + * Returns: the character written. If a write error occurs, the error + * indicator is set and fputc returns EOF. + */ +int fputc(int ch, FILE * stream ) +{ + if(ch == '\n') + while(!(COMLSR_THRE==(UrtLinSta(0) & COMLSR_THRE))); + UrtTx(0, CR); /* output CR */ + while(!(COMLSR_THRE==(UrtLinSta(0) & COMLSR_THRE))); + UrtTx(0, ch); + return(ch); +} + +int __backspace(FILE *stream) +{ + return 0x0; + +} +/* + * obtains the next character (if present) as an unsigned char converted to + * an int, from the input stream pointed to by stream, and advances the + * associated file position indicator (if defined). + * Returns: the next character from the input stream pointed to by stream. + * If the stream is at end-of-file, the end-of-file indicator is + * set and fgetc returns EOF. If a read error occurs, the error + * indicator is set and fgetc returns EOF. + */ +int fgetc(FILE * stream) +{ + return (UrtRx(0)); +} + + +int ferror(FILE *f) { + /* Your implementation of ferror */ + return EOF; +} + + +void _ttywrch(int ch) { UrtTx(0, ch); } + + +void _sys_exit(int return_code) { +label: goto label; /* endless loop */ +} diff --git a/cpu/arm/aducrf101/Common/RealView/startup_ADuCRF101.s b/cpu/arm/aducrf101/Common/RealView/startup_ADuCRF101.s new file mode 100644 index 000000000..314f9cb0a --- /dev/null +++ b/cpu/arm/aducrf101/Common/RealView/startup_ADuCRF101.s @@ -0,0 +1,312 @@ +; Copyright (c) 2014, Analog Devices, Inc. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted (subject to the limitations in the +; disclaimer below) 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 Analog Devices, Inc. nor the names of its +; contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE +; GRANTED BY THIS LICENSE. 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 OWNER 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. + +; Module : startup_ADuCRF101.s +; Description : Cortex-M3 startup file - ADuCRF101 - RealView Version +; Date : 14 January 2013 +; Version : v1.01 +; Changelog : v1.01 Added call to SystemInit +; Changelog : v1.00 Initial + + IMPORT __use_no_semihosting_swi +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000400 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000200 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; The NMI handler + DCD HardFault_Handler ; The hard fault handler + DCD MemManage_Handler ; The MPU fault handler + DCD BusFault_Handler ; The bus fault handler + DCD UsageFault_Handler ; The usage fault handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall handler + DCD DebugMon_Handler ; Debug monitor handler + DCD 0 ; Reserved + DCD PendSV_Handler ; The PendSV handler + DCD SysTick_Handler ; The SysTick handler + + ; External Interrupts + DCD WakeUp_Int_Handler ; Wake Up Timer [ 0] + DCD Ext_Int0_Handler ; External Interrupt 0 [ 1] + DCD Ext_Int1_Handler ; External Interrupt 1 [ 2] + DCD Ext_Int2_Handler ; External Interrupt 2 [ 3] + DCD Ext_Int3_Handler ; External Interrupt 3 [ 4] + DCD Ext_Int4_Handler ; External Interrupt 4 [ 5] + DCD Ext_Int5_Handler ; External Interrupt 5 [ 6] + DCD Ext_Int6_Handler ; External Interrupt 6 [ 7] + DCD Ext_Int7_Handler ; External Interrupt 7 [ 8] + DCD Ext_Int8_Handler ; External Interrupt 8 [ 9] + DCD WDog_Tmr_Int_Handler ; Watchdog timer handler [10] + DCD UnUsed_Handler ; Reserved [11] + DCD GP_Tmr0_Int_Handler ; General purpose timer 0 [12] + DCD GP_Tmr1_Int_Handler ; General purpose timer 1 [13] + DCD ADC0_Int_Handler ; ADC Interrupt [14] + DCD Flsh_Int_Handler ; Flash IRQ [15] + DCD UART_Int_Handler ; UART0 [16] + DCD SPI0_Int_Handler ; SPI 0 [17] + DCD SPI1_Int_Handler ; SPI 1 [18] + DCD I2C0_Slave_Int_Handler ; I2C0 Slave [19] + DCD I2C0_Master_Int_Handler ; I2C0 Master [20] + DCD UnUsed_Handler ; Reserved [21] + DCD UnUsed_Handler ; Reserved [22] + DCD DMA_Err_Int_Handler ; DMA Error interrupt [23] + DCD DMA_SPI1_TX_Int_Handler ; DMA SPI1 TX [24] + DCD DMA_SPI1_RX_Int_Handler ; DMA SPI1 RX [25] + DCD DMA_UART_TX_Int_Handler ; DMA UART TX [26] + DCD DMA_UART_RX_Int_Handler ; DMA UART RX [27] + DCD DMA_I2C0_STX_Int_Handler ; DMA I2C0 Slave TX [28] + DCD DMA_I2C0_SRX_Int_Handler ; DMA I2C0 Slave RX [29] + DCD DMA_I2C0_MTX_Int_Handler ; DMA I2C0 Master TX [30] + DCD DMA_I2C0_MRX_Int_Handler ; DMA I2C0 Master RX [31] + DCD UnUsed_Handler ; Reserved [32] + DCD UnUsed_Handler ; Reserved [33] + DCD UnUsed_Handler ; Reserved [34] + DCD DMA_ADC_Int_Handler ; DMA ADC [35] + DCD DMA_SPI0_TX_Int_Handler ; DMA SPI0 TX [36] + DCD DMA_SPI0_RX_Int_Handler ; DMA SPI0 RX [37] + DCD PWMTrip_Int_Handler ; PWM Trip [38] + DCD PWM0_Int_Handler ; PWM 0 [39] + DCD PWM1_Int_Handler ; PWM 1 [40] + DCD PWM2_Int_Handler ; PWM 2 [41] + DCD PWM3_Int_Handler ; PWM 3 [42] + DCD UnUsed_Handler ; Unused [43] +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset handler +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + LDR R0, =SystemInit ; Defined in system_ADuCRF101.c + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WakeUp_Int_Handler [WEAK] + EXPORT Ext_Int0_Handler [WEAK] + EXPORT Ext_Int1_Handler [WEAK] + EXPORT Ext_Int2_Handler [WEAK] + EXPORT Ext_Int3_Handler [WEAK] + EXPORT Ext_Int4_Handler [WEAK] + EXPORT Ext_Int5_Handler [WEAK] + EXPORT Ext_Int6_Handler [WEAK] + EXPORT Ext_Int7_Handler [WEAK] + EXPORT Ext_Int8_Handler [WEAK] + EXPORT WDog_Tmr_Int_Handler [WEAK] + EXPORT GP_Tmr0_Int_Handler [WEAK] + EXPORT GP_Tmr1_Int_Handler [WEAK] + EXPORT ADC0_Int_Handler [WEAK] + EXPORT Flsh_Int_Handler [WEAK] + EXPORT UART_Int_Handler [WEAK] + EXPORT SPI0_Int_Handler [WEAK] + EXPORT SPI1_Int_Handler [WEAK] + EXPORT I2C0_Slave_Int_Handler [WEAK] + EXPORT I2C0_Master_Int_Handler [WEAK] + EXPORT DMA_Err_Int_Handler [WEAK] + EXPORT DMA_SPI1_TX_Int_Handler [WEAK] + EXPORT DMA_SPI1_RX_Int_Handler [WEAK] + EXPORT DMA_UART_TX_Int_Handler [WEAK] + EXPORT DMA_UART_RX_Int_Handler [WEAK] + EXPORT DMA_I2C0_STX_Int_Handler [WEAK] + EXPORT DMA_I2C0_SRX_Int_Handler [WEAK] + EXPORT DMA_I2C0_MTX_Int_Handler [WEAK] + EXPORT DMA_I2C0_MRX_Int_Handler [WEAK] + EXPORT DMA_ADC_Int_Handler [WEAK] + EXPORT DMA_SPI0_TX_Int_Handler [WEAK] + EXPORT DMA_SPI0_RX_Int_Handler [WEAK] + EXPORT PWMTrip_Int_Handler [WEAK] + EXPORT PWM0_Int_Handler [WEAK] + EXPORT PWM1_Int_Handler [WEAK] + EXPORT PWM2_Int_Handler [WEAK] + EXPORT PWM3_Int_Handler [WEAK] + EXPORT UnUsed_Handler [WEAK] + + +WakeUp_Int_Handler +Ext_Int0_Handler +Ext_Int1_Handler +Ext_Int2_Handler +Ext_Int3_Handler +Ext_Int4_Handler +Ext_Int5_Handler +Ext_Int6_Handler +Ext_Int7_Handler +Ext_Int8_Handler +WDog_Tmr_Int_Handler +GP_Tmr0_Int_Handler +GP_Tmr1_Int_Handler +ADC0_Int_Handler +Flsh_Int_Handler +UART_Int_Handler +SPI0_Int_Handler +SPI1_Int_Handler +I2C0_Slave_Int_Handler +I2C0_Master_Int_Handler +DMA_Err_Int_Handler +DMA_SPI1_TX_Int_Handler +DMA_SPI1_RX_Int_Handler +DMA_UART_TX_Int_Handler +DMA_UART_RX_Int_Handler +DMA_I2C0_STX_Int_Handler +DMA_I2C0_SRX_Int_Handler +DMA_I2C0_MTX_Int_Handler +DMA_I2C0_MRX_Int_Handler +DMA_ADC_Int_Handler +DMA_SPI0_TX_Int_Handler +DMA_SPI0_RX_Int_Handler +PWMTrip_Int_Handler +PWM0_Int_Handler +PWM1_Int_Handler +PWM2_Int_Handler +PWM3_Int_Handler +UnUsed_Handler + + B . + + ENDP + + ALIGN + +;******************************************************************************* +; User Stack and Heap initialization +;******************************************************************************* + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + + END + diff --git a/cpu/arm/aducrf101/Common/aducrf101-include.h b/cpu/arm/aducrf101/Common/aducrf101-include.h new file mode 100644 index 000000000..1d250d121 --- /dev/null +++ b/cpu/arm/aducrf101/Common/aducrf101-include.h @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + @module include.h + @brief Main Include file + @version V0.2 + @author PAD CSE group, Analog Devices Inc + @date January 2013 + + @par Revision History: + - V0.1, February 2012: initial version. + - V0.2, January 2013: addition of PwmLib, FeeLib and DmaLib + remove uart.h +**/ + +#ifndef __INCLUDE_H +#define __INCLUDE_H + +#include +#include +#include +#include +#include +#include + +#include + +#include "radioeng.h" + +#endif // __INCLUDE_H diff --git a/cpu/arm/aducrf101/Common/defs.h b/cpu/arm/aducrf101/Common/defs.h new file mode 100644 index 000000000..e129c7e58 --- /dev/null +++ b/cpu/arm/aducrf101/Common/defs.h @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + @file defs.h + @brief Global definitions. + @version V0.1 + @author PAD CSE group, Analog Devices Inc + @date January 2012 +**/ + +typedef enum {FALSE = 0, TRUE = !FALSE} boolean; diff --git a/cpu/arm/aducrf101/Common/radioeng.c b/cpu/arm/aducrf101/Common/radioeng.c new file mode 100644 index 000000000..d6ee03c0f --- /dev/null +++ b/cpu/arm/aducrf101/Common/radioeng.c @@ -0,0 +1,1790 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + @file radioeng.c + @brief Radio Interface Engine Functions + @version v1.0 + @author PAD CSE group, Analog Devices Inc + @date May 08th 2013 +**/ + +#include "aducrf101-include.h" + +// 1.0 of the Engine +#define RIE_ENGINE_MAJOR_VERSION 1UL +#define RIE_ENGINE_MINOR_VERSION 0UL + + +#define RADIO_SPI_CLK_FREQ 4000000 // 4 MHz SPI CLK for radio interface +#define SYSTEM_UCLK 16000000 // 16 MHz UCLK +// Default Radio Parameters +#define DEFAULT_CHNL_FREQ 915000000 +#define FREQ_CNVRT_VAL 0.00252061538 +// Defines for radio memory mapped areas +#define PACKETRAM_START 0x10 +#define PACKETRAM_LEN 240 +#define BBRAM_START 0x100 +#define PR_var_tx_mode_ADR 0x00D + +// PrF Table 35 +#define PARAM_TX_NORMAL_PACKET 0 +#define PARAM_TX_PREAMBLE_FOREVER 2 +#define PARAM_TX_CARRIER_FOREVER 3 + +#define gpio_configure_sport_mode_0 0xA0 +#define gpio_configure_default 0x00 +#define MCR_pa_level_mcr_Adr 0x307 +#define MCR_rssi_readback_Adr 0x312 +#define MCR_gpio_configure_Adr 0x3fa +#define MCR_ext_uc_clk_divide_Adr 0x32e +#define MCR_interrupt_source_0_Adr 0x336 +#define MCR_interrupt_source_1_Adr 0x337 + +// Macros for manual GPIO checking of Radio MISO pin P2.0 (SPI0) +#define RADIO_MISO_IN GP2IN_IN0_BBA +// Macros for manual GPIO control of P2.3 (Radio SPI CS) (SPI0) +#define RADIO_CSN_DEASSERT (pADI_GP2->GPSET = GP2SET_SET3) +#define RADIO_CSN_ASSERT (pADI_GP2->GPCLR = GP2CLR_CLR3) +// Macros for Sending\Receiving single bytes via SPI +#define SEND_SPI(x) pADI_SPI0->SPITX = x +#define WAIT_SPI_RX while((pADI_SPI0->SPISTA & SPISTA_RXFSTA_MSK) == 0x0); +#define READ_SPI pADI_SPI0->SPIRX + +// Bit Manipulation Macros +#define MSKSET_VAL(byte,numbits,offset,value) ((byte & ~(((0x1 << numbits)-1) << offset)) | value) + + + +/*************************************************************************/ +/* Local Types */ +/*************************************************************************/ +/*************************************************************************/ +/* Radio Command Codes */ +/*************************************************************************/ +typedef enum +{ + CMD_SYNC = 0xA2, // Synchronizatio + CMD_PHY_OFF = 0xB0, // Transition to state PHY_OFF + CMD_PHY_ON = 0xB1, // transition to state PHY_ON + CMD_PHY_RX = 0xB2, // transition to state PHY_RX + CMD_PHY_TX = 0xB5, // transition to state PHY_TX + CMD_PHY_SLEEP = 0xBA, // transition to state PHY_SLEEP + CMD_CONFIG_DEV = 0xBB, // Apply Radio Configuration + CMD_GET_RSSI = 0xBC, // Performs an RSSI measurement + CMD_HW_RESET = 0xC8, // Power Down radio + SPI_MEM_WR = 0x18, // Sequential SPI Write + SPI_MEM_RD = 0x38, // Sequential SPI Read + SPI_NOP = 0xFF // No operation +} Radio_CmdCodes; +/*************************************************************************/ +/* Firmware States */ +/*************************************************************************/ +typedef enum +{ + FW_INIT = 0x0F, // Radio Starting Up + FW_BUSY = 0x00, // Radio not completed current operation + FW_RSSI = 0x05, // Performing CMD_GET_RSSI + FW_OFF = 0x11, // Radio is OFF + FW_ON = 0x12, // Radio is ON + FW_RX = 0x13, // Radio is in receive mode + FW_TX = 0x14, // Radio is in transmit mode + +} RadioState; +/*************************************************************************/ +/* Status Byte Masks */ +/*************************************************************************/ +#define STATUS_BYTE_FW_STATE (0x1F << 0) +#define STATUS_BYTE_CMD_READY (0x1 << 5) +#define STATUS_BYTE_IRQ_STATUS (0x1 << 6) +#define STATUS_BYTE_SPI_READY (0x1 << 7) +/*************************************************************************/ +/* SPI Memory Access Defs */ +/*************************************************************************/ +#define SPI_MEMCMD_BYTE0_ADR_MSK (0x3 << 0) +#define SPI_MEMCMD_BYTE0_CMD_BITOFFSET 3 +#define SPI_MEMCMD_BYTE0_CMD_MSK (0x1F << SPI_MEMCMD_BYTE0_CMD_BITOFFSET) +/*************************************************************************/ +/* Radio Configuration Structure */ +/*************************************************************************/ +/** + \internal Hide from Doxegen + \var TyRadioConfiguration + **/ +typedef struct +{ + RIE_U8 interrupt_mask_0_r; // 0x100 + RIE_U8 cfg_101_r; // 0x101 + RIE_U8 cfg_102_r; // 0x102 + RIE_U8 cfg_103_r; // 0x103 + RIE_U8 cfg_104_r; // 0x104 + RIE_U8 cfg_105_r; // 0x105 + RIE_U8 cfg_106_r; // 0x106 + RIE_U8 cfg_107_r; // 0x107 + RIE_U8 cfg_108_r; // 0x108 + RIE_U8 channel_freq_0_r; // 0x109 + RIE_U8 channel_freq_1_r; // 0x10A + RIE_U8 channel_freq_2_r; // 0x10B + RIE_U8 cfg_10C_r; // 0x10C + RIE_U8 cfg_10D_r; // 0x10D + RIE_U8 cfg_10E_r; // 0x10E + RIE_U8 cfg_10F_r; // 0x10F + RIE_U8 cfg_110_r; // 0x110 + RIE_U8 cfg_111_r; // 0x111 + RIE_U8 cfg_112_r; // 0x112 + RIE_U8 cfg_113_r; // 0x113 + RIE_U8 radio_cfg_8_r; // 0x114 + RIE_U8 radio_cfg_9_r; // 0x115 + RIE_U8 cfg_116_r; // 0x116 + RIE_U8 cfg_117_r; // 0x117 + RIE_U8 image_reject_cal_phase_r; // 0x118 + RIE_U8 image_reject_cal_amplitude_r; // 0x119 + RIE_U8 cfg_11A_r; // 0x11A + RIE_U8 cfg_11B_r; // 0x11B + RIE_U8 symbol_mode_r; // 0x11C + RIE_U8 cfg_11D_r; // 0x11D + RIE_U8 cfg_11E_r; // 0x11E + RIE_U8 cfg_11F_r; // 0x11F + RIE_U8 cfg_120_r; // 0x120 + RIE_U8 cfg_121_r; // 0x121 + RIE_U8 cfg_122_r; // 0x122 + RIE_U8 cfg_123_r; // 0x123 + RIE_U8 tx_base_adr_r; // 0x124 + RIE_U8 rx_base_adr_r; // 0x125 + RIE_U8 packet_length_control_r; // 0x126 + RIE_U8 packet_length_max_r; // 0x127 + RIE_U8 cfg_128_r; // 0x128 + RIE_U8 cfg_129_r; // 0x129 + RIE_U8 cfg_12A_r; // 0x12A + RIE_U8 cfg_12B_r; // 0x12B + RIE_U8 cfg_12C_r; // 0x12C + RIE_U8 cfg_12D_r; // 0x12D + RIE_U8 cfg_12E_r; // 0x12E + RIE_U8 cfg_12F_r; // 0x12F + RIE_U8 cfg_130_r; // 0x130 + RIE_U8 cfg_131_r; // 0x131 + RIE_U8 cfg_132_r; // 0x132 + RIE_U8 cfg_133_r; // 0x133 + RIE_U8 cfg_134_r; // 0x134 + RIE_U8 cfg_135_r; // 0x135 + RIE_U8 cfg_136_r; // 0x136 + RIE_U8 cfg_137_r; // 0x137 + RIE_U8 cfg_138_r; // 0x138 + RIE_U8 cfg_139_r; // 0x139 + RIE_U8 cfg_13A_r; // 0x13A + RIE_U8 cfg_13B_r; // 0x13B + RIE_U8 cfg_13C_r; // 0x13C + RIE_U8 cfg_13D_r; // 0x13D + RIE_U8 cfg_13E_r; // 0x13E + RIE_U8 cfg_13F_r; // 0x13F +} TyRadioConfiguration; +/*************************************************************************/ +/* Radio Configuration Constants */ +/*************************************************************************/ +#define interrupt_mask_0_interrupt_tx_eof (0x1 << 4) +#define interrupt_mask_0_interrupt_crc_correct (0x1 << 2) + +#define packet_length_control_length_offset_offset (0) +#define packet_length_control_length_offset_minus0 (0x4 << packet_length_control_length_offset_offset) +#define packet_length_control_data_mode_offset (3) +#define packet_length_control_data_mode_packet (0x0 << packet_length_control_data_mode_offset) +#define packet_length_control_crc_en_yes (0x1 << 5) +#define packet_length_control_packet_len_variable (0x0 << 6) +#define packet_length_control_packet_len_fixed (0x1 << 6) +#define packet_length_control_data_byte_lsb (0x0 << 7) + +#define symbol_mode_symbol_length_8_bit (0 << 0) +#define symbol_mode_data_whitening_disabled (0 << 3) +#define symbol_mode_data_whitening_enabled (1 << 3) +#define symbol_mode_eight_ten_enc_disabled (0 << 4 ) +#define symbol_mode_prog_crc_en_disabled (0 << 5) +#define symbol_mode_manchester_enc_enabled (1 << 6) + +#define radio_cfg_8_pa_single_diff_sel_single_ended (0x0 << 7) +#define radio_cfg_8_pa_single_diff_sel_differential (0x1 << 7) +#define radio_cfg_8_pa_power_numbits (4) +#define radio_cfg_8_pa_power_offset (3) +#define radio_cfg_8_pa_power_setting_63 (0xF << radio_cfg_8_pa_power_offset) +#define radio_cfg_8_pa_ramp_numbits (3) +#define radio_cfg_8_pa_ramp_offset (0) +#define radio_cfg_8_pa_ramp_16 (0x5 << radio_cfg_8_pa_ramp_offset) + +#define radio_cfg_9_demod_scheme_offset (0) +#define radio_cfg_9_demod_scheme_FSK (0x0 << radio_cfg_9_demod_scheme_offset) +#define radio_cfg_9_mod_scheme_numbits (3) +#define radio_cfg_9_mod_scheme_offset (3) +#define radio_cfg_9_mod_scheme_2_level_FSK (0x0 << radio_cfg_9_mod_scheme_offset) +#define radio_cfg_9_mod_scheme_2_level_GFSK (0x1 << radio_cfg_9_mod_scheme_offset) +#define radio_cfg_9_ifbw_numbits (2) +#define radio_cfg_9_ifbw_offset (6) +#define radio_cfg_9_ifbw_100kHz (0x0 << radio_cfg_9_ifbw_offset) +#define radio_cfg_9_ifbw_150kHz (0x1 << radio_cfg_9_ifbw_offset) +#define radio_cfg_9_ifbw_200kHz (0x2 << radio_cfg_9_ifbw_offset) +#define radio_cfg_9_ifbw_300kHz (0x3 << radio_cfg_9_ifbw_offset) + +/*************************************************************************/ +/* Local Variables */ +/*************************************************************************/ +static TyRadioConfiguration RadioConfiguration; +static RIE_BOOL bRadioConfigurationChanged = RIE_FALSE; +static RIE_BOOL bTestModeEnabled = RIE_FALSE; +static RIE_U32 DataRate = 38400; +static volatile RIE_BOOL bPacketTx = RIE_FALSE; +static volatile RIE_BOOL bPacketRx = RIE_FALSE; + +const RIE_U8 DR_38_4kbps_Dev20kHz_Configuration[] = +{ + 0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x76,0x62,0x21, + +// 0 1 2 3 4 5 6 7 8 9 A B + 0x80,0x01,0xC8,0x20,0x0E,0x00,0x00,0x00,0xFD,0x00,0x0B,0x37, + 0x16,0x07, + + 0x40,0x0C,0x00,0x0C,0x00,0x00, + 0x10,0x00,0xC3,0x36,0x10,0x10,0x24,0xF0,0x2A,0x00,0x2F,0x19,0x5E,0x46,0x5F,0x78, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; + + +const RIE_U8 DR_300_0kbps_Dev75_0kHz_Configuration[] = +{ + 0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x76,0x62,0x21, + +// 0 1 2 3 4 5 6 7 8 9 A B + 0xB8,0x2B,0xEE,0x0B,0x70,0x00,0x03,0x00,0xFD,0xC0,0x0B,0x37, + 0x16,0x07, + + 0x40,0x0C,0x00,0x0C,0x00,0x00, + 0x10,0x00,0xC3,0x36,0x10,0x10,0x24,0xF0,0x2A,0x00,0x2F,0x19,0x5E,0x46,0x5F,0x78, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; + + + +const RIE_U8 DR_1_0kbps_Dev10_0kHz_Configuration[] = +{ + 0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x76,0x62,0x21, +// 0 1 2 3 4 5 6 7 8 9 A B + 0x0A,0x00,0x64,0x41,0x01,0x00,0x02,0x00,0xFD,0x00,0x0B,0x37, + 0x16,0x07, + + 0x40,0x0C,0x00,0x0C,0x00,0x00, + 0x10,0x00,0xC3,0x36,0x10,0x10,0x24,0xF0,0x2A,0x00,0x2F,0x19,0x5E,0x46,0x5F,0x78, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; + +/*************************************************************************/ +/* Local Functions */ +/*************************************************************************/ +static RIE_Responses RadioSPIXferByte (RIE_U8 ucByte, + RIE_U8 * pData); +static RIE_Responses RadioSendCommandBytes (RIE_U8 * pCmdBytes, + RIE_U8 NumBytes); +static RIE_Responses RadioSendCommandNoWait (Radio_CmdCodes CmdCode); +static RIE_Responses RadioSendCommandWait (Radio_CmdCodes CmdCode); +static RIE_Responses RadioMMapRead (RIE_U32 ulAdr, + RIE_U32 ulLen, + RIE_U8 * pData); +static RIE_Responses RadioMMapWrite (RIE_U32 ulAdr, + RIE_U32 ulLen, + RIE_U8 * pData); +static RIE_Responses RadioReadState (RadioState * pState); +static RIE_Responses RadioWaitOnState (RadioState FinalState); +static RIE_Responses RadioWaitForPowerUp (void); +static RIE_Responses RadioSyncComms (void); +static RIE_Responses SetRadioConfiguration (RIE_BaseConfigs BaseConfig); +static RIE_Responses RadioCommitRadioConfig (void); +static RIE_Responses RadioConfigure (void); +static RIE_Responses RadioToOnMode (void); +static RIE_Responses RadioToOffMode (void); +static RIE_Responses RadioWaitOnCmdLdr (void); +/*************************************************************************/ +/* Functions Implementations - Start */ +/*************************************************************************/ + +/** + @fn RIE_Responses RadioGetAPIVersion(RIE_U32 *pVersion) + @brief Return the Radio Interface Engine API Version + @param pVersion :{} + pVersion Storage for Radio Interface Engine API version. + @code + RIE_U32 Version; + Response = RadioGetAPIVersion(&Version); + @endcode + @return RIE_Responses Error code. +**/ + +RIE_Responses RadioGetAPIVersion(RIE_U32 *pVersion) +{ + RIE_Responses Response = RIE_Success; + + if (pVersion) + *pVersion = RIE_ENGINE_MINOR_VERSION | (RIE_ENGINE_MAJOR_VERSION << 8); + return Response; +} + + +/** + @fn RIE_U32 RadioSwitchConfig(RIE_BaseConfigs BaseConfig) + @brief Change the Radio to using specified configuration. + @param BaseConfig :{DR_1_0kbps_Dev10_0kHz, DR_38_4kbps_Dev20kHz, DR_300_0kbps_Dev75_0kHz} + - DR_1_0kbps_Dev10_0kHz Base configuration of 1 kbps datarate, 10.0 kHz frequency deviation. + - DR_38_4kbps_Dev20kHz Base configuration of 38.4 kbps datarate, 20 kHz frequency deviation. + - DR_300_0kbps_Dev75_0kHz Base configuration of 300 kbps datarate, 75 kHz frequency deviation. + @pre + RadioInit() must be called before this function is called. + @return RIE_Responses Error code. +**/ + +RIE_Responses RadioSwitchConfig(RIE_BaseConfigs BaseConfig) +{ + RIE_Responses Response = RIE_Success; + if(Response == RIE_Success) + Response = RadioToOffMode(); + if(Response == RIE_Success) + Response = SetRadioConfiguration(BaseConfig); + if(Response == RIE_Success) + Response = RadioCommitRadioConfig(); + if(Response == RIE_Success) + Response = RadioToOnMode(); + return Response; +} + + +/** + @fn RIE_U32 RadioInit(RIE_BaseConfigs BaseConfig) + @brief Initialise the Radio, using specified configuration. + @param BaseConfig :{DR_1_0kbps_Dev10_0kHz , DR_38_4kbps_Dev20kHz ,DR_300_0kbps_Dev75_0kHz } + - DR_1_0kbps_Dev10_0kHz Base configuration of 1 kbps datarate, 10.0 kHz frequency deviation. + - DR_38_4kbps_Dev20kHz Base configuration of 38.4 kbps datarate, 20 kHz frequency deviation. + - DR_300_0kbps_Dev75_0kHz Base configuration of 300 kbps datarate, 75 kHz frequency deviation. + @note + This must be called before any other function is called. + @return RIE_Responses Error code. +**/ + +RIE_Responses RadioInit(RIE_BaseConfigs BaseConfig) +{ + RIE_Responses Response = RIE_Success; + + // Disable the radio interrupt until we have initialised the radio + NVIC_DisableIRQ(UHFTRX_IRQn); + + // Initialise GPIO Port 2 for Radio Use + pADI_GP2->GPCON = GP2CON_CON0_SPI0MISO | GP2CON_CON1_SPI0SCLK | + GP2CON_CON2_SPI0MOSI | GP2CON_CON3_GPIO | + GP2CON_CON4_IRQ8 | GP2CON_CON5_GPIO | + GP2CON_CON6_GPIO | GP2CON_CON7_GPIOIRQ7; + + pADI_GP2->GPOEN = GP2OEN_OEN0_IN | GP2OEN_OEN1_IN | + GP2OEN_OEN2_IN | GP2OEN_OEN3_OUT | + GP2OEN_OEN4_IN | GP2OEN_OEN5_IN | + GP2OEN_OEN6_IN | GP2OEN_OEN7_IN; + + // Disable the PULL-Up on P2.4 which is connected to the radio + GP2PUL_PUL4_BBA = 0x0; + + // Configure the SPI Interface to the Radio and flush it + pADI_SPI0->SPIDIV = ((SYSTEM_UCLK/RADIO_SPI_CLK_FREQ)/2)-0x1; + pADI_SPI0->SPICON = SPICON_MASEN | // Master mode + SPICON_TIM | // Interrupt on transmit + SPICON_TFLUSH | // Flush FIFO + SPICON_RFLUSH | // Flush FIFO + SPICON_ENABLE; + pADI_SPI0->SPICON = SPICON_MASEN | // Master mode + SPICON_TIM | // Interrupt on transmit + SPICON_ENABLE; + + // Initialise the chip select line to starting position + RADIO_CSN_DEASSERT; + + + // Power it down and up again to return to a known state + // which will be PHY_OFF. + // This will clear any pre-existing radio interrupt before + // we enable the Cortex interrupt handling of it + if(Response == RIE_Success) + Response = RadioPowerOff(); + // Configure a "high level" radio interrupt ... + pADI_INTERRUPT->EI2CFG = EI2CFG_IRQ8MDE_HIGHLEVEL | EI2CFG_IRQ8EN; + // ... and set it up in the NVIC so that our interrupt handler is called + // when the radio wants our attention. Clear any pre-existing condition + // before enabling the interrupt. + pADI_INTERRUPT->EICLR = EICLR_IRQ8; + NVIC_ClearPendingIRQ(UHFTRX_IRQn); + NVIC_SetPriority (UHFTRX_IRQn,0x0); + NVIC_EnableIRQ (UHFTRX_IRQn); + + if(Response == RIE_Success) + Response = RadioWaitForPowerUp(); + if(Response == RIE_Success) + Response = RadioSyncComms(); + if(Response == RIE_Success) + Response = RadioToOffMode(); + if(Response == RIE_Success) + Response = SetRadioConfiguration(BaseConfig); + if(Response == RIE_Success) + Response = RadioCommitRadioConfig(); + if(Response == RIE_Success) + Response = RadioToOnMode(); + return Response; +} + +/** + @fn RIE_U32 RadioDeInit(void) + @brief Deinitialise the Radio, and power it down. + @note + This can be called independently of all other functions to power down + the radio + @return RIE_Responses Error code. +**/ + +RIE_Responses RadioDeInit(void) +{ + RIE_Responses Response = RIE_Success; + + // Disable the radio interrupt + NVIC_DisableIRQ(UHFTRX_IRQn); + + // Initialise GPIO Port 2 for Radio Use + pADI_GP2->GPCON = GP2CON_CON0_SPI0MISO | GP2CON_CON1_SPI0SCLK | + GP2CON_CON2_SPI0MOSI | GP2CON_CON3_GPIO | + GP2CON_CON4_IRQ8 | GP2CON_CON5_GPIO | + GP2CON_CON6_GPIO | GP2CON_CON7_GPIOIRQ7; + + pADI_GP2->GPOEN = GP2OEN_OEN0_IN | GP2OEN_OEN1_IN | + GP2OEN_OEN2_IN | GP2OEN_OEN3_OUT | + GP2OEN_OEN4_IN | GP2OEN_OEN5_IN | + GP2OEN_OEN6_IN | GP2OEN_OEN7_IN; + + // Enable the pull-up as we are powering down the radion + GP2PUL_PUL4_BBA = 0x1; + + // Configure the SPI Interface to the Radio and flush it + pADI_SPI0->SPIDIV = ((SYSTEM_UCLK/RADIO_SPI_CLK_FREQ)/2)-0x1; + pADI_SPI0->SPICON = SPICON_MASEN | // Master mode + SPICON_TIM | // Interrupt on transmit + SPICON_TFLUSH | // Flush FIFO + SPICON_RFLUSH | // Flush FIFO + SPICON_ENABLE; + pADI_SPI0->SPICON = SPICON_MASEN | // Master mode + SPICON_TIM | // Interrupt on transmit + SPICON_ENABLE; + + // Initialise the chip select line to starting position + RADIO_CSN_DEASSERT; + + // Power it down + Response = RadioSendCommandNoWait(CMD_HW_RESET); + + return Response; +} + +/** + @fn RIE_Responses RadioPowerOff(void) + @brief Shutdown the radio and place it in its lowest power sleep mode. + @pre + RadioInit() must be called before this function is called. + @return RIE_Response Error code. +**/ + +RIE_Responses RadioPowerOff(void) +{ + volatile RIE_U32 ulDelay; + RIE_Responses Response = RIE_Success; + + Response = RadioSendCommandNoWait(CMD_HW_RESET); + + // Delay for approximately 1 ms + ulDelay = 0x1000; + while (ulDelay--); + + return Response; +} + +/** + @fn RIE_Responses RadioTerminateRadioOp(void) + @brief Terminate a currently running radio RX or TX operation. + @pre RadioInit() must be called before this function is called. + @code + if (RIE_Response == RIE_Success) + RIE_Response = RadioRxPacketFixedLen(12); + // Delay for a while waiting for a packet + if (RIE_Response == RIE_Success) + { + // Abort the waiting + RIE_Response = RadioTerminateRadioOp(); + } + @endcode + @return RIE_Responses Error code +**/ +RIE_Responses RadioTerminateRadioOp (void) +{ + RIE_Responses Response = RIE_Success; + + Response = RadioToOnMode(); + + return Response; +} + +/** + @fn RIE_Responses RadioSetFrequency(RIE_U32 Frequency) + @brief Set frequency for radio communications + @param Frequency :{431000000-928000000} + - This must be within the available bands of the radio: + - 431000000Hz to 464000000Hz and + - 862000000Hz to 928000000Hz. + @pre RadioInit() must be called before this function is called. + @code + if (RIE_Response == RIE_Success) + RIE_Response = RadioSetFrequency(915000000); + @endcode + @return RIE_Responses Error code +**/ +RIE_Responses RadioSetFrequency(RIE_U32 Frequency) +{ + RIE_Responses Response = RIE_Success; + RIE_U32 EncodedFrequency; + + bRadioConfigurationChanged = RIE_TRUE; + + EncodedFrequency = (RIE_U32)(Frequency * FREQ_CNVRT_VAL); + RadioConfiguration.channel_freq_0_r = (EncodedFrequency >> 0) & 0xFF; + RadioConfiguration.channel_freq_1_r = (EncodedFrequency >> 8) & 0xFF; + RadioConfiguration.channel_freq_2_r = (EncodedFrequency >> 16)& 0xFF; + if (Frequency >= 862000000) + { + RadioConfiguration.image_reject_cal_amplitude_r = 0x07; + RadioConfiguration.image_reject_cal_phase_r = 0x16; + } + else + { + RadioConfiguration.image_reject_cal_amplitude_r = 0x03; + RadioConfiguration.image_reject_cal_phase_r = 0x08; + } + return Response; +} + +/** + @fn RIE_Responses RadioSetModulationType(RIE_ModulationTypes ModulationType) + @brief Set the Radio Transmitter Modulation Type. Can be FSK_Modulation or GFSK_Modulation. + @param ModulationType :{DR_1_0kbps_Dev10_0kHz , DR_38_4kbps_Dev20kHz ,DR_300_0kbps_Dev75_0kHz } + - DR_1_0kbps_Dev10_0kHz Base configuration of 1 kbps datarate, 10.0 kHz frequency deviation. + - DR_38_4kbps_Dev20kHz Base configuration of 38.4 kbps datarate, 20 kHz frequency deviation. + - DR_300_0kbps_Dev75_0kHz Base configuration of 300 kbps datarate, 75 kHz frequency deviation. + @pre RadioInit() must be called before this function is called. + @code + Response = RadioSetModulationType(GFSK_Modulation); + @endcode + @note FSK_Modulation is used by default. + @return RIE_Responses Error code +**/ +RIE_Responses RadioSetModulationType(RIE_ModulationTypes ModulationType) +{ + RIE_Responses Response = RIE_Success; + RIE_U8 ucNewCode; + RIE_U8 ucNewRegVal = RadioConfiguration.radio_cfg_9_r; + + switch (ModulationType) + { + case FSK_Modulation: + ucNewCode = radio_cfg_9_mod_scheme_2_level_FSK; + break; + case GFSK_Modulation: + ucNewCode = radio_cfg_9_mod_scheme_2_level_GFSK; + break; + default: + Response = RIE_UnsupportedRadioConfig; + break; + } + if(Response == RIE_Success) + { + ucNewRegVal = MSKSET_VAL(RadioConfiguration.radio_cfg_9_r, + radio_cfg_9_mod_scheme_numbits, + radio_cfg_9_mod_scheme_offset, + ucNewCode); + if (ucNewRegVal != RadioConfiguration.radio_cfg_9_r ) + { + bRadioConfigurationChanged = RIE_TRUE; + RadioConfiguration.radio_cfg_9_r = ucNewRegVal; + } + + } + return Response; +} + +/** + @fn RIE_Responses RadioPayldManchesterEncode(RIE_BOOL bEnable) + @brief Enable or Disable Manchester Encoding of payload data. + + Manchester encoding can be used to ensure a dc-free (zero mean) + transmission. + + A Binary 0 is mapped to 10, and a Binary 1 is mapped to 01. + + Manchester encoding and decoding are applied to the payload data + and the CRC. + + @param bEnable :{RIE_FALSE,RIE_TRUE} + - RIE_TRUE if Manchester Encoding is to be enabled. + - RIE_FALSE if disabled. + + @pre RadioInit() must be called before this function is called. + @code + Response = RadioPayldManchesterEncode(RIE_TRUE); + + @endcode + @note Manchester Encoding is disabled by default. + @return RIE_Responses Error code +**/ +RIE_Responses RadioPayldManchesterEncode(RIE_BOOL bEnable) +{ + RIE_Responses Response = RIE_Success; + RIE_U8 ucNewRegVal = RadioConfiguration.symbol_mode_r; + + switch (bEnable) + { + case RIE_FALSE: + ucNewRegVal &= ~symbol_mode_manchester_enc_enabled; + break; + case RIE_TRUE: + ucNewRegVal |= symbol_mode_manchester_enc_enabled; + break; + default: + Response = RIE_UnsupportedRadioConfig; + break; + } + if(Response == RIE_Success) + { + if (ucNewRegVal != RadioConfiguration.symbol_mode_r ) + { + bRadioConfigurationChanged = RIE_TRUE; + RadioConfiguration.symbol_mode_r = ucNewRegVal; + } + } + return Response; +} +/** + @fn RIE_Responses RadioPayldDataWhitening(RIE_BOOL bEnable) + @brief Enable or Disable Data Whitening of payload data. + + Data whitening can be employed to avoid long runs of 1s or 0s + in the transmitted data stream. + + This ensures sufficient bit transitions in the packet, which + aids in receiver clock and data recovery because the encoding + breaks up long runs of 1s or 0s in the transmit packet. + + The data, excluding the preamble and sync word, is automatically + whitened before transmission by XORing the data with an 8-bit + pseudorandom sequence. + + At the receiver, the data is XORed with the same pseudorandom + sequence, thereby reversing the whitening. + + The linear feedback shift register polynomial used is x7 + x1 + 1. + + @param bEnable :{RIE_FALSE, RIE_TRUE} + - RIE_TRUE if Manchester Encoding is to be enabled. + - RIE_FALSE if disabled. + + @pre RadioInit() must be called before this function is called. + @code + Response = RadioPayldDataWhitening(RIE_TRUE); + + @endcode + @note Data Whitening is disabled by default. + @return RIE_Responses Error code +**/ +RIE_Responses RadioPayldDataWhitening(RIE_BOOL bEnable) +{ + RIE_Responses Response = RIE_Success; + RIE_U8 ucNewRegVal = RadioConfiguration.symbol_mode_r; + + switch (bEnable) + { + case RIE_FALSE: + ucNewRegVal &= ~symbol_mode_data_whitening_enabled; + break; + case RIE_TRUE: + ucNewRegVal |= symbol_mode_data_whitening_enabled; + break; + default: + Response = RIE_UnsupportedRadioConfig; + break; + } + if(Response == RIE_Success) + { + if (ucNewRegVal != RadioConfiguration.symbol_mode_r ) + { + bRadioConfigurationChanged = RIE_TRUE; + RadioConfiguration.symbol_mode_r = ucNewRegVal; + } + } + return Response; +} + +/** + @fn RIE_Responses RadioTxPacketFixedLen(RIE_U8 Len, RIE_U8 *pData) + @brief Transmit a fixed length packet. + @param Len :{1-240} Length of packet to be transmitted. + @param pData :{} Data bytes to be transmitted. + @pre RadioInit() must be called before this function is called. + @code + if (RIE_Response == RIE_Success) + RIE_Response = RadioTxSetPA(DifferentialPA,PowerLevel15); + if (RIE_Response == RIE_Success) + RIE_Response = RadioTxPacketFixedLen(12, "HELLO WORLD"); + while (!RadioTxPacketComplete()); + @endcode + @return RIE_Responses Error code +**/ +RIE_Responses RadioTxPacketFixedLen(RIE_U8 Len, RIE_U8 *pData) +{ + RIE_Responses Response = RIE_Success; + + bPacketTx = RIE_FALSE; + if (Len > PACKETRAM_LEN) + Response = RIE_InvalidParamter; + if (Response == RIE_Success) + Response = RadioToOnMode(); + if (Response == RIE_Success) + Response = RadioMMapWrite(PACKETRAM_START, Len, pData); + if (Response == RIE_Success) + { + RadioConfiguration.packet_length_max_r = Len; + RadioConfiguration.packet_length_control_r |= packet_length_control_packet_len_fixed; + } + if(Response == RIE_Success) + Response = RadioCommitRadioConfig(); + if (Response == RIE_Success) + Response = RadioToOnMode(); + if (Response == RIE_Success) + Response = RadioSendCommandWait(CMD_PHY_TX); + + return Response; +} + +/** + @fn RIE_Responses RadioTxPacketVariableLen(RIE_U8 Len, RIE_U8 *pData) + @brief Transmit a Variable length packet. + @param Len :{1-240} Length of packet to be transmitted. + @param pData :{} Data bytes to be transmitted. + @pre RadioInit() must be called before this function is called. + @code + if (RIE_Response == RIE_Success) + RIE_Response = RadioTxSetPA(DifferentialPA,PowerLevel15); + if (RIE_Response == RIE_Success) + RIE_Response = RadioTxPacketVariableLen(12, "HELLO WORLD"); + while (!RadioTxPacketComplete()); + @endcode + @return RIE_Responses Error code +**/ +RIE_Responses RadioTxPacketVariableLen(RIE_U8 Len, RIE_U8 *pData) +{ + RIE_Responses Response = RIE_Success; + + bPacketTx = RIE_FALSE; + + Len += 0x1; + if (Len > PACKETRAM_LEN) + Response = RIE_InvalidParamter; + if (Response == RIE_Success) + Response = RadioToOnMode(); + if (Response == RIE_Success) + Response = RadioMMapWrite(PACKETRAM_START, 0x1, &Len); + if (Response == RIE_Success) + Response = RadioMMapWrite(PACKETRAM_START+0x1, Len-1, pData); + if (Response == RIE_Success) + { + RadioConfiguration.packet_length_max_r = PACKETRAM_LEN; + RadioConfiguration.packet_length_control_r &= ~packet_length_control_packet_len_fixed; + } + if(Response == RIE_Success) + Response = RadioCommitRadioConfig(); + if (Response == RIE_Success) + Response = RadioToOnMode(); + if (Response == RIE_Success) + Response = RadioSendCommandWait(CMD_PHY_TX); + + return Response; +} + + +/** + @fn RIE_BOOL RadioTxPacketComplete(void) + @brief Checks if a packet has finished transmitting + @pre RadioInit() must be called before this function is called. + @pre RadioRxPacketFixedLen() or equivalent should be called first. + @code + if (RIE_Response == RIE_Success) + RIE_Response = RadioTxSetPA(DifferentialPA,PowerLevel15); + if (RIE_Response == RIE_Success) + RIE_Response = RadioTxPacketFixedLen(12, "HELLO WORLD"); + while (!RadioTxPacketComplete()); + @endcode + @return RIE_BOOL RIE_TRUE if packet has finished transmitting, else RIE_FALSE +**/ +RIE_BOOL RadioTxPacketComplete (void) +{ + return bPacketTx; +} + +/** + @fn RIE_Responses RadioTxSetPA(RIE_PATypes PAType,RIE_PAPowerLevel Power) + @brief Set PA Type and the Transmit Power Level for Radio Transmission. + @param PAType :{DifferentialPA, SingleEndedPA} Select Single Ended or Differential PA Type + @param Power :{PowerLevel0 ,PowerLevel1 ,PowerLevel2 ,PowerLevel3, + PowerLevel4 ,PowerLevel5 ,PowerLevel6 ,PowerLevel7, + PowerLevel8 ,PowerLevel9 ,PowerLevel10,PowerLevel11, + PowerLevel12,PowerLevel13,PowerLevel14,PowerLevel15} + @pre RadioInit() must be called before this function is called. + @code + Response = RadioTxSetPA(SingleEndedPA,PowerLevel8); + @endcode + @note Differential PA is enabled by default. + @note Max TX Power is used by default. + @return RIE_Responses Error code +**/ +RIE_Responses RadioTxSetPA(RIE_PATypes PAType,RIE_PAPowerLevel Power) +{ + RIE_Responses Response = RIE_Success; + RIE_U8 ucNewRegVal = 0x0; + unsigned long pa_level_mcr,pa_ramp, codes_per_bit,min_codes_per_bit; + + switch (PAType) + { + case DifferentialPA: + ucNewRegVal |= radio_cfg_8_pa_single_diff_sel_differential; + break; + case SingleEndedPA: + ucNewRegVal |= radio_cfg_8_pa_single_diff_sel_single_ended; + break; + default: + Response = RIE_UnsupportedRadioConfig; + break; + } + if(Response == RIE_Success) + { + switch (Power) + { + case PowerLevel0 : + case PowerLevel1 : + case PowerLevel2 : + case PowerLevel3 : + case PowerLevel4 : + case PowerLevel5 : + case PowerLevel6 : + case PowerLevel7 : + case PowerLevel8 : + case PowerLevel9 : + case PowerLevel10: + case PowerLevel11: + case PowerLevel12: + case PowerLevel13: + case PowerLevel14: + case PowerLevel15: + ucNewRegVal |= ((RIE_U8)Power << radio_cfg_8_pa_power_offset); + // Calculate the minimum allowable codes per bit + pa_level_mcr = (((RIE_U8)Power)* 4) + 0x3; + min_codes_per_bit = (pa_level_mcr * 2500)/(DataRate/100); + pa_ramp = 0x1; + codes_per_bit = 256; + while (codes_per_bit > min_codes_per_bit) + { + pa_ramp++; + codes_per_bit = 512 >> pa_ramp; + if (pa_ramp >= 7) + break; // This is the maximum + } + ucNewRegVal |= ((RIE_U8)pa_ramp << radio_cfg_8_pa_ramp_offset); + break; + default: + Response = RIE_UnsupportedRadioConfig; + break; + } + } + + if(Response == RIE_Success) + { + if (ucNewRegVal != RadioConfiguration.radio_cfg_8_r ) + { + bRadioConfigurationChanged = RIE_TRUE; + RadioConfiguration.radio_cfg_8_r = ucNewRegVal; + } + } + return Response; +} +/** + @fn RIE_Responses RadioTxCarrier(void) + @brief Transmit a carrier tone + using the current radio configuration. + @pre RadioInit() must be called before this function is called. + @code + Response = RadioTxCarrier(); + @endcode + @note Terminate this mode by calling RadioTerminateRadioOp(); + @return RIE_Responses Error code +**/ +RIE_Responses RadioTxCarrier (void) +{ + RIE_Responses Response = RIE_Success; + RIE_U8 ParamTX = PARAM_TX_CARRIER_FOREVER; + + if(Response == RIE_Success) + Response = RadioCommitRadioConfig(); + bTestModeEnabled = RIE_TRUE; + if (Response == RIE_Success) + Response = RadioToOnMode(); + // Mode needs to be set, before entry to PHY_TX + if (Response == RIE_Success) + Response = RadioMMapWrite(PR_var_tx_mode_ADR,sizeof(ParamTX),&ParamTX); + if (Response == RIE_Success) + Response = RadioSendCommandWait(CMD_PHY_TX); + return Response; +} +/** + @fn RIE_Responses RadioTxPreamble(void) + @brief Transmit a pre-amble (alternating ones and zeros) + using the current radio configuration. + @pre RadioInit() must be called before this function is called. + @code + Response = RadioTxPreamble(); + @endcode + @note Terminate this mode by calling RadioTerminateRadioOp(); + @return RIE_Responses Error code +**/ +RIE_Responses RadioTxPreamble (void) +{ + RIE_Responses Response = RIE_Success; + RIE_U8 ParamTX = PARAM_TX_PREAMBLE_FOREVER; + + if(Response == RIE_Success) + Response = RadioCommitRadioConfig(); + if (Response == RIE_Success) + Response = RadioToOnMode(); + bTestModeEnabled = RIE_TRUE; + // Mode needs to be set, before entry to PHY_TX + if (Response == RIE_Success) + Response = RadioMMapWrite(PR_var_tx_mode_ADR,sizeof(ParamTX),&ParamTX); + if (Response == RIE_Success) + Response = RadioSendCommandWait(CMD_PHY_TX); + return Response; +} + +/** + @fn RIE_Responses RadioRxPacketFixedLen(RIE_U8 Len) + @brief Enter receive mode and wait for a packet to be received. + + Radio will stay in Receive Mode until + 1) A packet is received. + 2) User manually exits Receive Mode with a call to RadioTerminateRadioOp() + + @param Len :{1-240} Fixed Length of packet to be received. + @pre RadioInit() must be called before this function is called. + @return RIE_Responses Error code +**/ +RIE_Responses RadioRxPacketFixedLen(RIE_U8 Len) +{ + RIE_Responses Response = RIE_Success; + + bPacketRx = RIE_FALSE; + if (Len > PACKETRAM_LEN) + Response = RIE_InvalidParamter; + + if (Response == RIE_Success) + { + RadioConfiguration.packet_length_max_r = Len; + RadioConfiguration.packet_length_control_r |= packet_length_control_packet_len_fixed; + } + if(Response == RIE_Success) + Response = RadioCommitRadioConfig(); + if (Response == RIE_Success) + Response = RadioToOnMode(); + if (Response == RIE_Success) + Response = RadioSendCommandWait(CMD_PHY_RX); + return Response; +} + +/** + @fn RIE_Responses RadioRxPacketVariableLen(void) + @brief Enter receive mode and wait for a packet to be received. + + Radio will stay in Receive Mode until + 1) A packet is received. + 2) User manually exits Receive Mode with a call to RadioTerminateRadioOp() + + @pre RadioInit() must be called before this function is called. + @return RIE_Responses Error code +**/ +RIE_Responses RadioRxPacketVariableLen(void) +{ + RIE_Responses Response = RIE_Success; + + bPacketRx = RIE_FALSE; + + if (Response == RIE_Success) + { + RadioConfiguration.packet_length_max_r = PACKETRAM_LEN; + RadioConfiguration.packet_length_control_r &= ~packet_length_control_packet_len_fixed; + } + if(Response == RIE_Success) + Response = RadioCommitRadioConfig(); + if (Response == RIE_Success) + Response = RadioToOnMode(); + if (Response == RIE_Success) + Response = RadioSendCommandWait(CMD_PHY_RX); + return Response; +} + +/** + @fn RIE_BOOL RadioRxPacketAvailable(void) + @brief Checks if a packet has been received. + @pre RadioInit() must be called before this function is called. + @pre RadioRxPacketFixedLen() or equivalent should be called first. + @code + if (RIE_Response == RIE_Success) + RIE_Response = RadioRxPacketFixedLen(12); + if (RIE_Response == RIE_Success) + { + while (!RadioRxPacketAvailable()); + } + if (RIE_Response == RIE_Success) + { + unsigned char Buffer[0x20]; + RIE_U8 PktLen; + RIE_S8 RSSI; + RIE_Response = RadioRxPacketRead(sizeof(Buffer),&PktLen,Buffer,&RSSI); + } + @endcode + @return RIE_BOOL RIE_TRUE if packet received, else RIE_FALSE +**/ +RIE_BOOL RadioRxPacketAvailable(void) +{ + return bPacketRx; + +} + +/** + @fn RIE_Responses RadioRxPacketRead(RIE_U8 BufferLen,RIE_U8 *pPktLen,RIE_U8 *pData,RIE_S8 *pRSSIdBm) + @brief Read the packet that was received by the radio. + @param BufferLen :{1-240} Size of passed in buffer + @param pPktLen :{1-240} Storage for size of actual received packet + @param pData :{} Received Packet will be stored here. + @param pRSSIdBm :{} RSSI of received packet in dBm. + @pre RadioInit() must be called before this function is called. + @pre RadioRxPacketFixedLen() or equivalent should be called first. + @code + if (RIE_Response == RIE_Success) + RIE_Response = RadioRxPacketFixedLen(12); + if (RIE_Response == RIE_Success) + { + while (!RadioRxPacketAvailable()); + } + if (RIE_Response == RIE_Success) + { + unsigned char Buffer[0x20]; + RIE_U8 PktLen; + RIE_S8 RSSI; + RIE_Response = RadioRxPacketRead(sizeof(Buffer),&PktLen,Buffer,&RSSI); + } + @endcode + @note Check for the presence of a packet by calling RadioRxPacketAvailable(); + @return RIE_Responses Error code +**/ +RIE_Responses RadioRxPacketRead(RIE_U8 BufferLen,RIE_U8 *pPktLen,RIE_U8 *pData,RIE_S8 *pRSSIdBm) +{ + RIE_Responses Response = RIE_Success; + + if (RadioRxPacketAvailable()) + { + RIE_U8 RdLen; + if(RadioConfiguration.packet_length_control_r & packet_length_control_packet_len_fixed) + { + if (pPktLen) + *pPktLen = RadioConfiguration.packet_length_max_r; + RdLen = RadioConfiguration.packet_length_max_r; + if (RdLen > BufferLen) + RdLen = BufferLen; + if (Response == RIE_Success) + Response = RadioMMapRead(PACKETRAM_START,RdLen, pData); + } + else + { + if (Response == RIE_Success) + Response = RadioMMapRead(PACKETRAM_START,0x1, &RdLen); + RdLen -= 0x1; + if (pPktLen) + *pPktLen = RdLen; + if (RdLen > BufferLen) + RdLen = BufferLen; + if (Response == RIE_Success) + Response = RadioMMapRead(PACKETRAM_START+0x1,RdLen, pData); + } + + if (pRSSIdBm) + { + if (Response == RIE_Success) + Response = RadioMMapRead(MCR_rssi_readback_Adr,0x1, (RIE_U8 *)pRSSIdBm); + + *pRSSIdBm -= 107; // Convert to dBm + } + + } + else + { + if (pPktLen) + *pPktLen = 0x0; + } + + return Response; +} + +/** + @fn RIE_Responses RadioRxBERTestMode(void) + @brief Enter receiver Bit Error Rate (BER) test mode where the + clock and data appear on GPIO pins. + Clock on P0.6 and Data on P2.6 + @pre RadioInit() must be called before this function is called. + @code + Response = RadioRxBERTestMode(); + @endcode + @note Terminate this mode by calling RadioTerminateRadioOp(); + @return RIE_Responses Error code +**/ +RIE_Responses RadioRxBERTestMode(void) +{ + RIE_Responses Response = RIE_Success; + RIE_U8 Data; + // Enables internal radio signals on external pins + // but overrides some of the standard GPIO muxed + // functionality (UART?) + pADI_MISC->RFTST = 0x7E1; + + if(Response == RIE_Success) + Response = RadioCommitRadioConfig(); + + bTestModeEnabled = RIE_TRUE; + // Enable the RX signals on GPIO pins + Data = gpio_configure_sport_mode_0; + if (Response == RIE_Success) + Response = RadioMMapWrite(MCR_gpio_configure_Adr, 0x1, (RIE_U8 *)&Data); + + // disable ext_uc_clk on GP5 + Data = 0; + if (Response == RIE_Success) + Response = RadioMMapWrite(MCR_ext_uc_clk_divide_Adr, + 0x1, + (RIE_U8 *)&Data); + if (Response == RIE_Success) + Response = RadioSendCommandWait(CMD_PHY_RX); + return Response; +} + +/** + @internal Hide from Doxegen + @fn RIE_Responses RadioCommitRadioConfig(void) + @brief Configures the radio if any changes were made + since the last time. + @return RIE_Responses Error code +**/ +static RIE_Responses RadioCommitRadioConfig(void) +{ + RIE_Responses Response = RIE_Success; + + if(bTestModeEnabled) + { + RIE_U8 Data; + Data = gpio_configure_default; + if (Response == RIE_Success) + Response = RadioMMapWrite(MCR_gpio_configure_Adr, 0x1, (RIE_U8 *)&Data); + Data = 4; + if (Response == RIE_Success) + Response = RadioMMapWrite(MCR_ext_uc_clk_divide_Adr, + 0x1, + (RIE_U8 *)&Data); + + Data = PARAM_TX_NORMAL_PACKET; + if (Response == RIE_Success) + Response = RadioMMapWrite(PR_var_tx_mode_ADR,sizeof(Data),&Data); + bTestModeEnabled = RIE_FALSE; + } + if (bRadioConfigurationChanged) + { + Response = RadioConfigure(); + if(Response == RIE_Success) + bRadioConfigurationChanged = RIE_FALSE; + } + return Response; +} +/** + @fn RIE_Responses RadioReadState(RadioState *pState) + @brief Read the current state + @param pState Pointer to return storage of state + @return RIE_Responses Error code +**/ +static RIE_Responses RadioReadState(RadioState *pState) +{ + RIE_Responses Response = RIE_Success; + RIE_U8 StatusByte; + + NVIC_DisableIRQ(UHFTRX_IRQn); + RADIO_CSN_ASSERT; + if (Response == RIE_Success) + Response = RadioSPIXferByte(SPI_NOP,NULL); + if (Response == RIE_Success) + Response = RadioSPIXferByte(SPI_NOP,&StatusByte); + RADIO_CSN_DEASSERT; + NVIC_EnableIRQ (UHFTRX_IRQn); + if ((Response == RIE_Success) && pState) + *pState = (RadioState)(StatusByte & STATUS_BYTE_FW_STATE); + return Response; +} + +/** + @fn RIE_Responses RadioWaitOnState(RadioState FinalState) + @brief Wait for Final State to be reached + @param FinalState State to wait on + @return RIE_Responses Error code +**/ +static RIE_Responses RadioWaitOnState(RadioState FinalState) +{ + RIE_Responses Response = RIE_Success; + RadioState CurrState; + do + { + Response = RadioReadState(&CurrState); + } + while((Response == RIE_Success) && (CurrState != FinalState)); + return Response; +} + +/** + @fn RIE_Responses RadioWaitOnCmdLdr(void) + @brief Wait for Final State to be reached + @return RIE_Responses Error code +**/ +static RIE_Responses RadioWaitOnCmdLdr(void) +{ + RIE_Responses Response = RIE_Success; + do + { + RIE_U8 StatusByte; + NVIC_DisableIRQ(UHFTRX_IRQn); + RADIO_CSN_ASSERT; + if (Response == RIE_Success) + Response = RadioSPIXferByte(SPI_NOP,NULL); + if (Response == RIE_Success) + Response = RadioSPIXferByte(SPI_NOP,&StatusByte); + RADIO_CSN_DEASSERT; + NVIC_EnableIRQ (UHFTRX_IRQn); + if ((Response == RIE_Success)) + if(StatusByte & STATUS_BYTE_CMD_READY) + break; + } + while((Response == RIE_Success)); + return Response; +} + +/** + @internal Hide from Doxegen + @fn RIE_Responses RadioToOnMode(void) + @brief Transition to On Mode + + Handle all possible states that the radio could be in + and brings it back to PHY_ON state + @param None + @return RIE_Responses Error code +**/ +static RIE_Responses RadioToOnMode(void) +{ + RIE_Responses Response = RIE_Success; + RadioState FwState; + + if (Response == RIE_Success) + Response = RadioReadState(&FwState); + + while ((FwState != FW_ON) && (Response == RIE_Success)) + { + switch (FwState) + { + case FW_BUSY: + break; + case FW_TX: + if(Response == RIE_Success) + Response = RadioSendCommandNoWait(CMD_PHY_ON); + if (Response == RIE_Success) + Response = RadioWaitOnState (FW_ON); + break; + case FW_RX: + if(Response == RIE_Success) + Response = RadioSendCommandNoWait(CMD_PHY_ON); + if (Response == RIE_Success) + Response = RadioWaitOnState (FW_ON); + break; + default: + if(Response == RIE_Success) + Response = RadioSendCommandNoWait(CMD_PHY_ON); + if (Response == RIE_Success) + Response = RadioWaitOnState (FW_ON); + break; + } + if (Response == RIE_Success) + Response = RadioReadState(&FwState); + } + return Response; +} +/** + @internal Hide from Doxegen + @fn RIE_Responses RadioToOffMode(void) + @brief Transition to Off Mode + + Handle all possible states that the radio could be in + and bring it back to PHY_OFF state. + + @param None + @return RIE_Responses Error code +**/ +static RIE_Responses RadioToOffMode(void) +{ + RIE_Responses Response = RIE_Success; + RadioState FwState; + + if (Response == RIE_Success) + Response = RadioReadState(&FwState); + + while ((FwState != FW_OFF) && (Response == RIE_Success)) + { + switch (FwState) + { + case FW_BUSY: + break; + case FW_TX: + if(Response == RIE_Success) + Response = RadioSendCommandNoWait(CMD_PHY_ON); + if (Response == RIE_Success) + Response = RadioWaitOnState (FW_ON); + break; + case FW_RX: + if(Response == RIE_Success) + Response = RadioSendCommandNoWait(CMD_PHY_ON); + if (Response == RIE_Success) + Response = RadioWaitOnState (FW_ON); + break; + default: + if(Response == RIE_Success) + Response = RadioSendCommandNoWait(CMD_PHY_OFF); + if (Response == RIE_Success) + Response = RadioWaitOnState (FW_OFF); + break; + } + if (Response == RIE_Success) + Response = RadioReadState(&FwState); + } + return Response; +} +/** + @internal Hide from Doxegen + @fn RIE_Responses RadioSyncComms (void) + @brief Sync comms with the radio + @param None + @return RIE_Responses Error code +**/ +static RIE_Responses RadioSyncComms (void) +{ + RIE_Responses Response = RIE_Success; + if (Response == RIE_Success) + Response = RadioSendCommandWait(CMD_SYNC); + if (Response == RIE_Success) + Response = RadioWaitOnCmdLdr(); + return Response; +} +/** + @fn RIE_Responses RadioWaitForPowerUp(void) + @brief Wake Up the Part + + Assert SPI chip select which will wake up the radio if asleep + Wait for MISO line to go high indicating SPI comms now possible + + @return RIE_Responses Error code +**/ +static RIE_Responses RadioWaitForPowerUp(void) +{ + RIE_Responses Response = RIE_Success; + int i = 0x0; + RADIO_CSN_ASSERT; + while (!RADIO_MISO_IN && (i < 1000)) + i++; + if (1000 == i)// Timed out waiting for MISO high? + Response = RIE_RadioSPICommsFail; + RADIO_CSN_DEASSERT; + return Response; +} + +/** + \internal Hide from Doxegen + \fn void Ext_Int8_Handler(void) + \brief Radio Interrupt Handler +**/ +extern void aducrf101_rx_packet_hook(void); +void Ext_Int8_Handler (void) +{ + RIE_Responses Response = RIE_Success; + RIE_U8 ucInt0; + RIE_U8 ucInt1; + + if (Response == RIE_Success) + Response = RadioMMapRead(MCR_interrupt_source_0_Adr,0x1, &ucInt0); + if (Response == RIE_Success) + Response = RadioMMapRead(MCR_interrupt_source_1_Adr,0x1,&ucInt1); + if (ucInt0 & interrupt_mask_0_interrupt_tx_eof) + bPacketTx = RIE_TRUE; + if (ucInt0 & interrupt_mask_0_interrupt_crc_correct) { + bPacketRx = RIE_TRUE; + aducrf101_rx_packet_hook(); + } + // Clear all the interrupts that we have just handleed + if (Response == RIE_Success) + Response = RadioMMapWrite(MCR_interrupt_source_0_Adr,0x1, &ucInt0); + if (Response == RIE_Success) + Response = RadioMMapWrite(MCR_interrupt_source_1_Adr,0x1,&ucInt1); + // Clear the interrupt + pADI_INTERRUPT->EICLR = EICLR_IRQ8; +} +/** + \internal Hide from Doxegen + \fn void RadioSPIXferByte(RIE_U8 ucByte,RIE_U8 *pData) + \brief Transfer a byte via SPI to the radio and optionally return + received byte. + Chip Select is manually controlled elsewhere. + \param ucByte Command or data byte to be transferred. + \param pData NULL, or storage for response + \return RIE_Responses Error code +**/ +static RIE_Responses RadioSPIXferByte(RIE_U8 ucByte,RIE_U8 *pData) +{ + RIE_Responses Response = RIE_Success; + + SEND_SPI(ucByte); // Send byte + WAIT_SPI_RX; // wait for data received status bit + if(pData) + *pData = READ_SPI; + else + (void)READ_SPI; + return Response; +} +/** + \internal Hide from Doxegen + \fn RIE_Responses RadioSendCommandBytes(RIE_U8 *pCmdBytes,RIE_U8 NumBytes) + \brief Send a complete command to the radio. + + It is neccessary to disable the radio interrupt when doing this + as a command in progress must finish before a radio interrupt + can be handled. + + \param pCmdBytes Pointer to a number of bytes to be transferred. + \param NumBytes Number of bytes to transfer + + \return RIE_Responses Error code +**/ +static RIE_Responses RadioSendCommandBytes(RIE_U8 *pCmdBytes,RIE_U8 NumBytes) +{ + RIE_Responses Response = RIE_Success; + + NVIC_DisableIRQ(UHFTRX_IRQn); + RADIO_CSN_ASSERT; + while ((NumBytes--) && (Response == RIE_Success)) + Response = RadioSPIXferByte(*(pCmdBytes++),NULL); // Send Command + RADIO_CSN_DEASSERT; // De-assert SPI chip select + NVIC_EnableIRQ (UHFTRX_IRQn); + + return Response; +} +/** + \internal Hide from Doxegen + \fn RIE_Responses RadioSendCommandNoWait (Radio_CmdCodes CmdCode ) + \brief Send a single byte command to the radio. + \param CmdCode Command code to be sent + \return RIE_Responses Error code +**/ +static RIE_Responses RadioSendCommandNoWait (Radio_CmdCodes CmdCode ) +{ + RIE_U8 Command = (RIE_U8)CmdCode; + return RadioSendCommandBytes(&Command,0x1); +} +/** + \internal Hide from Doxegen + \fn RIE_Responses RadioSendCommandWait (Radio_CmdCodes CmdCode ) + \brief Send a single byte command to the radio. + \param CmdCode Command code to be sent + \return RIE_Responses Error code +**/ +static RIE_Responses RadioSendCommandWait (Radio_CmdCodes CmdCode ) +{ + RIE_Responses Response = RIE_Success; + RIE_U8 Command = (RIE_U8)CmdCode; + + if (Response == RIE_Success) + Response = RadioWaitOnCmdLdr(); + if (Response == RIE_Success) + Response = RadioSendCommandBytes(&Command,0x1); + return Response; +} +/** + \fn RIE_Responses RadioMMapRead(RIE_U32 ulAdr, RIE_U32 ulLen, RIE_U8 *pData) + \brief Read bytes from specified memory map address + \param ulAdr Address to read at. + \param ulLen Length of data to read. + \param pData Pointer to location to stored read data. + \return RIE_Responses Error code +**/ +static RIE_Responses RadioMMapRead(RIE_U32 ulAdr, RIE_U32 ulLen, RIE_U8 *pData) +{ + RIE_Responses Response = RIE_Success; + + NVIC_DisableIRQ(UHFTRX_IRQn); + RADIO_CSN_ASSERT; + + if(Response == RIE_Success) // Send first byte (SPI_MEMR_RD + Bytes) + Response = RadioSPIXferByte(SPI_MEM_RD | ((ulAdr & 0x700) >> 8),NULL); + if(Response == RIE_Success)// Send Second byte remainder of address + Response = RadioSPIXferByte((RIE_U8)(ulAdr & 0xFF),NULL); + if(Response == RIE_Success) + Response = RadioSPIXferByte((RIE_U8)SPI_NOP,NULL); + while(ulLen-- && (Response == RIE_Success)) + Response = RadioSPIXferByte(SPI_NOP,pData++); + RADIO_CSN_DEASSERT; + NVIC_EnableIRQ (UHFTRX_IRQn); + + return Response; +} +/** + \fn RIE_Responses RadioMMapWrite(RIE_U32 ulAdr, RIE_U32 ulLen, RIE_U8 *pData) + \brief Read bytes from specified memory map address + \param ulAdr Address to read at. + \param ulLen Length of data to read. + \param pData Pointer to location of data to write. + \return RIE_Responses Error code +**/ +static RIE_Responses RadioMMapWrite(RIE_U32 ulAdr,RIE_U32 ulLen,RIE_U8 * pData) +{ + RIE_Responses Response = RIE_Success; + + NVIC_DisableIRQ(UHFTRX_IRQn); + RADIO_CSN_ASSERT; + if(Response == RIE_Success) // Send first byte (SPI_MEMR_WR + Bytes) + Response = RadioSPIXferByte(SPI_MEM_WR | ((ulAdr & 0x700) >> 8),NULL); + if(Response == RIE_Success) // Send Second byte remainder of addrress + Response = RadioSPIXferByte((RIE_U8)(ulAdr & 0xFF),NULL); + while(ulLen-- && (Response == RIE_Success)) + Response = RadioSPIXferByte(*(pData++),NULL); + RADIO_CSN_DEASSERT; + NVIC_EnableIRQ (UHFTRX_IRQn); + + return Response; +} + +/** + \internal Hide from Doxegen + \fn void SetRadioConfiguration(void) + \brief Create a default radio configuration that all base configurations + are derived from. + + \return RIE_Responses Error code +**/ +static RIE_Responses SetRadioConfiguration(RIE_BaseConfigs BaseConfig) +{ + RIE_Responses Response = RIE_Success; + + bRadioConfigurationChanged = RIE_TRUE; + switch (BaseConfig) + { + case DR_1_0kbps_Dev10_0kHz: + memcpy((void *)&RadioConfiguration, + (void *)DR_1_0kbps_Dev10_0kHz_Configuration, + sizeof(TyRadioConfiguration)); + DataRate = 1000; + break; + case DR_38_4kbps_Dev20kHz: + memcpy((void *)&RadioConfiguration, + (void *)DR_38_4kbps_Dev20kHz_Configuration, + sizeof(TyRadioConfiguration)); + DataRate = 38400; + break; + case DR_300_0kbps_Dev75_0kHz: + memcpy((void *)&RadioConfiguration, + (void *)DR_300_0kbps_Dev75_0kHz_Configuration, + sizeof(TyRadioConfiguration)); + DataRate = 300000; + break; + default: + Response = RIE_UnsupportedRadioConfig; + break; + } + return Response; +} +/** + @internal Hide from Doxegen + @fn RIE_Responses RadioConfigure (void) + @brief Configure the Radio as per the current configuration + @return RIE_Responses Error code +**/ +RIE_Responses RadioConfigure (void) +{ + RIE_Responses Response = RIE_Success; + if(Response == RIE_Success) + Response = RadioToOffMode(); + if(Response == RIE_Success) // Write the configuration to the radio memory + Response = RadioMMapWrite(BBRAM_START, + sizeof(TyRadioConfiguration), + (RIE_U8 *)&RadioConfiguration); + if(Response == RIE_Success) // Apply that configuration to the radio + Response = RadioSendCommandWait(CMD_CONFIG_DEV); + if(Response == RIE_Success) + Response = RadioToOnMode(); + return Response; +} + + +/** + @fn RIE_Responses RadioRadioGetRSSI (RIE_S8 *pRSSIdBm) + @brief Return a Received Signal Strength Indicator value + @param pRSSIdBm :{} detected RSSI in dBm. + @pre RadioInit() must be called before this function is called. + @code + RIE_S8 RSSIdBm; + if (RIE_Response == RIE_Success) + RIE_Response = RadioRadioGetRSSI(&RSSIdBm); + @endcode + @return RIE_Responses Error code +**/ +RIE_Responses RadioRadioGetRSSI (RIE_S8 *pRSSIdBm) +{ + RIE_Responses Response = RIE_Success; + + if(Response == RIE_Success) + Response = RadioCommitRadioConfig(); + if (Response == RIE_Success) + Response = RadioToOnMode(); + if (Response == RIE_Success) + Response = RadioSendCommandWait(CMD_GET_RSSI); + if (Response == RIE_Success) + Response = RadioSyncComms(); // + if (pRSSIdBm) + { + if (Response == RIE_Success) + Response = RadioMMapRead(MCR_rssi_readback_Adr,0x1, (RIE_U8 *)pRSSIdBm); + *pRSSIdBm -= 107; // Convert to dBm + } + return Response; +} + +/** + @fn RIE_Responses RadioTxSetPower(RIE_PAPowerLevel Power) + @brief Set the Transmit Power Level for Radio Transmission. + @param Power :{PowerLevel0 ,PowerLevel1 ,PowerLevel2 ,PowerLevel3, + PowerLevel4 ,PowerLevel5 ,PowerLevel6 ,PowerLevel7, + PowerLevel8 ,PowerLevel9 ,PowerLevel10,PowerLevel11, + PowerLevel12,PowerLevel13,PowerLevel14,PowerLevel15} + @pre RadioInit() must be called before this function is called. + @code + Response = RadioTxSetPower(PowerLevel8); + @endcode + @note Max TX Power is used by default. + @return RIE_Responses Error code +*/ +RIE_Responses RadioTxSetPower (RIE_PAPowerLevel Power) +{ + RIE_Responses Response = RIE_Success; + RIE_U8 ucNewRegVal = RadioConfiguration.radio_cfg_8_r; + unsigned long pa_level_mcr,pa_ramp, codes_per_bit,min_codes_per_bit; + + if (RadioConfiguration.radio_cfg_8_r & radio_cfg_8_pa_single_diff_sel_differential) + ucNewRegVal = radio_cfg_8_pa_single_diff_sel_differential; + else + ucNewRegVal = radio_cfg_8_pa_single_diff_sel_single_ended; + + if(Response == RIE_Success) + { + switch (Power) + { + case PowerLevel0 : + case PowerLevel1 : + case PowerLevel2 : + case PowerLevel3 : + case PowerLevel4 : + case PowerLevel5 : + case PowerLevel6 : + case PowerLevel7 : + case PowerLevel8 : + case PowerLevel9 : + case PowerLevel10: + case PowerLevel11: + case PowerLevel12: + case PowerLevel13: + case PowerLevel14: + case PowerLevel15: + ucNewRegVal |= ((RIE_U8)Power << radio_cfg_8_pa_power_offset); + // Calculate the minimum allowable codes per bit + pa_level_mcr = (((RIE_U8)Power)* 4) + 0x3; + min_codes_per_bit = (pa_level_mcr * 2500)/(DataRate/100); + pa_ramp = 0x1; + codes_per_bit = 256; + while (codes_per_bit > min_codes_per_bit) + { + pa_ramp++; + codes_per_bit = 512 >> pa_ramp; + if (pa_ramp >= 7) + break; // This is the maximum + } + ucNewRegVal |= ((RIE_U8)pa_ramp << radio_cfg_8_pa_ramp_offset); + break; + default: + Response = RIE_UnsupportedRadioConfig; + break; + } + } + + if(Response == RIE_Success) + { + if (ucNewRegVal != RadioConfiguration.radio_cfg_8_r ) + { + // Write directly to the MCR in this case and avoid a reconfigure + if (Response == RIE_Success) + Response = RadioMMapWrite(MCR_pa_level_mcr_Adr, 0x1, (RIE_U8 *)&ucNewRegVal); + RadioConfiguration.radio_cfg_8_r = ucNewRegVal; + } + } + return Response; +} + diff --git a/cpu/arm/aducrf101/Common/radioeng.h b/cpu/arm/aducrf101/Common/radioeng.h new file mode 100644 index 000000000..22f68cc63 --- /dev/null +++ b/cpu/arm/aducrf101/Common/radioeng.h @@ -0,0 +1,174 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** +@file radioeng.h +@brief Radio Interface Engine Functions +@version v1.0 +@author PAD CSE group, Analog Devices Inc +@date May 08th 2013 +**/ + +#define RIE_U32 unsigned long +#define RIE_U16 unsigned short int +#define RIE_U8 unsigned char +#define RIE_S8 signed char + +/*! \enum RIE_BaseConfigs + * Variables of this type are used to define the Base Configuration + */ +/*! \var RIE_BaseConfigs DR_1_0kbps_Dev10_0kHz + * Base configuration of 1 kbps datarate, 10.0 kHz frequency deviation. + Use for achieving longer distances. + */ +/*! \var RIE_BaseConfigs DR_38_4kbps_Dev20kHz + * Base configuration of 38.4 kbps datarate, 20 kHz frequency deviation. + Use as a compromise of distance and power. + */ +/*! \var RIE_BaseConfigs DR_300_0kbps_Dev75_0kHz + * Base configuration of 300 kbps datarate, 75 kHz frequency deviation. + Use for achieving faster transmission times hence lower power. + */ +typedef enum +{ + DR_1_0kbps_Dev10_0kHz = 0x0, + DR_38_4kbps_Dev20kHz = 0x1, + DR_300_0kbps_Dev75_0kHz = 0x2, + UnsupportedDRDev +} RIE_BaseConfigs; + +/*! \enum RIE_ModulationTypes + * Variables of this type are used to define a tx modulation type + */ +/*! \var RIE_ModulationTypes FSK_Modulation + * FSK Modulation + */ +/*! \var RIE_ModulationTypes GFSK_Modulation + * GFSK Modulation + */ +typedef enum {FSK_Modulation = 0, GFSK_Modulation = 1} RIE_ModulationTypes; + +/*! \enum RIE_PATypes + * Variables of this type are used to define a PA type + */ +/*! \var RIE_PATypes DifferentialPA + * Differential PA + */ +/*! \var RIE_PATypes SingleEndedPA + * Single Ended PA + */ +typedef enum {DifferentialPA = 0, SingleEndedPA = 1} RIE_PATypes; + + + +typedef enum {PowerLevel0 ,PowerLevel1 ,PowerLevel2 ,PowerLevel3, + PowerLevel4 ,PowerLevel5 ,PowerLevel6 ,PowerLevel7, + PowerLevel8 ,PowerLevel9 ,PowerLevel10,PowerLevel11, + PowerLevel12,PowerLevel13,PowerLevel14,PowerLevel15 + } RIE_PAPowerLevel; + + +/*! \enum RIE_BOOL + * Variables of this type are used to define a TRUE or FALSE condition + */ +/*! \var RIE_BOOL RIE_TRUE + * TRUE condition + */ +/*! \var RIE_BOOL RIE_FALSE + * FALSE condition + */ +typedef enum {RIE_FALSE = 0, RIE_TRUE = !RIE_FALSE} RIE_BOOL; + + +/*! \enum RIE_Responses + * Variables of this type are used to define the return value from functions + */ +/*! \var RIE_Responses RIE_Success + * Successful completion + */ +/*! \var RIE_Responses RIE_RadioSPICommsFail + * SPI communications with the radio failure. + */ +/*! \var RIE_Responses RIE_UnsupportedRadioConfig + * This is an unsupported radio configuration + */ +/*! \var RIE_Responses RIE_Unimplemented + * This feature has not been implemented + */ +/*! \var RIE_Responses RIE_InvalidParamter + * An invaild parameter was passed + */ +typedef enum +{ + RIE_Success = 0x0, + RIE_RadioSPICommsFail = 0x1, + RIE_UnsupportedRadioConfig = 0x2, + RIE_Unimplemented = 0x3, + RIE_InvalidParamter = 0x4, +} RIE_Responses; + +// Added in Radio Interface Engine v0.1 +RIE_Responses RadioGetAPIVersion (RIE_U32 *pVersion); +RIE_Responses RadioInit (RIE_BaseConfigs BaseConfig); +RIE_Responses RadioPowerOff (void); +RIE_Responses RadioTerminateRadioOp (void); +RIE_Responses RadioSetFrequency (RIE_U32 Frequency); +RIE_Responses RadioSetModulationType (RIE_ModulationTypes ModulationType); +RIE_Responses RadioPayldManchesterEncode(RIE_BOOL bEnable); +RIE_Responses RadioPayldDataWhitening (RIE_BOOL bEnable); +RIE_Responses RadioTxPacketFixedLen (RIE_U8 Len, RIE_U8 *pData); +RIE_BOOL RadioTxPacketComplete (void); +RIE_Responses RadioTxSetPA (RIE_PATypes PAType,RIE_PAPowerLevel Power); +RIE_Responses RadioTxCarrier (void); +RIE_Responses RadioTxPreamble (void); +RIE_Responses RadioRxPacketFixedLen (RIE_U8 Len); +RIE_BOOL RadioRxPacketAvailable (void); +RIE_Responses RadioRxPacketRead (RIE_U8 BufferLen,RIE_U8 *pPktLen,RIE_U8 *pData,RIE_S8 *pRSSIdBm); +RIE_Responses RadioRxBERTestMode (void); + +// Added in Radio Interface Engine v0.2 +RIE_Responses RadioSwitchConfig (RIE_BaseConfigs BaseConfig); +RIE_Responses RadioRadioGetRSSI (RIE_S8 *pRSSIdBm); +RIE_Responses RadioTxSetPower (RIE_PAPowerLevel Power); + +// Added in Radio Interface Engine v0.3 +RIE_Responses RadioTxPacketVariableLen (RIE_U8 Len, RIE_U8 *pData); +RIE_Responses RadioRxPacketVariableLen (void); + +// Added in Radio Interface Engine v0.5 +RIE_Responses RadioDeInit (void); + + + + + diff --git a/cpu/arm/aducrf101/Common/system_ADuCRF101.c b/cpu/arm/aducrf101/Common/system_ADuCRF101.c new file mode 100644 index 000000000..f6abc0a98 --- /dev/null +++ b/cpu/arm/aducrf101/Common/system_ADuCRF101.c @@ -0,0 +1,178 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** +@file system_ADuCRF101.c +@brief CMSIS Cortex-M3 Device Peripheral Access Layer Implementation File + for the ADuCRF101 +@version v1.0 +@author PAD CSE group, Analog Devices Inc +@date January 14th 2013 +**/ + +#include +#include "ADuCRF101.h" + + +/*---------------------------------------------------------------------------- + DEFINES + *---------------------------------------------------------------------------*/ + +/* Extract the Clock Divider */ +#define __CCLK_DIV (1 << (pADI_CLKCTL->CLKCON & CLKCON_CD_MSK) ) + +/* define the clock multiplexer input frequencies */ +#define __HFOSC 16000000 +#define __LFXTAL 32768 +#define __LFOSC 32768 + +/*---------------------------------------------------------------------------- + Internal Clock Variables + *---------------------------------------------------------------------------*/ +static uint32_t uClk = 0; /* Undivided System Clock Frequency (UCLK) */ +static uint32_t uClkDiv = 0; /* Divided System Clock Frequency (UCLK_DIV) */ + +/* Frequency of the external clock source connected to P0.5 */ +static uint32_t SystemExtClock = 0; + +/*---------------------------------------------------------------------------- + Clock functions + *---------------------------------------------------------------------------*/ +void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */ +{ +/* pre-processor verification that clock mux mask and allowed values agree */ +#if ((CLKCON_CLKMUX_HFOSC \ + | CLKCON_CLKMUX_LFXTAL \ + | CLKCON_CLKMUX_LFOSC \ + | CLKCON_CLKMUX_EXTP05) \ + == CLKCON_CLKMUX_MSK) + + /* update the system core clock according the the current clock mux setting */ + switch (pADI_CLKCTL->CLKCON & CLKCON_CLKMUX_MSK ) { + + case CLKCON_CLKMUX_HFOSC: + uClk = __HFOSC; + break; + case CLKCON_CLKMUX_LFXTAL: + uClk = __LFXTAL; + break; + case CLKCON_CLKMUX_LFOSC: + uClk = __LFOSC; + break; + case CLKCON_CLKMUX_ECLKIN: + uClk = SystemExtClock; + break; + /* no need to catch default case due to pre-processor test */ + } + + /* update the divided system clock */ + uClkDiv = uClk / __CCLK_DIV; + +#else +#error "Clock mux mask and allowed value mismatch!" +#endif +} + +/** + * Initialize the system + * + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemFrequency variable. + */ +void SystemInit (void) +{ + /* reset CLKCON register */ + pADI_CLKCTL->CLKCON = CLKCON_RVAL; + + /* reset XOSCCON register */ + pADI_CLKCTL->XOSCCON = XOSCCON_RVAL; + + /* compute internal clocks */ + SystemCoreClockUpdate(); +} + +/** + * @brief Sets the system external clock frequency + * + * @param ExtClkFreq External clock frequency in Hz + * @return none + * + * Sets the clock frequency of the source connected to P0.5 clock input source + */ +void SetSystemExtClkFreq (uint32_t ExtClkFreq) +{ + SystemExtClock = ExtClkFreq; +} + +/** + * @brief Gets the system external clock frequency + * + * @return External Clock frequency + * + * Gets the clock frequency of the source connected to P0.5 clock input source + */ +uint32_t GetSystemExtClkFreq (void) +{ + return SystemExtClock; +} + + +/* set the system clock dividers */ +void SystemSetClockDivider(uint16_t div) +{ + /* critical region */ + __disable_irq(); + + /* read-modify-write without any interrupts */ + + pADI_CLKCTL->CLKCON &= ~(CLKCON_CD_MSK); /* keep everything else */ + pADI_CLKCTL->CLKCON |= div; /* set new value */ + + /* end critical region */ + __enable_irq(); + + /* refresh internal clock variables */ + SystemCoreClockUpdate(); +} + + +uint32_t SystemGetClockFrequency(void) +{ + return uClkDiv; +} + + + + diff --git a/cpu/arm/aducrf101/Common/system_ADuCRF101.h b/cpu/arm/aducrf101/Common/system_ADuCRF101.h new file mode 100644 index 000000000..241e3b062 --- /dev/null +++ b/cpu/arm/aducrf101/Common/system_ADuCRF101.h @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** +@file system_ADuCRF101.h +@brief: CMSIS Cortex-M3 Device Peripheral Access Layer Header File + for the ADuCRF101 +@version v0.2 +@author PAD CSE group, Analog Devices Inc +@date March 09th 2012 +**/ + + +#ifndef __SYSTEM_ADUCRF101_H__ +#define __SYSTEM_ADUCRF101_H__ + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * @brief Initialize the system + * + * @return none + * + * Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit (void); + +/** + * @brief Update internal SystemCoreClock variable + * + * @return none + * + * Updates the internal SystemCoreClock with current core + * Clock retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate (void); + + +/** + * @brief Sets the system external clock frequency + * + * @param ExtClkFreq External clock frequency in Hz + * @return none + * + * Sets the clock frequency of the source connected to P0.5 clock input source + */ +extern void SetSystemExtClkFreq (uint32_t ExtClkFreq); + + +/** + * @brief Gets the system external clock frequency + * + * @return External Clock frequency + * + * Gets the clock frequency of the source connected to P0.5 clock input source + */ +extern uint32_t GetSystemExtClkFreq (void); + + +#ifdef __cplusplus +} +#endif + +#endif /* __SYSTEM_ADUCRF101_H__ */ + diff --git a/cpu/arm/aducrf101/Makefile.aducrf101 b/cpu/arm/aducrf101/Makefile.aducrf101 new file mode 100644 index 000000000..350e89ab8 --- /dev/null +++ b/cpu/arm/aducrf101/Makefile.aducrf101 @@ -0,0 +1,88 @@ +# -*- makefile -*- + +# Copyright (c) 2014, Analog Devices, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted (subject to the limitations in the +# disclaimer below) 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 Analog Devices, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE +# GRANTED BY THIS LICENSE. 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 OWNER 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. + +# Author: Jim Paris + +CONTIKI_CPU = $(CONTIKI)/cpu/arm/aducrf101 + +ifdef IAR +include $(CONTIKI_CPU)/Makefile.aducrf101.iar +else +include $(CONTIKI_CPU)/Makefile.aducrf101.gnu +endif + +ifdef SERIAL_ID + CFLAGS += -DSERIAL_ID='$(SERIAL_ID)' +endif + +ifdef __STACK_SIZE + CFLAGS += -D__STACK_SIZE=$(__STACK_SIZE) +endif + +ifdef RF_CHANNEL + CFLAGS += -DRF_CHANNEL=$(RF_CHANNEL) +endif + +# HSI internal oscillator by default +CFLAGS += -DF_CPU=16000000 + +### CPU-dependent directories and source files +CONTIKI_CPU_DIRS += ../common/CMSIS + +CONTIKI_CPU_DIRS += . +CONTIKI_SOURCEFILES += slip-arch.c +CONTIKI_SOURCEFILES += rtimer-arch.c + +CONTIKI_CPU_DIRS += dev +CONTIKI_SOURCEFILES += uart.c +CONTIKI_SOURCEFILES += clock.c +CONTIKI_SOURCEFILES += watchdog.c +CONTIKI_SOURCEFILES += radio.c + +CONTIKI_CPU_DIRS += Common +CONTIKI_SOURCEFILES += system_ADuCRF101.c +CONTIKI_SOURCEFILES += radioeng.c + +ifdef CORE +.PHONY: symbols.c symbols.h +symbols.c symbols.h: + $(NM) -C $(CORE) | grep -v @ | grep -v dll_crt0 | \ + awk -f $(CONTIKI)/tools/mknmlist > symbols.c || rm -f symbols.c +else +symbols.c symbols.h: + cp ${CONTIKI}/tools/empty-symbols.c symbols.c + cp ${CONTIKI}/tools/empty-symbols.h symbols.h +endif + +contiki-$(TARGET).a: ${addprefix $(OBJECTDIR)/,symbols.o} diff --git a/cpu/arm/aducrf101/Makefile.aducrf101.gnu b/cpu/arm/aducrf101/Makefile.aducrf101.gnu new file mode 100644 index 000000000..bafb06aa9 --- /dev/null +++ b/cpu/arm/aducrf101/Makefile.aducrf101.gnu @@ -0,0 +1,86 @@ +# -*- makefile -*- + +# Copyright (c) 2014, Analog Devices, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted (subject to the limitations in the +# disclaimer below) 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 Analog Devices, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE +# GRANTED BY THIS LICENSE. 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 OWNER 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. + +# Author: Jim Paris + +CROSS_COMPILE = arm-none-eabi- + +CC = $(CROSS_COMPILE)gcc +LD = $(CROSS_COMPILE)gcc +AS = $(CROSS_COMPILE)gcc +AR = $(CROSS_COMPILE)gcc-ar +NM = $(CROSS_COMPILE)gcc-nm +OBJCOPY = $(CROSS_COMPILE)objcopy +OBJDUMP = $(CROSS_COMPILE)objdump +STRIP = $(CROSS_COMPILE)strip + +CFLAGS_OPT ?= -Os +CFLAGS_DEBUG ?= -ggdb3 -fomit-frame-pointer +CFLAGS += $(CFLAGS_OPT) $(CFLAGS_DEBUG) +CFLAGS += -std=gnu99 +CFLAGS += -ffreestanding -mcpu=cortex-m3 -mthumb -mno-thumb-interwork +CFLAGS += -ffunction-sections -fdata-sections -fno-common -fno-builtin +CFLAGS += -flto + +ifdef WERROR + CFLAGS += -Wall -Werror + # These warnings are triggered by existing Contiki code + CFLAGS += -Wno-error=pointer-sign + CFLAGS += -Wno-error=char-subscripts + CFLAGS += -Wno-error=unused-variable + CFLAGS += -Wno-error=unused-but-set-variable +endif + +# UIP code does not follow C aliasing rules +CFLAGS += -fno-strict-aliasing + +LDFLAGS = $(CFLAGS) +LDFLAGS += -specs=nosys.specs -nostartfiles + +# TODO: When it becomes more commonly available, switch to newlib-nano +# for significant size reduction, by uncommenting this: +# LDFLAGS += -specs=nano.specs + +LDFLAGS += -Wl,--gc-sections +LDFLAGS += -Wl,-T$(CONTIKI_CPU)/Common/GCC/ADuCRF101.ld + +ASFLAGS += -c $(CFLAGS) + +# Compiler-specific startup code +CONTIKI_CPU_DIRS += Common/GCC +CONTIKI_SOURCEFILES += crt0.S + +# Rules +%.hex: % + $(OBJCOPY) -O ihex $^ $@ \ No newline at end of file diff --git a/cpu/arm/aducrf101/Makefile.aducrf101.iar b/cpu/arm/aducrf101/Makefile.aducrf101.iar new file mode 100644 index 000000000..08f46be85 --- /dev/null +++ b/cpu/arm/aducrf101/Makefile.aducrf101.iar @@ -0,0 +1,94 @@ +# -*- makefile -*- + +# Copyright (c) 2014, Analog Devices, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted (subject to the limitations in the +# disclaimer below) 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 Analog Devices, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE +# GRANTED BY THIS LICENSE. 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 OWNER 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. + +# Author: Jim Paris + +# Filename quoting here is very tricky, and probably depends on which Windows +# build of "make" is being used. This works for mingw32-make. + +ifeq ($(IAR_PATH),) + IAR_SUBPATH := $(shell ls "${PROGRAMFILES}\IAR Systems" 2>/dev/null | tail -1) + ifeq ($(IAR_SUBPATH),) + define iar_error + +Unable to find the IAR installation path. Please specify IAR_PATH. +For example: $(MAKE) IAR_PATH="C:\\Program Files (x86)\\IAR Systems\\Embedded Workbench 7.0\\arm" + endef + $(error $(iar_error)) + endif + IAR_PATH := ${PROGRAMFILES}\IAR Systems\${IAR_SUBPATH}\arm +endif + +CC := "$(IAR_PATH)""\\bin\iccarm" +LD := "$(IAR_PATH)""\\bin\ilinkarm" +AS := "$(IAR_PATH)""\\bin\iasmarm" +AR := "$(IAR_PATH)""\\bin\iarchive" +OBJCOPY := "$(IAR_PATH)""\\bin\ielftool" + +CFLAGS += -Ohz +CFLAGS += --silent +CFLAGS += --debug +CFLAGS += --endian=little +CFLAGS += --cpu=Cortex-M3 +CFLAGS += -I"$(IAR_PATH)""\\inc" +CFLAGS += -D__ICCARM__ + +AROPTS = --create +ASFLAGS = -S -s+ -w+ --cpu Cortex-M3 + +LDFLAGS += --config $(CONTIKI_CPU)/Common/IAR/ADUCRF101.icf + +# Compiler-specific startup code +CONTIKI_CPU_DIRS += Common/IAR +CONTIKI_SOURCEFILES += startup_ADuCRF101.S + +# Rules + +CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 +$(OBJECTDIR)/%.o: %.c | $(OBJECTDIR) + $(TRACE_CC) + $(Q)$(CC) $(CFLAGS) $< --dependencies=m $(@:.o=.d) -o $@ + +CUSTOM_RULE_C_TO_O = 1 +%.co: %.c + $(TRACE_CC) + $(Q)$(CC) $(CFLAGS) $< -o $@ + +CUSTOM_RULE_C_TO_CO = 1 +%.co: %.c + $(TRACE_CC) + $(Q)$(CC) $(CFLAGS) -DAUTOSTART_ENABLE $< -o $@ + +%.hex: % + $(OBJCOPY) --silent --ihex $^ $@ diff --git a/cpu/arm/aducrf101/aducrf101-contiki.h b/cpu/arm/aducrf101/aducrf101-contiki.h new file mode 100644 index 000000000..4610c49d6 --- /dev/null +++ b/cpu/arm/aducrf101/aducrf101-contiki.h @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + * \author Jim Paris + */ + +#ifndef ADUCRF101_CONTIKI_H +#define ADUCRF101_CONTIKI_H + +#include + +#include + +typedef uint32_t clock_time_t; +typedef uint16_t uip_stats_t; + +typedef uint32_t rtimer_clock_t; +#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b))) +rtimer_clock_t rtimer_arch_now(void); + +#endif diff --git a/cpu/arm/aducrf101/clock.c b/cpu/arm/aducrf101/clock.c new file mode 100644 index 000000000..e1feab63f --- /dev/null +++ b/cpu/arm/aducrf101/clock.c @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + * \author Jim Paris + */ + +#include +#include +#include + +static volatile clock_time_t current_clock = 0; +static volatile unsigned long current_seconds = 0; +static unsigned int second_countdown = CLOCK_SECOND; + +#define SAMPLE_STACK_POINTER +#ifdef SAMPLE_STACK_POINTER +volatile uint32_t *__min_sampled_sp = (uint32_t *)0xFFFFFFFF; +#endif + +void +SysTick_Handler(void) +{ +#ifdef SAMPLE_STACK_POINTER + /* Take note of the lowest stack pointer we ever saw. + When compiling against newlib, the total free bytes of + RAM not ever used by heap or stack can be found via GDB: + (gdb) p (char *)__min_sampled_sp - (char *)_sbrk(0) + */ + uint32_t *sp = (uint32_t *)&sp; + if (sp < __min_sampled_sp) + __min_sampled_sp = sp; +#endif + + current_clock++; + if(etimer_pending()) { + etimer_request_poll(); + } + if(--second_countdown == 0) { + current_seconds++; + second_countdown = CLOCK_SECOND; + } +} +/*---------------------------------------------------------------------------*/ +void +clock_init() +{ + SysTick_Config(F_CPU / CLOCK_SECOND); +} +/*---------------------------------------------------------------------------*/ +clock_time_t +clock_time(void) +{ + return current_clock; +} +/*---------------------------------------------------------------------------*/ +unsigned long +clock_seconds(void) +{ + return current_seconds; +} +/*---------------------------------------------------------------------------*/ +void +clock_delay_usec(uint16_t usec) +{ + /* Delay by watching the SysTick value change. */ + int32_t remaining = (int32_t)usec * F_CPU / 1000000; + int32_t old = SysTick->VAL; + while(remaining > 0) { + int32_t new = SysTick->VAL; + if(new > old) { /* wraparound */ + old += SysTick->LOAD; + } + remaining -= (old - new); + old = new; + } +} diff --git a/cpu/arm/aducrf101/dev/radio.c b/cpu/arm/aducrf101/dev/radio.c new file mode 100644 index 000000000..6e2b2ca47 --- /dev/null +++ b/cpu/arm/aducrf101/dev/radio.c @@ -0,0 +1,425 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + * \author Jim Paris + */ + +#include +#include + +#include + +#include "contiki.h" +#include "contiki-net.h" +#include "net/netstack.h" +#include "radio.h" + +#define MAX_PACKET_LEN 240 + +static uint8_t tx_buf[MAX_PACKET_LEN]; + +#ifndef ADUCRF101_RADIO_BASE_CONFIG +#define ADUCRF101_RADIO_BASE_CONFIG DR_38_4kbps_Dev20kHz +#endif + +static RIE_BaseConfigs base_config = ADUCRF101_RADIO_BASE_CONFIG; +static int current_channel = 915000000; +static int current_power = 31; +static int radio_is_on = 0; + +/*---------------------------------------------------------------------------*/ +/* Sniffer configuration. We can re-use the CC2538 sniffer application + if we also accept CC2538_RF_CONF_SNIFFER. */ +#ifndef ADUCRF101_RF_CONF_SNIFFER +#if CC2538_RF_CONF_SNIFFER +#define ADUCRF101_RF_CONF_SNIFFER 1 +#endif +#endif + +#if ADUCRF101_RF_CONF_SNIFFER +#include "dev/uart.h" +static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; /* Snif */ +#endif +/*---------------------------------------------------------------------------*/ +/* "Channel" is really frequency, and can be within the bands: + 431000000 Hz to 464000000 Hz + 862000000 Hz to 928000000 Hz + */ +#define MIN_CHANNEL 431000000 +#define MAX_CHANNEL 928000000 +static int +_set_channel(int freq) +{ + if(freq < 431000000) { + freq = 431000000; + } else if(freq > 464000000 && freq < 663000000) { + freq = 464000000; + } else if(freq >= 663000000 && freq < 862000000) { + freq = 862000000; + } else if(freq > 928000000) { + freq = 928000000; + } + current_channel = freq; + if(RadioSetFrequency(freq) != RIE_Success) { + return RADIO_RESULT_ERROR; + } + return RADIO_RESULT_OK; +} +/*---------------------------------------------------------------------------*/ +/* "Power" covers both PA type and power level: + 0 through 15 means single-ended, power level 0 through 15 + 16 through 31 means differential, power level 0 through 15 */ +#define MIN_POWER 0 +#define MAX_POWER 31 +static int +_set_power(int power) +{ + RIE_Responses ret; + if(power < 0) { + power = 0; + } + if(power > 31) { + power = 31; + } + if(power <= 15) { + ret = RadioTxSetPA(SingleEndedPA, power); + } else { + ret = RadioTxSetPA(DifferentialPA, power - 16); + } + current_power = power; + if(ret != RIE_Success) { + return RADIO_RESULT_ERROR; + } + return RADIO_RESULT_OK; +} +/*---------------------------------------------------------------------------*/ +PROCESS(aducrf101_rf_process, "ADuCRF101 RF driver"); +/*---------------------------------------------------------------------------*/ +/** Turn the radio on. */ +static int +on(void) +{ + if(radio_is_on) { + return 1; + } + + /* Power radio on */ + if(RadioInit(base_config) != RIE_Success) { + return 0; + } + + /* Ensure channel and power are set */ + if(_set_channel(current_channel) != RADIO_RESULT_OK) { + return 0; + } + if(_set_power(current_power) != RADIO_RESULT_OK) { + return 0; + } + + /* Enter receive mode */ + RadioRxPacketVariableLen(); + + radio_is_on = 1; + return 1; +} +/*---------------------------------------------------------------------------*/ +/** Turn the radio off. */ +static int +off(void) +{ + if(!radio_is_on) { + return 1; + } + if(RadioPowerOff() != RIE_Success) { + return 0; + } + radio_is_on = 0; + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +init(void) +{ + off(); + on(); + process_start(&aducrf101_rf_process, NULL); + return 1; +} +/*---------------------------------------------------------------------------*/ +/** Prepare the radio with a packet to be sent. */ +static int +prepare(const void *payload, unsigned short payload_len) +{ + /* Truncate long packets */ + if(payload_len > MAX_PACKET_LEN) { + payload_len = MAX_PACKET_LEN; + } + memcpy(tx_buf, payload, payload_len); + return 0; +} +/*---------------------------------------------------------------------------*/ +/** Send the packet that has previously been prepared. */ +static int +transmit(unsigned short transmit_len) +{ + if(!radio_is_on) + return RADIO_TX_ERR; + + /* Transmit the packet */ + if(transmit_len > MAX_PACKET_LEN) { + transmit_len = MAX_PACKET_LEN; + } + if(RadioTxPacketVariableLen(transmit_len, tx_buf) != RIE_Success) { + return RADIO_TX_ERR; + } + while(!RadioTxPacketComplete()) + continue; + + /* Enter receive mode immediately after transmitting a packet */ + RadioRxPacketVariableLen(); + + return RADIO_TX_OK; +} +/*---------------------------------------------------------------------------*/ +/** Prepare & transmit a packet. */ +static int +send(const void *payload, unsigned short payload_len) +{ + prepare(payload, payload_len); + return transmit(payload_len); +} +/*---------------------------------------------------------------------------*/ +/** Read a received packet into a buffer. */ +static int +read(void *buf, unsigned short buf_len) +{ + uint8_t packet_len; + int8_t rssi; + + if(!radio_is_on) + return 0; + + if(buf_len > MAX_PACKET_LEN) { + buf_len = MAX_PACKET_LEN; + } + + /* Read already-received packet */ + if(RadioRxPacketRead(buf_len, &packet_len, buf, &rssi) != RIE_Success) { + return 0; + } + + if(packet_len > buf_len) { + packet_len = buf_len; + } + + /* Re-enter receive mode immediately after receiving a packet */ + RadioRxPacketVariableLen(); + +#if ADUCRF101_RF_CONF_SNIFFER + uart_put(magic[0]); + uart_put(magic[1]); + uart_put(magic[2]); + uart_put(magic[3]); + uart_put(packet_len + 2); + for(int i = 0; i < packet_len; i++) { + uart_put(((uint8_t *)buf)[i]); + } + /* FCS value is Wireshark's "TI CC24xx format" option: */ + uart_put(rssi); /* RSSI */ + uart_put(0x80); /* CRC is OK, LQI correlation is 0 */ +#endif + + return packet_len; +} +/*---------------------------------------------------------------------------*/ +/** Perform a Clear-Channel Assessment (CCA) to find out if there is + a packet in the air or not. */ +static int +channel_clear(void) +{ + /* Not implemented; assume clear */ + return 1; +} +/*---------------------------------------------------------------------------*/ +/** Check if the radio driver is currently receiving a packet */ +static int +receiving_packet(void) +{ + /* Not implemented; assume no. */ + return 0; +} +/*---------------------------------------------------------------------------*/ +/** Check if the radio driver has just received a packet */ +static int +pending_packet(void) +{ + if(RadioRxPacketAvailable()) { + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +/** Get a radio parameter value. */ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + if(!value) { + return RADIO_RESULT_INVALID_VALUE; + } + + switch(param) { + case RADIO_PARAM_RSSI: + { + int8_t dbm; + if(!radio_is_on || RadioRadioGetRSSI(&dbm) != RIE_Success) { + return RADIO_RESULT_ERROR; + } + *value = dbm; + return RADIO_RESULT_OK; + } + + case RADIO_PARAM_CHANNEL: + *value = current_channel; + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MIN: + *value = MIN_CHANNEL; + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MAX: + *value = MAX_CHANNEL; + return RADIO_RESULT_OK; + + case RADIO_PARAM_TXPOWER: + *value = current_power; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MIN: + *value = MIN_POWER; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MAX: + *value = MAX_POWER; + return RADIO_RESULT_OK; + + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} +/*---------------------------------------------------------------------------*/ +/** Set a radio parameter value. */ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + switch(param) { + case RADIO_PARAM_CHANNEL: + return _set_channel(value); + + case RADIO_PARAM_TXPOWER: + return _set_power(value); + + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} +/*---------------------------------------------------------------------------*/ +/** + * Get a radio parameter object. The argument 'dest' must point to a + * memory area of at least 'size' bytes, and this memory area will + * contain the parameter object if the function succeeds. + */ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +/** + * Set a radio parameter object. The memory area referred to by the + * argument 'src' will not be accessed after the function returns. + */ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Implementation of the ADuCRF101 RF driver process + * + * This process is started by init(). It waits for events triggered + * by packet reception. + */ +PROCESS_THREAD(aducrf101_rf_process, ev, data) +{ + int len; + PROCESS_BEGIN(); + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + + packetbuf_clear(); + len = read(packetbuf_dataptr(), PACKETBUF_SIZE); + + if(len > 0) { + packetbuf_set_datalen(len); + + NETSTACK_RDC.input(); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Trigger function called by ADI radio engine upon packet RX. + */ +void +aducrf101_rx_packet_hook(void) +{ + process_poll(&aducrf101_rf_process); +} +/*---------------------------------------------------------------------------*/ +const struct radio_driver aducrf101_radio_driver = { + .init = init, + .prepare = prepare, + .transmit = transmit, + .send = send, + .read = read, + .channel_clear = channel_clear, + .receiving_packet = receiving_packet, + .pending_packet = pending_packet, + .on = on, + .off = off, + .get_value = get_value, + .set_value = set_value, + .get_object = get_object, + .set_object = set_object, +}; diff --git a/cpu/arm/aducrf101/dev/uart.c b/cpu/arm/aducrf101/dev/uart.c new file mode 100644 index 000000000..569e54fdd --- /dev/null +++ b/cpu/arm/aducrf101/dev/uart.c @@ -0,0 +1,124 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + * \author Jim Paris + */ + +#include + +static int (*uart_input_handler)(unsigned char c); +static int stdout_enabled; + +void +uart_init(int baud) +{ + /* P1.0 is UARTRXD, P1.1 is UARTTXD */ + pADI_GP1->GPCON &= ~(GP1CON_CON0_MSK | GP1CON_CON1_MSK); + pADI_GP1->GPCON |= GP1CON_CON0_UART0RXD | GP1CON_CON1_UART0TXD; + + /* Set P1.1 as output */ + GP1OEN_OEN1_BBA = 1; + + /* Set baudrate */ + int div = (F_CPU / 32) / baud; + pADI_UART->COMDIV = div; + pADI_UART->COMFBR = 0x8800 | ((((64 * F_CPU) / div) / baud) - 2048); + pADI_UART->COMIEN = 0; + pADI_UART->COMLCR = 3; + + /* Set up RX IRQ */ + pADI_UART->COMIEN = COMIEN_ERBFI_EN; + NVIC_EnableIRQ(UART_IRQn); + __enable_irq(); + + uart_input_handler = NULL; + stdout_enabled = 1; +} +/*---------------------------------------------------------------------------*/ +void +uart_put(unsigned char x) +{ + while(!(pADI_UART->COMLSR & COMLSR_THRE)) + continue; + pADI_UART->COMTX = x; +} +/*---------------------------------------------------------------------------*/ +void +UART_Int_Handler(void) +{ + if(pADI_UART->COMIIR & COMIIR_STA_RXBUFFULL) { + unsigned char x = pADI_UART->COMRX; + if(uart_input_handler) { + uart_input_handler(x); + } + } +} +/*---------------------------------------------------------------------------*/ +void +uart_set_input(int (*input)(unsigned char c)) +{ + uart_input_handler = input; +} +void +uart_enable_stdout(int enabled) +{ + stdout_enabled = enabled; +} +/*---------------------------------------------------------------------------*/ +/* Connect newlib's _write function to the UART. */ +int +_write(int fd, const void *buf, size_t len) +{ + if(stdout_enabled == 0) { + return -1; + } + + if(fd == 1 || fd == 2) { + int n = len; + const unsigned char *p = buf; + while(n--) + uart_put(*p++); + return len; + } + return -1; +} +/*---------------------------------------------------------------------------*/ +#ifdef __ICCARM__ +/* Connect IAR's __write function to the UART. */ +size_t +__write(int fd, const unsigned char *buf, size_t count) +{ + return _write(fd, buf, count); +} +#endif diff --git a/cpu/arm/aducrf101/dev/uart.h b/cpu/arm/aducrf101/dev/uart.h new file mode 100644 index 000000000..deaec627c --- /dev/null +++ b/cpu/arm/aducrf101/dev/uart.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + * \author Jim Paris + */ + +#ifndef UART_H +#define UART_H + +void uart_init(int baud); +void uart_put(unsigned char x); +void uart_set_input(int (*input)(unsigned char c)); + +void uart_enable_stdout(int enabled); + +#endif diff --git a/cpu/arm/aducrf101/dev/uart0.h b/cpu/arm/aducrf101/dev/uart0.h new file mode 100644 index 000000000..2f8670044 --- /dev/null +++ b/cpu/arm/aducrf101/dev/uart0.h @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + * \author Jim Paris + * + * \file + * This file exists only because some examples rely on it. + */ + +#ifndef UART1_H +#define UART1_H + +#include "dev/uart.h" +#undef BAUD2UBR +#define BAUD2UBR(x) (x) +#define uart1_set_input(f) uart_set_input(f) + +#endif /* UART1_H */ diff --git a/cpu/arm/aducrf101/dev/uart1.h b/cpu/arm/aducrf101/dev/uart1.h new file mode 100644 index 000000000..6b7ca27df --- /dev/null +++ b/cpu/arm/aducrf101/dev/uart1.h @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + * \author Jim Paris + * + * \file + * This file exists only because some examples rely on it. + */ + +#ifndef UART0_H +#define UART0_H + +#include "dev/uart.h" +#undef BAUD2UBR +#define BAUD2UBR(x) (x) +#define uart0_set_input(f) uart_set_input(f) + +#endif /* UART0_H */ diff --git a/cpu/arm/aducrf101/dev/watchdog.c b/cpu/arm/aducrf101/dev/watchdog.c new file mode 100644 index 000000000..3c5cb4e49 --- /dev/null +++ b/cpu/arm/aducrf101/dev/watchdog.c @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + * \author Jim Paris + */ + +#include +#include + +void +watchdog_init(void) +{ + /* Start disabled. */ + T3CON_ENABLE_BBA = 0; +} +/*---------------------------------------------------------------------------*/ +void +watchdog_start(void) +{ + /* 32 second timeout. This also locks the watchdog configuration. */ + pADI_WDT->T3CON = 0x00E9; + pADI_WDT->T3LD = 0x1000; + pADI_WDT->T3VAL = 0x1000; +} +/*---------------------------------------------------------------------------*/ +void +watchdog_stop(void) +{ + /* Not possible to stop, once enabled */ +} +/*---------------------------------------------------------------------------*/ +void +watchdog_periodic(void) +{ + pADI_WDT->T3CLRI = 0xcccc; +} diff --git a/cpu/arm/aducrf101/mtarch.h b/cpu/arm/aducrf101/mtarch.h new file mode 100644 index 000000000..e968158c0 --- /dev/null +++ b/cpu/arm/aducrf101/mtarch.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + * \author Jim Paris + */ + +#ifndef MTARCH_H_ +#define MTARCH_H_ + +/* Multithreading is currently unimplemented for ARM Cortex-M3 */ + +struct mtarch_thread { + short mt_thread; +}; + +#endif /* MTARCH_H_ */ diff --git a/cpu/arm/aducrf101/rtimer-arch.c b/cpu/arm/aducrf101/rtimer-arch.c new file mode 100644 index 000000000..4f6b3caa3 --- /dev/null +++ b/cpu/arm/aducrf101/rtimer-arch.c @@ -0,0 +1,138 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + * \author Jim Paris + */ + +#include +#include "rtimer-arch.h" +#include "aducrf101-contiki.h" + +/* rtimer on the ADuCRF101 is implemented with the "wakeup" timer. + (timer 2). It should be clocked from an external crystal, + but if that doesn't seem to be present, this code will select the + imprecise internal 32.768 KHz oscillator instead. */ + +static void +_timer2_enable(int enable) +{ + T2CON_ENABLE_BBA = enable; + clock_time_t now = clock_time(); + while(T2STA_CON_BBA) { + /* Synchronizing settings may fail if the chosen clock isn't running; + wait no more than 1ms for it */ + if((clock_time() - now) > (CLOCK_SECOND / 1000)) { + break; + } + } +} +static uint32_t +_timer2_val(void) +{ + /* This is atomic because the FREEZE bit is set in T2CON. */ + uint32_t now; + now = pADI_WUT->T2VAL0; + now |= pADI_WUT->T2VAL1 << 16; + return now; +} +static uint32_t +_timer2_measure_freq(void) +{ + const int test_usec = 10000; + uint32_t now = _timer2_val(); + clock_delay_usec(test_usec); + return (_timer2_val() - now) * (1000000 / test_usec); +} +void +rtimer_arch_init(void) +{ + uint32_t freq; + const char *timer = "LFXTAL"; + + _timer2_enable(0); + pADI_WUT->T2CON = T2CON_PRE_DIV1 | T2CON_MOD_FREERUN | T2CON_FREEZE_EN | + T2CON_WUEN_EN; + + /* Try 32.768 KHz crystal */ + pADI_WUT->T2CON |= T2CON_CLK_LFXTAL; + _timer2_enable(1); + freq = _timer2_measure_freq(); + + if(freq < 20000 || freq > 40000) { + /* No good; use 32.768 KHz internal oscillator */ + _timer2_enable(0); + pADI_WUT->T2CON &= ~T2CON_CLK_MSK; + pADI_WUT->T2CON |= T2CON_CLK_LFOSC; + _timer2_enable(1); + freq = _timer2_measure_freq(); + timer = "LFOSC"; + } + + printf("Using %s for rtimer (%ld Hz)\n", timer, freq); + + /* Enable interrupt in NVIC, but disable in WUT for now. */ + pADI_WUT->T2IEN = 0; + NVIC_EnableIRQ(WUT_IRQn); +} +rtimer_clock_t +rtimer_arch_now(void) +{ + /* This is atomic because the FREEZE bit is set in T2CON. */ + return _timer2_val(); +} +void +rtimer_arch_schedule(rtimer_clock_t t) +{ + uint32_t now = _timer2_val(); + + /* Minimum of 5 wakeup timer ticks */ + if((int32_t)(t - now) < 5) { + t = now + 5; + } + + /* Set T2WUFB to match at target time */ + T2IEN_WUFB_BBA = 0; + pADI_WUT->T2WUFB0 = (t & 0xffff); + pADI_WUT->T2WUFB1 = (t >> 16); + T2IEN_WUFB_BBA = 1; +} +void +WakeUp_Int_Handler(void) +{ + /* clear interrupt */ + T2CLRI_WUFB_BBA = 1; + /* disable T2WUFB match */ + T2IEN_WUFB_BBA = 0; + rtimer_run_next(); +} diff --git a/cpu/arm/aducrf101/rtimer-arch.h b/cpu/arm/aducrf101/rtimer-arch.h new file mode 100644 index 000000000..ec28dcf7d --- /dev/null +++ b/cpu/arm/aducrf101/rtimer-arch.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + * \author Jim Paris + */ + +#ifndef __RTIMER_ARCH_H__ +#define __RTIMER_ARCH_H__ + +#include + +#define RTIMER_ARCH_SECOND (32768) + +#include "sys/rtimer.h" + +#endif /* __RTIMER_ARCH_H__ */ diff --git a/cpu/arm/aducrf101/slip-arch.c b/cpu/arm/aducrf101/slip-arch.c new file mode 100644 index 000000000..523e30313 --- /dev/null +++ b/cpu/arm/aducrf101/slip-arch.c @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + * \author Jim Paris + */ + +#include + +#include "contiki.h" +#include "dev/slip.h" +#include "uart.h" + +/*---------------------------------------------------------------------------*/ +void +slip_arch_writeb(unsigned char c) +{ + uart_put(c); +} +/*---------------------------------------------------------------------------*/ +/** + * Initalize the RS232 port and the SLIP driver. + * + */ +void +slip_arch_init(unsigned long ubr) +{ + uart_set_input(slip_input_byte); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/arm/arm.txt b/cpu/arm/arm.txt new file mode 100644 index 000000000..5ab586778 --- /dev/null +++ b/cpu/arm/arm.txt @@ -0,0 +1,19 @@ +/** + * @defgroup cmsis CMSIS (Cortex Microcontroller Software Interface Standard) + * @ingroup arm + */ + +/** + * @defgroup aducrf101 ADUCRF101 + * @ingroup arm + */ + +/** + * @defgroup at91sam7s AT91SAM7S + * @ingroup arm + */ + +/** + * @defgroup stm32f103 STM32F103 + * @ingroup arm + */ diff --git a/cpu/arm/at91sam7s/Makefile.at91sam7s b/cpu/arm/at91sam7s/Makefile.at91sam7s index 95f30a36c..8ce761be7 100644 --- a/cpu/arm/at91sam7s/Makefile.at91sam7s +++ b/cpu/arm/at91sam7s/Makefile.at91sam7s @@ -76,7 +76,7 @@ CFLAGSNO = -I. -I$(CONTIKI)/core -I$(CONTIKI_CPU) -I$(CONTIKI_CPU)/loader \ -I$(CONTIKI_CPU)/dbg-io \ -I$(CONTIKI)/platform/$(TARGET) \ ${addprefix -I,$(APPDIRS)} \ - -DWITH_UIP -DWITH_ASCII -DMCK=$(MCK) \ + -DWITH_ASCII -DMCK=$(MCK) \ -Wall $(ARCH_FLAGS) -g -D SUBTARGET=$(SUBTARGET) CFLAGS += $(CFLAGSNO) -O -DRUN_AS_SYSTEM -DROM_RUN diff --git a/cpu/arm/at91sam7s/loader/codeprop-otf.c b/cpu/arm/at91sam7s/loader/codeprop-otf.c index 2ffbe2556..8991106fd 100644 --- a/cpu/arm/at91sam7s/loader/codeprop-otf.c +++ b/cpu/arm/at91sam7s/loader/codeprop-otf.c @@ -30,9 +30,6 @@ * */ -/** \addtogroup esb - * @{ */ - /** * * \file @@ -519,4 +516,3 @@ uipcall(void *state) } } /*---------------------------------------------------------------------*/ -/** @} */ diff --git a/cpu/arm/at91sam7s/loader/elfloader-arch-otf.h b/cpu/arm/at91sam7s/loader/elfloader-arch-otf.h index 9fe8a77ae..4dd046887 100644 --- a/cpu/arm/at91sam7s/loader/elfloader-arch-otf.h +++ b/cpu/arm/at91sam7s/loader/elfloader-arch-otf.h @@ -71,7 +71,8 @@ /** * \brief Perform a relocation. - * \param output The output object for the segment. + * \param input_fd The file descriptor for the ELF file. + * \param output The output object for the segment. * \param sectionoffset The file offset at which the relocation can be found. * \param sectionaddr The section start address (absolute runtime). * \param rela A pointer to an ELF32 rela structure (struct elf32_rela). @@ -89,10 +90,10 @@ * processor. */ int elfloader_arch_relocate(int input_fd, - struct elfloader_output *output, - unsigned int sectionoffset, - char *sectionaddr, - struct elf32_rela *rela, char *addr); + struct elfloader_output *output, + unsigned int sectionoffset, + char *sectionaddr, + struct elf32_rela *rela, char *addr); #endif /* ELFLOADER_ARCH_H_ */ diff --git a/cpu/arm/at91sam7s/loader/elfloader-otf.h b/cpu/arm/at91sam7s/loader/elfloader-otf.h index d3c06c091..5f57feccd 100644 --- a/cpu/arm/at91sam7s/loader/elfloader-otf.h +++ b/cpu/arm/at91sam7s/loader/elfloader-otf.h @@ -37,7 +37,7 @@ * Header file for the Contiki ELF loader. * \author * Adam Dunkels - * Simon Berg + * Simon Berg * */ @@ -132,7 +132,7 @@ * Return value from elfloader_load() indicating that the offset for * a relative addressing mode was too big. */ -#define ELFLOADER_OUTOF_RANGE 9 +#define ELFLOADER_OUTOF_RANGE 9 /** * Return value from elfloader_load() indicating that the relocations @@ -144,13 +144,13 @@ * Return value from elfloader_load() indicating that reading from the * ELF file failed in some way. */ -#define ELFLOADER_INPUT_ERROR 11 +#define ELFLOADER_INPUT_ERROR 11 /** * Return value from elfloader_load() indicating that writing to a segment * failed. */ -#define ELFLOADER_OUTPUT_ERROR 12 +#define ELFLOADER_OUTPUT_ERROR 12 #define ELFLOADER_SEG_TEXT 1 @@ -164,62 +164,58 @@ * This object defines methods (callbacks) for writing the segments to memory. * It can be extended by the user to include any necessary state. */ - struct elfloader_output { const struct elfloader_output_ops *ops; }; + /** - * \brief Allocate a new segment - * \param input The output object - * \param type Type of segment - * \param size Size of segment in bytes - * \return A pointer to the start of the segment. + * \brief Allocate a new segment + * \param output The output object + * \param type Type of segment + * \param size Size of segment in bytes + * \return A pointer to the start of the segment. * * The returned address doesn't need to correspond to any real memory, * since it's only used for calculating the relocations. */ - void *elfloader_allocate_segment(struct elfloader_output *output, - unsigned int type, int size); + unsigned int type, int size); /** - * \brief Start writing to a new segment - * \param input The output object - * \param type Type of segment - * \param addr Address of segment from elfloader_allocate_segment - * \param size Size of segment in bytes - * \return Returns ELFLOADER_OK if successful, otherwise an error code + * \brief Start writing to a new segment + * \param output The output object + * \param type Type of segment + * \param addr Address of segment from elfloader_allocate_segment + * \param size Size of segment in bytes + * \return Returns ELFLOADER_OK if successful, otherwise an error code * */ - int elfloader_start_segment(struct elfloader_output *output, - unsigned int type, void *addr, int size); -/** - * \brief Mark end of segment - * \param input The output object - * \return Zero if successful - */ + unsigned int type, void *addr, int size); +/** + * \brief Mark end of segment + * \param output The output object + * \return Zero if successful + */ int elfloader_end_segment(struct elfloader_output *output); /** - * \brief Write data to a segment - * \param input The output object - * \param buf Data to be written - * \param len Length of data - * \return The number of bytes actually written, or negative if failed. + * \brief Write data to a segment + * \param output The output object + * \param buf Data to be written + * \param len Length of data + * \return The number of bytes actually written, or negative if failed. */ - int elfloader_write_segment(struct elfloader_output *output, const char *buf, - unsigned int len); + unsigned int len); /** - * \brief Get the current offset in the file where the next data will - * be written. - * \param input The output object - * \return The current offset. + * \brief Get the current offset in the file where the next data will + * be written. + * \param output The output object + * \return The current offset. */ - unsigned int elfloader_segment_offset(struct elfloader_output *output); #define elfloader_output_alloc_segment(output, type, size) \ @@ -240,12 +236,12 @@ unsigned int elfloader_segment_offset(struct elfloader_output *output); struct elfloader_output_ops { void * (*allocate_segment)(struct elfloader_output *output, - unsigned int type, int size); + unsigned int type, int size); int (*start_segment)(struct elfloader_output *output, - unsigned int type, void *addr, int size); + unsigned int type, void *addr, int size); int (*end_segment)(struct elfloader_output *output); int (*write_segment)(struct elfloader_output *output, const char *buf, - unsigned int len); + unsigned int len); unsigned int (*segment_offset)(struct elfloader_output *output); }; @@ -259,8 +255,8 @@ void elfloader_init(void); /** * \brief Load and relocate an ELF file. - * \param input Input object defining how to read from the ELF file - * \param output Output object defining how to create and write to seegments. + * \param input_fd Input object defining how to read from the ELF file + * \param output Output object defining how to create and write to seegments. * \return ELFLOADER_OK if loading and relocation worked. * Otherwise an error value. * @@ -269,8 +265,7 @@ void elfloader_init(void); * elfloader_loaded_process variable. * */ -int elfloader_load(int input_fd, - struct elfloader_output *output); +int elfloader_load(int input_fd, struct elfloader_output *output); /** * A pointer to the processes loaded with elfloader_load(). diff --git a/cpu/arm/common/CMSIS/core.txt b/cpu/arm/common/CMSIS/core.txt new file mode 100644 index 000000000..b9270e199 --- /dev/null +++ b/cpu/arm/common/CMSIS/core.txt @@ -0,0 +1,50 @@ +/** + * @addtogroup CMSIS_Core_FunctionInterface + * @ingroup cmsis + */ + +/** + * @addtogroup CMSIS_core_register + * @ingroup cmsis + */ + +/** + * @addtogroup CMSIS_glob_defs + * @ingroup cmsis + */ + +/** + * @addtogroup CMSIS_MISRA_Exceptions + * @ingroup cmsis + */ + +/** + * @addtogroup CMSIS_core_definitions + * @ingroup cmsis + */ + +/** + * @addtogroup CMSIS_SIMD_intrinsics + * @ingroup cmsis + */ + +/** + * @addtogroup CMSIS_Core_InstructionInterface + * @ingroup cmsis + */ + +/** + * @defgroup Cortex_M0 Cortex-M0 + * @ingroup cmsis + */ + +/** + * @defgroup Cortex_M3 Cortex-M3 + * @ingroup cmsis + */ + +/** + * @defgroup Cortex_M4 Cortex-M4 + * @ingroup cmsis + */ + diff --git a/cpu/arm/common/CMSIS/core_cm0.h b/cpu/arm/common/CMSIS/core_cm0.h new file mode 100644 index 000000000..0388d076d --- /dev/null +++ b/cpu/arm/common/CMSIS/core_cm0.h @@ -0,0 +1,702 @@ +/**************************************************************************//** + * @file core_cm0.h + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File + * @version V3.30 + * @date 06. May 2014 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + 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 ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifndef __CORE_CM0_H_GENERIC +#define __CORE_CM0_H_GENERIC + +#ifdef __cplusplus + extern "C" { +#endif + +/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
    + Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
    + Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
    + Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex_M0 + @{ + */ + +/* CMSIS CM0 definitions */ +#define __CM0_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB (0x30) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16) | \ + __CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x00) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) /* Cosmic */ + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ + #define __STATIC_INLINE static inline + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all +*/ +#define __FPU_USED 0 + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI__VFP_SUPPORT____ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) /* Cosmic */ + #if ( __CSMC__ & 0x400) // FPU present for parser + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ + +#endif /* __CORE_CM0_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0_H_DEPENDANT +#define __CORE_CM0_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0_REV + #define __CM0_REV 0x0000 + #warning "__CM0_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/*@} end of group Cortex_M0 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ +/** \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31]; + __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31]; + __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31]; + __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31]; + uint32_t RESERVED4[64]; + __IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_CALIB_TENMS_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) + are only accessible over DAP and not via processor. Therefore + they are not covered by the Cortex-M0 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M0 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 ) +#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) ) +#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) ) + + +/** \brief Enable External Interrupt + + The function enables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Disable External Interrupt + + The function disables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Get Pending Interrupt + + The function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + + +/** \brief Set Pending Interrupt + + The function sets the pending bit of an external interrupt. + + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Clear Pending Interrupt + + The function clears the pending bit of an external interrupt. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Set Interrupt Priority + + The function sets the priority of an interrupt. + + \note The priority cannot be set for every core interrupt. + + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } + else { + NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } +} + + +/** \brief Get Interrupt Priority + + The function reads the priority of an interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented + priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */ + else { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief System Reset + + The function initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + The function initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + + \param [in] ticks Number of ticks between two interrupts. + + \return 0 Function succeeded. + \return 1 Function failed. + + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#endif /* __CORE_CM0_H_DEPENDANT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CMSIS_GENERIC */ diff --git a/cpu/arm/common/CMSIS/core_cm0plus.h b/cpu/arm/common/CMSIS/core_cm0plus.h new file mode 100644 index 000000000..b2770cef5 --- /dev/null +++ b/cpu/arm/common/CMSIS/core_cm0plus.h @@ -0,0 +1,813 @@ +/**************************************************************************//** + * @file core_cm0plus.h + * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File + * @version V3.30 + * @date 06. May 2014 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + 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 ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifndef __CORE_CM0PLUS_H_GENERIC +#define __CORE_CM0PLUS_H_GENERIC + +#ifdef __cplusplus + extern "C" { +#endif + +/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
    + Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
    + Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
    + Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex-M0+ + @{ + */ + +/* CMSIS CM0P definitions */ +#define __CM0PLUS_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB (0x30) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16) | \ + __CM0PLUS_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x00) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) /* Cosmic */ + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ + #define __STATIC_INLINE static inline + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all +*/ +#define __FPU_USED 0 + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI__VFP_SUPPORT____ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) /* Cosmic */ + #if ( __CSMC__ & 0x400) // FPU present for parser + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ + +#endif /* __CORE_CM0PLUS_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0PLUS_H_DEPENDANT +#define __CORE_CM0PLUS_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0PLUS_REV + #define __CM0PLUS_REV 0x0000 + #warning "__CM0PLUS_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0 + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/*@} end of group Cortex-M0+ */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31]; + __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31]; + __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31]; + __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31]; + uint32_t RESERVED4[64]; + __IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if (__VTOR_PRESENT == 1) + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if (__VTOR_PRESENT == 1) +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 8 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_CALIB_TENMS_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 8 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) + are only accessible over DAP and not via processor. Therefore + they are not covered by the Cortex-M0 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M0+ Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 ) +#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) ) +#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) ) + + +/** \brief Enable External Interrupt + + The function enables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Disable External Interrupt + + The function disables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Get Pending Interrupt + + The function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + + +/** \brief Set Pending Interrupt + + The function sets the pending bit of an external interrupt. + + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Clear Pending Interrupt + + The function clears the pending bit of an external interrupt. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Set Interrupt Priority + + The function sets the priority of an interrupt. + + \note The priority cannot be set for every core interrupt. + + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } + else { + NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } +} + + +/** \brief Get Interrupt Priority + + The function reads the priority of an interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented + priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */ + else { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief System Reset + + The function initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + The function initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + + \param [in] ticks Number of ticks between two interrupts. + + \return 0 Function succeeded. + \return 1 Function failed. + + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#endif /* __CORE_CM0PLUS_H_DEPENDANT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CMSIS_GENERIC */ diff --git a/cpu/arm/common/CMSIS/core_cm3.h b/cpu/arm/common/CMSIS/core_cm3.h new file mode 100644 index 000000000..436ac5b11 --- /dev/null +++ b/cpu/arm/common/CMSIS/core_cm3.h @@ -0,0 +1,1638 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V3.30 + * @date 06. May 2014 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + 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 ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifndef __CORE_CM3_H_GENERIC +#define __CORE_CM3_H_GENERIC + +#ifdef __cplusplus + extern "C" { +#endif + +/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
    + Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
    + Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
    + Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex_M3 + @{ + */ + +/* CMSIS CM3 definitions */ +#define __CM3_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (0x30) /*!< [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | \ + __CM3_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x03) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) /* Cosmic */ + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ + #define __STATIC_INLINE static inline + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all +*/ +#define __FPU_USED 0 + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI__VFP_SUPPORT____ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) /* Cosmic */ + #if ( __CSMC__ & 0x400) // FPU present for parser + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ + +#endif /* __CORE_CM3_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM3_H_DEPENDANT +#define __CORE_CM3_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM3_REV + #define __CM3_REV 0x0200 + #warning "__CM3_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/*@} end of group Cortex_M3 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#if (__CM3_REV < 0x0201) /* core r2p1 */ +#define SCB_VTOR_TBLBASE_Pos 29 /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#else +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ +#if ((defined __CM3_REV) && (__CM3_REV >= 0x200)) + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +#else + uint32_t RESERVED1[1]; +#endif +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_CALIB_TENMS_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29]; + __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43]; + __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6]; + __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1]; + __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1]; + __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1]; + __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL << DWT_CPICNT_CPICNT_Pos) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL << DWT_EXCCNT_EXCCNT_Pos) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL << DWT_LSUCNT_LSUCNT_Pos) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL << DWT_MASK_MASK_Pos) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL << DWT_FUNCTION_FUNCTION_Pos) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2]; + __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55]; + __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131]; + __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759]; + __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1]; + __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39]; + __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8]; + __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL << TPI_ACPR_PRESCALER_Pos) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL << TPI_SPPR_TXMODE_Pos) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL << TPI_FFSR_FlInProg_Pos) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL << TPI_TRIGGER_TRIGGER_Pos) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL << TPI_FIFO0_ETM0_Pos) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL << TPI_FIFO1_ITM0_Pos) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL << TPI_DEVID_NrTraceInput_Pos) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M3 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** \brief Set Priority Grouping + + The function sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + The function reads the priority grouping field from the NVIC Interrupt Controller. + + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ +} + + +/** \brief Enable External Interrupt + + The function enables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */ +} + + +/** \brief Disable External Interrupt + + The function disables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \brief Get Pending Interrupt + + The function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ +} + + +/** \brief Set Pending Interrupt + + The function sets the pending bit of an external interrupt. + + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \brief Clear Pending Interrupt + + The function clears the pending bit of an external interrupt. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + The function reads the active register in NVIC and returns the active bit. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + + +/** \brief Set Interrupt Priority + + The function sets the priority of an interrupt. + + \note The priority cannot be set for every core interrupt. + + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \brief Get Interrupt Priority + + The function reads the priority of an interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented + priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + The function encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** \brief Decode Priority + + The function decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + +/** \brief System Reset + + The function initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + The function initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + + \param [in] ticks Number of ticks between two interrupts. + + \return 0 Function succeeded. + \return 1 Function failed. + + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** \brief ITM Send Character + + The function transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + + \param [in] ch Character to transmit. + + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + + +/** \brief ITM Receive Character + + The function inputs a character via the external variable \ref ITM_RxBuffer. + + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) { + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** \brief ITM Check Character + + The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + +#endif /* __CORE_CM3_H_DEPENDANT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CMSIS_GENERIC */ diff --git a/cpu/arm/common/CMSIS/core_cm4.h b/cpu/arm/common/CMSIS/core_cm4.h new file mode 100644 index 000000000..610c4afb4 --- /dev/null +++ b/cpu/arm/common/CMSIS/core_cm4.h @@ -0,0 +1,1790 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V3.30 + * @date 06. May 2014 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + 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 ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +#ifdef __cplusplus + extern "C" { +#endif + +/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
    + Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
    + Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
    + Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex_M4 + @{ + */ + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (0x30) /*!< [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x04) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) /* Cosmic */ + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ + #define __STATIC_INLINE static inline + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __CSMC__ ) /* Cosmic */ + #if ( __CSMC__ & 0x400) // FPU present for parser + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ +#include /* Compiler specific SIMD Intrinsics */ + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000 + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0 + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9 /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8 /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_CALIB_TENMS_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29]; + __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43]; + __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6]; + __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1]; + __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1]; + __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1]; + __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL << DWT_CPICNT_CPICNT_Pos) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL << DWT_EXCCNT_EXCCNT_Pos) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL << DWT_LSUCNT_LSUCNT_Pos) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL << DWT_MASK_MASK_Pos) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL << DWT_FUNCTION_FUNCTION_Pos) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2]; + __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55]; + __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131]; + __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759]; + __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1]; + __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39]; + __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8]; + __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL << TPI_ACPR_PRESCALER_Pos) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL << TPI_SPPR_TXMODE_Pos) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL << TPI_FFSR_FlInProg_Pos) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL << TPI_TRIGGER_TRIGGER_Pos) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL << TPI_FIFO0_ETM0_Pos) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL << TPI_FIFO1_ITM0_Pos) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL << TPI_DEVID_NrTraceInput_Pos) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if (__FPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register */ +#define FPU_FPCCR_ASPEN_Pos 31 /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30 /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8 /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6 /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5 /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4 /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3 /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1 /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0 /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL << FPU_FPCCR_LSPACT_Pos) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register */ +#define FPU_FPCAR_ADDRESS_Pos 3 /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register */ +#define FPU_FPDSCR_AHP_Pos 26 /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25 /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24 /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22 /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28 /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24 /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20 /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16 /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12 /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8 /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4 /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0 /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL << FPU_MVFR0_A_SIMD_registers_Pos) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28 /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24 /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4 /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0 /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL << FPU_MVFR1_FtZ_mode_Pos) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M4 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#if (__FPU_PRESENT == 1) + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** \brief Set Priority Grouping + + The function sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + The function reads the priority grouping field from the NVIC Interrupt Controller. + + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ +} + + +/** \brief Enable External Interrupt + + The function enables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ +/* NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); enable interrupt */ + NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */ +} + + +/** \brief Disable External Interrupt + + The function disables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \brief Get Pending Interrupt + + The function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ +} + + +/** \brief Set Pending Interrupt + + The function sets the pending bit of an external interrupt. + + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \brief Clear Pending Interrupt + + The function clears the pending bit of an external interrupt. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + The function reads the active register in NVIC and returns the active bit. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + + +/** \brief Set Interrupt Priority + + The function sets the priority of an interrupt. + + \note The priority cannot be set for every core interrupt. + + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \brief Get Interrupt Priority + + The function reads the priority of an interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented + priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + The function encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** \brief Decode Priority + + The function decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + +/** \brief System Reset + + The function initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + The function initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + + \param [in] ticks Number of ticks between two interrupts. + + \return 0 Function succeeded. + \return 1 Function failed. + + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** \brief ITM Send Character + + The function transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + + \param [in] ch Character to transmit. + + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + + +/** \brief ITM Receive Character + + The function inputs a character via the external variable \ref ITM_RxBuffer. + + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) { + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** \brief ITM Check Character + + The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CMSIS_GENERIC */ diff --git a/cpu/arm/common/CMSIS/core_cm4_simd.h b/cpu/arm/common/CMSIS/core_cm4_simd.h new file mode 100644 index 000000000..f9bceff1e --- /dev/null +++ b/cpu/arm/common/CMSIS/core_cm4_simd.h @@ -0,0 +1,697 @@ +/**************************************************************************//** + * @file core_cm4_simd.h + * @brief CMSIS Cortex-M4 SIMD Header File + * @version V3.30 + * @date 17. February 2014 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + 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 ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifndef __CORE_CM4_SIMD_H +#define __CORE_CM4_SIMD_H + +#ifdef __cplusplus + extern "C" { +#endif + + +/******************************************************************************* + * Hardware Abstraction Layer + ******************************************************************************/ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32) ) >> 32)) + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ // Little endian + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else // Big endian + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ // Little endian + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else // Big endian + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ // Little endian + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else // Big endian + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ // Little endian + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else // Big endian + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ +#include + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ +/* not yet supported */ + + +#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ +/* Cosmic specific functions */ +#include + +#endif + +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_SIMD_H */ diff --git a/cpu/arm/common/CMSIS/core_cmFunc.h b/cpu/arm/common/CMSIS/core_cmFunc.h new file mode 100644 index 000000000..2c2af69c1 --- /dev/null +++ b/cpu/arm/common/CMSIS/core_cmFunc.h @@ -0,0 +1,637 @@ +/**************************************************************************//** + * @file core_cmFunc.h + * @brief CMSIS Cortex-M Core Function Access Header File + * @version V3.30 + * @date 17. February 2014 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + 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 ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#ifndef __CORE_CMFUNC_H +#define __CORE_CMFUNC_H + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + +/* intrinsic void __enable_irq(); */ +/* intrinsic void __disable_irq(); */ + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** \brief Get IPSR Register + + This function returns the content of the IPSR Register. + + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xff); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#endif +} + +#endif /* (__CORTEX_M == 0x04) */ + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** \brief Enable IRQ Interrupts + + This function enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** \brief Disable IRQ Interrupts + + This function disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +/** \brief Get IPSR Register + + This function returns the content of the IPSR Register. + + \return IPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp"); +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp"); +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); + return(result); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory"); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + uint32_t result; + + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + __ASM volatile (""); + return(result); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc"); + __ASM volatile (""); +#endif +} + +#endif /* (__CORTEX_M == 0x04) */ + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ +#include + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + +#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ +/* Cosmic specific functions */ +#include + +#endif + +/*@} end of CMSIS_Core_RegAccFunctions */ + +#endif /* __CORE_CMFUNC_H */ diff --git a/cpu/arm/common/CMSIS/core_cmInstr.h b/cpu/arm/common/CMSIS/core_cmInstr.h new file mode 100644 index 000000000..d2ec262f1 --- /dev/null +++ b/cpu/arm/common/CMSIS/core_cmInstr.h @@ -0,0 +1,687 @@ +/**************************************************************************//** + * @file core_cmInstr.h + * @brief CMSIS Cortex-M Core Instruction Access Header File + * @version V3.30 + * @date 17. February 2014 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + 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 ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#ifndef __CORE_CMINSTR_H +#define __CORE_CMINSTR_H + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +#define __ISB() __isb(0xF) + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __dsb(0xF) + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __dmb(0xF) + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** \brief Rotate Right in unsigned value (32 bit) + + This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** \brief Breakpoint + + This function causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __rbit + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW(value, ptr) __strex(value, ptr) + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +#define __CLREX __clrex + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + +#endif /* (__CORTEX_M >= 0x03) */ + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constrant "l" + * Otherwise, use general registers, specified by constrant "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void) +{ + __ASM volatile ("nop"); +} + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void) +{ + __ASM volatile ("wfi"); +} + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void) +{ + __ASM volatile ("wfe"); +} + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void) +{ + __ASM volatile ("sev"); +} + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void) +{ + __ASM volatile ("isb"); +} + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void) +{ + __ASM volatile ("dsb"); +} + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void) +{ + __ASM volatile ("dmb"); +} + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (short)__builtin_bswap16(value); +#else + uint32_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** \brief Rotate Right in unsigned value (32 bit) + + This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32 - op2)); +} + + +/** \brief Breakpoint + + This function causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ +#include + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + +#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ +/* Cosmic specific functions */ +#include + +#endif + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + +#endif /* __CORE_CMINSTR_H */ diff --git a/cpu/arm/common/CMSIS/core_sc000.h b/cpu/arm/common/CMSIS/core_sc000.h new file mode 100644 index 000000000..a32cc40d9 --- /dev/null +++ b/cpu/arm/common/CMSIS/core_sc000.h @@ -0,0 +1,833 @@ +/**************************************************************************//** + * @file core_sc000.h + * @brief CMSIS SC000 Core Peripheral Access Layer Header File + * @version V3.30 + * @date 06. May 2014 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + 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 ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifndef __CORE_SC000_H_GENERIC +#define __CORE_SC000_H_GENERIC + +#ifdef __cplusplus + extern "C" { +#endif + +/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
    + Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
    + Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
    + Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup SC000 + @{ + */ + +/* CMSIS SC000 definitions */ +#define __SC000_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __SC000_CMSIS_VERSION_SUB (0x30) /*!< [15:0] CMSIS HAL sub version */ +#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16) | \ + __SC000_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_SC (000) /*!< Cortex secure core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) /* Cosmic */ + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ + #define __STATIC_INLINE static inline + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all +*/ +#define __FPU_USED 0 + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI__VFP_SUPPORT____ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) /* Cosmic */ + #if ( __CSMC__ & 0x400) // FPU present for parser + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ + +#endif /* __CORE_SC000_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC000_H_DEPENDANT +#define __CORE_SC000_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC000_REV + #define __SC000_REV 0x0000 + #warning "__SC000_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/*@} end of group SC000 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31]; + __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31]; + __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31]; + __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31]; + uint32_t RESERVED4[64]; + __IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED0[1]; + __IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + uint32_t RESERVED1[154]; + __IO uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/* SCB Security Features Register Definitions */ +#define SCB_SFCR_UNIBRTIMING_Pos 0 /*!< SCB SFCR: UNIBRTIMING Position */ +#define SCB_SFCR_UNIBRTIMING_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SFCR: UNIBRTIMING Mask */ + +#define SCB_SFCR_SECKEY_Pos 16 /*!< SCB SFCR: SECKEY Position */ +#define SCB_SFCR_SECKEY_Msk (0xFFFFUL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SFCR: SECKEY Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[2]; + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_CALIB_TENMS_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 8 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) + are only accessible over DAP and not via processor. Therefore + they are not covered by the Cortex-M0 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of SC000 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 ) +#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) ) +#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) ) + + +/** \brief Enable External Interrupt + + The function enables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Disable External Interrupt + + The function disables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Get Pending Interrupt + + The function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + + +/** \brief Set Pending Interrupt + + The function sets the pending bit of an external interrupt. + + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Clear Pending Interrupt + + The function clears the pending bit of an external interrupt. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Set Interrupt Priority + + The function sets the priority of an interrupt. + + \note The priority cannot be set for every core interrupt. + + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } + else { + NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } +} + + +/** \brief Get Interrupt Priority + + The function reads the priority of an interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented + priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */ + else { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief System Reset + + The function initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + The function initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + + \param [in] ticks Number of ticks between two interrupts. + + \return 0 Function succeeded. + \return 1 Function failed. + + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#endif /* __CORE_SC000_H_DEPENDANT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CMSIS_GENERIC */ diff --git a/cpu/arm/common/CMSIS/core_sc300.h b/cpu/arm/common/CMSIS/core_sc300.h new file mode 100644 index 000000000..b22711749 --- /dev/null +++ b/cpu/arm/common/CMSIS/core_sc300.h @@ -0,0 +1,1618 @@ +/**************************************************************************//** + * @file core_sc300.h + * @brief CMSIS SC300 Core Peripheral Access Layer Header File + * @version V3.30 + * @date 06. May 2014 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + 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 ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifndef __CORE_SC300_H_GENERIC +#define __CORE_SC300_H_GENERIC + +#ifdef __cplusplus + extern "C" { +#endif + +/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
    + Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
    + Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
    + Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup SC3000 + @{ + */ + +/* CMSIS SC300 definitions */ +#define __SC300_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __SC300_CMSIS_VERSION_SUB (0x30) /*!< [15:0] CMSIS HAL sub version */ +#define __SC300_CMSIS_VERSION ((__SC300_CMSIS_VERSION_MAIN << 16) | \ + __SC300_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_SC (300) /*!< Cortex secure core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) /* Cosmic */ + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ + #define __STATIC_INLINE static inline + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all +*/ +#define __FPU_USED 0 + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI__VFP_SUPPORT____ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) /* Cosmic */ + #if ( __CSMC__ & 0x400) // FPU present for parser + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ + +#endif /* __CORE_SC300_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC300_H_DEPENDANT +#define __CORE_SC300_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC300_REV + #define __SC300_REV 0x0000 + #warning "__SC300_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/*@} end of group SC300 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLBASE_Pos 29 /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + uint32_t RESERVED1[1]; +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_CALIB_TENMS_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29]; + __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43]; + __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6]; + __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1]; + __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1]; + __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1]; + __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL << DWT_CPICNT_CPICNT_Pos) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL << DWT_EXCCNT_EXCCNT_Pos) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL << DWT_LSUCNT_LSUCNT_Pos) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL << DWT_MASK_MASK_Pos) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL << DWT_FUNCTION_FUNCTION_Pos) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2]; + __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55]; + __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131]; + __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759]; + __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1]; + __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39]; + __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8]; + __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL << TPI_ACPR_PRESCALER_Pos) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL << TPI_SPPR_TXMODE_Pos) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL << TPI_FFSR_FlInProg_Pos) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL << TPI_TRIGGER_TRIGGER_Pos) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL << TPI_FIFO0_ETM0_Pos) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL << TPI_FIFO1_ITM0_Pos) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL << TPI_DEVID_NrTraceInput_Pos) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M3 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** \brief Set Priority Grouping + + The function sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + The function reads the priority grouping field from the NVIC Interrupt Controller. + + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ +} + + +/** \brief Enable External Interrupt + + The function enables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */ +} + + +/** \brief Disable External Interrupt + + The function disables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \brief Get Pending Interrupt + + The function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ +} + + +/** \brief Set Pending Interrupt + + The function sets the pending bit of an external interrupt. + + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \brief Clear Pending Interrupt + + The function clears the pending bit of an external interrupt. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + The function reads the active register in NVIC and returns the active bit. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + + +/** \brief Set Interrupt Priority + + The function sets the priority of an interrupt. + + \note The priority cannot be set for every core interrupt. + + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \brief Get Interrupt Priority + + The function reads the priority of an interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented + priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + The function encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** \brief Decode Priority + + The function decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + +/** \brief System Reset + + The function initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + The function initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + + \param [in] ticks Number of ticks between two interrupts. + + \return 0 Function succeeded. + \return 1 Function failed. + + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** \brief ITM Send Character + + The function transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + + \param [in] ch Character to transmit. + + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + + +/** \brief ITM Receive Character + + The function inputs a character via the external variable \ref ITM_RxBuffer. + + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) { + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** \brief ITM Check Character + + The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + +#endif /* __CORE_SC300_H_DEPENDANT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CMSIS_GENERIC */ diff --git a/cpu/arm/common/usb/cdc-eth/cdc-eth.c b/cpu/arm/common/usb/cdc-eth/cdc-eth.c index 2d720ce20..1b074e7a9 100644 --- a/cpu/arm/common/usb/cdc-eth/cdc-eth.c +++ b/cpu/arm/common/usb/cdc-eth/cdc-eth.c @@ -117,12 +117,12 @@ PROCESS_THREAD(usb_eth_process, ev , data) uip_len = sizeof(recv_data) - recv_buffer.left; /* printf("Received: %d bytes\n", uip_len); */ memcpy(uip_buf, recv_data, uip_len); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) { uip_neighbor_add(&IPBUF->srcipaddr, &BUF->src); tcpip_input(); } else -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) { uip_len -= sizeof(struct uip_eth_hdr); tcpip_input(); diff --git a/cpu/arm/stm32f103/Makefile.stm32f103 b/cpu/arm/stm32f103/Makefile.stm32f103 index cfba80f5b..6f56bcfdf 100644 --- a/cpu/arm/stm32f103/Makefile.stm32f103 +++ b/cpu/arm/stm32f103/Makefile.stm32f103 @@ -75,7 +75,7 @@ CFLAGSNO = -I. -I$(CONTIKI)/core -I$(CONTIKI_CPU) -I$(CONTIKI_CPU)/loader \ -I$(CONTIKI_CPU)/dbg-io \ -I$(CONTIKI)/platform/$(TARGET) \ ${addprefix -I,$(APPDIRS)} \ - -DWITH_UIP -DWITH_ASCII -DMCK=$(MCK) \ + -DWITH_ASCII -DMCK=$(MCK) \ -Wall $(ARCH_FLAGS) -g -D SUBTARGET=$(SUBTARGET) CFLAGS += $(CFLAGSNO) -O -DRUN_AS_SYSTEM -DROM_RUN diff --git a/cpu/arm/stm32l152/Makefile.stm32l152 b/cpu/arm/stm32l152/Makefile.stm32l152 new file mode 100644 index 000000000..4d461df0c --- /dev/null +++ b/cpu/arm/stm32l152/Makefile.stm32l152 @@ -0,0 +1,136 @@ +# Makefile for the STM32L152 Cortex M3 medium-density microcontroller + +.SUFFIXES: + +# CPU folder +CONTIKI_CPU=$(CONTIKI)/cpu/arm/stm32l152 + +# Source folders for contiki cpu files +CONTIKI_CPU_DIRS = . + +# source files: proprietary sources for startup. Refer to CMSIS docs. +PROP_SYS_ARCH_C = system_stm32l1xx.c + + +ifdef IAR +include $(CONTIKI_CPU)/Makefile.stm32l152.iar +else +include $(CONTIKI_CPU)/Makefile.stm32l152.gnu +endif + + +# source files: Contiki arch source files +CONTIKI_CPU_ARCH= watchdog.c \ + rtimer-arch.c \ + clock.c + +ifdef GCC +CONTIKI_CPU_PORT= syscalls.c \ + console.c \ + crt.c \ + uart.c +else +CONTIKI_CPU_PORT= +endif + + + +UIPDRIVERS= + +# to be implemented +ELFLOADER= + + +# add CPU folder to search path for .s (assembler) files +ifdef GCC +vpath %.s $(CONTIKI)/platform/$(TARGET)/stm32cube-lib/stm32cube-prj/startup_files/gcc +else +vpath %.s $(CONTIKI)/platform/$(TARGET)/stm32cube-lib/stm32cube-prj/startup_files/iar +endif + +# include all files above +ssubst = ${patsubst %.s,%.o,${patsubst %.s79,%.o,$(1)}} +CONTIKI_TARGET_SOURCEFILES += $(PROP_SYS_ARCH_C) $(PROP_USB_ARCH) $(CONTIKI_CPU_ARCH) $(CONTIKI_CPU_PORT) $(ELFLOADER) $(UIPDRIVERS) +CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) +PROJECT_OBJECTFILES += ${addprefix $(OBJECTDIR)/,$(CONTIKI_TARGET_MAIN:.c=.o)} +PROJECT_OBJECTFILES += ${addprefix $(OBJECTDIR)/,${call ssubst, $(PROP_SYS_ARCH_S)}} +#CONTIKI_OBJECTFILES += ${addprefix $(OBJECTDIR)/,${call ssubst, $(PROP_SYS_ARCH_S)}} + +#------------------------------------------------ defines common for IAR and GCC +# set CPU speed in Hz, NB this might have unexpected side-effects if not at 32 +# Mhz as it is not immediately clear how specialized the startup code etc is. +# That being said, setting to 24MHz seems to work fine, looking at Contiki clocks +# at least. +F_CPU = 32000000 + +CFLAGS+=\ + -DHSE_VALUE=$(F_CPU)ul \ + -DUSE_STDPERIPH_DRIVER \ + -DSTM32L1XX_MD \ + -DIAR_ARM_CM3 \ + -DVECT_TAB_FLASH \ + -DWITH_UIP6 + +# ------------------------------------------------------------------ Build rules +CUSTOM_RULE_C_TO_CE=yes +CUSTOM_RULE_C_TO_CO=yes +CUSTOM_RULE_C_TO_O=yes +CUSTOM_RULE_S_TO_OBJECTDIR_O=yes +CUSTOM_RULE_LINK=yes + +%.o: %.c + $(CC) $(CFLAGS) $< -o $@ + +%.o: %.s + $(AS) $(ASFLAGS) $< -o $@ + +define FINALIZE_CYGWIN_DEPENDENCY +sed -e 's/ \([A-Z]\):\\/ \/cygdrive\/\L\1\//' -e 's/\\\([^ ]\)/\/\1/g' \ + <$(@:.o=.P) >$(@:.o=.d); \ +rm -f $(@:.o=.P) +endef + +$(OBJECTDIR)/%.o: %.s + $(AS) $(ASFLAGS) $< -o $@ + +%.ce: %.o + $(LD) $(LDFLAGS) --relocatable -T $(CONTIKI_CPU)/merge-rodata.ld $< -o $@ $(LDLIBS) + $(STRIP) -K _init -K _fini --strip-unneeded -g -x $@ + +%-stripped.o: %.c + $(CC) $(CFLAGS) $< -o $@ + $(STRIP) --strip $@ + +%-stripped.o: %.o + $(STRIP) --strip $@ $< + +%.o: ${CONTIKI_TARGET}/loader/%.S + $(AS) -o $(notdir $(<:.S=.o)) $< + +ifdef IAR +%.$(TARGET): %.co $(PROJECT_OBJECTFILES) contiki-$(TARGET).a $(STARTUPFOLDER) # $(OBJECTDIR)/empty-symbols.o + $(LD) $(LDFLAGS) -o $@ $(filter-out %.a,$^) $(filter %.a,$^) $(LDLIBS) +else +#CONTIKI_CPU_OBJS=$(CONTIKI_CPU_PORT:%.c=obj_stm32nucleo-spirit1/%.o) +CONTIKI_CPU_OBJS=$(CONTIKI_CPU_PORT:%.c=$(OBJECTDIR)/%.o) +%.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a $(OBJECTDIR)/symbols.o + $(TRACE_LD) + $(Q)$(LD) $(LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} -Wl,-\( ${filter %.a,$^} $(TARGET_LIBFILES) -Wl,-\) $(CONTIKI_CPU_OBJS) -o $@ + @echo >> contiki-$(TARGET).map + @$(SIZE) $(SIZEFLAGS) $@ >> contiki-$(TARGET).map +endif + +%.hex: %.ihex + # @rm $*.hex + @mv -f $*.ihex $*.hex + +.PHONY: symbols.c + +symbols.c: + cp ${CONTIKI}/tools/empty-symbols.c symbols.c + cp ${CONTIKI}/tools/empty-symbols.h symbols.h + +# Don't use core/loader/elfloader.c, use elfloader-otf.c instead +$(OBJECTDIR)/elfloader.o: + echo -n >$@ + diff --git a/cpu/arm/stm32l152/Makefile.stm32l152.gnu b/cpu/arm/stm32l152/Makefile.stm32l152.gnu new file mode 100644 index 000000000..a6c62e7c6 --- /dev/null +++ b/cpu/arm/stm32l152/Makefile.stm32l152.gnu @@ -0,0 +1,65 @@ +PROP_SYS_ARCH_S = startup_stm32l152xe.s + +### Compiler definitions +GCC = 1 +CC = arm-none-eabi-gcc +LD = arm-none-eabi-gcc +SIZE = arm-none-eabi-size +AS = arm-none-eabi-as +AR = arm-none-eabi-ar +NM = arm-none-eabi-nm +OBJCOPY = arm-none-eabi-objcopy +STRIP = arm-none-eabi-strip + +%.ihex: %.$(TARGET) + $(OBJCOPY) -O ihex $^ $@ +%.bin: %.$(TARGET) + $(OBJCOPY) -O binary $^ $@ +%.co: %.c + $(CC) $(CFLAGS) -c -DAUTOSTART_ENABLE $< -o $@ + + +ifndef LDSCRIPT +LDSCRIPT = $(CONTIKI)/platform/$(TARGET)/stm32cube-lib/stm32cube-prj/linker/gcc/STM32L152RETx_FLASH.ld +endif + +#ASFLAGS += -mcpu=cortex-m3 -mthumb + +# this platform wields a STM32L152VB medium-density device +CFLAGS+=-DSTM32L1XX_MD=1 + +CFLAGS+=\ + -I$(CONTIKI)/cpu/arm/common/CMSIS \ + -Wall -g -O0 \ + -DWITH_UIP -DWITH_ASCII \ + -mcpu=cortex-m3 \ + -mthumb \ + -mno-unaligned-access \ + -mfix-cortex-m3-ldrd \ + -std=gnu99 \ + -Wl,-cref \ + -D __SOURCEFILE__=\"$*.c\" + + +LDFLAGS += -Wl,-Map=contiki-$(TARGET).map,--cref,--no-warn-mismatch + + +LDLIBS += $(CONTIKI_CPU)/lib/smallprintf_thumb2.a + + + +LDFLAGS += -mcpu=cortex-m3 -mthumb -mfloat-abi=soft -T$(LDSCRIPT) -Wl,-Map=output.map -Wl,--gc-sections -lm + + +LDFLAGS += $(LDLIBS) + +SMALL=1 +ifeq ($(SMALL),1) +CFLAGS += -ffunction-sections +CFLAGS += -fdata-sections + +LDFLAGS += -Wl,--undefined=_reset_vector__,--undefined=InterruptVectors,--undefined=_copy_data_init__,--undefined=_clear_bss_init__,--undefined=_end_of_init__ + +endif # /SMALL + + diff --git a/cpu/arm/stm32l152/Makefile.stm32l152.iar b/cpu/arm/stm32l152/Makefile.stm32l152.iar new file mode 100644 index 000000000..5e6758313 --- /dev/null +++ b/cpu/arm/stm32l152/Makefile.stm32l152.iar @@ -0,0 +1,84 @@ +PROP_SYS_ARCH_S = startup_stm32l152xe.s + + +# Compiler definitions +IAR = 1 +CC = iccarm +LD = ilinkarm +AS = iasmarm +AR = iarchive +OBJCOPY = ielftool +STRIP = iobjmanip +SIZE = +NM = + +%.ihex: %.$(TARGET) + $(OBJCOPY) $^ --ihex $@ +%.bin: %.$(TARGET) + $(OBJCOPY) --bin $@ + + +# Find the path to compiler; this works with cygwin +ifndef IAR_PATH +IAR_BIN_PATH := $(shell dirname "`which $(CC)`") +IAR_PATH_C := $(shell dirname "$(IAR_BIN_PATH)") +IAR_PATH := $(shell cygpath -m "$(IAR_PATH_C)") +endif + +# ------------compiler flags +CFLAGS+=\ + -I"$(IAR_PATH)/CMSIS/Include" \ + --diag_suppress Pa050 \ + --no_unroll \ + --no_inline \ + --no_tbaa \ + --no_scheduling \ + --debug \ + --endian=little \ + --cpu=Cortex-M3 \ + -Om \ + -e \ + --fpu=None \ + --dlib_config "$(IAR_PATH)/inc/c/DLib_Config_Normal.h" \ + -DIAR=1 \ + -DWITH_USB_PRINTF=1 + +# -I$(CONTIKI)/cpu/arm/common/CMSIS \ + +# ------------assembler flags +ASFLAGS+= -s+ -r -DIAR_ARM_CM3 -cAOM -B -t8 --cpu Cortex-M3 --fpu None + +#iasmarm -s+ -w+ -r -DIAR_ARM_CM3 -cAOM -B -t8 --cpu Cortex-M3 --fpu None startup_stm32l1xx_md.s + +# ------------archive creation flags +AROPTS= --create --output + +# ----------linker flags +# this will also generate log and symbol map files +ICF_FILE="$(CONTIKI)/platform/$(TARGET)/stm32cube-lib/stm32cube-prj/linker/iar/stm32l1xx_flash.icf" +LDFLAGS+= \ + --config $(ICF_FILE) \ + --entry __iar_program_start \ + --redirect _Printf=_PrintfLarge \ + --redirect _Scanf=_ScanfLarge \ + --semihosting \ + --no_exceptions \ + --no_remove \ + --cpu=Cortex-M3 \ + --log libraries,initialization,modules,redirects,sections,veneers,unused_fragments \ + --log_file contiki-$(TARGET).log \ + --map contiki-$(TARGET).map \ + --vfe + +CUSTOM_RULE_C_TO_OBJECTDIR_O=yes +$(OBJECTDIR)/%.o: %.c | $(OBJECTDIR) + $(CC) $(CFLAGS) --dependencies=m $(@:.o=.P) $< -o $@ +ifeq ($(HOST_OS),Windows) + @$(FINALIZE_CYGWIN_DEPENDENCY) +endif + +%.co: %.c + $(CC) $(CFLAGS) -DAUTOSTART_ENABLE $< -o $@ + + + diff --git a/cpu/arm/stm32l152/clock.c b/cpu/arm/stm32l152/clock.c new file mode 100644 index 000000000..a2a48e44b --- /dev/null +++ b/cpu/arm/stm32l152/clock.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "platform-conf.h" +#include "contiki-conf.h" +#include "dev/leds.h" +#include "stm32l1xx.h" +#include "stm32l1xx_hal_rcc.h" +#include "stm32l1xx_hal_cortex.h" +#include "stm32l1xx_hal.h" +#include "st-lib.h" +/*---------------------------------------------------------------------------*/ +#define RELOAD_VALUE ((F_CPU / CLOCK_CONF_SECOND) - 1) +/*---------------------------------------------------------------------------*/ +static volatile unsigned long seconds = 0; +static volatile clock_time_t ticks; +void st_lib_sys_tick_handler(void); +/*---------------------------------------------------------------------------*/ +void +st_lib_sys_tick_handler(void) +{ + ticks++; + if((ticks % CLOCK_SECOND) == 0) { + seconds++; + energest_flush(); + } + HAL_IncTick(); + + if(etimer_pending()) { + etimer_request_poll(); + } +} +/*---------------------------------------------------------------------------*/ +void +clock_init(void) +{ + ticks = 0; + st_lib_hal_systick_clk_source_config(SYSTICK_CLKSOURCE_HCLK); + st_lib_hal_systick_config(RELOAD_VALUE); +} +/*---------------------------------------------------------------------------*/ +unsigned long +clock_seconds(void) +{ + return seconds; +} +/*---------------------------------------------------------------------------*/ +void +clock_set_seconds(unsigned long sec) +{ + seconds = sec; +} +/*---------------------------------------------------------------------------*/ +clock_time_t +clock_time(void) +{ + return ticks; +} +/*---------------------------------------------------------------------------*/ +void +clock_delay(unsigned int i) +{ + for(; i > 0; i--) { + unsigned int j; + for(j = 50; j > 0; j--) { + asm ("nop"); + } + } +} +/*---------------------------------------------------------------------------*/ +/* Wait for a multiple of clock ticks (7.8 ms at 128 Hz). */ +void +clock_wait(clock_time_t t) +{ + clock_time_t start; + start = clock_time(); + while(clock_time() - start < (clock_time_t)t) ; +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/arm/stm32l152/console.c b/cpu/arm/stm32l152/console.c new file mode 100644 index 000000000..6a619a5c1 --- /dev/null +++ b/cpu/arm/stm32l152/console.c @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +#include +#include +#include "console.h" +#include "stm32l1xx.h" +#include "stm32l1xx_hal_dma.h" +#include "stm32l1xx_hal_uart.h" +#include "st-lib.h" +/*---------------------------------------------------------------------------*/ +extern st_lib_uart_handle_typedef st_lib_uart_handle; +/*---------------------------------------------------------------------------*/ +/** + * @brief Initialises Nucleo UART port for user IO + * @retval 0 + */ +int +console_init(void) +{ + st_lib_uart_handle.Instance = USART2; + + st_lib_uart_handle.Init.BaudRate = 115200; + st_lib_uart_handle.Init.WordLength = UART_WORDLENGTH_8B; + st_lib_uart_handle.Init.StopBits = UART_STOPBITS_1; + st_lib_uart_handle.Init.Parity = UART_PARITY_NONE; + st_lib_uart_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; + st_lib_uart_handle.Init.Mode = UART_MODE_TX_RX; + + st_lib_hal_uart_init(&st_lib_uart_handle); + + return 0; +} +/*---------------------------------------------------------------------------*/ +/** @brief Sends a character to serial port + * @param ch Character to send + * @retval Character sent + */ +int +uart_send_char(int ch) +{ + st_lib_hal_uart_transmit(&st_lib_uart_handle, (uint8_t *)&ch, 1, HAL_MAX_DELAY); + return ch; +} +/*---------------------------------------------------------------------------*/ +/** @brief Receives a character from serial port + * @retval Character received + */ +int +uart_receive_char(void) +{ + uint8_t ch; + st_lib_hal_uart_receive(&st_lib_uart_handle, &ch, 1, HAL_MAX_DELAY); + + /* Echo character back to console */ + st_lib_hal_uart_transmit(&st_lib_uart_handle, &ch, 1, HAL_MAX_DELAY); + + /* And cope with Windows */ + if(ch == '\r') { + uint8_t ret = '\n'; + st_lib_hal_uart_transmit(&st_lib_uart_handle, &ret, 1, HAL_MAX_DELAY); + } + + return ch; +} +/*---------------------------------------------------------------------------*/ +#if defined(__IAR_SYSTEMS_ICC__) + +size_t __write(int Handle, const unsigned char *Buf, size_t Bufsize); +size_t __read(int Handle, unsigned char *Buf, size_t Bufsize); + +/** @brief IAR specific low level standard input + * @param handle IAR internal handle + * @param buf Buffer where to store characters read from stdin + * @param bufsize Number of characters to read + * @retval Number of characters read + */ +size_t +__read(int handle, unsigned char *buf, size_t bufsize) +{ + int i; + + if(handle != 0) { + return -1; + } + + for(i = 0; i < bufsize; i++) { + buf[i] = uart_receive_char(); + } + + return bufsize; +} +/** @brief IAR specific low level standard output + * @param handle IAR internal handle + * @param buf Buffer containing characters to be written to stdout + * @param bufsize Number of characters to write + * @retval Number of characters read + */ +size_t +__write(int handle, const unsigned char *buf, size_t bufsize) +{ + int i; + + if(handle != 1 && handle != 2) { + return -1; + } + + for(i = 0; i < bufsize; i++) { + uart_send_char(buf[i]); + } + + return bufsize; +} +/*---------------------------------------------------------------------------*/ +#elif defined(__CC_ARM) +/** + * @brief fputc call for standard output implementation + * @param ch Character to print + * @param f File pointer + * @retval Character printed + */ +int +fputc(int ch, FILE *f) +{ + return uart_send_char(ch); +} +/** @brief fgetc call for standard input implementation + * @param f File pointer + * @retval Character acquired from standard input + */ +int +fgetc(FILE *f) +{ + return uart_receive_char(); +} +/*---------------------------------------------------------------------------*/ +#elif defined(__GNUC__) + +/** @brief putchar call for standard output implementation + * @param ch Character to print + * @retval Character printed + */ +int +__io_putchar(int ch) +{ + return uart_send_char(ch); +} +/** @brief getchar call for standard input implementation + * @param None + * @retval Character acquired from standard input + */ +int +__io_getchar(void) +{ + return uart_receive_char(); +} +/*---------------------------------------------------------------------------*/ +#else +#error "Toolchain not supported" +#endif +/*---------------------------------------------------------------------------*/ diff --git a/cpu/arm/stm32l152/console.h b/cpu/arm/stm32l152/console.h new file mode 100644 index 000000000..20a04ec8e --- /dev/null +++ b/cpu/arm/stm32l152/console.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +#if defined(__IAR_SYSTEMS_ICC__) +size_t __write(int handle, const unsigned char *buf, size_t bufsize); +size_t __read(int handle, unsigned char *buf, size_t bufsize); +/*---------------------------------------------------------------------------*/ +#elif defined(__CC_ARM) +/** + * @brief fputc call for standard output implementation + * @param ch Character to print + * @param f File pointer + * @retval Character printed + */ +int fputc(int ch, FILE *f); + +/** @brief fgetc call for standard input implementation + * @param f File pointer + * @retval Character acquired from standard input + */ +int fgetc(FILE *f); +/*---------------------------------------------------------------------------*/ +#elif defined(__GNUC__) +/** @brief putchar call for standard output implementation + * @param ch Character to print + * @retval Character printed + */ +int __io_putchar(int ch); + +/** @brief getchar call for standard input implementation + * @param None + * @retval Character acquired from standard input + */ +int __io_getchar(void); +/*---------------------------------------------------------------------------*/ +#else +#error "Toolchain not supported" +#endif +/*---------------------------------------------------------------------------*/ diff --git a/platform/z1sp/dev/potentiometer-sensor.c b/cpu/arm/stm32l152/crt.c similarity index 65% rename from platform/z1sp/dev/potentiometer-sensor.c rename to cpu/arm/stm32l152/crt.c index ccfc1e851..0022eff66 100644 --- a/platform/z1sp/dev/potentiometer-sensor.c +++ b/cpu/arm/stm32l152/crt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Zolertia(TM) is a trademark by Advancare,SL + * Copyright (c) 2012, STMicroelectronics. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,41 +27,61 @@ * SUCH DAMAGE. * * - * ----------------------------------------------------------------- - * - * Author : Enric M. Calvo (based on work by A. Dunkels, J. Eriksson, N. Finne) - * Created : 2011-02-22 - * $Revision: 1.0 $ */ - -#include "contiki.h" -#include "dev/potentiometer-sensor.h" -#include "dev/sky-sensors.h" - -/* Configure ADC12_2 to sample channel 11 (voltage) and use */ -/* the Vref+ as reference (SREF_1) since it is a stable reference */ -#define INPUT_CHANNEL (1 << INCH_4) -#define INPUT_REFERENCE SREF_0 -#define POTENTIOMETER_MEM ADC12MEM4 - -const struct sensors_sensor battery_sensor; /*---------------------------------------------------------------------------*/ -static int -value(int type) +#include +#include +/*---------------------------------------------------------------------------*/ +int +_lseek(int file, + int ptr, + int dir) { - return POTENTIOMETER_MEM; + return 0; } /*---------------------------------------------------------------------------*/ -static int -configure(int type, int c) +int +_close(int file) { - return sky_sensors_configure(INPUT_CHANNEL, INPUT_REFERENCE, type, c); + return -1; } /*---------------------------------------------------------------------------*/ -static int -status(int type) +void +_exit(int n) { - return sky_sensors_status(INPUT_CHANNEL, type); + /* FIXME: return code is thrown away. */ + while(1) ; +} +/*---------------------------------------------------------------------------*/ +int +_kill(int n, int m) +{ + return -1; +} +/*---------------------------------------------------------------------------*/ +int +_fstat(int file, struct stat *st) +{ + st->st_mode = S_IFCHR; + return 0; +} +/*---------------------------------------------------------------------------*/ +int +_isatty(int fd) +{ + return 1; + fd = fd; +} +/*---------------------------------------------------------------------------*/ +int +_getpid(int n) +{ + return -1; +} +/*---------------------------------------------------------------------------*/ +int +_open(const char *path, int flags, ...) +{ + return -1; } /*---------------------------------------------------------------------------*/ -SENSORS_SENSOR(potentiometer_sensor, POTENTIOMETER_SENSOR, value, configure, status); diff --git a/cpu/arm/stm32l152/lib/e_stdio_intonly_thumb2.a b/cpu/arm/stm32l152/lib/e_stdio_intonly_thumb2.a new file mode 100644 index 000000000..bd3878d65 Binary files /dev/null and b/cpu/arm/stm32l152/lib/e_stdio_intonly_thumb2.a differ diff --git a/cpu/arm/stm32l152/lib/e_stdio_thumb2.a b/cpu/arm/stm32l152/lib/e_stdio_thumb2.a new file mode 100644 index 000000000..61c4323c9 Binary files /dev/null and b/cpu/arm/stm32l152/lib/e_stdio_thumb2.a differ diff --git a/cpu/arm/stm32l152/lib/smallprintf_thumb2.a b/cpu/arm/stm32l152/lib/smallprintf_thumb2.a new file mode 100644 index 000000000..30d31872a Binary files /dev/null and b/cpu/arm/stm32l152/lib/smallprintf_thumb2.a differ diff --git a/examples/sensinode/sniffer/sniffer.c b/cpu/arm/stm32l152/mtarch.h similarity index 78% rename from examples/sensinode/sniffer/sniffer.c rename to cpu/arm/stm32l152/mtarch.h index 74d24588e..0f18b4015 100644 --- a/examples/sensinode/sniffer/sniffer.c +++ b/cpu/arm/stm32l152/mtarch.h @@ -1,4 +1,7 @@ /* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -23,32 +26,17 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * This file is part of the Contiki operating system. * */ - -#include "contiki.h" -#include "cc2430_sfr.h" - -#define DEBUG DEBUG_NONE -#include "net/ip/uip-debug.h" - /*---------------------------------------------------------------------------*/ -PROCESS(sniffer_process, "Sniffer process"); -AUTOSTART_PROCESSES(&sniffer_process); +/* + * Implementation of multithreading in ARM Cortex-M3. To be done. + */ +#ifndef __MTARCH_H__ +#define __MTARCH_H__ /*---------------------------------------------------------------------------*/ -PROCESS_THREAD(sniffer_process, ev, data) -{ - - PROCESS_BEGIN(); - - PRINTF("Sniffer started\n"); - - /* Turn off cc2430 Address Recognition - We need to accept all frames */ - MDMCTRL0H &= ~0x08; - - PROCESS_EXIT(); - - PROCESS_END(); -} +struct mtarch_thread { + short mt_thread; +}; /*---------------------------------------------------------------------------*/ +#endif /* __MTARCH_H__ */ diff --git a/cpu/arm/stm32l152/regs.h b/cpu/arm/stm32l152/regs.h new file mode 100644 index 000000000..6d80c3622 --- /dev/null +++ b/cpu/arm/stm32l152/regs.h @@ -0,0 +1,11575 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +#ifndef REGS_H_ +#define REGS_H_ 1 +/*---------------------------------------------------------------------------*/ +#define ReadRegister(a) a +#define WriteRegister(a, b) a = b + +/* FLASH_BASE block */ +#define DATA_FLASH_BASE_BASE (0x00000000u) +#define DATA_FLASH_BASE_END (0x0001FFFFu) +#define DATA_FLASH_BASE_SIZE (DATA_FLASH_BASE_END - DATA_FLASH_BASE_BASE + 1) + +/* FLASH block */ +#define DATA_FLASH_BASE (0x08000000u) +#define DATA_FLASH_END (0x0801FFFFu) +#define DATA_FLASH_SIZE (DATA_FLASH_END - DATA_FLASH_BASE + 1) + +/* BIG_INFO_BASE block */ +#define DATA_BIG_INFO_BASE_BASE (0x00000000u) +#define DATA_BIG_INFO_BASE_END (0x000007FFu) +#define DATA_BIG_INFO_BASE_SIZE (DATA_BIG_INFO_BASE_END - DATA_BIG_INFO_BASE_BASE + 1) + +/* BIG_INFO block */ +#define DATA_BIG_INFO_BASE (0x08040000u) +#define DATA_BIG_INFO_END (0x080407FFu) +#define DATA_BIG_INFO_SIZE (DATA_BIG_INFO_END - DATA_BIG_INFO_BASE + 1) + +/* SMALL_INFO block */ +#define DATA_SMALL_INFO_BASE (0x08040800u) +#define DATA_SMALL_INFO_END (0x080409FFu) +#define DATA_SMALL_INFO_SIZE (DATA_SMALL_INFO_END - DATA_SMALL_INFO_BASE + 1) + +/* SRAM block */ +#define DATA_SRAM_BASE (0x20000000u) +#define DATA_SRAM_END (0x20001FFFu) +#define DATA_SRAM_SIZE (DATA_SRAM_END - DATA_SRAM_BASE + 1) + +/* CM_HV block */ +#define DATA_CM_HV_BASE (0x40000000u) +#define DATA_CM_HV_END (0x40000044u) +#define DATA_CM_HV_SIZE (DATA_CM_HV_END - DATA_CM_HV_BASE + 1) + +#define HV_SPARE *((volatile uint32_t *)0x40000000u) +#define HV_SPARE_REG *((volatile uint32_t *)0x40000000u) +#define HV_SPARE_ADDR (0x40000000u) +#define HV_SPARE_RESET (0x00000000u) +/* HV_SPARE field */ +#define HV_SPARE_HV_SPARE (0x000000FFu) +#define HV_SPARE_HV_SPARE_MASK (0x000000FFu) +#define HV_SPARE_HV_SPARE_BIT (0) +#define HV_SPARE_HV_SPARE_BITS (8) + +#define EVENT_CTRL *((volatile uint32_t *)0x40000004u) +#define EVENT_CTRL_REG *((volatile uint32_t *)0x40000004u) +#define EVENT_CTRL_ADDR (0x40000004u) +#define EVENT_CTRL_RESET (0x00000000u) +/* LV_FREEZE field */ +#define LV_FREEZE (0x00000002u) +#define LV_FREEZE_MASK (0x00000002u) +#define LV_FREEZE_BIT (1) +#define LV_FREEZE_BITS (1) + +#define SLEEPTMR_CLKEN *((volatile uint32_t *)0x40000008u) +#define SLEEPTMR_CLKEN_REG *((volatile uint32_t *)0x40000008u) +#define SLEEPTMR_CLKEN_ADDR (0x40000008u) +#define SLEEPTMR_CLKEN_RESET (0x00000002u) +/* SLEEPTMR_CLK10KEN field */ +#define SLEEPTMR_CLK10KEN (0x00000002u) +#define SLEEPTMR_CLK10KEN_MASK (0x00000002u) +#define SLEEPTMR_CLK10KEN_BIT (1) +#define SLEEPTMR_CLK10KEN_BITS (1) +/* SLEEPTMR_CLK32KEN field */ +#define SLEEPTMR_CLK32KEN (0x00000001u) +#define SLEEPTMR_CLK32KEN_MASK (0x00000001u) +#define SLEEPTMR_CLK32KEN_BIT (0) +#define SLEEPTMR_CLK32KEN_BITS (1) + +#define CLKRC_TUNE *((volatile uint32_t *)0x4000000Cu) +#define CLKRC_TUNE_REG *((volatile uint32_t *)0x4000000Cu) +#define CLKRC_TUNE_ADDR (0x4000000Cu) +#define CLKRC_TUNE_RESET (0x00000000u) +/* CLKRC_TUNE_FIELD field */ +#define CLKRC_TUNE_FIELD (0x0000000Fu) +#define CLKRC_TUNE_FIELD_MASK (0x0000000Fu) +#define CLKRC_TUNE_FIELD_BIT (0) +#define CLKRC_TUNE_FIELD_BITS (4) + +#define CLK1K_CAL *((volatile uint32_t *)0x40000010u) +#define CLK1K_CAL_REG *((volatile uint32_t *)0x40000010u) +#define CLK1K_CAL_ADDR (0x40000010u) +#define CLK1K_CAL_RESET (0x00005000u) +/* CLK1K_INTEGER field */ +#define CLK1K_INTEGER (0x0000F800u) +#define CLK1K_INTEGER_MASK (0x0000F800u) +#define CLK1K_INTEGER_BIT (11) +#define CLK1K_INTEGER_BITS (5) +/* CLK1K_FRACTIONAL field */ +#define CLK1K_FRACTIONAL (0x000007FFu) +#define CLK1K_FRACTIONAL_MASK (0x000007FFu) +#define CLK1K_FRACTIONAL_BIT (0) +#define CLK1K_FRACTIONAL_BITS (11) + +#define REGEN_DSLEEP *((volatile uint32_t *)0x40000014u) +#define REGEN_DSLEEP_REG *((volatile uint32_t *)0x40000014u) +#define REGEN_DSLEEP_ADDR (0x40000014u) +#define REGEN_DSLEEP_RESET (0x00000001u) +/* REGEN_DSLEEP_FIELD field */ +#define REGEN_DSLEEP_FIELD (0x00000001u) +#define REGEN_DSLEEP_FIELD_MASK (0x00000001u) +#define REGEN_DSLEEP_FIELD_BIT (0) +#define REGEN_DSLEEP_FIELD_BITS (1) + +#define VREG *((volatile uint32_t *)0x40000018u) +#define VREG_REG *((volatile uint32_t *)0x40000018u) +#define VREG_ADDR (0x40000018u) +#define VREG_RESET (0x00000207u) +/* VREF_EN field */ +#define VREG_VREF_EN (0x00008000u) +#define VREG_VREF_EN_MASK (0x00008000u) +#define VREG_VREF_EN_BIT (15) +#define VREG_VREF_EN_BITS (1) +/* VREF_TEST field */ +#define VREG_VREF_TEST (0x00004000u) +#define VREG_VREF_TEST_MASK (0x00004000u) +#define VREG_VREF_TEST_BIT (14) +#define VREG_VREF_TEST_BITS (1) +/* VREG_1V8_EN field */ +#define VREG_VREG_1V8_EN (0x00000800u) +#define VREG_VREG_1V8_EN_MASK (0x00000800u) +#define VREG_VREG_1V8_EN_BIT (11) +#define VREG_VREG_1V8_EN_BITS (1) +/* VREG_1V8_TEST field */ +#define VREG_VREG_1V8_TEST (0x00000400u) +#define VREG_VREG_1V8_TEST_MASK (0x00000400u) +#define VREG_VREG_1V8_TEST_BIT (10) +#define VREG_VREG_1V8_TEST_BITS (1) +/* VREG_1V8_TRIM field */ +#define VREG_VREG_1V8_TRIM (0x00000380u) +#define VREG_VREG_1V8_TRIM_MASK (0x00000380u) +#define VREG_VREG_1V8_TRIM_BIT (7) +#define VREG_VREG_1V8_TRIM_BITS (3) +/* VREG_1V2_EN field */ +#define VREG_VREG_1V2_EN (0x00000010u) +#define VREG_VREG_1V2_EN_MASK (0x00000010u) +#define VREG_VREG_1V2_EN_BIT (4) +#define VREG_VREG_1V2_EN_BITS (1) +/* VREG_1V2_TEST field */ +#define VREG_VREG_1V2_TEST (0x00000008u) +#define VREG_VREG_1V2_TEST_MASK (0x00000008u) +#define VREG_VREG_1V2_TEST_BIT (3) +#define VREG_VREG_1V2_TEST_BITS (1) +/* VREG_1V2_TRIM field */ +#define VREG_VREG_1V2_TRIM (0x00000007u) +#define VREG_VREG_1V2_TRIM_MASK (0x00000007u) +#define VREG_VREG_1V2_TRIM_BIT (0) +#define VREG_VREG_1V2_TRIM_BITS (3) + +#define WAKE_SEL *((volatile uint32_t *)0x40000020u) +#define WAKE_SEL_REG *((volatile uint32_t *)0x40000020u) +#define WAKE_SEL_ADDR (0x40000020u) +#define WAKE_SEL_RESET (0x00000200u) +/* WAKE_CSYSPWRUPREQ field */ +#define WAKE_CSYSPWRUPREQ (0x00000200u) +#define WAKE_CSYSPWRUPREQ_MASK (0x00000200u) +#define WAKE_CSYSPWRUPREQ_BIT (9) +#define WAKE_CSYSPWRUPREQ_BITS (1) +/* WAKE_CDBGPWRUPREQ field */ +#define WAKE_CDBGPWRUPREQ (0x00000100u) +#define WAKE_CDBGPWRUPREQ_MASK (0x00000100u) +#define WAKE_CDBGPWRUPREQ_BIT (8) +#define WAKE_CDBGPWRUPREQ_BITS (1) +/* WAKE_WAKE_CORE field */ +#define WAKE_WAKE_CORE (0x00000080u) +#define WAKE_WAKE_CORE_MASK (0x00000080u) +#define WAKE_WAKE_CORE_BIT (7) +#define WAKE_WAKE_CORE_BITS (1) +/* WAKE_SLEEPTMRWRAP field */ +#define WAKE_SLEEPTMRWRAP (0x00000040u) +#define WAKE_SLEEPTMRWRAP_MASK (0x00000040u) +#define WAKE_SLEEPTMRWRAP_BIT (6) +#define WAKE_SLEEPTMRWRAP_BITS (1) +/* WAKE_SLEEPTMRCMPB field */ +#define WAKE_SLEEPTMRCMPB (0x00000020u) +#define WAKE_SLEEPTMRCMPB_MASK (0x00000020u) +#define WAKE_SLEEPTMRCMPB_BIT (5) +#define WAKE_SLEEPTMRCMPB_BITS (1) +/* WAKE_SLEEPTMRCMPA field */ +#define WAKE_SLEEPTMRCMPA (0x00000010u) +#define WAKE_SLEEPTMRCMPA_MASK (0x00000010u) +#define WAKE_SLEEPTMRCMPA_BIT (4) +#define WAKE_SLEEPTMRCMPA_BITS (1) +/* WAKE_IRQD field */ +#define WAKE_IRQD (0x00000008u) +#define WAKE_IRQD_MASK (0x00000008u) +#define WAKE_IRQD_BIT (3) +#define WAKE_IRQD_BITS (1) +/* WAKE_SC2 field */ +#define WAKE_SC2 (0x00000004u) +#define WAKE_SC2_MASK (0x00000004u) +#define WAKE_SC2_BIT (2) +#define WAKE_SC2_BITS (1) +/* WAKE_SC1 field */ +#define WAKE_SC1 (0x00000002u) +#define WAKE_SC1_MASK (0x00000002u) +#define WAKE_SC1_BIT (1) +#define WAKE_SC1_BITS (1) +/* GPIO_WAKE field */ +#define GPIO_WAKE (0x00000001u) +#define GPIO_WAKE_MASK (0x00000001u) +#define GPIO_WAKE_BIT (0) +#define GPIO_WAKE_BITS (1) + +#define WAKE_CORE *((volatile uint32_t *)0x40000024u) +#define WAKE_CORE_REG *((volatile uint32_t *)0x40000024u) +#define WAKE_CORE_ADDR (0x40000024u) +#define WAKE_CORE_RESET (0x00000000u) +/* WAKE_CORE_FIELD field */ +#define WAKE_CORE_FIELD (0x00000020u) +#define WAKE_CORE_FIELD_MASK (0x00000020u) +#define WAKE_CORE_FIELD_BIT (5) +#define WAKE_CORE_FIELD_BITS (1) + +#define PWRUP_EVENT *((volatile uint32_t *)0x40000028u) +#define PWRUP_EVENT_REG *((volatile uint32_t *)0x40000028u) +#define PWRUP_EVENT_ADDR (0x40000028u) +#define PWRUP_EVENT_RESET (0x00000000u) +/* PWRUP_CSYSPWRUPREQ field */ +#define PWRUP_CSYSPWRUPREQ (0x00000200u) +#define PWRUP_CSYSPWRUPREQ_MASK (0x00000200u) +#define PWRUP_CSYSPWRUPREQ_BIT (9) +#define PWRUP_CSYSPWRUPREQ_BITS (1) +/* PWRUP_CDBGPWRUPREQ field */ +#define PWRUP_CDBGPWRUPREQ (0x00000100u) +#define PWRUP_CDBGPWRUPREQ_MASK (0x00000100u) +#define PWRUP_CDBGPWRUPREQ_BIT (8) +#define PWRUP_CDBGPWRUPREQ_BITS (1) +/* PWRUP_WAKECORE field */ +#define PWRUP_WAKECORE (0x00000080u) +#define PWRUP_WAKECORE_MASK (0x00000080u) +#define PWRUP_WAKECORE_BIT (7) +#define PWRUP_WAKECORE_BITS (1) +/* PWRUP_SLEEPTMRWRAP field */ +#define PWRUP_SLEEPTMRWRAP (0x00000040u) +#define PWRUP_SLEEPTMRWRAP_MASK (0x00000040u) +#define PWRUP_SLEEPTMRWRAP_BIT (6) +#define PWRUP_SLEEPTMRWRAP_BITS (1) +/* PWRUP_SLEEPTMRCOMPB field */ +#define PWRUP_SLEEPTMRCOMPB (0x00000020u) +#define PWRUP_SLEEPTMRCOMPB_MASK (0x00000020u) +#define PWRUP_SLEEPTMRCOMPB_BIT (5) +#define PWRUP_SLEEPTMRCOMPB_BITS (1) +/* PWRUP_SLEEPTMRCOMPA field */ +#define PWRUP_SLEEPTMRCOMPA (0x00000010u) +#define PWRUP_SLEEPTMRCOMPA_MASK (0x00000010u) +#define PWRUP_SLEEPTMRCOMPA_BIT (4) +#define PWRUP_SLEEPTMRCOMPA_BITS (1) +/* PWRUP_IRQD field */ +#define PWRUP_IRQD (0x00000008u) +#define PWRUP_IRQD_MASK (0x00000008u) +#define PWRUP_IRQD_BIT (3) +#define PWRUP_IRQD_BITS (1) +/* PWRUP_SC2 field */ +#define PWRUP_SC2 (0x00000004u) +#define PWRUP_SC2_MASK (0x00000004u) +#define PWRUP_SC2_BIT (2) +#define PWRUP_SC2_BITS (1) +/* PWRUP_SC1 field */ +#define PWRUP_SC1 (0x00000002u) +#define PWRUP_SC1_MASK (0x00000002u) +#define PWRUP_SC1_BIT (1) +#define PWRUP_SC1_BITS (1) +/* PWRUP_GPIO field */ +#define PWRUP_GPIO (0x00000001u) +#define PWRUP_GPIO_MASK (0x00000001u) +#define PWRUP_GPIO_BIT (0) +#define PWRUP_GPIO_BITS (1) + +#define RESET_EVENT *((volatile uint32_t *)0x4000002Cu) +#define RESET_EVENT_REG *((volatile uint32_t *)0x4000002Cu) +#define RESET_EVENT_ADDR (0x4000002Cu) +#define RESET_EVENT_RESET (0x00000001u) +/* RESET_CPULOCKUP field */ +#define RESET_CPULOCKUP (0x00000080u) +#define RESET_CPULOCKUP_MASK (0x00000080u) +#define RESET_CPULOCKUP_BIT (7) +#define RESET_CPULOCKUP_BITS (1) +/* RESET_OPTBYTEFAIL field */ +#define RESET_OPTBYTEFAIL (0x00000040u) +#define RESET_OPTBYTEFAIL_MASK (0x00000040u) +#define RESET_OPTBYTEFAIL_BIT (6) +#define RESET_OPTBYTEFAIL_BITS (1) +/* RESET_DSLEEP field */ +#define RESET_DSLEEP (0x00000020u) +#define RESET_DSLEEP_MASK (0x00000020u) +#define RESET_DSLEEP_BIT (5) +#define RESET_DSLEEP_BITS (1) +/* RESET_SW field */ +#define RESET_SW (0x00000010u) +#define RESET_SW_MASK (0x00000010u) +#define RESET_SW_BIT (4) +#define RESET_SW_BITS (1) +/* RESET_WDOG field */ +#define RESET_WDOG (0x00000008u) +#define RESET_WDOG_MASK (0x00000008u) +#define RESET_WDOG_BIT (3) +#define RESET_WDOG_BITS (1) +/* RESET_NRESET field */ +#define RESET_NRESET (0x00000004u) +#define RESET_NRESET_MASK (0x00000004u) +#define RESET_NRESET_BIT (2) +#define RESET_NRESET_BITS (1) +/* RESET_PWRLV field */ +#define RESET_PWRLV (0x00000002u) +#define RESET_PWRLV_MASK (0x00000002u) +#define RESET_PWRLV_BIT (1) +#define RESET_PWRLV_BITS (1) +/* RESET_PWRHV field */ +#define RESET_PWRHV (0x00000001u) +#define RESET_PWRHV_MASK (0x00000001u) +#define RESET_PWRHV_BIT (0) +#define RESET_PWRHV_BITS (1) + +#define DBG_MBOX *((volatile uint32_t *)0x40000030u) +#define DBG_MBOX_REG *((volatile uint32_t *)0x40000030u) +#define DBG_MBOX_ADDR (0x40000030u) +#define DBG_MBOX_RESET (0x00000000u) +/* DBG_MBOX field */ +#define DBG_MBOX_DBG_MBOX (0x0000FFFFu) +#define DBG_MBOX_DBG_MBOX_MASK (0x0000FFFFu) +#define DBG_MBOX_DBG_MBOX_BIT (0) +#define DBG_MBOX_DBG_MBOX_BITS (16) + +#define CPWRUPREQ_STATUS *((volatile uint32_t *)0x40000034u) +#define CPWRUPREQ_STATUS_REG *((volatile uint32_t *)0x40000034u) +#define CPWRUPREQ_STATUS_ADDR (0x40000034u) +#define CPWRUPREQ_STATUS_RESET (0x00000000u) +/* CPWRUPREQ field */ +#define CPWRUPREQ_STATUS_CPWRUPREQ (0x00000001u) +#define CPWRUPREQ_STATUS_CPWRUPREQ_MASK (0x00000001u) +#define CPWRUPREQ_STATUS_CPWRUPREQ_BIT (0) +#define CPWRUPREQ_STATUS_CPWRUPREQ_BITS (1) + +#define CSYSPWRUPREQ_STATUS *((volatile uint32_t *)0x40000038u) +#define CSYSPWRUPREQ_STATUS_REG *((volatile uint32_t *)0x40000038u) +#define CSYSPWRUPREQ_STATUS_ADDR (0x40000038u) +#define CSYSPWRUPREQ_STATUS_RESET (0x00000000u) +/* CSYSPWRUPREQ field */ +#define CSYSPWRUPREQ_STATUS_CSYSPWRUPREQ (0x00000001u) +#define CSYSPWRUPREQ_STATUS_CSYSPWRUPREQ_MASK (0x00000001u) +#define CSYSPWRUPREQ_STATUS_CSYSPWRUPREQ_BIT (0) +#define CSYSPWRUPREQ_STATUS_CSYSPWRUPREQ_BITS (1) + +#define CSYSPWRUPACK_STATUS *((volatile uint32_t *)0x4000003Cu) +#define CSYSPWRUPACK_STATUS_REG *((volatile uint32_t *)0x4000003Cu) +#define CSYSPWRUPACK_STATUS_ADDR (0x4000003Cu) +#define CSYSPWRUPACK_STATUS_RESET (0x00000000u) +/* CSYSPWRUPACK field */ +#define CSYSPWRUPACK_STATUS_CSYSPWRUPACK (0x00000001u) +#define CSYSPWRUPACK_STATUS_CSYSPWRUPACK_MASK (0x00000001u) +#define CSYSPWRUPACK_STATUS_CSYSPWRUPACK_BIT (0) +#define CSYSPWRUPACK_STATUS_CSYSPWRUPACK_BITS (1) + +#define CSYSPWRUPACK_INHIBIT *((volatile uint32_t *)0x40000040u) +#define CSYSPWRUPACK_INHIBIT_REG *((volatile uint32_t *)0x40000040u) +#define CSYSPWRUPACK_INHIBIT_ADDR (0x40000040u) +#define CSYSPWRUPACK_INHIBIT_RESET (0x00000000u) +/* CSYSPWRUPACK_INHIBIT field */ +#define CSYSPWRUPACK_INHIBIT_CSYSPWRUPACK_INHIBIT (0x00000001u) +#define CSYSPWRUPACK_INHIBIT_CSYSPWRUPACK_INHIBIT_MASK (0x00000001u) +#define CSYSPWRUPACK_INHIBIT_CSYSPWRUPACK_INHIBIT_BIT (0) +#define CSYSPWRUPACK_INHIBIT_CSYSPWRUPACK_INHIBIT_BITS (1) + +#define OPT_ERR_MAINTAIN_WAKE *((volatile uint32_t *)0x40000044u) +#define OPT_ERR_MAINTAIN_WAKE_REG *((volatile uint32_t *)0x40000044u) +#define OPT_ERR_MAINTAIN_WAKE_ADDR (0x40000044u) +#define OPT_ERR_MAINTAIN_WAKE_RESET (0x00000000u) +/* OPT_ERR_MAINTAIN_WAKE field */ +#define OPT_ERR_MAINTAIN_WAKE_OPT_ERR_MAINTAIN_WAKE (0x00000001u) +#define OPT_ERR_MAINTAIN_WAKE_OPT_ERR_MAINTAIN_WAKE_MASK (0x00000001u) +#define OPT_ERR_MAINTAIN_WAKE_OPT_ERR_MAINTAIN_WAKE_BIT (0) +#define OPT_ERR_MAINTAIN_WAKE_OPT_ERR_MAINTAIN_WAKE_BITS (1) + +/* BASEBAND block */ +#define DATA_BASEBAND_BASE (0x40001000u) +#define DATA_BASEBAND_END (0x40001114u) +#define DATA_BASEBAND_SIZE (DATA_BASEBAND_END - DATA_BASEBAND_BASE + 1) + +#define MOD_CAL_CTRL *((volatile uint32_t *)0x40001000u) +#define MOD_CAL_CTRL_REG *((volatile uint32_t *)0x40001000u) +#define MOD_CAL_CTRL_ADDR (0x40001000u) +#define MOD_CAL_CTRL_RESET (0x00000000u) +/* MOD_CAL_GO field */ +#define MOD_CAL_CTRL_MOD_CAL_GO (0x00008000u) +#define MOD_CAL_CTRL_MOD_CAL_GO_MASK (0x00008000u) +#define MOD_CAL_CTRL_MOD_CAL_GO_BIT (15) +#define MOD_CAL_CTRL_MOD_CAL_GO_BITS (1) +/* MOD_CAL_DONE field */ +#define MOD_CAL_CTRL_MOD_CAL_DONE (0x00000010u) +#define MOD_CAL_CTRL_MOD_CAL_DONE_MASK (0x00000010u) +#define MOD_CAL_CTRL_MOD_CAL_DONE_BIT (4) +#define MOD_CAL_CTRL_MOD_CAL_DONE_BITS (1) +/* MOD_CAL_CYCLES field */ +#define MOD_CAL_CTRL_MOD_CAL_CYCLES (0x00000003u) +#define MOD_CAL_CTRL_MOD_CAL_CYCLES_MASK (0x00000003u) +#define MOD_CAL_CTRL_MOD_CAL_CYCLES_BIT (0) +#define MOD_CAL_CTRL_MOD_CAL_CYCLES_BITS (2) + +#define MOD_CAL_COUNT_H *((volatile uint32_t *)0x40001004u) +#define MOD_CAL_COUNT_H_REG *((volatile uint32_t *)0x40001004u) +#define MOD_CAL_COUNT_H_ADDR (0x40001004u) +#define MOD_CAL_COUNT_H_RESET (0x00000000u) +/* MOD_CAL_COUNT_H field */ +#define MOD_CAL_COUNT_H_MOD_CAL_COUNT_H (0x000000FFu) +#define MOD_CAL_COUNT_H_MOD_CAL_COUNT_H_MASK (0x000000FFu) +#define MOD_CAL_COUNT_H_MOD_CAL_COUNT_H_BIT (0) +#define MOD_CAL_COUNT_H_MOD_CAL_COUNT_H_BITS (8) + +#define MOD_CAL_COUNT_L *((volatile uint32_t *)0x40001008u) +#define MOD_CAL_COUNT_L_REG *((volatile uint32_t *)0x40001008u) +#define MOD_CAL_COUNT_L_ADDR (0x40001008u) +#define MOD_CAL_COUNT_L_RESET (0x00000000u) +/* MOD_CAL_COUNT_L field */ +#define MOD_CAL_COUNT_L_MOD_CAL_COUNT_L (0x0000FFFFu) +#define MOD_CAL_COUNT_L_MOD_CAL_COUNT_L_MASK (0x0000FFFFu) +#define MOD_CAL_COUNT_L_MOD_CAL_COUNT_L_BIT (0) +#define MOD_CAL_COUNT_L_MOD_CAL_COUNT_L_BITS (16) + +#define RSSI_ROLLING *((volatile uint32_t *)0x4000100Cu) +#define RSSI_ROLLING_REG *((volatile uint32_t *)0x4000100Cu) +#define RSSI_ROLLING_ADDR (0x4000100Cu) +#define RSSI_ROLLING_RESET (0x00000000u) +/* RSSI_ROLLING field */ +#define RSSI_ROLLING_RSSI_ROLLING (0x00003FFFu) +#define RSSI_ROLLING_RSSI_ROLLING_MASK (0x00003FFFu) +#define RSSI_ROLLING_RSSI_ROLLING_BIT (0) +#define RSSI_ROLLING_RSSI_ROLLING_BITS (14) + +#define RSSI_PKT *((volatile uint32_t *)0x40001010u) +#define RSSI_PKT_REG *((volatile uint32_t *)0x40001010u) +#define RSSI_PKT_ADDR (0x40001010u) +#define RSSI_PKT_RESET (0x00000000u) +/* RSSI_PKT field */ +#define RSSI_PKT_RSSI_PKT (0x000000FFu) +#define RSSI_PKT_RSSI_PKT_MASK (0x000000FFu) +#define RSSI_PKT_RSSI_PKT_BIT (0) +#define RSSI_PKT_RSSI_PKT_BITS (8) + +#define RX_ADC *((volatile uint32_t *)0x40001014u) +#define RX_ADC_REG *((volatile uint32_t *)0x40001014u) +#define RX_ADC_ADDR (0x40001014u) +#define RX_ADC_RESET (0x00000024u) +/* RX_ADC field */ +#define RX_ADC_RX_ADC (0x0000007Fu) +#define RX_ADC_RX_ADC_MASK (0x0000007Fu) +#define RX_ADC_RX_ADC_BIT (0) +#define RX_ADC_RX_ADC_BITS (7) + +#define DEBUG_BB_MODE *((volatile uint32_t *)0x40001018u) +#define DEBUG_BB_MODE_REG *((volatile uint32_t *)0x40001018u) +#define DEBUG_BB_MODE_ADDR (0x40001018u) +#define DEBUG_BB_MODE_RESET (0x00000000u) +/* DEBUG_BB_MODE_EN field */ +#define DEBUG_BB_MODE_DEBUG_BB_MODE_EN (0x00008000u) +#define DEBUG_BB_MODE_DEBUG_BB_MODE_EN_MASK (0x00008000u) +#define DEBUG_BB_MODE_DEBUG_BB_MODE_EN_BIT (15) +#define DEBUG_BB_MODE_DEBUG_BB_MODE_EN_BITS (1) +/* DEBUG_BB_MODE field */ +#define DEBUG_BB_MODE_DEBUG_BB_MODE (0x00000003u) +#define DEBUG_BB_MODE_DEBUG_BB_MODE_MASK (0x00000003u) +#define DEBUG_BB_MODE_DEBUG_BB_MODE_BIT (0) +#define DEBUG_BB_MODE_DEBUG_BB_MODE_BITS (2) + +#define BB_DEBUG *((volatile uint32_t *)0x4000101Cu) +#define BB_DEBUG_REG *((volatile uint32_t *)0x4000101Cu) +#define BB_DEBUG_ADDR (0x4000101Cu) +#define BB_DEBUG_RESET (0x00000002u) +/* SYNC_REG_EN field */ +#define BB_DEBUG_SYNC_REG_EN (0x00008000u) +#define BB_DEBUG_SYNC_REG_EN_MASK (0x00008000u) +#define BB_DEBUG_SYNC_REG_EN_BIT (15) +#define BB_DEBUG_SYNC_REG_EN_BITS (1) +/* DEBUG_MUX_ADDR field */ +#define BB_DEBUG_DEBUG_MUX_ADDR (0x000000F0u) +#define BB_DEBUG_DEBUG_MUX_ADDR_MASK (0x000000F0u) +#define BB_DEBUG_DEBUG_MUX_ADDR_BIT (4) +#define BB_DEBUG_DEBUG_MUX_ADDR_BITS (4) +/* BB_DEBUG_SEL field */ +#define BB_DEBUG_BB_DEBUG_SEL (0x00000003u) +#define BB_DEBUG_BB_DEBUG_SEL_MASK (0x00000003u) +#define BB_DEBUG_BB_DEBUG_SEL_BIT (0) +#define BB_DEBUG_BB_DEBUG_SEL_BITS (2) + +#define BB_DEBUG_VIEW *((volatile uint32_t *)0x40001020u) +#define BB_DEBUG_VIEW_REG *((volatile uint32_t *)0x40001020u) +#define BB_DEBUG_VIEW_ADDR (0x40001020u) +#define BB_DEBUG_VIEW_RESET (0x00000000u) +/* BB_DEBUG_VIEW field */ +#define BB_DEBUG_VIEW_BB_DEBUG_VIEW (0x0000FFFFu) +#define BB_DEBUG_VIEW_BB_DEBUG_VIEW_MASK (0x0000FFFFu) +#define BB_DEBUG_VIEW_BB_DEBUG_VIEW_BIT (0) +#define BB_DEBUG_VIEW_BB_DEBUG_VIEW_BITS (16) + +#define IF_FREQ *((volatile uint32_t *)0x40001024u) +#define IF_FREQ_REG *((volatile uint32_t *)0x40001024u) +#define IF_FREQ_ADDR (0x40001024u) +#define IF_FREQ_RESET (0x00000155u) +/* TIMING_CORR_EN field */ +#define IF_FREQ_TIMING_CORR_EN (0x00008000u) +#define IF_FREQ_TIMING_CORR_EN_MASK (0x00008000u) +#define IF_FREQ_TIMING_CORR_EN_BIT (15) +#define IF_FREQ_TIMING_CORR_EN_BITS (1) +/* IF_FREQ field */ +#define IF_FREQ_IF_FREQ (0x000001FFu) +#define IF_FREQ_IF_FREQ_MASK (0x000001FFu) +#define IF_FREQ_IF_FREQ_BIT (0) +#define IF_FREQ_IF_FREQ_BITS (9) + +#define MOD_EN *((volatile uint32_t *)0x40001028u) +#define MOD_EN_REG *((volatile uint32_t *)0x40001028u) +#define MOD_EN_ADDR (0x40001028u) +#define MOD_EN_RESET (0x00000001u) +/* MOD_EN field */ +#define MOD_EN_MOD_EN (0x00000001u) +#define MOD_EN_MOD_EN_MASK (0x00000001u) +#define MOD_EN_MOD_EN_BIT (0) +#define MOD_EN_MOD_EN_BITS (1) + +#define PRESCALE_CTRL *((volatile uint32_t *)0x4000102Cu) +#define PRESCALE_CTRL_REG *((volatile uint32_t *)0x4000102Cu) +#define PRESCALE_CTRL_ADDR (0x4000102Cu) +#define PRESCALE_CTRL_RESET (0x00000000u) +/* PRESCALE_SET field */ +#define PRESCALE_CTRL_PRESCALE_SET (0x00008000u) +#define PRESCALE_CTRL_PRESCALE_SET_MASK (0x00008000u) +#define PRESCALE_CTRL_PRESCALE_SET_BIT (15) +#define PRESCALE_CTRL_PRESCALE_SET_BITS (1) +/* PRESCALE_VAL field */ +#define PRESCALE_CTRL_PRESCALE_VAL (0x00000007u) +#define PRESCALE_CTRL_PRESCALE_VAL_MASK (0x00000007u) +#define PRESCALE_CTRL_PRESCALE_VAL_BIT (0) +#define PRESCALE_CTRL_PRESCALE_VAL_BITS (3) + +#define ADC_BYPASS_EN *((volatile uint32_t *)0x40001030u) +#define ADC_BYPASS_EN_REG *((volatile uint32_t *)0x40001030u) +#define ADC_BYPASS_EN_ADDR (0x40001030u) +#define ADC_BYPASS_EN_RESET (0x00000000u) +/* ADC_BYPASS_EN field */ +#define ADC_BYPASS_EN_ADC_BYPASS_EN (0x00000001u) +#define ADC_BYPASS_EN_ADC_BYPASS_EN_MASK (0x00000001u) +#define ADC_BYPASS_EN_ADC_BYPASS_EN_BIT (0) +#define ADC_BYPASS_EN_ADC_BYPASS_EN_BITS (1) + +#define FIXED_CODE_EN *((volatile uint32_t *)0x40001034u) +#define FIXED_CODE_EN_REG *((volatile uint32_t *)0x40001034u) +#define FIXED_CODE_EN_ADDR (0x40001034u) +#define FIXED_CODE_EN_RESET (0x00000000u) +/* FIXED_CODE_EN field */ +#define FIXED_CODE_EN_FIXED_CODE_EN (0x00000001u) +#define FIXED_CODE_EN_FIXED_CODE_EN_MASK (0x00000001u) +#define FIXED_CODE_EN_FIXED_CODE_EN_BIT (0) +#define FIXED_CODE_EN_FIXED_CODE_EN_BITS (1) + +#define FIXED_CODE_H *((volatile uint32_t *)0x40001038u) +#define FIXED_CODE_H_REG *((volatile uint32_t *)0x40001038u) +#define FIXED_CODE_H_ADDR (0x40001038u) +#define FIXED_CODE_H_RESET (0x00000000u) +/* FIXED_CODE_H field */ +#define FIXED_CODE_H_FIXED_CODE_H (0x0000FFFFu) +#define FIXED_CODE_H_FIXED_CODE_H_MASK (0x0000FFFFu) +#define FIXED_CODE_H_FIXED_CODE_H_BIT (0) +#define FIXED_CODE_H_FIXED_CODE_H_BITS (16) + +#define FIXED_CODE_L *((volatile uint32_t *)0x4000103Cu) +#define FIXED_CODE_L_REG *((volatile uint32_t *)0x4000103Cu) +#define FIXED_CODE_L_ADDR (0x4000103Cu) +#define FIXED_CODE_L_RESET (0x00000000u) +/* FIXED_CODE_L field */ +#define FIXED_CODE_L_FIXED_CODE_L (0x0000FFFFu) +#define FIXED_CODE_L_FIXED_CODE_L_MASK (0x0000FFFFu) +#define FIXED_CODE_L_FIXED_CODE_L_BIT (0) +#define FIXED_CODE_L_FIXED_CODE_L_BITS (16) + +#define FIXED_CODE_L_SHADOW *((volatile uint32_t *)0x40001040u) +#define FIXED_CODE_L_SHADOW_REG *((volatile uint32_t *)0x40001040u) +#define FIXED_CODE_L_SHADOW_ADDR (0x40001040u) +#define FIXED_CODE_L_SHADOW_RESET (0x00000000u) +/* FIXED_CODE_L_SHADOW field */ +#define FIXED_CODE_L_SHADOW_FIXED_CODE_L_SHADOW (0x0000FFFFu) +#define FIXED_CODE_L_SHADOW_FIXED_CODE_L_SHADOW_MASK (0x0000FFFFu) +#define FIXED_CODE_L_SHADOW_FIXED_CODE_L_SHADOW_BIT (0) +#define FIXED_CODE_L_SHADOW_FIXED_CODE_L_SHADOW_BITS (16) + +#define RX_GAIN_CTRL *((volatile uint32_t *)0x40001044u) +#define RX_GAIN_CTRL_REG *((volatile uint32_t *)0x40001044u) +#define RX_GAIN_CTRL_ADDR (0x40001044u) +#define RX_GAIN_CTRL_RESET (0x00000000u) +/* RX_GAIN_MUX field */ +#define RX_GAIN_CTRL_RX_GAIN_MUX (0x00008000u) +#define RX_GAIN_CTRL_RX_GAIN_MUX_MASK (0x00008000u) +#define RX_GAIN_CTRL_RX_GAIN_MUX_BIT (15) +#define RX_GAIN_CTRL_RX_GAIN_MUX_BITS (1) +/* RX_RF_GAIN_TEST field */ +#define RX_GAIN_CTRL_RX_RF_GAIN_TEST (0x00000080u) +#define RX_GAIN_CTRL_RX_RF_GAIN_TEST_MASK (0x00000080u) +#define RX_GAIN_CTRL_RX_RF_GAIN_TEST_BIT (7) +#define RX_GAIN_CTRL_RX_RF_GAIN_TEST_BITS (1) +/* RX_MIXER_GAIN_TEST field */ +#define RX_GAIN_CTRL_RX_MIXER_GAIN_TEST (0x00000040u) +#define RX_GAIN_CTRL_RX_MIXER_GAIN_TEST_MASK (0x00000040u) +#define RX_GAIN_CTRL_RX_MIXER_GAIN_TEST_BIT (6) +#define RX_GAIN_CTRL_RX_MIXER_GAIN_TEST_BITS (1) +/* RX_FILTER_GAIN_TEST field */ +#define RX_GAIN_CTRL_RX_FILTER_GAIN_TEST (0x00000030u) +#define RX_GAIN_CTRL_RX_FILTER_GAIN_TEST_MASK (0x00000030u) +#define RX_GAIN_CTRL_RX_FILTER_GAIN_TEST_BIT (4) +#define RX_GAIN_CTRL_RX_FILTER_GAIN_TEST_BITS (2) +/* RX_IF_GAIN_TEST field */ +#define RX_GAIN_CTRL_RX_IF_GAIN_TEST (0x0000000Fu) +#define RX_GAIN_CTRL_RX_IF_GAIN_TEST_MASK (0x0000000Fu) +#define RX_GAIN_CTRL_RX_IF_GAIN_TEST_BIT (0) +#define RX_GAIN_CTRL_RX_IF_GAIN_TEST_BITS (4) + +#define PD_DITHER_EN *((volatile uint32_t *)0x40001048u) +#define PD_DITHER_EN_REG *((volatile uint32_t *)0x40001048u) +#define PD_DITHER_EN_ADDR (0x40001048u) +#define PD_DITHER_EN_RESET (0x00000001u) +/* PD_DITHER_EN field */ +#define PD_DITHER_EN_PD_DITHER_EN (0x00000001u) +#define PD_DITHER_EN_PD_DITHER_EN_MASK (0x00000001u) +#define PD_DITHER_EN_PD_DITHER_EN_BIT (0) +#define PD_DITHER_EN_PD_DITHER_EN_BITS (1) + +#define RX_ERR_THRESH *((volatile uint32_t *)0x4000104Cu) +#define RX_ERR_THRESH_REG *((volatile uint32_t *)0x4000104Cu) +#define RX_ERR_THRESH_ADDR (0x4000104Cu) +#define RX_ERR_THRESH_RESET (0x00004608u) +/* LPF_RX_ERR_COEFF field */ +#define RX_ERR_THRESH_LPF_RX_ERR_COEFF (0x0000E000u) +#define RX_ERR_THRESH_LPF_RX_ERR_COEFF_MASK (0x0000E000u) +#define RX_ERR_THRESH_LPF_RX_ERR_COEFF_BIT (13) +#define RX_ERR_THRESH_LPF_RX_ERR_COEFF_BITS (3) +/* LPF_RX_ERR_THRESH field */ +#define RX_ERR_THRESH_LPF_RX_ERR_THRESH (0x00001F00u) +#define RX_ERR_THRESH_LPF_RX_ERR_THRESH_MASK (0x00001F00u) +#define RX_ERR_THRESH_LPF_RX_ERR_THRESH_BIT (8) +#define RX_ERR_THRESH_LPF_RX_ERR_THRESH_BITS (5) +/* RX_ERR_THRESH field */ +#define RX_ERR_THRESH_RX_ERR_THRESH (0x0000001Fu) +#define RX_ERR_THRESH_RX_ERR_THRESH_MASK (0x0000001Fu) +#define RX_ERR_THRESH_RX_ERR_THRESH_BIT (0) +#define RX_ERR_THRESH_RX_ERR_THRESH_BITS (5) + +#define CARRIER_THRESH *((volatile uint32_t *)0x40001050u) +#define CARRIER_THRESH_REG *((volatile uint32_t *)0x40001050u) +#define CARRIER_THRESH_ADDR (0x40001050u) +#define CARRIER_THRESH_RESET (0x00002332u) +/* CARRIER_SPIKE_THRESH field */ +#define CARRIER_THRESH_CARRIER_SPIKE_THRESH (0x0000FF00u) +#define CARRIER_THRESH_CARRIER_SPIKE_THRESH_MASK (0x0000FF00u) +#define CARRIER_THRESH_CARRIER_SPIKE_THRESH_BIT (8) +#define CARRIER_THRESH_CARRIER_SPIKE_THRESH_BITS (8) +/* CARRIER_THRESH field */ +#define CARRIER_THRESH_CARRIER_THRESH (0x000000FFu) +#define CARRIER_THRESH_CARRIER_THRESH_MASK (0x000000FFu) +#define CARRIER_THRESH_CARRIER_THRESH_BIT (0) +#define CARRIER_THRESH_CARRIER_THRESH_BITS (8) + +#define RSSI_THRESH *((volatile uint32_t *)0x40001054u) +#define RSSI_THRESH_REG *((volatile uint32_t *)0x40001054u) +#define RSSI_THRESH_ADDR (0x40001054u) +#define RSSI_THRESH_RESET (0x00000100u) +/* RSSI_THRESH field */ +#define RSSI_THRESH_RSSI_THRESH (0x0000FFFFu) +#define RSSI_THRESH_RSSI_THRESH_MASK (0x0000FFFFu) +#define RSSI_THRESH_RSSI_THRESH_BIT (0) +#define RSSI_THRESH_RSSI_THRESH_BITS (16) + +#define SYNTH_START *((volatile uint32_t *)0x40001058u) +#define SYNTH_START_REG *((volatile uint32_t *)0x40001058u) +#define SYNTH_START_ADDR (0x40001058u) +#define SYNTH_START_RESET (0x00006464u) +/* SYNTH_WARM_START field */ +#define SYNTH_START_SYNTH_WARM_START (0x0000FF00u) +#define SYNTH_START_SYNTH_WARM_START_MASK (0x0000FF00u) +#define SYNTH_START_SYNTH_WARM_START_BIT (8) +#define SYNTH_START_SYNTH_WARM_START_BITS (8) +/* SYNTH_COLD_START field */ +#define SYNTH_START_SYNTH_COLD_START (0x000000FFu) +#define SYNTH_START_SYNTH_COLD_START_MASK (0x000000FFu) +#define SYNTH_START_SYNTH_COLD_START_BIT (0) +#define SYNTH_START_SYNTH_COLD_START_BITS (8) + +#define IN_LOCK_EN *((volatile uint32_t *)0x4000105Cu) +#define IN_LOCK_EN_REG *((volatile uint32_t *)0x4000105Cu) +#define IN_LOCK_EN_ADDR (0x4000105Cu) +#define IN_LOCK_EN_RESET (0x00000001u) +/* IN_LOCK_EN field */ +#define IN_LOCK_EN_IN_LOCK_EN (0x00000001u) +#define IN_LOCK_EN_IN_LOCK_EN_MASK (0x00000001u) +#define IN_LOCK_EN_IN_LOCK_EN_BIT (0) +#define IN_LOCK_EN_IN_LOCK_EN_BITS (1) + +#define DITHER_AMPLITUDE *((volatile uint32_t *)0x40001060u) +#define DITHER_AMPLITUDE_REG *((volatile uint32_t *)0x40001060u) +#define DITHER_AMPLITUDE_ADDR (0x40001060u) +#define DITHER_AMPLITUDE_RESET (0x0000003Fu) +/* DITHER_AMP field */ +#define DITHER_AMPLITUDE_DITHER_AMP (0x0000003Fu) +#define DITHER_AMPLITUDE_DITHER_AMP_MASK (0x0000003Fu) +#define DITHER_AMPLITUDE_DITHER_AMP_BIT (0) +#define DITHER_AMPLITUDE_DITHER_AMP_BITS (6) + +#define TX_STEP_TIME *((volatile uint32_t *)0x40001064u) +#define TX_STEP_TIME_REG *((volatile uint32_t *)0x40001064u) +#define TX_STEP_TIME_ADDR (0x40001064u) +#define TX_STEP_TIME_RESET (0x00000000u) +/* TX_STEP_TIME field */ +#define TX_STEP_TIME_TX_STEP_TIME (0x000000FFu) +#define TX_STEP_TIME_TX_STEP_TIME_MASK (0x000000FFu) +#define TX_STEP_TIME_TX_STEP_TIME_BIT (0) +#define TX_STEP_TIME_TX_STEP_TIME_BITS (8) + +#define GAIN_THRESH_MAX *((volatile uint32_t *)0x40001068u) +#define GAIN_THRESH_MAX_REG *((volatile uint32_t *)0x40001068u) +#define GAIN_THRESH_MAX_ADDR (0x40001068u) +#define GAIN_THRESH_MAX_RESET (0x00000060u) +/* GAIN_THRESH_MAX field */ +#define GAIN_THRESH_MAX_GAIN_THRESH_MAX (0x000000FFu) +#define GAIN_THRESH_MAX_GAIN_THRESH_MAX_MASK (0x000000FFu) +#define GAIN_THRESH_MAX_GAIN_THRESH_MAX_BIT (0) +#define GAIN_THRESH_MAX_GAIN_THRESH_MAX_BITS (8) + +#define GAIN_THRESH_MID *((volatile uint32_t *)0x4000106Cu) +#define GAIN_THRESH_MID_REG *((volatile uint32_t *)0x4000106Cu) +#define GAIN_THRESH_MID_ADDR (0x4000106Cu) +#define GAIN_THRESH_MID_RESET (0x00000030u) +/* GAIN_THRESH_MID field */ +#define GAIN_THRESH_MID_GAIN_THRESH_MID (0x000000FFu) +#define GAIN_THRESH_MID_GAIN_THRESH_MID_MASK (0x000000FFu) +#define GAIN_THRESH_MID_GAIN_THRESH_MID_BIT (0) +#define GAIN_THRESH_MID_GAIN_THRESH_MID_BITS (8) + +#define GAIN_THRESH_MIN *((volatile uint32_t *)0x40001070u) +#define GAIN_THRESH_MIN_REG *((volatile uint32_t *)0x40001070u) +#define GAIN_THRESH_MIN_ADDR (0x40001070u) +#define GAIN_THRESH_MIN_RESET (0x00000018u) +/* GAIN_THRESH_MIN field */ +#define GAIN_THRESH_MIN_GAIN_THRESH_MIN (0x000000FFu) +#define GAIN_THRESH_MIN_GAIN_THRESH_MIN_MASK (0x000000FFu) +#define GAIN_THRESH_MIN_GAIN_THRESH_MIN_BIT (0) +#define GAIN_THRESH_MIN_GAIN_THRESH_MIN_BITS (8) + +#define GAIN_SETTING_0 *((volatile uint32_t *)0x40001074u) +#define GAIN_SETTING_0_REG *((volatile uint32_t *)0x40001074u) +#define GAIN_SETTING_0_ADDR (0x40001074u) +#define GAIN_SETTING_0_RESET (0x00000000u) +/* RX_MIXER_GAIN_0 field */ +#define GAIN_SETTING_0_RX_MIXER_GAIN_0 (0x00000040u) +#define GAIN_SETTING_0_RX_MIXER_GAIN_0_MASK (0x00000040u) +#define GAIN_SETTING_0_RX_MIXER_GAIN_0_BIT (6) +#define GAIN_SETTING_0_RX_MIXER_GAIN_0_BITS (1) +/* RX_FILTER_GAIN_0 field */ +#define GAIN_SETTING_0_RX_FILTER_GAIN_0 (0x00000030u) +#define GAIN_SETTING_0_RX_FILTER_GAIN_0_MASK (0x00000030u) +#define GAIN_SETTING_0_RX_FILTER_GAIN_0_BIT (4) +#define GAIN_SETTING_0_RX_FILTER_GAIN_0_BITS (2) +/* RX_IF_GAIN_0 field */ +#define GAIN_SETTING_0_RX_IF_GAIN_0 (0x0000000Fu) +#define GAIN_SETTING_0_RX_IF_GAIN_0_MASK (0x0000000Fu) +#define GAIN_SETTING_0_RX_IF_GAIN_0_BIT (0) +#define GAIN_SETTING_0_RX_IF_GAIN_0_BITS (4) + +#define GAIN_SETTING_1 *((volatile uint32_t *)0x40001078u) +#define GAIN_SETTING_1_REG *((volatile uint32_t *)0x40001078u) +#define GAIN_SETTING_1_ADDR (0x40001078u) +#define GAIN_SETTING_1_RESET (0x00000010u) +/* RX_MIXER_GAIN_1 field */ +#define GAIN_SETTING_1_RX_MIXER_GAIN_1 (0x00000040u) +#define GAIN_SETTING_1_RX_MIXER_GAIN_1_MASK (0x00000040u) +#define GAIN_SETTING_1_RX_MIXER_GAIN_1_BIT (6) +#define GAIN_SETTING_1_RX_MIXER_GAIN_1_BITS (1) +/* RX_FILTER_GAIN_1 field */ +#define GAIN_SETTING_1_RX_FILTER_GAIN_1 (0x00000030u) +#define GAIN_SETTING_1_RX_FILTER_GAIN_1_MASK (0x00000030u) +#define GAIN_SETTING_1_RX_FILTER_GAIN_1_BIT (4) +#define GAIN_SETTING_1_RX_FILTER_GAIN_1_BITS (2) +/* RX_IF_GAIN_1 field */ +#define GAIN_SETTING_1_RX_IF_GAIN_1 (0x0000000Fu) +#define GAIN_SETTING_1_RX_IF_GAIN_1_MASK (0x0000000Fu) +#define GAIN_SETTING_1_RX_IF_GAIN_1_BIT (0) +#define GAIN_SETTING_1_RX_IF_GAIN_1_BITS (4) + +#define GAIN_SETTING_2 *((volatile uint32_t *)0x4000107Cu) +#define GAIN_SETTING_2_REG *((volatile uint32_t *)0x4000107Cu) +#define GAIN_SETTING_2_ADDR (0x4000107Cu) +#define GAIN_SETTING_2_RESET (0x00000030u) +/* RX_MIXER_GAIN_2 field */ +#define GAIN_SETTING_2_RX_MIXER_GAIN_2 (0x00000040u) +#define GAIN_SETTING_2_RX_MIXER_GAIN_2_MASK (0x00000040u) +#define GAIN_SETTING_2_RX_MIXER_GAIN_2_BIT (6) +#define GAIN_SETTING_2_RX_MIXER_GAIN_2_BITS (1) +/* RX_FILTER_GAIN_2 field */ +#define GAIN_SETTING_2_RX_FILTER_GAIN_2 (0x00000030u) +#define GAIN_SETTING_2_RX_FILTER_GAIN_2_MASK (0x00000030u) +#define GAIN_SETTING_2_RX_FILTER_GAIN_2_BIT (4) +#define GAIN_SETTING_2_RX_FILTER_GAIN_2_BITS (2) +/* RX_IF_GAIN_2 field */ +#define GAIN_SETTING_2_RX_IF_GAIN_2 (0x0000000Fu) +#define GAIN_SETTING_2_RX_IF_GAIN_2_MASK (0x0000000Fu) +#define GAIN_SETTING_2_RX_IF_GAIN_2_BIT (0) +#define GAIN_SETTING_2_RX_IF_GAIN_2_BITS (4) + +#define GAIN_SETTING_3 *((volatile uint32_t *)0x40001080u) +#define GAIN_SETTING_3_REG *((volatile uint32_t *)0x40001080u) +#define GAIN_SETTING_3_ADDR (0x40001080u) +#define GAIN_SETTING_3_RESET (0x00000031u) +/* RX_MIXER_GAIN_3 field */ +#define GAIN_SETTING_3_RX_MIXER_GAIN_3 (0x00000040u) +#define GAIN_SETTING_3_RX_MIXER_GAIN_3_MASK (0x00000040u) +#define GAIN_SETTING_3_RX_MIXER_GAIN_3_BIT (6) +#define GAIN_SETTING_3_RX_MIXER_GAIN_3_BITS (1) +/* RX_FILTER_GAIN_3 field */ +#define GAIN_SETTING_3_RX_FILTER_GAIN_3 (0x00000030u) +#define GAIN_SETTING_3_RX_FILTER_GAIN_3_MASK (0x00000030u) +#define GAIN_SETTING_3_RX_FILTER_GAIN_3_BIT (4) +#define GAIN_SETTING_3_RX_FILTER_GAIN_3_BITS (2) +/* RX_IF_GAIN_3 field */ +#define GAIN_SETTING_3_RX_IF_GAIN_3 (0x0000000Fu) +#define GAIN_SETTING_3_RX_IF_GAIN_3_MASK (0x0000000Fu) +#define GAIN_SETTING_3_RX_IF_GAIN_3_BIT (0) +#define GAIN_SETTING_3_RX_IF_GAIN_3_BITS (4) + +#define GAIN_SETTING_4 *((volatile uint32_t *)0x40001084u) +#define GAIN_SETTING_4_REG *((volatile uint32_t *)0x40001084u) +#define GAIN_SETTING_4_ADDR (0x40001084u) +#define GAIN_SETTING_4_RESET (0x00000032u) +/* RX_MIXER_GAIN_4 field */ +#define GAIN_SETTING_4_RX_MIXER_GAIN_4 (0x00000040u) +#define GAIN_SETTING_4_RX_MIXER_GAIN_4_MASK (0x00000040u) +#define GAIN_SETTING_4_RX_MIXER_GAIN_4_BIT (6) +#define GAIN_SETTING_4_RX_MIXER_GAIN_4_BITS (1) +/* RX_FILTER_GAIN_4 field */ +#define GAIN_SETTING_4_RX_FILTER_GAIN_4 (0x00000030u) +#define GAIN_SETTING_4_RX_FILTER_GAIN_4_MASK (0x00000030u) +#define GAIN_SETTING_4_RX_FILTER_GAIN_4_BIT (4) +#define GAIN_SETTING_4_RX_FILTER_GAIN_4_BITS (2) +/* RX_IF_GAIN_4 field */ +#define GAIN_SETTING_4_RX_IF_GAIN_4 (0x0000000Fu) +#define GAIN_SETTING_4_RX_IF_GAIN_4_MASK (0x0000000Fu) +#define GAIN_SETTING_4_RX_IF_GAIN_4_BIT (0) +#define GAIN_SETTING_4_RX_IF_GAIN_4_BITS (4) + +#define GAIN_SETTING_5 *((volatile uint32_t *)0x40001088u) +#define GAIN_SETTING_5_REG *((volatile uint32_t *)0x40001088u) +#define GAIN_SETTING_5_ADDR (0x40001088u) +#define GAIN_SETTING_5_RESET (0x00000033u) +/* RX_MIXER_GAIN_5 field */ +#define GAIN_SETTING_5_RX_MIXER_GAIN_5 (0x00000040u) +#define GAIN_SETTING_5_RX_MIXER_GAIN_5_MASK (0x00000040u) +#define GAIN_SETTING_5_RX_MIXER_GAIN_5_BIT (6) +#define GAIN_SETTING_5_RX_MIXER_GAIN_5_BITS (1) +/* RX_FILTER_GAIN_5 field */ +#define GAIN_SETTING_5_RX_FILTER_GAIN_5 (0x00000030u) +#define GAIN_SETTING_5_RX_FILTER_GAIN_5_MASK (0x00000030u) +#define GAIN_SETTING_5_RX_FILTER_GAIN_5_BIT (4) +#define GAIN_SETTING_5_RX_FILTER_GAIN_5_BITS (2) +/* RX_IF_GAIN_5 field */ +#define GAIN_SETTING_5_RX_IF_GAIN_5 (0x0000000Fu) +#define GAIN_SETTING_5_RX_IF_GAIN_5_MASK (0x0000000Fu) +#define GAIN_SETTING_5_RX_IF_GAIN_5_BIT (0) +#define GAIN_SETTING_5_RX_IF_GAIN_5_BITS (4) + +#define GAIN_SETTING_6 *((volatile uint32_t *)0x4000108Cu) +#define GAIN_SETTING_6_REG *((volatile uint32_t *)0x4000108Cu) +#define GAIN_SETTING_6_ADDR (0x4000108Cu) +#define GAIN_SETTING_6_RESET (0x00000034u) +/* RX_MIXER_GAIN_6 field */ +#define GAIN_SETTING_6_RX_MIXER_GAIN_6 (0x00000040u) +#define GAIN_SETTING_6_RX_MIXER_GAIN_6_MASK (0x00000040u) +#define GAIN_SETTING_6_RX_MIXER_GAIN_6_BIT (6) +#define GAIN_SETTING_6_RX_MIXER_GAIN_6_BITS (1) +/* RX_FILTER_GAIN_6 field */ +#define GAIN_SETTING_6_RX_FILTER_GAIN_6 (0x00000030u) +#define GAIN_SETTING_6_RX_FILTER_GAIN_6_MASK (0x00000030u) +#define GAIN_SETTING_6_RX_FILTER_GAIN_6_BIT (4) +#define GAIN_SETTING_6_RX_FILTER_GAIN_6_BITS (2) +/* RX_IF_GAIN_6 field */ +#define GAIN_SETTING_6_RX_IF_GAIN_6 (0x0000000Fu) +#define GAIN_SETTING_6_RX_IF_GAIN_6_MASK (0x0000000Fu) +#define GAIN_SETTING_6_RX_IF_GAIN_6_BIT (0) +#define GAIN_SETTING_6_RX_IF_GAIN_6_BITS (4) + +#define GAIN_SETTING_7 *((volatile uint32_t *)0x40001090u) +#define GAIN_SETTING_7_REG *((volatile uint32_t *)0x40001090u) +#define GAIN_SETTING_7_ADDR (0x40001090u) +#define GAIN_SETTING_7_RESET (0x00000035u) +/* RX_MIXER_GAIN_7 field */ +#define GAIN_SETTING_7_RX_MIXER_GAIN_7 (0x00000040u) +#define GAIN_SETTING_7_RX_MIXER_GAIN_7_MASK (0x00000040u) +#define GAIN_SETTING_7_RX_MIXER_GAIN_7_BIT (6) +#define GAIN_SETTING_7_RX_MIXER_GAIN_7_BITS (1) +/* RX_FILTER_GAIN_7 field */ +#define GAIN_SETTING_7_RX_FILTER_GAIN_7 (0x00000030u) +#define GAIN_SETTING_7_RX_FILTER_GAIN_7_MASK (0x00000030u) +#define GAIN_SETTING_7_RX_FILTER_GAIN_7_BIT (4) +#define GAIN_SETTING_7_RX_FILTER_GAIN_7_BITS (2) +/* RX_IF_GAIN_7 field */ +#define GAIN_SETTING_7_RX_IF_GAIN_7 (0x0000000Fu) +#define GAIN_SETTING_7_RX_IF_GAIN_7_MASK (0x0000000Fu) +#define GAIN_SETTING_7_RX_IF_GAIN_7_BIT (0) +#define GAIN_SETTING_7_RX_IF_GAIN_7_BITS (4) + +#define GAIN_SETTING_8 *((volatile uint32_t *)0x40001094u) +#define GAIN_SETTING_8_REG *((volatile uint32_t *)0x40001094u) +#define GAIN_SETTING_8_ADDR (0x40001094u) +#define GAIN_SETTING_8_RESET (0x00000036u) +/* RX_MIXER_GAIN_8 field */ +#define GAIN_SETTING_8_RX_MIXER_GAIN_8 (0x00000040u) +#define GAIN_SETTING_8_RX_MIXER_GAIN_8_MASK (0x00000040u) +#define GAIN_SETTING_8_RX_MIXER_GAIN_8_BIT (6) +#define GAIN_SETTING_8_RX_MIXER_GAIN_8_BITS (1) +/* RX_FILTER_GAIN_8 field */ +#define GAIN_SETTING_8_RX_FILTER_GAIN_8 (0x00000030u) +#define GAIN_SETTING_8_RX_FILTER_GAIN_8_MASK (0x00000030u) +#define GAIN_SETTING_8_RX_FILTER_GAIN_8_BIT (4) +#define GAIN_SETTING_8_RX_FILTER_GAIN_8_BITS (2) +/* RX_IF_GAIN_8 field */ +#define GAIN_SETTING_8_RX_IF_GAIN_8 (0x0000000Fu) +#define GAIN_SETTING_8_RX_IF_GAIN_8_MASK (0x0000000Fu) +#define GAIN_SETTING_8_RX_IF_GAIN_8_BIT (0) +#define GAIN_SETTING_8_RX_IF_GAIN_8_BITS (4) + +#define GAIN_SETTING_9 *((volatile uint32_t *)0x40001098u) +#define GAIN_SETTING_9_REG *((volatile uint32_t *)0x40001098u) +#define GAIN_SETTING_9_ADDR (0x40001098u) +#define GAIN_SETTING_9_RESET (0x00000076u) +/* RX_MIXER_GAIN_9 field */ +#define GAIN_SETTING_9_RX_MIXER_GAIN_9 (0x00000040u) +#define GAIN_SETTING_9_RX_MIXER_GAIN_9_MASK (0x00000040u) +#define GAIN_SETTING_9_RX_MIXER_GAIN_9_BIT (6) +#define GAIN_SETTING_9_RX_MIXER_GAIN_9_BITS (1) +/* RX_FILTER_GAIN_9 field */ +#define GAIN_SETTING_9_RX_FILTER_GAIN_9 (0x00000030u) +#define GAIN_SETTING_9_RX_FILTER_GAIN_9_MASK (0x00000030u) +#define GAIN_SETTING_9_RX_FILTER_GAIN_9_BIT (4) +#define GAIN_SETTING_9_RX_FILTER_GAIN_9_BITS (2) +/* RX_IF_GAIN_9 field */ +#define GAIN_SETTING_9_RX_IF_GAIN_9 (0x0000000Fu) +#define GAIN_SETTING_9_RX_IF_GAIN_9_MASK (0x0000000Fu) +#define GAIN_SETTING_9_RX_IF_GAIN_9_BIT (0) +#define GAIN_SETTING_9_RX_IF_GAIN_9_BITS (4) + +#define GAIN_SETTING_10 *((volatile uint32_t *)0x4000109Cu) +#define GAIN_SETTING_10_REG *((volatile uint32_t *)0x4000109Cu) +#define GAIN_SETTING_10_ADDR (0x4000109Cu) +#define GAIN_SETTING_10_RESET (0x00000077u) +/* RX_MIXER_GAIN_10 field */ +#define GAIN_SETTING_10_RX_MIXER_GAIN_10 (0x00000040u) +#define GAIN_SETTING_10_RX_MIXER_GAIN_10_MASK (0x00000040u) +#define GAIN_SETTING_10_RX_MIXER_GAIN_10_BIT (6) +#define GAIN_SETTING_10_RX_MIXER_GAIN_10_BITS (1) +/* RX_FILTER_GAIN_10 field */ +#define GAIN_SETTING_10_RX_FILTER_GAIN_10 (0x00000030u) +#define GAIN_SETTING_10_RX_FILTER_GAIN_10_MASK (0x00000030u) +#define GAIN_SETTING_10_RX_FILTER_GAIN_10_BIT (4) +#define GAIN_SETTING_10_RX_FILTER_GAIN_10_BITS (2) +/* RX_IF_GAIN_10 field */ +#define GAIN_SETTING_10_RX_IF_GAIN_10 (0x0000000Fu) +#define GAIN_SETTING_10_RX_IF_GAIN_10_MASK (0x0000000Fu) +#define GAIN_SETTING_10_RX_IF_GAIN_10_BIT (0) +#define GAIN_SETTING_10_RX_IF_GAIN_10_BITS (4) + +#define GAIN_SETTING_11 *((volatile uint32_t *)0x400010A0u) +#define GAIN_SETTING_11_REG *((volatile uint32_t *)0x400010A0u) +#define GAIN_SETTING_11_ADDR (0x400010A0u) +#define GAIN_SETTING_11_RESET (0x00000078u) +/* RX_MIXER_GAIN_11 field */ +#define GAIN_SETTING_11_RX_MIXER_GAIN_11 (0x00000040u) +#define GAIN_SETTING_11_RX_MIXER_GAIN_11_MASK (0x00000040u) +#define GAIN_SETTING_11_RX_MIXER_GAIN_11_BIT (6) +#define GAIN_SETTING_11_RX_MIXER_GAIN_11_BITS (1) +/* RX_FILTER_GAIN_11 field */ +#define GAIN_SETTING_11_RX_FILTER_GAIN_11 (0x00000030u) +#define GAIN_SETTING_11_RX_FILTER_GAIN_11_MASK (0x00000030u) +#define GAIN_SETTING_11_RX_FILTER_GAIN_11_BIT (4) +#define GAIN_SETTING_11_RX_FILTER_GAIN_11_BITS (2) +/* RX_IF_GAIN_11 field */ +#define GAIN_SETTING_11_RX_IF_GAIN_11 (0x0000000Fu) +#define GAIN_SETTING_11_RX_IF_GAIN_11_MASK (0x0000000Fu) +#define GAIN_SETTING_11_RX_IF_GAIN_11_BIT (0) +#define GAIN_SETTING_11_RX_IF_GAIN_11_BITS (4) + +#define GAIN_CTRL_MIN_RF *((volatile uint32_t *)0x400010A4u) +#define GAIN_CTRL_MIN_RF_REG *((volatile uint32_t *)0x400010A4u) +#define GAIN_CTRL_MIN_RF_ADDR (0x400010A4u) +#define GAIN_CTRL_MIN_RF_RESET (0x000000F0u) +/* GAIN_CTRL_MIN_RF field */ +#define GAIN_CTRL_MIN_RF_GAIN_CTRL_MIN_RF (0x000001FFu) +#define GAIN_CTRL_MIN_RF_GAIN_CTRL_MIN_RF_MASK (0x000001FFu) +#define GAIN_CTRL_MIN_RF_GAIN_CTRL_MIN_RF_BIT (0) +#define GAIN_CTRL_MIN_RF_GAIN_CTRL_MIN_RF_BITS (9) + +#define GAIN_CTRL_MAX_RF *((volatile uint32_t *)0x400010A8u) +#define GAIN_CTRL_MAX_RF_REG *((volatile uint32_t *)0x400010A8u) +#define GAIN_CTRL_MAX_RF_ADDR (0x400010A8u) +#define GAIN_CTRL_MAX_RF_RESET (0x000000FCu) +/* GAIN_CTRL_MAX_RF field */ +#define GAIN_CTRL_MAX_RF_GAIN_CTRL_MAX_RF (0x000001FFu) +#define GAIN_CTRL_MAX_RF_GAIN_CTRL_MAX_RF_MASK (0x000001FFu) +#define GAIN_CTRL_MAX_RF_GAIN_CTRL_MAX_RF_BIT (0) +#define GAIN_CTRL_MAX_RF_GAIN_CTRL_MAX_RF_BITS (9) + +#define MIXER_GAIN_STEP *((volatile uint32_t *)0x400010ACu) +#define MIXER_GAIN_STEP_REG *((volatile uint32_t *)0x400010ACu) +#define MIXER_GAIN_STEP_ADDR (0x400010ACu) +#define MIXER_GAIN_STEP_RESET (0x0000000Cu) +/* MIXER_GAIN_STEP field */ +#define MIXER_GAIN_STEP_MIXER_GAIN_STEP (0x0000000Fu) +#define MIXER_GAIN_STEP_MIXER_GAIN_STEP_MASK (0x0000000Fu) +#define MIXER_GAIN_STEP_MIXER_GAIN_STEP_BIT (0) +#define MIXER_GAIN_STEP_MIXER_GAIN_STEP_BITS (4) + +#define PREAMBLE_EVENT *((volatile uint32_t *)0x400010B0u) +#define PREAMBLE_EVENT_REG *((volatile uint32_t *)0x400010B0u) +#define PREAMBLE_EVENT_ADDR (0x400010B0u) +#define PREAMBLE_EVENT_RESET (0x00005877u) +/* PREAMBLE_CONFIRM_THRESH field */ +#define PREAMBLE_EVENT_PREAMBLE_CONFIRM_THRESH (0x0000FF00u) +#define PREAMBLE_EVENT_PREAMBLE_CONFIRM_THRESH_MASK (0x0000FF00u) +#define PREAMBLE_EVENT_PREAMBLE_CONFIRM_THRESH_BIT (8) +#define PREAMBLE_EVENT_PREAMBLE_CONFIRM_THRESH_BITS (8) +/* PREAMBLE_EVENT_THRESH field */ +#define PREAMBLE_EVENT_PREAMBLE_EVENT_THRESH (0x000000FFu) +#define PREAMBLE_EVENT_PREAMBLE_EVENT_THRESH_MASK (0x000000FFu) +#define PREAMBLE_EVENT_PREAMBLE_EVENT_THRESH_BIT (0) +#define PREAMBLE_EVENT_PREAMBLE_EVENT_THRESH_BITS (8) + +#define PREAMBLE_ABORT_THRESH *((volatile uint32_t *)0x400010B4u) +#define PREAMBLE_ABORT_THRESH_REG *((volatile uint32_t *)0x400010B4u) +#define PREAMBLE_ABORT_THRESH_ADDR (0x400010B4u) +#define PREAMBLE_ABORT_THRESH_RESET (0x00000071u) +/* PREAMBLE_ABORT_THRESH field */ +#define PREAMBLE_ABORT_THRESH_PREAMBLE_ABORT_THRESH (0x000000FFu) +#define PREAMBLE_ABORT_THRESH_PREAMBLE_ABORT_THRESH_MASK (0x000000FFu) +#define PREAMBLE_ABORT_THRESH_PREAMBLE_ABORT_THRESH_BIT (0) +#define PREAMBLE_ABORT_THRESH_PREAMBLE_ABORT_THRESH_BITS (8) + +#define PREAMBLE_ACCEPT_WINDOW *((volatile uint32_t *)0x400010B8u) +#define PREAMBLE_ACCEPT_WINDOW_REG *((volatile uint32_t *)0x400010B8u) +#define PREAMBLE_ACCEPT_WINDOW_ADDR (0x400010B8u) +#define PREAMBLE_ACCEPT_WINDOW_RESET (0x00000003u) +/* PREAMBLE_ACCEPT_WINDOW field */ +#define PREAMBLE_ACCEPT_WINDOW_PREAMBLE_ACCEPT_WINDOW (0x0000007Fu) +#define PREAMBLE_ACCEPT_WINDOW_PREAMBLE_ACCEPT_WINDOW_MASK (0x0000007Fu) +#define PREAMBLE_ACCEPT_WINDOW_PREAMBLE_ACCEPT_WINDOW_BIT (0) +#define PREAMBLE_ACCEPT_WINDOW_PREAMBLE_ACCEPT_WINDOW_BITS (7) + +#define CCA_MODE *((volatile uint32_t *)0x400010BCu) +#define CCA_MODE_REG *((volatile uint32_t *)0x400010BCu) +#define CCA_MODE_ADDR (0x400010BCu) +#define CCA_MODE_RESET (0x00000000u) +/* CCA_MODE field */ +#define CCA_MODE_CCA_MODE (0x00000003u) +#define CCA_MODE_CCA_MODE_MASK (0x00000003u) +#define CCA_MODE_CCA_MODE_BIT (0) +#define CCA_MODE_CCA_MODE_BITS (2) + +#define TX_POWER_MAX *((volatile uint32_t *)0x400010C0u) +#define TX_POWER_MAX_REG *((volatile uint32_t *)0x400010C0u) +#define TX_POWER_MAX_ADDR (0x400010C0u) +#define TX_POWER_MAX_RESET (0x00000000u) +/* MANUAL_POWER field */ +#define TX_POWER_MAX_MANUAL_POWER (0x00008000u) +#define TX_POWER_MAX_MANUAL_POWER_MASK (0x00008000u) +#define TX_POWER_MAX_MANUAL_POWER_BIT (15) +#define TX_POWER_MAX_MANUAL_POWER_BITS (1) +/* TX_POWER_MAX field */ +#define TX_POWER_MAX_TX_POWER_MAX (0x0000001Fu) +#define TX_POWER_MAX_TX_POWER_MAX_MASK (0x0000001Fu) +#define TX_POWER_MAX_TX_POWER_MAX_BIT (0) +#define TX_POWER_MAX_TX_POWER_MAX_BITS (5) + +#define SYNTH_FREQ_H *((volatile uint32_t *)0x400010C4u) +#define SYNTH_FREQ_H_REG *((volatile uint32_t *)0x400010C4u) +#define SYNTH_FREQ_H_ADDR (0x400010C4u) +#define SYNTH_FREQ_H_RESET (0x00000003u) +/* SYNTH_FREQ_H field */ +#define SYNTH_FREQ_H_SYNTH_FREQ_H (0x00000003u) +#define SYNTH_FREQ_H_SYNTH_FREQ_H_MASK (0x00000003u) +#define SYNTH_FREQ_H_SYNTH_FREQ_H_BIT (0) +#define SYNTH_FREQ_H_SYNTH_FREQ_H_BITS (2) + +#define SYNTH_FREQ_L *((volatile uint32_t *)0x400010C8u) +#define SYNTH_FREQ_L_REG *((volatile uint32_t *)0x400010C8u) +#define SYNTH_FREQ_L_ADDR (0x400010C8u) +#define SYNTH_FREQ_L_RESET (0x00003800u) +/* SYNTH_FREQ_L field */ +#define SYNTH_FREQ_L_SYNTH_FREQ_L (0x0000FFFFu) +#define SYNTH_FREQ_L_SYNTH_FREQ_L_MASK (0x0000FFFFu) +#define SYNTH_FREQ_L_SYNTH_FREQ_L_BIT (0) +#define SYNTH_FREQ_L_SYNTH_FREQ_L_BITS (16) + +#define RSSI_INST *((volatile uint32_t *)0x400010CCu) +#define RSSI_INST_REG *((volatile uint32_t *)0x400010CCu) +#define RSSI_INST_ADDR (0x400010CCu) +#define RSSI_INST_RESET (0x00000000u) +/* NEW_RSSI_INST field */ +#define RSSI_INST_NEW_RSSI_INST (0x00000200u) +#define RSSI_INST_NEW_RSSI_INST_MASK (0x00000200u) +#define RSSI_INST_NEW_RSSI_INST_BIT (9) +#define RSSI_INST_NEW_RSSI_INST_BITS (1) +/* RSSI_INST field */ +#define RSSI_INST_RSSI_INST (0x000001FFu) +#define RSSI_INST_RSSI_INST_MASK (0x000001FFu) +#define RSSI_INST_RSSI_INST_BIT (0) +#define RSSI_INST_RSSI_INST_BITS (9) + +#define FREQ_MEAS_CTRL1 *((volatile uint32_t *)0x400010D0u) +#define FREQ_MEAS_CTRL1_REG *((volatile uint32_t *)0x400010D0u) +#define FREQ_MEAS_CTRL1_ADDR (0x400010D0u) +#define FREQ_MEAS_CTRL1_RESET (0x00000160u) +/* AUTO_TUNE_EN field */ +#define FREQ_MEAS_CTRL1_AUTO_TUNE_EN (0x00008000u) +#define FREQ_MEAS_CTRL1_AUTO_TUNE_EN_MASK (0x00008000u) +#define FREQ_MEAS_CTRL1_AUTO_TUNE_EN_BIT (15) +#define FREQ_MEAS_CTRL1_AUTO_TUNE_EN_BITS (1) +/* FREQ_MEAS_EN field */ +#define FREQ_MEAS_CTRL1_FREQ_MEAS_EN (0x00004000u) +#define FREQ_MEAS_CTRL1_FREQ_MEAS_EN_MASK (0x00004000u) +#define FREQ_MEAS_CTRL1_FREQ_MEAS_EN_BIT (14) +#define FREQ_MEAS_CTRL1_FREQ_MEAS_EN_BITS (1) +/* OPEN_LOOP_MANUAL field */ +#define FREQ_MEAS_CTRL1_OPEN_LOOP_MANUAL (0x00002000u) +#define FREQ_MEAS_CTRL1_OPEN_LOOP_MANUAL_MASK (0x00002000u) +#define FREQ_MEAS_CTRL1_OPEN_LOOP_MANUAL_BIT (13) +#define FREQ_MEAS_CTRL1_OPEN_LOOP_MANUAL_BITS (1) +/* OPEN_LOOP field */ +#define FREQ_MEAS_CTRL1_OPEN_LOOP (0x00001000u) +#define FREQ_MEAS_CTRL1_OPEN_LOOP_MASK (0x00001000u) +#define FREQ_MEAS_CTRL1_OPEN_LOOP_BIT (12) +#define FREQ_MEAS_CTRL1_OPEN_LOOP_BITS (1) +/* DELAY_FIRST_MEAS field */ +#define FREQ_MEAS_CTRL1_DELAY_FIRST_MEAS (0x00000400u) +#define FREQ_MEAS_CTRL1_DELAY_FIRST_MEAS_MASK (0x00000400u) +#define FREQ_MEAS_CTRL1_DELAY_FIRST_MEAS_BIT (10) +#define FREQ_MEAS_CTRL1_DELAY_FIRST_MEAS_BITS (1) +/* DELAY_ALL_MEAS field */ +#define FREQ_MEAS_CTRL1_DELAY_ALL_MEAS (0x00000200u) +#define FREQ_MEAS_CTRL1_DELAY_ALL_MEAS_MASK (0x00000200u) +#define FREQ_MEAS_CTRL1_DELAY_ALL_MEAS_BIT (9) +#define FREQ_MEAS_CTRL1_DELAY_ALL_MEAS_BITS (1) +/* BIN_SEARCH_MSB field */ +#define FREQ_MEAS_CTRL1_BIN_SEARCH_MSB (0x000001C0u) +#define FREQ_MEAS_CTRL1_BIN_SEARCH_MSB_MASK (0x000001C0u) +#define FREQ_MEAS_CTRL1_BIN_SEARCH_MSB_BIT (6) +#define FREQ_MEAS_CTRL1_BIN_SEARCH_MSB_BITS (3) +/* TUNE_VCO_INIT field */ +#define FREQ_MEAS_CTRL1_TUNE_VCO_INIT (0x0000003Fu) +#define FREQ_MEAS_CTRL1_TUNE_VCO_INIT_MASK (0x0000003Fu) +#define FREQ_MEAS_CTRL1_TUNE_VCO_INIT_BIT (0) +#define FREQ_MEAS_CTRL1_TUNE_VCO_INIT_BITS (6) + +#define FREQ_MEAS_CTRL2 *((volatile uint32_t *)0x400010D4u) +#define FREQ_MEAS_CTRL2_REG *((volatile uint32_t *)0x400010D4u) +#define FREQ_MEAS_CTRL2_ADDR (0x400010D4u) +#define FREQ_MEAS_CTRL2_RESET (0x0000201Eu) +/* FREQ_MEAS_TIMER field */ +#define FREQ_MEAS_CTRL2_FREQ_MEAS_TIMER (0x0000FF00u) +#define FREQ_MEAS_CTRL2_FREQ_MEAS_TIMER_MASK (0x0000FF00u) +#define FREQ_MEAS_CTRL2_FREQ_MEAS_TIMER_BIT (8) +#define FREQ_MEAS_CTRL2_FREQ_MEAS_TIMER_BITS (8) +/* TARGET_PERIOD field */ +#define FREQ_MEAS_CTRL2_TARGET_PERIOD (0x000000FFu) +#define FREQ_MEAS_CTRL2_TARGET_PERIOD_MASK (0x000000FFu) +#define FREQ_MEAS_CTRL2_TARGET_PERIOD_BIT (0) +#define FREQ_MEAS_CTRL2_TARGET_PERIOD_BITS (8) + +#define FREQ_MEAS_SHIFT *((volatile uint32_t *)0x400010D8u) +#define FREQ_MEAS_SHIFT_REG *((volatile uint32_t *)0x400010D8u) +#define FREQ_MEAS_SHIFT_ADDR (0x400010D8u) +#define FREQ_MEAS_SHIFT_RESET (0x00000035u) +/* FREQ_MEAS_SHIFT field */ +#define FREQ_MEAS_SHIFT_FREQ_MEAS_SHIFT (0x000000FFu) +#define FREQ_MEAS_SHIFT_FREQ_MEAS_SHIFT_MASK (0x000000FFu) +#define FREQ_MEAS_SHIFT_FREQ_MEAS_SHIFT_BIT (0) +#define FREQ_MEAS_SHIFT_FREQ_MEAS_SHIFT_BITS (8) + +#define FREQ_MEAS_STATUS1 *((volatile uint32_t *)0x400010DCu) +#define FREQ_MEAS_STATUS1_REG *((volatile uint32_t *)0x400010DCu) +#define FREQ_MEAS_STATUS1_ADDR (0x400010DCu) +#define FREQ_MEAS_STATUS1_RESET (0x00000000u) +/* INVALID_EDGE field */ +#define FREQ_MEAS_STATUS1_INVALID_EDGE (0x00008000u) +#define FREQ_MEAS_STATUS1_INVALID_EDGE_MASK (0x00008000u) +#define FREQ_MEAS_STATUS1_INVALID_EDGE_BIT (15) +#define FREQ_MEAS_STATUS1_INVALID_EDGE_BITS (1) +/* SIGN_FOUND field */ +#define FREQ_MEAS_STATUS1_SIGN_FOUND (0x00004000u) +#define FREQ_MEAS_STATUS1_SIGN_FOUND_MASK (0x00004000u) +#define FREQ_MEAS_STATUS1_SIGN_FOUND_BIT (14) +#define FREQ_MEAS_STATUS1_SIGN_FOUND_BITS (1) +/* FREQ_SIGN field */ +#define FREQ_MEAS_STATUS1_FREQ_SIGN (0x00002000u) +#define FREQ_MEAS_STATUS1_FREQ_SIGN_MASK (0x00002000u) +#define FREQ_MEAS_STATUS1_FREQ_SIGN_BIT (13) +#define FREQ_MEAS_STATUS1_FREQ_SIGN_BITS (1) +/* PERIOD_FOUND field */ +#define FREQ_MEAS_STATUS1_PERIOD_FOUND (0x00001000u) +#define FREQ_MEAS_STATUS1_PERIOD_FOUND_MASK (0x00001000u) +#define FREQ_MEAS_STATUS1_PERIOD_FOUND_BIT (12) +#define FREQ_MEAS_STATUS1_PERIOD_FOUND_BITS (1) +/* NEAREST_DIFF field */ +#define FREQ_MEAS_STATUS1_NEAREST_DIFF (0x000003FFu) +#define FREQ_MEAS_STATUS1_NEAREST_DIFF_MASK (0x000003FFu) +#define FREQ_MEAS_STATUS1_NEAREST_DIFF_BIT (0) +#define FREQ_MEAS_STATUS1_NEAREST_DIFF_BITS (10) + +#define FREQ_MEAS_STATUS2 *((volatile uint32_t *)0x400010E0u) +#define FREQ_MEAS_STATUS2_REG *((volatile uint32_t *)0x400010E0u) +#define FREQ_MEAS_STATUS2_ADDR (0x400010E0u) +#define FREQ_MEAS_STATUS2_RESET (0x00000000u) +/* BEAT_TIMER field */ +#define FREQ_MEAS_STATUS2_BEAT_TIMER (0x0000FFC0u) +#define FREQ_MEAS_STATUS2_BEAT_TIMER_MASK (0x0000FFC0u) +#define FREQ_MEAS_STATUS2_BEAT_TIMER_BIT (6) +#define FREQ_MEAS_STATUS2_BEAT_TIMER_BITS (10) +/* BEATS field */ +#define FREQ_MEAS_STATUS2_BEATS (0x0000003Fu) +#define FREQ_MEAS_STATUS2_BEATS_MASK (0x0000003Fu) +#define FREQ_MEAS_STATUS2_BEATS_BIT (0) +#define FREQ_MEAS_STATUS2_BEATS_BITS (6) + +#define FREQ_MEAS_STATUS3 *((volatile uint32_t *)0x400010E4u) +#define FREQ_MEAS_STATUS3_REG *((volatile uint32_t *)0x400010E4u) +#define FREQ_MEAS_STATUS3_ADDR (0x400010E4u) +#define FREQ_MEAS_STATUS3_RESET (0x00000020u) +/* TUNE_VCO field */ +#define FREQ_MEAS_STATUS3_TUNE_VCO (0x0000003Fu) +#define FREQ_MEAS_STATUS3_TUNE_VCO_MASK (0x0000003Fu) +#define FREQ_MEAS_STATUS3_TUNE_VCO_BIT (0) +#define FREQ_MEAS_STATUS3_TUNE_VCO_BITS (6) + +#define SCR_CTRL *((volatile uint32_t *)0x400010E8u) +#define SCR_CTRL_REG *((volatile uint32_t *)0x400010E8u) +#define SCR_CTRL_ADDR (0x400010E8u) +#define SCR_CTRL_RESET (0x00000004u) +/* SCR_RESET field */ +#define SCR_CTRL_SCR_RESET (0x00000004u) +#define SCR_CTRL_SCR_RESET_MASK (0x00000004u) +#define SCR_CTRL_SCR_RESET_BIT (2) +#define SCR_CTRL_SCR_RESET_BITS (1) +/* SCR_WRITE field */ +#define SCR_CTRL_SCR_WRITE (0x00000002u) +#define SCR_CTRL_SCR_WRITE_MASK (0x00000002u) +#define SCR_CTRL_SCR_WRITE_BIT (1) +#define SCR_CTRL_SCR_WRITE_BITS (1) +/* SCR_READ field */ +#define SCR_CTRL_SCR_READ (0x00000001u) +#define SCR_CTRL_SCR_READ_MASK (0x00000001u) +#define SCR_CTRL_SCR_READ_BIT (0) +#define SCR_CTRL_SCR_READ_BITS (1) + +#define SCR_BUSY *((volatile uint32_t *)0x400010ECu) +#define SCR_BUSY_REG *((volatile uint32_t *)0x400010ECu) +#define SCR_BUSY_ADDR (0x400010ECu) +#define SCR_BUSY_RESET (0x00000000u) +/* SCR_BUSY field */ +#define SCR_BUSY_SCR_BUSY (0x00000001u) +#define SCR_BUSY_SCR_BUSY_MASK (0x00000001u) +#define SCR_BUSY_SCR_BUSY_BIT (0) +#define SCR_BUSY_SCR_BUSY_BITS (1) + +#define SCR_ADDR *((volatile uint32_t *)0x400010F0u) +#define SCR_ADDR_REG *((volatile uint32_t *)0x400010F0u) +#define SCR_ADDR_ADDR (0x400010F0u) +#define SCR_ADDR_RESET (0x00000000u) +/* SCR_ADDR field */ +#define SCR_ADDR_SCR_ADDR (0x000000FFu) +#define SCR_ADDR_SCR_ADDR_MASK (0x000000FFu) +#define SCR_ADDR_SCR_ADDR_BIT (0) +#define SCR_ADDR_SCR_ADDR_BITS (8) + +#define SCR_WRITE *((volatile uint32_t *)0x400010F4u) +#define SCR_WRITE_REG *((volatile uint32_t *)0x400010F4u) +#define SCR_WRITE_ADDR (0x400010F4u) +#define SCR_WRITE_RESET (0x00000000u) +/* SCR_WRITE field */ +#define SCR_WRITE_SCR_WRITE (0x0000FFFFu) +#define SCR_WRITE_SCR_WRITE_MASK (0x0000FFFFu) +#define SCR_WRITE_SCR_WRITE_BIT (0) +#define SCR_WRITE_SCR_WRITE_BITS (16) + +#define SCR_READ *((volatile uint32_t *)0x400010F8u) +#define SCR_READ_REG *((volatile uint32_t *)0x400010F8u) +#define SCR_READ_ADDR (0x400010F8u) +#define SCR_READ_RESET (0x00000000u) +/* SCR_READ field */ +#define SCR_READ_SCR_READ (0x0000FFFFu) +#define SCR_READ_SCR_READ_MASK (0x0000FFFFu) +#define SCR_READ_SCR_READ_BIT (0) +#define SCR_READ_SCR_READ_BITS (16) + +#define SYNTH_LOCK *((volatile uint32_t *)0x400010FCu) +#define SYNTH_LOCK_REG *((volatile uint32_t *)0x400010FCu) +#define SYNTH_LOCK_ADDR (0x400010FCu) +#define SYNTH_LOCK_RESET (0x00000000u) +/* IN_LOCK field */ +#define SYNTH_LOCK_IN_LOCK (0x00000001u) +#define SYNTH_LOCK_IN_LOCK_MASK (0x00000001u) +#define SYNTH_LOCK_IN_LOCK_BIT (0) +#define SYNTH_LOCK_IN_LOCK_BITS (1) + +#define AN_CAL_STATUS *((volatile uint32_t *)0x40001100u) +#define AN_CAL_STATUS_REG *((volatile uint32_t *)0x40001100u) +#define AN_CAL_STATUS_ADDR (0x40001100u) +#define AN_CAL_STATUS_RESET (0x00000000u) +/* VCO_CTRL field */ +#define AN_CAL_STATUS_VCO_CTRL (0x0000000Cu) +#define AN_CAL_STATUS_VCO_CTRL_MASK (0x0000000Cu) +#define AN_CAL_STATUS_VCO_CTRL_BIT (2) +#define AN_CAL_STATUS_VCO_CTRL_BITS (2) + +#define BIAS_CAL_STATUS *((volatile uint32_t *)0x40001104u) +#define BIAS_CAL_STATUS_REG *((volatile uint32_t *)0x40001104u) +#define BIAS_CAL_STATUS_ADDR (0x40001104u) +#define BIAS_CAL_STATUS_RESET (0x00000000u) +/* VCOMP field */ +#define BIAS_CAL_STATUS_VCOMP (0x00000002u) +#define BIAS_CAL_STATUS_VCOMP_MASK (0x00000002u) +#define BIAS_CAL_STATUS_VCOMP_BIT (1) +#define BIAS_CAL_STATUS_VCOMP_BITS (1) +/* ICOMP field */ +#define BIAS_CAL_STATUS_ICOMP (0x00000001u) +#define BIAS_CAL_STATUS_ICOMP_MASK (0x00000001u) +#define BIAS_CAL_STATUS_ICOMP_BIT (0) +#define BIAS_CAL_STATUS_ICOMP_BITS (1) + +#define ATEST_SEL *((volatile uint32_t *)0x40001108u) +#define ATEST_SEL_REG *((volatile uint32_t *)0x40001108u) +#define ATEST_SEL_ADDR (0x40001108u) +#define ATEST_SEL_RESET (0x00000000u) +/* ATEST_CTRL field */ +#define ATEST_SEL_ATEST_CTRL (0x0000FF00u) +#define ATEST_SEL_ATEST_CTRL_MASK (0x0000FF00u) +#define ATEST_SEL_ATEST_CTRL_BIT (8) +#define ATEST_SEL_ATEST_CTRL_BITS (8) +/* ATEST_SEL field */ +#define ATEST_SEL_ATEST_SEL (0x0000001Fu) +#define ATEST_SEL_ATEST_SEL_MASK (0x0000001Fu) +#define ATEST_SEL_ATEST_SEL_BIT (0) +#define ATEST_SEL_ATEST_SEL_BITS (5) + +#define AN_EN_TEST *((volatile uint32_t *)0x4000110Cu) +#define AN_EN_TEST_REG *((volatile uint32_t *)0x4000110Cu) +#define AN_EN_TEST_ADDR (0x4000110Cu) +#define AN_EN_TEST_RESET (0x00000000u) +/* AN_TEST_MODE field */ +#define AN_EN_TEST_AN_TEST_MODE (0x00008000u) +#define AN_EN_TEST_AN_TEST_MODE_MASK (0x00008000u) +#define AN_EN_TEST_AN_TEST_MODE_BIT (15) +#define AN_EN_TEST_AN_TEST_MODE_BITS (1) +/* PFD_EN field */ +#define AN_EN_TEST_PFD_EN (0x00004000u) +#define AN_EN_TEST_PFD_EN_MASK (0x00004000u) +#define AN_EN_TEST_PFD_EN_BIT (14) +#define AN_EN_TEST_PFD_EN_BITS (1) +/* ADC_EN field */ +#define AN_EN_TEST_ADC_EN (0x00002000u) +#define AN_EN_TEST_ADC_EN_MASK (0x00002000u) +#define AN_EN_TEST_ADC_EN_BIT (13) +#define AN_EN_TEST_ADC_EN_BITS (1) +/* UNUSED field */ +#define AN_EN_TEST_UNUSED (0x00001000u) +#define AN_EN_TEST_UNUSED_MASK (0x00001000u) +#define AN_EN_TEST_UNUSED_BIT (12) +#define AN_EN_TEST_UNUSED_BITS (1) +/* PRE_FILT_EN field */ +#define AN_EN_TEST_PRE_FILT_EN (0x00000800u) +#define AN_EN_TEST_PRE_FILT_EN_MASK (0x00000800u) +#define AN_EN_TEST_PRE_FILT_EN_BIT (11) +#define AN_EN_TEST_PRE_FILT_EN_BITS (1) +/* IF_AMP_EN field */ +#define AN_EN_TEST_IF_AMP_EN (0x00000400u) +#define AN_EN_TEST_IF_AMP_EN_MASK (0x00000400u) +#define AN_EN_TEST_IF_AMP_EN_BIT (10) +#define AN_EN_TEST_IF_AMP_EN_BITS (1) +/* LNA_EN field */ +#define AN_EN_TEST_LNA_EN (0x00000200u) +#define AN_EN_TEST_LNA_EN_MASK (0x00000200u) +#define AN_EN_TEST_LNA_EN_BIT (9) +#define AN_EN_TEST_LNA_EN_BITS (1) +/* MIXER_EN field */ +#define AN_EN_TEST_MIXER_EN (0x00000100u) +#define AN_EN_TEST_MIXER_EN_MASK (0x00000100u) +#define AN_EN_TEST_MIXER_EN_BIT (8) +#define AN_EN_TEST_MIXER_EN_BITS (1) +/* CH_FILT_EN field */ +#define AN_EN_TEST_CH_FILT_EN (0x00000080u) +#define AN_EN_TEST_CH_FILT_EN_MASK (0x00000080u) +#define AN_EN_TEST_CH_FILT_EN_BIT (7) +#define AN_EN_TEST_CH_FILT_EN_BITS (1) +/* MOD_DAC_EN field */ +#define AN_EN_TEST_MOD_DAC_EN (0x00000040u) +#define AN_EN_TEST_MOD_DAC_EN_MASK (0x00000040u) +#define AN_EN_TEST_MOD_DAC_EN_BIT (6) +#define AN_EN_TEST_MOD_DAC_EN_BITS (1) +/* PA_EN field */ +#define AN_EN_TEST_PA_EN (0x00000010u) +#define AN_EN_TEST_PA_EN_MASK (0x00000010u) +#define AN_EN_TEST_PA_EN_BIT (4) +#define AN_EN_TEST_PA_EN_BITS (1) +/* PRESCALER_EN field */ +#define AN_EN_TEST_PRESCALER_EN (0x00000008u) +#define AN_EN_TEST_PRESCALER_EN_MASK (0x00000008u) +#define AN_EN_TEST_PRESCALER_EN_BIT (3) +#define AN_EN_TEST_PRESCALER_EN_BITS (1) +/* VCO_EN field */ +#define AN_EN_TEST_VCO_EN (0x00000004u) +#define AN_EN_TEST_VCO_EN_MASK (0x00000004u) +#define AN_EN_TEST_VCO_EN_BIT (2) +#define AN_EN_TEST_VCO_EN_BITS (1) +/* BIAS_EN field */ +#define AN_EN_TEST_BIAS_EN (0x00000001u) +#define AN_EN_TEST_BIAS_EN_MASK (0x00000001u) +#define AN_EN_TEST_BIAS_EN_BIT (0) +#define AN_EN_TEST_BIAS_EN_BITS (1) + +#define TUNE_FILTER_CTRL *((volatile uint32_t *)0x40001110u) +#define TUNE_FILTER_CTRL_REG *((volatile uint32_t *)0x40001110u) +#define TUNE_FILTER_CTRL_ADDR (0x40001110u) +#define TUNE_FILTER_CTRL_RESET (0x00000000u) +/* TUNE_FILTER_EN field */ +#define TUNE_FILTER_CTRL_TUNE_FILTER_EN (0x00000002u) +#define TUNE_FILTER_CTRL_TUNE_FILTER_EN_MASK (0x00000002u) +#define TUNE_FILTER_CTRL_TUNE_FILTER_EN_BIT (1) +#define TUNE_FILTER_CTRL_TUNE_FILTER_EN_BITS (1) +/* TUNE_FILTER_RESET field */ +#define TUNE_FILTER_CTRL_TUNE_FILTER_RESET (0x00000001u) +#define TUNE_FILTER_CTRL_TUNE_FILTER_RESET_MASK (0x00000001u) +#define TUNE_FILTER_CTRL_TUNE_FILTER_RESET_BIT (0) +#define TUNE_FILTER_CTRL_TUNE_FILTER_RESET_BITS (1) + +#define NOISE_EN *((volatile uint32_t *)0x40001114u) +#define NOISE_EN_REG *((volatile uint32_t *)0x40001114u) +#define NOISE_EN_ADDR (0x40001114u) +#define NOISE_EN_RESET (0x00000000u) +/* NOISE_EN field */ +#define NOISE_EN_NOISE_EN (0x00000001u) +#define NOISE_EN_NOISE_EN_MASK (0x00000001u) +#define NOISE_EN_NOISE_EN_BIT (0) +#define NOISE_EN_NOISE_EN_BITS (1) + +/* MAC block */ +#define DATA_MAC_BASE (0x40002000u) +#define DATA_MAC_END (0x400020C8u) +#define DATA_MAC_SIZE (DATA_MAC_END - DATA_MAC_BASE + 1) + +#define MAC_RX_ST_ADDR_A *((volatile uint32_t *)0x40002000u) +#define MAC_RX_ST_ADDR_A_REG *((volatile uint32_t *)0x40002000u) +#define MAC_RX_ST_ADDR_A_ADDR (0x40002000u) +#define MAC_RX_ST_ADDR_A_RESET (0x20000000u) +/* MAC_RAM_OFFS field */ +#define MAC_RX_ST_ADDR_A_MAC_RAM_OFFS (0xFFFFE000u) +#define MAC_RX_ST_ADDR_A_MAC_RAM_OFFS_MASK (0xFFFFE000u) +#define MAC_RX_ST_ADDR_A_MAC_RAM_OFFS_BIT (13) +#define MAC_RX_ST_ADDR_A_MAC_RAM_OFFS_BITS (19) +/* MAC_RX_ST_ADDR_A field */ +#define MAC_RX_ST_ADDR_A_MAC_RX_ST_ADDR_A (0x00001FFEu) +#define MAC_RX_ST_ADDR_A_MAC_RX_ST_ADDR_A_MASK (0x00001FFEu) +#define MAC_RX_ST_ADDR_A_MAC_RX_ST_ADDR_A_BIT (1) +#define MAC_RX_ST_ADDR_A_MAC_RX_ST_ADDR_A_BITS (12) + +#define MAC_RX_END_ADDR_A *((volatile uint32_t *)0x40002004u) +#define MAC_RX_END_ADDR_A_REG *((volatile uint32_t *)0x40002004u) +#define MAC_RX_END_ADDR_A_ADDR (0x40002004u) +#define MAC_RX_END_ADDR_A_RESET (0x20000088u) +/* MAC_RAM_OFFS field */ +#define MAC_RX_END_ADDR_A_MAC_RAM_OFFS (0xFFFFE000u) +#define MAC_RX_END_ADDR_A_MAC_RAM_OFFS_MASK (0xFFFFE000u) +#define MAC_RX_END_ADDR_A_MAC_RAM_OFFS_BIT (13) +#define MAC_RX_END_ADDR_A_MAC_RAM_OFFS_BITS (19) +/* MAC_RX_END_ADDR_A field */ +#define MAC_RX_END_ADDR_A_MAC_RX_END_ADDR_A (0x00001FFEu) +#define MAC_RX_END_ADDR_A_MAC_RX_END_ADDR_A_MASK (0x00001FFEu) +#define MAC_RX_END_ADDR_A_MAC_RX_END_ADDR_A_BIT (1) +#define MAC_RX_END_ADDR_A_MAC_RX_END_ADDR_A_BITS (12) + +#define MAC_RX_ST_ADDR_B *((volatile uint32_t *)0x40002008u) +#define MAC_RX_ST_ADDR_B_REG *((volatile uint32_t *)0x40002008u) +#define MAC_RX_ST_ADDR_B_ADDR (0x40002008u) +#define MAC_RX_ST_ADDR_B_RESET (0x20000000u) +/* MAC_RAM_OFFS field */ +#define MAC_RX_ST_ADDR_B_MAC_RAM_OFFS (0xFFFFE000u) +#define MAC_RX_ST_ADDR_B_MAC_RAM_OFFS_MASK (0xFFFFE000u) +#define MAC_RX_ST_ADDR_B_MAC_RAM_OFFS_BIT (13) +#define MAC_RX_ST_ADDR_B_MAC_RAM_OFFS_BITS (19) +/* MAC_RX_ST_ADDR_B field */ +#define MAC_RX_ST_ADDR_B_MAC_RX_ST_ADDR_B (0x00001FFEu) +#define MAC_RX_ST_ADDR_B_MAC_RX_ST_ADDR_B_MASK (0x00001FFEu) +#define MAC_RX_ST_ADDR_B_MAC_RX_ST_ADDR_B_BIT (1) +#define MAC_RX_ST_ADDR_B_MAC_RX_ST_ADDR_B_BITS (12) + +#define MAC_RX_END_ADDR_B *((volatile uint32_t *)0x4000200Cu) +#define MAC_RX_END_ADDR_B_REG *((volatile uint32_t *)0x4000200Cu) +#define MAC_RX_END_ADDR_B_ADDR (0x4000200Cu) +#define MAC_RX_END_ADDR_B_RESET (0x20000088u) +/* MAC_RAM_OFFS field */ +#define MAC_RX_END_ADDR_B_MAC_RAM_OFFS (0xFFFFE000u) +#define MAC_RX_END_ADDR_B_MAC_RAM_OFFS_MASK (0xFFFFE000u) +#define MAC_RX_END_ADDR_B_MAC_RAM_OFFS_BIT (13) +#define MAC_RX_END_ADDR_B_MAC_RAM_OFFS_BITS (19) +/* MAC_RX_END_ADDR_B field */ +#define MAC_RX_END_ADDR_B_MAC_RX_END_ADDR_B (0x00001FFEu) +#define MAC_RX_END_ADDR_B_MAC_RX_END_ADDR_B_MASK (0x00001FFEu) +#define MAC_RX_END_ADDR_B_MAC_RX_END_ADDR_B_BIT (1) +#define MAC_RX_END_ADDR_B_MAC_RX_END_ADDR_B_BITS (12) + +#define MAC_TX_ST_ADDR_A *((volatile uint32_t *)0x40002010u) +#define MAC_TX_ST_ADDR_A_REG *((volatile uint32_t *)0x40002010u) +#define MAC_TX_ST_ADDR_A_ADDR (0x40002010u) +#define MAC_TX_ST_ADDR_A_RESET (0x20000000u) +/* MAC_RAM_OFFS field */ +#define MAC_TX_ST_ADDR_A_MAC_RAM_OFFS (0xFFFFE000u) +#define MAC_TX_ST_ADDR_A_MAC_RAM_OFFS_MASK (0xFFFFE000u) +#define MAC_TX_ST_ADDR_A_MAC_RAM_OFFS_BIT (13) +#define MAC_TX_ST_ADDR_A_MAC_RAM_OFFS_BITS (19) +/* MAC_TX_ST_ADDR_A field */ +#define MAC_TX_ST_ADDR_A_MAC_TX_ST_ADDR_A (0x00001FFEu) +#define MAC_TX_ST_ADDR_A_MAC_TX_ST_ADDR_A_MASK (0x00001FFEu) +#define MAC_TX_ST_ADDR_A_MAC_TX_ST_ADDR_A_BIT (1) +#define MAC_TX_ST_ADDR_A_MAC_TX_ST_ADDR_A_BITS (12) + +#define MAC_TX_END_ADDR_A *((volatile uint32_t *)0x40002014u) +#define MAC_TX_END_ADDR_A_REG *((volatile uint32_t *)0x40002014u) +#define MAC_TX_END_ADDR_A_ADDR (0x40002014u) +#define MAC_TX_END_ADDR_A_RESET (0x20000000u) +/* MAC_RAM_OFFS field */ +#define MAC_TX_END_ADDR_A_MAC_RAM_OFFS (0xFFFFE000u) +#define MAC_TX_END_ADDR_A_MAC_RAM_OFFS_MASK (0xFFFFE000u) +#define MAC_TX_END_ADDR_A_MAC_RAM_OFFS_BIT (13) +#define MAC_TX_END_ADDR_A_MAC_RAM_OFFS_BITS (19) +/* MAC_TX_END_ADDR_A field */ +#define MAC_TX_END_ADDR_A_MAC_TX_END_ADDR_A (0x00001FFEu) +#define MAC_TX_END_ADDR_A_MAC_TX_END_ADDR_A_MASK (0x00001FFEu) +#define MAC_TX_END_ADDR_A_MAC_TX_END_ADDR_A_BIT (1) +#define MAC_TX_END_ADDR_A_MAC_TX_END_ADDR_A_BITS (12) + +#define MAC_TX_ST_ADDR_B *((volatile uint32_t *)0x40002018u) +#define MAC_TX_ST_ADDR_B_REG *((volatile uint32_t *)0x40002018u) +#define MAC_TX_ST_ADDR_B_ADDR (0x40002018u) +#define MAC_TX_ST_ADDR_B_RESET (0x20000000u) +/* MAC_RAM_OFFS field */ +#define MAC_TX_ST_ADDR_B_MAC_RAM_OFFS (0xFFFFE000u) +#define MAC_TX_ST_ADDR_B_MAC_RAM_OFFS_MASK (0xFFFFE000u) +#define MAC_TX_ST_ADDR_B_MAC_RAM_OFFS_BIT (13) +#define MAC_TX_ST_ADDR_B_MAC_RAM_OFFS_BITS (19) +/* MAC_TX_ST_ADDR_B field */ +#define MAC_TX_ST_ADDR_B_MAC_TX_ST_ADDR_B (0x00001FFEu) +#define MAC_TX_ST_ADDR_B_MAC_TX_ST_ADDR_B_MASK (0x00001FFEu) +#define MAC_TX_ST_ADDR_B_MAC_TX_ST_ADDR_B_BIT (1) +#define MAC_TX_ST_ADDR_B_MAC_TX_ST_ADDR_B_BITS (12) + +#define MAC_TX_END_ADDR_B *((volatile uint32_t *)0x4000201Cu) +#define MAC_TX_END_ADDR_B_REG *((volatile uint32_t *)0x4000201Cu) +#define MAC_TX_END_ADDR_B_ADDR (0x4000201Cu) +#define MAC_TX_END_ADDR_B_RESET (0x20000000u) +/* MAC_RAM_OFFS field */ +#define MAC_TX_END_ADDR_B_MAC_RAM_OFFS (0xFFFFE000u) +#define MAC_TX_END_ADDR_B_MAC_RAM_OFFS_MASK (0xFFFFE000u) +#define MAC_TX_END_ADDR_B_MAC_RAM_OFFS_BIT (13) +#define MAC_TX_END_ADDR_B_MAC_RAM_OFFS_BITS (19) +/* MAC_TX_END_ADDR_B field */ +#define MAC_TX_END_ADDR_B_MAC_TX_END_ADDR_B (0x00001FFEu) +#define MAC_TX_END_ADDR_B_MAC_TX_END_ADDR_B_MASK (0x00001FFEu) +#define MAC_TX_END_ADDR_B_MAC_TX_END_ADDR_B_BIT (1) +#define MAC_TX_END_ADDR_B_MAC_TX_END_ADDR_B_BITS (12) + +#define RX_A_COUNT *((volatile uint32_t *)0x40002020u) +#define RX_A_COUNT_REG *((volatile uint32_t *)0x40002020u) +#define RX_A_COUNT_ADDR (0x40002020u) +#define RX_A_COUNT_RESET (0x00000000u) +/* RX_A_COUNT field */ +#define RX_A_COUNT_RX_A_COUNT (0x000007FFu) +#define RX_A_COUNT_RX_A_COUNT_MASK (0x000007FFu) +#define RX_A_COUNT_RX_A_COUNT_BIT (0) +#define RX_A_COUNT_RX_A_COUNT_BITS (11) + +#define RX_B_COUNT *((volatile uint32_t *)0x40002024u) +#define RX_B_COUNT_REG *((volatile uint32_t *)0x40002024u) +#define RX_B_COUNT_ADDR (0x40002024u) +#define RX_B_COUNT_RESET (0x00000000u) +/* RX_B_COUNT field */ +#define RX_B_COUNT_RX_B_COUNT (0x000007FFu) +#define RX_B_COUNT_RX_B_COUNT_MASK (0x000007FFu) +#define RX_B_COUNT_RX_B_COUNT_BIT (0) +#define RX_B_COUNT_RX_B_COUNT_BITS (11) + +#define TX_COUNT *((volatile uint32_t *)0x40002028u) +#define TX_COUNT_REG *((volatile uint32_t *)0x40002028u) +#define TX_COUNT_ADDR (0x40002028u) +#define TX_COUNT_RESET (0x00000000u) +/* TX_COUNT field */ +#define TX_COUNT_TX_COUNT (0x000007FFu) +#define TX_COUNT_TX_COUNT_MASK (0x000007FFu) +#define TX_COUNT_TX_COUNT_BIT (0) +#define TX_COUNT_TX_COUNT_BITS (11) + +#define MAC_DMA_STATUS *((volatile uint32_t *)0x4000202Cu) +#define MAC_DMA_STATUS_REG *((volatile uint32_t *)0x4000202Cu) +#define MAC_DMA_STATUS_ADDR (0x4000202Cu) +#define MAC_DMA_STATUS_RESET (0x00000000u) +/* TX_ACTIVE_B field */ +#define MAC_DMA_STATUS_TX_ACTIVE_B (0x00000008u) +#define MAC_DMA_STATUS_TX_ACTIVE_B_MASK (0x00000008u) +#define MAC_DMA_STATUS_TX_ACTIVE_B_BIT (3) +#define MAC_DMA_STATUS_TX_ACTIVE_B_BITS (1) +/* TX_ACTIVE_A field */ +#define MAC_DMA_STATUS_TX_ACTIVE_A (0x00000004u) +#define MAC_DMA_STATUS_TX_ACTIVE_A_MASK (0x00000004u) +#define MAC_DMA_STATUS_TX_ACTIVE_A_BIT (2) +#define MAC_DMA_STATUS_TX_ACTIVE_A_BITS (1) +/* RX_ACTIVE_B field */ +#define MAC_DMA_STATUS_RX_ACTIVE_B (0x00000002u) +#define MAC_DMA_STATUS_RX_ACTIVE_B_MASK (0x00000002u) +#define MAC_DMA_STATUS_RX_ACTIVE_B_BIT (1) +#define MAC_DMA_STATUS_RX_ACTIVE_B_BITS (1) +/* RX_ACTIVE_A field */ +#define MAC_DMA_STATUS_RX_ACTIVE_A (0x00000001u) +#define MAC_DMA_STATUS_RX_ACTIVE_A_MASK (0x00000001u) +#define MAC_DMA_STATUS_RX_ACTIVE_A_BIT (0) +#define MAC_DMA_STATUS_RX_ACTIVE_A_BITS (1) + +#define MAC_DMA_CONFIG *((volatile uint32_t *)0x40002030u) +#define MAC_DMA_CONFIG_REG *((volatile uint32_t *)0x40002030u) +#define MAC_DMA_CONFIG_ADDR (0x40002030u) +#define MAC_DMA_CONFIG_RESET (0x00000000u) +/* TX_DMA_RESET field */ +#define MAC_DMA_CONFIG_TX_DMA_RESET (0x00000020u) +#define MAC_DMA_CONFIG_TX_DMA_RESET_MASK (0x00000020u) +#define MAC_DMA_CONFIG_TX_DMA_RESET_BIT (5) +#define MAC_DMA_CONFIG_TX_DMA_RESET_BITS (1) +/* RX_DMA_RESET field */ +#define MAC_DMA_CONFIG_RX_DMA_RESET (0x00000010u) +#define MAC_DMA_CONFIG_RX_DMA_RESET_MASK (0x00000010u) +#define MAC_DMA_CONFIG_RX_DMA_RESET_BIT (4) +#define MAC_DMA_CONFIG_RX_DMA_RESET_BITS (1) +/* TX_LOAD_B field */ +#define MAC_DMA_CONFIG_TX_LOAD_B (0x00000008u) +#define MAC_DMA_CONFIG_TX_LOAD_B_MASK (0x00000008u) +#define MAC_DMA_CONFIG_TX_LOAD_B_BIT (3) +#define MAC_DMA_CONFIG_TX_LOAD_B_BITS (1) +/* TX_LOAD_A field */ +#define MAC_DMA_CONFIG_TX_LOAD_A (0x00000004u) +#define MAC_DMA_CONFIG_TX_LOAD_A_MASK (0x00000004u) +#define MAC_DMA_CONFIG_TX_LOAD_A_BIT (2) +#define MAC_DMA_CONFIG_TX_LOAD_A_BITS (1) +/* RX_LOAD_B field */ +#define MAC_DMA_CONFIG_RX_LOAD_B (0x00000002u) +#define MAC_DMA_CONFIG_RX_LOAD_B_MASK (0x00000002u) +#define MAC_DMA_CONFIG_RX_LOAD_B_BIT (1) +#define MAC_DMA_CONFIG_RX_LOAD_B_BITS (1) +/* RX_LOAD_A field */ +#define MAC_DMA_CONFIG_RX_LOAD_A (0x00000001u) +#define MAC_DMA_CONFIG_RX_LOAD_A_MASK (0x00000001u) +#define MAC_DMA_CONFIG_RX_LOAD_A_BIT (0) +#define MAC_DMA_CONFIG_RX_LOAD_A_BITS (1) + +#define MAC_TIMER *((volatile uint32_t *)0x40002038u) +#define MAC_TIMER_REG *((volatile uint32_t *)0x40002038u) +#define MAC_TIMER_ADDR (0x40002038u) +#define MAC_TIMER_RESET (0x00000000u) +/* MAC_TIMER field */ +#define MAC_TIMER_MAC_TIMER (0x000FFFFFu) +#define MAC_TIMER_MAC_TIMER_MASK (0x000FFFFFu) +#define MAC_TIMER_MAC_TIMER_BIT (0) +#define MAC_TIMER_MAC_TIMER_BITS (20) + +#define MAC_TIMER_COMPARE_A_H *((volatile uint32_t *)0x40002040u) +#define MAC_TIMER_COMPARE_A_H_REG *((volatile uint32_t *)0x40002040u) +#define MAC_TIMER_COMPARE_A_H_ADDR (0x40002040u) +#define MAC_TIMER_COMPARE_A_H_RESET (0x00000000u) +/* MAC_COMPARE_A_H field */ +#define MAC_TIMER_COMPARE_A_H_MAC_COMPARE_A_H (0x0000000Fu) +#define MAC_TIMER_COMPARE_A_H_MAC_COMPARE_A_H_MASK (0x0000000Fu) +#define MAC_TIMER_COMPARE_A_H_MAC_COMPARE_A_H_BIT (0) +#define MAC_TIMER_COMPARE_A_H_MAC_COMPARE_A_H_BITS (4) + +#define MAC_TIMER_COMPARE_A_L *((volatile uint32_t *)0x40002044u) +#define MAC_TIMER_COMPARE_A_L_REG *((volatile uint32_t *)0x40002044u) +#define MAC_TIMER_COMPARE_A_L_ADDR (0x40002044u) +#define MAC_TIMER_COMPARE_A_L_RESET (0x00000000u) +/* MAC_COMPARE_A_L field */ +#define MAC_TIMER_COMPARE_A_L_MAC_COMPARE_A_L (0x0000FFFFu) +#define MAC_TIMER_COMPARE_A_L_MAC_COMPARE_A_L_MASK (0x0000FFFFu) +#define MAC_TIMER_COMPARE_A_L_MAC_COMPARE_A_L_BIT (0) +#define MAC_TIMER_COMPARE_A_L_MAC_COMPARE_A_L_BITS (16) + +#define MAC_TIMER_COMPARE_B_H *((volatile uint32_t *)0x40002048u) +#define MAC_TIMER_COMPARE_B_H_REG *((volatile uint32_t *)0x40002048u) +#define MAC_TIMER_COMPARE_B_H_ADDR (0x40002048u) +#define MAC_TIMER_COMPARE_B_H_RESET (0x00000000u) +/* MAC_COMPARE_B_H field */ +#define MAC_TIMER_COMPARE_B_H_MAC_COMPARE_B_H (0x0000000Fu) +#define MAC_TIMER_COMPARE_B_H_MAC_COMPARE_B_H_MASK (0x0000000Fu) +#define MAC_TIMER_COMPARE_B_H_MAC_COMPARE_B_H_BIT (0) +#define MAC_TIMER_COMPARE_B_H_MAC_COMPARE_B_H_BITS (4) + +#define MAC_TIMER_COMPARE_B_L *((volatile uint32_t *)0x4000204Cu) +#define MAC_TIMER_COMPARE_B_L_REG *((volatile uint32_t *)0x4000204Cu) +#define MAC_TIMER_COMPARE_B_L_ADDR (0x4000204Cu) +#define MAC_TIMER_COMPARE_B_L_RESET (0x00000000u) +/* MAC_COMPARE_B_L field */ +#define MAC_TIMER_COMPARE_B_L_MAC_COMPARE_B_L (0x0000FFFFu) +#define MAC_TIMER_COMPARE_B_L_MAC_COMPARE_B_L_MASK (0x0000FFFFu) +#define MAC_TIMER_COMPARE_B_L_MAC_COMPARE_B_L_BIT (0) +#define MAC_TIMER_COMPARE_B_L_MAC_COMPARE_B_L_BITS (16) + +#define MAC_TIMER_CAPTURE_H *((volatile uint32_t *)0x40002050u) +#define MAC_TIMER_CAPTURE_H_REG *((volatile uint32_t *)0x40002050u) +#define MAC_TIMER_CAPTURE_H_ADDR (0x40002050u) +#define MAC_TIMER_CAPTURE_H_RESET (0x00000000u) +/* MAC_SFD_CAPTURE_HIGH field */ +#define MAC_TIMER_CAPTURE_H_MAC_SFD_CAPTURE_HIGH (0x0000000Fu) +#define MAC_TIMER_CAPTURE_H_MAC_SFD_CAPTURE_HIGH_MASK (0x0000000Fu) +#define MAC_TIMER_CAPTURE_H_MAC_SFD_CAPTURE_HIGH_BIT (0) +#define MAC_TIMER_CAPTURE_H_MAC_SFD_CAPTURE_HIGH_BITS (4) + +#define MAC_TIMER_CAPTURE_L *((volatile uint32_t *)0x40002054u) +#define MAC_TIMER_CAPTURE_L_REG *((volatile uint32_t *)0x40002054u) +#define MAC_TIMER_CAPTURE_L_ADDR (0x40002054u) +#define MAC_TIMER_CAPTURE_L_RESET (0x00000000u) +/* MAC_SFD_CAPTURE_LOW field */ +#define MAC_TIMER_CAPTURE_L_MAC_SFD_CAPTURE_LOW (0x0000FFFFu) +#define MAC_TIMER_CAPTURE_L_MAC_SFD_CAPTURE_LOW_MASK (0x0000FFFFu) +#define MAC_TIMER_CAPTURE_L_MAC_SFD_CAPTURE_LOW_BIT (0) +#define MAC_TIMER_CAPTURE_L_MAC_SFD_CAPTURE_LOW_BITS (16) + +#define MAC_BO_TIMER *((volatile uint32_t *)0x40002058u) +#define MAC_BO_TIMER_REG *((volatile uint32_t *)0x40002058u) +#define MAC_BO_TIMER_ADDR (0x40002058u) +#define MAC_BO_TIMER_RESET (0x00000000u) +/* MAC_BO_TIMER field */ +#define MAC_BO_TIMER_MAC_BO_TIMER (0x00000FFFu) +#define MAC_BO_TIMER_MAC_BO_TIMER_MASK (0x00000FFFu) +#define MAC_BO_TIMER_MAC_BO_TIMER_BIT (0) +#define MAC_BO_TIMER_MAC_BO_TIMER_BITS (12) + +#define MAC_BOP_TIMER *((volatile uint32_t *)0x4000205Cu) +#define MAC_BOP_TIMER_REG *((volatile uint32_t *)0x4000205Cu) +#define MAC_BOP_TIMER_ADDR (0x4000205Cu) +#define MAC_BOP_TIMER_RESET (0x00000000u) +/* MAC_BOP_TIMER field */ +#define MAC_BOP_TIMER_MAC_BOP_TIMER (0x0000007Fu) +#define MAC_BOP_TIMER_MAC_BOP_TIMER_MASK (0x0000007Fu) +#define MAC_BOP_TIMER_MAC_BOP_TIMER_BIT (0) +#define MAC_BOP_TIMER_MAC_BOP_TIMER_BITS (7) + +#define MAC_TX_STROBE *((volatile uint32_t *)0x40002060u) +#define MAC_TX_STROBE_REG *((volatile uint32_t *)0x40002060u) +#define MAC_TX_STROBE_ADDR (0x40002060u) +#define MAC_TX_STROBE_RESET (0x00000000u) +/* AUTO_CRC_TX field */ +#define MAC_TX_STROBE_AUTO_CRC_TX (0x00000008u) +#define MAC_TX_STROBE_AUTO_CRC_TX_MASK (0x00000008u) +#define MAC_TX_STROBE_AUTO_CRC_TX_BIT (3) +#define MAC_TX_STROBE_AUTO_CRC_TX_BITS (1) +/* CCA_ON field */ +#define MAC_TX_STROBE_CCA_ON (0x00000004u) +#define MAC_TX_STROBE_CCA_ON_MASK (0x00000004u) +#define MAC_TX_STROBE_CCA_ON_BIT (2) +#define MAC_TX_STROBE_CCA_ON_BITS (1) +/* MAC_TX_RST field */ +#define MAC_TX_STROBE_MAC_TX_RST (0x00000002u) +#define MAC_TX_STROBE_MAC_TX_RST_MASK (0x00000002u) +#define MAC_TX_STROBE_MAC_TX_RST_BIT (1) +#define MAC_TX_STROBE_MAC_TX_RST_BITS (1) +/* START_TX field */ +#define MAC_TX_STROBE_START_TX (0x00000001u) +#define MAC_TX_STROBE_START_TX_MASK (0x00000001u) +#define MAC_TX_STROBE_START_TX_BIT (0) +#define MAC_TX_STROBE_START_TX_BITS (1) + +#define MAC_ACK_STROBE *((volatile uint32_t *)0x40002064u) +#define MAC_ACK_STROBE_REG *((volatile uint32_t *)0x40002064u) +#define MAC_ACK_STROBE_ADDR (0x40002064u) +#define MAC_ACK_STROBE_RESET (0x00000000u) +/* MANUAL_ACK field */ +#define MAC_ACK_STROBE_MANUAL_ACK (0x00000002u) +#define MAC_ACK_STROBE_MANUAL_ACK_MASK (0x00000002u) +#define MAC_ACK_STROBE_MANUAL_ACK_BIT (1) +#define MAC_ACK_STROBE_MANUAL_ACK_BITS (1) +/* FRAME_PENDING field */ +#define MAC_ACK_STROBE_FRAME_PENDING (0x00000001u) +#define MAC_ACK_STROBE_FRAME_PENDING_MASK (0x00000001u) +#define MAC_ACK_STROBE_FRAME_PENDING_BIT (0) +#define MAC_ACK_STROBE_FRAME_PENDING_BITS (1) + +#define MAC_STATUS *((volatile uint32_t *)0x40002068u) +#define MAC_STATUS_REG *((volatile uint32_t *)0x40002068u) +#define MAC_STATUS_ADDR (0x40002068u) +#define MAC_STATUS_RESET (0x00000000u) +/* RX_B_PEND_TX_ACK field */ +#define MAC_STATUS_RX_B_PEND_TX_ACK (0x00000800u) +#define MAC_STATUS_RX_B_PEND_TX_ACK_MASK (0x00000800u) +#define MAC_STATUS_RX_B_PEND_TX_ACK_BIT (11) +#define MAC_STATUS_RX_B_PEND_TX_ACK_BITS (1) +/* RX_A_PEND_TX_ACK field */ +#define MAC_STATUS_RX_A_PEND_TX_ACK (0x00000400u) +#define MAC_STATUS_RX_A_PEND_TX_ACK_MASK (0x00000400u) +#define MAC_STATUS_RX_A_PEND_TX_ACK_BIT (10) +#define MAC_STATUS_RX_A_PEND_TX_ACK_BITS (1) +/* RX_B_LAST_UNLOAD field */ +#define MAC_STATUS_RX_B_LAST_UNLOAD (0x00000200u) +#define MAC_STATUS_RX_B_LAST_UNLOAD_MASK (0x00000200u) +#define MAC_STATUS_RX_B_LAST_UNLOAD_BIT (9) +#define MAC_STATUS_RX_B_LAST_UNLOAD_BITS (1) +/* RX_A_LAST_UNLOAD field */ +#define MAC_STATUS_RX_A_LAST_UNLOAD (0x00000100u) +#define MAC_STATUS_RX_A_LAST_UNLOAD_MASK (0x00000100u) +#define MAC_STATUS_RX_A_LAST_UNLOAD_BIT (8) +#define MAC_STATUS_RX_A_LAST_UNLOAD_BITS (1) +/* WRONG_FORMAT field */ +#define MAC_STATUS_WRONG_FORMAT (0x00000080u) +#define MAC_STATUS_WRONG_FORMAT_MASK (0x00000080u) +#define MAC_STATUS_WRONG_FORMAT_BIT (7) +#define MAC_STATUS_WRONG_FORMAT_BITS (1) +/* WRONG_ADDRESS field */ +#define MAC_STATUS_WRONG_ADDRESS (0x00000040u) +#define MAC_STATUS_WRONG_ADDRESS_MASK (0x00000040u) +#define MAC_STATUS_WRONG_ADDRESS_BIT (6) +#define MAC_STATUS_WRONG_ADDRESS_BITS (1) +/* RX_ACK_REC field */ +#define MAC_STATUS_RX_ACK_REC (0x00000020u) +#define MAC_STATUS_RX_ACK_REC_MASK (0x00000020u) +#define MAC_STATUS_RX_ACK_REC_BIT (5) +#define MAC_STATUS_RX_ACK_REC_BITS (1) +/* SENDING_ACK field */ +#define MAC_STATUS_SENDING_ACK (0x00000010u) +#define MAC_STATUS_SENDING_ACK_MASK (0x00000010u) +#define MAC_STATUS_SENDING_ACK_BIT (4) +#define MAC_STATUS_SENDING_ACK_BITS (1) +/* RUN_BO field */ +#define MAC_STATUS_RUN_BO (0x00000008u) +#define MAC_STATUS_RUN_BO_MASK (0x00000008u) +#define MAC_STATUS_RUN_BO_BIT (3) +#define MAC_STATUS_RUN_BO_BITS (1) +/* TX_FRAME field */ +#define MAC_STATUS_TX_FRAME (0x00000004u) +#define MAC_STATUS_TX_FRAME_MASK (0x00000004u) +#define MAC_STATUS_TX_FRAME_BIT (2) +#define MAC_STATUS_TX_FRAME_BITS (1) +/* RX_FRAME field */ +#define MAC_STATUS_RX_FRAME (0x00000002u) +#define MAC_STATUS_RX_FRAME_MASK (0x00000002u) +#define MAC_STATUS_RX_FRAME_BIT (1) +#define MAC_STATUS_RX_FRAME_BITS (1) +/* RX_CRC_PASS field */ +#define MAC_STATUS_RX_CRC_PASS (0x00000001u) +#define MAC_STATUS_RX_CRC_PASS_MASK (0x00000001u) +#define MAC_STATUS_RX_CRC_PASS_BIT (0) +#define MAC_STATUS_RX_CRC_PASS_BITS (1) + +#define TX_CRC *((volatile uint32_t *)0x4000206Cu) +#define TX_CRC_REG *((volatile uint32_t *)0x4000206Cu) +#define TX_CRC_ADDR (0x4000206Cu) +#define TX_CRC_RESET (0x00000000u) +/* TX_CRC field */ +#define TX_CRC_TX_CRC (0x0000FFFFu) +#define TX_CRC_TX_CRC_MASK (0x0000FFFFu) +#define TX_CRC_TX_CRC_BIT (0) +#define TX_CRC_TX_CRC_BITS (16) + +#define RX_CRC *((volatile uint32_t *)0x40002070u) +#define RX_CRC_REG *((volatile uint32_t *)0x40002070u) +#define RX_CRC_ADDR (0x40002070u) +#define RX_CRC_RESET (0x00000000u) +/* RX_CRC field */ +#define RX_CRC_RX_CRC (0x0000FFFFu) +#define RX_CRC_RX_CRC_MASK (0x0000FFFFu) +#define RX_CRC_RX_CRC_BIT (0) +#define RX_CRC_RX_CRC_BITS (16) + +#define MAC_ACK_TO *((volatile uint32_t *)0x40002074u) +#define MAC_ACK_TO_REG *((volatile uint32_t *)0x40002074u) +#define MAC_ACK_TO_ADDR (0x40002074u) +#define MAC_ACK_TO_RESET (0x00000300u) +/* ACK_TO field */ +#define MAC_ACK_TO_ACK_TO (0x00003FFFu) +#define MAC_ACK_TO_ACK_TO_MASK (0x00003FFFu) +#define MAC_ACK_TO_ACK_TO_BIT (0) +#define MAC_ACK_TO_ACK_TO_BITS (14) + +#define MAC_BOP_COMPARE *((volatile uint32_t *)0x40002078u) +#define MAC_BOP_COMPARE_REG *((volatile uint32_t *)0x40002078u) +#define MAC_BOP_COMPARE_ADDR (0x40002078u) +#define MAC_BOP_COMPARE_RESET (0x00000014u) +/* MAC_BOP_COMPARE field */ +#define MAC_BOP_COMPARE_MAC_BOP_COMPARE (0x0000007Fu) +#define MAC_BOP_COMPARE_MAC_BOP_COMPARE_MASK (0x0000007Fu) +#define MAC_BOP_COMPARE_MAC_BOP_COMPARE_BIT (0) +#define MAC_BOP_COMPARE_MAC_BOP_COMPARE_BITS (7) + +#define MAC_TX_ACK_FRAME *((volatile uint32_t *)0x4000207Cu) +#define MAC_TX_ACK_FRAME_REG *((volatile uint32_t *)0x4000207Cu) +#define MAC_TX_ACK_FRAME_ADDR (0x4000207Cu) +#define MAC_TX_ACK_FRAME_RESET (0x00000002u) +/* ACK_SRC_AM field */ +#define MAC_TX_ACK_FRAME_ACK_SRC_AM (0x0000C000u) +#define MAC_TX_ACK_FRAME_ACK_SRC_AM_MASK (0x0000C000u) +#define MAC_TX_ACK_FRAME_ACK_SRC_AM_BIT (14) +#define MAC_TX_ACK_FRAME_ACK_SRC_AM_BITS (2) +/* RES1213 field */ +#define MAC_TX_ACK_FRAME_RES1213 (0x00003000u) +#define MAC_TX_ACK_FRAME_RES1213_MASK (0x00003000u) +#define MAC_TX_ACK_FRAME_RES1213_BIT (12) +#define MAC_TX_ACK_FRAME_RES1213_BITS (2) +/* ACK_DST_AM field */ +#define MAC_TX_ACK_FRAME_ACK_DST_AM (0x00000C00u) +#define MAC_TX_ACK_FRAME_ACK_DST_AM_MASK (0x00000C00u) +#define MAC_TX_ACK_FRAME_ACK_DST_AM_BIT (10) +#define MAC_TX_ACK_FRAME_ACK_DST_AM_BITS (2) +/* RES789 field */ +#define MAC_TX_ACK_FRAME_RES789 (0x00000380u) +#define MAC_TX_ACK_FRAME_RES789_MASK (0x00000380u) +#define MAC_TX_ACK_FRAME_RES789_BIT (7) +#define MAC_TX_ACK_FRAME_RES789_BITS (3) +/* ACK_IP field */ +#define MAC_TX_ACK_FRAME_ACK_IP (0x00000040u) +#define MAC_TX_ACK_FRAME_ACK_IP_MASK (0x00000040u) +#define MAC_TX_ACK_FRAME_ACK_IP_BIT (6) +#define MAC_TX_ACK_FRAME_ACK_IP_BITS (1) +/* ACK_ACK_REQ field */ +#define MAC_TX_ACK_FRAME_ACK_ACK_REQ (0x00000020u) +#define MAC_TX_ACK_FRAME_ACK_ACK_REQ_MASK (0x00000020u) +#define MAC_TX_ACK_FRAME_ACK_ACK_REQ_BIT (5) +#define MAC_TX_ACK_FRAME_ACK_ACK_REQ_BITS (1) +/* ACK_FRAME_P field */ +#define MAC_TX_ACK_FRAME_ACK_FRAME_P (0x00000010u) +#define MAC_TX_ACK_FRAME_ACK_FRAME_P_MASK (0x00000010u) +#define MAC_TX_ACK_FRAME_ACK_FRAME_P_BIT (4) +#define MAC_TX_ACK_FRAME_ACK_FRAME_P_BITS (1) +/* ACK_SEC_EN field */ +#define MAC_TX_ACK_FRAME_ACK_SEC_EN (0x00000008u) +#define MAC_TX_ACK_FRAME_ACK_SEC_EN_MASK (0x00000008u) +#define MAC_TX_ACK_FRAME_ACK_SEC_EN_BIT (3) +#define MAC_TX_ACK_FRAME_ACK_SEC_EN_BITS (1) +/* ACK_FRAME_T field */ +#define MAC_TX_ACK_FRAME_ACK_FRAME_T (0x00000007u) +#define MAC_TX_ACK_FRAME_ACK_FRAME_T_MASK (0x00000007u) +#define MAC_TX_ACK_FRAME_ACK_FRAME_T_BIT (0) +#define MAC_TX_ACK_FRAME_ACK_FRAME_T_BITS (3) + +#define MAC_CONFIG *((volatile uint32_t *)0x40002080u) +#define MAC_CONFIG_REG *((volatile uint32_t *)0x40002080u) +#define MAC_CONFIG_ADDR (0x40002080u) +#define MAC_CONFIG_RESET (0x00000000u) +/* RSSI_INST_EN field */ +#define MAC_CONFIG_RSSI_INST_EN (0x00000004u) +#define MAC_CONFIG_RSSI_INST_EN_MASK (0x00000004u) +#define MAC_CONFIG_RSSI_INST_EN_BIT (2) +#define MAC_CONFIG_RSSI_INST_EN_BITS (1) +/* SPI_SPY_EN field */ +#define MAC_CONFIG_SPI_SPY_EN (0x00000002u) +#define MAC_CONFIG_SPI_SPY_EN_MASK (0x00000002u) +#define MAC_CONFIG_SPI_SPY_EN_BIT (1) +#define MAC_CONFIG_SPI_SPY_EN_BITS (1) +/* MAC_MODE field */ +#define MAC_CONFIG_MAC_MODE (0x00000001u) +#define MAC_CONFIG_MAC_MODE_MASK (0x00000001u) +#define MAC_CONFIG_MAC_MODE_BIT (0) +#define MAC_CONFIG_MAC_MODE_BITS (1) + +#define MAC_RX_CONFIG *((volatile uint32_t *)0x40002084u) +#define MAC_RX_CONFIG_REG *((volatile uint32_t *)0x40002084u) +#define MAC_RX_CONFIG_ADDR (0x40002084u) +#define MAC_RX_CONFIG_RESET (0x00000000u) +/* AUTO_ACK field */ +#define MAC_RX_CONFIG_AUTO_ACK (0x00000080u) +#define MAC_RX_CONFIG_AUTO_ACK_MASK (0x00000080u) +#define MAC_RX_CONFIG_AUTO_ACK_BIT (7) +#define MAC_RX_CONFIG_AUTO_ACK_BITS (1) +/* APPEND_INFO field */ +#define MAC_RX_CONFIG_APPEND_INFO (0x00000040u) +#define MAC_RX_CONFIG_APPEND_INFO_MASK (0x00000040u) +#define MAC_RX_CONFIG_APPEND_INFO_BIT (6) +#define MAC_RX_CONFIG_APPEND_INFO_BITS (1) +/* COORDINATOR field */ +#define MAC_RX_CONFIG_COORDINATOR (0x00000020u) +#define MAC_RX_CONFIG_COORDINATOR_MASK (0x00000020u) +#define MAC_RX_CONFIG_COORDINATOR_BIT (5) +#define MAC_RX_CONFIG_COORDINATOR_BITS (1) +/* FILT_ADDR_ON field */ +#define MAC_RX_CONFIG_FILT_ADDR_ON (0x00000010u) +#define MAC_RX_CONFIG_FILT_ADDR_ON_MASK (0x00000010u) +#define MAC_RX_CONFIG_FILT_ADDR_ON_BIT (4) +#define MAC_RX_CONFIG_FILT_ADDR_ON_BITS (1) +/* RES_FILT_PASS_ADDR field */ +#define MAC_RX_CONFIG_RES_FILT_PASS_ADDR (0x00000008u) +#define MAC_RX_CONFIG_RES_FILT_PASS_ADDR_MASK (0x00000008u) +#define MAC_RX_CONFIG_RES_FILT_PASS_ADDR_BIT (3) +#define MAC_RX_CONFIG_RES_FILT_PASS_ADDR_BITS (1) +/* RES_FILT_PASS field */ +#define MAC_RX_CONFIG_RES_FILT_PASS (0x00000004u) +#define MAC_RX_CONFIG_RES_FILT_PASS_MASK (0x00000004u) +#define MAC_RX_CONFIG_RES_FILT_PASS_BIT (2) +#define MAC_RX_CONFIG_RES_FILT_PASS_BITS (1) +/* FILT_FORMAT_ON field */ +#define MAC_RX_CONFIG_FILT_FORMAT_ON (0x00000002u) +#define MAC_RX_CONFIG_FILT_FORMAT_ON_MASK (0x00000002u) +#define MAC_RX_CONFIG_FILT_FORMAT_ON_BIT (1) +#define MAC_RX_CONFIG_FILT_FORMAT_ON_BITS (1) +/* MAC_RX_RST field */ +#define MAC_RX_CONFIG_MAC_RX_RST (0x00000001u) +#define MAC_RX_CONFIG_MAC_RX_RST_MASK (0x00000001u) +#define MAC_RX_CONFIG_MAC_RX_RST_BIT (0) +#define MAC_RX_CONFIG_MAC_RX_RST_BITS (1) + +#define MAC_TX_CONFIG *((volatile uint32_t *)0x40002088u) +#define MAC_TX_CONFIG_REG *((volatile uint32_t *)0x40002088u) +#define MAC_TX_CONFIG_ADDR (0x40002088u) +#define MAC_TX_CONFIG_RESET (0x00000008u) +/* SLOTTED field */ +#define MAC_TX_CONFIG_SLOTTED (0x00000010u) +#define MAC_TX_CONFIG_SLOTTED_MASK (0x00000010u) +#define MAC_TX_CONFIG_SLOTTED_BIT (4) +#define MAC_TX_CONFIG_SLOTTED_BITS (1) +/* CCA_DELAY field */ +#define MAC_TX_CONFIG_CCA_DELAY (0x00000008u) +#define MAC_TX_CONFIG_CCA_DELAY_MASK (0x00000008u) +#define MAC_TX_CONFIG_CCA_DELAY_BIT (3) +#define MAC_TX_CONFIG_CCA_DELAY_BITS (1) +/* SLOTTED_ACK field */ +#define MAC_TX_CONFIG_SLOTTED_ACK (0x00000004u) +#define MAC_TX_CONFIG_SLOTTED_ACK_MASK (0x00000004u) +#define MAC_TX_CONFIG_SLOTTED_ACK_BIT (2) +#define MAC_TX_CONFIG_SLOTTED_ACK_BITS (1) +/* INFINITE_CRC field */ +#define MAC_TX_CONFIG_INFINITE_CRC (0x00000002u) +#define MAC_TX_CONFIG_INFINITE_CRC_MASK (0x00000002u) +#define MAC_TX_CONFIG_INFINITE_CRC_BIT (1) +#define MAC_TX_CONFIG_INFINITE_CRC_BITS (1) +/* WAIT_ACK field */ +#define MAC_TX_CONFIG_WAIT_ACK (0x00000001u) +#define MAC_TX_CONFIG_WAIT_ACK_MASK (0x00000001u) +#define MAC_TX_CONFIG_WAIT_ACK_BIT (0) +#define MAC_TX_CONFIG_WAIT_ACK_BITS (1) + +#define MAC_TIMER_CTRL *((volatile uint32_t *)0x4000208Cu) +#define MAC_TIMER_CTRL_REG *((volatile uint32_t *)0x4000208Cu) +#define MAC_TIMER_CTRL_ADDR (0x4000208Cu) +#define MAC_TIMER_CTRL_RESET (0x00000000u) +/* COMP_A_SYNC field */ +#define MAC_TIMER_CTRL_COMP_A_SYNC (0x00000040u) +#define MAC_TIMER_CTRL_COMP_A_SYNC_MASK (0x00000040u) +#define MAC_TIMER_CTRL_COMP_A_SYNC_BIT (6) +#define MAC_TIMER_CTRL_COMP_A_SYNC_BITS (1) +/* BOP_TIMER_RST field */ +#define MAC_TIMER_CTRL_BOP_TIMER_RST (0x00000020u) +#define MAC_TIMER_CTRL_BOP_TIMER_RST_MASK (0x00000020u) +#define MAC_TIMER_CTRL_BOP_TIMER_RST_BIT (5) +#define MAC_TIMER_CTRL_BOP_TIMER_RST_BITS (1) +/* BOP_TIMER_EN field */ +#define MAC_TIMER_CTRL_BOP_TIMER_EN (0x00000010u) +#define MAC_TIMER_CTRL_BOP_TIMER_EN_MASK (0x00000010u) +#define MAC_TIMER_CTRL_BOP_TIMER_EN_BIT (4) +#define MAC_TIMER_CTRL_BOP_TIMER_EN_BITS (1) +/* BO_TIMER_RST field */ +#define MAC_TIMER_CTRL_BO_TIMER_RST (0x00000008u) +#define MAC_TIMER_CTRL_BO_TIMER_RST_MASK (0x00000008u) +#define MAC_TIMER_CTRL_BO_TIMER_RST_BIT (3) +#define MAC_TIMER_CTRL_BO_TIMER_RST_BITS (1) +/* BO_TIMER_EN field */ +#define MAC_TIMER_CTRL_BO_TIMER_EN (0x00000004u) +#define MAC_TIMER_CTRL_BO_TIMER_EN_MASK (0x00000004u) +#define MAC_TIMER_CTRL_BO_TIMER_EN_BIT (2) +#define MAC_TIMER_CTRL_BO_TIMER_EN_BITS (1) +/* MAC_TIMER_RST field */ +#define MAC_TIMER_CTRL_MAC_TIMER_RST (0x00000002u) +#define MAC_TIMER_CTRL_MAC_TIMER_RST_MASK (0x00000002u) +#define MAC_TIMER_CTRL_MAC_TIMER_RST_BIT (1) +#define MAC_TIMER_CTRL_MAC_TIMER_RST_BITS (1) +/* MAC_TIMER_EN field */ +#define MAC_TIMER_CTRL_MAC_TIMER_EN (0x00000001u) +#define MAC_TIMER_CTRL_MAC_TIMER_EN_MASK (0x00000001u) +#define MAC_TIMER_CTRL_MAC_TIMER_EN_BIT (0) +#define MAC_TIMER_CTRL_MAC_TIMER_EN_BITS (1) + +#define PAN_ID *((volatile uint32_t *)0x40002090u) +#define PAN_ID_REG *((volatile uint32_t *)0x40002090u) +#define PAN_ID_ADDR (0x40002090u) +#define PAN_ID_RESET (0x00000000u) +/* PAN_ID field */ +#define PAN_ID_PAN_ID (0x0000FFFFu) +#define PAN_ID_PAN_ID_MASK (0x0000FFFFu) +#define PAN_ID_PAN_ID_BIT (0) +#define PAN_ID_PAN_ID_BITS (16) + +#define SHORT_ADDR *((volatile uint32_t *)0x40002094u) +#define SHORT_ADDR_REG *((volatile uint32_t *)0x40002094u) +#define SHORT_ADDR_ADDR (0x40002094u) +#define SHORT_ADDR_RESET (0x00000000u) +/* SHORT_ADDR field */ +#define SHORT_ADDR_SHORT_ADDR (0x0000FFFFu) +#define SHORT_ADDR_SHORT_ADDR_MASK (0x0000FFFFu) +#define SHORT_ADDR_SHORT_ADDR_BIT (0) +#define SHORT_ADDR_SHORT_ADDR_BITS (16) + +#define EXT_ADDR_0 *((volatile uint32_t *)0x40002098u) +#define EXT_ADDR_0_REG *((volatile uint32_t *)0x40002098u) +#define EXT_ADDR_0_ADDR (0x40002098u) +#define EXT_ADDR_0_RESET (0x00000000u) +/* EXT_ADDR_0 field */ +#define EXT_ADDR_0_EXT_ADDR_0 (0x0000FFFFu) +#define EXT_ADDR_0_EXT_ADDR_0_MASK (0x0000FFFFu) +#define EXT_ADDR_0_EXT_ADDR_0_BIT (0) +#define EXT_ADDR_0_EXT_ADDR_0_BITS (16) + +#define EXT_ADDR_1 *((volatile uint32_t *)0x4000209Cu) +#define EXT_ADDR_1_REG *((volatile uint32_t *)0x4000209Cu) +#define EXT_ADDR_1_ADDR (0x4000209Cu) +#define EXT_ADDR_1_RESET (0x00000000u) +/* EXT_ADDR_1 field */ +#define EXT_ADDR_1_EXT_ADDR_1 (0x0000FFFFu) +#define EXT_ADDR_1_EXT_ADDR_1_MASK (0x0000FFFFu) +#define EXT_ADDR_1_EXT_ADDR_1_BIT (0) +#define EXT_ADDR_1_EXT_ADDR_1_BITS (16) + +#define EXT_ADDR_2 *((volatile uint32_t *)0x400020A0u) +#define EXT_ADDR_2_REG *((volatile uint32_t *)0x400020A0u) +#define EXT_ADDR_2_ADDR (0x400020A0u) +#define EXT_ADDR_2_RESET (0x00000000u) +/* EXT_ADDR_2 field */ +#define EXT_ADDR_2_EXT_ADDR_2 (0x0000FFFFu) +#define EXT_ADDR_2_EXT_ADDR_2_MASK (0x0000FFFFu) +#define EXT_ADDR_2_EXT_ADDR_2_BIT (0) +#define EXT_ADDR_2_EXT_ADDR_2_BITS (16) + +#define EXT_ADDR_3 *((volatile uint32_t *)0x400020A4u) +#define EXT_ADDR_3_REG *((volatile uint32_t *)0x400020A4u) +#define EXT_ADDR_3_ADDR (0x400020A4u) +#define EXT_ADDR_3_RESET (0x00000000u) +/* EXT_ADDR_3 field */ +#define EXT_ADDR_3_EXT_ADDR_3 (0x0000FFFFu) +#define EXT_ADDR_3_EXT_ADDR_3_MASK (0x0000FFFFu) +#define EXT_ADDR_3_EXT_ADDR_3_BIT (0) +#define EXT_ADDR_3_EXT_ADDR_3_BITS (16) + +#define MAC_STATE *((volatile uint32_t *)0x400020A8u) +#define MAC_STATE_REG *((volatile uint32_t *)0x400020A8u) +#define MAC_STATE_ADDR (0x400020A8u) +#define MAC_STATE_RESET (0x00000000u) +/* SPY_STATE field */ +#define MAC_STATE_SPY_STATE (0x00000700u) +#define MAC_STATE_SPY_STATE_MASK (0x00000700u) +#define MAC_STATE_SPY_STATE_BIT (8) +#define MAC_STATE_SPY_STATE_BITS (3) +/* ACK_STATE field */ +#define MAC_STATE_ACK_STATE (0x000000C0u) +#define MAC_STATE_ACK_STATE_MASK (0x000000C0u) +#define MAC_STATE_ACK_STATE_BIT (6) +#define MAC_STATE_ACK_STATE_BITS (2) +/* BO_STATE field */ +#define MAC_STATE_BO_STATE (0x0000003Cu) +#define MAC_STATE_BO_STATE_MASK (0x0000003Cu) +#define MAC_STATE_BO_STATE_BIT (2) +#define MAC_STATE_BO_STATE_BITS (4) +/* TOP_STATE field */ +#define MAC_STATE_TOP_STATE (0x00000003u) +#define MAC_STATE_TOP_STATE_MASK (0x00000003u) +#define MAC_STATE_TOP_STATE_BIT (0) +#define MAC_STATE_TOP_STATE_BITS (2) + +#define RX_STATE *((volatile uint32_t *)0x400020ACu) +#define RX_STATE_REG *((volatile uint32_t *)0x400020ACu) +#define RX_STATE_ADDR (0x400020ACu) +#define RX_STATE_RESET (0x00000000u) +/* RX_BUFFER_STATE field */ +#define RX_STATE_RX_BUFFER_STATE (0x000001E0u) +#define RX_STATE_RX_BUFFER_STATE_MASK (0x000001E0u) +#define RX_STATE_RX_BUFFER_STATE_BIT (5) +#define RX_STATE_RX_BUFFER_STATE_BITS (4) +/* RX_TOP_STATE field */ +#define RX_STATE_RX_TOP_STATE (0x0000001Fu) +#define RX_STATE_RX_TOP_STATE_MASK (0x0000001Fu) +#define RX_STATE_RX_TOP_STATE_BIT (0) +#define RX_STATE_RX_TOP_STATE_BITS (5) + +#define TX_STATE *((volatile uint32_t *)0x400020B0u) +#define TX_STATE_REG *((volatile uint32_t *)0x400020B0u) +#define TX_STATE_ADDR (0x400020B0u) +#define TX_STATE_RESET (0x00000000u) +/* TX_BUFFER_STATE field */ +#define TX_STATE_TX_BUFFER_STATE (0x000000F0u) +#define TX_STATE_TX_BUFFER_STATE_MASK (0x000000F0u) +#define TX_STATE_TX_BUFFER_STATE_BIT (4) +#define TX_STATE_TX_BUFFER_STATE_BITS (4) +/* TX_TOP_STATE field */ +#define TX_STATE_TX_TOP_STATE (0x0000000Fu) +#define TX_STATE_TX_TOP_STATE_MASK (0x0000000Fu) +#define TX_STATE_TX_TOP_STATE_BIT (0) +#define TX_STATE_TX_TOP_STATE_BITS (4) + +#define DMA_STATE *((volatile uint32_t *)0x400020B4u) +#define DMA_STATE_REG *((volatile uint32_t *)0x400020B4u) +#define DMA_STATE_ADDR (0x400020B4u) +#define DMA_STATE_RESET (0x00000000u) +/* DMA_RX_STATE field */ +#define DMA_STATE_DMA_RX_STATE (0x00000038u) +#define DMA_STATE_DMA_RX_STATE_MASK (0x00000038u) +#define DMA_STATE_DMA_RX_STATE_BIT (3) +#define DMA_STATE_DMA_RX_STATE_BITS (3) +/* DMA_TX_STATE field */ +#define DMA_STATE_DMA_TX_STATE (0x00000007u) +#define DMA_STATE_DMA_TX_STATE_MASK (0x00000007u) +#define DMA_STATE_DMA_TX_STATE_BIT (0) +#define DMA_STATE_DMA_TX_STATE_BITS (3) + +#define MAC_DEBUG *((volatile uint32_t *)0x400020B8u) +#define MAC_DEBUG_REG *((volatile uint32_t *)0x400020B8u) +#define MAC_DEBUG_ADDR (0x400020B8u) +#define MAC_DEBUG_RESET (0x00000000u) +/* SW_DEBUG_OUT field */ +#define MAC_DEBUG_SW_DEBUG_OUT (0x00000060u) +#define MAC_DEBUG_SW_DEBUG_OUT_MASK (0x00000060u) +#define MAC_DEBUG_SW_DEBUG_OUT_BIT (5) +#define MAC_DEBUG_SW_DEBUG_OUT_BITS (2) +/* MAC_DEBUG_MUX field */ +#define MAC_DEBUG_MAC_DEBUG_MUX (0x0000001Fu) +#define MAC_DEBUG_MAC_DEBUG_MUX_MASK (0x0000001Fu) +#define MAC_DEBUG_MAC_DEBUG_MUX_BIT (0) +#define MAC_DEBUG_MAC_DEBUG_MUX_BITS (5) + +#define MAC_DEBUG_VIEW *((volatile uint32_t *)0x400020BCu) +#define MAC_DEBUG_VIEW_REG *((volatile uint32_t *)0x400020BCu) +#define MAC_DEBUG_VIEW_ADDR (0x400020BCu) +#define MAC_DEBUG_VIEW_RESET (0x00000010u) +/* MAC_DEBUG_VIEW field */ +#define MAC_DEBUG_VIEW_MAC_DEBUG_VIEW (0x0000FFFFu) +#define MAC_DEBUG_VIEW_MAC_DEBUG_VIEW_MASK (0x0000FFFFu) +#define MAC_DEBUG_VIEW_MAC_DEBUG_VIEW_BIT (0) +#define MAC_DEBUG_VIEW_MAC_DEBUG_VIEW_BITS (16) + +#define MAC_RSSI_DELAY *((volatile uint32_t *)0x400020C0u) +#define MAC_RSSI_DELAY_REG *((volatile uint32_t *)0x400020C0u) +#define MAC_RSSI_DELAY_ADDR (0x400020C0u) +#define MAC_RSSI_DELAY_RESET (0x00000000u) +/* RSSI_INST_DELAY_OK field */ +#define MAC_RSSI_DELAY_RSSI_INST_DELAY_OK (0x00000FC0u) +#define MAC_RSSI_DELAY_RSSI_INST_DELAY_OK_MASK (0x00000FC0u) +#define MAC_RSSI_DELAY_RSSI_INST_DELAY_OK_BIT (6) +#define MAC_RSSI_DELAY_RSSI_INST_DELAY_OK_BITS (6) +/* RSSI_INST_DELAY field */ +#define MAC_RSSI_DELAY_RSSI_INST_DELAY (0x0000003Fu) +#define MAC_RSSI_DELAY_RSSI_INST_DELAY_MASK (0x0000003Fu) +#define MAC_RSSI_DELAY_RSSI_INST_DELAY_BIT (0) +#define MAC_RSSI_DELAY_RSSI_INST_DELAY_BITS (6) + +#define PANID_COUNT *((volatile uint32_t *)0x400020C4u) +#define PANID_COUNT_REG *((volatile uint32_t *)0x400020C4u) +#define PANID_COUNT_ADDR (0x400020C4u) +#define PANID_COUNT_RESET (0x00000000u) +/* PANID_COUNT field */ +#define PANID_COUNT_PANID_COUNT (0x0000FFFFu) +#define PANID_COUNT_PANID_COUNT_MASK (0x0000FFFFu) +#define PANID_COUNT_PANID_COUNT_BIT (0) +#define PANID_COUNT_PANID_COUNT_BITS (16) + +#define NONPAN_COUNT *((volatile uint32_t *)0x400020C8u) +#define NONPAN_COUNT_REG *((volatile uint32_t *)0x400020C8u) +#define NONPAN_COUNT_ADDR (0x400020C8u) +#define NONPAN_COUNT_RESET (0x00000000u) +/* NONPAN_COUNT field */ +#define NONPAN_COUNT_NONPAN_COUNT (0x0000FFFFu) +#define NONPAN_COUNT_NONPAN_COUNT_MASK (0x0000FFFFu) +#define NONPAN_COUNT_NONPAN_COUNT_BIT (0) +#define NONPAN_COUNT_NONPAN_COUNT_BITS (16) + +/* SECURITY block */ +#define DATA_SECURITY_BASE (0x40003000u) +#define DATA_SECURITY_END (0x40003044u) +#define DATA_SECURITY_SIZE (DATA_SECURITY_END - DATA_SECURITY_BASE + 1) + +#define SECURITY_CONFIG *((volatile uint32_t *)0x40003000u) +#define SECURITY_CONFIG_REG *((volatile uint32_t *)0x40003000u) +#define SECURITY_CONFIG_ADDR (0x40003000u) +#define SECURITY_CONFIG_RESET (0x00000000u) +/* SEC_RST field */ +#define SECURITY_CONFIG_SEC_RST (0x00000080u) +#define SECURITY_CONFIG_SEC_RST_MASK (0x00000080u) +#define SECURITY_CONFIG_SEC_RST_BIT (7) +#define SECURITY_CONFIG_SEC_RST_BITS (1) +/* CTR_IN field */ +#define SECURITY_CONFIG_CTR_IN (0x00000040u) +#define SECURITY_CONFIG_CTR_IN_MASK (0x00000040u) +#define SECURITY_CONFIG_CTR_IN_BIT (6) +#define SECURITY_CONFIG_CTR_IN_BITS (1) +/* MIC_XOR_CT field */ +#define SECURITY_CONFIG_MIC_XOR_CT (0x00000020u) +#define SECURITY_CONFIG_MIC_XOR_CT_MASK (0x00000020u) +#define SECURITY_CONFIG_MIC_XOR_CT_BIT (5) +#define SECURITY_CONFIG_MIC_XOR_CT_BITS (1) +/* CBC_XOR_PT field */ +#define SECURITY_CONFIG_CBC_XOR_PT (0x00000010u) +#define SECURITY_CONFIG_CBC_XOR_PT_MASK (0x00000010u) +#define SECURITY_CONFIG_CBC_XOR_PT_BIT (4) +#define SECURITY_CONFIG_CBC_XOR_PT_BITS (1) +/* CT_TO_CBC_ST field */ +#define SECURITY_CONFIG_CT_TO_CBC_ST (0x00000008u) +#define SECURITY_CONFIG_CT_TO_CBC_ST_MASK (0x00000008u) +#define SECURITY_CONFIG_CT_TO_CBC_ST_BIT (3) +#define SECURITY_CONFIG_CT_TO_CBC_ST_BITS (1) +/* WAIT_CT_READ field */ +#define SECURITY_CONFIG_WAIT_CT_READ (0x00000004u) +#define SECURITY_CONFIG_WAIT_CT_READ_MASK (0x00000004u) +#define SECURITY_CONFIG_WAIT_CT_READ_BIT (2) +#define SECURITY_CONFIG_WAIT_CT_READ_BITS (1) +/* WAIT_PT_WRITE field */ +#define SECURITY_CONFIG_WAIT_PT_WRITE (0x00000002u) +#define SECURITY_CONFIG_WAIT_PT_WRITE_MASK (0x00000002u) +#define SECURITY_CONFIG_WAIT_PT_WRITE_BIT (1) +#define SECURITY_CONFIG_WAIT_PT_WRITE_BITS (1) +/* START_AES field */ +#define SECURITY_CONFIG_START_AES (0x00000001u) +#define SECURITY_CONFIG_START_AES_MASK (0x00000001u) +#define SECURITY_CONFIG_START_AES_BIT (0) +#define SECURITY_CONFIG_START_AES_BITS (1) + +#define SECURITY_STATUS *((volatile uint32_t *)0x40003004u) +#define SECURITY_STATUS_REG *((volatile uint32_t *)0x40003004u) +#define SECURITY_STATUS_ADDR (0x40003004u) +#define SECURITY_STATUS_RESET (0x00000000u) +/* SEC_BUSY field */ +#define SECURITY_STATUS_SEC_BUSY (0x00000001u) +#define SECURITY_STATUS_SEC_BUSY_MASK (0x00000001u) +#define SECURITY_STATUS_SEC_BUSY_BIT (0) +#define SECURITY_STATUS_SEC_BUSY_BITS (1) + +#define CBC_STATE_0 *((volatile uint32_t *)0x40003008u) +#define CBC_STATE_0_REG *((volatile uint32_t *)0x40003008u) +#define CBC_STATE_0_ADDR (0x40003008u) +#define CBC_STATE_0_RESET (0x00000000u) +/* CBC_STATE field */ +#define CBC_STATE_0_CBC_STATE (0xFFFFFFFFu) +#define CBC_STATE_0_CBC_STATE_MASK (0xFFFFFFFFu) +#define CBC_STATE_0_CBC_STATE_BIT (0) +#define CBC_STATE_0_CBC_STATE_BITS (32) + +#define CBC_STATE_1 *((volatile uint32_t *)0x4000300Cu) +#define CBC_STATE_1_REG *((volatile uint32_t *)0x4000300Cu) +#define CBC_STATE_1_ADDR (0x4000300Cu) +#define CBC_STATE_1_RESET (0x00000000u) +/* CBC_STATE_1 field */ +#define CBC_STATE_1_CBC_STATE_1 (0xFFFFFFFFu) +#define CBC_STATE_1_CBC_STATE_1_MASK (0xFFFFFFFFu) +#define CBC_STATE_1_CBC_STATE_1_BIT (0) +#define CBC_STATE_1_CBC_STATE_1_BITS (32) + +#define CBC_STATE_2 *((volatile uint32_t *)0x40003010u) +#define CBC_STATE_2_REG *((volatile uint32_t *)0x40003010u) +#define CBC_STATE_2_ADDR (0x40003010u) +#define CBC_STATE_2_RESET (0x00000000u) +/* CBC_STATE_2 field */ +#define CBC_STATE_2_CBC_STATE_2 (0xFFFFFFFFu) +#define CBC_STATE_2_CBC_STATE_2_MASK (0xFFFFFFFFu) +#define CBC_STATE_2_CBC_STATE_2_BIT (0) +#define CBC_STATE_2_CBC_STATE_2_BITS (32) + +#define CBC_STATE_3 *((volatile uint32_t *)0x40003014u) +#define CBC_STATE_3_REG *((volatile uint32_t *)0x40003014u) +#define CBC_STATE_3_ADDR (0x40003014u) +#define CBC_STATE_3_RESET (0x00000000u) +/* CBC_STATE_3 field */ +#define CBC_STATE_3_CBC_STATE_3 (0xFFFFFFFFu) +#define CBC_STATE_3_CBC_STATE_3_MASK (0xFFFFFFFFu) +#define CBC_STATE_3_CBC_STATE_3_BIT (0) +#define CBC_STATE_3_CBC_STATE_3_BITS (32) + +#define PT *((volatile uint32_t *)0x40003028u) +#define PT_REG *((volatile uint32_t *)0x40003028u) +#define PT_ADDR (0x40003028u) +#define PT_RESET (0x00000000u) +/* PT field */ +#define PT_PT (0xFFFFFFFFu) +#define PT_PT_MASK (0xFFFFFFFFu) +#define PT_PT_BIT (0) +#define PT_PT_BITS (32) + +#define CT *((volatile uint32_t *)0x40003030u) +#define CT_REG *((volatile uint32_t *)0x40003030u) +#define CT_ADDR (0x40003030u) +#define CT_RESET (0x00000000u) +/* CT field */ +#define CT_CT (0xFFFFFFFFu) +#define CT_CT_MASK (0xFFFFFFFFu) +#define CT_CT_BIT (0) +#define CT_CT_BITS (32) + +#define KEY_0 *((volatile uint32_t *)0x40003038u) +#define KEY_0_REG *((volatile uint32_t *)0x40003038u) +#define KEY_0_ADDR (0x40003038u) +#define KEY_0_RESET (0x00000000u) +/* KEY_O field */ +#define KEY_0_KEY_O (0xFFFFFFFFu) +#define KEY_0_KEY_O_MASK (0xFFFFFFFFu) +#define KEY_0_KEY_O_BIT (0) +#define KEY_0_KEY_O_BITS (32) + +#define KEY_1 *((volatile uint32_t *)0x4000303Cu) +#define KEY_1_REG *((volatile uint32_t *)0x4000303Cu) +#define KEY_1_ADDR (0x4000303Cu) +#define KEY_1_RESET (0x00000000u) +/* KEY_1 field */ +#define KEY_1_KEY_1 (0xFFFFFFFFu) +#define KEY_1_KEY_1_MASK (0xFFFFFFFFu) +#define KEY_1_KEY_1_BIT (0) +#define KEY_1_KEY_1_BITS (32) + +#define KEY_2 *((volatile uint32_t *)0x40003040u) +#define KEY_2_REG *((volatile uint32_t *)0x40003040u) +#define KEY_2_ADDR (0x40003040u) +#define KEY_2_RESET (0x00000000u) +/* KEY_2 field */ +#define KEY_2_KEY_2 (0xFFFFFFFFu) +#define KEY_2_KEY_2_MASK (0xFFFFFFFFu) +#define KEY_2_KEY_2_BIT (0) +#define KEY_2_KEY_2_BITS (32) + +#define KEY_3 *((volatile uint32_t *)0x40003044u) +#define KEY_3_REG *((volatile uint32_t *)0x40003044u) +#define KEY_3_ADDR (0x40003044u) +#define KEY_3_RESET (0x00000000u) +/* KEY_3 field */ +#define KEY_3_KEY_3 (0xFFFFFFFFu) +#define KEY_3_KEY_3_MASK (0xFFFFFFFFu) +#define KEY_3_KEY_3_BIT (0) +#define KEY_3_KEY_3_BITS (32) + +/* CM_LV block */ +#define BLOCK_CM_LV_BASE (0x40004000u) +#define BLOCK_CM_LV_END (0x40004034u) +#define BLOCK_CM_LV_SIZE (BLOCK_CM_LV_END - BLOCK_CM_LV_BASE + 1) + +#define SILICON_ID *((volatile uint32_t *)0x40004000u) +#define SILICON_ID_REG *((volatile uint32_t *)0x40004000u) +#define SILICON_ID_ADDR (0x40004000u) +#define SILICON_ID_RESET (0x069A862Bu) +/* HW_VERSION field */ +#define SILICON_ID_HW_VERSION (0xF0000000u) +#define SILICON_ID_HW_VERSION_MASK (0xF0000000u) +#define SILICON_ID_HW_VERSION_BIT (28) +#define SILICON_ID_HW_VERSION_BITS (4) +/* ST_DIVISION field */ +#define SILICON_ID_ST_DIVISION (0x0F000000u) +#define SILICON_ID_ST_DIVISION_MASK (0x0F000000u) +#define SILICON_ID_ST_DIVISION_BIT (24) +#define SILICON_ID_ST_DIVISION_BITS (4) +/* CHIP_TYPE field */ +#define SILICON_ID_CHIP_TYPE (0x00FF8000u) +#define SILICON_ID_CHIP_TYPE_MASK (0x00FF8000u) +#define SILICON_ID_CHIP_TYPE_BIT (15) +#define SILICON_ID_CHIP_TYPE_BITS (9) +/* SUB_TYPE field */ +#define SILICON_ID_SUB_TYPE (0x00007000u) +#define SILICON_ID_SUB_TYPE_MASK (0x00007000u) +#define SILICON_ID_SUB_TYPE_BIT (12) +#define SILICON_ID_SUB_TYPE_BITS (3) +/* JEDEC_MAN_ID field */ +#define SILICON_ID_JEDEC_MAN_ID (0x00000FFEu) +#define SILICON_ID_JEDEC_MAN_ID_MASK (0x00000FFEu) +#define SILICON_ID_JEDEC_MAN_ID_BIT (1) +#define SILICON_ID_JEDEC_MAN_ID_BITS (11) +/* ONE field */ +#define SILICON_ID_ONE (0x00000001u) +#define SILICON_ID_ONE_MASK (0x00000001u) +#define SILICON_ID_ONE_BIT (0) +#define SILICON_ID_ONE_BITS (1) + +#define OSC24M_BIASTRIM *((volatile uint32_t *)0x40004004u) +#define OSC24M_BIASTRIM_REG *((volatile uint32_t *)0x40004004u) +#define OSC24M_BIASTRIM_ADDR (0x40004004u) +#define OSC24M_BIASTRIM_RESET (0x0000000Fu) +/* OSC24M_BIAS_TRIM field */ +#define OSC24M_BIASTRIM_OSC24M_BIAS_TRIM (0x0000000Fu) +#define OSC24M_BIASTRIM_OSC24M_BIAS_TRIM_MASK (0x0000000Fu) +#define OSC24M_BIASTRIM_OSC24M_BIAS_TRIM_BIT (0) +#define OSC24M_BIASTRIM_OSC24M_BIAS_TRIM_BITS (4) + +#define OSCHF_TUNE *((volatile uint32_t *)0x40004008u) +#define OSCHF_TUNE_REG *((volatile uint32_t *)0x40004008u) +#define OSCHF_TUNE_ADDR (0x40004008u) +#define OSCHF_TUNE_RESET (0x00000017u) +/* OSCHF_TUNE_FIELD field */ +#define OSCHF_TUNE_FIELD (0x0000001Fu) +#define OSCHF_TUNE_FIELD_MASK (0x0000001Fu) +#define OSCHF_TUNE_FIELD_BIT (0) +#define OSCHF_TUNE_FIELD_BITS (5) + +#define OSC24M_COMP *((volatile uint32_t *)0x4000400Cu) +#define OSC24M_COMP_REG *((volatile uint32_t *)0x4000400Cu) +#define OSC24M_COMP_ADDR (0x4000400Cu) +#define OSC24M_COMP_RESET (0x00000000u) +/* OSC24M_HI field */ +#define OSC24M_HI (0x00000002u) +#define OSC24M_HI_MASK (0x00000002u) +#define OSC24M_HI_BIT (1) +#define OSC24M_HI_BITS (1) +/* OSC24M_LO field */ +#define OSC24M_LO (0x00000001u) +#define OSC24M_LO_MASK (0x00000001u) +#define OSC24M_LO_BIT (0) +#define OSC24M_LO_BITS (1) + +#define CLK_PERIODMODE *((volatile uint32_t *)0x40004010u) +#define CLK_PERIODMODE_REG *((volatile uint32_t *)0x40004010u) +#define CLK_PERIODMODE_ADDR (0x40004010u) +#define CLK_PERIODMODE_RESET (0x00000000u) +/* CLK_PERIODMODE_FIELD field */ +#define CLK_PERIODMODE_FIELD (0x00000003u) +#define CLK_PERIODMODE_FIELD_MASK (0x00000003u) +#define CLK_PERIODMODE_FIELD_BIT (0) +#define CLK_PERIODMODE_FIELD_BITS (2) + +#define CLK_PERIOD *((volatile uint32_t *)0x40004014u) +#define CLK_PERIOD_REG *((volatile uint32_t *)0x40004014u) +#define CLK_PERIOD_ADDR (0x40004014u) +#define CLK_PERIOD_RESET (0x00000000u) +/* CLK_PERIOD_FIELD field */ +#define CLK_PERIOD_FIELD (0x0000FFFFu) +#define CLK_PERIOD_FIELD_MASK (0x0000FFFFu) +#define CLK_PERIOD_FIELD_BIT (0) +#define CLK_PERIOD_FIELD_BITS (16) + +#define DITHER_DIS *((volatile uint32_t *)0x40004018u) +#define DITHER_DIS_REG *((volatile uint32_t *)0x40004018u) +#define DITHER_DIS_ADDR (0x40004018u) +#define DITHER_DIS_RESET (0x00000000u) +/* DITHER_DIS field */ +#define DITHER_DIS_DITHER_DIS (0x00000001u) +#define DITHER_DIS_DITHER_DIS_MASK (0x00000001u) +#define DITHER_DIS_DITHER_DIS_BIT (0) +#define DITHER_DIS_DITHER_DIS_BITS (1) + +#define OSC24M_CTRL *((volatile uint32_t *)0x4000401Cu) +#define OSC24M_CTRL_REG *((volatile uint32_t *)0x4000401Cu) +#define OSC24M_CTRL_ADDR (0x4000401Cu) +#define OSC24M_CTRL_RESET (0x00000000u) +/* OSC24M_EN field */ +#define OSC24M_CTRL_OSC24M_EN (0x00000002u) +#define OSC24M_CTRL_OSC24M_EN_MASK (0x00000002u) +#define OSC24M_CTRL_OSC24M_EN_BIT (1) +#define OSC24M_CTRL_OSC24M_EN_BITS (1) +/* OSC24M_SEL field */ +#define OSC24M_CTRL_OSC24M_SEL (0x00000001u) +#define OSC24M_CTRL_OSC24M_SEL_MASK (0x00000001u) +#define OSC24M_CTRL_OSC24M_SEL_BIT (0) +#define OSC24M_CTRL_OSC24M_SEL_BITS (1) + +#define CPU_CLKSEL *((volatile uint32_t *)0x40004020u) +#define CPU_CLKSEL_REG *((volatile uint32_t *)0x40004020u) +#define CPU_CLKSEL_ADDR (0x40004020u) +#define CPU_CLKSEL_RESET (0x00000000u) +/* CPU_CLKSEL_FIELD field */ +#define CPU_CLKSEL_FIELD (0x00000001u) +#define CPU_CLKSEL_FIELD_MASK (0x00000001u) +#define CPU_CLKSEL_FIELD_BIT (0) +#define CPU_CLKSEL_FIELD_BITS (1) + +#define BUS_FAULT *((volatile uint32_t *)0x40004024u) +#define BUS_FAULT_REG *((volatile uint32_t *)0x40004024u) +#define BUS_FAULT_ADDR (0x40004024u) +#define BUS_FAULT_RESET (0x00000000u) +/* WRONGSIZE field */ +#define BUS_FAULT_WRONGSIZE (0x00000008u) +#define BUS_FAULT_WRONGSIZE_MASK (0x00000008u) +#define BUS_FAULT_WRONGSIZE_BIT (3) +#define BUS_FAULT_WRONGSIZE_BITS (1) +/* PROTECTED field */ +#define BUS_FAULT_PROTECTED (0x00000004u) +#define BUS_FAULT_PROTECTED_MASK (0x00000004u) +#define BUS_FAULT_PROTECTED_BIT (2) +#define BUS_FAULT_PROTECTED_BITS (1) +/* RESERVED field */ +#define BUS_FAULT_RESERVED (0x00000002u) +#define BUS_FAULT_RESERVED_MASK (0x00000002u) +#define BUS_FAULT_RESERVED_BIT (1) +#define BUS_FAULT_RESERVED_BITS (1) +/* MISSED field */ +#define BUS_FAULT_MISSED (0x00000001u) +#define BUS_FAULT_MISSED_MASK (0x00000001u) +#define BUS_FAULT_MISSED_BIT (0) +#define BUS_FAULT_MISSED_BITS (1) + +#define PCTRACE_SEL *((volatile uint32_t *)0x40004028u) +#define PCTRACE_SEL_REG *((volatile uint32_t *)0x40004028u) +#define PCTRACE_SEL_ADDR (0x40004028u) +#define PCTRACE_SEL_RESET (0x00000000u) +/* PCTRACE_SEL_FIELD field */ +#define PCTRACE_SEL_FIELD (0x00000001u) +#define PCTRACE_SEL_FIELD_MASK (0x00000001u) +#define PCTRACE_SEL_FIELD_BIT (0) +#define PCTRACE_SEL_FIELD_BITS (1) + +#define FPEC_CLKREQ *((volatile uint32_t *)0x4000402Cu) +#define FPEC_CLKREQ_REG *((volatile uint32_t *)0x4000402Cu) +#define FPEC_CLKREQ_ADDR (0x4000402Cu) +#define FPEC_CLKREQ_RESET (0x00000000u) +/* FPEC_CLKREQ_FIELD field */ +#define FPEC_CLKREQ_FIELD (0x00000001u) +#define FPEC_CLKREQ_FIELD_MASK (0x00000001u) +#define FPEC_CLKREQ_FIELD_BIT (0) +#define FPEC_CLKREQ_FIELD_BITS (1) + +#define FPEC_CLKSTAT *((volatile uint32_t *)0x40004030u) +#define FPEC_CLKSTAT_REG *((volatile uint32_t *)0x40004030u) +#define FPEC_CLKSTAT_ADDR (0x40004030u) +#define FPEC_CLKSTAT_RESET (0x00000000u) +/* FPEC_CLKBSY field */ +#define FPEC_CLKBSY (0x00000002u) +#define FPEC_CLKBSY_MASK (0x00000002u) +#define FPEC_CLKBSY_BIT (1) +#define FPEC_CLKBSY_BITS (1) +/* FPEC_CLKACK field */ +#define FPEC_CLKACK (0x00000001u) +#define FPEC_CLKACK_MASK (0x00000001u) +#define FPEC_CLKACK_BIT (0) +#define FPEC_CLKACK_BITS (1) + +#define LV_SPARE *((volatile uint32_t *)0x40004034u) +#define LV_SPARE_REG *((volatile uint32_t *)0x40004034u) +#define LV_SPARE_ADDR (0x40004034u) +#define LV_SPARE_RESET (0x00000000u) +/* LV_SPARE field */ +#define LV_SPARE_LV_SPARE (0x000000FFu) +#define LV_SPARE_LV_SPARE_MASK (0x000000FFu) +#define LV_SPARE_LV_SPARE_BIT (0) +#define LV_SPARE_LV_SPARE_BITS (8) + +/* RAM_CTRL block */ +#define DATA_RAM_CTRL_BASE (0x40005000u) +#define DATA_RAM_CTRL_END (0x40005028u) +#define DATA_RAM_CTRL_SIZE (DATA_RAM_CTRL_END - DATA_RAM_CTRL_BASE + 1) + +#define MEM_PROT_0 *((volatile uint32_t *)0x40005000u) +#define MEM_PROT_0_REG *((volatile uint32_t *)0x40005000u) +#define MEM_PROT_0_ADDR (0x40005000u) +#define MEM_PROT_0_RESET (0x00000000u) +/* MEM_PROT_0 field */ +#define MEM_PROT_0_MEM_PROT_0 (0xFFFFFFFFu) +#define MEM_PROT_0_MEM_PROT_0_MASK (0xFFFFFFFFu) +#define MEM_PROT_0_MEM_PROT_0_BIT (0) +#define MEM_PROT_0_MEM_PROT_0_BITS (32) + +#define MEM_PROT_1 *((volatile uint32_t *)0x40005004u) +#define MEM_PROT_1_REG *((volatile uint32_t *)0x40005004u) +#define MEM_PROT_1_ADDR (0x40005004u) +#define MEM_PROT_1_RESET (0x00000000u) +/* MEM_PROT_1 field */ +#define MEM_PROT_1_MEM_PROT_1 (0xFFFFFFFFu) +#define MEM_PROT_1_MEM_PROT_1_MASK (0xFFFFFFFFu) +#define MEM_PROT_1_MEM_PROT_1_BIT (0) +#define MEM_PROT_1_MEM_PROT_1_BITS (32) + +#define MEM_PROT_2 *((volatile uint32_t *)0x40005008u) +#define MEM_PROT_2_REG *((volatile uint32_t *)0x40005008u) +#define MEM_PROT_2_ADDR (0x40005008u) +#define MEM_PROT_2_RESET (0x00000000u) +/* MEM_PROT_2 field */ +#define MEM_PROT_2_MEM_PROT_2 (0xFFFFFFFFu) +#define MEM_PROT_2_MEM_PROT_2_MASK (0xFFFFFFFFu) +#define MEM_PROT_2_MEM_PROT_2_BIT (0) +#define MEM_PROT_2_MEM_PROT_2_BITS (32) + +#define MEM_PROT_3 *((volatile uint32_t *)0x4000500Cu) +#define MEM_PROT_3_REG *((volatile uint32_t *)0x4000500Cu) +#define MEM_PROT_3_ADDR (0x4000500Cu) +#define MEM_PROT_3_RESET (0x00000000u) +/* MEM_PROT_3 field */ +#define MEM_PROT_3_MEM_PROT_3 (0xFFFFFFFFu) +#define MEM_PROT_3_MEM_PROT_3_MASK (0xFFFFFFFFu) +#define MEM_PROT_3_MEM_PROT_3_BIT (0) +#define MEM_PROT_3_MEM_PROT_3_BITS (32) + +#define MEM_PROT_4 *((volatile uint32_t *)0x40005010u) +#define MEM_PROT_4_REG *((volatile uint32_t *)0x40005010u) +#define MEM_PROT_4_ADDR (0x40005010u) +#define MEM_PROT_4_RESET (0x00000000u) +/* MEM_PROT_4 field */ +#define MEM_PROT_4_MEM_PROT_4 (0xFFFFFFFFu) +#define MEM_PROT_4_MEM_PROT_4_MASK (0xFFFFFFFFu) +#define MEM_PROT_4_MEM_PROT_4_BIT (0) +#define MEM_PROT_4_MEM_PROT_4_BITS (32) + +#define MEM_PROT_5 *((volatile uint32_t *)0x40005014u) +#define MEM_PROT_5_REG *((volatile uint32_t *)0x40005014u) +#define MEM_PROT_5_ADDR (0x40005014u) +#define MEM_PROT_5_RESET (0x00000000u) +/* MEM_PROT_5 field */ +#define MEM_PROT_5_MEM_PROT_5 (0xFFFFFFFFu) +#define MEM_PROT_5_MEM_PROT_5_MASK (0xFFFFFFFFu) +#define MEM_PROT_5_MEM_PROT_5_BIT (0) +#define MEM_PROT_5_MEM_PROT_5_BITS (32) + +#define MEM_PROT_6 *((volatile uint32_t *)0x40005018u) +#define MEM_PROT_6_REG *((volatile uint32_t *)0x40005018u) +#define MEM_PROT_6_ADDR (0x40005018u) +#define MEM_PROT_6_RESET (0x00000000u) +/* MEM_PROT_6 field */ +#define MEM_PROT_6_MEM_PROT_6 (0xFFFFFFFFu) +#define MEM_PROT_6_MEM_PROT_6_MASK (0xFFFFFFFFu) +#define MEM_PROT_6_MEM_PROT_6_BIT (0) +#define MEM_PROT_6_MEM_PROT_6_BITS (32) + +#define MEM_PROT_7 *((volatile uint32_t *)0x4000501Cu) +#define MEM_PROT_7_REG *((volatile uint32_t *)0x4000501Cu) +#define MEM_PROT_7_ADDR (0x4000501Cu) +#define MEM_PROT_7_RESET (0x00000000u) +/* MEM_PROT_7 field */ +#define MEM_PROT_7_MEM_PROT_7 (0xFFFFFFFFu) +#define MEM_PROT_7_MEM_PROT_7_MASK (0xFFFFFFFFu) +#define MEM_PROT_7_MEM_PROT_7_BIT (0) +#define MEM_PROT_7_MEM_PROT_7_BITS (32) + +#define DMA_PROT_ADDR *((volatile uint32_t *)0x40005020u) +#define DMA_PROT_ADDR_REG *((volatile uint32_t *)0x40005020u) +#define DMA_PROT_ADDR_ADDR (0x40005020u) +#define DMA_PROT_ADDR_RESET (0x20000000u) +/* DMA_PROT_OFFS field */ +#define DMA_PROT_ADDR_DMA_PROT_OFFS (0xFFFFE000u) +#define DMA_PROT_ADDR_DMA_PROT_OFFS_MASK (0xFFFFE000u) +#define DMA_PROT_ADDR_DMA_PROT_OFFS_BIT (13) +#define DMA_PROT_ADDR_DMA_PROT_OFFS_BITS (19) +/* DMA_PROT_ADDR field */ +#define DMA_PROT_ADDR_DMA_PROT_ADDR (0x00001FFFu) +#define DMA_PROT_ADDR_DMA_PROT_ADDR_MASK (0x00001FFFu) +#define DMA_PROT_ADDR_DMA_PROT_ADDR_BIT (0) +#define DMA_PROT_ADDR_DMA_PROT_ADDR_BITS (13) + +#define DMA_PROT_CH *((volatile uint32_t *)0x40005024u) +#define DMA_PROT_CH_REG *((volatile uint32_t *)0x40005024u) +#define DMA_PROT_CH_ADDR (0x40005024u) +#define DMA_PROT_CH_RESET (0x00000000u) +/* DMA_PROT_CH field */ +#define DMA_PROT_CH_DMA_PROT_CH (0x00000007u) +#define DMA_PROT_CH_DMA_PROT_CH_MASK (0x00000007u) +#define DMA_PROT_CH_DMA_PROT_CH_BIT (0) +#define DMA_PROT_CH_DMA_PROT_CH_BITS (3) + +#define MEM_PROT_EN *((volatile uint32_t *)0x40005028u) +#define MEM_PROT_EN_REG *((volatile uint32_t *)0x40005028u) +#define MEM_PROT_EN_ADDR (0x40005028u) +#define MEM_PROT_EN_RESET (0x00000000u) +/* FORCE_PROT field */ +#define MEM_PROT_EN_FORCE_PROT (0x00000004u) +#define MEM_PROT_EN_FORCE_PROT_MASK (0x00000004u) +#define MEM_PROT_EN_FORCE_PROT_BIT (2) +#define MEM_PROT_EN_FORCE_PROT_BITS (1) +/* DMA_PROT_EN_MAC field */ +#define MEM_PROT_EN_DMA_PROT_EN_MAC (0x00000002u) +#define MEM_PROT_EN_DMA_PROT_EN_MAC_MASK (0x00000002u) +#define MEM_PROT_EN_DMA_PROT_EN_MAC_BIT (1) +#define MEM_PROT_EN_DMA_PROT_EN_MAC_BITS (1) +/* DMA_PROT_EN_OTHER field */ +#define MEM_PROT_EN_DMA_PROT_EN_OTHER (0x00000001u) +#define MEM_PROT_EN_DMA_PROT_EN_OTHER_MASK (0x00000001u) +#define MEM_PROT_EN_DMA_PROT_EN_OTHER_BIT (0) +#define MEM_PROT_EN_DMA_PROT_EN_OTHER_BITS (1) + +/* SLOW_TIMERS block */ +#define DATA_SLOW_TIMERS_BASE (0x40006000u) +#define DATA_SLOW_TIMERS_END (0x40006024u) +#define DATA_SLOW_TIMERS_SIZE (DATA_SLOW_TIMERS_END - DATA_SLOW_TIMERS_BASE + 1) + +#define WDOG_CFG *((volatile uint32_t *)0x40006000u) +#define WDOG_CFG_REG *((volatile uint32_t *)0x40006000u) +#define WDOG_CFG_ADDR (0x40006000u) +#define WDOG_CFG_RESET (0x00000002u) +/* WDOG_DISABLE field */ +#define WDOG_DISABLE (0x00000002u) +#define WDOG_DISABLE_MASK (0x00000002u) +#define WDOG_DISABLE_BIT (1) +#define WDOG_DISABLE_BITS (1) +/* WDOG_ENABLE field */ +#define WDOG_ENABLE (0x00000001u) +#define WDOG_ENABLE_MASK (0x00000001u) +#define WDOG_ENABLE_BIT (0) +#define WDOG_ENABLE_BITS (1) + +#define WDOG_KEY *((volatile uint32_t *)0x40006004u) +#define WDOG_KEY_REG *((volatile uint32_t *)0x40006004u) +#define WDOG_KEY_ADDR (0x40006004u) +#define WDOG_KEY_RESET (0x00000000u) +/* WDOG_KEY_FIELD field */ +#define WDOG_KEY_FIELD (0x0000FFFFu) +#define WDOG_KEY_FIELD_MASK (0x0000FFFFu) +#define WDOG_KEY_FIELD_BIT (0) +#define WDOG_KEY_FIELD_BITS (16) + +#define WDOG_RESET *((volatile uint32_t *)0x40006008u) +#define WDOG_RESET_REG *((volatile uint32_t *)0x40006008u) +#define WDOG_RESET_ADDR (0x40006008u) +#define WDOG_RESET_RESET (0x00000000u) + +#define SLEEPTMR_CFG *((volatile uint32_t *)0x4000600Cu) +#define SLEEPTMR_CFG_REG *((volatile uint32_t *)0x4000600Cu) +#define SLEEPTMR_CFG_ADDR (0x4000600Cu) +#define SLEEPTMR_CFG_RESET (0x00000400u) +/* SLEEPTMR_REVERSE field */ +#define SLEEPTMR_REVERSE (0x00001000u) +#define SLEEPTMR_REVERSE_MASK (0x00001000u) +#define SLEEPTMR_REVERSE_BIT (12) +#define SLEEPTMR_REVERSE_BITS (1) +/* SLEEPTMR_ENABLE field */ +#define SLEEPTMR_ENABLE (0x00000800u) +#define SLEEPTMR_ENABLE_MASK (0x00000800u) +#define SLEEPTMR_ENABLE_BIT (11) +#define SLEEPTMR_ENABLE_BITS (1) +/* SLEEPTMR_DBGPAUSE field */ +#define SLEEPTMR_DBGPAUSE (0x00000400u) +#define SLEEPTMR_DBGPAUSE_MASK (0x00000400u) +#define SLEEPTMR_DBGPAUSE_BIT (10) +#define SLEEPTMR_DBGPAUSE_BITS (1) +/* SLEEPTMR_CLKDIV field */ +#define SLEEPTMR_CLKDIV (0x000000F0u) +#define SLEEPTMR_CLKDIV_MASK (0x000000F0u) +#define SLEEPTMR_CLKDIV_BIT (4) +#define SLEEPTMR_CLKDIV_BITS (4) +/* SLEEPTMR_CLKSEL field */ +#define SLEEPTMR_CLKSEL (0x00000001u) +#define SLEEPTMR_CLKSEL_MASK (0x00000001u) +#define SLEEPTMR_CLKSEL_BIT (0) +#define SLEEPTMR_CLKSEL_BITS (1) + +#define SLEEPTMR_CNTH *((volatile uint32_t *)0x40006010u) +#define SLEEPTMR_CNTH_REG *((volatile uint32_t *)0x40006010u) +#define SLEEPTMR_CNTH_ADDR (0x40006010u) +#define SLEEPTMR_CNTH_RESET (0x00000000u) +/* SLEEPTMR_CNTH_FIELD field */ +#define SLEEPTMR_CNTH_FIELD (0x0000FFFFu) +#define SLEEPTMR_CNTH_FIELD_MASK (0x0000FFFFu) +#define SLEEPTMR_CNTH_FIELD_BIT (0) +#define SLEEPTMR_CNTH_FIELD_BITS (16) + +#define SLEEPTMR_CNTL *((volatile uint32_t *)0x40006014u) +#define SLEEPTMR_CNTL_REG *((volatile uint32_t *)0x40006014u) +#define SLEEPTMR_CNTL_ADDR (0x40006014u) +#define SLEEPTMR_CNTL_RESET (0x00000000u) +/* SLEEPTMR_CNTL_FIELD field */ +#define SLEEPTMR_CNTL_FIELD (0x0000FFFFu) +#define SLEEPTMR_CNTL_FIELD_MASK (0x0000FFFFu) +#define SLEEPTMR_CNTL_FIELD_BIT (0) +#define SLEEPTMR_CNTL_FIELD_BITS (16) + +#define SLEEPTMR_CMPAH *((volatile uint32_t *)0x40006018u) +#define SLEEPTMR_CMPAH_REG *((volatile uint32_t *)0x40006018u) +#define SLEEPTMR_CMPAH_ADDR (0x40006018u) +#define SLEEPTMR_CMPAH_RESET (0x0000FFFFu) +/* SLEEPTMR_CMPAH_FIELD field */ +#define SLEEPTMR_CMPAH_FIELD (0x0000FFFFu) +#define SLEEPTMR_CMPAH_FIELD_MASK (0x0000FFFFu) +#define SLEEPTMR_CMPAH_FIELD_BIT (0) +#define SLEEPTMR_CMPAH_FIELD_BITS (16) + +#define SLEEPTMR_CMPAL *((volatile uint32_t *)0x4000601Cu) +#define SLEEPTMR_CMPAL_REG *((volatile uint32_t *)0x4000601Cu) +#define SLEEPTMR_CMPAL_ADDR (0x4000601Cu) +#define SLEEPTMR_CMPAL_RESET (0x0000FFFFu) +/* SLEEPTMR_CMPAL_FIELD field */ +#define SLEEPTMR_CMPAL_FIELD (0x0000FFFFu) +#define SLEEPTMR_CMPAL_FIELD_MASK (0x0000FFFFu) +#define SLEEPTMR_CMPAL_FIELD_BIT (0) +#define SLEEPTMR_CMPAL_FIELD_BITS (16) + +#define SLEEPTMR_CMPBH *((volatile uint32_t *)0x40006020u) +#define SLEEPTMR_CMPBH_REG *((volatile uint32_t *)0x40006020u) +#define SLEEPTMR_CMPBH_ADDR (0x40006020u) +#define SLEEPTMR_CMPBH_RESET (0x0000FFFFu) +/* SLEEPTMR_CMPBH_FIELD field */ +#define SLEEPTMR_CMPBH_FIELD (0x0000FFFFu) +#define SLEEPTMR_CMPBH_FIELD_MASK (0x0000FFFFu) +#define SLEEPTMR_CMPBH_FIELD_BIT (0) +#define SLEEPTMR_CMPBH_FIELD_BITS (16) + +#define SLEEPTMR_CMPBL *((volatile uint32_t *)0x40006024u) +#define SLEEPTMR_CMPBL_REG *((volatile uint32_t *)0x40006024u) +#define SLEEPTMR_CMPBL_ADDR (0x40006024u) +#define SLEEPTMR_CMPBL_RESET (0x0000FFFFu) +/* SLEEPTMR_CMPBL_FIELD field */ +#define SLEEPTMR_CMPBL_FIELD (0x0000FFFFu) +#define SLEEPTMR_CMPBL_FIELD_MASK (0x0000FFFFu) +#define SLEEPTMR_CMPBL_FIELD_BIT (0) +#define SLEEPTMR_CMPBL_FIELD_BITS (16) + +/* CAL_ADC block */ +#define DATA_CAL_ADC_BASE (0x40007000u) +#define DATA_CAL_ADC_END (0x40007004u) +#define DATA_CAL_ADC_SIZE (DATA_CAL_ADC_END - DATA_CAL_ADC_BASE + 1) + +#define CAL_ADC_DATA *((volatile uint32_t *)0x40007000u) +#define CAL_ADC_DATA_REG *((volatile uint32_t *)0x40007000u) +#define CAL_ADC_DATA_ADDR (0x40007000u) +#define CAL_ADC_DATA_RESET (0x00000000u) +/* CAL_ADC_DATA field */ +#define CAL_ADC_DATA_CAL_ADC_DATA (0x0000FFFFu) +#define CAL_ADC_DATA_CAL_ADC_DATA_MASK (0x0000FFFFu) +#define CAL_ADC_DATA_CAL_ADC_DATA_BIT (0) +#define CAL_ADC_DATA_CAL_ADC_DATA_BITS (16) + +#define CAL_ADC_CONFIG *((volatile uint32_t *)0x40007004u) +#define CAL_ADC_CONFIG_REG *((volatile uint32_t *)0x40007004u) +#define CAL_ADC_CONFIG_ADDR (0x40007004u) +#define CAL_ADC_CONFIG_RESET (0x00000000u) +/* CAL_ADC_RATE field */ +#define CAL_ADC_CONFIG_CAL_ADC_RATE (0x00007000u) +#define CAL_ADC_CONFIG_CAL_ADC_RATE_MASK (0x00007000u) +#define CAL_ADC_CONFIG_CAL_ADC_RATE_BIT (12) +#define CAL_ADC_CONFIG_CAL_ADC_RATE_BITS (3) +/* CAL_ADC_MUX field */ +#define CAL_ADC_CONFIG_CAL_ADC_MUX (0x00000F80u) +#define CAL_ADC_CONFIG_CAL_ADC_MUX_MASK (0x00000F80u) +#define CAL_ADC_CONFIG_CAL_ADC_MUX_BIT (7) +#define CAL_ADC_CONFIG_CAL_ADC_MUX_BITS (5) +/* CAL_ADC_CLKSEL field */ +#define CAL_ADC_CONFIG_CAL_ADC_CLKSEL (0x00000004u) +#define CAL_ADC_CONFIG_CAL_ADC_CLKSEL_MASK (0x00000004u) +#define CAL_ADC_CONFIG_CAL_ADC_CLKSEL_BIT (2) +#define CAL_ADC_CONFIG_CAL_ADC_CLKSEL_BITS (1) +/* CAL_ADC_DITHER_DIS field */ +#define CAL_ADC_CONFIG_CAL_ADC_DITHER_DIS (0x00000002u) +#define CAL_ADC_CONFIG_CAL_ADC_DITHER_DIS_MASK (0x00000002u) +#define CAL_ADC_CONFIG_CAL_ADC_DITHER_DIS_BIT (1) +#define CAL_ADC_CONFIG_CAL_ADC_DITHER_DIS_BITS (1) +/* CAL_ADC_EN field */ +#define CAL_ADC_CONFIG_CAL_ADC_EN (0x00000001u) +#define CAL_ADC_CONFIG_CAL_ADC_EN_MASK (0x00000001u) +#define CAL_ADC_CONFIG_CAL_ADC_EN_BIT (0) +#define CAL_ADC_CONFIG_CAL_ADC_EN_BITS (1) + +/* FLASH_CONTROL block */ +#define DATA_FLASH_CONTROL_BASE (0x40008000u) +#define DATA_FLASH_CONTROL_END (0x40008084u) +#define DATA_FLASH_CONTROL_SIZE (DATA_FLASH_CONTROL_END - DATA_FLASH_CONTROL_BASE + 1) + +#define FLASH_ACCESS *((volatile uint32_t *)0x40008000u) +#define FLASH_ACCESS_REG *((volatile uint32_t *)0x40008000u) +#define FLASH_ACCESS_ADDR (0x40008000u) +#define FLASH_ACCESS_RESET (0x00000031u) +/* PREFETCH_STATUS field */ +#define FLASH_ACCESS_PREFETCH_STATUS (0x00000020u) +#define FLASH_ACCESS_PREFETCH_STATUS_MASK (0x00000020u) +#define FLASH_ACCESS_PREFETCH_STATUS_BIT (5) +#define FLASH_ACCESS_PREFETCH_STATUS_BITS (1) +/* PREFETCH_EN field */ +#define FLASH_ACCESS_PREFETCH_EN (0x00000010u) +#define FLASH_ACCESS_PREFETCH_EN_MASK (0x00000010u) +#define FLASH_ACCESS_PREFETCH_EN_BIT (4) +#define FLASH_ACCESS_PREFETCH_EN_BITS (1) +/* HALFCYCLE_ACCESS field */ +#define FLASH_ACCESS_HALFCYCLE_ACCESS (0x00000008u) +#define FLASH_ACCESS_HALFCYCLE_ACCESS_MASK (0x00000008u) +#define FLASH_ACCESS_HALFCYCLE_ACCESS_BIT (3) +#define FLASH_ACCESS_HALFCYCLE_ACCESS_BITS (1) +/* CODE_LATENCY field */ +#define FLASH_ACCESS_CODE_LATENCY (0x00000007u) +#define FLASH_ACCESS_CODE_LATENCY_MASK (0x00000007u) +#define FLASH_ACCESS_CODE_LATENCY_BIT (0) +#define FLASH_ACCESS_CODE_LATENCY_BITS (3) + +#define FPEC_KEY *((volatile uint32_t *)0x40008004u) +#define FPEC_KEY_REG *((volatile uint32_t *)0x40008004u) +#define FPEC_KEY_ADDR (0x40008004u) +#define FPEC_KEY_RESET (0x00000000u) +/* FKEYR field */ +#define FPEC_KEY_FKEYR (0xFFFFFFFFu) +#define FPEC_KEY_FKEYR_MASK (0xFFFFFFFFu) +#define FPEC_KEY_FKEYR_BIT (0) +#define FPEC_KEY_FKEYR_BITS (32) + +#define OPT_KEY *((volatile uint32_t *)0x40008008u) +#define OPT_KEY_REG *((volatile uint32_t *)0x40008008u) +#define OPT_KEY_ADDR (0x40008008u) +#define OPT_KEY_RESET (0x00000000u) +/* OPTKEYR field */ +#define OPT_KEY_OPTKEYR (0xFFFFFFFFu) +#define OPT_KEY_OPTKEYR_MASK (0xFFFFFFFFu) +#define OPT_KEY_OPTKEYR_BIT (0) +#define OPT_KEY_OPTKEYR_BITS (32) + +#define FLASH_STATUS *((volatile uint32_t *)0x4000800Cu) +#define FLASH_STATUS_REG *((volatile uint32_t *)0x4000800Cu) +#define FLASH_STATUS_ADDR (0x4000800Cu) +#define FLASH_STATUS_RESET (0x00000000u) +/* EOP field */ +#define FLASH_STATUS_EOP (0x00000020u) +#define FLASH_STATUS_EOP_MASK (0x00000020u) +#define FLASH_STATUS_EOP_BIT (5) +#define FLASH_STATUS_EOP_BITS (1) +/* WRP_ERR field */ +#define FLASH_STATUS_WRP_ERR (0x00000010u) +#define FLASH_STATUS_WRP_ERR_MASK (0x00000010u) +#define FLASH_STATUS_WRP_ERR_BIT (4) +#define FLASH_STATUS_WRP_ERR_BITS (1) +/* PAGE_PROG_ERR field */ +#define FLASH_STATUS_PAGE_PROG_ERR (0x00000008u) +#define FLASH_STATUS_PAGE_PROG_ERR_MASK (0x00000008u) +#define FLASH_STATUS_PAGE_PROG_ERR_BIT (3) +#define FLASH_STATUS_PAGE_PROG_ERR_BITS (1) +/* PROG_ERR field */ +#define FLASH_STATUS_PROG_ERR (0x00000004u) +#define FLASH_STATUS_PROG_ERR_MASK (0x00000004u) +#define FLASH_STATUS_PROG_ERR_BIT (2) +#define FLASH_STATUS_PROG_ERR_BITS (1) +/* EARLY_BSY field */ +#define FLASH_STATUS_EARLY_BSY (0x00000002u) +#define FLASH_STATUS_EARLY_BSY_MASK (0x00000002u) +#define FLASH_STATUS_EARLY_BSY_BIT (1) +#define FLASH_STATUS_EARLY_BSY_BITS (1) +/* FLA_BSY field */ +#define FLASH_STATUS_FLA_BSY (0x00000001u) +#define FLASH_STATUS_FLA_BSY_MASK (0x00000001u) +#define FLASH_STATUS_FLA_BSY_BIT (0) +#define FLASH_STATUS_FLA_BSY_BITS (1) + +#define FLASH_CTRL *((volatile uint32_t *)0x40008010u) +#define FLASH_CTRL_REG *((volatile uint32_t *)0x40008010u) +#define FLASH_CTRL_ADDR (0x40008010u) +#define FLASH_CTRL_RESET (0x00000080u) +/* EOPIE field */ +#define FLASH_CTRL_EOPIE (0x00001000u) +#define FLASH_CTRL_EOPIE_MASK (0x00001000u) +#define FLASH_CTRL_EOPIE_BIT (12) +#define FLASH_CTRL_EOPIE_BITS (1) +/* EARLYBSYIE field */ +#define FLASH_CTRL_EARLYBSYIE (0x00000800u) +#define FLASH_CTRL_EARLYBSYIE_MASK (0x00000800u) +#define FLASH_CTRL_EARLYBSYIE_BIT (11) +#define FLASH_CTRL_EARLYBSYIE_BITS (1) +/* ERRIE field */ +#define FLASH_CTRL_ERRIE (0x00000400u) +#define FLASH_CTRL_ERRIE_MASK (0x00000400u) +#define FLASH_CTRL_ERRIE_BIT (10) +#define FLASH_CTRL_ERRIE_BITS (1) +/* OPTWREN field */ +#define FLASH_CTRL_OPTWREN (0x00000200u) +#define FLASH_CTRL_OPTWREN_MASK (0x00000200u) +#define FLASH_CTRL_OPTWREN_BIT (9) +#define FLASH_CTRL_OPTWREN_BITS (1) +/* FSTPROG field */ +#define FLASH_CTRL_FSTPROG (0x00000100u) +#define FLASH_CTRL_FSTPROG_MASK (0x00000100u) +#define FLASH_CTRL_FSTPROG_BIT (8) +#define FLASH_CTRL_FSTPROG_BITS (1) +/* LOCK field */ +#define FLASH_CTRL_LOCK (0x00000080u) +#define FLASH_CTRL_LOCK_MASK (0x00000080u) +#define FLASH_CTRL_LOCK_BIT (7) +#define FLASH_CTRL_LOCK_BITS (1) +/* FLA_START field */ +#define FLASH_CTRL_FLA_START (0x00000040u) +#define FLASH_CTRL_FLA_START_MASK (0x00000040u) +#define FLASH_CTRL_FLA_START_BIT (6) +#define FLASH_CTRL_FLA_START_BITS (1) +/* OPTERASE field */ +#define FLASH_CTRL_OPTERASE (0x00000020u) +#define FLASH_CTRL_OPTERASE_MASK (0x00000020u) +#define FLASH_CTRL_OPTERASE_BIT (5) +#define FLASH_CTRL_OPTERASE_BITS (1) +/* OPTPROG field */ +#define FLASH_CTRL_OPTPROG (0x00000010u) +#define FLASH_CTRL_OPTPROG_MASK (0x00000010u) +#define FLASH_CTRL_OPTPROG_BIT (4) +#define FLASH_CTRL_OPTPROG_BITS (1) +/* GLOBALERASE field */ +#define FLASH_CTRL_GLOBALERASE (0x00000008u) +#define FLASH_CTRL_GLOBALERASE_MASK (0x00000008u) +#define FLASH_CTRL_GLOBALERASE_BIT (3) +#define FLASH_CTRL_GLOBALERASE_BITS (1) +/* MASSERASE field */ +#define FLASH_CTRL_MASSERASE (0x00000004u) +#define FLASH_CTRL_MASSERASE_MASK (0x00000004u) +#define FLASH_CTRL_MASSERASE_BIT (2) +#define FLASH_CTRL_MASSERASE_BITS (1) +/* PAGEERASE field */ +#define FLASH_CTRL_PAGEERASE (0x00000002u) +#define FLASH_CTRL_PAGEERASE_MASK (0x00000002u) +#define FLASH_CTRL_PAGEERASE_BIT (1) +#define FLASH_CTRL_PAGEERASE_BITS (1) +/* PROG field */ +#define FLASH_CTRL_PROG (0x00000001u) +#define FLASH_CTRL_PROG_MASK (0x00000001u) +#define FLASH_CTRL_PROG_BIT (0) +#define FLASH_CTRL_PROG_BITS (1) + +#define FLASH_ADDR *((volatile uint32_t *)0x40008014u) +#define FLASH_ADDR_REG *((volatile uint32_t *)0x40008014u) +#define FLASH_ADDR_ADDR (0x40008014u) +#define FLASH_ADDR_RESET (0x00000000u) +/* FAR field */ +#define FLASH_ADDR_FAR (0xFFFFFFFFu) +#define FLASH_ADDR_FAR_MASK (0xFFFFFFFFu) +#define FLASH_ADDR_FAR_BIT (0) +#define FLASH_ADDR_FAR_BITS (32) + +#define OPT_BYTE *((volatile uint32_t *)0x4000801Cu) +#define OPT_BYTE_REG *((volatile uint32_t *)0x4000801Cu) +#define OPT_BYTE_ADDR (0x4000801Cu) +#define OPT_BYTE_RESET (0xFBFFFFFEu) +/* RSVD field */ +#define OPT_BYTE_RSVD (0xF8000000u) +#define OPT_BYTE_RSVD_MASK (0xF8000000u) +#define OPT_BYTE_RSVD_BIT (27) +#define OPT_BYTE_RSVD_BITS (5) +/* OBR field */ +#define OPT_BYTE_OBR (0x07FFFFFCu) +#define OPT_BYTE_OBR_MASK (0x07FFFFFCu) +#define OPT_BYTE_OBR_BIT (2) +#define OPT_BYTE_OBR_BITS (25) +/* RDPROT field */ +#define OPT_BYTE_RDPROT (0x00000002u) +#define OPT_BYTE_RDPROT_MASK (0x00000002u) +#define OPT_BYTE_RDPROT_BIT (1) +#define OPT_BYTE_RDPROT_BITS (1) +/* OPT_ERR field */ +#define OPT_BYTE_OPT_ERR (0x00000001u) +#define OPT_BYTE_OPT_ERR_MASK (0x00000001u) +#define OPT_BYTE_OPT_ERR_BIT (0) +#define OPT_BYTE_OPT_ERR_BITS (1) + +#define WRPROT *((volatile uint32_t *)0x40008020u) +#define WRPROT_REG *((volatile uint32_t *)0x40008020u) +#define WRPROT_ADDR (0x40008020u) +#define WRPROT_RESET (0xFFFFFFFFu) +/* WRP field */ +#define WRPROT_WRP (0xFFFFFFFFu) +#define WRPROT_WRP_MASK (0xFFFFFFFFu) +#define WRPROT_WRP_BIT (0) +#define WRPROT_WRP_BITS (32) + +#define FLASH_TEST_CTRL *((volatile uint32_t *)0x40008080u) +#define FLASH_TEST_CTRL_REG *((volatile uint32_t *)0x40008080u) +#define FLASH_TEST_CTRL_ADDR (0x40008080u) +#define FLASH_TEST_CTRL_RESET (0x00000000u) +/* TMR field */ +#define FLASH_TEST_CTRL_TMR (0x00001000u) +#define FLASH_TEST_CTRL_TMR_MASK (0x00001000u) +#define FLASH_TEST_CTRL_TMR_BIT (12) +#define FLASH_TEST_CTRL_TMR_BITS (1) +/* ERASE field */ +#define FLASH_TEST_CTRL_ERASE (0x00000800u) +#define FLASH_TEST_CTRL_ERASE_MASK (0x00000800u) +#define FLASH_TEST_CTRL_ERASE_BIT (11) +#define FLASH_TEST_CTRL_ERASE_BITS (1) +/* MAS1 field */ +#define FLASH_TEST_CTRL_MAS1 (0x00000400u) +#define FLASH_TEST_CTRL_MAS1_MASK (0x00000400u) +#define FLASH_TEST_CTRL_MAS1_BIT (10) +#define FLASH_TEST_CTRL_MAS1_BITS (1) +/* TEST_PROG field */ +#define FLASH_TEST_CTRL_TEST_PROG (0x00000200u) +#define FLASH_TEST_CTRL_TEST_PROG_MASK (0x00000200u) +#define FLASH_TEST_CTRL_TEST_PROG_BIT (9) +#define FLASH_TEST_CTRL_TEST_PROG_BITS (1) +/* NVSTR field */ +#define FLASH_TEST_CTRL_NVSTR (0x00000100u) +#define FLASH_TEST_CTRL_NVSTR_MASK (0x00000100u) +#define FLASH_TEST_CTRL_NVSTR_BIT (8) +#define FLASH_TEST_CTRL_NVSTR_BITS (1) +/* SE field */ +#define FLASH_TEST_CTRL_SE (0x00000080u) +#define FLASH_TEST_CTRL_SE_MASK (0x00000080u) +#define FLASH_TEST_CTRL_SE_BIT (7) +#define FLASH_TEST_CTRL_SE_BITS (1) +/* IFREN field */ +#define FLASH_TEST_CTRL_IFREN (0x00000040u) +#define FLASH_TEST_CTRL_IFREN_MASK (0x00000040u) +#define FLASH_TEST_CTRL_IFREN_BIT (6) +#define FLASH_TEST_CTRL_IFREN_BITS (1) +/* YE field */ +#define FLASH_TEST_CTRL_YE (0x00000020u) +#define FLASH_TEST_CTRL_YE_MASK (0x00000020u) +#define FLASH_TEST_CTRL_YE_BIT (5) +#define FLASH_TEST_CTRL_YE_BITS (1) +/* XE field */ +#define FLASH_TEST_CTRL_XE (0x00000010u) +#define FLASH_TEST_CTRL_XE_MASK (0x00000010u) +#define FLASH_TEST_CTRL_XE_BIT (4) +#define FLASH_TEST_CTRL_XE_BITS (1) +/* SW_CTRL field */ +#define FLASH_TEST_CTRL_SW_CTRL (0x00000008u) +#define FLASH_TEST_CTRL_SW_CTRL_MASK (0x00000008u) +#define FLASH_TEST_CTRL_SW_CTRL_BIT (3) +#define FLASH_TEST_CTRL_SW_CTRL_BITS (1) +/* SW field */ +#define FLASH_TEST_CTRL_SW (0x00000006u) +#define FLASH_TEST_CTRL_SW_MASK (0x00000006u) +#define FLASH_TEST_CTRL_SW_BIT (1) +#define FLASH_TEST_CTRL_SW_BITS (2) +/* SW_EN field */ +#define FLASH_TEST_CTRL_SW_EN (0x00000001u) +#define FLASH_TEST_CTRL_SW_EN_MASK (0x00000001u) +#define FLASH_TEST_CTRL_SW_EN_BIT (0) +#define FLASH_TEST_CTRL_SW_EN_BITS (1) + +#define FLASH_DATA0 *((volatile uint32_t *)0x40008084u) +#define FLASH_DATA0_REG *((volatile uint32_t *)0x40008084u) +#define FLASH_DATA0_ADDR (0x40008084u) +#define FLASH_DATA0_RESET (0xFFFFFFFFu) +/* FDR0 field */ +#define FLASH_DATA0_FDR0 (0xFFFFFFFFu) +#define FLASH_DATA0_FDR0_MASK (0xFFFFFFFFu) +#define FLASH_DATA0_FDR0_BIT (0) +#define FLASH_DATA0_FDR0_BITS (32) + +/* EMU_REGS block */ +#define DATA_EMU_REGS_BASE (0x40009000u) +#define DATA_EMU_REGS_END (0x40009000u) +#define DATA_EMU_REGS_SIZE (DATA_EMU_REGS_END - DATA_EMU_REGS_BASE + 1) + +#define I_AM_AN_EMULATOR *((volatile uint32_t *)0x40009000u) +#define I_AM_AN_EMULATOR_REG *((volatile uint32_t *)0x40009000u) +#define I_AM_AN_EMULATOR_ADDR (0x40009000u) +#define I_AM_AN_EMULATOR_RESET (0x00000000u) +/* I_AM_AN_EMULATOR field */ +#define I_AM_AN_EMULATOR_I_AM_AN_EMULATOR (0x00000001u) +#define I_AM_AN_EMULATOR_I_AM_AN_EMULATOR_MASK (0x00000001u) +#define I_AM_AN_EMULATOR_I_AM_AN_EMULATOR_BIT (0) +#define I_AM_AN_EMULATOR_I_AM_AN_EMULATOR_BITS (1) + +/* INTERRUPTS block */ +#define BLOCK_INTERRUPTS_BASE (0x4000A000u) +#define BLOCK_INTERRUPTS_END (0x4000A86Cu) +#define BLOCK_INTERRUPTS_SIZE (BLOCK_INTERRUPTS_END - BLOCK_INTERRUPTS_BASE + 1) + +#define MAC_RX_INT_SRC *((volatile uint32_t *)0x4000A000u) +#define MAC_RX_INT_SRC_REG *((volatile uint32_t *)0x4000A000u) +#define MAC_RX_INT_SRC_ADDR (0x4000A000u) +#define MAC_RX_INT_SRC_RESET (0x00000000u) +/* TX_B_ACK_ERR_SRC field */ +#define MAC_RX_INT_SRC_TX_B_ACK_ERR_SRC (0x00008000u) +#define MAC_RX_INT_SRC_TX_B_ACK_ERR_SRC_MASK (0x00008000u) +#define MAC_RX_INT_SRC_TX_B_ACK_ERR_SRC_BIT (15) +#define MAC_RX_INT_SRC_TX_B_ACK_ERR_SRC_BITS (1) +/* TX_A_ACK_ERR_SRC field */ +#define MAC_RX_INT_SRC_TX_A_ACK_ERR_SRC (0x00004000u) +#define MAC_RX_INT_SRC_TX_A_ACK_ERR_SRC_MASK (0x00004000u) +#define MAC_RX_INT_SRC_TX_A_ACK_ERR_SRC_BIT (14) +#define MAC_RX_INT_SRC_TX_A_ACK_ERR_SRC_BITS (1) +/* RX_OVFLW_SRC field */ +#define MAC_RX_INT_SRC_RX_OVFLW_SRC (0x00002000u) +#define MAC_RX_INT_SRC_RX_OVFLW_SRC_MASK (0x00002000u) +#define MAC_RX_INT_SRC_RX_OVFLW_SRC_BIT (13) +#define MAC_RX_INT_SRC_RX_OVFLW_SRC_BITS (1) +/* RX_ERROR_SRC field */ +#define MAC_RX_INT_SRC_RX_ERROR_SRC (0x00001000u) +#define MAC_RX_INT_SRC_RX_ERROR_SRC_MASK (0x00001000u) +#define MAC_RX_INT_SRC_RX_ERROR_SRC_BIT (12) +#define MAC_RX_INT_SRC_RX_ERROR_SRC_BITS (1) +/* BB_RX_LEN_ERR_SRC field */ +#define MAC_RX_INT_SRC_BB_RX_LEN_ERR_SRC (0x00000800u) +#define MAC_RX_INT_SRC_BB_RX_LEN_ERR_SRC_MASK (0x00000800u) +#define MAC_RX_INT_SRC_BB_RX_LEN_ERR_SRC_BIT (11) +#define MAC_RX_INT_SRC_BB_RX_LEN_ERR_SRC_BITS (1) +/* TX_COLL_RX_SRC field */ +#define MAC_RX_INT_SRC_TX_COLL_RX_SRC (0x00000400u) +#define MAC_RX_INT_SRC_TX_COLL_RX_SRC_MASK (0x00000400u) +#define MAC_RX_INT_SRC_TX_COLL_RX_SRC_BIT (10) +#define MAC_RX_INT_SRC_TX_COLL_RX_SRC_BITS (1) +/* RSSI_INST_MEAS_SRC field */ +#define MAC_RX_INT_SRC_RSSI_INST_MEAS_SRC (0x00000200u) +#define MAC_RX_INT_SRC_RSSI_INST_MEAS_SRC_MASK (0x00000200u) +#define MAC_RX_INT_SRC_RSSI_INST_MEAS_SRC_BIT (9) +#define MAC_RX_INT_SRC_RSSI_INST_MEAS_SRC_BITS (1) +/* TX_B_ACK_SRC field */ +#define MAC_RX_INT_SRC_TX_B_ACK_SRC (0x00000100u) +#define MAC_RX_INT_SRC_TX_B_ACK_SRC_MASK (0x00000100u) +#define MAC_RX_INT_SRC_TX_B_ACK_SRC_BIT (8) +#define MAC_RX_INT_SRC_TX_B_ACK_SRC_BITS (1) +/* TX_A_ACK_SRC field */ +#define MAC_RX_INT_SRC_TX_A_ACK_SRC (0x00000080u) +#define MAC_RX_INT_SRC_TX_A_ACK_SRC_MASK (0x00000080u) +#define MAC_RX_INT_SRC_TX_A_ACK_SRC_BIT (7) +#define MAC_RX_INT_SRC_TX_A_ACK_SRC_BITS (1) +/* RX_B_UNLOAD_COMP_SRC field */ +#define MAC_RX_INT_SRC_RX_B_UNLOAD_COMP_SRC (0x00000040u) +#define MAC_RX_INT_SRC_RX_B_UNLOAD_COMP_SRC_MASK (0x00000040u) +#define MAC_RX_INT_SRC_RX_B_UNLOAD_COMP_SRC_BIT (6) +#define MAC_RX_INT_SRC_RX_B_UNLOAD_COMP_SRC_BITS (1) +/* RX_A_UNLOAD_COMP_SRC field */ +#define MAC_RX_INT_SRC_RX_A_UNLOAD_COMP_SRC (0x00000020u) +#define MAC_RX_INT_SRC_RX_A_UNLOAD_COMP_SRC_MASK (0x00000020u) +#define MAC_RX_INT_SRC_RX_A_UNLOAD_COMP_SRC_BIT (5) +#define MAC_RX_INT_SRC_RX_A_UNLOAD_COMP_SRC_BITS (1) +/* RX_B_ADDR_REC_SRC field */ +#define MAC_RX_INT_SRC_RX_B_ADDR_REC_SRC (0x00000010u) +#define MAC_RX_INT_SRC_RX_B_ADDR_REC_SRC_MASK (0x00000010u) +#define MAC_RX_INT_SRC_RX_B_ADDR_REC_SRC_BIT (4) +#define MAC_RX_INT_SRC_RX_B_ADDR_REC_SRC_BITS (1) +/* RX_A_ADDR_REC_SRC field */ +#define MAC_RX_INT_SRC_RX_A_ADDR_REC_SRC (0x00000008u) +#define MAC_RX_INT_SRC_RX_A_ADDR_REC_SRC_MASK (0x00000008u) +#define MAC_RX_INT_SRC_RX_A_ADDR_REC_SRC_BIT (3) +#define MAC_RX_INT_SRC_RX_A_ADDR_REC_SRC_BITS (1) +/* RX_B_FILT_COMP_SRC field */ +#define MAC_RX_INT_SRC_RX_B_FILT_COMP_SRC (0x00000004u) +#define MAC_RX_INT_SRC_RX_B_FILT_COMP_SRC_MASK (0x00000004u) +#define MAC_RX_INT_SRC_RX_B_FILT_COMP_SRC_BIT (2) +#define MAC_RX_INT_SRC_RX_B_FILT_COMP_SRC_BITS (1) +/* RX_A_FILT_COMP_SRC field */ +#define MAC_RX_INT_SRC_RX_A_FILT_COMP_SRC (0x00000002u) +#define MAC_RX_INT_SRC_RX_A_FILT_COMP_SRC_MASK (0x00000002u) +#define MAC_RX_INT_SRC_RX_A_FILT_COMP_SRC_BIT (1) +#define MAC_RX_INT_SRC_RX_A_FILT_COMP_SRC_BITS (1) +/* RX_FRAME_SRC field */ +#define MAC_RX_INT_SRC_RX_FRAME_SRC (0x00000001u) +#define MAC_RX_INT_SRC_RX_FRAME_SRC_MASK (0x00000001u) +#define MAC_RX_INT_SRC_RX_FRAME_SRC_BIT (0) +#define MAC_RX_INT_SRC_RX_FRAME_SRC_BITS (1) + +#define MAC_TX_INT_SRC *((volatile uint32_t *)0x4000A004u) +#define MAC_TX_INT_SRC_REG *((volatile uint32_t *)0x4000A004u) +#define MAC_TX_INT_SRC_ADDR (0x4000A004u) +#define MAC_TX_INT_SRC_RESET (0x00000000u) +/* RX_B_ACK_SRC field */ +#define MAC_TX_INT_SRC_RX_B_ACK_SRC (0x00000800u) +#define MAC_TX_INT_SRC_RX_B_ACK_SRC_MASK (0x00000800u) +#define MAC_TX_INT_SRC_RX_B_ACK_SRC_BIT (11) +#define MAC_TX_INT_SRC_RX_B_ACK_SRC_BITS (1) +/* RX_A_ACK_SRC field */ +#define MAC_TX_INT_SRC_RX_A_ACK_SRC (0x00000400u) +#define MAC_TX_INT_SRC_RX_A_ACK_SRC_MASK (0x00000400u) +#define MAC_TX_INT_SRC_RX_A_ACK_SRC_BIT (10) +#define MAC_TX_INT_SRC_RX_A_ACK_SRC_BITS (1) +/* TX_B_UNLOAD_SRC field */ +#define MAC_TX_INT_SRC_TX_B_UNLOAD_SRC (0x00000200u) +#define MAC_TX_INT_SRC_TX_B_UNLOAD_SRC_MASK (0x00000200u) +#define MAC_TX_INT_SRC_TX_B_UNLOAD_SRC_BIT (9) +#define MAC_TX_INT_SRC_TX_B_UNLOAD_SRC_BITS (1) +/* TX_A_UNLOAD_SRC field */ +#define MAC_TX_INT_SRC_TX_A_UNLOAD_SRC (0x00000100u) +#define MAC_TX_INT_SRC_TX_A_UNLOAD_SRC_MASK (0x00000100u) +#define MAC_TX_INT_SRC_TX_A_UNLOAD_SRC_BIT (8) +#define MAC_TX_INT_SRC_TX_A_UNLOAD_SRC_BITS (1) +/* ACK_EXPIRED_SRC field */ +#define MAC_TX_INT_SRC_ACK_EXPIRED_SRC (0x00000080u) +#define MAC_TX_INT_SRC_ACK_EXPIRED_SRC_MASK (0x00000080u) +#define MAC_TX_INT_SRC_ACK_EXPIRED_SRC_BIT (7) +#define MAC_TX_INT_SRC_ACK_EXPIRED_SRC_BITS (1) +/* TX_LOCK_FAIL_SRC field */ +#define MAC_TX_INT_SRC_TX_LOCK_FAIL_SRC (0x00000040u) +#define MAC_TX_INT_SRC_TX_LOCK_FAIL_SRC_MASK (0x00000040u) +#define MAC_TX_INT_SRC_TX_LOCK_FAIL_SRC_BIT (6) +#define MAC_TX_INT_SRC_TX_LOCK_FAIL_SRC_BITS (1) +/* TX_UNDERFLOW_SRC field */ +#define MAC_TX_INT_SRC_TX_UNDERFLOW_SRC (0x00000020u) +#define MAC_TX_INT_SRC_TX_UNDERFLOW_SRC_MASK (0x00000020u) +#define MAC_TX_INT_SRC_TX_UNDERFLOW_SRC_BIT (5) +#define MAC_TX_INT_SRC_TX_UNDERFLOW_SRC_BITS (1) +/* CCA_FAIL_SRC field */ +#define MAC_TX_INT_SRC_CCA_FAIL_SRC (0x00000010u) +#define MAC_TX_INT_SRC_CCA_FAIL_SRC_MASK (0x00000010u) +#define MAC_TX_INT_SRC_CCA_FAIL_SRC_BIT (4) +#define MAC_TX_INT_SRC_CCA_FAIL_SRC_BITS (1) +/* SFD_SENT_SRC field */ +#define MAC_TX_INT_SRC_SFD_SENT_SRC (0x00000008u) +#define MAC_TX_INT_SRC_SFD_SENT_SRC_MASK (0x00000008u) +#define MAC_TX_INT_SRC_SFD_SENT_SRC_BIT (3) +#define MAC_TX_INT_SRC_SFD_SENT_SRC_BITS (1) +/* BO_COMPLETE_SRC field */ +#define MAC_TX_INT_SRC_BO_COMPLETE_SRC (0x00000004u) +#define MAC_TX_INT_SRC_BO_COMPLETE_SRC_MASK (0x00000004u) +#define MAC_TX_INT_SRC_BO_COMPLETE_SRC_BIT (2) +#define MAC_TX_INT_SRC_BO_COMPLETE_SRC_BITS (1) +/* RX_ACK_SRC field */ +#define MAC_TX_INT_SRC_RX_ACK_SRC (0x00000002u) +#define MAC_TX_INT_SRC_RX_ACK_SRC_MASK (0x00000002u) +#define MAC_TX_INT_SRC_RX_ACK_SRC_BIT (1) +#define MAC_TX_INT_SRC_RX_ACK_SRC_BITS (1) +/* TX_COMPLETE_SRC field */ +#define MAC_TX_INT_SRC_TX_COMPLETE_SRC (0x00000001u) +#define MAC_TX_INT_SRC_TX_COMPLETE_SRC_MASK (0x00000001u) +#define MAC_TX_INT_SRC_TX_COMPLETE_SRC_BIT (0) +#define MAC_TX_INT_SRC_TX_COMPLETE_SRC_BITS (1) + +#define MAC_TIMER_INT_SRC *((volatile uint32_t *)0x4000A008u) +#define MAC_TIMER_INT_SRC_REG *((volatile uint32_t *)0x4000A008u) +#define MAC_TIMER_INT_SRC_ADDR (0x4000A008u) +#define MAC_TIMER_INT_SRC_RESET (0x00000000u) +/* TIMER_COMP_B_SRC field */ +#define MAC_TIMER_INT_SRC_TIMER_COMP_B_SRC (0x00000004u) +#define MAC_TIMER_INT_SRC_TIMER_COMP_B_SRC_MASK (0x00000004u) +#define MAC_TIMER_INT_SRC_TIMER_COMP_B_SRC_BIT (2) +#define MAC_TIMER_INT_SRC_TIMER_COMP_B_SRC_BITS (1) +/* TIMER_COMP_A_SRC field */ +#define MAC_TIMER_INT_SRC_TIMER_COMP_A_SRC (0x00000002u) +#define MAC_TIMER_INT_SRC_TIMER_COMP_A_SRC_MASK (0x00000002u) +#define MAC_TIMER_INT_SRC_TIMER_COMP_A_SRC_BIT (1) +#define MAC_TIMER_INT_SRC_TIMER_COMP_A_SRC_BITS (1) +/* TIMER_WRAP_SRC field */ +#define MAC_TIMER_INT_SRC_TIMER_WRAP_SRC (0x00000001u) +#define MAC_TIMER_INT_SRC_TIMER_WRAP_SRC_MASK (0x00000001u) +#define MAC_TIMER_INT_SRC_TIMER_WRAP_SRC_BIT (0) +#define MAC_TIMER_INT_SRC_TIMER_WRAP_SRC_BITS (1) + +#define BB_INT_SRC *((volatile uint32_t *)0x4000A00Cu) +#define BB_INT_SRC_REG *((volatile uint32_t *)0x4000A00Cu) +#define BB_INT_SRC_ADDR (0x4000A00Cu) +#define BB_INT_SRC_RESET (0x00000000u) +/* RSSI_INT_SRC field */ +#define BB_INT_SRC_RSSI_INT_SRC (0x00000002u) +#define BB_INT_SRC_RSSI_INT_SRC_MASK (0x00000002u) +#define BB_INT_SRC_RSSI_INT_SRC_BIT (1) +#define BB_INT_SRC_RSSI_INT_SRC_BITS (1) +/* BASEBAND_INT_SRC field */ +#define BB_INT_SRC_BASEBAND_INT_SRC (0x00000001u) +#define BB_INT_SRC_BASEBAND_INT_SRC_MASK (0x00000001u) +#define BB_INT_SRC_BASEBAND_INT_SRC_BIT (0) +#define BB_INT_SRC_BASEBAND_INT_SRC_BITS (1) + +#define SEC_INT_SRC *((volatile uint32_t *)0x4000A010u) +#define SEC_INT_SRC_REG *((volatile uint32_t *)0x4000A010u) +#define SEC_INT_SRC_ADDR (0x4000A010u) +#define SEC_INT_SRC_RESET (0x00000000u) +/* CT_WORD_VALID_SRC field */ +#define SEC_INT_SRC_CT_WORD_VALID_SRC (0x00000004u) +#define SEC_INT_SRC_CT_WORD_VALID_SRC_MASK (0x00000004u) +#define SEC_INT_SRC_CT_WORD_VALID_SRC_BIT (2) +#define SEC_INT_SRC_CT_WORD_VALID_SRC_BITS (1) +/* PT_WORD_REQ_SRC field */ +#define SEC_INT_SRC_PT_WORD_REQ_SRC (0x00000002u) +#define SEC_INT_SRC_PT_WORD_REQ_SRC_MASK (0x00000002u) +#define SEC_INT_SRC_PT_WORD_REQ_SRC_BIT (1) +#define SEC_INT_SRC_PT_WORD_REQ_SRC_BITS (1) +/* ENC_COMPLETE_SRC field */ +#define SEC_INT_SRC_ENC_COMPLETE_SRC (0x00000001u) +#define SEC_INT_SRC_ENC_COMPLETE_SRC_MASK (0x00000001u) +#define SEC_INT_SRC_ENC_COMPLETE_SRC_BIT (0) +#define SEC_INT_SRC_ENC_COMPLETE_SRC_BITS (1) + +#define INT_SLEEPTMRFLAG *((volatile uint32_t *)0x4000A014u) +#define INT_SLEEPTMRFLAG_REG *((volatile uint32_t *)0x4000A014u) +#define INT_SLEEPTMRFLAG_ADDR (0x4000A014u) +#define INT_SLEEPTMRFLAG_RESET (0x00000000u) +/* INT_SLEEPTMRCMPB field */ +#define INT_SLEEPTMRCMPB (0x00000004u) +#define INT_SLEEPTMRCMPB_MASK (0x00000004u) +#define INT_SLEEPTMRCMPB_BIT (2) +#define INT_SLEEPTMRCMPB_BITS (1) +/* INT_SLEEPTMRCMPA field */ +#define INT_SLEEPTMRCMPA (0x00000002u) +#define INT_SLEEPTMRCMPA_MASK (0x00000002u) +#define INT_SLEEPTMRCMPA_BIT (1) +#define INT_SLEEPTMRCMPA_BITS (1) +/* INT_SLEEPTMRWRAP field */ +#define INT_SLEEPTMRWRAP (0x00000001u) +#define INT_SLEEPTMRWRAP_MASK (0x00000001u) +#define INT_SLEEPTMRWRAP_BIT (0) +#define INT_SLEEPTMRWRAP_BITS (1) + +#define INT_MGMTFLAG *((volatile uint32_t *)0x4000A018u) +#define INT_MGMTFLAG_REG *((volatile uint32_t *)0x4000A018u) +#define INT_MGMTFLAG_ADDR (0x4000A018u) +#define INT_MGMTFLAG_RESET (0x00000000u) +/* INT_MGMTDMAPROT field */ +#define INT_MGMTDMAPROT (0x00000010u) +#define INT_MGMTDMAPROT_MASK (0x00000010u) +#define INT_MGMTDMAPROT_BIT (4) +#define INT_MGMTDMAPROT_BITS (1) +/* INT_MGMTCALADC field */ +#define INT_MGMTCALADC (0x00000008u) +#define INT_MGMTCALADC_MASK (0x00000008u) +#define INT_MGMTCALADC_BIT (3) +#define INT_MGMTCALADC_BITS (1) +/* INT_MGMTFPEC field */ +#define INT_MGMTFPEC (0x00000004u) +#define INT_MGMTFPEC_MASK (0x00000004u) +#define INT_MGMTFPEC_BIT (2) +#define INT_MGMTFPEC_BITS (1) +/* INT_MGMTOSC24MHI field */ +#define INT_MGMTOSC24MHI (0x00000002u) +#define INT_MGMTOSC24MHI_MASK (0x00000002u) +#define INT_MGMTOSC24MHI_BIT (1) +#define INT_MGMTOSC24MHI_BITS (1) +/* INT_MGMTOSC24MLO field */ +#define INT_MGMTOSC24MLO (0x00000001u) +#define INT_MGMTOSC24MLO_MASK (0x00000001u) +#define INT_MGMTOSC24MLO_BIT (0) +#define INT_MGMTOSC24MLO_BITS (1) + +#define INT_NMIFLAG *((volatile uint32_t *)0x4000A01Cu) +#define INT_NMIFLAG_REG *((volatile uint32_t *)0x4000A01Cu) +#define INT_NMIFLAG_ADDR (0x4000A01Cu) +#define INT_NMIFLAG_RESET (0x00000000u) +/* INT_NMICLK24M field */ +#define INT_NMICLK24M (0x00000002u) +#define INT_NMICLK24M_MASK (0x00000002u) +#define INT_NMICLK24M_BIT (1) +#define INT_NMICLK24M_BITS (1) +/* INT_NMIWDOG field */ +#define INT_NMIWDOG (0x00000001u) +#define INT_NMIWDOG_MASK (0x00000001u) +#define INT_NMIWDOG_BIT (0) +#define INT_NMIWDOG_BITS (1) + +#define INT_SLEEPTMRFORCE *((volatile uint32_t *)0x4000A020u) +#define INT_SLEEPTMRFORCE_REG *((volatile uint32_t *)0x4000A020u) +#define INT_SLEEPTMRFORCE_ADDR (0x4000A020u) +#define INT_SLEEPTMRFORCE_RESET (0x00000000u) +/* INT_SLEEPTMRCMPB field */ +#define INT_SLEEPTMRCMPB (0x00000004u) +#define INT_SLEEPTMRCMPB_MASK (0x00000004u) +#define INT_SLEEPTMRCMPB_BIT (2) +#define INT_SLEEPTMRCMPB_BITS (1) +/* INT_SLEEPTMRCMPA field */ +#define INT_SLEEPTMRCMPA (0x00000002u) +#define INT_SLEEPTMRCMPA_MASK (0x00000002u) +#define INT_SLEEPTMRCMPA_BIT (1) +#define INT_SLEEPTMRCMPA_BITS (1) +/* INT_SLEEPTMRWRAP field */ +#define INT_SLEEPTMRWRAP (0x00000001u) +#define INT_SLEEPTMRWRAP_MASK (0x00000001u) +#define INT_SLEEPTMRWRAP_BIT (0) +#define INT_SLEEPTMRWRAP_BITS (1) + +#define TEST_FORCE_ALL_INT *((volatile uint32_t *)0x4000A024u) +#define TEST_FORCE_ALL_INT_REG *((volatile uint32_t *)0x4000A024u) +#define TEST_FORCE_ALL_INT_ADDR (0x4000A024u) +#define TEST_FORCE_ALL_INT_RESET (0x00000000u) +/* FORCE_ALL_INT field */ +#define TEST_FORCE_ALL_INT_FORCE_ALL_INT (0x00000001u) +#define TEST_FORCE_ALL_INT_FORCE_ALL_INT_MASK (0x00000001u) +#define TEST_FORCE_ALL_INT_FORCE_ALL_INT_BIT (0) +#define TEST_FORCE_ALL_INT_FORCE_ALL_INT_BITS (1) + +#define MAC_RX_INT_MASK *((volatile uint32_t *)0x4000A040u) +#define MAC_RX_INT_MASK_REG *((volatile uint32_t *)0x4000A040u) +#define MAC_RX_INT_MASK_ADDR (0x4000A040u) +#define MAC_RX_INT_MASK_RESET (0x00000000u) +/* TX_B_ACK_ERR_MSK field */ +#define MAC_RX_INT_MASK_TX_B_ACK_ERR_MSK (0x00008000u) +#define MAC_RX_INT_MASK_TX_B_ACK_ERR_MSK_MASK (0x00008000u) +#define MAC_RX_INT_MASK_TX_B_ACK_ERR_MSK_BIT (15) +#define MAC_RX_INT_MASK_TX_B_ACK_ERR_MSK_BITS (1) +/* TX_A_ACK_ERR_MSK field */ +#define MAC_RX_INT_MASK_TX_A_ACK_ERR_MSK (0x00004000u) +#define MAC_RX_INT_MASK_TX_A_ACK_ERR_MSK_MASK (0x00004000u) +#define MAC_RX_INT_MASK_TX_A_ACK_ERR_MSK_BIT (14) +#define MAC_RX_INT_MASK_TX_A_ACK_ERR_MSK_BITS (1) +/* RX_OVFLW_MSK field */ +#define MAC_RX_INT_MASK_RX_OVFLW_MSK (0x00002000u) +#define MAC_RX_INT_MASK_RX_OVFLW_MSK_MASK (0x00002000u) +#define MAC_RX_INT_MASK_RX_OVFLW_MSK_BIT (13) +#define MAC_RX_INT_MASK_RX_OVFLW_MSK_BITS (1) +/* RX_ERROR_MSK field */ +#define MAC_RX_INT_MASK_RX_ERROR_MSK (0x00001000u) +#define MAC_RX_INT_MASK_RX_ERROR_MSK_MASK (0x00001000u) +#define MAC_RX_INT_MASK_RX_ERROR_MSK_BIT (12) +#define MAC_RX_INT_MASK_RX_ERROR_MSK_BITS (1) +/* BB_RX_LEN_ERR_MSK field */ +#define MAC_RX_INT_MASK_BB_RX_LEN_ERR_MSK (0x00000800u) +#define MAC_RX_INT_MASK_BB_RX_LEN_ERR_MSK_MASK (0x00000800u) +#define MAC_RX_INT_MASK_BB_RX_LEN_ERR_MSK_BIT (11) +#define MAC_RX_INT_MASK_BB_RX_LEN_ERR_MSK_BITS (1) +/* TX_COLL_RX_MSK field */ +#define MAC_RX_INT_MASK_TX_COLL_RX_MSK (0x00000400u) +#define MAC_RX_INT_MASK_TX_COLL_RX_MSK_MASK (0x00000400u) +#define MAC_RX_INT_MASK_TX_COLL_RX_MSK_BIT (10) +#define MAC_RX_INT_MASK_TX_COLL_RX_MSK_BITS (1) +/* RSSI_INST_MEAS_MSK field */ +#define MAC_RX_INT_MASK_RSSI_INST_MEAS_MSK (0x00000200u) +#define MAC_RX_INT_MASK_RSSI_INST_MEAS_MSK_MASK (0x00000200u) +#define MAC_RX_INT_MASK_RSSI_INST_MEAS_MSK_BIT (9) +#define MAC_RX_INT_MASK_RSSI_INST_MEAS_MSK_BITS (1) +/* TX_B_ACK_MSK field */ +#define MAC_RX_INT_MASK_TX_B_ACK_MSK (0x00000100u) +#define MAC_RX_INT_MASK_TX_B_ACK_MSK_MASK (0x00000100u) +#define MAC_RX_INT_MASK_TX_B_ACK_MSK_BIT (8) +#define MAC_RX_INT_MASK_TX_B_ACK_MSK_BITS (1) +/* TX_A_ACK_MSK field */ +#define MAC_RX_INT_MASK_TX_A_ACK_MSK (0x00000080u) +#define MAC_RX_INT_MASK_TX_A_ACK_MSK_MASK (0x00000080u) +#define MAC_RX_INT_MASK_TX_A_ACK_MSK_BIT (7) +#define MAC_RX_INT_MASK_TX_A_ACK_MSK_BITS (1) +/* RX_B_UNLOAD_COMP_MSK field */ +#define MAC_RX_INT_MASK_RX_B_UNLOAD_COMP_MSK (0x00000040u) +#define MAC_RX_INT_MASK_RX_B_UNLOAD_COMP_MSK_MASK (0x00000040u) +#define MAC_RX_INT_MASK_RX_B_UNLOAD_COMP_MSK_BIT (6) +#define MAC_RX_INT_MASK_RX_B_UNLOAD_COMP_MSK_BITS (1) +/* RX_A_UNLOAD_COMP_MSK field */ +#define MAC_RX_INT_MASK_RX_A_UNLOAD_COMP_MSK (0x00000020u) +#define MAC_RX_INT_MASK_RX_A_UNLOAD_COMP_MSK_MASK (0x00000020u) +#define MAC_RX_INT_MASK_RX_A_UNLOAD_COMP_MSK_BIT (5) +#define MAC_RX_INT_MASK_RX_A_UNLOAD_COMP_MSK_BITS (1) +/* RX_B_ADDR_REC_MSK field */ +#define MAC_RX_INT_MASK_RX_B_ADDR_REC_MSK (0x00000010u) +#define MAC_RX_INT_MASK_RX_B_ADDR_REC_MSK_MASK (0x00000010u) +#define MAC_RX_INT_MASK_RX_B_ADDR_REC_MSK_BIT (4) +#define MAC_RX_INT_MASK_RX_B_ADDR_REC_MSK_BITS (1) +/* RX_A_ADDR_REC_MSK field */ +#define MAC_RX_INT_MASK_RX_A_ADDR_REC_MSK (0x00000008u) +#define MAC_RX_INT_MASK_RX_A_ADDR_REC_MSK_MASK (0x00000008u) +#define MAC_RX_INT_MASK_RX_A_ADDR_REC_MSK_BIT (3) +#define MAC_RX_INT_MASK_RX_A_ADDR_REC_MSK_BITS (1) +/* RX_B_FILT_COMP_MSK field */ +#define MAC_RX_INT_MASK_RX_B_FILT_COMP_MSK (0x00000004u) +#define MAC_RX_INT_MASK_RX_B_FILT_COMP_MSK_MASK (0x00000004u) +#define MAC_RX_INT_MASK_RX_B_FILT_COMP_MSK_BIT (2) +#define MAC_RX_INT_MASK_RX_B_FILT_COMP_MSK_BITS (1) +/* RX_A_FILT_COMP_MSK field */ +#define MAC_RX_INT_MASK_RX_A_FILT_COMP_MSK (0x00000002u) +#define MAC_RX_INT_MASK_RX_A_FILT_COMP_MSK_MASK (0x00000002u) +#define MAC_RX_INT_MASK_RX_A_FILT_COMP_MSK_BIT (1) +#define MAC_RX_INT_MASK_RX_A_FILT_COMP_MSK_BITS (1) +/* RX_FRAME_MSK field */ +#define MAC_RX_INT_MASK_RX_FRAME_MSK (0x00000001u) +#define MAC_RX_INT_MASK_RX_FRAME_MSK_MASK (0x00000001u) +#define MAC_RX_INT_MASK_RX_FRAME_MSK_BIT (0) +#define MAC_RX_INT_MASK_RX_FRAME_MSK_BITS (1) + +#define MAC_TX_INT_MASK *((volatile uint32_t *)0x4000A044u) +#define MAC_TX_INT_MASK_REG *((volatile uint32_t *)0x4000A044u) +#define MAC_TX_INT_MASK_ADDR (0x4000A044u) +#define MAC_TX_INT_MASK_RESET (0x00000000u) +/* RX_B_ACK_MSK field */ +#define MAC_TX_INT_MASK_RX_B_ACK_MSK (0x00000800u) +#define MAC_TX_INT_MASK_RX_B_ACK_MSK_MASK (0x00000800u) +#define MAC_TX_INT_MASK_RX_B_ACK_MSK_BIT (11) +#define MAC_TX_INT_MASK_RX_B_ACK_MSK_BITS (1) +/* RX_A_ACK_MSK field */ +#define MAC_TX_INT_MASK_RX_A_ACK_MSK (0x00000400u) +#define MAC_TX_INT_MASK_RX_A_ACK_MSK_MASK (0x00000400u) +#define MAC_TX_INT_MASK_RX_A_ACK_MSK_BIT (10) +#define MAC_TX_INT_MASK_RX_A_ACK_MSK_BITS (1) +/* TX_B_UNLOAD_MSK field */ +#define MAC_TX_INT_MASK_TX_B_UNLOAD_MSK (0x00000200u) +#define MAC_TX_INT_MASK_TX_B_UNLOAD_MSK_MASK (0x00000200u) +#define MAC_TX_INT_MASK_TX_B_UNLOAD_MSK_BIT (9) +#define MAC_TX_INT_MASK_TX_B_UNLOAD_MSK_BITS (1) +/* TX_A_UNLOAD_MSK field */ +#define MAC_TX_INT_MASK_TX_A_UNLOAD_MSK (0x00000100u) +#define MAC_TX_INT_MASK_TX_A_UNLOAD_MSK_MASK (0x00000100u) +#define MAC_TX_INT_MASK_TX_A_UNLOAD_MSK_BIT (8) +#define MAC_TX_INT_MASK_TX_A_UNLOAD_MSK_BITS (1) +/* ACK_EXPIRED_MSK field */ +#define MAC_TX_INT_MASK_ACK_EXPIRED_MSK (0x00000080u) +#define MAC_TX_INT_MASK_ACK_EXPIRED_MSK_MASK (0x00000080u) +#define MAC_TX_INT_MASK_ACK_EXPIRED_MSK_BIT (7) +#define MAC_TX_INT_MASK_ACK_EXPIRED_MSK_BITS (1) +/* TX_LOCK_FAIL_MSK field */ +#define MAC_TX_INT_MASK_TX_LOCK_FAIL_MSK (0x00000040u) +#define MAC_TX_INT_MASK_TX_LOCK_FAIL_MSK_MASK (0x00000040u) +#define MAC_TX_INT_MASK_TX_LOCK_FAIL_MSK_BIT (6) +#define MAC_TX_INT_MASK_TX_LOCK_FAIL_MSK_BITS (1) +/* TX_UNDERFLOW_MSK field */ +#define MAC_TX_INT_MASK_TX_UNDERFLOW_MSK (0x00000020u) +#define MAC_TX_INT_MASK_TX_UNDERFLOW_MSK_MASK (0x00000020u) +#define MAC_TX_INT_MASK_TX_UNDERFLOW_MSK_BIT (5) +#define MAC_TX_INT_MASK_TX_UNDERFLOW_MSK_BITS (1) +/* CCA_FAIL_MSK field */ +#define MAC_TX_INT_MASK_CCA_FAIL_MSK (0x00000010u) +#define MAC_TX_INT_MASK_CCA_FAIL_MSK_MASK (0x00000010u) +#define MAC_TX_INT_MASK_CCA_FAIL_MSK_BIT (4) +#define MAC_TX_INT_MASK_CCA_FAIL_MSK_BITS (1) +/* SFD_SENT_MSK field */ +#define MAC_TX_INT_MASK_SFD_SENT_MSK (0x00000008u) +#define MAC_TX_INT_MASK_SFD_SENT_MSK_MASK (0x00000008u) +#define MAC_TX_INT_MASK_SFD_SENT_MSK_BIT (3) +#define MAC_TX_INT_MASK_SFD_SENT_MSK_BITS (1) +/* BO_COMPLETE_MSK field */ +#define MAC_TX_INT_MASK_BO_COMPLETE_MSK (0x00000004u) +#define MAC_TX_INT_MASK_BO_COMPLETE_MSK_MASK (0x00000004u) +#define MAC_TX_INT_MASK_BO_COMPLETE_MSK_BIT (2) +#define MAC_TX_INT_MASK_BO_COMPLETE_MSK_BITS (1) +/* RX_ACK_MSK field */ +#define MAC_TX_INT_MASK_RX_ACK_MSK (0x00000002u) +#define MAC_TX_INT_MASK_RX_ACK_MSK_MASK (0x00000002u) +#define MAC_TX_INT_MASK_RX_ACK_MSK_BIT (1) +#define MAC_TX_INT_MASK_RX_ACK_MSK_BITS (1) +/* TX_COMPLETE_MSK field */ +#define MAC_TX_INT_MASK_TX_COMPLETE_MSK (0x00000001u) +#define MAC_TX_INT_MASK_TX_COMPLETE_MSK_MASK (0x00000001u) +#define MAC_TX_INT_MASK_TX_COMPLETE_MSK_BIT (0) +#define MAC_TX_INT_MASK_TX_COMPLETE_MSK_BITS (1) + +#define MAC_TIMER_INT_MASK *((volatile uint32_t *)0x4000A048u) +#define MAC_TIMER_INT_MASK_REG *((volatile uint32_t *)0x4000A048u) +#define MAC_TIMER_INT_MASK_ADDR (0x4000A048u) +#define MAC_TIMER_INT_MASK_RESET (0x00000000u) +/* TIMER_COMP_B_MSK field */ +#define MAC_TIMER_INT_MASK_TIMER_COMP_B_MSK (0x00000004u) +#define MAC_TIMER_INT_MASK_TIMER_COMP_B_MSK_MASK (0x00000004u) +#define MAC_TIMER_INT_MASK_TIMER_COMP_B_MSK_BIT (2) +#define MAC_TIMER_INT_MASK_TIMER_COMP_B_MSK_BITS (1) +/* TIMER_COMP_A_MSK field */ +#define MAC_TIMER_INT_MASK_TIMER_COMP_A_MSK (0x00000002u) +#define MAC_TIMER_INT_MASK_TIMER_COMP_A_MSK_MASK (0x00000002u) +#define MAC_TIMER_INT_MASK_TIMER_COMP_A_MSK_BIT (1) +#define MAC_TIMER_INT_MASK_TIMER_COMP_A_MSK_BITS (1) +/* TIMER_WRAP_MSK field */ +#define MAC_TIMER_INT_MASK_TIMER_WRAP_MSK (0x00000001u) +#define MAC_TIMER_INT_MASK_TIMER_WRAP_MSK_MASK (0x00000001u) +#define MAC_TIMER_INT_MASK_TIMER_WRAP_MSK_BIT (0) +#define MAC_TIMER_INT_MASK_TIMER_WRAP_MSK_BITS (1) + +#define BB_INT_MASK *((volatile uint32_t *)0x4000A04Cu) +#define BB_INT_MASK_REG *((volatile uint32_t *)0x4000A04Cu) +#define BB_INT_MASK_ADDR (0x4000A04Cu) +#define BB_INT_MASK_RESET (0x00000000u) +/* RSSI_INT_MSK field */ +#define BB_INT_MASK_RSSI_INT_MSK (0x00000002u) +#define BB_INT_MASK_RSSI_INT_MSK_MASK (0x00000002u) +#define BB_INT_MASK_RSSI_INT_MSK_BIT (1) +#define BB_INT_MASK_RSSI_INT_MSK_BITS (1) +/* BASEBAND_INT_MSK field */ +#define BB_INT_MASK_BASEBAND_INT_MSK (0x00000001u) +#define BB_INT_MASK_BASEBAND_INT_MSK_MASK (0x00000001u) +#define BB_INT_MASK_BASEBAND_INT_MSK_BIT (0) +#define BB_INT_MASK_BASEBAND_INT_MSK_BITS (1) + +#define SEC_INT_MASK *((volatile uint32_t *)0x4000A050u) +#define SEC_INT_MASK_REG *((volatile uint32_t *)0x4000A050u) +#define SEC_INT_MASK_ADDR (0x4000A050u) +#define SEC_INT_MASK_RESET (0x00000000u) +/* CT_WORD_VALID_MSK field */ +#define SEC_INT_MASK_CT_WORD_VALID_MSK (0x00000004u) +#define SEC_INT_MASK_CT_WORD_VALID_MSK_MASK (0x00000004u) +#define SEC_INT_MASK_CT_WORD_VALID_MSK_BIT (2) +#define SEC_INT_MASK_CT_WORD_VALID_MSK_BITS (1) +/* PT_WORD_REQ_MSK field */ +#define SEC_INT_MASK_PT_WORD_REQ_MSK (0x00000002u) +#define SEC_INT_MASK_PT_WORD_REQ_MSK_MASK (0x00000002u) +#define SEC_INT_MASK_PT_WORD_REQ_MSK_BIT (1) +#define SEC_INT_MASK_PT_WORD_REQ_MSK_BITS (1) +/* ENC_COMPLETE_MSK field */ +#define SEC_INT_MASK_ENC_COMPLETE_MSK (0x00000001u) +#define SEC_INT_MASK_ENC_COMPLETE_MSK_MASK (0x00000001u) +#define SEC_INT_MASK_ENC_COMPLETE_MSK_BIT (0) +#define SEC_INT_MASK_ENC_COMPLETE_MSK_BITS (1) + +#define INT_SLEEPTMRCFG *((volatile uint32_t *)0x4000A054u) +#define INT_SLEEPTMRCFG_REG *((volatile uint32_t *)0x4000A054u) +#define INT_SLEEPTMRCFG_ADDR (0x4000A054u) +#define INT_SLEEPTMRCFG_RESET (0x00000000u) +/* INT_SLEEPTMRCMPB field */ +#define INT_SLEEPTMRCMPB (0x00000004u) +#define INT_SLEEPTMRCMPB_MASK (0x00000004u) +#define INT_SLEEPTMRCMPB_BIT (2) +#define INT_SLEEPTMRCMPB_BITS (1) +/* INT_SLEEPTMRCMPA field */ +#define INT_SLEEPTMRCMPA (0x00000002u) +#define INT_SLEEPTMRCMPA_MASK (0x00000002u) +#define INT_SLEEPTMRCMPA_BIT (1) +#define INT_SLEEPTMRCMPA_BITS (1) +/* INT_SLEEPTMRWRAP field */ +#define INT_SLEEPTMRWRAP (0x00000001u) +#define INT_SLEEPTMRWRAP_MASK (0x00000001u) +#define INT_SLEEPTMRWRAP_BIT (0) +#define INT_SLEEPTMRWRAP_BITS (1) + +#define INT_MGMTCFG *((volatile uint32_t *)0x4000A058u) +#define INT_MGMTCFG_REG *((volatile uint32_t *)0x4000A058u) +#define INT_MGMTCFG_ADDR (0x4000A058u) +#define INT_MGMTCFG_RESET (0x00000000u) +/* INT_MGMTDMAPROT field */ +#define INT_MGMTDMAPROT (0x00000010u) +#define INT_MGMTDMAPROT_MASK (0x00000010u) +#define INT_MGMTDMAPROT_BIT (4) +#define INT_MGMTDMAPROT_BITS (1) +/* INT_MGMTCALADC field */ +#define INT_MGMTCALADC (0x00000008u) +#define INT_MGMTCALADC_MASK (0x00000008u) +#define INT_MGMTCALADC_BIT (3) +#define INT_MGMTCALADC_BITS (1) +/* INT_MGMTFPEC field */ +#define INT_MGMTFPEC (0x00000004u) +#define INT_MGMTFPEC_MASK (0x00000004u) +#define INT_MGMTFPEC_BIT (2) +#define INT_MGMTFPEC_BITS (1) +/* INT_MGMTOSC24MHI field */ +#define INT_MGMTOSC24MHI (0x00000002u) +#define INT_MGMTOSC24MHI_MASK (0x00000002u) +#define INT_MGMTOSC24MHI_BIT (1) +#define INT_MGMTOSC24MHI_BITS (1) +/* INT_MGMTOSC24MLO field */ +#define INT_MGMTOSC24MLO (0x00000001u) +#define INT_MGMTOSC24MLO_MASK (0x00000001u) +#define INT_MGMTOSC24MLO_BIT (0) +#define INT_MGMTOSC24MLO_BITS (1) + +#define INT_TIM1FLAG *((volatile uint32_t *)0x4000A800u) +#define INT_TIM1FLAG_REG *((volatile uint32_t *)0x4000A800u) +#define INT_TIM1FLAG_ADDR (0x4000A800u) +#define INT_TIM1FLAG_RESET (0x00000000u) +/* INT_TIMRSVD field */ +#define INT_TIMRSVD (0x00001E00u) +#define INT_TIMRSVD_MASK (0x00001E00u) +#define INT_TIMRSVD_BIT (9) +#define INT_TIMRSVD_BITS (4) +/* INT_TIMTIF field */ +#define INT_TIMTIF (0x00000040u) +#define INT_TIMTIF_MASK (0x00000040u) +#define INT_TIMTIF_BIT (6) +#define INT_TIMTIF_BITS (1) +/* INT_TIMCC4IF field */ +#define INT_TIMCC4IF (0x00000010u) +#define INT_TIMCC4IF_MASK (0x00000010u) +#define INT_TIMCC4IF_BIT (4) +#define INT_TIMCC4IF_BITS (1) +/* INT_TIMCC3IF field */ +#define INT_TIMCC3IF (0x00000008u) +#define INT_TIMCC3IF_MASK (0x00000008u) +#define INT_TIMCC3IF_BIT (3) +#define INT_TIMCC3IF_BITS (1) +/* INT_TIMCC2IF field */ +#define INT_TIMCC2IF (0x00000004u) +#define INT_TIMCC2IF_MASK (0x00000004u) +#define INT_TIMCC2IF_BIT (2) +#define INT_TIMCC2IF_BITS (1) +/* INT_TIMCC1IF field */ +#define INT_TIMCC1IF (0x00000002u) +#define INT_TIMCC1IF_MASK (0x00000002u) +#define INT_TIMCC1IF_BIT (1) +#define INT_TIMCC1IF_BITS (1) +/* INT_TIMUIF field */ +#define INT_TIMUIF (0x00000001u) +#define INT_TIMUIF_MASK (0x00000001u) +#define INT_TIMUIF_BIT (0) +#define INT_TIMUIF_BITS (1) + +#define INT_TIM2FLAG *((volatile uint32_t *)0x4000A804u) +#define INT_TIM2FLAG_REG *((volatile uint32_t *)0x4000A804u) +#define INT_TIM2FLAG_ADDR (0x4000A804u) +#define INT_TIM2FLAG_RESET (0x00000000u) +/* INT_TIMRSVD field */ +#define INT_TIMRSVD (0x00001E00u) +#define INT_TIMRSVD_MASK (0x00001E00u) +#define INT_TIMRSVD_BIT (9) +#define INT_TIMRSVD_BITS (4) +/* INT_TIMTIF field */ +#define INT_TIMTIF (0x00000040u) +#define INT_TIMTIF_MASK (0x00000040u) +#define INT_TIMTIF_BIT (6) +#define INT_TIMTIF_BITS (1) +/* INT_TIMCC4IF field */ +#define INT_TIMCC4IF (0x00000010u) +#define INT_TIMCC4IF_MASK (0x00000010u) +#define INT_TIMCC4IF_BIT (4) +#define INT_TIMCC4IF_BITS (1) +/* INT_TIMCC3IF field */ +#define INT_TIMCC3IF (0x00000008u) +#define INT_TIMCC3IF_MASK (0x00000008u) +#define INT_TIMCC3IF_BIT (3) +#define INT_TIMCC3IF_BITS (1) +/* INT_TIMCC2IF field */ +#define INT_TIMCC2IF (0x00000004u) +#define INT_TIMCC2IF_MASK (0x00000004u) +#define INT_TIMCC2IF_BIT (2) +#define INT_TIMCC2IF_BITS (1) +/* INT_TIMCC1IF field */ +#define INT_TIMCC1IF (0x00000002u) +#define INT_TIMCC1IF_MASK (0x00000002u) +#define INT_TIMCC1IF_BIT (1) +#define INT_TIMCC1IF_BITS (1) +/* INT_TIMUIF field */ +#define INT_TIMUIF (0x00000001u) +#define INT_TIMUIF_MASK (0x00000001u) +#define INT_TIMUIF_BIT (0) +#define INT_TIMUIF_BITS (1) + +#define INT_SC1FLAG *((volatile uint32_t *)0x4000A808u) +#define INT_SC1FLAG_REG *((volatile uint32_t *)0x4000A808u) +#define INT_SC1FLAG_ADDR (0x4000A808u) +#define INT_SC1FLAG_RESET (0x00000000u) +/* INT_SC1PARERR field */ +#define INT_SC1PARERR (0x00004000u) +#define INT_SC1PARERR_MASK (0x00004000u) +#define INT_SC1PARERR_BIT (14) +#define INT_SC1PARERR_BITS (1) +/* INT_SC1FRMERR field */ +#define INT_SC1FRMERR (0x00002000u) +#define INT_SC1FRMERR_MASK (0x00002000u) +#define INT_SC1FRMERR_BIT (13) +#define INT_SC1FRMERR_BITS (1) +/* INT_SCTXULDB field */ +#define INT_SCTXULDB (0x00001000u) +#define INT_SCTXULDB_MASK (0x00001000u) +#define INT_SCTXULDB_BIT (12) +#define INT_SCTXULDB_BITS (1) +/* INT_SCTXULDA field */ +#define INT_SCTXULDA (0x00000800u) +#define INT_SCTXULDA_MASK (0x00000800u) +#define INT_SCTXULDA_BIT (11) +#define INT_SCTXULDA_BITS (1) +/* INT_SCRXULDB field */ +#define INT_SCRXULDB (0x00000400u) +#define INT_SCRXULDB_MASK (0x00000400u) +#define INT_SCRXULDB_BIT (10) +#define INT_SCRXULDB_BITS (1) +/* INT_SCRXULDA field */ +#define INT_SCRXULDA (0x00000200u) +#define INT_SCRXULDA_MASK (0x00000200u) +#define INT_SCRXULDA_BIT (9) +#define INT_SCRXULDA_BITS (1) +/* INT_SCNAK field */ +#define INT_SCNAK (0x00000100u) +#define INT_SCNAK_MASK (0x00000100u) +#define INT_SCNAK_BIT (8) +#define INT_SCNAK_BITS (1) +/* INT_SCCMDFIN field */ +#define INT_SCCMDFIN (0x00000080u) +#define INT_SCCMDFIN_MASK (0x00000080u) +#define INT_SCCMDFIN_BIT (7) +#define INT_SCCMDFIN_BITS (1) +/* INT_SCTXFIN field */ +#define INT_SCTXFIN (0x00000040u) +#define INT_SCTXFIN_MASK (0x00000040u) +#define INT_SCTXFIN_BIT (6) +#define INT_SCTXFIN_BITS (1) +/* INT_SCRXFIN field */ +#define INT_SCRXFIN (0x00000020u) +#define INT_SCRXFIN_MASK (0x00000020u) +#define INT_SCRXFIN_BIT (5) +#define INT_SCRXFIN_BITS (1) +/* INT_SCTXUND field */ +#define INT_SCTXUND (0x00000010u) +#define INT_SCTXUND_MASK (0x00000010u) +#define INT_SCTXUND_BIT (4) +#define INT_SCTXUND_BITS (1) +/* INT_SCRXOVF field */ +#define INT_SCRXOVF (0x00000008u) +#define INT_SCRXOVF_MASK (0x00000008u) +#define INT_SCRXOVF_BIT (3) +#define INT_SCRXOVF_BITS (1) +/* INT_SCTXIDLE field */ +#define INT_SCTXIDLE (0x00000004u) +#define INT_SCTXIDLE_MASK (0x00000004u) +#define INT_SCTXIDLE_BIT (2) +#define INT_SCTXIDLE_BITS (1) +/* INT_SCTXFREE field */ +#define INT_SCTXFREE (0x00000002u) +#define INT_SCTXFREE_MASK (0x00000002u) +#define INT_SCTXFREE_BIT (1) +#define INT_SCTXFREE_BITS (1) +/* INT_SCRXVAL field */ +#define INT_SCRXVAL (0x00000001u) +#define INT_SCRXVAL_MASK (0x00000001u) +#define INT_SCRXVAL_BIT (0) +#define INT_SCRXVAL_BITS (1) + +#define INT_SC2FLAG *((volatile uint32_t *)0x4000A80Cu) +#define INT_SC2FLAG_REG *((volatile uint32_t *)0x4000A80Cu) +#define INT_SC2FLAG_ADDR (0x4000A80Cu) +#define INT_SC2FLAG_RESET (0x00000000u) +/* INT_SCTXULDB field */ +#define INT_SCTXULDB (0x00001000u) +#define INT_SCTXULDB_MASK (0x00001000u) +#define INT_SCTXULDB_BIT (12) +#define INT_SCTXULDB_BITS (1) +/* INT_SCTXULDA field */ +#define INT_SCTXULDA (0x00000800u) +#define INT_SCTXULDA_MASK (0x00000800u) +#define INT_SCTXULDA_BIT (11) +#define INT_SCTXULDA_BITS (1) +/* INT_SCRXULDB field */ +#define INT_SCRXULDB (0x00000400u) +#define INT_SCRXULDB_MASK (0x00000400u) +#define INT_SCRXULDB_BIT (10) +#define INT_SCRXULDB_BITS (1) +/* INT_SCRXULDA field */ +#define INT_SCRXULDA (0x00000200u) +#define INT_SCRXULDA_MASK (0x00000200u) +#define INT_SCRXULDA_BIT (9) +#define INT_SCRXULDA_BITS (1) +/* INT_SCNAK field */ +#define INT_SCNAK (0x00000100u) +#define INT_SCNAK_MASK (0x00000100u) +#define INT_SCNAK_BIT (8) +#define INT_SCNAK_BITS (1) +/* INT_SCCMDFIN field */ +#define INT_SCCMDFIN (0x00000080u) +#define INT_SCCMDFIN_MASK (0x00000080u) +#define INT_SCCMDFIN_BIT (7) +#define INT_SCCMDFIN_BITS (1) +/* INT_SCTXFIN field */ +#define INT_SCTXFIN (0x00000040u) +#define INT_SCTXFIN_MASK (0x00000040u) +#define INT_SCTXFIN_BIT (6) +#define INT_SCTXFIN_BITS (1) +/* INT_SCRXFIN field */ +#define INT_SCRXFIN (0x00000020u) +#define INT_SCRXFIN_MASK (0x00000020u) +#define INT_SCRXFIN_BIT (5) +#define INT_SCRXFIN_BITS (1) +/* INT_SCTXUND field */ +#define INT_SCTXUND (0x00000010u) +#define INT_SCTXUND_MASK (0x00000010u) +#define INT_SCTXUND_BIT (4) +#define INT_SCTXUND_BITS (1) +/* INT_SCRXOVF field */ +#define INT_SCRXOVF (0x00000008u) +#define INT_SCRXOVF_MASK (0x00000008u) +#define INT_SCRXOVF_BIT (3) +#define INT_SCRXOVF_BITS (1) +/* INT_SCTXIDLE field */ +#define INT_SCTXIDLE (0x00000004u) +#define INT_SCTXIDLE_MASK (0x00000004u) +#define INT_SCTXIDLE_BIT (2) +#define INT_SCTXIDLE_BITS (1) +/* INT_SCTXFREE field */ +#define INT_SCTXFREE (0x00000002u) +#define INT_SCTXFREE_MASK (0x00000002u) +#define INT_SCTXFREE_BIT (1) +#define INT_SCTXFREE_BITS (1) +/* INT_SCRXVAL field */ +#define INT_SCRXVAL (0x00000001u) +#define INT_SCRXVAL_MASK (0x00000001u) +#define INT_SCRXVAL_BIT (0) +#define INT_SCRXVAL_BITS (1) + +#define INT_ADCFLAG *((volatile uint32_t *)0x4000A810u) +#define INT_ADCFLAG_REG *((volatile uint32_t *)0x4000A810u) +#define INT_ADCFLAG_ADDR (0x4000A810u) +#define INT_ADCFLAG_RESET (0x00000000u) +/* INT_ADCOVF field */ +#define INT_ADCOVF (0x00000010u) +#define INT_ADCOVF_MASK (0x00000010u) +#define INT_ADCOVF_BIT (4) +#define INT_ADCOVF_BITS (1) +/* INT_ADCSAT field */ +#define INT_ADCSAT (0x00000008u) +#define INT_ADCSAT_MASK (0x00000008u) +#define INT_ADCSAT_BIT (3) +#define INT_ADCSAT_BITS (1) +/* INT_ADCULDFULL field */ +#define INT_ADCULDFULL (0x00000004u) +#define INT_ADCULDFULL_MASK (0x00000004u) +#define INT_ADCULDFULL_BIT (2) +#define INT_ADCULDFULL_BITS (1) +/* INT_ADCULDHALF field */ +#define INT_ADCULDHALF (0x00000002u) +#define INT_ADCULDHALF_MASK (0x00000002u) +#define INT_ADCULDHALF_BIT (1) +#define INT_ADCULDHALF_BITS (1) +/* INT_ADCFLAGRSVD field */ +#define INT_ADCFLAGRSVD (0x00000001u) +#define INT_ADCFLAGRSVD_MASK (0x00000001u) +#define INT_ADCFLAGRSVD_BIT (0) +#define INT_ADCFLAGRSVD_BITS (1) + +#define INT_GPIOFLAG *((volatile uint32_t *)0x4000A814u) +#define INT_GPIOFLAG_REG *((volatile uint32_t *)0x4000A814u) +#define INT_GPIOFLAG_ADDR (0x4000A814u) +#define INT_GPIOFLAG_RESET (0x00000000u) +/* INT_IRQDFLAG field */ +#define INT_IRQDFLAG (0x00000008u) +#define INT_IRQDFLAG_MASK (0x00000008u) +#define INT_IRQDFLAG_BIT (3) +#define INT_IRQDFLAG_BITS (1) +/* INT_IRQCFLAG field */ +#define INT_IRQCFLAG (0x00000004u) +#define INT_IRQCFLAG_MASK (0x00000004u) +#define INT_IRQCFLAG_BIT (2) +#define INT_IRQCFLAG_BITS (1) +/* INT_IRQBFLAG field */ +#define INT_IRQBFLAG (0x00000002u) +#define INT_IRQBFLAG_MASK (0x00000002u) +#define INT_IRQBFLAG_BIT (1) +#define INT_IRQBFLAG_BITS (1) +/* INT_IRQAFLAG field */ +#define INT_IRQAFLAG (0x00000001u) +#define INT_IRQAFLAG_MASK (0x00000001u) +#define INT_IRQAFLAG_BIT (0) +#define INT_IRQAFLAG_BITS (1) + +#define INT_TIM1MISS *((volatile uint32_t *)0x4000A818u) +#define INT_TIM1MISS_REG *((volatile uint32_t *)0x4000A818u) +#define INT_TIM1MISS_ADDR (0x4000A818u) +#define INT_TIM1MISS_RESET (0x00000000u) +/* INT_TIMMISSCC4IF field */ +#define INT_TIMMISSCC4IF (0x00001000u) +#define INT_TIMMISSCC4IF_MASK (0x00001000u) +#define INT_TIMMISSCC4IF_BIT (12) +#define INT_TIMMISSCC4IF_BITS (1) +/* INT_TIMMISSCC3IF field */ +#define INT_TIMMISSCC3IF (0x00000800u) +#define INT_TIMMISSCC3IF_MASK (0x00000800u) +#define INT_TIMMISSCC3IF_BIT (11) +#define INT_TIMMISSCC3IF_BITS (1) +/* INT_TIMMISSCC2IF field */ +#define INT_TIMMISSCC2IF (0x00000400u) +#define INT_TIMMISSCC2IF_MASK (0x00000400u) +#define INT_TIMMISSCC2IF_BIT (10) +#define INT_TIMMISSCC2IF_BITS (1) +/* INT_TIMMISSCC1IF field */ +#define INT_TIMMISSCC1IF (0x00000200u) +#define INT_TIMMISSCC1IF_MASK (0x00000200u) +#define INT_TIMMISSCC1IF_BIT (9) +#define INT_TIMMISSCC1IF_BITS (1) +/* INT_TIMMISSRSVD field */ +#define INT_TIMMISSRSVD (0x0000007Fu) +#define INT_TIMMISSRSVD_MASK (0x0000007Fu) +#define INT_TIMMISSRSVD_BIT (0) +#define INT_TIMMISSRSVD_BITS (7) + +#define INT_TIM2MISS *((volatile uint32_t *)0x4000A81Cu) +#define INT_TIM2MISS_REG *((volatile uint32_t *)0x4000A81Cu) +#define INT_TIM2MISS_ADDR (0x4000A81Cu) +#define INT_TIM2MISS_RESET (0x00000000u) +/* INT_TIMMISSCC4IF field */ +#define INT_TIMMISSCC4IF (0x00001000u) +#define INT_TIMMISSCC4IF_MASK (0x00001000u) +#define INT_TIMMISSCC4IF_BIT (12) +#define INT_TIMMISSCC4IF_BITS (1) +/* INT_TIMMISSCC3IF field */ +#define INT_TIMMISSCC3IF (0x00000800u) +#define INT_TIMMISSCC3IF_MASK (0x00000800u) +#define INT_TIMMISSCC3IF_BIT (11) +#define INT_TIMMISSCC3IF_BITS (1) +/* INT_TIMMISSCC2IF field */ +#define INT_TIMMISSCC2IF (0x00000400u) +#define INT_TIMMISSCC2IF_MASK (0x00000400u) +#define INT_TIMMISSCC2IF_BIT (10) +#define INT_TIMMISSCC2IF_BITS (1) +/* INT_TIMMISSCC1IF field */ +#define INT_TIMMISSCC1IF (0x00000200u) +#define INT_TIMMISSCC1IF_MASK (0x00000200u) +#define INT_TIMMISSCC1IF_BIT (9) +#define INT_TIMMISSCC1IF_BITS (1) +/* INT_TIMMISSRSVD field */ +#define INT_TIMMISSRSVD (0x0000007Fu) +#define INT_TIMMISSRSVD_MASK (0x0000007Fu) +#define INT_TIMMISSRSVD_BIT (0) +#define INT_TIMMISSRSVD_BITS (7) + +#define INT_MISS *((volatile uint32_t *)0x4000A820u) +#define INT_MISS_REG *((volatile uint32_t *)0x4000A820u) +#define INT_MISS_ADDR (0x4000A820u) +#define INT_MISS_RESET (0x00000000u) +/* INT_MISSIRQD field */ +#define INT_MISSIRQD (0x00008000u) +#define INT_MISSIRQD_MASK (0x00008000u) +#define INT_MISSIRQD_BIT (15) +#define INT_MISSIRQD_BITS (1) +/* INT_MISSIRQC field */ +#define INT_MISSIRQC (0x00004000u) +#define INT_MISSIRQC_MASK (0x00004000u) +#define INT_MISSIRQC_BIT (14) +#define INT_MISSIRQC_BITS (1) +/* INT_MISSIRQB field */ +#define INT_MISSIRQB (0x00002000u) +#define INT_MISSIRQB_MASK (0x00002000u) +#define INT_MISSIRQB_BIT (13) +#define INT_MISSIRQB_BITS (1) +/* INT_MISSIRQA field */ +#define INT_MISSIRQA (0x00001000u) +#define INT_MISSIRQA_MASK (0x00001000u) +#define INT_MISSIRQA_BIT (12) +#define INT_MISSIRQA_BITS (1) +/* INT_MISSADC field */ +#define INT_MISSADC (0x00000800u) +#define INT_MISSADC_MASK (0x00000800u) +#define INT_MISSADC_BIT (11) +#define INT_MISSADC_BITS (1) +/* INT_MISSMACRX field */ +#define INT_MISSMACRX (0x00000400u) +#define INT_MISSMACRX_MASK (0x00000400u) +#define INT_MISSMACRX_BIT (10) +#define INT_MISSMACRX_BITS (1) +/* INT_MISSMACTX field */ +#define INT_MISSMACTX (0x00000200u) +#define INT_MISSMACTX_MASK (0x00000200u) +#define INT_MISSMACTX_BIT (9) +#define INT_MISSMACTX_BITS (1) +/* INT_MISSMACTMR field */ +#define INT_MISSMACTMR (0x00000100u) +#define INT_MISSMACTMR_MASK (0x00000100u) +#define INT_MISSMACTMR_BIT (8) +#define INT_MISSMACTMR_BITS (1) +/* INT_MISSSEC field */ +#define INT_MISSSEC (0x00000080u) +#define INT_MISSSEC_MASK (0x00000080u) +#define INT_MISSSEC_BIT (7) +#define INT_MISSSEC_BITS (1) +/* INT_MISSSC2 field */ +#define INT_MISSSC2 (0x00000040u) +#define INT_MISSSC2_MASK (0x00000040u) +#define INT_MISSSC2_BIT (6) +#define INT_MISSSC2_BITS (1) +/* INT_MISSSC1 field */ +#define INT_MISSSC1 (0x00000020u) +#define INT_MISSSC1_MASK (0x00000020u) +#define INT_MISSSC1_BIT (5) +#define INT_MISSSC1_BITS (1) +/* INT_MISSSLEEP field */ +#define INT_MISSSLEEP (0x00000010u) +#define INT_MISSSLEEP_MASK (0x00000010u) +#define INT_MISSSLEEP_BIT (4) +#define INT_MISSSLEEP_BITS (1) +/* INT_MISSBB field */ +#define INT_MISSBB (0x00000008u) +#define INT_MISSBB_MASK (0x00000008u) +#define INT_MISSBB_BIT (3) +#define INT_MISSBB_BITS (1) +/* INT_MISSMGMT field */ +#define INT_MISSMGMT (0x00000004u) +#define INT_MISSMGMT_MASK (0x00000004u) +#define INT_MISSMGMT_BIT (2) +#define INT_MISSMGMT_BITS (1) + +#define INT_TIM1CFG *((volatile uint32_t *)0x4000A840u) +#define INT_TIM1CFG_REG *((volatile uint32_t *)0x4000A840u) +#define INT_TIM1CFG_ADDR (0x4000A840u) +#define INT_TIM1CFG_RESET (0x00000000u) +/* INT_TIMTIF field */ +#define INT_TIMTIF (0x00000040u) +#define INT_TIMTIF_MASK (0x00000040u) +#define INT_TIMTIF_BIT (6) +#define INT_TIMTIF_BITS (1) +/* INT_TIMCC4IF field */ +#define INT_TIMCC4IF (0x00000010u) +#define INT_TIMCC4IF_MASK (0x00000010u) +#define INT_TIMCC4IF_BIT (4) +#define INT_TIMCC4IF_BITS (1) +/* INT_TIMCC3IF field */ +#define INT_TIMCC3IF (0x00000008u) +#define INT_TIMCC3IF_MASK (0x00000008u) +#define INT_TIMCC3IF_BIT (3) +#define INT_TIMCC3IF_BITS (1) +/* INT_TIMCC2IF field */ +#define INT_TIMCC2IF (0x00000004u) +#define INT_TIMCC2IF_MASK (0x00000004u) +#define INT_TIMCC2IF_BIT (2) +#define INT_TIMCC2IF_BITS (1) +/* INT_TIMCC1IF field */ +#define INT_TIMCC1IF (0x00000002u) +#define INT_TIMCC1IF_MASK (0x00000002u) +#define INT_TIMCC1IF_BIT (1) +#define INT_TIMCC1IF_BITS (1) +/* INT_TIMUIF field */ +#define INT_TIMUIF (0x00000001u) +#define INT_TIMUIF_MASK (0x00000001u) +#define INT_TIMUIF_BIT (0) +#define INT_TIMUIF_BITS (1) + +#define INT_TIM2CFG *((volatile uint32_t *)0x4000A844u) +#define INT_TIM2CFG_REG *((volatile uint32_t *)0x4000A844u) +#define INT_TIM2CFG_ADDR (0x4000A844u) +#define INT_TIM2CFG_RESET (0x00000000u) +/* INT_TIMTIF field */ +#define INT_TIMTIF (0x00000040u) +#define INT_TIMTIF_MASK (0x00000040u) +#define INT_TIMTIF_BIT (6) +#define INT_TIMTIF_BITS (1) +/* INT_TIMCC4IF field */ +#define INT_TIMCC4IF (0x00000010u) +#define INT_TIMCC4IF_MASK (0x00000010u) +#define INT_TIMCC4IF_BIT (4) +#define INT_TIMCC4IF_BITS (1) +/* INT_TIMCC3IF field */ +#define INT_TIMCC3IF (0x00000008u) +#define INT_TIMCC3IF_MASK (0x00000008u) +#define INT_TIMCC3IF_BIT (3) +#define INT_TIMCC3IF_BITS (1) +/* INT_TIMCC2IF field */ +#define INT_TIMCC2IF (0x00000004u) +#define INT_TIMCC2IF_MASK (0x00000004u) +#define INT_TIMCC2IF_BIT (2) +#define INT_TIMCC2IF_BITS (1) +/* INT_TIMCC1IF field */ +#define INT_TIMCC1IF (0x00000002u) +#define INT_TIMCC1IF_MASK (0x00000002u) +#define INT_TIMCC1IF_BIT (1) +#define INT_TIMCC1IF_BITS (1) +/* INT_TIMUIF field */ +#define INT_TIMUIF (0x00000001u) +#define INT_TIMUIF_MASK (0x00000001u) +#define INT_TIMUIF_BIT (0) +#define INT_TIMUIF_BITS (1) + +#define INT_SC1CFG *((volatile uint32_t *)0x4000A848u) +#define INT_SC1CFG_REG *((volatile uint32_t *)0x4000A848u) +#define INT_SC1CFG_ADDR (0x4000A848u) +#define INT_SC1CFG_RESET (0x00000000u) +/* INT_SC1PARERR field */ +#define INT_SC1PARERR (0x00004000u) +#define INT_SC1PARERR_MASK (0x00004000u) +#define INT_SC1PARERR_BIT (14) +#define INT_SC1PARERR_BITS (1) +/* INT_SC1FRMERR field */ +#define INT_SC1FRMERR (0x00002000u) +#define INT_SC1FRMERR_MASK (0x00002000u) +#define INT_SC1FRMERR_BIT (13) +#define INT_SC1FRMERR_BITS (1) +/* INT_SCTXULDB field */ +#define INT_SCTXULDB (0x00001000u) +#define INT_SCTXULDB_MASK (0x00001000u) +#define INT_SCTXULDB_BIT (12) +#define INT_SCTXULDB_BITS (1) +/* INT_SCTXULDA field */ +#define INT_SCTXULDA (0x00000800u) +#define INT_SCTXULDA_MASK (0x00000800u) +#define INT_SCTXULDA_BIT (11) +#define INT_SCTXULDA_BITS (1) +/* INT_SCRXULDB field */ +#define INT_SCRXULDB (0x00000400u) +#define INT_SCRXULDB_MASK (0x00000400u) +#define INT_SCRXULDB_BIT (10) +#define INT_SCRXULDB_BITS (1) +/* INT_SCRXULDA field */ +#define INT_SCRXULDA (0x00000200u) +#define INT_SCRXULDA_MASK (0x00000200u) +#define INT_SCRXULDA_BIT (9) +#define INT_SCRXULDA_BITS (1) +/* INT_SCNAK field */ +#define INT_SCNAK (0x00000100u) +#define INT_SCNAK_MASK (0x00000100u) +#define INT_SCNAK_BIT (8) +#define INT_SCNAK_BITS (1) +/* INT_SCCMDFIN field */ +#define INT_SCCMDFIN (0x00000080u) +#define INT_SCCMDFIN_MASK (0x00000080u) +#define INT_SCCMDFIN_BIT (7) +#define INT_SCCMDFIN_BITS (1) +/* INT_SCTXFIN field */ +#define INT_SCTXFIN (0x00000040u) +#define INT_SCTXFIN_MASK (0x00000040u) +#define INT_SCTXFIN_BIT (6) +#define INT_SCTXFIN_BITS (1) +/* INT_SCRXFIN field */ +#define INT_SCRXFIN (0x00000020u) +#define INT_SCRXFIN_MASK (0x00000020u) +#define INT_SCRXFIN_BIT (5) +#define INT_SCRXFIN_BITS (1) +/* INT_SCTXUND field */ +#define INT_SCTXUND (0x00000010u) +#define INT_SCTXUND_MASK (0x00000010u) +#define INT_SCTXUND_BIT (4) +#define INT_SCTXUND_BITS (1) +/* INT_SCRXOVF field */ +#define INT_SCRXOVF (0x00000008u) +#define INT_SCRXOVF_MASK (0x00000008u) +#define INT_SCRXOVF_BIT (3) +#define INT_SCRXOVF_BITS (1) +/* INT_SCTXIDLE field */ +#define INT_SCTXIDLE (0x00000004u) +#define INT_SCTXIDLE_MASK (0x00000004u) +#define INT_SCTXIDLE_BIT (2) +#define INT_SCTXIDLE_BITS (1) +/* INT_SCTXFREE field */ +#define INT_SCTXFREE (0x00000002u) +#define INT_SCTXFREE_MASK (0x00000002u) +#define INT_SCTXFREE_BIT (1) +#define INT_SCTXFREE_BITS (1) +/* INT_SCRXVAL field */ +#define INT_SCRXVAL (0x00000001u) +#define INT_SCRXVAL_MASK (0x00000001u) +#define INT_SCRXVAL_BIT (0) +#define INT_SCRXVAL_BITS (1) + +#define INT_SC2CFG *((volatile uint32_t *)0x4000A84Cu) +#define INT_SC2CFG_REG *((volatile uint32_t *)0x4000A84Cu) +#define INT_SC2CFG_ADDR (0x4000A84Cu) +#define INT_SC2CFG_RESET (0x00000000u) +/* INT_SCTXULDB field */ +#define INT_SCTXULDB (0x00001000u) +#define INT_SCTXULDB_MASK (0x00001000u) +#define INT_SCTXULDB_BIT (12) +#define INT_SCTXULDB_BITS (1) +/* INT_SCTXULDA field */ +#define INT_SCTXULDA (0x00000800u) +#define INT_SCTXULDA_MASK (0x00000800u) +#define INT_SCTXULDA_BIT (11) +#define INT_SCTXULDA_BITS (1) +/* INT_SCRXULDB field */ +#define INT_SCRXULDB (0x00000400u) +#define INT_SCRXULDB_MASK (0x00000400u) +#define INT_SCRXULDB_BIT (10) +#define INT_SCRXULDB_BITS (1) +/* INT_SCRXULDA field */ +#define INT_SCRXULDA (0x00000200u) +#define INT_SCRXULDA_MASK (0x00000200u) +#define INT_SCRXULDA_BIT (9) +#define INT_SCRXULDA_BITS (1) +/* INT_SCNAK field */ +#define INT_SCNAK (0x00000100u) +#define INT_SCNAK_MASK (0x00000100u) +#define INT_SCNAK_BIT (8) +#define INT_SCNAK_BITS (1) +/* INT_SCCMDFIN field */ +#define INT_SCCMDFIN (0x00000080u) +#define INT_SCCMDFIN_MASK (0x00000080u) +#define INT_SCCMDFIN_BIT (7) +#define INT_SCCMDFIN_BITS (1) +/* INT_SCTXFIN field */ +#define INT_SCTXFIN (0x00000040u) +#define INT_SCTXFIN_MASK (0x00000040u) +#define INT_SCTXFIN_BIT (6) +#define INT_SCTXFIN_BITS (1) +/* INT_SCRXFIN field */ +#define INT_SCRXFIN (0x00000020u) +#define INT_SCRXFIN_MASK (0x00000020u) +#define INT_SCRXFIN_BIT (5) +#define INT_SCRXFIN_BITS (1) +/* INT_SCTXUND field */ +#define INT_SCTXUND (0x00000010u) +#define INT_SCTXUND_MASK (0x00000010u) +#define INT_SCTXUND_BIT (4) +#define INT_SCTXUND_BITS (1) +/* INT_SCRXOVF field */ +#define INT_SCRXOVF (0x00000008u) +#define INT_SCRXOVF_MASK (0x00000008u) +#define INT_SCRXOVF_BIT (3) +#define INT_SCRXOVF_BITS (1) +/* INT_SCTXIDLE field */ +#define INT_SCTXIDLE (0x00000004u) +#define INT_SCTXIDLE_MASK (0x00000004u) +#define INT_SCTXIDLE_BIT (2) +#define INT_SCTXIDLE_BITS (1) +/* INT_SCTXFREE field */ +#define INT_SCTXFREE (0x00000002u) +#define INT_SCTXFREE_MASK (0x00000002u) +#define INT_SCTXFREE_BIT (1) +#define INT_SCTXFREE_BITS (1) +/* INT_SCRXVAL field */ +#define INT_SCRXVAL (0x00000001u) +#define INT_SCRXVAL_MASK (0x00000001u) +#define INT_SCRXVAL_BIT (0) +#define INT_SCRXVAL_BITS (1) + +#define INT_ADCCFG *((volatile uint32_t *)0x4000A850u) +#define INT_ADCCFG_REG *((volatile uint32_t *)0x4000A850u) +#define INT_ADCCFG_ADDR (0x4000A850u) +#define INT_ADCCFG_RESET (0x00000000u) +/* INT_ADCOVF field */ +#define INT_ADCOVF (0x00000010u) +#define INT_ADCOVF_MASK (0x00000010u) +#define INT_ADCOVF_BIT (4) +#define INT_ADCOVF_BITS (1) +/* INT_ADCSAT field */ +#define INT_ADCSAT (0x00000008u) +#define INT_ADCSAT_MASK (0x00000008u) +#define INT_ADCSAT_BIT (3) +#define INT_ADCSAT_BITS (1) +/* INT_ADCULDFULL field */ +#define INT_ADCULDFULL (0x00000004u) +#define INT_ADCULDFULL_MASK (0x00000004u) +#define INT_ADCULDFULL_BIT (2) +#define INT_ADCULDFULL_BITS (1) +/* INT_ADCULDHALF field */ +#define INT_ADCULDHALF (0x00000002u) +#define INT_ADCULDHALF_MASK (0x00000002u) +#define INT_ADCULDHALF_BIT (1) +#define INT_ADCULDHALF_BITS (1) +/* INT_ADCCFGRSVD field */ +#define INT_ADCCFGRSVD (0x00000001u) +#define INT_ADCCFGRSVD_MASK (0x00000001u) +#define INT_ADCCFGRSVD_BIT (0) +#define INT_ADCCFGRSVD_BITS (1) + +#define SC1_INTMODE *((volatile uint32_t *)0x4000A854u) +#define SC1_INTMODE_REG *((volatile uint32_t *)0x4000A854u) +#define SC1_INTMODE_ADDR (0x4000A854u) +#define SC1_INTMODE_RESET (0x00000000u) +/* SC_TXIDLELEVEL field */ +#define SC_TXIDLELEVEL (0x00000004u) +#define SC_TXIDLELEVEL_MASK (0x00000004u) +#define SC_TXIDLELEVEL_BIT (2) +#define SC_TXIDLELEVEL_BITS (1) +/* SC_TXFREELEVEL field */ +#define SC_TXFREELEVEL (0x00000002u) +#define SC_TXFREELEVEL_MASK (0x00000002u) +#define SC_TXFREELEVEL_BIT (1) +#define SC_TXFREELEVEL_BITS (1) +/* SC_RXVALLEVEL field */ +#define SC_RXVALLEVEL (0x00000001u) +#define SC_RXVALLEVEL_MASK (0x00000001u) +#define SC_RXVALLEVEL_BIT (0) +#define SC_RXVALLEVEL_BITS (1) + +#define SC2_INTMODE *((volatile uint32_t *)0x4000A858u) +#define SC2_INTMODE_REG *((volatile uint32_t *)0x4000A858u) +#define SC2_INTMODE_ADDR (0x4000A858u) +#define SC2_INTMODE_RESET (0x00000000u) +/* SC_TXIDLELEVEL field */ +#define SC_TXIDLELEVEL (0x00000004u) +#define SC_TXIDLELEVEL_MASK (0x00000004u) +#define SC_TXIDLELEVEL_BIT (2) +#define SC_TXIDLELEVEL_BITS (1) +/* SC_TXFREELEVEL field */ +#define SC_TXFREELEVEL (0x00000002u) +#define SC_TXFREELEVEL_MASK (0x00000002u) +#define SC_TXFREELEVEL_BIT (1) +#define SC_TXFREELEVEL_BITS (1) +/* SC_RXVALLEVEL field */ +#define SC_RXVALLEVEL (0x00000001u) +#define SC_RXVALLEVEL_MASK (0x00000001u) +#define SC_RXVALLEVEL_BIT (0) +#define SC_RXVALLEVEL_BITS (1) + +#define GPIO_INTCFGA *((volatile uint32_t *)0x4000A860u) +#define GPIO_INTCFGA_REG *((volatile uint32_t *)0x4000A860u) +#define GPIO_INTCFGA_ADDR (0x4000A860u) +#define GPIO_INTCFGA_RESET (0x00000000u) +/* GPIO_INTFILT field */ +#define GPIO_INTFILT (0x00000100u) +#define GPIO_INTFILT_MASK (0x00000100u) +#define GPIO_INTFILT_BIT (8) +#define GPIO_INTFILT_BITS (1) +/* GPIO_INTMOD field */ +#define GPIO_INTMOD (0x000000E0u) +#define GPIO_INTMOD_MASK (0x000000E0u) +#define GPIO_INTMOD_BIT (5) +#define GPIO_INTMOD_BITS (3) + +#define GPIO_INTCFGB *((volatile uint32_t *)0x4000A864u) +#define GPIO_INTCFGB_REG *((volatile uint32_t *)0x4000A864u) +#define GPIO_INTCFGB_ADDR (0x4000A864u) +#define GPIO_INTCFGB_RESET (0x00000000u) +/* GPIO_INTFILT field */ +#define GPIO_INTFILT (0x00000100u) +#define GPIO_INTFILT_MASK (0x00000100u) +#define GPIO_INTFILT_BIT (8) +#define GPIO_INTFILT_BITS (1) +/* GPIO_INTMOD field */ +#define GPIO_INTMOD (0x000000E0u) +#define GPIO_INTMOD_MASK (0x000000E0u) +#define GPIO_INTMOD_BIT (5) +#define GPIO_INTMOD_BITS (3) + +#define GPIO_INTCFGC *((volatile uint32_t *)0x4000A868u) +#define GPIO_INTCFGC_REG *((volatile uint32_t *)0x4000A868u) +#define GPIO_INTCFGC_ADDR (0x4000A868u) +#define GPIO_INTCFGC_RESET (0x00000000u) +/* GPIO_INTFILT field */ +#define GPIO_INTFILT (0x00000100u) +#define GPIO_INTFILT_MASK (0x00000100u) +#define GPIO_INTFILT_BIT (8) +#define GPIO_INTFILT_BITS (1) +/* GPIO_INTMOD field */ +#define GPIO_INTMOD (0x000000E0u) +#define GPIO_INTMOD_MASK (0x000000E0u) +#define GPIO_INTMOD_BIT (5) +#define GPIO_INTMOD_BITS (3) + +#define GPIO_INTCFGD *((volatile uint32_t *)0x4000A86Cu) +#define GPIO_INTCFGD_REG *((volatile uint32_t *)0x4000A86Cu) +#define GPIO_INTCFGD_ADDR (0x4000A86Cu) +#define GPIO_INTCFGD_RESET (0x00000000u) +/* GPIO_INTFILT field */ +#define GPIO_INTFILT (0x00000100u) +#define GPIO_INTFILT_MASK (0x00000100u) +#define GPIO_INTFILT_BIT (8) +#define GPIO_INTFILT_BITS (1) +/* GPIO_INTMOD field */ +#define GPIO_INTMOD (0x000000E0u) +#define GPIO_INTMOD_MASK (0x000000E0u) +#define GPIO_INTMOD_BIT (5) +#define GPIO_INTMOD_BITS (3) + +/* GPIO block */ +#define BLOCK_GPIO_BASE (0x4000B000u) +#define BLOCK_GPIO_END (0x4000BC1Cu) +#define BLOCK_GPIO_SIZE (BLOCK_GPIO_END - BLOCK_GPIO_BASE + 1) + +#define GPIO_PACFGL *((volatile uint32_t *)0x4000B000u) +#define GPIO_PACFGL_REG *((volatile uint32_t *)0x4000B000u) +#define GPIO_PACFGL_ADDR (0x4000B000u) +#define GPIO_PACFGL_RESET (0x00004444u) +/* PA3_CFG field */ +#define PA3_CFG (0x0000F000u) +#define PA3_CFG_MASK (0x0000F000u) +#define PA3_CFG_BIT (12) +#define PA3_CFG_BITS (4) +/* PA2_CFG field */ +#define PA2_CFG (0x00000F00u) +#define PA2_CFG_MASK (0x00000F00u) +#define PA2_CFG_BIT (8) +#define PA2_CFG_BITS (4) +/* PA1_CFG field */ +#define PA1_CFG (0x000000F0u) +#define PA1_CFG_MASK (0x000000F0u) +#define PA1_CFG_BIT (4) +#define PA1_CFG_BITS (4) +/* PA0_CFG field */ +#define PA0_CFG (0x0000000Fu) +#define PA0_CFG_MASK (0x0000000Fu) +#define PA0_CFG_BIT (0) +#define PA0_CFG_BITS (4) +/* GPIO_PxCFGx Bit Field Values */ +#define GPIOCFG_OUT (0x1u) +#define GPIOCFG_OUT_OD (0x5u) +#define GPIOCFG_OUT_ALT (0x9u) +#define GPIOCFG_OUT_ALT_OD (0xDu) +#define GPIOCFG_ANALOG (0x0u) +#define GPIOCFG_IN (0x4u) +#define GPIOCFG_IN_PUD (0x8u) + +#define GPIO_PACFGH *((volatile uint32_t *)0x4000B004u) +#define GPIO_PACFGH_REG *((volatile uint32_t *)0x4000B004u) +#define GPIO_PACFGH_ADDR (0x4000B004u) +#define GPIO_PACFGH_RESET (0x00004444u) +/* PA7_CFG field */ +#define PA7_CFG (0x0000F000u) +#define PA7_CFG_MASK (0x0000F000u) +#define PA7_CFG_BIT (12) +#define PA7_CFG_BITS (4) +/* PA6_CFG field */ +#define PA6_CFG (0x00000F00u) +#define PA6_CFG_MASK (0x00000F00u) +#define PA6_CFG_BIT (8) +#define PA6_CFG_BITS (4) +/* PA5_CFG field */ +#define PA5_CFG (0x000000F0u) +#define PA5_CFG_MASK (0x000000F0u) +#define PA5_CFG_BIT (4) +#define PA5_CFG_BITS (4) +/* PA4_CFG field */ +#define PA4_CFG (0x0000000Fu) +#define PA4_CFG_MASK (0x0000000Fu) +#define PA4_CFG_BIT (0) +#define PA4_CFG_BITS (4) + +#define GPIO_PAIN *((volatile uint32_t *)0x4000B008u) +#define GPIO_PAIN_REG *((volatile uint32_t *)0x4000B008u) +#define GPIO_PAIN_ADDR (0x4000B008u) +#define GPIO_PAIN_RESET (0x00000000u) +/* PA7 field */ +#define PA7 (0x00000080u) +#define PA7_MASK (0x00000080u) +#define PA7_BIT (7) +#define PA7_BITS (1) +/* PA6 field */ +#define PA6 (0x00000040u) +#define PA6_MASK (0x00000040u) +#define PA6_BIT (6) +#define PA6_BITS (1) +/* PA5 field */ +#define PA5 (0x00000020u) +#define PA5_MASK (0x00000020u) +#define PA5_BIT (5) +#define PA5_BITS (1) +/* PA4 field */ +#define PA4 (0x00000010u) +#define PA4_MASK (0x00000010u) +#define PA4_BIT (4) +#define PA4_BITS (1) +/* PA3 field */ +#define PA3 (0x00000008u) +#define PA3_MASK (0x00000008u) +#define PA3_BIT (3) +#define PA3_BITS (1) +/* PA2 field */ +#define PA2 (0x00000004u) +#define PA2_MASK (0x00000004u) +#define PA2_BIT (2) +#define PA2_BITS (1) +/* PA1 field */ +#define PA1 (0x00000002u) +#define PA1_MASK (0x00000002u) +#define PA1_BIT (1) +#define PA1_BITS (1) +/* PA0 field */ +#define PA0 (0x00000001u) +#define PA0_MASK (0x00000001u) +#define PA0_BIT (0) +#define PA0_BITS (1) + +#define GPIO_PAOUT *((volatile uint32_t *)0x4000B00Cu) +#define GPIO_PAOUT_REG *((volatile uint32_t *)0x4000B00Cu) +#define GPIO_PAOUT_ADDR (0x4000B00Cu) +#define GPIO_PAOUT_RESET (0x00000000u) +/* PA7 field */ +#define PA7 (0x00000080u) +#define PA7_MASK (0x00000080u) +#define PA7_BIT (7) +#define PA7_BITS (1) +/* PA6 field */ +#define PA6 (0x00000040u) +#define PA6_MASK (0x00000040u) +#define PA6_BIT (6) +#define PA6_BITS (1) +/* PA5 field */ +#define PA5 (0x00000020u) +#define PA5_MASK (0x00000020u) +#define PA5_BIT (5) +#define PA5_BITS (1) +/* PA4 field */ +#define PA4 (0x00000010u) +#define PA4_MASK (0x00000010u) +#define PA4_BIT (4) +#define PA4_BITS (1) +/* PA3 field */ +#define PA3 (0x00000008u) +#define PA3_MASK (0x00000008u) +#define PA3_BIT (3) +#define PA3_BITS (1) +/* PA2 field */ +#define PA2 (0x00000004u) +#define PA2_MASK (0x00000004u) +#define PA2_BIT (2) +#define PA2_BITS (1) +/* PA1 field */ +#define PA1 (0x00000002u) +#define PA1_MASK (0x00000002u) +#define PA1_BIT (1) +#define PA1_BITS (1) +/* PA0 field */ +#define PA0 (0x00000001u) +#define PA0_MASK (0x00000001u) +#define PA0_BIT (0) +#define PA0_BITS (1) +/* GPIO_PxOUT Bit Field Values */ +#define GPIOOUT_PULLUP (0x1u) +#define GPIOOUT_PULLDOWN (0x0u) + +#define GPIO_PASET *((volatile uint32_t *)0x4000B010u) +#define GPIO_PASET_REG *((volatile uint32_t *)0x4000B010u) +#define GPIO_PASET_ADDR (0x4000B010u) +#define GPIO_PASET_RESET (0x00000000u) +/* GPIO_PXSETRSVD field */ +#define GPIO_PXSETRSVD (0x0000FF00u) +#define GPIO_PXSETRSVD_MASK (0x0000FF00u) +#define GPIO_PXSETRSVD_BIT (8) +#define GPIO_PXSETRSVD_BITS (8) +/* PA7 field */ +#define PA7 (0x00000080u) +#define PA7_MASK (0x00000080u) +#define PA7_BIT (7) +#define PA7_BITS (1) +/* PA6 field */ +#define PA6 (0x00000040u) +#define PA6_MASK (0x00000040u) +#define PA6_BIT (6) +#define PA6_BITS (1) +/* PA5 field */ +#define PA5 (0x00000020u) +#define PA5_MASK (0x00000020u) +#define PA5_BIT (5) +#define PA5_BITS (1) +/* PA4 field */ +#define PA4 (0x00000010u) +#define PA4_MASK (0x00000010u) +#define PA4_BIT (4) +#define PA4_BITS (1) +/* PA3 field */ +#define PA3 (0x00000008u) +#define PA3_MASK (0x00000008u) +#define PA3_BIT (3) +#define PA3_BITS (1) +/* PA2 field */ +#define PA2 (0x00000004u) +#define PA2_MASK (0x00000004u) +#define PA2_BIT (2) +#define PA2_BITS (1) +/* PA1 field */ +#define PA1 (0x00000002u) +#define PA1_MASK (0x00000002u) +#define PA1_BIT (1) +#define PA1_BITS (1) +/* PA0 field */ +#define PA0 (0x00000001u) +#define PA0_MASK (0x00000001u) +#define PA0_BIT (0) +#define PA0_BITS (1) + +#define GPIO_PACLR *((volatile uint32_t *)0x4000B014u) +#define GPIO_PACLR_REG *((volatile uint32_t *)0x4000B014u) +#define GPIO_PACLR_ADDR (0x4000B014u) +#define GPIO_PACLR_RESET (0x00000000u) +/* PA7 field */ +#define PA7 (0x00000080u) +#define PA7_MASK (0x00000080u) +#define PA7_BIT (7) +#define PA7_BITS (1) +/* PA6 field */ +#define PA6 (0x00000040u) +#define PA6_MASK (0x00000040u) +#define PA6_BIT (6) +#define PA6_BITS (1) +/* PA5 field */ +#define PA5 (0x00000020u) +#define PA5_MASK (0x00000020u) +#define PA5_BIT (5) +#define PA5_BITS (1) +/* PA4 field */ +#define PA4 (0x00000010u) +#define PA4_MASK (0x00000010u) +#define PA4_BIT (4) +#define PA4_BITS (1) +/* PA3 field */ +#define PA3 (0x00000008u) +#define PA3_MASK (0x00000008u) +#define PA3_BIT (3) +#define PA3_BITS (1) +/* PA2 field */ +#define PA2 (0x00000004u) +#define PA2_MASK (0x00000004u) +#define PA2_BIT (2) +#define PA2_BITS (1) +/* PA1 field */ +#define PA1 (0x00000002u) +#define PA1_MASK (0x00000002u) +#define PA1_BIT (1) +#define PA1_BITS (1) +/* PA0 field */ +#define PA0 (0x00000001u) +#define PA0_MASK (0x00000001u) +#define PA0_BIT (0) +#define PA0_BITS (1) + +#define GPIO_PBCFGL *((volatile uint32_t *)0x4000B400u) +#define GPIO_PBCFGL_REG *((volatile uint32_t *)0x4000B400u) +#define GPIO_PBCFGL_ADDR (0x4000B400u) +#define GPIO_PBCFGL_RESET (0x00004444u) +/* PB3_CFG field */ +#define PB3_CFG (0x0000F000u) +#define PB3_CFG_MASK (0x0000F000u) +#define PB3_CFG_BIT (12) +#define PB3_CFG_BITS (4) +/* PB2_CFG field */ +#define PB2_CFG (0x00000F00u) +#define PB2_CFG_MASK (0x00000F00u) +#define PB2_CFG_BIT (8) +#define PB2_CFG_BITS (4) +/* PB1_CFG field */ +#define PB1_CFG (0x000000F0u) +#define PB1_CFG_MASK (0x000000F0u) +#define PB1_CFG_BIT (4) +#define PB1_CFG_BITS (4) +/* PB0_CFG field */ +#define PB0_CFG (0x0000000Fu) +#define PB0_CFG_MASK (0x0000000Fu) +#define PB0_CFG_BIT (0) +#define PB0_CFG_BITS (4) + +#define GPIO_PBCFGH *((volatile uint32_t *)0x4000B404u) +#define GPIO_PBCFGH_REG *((volatile uint32_t *)0x4000B404u) +#define GPIO_PBCFGH_ADDR (0x4000B404u) +#define GPIO_PBCFGH_RESET (0x00004444u) +/* PB7_CFG field */ +#define PB7_CFG (0x0000F000u) +#define PB7_CFG_MASK (0x0000F000u) +#define PB7_CFG_BIT (12) +#define PB7_CFG_BITS (4) +/* PB6_CFG field */ +#define PB6_CFG (0x00000F00u) +#define PB6_CFG_MASK (0x00000F00u) +#define PB6_CFG_BIT (8) +#define PB6_CFG_BITS (4) +/* PB5_CFG field */ +#define PB5_CFG (0x000000F0u) +#define PB5_CFG_MASK (0x000000F0u) +#define PB5_CFG_BIT (4) +#define PB5_CFG_BITS (4) +/* PB4_CFG field */ +#define PB4_CFG (0x0000000Fu) +#define PB4_CFG_MASK (0x0000000Fu) +#define PB4_CFG_BIT (0) +#define PB4_CFG_BITS (4) + +#define GPIO_PBIN *((volatile uint32_t *)0x4000B408u) +#define GPIO_PBIN_REG *((volatile uint32_t *)0x4000B408u) +#define GPIO_PBIN_ADDR (0x4000B408u) +#define GPIO_PBIN_RESET (0x00000000u) +/* PB7 field */ +#define PB7 (0x00000080u) +#define PB7_MASK (0x00000080u) +#define PB7_BIT (7) +#define PB7_BITS (1) +/* PB6 field */ +#define PB6 (0x00000040u) +#define PB6_MASK (0x00000040u) +#define PB6_BIT (6) +#define PB6_BITS (1) +/* PB5 field */ +#define PB5 (0x00000020u) +#define PB5_MASK (0x00000020u) +#define PB5_BIT (5) +#define PB5_BITS (1) +/* PB4 field */ +#define PB4 (0x00000010u) +#define PB4_MASK (0x00000010u) +#define PB4_BIT (4) +#define PB4_BITS (1) +/* PB3 field */ +#define PB3 (0x00000008u) +#define PB3_MASK (0x00000008u) +#define PB3_BIT (3) +#define PB3_BITS (1) +/* PB2 field */ +#define PB2 (0x00000004u) +#define PB2_MASK (0x00000004u) +#define PB2_BIT (2) +#define PB2_BITS (1) +/* PB1 field */ +#define PB1 (0x00000002u) +#define PB1_MASK (0x00000002u) +#define PB1_BIT (1) +#define PB1_BITS (1) +/* PB0 field */ +#define PB0 (0x00000001u) +#define PB0_MASK (0x00000001u) +#define PB0_BIT (0) +#define PB0_BITS (1) + +#define GPIO_PBOUT *((volatile uint32_t *)0x4000B40Cu) +#define GPIO_PBOUT_REG *((volatile uint32_t *)0x4000B40Cu) +#define GPIO_PBOUT_ADDR (0x4000B40Cu) +#define GPIO_PBOUT_RESET (0x00000000u) +/* PB7 field */ +#define PB7 (0x00000080u) +#define PB7_MASK (0x00000080u) +#define PB7_BIT (7) +#define PB7_BITS (1) +/* PB6 field */ +#define PB6 (0x00000040u) +#define PB6_MASK (0x00000040u) +#define PB6_BIT (6) +#define PB6_BITS (1) +/* PB5 field */ +#define PB5 (0x00000020u) +#define PB5_MASK (0x00000020u) +#define PB5_BIT (5) +#define PB5_BITS (1) +/* PB4 field */ +#define PB4 (0x00000010u) +#define PB4_MASK (0x00000010u) +#define PB4_BIT (4) +#define PB4_BITS (1) +/* PB3 field */ +#define PB3 (0x00000008u) +#define PB3_MASK (0x00000008u) +#define PB3_BIT (3) +#define PB3_BITS (1) +/* PB2 field */ +#define PB2 (0x00000004u) +#define PB2_MASK (0x00000004u) +#define PB2_BIT (2) +#define PB2_BITS (1) +/* PB1 field */ +#define PB1 (0x00000002u) +#define PB1_MASK (0x00000002u) +#define PB1_BIT (1) +#define PB1_BITS (1) +/* PB0 field */ +#define PB0 (0x00000001u) +#define PB0_MASK (0x00000001u) +#define PB0_BIT (0) +#define PB0_BITS (1) + +#define GPIO_PBSET *((volatile uint32_t *)0x4000B410u) +#define GPIO_PBSET_REG *((volatile uint32_t *)0x4000B410u) +#define GPIO_PBSET_ADDR (0x4000B410u) +#define GPIO_PBSET_RESET (0x00000000u) +/* GPIO_PXSETRSVD field */ +#define GPIO_PXSETRSVD (0x0000FF00u) +#define GPIO_PXSETRSVD_MASK (0x0000FF00u) +#define GPIO_PXSETRSVD_BIT (8) +#define GPIO_PXSETRSVD_BITS (8) +/* PB7 field */ +#define PB7 (0x00000080u) +#define PB7_MASK (0x00000080u) +#define PB7_BIT (7) +#define PB7_BITS (1) +/* PB6 field */ +#define PB6 (0x00000040u) +#define PB6_MASK (0x00000040u) +#define PB6_BIT (6) +#define PB6_BITS (1) +/* PB5 field */ +#define PB5 (0x00000020u) +#define PB5_MASK (0x00000020u) +#define PB5_BIT (5) +#define PB5_BITS (1) +/* PB4 field */ +#define PB4 (0x00000010u) +#define PB4_MASK (0x00000010u) +#define PB4_BIT (4) +#define PB4_BITS (1) +/* PB3 field */ +#define PB3 (0x00000008u) +#define PB3_MASK (0x00000008u) +#define PB3_BIT (3) +#define PB3_BITS (1) +/* PB2 field */ +#define PB2 (0x00000004u) +#define PB2_MASK (0x00000004u) +#define PB2_BIT (2) +#define PB2_BITS (1) +/* PB1 field */ +#define PB1 (0x00000002u) +#define PB1_MASK (0x00000002u) +#define PB1_BIT (1) +#define PB1_BITS (1) +/* PB0 field */ +#define PB0 (0x00000001u) +#define PB0_MASK (0x00000001u) +#define PB0_BIT (0) +#define PB0_BITS (1) + +#define GPIO_PBCLR *((volatile uint32_t *)0x4000B414u) +#define GPIO_PBCLR_REG *((volatile uint32_t *)0x4000B414u) +#define GPIO_PBCLR_ADDR (0x4000B414u) +#define GPIO_PBCLR_RESET (0x00000000u) +/* PB7 field */ +#define PB7 (0x00000080u) +#define PB7_MASK (0x00000080u) +#define PB7_BIT (7) +#define PB7_BITS (1) +/* PB6 field */ +#define PB6 (0x00000040u) +#define PB6_MASK (0x00000040u) +#define PB6_BIT (6) +#define PB6_BITS (1) +/* PB5 field */ +#define PB5 (0x00000020u) +#define PB5_MASK (0x00000020u) +#define PB5_BIT (5) +#define PB5_BITS (1) +/* PB4 field */ +#define PB4 (0x00000010u) +#define PB4_MASK (0x00000010u) +#define PB4_BIT (4) +#define PB4_BITS (1) +/* PB3 field */ +#define PB3 (0x00000008u) +#define PB3_MASK (0x00000008u) +#define PB3_BIT (3) +#define PB3_BITS (1) +/* PB2 field */ +#define PB2 (0x00000004u) +#define PB2_MASK (0x00000004u) +#define PB2_BIT (2) +#define PB2_BITS (1) +/* PB1 field */ +#define PB1 (0x00000002u) +#define PB1_MASK (0x00000002u) +#define PB1_BIT (1) +#define PB1_BITS (1) +/* PB0 field */ +#define PB0 (0x00000001u) +#define PB0_MASK (0x00000001u) +#define PB0_BIT (0) +#define PB0_BITS (1) + +#define GPIO_PCCFGL *((volatile uint32_t *)0x4000B800u) +#define GPIO_PCCFGL_REG *((volatile uint32_t *)0x4000B800u) +#define GPIO_PCCFGL_ADDR (0x4000B800u) +#define GPIO_PCCFGL_RESET (0x00004444u) +/* PC3_CFG field */ +#define PC3_CFG (0x0000F000u) +#define PC3_CFG_MASK (0x0000F000u) +#define PC3_CFG_BIT (12) +#define PC3_CFG_BITS (4) +/* PC2_CFG field */ +#define PC2_CFG (0x00000F00u) +#define PC2_CFG_MASK (0x00000F00u) +#define PC2_CFG_BIT (8) +#define PC2_CFG_BITS (4) +/* PC1_CFG field */ +#define PC1_CFG (0x000000F0u) +#define PC1_CFG_MASK (0x000000F0u) +#define PC1_CFG_BIT (4) +#define PC1_CFG_BITS (4) +/* PC0_CFG field */ +#define PC0_CFG (0x0000000Fu) +#define PC0_CFG_MASK (0x0000000Fu) +#define PC0_CFG_BIT (0) +#define PC0_CFG_BITS (4) + +#define GPIO_PCCFGH *((volatile uint32_t *)0x4000B804u) +#define GPIO_PCCFGH_REG *((volatile uint32_t *)0x4000B804u) +#define GPIO_PCCFGH_ADDR (0x4000B804u) +#define GPIO_PCCFGH_RESET (0x00004444u) +/* PC7_CFG field */ +#define PC7_CFG (0x0000F000u) +#define PC7_CFG_MASK (0x0000F000u) +#define PC7_CFG_BIT (12) +#define PC7_CFG_BITS (4) +/* PC6_CFG field */ +#define PC6_CFG (0x00000F00u) +#define PC6_CFG_MASK (0x00000F00u) +#define PC6_CFG_BIT (8) +#define PC6_CFG_BITS (4) +/* PC5_CFG field */ +#define PC5_CFG (0x000000F0u) +#define PC5_CFG_MASK (0x000000F0u) +#define PC5_CFG_BIT (4) +#define PC5_CFG_BITS (4) +/* PC4_CFG field */ +#define PC4_CFG (0x0000000Fu) +#define PC4_CFG_MASK (0x0000000Fu) +#define PC4_CFG_BIT (0) +#define PC4_CFG_BITS (4) + +#define GPIO_PCIN *((volatile uint32_t *)0x4000B808u) +#define GPIO_PCIN_REG *((volatile uint32_t *)0x4000B808u) +#define GPIO_PCIN_ADDR (0x4000B808u) +#define GPIO_PCIN_RESET (0x00000000u) +/* PC7 field */ +#define PC7 (0x00000080u) +#define PC7_MASK (0x00000080u) +#define PC7_BIT (7) +#define PC7_BITS (1) +/* PC6 field */ +#define PC6 (0x00000040u) +#define PC6_MASK (0x00000040u) +#define PC6_BIT (6) +#define PC6_BITS (1) +/* PC5 field */ +#define PC5 (0x00000020u) +#define PC5_MASK (0x00000020u) +#define PC5_BIT (5) +#define PC5_BITS (1) +/* PC4 field */ +#define PC4 (0x00000010u) +#define PC4_MASK (0x00000010u) +#define PC4_BIT (4) +#define PC4_BITS (1) +/* PC3 field */ +#define PC3 (0x00000008u) +#define PC3_MASK (0x00000008u) +#define PC3_BIT (3) +#define PC3_BITS (1) +/* PC2 field */ +#define PC2 (0x00000004u) +#define PC2_MASK (0x00000004u) +#define PC2_BIT (2) +#define PC2_BITS (1) +/* PC1 field */ +#define PC1 (0x00000002u) +#define PC1_MASK (0x00000002u) +#define PC1_BIT (1) +#define PC1_BITS (1) +/* PC0 field */ +#define PC0 (0x00000001u) +#define PC0_MASK (0x00000001u) +#define PC0_BIT (0) +#define PC0_BITS (1) + +#define GPIO_PCOUT *((volatile uint32_t *)0x4000B80Cu) +#define GPIO_PCOUT_REG *((volatile uint32_t *)0x4000B80Cu) +#define GPIO_PCOUT_ADDR (0x4000B80Cu) +#define GPIO_PCOUT_RESET (0x00000000u) +/* PC7 field */ +#define PC7 (0x00000080u) +#define PC7_MASK (0x00000080u) +#define PC7_BIT (7) +#define PC7_BITS (1) +/* PC6 field */ +#define PC6 (0x00000040u) +#define PC6_MASK (0x00000040u) +#define PC6_BIT (6) +#define PC6_BITS (1) +/* PC5 field */ +#define PC5 (0x00000020u) +#define PC5_MASK (0x00000020u) +#define PC5_BIT (5) +#define PC5_BITS (1) +/* PC4 field */ +#define PC4 (0x00000010u) +#define PC4_MASK (0x00000010u) +#define PC4_BIT (4) +#define PC4_BITS (1) +/* PC3 field */ +#define PC3 (0x00000008u) +#define PC3_MASK (0x00000008u) +#define PC3_BIT (3) +#define PC3_BITS (1) +/* PC2 field */ +#define PC2 (0x00000004u) +#define PC2_MASK (0x00000004u) +#define PC2_BIT (2) +#define PC2_BITS (1) +/* PC1 field */ +#define PC1 (0x00000002u) +#define PC1_MASK (0x00000002u) +#define PC1_BIT (1) +#define PC1_BITS (1) +/* PC0 field */ +#define PC0 (0x00000001u) +#define PC0_MASK (0x00000001u) +#define PC0_BIT (0) +#define PC0_BITS (1) + +#define GPIO_PCSET *((volatile uint32_t *)0x4000B810u) +#define GPIO_PCSET_REG *((volatile uint32_t *)0x4000B810u) +#define GPIO_PCSET_ADDR (0x4000B810u) +#define GPIO_PCSET_RESET (0x00000000u) +/* GPIO_PXSETRSVD field */ +#define GPIO_PXSETRSVD (0x0000FF00u) +#define GPIO_PXSETRSVD_MASK (0x0000FF00u) +#define GPIO_PXSETRSVD_BIT (8) +#define GPIO_PXSETRSVD_BITS (8) +/* PC7 field */ +#define PC7 (0x00000080u) +#define PC7_MASK (0x00000080u) +#define PC7_BIT (7) +#define PC7_BITS (1) +/* PC6 field */ +#define PC6 (0x00000040u) +#define PC6_MASK (0x00000040u) +#define PC6_BIT (6) +#define PC6_BITS (1) +/* PC5 field */ +#define PC5 (0x00000020u) +#define PC5_MASK (0x00000020u) +#define PC5_BIT (5) +#define PC5_BITS (1) +/* PC4 field */ +#define PC4 (0x00000010u) +#define PC4_MASK (0x00000010u) +#define PC4_BIT (4) +#define PC4_BITS (1) +/* PC3 field */ +#define PC3 (0x00000008u) +#define PC3_MASK (0x00000008u) +#define PC3_BIT (3) +#define PC3_BITS (1) +/* PC2 field */ +#define PC2 (0x00000004u) +#define PC2_MASK (0x00000004u) +#define PC2_BIT (2) +#define PC2_BITS (1) +/* PC1 field */ +#define PC1 (0x00000002u) +#define PC1_MASK (0x00000002u) +#define PC1_BIT (1) +#define PC1_BITS (1) +/* PC0 field */ +#define PC0 (0x00000001u) +#define PC0_MASK (0x00000001u) +#define PC0_BIT (0) +#define PC0_BITS (1) + +#define GPIO_PCCLR *((volatile uint32_t *)0x4000B814u) +#define GPIO_PCCLR_REG *((volatile uint32_t *)0x4000B814u) +#define GPIO_PCCLR_ADDR (0x4000B814u) +#define GPIO_PCCLR_RESET (0x00000000u) +/* PC7 field */ +#define PC7 (0x00000080u) +#define PC7_MASK (0x00000080u) +#define PC7_BIT (7) +#define PC7_BITS (1) +/* PC6 field */ +#define PC6 (0x00000040u) +#define PC6_MASK (0x00000040u) +#define PC6_BIT (6) +#define PC6_BITS (1) +/* PC5 field */ +#define PC5 (0x00000020u) +#define PC5_MASK (0x00000020u) +#define PC5_BIT (5) +#define PC5_BITS (1) +/* PC4 field */ +#define PC4 (0x00000010u) +#define PC4_MASK (0x00000010u) +#define PC4_BIT (4) +#define PC4_BITS (1) +/* PC3 field */ +#define PC3 (0x00000008u) +#define PC3_MASK (0x00000008u) +#define PC3_BIT (3) +#define PC3_BITS (1) +/* PC2 field */ +#define PC2 (0x00000004u) +#define PC2_MASK (0x00000004u) +#define PC2_BIT (2) +#define PC2_BITS (1) +/* PC1 field */ +#define PC1 (0x00000002u) +#define PC1_MASK (0x00000002u) +#define PC1_BIT (1) +#define PC1_BITS (1) +/* PC0 field */ +#define PC0 (0x00000001u) +#define PC0_MASK (0x00000001u) +#define PC0_BIT (0) +#define PC0_BITS (1) + +#define GPIO_DBGCFG *((volatile uint32_t *)0x4000BC00u) +#define GPIO_DBGCFG_REG *((volatile uint32_t *)0x4000BC00u) +#define GPIO_DBGCFG_ADDR (0x4000BC00u) +#define GPIO_DBGCFG_RESET (0x00000010u) +/* GPIO_DEBUGDIS field */ +#define GPIO_DEBUGDIS (0x00000020u) +#define GPIO_DEBUGDIS_MASK (0x00000020u) +#define GPIO_DEBUGDIS_BIT (5) +#define GPIO_DEBUGDIS_BITS (1) +/* GPIO_EXTREGEN field */ +#define GPIO_EXTREGEN (0x00000010u) +#define GPIO_EXTREGEN_MASK (0x00000010u) +#define GPIO_EXTREGEN_BIT (4) +#define GPIO_EXTREGEN_BITS (1) +/* GPIO_DBGCFGRSVD field */ +#define GPIO_DBGCFGRSVD (0x00000008u) +#define GPIO_DBGCFGRSVD_MASK (0x00000008u) +#define GPIO_DBGCFGRSVD_BIT (3) +#define GPIO_DBGCFGRSVD_BITS (1) + +#define GPIO_DBGSTAT *((volatile uint32_t *)0x4000BC04u) +#define GPIO_DBGSTAT_REG *((volatile uint32_t *)0x4000BC04u) +#define GPIO_DBGSTAT_ADDR (0x4000BC04u) +#define GPIO_DBGSTAT_RESET (0x00000000u) +/* GPIO_BOOTMODE field */ +#define GPIO_BOOTMODE (0x00000008u) +#define GPIO_BOOTMODE_MASK (0x00000008u) +#define GPIO_BOOTMODE_BIT (3) +#define GPIO_BOOTMODE_BITS (1) +/* GPIO_FORCEDBG field */ +#define GPIO_FORCEDBG (0x00000002u) +#define GPIO_FORCEDBG_MASK (0x00000002u) +#define GPIO_FORCEDBG_BIT (1) +#define GPIO_FORCEDBG_BITS (1) +/* GPIO_SWEN field */ +#define GPIO_SWEN (0x00000001u) +#define GPIO_SWEN_MASK (0x00000001u) +#define GPIO_SWEN_BIT (0) +#define GPIO_SWEN_BITS (1) + +#define GPIO_PAWAKE *((volatile uint32_t *)0x4000BC08u) +#define GPIO_PAWAKE_REG *((volatile uint32_t *)0x4000BC08u) +#define GPIO_PAWAKE_ADDR (0x4000BC08u) +#define GPIO_PAWAKE_RESET (0x00000000u) +/* PA7 field */ +#define PA7 (0x00000080u) +#define PA7_MASK (0x00000080u) +#define PA7_BIT (7) +#define PA7_BITS (1) +/* PA6 field */ +#define PA6 (0x00000040u) +#define PA6_MASK (0x00000040u) +#define PA6_BIT (6) +#define PA6_BITS (1) +/* PA5 field */ +#define PA5 (0x00000020u) +#define PA5_MASK (0x00000020u) +#define PA5_BIT (5) +#define PA5_BITS (1) +/* PA4 field */ +#define PA4 (0x00000010u) +#define PA4_MASK (0x00000010u) +#define PA4_BIT (4) +#define PA4_BITS (1) +/* PA3 field */ +#define PA3 (0x00000008u) +#define PA3_MASK (0x00000008u) +#define PA3_BIT (3) +#define PA3_BITS (1) +/* PA2 field */ +#define PA2 (0x00000004u) +#define PA2_MASK (0x00000004u) +#define PA2_BIT (2) +#define PA2_BITS (1) +/* PA1 field */ +#define PA1 (0x00000002u) +#define PA1_MASK (0x00000002u) +#define PA1_BIT (1) +#define PA1_BITS (1) +/* PA0 field */ +#define PA0 (0x00000001u) +#define PA0_MASK (0x00000001u) +#define PA0_BIT (0) +#define PA0_BITS (1) + +#define GPIO_PBWAKE *((volatile uint32_t *)0x4000BC0Cu) +#define GPIO_PBWAKE_REG *((volatile uint32_t *)0x4000BC0Cu) +#define GPIO_PBWAKE_ADDR (0x4000BC0Cu) +#define GPIO_PBWAKE_RESET (0x00000000u) +/* PB7 field */ +#define PB7 (0x00000080u) +#define PB7_MASK (0x00000080u) +#define PB7_BIT (7) +#define PB7_BITS (1) +/* PB6 field */ +#define PB6 (0x00000040u) +#define PB6_MASK (0x00000040u) +#define PB6_BIT (6) +#define PB6_BITS (1) +/* PB5 field */ +#define PB5 (0x00000020u) +#define PB5_MASK (0x00000020u) +#define PB5_BIT (5) +#define PB5_BITS (1) +/* PB4 field */ +#define PB4 (0x00000010u) +#define PB4_MASK (0x00000010u) +#define PB4_BIT (4) +#define PB4_BITS (1) +/* PB3 field */ +#define PB3 (0x00000008u) +#define PB3_MASK (0x00000008u) +#define PB3_BIT (3) +#define PB3_BITS (1) +/* PB2 field */ +#define PB2 (0x00000004u) +#define PB2_MASK (0x00000004u) +#define PB2_BIT (2) +#define PB2_BITS (1) +/* PB1 field */ +#define PB1 (0x00000002u) +#define PB1_MASK (0x00000002u) +#define PB1_BIT (1) +#define PB1_BITS (1) +/* PB0 field */ +#define PB0 (0x00000001u) +#define PB0_MASK (0x00000001u) +#define PB0_BIT (0) +#define PB0_BITS (1) + +#define GPIO_PCWAKE *((volatile uint32_t *)0x4000BC10u) +#define GPIO_PCWAKE_REG *((volatile uint32_t *)0x4000BC10u) +#define GPIO_PCWAKE_ADDR (0x4000BC10u) +#define GPIO_PCWAKE_RESET (0x00000000u) +/* PC7 field */ +#define PC7 (0x00000080u) +#define PC7_MASK (0x00000080u) +#define PC7_BIT (7) +#define PC7_BITS (1) +/* PC6 field */ +#define PC6 (0x00000040u) +#define PC6_MASK (0x00000040u) +#define PC6_BIT (6) +#define PC6_BITS (1) +/* PC5 field */ +#define PC5 (0x00000020u) +#define PC5_MASK (0x00000020u) +#define PC5_BIT (5) +#define PC5_BITS (1) +/* PC4 field */ +#define PC4 (0x00000010u) +#define PC4_MASK (0x00000010u) +#define PC4_BIT (4) +#define PC4_BITS (1) +/* PC3 field */ +#define PC3 (0x00000008u) +#define PC3_MASK (0x00000008u) +#define PC3_BIT (3) +#define PC3_BITS (1) +/* PC2 field */ +#define PC2 (0x00000004u) +#define PC2_MASK (0x00000004u) +#define PC2_BIT (2) +#define PC2_BITS (1) +/* PC1 field */ +#define PC1 (0x00000002u) +#define PC1_MASK (0x00000002u) +#define PC1_BIT (1) +#define PC1_BITS (1) +/* PC0 field */ +#define PC0 (0x00000001u) +#define PC0_MASK (0x00000001u) +#define PC0_BIT (0) +#define PC0_BITS (1) + +#define GPIO_IRQCSEL *((volatile uint32_t *)0x4000BC14u) +#define GPIO_IRQCSEL_REG *((volatile uint32_t *)0x4000BC14u) +#define GPIO_IRQCSEL_ADDR (0x4000BC14u) +#define GPIO_IRQCSEL_RESET (0x0000000Fu) +/* SEL_GPIO field */ +#define SEL_GPIO (0x0000001Fu) +#define SEL_GPIO_MASK (0x0000001Fu) +#define SEL_GPIO_BIT (0) +#define SEL_GPIO_BITS (5) + +#define GPIO_IRQDSEL *((volatile uint32_t *)0x4000BC18u) +#define GPIO_IRQDSEL_REG *((volatile uint32_t *)0x4000BC18u) +#define GPIO_IRQDSEL_ADDR (0x4000BC18u) +#define GPIO_IRQDSEL_RESET (0x00000010u) +/* SEL_GPIO field */ +#define SEL_GPIO (0x0000001Fu) +#define SEL_GPIO_MASK (0x0000001Fu) +#define SEL_GPIO_BIT (0) +#define SEL_GPIO_BITS (5) + +#define GPIO_WAKEFILT *((volatile uint32_t *)0x4000BC1Cu) +#define GPIO_WAKEFILT_REG *((volatile uint32_t *)0x4000BC1Cu) +#define GPIO_WAKEFILT_ADDR (0x4000BC1Cu) +#define GPIO_WAKEFILT_RESET (0x00000000u) +/* IRQD_WAKE_FILTER field */ +#define IRQD_WAKE_FILTER (0x00000008u) +#define IRQD_WAKE_FILTER_MASK (0x00000008u) +#define IRQD_WAKE_FILTER_BIT (3) +#define IRQD_WAKE_FILTER_BITS (1) +/* SC2_WAKE_FILTER field */ +#define SC2_WAKE_FILTER (0x00000004u) +#define SC2_WAKE_FILTER_MASK (0x00000004u) +#define SC2_WAKE_FILTER_BIT (2) +#define SC2_WAKE_FILTER_BITS (1) +/* SC1_WAKE_FILTER field */ +#define SC1_WAKE_FILTER (0x00000002u) +#define SC1_WAKE_FILTER_MASK (0x00000002u) +#define SC1_WAKE_FILTER_BIT (1) +#define SC1_WAKE_FILTER_BITS (1) +/* GPIO_WAKE_FILTER field */ +#define GPIO_WAKE_FILTER (0x00000001u) +#define GPIO_WAKE_FILTER_MASK (0x00000001u) +#define GPIO_WAKE_FILTER_BIT (0) +#define GPIO_WAKE_FILTER_BITS (1) + +/* SERIAL block */ +#define BLOCK_SERIAL_BASE (0x4000C000u) +#define BLOCK_SERIAL_END (0x4000C870u) +#define BLOCK_SERIAL_SIZE (BLOCK_SERIAL_END - BLOCK_SERIAL_BASE + 1) + +#define SC2_RXBEGA *((volatile uint32_t *)0x4000C000u) +#define SC2_RXBEGA_REG *((volatile uint32_t *)0x4000C000u) +#define SC2_RXBEGA_ADDR (0x4000C000u) +#define SC2_RXBEGA_RESET (0x20000000u) +/* FIXED field */ +#define SC2_RXBEGA_FIXED (0xFFFFE000u) +#define SC2_RXBEGA_FIXED_MASK (0xFFFFE000u) +#define SC2_RXBEGA_FIXED_BIT (13) +#define SC2_RXBEGA_FIXED_BITS (19) +/* SC_RXBEGA field */ +#define SC_RXBEGA (0x00001FFFu) +#define SC_RXBEGA_MASK (0x00001FFFu) +#define SC_RXBEGA_BIT (0) +#define SC_RXBEGA_BITS (13) + +#define SC2_RXENDA *((volatile uint32_t *)0x4000C004u) +#define SC2_RXENDA_REG *((volatile uint32_t *)0x4000C004u) +#define SC2_RXENDA_ADDR (0x4000C004u) +#define SC2_RXENDA_RESET (0x20000000u) +/* FIXED field */ +#define SC2_RXENDA_FIXED (0xFFFFE000u) +#define SC2_RXENDA_FIXED_MASK (0xFFFFE000u) +#define SC2_RXENDA_FIXED_BIT (13) +#define SC2_RXENDA_FIXED_BITS (19) +/* SC_RXENDA field */ +#define SC_RXENDA (0x00001FFFu) +#define SC_RXENDA_MASK (0x00001FFFu) +#define SC_RXENDA_BIT (0) +#define SC_RXENDA_BITS (13) + +#define SC2_RXBEGB *((volatile uint32_t *)0x4000C008u) +#define SC2_RXBEGB_REG *((volatile uint32_t *)0x4000C008u) +#define SC2_RXBEGB_ADDR (0x4000C008u) +#define SC2_RXBEGB_RESET (0x20000000u) +/* FIXED field */ +#define SC2_RXBEGB_FIXED (0xFFFFE000u) +#define SC2_RXBEGB_FIXED_MASK (0xFFFFE000u) +#define SC2_RXBEGB_FIXED_BIT (13) +#define SC2_RXBEGB_FIXED_BITS (19) +/* SC_RXBEGB field */ +#define SC_RXBEGB (0x00001FFFu) +#define SC_RXBEGB_MASK (0x00001FFFu) +#define SC_RXBEGB_BIT (0) +#define SC_RXBEGB_BITS (13) + +#define SC2_RXENDB *((volatile uint32_t *)0x4000C00Cu) +#define SC2_RXENDB_REG *((volatile uint32_t *)0x4000C00Cu) +#define SC2_RXENDB_ADDR (0x4000C00Cu) +#define SC2_RXENDB_RESET (0x20000000u) +/* FIXED field */ +#define SC2_RXENDB_FIXED (0xFFFFE000u) +#define SC2_RXENDB_FIXED_MASK (0xFFFFE000u) +#define SC2_RXENDB_FIXED_BIT (13) +#define SC2_RXENDB_FIXED_BITS (19) +/* SC_RXENDB field */ +#define SC_RXENDB (0x00001FFFu) +#define SC_RXENDB_MASK (0x00001FFFu) +#define SC_RXENDB_BIT (0) +#define SC_RXENDB_BITS (13) + +#define SC2_TXBEGA *((volatile uint32_t *)0x4000C010u) +#define SC2_TXBEGA_REG *((volatile uint32_t *)0x4000C010u) +#define SC2_TXBEGA_ADDR (0x4000C010u) +#define SC2_TXBEGA_RESET (0x20000000u) +/* FIXED field */ +#define SC2_TXBEGA_FIXED (0xFFFFE000u) +#define SC2_TXBEGA_FIXED_MASK (0xFFFFE000u) +#define SC2_TXBEGA_FIXED_BIT (13) +#define SC2_TXBEGA_FIXED_BITS (19) +/* SC_TXBEGA field */ +#define SC_TXBEGA (0x00001FFFu) +#define SC_TXBEGA_MASK (0x00001FFFu) +#define SC_TXBEGA_BIT (0) +#define SC_TXBEGA_BITS (13) + +#define SC2_TXENDA *((volatile uint32_t *)0x4000C014u) +#define SC2_TXENDA_REG *((volatile uint32_t *)0x4000C014u) +#define SC2_TXENDA_ADDR (0x4000C014u) +#define SC2_TXENDA_RESET (0x20000000u) +/* FIXED field */ +#define SC2_TXENDA_FIXED (0xFFFFE000u) +#define SC2_TXENDA_FIXED_MASK (0xFFFFE000u) +#define SC2_TXENDA_FIXED_BIT (13) +#define SC2_TXENDA_FIXED_BITS (19) +/* SC_TXENDA field */ +#define SC_TXENDA (0x00001FFFu) +#define SC_TXENDA_MASK (0x00001FFFu) +#define SC_TXENDA_BIT (0) +#define SC_TXENDA_BITS (13) + +#define SC2_TXBEGB *((volatile uint32_t *)0x4000C018u) +#define SC2_TXBEGB_REG *((volatile uint32_t *)0x4000C018u) +#define SC2_TXBEGB_ADDR (0x4000C018u) +#define SC2_TXBEGB_RESET (0x20000000u) +/* FIXED field */ +#define SC2_TXBEGB_FIXED (0xFFFFE000u) +#define SC2_TXBEGB_FIXED_MASK (0xFFFFE000u) +#define SC2_TXBEGB_FIXED_BIT (13) +#define SC2_TXBEGB_FIXED_BITS (19) +/* SC_TXBEGB field */ +#define SC_TXBEGB (0x00001FFFu) +#define SC_TXBEGB_MASK (0x00001FFFu) +#define SC_TXBEGB_BIT (0) +#define SC_TXBEGB_BITS (13) + +#define SC2_TXENDB *((volatile uint32_t *)0x4000C01Cu) +#define SC2_TXENDB_REG *((volatile uint32_t *)0x4000C01Cu) +#define SC2_TXENDB_ADDR (0x4000C01Cu) +#define SC2_TXENDB_RESET (0x20000000u) +/* FIXED field */ +#define SC2_TXENDB_FIXED (0xFFFFE000u) +#define SC2_TXENDB_FIXED_MASK (0xFFFFE000u) +#define SC2_TXENDB_FIXED_BIT (13) +#define SC2_TXENDB_FIXED_BITS (19) +/* SC_TXENDB field */ +#define SC_TXENDB (0x00001FFFu) +#define SC_TXENDB_MASK (0x00001FFFu) +#define SC_TXENDB_BIT (0) +#define SC_TXENDB_BITS (13) + +#define SC2_RXCNTA *((volatile uint32_t *)0x4000C020u) +#define SC2_RXCNTA_REG *((volatile uint32_t *)0x4000C020u) +#define SC2_RXCNTA_ADDR (0x4000C020u) +#define SC2_RXCNTA_RESET (0x00000000u) +/* SC_RXCNTA field */ +#define SC_RXCNTA (0x00001FFFu) +#define SC_RXCNTA_MASK (0x00001FFFu) +#define SC_RXCNTA_BIT (0) +#define SC_RXCNTA_BITS (13) + +#define SC2_RXCNTB *((volatile uint32_t *)0x4000C024u) +#define SC2_RXCNTB_REG *((volatile uint32_t *)0x4000C024u) +#define SC2_RXCNTB_ADDR (0x4000C024u) +#define SC2_RXCNTB_RESET (0x00000000u) +/* SC_RXCNTB field */ +#define SC_RXCNTB (0x00001FFFu) +#define SC_RXCNTB_MASK (0x00001FFFu) +#define SC_RXCNTB_BIT (0) +#define SC_RXCNTB_BITS (13) + +#define SC2_TXCNT *((volatile uint32_t *)0x4000C028u) +#define SC2_TXCNT_REG *((volatile uint32_t *)0x4000C028u) +#define SC2_TXCNT_ADDR (0x4000C028u) +#define SC2_TXCNT_RESET (0x00000000u) +/* SC_TXCNT field */ +#define SC_TXCNT (0x00001FFFu) +#define SC_TXCNT_MASK (0x00001FFFu) +#define SC_TXCNT_BIT (0) +#define SC_TXCNT_BITS (13) + +#define SC2_DMASTAT *((volatile uint32_t *)0x4000C02Cu) +#define SC2_DMASTAT_REG *((volatile uint32_t *)0x4000C02Cu) +#define SC2_DMASTAT_ADDR (0x4000C02Cu) +#define SC2_DMASTAT_RESET (0x00000000u) +/* SC_RXSSEL field */ +#define SC_RXSSEL (0x00001C00u) +#define SC_RXSSEL_MASK (0x00001C00u) +#define SC_RXSSEL_BIT (10) +#define SC_RXSSEL_BITS (3) +/* SC_RXOVFB field */ +#define SC_RXOVFB (0x00000020u) +#define SC_RXOVFB_MASK (0x00000020u) +#define SC_RXOVFB_BIT (5) +#define SC_RXOVFB_BITS (1) +/* SC_RXOVFA field */ +#define SC_RXOVFA (0x00000010u) +#define SC_RXOVFA_MASK (0x00000010u) +#define SC_RXOVFA_BIT (4) +#define SC_RXOVFA_BITS (1) +/* SC_TXACTB field */ +#define SC_TXACTB (0x00000008u) +#define SC_TXACTB_MASK (0x00000008u) +#define SC_TXACTB_BIT (3) +#define SC_TXACTB_BITS (1) +/* SC_TXACTA field */ +#define SC_TXACTA (0x00000004u) +#define SC_TXACTA_MASK (0x00000004u) +#define SC_TXACTA_BIT (2) +#define SC_TXACTA_BITS (1) +/* SC_RXACTB field */ +#define SC_RXACTB (0x00000002u) +#define SC_RXACTB_MASK (0x00000002u) +#define SC_RXACTB_BIT (1) +#define SC_RXACTB_BITS (1) +/* SC_RXACTA field */ +#define SC_RXACTA (0x00000001u) +#define SC_RXACTA_MASK (0x00000001u) +#define SC_RXACTA_BIT (0) +#define SC_RXACTA_BITS (1) + +#define SC2_DMACTRL *((volatile uint32_t *)0x4000C030u) +#define SC2_DMACTRL_REG *((volatile uint32_t *)0x4000C030u) +#define SC2_DMACTRL_ADDR (0x4000C030u) +#define SC2_DMACTRL_RESET (0x00000000u) +/* SC_TXDMARST field */ +#define SC_TXDMARST (0x00000020u) +#define SC_TXDMARST_MASK (0x00000020u) +#define SC_TXDMARST_BIT (5) +#define SC_TXDMARST_BITS (1) +/* SC_RXDMARST field */ +#define SC_RXDMARST (0x00000010u) +#define SC_RXDMARST_MASK (0x00000010u) +#define SC_RXDMARST_BIT (4) +#define SC_RXDMARST_BITS (1) +/* SC_TXLODB field */ +#define SC_TXLODB (0x00000008u) +#define SC_TXLODB_MASK (0x00000008u) +#define SC_TXLODB_BIT (3) +#define SC_TXLODB_BITS (1) +/* SC_TXLODA field */ +#define SC_TXLODA (0x00000004u) +#define SC_TXLODA_MASK (0x00000004u) +#define SC_TXLODA_BIT (2) +#define SC_TXLODA_BITS (1) +/* SC_RXLODB field */ +#define SC_RXLODB (0x00000002u) +#define SC_RXLODB_MASK (0x00000002u) +#define SC_RXLODB_BIT (1) +#define SC_RXLODB_BITS (1) +/* SC_RXLODA field */ +#define SC_RXLODA (0x00000001u) +#define SC_RXLODA_MASK (0x00000001u) +#define SC_RXLODA_BIT (0) +#define SC_RXLODA_BITS (1) + +#define SC2_RXERRA *((volatile uint32_t *)0x4000C034u) +#define SC2_RXERRA_REG *((volatile uint32_t *)0x4000C034u) +#define SC2_RXERRA_ADDR (0x4000C034u) +#define SC2_RXERRA_RESET (0x00000000u) +/* SC_RXERRA field */ +#define SC_RXERRA (0x00001FFFu) +#define SC_RXERRA_MASK (0x00001FFFu) +#define SC_RXERRA_BIT (0) +#define SC_RXERRA_BITS (13) + +#define SC2_RXERRB *((volatile uint32_t *)0x4000C038u) +#define SC2_RXERRB_REG *((volatile uint32_t *)0x4000C038u) +#define SC2_RXERRB_ADDR (0x4000C038u) +#define SC2_RXERRB_RESET (0x00000000u) +/* SC_RXERRB field */ +#define SC_RXERRB (0x00001FFFu) +#define SC_RXERRB_MASK (0x00001FFFu) +#define SC_RXERRB_BIT (0) +#define SC_RXERRB_BITS (13) + +#define SC2_DATA *((volatile uint32_t *)0x4000C03Cu) +#define SC2_DATA_REG *((volatile uint32_t *)0x4000C03Cu) +#define SC2_DATA_ADDR (0x4000C03Cu) +#define SC2_DATA_RESET (0x00000000u) +/* SC_DATA field */ +#define SC_DATA (0x000000FFu) +#define SC_DATA_MASK (0x000000FFu) +#define SC_DATA_BIT (0) +#define SC_DATA_BITS (8) + +#define SC2_SPISTAT *((volatile uint32_t *)0x4000C040u) +#define SC2_SPISTAT_REG *((volatile uint32_t *)0x4000C040u) +#define SC2_SPISTAT_ADDR (0x4000C040u) +#define SC2_SPISTAT_RESET (0x00000000u) +/* SC_SPITXIDLE field */ +#define SC_SPITXIDLE (0x00000008u) +#define SC_SPITXIDLE_MASK (0x00000008u) +#define SC_SPITXIDLE_BIT (3) +#define SC_SPITXIDLE_BITS (1) +/* SC_SPITXFREE field */ +#define SC_SPITXFREE (0x00000004u) +#define SC_SPITXFREE_MASK (0x00000004u) +#define SC_SPITXFREE_BIT (2) +#define SC_SPITXFREE_BITS (1) +/* SC_SPIRXVAL field */ +#define SC_SPIRXVAL (0x00000002u) +#define SC_SPIRXVAL_MASK (0x00000002u) +#define SC_SPIRXVAL_BIT (1) +#define SC_SPIRXVAL_BITS (1) +/* SC_SPIRXOVF field */ +#define SC_SPIRXOVF (0x00000001u) +#define SC_SPIRXOVF_MASK (0x00000001u) +#define SC_SPIRXOVF_BIT (0) +#define SC_SPIRXOVF_BITS (1) + +#define SC2_TWISTAT *((volatile uint32_t *)0x4000C044u) +#define SC2_TWISTAT_REG *((volatile uint32_t *)0x4000C044u) +#define SC2_TWISTAT_ADDR (0x4000C044u) +#define SC2_TWISTAT_RESET (0x00000000u) +/* SC_TWICMDFIN field */ +#define SC_TWICMDFIN (0x00000008u) +#define SC_TWICMDFIN_MASK (0x00000008u) +#define SC_TWICMDFIN_BIT (3) +#define SC_TWICMDFIN_BITS (1) +/* SC_TWIRXFIN field */ +#define SC_TWIRXFIN (0x00000004u) +#define SC_TWIRXFIN_MASK (0x00000004u) +#define SC_TWIRXFIN_BIT (2) +#define SC_TWIRXFIN_BITS (1) +/* SC_TWITXFIN field */ +#define SC_TWITXFIN (0x00000002u) +#define SC_TWITXFIN_MASK (0x00000002u) +#define SC_TWITXFIN_BIT (1) +#define SC_TWITXFIN_BITS (1) +/* SC_TWIRXNAK field */ +#define SC_TWIRXNAK (0x00000001u) +#define SC_TWIRXNAK_MASK (0x00000001u) +#define SC_TWIRXNAK_BIT (0) +#define SC_TWIRXNAK_BITS (1) + +#define SC2_TWICTRL1 *((volatile uint32_t *)0x4000C04Cu) +#define SC2_TWICTRL1_REG *((volatile uint32_t *)0x4000C04Cu) +#define SC2_TWICTRL1_ADDR (0x4000C04Cu) +#define SC2_TWICTRL1_RESET (0x00000000u) +/* SC_TWISTOP field */ +#define SC_TWISTOP (0x00000008u) +#define SC_TWISTOP_MASK (0x00000008u) +#define SC_TWISTOP_BIT (3) +#define SC_TWISTOP_BITS (1) +/* SC_TWISTART field */ +#define SC_TWISTART (0x00000004u) +#define SC_TWISTART_MASK (0x00000004u) +#define SC_TWISTART_BIT (2) +#define SC_TWISTART_BITS (1) +/* SC_TWISEND field */ +#define SC_TWISEND (0x00000002u) +#define SC_TWISEND_MASK (0x00000002u) +#define SC_TWISEND_BIT (1) +#define SC_TWISEND_BITS (1) +/* SC_TWIRECV field */ +#define SC_TWIRECV (0x00000001u) +#define SC_TWIRECV_MASK (0x00000001u) +#define SC_TWIRECV_BIT (0) +#define SC_TWIRECV_BITS (1) + +#define SC2_TWICTRL2 *((volatile uint32_t *)0x4000C050u) +#define SC2_TWICTRL2_REG *((volatile uint32_t *)0x4000C050u) +#define SC2_TWICTRL2_ADDR (0x4000C050u) +#define SC2_TWICTRL2_RESET (0x00000000u) +/* SC_TWIACK field */ +#define SC_TWIACK (0x00000001u) +#define SC_TWIACK_MASK (0x00000001u) +#define SC_TWIACK_BIT (0) +#define SC_TWIACK_BITS (1) + +#define SC2_MODE *((volatile uint32_t *)0x4000C054u) +#define SC2_MODE_REG *((volatile uint32_t *)0x4000C054u) +#define SC2_MODE_ADDR (0x4000C054u) +#define SC2_MODE_RESET (0x00000000u) +/* SC_MODE field */ +#define SC_MODE (0x00000003u) +#define SC_MODE_MASK (0x00000003u) +#define SC_MODE_BIT (0) +#define SC_MODE_BITS (2) +/* SC_MODE Bit Field Values */ +#define SC2_MODE_DISABLED (0) +#define SC2_MODE_SPI (2) +#define SC2_MODE_I2C (3) + +#define SC2_SPICFG *((volatile uint32_t *)0x4000C058u) +#define SC2_SPICFG_REG *((volatile uint32_t *)0x4000C058u) +#define SC2_SPICFG_ADDR (0x4000C058u) +#define SC2_SPICFG_RESET (0x00000000u) +/* SC_SPIRXDRV field */ +#define SC_SPIRXDRV (0x00000020u) +#define SC_SPIRXDRV_MASK (0x00000020u) +#define SC_SPIRXDRV_BIT (5) +#define SC_SPIRXDRV_BITS (1) +/* SC_SPIMST field */ +#define SC_SPIMST (0x00000010u) +#define SC_SPIMST_MASK (0x00000010u) +#define SC_SPIMST_BIT (4) +#define SC_SPIMST_BITS (1) +/* SC_SPIRPT field */ +#define SC_SPIRPT (0x00000008u) +#define SC_SPIRPT_MASK (0x00000008u) +#define SC_SPIRPT_BIT (3) +#define SC_SPIRPT_BITS (1) +/* SC_SPIORD field */ +#define SC_SPIORD (0x00000004u) +#define SC_SPIORD_MASK (0x00000004u) +#define SC_SPIORD_BIT (2) +#define SC_SPIORD_BITS (1) +/* SC_SPIPHA field */ +#define SC_SPIPHA (0x00000002u) +#define SC_SPIPHA_MASK (0x00000002u) +#define SC_SPIPHA_BIT (1) +#define SC_SPIPHA_BITS (1) +/* SC_SPIPOL field */ +#define SC_SPIPOL (0x00000001u) +#define SC_SPIPOL_MASK (0x00000001u) +#define SC_SPIPOL_BIT (0) +#define SC_SPIPOL_BITS (1) + +#define SC2_RATELIN *((volatile uint32_t *)0x4000C060u) +#define SC2_RATELIN_REG *((volatile uint32_t *)0x4000C060u) +#define SC2_RATELIN_ADDR (0x4000C060u) +#define SC2_RATELIN_RESET (0x00000000u) +/* SC_RATELIN field */ +#define SC_RATELIN (0x0000000Fu) +#define SC_RATELIN_MASK (0x0000000Fu) +#define SC_RATELIN_BIT (0) +#define SC_RATELIN_BITS (4) + +#define SC2_RATEEXP *((volatile uint32_t *)0x4000C064u) +#define SC2_RATEEXP_REG *((volatile uint32_t *)0x4000C064u) +#define SC2_RATEEXP_ADDR (0x4000C064u) +#define SC2_RATEEXP_RESET (0x00000000u) +/* SC_RATEEXP field */ +#define SC_RATEEXP (0x0000000Fu) +#define SC_RATEEXP_MASK (0x0000000Fu) +#define SC_RATEEXP_BIT (0) +#define SC_RATEEXP_BITS (4) + +#define SC2_RXCNTSAVED *((volatile uint32_t *)0x4000C070u) +#define SC2_RXCNTSAVED_REG *((volatile uint32_t *)0x4000C070u) +#define SC2_RXCNTSAVED_ADDR (0x4000C070u) +#define SC2_RXCNTSAVED_RESET (0x00000000u) +/* SC_RXCNTSAVED field */ +#define SC_RXCNTSAVED (0x00001FFFu) +#define SC_RXCNTSAVED_MASK (0x00001FFFu) +#define SC_RXCNTSAVED_BIT (0) +#define SC_RXCNTSAVED_BITS (13) + +#define SC1_RXBEGA *((volatile uint32_t *)0x4000C800u) +#define SC1_RXBEGA_REG *((volatile uint32_t *)0x4000C800u) +#define SC1_RXBEGA_ADDR (0x4000C800u) +#define SC1_RXBEGA_RESET (0x20000000u) +/* FIXED field */ +#define SC1_RXBEGA_FIXED (0xFFFFE000u) +#define SC1_RXBEGA_FIXED_MASK (0xFFFFE000u) +#define SC1_RXBEGA_FIXED_BIT (13) +#define SC1_RXBEGA_FIXED_BITS (19) +/* SC_RXBEGA field */ +#define SC_RXBEGA (0x00001FFFu) +#define SC_RXBEGA_MASK (0x00001FFFu) +#define SC_RXBEGA_BIT (0) +#define SC_RXBEGA_BITS (13) + +#define SC1_RXENDA *((volatile uint32_t *)0x4000C804u) +#define SC1_RXENDA_REG *((volatile uint32_t *)0x4000C804u) +#define SC1_RXENDA_ADDR (0x4000C804u) +#define SC1_RXENDA_RESET (0x20000000u) +/* FIXED field */ +#define SC1_RXENDA_FIXED (0xFFFFE000u) +#define SC1_RXENDA_FIXED_MASK (0xFFFFE000u) +#define SC1_RXENDA_FIXED_BIT (13) +#define SC1_RXENDA_FIXED_BITS (19) +/* SC_RXENDA field */ +#define SC_RXENDA (0x00001FFFu) +#define SC_RXENDA_MASK (0x00001FFFu) +#define SC_RXENDA_BIT (0) +#define SC_RXENDA_BITS (13) + +#define SC1_RXBEGB *((volatile uint32_t *)0x4000C808u) +#define SC1_RXBEGB_REG *((volatile uint32_t *)0x4000C808u) +#define SC1_RXBEGB_ADDR (0x4000C808u) +#define SC1_RXBEGB_RESET (0x20000000u) +/* FIXED field */ +#define SC1_RXBEGB_FIXED (0xFFFFE000u) +#define SC1_RXBEGB_FIXED_MASK (0xFFFFE000u) +#define SC1_RXBEGB_FIXED_BIT (13) +#define SC1_RXBEGB_FIXED_BITS (19) +/* SC_RXBEGB field */ +#define SC_RXBEGB (0x00001FFFu) +#define SC_RXBEGB_MASK (0x00001FFFu) +#define SC_RXBEGB_BIT (0) +#define SC_RXBEGB_BITS (13) + +#define SC1_RXENDB *((volatile uint32_t *)0x4000C80Cu) +#define SC1_RXENDB_REG *((volatile uint32_t *)0x4000C80Cu) +#define SC1_RXENDB_ADDR (0x4000C80Cu) +#define SC1_RXENDB_RESET (0x20000000u) +/* FIXED field */ +#define SC1_RXENDB_FIXED (0xFFFFE000u) +#define SC1_RXENDB_FIXED_MASK (0xFFFFE000u) +#define SC1_RXENDB_FIXED_BIT (13) +#define SC1_RXENDB_FIXED_BITS (19) +/* SC_RXENDB field */ +#define SC_RXENDB (0x00001FFFu) +#define SC_RXENDB_MASK (0x00001FFFu) +#define SC_RXENDB_BIT (0) +#define SC_RXENDB_BITS (13) + +#define SC1_TXBEGA *((volatile uint32_t *)0x4000C810u) +#define SC1_TXBEGA_REG *((volatile uint32_t *)0x4000C810u) +#define SC1_TXBEGA_ADDR (0x4000C810u) +#define SC1_TXBEGA_RESET (0x20000000u) +/* FIXED field */ +#define SC1_TXBEGA_FIXED (0xFFFFE000u) +#define SC1_TXBEGA_FIXED_MASK (0xFFFFE000u) +#define SC1_TXBEGA_FIXED_BIT (13) +#define SC1_TXBEGA_FIXED_BITS (19) +/* SC_TXBEGA field */ +#define SC_TXBEGA (0x00001FFFu) +#define SC_TXBEGA_MASK (0x00001FFFu) +#define SC_TXBEGA_BIT (0) +#define SC_TXBEGA_BITS (13) + +#define SC1_TXENDA *((volatile uint32_t *)0x4000C814u) +#define SC1_TXENDA_REG *((volatile uint32_t *)0x4000C814u) +#define SC1_TXENDA_ADDR (0x4000C814u) +#define SC1_TXENDA_RESET (0x20000000u) +/* FIXED field */ +#define SC1_TXENDA_FIXED (0xFFFFE000u) +#define SC1_TXENDA_FIXED_MASK (0xFFFFE000u) +#define SC1_TXENDA_FIXED_BIT (13) +#define SC1_TXENDA_FIXED_BITS (19) +/* SC_TXENDA field */ +#define SC_TXENDA (0x00001FFFu) +#define SC_TXENDA_MASK (0x00001FFFu) +#define SC_TXENDA_BIT (0) +#define SC_TXENDA_BITS (13) + +#define SC1_TXBEGB *((volatile uint32_t *)0x4000C818u) +#define SC1_TXBEGB_REG *((volatile uint32_t *)0x4000C818u) +#define SC1_TXBEGB_ADDR (0x4000C818u) +#define SC1_TXBEGB_RESET (0x20000000u) +/* FIXED field */ +#define SC1_TXBEGB_FIXED (0xFFFFE000u) +#define SC1_TXBEGB_FIXED_MASK (0xFFFFE000u) +#define SC1_TXBEGB_FIXED_BIT (13) +#define SC1_TXBEGB_FIXED_BITS (19) +/* SC_TXBEGB field */ +#define SC_TXBEGB (0x00001FFFu) +#define SC_TXBEGB_MASK (0x00001FFFu) +#define SC_TXBEGB_BIT (0) +#define SC_TXBEGB_BITS (13) + +#define SC1_TXENDB *((volatile uint32_t *)0x4000C81Cu) +#define SC1_TXENDB_REG *((volatile uint32_t *)0x4000C81Cu) +#define SC1_TXENDB_ADDR (0x4000C81Cu) +#define SC1_TXENDB_RESET (0x20000000u) +/* FIXED field */ +#define SC1_TXENDB_FIXED (0xFFFFE000u) +#define SC1_TXENDB_FIXED_MASK (0xFFFFE000u) +#define SC1_TXENDB_FIXED_BIT (13) +#define SC1_TXENDB_FIXED_BITS (19) +/* SC_TXENDB field */ +#define SC_TXENDB (0x00001FFFu) +#define SC_TXENDB_MASK (0x00001FFFu) +#define SC_TXENDB_BIT (0) +#define SC_TXENDB_BITS (13) + +#define SC1_RXCNTA *((volatile uint32_t *)0x4000C820u) +#define SC1_RXCNTA_REG *((volatile uint32_t *)0x4000C820u) +#define SC1_RXCNTA_ADDR (0x4000C820u) +#define SC1_RXCNTA_RESET (0x00000000u) +/* SC_RXCNTA field */ +#define SC_RXCNTA (0x00001FFFu) +#define SC_RXCNTA_MASK (0x00001FFFu) +#define SC_RXCNTA_BIT (0) +#define SC_RXCNTA_BITS (13) + +#define SC1_RXCNTB *((volatile uint32_t *)0x4000C824u) +#define SC1_RXCNTB_REG *((volatile uint32_t *)0x4000C824u) +#define SC1_RXCNTB_ADDR (0x4000C824u) +#define SC1_RXCNTB_RESET (0x00000000u) +/* SC_RXCNTB field */ +#define SC_RXCNTB (0x00001FFFu) +#define SC_RXCNTB_MASK (0x00001FFFu) +#define SC_RXCNTB_BIT (0) +#define SC_RXCNTB_BITS (13) + +#define SC1_TXCNT *((volatile uint32_t *)0x4000C828u) +#define SC1_TXCNT_REG *((volatile uint32_t *)0x4000C828u) +#define SC1_TXCNT_ADDR (0x4000C828u) +#define SC1_TXCNT_RESET (0x00000000u) +/* SC_TXCNT field */ +#define SC_TXCNT (0x00001FFFu) +#define SC_TXCNT_MASK (0x00001FFFu) +#define SC_TXCNT_BIT (0) +#define SC_TXCNT_BITS (13) + +#define SC1_DMASTAT *((volatile uint32_t *)0x4000C82Cu) +#define SC1_DMASTAT_REG *((volatile uint32_t *)0x4000C82Cu) +#define SC1_DMASTAT_ADDR (0x4000C82Cu) +#define SC1_DMASTAT_RESET (0x00000000u) +/* SC_RXSSEL field */ +#define SC_RXSSEL (0x00001C00u) +#define SC_RXSSEL_MASK (0x00001C00u) +#define SC_RXSSEL_BIT (10) +#define SC_RXSSEL_BITS (3) +/* SC_RXFRMB field */ +#define SC_RXFRMB (0x00000200u) +#define SC_RXFRMB_MASK (0x00000200u) +#define SC_RXFRMB_BIT (9) +#define SC_RXFRMB_BITS (1) +/* SC_RXFRMA field */ +#define SC_RXFRMA (0x00000100u) +#define SC_RXFRMA_MASK (0x00000100u) +#define SC_RXFRMA_BIT (8) +#define SC_RXFRMA_BITS (1) +/* SC_RXPARB field */ +#define SC_RXPARB (0x00000080u) +#define SC_RXPARB_MASK (0x00000080u) +#define SC_RXPARB_BIT (7) +#define SC_RXPARB_BITS (1) +/* SC_RXPARA field */ +#define SC_RXPARA (0x00000040u) +#define SC_RXPARA_MASK (0x00000040u) +#define SC_RXPARA_BIT (6) +#define SC_RXPARA_BITS (1) +/* SC_RXOVFB field */ +#define SC_RXOVFB (0x00000020u) +#define SC_RXOVFB_MASK (0x00000020u) +#define SC_RXOVFB_BIT (5) +#define SC_RXOVFB_BITS (1) +/* SC_RXOVFA field */ +#define SC_RXOVFA (0x00000010u) +#define SC_RXOVFA_MASK (0x00000010u) +#define SC_RXOVFA_BIT (4) +#define SC_RXOVFA_BITS (1) +/* SC_TXACTB field */ +#define SC_TXACTB (0x00000008u) +#define SC_TXACTB_MASK (0x00000008u) +#define SC_TXACTB_BIT (3) +#define SC_TXACTB_BITS (1) +/* SC_TXACTA field */ +#define SC_TXACTA (0x00000004u) +#define SC_TXACTA_MASK (0x00000004u) +#define SC_TXACTA_BIT (2) +#define SC_TXACTA_BITS (1) +/* SC_RXACTB field */ +#define SC_RXACTB (0x00000002u) +#define SC_RXACTB_MASK (0x00000002u) +#define SC_RXACTB_BIT (1) +#define SC_RXACTB_BITS (1) +/* SC_RXACTA field */ +#define SC_RXACTA (0x00000001u) +#define SC_RXACTA_MASK (0x00000001u) +#define SC_RXACTA_BIT (0) +#define SC_RXACTA_BITS (1) + +#define SC1_DMACTRL *((volatile uint32_t *)0x4000C830u) +#define SC1_DMACTRL_REG *((volatile uint32_t *)0x4000C830u) +#define SC1_DMACTRL_ADDR (0x4000C830u) +#define SC1_DMACTRL_RESET (0x00000000u) +/* SC_TXDMARST field */ +#define SC_TXDMARST (0x00000020u) +#define SC_TXDMARST_MASK (0x00000020u) +#define SC_TXDMARST_BIT (5) +#define SC_TXDMARST_BITS (1) +/* SC_RXDMARST field */ +#define SC_RXDMARST (0x00000010u) +#define SC_RXDMARST_MASK (0x00000010u) +#define SC_RXDMARST_BIT (4) +#define SC_RXDMARST_BITS (1) +/* SC_TXLODB field */ +#define SC_TXLODB (0x00000008u) +#define SC_TXLODB_MASK (0x00000008u) +#define SC_TXLODB_BIT (3) +#define SC_TXLODB_BITS (1) +/* SC_TXLODA field */ +#define SC_TXLODA (0x00000004u) +#define SC_TXLODA_MASK (0x00000004u) +#define SC_TXLODA_BIT (2) +#define SC_TXLODA_BITS (1) +/* SC_RXLODB field */ +#define SC_RXLODB (0x00000002u) +#define SC_RXLODB_MASK (0x00000002u) +#define SC_RXLODB_BIT (1) +#define SC_RXLODB_BITS (1) +/* SC_RXLODA field */ +#define SC_RXLODA (0x00000001u) +#define SC_RXLODA_MASK (0x00000001u) +#define SC_RXLODA_BIT (0) +#define SC_RXLODA_BITS (1) + +#define SC1_RXERRA *((volatile uint32_t *)0x4000C834u) +#define SC1_RXERRA_REG *((volatile uint32_t *)0x4000C834u) +#define SC1_RXERRA_ADDR (0x4000C834u) +#define SC1_RXERRA_RESET (0x00000000u) +/* SC_RXERRA field */ +#define SC_RXERRA (0x00001FFFu) +#define SC_RXERRA_MASK (0x00001FFFu) +#define SC_RXERRA_BIT (0) +#define SC_RXERRA_BITS (13) + +#define SC1_RXERRB *((volatile uint32_t *)0x4000C838u) +#define SC1_RXERRB_REG *((volatile uint32_t *)0x4000C838u) +#define SC1_RXERRB_ADDR (0x4000C838u) +#define SC1_RXERRB_RESET (0x00000000u) +/* SC_RXERRB field */ +#define SC_RXERRB (0x00001FFFu) +#define SC_RXERRB_MASK (0x00001FFFu) +#define SC_RXERRB_BIT (0) +#define SC_RXERRB_BITS (13) + +#define SC1_DATA *((volatile uint32_t *)0x4000C83Cu) +#define SC1_DATA_REG *((volatile uint32_t *)0x4000C83Cu) +#define SC1_DATA_ADDR (0x4000C83Cu) +#define SC1_DATA_RESET (0x00000000u) +/* SC_DATA field */ +#define SC_DATA (0x000000FFu) +#define SC_DATA_MASK (0x000000FFu) +#define SC_DATA_BIT (0) +#define SC_DATA_BITS (8) + +#define SC1_SPISTAT *((volatile uint32_t *)0x4000C840u) +#define SC1_SPISTAT_REG *((volatile uint32_t *)0x4000C840u) +#define SC1_SPISTAT_ADDR (0x4000C840u) +#define SC1_SPISTAT_RESET (0x00000000u) +/* SC_SPITXIDLE field */ +#define SC_SPITXIDLE (0x00000008u) +#define SC_SPITXIDLE_MASK (0x00000008u) +#define SC_SPITXIDLE_BIT (3) +#define SC_SPITXIDLE_BITS (1) +/* SC_SPITXFREE field */ +#define SC_SPITXFREE (0x00000004u) +#define SC_SPITXFREE_MASK (0x00000004u) +#define SC_SPITXFREE_BIT (2) +#define SC_SPITXFREE_BITS (1) +/* SC_SPIRXVAL field */ +#define SC_SPIRXVAL (0x00000002u) +#define SC_SPIRXVAL_MASK (0x00000002u) +#define SC_SPIRXVAL_BIT (1) +#define SC_SPIRXVAL_BITS (1) +/* SC_SPIRXOVF field */ +#define SC_SPIRXOVF (0x00000001u) +#define SC_SPIRXOVF_MASK (0x00000001u) +#define SC_SPIRXOVF_BIT (0) +#define SC_SPIRXOVF_BITS (1) + +#define SC1_TWISTAT *((volatile uint32_t *)0x4000C844u) +#define SC1_TWISTAT_REG *((volatile uint32_t *)0x4000C844u) +#define SC1_TWISTAT_ADDR (0x4000C844u) +#define SC1_TWISTAT_RESET (0x00000000u) +/* SC_TWICMDFIN field */ +#define SC_TWICMDFIN (0x00000008u) +#define SC_TWICMDFIN_MASK (0x00000008u) +#define SC_TWICMDFIN_BIT (3) +#define SC_TWICMDFIN_BITS (1) +/* SC_TWIRXFIN field */ +#define SC_TWIRXFIN (0x00000004u) +#define SC_TWIRXFIN_MASK (0x00000004u) +#define SC_TWIRXFIN_BIT (2) +#define SC_TWIRXFIN_BITS (1) +/* SC_TWITXFIN field */ +#define SC_TWITXFIN (0x00000002u) +#define SC_TWITXFIN_MASK (0x00000002u) +#define SC_TWITXFIN_BIT (1) +#define SC_TWITXFIN_BITS (1) +/* SC_TWIRXNAK field */ +#define SC_TWIRXNAK (0x00000001u) +#define SC_TWIRXNAK_MASK (0x00000001u) +#define SC_TWIRXNAK_BIT (0) +#define SC_TWIRXNAK_BITS (1) + +#define SC1_UARTSTAT *((volatile uint32_t *)0x4000C848u) +#define SC1_UARTSTAT_REG *((volatile uint32_t *)0x4000C848u) +#define SC1_UARTSTAT_ADDR (0x4000C848u) +#define SC1_UARTSTAT_RESET (0x00000040u) +/* SC_UARTTXIDLE field */ +#define SC_UARTTXIDLE (0x00000040u) +#define SC_UARTTXIDLE_MASK (0x00000040u) +#define SC_UARTTXIDLE_BIT (6) +#define SC_UARTTXIDLE_BITS (1) +/* SC_UARTPARERR field */ +#define SC_UARTPARERR (0x00000020u) +#define SC_UARTPARERR_MASK (0x00000020u) +#define SC_UARTPARERR_BIT (5) +#define SC_UARTPARERR_BITS (1) +/* SC_UARTFRMERR field */ +#define SC_UARTFRMERR (0x00000010u) +#define SC_UARTFRMERR_MASK (0x00000010u) +#define SC_UARTFRMERR_BIT (4) +#define SC_UARTFRMERR_BITS (1) +/* SC_UARTRXOVF field */ +#define SC_UARTRXOVF (0x00000008u) +#define SC_UARTRXOVF_MASK (0x00000008u) +#define SC_UARTRXOVF_BIT (3) +#define SC_UARTRXOVF_BITS (1) +/* SC_UARTTXFREE field */ +#define SC_UARTTXFREE (0x00000004u) +#define SC_UARTTXFREE_MASK (0x00000004u) +#define SC_UARTTXFREE_BIT (2) +#define SC_UARTTXFREE_BITS (1) +/* SC_UARTRXVAL field */ +#define SC_UARTRXVAL (0x00000002u) +#define SC_UARTRXVAL_MASK (0x00000002u) +#define SC_UARTRXVAL_BIT (1) +#define SC_UARTRXVAL_BITS (1) +/* SC_UARTCTS field */ +#define SC_UARTCTS (0x00000001u) +#define SC_UARTCTS_MASK (0x00000001u) +#define SC_UARTCTS_BIT (0) +#define SC_UARTCTS_BITS (1) + +#define SC1_TWICTRL1 *((volatile uint32_t *)0x4000C84Cu) +#define SC1_TWICTRL1_REG *((volatile uint32_t *)0x4000C84Cu) +#define SC1_TWICTRL1_ADDR (0x4000C84Cu) +#define SC1_TWICTRL1_RESET (0x00000000u) +/* SC_TWISTOP field */ +#define SC_TWISTOP (0x00000008u) +#define SC_TWISTOP_MASK (0x00000008u) +#define SC_TWISTOP_BIT (3) +#define SC_TWISTOP_BITS (1) +/* SC_TWISTART field */ +#define SC_TWISTART (0x00000004u) +#define SC_TWISTART_MASK (0x00000004u) +#define SC_TWISTART_BIT (2) +#define SC_TWISTART_BITS (1) +/* SC_TWISEND field */ +#define SC_TWISEND (0x00000002u) +#define SC_TWISEND_MASK (0x00000002u) +#define SC_TWISEND_BIT (1) +#define SC_TWISEND_BITS (1) +/* SC_TWIRECV field */ +#define SC_TWIRECV (0x00000001u) +#define SC_TWIRECV_MASK (0x00000001u) +#define SC_TWIRECV_BIT (0) +#define SC_TWIRECV_BITS (1) + +#define SC1_TWICTRL2 *((volatile uint32_t *)0x4000C850u) +#define SC1_TWICTRL2_REG *((volatile uint32_t *)0x4000C850u) +#define SC1_TWICTRL2_ADDR (0x4000C850u) +#define SC1_TWICTRL2_RESET (0x00000000u) +/* SC_TWIACK field */ +#define SC_TWIACK (0x00000001u) +#define SC_TWIACK_MASK (0x00000001u) +#define SC_TWIACK_BIT (0) +#define SC_TWIACK_BITS (1) + +#define SC1_MODE *((volatile uint32_t *)0x4000C854u) +#define SC1_MODE_REG *((volatile uint32_t *)0x4000C854u) +#define SC1_MODE_ADDR (0x4000C854u) +#define SC1_MODE_RESET (0x00000000u) +/* SC_MODE field */ +#define SC_MODE (0x00000003u) +#define SC_MODE_MASK (0x00000003u) +#define SC_MODE_BIT (0) +#define SC_MODE_BITS (2) +/* SC_MODE Bit Field Values */ +#define SC1_MODE_DISABLED (0) +#define SC1_MODE_UART (1) +#define SC1_MODE_SPI (2) +#define SC1_MODE_I2C (3) + +#define SC1_SPICFG *((volatile uint32_t *)0x4000C858u) +#define SC1_SPICFG_REG *((volatile uint32_t *)0x4000C858u) +#define SC1_SPICFG_ADDR (0x4000C858u) +#define SC1_SPICFG_RESET (0x00000000u) +/* SC_SPIRXDRV field */ +#define SC_SPIRXDRV (0x00000020u) +#define SC_SPIRXDRV_MASK (0x00000020u) +#define SC_SPIRXDRV_BIT (5) +#define SC_SPIRXDRV_BITS (1) +/* SC_SPIMST field */ +#define SC_SPIMST (0x00000010u) +#define SC_SPIMST_MASK (0x00000010u) +#define SC_SPIMST_BIT (4) +#define SC_SPIMST_BITS (1) +/* SC_SPIRPT field */ +#define SC_SPIRPT (0x00000008u) +#define SC_SPIRPT_MASK (0x00000008u) +#define SC_SPIRPT_BIT (3) +#define SC_SPIRPT_BITS (1) +/* SC_SPIORD field */ +#define SC_SPIORD (0x00000004u) +#define SC_SPIORD_MASK (0x00000004u) +#define SC_SPIORD_BIT (2) +#define SC_SPIORD_BITS (1) +/* SC_SPIPHA field */ +#define SC_SPIPHA (0x00000002u) +#define SC_SPIPHA_MASK (0x00000002u) +#define SC_SPIPHA_BIT (1) +#define SC_SPIPHA_BITS (1) +/* SC_SPIPOL field */ +#define SC_SPIPOL (0x00000001u) +#define SC_SPIPOL_MASK (0x00000001u) +#define SC_SPIPOL_BIT (0) +#define SC_SPIPOL_BITS (1) + +#define SC1_UARTCFG *((volatile uint32_t *)0x4000C85Cu) +#define SC1_UARTCFG_REG *((volatile uint32_t *)0x4000C85Cu) +#define SC1_UARTCFG_ADDR (0x4000C85Cu) +#define SC1_UARTCFG_RESET (0x00000000u) +/* SC_UARTAUTO field */ +#define SC_UARTAUTO (0x00000040u) +#define SC_UARTAUTO_MASK (0x00000040u) +#define SC_UARTAUTO_BIT (6) +#define SC_UARTAUTO_BITS (1) +/* SC_UARTFLOW field */ +#define SC_UARTFLOW (0x00000020u) +#define SC_UARTFLOW_MASK (0x00000020u) +#define SC_UARTFLOW_BIT (5) +#define SC_UARTFLOW_BITS (1) +/* SC_UARTODD field */ +#define SC_UARTODD (0x00000010u) +#define SC_UARTODD_MASK (0x00000010u) +#define SC_UARTODD_BIT (4) +#define SC_UARTODD_BITS (1) +/* SC_UARTPAR field */ +#define SC_UARTPAR (0x00000008u) +#define SC_UARTPAR_MASK (0x00000008u) +#define SC_UARTPAR_BIT (3) +#define SC_UARTPAR_BITS (1) +/* SC_UART2STP field */ +#define SC_UART2STP (0x00000004u) +#define SC_UART2STP_MASK (0x00000004u) +#define SC_UART2STP_BIT (2) +#define SC_UART2STP_BITS (1) +/* SC_UART8BIT field */ +#define SC_UART8BIT (0x00000002u) +#define SC_UART8BIT_MASK (0x00000002u) +#define SC_UART8BIT_BIT (1) +#define SC_UART8BIT_BITS (1) +/* SC_UARTRTS field */ +#define SC_UARTRTS (0x00000001u) +#define SC_UARTRTS_MASK (0x00000001u) +#define SC_UARTRTS_BIT (0) +#define SC_UARTRTS_BITS (1) + +#define SC1_RATELIN *((volatile uint32_t *)0x4000C860u) +#define SC1_RATELIN_REG *((volatile uint32_t *)0x4000C860u) +#define SC1_RATELIN_ADDR (0x4000C860u) +#define SC1_RATELIN_RESET (0x00000000u) +/* SC_RATELIN field */ +#define SC_RATELIN (0x0000000Fu) +#define SC_RATELIN_MASK (0x0000000Fu) +#define SC_RATELIN_BIT (0) +#define SC_RATELIN_BITS (4) + +#define SC1_RATEEXP *((volatile uint32_t *)0x4000C864u) +#define SC1_RATEEXP_REG *((volatile uint32_t *)0x4000C864u) +#define SC1_RATEEXP_ADDR (0x4000C864u) +#define SC1_RATEEXP_RESET (0x00000000u) +/* SC_RATEEXP field */ +#define SC_RATEEXP (0x0000000Fu) +#define SC_RATEEXP_MASK (0x0000000Fu) +#define SC_RATEEXP_BIT (0) +#define SC_RATEEXP_BITS (4) + +#define SC1_UARTPER *((volatile uint32_t *)0x4000C868u) +#define SC1_UARTPER_REG *((volatile uint32_t *)0x4000C868u) +#define SC1_UARTPER_ADDR (0x4000C868u) +#define SC1_UARTPER_RESET (0x00000000u) +/* SC_UARTPER field */ +#define SC_UARTPER (0x0000FFFFu) +#define SC_UARTPER_MASK (0x0000FFFFu) +#define SC_UARTPER_BIT (0) +#define SC_UARTPER_BITS (16) + +#define SC1_UARTFRAC *((volatile uint32_t *)0x4000C86Cu) +#define SC1_UARTFRAC_REG *((volatile uint32_t *)0x4000C86Cu) +#define SC1_UARTFRAC_ADDR (0x4000C86Cu) +#define SC1_UARTFRAC_RESET (0x00000000u) +/* SC_UARTFRAC field */ +#define SC_UARTFRAC (0x00000001u) +#define SC_UARTFRAC_MASK (0x00000001u) +#define SC_UARTFRAC_BIT (0) +#define SC_UARTFRAC_BITS (1) + +#define SC1_RXCNTSAVED *((volatile uint32_t *)0x4000C870u) +#define SC1_RXCNTSAVED_REG *((volatile uint32_t *)0x4000C870u) +#define SC1_RXCNTSAVED_ADDR (0x4000C870u) +#define SC1_RXCNTSAVED_RESET (0x00000000u) +/* SC_RXCNTSAVED field */ +#define SC_RXCNTSAVED (0x00001FFFu) +#define SC_RXCNTSAVED_MASK (0x00001FFFu) +#define SC_RXCNTSAVED_BIT (0) +#define SC_RXCNTSAVED_BITS (13) + +/* ADC block */ +#define BLOCK_ADC_BASE (0x4000D000u) +#define BLOCK_ADC_END (0x4000D024u) +#define BLOCK_ADC_SIZE (BLOCK_ADC_END - BLOCK_ADC_BASE + 1) + +#define ADC_DATA *((volatile uint32_t *)0x4000D000u) +#define ADC_DATA_REG *((volatile uint32_t *)0x4000D000u) +#define ADC_DATA_ADDR (0x4000D000u) +#define ADC_DATA_RESET (0x00000000u) +/* ADC_DATA_FIELD field */ +#define ADC_DATA_FIELD (0x0000FFFFu) +#define ADC_DATA_FIELD_MASK (0x0000FFFFu) +#define ADC_DATA_FIELD_BIT (0) +#define ADC_DATA_FIELD_BITS (16) + +#define ADC_CFG *((volatile uint32_t *)0x4000D004u) +#define ADC_CFG_REG *((volatile uint32_t *)0x4000D004u) +#define ADC_CFG_ADDR (0x4000D004u) +#define ADC_CFG_RESET (0x00001800u) +/* ADC_PERIOD field */ +#define ADC_PERIOD (0x0000E000u) +#define ADC_PERIOD_MASK (0x0000E000u) +#define ADC_PERIOD_BIT (13) +#define ADC_PERIOD_BITS (3) +/* ADC_HVSELP field */ +#define ADC_HVSELP (0x00001000u) +#define ADC_HVSELP_MASK (0x00001000u) +#define ADC_HVSELP_BIT (12) +#define ADC_HVSELP_BITS (1) +/* ADC_HVSELN field */ +#define ADC_HVSELN (0x00000800u) +#define ADC_HVSELN_MASK (0x00000800u) +#define ADC_HVSELN_BIT (11) +#define ADC_HVSELN_BITS (1) +/* ADC_MUXP field */ +#define ADC_MUXP (0x00000780u) +#define ADC_MUXP_MASK (0x00000780u) +#define ADC_MUXP_BIT (7) +#define ADC_MUXP_BITS (4) +/* ADC_MUXN field */ +#define ADC_MUXN (0x00000078u) +#define ADC_MUXN_MASK (0x00000078u) +#define ADC_MUXN_BIT (3) +#define ADC_MUXN_BITS (4) +/* ADC_1MHZCLK field */ +#define ADC_1MHZCLK (0x00000004u) +#define ADC_1MHZCLK_MASK (0x00000004u) +#define ADC_1MHZCLK_BIT (2) +#define ADC_1MHZCLK_BITS (1) +/* ADC_CFGRSVD field */ +#define ADC_CFGRSVD (0x00000002u) +#define ADC_CFGRSVD_MASK (0x00000002u) +#define ADC_CFGRSVD_BIT (1) +#define ADC_CFGRSVD_BITS (1) +/* ADC_ENABLE field */ +#define ADC_ENABLE (0x00000001u) +#define ADC_ENABLE_MASK (0x00000001u) +#define ADC_ENABLE_BIT (0) +#define ADC_ENABLE_BITS (1) + +#define ADC_OFFSET *((volatile uint32_t *)0x4000D008u) +#define ADC_OFFSET_REG *((volatile uint32_t *)0x4000D008u) +#define ADC_OFFSET_ADDR (0x4000D008u) +#define ADC_OFFSET_RESET (0x00000000u) +/* ADC_OFFSET_FIELD field */ +#define ADC_OFFSET_FIELD (0x0000FFFFu) +#define ADC_OFFSET_FIELD_MASK (0x0000FFFFu) +#define ADC_OFFSET_FIELD_BIT (0) +#define ADC_OFFSET_FIELD_BITS (16) + +#define ADC_GAIN *((volatile uint32_t *)0x4000D00Cu) +#define ADC_GAIN_REG *((volatile uint32_t *)0x4000D00Cu) +#define ADC_GAIN_ADDR (0x4000D00Cu) +#define ADC_GAIN_RESET (0x00008000u) +/* ADC_GAIN_FIELD field */ +#define ADC_GAIN_FIELD (0x0000FFFFu) +#define ADC_GAIN_FIELD_MASK (0x0000FFFFu) +#define ADC_GAIN_FIELD_BIT (0) +#define ADC_GAIN_FIELD_BITS (16) + +#define ADC_DMACFG *((volatile uint32_t *)0x4000D010u) +#define ADC_DMACFG_REG *((volatile uint32_t *)0x4000D010u) +#define ADC_DMACFG_ADDR (0x4000D010u) +#define ADC_DMACFG_RESET (0x00000000u) +/* ADC_DMARST field */ +#define ADC_DMARST (0x00000010u) +#define ADC_DMARST_MASK (0x00000010u) +#define ADC_DMARST_BIT (4) +#define ADC_DMARST_BITS (1) +/* ADC_DMAAUTOWRAP field */ +#define ADC_DMAAUTOWRAP (0x00000002u) +#define ADC_DMAAUTOWRAP_MASK (0x00000002u) +#define ADC_DMAAUTOWRAP_BIT (1) +#define ADC_DMAAUTOWRAP_BITS (1) +/* ADC_DMALOAD field */ +#define ADC_DMALOAD (0x00000001u) +#define ADC_DMALOAD_MASK (0x00000001u) +#define ADC_DMALOAD_BIT (0) +#define ADC_DMALOAD_BITS (1) + +#define ADC_DMASTAT *((volatile uint32_t *)0x4000D014u) +#define ADC_DMASTAT_REG *((volatile uint32_t *)0x4000D014u) +#define ADC_DMASTAT_ADDR (0x4000D014u) +#define ADC_DMASTAT_RESET (0x00000000u) +/* ADC_DMAOVF field */ +#define ADC_DMAOVF (0x00000002u) +#define ADC_DMAOVF_MASK (0x00000002u) +#define ADC_DMAOVF_BIT (1) +#define ADC_DMAOVF_BITS (1) +/* ADC_DMAACT field */ +#define ADC_DMAACT (0x00000001u) +#define ADC_DMAACT_MASK (0x00000001u) +#define ADC_DMAACT_BIT (0) +#define ADC_DMAACT_BITS (1) + +#define ADC_DMABEG *((volatile uint32_t *)0x4000D018u) +#define ADC_DMABEG_REG *((volatile uint32_t *)0x4000D018u) +#define ADC_DMABEG_ADDR (0x4000D018u) +#define ADC_DMABEG_RESET (0x20000000u) +/* ADC_DMABEG_FIXED field */ +#define ADC_DMABEG_FIXED (0xFFFFE000u) +#define ADC_DMABEG_FIXED_MASK (0xFFFFE000u) +#define ADC_DMABEG_FIXED_BIT (13) +#define ADC_DMABEG_FIXED_BITS (19) +/* ADC_DMABEG_FIELD field */ +#define ADC_DMABEG_FIELD (0x00001FFFu) +#define ADC_DMABEG_FIELD_MASK (0x00001FFFu) +#define ADC_DMABEG_FIELD_BIT (0) +#define ADC_DMABEG_FIELD_BITS (13) + +#define ADC_DMASIZE *((volatile uint32_t *)0x4000D01Cu) +#define ADC_DMASIZE_REG *((volatile uint32_t *)0x4000D01Cu) +#define ADC_DMASIZE_ADDR (0x4000D01Cu) +#define ADC_DMASIZE_RESET (0x00000000u) +/* ADC_DMASIZE_FIELD field */ +#define ADC_DMASIZE_FIELD (0x00000FFFu) +#define ADC_DMASIZE_FIELD_MASK (0x00000FFFu) +#define ADC_DMASIZE_FIELD_BIT (0) +#define ADC_DMASIZE_FIELD_BITS (12) + +#define ADC_DMACUR *((volatile uint32_t *)0x4000D020u) +#define ADC_DMACUR_REG *((volatile uint32_t *)0x4000D020u) +#define ADC_DMACUR_ADDR (0x4000D020u) +#define ADC_DMACUR_RESET (0x20000000u) +/* ADC_DMACUR_FIXED field */ +#define ADC_DMACUR_FIXED (0xFFFFE000u) +#define ADC_DMACUR_FIXED_MASK (0xFFFFE000u) +#define ADC_DMACUR_FIXED_BIT (13) +#define ADC_DMACUR_FIXED_BITS (19) +/* ADC_DMACUR_FIELD field */ +#define ADC_DMACUR_FIELD (0x00001FFFu) +#define ADC_DMACUR_FIELD_MASK (0x00001FFFu) +#define ADC_DMACUR_FIELD_BIT (0) +#define ADC_DMACUR_FIELD_BITS (13) + +#define ADC_DMACNT *((volatile uint32_t *)0x4000D024u) +#define ADC_DMACNT_REG *((volatile uint32_t *)0x4000D024u) +#define ADC_DMACNT_ADDR (0x4000D024u) +#define ADC_DMACNT_RESET (0x00000000u) +/* ADC_DMACNT_FIELD field */ +#define ADC_DMACNT_FIELD (0x00000FFFu) +#define ADC_DMACNT_FIELD_MASK (0x00000FFFu) +#define ADC_DMACNT_FIELD_BIT (0) +#define ADC_DMACNT_FIELD_BITS (12) + +/* TIM1 block */ +#define BLOCK_TIM1_BASE (0x4000E000u) +#define BLOCK_TIM1_END (0x4000E050u) +#define BLOCK_TIM1_SIZE (BLOCK_TIM1_END - BLOCK_TIM1_BASE + 1) + +#define TIM1_CR1 *((volatile uint32_t *)0x4000E000u) +#define TIM1_CR1_REG *((volatile uint32_t *)0x4000E000u) +#define TIM1_CR1_ADDR (0x4000E000u) +#define TIM1_CR1_RESET (0x00000000u) +/* TIM_ARBE field */ +#define TIM_ARBE (0x00000080u) +#define TIM_ARBE_MASK (0x00000080u) +#define TIM_ARBE_BIT (7) +#define TIM_ARBE_BITS (1) +/* TIM_CMS field */ +#define TIM_CMS (0x00000060u) +#define TIM_CMS_MASK (0x00000060u) +#define TIM_CMS_BIT (5) +#define TIM_CMS_BITS (2) +/* TIM_DIR field */ +#define TIM_DIR (0x00000010u) +#define TIM_DIR_MASK (0x00000010u) +#define TIM_DIR_BIT (4) +#define TIM_DIR_BITS (1) +/* TIM_OPM field */ +#define TIM_OPM (0x00000008u) +#define TIM_OPM_MASK (0x00000008u) +#define TIM_OPM_BIT (3) +#define TIM_OPM_BITS (1) +/* TIM_URS field */ +#define TIM_URS (0x00000004u) +#define TIM_URS_MASK (0x00000004u) +#define TIM_URS_BIT (2) +#define TIM_URS_BITS (1) +/* TIM_UDIS field */ +#define TIM_UDIS (0x00000002u) +#define TIM_UDIS_MASK (0x00000002u) +#define TIM_UDIS_BIT (1) +#define TIM_UDIS_BITS (1) +/* TIM_CEN field */ +#define TIM_CEN (0x00000001u) +#define TIM_CEN_MASK (0x00000001u) +#define TIM_CEN_BIT (0) +#define TIM_CEN_BITS (1) + +#define TIM1_CR2 *((volatile uint32_t *)0x4000E004u) +#define TIM1_CR2_REG *((volatile uint32_t *)0x4000E004u) +#define TIM1_CR2_ADDR (0x4000E004u) +#define TIM1_CR2_RESET (0x00000000u) +/* TIM_TI1S field */ +#define TIM_TI1S (0x00000080u) +#define TIM_TI1S_MASK (0x00000080u) +#define TIM_TI1S_BIT (7) +#define TIM_TI1S_BITS (1) +/* TIM_MMS field */ +#define TIM_MMS (0x00000070u) +#define TIM_MMS_MASK (0x00000070u) +#define TIM_MMS_BIT (4) +#define TIM_MMS_BITS (3) + +#define TIM1_SMCR *((volatile uint32_t *)0x4000E008u) +#define TIM1_SMCR_REG *((volatile uint32_t *)0x4000E008u) +#define TIM1_SMCR_ADDR (0x4000E008u) +#define TIM1_SMCR_RESET (0x00000000u) +/* TIM_ETP field */ +#define TIM_ETP (0x00008000u) +#define TIM_ETP_MASK (0x00008000u) +#define TIM_ETP_BIT (15) +#define TIM_ETP_BITS (1) +/* TIM_ECE field */ +#define TIM_ECE (0x00004000u) +#define TIM_ECE_MASK (0x00004000u) +#define TIM_ECE_BIT (14) +#define TIM_ECE_BITS (1) +/* TIM_ETPS field */ +#define TIM_ETPS (0x00003000u) +#define TIM_ETPS_MASK (0x00003000u) +#define TIM_ETPS_BIT (12) +#define TIM_ETPS_BITS (2) +/* TIM_ETF field */ +#define TIM_ETF (0x00000F00u) +#define TIM_ETF_MASK (0x00000F00u) +#define TIM_ETF_BIT (8) +#define TIM_ETF_BITS (4) +/* TIM_MSM field */ +#define TIM_MSM (0x00000080u) +#define TIM_MSM_MASK (0x00000080u) +#define TIM_MSM_BIT (7) +#define TIM_MSM_BITS (1) +/* TIM_TS field */ +#define TIM_TS (0x00000070u) +#define TIM_TS_MASK (0x00000070u) +#define TIM_TS_BIT (4) +#define TIM_TS_BITS (3) +/* TIM_SMS field */ +#define TIM_SMS (0x00000007u) +#define TIM_SMS_MASK (0x00000007u) +#define TIM_SMS_BIT (0) +#define TIM_SMS_BITS (3) + +#define TMR1_DIER *((volatile uint32_t *)0x4000E00Cu) +#define TMR1_DIER_REG *((volatile uint32_t *)0x4000E00Cu) +#define TMR1_DIER_ADDR (0x4000E00Cu) +#define TMR1_DIER_RESET (0x00000000u) +/* TIE field */ +#define TMR1_DIER_TIE (0x00000040u) +#define TMR1_DIER_TIE_MASK (0x00000040u) +#define TMR1_DIER_TIE_BIT (6) +#define TMR1_DIER_TIE_BITS (1) +/* CC4IE field */ +#define TMR1_DIER_CC4IE (0x00000010u) +#define TMR1_DIER_CC4IE_MASK (0x00000010u) +#define TMR1_DIER_CC4IE_BIT (4) +#define TMR1_DIER_CC4IE_BITS (1) +/* CC3IE field */ +#define TMR1_DIER_CC3IE (0x00000008u) +#define TMR1_DIER_CC3IE_MASK (0x00000008u) +#define TMR1_DIER_CC3IE_BIT (3) +#define TMR1_DIER_CC3IE_BITS (1) +/* CC2IE field */ +#define TMR1_DIER_CC2IE (0x00000004u) +#define TMR1_DIER_CC2IE_MASK (0x00000004u) +#define TMR1_DIER_CC2IE_BIT (2) +#define TMR1_DIER_CC2IE_BITS (1) +/* CC1IE field */ +#define TMR1_DIER_CC1IE (0x00000002u) +#define TMR1_DIER_CC1IE_MASK (0x00000002u) +#define TMR1_DIER_CC1IE_BIT (1) +#define TMR1_DIER_CC1IE_BITS (1) +/* UIE field */ +#define TMR1_DIER_UIE (0x00000001u) +#define TMR1_DIER_UIE_MASK (0x00000001u) +#define TMR1_DIER_UIE_BIT (0) +#define TMR1_DIER_UIE_BITS (1) + +#define TMR1_SR *((volatile uint32_t *)0x4000E010u) +#define TMR1_SR_REG *((volatile uint32_t *)0x4000E010u) +#define TMR1_SR_ADDR (0x4000E010u) +#define TMR1_SR_RESET (0x00000000u) +/* CC4OF field */ +#define TMR1_SR_CC4OF (0x00001000u) +#define TMR1_SR_CC4OF_MASK (0x00001000u) +#define TMR1_SR_CC4OF_BIT (12) +#define TMR1_SR_CC4OF_BITS (1) +/* CC3OF field */ +#define TMR1_SR_CC3OF (0x00000800u) +#define TMR1_SR_CC3OF_MASK (0x00000800u) +#define TMR1_SR_CC3OF_BIT (11) +#define TMR1_SR_CC3OF_BITS (1) +/* CC2OF field */ +#define TMR1_SR_CC2OF (0x00000400u) +#define TMR1_SR_CC2OF_MASK (0x00000400u) +#define TMR1_SR_CC2OF_BIT (10) +#define TMR1_SR_CC2OF_BITS (1) +/* CC1OF field */ +#define TMR1_SR_CC1OF (0x00000200u) +#define TMR1_SR_CC1OF_MASK (0x00000200u) +#define TMR1_SR_CC1OF_BIT (9) +#define TMR1_SR_CC1OF_BITS (1) +/* TIF field */ +#define TMR1_SR_TIF (0x00000040u) +#define TMR1_SR_TIF_MASK (0x00000040u) +#define TMR1_SR_TIF_BIT (6) +#define TMR1_SR_TIF_BITS (1) +/* CC4IF field */ +#define TMR1_SR_CC4IF (0x00000010u) +#define TMR1_SR_CC4IF_MASK (0x00000010u) +#define TMR1_SR_CC4IF_BIT (4) +#define TMR1_SR_CC4IF_BITS (1) +/* CC3IF field */ +#define TMR1_SR_CC3IF (0x00000008u) +#define TMR1_SR_CC3IF_MASK (0x00000008u) +#define TMR1_SR_CC3IF_BIT (3) +#define TMR1_SR_CC3IF_BITS (1) +/* CC2IF field */ +#define TMR1_SR_CC2IF (0x00000004u) +#define TMR1_SR_CC2IF_MASK (0x00000004u) +#define TMR1_SR_CC2IF_BIT (2) +#define TMR1_SR_CC2IF_BITS (1) +/* CC1IF field */ +#define TMR1_SR_CC1IF (0x00000002u) +#define TMR1_SR_CC1IF_MASK (0x00000002u) +#define TMR1_SR_CC1IF_BIT (1) +#define TMR1_SR_CC1IF_BITS (1) +/* UIF field */ +#define TMR1_SR_UIF (0x00000001u) +#define TMR1_SR_UIF_MASK (0x00000001u) +#define TMR1_SR_UIF_BIT (0) +#define TMR1_SR_UIF_BITS (1) + +#define TIM1_EGR *((volatile uint32_t *)0x4000E014u) +#define TIM1_EGR_REG *((volatile uint32_t *)0x4000E014u) +#define TIM1_EGR_ADDR (0x4000E014u) +#define TIM1_EGR_RESET (0x00000000u) +/* TIM_TG field */ +#define TIM_TG (0x00000040u) +#define TIM_TG_MASK (0x00000040u) +#define TIM_TG_BIT (6) +#define TIM_TG_BITS (1) +/* TIM_CC4G field */ +#define TIM_CC4G (0x00000010u) +#define TIM_CC4G_MASK (0x00000010u) +#define TIM_CC4G_BIT (4) +#define TIM_CC4G_BITS (1) +/* TIM_CC3G field */ +#define TIM_CC3G (0x00000008u) +#define TIM_CC3G_MASK (0x00000008u) +#define TIM_CC3G_BIT (3) +#define TIM_CC3G_BITS (1) +/* TIM_CC2G field */ +#define TIM_CC2G (0x00000004u) +#define TIM_CC2G_MASK (0x00000004u) +#define TIM_CC2G_BIT (2) +#define TIM_CC2G_BITS (1) +/* TIM_CC1G field */ +#define TIM_CC1G (0x00000002u) +#define TIM_CC1G_MASK (0x00000002u) +#define TIM_CC1G_BIT (1) +#define TIM_CC1G_BITS (1) +/* TIM_UG field */ +#define TIM_UG (0x00000001u) +#define TIM_UG_MASK (0x00000001u) +#define TIM_UG_BIT (0) +#define TIM_UG_BITS (1) + +#define TIM1_CCMR1 *((volatile uint32_t *)0x4000E018u) +#define TIM1_CCMR1_REG *((volatile uint32_t *)0x4000E018u) +#define TIM1_CCMR1_ADDR (0x4000E018u) +#define TIM1_CCMR1_RESET (0x00000000u) +/* TIM_IC2F field */ +#define TIM_IC2F (0x0000F000u) +#define TIM_IC2F_MASK (0x0000F000u) +#define TIM_IC2F_BIT (12) +#define TIM_IC2F_BITS (4) +/* TIM_IC2PSC field */ +#define TIM_IC2PSC (0x00000C00u) +#define TIM_IC2PSC_MASK (0x00000C00u) +#define TIM_IC2PSC_BIT (10) +#define TIM_IC2PSC_BITS (2) +/* TIM_IC1F field */ +#define TIM_IC1F (0x000000F0u) +#define TIM_IC1F_MASK (0x000000F0u) +#define TIM_IC1F_BIT (4) +#define TIM_IC1F_BITS (4) +/* TIM_IC1PSC field */ +#define TIM_IC1PSC (0x0000000Cu) +#define TIM_IC1PSC_MASK (0x0000000Cu) +#define TIM_IC1PSC_BIT (2) +#define TIM_IC1PSC_BITS (2) +/* TIM_OC2CE field */ +#define TIM_OC2CE (0x00008000u) +#define TIM_OC2CE_MASK (0x00008000u) +#define TIM_OC2CE_BIT (15) +#define TIM_OC2CE_BITS (1) +/* TIM_OC2M field */ +#define TIM_OC2M (0x00007000u) +#define TIM_OC2M_MASK (0x00007000u) +#define TIM_OC2M_BIT (12) +#define TIM_OC2M_BITS (3) +/* TIM_OC2BE field */ +#define TIM_OC2BE (0x00000800u) +#define TIM_OC2BE_MASK (0x00000800u) +#define TIM_OC2BE_BIT (11) +#define TIM_OC2BE_BITS (1) +/* TIM_OC2FE field */ +#define TIM_OC2FE (0x00000400u) +#define TIM_OC2FE_MASK (0x00000400u) +#define TIM_OC2FE_BIT (10) +#define TIM_OC2FE_BITS (1) +/* TIM_CC2S field */ +#define TIM_CC2S (0x00000300u) +#define TIM_CC2S_MASK (0x00000300u) +#define TIM_CC2S_BIT (8) +#define TIM_CC2S_BITS (2) +/* TIM_OC1CE field */ +#define TIM_OC1CE (0x00000080u) +#define TIM_OC1CE_MASK (0x00000080u) +#define TIM_OC1CE_BIT (7) +#define TIM_OC1CE_BITS (1) +/* TIM_OC1M field */ +#define TIM_OC1M (0x00000070u) +#define TIM_OC1M_MASK (0x00000070u) +#define TIM_OC1M_BIT (4) +#define TIM_OC1M_BITS (3) +/* TIM_OC1PE field */ +#define TIM_OC1PE (0x00000008u) +#define TIM_OC1PE_MASK (0x00000008u) +#define TIM_OC1PE_BIT (3) +#define TIM_OC1PE_BITS (1) +/* TIM_OC1FE field */ +#define TIM_OC1FE (0x00000004u) +#define TIM_OC1FE_MASK (0x00000004u) +#define TIM_OC1FE_BIT (2) +#define TIM_OC1FE_BITS (1) +/* TIM_CC1S field */ +#define TIM_CC1S (0x00000003u) +#define TIM_CC1S_MASK (0x00000003u) +#define TIM_CC1S_BIT (0) +#define TIM_CC1S_BITS (2) + +#define TIM1_CCMR2 *((volatile uint32_t *)0x4000E01Cu) +#define TIM1_CCMR2_REG *((volatile uint32_t *)0x4000E01Cu) +#define TIM1_CCMR2_ADDR (0x4000E01Cu) +#define TIM1_CCMR2_RESET (0x00000000u) +/* TIM_IC4F field */ +#define TIM_IC4F (0x0000F000u) +#define TIM_IC4F_MASK (0x0000F000u) +#define TIM_IC4F_BIT (12) +#define TIM_IC4F_BITS (4) +/* TIM_IC4PSC field */ +#define TIM_IC4PSC (0x00000C00u) +#define TIM_IC4PSC_MASK (0x00000C00u) +#define TIM_IC4PSC_BIT (10) +#define TIM_IC4PSC_BITS (2) +/* TIM_IC3F field */ +#define TIM_IC3F (0x000000F0u) +#define TIM_IC3F_MASK (0x000000F0u) +#define TIM_IC3F_BIT (4) +#define TIM_IC3F_BITS (4) +/* TIM_IC3PSC field */ +#define TIM_IC3PSC (0x0000000Cu) +#define TIM_IC3PSC_MASK (0x0000000Cu) +#define TIM_IC3PSC_BIT (2) +#define TIM_IC3PSC_BITS (2) +/* TIM_OC4CE field */ +#define TIM_OC4CE (0x00008000u) +#define TIM_OC4CE_MASK (0x00008000u) +#define TIM_OC4CE_BIT (15) +#define TIM_OC4CE_BITS (1) +/* TIM_OC4M field */ +#define TIM_OC4M (0x00007000u) +#define TIM_OC4M_MASK (0x00007000u) +#define TIM_OC4M_BIT (12) +#define TIM_OC4M_BITS (3) +/* TIM_OC4BE field */ +#define TIM_OC4BE (0x00000800u) +#define TIM_OC4BE_MASK (0x00000800u) +#define TIM_OC4BE_BIT (11) +#define TIM_OC4BE_BITS (1) +/* TIM_OC4FE field */ +#define TIM_OC4FE (0x00000400u) +#define TIM_OC4FE_MASK (0x00000400u) +#define TIM_OC4FE_BIT (10) +#define TIM_OC4FE_BITS (1) +/* TIM_CC4S field */ +#define TIM_CC4S (0x00000300u) +#define TIM_CC4S_MASK (0x00000300u) +#define TIM_CC4S_BIT (8) +#define TIM_CC4S_BITS (2) +/* TIM_OC3CE field */ +#define TIM_OC3CE (0x00000080u) +#define TIM_OC3CE_MASK (0x00000080u) +#define TIM_OC3CE_BIT (7) +#define TIM_OC3CE_BITS (1) +/* TIM_OC3M field */ +#define TIM_OC3M (0x00000070u) +#define TIM_OC3M_MASK (0x00000070u) +#define TIM_OC3M_BIT (4) +#define TIM_OC3M_BITS (3) +/* TIM_OC3BE field */ +#define TIM_OC3BE (0x00000008u) +#define TIM_OC3BE_MASK (0x00000008u) +#define TIM_OC3BE_BIT (3) +#define TIM_OC3BE_BITS (1) +/* TIM_OC3FE field */ +#define TIM_OC3FE (0x00000004u) +#define TIM_OC3FE_MASK (0x00000004u) +#define TIM_OC3FE_BIT (2) +#define TIM_OC3FE_BITS (1) +/* TIM_CC3S field */ +#define TIM_CC3S (0x00000003u) +#define TIM_CC3S_MASK (0x00000003u) +#define TIM_CC3S_BIT (0) +#define TIM_CC3S_BITS (2) + +#define TIM1_CCER *((volatile uint32_t *)0x4000E020u) +#define TIM1_CCER_REG *((volatile uint32_t *)0x4000E020u) +#define TIM1_CCER_ADDR (0x4000E020u) +#define TIM1_CCER_RESET (0x00000000u) +/* TIM_CC4P field */ +#define TIM_CC4P (0x00002000u) +#define TIM_CC4P_MASK (0x00002000u) +#define TIM_CC4P_BIT (13) +#define TIM_CC4P_BITS (1) +/* TIM_CC4E field */ +#define TIM_CC4E (0x00001000u) +#define TIM_CC4E_MASK (0x00001000u) +#define TIM_CC4E_BIT (12) +#define TIM_CC4E_BITS (1) +/* TIM_CC3P field */ +#define TIM_CC3P (0x00000200u) +#define TIM_CC3P_MASK (0x00000200u) +#define TIM_CC3P_BIT (9) +#define TIM_CC3P_BITS (1) +/* TIM_CC3E field */ +#define TIM_CC3E (0x00000100u) +#define TIM_CC3E_MASK (0x00000100u) +#define TIM_CC3E_BIT (8) +#define TIM_CC3E_BITS (1) +/* TIM_CC2P field */ +#define TIM_CC2P (0x00000020u) +#define TIM_CC2P_MASK (0x00000020u) +#define TIM_CC2P_BIT (5) +#define TIM_CC2P_BITS (1) +/* TIM_CC2E field */ +#define TIM_CC2E (0x00000010u) +#define TIM_CC2E_MASK (0x00000010u) +#define TIM_CC2E_BIT (4) +#define TIM_CC2E_BITS (1) +/* TIM_CC1P field */ +#define TIM_CC1P (0x00000002u) +#define TIM_CC1P_MASK (0x00000002u) +#define TIM_CC1P_BIT (1) +#define TIM_CC1P_BITS (1) +/* TIM_CC1E field */ +#define TIM_CC1E (0x00000001u) +#define TIM_CC1E_MASK (0x00000001u) +#define TIM_CC1E_BIT (0) +#define TIM_CC1E_BITS (1) + +#define TIM1_CNT *((volatile uint32_t *)0x4000E024u) +#define TIM1_CNT_REG *((volatile uint32_t *)0x4000E024u) +#define TIM1_CNT_ADDR (0x4000E024u) +#define TIM1_CNT_RESET (0x00000000u) +/* TIM_CNT field */ +#define TIM_CNT (0x0000FFFFu) +#define TIM_CNT_MASK (0x0000FFFFu) +#define TIM_CNT_BIT (0) +#define TIM_CNT_BITS (16) + +#define TIM1_PSC *((volatile uint32_t *)0x4000E028u) +#define TIM1_PSC_REG *((volatile uint32_t *)0x4000E028u) +#define TIM1_PSC_ADDR (0x4000E028u) +#define TIM1_PSC_RESET (0x00000000u) +/* TIM_PSC field */ +#define TIM_PSC (0x0000000Fu) +#define TIM_PSC_MASK (0x0000000Fu) +#define TIM_PSC_BIT (0) +#define TIM_PSC_BITS (4) + +#define TIM1_ARR *((volatile uint32_t *)0x4000E02Cu) +#define TIM1_ARR_REG *((volatile uint32_t *)0x4000E02Cu) +#define TIM1_ARR_ADDR (0x4000E02Cu) +#define TIM1_ARR_RESET (0x0000FFFFu) +/* TIM_ARR field */ +#define TIM_ARR (0x0000FFFFu) +#define TIM_ARR_MASK (0x0000FFFFu) +#define TIM_ARR_BIT (0) +#define TIM_ARR_BITS (16) + +#define TIM1_CCR1 *((volatile uint32_t *)0x4000E034u) +#define TIM1_CCR1_REG *((volatile uint32_t *)0x4000E034u) +#define TIM1_CCR1_ADDR (0x4000E034u) +#define TIM1_CCR1_RESET (0x00000000u) +/* TIM_CCR field */ +#define TIM_CCR (0x0000FFFFu) +#define TIM_CCR_MASK (0x0000FFFFu) +#define TIM_CCR_BIT (0) +#define TIM_CCR_BITS (16) + +#define TIM1_CCR2 *((volatile uint32_t *)0x4000E038u) +#define TIM1_CCR2_REG *((volatile uint32_t *)0x4000E038u) +#define TIM1_CCR2_ADDR (0x4000E038u) +#define TIM1_CCR2_RESET (0x00000000u) +/* TIM_CCR field */ +#define TIM_CCR (0x0000FFFFu) +#define TIM_CCR_MASK (0x0000FFFFu) +#define TIM_CCR_BIT (0) +#define TIM_CCR_BITS (16) + +#define TIM1_CCR3 *((volatile uint32_t *)0x4000E03Cu) +#define TIM1_CCR3_REG *((volatile uint32_t *)0x4000E03Cu) +#define TIM1_CCR3_ADDR (0x4000E03Cu) +#define TIM1_CCR3_RESET (0x00000000u) +/* TIM_CCR field */ +#define TIM_CCR (0x0000FFFFu) +#define TIM_CCR_MASK (0x0000FFFFu) +#define TIM_CCR_BIT (0) +#define TIM_CCR_BITS (16) + +#define TIM1_CCR4 *((volatile uint32_t *)0x4000E040u) +#define TIM1_CCR4_REG *((volatile uint32_t *)0x4000E040u) +#define TIM1_CCR4_ADDR (0x4000E040u) +#define TIM1_CCR4_RESET (0x00000000u) +/* TIM_CCR field */ +#define TIM_CCR (0x0000FFFFu) +#define TIM_CCR_MASK (0x0000FFFFu) +#define TIM_CCR_BIT (0) +#define TIM_CCR_BITS (16) + +#define TIM1_OR *((volatile uint32_t *)0x4000E050u) +#define TIM1_OR_REG *((volatile uint32_t *)0x4000E050u) +#define TIM1_OR_ADDR (0x4000E050u) +#define TIM1_OR_RESET (0x00000000u) +/* TIM_ORRSVD field */ +#define TIM_ORRSVD (0x00000008u) +#define TIM_ORRSVD_MASK (0x00000008u) +#define TIM_ORRSVD_BIT (3) +#define TIM_ORRSVD_BITS (1) +/* TIM_CLKMSKEN field */ +#define TIM_CLKMSKEN (0x00000004u) +#define TIM_CLKMSKEN_MASK (0x00000004u) +#define TIM_CLKMSKEN_BIT (2) +#define TIM_CLKMSKEN_BITS (1) +/* TIM1_EXTRIGSEL field */ +#define TIM1_EXTRIGSEL (0x00000003u) +#define TIM1_EXTRIGSEL_MASK (0x00000003u) +#define TIM1_EXTRIGSEL_BIT (0) +#define TIM1_EXTRIGSEL_BITS (2) + +/* TIM2 block */ +#define BLOCK_TIM2_BASE (0x4000F000u) +#define BLOCK_TIM2_END (0x4000F050u) +#define BLOCK_TIM2_SIZE (BLOCK_TIM2_END - BLOCK_TIM2_BASE + 1) + +#define TIM2_CR1 *((volatile uint32_t *)0x4000F000u) +#define TIM2_CR1_REG *((volatile uint32_t *)0x4000F000u) +#define TIM2_CR1_ADDR (0x4000F000u) +#define TIM2_CR1_RESET (0x00000000u) +/* TIM_ARBE field */ +#define TIM_ARBE (0x00000080u) +#define TIM_ARBE_MASK (0x00000080u) +#define TIM_ARBE_BIT (7) +#define TIM_ARBE_BITS (1) +/* TIM_CMS field */ +#define TIM_CMS (0x00000060u) +#define TIM_CMS_MASK (0x00000060u) +#define TIM_CMS_BIT (5) +#define TIM_CMS_BITS (2) +/* TIM_DIR field */ +#define TIM_DIR (0x00000010u) +#define TIM_DIR_MASK (0x00000010u) +#define TIM_DIR_BIT (4) +#define TIM_DIR_BITS (1) +/* TIM_OPM field */ +#define TIM_OPM (0x00000008u) +#define TIM_OPM_MASK (0x00000008u) +#define TIM_OPM_BIT (3) +#define TIM_OPM_BITS (1) +/* TIM_URS field */ +#define TIM_URS (0x00000004u) +#define TIM_URS_MASK (0x00000004u) +#define TIM_URS_BIT (2) +#define TIM_URS_BITS (1) +/* TIM_UDIS field */ +#define TIM_UDIS (0x00000002u) +#define TIM_UDIS_MASK (0x00000002u) +#define TIM_UDIS_BIT (1) +#define TIM_UDIS_BITS (1) +/* TIM_CEN field */ +#define TIM_CEN (0x00000001u) +#define TIM_CEN_MASK (0x00000001u) +#define TIM_CEN_BIT (0) +#define TIM_CEN_BITS (1) + +#define TIM2_CR2 *((volatile uint32_t *)0x4000F004u) +#define TIM2_CR2_REG *((volatile uint32_t *)0x4000F004u) +#define TIM2_CR2_ADDR (0x4000F004u) +#define TIM2_CR2_RESET (0x00000000u) +/* TIM_TI1S field */ +#define TIM_TI1S (0x00000080u) +#define TIM_TI1S_MASK (0x00000080u) +#define TIM_TI1S_BIT (7) +#define TIM_TI1S_BITS (1) +/* TIM_MMS field */ +#define TIM_MMS (0x00000070u) +#define TIM_MMS_MASK (0x00000070u) +#define TIM_MMS_BIT (4) +#define TIM_MMS_BITS (3) + +#define TIM2_SMCR *((volatile uint32_t *)0x4000F008u) +#define TIM2_SMCR_REG *((volatile uint32_t *)0x4000F008u) +#define TIM2_SMCR_ADDR (0x4000F008u) +#define TIM2_SMCR_RESET (0x00000000u) +/* TIM_ETP field */ +#define TIM_ETP (0x00008000u) +#define TIM_ETP_MASK (0x00008000u) +#define TIM_ETP_BIT (15) +#define TIM_ETP_BITS (1) +/* TIM_ECE field */ +#define TIM_ECE (0x00004000u) +#define TIM_ECE_MASK (0x00004000u) +#define TIM_ECE_BIT (14) +#define TIM_ECE_BITS (1) +/* TIM_ETPS field */ +#define TIM_ETPS (0x00003000u) +#define TIM_ETPS_MASK (0x00003000u) +#define TIM_ETPS_BIT (12) +#define TIM_ETPS_BITS (2) +/* TIM_ETF field */ +#define TIM_ETF (0x00000F00u) +#define TIM_ETF_MASK (0x00000F00u) +#define TIM_ETF_BIT (8) +#define TIM_ETF_BITS (4) +/* TIM_MSM field */ +#define TIM_MSM (0x00000080u) +#define TIM_MSM_MASK (0x00000080u) +#define TIM_MSM_BIT (7) +#define TIM_MSM_BITS (1) +/* TIM_TS field */ +#define TIM_TS (0x00000070u) +#define TIM_TS_MASK (0x00000070u) +#define TIM_TS_BIT (4) +#define TIM_TS_BITS (3) +/* TIM_SMS field */ +#define TIM_SMS (0x00000007u) +#define TIM_SMS_MASK (0x00000007u) +#define TIM_SMS_BIT (0) +#define TIM_SMS_BITS (3) + +#define TMR2_DIER *((volatile uint32_t *)0x4000F00Cu) +#define TMR2_DIER_REG *((volatile uint32_t *)0x4000F00Cu) +#define TMR2_DIER_ADDR (0x4000F00Cu) +#define TMR2_DIER_RESET (0x00000000u) +/* TIE field */ +#define TMR2_DIER_TIE (0x00000040u) +#define TMR2_DIER_TIE_MASK (0x00000040u) +#define TMR2_DIER_TIE_BIT (6) +#define TMR2_DIER_TIE_BITS (1) +/* CC4IE field */ +#define TMR2_DIER_CC4IE (0x00000010u) +#define TMR2_DIER_CC4IE_MASK (0x00000010u) +#define TMR2_DIER_CC4IE_BIT (4) +#define TMR2_DIER_CC4IE_BITS (1) +/* CC3IE field */ +#define TMR2_DIER_CC3IE (0x00000008u) +#define TMR2_DIER_CC3IE_MASK (0x00000008u) +#define TMR2_DIER_CC3IE_BIT (3) +#define TMR2_DIER_CC3IE_BITS (1) +/* CC2IE field */ +#define TMR2_DIER_CC2IE (0x00000004u) +#define TMR2_DIER_CC2IE_MASK (0x00000004u) +#define TMR2_DIER_CC2IE_BIT (2) +#define TMR2_DIER_CC2IE_BITS (1) +/* CC1IE field */ +#define TMR2_DIER_CC1IE (0x00000002u) +#define TMR2_DIER_CC1IE_MASK (0x00000002u) +#define TMR2_DIER_CC1IE_BIT (1) +#define TMR2_DIER_CC1IE_BITS (1) +/* UIE field */ +#define TMR2_DIER_UIE (0x00000001u) +#define TMR2_DIER_UIE_MASK (0x00000001u) +#define TMR2_DIER_UIE_BIT (0) +#define TMR2_DIER_UIE_BITS (1) + +#define TMR2_SR *((volatile uint32_t *)0x4000F010u) +#define TMR2_SR_REG *((volatile uint32_t *)0x4000F010u) +#define TMR2_SR_ADDR (0x4000F010u) +#define TMR2_SR_RESET (0x00000000u) +/* CC4OF field */ +#define TMR2_SR_CC4OF (0x00001000u) +#define TMR2_SR_CC4OF_MASK (0x00001000u) +#define TMR2_SR_CC4OF_BIT (12) +#define TMR2_SR_CC4OF_BITS (1) +/* CC3OF field */ +#define TMR2_SR_CC3OF (0x00000800u) +#define TMR2_SR_CC3OF_MASK (0x00000800u) +#define TMR2_SR_CC3OF_BIT (11) +#define TMR2_SR_CC3OF_BITS (1) +/* CC2OF field */ +#define TMR2_SR_CC2OF (0x00000400u) +#define TMR2_SR_CC2OF_MASK (0x00000400u) +#define TMR2_SR_CC2OF_BIT (10) +#define TMR2_SR_CC2OF_BITS (1) +/* CC1OF field */ +#define TMR2_SR_CC1OF (0x00000200u) +#define TMR2_SR_CC1OF_MASK (0x00000200u) +#define TMR2_SR_CC1OF_BIT (9) +#define TMR2_SR_CC1OF_BITS (1) +/* TIF field */ +#define TMR2_SR_TIF (0x00000040u) +#define TMR2_SR_TIF_MASK (0x00000040u) +#define TMR2_SR_TIF_BIT (6) +#define TMR2_SR_TIF_BITS (1) +/* CC4IF field */ +#define TMR2_SR_CC4IF (0x00000010u) +#define TMR2_SR_CC4IF_MASK (0x00000010u) +#define TMR2_SR_CC4IF_BIT (4) +#define TMR2_SR_CC4IF_BITS (1) +/* CC3IF field */ +#define TMR2_SR_CC3IF (0x00000008u) +#define TMR2_SR_CC3IF_MASK (0x00000008u) +#define TMR2_SR_CC3IF_BIT (3) +#define TMR2_SR_CC3IF_BITS (1) +/* CC2IF field */ +#define TMR2_SR_CC2IF (0x00000004u) +#define TMR2_SR_CC2IF_MASK (0x00000004u) +#define TMR2_SR_CC2IF_BIT (2) +#define TMR2_SR_CC2IF_BITS (1) +/* CC1IF field */ +#define TMR2_SR_CC1IF (0x00000002u) +#define TMR2_SR_CC1IF_MASK (0x00000002u) +#define TMR2_SR_CC1IF_BIT (1) +#define TMR2_SR_CC1IF_BITS (1) +/* UIF field */ +#define TMR2_SR_UIF (0x00000001u) +#define TMR2_SR_UIF_MASK (0x00000001u) +#define TMR2_SR_UIF_BIT (0) +#define TMR2_SR_UIF_BITS (1) + +#define TIM2_EGR *((volatile uint32_t *)0x4000F014u) +#define TIM2_EGR_REG *((volatile uint32_t *)0x4000F014u) +#define TIM2_EGR_ADDR (0x4000F014u) +#define TIM2_EGR_RESET (0x00000000u) +/* TIM_TG field */ +#define TIM_TG (0x00000040u) +#define TIM_TG_MASK (0x00000040u) +#define TIM_TG_BIT (6) +#define TIM_TG_BITS (1) +/* TIM_CC4G field */ +#define TIM_CC4G (0x00000010u) +#define TIM_CC4G_MASK (0x00000010u) +#define TIM_CC4G_BIT (4) +#define TIM_CC4G_BITS (1) +/* TIM_CC3G field */ +#define TIM_CC3G (0x00000008u) +#define TIM_CC3G_MASK (0x00000008u) +#define TIM_CC3G_BIT (3) +#define TIM_CC3G_BITS (1) +/* TIM_CC2G field */ +#define TIM_CC2G (0x00000004u) +#define TIM_CC2G_MASK (0x00000004u) +#define TIM_CC2G_BIT (2) +#define TIM_CC2G_BITS (1) +/* TIM_CC1G field */ +#define TIM_CC1G (0x00000002u) +#define TIM_CC1G_MASK (0x00000002u) +#define TIM_CC1G_BIT (1) +#define TIM_CC1G_BITS (1) +/* TIM_UG field */ +#define TIM_UG (0x00000001u) +#define TIM_UG_MASK (0x00000001u) +#define TIM_UG_BIT (0) +#define TIM_UG_BITS (1) + +#define TIM2_CCMR1 *((volatile uint32_t *)0x4000F018u) +#define TIM2_CCMR1_REG *((volatile uint32_t *)0x4000F018u) +#define TIM2_CCMR1_ADDR (0x4000F018u) +#define TIM2_CCMR1_RESET (0x00000000u) +/* TIM_IC2F field */ +#define TIM_IC2F (0x0000F000u) +#define TIM_IC2F_MASK (0x0000F000u) +#define TIM_IC2F_BIT (12) +#define TIM_IC2F_BITS (4) +/* TIM_IC2PSC field */ +#define TIM_IC2PSC (0x00000C00u) +#define TIM_IC2PSC_MASK (0x00000C00u) +#define TIM_IC2PSC_BIT (10) +#define TIM_IC2PSC_BITS (2) +/* TIM_IC1F field */ +#define TIM_IC1F (0x000000F0u) +#define TIM_IC1F_MASK (0x000000F0u) +#define TIM_IC1F_BIT (4) +#define TIM_IC1F_BITS (4) +/* TIM_IC1PSC field */ +#define TIM_IC1PSC (0x0000000Cu) +#define TIM_IC1PSC_MASK (0x0000000Cu) +#define TIM_IC1PSC_BIT (2) +#define TIM_IC1PSC_BITS (2) +/* TIM_OC2CE field */ +#define TIM_OC2CE (0x00008000u) +#define TIM_OC2CE_MASK (0x00008000u) +#define TIM_OC2CE_BIT (15) +#define TIM_OC2CE_BITS (1) +/* TIM_OC2M field */ +#define TIM_OC2M (0x00007000u) +#define TIM_OC2M_MASK (0x00007000u) +#define TIM_OC2M_BIT (12) +#define TIM_OC2M_BITS (3) +/* TIM_OC2BE field */ +#define TIM_OC2BE (0x00000800u) +#define TIM_OC2BE_MASK (0x00000800u) +#define TIM_OC2BE_BIT (11) +#define TIM_OC2BE_BITS (1) +/* TIM_OC2FE field */ +#define TIM_OC2FE (0x00000400u) +#define TIM_OC2FE_MASK (0x00000400u) +#define TIM_OC2FE_BIT (10) +#define TIM_OC2FE_BITS (1) +/* TIM_CC2S field */ +#define TIM_CC2S (0x00000300u) +#define TIM_CC2S_MASK (0x00000300u) +#define TIM_CC2S_BIT (8) +#define TIM_CC2S_BITS (2) +/* TIM_OC1CE field */ +#define TIM_OC1CE (0x00000080u) +#define TIM_OC1CE_MASK (0x00000080u) +#define TIM_OC1CE_BIT (7) +#define TIM_OC1CE_BITS (1) +/* TIM_OC1M field */ +#define TIM_OC1M (0x00000070u) +#define TIM_OC1M_MASK (0x00000070u) +#define TIM_OC1M_BIT (4) +#define TIM_OC1M_BITS (3) +/* TIM_OC1PE field */ +#define TIM_OC1PE (0x00000008u) +#define TIM_OC1PE_MASK (0x00000008u) +#define TIM_OC1PE_BIT (3) +#define TIM_OC1PE_BITS (1) +/* TIM_OC1FE field */ +#define TIM_OC1FE (0x00000004u) +#define TIM_OC1FE_MASK (0x00000004u) +#define TIM_OC1FE_BIT (2) +#define TIM_OC1FE_BITS (1) +/* TIM_CC1S field */ +#define TIM_CC1S (0x00000003u) +#define TIM_CC1S_MASK (0x00000003u) +#define TIM_CC1S_BIT (0) +#define TIM_CC1S_BITS (2) + +#define TIM2_CCMR2 *((volatile uint32_t *)0x4000F01Cu) +#define TIM2_CCMR2_REG *((volatile uint32_t *)0x4000F01Cu) +#define TIM2_CCMR2_ADDR (0x4000F01Cu) +#define TIM2_CCMR2_RESET (0x00000000u) +/* TIM_IC4F field */ +#define TIM_IC4F (0x0000F000u) +#define TIM_IC4F_MASK (0x0000F000u) +#define TIM_IC4F_BIT (12) +#define TIM_IC4F_BITS (4) +/* TIM_IC4PSC field */ +#define TIM_IC4PSC (0x00000C00u) +#define TIM_IC4PSC_MASK (0x00000C00u) +#define TIM_IC4PSC_BIT (10) +#define TIM_IC4PSC_BITS (2) +/* TIM_IC3F field */ +#define TIM_IC3F (0x000000F0u) +#define TIM_IC3F_MASK (0x000000F0u) +#define TIM_IC3F_BIT (4) +#define TIM_IC3F_BITS (4) +/* TIM_IC3PSC field */ +#define TIM_IC3PSC (0x0000000Cu) +#define TIM_IC3PSC_MASK (0x0000000Cu) +#define TIM_IC3PSC_BIT (2) +#define TIM_IC3PSC_BITS (2) +/* TIM_OC4CE field */ +#define TIM_OC4CE (0x00008000u) +#define TIM_OC4CE_MASK (0x00008000u) +#define TIM_OC4CE_BIT (15) +#define TIM_OC4CE_BITS (1) +/* TIM_OC4M field */ +#define TIM_OC4M (0x00007000u) +#define TIM_OC4M_MASK (0x00007000u) +#define TIM_OC4M_BIT (12) +#define TIM_OC4M_BITS (3) +/* TIM_OC4BE field */ +#define TIM_OC4BE (0x00000800u) +#define TIM_OC4BE_MASK (0x00000800u) +#define TIM_OC4BE_BIT (11) +#define TIM_OC4BE_BITS (1) +/* TIM_OC4FE field */ +#define TIM_OC4FE (0x00000400u) +#define TIM_OC4FE_MASK (0x00000400u) +#define TIM_OC4FE_BIT (10) +#define TIM_OC4FE_BITS (1) +/* TIM_CC4S field */ +#define TIM_CC4S (0x00000300u) +#define TIM_CC4S_MASK (0x00000300u) +#define TIM_CC4S_BIT (8) +#define TIM_CC4S_BITS (2) +/* TIM_OC3CE field */ +#define TIM_OC3CE (0x00000080u) +#define TIM_OC3CE_MASK (0x00000080u) +#define TIM_OC3CE_BIT (7) +#define TIM_OC3CE_BITS (1) +/* TIM_OC3M field */ +#define TIM_OC3M (0x00000070u) +#define TIM_OC3M_MASK (0x00000070u) +#define TIM_OC3M_BIT (4) +#define TIM_OC3M_BITS (3) +/* TIM_OC3BE field */ +#define TIM_OC3BE (0x00000008u) +#define TIM_OC3BE_MASK (0x00000008u) +#define TIM_OC3BE_BIT (3) +#define TIM_OC3BE_BITS (1) +/* TIM_OC3FE field */ +#define TIM_OC3FE (0x00000004u) +#define TIM_OC3FE_MASK (0x00000004u) +#define TIM_OC3FE_BIT (2) +#define TIM_OC3FE_BITS (1) +/* TIM_CC3S field */ +#define TIM_CC3S (0x00000003u) +#define TIM_CC3S_MASK (0x00000003u) +#define TIM_CC3S_BIT (0) +#define TIM_CC3S_BITS (2) + +#define TIM2_CCER *((volatile uint32_t *)0x4000F020u) +#define TIM2_CCER_REG *((volatile uint32_t *)0x4000F020u) +#define TIM2_CCER_ADDR (0x4000F020u) +#define TIM2_CCER_RESET (0x00000000u) +/* TIM_CC4P field */ +#define TIM_CC4P (0x00002000u) +#define TIM_CC4P_MASK (0x00002000u) +#define TIM_CC4P_BIT (13) +#define TIM_CC4P_BITS (1) +/* TIM_CC4E field */ +#define TIM_CC4E (0x00001000u) +#define TIM_CC4E_MASK (0x00001000u) +#define TIM_CC4E_BIT (12) +#define TIM_CC4E_BITS (1) +/* TIM_CC3P field */ +#define TIM_CC3P (0x00000200u) +#define TIM_CC3P_MASK (0x00000200u) +#define TIM_CC3P_BIT (9) +#define TIM_CC3P_BITS (1) +/* TIM_CC3E field */ +#define TIM_CC3E (0x00000100u) +#define TIM_CC3E_MASK (0x00000100u) +#define TIM_CC3E_BIT (8) +#define TIM_CC3E_BITS (1) +/* TIM_CC2P field */ +#define TIM_CC2P (0x00000020u) +#define TIM_CC2P_MASK (0x00000020u) +#define TIM_CC2P_BIT (5) +#define TIM_CC2P_BITS (1) +/* TIM_CC2E field */ +#define TIM_CC2E (0x00000010u) +#define TIM_CC2E_MASK (0x00000010u) +#define TIM_CC2E_BIT (4) +#define TIM_CC2E_BITS (1) +/* TIM_CC1P field */ +#define TIM_CC1P (0x00000002u) +#define TIM_CC1P_MASK (0x00000002u) +#define TIM_CC1P_BIT (1) +#define TIM_CC1P_BITS (1) +/* TIM_CC1E field */ +#define TIM_CC1E (0x00000001u) +#define TIM_CC1E_MASK (0x00000001u) +#define TIM_CC1E_BIT (0) +#define TIM_CC1E_BITS (1) + +#define TIM2_CNT *((volatile uint32_t *)0x4000F024u) +#define TIM2_CNT_REG *((volatile uint32_t *)0x4000F024u) +#define TIM2_CNT_ADDR (0x4000F024u) +#define TIM2_CNT_RESET (0x00000000u) +/* TIM_CNT field */ +#define TIM_CNT (0x0000FFFFu) +#define TIM_CNT_MASK (0x0000FFFFu) +#define TIM_CNT_BIT (0) +#define TIM_CNT_BITS (16) + +#define TIM2_PSC *((volatile uint32_t *)0x4000F028u) +#define TIM2_PSC_REG *((volatile uint32_t *)0x4000F028u) +#define TIM2_PSC_ADDR (0x4000F028u) +#define TIM2_PSC_RESET (0x00000000u) +/* TIM_PSC field */ +#define TIM_PSC (0x0000000Fu) +#define TIM_PSC_MASK (0x0000000Fu) +#define TIM_PSC_BIT (0) +#define TIM_PSC_BITS (4) + +#define TIM2_ARR *((volatile uint32_t *)0x4000F02Cu) +#define TIM2_ARR_REG *((volatile uint32_t *)0x4000F02Cu) +#define TIM2_ARR_ADDR (0x4000F02Cu) +#define TIM2_ARR_RESET (0x0000FFFFu) +/* TIM_ARR field */ +#define TIM_ARR (0x0000FFFFu) +#define TIM_ARR_MASK (0x0000FFFFu) +#define TIM_ARR_BIT (0) +#define TIM_ARR_BITS (16) + +#define TIM2_CCR1 *((volatile uint32_t *)0x4000F034u) +#define TIM2_CCR1_REG *((volatile uint32_t *)0x4000F034u) +#define TIM2_CCR1_ADDR (0x4000F034u) +#define TIM2_CCR1_RESET (0x00000000u) +/* TIM_CCR field */ +#define TIM_CCR (0x0000FFFFu) +#define TIM_CCR_MASK (0x0000FFFFu) +#define TIM_CCR_BIT (0) +#define TIM_CCR_BITS (16) + +#define TIM2_CCR2 *((volatile uint32_t *)0x4000F038u) +#define TIM2_CCR2_REG *((volatile uint32_t *)0x4000F038u) +#define TIM2_CCR2_ADDR (0x4000F038u) +#define TIM2_CCR2_RESET (0x00000000u) +/* TIM_CCR field */ +#define TIM_CCR (0x0000FFFFu) +#define TIM_CCR_MASK (0x0000FFFFu) +#define TIM_CCR_BIT (0) +#define TIM_CCR_BITS (16) + +#define TIM2_CCR3 *((volatile uint32_t *)0x4000F03Cu) +#define TIM2_CCR3_REG *((volatile uint32_t *)0x4000F03Cu) +#define TIM2_CCR3_ADDR (0x4000F03Cu) +#define TIM2_CCR3_RESET (0x00000000u) +/* TIM_CCR field */ +#define TIM_CCR (0x0000FFFFu) +#define TIM_CCR_MASK (0x0000FFFFu) +#define TIM_CCR_BIT (0) +#define TIM_CCR_BITS (16) + +#define TIM2_CCR4 *((volatile uint32_t *)0x4000F040u) +#define TIM2_CCR4_REG *((volatile uint32_t *)0x4000F040u) +#define TIM2_CCR4_ADDR (0x4000F040u) +#define TIM2_CCR4_RESET (0x00000000u) +/* TIM_CCR field */ +#define TIM_CCR (0x0000FFFFu) +#define TIM_CCR_MASK (0x0000FFFFu) +#define TIM_CCR_BIT (0) +#define TIM_CCR_BITS (16) + +#define TIM2_OR *((volatile uint32_t *)0x4000F050u) +#define TIM2_OR_REG *((volatile uint32_t *)0x4000F050u) +#define TIM2_OR_ADDR (0x4000F050u) +#define TIM2_OR_RESET (0x00000000u) +/* TIM_REMAPC4 field */ +#define TIM_REMAPC4 (0x00000080u) +#define TIM_REMAPC4_MASK (0x00000080u) +#define TIM_REMAPC4_BIT (7) +#define TIM_REMAPC4_BITS (1) +/* TIM_REMAPC3 field */ +#define TIM_REMAPC3 (0x00000040u) +#define TIM_REMAPC3_MASK (0x00000040u) +#define TIM_REMAPC3_BIT (6) +#define TIM_REMAPC3_BITS (1) +/* TIM_REMAPC2 field */ +#define TIM_REMAPC2 (0x00000020u) +#define TIM_REMAPC2_MASK (0x00000020u) +#define TIM_REMAPC2_BIT (5) +#define TIM_REMAPC2_BITS (1) +/* TIM_REMAPC1 field */ +#define TIM_REMAPC1 (0x00000010u) +#define TIM_REMAPC1_MASK (0x00000010u) +#define TIM_REMAPC1_BIT (4) +#define TIM_REMAPC1_BITS (1) +/* TIM_ORRSVD field */ +#define TIM_ORRSVD (0x00000008u) +#define TIM_ORRSVD_MASK (0x00000008u) +#define TIM_ORRSVD_BIT (3) +#define TIM_ORRSVD_BITS (1) +/* TIM_CLKMSKEN field */ +#define TIM_CLKMSKEN (0x00000004u) +#define TIM_CLKMSKEN_MASK (0x00000004u) +#define TIM_CLKMSKEN_BIT (2) +#define TIM_CLKMSKEN_BITS (1) +/* TIM1_EXTRIGSEL field */ +#define TIM1_EXTRIGSEL (0x00000003u) +#define TIM1_EXTRIGSEL_MASK (0x00000003u) +#define TIM1_EXTRIGSEL_BIT (0) +#define TIM1_EXTRIGSEL_BITS (2) + +/* EXT_RAM block */ +#define DATA_EXT_RAM_BASE (0x60000000u) +#define DATA_EXT_RAM_END (0x9FFFFFFFu) +#define DATA_EXT_RAM_SIZE (DATA_EXT_RAM_END - DATA_EXT_RAM_BASE + 1) + +/* EXT_DEVICE block */ +#define DATA_EXT_DEVICE_BASE (0xA0000000u) +#define DATA_EXT_DEVICE_END (0xDFFFFFFFu) +#define DATA_EXT_DEVICE_SIZE (DATA_EXT_DEVICE_END - DATA_EXT_DEVICE_BASE + 1) + +/* ITM block */ +#define DATA_ITM_BASE (0xE0000000u) +#define DATA_ITM_END (0xE0000FFFu) +#define DATA_ITM_SIZE (DATA_ITM_END - DATA_ITM_BASE + 1) + +#define ITM_SP0 *((volatile uint32_t *)0xE0000000u) +#define ITM_SP0_REG *((volatile uint32_t *)0xE0000000u) +#define ITM_SP0_ADDR (0xE0000000u) +#define ITM_SP0_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP0_FIFOREADY (0x00000001u) +#define ITM_SP0_FIFOREADY_MASK (0x00000001u) +#define ITM_SP0_FIFOREADY_BIT (0) +#define ITM_SP0_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP0_STIMULUS (0xFFFFFFFFu) +#define ITM_SP0_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP0_STIMULUS_BIT (0) +#define ITM_SP0_STIMULUS_BITS (32) + +#define ITM_SP1 *((volatile uint32_t *)0xE0000004u) +#define ITM_SP1_REG *((volatile uint32_t *)0xE0000004u) +#define ITM_SP1_ADDR (0xE0000004u) +#define ITM_SP1_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP1_FIFOREADY (0x00000001u) +#define ITM_SP1_FIFOREADY_MASK (0x00000001u) +#define ITM_SP1_FIFOREADY_BIT (0) +#define ITM_SP1_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP1_STIMULUS (0xFFFFFFFFu) +#define ITM_SP1_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP1_STIMULUS_BIT (0) +#define ITM_SP1_STIMULUS_BITS (32) + +#define ITM_SP2 *((volatile uint32_t *)0xE0000008u) +#define ITM_SP2_REG *((volatile uint32_t *)0xE0000008u) +#define ITM_SP2_ADDR (0xE0000008u) +#define ITM_SP2_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP2_FIFOREADY (0x00000001u) +#define ITM_SP2_FIFOREADY_MASK (0x00000001u) +#define ITM_SP2_FIFOREADY_BIT (0) +#define ITM_SP2_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP2_STIMULUS (0xFFFFFFFFu) +#define ITM_SP2_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP2_STIMULUS_BIT (0) +#define ITM_SP2_STIMULUS_BITS (32) + +#define ITM_SP3 *((volatile uint32_t *)0xE000000Cu) +#define ITM_SP3_REG *((volatile uint32_t *)0xE000000Cu) +#define ITM_SP3_ADDR (0xE000000Cu) +#define ITM_SP3_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP3_FIFOREADY (0x00000001u) +#define ITM_SP3_FIFOREADY_MASK (0x00000001u) +#define ITM_SP3_FIFOREADY_BIT (0) +#define ITM_SP3_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP3_STIMULUS (0xFFFFFFFFu) +#define ITM_SP3_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP3_STIMULUS_BIT (0) +#define ITM_SP3_STIMULUS_BITS (32) + +#define ITM_SP4 *((volatile uint32_t *)0xE0000010u) +#define ITM_SP4_REG *((volatile uint32_t *)0xE0000010u) +#define ITM_SP4_ADDR (0xE0000010u) +#define ITM_SP4_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP4_FIFOREADY (0x00000001u) +#define ITM_SP4_FIFOREADY_MASK (0x00000001u) +#define ITM_SP4_FIFOREADY_BIT (0) +#define ITM_SP4_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP4_STIMULUS (0xFFFFFFFFu) +#define ITM_SP4_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP4_STIMULUS_BIT (0) +#define ITM_SP4_STIMULUS_BITS (32) + +#define ITM_SP5 *((volatile uint32_t *)0xE0000014u) +#define ITM_SP5_REG *((volatile uint32_t *)0xE0000014u) +#define ITM_SP5_ADDR (0xE0000014u) +#define ITM_SP5_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP5_FIFOREADY (0x00000001u) +#define ITM_SP5_FIFOREADY_MASK (0x00000001u) +#define ITM_SP5_FIFOREADY_BIT (0) +#define ITM_SP5_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP5_STIMULUS (0xFFFFFFFFu) +#define ITM_SP5_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP5_STIMULUS_BIT (0) +#define ITM_SP5_STIMULUS_BITS (32) + +#define ITM_SP6 *((volatile uint32_t *)0xE0000018u) +#define ITM_SP6_REG *((volatile uint32_t *)0xE0000018u) +#define ITM_SP6_ADDR (0xE0000018u) +#define ITM_SP6_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP6_FIFOREADY (0x00000001u) +#define ITM_SP6_FIFOREADY_MASK (0x00000001u) +#define ITM_SP6_FIFOREADY_BIT (0) +#define ITM_SP6_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP6_STIMULUS (0xFFFFFFFFu) +#define ITM_SP6_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP6_STIMULUS_BIT (0) +#define ITM_SP6_STIMULUS_BITS (32) + +#define ITM_SP7 *((volatile uint32_t *)0xE000001Cu) +#define ITM_SP7_REG *((volatile uint32_t *)0xE000001Cu) +#define ITM_SP7_ADDR (0xE000001Cu) +#define ITM_SP7_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP7_FIFOREADY (0x00000001u) +#define ITM_SP7_FIFOREADY_MASK (0x00000001u) +#define ITM_SP7_FIFOREADY_BIT (0) +#define ITM_SP7_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP7_STIMULUS (0xFFFFFFFFu) +#define ITM_SP7_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP7_STIMULUS_BIT (0) +#define ITM_SP7_STIMULUS_BITS (32) + +#define ITM_SP8 *((volatile uint32_t *)0xE0000020u) +#define ITM_SP8_REG *((volatile uint32_t *)0xE0000020u) +#define ITM_SP8_ADDR (0xE0000020u) +#define ITM_SP8_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP8_FIFOREADY (0x00000001u) +#define ITM_SP8_FIFOREADY_MASK (0x00000001u) +#define ITM_SP8_FIFOREADY_BIT (0) +#define ITM_SP8_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP8_STIMULUS (0xFFFFFFFFu) +#define ITM_SP8_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP8_STIMULUS_BIT (0) +#define ITM_SP8_STIMULUS_BITS (32) + +#define ITM_SP9 *((volatile uint32_t *)0xE0000024u) +#define ITM_SP9_REG *((volatile uint32_t *)0xE0000024u) +#define ITM_SP9_ADDR (0xE0000024u) +#define ITM_SP9_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP9_FIFOREADY (0x00000001u) +#define ITM_SP9_FIFOREADY_MASK (0x00000001u) +#define ITM_SP9_FIFOREADY_BIT (0) +#define ITM_SP9_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP9_STIMULUS (0xFFFFFFFFu) +#define ITM_SP9_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP9_STIMULUS_BIT (0) +#define ITM_SP9_STIMULUS_BITS (32) + +#define ITM_SP10 *((volatile uint32_t *)0xE0000028u) +#define ITM_SP10_REG *((volatile uint32_t *)0xE0000028u) +#define ITM_SP10_ADDR (0xE0000028u) +#define ITM_SP10_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP10_FIFOREADY (0x00000001u) +#define ITM_SP10_FIFOREADY_MASK (0x00000001u) +#define ITM_SP10_FIFOREADY_BIT (0) +#define ITM_SP10_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP10_STIMULUS (0xFFFFFFFFu) +#define ITM_SP10_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP10_STIMULUS_BIT (0) +#define ITM_SP10_STIMULUS_BITS (32) + +#define ITM_SP11 *((volatile uint32_t *)0xE000002Cu) +#define ITM_SP11_REG *((volatile uint32_t *)0xE000002Cu) +#define ITM_SP11_ADDR (0xE000002Cu) +#define ITM_SP11_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP11_FIFOREADY (0x00000001u) +#define ITM_SP11_FIFOREADY_MASK (0x00000001u) +#define ITM_SP11_FIFOREADY_BIT (0) +#define ITM_SP11_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP11_STIMULUS (0xFFFFFFFFu) +#define ITM_SP11_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP11_STIMULUS_BIT (0) +#define ITM_SP11_STIMULUS_BITS (32) + +#define ITM_SP12 *((volatile uint32_t *)0xE0000030u) +#define ITM_SP12_REG *((volatile uint32_t *)0xE0000030u) +#define ITM_SP12_ADDR (0xE0000030u) +#define ITM_SP12_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP12_FIFOREADY (0x00000001u) +#define ITM_SP12_FIFOREADY_MASK (0x00000001u) +#define ITM_SP12_FIFOREADY_BIT (0) +#define ITM_SP12_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP12_STIMULUS (0xFFFFFFFFu) +#define ITM_SP12_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP12_STIMULUS_BIT (0) +#define ITM_SP12_STIMULUS_BITS (32) + +#define ITM_SP13 *((volatile uint32_t *)0xE0000034u) +#define ITM_SP13_REG *((volatile uint32_t *)0xE0000034u) +#define ITM_SP13_ADDR (0xE0000034u) +#define ITM_SP13_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP13_FIFOREADY (0x00000001u) +#define ITM_SP13_FIFOREADY_MASK (0x00000001u) +#define ITM_SP13_FIFOREADY_BIT (0) +#define ITM_SP13_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP13_STIMULUS (0xFFFFFFFFu) +#define ITM_SP13_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP13_STIMULUS_BIT (0) +#define ITM_SP13_STIMULUS_BITS (32) + +#define ITM_SP14 *((volatile uint32_t *)0xE0000038u) +#define ITM_SP14_REG *((volatile uint32_t *)0xE0000038u) +#define ITM_SP14_ADDR (0xE0000038u) +#define ITM_SP14_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP14_FIFOREADY (0x00000001u) +#define ITM_SP14_FIFOREADY_MASK (0x00000001u) +#define ITM_SP14_FIFOREADY_BIT (0) +#define ITM_SP14_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP14_STIMULUS (0xFFFFFFFFu) +#define ITM_SP14_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP14_STIMULUS_BIT (0) +#define ITM_SP14_STIMULUS_BITS (32) + +#define ITM_SP15 *((volatile uint32_t *)0xE000003Cu) +#define ITM_SP15_REG *((volatile uint32_t *)0xE000003Cu) +#define ITM_SP15_ADDR (0xE000003Cu) +#define ITM_SP15_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP15_FIFOREADY (0x00000001u) +#define ITM_SP15_FIFOREADY_MASK (0x00000001u) +#define ITM_SP15_FIFOREADY_BIT (0) +#define ITM_SP15_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP15_STIMULUS (0xFFFFFFFFu) +#define ITM_SP15_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP15_STIMULUS_BIT (0) +#define ITM_SP15_STIMULUS_BITS (32) + +#define ITM_SP16 *((volatile uint32_t *)0xE0000040u) +#define ITM_SP16_REG *((volatile uint32_t *)0xE0000040u) +#define ITM_SP16_ADDR (0xE0000040u) +#define ITM_SP16_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP16_FIFOREADY (0x00000001u) +#define ITM_SP16_FIFOREADY_MASK (0x00000001u) +#define ITM_SP16_FIFOREADY_BIT (0) +#define ITM_SP16_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP16_STIMULUS (0xFFFFFFFFu) +#define ITM_SP16_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP16_STIMULUS_BIT (0) +#define ITM_SP16_STIMULUS_BITS (32) + +#define ITM_SP17 *((volatile uint32_t *)0xE0000044u) +#define ITM_SP17_REG *((volatile uint32_t *)0xE0000044u) +#define ITM_SP17_ADDR (0xE0000044u) +#define ITM_SP17_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP17_FIFOREADY (0x00000001u) +#define ITM_SP17_FIFOREADY_MASK (0x00000001u) +#define ITM_SP17_FIFOREADY_BIT (0) +#define ITM_SP17_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP17_STIMULUS (0xFFFFFFFFu) +#define ITM_SP17_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP17_STIMULUS_BIT (0) +#define ITM_SP17_STIMULUS_BITS (32) + +#define ITM_SP18 *((volatile uint32_t *)0xE0000048u) +#define ITM_SP18_REG *((volatile uint32_t *)0xE0000048u) +#define ITM_SP18_ADDR (0xE0000048u) +#define ITM_SP18_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP18_FIFOREADY (0x00000001u) +#define ITM_SP18_FIFOREADY_MASK (0x00000001u) +#define ITM_SP18_FIFOREADY_BIT (0) +#define ITM_SP18_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP18_STIMULUS (0xFFFFFFFFu) +#define ITM_SP18_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP18_STIMULUS_BIT (0) +#define ITM_SP18_STIMULUS_BITS (32) + +#define ITM_SP19 *((volatile uint32_t *)0xE000004Cu) +#define ITM_SP19_REG *((volatile uint32_t *)0xE000004Cu) +#define ITM_SP19_ADDR (0xE000004Cu) +#define ITM_SP19_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP19_FIFOREADY (0x00000001u) +#define ITM_SP19_FIFOREADY_MASK (0x00000001u) +#define ITM_SP19_FIFOREADY_BIT (0) +#define ITM_SP19_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP19_STIMULUS (0xFFFFFFFFu) +#define ITM_SP19_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP19_STIMULUS_BIT (0) +#define ITM_SP19_STIMULUS_BITS (32) + +#define ITM_SP20 *((volatile uint32_t *)0xE0000050u) +#define ITM_SP20_REG *((volatile uint32_t *)0xE0000050u) +#define ITM_SP20_ADDR (0xE0000050u) +#define ITM_SP20_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP20_FIFOREADY (0x00000001u) +#define ITM_SP20_FIFOREADY_MASK (0x00000001u) +#define ITM_SP20_FIFOREADY_BIT (0) +#define ITM_SP20_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP20_STIMULUS (0xFFFFFFFFu) +#define ITM_SP20_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP20_STIMULUS_BIT (0) +#define ITM_SP20_STIMULUS_BITS (32) + +#define ITM_SP21 *((volatile uint32_t *)0xE0000054u) +#define ITM_SP21_REG *((volatile uint32_t *)0xE0000054u) +#define ITM_SP21_ADDR (0xE0000054u) +#define ITM_SP21_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP21_FIFOREADY (0x00000001u) +#define ITM_SP21_FIFOREADY_MASK (0x00000001u) +#define ITM_SP21_FIFOREADY_BIT (0) +#define ITM_SP21_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP21_STIMULUS (0xFFFFFFFFu) +#define ITM_SP21_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP21_STIMULUS_BIT (0) +#define ITM_SP21_STIMULUS_BITS (32) + +#define ITM_SP22 *((volatile uint32_t *)0xE0000058u) +#define ITM_SP22_REG *((volatile uint32_t *)0xE0000058u) +#define ITM_SP22_ADDR (0xE0000058u) +#define ITM_SP22_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP22_FIFOREADY (0x00000001u) +#define ITM_SP22_FIFOREADY_MASK (0x00000001u) +#define ITM_SP22_FIFOREADY_BIT (0) +#define ITM_SP22_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP22_STIMULUS (0xFFFFFFFFu) +#define ITM_SP22_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP22_STIMULUS_BIT (0) +#define ITM_SP22_STIMULUS_BITS (32) + +#define ITM_SP23 *((volatile uint32_t *)0xE000005Cu) +#define ITM_SP23_REG *((volatile uint32_t *)0xE000005Cu) +#define ITM_SP23_ADDR (0xE000005Cu) +#define ITM_SP23_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP23_FIFOREADY (0x00000001u) +#define ITM_SP23_FIFOREADY_MASK (0x00000001u) +#define ITM_SP23_FIFOREADY_BIT (0) +#define ITM_SP23_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP23_STIMULUS (0xFFFFFFFFu) +#define ITM_SP23_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP23_STIMULUS_BIT (0) +#define ITM_SP23_STIMULUS_BITS (32) + +#define ITM_SP24 *((volatile uint32_t *)0xE0000060u) +#define ITM_SP24_REG *((volatile uint32_t *)0xE0000060u) +#define ITM_SP24_ADDR (0xE0000060u) +#define ITM_SP24_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP24_FIFOREADY (0x00000001u) +#define ITM_SP24_FIFOREADY_MASK (0x00000001u) +#define ITM_SP24_FIFOREADY_BIT (0) +#define ITM_SP24_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP24_STIMULUS (0xFFFFFFFFu) +#define ITM_SP24_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP24_STIMULUS_BIT (0) +#define ITM_SP24_STIMULUS_BITS (32) + +#define ITM_SP25 *((volatile uint32_t *)0xE0000064u) +#define ITM_SP25_REG *((volatile uint32_t *)0xE0000064u) +#define ITM_SP25_ADDR (0xE0000064u) +#define ITM_SP25_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP25_FIFOREADY (0x00000001u) +#define ITM_SP25_FIFOREADY_MASK (0x00000001u) +#define ITM_SP25_FIFOREADY_BIT (0) +#define ITM_SP25_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP25_STIMULUS (0xFFFFFFFFu) +#define ITM_SP25_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP25_STIMULUS_BIT (0) +#define ITM_SP25_STIMULUS_BITS (32) + +#define ITM_SP26 *((volatile uint32_t *)0xE0000068u) +#define ITM_SP26_REG *((volatile uint32_t *)0xE0000068u) +#define ITM_SP26_ADDR (0xE0000068u) +#define ITM_SP26_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP26_FIFOREADY (0x00000001u) +#define ITM_SP26_FIFOREADY_MASK (0x00000001u) +#define ITM_SP26_FIFOREADY_BIT (0) +#define ITM_SP26_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP26_STIMULUS (0xFFFFFFFFu) +#define ITM_SP26_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP26_STIMULUS_BIT (0) +#define ITM_SP26_STIMULUS_BITS (32) + +#define ITM_SP27 *((volatile uint32_t *)0xE000006Cu) +#define ITM_SP27_REG *((volatile uint32_t *)0xE000006Cu) +#define ITM_SP27_ADDR (0xE000006Cu) +#define ITM_SP27_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP27_FIFOREADY (0x00000001u) +#define ITM_SP27_FIFOREADY_MASK (0x00000001u) +#define ITM_SP27_FIFOREADY_BIT (0) +#define ITM_SP27_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP27_STIMULUS (0xFFFFFFFFu) +#define ITM_SP27_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP27_STIMULUS_BIT (0) +#define ITM_SP27_STIMULUS_BITS (32) + +#define ITM_SP28 *((volatile uint32_t *)0xE0000070u) +#define ITM_SP28_REG *((volatile uint32_t *)0xE0000070u) +#define ITM_SP28_ADDR (0xE0000070u) +#define ITM_SP28_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP28_FIFOREADY (0x00000001u) +#define ITM_SP28_FIFOREADY_MASK (0x00000001u) +#define ITM_SP28_FIFOREADY_BIT (0) +#define ITM_SP28_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP28_STIMULUS (0xFFFFFFFFu) +#define ITM_SP28_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP28_STIMULUS_BIT (0) +#define ITM_SP28_STIMULUS_BITS (32) + +#define ITM_SP29 *((volatile uint32_t *)0xE0000074u) +#define ITM_SP29_REG *((volatile uint32_t *)0xE0000074u) +#define ITM_SP29_ADDR (0xE0000074u) +#define ITM_SP29_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP29_FIFOREADY (0x00000001u) +#define ITM_SP29_FIFOREADY_MASK (0x00000001u) +#define ITM_SP29_FIFOREADY_BIT (0) +#define ITM_SP29_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP29_STIMULUS (0xFFFFFFFFu) +#define ITM_SP29_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP29_STIMULUS_BIT (0) +#define ITM_SP29_STIMULUS_BITS (32) + +#define ITM_SP30 *((volatile uint32_t *)0xE0000078u) +#define ITM_SP30_REG *((volatile uint32_t *)0xE0000078u) +#define ITM_SP30_ADDR (0xE0000078u) +#define ITM_SP30_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP30_FIFOREADY (0x00000001u) +#define ITM_SP30_FIFOREADY_MASK (0x00000001u) +#define ITM_SP30_FIFOREADY_BIT (0) +#define ITM_SP30_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP30_STIMULUS (0xFFFFFFFFu) +#define ITM_SP30_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP30_STIMULUS_BIT (0) +#define ITM_SP30_STIMULUS_BITS (32) + +#define ITM_SP31 *((volatile uint32_t *)0xE000007Cu) +#define ITM_SP31_REG *((volatile uint32_t *)0xE000007Cu) +#define ITM_SP31_ADDR (0xE000007Cu) +#define ITM_SP31_RESET (0x00000000u) +/* FIFOREADY field */ +#define ITM_SP31_FIFOREADY (0x00000001u) +#define ITM_SP31_FIFOREADY_MASK (0x00000001u) +#define ITM_SP31_FIFOREADY_BIT (0) +#define ITM_SP31_FIFOREADY_BITS (1) +/* STIMULUS field */ +#define ITM_SP31_STIMULUS (0xFFFFFFFFu) +#define ITM_SP31_STIMULUS_MASK (0xFFFFFFFFu) +#define ITM_SP31_STIMULUS_BIT (0) +#define ITM_SP31_STIMULUS_BITS (32) + +#define ITM_TER *((volatile uint32_t *)0xE0000E00u) +#define ITM_TER_REG *((volatile uint32_t *)0xE0000E00u) +#define ITM_TER_ADDR (0xE0000E00u) +#define ITM_TER_RESET (0x00000000u) +/* STIMENA field */ +#define ITM_TER_STIMENA (0xFFFFFFFFu) +#define ITM_TER_STIMENA_MASK (0xFFFFFFFFu) +#define ITM_TER_STIMENA_BIT (0) +#define ITM_TER_STIMENA_BITS (32) + +#define ITM_TPR *((volatile uint32_t *)0xE0000E40u) +#define ITM_TPR_REG *((volatile uint32_t *)0xE0000E40u) +#define ITM_TPR_ADDR (0xE0000E40u) +#define ITM_TPR_RESET (0x00000000u) +/* PRIVMASK field */ +#define ITM_TPR_PRIVMASK (0x0000000Fu) +#define ITM_TPR_PRIVMASK_MASK (0x0000000Fu) +#define ITM_TPR_PRIVMASK_BIT (0) +#define ITM_TPR_PRIVMASK_BITS (4) + +#define ITM_TCR *((volatile uint32_t *)0xE0000E80u) +#define ITM_TCR_REG *((volatile uint32_t *)0xE0000E80u) +#define ITM_TCR_ADDR (0xE0000E80u) +#define ITM_TCR_RESET (0x00000000u) +/* BUSY field */ +#define ITM_TCR_BUSY (0x00800000u) +#define ITM_TCR_BUSY_MASK (0x00800000u) +#define ITM_TCR_BUSY_BIT (23) +#define ITM_TCR_BUSY_BITS (1) +/* ATBID field */ +#define ITM_TCR_ATBID (0x007F0000u) +#define ITM_TCR_ATBID_MASK (0x007F0000u) +#define ITM_TCR_ATBID_BIT (16) +#define ITM_TCR_ATBID_BITS (7) +/* TSPRESCALE field */ +#define ITM_TCR_TSPRESCALE (0x00000300u) +#define ITM_TCR_TSPRESCALE_MASK (0x00000300u) +#define ITM_TCR_TSPRESCALE_BIT (8) +#define ITM_TCR_TSPRESCALE_BITS (2) +/* SWOENA field */ +#define ITM_TCR_SWOENA (0x00000010u) +#define ITM_TCR_SWOENA_MASK (0x00000010u) +#define ITM_TCR_SWOENA_BIT (4) +#define ITM_TCR_SWOENA_BITS (1) +/* DWTENA field */ +#define ITM_TCR_DWTENA (0x00000008u) +#define ITM_TCR_DWTENA_MASK (0x00000008u) +#define ITM_TCR_DWTENA_BIT (3) +#define ITM_TCR_DWTENA_BITS (1) +/* SYNCENA field */ +#define ITM_TCR_SYNCENA (0x00000004u) +#define ITM_TCR_SYNCENA_MASK (0x00000004u) +#define ITM_TCR_SYNCENA_BIT (2) +#define ITM_TCR_SYNCENA_BITS (1) +/* TSENA field */ +#define ITM_TCR_TSENA (0x00000002u) +#define ITM_TCR_TSENA_MASK (0x00000002u) +#define ITM_TCR_TSENA_BIT (1) +#define ITM_TCR_TSENA_BITS (1) +/* ITMEN field */ +#define ITM_TCR_ITMEN (0x00000001u) +#define ITM_TCR_ITMEN_MASK (0x00000001u) +#define ITM_TCR_ITMEN_BIT (0) +#define ITM_TCR_ITMEN_BITS (1) + +#define ITM_IW *((volatile uint32_t *)0xE0000EF8u) +#define ITM_IW_REG *((volatile uint32_t *)0xE0000EF8u) +#define ITM_IW_ADDR (0xE0000EF8u) +#define ITM_IW_RESET (0x00000000u) +/* ATVALIDM field */ +#define ITM_IW_ATVALIDM (0x00000001u) +#define ITM_IW_ATVALIDM_MASK (0x00000001u) +#define ITM_IW_ATVALIDM_BIT (0) +#define ITM_IW_ATVALIDM_BITS (1) + +#define ITM_IR *((volatile uint32_t *)0xE0000EFCu) +#define ITM_IR_REG *((volatile uint32_t *)0xE0000EFCu) +#define ITM_IR_ADDR (0xE0000EFCu) +#define ITM_IR_RESET (0x00000000u) +/* ATREADYM field */ +#define ITM_IR_ATREADYM (0x00000001u) +#define ITM_IR_ATREADYM_MASK (0x00000001u) +#define ITM_IR_ATREADYM_BIT (0) +#define ITM_IR_ATREADYM_BITS (1) + +#define ITM_IMC *((volatile uint32_t *)0xE0000F00u) +#define ITM_IMC_REG *((volatile uint32_t *)0xE0000F00u) +#define ITM_IMC_ADDR (0xE0000F00u) +#define ITM_IMC_RESET (0x00000000u) +/* INTEGRATION field */ +#define ITM_IMC_INTEGRATION (0x00000001u) +#define ITM_IMC_INTEGRATION_MASK (0x00000001u) +#define ITM_IMC_INTEGRATION_BIT (0) +#define ITM_IMC_INTEGRATION_BITS (1) + +#define ITM_LA *((volatile uint32_t *)0xE0000FB0u) +#define ITM_LA_REG *((volatile uint32_t *)0xE0000FB0u) +#define ITM_LA_ADDR (0xE0000FB0u) +#define ITM_LA_RESET (0x00000000u) +/* LOCKACC field */ +#define ITM_LA_LOCKACC (0xFFFFFFFFu) +#define ITM_LA_LOCKACC_MASK (0xFFFFFFFFu) +#define ITM_LA_LOCKACC_BIT (0) +#define ITM_LA_LOCKACC_BITS (32) + +#define ITM_LS *((volatile uint32_t *)0xE0000FB4u) +#define ITM_LS_REG *((volatile uint32_t *)0xE0000FB4u) +#define ITM_LS_ADDR (0xE0000FB4u) +#define ITM_LS_RESET (0x00000000u) +/* BYTEACC field */ +#define ITM_LS_BYTEACC (0x00000004u) +#define ITM_LS_BYTEACC_MASK (0x00000004u) +#define ITM_LS_BYTEACC_BIT (2) +#define ITM_LS_BYTEACC_BITS (1) +/* ACCESS field */ +#define ITM_LS_ACCESS (0x00000002u) +#define ITM_LS_ACCESS_MASK (0x00000002u) +#define ITM_LS_ACCESS_BIT (1) +#define ITM_LS_ACCESS_BITS (1) +/* PRESENT field */ +#define ITM_LS_PRESENT (0x00000001u) +#define ITM_LS_PRESENT_MASK (0x00000001u) +#define ITM_LS_PRESENT_BIT (0) +#define ITM_LS_PRESENT_BITS (1) + +#define ITM_PERIPHID4 *((volatile uint32_t *)0xE0000FD0u) +#define ITM_PERIPHID4_REG *((volatile uint32_t *)0xE0000FD0u) +#define ITM_PERIPHID4_ADDR (0xE0000FD0u) +#define ITM_PERIPHID4_RESET (0x00000004u) +/* PERIPHID field */ +#define ITM_PERIPHID4_PERIPHID (0xFFFFFFFFu) +#define ITM_PERIPHID4_PERIPHID_MASK (0xFFFFFFFFu) +#define ITM_PERIPHID4_PERIPHID_BIT (0) +#define ITM_PERIPHID4_PERIPHID_BITS (32) + +#define ITM_PERIPHID5 *((volatile uint32_t *)0xE0000FD4u) +#define ITM_PERIPHID5_REG *((volatile uint32_t *)0xE0000FD4u) +#define ITM_PERIPHID5_ADDR (0xE0000FD4u) +#define ITM_PERIPHID5_RESET (0x00000000u) +/* PERIPHID field */ +#define ITM_PERIPHID5_PERIPHID (0xFFFFFFFFu) +#define ITM_PERIPHID5_PERIPHID_MASK (0xFFFFFFFFu) +#define ITM_PERIPHID5_PERIPHID_BIT (0) +#define ITM_PERIPHID5_PERIPHID_BITS (32) + +#define ITM_PERIPHID6 *((volatile uint32_t *)0xE0000FD8u) +#define ITM_PERIPHID6_REG *((volatile uint32_t *)0xE0000FD8u) +#define ITM_PERIPHID6_ADDR (0xE0000FD8u) +#define ITM_PERIPHID6_RESET (0x00000000u) +/* PERIPHID field */ +#define ITM_PERIPHID6_PERIPHID (0xFFFFFFFFu) +#define ITM_PERIPHID6_PERIPHID_MASK (0xFFFFFFFFu) +#define ITM_PERIPHID6_PERIPHID_BIT (0) +#define ITM_PERIPHID6_PERIPHID_BITS (32) + +#define ITM_PERIPHID7 *((volatile uint32_t *)0xE0000FDCu) +#define ITM_PERIPHID7_REG *((volatile uint32_t *)0xE0000FDCu) +#define ITM_PERIPHID7_ADDR (0xE0000FDCu) +#define ITM_PERIPHID7_RESET (0x00000000u) +/* PERIPHID field */ +#define ITM_PERIPHID7_PERIPHID (0xFFFFFFFFu) +#define ITM_PERIPHID7_PERIPHID_MASK (0xFFFFFFFFu) +#define ITM_PERIPHID7_PERIPHID_BIT (0) +#define ITM_PERIPHID7_PERIPHID_BITS (32) + +#define ITM_PERIPHID0 *((volatile uint32_t *)0xE0000FE0u) +#define ITM_PERIPHID0_REG *((volatile uint32_t *)0xE0000FE0u) +#define ITM_PERIPHID0_ADDR (0xE0000FE0u) +#define ITM_PERIPHID0_RESET (0x00000001u) +/* PERIPHID field */ +#define ITM_PERIPHID0_PERIPHID (0xFFFFFFFFu) +#define ITM_PERIPHID0_PERIPHID_MASK (0xFFFFFFFFu) +#define ITM_PERIPHID0_PERIPHID_BIT (0) +#define ITM_PERIPHID0_PERIPHID_BITS (32) + +#define ITM_PERIPHID1 *((volatile uint32_t *)0xE0000FE4u) +#define ITM_PERIPHID1_REG *((volatile uint32_t *)0xE0000FE4u) +#define ITM_PERIPHID1_ADDR (0xE0000FE4u) +#define ITM_PERIPHID1_RESET (0x000000B0u) +/* PERIPHID field */ +#define ITM_PERIPHID1_PERIPHID (0xFFFFFFFFu) +#define ITM_PERIPHID1_PERIPHID_MASK (0xFFFFFFFFu) +#define ITM_PERIPHID1_PERIPHID_BIT (0) +#define ITM_PERIPHID1_PERIPHID_BITS (32) + +#define ITM_PERIPHID2 *((volatile uint32_t *)0xE0000FE8u) +#define ITM_PERIPHID2_REG *((volatile uint32_t *)0xE0000FE8u) +#define ITM_PERIPHID2_ADDR (0xE0000FE8u) +#define ITM_PERIPHID2_RESET (0x0000001Bu) +/* PERIPHID field */ +#define ITM_PERIPHID2_PERIPHID (0xFFFFFFFFu) +#define ITM_PERIPHID2_PERIPHID_MASK (0xFFFFFFFFu) +#define ITM_PERIPHID2_PERIPHID_BIT (0) +#define ITM_PERIPHID2_PERIPHID_BITS (32) + +#define ITM_PERIPHID3 *((volatile uint32_t *)0xE0000FECu) +#define ITM_PERIPHID3_REG *((volatile uint32_t *)0xE0000FECu) +#define ITM_PERIPHID3_ADDR (0xE0000FECu) +#define ITM_PERIPHID3_RESET (0x00000000u) +/* PERIPHID field */ +#define ITM_PERIPHID3_PERIPHID (0xFFFFFFFFu) +#define ITM_PERIPHID3_PERIPHID_MASK (0xFFFFFFFFu) +#define ITM_PERIPHID3_PERIPHID_BIT (0) +#define ITM_PERIPHID3_PERIPHID_BITS (32) + +#define ITM_CELLID0 *((volatile uint32_t *)0xE0000FF0u) +#define ITM_CELLID0_REG *((volatile uint32_t *)0xE0000FF0u) +#define ITM_CELLID0_ADDR (0xE0000FF0u) +#define ITM_CELLID0_RESET (0x0000000Du) +/* PERIPHID field */ +#define ITM_CELLID0_PERIPHID (0xFFFFFFFFu) +#define ITM_CELLID0_PERIPHID_MASK (0xFFFFFFFFu) +#define ITM_CELLID0_PERIPHID_BIT (0) +#define ITM_CELLID0_PERIPHID_BITS (32) + +#define ITM_CELLID1 *((volatile uint32_t *)0xE0000FF4u) +#define ITM_CELLID1_REG *((volatile uint32_t *)0xE0000FF4u) +#define ITM_CELLID1_ADDR (0xE0000FF4u) +#define ITM_CELLID1_RESET (0x000000E0u) +/* PERIPHID field */ +#define ITM_CELLID1_PERIPHID (0xFFFFFFFFu) +#define ITM_CELLID1_PERIPHID_MASK (0xFFFFFFFFu) +#define ITM_CELLID1_PERIPHID_BIT (0) +#define ITM_CELLID1_PERIPHID_BITS (32) + +#define ITM_CELLID2 *((volatile uint32_t *)0xE0000FF8u) +#define ITM_CELLID2_REG *((volatile uint32_t *)0xE0000FF8u) +#define ITM_CELLID2_ADDR (0xE0000FF8u) +#define ITM_CELLID2_RESET (0x00000005u) +/* PERIPHID field */ +#define ITM_CELLID2_PERIPHID (0xFFFFFFFFu) +#define ITM_CELLID2_PERIPHID_MASK (0xFFFFFFFFu) +#define ITM_CELLID2_PERIPHID_BIT (0) +#define ITM_CELLID2_PERIPHID_BITS (32) + +#define ITM_CELLID3 *((volatile uint32_t *)0xE0000FFCu) +#define ITM_CELLID3_REG *((volatile uint32_t *)0xE0000FFCu) +#define ITM_CELLID3_ADDR (0xE0000FFCu) +#define ITM_CELLID3_RESET (0x000000B1u) +/* PERIPHID field */ +#define ITM_CELLID3_PERIPHID (0xFFFFFFFFu) +#define ITM_CELLID3_PERIPHID_MASK (0xFFFFFFFFu) +#define ITM_CELLID3_PERIPHID_BIT (0) +#define ITM_CELLID3_PERIPHID_BITS (32) + +/* DWT block */ +#define DATA_DWT_BASE (0xE0001000u) +#define DATA_DWT_END (0xE0001FFFu) +#define DATA_DWT_SIZE (DATA_DWT_END - DATA_DWT_BASE + 1) + +#define DWT_CTRL *((volatile uint32_t *)0xE0001000u) +#define DWT_CTRL_REG *((volatile uint32_t *)0xE0001000u) +#define DWT_CTRL_ADDR (0xE0001000u) +#define DWT_CTRL_RESET (0x40000000u) +/* NUMCOMP field */ +#define DWT_CTRL_NUMCOMP (0xF0000000u) +#define DWT_CTRL_NUMCOMP_MASK (0xF0000000u) +#define DWT_CTRL_NUMCOMP_BIT (28) +#define DWT_CTRL_NUMCOMP_BITS (4) +/* CYCEVTENA field */ +#define DWT_CTRL_CYCEVTENA (0x00400000u) +#define DWT_CTRL_CYCEVTENA_MASK (0x00400000u) +#define DWT_CTRL_CYCEVTENA_BIT (22) +#define DWT_CTRL_CYCEVTENA_BITS (1) +/* FOLDEVTENA field */ +#define DWT_CTRL_FOLDEVTENA (0x00200000u) +#define DWT_CTRL_FOLDEVTENA_MASK (0x00200000u) +#define DWT_CTRL_FOLDEVTENA_BIT (21) +#define DWT_CTRL_FOLDEVTENA_BITS (1) +/* LSUEVTENA field */ +#define DWT_CTRL_LSUEVTENA (0x00100000u) +#define DWT_CTRL_LSUEVTENA_MASK (0x00100000u) +#define DWT_CTRL_LSUEVTENA_BIT (20) +#define DWT_CTRL_LSUEVTENA_BITS (1) +/* SLEEPEVTENA field */ +#define DWT_CTRL_SLEEPEVTENA (0x00080000u) +#define DWT_CTRL_SLEEPEVTENA_MASK (0x00080000u) +#define DWT_CTRL_SLEEPEVTENA_BIT (19) +#define DWT_CTRL_SLEEPEVTENA_BITS (1) +/* EXCEVTENA field */ +#define DWT_CTRL_EXCEVTENA (0x00040000u) +#define DWT_CTRL_EXCEVTENA_MASK (0x00040000u) +#define DWT_CTRL_EXCEVTENA_BIT (18) +#define DWT_CTRL_EXCEVTENA_BITS (1) +/* CPIEVTENA field */ +#define DWT_CTRL_CPIEVTENA (0x00020000u) +#define DWT_CTRL_CPIEVTENA_MASK (0x00020000u) +#define DWT_CTRL_CPIEVTENA_BIT (17) +#define DWT_CTRL_CPIEVTENA_BITS (1) +/* EXCTRCENA field */ +#define DWT_CTRL_EXCTRCENA (0x00010000u) +#define DWT_CTRL_EXCTRCENA_MASK (0x00010000u) +#define DWT_CTRL_EXCTRCENA_BIT (16) +#define DWT_CTRL_EXCTRCENA_BITS (1) +/* PCSAMPLEENA field */ +#define DWT_CTRL_PCSAMPLEENA (0x00001000u) +#define DWT_CTRL_PCSAMPLEENA_MASK (0x00001000u) +#define DWT_CTRL_PCSAMPLEENA_BIT (12) +#define DWT_CTRL_PCSAMPLEENA_BITS (1) +/* SYNCTAP field */ +#define DWT_CTRL_SYNCTAP (0x00000C00u) +#define DWT_CTRL_SYNCTAP_MASK (0x00000C00u) +#define DWT_CTRL_SYNCTAP_BIT (10) +#define DWT_CTRL_SYNCTAP_BITS (2) +/* CYCTAP field */ +#define DWT_CTRL_CYCTAP (0x00000200u) +#define DWT_CTRL_CYCTAP_MASK (0x00000200u) +#define DWT_CTRL_CYCTAP_BIT (9) +#define DWT_CTRL_CYCTAP_BITS (1) +/* POSTCNT field */ +#define DWT_CTRL_POSTCNT (0x000001E0u) +#define DWT_CTRL_POSTCNT_MASK (0x000001E0u) +#define DWT_CTRL_POSTCNT_BIT (5) +#define DWT_CTRL_POSTCNT_BITS (4) +/* POSTPRESET field */ +#define DWT_CTRL_POSTPRESET (0x0000001Eu) +#define DWT_CTRL_POSTPRESET_MASK (0x0000001Eu) +#define DWT_CTRL_POSTPRESET_BIT (1) +#define DWT_CTRL_POSTPRESET_BITS (4) +/* CYCCNTENA field */ +#define DWT_CTRL_CYCCNTENA (0x00000001u) +#define DWT_CTRL_CYCCNTENA_MASK (0x00000001u) +#define DWT_CTRL_CYCCNTENA_BIT (0) +#define DWT_CTRL_CYCCNTENA_BITS (1) + +#define DWT_CYCCNT *((volatile uint32_t *)0xE0001004u) +#define DWT_CYCCNT_REG *((volatile uint32_t *)0xE0001004u) +#define DWT_CYCCNT_ADDR (0xE0001004u) +#define DWT_CYCCNT_RESET (0x00000000u) +/* CYCCNT field */ +#define DWT_CYCCNT_CYCCNT (0xFFFFFFFFu) +#define DWT_CYCCNT_CYCCNT_MASK (0xFFFFFFFFu) +#define DWT_CYCCNT_CYCCNT_BIT (0) +#define DWT_CYCCNT_CYCCNT_BITS (32) + +#define DWT_CPICNT *((volatile uint32_t *)0xE0001008u) +#define DWT_CPICNT_REG *((volatile uint32_t *)0xE0001008u) +#define DWT_CPICNT_ADDR (0xE0001008u) +#define DWT_CPICNT_RESET (0x00000000u) +/* CPICNT field */ +#define DWT_CPICNT_CPICNT (0x000000FFu) +#define DWT_CPICNT_CPICNT_MASK (0x000000FFu) +#define DWT_CPICNT_CPICNT_BIT (0) +#define DWT_CPICNT_CPICNT_BITS (8) + +#define DWT_EXCCNT *((volatile uint32_t *)0xE000100Cu) +#define DWT_EXCCNT_REG *((volatile uint32_t *)0xE000100Cu) +#define DWT_EXCCNT_ADDR (0xE000100Cu) +#define DWT_EXCCNT_RESET (0x00000000u) +/* EXCCNT field */ +#define DWT_EXCCNT_EXCCNT (0x000000FFu) +#define DWT_EXCCNT_EXCCNT_MASK (0x000000FFu) +#define DWT_EXCCNT_EXCCNT_BIT (0) +#define DWT_EXCCNT_EXCCNT_BITS (8) + +#define DWT_SLEEPCNT *((volatile uint32_t *)0xE0001010u) +#define DWT_SLEEPCNT_REG *((volatile uint32_t *)0xE0001010u) +#define DWT_SLEEPCNT_ADDR (0xE0001010u) +#define DWT_SLEEPCNT_RESET (0x00000000u) +/* SLEEPCNT field */ +#define DWT_SLEEPCNT_SLEEPCNT (0x000000FFu) +#define DWT_SLEEPCNT_SLEEPCNT_MASK (0x000000FFu) +#define DWT_SLEEPCNT_SLEEPCNT_BIT (0) +#define DWT_SLEEPCNT_SLEEPCNT_BITS (8) + +#define DWT_LSUCNT *((volatile uint32_t *)0xE0001014u) +#define DWT_LSUCNT_REG *((volatile uint32_t *)0xE0001014u) +#define DWT_LSUCNT_ADDR (0xE0001014u) +#define DWT_LSUCNT_RESET (0x00000000u) +/* CPICNT field */ +#define DWT_LSUCNT_CPICNT (0x000000FFu) +#define DWT_LSUCNT_CPICNT_MASK (0x000000FFu) +#define DWT_LSUCNT_CPICNT_BIT (0) +#define DWT_LSUCNT_CPICNT_BITS (8) + +#define DWT_FOLDCNT *((volatile uint32_t *)0xE0001018u) +#define DWT_FOLDCNT_REG *((volatile uint32_t *)0xE0001018u) +#define DWT_FOLDCNT_ADDR (0xE0001018u) +#define DWT_FOLDCNT_RESET (0x00000000u) +/* CPICNT field */ +#define DWT_FOLDCNT_CPICNT (0x000000FFu) +#define DWT_FOLDCNT_CPICNT_MASK (0x000000FFu) +#define DWT_FOLDCNT_CPICNT_BIT (0) +#define DWT_FOLDCNT_CPICNT_BITS (8) + +#define DWT_PCSR *((volatile uint32_t *)0xE000101Cu) +#define DWT_PCSR_REG *((volatile uint32_t *)0xE000101Cu) +#define DWT_PCSR_ADDR (0xE000101Cu) +#define DWT_PCSR_RESET (0x00000000u) +/* EIASAMPLE field */ +#define DWT_PCSR_EIASAMPLE (0xFFFFFFFFu) +#define DWT_PCSR_EIASAMPLE_MASK (0xFFFFFFFFu) +#define DWT_PCSR_EIASAMPLE_BIT (0) +#define DWT_PCSR_EIASAMPLE_BITS (32) + +#define DWT_COMP0 *((volatile uint32_t *)0xE0001020u) +#define DWT_COMP0_REG *((volatile uint32_t *)0xE0001020u) +#define DWT_COMP0_ADDR (0xE0001020u) +#define DWT_COMP0_RESET (0x00000000u) +/* COMP0 field */ +#define DWT_COMP0_COMP0 (0xFFFFFFFFu) +#define DWT_COMP0_COMP0_MASK (0xFFFFFFFFu) +#define DWT_COMP0_COMP0_BIT (0) +#define DWT_COMP0_COMP0_BITS (32) + +#define DWT_MASK0 *((volatile uint32_t *)0xE0001024u) +#define DWT_MASK0_REG *((volatile uint32_t *)0xE0001024u) +#define DWT_MASK0_ADDR (0xE0001024u) +#define DWT_MASK0_RESET (0x00000000u) +/* MASK0 field */ +#define DWT_MASK0_MASK0 (0x0000001Fu) +#define DWT_MASK0_MASK0_MASK (0x0000001Fu) +#define DWT_MASK0_MASK0_BIT (0) +#define DWT_MASK0_MASK0_BITS (5) + +#define DWT_FUNCTION0 *((volatile uint32_t *)0xE0001028u) +#define DWT_FUNCTION0_REG *((volatile uint32_t *)0xE0001028u) +#define DWT_FUNCTION0_ADDR (0xE0001028u) +#define DWT_FUNCTION0_RESET (0x00000000u) +/* MATCHED field */ +#define DWT_FUNCTION0_MATCHED (0x01000000u) +#define DWT_FUNCTION0_MATCHED_MASK (0x01000000u) +#define DWT_FUNCTION0_MATCHED_BIT (24) +#define DWT_FUNCTION0_MATCHED_BITS (1) +/* CYCMATCH field */ +#define DWT_FUNCTION0_CYCMATCH (0x00000080u) +#define DWT_FUNCTION0_CYCMATCH_MASK (0x00000080u) +#define DWT_FUNCTION0_CYCMATCH_BIT (7) +#define DWT_FUNCTION0_CYCMATCH_BITS (1) +/* EMITRANGE field */ +#define DWT_FUNCTION0_EMITRANGE (0x00000020u) +#define DWT_FUNCTION0_EMITRANGE_MASK (0x00000020u) +#define DWT_FUNCTION0_EMITRANGE_BIT (5) +#define DWT_FUNCTION0_EMITRANGE_BITS (1) +/* FUNCTION field */ +#define DWT_FUNCTION0_FUNCTION (0x0000000Fu) +#define DWT_FUNCTION0_FUNCTION_MASK (0x0000000Fu) +#define DWT_FUNCTION0_FUNCTION_BIT (0) +#define DWT_FUNCTION0_FUNCTION_BITS (4) + +#define DWT_COMP1 *((volatile uint32_t *)0xE0001030u) +#define DWT_COMP1_REG *((volatile uint32_t *)0xE0001030u) +#define DWT_COMP1_ADDR (0xE0001030u) +#define DWT_COMP1_RESET (0x00000000u) +/* COMP1 field */ +#define DWT_COMP1_COMP1 (0xFFFFFFFFu) +#define DWT_COMP1_COMP1_MASK (0xFFFFFFFFu) +#define DWT_COMP1_COMP1_BIT (0) +#define DWT_COMP1_COMP1_BITS (32) + +#define DWT_MASK1 *((volatile uint32_t *)0xE0001034u) +#define DWT_MASK1_REG *((volatile uint32_t *)0xE0001034u) +#define DWT_MASK1_ADDR (0xE0001034u) +#define DWT_MASK1_RESET (0x00000000u) +/* MASK1 field */ +#define DWT_MASK1_MASK1 (0x0000001Fu) +#define DWT_MASK1_MASK1_MASK (0x0000001Fu) +#define DWT_MASK1_MASK1_BIT (0) +#define DWT_MASK1_MASK1_BITS (5) + +#define DWT_FUNCTION1 *((volatile uint32_t *)0xE0001038u) +#define DWT_FUNCTION1_REG *((volatile uint32_t *)0xE0001038u) +#define DWT_FUNCTION1_ADDR (0xE0001038u) +#define DWT_FUNCTION1_RESET (0x00000200u) +/* MATCHED field */ +#define DWT_FUNCTION1_MATCHED (0x01000000u) +#define DWT_FUNCTION1_MATCHED_MASK (0x01000000u) +#define DWT_FUNCTION1_MATCHED_BIT (24) +#define DWT_FUNCTION1_MATCHED_BITS (1) +/* DATAVADDR1 field */ +#define DWT_FUNCTION1_DATAVADDR1 (0x000F0000u) +#define DWT_FUNCTION1_DATAVADDR1_MASK (0x000F0000u) +#define DWT_FUNCTION1_DATAVADDR1_BIT (16) +#define DWT_FUNCTION1_DATAVADDR1_BITS (4) +/* DATAVADDR0 field */ +#define DWT_FUNCTION1_DATAVADDR0 (0x0000F000u) +#define DWT_FUNCTION1_DATAVADDR0_MASK (0x0000F000u) +#define DWT_FUNCTION1_DATAVADDR0_BIT (12) +#define DWT_FUNCTION1_DATAVADDR0_BITS (4) +/* DATAVSIZE field */ +#define DWT_FUNCTION1_DATAVSIZE (0x00000C00u) +#define DWT_FUNCTION1_DATAVSIZE_MASK (0x00000C00u) +#define DWT_FUNCTION1_DATAVSIZE_BIT (10) +#define DWT_FUNCTION1_DATAVSIZE_BITS (2) +/* LNK1ENA field */ +#define DWT_FUNCTION1_LNK1ENA (0x00000200u) +#define DWT_FUNCTION1_LNK1ENA_MASK (0x00000200u) +#define DWT_FUNCTION1_LNK1ENA_BIT (9) +#define DWT_FUNCTION1_LNK1ENA_BITS (1) +/* DATAVMATCH field */ +#define DWT_FUNCTION1_DATAVMATCH (0x00000100u) +#define DWT_FUNCTION1_DATAVMATCH_MASK (0x00000100u) +#define DWT_FUNCTION1_DATAVMATCH_BIT (8) +#define DWT_FUNCTION1_DATAVMATCH_BITS (1) +/* EMITRANGE field */ +#define DWT_FUNCTION1_EMITRANGE (0x00000020u) +#define DWT_FUNCTION1_EMITRANGE_MASK (0x00000020u) +#define DWT_FUNCTION1_EMITRANGE_BIT (5) +#define DWT_FUNCTION1_EMITRANGE_BITS (1) +/* FUNCTION field */ +#define DWT_FUNCTION1_FUNCTION (0x0000000Fu) +#define DWT_FUNCTION1_FUNCTION_MASK (0x0000000Fu) +#define DWT_FUNCTION1_FUNCTION_BIT (0) +#define DWT_FUNCTION1_FUNCTION_BITS (4) + +#define DWT_COMP2 *((volatile uint32_t *)0xE0001040u) +#define DWT_COMP2_REG *((volatile uint32_t *)0xE0001040u) +#define DWT_COMP2_ADDR (0xE0001040u) +#define DWT_COMP2_RESET (0x00000000u) +/* COMP2 field */ +#define DWT_COMP2_COMP2 (0xFFFFFFFFu) +#define DWT_COMP2_COMP2_MASK (0xFFFFFFFFu) +#define DWT_COMP2_COMP2_BIT (0) +#define DWT_COMP2_COMP2_BITS (32) + +#define DWT_MASK2 *((volatile uint32_t *)0xE0001044u) +#define DWT_MASK2_REG *((volatile uint32_t *)0xE0001044u) +#define DWT_MASK2_ADDR (0xE0001044u) +#define DWT_MASK2_RESET (0x00000000u) +/* MASK2 field */ +#define DWT_MASK2_MASK2 (0x0000001Fu) +#define DWT_MASK2_MASK2_MASK (0x0000001Fu) +#define DWT_MASK2_MASK2_BIT (0) +#define DWT_MASK2_MASK2_BITS (5) + +#define DWT_FUNCTION2 *((volatile uint32_t *)0xE0001048u) +#define DWT_FUNCTION2_REG *((volatile uint32_t *)0xE0001048u) +#define DWT_FUNCTION2_ADDR (0xE0001048u) +#define DWT_FUNCTION2_RESET (0x00000000u) +/* MATCHED field */ +#define DWT_FUNCTION2_MATCHED (0x01000000u) +#define DWT_FUNCTION2_MATCHED_MASK (0x01000000u) +#define DWT_FUNCTION2_MATCHED_BIT (24) +#define DWT_FUNCTION2_MATCHED_BITS (1) +/* EMITRANGE field */ +#define DWT_FUNCTION2_EMITRANGE (0x00000020u) +#define DWT_FUNCTION2_EMITRANGE_MASK (0x00000020u) +#define DWT_FUNCTION2_EMITRANGE_BIT (5) +#define DWT_FUNCTION2_EMITRANGE_BITS (1) +/* FUNCTION field */ +#define DWT_FUNCTION2_FUNCTION (0x0000000Fu) +#define DWT_FUNCTION2_FUNCTION_MASK (0x0000000Fu) +#define DWT_FUNCTION2_FUNCTION_BIT (0) +#define DWT_FUNCTION2_FUNCTION_BITS (4) + +#define DWT_COMP3 *((volatile uint32_t *)0xE0001050u) +#define DWT_COMP3_REG *((volatile uint32_t *)0xE0001050u) +#define DWT_COMP3_ADDR (0xE0001050u) +#define DWT_COMP3_RESET (0x00000000u) +/* COMP3 field */ +#define DWT_COMP3_COMP3 (0xFFFFFFFFu) +#define DWT_COMP3_COMP3_MASK (0xFFFFFFFFu) +#define DWT_COMP3_COMP3_BIT (0) +#define DWT_COMP3_COMP3_BITS (32) + +#define DWT_MASK3 *((volatile uint32_t *)0xE0001054u) +#define DWT_MASK3_REG *((volatile uint32_t *)0xE0001054u) +#define DWT_MASK3_ADDR (0xE0001054u) +#define DWT_MASK3_RESET (0x00000000u) +/* MASK3 field */ +#define DWT_MASK3_MASK3 (0x0000001Fu) +#define DWT_MASK3_MASK3_MASK (0x0000001Fu) +#define DWT_MASK3_MASK3_BIT (0) +#define DWT_MASK3_MASK3_BITS (5) + +#define DWT_FUNCTION3 *((volatile uint32_t *)0xE0001058u) +#define DWT_FUNCTION3_REG *((volatile uint32_t *)0xE0001058u) +#define DWT_FUNCTION3_ADDR (0xE0001058u) +#define DWT_FUNCTION3_RESET (0x00000000u) +/* MATCHED field */ +#define DWT_FUNCTION3_MATCHED (0x01000000u) +#define DWT_FUNCTION3_MATCHED_MASK (0x01000000u) +#define DWT_FUNCTION3_MATCHED_BIT (24) +#define DWT_FUNCTION3_MATCHED_BITS (1) +/* EMITRANGE field */ +#define DWT_FUNCTION3_EMITRANGE (0x00000020u) +#define DWT_FUNCTION3_EMITRANGE_MASK (0x00000020u) +#define DWT_FUNCTION3_EMITRANGE_BIT (5) +#define DWT_FUNCTION3_EMITRANGE_BITS (1) +/* FUNCTION field */ +#define DWT_FUNCTION3_FUNCTION (0x0000000Fu) +#define DWT_FUNCTION3_FUNCTION_MASK (0x0000000Fu) +#define DWT_FUNCTION3_FUNCTION_BIT (0) +#define DWT_FUNCTION3_FUNCTION_BITS (4) + +#define DWT_PERIPHID4 *((volatile uint32_t *)0xE0001FD0u) +#define DWT_PERIPHID4_REG *((volatile uint32_t *)0xE0001FD0u) +#define DWT_PERIPHID4_ADDR (0xE0001FD0u) +#define DWT_PERIPHID4_RESET (0x00000004u) +/* PERIPHID field */ +#define DWT_PERIPHID4_PERIPHID (0xFFFFFFFFu) +#define DWT_PERIPHID4_PERIPHID_MASK (0xFFFFFFFFu) +#define DWT_PERIPHID4_PERIPHID_BIT (0) +#define DWT_PERIPHID4_PERIPHID_BITS (32) + +#define DWT_PERIPHID5 *((volatile uint32_t *)0xE0001FD4u) +#define DWT_PERIPHID5_REG *((volatile uint32_t *)0xE0001FD4u) +#define DWT_PERIPHID5_ADDR (0xE0001FD4u) +#define DWT_PERIPHID5_RESET (0x00000000u) +/* PERIPHID field */ +#define DWT_PERIPHID5_PERIPHID (0xFFFFFFFFu) +#define DWT_PERIPHID5_PERIPHID_MASK (0xFFFFFFFFu) +#define DWT_PERIPHID5_PERIPHID_BIT (0) +#define DWT_PERIPHID5_PERIPHID_BITS (32) + +#define DWT_PERIPHID6 *((volatile uint32_t *)0xE0001FD8u) +#define DWT_PERIPHID6_REG *((volatile uint32_t *)0xE0001FD8u) +#define DWT_PERIPHID6_ADDR (0xE0001FD8u) +#define DWT_PERIPHID6_RESET (0x00000000u) +/* PERIPHID field */ +#define DWT_PERIPHID6_PERIPHID (0xFFFFFFFFu) +#define DWT_PERIPHID6_PERIPHID_MASK (0xFFFFFFFFu) +#define DWT_PERIPHID6_PERIPHID_BIT (0) +#define DWT_PERIPHID6_PERIPHID_BITS (32) + +#define DWT_PERIPHID7 *((volatile uint32_t *)0xE0001FDCu) +#define DWT_PERIPHID7_REG *((volatile uint32_t *)0xE0001FDCu) +#define DWT_PERIPHID7_ADDR (0xE0001FDCu) +#define DWT_PERIPHID7_RESET (0x00000000u) +/* PERIPHID field */ +#define DWT_PERIPHID7_PERIPHID (0xFFFFFFFFu) +#define DWT_PERIPHID7_PERIPHID_MASK (0xFFFFFFFFu) +#define DWT_PERIPHID7_PERIPHID_BIT (0) +#define DWT_PERIPHID7_PERIPHID_BITS (32) + +#define DWT_PERIPHID0 *((volatile uint32_t *)0xE0001FE0u) +#define DWT_PERIPHID0_REG *((volatile uint32_t *)0xE0001FE0u) +#define DWT_PERIPHID0_ADDR (0xE0001FE0u) +#define DWT_PERIPHID0_RESET (0x00000002u) +/* PERIPHID field */ +#define DWT_PERIPHID0_PERIPHID (0xFFFFFFFFu) +#define DWT_PERIPHID0_PERIPHID_MASK (0xFFFFFFFFu) +#define DWT_PERIPHID0_PERIPHID_BIT (0) +#define DWT_PERIPHID0_PERIPHID_BITS (32) + +#define DWT_PERIPHID1 *((volatile uint32_t *)0xE0001FE4u) +#define DWT_PERIPHID1_REG *((volatile uint32_t *)0xE0001FE4u) +#define DWT_PERIPHID1_ADDR (0xE0001FE4u) +#define DWT_PERIPHID1_RESET (0x00000000u) +/* PERIPHID field */ +#define DWT_PERIPHID1_PERIPHID (0xFFFFFFFFu) +#define DWT_PERIPHID1_PERIPHID_MASK (0xFFFFFFFFu) +#define DWT_PERIPHID1_PERIPHID_BIT (0) +#define DWT_PERIPHID1_PERIPHID_BITS (32) + +#define DWT_PERIPHID2 *((volatile uint32_t *)0xE0001FE8u) +#define DWT_PERIPHID2_REG *((volatile uint32_t *)0xE0001FE8u) +#define DWT_PERIPHID2_ADDR (0xE0001FE8u) +#define DWT_PERIPHID2_RESET (0x0000001Bu) +/* PERIPHID field */ +#define DWT_PERIPHID2_PERIPHID (0xFFFFFFFFu) +#define DWT_PERIPHID2_PERIPHID_MASK (0xFFFFFFFFu) +#define DWT_PERIPHID2_PERIPHID_BIT (0) +#define DWT_PERIPHID2_PERIPHID_BITS (32) + +#define DWT_PERIPHID3 *((volatile uint32_t *)0xE0001FECu) +#define DWT_PERIPHID3_REG *((volatile uint32_t *)0xE0001FECu) +#define DWT_PERIPHID3_ADDR (0xE0001FECu) +#define DWT_PERIPHID3_RESET (0x00000000u) +/* PERIPHID field */ +#define DWT_PERIPHID3_PERIPHID (0xFFFFFFFFu) +#define DWT_PERIPHID3_PERIPHID_MASK (0xFFFFFFFFu) +#define DWT_PERIPHID3_PERIPHID_BIT (0) +#define DWT_PERIPHID3_PERIPHID_BITS (32) + +#define DWT_CELLID0 *((volatile uint32_t *)0xE0001FF0u) +#define DWT_CELLID0_REG *((volatile uint32_t *)0xE0001FF0u) +#define DWT_CELLID0_ADDR (0xE0001FF0u) +#define DWT_CELLID0_RESET (0x0000000Du) +/* CELLID field */ +#define DWT_CELLID0_CELLID (0xFFFFFFFFu) +#define DWT_CELLID0_CELLID_MASK (0xFFFFFFFFu) +#define DWT_CELLID0_CELLID_BIT (0) +#define DWT_CELLID0_CELLID_BITS (32) + +#define DWT_CELLID1 *((volatile uint32_t *)0xE0001FF4u) +#define DWT_CELLID1_REG *((volatile uint32_t *)0xE0001FF4u) +#define DWT_CELLID1_ADDR (0xE0001FF4u) +#define DWT_CELLID1_RESET (0x000000E0u) +/* CELLID field */ +#define DWT_CELLID1_CELLID (0xFFFFFFFFu) +#define DWT_CELLID1_CELLID_MASK (0xFFFFFFFFu) +#define DWT_CELLID1_CELLID_BIT (0) +#define DWT_CELLID1_CELLID_BITS (32) + +#define DWT_CELLID2 *((volatile uint32_t *)0xE0001FF8u) +#define DWT_CELLID2_REG *((volatile uint32_t *)0xE0001FF8u) +#define DWT_CELLID2_ADDR (0xE0001FF8u) +#define DWT_CELLID2_RESET (0x00000005u) +/* CELLID field */ +#define DWT_CELLID2_CELLID (0xFFFFFFFFu) +#define DWT_CELLID2_CELLID_MASK (0xFFFFFFFFu) +#define DWT_CELLID2_CELLID_BIT (0) +#define DWT_CELLID2_CELLID_BITS (32) + +#define DWT_CELLID3 *((volatile uint32_t *)0xE0001FFCu) +#define DWT_CELLID3_REG *((volatile uint32_t *)0xE0001FFCu) +#define DWT_CELLID3_ADDR (0xE0001FFCu) +#define DWT_CELLID3_RESET (0x000000B1u) +/* CELLID field */ +#define DWT_CELLID3_CELLID (0xFFFFFFFFu) +#define DWT_CELLID3_CELLID_MASK (0xFFFFFFFFu) +#define DWT_CELLID3_CELLID_BIT (0) +#define DWT_CELLID3_CELLID_BITS (32) + +/* FPB block */ +#define DATA_FPB_BASE (0xE0002000u) +#define DATA_FPB_END (0xE0002FFFu) +#define DATA_FPB_SIZE (DATA_FPB_END - DATA_FPB_BASE + 1) + +#define FPB_CTRL *((volatile uint32_t *)0xE0002000u) +#define FPB_CTRL_REG *((volatile uint32_t *)0xE0002000u) +#define FPB_CTRL_ADDR (0xE0002000u) +#define FPB_CTRL_RESET (0x00000000u) +/* NUM_LIT field */ +#define FPB_CTRL_NUM_LIT (0x00000F00u) +#define FPB_CTRL_NUM_LIT_MASK (0x00000F00u) +#define FPB_CTRL_NUM_LIT_BIT (8) +#define FPB_CTRL_NUM_LIT_BITS (4) +/* NUM_CODE field */ +#define FPB_CTRL_NUM_CODE (0x000000F0u) +#define FPB_CTRL_NUM_CODE_MASK (0x000000F0u) +#define FPB_CTRL_NUM_CODE_BIT (4) +#define FPB_CTRL_NUM_CODE_BITS (4) +/* KEY field */ +#define FPB_CTRL_KEY (0x00000002u) +#define FPB_CTRL_KEY_MASK (0x00000002u) +#define FPB_CTRL_KEY_BIT (1) +#define FPB_CTRL_KEY_BITS (1) +/* enable field */ +#define FPB_CTRL_enable (0x00000001u) +#define FPB_CTRL_enable_MASK (0x00000001u) +#define FPB_CTRL_enable_BIT (0) +#define FPB_CTRL_enable_BITS (1) + +#define FPB_REMAP *((volatile uint32_t *)0xE0002004u) +#define FPB_REMAP_REG *((volatile uint32_t *)0xE0002004u) +#define FPB_REMAP_ADDR (0xE0002004u) +#define FPB_REMAP_RESET (0x20000000u) +/* REMAP field */ +#define FPB_REMAP_REMAP (0x1FFFFFE0u) +#define FPB_REMAP_REMAP_MASK (0x1FFFFFE0u) +#define FPB_REMAP_REMAP_BIT (5) +#define FPB_REMAP_REMAP_BITS (24) + +#define FPB_COMP0 *((volatile uint32_t *)0xE0002008u) +#define FPB_COMP0_REG *((volatile uint32_t *)0xE0002008u) +#define FPB_COMP0_ADDR (0xE0002008u) +#define FPB_COMP0_RESET (0x00000000u) +/* REPLACE field */ +#define FPB_COMP0_REPLACE (0xC0000000u) +#define FPB_COMP0_REPLACE_MASK (0xC0000000u) +#define FPB_COMP0_REPLACE_BIT (30) +#define FPB_COMP0_REPLACE_BITS (2) +/* COMP field */ +#define FPB_COMP0_COMP (0x1FFFFFFCu) +#define FPB_COMP0_COMP_MASK (0x1FFFFFFCu) +#define FPB_COMP0_COMP_BIT (2) +#define FPB_COMP0_COMP_BITS (27) +/* enable field */ +#define FPB_COMP0_enable (0x00000001u) +#define FPB_COMP0_enable_MASK (0x00000001u) +#define FPB_COMP0_enable_BIT (0) +#define FPB_COMP0_enable_BITS (1) + +#define FPB_COMP1 *((volatile uint32_t *)0xE000200Cu) +#define FPB_COMP1_REG *((volatile uint32_t *)0xE000200Cu) +#define FPB_COMP1_ADDR (0xE000200Cu) +#define FPB_COMP1_RESET (0x00000000u) +/* REPLACE field */ +#define FPB_COMP1_REPLACE (0xC0000000u) +#define FPB_COMP1_REPLACE_MASK (0xC0000000u) +#define FPB_COMP1_REPLACE_BIT (30) +#define FPB_COMP1_REPLACE_BITS (2) +/* COMP field */ +#define FPB_COMP1_COMP (0x1FFFFFFCu) +#define FPB_COMP1_COMP_MASK (0x1FFFFFFCu) +#define FPB_COMP1_COMP_BIT (2) +#define FPB_COMP1_COMP_BITS (27) +/* enable field */ +#define FPB_COMP1_enable (0x00000001u) +#define FPB_COMP1_enable_MASK (0x00000001u) +#define FPB_COMP1_enable_BIT (0) +#define FPB_COMP1_enable_BITS (1) + +#define FPB_COMP2 *((volatile uint32_t *)0xE0002010u) +#define FPB_COMP2_REG *((volatile uint32_t *)0xE0002010u) +#define FPB_COMP2_ADDR (0xE0002010u) +#define FPB_COMP2_RESET (0x00000000u) +/* REPLACE field */ +#define FPB_COMP2_REPLACE (0xC0000000u) +#define FPB_COMP2_REPLACE_MASK (0xC0000000u) +#define FPB_COMP2_REPLACE_BIT (30) +#define FPB_COMP2_REPLACE_BITS (2) +/* COMP field */ +#define FPB_COMP2_COMP (0x1FFFFFFCu) +#define FPB_COMP2_COMP_MASK (0x1FFFFFFCu) +#define FPB_COMP2_COMP_BIT (2) +#define FPB_COMP2_COMP_BITS (27) +/* enable field */ +#define FPB_COMP2_enable (0x00000001u) +#define FPB_COMP2_enable_MASK (0x00000001u) +#define FPB_COMP2_enable_BIT (0) +#define FPB_COMP2_enable_BITS (1) + +#define FPB_COMP3 *((volatile uint32_t *)0xE0002014u) +#define FPB_COMP3_REG *((volatile uint32_t *)0xE0002014u) +#define FPB_COMP3_ADDR (0xE0002014u) +#define FPB_COMP3_RESET (0x00000000u) +/* REPLACE field */ +#define FPB_COMP3_REPLACE (0xC0000000u) +#define FPB_COMP3_REPLACE_MASK (0xC0000000u) +#define FPB_COMP3_REPLACE_BIT (30) +#define FPB_COMP3_REPLACE_BITS (2) +/* COMP field */ +#define FPB_COMP3_COMP (0x1FFFFFFCu) +#define FPB_COMP3_COMP_MASK (0x1FFFFFFCu) +#define FPB_COMP3_COMP_BIT (2) +#define FPB_COMP3_COMP_BITS (27) +/* enable field */ +#define FPB_COMP3_enable (0x00000001u) +#define FPB_COMP3_enable_MASK (0x00000001u) +#define FPB_COMP3_enable_BIT (0) +#define FPB_COMP3_enable_BITS (1) + +#define FPB_COMP4 *((volatile uint32_t *)0xE0002018u) +#define FPB_COMP4_REG *((volatile uint32_t *)0xE0002018u) +#define FPB_COMP4_ADDR (0xE0002018u) +#define FPB_COMP4_RESET (0x00000000u) +/* REPLACE field */ +#define FPB_COMP4_REPLACE (0xC0000000u) +#define FPB_COMP4_REPLACE_MASK (0xC0000000u) +#define FPB_COMP4_REPLACE_BIT (30) +#define FPB_COMP4_REPLACE_BITS (2) +/* COMP field */ +#define FPB_COMP4_COMP (0x1FFFFFFCu) +#define FPB_COMP4_COMP_MASK (0x1FFFFFFCu) +#define FPB_COMP4_COMP_BIT (2) +#define FPB_COMP4_COMP_BITS (27) +/* enable field */ +#define FPB_COMP4_enable (0x00000001u) +#define FPB_COMP4_enable_MASK (0x00000001u) +#define FPB_COMP4_enable_BIT (0) +#define FPB_COMP4_enable_BITS (1) + +#define FPB_COMP5 *((volatile uint32_t *)0xE000201Cu) +#define FPB_COMP5_REG *((volatile uint32_t *)0xE000201Cu) +#define FPB_COMP5_ADDR (0xE000201Cu) +#define FPB_COMP5_RESET (0x00000000u) +/* REPLACE field */ +#define FPB_COMP5_REPLACE (0xC0000000u) +#define FPB_COMP5_REPLACE_MASK (0xC0000000u) +#define FPB_COMP5_REPLACE_BIT (30) +#define FPB_COMP5_REPLACE_BITS (2) +/* COMP field */ +#define FPB_COMP5_COMP (0x1FFFFFFCu) +#define FPB_COMP5_COMP_MASK (0x1FFFFFFCu) +#define FPB_COMP5_COMP_BIT (2) +#define FPB_COMP5_COMP_BITS (27) +/* enable field */ +#define FPB_COMP5_enable (0x00000001u) +#define FPB_COMP5_enable_MASK (0x00000001u) +#define FPB_COMP5_enable_BIT (0) +#define FPB_COMP5_enable_BITS (1) + +#define FPB_COMP6 *((volatile uint32_t *)0xE0002020u) +#define FPB_COMP6_REG *((volatile uint32_t *)0xE0002020u) +#define FPB_COMP6_ADDR (0xE0002020u) +#define FPB_COMP6_RESET (0x00000000u) +/* REPLACE field */ +#define FPB_COMP6_REPLACE (0xC0000000u) +#define FPB_COMP6_REPLACE_MASK (0xC0000000u) +#define FPB_COMP6_REPLACE_BIT (30) +#define FPB_COMP6_REPLACE_BITS (2) +/* COMP field */ +#define FPB_COMP6_COMP (0x1FFFFFFCu) +#define FPB_COMP6_COMP_MASK (0x1FFFFFFCu) +#define FPB_COMP6_COMP_BIT (2) +#define FPB_COMP6_COMP_BITS (27) +/* enable field */ +#define FPB_COMP6_enable (0x00000001u) +#define FPB_COMP6_enable_MASK (0x00000001u) +#define FPB_COMP6_enable_BIT (0) +#define FPB_COMP6_enable_BITS (1) + +#define FPB_COMP7 *((volatile uint32_t *)0xE0002024u) +#define FPB_COMP7_REG *((volatile uint32_t *)0xE0002024u) +#define FPB_COMP7_ADDR (0xE0002024u) +#define FPB_COMP7_RESET (0x00000000u) +/* REPLACE field */ +#define FPB_COMP7_REPLACE (0xC0000000u) +#define FPB_COMP7_REPLACE_MASK (0xC0000000u) +#define FPB_COMP7_REPLACE_BIT (30) +#define FPB_COMP7_REPLACE_BITS (2) +/* COMP field */ +#define FPB_COMP7_COMP (0x1FFFFFFCu) +#define FPB_COMP7_COMP_MASK (0x1FFFFFFCu) +#define FPB_COMP7_COMP_BIT (2) +#define FPB_COMP7_COMP_BITS (27) +/* enable field */ +#define FPB_COMP7_enable (0x00000001u) +#define FPB_COMP7_enable_MASK (0x00000001u) +#define FPB_COMP7_enable_BIT (0) +#define FPB_COMP7_enable_BITS (1) + +#define FPB_PERIPHID4 *((volatile uint32_t *)0xE0002FD0u) +#define FPB_PERIPHID4_REG *((volatile uint32_t *)0xE0002FD0u) +#define FPB_PERIPHID4_ADDR (0xE0002FD0u) +#define FPB_PERIPHID4_RESET (0x00000004u) +/* PERIPHID field */ +#define FPB_PERIPHID4_PERIPHID (0xFFFFFFFFu) +#define FPB_PERIPHID4_PERIPHID_MASK (0xFFFFFFFFu) +#define FPB_PERIPHID4_PERIPHID_BIT (0) +#define FPB_PERIPHID4_PERIPHID_BITS (32) + +#define FPB_PERIPHID5 *((volatile uint32_t *)0xE0002FD4u) +#define FPB_PERIPHID5_REG *((volatile uint32_t *)0xE0002FD4u) +#define FPB_PERIPHID5_ADDR (0xE0002FD4u) +#define FPB_PERIPHID5_RESET (0x00000000u) +/* PERIPHID field */ +#define FPB_PERIPHID5_PERIPHID (0xFFFFFFFFu) +#define FPB_PERIPHID5_PERIPHID_MASK (0xFFFFFFFFu) +#define FPB_PERIPHID5_PERIPHID_BIT (0) +#define FPB_PERIPHID5_PERIPHID_BITS (32) + +#define FPB_PERIPHID6 *((volatile uint32_t *)0xE0002FD8u) +#define FPB_PERIPHID6_REG *((volatile uint32_t *)0xE0002FD8u) +#define FPB_PERIPHID6_ADDR (0xE0002FD8u) +#define FPB_PERIPHID6_RESET (0x00000000u) +/* PERIPHID field */ +#define FPB_PERIPHID6_PERIPHID (0xFFFFFFFFu) +#define FPB_PERIPHID6_PERIPHID_MASK (0xFFFFFFFFu) +#define FPB_PERIPHID6_PERIPHID_BIT (0) +#define FPB_PERIPHID6_PERIPHID_BITS (32) + +#define FPB_PERIPHID7 *((volatile uint32_t *)0xE0002FDCu) +#define FPB_PERIPHID7_REG *((volatile uint32_t *)0xE0002FDCu) +#define FPB_PERIPHID7_ADDR (0xE0002FDCu) +#define FPB_PERIPHID7_RESET (0x00000000u) +/* PERIPHID field */ +#define FPB_PERIPHID7_PERIPHID (0xFFFFFFFFu) +#define FPB_PERIPHID7_PERIPHID_MASK (0xFFFFFFFFu) +#define FPB_PERIPHID7_PERIPHID_BIT (0) +#define FPB_PERIPHID7_PERIPHID_BITS (32) + +#define FPB_PERIPHID0 *((volatile uint32_t *)0xE0002FE0u) +#define FPB_PERIPHID0_REG *((volatile uint32_t *)0xE0002FE0u) +#define FPB_PERIPHID0_ADDR (0xE0002FE0u) +#define FPB_PERIPHID0_RESET (0x00000003u) +/* PERIPHID field */ +#define FPB_PERIPHID0_PERIPHID (0xFFFFFFFFu) +#define FPB_PERIPHID0_PERIPHID_MASK (0xFFFFFFFFu) +#define FPB_PERIPHID0_PERIPHID_BIT (0) +#define FPB_PERIPHID0_PERIPHID_BITS (32) + +#define FPB_PERIPHID1 *((volatile uint32_t *)0xE0002FE4u) +#define FPB_PERIPHID1_REG *((volatile uint32_t *)0xE0002FE4u) +#define FPB_PERIPHID1_ADDR (0xE0002FE4u) +#define FPB_PERIPHID1_RESET (0x000000B0u) +/* PERIPHID field */ +#define FPB_PERIPHID1_PERIPHID (0xFFFFFFFFu) +#define FPB_PERIPHID1_PERIPHID_MASK (0xFFFFFFFFu) +#define FPB_PERIPHID1_PERIPHID_BIT (0) +#define FPB_PERIPHID1_PERIPHID_BITS (32) + +#define FPB_PERIPHID2 *((volatile uint32_t *)0xE0002FE8u) +#define FPB_PERIPHID2_REG *((volatile uint32_t *)0xE0002FE8u) +#define FPB_PERIPHID2_ADDR (0xE0002FE8u) +#define FPB_PERIPHID2_RESET (0x0000000Bu) +/* PERIPHID field */ +#define FPB_PERIPHID2_PERIPHID (0xFFFFFFFFu) +#define FPB_PERIPHID2_PERIPHID_MASK (0xFFFFFFFFu) +#define FPB_PERIPHID2_PERIPHID_BIT (0) +#define FPB_PERIPHID2_PERIPHID_BITS (32) + +#define FPB_PERIPHID3 *((volatile uint32_t *)0xE0002FECu) +#define FPB_PERIPHID3_REG *((volatile uint32_t *)0xE0002FECu) +#define FPB_PERIPHID3_ADDR (0xE0002FECu) +#define FPB_PERIPHID3_RESET (0x00000000u) +/* PERIPHID field */ +#define FPB_PERIPHID3_PERIPHID (0xFFFFFFFFu) +#define FPB_PERIPHID3_PERIPHID_MASK (0xFFFFFFFFu) +#define FPB_PERIPHID3_PERIPHID_BIT (0) +#define FPB_PERIPHID3_PERIPHID_BITS (32) + +#define FPB_CELLID0 *((volatile uint32_t *)0xE0002FF0u) +#define FPB_CELLID0_REG *((volatile uint32_t *)0xE0002FF0u) +#define FPB_CELLID0_ADDR (0xE0002FF0u) +#define FPB_CELLID0_RESET (0x0000000Du) +/* CELLID field */ +#define FPB_CELLID0_CELLID (0xFFFFFFFFu) +#define FPB_CELLID0_CELLID_MASK (0xFFFFFFFFu) +#define FPB_CELLID0_CELLID_BIT (0) +#define FPB_CELLID0_CELLID_BITS (32) + +#define FPB_CELLID1 *((volatile uint32_t *)0xE0002FF4u) +#define FPB_CELLID1_REG *((volatile uint32_t *)0xE0002FF4u) +#define FPB_CELLID1_ADDR (0xE0002FF4u) +#define FPB_CELLID1_RESET (0x000000E0u) +/* CELLID field */ +#define FPB_CELLID1_CELLID (0xFFFFFFFFu) +#define FPB_CELLID1_CELLID_MASK (0xFFFFFFFFu) +#define FPB_CELLID1_CELLID_BIT (0) +#define FPB_CELLID1_CELLID_BITS (32) + +#define FPB_CELLID2 *((volatile uint32_t *)0xE0002FF8u) +#define FPB_CELLID2_REG *((volatile uint32_t *)0xE0002FF8u) +#define FPB_CELLID2_ADDR (0xE0002FF8u) +#define FPB_CELLID2_RESET (0x00000005u) +/* CELLID field */ +#define FPB_CELLID2_CELLID (0xFFFFFFFFu) +#define FPB_CELLID2_CELLID_MASK (0xFFFFFFFFu) +#define FPB_CELLID2_CELLID_BIT (0) +#define FPB_CELLID2_CELLID_BITS (32) + +#define FPB_CELLID3 *((volatile uint32_t *)0xE0002FFCu) +#define FPB_CELLID3_REG *((volatile uint32_t *)0xE0002FFCu) +#define FPB_CELLID3_ADDR (0xE0002FFCu) +#define FPB_CELLID3_RESET (0x000000B1u) +/* CELLID field */ +#define FPB_CELLID3_CELLID (0xFFFFFFFFu) +#define FPB_CELLID3_CELLID_MASK (0xFFFFFFFFu) +#define FPB_CELLID3_CELLID_BIT (0) +#define FPB_CELLID3_CELLID_BITS (32) + +/* NVIC block */ +#define BLOCK_NVIC_BASE (0xE000E000u) +#define BLOCK_NVIC_END (0xE000EFFFu) +#define BLOCK_NVIC_SIZE (BLOCK_NVIC_END - BLOCK_NVIC_BASE + 1) + +#define NVIC_MCR *((volatile uint32_t *)0xE000E000u) +#define NVIC_MCR_REG *((volatile uint32_t *)0xE000E000u) +#define NVIC_MCR_ADDR (0xE000E000u) +#define NVIC_MCR_RESET (0x00000000u) + +#define NVIC_ICTR *((volatile uint32_t *)0xE000E004u) +#define NVIC_ICTR_REG *((volatile uint32_t *)0xE000E004u) +#define NVIC_ICTR_ADDR (0xE000E004u) +#define NVIC_ICTR_RESET (0x00000000u) +/* INTLINESNUM field */ +#define NVIC_ICTR_INTLINESNUM (0x0000001Fu) +#define NVIC_ICTR_INTLINESNUM_MASK (0x0000001Fu) +#define NVIC_ICTR_INTLINESNUM_BIT (0) +#define NVIC_ICTR_INTLINESNUM_BITS (5) + +#define ST_CSR *((volatile uint32_t *)0xE000E010u) +#define ST_CSR_REG *((volatile uint32_t *)0xE000E010u) +#define ST_CSR_ADDR (0xE000E010u) +#define ST_CSR_RESET (0x00000000u) +/* COUNTFLAG field */ +#define ST_CSR_COUNTFLAG (0x00010000u) +#define ST_CSR_COUNTFLAG_MASK (0x00010000u) +#define ST_CSR_COUNTFLAG_BIT (16) +#define ST_CSR_COUNTFLAG_BITS (1) +/* CLKSOURCE field */ +#define ST_CSR_CLKSOURCE (0x00000004u) +#define ST_CSR_CLKSOURCE_MASK (0x00000004u) +#define ST_CSR_CLKSOURCE_BIT (2) +#define ST_CSR_CLKSOURCE_BITS (1) +/* TICKINT field */ +#define ST_CSR_TICKINT (0x00000002u) +#define ST_CSR_TICKINT_MASK (0x00000002u) +#define ST_CSR_TICKINT_BIT (1) +#define ST_CSR_TICKINT_BITS (1) +/* ENABLE field */ +#define ST_CSR_ENABLE (0x00000001u) +#define ST_CSR_ENABLE_MASK (0x00000001u) +#define ST_CSR_ENABLE_BIT (0) +#define ST_CSR_ENABLE_BITS (1) + +#define ST_RVR *((volatile uint32_t *)0xE000E014u) +#define ST_RVR_REG *((volatile uint32_t *)0xE000E014u) +#define ST_RVR_ADDR (0xE000E014u) +#define ST_RVR_RESET (0x00000000u) +/* RELOAD field */ +#define ST_RVR_RELOAD (0x00FFFFFFu) +#define ST_RVR_RELOAD_MASK (0x00FFFFFFu) +#define ST_RVR_RELOAD_BIT (0) +#define ST_RVR_RELOAD_BITS (24) + +#define ST_CVR *((volatile uint32_t *)0xE000E018u) +#define ST_CVR_REG *((volatile uint32_t *)0xE000E018u) +#define ST_CVR_ADDR (0xE000E018u) +#define ST_CVR_RESET (0x00000000u) +/* CURRENT field */ +#define ST_CVR_CURRENT (0xFFFFFFFFu) +#define ST_CVR_CURRENT_MASK (0xFFFFFFFFu) +#define ST_CVR_CURRENT_BIT (0) +#define ST_CVR_CURRENT_BITS (32) + +#define ST_CALVR *((volatile uint32_t *)0xE000E01Cu) +#define ST_CALVR_REG *((volatile uint32_t *)0xE000E01Cu) +#define ST_CALVR_ADDR (0xE000E01Cu) +#define ST_CALVR_RESET (0x00000000u) +/* NOREF field */ +#define ST_CALVR_NOREF (0x80000000u) +#define ST_CALVR_NOREF_MASK (0x80000000u) +#define ST_CALVR_NOREF_BIT (31) +#define ST_CALVR_NOREF_BITS (1) +/* SKEW field */ +#define ST_CALVR_SKEW (0x40000000u) +#define ST_CALVR_SKEW_MASK (0x40000000u) +#define ST_CALVR_SKEW_BIT (30) +#define ST_CALVR_SKEW_BITS (1) +/* TENMS field */ +#define ST_CALVR_TENMS (0x00FFFFFFu) +#define ST_CALVR_TENMS_MASK (0x00FFFFFFu) +#define ST_CALVR_TENMS_BIT (0) +#define ST_CALVR_TENMS_BITS (24) + +#define INT_CFGSET *((volatile uint32_t *)0xE000E100u) +#define INT_CFGSET_REG *((volatile uint32_t *)0xE000E100u) +#define INT_CFGSET_ADDR (0xE000E100u) +#define INT_CFGSET_RESET (0x00000000u) +/* INT_DEBUG field */ +#define INT_DEBUG (0x00010000u) +#define INT_DEBUG_MASK (0x00010000u) +#define INT_DEBUG_BIT (16) +#define INT_DEBUG_BITS (1) +/* INT_IRQD field */ +#define INT_IRQD (0x00008000u) +#define INT_IRQD_MASK (0x00008000u) +#define INT_IRQD_BIT (15) +#define INT_IRQD_BITS (1) +/* INT_IRQC field */ +#define INT_IRQC (0x00004000u) +#define INT_IRQC_MASK (0x00004000u) +#define INT_IRQC_BIT (14) +#define INT_IRQC_BITS (1) +/* INT_IRQB field */ +#define INT_IRQB (0x00002000u) +#define INT_IRQB_MASK (0x00002000u) +#define INT_IRQB_BIT (13) +#define INT_IRQB_BITS (1) +/* INT_IRQA field */ +#define INT_IRQA (0x00001000u) +#define INT_IRQA_MASK (0x00001000u) +#define INT_IRQA_BIT (12) +#define INT_IRQA_BITS (1) +/* INT_ADC field */ +#define INT_ADC (0x00000800u) +#define INT_ADC_MASK (0x00000800u) +#define INT_ADC_BIT (11) +#define INT_ADC_BITS (1) +/* INT_MACRX field */ +#define INT_MACRX (0x00000400u) +#define INT_MACRX_MASK (0x00000400u) +#define INT_MACRX_BIT (10) +#define INT_MACRX_BITS (1) +/* INT_MACTX field */ +#define INT_MACTX (0x00000200u) +#define INT_MACTX_MASK (0x00000200u) +#define INT_MACTX_BIT (9) +#define INT_MACTX_BITS (1) +/* INT_MACTMR field */ +#define INT_MACTMR (0x00000100u) +#define INT_MACTMR_MASK (0x00000100u) +#define INT_MACTMR_BIT (8) +#define INT_MACTMR_BITS (1) +/* INT_SEC field */ +#define INT_SEC (0x00000080u) +#define INT_SEC_MASK (0x00000080u) +#define INT_SEC_BIT (7) +#define INT_SEC_BITS (1) +/* INT_SC2 field */ +#define INT_SC2 (0x00000040u) +#define INT_SC2_MASK (0x00000040u) +#define INT_SC2_BIT (6) +#define INT_SC2_BITS (1) +/* INT_SC1 field */ +#define INT_SC1 (0x00000020u) +#define INT_SC1_MASK (0x00000020u) +#define INT_SC1_BIT (5) +#define INT_SC1_BITS (1) +/* INT_SLEEPTMR field */ +#define INT_SLEEPTMR (0x00000010u) +#define INT_SLEEPTMR_MASK (0x00000010u) +#define INT_SLEEPTMR_BIT (4) +#define INT_SLEEPTMR_BITS (1) +/* INT_BB field */ +#define INT_BB (0x00000008u) +#define INT_BB_MASK (0x00000008u) +#define INT_BB_BIT (3) +#define INT_BB_BITS (1) +/* INT_MGMT field */ +#define INT_MGMT (0x00000004u) +#define INT_MGMT_MASK (0x00000004u) +#define INT_MGMT_BIT (2) +#define INT_MGMT_BITS (1) +/* INT_TIM2 field */ +#define INT_TIM2 (0x00000002u) +#define INT_TIM2_MASK (0x00000002u) +#define INT_TIM2_BIT (1) +#define INT_TIM2_BITS (1) +/* INT_TIM1 field */ +#define INT_TIM1 (0x00000001u) +#define INT_TIM1_MASK (0x00000001u) +#define INT_TIM1_BIT (0) +#define INT_TIM1_BITS (1) + +#define INT_CFGCLR *((volatile uint32_t *)0xE000E180u) +#define INT_CFGCLR_REG *((volatile uint32_t *)0xE000E180u) +#define INT_CFGCLR_ADDR (0xE000E180u) +#define INT_CFGCLR_RESET (0x00000000u) +/* INT_DEBUG field */ +#define INT_DEBUG (0x00010000u) +#define INT_DEBUG_MASK (0x00010000u) +#define INT_DEBUG_BIT (16) +#define INT_DEBUG_BITS (1) +/* INT_IRQD field */ +#define INT_IRQD (0x00008000u) +#define INT_IRQD_MASK (0x00008000u) +#define INT_IRQD_BIT (15) +#define INT_IRQD_BITS (1) +/* INT_IRQC field */ +#define INT_IRQC (0x00004000u) +#define INT_IRQC_MASK (0x00004000u) +#define INT_IRQC_BIT (14) +#define INT_IRQC_BITS (1) +/* INT_IRQB field */ +#define INT_IRQB (0x00002000u) +#define INT_IRQB_MASK (0x00002000u) +#define INT_IRQB_BIT (13) +#define INT_IRQB_BITS (1) +/* INT_IRQA field */ +#define INT_IRQA (0x00001000u) +#define INT_IRQA_MASK (0x00001000u) +#define INT_IRQA_BIT (12) +#define INT_IRQA_BITS (1) +/* INT_ADC field */ +#define INT_ADC (0x00000800u) +#define INT_ADC_MASK (0x00000800u) +#define INT_ADC_BIT (11) +#define INT_ADC_BITS (1) +/* INT_MACRX field */ +#define INT_MACRX (0x00000400u) +#define INT_MACRX_MASK (0x00000400u) +#define INT_MACRX_BIT (10) +#define INT_MACRX_BITS (1) +/* INT_MACTX field */ +#define INT_MACTX (0x00000200u) +#define INT_MACTX_MASK (0x00000200u) +#define INT_MACTX_BIT (9) +#define INT_MACTX_BITS (1) +/* INT_MACTMR field */ +#define INT_MACTMR (0x00000100u) +#define INT_MACTMR_MASK (0x00000100u) +#define INT_MACTMR_BIT (8) +#define INT_MACTMR_BITS (1) +/* INT_SEC field */ +#define INT_SEC (0x00000080u) +#define INT_SEC_MASK (0x00000080u) +#define INT_SEC_BIT (7) +#define INT_SEC_BITS (1) +/* INT_SC2 field */ +#define INT_SC2 (0x00000040u) +#define INT_SC2_MASK (0x00000040u) +#define INT_SC2_BIT (6) +#define INT_SC2_BITS (1) +/* INT_SC1 field */ +#define INT_SC1 (0x00000020u) +#define INT_SC1_MASK (0x00000020u) +#define INT_SC1_BIT (5) +#define INT_SC1_BITS (1) +/* INT_SLEEPTMR field */ +#define INT_SLEEPTMR (0x00000010u) +#define INT_SLEEPTMR_MASK (0x00000010u) +#define INT_SLEEPTMR_BIT (4) +#define INT_SLEEPTMR_BITS (1) +/* INT_BB field */ +#define INT_BB (0x00000008u) +#define INT_BB_MASK (0x00000008u) +#define INT_BB_BIT (3) +#define INT_BB_BITS (1) +/* INT_MGMT field */ +#define INT_MGMT (0x00000004u) +#define INT_MGMT_MASK (0x00000004u) +#define INT_MGMT_BIT (2) +#define INT_MGMT_BITS (1) +/* INT_TIM2 field */ +#define INT_TIM2 (0x00000002u) +#define INT_TIM2_MASK (0x00000002u) +#define INT_TIM2_BIT (1) +#define INT_TIM2_BITS (1) +/* INT_TIM1 field */ +#define INT_TIM1 (0x00000001u) +#define INT_TIM1_MASK (0x00000001u) +#define INT_TIM1_BIT (0) +#define INT_TIM1_BITS (1) + +#define INT_PENDSET *((volatile uint32_t *)0xE000E200u) +#define INT_PENDSET_REG *((volatile uint32_t *)0xE000E200u) +#define INT_PENDSET_ADDR (0xE000E200u) +#define INT_PENDSET_RESET (0x00000000u) +/* INT_DEBUG field */ +#define INT_DEBUG (0x00010000u) +#define INT_DEBUG_MASK (0x00010000u) +#define INT_DEBUG_BIT (16) +#define INT_DEBUG_BITS (1) +/* INT_IRQD field */ +#define INT_IRQD (0x00008000u) +#define INT_IRQD_MASK (0x00008000u) +#define INT_IRQD_BIT (15) +#define INT_IRQD_BITS (1) +/* INT_IRQC field */ +#define INT_IRQC (0x00004000u) +#define INT_IRQC_MASK (0x00004000u) +#define INT_IRQC_BIT (14) +#define INT_IRQC_BITS (1) +/* INT_IRQB field */ +#define INT_IRQB (0x00002000u) +#define INT_IRQB_MASK (0x00002000u) +#define INT_IRQB_BIT (13) +#define INT_IRQB_BITS (1) +/* INT_IRQA field */ +#define INT_IRQA (0x00001000u) +#define INT_IRQA_MASK (0x00001000u) +#define INT_IRQA_BIT (12) +#define INT_IRQA_BITS (1) +/* INT_ADC field */ +#define INT_ADC (0x00000800u) +#define INT_ADC_MASK (0x00000800u) +#define INT_ADC_BIT (11) +#define INT_ADC_BITS (1) +/* INT_MACRX field */ +#define INT_MACRX (0x00000400u) +#define INT_MACRX_MASK (0x00000400u) +#define INT_MACRX_BIT (10) +#define INT_MACRX_BITS (1) +/* INT_MACTX field */ +#define INT_MACTX (0x00000200u) +#define INT_MACTX_MASK (0x00000200u) +#define INT_MACTX_BIT (9) +#define INT_MACTX_BITS (1) +/* INT_MACTMR field */ +#define INT_MACTMR (0x00000100u) +#define INT_MACTMR_MASK (0x00000100u) +#define INT_MACTMR_BIT (8) +#define INT_MACTMR_BITS (1) +/* INT_SEC field */ +#define INT_SEC (0x00000080u) +#define INT_SEC_MASK (0x00000080u) +#define INT_SEC_BIT (7) +#define INT_SEC_BITS (1) +/* INT_SC2 field */ +#define INT_SC2 (0x00000040u) +#define INT_SC2_MASK (0x00000040u) +#define INT_SC2_BIT (6) +#define INT_SC2_BITS (1) +/* INT_SC1 field */ +#define INT_SC1 (0x00000020u) +#define INT_SC1_MASK (0x00000020u) +#define INT_SC1_BIT (5) +#define INT_SC1_BITS (1) +/* INT_SLEEPTMR field */ +#define INT_SLEEPTMR (0x00000010u) +#define INT_SLEEPTMR_MASK (0x00000010u) +#define INT_SLEEPTMR_BIT (4) +#define INT_SLEEPTMR_BITS (1) +/* INT_BB field */ +#define INT_BB (0x00000008u) +#define INT_BB_MASK (0x00000008u) +#define INT_BB_BIT (3) +#define INT_BB_BITS (1) +/* INT_MGMT field */ +#define INT_MGMT (0x00000004u) +#define INT_MGMT_MASK (0x00000004u) +#define INT_MGMT_BIT (2) +#define INT_MGMT_BITS (1) +/* INT_TIM2 field */ +#define INT_TIM2 (0x00000002u) +#define INT_TIM2_MASK (0x00000002u) +#define INT_TIM2_BIT (1) +#define INT_TIM2_BITS (1) +/* INT_TIM1 field */ +#define INT_TIM1 (0x00000001u) +#define INT_TIM1_MASK (0x00000001u) +#define INT_TIM1_BIT (0) +#define INT_TIM1_BITS (1) + +#define INT_PENDCLR *((volatile uint32_t *)0xE000E280u) +#define INT_PENDCLR_REG *((volatile uint32_t *)0xE000E280u) +#define INT_PENDCLR_ADDR (0xE000E280u) +#define INT_PENDCLR_RESET (0x00000000u) +/* INT_DEBUG field */ +#define INT_DEBUG (0x00010000u) +#define INT_DEBUG_MASK (0x00010000u) +#define INT_DEBUG_BIT (16) +#define INT_DEBUG_BITS (1) +/* INT_IRQD field */ +#define INT_IRQD (0x00008000u) +#define INT_IRQD_MASK (0x00008000u) +#define INT_IRQD_BIT (15) +#define INT_IRQD_BITS (1) +/* INT_IRQC field */ +#define INT_IRQC (0x00004000u) +#define INT_IRQC_MASK (0x00004000u) +#define INT_IRQC_BIT (14) +#define INT_IRQC_BITS (1) +/* INT_IRQB field */ +#define INT_IRQB (0x00002000u) +#define INT_IRQB_MASK (0x00002000u) +#define INT_IRQB_BIT (13) +#define INT_IRQB_BITS (1) +/* INT_IRQA field */ +#define INT_IRQA (0x00001000u) +#define INT_IRQA_MASK (0x00001000u) +#define INT_IRQA_BIT (12) +#define INT_IRQA_BITS (1) +/* INT_ADC field */ +#define INT_ADC (0x00000800u) +#define INT_ADC_MASK (0x00000800u) +#define INT_ADC_BIT (11) +#define INT_ADC_BITS (1) +/* INT_MACRX field */ +#define INT_MACRX (0x00000400u) +#define INT_MACRX_MASK (0x00000400u) +#define INT_MACRX_BIT (10) +#define INT_MACRX_BITS (1) +/* INT_MACTX field */ +#define INT_MACTX (0x00000200u) +#define INT_MACTX_MASK (0x00000200u) +#define INT_MACTX_BIT (9) +#define INT_MACTX_BITS (1) +/* INT_MACTMR field */ +#define INT_MACTMR (0x00000100u) +#define INT_MACTMR_MASK (0x00000100u) +#define INT_MACTMR_BIT (8) +#define INT_MACTMR_BITS (1) +/* INT_SEC field */ +#define INT_SEC (0x00000080u) +#define INT_SEC_MASK (0x00000080u) +#define INT_SEC_BIT (7) +#define INT_SEC_BITS (1) +/* INT_SC2 field */ +#define INT_SC2 (0x00000040u) +#define INT_SC2_MASK (0x00000040u) +#define INT_SC2_BIT (6) +#define INT_SC2_BITS (1) +/* INT_SC1 field */ +#define INT_SC1 (0x00000020u) +#define INT_SC1_MASK (0x00000020u) +#define INT_SC1_BIT (5) +#define INT_SC1_BITS (1) +/* INT_SLEEPTMR field */ +#define INT_SLEEPTMR (0x00000010u) +#define INT_SLEEPTMR_MASK (0x00000010u) +#define INT_SLEEPTMR_BIT (4) +#define INT_SLEEPTMR_BITS (1) +/* INT_BB field */ +#define INT_BB (0x00000008u) +#define INT_BB_MASK (0x00000008u) +#define INT_BB_BIT (3) +#define INT_BB_BITS (1) +/* INT_MGMT field */ +#define INT_MGMT (0x00000004u) +#define INT_MGMT_MASK (0x00000004u) +#define INT_MGMT_BIT (2) +#define INT_MGMT_BITS (1) +/* INT_TIM2 field */ +#define INT_TIM2 (0x00000002u) +#define INT_TIM2_MASK (0x00000002u) +#define INT_TIM2_BIT (1) +#define INT_TIM2_BITS (1) +/* INT_TIM1 field */ +#define INT_TIM1 (0x00000001u) +#define INT_TIM1_MASK (0x00000001u) +#define INT_TIM1_BIT (0) +#define INT_TIM1_BITS (1) + +#define INT_ACTIVE *((volatile uint32_t *)0xE000E300u) +#define INT_ACTIVE_REG *((volatile uint32_t *)0xE000E300u) +#define INT_ACTIVE_ADDR (0xE000E300u) +#define INT_ACTIVE_RESET (0x00000000u) +/* INT_DEBUG field */ +#define INT_DEBUG (0x00010000u) +#define INT_DEBUG_MASK (0x00010000u) +#define INT_DEBUG_BIT (16) +#define INT_DEBUG_BITS (1) +/* INT_IRQD field */ +#define INT_IRQD (0x00008000u) +#define INT_IRQD_MASK (0x00008000u) +#define INT_IRQD_BIT (15) +#define INT_IRQD_BITS (1) +/* INT_IRQC field */ +#define INT_IRQC (0x00004000u) +#define INT_IRQC_MASK (0x00004000u) +#define INT_IRQC_BIT (14) +#define INT_IRQC_BITS (1) +/* INT_IRQB field */ +#define INT_IRQB (0x00002000u) +#define INT_IRQB_MASK (0x00002000u) +#define INT_IRQB_BIT (13) +#define INT_IRQB_BITS (1) +/* INT_IRQA field */ +#define INT_IRQA (0x00001000u) +#define INT_IRQA_MASK (0x00001000u) +#define INT_IRQA_BIT (12) +#define INT_IRQA_BITS (1) +/* INT_ADC field */ +#define INT_ADC (0x00000800u) +#define INT_ADC_MASK (0x00000800u) +#define INT_ADC_BIT (11) +#define INT_ADC_BITS (1) +/* INT_MACRX field */ +#define INT_MACRX (0x00000400u) +#define INT_MACRX_MASK (0x00000400u) +#define INT_MACRX_BIT (10) +#define INT_MACRX_BITS (1) +/* INT_MACTX field */ +#define INT_MACTX (0x00000200u) +#define INT_MACTX_MASK (0x00000200u) +#define INT_MACTX_BIT (9) +#define INT_MACTX_BITS (1) +/* INT_MACTMR field */ +#define INT_MACTMR (0x00000100u) +#define INT_MACTMR_MASK (0x00000100u) +#define INT_MACTMR_BIT (8) +#define INT_MACTMR_BITS (1) +/* INT_SEC field */ +#define INT_SEC (0x00000080u) +#define INT_SEC_MASK (0x00000080u) +#define INT_SEC_BIT (7) +#define INT_SEC_BITS (1) +/* INT_SC2 field */ +#define INT_SC2 (0x00000040u) +#define INT_SC2_MASK (0x00000040u) +#define INT_SC2_BIT (6) +#define INT_SC2_BITS (1) +/* INT_SC1 field */ +#define INT_SC1 (0x00000020u) +#define INT_SC1_MASK (0x00000020u) +#define INT_SC1_BIT (5) +#define INT_SC1_BITS (1) +/* INT_SLEEPTMR field */ +#define INT_SLEEPTMR (0x00000010u) +#define INT_SLEEPTMR_MASK (0x00000010u) +#define INT_SLEEPTMR_BIT (4) +#define INT_SLEEPTMR_BITS (1) +/* INT_BB field */ +#define INT_BB (0x00000008u) +#define INT_BB_MASK (0x00000008u) +#define INT_BB_BIT (3) +#define INT_BB_BITS (1) +/* INT_MGMT field */ +#define INT_MGMT (0x00000004u) +#define INT_MGMT_MASK (0x00000004u) +#define INT_MGMT_BIT (2) +#define INT_MGMT_BITS (1) +/* INT_TIM2 field */ +#define INT_TIM2 (0x00000002u) +#define INT_TIM2_MASK (0x00000002u) +#define INT_TIM2_BIT (1) +#define INT_TIM2_BITS (1) +/* INT_TIM1 field */ +#define INT_TIM1 (0x00000001u) +#define INT_TIM1_MASK (0x00000001u) +#define INT_TIM1_BIT (0) +#define INT_TIM1_BITS (1) + +#define NVIC_IPR_3to0 *((volatile uint32_t *)0xE000E400u) +#define NVIC_IPR_3to0_REG *((volatile uint32_t *)0xE000E400u) +#define NVIC_IPR_3to0_ADDR (0xE000E400u) +#define NVIC_IPR_3to0_RESET (0x00000000u) +/* PRI_3 field */ +#define NVIC_IPR_3to0_PRI_3 (0xFF000000u) +#define NVIC_IPR_3to0_PRI_3_MASK (0xFF000000u) +#define NVIC_IPR_3to0_PRI_3_BIT (24) +#define NVIC_IPR_3to0_PRI_3_BITS (8) +/* PRI_2 field */ +#define NVIC_IPR_3to0_PRI_2 (0x00FF0000u) +#define NVIC_IPR_3to0_PRI_2_MASK (0x00FF0000u) +#define NVIC_IPR_3to0_PRI_2_BIT (16) +#define NVIC_IPR_3to0_PRI_2_BITS (8) +/* PRI_1 field */ +#define NVIC_IPR_3to0_PRI_1 (0x0000FF00u) +#define NVIC_IPR_3to0_PRI_1_MASK (0x0000FF00u) +#define NVIC_IPR_3to0_PRI_1_BIT (8) +#define NVIC_IPR_3to0_PRI_1_BITS (8) +/* PRI_0 field */ +#define NVIC_IPR_3to0_PRI_0 (0x000000FFu) +#define NVIC_IPR_3to0_PRI_0_MASK (0x000000FFu) +#define NVIC_IPR_3to0_PRI_0_BIT (0) +#define NVIC_IPR_3to0_PRI_0_BITS (8) + +#define NVIC_IPR_7to4 *((volatile uint32_t *)0xE000E404u) +#define NVIC_IPR_7to4_REG *((volatile uint32_t *)0xE000E404u) +#define NVIC_IPR_7to4_ADDR (0xE000E404u) +#define NVIC_IPR_7to4_RESET (0x00000000u) +/* PRI_7 field */ +#define NVIC_IPR_7to4_PRI_7 (0xFF000000u) +#define NVIC_IPR_7to4_PRI_7_MASK (0xFF000000u) +#define NVIC_IPR_7to4_PRI_7_BIT (24) +#define NVIC_IPR_7to4_PRI_7_BITS (8) +/* PRI_6 field */ +#define NVIC_IPR_7to4_PRI_6 (0x00FF0000u) +#define NVIC_IPR_7to4_PRI_6_MASK (0x00FF0000u) +#define NVIC_IPR_7to4_PRI_6_BIT (16) +#define NVIC_IPR_7to4_PRI_6_BITS (8) +/* PRI_5 field */ +#define NVIC_IPR_7to4_PRI_5 (0x0000FF00u) +#define NVIC_IPR_7to4_PRI_5_MASK (0x0000FF00u) +#define NVIC_IPR_7to4_PRI_5_BIT (8) +#define NVIC_IPR_7to4_PRI_5_BITS (8) +/* PRI_4 field */ +#define NVIC_IPR_7to4_PRI_4 (0x000000FFu) +#define NVIC_IPR_7to4_PRI_4_MASK (0x000000FFu) +#define NVIC_IPR_7to4_PRI_4_BIT (0) +#define NVIC_IPR_7to4_PRI_4_BITS (8) + +#define NVIC_IPR_11to8 *((volatile uint32_t *)0xE000E408u) +#define NVIC_IPR_11to8_REG *((volatile uint32_t *)0xE000E408u) +#define NVIC_IPR_11to8_ADDR (0xE000E408u) +#define NVIC_IPR_11to8_RESET (0x00000000u) +/* PRI_11 field */ +#define NVIC_IPR_11to8_PRI_11 (0xFF000000u) +#define NVIC_IPR_11to8_PRI_11_MASK (0xFF000000u) +#define NVIC_IPR_11to8_PRI_11_BIT (24) +#define NVIC_IPR_11to8_PRI_11_BITS (8) +/* PRI_10 field */ +#define NVIC_IPR_11to8_PRI_10 (0x00FF0000u) +#define NVIC_IPR_11to8_PRI_10_MASK (0x00FF0000u) +#define NVIC_IPR_11to8_PRI_10_BIT (16) +#define NVIC_IPR_11to8_PRI_10_BITS (8) +/* PRI_9 field */ +#define NVIC_IPR_11to8_PRI_9 (0x0000FF00u) +#define NVIC_IPR_11to8_PRI_9_MASK (0x0000FF00u) +#define NVIC_IPR_11to8_PRI_9_BIT (8) +#define NVIC_IPR_11to8_PRI_9_BITS (8) +/* PRI_8 field */ +#define NVIC_IPR_11to8_PRI_8 (0x000000FFu) +#define NVIC_IPR_11to8_PRI_8_MASK (0x000000FFu) +#define NVIC_IPR_11to8_PRI_8_BIT (0) +#define NVIC_IPR_11to8_PRI_8_BITS (8) + +#define NVIC_IPR_15to12 *((volatile uint32_t *)0xE000E40Cu) +#define NVIC_IPR_15to12_REG *((volatile uint32_t *)0xE000E40Cu) +#define NVIC_IPR_15to12_ADDR (0xE000E40Cu) +#define NVIC_IPR_15to12_RESET (0x00000000u) +/* PRI_15 field */ +#define NVIC_IPR_15to12_PRI_15 (0xFF000000u) +#define NVIC_IPR_15to12_PRI_15_MASK (0xFF000000u) +#define NVIC_IPR_15to12_PRI_15_BIT (24) +#define NVIC_IPR_15to12_PRI_15_BITS (8) +/* PRI_14 field */ +#define NVIC_IPR_15to12_PRI_14 (0x00FF0000u) +#define NVIC_IPR_15to12_PRI_14_MASK (0x00FF0000u) +#define NVIC_IPR_15to12_PRI_14_BIT (16) +#define NVIC_IPR_15to12_PRI_14_BITS (8) +/* PRI_13 field */ +#define NVIC_IPR_15to12_PRI_13 (0x0000FF00u) +#define NVIC_IPR_15to12_PRI_13_MASK (0x0000FF00u) +#define NVIC_IPR_15to12_PRI_13_BIT (8) +#define NVIC_IPR_15to12_PRI_13_BITS (8) +/* PRI_12 field */ +#define NVIC_IPR_15to12_PRI_12 (0x000000FFu) +#define NVIC_IPR_15to12_PRI_12_MASK (0x000000FFu) +#define NVIC_IPR_15to12_PRI_12_BIT (0) +#define NVIC_IPR_15to12_PRI_12_BITS (8) + +#define NVIC_IPR_19to16 *((volatile uint32_t *)0xE000E410u) +#define NVIC_IPR_19to16_REG *((volatile uint32_t *)0xE000E410u) +#define NVIC_IPR_19to16_ADDR (0xE000E410u) +#define NVIC_IPR_19to16_RESET (0x00000000u) +/* PRI_19 field */ +#define NVIC_IPR_19to16_PRI_19 (0xFF000000u) +#define NVIC_IPR_19to16_PRI_19_MASK (0xFF000000u) +#define NVIC_IPR_19to16_PRI_19_BIT (24) +#define NVIC_IPR_19to16_PRI_19_BITS (8) +/* PRI_18 field */ +#define NVIC_IPR_19to16_PRI_18 (0x00FF0000u) +#define NVIC_IPR_19to16_PRI_18_MASK (0x00FF0000u) +#define NVIC_IPR_19to16_PRI_18_BIT (16) +#define NVIC_IPR_19to16_PRI_18_BITS (8) +/* PRI_17 field */ +#define NVIC_IPR_19to16_PRI_17 (0x0000FF00u) +#define NVIC_IPR_19to16_PRI_17_MASK (0x0000FF00u) +#define NVIC_IPR_19to16_PRI_17_BIT (8) +#define NVIC_IPR_19to16_PRI_17_BITS (8) +/* PRI_16 field */ +#define NVIC_IPR_19to16_PRI_16 (0x000000FFu) +#define NVIC_IPR_19to16_PRI_16_MASK (0x000000FFu) +#define NVIC_IPR_19to16_PRI_16_BIT (0) +#define NVIC_IPR_19to16_PRI_16_BITS (8) + +#define SCS_CPUID *((volatile uint32_t *)0xE000ED00u) +#define SCS_CPUID_REG *((volatile uint32_t *)0xE000ED00u) +#define SCS_CPUID_ADDR (0xE000ED00u) +#define SCS_CPUID_RESET (0x411FC231u) +/* IMPLEMENTER field */ +#define SCS_CPUID_IMPLEMENTER (0xFF000000u) +#define SCS_CPUID_IMPLEMENTER_MASK (0xFF000000u) +#define SCS_CPUID_IMPLEMENTER_BIT (24) +#define SCS_CPUID_IMPLEMENTER_BITS (8) +/* VARIANT field */ +#define SCS_CPUID_VARIANT (0x00F00000u) +#define SCS_CPUID_VARIANT_MASK (0x00F00000u) +#define SCS_CPUID_VARIANT_BIT (20) +#define SCS_CPUID_VARIANT_BITS (4) +/* CONSTANT field */ +#define SCS_CPUID_CONSTANT (0x000F0000u) +#define SCS_CPUID_CONSTANT_MASK (0x000F0000u) +#define SCS_CPUID_CONSTANT_BIT (16) +#define SCS_CPUID_CONSTANT_BITS (4) +/* PARTNO field */ +#define SCS_CPUID_PARTNO (0x0000FFF0u) +#define SCS_CPUID_PARTNO_MASK (0x0000FFF0u) +#define SCS_CPUID_PARTNO_BIT (4) +#define SCS_CPUID_PARTNO_BITS (12) +/* REVISION field */ +#define SCS_CPUID_REVISION (0x0000000Fu) +#define SCS_CPUID_REVISION_MASK (0x0000000Fu) +#define SCS_CPUID_REVISION_BIT (0) +#define SCS_CPUID_REVISION_BITS (4) + +#define SCS_ICSR *((volatile uint32_t *)0xE000ED04u) +#define SCS_ICSR_REG *((volatile uint32_t *)0xE000ED04u) +#define SCS_ICSR_ADDR (0xE000ED04u) +#define SCS_ICSR_RESET (0x00000000u) +/* NMIPENDSET field */ +#define SCS_ICSR_NMIPENDSET (0x80000000u) +#define SCS_ICSR_NMIPENDSET_MASK (0x80000000u) +#define SCS_ICSR_NMIPENDSET_BIT (31) +#define SCS_ICSR_NMIPENDSET_BITS (1) +/* PENDSVSET field */ +#define SCS_ICSR_PENDSVSET (0x10000000u) +#define SCS_ICSR_PENDSVSET_MASK (0x10000000u) +#define SCS_ICSR_PENDSVSET_BIT (28) +#define SCS_ICSR_PENDSVSET_BITS (1) +/* PENDSVCLR field */ +#define SCS_ICSR_PENDSVCLR (0x08000000u) +#define SCS_ICSR_PENDSVCLR_MASK (0x08000000u) +#define SCS_ICSR_PENDSVCLR_BIT (27) +#define SCS_ICSR_PENDSVCLR_BITS (1) +/* PENDSTSET field */ +#define SCS_ICSR_PENDSTSET (0x04000000u) +#define SCS_ICSR_PENDSTSET_MASK (0x04000000u) +#define SCS_ICSR_PENDSTSET_BIT (26) +#define SCS_ICSR_PENDSTSET_BITS (1) +/* PENDSTCLR field */ +#define SCS_ICSR_PENDSTCLR (0x02000000u) +#define SCS_ICSR_PENDSTCLR_MASK (0x02000000u) +#define SCS_ICSR_PENDSTCLR_BIT (25) +#define SCS_ICSR_PENDSTCLR_BITS (1) +/* ISRPREEMPT field */ +#define SCS_ICSR_ISRPREEMPT (0x00800000u) +#define SCS_ICSR_ISRPREEMPT_MASK (0x00800000u) +#define SCS_ICSR_ISRPREEMPT_BIT (23) +#define SCS_ICSR_ISRPREEMPT_BITS (1) +/* ISRPENDING field */ +#define SCS_ICSR_ISRPENDING (0x00400000u) +#define SCS_ICSR_ISRPENDING_MASK (0x00400000u) +#define SCS_ICSR_ISRPENDING_BIT (22) +#define SCS_ICSR_ISRPENDING_BITS (1) +/* VECTPENDING field */ +#define SCS_ICSR_VECTPENDING (0x001FF000u) +#define SCS_ICSR_VECTPENDING_MASK (0x001FF000u) +#define SCS_ICSR_VECTPENDING_BIT (12) +#define SCS_ICSR_VECTPENDING_BITS (9) +/* RETTOBASE field */ +#define SCS_ICSR_RETTOBASE (0x00000800u) +#define SCS_ICSR_RETTOBASE_MASK (0x00000800u) +#define SCS_ICSR_RETTOBASE_BIT (11) +#define SCS_ICSR_RETTOBASE_BITS (1) +/* VECACTIVE field */ +#define SCS_ICSR_VECACTIVE (0x000001FFu) +#define SCS_ICSR_VECACTIVE_MASK (0x000001FFu) +#define SCS_ICSR_VECACTIVE_BIT (0) +#define SCS_ICSR_VECACTIVE_BITS (9) + +#define SCS_VTOR *((volatile uint32_t *)0xE000ED08u) +#define SCS_VTOR_REG *((volatile uint32_t *)0xE000ED08u) +#define SCS_VTOR_ADDR (0xE000ED08u) +#define SCS_VTOR_RESET (0x00000000u) +/* TBLBASE field */ +#define SCS_VTOR_TBLBASE (0x20000000u) +#define SCS_VTOR_TBLBASE_MASK (0x20000000u) +#define SCS_VTOR_TBLBASE_BIT (29) +#define SCS_VTOR_TBLBASE_BITS (1) +/* TBLOFF field */ +#define SCS_VTOR_TBLOFF (0x1FFFFF00u) +#define SCS_VTOR_TBLOFF_MASK (0x1FFFFF00u) +#define SCS_VTOR_TBLOFF_BIT (8) +#define SCS_VTOR_TBLOFF_BITS (21) + +#define SCS_AIRCR *((volatile uint32_t *)0xE000ED0Cu) +#define SCS_AIRCR_REG *((volatile uint32_t *)0xE000ED0Cu) +#define SCS_AIRCR_ADDR (0xE000ED0Cu) +#define SCS_AIRCR_RESET (0x00000000u) +/* VECTKEYSTAT field */ +#define SCS_AIRCR_VECTKEYSTAT (0xFFFF0000u) +#define SCS_AIRCR_VECTKEYSTAT_MASK (0xFFFF0000u) +#define SCS_AIRCR_VECTKEYSTAT_BIT (16) +#define SCS_AIRCR_VECTKEYSTAT_BITS (16) +/* VECTKEY field */ +#define SCS_AIRCR_VECTKEY (0xFFFF0000u) +#define SCS_AIRCR_VECTKEY_MASK (0xFFFF0000u) +#define SCS_AIRCR_VECTKEY_BIT (16) +#define SCS_AIRCR_VECTKEY_BITS (16) +/* ENDIANESS field */ +#define SCS_AIRCR_ENDIANESS (0x00008000u) +#define SCS_AIRCR_ENDIANESS_MASK (0x00008000u) +#define SCS_AIRCR_ENDIANESS_BIT (15) +#define SCS_AIRCR_ENDIANESS_BITS (1) +/* PRIGROUP field */ +#define SCS_AIRCR_PRIGROUP (0x00000700u) +#define SCS_AIRCR_PRIGROUP_MASK (0x00000700u) +#define SCS_AIRCR_PRIGROUP_BIT (8) +#define SCS_AIRCR_PRIGROUP_BITS (3) +/* SYSRESETREQ field */ +#define SCS_AIRCR_SYSRESETREQ (0x00000004u) +#define SCS_AIRCR_SYSRESETREQ_MASK (0x00000004u) +#define SCS_AIRCR_SYSRESETREQ_BIT (2) +#define SCS_AIRCR_SYSRESETREQ_BITS (1) +/* VECTCLRACTIVE field */ +#define SCS_AIRCR_VECTCLRACTIVE (0x00000002u) +#define SCS_AIRCR_VECTCLRACTIVE_MASK (0x00000002u) +#define SCS_AIRCR_VECTCLRACTIVE_BIT (1) +#define SCS_AIRCR_VECTCLRACTIVE_BITS (1) +/* VECTRESET field */ +#define SCS_AIRCR_VECTRESET (0x00000001u) +#define SCS_AIRCR_VECTRESET_MASK (0x00000001u) +#define SCS_AIRCR_VECTRESET_BIT (0) +#define SCS_AIRCR_VECTRESET_BITS (1) + +#define SCS_SCR *((volatile uint32_t *)0xE000ED10u) +#define SCS_SCR_REG *((volatile uint32_t *)0xE000ED10u) +#define SCS_SCR_ADDR (0xE000ED10u) +#define SCS_SCR_RESET (0x00000000u) +/* SEVONPEND field */ +#define SCS_SCR_SEVONPEND (0x00000010u) +#define SCS_SCR_SEVONPEND_MASK (0x00000010u) +#define SCS_SCR_SEVONPEND_BIT (4) +#define SCS_SCR_SEVONPEND_BITS (1) +/* SLEEPDEEP field */ +#define SCS_SCR_SLEEPDEEP (0x00000004u) +#define SCS_SCR_SLEEPDEEP_MASK (0x00000004u) +#define SCS_SCR_SLEEPDEEP_BIT (2) +#define SCS_SCR_SLEEPDEEP_BITS (1) +/* SLEEPONEXIT field */ +#define SCS_SCR_SLEEPONEXIT (0x00000002u) +#define SCS_SCR_SLEEPONEXIT_MASK (0x00000002u) +#define SCS_SCR_SLEEPONEXIT_BIT (1) +#define SCS_SCR_SLEEPONEXIT_BITS (1) + +#define SCS_CCR *((volatile uint32_t *)0xE000ED14u) +#define SCS_CCR_REG *((volatile uint32_t *)0xE000ED14u) +#define SCS_CCR_ADDR (0xE000ED14u) +#define SCS_CCR_RESET (0x00000000u) +/* STKALIGN field */ +#define SCS_CCR_STKALIGN (0x00000200u) +#define SCS_CCR_STKALIGN_MASK (0x00000200u) +#define SCS_CCR_STKALIGN_BIT (9) +#define SCS_CCR_STKALIGN_BITS (1) +/* BFHFNMIGN field */ +#define SCS_CCR_BFHFNMIGN (0x00000100u) +#define SCS_CCR_BFHFNMIGN_MASK (0x00000100u) +#define SCS_CCR_BFHFNMIGN_BIT (8) +#define SCS_CCR_BFHFNMIGN_BITS (1) +/* DIV_0_TRP field */ +#define SCS_CCR_DIV_0_TRP (0x00000010u) +#define SCS_CCR_DIV_0_TRP_MASK (0x00000010u) +#define SCS_CCR_DIV_0_TRP_BIT (4) +#define SCS_CCR_DIV_0_TRP_BITS (1) +/* UNALIGN_TRP field */ +#define SCS_CCR_UNALIGN_TRP (0x00000008u) +#define SCS_CCR_UNALIGN_TRP_MASK (0x00000008u) +#define SCS_CCR_UNALIGN_TRP_BIT (3) +#define SCS_CCR_UNALIGN_TRP_BITS (1) +/* USERSETMPEND field */ +#define SCS_CCR_USERSETMPEND (0x00000002u) +#define SCS_CCR_USERSETMPEND_MASK (0x00000002u) +#define SCS_CCR_USERSETMPEND_BIT (1) +#define SCS_CCR_USERSETMPEND_BITS (1) +/* NONBASETHRDENA field */ +#define SCS_CCR_NONBASETHRDENA (0x00000001u) +#define SCS_CCR_NONBASETHRDENA_MASK (0x00000001u) +#define SCS_CCR_NONBASETHRDENA_BIT (0) +#define SCS_CCR_NONBASETHRDENA_BITS (1) + +#define SCS_SHPR_7to4 *((volatile uint32_t *)0xE000ED18u) +#define SCS_SHPR_7to4_REG *((volatile uint32_t *)0xE000ED18u) +#define SCS_SHPR_7to4_ADDR (0xE000ED18u) +#define SCS_SHPR_7to4_RESET (0x00000000u) +/* PRI_7 field */ +#define SCS_SHPR_7to4_PRI_7 (0xFF000000u) +#define SCS_SHPR_7to4_PRI_7_MASK (0xFF000000u) +#define SCS_SHPR_7to4_PRI_7_BIT (24) +#define SCS_SHPR_7to4_PRI_7_BITS (8) +/* PRI_6 field */ +#define SCS_SHPR_7to4_PRI_6 (0x00FF0000u) +#define SCS_SHPR_7to4_PRI_6_MASK (0x00FF0000u) +#define SCS_SHPR_7to4_PRI_6_BIT (16) +#define SCS_SHPR_7to4_PRI_6_BITS (8) +/* PRI_5 field */ +#define SCS_SHPR_7to4_PRI_5 (0x0000FF00u) +#define SCS_SHPR_7to4_PRI_5_MASK (0x0000FF00u) +#define SCS_SHPR_7to4_PRI_5_BIT (8) +#define SCS_SHPR_7to4_PRI_5_BITS (8) +/* PRI_4 field */ +#define SCS_SHPR_7to4_PRI_4 (0x000000FFu) +#define SCS_SHPR_7to4_PRI_4_MASK (0x000000FFu) +#define SCS_SHPR_7to4_PRI_4_BIT (0) +#define SCS_SHPR_7to4_PRI_4_BITS (8) + +#define SCS_SHPR_11to8 *((volatile uint32_t *)0xE000ED1Cu) +#define SCS_SHPR_11to8_REG *((volatile uint32_t *)0xE000ED1Cu) +#define SCS_SHPR_11to8_ADDR (0xE000ED1Cu) +#define SCS_SHPR_11to8_RESET (0x00000000u) +/* PRI_11 field */ +#define SCS_SHPR_11to8_PRI_11 (0xFF000000u) +#define SCS_SHPR_11to8_PRI_11_MASK (0xFF000000u) +#define SCS_SHPR_11to8_PRI_11_BIT (24) +#define SCS_SHPR_11to8_PRI_11_BITS (8) +/* PRI_10 field */ +#define SCS_SHPR_11to8_PRI_10 (0x00FF0000u) +#define SCS_SHPR_11to8_PRI_10_MASK (0x00FF0000u) +#define SCS_SHPR_11to8_PRI_10_BIT (16) +#define SCS_SHPR_11to8_PRI_10_BITS (8) +/* PRI_9 field */ +#define SCS_SHPR_11to8_PRI_9 (0x0000FF00u) +#define SCS_SHPR_11to8_PRI_9_MASK (0x0000FF00u) +#define SCS_SHPR_11to8_PRI_9_BIT (8) +#define SCS_SHPR_11to8_PRI_9_BITS (8) +/* PRI_8 field */ +#define SCS_SHPR_11to8_PRI_8 (0x000000FFu) +#define SCS_SHPR_11to8_PRI_8_MASK (0x000000FFu) +#define SCS_SHPR_11to8_PRI_8_BIT (0) +#define SCS_SHPR_11to8_PRI_8_BITS (8) + +#define SCS_SHPR_15to12 *((volatile uint32_t *)0xE000ED20u) +#define SCS_SHPR_15to12_REG *((volatile uint32_t *)0xE000ED20u) +#define SCS_SHPR_15to12_ADDR (0xE000ED20u) +#define SCS_SHPR_15to12_RESET (0x00000000u) +/* PRI_15 field */ +#define SCS_SHPR_15to12_PRI_15 (0xFF000000u) +#define SCS_SHPR_15to12_PRI_15_MASK (0xFF000000u) +#define SCS_SHPR_15to12_PRI_15_BIT (24) +#define SCS_SHPR_15to12_PRI_15_BITS (8) +/* PRI_14 field */ +#define SCS_SHPR_15to12_PRI_14 (0x00FF0000u) +#define SCS_SHPR_15to12_PRI_14_MASK (0x00FF0000u) +#define SCS_SHPR_15to12_PRI_14_BIT (16) +#define SCS_SHPR_15to12_PRI_14_BITS (8) +/* PRI_13 field */ +#define SCS_SHPR_15to12_PRI_13 (0x0000FF00u) +#define SCS_SHPR_15to12_PRI_13_MASK (0x0000FF00u) +#define SCS_SHPR_15to12_PRI_13_BIT (8) +#define SCS_SHPR_15to12_PRI_13_BITS (8) +/* PRI_12 field */ +#define SCS_SHPR_15to12_PRI_12 (0x000000FFu) +#define SCS_SHPR_15to12_PRI_12_MASK (0x000000FFu) +#define SCS_SHPR_15to12_PRI_12_BIT (0) +#define SCS_SHPR_15to12_PRI_12_BITS (8) + +#define SCS_SHCSR *((volatile uint32_t *)0xE000ED24u) +#define SCS_SHCSR_REG *((volatile uint32_t *)0xE000ED24u) +#define SCS_SHCSR_ADDR (0xE000ED24u) +#define SCS_SHCSR_RESET (0x00000000u) +/* USGFAULTENA field */ +#define SCS_SHCSR_USGFAULTENA (0x00040000u) +#define SCS_SHCSR_USGFAULTENA_MASK (0x00040000u) +#define SCS_SHCSR_USGFAULTENA_BIT (18) +#define SCS_SHCSR_USGFAULTENA_BITS (1) +/* BUSFAULTENA field */ +#define SCS_SHCSR_BUSFAULTENA (0x00020000u) +#define SCS_SHCSR_BUSFAULTENA_MASK (0x00020000u) +#define SCS_SHCSR_BUSFAULTENA_BIT (17) +#define SCS_SHCSR_BUSFAULTENA_BITS (1) +/* MEMFAULTENA field */ +#define SCS_SHCSR_MEMFAULTENA (0x00010000u) +#define SCS_SHCSR_MEMFAULTENA_MASK (0x00010000u) +#define SCS_SHCSR_MEMFAULTENA_BIT (16) +#define SCS_SHCSR_MEMFAULTENA_BITS (1) +/* SVCALLPENDED field */ +#define SCS_SHCSR_SVCALLPENDED (0x00008000u) +#define SCS_SHCSR_SVCALLPENDED_MASK (0x00008000u) +#define SCS_SHCSR_SVCALLPENDED_BIT (15) +#define SCS_SHCSR_SVCALLPENDED_BITS (1) +/* BUSFAULTPENDED field */ +#define SCS_SHCSR_BUSFAULTPENDED (0x00004000u) +#define SCS_SHCSR_BUSFAULTPENDED_MASK (0x00004000u) +#define SCS_SHCSR_BUSFAULTPENDED_BIT (14) +#define SCS_SHCSR_BUSFAULTPENDED_BITS (1) +/* MEMFAULTPENDED field */ +#define SCS_SHCSR_MEMFAULTPENDED (0x00002000u) +#define SCS_SHCSR_MEMFAULTPENDED_MASK (0x00002000u) +#define SCS_SHCSR_MEMFAULTPENDED_BIT (13) +#define SCS_SHCSR_MEMFAULTPENDED_BITS (1) +/* USGFAULTPENDED field */ +#define SCS_SHCSR_USGFAULTPENDED (0x00001000u) +#define SCS_SHCSR_USGFAULTPENDED_MASK (0x00001000u) +#define SCS_SHCSR_USGFAULTPENDED_BIT (12) +#define SCS_SHCSR_USGFAULTPENDED_BITS (1) +/* SYSTICKACT field */ +#define SCS_SHCSR_SYSTICKACT (0x00000800u) +#define SCS_SHCSR_SYSTICKACT_MASK (0x00000800u) +#define SCS_SHCSR_SYSTICKACT_BIT (11) +#define SCS_SHCSR_SYSTICKACT_BITS (1) +/* PENDSVACT field */ +#define SCS_SHCSR_PENDSVACT (0x00000400u) +#define SCS_SHCSR_PENDSVACT_MASK (0x00000400u) +#define SCS_SHCSR_PENDSVACT_BIT (10) +#define SCS_SHCSR_PENDSVACT_BITS (1) +/* MONITORACT field */ +#define SCS_SHCSR_MONITORACT (0x00000100u) +#define SCS_SHCSR_MONITORACT_MASK (0x00000100u) +#define SCS_SHCSR_MONITORACT_BIT (8) +#define SCS_SHCSR_MONITORACT_BITS (1) +/* SVCALLACT field */ +#define SCS_SHCSR_SVCALLACT (0x00000080u) +#define SCS_SHCSR_SVCALLACT_MASK (0x00000080u) +#define SCS_SHCSR_SVCALLACT_BIT (7) +#define SCS_SHCSR_SVCALLACT_BITS (1) +/* USGFAULTACT field */ +#define SCS_SHCSR_USGFAULTACT (0x00000008u) +#define SCS_SHCSR_USGFAULTACT_MASK (0x00000008u) +#define SCS_SHCSR_USGFAULTACT_BIT (3) +#define SCS_SHCSR_USGFAULTACT_BITS (1) +/* BUSFAULTACT field */ +#define SCS_SHCSR_BUSFAULTACT (0x00000002u) +#define SCS_SHCSR_BUSFAULTACT_MASK (0x00000002u) +#define SCS_SHCSR_BUSFAULTACT_BIT (1) +#define SCS_SHCSR_BUSFAULTACT_BITS (1) +/* MEMFAULTACT field */ +#define SCS_SHCSR_MEMFAULTACT (0x00000001u) +#define SCS_SHCSR_MEMFAULTACT_MASK (0x00000001u) +#define SCS_SHCSR_MEMFAULTACT_BIT (0) +#define SCS_SHCSR_MEMFAULTACT_BITS (1) + +#define SCS_CFSR *((volatile uint32_t *)0xE000ED28u) +#define SCS_CFSR_REG *((volatile uint32_t *)0xE000ED28u) +#define SCS_CFSR_ADDR (0xE000ED28u) +#define SCS_CFSR_RESET (0x00000000u) +/* DIVBYZERO field */ +#define SCS_CFSR_DIVBYZERO (0x02000000u) +#define SCS_CFSR_DIVBYZERO_MASK (0x02000000u) +#define SCS_CFSR_DIVBYZERO_BIT (25) +#define SCS_CFSR_DIVBYZERO_BITS (1) +/* UNALIGNED field */ +#define SCS_CFSR_UNALIGNED (0x01000000u) +#define SCS_CFSR_UNALIGNED_MASK (0x01000000u) +#define SCS_CFSR_UNALIGNED_BIT (24) +#define SCS_CFSR_UNALIGNED_BITS (1) +/* NOCP field */ +#define SCS_CFSR_NOCP (0x00080000u) +#define SCS_CFSR_NOCP_MASK (0x00080000u) +#define SCS_CFSR_NOCP_BIT (19) +#define SCS_CFSR_NOCP_BITS (1) +/* INVPC field */ +#define SCS_CFSR_INVPC (0x00040000u) +#define SCS_CFSR_INVPC_MASK (0x00040000u) +#define SCS_CFSR_INVPC_BIT (18) +#define SCS_CFSR_INVPC_BITS (1) +/* INVSTATE field */ +#define SCS_CFSR_INVSTATE (0x00020000u) +#define SCS_CFSR_INVSTATE_MASK (0x00020000u) +#define SCS_CFSR_INVSTATE_BIT (17) +#define SCS_CFSR_INVSTATE_BITS (1) +/* UNDEFINSTR field */ +#define SCS_CFSR_UNDEFINSTR (0x00010000u) +#define SCS_CFSR_UNDEFINSTR_MASK (0x00010000u) +#define SCS_CFSR_UNDEFINSTR_BIT (16) +#define SCS_CFSR_UNDEFINSTR_BITS (1) +/* BFARVALID field */ +#define SCS_CFSR_BFARVALID (0x00008000u) +#define SCS_CFSR_BFARVALID_MASK (0x00008000u) +#define SCS_CFSR_BFARVALID_BIT (15) +#define SCS_CFSR_BFARVALID_BITS (1) +/* STKERR field */ +#define SCS_CFSR_STKERR (0x00001000u) +#define SCS_CFSR_STKERR_MASK (0x00001000u) +#define SCS_CFSR_STKERR_BIT (12) +#define SCS_CFSR_STKERR_BITS (1) +/* UNSTKERR field */ +#define SCS_CFSR_UNSTKERR (0x00000800u) +#define SCS_CFSR_UNSTKERR_MASK (0x00000800u) +#define SCS_CFSR_UNSTKERR_BIT (11) +#define SCS_CFSR_UNSTKERR_BITS (1) +/* IMPRECISERR field */ +#define SCS_CFSR_IMPRECISERR (0x00000400u) +#define SCS_CFSR_IMPRECISERR_MASK (0x00000400u) +#define SCS_CFSR_IMPRECISERR_BIT (10) +#define SCS_CFSR_IMPRECISERR_BITS (1) +/* PRECISERR field */ +#define SCS_CFSR_PRECISERR (0x00000200u) +#define SCS_CFSR_PRECISERR_MASK (0x00000200u) +#define SCS_CFSR_PRECISERR_BIT (9) +#define SCS_CFSR_PRECISERR_BITS (1) +/* IBUSERR field */ +#define SCS_CFSR_IBUSERR (0x00000100u) +#define SCS_CFSR_IBUSERR_MASK (0x00000100u) +#define SCS_CFSR_IBUSERR_BIT (8) +#define SCS_CFSR_IBUSERR_BITS (1) +/* MMARVALID field */ +#define SCS_CFSR_MMARVALID (0x00000080u) +#define SCS_CFSR_MMARVALID_MASK (0x00000080u) +#define SCS_CFSR_MMARVALID_BIT (7) +#define SCS_CFSR_MMARVALID_BITS (1) +/* MSTKERR field */ +#define SCS_CFSR_MSTKERR (0x00000010u) +#define SCS_CFSR_MSTKERR_MASK (0x00000010u) +#define SCS_CFSR_MSTKERR_BIT (4) +#define SCS_CFSR_MSTKERR_BITS (1) +/* MUNSTKERR field */ +#define SCS_CFSR_MUNSTKERR (0x00000008u) +#define SCS_CFSR_MUNSTKERR_MASK (0x00000008u) +#define SCS_CFSR_MUNSTKERR_BIT (3) +#define SCS_CFSR_MUNSTKERR_BITS (1) +/* DACCVIOL field */ +#define SCS_CFSR_DACCVIOL (0x00000002u) +#define SCS_CFSR_DACCVIOL_MASK (0x00000002u) +#define SCS_CFSR_DACCVIOL_BIT (1) +#define SCS_CFSR_DACCVIOL_BITS (1) +/* IACCVIOL field */ +#define SCS_CFSR_IACCVIOL (0x00000001u) +#define SCS_CFSR_IACCVIOL_MASK (0x00000001u) +#define SCS_CFSR_IACCVIOL_BIT (0) +#define SCS_CFSR_IACCVIOL_BITS (1) + +#define SCS_HFSR *((volatile uint32_t *)0xE000ED2Cu) +#define SCS_HFSR_REG *((volatile uint32_t *)0xE000ED2Cu) +#define SCS_HFSR_ADDR (0xE000ED2Cu) +#define SCS_HFSR_RESET (0x00000000u) +/* DEBUGEVT field */ +#define SCS_HFSR_DEBUGEVT (0x80000000u) +#define SCS_HFSR_DEBUGEVT_MASK (0x80000000u) +#define SCS_HFSR_DEBUGEVT_BIT (31) +#define SCS_HFSR_DEBUGEVT_BITS (1) +/* FORCED field */ +#define SCS_HFSR_FORCED (0x40000000u) +#define SCS_HFSR_FORCED_MASK (0x40000000u) +#define SCS_HFSR_FORCED_BIT (30) +#define SCS_HFSR_FORCED_BITS (1) +/* VECTTBL field */ +#define SCS_HFSR_VECTTBL (0x00000002u) +#define SCS_HFSR_VECTTBL_MASK (0x00000002u) +#define SCS_HFSR_VECTTBL_BIT (1) +#define SCS_HFSR_VECTTBL_BITS (1) + +#define SCS_DFSR *((volatile uint32_t *)0xE000ED30u) +#define SCS_DFSR_REG *((volatile uint32_t *)0xE000ED30u) +#define SCS_DFSR_ADDR (0xE000ED30u) +#define SCS_DFSR_RESET (0x00000000u) +/* EXTERNAL field */ +#define SCS_DFSR_EXTERNAL (0x00000010u) +#define SCS_DFSR_EXTERNAL_MASK (0x00000010u) +#define SCS_DFSR_EXTERNAL_BIT (4) +#define SCS_DFSR_EXTERNAL_BITS (1) +/* VCATCH field */ +#define SCS_DFSR_VCATCH (0x00000008u) +#define SCS_DFSR_VCATCH_MASK (0x00000008u) +#define SCS_DFSR_VCATCH_BIT (3) +#define SCS_DFSR_VCATCH_BITS (1) +/* DWTTRAP field */ +#define SCS_DFSR_DWTTRAP (0x00000004u) +#define SCS_DFSR_DWTTRAP_MASK (0x00000004u) +#define SCS_DFSR_DWTTRAP_BIT (2) +#define SCS_DFSR_DWTTRAP_BITS (1) +/* BKPT field */ +#define SCS_DFSR_BKPT (0x00000002u) +#define SCS_DFSR_BKPT_MASK (0x00000002u) +#define SCS_DFSR_BKPT_BIT (1) +#define SCS_DFSR_BKPT_BITS (1) +/* HALTED field */ +#define SCS_DFSR_HALTED (0x00000001u) +#define SCS_DFSR_HALTED_MASK (0x00000001u) +#define SCS_DFSR_HALTED_BIT (0) +#define SCS_DFSR_HALTED_BITS (1) + +#define SCS_MMAR *((volatile uint32_t *)0xE000ED34u) +#define SCS_MMAR_REG *((volatile uint32_t *)0xE000ED34u) +#define SCS_MMAR_ADDR (0xE000ED34u) +#define SCS_MMAR_RESET (0x00000000u) +/* ADDRESS field */ +#define SCS_MMAR_ADDRESS (0xFFFFFFFFu) +#define SCS_MMAR_ADDRESS_MASK (0xFFFFFFFFu) +#define SCS_MMAR_ADDRESS_BIT (0) +#define SCS_MMAR_ADDRESS_BITS (32) + +#define SCS_BFAR *((volatile uint32_t *)0xE000ED38u) +#define SCS_BFAR_REG *((volatile uint32_t *)0xE000ED38u) +#define SCS_BFAR_ADDR (0xE000ED38u) +#define SCS_BFAR_RESET (0x00000000u) +/* ADDRESS field */ +#define SCS_BFAR_ADDRESS (0xFFFFFFFFu) +#define SCS_BFAR_ADDRESS_MASK (0xFFFFFFFFu) +#define SCS_BFAR_ADDRESS_BIT (0) +#define SCS_BFAR_ADDRESS_BITS (32) + +#define SCS_AFSR *((volatile uint32_t *)0xE000ED3Cu) +#define SCS_AFSR_REG *((volatile uint32_t *)0xE000ED3Cu) +#define SCS_AFSR_ADDR (0xE000ED3Cu) +#define SCS_AFSR_RESET (0x00000000u) +/* WRONGSIZE field */ +#define SCS_AFSR_WRONGSIZE (0x00000008u) +#define SCS_AFSR_WRONGSIZE_MASK (0x00000008u) +#define SCS_AFSR_WRONGSIZE_BIT (3) +#define SCS_AFSR_WRONGSIZE_BITS (1) +/* PROTECTED field */ +#define SCS_AFSR_PROTECTED (0x00000004u) +#define SCS_AFSR_PROTECTED_MASK (0x00000004u) +#define SCS_AFSR_PROTECTED_BIT (2) +#define SCS_AFSR_PROTECTED_BITS (1) +/* RESERVED field */ +#define SCS_AFSR_RESERVED (0x00000002u) +#define SCS_AFSR_RESERVED_MASK (0x00000002u) +#define SCS_AFSR_RESERVED_BIT (1) +#define SCS_AFSR_RESERVED_BITS (1) +/* MISSED field */ +#define SCS_AFSR_MISSED (0x00000001u) +#define SCS_AFSR_MISSED_MASK (0x00000001u) +#define SCS_AFSR_MISSED_BIT (0) +#define SCS_AFSR_MISSED_BITS (1) + +#define SCS_PFR0 *((volatile uint32_t *)0xE000ED40u) +#define SCS_PFR0_REG *((volatile uint32_t *)0xE000ED40u) +#define SCS_PFR0_ADDR (0xE000ED40u) +#define SCS_PFR0_RESET (0x00000030u) +/* FEATURE field */ +#define SCS_PFR0_FEATURE (0xFFFFFFFFu) +#define SCS_PFR0_FEATURE_MASK (0xFFFFFFFFu) +#define SCS_PFR0_FEATURE_BIT (0) +#define SCS_PFR0_FEATURE_BITS (32) + +#define SCS_PFR1 *((volatile uint32_t *)0xE000ED44u) +#define SCS_PFR1_REG *((volatile uint32_t *)0xE000ED44u) +#define SCS_PFR1_ADDR (0xE000ED44u) +#define SCS_PFR1_RESET (0x00000200u) +/* FEATURE field */ +#define SCS_PFR1_FEATURE (0xFFFFFFFFu) +#define SCS_PFR1_FEATURE_MASK (0xFFFFFFFFu) +#define SCS_PFR1_FEATURE_BIT (0) +#define SCS_PFR1_FEATURE_BITS (32) + +#define SCS_DFR0 *((volatile uint32_t *)0xE000ED48u) +#define SCS_DFR0_REG *((volatile uint32_t *)0xE000ED48u) +#define SCS_DFR0_ADDR (0xE000ED48u) +#define SCS_DFR0_RESET (0x00100000u) +/* FEATURE field */ +#define SCS_DFR0_FEATURE (0xFFFFFFFFu) +#define SCS_DFR0_FEATURE_MASK (0xFFFFFFFFu) +#define SCS_DFR0_FEATURE_BIT (0) +#define SCS_DFR0_FEATURE_BITS (32) + +#define SCS_AFR0 *((volatile uint32_t *)0xE000ED4Cu) +#define SCS_AFR0_REG *((volatile uint32_t *)0xE000ED4Cu) +#define SCS_AFR0_ADDR (0xE000ED4Cu) +#define SCS_AFR0_RESET (0x00000000u) +/* FEATURE field */ +#define SCS_AFR0_FEATURE (0xFFFFFFFFu) +#define SCS_AFR0_FEATURE_MASK (0xFFFFFFFFu) +#define SCS_AFR0_FEATURE_BIT (0) +#define SCS_AFR0_FEATURE_BITS (32) + +#define SCS_MMFR0 *((volatile uint32_t *)0xE000ED50u) +#define SCS_MMFR0_REG *((volatile uint32_t *)0xE000ED50u) +#define SCS_MMFR0_ADDR (0xE000ED50u) +#define SCS_MMFR0_RESET (0x00000030u) +/* FEATURE field */ +#define SCS_MMFR0_FEATURE (0xFFFFFFFFu) +#define SCS_MMFR0_FEATURE_MASK (0xFFFFFFFFu) +#define SCS_MMFR0_FEATURE_BIT (0) +#define SCS_MMFR0_FEATURE_BITS (32) + +#define SCS_MMFR1 *((volatile uint32_t *)0xE000ED54u) +#define SCS_MMFR1_REG *((volatile uint32_t *)0xE000ED54u) +#define SCS_MMFR1_ADDR (0xE000ED54u) +#define SCS_MMFR1_RESET (0x00000000u) +/* FEATURE field */ +#define SCS_MMFR1_FEATURE (0xFFFFFFFFu) +#define SCS_MMFR1_FEATURE_MASK (0xFFFFFFFFu) +#define SCS_MMFR1_FEATURE_BIT (0) +#define SCS_MMFR1_FEATURE_BITS (32) + +#define SCS_MMFR2 *((volatile uint32_t *)0xE000ED58u) +#define SCS_MMFR2_REG *((volatile uint32_t *)0xE000ED58u) +#define SCS_MMFR2_ADDR (0xE000ED58u) +#define SCS_MMFR2_RESET (0x00000000u) +/* FEATURE field */ +#define SCS_MMFR2_FEATURE (0xFFFFFFFFu) +#define SCS_MMFR2_FEATURE_MASK (0xFFFFFFFFu) +#define SCS_MMFR2_FEATURE_BIT (0) +#define SCS_MMFR2_FEATURE_BITS (32) + +#define SCS_MMFR3 *((volatile uint32_t *)0xE000ED5Cu) +#define SCS_MMFR3_REG *((volatile uint32_t *)0xE000ED5Cu) +#define SCS_MMFR3_ADDR (0xE000ED5Cu) +#define SCS_MMFR3_RESET (0x00000000u) +/* FEATURE field */ +#define SCS_MMFR3_FEATURE (0xFFFFFFFFu) +#define SCS_MMFR3_FEATURE_MASK (0xFFFFFFFFu) +#define SCS_MMFR3_FEATURE_BIT (0) +#define SCS_MMFR3_FEATURE_BITS (32) + +#define SCS_ISAFR0 *((volatile uint32_t *)0xE000ED60u) +#define SCS_ISAFR0_REG *((volatile uint32_t *)0xE000ED60u) +#define SCS_ISAFR0_ADDR (0xE000ED60u) +#define SCS_ISAFR0_RESET (0x01141110u) +/* FEATURE field */ +#define SCS_ISAFR0_FEATURE (0xFFFFFFFFu) +#define SCS_ISAFR0_FEATURE_MASK (0xFFFFFFFFu) +#define SCS_ISAFR0_FEATURE_BIT (0) +#define SCS_ISAFR0_FEATURE_BITS (32) + +#define SCS_ISAFR1 *((volatile uint32_t *)0xE000ED64u) +#define SCS_ISAFR1_REG *((volatile uint32_t *)0xE000ED64u) +#define SCS_ISAFR1_ADDR (0xE000ED64u) +#define SCS_ISAFR1_RESET (0x02111000u) +/* FEATURE field */ +#define SCS_ISAFR1_FEATURE (0xFFFFFFFFu) +#define SCS_ISAFR1_FEATURE_MASK (0xFFFFFFFFu) +#define SCS_ISAFR1_FEATURE_BIT (0) +#define SCS_ISAFR1_FEATURE_BITS (32) + +#define SCS_ISAFR2 *((volatile uint32_t *)0xE000ED68u) +#define SCS_ISAFR2_REG *((volatile uint32_t *)0xE000ED68u) +#define SCS_ISAFR2_ADDR (0xE000ED68u) +#define SCS_ISAFR2_RESET (0x21112231u) +/* FEATURE field */ +#define SCS_ISAFR2_FEATURE (0xFFFFFFFFu) +#define SCS_ISAFR2_FEATURE_MASK (0xFFFFFFFFu) +#define SCS_ISAFR2_FEATURE_BIT (0) +#define SCS_ISAFR2_FEATURE_BITS (32) + +#define SCS_ISAFR3 *((volatile uint32_t *)0xE000ED6Cu) +#define SCS_ISAFR3_REG *((volatile uint32_t *)0xE000ED6Cu) +#define SCS_ISAFR3_ADDR (0xE000ED6Cu) +#define SCS_ISAFR3_RESET (0x11111110u) +/* FEATURE field */ +#define SCS_ISAFR3_FEATURE (0xFFFFFFFFu) +#define SCS_ISAFR3_FEATURE_MASK (0xFFFFFFFFu) +#define SCS_ISAFR3_FEATURE_BIT (0) +#define SCS_ISAFR3_FEATURE_BITS (32) + +#define SCS_ISAFR4 *((volatile uint32_t *)0xE000ED70u) +#define SCS_ISAFR4_REG *((volatile uint32_t *)0xE000ED70u) +#define SCS_ISAFR4_ADDR (0xE000ED70u) +#define SCS_ISAFR4_RESET (0x01310102u) +/* FEATURE field */ +#define SCS_ISAFR4_FEATURE (0xFFFFFFFFu) +#define SCS_ISAFR4_FEATURE_MASK (0xFFFFFFFFu) +#define SCS_ISAFR4_FEATURE_BIT (0) +#define SCS_ISAFR4_FEATURE_BITS (32) + +#define MPU_TYPE *((volatile uint32_t *)0xE000ED90u) +#define MPU_TYPE_REG *((volatile uint32_t *)0xE000ED90u) +#define MPU_TYPE_ADDR (0xE000ED90u) +#define MPU_TYPE_RESET (0x00000800u) +/* IREGION field */ +#define MPU_TYPE_IREGION (0x00FF0000u) +#define MPU_TYPE_IREGION_MASK (0x00FF0000u) +#define MPU_TYPE_IREGION_BIT (16) +#define MPU_TYPE_IREGION_BITS (8) +/* DREGION field */ +#define MPU_TYPE_DREGION (0x0000FF00u) +#define MPU_TYPE_DREGION_MASK (0x0000FF00u) +#define MPU_TYPE_DREGION_BIT (8) +#define MPU_TYPE_DREGION_BITS (8) + +#define MPU_CTRL *((volatile uint32_t *)0xE000ED94u) +#define MPU_CTRL_REG *((volatile uint32_t *)0xE000ED94u) +#define MPU_CTRL_ADDR (0xE000ED94u) +#define MPU_CTRL_RESET (0x00000000u) +/* PRIVDEFENA field */ +#define MPU_CTRL_PRIVDEFENA (0x00000004u) +#define MPU_CTRL_PRIVDEFENA_MASK (0x00000004u) +#define MPU_CTRL_PRIVDEFENA_BIT (2) +#define MPU_CTRL_PRIVDEFENA_BITS (1) +/* HFNMIENA field */ +#define MPU_CTRL_HFNMIENA (0x00000002u) +#define MPU_CTRL_HFNMIENA_MASK (0x00000002u) +#define MPU_CTRL_HFNMIENA_BIT (1) +#define MPU_CTRL_HFNMIENA_BITS (1) +/* ENABLE field */ +#define MPU_CTRL_ENABLE (0x00000001u) +#define MPU_CTRL_ENABLE_MASK (0x00000001u) +#define MPU_CTRL_ENABLE_BIT (0) +#define MPU_CTRL_ENABLE_BITS (1) + +#define MPU_REGION *((volatile uint32_t *)0xE000ED98u) +#define MPU_REGION_REG *((volatile uint32_t *)0xE000ED98u) +#define MPU_REGION_ADDR (0xE000ED98u) +#define MPU_REGION_RESET (0x00000000u) +/* REGION field */ +#define MPU_REGION_REGION (0x000000FFu) +#define MPU_REGION_REGION_MASK (0x000000FFu) +#define MPU_REGION_REGION_BIT (0) +#define MPU_REGION_REGION_BITS (8) + +#define MPU_BASE *((volatile uint32_t *)0xE000ED9Cu) +#define MPU_BASE_REG *((volatile uint32_t *)0xE000ED9Cu) +#define MPU_BASE_ADDR (0xE000ED9Cu) +#define MPU_BASE_RESET (0x00000000u) +/* ADDRESS field */ +#define MPU_BASE_ADDRESS (0xFFFFFFE0u) +#define MPU_BASE_ADDRESS_MASK (0xFFFFFFE0u) +#define MPU_BASE_ADDRESS_BIT (5) +#define MPU_BASE_ADDRESS_BITS (27) +/* VALID field */ +#define MPU_BASE_VALID (0x00000010u) +#define MPU_BASE_VALID_MASK (0x00000010u) +#define MPU_BASE_VALID_BIT (4) +#define MPU_BASE_VALID_BITS (1) +/* REGION field */ +#define MPU_BASE_REGION (0x0000000Fu) +#define MPU_BASE_REGION_MASK (0x0000000Fu) +#define MPU_BASE_REGION_BIT (0) +#define MPU_BASE_REGION_BITS (4) + +#define MPU_ATTR *((volatile uint32_t *)0xE000EDA0u) +#define MPU_ATTR_REG *((volatile uint32_t *)0xE000EDA0u) +#define MPU_ATTR_ADDR (0xE000EDA0u) +#define MPU_ATTR_RESET (0x00000000u) +/* XN field */ +#define MPU_ATTR_XN (0x10000000u) +#define MPU_ATTR_XN_MASK (0x10000000u) +#define MPU_ATTR_XN_BIT (28) +#define MPU_ATTR_XN_BITS (1) +/* AP field */ +#define MPU_ATTR_AP (0x07000000u) +#define MPU_ATTR_AP_MASK (0x07000000u) +#define MPU_ATTR_AP_BIT (24) +#define MPU_ATTR_AP_BITS (3) +/* TEX field */ +#define MPU_ATTR_TEX (0x00380000u) +#define MPU_ATTR_TEX_MASK (0x00380000u) +#define MPU_ATTR_TEX_BIT (19) +#define MPU_ATTR_TEX_BITS (3) +/* S field */ +#define MPU_ATTR_S (0x00040000u) +#define MPU_ATTR_S_MASK (0x00040000u) +#define MPU_ATTR_S_BIT (18) +#define MPU_ATTR_S_BITS (1) +/* C field */ +#define MPU_ATTR_C (0x00020000u) +#define MPU_ATTR_C_MASK (0x00020000u) +#define MPU_ATTR_C_BIT (17) +#define MPU_ATTR_C_BITS (1) +/* B field */ +#define MPU_ATTR_B (0x00010000u) +#define MPU_ATTR_B_MASK (0x00010000u) +#define MPU_ATTR_B_BIT (16) +#define MPU_ATTR_B_BITS (1) +/* SRD field */ +#define MPU_ATTR_SRD (0x0000FF00u) +#define MPU_ATTR_SRD_MASK (0x0000FF00u) +#define MPU_ATTR_SRD_BIT (8) +#define MPU_ATTR_SRD_BITS (8) +/* SIZE field */ +#define MPU_ATTR_SIZE (0x0000003Eu) +#define MPU_ATTR_SIZE_MASK (0x0000003Eu) +#define MPU_ATTR_SIZE_BIT (1) +#define MPU_ATTR_SIZE_BITS (5) +/* ENABLE field */ +#define MPU_ATTR_ENABLE (0x00000001u) +#define MPU_ATTR_ENABLE_MASK (0x00000001u) +#define MPU_ATTR_ENABLE_BIT (0) +#define MPU_ATTR_ENABLE_BITS (1) + +#define MPU_BASE1 *((volatile uint32_t *)0xE000EDA4u) +#define MPU_BASE1_REG *((volatile uint32_t *)0xE000EDA4u) +#define MPU_BASE1_ADDR (0xE000EDA4u) +#define MPU_BASE1_RESET (0x00000000u) +/* ADDRESS field */ +#define MPU_BASE1_ADDRESS (0xFFFFFFE0u) +#define MPU_BASE1_ADDRESS_MASK (0xFFFFFFE0u) +#define MPU_BASE1_ADDRESS_BIT (5) +#define MPU_BASE1_ADDRESS_BITS (27) +/* VALID field */ +#define MPU_BASE1_VALID (0x00000010u) +#define MPU_BASE1_VALID_MASK (0x00000010u) +#define MPU_BASE1_VALID_BIT (4) +#define MPU_BASE1_VALID_BITS (1) +/* REGION field */ +#define MPU_BASE1_REGION (0x0000000Fu) +#define MPU_BASE1_REGION_MASK (0x0000000Fu) +#define MPU_BASE1_REGION_BIT (0) +#define MPU_BASE1_REGION_BITS (4) + +#define MPU_ATTR1 *((volatile uint32_t *)0xE000EDA8u) +#define MPU_ATTR1_REG *((volatile uint32_t *)0xE000EDA8u) +#define MPU_ATTR1_ADDR (0xE000EDA8u) +#define MPU_ATTR1_RESET (0x00000000u) +/* XN field */ +#define MPU_ATTR1_XN (0x10000000u) +#define MPU_ATTR1_XN_MASK (0x10000000u) +#define MPU_ATTR1_XN_BIT (28) +#define MPU_ATTR1_XN_BITS (1) +/* AP field */ +#define MPU_ATTR1_AP (0x07000000u) +#define MPU_ATTR1_AP_MASK (0x07000000u) +#define MPU_ATTR1_AP_BIT (24) +#define MPU_ATTR1_AP_BITS (3) +/* TEX field */ +#define MPU_ATTR1_TEX (0x00380000u) +#define MPU_ATTR1_TEX_MASK (0x00380000u) +#define MPU_ATTR1_TEX_BIT (19) +#define MPU_ATTR1_TEX_BITS (3) +/* S field */ +#define MPU_ATTR1_S (0x00040000u) +#define MPU_ATTR1_S_MASK (0x00040000u) +#define MPU_ATTR1_S_BIT (18) +#define MPU_ATTR1_S_BITS (1) +/* C field */ +#define MPU_ATTR1_C (0x00020000u) +#define MPU_ATTR1_C_MASK (0x00020000u) +#define MPU_ATTR1_C_BIT (17) +#define MPU_ATTR1_C_BITS (1) +/* B field */ +#define MPU_ATTR1_B (0x00010000u) +#define MPU_ATTR1_B_MASK (0x00010000u) +#define MPU_ATTR1_B_BIT (16) +#define MPU_ATTR1_B_BITS (1) +/* SRD field */ +#define MPU_ATTR1_SRD (0x0000FF00u) +#define MPU_ATTR1_SRD_MASK (0x0000FF00u) +#define MPU_ATTR1_SRD_BIT (8) +#define MPU_ATTR1_SRD_BITS (8) +/* SIZE field */ +#define MPU_ATTR1_SIZE (0x0000003Eu) +#define MPU_ATTR1_SIZE_MASK (0x0000003Eu) +#define MPU_ATTR1_SIZE_BIT (1) +#define MPU_ATTR1_SIZE_BITS (5) +/* ENABLE field */ +#define MPU_ATTR1_ENABLE (0x00000001u) +#define MPU_ATTR1_ENABLE_MASK (0x00000001u) +#define MPU_ATTR1_ENABLE_BIT (0) +#define MPU_ATTR1_ENABLE_BITS (1) + +#define MPU_BASE2 *((volatile uint32_t *)0xE000EDACu) +#define MPU_BASE2_REG *((volatile uint32_t *)0xE000EDACu) +#define MPU_BASE2_ADDR (0xE000EDACu) +#define MPU_BASE2_RESET (0x00000000u) +/* ADDRESS field */ +#define MPU_BASE2_ADDRESS (0xFFFFFFE0u) +#define MPU_BASE2_ADDRESS_MASK (0xFFFFFFE0u) +#define MPU_BASE2_ADDRESS_BIT (5) +#define MPU_BASE2_ADDRESS_BITS (27) +/* VALID field */ +#define MPU_BASE2_VALID (0x00000010u) +#define MPU_BASE2_VALID_MASK (0x00000010u) +#define MPU_BASE2_VALID_BIT (4) +#define MPU_BASE2_VALID_BITS (1) +/* REGION field */ +#define MPU_BASE2_REGION (0x0000000Fu) +#define MPU_BASE2_REGION_MASK (0x0000000Fu) +#define MPU_BASE2_REGION_BIT (0) +#define MPU_BASE2_REGION_BITS (4) + +#define MPU_ATTR2 *((volatile uint32_t *)0xE000EDB0u) +#define MPU_ATTR2_REG *((volatile uint32_t *)0xE000EDB0u) +#define MPU_ATTR2_ADDR (0xE000EDB0u) +#define MPU_ATTR2_RESET (0x00000000u) +/* XN field */ +#define MPU_ATTR2_XN (0x10000000u) +#define MPU_ATTR2_XN_MASK (0x10000000u) +#define MPU_ATTR2_XN_BIT (28) +#define MPU_ATTR2_XN_BITS (1) +/* AP field */ +#define MPU_ATTR2_AP (0x1F000000u) +#define MPU_ATTR2_AP_MASK (0x1F000000u) +#define MPU_ATTR2_AP_BIT (24) +#define MPU_ATTR2_AP_BITS (5) +/* TEX field */ +#define MPU_ATTR2_TEX (0x00380000u) +#define MPU_ATTR2_TEX_MASK (0x00380000u) +#define MPU_ATTR2_TEX_BIT (19) +#define MPU_ATTR2_TEX_BITS (3) +/* S field */ +#define MPU_ATTR2_S (0x00040000u) +#define MPU_ATTR2_S_MASK (0x00040000u) +#define MPU_ATTR2_S_BIT (18) +#define MPU_ATTR2_S_BITS (1) +/* C field */ +#define MPU_ATTR2_C (0x00020000u) +#define MPU_ATTR2_C_MASK (0x00020000u) +#define MPU_ATTR2_C_BIT (17) +#define MPU_ATTR2_C_BITS (1) +/* B field */ +#define MPU_ATTR2_B (0x00010000u) +#define MPU_ATTR2_B_MASK (0x00010000u) +#define MPU_ATTR2_B_BIT (16) +#define MPU_ATTR2_B_BITS (1) +/* SRD field */ +#define MPU_ATTR2_SRD (0x0000FF00u) +#define MPU_ATTR2_SRD_MASK (0x0000FF00u) +#define MPU_ATTR2_SRD_BIT (8) +#define MPU_ATTR2_SRD_BITS (8) +/* SIZE field */ +#define MPU_ATTR2_SIZE (0x0000003Eu) +#define MPU_ATTR2_SIZE_MASK (0x0000003Eu) +#define MPU_ATTR2_SIZE_BIT (1) +#define MPU_ATTR2_SIZE_BITS (5) +/* ENABLE field */ +#define MPU_ATTR2_ENABLE (0x00000003u) +#define MPU_ATTR2_ENABLE_MASK (0x00000003u) +#define MPU_ATTR2_ENABLE_BIT (0) +#define MPU_ATTR2_ENABLE_BITS (2) + +#define MPU_BASE3 *((volatile uint32_t *)0xE000EDB4u) +#define MPU_BASE3_REG *((volatile uint32_t *)0xE000EDB4u) +#define MPU_BASE3_ADDR (0xE000EDB4u) +#define MPU_BASE3_RESET (0x00000000u) +/* ADDRESS field */ +#define MPU_BASE3_ADDRESS (0xFFFFFFE0u) +#define MPU_BASE3_ADDRESS_MASK (0xFFFFFFE0u) +#define MPU_BASE3_ADDRESS_BIT (5) +#define MPU_BASE3_ADDRESS_BITS (27) +/* VALID field */ +#define MPU_BASE3_VALID (0x00000010u) +#define MPU_BASE3_VALID_MASK (0x00000010u) +#define MPU_BASE3_VALID_BIT (4) +#define MPU_BASE3_VALID_BITS (1) +/* REGION field */ +#define MPU_BASE3_REGION (0x0000000Fu) +#define MPU_BASE3_REGION_MASK (0x0000000Fu) +#define MPU_BASE3_REGION_BIT (0) +#define MPU_BASE3_REGION_BITS (4) + +#define MPU_ATTR3 *((volatile uint32_t *)0xE000EDBCu) +#define MPU_ATTR3_REG *((volatile uint32_t *)0xE000EDBCu) +#define MPU_ATTR3_ADDR (0xE000EDBCu) +#define MPU_ATTR3_RESET (0x00000000u) +/* XN field */ +#define MPU_ATTR3_XN (0x10000000u) +#define MPU_ATTR3_XN_MASK (0x10000000u) +#define MPU_ATTR3_XN_BIT (28) +#define MPU_ATTR3_XN_BITS (1) +/* AP field */ +#define MPU_ATTR3_AP (0x1F000000u) +#define MPU_ATTR3_AP_MASK (0x1F000000u) +#define MPU_ATTR3_AP_BIT (24) +#define MPU_ATTR3_AP_BITS (5) +/* TEX field */ +#define MPU_ATTR3_TEX (0x00380000u) +#define MPU_ATTR3_TEX_MASK (0x00380000u) +#define MPU_ATTR3_TEX_BIT (19) +#define MPU_ATTR3_TEX_BITS (3) +/* S field */ +#define MPU_ATTR3_S (0x00040000u) +#define MPU_ATTR3_S_MASK (0x00040000u) +#define MPU_ATTR3_S_BIT (18) +#define MPU_ATTR3_S_BITS (1) +/* C field */ +#define MPU_ATTR3_C (0x00020000u) +#define MPU_ATTR3_C_MASK (0x00020000u) +#define MPU_ATTR3_C_BIT (17) +#define MPU_ATTR3_C_BITS (1) +/* B field */ +#define MPU_ATTR3_B (0x00010000u) +#define MPU_ATTR3_B_MASK (0x00010000u) +#define MPU_ATTR3_B_BIT (16) +#define MPU_ATTR3_B_BITS (1) +/* SRD field */ +#define MPU_ATTR3_SRD (0x0000FF00u) +#define MPU_ATTR3_SRD_MASK (0x0000FF00u) +#define MPU_ATTR3_SRD_BIT (8) +#define MPU_ATTR3_SRD_BITS (8) +/* SIZE field */ +#define MPU_ATTR3_SIZE (0x0000003Eu) +#define MPU_ATTR3_SIZE_MASK (0x0000003Eu) +#define MPU_ATTR3_SIZE_BIT (1) +#define MPU_ATTR3_SIZE_BITS (5) +/* ENABLE field */ +#define MPU_ATTR3_ENABLE (0x00000003u) +#define MPU_ATTR3_ENABLE_MASK (0x00000003u) +#define MPU_ATTR3_ENABLE_BIT (0) +#define MPU_ATTR3_ENABLE_BITS (2) + +#define DEBUG_HCSR *((volatile uint32_t *)0xE000EDF0u) +#define DEBUG_HCSR_REG *((volatile uint32_t *)0xE000EDF0u) +#define DEBUG_HCSR_ADDR (0xE000EDF0u) +#define DEBUG_HCSR_RESET (0x00000000u) +/* S_RESET_ST field */ +#define DEBUG_HCSR_S_RESET_ST (0x02000000u) +#define DEBUG_HCSR_S_RESET_ST_MASK (0x02000000u) +#define DEBUG_HCSR_S_RESET_ST_BIT (25) +#define DEBUG_HCSR_S_RESET_ST_BITS (1) +/* S_RETIRE_ST field */ +#define DEBUG_HCSR_S_RETIRE_ST (0x01000000u) +#define DEBUG_HCSR_S_RETIRE_ST_MASK (0x01000000u) +#define DEBUG_HCSR_S_RETIRE_ST_BIT (24) +#define DEBUG_HCSR_S_RETIRE_ST_BITS (1) +/* S_LOCKUP field */ +#define DEBUG_HCSR_S_LOCKUP (0x00080000u) +#define DEBUG_HCSR_S_LOCKUP_MASK (0x00080000u) +#define DEBUG_HCSR_S_LOCKUP_BIT (19) +#define DEBUG_HCSR_S_LOCKUP_BITS (1) +/* S_SLEEP field */ +#define DEBUG_HCSR_S_SLEEP (0x00040000u) +#define DEBUG_HCSR_S_SLEEP_MASK (0x00040000u) +#define DEBUG_HCSR_S_SLEEP_BIT (18) +#define DEBUG_HCSR_S_SLEEP_BITS (1) +/* S_HALT field */ +#define DEBUG_HCSR_S_HALT (0x00020000u) +#define DEBUG_HCSR_S_HALT_MASK (0x00020000u) +#define DEBUG_HCSR_S_HALT_BIT (17) +#define DEBUG_HCSR_S_HALT_BITS (1) +/* S_REGRDY field */ +#define DEBUG_HCSR_S_REGRDY (0x00010000u) +#define DEBUG_HCSR_S_REGRDY_MASK (0x00010000u) +#define DEBUG_HCSR_S_REGRDY_BIT (16) +#define DEBUG_HCSR_S_REGRDY_BITS (1) +/* DBGKEY field */ +#define DEBUG_HCSR_DBGKEY (0xFFFF0000u) +#define DEBUG_HCSR_DBGKEY_MASK (0xFFFF0000u) +#define DEBUG_HCSR_DBGKEY_BIT (16) +#define DEBUG_HCSR_DBGKEY_BITS (16) +/* C_SNAPSTALL field */ +#define DEBUG_HCSR_C_SNAPSTALL (0x00000020u) +#define DEBUG_HCSR_C_SNAPSTALL_MASK (0x00000020u) +#define DEBUG_HCSR_C_SNAPSTALL_BIT (5) +#define DEBUG_HCSR_C_SNAPSTALL_BITS (1) +/* C_MASKINTS field */ +#define DEBUG_HCSR_C_MASKINTS (0x00000008u) +#define DEBUG_HCSR_C_MASKINTS_MASK (0x00000008u) +#define DEBUG_HCSR_C_MASKINTS_BIT (3) +#define DEBUG_HCSR_C_MASKINTS_BITS (1) +/* C_STEP field */ +#define DEBUG_HCSR_C_STEP (0x00000004u) +#define DEBUG_HCSR_C_STEP_MASK (0x00000004u) +#define DEBUG_HCSR_C_STEP_BIT (2) +#define DEBUG_HCSR_C_STEP_BITS (1) +/* C_HALT field */ +#define DEBUG_HCSR_C_HALT (0x00000002u) +#define DEBUG_HCSR_C_HALT_MASK (0x00000002u) +#define DEBUG_HCSR_C_HALT_BIT (1) +#define DEBUG_HCSR_C_HALT_BITS (1) +/* C_DEBUGEN field */ +#define DEBUG_HCSR_C_DEBUGEN (0x00000001u) +#define DEBUG_HCSR_C_DEBUGEN_MASK (0x00000001u) +#define DEBUG_HCSR_C_DEBUGEN_BIT (0) +#define DEBUG_HCSR_C_DEBUGEN_BITS (1) + +#define DEBUG_CRSR *((volatile uint32_t *)0xE000EDF4u) +#define DEBUG_CRSR_REG *((volatile uint32_t *)0xE000EDF4u) +#define DEBUG_CRSR_ADDR (0xE000EDF4u) +#define DEBUG_CRSR_RESET (0x00000000u) +/* REGWnR field */ +#define DEBUG_CRSR_REGWnR (0x00010000u) +#define DEBUG_CRSR_REGWnR_MASK (0x00010000u) +#define DEBUG_CRSR_REGWnR_BIT (16) +#define DEBUG_CRSR_REGWnR_BITS (1) +/* REGSEL field */ +#define DEBUG_CRSR_REGSEL (0x0000001Fu) +#define DEBUG_CRSR_REGSEL_MASK (0x0000001Fu) +#define DEBUG_CRSR_REGSEL_BIT (0) +#define DEBUG_CRSR_REGSEL_BITS (5) + +#define DEBUG_CRDR *((volatile uint32_t *)0xE000EDF8u) +#define DEBUG_CRDR_REG *((volatile uint32_t *)0xE000EDF8u) +#define DEBUG_CRDR_ADDR (0xE000EDF8u) +#define DEBUG_CRDR_RESET (0x00000000u) +/* DBGTMP field */ +#define DEBUG_CRDR_DBGTMP (0xFFFFFFFFu) +#define DEBUG_CRDR_DBGTMP_MASK (0xFFFFFFFFu) +#define DEBUG_CRDR_DBGTMP_BIT (0) +#define DEBUG_CRDR_DBGTMP_BITS (32) + +#define DEBUG_EMCR *((volatile uint32_t *)0xE000EDFCu) +#define DEBUG_EMCR_REG *((volatile uint32_t *)0xE000EDFCu) +#define DEBUG_EMCR_ADDR (0xE000EDFCu) +#define DEBUG_EMCR_RESET (0x00000000u) +/* TRCENA field */ +#define DEBUG_EMCR_TRCENA (0x01000000u) +#define DEBUG_EMCR_TRCENA_MASK (0x01000000u) +#define DEBUG_EMCR_TRCENA_BIT (24) +#define DEBUG_EMCR_TRCENA_BITS (1) +/* MON_REQ field */ +#define DEBUG_EMCR_MON_REQ (0x00080000u) +#define DEBUG_EMCR_MON_REQ_MASK (0x00080000u) +#define DEBUG_EMCR_MON_REQ_BIT (19) +#define DEBUG_EMCR_MON_REQ_BITS (1) +/* MON_STEP field */ +#define DEBUG_EMCR_MON_STEP (0x00040000u) +#define DEBUG_EMCR_MON_STEP_MASK (0x00040000u) +#define DEBUG_EMCR_MON_STEP_BIT (18) +#define DEBUG_EMCR_MON_STEP_BITS (1) +/* MON_PEND field */ +#define DEBUG_EMCR_MON_PEND (0x00020000u) +#define DEBUG_EMCR_MON_PEND_MASK (0x00020000u) +#define DEBUG_EMCR_MON_PEND_BIT (17) +#define DEBUG_EMCR_MON_PEND_BITS (1) +/* MON_EN field */ +#define DEBUG_EMCR_MON_EN (0x00010000u) +#define DEBUG_EMCR_MON_EN_MASK (0x00010000u) +#define DEBUG_EMCR_MON_EN_BIT (16) +#define DEBUG_EMCR_MON_EN_BITS (1) +/* VC_HARDERR field */ +#define DEBUG_EMCR_VC_HARDERR (0x00000400u) +#define DEBUG_EMCR_VC_HARDERR_MASK (0x00000400u) +#define DEBUG_EMCR_VC_HARDERR_BIT (10) +#define DEBUG_EMCR_VC_HARDERR_BITS (1) +/* VC_INTERR field */ +#define DEBUG_EMCR_VC_INTERR (0x00000200u) +#define DEBUG_EMCR_VC_INTERR_MASK (0x00000200u) +#define DEBUG_EMCR_VC_INTERR_BIT (9) +#define DEBUG_EMCR_VC_INTERR_BITS (1) +/* VC_BUSERR field */ +#define DEBUG_EMCR_VC_BUSERR (0x00000100u) +#define DEBUG_EMCR_VC_BUSERR_MASK (0x00000100u) +#define DEBUG_EMCR_VC_BUSERR_BIT (8) +#define DEBUG_EMCR_VC_BUSERR_BITS (1) +/* VC_STATERR field */ +#define DEBUG_EMCR_VC_STATERR (0x00000080u) +#define DEBUG_EMCR_VC_STATERR_MASK (0x00000080u) +#define DEBUG_EMCR_VC_STATERR_BIT (7) +#define DEBUG_EMCR_VC_STATERR_BITS (1) +/* VC_CHKERR field */ +#define DEBUG_EMCR_VC_CHKERR (0x00000040u) +#define DEBUG_EMCR_VC_CHKERR_MASK (0x00000040u) +#define DEBUG_EMCR_VC_CHKERR_BIT (6) +#define DEBUG_EMCR_VC_CHKERR_BITS (1) +/* VC_NOCPERR field */ +#define DEBUG_EMCR_VC_NOCPERR (0x00000020u) +#define DEBUG_EMCR_VC_NOCPERR_MASK (0x00000020u) +#define DEBUG_EMCR_VC_NOCPERR_BIT (5) +#define DEBUG_EMCR_VC_NOCPERR_BITS (1) +/* VC_MMERR field */ +#define DEBUG_EMCR_VC_MMERR (0x00000010u) +#define DEBUG_EMCR_VC_MMERR_MASK (0x00000010u) +#define DEBUG_EMCR_VC_MMERR_BIT (4) +#define DEBUG_EMCR_VC_MMERR_BITS (1) +/* VC_CORERESET field */ +#define DEBUG_EMCR_VC_CORERESET (0x00000001u) +#define DEBUG_EMCR_VC_CORERESET_MASK (0x00000001u) +#define DEBUG_EMCR_VC_CORERESET_BIT (0) +#define DEBUG_EMCR_VC_CORERESET_BITS (1) + +#define NVIC_STIR *((volatile uint32_t *)0xE000EF00u) +#define NVIC_STIR_REG *((volatile uint32_t *)0xE000EF00u) +#define NVIC_STIR_ADDR (0xE000EF00u) +#define NVIC_STIR_RESET (0x00000000u) +/* INTID field */ +#define NVIC_STIR_INTID (0x000003FFu) +#define NVIC_STIR_INTID_MASK (0x000003FFu) +#define NVIC_STIR_INTID_BIT (0) +#define NVIC_STIR_INTID_BITS (10) + +#define NVIC_PERIPHID4 *((volatile uint32_t *)0xE000EFD0u) +#define NVIC_PERIPHID4_REG *((volatile uint32_t *)0xE000EFD0u) +#define NVIC_PERIPHID4_ADDR (0xE000EFD0u) +#define NVIC_PERIPHID4_RESET (0x00000004u) +/* PERIPHID field */ +#define NVIC_PERIPHID4_PERIPHID (0xFFFFFFFFu) +#define NVIC_PERIPHID4_PERIPHID_MASK (0xFFFFFFFFu) +#define NVIC_PERIPHID4_PERIPHID_BIT (0) +#define NVIC_PERIPHID4_PERIPHID_BITS (32) + +#define NVIC_PERIPHID5 *((volatile uint32_t *)0xE000EFD4u) +#define NVIC_PERIPHID5_REG *((volatile uint32_t *)0xE000EFD4u) +#define NVIC_PERIPHID5_ADDR (0xE000EFD4u) +#define NVIC_PERIPHID5_RESET (0x00000000u) +/* PERIPHID field */ +#define NVIC_PERIPHID5_PERIPHID (0xFFFFFFFFu) +#define NVIC_PERIPHID5_PERIPHID_MASK (0xFFFFFFFFu) +#define NVIC_PERIPHID5_PERIPHID_BIT (0) +#define NVIC_PERIPHID5_PERIPHID_BITS (32) + +#define NVIC_PERIPHID6 *((volatile uint32_t *)0xE000EFD8u) +#define NVIC_PERIPHID6_REG *((volatile uint32_t *)0xE000EFD8u) +#define NVIC_PERIPHID6_ADDR (0xE000EFD8u) +#define NVIC_PERIPHID6_RESET (0x00000000u) +/* PERIPHID field */ +#define NVIC_PERIPHID6_PERIPHID (0xFFFFFFFFu) +#define NVIC_PERIPHID6_PERIPHID_MASK (0xFFFFFFFFu) +#define NVIC_PERIPHID6_PERIPHID_BIT (0) +#define NVIC_PERIPHID6_PERIPHID_BITS (32) + +#define NVIC_PERIPHID7 *((volatile uint32_t *)0xE000EFDCu) +#define NVIC_PERIPHID7_REG *((volatile uint32_t *)0xE000EFDCu) +#define NVIC_PERIPHID7_ADDR (0xE000EFDCu) +#define NVIC_PERIPHID7_RESET (0x00000000u) +/* PERIPHID field */ +#define NVIC_PERIPHID7_PERIPHID (0xFFFFFFFFu) +#define NVIC_PERIPHID7_PERIPHID_MASK (0xFFFFFFFFu) +#define NVIC_PERIPHID7_PERIPHID_BIT (0) +#define NVIC_PERIPHID7_PERIPHID_BITS (32) + +#define NVIC_PERIPHID0 *((volatile uint32_t *)0xE000EFE0u) +#define NVIC_PERIPHID0_REG *((volatile uint32_t *)0xE000EFE0u) +#define NVIC_PERIPHID0_ADDR (0xE000EFE0u) +#define NVIC_PERIPHID0_RESET (0x00000000u) +/* PERIPHID field */ +#define NVIC_PERIPHID0_PERIPHID (0xFFFFFFFFu) +#define NVIC_PERIPHID0_PERIPHID_MASK (0xFFFFFFFFu) +#define NVIC_PERIPHID0_PERIPHID_BIT (0) +#define NVIC_PERIPHID0_PERIPHID_BITS (32) + +#define NVIC_PERIPHID1 *((volatile uint32_t *)0xE000EFE4u) +#define NVIC_PERIPHID1_REG *((volatile uint32_t *)0xE000EFE4u) +#define NVIC_PERIPHID1_ADDR (0xE000EFE4u) +#define NVIC_PERIPHID1_RESET (0x000000B0u) +/* PERIPHID field */ +#define NVIC_PERIPHID1_PERIPHID (0xFFFFFFFFu) +#define NVIC_PERIPHID1_PERIPHID_MASK (0xFFFFFFFFu) +#define NVIC_PERIPHID1_PERIPHID_BIT (0) +#define NVIC_PERIPHID1_PERIPHID_BITS (32) + +#define NVIC_PERIPHID2 *((volatile uint32_t *)0xE000EFE8u) +#define NVIC_PERIPHID2_REG *((volatile uint32_t *)0xE000EFE8u) +#define NVIC_PERIPHID2_ADDR (0xE000EFE8u) +#define NVIC_PERIPHID2_RESET (0x0000001Bu) +/* PERIPHID field */ +#define NVIC_PERIPHID2_PERIPHID (0xFFFFFFFFu) +#define NVIC_PERIPHID2_PERIPHID_MASK (0xFFFFFFFFu) +#define NVIC_PERIPHID2_PERIPHID_BIT (0) +#define NVIC_PERIPHID2_PERIPHID_BITS (32) + +#define NVIC_PERIPHID3 *((volatile uint32_t *)0xE000EFECu) +#define NVIC_PERIPHID3_REG *((volatile uint32_t *)0xE000EFECu) +#define NVIC_PERIPHID3_ADDR (0xE000EFECu) +#define NVIC_PERIPHID3_RESET (0x00000000u) +/* PERIPHID field */ +#define NVIC_PERIPHID3_PERIPHID (0xFFFFFFFFu) +#define NVIC_PERIPHID3_PERIPHID_MASK (0xFFFFFFFFu) +#define NVIC_PERIPHID3_PERIPHID_BIT (0) +#define NVIC_PERIPHID3_PERIPHID_BITS (32) + +#define NVIC_PCELLID0 *((volatile uint32_t *)0xE000EFF0u) +#define NVIC_PCELLID0_REG *((volatile uint32_t *)0xE000EFF0u) +#define NVIC_PCELLID0_ADDR (0xE000EFF0u) +#define NVIC_PCELLID0_RESET (0x0000000Du) +/* PCELLID field */ +#define NVIC_PCELLID0_PCELLID (0xFFFFFFFFu) +#define NVIC_PCELLID0_PCELLID_MASK (0xFFFFFFFFu) +#define NVIC_PCELLID0_PCELLID_BIT (0) +#define NVIC_PCELLID0_PCELLID_BITS (32) + +#define NVIC_PCELLID1 *((volatile uint32_t *)0xE000EFF4u) +#define NVIC_PCELLID1_REG *((volatile uint32_t *)0xE000EFF4u) +#define NVIC_PCELLID1_ADDR (0xE000EFF4u) +#define NVIC_PCELLID1_RESET (0x000000E0u) +/* PCELLID field */ +#define NVIC_PCELLID1_PCELLID (0xFFFFFFFFu) +#define NVIC_PCELLID1_PCELLID_MASK (0xFFFFFFFFu) +#define NVIC_PCELLID1_PCELLID_BIT (0) +#define NVIC_PCELLID1_PCELLID_BITS (32) + +#define NVIC_PCELLID2 *((volatile uint32_t *)0xE000EFF8u) +#define NVIC_PCELLID2_REG *((volatile uint32_t *)0xE000EFF8u) +#define NVIC_PCELLID2_ADDR (0xE000EFF8u) +#define NVIC_PCELLID2_RESET (0x00000005u) +/* PCELLID field */ +#define NVIC_PCELLID2_PCELLID (0xFFFFFFFFu) +#define NVIC_PCELLID2_PCELLID_MASK (0xFFFFFFFFu) +#define NVIC_PCELLID2_PCELLID_BIT (0) +#define NVIC_PCELLID2_PCELLID_BITS (32) + +#define NVIC_PCELLID3 *((volatile uint32_t *)0xE000EFFCu) +#define NVIC_PCELLID3_REG *((volatile uint32_t *)0xE000EFFCu) +#define NVIC_PCELLID3_ADDR (0xE000EFFCu) +#define NVIC_PCELLID3_RESET (0x000000B1u) +/* PCELLID field */ +#define NVIC_PCELLID3_PCELLID (0xFFFFFFFFu) +#define NVIC_PCELLID3_PCELLID_MASK (0xFFFFFFFFu) +#define NVIC_PCELLID3_PCELLID_BIT (0) +#define NVIC_PCELLID3_PCELLID_BITS (32) + +/* TPIU block */ +#define DATA_TPIU_BASE (0xE0040000u) +#define DATA_TPIU_END (0xE0040EF8u) +#define DATA_TPIU_SIZE (DATA_TPIU_END - DATA_TPIU_BASE + 1) + +#define TPIU_SPS *((volatile uint32_t *)0xE0040000u) +#define TPIU_SPS_REG *((volatile uint32_t *)0xE0040000u) +#define TPIU_SPS_ADDR (0xE0040000u) +#define TPIU_SPS_RESET (0x00000000u) +/* SPS_04 field */ +#define TPIU_SPS_SPS_04 (0x00000008u) +#define TPIU_SPS_SPS_04_MASK (0x00000008u) +#define TPIU_SPS_SPS_04_BIT (3) +#define TPIU_SPS_SPS_04_BITS (1) +/* SPS_03 field */ +#define TPIU_SPS_SPS_03 (0x00000004u) +#define TPIU_SPS_SPS_03_MASK (0x00000004u) +#define TPIU_SPS_SPS_03_BIT (2) +#define TPIU_SPS_SPS_03_BITS (1) +/* SPS_02 field */ +#define TPIU_SPS_SPS_02 (0x00000002u) +#define TPIU_SPS_SPS_02_MASK (0x00000002u) +#define TPIU_SPS_SPS_02_BIT (1) +#define TPIU_SPS_SPS_02_BITS (1) +/* SPS_01 field */ +#define TPIU_SPS_SPS_01 (0x00000001u) +#define TPIU_SPS_SPS_01_MASK (0x00000001u) +#define TPIU_SPS_SPS_01_BIT (0) +#define TPIU_SPS_SPS_01_BITS (1) + +#define TPIU_CPS *((volatile uint32_t *)0xE0040004u) +#define TPIU_CPS_REG *((volatile uint32_t *)0xE0040004u) +#define TPIU_CPS_ADDR (0xE0040004u) +#define TPIU_CPS_RESET (0x00000001u) +/* CPS_04 field */ +#define TPIU_CPS_CPS_04 (0x00000008u) +#define TPIU_CPS_CPS_04_MASK (0x00000008u) +#define TPIU_CPS_CPS_04_BIT (3) +#define TPIU_CPS_CPS_04_BITS (1) +/* CPS_03 field */ +#define TPIU_CPS_CPS_03 (0x00000004u) +#define TPIU_CPS_CPS_03_MASK (0x00000004u) +#define TPIU_CPS_CPS_03_BIT (2) +#define TPIU_CPS_CPS_03_BITS (1) +/* CPS_02 field */ +#define TPIU_CPS_CPS_02 (0x00000002u) +#define TPIU_CPS_CPS_02_MASK (0x00000002u) +#define TPIU_CPS_CPS_02_BIT (1) +#define TPIU_CPS_CPS_02_BITS (1) +/* CPS_01 field */ +#define TPIU_CPS_CPS_01 (0x00000001u) +#define TPIU_CPS_CPS_01_MASK (0x00000001u) +#define TPIU_CPS_CPS_01_BIT (0) +#define TPIU_CPS_CPS_01_BITS (1) + +#define TPIU_COSD *((volatile uint32_t *)0xE0040010u) +#define TPIU_COSD_REG *((volatile uint32_t *)0xE0040010u) +#define TPIU_COSD_ADDR (0xE0040010u) +#define TPIU_COSD_RESET (0x00000000u) +/* PRESCALER field */ +#define TPIU_COSD_PRESCALER (0x00001FFFu) +#define TPIU_COSD_PRESCALER_MASK (0x00001FFFu) +#define TPIU_COSD_PRESCALER_BIT (0) +#define TPIU_COSD_PRESCALER_BITS (13) + +#define TPIU_SPP *((volatile uint32_t *)0xE00400F0u) +#define TPIU_SPP_REG *((volatile uint32_t *)0xE00400F0u) +#define TPIU_SPP_ADDR (0xE00400F0u) +#define TPIU_SPP_RESET (0x00000001u) +/* PROTOCOL field */ +#define TPIU_SPP_PROTOCOL (0x00000003u) +#define TPIU_SPP_PROTOCOL_MASK (0x00000003u) +#define TPIU_SPP_PROTOCOL_BIT (0) +#define TPIU_SPP_PROTOCOL_BITS (2) + +#define TPIU_FFS *((volatile uint32_t *)0xE0040300u) +#define TPIU_FFS_REG *((volatile uint32_t *)0xE0040300u) +#define TPIU_FFS_ADDR (0xE0040300u) +#define TPIU_FFS_RESET (0x00000008u) +/* FTNONSTOP field */ +#define TPIU_FFS_FTNONSTOP (0x00000008u) +#define TPIU_FFS_FTNONSTOP_MASK (0x00000008u) +#define TPIU_FFS_FTNONSTOP_BIT (3) +#define TPIU_FFS_FTNONSTOP_BITS (1) +/* TCPRESENT field */ +#define TPIU_FFS_TCPRESENT (0x00000004u) +#define TPIU_FFS_TCPRESENT_MASK (0x00000004u) +#define TPIU_FFS_TCPRESENT_BIT (2) +#define TPIU_FFS_TCPRESENT_BITS (1) +/* FTSTOPPED field */ +#define TPIU_FFS_FTSTOPPED (0x00000002u) +#define TPIU_FFS_FTSTOPPED_MASK (0x00000002u) +#define TPIU_FFS_FTSTOPPED_BIT (1) +#define TPIU_FFS_FTSTOPPED_BITS (1) +/* FLINPROG field */ +#define TPIU_FFS_FLINPROG (0x00000001u) +#define TPIU_FFS_FLINPROG_MASK (0x00000001u) +#define TPIU_FFS_FLINPROG_BIT (0) +#define TPIU_FFS_FLINPROG_BITS (1) + +#define TPIU_FFC *((volatile uint32_t *)0xE0040304u) +#define TPIU_FFC_REG *((volatile uint32_t *)0xE0040304u) +#define TPIU_FFC_ADDR (0xE0040304u) +#define TPIU_FFC_RESET (0x00000102u) +/* TRIGIN field */ +#define TPIU_FFC_TRIGIN (0x00000100u) +#define TPIU_FFC_TRIGIN_MASK (0x00000100u) +#define TPIU_FFC_TRIGIN_BIT (8) +#define TPIU_FFC_TRIGIN_BITS (1) +/* ENFCONT field */ +#define TPIU_FFC_ENFCONT (0x00000002u) +#define TPIU_FFC_ENFCONT_MASK (0x00000002u) +#define TPIU_FFC_ENFCONT_BIT (1) +#define TPIU_FFC_ENFCONT_BITS (1) + +#define TPIU_FSC *((volatile uint32_t *)0xE0040308u) +#define TPIU_FSC_REG *((volatile uint32_t *)0xE0040308u) +#define TPIU_FSC_ADDR (0xE0040308u) +#define TPIU_FSC_RESET (0x00000000u) +/* FSC field */ +#define TPIU_FSC_FSC (0xFFFFFFFFu) +#define TPIU_FSC_FSC_MASK (0xFFFFFFFFu) +#define TPIU_FSC_FSC_BIT (0) +#define TPIU_FSC_FSC_BITS (32) + +#define TPIU_ITATBCTR2 *((volatile uint32_t *)0xE0040EF0u) +#define TPIU_ITATBCTR2_REG *((volatile uint32_t *)0xE0040EF0u) +#define TPIU_ITATBCTR2_ADDR (0xE0040EF0u) +#define TPIU_ITATBCTR2_RESET (0x00000000u) +/* ATREADY1 field */ +#define TPIU_ITATBCTR2_ATREADY1 (0x00000001u) +#define TPIU_ITATBCTR2_ATREADY1_MASK (0x00000001u) +#define TPIU_ITATBCTR2_ATREADY1_BIT (0) +#define TPIU_ITATBCTR2_ATREADY1_BITS (1) + +#define TPIU_ITATBCTR0 *((volatile uint32_t *)0xE0040EF8u) +#define TPIU_ITATBCTR0_REG *((volatile uint32_t *)0xE0040EF8u) +#define TPIU_ITATBCTR0_ADDR (0xE0040EF8u) +#define TPIU_ITATBCTR0_RESET (0x00000000u) +/* ATREADY1 field */ +#define TPIU_ITATBCTR0_ATREADY1 (0x00000001u) +#define TPIU_ITATBCTR0_ATREADY1_MASK (0x00000001u) +#define TPIU_ITATBCTR0_ATREADY1_BIT (0) +#define TPIU_ITATBCTR0_ATREADY1_BITS (1) + +/* ETM block */ +#define DATA_ETM_BASE (0xE0041000u) +#define DATA_ETM_END (0xE0041FFFu) +#define DATA_ETM_SIZE (DATA_ETM_END - DATA_ETM_BASE + 1) + +/* ROM_TAB block */ +#define DATA_ROM_TAB_BASE (0xE00FF000u) +#define DATA_ROM_TAB_END (0xE00FFFFFu) +#define DATA_ROM_TAB_SIZE (DATA_ROM_TAB_END - DATA_ROM_TAB_BASE + 1) + +#define ROM_SCS *((volatile uint32_t *)0xE00FF000u) +#define ROM_SCS_REG *((volatile uint32_t *)0xE00FF000u) +#define ROM_SCS_ADDR (0xE00FF000u) +#define ROM_SCS_RESET (0xFFF0F003u) +/* ADDR_OFF field */ +#define ROM_SCS_ADDR_OFF (0xFFFFF000u) +#define ROM_SCS_ADDR_OFF_MASK (0xFFFFF000u) +#define ROM_SCS_ADDR_OFF_BIT (12) +#define ROM_SCS_ADDR_OFF_BITS (20) +/* FORMAT field */ +#define ROM_SCS_FORMAT (0x00000002u) +#define ROM_SCS_FORMAT_MASK (0x00000002u) +#define ROM_SCS_FORMAT_BIT (1) +#define ROM_SCS_FORMAT_BITS (1) +/* ENTRY_PRES field */ +#define ROM_SCS_ENTRY_PRES (0x00000001u) +#define ROM_SCS_ENTRY_PRES_MASK (0x00000001u) +#define ROM_SCS_ENTRY_PRES_BIT (0) +#define ROM_SCS_ENTRY_PRES_BITS (1) + +#define ROM_DWT *((volatile uint32_t *)0xE00FF004u) +#define ROM_DWT_REG *((volatile uint32_t *)0xE00FF004u) +#define ROM_DWT_ADDR (0xE00FF004u) +#define ROM_DWT_RESET (0xFFF02003u) +/* ADDR_OFF field */ +#define ROM_DWT_ADDR_OFF (0xFFFFF000u) +#define ROM_DWT_ADDR_OFF_MASK (0xFFFFF000u) +#define ROM_DWT_ADDR_OFF_BIT (12) +#define ROM_DWT_ADDR_OFF_BITS (20) +/* FORMAT field */ +#define ROM_DWT_FORMAT (0x00000002u) +#define ROM_DWT_FORMAT_MASK (0x00000002u) +#define ROM_DWT_FORMAT_BIT (1) +#define ROM_DWT_FORMAT_BITS (1) +/* ENTRY_PRES field */ +#define ROM_DWT_ENTRY_PRES (0x00000001u) +#define ROM_DWT_ENTRY_PRES_MASK (0x00000001u) +#define ROM_DWT_ENTRY_PRES_BIT (0) +#define ROM_DWT_ENTRY_PRES_BITS (1) + +#define ROM_FPB *((volatile uint32_t *)0xE00FF008u) +#define ROM_FPB_REG *((volatile uint32_t *)0xE00FF008u) +#define ROM_FPB_ADDR (0xE00FF008u) +#define ROM_FPB_RESET (0xFFF03003u) +/* ADDR_OFF field */ +#define ROM_FPB_ADDR_OFF (0xFFFFF000u) +#define ROM_FPB_ADDR_OFF_MASK (0xFFFFF000u) +#define ROM_FPB_ADDR_OFF_BIT (12) +#define ROM_FPB_ADDR_OFF_BITS (20) +/* FORMAT field */ +#define ROM_FPB_FORMAT (0x00000002u) +#define ROM_FPB_FORMAT_MASK (0x00000002u) +#define ROM_FPB_FORMAT_BIT (1) +#define ROM_FPB_FORMAT_BITS (1) +/* ENTRY_PRES field */ +#define ROM_FPB_ENTRY_PRES (0x00000001u) +#define ROM_FPB_ENTRY_PRES_MASK (0x00000001u) +#define ROM_FPB_ENTRY_PRES_BIT (0) +#define ROM_FPB_ENTRY_PRES_BITS (1) + +#define ROM_ITM *((volatile uint32_t *)0xE00FF00Cu) +#define ROM_ITM_REG *((volatile uint32_t *)0xE00FF00Cu) +#define ROM_ITM_ADDR (0xE00FF00Cu) +#define ROM_ITM_RESET (0xFFF01003u) +/* ADDR_OFF field */ +#define ROM_ITM_ADDR_OFF (0xFFFFF000u) +#define ROM_ITM_ADDR_OFF_MASK (0xFFFFF000u) +#define ROM_ITM_ADDR_OFF_BIT (12) +#define ROM_ITM_ADDR_OFF_BITS (20) +/* FORMAT field */ +#define ROM_ITM_FORMAT (0x00000002u) +#define ROM_ITM_FORMAT_MASK (0x00000002u) +#define ROM_ITM_FORMAT_BIT (1) +#define ROM_ITM_FORMAT_BITS (1) +/* ENTRY_PRES field */ +#define ROM_ITM_ENTRY_PRES (0x00000001u) +#define ROM_ITM_ENTRY_PRES_MASK (0x00000001u) +#define ROM_ITM_ENTRY_PRES_BIT (0) +#define ROM_ITM_ENTRY_PRES_BITS (1) + +#define ROM_TPIU *((volatile uint32_t *)0xE00FF010u) +#define ROM_TPIU_REG *((volatile uint32_t *)0xE00FF010u) +#define ROM_TPIU_ADDR (0xE00FF010u) +#define ROM_TPIU_RESET (0xFFF0F003u) +/* ADDR_OFF field */ +#define ROM_TPIU_ADDR_OFF (0xFFFFF000u) +#define ROM_TPIU_ADDR_OFF_MASK (0xFFFFF000u) +#define ROM_TPIU_ADDR_OFF_BIT (12) +#define ROM_TPIU_ADDR_OFF_BITS (20) +/* FORMAT field */ +#define ROM_TPIU_FORMAT (0x00000002u) +#define ROM_TPIU_FORMAT_MASK (0x00000002u) +#define ROM_TPIU_FORMAT_BIT (1) +#define ROM_TPIU_FORMAT_BITS (1) +/* ENTRY_PRES field */ +#define ROM_TPIU_ENTRY_PRES (0x00000001u) +#define ROM_TPIU_ENTRY_PRES_MASK (0x00000001u) +#define ROM_TPIU_ENTRY_PRES_BIT (0) +#define ROM_TPIU_ENTRY_PRES_BITS (1) + +#define ROM_ETM *((volatile uint32_t *)0xE00FF014u) +#define ROM_ETM_REG *((volatile uint32_t *)0xE00FF014u) +#define ROM_ETM_ADDR (0xE00FF014u) +#define ROM_ETM_RESET (0xFFF0F002u) +/* ADDR_OFF field */ +#define ROM_ETM_ADDR_OFF (0xFFFFF000u) +#define ROM_ETM_ADDR_OFF_MASK (0xFFFFF000u) +#define ROM_ETM_ADDR_OFF_BIT (12) +#define ROM_ETM_ADDR_OFF_BITS (20) +/* FORMAT field */ +#define ROM_ETM_FORMAT (0x00000002u) +#define ROM_ETM_FORMAT_MASK (0x00000002u) +#define ROM_ETM_FORMAT_BIT (1) +#define ROM_ETM_FORMAT_BITS (1) +/* ENTRY_PRES field */ +#define ROM_ETM_ENTRY_PRES (0x00000001u) +#define ROM_ETM_ENTRY_PRES_MASK (0x00000001u) +#define ROM_ETM_ENTRY_PRES_BIT (0) +#define ROM_ETM_ENTRY_PRES_BITS (1) + +#define ROM_END *((volatile uint32_t *)0xE00FF018u) +#define ROM_END_REG *((volatile uint32_t *)0xE00FF018u) +#define ROM_END_ADDR (0xE00FF018u) +#define ROM_END_RESET (0x00000000u) +/* END field */ +#define ROM_END_END (0xFFFFFFFFu) +#define ROM_END_END_MASK (0xFFFFFFFFu) +#define ROM_END_END_BIT (0) +#define ROM_END_END_BITS (32) + +#define ROM_MEMTYPE *((volatile uint32_t *)0xE00FFFCCu) +#define ROM_MEMTYPE_REG *((volatile uint32_t *)0xE00FFFCCu) +#define ROM_MEMTYPE_ADDR (0xE00FFFCCu) +#define ROM_MEMTYPE_RESET (0x00000001u) +/* MEMTYPE field */ +#define ROM_MEMTYPE_MEMTYPE (0x00000001u) +#define ROM_MEMTYPE_MEMTYPE_MASK (0x00000001u) +#define ROM_MEMTYPE_MEMTYPE_BIT (0) +#define ROM_MEMTYPE_MEMTYPE_BITS (1) + +#define ROM_PID4 *((volatile uint32_t *)0xE00FFFD0u) +#define ROM_PID4_REG *((volatile uint32_t *)0xE00FFFD0u) +#define ROM_PID4_ADDR (0xE00FFFD0u) +#define ROM_PID4_RESET (0x00000000u) +/* PID field */ +#define ROM_PID4_PID (0x0000000Fu) +#define ROM_PID4_PID_MASK (0x0000000Fu) +#define ROM_PID4_PID_BIT (0) +#define ROM_PID4_PID_BITS (4) + +#define ROM_PID5 *((volatile uint32_t *)0xE00FFFD4u) +#define ROM_PID5_REG *((volatile uint32_t *)0xE00FFFD4u) +#define ROM_PID5_ADDR (0xE00FFFD4u) +#define ROM_PID5_RESET (0x00000000u) +/* PID field */ +#define ROM_PID5_PID (0x0000000Fu) +#define ROM_PID5_PID_MASK (0x0000000Fu) +#define ROM_PID5_PID_BIT (0) +#define ROM_PID5_PID_BITS (4) + +#define ROM_PID6 *((volatile uint32_t *)0xE00FFFD8u) +#define ROM_PID6_REG *((volatile uint32_t *)0xE00FFFD8u) +#define ROM_PID6_ADDR (0xE00FFFD8u) +#define ROM_PID6_RESET (0x00000000u) +/* PID field */ +#define ROM_PID6_PID (0x0000000Fu) +#define ROM_PID6_PID_MASK (0x0000000Fu) +#define ROM_PID6_PID_BIT (0) +#define ROM_PID6_PID_BITS (4) + +#define ROM_PID7 *((volatile uint32_t *)0xE00FFFDCu) +#define ROM_PID7_REG *((volatile uint32_t *)0xE00FFFDCu) +#define ROM_PID7_ADDR (0xE00FFFDCu) +#define ROM_PID7_RESET (0x00000000u) +/* PID field */ +#define ROM_PID7_PID (0x0000000Fu) +#define ROM_PID7_PID_MASK (0x0000000Fu) +#define ROM_PID7_PID_BIT (0) +#define ROM_PID7_PID_BITS (4) + +#define ROM_PID0 *((volatile uint32_t *)0xE00FFFE0u) +#define ROM_PID0_REG *((volatile uint32_t *)0xE00FFFE0u) +#define ROM_PID0_ADDR (0xE00FFFE0u) +#define ROM_PID0_RESET (0x00000000u) +/* PID field */ +#define ROM_PID0_PID (0x0000000Fu) +#define ROM_PID0_PID_MASK (0x0000000Fu) +#define ROM_PID0_PID_BIT (0) +#define ROM_PID0_PID_BITS (4) + +#define ROM_PID1 *((volatile uint32_t *)0xE00FFFE4u) +#define ROM_PID1_REG *((volatile uint32_t *)0xE00FFFE4u) +#define ROM_PID1_ADDR (0xE00FFFE4u) +#define ROM_PID1_RESET (0x00000000u) +/* PID field */ +#define ROM_PID1_PID (0x0000000Fu) +#define ROM_PID1_PID_MASK (0x0000000Fu) +#define ROM_PID1_PID_BIT (0) +#define ROM_PID1_PID_BITS (4) + +#define ROM_PID2 *((volatile uint32_t *)0xE00FFFE8u) +#define ROM_PID2_REG *((volatile uint32_t *)0xE00FFFE8u) +#define ROM_PID2_ADDR (0xE00FFFE8u) +#define ROM_PID2_RESET (0x00000000u) +/* PID field */ +#define ROM_PID2_PID (0x0000000Fu) +#define ROM_PID2_PID_MASK (0x0000000Fu) +#define ROM_PID2_PID_BIT (0) +#define ROM_PID2_PID_BITS (4) + +#define ROM_PID3 *((volatile uint32_t *)0xE00FFFECu) +#define ROM_PID3_REG *((volatile uint32_t *)0xE00FFFECu) +#define ROM_PID3_ADDR (0xE00FFFECu) +#define ROM_PID3_RESET (0x00000000u) +/* PID field */ +#define ROM_PID3_PID (0x0000000Fu) +#define ROM_PID3_PID_MASK (0x0000000Fu) +#define ROM_PID3_PID_BIT (0) +#define ROM_PID3_PID_BITS (4) + +#define ROM_CID0 *((volatile uint32_t *)0xE00FFFF0u) +#define ROM_CID0_REG *((volatile uint32_t *)0xE00FFFF0u) +#define ROM_CID0_ADDR (0xE00FFFF0u) +#define ROM_CID0_RESET (0x0000000Du) +/* CID field */ +#define ROM_CID0_CID (0x000000FFu) +#define ROM_CID0_CID_MASK (0x000000FFu) +#define ROM_CID0_CID_BIT (0) +#define ROM_CID0_CID_BITS (8) + +#define ROM_CID1 *((volatile uint32_t *)0xE00FFFF4u) +#define ROM_CID1_REG *((volatile uint32_t *)0xE00FFFF4u) +#define ROM_CID1_ADDR (0xE00FFFF4u) +#define ROM_CID1_RESET (0x00000010u) +/* CID field */ +#define ROM_CID1_CID (0x000000FFu) +#define ROM_CID1_CID_MASK (0x000000FFu) +#define ROM_CID1_CID_BIT (0) +#define ROM_CID1_CID_BITS (8) + +#define ROM_CID2 *((volatile uint32_t *)0xE00FFFF8u) +#define ROM_CID2_REG *((volatile uint32_t *)0xE00FFFF8u) +#define ROM_CID2_ADDR (0xE00FFFF8u) +#define ROM_CID2_RESET (0x00000005u) +/* CID field */ +#define ROM_CID2_CID (0x000000FFu) +#define ROM_CID2_CID_MASK (0x000000FFu) +#define ROM_CID2_CID_BIT (0) +#define ROM_CID2_CID_BITS (8) + +#define ROM_CID3 *((volatile uint32_t *)0xE00FFFFCu) +#define ROM_CID3_REG *((volatile uint32_t *)0xE00FFFFCu) +#define ROM_CID3_ADDR (0xE00FFFFCu) +#define ROM_CID3_RESET (0x000000B1u) +/* CID field */ +#define ROM_CID3_CID (0x000000FFu) +#define ROM_CID3_CID_MASK (0x000000FFu) +#define ROM_CID3_CID_BIT (0) +#define ROM_CID3_CID_BITS (8) + +/* VENDOR block */ +#define DATA_VENDOR_BASE (0xE0100000u) +#define DATA_VENDOR_END (0xFFFFFFFFu) +#define DATA_VENDOR_SIZE (DATA_VENDOR_END - DATA_VENDOR_BASE + 1) + +/*---------------------------------------------------------------------------*/ +#endif /*REGS_H_*/ +/*---------------------------------------------------------------------------*/ diff --git a/cpu/arm/stm32l152/rtimer-arch.c b/cpu/arm/stm32l152/rtimer-arch.c new file mode 100644 index 000000000..cd786969c --- /dev/null +++ b/cpu/arm/stm32l152/rtimer-arch.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "platform-conf.h" + +#include "sys/rtimer.h" +#include "sys/process.h" +#include "dev/watchdog.h" + +#include "stm32l1xx.h" +#include "stm32l1xx_hal_gpio.h" +#include "stm32l1xx_hal_rcc.h" +#include "stm32l1xx_hal_tim.h" +#include "stm32l1xx_hal_cortex.h" +#include "st-lib.h" +/*---------------------------------------------------------------------------*/ +volatile uint32_t rtimer_clock = 0uL; +/*---------------------------------------------------------------------------*/ +st_lib_tim_handle_typedef htim2; +/*---------------------------------------------------------------------------*/ +void +st_lib_tim2_irq_handler(void) +{ + /* clear interrupt pending flag */ + st_lib_hal_tim_clear_it(&htim2, TIM_IT_UPDATE); + + rtimer_clock++; +} +/*---------------------------------------------------------------------------*/ +void +rtimer_arch_init(void) +{ + st_lib_tim_clock_config_typedef s_clock_source_config; + st_lib_tim_oc_init_typedef s_config_oc; + + st_lib_tim2_clk_enable(); + htim2.Instance = TIM2; + htim2.Init.Prescaler = PRESCALER; + htim2.Init.CounterMode = TIM_COUNTERMODE_UP; + htim2.Init.Period = 1; + + st_lib_hal_tim_base_init(&htim2); + st_lib_hal_tim_base_start_it(&htim2); + + s_clock_source_config.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + st_lib_hal_tim_config_clock_source(&htim2, &s_clock_source_config); + + st_lib_hal_tim_oc_init(&htim2); + + s_config_oc.OCMode = TIM_OCMODE_TIMING; + s_config_oc.Pulse = 0; + s_config_oc.OCPolarity = TIM_OCPOLARITY_HIGH; + st_lib_hal_tim_oc_config_channel(&htim2, &s_config_oc, TIM_CHANNEL_1); + + st_lib_hal_tim_clear_flag(&htim2, TIM_FLAG_UPDATE); + + /* Enable TIM2 Update interrupt */ + st_lib_hal_tim_enable_it(&htim2, TIM_IT_UPDATE); + + st_lib_hal_tim_enable(&htim2); + + st_lib_hal_nvic_set_priority((st_lib_irq_n_type)TIM2_IRQn, 0, 0); + st_lib_hal_nvic_enable_irq((st_lib_irq_n_type)(TIM2_IRQn)); +} +/*---------------------------------------------------------------------------*/ +rtimer_clock_t +rtimer_arch_now(void) +{ + return rtimer_clock; +} +/*---------------------------------------------------------------------------*/ +void +rtimer_arch_schedule(rtimer_clock_t t) +{ +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/arm/stm32l152/rtimer-arch.h b/cpu/arm/stm32l152/rtimer-arch.h new file mode 100644 index 000000000..555c1f6df --- /dev/null +++ b/cpu/arm/stm32l152/rtimer-arch.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2010, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the Contiki OS + * + */ +/*---------------------------------------------------------------------------*/ +#ifndef __RTIMER_ARCH_H__ +#define __RTIMER_ARCH_H__ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "sys/clock.h" +/*---------------------------------------------------------------------------*/ +rtimer_clock_t rtimer_arch_now(void); +void rtimer_arch_disable_irq(void); +void rtimer_arch_enable_irq(void); +/*---------------------------------------------------------------------------*/ +#endif /* __RTIMER_ARCH_H__ */ +/*---------------------------------------------------------------------------*/ diff --git a/cpu/arm/stm32l152/syscalls.c b/cpu/arm/stm32l152/syscalls.c new file mode 100644 index 000000000..8390ecc99 --- /dev/null +++ b/cpu/arm/stm32l152/syscalls.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/* + * Function implementation taken and adapted from: + * cpu/stm32w108/e_stdio/src/syscalls.c + */ +/*---------------------------------------------------------------------------*/ +#include +#include +/*---------------------------------------------------------------------------*/ +extern int errno; +/*---------------------------------------------------------------------------*/ +/* Register name faking - works in collusion with the linker. */ +register char *stack_ptr asm ("sp"); +/*---------------------------------------------------------------------------*/ +caddr_t +_sbrk(int incr) +{ + extern char end; /* Defined by the linker */ + static char *heap_end; + char *prev_heap_end; + + if(heap_end == 0) { + heap_end = &end; + } + prev_heap_end = heap_end; + if(heap_end + incr > stack_ptr) { + _write(1, "Heap and stack collision\n", 25); + /*abort ();*/ + errno = ENOMEM; + return (caddr_t)-1; + } + + heap_end += incr; + return (caddr_t)prev_heap_end; +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/iris/apps/mts310/accel-test.c b/cpu/arm/stm32l152/uart.c similarity index 76% rename from platform/iris/apps/mts310/accel-test.c rename to cpu/arm/stm32l152/uart.c index 94de0c474..4f79465e4 100644 --- a/platform/iris/apps/mts310/accel-test.c +++ b/cpu/arm/stm32l152/uart.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, University of Colombo School of Computing + * Copyright (c) 2012, STMicroelectronics. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,34 +26,28 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * This file is part of the Contiki operating system. * - * @(#)$$ */ - +/*---------------------------------------------------------------------------*/ +#include "console.h" #include -#include "contiki.h" -#include "dev/sensors/mts300.h" - /*---------------------------------------------------------------------------*/ -PROCESS(test_accel_process, "Accel test"); -AUTOSTART_PROCESSES(&test_accel_process); -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(test_accel_process, ev, data) +size_t +_write(int handle, const unsigned char *buffer, size_t size) { - static struct etimer et; + int data_idx; - PROCESS_BEGIN(); - - while(1) { - - printf("AccX : %d\n",get_accx()); - printf("AccY : %d\n",get_accy()); - - etimer_set(&et, CLOCK_SECOND / 2); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + for(data_idx = 0; data_idx < size; data_idx++) { + __io_putchar(*buffer++); } - - PROCESS_END(); + return size; +} +/*---------------------------------------------------------------------------*/ +size_t +_read(int handle, unsigned char *buffer, size_t size) +{ + /* scanf calls _read() with len=1024, so eat one character at time */ + *buffer = __io_getchar(); + return 1; } /*---------------------------------------------------------------------------*/ diff --git a/cpu/arm/stm32l152/watchdog.c b/cpu/arm/stm32l152/watchdog.c new file mode 100644 index 000000000..ab0193ac4 --- /dev/null +++ b/cpu/arm/stm32l152/watchdog.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2010, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the Contiki OS + * + */ +/*---------------------------------------------------------------------------*/ +#include +#include "dev/watchdog.h" +/*---------------------------------------------------------------------------*/ +void +watchdog_init(void) +{ +} +/*---------------------------------------------------------------------------*/ +void +watchdog_start(void) +{ +} +/*---------------------------------------------------------------------------*/ +void +watchdog_periodic(void) +{ +} +/*---------------------------------------------------------------------------*/ +void +watchdog_stop(void) +{ +} +/*---------------------------------------------------------------------------*/ +void +watchdog_reboot(void) +{ +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/avr/Makefile.avr b/cpu/avr/Makefile.avr index d3ef8235f..bc94010a2 100644 --- a/cpu/avr/Makefile.avr +++ b/cpu/avr/Makefile.avr @@ -12,7 +12,7 @@ CONTIKI_CPU=$(CONTIKI)/cpu/avr ### These directories will be searched for the specified source files ### TARGETLIBS are platform-specific routines in the contiki library path -CONTIKI_CPU_DIRS = . dev +CONTIKI_CPU_DIRS = . dev dev/arduino AVR = clock.c mtarch.c eeprom.c flash.c rs232.c leds-arch.c \ watchdog.c rtimer-arch.c bootloader.c ELFLOADER = elfloader.c elfloader-avr.c symtab-avr.c @@ -101,6 +101,7 @@ CFLAGSNO = -Wall -mmcu=$(MCU) -gdwarf-2 -fno-strict-aliasing \ -I. -I$(CONTIKI)/core -I$(CONTIKI_CPU) $(USB_INCLUDES) \ $(CONTIKI_PLAT_DEFS) CFLAGS += $(CFLAGSNO) -O$(OPTI) +ASFLAGS += -mmcu=$(MCU) ifndef BOOTLOADER_START BOOTLOADER_START = 0x1F800 endif @@ -146,10 +147,10 @@ ifndef NOAVRSIZE avr-size -C --mcu=$(MCU) $@ endif -%.hex: %.out +%.hex: %.$(TARGET) $(OBJCOPY) $^ -j .text -j .data -O ihex $@ -%.ihex: %.out +%.ihex: %.$(TARGET) $(OBJCOPY) $^ -O ihex $@ # Add a namelist to the kernel @@ -167,7 +168,7 @@ endif #%.hex: %.elf # $(OBJCOPY) -R .eeprom -R .fuse -R .signature $^ -O ihex $@ -%.eep: %.out +%.eep: %.$(TARGET) -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ --change-section-lma .eeprom=0 -O ihex $^ $@ @@ -201,23 +202,30 @@ endif ### Upload image #Let avrdude use defaults if port or programmer not defined AVRDUDE ?= avrdude -ifdef AVRDUDE_PORT - AVRDUDE_PORT:=-P $(AVRDUDE_PORT) -endif -ifdef AVRDUDE_PROGRAMMER - AVRDUDE_PROGRAMMER:=-c $(AVRDUDE_PROGRAMMER) -endif ifdef AVRDUDE_MCU - AVRDUDE_MCU:=-p $(AVRDUDE_MCU) + DUDE_MCU:=-p $(AVRDUDE_MCU) else - AVRDUDE_MCU:=-p $(MCU) + DUDE_MCU:=-p $(MCU) endif %.u: %.hex - $(AVRDUDE) $(AVRDUDE_MCU) $(AVRDUDE_OPTIONS) $(AVRDUDE_PORT) $(AVRDUDE_PROGRAMMER) -U flash:w:$< + $(AVRDUDE) $(DUDE_MCU) $(AVRDUDE_OPTIONS) -P $(AVRDUDE_PORT) \ + -c $(AVRDUDE_PROGRAMMER) -U flash:w:$<:i %.eu: %.eep - $(AVRDUDE) $(AVRDUDE_MCU) ${AVRDUDE_OPTIONS} ${AVRDUDE_PORT} ${AVRDUDE_PROGRAMMER} -U eeprom:w:$< + $(AVRDUDE) $(DUDE_MCU) ${AVRDUDE_OPTIONS} -P ${AVRDUDE_PORT} \ + -c ${AVRDUDE_PROGRAMMER} -U eeprom:w:$<:i symbols.c: cp ${CONTIKI}/tools/empty-symbols.c symbols.c cp ${CONTIKI}/tools/empty-symbols.h symbols.h + +# Generic rules for .hex, .eep and .sz (size) file: +%.$(TARGET).hex: %.$(TARGET) + $(OBJCOPY) -j .text -j .data -O ihex $< $@ + +%.$(TARGET).eep: %.$(TARGET) + $(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O ihex $< $@ + +%.$(TARGET).sz: %.$(TARGET) + $(ELF_SIZE) $< diff --git a/cpu/avr/bootloader.c b/cpu/avr/bootloader.c index 5cee7d1b2..844dc20a1 100644 --- a/cpu/avr/bootloader.c +++ b/cpu/avr/bootloader.c @@ -9,10 +9,11 @@ #include #include -/* Not all AVR toolchains alias MCUSR to the older MSUSCR name */ -#if !defined (MCUSR) && defined (MCUCSR) -#warning *** MCUSR not defined, using MCUCSR instead *** -#define MCUSR MCUCSR +/* MCUSR is a deprecated name but older avr-libc versions may define it */ +#if !defined (MCUCSR) +# if defined (MCUSR) +# define MCUCSR MCUSR +# endif #endif #ifndef EEPROM_MAGIC_BYTE_ADDR @@ -69,8 +70,8 @@ Bootloader_Jump_Check(void) /* If the reset source was the bootloader and the key is correct, * clear it and jump to the bootloader */ - if(MCUSR & (1 << WDRF)) { - MCUSR = 0; + if(MCUCSR & (1 << WDRF)) { + MCUCSR = 0; if(Boot_Key == MAGIC_BOOT_KEY) { Boot_Key = 0; wdt_disable(); diff --git a/platform/osd-merkur/dev/adc.c b/cpu/avr/dev/adc.c similarity index 100% rename from platform/osd-merkur/dev/adc.c rename to cpu/avr/dev/adc.c diff --git a/platform/osd-merkur/dev/adc.h b/cpu/avr/dev/adc.h similarity index 100% rename from platform/osd-merkur/dev/adc.h rename to cpu/avr/dev/adc.h diff --git a/platform/osd-merkur/dev/Arduino.h b/cpu/avr/dev/arduino/Arduino.h similarity index 100% rename from platform/osd-merkur/dev/Arduino.h rename to cpu/avr/dev/arduino/Arduino.h diff --git a/cpu/avr/dev/arduino/Print.cpp b/cpu/avr/dev/arduino/Print.cpp new file mode 100644 index 000000000..bc97c851f --- /dev/null +++ b/cpu/avr/dev/arduino/Print.cpp @@ -0,0 +1,265 @@ +/* + Print.cpp - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. All right reserved. + + 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 + + Modified 23 November 2006 by David A. Mellis + Modified 03 August 2015 by Chuck Todd + */ + +#include +#include +#include +#include +#include "Arduino.h" + +#include "Print.h" + +// Public Methods ////////////////////////////////////////////////////////////// + +/* default implementation: may be overridden */ +size_t Print::write(const uint8_t *buffer, size_t size) +{ + size_t n = 0; + while (size--) { + if (write(*buffer++)) n++; + else break; + } + return n; +} + +size_t Print::print(const __FlashStringHelper *ifsh) +{ + PGM_P p = reinterpret_cast(ifsh); + size_t n = 0; + while (1) { + unsigned char c = pgm_read_byte(p++); + if (c == 0) break; + if (write(c)) n++; + else break; + } + return n; +} + +size_t Print::print(const String &s) +{ + return write(s.c_str(), s.length()); +} + +size_t Print::print(const char str[]) +{ + return write(str); +} + +size_t Print::print(char c) +{ + return write(c); +} + +size_t Print::print(unsigned char b, int base) +{ + return print((unsigned long) b, base); +} + +size_t Print::print(int n, int base) +{ + return print((long) n, base); +} + +size_t Print::print(unsigned int n, int base) +{ + return print((unsigned long) n, base); +} + +size_t Print::print(long n, int base) +{ + if (base == 0) { + return write(n); + } else if (base == 10) { + if (n < 0) { + int t = print('-'); + n = -n; + return printNumber(n, 10) + t; + } + return printNumber(n, 10); + } else { + return printNumber(n, base); + } +} + +size_t Print::print(unsigned long n, int base) +{ + if (base == 0) return write(n); + else return printNumber(n, base); +} + +size_t Print::print(double n, int digits) +{ + return printFloat(n, digits); +} + +size_t Print::println(const __FlashStringHelper *ifsh) +{ + size_t n = print(ifsh); + n += println(); + return n; +} + +size_t Print::print(const Printable& x) +{ + return x.printTo(*this); +} + +size_t Print::println(void) +{ + return write("\r\n"); +} + +size_t Print::println(const String &s) +{ + size_t n = print(s); + n += println(); + return n; +} + +size_t Print::println(const char c[]) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(char c) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(unsigned char b, int base) +{ + size_t n = print(b, base); + n += println(); + return n; +} + +size_t Print::println(int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(double num, int digits) +{ + size_t n = print(num, digits); + n += println(); + return n; +} + +size_t Print::println(const Printable& x) +{ + size_t n = print(x); + n += println(); + return n; +} + +// Private Methods ///////////////////////////////////////////////////////////// + +size_t Print::printNumber(unsigned long n, uint8_t base) { + char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. + char *str = &buf[sizeof(buf) - 1]; + + *str = '\0'; + + // prevent crash if called with base == 1 + if (base < 2) base = 10; + + do { + unsigned long m = n; + n /= base; + char c = m - base * n; + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } while(n); + + return write(str); +} + +size_t Print::printFloat(double number, uint8_t digits) +{ + size_t n = 0; + + if (isnan(number)) return print("nan"); + if (isinf(number)) return print("inf"); + if (number > 4294967040.0) return print ("ovf"); // constant determined empirically + if (number <-4294967040.0) return print ("ovf"); // constant determined empirically + + // Handle negative numbers + if (number < 0.0) + { + n += print('-'); + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for (uint8_t i=0; i 0) { + n += print("."); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) + { + remainder *= 10.0; + int toPrint = int(remainder); + n += print(toPrint); + remainder -= toPrint; + } + + return n; +} diff --git a/cpu/avr/dev/arduino/Print.h b/cpu/avr/dev/arduino/Print.h new file mode 100644 index 000000000..7b53aa4d1 --- /dev/null +++ b/cpu/avr/dev/arduino/Print.h @@ -0,0 +1,84 @@ +/* + Print.h - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. All right reserved. + + 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 Print_h +#define Print_h + +#include +#include // for size_t + +#include "WString.h" +#include "Printable.h" + +#define DEC 10 +#define HEX 16 +#define OCT 8 +#define BIN 2 + +class Print +{ + private: + int write_error; + size_t printNumber(unsigned long, uint8_t); + size_t printFloat(double, uint8_t); + protected: + void setWriteError(int err = 1) { write_error = err; } + public: + Print() : write_error(0) {} + + int getWriteError() { return write_error; } + void clearWriteError() { setWriteError(0); } + + virtual size_t write(uint8_t) = 0; + size_t write(const char *str) { + if (str == NULL) return 0; + return write((const uint8_t *)str, strlen(str)); + } + virtual size_t write(const uint8_t *buffer, size_t size); + size_t write(const char *buffer, size_t size) { + return write((const uint8_t *)buffer, size); + } + + size_t print(const __FlashStringHelper *); + size_t print(const String &); + size_t print(const char[]); + size_t print(char); + size_t print(unsigned char, int = DEC); + size_t print(int, int = DEC); + size_t print(unsigned int, int = DEC); + size_t print(long, int = DEC); + size_t print(unsigned long, int = DEC); + size_t print(double, int = 2); + size_t print(const Printable&); + + size_t println(const __FlashStringHelper *); + size_t println(const String &s); + size_t println(const char[]); + size_t println(char); + size_t println(unsigned char, int = DEC); + size_t println(int, int = DEC); + size_t println(unsigned int, int = DEC); + size_t println(long, int = DEC); + size_t println(unsigned long, int = DEC); + size_t println(double, int = 2); + size_t println(const Printable&); + size_t println(void); +}; + +#endif diff --git a/cpu/avr/dev/arduino/Printable.h b/cpu/avr/dev/arduino/Printable.h new file mode 100644 index 000000000..2a1b2e9f2 --- /dev/null +++ b/cpu/avr/dev/arduino/Printable.h @@ -0,0 +1,40 @@ +/* + Printable.h - Interface class that allows printing of complex types + Copyright (c) 2011 Adrian McEwen. All right reserved. + + 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 Printable_h +#define Printable_h + +#include + +class Print; + +/** The Printable class provides a way for new classes to allow themselves to be printed. + By deriving from Printable and implementing the printTo method, it will then be possible + for users to print out instances of this class by passing them into the usual + Print::print and Print::println methods. +*/ + +class Printable +{ + public: + virtual size_t printTo(Print& p) const = 0; +}; + +#endif + diff --git a/cpu/avr/dev/arduino/Stream.cpp b/cpu/avr/dev/arduino/Stream.cpp new file mode 100644 index 000000000..f66546532 --- /dev/null +++ b/cpu/avr/dev/arduino/Stream.cpp @@ -0,0 +1,319 @@ +/* + Stream.cpp - adds parsing methods to Stream class + Copyright (c) 2008 David A. Mellis. All right reserved. + + 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 + + Created July 2011 + parsing functions based on TextFinder library by Michael Margolis + + findMulti/findUntil routines written by Jim Leonard/Xuth + */ + +#include "Arduino.h" +#include "Stream.h" + +#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait + +// private method to read stream with timeout +int Stream::timedRead() +{ + int c; + _startMillis = millis(); + do { + c = read(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// private method to peek stream with timeout +int Stream::timedPeek() +{ + int c; + _startMillis = millis(); + do { + c = peek(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// returns peek of the next digit in the stream or -1 if timeout +// discards non-numeric characters +int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal) +{ + int c; + while (1) { + c = timedPeek(); + + if( c < 0 || + c == '-' || + (c >= '0' && c <= '9') || + (detectDecimal && c == '.')) return c; + + switch( lookahead ){ + case SKIP_NONE: return -1; // Fail code. + case SKIP_WHITESPACE: + switch( c ){ + case ' ': + case '\t': + case '\r': + case '\n': break; + default: return -1; // Fail code. + } + case SKIP_ALL: + break; + } + read(); // discard non-numeric + } +} + +// Public Methods +////////////////////////////////////////////////////////////// + +void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait +{ + _timeout = timeout; +} + + // find returns true if the target string is found +bool Stream::find(char *target) +{ + return findUntil(target, strlen(target), NULL, 0); +} + +// reads data from the stream until the target string of given length is found +// returns true if target string is found, false if timed out +bool Stream::find(char *target, size_t length) +{ + return findUntil(target, length, NULL, 0); +} + +// as find but search ends if the terminator string is found +bool Stream::findUntil(char *target, char *terminator) +{ + return findUntil(target, strlen(target), terminator, strlen(terminator)); +} + +// reads data from the stream until the target string of the given length is found +// search terminated if the terminator string is found +// returns true if target string is found, false if terminated or timed out +bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen) +{ + if (terminator == NULL) { + MultiTarget t[1] = {{target, targetLen, 0}}; + return findMulti(t, 1) == 0 ? true : false; + } else { + MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}}; + return findMulti(t, 2) == 0 ? true : false; + } +} + +// returns the first valid (long) integer value from the current position. +// lookahead determines how parseInt looks ahead in the stream. +// See LookaheadMode enumeration at the top of the file. +// Lookahead is terminated by the first character that is not a valid part of an integer. +// Once parsing commences, 'ignore' will be skipped in the stream. +long Stream::parseInt(LookaheadMode lookahead, char ignore) +{ + bool isNegative = false; + long value = 0; + int c; + + c = peekNextDigit(lookahead, false); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == ignore) + ; // ignore this character + else if(c == '-') + isNegative = true; + else if(c >= '0' && c <= '9') // is c a digit? + value = value * 10 + c - '0'; + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || c == ignore ); + + if(isNegative) + value = -value; + return value; +} + +// as parseInt but returns a floating point value +float Stream::parseFloat(LookaheadMode lookahead, char ignore) +{ + bool isNegative = false; + bool isFraction = false; + long value = 0; + int c; + float fraction = 1.0; + + c = peekNextDigit(lookahead, true); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == ignore) + ; // ignore + else if(c == '-') + isNegative = true; + else if (c == '.') + isFraction = true; + else if(c >= '0' && c <= '9') { // is c a digit? + value = value * 10 + c - '0'; + if(isFraction) + fraction *= 0.1; + } + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || (c == '.' && !isFraction) || c == ignore ); + + if(isNegative) + value = -value; + if(isFraction) + return value * fraction; + else + return value; +} + +// read characters from stream into buffer +// terminates if length characters have been read, or timeout (see setTimeout) +// returns the number of characters placed in the buffer +// the buffer is NOT null terminated. +// +size_t Stream::readBytes(char *buffer, size_t length) +{ + size_t count = 0; + while (count < length) { + int c = timedRead(); + if (c < 0) break; + *buffer++ = (char)c; + count++; + } + return count; +} + + +// as readBytes with terminator character +// terminates if length characters have been read, timeout, or if the terminator character detected +// returns the number of characters placed in the buffer (0 means no valid data found) + +size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) +{ + if (length < 1) return 0; + size_t index = 0; + while (index < length) { + int c = timedRead(); + if (c < 0 || c == terminator) break; + *buffer++ = (char)c; + index++; + } + return index; // return number of characters, not including null terminator +} + +String Stream::readString() +{ + String ret; + int c = timedRead(); + while (c >= 0) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +String Stream::readStringUntil(char terminator) +{ + String ret; + int c = timedRead(); + while (c >= 0 && c != terminator) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) { + // any zero length target string automatically matches and would make + // a mess of the rest of the algorithm. + for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { + if (t->len <= 0) + return t - targets; + } + + while (1) { + int c = timedRead(); + if (c < 0) + return -1; + + for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { + // the simple case is if we match, deal with that first. + if (c == t->str[t->index]) { + if (++t->index == t->len) + return t - targets; + else + continue; + } + + // if not we need to walk back and see if we could have matched further + // down the stream (ie '1112' doesn't match the first position in '11112' + // but it will match the second position so we can't just reset the current + // index to 0 when we find a mismatch. + if (t->index == 0) + continue; + + int origIndex = t->index; + do { + --t->index; + // first check if current char works against the new current index + if (c != t->str[t->index]) + continue; + + // if it's the only char then we're good, nothing more to check + if (t->index == 0) { + t->index++; + break; + } + + // otherwise we need to check the rest of the found string + int diff = origIndex - t->index; + size_t i; + for (i = 0; i < t->index; ++i) { + if (t->str[i] != t->str[i + diff]) + break; + } + + // if we successfully got through the previous loop then our current + // index is good. + if (i == t->index) { + t->index++; + break; + } + + // otherwise we just try the next index + } while (t->index); + } + } + // unreachable + return -1; +} diff --git a/cpu/avr/dev/arduino/Stream.h b/cpu/avr/dev/arduino/Stream.h new file mode 100644 index 000000000..db71bb6cd --- /dev/null +++ b/cpu/avr/dev/arduino/Stream.h @@ -0,0 +1,129 @@ +/* + Stream.h - base class for character-based streams. + Copyright (c) 2010 David A. Mellis. All right reserved. + + 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 + + parsing functions based on TextFinder library by Michael Margolis +*/ + +#ifndef Stream_h +#define Stream_h + +#include +#include "Print.h" + +// compatability macros for testing +/* +#define getInt() parseInt() +#define getInt(ignore) parseInt(ignore) +#define getFloat() parseFloat() +#define getFloat(ignore) parseFloat(ignore) +#define getString( pre_string, post_string, buffer, length) +readBytesBetween( pre_string, terminator, buffer, length) +*/ + +// This enumeration provides the lookahead options for parseInt(), parseFloat() +// The rules set out here are used until either the first valid character is found +// or a time out occurs due to lack of input. +enum LookaheadMode{ + SKIP_ALL, // All invalid characters are ignored. + SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid. + SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped. +}; + +#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field + +class Stream : public Print +{ + protected: + unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read + unsigned long _startMillis; // used for timeout measurement + int timedRead(); // private method to read stream with timeout + int timedPeek(); // private method to peek stream with timeout + int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout + + public: + virtual int available() = 0; + virtual int read() = 0; + virtual int peek() = 0; + virtual void flush() = 0; + + Stream() {_timeout=1000;} + +// parsing methods + + void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second + + bool find(char *target); // reads data from the stream until the target string is found + bool find(uint8_t *target) { return find ((char *)target); } + // returns true if target string is found, false if timed out (see setTimeout) + + bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found + bool find(uint8_t *target, size_t length) { return find ((char *)target, length); } + // returns true if target string is found, false if timed out + + bool find(char target) { return find (&target, 1); } + + bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found + bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); } + + bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found + bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); } + + long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // returns the first valid (long) integer value from the current position. + // lookahead determines how parseInt looks ahead in the stream. + // See LookaheadMode enumeration at the top of the file. + // Lookahead is terminated by the first character that is not a valid part of an integer. + // Once parsing commences, 'ignore' will be skipped in the stream. + + float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // float version of parseInt + + size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer + size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } + // terminates if length characters have been read or timeout (see setTimeout) + // returns the number of characters placed in the buffer (0 means no valid data found) + + size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character + size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); } + // terminates if length characters have been read, timeout, or if the terminator character detected + // returns the number of characters placed in the buffer (0 means no valid data found) + + // Arduino String functions to be added here + String readString(); + String readStringUntil(char terminator); + + protected: + long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); } + float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); } + // These overload exists for compatibility with any class that has derived + // Stream and used parseFloat/Int with a custom ignore character. To keep + // the public API simple, these overload remains protected. + + struct MultiTarget { + const char *str; // string you're searching for + size_t len; // length of string you're searching for + size_t index; // index used by the search routine. + }; + + // This allows you to search for an arbitrary number of strings. + // Returns index of the target that is found first or -1 if timeout occurs. + int findMulti(struct MultiTarget *targets, int tCount); +}; + +#undef NO_IGNORE_CHAR +#endif diff --git a/cpu/avr/dev/arduino/WMath.cpp b/cpu/avr/dev/arduino/WMath.cpp new file mode 100644 index 000000000..9fb072f46 --- /dev/null +++ b/cpu/avr/dev/arduino/WMath.cpp @@ -0,0 +1,58 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Wiring project - http://wiring.org.co + Copyright (c) 2004-06 Hernando Barragan + Modified 13 August 2006, David A. Mellis for Arduino - http://www.arduino.cc/ + + 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., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +extern "C" { + #include "stdlib.h" +} + +void randomSeed(unsigned long seed) +{ + if (seed != 0) { + srandom(seed); + } +} + +long random(long howbig) +{ + if (howbig == 0) { + return 0; + } + return random() % howbig; +} + +long random(long howsmall, long howbig) +{ + if (howsmall >= howbig) { + return howsmall; + } + long diff = howbig - howsmall; + return random(diff) + howsmall; +} + +long map(long x, long in_min, long in_max, long out_min, long out_max) +{ + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +unsigned int makeWord(unsigned int w) { return w; } +unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8) | l; } diff --git a/cpu/avr/dev/arduino/WString.cpp b/cpu/avr/dev/arduino/WString.cpp new file mode 100644 index 000000000..cd3e0e876 --- /dev/null +++ b/cpu/avr/dev/arduino/WString.cpp @@ -0,0 +1,745 @@ +/* + WString.cpp - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All rights reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + 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 +*/ + +#include "WString.h" + +/*********************************************/ +/* Constructors */ +/*********************************************/ + +String::String(const char *cstr) +{ + init(); + if (cstr) copy(cstr, strlen(cstr)); +} + +String::String(const String &value) +{ + init(); + *this = value; +} + +String::String(const __FlashStringHelper *pstr) +{ + init(); + *this = pstr; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +String::String(String &&rval) +{ + init(); + move(rval); +} +String::String(StringSumHelper &&rval) +{ + init(); + move(rval); +} +#endif + +String::String(char c) +{ + init(); + char buf[2]; + buf[0] = c; + buf[1] = 0; + *this = buf; +} + +String::String(unsigned char value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned char)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(int value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(int)]; + itoa(value, buf, base); + *this = buf; +} + +String::String(unsigned int value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned int)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(long value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(long)]; + ltoa(value, buf, base); + *this = buf; +} + +String::String(unsigned long value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned long)]; + ultoa(value, buf, base); + *this = buf; +} + +String::String(float value, unsigned char decimalPlaces) +{ + init(); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::String(double value, unsigned char decimalPlaces) +{ + init(); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::~String() +{ + free(buffer); +} + +/*********************************************/ +/* Memory Management */ +/*********************************************/ + +inline void String::init(void) +{ + buffer = NULL; + capacity = 0; + len = 0; +} + +void String::invalidate(void) +{ + if (buffer) free(buffer); + buffer = NULL; + capacity = len = 0; +} + +unsigned char String::reserve(unsigned int size) +{ + if (buffer && capacity >= size) return 1; + if (changeBuffer(size)) { + if (len == 0) buffer[0] = 0; + return 1; + } + return 0; +} + +unsigned char String::changeBuffer(unsigned int maxStrLen) +{ + char *newbuffer = (char *)realloc(buffer, maxStrLen + 1); + if (newbuffer) { + buffer = newbuffer; + capacity = maxStrLen; + return 1; + } + return 0; +} + +/*********************************************/ +/* Copy and Move */ +/*********************************************/ + +String & String::copy(const char *cstr, unsigned int length) +{ + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy(buffer, cstr); + return *this; +} + +String & String::copy(const __FlashStringHelper *pstr, unsigned int length) +{ + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy_P(buffer, (PGM_P)pstr); + return *this; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +void String::move(String &rhs) +{ + if (buffer) { + if (capacity >= rhs.len) { + strcpy(buffer, rhs.buffer); + len = rhs.len; + rhs.len = 0; + return; + } else { + free(buffer); + } + } + buffer = rhs.buffer; + capacity = rhs.capacity; + len = rhs.len; + rhs.buffer = NULL; + rhs.capacity = 0; + rhs.len = 0; +} +#endif + +String & String::operator = (const String &rhs) +{ + if (this == &rhs) return *this; + + if (rhs.buffer) copy(rhs.buffer, rhs.len); + else invalidate(); + + return *this; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +String & String::operator = (String &&rval) +{ + if (this != &rval) move(rval); + return *this; +} + +String & String::operator = (StringSumHelper &&rval) +{ + if (this != &rval) move(rval); + return *this; +} +#endif + +String & String::operator = (const char *cstr) +{ + if (cstr) copy(cstr, strlen(cstr)); + else invalidate(); + + return *this; +} + +String & String::operator = (const __FlashStringHelper *pstr) +{ + if (pstr) copy(pstr, strlen_P((PGM_P)pstr)); + else invalidate(); + + return *this; +} + +/*********************************************/ +/* concat */ +/*********************************************/ + +unsigned char String::concat(const String &s) +{ + return concat(s.buffer, s.len); +} + +unsigned char String::concat(const char *cstr, unsigned int length) +{ + unsigned int newlen = len + length; + if (!cstr) return 0; + if (length == 0) return 1; + if (!reserve(newlen)) return 0; + strcpy(buffer + len, cstr); + len = newlen; + return 1; +} + +unsigned char String::concat(const char *cstr) +{ + if (!cstr) return 0; + return concat(cstr, strlen(cstr)); +} + +unsigned char String::concat(char c) +{ + char buf[2]; + buf[0] = c; + buf[1] = 0; + return concat(buf, 1); +} + +unsigned char String::concat(unsigned char num) +{ + char buf[1 + 3 * sizeof(unsigned char)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(int num) +{ + char buf[2 + 3 * sizeof(int)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned int num) +{ + char buf[1 + 3 * sizeof(unsigned int)]; + utoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(long num) +{ + char buf[2 + 3 * sizeof(long)]; + ltoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned long num) +{ + char buf[1 + 3 * sizeof(unsigned long)]; + ultoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(float num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +unsigned char String::concat(double num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +unsigned char String::concat(const __FlashStringHelper * str) +{ + if (!str) return 0; + int length = strlen_P((const char *) str); + if (length == 0) return 1; + unsigned int newlen = len + length; + if (!reserve(newlen)) return 0; + strcpy_P(buffer + len, (const char *) str); + len = newlen; + return 1; +} + +/*********************************************/ +/* Concatenate */ +/*********************************************/ + +StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) +{ + StringSumHelper &a = const_cast(lhs); + if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, char c) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(c)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, float num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, double num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs)) a.invalidate(); + return a; +} + +/*********************************************/ +/* Comparison */ +/*********************************************/ + +int String::compareTo(const String &s) const +{ + if (!buffer || !s.buffer) { + if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; + if (buffer && len > 0) return *(unsigned char *)buffer; + return 0; + } + return strcmp(buffer, s.buffer); +} + +unsigned char String::equals(const String &s2) const +{ + return (len == s2.len && compareTo(s2) == 0); +} + +unsigned char String::equals(const char *cstr) const +{ + if (len == 0) return (cstr == NULL || *cstr == 0); + if (cstr == NULL) return buffer[0] == 0; + return strcmp(buffer, cstr) == 0; +} + +unsigned char String::operator<(const String &rhs) const +{ + return compareTo(rhs) < 0; +} + +unsigned char String::operator>(const String &rhs) const +{ + return compareTo(rhs) > 0; +} + +unsigned char String::operator<=(const String &rhs) const +{ + return compareTo(rhs) <= 0; +} + +unsigned char String::operator>=(const String &rhs) const +{ + return compareTo(rhs) >= 0; +} + +unsigned char String::equalsIgnoreCase( const String &s2 ) const +{ + if (this == &s2) return 1; + if (len != s2.len) return 0; + if (len == 0) return 1; + const char *p1 = buffer; + const char *p2 = s2.buffer; + while (*p1) { + if (tolower(*p1++) != tolower(*p2++)) return 0; + } + return 1; +} + +unsigned char String::startsWith( const String &s2 ) const +{ + if (len < s2.len) return 0; + return startsWith(s2, 0); +} + +unsigned char String::startsWith( const String &s2, unsigned int offset ) const +{ + if (offset > len - s2.len || !buffer || !s2.buffer) return 0; + return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0; +} + +unsigned char String::endsWith( const String &s2 ) const +{ + if ( len < s2.len || !buffer || !s2.buffer) return 0; + return strcmp(&buffer[len - s2.len], s2.buffer) == 0; +} + +/*********************************************/ +/* Character Access */ +/*********************************************/ + +char String::charAt(unsigned int loc) const +{ + return operator[](loc); +} + +void String::setCharAt(unsigned int loc, char c) +{ + if (loc < len) buffer[loc] = c; +} + +char & String::operator[](unsigned int index) +{ + static char dummy_writable_char; + if (index >= len || !buffer) { + dummy_writable_char = 0; + return dummy_writable_char; + } + return buffer[index]; +} + +char String::operator[]( unsigned int index ) const +{ + if (index >= len || !buffer) return 0; + return buffer[index]; +} + +void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const +{ + if (!bufsize || !buf) return; + if (index >= len) { + buf[0] = 0; + return; + } + unsigned int n = bufsize - 1; + if (n > len - index) n = len - index; + strncpy((char *)buf, buffer + index, n); + buf[n] = 0; +} + +/*********************************************/ +/* Search */ +/*********************************************/ + +int String::indexOf(char c) const +{ + return indexOf(c, 0); +} + +int String::indexOf( char ch, unsigned int fromIndex ) const +{ + if (fromIndex >= len) return -1; + const char* temp = strchr(buffer + fromIndex, ch); + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::indexOf(const String &s2) const +{ + return indexOf(s2, 0); +} + +int String::indexOf(const String &s2, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + const char *found = strstr(buffer + fromIndex, s2.buffer); + if (found == NULL) return -1; + return found - buffer; +} + +int String::lastIndexOf( char theChar ) const +{ + return lastIndexOf(theChar, len - 1); +} + +int String::lastIndexOf(char ch, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + char tempchar = buffer[fromIndex + 1]; + buffer[fromIndex + 1] = '\0'; + char* temp = strrchr( buffer, ch ); + buffer[fromIndex + 1] = tempchar; + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::lastIndexOf(const String &s2) const +{ + return lastIndexOf(s2, len - s2.len); +} + +int String::lastIndexOf(const String &s2, unsigned int fromIndex) const +{ + if (s2.len == 0 || len == 0 || s2.len > len) return -1; + if (fromIndex >= len) fromIndex = len - 1; + int found = -1; + for (char *p = buffer; p <= buffer + fromIndex; p++) { + p = strstr(p, s2.buffer); + if (!p) break; + if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; + } + return found; +} + +String String::substring(unsigned int left, unsigned int right) const +{ + if (left > right) { + unsigned int temp = right; + right = left; + left = temp; + } + String out; + if (left >= len) return out; + if (right > len) right = len; + char temp = buffer[right]; // save the replaced character + buffer[right] = '\0'; + out = buffer + left; // pointer arithmetic + buffer[right] = temp; //restore character + return out; +} + +/*********************************************/ +/* Modification */ +/*********************************************/ + +void String::replace(char find, char replace) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + if (*p == find) *p = replace; + } +} + +void String::replace(const String& find, const String& replace) +{ + if (len == 0 || find.len == 0) return; + int diff = replace.len - find.len; + char *readFrom = buffer; + char *foundAt; + if (diff == 0) { + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + memcpy(foundAt, replace.buffer, replace.len); + readFrom = foundAt + replace.len; + } + } else if (diff < 0) { + char *writeTo = buffer; + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + unsigned int n = foundAt - readFrom; + memcpy(writeTo, readFrom, n); + writeTo += n; + memcpy(writeTo, replace.buffer, replace.len); + writeTo += replace.len; + readFrom = foundAt + find.len; + len += diff; + } + strcpy(writeTo, readFrom); + } else { + unsigned int size = len; // compute size needed for result + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + readFrom = foundAt + find.len; + size += diff; + } + if (size == len) return; + if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! + int index = len - 1; + while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { + readFrom = buffer + index + find.len; + memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); + len += diff; + buffer[len] = 0; + memcpy(buffer + index, replace.buffer, replace.len); + index--; + } + } +} + +void String::remove(unsigned int index){ + // Pass the biggest integer as the count. The remove method + // below will take care of truncating it at the end of the + // string. + remove(index, (unsigned int)-1); +} + +void String::remove(unsigned int index, unsigned int count){ + if (index >= len) { return; } + if (count <= 0) { return; } + if (count > len - index) { count = len - index; } + char *writeTo = buffer + index; + len = len - count; + strncpy(writeTo, buffer + index + count,len - index); + buffer[len] = 0; +} + +void String::toLowerCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = tolower(*p); + } +} + +void String::toUpperCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = toupper(*p); + } +} + +void String::trim(void) +{ + if (!buffer || len == 0) return; + char *begin = buffer; + while (isspace(*begin)) begin++; + char *end = buffer + len - 1; + while (isspace(*end) && end >= begin) end--; + len = end + 1 - begin; + if (begin > buffer) memcpy(buffer, begin, len); + buffer[len] = 0; +} + +/*********************************************/ +/* Parsing / Conversion */ +/*********************************************/ + +long String::toInt(void) const +{ + if (buffer) return atol(buffer); + return 0; +} + +float String::toFloat(void) const +{ + if (buffer) return float(atof(buffer)); + return 0; +} diff --git a/cpu/avr/dev/arduino/WString.h b/cpu/avr/dev/arduino/WString.h new file mode 100644 index 000000000..b04798087 --- /dev/null +++ b/cpu/avr/dev/arduino/WString.h @@ -0,0 +1,224 @@ +/* + WString.h - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All right reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + 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 String_class_h +#define String_class_h +#ifdef __cplusplus + +#include +#include +#include +#include + +// When compiling programs with this class, the following gcc parameters +// dramatically increase performance and memory (RAM) efficiency, typically +// with little or no increase in code size. +// -felide-constructors +// -std=c++0x + +class __FlashStringHelper; +#define F(string_literal) (reinterpret_cast(PSTR(string_literal))) + +// An inherited class for holding the result of a concatenation. These +// result objects are assumed to be writable by subsequent concatenations. +class StringSumHelper; + +// The string class +class String +{ + // use a function pointer to allow for "if (s)" without the + // complications of an operator bool(). for more information, see: + // http://www.artima.com/cppsource/safebool.html + typedef void (String::*StringIfHelperType)() const; + void StringIfHelper() const {} + +public: + // constructors + // creates a copy of the initial value. + // if the initial value is null or invalid, or if memory allocation + // fails, the string will be marked as invalid (i.e. "if (s)" will + // be false). + String(const char *cstr = ""); + String(const String &str); + String(const __FlashStringHelper *str); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String(String &&rval); + String(StringSumHelper &&rval); + #endif + explicit String(char c); + explicit String(unsigned char, unsigned char base=10); + explicit String(int, unsigned char base=10); + explicit String(unsigned int, unsigned char base=10); + explicit String(long, unsigned char base=10); + explicit String(unsigned long, unsigned char base=10); + explicit String(float, unsigned char decimalPlaces=2); + explicit String(double, unsigned char decimalPlaces=2); + ~String(void); + + // memory management + // return true on success, false on failure (in which case, the string + // is left unchanged). reserve(0), if successful, will validate an + // invalid string (i.e., "if (s)" will be true afterwards) + unsigned char reserve(unsigned int size); + inline unsigned int length(void) const {return len;} + + // creates a copy of the assigned value. if the value is null or + // invalid, or if the memory allocation fails, the string will be + // marked as invalid ("if (s)" will be false). + String & operator = (const String &rhs); + String & operator = (const char *cstr); + String & operator = (const __FlashStringHelper *str); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String & operator = (String &&rval); + String & operator = (StringSumHelper &&rval); + #endif + + // concatenate (works w/ built-in types) + + // returns true on success, false on failure (in which case, the string + // is left unchanged). if the argument is null or invalid, the + // concatenation is considered unsucessful. + unsigned char concat(const String &str); + unsigned char concat(const char *cstr); + unsigned char concat(char c); + unsigned char concat(unsigned char c); + unsigned char concat(int num); + unsigned char concat(unsigned int num); + unsigned char concat(long num); + unsigned char concat(unsigned long num); + unsigned char concat(float num); + unsigned char concat(double num); + unsigned char concat(const __FlashStringHelper * str); + + // if there's not enough memory for the concatenated value, the string + // will be left unchanged (but this isn't signalled in any way) + String & operator += (const String &rhs) {concat(rhs); return (*this);} + String & operator += (const char *cstr) {concat(cstr); return (*this);} + String & operator += (char c) {concat(c); return (*this);} + String & operator += (unsigned char num) {concat(num); return (*this);} + String & operator += (int num) {concat(num); return (*this);} + String & operator += (unsigned int num) {concat(num); return (*this);} + String & operator += (long num) {concat(num); return (*this);} + String & operator += (unsigned long num) {concat(num); return (*this);} + String & operator += (float num) {concat(num); return (*this);} + String & operator += (double num) {concat(num); return (*this);} + String & operator += (const __FlashStringHelper *str){concat(str); return (*this);} + + friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); + friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); + + // comparison (only works w/ Strings and "strings") + operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; } + int compareTo(const String &s) const; + unsigned char equals(const String &s) const; + unsigned char equals(const char *cstr) const; + unsigned char operator == (const String &rhs) const {return equals(rhs);} + unsigned char operator == (const char *cstr) const {return equals(cstr);} + unsigned char operator != (const String &rhs) const {return !equals(rhs);} + unsigned char operator != (const char *cstr) const {return !equals(cstr);} + unsigned char operator < (const String &rhs) const; + unsigned char operator > (const String &rhs) const; + unsigned char operator <= (const String &rhs) const; + unsigned char operator >= (const String &rhs) const; + unsigned char equalsIgnoreCase(const String &s) const; + unsigned char startsWith( const String &prefix) const; + unsigned char startsWith(const String &prefix, unsigned int offset) const; + unsigned char endsWith(const String &suffix) const; + + // character acccess + char charAt(unsigned int index) const; + void setCharAt(unsigned int index, char c); + char operator [] (unsigned int index) const; + char& operator [] (unsigned int index); + void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const; + void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const + {getBytes((unsigned char *)buf, bufsize, index);} + const char * c_str() const { return buffer; } + + // search + int indexOf( char ch ) const; + int indexOf( char ch, unsigned int fromIndex ) const; + int indexOf( const String &str ) const; + int indexOf( const String &str, unsigned int fromIndex ) const; + int lastIndexOf( char ch ) const; + int lastIndexOf( char ch, unsigned int fromIndex ) const; + int lastIndexOf( const String &str ) const; + int lastIndexOf( const String &str, unsigned int fromIndex ) const; + String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); }; + String substring( unsigned int beginIndex, unsigned int endIndex ) const; + + // modification + void replace(char find, char replace); + void replace(const String& find, const String& replace); + void remove(unsigned int index); + void remove(unsigned int index, unsigned int count); + void toLowerCase(void); + void toUpperCase(void); + void trim(void); + + // parsing/conversion + long toInt(void) const; + float toFloat(void) const; + +protected: + char *buffer; // the actual char array + unsigned int capacity; // the array length minus one (for the '\0') + unsigned int len; // the String length (not counting the '\0') +protected: + void init(void); + void invalidate(void); + unsigned char changeBuffer(unsigned int maxStrLen); + unsigned char concat(const char *cstr, unsigned int length); + + // copy and move + String & copy(const char *cstr, unsigned int length); + String & copy(const __FlashStringHelper *pstr, unsigned int length); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + void move(String &rhs); + #endif +}; + +class StringSumHelper : public String +{ +public: + StringSumHelper(const String &s) : String(s) {} + StringSumHelper(const char *p) : String(p) {} + StringSumHelper(char c) : String(c) {} + StringSumHelper(unsigned char num) : String(num) {} + StringSumHelper(int num) : String(num) {} + StringSumHelper(unsigned int num) : String(num) {} + StringSumHelper(long num) : String(num) {} + StringSumHelper(unsigned long num) : String(num) {} + StringSumHelper(float num) : String(num) {} + StringSumHelper(double num) : String(num) {} +}; + +#endif // __cplusplus +#endif // String_class_h diff --git a/cpu/avr/dev/arduino/Wire.cpp b/cpu/avr/dev/arduino/Wire.cpp new file mode 100644 index 000000000..2bd48ed8a --- /dev/null +++ b/cpu/avr/dev/arduino/Wire.cpp @@ -0,0 +1,330 @@ +/* + TwoWire.cpp - TWI/I2C library for Wiring & Arduino + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + 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 + + Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts +*/ + +extern "C" { + #include + #include + #include + #include "twi.h" +} + +#include "Wire.h" + +// Initialize Class Variables ////////////////////////////////////////////////// + +uint8_t TwoWire::rxBuffer[BUFFER_LENGTH]; +uint8_t TwoWire::rxBufferIndex = 0; +uint8_t TwoWire::rxBufferLength = 0; + +uint8_t TwoWire::txAddress = 0; +uint8_t TwoWire::txBuffer[BUFFER_LENGTH]; +uint8_t TwoWire::txBufferIndex = 0; +uint8_t TwoWire::txBufferLength = 0; + +uint8_t TwoWire::transmitting = 0; +void (*TwoWire::user_onRequest)(void); +void (*TwoWire::user_onReceive)(int); + +// Constructors //////////////////////////////////////////////////////////////// + +TwoWire::TwoWire() +{ +} + +// Public Methods ////////////////////////////////////////////////////////////// + +void TwoWire::begin(void) +{ + rxBufferIndex = 0; + rxBufferLength = 0; + + txBufferIndex = 0; + txBufferLength = 0; + + twi_init(); +} + +void TwoWire::begin(uint8_t address) +{ + twi_setAddress(address); + twi_attachSlaveTxEvent(onRequestService); + twi_attachSlaveRxEvent(onReceiveService); + begin(); +} + +void TwoWire::begin(int address) +{ + begin((uint8_t)address); +} + +void TwoWire::end(void) +{ + twi_disable(); +} + +void TwoWire::setClock(uint32_t frequency) +{ + TWBR = ((F_CPU / frequency) - 16) / 2; +} + +uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop) +{ + if (isize > 0) { + // send internal address; this mode allows sending a repeated start to access + // some devices' internal registers. This function is executed by the hardware + // TWI module on other processors (for example Due's TWI_IADR and TWI_MMR registers) + + beginTransmission(address); + + // the maximum size of internal address is 3 bytes + if (isize > 3){ + isize = 3; + } + + // write internal register address - most significant byte first + while (isize-- > 0) + write((uint8_t)(iaddress >> (isize*8))); + endTransmission(false); + } + + // clamp to buffer length + if(quantity > BUFFER_LENGTH){ + quantity = BUFFER_LENGTH; + } + // perform blocking read into buffer + uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop); + // set rx buffer iterator vars + rxBufferIndex = 0; + rxBufferLength = read; + + return read; +} + +uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) { + return requestFrom((uint8_t)address, (uint8_t)quantity, (uint32_t)0, (uint8_t)0, (uint8_t)sendStop); +} + +uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) +{ + return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true); +} + +uint8_t TwoWire::requestFrom(int address, int quantity) +{ + return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true); +} + +uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) +{ + return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop); +} + +void TwoWire::beginTransmission(uint8_t address) +{ + // indicate that we are transmitting + transmitting = 1; + // set address of targeted slave + txAddress = address; + // reset tx buffer iterator vars + txBufferIndex = 0; + txBufferLength = 0; +} + +void TwoWire::beginTransmission(int address) +{ + beginTransmission((uint8_t)address); +} + +// +// Originally, 'endTransmission' was an f(void) function. +// It has been modified to take one parameter indicating +// whether or not a STOP should be performed on the bus. +// Calling endTransmission(false) allows a sketch to +// perform a repeated start. +// +// WARNING: Nothing in the library keeps track of whether +// the bus tenure has been properly ended with a STOP. It +// is very possible to leave the bus in a hung state if +// no call to endTransmission(true) is made. Some I2C +// devices will behave oddly if they do not see a STOP. +// +uint8_t TwoWire::endTransmission(uint8_t sendStop) +{ + // transmit buffer (blocking) + int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop); + // reset tx buffer iterator vars + txBufferIndex = 0; + txBufferLength = 0; + // indicate that we are done transmitting + transmitting = 0; + return ret; +} + +// This provides backwards compatibility with the original +// definition, and expected behaviour, of endTransmission +// +uint8_t TwoWire::endTransmission(void) +{ + return endTransmission(true); +} + +// must be called in: +// slave tx event callback +// or after beginTransmission(address) +size_t TwoWire::write(uint8_t data) +{ + if(transmitting){ + // in master transmitter mode + // don't bother if buffer is full + if(txBufferLength >= BUFFER_LENGTH){ + setWriteError(); + return 0; + } + // put byte in tx buffer + txBuffer[txBufferIndex] = data; + ++txBufferIndex; + // update amount in buffer + txBufferLength = txBufferIndex; + }else{ + // in slave send mode + // reply to master + twi_transmit(&data, 1); + } + return 1; +} + +// must be called in: +// slave tx event callback +// or after beginTransmission(address) +size_t TwoWire::write(const uint8_t *data, size_t quantity) +{ + if(transmitting){ + // in master transmitter mode + for(size_t i = 0; i < quantity; ++i){ + write(data[i]); + } + }else{ + // in slave send mode + // reply to master + twi_transmit(data, quantity); + } + return quantity; +} + +// must be called in: +// slave rx event callback +// or after requestFrom(address, numBytes) +int TwoWire::available(void) +{ + return rxBufferLength - rxBufferIndex; +} + +// must be called in: +// slave rx event callback +// or after requestFrom(address, numBytes) +int TwoWire::read(void) +{ + int value = -1; + + // get each successive byte on each call + if(rxBufferIndex < rxBufferLength){ + value = rxBuffer[rxBufferIndex]; + ++rxBufferIndex; + } + + return value; +} + +// must be called in: +// slave rx event callback +// or after requestFrom(address, numBytes) +int TwoWire::peek(void) +{ + int value = -1; + + if(rxBufferIndex < rxBufferLength){ + value = rxBuffer[rxBufferIndex]; + } + + return value; +} + +void TwoWire::flush(void) +{ + // XXX: to be implemented. +} + +// behind the scenes function that is called when data is received +void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes) +{ + // don't bother if user hasn't registered a callback + if(!user_onReceive){ + return; + } + // don't bother if rx buffer is in use by a master requestFrom() op + // i know this drops data, but it allows for slight stupidity + // meaning, they may not have read all the master requestFrom() data yet + if(rxBufferIndex < rxBufferLength){ + return; + } + // copy twi rx buffer into local read buffer + // this enables new reads to happen in parallel + for(uint8_t i = 0; i < numBytes; ++i){ + rxBuffer[i] = inBytes[i]; + } + // set rx iterator vars + rxBufferIndex = 0; + rxBufferLength = numBytes; + // alert user program + user_onReceive(numBytes); +} + +// behind the scenes function that is called when data is requested +void TwoWire::onRequestService(void) +{ + // don't bother if user hasn't registered a callback + if(!user_onRequest){ + return; + } + // reset tx buffer iterator vars + // !!! this will kill any pending pre-master sendTo() activity + txBufferIndex = 0; + txBufferLength = 0; + // alert user program + user_onRequest(); +} + +// sets function called on slave write +void TwoWire::onReceive( void (*function)(int) ) +{ + user_onReceive = function; +} + +// sets function called on slave read +void TwoWire::onRequest( void (*function)(void) ) +{ + user_onRequest = function; +} + +// Preinstantiate Objects ////////////////////////////////////////////////////// + +TwoWire Wire = TwoWire(); + diff --git a/cpu/avr/dev/arduino/Wire.h b/cpu/avr/dev/arduino/Wire.h new file mode 100644 index 000000000..702f37d64 --- /dev/null +++ b/cpu/avr/dev/arduino/Wire.h @@ -0,0 +1,85 @@ +/* + TwoWire.h - TWI/I2C library for Arduino & Wiring + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + 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 + + Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts +*/ + +#ifndef TwoWire_h +#define TwoWire_h + +#include +#include "Stream.h" + +#define BUFFER_LENGTH 32 + +// WIRE_HAS_END means Wire has end() +#define WIRE_HAS_END 1 + +class TwoWire : public Stream +{ + private: + static uint8_t rxBuffer[]; + static uint8_t rxBufferIndex; + static uint8_t rxBufferLength; + + static uint8_t txAddress; + static uint8_t txBuffer[]; + static uint8_t txBufferIndex; + static uint8_t txBufferLength; + + static uint8_t transmitting; + static void (*user_onRequest)(void); + static void (*user_onReceive)(int); + static void onRequestService(void); + static void onReceiveService(uint8_t*, int); + public: + TwoWire(); + void begin(); + void begin(uint8_t); + void begin(int); + void end(); + void setClock(uint32_t); + void beginTransmission(uint8_t); + void beginTransmission(int); + uint8_t endTransmission(void); + uint8_t endTransmission(uint8_t); + uint8_t requestFrom(uint8_t, uint8_t); + uint8_t requestFrom(uint8_t, uint8_t, uint8_t); + uint8_t requestFrom(uint8_t, uint8_t, uint32_t, uint8_t, uint8_t); + uint8_t requestFrom(int, int); + uint8_t requestFrom(int, int, int); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *, size_t); + virtual int available(void); + virtual int read(void); + virtual int peek(void); + virtual void flush(void); + void onReceive( void (*)(int) ); + void onRequest( void (*)(void) ); + + inline size_t write(unsigned long n) { return write((uint8_t)n); } + inline size_t write(long n) { return write((uint8_t)n); } + inline size_t write(unsigned int n) { return write((uint8_t)n); } + inline size_t write(int n) { return write((uint8_t)n); } + using Print::write; +}; + +extern TwoWire Wire; + +#endif + diff --git a/platform/osd-merkur/dev/binary.h b/cpu/avr/dev/arduino/binary.h similarity index 100% rename from platform/osd-merkur/dev/binary.h rename to cpu/avr/dev/arduino/binary.h diff --git a/platform/osd-merkur/dev/hw-arduino.h b/cpu/avr/dev/arduino/hw-arduino.h similarity index 100% rename from platform/osd-merkur/dev/hw-arduino.h rename to cpu/avr/dev/arduino/hw-arduino.h diff --git a/cpu/avr/dev/arduino/new.cpp b/cpu/avr/dev/arduino/new.cpp new file mode 100644 index 000000000..cf6f89c17 --- /dev/null +++ b/cpu/avr/dev/arduino/new.cpp @@ -0,0 +1,36 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + 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 +*/ + +#include + +void *operator new(size_t size) { + return malloc(size); +} + +void *operator new[](size_t size) { + return malloc(size); +} + +void operator delete(void * ptr) { + free(ptr); +} + +void operator delete[](void * ptr) { + free(ptr); +} + diff --git a/cpu/avr/dev/arduino/new.h b/cpu/avr/dev/arduino/new.h new file mode 100644 index 000000000..6e1b68f0d --- /dev/null +++ b/cpu/avr/dev/arduino/new.h @@ -0,0 +1,30 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + 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 NEW_H +#define NEW_H + +#include + +void * operator new(size_t size); +void * operator new[](size_t size); +void operator delete(void * ptr); +void operator delete[](void * ptr); + +#endif + diff --git a/cpu/avr/dev/arduino/twi.c b/cpu/avr/dev/arduino/twi.c new file mode 100644 index 000000000..2af0597dd --- /dev/null +++ b/cpu/avr/dev/arduino/twi.c @@ -0,0 +1,545 @@ +/* + twi.c - TWI/I2C library for Wiring & Arduino + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + 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 + + Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts +*/ + +#include +#include +#include +#include +#include +#include +#include "Arduino.h" // for digitalWrite + +#ifndef cbi +#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +#endif + +#ifndef sbi +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#endif + +#include "pins_arduino.h" +#include "twi.h" + +static volatile uint8_t twi_state; +static volatile uint8_t twi_slarw; +static volatile uint8_t twi_sendStop; // should the transaction end with a stop +static volatile uint8_t twi_inRepStart; // in the middle of a repeated start + +static void (*twi_onSlaveTransmit)(void); +static void (*twi_onSlaveReceive)(uint8_t*, int); + +static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; +static volatile uint8_t twi_masterBufferIndex; +static volatile uint8_t twi_masterBufferLength; + +static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH]; +static volatile uint8_t twi_txBufferIndex; +static volatile uint8_t twi_txBufferLength; + +static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; +static volatile uint8_t twi_rxBufferIndex; + +static volatile uint8_t twi_error; + +/* + * Function twi_init + * Desc readys twi pins and sets twi bitrate + * Input none + * Output none + */ +void twi_init(void) +{ + // initialize state + twi_state = TWI_READY; + twi_sendStop = true; // default value + twi_inRepStart = false; + + // activate internal pullups for twi. + digitalWrite(SDA, 1); + digitalWrite(SCL, 1); + + // initialize twi prescaler and bit rate + cbi(TWSR, TWPS0); + cbi(TWSR, TWPS1); + TWBR = ((F_CPU / TWI_FREQ) - 16) / 2; + + /* twi bit rate formula from atmega128 manual pg 204 + SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) + note: TWBR should be 10 or higher for master mode + It is 72 for a 16mhz Wiring board with 100kHz TWI */ + + // enable twi module, acks, and twi interrupt + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); +} + +/* + * Function twi_disable + * Desc disables twi pins + * Input none + * Output none + */ +void twi_disable(void) +{ + // disable twi module, acks, and twi interrupt + TWCR &= ~(_BV(TWEN) | _BV(TWIE) | _BV(TWEA)); + + // deactivate internal pullups for twi. + digitalWrite(SDA, 0); + digitalWrite(SCL, 0); +} + +/* + * Function twi_slaveInit + * Desc sets slave address and enables interrupt + * Input none + * Output none + */ +void twi_setAddress(uint8_t address) +{ + // set twi slave address (skip over TWGCE bit) + TWAR = address << 1; +} + +/* + * Function twi_readFrom + * Desc attempts to become twi bus master and read a + * series of bytes from a device on the bus + * Input address: 7bit i2c device address + * data: pointer to byte array + * length: number of bytes to read into array + * sendStop: Boolean indicating whether to send a stop at the end + * Output number of bytes read + */ +uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) +{ + uint8_t i; + + // ensure data will fit into buffer + if(TWI_BUFFER_LENGTH < length){ + return 0; + } + + // wait until twi is ready, become master receiver + while(TWI_READY != twi_state){ + continue; + } + twi_state = TWI_MRX; + twi_sendStop = sendStop; + // reset error state (0xFF.. no error occured) + twi_error = 0xFF; + + // initialize buffer iteration vars + twi_masterBufferIndex = 0; + twi_masterBufferLength = length-1; // This is not intuitive, read on... + // On receive, the previously configured ACK/NACK setting is transmitted in + // response to the received byte before the interrupt is signalled. + // Therefor we must actually set NACK when the _next_ to last byte is + // received, causing that NACK to be sent in response to receiving the last + // expected byte of data. + + // build sla+w, slave device address + w bit + twi_slarw = TW_READ; + twi_slarw |= address << 1; + + if (true == twi_inRepStart) { + // if we're in the repeated start state, then we've already sent the start, + // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. + // We need to remove ourselves from the repeated start state before we enable interrupts, + // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning + // up. Also, don't enable the START interrupt. There may be one pending from the + // repeated start that we sent outselves, and that would really confuse things. + twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR + do { + TWDR = twi_slarw; + } while(TWCR & _BV(TWWC)); + TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START + } + else + // send start condition + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); + + // wait for read operation to complete + while(TWI_MRX == twi_state){ + continue; + } + + if (twi_masterBufferIndex < length) + length = twi_masterBufferIndex; + + // copy twi buffer to data + for(i = 0; i < length; ++i){ + data[i] = twi_masterBuffer[i]; + } + + return length; +} + +/* + * Function twi_writeTo + * Desc attempts to become twi bus master and write a + * series of bytes to a device on the bus + * Input address: 7bit i2c device address + * data: pointer to byte array + * length: number of bytes in array + * wait: boolean indicating to wait for write or not + * sendStop: boolean indicating whether or not to send a stop at the end + * Output 0 .. success + * 1 .. length to long for buffer + * 2 .. address send, NACK received + * 3 .. data send, NACK received + * 4 .. other twi error (lost bus arbitration, bus error, ..) + */ +uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop) +{ + uint8_t i; + + // ensure data will fit into buffer + if(TWI_BUFFER_LENGTH < length){ + return 1; + } + + // wait until twi is ready, become master transmitter + while(TWI_READY != twi_state){ + continue; + } + twi_state = TWI_MTX; + twi_sendStop = sendStop; + // reset error state (0xFF.. no error occured) + twi_error = 0xFF; + + // initialize buffer iteration vars + twi_masterBufferIndex = 0; + twi_masterBufferLength = length; + + // copy data to twi buffer + for(i = 0; i < length; ++i){ + twi_masterBuffer[i] = data[i]; + } + + // build sla+w, slave device address + w bit + twi_slarw = TW_WRITE; + twi_slarw |= address << 1; + + // if we're in a repeated start, then we've already sent the START + // in the ISR. Don't do it again. + // + if (true == twi_inRepStart) { + // if we're in the repeated start state, then we've already sent the start, + // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. + // We need to remove ourselves from the repeated start state before we enable interrupts, + // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning + // up. Also, don't enable the START interrupt. There may be one pending from the + // repeated start that we sent outselves, and that would really confuse things. + twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR + do { + TWDR = twi_slarw; + } while(TWCR & _BV(TWWC)); + TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START + } + else + // send start condition + TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs + + // wait for write operation to complete + while(wait && (TWI_MTX == twi_state)){ + continue; + } + + if (twi_error == 0xFF) + return 0; // success + else if (twi_error == TW_MT_SLA_NACK) + return 2; // error: address send, nack received + else if (twi_error == TW_MT_DATA_NACK) + return 3; // error: data send, nack received + else + return 4; // other twi error +} + +/* + * Function twi_transmit + * Desc fills slave tx buffer with data + * must be called in slave tx event callback + * Input data: pointer to byte array + * length: number of bytes in array + * Output 1 length too long for buffer + * 2 not slave transmitter + * 0 ok + */ +uint8_t twi_transmit(const uint8_t* data, uint8_t length) +{ + uint8_t i; + + // ensure data will fit into buffer + if(TWI_BUFFER_LENGTH < length){ + return 1; + } + + // ensure we are currently a slave transmitter + if(TWI_STX != twi_state){ + return 2; + } + + // set length and copy data into tx buffer + twi_txBufferLength = length; + for(i = 0; i < length; ++i){ + twi_txBuffer[i] = data[i]; + } + + return 0; +} + +/* + * Function twi_attachSlaveRxEvent + * Desc sets function called before a slave read operation + * Input function: callback function to use + * Output none + */ +void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) ) +{ + twi_onSlaveReceive = function; +} + +/* + * Function twi_attachSlaveTxEvent + * Desc sets function called before a slave write operation + * Input function: callback function to use + * Output none + */ +void twi_attachSlaveTxEvent( void (*function)(void) ) +{ + twi_onSlaveTransmit = function; +} + +/* + * Function twi_reply + * Desc sends byte or readys receive line + * Input ack: byte indicating to ack or to nack + * Output none + */ +void twi_reply(uint8_t ack) +{ + // transmit master read ready signal, with or without ack + if(ack){ + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); + }else{ + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); + } +} + +/* + * Function twi_stop + * Desc relinquishes bus master status + * Input none + * Output none + */ +void twi_stop(void) +{ + // send stop condition + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO); + + // wait for stop condition to be exectued on bus + // TWINT is not set after a stop condition! + while(TWCR & _BV(TWSTO)){ + continue; + } + + // update twi state + twi_state = TWI_READY; +} + +/* + * Function twi_releaseBus + * Desc releases bus control + * Input none + * Output none + */ +void twi_releaseBus(void) +{ + // release bus + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); + + // update twi state + twi_state = TWI_READY; +} + +ISR(TWI_vect) +{ + switch(TW_STATUS){ + // All Master + case TW_START: // sent start condition + case TW_REP_START: // sent repeated start condition + // copy device address and r/w bit to output register and ack + TWDR = twi_slarw; + twi_reply(1); + break; + + // Master Transmitter + case TW_MT_SLA_ACK: // slave receiver acked address + case TW_MT_DATA_ACK: // slave receiver acked data + // if there is data to send, send it, otherwise stop + if(twi_masterBufferIndex < twi_masterBufferLength){ + // copy data to output register and ack + TWDR = twi_masterBuffer[twi_masterBufferIndex++]; + twi_reply(1); + }else{ + if (twi_sendStop) + twi_stop(); + else { + twi_inRepStart = true; // we're gonna send the START + // don't enable the interrupt. We'll generate the start, but we + // avoid handling the interrupt until we're in the next transaction, + // at the point where we would normally issue the start. + TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; + twi_state = TWI_READY; + } + } + break; + case TW_MT_SLA_NACK: // address sent, nack received + twi_error = TW_MT_SLA_NACK; + twi_stop(); + break; + case TW_MT_DATA_NACK: // data sent, nack received + twi_error = TW_MT_DATA_NACK; + twi_stop(); + break; + case TW_MT_ARB_LOST: // lost bus arbitration + twi_error = TW_MT_ARB_LOST; + twi_releaseBus(); + break; + + // Master Receiver + case TW_MR_DATA_ACK: // data received, ack sent + // put byte into buffer + twi_masterBuffer[twi_masterBufferIndex++] = TWDR; + case TW_MR_SLA_ACK: // address sent, ack received + // ack if more bytes are expected, otherwise nack + if(twi_masterBufferIndex < twi_masterBufferLength){ + twi_reply(1); + }else{ + twi_reply(0); + } + break; + case TW_MR_DATA_NACK: // data received, nack sent + // put final byte into buffer + twi_masterBuffer[twi_masterBufferIndex++] = TWDR; + if (twi_sendStop) + twi_stop(); + else { + twi_inRepStart = true; // we're gonna send the START + // don't enable the interrupt. We'll generate the start, but we + // avoid handling the interrupt until we're in the next transaction, + // at the point where we would normally issue the start. + TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; + twi_state = TWI_READY; + } + break; + case TW_MR_SLA_NACK: // address sent, nack received + twi_stop(); + break; + // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case + + // Slave Receiver + case TW_SR_SLA_ACK: // addressed, returned ack + case TW_SR_GCALL_ACK: // addressed generally, returned ack + case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack + case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack + // enter slave receiver mode + twi_state = TWI_SRX; + // indicate that rx buffer can be overwritten and ack + twi_rxBufferIndex = 0; + twi_reply(1); + break; + case TW_SR_DATA_ACK: // data received, returned ack + case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack + // if there is still room in the rx buffer + if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ + // put byte in buffer and ack + twi_rxBuffer[twi_rxBufferIndex++] = TWDR; + twi_reply(1); + }else{ + // otherwise nack + twi_reply(0); + } + break; + case TW_SR_STOP: // stop or repeated start condition received + // ack future responses and leave slave receiver state + twi_releaseBus(); + // put a null char after data if there's room + if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ + twi_rxBuffer[twi_rxBufferIndex] = '\0'; + } + // callback to user defined callback + twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); + // since we submit rx buffer to "wire" library, we can reset it + twi_rxBufferIndex = 0; + break; + case TW_SR_DATA_NACK: // data received, returned nack + case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack + // nack back at master + twi_reply(0); + break; + + // Slave Transmitter + case TW_ST_SLA_ACK: // addressed, returned ack + case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack + // enter slave transmitter mode + twi_state = TWI_STX; + // ready the tx buffer index for iteration + twi_txBufferIndex = 0; + // set tx buffer length to be zero, to verify if user changes it + twi_txBufferLength = 0; + // request for txBuffer to be filled and length to be set + // note: user must call twi_transmit(bytes, length) to do this + twi_onSlaveTransmit(); + // if they didn't change buffer & length, initialize it + if(0 == twi_txBufferLength){ + twi_txBufferLength = 1; + twi_txBuffer[0] = 0x00; + } + // transmit first byte from buffer, fall + case TW_ST_DATA_ACK: // byte sent, ack returned + // copy data to output register + TWDR = twi_txBuffer[twi_txBufferIndex++]; + // if there is more to send, ack, otherwise nack + if(twi_txBufferIndex < twi_txBufferLength){ + twi_reply(1); + }else{ + twi_reply(0); + } + break; + case TW_ST_DATA_NACK: // received nack, we are done + case TW_ST_LAST_DATA: // received ack, but we are done already! + // ack future responses + twi_reply(1); + // leave slave receiver state + twi_state = TWI_READY; + break; + + // All + case TW_NO_INFO: // no state information + break; + case TW_BUS_ERROR: // bus error, illegal stop/start + twi_error = TW_BUS_ERROR; + twi_stop(); + break; + } +} + diff --git a/cpu/avr/dev/arduino/twi.h b/cpu/avr/dev/arduino/twi.h new file mode 100644 index 000000000..4c52bc5a0 --- /dev/null +++ b/cpu/avr/dev/arduino/twi.h @@ -0,0 +1,54 @@ +/* + twi.h - TWI/I2C library for Wiring & Arduino + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + 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 twi_h +#define twi_h + + #include + + //#define ATMEGA8 + + #ifndef TWI_FREQ + #define TWI_FREQ 100000L + #endif + + #ifndef TWI_BUFFER_LENGTH + #define TWI_BUFFER_LENGTH 32 + #endif + + #define TWI_READY 0 + #define TWI_MRX 1 + #define TWI_MTX 2 + #define TWI_SRX 3 + #define TWI_STX 4 + + void twi_init(void); + void twi_disable(void); + void twi_setAddress(uint8_t); + uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t); + uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t); + uint8_t twi_transmit(const uint8_t*, uint8_t); + void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) ); + void twi_attachSlaveTxEvent( void (*)(void) ); + void twi_reply(uint8_t); + void twi_stop(void); + void twi_releaseBus(void); + +#endif + diff --git a/platform/osd-merkur/dev/wiring_digital.c b/cpu/avr/dev/arduino/wiring_digital.c similarity index 100% rename from platform/osd-merkur/dev/wiring_digital.c rename to cpu/avr/dev/arduino/wiring_digital.c diff --git a/platform/osd-merkur/dev/wiring_private.h b/cpu/avr/dev/arduino/wiring_private.h similarity index 100% rename from platform/osd-merkur/dev/wiring_private.h rename to cpu/avr/dev/arduino/wiring_private.h diff --git a/platform/osd-merkur/dev/batmon.c b/cpu/avr/dev/batmon.c similarity index 100% rename from platform/osd-merkur/dev/batmon.c rename to cpu/avr/dev/batmon.c diff --git a/platform/osd-merkur/dev/batmon.h b/cpu/avr/dev/batmon.h similarity index 100% rename from platform/osd-merkur/dev/batmon.h rename to cpu/avr/dev/batmon.h diff --git a/platform/osd-merkur/dev/battery-sensor.c b/cpu/avr/dev/battery-sensor.c similarity index 100% rename from platform/osd-merkur/dev/battery-sensor.c rename to cpu/avr/dev/battery-sensor.c diff --git a/platform/osd-merkur/dev/battery-sensor.h b/cpu/avr/dev/battery-sensor.h similarity index 100% rename from platform/osd-merkur/dev/battery-sensor.h rename to cpu/avr/dev/battery-sensor.h diff --git a/platform/osd-merkur/dev/button-sensor.c b/cpu/avr/dev/button-sensor.c similarity index 97% rename from platform/osd-merkur/dev/button-sensor.c rename to cpu/avr/dev/button-sensor.c index 4bf62ea5a..067df7246 100644 --- a/platform/osd-merkur/dev/button-sensor.c +++ b/cpu/avr/dev/button-sensor.c @@ -27,7 +27,7 @@ ISR(INT4_vect) if(BUTTON_CHECK_IRQ()) { if(timer_expired(&debouncetimer)) { // led1_on(); - timer_set(&debouncetimer, CLOCK_SECOND / 4); + timer_set(&debouncetimer, CLOCK_SECOND / 8); sensors_changed(&button_sensor); // led1_off(); } diff --git a/cpu/avr/dev/clock-avr.h b/cpu/avr/dev/clock-avr.h index 97a79ee23..662bd21d3 100644 --- a/cpu/avr/dev/clock-avr.h +++ b/cpu/avr/dev/clock-avr.h @@ -73,7 +73,7 @@ TIMSK0 = _BV (OCIE0A); -#elif defined (__AVR_ATmega1284P__) || (__AVR_AT90USB1287__) || (__AVR_ATmega1281__) || defined (__AVR_ATmega128RFA1__) +#elif defined (__AVR_ATmega1284P__) || (__AVR_AT90USB1287__) || (__AVR_ATmega1281__) || defined (__AVR_ATmega128RFA1__) || defined (__AVR_ATmega128RFR2__) || defined (__AVR_ATmega256RFR2__) /* The Raven has a 32768Hz watch crystal that can be used to clock the timer while the 1284p is sleeping. The Jackdaw has pads for a crystal. The crystal diff --git a/cpu/avr/dev/clock.c b/cpu/avr/dev/clock.c index ea646562c..95e730feb 100644 --- a/cpu/avr/dev/clock.c +++ b/cpu/avr/dev/clock.c @@ -72,7 +72,7 @@ #include /* Two tick counters avoid a software divide when CLOCK_SECOND is not a power of two. */ -#if CLOCK_SECOND && (CLOCK_SECOND - 1) +#if CLOCK_SECOND & (CLOCK_SECOND - 1) #define TWO_COUNTERS 1 #endif @@ -159,7 +159,7 @@ clock_set_seconds(unsigned long sec) seconds = sec; } /*---------------------------------------------------------------------------*/ -/** +/* * Wait for a number of clock ticks. */ void @@ -175,7 +175,7 @@ clock_wait(clock_time_t t) } } /*---------------------------------------------------------------------------*/ -/** +/* * Delay the CPU for up to 65535*(4000000/F_CPU) microseconds. * Copied from _delay_loop_2 in AVR library delay_basic.h, 4 clocks per loop. * For accurate short delays, inline _delay_loop_2 in the caller, use a constant @@ -193,44 +193,44 @@ my_delay_loop_2(uint16_t __count) ); } void -clock_delay_usec(uint16_t howlong) +clock_delay_usec(uint16_t dt) { #if 0 /* Accurate delay at any frequency, but introduces a 64 bit intermediate * and has a 279 clock overhead. */ - if(howlong<=(uint16_t)(279000000UL/F_CPU)) return; - howlong-=(uint16_t) (279000000UL/F_CPU); - my_delay_loop_2(((uint64_t)(howlong) * (uint64_t) F_CPU) / 4000000ULL); + if(dt<=(uint16_t)(279000000UL/F_CPU)) return; + dt-=(uint16_t) (279000000UL/F_CPU); + my_delay_loop_2(((uint64_t)(dt) * (uint64_t) F_CPU) / 4000000ULL); /* Remaining numbers tweaked for the breakpoint CPU frequencies */ /* Add other frequencies as necessary */ #elif F_CPU>=16000000UL - if(howlong<1) return; - my_delay_loop_2((howlong*(uint16_t)(F_CPU/3250000))); + if(dt<1) return; + my_delay_loop_2((dt*(uint16_t)(F_CPU/3250000))); #elif F_CPU >= 12000000UL - if(howlong<2) return; - howlong-=(uint16_t) (3*12000000/F_CPU); - my_delay_loop_2((howlong*(uint16_t)(F_CPU/3250000))); + if(dt<2) return; + dt-=(uint16_t) (3*12000000/F_CPU); + my_delay_loop_2((dt*(uint16_t)(F_CPU/3250000))); #elif F_CPU >= 8000000UL - if(howlong<4) return; - howlong-=(uint16_t) (3*8000000/F_CPU); - my_delay_loop_2((howlong*(uint16_t)(F_CPU/2000000))/2); + if(dt<4) return; + dt-=(uint16_t) (3*8000000/F_CPU); + my_delay_loop_2((dt*(uint16_t)(F_CPU/2000000))/2); #elif F_CPU >= 4000000UL - if(howlong<5) return; - howlong-=(uint16_t) (4*4000000/F_CPU); - my_delay_loop_2((howlong*(uint16_t)(F_CPU/2000000))/2); + if(dt<5) return; + dt-=(uint16_t) (4*4000000/F_CPU); + my_delay_loop_2((dt*(uint16_t)(F_CPU/2000000))/2); #elif F_CPU >= 2000000UL - if(howlong<11) return; - howlong-=(uint16_t) (10*2000000/F_CPU); - my_delay_loop_2((howlong*(uint16_t)(F_CPU/1000000))/4); + if(dt<11) return; + dt-=(uint16_t) (10*2000000/F_CPU); + my_delay_loop_2((dt*(uint16_t)(F_CPU/1000000))/4); #elif F_CPU >= 1000000UL - if(howlong<=17) return; - howlong-=(uint16_t) (17*1000000/F_CPU); - my_delay_loop_2((howlong*(uint16_t)(F_CPU/1000000))/4); + if(dt<=17) return; + dt-=(uint16_t) (17*1000000/F_CPU); + my_delay_loop_2((dt*(uint16_t)(F_CPU/1000000))/4); #else - howlong >> 5; - if (howlong < 1) return; - my_delay_loop_2(howlong); + dt >> 5; + if (dt < 1) return; + my_delay_loop_2(dt); #endif } #if 0 @@ -250,7 +250,7 @@ clock_delay(unsigned int howlong) /*---------------------------------------------------------------------------*/ /** * Delay up to 65535 milliseconds. - * \param dt How many milliseconds to delay. + * \param howlong How many milliseconds to delay. * * Neither interrupts nor the watchdog timer is disabled over the delay. * Platforms are not required to implement this call. @@ -279,7 +279,7 @@ clock_delay_msec(uint16_t howlong) /*---------------------------------------------------------------------------*/ /** * Adjust the system current clock time. - * \param dt How many ticks to add + * \param howmany How many ticks to add * * Typically used to add ticks after an MCU sleep * clock_seconds will increment if necessary to reflect the tick addition. diff --git a/platform/osd-merkur/dev/dht11.c b/cpu/avr/dev/dht11.c similarity index 99% rename from platform/osd-merkur/dev/dht11.c rename to cpu/avr/dev/dht11.c index 0bea2efbf..39e1a7701 100644 --- a/platform/osd-merkur/dev/dht11.c +++ b/cpu/avr/dev/dht11.c @@ -29,6 +29,7 @@ #define udelay(u) clock_delay_usec(u) #define mdelay(u) clock_delay_msec(u) +// todo: set DHT22 or DHT11 in project file // define for DHT11 else for DHT22, RHT03 // #define DHT11 1 diff --git a/platform/osd-merkur/dev/dht11.h b/cpu/avr/dev/dht11.h similarity index 100% rename from platform/osd-merkur/dev/dht11.h rename to cpu/avr/dev/dht11.h diff --git a/platform/osd-merkur/dev/ds1820.c b/cpu/avr/dev/ds1820.c similarity index 100% rename from platform/osd-merkur/dev/ds1820.c rename to cpu/avr/dev/ds1820.c diff --git a/platform/osd-merkur/dev/ds1820.h b/cpu/avr/dev/ds1820.h similarity index 100% rename from platform/osd-merkur/dev/ds1820.h rename to cpu/avr/dev/ds1820.h diff --git a/platform/osd-merkur/dev/i2c.c b/cpu/avr/dev/i2c.c similarity index 95% rename from platform/osd-merkur/dev/i2c.c rename to cpu/avr/dev/i2c.c index d5fe8d34a..0fa295849 100644 --- a/platform/osd-merkur/dev/i2c.c +++ b/cpu/avr/dev/i2c.c @@ -1,391 +1,391 @@ -/* - * Copyright (c) 2014, Ingo Gulyas Intembsys - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - - /** - * \file - * I2C driver for ATMEGA128rfa1 - * - * \author - * Ingo Gulyas Intembsys - * office@intembsys.at - * www.intembsys.at - */ - - -#include "i2c.h" -#include "contiki-conf.h" -#include -#include -#include -#include - -#if I2C_TD != 0 -#include -#include -#include "system_mgmt.h" -#define PRINTD(FORMAT,args...) {sleep_acquire_lock(); printf_P(PSTR(FORMAT),##args); sleep_release_lock();} -#else -#define PRINTD(...) -#endif - -#if WITH_RTDEBUG == 1 -#include "rtdebug.h" -#define RTDEBUG_PUSH(x) rtdebug_push(x) -#else -#warning "I2C Driver compiling without RTDEBUG!" -#define RTDEBUG_PUSH(x) -#endif - -#ifndef TIMEOUT_TIMER -#warning "I2C Driver compiling without TIMEOUT!" -#endif - - -static int8_t wait_job(); -static int8_t wait_stop(); - -static int8_t i2c_ioctl(const i2c_driver* const me, uint8_t cmd, uint8_t arg); -static int8_t i2c_read(const i2c_driver* const me, uint8_t cmd_flags, uint8_t* buffer, uint8_t len); -static int8_t i2c_write(const i2c_driver* const me, uint8_t cmd_flags, const uint8_t* data, uint8_t len); - - -// static linkage of member functions -i2c_driver i2c_drv = {i2c_ioctl, i2c_read, i2c_write}; -// lock spi if driver opened to prevent further opening access -static volatile bool i2c_lock = false; - - -/////////////////////////////////////////////////////////////// -// global functions -/////////////////////////////////////////////////////////////// - -i2c_driver* i2c_open(void) -{ - if(i2c_lock == true) - { - RTDEBUG_PUSH(RTDEBUG_CODE__I2C_OPEN__DEVICE_BUSY); - return NULL; - } - - i2c_lock = true; - power_twi_enable(); - I2C_INIT(); - - TWBR = I2C_FREQ_STANDARD; - TWSR &= ~((1< 0) && (buffer == NULL)) - { - RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__ERROR_NULLPOINTER); - return I2C_ERROR_DRIVER; - } - - do - { - if(cmd_flags & I2C_CMD_FLAG_START) - { - I2C_START(); - if(wait_job() != I2C_OK) - { - RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__START_TIMEOUT); - status = I2C_ERROR_TIMEOUT; - break; - } - if((I2C_STATUS() != I2C_STATUS_START) && (I2C_STATUS() != I2C_STATUS_START_REP)) - { - RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__START_ERROR); - status = I2C_ERROR_START; - break; - } - PRINTD("I2C-RD-START\n"); - } - - if(len == 0) break; - - for(i=0; i<(len-1); i++) - { - I2C_READ_BYTE_ACK(); - if(wait_job() != I2C_OK) - { - RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__READ_BYTE_ACK_TIMEOUT); - status = I2C_ERROR_TIMEOUT; - break; - } - if(I2C_STATUS() != I2C_STATUS_DATAR_ACK) - { - RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__READ_BYTE_ACK_ERROR); - status = I2C_ERROR_READ; - break; - } - buffer[i] = I2C_RX_REG; - PRINTD("I2C-RD-RACK: 0x%02X\n", buffer[i]); - } - - I2C_READ_BYTE_NACK(); - if(wait_job() != I2C_OK) - { - RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__READ_BYTE_NACK_TIMEOUT); - status = I2C_ERROR_TIMEOUT; - break; - } - if(I2C_STATUS() != I2C_STATUS_DATAR_NACK) - { - RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__READ_BYTE_NACK_ERROR); - status = I2C_ERROR_READ; - break; - } - buffer[i] = I2C_RX_REG; - PRINTD("I2C-RD-RNACK: 0x%02X\n", buffer[i]); - - } while (0); - - if(cmd_flags & I2C_CMD_FLAG_STOP) - { - I2C_STOP(); - if(wait_stop() != I2C_OK) - { - RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__STOP_TIMEOUT); - status = I2C_ERROR_TIMEOUT; - } - PRINTD("I2C-RD_STOP\n"); - } - - return status; -} - -static int8_t i2c_write(const i2c_driver* const me, uint8_t cmd_flags, const uint8_t* data, uint8_t len) -{ - uint8_t i = 0; - int8_t status = I2C_OK; - - - if(me == NULL || i2c_lock == false) - { - RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__DEVICE_CLOSED); - return I2C_ERROR_DRIVER; - } - - if((len > 0) && (data == NULL)) - { - RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__ERROR_NULLPOINTER); - return I2C_ERROR_DRIVER; - } - - do - { - if(cmd_flags & I2C_CMD_FLAG_START) - { - I2C_START(); - if(wait_job() != I2C_OK) - { - RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__START_TIMEOUT); - status = I2C_ERROR_TIMEOUT; - break; - } - if((I2C_STATUS() != I2C_STATUS_START) && (I2C_STATUS() != I2C_STATUS_START_REP)) - { - RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__START_ERROR); - status = I2C_ERROR_START; - break; - } - PRINTD("I2C-WR-START\n"); - } - - - - for(i=0; i +#include +#include +#include + +#if I2C_TD != 0 +#include +#include +#include "system_mgmt.h" +#define PRINTD(FORMAT,args...) {sleep_acquire_lock(); printf_P(PSTR(FORMAT),##args); sleep_release_lock();} +#else +#define PRINTD(...) +#endif + +#if WITH_RTDEBUG == 1 +#include "rtdebug.h" +#define RTDEBUG_PUSH(x) rtdebug_push(x) +#else +#warning "I2C Driver compiling without RTDEBUG!" +#define RTDEBUG_PUSH(x) +#endif + +#ifndef TIMEOUT_TIMER +#warning "I2C Driver compiling without TIMEOUT!" +#endif + + +static int8_t wait_job(); +static int8_t wait_stop(); + +static int8_t i2c_ioctl(const i2c_driver* const me, uint8_t cmd, uint8_t arg); +static int8_t i2c_read(const i2c_driver* const me, uint8_t cmd_flags, uint8_t* buffer, uint8_t len); +static int8_t i2c_write(const i2c_driver* const me, uint8_t cmd_flags, const uint8_t* data, uint8_t len); + + +// static linkage of member functions +i2c_driver i2c_drv = {i2c_ioctl, i2c_read, i2c_write}; +// lock spi if driver opened to prevent further opening access +static volatile bool i2c_lock = false; + + +/////////////////////////////////////////////////////////////// +// global functions +/////////////////////////////////////////////////////////////// + +i2c_driver* i2c_open(void) +{ + if(i2c_lock == true) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_OPEN__DEVICE_BUSY); + return NULL; + } + + i2c_lock = true; + power_twi_enable(); + I2C_INIT(); + + TWBR = I2C_FREQ_STANDARD; + TWSR &= ~((1< 0) && (buffer == NULL)) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__ERROR_NULLPOINTER); + return I2C_ERROR_DRIVER; + } + + do + { + if(cmd_flags & I2C_CMD_FLAG_START) + { + I2C_START(); + if(wait_job() != I2C_OK) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__START_TIMEOUT); + status = I2C_ERROR_TIMEOUT; + break; + } + if((I2C_STATUS() != I2C_STATUS_START) && (I2C_STATUS() != I2C_STATUS_START_REP)) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__START_ERROR); + status = I2C_ERROR_START; + break; + } + PRINTD("I2C-RD-START\n"); + } + + if(len == 0) break; + + for(i=0; i<(len-1); i++) + { + I2C_READ_BYTE_ACK(); + if(wait_job() != I2C_OK) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__READ_BYTE_ACK_TIMEOUT); + status = I2C_ERROR_TIMEOUT; + break; + } + if(I2C_STATUS() != I2C_STATUS_DATAR_ACK) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__READ_BYTE_ACK_ERROR); + status = I2C_ERROR_READ; + break; + } + buffer[i] = I2C_RX_REG; + PRINTD("I2C-RD-RACK: 0x%02X\n", buffer[i]); + } + + I2C_READ_BYTE_NACK(); + if(wait_job() != I2C_OK) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__READ_BYTE_NACK_TIMEOUT); + status = I2C_ERROR_TIMEOUT; + break; + } + if(I2C_STATUS() != I2C_STATUS_DATAR_NACK) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__READ_BYTE_NACK_ERROR); + status = I2C_ERROR_READ; + break; + } + buffer[i] = I2C_RX_REG; + PRINTD("I2C-RD-RNACK: 0x%02X\n", buffer[i]); + + } while (0); + + if(cmd_flags & I2C_CMD_FLAG_STOP) + { + I2C_STOP(); + if(wait_stop() != I2C_OK) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__STOP_TIMEOUT); + status = I2C_ERROR_TIMEOUT; + } + PRINTD("I2C-RD_STOP\n"); + } + + return status; +} + +static int8_t i2c_write(const i2c_driver* const me, uint8_t cmd_flags, const uint8_t* data, uint8_t len) +{ + uint8_t i = 0; + int8_t status = I2C_OK; + + + if(me == NULL || i2c_lock == false) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__DEVICE_CLOSED); + return I2C_ERROR_DRIVER; + } + + if((len > 0) && (data == NULL)) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__ERROR_NULLPOINTER); + return I2C_ERROR_DRIVER; + } + + do + { + if(cmd_flags & I2C_CMD_FLAG_START) + { + I2C_START(); + if(wait_job() != I2C_OK) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__START_TIMEOUT); + status = I2C_ERROR_TIMEOUT; + break; + } + if((I2C_STATUS() != I2C_STATUS_START) && (I2C_STATUS() != I2C_STATUS_START_REP)) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__START_ERROR); + status = I2C_ERROR_START; + break; + } + PRINTD("I2C-WR-START\n"); + } + + + + for(i=0; i - -//////////////////////////////////////////////////////////////////////////////////////////// -// CONFIGURATION SECTION: - -#define I2C_TD 0 // compiler switch: i2c testdriver code - -#define I2C_PORT PORTD -#define I2C_DDR DDRD -#define I2C_SCL_PIN 0 -#define I2C_SDA_PIN 1 - -// END OF CONFIGURATION SECTION -//////////////////////////////////////////////////////////////////////////////////////////// - -#define I2C_INIT() ({I2C_DDR &= ~((1< CHECK F_CPU SETTINGS!" -#endif - - -#define I2C_STATUS_REG TWSR -#define I2C_TX_REG TWDR -#define I2C_RX_REG TWDR - -#define I2C_START() (TWCR = (1< + +//////////////////////////////////////////////////////////////////////////////////////////// +// CONFIGURATION SECTION: + +#define I2C_TD 0 // compiler switch: i2c testdriver code + +#define I2C_PORT PORTD +#define I2C_DDR DDRD +#define I2C_SCL_PIN 0 +#define I2C_SDA_PIN 1 + +// END OF CONFIGURATION SECTION +//////////////////////////////////////////////////////////////////////////////////////////// + +#define I2C_INIT() ({I2C_DDR &= ~((1< CHECK F_CPU SETTINGS!" +#endif + + +#define I2C_STATUS_REG TWSR +#define I2C_TX_REG TWDR +#define I2C_RX_REG TWDR + +#define I2C_START() (TWCR = (1<nb_dl.vp, fbc);*/ + /* if (nb) + NicRead(nb->nb_dl.vp, fbc);*/ } /* Release the packet. */ @@ -1011,6 +1011,7 @@ static NETBUF *NicGetPacket(void) return nb; } +#if 0 /*! * \brief Load a packet into the nic's transmit ring buffer. * @@ -1025,7 +1026,6 @@ static NETBUF *NicGetPacket(void) * will automatically release the network buffer * structure. */ -#if 0 static int NicPutPacket(NETBUF * nb) { uint16_t sz; @@ -1116,13 +1116,12 @@ static int NicPutPacket(NETBUF * nb) return 0; } -#endif +#endif /* 0 */ -/*! \fn NicRxLanc(void *arg) - * \brief NIC receiver thread. - * - */ #if 1 +/*! + * \brief NIC receiver thread. + */ PROCESS_THREAD(lanc111_process, ev, data) /*THREAD(NicRxLanc, arg)*/ { @@ -1188,18 +1187,19 @@ PROCESS_THREAD(lanc111_process, ev, data) */ imsk = nic_inlb(NIC_MSK); nic_outlb(NIC_MSK, 0); - /* while ((nb = NicGetPacket()) != 0) { - if (nb != (NETBUF *) 0xFFFF) { - ni->ni_rx_packets++; - (*ifn->if_recv) (dev, nb); - } - }*/ + /* while ((nb = NicGetPacket()) != 0) { + if (nb != (NETBUF *) 0xFFFF) { + ni->ni_rx_packets++; + (*ifn->if_recv) (dev, nb); + } + }*/ nic_outlb(NIC_MSK, imsk | INT_RCV | INT_ERCV); } PROCESS_END(); } -#endif /* 0 */ +#endif /* 1 */ +#if 0 /*! * \brief Send Ethernet packet. * @@ -1210,7 +1210,6 @@ PROCESS_THREAD(lanc111_process, ev, data) * * \return 0 on success, -1 in case of any errors. */ -#if 0 int LancOutput(NUTDEVICE * dev, NETBUF * nb) { static u_long mx_wait = 5000; @@ -1242,7 +1241,7 @@ int LancOutput(NUTDEVICE * dev, NETBUF * nb) } return rc; } -#endif +#endif /* 0 */ #if 0 /*! * \brief Initialize Ethernet hardware. @@ -1337,7 +1336,7 @@ NUTDEVICE devSmsc111 = { }; /*@}*/ -#endif +#endif /* 0 */ int @@ -1348,7 +1347,7 @@ lanc111_init(void) /* Register interrupt handler and enable interrupts. */ /* if (NutRegisterIrqHandler(&LANC111_SIGNAL, NicInterrupt, dev)) - return -1;*/ + return -1;*/ /* * Start the receiver thread. @@ -1361,3 +1360,6 @@ lanc111_init(void) } /** @} */ +/** @} */ + +/** @} */ diff --git a/platform/osd-merkur/dev/led.c b/cpu/avr/dev/led.c similarity index 100% rename from platform/osd-merkur/dev/led.c rename to cpu/avr/dev/led.c diff --git a/cpu/avr/dev/led.h b/cpu/avr/dev/led.h new file mode 100644 index 000000000..60ce30b01 --- /dev/null +++ b/cpu/avr/dev/led.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012 Harald Pichler + * All rights reserved. + * + * 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 + * 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 OWNER 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. + */ +/** + * \file + * + * \brief + * This file provides Raven LED support. + * + * \author + * Harald Pichler harald@the-develop.net + * + */ + +#ifndef __LED_H__ +#define __LED_H__ + +#include + +/* Some io.h definitions of shift vary among processors */ +#ifndef DDE0 +#define DDE0 DDRE0 +#define DDE1 DDRE1 +#define DDE2 DDRE2 +#define DDE3 DDRE3 +#define DDE4 DDRE4 +#define DDE5 DDRE5 +#define DDE6 DDRE6 +#define DDE7 DDRE7 +#endif + + +/** @name LED Functions */ +/** @{ */ +void led1_on(void); +void led1_off(void); +void led2_on(void); +void led2_off(void); +/** @} */ + +#endif /* __LED_H__ */ diff --git a/platform/osd-merkur/dev/optriac-sensor.c b/cpu/avr/dev/optriac-sensor.c similarity index 100% rename from platform/osd-merkur/dev/optriac-sensor.c rename to cpu/avr/dev/optriac-sensor.c diff --git a/platform/osd-merkur/dev/optriac-sensor.h b/cpu/avr/dev/optriac-sensor.h similarity index 100% rename from platform/osd-merkur/dev/optriac-sensor.h rename to cpu/avr/dev/optriac-sensor.h diff --git a/platform/osd-merkur/dev/pir-sensor.c b/cpu/avr/dev/pir-sensor.c similarity index 100% rename from platform/osd-merkur/dev/pir-sensor.c rename to cpu/avr/dev/pir-sensor.c diff --git a/platform/osd-merkur/dev/pir-sensor.h b/cpu/avr/dev/pir-sensor.h similarity index 100% rename from platform/osd-merkur/dev/pir-sensor.h rename to cpu/avr/dev/pir-sensor.h diff --git a/platform/osd-merkur/dev/relay-sensor.c b/cpu/avr/dev/relay-sensor.c similarity index 100% rename from platform/osd-merkur/dev/relay-sensor.c rename to cpu/avr/dev/relay-sensor.c diff --git a/platform/osd-merkur/dev/relay-sensor.h b/cpu/avr/dev/relay-sensor.h similarity index 100% rename from platform/osd-merkur/dev/relay-sensor.h rename to cpu/avr/dev/relay-sensor.h diff --git a/platform/osd-merkur/dev/relay.c b/cpu/avr/dev/relay.c similarity index 100% rename from platform/osd-merkur/dev/relay.c rename to cpu/avr/dev/relay.c diff --git a/platform/osd-merkur/dev/relay.h b/cpu/avr/dev/relay.h similarity index 100% rename from platform/osd-merkur/dev/relay.h rename to cpu/avr/dev/relay.h diff --git a/cpu/avr/dev/rs232.c b/cpu/avr/dev/rs232.c index 94cf5035f..2df263491 100644 --- a/cpu/avr/dev/rs232.c +++ b/cpu/avr/dev/rs232.c @@ -83,7 +83,7 @@ #define NUMPORTS RS232_CONF_NUMPORTS #endif -#if defined (__AVR_ATmega128__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega128RFA1__) +#if defined (__AVR_ATmega128__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) #ifndef NUMPORTS #define NUMPORTS 2 #elif NUMPORTS > 2 diff --git a/cpu/avr/dev/rs232.h b/cpu/avr/dev/rs232.h index 08a3d4f9f..e55ace99a 100644 --- a/cpu/avr/dev/rs232.h +++ b/cpu/avr/dev/rs232.h @@ -49,6 +49,10 @@ #include "dev/rs232_at90usb1287.h" #elif defined (__AVR_ATmega128RFA1__) #include "dev/rs232_atmega128rfa1.h" +#elif defined (__AVR_ATmega128RFR2__) +#include "dev/rs232_atmega128rfa1.h" +#elif defined (__AVR_ATmega256RFR2__) +#include "dev/rs232_atmega256rfr2.h" #elif defined (__AVR_ATmega644__) || defined (__AVR_ATmega328P__) #include "dev/rs232_atmega644.h" #elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega8515__) \ diff --git a/cpu/avr/dev/rs232_atmega256rfr2.h b/cpu/avr/dev/rs232_atmega256rfr2.h new file mode 100644 index 000000000..abd32f7b7 --- /dev/null +++ b/cpu/avr/dev/rs232_atmega256rfr2.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2006, Technical University of Munich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * @(#)$$ + */ + +/** + * \file + * AVR specific definitions for the rs232 port. + * + * \author + * Simon Barner + +/******************************************************************************/ +/*** RS232 ports */ +/******************************************************************************/ +#define RS232_PORT_0 0 +#define RS232_PORT_1 1 + +/******************************************************************************/ +/*** Baud rates */ +/******************************************************************************/ +#if (F_CPU == 16000000UL) +/* Single speed operation (U2X = 0)*/ +#define USART_BAUD_2400 416 +#define USART_BAUD_4800 207 +#define USART_BAUD_9600 103 +#define USART_BAUD_14400 68 +#define USART_BAUD_19200 51 +#define USART_BAUD_28800 34 +#define USART_BAUD_38400 25 +#define USART_BAUD_57600 16 +#define USART_BAUD_76800 12 +#define USART_BAUD_115200 8 +#define USART_BAUD_230400 3 +#define USART_BAUD_250000 3 +#define USART_BAUD_500000 1 +#define USART_BAUD_1000000 0 +#elif (F_CPU == 8000000UL) +/* Single speed operation (U2X = 0)*/ +#define USART_BAUD_2400 207 +#define USART_BAUD_4800 103 +#define USART_BAUD_9600 51 +#define USART_BAUD_14400 34 +#define USART_BAUD_19200 25 +#define USART_BAUD_28800 16 +#define USART_BAUD_38400 12 +#define USART_BAUD_57600 8 +#define USART_BAUD_76800 6 +#define USART_BAUD_115200 3 +#define USART_BAUD_230400 1 +#define USART_BAUD_250000 1 +#define USART_BAUD_500000 0 +#else +#error "Please define the baud rates for your CPU clock (see ATmega256rfr2 datasheet) \ +or set the rate in contiki-conf.h" +#endif + + +/******************************************************************************/ +/*** Interrupt settings */ +/******************************************************************************/ +#define USART_INTERRUPT_RX_COMPLETE _BV (RXCIE0) +#define USART_INTERRUPT_TX_COMPLETE _BV (TXCIE0) +#define USART_INTERRUPT_DATA_REG_EMPTY _BV (UDRIE0) + +/******************************************************************************/ +/*** Receiver / transmitter */ +/******************************************************************************/ +#define USART_RECEIVER_ENABLE _BV (RXEN0) +#define USART_TRANSMITTER_ENABLE _BV (TXEN0) + +/******************************************************************************/ +/*** Mode select */ +/******************************************************************************/ +#define USART_MODE_ASYNC 0x00 +#define USART_MODE_SYNC _BV (UMSEL00) + +/******************************************************************************/ +/*** Parity */ +/******************************************************************************/ +#define USART_PARITY_NONE 0x00 +#define USART_PARITY_EVEN _BV (UPM01) +#define USART_PARITY_ODD _BV (UPM01) | _BV (UPM00) + +/******************************************************************************/ +/*** Stop bits */ +/******************************************************************************/ +#define USART_STOP_BITS_1 0x00 +#define USART_STOP_BITS_2 _BV (USBS) + +/******************************************************************************/ +/*** Character size */ +/******************************************************************************/ +#define USART_DATA_BITS_5 0x00 +#define USART_DATA_BITS_6 _BV (UCSZ00) +#define USART_DATA_BITS_7 _BV (UCSZ01) +#define USART_DATA_BITS_8 _BV (UCSZ01) | _BV (UCSZ00) +// #define USART_DATA_BITS_9 (needs also UCSZ2 bit in UCSRnB) + +/******************************************************************************/ +/*** Clock polarity */ +/******************************************************************************/ +#define USART_RISING_XCKN_EDGE 0x00 +#define USART_FALLING_XCKN_EDGE _BV (UCPOL0) + +#endif /* #ifndef __RS232_ATMEGA128RFA1__ */ diff --git a/platform/osd-merkur/dev/servo-sensor.c b/cpu/avr/dev/servo-sensor.c similarity index 100% rename from platform/osd-merkur/dev/servo-sensor.c rename to cpu/avr/dev/servo-sensor.c diff --git a/platform/osd-merkur/dev/servo-sensor.h b/cpu/avr/dev/servo-sensor.h similarity index 100% rename from platform/osd-merkur/dev/servo-sensor.h rename to cpu/avr/dev/servo-sensor.h diff --git a/platform/osd-merkur/dev/servo.c b/cpu/avr/dev/servo.c similarity index 60% rename from platform/osd-merkur/dev/servo.c rename to cpu/avr/dev/servo.c index 1e4169b89..874e98b89 100644 --- a/platform/osd-merkur/dev/servo.c +++ b/cpu/avr/dev/servo.c @@ -52,57 +52,54 @@ * servo device */ -#define SERVO_OFFSET 1000 -#define SERVO_MAX 1000 -#define SERVO_INIT 500 - unsigned int servoa=SERVO_INIT; unsigned int servob=SERVO_INIT; void servo_init(void) { -// Port B initialization -// Func7=Out Func6=Out Func5=Out Func4=In Func3=In Func2=In Func1=In Func0=In -// State7=0 State6=0 State5=0 State4=T State3=T State2=T State1=T State0=T -PORTB=0x00; -DDRB=0xE0; -// Timer/Counter 1 initialization -// Clock source: System Clock -// Clock value: 2000.000 kHz -// Mode: Ph. & fr. cor. PWM top=ICR1 -// OC1A output: Connected -// OC1B output: Connected -// OC1C output: Connected -// Noise Canceler: Off -// Input Capture on Falling Edge -// Timer1 Overflow Interrupt: Off -// Input Capture Interrupt: Off -// Compare A Match Interrupt: Off -// Compare B Match Interrupt: Off -// Compare C Match Interrupt: Off -TCCR1A=0xA8; -TCCR1B=0x12; -TCNT1H=0x00; -TCNT1L=0x00; -// ICR1 has a computed value of 20,000 - see the ESawdust.com/blog article for how this -// value was derived. -// 20000 == 0x4e20 so that's what goes into the high and low byte of the ICR1 register -// alternatively, Codevision would let you just do ICR1 = 20000; -ICR1H=0x4E; -ICR1L=0x20; + // Port E initialization + // Set Pin 3 and 4 to output mode for OCR1A and OCR2A + DDRE |= 1<<3 | 1<<4; -/* OCR1AH=0x00; -OCR1AL=0x00; -*/ -// OCR1A will govern the steering servo, OCR1B will govern throttle -OCR1A = 1500; // set it to an initial position somewhere in the middle of the 1 to 2ms range + // Timer/Counter 3 initialization + // Clock source: System Clock + // Clock value: 2000.000 kHz + // Mode: Ph. & fr. cor. PWM top=ICR1 + // OC3A output: Connected + // OC3B output: Connected + // OC3C output: Connected + // Noise Canceler: Off + // Input Capture on Falling Edge + // Timer3 Overflow Interrupt: Off + // Input Capture Interrupt: Off + // Compare A Match Interrupt: Off + // Compare B Match Interrupt: Off + // Compare C Match Interrupt: Off -// OCR1A will govern the steering servo, OCR1B will govern throttle -OCR1B = 1500; // set it to an initial position somewhere in the middle of the 1 to 2ms range -// start with motor off - no duty cycle at all -OCR1CH=0x00; -OCR1CL=0x00; + /* TCCR3A = [COM3A1|COM3A0|COM3B1|COM3B0||FOC3A|FOC3B|WGM31|WGM30] */ + /* 1 0 1 0 1 0 0 0 */ + TCCR3A=0xA8; + /* TCCR3B = [ ICNC3| ICES3| -| WGM33||WGM32| CS32| CS31| CS30] */ + /* 0 0 0 1 0 0 1 0 */ + TCCR3B=0x12; + TCNT3H=0x00; + TCNT3L=0x00; + // ICR3 has a computed value of 20,000 - see the chip manual for how this + // value was derived. + // 20000 == 0x4e20 so that's what goes into the high and low byte of the ICR3 register + // alternatively, Codevision would let you just do ICR3 = 20000; + ICR3H=0x4E; + ICR3L=0x20; + + // OCR3A will govern the steering servo, OCR3B will govern throttle + OCR3A = servoa; // set it to an initial position somewhere in the middle of the 1 to 2ms range + + // OCR3A will govern the steering servo, OCR3B will govern throttle + OCR3B = servob; // set it to an initial position somewhere in the middle of the 1 to 2ms range + // start with motor off - no duty cycle at all + OCR3CH=0x00; + OCR3CL=0x00; } /*---------------------------------------------------------------------------*/ /* @@ -134,14 +131,22 @@ unsigned int servo_set(unsigned i,unsigned int j) { if(j > SERVO_MAX) - j=SERVO_MAX; + j=SERVO_MAX; + if(j < SERVO_MIN) + j=SERVO_MIN; if(i==0) + { servoa=j; - OCR1A = SERVO_OFFSET + servoa; - return 1; + OCR3A = servoa; + return 1; + } if(i==1) + { servob=j; - OCR1A = SERVO_OFFSET + servob; - return 1; + OCR3B = servob; + return 1; + } + + return 0; } diff --git a/platform/osd-merkur/dev/servo.h b/cpu/avr/dev/servo.h similarity index 96% rename from platform/osd-merkur/dev/servo.h rename to cpu/avr/dev/servo.h index c10f8657c..c6ae4ab57 100644 --- a/platform/osd-merkur/dev/servo.h +++ b/cpu/avr/dev/servo.h @@ -31,6 +31,10 @@ #ifndef SERVO_H #define SERVO_H +#define SERVO_MIN 575 +#define SERVO_MAX 2425 +#define SERVO_INIT 1500 + void servo_init(void); void servo_off(void); diff --git a/cpu/avr/dev/sg-ready.c b/cpu/avr/dev/sg-ready.c new file mode 100644 index 000000000..93c1990bc --- /dev/null +++ b/cpu/avr/dev/sg-ready.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2015 Bernhard Trinnes + * All rights reserved. + * + * 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 + * 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 OWNER 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. + */ +/** + * \file + * + * \brief + * Smart Grid Ready Module - guhRF + * + * \author + * Bernhard Trinnes bernhard.trinnes@guh.guru + guh Gmbh + * + */ + +#include "sg-ready.h" +#include + + +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + + + +/** + * \addtogroup relay + * \{ +*/ +/*---------------------------------------------------------------------------*/ +/** + * \brief init RELAY PINS - direction & pull-ups +*/ +void +sg_relay_init(uint8_t state) +{ + /*2 latching dual coal relay + RELAY 1 Coil 1 PB4 - ON + Coil 2 PB5 - OFF + Feedback PD5 + RELAY 2 Coil 1 PB6 - ON + Coil 2 PB7 - OFF + Feedback PD7 + + */ + + PRINTF("SET DDRB\n"); + DDRB |= (RELAY1_ON | RELAY1_OFF | RELAY2_ON | RELAY2_OFF); + PRINTF("SET PORTB\n"); + PORTB &= ~(RELAY1_ON | RELAY1_OFF | RELAY2_ON | RELAY2_OFF); + + PRINTF("SET DDRD\n"); + DDRD &= ~(RELAY1_FB | RELAY2_FB); + PRINTF("SET PORTD\n"); + PORTD |= (RELAY1_FB | RELAY2_FB); + + PRINTF("SET STATE\n"); + sg_set_state(state); // set default state - heat pump normal operation +} + +/** + * \brief +*/ + +void +sg_set_state(uint8_t state) +{ + /* State 1 - Relays 1:0 + State 2 - Relays 0:0 + State 3 - Relays 0:1 + State 4 - Relays 1:1 + uint8_t i = 0; + */ + uint8_t current_state; + + PRINTF("GET STATE\n"); + current_state = sg_get_state(); + + PRINTF("SET DIFFERENCE: %u %u\n", current_state, state); + sg_switch_difference(current_state, state); + + + +/* while ( i<=3 || (current_state != state)){ + i++; + sg_switch_difference(current_state, state); + current_state = sg_get_state(); + } +*/ +} +/** + * \brief +*/ + + +uint8_t +sg_get_state() +{ + uint8_t state; + /* Pull up -> Pin high = Relay Open */ + if ((~PIND & RELAY1_FB) && (~PIND & RELAY2_FB)){ + state = 4; + }else if (~PIND & RELAY1_FB){ + state = 1; + } else if (~PIND & RELAY2_FB){ + state = 3; + } else { + state = 2; + } + return state; +} +/** + * \brief +*/ + +void +sg_switch_difference(uint8_t old_state, uint8_t new_state) +{ + switch(old_state) { + case 1: + switch(new_state) { + case 2: + PORTB |= RELAY1_OFF; + PORTB &= ~(RELAY1_ON | RELAY2_ON | RELAY2_OFF); + _delay_us(LATCH_TIME); + PORTB &= ~(RELAY1_OFF); + break; + case 3: + PORTB |= (RELAY1_OFF | RELAY2_ON ); + PORTB &= ~(RELAY1_ON | RELAY2_OFF); + _delay_us(LATCH_TIME); + PORTB &= ~(RELAY1_OFF | RELAY2_ON); + break; + case 4: + PORTB |= RELAY2_ON; + PORTB &= ~(RELAY1_ON | RELAY1_OFF | RELAY2_OFF); + _delay_us(LATCH_TIME); + PORTB &= ~(RELAY2_ON); + break; + } + break; + case 2: + switch(new_state) { + case 1: + PORTB |= RELAY1_ON; + PORTB &= ~(RELAY1_OFF | RELAY2_ON | RELAY2_OFF); + _delay_us(LATCH_TIME); + PORTB &= ~(RELAY1_ON); + break; + case 3: + PORTB |= (RELAY2_ON); + PORTB &= ~(RELAY1_ON | RELAY1_OFF | RELAY2_OFF); + _delay_us(LATCH_TIME); + PORTB &= ~(RELAY2_ON); + break; + case 4: + PORTB |= (RELAY1_ON | RELAY2_ON); + PORTB &= ~(RELAY1_OFF | RELAY2_OFF); + _delay_us(LATCH_TIME); + PORTB &= ~(RELAY1_ON | RELAY2_ON); + break; + } + + break; + case 3: + switch(new_state) { + case 1: + PORTB |= (RELAY1_ON | RELAY2_OFF); + PORTB &= ~(RELAY1_OFF | RELAY2_ON); + _delay_us(LATCH_TIME); + PORTB &= ~(RELAY1_ON | RELAY2_OFF); + break; + case 2: + PORTB |= RELAY2_OFF; + PORTB &= ~(RELAY1_ON | RELAY1_OFF | RELAY2_ON); + _delay_us(LATCH_TIME); + PORTB &= ~(RELAY2_OFF); + break; + case 4: + PORTB |= RELAY1_ON; + PORTB &= ~(RELAY1_OFF | RELAY2_ON | RELAY2_OFF); + _delay_us(LATCH_TIME); + PORTB &= ~(RELAY1_ON); + break; + } + break; + case 4: + switch(new_state) { + case 1: + PORTB |= RELAY2_OFF; + PORTB &= ~(RELAY1_ON | RELAY1_OFF | RELAY2_ON); + _delay_us(LATCH_TIME); + PORTB &= ~(RELAY2_OFF); + break; + case 2: + PORTB |= (RELAY1_OFF | RELAY2_OFF); + PORTB &= ~(RELAY1_ON | RELAY2_ON ); + _delay_us(LATCH_TIME); + PORTB &= ~(RELAY1_OFF | RELAY2_OFF); + break; + case 3: + PORTB |= RELAY1_OFF; + PORTB &= ~(RELAY1_ON | RELAY2_ON | RELAY2_OFF); + _delay_us(LATCH_TIME); + PORTB &= ~(RELAY1_OFF); + break; + } + break; + } +} + diff --git a/cpu/avr/dev/sg-ready.h b/cpu/avr/dev/sg-ready.h new file mode 100644 index 000000000..644df6109 --- /dev/null +++ b/cpu/avr/dev/sg-ready.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2015 Bernhard Trinnes + * All rights reserved. + * + * 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 + * 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 OWNER 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. + */ +/** + * \file + * + * \brief + * + * + * \author + * Bernhard Trinnes bernhard.trinnes@guh.guru + * + */ + +#ifndef __SGREADY_H__ +#define __SGREADY_H__ + +#include + +/* Some other io settings of io include define DDRxx as DDxx */ +#ifndef DDRB0 +#define DDRB0 DDB0 +#define DDRB1 DDB1 +#define DDRB2 DDB2 +#define DDRB3 DDB3 +#define DDRB4 DDB4 +#define DDRB5 DDB5 +#define DDRB6 DDB6 +#define DDRB7 DDB7 +#endif + +#ifndef DDRD0 +#define DDRD0 DDD0 +#define DDRD1 DDD1 +#define DDRD2 DDD2 +#define DDRD3 DDD3 +#define DDRD4 DDD4 +#define DDRD5 DDD5 +#define DDRD6 DDD6 +#define DDRD7 DDD7 +#endif + +#define LATCH_TIME 3000 // time in micro seconds + +#define RELAY1_ON (1<(b) ? (a) : (b) ) // Take the max between a and b -# define Min(a, b) ( (a)<(b) ? (a) : (b) ) // Take the min between a and b - // Align on the upper value on a boundary // i.e. Upper(0, 4)= 4 // Upper(1, 4)= 4 diff --git a/cpu/avr/dev/usb/config.h b/cpu/avr/dev/usb/config.h index aa6d81ba4..5faa49198 100644 --- a/cpu/avr/dev/usb/config.h +++ b/cpu/avr/dev/usb/config.h @@ -53,7 +53,7 @@ #define CONFIG_H_ /** - @addtogroup usb + @addtogroup usbstick @{ */ diff --git a/cpu/avr/dev/usb/pll_drv.h b/cpu/avr/dev/usb/pll_drv.h index 6a35ca055..e1b63ed64 100644 --- a/cpu/avr/dev/usb/pll_drv.h +++ b/cpu/avr/dev/usb/pll_drv.h @@ -55,7 +55,7 @@ //_____ I N C L U D E S ____________________________________________________ /** - @addtogroup usb + @addtogroup usbstick @{ */ //_____ M A C R O S ________________________________________________________ diff --git a/cpu/avr/dev/usb/rndis/rndis_task.h b/cpu/avr/dev/usb/rndis/rndis_task.h index 28148f1da..b77682790 100644 --- a/cpu/avr/dev/usb/rndis/rndis_task.h +++ b/cpu/avr/dev/usb/rndis/rndis_task.h @@ -56,7 +56,7 @@ //_____ M A C R O S ________________________________________________________ -#define USB_ETH_MTU UIP_BUFSIZE+4 +#define USB_ETH_MTU (UIP_BUFSIZE + 4) /*! Hook Documentation diff --git a/cpu/avr/minileds.c b/cpu/avr/minileds.c index e708e6bbf..650169d17 100644 --- a/cpu/avr/minileds.c +++ b/cpu/avr/minileds.c @@ -1,32 +1,32 @@ /* * Copyright (c) 2006, Swedish Institute of Computer Science - * All rights reserved. + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. * + */ /** * \file * Dummy implementation of minileds module @@ -58,8 +58,4 @@ leds_off(unsigned char leds) void leds_toggle(unsigned char leds) { - /* - * Synonym: void leds_invert(unsigned char leds); - */ - asm(".global leds_invert\nleds_invert:\n"); } diff --git a/cpu/avr/radio/mac/sicslowmac.c b/cpu/avr/radio/mac/sicslowmac.c index 0d21d997e..b836bcd3a 100644 --- a/cpu/avr/radio/mac/sicslowmac.c +++ b/cpu/avr/radio/mac/sicslowmac.c @@ -402,14 +402,18 @@ sicslowmac_dataRequest(void) frame_create_params_t params; frame_result_t result; +#if NETSTACK_CONF_WITH_RIME /* Save the msduHandle in a global variable. */ msduHandle = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID); +#endif /* Build the FCF. */ params.fcf.frameType = DATAFRAME; params.fcf.securityEnabled = false; params.fcf.framePending = false; +#if NETSTACK_CONF_WITH_RIME params.fcf.ackRequired = packetbuf_attr(PACKETBUF_ATTR_RELIABLE); +#endif params.fcf.panIdCompression = false; /* Insert IEEE 802.15.4 (2003) version bit. */ @@ -426,11 +430,7 @@ sicslowmac_dataRequest(void) params.fcf.srcAddrMode = LONGADDRMODE; params.dest_pid = ieee15_4ManagerAddress.get_dst_panid(); - /* - * If the output address is NULL in the Rime buf, then it is broadcast - * on the 802.15.4 network. - */ - if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null) ) { + if(packetbuf_holds_broadcast()) { /* Broadcast requires short address mode. */ params.fcf.destAddrMode = SHORTADDRMODE; params.dest_pid = BROADCASTPANDID; diff --git a/cpu/avr/radio/rf230bb/atmega128rfa1_registermap.h b/cpu/avr/radio/rf230bb/atmega128rfa1_registermap.h index 7eeb068ab..b28ed0ec0 100644 --- a/cpu/avr/radio/rf230bb/atmega128rfa1_registermap.h +++ b/cpu/avr/radio/rf230bb/atmega128rfa1_registermap.h @@ -71,6 +71,7 @@ #define RG_PHY_ED_LEVEL PHY_ED_LEVEL #define RG_RX_SYN RX_SYN #define SR_RSSI 0x146, 0x1f, 0 +#define SR_RX_CRC_VALID 0x146, 0x80, 7 #define SR_PLL_CF_START 0x15a, 0x80, 7 #define SR_PLL_DCU_START 0x15b, 0x80, 7 #define SR_MAX_CSMA_RETRIES 0x16c, 0x0e, 1 diff --git a/cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h b/cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h new file mode 100644 index 000000000..1baf1a3ac --- /dev/null +++ b/cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h @@ -0,0 +1,399 @@ +/** + * @file + * @brief This file contains RF230-formatted register definitions for the atmega128rfa1 + */ +/* Copyright (c) 2008, Swedish Institute of Computer Science + + All rights reserved. + + 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 + 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 OWNER 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. +*/ + +#ifndef PHY256RFR2_REGISTERMAP_EXTERNAL_H +#define PHY256RFR2_REGISTERMAP_EXTERNAL_H + +/* RF230 register access is through SPI which transfers 8 bits address/8 bits data. + * ATmega128rfa1 registers are defined in I/O space, e.g. in gcc /include/avr/iom128rfa1.h + * A typical definition is #define TRX_STATUS _SFR_MEM8(0x141) + * Registers can be read with a macro, but the args for subregisters don't expand properly so the actual address + * is used with explicit _SFR_MEM8 in the subregister read/write routines. + */ +#define RG_TRX_STATUS TRX_STATUS +#define SR_TRX_STATUS 0x141, 0x1f, 0 +#define SR_TRX_CMD 0x142, 0x1f, 0 +#define STATE_TRANSITION (31) +#define SR_TX_PWR 0x145, 0x0f, 0 +#define RG_VERSION_NUM VERSION_NUM +#define RG_MAN_ID_0 MAN_ID_0 +#define RG_IRQ_MASK IRQ_MASK +#define SR_MAX_FRAME_RETRIES 0x16C, 0xf0, 4 +#define SR_TX_AUTO_CRC_ON 0x144, 0x20, 5 +#define SR_TRAC_STATUS 0x142, 0xe0, 5 +#define SR_CHANNEL 0x148, 0x1f, 0 +#define SR_CCA_MODE 0x148, 0x60, 5 +#define SR_CCA_REQUEST 0x148, 0x80, 7 +#define RG_PAN_ID_0 PAN_ID_0 +#define RG_PAN_ID_1 PAN_ID_1 +#define RG_SHORT_ADDR_0 SHORT_ADDR_0 +#define RG_SHORT_ADDR_1 SHORT_ADDR_1 +#define RG_IEEE_ADDR_0 IEEE_ADDR_0 +#define RG_IEEE_ADDR_1 IEEE_ADDR_1 +#define RG_IEEE_ADDR_2 IEEE_ADDR_2 +#define RG_IEEE_ADDR_3 IEEE_ADDR_3 +#define RG_IEEE_ADDR_4 IEEE_ADDR_4 +#define RG_IEEE_ADDR_5 IEEE_ADDR_5 +#define RG_IEEE_ADDR_6 IEEE_ADDR_6 +#define RG_IEEE_ADDR_7 IEEE_ADDR_7 +//#define SR_ED_LEVEL 0x147, 0xff, 0 +#define RG_PHY_ED_LEVEL PHY_ED_LEVEL +#define RG_RX_SYN RX_SYN +#define SR_RSSI 0x146, 0x1f, 0 +#define SR_RX_CRC_VALID 0x146, 0x80, 7 +#define SR_RX_SYN 0x155, 0xff, 0 +#define SR_TRX_RPC 0x156, 0xff, 0 +#define SR_XAH_CTRL_1 0x157, 0xf5, 2 +#define SR_PLL_CF_START 0x15a, 0x80, 7 +#define SR_PLL_DCU_START 0x15b, 0x80, 7 +#define SR_MAX_CSMA_RETRIES 0x16c, 0x0e, 1 +#define RG_CSMA_BE CSMA_BE +#define RG_CSMA_SEED_0 CSMA_SEED_0 +#define RG_PHY_RSSI PHY_RSSI +//#define SR_CCA_CS_THRES 0x149, 0xf0, 4 +#define SR_CCA_ED_THRES 0x149, 0x0f, 0 +#define SR_CCA_DONE 0x141, 0x80, 7 +#define SR_CCA_STATUS 0x141, 0x40, 6 +#define SR_AACK_SET_PD 0x16e, 0x20, 5 +#define SR_CSMA_SEED_1 0x16e, 0x10, 4 + +/* RF230 register assignments, for reference */ +#if 1 +//#define HAVE_REGISTER_MAP (1) +/** Offset for register TRX_STATUS */ +//#define RG_TRX_STATUS (0x01) +/** Access parameters for sub-register CCA_DONE in register @ref RG_TRX_STATUS */ +//#define SR_CCA_DONE 0x01, 0x80, 7 +/** Access parameters for sub-register CCA_STATUS in register @ref RG_TRX_STATUS */ +//#define SR_CCA_STATUS 0x01, 0x40, 6 +//#define SR_reserved_01_3 0x01, 0x20, 5 +/** Access parameters for sub-register TRX_STATUS in register @ref RG_TRX_STATUS */ +//#define SR_TRX_STATUS 0x01, 0x1f, 0 +/** Constant P_ON for sub-register @ref SR_TRX_STATUS */ +//#define P_ON (0) +/** Constant BUSY_RX for sub-register @ref SR_TRX_STATUS */ +#define BUSY_RX (1) +/** Constant BUSY_TX for sub-register @ref SR_TRX_STATUS */ +#define BUSY_TX (2) +/** Constant RX_ON for sub-register @ref SR_TRX_STATUS */ +#define RX_ON (6) +/** Constant TRX_OFF for sub-register @ref SR_TRX_STATUS */ +#define TRX_OFF (8) +/** Constant PLL_ON for sub-register @ref SR_TRX_STATUS */ +#define PLL_ON (9) +/** Constant SLEEP for sub-register @ref SR_TRX_STATUS */ +//#define SLEEP (15) +/** Constant BUSY_RX_AACK for sub-register @ref SR_TRX_STATUS */ +#define BUSY_RX_AACK (17) +/** Constant BUSY_TX_ARET for sub-register @ref SR_TRX_STATUS */ +#define BUSY_TX_ARET (18) +/** Constant RX_AACK_ON for sub-register @ref SR_TRX_STATUS */ +#define RX_AACK_ON (22) +/** Constant TX_ARET_ON for sub-register @ref SR_TRX_STATUS */ +#define TX_ARET_ON (25) +/** Constant RX_ON_NOCLK for sub-register @ref SR_TRX_STATUS */ +//#define RX_ON_NOCLK (28) +/** Constant RX_AACK_ON_NOCLK for sub-register @ref SR_TRX_STATUS */ +//#define RX_AACK_ON_NOCLK (29) +/** Constant BUSY_RX_AACK_NOCLK for sub-register @ref SR_TRX_STATUS */ +//#define BUSY_RX_AACK_NOCLK (30) +/** Constant STATE_TRANSITION for sub-register @ref SR_TRX_STATUS */ +//#define STATE_TRANSITION (31) + +/** Offset for register TRX_STATE */ +//#define RG_TRX_STATE (0x02) +/** Access parameters for sub-register TRAC_STATUS in register @ref RG_TRX_STATE */ +//#define SR_TRAC_STATUS 0x02, 0xe0, 5 +/** Access parameters for sub-register TRX_CMD in register @ref RG_TRX_STATE */ +//#define SR_TRX_CMD 0x02, 0x1f, 0 +/** Constant CMD_NOP for sub-register @ref SR_TRX_CMD */ +//#define CMD_NOP (0) +/** Constant CMD_TX_START for sub-register @ref SR_TRX_CMD */ +//#define CMD_TX_START (2) +/** Constant CMD_FORCE_TRX_OFF for sub-register @ref SR_TRX_CMD */ +#define CMD_FORCE_TRX_OFF (3) +///** Constant CMD_RX_ON for sub-register @ref SR_TRX_CMD */ +//#define CMD_RX_ON (6) +///** Constant CMD_TRX_OFF for sub-register @ref SR_TRX_CMD */ +//#define CMD_TRX_OFF (8) +///** Constant CMD_PLL_ON for sub-register @ref SR_TRX_CMD */ +//#define CMD_PLL_ON (9) +///** Constant CMD_RX_AACK_ON for sub-register @ref SR_TRX_CMD */ +//#define CMD_RX_AACK_ON (22) +///** Constant CMD_TX_ARET_ON for sub-register @ref SR_TRX_CMD */ +//#define CMD_TX_ARET_ON (25) +///** Offset for register TRX_CTRL_0 */ +//#define RG_TRX_CTRL_0 (0x03) +///** Offset for register TRX_CTRL_1 */ +//#define RG_TRX_CTRL_1 (0x04) +///** Access parameters for sub-register PAD_IO in register @ref RG_TRX_CTRL_0 */ +//#define SR_PAD_IO 0x03, 0xc0, 6 +///** Access parameters for sub-register PAD_IO_CLKM in register @ref RG_TRX_CTRL_0 */ +//#define SR_PAD_IO_CLKM 0x03, 0x30, 4 +///** Constant CLKM_2mA for sub-register @ref SR_PAD_IO_CLKM */ +//#define CLKM_2mA (0) +///** Constant CLKM_4mA for sub-register @ref SR_PAD_IO_CLKM */ +//#define CLKM_4mA (1) +///** Constant CLKM_6mA for sub-register @ref SR_PAD_IO_CLKM */ +//#define CLKM_6mA (2) +///** Constant CLKM_8mA for sub-register @ref SR_PAD_IO_CLKM */ +//#define CLKM_8mA (3) +///** Access parameters for sub-register CLKM_SHA_SEL in register @ref RG_TRX_CTRL_0 */ +//#define SR_CLKM_SHA_SEL 0x03, 0x08, 3 +///** Access parameters for sub-register CLKM_CTRL in register @ref RG_TRX_CTRL_0 */ +//#define SR_CLKM_CTRL 0x03, 0x07, 0 +///** Constant CLKM_no_clock for sub-register @ref SR_CLKM_CTRL */ +//#define CLKM_no_clock (0) +///** Constant CLKM_1MHz for sub-register @ref SR_CLKM_CTRL */ +//#define CLKM_1MHz (1) +///** Constant CLKM_2MHz for sub-register @ref SR_CLKM_CTRL */ +//#define CLKM_2MHz (2) +///** Constant CLKM_4MHz for sub-register @ref SR_CLKM_CTRL */ +//#define CLKM_4MHz (3) +///** Constant CLKM_8MHz for sub-register @ref SR_CLKM_CTRL */ +//#define CLKM_8MHz (4) +///** Constant CLKM_16MHz for sub-register @ref SR_CLKM_CTRL */ +//#define CLKM_16MHz (5) +///** Offset for register PHY_TX_PWR */ +//#define RG_PHY_TX_PWR (0x05) +///** Access parameters for sub-register TX_AUTO_CRC_ON in register @ref RG_PHY_TX_PWR */ +//#define SR_TX_AUTO_CRC_ON 0x05, 0x80, 7 +//#define SR_reserved_05_2 0x05, 0x70, 4 +///** Access parameters for sub-register TX_PWR in register @ref RG_PHY_TX_PWR */ +//#define SR_TX_PWR 0x05, 0x0f, 0 +///** Offset for register PHY_RSSI */ +//#define RG_PHY_RSSI (0x06) +//#define SR_reserved_06_1 0x06, 0xe0, 5 +///** Access parameters for sub-register RSSI in register @ref RG_PHY_RSSI */ +//#define SR_RSSI 0x06, 0x1f, 0 +///** Offset for register PHY_ED_LEVEL */ +//#define RG_PHY_ED_LEVEL (0x07) +///** Access parameters for sub-register ED_LEVEL in register @ref RG_PHY_ED_LEVEL */ +//#define SR_ED_LEVEL 0x07, 0xff, 0 +///** Offset for register PHY_CC_CCA */ +//#define RG_PHY_CC_CCA (0x08) +///** Access parameters for sub-register CCA_REQUEST in register @ref RG_PHY_CC_CCA */ +//#define SR_CCA_REQUEST 0x08, 0x80, 7 +///** Access parameters for sub-register CCA_MODE in register @ref RG_PHY_CC_CCA */ +//#define SR_CCA_MODE 0x08, 0x60, 5 +///** Access parameters for sub-register CHANNEL in register @ref RG_PHY_CC_CCA */ +//#define SR_CHANNEL 0x08, 0x1f, 0 +///** Offset for register CCA_THRES */ +//#define RG_CCA_THRES (0x09) +///** Access parameters for sub-register CCA_CS_THRES in register @ref RG_CCA_THRES */ +//#define SR_CCA_CS_THRES 0x09, 0xf0, 4 +///** Access parameters for sub-register CCA_ED_THRES in register @ref RG_CCA_THRES */ +//#define SR_CCA_ED_THRES 0x09, 0x0f, 0 +///** Offset for register IRQ_MASK */ +//#define RG_IRQ_MASK (0x0e) +///** Access parameters for sub-register IRQ_MASK in register @ref RG_IRQ_MASK */ +//#define SR_IRQ_MASK 0x0e, 0xff, 0 +///** Offset for register IRQ_STATUS */ +//#define RG_IRQ_STATUS (0x0f) +///** Access parameters for sub-register IRQ_7_BAT_LOW in register @ref RG_IRQ_STATUS */ +//#define SR_IRQ_7_BAT_LOW 0x0f, 0x80, 7 +///** Access parameters for sub-register IRQ_6_TRX_UR in register @ref RG_IRQ_STATUS */ +//#define SR_IRQ_6_TRX_UR 0x0f, 0x40, 6 +///** Access parameters for sub-register IRQ_5 in register @ref RG_IRQ_STATUS */ +//#define SR_IRQ_5 0x0f, 0x20, 5 +///** Access parameters for sub-register IRQ_4 in register @ref RG_IRQ_STATUS */ +//#define SR_IRQ_4 0x0f, 0x10, 4 +///** Access parameters for sub-register IRQ_3_TRX_END in register @ref RG_IRQ_STATUS */ +//#define SR_IRQ_3_TRX_END 0x0f, 0x08, 3 +///** Access parameters for sub-register IRQ_2_RX_START in register @ref RG_IRQ_STATUS */ +//#define SR_IRQ_2_RX_START 0x0f, 0x04, 2 +///** Access parameters for sub-register IRQ_1_PLL_UNLOCK in register @ref RG_IRQ_STATUS */ +//#define SR_IRQ_1_PLL_UNLOCK 0x0f, 0x02, 1 +///** Access parameters for sub-register IRQ_0_PLL_LOCK in register @ref RG_IRQ_STATUS */ +//#define SR_IRQ_0_PLL_LOCK 0x0f, 0x01, 0 +///** Offset for register VREG_CTRL */ +//#define RG_VREG_CTRL (0x10) +///** Access parameters for sub-register AVREG_EXT in register @ref RG_VREG_CTRL */ +//#define SR_AVREG_EXT 0x10, 0x80, 7 +///** Access parameters for sub-register AVDD_OK in register @ref RG_VREG_CTRL */ +//#define SR_AVDD_OK 0x10, 0x40, 6 +///** Access parameters for sub-register AVREG_TRIM in register @ref RG_VREG_CTRL */ +//#define SR_AVREG_TRIM 0x10, 0x30, 4 +///** Constant AVREG_1_80V for sub-register @ref SR_AVREG_TRIM */ +//#define AVREG_1_80V (0) +///** Constant AVREG_1_75V for sub-register @ref SR_AVREG_TRIM */ +//#define AVREG_1_75V (1) +///** Constant AVREG_1_84V for sub-register @ref SR_AVREG_TRIM */ +//#define AVREG_1_84V (2) +///** Constant AVREG_1_88V for sub-register @ref SR_AVREG_TRIM */ +//#define AVREG_1_88V (3) +///** Access parameters for sub-register DVREG_EXT in register @ref RG_VREG_CTRL */ +//#define SR_DVREG_EXT 0x10, 0x08, 3 +///** Access parameters for sub-register DVDD_OK in register @ref RG_VREG_CTRL */ +//#define SR_DVDD_OK 0x10, 0x04, 2 +///** Access parameters for sub-register DVREG_TRIM in register @ref RG_VREG_CTRL */ +//#define SR_DVREG_TRIM 0x10, 0x03, 0 +///** Constant DVREG_1_80V for sub-register @ref SR_DVREG_TRIM */ +//#define DVREG_1_80V (0) +///** Constant DVREG_1_75V for sub-register @ref SR_DVREG_TRIM */ +//#define DVREG_1_75V (1) +///** Constant DVREG_1_84V for sub-register @ref SR_DVREG_TRIM */ +//#define DVREG_1_84V (2) +///** Constant DVREG_1_88V for sub-register @ref SR_DVREG_TRIM */ +//#define DVREG_1_88V (3) +///** Offset for register BATMON */ +//#define RG_BATMON (0x11) +//#define SR_reserved_11_1 0x11, 0xc0, 6 +///** Access parameters for sub-register BATMON_OK in register @ref RG_BATMON */ +//#define SR_BATMON_OK 0x11, 0x20, 5 +///** Access parameters for sub-register BATMON_HR in register @ref RG_BATMON */ +//#define SR_BATMON_HR 0x11, 0x10, 4 +///** Access parameters for sub-register BATMON_VTH in register @ref RG_BATMON */ +//#define SR_BATMON_VTH 0x11, 0x0f, 0 +///** Offset for register XOSC_CTRL */ +//#define RG_XOSC_CTRL (0x12) +///** Offset for register RX_SYN */ +//#define RG_RX_SYN 0x15 +///** Offset for register XAH_CTRL_1 */ +//#define RG_XAH_CTRL_1 0x17 +///** Access parameters for sub-register XTAL_MODE in register @ref RG_XOSC_CTRL */ +//#define SR_XTAL_MODE 0x12, 0xf0, 4 +///** Access parameters for sub-register XTAL_TRIM in register @ref RG_XOSC_CTRL */ +//#define SR_XTAL_TRIM 0x12, 0x0f, 0 +///** Offset for register FTN_CTRL */ +//#define RG_FTN_CTRL (0x18) +///** Access parameters for sub-register FTN_START in register @ref RG_FTN_CTRL */ +//#define SR_FTN_START 0x18, 0x80, 7 +//#define SR_reserved_18_2 0x18, 0x40, 6 +///** Access parameters for sub-register FTNV in register @ref RG_FTN_CTRL */ +//#define SR_FTNV 0x18, 0x3f, 0 +///** Offset for register PLL_CF */ +//#define RG_PLL_CF (0x1a) +///** Access parameters for sub-register PLL_CF_START in register @ref RG_PLL_CF */ +//#define SR_PLL_CF_START 0x1a, 0x80, 7 +//#define SR_reserved_1a_2 0x1a, 0x70, 4 +///** Access parameters for sub-register PLL_CF in register @ref RG_PLL_CF */ +//#define SR_PLL_CF 0x1a, 0x0f, 0 +///** Offset for register PLL_DCU */ +//#define RG_PLL_DCU (0x1b) +///** Access parameters for sub-register PLL_DCU_START in register @ref RG_PLL_DCU */ +//#define SR_PLL_DCU_START 0x1b, 0x80, 7 +//#define SR_reserved_1b_2 0x1b, 0x40, 6 +///** Access parameters for sub-register PLL_DCUW in register @ref RG_PLL_DCU */ +//#define SR_PLL_DCUW 0x1b, 0x3f, 0 +///** Offset for register PART_NUM */ +//#define RG_PART_NUM (0x1c) +///** Access parameters for sub-register PART_NUM in register @ref RG_PART_NUM */ +//#define SR_PART_NUM 0x1c, 0xff, 0 +///** Constant RF230 for sub-register @ref SR_PART_NUM */ +//#define RF230 (2) +///** Offset for register VERSION_NUM */ +//#define RG_VERSION_NUM (0x1d) +///** Access parameters for sub-register VERSION_NUM in register @ref RG_VERSION_NUM */ +//#define SR_VERSION_NUM 0x1d, 0xff, 0 +///** Offset for register MAN_ID_0 */ +//#define RG_MAN_ID_0 (0x1e) +///** Access parameters for sub-register MAN_ID_0 in register @ref RG_MAN_ID_0 */ +//#define SR_MAN_ID_0 0x1e, 0xff, 0 +///** Offset for register MAN_ID_1 */ +//#define RG_MAN_ID_1 (0x1f) +///** Access parameters for sub-register MAN_ID_1 in register @ref RG_MAN_ID_1 */ +//#define SR_MAN_ID_1 0x1f, 0xff, 0 +///** Offset for register SHORT_ADDR_0 */ +//#define RG_SHORT_ADDR_0 (0x20) +///** Access parameters for sub-register SHORT_ADDR_0 in register @ref RG_SHORT_ADDR_0 */ +//#define SR_SHORT_ADDR_0 0x20, 0xff, 0 +///** Offset for register SHORT_ADDR_1 */ +//#define RG_SHORT_ADDR_1 (0x21) +///** Access parameters for sub-register SHORT_ADDR_1 in register @ref RG_SHORT_ADDR_1 */ +//#define SR_SHORT_ADDR_1 0x21, 0xff, 0 +///** Offset for register PAN_ID_0 */ +//#define RG_PAN_ID_0 (0x22) +///** Access parameters for sub-register PAN_ID_0 in register @ref RG_PAN_ID_0 */ +//#define SR_PAN_ID_0 0x22, 0xff, 0 +///** Offset for register PAN_ID_1 */ +//#define RG_PAN_ID_1 (0x23) +///** Access parameters for sub-register PAN_ID_1 in register @ref RG_PAN_ID_1 */ +//#define SR_PAN_ID_1 0x23, 0xff, 0 +///** Offset for register IEEE_ADDR_0 */ +//#define RG_IEEE_ADDR_0 (0x24) +///** Access parameters for sub-register IEEE_ADDR_0 in register @ref RG_IEEE_ADDR_0 */ +//#define SR_IEEE_ADDR_0 0x24, 0xff, 0 +///** Offset for register IEEE_ADDR_1 */ +//#define RG_IEEE_ADDR_1 (0x25) +///** Access parameters for sub-register IEEE_ADDR_1 in register @ref RG_IEEE_ADDR_1 */ +//#define SR_IEEE_ADDR_1 0x25, 0xff, 0 +///** Offset for register IEEE_ADDR_2 */ +//#define RG_IEEE_ADDR_2 (0x26) +///** Access parameters for sub-register IEEE_ADDR_2 in register @ref RG_IEEE_ADDR_2 */ +//#define SR_IEEE_ADDR_2 0x26, 0xff, 0 +///** Offset for register IEEE_ADDR_3 */ +//#define RG_IEEE_ADDR_3 (0x27) +///** Access parameters for sub-register IEEE_ADDR_3 in register @ref RG_IEEE_ADDR_3 */ +//#define SR_IEEE_ADDR_3 0x27, 0xff, 0 +///** Offset for register IEEE_ADDR_4 */ +//#define RG_IEEE_ADDR_4 (0x28) +///** Access parameters for sub-register IEEE_ADDR_4 in register @ref RG_IEEE_ADDR_4 */ +//#define SR_IEEE_ADDR_4 0x28, 0xff, 0 +///** Offset for register IEEE_ADDR_5 */ +//#define RG_IEEE_ADDR_5 (0x29) +///** Access parameters for sub-register IEEE_ADDR_5 in register @ref RG_IEEE_ADDR_5 */ +//#define SR_IEEE_ADDR_5 0x29, 0xff, 0 +///** Offset for register IEEE_ADDR_6 */ +//#define RG_IEEE_ADDR_6 (0x2a) +///** Access parameters for sub-register IEEE_ADDR_6 in register @ref RG_IEEE_ADDR_6 */ +//#define SR_IEEE_ADDR_6 0x2a, 0xff, 0 +///** Offset for register IEEE_ADDR_7 */ +//#define RG_IEEE_ADDR_7 (0x2b) +///** Access parameters for sub-register IEEE_ADDR_7 in register @ref RG_IEEE_ADDR_7 */ +//#define SR_IEEE_ADDR_7 0x2b, 0xff, 0 +///** Offset for register XAH_CTRL */ +//#define RG_XAH_CTRL_0 (0x2c) +///** Access parameters for sub-register MAX_FRAME_RETRIES in register @ref RG_XAH_CTRL_0 */ +//#define SR_MAX_FRAME_RETRIES 0x2c, 0xf0, 4 +///** Access parameters for sub-register MAX_CSMA_RETRIES in register @ref RG_XAH_CTRL_0 */ +//#define SR_MAX_CSMA_RETRIES 0x2c, 0x0e, 1 +//#define SR_reserved_2c_3 0x2c, 0x01, 0 +///** Offset for register CSMA_SEED_0 */ +//#define RG_CSMA_SEED_0 (0x2d) +///** Access parameters for sub-register CSMA_SEED_0 in register @ref RG_CSMA_SEED_0 */ +//#define SR_CSMA_SEED_0 0x2d, 0xff, 0 +///** Offset for register CSMA_SEED_1 */ +//#define RG_CSMA_SEED_1 (0x2e) +///** Offset for register CSMA_BE */ +//#define RG_CSMA_BE 0x2f +///** Access parameters for sub-register MIN_BE in register @ref RG_CSMA_SEED_1 */ +//#define SR_MIN_BE 0x2e, 0xc0, 6 +//#define SR_reserved_2e_2 0x2e, 0x30, 4 +///** Access parameters for sub-register I_AM_COORD in register @ref RG_CSMA_SEED_1 */ +//#define SR_I_AM_COORD 0x2e, 0x08, 3 +///** Access parameters for sub-register CSMA_SEED_1 in register @ref RG_CSMA_SEED_1 */ +//#define SR_CSMA_SEED_1 0x2e, 0x07, 0 +#endif +#endif /* PHY256RFR2y_REGISTERMAP_EXTERNAL_H */ diff --git a/cpu/avr/radio/rf230bb/hal.h b/cpu/avr/radio/rf230bb/hal.h index 737680d68..00685626a 100644 --- a/cpu/avr/radio/rf230bb/hal.h +++ b/cpu/avr/radio/rf230bb/hal.h @@ -78,6 +78,7 @@ #define ZIGBIT 4 #define IRIS 5 #define ATMEGA128RFA1 6 +#define ATMEGA256RFR2 7 #if PLATFORM_TYPE == RCB_B /* 1281 rcb */ @@ -140,7 +141,12 @@ # define SLPTRPORT B # define SLPTRPIN (0x04) -#elif PLATFORM_TYPE == ATMEGA128RFA1 +#elif PLATFORM_TYPE == ATMEGA128RFA1 || PLATFORM_TYPE == ATMEGA256RFR2 +/* ATmega1281 with internal AT86RF231 radio */ +# define SLPTRPORT TRXPR +# define SLPTRPIN 1 + +#elif PLATFORM_TYPE == ATMEGA256RFR2 /* ATmega1281 with internal AT86RF231 radio */ # define SLPTRPORT TRXPR # define SLPTRPIN 1 @@ -233,7 +239,7 @@ * that the source code can directly use. * \{ */ -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) #define hal_set_rst_low( ) ( TRXPR &= ~( 1 << TRXRST ) ) /**< This macro pulls the RST pin low. */ #define hal_set_rst_high( ) ( TRXPR |= ( 1 << TRXRST ) ) /**< This macro pulls the RST pin high. */ @@ -274,7 +280,7 @@ #define HAL_DD_SCK SCKPIN /**< Data Direction bit for SCK. */ #define HAL_DD_MOSI MOSIPIN /**< Data Direction bit for MOSI. */ #define HAL_DD_MISO MISOPIN /**< Data Direction bit for MISO. */ -#endif /* defined(__AVR_ATmega128RFA1__) */ +#endif /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega256RFR2__) */ /** \} */ @@ -367,7 +373,7 @@ typedef struct{ void hal_init( void ); /* Hack for atmega128rfa1 with integrated radio. Access registers directly, not through SPI */ -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) //#define hal_register_read(address) _SFR_MEM8((uint16_t)address) #define hal_register_read(address) address uint8_t hal_subregister_read( uint16_t address, uint8_t mask, uint8_t position ); diff --git a/cpu/avr/radio/rf230bb/halbb.c b/cpu/avr/radio/rf230bb/halbb.c index 6aa991eb6..862eb9c8d 100644 --- a/cpu/avr/radio/rf230bb/halbb.c +++ b/cpu/avr/radio/rf230bb/halbb.c @@ -74,8 +74,9 @@ extern uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE]; #include "hal.h" #if defined(__AVR_ATmega128RFA1__) -#include #include "atmega128rfa1_registermap.h" +#elif defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) +#include "atmega256rfr2_registermap.h" #else #include "at86rf230_registermap.h" #endif @@ -88,7 +89,7 @@ volatile extern signed char rf230_last_rssi; /*============================ IMPLEMENTATION ================================*/ -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) /* AVR1281 with internal RF231 radio */ #include @@ -158,8 +159,7 @@ inline uint8_t spiWrite(uint8_t byte) /** \brief This function initializes the Hardware Abstraction Layer. */ -#if defined(__AVR_ATmega128RFA1__) - +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) void hal_init(void) { @@ -241,8 +241,7 @@ hal_init(void) } #endif /* !__AVR__ */ - -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) /* Hack for internal radio registers. hal_register_read and hal_register_write are handled through defines, but the preprocesser can't parse a macro containing another #define with multiple arguments, e.g. using @@ -279,7 +278,7 @@ hal_subregister_write(uint16_t address, uint8_t mask, uint8_t position, HAL_LEAVE_CRITICAL_REGION(); } -#else /* defined(__AVR_ATmega128RFA1__) */ +#else /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) */ /*----------------------------------------------------------------------------*/ /** \brief This function reads data from one of the radio transceiver's registers. * @@ -383,7 +382,7 @@ hal_subregister_write(uint8_t address, uint8_t mask, uint8_t position, /* Write the modified register value. */ hal_register_write(address, value); } -#endif /* defined(__AVR_ATmega128RFA1__) */ +#endif /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) */ /*----------------------------------------------------------------------------*/ /** \brief Transfer a frame from the radio transceiver to a RAM buffer * @@ -399,7 +398,7 @@ hal_subregister_write(uint8_t address, uint8_t mask, uint8_t position, void hal_frame_read(hal_rx_frame_t *rx_frame) { -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) uint8_t frame_length,*rx_data,*rx_buffer; @@ -431,8 +430,8 @@ hal_frame_read(hal_rx_frame_t *rx_frame) * Else show the crc has passed the hardware check. */ rx_frame->crc = true; - -#else /* defined(__AVR_ATmega128RFA1__) */ + +#else /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega256RFR2__) */ uint8_t frame_length, *rx_data; @@ -487,7 +486,8 @@ hal_frame_read(hal_rx_frame_t *rx_frame) HAL_SPI_TRANSFER_CLOSE(); -#endif /* defined(__AVR_ATmega128RFA1__) */ + +#endif /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) */ } /*----------------------------------------------------------------------------*/ @@ -500,7 +500,7 @@ hal_frame_read(hal_rx_frame_t *rx_frame) void hal_frame_write(uint8_t *write_buffer, uint8_t length) { -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) uint8_t *tx_buffer; tx_buffer=(uint8_t *)0x180; //start of fifo in i/o space /* Write frame length, including the two byte checksum */ @@ -518,7 +518,7 @@ hal_frame_write(uint8_t *write_buffer, uint8_t length) #endif do _SFR_MEM8(tx_buffer++)= *write_buffer++; while (--length); -#else /* defined(__AVR_ATmega128RFA1__) */ +#else /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) */ /* Optionally truncate length to maximum frame length. * Not doing this is a fast way to know when the application needs fixing! */ @@ -540,10 +540,11 @@ hal_frame_write(uint8_t *write_buffer, uint8_t length) do HAL_SPI_TRANSFER(*write_buffer++); while (--length); HAL_SPI_TRANSFER_CLOSE(); -#endif /* defined(__AVR_ATmega128RFA1__) */ +#endif /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) */ } /*----------------------------------------------------------------------------*/ +#if 0 //Uses 80 bytes (on Raven) omit unless needed /** \brief Read SRAM * * This function reads from the SRAM of the radio transceiver. @@ -552,7 +553,6 @@ hal_frame_write(uint8_t *write_buffer, uint8_t length) * \param length Length of the read burst * \param data Pointer to buffer where data is stored. */ -#if 0 //Uses 80 bytes (on Raven) omit unless needed void hal_sram_read(uint8_t address, uint8_t length, uint8_t *data) { @@ -576,6 +576,7 @@ hal_sram_read(uint8_t address, uint8_t length, uint8_t *data) } #endif /*----------------------------------------------------------------------------*/ +#if 0 //omit unless needed /** \brief Write SRAM * * This function writes into the SRAM of the radio transceiver. It can reduce @@ -585,7 +586,6 @@ hal_sram_read(uint8_t address, uint8_t length, uint8_t *data) * \param length Length of the write burst * \param data Pointer to an array of bytes that should be written */ -#if 0 //omit unless needed void hal_sram_write(uint8_t address, uint8_t length, uint8_t *data) { @@ -632,7 +632,7 @@ volatile char rf230interruptflag; #define INTERRUPTDEBUG(arg) #endif -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) /* The atmega128rfa1 has individual interrupts for the integrated radio' * Whichever are enabled by the RF230 driver must be present even if not used! */ @@ -700,12 +700,12 @@ ISR(TRX24_TX_END_vect) rf230_txendwait=0; } -extern volatile uint8_t rf230_pending; +//extern volatile uint8_t rf230_pending; /* Frame address has matched ours */ ISR(TRX24_XAH_AMI_vect) { // DEBUGFLOW('8'); - rf230_pending=1; +// rf230_pending=1; } /* CCAED measurement has completed */ @@ -715,7 +715,7 @@ ISR(TRX24_CCA_ED_DONE_vect) rf230_ccawait=0; } -#else /* defined(__AVR_ATmega128RFA1__) */ +#else /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) */ /* Separate RF230 has a single radio interrupt and the source must be read from the IRQ_STATUS register */ HAL_RF230_ISR() { @@ -753,7 +753,8 @@ HAL_RF230_ISR() #endif #endif - } else if (interrupt_source & HAL_TRX_END_MASK){ + } + if (interrupt_source & HAL_TRX_END_MASK){ INTERRUPTDEBUG(11); state = hal_subregister_read(SR_TRX_STATUS); @@ -780,16 +781,20 @@ HAL_RF230_ISR() } - } else if (interrupt_source & HAL_TRX_UR_MASK){ + } + if (interrupt_source & HAL_TRX_UR_MASK){ INTERRUPTDEBUG(13); ; - } else if (interrupt_source & HAL_PLL_UNLOCK_MASK){ + } + if (interrupt_source & HAL_PLL_UNLOCK_MASK){ INTERRUPTDEBUG(14); ; - } else if (interrupt_source & HAL_PLL_LOCK_MASK){ + } + if (interrupt_source & HAL_PLL_LOCK_MASK){ INTERRUPTDEBUG(15); ; - } else if (interrupt_source & HAL_BAT_LOW_MASK){ + } + if (interrupt_source & HAL_BAT_LOW_MASK){ /* Disable BAT_LOW interrupt to prevent endless interrupts. The interrupt */ /* will continously be asserted while the supply voltage is less than the */ /* user-defined voltage threshold. */ @@ -798,12 +803,9 @@ HAL_RF230_ISR() hal_register_write(RG_IRQ_MASK, trx_isr_mask); INTERRUPTDEBUG(16); ; - } else { - INTERRUPTDEBUG(99); - ; } } -#endif /* defined(__AVR_ATmega128RFA1__) */ +#endif /* defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) */ # endif /* defined(DOXYGEN) */ /** @} */ diff --git a/cpu/avr/radio/rf230bb/rf230bb.c b/cpu/avr/radio/rf230bb/rf230bb.c index fa9ed2e99..a6b7572cf 100644 --- a/cpu/avr/radio/rf230bb/rf230bb.c +++ b/cpu/avr/radio/rf230bb/rf230bb.c @@ -212,7 +212,7 @@ static unsigned long total_time_for_transmission, total_transmission_len; static int num_transmissions; #endif -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) volatile uint8_t rf230_wakewait, rf230_txendwait, rf230_ccawait; #endif @@ -237,6 +237,8 @@ typedef enum{ PROCESS(rf230_process, "RF230 driver"); /*---------------------------------------------------------------------------*/ +int rf230_interrupt(void); + static int rf230_on(void); static int rf230_off(void); @@ -252,6 +254,31 @@ static int rf230_cca(void); uint8_t rf230_last_correlation,rf230_last_rssi,rf230_smallest_rssi; +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ const struct radio_driver rf230_driver = { rf230_init, @@ -263,7 +290,11 @@ const struct radio_driver rf230_driver = rf230_receiving_packet, rf230_pending_packet, rf230_on, - rf230_off + rf230_off, + get_value, + set_value, + get_object, + set_object }; uint8_t RF230_receive_on; @@ -402,7 +433,21 @@ rf230_waitidle(void) } } -/*----------------------------------------------------------------------------*/ +/* Set reduced power consumption for AtMegaXXXRFR2 MCU's. See AT02594 */ + +static uint8_t rpc = 0xFF; /* Default max power save */ +void +rf230_set_rpc(uint8_t data) +{ + rpc = data; +} + +uint8_t +rf230_get_rpc(void) +{ + return rpc; +} + /** \brief This function will change the current state of the radio * transceiver's internal state machine. * @@ -476,6 +521,10 @@ radio_set_trx_state(uint8_t new_state) /* When the PLL is active most states can be reached in 1us. However, from */ /* TRX_OFF the PLL needs time to activate. */ if (current_state == TRX_OFF){ + +#if defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) + hal_subregister_write(SR_TRX_RPC, rpc); /* Enable RPC features */ +#endif delay_us(TIME_TRX_OFF_TO_PLL_ACTIVE); } else { delay_us(TIME_STATE_TRANSITION_PLL_ACTIVE); @@ -504,7 +553,7 @@ rf230_set_promiscuous_mode(bool isPromiscuous) { #if RF230_CONF_AUTOACK is_promiscuous = isPromiscuous; /* TODO: Figure out when to pass promisc state to 802.15.4 */ -// radio_set_trx_state(is_promiscuous?RX_ON:RX_AACK_ON); + radio_set_trx_state(is_promiscuous?RX_ON:RX_AACK_ON); #endif } @@ -523,7 +572,19 @@ rf230_is_ready_to_send() { static void flushrx(void) { + /* Clear the length field to allow buffering of the next packet */ rxframe[rxframe_head].length=0; + rxframe_head++; + if (rxframe_head >= RF230_CONF_RX_BUFFERS) { + rxframe_head=0; + } + /* If another packet has been buffered, schedule another receive poll */ + if (rxframe[rxframe_head].length) { + rf230_interrupt(); + } + else { + rf230_pending = 0; + } } /*---------------------------------------------------------------------------*/ static void @@ -542,7 +603,7 @@ radio_on(void) #if RF230BB_CONF_LEDONPORTE1 PORTE|=(1<1 { uint8_t i; @@ -1403,6 +1504,7 @@ rf230_read(void *buf, unsigned short bufsize) #if RADIOALWAYSON && DEBUGFLOWSIZE if (RF230_receive_on==0) {if (debugflow[debugflowsize-1]!='z') DEBUGFLOW('z');} //cxmac calls with radio off? #endif + flushrx(); return 0; } @@ -1445,19 +1547,8 @@ rf230_read(void *buf, unsigned short bufsize) memcpy(buf,framep,len-AUX_LEN+CHECKSUM_LEN); rf230_last_correlation = rxframe[rxframe_head].lqi; - /* Clear the length field to allow buffering of the next packet */ - rxframe[rxframe_head].length=0; - rxframe_head++; - if (rxframe_head >= RF230_CONF_RX_BUFFERS) { - rxframe_head=0; - } - /* If another packet has been buffered, schedule another receive poll */ - if (rxframe[rxframe_head].length) { - rf230_interrupt(); - } - else { - rf230_pending = 0; - } + /* Prepare to receive another packet */ + flushrx(); /* Point to the checksum */ framep+=len-AUX_LEN; @@ -1623,7 +1714,7 @@ rf230_cca(void) /* Start the CCA, wait till done, return result */ /* Note reading the TRX_STATUS register clears both CCA_STATUS and CCA_DONE bits */ -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) #if 1 //interrupt method /* Disable rx transitions to busy (RX_PDT_BIT) */ /* Note: for speed this resets rx threshold to the compiled default */ @@ -1650,7 +1741,7 @@ rf230_cca(void) /* Use ED register to determine result. 77dBm is poweron csma default.*/ #ifdef RF230_CONF_CCA_THRES - if (hal_register_read(RG_PHY_ED_LEVEL)<(91+RF230_CONF_CCA_THRES) cca=0xff; + if (hal_register_read(RG_PHY_ED_LEVEL)<(91+RF230_CONF_CCA_THRES)) cca=0xff; #else if (hal_register_read(RG_PHY_ED_LEVEL)<(91-77)) cca=0xff; #endif @@ -1672,9 +1763,9 @@ rf230_cca(void) /* If already in receive mode can read the current ED register without delay */ /* CCA energy threshold = -91dB + 2*SR_CCA_ED_THRESH. Reset defaults to -77dB */ #ifdef RF230_CONF_CCA_THRES - if (hal_register_read(RG_PHY_ED_LEVEL)<(91+RF230_CONF_CCA_THRES) cca=0xff; + if (hal_register_read(RG_PHY_ED_LEVEL)<(91+RF230_CONF_CCA_THRES)) cca=0xff; #else - if (hal_register_read(RG_PHY_ED_LEVEL)<(91-77)) cca=0xff; + if (hal_register_read(RG_PHY_ED_LEVEL)<(91-77)) cca=0xff; #endif #endif diff --git a/cpu/avr/radio/rf230bb/rf230bb.h b/cpu/avr/radio/rf230bb/rf230bb.h index 020c3250f..c441e09ab 100644 --- a/cpu/avr/radio/rf230bb/rf230bb.h +++ b/cpu/avr/radio/rf230bb/rf230bb.h @@ -49,14 +49,16 @@ * */ -#ifndef RADIO_H -#define RADIO_H +#ifndef RF230BB_H_ +#define RF230BB_H_ /*============================ INCLUDE =======================================*/ #include #include #include "hal.h" #if defined(__AVR_ATmega128RFA1__) #include "atmega128rfa1_registermap.h" +#elif defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) +#include "atmega256rfr2_registermap.h" #else #include "at86rf230_registermap.h" #endif @@ -68,7 +70,7 @@ #define RF230_REVB ( 2 ) #define SUPPORTED_MANUFACTURER_ID ( 31 ) -#if defined(__AVR_ATmega128RFA1__) +#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega128RFR2__) || defined(__AVR_ATmega256RFR2__) #define RF230_SUPPORTED_INTERRUPT_MASK ( 0xFF ) #else /* RF230 does not support RX_START interrupts in extended mode, but it seems harmless to always enable it. */ @@ -215,6 +217,8 @@ uint8_t rf230_get_channel(void); void rf230_set_pan_addr(unsigned pan,unsigned addr,const uint8_t ieee_addr[8]); void rf230_set_txpower(uint8_t power); uint8_t rf230_get_txpower(void); +void rf230_set_rpc(uint8_t rpc); +uint8_t rf230_get_rpc(void); void rf230_set_promiscuous_mode(bool isPromiscuous); bool rf230_is_ready_to_send(); @@ -225,6 +229,6 @@ uint8_t rf230_get_raw_rssi(void); #define rf230_rssi rf230_get_raw_rssi -#endif +#endif /* RF230BB_H_ */ /** @} */ /*EOF*/ diff --git a/cpu/avr/watchdog.c b/cpu/avr/watchdog.c index 04734fcdf..b37691e39 100644 --- a/cpu/avr/watchdog.c +++ b/cpu/avr/watchdog.c @@ -64,11 +64,11 @@ #include #include -//Not all AVR toolchains alias MCUSR to the older MSUSCR name -//#if defined (__AVR_ATmega8__) || defined (__AVR_ATmega8515__) || defined (__AVR_ATmega16__) -#if !defined (MCUSR) && defined (MCUCSR) -#warning *** MCUSR not defined, using MCUCSR instead *** -#define MCUSR MCUCSR +/* MCUSR is a deprecated name but older avr-libc versions may define it */ +#if !defined (MCUCSR) +# if defined (MCUSR) +# define MCUCSR MCUSR +# endif #endif #if WATCHDOG_CONF_BALANCE && WATCHDOG_CONF_TIMEOUT >= 0 @@ -82,7 +82,7 @@ watchdog_init(void) /* Clear startup bit and disable the wdt, whether or not it will be used. Random code may have caused the last reset. */ - MCUSR&=~(1<= 0 stopped = 1; diff --git a/cpu/cc2430/8051def.h b/cpu/cc2430/8051def.h deleted file mode 100644 index 6d89a1fb2..000000000 --- a/cpu/cc2430/8051def.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * \file - * This file contains a set of configuration for using SDCC as a compiler. - * Modified from z80 port for cc2430 port. - * - * \author - * Takahide Matsutsuka (Original) - * George Oikonomou - - * (recent updates for the sensinode/cc2430 port) - */ - -#ifndef E051_DEF_H_ -#define E051_DEF_H_ - -#include - -/* This port no longer implements the legacy clock_delay. Hack its usages - * outta the way till it gets phased out completely - * NB: This also overwrites the prototype so delay_usec() is declared twice */ -#define clock_delay(t) clock_delay_usec(t) - -/* - * lint - style defines to help syntax parsers with sdcc-specific 8051 code - * They don't interfere with actual compilation - */ -#if !defined(__SDCC_mcs51) && !defined(SDCC_mcs51) -#define __data -#define __xdata -#define __code -#define __bit bool -#define __sfr volatile unsigned char -#define __sbit volatile bool -#define __critical -#define __at(x) -#define __using(x) -#define __interrupt(x) -#define __naked -#endif - -#define CC_CONF_FUNCTION_POINTER_ARGS 1 -#define CC_CONF_FASTCALL -#define CC_CONF_VA_ARGS 1 -#define CC_CONF_UNSIGNED_CHAR_BUGS 0 -#define CC_CONF_REGISTER_ARGS 0 -#define CC_CONF_FUNCTION_POINTER_KEYWORD __reentrant -#define CC_CONF_NON_BANKED_OPTIMIZATION 1 - -#if (defined(__SDCC_mcs51) || defined(SDCC_mcs51)) && CC_CONF_NON_BANKED_OPTIMIZATION -#define CC_NON_BANKED __nonbanked -#else -#define CC_NON_BANKED -#endif - -/* - * Max Stack Depth manipulation. It is possible to get up to 247 bytes - * allocated for the stack if: - * - You set this to 1 and - * - You have a patched toolchain and - * - You don't use __bit variables - * - You do not link libraries using BIT registers (e.g. printf_large) - * Enabling this will mean ISRs will NOT push bits (#pragma exclude bits) so - * make sure you know what you're doing - * - * More information on the wiki - */ -#define CC_CONF_OPTIMIZE_STACK_SIZE 0 - -#if CC_CONF_OPTIMIZE_STACK_SIZE -#define CC_AT_DATA -#else -#define CC_AT_DATA __data -#endif - -/* Generic types. */ -typedef unsigned short uip_stats_t; - -/* Time type. */ -typedef unsigned short clock_time_t; -#define MAX_TICKS (~((clock_time_t)0) / 2) -/* Defines tick counts for a second. */ -#define CLOCK_CONF_SECOND 128 - -/* Compiler configurations */ -#define CCIF -#define CLIF - -/* Single asm instruction without messing up syntax highlighting */ -#if defined(__SDCC_mcs51) || defined(SDCC_mcs51) -#define ASM(x) __asm \ - x \ - __endasm -#else -#define ASM(x) -#endif - -/* Critical section management */ -#define DISABLE_INTERRUPTS() do {EA = 0;} while(0) -#define ENABLE_INTERRUPTS() do {EA = 1;} while(0) - -/* Macro for a soft reset. */ -#define SOFT_RESET() do {((void (__code *) (void)) 0x0000) ();} while(0) - -/* We don't provide architecture-specific checksum calculations */ -#define UIP_ARCH_ADD32 0 -#define UIP_ARCH_CHKSUM 0 - -#define CC_CONF_ASSIGN_AGGREGATE(dest, src) \ - memcpy(dest, src, sizeof(*dest)) - -#define uip_ipaddr_copy(dest, src) \ - memcpy(dest, src, sizeof(*dest)) - -#endif /* E051_DEF_H_ */ diff --git a/cpu/cc2430/Makefile.cc2430 b/cpu/cc2430/Makefile.cc2430 deleted file mode 100644 index 1cd207356..000000000 --- a/cpu/cc2430/Makefile.cc2430 +++ /dev/null @@ -1,116 +0,0 @@ -### Compiler definitions -CC = sdcc -LD = sdcc -AS = sdcc -AR = sdar -OBJCOPY = objcopy -STRIP = strip -PACKIHX = packihx -BANK_ALLOC = $(CONTIKI)/cpu/cc2430/bank-alloc.py -SEGMENT_RULES = $(OBJECTDIR)/segment.rules - -CFLAGS += --model-$(MEMORY_MODEL) --stack-auto -DSDCC_CC2430 --std-c99 -CFLAGS += --fomit-frame-pointer - -### Disable warning 110 (EVELYN the modified dog) and 126 (unreachable code) -CFLAGS += --disable-warning 110 --disable-warning 126 - -LDFLAGS += --model-$(MEMORY_MODEL) --stack-auto -DSDCC_CC2430 --out-fmt-ihx -LDFLAGS += --xram-loc 0xE000 --xram-size 0x1F00 -LDFLAGS += --code-loc $(START_ADDR) --code-size $(CODE_SIZE) - -ASFLAGS += -plosgff - -AROPTS = -rc - -### Our object files are .rel, so we can't use the default finalize dependency -### generation. Override here. -define FINALIZE_SDCC_DEPENDENCY -cp $(@:.rel=.d) $(@:.rel=.$$$$); \ -sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ - -e '/^$$/ d' -e 's/$$/ :/' < $(@:.rel=.$$$$) >> $(@:.rel=.d); \ -rm -f $(@:.rel=.$$$$) -endef - -### Banking Guesswork: -### Examples outside examples/sensinode do not specify banking. -### We automatically turn it on if its unspecified and if we are building with -### UIP_CONF_IPV6 -ifndef HAVE_BANKING - ifeq ($(UIP_CONF_IPV6),1) - HAVE_BANKING=1 - else - HAVE_BANKING=0 - endif -endif - -### Does the project want us to offset the firmware? -### define start address and max code size accordingly, turn Disco on -ifeq ($(OFFSET_FIRMWARE),1) - START_ADDR = 0x01000 - HOME_START = 00001000 - ifeq ($(HAVE_BANKING),1) - CODE_SIZE = 0x1F000 - else - CODE_SIZE = 0x0F000 - endif -else - START_ADDR = 0x00000 - HOME_START = 00000000 - ifeq ($(HAVE_BANKING),1) - CODE_SIZE = 0x20000 - else - CODE_SIZE = 0x10000 - endif -endif - -### Are we building with BANKing supoprt? -ifeq ($(HAVE_BANKING),1) - ## Yes - MEMORY_MODEL=huge - LDFLAGS += -Wl-bBANK1=0x018000 - LD_POST_FLAGS += -Wl-bBANK2=0x028000 - LD_POST_FLAGS += -Wl-bBANK3=0x038000 - LDFLAGS += -Wl-r - CFLAGS += -DHAVE_SDCC_BANKING - #use this in $(call c_seg,$<) to get segment for a source file. - c_seg = --codeseg $(shell python $(BANK_ALLOC) $1 $(SEGMENT_RULES) $2) -else - ## No banking - MEMORY_MODEL=large - c_seg = -endif - -### CPU-dependent cleanup files -CLEAN += *.lnk *.lk *.sym *.lib *.ihx *.rel *.mem *.rst *.asm *.hex -CLEAN += *.omf *.cdb *.banks -CLEAN += symbols.c symbols.h - -### CPU-dependent directories -CONTIKI_CPU_DIRS = . dev - -### CPU-dependent source files -CONTIKI_SOURCEFILES += bus.c clock.c uart0.c uart1.c cc2430_rf.c dma.c -CONTIKI_SOURCEFILES += uart_intr.c cc2430_rf_intr.c dma_intr.c -CONTIKI_SOURCEFILES += watchdog-cc2430.c rtimer-arch.c stack.c -CONTIKI_ASMFILES += - -CONTIKI_ASMOBJECTFILES = $(addprefix $(OBJECTDIR)/,$(CONTIKI_ASMFILES:.S=.rel)) - -CONTIKI_CASMOBJECTFILES = $(addprefix $(OBJECTDIR)/, \ - $(CONTIKI_CASMFILES:.cS=.rel)) - -CONTIKI_PLATFORM_DIRS = $(PLATFORM_APPDIRS) \ - $(addprefix $(CONTIKI)/platform/$(TARGET)/, $(CONTIKI_TARGET_DIRS)) - -CONTIKI_CPU_DIRS_LIST = $(addprefix $(CONTIKI_CPU)/, \ - $(CONTIKI_CPU_DIRS)) - -oname = $(patsubst %.c,%.rel,$(patsubst %.S,%.rel,$(1))) - -CONTIKI_OBJECTFILES = $(addprefix $(OBJECTDIR)/, \ - $(call oname, $(CONTIKI_SOURCEFILES))) - -PROJECT_OBJECTFILES = $(addprefix $(OBJECTDIR)/, \ - $(call oname, $(PROJECT_SOURCEFILES))) - diff --git a/cpu/cc2430/Makefile.customrules-cc2430 b/cpu/cc2430/Makefile.customrules-cc2430 deleted file mode 100644 index 68ed21c60..000000000 --- a/cpu/cc2430/Makefile.customrules-cc2430 +++ /dev/null @@ -1,63 +0,0 @@ -### Compilation rules - -SEGMENT_RULE_FILES = $(foreach dir, . $(CONTIKI_PLATFORM_DIRS) \ - $(CONTIKI_CPU_DIRS_LIST), $(wildcard $(dir)/segment.rules) ) - -# NB: Assumes SEGMENT_RULES was not overridden and is in $(OBJECTDIR) -$(SEGMENT_RULES): $(SEGMENT_RULE_FILES) | $(OBJECTDIR) - cat $(SEGMENT_RULE_FILES) | \ - sed -e 's/#.*$$//' -e 's/^\s*//' -e '/^$$/d' > $@ - -CUSTOM_RULE_LINK=1 -CUSTOM_RULE_C_TO_OBJECTDIR_O=1 -CUSTOM_RULE_ALLOBJS_TO_TARGETLIB=1 - -$(OBJECTDIR)/%.rel: %.c $(SEGMENT_RULES) | $(OBJECTDIR) - $(TRACE_CC) - $(Q)$(CC) $(call c_seg,$<,$@) $(CFLAGS) -c $< -o $@ -Wp,-MMD,$(@:.rel=.d),-MQ,$@ - @$(FINALIZE_SDCC_DEPENDENCY) - -contiki-$(TARGET).lib: $(CONTIKI_OBJECTFILES) $(PROJECT_OBJECTFILES) \ - $(CONTIKI_ASMOBJECTFILES) $(CONTIKI_CASMOBJECTFILES) - rm -f $@ - for target in $^; do echo $$target >> $@; done - -.PRECIOUS: %.$(TARGET) %.hex - -# build app/example local object files. We need a separate rule so that we can -# pass -DAUTOSTART_ENABLE for those files only -$(OBJECTDIR)/%.app.rel: %.c $(SEGMENT_RULES) | $(OBJECTDIR) - $(TRACE_CC) - $(Q)$(CC) $(call c_seg,$<,$@) -DAUTOSTART_ENABLE $(CFLAGS) -c $< -o $@ - -# .ihx is the sdcc binary output file -%.ihx: $(OBJECTDIR)/%.app.rel $(CONTIKI_TARGET_MAIN) contiki-$(TARGET).lib -# Automatic bank relocation when building banked code -ifeq ($(HAVE_BANKING),1) - @echo "\nFirst Link" - @echo "===============" - $(TRACE_LD) - $(Q)$(LD) $(LDFLAGS) -o $@ $(CONTIKI_TARGET_MAIN) $(OBJECTDIR)/$*.app.rel -llibsdcc.lib -lcontiki-$(TARGET).lib - @echo "\nBank Allocation" - @echo "===============" - python $(BANK_ALLOC) $(basename $(@F)) $(SEGMENT_RULES) $(OFFSET_FIRMWARE) - @echo "\nFinal Link" - @echo "===============" -endif - $(TRACE_LD) - $(Q)$(LD) $(LDFLAGS) $(LD_POST_FLAGS) -o $@ $(CONTIKI_TARGET_MAIN) $(OBJECTDIR)/$*.app.rel -llibsdcc.lib -lcontiki-$(TARGET).lib - -# Pack the hex file for programmers which dislike SDCC output hex format -%.hex: %.ihx - @echo "\nPack hex file" - @echo "===============" -ifeq ($(HAVE_BANKING),1) - srec_cat -disable_sequence_warnings $< -intel -crop 0x10000 0x1FFFF -offset -0x10000 -o bank1.hex -intel - srec_cat -disable_sequence_warnings $< -intel -crop 0x20000 0x2FFFF -offset -0x18000 -o bank2.hex -intel - srec_cat -disable_sequence_warnings $< -intel -crop 0x30000 0x3FFFF -offset -0x20000 -o bank3.hex -intel - srec_cat -disable_sequence_warnings $< -intel -crop 0x00000 0x0FFFF -o home.ihx -intel - srec_cat home.ihx -intel bank1.hex -intel bank2.hex -intel bank3.hex -intel -o $@ -intel - rm -f home.ihx bank1.hex bank2.hex bank3.hex -else - $(PACKIHX) $< > $@ -endif diff --git a/cpu/cc2430/bank-alloc.py b/cpu/cc2430/bank-alloc.py deleted file mode 100644 index 10e452577..000000000 --- a/cpu/cc2430/bank-alloc.py +++ /dev/null @@ -1,228 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2010, Loughborough University - Computer Science -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. 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. -# 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. -# -# This file is part of the Contiki operating system. - -# \file -# Automatic allocation of modules to code segments for bankable builds -# with SDCC's huge memory model. -# -# \author -# George Oikonomou - -import sys -import re -import operator -import fileinput -import os - -# Open a module object file (.rel) and read it's code size -def retrieve_module_size(file_name): - size_pat = re.compile('^A\s+(?:HOME|BANK[0-9])\s+size\s+([1-9A-F][0-9A-F]*)') - for code_line in open(file_name): - matches = size_pat.search(code_line) - if matches is not None: - return int(matches.group(1), 16) - return 0 - -# Searches for a code segment rule for file_name in the segment_rules file -# If there is a rule, we respect it. Otherwise, we can move the file around -def get_source_seg(source_file, object_file, segment_rules): - for line in open(segment_rules): - tokens = line.split(None) - match = re.search(tokens[1], source_file) - if match is not None: - # Save it in basename.seg - base, ext = os.path.splitext(object_file) - of = open(base + '.seg', 'w') - of.write(tokens[0] + '\n') - of.close - return tokens[0] - return None - -# If segment.rules specified a rule for a source file, the respective object -# file's banking requirement will be stored in object_file.seg -def get_object_seg(object_file): - base, ext = os.path.splitext(object_file) - seg = base + '.seg' - bank = None - if os.path.isfile(seg) is True: - of = open(base + '.seg', 'r') - bank = of.readline().strip() - of.close() - return bank - -# Open project.mem and retreive the project's total code footprint -def get_total_size(project): - mem_file = project + '.mem' - pat = re.compile('FLASH\s+(0x[0-9a-f]+\s+){2}([0-9]+)') - for line in open(mem_file): - l = pat.search(line) - if l is not None: - return int(l.group(2)) - -# Open project.map and retrieve the list of modules linked in -# This will only consider contiki sources, not SDCC libraries -# NB: Sometimes object filenames get truncated: -# contiki-sensinode.lib [ obj_sensinode/watchdog-cc2430.re ] -# See how for this file the 'l' in 'rel' is missing. For that reason, we retrieve -# the filaname until the last '.' but without the extension and we append 'rel' -# As long as the filename doesn't get truncated, we're good -def populate(project, modules, segment_rules, bins): - bankable_total = 0 - user_total = 0 - - map_file = project + '.map' - file_pat = re.compile('obj_sensinode[^ ]+\.') - for line in open(map_file): - file_name = file_pat.search(line) - if file_name is not None: - mod = file_name.group(0) + 'rel' - code_size = retrieve_module_size(mod) - seg = get_object_seg(mod) - if seg is not None: - # This module has been assigned to a bank by the user - #print 'In', seg, file_name.group(0), 'size', code_size - bins[seg][0] += code_size - user_total += code_size - else: - # We are free to allocate this module - modules.append([mod, code_size, "NONE"]) - bankable_total += code_size - return bankable_total, user_total - -# Allocate bankable modules to banks according to a simple -# 'first fit, decreasing' bin packing heuristic. -def bin_pack(modules, bins, offset, log): - if offset==1: - bins['HOME'][1] -= 4096 - - # Sort by size, descending, in=place - modules.sort(key=operator.itemgetter(1), reverse=True) - - for module in modules: - # We want to iterate in a specific order and dict.keys() won't do that - for bin_id in ['BANK1', 'BANK2', 'BANK3', 'HOME']: - if bins[bin_id][0] + module[1] < bins[bin_id][1]: - bins[bin_id][0] += module[1] - module[2] = bin_id - log.writelines(' '.join([module[2].ljust(8), \ - str(module[1]).rjust(5), module[0], '\n'])) - break - else: - if bin_id == 'HOME': - print "Failed to allocate", module[0], "with size", module[1], \ - "to a code bank. This is fatal" - return 1 - return 0 - -# Hack the new bank directly in the .rel file -def relocate(module, bank): - code_pat = re.compile('(A\s+)(?:HOME|BANK[0-9])(\s+size\s+[1-9A-F][0-9A-F]*.+\n)') - - for line in fileinput.input(module, inplace=1): - m = code_pat.search(line) - if m is not None: - line = m.group(1) + bank + m.group(2) - sys.stdout.write(line) - return - -if len(sys.argv) < 3: - print 'Usage:' - print 'bank-alloc.py project path_to_segment_rules [offset]' - print 'bank-alloc.py source_file path_to_segment_rules object_file' - sys.exit(1) - -modules = list() -file_name = sys.argv[1] -segment_rules = sys.argv[2] - -# Magic: Guess whether we want to determine the code bank for a code file -# or whether we want to bin-pack -basename, ext = os.path.splitext(file_name) -if ext == '.c': - # Code Segment determination - if len(sys.argv) < 4: - print 'Usage:' - print 'bank-alloc.py project path_to_segment_rules [offset]' - print 'bank-alloc.py source_file path_to_segment_rules object_file' - sys.exit(1) - object_file = sys.argv[3] - seg = get_source_seg(file_name, object_file, segment_rules) - if seg is None: - print "BANK1" - else: - print seg - exit() - -# Bin-Packing -offset = 0 -if len(sys.argv) > 3 and sys.argv[3] is not None: - offset = int(sys.argv[3]) - -sizes = {'total': 0, 'bankable': 0, 'user': 0, 'libs': 0} - -# Name : [Allocated, capacity] -bins = { - 'HOME': [0, 32768], - 'BANK1': [0, 32768], - 'BANK2': [0, 32768], - 'BANK3': [0, 30720] -} - -sizes['total'] = get_total_size(basename) -sizes['bankable'], sizes['user'] = populate(basename, modules, segment_rules, bins) -sizes['libs'] = sizes['total'] - sizes['bankable'] - sizes['user'] - -print 'Total Size =', sizes['total'], 'bytes (' + \ - str(sizes['bankable']), 'bankable,', \ - str(sizes['user']), 'user-allocated,', \ - str(sizes['libs']), 'const+libs)' - -bins['HOME'][0] += sizes['libs'] - -print 'Preallocations: HOME=' + str(bins['HOME'][0]) + \ - ', BANK1=' + str(bins['BANK1'][0]) + ', BANK2=' + str(bins['BANK2'][0]) + \ - ', BANK3=' + str(bins['BANK3'][0]) - -# Open a log file -of = open(basename + '.banks', 'w') -pack = bin_pack(modules, bins, offset, of) -of.close() - -print "Bin-Packing results (target allocation):" -print "Segment - max - alloc" -for bin_id in ['HOME', 'BANK1', 'BANK2', 'BANK3']: - print bin_id.rjust(7), str(bins[bin_id][1]).rjust(6), str(bins[bin_id][0]).rjust(6) - -if pack > 0: - sys.exit(1) - -# If we reach here we seem to have a sane allocation. Start changing .rel files -for module in modules: - relocate(module[0], module[2]) diff --git a/cpu/cc2430/cc2430_sfr.h b/cpu/cc2430/cc2430_sfr.h deleted file mode 100644 index 53581cd29..000000000 --- a/cpu/cc2430/cc2430_sfr.h +++ /dev/null @@ -1,709 +0,0 @@ -/** - * - * \file cc2430_sfr.h - * \brief CC2430 registers header file for CC2430. - * - * Definitions for CC2430 SFR registers. - * - * - */ - -#ifndef REG_CC2430_H -#define REG_CC2430_H - -#include "8051def.h" - -/* BYTE Register */ - -__sfr __at (0x80) P0 ; -/* P0 */ -__sbit __at (0x87) P0_7 ; -__sbit __at (0x86) P0_6 ; -__sbit __at (0x85) P0_5 ; -__sbit __at (0x84) P0_4 ; -__sbit __at (0x83) P0_3 ; -__sbit __at (0x82) P0_2 ; -__sbit __at (0x81) P0_1 ; -__sbit __at (0x80) P0_0 ; - -__sfr __at (0x81) SP ; -__sfr __at (0x82) DPL0 ; -__sfr __at (0x83) DPH0 ; -/*DPL and DPH correspond DPL0 and DPH0 (82-83)*/ -__sfr __at (0x84) DPL1; -__sfr __at (0x85) DPH1; -__sfr __at (0x86) U0CSR; -#define U_MODE 0x80 -#define U_RE 0x40 -#define U_SLAVE 0x20 -#define U_FE 0x10 -#define U_ERR 0x08 -#define U_RXB 0x04 -#define U_TXB 0x02 -#define U_ACTIVE 0x01 - -__sfr __at (0x87) PCON ; -/* PCON (0x87) */ -#define IDLE 0x01 - -__sfr __at (0x88) TCON ; -/* TCON (0x88) */ -__sbit __at (0x8F) TCON_URX1IF; -/*__sbit __at (0x8E) RES;*/ -__sbit __at (0x8D) TCON_ADCIF; -/*__sbit __at (0x8C) RES;*/ -__sbit __at (0x8B) TCON_URX0IF; -__sbit __at (0x8A) TCON_IT1; -__sbit __at (0x89) TCON_RFERRIF; -__sbit __at (0x88) TCON_IT0; - - -__sfr __at (0x89) P0IFG; -__sfr __at (0x8A) P1IFG; -__sfr __at (0x8B) P2IFG; -__sfr __at (0x8C) PICTL; -/*PICTL bits*/ -#define PADSC 0x40 -#define P2IEN 0x20 -#define P0IENH 0x10 -#define P0IENL 0x08 -#define P2ICON 0x04 -#define P1ICON 0x02 -#define P0ICON 0x01 - -__sfr __at (0x8D) P1IEN; -__sfr __at (0x8F) P0INP; - -__sfr __at (0x90) P1 ; -/* P1 */ -__sbit __at (0x90) P1_0 ; -__sbit __at (0x91) P1_1 ; -__sbit __at (0x92) P1_2 ; -__sbit __at (0x93) P1_3 ; -__sbit __at (0x94) P1_4 ; -__sbit __at (0x95) P1_5 ; -__sbit __at (0x96) P1_6 ; -__sbit __at (0x97) P1_7 ; - -__sfr __at (0x91) RFIM; -__sfr __at (0x92) DPS; -__sfr __at (0x93) _XPAGE; /*MPAGE as paging register for sdcc*/ -__sfr __at (0x94) T2CMP; -__sfr __at (0x95) ST0; -__sfr __at (0x96) ST1; -__sfr __at (0x97) ST2; -__sfr __at (0x98) S0CON ; - -__sbit __at (0x99) S0CON_ENCIF_1; -__sbit __at (0x98) S0CON_ENCIF_0; - -__sfr __at (0x99) HSRC; -__sfr __at (0x9A) IEN2; -/*IEN2 bits*/ -#define WDTIE 0x20 -#define P1IE 0x10 -#define UTX1IE 0x08 -#define UTX0IE 0x04 -#define P2IE 0x02 -#define RFIE 0x01 -__sfr __at (0x9B) S1CON; -/*S1CON bits*/ -#define RFIF_1 0x02 -#define RFIF_0 0x01 -__sfr __at (0x9C) T2PEROF0; -__sfr __at (0x9D) T2PEROF1; -__sfr __at (0x9E) T2PEROF2; -/*T2PEROF2 bits*/ -#define CMPIM 0x80 -#define PERIM 0x40 -#define OFCMPIM 0x20 - -#define PEROF23 0x08 -#define PEROF22 0x04 -#define PEROF21 0x02 -#define PEROF20 0x01 - -__sfr __at (0x9F) FMAP; -__sfr __at (0x9F) PSBANK; - -__sfr __at (0xA0) P2 ; -/* P2 */ -__sbit __at (0xA0) P2_0 ; -__sbit __at (0xA1) P2_1 ; -__sbit __at (0xA2) P2_2 ; -__sbit __at (0xA3) P2_3 ; -__sbit __at (0xA4) P2_4 ; -/*__sbit __at (0xA5) P2_5 ; -__sbit __at (0xA6) P2_6 ; -__sbit __at (0xA7) P2_7 ;*/ - -__sfr __at (0xA1) T2OF0; -__sfr __at (0xA2) T2OF1; -__sfr __at (0xA3) T2OF2; -__sfr __at (0xA4) T2CAPLPL; -__sfr __at (0xA5) T2CAPHPH; -__sfr __at (0xA6) T2TLD; -__sfr __at (0xA7) T2THD; - -__sfr __at (0xA8) IE ; -__sfr __at (0xA8) IEN0; -/*IEN0 bits*/ -#define IEN0_EA_MASK 0x80 -#define STIE 0x20 -#define ENCIE 0x10 -#define URX1IE 0x08 -#define URX0IE 0x04 -#define ADCIE 0x02 -#define RFERRIE 0x01 -/* IEN0 (0xA8) */ -__sbit __at (0xAF) EA; -__sbit __at (0xAF) IEN0_EA; -/*__sbit __at (0xAE) RES;*/ -__sbit __at (0xAD) IEN0_STIE; -__sbit __at (0xAC) IEN0_ENCIE; -__sbit __at (0xAB) IEN0_URX1IE; -__sbit __at (0xAA) IEN0_URX0IE; -__sbit __at (0xA9) IEN0_ADCIE; -__sbit __at (0xA8) IEN0_RFERRIE; - -__sfr __at (0xA9) IP0; -/*IP0 bits*/ -#define IP0_5 0x20 -#define IP0_4 0x10 -#define IP0_3 0x08 -#define IP0_2 0x04 -#define IP0_1 0x02 -#define IP0_0 0x01 -__sfr __at (0xAB) FWT; -__sfr __at (0xAC) FADDRL; -__sfr __at (0xAD) FADDRH; - -__sfr __at (0xAE) FCTL; -#define F_BUSY 0x80 -#define F_SWBSY 0x40 -#define F_CONTRD 0x10 -#define F_WRITE 0x02 -#define F_ERASE 0x01 -__sfr __at (0xAF) FWDATA; - -/*No port 3 (0xB0)*/ -__sfr __at (0xB1) ENCDI; -__sfr __at (0xB2) ENCDO; -__sfr __at (0xB3) ENCCS; -#define CCS_MODE2 0x40 -#define CCS_MODE1 0x20 -#define CCS_MODE0 0x10 -#define CCS_RDY 0x08 -#define CCS_CMD1 0x04 -#define CCS_CMD0 0x02 -#define CCS_ST 0x01 -__sfr __at (0xB4) ADCCON1; -/*ADCCON1 bits*/ -#define ADEOC 0x80 -#define ADST 0x40 -#define ADSTS1 0x20 -#define ADSTS0 0x10 -#define ADRCTRL1 0x08 -#define ADRCTRL0 0x04 -__sfr __at (0xB5) ADCCON2; -/*ADCCON2 bits*/ -#define ADSREF1 0x80 -#define ADSREF0 0x40 -#define ADSDIV1 0x20 -#define ADSDIV0 0x10 -#define ADSCH3 0x08 -#define ADSCH2 0x04 -#define ADSCH1 0x02 -#define ADSCH0 0x01 -__sfr __at (0xB6) ADCCON3; -/*ADCCON3 bits*/ -#define ADEREF1 0x80 -#define ADEREF0 0x40 -#define ADEDIV1 0x20 -#define ADEDIV0 0x10 -#define ADECH3 0x08 -#define ADECH2 0x04 -#define ADECH1 0x02 -#define ADECH0 0x01 - -__sfr __at (0xB7) RCCTL; -#undef IP /*this is 0xb8 in base core*/ - -__sfr __at (0xB8) IEN1; -/*IEN1 bits*/ -#define P0IE 0x20 -#define T4IE 0x10 -#define T3IE 0x08 -#define T2IE 0x04 -#define T1IE 0x02 -#define DMAIE 0x01 -/* IEN1 (0xB8) */ -/*__sbit __at (0xBF) IEN1_RES;*/ -/*__sbit __at (0xBE) RES;*/ -__sbit __at (0xBD) IEN1_P0IE; -__sbit __at (0xBC) IEN1_T4IE; -__sbit __at (0xBB) IEN1_T3IE; -__sbit __at (0xBA) IEN1_T2IE; -__sbit __at (0xB9) IEN1_T1IE; -__sbit __at (0xB8) IEN1_DMAIE; - -__sfr __at (0xB9) IP1; -/*IP1 bits*/ -#define IP1_5 0x20 -#define IP1_4 0x10 -#define IP1_3 0x08 -#define IP1_2 0x04 -#define IP1_1 0x02 -#define IP1_0 0x01 - -__sfr __at (0xBA) ADCL; -__sfr __at (0xBB) ADCH; -__sfr __at (0xBC) RNDL; -__sfr __at (0xBD) RNDH; - -__sfr __at (0xBE) SLEEP; -#define OSC32K_CALDIS 0x80 -#define XOSC_STB 0x40 -#define HFRC_STB 0x20 -#define RST1 0x10 -#define RST0 0x08 -#define OSC_PD 0x04 -#define SLEEP_MODE1 0x02 -#define SLEEP_MODE0 0x01 - -__sfr __at (0xC0) IRCON; -/*IRCON bits*/ -#define STIF 0x80 -#define P0IF 0x20 -#define T4IF 0x10 -#define T3IF 0x08 -#define T2IF 0x04 -#define T1IF 0x02 -#define DMAIF 0x01 -/* IRCON */ -__sbit __at (0xC7) IRCON_STIF ; -/*__sbit __at (0x86) IRCON_6 ;*/ -__sbit __at (0xC5) IRCON_P0IF; -__sbit __at (0xC4) IRCON_T4IF; -__sbit __at (0xC3) IRCON_T3IF; -__sbit __at (0xC2) IRCON_T2IF; -__sbit __at (0xC1) IRCON_T1IF; -__sbit __at (0xC0) IRCON_DMAIF; - -__sfr __at (0xC1) U0BUF; - -__sfr __at (0xC2) U0BAUD; -__sfr __at (0xC3) T2CNF; -/*T2SEL bits*/ -#define CMPIF 0x80 -#define PERIF 0x40 -#define OFCMPIF 0x20 - -#define CMSEL 0x08 - -#define SYNC 0x02 -#define RUN 0x01 - -__sfr __at (0xC4) U0UCR; -#define U_FLUSH 0x80 -#define U_FLOW 0x40 -#define U_D9 0x20 -#define U_BIT9 0x10 -#define U_PARITY 0x08 -#define U_SPB 0x04 -#define U_STOP 0x02 -#define U_START 0x01 - -__sfr __at (0xC5) U0GCR; -#define U_CPOL 0x80 -#define U_CPHA 0x40 -#define U_ORDER 0x20 -#define U_BAUD_E4 0x10 -#define U_BAUD_E3 0x08 -#define U_BAUD_E2 0x04 -#define U_BAUD_E1 0x02 -#define U_BAUD_E0 0x01 - -__sfr __at (0xC6) CLKCON; -#define OSC32K 0x80 -#define OSC 0x40 -#define TICKSPD2 0x20 -#define TICKSPD1 0x10 -#define TICKSPD0 0x08 -#define CLKSPD 0x01 - -__sfr __at (0xC7) MEMCTR; -#define MUNIF 0x40 -__sfr __at (0xC8) T2CON; - -__sfr __at (0xC9) WDCTL; -#define WDT_CLR3 0x80 -#define WDT_CLR2 0x40 -#define WDT_CLR1 0x20 -#define WDT_CLR0 0x10 -#define WDT_EN 0x08 -#define WDT_MODE 0x04 -#define WDT_INT1 0x02 -#define WDT_INT0 0x01 - -__sfr __at (0xCA) T3CNT; - -__sfr __at (0xCB) T3CTL; -/*T3CTL bits*/ -#define T3DIV2 0x80 -#define T3DIV1 0x40 -#define T3DIV0 0x20 -#define T3START 0x10 -#define T3OVFIM 0x08 -#define T3CLR 0x04 -#define T3MODE1 0x02 -#define T3MODE0 0x01 - -__sfr __at (0xCC) T3CCTL0; -/*T3CCTL0 bits*/ -#define T3IM 0x40 -#define T3CMP2 0x20 -#define T3CMP1 0x10 -#define T3CMP0 0x08 -#define T3MODE 0x04 -#define T3CAP1 0x02 -#define T3CAP0 0x01 - -__sfr __at (0xCD) T3CC0; -__sfr __at (0xCE) T3CCTL1; -/*T3CCTL0 bits apply*/ -__sfr __at (0xCF) T3CC1; - -__sfr __at (0xD0) PSW ; -/* PSW */ -__sbit __at (0xD0) P ; -__sbit __at (0xD1) F1 ; -__sbit __at (0xD2) OV ; -__sbit __at (0xD3) RS0 ; -__sbit __at (0xD4) RS1 ; -__sbit __at (0xD5) F0 ; -__sbit __at (0xD6) AC ; -__sbit __at (0xD7) CY ; - -__sfr __at (0xD1) DMAIRQ; -/*DMAIRQ bits*/ -#define DMAIF4 0x10 -#define DMAIF3 0x08 -#define DMAIF2 0x04 -#define DMAIF1 0x02 -#define DMAIF0 0x01 - -__sfr __at (0xD2) DMA1CFGL; -__sfr __at (0xD3) DMA1CFGH; -__sfr __at (0xD4) DMA0CFGL; -__sfr __at (0xD5) DMA0CFGH; - -__sfr __at (0xD6) DMAARM; -/*DMAARM bits*/ -#define ABORT 0x80 -#define DMAARM4 0x10 -#define DMAARM3 0x08 -#define DMAARM2 0x04 -#define DMAARM1 0x02 -#define DMAARM0 0x01 - -__sfr __at (0xD7) DMAREQ; -/*DMAREQ bits*/ -#define DMAREQ4 0x10 -#define DMAREQ3 0x08 -#define DMAREQ2 0x04 -#define DMAREQ1 0x02 -#define DMAREQ0 0x01 - -__sfr __at (0xD8) TIMIF; -/*TIMIF bits*/ -#define OVFIM 0x40 -#define T4CH1IF 0x20 -#define T4CH0IF 0x10 -#define T4OVFIF 0x08 -#define T3CH1IF 0x04 -#define T3CH0IF 0x02 -#define T3OVFIF 0x01 - -__sfr __at (0xD9) RFD; -__sfr __at (0xDA) T1CC0L; -__sfr __at (0xDB) T1CC0H; -__sfr __at (0xDC) T1CC1L; -__sfr __at (0xDD) T1CC1H; -__sfr __at (0xDE) T1CC2L; -__sfr __at (0xDF) T1CC2H; - -__sfr __at (0xE0) ACC; -__sfr __at (0xE1) RFST; -__sfr __at (0xE2) T1CNTL; -__sfr __at (0xE3) T1CNTH; - -__sfr __at (0xE4) T1CTL; -/*T1CTL bits*/ -#define CH2IF 0x80 -#define CH1IF 0x40 -#define CH0IF 0x20 -#define OVFIF 0x10 -#define T1DIV1 0x08 -#define T1DIV0 0x04 -#define T1MODE1 0x02 -#define T1MODE0 0x01 - -__sfr __at (0xE5) T1CCTL0; -/*T1CCTL0 bits*/ -#define T1CPSEL 0x80 -#define T1IM 0x40 -#define T1CMP2 0x20 -#define T1CMP1 0x10 -#define T1CMP0 0x08 -#define T1MODE 0x04 -#define T1CAP1 0x02 -#define T1CAP0 0x01 - -__sfr __at (0xE6) T1CCTL1; -/*Bits defined in T1CCTL0 */ -__sfr __at (0xE7) T1CCTL2; -/*Bits defined in T1CCTL0 */ -__sfr __at (0xE8) IRCON2; -/*IRCON2 bits*/ -#define WDTIF 0x10 -#define P1IF 0x08 -#define UTX1IF 0x04 -#define UTX0IF 0x02 -#define P2IF 0x01 -/* IRCON 2 */ -/*__sbit __at (0xEF) IRCON2_P1_7 ; -__sbit __at (0xEE) IRCON2_P1_6 ; -__sbit __at (0xED) IRCON2_P1_5 ;*/ -__sbit __at (0xEC) IRCON2_WDTIF ; -__sbit __at (0xEB) IRCON2_P1IF ; -__sbit __at (0xEA) IRCON2_UTX1IF ; -__sbit __at (0xE9) IRCON2_UTX0IF ; -__sbit __at (0xE8) IRCON2_P2IF; - - -__sfr __at (0xE9) RFIF; -/*RFIF bits*/ -#define IRQ_RREG_ON 0x80 -#define IRQ_TXDONE 0x40 -#define IRQ_FIFOP 0x20 -#define IRQ_SFD 0x10 -#define IRQ_CCA 0x08 -#define IRQ_CSP_WT 0x04 -#define IRQ_CSP_STOP 0x02 -#define IRQ_CSP_INT 0x01 - -__sfr __at (0xEA) T4CNT; -__sfr __at (0xEB) T4CTL; -/*T4CTL bits*/ -#define T4DIV2 0x80 -#define T4DIV1 0x40 -#define T4DIV0 0x20 -#define T4START 0x10 -#define T4OVFIM 0x08 -#define T4CLR 0x04 -#define T4MODE1 0x02 -#define T4MODE0 0x01 - -__sfr __at (0xEC) T4CCTL0; -/*T4CCTL0 bits*/ -#define T4IM 0x40 -#define T4CMP2 0x20 -#define T4CMP1 0x10 -#define T4CMP0 0x08 -#define T4MODE 0x04 -#define T4CAP1 0x02 -#define T4CAP0 0x01 - -__sfr __at (0xED) T4CC0; -__sfr __at (0xEE) T4CCTL1; -/*T4CCTL0 bits apply*/ -__sfr __at (0xEF) T4CC1; - -__sfr __at (0xF0) B ; -__sfr __at (0xF1) PERCFG; -/*PERCFG bits*/ -#define T1CFG 0x40 -#define T3CFG 0x20 -#define T4CFG 0x10 -#define U1CFG 0x02 -#define U0CFG 0x01 - -__sfr __at (0xF2) ADCCFG; -/*ADCCFG bits*/ -#define ADC7EN 0x80 -#define ADC6EN 0x40 -#define ADC5EN 0x20 -#define ADC4EN 0x10 -#define ADC3EN 0x08 -#define ADC2EN 0x04 -#define ADC1EN 0x02 -#define ADC0EN 0x01 - -__sfr __at (0xF3) P0SEL; -__sfr __at (0xF4) P1SEL; -__sfr __at (0xF5) P2SEL; -/*P2SEL bits*/ -#define PRI3P1 0x40 -#define PRI2P1 0x20 -#define PRI1P1 0x10 -#define PRI0P1 0x08 -#define SELP2_4 0x04 -#define SELP2_3 0x02 -#define SELP2_0 0x01 - -__sfr __at (0xF6) P1INP; - -__sfr __at (0xF7) P2INP; -/*P2INP bits*/ -#define PDUP2 0x80 -#define PDUP1 0x40 -#define PDUP0 0x20 -#define MDP2_4 0x10 -#define MDP2_3 0x08 -#define MDP2_2 0x04 -#define MDP2_1 0x02 -#define MDP2_0 0x01 - -__sfr __at (0xF8) U1CSR; -__sfr __at (0xF9) U1BUF; -__sfr __at (0xFA) U1BAUD; -__sfr __at (0xFB) U1UCR; -__sfr __at (0xFC) U1GCR; -__sfr __at (0xFD) P0DIR; -__sfr __at (0xFE) P1DIR; - -__sfr __at (0xFF) P2DIR; -/*P2DIR bits*/ -#define PRI1P0 0x80 -#define PRI0P0 0x40 -#define DIRP2_4 0x10 -#define DIRP2_3 0x08 -#define DIRP2_2 0x04 -#define DIRP2_1 0x02 -#define DIRP2_0 0x01 - -/* IEN0 */ -/*__sbit __at (0xA8) EA ; -__sbit __at (0x99) TI ; -__sbit __at (0x9A) RB8 ; -__sbit __at (0x9B) TB8 ; -__sbit __at (0x9C) REN ; -__sbit __at (0x9D) SM2 ; -__sbit __at (0x9E) SM1 ; -__sbit __at (0x9F) SM0 ;*/ - - - -/* Interrupt numbers: address = (number * 8) + 3 */ -/*#undef IE0_VECTOR -#undef TF0_VECTOR -#undef IE1_VECTOR -#undef TF1_VECTOR -#undef SI0_VECTOR*/ - -/* CC2430 interrupt vectors */ -#define RFERR_VECTOR 0 -#define ADC_VECTOR 1 -#define URX0_VECTOR 2 -#define URX1_VECTOR 3 -#define ENC_VECTOR 4 -#define ST_VECTOR 5 -#define P2INT_VECTOR 6 -#define UTX0_VECTOR 7 -#define DMA_VECTOR 8 -#define T1_VECTOR 9 -#define T2_VECTOR 10 -#define T3_VECTOR 11 -#define T4_VECTOR 12 -#define P0INT_VECTOR 13 -#define UTX1_VECTOR 14 -#define P1INT_VECTOR 15 -#define RF_VECTOR 16 -#define WDT_VECTOR 17 - -/* RF control registers*/ -__xdata __at (0xDF02) unsigned char MDMCTRL0H; -__xdata __at (0xDF03) unsigned char MDMCTRL0L; -__xdata __at (0xDF04) unsigned char MDMCTRL1H; -__xdata __at (0xDF05) unsigned char MDMCTRL1L; -__xdata __at (0xDF06) unsigned char RSSIH; -__xdata __at (0xDF07) unsigned char RSSIL; -__xdata __at (0xDF08) unsigned char SYNCWORDH; -__xdata __at (0xDF09) unsigned char SYNCWORDL; -__xdata __at (0xDF0A) unsigned char TXCTRLH; -__xdata __at (0xDF0B) unsigned char TXCTRLL; -__xdata __at (0xDF0C) unsigned char RXCTRL0H; -__xdata __at (0xDF0D) unsigned char RXCTRL0L; -__xdata __at (0xDF0E) unsigned char RXCTRL1H; -__xdata __at (0xDF0F) unsigned char RXCTRL1L; -__xdata __at (0xDF10) unsigned char FSCTRLH; -__xdata __at (0xDF11) unsigned char FSCTRLL; -__xdata __at (0xDF12) unsigned char CSPX; -__xdata __at (0xDF13) unsigned char CSPY; -__xdata __at (0xDF14) unsigned char CSPZ; -__xdata __at (0xDF15) unsigned char CSPCTRL; -__xdata __at (0xDF16) unsigned char CSPT; -__xdata __at (0xDF17) unsigned char RFPWR; -#define ADI_RADIO_PD 0x10 -#define RREG_RADIO_PD 0x08 -#define RREG_DELAY_MASK 0x07 - -__xdata __at (0xDF20) unsigned char FSMTCH; -__xdata __at (0xDF21) unsigned char FSMTCL; -__xdata __at (0xDF22) unsigned char MANANDH; -__xdata __at (0xDF23) unsigned char MANANDL; -__xdata __at (0xDF24) unsigned char MANORH; -__xdata __at (0xDF25) unsigned char MANORL; -__xdata __at (0xDF26) unsigned char AGCCTRLH; -__xdata __at (0xDF27) unsigned char AGCCTRLL; - -__xdata __at (0xDF39) unsigned char FSMSTATE; -__xdata __at (0xDF3A) unsigned char ADCTSTH; -__xdata __at (0xDF3B) unsigned char ADCTSTL; -__xdata __at (0xDF3C) unsigned char DACTSTH; -__xdata __at (0xDF3D) unsigned char DACTSTL; - -__xdata __at (0xDF43) unsigned char IEEE_ADDR0; -__xdata __at (0xDF44) unsigned char IEEE_ADDR1; -__xdata __at (0xDF45) unsigned char IEEE_ADDR2; -__xdata __at (0xDF46) unsigned char IEEE_ADDR3; -__xdata __at (0xDF47) unsigned char IEEE_ADDR4; -__xdata __at (0xDF48) unsigned char IEEE_ADDR5; -__xdata __at (0xDF49) unsigned char IEEE_ADDR6; -__xdata __at (0xDF4A) unsigned char IEEE_ADDR7; -__xdata __at (0xDF4B) unsigned char PANIDH; -__xdata __at (0xDF4C) unsigned char PANIDL; -__xdata __at (0xDF4D) unsigned char SHORTADDRH; -__xdata __at (0xDF4E) unsigned char SHORTADDRL; -__xdata __at (0xDF4F) unsigned char IOCFG0; -__xdata __at (0xDF50) unsigned char IOCFG1; -__xdata __at (0xDF51) unsigned char IOCFG2; -__xdata __at (0xDF52) unsigned char IOCFG3; -__xdata __at (0xDF53) unsigned char RXFIFOCNT; -__xdata __at (0xDF54) unsigned char FSMTC1; -#define ABORTRX_ON_SRXON 0x20 -#define RX_INTERRUPTED 0x10 -#define AUTO_TX2RX_OFF 0x08 -#define RX2RX_TIME_OFF 0x04 -#define PENDING_OR 0x02 -#define ACCEPT_ACKPKT 0x01 - -__xdata __at (0xDF60) unsigned char CHVER; -__xdata __at (0xDF61) unsigned char CHIPID; -__xdata __at (0xDF62) unsigned char RFSTATUS; -#define TX_ACTIVE 0x10 -#define FIFO 0x08 -#define FIFOP 0x04 -#define SFD 0x02 -#define CCA 0x01 - -__xdata __at (0xDFC1) unsigned char U0BUF_SHADOW; - -__xdata __at (0xDFD9) unsigned char RFD_SHADOW; - -__xdata __at (0xDFF9) unsigned char U1BUF_SHADOW; - -__xdata __at (0xDFBA) unsigned int ADC_SHADOW; - -#endif /*REG_CC2430*/ diff --git a/cpu/cc2430/dev/cc2430_rf.c b/cpu/cc2430/dev/cc2430_rf.c deleted file mode 100644 index ac897c28c..000000000 --- a/cpu/cc2430/dev/cc2430_rf.c +++ /dev/null @@ -1,722 +0,0 @@ -/** - * \file - * CC2430 RF driver - * \author - * Zach Shelby (Original) - * George Oikonomou - - * (port to the netstack API, hexdump output, RX FIFO overflow fixes - * code cleanup, ...) - * - * bankable code for cc2430 rf driver. this code can be placed in any bank. - * - */ - -#include - -#include "contiki.h" -#include "dev/radio.h" -#include "dev/cc2430_rf.h" -#include "cc2430_sfr.h" -#include "sys/clock.h" -#include "sys/rtimer.h" - -#include "net/packetbuf.h" -#include "net/rime/rimestats.h" -#include "net/netstack.h" - -#define CC2430_RF_TX_POWER_RECOMMENDED 0x5F -#ifdef CC2430_RF_CONF_TX_POWER -#define CC2430_RF_TX_POWER CC2430_RF_CONF_TX_POWER -#else -#define CC2430_RF_TX_POWER CC2430_RF_TX_POWER_RECOMMENDED -#endif - -#ifdef CC2430_RF_CONF_CHANNEL -#define CC2430_RF_CHANNEL CC2430_RF_CONF_CHANNEL -#else -#define CC2430_RF_CHANNEL 18 -#endif /* CC2430_RF_CONF_CHANNEL */ -#define CC2430_CHANNEL_MIN 11 -#define CC2430_CHANNEL_MAX 26 - -#ifdef CC2430_RF_CONF_AUTOACK -#define CC2430_RF_AUTOACK CC2430_RF_CONF_AUTOACK -#else -#define CC2430_RF_AUTOACK 1 -#endif - -#ifndef CC2430_CONF_CHECKSUM -#define CC2430_CONF_CHECKSUM 0 -#endif /* CC2420_CONF_CHECKSUM */ - -#if CC2430_CONF_CHECKSUM -#include "lib/crc16.h" -#define CHECKSUM_LEN 2 -#else -#define CHECKSUM_LEN 2 -#endif /* CC2430_CONF_CHECKSUM */ -#if DEBUG_LEDS -/* moved leds code to BANK1 to make space for cc2430_rf_process in HOME */ -/* can't call code in BANK1 from alternate banks unless it is marked with __banked */ -#include "dev/leds.h" -#define RF_RX_LED_ON() leds_on(LEDS_RED); -#define RF_RX_LED_OFF() leds_off(LEDS_RED); -#define RF_TX_LED_ON() leds_on(LEDS_GREEN); -#define RF_TX_LED_OFF() leds_off(LEDS_GREEN); -#else -#define RF_RX_LED_ON() -#define RF_RX_LED_OFF() -#define RF_TX_LED_ON() -#define RF_TX_LED_OFF() -#endif -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) do {} while (0) -#endif - -/* rf_flags bits */ -#define RX_ACTIVE 0x80 -#define TX_ACK 0x40 -#define TX_ON_AIR 0x20 -#define WAS_OFF 0x10 -#define INITIALISED 0x01 - -#define RX_NO_DMA -/* Bits of the last byte in the RX FIFO */ -#define CRC_BIT_MASK 0x80 -#define LQI_BIT_MASK 0x7F - -/* 192 ms, radio off -> on interval */ -#define ONOFF_TIME ((RTIMER_ARCH_SECOND / 3125) + 4) - -#if CC2430_RF_CONF_HEXDUMP -#include "uart1.h" -static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; /* Snif */ -#endif - -#ifdef HAVE_RF_ERROR -uint8_t rf_error = 0; -#endif - -/*---------------------------------------------------------------------------*/ -#if !NETSTACK_CONF_SHORTCUTS -PROCESS(cc2430_rf_process, "CC2430 RF driver"); -#endif -/*---------------------------------------------------------------------------*/ -static uint8_t CC_AT_DATA rf_flags; -static uint8_t rf_channel; - -static int on(void); /* prepare() needs our prototype */ -static int off(void); /* transmit() needs our prototype */ -static int channel_clear(void); /* transmit() needs our prototype */ -/*---------------------------------------------------------------------------*/ -/** - * Execute a single CSP command. - * - * \param command command to execute - * - */ -void -cc2430_rf_command(uint8_t command) -{ - if(command >= 0xE0) { /*immediate strobe*/ - uint8_t fifo_count; - switch (command) { /*hardware bug workaround*/ - case ISRFOFF: - case ISRXON: - case ISTXON: - fifo_count = RXFIFOCNT; - RFST = command; - clock_delay_usec(2); - if(fifo_count != RXFIFOCNT) { - RFST = ISFLUSHRX; - RFST = ISFLUSHRX; - } - break; - - default: - RFST = command; - } - } else if(command == SSTART) { - RFIF &= ~IRQ_CSP_STOP; /*clear IRQ flag*/ - RFST = SSTOP; /*make sure there is a stop in the end*/ - RFST = ISSTART; /*start execution*/ - while((RFIF & IRQ_CSP_STOP) == 0); - } else { - RFST = command; /*write command*/ - } -} -/*---------------------------------------------------------------------------*/ -static void -flush_rx() -{ - cc2430_rf_command(ISFLUSHRX); - cc2430_rf_command(ISFLUSHRX); - -#if !NETSTACK_CONF_SHORTCUTS - IEN2 |= RFIE; -#endif -#if CC2430_RFERR_INTERRUPT - IEN0 |= RFERRIE; -#endif - - RFIF &= ~IRQ_FIFOP; -} -/*---------------------------------------------------------------------------*/ -/** - * Select RF channel. - * - * \param channel channel number to select - * - * \return channel value or negative (invalid channel number) - */ - - /* channel freqdiv = (2048 + FSCTRL(9:0)) / 4 - freq = (2048 + FSCTRL(9:0)) MHz */ - -int8_t -cc2430_rf_channel_set(uint8_t channel) -{ - uint16_t freq; - - if((channel < 11) || (channel > 26)) { - return -1; - } - - cc2430_rf_command(ISSTOP); /*make sure CSP is not running*/ - cc2430_rf_command(ISRFOFF); - /* Channel values: 11-26 */ - freq = (uint16_t) channel - 11; - freq *= 5; /*channel spacing*/ - freq += 357; /*correct channel range*/ - freq |= 0x4000; /*LOCK_THR = 1*/ - FSCTRLH = (freq >> 8); - FSCTRLL = (uint8_t)freq; - - cc2430_rf_command(ISRXON); - - rf_channel = channel; - - return (int8_t) channel; -} -/*---------------------------------------------------------------------------*/ -uint8_t -cc2430_rf_channel_get() -{ - return rf_channel; -} -/*---------------------------------------------------------------------------*/ -/** - * Select RF transmit power. - * - * \param new_power new power level - * - * \return new level - */ -uint8_t -cc2430_rf_power_set(uint8_t new_power) -{ - /* Set transmitter power */ - TXCTRLL = new_power; - - return TXCTRLL; -} -/*---------------------------------------------------------------------------*/ -#if 0 /* unused */ -/** - * Enable RF transmitter. - * - * - * \return pdTRUE - * \return pdFALSE bus not free - */ -int -cc2430_rf_tx_enable(void) -{ - DMAARM = 0x80 + (1 << 0); /*ABORT + channel bit*/ - - return 1; -} -#endif -/*---------------------------------------------------------------------------*/ -/** - * Set MAC addresses - * - * \param pan The PAN address to set - * \param addr The short address to set - * \param ieee_addr The 64-bit IEEE address to set - */ -void -cc2430_rf_set_addr(unsigned pan, unsigned addr, const uint8_t *ieee_addr) -{ - uint8_t f; - __xdata unsigned char *ptr; - - PANIDH = pan >> 8; - PANIDL = pan & 0xff; - - SHORTADDRH = addr >> 8; - SHORTADDRL = addr & 0xff; - - if(ieee_addr != NULL) { - ptr = &IEEE_ADDR7; - /* LSB first, MSB last for 802.15.4 addresses in CC2420 */ - for(f = 0; f < 8; f++) { - *ptr-- = ieee_addr[f]; - } - } -} -#if 0 /* currently unused */ -/*---------------------------------------------------------------------------*/ -/** - * Channel energy detect. - * - * Coordinator use this function detect best channel for PAN-network. - * \return RSSI-energy level dBm. - * \return 0 operation failed. - */ - -int8_t -cc2430_rf_analyze_rssi(void) -{ - int8_t retval = -128; - /*pause_us(128);*/ - - retval = (int8_t)RSSIL; - retval -= 45; - return retval; -} -#endif /* currently unused */ -/*---------------------------------------------------------------------------*/ -/** - * Send ACK. - * - *\param pending set up pending flag if pending > 0. - */ -void -cc2430_rf_send_ack(uint8_t pending) -{ - if(pending) { - cc2430_rf_command(ISACKPEND); - } else { - cc2430_rf_command(ISACK); - } -} -/*---------------------------------------------------------------------------*/ -/* Netstack API radio driver functions */ -/*---------------------------------------------------------------------------*/ -static int -init(void) -{ - if(rf_flags & INITIALISED) { - return 0; - } - - PRINTF("cc2430_rf_init called\n"); - - RFPWR &= ~RREG_RADIO_PD; /*make sure it's powered*/ - while((RFPWR & ADI_RADIO_PD) == 1); - while((RFIF & IRQ_RREG_ON) == 0); /*wait for power up*/ - SLEEP &= ~OSC_PD; /*Osc on*/ - while((SLEEP & XOSC_STB) == 0); /*wait for power up*/ - - rf_flags = 0; - - FSMTC1 = 1; /*don't abort reception, if enable called, accept ack, auto rx after tx*/ - - MDMCTRL0H = 0x0A; /* Generic client, standard hysteresis, decoder on 0x0a */ - MDMCTRL0L = 0xE2; /* automatic CRC, standard CCA and preamble 0xE2 */ -#if CC2430_RF_AUTOACK - MDMCTRL0L |= 0x10; -#endif - - MDMCTRL1H = 0x30; /* Defaults */ - MDMCTRL1L = 0x0; - - RXCTRL0H = 0x32; /* RX tuning optimized */ - RXCTRL0L = 0xf5; - - cc2430_rf_channel_set(CC2430_RF_CHANNEL); - cc2430_rf_command(ISFLUSHTX); - cc2430_rf_command(ISFLUSHRX); - - /* Temporary values, main() will sort this out later on */ - cc2430_rf_set_addr(0xffff, 0x0000, NULL); - - RFIM = IRQ_FIFOP; - RFIF &= ~(IRQ_FIFOP); - - S1CON &= ~(RFIF_0 | RFIF_1); -#if !NETSTACK_CONF_SHORTCUTS - IEN2 |= RFIE; -#endif - - /* If contiki-conf.h turns on the RFERR interrupt, enable it here */ -#if CC2430_RFERR_INTERRUPT - IEN0 |= RFERRIE; -#endif - - RF_TX_LED_OFF(); - RF_RX_LED_OFF(); - - rf_flags |= INITIALISED; - -#if !NETSTACK_CONF_SHORTCUTS - process_start(&cc2430_rf_process, NULL); -#endif - - cc2430_rf_power_set(CC2430_RF_TX_POWER); - - return 1; -} -/*---------------------------------------------------------------------------*/ -static int -prepare(const void *payload, unsigned short payload_len) -{ - uint8_t i; - /* - * When we transmit in very quick bursts, make sure previous transmission - * is not still in progress before re-writing in the TX FIFO - */ - while(RFSTATUS & TX_ACTIVE); - - if(rf_flags & TX_ACK) { - return -1; - } - - if((rf_flags & RX_ACTIVE) == 0) { - on(); - } - - PRINTF("cc2430_rf: sending %u byte payload\n", payload_len); - - cc2430_rf_command(ISFLUSHTX); - PRINTF("cc2430_rf: data = "); - /* Send the phy length byte first */ - RFD = payload_len + CHECKSUM_LEN; /* Payload plus FCS */ - PRINTF("(%d)", payload_len + CHECKSUM_LEN); - for(i = 0; i < payload_len; i++) { - RFD = ((unsigned char *)(payload))[i]; - PRINTF("%02X", ((unsigned char *)(payload))[i]); - } - PRINTF("\n"); - - /* Leave space for the FCS */ - RFD = 0; - RFD = 0; - - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -transmit(unsigned short transmit_len) -{ - uint8_t counter; - int ret = RADIO_TX_ERR; - - if(!(rf_flags & RX_ACTIVE)) { - on(); - rf_flags |= WAS_OFF; - } - - if(channel_clear() == CC2430_CCA_BUSY) { - RIMESTATS_ADD(contentiondrop); - return RADIO_TX_COLLISION; - } - - /* - * prepare() double checked that TX_ACTIVE is low. If SFD is high we are - * receiving. Abort transmission and bail out with RADIO_TX_COLLISION - */ - if(RFSTATUS & SFD) { - RIMESTATS_ADD(contentiondrop); - return RADIO_TX_COLLISION; - } - - /* Start the transmission */ - ENERGEST_OFF(ENERGEST_TYPE_LISTEN); - ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); - - cc2430_rf_command(ISTXON); - counter = 0; - while(!(RFSTATUS & TX_ACTIVE) && (counter++ < 3)) { - clock_delay_usec(6); - } - - if(!(RFSTATUS & TX_ACTIVE)) { - PRINTF("cc2430_rf: TX never active.\n"); - cc2430_rf_command(ISFLUSHTX); - ret = RADIO_TX_ERR; - } else { - /* Wait for the transmission to finish */ - while(RFSTATUS & TX_ACTIVE); - RF_RX_LED_OFF(); - RF_TX_LED_ON(); - ret = RADIO_TX_OK; - // rf_flags |= TX_ON_AIR; - } - ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); - ENERGEST_ON(ENERGEST_TYPE_LISTEN); - - if(rf_flags & WAS_OFF) { - off(); - } - - RIMESTATS_ADD(lltx); - /* OK, sent. We are now ready to send more */ - return ret; -} -/*---------------------------------------------------------------------------*/ -static int -send(void *payload, unsigned short payload_len) -{ - prepare(payload, payload_len); - return transmit(payload_len); -} -/*---------------------------------------------------------------------------*/ -static int -read(void *buf, unsigned short bufsize) -{ - uint8_t i; - uint8_t len; - uint8_t crc_corr; - int8_t rssi; -#if CC2420_CONF_CHECKSUM - uint16_t checksum; -#endif /* CC2420_CONF_CHECKSUM */ - - /* Don't interrupt us while emptying the FIFO */ -#if !NETSTACK_CONF_SHORTCUTS - IEN2 &= ~RFIE; -#endif -#if CC2430_RFERR_INTERRUPT - IEN0 &= ~RFERRIE; -#endif - - /* RX interrupt polled the cc2430_rf_process, now read the RX FIFO */ - /* Check the length */ - len = RFD; - - /* Check for validity */ - if(len > CC2430_MAX_PACKET_LEN) { - /* Oops, we must be out of sync. */ - PRINTF("error: bad sync\n"); - - RIMESTATS_ADD(badsynch); - flush_rx(); - return 0; - } - - if(len <= CC2430_MIN_PACKET_LEN) { - PRINTF("error: too short\n"); - - RIMESTATS_ADD(tooshort); - flush_rx(); - return 0; - } - - if(len - CHECKSUM_LEN > bufsize) { - PRINTF("error: too long\n"); - - RIMESTATS_ADD(toolong); - flush_rx(); - return 0; - } - -#if CC2430_RF_CONF_HEXDUMP - /* If we reach here, chances are the FIFO is holding a valid frame */ - uart1_writeb(magic[0]); - uart1_writeb(magic[1]); - uart1_writeb(magic[2]); - uart1_writeb(magic[3]); - uart1_writeb(len); -#endif - - PRINTF("cc2430_rf: read = "); - PRINTF("(%d)", len); - len -= CHECKSUM_LEN; - for(i = 0; i < len; ++i) { - ((unsigned char *)(buf))[i] = RFD; -#if CC2430_RF_CONF_HEXDUMP - uart1_writeb(((unsigned char *)(buf))[i]); -#endif - PRINTF("%02X", ((unsigned char *)(buf))[i]); - } - PRINTF("\n"); - -#if CC2430_CONF_CHECKSUM - /* Deal with the checksum */ - checksum = RFD * 256; - checksum += RFD; -#endif /* CC2430_CONF_CHECKSUM */ - - /* Read the RSSI and CRC/Corr bytes */ - rssi = ((int8_t) RFD) - 45; - crc_corr = RFD; - -#if CC2430_RF_CONF_HEXDUMP - uart1_writeb(rssi); - uart1_writeb(crc_corr); -#endif - - /* MS bit CRC OK/Not OK, 7 LS Bits, Correlation value */ - if(crc_corr & CRC_BIT_MASK) { - packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi); - packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, crc_corr & LQI_BIT_MASK); - RIMESTATS_ADD(llrx); - } else { - RIMESTATS_ADD(badcrc); - flush_rx(); - return 0; - } - - /* If FIFOP==1 and FIFO==0 then we had a FIFO overflow at some point. */ - if((RFSTATUS & (FIFO | FIFOP)) == FIFOP) { - /* - * If we reach here means that there might be more intact packets in the - * FIFO despite the overflow. This can happen with bursts of small packets. - * - * Only flush if the FIFO is actually empty. If not, then next pass we will - * pick up one more packet or flush due to an error. - */ - if(!RXFIFOCNT) { - flush_rx(); - } - } - - RF_RX_LED_OFF(); - -#if !NETSTACK_CONF_SHORTCUTS - IEN2 |= RFIE; -#endif -#if CC2430_RFERR_INTERRUPT - IEN0 |= RFERRIE; -#endif - - RFIF &= ~IRQ_FIFOP; - - return (len); -} -/*---------------------------------------------------------------------------*/ -static int -channel_clear(void) -{ - if(!(RFSTATUS & CCA)) { - return CC2430_CCA_BUSY; - } - return CC2430_CCA_CLEAR; -} -/*---------------------------------------------------------------------------*/ -static int -receiving_packet(void) -{ - /* - * SFD high while transmitting and receiving. - * TX_ACTIVE high only when transmitting - * - * RFSTATUS & (TX_ACTIVE | SFD) == SFD <=> receiving - */ - return (RFSTATUS & (TX_ACTIVE | SFD) == SFD); -} -/*---------------------------------------------------------------------------*/ -static int -pending_packet(void) -{ - return (RFSTATUS & FIFOP); -} -/*---------------------------------------------------------------------------*/ -/** - * Enable RF receiver. - * - * - * \return pdTRUE - * \return pdFALSE bus not free - */ -static int -on(void) -{ - rtimer_clock_t t0; - PRINTF("cc2430_rf_rx_enable called\n"); - if(!(rf_flags & RX_ACTIVE)) { - t0 = RTIMER_NOW(); - rf_flags |= RX_ACTIVE; - IOCFG0 = 0x7f; /* Set the FIFOP threshold 127 */ - RSSIH = 0xd2; /* -84dbm = 0xd2 default, 0xe0 -70 dbm */ - - RFPWR &= ~RREG_RADIO_PD; /* make sure it's powered */ - while((RFIF & IRQ_RREG_ON) == 0); /* wait for power up */ - - /* Make sure the RREG On Interrupt Flag is 0 next time we get called */ - RFIF &= ~IRQ_RREG_ON; - - cc2430_rf_command(ISRXON); - cc2430_rf_command(ISFLUSHRX); - while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ONOFF_TIME)); - - } - PRINTF("cc2430_rf_rx_enable done\n"); - ENERGEST_ON(ENERGEST_TYPE_LISTEN); - return 1; -} -/*---------------------------------------------------------------------------*/ -/** - * Disable RF receiver. - * - * - * \return pdTRUE - * \return pdFALSE bus not free - */ - -static int -off(void) -{ - cc2430_rf_command(ISSTOP); /* make sure CSP is not running */ - cc2430_rf_command(ISRFOFF); - - RFPWR |= RREG_RADIO_PD; /* RF powerdown */ - - /* Clear the RREG On Interrupt Flag */ - RFIF &= ~IRQ_RREG_ON; - - rf_flags &= ~RX_ACTIVE; - rf_flags &= ~WAS_OFF; - ENERGEST_OFF(ENERGEST_TYPE_LISTEN); - return 1; -} -/*---------------------------------------------------------------------------*/ -const struct radio_driver cc2430_rf_driver = { - init, - prepare, - transmit, - send, - read, - channel_clear, - receiving_packet, - pending_packet, - on, - off, -}; -/*---------------------------------------------------------------------------*/ -#if !NETSTACK_CONF_SHORTCUTS -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(cc2430_rf_process, ev, data) -{ - int len; - PROCESS_BEGIN(); - while(1) { - PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); - - packetbuf_clear(); - len = read(packetbuf_dataptr(), PACKETBUF_SIZE); - if(len > 0) { - packetbuf_set_datalen(len); - NETSTACK_RDC.input(); - } - } - - PROCESS_END(); -} -#endif -/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/cc2430_rf.h b/cpu/cc2430/dev/cc2430_rf.h deleted file mode 100644 index 83527d4ba..000000000 --- a/cpu/cc2430/dev/cc2430_rf.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * \file - * CC2430 RF driver header file - * \author - * Zach Shelby - */ - -#ifndef CC2430_RF_H_ -#define CC2430_RF_H_ - -#include "contiki.h" -#include "dev/radio.h" -#include "cc2430_sfr.h" -#if HAVE_RF_DMA -#include "dev/dma.h" -#endif - -/* Constants */ -typedef enum rf_address_mode_t { - RF_DECODER_NONE = 0, - RF_DECODER_COORDINATOR, - RF_SOFTACK_MONITOR, - RF_MONITOR, - RF_SOFTACK_CLIENT, - RF_DECODER_ON -} rf_address_mode_t; - -/*CSP command set*/ -#define SSTOP 0xDF -/*this is not a real command but a way of having rf_command - wait until the script is done*/ -#define SSTART 0xDE - -#define SNOP 0xC0 -#define STXCALN 0xC1 -#define SRXON 0xC2 -#define STXON 0xC3 -#define STXONCCA 0xC4 -#define SRFOFF 0xC5 -#define SFLUSHRX 0xC6 -#define SFLUSHTX 0xC7 -#define SACK 0xC8 -#define SACKPEND 0xC9 - -#define ISTXCALN 0xE1 -#define ISRXON 0xE2 -#define ISTXON 0xE3 -#define ISTXONCCA 0xE4 -#define ISRFOFF 0xE5 -#define ISFLUSHRX 0xE6 -#define ISFLUSHTX 0xE7 -#define ISACK 0xE8 -#define ISACKPEND 0xE9 - -#define ISSTOP 0xFF -#define ISSTART 0xFE - -#define MAC_IFS (1200/128) - -#define CC2430_MAX_PACKET_LEN 127 -#define CC2430_MIN_PACKET_LEN 4 - -#define CC2430_CCA_CLEAR 1 -#define CC2430_CCA_BUSY 0 - -#ifdef CC2430_CONF_RFERR_INTERRUPT -#define CC2430_RFERR_INTERRUPT CC2430_CONF_RFERR_INTERRUPT -#else -#define CC2430_RFERR_INTERRUPT 0 -#endif - -extern const struct radio_driver cc2430_rf_driver; - -void cc2430_rf_command(uint8_t command); -int8_t cc2430_rf_channel_set(uint8_t channel); -uint8_t cc2430_rf_channel_get(); -uint8_t cc2430_rf_power_set(uint8_t new_power); -void cc2430_rf_set_addr(unsigned pan, unsigned addr, const uint8_t *ieee_addr); - -#if !NETSTACK_CONF_SHORTCUTS -extern void cc2430_rf_ISR(void) __interrupt(RF_VECTOR); -#endif -#if CC2430_RFERR_INTERRUPT -extern void cc2430_rf_error_ISR(void) __interrupt(RFERR_VECTOR); -#endif - -#ifdef HAVE_RF_DMA -void rf_dma_callback_isr(void); -#endif - -#endif /* CC2430_RF_H_ */ diff --git a/cpu/cc2430/dev/cc2430_rf_intr.c b/cpu/cc2430/dev/cc2430_rf_intr.c deleted file mode 100644 index 85b9879c9..000000000 --- a/cpu/cc2430/dev/cc2430_rf_intr.c +++ /dev/null @@ -1,112 +0,0 @@ -/** - * \file - * CC2430 RF driver - * \author - * Zach Shelby (Original) - * George Oikonomou - - * (recent updates for the contiki cc2430 port) - * - * Non-bankable code for cc2430 rf driver. - * Interrupt routines must be placed into the HOME bank. - * - */ - -#include - -#include "contiki.h" -#include "dev/radio.h" -#include "dev/cc2430_rf.h" -#include "cc2430_sfr.h" -#ifdef RF_LED_ENABLE -#include "dev/leds.h" -#endif -#include "sys/clock.h" - -#include "net/packetbuf.h" -#include "net/rime/rimestats.h" -#include "net/netstack.h" -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) do {} while (0) -#endif - -#ifdef RF_LED_ENABLE -#define RF_RX_LED_ON() leds_on(LEDS_RED); -#define RF_RX_LED_OFF() leds_off(LEDS_RED); -#define RF_TX_LED_ON() leds_on(LEDS_GREEN); -#define RF_TX_LED_OFF() leds_off(LEDS_GREEN); -#else -#define RF_RX_LED_ON() -#define RF_RX_LED_OFF() -#define RF_TX_LED_ON() -#define RF_TX_LED_OFF() -#endif - -#ifdef HAVE_RF_ERROR -uint8_t rf_error = 0; -#endif - -PROCESS_NAME(cc2430_rf_process); - -#if !NETSTACK_CONF_SHORTCUTS -/*---------------------------------------------------------------------------*/ -/** - * RF interrupt service routine. - * - */ -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -cc2430_rf_ISR(void) __interrupt(RF_VECTOR) -{ - EA = 0; - ENERGEST_ON(ENERGEST_TYPE_IRQ); - /* - * We only vector here if RFSTATUS.FIFOP goes high. - * Just double check the flag. - */ - if(RFIF & IRQ_FIFOP) { - RF_RX_LED_ON(); - /* Poll the RF process which calls cc2430_rf_read() */ - process_poll(&cc2430_rf_process); - } - S1CON &= ~(RFIF_0 | RFIF_1); - - ENERGEST_OFF(ENERGEST_TYPE_IRQ); - EA = 1; -} -#pragma restore -#endif -/*---------------------------------------------------------------------------*/ -#if CC2430_RFERR_INTERRUPT -/** - * RF error interrupt service routine. - * Turned off by default, can be turned on in contiki-conf.h - */ -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -cc2430_rf_error_ISR(void) __interrupt(RFERR_VECTOR) -{ - EA = 0; - TCON_RFERRIF = 0; -#ifdef HAVE_RF_ERROR - rf_error = 254; -#endif - cc2430_rf_command(ISRFOFF); - cc2430_rf_command(ISFLUSHRX); - cc2430_rf_command(ISFLUSHRX); - cc2430_rf_command(ISRXON); - RF_RX_LED_OFF(); - RF_TX_LED_OFF(); - EA = 1; -} -#pragma restore -#endif -/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/clock.c b/cpu/cc2430/dev/clock.c deleted file mode 100644 index c0b8f2c9d..000000000 --- a/cpu/cc2430/dev/clock.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2009, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Implementation of the clock functions for the cc243x - * \author - * Zach Shelby (zach@sensinode.com) - original - * George Oikonomou - - */ -#include "sys/clock.h" -#include "sys/etimer.h" -#include "cc2430_sfr.h" -#include "sys/energest.h" - -/* Sleep timer runs on the 32k RC osc. */ -/* One clock tick is 7.8 ms */ -#define TICK_VAL (32768/128) /* 256 */ -/*---------------------------------------------------------------------------*/ -#if CLOCK_CONF_STACK_FRIENDLY -volatile uint8_t sleep_flag; -#endif -/*---------------------------------------------------------------------------*/ -/* Used in sleep timer interrupt for calculating the next interrupt time */ -static unsigned long timer_value; -static volatile CC_AT_DATA clock_time_t count = 0; /* Uptime in ticks */ -static volatile CC_AT_DATA clock_time_t seconds = 0; /* Uptime in secs */ -/*---------------------------------------------------------------------------*/ -/** - * Each iteration is ~1.0xy usec, so this function delays for roughly len usec - */ -void -clock_delay_usec(uint16_t len) -{ - DISABLE_INTERRUPTS(); - while(len--) { - ASM(nop); ASM(nop); - ASM(nop); ASM(nop); - } - ENABLE_INTERRUPTS(); -} -/*---------------------------------------------------------------------------*/ -/** - * Wait for a multiple of ~8 ms (a tick) - */ -void -clock_wait(clock_time_t i) -{ - clock_time_t start; - - start = clock_time(); - while(clock_time() - start < (clock_time_t)i); -} -/*---------------------------------------------------------------------------*/ -CCIF clock_time_t -clock_time(void) -{ - return count; -} -/*---------------------------------------------------------------------------*/ -CCIF unsigned long -clock_seconds(void) -{ - return seconds; -} -/*---------------------------------------------------------------------------*/ -void -clock_init(void) -{ - CLKCON = OSC32K | TICKSPD2 | TICKSPD1; /* tickspeed 500 kHz for timers[1-4] */ - - /* Initialize tick value */ - timer_value = ST0; /* ST low bits [7:0] */ - timer_value += ((unsigned long int)ST1) << 8; /* middle bits [15:8] */ - timer_value += ((unsigned long int)ST2) << 16; /* high bits [23:16] */ - timer_value += TICK_VAL; /* Init value 256 */ - ST2 = (unsigned char)(timer_value >> 16); - ST1 = (unsigned char)(timer_value >> 8); - ST0 = (unsigned char)timer_value; - - IEN0_STIE = 1; /* IEN0.STIE acknowledge Sleep Timer Interrupt */ -} -/*---------------------------------------------------------------------------*/ -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -clock_ISR(void) __interrupt(ST_VECTOR) -{ - DISABLE_INTERRUPTS(); - ENERGEST_ON(ENERGEST_TYPE_IRQ); - - /* - * If the Sleep timer throws an interrupt while we are powering down to - * PM1, we need to abort the power down. Clear SLEEP.MODE, this will signal - * main() to abort the PM1 transition - */ - SLEEP &= 0xFC; - - /* - * Read value of the ST0:ST1:ST2, add TICK_VAL and write it back. - * Next interrupt occurs after the current time + TICK_VAL - */ - timer_value = ST0; - timer_value += ((unsigned long int)ST1) << 8; - timer_value += ((unsigned long int)ST2) << 16; - timer_value += TICK_VAL; - ST2 = (unsigned char)(timer_value >> 16); - ST1 = (unsigned char)(timer_value >> 8); - ST0 = (unsigned char)timer_value; - - ++count; - - /* Make sure the CLOCK_CONF_SECOND is a power of two, to ensure - that the modulo operation below becomes a logical and and not - an expensive divide. Algorithm from Wikipedia: - http://en.wikipedia.org/wiki/Power_of_two */ -#if (CLOCK_CONF_SECOND & (CLOCK_CONF_SECOND - 1)) != 0 -#error CLOCK_CONF_SECOND must be a power of two (i.e., 1, 2, 4, 8, 16, 32, 64, ...). -#error Change CLOCK_CONF_SECOND in contiki-conf.h. -#endif - if(count % CLOCK_CONF_SECOND == 0) { - ++seconds; - } - -#if CLOCK_CONF_STACK_FRIENDLY - sleep_flag = 1; -#else - if(etimer_pending() - && (etimer_next_expiration_time() - count - 1) > MAX_TICKS) { - etimer_request_poll(); - } -#endif - - IRCON_STIF = 0; - ENERGEST_OFF(ENERGEST_TYPE_IRQ); - ENABLE_INTERRUPTS(); -} -#pragma restore -/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/dma.c b/cpu/cc2430/dev/dma.c deleted file mode 100644 index 2c198acc3..000000000 --- a/cpu/cc2430/dev/dma.c +++ /dev/null @@ -1,69 +0,0 @@ -/** - * \file - * Driver for the cc2430 DMA controller. Can be assigned to any bank - * - * \author - * Original: Martti Huttunen - * Port: Zach Shelby - * Further Modifications: - * George Oikonomou - * - */ - -#include "contiki.h" -#include "dev/dma.h" -#include "cc2430_sfr.h" - -#if DMA_ON -struct dma_config dma_conf[DMA_CHANNEL_COUNT]; /* DMA Descriptors */ -struct process *dma_callback[DMA_CHANNEL_COUNT]; -/*---------------------------------------------------------------------------*/ -void -dma_init(void) -{ - uint16_t tmp_ptr; - - memset(dma_conf, 0, 4 * sizeof(dma_config_t)); - - for(tmp_ptr = 0; tmp_ptr < DMA_CHANNEL_COUNT; tmp_ptr++) { - dma_callback[tmp_ptr] = 0; - } - - /* The address of the descriptor for Channel 0 is configured separately */ - tmp_ptr = (uint16_t)&(dma_conf[0]); - DMA0CFGH = tmp_ptr >> 8; - DMA0CFGL = tmp_ptr; - - /* - * Descriptors for Channels 1-4 must be consecutive in RAM. - * We write the address of the 1st one to the register and the rest are - * derived by the SoC - */ -#if (DMA_CHANNEL_COUNT > 1) - tmp_ptr = (uint16_t)&(dma_conf[1]); - DMA1CFGH = tmp_ptr >> 8; - DMA1CFGL = tmp_ptr; -#endif - - IEN1_DMAIE = 1; /* Enable DMA interrupts */ -} -/*---------------------------------------------------------------------------*/ -/* - * Associate process p with DMA channel c. When a transfer on that channel - * completes, the ISR will poll this process. - */ -void -dma_associate_process(struct process *p, uint8_t c) -{ - if((!c) || (c >= DMA_CHANNEL_COUNT)) { - return; - } - - if(p) { - dma_conf[c].inc_prio |= 8; /* Enable interrupt generation */ - IEN1_DMAIE = 1; /* Make sure DMA interrupts are acknowledged */ - } - dma_callback[c] = p; -} -/*---------------------------------------------------------------------------*/ -#endif diff --git a/cpu/cc2430/dev/dma.h b/cpu/cc2430/dev/dma.h deleted file mode 100644 index 30060b40f..000000000 --- a/cpu/cc2430/dev/dma.h +++ /dev/null @@ -1,148 +0,0 @@ -/** - * \file - * Header file for the cc2430 DMA controller - * - * \author - * Original: Martti Huttunen - * Port: Zach Shelby - * Further Modifications: - * George Oikonomou - */ - -#ifndef __DMA_H -#define __DMA_H -#include "cc2430_sfr.h" - -/* DMA triggers */ -#define DMA_T_NONE 0 /* None, DMAREQ.DMAREQx bits start transfer */ -#define DMA_T_PREV 1 /* completion of previous channel */ -#define DMA_T_T1_CH0 2 /* Timer 1, compare, channel 0 */ -#define DMA_T_T1_CH1 3 /* Timer 1, compare, channel 1 */ -#define DMA_T_T1_CH2 4 /* Timer 1, compare, channel 2 */ -#define DMA_T_T2_COMP 5 /* Timer 2, compare */ -#define DMA_T_T2_OVFL 6 /* Timer 2, overflow */ -#define DMA_T_T3_CH0 7 /* Timer 3, compare, channel 0 */ -#define DMA_T_T3_CH1 8 /* Timer 3, compare, channel 1 */ -#define DMA_T_T4_CH0 9 /* Timer 4, compare, channel 0 */ -#define DMA_T_T4_CH1 10 /* Timer 4, compare, channel 1 */ -#define DMA_T_ST 11 /* Sleep Timer compare */ -#define DMA_T_IOC_0 12 /* Port 0 I/O pin input transition */ -#define DMA_T_IOC_1 13 /* Port 1 I/O pin input transition */ -#define DMA_T_URX0 14 /* USART0 RX complete */ -#define DMA_T_UTX0 15 /* USART0 TX complete */ -#define DMA_T_URX1 16 /* USART1 RX complete */ -#define DMA_T_UTX1 17 /* USART1 TX complete */ -#define DMA_T_FLASH 18 /* Flash data write complete */ -#define DMA_T_RADIO 19 /* RF packet byte received/transmit */ -#define DMA_T_ADC_CHALL 20 /* ADC end of a conversion in a sequence */ -#define DMA_T_ADC_CH11 21 /* ADC end of conversion channel 0 in sequence */ -#define DMA_T_ADC_CH21 22 /* ADC end of conversion channel 1 in sequence */ -#define DMA_T_ADC_CH32 23 /* ADC end of conversion channel 2 in sequence */ -#define DMA_T_ADC_CH42 24 /* ADC end of conversion channel 3 in sequence */ -#define DMA_T_ADC_CH53 25 /* ADC end of conversion channel 4 in sequence */ -#define DMA_T_ADC_CH63 26 /* ADC end of conversion channel 5 in sequence */ -#define DMA_T_ADC_CH74 27 /* ADC end of conversion channel 6 in sequence */ -#define DMA_T_ADC_CH84 28 /* ADC end of conversion channel 7 in sequence */ -#define DMA_T_ENC_DW 29 /* AES processor requests download input data */ -#define DMA_T_ENC_UP 30 /* AES processor requests upload output data */ - -/* variable DMA length modes (VLEN) */ -#define DMA_VLEN_LEN (0 << 5) /* Use LEN for transfer count*/ -/* - * Transfer the number of bytes/words specified by first byte/word + 1 - * (up to a maximum specified by LEN). - * Thus transfer count excludes length byte/word. - */ -#define DMA_VLEN_N1 (1 << 5) - /* - * Transfer the number of bytes/words specified by first byte/word - * (up to a maximum specified by LEN). - * Thus transfer count includes length byte/word. - */ -#define DMA_VLEN_N (2 << 5) - /* - * Transfer the number of bytes/words specified by first byte/word + 2 - * (up to a maximum specified by LEN). - */ -#define DMA_VLEN_N2 (3 << 5) - /* - * Transfer the number of bytes/words specified by first byte/word + 3 - * (up to a maximum specified by LEN). - */ -#define DMA_VLEN_N3 (4 << 5) -#define DMA_VLEN_RES1 (5 << 5) /* reserved */ -#define DMA_VLEN_RES2 (6 << 5) /* reserved */ -#define DMA_VLEN_LEN2 (7 << 5) /* Use LEN for transfer count */ - -/* Transfer Types (Byte 6 [6:5]) */ -#define DMA_SINGLE 0x00 /* Single */ -#define DMA_BLOCK 0x20 /* Block */ -#define DMA_RPT_SINGLE 0x40 /* Repeated single */ -#define DMA_RPT_BLOCK 0x60 /* Repeated block */ - -/* Source Increment Modes (Byte 7 [7:6])*/ -#define DMA_SRC_INC_NO 0x00 /* Source No increment */ -#define DMA_SRC_INC_1 0x40 /* Source Increment 1 */ -#define DMA_SRC_INC_2 0x80 /* Source Increment 2 */ -#define DMA_SRC_DEC 0xC0 /* Source Decrement 1 */ -/* Source Increment Modes (Byte 7 [5:4])*/ -#define DMA_DST_INC_NO 0x00 /* DestinationNo increment */ -#define DMA_DST_INC_1 0x10 /* Destination Increment 1 */ -#define DMA_DST_INC_2 0x20 /* Destination Increment 2 */ -#define DMA_DST_DEC 0x30 /* Destination Decrement 1 */ - -/* Descriptor Byte 7, Bits[3:0] */ -#define DMA_IRQ_MASK_ENABLE 0x08 -#define DMA_MODE_7_BIT 0x04 -#define DMA_PRIO_HIGHEST 0x03 -#define DMA_PRIO_HIGH 0x02 -#define DMA_PRIO_GUARANTEED 0x01 -#define DMA_PRIO_LOW 0x00 - -/** DMA configuration structure */ -typedef struct dma_config { - uint8_t src_h; /* source address high byte*/ - uint8_t src_l; /* source address low byte*/ - uint8_t dst_h; /* dest. address high byte*/ - uint8_t dst_l; /* dest. address low byte*/ - uint8_t len_h; /* [7:5] VLEN, [4:0] length high byte, 5 lowest bits*/ - uint8_t len_l; /* length low byte*/ - uint8_t wtt; /* 7: wordsize, [6:5] transfer mode, [4:0] trigger */ - /* [7:6] src inc, [5:4] dst_inc, 3: IRQ, 2: M8(vlen), [1-0] prio */ - uint8_t inc_prio; -} dma_config_t; - -#ifdef DMA_CONF_ON -#define DMA_ON DMA_CONF_ON -#else -#define DMA_ON 0 -#endif - -/* Number of DMA Channels and their Descriptors */ -#if DMA_ON -#define DMA_CHANNEL_COUNT 2 -extern dma_config_t dma_conf[DMA_CHANNEL_COUNT]; -#endif - -/* DMA-Related Macros */ -#define DMA_ARM(c) (DMAARM |= (1 << c)) /* Arm DMA Channel C */ -#define DMA_TRIGGER(c) (DMAREQ |= (1 << c)) /* Trigger DMA Channel C */ -/* - * Check Channel C for Transfer Status - * 1: Complete, Pending Interrupt, 0: Incomplete - */ -#define DMA_STATUS(c) (DMAIRQ &(1 << c)) -/* Abort Ongoing DMA Transfers on Channel C */ -#define DMA_ABORT(c) (DMAARM = ABORT | (1 << c)) -#define DMA_ABORT_ALL() (DMAARM = 0x9F) /* Abort ALL Ongoing DMA Transfers */ - -/* Functions Declarations */ -void dma_init(void); -void dma_associate_process(struct process *p, uint8_t c); - -/* Only link the ISR when DMA_ON is .... on */ -#if DMA_ON -void dma_ISR(void) __interrupt(DMA_VECTOR); -#endif - -#endif /*__DMA_H*/ diff --git a/cpu/cc2430/dev/dma_intr.c b/cpu/cc2430/dev/dma_intr.c deleted file mode 100644 index 01e96c8ac..000000000 --- a/cpu/cc2430/dev/dma_intr.c +++ /dev/null @@ -1,73 +0,0 @@ -/** - * \file - * DMA driver ISRs - * \author - * Original: Martti Huttunen - * Port: Zach Shelby - * - * DMA interrupt routines, must be stored in HOME bank - */ - -#include - -#include "contiki.h" - -#include "dev/dma.h" -#include "cc2430_sfr.h" - -#if DMA_ON -extern struct process *dma_callback[DMA_CHANNEL_COUNT]; -#endif - -/*---------------------------------------------------------------------------*/ -#ifdef HAVE_RF_DMA -extern void rf_dma_callback_isr(void); -#endif -#ifdef SPI_DMA_RX -extern void spi_rx_dma_callback(void); -#endif -/*---------------------------------------------------------------------------*/ -/** - * DMA interrupt service routine. - * - * if callback defined a poll is made to that process - */ -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -dma_ISR(void) __interrupt(DMA_VECTOR) -{ -#if DMA_ON - uint8_t i; -#endif - EA = 0; - IRCON_DMAIF = 0; -#ifdef HAVE_RF_DMA - if((DMAIRQ & 1) != 0) { - DMAIRQ &= ~1; - DMAARM = 0x81; - rf_dma_callback_isr(); - } -#endif -#ifdef SPI_DMA_RX - if((DMAIRQ & 0x08) != 0) { - DMAIRQ &= ~(1 << 3); - spi_rx_dma_callback(); - } -#endif -#if DMA_ON - for(i = 0; i < DMA_CHANNEL_COUNT; i++) { - if((DMAIRQ & (1 << i)) != 0) { - DMAIRQ &= ~(1 << i); - if(dma_callback[i] != 0) { - process_poll(dma_callback[i]); - } - } - } -#endif - EA = 1; -} -#pragma restore -/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/hwconf.h b/cpu/cc2430/dev/hwconf.h deleted file mode 100644 index 6d1fad135..000000000 --- a/cpu/cc2430/dev/hwconf.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ -#ifndef HWCONF_H_ -#define HWCONF_H_ - -#include "sys/cc.h" - -#include - -#define HWCONF_PIN(name, port, bit) \ -static CC_INLINE void name##_SELECT() {P##port##SEL &= ~(1 << bit);} \ -static CC_INLINE void name##_SELECT_IO() {P##port##SEL &= ~(1 << bit);} \ -static CC_INLINE void name##_SELECT_PM() {P##port##SEL |= 1 << bit;} \ -static CC_INLINE void name##_SET() {P##port##_##bit = 1; } \ -static CC_INLINE void name##_CLEAR() {P##port##_##bit = 0; } \ -static CC_INLINE unsigned char name##_READ() {return P##port##_##bit; } \ -static CC_INLINE void name##_MAKE_OUTPUT() {P##port##DIR |= 1 << bit;} \ -static CC_INLINE void name##_MAKE_INPUT() {P##port##DIR &= ~(1 << bit); } - -#define HWCONF_IRQ_XXX(name, port, bit) \ -static CC_INLINE void name##_ENABLE_IRQ() { \ - if ( port == 2 ) { PICTL |= P2IEN; p2ien |= 1<=4)) { PICTL |= P0IENH; p0ien |= 1<=4)) { \ - p0ien &= ~(1<=4 ) { PICTL |= P0IENH; p0ien |= 1<=4) { \ - p0ien &= ~(1< - */ -#include "cc2430_sfr.h" -#include "dev/cc2430_rf.h" -/*---------------------------------------------------------------------------*/ -/** - * \brief Generates a new random number using the cc2430 RNG. - * \return The random number. - */ -unsigned short -random_rand(void) -{ - /* Clock the RNG LSFR once */ - ADCCON1 |= ADRCTRL0; - - return (RNDL | (RNDH << 8)); -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Seed the cc2430 random number generator. - * \param seed Seed value for the RNG. - * - * If the SEED argument is 0, seed the RNG with IF_ADC as - * discussed in the cc2430 datasheet (rev. 2.1), section 13.11.2.2, - * page 134. Seeding with this method should not be done during - * normal radio operation. Thus, use this function before - * initialising the network. - * - * If the SEED is provided, seed with this value instead. This will - * result in the same sequence of random numbers each time the node - * reboots. So, don't use it unless you have a reason (e.g. tests) - */ -void -random_init(unsigned short seed) -{ - int i; - - /* Comment out this if() block to save a nice 16 bytes of code size */ - if(seed) { - /* If the caller provides a seed, write the high-byte first and then - * write the low byte */ - RNDL = seed >> 8; /* High byte first */ - RNDL = seed & 0xFF; - return; - } - - /* - * cc2430 Datasheet: - * "When a true random value is required, the LFSR should be seeded by - * writing RNDL with random values from the IF_ADC in the RF receive path." - * - * "To use this seeding method, the radio must first be powered on by - * enabling the voltage regulator" - */ - RFPWR &= ~RREG_RADIO_PD; /* Turn on the voltage regulator */ - while(!(RFIF & IRQ_RREG_ON)); /* Wait for power up*/ - - /* OK, it's powered. The respective interrupt flag has been set, clear it */ - RFIF &= ~IRQ_RREG_ON; - - /* - * "The radio should be placed in infinite TX state, to avoid possible sync - * detect in RX state." - * - * Judging by old chipcon cc2430 code examples as well as by the way cc2530 - * works, this is very likely to be "RX state" (i.e. a typo in the datasheet) - * - * With infinite TX, ADCTSTx always read as 0 so we'll use infinite RX - */ - MDMCTRL1L = 0x02; /* RX mode 10 - RX_INFINITE state */ - - /* "Enter RX State - Immediate" command strobe */ - cc2430_rf_command(ISRXON); - - /* Make sure the RNG is on */ - ADCCON1 &= ~(ADRCTRL1 | ADRCTRL0); - - /* Wait for IF_ADC I-branch and Q-branch values */ - while(!(ADCTSTH & ADCTSTL)); - - /* 32 times as per the chipcon example. This seems to increase randomness */ - for(i = 0; i < 32; i++) { - /* Seed the RNG by writing into RNDL twice with values from ADCTSTx */ - RNDL = ADCTSTH; - RNDL = ADCTSTL; - - /* Clock the RNG LSFR once */ - ADCCON1 |= ADRCTRL0; - } - - /* - * Exit RX state. Just shut down, network initialisation will take care of - * properly starting the radio for us. - */ - RFPWR |= RREG_RADIO_PD; -} diff --git a/cpu/cc2430/dev/uart.h b/cpu/cc2430/dev/uart.h deleted file mode 100644 index e230c3bcd..000000000 --- a/cpu/cc2430/dev/uart.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef UART_H -#define UART_H - -#include "contiki-conf.h" - -#include "cc2430_sfr.h" -#include "8051def.h" - -/*---------------------------------------------------------------------------*/ -/* UART BAUD Rates */ -/* - * Macro to set speed of UART N by setting the UnBAUD SFR to M and the - * UnGCR SRF to E. See the cc2430 datasheet for possible values of M and E - */ -#define UART_SET_SPEED(N, M, E) do{ U##N##BAUD = M; U##N##GCR = E; } while(0) - -/* - * Sample Values for M and E in the macro above to achieve some common BAUD - * rates. For more values, see the cc2430 datasheet - */ -/* 2000000 - cc2430 theoretical MAX when using the 32MHz clock */ -#define UART_2K_M 0 -#define UART_2K_E 16 -/* 1000000 - cc2430 theoretical MAX when using the 16MHz clock */ -#define UART_1K_M 0 -#define UART_1K_E 15 -/* 921600 */ -#define UART_921_M 216 -#define UART_921_E 14 -/* 460800 Higher values lead to problems when the node needs to RX */ -#define UART_460_M 216 -#define UART_460_E 13 -/* 115200 */ -#define UART_115_M 216 -#define UART_115_E 11 -/* 38400 */ -#define UART_38_M 59 -#define UART_38_E 10 -/* 9600 */ -#define UART_9_M 59 -#define UART_9_E 8 - -#endif /* UART_H */ diff --git a/cpu/cc2430/dev/uart0.c b/cpu/cc2430/dev/uart0.c deleted file mode 100644 index 254dba765..000000000 --- a/cpu/cc2430/dev/uart0.c +++ /dev/null @@ -1,69 +0,0 @@ -/** - * \file - * - * uart0 write routines - * - * \author - * - * Anthony "Asterisk" Ambuehl - * - */ -#include -#include - -#include "cc2430_sfr.h" -#include "dev/uart0.h" - -#if UART_ZERO_ENABLE -/*---------------------------------------------------------------------------*/ -void -uart0_init() -{ - UART_SET_SPEED(0, UART_115_M, UART_115_E); - -#ifdef UART0_ALTERNATIVE_2 - PERCFG |= U0CFG; /*alternative port 2 = P1.5-2*/ -#ifdef UART0_RTSCTS - P1SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/ -#else - P1SEL |= 0x30; /*peripheral select for TX and RX*/ - P1 &= ~0x08; /*RTS down*/ -#endif - P1DIR |= 0x28; /*RTS, TX out*/ - P1DIR &= ~0x14; /*CTS & RX in*/ -#else - PERCFG &= ~U0CFG; /*alternative port 1 = P0.5-2*/ -#ifdef UART0_RTSCTS - P0SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/ -#else - P0SEL |= 0x0C; /*peripheral select for TX and RX*/ - P0 &= ~0x20; /*RTS down*/ -#endif - P0DIR |= 0x28; /*RTS & TX out*/ - P0DIR &= ~0x14; /*CTS & RX in*/ -#endif - - -#ifdef UART0_RTSCTS - U0UCR = 0x42; /*defaults: 8N1, RTS/CTS, high stop bit*/ -#else - U0UCR = 0x02; /*defaults: 8N1, no flow control, high stop bit*/ -#endif - - U0CSR = U_MODE | U_RE | U_TXB; /*UART mode, receiver enable, TX done*/ - - /*set priority group of group 3 to highest, so the UART won't miss bytes*/ - IP1 |= IP1_3; - IP0 |= IP0_3; -} -/*---------------------------------------------------------------------------*/ -/* Write one byte over the UART. */ -void -uart0_writeb(uint8_t byte) -{ - IRCON2_UTX0IF = 0; - U0BUF = byte; - while(!IRCON2_UTX0IF); /* Wait until byte has been transmitted. */ - IRCON2_UTX0IF = 0; -} -#endif diff --git a/cpu/cc2430/dev/uart0.h b/cpu/cc2430/dev/uart0.h deleted file mode 100644 index 8a1357639..000000000 --- a/cpu/cc2430/dev/uart0.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef UART_0_H -#define UART_0_H - -#include "contiki-conf.h" - -#include "cc2430_sfr.h" -#include "8051def.h" -#include "uart.h" - -/*---------------------------------------------------------------------------*/ -/* UART0 Enable - Disable */ -#ifdef UART_ZERO_CONF_ENABLE -#define UART_ZERO_ENABLE UART_ZERO_CONF_ENABLE -#else -#define UART_ZERO_ENABLE 0 -#endif -/*---------------------------------------------------------------------------*/ -/* UART0 Function Declarations */ -#if UART_ZERO_ENABLE -void uart0_init(); -void uart0_writeb(uint8_t byte); - -void uart0_set_input(int (* input)(unsigned char c)); - -void uart0_rx_ISR(void) __interrupt(URX0_VECTOR); -void uart0_tx_ISR(void) __interrupt(UTX0_VECTOR); -/* Macro to turn on / off UART RX Interrupt */ -#define UART0_RX_INT(v) do { IEN0_URX0IE = v; } while(0) -#endif - -#endif /* UART_0_H */ diff --git a/cpu/cc2430/dev/uart1.c b/cpu/cc2430/dev/uart1.c deleted file mode 100644 index 7f388c5b6..000000000 --- a/cpu/cc2430/dev/uart1.c +++ /dev/null @@ -1,74 +0,0 @@ -/** - * \file - * - * uart1 write routines - * - * \author - * - * Anthony "Asterisk" Ambuehl - * - */ -#include -#include - -#include "cc2430_sfr.h" -#include "dev/uart1.h" - -#if UART_ONE_ENABLE -/*---------------------------------------------------------------------------*/ -/* UART1 initialization */ -void -uart1_init() -{ -#ifdef UART1_ALTERNATIVE_1 - PERCFG &= ~U1CFG; /*alternative port 1 = P0.5-2*/ -#ifdef UART1_RTSCTS - P0SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/ -#else - P0SEL |= 0x30; /*peripheral select for TX and RX*/ - P0 &= ~0x08; /*RTS down*/ -#endif - P0DIR |= 0x18; /*RTS, TX out*/ - P0DIR &= ~0x24; /*CTS, RX in*/ -#else - PERCFG |= U1CFG; /*alternative port 2 = P1.7-4*/ -#ifdef UART1_RTSCTS - P1SEL |= 0xF0; /*peripheral select for TX and RX*/ -#else - P1SEL |= 0xC0; /*peripheral select for TX and RX*/ - P1 &= ~0x20; /*RTS down*/ -#endif - P1DIR |= 0x60; /*RTS, TX out*/ - P1DIR &= ~0x90; /*CTS, RX in*/ -#endif - -#if UART_ONE_CONF_HIGH_SPEED - UART_SET_SPEED(1, UART_460_M, UART_460_E); -#else - UART_SET_SPEED(1, UART_115_M, UART_115_E); -#endif - -#ifdef UART1_RTSCTS - U1UCR = 0x42; /*defaults: 8N1, RTS/CTS, high stop bit*/ -#else - U1UCR = 0x02; /*defaults: 8N1, no flow control, high stop bit*/ -#endif - - U1CSR = U_MODE | U_RE; /* UART mode, receiver enable */ - - /*set priority group of group 3 to highest, so the UART won't miss bytes*/ - IP1 |= IP1_3; - IP0 |= IP0_3; -} -/*---------------------------------------------------------------------------*/ -/* Write one byte over the UART. */ -void -uart1_writeb(uint8_t byte) -{ - IRCON2_UTX1IF = 0; - U1BUF = byte; - while(!IRCON2_UTX1IF); /* Wait until byte has been transmitted. */ - IRCON2_UTX1IF = 0; -} -/*---------------------------------------------------------------------------*/ -#endif diff --git a/cpu/cc2430/dev/uart1.h b/cpu/cc2430/dev/uart1.h deleted file mode 100644 index 1a4b7e9fa..000000000 --- a/cpu/cc2430/dev/uart1.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef UART_1_H -#define UART_1_H - -#include "contiki-conf.h" - -#include "cc2430_sfr.h" -#include "8051def.h" -#include "uart.h" - -/*---------------------------------------------------------------------------*/ -/* UART1 Enable - Disable */ -#ifdef UART_ONE_CONF_ENABLE -#define UART_ONE_ENABLE UART_ONE_CONF_ENABLE -#else -#define UART_ONE_ENABLE 0 -#endif -/*---------------------------------------------------------------------------*/ -/* UART1 Function Declarations */ -#if UART_ONE_ENABLE -void uart1_init(); -void uart1_writeb(uint8_t byte); - -void uart1_set_input(int (*input)(unsigned char c)); -#if UART_ONE_CONF_WITH_INPUT -void uart1_rx_ISR(void) __interrupt(URX1_VECTOR); -void uart1_tx_ISR(void) __interrupt(UTX1_VECTOR); -/* Macro to turn on / off UART RX Interrupt */ -#define UART1_RX_INT(v) do { IEN0_URX1IE = v; } while(0) -#else -#define UART1_RX_INT(v) -#endif /* UART_ONE_CONF_WITH_INPUT */ -#else -#define uart1_init(...) -#define uart1_writeb(...) -#define uart1_set_input(...) -#define UART1_RX_INT(v) -#endif /* UART_ONE_ENABLE */ - -#endif /* UART_1_H */ diff --git a/cpu/cc2430/dev/uart_intr.c b/cpu/cc2430/dev/uart_intr.c deleted file mode 100644 index 17a5427aa..000000000 --- a/cpu/cc2430/dev/uart_intr.c +++ /dev/null @@ -1,91 +0,0 @@ -/** - * \file - * - * uart write routines - * - * \author - * - * Anthony "Asterisk" Ambuehl - * - * interrupt routines which must be in HOME bank. handles received data from UART. - * - */ -#include -#include - -#include "cc2430_sfr.h" - -#include "dev/leds.h" -#include "dev/uart0.h" -#include "dev/uart1.h" -#include "sys/energest.h" - -#if UART_ZERO_ENABLE -static int (* uart0_input_handler)(unsigned char c); -#endif -#if UART_ONE_ENABLE -static int (* uart1_input_handler)(unsigned char c); -#endif - -#if UART_ZERO_ENABLE -/*---------------------------------------------------------------------------*/ -void -uart0_set_input(int (* input)(unsigned char c)) -{ - uart0_input_handler = input; -} - -/*---------------------------------------------------------------------------*/ -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -uart0_rx_ISR(void) __interrupt(URX0_VECTOR) -{ - ENERGEST_ON(ENERGEST_TYPE_IRQ); - TCON_URX0IF = 0; - if(uart0_input_handler != NULL) { - uart0_input_handler(U0BUF); - } - ENERGEST_OFF(ENERGEST_TYPE_IRQ); -} -/*---------------------------------------------------------------------------*/ -void -uart0_tx_ISR(void) __interrupt(UTX0_VECTOR) -{ -} -#pragma restore -#endif /* UART_ZERO_ENABLE */ -#if UART_ONE_ENABLE -/*---------------------------------------------------------------------------*/ -void -uart1_set_input(int (* input)(unsigned char c)) -{ - uart1_input_handler = input; -} -/*---------------------------------------------------------------------------*/ -#if UART_ONE_CONF_WITH_INPUT -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -uart1_rx_ISR(void) __interrupt(URX1_VECTOR) -{ - ENERGEST_ON(ENERGEST_TYPE_IRQ); - TCON_URX1IF = 0; - if(uart1_input_handler != NULL) { - uart1_input_handler(U1BUF); - } - ENERGEST_OFF(ENERGEST_TYPE_IRQ); -} -/*---------------------------------------------------------------------------*/ -void -uart1_tx_ISR(void) __interrupt(UTX1_VECTOR) -{ -} -#pragma restore -/*---------------------------------------------------------------------------*/ -#endif /* UART_ONE_CONF_WITH_INPUT */ -#endif /* UART_ONE_ENABLE */ diff --git a/cpu/cc2430/rtimer-arch.c b/cpu/cc2430/rtimer-arch.c deleted file mode 100644 index 1abff5c08..000000000 --- a/cpu/cc2430/rtimer-arch.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Hardware-dependent functions used to support the - * contiki rtimer module. - * - * clock and etimer are using the sleep timer on the cc2430 - * - * clock_init() has set our tick speed prescaler already, so we - * are ticking with 500 kHz freq. - * - * rtimer_clock_t is unsigned short (16bit on the cc2430) - * It thus makes sense to use the 16bit clock (Timer 1) - * - * This file contains an ISR and must reside in the HOME bank - * - * \author - * George Oikonomou - - */ - -#include "sys/rtimer.h" /* Includes rtimer-arch.h for us */ -#include "cc2430_sfr.h" -#include "sys/energest.h" - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif - -/*---------------------------------------------------------------------------*/ -void -rtimer_arch_init(void) -{ - PRINTF("rtimer_arch_init() "); - /* - * - Free running mode - * - Prescale by 32: - * Tick Speed has been prescaled to 500 kHz already in clock_init() - * We further prescale by 32 resulting in 15625 Hz for this timer. - */ - T1CTL = (T1DIV1 | T1MODE0); /* 00001001 */ - PRINTF("T1CTL=0x%02x\n", T1CTL); - /* Acknowledge Timer 1 Interrupts */ - IEN1_T1IE = 1; - PRINTF("IEN1_T1IE=0x%02x\n", IEN1_T1IE); - - /* Timer 1, Channel 1. Compare Mode (0x04), Interrupt mask on (0x40) */ - T1CCTL1 = T1MODE + T1IM; - PRINTF("T1CCTL1=0x%02x\n", T1CCTL1); - - /* Interrupt Mask Flags: No interrupt on overflow */ - TIMIF &= ~OVFIM; - PRINTF("TIMIF=0x%02x\n", TIMIF); - - PRINTF("done\n"); -} -/*---------------------------------------------------------------------------*/ -void -rtimer_arch_schedule(rtimer_clock_t t) -{ - PRINTF("rtimer_arch_schedule(%u)\n", t); - - /* set the compare mode values so we can get an interrupt after t */ - T1CC1L = (unsigned char)t; - T1CC1H = (unsigned char)(t >> 8); - PRINTF("T1CC1=%u, t=%u\n", (T1CC1L + (T1CC1H << 8)), t); - - /* Turn on compare mode interrupt */ - PRINTF("T1CTL=0x%02x\n", T1CTL); - T1CCTL1 |= T1IM; -} -/*---------------------------------------------------------------------------*/ -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -cc2430_timer_1_ISR(void) __interrupt(T1_VECTOR) -{ - IEN1_T1IE = 0; /* Ignore Timer 1 Interrupts */ - ENERGEST_ON(ENERGEST_TYPE_IRQ); - /* No more interrupts from Channel 1 till next rtimer_arch_schedule() call. - * Setting the mask will instantly generate an interrupt so we clear the - * flag first. */ - T1CTL &= ~(CH1IF); - T1CCTL1 &= ~T1IM; - - rtimer_run_next(); - - ENERGEST_OFF(ENERGEST_TYPE_IRQ); - IEN1_T1IE = 1; /* Acknowledge Timer 1 Interrupts */ -} -#pragma restore diff --git a/cpu/cc2430/segment.rules b/cpu/cc2430/segment.rules deleted file mode 100644 index 3b4ffbdfa..000000000 --- a/cpu/cc2430/segment.rules +++ /dev/null @@ -1,26 +0,0 @@ -# segment.rules files assign source code modules to specific banks -# These files are only used when we build code with banking (HAVE_BANKING=1) -# The final segment.rules file is constructed from any segment.rules found in -# the search path, defined in Makefile.cc2430 -# When building bankable code, the bank-alloc.py script automatically allocates -# modules to banks. segment.rules files provide hints, instructing the script -# as to which files are safe to move around and which files to leave alone -# In other words, only specify a rule for a file if you need to -# comments starting with "#" are supported -# The file spec in rules is actually interpreted as a python regex so you can -# write a rule that will match multiple files -# -# general rules -- -# This file is only used when the Makefile defines HAVE_BANKING=1 -# SDCC's standard libraries will always go in CSEG - We don't touch them -# Interrupt code must be in HOME. Specify all files with an ISR here -# All files without an associated rule get allocated to a bank automatically - -# Files with ISRs must be in HOME -HOME intr.c # Match all files ending in intr.c (e.g. uart_intr.c) -HOME rtimer-arch.c -HOME watchdog-cc2430.c -HOME clock.c - -# Some cc2430 files which need special treatment -HOME bus.c # bus.c::flash_read() must be run from HOME (if compiled in) diff --git a/cpu/cc2430/stack.c b/cpu/cc2430/stack.c deleted file mode 100644 index 7043b2edf..000000000 --- a/cpu/cc2430/stack.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2011, George Oikonomou - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 AUTHOR 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * 8051 stack debugging facilities - * - * \author - * George Oikonomou - - * Philippe Retornaz (EPFL) - */ -#include "contiki.h" - -#ifndef STACK_POISON -#define STACK_POISON 0xAA -#endif - -CC_AT_DATA uint8_t sp; - -void -stack_poison(void) -{ - __asm - mov r1, _SP -poison_loop: - inc r1 - mov @r1, #STACK_POISON - cjne r1, #0xFF, poison_loop - __endasm; -} - -uint8_t -stack_get_max(void) -{ - __data uint8_t *sp = (__data uint8_t *)0xff; - uint8_t free = 0; - - while(*sp-- == STACK_POISON) { - free++; - } - - return 0xff - free; -} diff --git a/cpu/cc2430/stack.h b/cpu/cc2430/stack.h deleted file mode 100644 index 6ee7442b6..000000000 --- a/cpu/cc2430/stack.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2011, George Oikonomou - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 AUTHOR 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Header file for 8051 stack debugging facilities - * - * \author - * George Oikonomou - - * Philippe Retornaz (EPFL) - */ -#ifndef STACK_H_ -#define STACK_H_ - -#if STACK_CONF_DEBUGGING -extern CC_AT_DATA uint8_t sp; - -#define stack_dump(f) do { \ - putstring(f); \ - sp = SP; \ - puthex(sp); \ - putchar('\n'); \ -} while(0) - -#define stack_max_sp_print(f) do { \ - putstring(f); \ - puthex(stack_get_max()); \ - putchar('\n'); \ -} while(0) - -void stack_poison(void); -uint8_t stack_get_max(void); -#else -#define stack_dump(...) -#define stack_max_sp_print(...) -#define stack_poison() -#define stack_get_max() -#endif - -#endif /* STACK_H_ */ diff --git a/cpu/cc2538/Makefile.cc2538 b/cpu/cc2538/Makefile.cc2538 index c13628b01..218f05200 100644 --- a/cpu/cc2538/Makefile.cc2538 +++ b/cpu/cc2538/Makefile.cc2538 @@ -3,6 +3,7 @@ CPP = arm-none-eabi-cpp LD = arm-none-eabi-gcc AR = arm-none-eabi-ar OBJCOPY = arm-none-eabi-objcopy +OBJDUMP = arm-none-eabi-objdump NM = arm-none-eabi-nm ifndef SOURCE_LDSCRIPT @@ -19,6 +20,11 @@ LDFLAGS += -T $(LDSCRIPT) LDFLAGS += -Wl,--gc-sections,--sort-section=alignment LDFLAGS += -Wl,-Map=$(@:.elf=-$(TARGET).map),--cref,--no-warn-mismatch OBJCOPY_FLAGS += -O binary --gap-fill 0xff +OBJDUMP_FLAGS += --disassemble --source --disassembler-options=force-thumb + +ifdef WERROR +CFLAGS += -Werror +endif ### Are we building with code size optimisations? ifeq ($(SMALL),1) @@ -45,20 +51,38 @@ CONTIKI_CPU_DIRS += ../arm/common/dbg-io CONTIKI_CPU_DIRS += ../cc253x/usb/common ../cc253x/usb/common/cdc-acm ### CPU-dependent source files -CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c uart.c watchdog.c +CONTIKI_CPU_SOURCEFILES += soc.c clock.c rtimer-arch.c uart.c watchdog.c CONTIKI_CPU_SOURCEFILES += nvic.c cpu.c sys-ctrl.c gpio.c ioc.c spi.c adc.c +CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ecb.c cbc.c ctr.c cbc-mac.c gcm.c +CONTIKI_CPU_SOURCEFILES += ccm.c sha256.c +CONTIKI_CPU_SOURCEFILES += cc2538-aes-128.c cc2538-ccm-star.c CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c +CONTIKI_CPU_SOURCEFILES += pka.c bignum-driver.c ecc-driver.c ecc-algorithm.c +CONTIKI_CPU_SOURCEFILES += ecc-curve.c CONTIKI_CPU_SOURCEFILES += dbg.c ieee-addr.c CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c +CONTIKI_CPU_SOURCEFILES += i2c.c cc2538-temp-sensor.c vdd3-sensor.c +CONTIKI_CPU_SOURCEFILES += cfs-coffee.c cfs-coffee-arch.c pwm.c DEBUG_IO_SOURCEFILES += dbg-printf.c dbg-snprintf.c dbg-sprintf.c strformat.c USB_CORE_SOURCEFILES += usb-core.c cdc-acm.c USB_ARCH_SOURCEFILES += usb-arch.c usb-serial.c cdc-acm-descriptors.c +ifneq ($(TARGET_START_SOURCEFILES),) + CPU_START_SOURCEFILES = TARGET_START_SOURCEFILES +else + CPU_START_SOURCEFILES = startup-gcc.c +endif +CPU_STARTFILES = ${addprefix $(OBJECTDIR)/,${call oname, $(CPU_START_SOURCEFILES)}} + CONTIKI_SOURCEFILES += $(CONTIKI_CPU_SOURCEFILES) $(DEBUG_IO_SOURCEFILES) CONTIKI_SOURCEFILES += $(USB_CORE_SOURCEFILES) $(USB_ARCH_SOURCEFILES) +MODULES += lib/newlib + +.SECONDEXPANSION: + ### Don't treat the .elf as intermediate .PRECIOUS: %.elf %.hex %.bin @@ -72,7 +96,7 @@ $(OBJECTDIR)/ieee-addr.o: ieee-addr.c FORCE | $(OBJECTDIR) ### Compilation rules CUSTOM_RULE_LINK=1 -%.elf: $(TARGET_STARTFILES) %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a $(LDSCRIPT) +%.elf: $(CPU_STARTFILES) $$(CONTIKI_OBJECTFILES) %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) $(LDSCRIPT) $(TRACE_LD) $(Q)$(LD) $(LDFLAGS) ${filter-out $(LDSCRIPT) %.a,$^} ${filter %.a,$^} $(TARGET_LIBFILES) -o $@ @@ -82,15 +106,18 @@ CUSTOM_RULE_LINK=1 %.bin: %.elf $(OBJCOPY) $(OBJCOPY_FLAGS) $< $@ +%.lst: %.elf + $(OBJDUMP) $(OBJDUMP_FLAGS) $< > $@ + ### We don't really need the .hex and .bin for the .$(TARGET) but let's make ### sure they get built %.$(TARGET): %.elf %.hex %.bin cp $< $@ ### This rule is used to generate the correct linker script -LDGENFLAGS += $(addprefix -D,$(subst $(COMMA), ,$(DEFINES))) -LDGENFLAGS += $(addprefix -I,$(SOURCEDIRS)) -LDGENFLAGS += -imacros "contiki-conf.h" +LDGENFLAGS += $(CFLAGS) +LDGENFLAGS += -imacros "contiki-conf.h" -imacros "dev/cc2538-dev.h" +LDGENFLAGS += -imacros "dev/flash.h" -imacros "cfs-coffee-arch.h" LDGENFLAGS += -x c -P -E # NB: Assumes LDSCRIPT was not overridden and is in $(OBJECTDIR) diff --git a/cpu/cc2538/cc2538.lds b/cpu/cc2538/cc2538.lds index 71115fbe3..ef465409e 100644 --- a/cpu/cc2538/cc2538.lds +++ b/cpu/cc2538/cc2538.lds @@ -33,53 +33,60 @@ * stage. Rather, it is used as input for the auto-generation of the actual * ld script, which is called cc2538.ld and will be in the project directory */ -#if (LPM_CONF_MAX_PM==2) && (LPM_CONF_ENABLE != 0) -#define NRSRAM_START 0x20000000 -#define NRSRAM_LEN 0x00004000 -#define SRAM_START 0x20004000 -#define SRAM_LEN 0x00004000 -#else -#define SRAM_START 0x20000000 -#define SRAM_LEN 0x00008000 -#endif - MEMORY { - FLASH (rx) : ORIGIN = 0x200000, LENGTH = 0x0007FFD4 - FLASH_CCA (RX) : ORIGIN = 0x0027FFD4, LENGTH = 44 -#if (LPM_CONF_MAX_PM==2) && (LPM_CONF_ENABLE != 0) - NRSRAM (RWX) : ORIGIN = NRSRAM_START, LENGTH = NRSRAM_LEN + FLASH_FW (rx) : ORIGIN = FLASH_FW_ADDR, LENGTH = FLASH_FW_SIZE + FLASH_CCA (RX) : ORIGIN = FLASH_CCA_ADDR, LENGTH = FLASH_CCA_SIZE + + /* + * If PM2 is enabled, then the PM2 SRAM limitations apply, i.e. the + * regular-leakage SRAM is a non-retention SRAM and the low-leakage SRAM is + * a full-retention SRAM. + * Else, the data in the regular-leakage SRAM is always retained, so there + * are virtually a non-retention SRAM with a size of 0 bytes and a + * full-retention SRAM spanning the whole SRAM, which is more convenient to + * use. + */ +#if LPM_CONF_ENABLE && LPM_CONF_MAX_PM >= 2 + NRSRAM (RWX) : ORIGIN = CC2538_DEV_RLSRAM_ADDR, + LENGTH = CC2538_DEV_RLSRAM_SIZE + FRSRAM (RWX) : ORIGIN = CC2538_DEV_LLSRAM_ADDR, + LENGTH = CC2538_DEV_LLSRAM_SIZE +#else + NRSRAM (RWX) : ORIGIN = CC2538_DEV_RLSRAM_ADDR, LENGTH = 0 + FRSRAM (RWX) : ORIGIN = CC2538_DEV_SRAM_ADDR, LENGTH = CC2538_DEV_SRAM_SIZE #endif - SRAM (RWX) : ORIGIN = SRAM_START, LENGTH = SRAM_LEN } +ENTRY(flash_cca_lock_page) SECTIONS { .text : { _text = .; - KEEP(*(.vectors)) + *(.vectors) *(.text*) *(.rodata*) _etext = .; - } > FLASH= 0 + } > FLASH_FW= 0 .socdata (NOLOAD) : { *(.udma_channel_control_table) - } > SRAM + } > FRSRAM - .data : + .data : ALIGN(4) { _data = .; *(.data*) _edata = .; - } > SRAM AT > FLASH + } > FRSRAM AT > FLASH_FW + _ldata = LOADADDR(.data); .ARM.exidx : { *(.ARM.exidx*) - } > FLASH + } > FLASH_FW .bss : { @@ -87,19 +94,25 @@ SECTIONS *(.bss*) *(COMMON) _ebss = .; - } > SRAM + } > FRSRAM + + .stack (NOLOAD) : + { + *(.stack) + } > FRSRAM + + _heap = .; + _eheap = ORIGIN(FRSRAM) + LENGTH(FRSRAM); -#if (LPM_CONF_MAX_PM==2) && (LPM_CONF_ENABLE != 0) .nrdata (NOLOAD) : { _nrdata = .; *(.nrdata*) _enrdata = .; } > NRSRAM -#endif .flashcca : { - KEEP(*(.flashcca)) + *(.flashcca) } > FLASH_CCA } diff --git a/cpu/cc2538/cfs-coffee-arch.c b/cpu/cc2538/cfs-coffee-arch.c new file mode 100644 index 000000000..6d3664f5b --- /dev/null +++ b/cpu/cc2538/cfs-coffee-arch.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2013, ADVANSEE - http://www.advansee.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-cfs-coffee-arch + * @{ + * + * \file + * Module for the cc2538 Coffee port + */ +#include "contiki-conf.h" +#include "sys/cc.h" +#include "cfs/cfs-coffee.h" +#include "dev/cc2538-dev.h" +#include "dev/rom-util.h" +#include "dev/flash.h" +#include "dev/watchdog.h" +#include "cpu.h" +#include "cfs-coffee-arch.h" + +#include + +#ifndef COFFEE_CONF_CUSTOM_PORT +/*---------------------------------------------------------------------------*/ +#if !COFFEE_SECTOR_SIZE || COFFEE_SECTOR_SIZE % FLASH_PAGE_SIZE +#error COFFEE_SECTOR_SIZE must be a non-zero multiple of the flash page size +#endif +#if !COFFEE_PAGE_SIZE || COFFEE_SECTOR_SIZE % COFFEE_PAGE_SIZE +#error COFFEE_PAGE_SIZE must be a divisor of COFFEE_SECTOR_SIZE +#endif +#if COFFEE_PAGE_SIZE % FLASH_WORD_SIZE +#error COFFEE_PAGE_SIZE must be a multiple of the flash word size +#endif +#if COFFEE_START % FLASH_PAGE_SIZE +#error COFFEE_START must be aligned with a flash page boundary +#endif +#if COFFEE_SIZE % COFFEE_SECTOR_SIZE +#error COFFEE_SIZE must be a multiple of COFFEE_SECTOR_SIZE +#endif +#if COFFEE_SIZE / COFFEE_PAGE_SIZE > INT16_MAX +#error Too many Coffee pages for coffee_page_t +#endif +#if COFFEE_START < CC2538_DEV_FLASH_ADDR || \ + COFFEE_START + COFFEE_SIZE > FLASH_CCA_ADDR +#error Coffee does not fit in flash +#endif +/*---------------------------------------------------------------------------*/ +void +cfs_coffee_arch_erase(uint16_t sector) +{ + watchdog_periodic(); + INTERRUPTS_DISABLE(); + rom_util_page_erase(COFFEE_START + sector * COFFEE_SECTOR_SIZE, + COFFEE_SECTOR_SIZE); + INTERRUPTS_ENABLE(); +} +/*---------------------------------------------------------------------------*/ +void +cfs_coffee_arch_write(const void *buf, unsigned int size, cfs_offset_t offset) +{ + const uint32_t *src = buf; + uint32_t flash_addr = COFFEE_START + offset; + unsigned int align; + uint32_t word, len; + uint32_t page_buf[COFFEE_PAGE_SIZE / FLASH_WORD_SIZE]; + unsigned int i; + + if(size && (align = flash_addr & (FLASH_WORD_SIZE - 1))) { + len = MIN(FLASH_WORD_SIZE - align, size); + word = ~((*src & ((1 << (len << 3)) - 1)) << (align << 3)); + watchdog_periodic(); + INTERRUPTS_DISABLE(); + rom_util_program_flash(&word, flash_addr & ~(FLASH_WORD_SIZE - 1), + FLASH_WORD_SIZE); + INTERRUPTS_ENABLE(); + *(const uint8_t **)&src += len; + size -= len; + flash_addr += len; + } + + while(size >= FLASH_WORD_SIZE) { + len = MIN(size & ~(FLASH_WORD_SIZE - 1), COFFEE_PAGE_SIZE); + for(i = 0; i < len / FLASH_WORD_SIZE; i++) { + page_buf[i] = ~*src++; + } + watchdog_periodic(); + INTERRUPTS_DISABLE(); + rom_util_program_flash(page_buf, flash_addr, len); + INTERRUPTS_ENABLE(); + size -= len; + flash_addr += len; + } + + if(size) { + word = ~(*src & ((1 << (size << 3)) - 1)); + watchdog_periodic(); + INTERRUPTS_DISABLE(); + rom_util_program_flash(&word, flash_addr, FLASH_WORD_SIZE); + INTERRUPTS_ENABLE(); + } +} +/*---------------------------------------------------------------------------*/ +void +cfs_coffee_arch_read(void *buf, unsigned int size, cfs_offset_t offset) +{ + const uint8_t *src; + uint8_t *dst; + + watchdog_periodic(); + for(src = (const void *)(COFFEE_START + offset), dst = buf; size; size--) { + *dst++ = ~*src++; + } +} + +#endif /* COFFEE_CONF_CUSTOM_PORT */ + +/** @} */ diff --git a/cpu/cc2538/cfs-coffee-arch.h b/cpu/cc2538/cfs-coffee-arch.h new file mode 100644 index 000000000..a0bf3dd75 --- /dev/null +++ b/cpu/cc2538/cfs-coffee-arch.h @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2013, ADVANSEE - http://www.advansee.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538 + * @{ + * + * \defgroup cc2538-cfs-coffee-arch cc2538 Coffee port module + * + * Module for the cc2538 Coffee port + * @{ + * + * \file + * Header file for the cc2538 Coffee port module + */ +#ifndef CFS_COFFEE_ARCH_H_ +#define CFS_COFFEE_ARCH_H_ + +#include "contiki-conf.h" +#include "cfs/cfs-coffee.h" +#include "dev/cc2538-dev.h" +#include "dev/flash.h" + +#include + +#ifdef COFFEE_CONF_CUSTOM_PORT +#include COFFEE_CONF_CUSTOM_PORT +#else +/*---------------------------------------------------------------------------*/ +/** \name Coffee port constants + * @{ + */ +/** Logical sector size */ +#ifdef COFFEE_CONF_SECTOR_SIZE +#define COFFEE_SECTOR_SIZE COFFEE_CONF_SECTOR_SIZE +#else +#define COFFEE_SECTOR_SIZE FLASH_PAGE_SIZE +#endif +/** Logical page size */ +#ifdef COFFEE_CONF_PAGE_SIZE +#define COFFEE_PAGE_SIZE COFFEE_CONF_PAGE_SIZE +#else +#define COFFEE_PAGE_SIZE (COFFEE_SECTOR_SIZE / 8) +#endif +/** Start offset of the file system */ +#ifdef COFFEE_CONF_START +#define COFFEE_START COFFEE_CONF_START +#else +#define COFFEE_START CC2538_DEV_FLASH_ADDR +#endif +/** Total size in bytes of the file system */ +#ifdef COFFEE_CONF_SIZE +#define COFFEE_SIZE COFFEE_CONF_SIZE +#else +#define COFFEE_SIZE 0 +#endif +/** Maximal filename length */ +#ifdef COFFEE_CONF_NAME_LENGTH +#define COFFEE_NAME_LENGTH COFFEE_CONF_NAME_LENGTH +#else +#define COFFEE_NAME_LENGTH 40 +#endif +/** Number of file cache entries */ +#ifdef COFFEE_CONF_MAX_OPEN_FILES +#define COFFEE_MAX_OPEN_FILES COFFEE_CONF_MAX_OPEN_FILES +#else +#define COFFEE_MAX_OPEN_FILES 5 +#endif +/** Number of file descriptor entries */ +#ifdef COFFEE_CONF_FD_SET_SIZE +#define COFFEE_FD_SET_SIZE COFFEE_CONF_FD_SET_SIZE +#else +#define COFFEE_FD_SET_SIZE 5 +#endif +/** Maximal amount of log table entries read in one batch */ +#ifdef COFFEE_CONF_LOG_TABLE_LIMIT +#define COFFEE_LOG_TABLE_LIMIT COFFEE_CONF_LOG_TABLE_LIMIT +#else +#define COFFEE_LOG_TABLE_LIMIT 16 +#endif +/** Default reserved file size */ +#ifdef COFFEE_CONF_DYN_SIZE +#define COFFEE_DYN_SIZE COFFEE_CONF_DYN_SIZE +#else +#define COFFEE_DYN_SIZE (COFFEE_SECTOR_SIZE - 50) +#endif +/** Default micro-log size */ +#ifdef COFFEE_CONF_LOG_SIZE +#define COFFEE_LOG_SIZE COFFEE_CONF_LOG_SIZE +#else +#define COFFEE_LOG_SIZE (4 * COFFEE_PAGE_SIZE) +#endif +/** Whether Coffee will use micro logs */ +#ifdef COFFEE_CONF_MICRO_LOGS +#define COFFEE_MICRO_LOGS COFFEE_CONF_MICRO_LOGS +#else +#define COFFEE_MICRO_LOGS 0 +#endif +/** Whether files are expected to be appended to only */ +#ifdef COFFEE_CONF_APPEND_ONLY +#define COFFEE_APPEND_ONLY COFFEE_CONF_APPEND_ONLY +#else +#define COFFEE_APPEND_ONLY 1 +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name Coffee port macros + * @{ + */ +/** Erase */ +#define COFFEE_ERASE(sector) \ + cfs_coffee_arch_erase(sector) +/** Write */ +#define COFFEE_WRITE(buf, size, offset) \ + cfs_coffee_arch_write((buf), (size), (offset)) +/** Read */ +#define COFFEE_READ(buf, size, offset) \ + cfs_coffee_arch_read((buf), (size), (offset)) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name Coffee port types + * @{ + */ +typedef int16_t coffee_page_t; /**< Page */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name Coffee port functions + * @{ + */ + +/** \brief Erases a device sector + * \param sector Sector to erase + */ +void cfs_coffee_arch_erase(uint16_t sector); + +/** \brief Writes a buffer to the device + * \param buf Pointer to the buffer + * \param size Byte size of the buffer + * \param offset Device offset to write to + */ +void cfs_coffee_arch_write(const void *buf, unsigned int size, + cfs_offset_t offset); + +/** \brief Reads from the device to a buffer + * \param buf Pointer to the buffer + * \param size Byte size of the buffer + * \param offset Device offset to read from + */ +void cfs_coffee_arch_read(void *buf, unsigned int size, cfs_offset_t offset); + +/** @} */ + +#endif /* COFFEE_CONF_CUSTOM_PORT */ +#endif /* CFS_COFFEE_ARCH_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/clock.c b/cpu/cc2538/clock.c index 98abdf2e3..953f06646 100644 --- a/cpu/cc2538/clock.c +++ b/cpu/cc2538/clock.c @@ -37,12 +37,12 @@ * Implementation of the clock module for the cc2538 * * To implement the clock functionality, we use the SysTick peripheral on the - * cortex-M3. We run the system clock at 16 MHz and we set the SysTick to give - * us 128 interrupts / sec. However, the Sleep Timer counter value is used for - * the number of elapsed ticks in order to avoid a significant time drift caused - * by PM1/2. Contrary to the Sleep Timer, the SysTick peripheral is indeed - * frozen during PM1/2, so adjusting upon wake-up a tick counter based on this - * peripheral would hardly be accurate. + * cortex-M3. We run the system clock at a configurable speed and set the + * SysTick to give us 128 interrupts / sec. However, the Sleep Timer counter + * value is used for the number of elapsed ticks in order to avoid a + * significant time drift caused by PM1/2. Contrary to the Sleep Timer, the + * SysTick peripheral is indeed frozen during PM1/2, so adjusting upon wake-up + * a tick counter based on this peripheral would hardly be accurate. * @{ * * \file @@ -62,7 +62,19 @@ #include /*---------------------------------------------------------------------------*/ #define RTIMER_CLOCK_TICK_RATIO (RTIMER_SECOND / CLOCK_SECOND) -#define RELOAD_VALUE (125000 - 1) /** Fire 128 times / sec */ + +/* Prescaler for GPT0:Timer A used for clock_delay_usec(). */ +#if SYS_CTRL_SYS_CLOCK < SYS_CTRL_1MHZ +#error System clock speeds below 1MHz are not supported +#endif +#define PRESCALER_VALUE (SYS_CTRL_SYS_CLOCK / SYS_CTRL_1MHZ - 1) + +/* Reload value for SysTick counter */ +#if SYS_CTRL_SYS_CLOCK % CLOCK_SECOND +/* Too low clock speeds will lead to reduced accurracy */ +#error System clock speed too slow for CLOCK_SECOND, accuracy reduced +#endif +#define RELOAD_VALUE (SYS_CTRL_SYS_CLOCK / CLOCK_SECOND - 1) static volatile uint64_t rt_ticks_startup = 0, rt_ticks_epoch = 0; /*---------------------------------------------------------------------------*/ @@ -74,8 +86,8 @@ static volatile uint64_t rt_ticks_startup = 0, rt_ticks_epoch = 0; * * We also initialise GPT0:Timer A, which is used by clock_delay_usec(). * We use 16-bit range (individual), count-down, one-shot, no interrupts. - * The system clock is at 16MHz giving us 62.5 nano sec ticks for Timer A. - * Prescaled by 16 gives us a very convenient 1 tick per usec + * The prescaler is computed according to the system clock in order to get 1 + * tick per usec. */ void clock_init(void) @@ -96,17 +108,16 @@ clock_init(void) REG(SYS_CTRL_RCGCGPT) |= SYS_CTRL_RCGCGPT_GPT0; /* Make sure GPT0 is off */ - REG(GPT_0_BASE | GPTIMER_CTL) = 0; - + REG(GPT_0_BASE + GPTIMER_CTL) = 0; /* 16-bit */ - REG(GPT_0_BASE | GPTIMER_CFG) = 0x04; + REG(GPT_0_BASE + GPTIMER_CFG) = 0x04; /* One-Shot, Count Down, No Interrupts */ - REG(GPT_0_BASE | GPTIMER_TAMR) = GPTIMER_TAMR_TAMR_ONE_SHOT; + REG(GPT_0_BASE + GPTIMER_TAMR) = GPTIMER_TAMR_TAMR_ONE_SHOT; - /* Prescale by 16 (thus, value 15 in TAPR) */ - REG(GPT_0_BASE | GPTIMER_TAPR) = 0x0F; + /* Prescale depending on system clock used */ + REG(GPT_0_BASE + GPTIMER_TAPR) = PRESCALER_VALUE; } /*---------------------------------------------------------------------------*/ CCIF clock_time_t @@ -136,20 +147,19 @@ clock_wait(clock_time_t i) while(clock_time() - start < (clock_time_t)i); } /*---------------------------------------------------------------------------*/ -/** - * \brief Arch-specific implementation of clock_delay_usec for the cc2538 - * \param len Delay \e len uSecs +/* + * Arch-specific implementation of clock_delay_usec for the cc2538 * * See clock_init() for GPT0 Timer A's configuration */ void -clock_delay_usec(uint16_t len) +clock_delay_usec(uint16_t dt) { - REG(GPT_0_BASE | GPTIMER_TAILR) = len; - REG(GPT_0_BASE | GPTIMER_CTL) |= GPTIMER_CTL_TAEN; + REG(GPT_0_BASE + GPTIMER_TAILR) = dt; + REG(GPT_0_BASE + GPTIMER_CTL) |= GPTIMER_CTL_TAEN; /* One-Shot mode: TAEN will be cleared when the timer reaches 0 */ - while(REG(GPT_0_BASE | GPTIMER_CTL) & GPTIMER_CTL_TAEN); + while(REG(GPT_0_BASE + GPTIMER_CTL) & GPTIMER_CTL_TAEN); } /*---------------------------------------------------------------------------*/ /** diff --git a/cpu/cc2538/cpu.h b/cpu/cc2538/cpu.h index e8cd7e282..51ffa9075 100644 --- a/cpu/cc2538/cpu.h +++ b/cpu/cc2538/cpu.h @@ -29,12 +29,21 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ /** - * \addtogroup cc2538 + * \addtogroup platform + * @{ + * + * \defgroup cc2538-platforms TI cc2538-powered platforms + * + * Documentation for all platforms powered by the TI cc2538 System-on-Chip + * @{ + * + * \defgroup cc2538 The TI cc2538 System-on-Chip + * CPU-Specific functionality - available to all cc2538-based platforms * @{ * * \defgroup cc2538-cpu cc2538 CPU * - * cc2538 CPU-specific functions for the cc2538 core + * CPU-specific functions for the cc2538 core * @{ * * \file @@ -60,6 +69,8 @@ unsigned long cpu_cpsie(void); #endif /* CPU_H_ */ /** + * @} + * @} * @} * @} */ diff --git a/cpu/cc2538/dbg.c b/cpu/cc2538/dbg.c index fd136436b..b97936feb 100644 --- a/cpu/cc2538/dbg.c +++ b/cpu/cc2538/dbg.c @@ -51,7 +51,7 @@ #define write_byte(b) usb_serial_writeb(b) #define flush() usb_serial_flush() #else -#define write_byte(b) uart_write_byte(b) +#define write_byte(b) uart_write_byte(DBG_CONF_UART, b) #define flush() #endif /*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2538/dbg.h b/cpu/cc2538/dbg.h index d861cadd7..2e283c0b1 100644 --- a/cpu/cc2538/dbg.h +++ b/cpu/cc2538/dbg.h @@ -34,7 +34,7 @@ * * \defgroup cc2538-char-io cc2538 Character I/O * - * cc2538 CPU-specific functions for debugging and SLIP I/O + * CPU-specific functions for debugging and SLIP I/O * * On the cc2538, character I/O can be directed over USB or UART. This is * controlled by a series of configuration directives: diff --git a/cpu/cc2538/dev/aes.c b/cpu/cc2538/dev/aes.c new file mode 100644 index 000000000..2b9e11a17 --- /dev/null +++ b/cpu/cc2538/dev/aes.c @@ -0,0 +1,330 @@ +/* + * Original file: + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2013, ADVANSEE - http://www.advansee.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-aes + * @{ + * + * \file + * Implementation of the cc2538 AES driver + */ +#include "contiki.h" +#include "dev/rom-util.h" +#include "dev/nvic.h" +#include "dev/aes.h" +#include "reg.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +uint8_t +aes_load_keys(const void *keys, uint8_t key_size, uint8_t count, + uint8_t start_area) +{ + uint32_t aes_key_store_size; + uint32_t areas; + uint64_t aligned_keys[AES_KEY_AREAS * 128 / 8 / sizeof(uint64_t)]; + int i; + + if(REG(AES_CTRL_ALG_SEL) != 0x00000000) { + return CRYPTO_RESOURCE_IN_USE; + } + + /* 192-bit keys must be padded to 256 bits */ + if(key_size == AES_KEY_STORE_SIZE_KEY_SIZE_192) { + for(i = 0; i < count; i++) { + rom_util_memcpy(&aligned_keys[i << 2], &((const uint64_t *)keys)[i * 3], + 192 / 8); + aligned_keys[(i << 2) + 3] = 0; + } + } + + /* Change count to the number of 128-bit key areas */ + if(key_size != AES_KEY_STORE_SIZE_KEY_SIZE_128) { + count <<= 1; + } + + /* The keys base address needs to be 4-byte aligned */ + if(key_size != AES_KEY_STORE_SIZE_KEY_SIZE_192) { + rom_util_memcpy(aligned_keys, keys, count << 4); + } + + /* Workaround for AES registers not retained after PM2 */ + REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL; + REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE | + AES_CTRL_INT_EN_RESULT_AV; + + /* Configure master control module */ + REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_KEYSTORE; + + /* Clear any outstanding events */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV; + + /* Configure key store module (areas, size) + * Note that writing AES_KEY_STORE_SIZE deletes all stored keys */ + aes_key_store_size = REG(AES_KEY_STORE_SIZE); + if((aes_key_store_size & AES_KEY_STORE_SIZE_KEY_SIZE_M) != key_size) { + REG(AES_KEY_STORE_SIZE) = (aes_key_store_size & + ~AES_KEY_STORE_SIZE_KEY_SIZE_M) | key_size; + } + + /* Free possibly already occupied key areas */ + areas = ((0x00000001 << count) - 1) << start_area; + REG(AES_KEY_STORE_WRITTEN_AREA) = areas; + + /* Enable key areas to write */ + REG(AES_KEY_STORE_WRITE_AREA) = areas; + + /* Configure DMAC + * Enable DMA channel 0 */ + REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN; + + /* Base address of the keys in ext. memory */ + REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)aligned_keys; + + /* Total keys length in bytes (e.g. 16 for 1 x 128-bit key) */ + REG(AES_DMAC_CH0_DMALENGTH) = (REG(AES_DMAC_CH0_DMALENGTH) & + ~AES_DMAC_CH_DMALENGTH_DMALEN_M) | + (count << (4 + AES_DMAC_CH_DMALENGTH_DMALEN_S)); + + /* Wait for operation to complete */ + while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV)); + + /* Check for absence of errors in DMA and key store */ + if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) { + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR; + /* Disable master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + return CRYPTO_DMA_BUS_ERROR; + } + if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_WR_ERR) { + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_KEY_ST_WR_ERR; + /* Disable master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + return AES_KEYSTORE_WRITE_ERROR; + } + + /* Acknowledge the interrupt */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV; + + /* Disable master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + + /* Check status, if error return error code */ + if((REG(AES_KEY_STORE_WRITTEN_AREA) & areas) != areas) { + return AES_KEYSTORE_WRITE_ERROR; + } + + return CRYPTO_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +aes_auth_crypt_start(uint32_t ctrl, uint8_t key_area, const void *iv, + const void *adata, uint16_t adata_len, + const void *data_in, void *data_out, uint16_t data_len, + struct process *process) +{ + if(REG(AES_CTRL_ALG_SEL) != 0x00000000) { + return CRYPTO_RESOURCE_IN_USE; + } + + /* Workaround for AES registers not retained after PM2 */ + REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL; + REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE | + AES_CTRL_INT_EN_RESULT_AV; + + REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_AES; + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV; + + REG(AES_KEY_STORE_READ_AREA) = key_area; + + /* Wait until key is loaded to the AES module */ + while(REG(AES_KEY_STORE_READ_AREA) & AES_KEY_STORE_READ_AREA_BUSY); + + /* Check for Key Store read error */ + if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_RD_ERR) { + /* Clear the Keystore Read error bit */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_KEY_ST_RD_ERR; + /* Disable the master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + return AES_KEYSTORE_READ_ERROR; + } + + if(iv != NULL) { + /* Write initialization vector */ + REG(AES_AES_IV_0) = ((const uint32_t *)iv)[0]; + REG(AES_AES_IV_1) = ((const uint32_t *)iv)[1]; + REG(AES_AES_IV_2) = ((const uint32_t *)iv)[2]; + REG(AES_AES_IV_3) = ((const uint32_t *)iv)[3]; + } + + /* Program AES authentication/crypto operation */ + REG(AES_AES_CTRL) = ctrl; + + /* Write the length of the payload block (lo) */ + REG(AES_AES_C_LENGTH_0) = data_len; + /* Write the length of the payload block (hi) */ + REG(AES_AES_C_LENGTH_1) = 0; + + /* For combined modes only (CCM or GCM) */ + if(ctrl & (AES_AES_CTRL_CCM | AES_AES_CTRL_GCM)) { + /* Write the length of the AAD data block (may be non-block size-aligned) */ + REG(AES_AES_AUTH_LENGTH) = adata_len; + + if(adata_len != 0) { + /* Configure DMAC to fetch the AAD data + * Enable DMA channel 0 */ + REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN; + /* Base address of the AAD data buffer */ + REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)adata; + /* AAD data length in bytes */ + REG(AES_DMAC_CH0_DMALENGTH) = adata_len; + + /* Wait for completion of the AAD data transfer, DMA_IN_DONE */ + while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_IN_DONE)); + + /* Check for the absence of error */ + if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) { + /* Clear the DMA error */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR; + /* Disable the master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + return CRYPTO_DMA_BUS_ERROR; + } + + /* Clear interrupt status */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE; + } + } + + /* Enable result available bit in interrupt enable */ + REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_RESULT_AV; + + if(process != NULL) { + crypto_register_process_notification(process); + nvic_interrupt_unpend(NVIC_INT_AES); + nvic_interrupt_enable(NVIC_INT_AES); + } + + if(data_len != 0) { + /* Configure DMAC + * Enable DMA channel 0 */ + REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN; + /* Base address of the input payload data buffer */ + REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)data_in; + /* Input payload data length in bytes */ + REG(AES_DMAC_CH0_DMALENGTH) = data_len; + + if(data_out != NULL) { + /* Enable DMA channel 1 */ + REG(AES_DMAC_CH1_CTRL) = AES_DMAC_CH_CTRL_EN; + /* Base address of the output payload data buffer */ + REG(AES_DMAC_CH1_EXTADDR) = (uint32_t)data_out; + /* Output payload data length in bytes */ + REG(AES_DMAC_CH1_DMALENGTH) = data_len; + } + } + + return CRYPTO_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +aes_auth_crypt_check_status(void) +{ + return !!(REG(AES_CTRL_INT_STAT) & + (AES_CTRL_INT_STAT_DMA_BUS_ERR | AES_CTRL_INT_STAT_KEY_ST_WR_ERR | + AES_CTRL_INT_STAT_KEY_ST_RD_ERR | AES_CTRL_INT_STAT_RESULT_AV)); +} +/*---------------------------------------------------------------------------*/ +uint8_t +aes_auth_crypt_get_result(void *iv, void *tag) +{ + uint32_t aes_ctrl_int_stat; + + aes_ctrl_int_stat = REG(AES_CTRL_INT_STAT); + /* Clear the error bits */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR | + AES_CTRL_INT_CLR_KEY_ST_WR_ERR | + AES_CTRL_INT_CLR_KEY_ST_RD_ERR; + + nvic_interrupt_disable(NVIC_INT_AES); + crypto_register_process_notification(NULL); + + /* Disable the master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + + if(aes_ctrl_int_stat & AES_CTRL_INT_STAT_DMA_BUS_ERR) { + return CRYPTO_DMA_BUS_ERROR; + } + if(aes_ctrl_int_stat & AES_CTRL_INT_STAT_KEY_ST_WR_ERR) { + return AES_KEYSTORE_WRITE_ERROR; + } + if(aes_ctrl_int_stat & AES_CTRL_INT_STAT_KEY_ST_RD_ERR) { + return AES_KEYSTORE_READ_ERROR; + } + + if(iv != NULL || tag != NULL) { + /* Read result + * Wait for the context ready bit */ + while(!(REG(AES_AES_CTRL) & AES_AES_CTRL_SAVED_CONTEXT_READY)); + + if(iv != NULL) { + /* Read the initialization vector registers */ + ((uint32_t *)iv)[0] = REG(AES_AES_IV_0); + ((uint32_t *)iv)[1] = REG(AES_AES_IV_1); + ((uint32_t *)iv)[2] = REG(AES_AES_IV_2); + ((uint32_t *)iv)[3] = REG(AES_AES_IV_3); + } + + if(tag != NULL) { + /* Read the tag registers */ + ((uint32_t *)tag)[0] = REG(AES_AES_TAG_OUT_0); + ((uint32_t *)tag)[1] = REG(AES_AES_TAG_OUT_1); + ((uint32_t *)tag)[2] = REG(AES_AES_TAG_OUT_2); + ((uint32_t *)tag)[3] = REG(AES_AES_TAG_OUT_3); + } + } + + /* Clear the interrupt status */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV; + + return CRYPTO_SUCCESS; +} + +/** @} */ diff --git a/cpu/cc2538/dev/aes.h b/cpu/cc2538/dev/aes.h new file mode 100644 index 000000000..19366e680 --- /dev/null +++ b/cpu/cc2538/dev/aes.h @@ -0,0 +1,544 @@ +/* + * Original file: + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2013, ADVANSEE - http://www.advansee.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-crypto + * @{ + * + * \defgroup cc2538-aes cc2538 AES + * + * Driver for the cc2538 AES modes of the security core + * @{ + * + * \file + * Header file for the cc2538 AES driver + */ +#ifndef AES_H_ +#define AES_H_ + +#include "contiki.h" +#include "dev/crypto.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/** \name AES register offsets + * @{ + */ +#define AES_DMAC_CH0_CTRL 0x4008B000 /**< Channel 0 control */ +#define AES_DMAC_CH0_EXTADDR 0x4008B004 /**< Channel 0 external address */ +#define AES_DMAC_CH0_DMALENGTH 0x4008B00C /**< Channel 0 DMA length */ +#define AES_DMAC_STATUS 0x4008B018 /**< DMAC status */ +#define AES_DMAC_SWRES 0x4008B01C /**< DMAC software reset */ +#define AES_DMAC_CH1_CTRL 0x4008B020 /**< Channel 1 control */ +#define AES_DMAC_CH1_EXTADDR 0x4008B024 /**< Channel 1 external address */ +#define AES_DMAC_CH1_DMALENGTH 0x4008B02C /**< Channel 1 DMA length */ +#define AES_DMAC_MST_RUNPARAMS 0x4008B078 /**< DMAC master run-time parameters */ +#define AES_DMAC_PERSR 0x4008B07C /**< DMAC port error raw status */ +#define AES_DMAC_OPTIONS 0x4008B0F8 /**< DMAC options */ +#define AES_DMAC_VERSION 0x4008B0FC /**< DMAC version */ +#define AES_KEY_STORE_WRITE_AREA \ + 0x4008B400 /**< Key store write area */ +#define AES_KEY_STORE_WRITTEN_AREA \ + 0x4008B404 /**< Key store written area */ +#define AES_KEY_STORE_SIZE 0x4008B408 /**< Key store size */ +#define AES_KEY_STORE_READ_AREA 0x4008B40C /**< Key store read area */ +#define AES_AES_KEY2_0 0x4008B500 /**< AES_KEY2_0 / AES_GHASH_H_IN_0 */ +#define AES_AES_KEY2_1 0x4008B504 /**< AES_KEY2_1 / AES_GHASH_H_IN_1 */ +#define AES_AES_KEY2_2 0x4008B508 /**< AES_KEY2_2 / AES_GHASH_H_IN_2 */ +#define AES_AES_KEY2_3 0x4008B50C /**< AES_KEY2_3 / AES_GHASH_H_IN_3 */ +#define AES_AES_KEY3_0 0x4008B510 /**< AES_KEY3_0 / AES_KEY2_4 */ +#define AES_AES_KEY3_1 0x4008B514 /**< AES_KEY3_1 / AES_KEY2_5 */ +#define AES_AES_KEY3_2 0x4008B518 /**< AES_KEY3_2 / AES_KEY2_6 */ +#define AES_AES_KEY3_3 0x4008B51C /**< AES_KEY3_3 / AES_KEY2_7 */ +#define AES_AES_IV_0 0x4008B540 /**< AES initialization vector */ +#define AES_AES_IV_1 0x4008B544 /**< AES initialization vector */ +#define AES_AES_IV_2 0x4008B548 /**< AES initialization vector */ +#define AES_AES_IV_3 0x4008B54C /**< AES initialization vector */ +#define AES_AES_CTRL 0x4008B550 /**< AES input/output buffer control and mode */ +#define AES_AES_C_LENGTH_0 0x4008B554 /**< AES crypto length (LSW) */ +#define AES_AES_C_LENGTH_1 0x4008B558 /**< AES crypto length (MSW) */ +#define AES_AES_AUTH_LENGTH 0x4008B55C /**< Authentication length */ +#define AES_AES_DATA_IN_OUT_0 0x4008B560 /**< Data input/output */ +#define AES_AES_DATA_IN_OUT_1 0x4008B564 /**< Data Input/Output */ +#define AES_AES_DATA_IN_OUT_2 0x4008B568 /**< Data Input/Output */ +#define AES_AES_DATA_IN_OUT_3 0x4008B56C /**< Data Input/Output */ +#define AES_AES_TAG_OUT_0 0x4008B570 /**< TAG */ +#define AES_AES_TAG_OUT_1 0x4008B574 /**< TAG */ +#define AES_AES_TAG_OUT_2 0x4008B578 /**< TAG */ +#define AES_AES_TAG_OUT_3 0x4008B57C /**< TAG */ +#define AES_HASH_DATA_IN_0 0x4008B600 /**< HASH data input */ +#define AES_HASH_DATA_IN_1 0x4008B604 /**< HASH data input */ +#define AES_HASH_DATA_IN_2 0x4008B608 /**< HASH data input */ +#define AES_HASH_DATA_IN_3 0x4008B60C /**< HASH data input */ +#define AES_HASH_DATA_IN_4 0x4008B610 /**< HASH data input */ +#define AES_HASH_DATA_IN_5 0x4008B614 /**< HASH data input */ +#define AES_HASH_DATA_IN_6 0x4008B618 /**< HASH data input */ +#define AES_HASH_DATA_IN_7 0x4008B61C /**< HASH data input */ +#define AES_HASH_DATA_IN_8 0x4008B620 /**< HASH data input */ +#define AES_HASH_DATA_IN_9 0x4008B624 /**< HASH data input */ +#define AES_HASH_DATA_IN_10 0x4008B628 /**< HASH data input */ +#define AES_HASH_DATA_IN_11 0x4008B62C /**< HASH data input */ +#define AES_HASH_DATA_IN_12 0x4008B630 /**< HASH data input */ +#define AES_HASH_DATA_IN_13 0x4008B634 /**< HASH data input */ +#define AES_HASH_DATA_IN_14 0x4008B638 /**< HASH data input */ +#define AES_HASH_DATA_IN_15 0x4008B63C /**< HASH data input */ +#define AES_HASH_IO_BUF_CTRL 0x4008B640 /**< Input/output buffer control and status */ +#define AES_HASH_MODE_IN 0x4008B644 /**< Hash mode */ +#define AES_HASH_LENGTH_IN_L 0x4008B648 /**< Hash length */ +#define AES_HASH_LENGTH_IN_H 0x4008B64C /**< Hash length */ +#define AES_HASH_DIGEST_A 0x4008B650 /**< Hash digest */ +#define AES_HASH_DIGEST_B 0x4008B654 /**< Hash digest */ +#define AES_HASH_DIGEST_C 0x4008B658 /**< Hash digest */ +#define AES_HASH_DIGEST_D 0x4008B65C /**< Hash digest */ +#define AES_HASH_DIGEST_E 0x4008B660 /**< Hash digest */ +#define AES_HASH_DIGEST_F 0x4008B664 /**< Hash digest */ +#define AES_HASH_DIGEST_G 0x4008B668 /**< Hash digest */ +#define AES_HASH_DIGEST_H 0x4008B66C /**< Hash digest */ +#define AES_CTRL_ALG_SEL 0x4008B700 /**< Algorithm select */ +#define AES_CTRL_PROT_EN 0x4008B704 /**< Master PROT privileged access enable */ +#define AES_CTRL_SW_RESET 0x4008B740 /**< Software reset */ +#define AES_CTRL_INT_CFG 0x4008B780 /**< Interrupt configuration */ +#define AES_CTRL_INT_EN 0x4008B784 /**< Interrupt enable */ +#define AES_CTRL_INT_CLR 0x4008B788 /**< Interrupt clear */ +#define AES_CTRL_INT_SET 0x4008B78C /**< Interrupt set */ +#define AES_CTRL_INT_STAT 0x4008B790 /**< Interrupt status */ +#define AES_CTRL_OPTIONS 0x4008B7F8 /**< Options */ +#define AES_CTRL_VERSION 0x4008B7FC /**< Version */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_DMAC_CHx_CTRL registers bit fields + * @{ + */ +#define AES_DMAC_CH_CTRL_PRIO 0x00000002 /**< Channel priority 0: Low 1: High */ +#define AES_DMAC_CH_CTRL_EN 0x00000001 /**< Channel enable */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_DMAC_CHx_DMALENGTH registers bit fields + * @{ + */ +#define AES_DMAC_CH_DMALENGTH_DMALEN_M \ + 0x0000FFFF /**< Channel DMA length in bytes mask */ +#define AES_DMAC_CH_DMALENGTH_DMALEN_S 0 /**< Channel DMA length in bytes shift */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_DMAC_STATUS register bit fields + * @{ + */ +#define AES_DMAC_STATUS_PORT_ERR \ + 0x00020000 /**< AHB port transfer errors */ +#define AES_DMAC_STATUS_CH1_ACT 0x00000002 /**< Channel 1 active (DMA transfer on-going) */ +#define AES_DMAC_STATUS_CH0_ACT 0x00000001 /**< Channel 0 active (DMA transfer on-going) */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_DMAC_SWRES register bit fields + * @{ + */ +#define AES_DMAC_SWRES_SWRES 0x00000001 /**< Software reset enable */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_DMAC_MST_RUNPARAMS register bit fields + * @{ + */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_4 \ + (2 << 12) /**< Maximum burst size: 4 bytes */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_8 \ + (3 << 12) /**< Maximum burst size: 8 bytes */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_16 \ + (4 << 12) /**< Maximum burst size: 16 bytes */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_32 \ + (5 << 12) /**< Maximum burst size: 32 bytes */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_64 \ + (6 << 12) /**< Maximum burst size: 64 bytes */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_M \ + 0x0000F000 /**< Maximum burst size mask */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_S \ + 12 /**< Maximum burst size shift */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_IDLE_EN \ + 0x00000800 /**< Idle insertion between bursts */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_INCR_EN \ + 0x00000400 /**< Fixed-length burst or single transfers */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_LOCK_EN \ + 0x00000200 /**< Locked transfers */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BIGEND \ + 0x00000100 /**< Big endian AHB master */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_DMAC_PERSR register bit fields + * @{ + */ +#define AES_DMAC_PERSR_PORT1_AHB_ERROR \ + 0x00001000 /**< AHB bus error */ +#define AES_DMAC_PERSR_PORT1_CHANNEL \ + 0x00000200 /**< Last serviced channel (0 or 1) */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_DMAC_OPTIONS register bit fields + * @{ + */ +#define AES_DMAC_OPTIONS_NR_OF_CHANNELS_M \ + 0x00000F00 /**< Number of channels implemented mask */ +#define AES_DMAC_OPTIONS_NR_OF_CHANNELS_S \ + 8 /**< Number of channels implemented shift */ +#define AES_DMAC_OPTIONS_NR_OF_PORTS_M \ + 0x00000007 /**< Number of ports implemented mask */ +#define AES_DMAC_OPTIONS_NR_OF_PORTS_S 0 /**< Number of ports implemented shift */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_DMAC_VERSION register bit fields + * @{ + */ +#define AES_DMAC_VERSION_HW_MAJOR_VERSION_M \ + 0x0F000000 /**< Major version number mask */ +#define AES_DMAC_VERSION_HW_MAJOR_VERSION_S \ + 24 /**< Major version number shift */ +#define AES_DMAC_VERSION_HW_MINOR_VERSION_M \ + 0x00F00000 /**< Minor version number mask */ +#define AES_DMAC_VERSION_HW_MINOR_VERSION_S \ + 20 /**< Minor version number shift */ +#define AES_DMAC_VERSION_HW_PATCH_LEVEL_M \ + 0x000F0000 /**< Patch level mask */ +#define AES_DMAC_VERSION_HW_PATCH_LEVEL_S \ + 16 /**< Patch level shift */ +#define AES_DMAC_VERSION_EIP_NUMBER_COMPL_M \ + 0x0000FF00 /**< EIP_NUMBER 1's complement mask */ +#define AES_DMAC_VERSION_EIP_NUMBER_COMPL_S \ + 8 /**< EIP_NUMBER 1's complement shift */ +#define AES_DMAC_VERSION_EIP_NUMBER_M \ + 0x000000FF /**< DMAC EIP-number mask */ +#define AES_DMAC_VERSION_EIP_NUMBER_S 0 /**< DMAC EIP-number shift */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_KEY_STORE_SIZE register bit fields + * @{ + */ +#define AES_KEY_STORE_SIZE_KEY_SIZE_128 1 /**< Key size: 128 bits */ +#define AES_KEY_STORE_SIZE_KEY_SIZE_192 2 /**< Key size: 192 bits */ +#define AES_KEY_STORE_SIZE_KEY_SIZE_256 3 /**< Key size: 256 bits */ +#define AES_KEY_STORE_SIZE_KEY_SIZE_M \ + 0x00000003 /**< Key size mask */ +#define AES_KEY_STORE_SIZE_KEY_SIZE_S 0 /**< Key size shift */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_KEY_STORE_READ_AREA register bit fields + * @{ + */ +#define AES_KEY_STORE_READ_AREA_BUSY \ + 0x80000000 /**< Key store operation busy */ +#define AES_KEY_STORE_READ_AREA_RAM_AREA_M \ + 0x0000000F /**< Key store RAM area select mask */ +#define AES_KEY_STORE_READ_AREA_RAM_AREA_S \ + 0 /**< Key store RAM area select shift */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_AES_CTRL register bit fields + * @{ + */ +#define AES_AES_CTRL_CONTEXT_READY \ + 0x80000000 /**< Context data registers can be overwritten */ +#define AES_AES_CTRL_SAVED_CONTEXT_READY \ + 0x40000000 /**< AES auth. TAG and/or IV block(s) available */ +#define AES_AES_CTRL_SAVE_CONTEXT \ + 0x20000000 /**< Auth. TAG or result IV needs to be stored */ +#define AES_AES_CTRL_CCM_M_M 0x01C00000 /**< CCM auth. field length mask */ +#define AES_AES_CTRL_CCM_M_S 22 /**< CCM auth. field length shift */ +#define AES_AES_CTRL_CCM_L_M 0x00380000 /**< CCM length field width mask */ +#define AES_AES_CTRL_CCM_L_S 19 /**< CCM length field width shift */ +#define AES_AES_CTRL_CCM 0x00040000 /**< AES-CCM mode */ +#define AES_AES_CTRL_GCM 0x00030000 /**< AES-GCM mode */ +#define AES_AES_CTRL_CBC_MAC 0x00008000 /**< AES-CBC MAC mode */ +#define AES_AES_CTRL_CTR_WIDTH_32 (0 << 7) /**< CTR counter width: 32 bits */ +#define AES_AES_CTRL_CTR_WIDTH_64 (1 << 7) /**< CTR counter width: 64 bits */ +#define AES_AES_CTRL_CTR_WIDTH_96 (2 << 7) /**< CTR counter width: 96 bits */ +#define AES_AES_CTRL_CTR_WIDTH_128 \ + (3 << 7) /**< CTR counter width: 128 bits */ +#define AES_AES_CTRL_CTR_WIDTH_M \ + 0x00000180 /**< CTR counter width mask */ +#define AES_AES_CTRL_CTR_WIDTH_S 7 /**< CTR counter width shift */ +#define AES_AES_CTRL_CTR 0x00000040 /**< AES-CTR mode */ +#define AES_AES_CTRL_CBC 0x00000020 /**< AES-CBC mode */ +#define AES_AES_CTRL_KEY_SIZE_128 (1 << 3) /**< Key size: 128 bits */ +#define AES_AES_CTRL_KEY_SIZE_192 (2 << 3) /**< Key size: 192 bits */ +#define AES_AES_CTRL_KEY_SIZE_256 (3 << 3) /**< Key size: 256 bits */ +#define AES_AES_CTRL_KEY_SIZE_M 0x00000018 /**< Key size mask */ +#define AES_AES_CTRL_KEY_SIZE_S 3 /**< Key size shift */ +#define AES_AES_CTRL_DIRECTION_ENCRYPT \ + 0x00000004 /**< Encrypt */ +#define AES_AES_CTRL_INPUT_READY \ + 0x00000002 /**< AES input buffer empty */ +#define AES_AES_CTRL_OUTPUT_READY \ + 0x00000001 /**< AES output block available */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_AES_C_LENGTH_1 register bit fields + * @{ + */ +#define AES_AES_C_LENGTH_1_C_LENGTH_M \ + 0x1FFFFFFF /**< Crypto length bits [60:32] mask */ +#define AES_AES_C_LENGTH_1_C_LENGTH_S 0 /**< Crypto length bits [60:32] shift */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_HASH_IO_BUF_CTRL register bit fields + * @{ + */ +#define AES_HASH_IO_BUF_CTRL_PAD_DMA_MESSAGE \ + 0x00000080 /**< Hash engine message padding required */ +#define AES_HASH_IO_BUF_CTRL_GET_DIGEST \ + 0x00000040 /**< Hash engine digest requested */ +#define AES_HASH_IO_BUF_CTRL_PAD_MESSAGE \ + 0x00000020 /**< Last message data in HASH_DATA_IN, apply hash padding */ +#define AES_HASH_IO_BUF_CTRL_RFD_IN \ + 0x00000004 /**< Hash engine input buffer can accept new data */ +#define AES_HASH_IO_BUF_CTRL_DATA_IN_AV \ + 0x00000002 /**< Start processing HASH_DATA_IN data */ +#define AES_HASH_IO_BUF_CTRL_OUTPUT_FULL \ + 0x00000001 /**< Output buffer registers available */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_HASH_MODE_IN register bit fields + * @{ + */ +#define AES_HASH_MODE_IN_SHA256_MODE \ + 0x00000008 /**< Hash mode */ +#define AES_HASH_MODE_IN_NEW_HASH \ + 0x00000001 /**< New hash session */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_ALG_SEL register bit fields + * @{ + */ +#define AES_CTRL_ALG_SEL_TAG 0x80000000 /**< DMA operation includes TAG */ +#define AES_CTRL_ALG_SEL_HASH 0x00000004 /**< Select hash engine as DMA destination */ +#define AES_CTRL_ALG_SEL_AES 0x00000002 /**< Select AES engine as DMA source/destination */ +#define AES_CTRL_ALG_SEL_KEYSTORE \ + 0x00000001 /**< Select Key Store as DMA destination */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_PROT_EN register bit fields + * @{ + */ +#define AES_CTRL_PROT_EN_PROT_EN \ + 0x00000001 /**< m_h_prot[1] asserted for DMA reads towards key store */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_SW_RESET register bit fields + * @{ + */ +#define AES_CTRL_SW_RESET_SW_RESET \ + 0x00000001 /**< Reset master control and key store */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_INT_CFG register bit fields + * @{ + */ +#define AES_CTRL_INT_CFG_LEVEL 0x00000001 /**< Level interrupt type */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_INT_EN register bit fields + * @{ + */ +#define AES_CTRL_INT_EN_DMA_IN_DONE \ + 0x00000002 /**< DMA input done interrupt enabled */ +#define AES_CTRL_INT_EN_RESULT_AV \ + 0x00000001 /**< Result available interrupt enabled */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_INT_CLR register bit fields + * @{ + */ +#define AES_CTRL_INT_CLR_DMA_BUS_ERR \ + 0x80000000 /**< Clear DMA bus error status */ +#define AES_CTRL_INT_CLR_KEY_ST_WR_ERR \ + 0x40000000 /**< Clear key store write error status */ +#define AES_CTRL_INT_CLR_KEY_ST_RD_ERR \ + 0x20000000 /**< Clear key store read error status */ +#define AES_CTRL_INT_CLR_DMA_IN_DONE \ + 0x00000002 /**< Clear DMA in done interrupt */ +#define AES_CTRL_INT_CLR_RESULT_AV \ + 0x00000001 /**< Clear result available interrupt */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_INT_SET register bit fields + * @{ + */ +#define AES_CTRL_INT_SET_DMA_IN_DONE \ + 0x00000002 /**< Set DMA data in done interrupt */ +#define AES_CTRL_INT_SET_RESULT_AV \ + 0x00000001 /**< Set result available interrupt */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_INT_STAT register bit fields + * @{ + */ +#define AES_CTRL_INT_STAT_DMA_BUS_ERR \ + 0x80000000 /**< DMA bus error detected */ +#define AES_CTRL_INT_STAT_KEY_ST_WR_ERR \ + 0x40000000 /**< Write error detected */ +#define AES_CTRL_INT_STAT_KEY_ST_RD_ERR \ + 0x20000000 /**< Read error detected */ +#define AES_CTRL_INT_STAT_DMA_IN_DONE \ + 0x00000002 /**< DMA data in done interrupt status */ +#define AES_CTRL_INT_STAT_RESULT_AV \ + 0x00000001 /**< Result available interrupt status */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_OPTIONS register bit fields + * @{ + */ +#define AES_CTRL_OPTIONS_TYPE_M 0xFF000000 /**< Device type mask */ +#define AES_CTRL_OPTIONS_TYPE_S 24 /**< Device type shift */ +#define AES_CTRL_OPTIONS_AHBINTERFACE \ + 0x00010000 /**< AHB interface available */ +#define AES_CTRL_OPTIONS_SHA_256 \ + 0x00000100 /**< The HASH core supports SHA-256 */ +#define AES_CTRL_OPTIONS_AES_CCM \ + 0x00000080 /**< AES-CCM available as single operation */ +#define AES_CTRL_OPTIONS_AES_GCM \ + 0x00000040 /**< AES-GCM available as single operation */ +#define AES_CTRL_OPTIONS_AES_256 \ + 0x00000020 /**< AES core supports 256-bit keys */ +#define AES_CTRL_OPTIONS_AES_128 \ + 0x00000010 /**< AES core supports 128-bit keys */ +#define AES_CTRL_OPTIONS_HASH 0x00000004 /**< HASH Core available */ +#define AES_CTRL_OPTIONS_AES 0x00000002 /**< AES core available */ +#define AES_CTRL_OPTIONS_KEYSTORE \ + 0x00000001 /**< KEY STORE available */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_VERSION register bit fields + * @{ + */ +#define AES_CTRL_VERSION_MAJOR_VERSION_M \ + 0x0F000000 /**< Major version number mask */ +#define AES_CTRL_VERSION_MAJOR_VERSION_S \ + 24 /**< Major version number shift */ +#define AES_CTRL_VERSION_MINOR_VERSION_M \ + 0x00F00000 /**< Minor version number mask */ +#define AES_CTRL_VERSION_MINOR_VERSION_S \ + 20 /**< Minor version number shift */ +#define AES_CTRL_VERSION_PATCH_LEVEL_M \ + 0x000F0000 /**< Patch level mask */ +#define AES_CTRL_VERSION_PATCH_LEVEL_S 16 /**< Patch level shift */ +#define AES_CTRL_VERSION_EIP_NUMBER_COMPL_M \ + 0x0000FF00 /**< EIP_NUMBER 1's complement mask */ +#define AES_CTRL_VERSION_EIP_NUMBER_COMPL_S \ + 8 /**< EIP_NUMBER 1's complement shift */ +#define AES_CTRL_VERSION_EIP_NUMBER_M \ + 0x000000FF /**< EIP-120t EIP-number mask */ +#define AES_CTRL_VERSION_EIP_NUMBER_S 0 /**< EIP-120t EIP-number shift */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES drivers return codes + * @{ + */ +#define AES_KEYSTORE_READ_ERROR 5 +#define AES_KEYSTORE_WRITE_ERROR 6 +#define AES_AUTHENTICATION_FAILED 7 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES constants + * @{ + */ +#define AES_KEY_AREAS 8 +#define AES_BLOCK_LEN (128 / 8) +#define AES_IV_LEN AES_BLOCK_LEN +#define AES_TAG_LEN AES_BLOCK_LEN +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES functions + * @{ + */ + +/** \brief Writes keys into the Key RAM + * \param keys Pointer to AES Keys + * \param key_size Key size: \c AES_KEY_STORE_SIZE_KEY_SIZE_x + * \param count Number of keys (1 to \c AES_KEY_AREAS - \p start_area for + * 128-bit keys, 1 to (\c AES_KEY_AREAS - \p start_area) / 2 for 192- and + * 256-bit keys) + * \param start_area Start area in Key RAM where to store the keys (0 to + * \c AES_KEY_AREAS - 1, must be even for 192- and 256-bit keys) + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES error code + * \note Calling this function with a value of \p key_size different from the + * one passed for the previous calls causes the deletion of all previously + * stored keys. + */ +uint8_t aes_load_keys(const void *keys, uint8_t key_size, uint8_t count, + uint8_t start_area); + +/** \brief Starts an AES authentication/crypto operation + * \param ctrl Contents of the \c AES_AES_CTRL register + * \param key_area Area in Key RAM where the key is stored (0 to + * \c AES_KEY_AREAS - 1) + * \param iv Pointer to 128-bit initialization vector, or \c NULL + * \param adata Pointer to additional authenticated data in SRAM, or \c NULL + * \param adata_len Length of additional authenticated data in octets, or \c 0 + * \param data_in Pointer to input payload data in SRAM, or \c NULL + * \param data_out Pointer to output payload data in SRAM (may be \p data_in), + * or \c NULL + * \param data_len Length of payload data in octets, or \c 0 + * \param process Process to be polled upon completion of the operation, or + * \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES error code + * \note This function is only supposed to be called by the AES drivers. + */ +uint8_t aes_auth_crypt_start(uint32_t ctrl, uint8_t key_area, const void *iv, + const void *adata, uint16_t adata_len, + const void *data_in, void *data_out, + uint16_t data_len, struct process *process); + +/** \brief Checks the status of the AES authentication/crypto operation + * \retval false Result not yet available, and no error occurred + * \retval true Result available, or error occurred + * \note This function is only supposed to be called by the AES drivers. + */ +uint8_t aes_auth_crypt_check_status(void); + +/** \brief Gets the result of the AES authentication/crypto operation + * \param iv Pointer to 128-bit result initialization vector, or \c NULL + * \param tag Pointer to 128-bit result tag, or \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES error code + * \note This function must be called only after \c aes_auth_crypt_start(). + * \note This function is only supposed to be called by the AES drivers. + */ +uint8_t aes_auth_crypt_get_result(void *iv, void *tag); + +/** @} */ + +#endif /* AES_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/ana-regs.h b/cpu/cc2538/dev/ana-regs.h index 1fb8496fa..e8f84a46a 100644 --- a/cpu/cc2538/dev/ana-regs.h +++ b/cpu/cc2538/dev/ana-regs.h @@ -43,7 +43,7 @@ * \name ANA_REGS register offsets * @{ */ -#define ANA_REGS_IVCTRL 0x00000004 +#define ANA_REGS_IVCTRL 0x400D6004 /** @} */ /*---------------------------------------------------------------------------*/ /** diff --git a/cpu/cc2538/dev/bignum-driver.c b/cpu/cc2538/dev/bignum-driver.c new file mode 100644 index 000000000..57c667e01 --- /dev/null +++ b/cpu/cc2538/dev/bignum-driver.c @@ -0,0 +1,1064 @@ +/* + * Original file: + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Authors: Andreas Dröscher + * Hu Luo + * Hossein Shafagh + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-bignum + * @{ + * + * \file + * Implementation of the cc2538 BigNum driver + * + * bignum_subtract_start bignum_subtract_get_result (subtraction) + * bignum_add_start bignum_add_get_result (addition) + * bignum_mod_start bignum_mod_get_result (modulo) + * bignum_exp_mod_start bignum_exp_mod_get_result (modular exponentiation operation) + * bignum_inv_mod_start bignum_inv_mod_get_result (inverse modulo operation) + * bignum_mul_start bignum_mul_get_result (multiplication) + * bignum_divide_start bignum_divide_get_result (division) + * bignum_cmp_start bignum_cmp_get_result (comparison) + */ +#include "dev/bignum-driver.h" + +#include + +#include "reg.h" +#include "dev/nvic.h" + +#define ASSERT(IF) if(!(IF)) { return PKA_STATUS_INVALID_PARAM; } + +/*---------------------------------------------------------------------------*/ +uint8_t +bignum_mod_start(const uint32_t *number, + const uint8_t number_size, + const uint32_t *modulus, + const uint8_t modulus_size, + uint32_t *result_vector, + struct process *process) +{ + + uint8_t extraBuf; + uint32_t offset; + int i; + + /* Check the arguments. */ + ASSERT(NULL != number); + ASSERT(NULL != modulus); + ASSERT(NULL != result_vector); + + /* make sure no operation is in progress. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* calculate the extra buffer requirement. */ + extraBuf = 2 + modulus_size % 2; + + offset = 0; + + /* Update the A ptr with the offset address of the PKA RAM location + * where the number will be stored. */ + REG(PKA_APTR) = offset >> 2; + + /* Load the number in PKA RAM */ + for(i = 0; i < number_size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = number[i]; + } + + /* determine the offset for the next data input. */ + offset += 4 * (i + number_size % 2); + + /* Update the B ptr with the offset address of the PKA RAM location + * where the divisor will be stored. */ + REG(PKA_BPTR) = offset >> 2; + + /* Load the divisor in PKA RAM. */ + for(i = 0; i < modulus_size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = modulus[i]; + } + + /* determine the offset for the next data. */ + offset += 4 * (i + extraBuf); + + /* Copy the result vector address location. */ + *result_vector = PKA_RAM_BASE + offset; + + /* Load C ptr with the result location in PKA RAM */ + REG(PKA_CPTR) = offset >> 2; + + /* Load A length registers with Big number length in 32 bit words. */ + REG(PKA_ALENGTH) = number_size; + + /* Load B length registers Divisor length in 32-bit words. */ + REG(PKA_BLENGTH) = modulus_size; + + /* Start the PKCP modulo operation by setting the PKA Function register. */ + REG(PKA_FUNCTION) = (PKA_FUNCTION_RUN | PKA_FUNCTION_MODULO); + + /* Enable Interrupt */ + if(process != NULL) { + pka_register_process_notification(process); + nvic_interrupt_unpend(NVIC_INT_PKA); + nvic_interrupt_enable(NVIC_INT_PKA); + } + + return PKA_STATUS_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +bignum_mod_get_result(uint32_t *buffer, + const uint8_t buffer_size, + const uint32_t result_vector) +{ + + uint32_t regMSWVal; + uint32_t len; + int i; + + /* Check the arguments. */ + ASSERT(NULL != buffer); + ASSERT(result_vector > PKA_RAM_BASE); + ASSERT(result_vector < (PKA_RAM_BASE + PKA_RAM_SIZE)); + + /* verify that the operation is complete. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Disable Interrupt */ + nvic_interrupt_disable(NVIC_INT_PKA); + pka_register_process_notification(NULL); + + /* Get the MSW register value. */ + regMSWVal = REG(PKA_DIVMSW); + + /* Check to make sure that the result vector is not all zeroes. */ + if(regMSWVal & PKA_DIVMSW_RESULT_IS_ZERO) { + return PKA_STATUS_RESULT_0; + } + + /* Get the length of the result. */ + len = ((regMSWVal & PKA_DIVMSW_MSW_ADDRESS_M) + 1) + - ((result_vector - PKA_RAM_BASE) >> 2); + + /* If the size of the buffer provided is less than the result length than + * return error. */ + if(buffer_size < len) { + return PKA_STATUS_BUF_UNDERFLOW; + } + /* copy the result from vector C into the pResult. */ + for(i = 0; i < len; i++) { + buffer[i] = REG(result_vector + 4 * i); + } + + return PKA_STATUS_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +bignum_cmp_start(const uint32_t *number1, + const uint32_t *number2, + const uint8_t size, + struct process *process) +{ + + uint32_t offset; + int i; + + /* Check the arguments. */ + ASSERT(NULL != number1); + ASSERT(NULL != number2); + + offset = 0; + + /* Make sure no operation is in progress. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Update the A ptr with the offset address of the PKA RAM location + * where the first big number will be stored. */ + REG(PKA_APTR) = offset >> 2; + + /* Load the first big number in PKA RAM. */ + for(i = 0; i < size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = number1[i]; + } + + /* Determine the offset in PKA RAM for the next pointer. */ + offset += 4 * (i + size % 2); + + /* Update the B ptr with the offset address of the PKA RAM location + * where the second big number will be stored. */ + REG(PKA_BPTR) = offset >> 2; + + /* Load the second big number in PKA RAM. */ + for(i = 0; i < size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = number2[i]; + } + + /* Load length registers in 32 bit word size. */ + REG(PKA_ALENGTH) = size; + + /* Set the PKA Function register for the compare operation + * and start the operation. */ + REG(PKA_FUNCTION) = (PKA_FUNCTION_RUN | PKA_FUNCTION_COMPARE); + + /* Enable Interrupt */ + if(process != NULL) { + pka_register_process_notification(process); + nvic_interrupt_unpend(NVIC_INT_PKA); + nvic_interrupt_enable(NVIC_INT_PKA); + } + + return PKA_STATUS_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +bignum_cmp_get_result(void) +{ + uint8_t status; + + /* verify that the operation is complete. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + status = PKA_STATUS_OPERATION_INPRG; + return status; + } + + /* Disable Interrupt */ + nvic_interrupt_disable(NVIC_INT_PKA); + pka_register_process_notification(NULL); + + /* Check the compare register. */ + switch(REG(PKA_COMPARE)) { + case PKA_COMPARE_A_EQUALS_B: + status = PKA_STATUS_SUCCESS; + break; + + case PKA_COMPARE_A_GREATER_THAN_B: + status = PKA_STATUS_A_GR_B; + break; + + case PKA_COMPARE_A_LESS_THAN_B: + status = PKA_STATUS_A_LT_B; + break; + + default: + status = PKA_STATUS_FAILURE; + break; + } + + return status; +} +/*---------------------------------------------------------------------------*/ +uint8_t +bignum_inv_mod_start(const uint32_t *number, + const uint8_t number_size, + const uint32_t *modulus, + const uint8_t modulus_size, + uint32_t *result_vector, + struct process *process) +{ + + uint32_t offset; + int i; + + /* Check the arguments. */ + ASSERT(NULL != number); + ASSERT(NULL != modulus); + ASSERT(NULL != result_vector); + + offset = 0; + + /* Make sure no operation is in progress. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Update the A ptr with the offset address of the PKA RAM location + * where the number will be stored. */ + REG(PKA_APTR) = offset >> 2; + + /* Load the \e number number in PKA RAM. */ + for(i = 0; i < number_size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = number[i]; + } + + /* Determine the offset for next data. */ + offset += 4 * (i + number_size % 2); + + /* Update the B ptr with the offset address of the PKA RAM location + * where the modulus will be stored. */ + REG(PKA_BPTR) = offset >> 2; + + /* Load the \e modulus divisor in PKA RAM. */ + for(i = 0; i < modulus_size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = modulus[i]; + } + + /* Determine the offset for result data. */ + offset += 4 * (i + modulus_size % 2); + + /* Copy the result vector address location. */ + *result_vector = PKA_RAM_BASE + offset; + + /* Load D ptr with the result location in PKA RAM. */ + REG(PKA_DPTR) = offset >> 2; + + /* Load the respective length registers. */ + REG(PKA_ALENGTH) = number_size; + REG(PKA_BLENGTH) = modulus_size; + + /* set the PKA function to InvMod operation and the start the operation. */ + REG(PKA_FUNCTION) = 0x0000F000; + + /* Enable Interrupt */ + if(process != NULL) { + pka_register_process_notification(process); + nvic_interrupt_unpend(NVIC_INT_PKA); + nvic_interrupt_enable(NVIC_INT_PKA); + } + + return PKA_STATUS_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +bignum_inv_mod_get_result(uint32_t *buffer, + const uint8_t buffer_size, + const uint32_t result_vector) +{ + + uint32_t regMSWVal; + uint32_t len; + int i; + + /* Check the arguments. */ + ASSERT(NULL != buffer); + ASSERT(result_vector > PKA_RAM_BASE); + ASSERT(result_vector < (PKA_RAM_BASE + PKA_RAM_SIZE)); + + /* Verify that the operation is complete. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Disable Interrupt */ + nvic_interrupt_disable(NVIC_INT_PKA); + pka_register_process_notification(NULL); + + /* Get the MSW register value. */ + regMSWVal = REG(PKA_MSW); + + /* Check to make sure that the result vector is not all zeroes. */ + if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) { + return PKA_STATUS_RESULT_0; + } + + /* Get the length of the result */ + len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1) + - ((result_vector - PKA_RAM_BASE) >> 2); + + /* Check if the provided buffer length is adequate to store the result + * data. */ + if(buffer_size < len) { + return PKA_STATUS_BUF_UNDERFLOW; + } + + /* Copy the result from vector C into the \e buffer. */ + for(i = 0; i < len; i++) { + buffer[i] = REG(result_vector + 4 * i); + } + + return PKA_STATUS_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +bignum_mul_start(const uint32_t *multiplicand, + const uint8_t multiplicand_size, + const uint32_t *multiplier, + const uint8_t multiplier_size, + uint32_t *result_vector, + struct process *process) +{ + + uint32_t offset; + int i; + + /* Check for the arguments. */ + ASSERT(NULL != multiplicand); + ASSERT(NULL != multiplier); + ASSERT(NULL != result_vector); + + offset = 0; + + /* Make sure no operation is in progress. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Update the A ptr with the offset address of the PKA RAM location + * where the multiplicand will be stored. */ + REG(PKA_APTR) = offset >> 2; + + /* Load the multiplicand in PKA RAM. */ + for(i = 0; i < multiplicand_size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = *multiplicand; + multiplicand++; + } + + /* Determine the offset for the next data. */ + offset += 4 * (i + (multiplicand_size % 2)); + + /* Update the B ptr with the offset address of the PKA RAM location + * where the multiplier will be stored. */ + REG(PKA_BPTR) = offset >> 2; + + /* Load the multiplier in PKA RAM. */ + for(i = 0; i < multiplier_size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = *multiplier; + multiplier++; + } + + /* Determine the offset for the next data. */ + offset += 4 * (i + (multiplier_size % 2)); + + /* Copy the result vector address location. */ + *result_vector = PKA_RAM_BASE + offset; + + /* Load C ptr with the result location in PKA RAM. */ + REG(PKA_CPTR) = offset >> 2; + + /* Load the respective length registers. */ + REG(PKA_ALENGTH) = multiplicand_size; + REG(PKA_BLENGTH) = multiplier_size; + + /* Set the PKA function to the multiplication and start it. */ + REG(PKA_FUNCTION) = (PKA_FUNCTION_RUN | PKA_FUNCTION_MULTIPLY); + + /* Enable Interrupt */ + if(process != NULL) { + pka_register_process_notification(process); + nvic_interrupt_unpend(NVIC_INT_PKA); + nvic_interrupt_enable(NVIC_INT_PKA); + } + + return PKA_STATUS_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +bignum_mul_get_result(uint32_t *buffer, + uint32_t *buffer_size, + const uint32_t result_vector) +{ + + uint32_t regMSWVal; + uint32_t len; + int i; + + /* Check for arguments. */ + ASSERT(NULL != buffer); + ASSERT(NULL != buffer_size); + ASSERT(result_vector > PKA_RAM_BASE); + ASSERT(result_vector < (PKA_RAM_BASE + PKA_RAM_SIZE)); + + /* Verify that the operation is complete. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Disable Interrupt */ + nvic_interrupt_disable(NVIC_INT_PKA); + pka_register_process_notification(NULL); + + /* Get the MSW register value. */ + regMSWVal = REG(PKA_MSW); + + /* Check to make sure that the result vector is not all zeroes. */ + if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) { + return PKA_STATUS_RESULT_0; + } + + /* Get the length of the result. */ + len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1) + - ((result_vector - PKA_RAM_BASE) >> 2); + + /* Make sure that the length of the supplied result buffer is adequate + * to store the resultant. */ + if(*buffer_size < len) { + return PKA_STATUS_BUF_UNDERFLOW; + } + + /* Copy the resultant length. */ + *buffer_size = len; + + /* Copy the result from vector C into the pResult. */ + for(i = 0; i < *buffer_size; i++) { + buffer[i] = REG(result_vector + 4 * i); + } + + return PKA_STATUS_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +bignum_add_start(const uint32_t *number1, + const uint8_t number1_size, + const uint32_t *number2, + const uint8_t number2_size, + uint32_t *result_vector, + struct process *process) +{ + + uint32_t offset; + int i; + + /* Check for arguments. */ + ASSERT(NULL != number1); + ASSERT(NULL != number2); + ASSERT(NULL != result_vector); + + offset = 0; + + /* Make sure no operation is in progress. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Update the A ptr with the offset address of the PKA RAM location + * where the big number 1 will be stored. */ + REG(PKA_APTR) = offset >> 2; + + /* Load the big number 1 in PKA RAM. */ + for(i = 0; i < number1_size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = number1[i]; + } + + /* Determine the offset in PKA RAM for the next data. */ + offset += 4 * (i + (number1_size % 2)); + + /* Update the B ptr with the offset address of the PKA RAM location + * where the big number 2 will be stored. */ + REG(PKA_BPTR) = offset >> 2; + + /* Load the big number 2 in PKA RAM. */ + for(i = 0; i < number2_size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = number2[i]; + } + + /* Determine the offset in PKA RAM for the next data. */ + offset += 4 * (i + (number2_size % 2)); + + /* Copy the result vector address location. */ + *result_vector = PKA_RAM_BASE + offset; + + /* Load C ptr with the result location in PKA RAM. */ + REG(PKA_CPTR) = offset >> 2; + + /* Load respective length registers. */ + REG(PKA_ALENGTH) = number1_size; + REG(PKA_BLENGTH) = number2_size; + + /* Set the function for the add operation and start the operation. */ + REG(PKA_FUNCTION) = (PKA_FUNCTION_RUN | PKA_FUNCTION_ADD); + + /* Enable Interrupt */ + if(process != NULL) { + pka_register_process_notification(process); + nvic_interrupt_unpend(NVIC_INT_PKA); + nvic_interrupt_enable(NVIC_INT_PKA); + } + + return PKA_STATUS_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +bignum_add_get_result(uint32_t *buffer, + uint32_t *buffer_size, + const uint32_t result_vector) +{ + + uint32_t regMSWVal; + uint32_t len; + int i; + + /* Check for the arguments. */ + ASSERT(NULL != buffer); + ASSERT(NULL != buffer_size); + ASSERT(result_vector > PKA_RAM_BASE); + ASSERT(result_vector < (PKA_RAM_BASE + PKA_RAM_SIZE)); + + /* Verify that the operation is complete. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Disable Interrupt */ + nvic_interrupt_disable(NVIC_INT_PKA); + pka_register_process_notification(NULL); + + /* Get the MSW register value. */ + regMSWVal = REG(PKA_MSW); + + /* Check to make sure that the result vector is not all zeroes. */ + if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) { + return PKA_STATUS_RESULT_0; + } + + /* Get the length of the result. */ + len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1) + - ((result_vector - PKA_RAM_BASE) >> 2); + + /* Make sure that the supplied result buffer is adequate to store the + * resultant data. */ + if(*buffer_size < len) { + return PKA_STATUS_BUF_UNDERFLOW; + } + + /* Copy the length. */ + *buffer_size = len; + + /* Copy the result from vector C into the provided buffer. */ + for(i = 0; i < *buffer_size; i++) { + buffer[i] = REG(result_vector + 4 * i); + } + + return PKA_STATUS_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +/* below functions are added by hu luo */ +uint8_t +bignum_subtract_start(const uint32_t *number1, + const uint8_t number1_size, + const uint32_t *number2, + const uint8_t number2_size, + uint32_t *result_vector, + struct process *process) +{ + + uint32_t offset; + int i; + + /* Check for arguments. */ + ASSERT(NULL != number1); + ASSERT(NULL != number2); + ASSERT(NULL != result_vector); + + offset = 0; + + /* Make sure no operation is in progress. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Update the A ptr with the offset address of the PKA RAM location + * where the big number 1 will be stored. */ + REG(PKA_APTR) = offset >> 2; + + /* Load the big number 1 in PKA RAM. */ + for(i = 0; i < number1_size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = number1[i]; + } + + /* Determine the offset in PKA RAM for the next data. */ + offset += 4 * (i + (number1_size % 2)); + + /* Update the B ptr with the offset address of the PKA RAM location + * where the big number 2 will be stored. */ + REG(PKA_BPTR) = offset >> 2; + + /* Load the big number 2 in PKA RAM. */ + for(i = 0; i < number2_size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = number2[i]; + } + + /* Determine the offset in PKA RAM for the next data. */ + offset += 4 * (i + (number2_size % 2)); + + /* Copy the result vector address location. */ + *result_vector = PKA_RAM_BASE + offset; + + /* Load C ptr with the result location in PKA RAM. */ + REG(PKA_CPTR) = offset >> 2; + + /* Load respective length registers. */ + REG(PKA_ALENGTH) = number1_size; + REG(PKA_BLENGTH) = number2_size; + + /* Set the function for the add operation and start the operation. */ + REG(PKA_FUNCTION) = (PKA_FUNCTION_RUN | PKA_FUNCTION_SUBTRACT); + + /* Enable Interrupt */ + if(process != NULL) { + pka_register_process_notification(process); + nvic_interrupt_unpend(NVIC_INT_PKA); + nvic_interrupt_enable(NVIC_INT_PKA); + } + + return PKA_STATUS_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +bignum_subtract_get_result(uint32_t *buffer, + uint32_t *buffer_size, + const uint32_t result_vector) +{ + + uint32_t regMSWVal; + uint32_t len; + int i; + + /* Check for the arguments. */ + ASSERT(NULL != buffer); + ASSERT(NULL != buffer_size); + ASSERT(result_vector > PKA_RAM_BASE); + ASSERT(result_vector < (PKA_RAM_BASE + PKA_RAM_SIZE)); + + /* Verify that the operation is complete. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Disable Interrupt */ + nvic_interrupt_disable(NVIC_INT_PKA); + pka_register_process_notification(NULL); + + /* Get the MSW register value. */ + regMSWVal = REG(PKA_MSW); + + /* Check to make sure that the result vector is not all zeroes. */ + if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) { + return PKA_STATUS_RESULT_0; + } + + /* Get the length of the result. */ + len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1) + - ((result_vector - PKA_RAM_BASE) >> 2); + + /* Make sure that the supplied result buffer is adequate to store the + * resultant data. */ + if(*buffer_size < len) { + return PKA_STATUS_BUF_UNDERFLOW; + } + + /* Copy the length. */ + *buffer_size = len; + + /* Copy the result from vector C into the provided buffer. */ + for(i = 0; i < *buffer_size; i++) { + buffer[i] = REG(result_vector + 4 * i); + } + + return PKA_STATUS_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +bignum_exp_mod_start(const uint32_t *number, + const uint8_t number_size, + const uint32_t *modulus, + const uint8_t modulus_size, + const uint32_t *base, + const uint8_t base_size, + uint32_t *result_vector, + struct process *process) +{ + uint32_t offset; + int i; + + /* Check for the arguments. */ + ASSERT(NULL != number); + ASSERT(NULL != modulus); + ASSERT(NULL != base); + ASSERT(NULL != result_vector); + ASSERT(modulus != base); + + offset = 0; + + /* Make sure no PKA operation is in progress. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Update the A ptr with the offset address of the PKA RAM location + * where the exponent will be stored. */ + REG(PKA_APTR) = offset >> 2; + + /* Load the Exponent in PKA RAM. */ + for(i = 0; i < number_size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = number[i]; + } + + /* Determine the offset for the next data(BPTR). */ + offset += 4 * (i + number_size % 2); + /* Update the B ptr with the offset address of the PKA RAM location + * where the divisor will be stored. */ + REG(PKA_BPTR) = offset >> 2; + + /* Load the Modulus in PKA RAM. */ + for(i = 0; i < modulus_size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = modulus[i]; + } + + /* Determine the offset for the next data(CPTR). */ + offset += 4 * (i + modulus_size % 2 + 2); + /* Update the C ptr with the offset address of the PKA RAM location + * where the Base will be stored. */ + REG(PKA_CPTR) = offset >> 2; + + /* Write Base to the Vector C in PKA RAM */ + + for(i = 0; i < base_size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = base[i]; + } + + /* Determine the offset for the next data. + * INFO D and B can share the same memory area! + * offset += 4 * (i + extraBuf + 2); */ + + /* Copy the result vector address location. */ + *result_vector = PKA_RAM_BASE + offset; + + /* Load D ptr with the result location in PKA RAM */ + REG(PKA_DPTR) = offset >> 2; + + /* Load A length registers with Big number length in 32 bit words. */ + REG(PKA_ALENGTH) = number_size; + + /* Load B length registers Divisor length in 32-bit words. */ + REG(PKA_BLENGTH) = modulus_size; + /* REG(PKA_SHIFT) = 0x00000001; + * Required for (EXPMod-variable): 0x0000A000 + * Start the PKCP modulo exponentiation operation(EXPMod-ACT2) + * by setting the PKA Function register. */ + REG(PKA_FUNCTION) = 0x0000C000; + + /* Enable Interrupt */ + if(process != NULL) { + pka_register_process_notification(process); + nvic_interrupt_unpend(NVIC_INT_PKA); + nvic_interrupt_enable(NVIC_INT_PKA); + } + + return PKA_STATUS_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +bignum_exp_mod_get_result(uint32_t *buffer, + const uint8_t buffer_size, + const uint32_t result_vector) +{ + + uint32_t regMSWVal; + uint32_t len; + int i; + + /* Check the arguments. */ + ASSERT(NULL != buffer); + ASSERT(result_vector > PKA_RAM_BASE); + ASSERT(result_vector < (PKA_RAM_BASE + PKA_RAM_SIZE)); + + /* verify that the operation is complete. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Disable Interrupt */ + nvic_interrupt_disable(NVIC_INT_PKA); + pka_register_process_notification(NULL); + + /* Get the MSW register value. */ + regMSWVal = REG(PKA_MSW); + + /* Check to make sure that the result vector is not all zeroes. */ + if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) { + return PKA_STATUS_RESULT_0; + } + + /* Get the length of the result */ + len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1) + - ((result_vector - PKA_RAM_BASE) >> 2); + /* If the size of the buffer provided is less than the result length than + * return error. */ + if(buffer_size < len) { + return PKA_STATUS_BUF_UNDERFLOW; + } + + /* copy the result from vector C into the pResult. */ + for(i = 0; i < len; i++) { + buffer[i] = REG(result_vector + 4 * i); + } + + return PKA_STATUS_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +bignum_divide_start(const uint32_t *dividend, + const uint8_t dividend_size, + const uint32_t *divisor, + const uint8_t divisor_size, + uint32_t *result_vector, + struct process *process) +{ + + uint32_t offset; + uint32_t spacing; + int i; + + /* We use largest len for spacing */ + if(dividend_size > divisor_size) { + spacing = dividend_size; + } else { + spacing = divisor_size; + } + spacing += 2 + spacing % 2; + + /* Check for the arguments. */ + ASSERT(NULL != dividend); + ASSERT(NULL != divisor); + ASSERT(NULL != result_vector); + + /* Make sure no operation is in progress. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Update the A ptr with the offset address of the PKA RAM location + * where the multiplicand will be stored. */ + offset = 0; + REG(PKA_APTR) = offset >> 2; + + /* Load the multiplicand in PKA RAM. */ + for(i = 0; i < dividend_size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = *dividend; + dividend++; + } + + /* Determine the offset for the next data. */ + offset += 4 * spacing; + + /* Update the B ptr with the offset address of the PKA RAM location + * where the multiplier will be stored. */ + REG(PKA_BPTR) = offset >> 2; + + /* Load the multiplier in PKA RAM. */ + for(i = 0; i < divisor_size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = *divisor; + divisor++; + } + + /* Determine the offset for the reminder. */ + offset += 4 * spacing; + + /* Load C ptr with the result location in PKA RAM. */ + REG(PKA_CPTR) = offset >> 2; + + /* Determine the offset for the quotient. */ + offset += 4 * spacing; + + /* Copy the quotient vector address location. */ + *result_vector = PKA_RAM_BASE + offset; + + /* Load D ptr with the result location in PKA RAM. */ + REG(PKA_DPTR) = offset >> 2; + + /* Load the respective length registers. */ + REG(PKA_ALENGTH) = dividend_size; + REG(PKA_BLENGTH) = divisor_size; + + /* Set the PKA function to the multiplication and start it. */ + REG(PKA_FUNCTION) = (PKA_FUNCTION_RUN | PKA_FUNCTION_DIVIDE); + + /* Enable Interrupt */ + if(process != NULL) { + pka_register_process_notification(process); + nvic_interrupt_unpend(NVIC_INT_PKA); + nvic_interrupt_enable(NVIC_INT_PKA); + } + + return PKA_STATUS_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +bignum_divide_get_result(uint32_t *buffer, + uint32_t *buffer_size, + const uint32_t result_vector) +{ + + uint32_t regMSWVal; + uint32_t len; + int i; + + /* Check for arguments. */ + ASSERT(NULL != buffer); + ASSERT(NULL != buffer_size); + ASSERT(result_vector > PKA_RAM_BASE); + ASSERT(result_vector < (PKA_RAM_BASE + PKA_RAM_SIZE)); + + /* Verify that the operation is complete. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Disable Interrupt */ + nvic_interrupt_disable(NVIC_INT_PKA); + pka_register_process_notification(NULL); + + /* Get the MSW register value. */ + regMSWVal = REG(PKA_MSW); + + /* Check to make sure that the result vector is not all zeroes. */ + if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) { + return PKA_STATUS_RESULT_0; + } + + /* Get the length of the result. */ + len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1) + - ((result_vector - PKA_RAM_BASE) >> 2); + + /* Make sure that the length of the supplied result buffer is adequate + * to store the resultant. */ + if(*buffer_size < len) { + return PKA_STATUS_BUF_UNDERFLOW; + } + + /* Copy the resultant length. */ + *buffer_size = len; + + /* Copy the result from vector C into the pResult. */ + for(i = 0; i < *buffer_size; i++) { + buffer[i] = REG(result_vector + 4 * i); + } + + return PKA_STATUS_SUCCESS; +} +/** @} */ + diff --git a/cpu/cc2538/dev/bignum-driver.h b/cpu/cc2538/dev/bignum-driver.h new file mode 100644 index 000000000..dd83a3058 --- /dev/null +++ b/cpu/cc2538/dev/bignum-driver.h @@ -0,0 +1,462 @@ +/* + * Original file: + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Authors: Andreas Dröscher + * Hu Luo + * Hossein Shafagh + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-pka + * @{ + * + * \defgroup cc2538-bignum cc2538 BigNum math function driver + * + * Driver for the cc2538 BigNum math functions of the PKC engine + * @{ + * + * \file + * Header file for the cc2538 BigNum driver + * + * bignum_subtract_start bignum_subtract_get_result (subtraction) + * bignum_add_start bignum_add_get_result (addition) + * bignum_mod_start bignum_mod_get_result (modulo) + * bignum_exp_mod_start bignum_exp_mod_get_result (modular exponentiation operation) + * bignum_inv_mod_start bignum_inv_mod_get_result (inverse modulo operation) + * bignum_mul_start bignum_mul_get_result (multiplication) + * bignum_divide_start bignum_divide_get_result (division) + * bignum_cmp_start bignum_cmp_get_result (comparison) + */ +#ifndef BIGNUM_DRIVER_H_ +#define BIGNUM_DRIVER_H_ + +#include "contiki.h" +#include "dev/pka.h" + +#include + +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \brief Starts the big number modulus operation. + * + * \param number Pointer to the big number on which modulo operation + * needs to be carried out. + * \param number_size Size of the big number \sa number in 32-bit word. + * \param modulus Pointer to the divisor. + * \param modulus_size Size of the divisor \sa modulus. + * \param result_vector Pointer to the result vector location + * which will be set by this function. + * \param process Process to be polled upon completion of the + * operation, or \c NULL + * + * This function starts the modulo operation on the big num \sa number + * using the divisor \sa modulus. The PKA RAM location where the result + * will be available is stored in \sa result_vector. + * + * \retval PKA_STATUS_SUCCESS if successful in starting the operation. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing + * some other operation. + */ +uint8_t bignum_mod_start(const uint32_t *number, + const uint8_t number_size, + const uint32_t *modulus, + const uint8_t modulus_size, + uint32_t *result_vector, + struct process *process); + +/** \brief Gets the result of the big number modulus operation. + * + * \param buffer Pointer to buffer where the result needs to + * be stored. + * \param buffer_size Size of the provided buffer in 32 bit size word. + * \param result_vector Address of the result location which + * was provided by the start function \sa PKABigNumModStart(). + * + * This function gets the result of the big number modulus operation which was + * previously started using the function \sa PKABigNumModStart(). + * + * \retval PKA_STATUS_SUCCESS if successful. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing + * the operation. + * \retval PKA_STATUS_RESULT_0 if the result is all zeroes. + * \retval PKA_STATUS_BUF_UNDERFLOW if the \e size is less than the length + * of the result. + */ +uint8_t bignum_mod_get_result(uint32_t *buffer, + const uint8_t buffer_size, + const uint32_t result_vector); + +/** \brief Starts the comparison of two big numbers. + * + * \param number1 Pointer to the first big number. + * \param number2 Pointer to the second big number. + * \param size Size of the big number in 32 bit size word. + * \param process Process to be polled upon completion of the + * operation, or \c NULL + * + * This function starts the comparison of two big numbers pointed by + * \e number1 and \e number2. + * Note this function expects the size of the two big numbers equal. + * + * \retval PKA_STATUS_SUCCESS if successful in starting the operation. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing + * some other operation. + */ +uint8_t bignum_cmp_start(const uint32_t *number1, + const uint32_t *number2, + uint8_t size, + struct process *process); + +/** \brief Gets the result of the comparison operation of two big numbers. + * + * This function provides the results of the comparison of two big numbers + * which was started using the \sa PKABigNumCmpStart(). + * + * \retval PKA_STATUS_OPERATION_INPRG if the operation is in progress. + * \retval PKA_STATUS_SUCCESS if the two big numbers are equal. + * \retval PKA_STATUS_A_GR_B if the first number is greater than the second. + * \retval PKA_STATUS_A_LT_B if the first number is less than the second. + */ +uint8_t bignum_cmp_get_result(void); + +/** \brief Starts the big number inverse modulo operation. + * + * \param number Pointer to the buffer containing the big number + * (dividend). + * \param number_size Size of the \e number in 32 bit word. + * \param modulus Pointer to the buffer containing the modulus. + * \param modulus_size Size of the modulus in 32 bit word. + * \param result_vector Pointer to the result vector location + * which will be set by this function. + * \param process Process to be polled upon completion of the + * operation, or \c NULL + * + * This function starts the the inverse modulo operation on \e number + * using the divisor \e modulus. + * + * \retval PKA_STATUS_SUCCESS if successful in starting the operation. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing + * some other operation. + */ +uint8_t bignum_inv_mod_start(const uint32_t *number, + const uint8_t number_size, + const uint32_t *modulus, + const uint8_t modulus_size, + uint32_t *result_vector, + struct process *process); + +/** \brief Gets the result of the big number inverse modulo operation. + * + * \param buffer Pointer to buffer where the result needs to be + * stored. + * \param buffer_size Size of the provided buffer in 32 bit size + * word. + * \param result_vector Address of the result location which + * was provided by the start function \sa PKABigNumInvModStart(). + * + * This function gets the result of the big number inverse modulo operation + * previously started using the function \sa PKABigNumInvModStart(). + * + * \retval PKA_STATUS_SUCCESS if the operation is successful. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing + * the operation. + * \retval PKA_STATUS_RESULT_0 if the result is all zeroes. + * \retval PKA_STATUS_BUF_UNDERFLOW if the length of the provided buffer is less + * then the result. + */ +uint8_t bignum_inv_mod_get_result(uint32_t *buffer, + const uint8_t buffer_size, + const uint32_t result_vector); + +/** \brief Starts the big number multiplication. + * + * \param multiplicand Pointer to the buffer containing the big + * number multiplicand. + * \param multiplicand_size Size of the multiplicand in 32-bit word. + * \param multiplier Pointer to the buffer containing the big + * number multiplier. + * \param multiplier_size Size of the multiplier in 32-bit word. + * \param result_vector Pointer to the result vector location + * which will be set by this function. + * \param process Process to be polled upon completion of the + * operation, or \c NULL + * + * This function starts the multiplication of the two big numbers. + * + * \retval PKA_STATUS_SUCCESS if successful in starting the operation. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing + * some other operation. + */ +uint8_t bignum_mul_start(const uint32_t *multiplicand, + const uint8_t multiplicand_size, + const uint32_t *multiplier, + const uint8_t multiplier_size, + uint32_t *result_vector, + struct process *process); + +/** \brief Gets the results of the big number multiplication. + * + * \param buffer Pointer to buffer where the result needs to be stored. + * \param buffer_size Address of the variable containing the length of the + * buffer. After the operation, the actual length of the resultant is + * stored at this address. + * \param result_vector Address of the result location which + * was provided by the start function \sa PKABigNumMultiplyStart(). + * + * This function gets the result of the multiplication of two big numbers + * operation previously started using the function \sa + * PKABigNumMultiplyStart(). + * + * \retval PKA_STATUS_SUCCESS if the operation is successful. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing + * the operation. + * \retval PKA_STATUS_RESULT_0 if the result is all zeroes. + * \retval PKA_STATUS_FAILURE if the operation is not successful. + * \retval PKA_STATUS_BUF_UNDERFLOW if the length of the provided buffer is less + * then the length of the result. + */ +uint8_t bignum_mul_get_result(uint32_t *buffer, + uint32_t *buffer_size, + const uint32_t result_vector); + +/** \brief Starts the addition of two big number. + * + * \param number1 Pointer to the buffer containing the first big mumber. + * \param number1_size Size of the first big number in 32-bit word. + * \param number2 Pointer to the buffer containing the second big number. + * \param number2_size Size of the second big number in 32-bit word. + * \param result_vector Pointer to the result vector location + * which will be set by this function. + * \param process Process to be polled upon completion of the + * operation, or \c NULL + * + * This function starts the addition of the two big numbers. + * + * \retval PKA_STATUS_SUCCESS if successful in starting the operation. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing + * some other operation. + */ +uint8_t bignum_add_start(const uint32_t *number1, + const uint8_t number1_size, + const uint32_t *number2, + const uint8_t number2_size, + uint32_t *result_vector, + struct process *process); + +/** \brief Gets the result of the addition operation on two big number. + * + * \param buffer Pointer to buffer where the result + * needs to be stored. + * \param buffer_size Address of the variable containing the length of + * the buffer. After the operation the actual length of the + * resultant is stored at this address. + * \param result_vector Address of the result location which + * was provided by the start function \sa PKABigNumAddStart(). + * + * This function gets the result of the addition operation on two big numbers, + * previously started using the function \sa PKABigNumAddStart(). + * + * \retval PKA_STATUS_SUCCESS if the operation is successful. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing + * the operation. + * \retval PKA_STATUS_RESULT_0 if the result is all zeroes. + * \retval PKA_STATUS_FAILURE if the operation is not successful. + * \retval PKA_STATUS_BUF_UNDERFLOW if the length of the provided buffer is less + * then the length of the result. + */ +uint8_t bignum_add_get_result(uint32_t *buffer, + uint32_t *buffer_size, + const uint32_t result_vector); + +/** \brief Starts the substract of two big number. + * + * \param number1 Pointer to the buffer containing the first big mumber. + * \param number1_size Size of the first big number in 32-bit word. + * \param number2 Pointer to the buffer containing the second big number. + * \param number2_size Size of the second big number in 32-bit word. + * \param result_vector Pointer to the result vector location + * which will be set by this function. + * \param process Process to be polled upon completion of the + * operation, or \c NULL + * + * This function starts the substraction of the two big numbers. + * + * \retval PKA_STATUS_SUCCESS if successful in starting the operation. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing + * some other operation. + */ +uint8_t bignum_subtract_start(const uint32_t *number1, + const uint8_t number1_size, + const uint32_t *number2, + const uint8_t number2_size, + uint32_t *result_vector, + struct process *process); + +/** \brief Gets the result of big number subtract. + * + * \param buffer Pointer to store the result of subtraction. + * \param buffer_size Address of the variable containing the length of the + * buffer. After the operation, the actual length of the resultant is + * stored at this address. + * \param result_vector Address of the result location which + * was provided by the start function PKABigNumSubtractStart(). + * + * This function gets the result of PKABigNumSubtractStart(). + * + * \retval PKA_STATUS_SUCCESS if the operation is successful. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing + * the operation. + * \retval PKA_STATUS_RESULT_0 if the result is all zeroes. + * \retval PKA_STATUS_FAILURE if the operation is not successful. + */ +uint8_t bignum_subtract_get_result(uint32_t *buffer, + uint32_t *buffer_size, + const uint32_t result_vector); + +/** \brief Starts the big number moduluar Exponentiation operation. + * + * \param number Pointer to the Exponent on which moduluar Exponentiation operation + * needs to be carried out. + * \param number_size Size of the the Exponent number number in 32-bit word. + * \param modulus Pointer to the divisor. + * \param modulus_size Size of the divisor modulus. + * \param base Pointer to the Base. + * \param base_size Size of the divisor base. + * \param result_vector Pointer to the result vector location + * which will be set by this function. + * \param process Process to be polled upon completion of the + * operation, or \c NULL + * + * This function starts the moduluar Exponentiation operation on the base num base + * using the Exponent number and the Modulus num modulus. The PKA RAM location where the result + * will be available is stored in \sa result_vector. + * IMPORTANT = Modulus and Based should have buffers of the same length! + * + * \retval PKA_STATUS_SUCCESS if successful in starting the operation. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing + * some other operation. + */ +uint8_t bignum_exp_mod_start(const uint32_t *number, + const uint8_t number_size, + const uint32_t *modulus, + const uint8_t modulus_size, + const uint32_t *base, + const uint8_t base_size, + uint32_t *result_vector, + struct process *process); + +/** \brief Gets the result of the big number modulus operation result. + * + * \param buffer Pointer to buffer where the result needs to + * be stored. + * \param buffer_size Size of the provided buffer in 32 bit size word. + * \param result_vector Address of the result location which + * was provided by the start function \sa PKABigNumExpModStart(). + * + * This function gets the result of the big number modulus operation which was + * previously started using the function \sa PKABigNumExpModStart(). + * + * \retval PKA_STATUS_SUCCESS if successful. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing + * the operation. + * \retval PKA_STATUS_RESULT_0 if the result is all zeroes. + * \retval PKA_STATUS_BUF_UNDERFLOW if the \e size is less than the length + * of the result. + * + * \note + * - 0 < number_size <= Max_Len + * - 1 < modulus_size <=Max_Len + * - modulus must be odd and modulus > 232 + * - base < modulus + */ +uint8_t bignum_exp_mod_get_result(uint32_t *buffer, + const uint8_t buffer_size, + const uint32_t result_vector); + +/** \brief Starts the big number Divide. + * + * \param dividend Pointer to the buffer containing the big + * number dividend. + * \param dividend_size Size of the dividend in 32-bit word. + * \param divisor Pointer to the buffer containing the big + * number divisor. + * \param divisor_size Size of the divisor in 32-bit word. + * \param result_vector Pointer to the result vector location + * which will be set by this function. + * \param process Process to be polled upon completion of the + * operation, or \c NULL + * + * This function starts the divide of the two big numbers. + * + * \retval PKA_STATUS_SUCCESS if successful in starting the operation. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing + * some other operation. + */ +uint8_t bignum_divide_start(const uint32_t *dividend, + const uint8_t dividend_size, + const uint32_t *divisor, + const uint8_t divisor_size, + uint32_t *result_vector, + struct process *process); + +/** \brief Gets the results of the big number Divide. + * + * \param buffer Pointer to buffer where the result needs to be stored. + * \param buffer_size Address of the variable containing the length of the + * buffer. After the operation, the actual length of the resultant is + * stored at this address. + * \param result_vector Address of the result location which + * was provided by the start function \sa PKABigNumMultiplyStart(). + * + * This function gets the result of the Divide of two big numbers + * operation previously started using the function \sa + * PKABigNumDivideStart(). + * + * \retval PKA_STATUS_SUCCESS if the operation is successful. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing + * the operation. + * \retval PKA_STATUS_RESULT_0 if the result is all zeroes. + * \retval PKA_STATUS_FAILURE if the operation is not successful. + * \retval PKA_STATUS_BUF_UNDERFLOW if the length of the provided buffer is less + * then the length of the result. + */ +uint8_t bignum_divide_get_result(uint32_t *buffer, + uint32_t *buffer_size, + const uint32_t result_vector); + +/** @} */ + +#endif /* BIGNUM_DRIVER_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/cbc-mac.c b/cpu/cc2538/dev/cbc-mac.c new file mode 100644 index 000000000..0635e4f53 --- /dev/null +++ b/cpu/cc2538/dev/cbc-mac.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2016, Benoît Thébaudeau + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-cbc-mac + * @{ + * + * \file + * Implementation of the cc2538 AES-CBC-MAC driver + */ +#include "contiki.h" +#include "dev/rom-util.h" +#include "dev/cbc-mac.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +uint8_t +cbc_mac_auth_start(uint8_t key_area, const void *mdata, uint16_t mdata_len, + struct process *process) +{ + uint32_t ctrl; + uint32_t iv[AES_IV_LEN / sizeof(uint32_t)]; + + /* Program AES-CBC-MAC authentication operation */ + ctrl = AES_AES_CTRL_SAVE_CONTEXT | /* Save context */ + AES_AES_CTRL_CBC_MAC | /* CBC-MAC */ + AES_AES_CTRL_DIRECTION_ENCRYPT; /* Encryption */ + + /* Prepare the crypto initialization vector + * Set initialization vector to 0 */ + rom_util_memset(iv, 0, AES_IV_LEN); + + return aes_auth_crypt_start(ctrl, key_area, iv, NULL, 0, + mdata, NULL, mdata_len, process); +} +/*---------------------------------------------------------------------------*/ +uint8_t +cbc_mac_auth_get_result(const void *mac_in, void *mac_out) +{ + uint32_t tag[AES_TAG_LEN / sizeof(uint32_t)]; + uint8_t ret; + + ret = aes_auth_crypt_get_result(NULL, tag); + if(ret != CRYPTO_SUCCESS) { + return ret; + } + + if(mac_in != NULL) { + /* Check MAC */ + if(rom_util_memcmp(tag, mac_in, CBC_MAC_MAC_LEN)) { + ret = AES_AUTHENTICATION_FAILED; + } + } + + if(mac_out != NULL) { + /* Copy tag to MAC */ + rom_util_memcpy(mac_out, tag, CBC_MAC_MAC_LEN); + } + + return ret; +} + +/** @} */ diff --git a/cpu/cc2538/dev/cbc-mac.h b/cpu/cc2538/dev/cbc-mac.h new file mode 100644 index 000000000..76b750bf5 --- /dev/null +++ b/cpu/cc2538/dev/cbc-mac.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2016, Benoît Thébaudeau + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-aes + * @{ + * + * \defgroup cc2538-cbc-mac cc2538 AES-CBC-MAC + * + * Driver for the cc2538 AES-CBC-MAC mode of the security core + * @{ + * + * \file + * Header file for the cc2538 AES-CBC-MAC driver + */ +#ifndef CBC_MAC_H_ +#define CBC_MAC_H_ + +#include "contiki.h" +#include "dev/aes.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/** \name AES-CBC-MAC constants + * @{ + */ +#define CBC_MAC_MAC_LEN AES_TAG_LEN +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES-CBC-MAC functions + * @{ + */ + +/** \brief Starts a CBC-MAC authentication operation + * \param key_area Area in Key RAM where the key is stored (0 to + * \c AES_KEY_AREAS - 1) + * \param mdata Pointer to message to authenticate in SRAM + * \param mdata_len Length of message to authenticate in octets + * \param process Process to be polled upon completion of the operation, or + * \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CBC-MAC error code + * \warning CBC-MAC is not secure for variable-length messages. There are a few + * workarounds that can be implemented by the caller, like prepending the + * message length to the first block of the message before passing it. + */ +uint8_t cbc_mac_auth_start(uint8_t key_area, const void *mdata, + uint16_t mdata_len, struct process *process); + +/** \brief Checks the status of the CBC-MAC authentication operation + * \retval false Result not yet available, and no error occurred + * \retval true Result available, or error occurred + */ +#define cbc_mac_auth_check_status aes_auth_crypt_check_status + +/** \brief Gets the result of the CBC-MAC authentication operation + * \param mac_in Pointer to 128-bit input MAC, or \c NULL + * \param mac_out Pointer to 128-bit output MAC, or \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CBC-MAC error code + * \note This function must be called only after \c cbc_mac_auth_start(). + */ +uint8_t cbc_mac_auth_get_result(const void *mac_in, void *mac_out); + +/** @} */ + +#endif /* CBC_MAC_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/cbc.c b/cpu/cc2538/dev/cbc.c new file mode 100644 index 000000000..c73a0f416 --- /dev/null +++ b/cpu/cc2538/dev/cbc.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-cbc + * @{ + * + * \file + * Implementation of the cc2538 AES-CBC driver + */ +#include "contiki.h" +#include "dev/cbc.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +uint8_t +cbc_crypt_start(uint8_t encrypt, uint8_t key_area, const void *iv, + const void *mdata_in, void *mdata_out, uint16_t mdata_len, + struct process *process) +{ + uint32_t ctrl; + + /* Program AES-CBC crypto operation */ + ctrl = AES_AES_CTRL_CBC | /* CBC */ + (encrypt ? AES_AES_CTRL_DIRECTION_ENCRYPT : 0); /* En/decryption */ + + return aes_auth_crypt_start(ctrl, key_area, iv, NULL, 0, + mdata_in, mdata_out, mdata_len, process); +} +/*---------------------------------------------------------------------------*/ +int8_t +cbc_crypt_check_status(void) +{ + return aes_auth_crypt_check_status() ? aes_auth_crypt_get_result(NULL, NULL) : + CRYPTO_PENDING; +} + +/** @} */ diff --git a/cpu/cc2538/dev/cbc.h b/cpu/cc2538/dev/cbc.h new file mode 100644 index 000000000..920708af3 --- /dev/null +++ b/cpu/cc2538/dev/cbc.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-aes + * @{ + * + * \defgroup cc2538-cbc cc2538 AES-CBC + * + * Driver for the cc2538 AES-CBC mode of the security core + * @{ + * + * \file + * Header file for the cc2538 AES-CBC driver + */ +#ifndef CBC_H_ +#define CBC_H_ + +#include "contiki.h" +#include "dev/aes.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/** \name AES-CBC constants + * @{ + */ +#define CBC_IV_LEN AES_IV_LEN +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES-CBC functions + * @{ + */ + +/** \brief Starts a CBC crypto operation + * \param encrypt \c true to encrypt, or \c false to decrypt + * \param key_area Area in Key RAM where the key is stored (0 to + * \c AES_KEY_AREAS - 1) + * \param iv Pointer to 128-bit initialization vector + * \param mdata_in Pointer to input message in SRAM + * \param mdata_out Pointer to output message in SRAM (may be \p mdata_in) + * \param mdata_len Length of message in octets + * \param process Process to be polled upon completion of the operation, or + * \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CBC error code + */ +uint8_t cbc_crypt_start(uint8_t encrypt, uint8_t key_area, const void *iv, + const void *mdata_in, void *mdata_out, + uint16_t mdata_len, struct process *process); + +/** \brief Checks the status of the CBC crypto operation + * \return \c CRYPTO_PENDING if operation still pending, \c CRYPTO_SUCCESS if + * successful, or CRYPTO/AES/CBC error code + * \note This function must be called only after \c cbc_crypt_start(). + */ +int8_t cbc_crypt_check_status(void); + +/** @} */ + +#endif /* CBC_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2430/dev/watchdog-cc2430.c b/cpu/cc2538/dev/cc2538-aes-128.c similarity index 52% rename from cpu/cc2430/dev/watchdog-cc2430.c rename to cpu/cc2538/dev/cc2538-aes-128.c index f8c4646a5..aa5b5e8e6 100644 --- a/cpu/cc2430/dev/watchdog-cc2430.c +++ b/cpu/cc2538/dev/cc2538-aes-128.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Loughborough University - Computer Science + * Copyright (c) 2015, Hasso-Plattner-Institut. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,102 +28,94 @@ * * This file is part of the Contiki operating system. */ - /** + * \addtogroup cc2538-aes-128 + * @{ + * * \file - * Hardware-dependent functions used for the cc2430 watchdog timer. - * - * This file contains an ISR and must reside in the HOME bank. - * + * Implementation of the AES-128 driver for the CC2538 SoC * \author - * George Oikonomou - + * Konrad Krentz */ +#include "contiki.h" +#include "dev/ecb.h" +#include "dev/cc2538-aes-128.h" +#include "dev/sys-ctrl.h" -#include "sys/energest.h" -#include "cc2430_sfr.h" -#include "contiki-conf.h" -#include "dev/watchdog-cc2430.h" +#include +#include +/*---------------------------------------------------------------------------*/ +#define MODULE_NAME "cc2538-aes-128" -/*---------------------------------------------------------------------------*/ -/* The watchdog only throws interrupts in timer mode */ -#if WDT_TIMER_MODE -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -cc4230_watchdog_ISR(void) __interrupt(WDT_VECTOR) -{ - EA = 0; - ENERGEST_ON(ENERGEST_TYPE_IRQ); - /* Do something */ - IRCON2 &= ~WDTIF; - ENERGEST_OFF(ENERGEST_TYPE_IRQ); - EA = 1; -} -#pragma restore -#endif -/*---------------------------------------------------------------------------*/ -void -watchdog_init(void) -{ - WDCTL = WDT_TIMER_MODE | WDT_INTERVAL; - -#if WDT_TIMER_MODE - /* Enable the watchdog interrupts in timer mode */ - IEN2 |= WDTIE; -#endif - return; -} -/*---------------------------------------------------------------------------*/ -void -watchdog_start(void) -{ - WDCTL |= WDT_EN; -} -/*---------------------------------------------------------------------------*/ -void -watchdog_periodic(void) -{ -#if WDT_TIMER_MODE - /* In timer mode, all we need to do is write 1 to WDT:CLR[0] */ - WDCTL |= WDT_CLR0; +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) #else - /* Write the 'clear' sequence while maintaining mode and interval setting */ - WDCTL = (WDCTL & 0x0F) | WDT_CLR3 | WDT_CLR1; - WDCTL = (WDCTL & 0x0F) | WDT_CLR2 | WDT_CLR0; +#define PRINTF(...) #endif +/*---------------------------------------------------------------------------*/ +static uint8_t +enable_crypto(void) +{ + uint8_t enabled = CRYPTO_IS_ENABLED(); + if(!enabled) { + crypto_enable(); + } + return enabled; } /*---------------------------------------------------------------------------*/ -void -watchdog_stop(void) +static void +restore_crypto(uint8_t enabled) { -#if WDT_TIMER_MODE - /* In timer mode, the watchdog can actually be stopped */ - WDCTL &= ~WDT_EN; - IRCON2 &= ~WDTIF; -#else - /* In watchdog mode, stopping is impossible so we just reset the timer */ - watchdog_periodic(); -#endif -} -/*---------------------------------------------------------------------------*/ -void -watchdog_reboot(void) -{ -#if WDT_TIMER_MODE - /* Switch modes to watchdog, minimum interval, enable */ - WDCTL = WDT_EN | WDT_TIMEOUT_2_MSEC; -#else - /* Let's get this over with ASAP */ - WDCTL = WDT_TIMEOUT_2_MSEC; -#endif - /* Dis-acknowledge all interrupts while we wait for the dog to bark */ - DISABLE_INTERRUPTS(); - /* NOP till the dog barks... */ - while(1) { - __asm - nop - __endasm; + if(!enabled) { + crypto_disable(); } } +/*---------------------------------------------------------------------------*/ +static void +set_key(const uint8_t *key) +{ + uint8_t crypto_enabled, ret; + + crypto_enabled = enable_crypto(); + + ret = aes_load_keys(key, AES_KEY_STORE_SIZE_KEY_SIZE_128, 1, + CC2538_AES_128_KEY_AREA); + if(ret != CRYPTO_SUCCESS) { + PRINTF("%s: aes_load_keys() error %u\n", MODULE_NAME, ret); + sys_ctrl_reset(); + } + + restore_crypto(crypto_enabled); +} +/*---------------------------------------------------------------------------*/ +static void +encrypt(uint8_t *plaintext_and_result) +{ + uint8_t crypto_enabled, ret; + int8_t res; + + crypto_enabled = enable_crypto(); + + ret = ecb_crypt_start(true, CC2538_AES_128_KEY_AREA, plaintext_and_result, + plaintext_and_result, AES_128_BLOCK_SIZE, NULL); + if(ret != CRYPTO_SUCCESS) { + PRINTF("%s: ecb_crypt_start() error %u\n", MODULE_NAME, ret); + sys_ctrl_reset(); + } + + while((res = ecb_crypt_check_status()) == CRYPTO_PENDING); + if(res != CRYPTO_SUCCESS) { + PRINTF("%s: ecb_crypt_check_status() error %d\n", MODULE_NAME, res); + sys_ctrl_reset(); + } + + restore_crypto(crypto_enabled); +} +/*---------------------------------------------------------------------------*/ +const struct aes_128_driver cc2538_aes_128_driver = { + set_key, + encrypt +}; + +/** @} */ diff --git a/cpu/cc2430/dev/bus.c b/cpu/cc2538/dev/cc2538-aes-128.h similarity index 73% rename from cpu/cc2430/dev/bus.c rename to cpu/cc2538/dev/cc2538-aes-128.h index 0108cde58..20615fc55 100644 --- a/cpu/cc2430/dev/bus.c +++ b/cpu/cc2538/dev/cc2538-aes-128.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Swedish Institute of Computer Science. + * Copyright (c) 2015, Hasso-Plattner-Institut. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,32 +27,37 @@ * SUCH DAMAGE. * * This file is part of the Contiki operating system. - * */ +/** + * \addtogroup cc2538-aes + * @{ + * + * \defgroup cc2538-aes-128 CC2538 AES-128 + * + * AES-128 driver for the CC2538 SoC + * @{ + * + * \file + * Header file of the AES-128 driver for the CC2538 SoC + * \author + * Konrad Krentz + */ +#ifndef CC2538_AES_128_H_ +#define CC2538_AES_128_H_ + +#include "lib/aes-128.h" +/*---------------------------------------------------------------------------*/ +#ifdef CC2538_AES_128_CONF_KEY_AREA +#define CC2538_AES_128_KEY_AREA CC2538_AES_128_CONF_KEY_AREA +#else +#define CC2538_AES_128_KEY_AREA 0 +#endif +/*---------------------------------------------------------------------------*/ +extern const struct aes_128_driver cc2538_aes_128_driver; + +#endif /* CC2538_AES_128_H_ */ /** - * \file - * Initialization functions for the 8051 bus - * \author - * Adam Dunkels + * @} + * @} */ - -#include "cc2430_sfr.h" -#include "dev/bus.h" -#include "sys/clock.h" -#include "contiki-conf.h" - -/*---------------------------------------------------------------------------*/ -void -bus_init(void) -{ - CLKCON = (0x00 | OSC32K); /* 32k internal */ - while(CLKCON != (0x00 | OSC32K)); - - P1DIR |= 0x0E; - IEN0_EA = 1; - - /* Initialize the clock */ - clock_init(); -} -/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2538/dev/cc2538-ccm-star.c b/cpu/cc2538/dev/cc2538-ccm-star.c new file mode 100644 index 000000000..754b0548e --- /dev/null +++ b/cpu/cc2538/dev/cc2538-ccm-star.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-ccm-star + * @{ + * + * \file + * Implementation of the AES-CCM* driver for the CC2538 SoC + */ +#include "contiki.h" +#include "dev/ccm.h" +#include "dev/cc2538-aes-128.h" +#include "dev/cc2538-ccm-star.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define MODULE_NAME "cc2538-ccm-star" + +#define CCM_STAR_LEN_LEN (CCM_NONCE_LEN_LEN - CCM_STAR_NONCE_LENGTH) + +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static uint8_t +enable_crypto(void) +{ + uint8_t enabled = CRYPTO_IS_ENABLED(); + if(!enabled) { + crypto_enable(); + } + return enabled; +} +/*---------------------------------------------------------------------------*/ +static void +restore_crypto(uint8_t enabled) +{ + if(!enabled) { + crypto_disable(); + } +} +/*---------------------------------------------------------------------------*/ +static void +set_key(const uint8_t *key) +{ + cc2538_aes_128_driver.set_key(key); +} +/*---------------------------------------------------------------------------*/ +static void +aead(const uint8_t *nonce, uint8_t *m, uint8_t m_len, const uint8_t *a, + uint8_t a_len, uint8_t *result, uint8_t mic_len, int forward) +{ + uint16_t cdata_len; + uint8_t crypto_enabled, ret; + + crypto_enabled = enable_crypto(); + + if(forward) { + ret = ccm_auth_encrypt_start(CCM_STAR_LEN_LEN, CC2538_AES_128_KEY_AREA, + nonce, a, a_len, m, m_len, m, mic_len, NULL); + if(ret != CRYPTO_SUCCESS) { + PRINTF("%s: ccm_auth_encrypt_start() error %u\n", MODULE_NAME, ret); + restore_crypto(crypto_enabled); + return; + } + + while(!ccm_auth_encrypt_check_status()); + ret = ccm_auth_encrypt_get_result(result, mic_len); + if(ret != CRYPTO_SUCCESS) { + PRINTF("%s: ccm_auth_encrypt_get_result() error %u\n", MODULE_NAME, ret); + } + } else { + cdata_len = m_len + mic_len; + ret = ccm_auth_decrypt_start(CCM_STAR_LEN_LEN, CC2538_AES_128_KEY_AREA, + nonce, a, a_len, m, cdata_len, m, mic_len, + NULL); + if(ret != CRYPTO_SUCCESS) { + PRINTF("%s: ccm_auth_decrypt_start() error %u\n", MODULE_NAME, ret); + restore_crypto(crypto_enabled); + return; + } + + while(!ccm_auth_decrypt_check_status()); + ret = ccm_auth_decrypt_get_result(m, cdata_len, result, mic_len); + if(ret != CRYPTO_SUCCESS) { + PRINTF("%s: ccm_auth_decrypt_get_result() error %u\n", MODULE_NAME, ret); + } + } + + restore_crypto(crypto_enabled); +} +/*---------------------------------------------------------------------------*/ +const struct ccm_star_driver cc2538_ccm_star_driver = { + set_key, + aead +}; + +/** @} */ diff --git a/cpu/cc2538/dev/cc2538-ccm-star.h b/cpu/cc2538/dev/cc2538-ccm-star.h new file mode 100644 index 000000000..a608444ce --- /dev/null +++ b/cpu/cc2538/dev/cc2538-ccm-star.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-aes + * @{ + * + * \defgroup cc2538-ccm-star CC2538 AES-CCM* + * + * AES-CCM* driver for the CC2538 SoC + * @{ + * + * \file + * Header file of the AES-CCM* driver for the CC2538 SoC + */ +#ifndef CC2538_CCM_STAR_H_ +#define CC2538_CCM_STAR_H_ + +#include "lib/ccm-star.h" +/*---------------------------------------------------------------------------*/ +extern const struct ccm_star_driver cc2538_ccm_star_driver; + +#endif /* CC2538_CCM_STAR_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/cc2538-dev.h b/cpu/cc2538/dev/cc2538-dev.h new file mode 100644 index 000000000..7bb81f662 --- /dev/null +++ b/cpu/cc2538/dev/cc2538-dev.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538 + * @{ + * + * \defgroup cc2538-devices cc2538 family of devices + * + * Definitions for the cc2538 family of devices + * @{ + * + * \file + * Header file for the cc2538 devices definitions + */ +#ifndef CC2538_DEV_H_ +#define CC2538_DEV_H_ + +#include "contiki-conf.h" +#include "sys/cc.h" +/*----------------------------------------------------------------------------*/ +/** \name Bit-fields for the CC2538 devices features + * @{ + */ +#define CC2538_DEV_ID_M 0x0000000F /**< ID mask */ +#define CC2538_DEV_ID_S 0 /**< ID shift */ +#define CC2538_DEV_FLASH_SIZE_KB_M 0x0000FFF0 /**< kiB flash size mask */ +#define CC2538_DEV_FLASH_SIZE_KB_S 4 /**< kiB flash size shift */ +#define CC2538_DEV_SRAM_SIZE_KB_M 0x00FF0000 /**< kiB SRAM size mask */ +#define CC2538_DEV_SRAM_SIZE_KB_S 16 /**< kiB SRAM size shift */ +#define CC2538_DEV_AES_SHA_M 0x01000000 /**< Security HW AES/SHA */ +#define CC2538_DEV_ECC_RSA_M 0x02000000 /**< Security HW ECC/RSA */ +/** @} */ +/*----------------------------------------------------------------------------*/ +/** \name Macro defining a CC2538 device from its features + * @{ + */ +#define CC2538_DEV_DEF(id, flash_size_kb, sram_size_kb, aes_sha, ecc_rsa) \ + ((id) << CC2538_DEV_ID_S | (flash_size_kb) << CC2538_DEV_FLASH_SIZE_KB_S | \ + (sram_size_kb) << CC2538_DEV_SRAM_SIZE_KB_S | \ + ((aes_sha) ? CC2538_DEV_AES_SHA_M : 0) | \ + ((ecc_rsa) ? CC2538_DEV_ECC_RSA_M : 0)) +/** @} */ +/*----------------------------------------------------------------------------*/ +/** \name Available CC2538 devices + * @{ + */ +#define CC2538_DEV_CC2538SF53 CC2538_DEV_DEF(0, 512, 32, 1, 1) +#define CC2538_DEV_CC2538SF23 CC2538_DEV_DEF(1, 256, 32, 1, 1) +#define CC2538_DEV_CC2538NF53 CC2538_DEV_DEF(2, 512, 32, 1, 0) +#define CC2538_DEV_CC2538NF23 CC2538_DEV_DEF(3, 256, 32, 1, 0) +#define CC2538_DEV_CC2538NF11 CC2538_DEV_DEF(4, 128, 16, 1, 0) +/** @} */ +/*----------------------------------------------------------------------------*/ +/** \name CC2538 device used by Contiki + * @{ + */ +#ifdef CC2538_DEV_CONF +#define CC2538_DEV CC2538_DEV_CONF +#else +#define CC2538_DEV CC2538_DEV_CC2538SF53 +#endif +/** @} */ +/*----------------------------------------------------------------------------*/ +/** \name Features of the CC2538 device used by Contiki + * @{ + */ +/** Flash address */ +#define CC2538_DEV_FLASH_ADDR 0x00200000 +/** Flash size in bytes */ +#define CC2538_DEV_FLASH_SIZE (((CC2538_DEV & CC2538_DEV_FLASH_SIZE_KB_M) >> \ + CC2538_DEV_FLASH_SIZE_KB_S) << 10) +/** SRAM (non-retention + low-leakage) address */ +#define CC2538_DEV_SRAM_ADDR (CC2538_DEV_RLSRAM_SIZE ? \ + CC2538_DEV_RLSRAM_ADDR : \ + CC2538_DEV_LLSRAM_ADDR) +/** SRAM (non-retention + low-leakage) size in bytes */ +#define CC2538_DEV_SRAM_SIZE (((CC2538_DEV & CC2538_DEV_SRAM_SIZE_KB_M) >> \ + CC2538_DEV_SRAM_SIZE_KB_S) << 10) +/** Regular-leakage SRAM address */ +#define CC2538_DEV_RLSRAM_ADDR 0x20000000 +/** Regular-leakage SRAM size in bytes */ +#define CC2538_DEV_RLSRAM_SIZE (CC2538_DEV_SRAM_SIZE - CC2538_DEV_LLSRAM_SIZE) +/** Low-leakage SRAM address */ +#define CC2538_DEV_LLSRAM_ADDR 0x20004000 +/** Low-leakage SRAM size in bytes */ +#define CC2538_DEV_LLSRAM_SIZE MIN(CC2538_DEV_SRAM_SIZE, 16384) +/** Security HW AES/SHA */ +#define CC2538_DEV_AES_SHA (!!(CC2538_DEV & CC2538_DEV_AES_SHA_M)) +/** Security HW ECC/RSA */ +#define CC2538_DEV_ECC_RSA (!!(CC2538_DEV & CC2538_DEV_ECC_RSA_M)) +/** @} */ + +#endif /* CC2538_DEV_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/cc2538-rf.c b/cpu/cc2538/dev/cc2538-rf.c index a42dd56a4..52708e0ca 100644 --- a/cpu/cc2538/dev/cc2538-rf.c +++ b/cpu/cc2538/dev/cc2538-rf.c @@ -80,7 +80,6 @@ /* Local RF Flags */ #define RX_ACTIVE 0x80 #define RF_MUST_RESET 0x40 -#define WAS_OFF 0x10 #define RF_ON 0x01 /* Bit Masks for the last byte in the RX FIFO */ @@ -106,7 +105,7 @@ static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; /** Snif */ #define flush() usb_serial_flush() #else #include "dev/uart.h" -#define write_byte(b) uart_write_byte(b) +#define write_byte(b) uart_write_byte(CC2538_RF_CONF_SNIFFER_UART, b) #define flush() #endif @@ -120,16 +119,69 @@ static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; /** Snif */ #else #define CC2538_RF_AUTOACK 1 #endif +/*--------------------------------------------------------------------------- + * MAC timer + *---------------------------------------------------------------------------*/ +/* Timer conversion */ +#define RADIO_TO_RTIMER(X) ((uint32_t)((uint64_t)(X) * RTIMER_ARCH_SECOND / SYS_CTRL_32MHZ)) + +#define CLOCK_STABLE() do { \ + while ( !(REG(SYS_CTRL_CLOCK_STA) & (SYS_CTRL_CLOCK_STA_XOSC_STB))); \ + } while(0) +/*---------------------------------------------------------------------------*/ +/* Are we currently in poll mode? Disabled by default */ +static uint8_t volatile poll_mode = 0; +/* Do we perform a CCA before sending? Enabled by default. */ +static uint8_t send_on_cca = 1; +static int8_t rssi; +static uint8_t crc_corr; + +void mac_timer_init(void); +uint32_t get_sfd_timestamp(void); /*---------------------------------------------------------------------------*/ static uint8_t rf_flags; +static uint8_t rf_channel = CC2538_RF_CHANNEL; static int on(void); static int off(void); /*---------------------------------------------------------------------------*/ +/* TX Power dBm lookup table. Values from SmartRF Studio v1.16.0 */ +typedef struct output_config { + radio_value_t power; + uint8_t txpower_val; +} output_config_t; + +static const output_config_t output_power[] = { + { 7, 0xFF }, + { 5, 0xED }, + { 3, 0xD5 }, + { 1, 0xC5 }, + { 0, 0xB6 }, + { -1, 0xB0 }, + { -3, 0xA1 }, + { -5, 0x91 }, + { -7, 0x88 }, + { -9, 0x72 }, + {-11, 0x62 }, + {-13, 0x58 }, + {-15, 0x42 }, + {-24, 0x00 }, +}; + +#define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t)) + +/* Max and Min Output Power in dBm */ +#define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].power) +#define OUTPUT_POWER_MAX (output_power[0].power) +/*---------------------------------------------------------------------------*/ PROCESS(cc2538_rf_process, "cc2538 RF driver"); /*---------------------------------------------------------------------------*/ -uint8_t -cc2538_rf_channel_get() +/** + * \brief Get the current operating channel + * \return Returns a value in [11,26] representing the current channel + */ +static uint8_t +get_channel() { uint8_t chan = REG(RFCORE_XREG_FREQCTRL) & RFCORE_XREG_FREQCTRL_FREQ; @@ -137,92 +189,209 @@ cc2538_rf_channel_get() + CC2538_RF_CHANNEL_MIN); } /*---------------------------------------------------------------------------*/ -int8_t -cc2538_rf_channel_set(uint8_t channel) +/** + * \brief Set the current operating channel + * \param channel The desired channel as a value in [11,26] + * \return Returns a value in [11,26] representing the current channel + * or a negative value if \e channel was out of bounds + */ +static int8_t +set_channel(uint8_t channel) { + uint8_t was_on = 0; + PRINTF("RF: Set Channel\n"); if((channel < CC2538_RF_CHANNEL_MIN) || (channel > CC2538_RF_CHANNEL_MAX)) { - return -1; + return CC2538_RF_CHANNEL_SET_ERROR; } /* Changes to FREQCTRL take effect after the next recalibration */ - off(); + + /* If we are off, save state, otherwise switch off and save state */ + if((REG(RFCORE_XREG_FSMSTAT0) & RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE) != 0) { + was_on = 1; + off(); + } REG(RFCORE_XREG_FREQCTRL) = (CC2538_RF_CHANNEL_MIN + (channel - CC2538_RF_CHANNEL_MIN) * CC2538_RF_CHANNEL_SPACING); - on(); + /* switch radio back on only if radio was on before - otherwise will turn on radio foor sleepy nodes */ + if(was_on) { + on(); + } + + rf_channel = channel; return (int8_t) channel; } /*---------------------------------------------------------------------------*/ -uint8_t -cc2538_rf_power_set(uint8_t new_power) +static radio_value_t +get_pan_id(void) { - PRINTF("RF: Set Power\n"); - - REG(RFCORE_XREG_TXPOWER) = new_power; - - return (REG(RFCORE_XREG_TXPOWER) & 0xFF); + return (radio_value_t)(REG(RFCORE_FFSM_PAN_ID1) << 8 | REG(RFCORE_FFSM_PAN_ID0)); } /*---------------------------------------------------------------------------*/ -/* ToDo: Check once we have info on the... infopage */ -void -cc2538_rf_set_addr(uint16_t pan) +static void +set_pan_id(uint16_t pan) { -#if LINKADDR_SIZE==8 - /* EXT_ADDR[7:0] is ignored when using short addresses */ - int i; - - for(i = (LINKADDR_SIZE - 1); i >= 0; --i) { - ((uint32_t *)RFCORE_FFSM_EXT_ADDR0)[i] = - linkaddr_node_addr.u8[LINKADDR_SIZE - 1 - i]; - } -#endif - REG(RFCORE_FFSM_PAN_ID0) = pan & 0xFF; REG(RFCORE_FFSM_PAN_ID1) = pan >> 8; - - REG(RFCORE_FFSM_SHORT_ADDR0) = linkaddr_node_addr.u8[LINKADDR_SIZE - 1]; - REG(RFCORE_FFSM_SHORT_ADDR1) = linkaddr_node_addr.u8[LINKADDR_SIZE - 2]; } /*---------------------------------------------------------------------------*/ -int -cc2538_rf_read_rssi(void) +static radio_value_t +get_short_addr(void) { - int rssi; + return (radio_value_t)(REG(RFCORE_FFSM_SHORT_ADDR1) << 8 | REG(RFCORE_FFSM_SHORT_ADDR0)); +} +/*---------------------------------------------------------------------------*/ +static void +set_short_addr(uint16_t addr) +{ + REG(RFCORE_FFSM_SHORT_ADDR0) = addr & 0xFF; + REG(RFCORE_FFSM_SHORT_ADDR1) = addr >> 8; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Reads the current signal strength (RSSI) + * \return The current RSSI in dBm + * + * This function reads the current RSSI on the currently configured + * channel. + */ +static radio_value_t +get_rssi(void) +{ + int8_t rssi; + uint8_t was_off = 0; /* If we are off, turn on first */ if((REG(RFCORE_XREG_FSMSTAT0) & RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE) == 0) { - rf_flags |= WAS_OFF; + was_off = 1; on(); } /* Wait on RSSI_VALID */ while((REG(RFCORE_XREG_RSSISTAT) & RFCORE_XREG_RSSISTAT_RSSI_VALID) == 0); - rssi = ((int8_t)REG(RFCORE_XREG_RSSI)) - RSSI_OFFSET; + rssi = (int8_t)(REG(RFCORE_XREG_RSSI) & RFCORE_XREG_RSSI_RSSI_VAL) - RSSI_OFFSET; /* If we were off, turn back off */ - if((rf_flags & WAS_OFF) == WAS_OFF) { - rf_flags &= ~WAS_OFF; + if(was_off) { off(); } return rssi; } /*---------------------------------------------------------------------------*/ +/* Returns the current CCA threshold in dBm */ +static radio_value_t +get_cca_threshold(void) +{ + return (int8_t)(REG(RFCORE_XREG_CCACTRL0) & RFCORE_XREG_CCACTRL0_CCA_THR) - RSSI_OFFSET; +} +/*---------------------------------------------------------------------------*/ +/* Sets the CCA threshold in dBm */ +static void +set_cca_threshold(radio_value_t value) +{ + REG(RFCORE_XREG_CCACTRL0) = (value & 0xFF) + RSSI_OFFSET; +} +/*---------------------------------------------------------------------------*/ +/* Returns the current TX power in dBm */ +static radio_value_t +get_tx_power(void) +{ + int i; + uint8_t reg_val = REG(RFCORE_XREG_TXPOWER) & 0xFF; + + /* + * Find the TXPOWER value in the lookup table + * If the value has been written with set_tx_power, we should be able to + * find the exact value. However, in case the register has been written in + * a different fashion, we return the immediately lower value of the lookup + */ + for(i = 0; i < OUTPUT_CONFIG_COUNT; i++) { + if(reg_val >= output_power[i].txpower_val) { + return output_power[i].power; + } + } + return OUTPUT_POWER_MIN; +} +/*---------------------------------------------------------------------------*/ +/* + * Set TX power to 'at least' power dBm + * This works with a lookup table. If the value of 'power' does not exist in + * the lookup table, TXPOWER will be set to the immediately higher available + * value + */ +static void +set_tx_power(radio_value_t power) +{ + int i; + + for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) { + if(power <= output_power[i].power) { + REG(RFCORE_XREG_TXPOWER) = output_power[i].txpower_val; + return; + } + } +} +/*---------------------------------------------------------------------------*/ +static void +set_frame_filtering(uint8_t enable) +{ + if(enable) { + REG(RFCORE_XREG_FRMFILT0) |= RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN; + } else { + REG(RFCORE_XREG_FRMFILT0) &= ~RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN; + } +} +/*---------------------------------------------------------------------------*/ +static void +set_poll_mode(uint8_t enable) +{ + poll_mode = enable; + + if(enable) { + mac_timer_init(); + REG(RFCORE_XREG_RFIRQM0) &= ~RFCORE_XREG_RFIRQM0_FIFOP; // mask out FIFOP interrupt source + REG(RFCORE_SFR_RFIRQF0) &= ~RFCORE_SFR_RFIRQF0_FIFOP; // clear pending FIFOP interrupt + nvic_interrupt_disable(NVIC_INT_RF_RXTX); // disable RF interrupts + } else { + REG(RFCORE_XREG_RFIRQM0) |= RFCORE_XREG_RFIRQM0_FIFOP; // enable FIFOP interrupt source + nvic_interrupt_enable(NVIC_INT_RF_RXTX); // enable RF interrupts + } +} +/*---------------------------------------------------------------------------*/ +static void +set_send_on_cca(uint8_t enable) +{ + send_on_cca = enable; +} +/*---------------------------------------------------------------------------*/ +static void +set_auto_ack(uint8_t enable) +{ + if(enable) { + REG(RFCORE_XREG_FRMCTRL0) |= RFCORE_XREG_FRMCTRL0_AUTOACK; + } else { + REG(RFCORE_XREG_FRMCTRL0) &= ~RFCORE_XREG_FRMCTRL0_AUTOACK; + } +} +/*---------------------------------------------------------------------------*/ /* Netstack API radio driver functions */ /*---------------------------------------------------------------------------*/ static int channel_clear(void) { int cca; + uint8_t was_off = 0; PRINTF("RF: CCA\n"); /* If we are off, turn on first */ if((REG(RFCORE_XREG_FSMSTAT0) & RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE) == 0) { - rf_flags |= WAS_OFF; + was_off = 1; on(); } @@ -236,8 +405,7 @@ channel_clear(void) } /* If we were off, turn back off */ - if((rf_flags & WAS_OFF) == WAS_OFF) { - rf_flags &= ~WAS_OFF; + if(was_off) { off(); } @@ -268,7 +436,9 @@ off(void) /* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */ while(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); - CC2538_RF_CSP_ISFLUSHRX(); + if(!(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP)) { + CC2538_RF_CSP_ISFLUSHRX(); + } /* Don't turn off if we are off as this will trigger a Strobe Error */ if(REG(RFCORE_XREG_RXENABLE) != 0) { @@ -327,12 +497,10 @@ init(void) /* MAX FIFOP threshold */ REG(RFCORE_XREG_FIFOPCTRL) = CC2538_RF_MAX_PACKET_LEN; - cc2538_rf_power_set(CC2538_RF_TX_POWER); - cc2538_rf_channel_set(CC2538_RF_CHANNEL); + /* Set TX Power */ + REG(RFCORE_XREG_TXPOWER) = CC2538_RF_TX_POWER; - /* Acknowledge RF interrupts, FIFOP only */ - REG(RFCORE_XREG_RFIRQM0) |= RFCORE_XREG_RFIRQM0_FIFOP; - nvic_interrupt_enable(NVIC_INT_RF_RXTX); + set_channel(rf_channel); /* Acknowledge all RF Error interrupts */ REG(RFCORE_XREG_RFERRM) = RFCORE_XREG_RFERRM_RFERRM; @@ -359,6 +527,8 @@ init(void) */ udma_set_channel_src(CC2538_RF_CONF_RX_DMA_CHAN, RFCORE_SFR_RFDATA); } + + set_poll_mode(poll_mode); process_start(&cc2538_rf_process, NULL); @@ -431,19 +601,22 @@ transmit(unsigned short transmit_len) uint8_t counter; int ret = RADIO_TX_ERR; rtimer_clock_t t0; + uint8_t was_off = 0; PRINTF("RF: Transmit\n"); if(!(rf_flags & RX_ACTIVE)) { t0 = RTIMER_NOW(); on(); - rf_flags |= WAS_OFF; + was_off = 1; while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ONOFF_TIME)); } - if(channel_clear() == CC2538_RF_CCA_BUSY) { - RIMESTATS_ADD(contentiondrop); - return RADIO_TX_COLLISION; + if(send_on_cca) { + if(channel_clear() == CC2538_RF_CCA_BUSY) { + RIMESTATS_ADD(contentiondrop); + return RADIO_TX_COLLISION; + } } /* @@ -479,8 +652,7 @@ transmit(unsigned short transmit_len) ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); ENERGEST_ON(ENERGEST_TYPE_LISTEN); - if(rf_flags & WAS_OFF) { - rf_flags &= ~WAS_OFF; + if(was_off) { off(); } @@ -501,8 +673,6 @@ read(void *buf, unsigned short bufsize) { uint8_t i; uint8_t len; - uint8_t crc_corr; - int8_t rssi; PRINTF("RF: Read\n"); @@ -602,14 +772,18 @@ read(void *buf, unsigned short bufsize) flush(); #endif - /* If FIFOP==1 and FIFO==0 then we had a FIFO overflow at some point. */ - if(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP) { - if(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFO) { - process_poll(&cc2538_rf_process); - } else { - CC2538_RF_CSP_ISFLUSHRX(); + if(!poll_mode) { + /* If FIFOP==1 and FIFO==0 then we had a FIFO overflow at some point. */ + if(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP) { + if(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFO) { + process_poll(&cc2538_rf_process); + } else { + CC2538_RF_CSP_ISFLUSHRX(); + } } } + + CC2538_RF_CSP_ISFLUSHRX(); return (len); } @@ -638,6 +812,188 @@ pending_packet(void) return (REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP); } /*---------------------------------------------------------------------------*/ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + if(!value) { + return RADIO_RESULT_INVALID_VALUE; + } + + switch(param) { + case RADIO_PARAM_POWER_MODE: + *value = (REG(RFCORE_XREG_RXENABLE) && RFCORE_XREG_RXENABLE_RXENMASK) == 0 + ? RADIO_POWER_MODE_OFF : RADIO_POWER_MODE_ON; + return RADIO_RESULT_OK; + case RADIO_PARAM_CHANNEL: + *value = (radio_value_t)get_channel(); + return RADIO_RESULT_OK; + case RADIO_PARAM_PAN_ID: + *value = get_pan_id(); + return RADIO_RESULT_OK; + case RADIO_PARAM_16BIT_ADDR: + *value = get_short_addr(); + return RADIO_RESULT_OK; + case RADIO_PARAM_RX_MODE: + *value = 0; + if(REG(RFCORE_XREG_FRMFILT0) & RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN) { + *value |= RADIO_RX_MODE_ADDRESS_FILTER; + } + if(REG(RFCORE_XREG_FRMCTRL0) & RFCORE_XREG_FRMCTRL0_AUTOACK) { + *value |= RADIO_RX_MODE_AUTOACK; + } + if(poll_mode) { + *value |= RADIO_RX_MODE_POLL_MODE; + } + return RADIO_RESULT_OK; + case RADIO_PARAM_TX_MODE: + *value = 0; + if(send_on_cca) { + *value |= RADIO_TX_MODE_SEND_ON_CCA; + } + return RADIO_RESULT_OK; + case RADIO_PARAM_TXPOWER: + *value = get_tx_power(); + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + *value = get_cca_threshold(); + return RADIO_RESULT_OK; + case RADIO_PARAM_RSSI: + *value = get_rssi(); + return RADIO_RESULT_OK; + case RADIO_PARAM_LAST_RSSI: + *value = rssi; + return RADIO_RESULT_OK; + case RADIO_PARAM_LAST_LINK_QUALITY: + *value = crc_corr & LQI_BIT_MASK; + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MIN: + *value = CC2538_RF_CHANNEL_MIN; + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MAX: + *value = CC2538_RF_CHANNEL_MAX; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MIN: + *value = OUTPUT_POWER_MIN; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MAX: + *value = OUTPUT_POWER_MAX; + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + switch(param) { + case RADIO_PARAM_POWER_MODE: + if(value == RADIO_POWER_MODE_ON) { + on(); + return RADIO_RESULT_OK; + } + if(value == RADIO_POWER_MODE_OFF) { + off(); + return RADIO_RESULT_OK; + } + return RADIO_RESULT_INVALID_VALUE; + case RADIO_PARAM_CHANNEL: + if(value < CC2538_RF_CHANNEL_MIN || + value > CC2538_RF_CHANNEL_MAX) { + return RADIO_RESULT_INVALID_VALUE; + } + if(set_channel(value) == CC2538_RF_CHANNEL_SET_ERROR) { + return RADIO_RESULT_ERROR; + } + return RADIO_RESULT_OK; + case RADIO_PARAM_PAN_ID: + set_pan_id(value & 0xffff); + return RADIO_RESULT_OK; + case RADIO_PARAM_16BIT_ADDR: + set_short_addr(value & 0xffff); + return RADIO_RESULT_OK; + case RADIO_PARAM_RX_MODE: + if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER | + RADIO_RX_MODE_AUTOACK | + RADIO_RX_MODE_POLL_MODE)) { + return RADIO_RESULT_INVALID_VALUE; + } + + set_frame_filtering((value & RADIO_RX_MODE_ADDRESS_FILTER) != 0); + set_auto_ack((value & RADIO_RX_MODE_AUTOACK) != 0); + set_poll_mode((value & RADIO_RX_MODE_POLL_MODE) != 0); + + return RADIO_RESULT_OK; + case RADIO_PARAM_TX_MODE: + if(value & ~(RADIO_TX_MODE_SEND_ON_CCA)) { + return RADIO_RESULT_INVALID_VALUE; + } + set_send_on_cca((value & RADIO_TX_MODE_SEND_ON_CCA) != 0); + return RADIO_RESULT_OK; + case RADIO_PARAM_TXPOWER: + if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) { + return RADIO_RESULT_INVALID_VALUE; + } + + set_tx_power(value); + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + set_cca_threshold(value); + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + uint8_t *target; + int i; + + if(param == RADIO_PARAM_64BIT_ADDR) { + if(size != 8 || !dest) { + return RADIO_RESULT_INVALID_VALUE; + } + + target = dest; + for(i = 0; i < 8; i++) { + target[i] = ((uint32_t *)RFCORE_FFSM_EXT_ADDR0)[7 - i] & 0xFF; + } + + return RADIO_RESULT_OK; + } + + if(param == RADIO_PARAM_LAST_PACKET_TIMESTAMP) { + if(size != sizeof(rtimer_clock_t) || !dest) { + return RADIO_RESULT_INVALID_VALUE; + } + *(rtimer_clock_t*)dest = get_sfd_timestamp(); + return RADIO_RESULT_OK; + } + + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + int i; + + if(param == RADIO_PARAM_64BIT_ADDR) { + if(size != 8 || !src) { + return RADIO_RESULT_INVALID_VALUE; + } + + for(i = 0; i < 8; i++) { + ((uint32_t *)RFCORE_FFSM_EXT_ADDR0)[i] = ((uint8_t *)src)[7 - i]; + } + + return RADIO_RESULT_OK; + } + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ const struct radio_driver cc2538_rf_driver = { init, prepare, @@ -649,6 +1005,10 @@ const struct radio_driver cc2538_rf_driver = { pending_packet, on, off, + get_value, + set_value, + get_object, + set_object }; /*---------------------------------------------------------------------------*/ /** @@ -667,23 +1027,37 @@ PROCESS_THREAD(cc2538_rf_process, ev, data) PROCESS_BEGIN(); while(1) { - PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + /* Only if we are not in poll mode oder we are in poll mode and transceiver has to be reset */ + PROCESS_YIELD_UNTIL((!poll_mode || (poll_mode && (rf_flags & RF_MUST_RESET))) && (ev == PROCESS_EVENT_POLL)); - packetbuf_clear(); - len = read(packetbuf_dataptr(), PACKETBUF_SIZE); + if(!poll_mode) { + packetbuf_clear(); + len = read(packetbuf_dataptr(), PACKETBUF_SIZE); - if(len > 0) { - packetbuf_set_datalen(len); + if(len > 0) { + packetbuf_set_datalen(len); - NETSTACK_RDC.input(); + NETSTACK_RDC.input(); + } } /* If we were polled due to an RF error, reset the transceiver */ if(rf_flags & RF_MUST_RESET) { + uint8_t was_on; rf_flags = 0; + /* save state so we know if to switch on again after re-init */ + if((REG(RFCORE_XREG_FSMSTAT0) & RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE) == 0) { + was_on = 0; + } else { + was_on = 1; + } off(); init(); + if(was_on) { + /* switch back on */ + on(); + } } } @@ -701,8 +1075,10 @@ void cc2538_rf_rx_tx_isr(void) { ENERGEST_ON(ENERGEST_TYPE_IRQ); - - process_poll(&cc2538_rf_process); + + if(!poll_mode) { + process_poll(&cc2538_rf_process); + } /* We only acknowledge FIFOP so we can safely wipe out the entire SFR */ REG(RFCORE_SFR_RFIRQF0) = 0; @@ -748,11 +1124,47 @@ cc2538_rf_err_isr(void) void cc2538_rf_set_promiscous_mode(char p) { - if(p) { - REG(RFCORE_XREG_FRMFILT0) &= ~RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN; - } else { - REG(RFCORE_XREG_FRMFILT0) |= RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN; - } + set_frame_filtering(p); +} +/*---------------------------------------------------------------------------*/ +uint32_t get_sfd_timestamp(void) +{ + uint64_t sfd, timer_val, buffer; + + REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMSEL) | 0x00000000; + REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_LATCH_MODE; + timer_val = REG(RFCORE_SFR_MTM0) & RFCORE_SFR_MTM0_MTM0; + timer_val |= ((REG(RFCORE_SFR_MTM1) & RFCORE_SFR_MTM1_MTM1) << 8); + REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMOVFSEL) | 0x00000000; + timer_val |= ((REG(RFCORE_SFR_MTMOVF0) & RFCORE_SFR_MTMOVF0_MTMOVF0) << 16); + timer_val |= ((REG(RFCORE_SFR_MTMOVF1) & RFCORE_SFR_MTMOVF1_MTMOVF1) << 24); + buffer = REG(RFCORE_SFR_MTMOVF2) & RFCORE_SFR_MTMOVF2_MTMOVF2; + timer_val |= (buffer << 32); + + REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMSEL) | 0x00000001; + REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_LATCH_MODE; + sfd = REG(RFCORE_SFR_MTM0) & RFCORE_SFR_MTM0_MTM0; + sfd |= ((REG(RFCORE_SFR_MTM1) & RFCORE_SFR_MTM1_MTM1) << 8); + REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMOVFSEL) | 0x00000010; + sfd |= ((REG(RFCORE_SFR_MTMOVF0) & RFCORE_SFR_MTMOVF0_MTMOVF0) << 16); + sfd |= ((REG(RFCORE_SFR_MTMOVF1) & RFCORE_SFR_MTMOVF1_MTMOVF1) << 24); + buffer = REG(RFCORE_SFR_MTMOVF2) & RFCORE_SFR_MTMOVF2_MTMOVF2; + sfd |= (buffer << 32); + + return (RTIMER_NOW() - RADIO_TO_RTIMER(timer_val - sfd)); +} +/*---------------------------------------------------------------------------*/ +void mac_timer_init(void) +{ + CLOCK_STABLE(); + REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_SYNC; + REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_RUN; + while(!(REG(RFCORE_SFR_MTCTRL) & RFCORE_SFR_MTCTRL_STATE)); + REG(RFCORE_SFR_MTCTRL) &= ~RFCORE_SFR_MTCTRL_RUN; + while(REG(RFCORE_SFR_MTCTRL) & RFCORE_SFR_MTCTRL_STATE); + REG(RFCORE_SFR_MTCTRL) |= RFCORE_SFR_MTCTRL_SYNC; + REG(RFCORE_SFR_MTCTRL) |= (RFCORE_SFR_MTCTRL_RUN); + while(!(REG(RFCORE_SFR_MTCTRL) & RFCORE_SFR_MTCTRL_STATE)); } /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/cpu/cc2538/dev/cc2538-rf.h b/cpu/cc2538/dev/cc2538-rf.h index 9d48929cf..5edb478ba 100644 --- a/cpu/cc2538/dev/cc2538-rf.h +++ b/cpu/cc2538/dev/cc2538-rf.h @@ -56,6 +56,7 @@ #define CC2538_RF_CHANNEL_MIN 11 #define CC2538_RF_CHANNEL_MAX 26 #define CC2538_RF_CHANNEL_SPACING 5 +#define CC2538_RF_CHANNEL_SET_ERROR -1 #define CC2538_RF_MAX_PACKET_LEN 127 #define CC2538_RF_MIN_PACKET_LEN 4 #define CC2538_RF_CCA_CLEAR 1 @@ -132,31 +133,6 @@ /** The NETSTACK data structure for the cc2538 RF driver */ extern const struct radio_driver cc2538_rf_driver; /*---------------------------------------------------------------------------*/ -/** - * \brief Set the current operating channel - * \param channel The desired channel as a value in [11,26] - * \return Returns a value in [11,26] representing the current channel - * or a negative value if \e channel was out of bounds - */ -int8_t cc2538_rf_channel_set(uint8_t channel); - -/** - * \brief Get the current operating channel - * \return Returns a value in [11,26] representing the current channel - */ -uint8_t cc2538_rf_channel_get(void); - -/** - * \brief Sets RF TX power - * \param new_power The desired power level - * \return The power level in use after the adjustment - * - * The value specified in \e new_power will be written directly to the - * RFCORE_XREG_TXPOWER register. See the datasheet for more details on - * possible values. - */ -uint8_t cc2538_rf_power_set(uint8_t new_power); - /** * \brief Sets addresses and PAN identifier to the relevant RF hardware * registers @@ -168,15 +144,6 @@ uint8_t cc2538_rf_power_set(uint8_t new_power); */ void cc2538_rf_set_addr(uint16_t pan); -/** - * \brief Reads the current signal strength (RSSI) - * \return The current RSSI - * - * This function reads the current RSSI on the currently configured - * channel. - */ -int cc2538_rf_read_rssi(void); - /** * \brief Turn promiscous mode on or off * \param p If promiscous mode should be on (1) or off (0) @@ -187,7 +154,6 @@ int cc2538_rf_read_rssi(void); * address as the receive address are returned from the RF core. */ void cc2538_rf_set_promiscous_mode(char p); - /*---------------------------------------------------------------------------*/ #endif /* CC2538_RF_H__ */ diff --git a/cpu/cc2538/dev/cc2538-sensors.h b/cpu/cc2538/dev/cc2538-sensors.h new file mode 100644 index 000000000..b4d3ada91 --- /dev/null +++ b/cpu/cc2538/dev/cc2538-sensors.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc2538 + * @{ + * + * \defgroup cc2538-sensors CC2538 Built-In Sensors + * + * Module controlling sensors on the CC2538 SoC (Tmp and VDD3) + * @{ + * + * \file + * Generic header usable by all CC2538 sensor drivers + */ +/*---------------------------------------------------------------------------*/ +#ifndef CC2538_SENSORS_H_ +#define CC2538_SENSORS_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "dev/cc2538-temp-sensor.h" +#include "dev/vdd3-sensor.h" +/*---------------------------------------------------------------------------*/ +/** + * \name CC2538 sensor constants + * + * These constants are used by various sensors on the CC2538. They can be used + * to differentiate between raw and converted readings, to configure ADC + * decimation rate (where applicable). + * @{ + */ +#define CC2538_SENSORS_VALUE_TYPE_RAW 0 /**< Request the raw reading */ +#define CC2538_SENSORS_VALUE_TYPE_CONVERTED 1 /**< Request the converted reading */ + +#define CC2538_SENSORS_ERROR 0x80000000 /**< Generic Error */ +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* CC2538_SENSORS_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/cc2538-temp-sensor.c b/cpu/cc2538/dev/cc2538-temp-sensor.c new file mode 100644 index 000000000..dd5dcba6c --- /dev/null +++ b/cpu/cc2538/dev/cc2538-temp-sensor.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc2538-temp-sensor + * @{ + * + * \file + * Driver for the CC2538 On-Chip temperature sensor + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/adc.h" +#include "dev/cc2538-sensors.h" + +#include +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + int raw = adc_get(SOC_ADC_ADCCON_CH_TEMP, SOC_ADC_ADCCON_REF_INT, + SOC_ADC_ADCCON_DIV_512); + + if(type == CC2538_SENSORS_VALUE_TYPE_RAW) { + return raw; + } else if(type == CC2538_SENSORS_VALUE_TYPE_CONVERTED) { + return 25000 + ((raw >> 4) - 1422) * 10000 / 42; + } + + return CC2538_SENSORS_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(cc2538_temp_sensor, TEMP_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/cpu/cc2538/dev/cc2538-temp-sensor.h b/cpu/cc2538/dev/cc2538-temp-sensor.h new file mode 100644 index 000000000..b515c5042 --- /dev/null +++ b/cpu/cc2538/dev/cc2538-temp-sensor.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc2538-sensors + * @{ + * + * \defgroup cc2538-temp-sensor CC2538 on-chip temperature Sensor + * + * Driver for the CC2538 on-chip temperature sensor + * + * This driver can return the raw as well as the converted value of the sensor + * reading. This is controlled by the type argument of the sensor driver's + * value() function. The choices for the type argument are: + * - CC2538_SENSORS_VALUE_TYPE_RAW (value() returns the raw reading) + * - CC2538_SENSORS_VALUE_TYPE_CONVERTED (value() returns degrees mC) + * @{ + * + * \file + * Header file for the CC2538 on-chip temperature Sensor Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef CC2538_TEMP_SENSOR_H_ +#define CC2538_TEMP_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +/** + * \name temperature sensor + * @{ + */ +#define TEMP_SENSOR "On-Chip Temperature" +/** @} */ +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor cc2538_temp_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* CC2538_TEMP_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/ccm.c b/cpu/cc2538/dev/ccm.c new file mode 100644 index 000000000..7559fbe76 --- /dev/null +++ b/cpu/cc2538/dev/ccm.c @@ -0,0 +1,142 @@ +/* + * Original file: + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2013, ADVANSEE - http://www.advansee.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-ccm + * @{ + * + * \file + * Implementation of the cc2538 AES-CCM driver + */ +#include "contiki.h" +#include "sys/cc.h" +#include "dev/rom-util.h" +#include "dev/ccm.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +static uint8_t +ccm_auth_crypt_start(uint8_t encrypt, uint8_t len_len, uint8_t key_area, + const void *nonce, const void *adata, uint16_t adata_len, + const void *data_in, void *data_out, uint16_t data_len, + uint8_t mic_len, struct process *process) +{ + uint32_t ctrl; + uint32_t iv[AES_IV_LEN / sizeof(uint32_t)]; + + /* Program AES-CCM authentication/crypto operation */ + ctrl = AES_AES_CTRL_SAVE_CONTEXT | /* Save context */ + (((MAX(mic_len, 2) - 2) >> 1) << AES_AES_CTRL_CCM_M_S) | /* M */ + ((len_len - 1) << AES_AES_CTRL_CCM_L_S) | /* L */ + AES_AES_CTRL_CCM | /* CCM */ + AES_AES_CTRL_CTR_WIDTH_128 | /* CTR width 128 */ + AES_AES_CTRL_CTR | /* CTR */ + (encrypt ? AES_AES_CTRL_DIRECTION_ENCRYPT : 0); /* En/decryption */ + + /* Prepare the crypto initialization vector + * Flags: L' = L - 1 */ + ((uint8_t *)iv)[0] = len_len - 1; + /* Nonce */ + rom_util_memcpy(&((uint8_t *)iv)[CCM_FLAGS_LEN], nonce, + CCM_NONCE_LEN_LEN - len_len); + /* Initialize counter to 0 */ + rom_util_memset(&((uint8_t *)iv)[AES_IV_LEN - len_len], 0, len_len); + + return aes_auth_crypt_start(ctrl, key_area, iv, adata, adata_len, + data_in, data_out, data_len, process); +} +/*---------------------------------------------------------------------------*/ +static uint8_t +ccm_auth_crypt_get_result(const void *cdata, uint16_t cdata_len, + void *mic, uint8_t mic_len) +{ + uint32_t tag[AES_TAG_LEN / sizeof(uint32_t)]; + uint16_t data_len; + uint8_t ret; + + ret = aes_auth_crypt_get_result(NULL, tag); + if(ret != CRYPTO_SUCCESS) { + return ret; + } + + if(cdata != NULL) { + /* Check MIC */ + data_len = cdata_len - mic_len; + if(rom_util_memcmp(tag, &((const uint8_t *)cdata)[data_len], mic_len)) { + ret = AES_AUTHENTICATION_FAILED; + } + } + + /* Copy tag to MIC */ + rom_util_memcpy(mic, tag, mic_len); + + return ret; +} +/*---------------------------------------------------------------------------*/ +uint8_t +ccm_auth_encrypt_start(uint8_t len_len, uint8_t key_area, const void *nonce, + const void *adata, uint16_t adata_len, const void *pdata, + uint16_t pdata_len, void *cdata, uint8_t mic_len, + struct process *process) +{ + return ccm_auth_crypt_start(true, len_len, key_area, nonce, adata, adata_len, + pdata, cdata, pdata_len, mic_len, process); +} +/*---------------------------------------------------------------------------*/ +uint8_t +ccm_auth_encrypt_get_result(void *mic, uint8_t mic_len) +{ + return ccm_auth_crypt_get_result(NULL, 0, mic, mic_len); +} +/*---------------------------------------------------------------------------*/ +uint8_t +ccm_auth_decrypt_start(uint8_t len_len, uint8_t key_area, const void *nonce, + const void *adata, uint16_t adata_len, const void *cdata, + uint16_t cdata_len, void *pdata, uint8_t mic_len, + struct process *process) +{ + uint16_t data_len = cdata_len - mic_len; + + return ccm_auth_crypt_start(false, len_len, key_area, nonce, adata, adata_len, + cdata, pdata, data_len, mic_len, process); +} +/*---------------------------------------------------------------------------*/ +uint8_t +ccm_auth_decrypt_get_result(const void *cdata, uint16_t cdata_len, + void *mic, uint8_t mic_len) +__attribute__ ((alias("ccm_auth_crypt_get_result"))); + +/** @} */ diff --git a/cpu/cc2538/dev/ccm.h b/cpu/cc2538/dev/ccm.h new file mode 100644 index 000000000..156cd1a6f --- /dev/null +++ b/cpu/cc2538/dev/ccm.h @@ -0,0 +1,159 @@ +/* + * Original file: + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2013, ADVANSEE - http://www.advansee.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-aes + * @{ + * + * \defgroup cc2538-ccm cc2538 AES-CCM + * + * Driver for the cc2538 AES-CCM mode of the security core + * @{ + * + * \file + * Header file for the cc2538 AES-CCM driver + */ +#ifndef CCM_H_ +#define CCM_H_ + +#include "contiki.h" +#include "dev/aes.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/** \name AES-CCM constants + * @{ + */ +#define CCM_FLAGS_LEN 1 +#define CCM_NONCE_LEN_LEN (AES_IV_LEN - CCM_FLAGS_LEN) +#define CCM_MIC_MAX_LEN AES_TAG_LEN +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES-CCM functions + * @{ + */ + +/** \brief Starts a CCM authentication and encryption operation + * \param len_len Number of octets in length field (2, 4, or 8) + * \param key_area Area in Key RAM where the key is stored (0 to + * \c AES_KEY_AREAS - 1) + * \param nonce Pointer to nonce (\c CCM_NONCE_LEN_LEN - \p len_len octets) + * \param adata Pointer to additional authenticated data in SRAM, or \c NULL + * \param adata_len Length of additional authenticated data in octets, or \c 0 + * \param pdata Pointer to message to authenticate and encrypt in SRAM, or + * \c NULL + * \param pdata_len Length of message to authenticate and encrypt in octets, or + * \c 0 + * \param cdata Pointer to encrypted message in SRAM (may be \p pdata), or + * \c NULL + * \param mic_len Number of octets in authentication field (even value between 0 + * and \c CCM_MIC_MAX_LEN) + * \param process Process to be polled upon completion of the operation, or + * \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CCM error code + */ +uint8_t ccm_auth_encrypt_start(uint8_t len_len, uint8_t key_area, + const void *nonce, const void *adata, + uint16_t adata_len, const void *pdata, + uint16_t pdata_len, void *cdata, uint8_t mic_len, + struct process *process); + +/** \brief Checks the status of the CCM authentication and encryption operation + * \retval false Result not yet available, and no error occurred + * \retval true Result available, or error occurred + */ +#define ccm_auth_encrypt_check_status aes_auth_crypt_check_status + +/** \brief Gets the result of the CCM authentication and encryption operation + * \param mic Pointer to authentication field, or \c NULL + * \param mic_len Number of octets in authentication field (even value between 0 + * and \c CCM_MIC_MAX_LEN) + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CCM error code + * \note This function must be called only after \c ccm_auth_encrypt_start(). + */ +uint8_t ccm_auth_encrypt_get_result(void *mic, uint8_t mic_len); + +/** \brief Starts a CCM authentication checking and decryption operation + * \param len_len Number of octets in length field (2, 4, or 8) + * \param key_area Area in Key RAM where the key is stored (0 to + * \c AES_KEY_AREAS - 1) + * \param nonce Pointer to nonce (\c CCM_NONCE_LEN_LEN - \p len_len octets) + * \param adata Pointer to additional authenticated data in SRAM, or \c NULL + * \param adata_len Length of additional authenticated data in octets, or \c 0 + * \param cdata Pointer to encrypted and authenticated message in SRAM + * \param cdata_len Length of encrypted and authenticated message in octets + * \param pdata Pointer to decrypted message in SRAM (may be \p cdata), or + * \c NULL + * \param mic_len Number of octets in authentication field (even value between 0 + * and \c CCM_MIC_MAX_LEN) + * \param process Process to be polled upon completion of the operation, or + * \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CCM error code + */ +uint8_t ccm_auth_decrypt_start(uint8_t len_len, uint8_t key_area, + const void *nonce, const void *adata, + uint16_t adata_len, const void *cdata, + uint16_t cdata_len, void *pdata, uint8_t mic_len, + struct process *process); + +/** \brief Checks the status of the CCM authentication checking and decryption + * operation + * \retval false Result not yet available, and no error occurred + * \retval true Result available, or error occurred + */ +#define ccm_auth_decrypt_check_status aes_auth_crypt_check_status + +/** \brief Gets the result of the CCM authentication checking and decryption + * operation + * \param cdata Pointer to encrypted and authenticated message + * \param cdata_len Length of encrypted and authenticated message in octets + * \param mic Pointer to authentication field, or \c NULL + * \param mic_len Number of octets in authentication field (even value between 0 + * and \c CCM_MIC_MAX_LEN) + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CCM error code + * \note This function must be called only after \c ccm_auth_decrypt_start(). + */ +uint8_t ccm_auth_decrypt_get_result(const void *cdata, uint16_t cdata_len, + void *mic, uint8_t mic_len); + +/** @} */ + +#endif /* CCM_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/crypto.c b/cpu/cc2538/dev/crypto.c new file mode 100644 index 000000000..7dc5d3342 --- /dev/null +++ b/cpu/cc2538/dev/crypto.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013, ADVANSEE - http://www.advansee.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-crypto + * @{ + * + * \file + * Implementation of the cc2538 AES/SHA cryptoprocessor driver + */ +#include "contiki.h" +#include "sys/energest.h" +#include "dev/sys-ctrl.h" +#include "dev/nvic.h" +#include "dev/crypto.h" +#include "dev/aes.h" +#include "reg.h" +#include "lpm.h" + +#include +/*---------------------------------------------------------------------------*/ +static volatile struct process *notification_process = NULL; +/*---------------------------------------------------------------------------*/ +/** \brief The AES/SHA cryptoprocessor ISR + * + * This is the interrupt service routine for the AES/SHA + * cryptoprocessor. + * + * This ISR is called at worst from PM0, so lpm_exit() does not need + * to be called. + */ +void +crypto_isr(void) +{ + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + nvic_interrupt_unpend(NVIC_INT_AES); + nvic_interrupt_disable(NVIC_INT_AES); + + if(notification_process != NULL) { + process_poll((struct process *)notification_process); + notification_process = NULL; + } + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +static bool +permit_pm1(void) +{ + return REG(AES_CTRL_ALG_SEL) == 0; +} +/*---------------------------------------------------------------------------*/ +void +crypto_init(void) +{ + volatile int i; + + lpm_register_peripheral(permit_pm1); + + crypto_enable(); + + /* Reset the AES/SHA cryptoprocessor */ + REG(SYS_CTRL_SRSEC) |= SYS_CTRL_SRSEC_AES; + for(i = 0; i < 16; i++); + REG(SYS_CTRL_SRSEC) &= ~SYS_CTRL_SRSEC_AES; +} +/*---------------------------------------------------------------------------*/ +void +crypto_enable(void) +{ + /* Enable the clock for the AES/SHA cryptoprocessor */ + REG(SYS_CTRL_RCGCSEC) |= SYS_CTRL_RCGCSEC_AES; + REG(SYS_CTRL_SCGCSEC) |= SYS_CTRL_SCGCSEC_AES; + REG(SYS_CTRL_DCGCSEC) |= SYS_CTRL_DCGCSEC_AES; +} +/*---------------------------------------------------------------------------*/ +void +crypto_disable(void) +{ + /* Gate the clock for the AES/SHA cryptoprocessor */ + REG(SYS_CTRL_RCGCSEC) &= ~SYS_CTRL_RCGCSEC_AES; + REG(SYS_CTRL_SCGCSEC) &= ~SYS_CTRL_SCGCSEC_AES; + REG(SYS_CTRL_DCGCSEC) &= ~SYS_CTRL_DCGCSEC_AES; +} +/*---------------------------------------------------------------------------*/ +void +crypto_register_process_notification(struct process *p) +{ + notification_process = p; +} + +/** @} */ diff --git a/cpu/cc2538/dev/crypto.h b/cpu/cc2538/dev/crypto.h new file mode 100644 index 000000000..5d164a400 --- /dev/null +++ b/cpu/cc2538/dev/crypto.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013, ADVANSEE - http://www.advansee.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538 + * @{ + * + * \defgroup cc2538-crypto cc2538 AES/SHA cryptoprocessor + * + * Driver for the cc2538 AES/SHA cryptoprocessor + * @{ + * + * \file + * Header file for the cc2538 AES/SHA cryptoprocessor driver + */ +#ifndef CRYPTO_H_ +#define CRYPTO_H_ + +#include "contiki.h" +#include "dev/sys-ctrl.h" +#include "reg.h" +/*---------------------------------------------------------------------------*/ +/** \name Crypto drivers return codes + * @{ + */ +#define CRYPTO_PENDING (-1) +#define CRYPTO_SUCCESS 0 +#define CRYPTO_INVALID_PARAM 1 +#define CRYPTO_NULL_ERROR 2 +#define CRYPTO_RESOURCE_IN_USE 3 +#define CRYPTO_DMA_BUS_ERROR 4 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name Crypto macros + * @{ + */ + +/** \brief Indicates whether the AES/SHA cryptoprocessor is enabled + * \return Boolean value indicating whether the AES/SHA cryptoprocessor is + * enabled + */ +#define CRYPTO_IS_ENABLED() (!!(REG(SYS_CTRL_RCGCSEC) & SYS_CTRL_RCGCSEC_AES)) + +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name Crypto functions + * @{ + */ + +/** \brief Enables and resets the AES/SHA cryptoprocessor + */ +void crypto_init(void); + +/** \brief Enables the AES/SHA cryptoprocessor + */ +void crypto_enable(void); + +/** \brief Disables the AES/SHA cryptoprocessor + * \note Call this function to save power when the cryptoprocessor is unused. + */ +void crypto_disable(void); + +/** \brief Registers a process to be notified of the completion of a crypto + * operation + * \param p Process to be polled upon IRQ + * \note This function is only supposed to be called by the crypto drivers. + */ +void crypto_register_process_notification(struct process *p); + +/** @} */ + +#endif /* CRYPTO_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/ctr.c b/cpu/cc2538/dev/ctr.c new file mode 100644 index 000000000..0b0a88580 --- /dev/null +++ b/cpu/cc2538/dev/ctr.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-ctr + * @{ + * + * \file + * Implementation of the cc2538 AES-CTR driver + */ +#include "contiki.h" +#include "dev/rom-util.h" +#include "dev/ctr.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +uint8_t +ctr_crypt_start(uint8_t encrypt, uint8_t key_area, const void *nonce, + const void *ictr, uint8_t ctr_len, const void *mdata_in, + void *mdata_out, uint16_t mdata_len, struct process *process) +{ + uint32_t ctrl; + uint32_t iv[AES_IV_LEN / sizeof(uint32_t)]; + uint8_t nonce_len; + + /* Program AES-CTR crypto operation */ + ctrl = (((ctr_len >> 2) - 1) << AES_AES_CTRL_CTR_WIDTH_S) | /* CTR width */ + AES_AES_CTRL_CTR | /* CTR */ + (encrypt ? AES_AES_CTRL_DIRECTION_ENCRYPT : 0); /* En/decryption */ + + /* Prepare the crypto initialization vector */ + nonce_len = AES_IV_LEN - ctr_len; + /* Nonce */ + rom_util_memcpy(&((uint8_t *)iv)[0], nonce, nonce_len); + /* Initial counter */ + rom_util_memcpy(&((uint8_t *)iv)[nonce_len], ictr, ctr_len); + + return aes_auth_crypt_start(ctrl, key_area, iv, NULL, 0, + mdata_in, mdata_out, mdata_len, process); +} +/*---------------------------------------------------------------------------*/ +int8_t +ctr_crypt_check_status(void) +{ + return aes_auth_crypt_check_status() ? aes_auth_crypt_get_result(NULL, NULL) : + CRYPTO_PENDING; +} + +/** @} */ diff --git a/cpu/cc2538/dev/ctr.h b/cpu/cc2538/dev/ctr.h new file mode 100644 index 000000000..491859d8f --- /dev/null +++ b/cpu/cc2538/dev/ctr.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-aes + * @{ + * + * \defgroup cc2538-ctr cc2538 AES-CTR + * + * Driver for the cc2538 AES-CTR mode of the security core + * @{ + * + * \file + * Header file for the cc2538 AES-CTR driver + */ +#ifndef CTR_H_ +#define CTR_H_ + +#include "contiki.h" +#include "dev/aes.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/** \name AES-CTR functions + * @{ + */ + +/** \brief Starts a CTR crypto operation + * \param encrypt \c true to encrypt, or \c false to decrypt + * \param key_area Area in Key RAM where the key is stored (0 to + * \c AES_KEY_AREAS - 1) + * \param nonce Pointer to nonce (\c AES_IV_LEN - \p ctr_len octets), or \c NULL + * \param ictr Pointer to initial counter + * \param ctr_len Length of counter in octets (4, 8, 12, or 16) + * \param mdata_in Pointer to input message in SRAM + * \param mdata_out Pointer to output message in SRAM (may be \p mdata_in) + * \param mdata_len Length of message in octets + * \param process Process to be polled upon completion of the operation, or + * \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CTR error code + */ +uint8_t ctr_crypt_start(uint8_t encrypt, uint8_t key_area, const void *nonce, + const void *ictr, uint8_t ctr_len, const void *mdata_in, + void *mdata_out, uint16_t mdata_len, + struct process *process); + +/** \brief Checks the status of the CTR crypto operation + * \return \c CRYPTO_PENDING if operation still pending, \c CRYPTO_SUCCESS if + * successful, or CRYPTO/AES/CTR error code + * \note This function must be called only after \c ctr_crypt_start(). + */ +int8_t ctr_crypt_check_status(void); + +/** @} */ + +#endif /* CTR_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/ecb.c b/cpu/cc2538/dev/ecb.c new file mode 100644 index 000000000..ddbc0837b --- /dev/null +++ b/cpu/cc2538/dev/ecb.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-ecb + * @{ + * + * \file + * Implementation of the cc2538 AES-ECB driver + */ +#include "contiki.h" +#include "dev/ecb.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +uint8_t +ecb_crypt_start(uint8_t encrypt, uint8_t key_area, const void *mdata_in, + void *mdata_out, uint16_t mdata_len, struct process *process) +{ + uint32_t ctrl; + + /* Program AES-ECB crypto operation */ + ctrl = encrypt ? AES_AES_CTRL_DIRECTION_ENCRYPT : 0; /* En/decryption */ + + return aes_auth_crypt_start(ctrl, key_area, NULL, NULL, 0, + mdata_in, mdata_out, mdata_len, process); +} +/*---------------------------------------------------------------------------*/ +int8_t +ecb_crypt_check_status(void) +{ + return aes_auth_crypt_check_status() ? aes_auth_crypt_get_result(NULL, NULL) : + CRYPTO_PENDING; +} + +/** @} */ diff --git a/cpu/cc2538/dev/ecb.h b/cpu/cc2538/dev/ecb.h new file mode 100644 index 000000000..840ba4d57 --- /dev/null +++ b/cpu/cc2538/dev/ecb.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-aes + * @{ + * + * \defgroup cc2538-ecb cc2538 AES-ECB + * + * Driver for the cc2538 AES-ECB mode of the security core + * @{ + * + * \file + * Header file for the cc2538 AES-ECB driver + */ +#ifndef ECB_H_ +#define ECB_H_ + +#include "contiki.h" +#include "dev/aes.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/** \name AES-ECB functions + * @{ + */ + +/** \brief Starts an ECB crypto operation + * \param encrypt \c true to encrypt, or \c false to decrypt + * \param key_area Area in Key RAM where the key is stored (0 to + * \c AES_KEY_AREAS - 1) + * \param mdata_in Pointer to input message in SRAM + * \param mdata_out Pointer to output message in SRAM (may be \p mdata_in) + * \param mdata_len Length of message in octets + * \param process Process to be polled upon completion of the operation, or + * \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/ECB error code + */ +uint8_t ecb_crypt_start(uint8_t encrypt, uint8_t key_area, const void *mdata_in, + void *mdata_out, uint16_t mdata_len, + struct process *process); + +/** \brief Checks the status of the ECB crypto operation + * \return \c CRYPTO_PENDING if operation still pending, \c CRYPTO_SUCCESS if + * successful, or CRYPTO/AES/ECB error code + * \note This function must be called only after \c ecb_crypt_start(). + */ +int8_t ecb_crypt_check_status(void); + +/** @} */ + +#endif /* ECB_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/ecc-algorithm.c b/cpu/cc2538/dev/ecc-algorithm.c new file mode 100644 index 000000000..7ecd99ad8 --- /dev/null +++ b/cpu/cc2538/dev/ecc-algorithm.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2014, Institute for Pervasive Computing, ETH Zurich. + * All rights reserved. + * + * Author: Andreas Dröscher + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ +/** + * \addtogroup c2538-ecc-algo + * @{ + * + * \file + * Implementation of the cc2538 ECC Algorithms + */ +#include "contiki.h" +#include "sys/process.h" + +#include +#include + +#include "dev/ecc-algorithm.h" +#include "dev/ecc-driver.h" +#include "dev/pka.h" + +#define CHECK_RESULT(...) \ + state->result = __VA_ARGS__; \ + if(state->result) { \ + printf("Line: %u Error: %u\n", __LINE__, (unsigned int)state->result); \ + PT_EXIT(&state->pt); \ + } + +PT_THREAD(ecc_compare(ecc_compare_state_t *state)) { + PT_BEGIN(&state->pt); + + CHECK_RESULT(bignum_cmp_start(state->a, state->b, state->size, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + state->result = bignum_cmp_get_result(); + + PT_END(&state->pt); +} + +PT_THREAD(ecc_multiply(ecc_multiply_state_t *state)) { + PT_BEGIN(&state->pt); + + CHECK_RESULT(ecc_mul_start(state->secret, &state->point_in, state->curve_info, &state->rv, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + CHECK_RESULT(ecc_mul_get_result(&state->point_out, state->rv)); + + PT_END(&state->pt); +} + +PT_THREAD(ecc_dsa_sign(ecc_dsa_sign_state_t *state)) { + /* Executed Every Time */ + uint8_t size = state->curve_info->size; + const uint32_t *ord = state->curve_info->n; + + ec_point_t point; + memcpy(point.x, state->curve_info->x, sizeof(point.x)); + memcpy(point.y, state->curve_info->y, sizeof(point.y)); + + PT_BEGIN(&state->pt); + + /* Invert k_e mod n */ + CHECK_RESULT(bignum_inv_mod_start(state->k_e, size, ord, size, &state->rv, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + CHECK_RESULT(bignum_inv_mod_get_result(state->k_e_inv, size, state->rv)); + + /* Calculate Point R = K_e * GeneratorPoint */ + CHECK_RESULT(ecc_mul_start(state->k_e, &point, state->curve_info, &state->rv, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + CHECK_RESULT(ecc_mul_get_result(&state->point_r, state->rv)); + + /* Calculate signature using big math functions + * d*r (r is the x coordinate of PointR) */ + CHECK_RESULT(bignum_mul_start(state->secret, size, state->point_r.x, size, &state->rv, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + state->len = 24; + CHECK_RESULT(bignum_mul_get_result(state->signature_s, &state->len, state->rv)); + + /* d*r mod n */ + CHECK_RESULT(bignum_mod_start(state->signature_s, state->len, ord, size, &state->rv, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + CHECK_RESULT(bignum_mod_get_result(state->signature_s, size, state->rv)); + + /* hash + d*r */ + CHECK_RESULT(bignum_add_start(state->hash, size, state->signature_s, size, &state->rv, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + state->len = 24; + CHECK_RESULT(bignum_add_get_result(state->signature_s, &state->len, state->rv)); + + /* hash + d*r mod n */ + CHECK_RESULT(bignum_mod_start(state->signature_s, state->len, ord, size, &state->rv, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + CHECK_RESULT(bignum_mod_get_result(state->signature_s, size, state->rv)); + + /* k_e_inv * (hash + d*r) */ + CHECK_RESULT(bignum_mul_start(state->k_e_inv, size, state->signature_s, size, &state->rv, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + state->len = 24; + CHECK_RESULT(bignum_mul_get_result(state->signature_s, &state->len, state->rv)); + + /* k_e_inv * (hash + d*r) mod n */ + CHECK_RESULT(bignum_mod_start(state->signature_s, state->len, ord, size, &state->rv, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + CHECK_RESULT(bignum_mod_get_result(state->signature_s, size, state->rv)); + + PT_END(&state->pt); +} + +PT_THREAD(ecc_dsa_verify(ecc_dsa_verify_state_t *state)) { + /* Executed Every Time */ + uint8_t size = state->curve_info->size; + const uint32_t *ord = state->curve_info->n; + + ec_point_t point; + memcpy(point.x, state->curve_info->x, sizeof(point.x)); + memcpy(point.y, state->curve_info->y, sizeof(point.y)); + + PT_BEGIN(&state->pt); + + /* Invert s mod n */ + CHECK_RESULT(bignum_inv_mod_start(state->signature_s, size, ord, size, &state->rv, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + CHECK_RESULT(bignum_inv_mod_get_result(state->s_inv, size, state->rv)); + + /* Calculate u1 = s_inv * hash */ + CHECK_RESULT(bignum_mul_start(state->s_inv, size, state->hash, size, &state->rv, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + state->len = 24; + CHECK_RESULT(bignum_mul_get_result(state->u1, &state->len, state->rv)); + + /* Calculate u1 = s_inv * hash mod n */ + CHECK_RESULT(bignum_mod_start(state->u1, state->len, ord, size, &state->rv, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + CHECK_RESULT(bignum_mod_get_result(state->u1, size, state->rv)); + + /* Calculate u2 = s_inv * r */ + CHECK_RESULT(bignum_mul_start(state->s_inv, size, state->signature_r, size, &state->rv, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + state->len = 24; + CHECK_RESULT(bignum_mul_get_result(state->u2, &state->len, state->rv)); + + /* Calculate u2 = s_inv * r mod n */ + CHECK_RESULT(bignum_mod_start(state->u2, state->len, ord, size, &state->rv, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + CHECK_RESULT(bignum_mod_get_result(state->u2, size, state->rv)); + + /* Calculate p1 = u1 * A */ + CHECK_RESULT(ecc_mul_start(state->u1, &point, state->curve_info, &state->rv, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + CHECK_RESULT(ecc_mul_get_result(&state->p1, state->rv)); + + /* Calculate p2 = u1 * B */ + CHECK_RESULT(ecc_mul_start(state->u2, &state->public, state->curve_info, &state->rv, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + CHECK_RESULT(ecc_mul_get_result(&state->p2, state->rv)); + + /* Calculate P = p1 + p2 */ + CHECK_RESULT(ecc_add_start(&state->p1, &state->p2, state->curve_info, &state->rv, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + CHECK_RESULT(ecc_add_get_result(&state->p1, state->rv)); + + /* Verify Result */ + CHECK_RESULT(bignum_cmp_start(state->signature_r, state->p1.x, size, state->process)); + PT_WAIT_UNTIL(&state->pt, pka_check_status()); + state->result = bignum_cmp_get_result(); + if((state->result == PKA_STATUS_A_GR_B) || (state->result == PKA_STATUS_A_LT_B)) { + state->result = PKA_STATUS_SIGNATURE_INVALID; + } + + PT_END(&state->pt); +} + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/ecc-algorithm.h b/cpu/cc2538/dev/ecc-algorithm.h new file mode 100644 index 000000000..059f011ee --- /dev/null +++ b/cpu/cc2538/dev/ecc-algorithm.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2014, Institute for Pervasive Computing, ETH Zurich. + * All rights reserved. + * + * Author: Andreas Dröscher + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ +/** + * \addtogroup cc2538-ecc + * @{ + * + * \defgroup cc2538-ecc-algo cc2538 ECC Algorithms + * + * This is a implementation of ECDH, ECDSA sign and ECDSA verify. It + * uses ecc-driver to communicate with the PKA. It uses continuations + * to free the main CPU / thread while the PKA is calculating. + * + * \note + * Only one request can be processed at a time. + * Maximal supported key length is 384bit (12 words). + * @{ + * + * \file + * Header file for the cc2538 ECC Algorithms + */ +#ifndef ECC_ALGORITHM_H_ +#define ECC_ALGORITHM_H_ + +#include "dev/bignum-driver.h" +#include "dev/ecc-driver.h" + +typedef struct { + /* Containers for the State */ + struct pt pt; + struct process *process; + + /* Input Variables */ + uint32_t a[12]; /**< Left Number */ + uint32_t b[12]; /**< Right Number */ + uint8_t size; /**< Length of a and b */ + + /* Output Variables */ + uint8_t result; /**< Result Code */ +} ecc_compare_state_t; + +/** + * \brief Do a compare of two big numbers + * + * This function can be used for ECDH as well as + * Calculating a Public Key for ECDSA + */ +PT_THREAD(ecc_compare(ecc_compare_state_t *state)); + +typedef struct { + /* Containers for the State */ + struct pt pt; + struct process *process; + + /* Input Variables */ + ecc_curve_info_t *curve_info; /**< Curve defining the CyclicGroup */ + ec_point_t point_in; /**< Generator Point */ + uint32_t secret[12]; /**< Secret */ + + /* Variables Holding intermediate data (initialized/used internally) */ + uint32_t rv; /**< Address of Next Result in PKA SRAM */ + + /* Output Variables */ + uint8_t result; /**< Result Code */ + ec_point_t point_out; /**< Generated Point */ +} ecc_multiply_state_t; + +/** + * \brief Do a Multiplication on a EC + * + * This function can be used for ECDH as well as + * Calculating a Public Key for ECDSA + */ +PT_THREAD(ecc_multiply(ecc_multiply_state_t *state)); + +typedef struct { + /* Containers for the State */ + struct pt pt; + struct process *process; + + /* Input Variables */ + ecc_curve_info_t *curve_info; /**< Curve defining the CyclicGroup */ + uint32_t secret[12]; /**< Secret Key */ + uint32_t k_e[12]; /**< Ephemeral Key */ + uint32_t hash[12]; /**< Hash to be signed */ + + /* Variables Holding intermediate data (initialized/used internally) */ + uint32_t rv; /**< Address of Next Result in PKA SRAM */ + uint32_t k_e_inv[12]; /**< Inverted ephemeral Key */ + uint32_t len; /**< Length of intermediate Result */ + + /* Output Variables */ + uint8_t result; /**< Result Code */ + ec_point_t point_r; /**< Signature R (x coordinate) */ + uint32_t signature_s[24]; /**< Signature S */ +} ecc_dsa_sign_state_t; + +/** + * \brief Sign a Hash + * + * This function has to be called several times until the + * pt state is EXIT + * If the result code is 0 (SUCCESS) the signature can be + * read from point_r and signature_s + */ +PT_THREAD(ecc_dsa_sign(ecc_dsa_sign_state_t *state)); + +typedef struct { + /* Containers for the State */ + struct pt pt; + struct process *process; + + /* Input Variables */ + ecc_curve_info_t *curve_info; /**< Curve defining the CyclicGroup */ + uint32_t signature_r[12]; /**< Signature R */ + uint32_t signature_s[12]; /**< Signature S */ + uint32_t hash[12]; /**< Hash to be signed */ + ec_point_t public; /**< Signature R (x coordinate) */ + + /* Variables Holding intermediate data (initialized/used internally) */ + uint32_t rv; /**< Address of Next Result in PKA SRAM */ + uint32_t s_inv[12]; /**< Inverted ephemeral Key */ + uint32_t u1[24]; /**< Intermediate result */ + uint32_t u2[24]; /**< Intermediate result */ + ec_point_t p1; /**< Intermediate result */ + ec_point_t p2; /**< Intermediate result */ + uint32_t len; /**< Length of intermediate Result */ + + /* Output Variables */ + uint8_t result; /**< Result Code */ +} ecc_dsa_verify_state_t; + +/** + * \brief Verify Signature + * + * This function has to be called several times until the + * pt state is EXIT + * If the result code is 0 (SUCCESS) the verification + * was success full. + * \note some error codes signal internal errors + * and others signal falls signatures. + */ +PT_THREAD(ecc_dsa_verify(ecc_dsa_verify_state_t *state)); + +#endif /* ECC_ALGORITHM_H_ */ + +/** + * @} + * @} + */ + diff --git a/cpu/cc2538/dev/ecc-curve.c b/cpu/cc2538/dev/ecc-curve.c new file mode 100644 index 000000000..d3291d1b6 --- /dev/null +++ b/cpu/cc2538/dev/ecc-curve.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014, Institute for Pervasive Computing, ETH Zurich. + * All rights reserved. + * + * Author: Andreas Dröscher + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ +/** + * \addtogroup c2538-ecc-curves + * @{ + */ +#include "contiki.h" +#include "dev/ecc-driver.h" + +/* [NIST P-256, X9.62 prime256v1] */ +static const uint32_t nist_p_256_p[8] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF }; +static const uint32_t nist_p_256_n[8] = { 0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF }; +static const uint32_t nist_p_256_a[8] = { 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF }; +static const uint32_t nist_p_256_b[8] = { 0x27D2604B, 0x3BCE3C3E, 0xCC53B0F6, 0x651D06B0, + 0x769886BC, 0xB3EBBD55, 0xAA3A93E7, 0x5AC635D8 }; +static const uint32_t nist_p_256_x[8] = { 0xD898C296, 0xF4A13945, 0x2DEB33A0, 0x77037D81, + 0x63A440F2, 0xF8BCE6E5, 0xE12C4247, 0x6B17D1F2 }; +static const uint32_t nist_p_256_y[8] = { 0x37BF51F5, 0xCBB64068, 0x6B315ECE, 0x2BCE3357, + 0x7C0F9E16, 0x8EE7EB4A, 0xFE1A7F9B, 0x4FE342E2 }; + +ecc_curve_info_t nist_p_256 = { + .name = "NIST P-256", + .size = 8, + .prime = nist_p_256_p, + .n = nist_p_256_n, + .a = nist_p_256_a, + .b = nist_p_256_b, + .x = nist_p_256_x, + .y = nist_p_256_y +}; + +/* [NIST P-192, X9.62 prime192v1] */ +static const uint32_t nist_p_192_p[6] = { 0xffffffff, 0xffffffff, 0xfffffffe, 0xffffffff, + 0xffffffff, 0xffffffff }; +static const uint32_t nist_p_192_a[6] = { 0xfffffffc, 0xffffffff, 0xfffffffe, 0xffffffff, + 0xffffffff, 0xffffffff }; +static const uint32_t nist_p_192_b[6] = { 0xc146b9b1, 0xfeb8deec, 0x72243049, 0x0fa7e9ab, + 0xe59c80e7, 0x64210519 }; +static const uint32_t nist_p_192_x[6] = { 0x82ff1012, 0xf4ff0afd, 0x43a18800, 0x7cbf20eb, + 0xb03090f6, 0x188da80e }; +static const uint32_t nist_p_192_y[6] = { 0x1e794811, 0x73f977a1, 0x6b24cdd5, 0x631011ed, + 0xffc8da78, 0x07192b95 }; +static const uint32_t nist_p_192_n[6] = { 0xb4d22831, 0x146bc9b1, 0x99def836, 0xffffffff, + 0xffffffff, 0xffffffff }; + +ecc_curve_info_t nist_p_192 = { + .name = "NIST P-192", + .size = 6, + .prime = nist_p_192_p, + .n = nist_p_192_n, + .a = nist_p_192_a, + .b = nist_p_192_b, + .x = nist_p_192_x, + .y = nist_p_192_y +}; + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/ecc-curve.h b/cpu/cc2538/dev/ecc-curve.h new file mode 100644 index 000000000..66c050a08 --- /dev/null +++ b/cpu/cc2538/dev/ecc-curve.h @@ -0,0 +1,65 @@ +/* + * Original file: + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2014 Andreas Dröscher + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-ecc + * @{ + * + * \defgroup cc2538-ecc-curves cc2538 NIST curves + * + * NIST curves for various key sizes + * @{ + * + * \file + * NIST curves for various key sizes + */ +#ifndef ECC_CURVE_H_ +#define ECC_CURVE_H_ + +/* + * NIST P-256, X9.62 prime256v1 + */ +ecc_curve_info_t nist_p_256; + +/* + * NIST P-192, X9.62 prime192v1 + */ +ecc_curve_info_t nist_p_192; + +#endif /* CURVE_INFO_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/ecc-driver.c b/cpu/cc2538/dev/ecc-driver.c new file mode 100644 index 000000000..d6bc5903c --- /dev/null +++ b/cpu/cc2538/dev/ecc-driver.c @@ -0,0 +1,559 @@ +/* + * Original file: + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2014 Andreas Dröscher + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-ecc + * @{ + * + * \file + * Implementation of the cc2538 ECC driver + */ +#include "dev/ecc-driver.h" +#include "reg.h" +#include "dev/nvic.h" + +#define ASSERT(IF) if(!(IF)) { return PKA_STATUS_INVALID_PARAM; } + +/*---------------------------------------------------------------------------*/ +uint8_t +ecc_mul_start(uint32_t *scalar, ec_point_t *ec_point, + ecc_curve_info_t *curve, uint32_t *result_vector, + struct process *process) +{ + + uint8_t extraBuf; + uint32_t offset; + int i; + + /* Check for the arguments. */ + ASSERT(NULL != scalar); + ASSERT(NULL != ec_point); + ASSERT(NULL != ec_point->x); + ASSERT(NULL != ec_point->y); + ASSERT(NULL != curve); + ASSERT(curve->size <= PKA_MAX_CURVE_SIZE); + ASSERT(NULL != result_vector); + + offset = 0; + + /* Make sure no PKA operation is in progress. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Calculate the extra buffer requirement. */ + extraBuf = 2 + curve->size % 2; + + /* Update the A ptr with the offset address of the PKA RAM location + * where the scalar will be stored. */ + REG(PKA_APTR) = offset >> 2; + + /* Load the scalar in PKA RAM. */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = *scalar++; + } + + /* Determine the offset for the next data. */ + offset += 4 * (i + (curve->size % 2)); + + /* Update the B ptr with the offset address of the PKA RAM location + * where the curve parameters will be stored. */ + REG(PKA_BPTR) = offset >> 2; + + /* Write curve parameter 'p' as 1st part of vector B immediately + * following vector A at PKA RAM */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->prime[i]; + } + + /* Determine the offset for the next data. */ + offset += 4 * (i + extraBuf); + + /* Copy curve parameter 'a' in PKA RAM. */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->a[i]; + } + + /* Determine the offset for the next data. */ + offset += 4 * (i + extraBuf); + + /* Copy curve parameter 'b' in PKA RAM. */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->b[i]; + } + + /* Determine the offset for the next data. */ + offset += 4 * (i + extraBuf); + + /* Update the C ptr with the offset address of the PKA RAM location + * where the x, y will be stored. */ + REG(PKA_CPTR) = offset >> 2; + + /* Write elliptic curve point.x co-ordinate value. */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = ec_point->x[i]; + } + + /* Determine the offset for the next data. */ + offset += 4 * (i + extraBuf); + + /* Write elliptic curve point.y co-ordinate value. */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = ec_point->y[i]; + } + + /* Determine the offset for the next data. */ + offset += 4 * (i + extraBuf); + + /* Update the result location. */ + *result_vector = PKA_RAM_BASE + offset; + + /* Load D ptr with the result location in PKA RAM. */ + REG(PKA_DPTR) = offset >> 2; + + /* Load length registers. */ + REG(PKA_ALENGTH) = curve->size; + REG(PKA_BLENGTH) = curve->size; + + /* set the PKA function to ECC-MULT and start the operation. */ + REG(PKA_FUNCTION) = 0x0000D000; + + /* Enable Interrupt */ + if(process != NULL) { + pka_register_process_notification(process); + nvic_interrupt_unpend(NVIC_INT_PKA); + nvic_interrupt_enable(NVIC_INT_PKA); + } + + return PKA_STATUS_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +ecc_mul_get_result(ec_point_t *ec_point, + uint32_t result_vector) +{ + int i; + uint32_t addr; + uint32_t regMSWVal; + uint32_t len; + + /* Check for the arguments. */ + ASSERT(NULL != ec_point); + ASSERT(NULL != ec_point->x); + ASSERT(NULL != ec_point->y); + ASSERT(result_vector > PKA_RAM_BASE); + ASSERT(result_vector < (PKA_RAM_BASE + PKA_RAM_SIZE)); + + /* Verify that the operation is completed. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Disable Interrupt */ + nvic_interrupt_disable(NVIC_INT_PKA); + pka_register_process_notification(NULL); + + if(REG(PKA_SHIFT) == 0x00000000) { + /* Get the MSW register value. */ + regMSWVal = REG(PKA_MSW); + + /* Check to make sure that the result vector is not all zeroes. */ + if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) { + return PKA_STATUS_RESULT_0; + } + + /* Get the length of the result */ + len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1) + - ((result_vector - PKA_RAM_BASE) >> 2); + + addr = result_vector; + + /* copy the x co-ordinate value of the result from vector D into + * the \e ec_point. */ + for(i = 0; i < len; i++) { + ec_point->x[i] = REG(addr + 4 * i); + } + + addr += 4 * (i + 2 + len % 2); + + /* copy the y co-ordinate value of the result from vector D into + * the \e ec_point. */ + for(i = 0; i < len; i++) { + ec_point->y[i] = REG(addr + 4 * i); + } + + return PKA_STATUS_SUCCESS; + } else { + return PKA_STATUS_FAILURE; + } +} +/*---------------------------------------------------------------------------*/ +uint8_t +ecc_mul_gen_pt_start(uint32_t *scalar, ecc_curve_info_t *curve, + uint32_t *result_vector, struct process *process) +{ + uint8_t extraBuf; + uint32_t offset; + int i; + + /* check for the arguments. */ + ASSERT(NULL != scalar); + ASSERT(NULL != curve); + ASSERT(curve->size <= PKA_MAX_CURVE_SIZE); + ASSERT(NULL != result_vector); + + offset = 0; + + /* Make sure no operation is in progress. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Calculate the extra buffer requirement. */ + extraBuf = 2 + curve->size % 2; + + /* Update the A ptr with the offset address of the PKA RAM location + * where the scalar will be stored. */ + REG(PKA_APTR) = offset >> 2; + + /* Load the scalar in PKA RAM. */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = *scalar++; + } + + /* Determine the offset in PKA RAM for the next data. */ + offset += 4 * (i + (curve->size % 2)); + + /* Update the B ptr with the offset address of the PKA RAM location + * where the curve parameters will be stored. */ + REG(PKA_BPTR) = offset >> 2; + + /* Write curve parameter 'p' as 1st part of vector B. */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->prime[i]; + } + + /* Determine the offset in PKA RAM for the next data. */ + offset += 4 * (i + extraBuf); + + /* Write curve parameter 'a' in PKA RAM. */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->a[i]; + } + + /* Determine the offset in PKA RAM for the next data. */ + offset += 4 * (i + extraBuf); + + /* write curve parameter 'b' in PKA RAM. */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->b[i]; + } + + /* Determine the offset in PKA RAM for the next data. */ + offset += 4 * (i + extraBuf); + + /* Update the C ptr with the offset address of the PKA RAM location + * where the x, y will be stored. */ + REG(PKA_CPTR) = offset >> 2; + + /* Write x co-ordinate value of the Generator point in PKA RAM. */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->x[i]; + } + + /* Determine the offset in PKA RAM for the next data. */ + offset += 4 * (i + extraBuf); + + /* Write y co-ordinate value of the Generator point in PKA RAM. */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->y[i]; + } + + /* Determine the offset in PKA RAM for the next data. */ + offset += 4 * (i + extraBuf); + + /* Update the result location. */ + *result_vector = PKA_RAM_BASE + offset; + + /* Load D ptr with the result location in PKA RAM. */ + REG(PKA_DPTR) = offset >> 2; + + /* Load length registers. */ + REG(PKA_ALENGTH) = curve->size; + REG(PKA_BLENGTH) = curve->size; + + /* Set the PKA function to ECC-MULT and start the operation. */ + REG(PKA_FUNCTION) = 0x0000D000; + + /* Enable Interrupt */ + if(process != NULL) { + pka_register_process_notification(process); + nvic_interrupt_unpend(NVIC_INT_PKA); + nvic_interrupt_enable(NVIC_INT_PKA); + } + + return PKA_STATUS_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +ecc_mul_gen_pt_get_result(ec_point_t *ec_point, + uint32_t result_vector) +{ + + int i; + uint32_t regMSWVal; + uint32_t addr; + uint32_t len; + + /* Check for the arguments. */ + ASSERT(NULL != ec_point); + ASSERT(NULL != ec_point->x); + ASSERT(NULL != ec_point->y); + ASSERT(result_vector > PKA_RAM_BASE); + ASSERT(result_vector < (PKA_RAM_BASE + PKA_RAM_SIZE)); + + /* Verify that the operation is completed. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Disable Interrupt */ + nvic_interrupt_disable(NVIC_INT_PKA); + pka_register_process_notification(NULL); + + if(REG(PKA_SHIFT) == 0x00000000) { + /* Get the MSW register value. */ + regMSWVal = REG(PKA_MSW); + + /* Check to make sure that the result vector is not all zeroes. */ + if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) { + return PKA_STATUS_RESULT_0; + } + + /* Get the length of the result. */ + len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1) + - ((result_vector - PKA_RAM_BASE) >> 2); + + addr = result_vector; + + /* Copy the x co-ordinate value of the result from vector D into the + * EC point. */ + for(i = 0; i < len; i++) { + ec_point->x[i] = REG(addr + 4 * i); + } + + addr += 4 * (i + 2 + len % 2); + + /* Copy the y co-ordinate value of the result from vector D into the + * EC point. */ + for(i = 0; i < len; i++) { + ec_point->y[i] = REG(addr + 4 * i); + } + + return PKA_STATUS_SUCCESS; + } else { + return PKA_STATUS_FAILURE; + } +} +/*---------------------------------------------------------------------------*/ +uint8_t +ecc_add_start(ec_point_t *ec_point1, ec_point_t *ec_point2, + ecc_curve_info_t *curve, uint32_t *result_vector, + struct process *process) +{ + + uint8_t extraBuf; + uint32_t offset; + int i; + + /* Check for the arguments. */ + ASSERT(NULL != ec_point1); + ASSERT(NULL != ec_point1->x); + ASSERT(NULL != ec_point1->y); + ASSERT(NULL != ec_point2); + ASSERT(NULL != ec_point2->x); + ASSERT(NULL != ec_point2->y); + ASSERT(NULL != curve); + ASSERT(NULL != result_vector); + + offset = 0; + + /* Make sure no operation is in progress. */ + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Calculate the extra buffer requirement. */ + extraBuf = 2 + curve->size % 2; + + /* Update the A ptr with the offset address of the PKA RAM location + * where the first ecPt will be stored. */ + REG(PKA_APTR) = offset >> 2; + + /* Load the x co-ordinate value of the first EC point in PKA RAM. */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = ec_point1->x[i]; + } + + /* Determine the offset in PKA RAM for the next data. */ + offset += 4 * (i + extraBuf); + + /* Load the y co-ordinate value of the first EC point in PKA RAM. */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = ec_point1->y[i]; + } + + /* Determine the offset in PKA RAM for the next data. */ + offset += 4 * (i + extraBuf); + + /* Update the B ptr with the offset address of the PKA RAM location + * where the curve parameters will be stored. */ + REG(PKA_BPTR) = offset >> 2; + + /* Write curve parameter 'p' as 1st part of vector B */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->prime[i]; + } + + /* Determine the offset in PKA RAM for the next data. */ + offset += 4 * (i + extraBuf); + + /* Write curve parameter 'a'. */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->a[i]; + } + + /* Determine the offset in PKA RAM for the next data. */ + offset += 4 * (i + extraBuf); + + /* Update the C ptr with the offset address of the PKA RAM location + * where the ecPt2 will be stored. */ + REG(PKA_CPTR) = offset >> 2; + + /* Load the x co-ordinate value of the second EC point in PKA RAM. */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = ec_point2->x[i]; + } + + /* Determine the offset in PKA RAM for the next data. */ + offset += 4 * (i + extraBuf); + + /* Load the y co-ordinate value of the second EC point in PKA RAM. */ + for(i = 0; i < curve->size; i++) { + REG(PKA_RAM_BASE + offset + 4 * i) = ec_point2->y[i]; + } + + /* Determine the offset in PKA RAM for the next data. */ + offset += 4 * (i + extraBuf); + + /* Copy the result vector location. */ + *result_vector = PKA_RAM_BASE + offset; + + /* Load D ptr with the result location in PKA RAM. */ + REG(PKA_DPTR) = offset >> 2; + + /* Load length registers. */ + REG(PKA_BLENGTH) = curve->size; + + /* Set the PKA Function to ECC-ADD and start the operation. */ + REG(PKA_FUNCTION) = 0x0000B000; + + /* Enable Interrupt */ + if(process != NULL) { + pka_register_process_notification(process); + nvic_interrupt_unpend(NVIC_INT_PKA); + nvic_interrupt_enable(NVIC_INT_PKA); + } + + return PKA_STATUS_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +ecc_add_get_result(ec_point_t *ec_point, uint32_t result_vector) +{ + uint32_t regMSWVal; + uint32_t addr; + int i; + uint32_t len; + + /* Check for the arguments. */ + ASSERT(NULL != ec_point); + ASSERT(NULL != ec_point->x); + ASSERT(NULL != ec_point->y); + ASSERT(result_vector > PKA_RAM_BASE); + ASSERT(result_vector < (PKA_RAM_BASE + PKA_RAM_SIZE)); + + if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) { + return PKA_STATUS_OPERATION_INPRG; + } + + /* Disable Interrupt */ + nvic_interrupt_disable(NVIC_INT_PKA); + pka_register_process_notification(NULL); + + if(REG(PKA_SHIFT) == 0x00000000) { + /* Get the MSW register value. */ + regMSWVal = REG(PKA_MSW); + + /* Check to make sure that the result vector is not all zeroes. */ + if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) { + return PKA_STATUS_RESULT_0; + } + + /* Get the length of the result. */ + len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1) + - ((result_vector - PKA_RAM_BASE) >> 2); + + addr = result_vector; + + /* Copy the x co-ordinate value of result from vector D into the + * the output EC Point. */ + for(i = 0; i < len; i++) { + ec_point->x[i] = REG(addr + 4 * i); + } + + addr += 4 * (i + 2 + len % 2); + + /* Copy the y co-ordinate value of result from vector D into the + * the output EC Point. */ + for(i = 0; i < len; i++) { + ec_point->y[i] = REG(addr + 4 * i); + } + + return PKA_STATUS_SUCCESS; + } else { + return PKA_STATUS_FAILURE; + } +} +/** @} */ diff --git a/cpu/cc2538/dev/ecc-driver.h b/cpu/cc2538/dev/ecc-driver.h new file mode 100644 index 000000000..3f71153a9 --- /dev/null +++ b/cpu/cc2538/dev/ecc-driver.h @@ -0,0 +1,227 @@ +/* + * Original file: + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2014 Andreas Dröscher + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-pka + * @{ + * + * \defgroup cc2538-ecc cc2538 ECC driver + * + * Driver for the cc2538 ECC mode of the PKC engine + * @{ + * + * \file + * Header file for the cc2538 ECC driver + */ +#ifndef ECC_DRIVER_H_ +#define ECC_DRIVER_H_ + +#include "contiki.h" +#include "dev/pka.h" + +#include +/*---------------------------------------------------------------------------*/ +/** \name ECC structures + * @{ + */ +typedef struct { + const char *name; /**< Name of the curve. */ + const uint8_t size; /**< Size of the curve in 32-bit word. */ + const uint32_t *prime; /**< The prime that defines the field of the curve. */ + const uint32_t *n; /**< Order of the curve. */ + const uint32_t *a; /**< Co-efficient a of the equation. */ + const uint32_t *b; /**< co-efficient b of the equation. */ + const uint32_t *x; /**< x co-ordinate value of the generator point. */ + const uint32_t *y; /**< y co-ordinate value of the generator point. */ +} ecc_curve_info_t; + +typedef struct { + uint32_t x[12]; /**< Pointer to value of the x co-ordinate. */ + uint32_t y[12]; /**< Pointer to value of the y co-ordinate. */ +} ec_point_t; + +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name ECC functions + * \note Not all sequencer functions are implemented in this driver + * look at the CC2538 manual for a complete list. + * @{ + */ + +/** \brief Starts ECC Multiplication. + * + * \param scalar Pointer to the buffer containing the scalar + * value to be multiplied. + * \param ec_point Pointer to the structure containing the + * elliptic curve point to be multiplied. The point should be + * on the given curve. + * \param curve Pointer to the structure containing the curve + * info. + * \param result_vector Pointer to the result vector location + * which will be set by this function. + * \param process Process to be polled upon completion of the + * operation, or \c NULL + * + * This function starts the Elliptical curve cryptography (ECC) point + * multiplication operation on the EC point and the scalar value. + * + * \retval PKA_STATUS_SUCCESS if successful in starting the operation. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing + * some other operation. + */ +uint8_t ecc_mul_start(uint32_t *scalar, + ec_point_t *ec_point, + ecc_curve_info_t *curve, + uint32_t *result_vector, + struct process *process); + +/** \brief Gets the result of ECC Multiplication + * + * \param ec_point Pointer to the structure where the resultant EC + * point will be stored. The callee is responsible to allocate the + * space for the ec point structure and the x and y co-ordinate as well. + * \param result_vector Address of the result location which + * was provided by the start function \sa PKAECCMultiplyStart(). + * + * This function gets the result of ecc point multiplication operation on the + * ec point and the scalar value, previously started using the function + * \sa PKAECCMultiplyStart(). + * + * \retval PKA_STATUS_SUCCESS if the operation is successful. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing + * the operation. + * \retval PKA_STATUS_RESULT_0 if the result is all zeroes. + * \retval PKA_STATUS_FAILURE if the operation is not successful. + */ +uint8_t ecc_mul_get_result(ec_point_t *ec_point, + uint32_t result_vector); + +/** \brief Starts the ECC Multiplication with Generator point. + * + * \param scalar Pointer to the buffer containing the + * scalar value. + * \param curve Pointer to the structure containing the curve + * info. + * \param result_vector Pointer to the result vector location + * which will be set by this function. + * \param process Process to be polled upon completion of the + * operation, or \c NULL + * + * This function starts the ecc point multiplication operation of the + * scalar value with the well known generator point of the given curve. + * + * \retval PKA_STATUS_SUCCESS if successful in starting the operation. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing + * some other operation. + */ +uint8_t ecc_mul_gen_pt_start(uint32_t *scalar, + ecc_curve_info_t *curve, + uint32_t *result_vector, + struct process *process); + +/** \brief Gets the result of ECC Multiplication with Generator point. + * + * \param ec_point Pointer to the structure where the resultant EC + * point will be stored. The callee is responsible to allocate the + * space for the ec point structure and the x and y co-ordinate as well. + * \param result_vector Address of the result location which + * was provided by the start function \sa PKAECCMultGenPtStart(). + * + * This function gets the result of ecc point multiplication operation on the + * scalar point and the known generator point on the curve, previously started + * using the function \sa PKAECCMultGenPtStart(). + * + * \retval PKA_STATUS_SUCCESS if the operation is successful. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing + * the operation. + * \retval PKA_STATUS_RESULT_0 if the result is all zeroes. + * \retval PKA_STATUS_FAILURE if the operation is not successful. + */ +uint8_t ecc_mul_gen_pt_get_result(ec_point_t *ec_point, + uint32_t result_vector); + +/** \brief Starts the ECC Addition. + * + * \param ec_point1 Pointer to the structure containing the first + * ecc point. + * \param ec_point2 Pointer to the structure containing the + * second ecc point. + * \param curve Pointer to the structure containing the curve + * info. + * \param result_vector Pointer to the result vector location + * which will be set by this function. + * \param process Process to be polled upon completion of the + * operation, or \c NULL + * + * This function starts the ecc point addition operation on the + * two given ec points and generates the resultant ecc point. + * + * \retval PKA_STATUS_SUCCESS if successful in starting the operation. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing + * some other operation. + */ +uint8_t ecc_add_start(ec_point_t *ec_point1, ec_point_t *ec_point2, + ecc_curve_info_t *curve, + uint32_t *result_vector, + struct process *process); + +/** \brief Gets the result of the ECC Addition + * + * \param ptOutEcPt Pointer to the structure where the resultant + * point will be stored. The callee is responsible to allocate memory, + * for the ec point structure including the memory for x and y + * co-ordinate values. + * \param ui32ResultLoc Address of the result location which + * was provided by the function \sa PKAECCAddStart(). + * + * This function gets the result of ecc point addition operation on the + * on the two given ec points, previously started using the function \sa + * PKAECCAddStart(). + * + * \retval PKA_STATUS_SUCCESS if the operation is successful. + * \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing + * the operation. + * \retval PKA_STATUS_RESULT_0 if the result is all zeroes. + * \retval PKA_STATUS_FAILURE if the operation is not successful. + */ +uint8_t ecc_add_get_result(ec_point_t *ptOutEcPt, uint32_t ui32ResultLoc); + +/** @} */ + +#endif /* ECC_DRIVER_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/flash-cca.h b/cpu/cc2538/dev/flash.h similarity index 74% rename from cpu/cc2538/dev/flash-cca.h rename to cpu/cc2538/dev/flash.h index 2dff2978b..49db85b20 100644 --- a/cpu/cc2538/dev/flash-cca.h +++ b/cpu/cc2538/dev/flash.h @@ -36,20 +36,37 @@ * \addtogroup cc2538 * @{ * - * \defgroup cc2538-flash-cca cc2538 flash CCA + * \defgroup cc2538-flash cc2538 flash memory * - * Definitions for the cc2538 flash lock bit page and customer configuration - * area + * Definitions for the cc2538 flash memory * @{ * * \file - * Header file for the flash lock bit page and CCA definitions + * Header file for the flash memory definitions */ -#ifndef FLASH_CCA_H_ -#define FLASH_CCA_H_ +#ifndef FLASH_H_ +#define FLASH_H_ + +#include "dev/cc2538-dev.h" +#include "cfs-coffee-arch.h" #include /*---------------------------------------------------------------------------*/ +/** \name Flash memory organization + * @{ + */ +#define FLASH_PAGE_SIZE 2048 +#define FLASH_WORD_SIZE 4 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name Flash lock bit page and CCA location + * @{ + */ +#define FLASH_CCA_ADDR (CC2538_DEV_FLASH_ADDR + CC2538_DEV_FLASH_SIZE - \ + FLASH_CCA_SIZE) /**< Address */ +#define FLASH_CCA_SIZE 0x0000002C /**< Size in bytes */ +/** @} */ +/*---------------------------------------------------------------------------*/ /** \name Bootloader backdoor configuration bit fields * @{ */ @@ -74,6 +91,23 @@ #define FLASH_CCA_LOCK_DEBUG_BIT 7 /**< Debug lock bit position in the corresponding lock byte */ /** @} */ /*---------------------------------------------------------------------------*/ +/** \name Firmware location in flash memory + * @{ + */ +#ifdef FLASH_CONF_FW_ADDR +#define FLASH_FW_ADDR FLASH_CONF_FW_ADDR +#elif !defined(COFFEE_CONF_CUSTOM_PORT) +#define FLASH_FW_ADDR (COFFEE_START + COFFEE_SIZE) +#else +#define FLASH_FW_ADDR CC2538_DEV_FLASH_ADDR +#endif +#ifdef FLASH_CONF_FW_SIZE +#define FLASH_FW_SIZE FLASH_CONF_FW_SIZE +#else +#define FLASH_FW_SIZE (FLASH_CCA_ADDR - FLASH_FW_ADDR) +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ /** \name Flash lock bit page and CCA layout * @{ */ @@ -85,7 +119,7 @@ typedef struct { } flash_cca_lock_page_t; /** @} */ -#endif /* FLASH_CCA_H_ */ +#endif /* FLASH_H_ */ /** * @} diff --git a/cpu/cc2538/dev/gcm.c b/cpu/cc2538/dev/gcm.c new file mode 100644 index 000000000..3108f00d0 --- /dev/null +++ b/cpu/cc2538/dev/gcm.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-gcm + * @{ + * + * \file + * Implementation of the cc2538 AES-GCM driver + */ +#include "contiki.h" +#include "dev/rom-util.h" +#include "dev/gcm.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +static uint8_t +gcm_auth_crypt_start(uint8_t encrypt, uint8_t key_area, const void *iv, + const void *adata, uint16_t adata_len, + const void *data_in, void *data_out, uint16_t data_len, + struct process *process) +{ + uint32_t ctrl; + uint32_t aes_iv[AES_IV_LEN / sizeof(uint32_t)]; + + /* Program AES-GCM authentication/crypto operation */ + ctrl = AES_AES_CTRL_SAVE_CONTEXT | /* Save context */ + AES_AES_CTRL_GCM | /* GCM */ + AES_AES_CTRL_CTR_WIDTH_32 | /* CTR width 32 */ + AES_AES_CTRL_CTR | /* CTR */ + (encrypt ? AES_AES_CTRL_DIRECTION_ENCRYPT : 0); /* En/decryption */ + + /* Prepare the crypto initialization vector + * Initialization vector */ + rom_util_memcpy(aes_iv, iv, GCM_IV_LEN); + /* Initialize counter to 1 */ + aes_iv[GCM_IV_LEN / sizeof(aes_iv[0])] = 0x01000000; + + return aes_auth_crypt_start(ctrl, key_area, aes_iv, adata, adata_len, + data_in, data_out, data_len, process); +} +/*---------------------------------------------------------------------------*/ +static uint8_t +gcm_auth_crypt_get_result(const void *tag_in, void *tag_out) +{ + uint32_t tag[AES_TAG_LEN / sizeof(uint32_t)]; + uint8_t ret; + + ret = aes_auth_crypt_get_result(NULL, tag); + if(ret != CRYPTO_SUCCESS) { + return ret; + } + + if(tag_in != NULL) { + /* Check tag */ + if(rom_util_memcmp(tag, tag_in, GCM_TAG_LEN)) { + ret = AES_AUTHENTICATION_FAILED; + } + } + + if(tag_out != NULL) { + /* Copy tag */ + rom_util_memcpy(tag_out, tag, GCM_TAG_LEN); + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +uint8_t +gcm_auth_encrypt_start(uint8_t key_area, const void *iv, const void *adata, + uint16_t adata_len, const void *pdata, + uint16_t pdata_len, void *cdata, struct process *process) +{ + return gcm_auth_crypt_start(true, key_area, iv, adata, adata_len, + pdata, cdata, pdata_len, process); +} +/*---------------------------------------------------------------------------*/ +uint8_t +gcm_auth_encrypt_get_result(void *tag) +{ + return gcm_auth_crypt_get_result(NULL, tag); +} +/*---------------------------------------------------------------------------*/ +uint8_t +gcm_auth_decrypt_start(uint8_t key_area, const void *iv, const void *adata, + uint16_t adata_len, const void *cdata, + uint16_t cdata_len, void *pdata, struct process *process) +{ + return gcm_auth_crypt_start(false, key_area, iv, adata, adata_len, + cdata, pdata, cdata_len, process); +} +/*---------------------------------------------------------------------------*/ +uint8_t +gcm_auth_decrypt_get_result(const void *tag_in, void *tag_out) +__attribute__ ((alias("gcm_auth_crypt_get_result"))); + +/** @} */ diff --git a/cpu/cc2538/dev/gcm.h b/cpu/cc2538/dev/gcm.h new file mode 100644 index 000000000..9633b6ff2 --- /dev/null +++ b/cpu/cc2538/dev/gcm.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-aes + * @{ + * + * \defgroup cc2538-gcm cc2538 AES-GCM + * + * Driver for the cc2538 AES-GCM mode of the security core + * @{ + * + * \file + * Header file for the cc2538 AES-GCM driver + */ +#ifndef GCM_H_ +#define GCM_H_ + +#include "contiki.h" +#include "dev/aes.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/** \name AES-GCM constants + * @{ + */ +#define GCM_IV_LEN (96 / 8) +#define GCM_TAG_LEN AES_TAG_LEN +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES-GCM functions + * @{ + */ + +/** \brief Starts a GCM authentication and encryption operation + * \param key_area Area in Key RAM where the key is stored (0 to + * \c AES_KEY_AREAS - 1) + * \param iv Pointer to 96-bit initialization vector + * \param adata Pointer to additional authenticated data in SRAM, or \c NULL + * \param adata_len Length of additional authenticated data in octets, or \c 0 + * \param pdata Pointer to message to authenticate and encrypt in SRAM, or + * \c NULL + * \param pdata_len Length of message to authenticate and encrypt in octets, or + * \c 0 + * \param cdata Pointer to encrypted message in SRAM (may be \p pdata), or + * \c NULL + * \param process Process to be polled upon completion of the operation, or + * \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/GCM error code + */ +uint8_t gcm_auth_encrypt_start(uint8_t key_area, const void *iv, + const void *adata, uint16_t adata_len, + const void *pdata, uint16_t pdata_len, + void *cdata, struct process *process); + +/** \brief Checks the status of the GCM authentication and encryption operation + * \retval false Result not yet available, and no error occurred + * \retval true Result available, or error occurred + */ +#define gcm_auth_encrypt_check_status aes_auth_crypt_check_status + +/** \brief Gets the result of the GCM authentication and encryption operation + * \param tag Pointer to 128-bit authentication tag, or \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/GCM error code + * \note This function must be called only after \c gcm_auth_encrypt_start(). + */ +uint8_t gcm_auth_encrypt_get_result(void *tag); + +/** \brief Starts a GCM authentication checking and decryption operation + * \param key_area Area in Key RAM where the key is stored (0 to + * \c AES_KEY_AREAS - 1) + * \param iv Pointer to 96-bit initialization vector + * \param adata Pointer to additional authenticated data in SRAM, or \c NULL + * \param adata_len Length of additional authenticated data in octets, or \c 0 + * \param cdata Pointer to encrypted message in SRAM, or \c NULL + * \param cdata_len Length of encrypted message in octets, or \c 0 + * \param pdata Pointer to decrypted message in SRAM (may be \p cdata), or + * \c NULL + * \param process Process to be polled upon completion of the operation, or + * \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/GCM error code + */ +uint8_t gcm_auth_decrypt_start(uint8_t key_area, const void *iv, + const void *adata, uint16_t adata_len, + const void *cdata, uint16_t cdata_len, + void *pdata, struct process *process); + +/** \brief Checks the status of the GCM authentication checking and decryption + * operation + * \retval false Result not yet available, and no error occurred + * \retval true Result available, or error occurred + */ +#define gcm_auth_decrypt_check_status aes_auth_crypt_check_status + +/** \brief Gets the result of the GCM authentication checking and decryption + * operation + * \param tag_in Pointer to 128-bit input authentication tag, or \c NULL + * \param tag_out Pointer to 128-bit output authentication tag, or \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/GCM error code + * \note This function must be called only after \c gcm_auth_decrypt_start(). + */ +uint8_t gcm_auth_decrypt_get_result(const void *tag_in, void *tag_out); + +/** @} */ + +#endif /* GCM_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/gpio.c b/cpu/cc2538/dev/gpio.c index 2961a2eb0..eb561c757 100644 --- a/cpu/cc2538/dev/gpio.c +++ b/cpu/cc2538/dev/gpio.c @@ -79,69 +79,41 @@ notify(uint8_t mask, uint8_t port) } } /*---------------------------------------------------------------------------*/ -/** \brief Interrupt service routine for Port A */ -void -gpio_port_a_isr() +/** \brief Interrupt service routine for Port \a port + * \param port Number between 0 and 3. Port A: 0, Port B: 1, etc. + */ +static void +gpio_port_isr(uint8_t port) { + uint32_t base; + uint8_t int_status, power_up_int_status; + lpm_exit(); ENERGEST_ON(ENERGEST_TYPE_IRQ); - notify(REG(GPIO_A_BASE | GPIO_MIS), GPIO_A_NUM); + base = GPIO_PORT_TO_BASE(port); + int_status = GPIO_GET_MASKED_INT_STATUS(base); + power_up_int_status = GPIO_GET_POWER_UP_INT_STATUS(port); - GPIO_CLEAR_INTERRUPT(GPIO_A_BASE, 0xFF); - GPIO_CLEAR_POWER_UP_INTERRUPT(GPIO_A_NUM, 0xFF); + notify(int_status | power_up_int_status, port); + + GPIO_CLEAR_INTERRUPT(base, int_status); + GPIO_CLEAR_POWER_UP_INTERRUPT(port, power_up_int_status); ENERGEST_OFF(ENERGEST_TYPE_IRQ); } /*---------------------------------------------------------------------------*/ -/** \brief Interrupt service routine for Port B */ -void -gpio_port_b_isr() -{ - lpm_exit(); - - ENERGEST_ON(ENERGEST_TYPE_IRQ); - - notify(REG(GPIO_B_BASE | GPIO_MIS), GPIO_B_NUM); - - GPIO_CLEAR_INTERRUPT(GPIO_B_BASE, 0xFF); - GPIO_CLEAR_POWER_UP_INTERRUPT(GPIO_B_NUM, 0xFF); - - ENERGEST_OFF(ENERGEST_TYPE_IRQ); -} -/*---------------------------------------------------------------------------*/ -/** \brief Interrupt service routine for Port C */ -void -gpio_port_c_isr() -{ - lpm_exit(); - - ENERGEST_ON(ENERGEST_TYPE_IRQ); - - notify(REG(GPIO_C_BASE | GPIO_MIS), GPIO_C_NUM); - - GPIO_CLEAR_INTERRUPT(GPIO_C_BASE, 0xFF); - GPIO_CLEAR_POWER_UP_INTERRUPT(GPIO_C_NUM, 0xFF); - - ENERGEST_OFF(ENERGEST_TYPE_IRQ); -} -/*---------------------------------------------------------------------------*/ -/** \brief Interrupt service routine for Port D */ -void -gpio_port_d_isr() -{ - lpm_exit(); - - ENERGEST_ON(ENERGEST_TYPE_IRQ); - - notify(REG(GPIO_D_BASE | GPIO_MIS), GPIO_D_NUM); - - GPIO_CLEAR_INTERRUPT(GPIO_D_BASE, 0xFF); - GPIO_CLEAR_POWER_UP_INTERRUPT(GPIO_D_NUM, 0xFF); - - ENERGEST_OFF(ENERGEST_TYPE_IRQ); +#define GPIO_PORT_ISR(lowercase_port, uppercase_port) \ +void \ +gpio_port_##lowercase_port##_isr(void) \ +{ \ + gpio_port_isr(GPIO_##uppercase_port##_NUM); \ } +GPIO_PORT_ISR(a, A) +GPIO_PORT_ISR(b, B) +GPIO_PORT_ISR(c, C) +GPIO_PORT_ISR(d, D) /*---------------------------------------------------------------------------*/ void gpio_init() diff --git a/cpu/cc2538/dev/gpio.h b/cpu/cc2538/dev/gpio.h index 8a61f668b..e97ba2825 100644 --- a/cpu/cc2538/dev/gpio.h +++ b/cpu/cc2538/dev/gpio.h @@ -91,56 +91,76 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin); * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_SET_INPUT(PORT_BASE, PIN_MASK) \ - do { REG((PORT_BASE) | GPIO_DIR) &= ~(PIN_MASK); } while(0) + do { REG((PORT_BASE) + GPIO_DIR) &= ~(PIN_MASK); } while(0) /** \brief Set pins with PIN_MASK of port with PORT_BASE to output. * \param PORT_BASE GPIO Port register offset * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_SET_OUTPUT(PORT_BASE, PIN_MASK) \ - do { REG((PORT_BASE) | GPIO_DIR) |= (PIN_MASK); } while(0) + do { REG((PORT_BASE) + GPIO_DIR) |= (PIN_MASK); } while(0) /** \brief Set pins with PIN_MASK of port with PORT_BASE high. * \param PORT_BASE GPIO Port register offset * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_SET_PIN(PORT_BASE, PIN_MASK) \ - do { REG(((PORT_BASE) | GPIO_DATA) + ((PIN_MASK) << 2)) = 0xFF; } while(0) + do { REG((PORT_BASE) + GPIO_DATA + ((PIN_MASK) << 2)) = 0xFF; } while(0) /** \brief Set pins with PIN_MASK of port with PORT_BASE low. * \param PORT_BASE GPIO Port register offset * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_CLR_PIN(PORT_BASE, PIN_MASK) \ - do { REG(((PORT_BASE) | GPIO_DATA) + ((PIN_MASK) << 2)) = 0x00; } while(0) + do { REG((PORT_BASE) + GPIO_DATA + ((PIN_MASK) << 2)) = 0x00; } while(0) /** \brief Set pins with PIN_MASK of port with PORT_BASE to value. * \param PORT_BASE GPIO Port register offset * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 + * \param value The new value to write to the register. Only pins specified + * by PIN_MASK will be set. + * + * \note The outcome of this macro invocation will be to write to the register + * a new value for multiple pins. For that reason, the value argument cannot be + * a simple 0 or 1. Instead, it must be the value corresponding to the pins that + * you wish to set. + * + * Thus, if you only want to set a single pin (e.g. pin 2), do \e not pass 1, + * but you must pass 0x04 instead (1 << 2). This may seem counter-intuitive at + * first glance, but it allows a single invocation of this macro to set + * multiple pins in one go if so desired. For example, you can set pins 3 and 1 + * and the same time clear pins 2 and 0. To do so, pass 0x0F as the PIN_MASK + * and then use 0x0A as the value ((1 << 3) | (1 << 1) for pins 3 and 1) */ #define GPIO_WRITE_PIN(PORT_BASE, PIN_MASK, value) \ - do { REG(((PORT_BASE) | GPIO_DATA) + ((PIN_MASK) << 2)) = (value); } while(0) + do { REG((PORT_BASE) + GPIO_DATA + ((PIN_MASK) << 2)) = (value); } while(0) /** \brief Read pins with PIN_MASK of port with PORT_BASE. * \param PORT_BASE GPIO Port register offset * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 + * \return The value of the pins specified by PIN_MASK + * + * This macro will \e not return 0 or 1. Instead, it will return the values of + * the pins specified by PIN_MASK ORd together. Thus, if you pass 0xC3 + * (0x80 | 0x40 | 0x02 | 0x01) as the PIN_MASK and pins 7 and 0 are high, + * the macro will return 0x81. */ #define GPIO_READ_PIN(PORT_BASE, PIN_MASK) \ - REG(((PORT_BASE) | GPIO_DATA) + ((PIN_MASK) << 2)) + REG((PORT_BASE) + GPIO_DATA + ((PIN_MASK) << 2)) /** \brief Set pins with PIN_MASK of port with PORT_BASE to detect edge. * \param PORT_BASE GPIO Port register offset * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_DETECT_EDGE(PORT_BASE, PIN_MASK) \ - do { REG((PORT_BASE) | GPIO_IS) &= ~(PIN_MASK); } while(0) + do { REG((PORT_BASE) + GPIO_IS) &= ~(PIN_MASK); } while(0) /** \brief Set pins with PIN_MASK of port with PORT_BASE to detect level. * \param PORT_BASE GPIO Port register offset * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_DETECT_LEVEL(PORT_BASE, PIN_MASK) \ - do { REG((PORT_BASE) | GPIO_IS) |= (PIN_MASK); } while(0) + do { REG((PORT_BASE) + GPIO_IS) |= (PIN_MASK); } while(0) /** \brief Set pins with PIN_MASK of port with PORT_BASE to trigger an * interrupt on both edges. @@ -148,7 +168,7 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin); * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_TRIGGER_BOTH_EDGES(PORT_BASE, PIN_MASK) \ - do { REG((PORT_BASE) | GPIO_IBE) |= (PIN_MASK); } while(0) + do { REG((PORT_BASE) + GPIO_IBE) |= (PIN_MASK); } while(0) /** \brief Set pins with PIN_MASK of port with PORT_BASE to trigger an * interrupt on single edge (controlled by GPIO_IEV). @@ -156,7 +176,7 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin); * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_TRIGGER_SINGLE_EDGE(PORT_BASE, PIN_MASK) \ - do { REG((PORT_BASE) | GPIO_IBE) &= ~(PIN_MASK); } while(0) + do { REG((PORT_BASE) + GPIO_IBE) &= ~(PIN_MASK); } while(0) /** \brief Set pins with PIN_MASK of port with PORT_BASE to trigger an * interrupt on rising edge. @@ -164,7 +184,7 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin); * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_DETECT_RISING(PORT_BASE, PIN_MASK) \ - do { REG((PORT_BASE) | GPIO_IEV) |= (PIN_MASK); } while(0) + do { REG((PORT_BASE) + GPIO_IEV) |= (PIN_MASK); } while(0) /** \brief Set pins with PIN_MASK of port with PORT_BASE to trigger an * interrupt on falling edge. @@ -172,7 +192,7 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin); * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_DETECT_FALLING(PORT_BASE, PIN_MASK) \ - do { REG((PORT_BASE) | GPIO_IEV) &= ~(PIN_MASK); } while(0) + do { REG((PORT_BASE) + GPIO_IEV) &= ~(PIN_MASK); } while(0) /** \brief Enable interrupt triggering for pins with PIN_MASK of port with * PORT_BASE. @@ -180,7 +200,7 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin); * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_ENABLE_INTERRUPT(PORT_BASE, PIN_MASK) \ - do { REG((PORT_BASE) | GPIO_IE) |= (PIN_MASK); } while(0) + do { REG((PORT_BASE) + GPIO_IE) |= (PIN_MASK); } while(0) /** \brief Disable interrupt triggering for pins with PIN_MASK of port with * PORT_BASE. @@ -188,7 +208,32 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin); * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_DISABLE_INTERRUPT(PORT_BASE, PIN_MASK) \ - do { REG((PORT_BASE) | GPIO_IE) &= ~(PIN_MASK); } while(0) + do { REG((PORT_BASE) + GPIO_IE) &= ~(PIN_MASK); } while(0) + +/** \brief Get raw interrupt status of port with PORT_BASE. + * \param PORT_BASE GPIO Port register offset + * \return Bit-mask reflecting the raw interrupt status of all the port pins + * + * The bits set in the returned bit-mask reflect the status of the interrupts + * trigger conditions detected (raw, before interrupt masking), indicating that + * all the requirements are met, before they are finally allowed to trigger by + * the interrupt mask. The bits cleared indicate that corresponding input pins + * have not initiated an interrupt. + */ +#define GPIO_GET_RAW_INT_STATUS(PORT_BASE) \ + REG((PORT_BASE) + GPIO_RIS) + +/** \brief Get masked interrupt status of port with PORT_BASE. + * \param PORT_BASE GPIO Port register offset + * \return Bit-mask reflecting the masked interrupt status of all the port pins + * + * The bits set in the returned bit-mask reflect the status of input lines + * triggering an interrupt. The bits cleared indicate that either no interrupt + * has been generated, or the interrupt is masked. This is the state of the + * interrupt after interrupt masking. + */ +#define GPIO_GET_MASKED_INT_STATUS(PORT_BASE) \ + REG((PORT_BASE) + GPIO_MIS) /** \brief Clear interrupt triggering for pins with PIN_MASK of port with * PORT_BASE. @@ -196,7 +241,7 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin); * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_CLEAR_INTERRUPT(PORT_BASE, PIN_MASK) \ - do { REG((PORT_BASE) | GPIO_IC) = (PIN_MASK); } while(0) + do { REG((PORT_BASE) + GPIO_IC) = (PIN_MASK); } while(0) /** \brief Configure the pin to be under peripheral control with PIN_MASK of * port with PORT_BASE. @@ -204,7 +249,7 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin); * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_PERIPHERAL_CONTROL(PORT_BASE, PIN_MASK) \ - do { REG((PORT_BASE) | GPIO_AFSEL) |= (PIN_MASK); } while(0) + do { REG((PORT_BASE) + GPIO_AFSEL) |= (PIN_MASK); } while(0) /** \brief Configure the pin to be software controlled with PIN_MASK of port * with PORT_BASE. @@ -212,7 +257,7 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin); * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_SOFTWARE_CONTROL(PORT_BASE, PIN_MASK) \ - do { REG((PORT_BASE) | GPIO_AFSEL) &= ~(PIN_MASK); } while(0) + do { REG((PORT_BASE) + GPIO_AFSEL) &= ~(PIN_MASK); } while(0) /** \brief Set pins with PIN_MASK of port PORT to trigger a power-up interrupt * on rising edge. @@ -220,7 +265,7 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin); * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_POWER_UP_ON_RISING(PORT, PIN_MASK) \ - do { REG(GPIO_PORT_TO_BASE(PORT) | GPIO_P_EDGE_CTRL) &= \ + do { REG(GPIO_PORT_TO_BASE(PORT) + GPIO_P_EDGE_CTRL) &= \ ~((PIN_MASK) << ((PORT) << 3)); } while(0) /** \brief Set pins with PIN_MASK of port PORT to trigger a power-up interrupt @@ -229,7 +274,7 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin); * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_POWER_UP_ON_FALLING(PORT, PIN_MASK) \ - do { REG(GPIO_PORT_TO_BASE(PORT) | GPIO_P_EDGE_CTRL) |= \ + do { REG(GPIO_PORT_TO_BASE(PORT) + GPIO_P_EDGE_CTRL) |= \ (PIN_MASK) << ((PORT) << 3); } while(0) /** \brief Enable power-up interrupt triggering for pins with PIN_MASK of port @@ -238,7 +283,7 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin); * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_ENABLE_POWER_UP_INTERRUPT(PORT, PIN_MASK) \ - do { REG(GPIO_PORT_TO_BASE(PORT) | GPIO_PI_IEN) |= \ + do { REG(GPIO_PORT_TO_BASE(PORT) + GPIO_PI_IEN) |= \ (PIN_MASK) << ((PORT) << 3); } while(0) /** \brief Disable power-up interrupt triggering for pins with PIN_MASK of port @@ -247,21 +292,29 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin); * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_DISABLE_POWER_UP_INTERRUPT(PORT, PIN_MASK) \ - do { REG(GPIO_PORT_TO_BASE(PORT) | GPIO_PI_IEN) &= \ + do { REG(GPIO_PORT_TO_BASE(PORT) + GPIO_PI_IEN) &= \ ~((PIN_MASK) << ((PORT) << 3)); } while(0) +/** \brief Get power-up interrupt status of port PORT. + * \param PORT GPIO Port (not port base address) + * \return Bit-mask reflecting the power-up interrupt status of all the port + * pins + */ +#define GPIO_GET_POWER_UP_INT_STATUS(PORT) \ + ((REG(GPIO_PORT_TO_BASE(PORT) + GPIO_IRQ_DETECT_ACK) >> ((PORT) << 3)) & 0xFF) + /** \brief Clear power-up interrupt triggering for pins with PIN_MASK of port * PORT. * \param PORT GPIO Port (not port base address) * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 */ #define GPIO_CLEAR_POWER_UP_INTERRUPT(PORT, PIN_MASK) \ - do { REG(GPIO_PORT_TO_BASE(PORT) | GPIO_IRQ_DETECT_ACK) = \ + do { REG(GPIO_PORT_TO_BASE(PORT) + GPIO_IRQ_DETECT_ACK) = \ (PIN_MASK) << ((PORT) << 3); } while(0) /** * \brief Converts a pin number to a pin mask - * \param The pin number in the range [0..7] + * \param PIN The pin number in the range [0..7] * \return A pin mask which can be used as the PIN_MASK argument of the macros * in this category */ @@ -269,7 +322,7 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin); /** * \brief Converts a port number to the port base address - * \param The port number in the range 0 - 3. Likely GPIO_X_NUM. + * \param PORT The port number in the range 0 - 3. Likely GPIO_X_NUM. * \return The base address for the registers corresponding to that port * number. */ diff --git a/cpu/cc2538/dev/i2c.c b/cpu/cc2538/dev/i2c.c new file mode 100644 index 000000000..76cac20f8 --- /dev/null +++ b/cpu/cc2538/dev/i2c.c @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2015, Mehdi Migault + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-i2c cc2538 I2C Control + * @{ + * + * \file + * Implementation file of the I2C Control module + * + * \author + * Mehdi Migault + */ + +#include "i2c.h" + +#include +#include "clock.h" +#include "sys-ctrl.h" +/*---------------------------------------------------------------------------*/ +void +i2c_init(uint8_t port_sda, uint8_t pin_sda, uint8_t port_scl, uint8_t pin_scl, + uint32_t bus_speed) +{ + /* Enable I2C clock in different modes */ + REG(SYS_CTRL_RCGCI2C) |= 1; /* Run mode */ + + /* Reset I2C peripheral */ + REG(SYS_CTRL_SRI2C) |= 1; /* Reset position */ + + /* Delay for a little bit */ + clock_delay_usec(50); + + REG(SYS_CTRL_SRI2C) &= ~1; /* Normal position */ + + /* Set pins in input */ + GPIO_SET_INPUT(GPIO_PORT_TO_BASE(port_sda), GPIO_PIN_MASK(pin_sda)); + GPIO_SET_INPUT(GPIO_PORT_TO_BASE(port_scl), GPIO_PIN_MASK(pin_scl)); + + /* Set peripheral control for the pins */ + GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(port_sda), GPIO_PIN_MASK(pin_sda)); + GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(port_scl), GPIO_PIN_MASK(pin_scl)); + + /* Set the pad to no drive type */ + ioc_set_over(port_sda, pin_sda, IOC_OVERRIDE_DIS); + ioc_set_over(port_scl, pin_scl, IOC_OVERRIDE_DIS); + + /* Set pins as peripheral inputs */ + REG(IOC_I2CMSSDA) = ioc_input_sel(port_sda, pin_sda); + REG(IOC_I2CMSSCL) = ioc_input_sel(port_scl, pin_scl); + + /* Set pins as peripheral outputs */ + ioc_set_sel(port_sda, pin_sda, IOC_PXX_SEL_I2C_CMSSDA); + ioc_set_sel(port_scl, pin_scl, IOC_PXX_SEL_I2C_CMSSCL); + + /* Enable the I2C master module */ + i2c_master_enable(); + + /* t the master clock frequency */ + i2c_set_frequency(bus_speed); +} +/*---------------------------------------------------------------------------*/ +void +i2c_master_enable(void) +{ + REG(I2CM_CR) |= 0x10; /* Set MFE bit */ +} +/*---------------------------------------------------------------------------*/ +void +i2c_master_disable(void) +{ + REG(I2CM_CR) &= ~0x10; /* Reset MFE bit */ +} +/*---------------------------------------------------------------------------*/ +void +i2c_set_frequency(uint32_t freq) +{ + /* Peripheral clock setting, using the system clock */ + REG(I2CM_TPR) = ((SYS_CTRL_SYS_CLOCK + (2 * 10 * freq) - 1) / + (2 * 10 * freq)) - 1; +} +/*---------------------------------------------------------------------------*/ +void +i2c_master_set_slave_address(uint8_t slave_addr, uint8_t access_mode) +{ + if(access_mode) { + REG(I2CM_SA) = ((slave_addr << 1) | 1); + } else { + REG(I2CM_SA) = (slave_addr << 1); + } +} +/*---------------------------------------------------------------------------*/ +void +i2c_master_data_put(uint8_t data) +{ + REG(I2CM_DR) = data; +} +/*---------------------------------------------------------------------------*/ +uint8_t +i2c_master_data_get(void) +{ + return REG(I2CM_DR); +} +/*---------------------------------------------------------------------------*/ +void +i2c_master_command(uint8_t cmd) +{ + REG(I2CM_CTRL) = cmd; + /* Here we need a delay, otherwise the I2C module keep the receiver mode */ + clock_delay_usec(1); +} +/*---------------------------------------------------------------------------*/ +uint8_t +i2c_master_busy(void) +{ + return REG(I2CM_STAT) & I2CM_STAT_BUSY; +} +/*---------------------------------------------------------------------------*/ +uint8_t +i2c_master_error(void) +{ + uint8_t temp = REG(I2CM_STAT); /* Get all status */ + if(temp & I2CM_STAT_BUSY) { /* No valid if BUSY bit is set */ + return I2C_MASTER_ERR_NONE; + } else if(temp & (I2CM_STAT_ERROR | I2CM_STAT_ARBLST)) { + return temp; /* Compare later */ + } + return I2C_MASTER_ERR_NONE; +} +/*---------------------------------------------------------------------------*/ +uint8_t +i2c_single_send(uint8_t slave_addr, uint8_t data) +{ + i2c_master_set_slave_address(slave_addr, I2C_SEND); + i2c_master_data_put(data); + i2c_master_command(I2C_MASTER_CMD_SINGLE_SEND); + + while(i2c_master_busy()); + + /* Return the STAT register of I2C module if error occured, I2C_MASTER_ERR_NONE otherwise */ + return i2c_master_error(); +} +/*---------------------------------------------------------------------------*/ +uint8_t +i2c_single_receive(uint8_t slave_addr, uint8_t *data) +{ + uint32_t temp; + + i2c_master_set_slave_address(slave_addr, I2C_RECEIVE); + i2c_master_command(I2C_MASTER_CMD_SINGLE_RECEIVE); + + while(i2c_master_busy()); + temp = i2c_master_error(); + if(temp == I2C_MASTER_ERR_NONE) { + *data = i2c_master_data_get(); + } + return temp; +} +/*---------------------------------------------------------------------------*/ +uint8_t +i2c_burst_send(uint8_t slave_addr, uint8_t *data, uint8_t len) +{ + uint8_t sent; + if((len == 0) || (data == NULL)) { + return I2CM_STAT_INVALID; + } + if(len == 1) { + return i2c_single_send(slave_addr, data[0]); + } + i2c_master_set_slave_address(slave_addr, I2C_SEND); + i2c_master_data_put(data[0]); + i2c_master_command(I2C_MASTER_CMD_BURST_SEND_START); + while(i2c_master_busy()); + if(i2c_master_error() == I2C_MASTER_ERR_NONE) { + for(sent = 1; sent <= (len - 2); sent++) { + i2c_master_data_put(data[sent]); + i2c_master_command(I2C_MASTER_CMD_BURST_SEND_CONT); + while(i2c_master_busy()); + } + /* This should be the last byte, stop sending */ + i2c_master_data_put(data[len - 1]); + i2c_master_command(I2C_MASTER_CMD_BURST_SEND_FINISH); + while(i2c_master_busy()); + } + + /* Return the STAT register of I2C module if error occurred, I2C_MASTER_ERR_NONE otherwise */ + return i2c_master_error(); +} +/*---------------------------------------------------------------------------*/ +uint8_t +i2c_burst_receive(uint8_t slave_addr, uint8_t *data, uint8_t len) +{ + uint8_t recv = 0; + if((len == 0) || data == NULL) { + return I2CM_STAT_INVALID; + } + if(len == 1) { + return i2c_single_receive(slave_addr, &data[0]); + } + i2c_master_set_slave_address(slave_addr, I2C_RECEIVE); + i2c_master_command(I2C_MASTER_CMD_BURST_RECEIVE_START); + while(i2c_master_busy()); + if(i2c_master_error() == I2C_MASTER_ERR_NONE) { + data[0] = i2c_master_data_get(); + /* If we got 2 or more bytes pending to be received, keep going*/ + for(recv = 1; recv <= (len - 2); recv++) { + i2c_master_command(I2C_MASTER_CMD_BURST_RECEIVE_CONT); + while(i2c_master_busy()); + data[recv] = i2c_master_data_get(); + } + /* This should be the last byte, stop receiving */ + i2c_master_command(I2C_MASTER_CMD_BURST_RECEIVE_FINISH); + while(i2c_master_busy()); + data[len - 1] = i2c_master_data_get(); + } + return i2c_master_error(); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/cpu/cc2538/dev/i2c.h b/cpu/cc2538/dev/i2c.h new file mode 100644 index 000000000..6ec606167 --- /dev/null +++ b/cpu/cc2538/dev/i2c.h @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2015, Mehdi Migault + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538 + * @{ + * + * \defgroup cc2538-i2c cc2538 I2C Control + * + * cc2538 I2C Control Module + * @{ + * + * \file + * Header file with declarations for the I2C Control module + * + * \author + * Mehdi Migault + */ +#ifndef I2C_H_ +#define I2C_H_ + +#include "reg.h" +#include "sys-ctrl.h" +#include "gpio.h" +#include "ioc.h" +#include /* For debug */ +#include "clock.h" /* For temporisation */ +/*---------------------------------------------------------------------------*/ +/** \name I2C Master commands + * @{ + */ +#define I2C_MASTER_CMD_SINGLE_SEND 0x00000007 +#define I2C_MASTER_CMD_SINGLE_RECEIVE 0x00000007 +#define I2C_MASTER_CMD_BURST_SEND_START 0x00000003 +#define I2C_MASTER_CMD_BURST_SEND_CONT 0x00000001 +#define I2C_MASTER_CMD_BURST_SEND_FINISH 0x00000005 +#define I2C_MASTER_CMD_BURST_SEND_ERROR_STOP 0x00000004 +#define I2C_MASTER_CMD_BURST_RECEIVE_START 0x0000000b +#define I2C_MASTER_CMD_BURST_RECEIVE_CONT 0x00000009 +#define I2C_MASTER_CMD_BURST_RECEIVE_FINISH 0x00000005 +#define I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP 0x00000004 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name I2C Master status flags + * @{ + */ +#define I2C_MASTER_ERR_NONE 0 +#define I2CM_STAT_BUSY 0x00000001 +#define I2CM_STAT_ERROR 0x00000002 +#define I2CM_STAT_ADRACK 0x00000004 +#define I2CM_STAT_DATACK 0x00000008 +#define I2CM_STAT_ARBLST 0x00000010 +#define I2CM_STAT_IDLE 0x00000020 +#define I2CM_STAT_BUSBSY 0x00000040 +#define I2CM_STAT_INVALID 0x00000080 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name I2C registers + * @{ + */ +#define I2CM_CR 0x40020020 /* I2C master config */ +#define I2CM_TPR 0x4002000C /* I2C master timer period */ +#define I2CM_SA 0x40020000 /* I2C master slave address */ +#define I2CM_DR 0x40020008 /* I2C master data */ +#define I2CM_CTRL 0x40020004 /* Master control in write */ +#define I2CM_STAT I2CM_CTRL /* Master status in read */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name I2C Miscellaneous + * @{ + */ +#define I2C_SCL_NORMAL_BUS_SPEED 100000 /* 100KHz I2C */ +#define I2C_SCL_FAST_BUS_SPEED 400000 /* 400KHz I2C */ +#define I2C_RECEIVE 0x01 /* Master receive */ +#define I2C_SEND 0x00 /* Master send */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name I2C Functions + * @{ + */ + +/** + * \brief Initialize the I2C peripheral and pins + * \param port_sda The GPIO number of the pin used fort SDA + * \param pin_sda The pin number used for SDA + * \param port_scl The GPIO number of the pin used fort SCL + * \param pin_scl The pin number used for SCL + * \param bus_speed The clock frequency used by I2C module + * + * \e bus_speed can take the following values: + * + * - I2C_SCL_NORMAL_BUS_SPEED : 100KHz + * - I2C_SCL_FAST_BUS_SPEED : 400KHz + */ +void i2c_init(uint8_t port_sda, uint8_t pin_sda, uint8_t port_scl, + uint8_t pin_scl, uint32_t bus_speed); + +/** \brief Enable master I2C module */ +void i2c_master_enable(void); + +/** \brief Disable master I2C module */ +void i2c_master_disable(void); + +/** + * \brief Initialize I2C peripheral clock with given frequency + * \param freq The desired frequency + * + * \e freq can take the following values: + * + * - I2C_SCL_NORMAL_BUS_SPEED : 100KHz + * - I2C_SCL_FAST_BUS_SPEED : 400KHz + */ +void i2c_set_frequency(uint32_t freq); + +/** + * \brief Set the address of slave and access mode for the next I2C communication + * \param slave_addr The receiver slave address on 7 bits + * \param access_mode The I2C access mode (send/receive) + * + * \e access_mode can take the following values: + * + * - I2C_RECEIVE : 1 + * - I2C_SEND : 0 + */ +void i2c_master_set_slave_address(uint8_t slave_addr, uint8_t access_mode); + +/** + * \brief Prepare data to be transmitted + * \param data The byte of data to be transmitted from the I2C master + */ +void i2c_master_data_put(uint8_t data); + +/** + * \brief Return received data from I2C + * \return The byte received by I2C after à receive command + */ +uint8_t i2c_master_data_get(void); + +/** + * \brief Control the state of the master module for send and receive operations + * \param cmd The operation to perform + * + * \e cmd can take the following values: + * + * - I2C_MASTER_CMD_SINGLE_SEND + * - I2C_MASTER_CMD_SINGLE_RECEIVE + * - I2C_MASTER_CMD_BURST_SEND_START + * - I2C_MASTER_CMD_BURST_SEND_CONT + * - I2C_MASTER_CMD_BURST_SEND_FINISH + * - I2C_MASTER_CMD_BURST_SEND_ERROR_STOP + * - I2C_MASTER_CMD_BURST_RECEIVE_START + * - I2C_MASTER_CMD_BURST_RECEIVE_CONT + * - I2C_MASTER_CMD_BURST_RECEIVE_FINISH + * - I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP + */ +void i2c_master_command(uint8_t cmd); + +/** + * \brief Return the busy state of I2C module + * \retval 0 The I2C module is not busy + * \retval 1 The I2C module is busy + */ +uint8_t i2c_master_busy(void); + +/** + * \brief Return the status register if error occurred during last communication + * \retval I2C_MASTER_ERR_NONE Return 0 if no error occurred + * + * If an error occurred, return the status register of the I2C module. + * Use the result with the I2CM_STAT_* flags to custom your processing + */ +uint8_t i2c_master_error(void); +/** + * \brief Perform all operations to send a byte to a slave + * \param slave_addr The adress of the slave to which data are sent + * \param data The data to send to the slave + * \return Return the value of i2c_master_error() after the I2C operation + */ +uint8_t i2c_single_send(uint8_t slave_addr, uint8_t data); + +/** + * \brief Perform all operations to receive a byte from a slave + * \param slave_addr The address of the slave from which data are received + * \param data A pointer to store the received data + * \return Return the value of i2c_master_error() after the I2C operation + */ +uint8_t i2c_single_receive(uint8_t slave_addr, uint8_t *data); +/** + * \brief Perform all operations to send multiple bytes to a slave + * \param slave_addr The address of the slave to which data are sent + * \param data A pointer to the data to send to the slave + * \param len Number of bytes to send + * \return Return the value of i2c_master_error() after the I2C operation + */ +uint8_t i2c_burst_send(uint8_t slave_addr, uint8_t *data, uint8_t len); + +/** + * \brief Perform all operations to receive multiple bytes from a slave + * \param slave_addr The address of the slave from which data are received + * \param data A pointer to store the received data + * \param len Number of bytes to receive + * \return Return the value of i2c_master_error() after the I2C operation + */ +uint8_t i2c_burst_receive(uint8_t slave_addr, uint8_t *data, uint8_t len); +/** @} */ + +#endif /* I2C_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/ioc.h b/cpu/cc2538/dev/ioc.h index 34fcce809..7fad9d275 100644 --- a/cpu/cc2538/dev/ioc.h +++ b/cpu/cc2538/dev/ioc.h @@ -34,7 +34,7 @@ * * \defgroup cc2538-ioc cc2538 I/O Control * - * cc2538 I/O Control Module + * Driver for the cc2538 I/O Control Module * @{ * * \file diff --git a/cpu/cc2538/dev/nvic.c b/cpu/cc2538/dev/nvic.c index 8e2e991ab..71e2414f8 100644 --- a/cpu/cc2538/dev/nvic.c +++ b/cpu/cc2538/dev/nvic.c @@ -57,7 +57,7 @@ nvic_init() interrupt_unpend = (uint32_t *)NVIC_UNPEND0; /* Provide our interrupt table to the NVIC */ - REG(SCB_VTABLE) = (NVIC_CONF_VTABLE_BASE | NVIC_CONF_VTABLE_OFFSET); + REG(SCB_VTABLE) = NVIC_VTABLE_ADDRESS; } /*---------------------------------------------------------------------------*/ void diff --git a/cpu/cc2538/dev/nvic.h b/cpu/cc2538/dev/nvic.h index b8c70b4a2..8f2f68259 100644 --- a/cpu/cc2538/dev/nvic.h +++ b/cpu/cc2538/dev/nvic.h @@ -48,18 +48,14 @@ /** \name NVIC Constants and Configuration * @{ */ -#define NVIC_VTABLE_IN_SRAM 0x20000000 -#define NVIC_VTABLE_IN_CODE 0x00000000 - #define NVIC_INTERRUPT_ENABLED 0x00000001 #define NVIC_INTERRUPT_DISABLED 0x00000000 -#ifndef NVIC_CONF_VTABLE_BASE -#define NVIC_CONF_VTABLE_BASE NVIC_VTABLE_IN_CODE -#endif - -#ifndef NVIC_CONF_VTABLE_OFFSET -#define NVIC_CONF_VTABLE_OFFSET 0x200000 +#ifdef NVIC_CONF_VTABLE_ADDRESS +#define NVIC_VTABLE_ADDRESS NVIC_CONF_VTABLE_ADDRESS +#else +extern void(*const vectors[])(void); +#define NVIC_VTABLE_ADDRESS ((uint32_t)&vectors) #endif /** @} */ /*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2538/dev/pka.c b/cpu/cc2538/dev/pka.c new file mode 100644 index 000000000..b325a454e --- /dev/null +++ b/cpu/cc2538/dev/pka.c @@ -0,0 +1,128 @@ +/* + * Original file: + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2014 Andreas Dröscher + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-pka + * @{ + * + * \file + * Implementation of the cc2538 PKA engine driver + */ +#include "contiki.h" +#include "sys/energest.h" +#include "dev/pka.h" +#include "dev/sys-ctrl.h" +#include "dev/nvic.h" +#include "lpm.h" +#include "reg.h" + +#include +#include + +static volatile struct process *notification_process = NULL; +/*---------------------------------------------------------------------------*/ +/** \brief The PKA engine ISR + * + * This is the interrupt service routine for the PKA engine. + * + * This ISR is called at worst from PM0, so lpm_exit() does not need + * to be called. + */ +void +pka_isr(void) +{ + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + nvic_interrupt_unpend(NVIC_INT_PKA); + nvic_interrupt_disable(NVIC_INT_PKA); + + if(notification_process != NULL) { + process_poll((struct process *)notification_process); + notification_process = NULL; + } + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +static bool +permit_pm1(void) +{ + return (REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) == 0; +} +/*---------------------------------------------------------------------------*/ +void +pka_init(void) +{ + volatile int i; + + lpm_register_peripheral(permit_pm1); + + pka_enable(); + + /* Reset the PKA engine */ + REG(SYS_CTRL_SRSEC) |= SYS_CTRL_SRSEC_PKA; + for(i = 0; i < 16; i++) { + REG(SYS_CTRL_SRSEC) &= ~SYS_CTRL_SRSEC_PKA; + } +} +/*---------------------------------------------------------------------------*/ +void +pka_enable(void) +{ + /* Enable the clock for the PKA engine */ + REG(SYS_CTRL_RCGCSEC) |= SYS_CTRL_RCGCSEC_PKA; + REG(SYS_CTRL_SCGCSEC) |= SYS_CTRL_SCGCSEC_PKA; + REG(SYS_CTRL_DCGCSEC) |= SYS_CTRL_DCGCSEC_PKA; +} +/*---------------------------------------------------------------------------*/ +void +pka_disable(void) +{ + /* Gate the clock for the PKA engine */ + REG(SYS_CTRL_RCGCSEC) &= ~SYS_CTRL_RCGCSEC_PKA; + REG(SYS_CTRL_SCGCSEC) &= ~SYS_CTRL_SCGCSEC_PKA; + REG(SYS_CTRL_DCGCSEC) &= ~SYS_CTRL_DCGCSEC_PKA; +} +/*---------------------------------------------------------------------------*/ +uint8_t +pka_check_status(void) +{ + return (REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) == 0; +} +void +pka_register_process_notification(struct process *p) +{ + notification_process = p; +} +/** @} */ diff --git a/cpu/cc2538/dev/pka.h b/cpu/cc2538/dev/pka.h new file mode 100644 index 000000000..7a63a3d02 --- /dev/null +++ b/cpu/cc2538/dev/pka.h @@ -0,0 +1,871 @@ +/* + * Original file: + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2014 Andreas Dröscher + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538 + * @{ + * + * \defgroup cc2538-pka cc2538 PKA engine + * + * Driver for the cc2538 PKA engine + * @{ + * + * \file + * Header file for the cc2538 PKA engine driver + */ +#ifndef PKA_H_ +#define PKA_H_ + +#include "contiki.h" +#include + +/*---------------------------------------------------------------------------*/ +/** \name PKA memory + * @{ + */ +#define PKA_RAM_BASE 0x44006000 /**< PKA Memory Address */ +#define PKA_RAM_SIZE 0x800 /**< PKA Memory Size */ +#define PKA_MAX_CURVE_SIZE 12 /**< Define for the maximum curve + size supported by the PKA module + in 32 bit word. */ +#define PKA_MAX_LEN 12 /**< Define for the maximum length of + the big number supported by the + PKA module in 32 bit word. */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA register offsets + * @{ + */ +#define PKA_APTR 0x44004000 /**< PKA vector A address During + execution of basic PKCP + operations, this register is + double buffered and can be + written with a new value for the + next operation; when not + written, the value remains + intact. During the execution of + sequencer-controlled complex + operations, this register may + not be written and its value is + undefined at the conclusion of + the operation. The driver + software cannot rely on the + written value to remain intact. */ +#define PKA_BPTR 0x44004004 /**< PKA vector B address During + execution of basic PKCP + operations, this register is + double buffered and can be + written with a new value for the + next operation; when not + written, the value remains + intact. During the execution of + sequencer-controlled complex + operations, this register may + not be written and its value is + undefined at the conclusion of + the operation. The driver + software cannot rely on the + written value to remain intact. */ +#define PKA_CPTR 0x44004008 /**< PKA vector C address During + execution of basic PKCP + operations, this register is + double buffered and can be + written with a new value for the + next operation; when not + written, the value remains + intact. During the execution of + sequencer-controlled complex + operations, this register may + not be written and its value is + undefined at the conclusion of + the operation. The driver + software cannot rely on the + written value to remain intact. */ +#define PKA_DPTR 0x4400400C /**< PKA vector D address During + execution of basic PKCP + operations, this register is + double buffered and can be + written with a new value for the + next operation; when not + written, the value remains + intact. During the execution of + sequencer-controlled complex + operations, this register may + not be written and its value is + undefined at the conclusion of + the operation. The driver + software cannot rely on the + written value to remain intact. */ +#define PKA_ALENGTH 0x44004010 /**< PKA vector A length During + execution of basic PKCP + operations, this register is + double buffered and can be + written with a new value for the + next operation; when not + written, the value remains + intact. During the execution of + sequencer-controlled complex + operations, this register may + not be written and its value is + undefined at the conclusion of + the operation. The driver + software cannot rely on the + written value to remain intact. */ +#define PKA_BLENGTH 0x44004014 /**< PKA vector B length During + execution of basic PKCP + operations, this register is + double buffered and can be + written with a new value for the + next operation; when not + written, the value remains + intact. During the execution of + sequencer-controlled complex + operations, this register may + not be written and its value is + undefined at the conclusion of + the operation. The driver + software cannot rely on the + written value to remain intact. */ +#define PKA_SHIFT 0x44004018 /**< PKA bit shift value For basic + PKCP operations, modifying the + contents of this register is + made impossible while the + operation is being performed. + For the ExpMod-variable and + ExpMod-CRT operations, this + register is used to indicate the + number of odd powers to use + (directly as a value in the + range 1-16). For the ModInv and + ECC operations, this register is + used to hold a completion code. */ +#define PKA_FUNCTION 0x4400401C /**< PKA function This register + contains the control bits to + start basic PKCP as well as + complex sequencer operations. + The run bit can be used to poll + for the completion of the + operation. Modifying bits [11:0] + is made impossible during the + execution of a basic PKCP + operation. During the execution + of sequencer-controlled complex + operations, this register is + modified; the run and stall + result bits are set to zero at + the conclusion, but other bits + are undefined. Attention: + Continuously reading this + register to poll the run bit is + not allowed when executing + complex sequencer operations + (the sequencer cannot access the + PKCP when this is done). Leave + at least one sysclk cycle + between poll operations. */ +#define PKA_COMPARE 0x44004020 /**< PKA compare result This + register provides the result of + a basic PKCP compare operation. + It is updated when the run bit + in the PKA_FUNCTION register is + reset at the end of that + operation. Status after a + complex sequencer operation is + unknown */ +#define PKA_MSW 0x44004024 /**< PKA most-significant-word of + result vector This register + indicates the (word) address in + the PKA RAM where the most + significant nonzero 32-bit word + of the result is stored. Should + be ignored for modulo + operations. For basic PKCP + operations, this register is + updated when the run bit in the + PKA_FUNCTION register is reset + at the end of the operation. For + the complex-sequencer controlled + operations, updating of the + final value matching the actual + result is done near the end of + the operation; note that the + result is only meaningful if no + errors were detected and that + for ECC operations, the PKA_MSW + register will provide + information for the x-coordinate + of the result point only. */ +#define PKA_DIVMSW 0x44004028 /**< PKA most-significant-word of + divide remainder This register + indicates the (32-bit word) + address in the PKA RAM where the + most significant nonzero 32-bit + word of the remainder result for + the basic divide and modulo + operations is stored. Bits [4:0] + are loaded with the bit number + of the most-significant nonzero + bit in the most-significant + nonzero word when MS one control + bit is set. For divide, modulo, + and MS one reporting, this + register is updated when the RUN + bit in the PKA_FUNCTION register + is reset at the end of the + operation. For the complex + sequencer controlled operations, + updating of bits [4:0] of this + register with the + most-significant bit location of + the actual result is done near + the end of the operation. The + result is meaningful only if no + errors were detected and that + for ECC operations; the + PKA_DIVMSW register provides + information for the x-coordinate + of the result point only. */ +#define PKA_SEQ_CTRL 0x440040C8 /**< PKA sequencer control and + status register The sequencer is + interfaced with the outside + world through a single control + and status register. With the + exception of bit [31], the + actual use of bits in the + separate sub-fields of this + register is determined by the + sequencer firmware. This + register need only be accessed + when the sequencer program is + stored in RAM. The reset value + of the RESTE bit depends upon + the option chosen for sequencer + program storage. */ +#define PKA_OPTIONS 0x440040F4 /**< PKA hardware options register + This register provides the host + with a means to determine the + hardware configuration + implemented in this PKA engine, + focused on options that have an + effect on software interacting + with the module. Note: (32 x + (1st LNME nr. of PEs + 1st LNME + FIFO RAM depth - 10)) equals the + maximum modulus vector length + (in bits) that can be handled by + the modular exponentiation and + ECC operations executed on a PKA + engine that includes an LNME. */ +#define PKA_SW_REV 0x440040F8 /**< PKA firmware revision and + capabilities register This + register allows the host access + to the internal firmware + revision number of the PKA + Engine for software driver + matching and diagnostic + purposes. This register also + contains a field that encodes + the capabilities of the embedded + firmware. The PKA_SW_REV + register is written by the + firmware within a few clock + cycles after starting up that + firmware. The hardware reset + value is zero, indicating that + the information has not been + written yet. */ +#define PKA_REVISION 0x440040FC /**< PKA hardware revision register + This register allows the host + access to the hardware revision + number of the PKA engine for + software driver matching and + diagnostic purposes. It is + always located at the highest + address in the access space of + the module and contains an + encoding of the EIP number (with + its complement as signature) for + recognition of the hardware + module. */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA_APTR register registers bit fields + * @{ + */ +#define PKA_APTR_APTR_M 0x000007FF /**< This register specifies the + location of vector A within the + PKA RAM. Vectors are identified + through the location of their + least-significant 32-bit word. + Note that bit [0] must be zero + to ensure that the vector starts + at an 8-byte boundary. */ +#define PKA_APTR_APTR_S 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA_BPTR register registers bit fields + * @{ + */ +#define PKA_BPTR_BPTR_M 0x000007FF /**< This register specifies the + location of vector B within the + PKA RAM. Vectors are identified + through the location of their + least-significant 32-bit word. + Note that bit [0] must be zero + to ensure that the vector starts + at an 8-byte boundary. */ +#define PKA_BPTR_BPTR_S 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA_CPTR register registers bit fields + * @{ + */ +#define PKA_CPTR_CPTR_M 0x000007FF /**< This register specifies the + location of vector C within the + PKA RAM. Vectors are identified + through the location of their + least-significant 32-bit word. + Note that bit [0] must be zero + to ensure that the vector starts + at an 8-byte boundary. */ +#define PKA_CPTR_CPTR_S 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA_DPTR register registers bit fields + * @{ + */ +#define PKA_DPTR_DPTR_M 0x000007FF /**< This register specifies the + location of vector D within the + PKA RAM. Vectors are identified + through the location of their + least-significant 32-bit word. + Note that bit [0] must be zero + to ensure that the vector starts + at an 8-byte boundary. */ +#define PKA_DPTR_DPTR_S 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA_ALENGTH register registers bit fields + * @{ + */ +#define PKA_ALENGTH_ALENGTH_M 0x000001FF /**< This register specifies the + length (in 32-bit words) of + Vector A. */ +#define PKA_ALENGTH_ALENGTH_S 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA_BLENGTH register registers bit fields + * @{ + */ +#define PKA_BLENGTH_BLENGTH_M 0x000001FF /**< This register specifies the + length (in 32-bit words) of + Vector B. */ +#define PKA_BLENGTH_BLENGTH_S 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA_SHIFT register registers bit fields + * @{ + */ +#define PKA_SHIFT_NUM_BITS_TO_SHIFT_M \ + 0x0000001F /**< This register specifies the + number of bits to shift the + input vector (in the range 0-31) + during a Rshift or Lshift + operation. */ + +#define PKA_SHIFT_NUM_BITS_TO_SHIFT_S 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA_FUNCTION register registers bit fields + * @{ + */ +#define PKA_FUNCTION_STALL_RESULT \ + 0x01000000 /**< When written with a 1b, + updating of the PKA_COMPARE, + PKA_MSW and PKA_DIVMSW + registers, as well as resetting + the run bit is stalled beyond + the point that a running + operation is actually finished. + Use this to allow software + enough time to read results from + a previous operation when the + newly started operation is known + to take only a short amount of + time. If a result is waiting, + the result registers is updated + and the run bit is reset in the + clock cycle following writing + the stall result bit back to 0b. + The Stall result function may + only be used for basic PKCP + operations. */ + +#define PKA_FUNCTION_STALL_RESULT_M \ + 0x01000000 +#define PKA_FUNCTION_STALL_RESULT_S 24 +#define PKA_FUNCTION_RUN 0x00008000 /**< The host sets this bit to + instruct the PKA module to begin + processing the basic PKCP or + complex sequencer operation. + This bit is reset low + automatically when the operation + is complete. The complement of + this bit is output as + interrupts[1]. After a reset, + the run bit is always set to 1b. + Depending on the option, program + ROM or program RAM, the + following applies: Program ROM - + The first sequencer instruction + sets the bit to 0b. This is done + immediately after the hardware + reset is released. Program RAM - + The sequencer must set the bit + to 0b. As a valid firmware may + not have been loaded, the + sequencer is held in software + reset after the hardware reset + is released (the reset bit in + PKA_SEQ_CRTL is set to 1b). + After the FW image is loaded and + the Reset bit is cleared, the + sequencer starts to execute the + FW. The first instruction clears + the run bit. In both cases a few + clock cycles are needed before + the first instruction is + executed and the run bit state + has been propagated. */ +#define PKA_FUNCTION_RUN_M 0x00008000 +#define PKA_FUNCTION_RUN_S 15 +#define PKA_FUNCTION_SEQUENCER_OPERATIONS_M \ + 0x00007000 /**< These bits select the complex + sequencer operation to perform: + 000b: None 001b: ExpMod-CRT + 010b: ExpMod-ACT4 (compatible + with EIP2315) 011b: ECC-ADD (if + available in firmware, otherwise + reserved) 100b: ExpMod-ACT2 + (compatible with EIP2316) 101b: + ECC-MUL (if available in + firmware, otherwise reserved) + 110b: ExpMod-variable 111b: + ModInv (if available in + firmware, otherwise reserved) + The encoding of these operations + is determined by sequencer + firmware. */ + +#define PKA_FUNCTION_SEQUENCER_OPERATIONS_S 12 +#define PKA_FUNCTION_COPY 0x00000800 /**< Perform copy operation */ +#define PKA_FUNCTION_COPY_M 0x00000800 +#define PKA_FUNCTION_COPY_S 11 +#define PKA_FUNCTION_COMPARE 0x00000400 /**< Perform compare operation */ +#define PKA_FUNCTION_COMPARE_M 0x00000400 +#define PKA_FUNCTION_COMPARE_S 10 +#define PKA_FUNCTION_MODULO 0x00000200 /**< Perform modulo operation */ +#define PKA_FUNCTION_MODULO_M 0x00000200 +#define PKA_FUNCTION_MODULO_S 9 +#define PKA_FUNCTION_DIVIDE 0x00000100 /**< Perform divide operation */ +#define PKA_FUNCTION_DIVIDE_M 0x00000100 +#define PKA_FUNCTION_DIVIDE_S 8 +#define PKA_FUNCTION_LSHIFT 0x00000080 /**< Perform left shift operation */ +#define PKA_FUNCTION_LSHIFT_M 0x00000080 +#define PKA_FUNCTION_LSHIFT_S 7 +#define PKA_FUNCTION_RSHIFT 0x00000040 /**< Perform right shift operation */ +#define PKA_FUNCTION_RSHIFT_M 0x00000040 +#define PKA_FUNCTION_RSHIFT_S 6 +#define PKA_FUNCTION_SUBTRACT 0x00000020 /**< Perform subtract operation */ +#define PKA_FUNCTION_SUBTRACT_M 0x00000020 +#define PKA_FUNCTION_SUBTRACT_S 5 +#define PKA_FUNCTION_ADD 0x00000010 /**< Perform add operation */ +#define PKA_FUNCTION_ADD_M 0x00000010 +#define PKA_FUNCTION_ADD_S 4 +#define PKA_FUNCTION_MS_ONE 0x00000008 /**< Loads the location of the Most + Significant one bit within the + result word indicated in the + PKA_MSW register into bits [4:0] + of the PKA_DIVMSW register - can + only be used with basic PKCP + operations, except for Divide, + Modulo and Compare. */ +#define PKA_FUNCTION_MS_ONE_M 0x00000008 +#define PKA_FUNCTION_MS_ONE_S 3 +#define PKA_FUNCTION_ADDSUB 0x00000002 /**< Perform combined add/subtract + operation */ +#define PKA_FUNCTION_ADDSUB_M 0x00000002 +#define PKA_FUNCTION_ADDSUB_S 1 +#define PKA_FUNCTION_MULTIPLY 0x00000001 /**< Perform multiply operation */ +#define PKA_FUNCTION_MULTIPLY_M 0x00000001 +#define PKA_FUNCTION_MULTIPLY_S 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA_COMPARE register registers bit fields + * @{ + */ +#define PKA_COMPARE_A_GREATER_THAN_B \ + 0x00000004 /**< Vector_A is greater than + Vector_B */ + +#define PKA_COMPARE_A_GREATER_THAN_B_M \ + 0x00000004 +#define PKA_COMPARE_A_GREATER_THAN_B_S 2 +#define PKA_COMPARE_A_LESS_THAN_B \ + 0x00000002 /**< Vector_A is less than Vector_B */ + +#define PKA_COMPARE_A_LESS_THAN_B_M \ + 0x00000002 +#define PKA_COMPARE_A_LESS_THAN_B_S 1 +#define PKA_COMPARE_A_EQUALS_B 0x00000001 /**< Vector_A is equal to Vector_B */ +#define PKA_COMPARE_A_EQUALS_B_M \ + 0x00000001 +#define PKA_COMPARE_A_EQUALS_B_S 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA_MSW register registers bit fields + * @{ + */ +#define PKA_MSW_RESULT_IS_ZERO 0x00008000 /**< The result vector is all + zeroes, ignore the address + returned in bits [10:0] */ +#define PKA_MSW_RESULT_IS_ZERO_M \ + 0x00008000 +#define PKA_MSW_RESULT_IS_ZERO_S 15 +#define PKA_MSW_MSW_ADDRESS_M 0x000007FF /**< Address of the most-significant + nonzero 32-bit word of the + result vector in PKA RAM */ +#define PKA_MSW_MSW_ADDRESS_S 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA_DIVMSW register registers bit fields + * @{ + */ +#define PKA_DIVMSW_RESULT_IS_ZERO \ + 0x00008000 /**< The result vector is all + zeroes, ignore the address + returned in bits [10:0] */ + +#define PKA_DIVMSW_RESULT_IS_ZERO_M \ + 0x00008000 +#define PKA_DIVMSW_RESULT_IS_ZERO_S 15 +#define PKA_DIVMSW_MSW_ADDRESS_M \ + 0x000007FF /**< Address of the most significant + nonzero 32-bit word of the + remainder result vector in PKA + RAM */ + +#define PKA_DIVMSW_MSW_ADDRESS_S 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA_SEQ_CTRL register registers bit fields + * @{ + */ +#define PKA_SEQ_CTRL_RESET 0x80000000 /**< Option program ROM: Reset value + = 0. Read/Write, reset value 0b + (ZERO). Writing 1b resets the + sequencer, write to 0b to + restart operations again. As the + reset value is 0b, the sequencer + will automatically start + operations executing from + program ROM. This bit should + always be written with zero and + ignored when reading this + register. Option Program RAM: + Reset value =1. Read/Write, + reset value 1b (ONE). When 1b, + the sequencer is held in a reset + state and the PKA_PROGRAM area + is accessible for loading the + sequencer program (while the + PKA_DATA_RAM is inaccessible), + write to 0b to (re)start + sequencer operations and disable + PKA_PROGRAM area accessibility + (also enables the PKA_DATA_RAM + accesses). Resetting the + sequencer (in order to load + other firmware) should only be + done when the PKA Engine is not + performing any operations (i.e. + the run bit in the PKA_FUNCTION + register should be zero). */ +#define PKA_SEQ_CTRL_RESET_M 0x80000000 +#define PKA_SEQ_CTRL_RESET_S 31 +#define PKA_SEQ_CTRL_SEQUENCER_STATUS_M \ + 0x0000FF00 /**< These read-only bits can be + used by the sequencer to + communicate status to the + outside world. Bit [8] is also + used as sequencer interrupt, + with the complement of this bit + ORed into the run bit in + PKA_FUNCTION. This field should + always be written with zeroes + and ignored when reading this + register. */ + +#define PKA_SEQ_CTRL_SEQUENCER_STATUS_S 8 +#define PKA_SEQ_CTRL_SW_CONTROL_STATUS_M \ + 0x000000FF /**< These bits can be used by + software to trigger sequencer + operations. External logic can + set these bits by writing 1b, + cannot reset them by writing 0b. + The sequencer can reset these + bits by writing 0b, cannot set + them by writing 1b. Setting the + run bit in PKA_FUNCTION together + with a nonzero sequencer + operations field automatically + sets bit [0] here. This field + should always be written with + zeroes and ignored when reading + this register. */ + +#define PKA_SEQ_CTRL_SW_CONTROL_STATUS_S 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA_OPTIONS register registers bit fields + * @{ + */ +#define PKA_OPTIONS_FIRST_LNME_FIFO_DEPTH_M \ + 0xFF000000 /**< Number of words in the first + LNME's FIFO RAM Should be + ignored if LNME configuration is + 0. The contents of this field + indicate the actual depth as + selected by the LNME FIFO RAM + size strap input, fifo_size_sel. + Note: Reset value is undefined */ + +#define PKA_OPTIONS_FIRST_LNME_FIFO_DEPTH_S 24 +#define PKA_OPTIONS_FIRST_LNME_NR_OF_PES_M \ + 0x003F0000 /**< Number of processing elements + in the pipeline of the first + LNME Should be ignored if LNME + configuration is 0. Note: Reset + value is undefined. */ + +#define PKA_OPTIONS_FIRST_LNME_NR_OF_PES_S 16 +#define PKA_OPTIONS_MMM3A 0x00001000 /**< Reserved for a future + functional extension to the LNME + Always 0b */ +#define PKA_OPTIONS_MMM3A_M 0x00001000 +#define PKA_OPTIONS_MMM3A_S 12 +#define PKA_OPTIONS_INT_MASKING 0x00000800 /**< Value 0b indicates that the + main interrupt output (bit [1] + of the interrupts output bus) is + the direct complement of the run + bit in the PKA_CONTROL register, + value 1b indicates that + interrupt masking logic is + present for this output. Note: + Reset value is undefined */ +#define PKA_OPTIONS_INT_MASKING_M \ + 0x00000800 +#define PKA_OPTIONS_INT_MASKING_S 11 +#define PKA_OPTIONS_PROTECTION_OPTION_M \ + 0x00000700 /**< Value 0 indicates no additional + protection against side channel + attacks, value 1 indicates the + SCAP option, value 3 indicates + the PROT option; other values + are reserved. Note: Reset value + is undefined */ + +#define PKA_OPTIONS_PROTECTION_OPTION_S 8 +#define PKA_OPTIONS_PROGRAM_RAM 0x00000080 /**< Value 1b indicates sequencer + program storage in RAM, value 0b + in ROM. Note: Reset value is + undefined */ +#define PKA_OPTIONS_PROGRAM_RAM_M \ + 0x00000080 +#define PKA_OPTIONS_PROGRAM_RAM_S 7 +#define PKA_OPTIONS_SEQUENCER_CONFIGURATION_M \ + 0x00000060 /**< Value 1 indicates a standard + sequencer; other values are + reserved. */ + +#define PKA_OPTIONS_SEQUENCER_CONFIGURATION_S 5 +#define PKA_OPTIONS_LNME_CONFIGURATION_M \ + 0x0000001C /**< Value 0 indicates NO LNME, + value 1 indicates one standard + LNME (with alpha = 32, beta = + 8); other values reserved. Note: + Reset value is undefined */ + +#define PKA_OPTIONS_LNME_CONFIGURATION_S 2 +#define PKA_OPTIONS_PKCP_CONFIGURATION_M \ + 0x00000003 /**< Value 1 indicates a PKCP with a + 16x16 multiplier, value 2 + indicates a PKCP with a 32x32 + multiplier, other values + reserved. Note: Reset value is + undefined. */ + +#define PKA_OPTIONS_PKCP_CONFIGURATION_S 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA_SW_REV register registers bit fields + * @{ + */ +#define PKA_SW_REV_FW_CAPABILITIES_M \ + 0xF0000000 /**< 4-bit binary encoding for the + functionality implemented in the + firmware. Value 0 indicates + basic ModExp with/without CRT. + Value 1 adds Modular Inversion, + value 2 adds Modular Inversion + and ECC operations. Values 3-15 + are reserved. */ + +#define PKA_SW_REV_FW_CAPABILITIES_S 28 +#define PKA_SW_REV_MAJOR_FW_REVISION_M \ + 0x0F000000 /**< 4-bit binary encoding of the + major firmware revision number */ + +#define PKA_SW_REV_MAJOR_FW_REVISION_S 24 +#define PKA_SW_REV_MINOR_FW_REVISION_M \ + 0x00F00000 /**< 4-bit binary encoding of the + minor firmware revision number */ + +#define PKA_SW_REV_MINOR_FW_REVISION_S 20 +#define PKA_SW_REV_FW_PATCH_LEVEL_M \ + 0x000F0000 /**< 4-bit binary encoding of the + firmware patch level, initial + release will carry value zero + Patches are used to remove bugs + without changing the + functionality or interface of a + module. */ + +#define PKA_SW_REV_FW_PATCH_LEVEL_S 16 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA_REVISION register registers bit fields + * @{ + */ +#define PKA_REVISION_MAJOR_HW_REVISION_M \ + 0x0F000000 /**< 4-bit binary encoding of the + major hardware revision number */ + +#define PKA_REVISION_MAJOR_HW_REVISION_S 24 +#define PKA_REVISION_MINOR_HW_REVISION_M \ + 0x00F00000 /**< 4-bit binary encoding of the + minor hardware revision number */ + +#define PKA_REVISION_MINOR_HW_REVISION_S 20 +#define PKA_REVISION_HW_PATCH_LEVEL_M \ + 0x000F0000 /**< 4-bit binary encoding of the + hardware patch level, initial + release will carry value zero + Patches are used to remove bugs + without changing the + functionality or interface of a + module. */ + +#define PKA_REVISION_HW_PATCH_LEVEL_S 16 +#define PKA_REVISION_COMPLEMENT_OF_BASIC_EIP_NUMBER_M \ + 0x0000FF00 /**< Bit-by-bit logic complement of + bits [7:0], EIP-28 gives 0xE3 */ + +#define PKA_REVISION_COMPLEMENT_OF_BASIC_EIP_NUMBER_S 8 +#define PKA_REVISION_BASIC_EIP_NUMBER_M \ + 0x000000FF /**< 8-bit binary encoding of the + EIP number, EIP-28 gives 0x1C */ + +#define PKA_REVISION_BASIC_EIP_NUMBER_S 0 + +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA driver return codes + * @{ + */ +#define PKA_STATUS_SUCCESS 0 /**< Success */ +#define PKA_STATUS_FAILURE 1 /**< Failure */ +#define PKA_STATUS_INVALID_PARAM 2 /**< Invalid parameter */ +#define PKA_STATUS_BUF_UNDERFLOW 3 /**< Buffer underflow */ +#define PKA_STATUS_RESULT_0 4 /**< Result is all zeros */ +#define PKA_STATUS_A_GR_B 5 /**< Big number compare return status if + the first big num is greater than + the second. */ +#define PKA_STATUS_A_LT_B 6 /**< Big number compare return status if + the first big num is less than the + second. */ +#define PKA_STATUS_OPERATION_INPRG 7 /**< PKA operation is in progress. */ +#define PKA_STATUS_OPERATION_NOT_INPRG 8 /**< No PKA operation is in progress. */ +#define PKA_STATUS_SIGNATURE_INVALID 9 /**< Signature is invalid. */ + +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PKA functions + * @{ + */ + +/** \brief Enables and resets the PKA engine + */ +void pka_init(void); + +/** \brief Enables the PKA engine + */ +void pka_enable(void); + +/** \brief Disables the PKA engine + * \note Call this function to save power when the engine is unused. + */ +void pka_disable(void); + +/** \brief Checks the status of the PKA engine operation + * \retval false Result not yet available, and no error occurred + * \retval true Result available, or error occurred + */ +uint8_t pka_check_status(void); + +/** \brief Registers a process to be notified of the completion of a PKA + * operation + * \param p Process to be polled upon IRQ + * \note This function is only supposed to be called by the PKA drivers. + */ +void pka_register_process_notification(struct process *p); + +/** @} */ + +#endif /* PKA_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/pwm.c b/cpu/cc2538/dev/pwm.c new file mode 100644 index 000000000..d6b5b9286 --- /dev/null +++ b/cpu/cc2538/dev/pwm.c @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc2538-pwm-driver + * @{ + * + * \file + * Driver for the CC2538 PWM + * + * \author + * Javier Sanchez + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/ioc.h" +#include "dev/gpio.h" +#include "dev/sys-ctrl.h" +#include "dev/pwm.h" +#include "lpm.h" +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +#define PWM_GPTIMER_NUM_TO_BASE(x) ((GPT_0_BASE) + ((x) << 12)) +/*---------------------------------------------------------------------------*/ +static uint8_t +pwm_configured(uint8_t timer, uint8_t ab) +{ + uint8_t offset; + uint32_t gpt_base; + gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer); + offset = (ab) ? 4 : 0; + + if((REG(gpt_base + GPTIMER_TAMR + offset) & GPTIMER_TAMR_TAAMS) && + (REG(gpt_base + GPTIMER_TAMR + offset) & GPTIMER_TAMR_TAMR_PERIODIC)) { + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static bool +permit_pm1(void) +{ + uint8_t timer, ab; + + for(timer = PWM_TIMER_0; timer <= PWM_TIMER_3; timer++) + for(ab = PWM_TIMER_A; ab <= PWM_TIMER_B; ab++) + if(pwm_configured(timer, ab) && + REG(PWM_GPTIMER_NUM_TO_BASE(timer) + GPTIMER_CTL) & + (ab == PWM_TIMER_A ? GPTIMER_CTL_TAEN : GPTIMER_CTL_TBEN)) + return false; + + return true; +} +/*---------------------------------------------------------------------------*/ +int8_t +pwm_enable(uint32_t freq, uint8_t duty, uint8_t timer, uint8_t ab) +{ + uint8_t offset = 0; + uint32_t interval_load, duty_count, copy; + uint32_t gpt_base, gpt_en, gpt_dir; + + if((freq < PWM_FREQ_MIN) || (freq > PWM_FREQ_MAX) || + (duty < PWM_DUTY_MIN) || (duty > PWM_DUTY_MAX) || + (timer > PWM_TIMER_MAX) || (timer < PWM_TIMER_MIN)) { + PRINTF("PWM: Invalid PWM settings\n"); + return PWM_ERROR; + } + + /* GPT0 timer A is used for clock_delay_usec() in clock.c */ + if((ab == PWM_TIMER_A) && (timer == PWM_TIMER_0)) { + PRINTF("PWM: GPT0 (timer A) is reserved for clock_delay_usec()\n"); + return PWM_ERROR; + } + + PRINTF("PWM: F%08luHz: %u%% on GPT%u-%u\n", freq, duty, timer, ab); + + lpm_register_peripheral(permit_pm1); + + gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer); + gpt_en = GPTIMER_CTL_TAEN; + gpt_dir = GPTIMER_CTL_TAPWML; + + if(ab == PWM_TIMER_B) { + offset = 4; + gpt_en = GPTIMER_CTL_TBEN; + gpt_dir = GPTIMER_CTL_TBPWML; + } + + PRINTF("PWM: GPT_x_BASE 0x%08lX (%u)\n", gpt_base, offset); + + /* Restore later, ensure GPTIMER_CTL_TxEN and GPTIMER_CTL_TxPWML are clear */ + copy = REG(gpt_base + GPTIMER_CTL); + copy &= ~(gpt_en | gpt_dir); + + /* Enable module clock for the GPTx in Active mode */ + REG(SYS_CTRL_RCGCGPT) |= (SYS_CTRL_RCGCGPT_GPT0 << timer); + /* Enable module clock for the GPTx in Sleep mode */ + REG(SYS_CTRL_SCGCGPT) |= (SYS_CTRL_SCGCGPT_GPT0 << timer); + /* Enable module clock for the GPTx in PM0, in PM1 and below this doesn't matter */ + REG(SYS_CTRL_DCGCGPT) |= (SYS_CTRL_DCGCGPT_GPT0 << timer); + + /* Stop the timer */ + REG(gpt_base + GPTIMER_CTL) = 0; + /* Use 16-bit timer */ + REG(gpt_base + GPTIMER_CFG) = PWM_GPTIMER_CFG_SPLIT_MODE; + /* Configure PWM mode */ + REG(gpt_base + GPTIMER_TAMR + offset) = 0; + REG(gpt_base + GPTIMER_TAMR + offset) |= GPTIMER_TAMR_TAAMS; + REG(gpt_base + GPTIMER_TAMR + offset) |= GPTIMER_TAMR_TAMR_PERIODIC; + + /* If the duty cycle is zero, leave the GPTIMER configured as PWM to pass a next + * configured check, but do nothing else */ + if(!duty) { + REG(gpt_base + GPTIMER_CTL) |= (copy | gpt_dir); + return PWM_SUCCESS; + } + + /* Get the peripheral clock and equivalent deassert count */ + interval_load = sys_ctrl_get_sys_clock() / freq; + duty_count = ((interval_load * duty) + 1) / 100; + + PRINTF("PWM: sys %luHz: %lu %lu\n", sys_ctrl_get_sys_clock(), + interval_load, duty_count); + + /* Set the start value (period), count down */ + REG(gpt_base + GPTIMER_TAILR + offset) = ((uint16_t *)&interval_load)[0] - 1; + /* Set the deassert period */ + REG(gpt_base + GPTIMER_TAMATCHR + offset) = ((uint16_t *)&duty_count)[0] - 1; + /* Set the prescaler if required */ + REG(gpt_base + GPTIMER_TAPR + offset) = ((uint8_t *)&interval_load)[2]; + /* Set the prescaler match if required */ + REG(gpt_base + GPTIMER_TAPMR + offset) = ((uint8_t *)&duty_count)[2]; + /* Restore the register content */ + REG(gpt_base + GPTIMER_CTL) |= (copy | gpt_dir); + + PRINTF("PWM: TnILR %lu ", REG(gpt_base + (GPTIMER_TAILR + offset))); + PRINTF("TnMATCHR %lu ", REG(gpt_base + (GPTIMER_TAMATCHR + offset))); + PRINTF("TnPR %lu ", REG(gpt_base + (GPTIMER_TAPR + offset))); + PRINTF("TnPMR %lu\n", REG(gpt_base + (GPTIMER_TAPMR + offset))); + + return PWM_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int8_t +pwm_stop(uint8_t timer, uint8_t ab, uint8_t port, uint8_t pin, uint8_t state) +{ + uint32_t gpt_base, gpt_dis; + + if((ab > PWM_TIMER_B) || (timer < PWM_TIMER_MIN) || + (timer > PWM_TIMER_MAX)) { + PRINTF("PWM: Invalid PWM values\n"); + return PWM_ERROR; + } + + if(!pwm_configured(timer, ab)) { + PRINTF("PWM: GPTn not configured as PWM\n"); + return PWM_ERROR; + } + + /* CC2538 has 4 ports (A-D) and up to 8 pins (0-7) */ + if((port > GPIO_D_NUM) || (pin > 7)) { + PRINTF("PWM: Invalid pin/port settings\n"); + return PWM_ERROR; + } + + /* CC2538 has 4 ports (A-D) and up to 8 pins (0-7) */ + if((state != PWM_OFF_WHEN_STOP) && (state != PWM_ON_WHEN_STOP)) { + PRINTF("PWM: Invalid pin state when PWM is halt\n"); + return PWM_ERROR; + } + + gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer); + gpt_dis = (ab == PWM_TIMER_B) ? GPTIMER_CTL_TBEN : GPTIMER_CTL_TAEN; + REG(gpt_base + GPTIMER_CTL) &= ~gpt_dis; + + /* Configure the port/pin as GPIO, input */ + ioc_set_over(port, pin, IOC_OVERRIDE_DIS); + GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + GPIO_SET_OUTPUT(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + if(state) { + GPIO_SET_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + } else { + GPIO_CLR_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + } + PRINTF("PWM: OFF -> Timer %u (%u)\n", timer, ab); + return PWM_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int8_t +pwm_start(uint8_t timer, uint8_t ab, uint8_t port, uint8_t pin) +{ + uint32_t gpt_base, gpt_en, gpt_sel; + + if((ab > PWM_TIMER_B) || (timer < PWM_TIMER_MIN) || + (timer > PWM_TIMER_MAX)) { + PRINTF("PWM: Invalid PWM values\n"); + return PWM_ERROR; + } + + if(!pwm_configured(timer, ab)) { + PRINTF("PWM: GPTn not configured as PWM\n"); + return PWM_ERROR; + } + + /* CC2538 has 4 ports (A-D) and up to 8 pins (0-7) */ + if((port > GPIO_D_NUM) || (pin > 7)) { + PRINTF("PWM: Invalid pin/port settings\n"); + return PWM_ERROR; + } + + /* Map to given port/pin */ + gpt_sel = IOC_PXX_SEL_GPT0_ICP1 + (timer * 2); + if(ab == PWM_TIMER_B) { + gpt_sel++; + } + ioc_set_sel(port, pin, gpt_sel); + ioc_set_over(port, pin, IOC_OVERRIDE_OE); + GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + + gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer); + gpt_en = (ab == PWM_TIMER_B) ? GPTIMER_CTL_TBEN : GPTIMER_CTL_TAEN; + REG(gpt_base + GPTIMER_CTL) |= gpt_en; + PRINTF("PWM: ON -> Timer %u (%u) IOC_PXX_SEL_GPTx_IPCx 0x%08lX\n", timer, ab, + gpt_sel); + return PWM_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int8_t +pwm_set_direction(uint8_t timer, uint8_t ab, uint8_t dir) +{ + uint32_t gpt_base, gpt_dir; + + if((ab > PWM_TIMER_B) || (timer < PWM_TIMER_MIN) || + (timer > PWM_TIMER_MAX) || (dir > PWM_SIGNAL_INVERTED)) { + PRINTF("PWM: Invalid PWM values\n"); + return PWM_ERROR; + } + + if(!pwm_configured(timer, ab)) { + PRINTF("PWM: GPTn not configured as PWM\n"); + return PWM_ERROR; + } + + gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer); + gpt_dir = (ab == PWM_TIMER_B) ? GPTIMER_CTL_TBPWML : GPTIMER_CTL_TAPWML; + if(dir) { + REG(gpt_base + GPTIMER_CTL) |= gpt_dir; + } else { + REG(gpt_base + GPTIMER_CTL) &= ~gpt_dir; + } + + PRINTF("PWM: Signal direction (%u) -> Timer %u (%u)\n", dir, timer, ab); + return PWM_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int8_t +pwm_toggle_direction(uint8_t timer, uint8_t ab) +{ + uint32_t gpt_base, gpt_dir; + + if((ab > PWM_TIMER_B) || (timer < PWM_TIMER_MIN) || + (timer > PWM_TIMER_MAX)) { + PRINTF("PWM: Invalid PWM values\n"); + return PWM_ERROR; + } + + if(!pwm_configured(timer, ab)) { + PRINTF("PWM: GPTn not configured as PWM\n"); + return PWM_ERROR; + } + + gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer); + gpt_dir = (ab == PWM_TIMER_B) ? GPTIMER_CTL_TBPWML : GPTIMER_CTL_TAPWML; + if(REG(gpt_base + GPTIMER_CTL) & gpt_dir) { + REG(gpt_base + GPTIMER_CTL) &= ~gpt_dir; + } else { + REG(gpt_base + GPTIMER_CTL) |= gpt_dir; + } + + PRINTF("PWM: direction toggled -> Timer %u (%u)\n", timer, ab); + return PWM_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int8_t +pwm_disable(uint8_t timer, uint8_t ab, uint8_t port, uint8_t pin) +{ + uint32_t gpt_base; + uint8_t offset = (ab == PWM_TIMER_B) ? 4 : 0; + gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer); + + if((ab > PWM_TIMER_B) || (timer < PWM_TIMER_MIN) || + (timer > PWM_TIMER_MAX)) { + PRINTF("PWM: Invalid PWM values\n"); + return PWM_ERROR; + } + + /* CC2538 has 4 ports (A-D) and up to 8 pins (0-7) */ + if((port > GPIO_D_NUM) || (pin > 7)) { + PRINTF("PWM: Invalid pin/port settings\n"); + return PWM_ERROR; + } + + if(!pwm_configured(timer, ab)) { + PRINTF("PWM: GPTn not configured as PWM\n"); + return PWM_ERROR; + } + + /* Stop the PWM */ + pwm_stop(timer, ab, port, pin, PWM_OFF_WHEN_STOP); + /* Disable the PWM mode */ + REG(gpt_base + (GPTIMER_TAMR + offset)) = 0; + /* Restart the interval load and deassert values */ + REG(gpt_base + (GPTIMER_TAILR + offset)) = 0; + REG(gpt_base + (GPTIMER_TAMATCHR + offset)) = 0; + + /* Configure the port/pin as GPIO, input */ + ioc_set_over(port, pin, IOC_OVERRIDE_DIS); + GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + GPIO_SET_INPUT(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + + return PWM_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/cpu/cc2538/dev/pwm.h b/cpu/cc2538/dev/pwm.h new file mode 100644 index 000000000..744fa4b6c --- /dev/null +++ b/cpu/cc2538/dev/pwm.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc2538 + * @{ + * + * \defgroup cc2538-pwm-driver CC2538 PWM driver + * + * Driver for the CC2538 PWM on GPTIMER + * + * The driver uses the timers A and B of the general purpose timers to create + * a PWM signal, allowing to set a duty cycle value from 1-100%. This + * implementation relies on having a peripheral clock of 16MHz, but it can be + * easily changed (see PWM_FREQ_MIN and PWM_FREQ_MAX values). The reason it is + * fixed to these frequencies is to have a consistent duty cycle + * implementation. + * + * Depending on the specific needs these limits can be changed to meet a given + * duty cycle and lower frequencies by using the prescaler (GPTIMER_TnPR). + * + * Running a PWM timer prevents the LPM driver from dropping to PM1+. + * + * @{ + * + * \file + * Header file for the CC2538 PWM driver + * + * \author + * Javier Sanchez + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#ifndef PWM_H_ +#define PWM_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/ioc.h" +#include "dev/gpio.h" +#include "dev/sys-ctrl.h" +/*---------------------------------------------------------------------------*/ +/** \name PWM return values + * @{ + */ +#define PWM_SUCCESS 0 +#define PWM_ERROR (-1) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PWM recommended values respect to peripheral clock frequency + * @{ + */ +/* Roughly 244 Hz with a 16-MHz system clock, no prescaler */ +#define PWM_SYS_16MHZ_NO_PRES_MIN 0xFFFF +#define PWM_SYS_16MHZ_NO_PRES_MIN_FREQ 244 +/* Roughly 1 Hz with a 16-MHz system clock, to keep frequency parameter in Hz */ +#define PWM_SYS_16MHZ_PRES_MIN 0x00F42400 +#define PWM_SYS_16MHZ_PRES_MIN_FREQ 1 +/* Yields 160 KHz at 16 MHz and allows down to 1% (integer) duty cycles */ +#define PWM_SYS_16MHZ_NO_PRES_MAX 100 +#define PWM_SYS_16MHZ_NO_PRES_MAX_FREQ 160000 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PWM driver definitions and configuration values + * @{ + */ +#define PWM_TIMER_A 0 +#define PWM_TIMER_B 1 +#define PWM_TIMER_0 0 +#define PWM_TIMER_1 1 +#define PWM_TIMER_2 2 +#define PWM_TIMER_3 3 +#define PWM_TIMER_MIN PWM_TIMER_0 +#define PWM_TIMER_MAX PWM_TIMER_3 +#define PWM_SIGNAL_STRAIGHT 1 +#define PWM_SIGNAL_INVERTED 0 +#define PWM_OFF_WHEN_STOP 0 +#define PWM_ON_WHEN_STOP 1 +#define PWM_GPTIMER_CFG_SPLIT_MODE 0x04 +#define PWM_DUTY_MAX 100 +#define PWM_DUTY_MIN 0 +#define PWM_FREQ_MIN PWM_SYS_16MHZ_PRES_MIN_FREQ +#define PWM_FREQ_MAX PWM_SYS_16MHZ_NO_PRES_MAX_FREQ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name PWM functions + * @{ + */ +/** \brief Configures the general purpose timer in PWM mode + * \param freq PWM frequency (in Hz) + * \param duty PWM duty cycle (percentage in integers) + * \param timer General purpose timer to use [0-3] + * \param ab Select which timer to use (Timer A or B) + * \return \c PWM_SUCCESS if successful, else \c PWM_ERROR + */ +int8_t pwm_enable(uint32_t freq, uint8_t duty, uint8_t timer, uint8_t ab); +/*---------------------------------------------------------------------------*/ +/** \brief Disables a previously PWM configured GPTn + * \param timer General purpose timer to disable [0-3] + * \param ab Select which timer to disable (Timer A or B) + * \param port Port number used as PWM to disable (set as input GPIO) + * \param pin Pin number used as PWM to disable (set as input GPIO) + * \return \c PWM_SUCCESS if successful, else \c PWM_ERROR + * + * This function disables a specific timer (A or B) and reset related registers + * to default values. The user must explicitely pass the port/pin number of + * the pin to disable as PWM and to be configured as input GPIO. + * The module clock is not disabled with this function + */ +int8_t pwm_disable(uint8_t timer, uint8_t ab, uint8_t port, uint8_t pin); +/*---------------------------------------------------------------------------*/ +/** \brief Once configured, starts the PWM + * \param timer General purpose timer to start [0-3] + * \param ab Select which timer to start (Timer A or B) + * \param port Port number to use as PWM + * \param pin Pin number to use as PWM + * \return \c PWM_SUCCESS if successful, else \c PWM_ERROR + */ +int8_t pwm_start(uint8_t timer, uint8_t ab, uint8_t port, uint8_t pin); +/*---------------------------------------------------------------------------*/ +/** \brief Halts the PWM in a given GPT/timer + * \param timer General purpose timer to stop [0-3] + * \param ab Select which timer to stop (Timer A or B) + * \param port Port of the gpio port mapped to the PWM to stop + * \param pin Pin of the gpio port mapped to the PWM to stop + * \param state State to leave the pin once stopped, on (1) or off (0) + * \return \c PWM_SUCCESS if successful, else \c PWM_ERROR + */ +int8_t pwm_stop(uint8_t timer, uint8_t ab, uint8_t port, uint8_t pin, uint8_t state); +/*---------------------------------------------------------------------------*/ +/** \brief Sets the PWM duty cycle signal direction (high/low) + * \param timer General purpose timer [0-3] + * \param ab Select which timer to use (Timer A or B) + * \param dir Direction of the PWM signal, \c PWM_SIGNAL_INVERTED or + * \c PWM_SIGNAL_STRAIGHT + * \return \c PWM_SUCCESS if successful, else \c PWM_ERROR + */ +int8_t pwm_set_direction(uint8_t timer, uint8_t ab, uint8_t dir); +/*---------------------------------------------------------------------------*/ +/** \brief Toggle the PWM signal direction (inverts the current duty cycle) + * \param timer General purpose timer to use [0-3] + * \param ab Select which timer to use (Timer A or B) + * \return \c PWM_SUCCESS if successful, else \c PWM_ERROR + */ +int8_t pwm_toggle_direction(uint8_t timer, uint8_t ab); +/*---------------------------------------------------------------------------*/ +/** @} */ +#endif /* PWM_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/random.c b/cpu/cc2538/dev/random.c index a4ef7c03a..8c955aa8a 100644 --- a/cpu/cc2538/dev/random.c +++ b/cpu/cc2538/dev/random.c @@ -92,6 +92,9 @@ random_init(unsigned short seed) /* Enable clock for the RF Core */ REG(SYS_CTRL_RCGCRFC) = 1; + /* Wait for the clock ungating to take effect */ + while(REG(SYS_CTRL_RCGCRFC) != 1); + /* Infinite RX - FRMCTRL0[3:2] = 10 * This will mess with radio operation - see note above */ REG(RFCORE_XREG_FRMCTRL0) = 0x00000008; diff --git a/cpu/cc2538/dev/scb.h b/cpu/cc2538/dev/scb.h index 53b1535e4..e91951ecb 100644 --- a/cpu/cc2538/dev/scb.h +++ b/cpu/cc2538/dev/scb.h @@ -32,7 +32,9 @@ * \addtogroup cc2538 * @{ * - * \defgroup cc2538-scb cc2538 System Control Block + * \defgroup cc2538-scb cc2538 System Control Block (SCB) + * + * Offsets and bit definitions for SCB registers * @{ * * \file diff --git a/cpu/cc2538/dev/sha256.c b/cpu/cc2538/dev/sha256.c new file mode 100644 index 000000000..347c54081 --- /dev/null +++ b/cpu/cc2538/dev/sha256.c @@ -0,0 +1,356 @@ +/* + * Original file: + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2013, ADVANSEE - http://www.advansee.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-sha256 + * @{ + * + * \file + * Implementation of the cc2538 SHA-256 driver + */ +#include "contiki.h" +#include "sys/cc.h" +#include "dev/rom-util.h" +#include "dev/aes.h" +#include "dev/sha256.h" +#include "reg.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define BLOCK_SIZE 64 +#define OUTPUT_LEN 32 +/*---------------------------------------------------------------------------*/ +/** \brief Starts a new hash session in hardware + * \param state Hash state + * \param data Pointer to input message + * \param hash Destination of the hash (32 bytes) + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code + */ +static uint8_t +new_hash(sha256_state_t *state, const void *data, void *hash) +{ + /* Workaround for AES registers not retained after PM2 */ + REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL; + REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE | + AES_CTRL_INT_EN_RESULT_AV; + + /* Configure master control module and enable DMA path to the SHA-256 engine + * + Digest readout */ + REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_TAG | AES_CTRL_ALG_SEL_HASH; + + /* Clear any outstanding events */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_RESULT_AV; + + /* Configure hash engine + * Indicate start of a new hash session and SHA-256 */ + REG(AES_HASH_MODE_IN) = AES_HASH_MODE_IN_SHA256_MODE | + AES_HASH_MODE_IN_NEW_HASH; + + /* If the final digest is required (pad the input DMA data), write the + * following register */ + if(state->final_digest) { + /* Write length of the message (lo) */ + REG(AES_HASH_LENGTH_IN_L) = (uint32_t)state->length; + /* Write length of the message (hi) */ + REG(AES_HASH_LENGTH_IN_H) = (uint32_t)(state->length >> 32); + /* Pad the DMA-ed data */ + REG(AES_HASH_IO_BUF_CTRL) = AES_HASH_IO_BUF_CTRL_PAD_DMA_MESSAGE; + } + + /* Enable DMA channel 0 for message data */ + REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN; + /* Base address of the data in ext. memory */ + REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)data; + if(state->final_digest) { + /* Input data length in bytes, equal to the message */ + REG(AES_DMAC_CH0_DMALENGTH) = state->curlen; + } else { + REG(AES_DMAC_CH0_DMALENGTH) = BLOCK_SIZE; + } + + /* Enable DMA channel 1 for result digest */ + REG(AES_DMAC_CH1_CTRL) = AES_DMAC_CH_CTRL_EN; + /* Base address of the digest buffer */ + REG(AES_DMAC_CH1_EXTADDR) = (uint32_t)hash; + /* Length of the result digest */ + REG(AES_DMAC_CH1_DMALENGTH) = OUTPUT_LEN; + + /* Wait for completion of the operation */ + while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV)); + + if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) { + /* Clear the DMA error */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR; + /* Disable master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + return CRYPTO_DMA_BUS_ERROR; + } + + /* Clear the interrupt */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV; + /* Disable master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + /* Clear mode */ + REG(AES_AES_CTRL) = 0x00000000; + + return CRYPTO_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +/** \brief Resumes an already started hash session in hardware + * \param state Hash state + * \param data Pointer to the input message + * \param hash Pointer to the destination of the hash (32 bytes) + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code + */ +static uint8_t +resume_hash(sha256_state_t *state, const void *data, void *hash) +{ + /* Workaround for AES registers not retained after PM2 */ + REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL; + REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE | + AES_CTRL_INT_EN_RESULT_AV; + + /* Configure master control module and enable the DMA path to the SHA-256 + * engine */ + REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_HASH; + + /* Clear any outstanding events */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_RESULT_AV; + + /* Configure hash engine + * Indicate the start of a resumed hash session and SHA-256 */ + REG(AES_HASH_MODE_IN) = AES_HASH_MODE_IN_SHA256_MODE; + + /* If the final digest is required (pad the input DMA data) */ + if(state->final_digest) { + /* Write length of the message (lo) */ + REG(AES_HASH_LENGTH_IN_L) = (uint32_t)state->length; + /* Write length of the message (hi) */ + REG(AES_HASH_LENGTH_IN_H) = (uint32_t)(state->length >> 32); + } + + /* Write the initial digest */ + REG(AES_HASH_DIGEST_A) = (uint32_t)state->state[0]; + REG(AES_HASH_DIGEST_B) = (uint32_t)state->state[1]; + REG(AES_HASH_DIGEST_C) = (uint32_t)state->state[2]; + REG(AES_HASH_DIGEST_D) = (uint32_t)state->state[3]; + REG(AES_HASH_DIGEST_E) = (uint32_t)state->state[4]; + REG(AES_HASH_DIGEST_F) = (uint32_t)state->state[5]; + REG(AES_HASH_DIGEST_G) = (uint32_t)state->state[6]; + REG(AES_HASH_DIGEST_H) = (uint32_t)state->state[7]; + + /* If final digest, pad the DMA-ed data */ + if(state->final_digest) { + REG(AES_HASH_IO_BUF_CTRL) = AES_HASH_IO_BUF_CTRL_PAD_DMA_MESSAGE; + } + + /* Enable DMA channel 0 for message data */ + REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN; + /* Base address of the data in ext. memory */ + REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)data; + /* Input data length in bytes, equal to the message */ + if(state->final_digest) { + REG(AES_DMAC_CH0_DMALENGTH) = state->curlen; + } else { + REG(AES_DMAC_CH0_DMALENGTH) = BLOCK_SIZE; + } + + /* Wait for completion of the operation */ + while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV)); + + /* Check for any DMA Bus errors */ + if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) { + /* Clear the DMA error */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR; + /* Disable master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + return CRYPTO_DMA_BUS_ERROR; + } + + /* Read digest */ + ((uint32_t *)hash)[0] = REG(AES_HASH_DIGEST_A); + ((uint32_t *)hash)[1] = REG(AES_HASH_DIGEST_B); + ((uint32_t *)hash)[2] = REG(AES_HASH_DIGEST_C); + ((uint32_t *)hash)[3] = REG(AES_HASH_DIGEST_D); + ((uint32_t *)hash)[4] = REG(AES_HASH_DIGEST_E); + ((uint32_t *)hash)[5] = REG(AES_HASH_DIGEST_F); + ((uint32_t *)hash)[6] = REG(AES_HASH_DIGEST_G); + ((uint32_t *)hash)[7] = REG(AES_HASH_DIGEST_H); + + /* Acknowledge reading of the digest */ + REG(AES_HASH_IO_BUF_CTRL) = AES_HASH_IO_BUF_CTRL_OUTPUT_FULL; + + /* Clear the interrupt */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV; + /* Disable master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + /* Clear mode */ + REG(AES_AES_CTRL) = 0x00000000; + + return CRYPTO_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +sha256_init(sha256_state_t *state) +{ + if(state == NULL) { + return CRYPTO_NULL_ERROR; + } + + state->curlen = 0; + state->length = 0; + state->new_digest = true; + state->final_digest = false; + return CRYPTO_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +sha256_process(sha256_state_t *state, const void *data, uint32_t len) +{ + uint32_t n; + uint8_t ret; + + if(state == NULL || data == NULL) { + return CRYPTO_NULL_ERROR; + } + + if(state->curlen > sizeof(state->buf)) { + return CRYPTO_INVALID_PARAM; + } + + if(REG(AES_CTRL_ALG_SEL) != 0x00000000) { + return CRYPTO_RESOURCE_IN_USE; + } + + if(len > 0 && state->new_digest) { + if(state->curlen == 0 && len > BLOCK_SIZE) { + rom_util_memcpy(state->buf, data, BLOCK_SIZE); + ret = new_hash(state, state->buf, state->state); + if(ret != CRYPTO_SUCCESS) { + return ret; + } + state->new_digest = false; + state->length += BLOCK_SIZE << 3; + data += BLOCK_SIZE; + len -= BLOCK_SIZE; + } else { + n = MIN(len, BLOCK_SIZE - state->curlen); + rom_util_memcpy(&state->buf[state->curlen], data, n); + state->curlen += n; + data += n; + len -= n; + if(state->curlen == BLOCK_SIZE && len > 0) { + ret = new_hash(state, state->buf, state->state); + if(ret != CRYPTO_SUCCESS) { + return ret; + } + state->new_digest = false; + state->length += BLOCK_SIZE << 3; + state->curlen = 0; + } + } + } + + while(len > 0 && !state->new_digest) { + if(state->curlen == 0 && len > BLOCK_SIZE) { + rom_util_memcpy(state->buf, data, BLOCK_SIZE); + ret = resume_hash(state, state->buf, state->state); + if(ret != CRYPTO_SUCCESS) { + return ret; + } + state->length += BLOCK_SIZE << 3; + data += BLOCK_SIZE; + len -= BLOCK_SIZE; + } else { + n = MIN(len, BLOCK_SIZE - state->curlen); + rom_util_memcpy(&state->buf[state->curlen], data, n); + state->curlen += n; + data += n; + len -= n; + if(state->curlen == BLOCK_SIZE && len > 0) { + ret = resume_hash(state, state->buf, state->state); + if(ret != CRYPTO_SUCCESS) { + return ret; + } + state->length += BLOCK_SIZE << 3; + state->curlen = 0; + } + } + } + + return CRYPTO_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +sha256_done(sha256_state_t *state, void *hash) +{ + uint8_t ret; + + if(state == NULL || hash == NULL) { + return CRYPTO_NULL_ERROR; + } + + if(state->curlen > sizeof(state->buf)) { + return CRYPTO_INVALID_PARAM; + } + + if(REG(AES_CTRL_ALG_SEL) != 0x00000000) { + return CRYPTO_RESOURCE_IN_USE; + } + + /* Increase the length of the message */ + state->length += state->curlen << 3; + state->final_digest = true; + if(state->new_digest) { + ret = new_hash(state, state->buf, hash); + if(ret != CRYPTO_SUCCESS) { + return ret; + } + } else { + ret = resume_hash(state, state->buf, hash); + if(ret != CRYPTO_SUCCESS) { + return ret; + } + } + state->new_digest = false; + state->final_digest = false; + + return CRYPTO_SUCCESS; +} + +/** @} */ diff --git a/cpu/cc2538/dev/sha256.h b/cpu/cc2538/dev/sha256.h new file mode 100644 index 000000000..b2e799bd8 --- /dev/null +++ b/cpu/cc2538/dev/sha256.h @@ -0,0 +1,103 @@ +/* + * Original file: + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2013, ADVANSEE - http://www.advansee.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-crypto + * @{ + * + * \defgroup cc2538-sha526 cc2538 SHA-256 + * + * Driver for the cc2538 SHA-256 mode of the security core + * @{ + * + * \file + * Header file for the cc2538 SHA-256 driver + */ +#ifndef SHA256_H_ +#define SHA256_H_ + +#include "contiki.h" +#include "dev/crypto.h" + +#include +/*---------------------------------------------------------------------------*/ +/** \name SHA-256 structures + * @{ + */ +typedef struct { + uint64_t length; + uint32_t state[8]; + uint32_t curlen; + uint8_t buf[64]; + uint8_t new_digest; + uint8_t final_digest; +} sha256_state_t; +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name SHA-256 functions + * @{ + */ + +/** \brief Initializes the hash state + * \param state Pointer to hash state to initialize + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code + */ +uint8_t sha256_init(sha256_state_t *state); + +/** \brief Processes a block of memory through the hash + * \param state Pointer to hash state + * \param data Pointer to the data to hash + * \param len Length of the data to hash in bytes (octets) + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code + * \note This function must be called only after \c sha256_init(). + */ +uint8_t sha256_process(sha256_state_t *state, const void *data, uint32_t len); + +/** \brief Terminates hash session to get the digest + * \param state Pointer to hash state + * \param hash Pointer to hash + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code + * \note This function must be called only after \c sha256_process(). + */ +uint8_t sha256_done(sha256_state_t *state, void *hash); + +/** @} */ + +#endif /* SHA256_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/spi.c b/cpu/cc2538/dev/spi.c index 8d7dca49b..48048a6a3 100644 --- a/cpu/cc2538/dev/spi.c +++ b/cpu/cc2538/dev/spi.c @@ -1,5 +1,9 @@ /* * Copyright (c) 2013, University of Michigan. + * + * Copyright (c) 2015, Weptech elektronik GmbH + * Author: Ulf Knoblich, ulf.knoblich@weptech.de + * * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,7 +35,7 @@ * @{ * * \file - * Implementation of the cc2538 SPI peripheral + * Implementation of the cc2538 SPI peripheral driver */ #include "contiki.h" #include "reg.h" @@ -41,95 +45,281 @@ #include "dev/spi.h" #include "dev/ssi.h" #include "dev/gpio.h" - -#define SPI_CLK_PORT_BASE GPIO_PORT_TO_BASE(SPI_CLK_PORT) -#define SPI_CLK_PIN_MASK GPIO_PIN_MASK(SPI_CLK_PIN) -#define SPI_MOSI_PORT_BASE GPIO_PORT_TO_BASE(SPI_MOSI_PORT) -#define SPI_MOSI_PIN_MASK GPIO_PIN_MASK(SPI_MOSI_PIN) -#define SPI_MISO_PORT_BASE GPIO_PORT_TO_BASE(SPI_MISO_PORT) -#define SPI_MISO_PIN_MASK GPIO_PIN_MASK(SPI_MISO_PIN) -#define SPI_SEL_PORT_BASE GPIO_PORT_TO_BASE(SPI_SEL_PORT) -#define SPI_SEL_PIN_MASK GPIO_PIN_MASK(SPI_SEL_PIN) - -/* Default: Motorola mode 3 with 8-bit data words */ -#ifndef SPI_CONF_PHASE -#define SPI_CONF_PHASE SSI_CR0_SPH +/*---------------------------------------------------------------------------*/ +/* Check port / pin settings for SPI0 and provide default values for spi_cfg */ +#ifndef SPI0_CLK_PORT +#define SPI0_CLK_PORT (-1) #endif -#ifndef SPI_CONF_POLARITY -#define SPI_CONF_POLARITY SSI_CR0_SPO +#ifndef SPI0_CLK_PIN +#define SPI0_CLK_PIN (-1) #endif -#ifndef SPI_CONF_DATA_SIZE -#define SPI_CONF_DATA_SIZE 8 +#if SPI0_CLK_PORT >= 0 && SPI0_CLK_PIN < 0 || \ + SPI0_CLK_PORT < 0 && SPI0_CLK_PIN >= 0 +#error Both SPI0_CLK_PORT and SPI0_CLK_PIN must be valid or invalid #endif -#if SPI_CONF_DATA_SIZE < 4 || SPI_CONF_DATA_SIZE > 16 -#error SPI_CONF_DATA_SIZE must be set between 4 and 16 inclusive. +#ifndef SPI0_TX_PORT +#define SPI0_TX_PORT (-1) +#endif +#ifndef SPI0_TX_PIN +#define SPI0_TX_PIN (-1) +#endif +#if SPI0_TX_PORT >= 0 && SPI0_TX_PIN < 0 || \ + SPI0_TX_PORT < 0 && SPI0_TX_PIN >= 0 +#error Both SPI0_TX_PORT and SPI0_TX_PIN must be valid or invalid #endif -/** - * \brief Initialize the SPI bus. - * - * This SPI init() function uses the following #defines to set the pins: - * SPI_CLK_PORT SPI_CLK_PIN - * SPI_MOSI_PORT SPI_MOSI_PIN - * SPI_MISO_PORT SPI_MISO_PIN - * SPI_SEL_PORT SPI_SEL_PIN - * - * This sets the mode to Motorola SPI with the following format options: - * SPI_CONF_PHASE: 0 or SSI_CR0_SPH - * SPI_CONF_POLARITY: 0 or SSI_CR0_SPO - * SPI_CONF_DATA_SIZE: 4 to 16 bits - */ +#ifndef SPI0_RX_PORT +#define SPI0_RX_PORT (-1) +#endif +#ifndef SPI0_RX_PIN +#define SPI0_RX_PIN (-1) +#endif +#if SPI0_RX_PORT >= 0 && SPI0_RX_PIN < 0 || \ + SPI0_RX_PORT < 0 && SPI0_RX_PIN >= 0 +#error Both SPI0_RX_PORT and SPI0_RX_PIN must be valid or invalid +#endif + +/* Here we check that either all or none of the ports are defined. As + we did already check that both ports + pins are either defined or + not for every pin, this means that we can check for an incomplete + configuration by only looking at the port defines */ +/* If some SPI0 pads are valid */ +#if SPI0_CLK_PORT >= 0 || SPI0_TX_PORT >= 0 || SPI0_RX_PORT >= 0 +/* but not all */ +#if SPI0_CLK_PORT < 0 || SPI0_TX_PORT < 0 || SPI0_RX_PORT < 0 +#error Some SPI0 pad definitions are invalid +#endif +#define SPI0_PADS_VALID +#endif +/*---------------------------------------------------------------------------*/ +/* Check port / pin settings for SPI1 and provide default values for spi_cfg */ +#ifndef SPI1_CLK_PORT +#define SPI1_CLK_PORT (-1) +#endif +#ifndef SPI1_CLK_PIN +#define SPI1_CLK_PIN (-1) +#endif +#if SPI1_CLK_PORT >= 0 && SPI1_CLK_PIN < 0 || \ + SPI1_CLK_PORT < 0 && SPI1_CLK_PIN >= 0 +#error Both SPI1_CLK_PORT and SPI1_CLK_PIN must be valid or invalid +#endif + +#ifndef SPI1_TX_PORT +#define SPI1_TX_PORT (-1) +#endif +#ifndef SPI1_TX_PIN +#define SPI1_TX_PIN (-1) +#endif +#if SPI1_TX_PORT >= 0 && SPI1_TX_PIN < 0 || \ + SPI1_TX_PORT < 0 && SPI1_TX_PIN >= 0 +#error Both SPI1_TX_PORT and SPI1_TX_PIN must be valid or invalid +#endif + +#ifndef SPI1_RX_PORT +#define SPI1_RX_PORT (-1) +#endif +#ifndef SPI1_RX_PIN +#define SPI1_RX_PIN (-1) +#endif +#if SPI1_RX_PORT >= 0 && SPI1_RX_PIN < 0 || \ + SPI1_RX_PORT < 0 && SPI1_RX_PIN >= 0 +#error Both SPI1_RX_PORT and SPI1_RX_PIN must be valid or invalid +#endif + +/* If some SPI1 pads are valid */ +#if SPI1_CLK_PORT >= 0 || SPI1_TX_PORT >= 0 || SPI1_RX_PORT >= 0 +/* but not all */ +#if SPI1_CLK_PORT < 0 || SPI1_TX_PORT < 0 || SPI1_RX_PORT < 0 +#error Some SPI1 pad definitions are invalid +#endif +#define SPI1_PADS_VALID +#endif + +#ifdef SPI_DEFAULT_INSTANCE +#if SPI_DEFAULT_INSTANCE == 0 +#ifndef SPI0_PADS_VALID +#error SPI_DEFAULT_INSTANCE is set to SPI0, but its pads are not valid +#endif +#elif SPI_DEFAULT_INSTANCE == 1 +#ifndef SPI1_PADS_VALID +#error SPI_DEFAULT_INSTANCE is set to SPI1, but its pads are not valid +#endif +#endif +#endif + +#if (SPI0_CPRS_CPSDVSR & 1) == 1 || SPI0_CPRS_CPSDVSR < 2 || SPI0_CPRS_CPSDVSR > 254 +#error SPI0_CPRS_CPSDVSR must be an even number between 2 and 254 +#endif + +#if (SPI1_CPRS_CPSDVSR & 1) == 1 || SPI1_CPRS_CPSDVSR < 2 || SPI1_CPRS_CPSDVSR > 254 +#error SPI1_CPRS_CPSDVSR must be an even number between 2 and 254 +#endif + +/*---------------------------------------------------------------------------*/ +typedef struct { + int8_t port; + int8_t pin; +} spi_pad_t; +typedef struct { + uint32_t base; + uint32_t ioc_ssirxd_ssi; + uint32_t ioc_pxx_sel_ssi_clkout; + uint32_t ioc_pxx_sel_ssi_txd; + uint8_t ssi_cprs_cpsdvsr; + spi_pad_t clk; + spi_pad_t tx; + spi_pad_t rx; +} spi_regs_t; +/*---------------------------------------------------------------------------*/ +static const spi_regs_t spi_regs[SSI_INSTANCE_COUNT] = { + { + .base = SSI0_BASE, + .ioc_ssirxd_ssi = IOC_SSIRXD_SSI0, + .ioc_pxx_sel_ssi_clkout = IOC_PXX_SEL_SSI0_CLKOUT, + .ioc_pxx_sel_ssi_txd = IOC_PXX_SEL_SSI0_TXD, + .ssi_cprs_cpsdvsr = SPI0_CPRS_CPSDVSR, + .clk = { SPI0_CLK_PORT, SPI0_CLK_PIN }, + .tx = { SPI0_TX_PORT, SPI0_TX_PIN }, + .rx = { SPI0_RX_PORT, SPI0_RX_PIN } + }, { + .base = SSI1_BASE, + .ioc_ssirxd_ssi = IOC_SSIRXD_SSI1, + .ioc_pxx_sel_ssi_clkout = IOC_PXX_SEL_SSI1_CLKOUT, + .ioc_pxx_sel_ssi_txd = IOC_PXX_SEL_SSI1_TXD, + .ssi_cprs_cpsdvsr = SPI1_CPRS_CPSDVSR, + .clk = { SPI1_CLK_PORT, SPI1_CLK_PIN }, + .tx = { SPI1_TX_PORT, SPI1_TX_PIN }, + .rx = { SPI1_RX_PORT, SPI1_RX_PIN } + } +}; +/*---------------------------------------------------------------------------*/ +/* Deprecated function call provided for compatibility reasons */ +#ifdef SPI_DEFAULT_INSTANCE void spi_init(void) { - spi_enable(); + spix_init(SPI_DEFAULT_INSTANCE); +} +#endif /* #ifdef SPI_DEFAULT_INSTANCE */ +/*---------------------------------------------------------------------------*/ +void +spix_init(uint8_t spi) +{ + const spi_regs_t *regs; + + if(spi >= SSI_INSTANCE_COUNT) { + return; + } + + regs = &spi_regs[spi]; + + if(regs->clk.port < 0) { + /* Port / pin configuration invalid. We checked for completeness + above. If clk.port is < 0, this means that all other defines are + < 0 as well */ + return; + } + + spix_enable(spi); /* Start by disabling the peripheral before configuring it */ - REG(SSI0_BASE + SSI_CR1) = 0; + REG(regs->base + SSI_CR1) = 0; - /* Set the IO clock as the SSI clock */ - REG(SSI0_BASE + SSI_CC) = 1; + /* Set the system clock as the SSI clock */ + REG(regs->base + SSI_CC) = 0; /* Set the mux correctly to connect the SSI pins to the correct GPIO pins */ - ioc_set_sel(SPI_CLK_PORT, SPI_CLK_PIN, IOC_PXX_SEL_SSI0_CLKOUT); - ioc_set_sel(SPI_MOSI_PORT, SPI_MOSI_PIN, IOC_PXX_SEL_SSI0_TXD); - REG(IOC_SSIRXD_SSI0) = (SPI_MISO_PORT * 8) + SPI_MISO_PIN; - ioc_set_sel(SPI_SEL_PORT, SPI_SEL_PIN, IOC_PXX_SEL_SSI0_FSSOUT); + ioc_set_sel(regs->clk.port, + regs->clk.pin, + regs->ioc_pxx_sel_ssi_clkout); + ioc_set_sel(regs->tx.port, + regs->tx.pin, + regs->ioc_pxx_sel_ssi_txd); + REG(regs->ioc_ssirxd_ssi) = (regs->rx.port * 8) + regs->rx.pin; /* Put all the SSI gpios into peripheral mode */ - GPIO_PERIPHERAL_CONTROL(SPI_CLK_PORT_BASE, SPI_CLK_PIN_MASK); - GPIO_PERIPHERAL_CONTROL(SPI_MOSI_PORT_BASE, SPI_MOSI_PIN_MASK); - GPIO_PERIPHERAL_CONTROL(SPI_MISO_PORT_BASE, SPI_MISO_PIN_MASK); - GPIO_PERIPHERAL_CONTROL(SPI_SEL_PORT_BASE, SPI_SEL_PIN_MASK); + GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(regs->clk.port), + GPIO_PIN_MASK(regs->clk.pin)); + GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(regs->tx.port), + GPIO_PIN_MASK(regs->tx.pin)); + GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(regs->rx.port), + GPIO_PIN_MASK(regs->rx.pin)); /* Disable any pull ups or the like */ - ioc_set_over(SPI_CLK_PORT, SPI_CLK_PIN, IOC_OVERRIDE_DIS); - ioc_set_over(SPI_MOSI_PORT, SPI_MOSI_PIN, IOC_OVERRIDE_DIS); - ioc_set_over(SPI_MISO_PORT, SPI_MISO_PIN, IOC_OVERRIDE_DIS); - ioc_set_over(SPI_SEL_PORT, SPI_SEL_PIN, IOC_OVERRIDE_DIS); + ioc_set_over(regs->clk.port, regs->clk.pin, IOC_OVERRIDE_DIS); + ioc_set_over(regs->tx.port, regs->tx.pin, IOC_OVERRIDE_DIS); + ioc_set_over(regs->rx.port, regs->rx.pin, IOC_OVERRIDE_DIS); /* Configure the clock */ - REG(SSI0_BASE + SSI_CPSR) = 2; + REG(regs->base + SSI_CPSR) = regs->ssi_cprs_cpsdvsr; - /* Put the ssi in Motorola SPI mode using the provided format options */ - REG(SSI0_BASE + SSI_CR0) = SPI_CONF_PHASE | SPI_CONF_POLARITY | (SPI_CONF_DATA_SIZE - 1); + /* + * Configure the default SPI options. + * mode: Motorola frame format + * clock: High when idle + * data: Valid on rising edges of the clock + * bits: 8 byte data + */ + REG(regs->base + SSI_CR0) = SSI_CR0_SPH | SSI_CR0_SPO | (0x07); /* Enable the SSI */ - REG(SSI0_BASE + SSI_CR1) |= SSI_CR1_SSE; + REG(regs->base + SSI_CR1) |= SSI_CR1_SSE; } /*---------------------------------------------------------------------------*/ void -spi_enable(void) +spix_enable(uint8_t spi) { - /* Enable the clock for the SSI peripheral */ - REG(SYS_CTRL_RCGCSSI) |= 1; + if(spi >= SSI_INSTANCE_COUNT) { + return; + } + REG(SYS_CTRL_RCGCSSI) |= (1 << spi); } /*---------------------------------------------------------------------------*/ void -spi_disable(void) +spix_disable(uint8_t spi) { - /* Gate the clock for the SSI peripheral */ - REG(SYS_CTRL_RCGCSSI) &= ~1; + if(spi >= SSI_INSTANCE_COUNT) { + return; + } + REG(SYS_CTRL_RCGCSSI) &= ~(1 << spi); +} +/*---------------------------------------------------------------------------*/ +void +spix_set_mode(uint8_t spi, + uint32_t frame_format, + uint32_t clock_polarity, + uint32_t clock_phase, + uint32_t data_size) +{ + const spi_regs_t *regs; + + if(spi >= SSI_INSTANCE_COUNT) { + return; + } + + regs = &spi_regs[spi]; + + /* Disable the SSI peripheral to configure it */ + REG(regs->base + SSI_CR1) = 0; + + /* Configure the SSI options */ + REG(regs->base + SSI_CR0) = clock_phase | + clock_polarity | + frame_format | + (data_size - 1); + + /* Re-enable the SSI */ + REG(regs->base + SSI_CR1) |= SSI_CR1_SSE; +} +/*---------------------------------------------------------------------------*/ +void +spix_cs_init(uint8_t port, uint8_t pin) +{ + GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(port), + GPIO_PIN_MASK(pin)); + ioc_set_over(port, pin, IOC_OVERRIDE_DIS); + GPIO_SET_OUTPUT(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + GPIO_SET_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); } /** @} */ diff --git a/cpu/cc2538/dev/ssi.h b/cpu/cc2538/dev/ssi.h index ca3a1fe21..ca06969ee 100644 --- a/cpu/cc2538/dev/ssi.h +++ b/cpu/cc2538/dev/ssi.h @@ -45,6 +45,12 @@ #ifndef SSI_H_ #define SSI_H_ +/*---------------------------------------------------------------------------*/ +/** \name Number of SSI instances supported by this CPU. + * @{ + */ +#define SSI_INSTANCE_COUNT 2 +/** @} */ /*---------------------------------------------------------------------------*/ /** \name Base register memory locations. * @{ @@ -74,98 +80,106 @@ */ #define SSI_CR0_SCR_M 0x0000FF00 /**< Serial clock rate mask */ #define SSI_CR0_SCR_S 8 /**< Serial clock rate shift */ -#define SSI_CR0_SPH 0x00000080 /**< Serial clock phase (H) */ #define SSI_CR0_SPH_M 0x00000080 /**< Serial clock phase (H) mask */ #define SSI_CR0_SPH_S 7 /**< Serial clock phase (H) shift */ -#define SSI_CR0_SPO 0x00000040 /**< Serial clock phase (O) */ #define SSI_CR0_SPO_M 0x00000040 /**< Serial clock phase (O) mask */ #define SSI_CR0_SPO_S 6 /**< Serial clock phase (O) shift */ #define SSI_CR0_FRF_M 0x00000030 /**< Frame format select mask */ #define SSI_CR0_FRF_S 4 /**< Frame format select shift */ #define SSI_CR0_DSS_M 0x0000000F /**< Data size select mask */ #define SSI_CR0_DSS_S 0 /**< Data size select shift */ -#define SSI_CR1_SOD 0x00000008 /**< Slave mode output disable */ #define SSI_CR1_SOD_M 0x00000008 /**< Slave mode output disable mask */ #define SSI_CR1_SOD_S 3 /**< Slave mode output disable shift */ -#define SSI_CR1_MS 0x00000004 /**< Master and slave select */ #define SSI_CR1_MS_M 0x00000004 /**< Master and slave select mask */ #define SSI_CR1_MS_S 2 /**< Master and slave select shift */ -#define SSI_CR1_SSE 0x00000002 /**< Synchronous serial port enable */ #define SSI_CR1_SSE_M 0x00000002 /**< Synchronous serial port enable mask */ #define SSI_CR1_SSE_S 1 /**< Synchronous serial port enable shift */ -#define SSI_CR1_LBM 0x00000001 /**< Loop-back mode */ #define SSI_CR1_LBM_M 0x00000001 /**< Loop-back mode mask */ #define SSI_CR1_LBM_S 0 /**< Loop-back mode shift */ #define SSI_DR_DATA_M 0x0000FFFF /**< FIFO data mask */ #define SSI_DR_DATA_S 0 /**< FIFO data shift */ -#define SSI_SR_BSY 0x00000010 /**< Busy bit */ #define SSI_SR_BSY_M 0x00000010 /**< Busy bit mask */ #define SSI_SR_BSY_S 4 /**< Busy bit shift */ -#define SSI_SR_RFF 0x00000008 /**< Receive FIFO full */ #define SSI_SR_RFF_M 0x00000008 /**< Receive FIFO full mask */ #define SSI_SR_RFF_S 3 /**< Receive FIFO full shift */ -#define SSI_SR_RNE 0x00000004 /**< Receive FIFO not empty */ #define SSI_SR_RNE_M 0x00000004 /**< Receive FIFO not empty mask */ #define SSI_SR_RNE_S 2 /**< Receive FIFO not empty shift */ -#define SSI_SR_TNF 0x00000002 /**< Transmit FIFO not full */ #define SSI_SR_TNF_M 0x00000002 /**< Transmit FIFO not full mask */ #define SSI_SR_TNF_S 1 /**< Transmit FIFO not full shift */ -#define SSI_SR_TFE 0x00000001 /**< Transmit FIFO empty */ #define SSI_SR_TFE_M 0x00000001 /**< Transmit FIFO empty mask */ #define SSI_SR_TFE_S 0 /**< Transmit FIFO empty shift */ #define SSI_CPSR_CPSDVSR_M 0x000000FF /**< Clock prescale divisor mask */ #define SSI_CPSR_CPSDVSR_S 0 /**< Clock prescale divisor shift */ -#define SSI_IM_TXIM 0x00000008 /**< Transmit FIFO interrupt mask */ #define SSI_IM_TXIM_M 0x00000008 /**< Transmit FIFO interrupt mask mask */ #define SSI_IM_TXIM_S 3 /**< Transmit FIFO interrupt mask shift */ -#define SSI_IM_RXIM 0x00000004 /**< Receive FIFO interrupt mask */ #define SSI_IM_RXIM_M 0x00000004 /**< Receive FIFO interrupt mask mask */ #define SSI_IM_RXIM_S 2 /**< Receive FIFO interrupt mask shift */ -#define SSI_IM_RTIM 0x00000002 /**< Receive time-out interrupt mask */ #define SSI_IM_RTIM_M 0x00000002 /**< Receive time-out interrupt mask mask */ #define SSI_IM_RTIM_S 1 /**< Receive time-out interrupt mask shift */ -#define SSI_IM_RORIM 0x00000001 /**< Receive overrun interrupt mask */ #define SSI_IM_RORIM_M 0x00000001 /**< Receive overrun interrupt mask mask */ #define SSI_IM_RORIM_S 0 /**< Receive overrun interrupt mask shift */ -#define SSI_RIS_TXRIS 0x00000008 /**< SSITXINTR raw state */ #define SSI_RIS_TXRIS_M 0x00000008 /**< SSITXINTR raw state mask */ #define SSI_RIS_TXRIS_S 3 /**< SSITXINTR raw state shift */ -#define SSI_RIS_RXRIS 0x00000004 /**< SSIRXINTR raw state */ #define SSI_RIS_RXRIS_M 0x00000004 /**< SSIRXINTR raw state mask */ #define SSI_RIS_RXRIS_S 2 /**< SSIRXINTR raw state shift */ -#define SSI_RIS_RTRIS 0x00000002 /**< SSIRTINTR raw state */ #define SSI_RIS_RTRIS_M 0x00000002 /**< SSIRTINTR raw state mask */ #define SSI_RIS_RTRIS_S 1 /**< SSIRTINTR raw state shift */ -#define SSI_RIS_RORRIS 0x00000001 /**< SSIRORINTR raw state */ #define SSI_RIS_RORRIS_M 0x00000001 /**< SSIRORINTR raw state mask */ #define SSI_RIS_RORRIS_S 0 /**< SSIRORINTR raw state shift */ -#define SSI_MIS_TXMIS 0x00000008 /**< SSITXINTR masked state */ #define SSI_MIS_TXMIS_M 0x00000008 /**< SSITXINTR masked state mask */ #define SSI_MIS_TXMIS_S 3 /**< SSITXINTR masked state shift */ -#define SSI_MIS_RXMIS 0x00000004 /**< SSIRXINTR masked state */ #define SSI_MIS_RXMIS_M 0x00000004 /**< SSIRXINTR masked state mask */ #define SSI_MIS_RXMIS_S 2 /**< SSIRXINTR masked state shift */ -#define SSI_MIS_RTMIS 0x00000002 /**< SSIRTINTR masked state */ #define SSI_MIS_RTMIS_M 0x00000002 /**< SSIRTINTR masked state mask */ #define SSI_MIS_RTMIS_S 1 /**< SSIRTINTR masked state shift */ -#define SSI_MIS_RORMIS 0x00000001 /**< SSIRORINTR masked state */ #define SSI_MIS_RORMIS_M 0x00000001 /**< SSIRORINTR masked state mask */ #define SSI_MIS_RORMIS_S 0 /**< SSIRORINTR masked state shift */ -#define SSI_ICR_RTIC 0x00000002 /**< Receive time-out interrupt clear */ #define SSI_ICR_RTIC_M 0x00000002 /**< Receive time-out interrupt clear mask */ #define SSI_ICR_RTIC_S 1 /**< Receive time-out interrupt clear shift */ -#define SSI_ICR_RORIC 0x00000001 /**< Receive overrun interrupt clear */ #define SSI_ICR_RORIC_M 0x00000001 /**< Receive overrun interrupt clear mask */ #define SSI_ICR_RORIC_S 0 /**< Receive overrun interrupt clear shift */ -#define SSI_DMACTL_TXDMAE 0x00000002 /**< Transmit DMA enable */ #define SSI_DMACTL_TXDMAE_M 0x00000002 /**< Transmit DMA enable mask */ #define SSI_DMACTL_TXDMAE_S 1 /**< Transmit DMA enable shift */ -#define SSI_DMACTL_RXDMAE 0x00000001 /**< Receive DMA enable */ #define SSI_DMACTL_RXDMAE_M 0x00000001 /**< Receive DMA enable mask */ #define SSI_DMACTL_RXDMAE_S 0 /**< Receive DMA enable shift */ #define SSI_CC_CS_M 0x00000007 /**< Baud and system clock source mask */ #define SSI_CC_CS_S 0 /**< Baud and system clock source shift */ /** @} */ +/*---------------------------------------------------------------------------*/ +/** \name SSI Register Values + * @{ + */ +#define SSI_CR0_SPH 0x00000080 /**< Serial clock phase (H) */ +#define SSI_CR0_SPO 0x00000040 /**< Serial clock phase (O) */ +#define SSI_CR0_FRF_MOTOROLA 0x00000000 /**< Motorola frame format */ +#define SSI_CR0_FRF_TI 0x00000010 /**< Texas Instruments frame format */ +#define SSI_CR0_FRF_MICROWIRE 0x00000020 /**< National Microwire frame format */ +#define SSI_CR1_SOD 0x00000008 /**< Slave mode output disable */ +#define SSI_CR1_MS 0x00000004 /**< Master and slave select */ +#define SSI_CR1_SSE 0x00000002 /**< Synchronous serial port enable */ +#define SSI_CR1_LBM 0x00000001 /**< Loop-back mode */ +#define SSI_SR_BSY 0x00000010 /**< Busy bit */ +#define SSI_SR_RFF 0x00000008 /**< Receive FIFO full */ +#define SSI_SR_RNE 0x00000004 /**< Receive FIFO not empty */ +#define SSI_SR_TNF 0x00000002 /**< Transmit FIFO not full */ +#define SSI_SR_TFE 0x00000001 /**< Transmit FIFO empty */ +#define SSI_IM_TXIM 0x00000008 /**< Transmit FIFO interrupt mask */ +#define SSI_IM_RXIM 0x00000004 /**< Receive FIFO interrupt mask */ +#define SSI_IM_RTIM 0x00000002 /**< Receive time-out interrupt mask */ +#define SSI_IM_RORIM 0x00000001 /**< Receive overrun interrupt mask */ +#define SSI_RIS_TXRIS 0x00000008 /**< SSITXINTR raw state */ +#define SSI_RIS_RXRIS 0x00000004 /**< SSIRXINTR raw state */ +#define SSI_RIS_RTRIS 0x00000002 /**< SSIRTINTR raw state */ +#define SSI_RIS_RORRIS 0x00000001 /**< SSIRORINTR raw state */ +#define SSI_MIS_TXMIS 0x00000008 /**< SSITXINTR masked state */ +#define SSI_MIS_RXMIS 0x00000004 /**< SSIRXINTR masked state */ +#define SSI_MIS_RTMIS 0x00000002 /**< SSIRTINTR masked state */ +#define SSI_MIS_RORMIS 0x00000001 /**< SSIRORINTR masked state */ +#define SSI_ICR_RTIC 0x00000002 /**< Receive time-out interrupt clear */ +#define SSI_ICR_RORIC 0x00000001 /**< Receive overrun interrupt clear */ +#define SSI_DMACTL_TXDMAE 0x00000002 /**< Transmit DMA enable */ +#define SSI_DMACTL_RXDMAE 0x00000001 /**< Receive DMA enable */ +/** @} */ #endif /** diff --git a/cpu/cc2538/dev/sys-ctrl.c b/cpu/cc2538/dev/sys-ctrl.c index 87eabfa44..92592b942 100644 --- a/cpu/cc2538/dev/sys-ctrl.c +++ b/cpu/cc2538/dev/sys-ctrl.c @@ -50,6 +50,26 @@ #define SYS_CTRL_OSCS SYS_CTRL_CLOCK_CTRL_OSC32K #endif /*---------------------------------------------------------------------------*/ +int +sys_ctrl_get_reset_cause(void) +{ + return (REG(SYS_CTRL_CLOCK_STA) & SYS_CTRL_CLOCK_STA_RST) >> + SYS_CTRL_CLOCK_STA_RST_S; +} +/*---------------------------------------------------------------------------*/ +const char * +sys_ctrl_get_reset_cause_str(void) +{ + static const char *reset_cause[] = { + "POR", + "External reset", + "WDT", + "CLD or software reset" + }; + + return reset_cause[sys_ctrl_get_reset_cause()]; +} +/*---------------------------------------------------------------------------*/ void sys_ctrl_init() { @@ -70,17 +90,18 @@ sys_ctrl_init() * 32KHz source: RC or crystal, according to SYS_CTRL_OSC32K_USE_XTAL * System Clock: 32 MHz * Power Down Unused - * I/O Div: 16MHz - * Sys Div: 16MHz + * I/O Div: according to SYS_CTRL_IO_DIV + * Sys Div: according to SYS_CTRL_SYS_DIV * Rest: Don't care */ val = SYS_CTRL_OSCS | SYS_CTRL_CLOCK_CTRL_OSC_PD - | SYS_CTRL_CLOCK_CTRL_IO_DIV_16MHZ | SYS_CTRL_CLOCK_CTRL_SYS_DIV_16MHZ; + | SYS_CTRL_IO_DIV | SYS_CTRL_SYS_DIV; REG(SYS_CTRL_CLOCK_CTRL) = val; - while((REG(SYS_CTRL_CLOCK_STA) & (SYS_CTRL_CLOCK_STA_OSC32K | - SYS_CTRL_CLOCK_STA_OSC)) != SYS_CTRL_OSCS); + while((REG(SYS_CTRL_CLOCK_STA) + & (SYS_CTRL_CLOCK_STA_OSC32K | SYS_CTRL_CLOCK_STA_OSC)) + != SYS_CTRL_OSCS); #if SYS_CTRL_OSC32K_USE_XTAL /* Wait for the 32-kHz crystal oscillator to stabilize */ @@ -94,7 +115,20 @@ sys_ctrl_reset() { REG(SYS_CTRL_PWRDBG) = SYS_CTRL_PWRDBG_FORCE_WARM_RESET; } - +/*---------------------------------------------------------------------------*/ +uint32_t +sys_ctrl_get_sys_clock(void) +{ + return SYS_CTRL_32MHZ >> (REG(SYS_CTRL_CLOCK_STA) & + SYS_CTRL_CLOCK_STA_SYS_DIV); +} +/*---------------------------------------------------------------------------*/ +uint32_t +sys_ctrl_get_io_clock(void) +{ + return SYS_CTRL_32MHZ >> ((REG(SYS_CTRL_CLOCK_STA) & + SYS_CTRL_CLOCK_STA_IO_DIV) >> 8); +} /** * @} * @} diff --git a/cpu/cc2538/dev/sys-ctrl.h b/cpu/cc2538/dev/sys-ctrl.h index f63fd5a50..22dece434 100644 --- a/cpu/cc2538/dev/sys-ctrl.h +++ b/cpu/cc2538/dev/sys-ctrl.h @@ -32,7 +32,7 @@ * \addtogroup cc2538 * @{ * - * \defgroup cc2538-sys-ctrl cc2538 System Control + * \defgroup cc2538-sys-ctrl cc2538 System Control (SysCtrl) * * Driver for the cc2538 System Control Module * @{ @@ -42,6 +42,8 @@ */ #ifndef SYS_CTRL_H_ #define SYS_CTRL_H_ + +#include /*---------------------------------------------------------------------------*/ /** \name SysCtrl Constants, used by the SYS_DIV and IO_DIV bits of the * SYS_CTRL_CLOCK_CTRL register @@ -113,6 +115,11 @@ #define SYS_CTRL_CLOCK_STA_OSC32K_CALDIS 0x02000000 #define SYS_CTRL_CLOCK_STA_OSC32K 0x01000000 #define SYS_CTRL_CLOCK_STA_RST 0x00C00000 +#define SYS_CTRL_CLOCK_STA_RST_S 22 +#define SYS_CTRL_CLOCK_STA_RST_POR 0 +#define SYS_CTRL_CLOCK_STA_RST_EXT 1 +#define SYS_CTRL_CLOCK_STA_RST_WDT 2 +#define SYS_CTRL_CLOCK_STA_RST_CLD_SW 3 #define SYS_CTRL_CLOCK_STA_SOURCE_CHANGE 0x00100000 #define SYS_CTRL_CLOCK_STA_XOSC_STB 0x00080000 #define SYS_CTRL_CLOCK_STA_HSOSC_STB 0x00040000 @@ -159,6 +166,34 @@ #define SYS_CTRL_SRGPT_GPT0 0x00000001 /**< GPT0 is reset */ /** @} */ /*---------------------------------------------------------------------------*/ +/** \name SYS_CTRL_RCGCSEC register bit masks + * @{ + */ +#define SYS_CTRL_RCGCSEC_AES 0x00000002 /**< AES clock enable, CPU running */ +#define SYS_CTRL_RCGCSEC_PKA 0x00000001 /**< PKA clock enable, CPU running */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name SYS_CTRL_SCGCSEC register bit masks + * @{ + */ +#define SYS_CTRL_SCGCSEC_AES 0x00000002 /**< AES clock enable, CPU IDLE */ +#define SYS_CTRL_SCGCSEC_PKA 0x00000001 /**< PKA clock enable, CPU IDLE */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name SYS_CTRL_DCGCSEC register bit masks + * @{ + */ +#define SYS_CTRL_DCGCSEC_AES 0x00000002 /**< AES clock enable, PM0 */ +#define SYS_CTRL_DCGCSEC_PKA 0x00000001 /**< PKA clock enable, PM0 */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name SYS_CTRL_SRSEC register bits + * @{ + */ +#define SYS_CTRL_SRSEC_AES 0x00000002 /**< AES is reset */ +#define SYS_CTRL_SRSEC_PKA 0x00000001 /**< PKA is reset */ +/** @} */ +/*---------------------------------------------------------------------------*/ /** \name SYS_CTRL_PWRDBG register bits * @{ */ @@ -242,9 +277,47 @@ #endif /** @} */ /*---------------------------------------------------------------------------*/ +/** \name System clock divisor selection + * @{ + */ +#ifdef SYS_CTRL_CONF_SYS_DIV +#if SYS_CTRL_CONF_SYS_DIV & ~SYS_CTRL_CLOCK_CTRL_SYS_DIV +#error Invalid system clock divisor +#endif +#define SYS_CTRL_SYS_DIV SYS_CTRL_CONF_SYS_DIV +#else +#define SYS_CTRL_SYS_DIV SYS_CTRL_CLOCK_CTRL_SYS_DIV_16MHZ +#endif + +#ifdef SYS_CTRL_CONF_IO_DIV +#if SYS_CTRL_CONF_IO_DIV & ~SYS_CTRL_CLOCK_CTRL_IO_DIV +#error Invalid I/O clock divisor +#endif +#define SYS_CTRL_IO_DIV SYS_CTRL_CONF_IO_DIV +#else +#define SYS_CTRL_IO_DIV SYS_CTRL_CLOCK_CTRL_IO_DIV_16MHZ +#endif + +/* Returns actual system clock in Hz */ +#define SYS_CTRL_SYS_CLOCK (SYS_CTRL_32MHZ >> SYS_CTRL_SYS_DIV) +/* Returns actual I/O clock in Hz */ +#define SYS_CTRL_IO_CLOCK (SYS_CTRL_32MHZ >> (SYS_CTRL_IO_DIV >> 8)) +/** @} */ +/*---------------------------------------------------------------------------*/ /** \name SysCtrl functions * @{ */ + +/** \brief Gets the cause of the last reset + * \return A \c SYS_CTRL_CLOCK_STA_RST_x reset cause + */ +int sys_ctrl_get_reset_cause(void); + +/** \brief Gets a string describing the cause of the last reset + * \return Last reset cause as a string + */ +const char *sys_ctrl_get_reset_cause_str(void); + /** \brief Initialises the System Control Driver. The main purpose of this * function is to power up and select clocks and oscillators * \note This function depends on ioc_init() having been called beforehand. */ @@ -253,6 +326,12 @@ void sys_ctrl_init(); /** \brief Generates a warm reset through the SYS_CTRL_PWRDBG register */ void sys_ctrl_reset(); +/** \brief Returns the actual system clock in Hz */ +uint32_t sys_ctrl_get_sys_clock(); + +/** \brief Returns the actual io clock in Hz */ +uint32_t sys_ctrl_get_io_clock(); + /** @} */ #endif /* SYS_CTRL_H_ */ diff --git a/cpu/cc2538/dev/uart.c b/cpu/cc2538/dev/uart.c index 1ab2f81f1..cefbecf82 100644 --- a/cpu/cc2538/dev/uart.c +++ b/cpu/cc2538/dev/uart.c @@ -48,88 +48,220 @@ #include #include -static int (* input_handler)(unsigned char c); -/*---------------------------------------------------------------------------*/ -#define UART_RX_PORT_BASE GPIO_PORT_TO_BASE(UART_RX_PORT) -#define UART_RX_PIN_MASK GPIO_PIN_MASK(UART_RX_PIN) +#ifndef UART0_RX_PORT +#define UART0_RX_PORT (-1) +#endif +#ifndef UART0_RX_PIN +#define UART0_RX_PIN (-1) +#endif +#if UART0_RX_PORT >= 0 && UART0_RX_PIN < 0 || \ + UART0_RX_PORT < 0 && UART0_RX_PIN >= 0 +#error Both UART0_RX_PORT and UART0_RX_PIN must be valid or invalid +#endif -#define UART_TX_PORT_BASE GPIO_PORT_TO_BASE(UART_TX_PORT) -#define UART_TX_PIN_MASK GPIO_PIN_MASK(UART_TX_PIN) +#ifndef UART0_TX_PORT +#define UART0_TX_PORT (-1) +#endif +#ifndef UART0_TX_PIN +#define UART0_TX_PIN (-1) +#endif +#if UART0_TX_PORT >= 0 && UART0_TX_PIN < 0 || \ + UART0_TX_PORT < 0 && UART0_TX_PIN >= 0 +#error Both UART0_TX_PORT and UART0_TX_PIN must be valid or invalid +#endif -#define UART_CTS_PORT_BASE GPIO_PORT_TO_BASE(UART_CTS_PORT) -#define UART_CTS_PIN_MASK GPIO_PIN_MASK(UART_CTS_PIN) +#if UART0_RX_PORT >= 0 && UART0_TX_PORT < 0 || \ + UART0_RX_PORT < 0 && UART0_TX_PORT >= 0 +#error Both UART0_RX and UART0_TX pads must be valid or invalid +#endif -#define UART_RTS_PORT_BASE GPIO_PORT_TO_BASE(UART_RTS_PORT) -#define UART_RTS_PIN_MASK GPIO_PIN_MASK(UART_RTS_PIN) -/*---------------------------------------------------------------------------*/ -/* - * Once we know what UART we're on, configure correct values to be written to - * the correct registers - */ -#if UART_BASE==UART_1_BASE -/* Running, in sleep, in deep sleep, enable the clock for the correct UART */ -#define SYS_CTRL_RCGCUART_UART SYS_CTRL_RCGCUART_UART1 -#define SYS_CTRL_SCGCUART_UART SYS_CTRL_SCGCUART_UART1 -#define SYS_CTRL_DCGCUART_UART SYS_CTRL_DCGCUART_UART1 +#if UART_IN_USE(0) && UART0_RX_PORT < 0 +#error Contiki is configured to use UART0, but its pads are not valid +#endif -#define NVIC_INT_UART NVIC_INT_UART1 -#define IOC_PXX_SEL_UART_TXD IOC_PXX_SEL_UART1_TXD -#define IOC_UARTRXD_UART IOC_UARTRXD_UART1 -#else /* Defaults for UART0 */ -#define SYS_CTRL_RCGCUART_UART SYS_CTRL_RCGCUART_UART0 -#define SYS_CTRL_SCGCUART_UART SYS_CTRL_SCGCUART_UART0 -#define SYS_CTRL_DCGCUART_UART SYS_CTRL_DCGCUART_UART0 +#ifndef UART1_RX_PORT +#define UART1_RX_PORT (-1) +#endif +#ifndef UART1_RX_PIN +#define UART1_RX_PIN (-1) +#endif +#if UART1_RX_PORT >= 0 && UART1_RX_PIN < 0 || \ + UART1_RX_PORT < 0 && UART1_RX_PIN >= 0 +#error Both UART1_RX_PORT and UART1_RX_PIN must be valid or invalid +#endif -#define NVIC_INT_UART NVIC_INT_UART0 +#ifndef UART1_TX_PORT +#define UART1_TX_PORT (-1) +#endif +#ifndef UART1_TX_PIN +#define UART1_TX_PIN (-1) +#endif +#if UART1_TX_PORT >= 0 && UART1_TX_PIN < 0 || \ + UART1_TX_PORT < 0 && UART1_TX_PIN >= 0 +#error Both UART1_TX_PORT and UART1_TX_PIN must be valid or invalid +#endif -#define IOC_PXX_SEL_UART_TXD IOC_PXX_SEL_UART0_TXD -#define IOC_UARTRXD_UART IOC_UARTRXD_UART0 +#if UART1_RX_PORT >= 0 && UART1_TX_PORT < 0 || \ + UART1_RX_PORT < 0 && UART1_TX_PORT >= 0 +#error Both UART1_RX and UART1_TX pads must be valid or invalid +#endif + +#if UART_IN_USE(1) && UART1_RX_PORT < 0 +#error Contiki is configured to use UART1, but its pads are not valid +#endif + +#ifndef UART1_CTS_PORT +#define UART1_CTS_PORT (-1) +#endif +#ifndef UART1_CTS_PIN +#define UART1_CTS_PIN (-1) +#endif +#if UART1_CTS_PORT >= 0 && UART1_CTS_PIN < 0 || \ + UART1_CTS_PORT < 0 && UART1_CTS_PIN >= 0 +#error Both UART1_CTS_PORT and UART1_CTS_PIN must be valid or invalid +#endif + +#ifndef UART1_RTS_PORT +#define UART1_RTS_PORT (-1) +#endif +#ifndef UART1_RTS_PIN +#define UART1_RTS_PIN (-1) +#endif +#if UART1_RTS_PORT >= 0 && UART1_RTS_PIN < 0 || \ + UART1_RTS_PORT < 0 && UART1_RTS_PIN >= 0 +#error Both UART1_RTS_PORT and UART1_RTS_PIN must be valid or invalid #endif /*---------------------------------------------------------------------------*/ +/* + * Baud rate defines used in uart_init() to set the values of UART_IBRD and + * UART_FBRD in order to achieve the configured baud rates. + */ +#define UART_CLOCK_RATE SYS_CTRL_SYS_CLOCK +#define UART_CTL_HSE_VALUE 0 +#define UART_CTL_VALUE (UART_CTL_RXE | UART_CTL_TXE | (UART_CTL_HSE_VALUE << 5)) + +/* DIV_ROUND() divides integers while avoiding a rounding error: */ +#define DIV_ROUND(num, denom) (((num) + (denom) / 2) / (denom)) + +#define BAUD2BRD(baud) DIV_ROUND(UART_CLOCK_RATE << (UART_CTL_HSE_VALUE + 2), (baud)) +#define BAUD2IBRD(baud) (BAUD2BRD(baud) >> 6) +#define BAUD2FBRD(baud) (BAUD2BRD(baud) & 0x3f) +/*---------------------------------------------------------------------------*/ +typedef struct { + int8_t port; + int8_t pin; +} uart_pad_t; +typedef struct { + uint32_t sys_ctrl_rcgcuart_uart; + uint32_t sys_ctrl_scgcuart_uart; + uint32_t sys_ctrl_dcgcuart_uart; + uint32_t base; + uint32_t ioc_uartrxd_uart; + uint32_t ioc_pxx_sel_uart_txd; + uint32_t ibrd; + uint32_t fbrd; + uart_pad_t rx; + uart_pad_t tx; + uart_pad_t cts; + uart_pad_t rts; + uint8_t nvic_int; +} uart_regs_t; +/*---------------------------------------------------------------------------*/ +static const uart_regs_t uart_regs[UART_INSTANCE_COUNT] = { + { + .sys_ctrl_rcgcuart_uart = SYS_CTRL_RCGCUART_UART0, + .sys_ctrl_scgcuart_uart = SYS_CTRL_SCGCUART_UART0, + .sys_ctrl_dcgcuart_uart = SYS_CTRL_DCGCUART_UART0, + .base = UART_0_BASE, + .ioc_uartrxd_uart = IOC_UARTRXD_UART0, + .ioc_pxx_sel_uart_txd = IOC_PXX_SEL_UART0_TXD, + .ibrd = BAUD2IBRD(UART0_CONF_BAUD_RATE), + .fbrd = BAUD2FBRD(UART0_CONF_BAUD_RATE), + .rx = {UART0_RX_PORT, UART0_RX_PIN}, + .tx = {UART0_TX_PORT, UART0_TX_PIN}, + .cts = {-1, -1}, + .rts = {-1, -1}, + .nvic_int = NVIC_INT_UART0 + }, { + .sys_ctrl_rcgcuart_uart = SYS_CTRL_RCGCUART_UART1, + .sys_ctrl_scgcuart_uart = SYS_CTRL_SCGCUART_UART1, + .sys_ctrl_dcgcuart_uart = SYS_CTRL_DCGCUART_UART1, + .base = UART_1_BASE, + .ioc_uartrxd_uart = IOC_UARTRXD_UART1, + .ioc_pxx_sel_uart_txd = IOC_PXX_SEL_UART1_TXD, + .ibrd = BAUD2IBRD(UART1_CONF_BAUD_RATE), + .fbrd = BAUD2FBRD(UART1_CONF_BAUD_RATE), + .rx = {UART1_RX_PORT, UART1_RX_PIN}, + .tx = {UART1_TX_PORT, UART1_TX_PIN}, + .cts = {UART1_CTS_PORT, UART1_CTS_PIN}, + .rts = {UART1_RTS_PORT, UART1_RTS_PIN}, + .nvic_int = NVIC_INT_UART1 + } +}; +static int (* input_handler[UART_INSTANCE_COUNT])(unsigned char c); +/*---------------------------------------------------------------------------*/ static void -reset(void) +reset(uint32_t uart_base) { uint32_t lchr; /* Make sure the UART is disabled before trying to configure it */ - REG(UART_BASE | UART_CTL) = UART_CTL_VALUE; + REG(uart_base + UART_CTL) = UART_CTL_VALUE; /* Clear error status */ - REG(UART_BASE | UART_ECR) = 0xFF; + REG(uart_base + UART_ECR) = 0xFF; /* Store LCHR configuration */ - lchr = REG(UART_BASE | UART_LCRH); + lchr = REG(uart_base + UART_LCRH); /* Flush FIFOs by clearing LCHR.FEN */ - REG(UART_BASE | UART_LCRH) = 0; + REG(uart_base + UART_LCRH) = 0; /* Restore LCHR configuration */ - REG(UART_BASE | UART_LCRH) = lchr; + REG(uart_base + UART_LCRH) = lchr; /* UART Enable */ - REG(UART_BASE | UART_CTL) |= UART_CTL_UARTEN; + REG(uart_base + UART_CTL) |= UART_CTL_UARTEN; } /*---------------------------------------------------------------------------*/ static bool permit_pm1(void) { - /* Note: UART_FR.TXFE reads 0 if the UART clock is gated. */ - return (REG(SYS_CTRL_RCGCUART) & SYS_CTRL_RCGCUART_UART) == 0 || - (REG(UART_BASE | UART_FR) & UART_FR_TXFE) != 0; + const uart_regs_t *regs; + + for(regs = &uart_regs[0]; regs < &uart_regs[UART_INSTANCE_COUNT]; regs++) { + /* Note: UART_FR.TXFE reads 0 if the UART clock is gated. */ + if((REG(SYS_CTRL_RCGCUART) & regs->sys_ctrl_rcgcuart_uart) != 0 && + (REG(regs->base + UART_FR) & UART_FR_TXFE) == 0) { + return false; + } + } + + return true; } /*---------------------------------------------------------------------------*/ void -uart_init(void) +uart_init(uint8_t uart) { + const uart_regs_t *regs; + + if(uart >= UART_INSTANCE_COUNT) { + return; + } + regs = &uart_regs[uart]; + if(regs->rx.port < 0 || regs->tx.port < 0) { + return; + } + lpm_register_peripheral(permit_pm1); /* Enable clock for the UART while Running, in Sleep and Deep Sleep */ - REG(SYS_CTRL_RCGCUART) |= SYS_CTRL_RCGCUART_UART; - REG(SYS_CTRL_SCGCUART) |= SYS_CTRL_SCGCUART_UART; - REG(SYS_CTRL_DCGCUART) |= SYS_CTRL_DCGCUART_UART; + REG(SYS_CTRL_RCGCUART) |= regs->sys_ctrl_rcgcuart_uart; + REG(SYS_CTRL_SCGCUART) |= regs->sys_ctrl_scgcuart_uart; + REG(SYS_CTRL_DCGCUART) |= regs->sys_ctrl_dcgcuart_uart; /* Run on SYS_DIV */ - REG(UART_BASE | UART_CC) = 0; + REG(regs->base + UART_CC) = 0; /* * Select the UARTx RX pin by writing to the IOC_UARTRXD_UARTn register @@ -139,91 +271,130 @@ uart_init(void) * * (port << 3) + pin */ - REG(IOC_UARTRXD_UART) = (UART_RX_PORT << 3) + UART_RX_PIN; + REG(regs->ioc_uartrxd_uart) = (regs->rx.port << 3) + regs->rx.pin; /* * Pad Control for the TX pin: - * - Set function to UART0 TX + * - Set function to UARTn TX * - Output Enable */ - ioc_set_sel(UART_TX_PORT, UART_TX_PIN, IOC_PXX_SEL_UART_TXD); - ioc_set_over(UART_TX_PORT, UART_TX_PIN, IOC_OVERRIDE_OE); + ioc_set_sel(regs->tx.port, regs->tx.pin, regs->ioc_pxx_sel_uart_txd); + ioc_set_over(regs->tx.port, regs->tx.pin, IOC_OVERRIDE_OE); /* Set RX and TX pins to peripheral mode */ - GPIO_PERIPHERAL_CONTROL(UART_TX_PORT_BASE, UART_TX_PIN_MASK); - GPIO_PERIPHERAL_CONTROL(UART_RX_PORT_BASE, UART_RX_PIN_MASK); + GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(regs->tx.port), + GPIO_PIN_MASK(regs->tx.pin)); + GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(regs->rx.port), + GPIO_PIN_MASK(regs->rx.pin)); /* * UART Interrupt Masks: * Acknowledge RX and RX Timeout * Acknowledge Framing, Overrun and Break Errors */ - REG(UART_BASE | UART_IM) = UART_IM_RXIM | UART_IM_RTIM; - REG(UART_BASE | UART_IM) |= UART_IM_OEIM | UART_IM_BEIM | UART_IM_FEIM; + REG(regs->base + UART_IM) = UART_IM_RXIM | UART_IM_RTIM; + REG(regs->base + UART_IM) |= UART_IM_OEIM | UART_IM_BEIM | UART_IM_FEIM; - REG(UART_BASE | UART_IFLS) = + REG(regs->base + UART_IFLS) = UART_IFLS_RXIFLSEL_1_8 | UART_IFLS_TXIFLSEL_1_2; /* Make sure the UART is disabled before trying to configure it */ - REG(UART_BASE | UART_CTL) = UART_CTL_VALUE; + REG(regs->base + UART_CTL) = UART_CTL_VALUE; /* Baud Rate Generation */ - uart_set_baudrate(UART_CONF_BAUD_RATE); + REG(regs->base + UART_IBRD) = regs->ibrd; + REG(regs->base + UART_FBRD) = regs->fbrd; /* UART Control: 8N1 with FIFOs */ - REG(UART_BASE | UART_LCRH) = UART_LCRH_WLEN_8 | UART_LCRH_FEN; + REG(regs->base + UART_LCRH) = UART_LCRH_WLEN_8 | UART_LCRH_FEN; + + /* + * Enable hardware flow control (RTS/CTS) if requested. + * Note that hardware flow control is available only on UART1. + */ + if(regs->cts.port >= 0) { + REG(IOC_UARTCTS_UART1) = ioc_input_sel(regs->cts.port, regs->cts.pin); + GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(regs->cts.port), GPIO_PIN_MASK(regs->cts.pin)); + ioc_set_over(regs->cts.port, regs->cts.pin, IOC_OVERRIDE_DIS); + REG(UART_1_BASE + UART_CTL) |= UART_CTL_CTSEN; + } + + if(regs->rts.port >= 0) { + ioc_set_sel(regs->rts.port, regs->rts.pin, IOC_PXX_SEL_UART1_RTS); + GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(regs->rts.port), GPIO_PIN_MASK(regs->rts.pin)); + ioc_set_over(regs->rts.port, regs->rts.pin, IOC_OVERRIDE_OE); + REG(UART_1_BASE + UART_CTL) |= UART_CTL_RTSEN; + } /* UART Enable */ - REG(UART_BASE | UART_CTL) |= UART_CTL_UARTEN; + REG(regs->base + UART_CTL) |= UART_CTL_UARTEN; /* Enable UART0 Interrupts */ - nvic_interrupt_enable(NVIC_INT_UART); + nvic_interrupt_enable(regs->nvic_int); } /*---------------------------------------------------------------------------*/ void -uart_set_input(int (* input)(unsigned char c)) +uart_set_input(uint8_t uart, int (* input)(unsigned char c)) { - input_handler = input; -} -/*---------------------------------------------------------------------------*/ -void -uart_write_byte(uint8_t b) -{ - /* Block if the TX FIFO is full */ - while(REG(UART_BASE | UART_FR) & UART_FR_TXFF); + if(uart >= UART_INSTANCE_COUNT) { + return; + } - REG(UART_BASE | UART_DR) = b; + input_handler[uart] = input; } /*---------------------------------------------------------------------------*/ void -uart_isr(void) +uart_write_byte(uint8_t uart, uint8_t b) { + uint32_t uart_base; + + if(uart >= UART_INSTANCE_COUNT) { + return; + } + uart_base = uart_regs[uart].base; + + /* Block if the TX FIFO is full */ + while(REG(uart_base + UART_FR) & UART_FR_TXFF); + + REG(uart_base + UART_DR) = b; +} +/*---------------------------------------------------------------------------*/ +static void +uart_isr(uint8_t uart) +{ + uint32_t uart_base; uint16_t mis; ENERGEST_ON(ENERGEST_TYPE_IRQ); + uart_base = uart_regs[uart].base; + /* Store the current MIS and clear all flags early, except the RTM flag. * This will clear itself when we read out the entire FIFO contents */ - mis = REG(UART_BASE | UART_MIS) & 0x0000FFFF; + mis = REG(uart_base + UART_MIS) & 0x0000FFFF; - REG(UART_BASE | UART_ICR) = 0x0000FFBF; + REG(uart_base + UART_ICR) = 0x0000FFBF; if(mis & (UART_MIS_RXMIS | UART_MIS_RTMIS)) { - while(!(REG(UART_BASE | UART_FR) & UART_FR_RXFE)) { - if(input_handler != NULL) { - input_handler((unsigned char)(REG(UART_BASE | UART_DR) & 0xFF)); + while(!(REG(uart_base + UART_FR) & UART_FR_RXFE)) { + if(input_handler[uart] != NULL) { + input_handler[uart]((unsigned char)(REG(uart_base + UART_DR) & 0xFF)); } else { /* To prevent an Overrun Error, we need to flush the FIFO even if we * don't have an input_handler. Use mis as a data trash can */ - mis = REG(UART_BASE | UART_DR); + mis = REG(uart_base + UART_DR); } } } else if(mis & (UART_MIS_OEMIS | UART_MIS_BEMIS | UART_MIS_FEMIS)) { /* ISR triggered due to some error condition */ - reset(); + reset(uart_base); } ENERGEST_OFF(ENERGEST_TYPE_IRQ); } +/*---------------------------------------------------------------------------*/ +#define UART_ISR(u) void uart##u##_isr(void) { uart_isr(u); } +UART_ISR(0) +UART_ISR(1) /** @} */ diff --git a/cpu/cc2538/dev/uart.h b/cpu/cc2538/dev/uart.h index fbc18fc18..3cde5b0af 100644 --- a/cpu/cc2538/dev/uart.h +++ b/cpu/cc2538/dev/uart.h @@ -47,42 +47,17 @@ #include /*---------------------------------------------------------------------------*/ +/** \name UART instance count + * @{ + */ +#define UART_INSTANCE_COUNT 2 +/** @} */ +/*---------------------------------------------------------------------------*/ /** \name UART base addresses * @{ */ #define UART_0_BASE 0x4000C000 #define UART_1_BASE 0x4000D000 - -/* Default to UART 0 unless the configuration tells us otherwise */ -#ifdef UART_CONF_BASE -#define UART_BASE UART_CONF_BASE -#else -#define UART_BASE UART_0_BASE -#endif -/** @} */ -/*---------------------------------------------------------------------------*/ -/** - * \name Baud rate defines - * - * Used in uart_init() to set the values of UART_IBRD and UART_FBRD in order to - * achieve some standard baud rates. - * @{ - */ -#define UART_CLOCK_RATE 16000000 /* 16 MHz */ -#define UART_CTL_HSE_VALUE 0 -#define UART_CTL_VALUE ( UART_CTL_RXE | UART_CTL_TXE | (UART_CTL_HSE_VALUE << 5) ) - -/* DIV_ROUND() divides integers while avoiding a rounding error: */ -#define DIV_ROUND(num, denom) ( ((num) + (denom) / 2) / (denom) ) - -#define BAUD2BRD(baud) DIV_ROUND(UART_CLOCK_RATE << (UART_CTL_HSE_VALUE + 2), (baud)) - -#define uart_set_baudrate(baud) do { \ - REG(UART_BASE | UART_IBRD) = BAUD2BRD(baud) >> 6; \ - REG(UART_BASE | UART_FBRD) = BAUD2BRD(baud) & 0x3f; \ - REG(UART_BASE | UART_LCRH) = REG(UART_BASE | UART_LCRH); \ -} while(0) - /** @} */ /*---------------------------------------------------------------------------*/ /** \name UART Register Offsets @@ -190,6 +165,8 @@ /** \name UART_CTL Register Bit-Masks * @{ */ +#define UART_CTL_CTSEN 0x00008000 /**< UART CTS flow-control enable (UART1 only) */ +#define UART_CTL_RTSEN 0x00004000 /**< UART RTS flow-control enable (UART1 only) */ #define UART_CTL_RXE 0x00000200 /**< UART receive enable */ #define UART_CTL_TXE 0x00000100 /**< UART transmit enable */ #define UART_CTL_LBE 0x00000080 /**< UART loop back enable */ @@ -356,18 +333,22 @@ */ /** \brief Initialises the UART controller, configures I/O control - * and interrupts */ -void uart_init(void); + * and interrupts + * \param uart The UART instance to use (0 to \c UART_INSTANCE_COUNT - 1) + */ +void uart_init(uint8_t uart); /** \brief Sends a single character down the UART + * \param uart The UART instance to use (0 to \c UART_INSTANCE_COUNT - 1) * \param b The character to transmit */ -void uart_write_byte(uint8_t b); +void uart_write_byte(uint8_t uart, uint8_t b); /** \brief Assigns a callback to be called when the UART receives a byte + * \param uart The UART instance to use (0 to \c UART_INSTANCE_COUNT - 1) * \param input A pointer to the function */ -void uart_set_input(int (* input)(unsigned char c)); +void uart_set_input(uint8_t uart, int (* input)(unsigned char c)); /** @} */ diff --git a/cpu/cc2538/dev/uart1.h b/cpu/cc2538/dev/uart1.h index e0e03b487..7493ea048 100644 --- a/cpu/cc2538/dev/uart1.h +++ b/cpu/cc2538/dev/uart1.h @@ -44,7 +44,7 @@ #include "dev/uart.h" #define BAUD2UBR(x) x -#define uart1_set_input(f) uart_set_input(f) +#define uart1_set_input(f) uart_set_input(UART1_CONF_UART, f) #endif /* UART1_H_ */ diff --git a/cpu/cc2538/dev/udma.c b/cpu/cc2538/dev/udma.c index c285d1b11..c9770869b 100644 --- a/cpu/cc2538/dev/udma.c +++ b/cpu/cc2538/dev/udma.c @@ -56,7 +56,7 @@ static volatile struct channel_ctrl channel_config[UDMA_CONF_MAX_CHANNEL + 1] void udma_init() { - memset(&channel_config, 0, sizeof(channel_config)); + memset((void *)&channel_config, 0, sizeof(channel_config)); REG(UDMA_CFG) = UDMA_CFG_MASTEN; diff --git a/cpu/cc2538/dev/udma.h b/cpu/cc2538/dev/udma.h index a6ddfc199..79cd58c20 100644 --- a/cpu/cc2538/dev/udma.h +++ b/cpu/cc2538/dev/udma.h @@ -560,12 +560,13 @@ void udma_init(void); /** * \brief Sets the channels source address * \param channel The channel as a value in [0 , UDMA_CONF_MAX_CHANNEL] - * \param + * \param src_end The source's end address */ void udma_set_channel_src(uint8_t channel, uint32_t src_end); /** - * \brief + * \brief Sets the channel's destination address + * \param dst_end The destination's end address * \param channel The channel as a value in [0 , UDMA_CONF_MAX_CHANNEL] */ void udma_set_channel_dst(uint8_t channel, uint32_t dst_end); diff --git a/cpu/cc2538/dev/vdd3-sensor.c b/cpu/cc2538/dev/vdd3-sensor.c new file mode 100644 index 000000000..678c25b8e --- /dev/null +++ b/cpu/cc2538/dev/vdd3-sensor.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc2538-vdd3-sensor + * @{ + * + * \file + * Driver for the CC2538 VDD3 sensor + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/vdd3-sensor.h" +#include "dev/adc.h" +#include "dev/cc2538-sensors.h" + +#include +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + int raw = adc_get(SOC_ADC_ADCCON_CH_VDD_3, SOC_ADC_ADCCON_REF_INT, + SOC_ADC_ADCCON_DIV_512); + + if(type == CC2538_SENSORS_VALUE_TYPE_RAW) { + return raw; + } else if(type == CC2538_SENSORS_VALUE_TYPE_CONVERTED) { + return raw * (3 * 1190) / (2047 << 4); + } + + return CC2538_SENSORS_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(vdd3_sensor, VDD3_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/cpu/cc2538/dev/vdd3-sensor.h b/cpu/cc2538/dev/vdd3-sensor.h new file mode 100644 index 000000000..aa0fcf94c --- /dev/null +++ b/cpu/cc2538/dev/vdd3-sensor.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc2538-sensors + * @{ + * + * \defgroup cc2538-vdd3-sensor CC2538 VDD3 Sensor + * + * Driver for the CC2538 VDD3 sensor + * + * This driver can return the raw as well as the converted value of the sensor + * reading. This is controlled by the type argument of the sensor driver's + * value() function. The choices for the type argument are: + * - REMOTE_SENSORS_VALUE_TYPE_RAW (value() returns the raw reading) + * - REMOTE_SENSORS_VALUE_TYPE_CONVERTED (value() returns mV) + * @{ + * + * \file + * Header file for the CC2538 VDD3 Sensor Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef VDD3_SENSOR_H_ +#define VDD3_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +/** + * \name VDD3 sensors + * @{ + */ +#define VDD3_SENSOR "VDD3" +/** @} */ +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor vdd3_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* VDD3_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/watchdog.c b/cpu/cc2538/dev/watchdog.c index 7d446e74e..9f306e586 100644 --- a/cpu/cc2538/dev/watchdog.c +++ b/cpu/cc2538/dev/watchdog.c @@ -46,6 +46,17 @@ #include "cpu.h" #include "dev/smwdthrosc.h" /*---------------------------------------------------------------------------*/ +/* Enabled by default */ +#ifndef WATCHDOG_CONF_ENABLE +#define WATCHDOG_CONF_ENABLE 1 +#endif + +#if WATCHDOG_CONF_ENABLE +#define WATCHDOG_ENABLE SMWDTHROSC_WDCTL_EN +#else +#define WATCHDOG_ENABLE 0 +#endif +/*---------------------------------------------------------------------------*/ /** \brief Initialisation function for the WDT. Currently simply explicitly * sets the WDT interval to max interval */ void @@ -55,38 +66,41 @@ watchdog_init(void) REG(SMWDTHROSC_WDCTL) = 0; } /*---------------------------------------------------------------------------*/ -/** \brief Starts the WDT in watchdog mode, maximum interval */ +/** \brief Starts the WDT in watchdog mode if enabled by user configuration, + * maximum interval */ void watchdog_start(void) { - /* Max interval (32768), watchdog mode, Enable */ - REG(SMWDTHROSC_WDCTL) = SMWDTHROSC_WDCTL_EN; + /* Max interval (32768), watchdog mode, enable if configured to do so */ + REG(SMWDTHROSC_WDCTL) = WATCHDOG_ENABLE; } /*---------------------------------------------------------------------------*/ -/** \brief Writes the WDT clear sequence. This function assumes that we are - * in watchdog mode and that interval bits (bits [1:0]) are 00 */ +/** + * \brief Writes the WDT clear sequence. + * + * Due to how the SMWDTHROSC_WDCTL works, it is OK to simply write these bits + * rather than use RMW operations. + */ void watchdog_periodic(void) { - /* Safe to write to bits [3:0] since EN is 1 */ REG(SMWDTHROSC_WDCTL) = (SMWDTHROSC_WDCTL_CLR_3 | SMWDTHROSC_WDCTL_CLR_1); REG(SMWDTHROSC_WDCTL) = (SMWDTHROSC_WDCTL_CLR_2 | SMWDTHROSC_WDCTL_CLR_0); } /*---------------------------------------------------------------------------*/ -/** \brief In watchdog mode, the WDT can not be stopped. This function is - * defined here to satisfy API requirements. - */ -void -watchdog_stop(void) -{ - return; -} -/*---------------------------------------------------------------------------*/ -/** \brief Keeps control until the WDT throws a reset signal */ +/** \brief Keeps control until the WDT throws a reset signal. Starts the WDT + * if not already started. */ void watchdog_reboot(void) { INTERRUPTS_DISABLE(); + + /* + * If the WDT is not started, set minimum interval and start + * If the WDT is started, this will have no effect + */ + REG(SMWDTHROSC_WDCTL) = SMWDTHROSC_WDCTL_INT | SMWDTHROSC_WDCTL_EN; + while(1); } /** diff --git a/cpu/cc2538/ieee-addr.c b/cpu/cc2538/ieee-addr.c index cb8c901bc..f45e4210d 100644 --- a/cpu/cc2538/ieee-addr.c +++ b/cpu/cc2538/ieee-addr.c @@ -49,10 +49,36 @@ ieee_addr_cpy_to(uint8_t *dst, uint8_t len) memcpy(dst, &ieee_addr_hc[8 - len], len); } else { - /* Reading from Info Page, we need to invert byte order */ + /* + * By default, we assume that the IEEE address is stored on flash using + * little-endian byte order. + * + * However, some SoCs ship with a different byte order, whereby the first + * four bytes are flipped with the four last ones. + * + * Using this address as an example: 00 12 4B 00 01 02 03 04 + * We expect it stored as: 04 03 02 01 00 4B 12 00 + * But it is also possible to encounter: 00 4B 12 00 04 03 02 01 + * + * Thus: read locations [3, 2, 1] and if we encounter the TI OUI, flip the + * order of the two 4-byte sequences. Each of the 4-byte sequences is still + * little-endian. + */ int i; - for(i = 0; i < len; i++) { - dst[i] = ((uint8_t *)IEEE_ADDR_LOCATION)[len - 1 - i]; + uint8_t oui_ti[3] = IEEE_ADDR_OUI_TI; + if(((uint8_t *)IEEE_ADDR_LOCATION)[3] == oui_ti[0] + && ((uint8_t *)IEEE_ADDR_LOCATION)[2] == oui_ti[1] + && ((uint8_t *)IEEE_ADDR_LOCATION)[1] == oui_ti[2]) { + for(i = 0; i < len / 2; i++) { + dst[i] = ((uint8_t *)IEEE_ADDR_LOCATION)[len / 2 - 1 - i]; + } + for(i = 0; i < len / 2; i++) { + dst[i + len / 2] = ((uint8_t *)IEEE_ADDR_LOCATION)[len - 1 - i]; + } + } else { + for(i = 0; i < len; i++) { + dst[i] = ((uint8_t *)IEEE_ADDR_LOCATION)[len - 1 - i]; + } } } diff --git a/cpu/cc2538/ieee-addr.h b/cpu/cc2538/ieee-addr.h index c7618c1e7..faeacdb8f 100644 --- a/cpu/cc2538/ieee-addr.h +++ b/cpu/cc2538/ieee-addr.h @@ -49,11 +49,27 @@ #include /*---------------------------------------------------------------------------*/ /** - * \name IEEE address locations + * \name TI OUI * @{ */ -#define IEEE_ADDR_LOCATION_PRIMARY 0x00280028 /**< IEEE address location */ -#define IEEE_ADDR_LOCATION_SECONDARY 0x0027FFCC /**< IEEE address location */ +#define IEEE_ADDR_OUI_TI { 0x00, 0x12, 0x4B } /**< TI OUI */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name IEEE address locations + * + * The address of the secondary location can be configured by the platform + * or example + * + * @{ + */ +#define IEEE_ADDR_LOCATION_PRIMARY 0x00280028 /**< Primary IEEE address location */ + +#ifdef IEEE_ADDR_CONF_LOCATION_SECONDARY +#define IEEE_ADDR_LOCATION_SECONDARY IEEE_ADDR_CONF_LOCATION_SECONDARY +#else +#define IEEE_ADDR_LOCATION_SECONDARY 0x0027FFCC /**< Secondary IEEE address location */ +#endif /** @} */ /*---------------------------------------------------------------------------*/ /** diff --git a/cpu/cc2538/lpm.c b/cpu/cc2538/lpm.c index 6270e51b7..7e582c6fb 100644 --- a/cpu/cc2538/lpm.c +++ b/cpu/cc2538/lpm.c @@ -78,8 +78,8 @@ static unsigned long irq_energest = 0; #if LPM_CONF_STATS rtimer_clock_t lpm_stats[3]; -#define LPM_STATS_INIT() do { memset(lpm_stats, 0, sizeof(lpm_stats)); \ - } while(0) +#define LPM_STATS_INIT() \ + do { memset(lpm_stats, 0, sizeof(lpm_stats)); } while(0) #define LPM_STATS_ADD(pm, val) do { lpm_stats[pm] += val; } while(0) #else #define LPM_STATS_INIT() @@ -101,7 +101,7 @@ static uint8_t max_pm; #ifdef LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX #define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX #else -#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 2 +#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 5 #endif static lpm_periph_permit_pm1_func_t @@ -128,8 +128,7 @@ periph_permit_pm1(void) static void enter_pm0(void) { - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* We are only interested in IRQ energest while idle or in LPM */ ENERGEST_IRQ_RESTORE(irq_energest); @@ -147,14 +146,13 @@ enter_pm0(void) /* Remember IRQ energest for next pass */ ENERGEST_IRQ_SAVE(irq_energest); - ENERGEST_ON(ENERGEST_TYPE_CPU); - ENERGEST_OFF(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } /*---------------------------------------------------------------------------*/ static void select_32_mhz_xosc(void) { - /*First, make sure there is no ongoing clock source change */ + /* First, make sure there is no ongoing clock source change */ while((REG(SYS_CTRL_CLOCK_STA) & SYS_CTRL_CLOCK_STA_SOURCE_CHANGE) != 0); /* Turn on the 32 MHz XOSC and source the system clock on it. */ @@ -163,8 +161,15 @@ select_32_mhz_xosc(void) /* Wait for the switch to take place */ while((REG(SYS_CTRL_CLOCK_STA) & SYS_CTRL_CLOCK_STA_OSC) != 0); - /* Power down the unused oscillator. */ - REG(SYS_CTRL_CLOCK_CTRL) |= SYS_CTRL_CLOCK_CTRL_OSC_PD; + /* Power down the unused oscillator and restore divisors (silicon errata) */ + REG(SYS_CTRL_CLOCK_CTRL) = (REG(SYS_CTRL_CLOCK_CTRL) +#if SYS_CTRL_SYS_DIV == SYS_CTRL_CLOCK_CTRL_SYS_DIV_32MHZ + & ~SYS_CTRL_CLOCK_CTRL_SYS_DIV +#endif +#if SYS_CTRL_IO_DIV == SYS_CTRL_CLOCK_CTRL_IO_DIV_32MHZ + & ~SYS_CTRL_CLOCK_CTRL_IO_DIV +#endif + ) | SYS_CTRL_CLOCK_CTRL_OSC_PD; } /*---------------------------------------------------------------------------*/ static void @@ -172,9 +177,19 @@ select_16_mhz_rcosc(void) { /* * Power up both oscillators in order to speed up the transition to the 32-MHz - * XOSC after wake up. + * XOSC after wake up. In addition, consider CC2538 silicon errata: + * "Possible Incorrect Value of Clock Dividers after PM2 and PM3" and + * set system clock divisor / I/O clock divisor to 16 MHz in case they run + * at full speed (=32 MHz) */ - REG(SYS_CTRL_CLOCK_CTRL) &= ~SYS_CTRL_CLOCK_CTRL_OSC_PD; + REG(SYS_CTRL_CLOCK_CTRL) = (REG(SYS_CTRL_CLOCK_CTRL) +#if SYS_CTRL_SYS_DIV == SYS_CTRL_CLOCK_CTRL_SYS_DIV_32MHZ + | SYS_CTRL_CLOCK_CTRL_SYS_DIV_16MHZ +#endif +#if SYS_CTRL_IO_DIV == SYS_CTRL_CLOCK_CTRL_IO_DIV_32MHZ + | SYS_CTRL_CLOCK_CTRL_IO_DIV_16MHZ +#endif + ) & ~SYS_CTRL_CLOCK_CTRL_OSC_PD; /*First, make sure there is no ongoing clock source change */ while((REG(SYS_CTRL_CLOCK_STA) & SYS_CTRL_CLOCK_STA_SOURCE_CHANGE) != 0); @@ -221,8 +236,7 @@ lpm_exit() /* Remember IRQ energest for next pass */ ENERGEST_IRQ_SAVE(irq_energest); - ENERGEST_ON(ENERGEST_TYPE_CPU); - ENERGEST_OFF(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } /*---------------------------------------------------------------------------*/ void @@ -295,8 +309,7 @@ lpm_enter() /* We are only interested in IRQ energest while idle or in LPM */ ENERGEST_IRQ_RESTORE(irq_energest); - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* Remember the current time so we can keep stats when we wake up */ if(LPM_CONF_STATS) { @@ -322,8 +335,7 @@ lpm_enter() /* Remember IRQ energest for next pass */ ENERGEST_IRQ_SAVE(irq_energest); - ENERGEST_ON(ENERGEST_TYPE_CPU); - ENERGEST_OFF(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } else { /* All clear. Assert WFI and drop to PM1/2. This is now un-interruptible */ assert_wfi(); diff --git a/cpu/cc2538/rtimer-arch.h b/cpu/cc2538/rtimer-arch.h index ddb020af1..45ebc5c5d 100644 --- a/cpu/cc2538/rtimer-arch.h +++ b/cpu/cc2538/rtimer-arch.h @@ -65,6 +65,20 @@ #define RTIMER_ARCH_SECOND 32768 +/* Do the math in 32bits to save precision. + * Round to nearest integer rather than truncate. */ +#define US_TO_RTIMERTICKS(US) ((US) >= 0 ? \ + (((int32_t)(US) * (RTIMER_ARCH_SECOND) + 500000) / 1000000L) : \ + ((int32_t)(US) * (RTIMER_ARCH_SECOND) - 500000) / 1000000L) + +#define RTIMERTICKS_TO_US(T) ((T) >= 0 ? \ + (((int32_t)(T) * 1000000L + ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND)) : \ + ((int32_t)(T) * 1000000L - ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND)) + +/* A 64-bit version because the 32-bit one cannot handle T >= 4295 ticks. + Intended only for positive values of T. */ +#define RTIMERTICKS_TO_US_64(T) ((uint32_t)(((uint64_t)(T) * 1000000 + ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND))) + /** \sa RTIMER_NOW() */ rtimer_clock_t rtimer_arch_now(void); diff --git a/cpu/cc2538/slip-arch.c b/cpu/cc2538/slip-arch.c index f26dad0f3..4205a1826 100644 --- a/cpu/cc2538/slip-arch.c +++ b/cpu/cc2538/slip-arch.c @@ -52,8 +52,8 @@ #define set_input(f) usb_serial_set_input(f) #define flush() usb_serial_flush() #else -#define write_byte(b) uart_write_byte(b) -#define set_input(f) uart_set_input(f) +#define write_byte(b) uart_write_byte(SLIP_ARCH_CONF_UART, b) +#define set_input(f) uart_set_input(SLIP_ARCH_CONF_UART, f) #define flush() #endif diff --git a/cpu/cc2538/soc.c b/cpu/cc2538/soc.c new file mode 100644 index 000000000..58ebb3692 --- /dev/null +++ b/cpu/cc2538/soc.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2016, Benoît Thébaudeau + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538-soc + * @{ + * + * \file + * Implementation of the cc2538 SoC driver + */ +#include "contiki-conf.h" +#include "dev/rom-util.h" +#include "dev/sys-ctrl.h" +#include "reg.h" +#include "soc.h" + +#include +#include +/*----------------------------------------------------------------------------*/ +#define DIECFG0 0x400d3014 +#define DIECFG0_SRAM_SIZE_OFS 7 +#define DIECFG0_SRAM_SIZE_SZ 3 +#define DIECFG0_SRAM_SIZE_MSK (((1 << DIECFG0_SRAM_SIZE_SZ) - 1) << \ + DIECFG0_SRAM_SIZE_OFS) +#define DIECFG2 0x400d301c +#define DIECFG2_DIE_REV_OFS 8 +#define DIECFG2_DIE_REV_SZ 8 +#define DIECFG2_DIE_REV_MSK (((1 << DIECFG2_DIE_REV_SZ) - 1) << \ + DIECFG2_DIE_REV_OFS) +#define DIECFG2_AES_EN 0x00000002 +#define DIECFG2_PKA_EN 0x00000001 +/*----------------------------------------------------------------------------*/ +uint8_t +soc_get_rev(void) +{ + uint8_t rev = (REG(DIECFG2) & DIECFG2_DIE_REV_MSK) >> DIECFG2_DIE_REV_OFS; + + /* PG1.0 is encoded as 0x00. */ + if(!(rev >> 4)) + rev += 0x10; + return rev; +} +/*----------------------------------------------------------------------------*/ +uint32_t +soc_get_sram_size(void) +{ + uint32_t size_code = (REG(DIECFG0) & DIECFG0_SRAM_SIZE_MSK) >> + DIECFG0_SRAM_SIZE_OFS; + + return size_code <= 1 ? (2 - size_code) << 13 : 32 << 10; +} +/*----------------------------------------------------------------------------*/ +uint32_t +soc_get_features(void) +{ + return REG(DIECFG2) & (DIECFG2_AES_EN | DIECFG2_PKA_EN); +} +/*----------------------------------------------------------------------------*/ +void +soc_print_info(void) +{ + uint8_t rev = soc_get_rev(); + uint32_t features = soc_get_features(); + + printf("CC2538: ID: 0x%04lx, rev.: PG%d.%d, Flash: %lu KiB, SRAM: %lu KiB, " + "AES/SHA: %u, ECC/RSA: %u\n" + "System clock: %lu Hz\n" + "I/O clock: %lu Hz\n" + "Reset cause: %s\n", + rom_util_get_chip_id(), + rev >> 4, rev & 0x0f, + rom_util_get_flash_size() >> 10, + soc_get_sram_size() >> 10, + !!(features & SOC_FEATURE_AES_SHA), + !!(features & SOC_FEATURE_ECC_RSA), + sys_ctrl_get_sys_clock(), + sys_ctrl_get_io_clock(), + sys_ctrl_get_reset_cause_str()); +} + +/** @} */ diff --git a/cpu/cc2538/soc.h b/cpu/cc2538/soc.h new file mode 100644 index 000000000..d8bf939de --- /dev/null +++ b/cpu/cc2538/soc.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2016, Benoît Thébaudeau + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc2538 + * @{ + * + * \defgroup cc2538-soc cc2538 SoC + * + * Driver for the cc2538 SoC + * @{ + * + * \file + * Header file with macro and function declarations for the cc2538 SoC + */ +#ifndef SOC_H_ +#define SOC_H_ + +#include "contiki-conf.h" + +#include +/*----------------------------------------------------------------------------*/ +/** \name SoC features + * @{ + */ +#define SOC_FEATURE_AES_SHA 0x00000002 /**< Security HW AES/SHA */ +#define SOC_FEATURE_ECC_RSA 0x00000001 /**< Security HW ECC/RSA */ +/** @} */ +/*----------------------------------------------------------------------------*/ +/** \name SoC functions + * @{ + */ + +/** \brief Gets the SoC revision + * \return The SoC revision as a byte with nibbles representing the major and + * minor revisions + */ +uint8_t soc_get_rev(void); + +/** \brief Gets the SRAM size of the SoC + * \return The SRAM size in bytes + */ +uint32_t soc_get_sram_size(void); + +/** \brief Gets the hardware features of the SoC that are enabled + * \return The enabled hardware features as a bitmask of \c SOC_FEATURE_x values + */ +uint32_t soc_get_features(void); + +/** \brief Prints SoC information */ +void soc_print_info(void); + +/** @} */ + +#endif /* SOC_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/spi-arch.h b/cpu/cc2538/spi-arch.h index 85eb058c1..137220b2f 100644 --- a/cpu/cc2538/spi-arch.h +++ b/cpu/cc2538/spi-arch.h @@ -1,5 +1,9 @@ /* * Copyright (c) 2013, University of Michigan. + * + * Copyright (c) 2015, Weptech elektronik GmbH + * Author: Ulf Knoblich, ulf.knoblich@weptech.de + * * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,55 +31,184 @@ * SUCH DAMAGE. */ /** - * \addtogroup cc2538 + * \addtogroup cc2538-spi * @{ * - * Implementation of the low-level SPI primitives such as waiting for the TX - * FIFO to be ready, inserting into the TX FIFO, etc. - * @{ - */ -/** * \file - * Header file for the cc2538 SPI commands + * Header file for the cc2538 SPI driver, including macros for the + * implementation of the low-level SPI primitives such as waiting for the TX + * FIFO to be ready, inserting into the TX FIFO, etc. + * + * It supports the usage of SSI_NUM_INSTANCES instances by providing new + * functions calls like + * + * - spix_init(uint8_t instance) + * - spix_enable(uint8_t instance) + * - spix_disable(uint8_t instance) + * - spix_set_mode(unit8_t instance, ...) + * + * and new macros like + * + * - SPIX_WAITFORTxREADY(x) + * - SPIX_WAITFOREOTx(x) + * - SPIX_WAITFOREORx(x) + * - SPIX_FLUSH(x) + * + * Some of the old functions and macros are still supported. + * When using these deprecated functions, the SSI module to use + * has to be be selected by means of the macro SPI_CONF_DEFAULT_INSTANCE. + * + * This SPI driver depends on the following defines: + * + * For the SSI0 module: + * + * - SPI0_CKL_PORT + * - SPI0_CLK_PIN + * - SPI0_TX_PORT + * - SPI0_TX_PIN + * - SPI0_RX_PORT + * - SPI0_RX_PIN + * + * For the SSI1 module: + * + * - SPI1_CKL_PORT + * - SPI1_CLK_PIN + * - SPI1_TX_PORT + * - SPI1_TX_PIN + * - SPI1_RX_PORT + * - SPI1_RX_PIN */ #ifndef SPI_ARCH_H_ #define SPI_ARCH_H_ #include "contiki.h" + #include "dev/ssi.h" +/*---------------------------------------------------------------------------*/ +/* The SPI instance to use when using the deprecated SPI API. */ +#ifdef SPI_CONF_DEFAULT_INSTANCE +#if SPI_CONF_DEFAULT_INSTANCE > (SSI_INSTANCE_COUNT - 1) +#error Invalid SPI_CONF_DEFAULT_INSTANCE: valid values are 0 and 1 +#else +#define SPI_DEFAULT_INSTANCE SPI_CONF_DEFAULT_INSTANCE +#endif +#endif +/*---------------------------------------------------------------------------*/ +/* Default values for the clock rate divider */ +#ifdef SPI0_CONF_CPRS_CPSDVSR +#define SPI0_CPRS_CPSDVSR SPI0_CONF_CPRS_CPSDVSR +#else +#define SPI0_CPRS_CPSDVSR 2 +#endif -#define SPI_WAITFORTxREADY() do { \ - while(!(REG(SSI0_BASE + SSI_SR) & SSI_SR_TNF)); \ -} while (0) - -#define SPI_TXBUF REG(SSI0_BASE + SSI_DR) -#define SPI_RXBUF REG(SSI0_BASE + SSI_DR) - -#define SPI_WAITFOREOTx() do { \ - while(REG(SSI0_BASE + SSI_SR) & SSI_SR_BSY); \ -} while (0) -#define SPI_WAITFOREORx() do { \ - while(!(REG(SSI0_BASE + SSI_SR) & SSI_SR_RNE)); \ -} while (0) +#ifdef SPI1_CONF_CPRS_CPSDVSR +#define SPI1_CPRS_CPSDVSR SPI1_CONF_CPRS_CPSDVSR +#else +#define SPI1_CPRS_CPSDVSR 2 +#endif +/*---------------------------------------------------------------------------*/ +/* New API macros */ +#define SPIX_WAITFORTxREADY(spi) do { \ + while(!(REG(CC_CONCAT3(SSI, spi, _BASE) + SSI_SR) & SSI_SR_TNF)) ; \ +} while(0) +#define SPIX_BUF(spi) REG(CC_CONCAT3(SSI, spi, _BASE) + SSI_DR) +#define SPIX_WAITFOREOTx(spi) do { \ + while(REG(CC_CONCAT3(SSI, spi, _BASE) + SSI_SR) & SSI_SR_BSY) ; \ +} while(0) +#define SPIX_WAITFOREORx(spi) do { \ + while(!(REG(CC_CONCAT3(SSI, spi, _BASE) + SSI_SR) & SSI_SR_RNE)) ; \ +} while(0) +#define SPIX_FLUSH(spi) do { \ + while(REG(CC_CONCAT3(SSI, spi, _BASE) + SSI_SR) & SSI_SR_RNE) { \ + SPIX_BUF(spi); \ + } \ +} while(0) +#define SPIX_CS_CLR(port, pin) do { \ + GPIO_CLR_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); \ +} while(0) +#define SPIX_CS_SET(port, pin) do { \ + GPIO_SET_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); \ +} while(0) +/*---------------------------------------------------------------------------*/ +/* Deprecated macros provided for compatibility reasons */ +#ifdef SPI_DEFAULT_INSTANCE +#define SPI_WAITFORTxREADY() SPIX_WAITFORTxREADY(SPI_DEFAULT_INSTANCE) +#define SPI_TXBUF SPIX_BUF(SPI_DEFAULT_INSTANCE) +#define SPI_RXBUF SPI_TXBUF +#define SPI_WAITFOREOTx() SPIX_WAITFOREOTx(SPI_DEFAULT_INSTANCE) +#define SPI_WAITFOREORx() SPIX_WAITFOREORx(SPI_DEFAULT_INSTANCE) +#ifdef SPI_FLUSH +#error You must include spi-arch.h before spi.h for the CC2538 +#else +#define SPI_FLUSH() SPIX_FLUSH(SPI_DEFAULT_INSTANCE) +#endif +#define SPI_CS_CLR(port, pin) SPIX_CS_CLR(port, pin) +#define SPI_CS_SET(port, pin) SPIX_CS_SET(port, pin) +#endif /* #ifdef SPI_DEFAULT_INSTANCE */ /*---------------------------------------------------------------------------*/ /** \name Arch-specific SPI functions * @{ */ -/** \brief Enables the SPI peripheral +/** + * \brief Initialize the SPI bus for the instance given + * + * This sets the mode to Motorola SPI with the following format options: + * Clock phase: 1; data captured on second (rising) edge + * Clock polarity: 1; clock is high when idle + * Data size: 8 bits + * + * Use spix_set_mode() to change the spi mode. */ -void spi_enable(void); +void spix_init(uint8_t spi); -/** \brief Disables the SPI peripheral +/** + * \brief Enables the SPI peripheral for the instance given + */ +void spix_enable(uint8_t spi); + +/** + * \brief Disables the SPI peripheral for the instance given * \note Call this function to save power when the SPI is unused. */ -void spi_disable(void); +void spix_disable(uint8_t spi); + +/** + * \brief Configure the SPI data and clock polarity and the data size for the + * instance given + * + * This function configures the SSI peripheral to use a particular SPI + * configuration that a slave device requires. It should always be called + * before using the SPI bus as another driver could have changed the settings. + * + * See section 19.4.4 in the CC2538 user guide for more information. + * + * \param spi The SSI instance to use. + * \param frame_format Set the SSI frame format. Use SSI_CR0_FRF_MOTOROLA, + * SSI_CR0_FRF_TI, or SSI_CR0_FRF_MICROWIRE. + * \param clock_polarity In Motorola mode, set whether the clock is high or low + * when idle. Use SSI_CR0_SPO or 0. + * \param clock_phase In Motorola mode, select whether data is valid on the + * first or second edge of the clock. Use SSI_CR0_SPH or 0. + * \param data_size The number of bits in each "byte" of data. Must be + * between 4 and 16, inclusive. + */ +void spix_set_mode(uint8_t spi, uint32_t frame_format, + uint32_t clock_polarity, uint32_t clock_phase, + uint32_t data_size); + +/** + * \brief Configure a GPIO to be the chip select pin. + * + * Even if this function does not depend on the SPI instance used, we rename + * it to reflect the new naming convention. + */ +void spix_cs_init(uint8_t port, uint8_t pin); /** @} */ #endif /* SPI_ARCH_H_ */ /** - * @} * @} */ diff --git a/platform/cc2538dk/startup-gcc.c b/cpu/cc2538/startup-gcc.c similarity index 88% rename from platform/cc2538dk/startup-gcc.c rename to cpu/cc2538/startup-gcc.c index 860a481d2..e09356e4d 100644 --- a/platform/cc2538dk/startup-gcc.c +++ b/cpu/cc2538/startup-gcc.c @@ -34,13 +34,13 @@ * @{ * * \file - * Startup code for the cc2538dk platform, to be used when building with gcc + * Startup code for the cc2538 chip, to be used when building with gcc */ #include "contiki.h" #include "reg.h" -#include "flash-cca.h" +#include "flash.h" #include "sys-ctrl.h" -#include "uart.h" +#include "rom-util.h" #include /*---------------------------------------------------------------------------*/ @@ -62,15 +62,8 @@ void cc2538_rf_rx_tx_isr(void); void cc2538_rf_err_isr(void); void udma_isr(void); void udma_err_isr(void); - -/* Boot Loader Backdoor selection */ -#if FLASH_CCA_CONF_BOOTLDR_BACKDOOR -/* Backdoor enabled, on PA_3 (Select button) */ -#define FLASH_CCA_BOOTLDR_CFG (FLASH_CCA_BOOTLDR_CFG_ENABLE \ - | ((3 << FLASH_CCA_BOOTLDR_CFG_PORT_A_PIN_S) & FLASH_CCA_BOOTLDR_CFG_PORT_A_PIN_M)) -#else -#define FLASH_CCA_BOOTLDR_CFG FLASH_CCA_BOOTLDR_CFG_DISABLE -#endif +void crypto_isr(void); +void pka_isr(void); /* Link in the USB ISR only if USB is enabled */ #if USB_SERIAL_CONF_ENABLE @@ -81,40 +74,38 @@ void usb_isr(void); /* Likewise for the UART[01] ISRs */ #if UART_CONF_ENABLE -void uart_isr(void); - -#if UART_BASE==UART_1_BASE -#define uart0_isr default_handler -#define uart1_isr uart_isr -#else -#define uart0_isr uart_isr -#define uart1_isr default_handler -#endif - +void uart0_isr(void); +void uart1_isr(void); #else /* UART_CONF_ENABLE */ #define uart0_isr default_handler #define uart1_isr default_handler #endif /* UART_CONF_ENABLE */ + +/* Boot Loader Backdoor selection */ +#if FLASH_CCA_CONF_BOOTLDR_BACKDOOR +/* Backdoor enabled */ + +#if FLASH_CCA_CONF_BOOTLDR_BACKDOOR_ACTIVE_HIGH +#define FLASH_CCA_BOOTLDR_CFG_ACTIVE_LEVEL FLASH_CCA_BOOTLDR_CFG_ACTIVE_HIGH +#else +#define FLASH_CCA_BOOTLDR_CFG_ACTIVE_LEVEL 0 +#endif + +#if ((FLASH_CCA_CONF_BOOTLDR_BACKDOOR_PORT_A_PIN < 0) || (FLASH_CCA_CONF_BOOTLDR_BACKDOOR_PORT_A_PIN > 7)) +#error Invalid boot loader backdoor pin. Please set FLASH_CCA_CONF_BOOTLDR_BACKDOOR_PORT_A_PIN between 0 and 7 (indicating PA0 - PA7). +#endif + +#define FLASH_CCA_BOOTLDR_CFG (FLASH_CCA_BOOTLDR_CFG_ENABLE \ + | FLASH_CCA_BOOTLDR_CFG_ACTIVE_LEVEL \ + | (FLASH_CCA_CONF_BOOTLDR_BACKDOOR_PORT_A_PIN << FLASH_CCA_BOOTLDR_CFG_PORT_A_PIN_S)) +#else +#define FLASH_CCA_BOOTLDR_CFG FLASH_CCA_BOOTLDR_CFG_DISABLE +#endif /*---------------------------------------------------------------------------*/ /* Allocate stack space */ -static unsigned long stack[512]; +static uint64_t stack[256] __attribute__ ((section(".stack"))); /*---------------------------------------------------------------------------*/ -/* Linker construct indicating .text section location */ -extern uint8_t _text[0]; -/*---------------------------------------------------------------------------*/ -__attribute__ ((section(".flashcca"), used)) -const flash_cca_lock_page_t __cca = { - FLASH_CCA_BOOTLDR_CFG, /* Boot loader backdoor configuration */ - FLASH_CCA_IMAGE_VALID, /* Image valid */ - &_text, /* Vector table located at the start of .text */ - /* Unlock all pages and debug */ - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } -}; -/*---------------------------------------------------------------------------*/ -__attribute__ ((section(".vectors"), used)) +__attribute__((__section__(".vectors"))) void(*const vectors[])(void) = { (void (*)(void))((unsigned long)stack + sizeof(stack)), /* Stack pointer */ @@ -276,18 +267,30 @@ void(*const vectors[])(void) = usb_isr, /* 156 USB */ cc2538_rf_rx_tx_isr, /* 157 RFCORE RX/TX */ cc2538_rf_err_isr, /* 158 RFCORE Error */ - default_handler, /* 159 AES */ - default_handler, /* 160 PKA */ + crypto_isr, /* 159 AES */ + pka_isr, /* 160 PKA */ rtimer_isr, /* 161 SM Timer */ default_handler, /* 162 MACTimer */ }; /*---------------------------------------------------------------------------*/ +__attribute__((__section__(".flashcca"))) +const flash_cca_lock_page_t flash_cca_lock_page = { + FLASH_CCA_BOOTLDR_CFG, /* Boot loader backdoor configuration */ + FLASH_CCA_IMAGE_VALID, /* Image valid */ + &vectors, /* Vector table */ + /* Unlock all pages and debug */ + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } +}; +/*---------------------------------------------------------------------------*/ /* Linker constructs indicating .data and .bss segment locations */ -extern unsigned long _etext; -extern unsigned long _data; -extern unsigned long _edata; -extern unsigned long _bss; -extern unsigned long _ebss; +extern uint8_t _ldata; +extern uint8_t _data; +extern uint8_t _edata; +extern uint8_t _bss; +extern uint8_t _ebss; /*---------------------------------------------------------------------------*/ /* Weak interrupt handlers. */ void @@ -306,26 +309,13 @@ default_handler(void) void reset_handler(void) { - unsigned long *pul_src, *pul_dst; - REG(SYS_CTRL_EMUOVR) = 0xFF; /* Copy the data segment initializers from flash to SRAM. */ - pul_src = &_etext; - - for(pul_dst = &_data; pul_dst < &_edata;) { - *pul_dst++ = *pul_src++; - } + rom_util_memcpy(&_data, &_ldata, &_edata - &_data); /* Zero-fill the bss segment. */ - __asm(" ldr r0, =_bss\n" - " ldr r1, =_ebss\n" - " mov r2, #0\n" - " .thumb_func\n" - "zero_loop:\n" - " cmp r0, r1\n" - " it lt\n" - " strlt r2, [r0], #4\n" " blt zero_loop"); + rom_util_memset(&_bss, 0, &_ebss - &_bss); /* call the application's entry point. */ main(); diff --git a/cpu/cc2538/usb/usb-arch.c b/cpu/cc2538/usb/usb-arch.c index c209d7778..ed771ce83 100644 --- a/cpu/cc2538/usb/usb-arch.c +++ b/cpu/cc2538/usb/usb-arch.c @@ -872,7 +872,7 @@ fill_buffers(usb_buffer *buffer, uint8_t hw_ep, unsigned int len, static uint8_t ep0_get_setup_pkt(void) { - uint8_t res; + uint8_t res = 0; usb_buffer *buffer = skip_buffers_until(usb_endpoints[0].buffer, USB_BUFFER_SETUP, USB_BUFFER_SETUP, &res); @@ -916,8 +916,6 @@ ep0_get_data_pkt(void) } if(buffer->flags & (USB_BUFFER_SETUP | USB_BUFFER_IN)) { - uint8_t temp; - buffer->flags |= USB_BUFFER_FAILED; buffer->flags &= ~USB_BUFFER_SUBMITTED; if(buffer->flags & USB_BUFFER_NOTIFY) { @@ -925,7 +923,7 @@ ep0_get_data_pkt(void) } /* Flush the fifo */ while(len--) { - temp = REG(USB_F0); + REG(USB_F0); } usb_endpoints[0].buffer = buffer->next; /* Force data stage end */ diff --git a/cpu/cc253x/8051def.h b/cpu/cc253x/8051def.h index 03dfc810e..e16cf3c2e 100644 --- a/cpu/cc253x/8051def.h +++ b/cpu/cc253x/8051def.h @@ -14,11 +14,6 @@ #include -/* In watchdog mode, our WDT can't be stopped once started - * Include watchdog_stop()'s declaration and then trash it */ -#include "dev/watchdog.h" -#define watchdog_stop() watchdog_periodic() - /* This port no longer implements the legacy clock_delay. Hack its usages * outta the way till it gets phased out completely * NB: This also overwrites the prototype so delay_usec() is declared twice */ @@ -43,7 +38,6 @@ #endif #define CC_CONF_FUNCTION_POINTER_ARGS 1 -#define CC_CONF_FASTCALL #define CC_CONF_VA_ARGS 1 #define CC_CONF_UNSIGNED_CHAR_BUGS 0 #define CC_CONF_REGISTER_ARGS 0 diff --git a/cpu/cc253x/Makefile.cc253x b/cpu/cc253x/Makefile.cc253x index 9d3c3a819..e9aaa8c0f 100644 --- a/cpu/cc253x/Makefile.cc253x +++ b/cpu/cc253x/Makefile.cc253x @@ -51,9 +51,9 @@ endif ### Banking Guesswork: ### Generic examples do not specify banking. ### We automatically turn it on if its unspecified and if we are building with -### UIP_CONF_IPV6 +### CONTIKI_WITH_IPV6 ifndef HAVE_BANKING - ifeq ($(UIP_CONF_IPV6),1) + ifeq ($(CONTIKI_WITH_IPV6),1) HAVE_BANKING=1 else HAVE_BANKING=0 diff --git a/cpu/cc253x/dev/cc2530-rf.c b/cpu/cc253x/dev/cc2530-rf.c index d9af05e1a..55e7d3125 100644 --- a/cpu/cc253x/dev/cc2530-rf.c +++ b/cpu/cc253x/dev/cc2530-rf.c @@ -96,6 +96,10 @@ /* 192 ms, radio off -> on interval */ #define ONOFF_TIME RTIMER_ARCH_SECOND / 3125 +#define CC2530_RF_CHANNEL_SET_ERROR -1 + +#define CC2530_RF_TX_POWER_TXCTRL_MIN_VAL 0x09 /* Value for min TX Power */ +#define CC2530_RF_TX_POWER_TXCTRL_DEF_VAL 0x69 /* Reset Value */ /*---------------------------------------------------------------------------*/ #if CC2530_RF_CONF_HEXDUMP #include "dev/io-arch.h" @@ -114,50 +118,215 @@ static int on(void); /* prepare() needs our prototype */ static int off(void); /* transmit() needs our prototype */ static int channel_clear(void); /* transmit() needs our prototype */ /*---------------------------------------------------------------------------*/ -int8_t -cc2530_rf_channel_set(uint8_t channel) +/* TX Power dBm lookup table. Values from SmartRF Studio v1.16.0 */ +typedef struct output_config { + radio_value_t power; + uint8_t txpower_val; +} output_config_t; + +static const output_config_t output_power[] = { + { 5, 0xF5 }, /* 4.5 */ + { 3, 0xE5 }, /* 2.5 */ + { 1, 0xD5 }, + { 0, 0xC5 }, /* -0.5 */ + { -1, 0xB5 }, /* -1.5 */ + { -3, 0xA5 }, + { -4, 0x95 }, + { -6, 0x85 }, + { -8, 0x75 }, + {-10, 0x65 }, + {-12, 0x55 }, + {-14, 0x45 }, + {-16, 0x35 }, + {-18, 0x25 }, + {-20, 0x15 }, + {-22, 0x05 }, + {-28, 0x05 }, /* TXCTRL must be set to 0x09 */ +}; + +#define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t)) + +/* Max and Min Output Power in dBm */ +#define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].power) +#define OUTPUT_POWER_MAX (output_power[0].power) +/*---------------------------------------------------------------------------*/ +/** + * \brief Get the current operating channel + * \return Returns a value in [11,26] representing the current channel + */ +static uint8_t +get_channel() +{ + return (uint8_t)((FREQCTRL + 44) / 5); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Set the current operating channel + * \param channel The desired channel as a value in [11,26] + * \return Returns a value in [11,26] representing the current channel + * or a negative value if \e channel was out of bounds + */ +static int8_t +set_channel(uint8_t channel) { PUTSTRING("RF: Set Chan\n"); if((channel < CC2530_RF_CHANNEL_MIN) || (channel > CC2530_RF_CHANNEL_MAX)) { - return -1; + return CC2530_RF_CHANNEL_SET_ERROR; } + /* Changes to FREQCTRL take effect after the next recalibration */ /* Changes to FREQCTRL take effect after the next recalibration */ off(); FREQCTRL = (CC2530_RF_CHANNEL_MIN + (channel - CC2530_RF_CHANNEL_MIN) * CC2530_RF_CHANNEL_SPACING); on(); - return (int8_t) channel; + return (int8_t)channel; } /*---------------------------------------------------------------------------*/ -uint8_t -cc2530_rf_power_set(uint8_t new_power) +static radio_value_t +get_pan_id(void) { - PUTSTRING("RF: Set Power\n"); - /* off() */ - TXPOWER = new_power; - /* on() */ - - return TXPOWER; + return (radio_value_t)(PAN_ID1 << 8 | PAN_ID0); } /*---------------------------------------------------------------------------*/ -void -cc2530_rf_set_addr(uint16_t pan) +static void +set_pan_id(uint16_t pan) { -#if LINKADDR_SIZE==8 /* EXT_ADDR[7:0] is ignored when using short addresses */ - int i; - for(i = (LINKADDR_SIZE - 1); i >= 0; --i) { - ((uint8_t *)&EXT_ADDR0)[i] = linkaddr_node_addr.u8[LINKADDR_SIZE - 1 - i]; - } -#endif - PAN_ID0 = pan & 0xFF; PAN_ID1 = pan >> 8; +} +/*---------------------------------------------------------------------------*/ +static radio_value_t +get_short_addr(void) +{ + return (radio_value_t)(SHORT_ADDR1 << 8 | SHORT_ADDR0); +} +/*---------------------------------------------------------------------------*/ +static void +set_short_addr(uint16_t addr) +{ + SHORT_ADDR0 = addr & 0xFF; + SHORT_ADDR1 = addr >> 8; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Reads the current signal strength (RSSI) + * \return The current RSSI in dBm + * + * This function reads the current RSSI on the currently configured + * channel. + */ +static radio_value_t +get_rssi(void) +{ + int8_t rssi; - SHORT_ADDR0 = linkaddr_node_addr.u8[LINKADDR_SIZE - 1]; - SHORT_ADDR1 = linkaddr_node_addr.u8[LINKADDR_SIZE - 2]; + /* If we are off, turn on first */ + if(RXENABLE == 0) { + rf_flags |= WAS_OFF; + on(); + } + + /* Wait on RSSI_VALID */ + while((RSSISTAT & RSSISTAT_RSSI_VALID) == 0); + + rssi = (radio_value_t)RSSI - RSSI_OFFSET; + + /* If we were off, turn back off */ + if((rf_flags & WAS_OFF) == WAS_OFF) { + rf_flags &= ~WAS_OFF; + off(); + } + + return rssi; +} +/*---------------------------------------------------------------------------*/ +/* Returns the current CCA threshold in dBm */ +static radio_value_t +get_cca_threshold(void) +{ + return (int8_t)CCACTRL0 - RSSI_OFFSET; +} +/*---------------------------------------------------------------------------*/ +/* Sets the CCA threshold in dBm */ +static void +set_cca_threshold(radio_value_t value) +{ + CCACTRL0 = (value + RSSI_OFFSET) & 0xFF; +} +/*---------------------------------------------------------------------------*/ +/* Returns the current TX power in dBm */ +static radio_value_t +get_tx_power(void) +{ + int i; + uint8_t reg_val = TXPOWER; + + if(TXCTRL == CC2530_RF_TX_POWER_TXCTRL_MIN_VAL) { + return OUTPUT_POWER_MIN; + } + + /* + * Find the TXPOWER value in the lookup table + * If the value has been written with set_tx_power, we should be able to + * find the exact value. However, in case the register has been written in + * a different fashion, we return the immediately lower value of the lookup + */ + for(i = 0; i < OUTPUT_CONFIG_COUNT; i++) { + if(reg_val >= output_power[i].txpower_val) { + return output_power[i].power; + } + } + return OUTPUT_POWER_MIN; +} +/*---------------------------------------------------------------------------*/ +/* + * Set TX power to 'at least' power dBm + * This works with a lookup table. If the value of 'power' does not exist in + * the lookup table, TXPOWER will be set to the immediately higher available + * value + */ +static void +set_tx_power(radio_value_t power) +{ + int i; + + if(power <= output_power[OUTPUT_CONFIG_COUNT - 1].power) { + TXCTRL = CC2530_RF_TX_POWER_TXCTRL_MIN_VAL; + TXPOWER = output_power[OUTPUT_CONFIG_COUNT - 1].txpower_val; + return; + } + + for(i = OUTPUT_CONFIG_COUNT - 2; i >= 0; --i) { + if(power <= output_power[i].power) { + /* Perhaps an earlier call set TXCTRL to 0x09. Restore */ + TXCTRL = CC2530_RF_TX_POWER_TXCTRL_DEF_VAL; + TXPOWER = output_power[i].txpower_val; + return; + } + } +} +/*---------------------------------------------------------------------------*/ +static void +set_frame_filtering(uint8_t enable) +{ + if(enable) { + FRMFILT0 |= FRMFILT0_FRAME_FILTER_EN; + } else { + FRMFILT0 &= ~FRMFILT0_FRAME_FILTER_EN; + } +} +/*---------------------------------------------------------------------------*/ +static void +set_auto_ack(uint8_t enable) +{ + if(enable) { + FRMCTRL0 |= FRMCTRL0_AUTOACK; + } else { + FRMCTRL0 &= ~FRMCTRL0_AUTOACK; + } } /*---------------------------------------------------------------------------*/ /* Netstack API radio driver functions */ @@ -204,8 +373,7 @@ init(void) /* MAX FIFOP threshold */ FIFOPCTRL = CC2530_RF_MAX_PACKET_LEN; - cc2530_rf_power_set(CC2530_RF_TX_POWER); - cc2530_rf_channel_set(CC2530_RF_CHANNEL); + TXPOWER = CC2530_RF_TX_POWER; RF_TX_LED_OFF(); RF_RX_LED_OFF(); @@ -318,7 +486,7 @@ transmit(unsigned short transmit_len) } /*---------------------------------------------------------------------------*/ static int -send(void *payload, unsigned short payload_len) +send(const void *payload, unsigned short payload_len) { prepare(payload, payload_len); return transmit(payload_len); @@ -483,6 +651,154 @@ off(void) return 1; } /*---------------------------------------------------------------------------*/ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + if(!value) { + return RADIO_RESULT_INVALID_VALUE; + } + + switch(param) { + case RADIO_PARAM_POWER_MODE: + *value = RXENABLE == 0 ? RADIO_POWER_MODE_OFF : RADIO_POWER_MODE_ON; + return RADIO_RESULT_OK; + case RADIO_PARAM_CHANNEL: + *value = (radio_value_t)get_channel(); + return RADIO_RESULT_OK; + case RADIO_PARAM_PAN_ID: + *value = get_pan_id(); + return RADIO_RESULT_OK; + case RADIO_PARAM_16BIT_ADDR: + *value = get_short_addr(); + return RADIO_RESULT_OK; + case RADIO_PARAM_RX_MODE: + *value = 0; + if(FRMFILT0 & FRMFILT0_FRAME_FILTER_EN) { + *value |= RADIO_RX_MODE_ADDRESS_FILTER; + } + if(FRMCTRL0 & FRMCTRL0_AUTOACK) { + *value |= RADIO_RX_MODE_AUTOACK; + } + return RADIO_RESULT_OK; + case RADIO_PARAM_TXPOWER: + *value = get_tx_power(); + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + *value = get_cca_threshold(); + return RADIO_RESULT_OK; + case RADIO_PARAM_RSSI: + *value = get_rssi(); + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MIN: + *value = CC2530_RF_CHANNEL_MIN; + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MAX: + *value = CC2530_RF_CHANNEL_MAX; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MIN: + *value = OUTPUT_POWER_MIN; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MAX: + *value = OUTPUT_POWER_MAX; + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + switch(param) { + case RADIO_PARAM_POWER_MODE: + if(value == RADIO_POWER_MODE_ON) { + on(); + return RADIO_RESULT_OK; + } + if(value == RADIO_POWER_MODE_OFF) { + off(); + return RADIO_RESULT_OK; + } + return RADIO_RESULT_INVALID_VALUE; + case RADIO_PARAM_CHANNEL: + if(value < CC2530_RF_CHANNEL_MIN || value > CC2530_RF_CHANNEL_MAX) { + return RADIO_RESULT_INVALID_VALUE; + } + if(set_channel(value) == CC2530_RF_CHANNEL_SET_ERROR) { + return RADIO_RESULT_ERROR; + } + return RADIO_RESULT_OK; + case RADIO_PARAM_PAN_ID: + set_pan_id(value & 0xffff); + return RADIO_RESULT_OK; + case RADIO_PARAM_16BIT_ADDR: + set_short_addr(value & 0xffff); + return RADIO_RESULT_OK; + case RADIO_PARAM_RX_MODE: + if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER | + RADIO_RX_MODE_AUTOACK)) { + return RADIO_RESULT_INVALID_VALUE; + } + + set_frame_filtering((value & RADIO_RX_MODE_ADDRESS_FILTER) != 0); + set_auto_ack((value & RADIO_RX_MODE_AUTOACK) != 0); + + return RADIO_RESULT_OK; + case RADIO_PARAM_TXPOWER: + if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) { + return RADIO_RESULT_INVALID_VALUE; + } + + set_tx_power(value); + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + set_cca_threshold(value); + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + uint8_t *target; + int i; + + if(param == RADIO_PARAM_64BIT_ADDR) { + if(size != 8 || !dest) { + return RADIO_RESULT_INVALID_VALUE; + } + + target = dest; + for(i = 0; i < 8; i++) { + target[i] = ((uint8_t *)&EXT_ADDR0)[7 - i] & 0xFF; + } + + return RADIO_RESULT_OK; + } + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + int i; + + if(param == RADIO_PARAM_64BIT_ADDR) { + if(size != 8 || !src) { + return RADIO_RESULT_INVALID_VALUE; + } + + for(i = 0; i < 8; i++) { + ((uint8_t *)&EXT_ADDR0)[i] = ((uint8_t *)src)[7 - i]; + } + + return RADIO_RESULT_OK; + } + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ const struct radio_driver cc2530_rf_driver = { init, prepare, @@ -494,5 +810,9 @@ const struct radio_driver cc2530_rf_driver = { pending_packet, on, off, + get_value, + set_value, + get_object, + set_object }; /*---------------------------------------------------------------------------*/ diff --git a/cpu/cc253x/dev/cc2530-rf.h b/cpu/cc253x/dev/cc2530-rf.h index f5722db5f..4e092ca7a 100644 --- a/cpu/cc253x/dev/cc2530-rf.h +++ b/cpu/cc253x/dev/cc2530-rf.h @@ -120,9 +120,6 @@ /*---------------------------------------------------------------------------*/ extern const struct radio_driver cc2530_rf_driver; /*---------------------------------------------------------------------------*/ -int8_t cc2530_rf_channel_set(uint8_t channel); -#define cc2530_rf_channel_get() ((uint8_t)((FREQCTRL + 44) / 5)) -uint8_t cc2530_rf_power_set(uint8_t new_power); void cc2530_rf_set_addr(uint16_t pan); /*---------------------------------------------------------------------------*/ #endif /* CC2530_RF_H_ */ diff --git a/cpu/cc253x/dev/clock.c b/cpu/cc253x/dev/clock.c index ff1c4cf4a..e78635361 100644 --- a/cpu/cc253x/dev/clock.c +++ b/cpu/cc253x/dev/clock.c @@ -70,7 +70,7 @@ clock_delay_usec(uint16_t len) ENABLE_INTERRUPTS(); } /*---------------------------------------------------------------------------*/ -/** +/* * Wait for a multiple of ~8 ms (a tick) */ void diff --git a/cpu/cc253x/dev/uart0.c b/cpu/cc253x/dev/uart0.c index a6a358a18..f5dc35640 100644 --- a/cpu/cc253x/dev/uart0.c +++ b/cpu/cc253x/dev/uart0.c @@ -39,7 +39,7 @@ uart0_init() #else PERCFG &= ~PERCFG_U0CFG; /* alternative port 1 = P0.5-2 */ #ifdef UART0_RTSCTS - P0SEL |= 0x20 | 0x10; /* peripheral select for TX and RX */ + P0SEL |= 0x3C; /* peripheral select for RTS and CTS, TX, RX */ #else P0SEL |= 0x0C; /* peripheral select for TX and RX */ P0 &= ~0x20; /* RTS down */ diff --git a/cpu/cc253x/sfr-bits.h b/cpu/cc253x/sfr-bits.h index 7a4d72cac..09173cf18 100644 --- a/cpu/cc253x/sfr-bits.h +++ b/cpu/cc253x/sfr-bits.h @@ -184,6 +184,9 @@ /*--------------------------------------------------------------------------- * Radio Register Bits *---------------------------------------------------------------------------*/ +/* FRMFILT0 */ +#define FRMFILT0_FRAME_FILTER_EN 0x01 + /* FRMCTRL0 */ #define FRMCTRL0_APPEND_DATA_MODE 0x80 #define FRMCTRL0_AUTOCRC 0x40 diff --git a/cpu/cc26xx-cc13xx/Makefile.cc13xx b/cpu/cc26xx-cc13xx/Makefile.cc13xx new file mode 100644 index 000000000..56593ee9f --- /dev/null +++ b/cpu/cc26xx-cc13xx/Makefile.cc13xx @@ -0,0 +1,7 @@ +TI_XXWARE_PATH = lib/cc13xxware + +CONTIKI_CPU_SOURCEFILES += smartrf-settings.c prop-mode.c + +CFLAGS += -DCPU_FAMILY_CC13XX=1 + +include $(CONTIKI_CPU)/Makefile.cc26xx-cc13xx diff --git a/cpu/cc26xx-cc13xx/Makefile.cc26xx b/cpu/cc26xx-cc13xx/Makefile.cc26xx new file mode 100644 index 000000000..4bc2cdcad --- /dev/null +++ b/cpu/cc26xx-cc13xx/Makefile.cc26xx @@ -0,0 +1,3 @@ +TI_XXWARE_PATH = lib/cc26xxware + +include $(CONTIKI_CPU)/Makefile.cc26xx-cc13xx diff --git a/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx b/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx new file mode 100644 index 000000000..6922b45fc --- /dev/null +++ b/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx @@ -0,0 +1,164 @@ +CC = arm-none-eabi-gcc +CPP = arm-none-eabi-cpp +LD = arm-none-eabi-gcc +AR = arm-none-eabi-ar +OBJCOPY = arm-none-eabi-objcopy +OBJDUMP = arm-none-eabi-objdump +NM = arm-none-eabi-nm +SIZE = arm-none-eabi-size +SREC_CAT = srec_cat + +CPU_ABS_PATH = cpu/cc26xx-cc13xx +TI_XXWARE = $(CONTIKI_CPU)/$(TI_XXWARE_PATH) + +### cc26xxware sources under driverlib will be added to the MODULES list +TI_XXWARE_SRC = $(CPU_ABS_PATH)/$(TI_XXWARE_PATH)/driverlib + +### The directory with startup sources will be added to the CONTIKI_CPU_DIRS +### and the sources therein are added to the sources list explicitly. They are +### also listed explicitly in the linker command (through TARGET_STARTFILES), +### to make sure they always get linked in the image +TI_XXWARE_STARTUP_DIR = $(TI_XXWARE_PATH)/startup_files +TI_XXWARE_STARTUP_SRCS = ccfg.c startup_gcc.c + +### MODULES will add some of these to the include path, but we need to add +### them earlier to prevent filename clashes with Contiki core files +CFLAGS += -I$(TI_XXWARE) -I$(CONTIKI)/$(TI_XXWARE_SRC) +CFLAGS += -I$(TI_XXWARE)/inc +MODULES += $(TI_XXWARE_SRC) + +LDSCRIPT = $(CONTIKI_CPU)/cc26xx.ld + +CFLAGS += -mcpu=cortex-m3 -mthumb -mlittle-endian +CFLAGS += -ffunction-sections -fdata-sections +CFLAGS += -fshort-enums -fomit-frame-pointer -fno-strict-aliasing +CFLAGS += -Wall -std=c99 + +LDFLAGS += -mcpu=cortex-m3 -mthumb -mlittle-endian -nostartfiles +LDFLAGS += -T $(LDSCRIPT) +LDFLAGS += -Wl,--gc-sections,--sort-section=alignment +LDFLAGS += -Wl,-Map=$(@:.elf=-$(TARGET).map),--cref,--no-warn-mismatch +OBJCOPY_FLAGS += -O binary --gap-fill 0xff +OBJDUMP_FLAGS += --disassemble --source --disassembler-options=force-thumb + +ifdef WERROR +CFLAGS += -Werror +endif + +### Are we building with code size optimisations? +ifeq ($(SMALL),1) + CFLAGS += -Os +else + CFLAGS += -O2 +endif + +### If the user-specified a Node ID, pass a define +ifdef NODEID + CFLAGS += -DIEEE_ADDR_NODE_ID=$(NODEID) +endif + +### CPU-dependent cleanup files +CLEAN += symbols.c symbols.h *.d *.elf *.hex + +### CPU-dependent directories +CONTIKI_CPU_DIRS = . dev rf-core rf-core/api $(TI_XXWARE_STARTUP_DIR) + +### Use the existing debug I/O in cpu/arm/common +CONTIKI_CPU_DIRS += ../arm/common/dbg-io + +### CPU-dependent source files +CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c soc-rtc.c uart.c +CONTIKI_CPU_SOURCEFILES += contiki-watchdog.c aux-ctrl.c +CONTIKI_CPU_SOURCEFILES += putchar.c ieee-addr.c batmon-sensor.c adc-sensor.c +CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c cc26xx-uart.c lpm.c +CONTIKI_CPU_SOURCEFILES += gpio-interrupt.c oscillators.c +CONTIKI_CPU_SOURCEFILES += rf-core.c rf-ble.c ieee-mode.c + +DEBUG_IO_SOURCEFILES += dbg-printf.c dbg-snprintf.c dbg-sprintf.c strformat.c + +CONTIKI_SOURCEFILES += $(CONTIKI_CPU_SOURCEFILES) $(DEBUG_IO_SOURCEFILES) + +TARGET_START_SOURCEFILES += fault-handlers.c $(TI_XXWARE_STARTUP_SRCS) +TARGET_STARTFILES = $(addprefix $(OBJECTDIR)/,$(call oname, $(TARGET_START_SOURCEFILES))) + +PYTHON = python +BSL_FLAGS += -e -w -v + +ifdef PORT + BSL_FLAGS += -p $(PORT) +endif + +BSL = $(CONTIKI)/tools/cc2538-bsl/cc2538-bsl.py + +### Don't treat the .elf as intermediate +.PRECIOUS: %.elf %.hex %.bin + +### Always re-build ieee-addr.o in case the command line passes a new NODEID +FORCE: + +$(OBJECTDIR)/ieee-addr.o: ieee-addr.c FORCE | $(OBJECTDIR) + $(TRACE_CC) + $(Q)$(CC) $(CFLAGS) -c $< -o $@ + +### Compilation rules +CUSTOM_RULE_LINK=1 + +%.elf: $(TARGET_STARTFILES) %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a $(LDSCRIPT) + $(TRACE_LD) + $(Q)$(LD) $(LDFLAGS) ${filter-out $(LDSCRIPT) %.a,$^} ${filter %.a,$^} $(TARGET_LIBFILES) -lm -o $@ + +%.i16hex: %.elf + $(OBJCOPY) -O ihex $< $@ + +%.hex: %.i16hex + $(SREC_CAT) $< -intel -o $@ -intel + +%.bin: %.elf + $(OBJCOPY) $(OBJCOPY_FLAGS) $< $@ + +%.lst: %.elf + $(OBJDUMP) $(OBJDUMP_FLAGS) $< > $@ + +### We don't really need the .hex and .bin for the .$(TARGET) but let's make +### sure they get built +%.$(TARGET): %.elf %.hex %.bin + cp $< $@ + +# a target that gives a user-friendly memory profile, taking into account the RAM +# that is statically occupied by the stack as defined in the linker script +# see $(LDSCRIPT) +RAM_SIZE = 0x00003E00 +FLASH_SIZE = 0x0001E000 +STACK_SIZE = 0 +%.size: %.$(TARGET) + @$(SIZE) -A $< | egrep "data|bss" | awk '{s+=$$2} END {s=s+$(STACK_SIZE); f=$(RAM_SIZE)-s; printf "[RAM] used %6d, free %6d\n",s,f;}' + @$(SIZE) -A $< | egrep "text|isr_vector" | awk '{s+=$$2} END {f=$(FLASH_SIZE)-s; printf "[Flash] used %6d, free %6d\n",s,f;}' + +ifeq ($(BOARD_SUPPORTS_BSL),1) +%.upload: %.bin +ifeq ($(wildcard $(BSL)), ) + @echo "ERROR: Could not find the cc2538-bsl script. Did you run 'git submodule update --init' ?" +else + $(PYTHON) $(BSL) $(BSL_FLAGS) $< +endif +else +%.upload: + @echo "This board cannot be programmed through the ROM bootloader and therefore does not support the .upload target." +endif + +# Check if we are running under Windows +ifeq ($(HOST_OS),Windows) + SERIALDUMP ?= $(CONTIKI)/tools/sky/serialdump-windows +else +ifeq ($(HOST_OS),Darwin) + SERIALDUMP ?= $(CONTIKI)/tools/sky/serialdump-macos +else + # Else assume Linux + SERIALDUMP ?= $(CONTIKI)/tools/sky/serialdump-linux +endif +endif + +UART_BAUDRATE = 115200 + +login: + $(SERIALDUMP) -b$(UART_BAUDRATE) $(PORT) diff --git a/cpu/cc26xx-cc13xx/cc26xx.ld b/cpu/cc26xx-cc13xx/cc26xx.ld new file mode 100644 index 000000000..84601ced6 --- /dev/null +++ b/cpu/cc26xx-cc13xx/cc26xx.ld @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ + +/* CC26XX linker script */ + +/* Entry Point */ +ENTRY(ResetISR) + +MEMORY +{ + /* Flash Size 128 KB minus the CCA area below (88 bytes) */ + FLASH (RX) : ORIGIN = 0x00000000, LENGTH = 0x0001FFA8 + + /* + * Customer Configuration Area and Bootloader Backdoor configuration + * in flash, up to 88 bytes + */ + FLASH_CCFG (RX) : ORIGIN = 0x0001FFA8, LENGTH = 88 + + /* RAM Size 20KB */ + SRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 0x00005000 + + /* Application can use GPRAM region as RAM if cache is disabled in CCFG */ + GPRAM (RWX) : ORIGIN = 0x11000000, LENGTH = 0x00002000 +} + +/*. Highest address of the stack. Used in startup file .*/ +_estack = ORIGIN(SRAM) + LENGTH(SRAM); /* End of SRAM */ + +/*. Generate a link error if heap and stack don’t fit into RAM .*/ +_Min_Heap_Size = 0; +_Min_Stack_Size = 0x100; + +SECTIONS +{ + .text : + { + _text = .; + KEEP(*(.vectors)) + *(.text*) + *(.rodata*) + _etext = .; + } > FLASH = 0 + + .data : + { + _data = .; + *(vtable) + *(.data*) + _edata = .; + } > SRAM AT > FLASH + + .ARM.exidx : + { + *(.ARM.exidx*) + } > FLASH + + .bss : + { + _bss = .; + *(.bss*) + *(COMMON) + _ebss = .; + } > SRAM + + .ccfg : + { + KEEP(*(.ccfg)) + } > FLASH_CCFG + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(4); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(4); + } > SRAM + + .gpram : + { + } > GPRAM + +} diff --git a/cpu/cc26xx-cc13xx/clock.c b/cpu/cc26xx-cc13xx/clock.c new file mode 100644 index 000000000..85ea6e444 --- /dev/null +++ b/cpu/cc26xx-cc13xx/clock.c @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup platform + * @{ + * + * \defgroup cc26xx-platforms TI CC26xx-powered Platforms + * @{ + * + * \defgroup cc26xx The TI CC26xx and CC13xx CPUs + * + * This group documents the TI CC26xx and CC13xx CPUs. The two CPU families are + * very similar, with the main difference being related to radio capability. + * + * Documentation in this group should be considered to be applicable to both + * families, unless explicitly stated otherwise. + * + * @{ + * + * \addtogroup cc26xx-clocks + * @{ + * + * \defgroup cc26xx-software-clock Software Clock + * + * Implementation of the clock module for the CC26xx and CC13xx. + * + * The software clock uses the facilities provided by the AON RTC driver + * @{ + * + * \file + * Software clock implementation for the TI CC13xx/CC26xx + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" + +#include "ti-lib.h" +/*---------------------------------------------------------------------------*/ +static volatile uint64_t count; +/*---------------------------------------------------------------------------*/ +static void +power_domain_on(void) +{ + ti_lib_prcm_power_domain_on(PRCM_DOMAIN_PERIPH); + while(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_PERIPH) != + PRCM_DOMAIN_POWER_ON); +} +/*---------------------------------------------------------------------------*/ +void +clock_init(void) +{ + count = 0; + + /* + * Here, we configure GPT0 Timer A, which we subsequently use in + * clock_delay_usec + * + * We need to access registers, so firstly power up the PD and then enable + * the clock to GPT0. + */ + if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_PERIPH) != + PRCM_DOMAIN_POWER_ON) { + power_domain_on(); + } + + ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_TIMER0); + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + /* Disable both GPT0 timers */ + HWREG(GPT0_BASE + GPT_O_CTL) &= ~(GPT_CTL_TAEN | GPT_CTL_TBEN); + + /* + * We assume that the clock is running at 48MHz, we use GPT0 Timer A, + * one-shot, countdown, prescaled by 48 gives us 1 tick per usec + */ + ti_lib_timer_configure(GPT0_BASE, + TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_ONE_SHOT); + + /* Global config: split pair (2 x 16-bit wide) */ + HWREG(GPT0_BASE + GPT_O_CFG) = TIMER_CFG_SPLIT_PAIR >> 24; + + /* + * Pre-scale value 47 pre-scales by 48 + * + * ToDo: The theoretical value here should be 47 (to provide x48 prescale) + * However, 49 seems to give results much closer to the desired delay + */ + ti_lib_timer_prescale_set(GPT0_BASE, TIMER_B, 49); + + /* GPT0 / Timer B: One shot, PWM interrupt enable */ + HWREG(GPT0_BASE + GPT_O_TBMR) = + ((TIMER_CFG_B_ONE_SHOT >> 8) & 0xFF) | GPT_TBMR_TBPWMIE; + + /* enable sync with radio timer */ + HWREGBITW(AON_RTC_BASE + AON_RTC_O_CTL, AON_RTC_CTL_RTC_UPD_EN_BITN) = 1; +} +/*---------------------------------------------------------------------------*/ +static void +update_clock_variable(void) +{ + uint32_t aon_rtc_secs_now; + uint32_t aon_rtc_secs_now2; + uint16_t aon_rtc_ticks_now; + + do { + aon_rtc_secs_now = HWREG(AON_RTC_BASE + AON_RTC_O_SEC); + aon_rtc_ticks_now = HWREG(AON_RTC_BASE + AON_RTC_O_SUBSEC) >> 16; + aon_rtc_secs_now2 = HWREG(AON_RTC_BASE + AON_RTC_O_SEC); + } while(aon_rtc_secs_now != aon_rtc_secs_now2); + + /* Convert AON RTC ticks to clock tick counter */ + count = (aon_rtc_secs_now * CLOCK_SECOND) + (aon_rtc_ticks_now >> 9); +} +/*---------------------------------------------------------------------------*/ +CCIF clock_time_t +clock_time(void) +{ + update_clock_variable(); + + return (clock_time_t)(count & 0xFFFFFFFF); +} +/*---------------------------------------------------------------------------*/ +void +clock_update(void) +{ + update_clock_variable(); + + if(etimer_pending()) { + etimer_request_poll(); + } +} +/*---------------------------------------------------------------------------*/ +CCIF unsigned long +clock_seconds(void) +{ + bool interrupts_disabled; + uint32_t secs_now; + + interrupts_disabled = ti_lib_int_master_disable(); + + secs_now = ti_lib_aon_rtc_sec_get(); + + /* Re-enable interrupts */ + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } + + return (unsigned long)secs_now; +} +/*---------------------------------------------------------------------------*/ +void +clock_wait(clock_time_t i) +{ + clock_time_t start; + + start = clock_time(); + while(clock_time() - start < (clock_time_t)i); +} +/*---------------------------------------------------------------------------*/ +void +clock_delay_usec(uint16_t len) +{ + uint32_t clock_status; + + if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_PERIPH) != + PRCM_DOMAIN_POWER_ON) { + power_domain_on(); + } + + clock_status = HWREG(PRCM_BASE + PRCM_O_GPTCLKGR) & PRCM_GPIOCLKGR_CLK_EN; + + ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_TIMER0); + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + ti_lib_timer_load_set(GPT0_BASE, TIMER_B, len); + ti_lib_timer_enable(GPT0_BASE, TIMER_B); + + /* + * Wait for TBEN to clear. CC26xxware does not provide us with a convenient + * function, hence the direct register access here + */ + while(HWREG(GPT0_BASE + GPT_O_CTL) & GPT_CTL_TBEN); + + if(clock_status == 0) { + ti_lib_prcm_peripheral_run_disable(PRCM_PERIPH_TIMER0); + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Obsolete delay function but we implement it here since some code + * still uses it + */ +void +clock_delay(unsigned int i) +{ + clock_delay_usec(i); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/dbg.h b/cpu/cc26xx-cc13xx/dbg.h new file mode 100644 index 000000000..9b28477f4 --- /dev/null +++ b/cpu/cc26xx-cc13xx/dbg.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx + * @{ + * + * \defgroup cc26xx-char-io CC13xx/CC26xx Character I/O + * + * CC13xx/CC26xx CPU-specific functions for debugging and SLIP I/O + * @{ + * + * \file + * Header file for the CC13xx/CC26xx Debug I/O module + */ +#ifndef DBG_H_ +#define DBG_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +/*---------------------------------------------------------------------------*/ +/** + * \brief Print a stream of bytes + * \param seq A pointer to the stream + * \param len The number of bytes to print + * \return The number of printed bytes + * + * This function is an arch-specific implementation required by the dbg-io + * API in cpu/arm/common/dbg-io. It prints a stream of bytes over the + * peripheral used by the platform. + */ +unsigned int dbg_send_bytes(const unsigned char *seq, unsigned int len); +/*---------------------------------------------------------------------------*/ +#endif /* DBG_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/debug-uart.h b/cpu/cc26xx-cc13xx/debug-uart.h new file mode 100644 index 000000000..c2d9b0ffb --- /dev/null +++ b/cpu/cc26xx-cc13xx/debug-uart.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-char-io + * @{ + * + * \file + * This file is here because DBG I/O expects it to be. It just includes + * our own dbg.h which has a non-misleading name and which also adheres + * to Contiki's naming convention + */ +/*---------------------------------------------------------------------------*/ +#ifndef DEBUG_UART_H_ +#define DEBUG_UART_H_ +/*---------------------------------------------------------------------------*/ +#include "dbg.h" +/*---------------------------------------------------------------------------*/ +#endif /* DEBUG_UART_H_ */ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/cpu/cc26xx-cc13xx/dev/adc-sensor.c b/cpu/cc26xx-cc13xx/dev/adc-sensor.c new file mode 100644 index 000000000..3ccf90e6d --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/adc-sensor.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2016, University of Bristol - http://www.bristol.ac.uk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-adc-sensor + * @{ + * + * \file + * Driver for the CC13xx/CC26xx ADC + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/adc-sensor.h" +#include "gpio-interrupt.h" +#include "sys/timer.h" +#include "lpm.h" + +#include "ti-lib.h" +#include "driverlib/aux_adc.h" +#include "aux-ctrl.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +static uint8_t channel = ADC_COMPB_IN_AUXIO0; +static bool is_active = false; + +static aux_consumer_module_t adc_aux = { + .clocks = AUX_WUC_ADI_CLOCK | AUX_WUC_ANAIF_CLOCK | AUX_WUC_SMPH_CLOCK +}; +/*---------------------------------------------------------------------------*/ +static int +config(int type, int c) +{ + switch(type) { + case SENSORS_ACTIVE: + is_active = c; + + if(is_active) { + /* Request AUX access, with ADI and SMPH clocks */ + aux_ctrl_register_consumer(&adc_aux); + + ti_lib_aux_adc_select_input(channel); + } else { + aux_ctrl_unregister_consumer(&adc_aux); + } + break; + + case ADC_SENSOR_SET_CHANNEL: + channel = c; + if(is_active) { + ti_lib_aux_adc_select_input(channel); + } + break; + + default: + break; + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + if(is_active) { + return 1; + } + break; + default: + break; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if(type == ADC_SENSOR_VALUE) { + int val; + + if(!is_active) { + puts("ADC not active"); + return 0; + } + + ti_lib_aux_adc_enable_sync(AUXADC_REF_FIXED, AUXADC_SAMPLE_TIME_2P7_US, + AUXADC_TRIGGER_MANUAL); + + ti_lib_aux_adc_gen_manual_trigger(); + val = ti_lib_aux_adc_read_fifo(); + + ti_lib_aux_adc_disable(); + + return val; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(adc_sensor, ADC_SENSOR, value, config, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/cpu/cc26xx-cc13xx/dev/adc-sensor.h b/cpu/cc26xx-cc13xx/dev/adc-sensor.h new file mode 100644 index 000000000..fd8f71537 --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/adc-sensor.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016, University of Bristol - http://www.bristol.ac.uk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx + * @{ + * + * \defgroup cc26xx-adc-sensor CC13xx/CC26xx ADC Sensor + * @{ + * + * \file + * Header file for the CC13xx/CC26xx ADC driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef ADC_SENSOR_H_ +#define ADC_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define ADC_SENSOR "ADC" +/*---------------------------------------------------------------------------*/ +#define ADC_SENSOR_VALUE 0 +/*---------------------------------------------------------------------------*/ +/* configuration commands */ +#define ADC_SENSOR_SET_CHANNEL 1 /* takes ADC_COMPB_IN_AUXIxx as parameter */ +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor adc_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* ADC_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/dev/aux-ctrl.c b/cpu/cc26xx-cc13xx/dev/aux-ctrl.c new file mode 100644 index 000000000..eb316d3df --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/aux-ctrl.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2016, University of Bristol - http://www.bris.ac.uk/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/aux-ctrl.h" +#include "lib/list.h" + +#include "ti-lib.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +LIST(consumers_list); +/*---------------------------------------------------------------------------*/ +void +aux_ctrl_register_consumer(aux_consumer_module_t *consumer) +{ + bool interrupts_disabled = ti_lib_int_master_disable(); + + list_add(consumers_list, consumer); + + aux_ctrl_power_up(); + + ti_lib_aux_wuc_clock_enable(consumer->clocks); + while(ti_lib_aux_wuc_clock_status(consumer->clocks) != AUX_WUC_CLOCK_READY); + + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } +} +/*---------------------------------------------------------------------------*/ +void +aux_ctrl_unregister_consumer(aux_consumer_module_t *consumer) +{ + bool interrupts_disabled = ti_lib_int_master_disable(); + + list_remove(consumers_list, consumer); + + aux_ctrl_power_down(false); + + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } +} +/*---------------------------------------------------------------------------*/ +void +aux_ctrl_power_up() +{ + /* Don't if we have no consumers */ + if(list_head(consumers_list) == NULL) { + return; + } + + ti_lib_aon_wuc_aux_wakeup_event(AONWUC_AUX_WAKEUP); + while(!(ti_lib_aon_wuc_power_status_get() & AONWUC_AUX_POWER_ON)); +} +/*---------------------------------------------------------------------------*/ +void +aux_ctrl_power_down(bool force) +{ + aux_consumer_module_t *consumer; + uint32_t clocks_in_use = 0; + + if(!force) { + /* Visit all modules and release clocks */ + for(consumer = list_head(consumers_list); consumer != NULL; + consumer = consumer->next) { + clocks_in_use |= consumer->clocks; + } + + /* If any clocks are still in use, AUX needs to stay powered and clocked */ + if(clocks_in_use) { + ti_lib_aon_wuc_aux_power_down_config(AONWUC_CLOCK_SRC_LF); + return; + } + } + + /* No clock for AUX in power down */ + ti_lib_aon_wuc_aux_power_down_config(AONWUC_NO_CLOCK); + + /* Disable retention */ + ti_lib_aon_wuc_aux_sram_config(false); + + /* Turn off AUX */ + ti_lib_aon_wuc_aux_wakeup_event(AONWUC_AUX_ALLOW_SLEEP); + ti_lib_aux_wuc_power_ctrl(AUX_WUC_POWER_OFF); + while(ti_lib_aon_wuc_power_status_get() & AONWUC_AUX_POWER_ON); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc26xx-cc13xx/dev/aux-ctrl.h b/cpu/cc26xx-cc13xx/dev/aux-ctrl.h new file mode 100644 index 000000000..8e65a7844 --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/aux-ctrl.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2016, University of Bristol - http://www.bris.ac.uk/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx + * @{ + * + * \defgroup cc26xx-aux-ctrl CC13xx/CC26xx AUX domain controller + * + * CC13xx/CC26xx AUX domain power management controller + * + * @{ + * + * \file + * Header file for the management of the CC13xx/CC26xx AUX domain + */ +/*---------------------------------------------------------------------------*/ +#ifndef AUX_CTRL_H_ +#define AUX_CTRL_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" + +#include "ti-lib.h" + +#include +/*---------------------------------------------------------------------------*/ +/** + * \brief The data structure to be used for modules that require access to AUX + * + * The clocks field should specify the clocks (within AUX) that your module + * requires in order to perform its functionality. Those clocks are an ORd + * value of AUX_WUC_xxxx_CLOCK. For instance, the oscillators module specifies + * AUX_WUC_OSCCTRL_CLOCK | AUX_WUC_SMPH_CLOCK + */ +typedef struct aux_consumer_module { + struct aux_consumer_module *next; + uint32_t clocks; +} aux_consumer_module_t; +/*---------------------------------------------------------------------------*/ +/** + * \brief Register a module that no longer requires access to the AUX power domain + * \param consumer A pointer to the data structure of your AUX consumer + * + * Call this function if you are developing a module that requires access to + * hardware within the AUX PD. Calling this function will achieve a number of + * things: + * + * - It will power up the AUX PD + * - It will enable the AUX clocks that you require + * + * If you call this function, AUX will stay powered-on and clocked during deep + * sleep, and retention will be enabled (so that you can e.g. use the sensor + * controller to monitor peripherals while the main MCU in deep sleep). If you + * do not need AUX enabled during deep sleep, you must release it by calling + * aux_ctrl_unregister_consumer() + * + * \sa aux_ctrl_unregister_consumer + */ +void aux_ctrl_register_consumer(aux_consumer_module_t *consumer); + +/** + * \brief Deregister a module that no longer requires access to the AUX power domain + * \param consumer A pointer to the data structure of your AUX consumer + * + * When your module is finished using features provided from within the AUX + * domain, you should call this function to signal that AUX is no longer + * required, so that the LPM module can power it down in deep sleep. If there + * are no more registered consumers left, this function will also power down + * AUX. + * + * \sa aux_ctrl_register_consumer + * \sa aux_ctrl_power_down + */ +void aux_ctrl_unregister_consumer(aux_consumer_module_t *consumer); + +/** + * \brief Power-up the AUX power domain + * + * This function will power up the AUX power-domain, but only if there are + * registered consumers for it. If there are not, the PD will stay off. + * + * This function will automatically get called by the LPM module whenever the + * chip comes out of deep sleep. + * + * User applications will normally not need to call this function. if you are + * developing a user application that requires access, to AUX, you should + * normally call aux_ctrl_register_consumer(), which will automatically power + * up AUX for you, if it's not already powered. + */ +void aux_ctrl_power_up(void); + +/** + * \brief Power down the AUX power domain + * \param force Force the power down irrespective of registered consumers + * + * This function will shut down the AUX power-domain. + * + * The shutdown is unconditional if force is true. If force is false and there + * are registered consumers, the power-down will be suppressed. + * + * This function will automatically get called by the LPM module whenever the + * chip tries to enter deep sleep or shuts down. + * + * User applications will normally not need to call this function. if you are + * developing a user application that no longer requires access, to AUX, you + * should normally simply release it by calling aux_ctrl_unregister_consumer(). + * If no other consumers are using AUX, then the lpm module will shut it down. + */ +void aux_ctrl_power_down(bool force); +/*---------------------------------------------------------------------------*/ +#endif /* AUX_CTRL_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/dev/batmon-sensor.c b/cpu/cc26xx-cc13xx/dev/batmon-sensor.c new file mode 100644 index 000000000..795b55dec --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/batmon-sensor.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-batmon + * @{ + * + * \file + * Driver for the CC13xx/CC26xx AON battery monitor + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "lib/sensors.h" +#include "batmon-sensor.h" + +#include "ti-lib.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +#define SENSOR_STATUS_DISABLED 0 +#define SENSOR_STATUS_ENABLED 1 + +static int enabled = SENSOR_STATUS_DISABLED; +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns a reading from the sensor + * \param type BATMON_SENSOR_TYPE_TEMP or BATMON_SENSOR_TYPE_VOLT + * + * \return The value as returned by the respective CC26xxware function + */ +static int +value(int type) +{ + if(enabled == SENSOR_STATUS_DISABLED) { + PRINTF("Sensor Disabled\n"); + return 0; + } + + if(type == BATMON_SENSOR_TYPE_TEMP) { + return (int)ti_lib_aon_batmon_temperature_get_deg_c(); + } else if(type == BATMON_SENSOR_TYPE_VOLT) { + return (int)ti_lib_aon_batmon_battery_voltage_get(); + } else { + PRINTF("Invalid type\n"); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the battery monitor sensor. + * + * \param type Activate, enable or disable the sensor. See below + * \param enable If + * + * When type == SENSORS_HW_INIT we turn on the hardware + * When type == SENSORS_ACTIVE and enable==1 we enable the sensor + * When type == SENSORS_ACTIVE and enable==0 we disable the sensor + */ +static int +configure(int type, int enable) +{ + switch(type) { + case SENSORS_HW_INIT: + ti_lib_aon_batmon_enable(); + enabled = SENSOR_STATUS_ENABLED; + break; + case SENSORS_ACTIVE: + if(enable) { + ti_lib_aon_batmon_enable(); + enabled = SENSOR_STATUS_ENABLED; + } else { + ti_lib_aon_batmon_disable(); + enabled = SENSOR_STATUS_DISABLED; + } + break; + default: + break; + } + return enabled; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns the status of the sensor + * \param type SENSORS_ACTIVE or SENSORS_READY + * \return 1 if the sensor is enabled + */ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + break; + default: + break; + } + return SENSOR_STATUS_DISABLED; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(batmon_sensor, "Battery Monitor", value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/cpu/cc26xx-cc13xx/dev/batmon-sensor.h b/cpu/cc26xx-cc13xx/dev/batmon-sensor.h new file mode 100644 index 000000000..014e9a17d --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/batmon-sensor.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx + * @{ + * + * \defgroup cc26xx-batmon CC13xx/CC26xx BatMon sensor driver + * + * Driver for the on-chip battery voltage and chip temperature sensor. + * @{ + * + * \file + * Header file for the CC13xx/CC26xx battery monitor + */ +/*---------------------------------------------------------------------------*/ +#ifndef BATMON_SENSOR_H_ +#define BATMON_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#define BATMON_SENSOR_TYPE_TEMP 1 +#define BATMON_SENSOR_TYPE_VOLT 2 +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor batmon_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* BATMON_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/dev/cc26xx-uart.c b/cpu/cc26xx-cc13xx/dev/cc26xx-uart.c new file mode 100644 index 000000000..d7753066f --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/cc26xx-uart.c @@ -0,0 +1,396 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-uart + * @{ + * + * \file + * Implementation of the CC13xx/CC26xx UART driver. + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "cc26xx-uart.h" +#include "hw_types.h" +#include "hw_memmap.h" +#include "sys_ctrl.h" +#include "prcm.h" +#include "ioc.h" +#include "uart.h" +#include "lpm.h" +#include "ti-lib.h" +#include "sys/energest.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +/* Which events to trigger a UART interrupt */ +#define CC26XX_UART_RX_INTERRUPT_TRIGGERS (UART_INT_RX | UART_INT_RT) + +/* All interrupt masks */ +#define CC26XX_UART_INTERRUPT_ALL (UART_INT_OE | UART_INT_BE | UART_INT_PE | \ + UART_INT_FE | UART_INT_RT | UART_INT_TX | \ + UART_INT_RX | UART_INT_CTS) +/*---------------------------------------------------------------------------*/ +#define cc26xx_uart_isr UART0IntHandler +/*---------------------------------------------------------------------------*/ +static int (*input_handler)(unsigned char c); +/*---------------------------------------------------------------------------*/ +static bool +usable(void) +{ + if(BOARD_IOID_UART_RX == IOID_UNUSED || + BOARD_IOID_UART_TX == IOID_UNUSED || + CC26XX_UART_CONF_ENABLE == 0) { + return false; + } + + return true; +} +/*---------------------------------------------------------------------------*/ +static void +power_and_clock(void) +{ + /* Power on the SERIAL PD */ + ti_lib_prcm_power_domain_on(PRCM_DOMAIN_SERIAL); + while(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL) + != PRCM_DOMAIN_POWER_ON); + + /* Enable UART clock in active mode */ + ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_UART0); + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); +} +/*---------------------------------------------------------------------------*/ +/* + * Returns 0 if either the SERIAL PD is off, or the PD is on but the run mode + * clock is gated. If this function would return 0, accessing UART registers + * will return a precise bus fault. If this function returns 1, it is safe to + * access UART registers. + * + * This function only checks the 'run mode' clock gate, since it can only ever + * be called with the MCU in run mode. + */ +static bool +accessible(void) +{ + /* First, check the PD */ + if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL) + != PRCM_DOMAIN_POWER_ON) { + return false; + } + + /* Then check the 'run mode' clock gate */ + if(!(HWREG(PRCM_BASE + PRCM_O_UARTCLKGR) & PRCM_UARTCLKGR_CLK_EN)) { + return false; + } + + return true; +} +/*---------------------------------------------------------------------------*/ +static void +disable_interrupts(void) +{ + /* Acknowledge UART interrupts */ + ti_lib_int_disable(INT_UART0); + + /* Disable all UART module interrupts */ + ti_lib_uart_int_disable(UART0_BASE, CC26XX_UART_INTERRUPT_ALL); + + /* Clear all UART interrupts */ + ti_lib_uart_int_clear(UART0_BASE, CC26XX_UART_INTERRUPT_ALL); +} +/*---------------------------------------------------------------------------*/ +static void +enable_interrupts(void) +{ + /* Clear all UART interrupts */ + ti_lib_uart_int_clear(UART0_BASE, CC26XX_UART_INTERRUPT_ALL); + + /* Enable RX-related interrupts only if we have an input handler */ + if(input_handler) { + /* Configure which interrupts to generate: FIFO level or after RX timeout */ + ti_lib_uart_int_enable(UART0_BASE, CC26XX_UART_RX_INTERRUPT_TRIGGERS); + + /* Acknowledge UART interrupts */ + ti_lib_int_enable(INT_UART0); + } +} +/*---------------------------------------------------------------------------*/ +static void +configure(void) +{ + uint32_t ctl_val = UART_CTL_UARTEN | UART_CTL_TXE; + /* + * Make sure the TX pin is output / high before assigning it to UART control + * to avoid falling edge glitches + */ + ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_UART_TX); + ti_lib_gpio_pin_write(BOARD_UART_TX, 1); + + /* + * Map UART signals to the correct GPIO pins and configure them as + * hardware controlled. + */ + ti_lib_ioc_pin_type_uart(UART0_BASE, BOARD_IOID_UART_RX, BOARD_IOID_UART_TX, + BOARD_IOID_UART_CTS, BOARD_IOID_UART_RTS); + + /* Configure the UART for 115,200, 8-N-1 operation. */ + ti_lib_uart_config_set_exp_clk(UART0_BASE, ti_lib_sys_ctrl_clock_get(), + CC26XX_UART_CONF_BAUD_RATE, + (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | + UART_CONFIG_PAR_NONE)); + + /* + * Generate an RX interrupt at FIFO 1/2 full. + * We don't really care about the TX interrupt + */ + ti_lib_uart_fifo_level_set(UART0_BASE, UART_FIFO_TX7_8, UART_FIFO_RX4_8); + + /* Enable FIFOs */ + HWREG(UART0_BASE + UART_O_LCRH) |= UART_LCRH_FEN; + + if(input_handler) { + ctl_val += UART_CTL_RXE; + } + + /* Enable TX, RX (conditionally), and the UART. */ + HWREG(UART0_BASE + UART_O_CTL) = ctl_val; +} +/*---------------------------------------------------------------------------*/ +static void +lpm_drop_handler(uint8_t mode) +{ + /* + * First, wait for any outstanding TX to complete. If we have an input + * handler, the SERIAL PD will be kept on and the UART module clock will + * be enabled under sleep as well as deep sleep. In theory, this means that + * we shouldn't lose any outgoing bytes, but we actually do on occasion. + * This byte loss may (or may not) be related to the freezing of IO latches + * between MCU and AON when we drop to deep sleep. This here is essentially a + * workaround + */ + if(accessible() == true) { + while(ti_lib_uart_busy(UART0_BASE)); + } + + /* + * If we have a registered input_handler then we need to retain RX + * capability. Thus, if this is not a shutdown notification and we have an + * input handler, we do nothing + */ + if((mode != LPM_MODE_SHUTDOWN) && (input_handler != NULL)) { + return; + } + + /* + * If we reach here, we either don't care about staying awake or we have + * received a shutdown notification + * + * Only touch UART registers if the module is powered and clocked + */ + if(accessible() == true) { + /* Disable the module */ + ti_lib_uart_disable(UART0_BASE); + + /* Disable all UART interrupts and clear all flags */ + disable_interrupts(); + } + + /* + * Always stop the clock in run mode. Also stop in Sleep and Deep Sleep if + * this is a request for full shutdown + */ + ti_lib_prcm_peripheral_run_disable(PRCM_PERIPH_UART0); + if(mode == LPM_MODE_SHUTDOWN) { + ti_lib_prcm_peripheral_sleep_disable(PRCM_PERIPH_UART0); + ti_lib_prcm_peripheral_deep_sleep_disable(PRCM_PERIPH_UART0); + } + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + /* Set pins to low leakage configuration in preparation for deep sleep */ + lpm_pin_set_default_state(BOARD_IOID_UART_TX); + lpm_pin_set_default_state(BOARD_IOID_UART_RX); + lpm_pin_set_default_state(BOARD_IOID_UART_CTS); + lpm_pin_set_default_state(BOARD_IOID_UART_RTS); +} +/*---------------------------------------------------------------------------*/ +/* Declare a data structure to register with LPM. */ +LPM_MODULE(uart_module, NULL, lpm_drop_handler, NULL, LPM_DOMAIN_NONE); +/*---------------------------------------------------------------------------*/ +static void +enable(void) +{ + power_and_clock(); + + /* Make sure the peripheral is disabled */ + ti_lib_uart_disable(UART0_BASE); + + /* Disable all UART interrupts and clear all flags */ + disable_interrupts(); + + /* Setup pins, Baud rate and FIFO levels */ + configure(); + + /* Enable UART interrupts */ + enable_interrupts(); +} +/*---------------------------------------------------------------------------*/ +void +cc26xx_uart_init() +{ + bool interrupts_disabled; + + /* Return early if disabled by user conf or if ports are misconfigured */ + if(usable() == false) { + return; + } + + /* Disable Interrupts */ + interrupts_disabled = ti_lib_int_master_disable(); + + /* Register ourselves with the LPM module */ + lpm_register_module(&uart_module); + + /* Only TX and EN to start with. RX will be enabled only if needed */ + input_handler = NULL; + + /* + * init() won't actually fire up the UART. We turn it on only when (and if) + * it gets requested, either to enable input or to send out a character + * + * Thus, we simply re-enable processor interrupts here + */ + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } +} +/*---------------------------------------------------------------------------*/ +void +cc26xx_uart_write_byte(uint8_t c) +{ + /* Return early if disabled by user conf or if ports are misconfigured */ + if(usable() == false) { + return; + } + + if(accessible() == false) { + enable(); + } + + ti_lib_uart_char_put(UART0_BASE, c); +} +/*---------------------------------------------------------------------------*/ +void +cc26xx_uart_set_input(int (*input)(unsigned char c)) +{ + input_handler = input; + + /* Return early if disabled by user conf or if ports are misconfigured */ + if(usable() == false) { + return; + } + + if(input == NULL) { + /* Let the SERIAL PD power down */ + uart_module.domain_lock = LPM_DOMAIN_NONE; + + /* Disable module clocks under sleep and deep sleep */ + ti_lib_prcm_peripheral_sleep_disable(PRCM_PERIPH_UART0); + ti_lib_prcm_peripheral_deep_sleep_disable(PRCM_PERIPH_UART0); + } else { + /* Request the SERIAL PD to stay on during deep sleep */ + uart_module.domain_lock = LPM_DOMAIN_SERIAL; + + /* Enable module clocks under sleep and deep sleep */ + ti_lib_prcm_peripheral_sleep_enable(PRCM_PERIPH_UART0); + ti_lib_prcm_peripheral_deep_sleep_enable(PRCM_PERIPH_UART0); + } + + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + enable(); + + return; +} +/*---------------------------------------------------------------------------*/ +uint8_t +cc26xx_uart_busy(void) +{ + /* Return early if disabled by user conf or if ports are misconfigured */ + if(usable() == false) { + return UART_IDLE; + } + + /* If the UART is not accessible, it is not busy */ + if(accessible() == false) { + return UART_IDLE; + } + + return ti_lib_uart_busy(UART0_BASE); +} +/*---------------------------------------------------------------------------*/ +void +cc26xx_uart_isr(void) +{ + char the_char; + uint32_t flags; + + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + power_and_clock(); + + /* Read out the masked interrupt status */ + flags = ti_lib_uart_int_status(UART0_BASE, true); + + /* Clear all UART interrupt flags */ + ti_lib_uart_int_clear(UART0_BASE, CC26XX_UART_INTERRUPT_ALL); + + if((flags & CC26XX_UART_RX_INTERRUPT_TRIGGERS) != 0) { + /* + * If this was a FIFO RX or an RX timeout, read all bytes available in the + * RX FIFO. + */ + while(ti_lib_uart_chars_avail(UART0_BASE)) { + the_char = ti_lib_uart_char_get_non_blocking(UART0_BASE); + + if(input_handler != NULL) { + input_handler((unsigned char)the_char); + } + } + } + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/cpu/cc26xx-cc13xx/dev/cc26xx-uart.h b/cpu/cc26xx-cc13xx/dev/cc26xx-uart.h new file mode 100644 index 000000000..0e5a905c2 --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/cc26xx-uart.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc26xx + * @{ + * + * \defgroup cc26xx-uart CC13xx/CC26xx UARTs + * + * Driver for the CC13xx/CC26xx UART controller + * @{ + * + * \file + * Header file for the CC13xx/CC26xx UART driver + */ +#ifndef CC26XX_UART_H_ +#define CC26XX_UART_H_ + +#include +/*---------------------------------------------------------------------------*/ +/** \name UART functions + * @{ + */ + +/** + * \brief Initialises the UART controller, configures I/O control + * and interrupts + */ +void cc26xx_uart_init(); + +/** + * \brief Sends a single character down the UART + * \param b The character to transmit + */ +void cc26xx_uart_write_byte(uint8_t b); + +/** + * \brief Assigns a callback to be called when the UART receives a byte + * \param input A pointer to the function + * + * If \e input is NULL, the UART driver will assume that RX functionality is + * not required and it will be disabled. It will also disable the module's + * clocks under sleep and deep sleep and allow the SERIAL PD to be powered off. + * + * If \e input is not NULL, the UART driver will assume that RX is in fact + * required and it will be enabled. The module's clocks will be enabled under + * sleep and deep sleep and the driver will not allow the SERIAL PD to turn + * off during deep sleep, so that the UART can still receive bytes. + * + * \note This has a significant impact on overall energy consumption, so you + * should only enabled UART RX input when it's actually required. + */ +void cc26xx_uart_set_input(int (*input)(unsigned char c)); + +/** + * \brief Returns the UART busy status + * \return UART_IDLE or UART_BUSY + * + * ti_lib_uart_busy() will access UART registers. It is our responsibility + * to first make sure the UART is accessible before calling it. Hence this + * wrapper. + * + * Return values are defined in CC26xxware's uart.h + */ +uint8_t cc26xx_uart_busy(void); +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* CC26XX_UART_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c new file mode 100644 index 000000000..f8eb4f666 --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc26xx-clocks + * @{ + * + * \defgroup cc26xx-wdt CC13xx/CC26xx watchdog timer driver + * + * Driver for the CC13xx/CC26xx Watchdog Timer + * + * This file is not called watchdog.c because the filename is in use by + * TI CC26xxware/CC13xxware + * @{ + * + * \file + * Implementation of the CC13xx/CC26xx watchdog driver. + */ +#include "contiki.h" +#include "dev/watchdog.h" +#include "ti-lib.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#ifdef CONTIKI_WATCHDOG_CONF_TIMER_TOP +#define CONTIKI_WATCHDOG_TIMER_TOP CONTIKI_WATCHDOG_CONF_TIMER_TOP +#else +#define CONTIKI_WATCHDOG_TIMER_TOP 0xFFFFF +#endif + +#ifdef CONTIKI_WATCHDOG_CONF_LOCK_CONFIG +#define CONTIKI_WATCHDOG_LOCK_CONFIG CONTIKI_WATCHDOG_CONF_LOCK_CONFIG +#else +#define CONTIKI_WATCHDOG_LOCK_CONFIG 1 +#endif + +#define LOCK_INTERRUPTS_DISABLED 0x01 +#define LOCK_REGISTERS_UNLOCKED 0x02 +/*---------------------------------------------------------------------------*/ +static uint32_t +unlock_config(void) +{ + uint32_t ret = 0; + bool int_status; + + if(CONTIKI_WATCHDOG_LOCK_CONFIG) { + int_status = ti_lib_int_master_disable(); + + if(ti_lib_watchdog_lock_state()) { + ret |= LOCK_REGISTERS_UNLOCKED; + ti_lib_watchdog_unlock(); + } + + ret |= (int_status) ? (0) : (LOCK_INTERRUPTS_DISABLED); + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static void +lock_config(uint32_t status) +{ + if(CONTIKI_WATCHDOG_LOCK_CONFIG) { + + if(status & LOCK_REGISTERS_UNLOCKED) { + ti_lib_watchdog_lock(); + } + if(status & LOCK_INTERRUPTS_DISABLED) { + ti_lib_int_master_enable(); + } + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialises the CC26xx WDT + * + * Simply sets the reload counter to a default value. The WDT is not started + * yet. To start it, watchdog_start() must be called. + */ +void +watchdog_init(void) +{ + ti_lib_watchdog_reload_set(CONTIKI_WATCHDOG_TIMER_TOP); + lock_config(LOCK_REGISTERS_UNLOCKED); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Starts the CC26xx WDT + */ +void +watchdog_start(void) +{ + uint32_t lock_status = unlock_config(); + + watchdog_periodic(); + ti_lib_watchdog_reset_enable(); + + lock_config(lock_status); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Refreshes the CC26xx WDT + */ +void +watchdog_periodic(void) +{ + ti_lib_watchdog_reload_set(CONTIKI_WATCHDOG_TIMER_TOP); + ti_lib_watchdog_int_clear(); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Stops the WDT such that it won't timeout and cause MCU reset + */ +void +watchdog_stop(void) +{ + uint32_t lock_status = unlock_config(); + + ti_lib_watchdog_reset_disable(); + + lock_config(lock_status); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Manually trigger a WDT reboot + */ +void +watchdog_reboot(void) +{ + watchdog_start(); + while(1); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/dev/gpio-interrupt.c b/cpu/cc26xx-cc13xx/dev/gpio-interrupt.c new file mode 100644 index 000000000..b080a5d3f --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/gpio-interrupt.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-gpio-interrupts + * @{ + * + * \file + * Implementation of CC13xx/CC26xx GPIO interrupt handling. + */ +/*---------------------------------------------------------------------------*/ +#include "ioc.h" +#include "gpio-interrupt.h" +#include "sys/energest.h" +#include "lpm.h" +#include "ti-lib.h" + +#include +/*---------------------------------------------------------------------------*/ +#define gpio_interrupt_isr GPIOIntHandler +/*---------------------------------------------------------------------------*/ +/* Handler array */ +static gpio_interrupt_handler_t handlers[NUM_IO_MAX]; +/*---------------------------------------------------------------------------*/ +void +gpio_interrupt_register_handler(uint8_t ioid, gpio_interrupt_handler_t f) +{ + uint8_t interrupts_disabled = ti_lib_int_master_disable(); + + /* Clear interrupts on specified pins */ + ti_lib_gpio_event_clear(1 << ioid); + + handlers[ioid] = f; + + /* Re-enable interrupts */ + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } +} +/*---------------------------------------------------------------------------*/ +void +gpio_interrupt_init() +{ + int i; + + for(i = 0; i < NUM_IO_MAX; i++) { + handlers[i] = NULL; + } + + ti_lib_int_enable(INT_EDGE_DETECT); +} +/*---------------------------------------------------------------------------*/ +void +gpio_interrupt_isr(void) +{ + uint32_t pin_mask; + uint8_t i; + + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + /* Read interrupt flags */ + pin_mask = (HWREG(GPIO_BASE + GPIO_O_EVFLAGS31_0) & GPIO_PIN_MASK); + + /* Clear the interrupt flags */ + HWREG(GPIO_BASE + GPIO_O_EVFLAGS31_0) = pin_mask; + + /* Run custom ISRs */ + for(i = 0; i < NUM_GPIO_PINS; i++) { + /* Call the handler if there is one registered for this event */ + if((pin_mask & (1 << i)) && handlers[i] != NULL) { + handlers[i](i); + } + } + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/cpu/cc26xx-cc13xx/dev/gpio-interrupt.h b/cpu/cc26xx-cc13xx/dev/gpio-interrupt.h new file mode 100644 index 000000000..1a993d3be --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/gpio-interrupt.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx + * @{ + * + * \defgroup cc26xx-gpio-interrupts CC13xx/CC26xx GPIO interrupt handling + * + * The CC13xx/CC26xx GPIO interrupt handler and an API which can be used by + * other parts of the code when they wish to be notified of a GPIO interrupt + * + * @{ + * + * \file + * Header file for the CC13xx/CC26xx GPIO interrupt management + */ +/*---------------------------------------------------------------------------*/ +#ifndef GPIO_INTERRUPT_H_ +#define GPIO_INTERRUPT_H_ +/*---------------------------------------------------------------------------*/ +#include +/*---------------------------------------------------------------------------*/ +typedef void (*gpio_interrupt_handler_t)(uint8_t ioid); +/*---------------------------------------------------------------------------*/ +/** \brief Initialise the GPIO interrupt handling module */ +void gpio_interrupt_init(void); + +/** + * \brief Register a GPIO interrupt handler + * \param f Pointer to a handler to be called when an interrupt is raised on + * ioid + * \param ioid Associate \a f with this ioid. \e ioid must be specified with + * its numeric representation (0, 1, .. 31). Defines for these + * numeric representations are IOID_x + */ +void gpio_interrupt_register_handler(uint8_t ioid, gpio_interrupt_handler_t f); + +#endif /* GPIO_INTERRUPT_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/dev/oscillators.c b/cpu/cc26xx-cc13xx/dev/oscillators.c new file mode 100644 index 000000000..7890a8e55 --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/oscillators.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-oscillators + * @{ + * + * \file + * Implementation of CC26xxware oscillator control wrappers. + */ +/*---------------------------------------------------------------------------*/ +#include "ti-lib.h" +#include "aux-ctrl.h" + +#include +/*---------------------------------------------------------------------------*/ +void +oscillators_select_lf_xosc(void) +{ + /* Request AUX access, with OSCCTRL and SMPH clocks */ + aux_consumer_module_t osc = { + .clocks = AUX_WUC_OSCCTRL_CLOCK | AUX_WUC_SMPH_CLOCK + }; + aux_ctrl_register_consumer(&osc); + + /* Switch LF clock source to the LF XOSC if required */ + if(ti_lib_osc_clock_source_get(OSC_SRC_CLK_LF) != OSC_XOSC_LF) { + ti_lib_osc_clock_source_set(OSC_SRC_CLK_LF, OSC_XOSC_LF); + + /* Wait for LF clock source to become XOSC_LF */ + while(ti_lib_osc_clock_source_get(OSC_SRC_CLK_LF) != OSC_XOSC_LF); + + /* Disable the LF clock qualifiers */ + ti_lib_ddi_16_bit_field_write(AUX_DDI0_OSC_BASE, DDI_0_OSC_O_CTL0, + DDI_0_OSC_CTL0_BYPASS_XOSC_LF_CLK_QUAL_M | + DDI_0_OSC_CTL0_BYPASS_RCOSC_LF_CLK_QUAL_M, + DDI_0_OSC_CTL0_BYPASS_RCOSC_LF_CLK_QUAL_S, + 0x3); + } + + /* Release the OSC AUX consumer */ + aux_ctrl_unregister_consumer(&osc); +} +/*---------------------------------------------------------------------------*/ +void +oscillators_select_lf_rcosc(void) +{ + /* Request AUX access, with OSCCTRL and SMPH clocks */ + aux_consumer_module_t osc = { + .clocks = AUX_WUC_OSCCTRL_CLOCK | AUX_WUC_SMPH_CLOCK + }; + aux_ctrl_register_consumer(&osc); + + /* Switch LF clock source to the LF XOSC if required */ + if(ti_lib_osc_clock_source_get(OSC_SRC_CLK_LF) != OSC_RCOSC_LF) { + ti_lib_osc_clock_source_set(OSC_SRC_CLK_LF, OSC_RCOSC_LF); + + /* Wait for LF clock source to become XOSC_LF */ + while(ti_lib_osc_clock_source_get(OSC_SRC_CLK_LF) != OSC_RCOSC_LF); + } + + /* Release the OSC AUX consumer */ + aux_ctrl_unregister_consumer(&osc); +} +/*---------------------------------------------------------------------------*/ +void +oscillators_request_hf_xosc(void) +{ + /* Request AUX access, with OSCCTRL and SMPH clocks */ + aux_consumer_module_t osc = { + .clocks = AUX_WUC_OSCCTRL_CLOCK | AUX_WUC_SMPH_CLOCK + }; + aux_ctrl_register_consumer(&osc); + + if(ti_lib_osc_clock_source_get(OSC_SRC_CLK_HF) != OSC_XOSC_HF) { + /* + * Request to switch to the crystal to enable radio operation. It takes a + * while for the XTAL to be ready so instead of performing the actual + * switch, we return and we do other stuff while the XOSC is getting ready. + */ + ti_lib_osc_clock_source_set(OSC_SRC_CLK_MF | OSC_SRC_CLK_HF, OSC_XOSC_HF); + } + + /* Release the OSC AUX consumer */ + aux_ctrl_unregister_consumer(&osc); +} +/*---------------------------------------------------------------------------*/ +void +oscillators_switch_to_hf_xosc(void) +{ + /* Request AUX access, with OSCCTRL and SMPH clocks */ + aux_consumer_module_t osc = { + .clocks = AUX_WUC_OSCCTRL_CLOCK | AUX_WUC_SMPH_CLOCK + }; + aux_ctrl_register_consumer(&osc); + + if(ti_lib_osc_clock_source_get(OSC_SRC_CLK_HF) != OSC_XOSC_HF) { + /* Switch the HF clock source (cc26xxware executes this from ROM) */ + ti_lib_osc_hf_source_switch(); + } + + /* Release the OSC AUX consumer */ + aux_ctrl_unregister_consumer(&osc); +} +/*---------------------------------------------------------------------------*/ +void +oscillators_switch_to_hf_rc(void) +{ + /* Request AUX access, with OSCCTRL and SMPH clocks */ + aux_consumer_module_t osc = { + .clocks = AUX_WUC_OSCCTRL_CLOCK | AUX_WUC_SMPH_CLOCK + }; + aux_ctrl_register_consumer(&osc); + + /* Set all clock sources to the HF RC Osc */ + ti_lib_osc_clock_source_set(OSC_SRC_CLK_MF | OSC_SRC_CLK_HF, OSC_RCOSC_HF); + + /* Check to not enable HF RC oscillator if already enabled */ + if(ti_lib_osc_clock_source_get(OSC_SRC_CLK_HF) != OSC_RCOSC_HF) { + /* Switch the HF clock source (cc26xxware executes this from ROM) */ + ti_lib_osc_hf_source_switch(); + } + + /* Release the OSC AUX consumer */ + aux_ctrl_unregister_consumer(&osc); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/cpu/cc26xx-cc13xx/dev/oscillators.h b/cpu/cc26xx-cc13xx/dev/oscillators.h new file mode 100644 index 000000000..47e95a311 --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/oscillators.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx + * @{ + * + * \defgroup cc26xx-oscillators CC13xx/CC26xx oscillator control + * + * Wrapper around CC26xxware/CC13xxware OSC functions that we need in Contiki. + * + * All CC26xxware OSC control requires access to the semaphore module within + * AUX. Thus, in addition to enabling the oscillator interface, we need to + * start the clock to SMPH and restore it to its previous state when we are + * done. + * @{ + * + * \file + * Header file for the CC13xx/CC26xx oscillator control + */ +/*---------------------------------------------------------------------------*/ +#ifndef OSCILLATORS_H_ +#define OSCILLATORS_H_ +/*---------------------------------------------------------------------------*/ +/** + * \brief Set the LF clock source to be the LF XOSC + * + * This function is only called once as soon as the system starts. + * + * Do not switch the LF clock source to the RC OSC for normal system operation + * See CC26xx Errata (swrz058) + */ +void oscillators_select_lf_xosc(void); + +/** + * \brief Set the LF clock source to be the LF RCOSC + * + * This function is only called once, when the systen transitions to a full + * shutdown + * + * Do not switch the LF clock source to the RC OSC for normal system operation + * See CC26xx Errata (swrz058) + */ +void oscillators_select_lf_rcosc(void); + +/** + * \brief Requests the HF XOSC as the source for the HF clock, but does not + * perform the actual switch. + * + * This triggers the startup sequence of the HF XOSC and returns so the CPU + * can perform other tasks while the XOSC is starting. + * + * The XOSC is requested as the source for the HF as well as the MF clock. + */ +void oscillators_request_hf_xosc(void); + +/** + * \brief Performs the switch to the XOSC + * + * This function must be preceded by a call to oscillators_request_hf_xosc() + */ +void oscillators_switch_to_hf_xosc(void); + +/** + * \brief Switches MF and HF clock source to be the HF RC OSC + */ +void oscillators_switch_to_hf_rc(void); +/*---------------------------------------------------------------------------*/ +#endif /* OSCILLATORS_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/dev/soc-rtc.c b/cpu/cc26xx-cc13xx/dev/soc-rtc.c new file mode 100644 index 000000000..398f14d6a --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/soc-rtc.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc13xx-cc26xx-rtc + * @{ + * + * \file + * Implementation of the CC13xx/CC26xx AON RTC driver + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sys/energest.h" +#include "rtimer.h" +#include "lpm.h" + +#include "ti-lib.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define soc_rtc_isr(...) AONRTCIntHandler(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* Prototype of a function in clock.c. Called every time the handler fires */ +void clock_update(void); + +static rtimer_clock_t last_isr_time; +/*---------------------------------------------------------------------------*/ +#define COMPARE_INCREMENT (RTIMER_SECOND / CLOCK_SECOND) +#define MULTIPLE_512_MASK 0xFFFFFE00 +/*---------------------------------------------------------------------------*/ +/* + * Used to test timer wraparounds. + * + * Set to 0xFFFFFFFA to test AON RTC second counter wraparound + * Set to 0xFFFA to test AON RTC 16.16 format wraparound + */ +#ifdef SOC_RTC_CONF_START_TICK_COUNT +#define SOC_RTC_START_TICK_COUNT SOC_RTC_CONF_START_TICK_COUNT +#else +#define SOC_RTC_START_TICK_COUNT 0 +#endif +/*---------------------------------------------------------------------------*/ +void +soc_rtc_init(void) +{ + bool interrupts_disabled; + uint32_t next; + + /* Disable and clear interrupts */ + interrupts_disabled = ti_lib_int_master_disable(); + + ti_lib_aon_rtc_disable(); + + ti_lib_aon_rtc_event_clear(AON_RTC_CH0); + ti_lib_aon_rtc_event_clear(AON_RTC_CH1); + ti_lib_aon_rtc_event_clear(AON_RTC_CH2); + + /* Setup the wakeup event */ + ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU0, AON_EVENT_RTC_CH0); + ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU1, AON_EVENT_RTC_CH1); + ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU2, AON_EVENT_RTC_CH2); + ti_lib_aon_rtc_combined_event_config(AON_RTC_CH0 | AON_RTC_CH1 | AON_RTC_CH2); + + HWREG(AON_RTC_BASE + AON_RTC_O_SEC) = SOC_RTC_START_TICK_COUNT; + + next = ti_lib_aon_rtc_current_compare_value_get() + COMPARE_INCREMENT; + + /* Configure channel 1 to start generating clock ticks. First tick at 512 */ + ti_lib_aon_rtc_compare_value_set(AON_RTC_CH1, next); + + /* Enable channel 1 and the RTC */ + ti_lib_aon_rtc_channel_enable(AON_RTC_CH1); + ti_lib_aon_rtc_enable(); + + ti_lib_int_enable(INT_AON_RTC); + + /* Re-enable interrupts */ + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } +} +/*---------------------------------------------------------------------------*/ +rtimer_clock_t +soc_rtc_get_next_trigger() +{ + rtimer_clock_t ch1 = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH1); + + if(HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL) & AON_RTC_CHCTL_CH0_EN) { + rtimer_clock_t ch0 = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH0); + + return RTIMER_CLOCK_LT(ch0, ch1) ? ch0 : ch1; + } + + return ch1; +} +/*---------------------------------------------------------------------------*/ +void +soc_rtc_schedule_one_shot(uint32_t channel, uint32_t ticks) +{ + if((channel != AON_RTC_CH0) && (channel != AON_RTC_CH1) && (channel != AON_RTC_CH2)) { + return; + } + + /* Set the channel to fire a one-shot compare event at time==ticks */ + ti_lib_aon_rtc_compare_value_set(channel, ticks); + ti_lib_aon_rtc_channel_enable(channel); +} +/*---------------------------------------------------------------------------*/ +rtimer_clock_t +soc_rtc_last_isr_time(void) +{ + return last_isr_time; +} +/*---------------------------------------------------------------------------*/ +/* The AON RTC interrupt handler */ +void +soc_rtc_isr(void) +{ + uint32_t next; + + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + last_isr_time = RTIMER_NOW(); + + /* Adjust the s/w tick counter irrespective of which event trigger this */ + clock_update(); + + if(ti_lib_aon_rtc_event_get(AON_RTC_CH1)) { + HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH1; + + /* + * We need to keep ticking while we are awake, so we schedule the next + * event on the next 512 tick boundary. If we drop to deep sleep before it + * happens, lpm_drop() will reschedule us in the 'distant' future + */ + next = ((ti_lib_aon_rtc_current_compare_value_get() + 5) + + COMPARE_INCREMENT) & MULTIPLE_512_MASK; + ti_lib_aon_rtc_compare_value_set(AON_RTC_CH1, next); + } + + if(ti_lib_aon_rtc_event_get(AON_RTC_CH0)) { + ti_lib_aon_rtc_channel_disable(AON_RTC_CH0); + HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH0; + rtimer_run_next(); + } + + if(ti_lib_aon_rtc_event_get(AON_RTC_CH2)) { + /* after sleep; since a rtimer is already scheduled, do nothing */ + ti_lib_aon_rtc_channel_disable(AON_RTC_CH2); + HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH2; + } + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/cpu/cc26xx-cc13xx/dev/soc-rtc.h b/cpu/cc26xx-cc13xx/dev/soc-rtc.h new file mode 100644 index 000000000..cedf318c5 --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/soc-rtc.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc26xx + * @{ + * + * \defgroup cc26xx-clocks CC13xx/CC26xx clock and timer subsystem + * + * For the CC13xx/CC26xx cpu we use the AON RTC as the basis for all clocks and + * timers + * + * We use two of the aviable AON RTC channels. Channel 0 is used by the rtimer + * sub-system. Channel 1 is used by the system clock and the LPM module. + * + * The RTC runs in all power modes except 'shutdown' + * + * @{ + * + * \defgroup cc13xx-cc26xx-rtc CC13xx/CC26xx AON RTC driver + * + * Underpins the platform's software clocks and timers + * + * @{ + * \file + * Header file for the CC13xx/CC26xx AON RTC driver + */ +#ifndef SOC_RTC_H_ +#define SOC_RTC_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" + +#include "rtimer.h" + +#include +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialise the CC13XX/CC26XX AON RTC module + * + * This timer configures AON RTC channels. + * + * This function must be called before clock_init() and rtimer_init() + */ +void soc_rtc_init(void); + +/** + * \brief Return the time of the next scheduled rtimer event + * \return The time at which the next rtimer event is due to fire + * + * This function will check both AON RTC channels and will only take CH0's + * compare into account if the channel is actually enabled + */ +rtimer_clock_t soc_rtc_get_next_trigger(void); + +/** + * \brief Schedule an AON RTC channel 0 one-shot compare event + * \param channel AON_RTC_CH0 or AON_RTC_CH1 + * \param t The time when the event will be fired. This is an absolute + * time, in other words the event will fire AT time \e t, + * not IN \e t ticks + * + * Channel AON_RTC_CH0 is reserved for the rtimer. AON_RTC_CH1 is reserved + * for the system clock. + * + * User applications should not use this function. User applications should + * instead use Contiki's timer-related libraries + */ +void soc_rtc_schedule_one_shot(uint32_t channel, uint32_t t); + +rtimer_clock_t soc_rtc_last_isr_time(void); +/*---------------------------------------------------------------------------*/ +#endif /* SOC_RTC_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/dev/uart1.h b/cpu/cc26xx-cc13xx/dev/uart1.h new file mode 100644 index 000000000..76dcdcdbe --- /dev/null +++ b/cpu/cc26xx-cc13xx/dev/uart1.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc26xx-uart + * @{ + * + * \file + * This file really only exists because some examples rely on it. + * + * For instance, some examples do uart1_set_input(f). We re-write this to + * uart_set_input + */ +#ifndef UART1_H_ +#define UART1_H_ + +#include "dev/cc26xx-uart.h" + +#define BAUD2UBR(x) x +#define uart1_set_input(f) cc26xx_uart_set_input(f) + +#endif /* UART1_H_ */ + +/** @} */ diff --git a/cpu/cc26xx-cc13xx/fault-handlers.c b/cpu/cc26xx-cc13xx/fault-handlers.c new file mode 100644 index 000000000..48dd9f204 --- /dev/null +++ b/cpu/cc26xx-cc13xx/fault-handlers.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +#include "inc/hw_types.h" +#include "inc/hw_memmap.h" +#include "inc/hw_cpu_scs.h" +/*---------------------------------------------------------------------------*/ +#define fault_handlers_hard_fault_isr FaultISR +/*---------------------------------------------------------------------------*/ +void +fault_handlers_hard_fault_isr(void) +{ + /* + * Workaround for (Im)precise Bus Faults caused under unknown circumstances, + * likely by access to RFC registers while the RF PD is off (which is + * something that should never happen because we do in fact check before + * accessing) + */ + if((HWREG(CPU_SCS_BASE + CPU_SCS_O_CFSR) == CPU_SCS_CFSR_IMPRECISERR) || + (HWREG(CPU_SCS_BASE + CPU_SCS_O_CFSR) & CPU_SCS_CFSR_PRECISERR)){ + /* ToDo: Check BFARVALID and then BFAR to filter down even further */ + return; + } + + while(1); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc26xx-cc13xx/ieee-addr.c b/cpu/cc26xx-cc13xx/ieee-addr.c new file mode 100644 index 000000000..6f7e9a296 --- /dev/null +++ b/cpu/cc26xx-cc13xx/ieee-addr.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-ieee-addr + * @{ + * + * \file + * Driver for the CC13xx/CC26xx IEEE addresses + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "net/linkaddr.h" +#include "ieee-addr.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +void +ieee_addr_cpy_to(uint8_t *dst, uint8_t len) +{ + if(IEEE_ADDR_CONF_HARDCODED) { + uint8_t ieee_addr_hc[8] = IEEE_ADDR_CONF_ADDRESS; + + memcpy(dst, &ieee_addr_hc[8 - len], len); + } else { + int i; + + /* Reading from primary location... */ + uint8_t *location = (uint8_t *)IEEE_ADDR_LOCATION_PRIMARY; + + /* + * ...unless we can find a byte != 0xFF in secondary + * + * Intentionally checking all 8 bytes here instead of len, because we + * are checking validity of the entire IEEE address irrespective of the + * actual number of bytes the caller wants to copy over. + */ + for(i = 0; i < 8; i++) { + if(((uint8_t *)IEEE_ADDR_LOCATION_SECONDARY)[i] != 0xFF) { + /* A byte in the secondary location is not 0xFF. Use the secondary */ + location = (uint8_t *)IEEE_ADDR_LOCATION_SECONDARY; + break; + } + } + + /* + * We have chosen what address to read the IEEE address from. Do so, + * inverting byte order + */ + for(i = 0; i < len; i++) { + dst[i] = location[len - 1 - i]; + } + } + +#if IEEE_ADDR_NODE_ID + dst[len - 1] = IEEE_ADDR_NODE_ID & 0xFF; + dst[len - 2] = IEEE_ADDR_NODE_ID >> 8; +#endif +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/cpu/cc26xx-cc13xx/ieee-addr.h b/cpu/cc26xx-cc13xx/ieee-addr.h new file mode 100644 index 000000000..582854d49 --- /dev/null +++ b/cpu/cc26xx-cc13xx/ieee-addr.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx + * @{ + * + * \defgroup cc26xx-ieee-addr CC13xx/CC26xx IEEE Address Control + * + * Driver for the retrieval of an IEEE address from flash + * + * The user can specify a hardcoded IEEE address through the + * IEEE_ADDR_CONF_HARDCODED configuration macro. + * + * If the user does not hard-code an address, then one will be read from either + * the primary location (InfoPage) or from the secondary location (on flash). + * + * In order to allow the user to easily program nodes with addresses, the + * secondary location is given priority: If it contains a valid address then + * it will be chosen in favour of the one on InfoPage. + * + * In this context, an address is valid if at least one of the 8 bytes does not + * equal 0xFF. If all 8 bytes are 0xFF, then the primary location will be used. + * + * In all cases, the address is assumed to be written little-endian. + * + * Lastly, it is possible to override the 2 LSB's of the address by using the + * NODE_ID make variable. + * @{ + * + * \file + * Header file with register and macro declarations for the cc26xx IEEE address + * driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef IEEE_ADDR_H_ +#define IEEE_ADDR_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" + +#include +/*---------------------------------------------------------------------------*/ +/** + * \name IEEE address locations + * + * The address of the secondary location can be configured by the platform + * or example + * + * @{ + */ +#define IEEE_ADDR_LOCATION_PRIMARY 0x500012F0 /**< Primary IEEE address location */ + +#ifdef IEEE_ADDR_CONF_LOCATION_SECONDARY +#define IEEE_ADDR_LOCATION_SECONDARY IEEE_ADDR_CONF_LOCATION_SECONDARY +#else +#define IEEE_ADDR_LOCATION_SECONDARY 0x0001FFC8 /**< Secondary IEEE address location */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief Copy the node's IEEE address to a destination memory area + * \param dst A pointer to the destination area where the IEEE address is to be + * written + * \param len The number of bytes to write to destination area + * + * This function will copy \e len LS bytes and it will invert byte order in + * the process. The factory address on devices is normally little-endian, + * therefore you should expect dst to store the address in a big-endian order. + */ +void ieee_addr_cpy_to(uint8_t *dst, uint8_t len); +/*---------------------------------------------------------------------------*/ +#endif /* IEEE_ADDR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/lib/cc26xxware b/cpu/cc26xx-cc13xx/lib/cc26xxware new file mode 160000 index 000000000..0270b50ac --- /dev/null +++ b/cpu/cc26xx-cc13xx/lib/cc26xxware @@ -0,0 +1 @@ +Subproject commit 0270b50ac750f8f3348a98f900a470e7a65ffce8 diff --git a/cpu/cc26xx-cc13xx/lpm.c b/cpu/cc26xx-cc13xx/lpm.c new file mode 100644 index 000000000..3253202c2 --- /dev/null +++ b/cpu/cc26xx-cc13xx/lpm.c @@ -0,0 +1,545 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-lpm + * @{ + * + * Implementation of CC13xx/CC26xx low-power operation functionality + * + * @{ + * + * \file + * Driver for CC13xx/CC26xx low-power operation + */ +/*---------------------------------------------------------------------------*/ +#include "prcm.h" +#include "contiki-conf.h" +#include "ti-lib.h" +#include "lpm.h" +#include "sys/energest.h" +#include "lib/list.h" +#include "dev/aux-ctrl.h" +#include "dev/leds.h" +#include "dev/watchdog.h" +#include "dev/soc-rtc.h" +#include "dev/oscillators.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#if ENERGEST_CONF_ON +static unsigned long irq_energest = 0; + +#define ENERGEST_IRQ_SAVE(a) do { \ + a = energest_type_time(ENERGEST_TYPE_IRQ); } while(0) +#define ENERGEST_IRQ_RESTORE(a) do { \ + energest_type_set(ENERGEST_TYPE_IRQ, a); } while(0) +#else +#define ENERGEST_IRQ_SAVE(a) do {} while(0) +#define ENERGEST_IRQ_RESTORE(a) do {} while(0) +#endif +/*---------------------------------------------------------------------------*/ +LIST(modules_list); +/*---------------------------------------------------------------------------*/ +/* PDs that may stay on in deep sleep */ +#define LOCKABLE_DOMAINS ((uint32_t)(PRCM_DOMAIN_SERIAL | PRCM_DOMAIN_PERIPH)) +/*---------------------------------------------------------------------------*/ +/* + * Don't consider standby mode if the next AON RTC event is scheduled to fire + * in less than STANDBY_MIN_DURATION rtimer ticks + */ +#define STANDBY_MIN_DURATION (RTIMER_SECOND / 100) /* 10.0 ms */ + +/* Wake up this much time earlier before the next rtimer */ +#define SLEEP_GUARD_TIME (RTIMER_SECOND / 1000) /* 1.0 ms */ + +#define MAX_SLEEP_TIME RTIMER_SECOND +#define MINIMAL_SAFE_SCHEDULE 8u +/*---------------------------------------------------------------------------*/ +/* Prototype of a function in clock.c. Called every time we come out of DS */ +void clock_update(void); +/*---------------------------------------------------------------------------*/ +void +lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on) +{ + lpm_registered_module_t *module; + int i; + uint32_t io_cfg = (IOC_STD_INPUT & ~IOC_IOPULL_M) | io_pull | wake_on; + aux_consumer_module_t aux = { .clocks = AUX_WUC_OSCCTRL_CLOCK }; + + /* This procedure may not be interrupted */ + ti_lib_int_master_disable(); + + /* Disable the RTC */ + ti_lib_aon_rtc_disable(); + ti_lib_aon_rtc_event_clear(AON_RTC_CH0); + ti_lib_aon_rtc_event_clear(AON_RTC_CH1); + ti_lib_aon_rtc_event_clear(AON_RTC_CH2); + + /* Reset AON even fabric to default wakeup sources */ + for(i = AON_EVENT_MCU_WU0; i <= AON_EVENT_MCU_WU3; i++) { + ti_lib_aon_event_mcu_wake_up_set(i, AON_EVENT_NONE); + } + for(i = AON_EVENT_AUX_WU0; i <= AON_EVENT_AUX_WU2; i++) { + ti_lib_aon_event_aux_wake_up_set(i, AON_EVENT_NONE); + } + + ti_lib_sys_ctrl_aon_sync(); + + watchdog_periodic(); + + /* Notify all modules that we're shutting down */ + for(module = list_head(modules_list); module != NULL; + module = module->next) { + if(module->shutdown) { + module->shutdown(LPM_MODE_SHUTDOWN); + } + } + + /* Configure the wakeup trigger */ + if(wakeup_pin != IOID_UNUSED) { + ti_lib_gpio_dir_mode_set((1 << wakeup_pin), GPIO_DIR_MODE_IN); + ti_lib_ioc_port_configure_set(wakeup_pin, IOC_PORT_GPIO, io_cfg); + } + + /* Freeze I/O latches in AON */ + ti_lib_aon_ioc_freeze_enable(); + + /* Turn off RFCORE, SERIAL and PERIPH PDs. This will happen immediately */ + ti_lib_prcm_power_domain_off(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_SERIAL | + PRCM_DOMAIN_PERIPH); + + /* Register an aux-ctrl consumer to avoid powercycling AUX twice in a row */ + aux_ctrl_register_consumer(&aux); + oscillators_switch_to_hf_rc(); + oscillators_select_lf_rcosc(); + + /* Configure clock sources for MCU: No clock */ + ti_lib_aon_wuc_mcu_power_down_config(AONWUC_NO_CLOCK); + + /* Disable SRAM retention */ + ti_lib_aon_wuc_mcu_sram_config(0); + + /* + * Request CPU, SYSBYS and VIMS PD off. + * This will only happen when the CM3 enters deep sleep + */ + ti_lib_prcm_power_domain_off(PRCM_DOMAIN_CPU | PRCM_DOMAIN_VIMS | + PRCM_DOMAIN_SYSBUS); + + /* Request JTAG domain power off */ + ti_lib_aon_wuc_jtag_power_off(); + + /* Turn off AUX */ + aux_ctrl_power_down(true); + ti_lib_aon_wuc_domain_power_down_enable(); + + /* + * Request MCU VD power off. + * This will only happen when the CM3 enters deep sleep + */ + ti_lib_prcm_mcu_power_off(); + + /* Set MCU wakeup to immediate and disable virtual power off */ + ti_lib_aon_wuc_mcu_wake_up_config(MCU_IMM_WAKE_UP); + ti_lib_aon_wuc_mcu_power_off_config(MCU_VIRT_PWOFF_DISABLE); + + /* Latch the IOs in the padring and enable I/O pad sleep mode */ + ti_lib_pwr_ctrl_io_freeze_enable(); + + /* Turn off VIMS cache, CRAM and TRAM - possibly not required */ + ti_lib_prcm_cache_retention_disable(); + ti_lib_vims_mode_set(VIMS_BASE, VIMS_MODE_OFF); + + /* Enable shutdown and sync AON */ + ti_lib_aon_wuc_shut_down_enable(); + ti_lib_sys_ctrl_aon_sync(); + + /* Deep Sleep */ + ti_lib_prcm_deep_sleep(); +} +/*---------------------------------------------------------------------------*/ +/* + * Notify all modules that we're back on and rely on them to restore clocks + * and power domains as required. + */ +static void +wake_up(void) +{ + lpm_registered_module_t *module; + + /* Remember IRQ energest for next pass */ + ENERGEST_IRQ_SAVE(irq_energest); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); + + /* Sync so that we get the latest values before adjusting recharge settings */ + ti_lib_sys_ctrl_aon_sync(); + + /* Adjust recharge settings */ + ti_lib_sys_ctrl_adjust_recharge_after_power_down(); + + /* + * Release the request to the uLDO + * This is likely not required, since the switch to GLDO/DCDC is automatic + * when coming back from deep sleep + */ + ti_lib_prcm_mcu_uldo_configure(false); + + /* Turn on cache again */ + ti_lib_vims_mode_set(VIMS_BASE, VIMS_MODE_ENABLED); + ti_lib_prcm_cache_retention_enable(); + + ti_lib_aon_ioc_freeze_disable(); + ti_lib_sys_ctrl_aon_sync(); + + /* Check operating conditions, optimally choose DCDC versus GLDO */ + ti_lib_sys_ctrl_dcdc_voltage_conditional_control(); + + /* Fire up AUX is the user has requested this */ + aux_ctrl_power_up(); + + /* + * We may or may not have been woken up by an AON RTC tick. If not, we need + * to adjust our software tick counter + */ + clock_update(); + + watchdog_periodic(); + + /* Notify all registered modules that we've just woken up */ + for(module = list_head(modules_list); module != NULL; + module = module->next) { + if(module->wakeup) { + module->wakeup(); + } + } + +#if CC2650_FAST_RADIO_STARTUP + /* + * Trigger a switch to the XOSC, so that we can subsequently use the RF FS + */ + oscillators_request_hf_xosc(); +#endif +} +/*---------------------------------------------------------------------------*/ +static int +setup_sleep_mode(rtimer_clock_t *next_timer) +{ + lpm_registered_module_t *module; + uint8_t max_pm = LPM_MODE_MAX_SUPPORTED; + + rtimer_clock_t now = RTIMER_NOW(); + const rtimer_clock_t max_sleep = now + MAX_SLEEP_TIME; + + /* next_timer will hold the time of the next system wakeup due to a timer*/ + *next_timer = max_sleep; + + /* Check if any events fired before we turned interrupts off. If so, abort */ + if(LPM_MODE_MAX_SUPPORTED == LPM_MODE_AWAKE || process_nevents()) { + return LPM_MODE_AWAKE; + } + + if(ti_lib_aon_rtc_channel_active(AON_RTC_CH0)) { + rtimer_clock_t next_rtimer; + /* find out the timer of the next rtimer interrupt */ + next_rtimer = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH0); + if(RTIMER_CLOCK_LT(next_rtimer, now + 2)) { + return LPM_MODE_AWAKE; + } + if(RTIMER_CLOCK_LT(next_rtimer, now + STANDBY_MIN_DURATION)) { + return LPM_MODE_SLEEP; + } + *next_timer = next_rtimer; + } + + /* also find out the timer of the next etimer */ + if(etimer_pending()) { + int32_t until_next_etimer; + rtimer_clock_t next_etimer; + + until_next_etimer = (int32_t)etimer_next_expiration_time() - (int32_t)clock_time(); + if(until_next_etimer < 1) { + return LPM_MODE_AWAKE; + } + + next_etimer = soc_rtc_last_isr_time() + (until_next_etimer * (RTIMER_SECOND / CLOCK_SECOND)); + if(RTIMER_CLOCK_LT(next_etimer, now + STANDBY_MIN_DURATION)) { + /* ensure that we schedule sleep a minimal number of ticks into the + future */ + soc_rtc_schedule_one_shot(AON_RTC_CH1, now + MINIMAL_SAFE_SCHEDULE); + return LPM_MODE_SLEEP; + } + + if(RTIMER_CLOCK_LT(max_sleep, next_etimer)) { + /* if max_pm is LPM_MODE_SLEEP, we could trigger the watchdog if we slept + for too long. */ + if(RTIMER_CLOCK_LT(max_sleep, *next_timer)) { + soc_rtc_schedule_one_shot(AON_RTC_CH1, max_sleep); + } + } else { + /* Reschedule AON RTC CH1 to fire just in time for the next etimer event */ + soc_rtc_schedule_one_shot(AON_RTC_CH1, next_etimer); + } + + if(RTIMER_CLOCK_LT(next_etimer, *next_timer)) { + /* set `next_timer` to the time the first etimer fires */ + *next_timer = next_etimer; + } + } + + /* Collect max allowed PM permission from interested modules */ + for(module = list_head(modules_list); module != NULL; + module = module->next) { + if(module->request_max_pm) { + uint8_t module_pm = module->request_max_pm(); + if(module_pm < max_pm) { + max_pm = module_pm; + } + } + } + + return max_pm; +} +/*---------------------------------------------------------------------------*/ +void +lpm_sleep(void) +{ + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); + + /* We are only interested in IRQ energest while idle or in LPM */ + ENERGEST_IRQ_RESTORE(irq_energest); + + /* Just to be on the safe side, explicitly disable Deep Sleep */ + HWREG(NVIC_SYS_CTRL) &= ~(NVIC_SYS_CTRL_SLEEPDEEP); + + ti_lib_prcm_sleep(); + + /* Remember IRQ energest for next pass */ + ENERGEST_IRQ_SAVE(irq_energest); + + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); +} +/*---------------------------------------------------------------------------*/ +static void +deep_sleep(rtimer_clock_t next_timer) +{ + uint32_t domains = LOCKABLE_DOMAINS; + lpm_registered_module_t *module; + +#if CC2650_FAST_RADIO_STARTUP + /* schedule a wakeup briefly before the next etimer/rtimer to wake up the system */ + soc_rtc_schedule_one_shot(AON_RTC_CH2, next_timer - SLEEP_GUARD_TIME); +#endif + + /* + * Notify all registered modules that we are dropping to mode X. We do not + * need to do this for simple sleep. + * + * This is a chance for modules to delay us a little bit until an ongoing + * operation has finished (e.g. uart TX) or to configure themselves for + * deep sleep. + * + * At this stage, we also collect power domain locks, if any. + * The argument to PRCMPowerDomainOff() is a bitwise OR, so every time + * we encounter a lock we just clear the respective bits in the 'domains' + * variable as required by the lock. In the end the domains variable will + * just hold whatever has not been cleared + */ + for(module = list_head(modules_list); module != NULL; + module = module->next) { + if(module->shutdown) { + module->shutdown(LPM_MODE_DEEP_SLEEP); + } + + /* Clear the bits specified in the lock */ + domains &= ~module->domain_lock; + } + + /* Pat the dog: We don't want it to shout right after we wake up */ + watchdog_periodic(); + + /* Clear unacceptable bits, just in case a lock provided a bad value */ + domains &= LOCKABLE_DOMAINS; + + /* + * Freeze the IOs on the boundary between MCU and AON. We only do this if + * PERIPH is not needed + */ + if(domains & PRCM_DOMAIN_PERIPH) { + ti_lib_aon_ioc_freeze_enable(); + } + + /* + * Among LOCKABLE_DOMAINS, turn off those that are not locked + * + * If domains is != 0, pass it as-is + */ + if(domains) { + ti_lib_prcm_power_domain_off(domains); + } + + /* + * Before entering Deep Sleep, we must switch off the HF XOSC. The HF XOSC + * is predominantly controlled by the RF driver. In a build with radio + * cycling (e.g. ContikiMAC), the RF driver will request the XOSC before + * using the Freq. Synth, and switch back to the RC when it is about to + * turn back off. + * + * If the radio is on, we won't even reach here, and if it's off the HF + * clock source should already be the HF RC, unless CC2650_FAST_RADIO_STARTUP + * is defined. + * + * Nevertheless, request the switch to the HF RC explicitly here. + */ + oscillators_switch_to_hf_rc(); + + /* Shut Down the AUX if the user application is not using it */ + aux_ctrl_power_down(false); + + /* Configure clock sources for MCU: No clock */ + ti_lib_aon_wuc_mcu_power_down_config(AONWUC_NO_CLOCK); + + /* Full RAM retention. */ + ti_lib_aon_wuc_mcu_sram_config(MCU_RAM0_RETENTION | MCU_RAM1_RETENTION | + MCU_RAM2_RETENTION | MCU_RAM3_RETENTION); + + /* + * Always turn off RFCORE, CPU, SYSBUS and VIMS. RFCORE should be off + * already + */ + ti_lib_prcm_power_domain_off(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_CPU | + PRCM_DOMAIN_VIMS | PRCM_DOMAIN_SYSBUS); + + /* Request JTAG domain power off */ + ti_lib_aon_wuc_jtag_power_off(); + + /* Allow MCU and AUX powerdown */ + ti_lib_aon_wuc_domain_power_down_enable(); + + /* Configure the recharge controller */ + ti_lib_sys_ctrl_set_recharge_before_power_down(XOSC_IN_HIGH_POWER_MODE); + + /* + * If both PERIPH and SERIAL PDs are off, request the uLDO as the power + * source while in deep sleep. + */ + if(domains == LOCKABLE_DOMAINS) { + ti_lib_pwr_ctrl_source_set(PWRCTRL_PWRSRC_ULDO); + } + + /* We are only interested in IRQ energest while idle or in LPM */ + ENERGEST_IRQ_RESTORE(irq_energest); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); + + /* Sync the AON interface to ensure all writes have gone through. */ + ti_lib_sys_ctrl_aon_sync(); + + /* + * Explicitly turn off VIMS cache, CRAM and TRAM. Needed because of + * retention mismatch between VIMS logic and cache. We wait to do this + * until right before deep sleep to be able to use the cache for as long + * as possible. + */ + ti_lib_prcm_cache_retention_disable(); + ti_lib_vims_mode_set(VIMS_BASE, VIMS_MODE_OFF); + + /* Deep Sleep */ + ti_lib_prcm_deep_sleep(); + + /* + * When we reach here, some interrupt woke us up. The global interrupt + * flag is off, hence we have a chance to run things here. We will wake up + * the chip properly, and then we will enable the global interrupt without + * unpending events so the handlers can fire + */ + wake_up(); + + ti_lib_int_master_enable(); +} +/*---------------------------------------------------------------------------*/ +void +lpm_drop() +{ + uint8_t max_pm; + rtimer_clock_t next_timer; + + /* Critical. Don't get interrupted! */ + ti_lib_int_master_disable(); + + max_pm = setup_sleep_mode(&next_timer); + + /* Drop */ + if(max_pm == LPM_MODE_SLEEP) { + lpm_sleep(); + } else if(max_pm == LPM_MODE_DEEP_SLEEP) { + deep_sleep(next_timer); + } + + ti_lib_int_master_enable(); +} +/*---------------------------------------------------------------------------*/ +void +lpm_register_module(lpm_registered_module_t *module) +{ + list_add(modules_list, module); +} +/*---------------------------------------------------------------------------*/ +void +lpm_unregister_module(lpm_registered_module_t *module) +{ + list_remove(modules_list, module); +} +/*---------------------------------------------------------------------------*/ +void +lpm_init() +{ + list_init(modules_list); + + /* Always wake up on any DIO edge detection */ + ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU3, AON_EVENT_IO); +} +/*---------------------------------------------------------------------------*/ +void +lpm_pin_set_default_state(uint32_t ioid) +{ + if(ioid == IOID_UNUSED) { + return; + } + + ti_lib_ioc_port_configure_set(ioid, IOC_PORT_GPIO, IOC_STD_OUTPUT); + ti_lib_gpio_dir_mode_set((1 << ioid), GPIO_DIR_MODE_IN); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/lpm.h b/cpu/cc26xx-cc13xx/lpm.h new file mode 100644 index 000000000..2d6f56d00 --- /dev/null +++ b/cpu/cc26xx-cc13xx/lpm.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx + * @{ + * + * \defgroup cc26xx-lpm CC13xx/CC26xx Low-Power management + * + * CC13xx/CC26xx low-power operation + * + * @{ + * + * \file + * Header file for the management of CC13xx/CC26xx low-power operation + */ +/*---------------------------------------------------------------------------*/ +#ifndef LPM_H_ +#define LPM_H_ +/*---------------------------------------------------------------------------*/ +#include "pwr_ctrl.h" + +#include +/*---------------------------------------------------------------------------*/ +#define LPM_MODE_AWAKE 0 +#define LPM_MODE_SLEEP 1 +#define LPM_MODE_DEEP_SLEEP 2 +#define LPM_MODE_SHUTDOWN 3 + +#define LPM_MODE_MAX_SUPPORTED LPM_MODE_DEEP_SLEEP +/*---------------------------------------------------------------------------*/ +#define LPM_DOMAIN_NONE 0 +#define LPM_DOMAIN_SERIAL PRCM_DOMAIN_SERIAL +#define LPM_DOMAIN_PERIPH PRCM_DOMAIN_PERIPH +/*---------------------------------------------------------------------------*/ +typedef struct lpm_registered_module { + struct lpm_registered_module *next; + uint8_t (*request_max_pm)(void); + void (*shutdown)(uint8_t mode); + void (*wakeup)(void); + uint32_t domain_lock; +} lpm_registered_module_t; +/*---------------------------------------------------------------------------*/ +/** + * \brief Declare a variable to be used in order to get notifications from LPM + * \param n the variable name to be declared + * \param m A pointer to a function which will tell the LPM module the max + * PM this module is willing to handle. This function will return + * LPM_MODE_SLEEP, LPM_MODE_DEEP_SLEEP etc. The LPM module will ask all + * registered modules and will trigger the highest LPM permitted + * \param s A pointer to a function which will receive a notification just + * before entering the low power mode. The callee can prepare for the + * imminent LPM state. The argument to this function will be the + * upcoming low power mode. This function can e.g. turn off a + * peripheral before the LPM module shuts down the power domain. + * \param w A pointer to a function which will be called just after we have + * woken up. This can be used to e.g. turn a peripheral back on. This + * function is in charge of turning power domains back on. This + * function will normally be called within an interrupt context. + * \param l Power domain locks, if any are required. The module can request + * that the SERIAL or PERIPH PD be kept powered up at the transition + * to deep sleep. This field can be a bitwise OR of LPM_DOMAIN_x, so + * if required multiple domains can be kept powered. + */ +#define LPM_MODULE(n, m, s, w, l) static lpm_registered_module_t n = \ + { NULL, m, s, w, l } +/*---------------------------------------------------------------------------*/ +/** + * \brief Drop the cortex to sleep / deep sleep and shut down peripherals + * + * Whether the cortex will drop to sleep or deep sleep is configurable. The + * exact peripherals which will be shut down is also configurable + */ +void lpm_drop(void); + +/** + * \brief Enter sleep mode + */ +void lpm_sleep(void); + +/** + * \brief Put the chip in shutdown power mode + * \param wakeup_pin The GPIO pin which will wake us up. Must be IOID_0 etc... + * \param io_pull Pull configuration for the shutdown pin: IOC_NO_IOPULL, + * IOC_IOPULL_UP or IOC_IOPULL_DOWN + * \param wake_on High or Low (IOC_WAKE_ON_LOW or IOC_WAKE_ON_HIGH) + */ +void lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on); + +/** + * \brief Register a module for LPM notifications. + * \param module A pointer to the data structure with the module definition + * + * When the LPM module is about to drop to some low power mode, it will first + * notify all modules about this. + * + * This function must not be called before the module has been initialised + * with lpm_init(). The code does not perform checks: This is the caller's + * responsibility. + */ +void lpm_register_module(lpm_registered_module_t *module); + +/** + * \brief Unregister a module from LPM notifications. + * \param module A pointer to the data structure with the module definition + * + * When a previously registered module is no longer interested in LPM + * notifications, this function can be used to unregister it. + */ +void lpm_unregister_module(lpm_registered_module_t *module); + +/** + * \brief Initialise the low-power mode management module + */ +void lpm_init(void); + +/** + * \brief Sets an IOID to a default state + * \param ioid IOID_0... + * + * This will set ioid to sw control, input, no pull. Input buffer and output + * driver will both be disabled + * + * The function will do nothing if ioid == IOID_UNUSED, so the caller does not + * have to check board configuration before calling this. + */ +void lpm_pin_set_default_state(uint32_t ioid); +/*---------------------------------------------------------------------------*/ +#endif /* LPM_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc2430/mtarch.h b/cpu/cc26xx-cc13xx/mtarch.h similarity index 82% rename from cpu/cc2430/mtarch.h rename to cpu/cc26xx-cc13xx/mtarch.h index 9542270a1..4f696669d 100644 --- a/cpu/cc2430/mtarch.h +++ b/cpu/cc26xx-cc13xx/mtarch.h @@ -28,22 +28,21 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ - /* * \file - * Stub header file for cc2430 multi-threading. It doesn't do anything, it - * just exists so that mt.c can compile cleanly. + * Stub header file for multi-threading. It doesn't do anything, it + * just exists so that mt.c can compile cleanly. * - * This is based on the original mtarch.h for z80 by Takahide Matsutsuka + * This is based on the original mtarch.h for z80 by Takahide Matsutsuka * * \author - * George Oikonomou - + * George Oikonomou - */ -#ifndef MTARCH_H_ -#define MTARCH_H_ +#ifndef __MTARCH_H__ +#define __MTARCH_H__ struct mtarch_thread { unsigned char *sp; }; -#endif /* MTARCH_H_ */ +#endif /* __MTARCH_H__ */ diff --git a/cpu/cc26xx-cc13xx/putchar.c b/cpu/cc26xx-cc13xx/putchar.c new file mode 100644 index 000000000..7cbd1901a --- /dev/null +++ b/cpu/cc26xx-cc13xx/putchar.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +#include "cc26xx-uart.h" +#include "ti-lib.h" + +#include +/*---------------------------------------------------------------------------*/ +int +putchar(int c) +{ + cc26xx_uart_write_byte(c); + return c; +} +/*---------------------------------------------------------------------------*/ +int +puts(const char *str) +{ + int i; + if(str == NULL) { + return 0; + } + for(i = 0; i < strlen(str); i++) { + cc26xx_uart_write_byte(str[i]); + } + cc26xx_uart_write_byte('\n'); + + /* + * Wait for the line to go out. This is to prevent garbage when used between + * UART on/off cycles + */ + while(cc26xx_uart_busy() == UART_BUSY); + + return i; +} +/*---------------------------------------------------------------------------*/ +unsigned int +dbg_send_bytes(const unsigned char *s, unsigned int len) +{ + unsigned int i = 0; + + while(s && *s != 0) { + if(i >= len) { + break; + } + cc26xx_uart_write_byte(*s++); + i++; + } + + /* + * Wait for the buffer to go out. This is to prevent garbage when used + * between UART on/off cycles + */ + while(cc26xx_uart_busy() == UART_BUSY); + + return i; +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc26xx-cc13xx/rf-core/api/ble_cmd.h b/cpu/cc26xx-cc13xx/rf-core/api/ble_cmd.h new file mode 100644 index 000000000..01324401f --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/api/ble_cmd.h @@ -0,0 +1,1081 @@ +/****************************************************************************** +* Filename: ble_cmd.h +* Revised: $ $ +* Revision: $ $ +* +* Description: CC26xx/CC13xx API for Bluetooth Low Energy commands +* +* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* 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 Texas Instruments Incorporated 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 +* OWNER 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. +* +******************************************************************************/ + +#ifndef BLE_CMD_H_ +#define BLE_CMD_H_ + +#ifndef __RFC_STRUCT +#ifdef __GNUC__ +#define __RFC_STRUCT __attribute__ ((aligned (4))) +#else +#define __RFC_STRUCT +#endif +#endif + +//! \addtogroup rfc +//! @{ + +//! \addtogroup ble_cmd +//! @{ + +#include +#include "mailbox.h" +#include "common_cmd.h" + +typedef struct __RFC_STRUCT rfc_bleRadioOp_s rfc_bleRadioOp_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_SLAVE_s rfc_CMD_BLE_SLAVE_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_MASTER_s rfc_CMD_BLE_MASTER_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_ADV_s rfc_CMD_BLE_ADV_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_ADV_DIR_s rfc_CMD_BLE_ADV_DIR_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_ADV_NC_s rfc_CMD_BLE_ADV_NC_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_ADV_SCAN_s rfc_CMD_BLE_ADV_SCAN_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_SCANNER_s rfc_CMD_BLE_SCANNER_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_INITIATOR_s rfc_CMD_BLE_INITIATOR_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_GENERIC_RX_s rfc_CMD_BLE_GENERIC_RX_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_TX_TEST_s rfc_CMD_BLE_TX_TEST_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_ADV_PAYLOAD_s rfc_CMD_BLE_ADV_PAYLOAD_t; +typedef struct __RFC_STRUCT rfc_bleMasterSlavePar_s rfc_bleMasterSlavePar_t; +typedef struct __RFC_STRUCT rfc_bleMasterPar_s rfc_bleMasterPar_t; +typedef struct __RFC_STRUCT rfc_bleSlavePar_s rfc_bleSlavePar_t; +typedef struct __RFC_STRUCT rfc_bleAdvPar_s rfc_bleAdvPar_t; +typedef struct __RFC_STRUCT rfc_bleScannerPar_s rfc_bleScannerPar_t; +typedef struct __RFC_STRUCT rfc_bleInitiatorPar_s rfc_bleInitiatorPar_t; +typedef struct __RFC_STRUCT rfc_bleGenericRxPar_s rfc_bleGenericRxPar_t; +typedef struct __RFC_STRUCT rfc_bleTxTestPar_s rfc_bleTxTestPar_t; +typedef struct __RFC_STRUCT rfc_bleMasterSlaveOutput_s rfc_bleMasterSlaveOutput_t; +typedef struct __RFC_STRUCT rfc_bleAdvOutput_s rfc_bleAdvOutput_t; +typedef struct __RFC_STRUCT rfc_bleScannerOutput_s rfc_bleScannerOutput_t; +typedef struct __RFC_STRUCT rfc_bleInitiatorOutput_s rfc_bleInitiatorOutput_t; +typedef struct __RFC_STRUCT rfc_bleGenericRxOutput_s rfc_bleGenericRxOutput_t; +typedef struct __RFC_STRUCT rfc_bleTxTestOutput_s rfc_bleTxTestOutput_t; +typedef struct __RFC_STRUCT rfc_bleWhiteListEntry_s rfc_bleWhiteListEntry_t; +typedef struct __RFC_STRUCT rfc_bleRxStatus_s rfc_bleRxStatus_t; + +//! \addtogroup bleRadioOp +//! @{ +struct __RFC_STRUCT rfc_bleRadioOp_s { + uint16_t commandNo; //!< The command ID number + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
    + //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
    + //!< 0: Do not use whitening
    + //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
    + //!< 1: Override whitening initialization with value of init + } whitening; + uint8_t* pParams; //!< Pointer to command specific parameter structure + uint8_t* pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_SLAVE +//! @{ +#define CMD_BLE_SLAVE 0x1801 +struct __RFC_STRUCT rfc_CMD_BLE_SLAVE_s { + uint16_t commandNo; //!< The command ID number 0x1801 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
    + //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
    + //!< 0: Do not use whitening
    + //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
    + //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleSlavePar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleMasterSlaveOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_MASTER +//! @{ +#define CMD_BLE_MASTER 0x1802 +struct __RFC_STRUCT rfc_CMD_BLE_MASTER_s { + uint16_t commandNo; //!< The command ID number 0x1802 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
    + //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
    + //!< 0: Do not use whitening
    + //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
    + //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleMasterPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleMasterSlaveOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_ADV +//! @{ +#define CMD_BLE_ADV 0x1803 +struct __RFC_STRUCT rfc_CMD_BLE_ADV_s { + uint16_t commandNo; //!< The command ID number 0x1803 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
    + //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
    + //!< 0: Do not use whitening
    + //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
    + //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleAdvPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleAdvOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_ADV_DIR +//! @{ +#define CMD_BLE_ADV_DIR 0x1804 +struct __RFC_STRUCT rfc_CMD_BLE_ADV_DIR_s { + uint16_t commandNo; //!< The command ID number 0x1804 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
    + //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
    + //!< 0: Do not use whitening
    + //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
    + //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleAdvPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleAdvOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_ADV_NC +//! @{ +#define CMD_BLE_ADV_NC 0x1805 +struct __RFC_STRUCT rfc_CMD_BLE_ADV_NC_s { + uint16_t commandNo; //!< The command ID number 0x1805 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
    + //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
    + //!< 0: Do not use whitening
    + //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
    + //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleAdvPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleAdvOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_ADV_SCAN +//! @{ +#define CMD_BLE_ADV_SCAN 0x1806 +struct __RFC_STRUCT rfc_CMD_BLE_ADV_SCAN_s { + uint16_t commandNo; //!< The command ID number 0x1806 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
    + //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
    + //!< 0: Do not use whitening
    + //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
    + //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleAdvPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleAdvOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_SCANNER +//! @{ +#define CMD_BLE_SCANNER 0x1807 +struct __RFC_STRUCT rfc_CMD_BLE_SCANNER_s { + uint16_t commandNo; //!< The command ID number 0x1807 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
    + //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
    + //!< 0: Do not use whitening
    + //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
    + //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleScannerPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleScannerOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_INITIATOR +//! @{ +#define CMD_BLE_INITIATOR 0x1808 +struct __RFC_STRUCT rfc_CMD_BLE_INITIATOR_s { + uint16_t commandNo; //!< The command ID number 0x1808 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
    + //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
    + //!< 0: Do not use whitening
    + //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
    + //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleInitiatorPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleInitiatorOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_GENERIC_RX +//! @{ +#define CMD_BLE_GENERIC_RX 0x1809 +struct __RFC_STRUCT rfc_CMD_BLE_GENERIC_RX_s { + uint16_t commandNo; //!< The command ID number 0x1809 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
    + //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
    + //!< 0: Do not use whitening
    + //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
    + //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleGenericRxPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleGenericRxOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_TX_TEST +//! @{ +#define CMD_BLE_TX_TEST 0x180A +struct __RFC_STRUCT rfc_CMD_BLE_TX_TEST_s { + uint16_t commandNo; //!< The command ID number 0x180A + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
    + //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
    + //!< 0: Do not use whitening
    + //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
    + //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleTxTestPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleTxTestOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_ADV_PAYLOAD +//! @{ +#define CMD_BLE_ADV_PAYLOAD 0x1001 +struct __RFC_STRUCT rfc_CMD_BLE_ADV_PAYLOAD_s { + uint16_t commandNo; //!< The command ID number 0x1001 + uint8_t payloadType; //!< \brief 0: Advertising data
    + //!< 1: Scan response data + uint8_t newLen; //!< Length of the new payload + uint8_t* pNewData; //!< Pointer to the buffer containing the new data + rfc_bleAdvPar_t *pParams; //!< Pointer to the parameter structure to update +}; + +//! @} + +//! \addtogroup bleMasterSlavePar +//! @{ +struct __RFC_STRUCT rfc_bleMasterSlavePar_s { + dataQueue_t* pRxQ; //!< Pointer to receive queue + dataQueue_t* pTxQ; //!< Pointer to transmit queue + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue + uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue + uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + } rxConfig; //!< Configuration bits for the receive queue entries + struct { + uint8_t lastRxSn:1; //!< The SN bit of the header of the last packet received with CRC OK + uint8_t lastTxSn:1; //!< The SN bit of the header of the last transmitted packet + uint8_t nextTxSn:1; //!< The SN bit of the header of the next packet to transmit + uint8_t bFirstPkt:1; //!< For slave: 0 if a packet has been transmitted on the connection, 1 otherwise + uint8_t bAutoEmpty:1; //!< 1 if the last transmitted packet was an auto-empty packet + uint8_t bLlCtrlTx:1; //!< 1 if the last transmitted packet was an LL control packet (LLID = 11) + uint8_t bLlCtrlAckRx:1; //!< 1 if the last received packet was the ACK of an LL control packet + uint8_t bLlCtrlAckPending:1; //!< 1 if the last successfully received packet was an LL control packet which has not yet been ACK'ed + } seqStat; + uint8_t maxNack; //!< Maximum number of NACKs received before operation ends. 0: No limit + uint8_t maxPkt; //!< Maximum number of packets transmitted in the operation before it ends. 0: No limit + uint32_t accessAddress; //!< Access address used on the connection + uint8_t crcInit0; //!< CRC initialization value used on the connection – least significant byte + uint8_t crcInit1; //!< CRC initialization value used on the connection – middle byte + uint8_t crcInit2; //!< CRC initialization value used on the connection – most significant byte +}; + +//! @} + +//! \addtogroup bleMasterPar +//! @{ +//! Parameter structure for master (CMD_BLE_MASTER) + +struct __RFC_STRUCT rfc_bleMasterPar_s { + dataQueue_t* pRxQ; //!< Pointer to receive queue + dataQueue_t* pTxQ; //!< Pointer to transmit queue + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue + uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue + uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + } rxConfig; //!< Configuration bits for the receive queue entries + struct { + uint8_t lastRxSn:1; //!< The SN bit of the header of the last packet received with CRC OK + uint8_t lastTxSn:1; //!< The SN bit of the header of the last transmitted packet + uint8_t nextTxSn:1; //!< The SN bit of the header of the next packet to transmit + uint8_t bFirstPkt:1; //!< For slave: 0 if a packet has been transmitted on the connection, 1 otherwise + uint8_t bAutoEmpty:1; //!< 1 if the last transmitted packet was an auto-empty packet + uint8_t bLlCtrlTx:1; //!< 1 if the last transmitted packet was an LL control packet (LLID = 11) + uint8_t bLlCtrlAckRx:1; //!< 1 if the last received packet was the ACK of an LL control packet + uint8_t bLlCtrlAckPending:1; //!< 1 if the last successfully received packet was an LL control packet which has not yet been ACK'ed + } seqStat; + uint8_t maxNack; //!< Maximum number of NACKs received before operation ends. 0: No limit + uint8_t maxPkt; //!< Maximum number of packets transmitted in the operation before it ends. 0: No limit + uint32_t accessAddress; //!< Access address used on the connection + uint8_t crcInit0; //!< CRC initialization value used on the connection – least significant byte + uint8_t crcInit1; //!< CRC initialization value used on the connection – middle byte + uint8_t crcInit2; //!< CRC initialization value used on the connection – most significant byte + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to end the connection event as soon as allowed + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the + //!< connection event as soon as allowed +}; + +//! @} + +//! \addtogroup bleSlavePar +//! @{ +//! Parameter structure for slave (CMD_BLE_SLAVE) + +struct __RFC_STRUCT rfc_bleSlavePar_s { + dataQueue_t* pRxQ; //!< Pointer to receive queue + dataQueue_t* pTxQ; //!< Pointer to transmit queue + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue + uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue + uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + } rxConfig; //!< Configuration bits for the receive queue entries + struct { + uint8_t lastRxSn:1; //!< The SN bit of the header of the last packet received with CRC OK + uint8_t lastTxSn:1; //!< The SN bit of the header of the last transmitted packet + uint8_t nextTxSn:1; //!< The SN bit of the header of the next packet to transmit + uint8_t bFirstPkt:1; //!< For slave: 0 if a packet has been transmitted on the connection, 1 otherwise + uint8_t bAutoEmpty:1; //!< 1 if the last transmitted packet was an auto-empty packet + uint8_t bLlCtrlTx:1; //!< 1 if the last transmitted packet was an LL control packet (LLID = 11) + uint8_t bLlCtrlAckRx:1; //!< 1 if the last received packet was the ACK of an LL control packet + uint8_t bLlCtrlAckPending:1; //!< 1 if the last successfully received packet was an LL control packet which has not yet been ACK'ed + } seqStat; + uint8_t maxNack; //!< Maximum number of NACKs received before operation ends. 0: No limit + uint8_t maxPkt; //!< Maximum number of packets transmitted in the operation before it ends. 0: No limit + uint32_t accessAddress; //!< Access address used on the connection + uint8_t crcInit0; //!< CRC initialization value used on the connection – least significant byte + uint8_t crcInit1; //!< CRC initialization value used on the connection – middle byte + uint8_t crcInit2; //!< CRC initialization value used on the connection – most significant byte + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } timeoutTrigger; //!< Trigger that defines timeout of the first receive operation + ratmr_t timeoutTime; //!< \brief Time used together with timeoutTrigger that defines timeout of the first + //!< receive operation + uint16_t __dummy0; + uint8_t __dummy1; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to end the connection event as soon as allowed + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the + //!< connection event as soon as allowed +}; + +//! @} + +//! \addtogroup bleAdvPar +//! @{ +//! Parameter structure for advertiser (CMD_BLE_ADV*) + +struct __RFC_STRUCT rfc_bleAdvPar_s { + dataQueue_t* pRxQ; //!< Pointer to receive queue + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue + uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue + uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + } rxConfig; //!< Configuration bits for the receive queue entries + struct { + uint8_t advFilterPolicy:2; //!< \brief The advertiser filter policy, as defined in Volume 2, Part E, Section 7.8.5 of + //!< the Bluetooth 4.0 spec + uint8_t deviceAddrType:1; //!< The type of the device address – public (0) or random (1) + uint8_t peerAddrType:1; //!< Directed advertiser: The type of the peer address – public (0) or random (1) + uint8_t bStrictLenFilter:1; //!< 1: Discard messages with illegal length + } advConfig; + uint8_t advLen; //!< Size of advertiser data + uint8_t scanRspLen; //!< Size of scan response data + uint8_t* pAdvData; //!< Pointer to buffer containing ADV*_IND data + uint8_t* pScanRspData; //!< Pointer to buffer containing SCAN_RSP data + uint16_t* pDeviceAddress; //!< Pointer to device address used for this device + rfc_bleWhiteListEntry_t *pWhiteList; //!< Pointer to white list or peer address (directed advertiser) + uint16_t __dummy0; + uint8_t __dummy1; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to end the advertiser event as soon as allowed + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the + //!< advertiser event as soon as allowed +}; + +//! @} + +//! \addtogroup bleScannerPar +//! @{ +//! Parameter structure for scanner (CMD_BLE_SCANNER) + +struct __RFC_STRUCT rfc_bleScannerPar_s { + dataQueue_t* pRxQ; //!< Pointer to receive queue + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue + uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue + uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + } rxConfig; //!< Configuration bits for the receive queue entries + struct { + uint8_t scanFilterPolicy:1; //!< \brief The advertiser filter policy, as defined in Volume 2, Part E, Section 7.8.10 of + //!< the Bluetooth 4.0 spec + uint8_t bActiveScan:1; //!< \brief 0: Passive scan
    + //!< 1: Active scan + uint8_t deviceAddrType:1; //!< The type of the device address – public (0) or random (1) + uint8_t :1; + uint8_t bStrictLenFilter:1; //!< 1: Discard messages with illegal length + uint8_t bAutoWlIgnore:1; //!< 1: Automatically set ignore bit in white list + uint8_t bEndOnRpt:1; //!< 1: End scanner operation after each reported ADV*_IND and potentially SCAN_RSP + } scanConfig; + uint16_t randomState; //!< State for pseudo-random number generation used in backoff procedure + uint16_t backoffCount; //!< Parameter backoffCount used in backoff procedure, cf. Bluetooth 4.0 spec + struct { + uint8_t logUpperLimit:4; //!< Binary logarithm of parameter upperLimit used in scanner backoff procedure + uint8_t bLastSucceeded:1; //!< \brief 1 if the last SCAN_RSP was successfully received and upperLimit + //!< not changed + uint8_t bLastFailed:1; //!< \brief 1 if reception of the last SCAN_RSP failed and upperLimit was not + //!< changed + } backoffPar; + uint8_t scanReqLen; //!< Size of scan request data + uint8_t* pScanReqData; //!< Pointer to buffer containing SCAN_REQ data + uint16_t* pDeviceAddress; //!< Pointer to device address used for this device + rfc_bleWhiteListEntry_t *pWhiteList; //!< Pointer to white list + uint16_t __dummy0; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } timeoutTrigger; //!< Trigger that causes the device to stop receiving as soon as allowed + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to stop receiving as soon as allowed + ratmr_t timeoutTime; //!< \brief Time used together with timeoutTrigger that causes the device to stop + //!< receiving as soon as allowed, ending with BLE_DONE_RXTIMEOUT + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to stop + //!< receiving as soon as allowed, ending with BLE_DONE_ENDED +}; + +//! @} + +//! \addtogroup bleInitiatorPar +//! @{ +//! Parameter structure for initiator (CMD_BLE_INITIATOR) + +struct __RFC_STRUCT rfc_bleInitiatorPar_s { + dataQueue_t* pRxQ; //!< Pointer to receive queue + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue + uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue + uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + } rxConfig; //!< Configuration bits for the receive queue entries + struct { + uint8_t bUseWhiteList:1; //!< \brief Initiator filter policy, cf. Volume 2, Part E, Section 7.8.10 of the + //!< Bluetooth 4.0 spec:
    + //!< 0: Use specific peer address
    + //!< 1: Use white list + uint8_t bDynamicWinOffset:1; //!< 1: Use dynamic WinOffset insertion + uint8_t deviceAddrType:1; //!< The type of the device address – public (0) or random (1) + uint8_t peerAddrType:1; //!< The type of the peer address – public (0) or random (1) + uint8_t bStrictLenFilter:1; //!< 1: Discard messages with illegal length + } initConfig; + uint8_t __dummy0; + uint8_t connectReqLen; //!< Size of connect request data + uint8_t* pConnectReqData; //!< Pointer to buffer containing LLData to go in the CONNECT_REQ + uint16_t* pDeviceAddress; //!< Pointer to device address used for this device + rfc_bleWhiteListEntry_t *pWhiteList; //!< Pointer to white list or peer address + ratmr_t connectTime; //!< \brief Indication of timer value of the first possible start time of the first connection event. + //!< Set to the calculated value if a connection is made and to the next possible connection + //!< time if not. + uint16_t __dummy1; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } timeoutTrigger; //!< Trigger that causes the device to stop receiving as soon as allowed + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to stop receiving as soon as allowed + ratmr_t timeoutTime; //!< \brief Time used together with timeoutTrigger that causes the device to stop + //!< receiving as soon as allowed, ending with BLE_DONE_RXTIMEOUT + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to stop + //!< receiving as soon as allowed, ending with BLE_DONE_ENDED +}; + +//! @} + +//! \addtogroup bleGenericRxPar +//! @{ +//! Parameter structure for generic Rx (CMD_BLE_GENERIC_RX) + +struct __RFC_STRUCT rfc_bleGenericRxPar_s { + dataQueue_t* pRxQ; //!< Pointer to receive queue. May be NULL; if so, received packets are not stored + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue + uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue + uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + } rxConfig; //!< Configuration bits for the receive queue entries + uint8_t bRepeat; //!< \brief 0: End operation after receiving a packet
    + //!< 1: Restart receiver after receiving a packet + uint16_t __dummy0; + uint32_t accessAddress; //!< Access address used on the connection + uint8_t crcInit0; //!< CRC initialization value used on the connection – least significant byte + uint8_t crcInit1; //!< CRC initialization value used on the connection – middle byte + uint8_t crcInit2; //!< CRC initialization value used on the connection – most significant byte + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to end the Rx operation + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the + //!< Rx operation +}; + +//! @} + +//! \addtogroup bleTxTestPar +//! @{ +//! Parameter structure for Tx test (CMD_BLE_TX_TEST) + +struct __RFC_STRUCT rfc_bleTxTestPar_s { + uint16_t numPackets; //!< \brief Number of packets to transmit
    + //!< 0: Transmit unlimited number of packets + uint8_t payloadLength; //!< The number of payload bytes in each packet. + uint8_t packetType; //!< \brief The packet type to be used, encoded according to the Bluetooth 4.0 spec, Volume 2, Part E, + //!< Section 7.8.29 + ratmr_t period; //!< Number of radio timer cycles between the start of each packet + struct { + uint8_t bOverrideDefault:1; //!< \brief 0: Use default packet encoding
    + //!< 1: Override packet contents + uint8_t bUsePrbs9:1; //!< \brief If bOverride is 1:
    + //!< 1: Use PRBS9 encoding of packet + uint8_t bUsePrbs15:1; //!< \brief If bOverride is 1:
    + //!< 1: Use PRBS15 encoding of packet + } config; + uint8_t byteVal; //!< If config.bOverride is 1, value of each byte to be sent + uint8_t __dummy0; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to end the Test Tx operation + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the + //!< Test Tx operation +}; + +//! @} + +//! \addtogroup bleMasterSlaveOutput +//! @{ +//! Output structure for master and slave (CMD_BLE_MASTER/CMD_BLE_SLAVE) + +struct __RFC_STRUCT rfc_bleMasterSlaveOutput_s { + uint8_t nTx; //!< \brief Total number of packets (including auto-empty and retransmissions) that have been + //!< transmitted + uint8_t nTxAck; //!< Total number of transmitted packets (including auto-empty) that have been ACK'ed + uint8_t nTxCtrl; //!< Number of unique LL control packets from the Tx queue that have been transmitted + uint8_t nTxCtrlAck; //!< Number of LL control packets from the Tx queue that have been finished (ACK'ed) + uint8_t nTxCtrlAckAck; //!< \brief Number of LL control packets that have been ACK'ed and where an ACK has been sent in + //!< response + uint8_t nTxRetrans; //!< Number of retransmissions that has been done + uint8_t nTxEntryDone; //!< Number of packets from the Tx queue that have been finished (ACK'ed) + uint8_t nRxOk; //!< Number of packets that have been received with payload, CRC OK and not ignored + uint8_t nRxCtrl; //!< Number of LL control packets that have been received with CRC OK and not ignored + uint8_t nRxCtrlAck; //!< \brief Number of LL control packets that have been received with CRC OK and not ignored, and + //!< then ACK'ed + uint8_t nRxNok; //!< Number of packets that have been received with CRC error + uint8_t nRxIgnored; //!< \brief Number of packets that have been received with CRC OK and ignored due to repeated + //!< sequence number + uint8_t nRxEmpty; //!< Number of packets that have been received with CRC OK and no payload + uint8_t nRxBufFull; //!< Number of packets that have been received and discarded due to lack of buffer space + int8_t lastRssi; //!< RSSI of last received packet + struct { + uint8_t bTimeStampValid:1; //!< 1 if a valid time stamp has been written to timeStamp; 0 otherwise + uint8_t bLastCrcErr:1; //!< 1 if the last received packet had CRC error; 0 otherwise + uint8_t bLastIgnored:1; //!< 1 if the last received packet with CRC OK was ignored; 0 otherwise + uint8_t bLastEmpty:1; //!< 1 if the last received packet with CRC OK was empty; 0 otherwise + uint8_t bLastCtrl:1; //!< 1 if the last received packet with CRC OK was empty; 0 otherwise + uint8_t bLastMd:1; //!< 1 if the last received packet with CRC OK had MD = 1; 0 otherwise + uint8_t bLastAck:1; //!< \brief 1 if the last received packet with CRC OK was an ACK of a transmitted packet; + //!< 0 otherwise + } pktStatus; + ratmr_t timeStamp; //!< Slave operation: Time stamp of first received packet +}; + +//! @} + +//! \addtogroup bleAdvOutput +//! @{ +//! Output structure for advertiser (CMD_BLE_ADV*) + +struct __RFC_STRUCT rfc_bleAdvOutput_s { + uint16_t nTxAdvInd; //!< Number of ADV*_IND packets completely transmitted + uint8_t nTxScanRsp; //!< Number of SCAN_RSP packets transmitted + uint8_t nRxScanReq; //!< Number of SCAN_REQ packets received OK and not ignored + uint8_t nRxConnectReq; //!< Number of CONNECT_REQ packets received OK and not ignored + uint8_t __dummy0; + uint16_t nRxNok; //!< Number of packets received with CRC error + uint16_t nRxIgnored; //!< Number of packets received with CRC OK, but ignored + uint8_t nRxBufFull; //!< Number of packets received that did not fit in Rx queue + int8_t lastRssi; //!< The RSSI of the last received packet + ratmr_t timeStamp; //!< Time stamp of the last received packet +}; + +//! @} + +//! \addtogroup bleScannerOutput +//! @{ +//! Output structure for scanner (CMD_BLE_SCANNER) + +struct __RFC_STRUCT rfc_bleScannerOutput_s { + uint16_t nTxScanReq; //!< Number of transmitted SCAN_REQ packets + uint16_t nBackedOffScanReq; //!< Number of SCAN_REQ packets not sent due to backoff procedure + uint16_t nRxAdvOk; //!< Number of ADV*_IND packets received with CRC OK and not ignored + uint16_t nRxAdvIgnored; //!< Number of ADV*_IND packets received with CRC OK, but ignored + uint16_t nRxAdvNok; //!< Number of ADV*_IND packets received with CRC error + uint16_t nRxScanRspOk; //!< Number of SCAN_RSP packets received with CRC OK and not ignored + uint16_t nRxScanRspIgnored; //!< Number of SCAN_RSP packets received with CRC OK, but ignored + uint16_t nRxScanRspNok; //!< Number of SCAN_RSP packets received with CRC error + uint8_t nRxAdvBufFull; //!< Number of ADV*_IND packets received that did not fit in Rx queue + uint8_t nRxScanRspBufFull; //!< Number of SCAN_RSP packets received that did not fit in Rx queue + int8_t lastRssi; //!< The RSSI of the last received packet + uint8_t __dummy0; + ratmr_t timeStamp; //!< Time stamp of the last successfully received ADV*_IND packet that was not ignored +}; + +//! @} + +//! \addtogroup bleInitiatorOutput +//! @{ +//! Output structure for initiator (CMD_BLE_INITIATOR) + +struct __RFC_STRUCT rfc_bleInitiatorOutput_s { + uint8_t nTxConnectReq; //!< Number of transmitted CONNECT_REQ packets + uint8_t nRxAdvOk; //!< Number of ADV*_IND packets received with CRC OK and not ignored + uint16_t nRxAdvIgnored; //!< Number of ADV*_IND packets received with CRC OK, but ignored + uint16_t nRxAdvNok; //!< Number of ADV*_IND packets received with CRC error + uint8_t nRxAdvBufFull; //!< Number of ADV*_IND packets received that did not fit in Rx queue + int8_t lastRssi; //!< The RSSI of the last received packet + ratmr_t timeStamp; //!< Time stamp of the received ADV*_IND packet that caused transmission of CONNECT_REQ +}; + +//! @} + +//! \addtogroup bleGenericRxOutput +//! @{ +//! Output structure for generic Rx (CMD_BLE_GENERIC_RX) + +struct __RFC_STRUCT rfc_bleGenericRxOutput_s { + uint16_t nRxOk; //!< Number of packets received with CRC OK + uint16_t nRxNok; //!< Number of packets received with CRC error + uint16_t nRxBufFull; //!< Number of packets that have been received and discarded due to lack of buffer space + int8_t lastRssi; //!< The RSSI of the last received packet + uint8_t __dummy0; + ratmr_t timeStamp; //!< Time stamp of the last received packet +}; + +//! @} + +//! \addtogroup bleTxTestOutput +//! @{ +//! Output structure for Tx test (CMD_BLE_TX_TEST) + +struct __RFC_STRUCT rfc_bleTxTestOutput_s { + uint16_t nTx; //!< Number of packets transmitted +}; + +//! @} + +//! \addtogroup bleWhiteListEntry +//! @{ +//! White list entry structure + +struct __RFC_STRUCT rfc_bleWhiteListEntry_s { + uint8_t size; //!< Number of while list entries. Used in the first entry of the list only + struct { + uint8_t bEnable:1; //!< 1 if the entry is in use, 0 if the entry is not in use + uint8_t addrType:1; //!< The type address in the entry – public (0) or random (1) + uint8_t bWlIgn:1; //!< \brief 1 if the entry is to be ignored by a scanner, 0 otherwise. Used to mask out + //!< entries that have already been scanned and reported. + } conf; + uint16_t address; //!< Least significant 16 bits of the address contained in the entry + uint32_t addressHi; //!< Most significant 32 bits of the address contained in the entry +}; + +//! @} + +//! \addtogroup bleRxStatus +//! @{ +//! Receive status byte that may be appended to message in receive buffer + +struct __RFC_STRUCT rfc_bleRxStatus_s { + struct { + uint8_t channel:6; //!< \brief The channel on which the packet was received, provided channel is in the range + //!< 0–39; otherwise 0x3F + uint8_t bIgnore:1; //!< 1 if the packet is marked as ignored, 0 otherwise + uint8_t bCrcErr:1; //!< 1 if the packet was received with CRC error, 0 otherwise + } status; +}; + +//! @} + +//! @} +//! @} +#endif /* BLE_CMD_H_ */ diff --git a/cpu/cc26xx-cc13xx/rf-core/api/ble_mailbox.h b/cpu/cc26xx-cc13xx/rf-core/api/ble_mailbox.h new file mode 100644 index 000000000..dcce1996c --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/api/ble_mailbox.h @@ -0,0 +1,69 @@ +/****************************************************************************** +* Filename: ble_mailbox.h +* Revised: $ $ +* Revision: $ $ +* +* Description: Definitions for BLE interface +* +* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* 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 Texas Instruments Incorporated 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 +* OWNER 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. +* +******************************************************************************/ + +#ifndef BLE_MAILBOX_H_ +#define BLE_MAILBOX_H_ + +/// \name Radio operation status +///@{ +/// \name Operation finished normally +///@{ +#define BLE_DONE_OK 0x1400 ///< Operation ended normally +#define BLE_DONE_RXTIMEOUT 0x1401 ///< Timeout of first Rx of slave operation or end of scan window +#define BLE_DONE_NOSYNC 0x1402 ///< Timeout of subsequent Rx +#define BLE_DONE_RXERR 0x1403 ///< Operation ended because of receive error (CRC or other) +#define BLE_DONE_CONNECT 0x1404 ///< CONNECT_REQ received or transmitted +#define BLE_DONE_MAXNACK 0x1405 ///< Maximum number of retransmissions exceeded +#define BLE_DONE_ENDED 0x1406 ///< Operation stopped after end trigger +#define BLE_DONE_ABORT 0x1407 ///< Operation aborted by command +#define BLE_DONE_STOPPED 0x1408 ///< Operation stopped after stop command +///@} +/// \name Operation finished with error +///@{ +#define BLE_ERROR_PAR 0x1800 ///< Illegal parameter +#define BLE_ERROR_RXBUF 0x1801 ///< No available Rx buffer (Advertiser, Scanner, Initiator) +#define BLE_ERROR_NO_SETUP 0x1802 ///< Operation using Rx or Tx attemted when not in BLE mode +#define BLE_ERROR_NO_FS 0x1803 ///< Operation using Rx or Tx attemted without frequency synth configured +#define BLE_ERROR_SYNTH_PROG 0x1804 ///< Synthesizer programming failed to complete on time +#define BLE_ERROR_RXOVF 0x1805 ///< Receiver overflowed during operation +#define BLE_ERROR_TXUNF 0x1806 ///< Transmitter underflowed during operation +///@} +///@} + +#endif /* BLE_MAILBOX_H_ */ diff --git a/cpu/cc26xx-cc13xx/rf-core/api/common_cmd.h b/cpu/cc26xx-cc13xx/rf-core/api/common_cmd.h new file mode 100644 index 000000000..308f0c3ee --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/api/common_cmd.h @@ -0,0 +1,1031 @@ +/****************************************************************************** +* Filename: common_cmd.h +* Revised: 2015-08-04 10:40:45 +0200 (Tue, 04 Aug 2015) +* Revision: 44326 +* +* Description: CC13xx API for common/generic commands +* +* Copyright (c) 2015, Texas Instruments Incorporated +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1) Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2) 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. +* +* 3) Neither the name of the ORGANIZATION 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. +* +******************************************************************************/ + +#ifndef COMMON_CMD_H_ +#define COMMON_CMD_H_ + +#ifndef __RFC_STRUCT +#ifdef __GNUC__ +#define __RFC_STRUCT __attribute__ ((aligned (4))) +#else +#define __RFC_STRUCT +#endif +#endif + +//! \addtogroup rfc +//! @{ + +//! \addtogroup common_cmd +//! @{ + +#include +#include "mailbox.h" + +typedef struct __RFC_STRUCT rfc_command_s rfc_command_t; +typedef struct __RFC_STRUCT rfc_radioOp_s rfc_radioOp_t; +typedef struct __RFC_STRUCT rfc_CMD_NOP_s rfc_CMD_NOP_t; +typedef struct __RFC_STRUCT rfc_CMD_RADIO_SETUP_s rfc_CMD_RADIO_SETUP_t; +typedef struct __RFC_STRUCT rfc_CMD_FS_s rfc_CMD_FS_t; +typedef struct __RFC_STRUCT rfc_CMD_FS_OFF_s rfc_CMD_FS_OFF_t; +typedef struct __RFC_STRUCT rfc_CMD_RX_s rfc_CMD_RX_t; +typedef struct __RFC_STRUCT rfc_CMD_TX_s rfc_CMD_TX_t; +typedef struct __RFC_STRUCT rfc_CMD_RX_TEST_s rfc_CMD_RX_TEST_t; +typedef struct __RFC_STRUCT rfc_CMD_TX_TEST_s rfc_CMD_TX_TEST_t; +typedef struct __RFC_STRUCT rfc_CMD_SYNC_STOP_RAT_s rfc_CMD_SYNC_STOP_RAT_t; +typedef struct __RFC_STRUCT rfc_CMD_SYNC_START_RAT_s rfc_CMD_SYNC_START_RAT_t; +typedef struct __RFC_STRUCT rfc_CMD_COUNT_s rfc_CMD_COUNT_t; +typedef struct __RFC_STRUCT rfc_CMD_FS_POWERUP_s rfc_CMD_FS_POWERUP_t; +typedef struct __RFC_STRUCT rfc_CMD_FS_POWERDOWN_s rfc_CMD_FS_POWERDOWN_t; +typedef struct __RFC_STRUCT rfc_CMD_SCH_IMM_s rfc_CMD_SCH_IMM_t; +typedef struct __RFC_STRUCT rfc_CMD_COUNT_BRANCH_s rfc_CMD_COUNT_BRANCH_t; +typedef struct __RFC_STRUCT rfc_CMD_PATTERN_CHECK_s rfc_CMD_PATTERN_CHECK_t; +typedef struct __RFC_STRUCT rfc_CMD_TX_POWER_BOOST_s rfc_CMD_TX_POWER_BOOST_t; +typedef struct __RFC_STRUCT rfc_CMD_ABORT_s rfc_CMD_ABORT_t; +typedef struct __RFC_STRUCT rfc_CMD_STOP_s rfc_CMD_STOP_t; +typedef struct __RFC_STRUCT rfc_CMD_GET_RSSI_s rfc_CMD_GET_RSSI_t; +typedef struct __RFC_STRUCT rfc_CMD_UPDATE_RADIO_SETUP_s rfc_CMD_UPDATE_RADIO_SETUP_t; +typedef struct __RFC_STRUCT rfc_CMD_TRIGGER_s rfc_CMD_TRIGGER_t; +typedef struct __RFC_STRUCT rfc_CMD_GET_FW_INFO_s rfc_CMD_GET_FW_INFO_t; +typedef struct __RFC_STRUCT rfc_CMD_START_RAT_s rfc_CMD_START_RAT_t; +typedef struct __RFC_STRUCT rfc_CMD_PING_s rfc_CMD_PING_t; +typedef struct __RFC_STRUCT rfc_CMD_ADD_DATA_ENTRY_s rfc_CMD_ADD_DATA_ENTRY_t; +typedef struct __RFC_STRUCT rfc_CMD_REMOVE_DATA_ENTRY_s rfc_CMD_REMOVE_DATA_ENTRY_t; +typedef struct __RFC_STRUCT rfc_CMD_FLUSH_QUEUE_s rfc_CMD_FLUSH_QUEUE_t; +typedef struct __RFC_STRUCT rfc_CMD_CLEAR_RX_s rfc_CMD_CLEAR_RX_t; +typedef struct __RFC_STRUCT rfc_CMD_REMOVE_PENDING_ENTRIES_s rfc_CMD_REMOVE_PENDING_ENTRIES_t; +typedef struct __RFC_STRUCT rfc_CMD_SET_RAT_CMP_s rfc_CMD_SET_RAT_CMP_t; +typedef struct __RFC_STRUCT rfc_CMD_SET_RAT_CPT_s rfc_CMD_SET_RAT_CPT_t; +typedef struct __RFC_STRUCT rfc_CMD_DISABLE_RAT_CH_s rfc_CMD_DISABLE_RAT_CH_t; +typedef struct __RFC_STRUCT rfc_CMD_SET_RAT_OUTPUT_s rfc_CMD_SET_RAT_OUTPUT_t; +typedef struct __RFC_STRUCT rfc_CMD_ARM_RAT_CH_s rfc_CMD_ARM_RAT_CH_t; +typedef struct __RFC_STRUCT rfc_CMD_DISARM_RAT_CH_s rfc_CMD_DISARM_RAT_CH_t; +typedef struct __RFC_STRUCT rfc_CMD_SET_TX_POWER_s rfc_CMD_SET_TX_POWER_t; +typedef struct __RFC_STRUCT rfc_CMD_UPDATE_FS_s rfc_CMD_UPDATE_FS_t; +typedef struct __RFC_STRUCT rfc_CMD_BUS_REQUEST_s rfc_CMD_BUS_REQUEST_t; + +//! \addtogroup command +//! @{ +struct __RFC_STRUCT rfc_command_s { + uint16_t commandNo; //!< The command ID number +}; + +//! @} + +//! \addtogroup radioOp +//! @{ +//! Common definition for radio operation commands + +struct __RFC_STRUCT rfc_radioOp_s { + uint16_t commandNo; //!< The command ID number + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; +}; + +//! @} + +//! \addtogroup CMD_NOP +//! @{ +#define CMD_NOP 0x0801 +struct __RFC_STRUCT rfc_CMD_NOP_s { + uint16_t commandNo; //!< The command ID number 0x0801 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; +}; + +//! @} + +//! \addtogroup CMD_RADIO_SETUP +//! @{ +#define CMD_RADIO_SETUP 0x0802 +struct __RFC_STRUCT rfc_CMD_RADIO_SETUP_s { + uint16_t commandNo; //!< The command ID number 0x0802 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t mode; //!< \brief The main mode to use
    + //!< 0x00: BLE
    + //!< 0x01: IEEE 802.15.4
    + //!< 0x02: 2 Mbps GFSK
    + //!< 0x05: 5 Mbps coded 8-FSK
    + //!< 0x06: ANT
    + //!< 0xFF: Keep existing mode; update overrides only
    + //!< Others: Reserved + uint8_t loDivider; //!< \brief LO divider setting to use. Supported values: 0 (equivalent to 2), 2, 5, 6, 10, 12, 15, + //!< and 30.
    + //!< Value of 0 or 2 only supported for devices that support 2.4 GHz operation + struct { + uint16_t frontEndMode:3; //!< \brief 0x00: Differential mode
    + //!< 0x01: Single-ended mode RFP
    + //!< 0x02: Single-ended mode RFN
    + //!< 0x05 Single-ended mode RFP with external frontend control on RF pins (RFN and RXTX)
    + //!< 0x06 Single-ended mode RFN with external frontend control on RF pins (RFP and RXTX)
    + //!< Others: Reserved + uint16_t biasMode:1; //!< \brief 0: Internal bias
    + //!< 1: External bias + uint16_t :6; + uint16_t bNoFsPowerUp:1; //!< \brief 0: Power up frequency synth
    + //!< 1: Do not power up frequency synth + } config; //!< Configuration options + struct { + uint16_t IB:6; //!< Value to write to the PA power control field at 25 °C + uint16_t GC:2; //!< Value to write to the gain control of the 1st stage of the PA + uint16_t boost:1; //!< Value of boost bit in synth + uint16_t tempCoeff:7; //!< Temperature coefficient for IB. 0: No temperature compensation + } txPower; //!< Transmit power + uint32_t* pRegOverride; //!< \brief Pointer to a list of hardware and configuration registers to override. If NULL, no + //!< override is used. +}; + +//! @} + +//! \addtogroup CMD_FS +//! @{ +#define CMD_FS 0x0803 +struct __RFC_STRUCT rfc_CMD_FS_s { + uint16_t commandNo; //!< The command ID number 0x0803 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint16_t frequency; //!< The frequency in MHz to tune to + uint16_t fractFreq; //!< Fractional part of the frequency to tune to + struct { + uint8_t bTxMode:1; //!< \brief 0: Start synth in Rx mode
    + //!< 1: Start synth in Tx mode + uint8_t refFreq:6; //!< \brief 0: Use default reference frequency
    + //!< Others: Use reference frequency 24 MHz/refFreq + } synthConf; + uint8_t __dummy0; + uint8_t midPrecal; //!< Mid pre-calibration value to use when bOverrideCalib and bSkipCoarseCalib are both 1 + uint8_t ktPrecal; //!< KT pre-calibration value to use when bOverrideCalib and bSkipCoarseCalib are both 1 + uint16_t tdcPrecal; //!< TDC pre-calibration value to use when bOverrideCalib and bSkipCoarseCalib are both 1 +}; + +//! @} + +//! \addtogroup CMD_FS_OFF +//! @{ +#define CMD_FS_OFF 0x0804 +struct __RFC_STRUCT rfc_CMD_FS_OFF_s { + uint16_t commandNo; //!< The command ID number 0x0804 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; +}; + +//! @} + +//! \addtogroup CMD_RX +//! @{ +#define CMD_RX 0x0805 +struct __RFC_STRUCT rfc_CMD_RX_s { + uint16_t commandNo; //!< The command ID number 0x0805 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint16_t endianness:1; //!< \brief 0: Least significant bit first
    + //!< 1: Most significant bit first + uint16_t numHdrBits:6; //!< Number of bits in the header + uint16_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
    + //!< 1: Turn frequency synth off after command + uint16_t bUseCrc:1; //!< \brief 0: No CRC
    + //!< 1: The last bytes of the packet are a CRC + uint16_t bCrcIncSw:1; //!< \brief 0: Do not include sync word in CRC calculation
    + //!< 1: Include sync word in CRC calculation + uint16_t bCrcIncHdr:1; //!< \brief 0: Do not include header in CRC calculation
    + //!< 1: Include header in CRC calculation + uint16_t bReportCrc:1; //!< \brief 0: Do not write CRC to receive buffer
    + //!< 1: Write received CRC to receive buffer + uint16_t endType:1; //!< \brief 0: Packet is received to the end if end trigger happens after sync is obtained
    + //!< 1: Packet reception is stopped if end trigger happens + uint16_t bDualSw:1; //!< \brief 0: Single sync word
    + //!< 1: Dual sync word. + } pktConfig; + uint32_t syncWord; //!< Sync word to receive + uint32_t syncWord2; //!< Secondary sync word to receive if pktConfig.bDualSw = 1 + struct { + uint16_t numLenBits:4; //!< Number of bits in the length field + uint16_t lenFieldPos:5; //!< Bit position of the first bit in the length field + uint16_t lenOffset:7; //!< Signed number to add to the received length field + } lenConfig; + uint16_t maxLen; //!< Maximum number of bytes in the received packet (including header, excluding CRC) + uint8_t* pRecPkt; //!< Pointer to buffer for received packet. NULL: Do not store the contents. + ratmr_t endTime; //!< Time to end the operation + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger classifier for ending the operation + int8_t rssi; //!< RSSI of received packet + uint16_t recLen; //!< Number of bytes written to receive buffer + ratmr_t timeStamp; //!< Time stamp of received packet + uint16_t nRxOk; //!< Counter of number of received packets with CRC OK and first sync word + uint16_t nRxNok; //!< Counter of number of received packets with CRC error and first sync word + uint16_t nRx2Ok; //!< \brief Counter of number of received packets with CRC OK and second sync word; may safely be + //!< omitted if pktConfig.bDualSw is 0 + uint16_t nRx2Nok; //!< \brief Counter of number of received packets with CRC error and second sync word; may safely be + //!< omitted if pktConfig.bDualSw is 0 +}; + +//! @} + +//! \addtogroup CMD_TX +//! @{ +#define CMD_TX 0x0806 +struct __RFC_STRUCT rfc_CMD_TX_s { + uint16_t commandNo; //!< The command ID number 0x0806 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint16_t endianness:1; //!< \brief 0: Least significant bit first
    + //!< 1: Most significant bit first + uint16_t numHdrBits:6; //!< Number of bits in the header + uint16_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
    + //!< 1: Turn frequency synth off after command + uint16_t bUseCrc:1; //!< \brief 0: No CRC
    + //!< 1: Append a CRC to the packet + uint16_t bCrcIncSw:1; //!< \brief 0: Do not include sync word in CRC calculation
    + //!< 1: Include sync word in CRC calculation + uint16_t bCrcIncHdr:1; //!< \brief 0: Do not include header in CRC calculation
    + //!< 1: Include header in CRC calculation + } pktConfig; + uint32_t syncWord; //!< Sync word to transmit + uint8_t* pTxPkt; //!< Pointer to buffer for transmitted packet. + uint16_t pktLen; //!< Number of bytes in the transmitted packet +}; + +//! @} + +//! \addtogroup CMD_RX_TEST +//! @{ +#define CMD_RX_TEST 0x0807 +struct __RFC_STRUCT rfc_CMD_RX_TEST_s { + uint16_t commandNo; //!< The command ID number 0x0807 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint8_t bEnaFifo:1; //!< \brief 0: Do not enable FIFO in modem, so that received data is not available
    + //!< 1: Enable FIFO in modem – the data must be read out by the application + uint8_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
    + //!< 1: Turn frequency synth off after command + uint8_t bNoSync:1; //!< \brief 0: Run sync search as normal for the configured mode
    + //!< 1: Write correlation thresholds to the maximum value to avoid getting sync + } config; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger classifier for ending the operation + uint32_t syncWord; //!< Sync word to use for receiver + ratmr_t endTime; //!< Time to end the operation +}; + +//! @} + +//! \addtogroup CMD_TX_TEST +//! @{ +#define CMD_TX_TEST 0x0808 +struct __RFC_STRUCT rfc_CMD_TX_TEST_s { + uint16_t commandNo; //!< The command ID number 0x0808 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint8_t bUseCw:1; //!< \brief 0: Send modulated signal
    + //!< 1: Send continuous wave + uint8_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
    + //!< 1: Turn frequency synth off after command + uint8_t whitenMode:2; //!< \brief 0: No whitening
    + //!< 1: Default whitening
    + //!< 2: PRBS-15
    + //!< 3: PRBS-32 + } config; + uint8_t __dummy0; + uint16_t txWord; //!< Value to send to the modem before whitening + uint8_t __dummy1; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger classifier for ending the operation + uint32_t syncWord; //!< Sync word to use for transmitter + ratmr_t endTime; //!< Time to end the operation +}; + +//! @} + +//! \addtogroup CMD_SYNC_STOP_RAT +//! @{ +#define CMD_SYNC_STOP_RAT 0x0809 +struct __RFC_STRUCT rfc_CMD_SYNC_STOP_RAT_s { + uint16_t commandNo; //!< The command ID number 0x0809 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint16_t __dummy0; + ratmr_t rat0; //!< \brief The returned RAT timer value corresponding to the value the RAT would have had when the + //!< RTC was zero +}; + +//! @} + +//! \addtogroup CMD_SYNC_START_RAT +//! @{ +#define CMD_SYNC_START_RAT 0x080A +struct __RFC_STRUCT rfc_CMD_SYNC_START_RAT_s { + uint16_t commandNo; //!< The command ID number 0x080A + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint16_t __dummy0; + ratmr_t rat0; //!< \brief The desired RAT timer value corresponding to the value the RAT would have had when the + //!< RTC was zero. This parameter is returned by CMD_SYNC_STOP_RAT +}; + +//! @} + +//! \addtogroup CMD_COUNT +//! @{ +#define CMD_COUNT 0x080B +struct __RFC_STRUCT rfc_CMD_COUNT_s { + uint16_t commandNo; //!< The command ID number 0x080B + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint16_t counter; //!< \brief Counter. On start, the radio CPU decrements the value, and the end status of the operation + //!< differs if the result is zero +}; + +//! @} + +//! \addtogroup CMD_FS_POWERUP +//! @{ +#define CMD_FS_POWERUP 0x080C +struct __RFC_STRUCT rfc_CMD_FS_POWERUP_s { + uint16_t commandNo; //!< The command ID number 0x080C + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint16_t __dummy0; + uint32_t* pRegOverride; //!< Pointer to a list of hardware and configuration registers to override. If NULL, no override is used. +}; + +//! @} + +//! \addtogroup CMD_FS_POWERDOWN +//! @{ +#define CMD_FS_POWERDOWN 0x080D +struct __RFC_STRUCT rfc_CMD_FS_POWERDOWN_s { + uint16_t commandNo; //!< The command ID number 0x080D + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; +}; + +//! @} + +//! \addtogroup CMD_SCH_IMM +//! @{ +#define CMD_SCH_IMM 0x0810 +struct __RFC_STRUCT rfc_CMD_SCH_IMM_s { + uint16_t commandNo; //!< The command ID number 0x0810 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint16_t __dummy0; + uint32_t cmdrVal; //!< Value as would be written to CMDR + uint32_t cmdstaVal; //!< Value as would be returned in CMDSTA +}; + +//! @} + +//! \addtogroup CMD_COUNT_BRANCH +//! @{ +#define CMD_COUNT_BRANCH 0x0812 +struct __RFC_STRUCT rfc_CMD_COUNT_BRANCH_s { + uint16_t commandNo; //!< The command ID number 0x0812 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint16_t counter; //!< \brief Counter. On start, the radio CPU decrements the value, and the end status of the operation + //!< differs if the result is zero + rfc_radioOp_t *pNextOpIfOk; //!< Pointer to next operation if counter did not expire +}; + +//! @} + +//! \addtogroup CMD_PATTERN_CHECK +//! @{ +#define CMD_PATTERN_CHECK 0x0813 +struct __RFC_STRUCT rfc_CMD_PATTERN_CHECK_s { + uint16_t commandNo; //!< The command ID number 0x0813 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint16_t operation:2; //!< \brief Operation to perform
    + //!< 0: True if value == compareVal
    + //!< 1: True if value < compareVal
    + //!< 2: True if value > compareVal
    + //!< 3: Reserved + uint16_t bByteRev:1; //!< \brief If 1, interchange the four bytes of the value, so that they are read + //!< most-significant-byte-first. + uint16_t bBitRev:1; //!< If 1, perform bit reversal of the value + uint16_t signExtend:5; //!< \brief 0: Treat value and compareVal as unsigned
    + //!< 1–31: Treat value and compareVal as signed, where the value + //!< gives the number of the most significant bit in the signed number. + uint16_t bRxVal:1; //!< \brief 0: Use pValue as a pointer
    + //!< 1: Use pValue as a signed offset to the start of the last + //!< committed Rx entry element + } patternOpt; //!< Options for comparison + rfc_radioOp_t *pNextOpIfOk; //!< Pointer to next operation if comparison result was true + uint8_t* pValue; //!< Pointer to read from, or offset from last Rx entry if patternOpt.bRxVal == 1 + uint32_t mask; //!< Bit mask to apply before comparison + uint32_t compareVal; //!< Value to compare to +}; + +//! @} + +//! \addtogroup CMD_TX_POWER_BOOST +//! @{ +#define CMD_TX_POWER_BOOST 0x0816 +struct __RFC_STRUCT rfc_CMD_TX_POWER_BOOST_s { + uint16_t commandNo; //!< The command ID number 0x0816 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t vddrLevel; //!< \brief VDDR level to set
    + //!< 0xFD: Trim VDDR voltage to normal level (VDDR_TRIM), nominally 1.68 V
    + //!< 0xFE: Trim VDDR voltage to high level (VDDR_TRIM_H), nominally 1.85 V
    + //!< 0xFF: Trim VDDR voltage to higher level (VDDR_TRIM_HH), nominally 1.95 V
    + //!< Other: reserved + uint8_t paTrimValue; //!< \brief Optional power amplifier trim setting manipulation
    + //!< 0x00-0x1F: Value to write in ADI_0_RF:PACTL0.TRIM register field
    + //!< 0xFE: Set PACTL0.TRIM to its default value from FCFG1
    + //!< 0xFF: Do not write PACTL0.TRIM, use the setting that is already applied
    +}; + +//! @} + +//! \addtogroup CMD_ABORT +//! @{ +#define CMD_ABORT 0x0401 +struct __RFC_STRUCT rfc_CMD_ABORT_s { + uint16_t commandNo; //!< The command ID number 0x0401 +}; + +//! @} + +//! \addtogroup CMD_STOP +//! @{ +#define CMD_STOP 0x0402 +struct __RFC_STRUCT rfc_CMD_STOP_s { + uint16_t commandNo; //!< The command ID number 0x0402 +}; + +//! @} + +//! \addtogroup CMD_GET_RSSI +//! @{ +#define CMD_GET_RSSI 0x0403 +struct __RFC_STRUCT rfc_CMD_GET_RSSI_s { + uint16_t commandNo; //!< The command ID number 0x0403 +}; + +//! @} + +//! \addtogroup CMD_UPDATE_RADIO_SETUP +//! @{ +#define CMD_UPDATE_RADIO_SETUP 0x0001 +struct __RFC_STRUCT rfc_CMD_UPDATE_RADIO_SETUP_s { + uint16_t commandNo; //!< The command ID number 0x0001 + uint16_t __dummy0; + uint32_t* pRegOverride; //!< Pointer to a list of hardware and configuration registers to override +}; + +//! @} + +//! \addtogroup CMD_TRIGGER +//! @{ +#define CMD_TRIGGER 0x0404 +struct __RFC_STRUCT rfc_CMD_TRIGGER_s { + uint16_t commandNo; //!< The command ID number 0x0404 + uint8_t triggerNo; //!< Command trigger number +}; + +//! @} + +//! \addtogroup CMD_GET_FW_INFO +//! @{ +#define CMD_GET_FW_INFO 0x0002 +struct __RFC_STRUCT rfc_CMD_GET_FW_INFO_s { + uint16_t commandNo; //!< The command ID number 0x0002 + uint16_t versionNo; //!< Firmware version number + uint16_t startOffset; //!< The start of free RAM + uint16_t freeRamSz; //!< The size of free RAM + uint16_t availRatCh; //!< Bitmap of available RAT channels +}; + +//! @} + +//! \addtogroup CMD_START_RAT +//! @{ +#define CMD_START_RAT 0x0405 +struct __RFC_STRUCT rfc_CMD_START_RAT_s { + uint16_t commandNo; //!< The command ID number 0x0405 +}; + +//! @} + +//! \addtogroup CMD_PING +//! @{ +#define CMD_PING 0x0406 +struct __RFC_STRUCT rfc_CMD_PING_s { + uint16_t commandNo; //!< The command ID number 0x0406 +}; + +//! @} + +//! \addtogroup CMD_ADD_DATA_ENTRY +//! @{ +#define CMD_ADD_DATA_ENTRY 0x0005 +struct __RFC_STRUCT rfc_CMD_ADD_DATA_ENTRY_s { + uint16_t commandNo; //!< The command ID number 0x0005 + uint16_t __dummy0; + dataQueue_t* pQueue; //!< Pointer to the queue structure to which the entry will be added + uint8_t* pEntry; //!< Pointer to the entry +}; + +//! @} + +//! \addtogroup CMD_REMOVE_DATA_ENTRY +//! @{ +#define CMD_REMOVE_DATA_ENTRY 0x0006 +struct __RFC_STRUCT rfc_CMD_REMOVE_DATA_ENTRY_s { + uint16_t commandNo; //!< The command ID number 0x0006 + uint16_t __dummy0; + dataQueue_t* pQueue; //!< Pointer to the queue structure from which the entry will be removed + uint8_t* pEntry; //!< Pointer to the entry that was removed +}; + +//! @} + +//! \addtogroup CMD_FLUSH_QUEUE +//! @{ +#define CMD_FLUSH_QUEUE 0x0007 +struct __RFC_STRUCT rfc_CMD_FLUSH_QUEUE_s { + uint16_t commandNo; //!< The command ID number 0x0007 + uint16_t __dummy0; + dataQueue_t* pQueue; //!< Pointer to the queue structure to be flushed + uint8_t* pFirstEntry; //!< Pointer to the first entry that was removed +}; + +//! @} + +//! \addtogroup CMD_CLEAR_RX +//! @{ +#define CMD_CLEAR_RX 0x0008 +struct __RFC_STRUCT rfc_CMD_CLEAR_RX_s { + uint16_t commandNo; //!< The command ID number 0x0008 + uint16_t __dummy0; + dataQueue_t* pQueue; //!< Pointer to the queue structure to be cleared +}; + +//! @} + +//! \addtogroup CMD_REMOVE_PENDING_ENTRIES +//! @{ +#define CMD_REMOVE_PENDING_ENTRIES 0x0009 +struct __RFC_STRUCT rfc_CMD_REMOVE_PENDING_ENTRIES_s { + uint16_t commandNo; //!< The command ID number 0x0009 + uint16_t __dummy0; + dataQueue_t* pQueue; //!< Pointer to the queue structure to be flushed + uint8_t* pFirstEntry; //!< Pointer to the first entry that was removed +}; + +//! @} + +//! \addtogroup CMD_SET_RAT_CMP +//! @{ +#define CMD_SET_RAT_CMP 0x000A +struct __RFC_STRUCT rfc_CMD_SET_RAT_CMP_s { + uint16_t commandNo; //!< The command ID number 0x000A + uint8_t ratCh; //!< The radio timer channel number + uint8_t __dummy0; + ratmr_t compareTime; //!< The time at which the compare occurs +}; + +//! @} + +//! \addtogroup CMD_SET_RAT_CPT +//! @{ +#define CMD_SET_RAT_CPT 0x0603 +struct __RFC_STRUCT rfc_CMD_SET_RAT_CPT_s { + uint16_t commandNo; //!< The command ID number 0x0603 + struct { + uint16_t :3; + uint16_t inputSrc:5; //!< Input source indicator + uint16_t ratCh:4; //!< The radio timer channel number + uint16_t bRepeated:1; //!< \brief 0: Single capture mode
    + //!< 1: Repeated capture mode + uint16_t inputMode:2; //!< \brief Input mode:
    + //!< 0: Capture on rising edge
    + //!< 1: Capture on falling edge
    + //!< 2: Capture on both edges
    + //!< 3: Reserved + } config; +}; + +//! @} + +//! \addtogroup CMD_DISABLE_RAT_CH +//! @{ +#define CMD_DISABLE_RAT_CH 0x0408 +struct __RFC_STRUCT rfc_CMD_DISABLE_RAT_CH_s { + uint16_t commandNo; //!< The command ID number 0x0408 + uint8_t ratCh; //!< The radio timer channel number +}; + +//! @} + +//! \addtogroup CMD_SET_RAT_OUTPUT +//! @{ +#define CMD_SET_RAT_OUTPUT 0x0604 +struct __RFC_STRUCT rfc_CMD_SET_RAT_OUTPUT_s { + uint16_t commandNo; //!< The command ID number 0x0604 + struct { + uint16_t :2; + uint16_t outputSel:3; //!< Output event indicator + uint16_t outputMode:3; //!< \brief 0: Set output line low as default; and pulse on event. Duration of pulse is one RF Core clock period (ca. 41.67 ns).
    + //!< 1: Set output line high on event
    + //!< 2: Set output line low on event
    + //!< 3: Toggle (invert) output line state on event
    + //!< 4: Immediately set output line to low (does not change upon event)
    + //!< 5: Immediately set output line to high (does not change upon event)
    + //!< Others: Reserved + uint16_t ratCh:4; //!< The radio timer channel number + } config; +}; + +//! @} + +//! \addtogroup CMD_ARM_RAT_CH +//! @{ +#define CMD_ARM_RAT_CH 0x0409 +struct __RFC_STRUCT rfc_CMD_ARM_RAT_CH_s { + uint16_t commandNo; //!< The command ID number 0x0409 + uint8_t ratCh; //!< The radio timer channel number +}; + +//! @} + +//! \addtogroup CMD_DISARM_RAT_CH +//! @{ +#define CMD_DISARM_RAT_CH 0x040A +struct __RFC_STRUCT rfc_CMD_DISARM_RAT_CH_s { + uint16_t commandNo; //!< The command ID number 0x040A + uint8_t ratCh; //!< The radio timer channel number +}; + +//! @} + +//! \addtogroup CMD_SET_TX_POWER +//! @{ +#define CMD_SET_TX_POWER 0x0010 +struct __RFC_STRUCT rfc_CMD_SET_TX_POWER_s { + uint16_t commandNo; //!< The command ID number 0x0010 + struct { + uint16_t IB:6; //!< Value to write to the PA power control field at 25 °C + uint16_t GC:2; //!< Value to write to the gain control of the 1st stage of the PA + uint16_t boost:1; //!< Value of boost bit in synth + uint16_t tempCoeff:7; //!< Temperature coefficient for IB. 0: No temperature compensation + } txPower; //!< New Tx power setting +}; + +//! @} + +//! \addtogroup CMD_UPDATE_FS +//! @{ +#define CMD_UPDATE_FS 0x0011 +struct __RFC_STRUCT rfc_CMD_UPDATE_FS_s { + uint16_t commandNo; //!< The command ID number 0x0011 + uint16_t frequency; //!< The frequency in MHz to tune to + uint16_t fractFreq; //!< Fractional part of the frequency to tune to +}; + +//! @} + +//! \addtogroup CMD_BUS_REQUEST +//! @{ +#define CMD_BUS_REQUEST 0x040E +struct __RFC_STRUCT rfc_CMD_BUS_REQUEST_s { + uint16_t commandNo; //!< The command ID number 0x040E + uint8_t bSysBusNeeded; //!< \brief 0: System bus may sleep
    + //!< 1: System bus access needed +}; + +//! @} + +//! @} +//! @} +#endif /* COMMON_CMD_H_ */ diff --git a/cpu/cc26xx-cc13xx/rf-core/api/data_entry.h b/cpu/cc26xx-cc13xx/rf-core/api/data_entry.h new file mode 100644 index 000000000..c396a211f --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/api/data_entry.h @@ -0,0 +1,213 @@ +/****************************************************************************** +* Filename: data_entry.h +* Revised: 2015-08-04 11:44:20 +0200 (Tue, 04 Aug 2015) +* Revision: 44329 +* +* Description: Definition of API for data exchange +* +* Copyright (c) 2015, Texas Instruments Incorporated +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1) Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2) 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. +* +* 3) Neither the name of the ORGANIZATION 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. +* +******************************************************************************/ + +#ifndef DATA_ENTRY_H_ +#define DATA_ENTRY_H_ + +#ifndef __RFC_STRUCT +#ifdef __GNUC__ +#define __RFC_STRUCT __attribute__ ((aligned (4))) +#else +#define __RFC_STRUCT +#endif +#endif + +//! \addtogroup rfc +//! @{ + +//! \addtogroup data_entry +//! @{ + +#include +#include "mailbox.h" + +typedef struct __RFC_STRUCT rfc_dataEntry_s rfc_dataEntry_t; +typedef struct __RFC_STRUCT rfc_dataEntryGeneral_s rfc_dataEntryGeneral_t; +typedef struct __RFC_STRUCT rfc_dataEntryMulti_s rfc_dataEntryMulti_t; +typedef struct __RFC_STRUCT rfc_dataEntryPointer_s rfc_dataEntryPointer_t; +typedef struct __RFC_STRUCT rfc_dataEntryPartial_s rfc_dataEntryPartial_t; + +//! \addtogroup dataEntry +//! @{ +struct __RFC_STRUCT rfc_dataEntry_s { + uint8_t* pNextEntry; //!< Pointer to next entry in the queue, NULL if this is the last entry + uint8_t status; //!< Indicates status of entry, including whether it is free for the system CPU to write to + struct { + uint8_t type:2; //!< \brief Type of data entry structure
    + //!< 0: General data entry
    + //!< 1: Multi-element Rx entry
    + //!< 2: Pointer entry
    + //!< 3: Partial read Rx entry + uint8_t lenSz:2; //!< \brief Size of length word in start of each Rx entry element
    + //!< 0: No length indicator
    + //!< 1: One byte length indicator
    + //!< 2: Two bytes length indicator
    + //!< 3: Reserved + uint8_t irqIntv:4; //!< \brief For partial read Rx entry only: The number of bytes between interrupt generated + //!< by the radio CPU (0: 16 bytes) + } config; + uint16_t length; //!< \brief For pointer entries: Number of bytes in the data buffer pointed to
    + //!< For other entries: Number of bytes following this length field +}; + +//! @} + +//! \addtogroup dataEntryGeneral +//! @{ +//! General data entry structure (type = 0) + +struct __RFC_STRUCT rfc_dataEntryGeneral_s { + uint8_t* pNextEntry; //!< Pointer to next entry in the queue, NULL if this is the last entry + uint8_t status; //!< Indicates status of entry, including whether it is free for the system CPU to write to + struct { + uint8_t type:2; //!< \brief Type of data entry structure
    + //!< 0: General data entry
    + //!< 1: Multi-element Rx entry
    + //!< 2: Pointer entry
    + //!< 3: Partial read Rx entry + uint8_t lenSz:2; //!< \brief Size of length word in start of each Rx entry element
    + //!< 0: No length indicator
    + //!< 1: One byte length indicator
    + //!< 2: Two bytes length indicator
    + //!< 3: Reserved + uint8_t irqIntv:4; //!< \brief For partial read Rx entry only: The number of bytes between interrupt generated + //!< by the radio CPU (0: 16 bytes) + } config; + uint16_t length; //!< \brief For pointer entries: Number of bytes in the data buffer pointed to
    + //!< For other entries: Number of bytes following this length field + uint8_t data; //!< First byte of the data array to be received or transmitted +}; + +//! @} + +//! \addtogroup dataEntryMulti +//! @{ +//! Multi-element data entry structure (type = 1) + +struct __RFC_STRUCT rfc_dataEntryMulti_s { + uint8_t* pNextEntry; //!< Pointer to next entry in the queue, NULL if this is the last entry + uint8_t status; //!< Indicates status of entry, including whether it is free for the system CPU to write to + struct { + uint8_t type:2; //!< \brief Type of data entry structure
    + //!< 0: General data entry
    + //!< 1: Multi-element Rx entry
    + //!< 2: Pointer entry
    + //!< 3: Partial read Rx entry + uint8_t lenSz:2; //!< \brief Size of length word in start of each Rx entry element
    + //!< 0: No length indicator
    + //!< 1: One byte length indicator
    + //!< 2: Two bytes length indicator
    + //!< 3: Reserved + uint8_t irqIntv:4; //!< \brief For partial read Rx entry only: The number of bytes between interrupt generated + //!< by the radio CPU (0: 16 bytes) + } config; + uint16_t length; //!< \brief For pointer entries: Number of bytes in the data buffer pointed to
    + //!< For other entries: Number of bytes following this length field + uint16_t numElements; //!< Number of entry elements committed in the entry + uint16_t nextIndex; //!< Index to the byte after the last byte of the last entry element committed by the radio CPU + uint8_t rxData; //!< First byte of the data array of received data entry elements +}; + +//! @} + +//! \addtogroup dataEntryPointer +//! @{ +//! Pointer data entry structure (type = 2) + +struct __RFC_STRUCT rfc_dataEntryPointer_s { + uint8_t* pNextEntry; //!< Pointer to next entry in the queue, NULL if this is the last entry + uint8_t status; //!< Indicates status of entry, including whether it is free for the system CPU to write to + struct { + uint8_t type:2; //!< \brief Type of data entry structure
    + //!< 0: General data entry
    + //!< 1: Multi-element Rx entry
    + //!< 2: Pointer entry
    + //!< 3: Partial read Rx entry + uint8_t lenSz:2; //!< \brief Size of length word in start of each Rx entry element
    + //!< 0: No length indicator
    + //!< 1: One byte length indicator
    + //!< 2: Two bytes length indicator
    + //!< 3: Reserved + uint8_t irqIntv:4; //!< \brief For partial read Rx entry only: The number of bytes between interrupt generated + //!< by the radio CPU (0: 16 bytes) + } config; + uint16_t length; //!< \brief For pointer entries: Number of bytes in the data buffer pointed to
    + //!< For other entries: Number of bytes following this length field + uint8_t* pData; //!< Pointer to data buffer of data to be received ro transmitted +}; + +//! @} + +//! \addtogroup dataEntryPartial +//! @{ +//! Partial read data entry structure (type = 3) + +struct __RFC_STRUCT rfc_dataEntryPartial_s { + uint8_t* pNextEntry; //!< Pointer to next entry in the queue, NULL if this is the last entry + uint8_t status; //!< Indicates status of entry, including whether it is free for the system CPU to write to + struct { + uint8_t type:2; //!< \brief Type of data entry structure
    + //!< 0: General data entry
    + //!< 1: Multi-element Rx entry
    + //!< 2: Pointer entry
    + //!< 3: Partial read Rx entry + uint8_t lenSz:2; //!< \brief Size of length word in start of each Rx entry element
    + //!< 0: No length indicator
    + //!< 1: One byte length indicator
    + //!< 2: Two bytes length indicator
    + //!< 3: Reserved + uint8_t irqIntv:4; //!< \brief For partial read Rx entry only: The number of bytes between interrupt generated + //!< by the radio CPU (0: 16 bytes) + } config; + uint16_t length; //!< \brief For pointer entries: Number of bytes in the data buffer pointed to
    + //!< For other entries: Number of bytes following this length field + struct { + uint16_t numElements:13; //!< Number of entry elements committed in the entry + uint16_t bEntryOpen:1; //!< 1 if the entry contains an element that is still open for appending data + uint16_t bFirstCont:1; //!< 1 if the first element is a continuation of the last packet from the previous entry + uint16_t bLastCont:1; //!< 1 if the packet in the last element continues in the next entry + } pktStatus; + uint16_t nextIndex; //!< Index to the byte after the last byte of the last entry element committed by the radio CPU + uint8_t rxData; //!< First byte of the data array of received data entry elements +}; + +//! @} + +//! @} +//! @} +#endif /* DATA_ENTRY_H_ */ diff --git a/cpu/cc26xx-cc13xx/rf-core/api/ieee_cmd.h b/cpu/cc26xx-cc13xx/rf-core/api/ieee_cmd.h new file mode 100644 index 000000000..62f9abd32 --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/api/ieee_cmd.h @@ -0,0 +1,611 @@ +/****************************************************************************** +* Filename: ieee_cmd.h +* Revised: $ $ +* Revision: $ $ +* +* Description: CC26xx/CC13xx API for IEEE 802.15.4 commands +* +* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* 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 Texas Instruments Incorporated 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 +* OWNER 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. +* +******************************************************************************/ + +#ifndef IEEE_CMD_H_ +#define IEEE_CMD_H_ + +#ifndef __RFC_STRUCT +#ifdef __GNUC__ +#define __RFC_STRUCT __attribute__ ((aligned (4))) +#else +#define __RFC_STRUCT +#endif +#endif + +//! \addtogroup rfc +//! @{ + +//! \addtogroup ieee_cmd +//! @{ + +#include +#include "mailbox.h" +#include "common_cmd.h" + +typedef struct __RFC_STRUCT rfc_CMD_IEEE_RX_s rfc_CMD_IEEE_RX_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_ED_SCAN_s rfc_CMD_IEEE_ED_SCAN_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_TX_s rfc_CMD_IEEE_TX_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_CSMA_s rfc_CMD_IEEE_CSMA_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_RX_ACK_s rfc_CMD_IEEE_RX_ACK_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_ABORT_BG_s rfc_CMD_IEEE_ABORT_BG_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_MOD_CCA_s rfc_CMD_IEEE_MOD_CCA_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_MOD_FILT_s rfc_CMD_IEEE_MOD_FILT_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_MOD_SRC_MATCH_s rfc_CMD_IEEE_MOD_SRC_MATCH_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_ABORT_FG_s rfc_CMD_IEEE_ABORT_FG_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_STOP_FG_s rfc_CMD_IEEE_STOP_FG_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_CCA_REQ_s rfc_CMD_IEEE_CCA_REQ_t; +typedef struct __RFC_STRUCT rfc_ieeeRxOutput_s rfc_ieeeRxOutput_t; +typedef struct __RFC_STRUCT rfc_shortAddrEntry_s rfc_shortAddrEntry_t; +typedef struct __RFC_STRUCT rfc_ieeeRxCorrCrc_s rfc_ieeeRxCorrCrc_t; + +//! \addtogroup CMD_IEEE_RX +//! @{ +#define CMD_IEEE_RX 0x2801 +struct __RFC_STRUCT rfc_CMD_IEEE_RX_s { + uint16_t commandNo; //!< The command ID number 0x2801 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to tune to in the start of the operation
    + //!< 0: Use existing channel
    + //!< 11–26: Use as IEEE 802.15.4 channel, i.e. frequency is (2405 + 5 × (channel - 11)) MHz
    + //!< 60–207: Frequency is (2300 + channel) MHz
    + //!< Others: Reserved + struct { + uint8_t bAutoFlushCrc:1; //!< If 1, automatically remove packets with CRC error from Rx queue + uint8_t bAutoFlushIgn:1; //!< If 1, automatically remove packets that can be ignored according to frame filtering from Rx queue + uint8_t bIncludePhyHdr:1; //!< If 1, include the received PHY header field in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendCorrCrc:1; //!< If 1, append a correlation value and CRC result byte to the packet in the Rx queue + uint8_t bAppendSrcInd:1; //!< If 1, append an index from the source matching algorithm + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + } rxConfig; + dataQueue_t* pRxQ; //!< Pointer to receive queue + rfc_ieeeRxOutput_t *pOutput; //!< Pointer to output structure (NULL: Do not store results) + struct { + uint16_t frameFiltEn:1; //!< \brief 0: Disable frame filtering
    + //!< 1: Enable frame filtering + uint16_t frameFiltStop:1; //!< \brief 0: Receive all packets to the end
    + //!< 1: Stop receiving frame once frame filtering has caused the frame to be rejected. + uint16_t autoAckEn:1; //!< \brief 0: Disable auto ACK
    + //!< 1: Enable auto ACK. + uint16_t slottedAckEn:1; //!< \brief 0: Non-slotted ACK
    + //!< 1: Slotted ACK. + uint16_t autoPendEn:1; //!< \brief 0: Auto-pend disabled
    + //!< 1: Auto-pend enabled + uint16_t defaultPend:1; //!< The value of the pending data bit in auto ACK packets that are not subject to auto-pend + uint16_t bPendDataReqOnly:1; //!< \brief 0: Use auto-pend for any packet
    + //!< 1: Use auto-pend for data request packets only + uint16_t bPanCoord:1; //!< \brief 0: Device is not PAN coordinator
    + //!< 1: Device is PAN coordinator + uint16_t maxFrameVersion:2; //!< Reject frames where the frame version field in the FCF is greater than this value + uint16_t fcfReservedMask:3; //!< Value to be AND-ed with the reserved part of the FCF; frame rejected if result is non-zero + uint16_t modifyFtFilter:2; //!< \brief Treatment of MSB of frame type field before frame-type filtering:
    + //!< 0: No modification
    + //!< 1: Invert MSB
    + //!< 2: Set MSB to 0
    + //!< 3: Set MSB to 1 + uint16_t bStrictLenFilter:1; //!< \brief 0: Accept acknowledgement frames of any length >= 5
    + //!< 1: Accept only acknowledgement frames of length 5 + } frameFiltOpt; //!< Frame filtering options + struct { + uint8_t bAcceptFt0Beacon:1; //!< \brief Treatment of frames with frame type 000 (beacon):
    + //!< 0: Reject
    + //!< 1: Accept + uint8_t bAcceptFt1Data:1; //!< \brief Treatment of frames with frame type 001 (data):
    + //!< 0: Reject
    + //!< 1: Accept + uint8_t bAcceptFt2Ack:1; //!< \brief Treatment of frames with frame type 010 (ACK):
    + //!< 0: Reject, unless running ACK receive command
    + //!< 1: Always accept + uint8_t bAcceptFt3MacCmd:1; //!< \brief Treatment of frames with frame type 011 (MAC command):
    + //!< 0: Reject
    + //!< 1: Accept + uint8_t bAcceptFt4Reserved:1; //!< \brief Treatment of frames with frame type 100 (reserved):
    + //!< 0: Reject
    + //!< 1: Accept + uint8_t bAcceptFt5Reserved:1; //!< \brief Treatment of frames with frame type 101 (reserved):
    + //!< 0: Reject
    + //!< 1: Accept + uint8_t bAcceptFt6Reserved:1; //!< \brief Treatment of frames with frame type 110 (reserved):
    + //!< 0: Reject
    + //!< 1: Accept + uint8_t bAcceptFt7Reserved:1; //!< \brief Treatment of frames with frame type 111 (reserved):
    + //!< 0: Reject
    + //!< 1: Accept + } frameTypes; //!< Frame types to receive in frame filtering + struct { + uint8_t ccaEnEnergy:1; //!< Enable energy scan as CCA source + uint8_t ccaEnCorr:1; //!< Enable correlator based carrier sense as CCA source + uint8_t ccaEnSync:1; //!< Enable sync found based carrier sense as CCA source + uint8_t ccaCorrOp:1; //!< \brief Operator to use between energy based and correlator based CCA
    + //!< 0: Report busy channel if either ccaEnergy or ccaCorr are busy
    + //!< 1: Report busy channel if both ccaEnergy and ccaCorr are busy + uint8_t ccaSyncOp:1; //!< \brief Operator to use between sync found based CCA and the others
    + //!< 0: Always report busy channel if ccaSync is busy
    + //!< 1: Always report idle channel if ccaSync is idle + uint8_t ccaCorrThr:2; //!< Threshold for number of correlation peaks in correlator based carrier sense + } ccaOpt; //!< CCA options + int8_t ccaRssiThr; //!< RSSI threshold for CCA + uint8_t __dummy0; + uint8_t numExtEntries; //!< Number of extended address entries + uint8_t numShortEntries; //!< Number of short address entries + uint32_t* pExtEntryList; //!< Pointer to list of extended address entries + rfc_shortAddrEntry_t *pShortEntryList;//!< Pointer to list of short address entries + uint64_t localExtAddr; //!< The extended address of the local device + uint16_t localShortAddr; //!< The short address of the local device + uint16_t localPanID; //!< The PAN ID of the local device + uint16_t __dummy1; + uint8_t __dummy2; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to end the Rx operation + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the Rx + //!< operation +}; + +//! @} + +//! \addtogroup CMD_IEEE_ED_SCAN +//! @{ +#define CMD_IEEE_ED_SCAN 0x2802 +struct __RFC_STRUCT rfc_CMD_IEEE_ED_SCAN_s { + uint16_t commandNo; //!< The command ID number 0x2802 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to tune to in the start of the operation
    + //!< 0: Use existing channel
    + //!< 11–26: Use as IEEE 802.15.4 channel, i.e. frequency is (2405 + 5 × (channel - 11)) MHz
    + //!< 60–207: Frequency is (2300 + channel) MHz
    + //!< Others: Reserved + struct { + uint8_t ccaEnEnergy:1; //!< Enable energy scan as CCA source + uint8_t ccaEnCorr:1; //!< Enable correlator based carrier sense as CCA source + uint8_t ccaEnSync:1; //!< Enable sync found based carrier sense as CCA source + uint8_t ccaCorrOp:1; //!< \brief Operator to use between energy based and correlator based CCA
    + //!< 0: Report busy channel if either ccaEnergy or ccaCorr are busy
    + //!< 1: Report busy channel if both ccaEnergy and ccaCorr are busy + uint8_t ccaSyncOp:1; //!< \brief Operator to use between sync found based CCA and the others
    + //!< 0: Always report busy channel if ccaSync is busy
    + //!< 1: Always report idle channel if ccaSync is idle + uint8_t ccaCorrThr:2; //!< Threshold for number of correlation peaks in correlator based carrier sense + } ccaOpt; //!< CCA options + int8_t ccaRssiThr; //!< RSSI threshold for CCA + uint8_t __dummy0; + int8_t maxRssi; //!< The maximum RSSI recorded during the ED scan + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to end the Rx operation + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the Rx + //!< operation +}; + +//! @} + +//! \addtogroup CMD_IEEE_TX +//! @{ +#define CMD_IEEE_TX 0x2C01 +struct __RFC_STRUCT rfc_CMD_IEEE_TX_s { + uint16_t commandNo; //!< The command ID number 0x2C01 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint8_t bIncludePhyHdr:1; //!< \brief 0: Find PHY header automatically
    + //!< 1: Insert PHY header from the buffer + uint8_t bIncludeCrc:1; //!< \brief 0: Append automatically calculated CRC
    + //!< 1: Insert FCS (CRC) from the buffer + uint8_t :1; + uint8_t payloadLenMsb:5; //!< \brief Most significant bits of payload length. Should only be non-zero to create long + //!< non-standard packets for test purposes + } txOpt; + uint8_t payloadLen; //!< Number of bytes in the payload + uint8_t* pPayload; //!< Pointer to payload buffer of size payloadLen + ratmr_t timeStamp; //!< Time stamp of transmitted frame +}; + +//! @} + +//! \addtogroup CMD_IEEE_CSMA +//! @{ +#define CMD_IEEE_CSMA 0x2C02 +struct __RFC_STRUCT rfc_CMD_IEEE_CSMA_s { + uint16_t commandNo; //!< The command ID number 0x2C02 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint16_t randomState; //!< The state of the pseudo-random generator + uint8_t macMaxBE; //!< The IEEE 802.15.4 MAC parameter macMaxBE + uint8_t macMaxCSMABackoffs; //!< The IEEE 802.15.4 MAC parameter macMaxCSMABackoffs + struct { + uint8_t initCW:5; //!< The initialization value for the CW parameter + uint8_t bSlotted:1; //!< \brief 0: non-slotted CSMA
    + //!< 1: slotted CSMA + uint8_t rxOffMode:2; //!< \brief 0: RX stays on during CSMA backoffs
    + //!< 1: The CSMA-CA algorithm will suspend the receiver if no frame is being received
    + //!< 2: The CSMA-CA algorithm will suspend the receiver if no frame is being received, + //!< or after finishing it (including auto ACK) otherwise
    + //!< 3: The CSMA-CA algorithm will suspend the receiver immediately during back-offs + } csmaConfig; + uint8_t NB; //!< The NB parameter from the IEEE 802.15.4 CSMA-CA algorithm + uint8_t BE; //!< The BE parameter from the IEEE 802.15.4 CSMA-CA algorithm + uint8_t remainingPeriods; //!< The number of remaining periods from a paused backoff countdown + int8_t lastRssi; //!< RSSI measured at the last CCA operation + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to end the CSMA-CA operation + ratmr_t lastTimeStamp; //!< Time of the last CCA operation + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the + //!< CSMA-CA operation +}; + +//! @} + +//! \addtogroup CMD_IEEE_RX_ACK +//! @{ +#define CMD_IEEE_RX_ACK 0x2C03 +struct __RFC_STRUCT rfc_CMD_IEEE_RX_ACK_s { + uint16_t commandNo; //!< The command ID number 0x2C03 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t seqNo; //!< Sequence number to expect + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to give up acknowledgement reception + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to give up + //!< acknowledgement reception +}; + +//! @} + +//! \addtogroup CMD_IEEE_ABORT_BG +//! @{ +#define CMD_IEEE_ABORT_BG 0x2C04 +struct __RFC_STRUCT rfc_CMD_IEEE_ABORT_BG_s { + uint16_t commandNo; //!< The command ID number 0x2C04 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; +}; + +//! @} + +//! \addtogroup CMD_IEEE_MOD_CCA +//! @{ +#define CMD_IEEE_MOD_CCA 0x2001 +struct __RFC_STRUCT rfc_CMD_IEEE_MOD_CCA_s { + uint16_t commandNo; //!< The command ID number 0x2001 + struct { + uint8_t ccaEnEnergy:1; //!< Enable energy scan as CCA source + uint8_t ccaEnCorr:1; //!< Enable correlator based carrier sense as CCA source + uint8_t ccaEnSync:1; //!< Enable sync found based carrier sense as CCA source + uint8_t ccaCorrOp:1; //!< \brief Operator to use between energy based and correlator based CCA
    + //!< 0: Report busy channel if either ccaEnergy or ccaCorr are busy
    + //!< 1: Report busy channel if both ccaEnergy and ccaCorr are busy + uint8_t ccaSyncOp:1; //!< \brief Operator to use between sync found based CCA and the others
    + //!< 0: Always report busy channel if ccaSync is busy
    + //!< 1: Always report idle channel if ccaSync is idle + uint8_t ccaCorrThr:2; //!< Threshold for number of correlation peaks in correlator based carrier sense + } newCcaOpt; //!< New value of ccaOpt for the running background level operation + int8_t newCcaRssiThr; //!< New value of ccaRssiThr for the running background level operation +}; + +//! @} + +//! \addtogroup CMD_IEEE_MOD_FILT +//! @{ +#define CMD_IEEE_MOD_FILT 0x2002 +struct __RFC_STRUCT rfc_CMD_IEEE_MOD_FILT_s { + uint16_t commandNo; //!< The command ID number 0x2002 + struct { + uint16_t frameFiltEn:1; //!< \brief 0: Disable frame filtering
    + //!< 1: Enable frame filtering + uint16_t frameFiltStop:1; //!< \brief 0: Receive all packets to the end
    + //!< 1: Stop receiving frame once frame filtering has caused the frame to be rejected. + uint16_t autoAckEn:1; //!< \brief 0: Disable auto ACK
    + //!< 1: Enable auto ACK. + uint16_t slottedAckEn:1; //!< \brief 0: Non-slotted ACK
    + //!< 1: Slotted ACK. + uint16_t autoPendEn:1; //!< \brief 0: Auto-pend disabled
    + //!< 1: Auto-pend enabled + uint16_t defaultPend:1; //!< The value of the pending data bit in auto ACK packets that are not subject to auto-pend + uint16_t bPendDataReqOnly:1; //!< \brief 0: Use auto-pend for any packet
    + //!< 1: Use auto-pend for data request packets only + uint16_t bPanCoord:1; //!< \brief 0: Device is not PAN coordinator
    + //!< 1: Device is PAN coordinator + uint16_t maxFrameVersion:2; //!< Reject frames where the frame version field in the FCF is greater than this value + uint16_t fcfReservedMask:3; //!< Value to be AND-ed with the reserved part of the FCF; frame rejected if result is non-zero + uint16_t modifyFtFilter:2; //!< \brief Treatment of MSB of frame type field before frame-type filtering:
    + //!< 0: No modification
    + //!< 1: Invert MSB
    + //!< 2: Set MSB to 0
    + //!< 3: Set MSB to 1 + uint16_t bStrictLenFilter:1; //!< \brief 0: Accept acknowledgement frames of any length >= 5
    + //!< 1: Accept only acknowledgement frames of length 5 + } newFrameFiltOpt; //!< New value of frameFiltOpt for the running background level operation + struct { + uint8_t bAcceptFt0Beacon:1; //!< \brief Treatment of frames with frame type 000 (beacon):
    + //!< 0: Reject
    + //!< 1: Accept + uint8_t bAcceptFt1Data:1; //!< \brief Treatment of frames with frame type 001 (data):
    + //!< 0: Reject
    + //!< 1: Accept + uint8_t bAcceptFt2Ack:1; //!< \brief Treatment of frames with frame type 010 (ACK):
    + //!< 0: Reject, unless running ACK receive command
    + //!< 1: Always accept + uint8_t bAcceptFt3MacCmd:1; //!< \brief Treatment of frames with frame type 011 (MAC command):
    + //!< 0: Reject
    + //!< 1: Accept + uint8_t bAcceptFt4Reserved:1; //!< \brief Treatment of frames with frame type 100 (reserved):
    + //!< 0: Reject
    + //!< 1: Accept + uint8_t bAcceptFt5Reserved:1; //!< \brief Treatment of frames with frame type 101 (reserved):
    + //!< 0: Reject
    + //!< 1: Accept + uint8_t bAcceptFt6Reserved:1; //!< \brief Treatment of frames with frame type 110 (reserved):
    + //!< 0: Reject
    + //!< 1: Accept + uint8_t bAcceptFt7Reserved:1; //!< \brief Treatment of frames with frame type 111 (reserved):
    + //!< 0: Reject
    + //!< 1: Accept + } newFrameTypes; //!< New value of frameTypes for the running background level operation +}; + +//! @} + +//! \addtogroup CMD_IEEE_MOD_SRC_MATCH +//! @{ +#define CMD_IEEE_MOD_SRC_MATCH 0x2003 +struct __RFC_STRUCT rfc_CMD_IEEE_MOD_SRC_MATCH_s { + uint16_t commandNo; //!< The command ID number 0x2003 + struct { + uint8_t bEnable:1; //!< \brief 0: Disable entry
    + //!< 1: Enable entry + uint8_t srcPend:1; //!< New value of the pending bit for the entry + uint8_t entryType:1; //!< \brief 0: Extended address
    + //!< 1: Short address + } options; + uint8_t entryNo; //!< Index of entry to enable or disable +}; + +//! @} + +//! \addtogroup CMD_IEEE_ABORT_FG +//! @{ +#define CMD_IEEE_ABORT_FG 0x2401 +struct __RFC_STRUCT rfc_CMD_IEEE_ABORT_FG_s { + uint16_t commandNo; //!< The command ID number 0x2401 +}; + +//! @} + +//! \addtogroup CMD_IEEE_STOP_FG +//! @{ +#define CMD_IEEE_STOP_FG 0x2402 +struct __RFC_STRUCT rfc_CMD_IEEE_STOP_FG_s { + uint16_t commandNo; //!< The command ID number 0x2402 +}; + +//! @} + +//! \addtogroup CMD_IEEE_CCA_REQ +//! @{ +#define CMD_IEEE_CCA_REQ 0x2403 +struct __RFC_STRUCT rfc_CMD_IEEE_CCA_REQ_s { + uint16_t commandNo; //!< The command ID number 0x2403 + int8_t currentRssi; //!< The RSSI currently observed on the channel + int8_t maxRssi; //!< The maximum RSSI observed on the channel since Rx was started + struct { + uint8_t ccaState:2; //!< \brief Value of the current CCA state
    + //!< 0: Idle
    + //!< 1: Busy
    + //!< 2: Invalid + uint8_t ccaEnergy:2; //!< \brief Value of the current energy detect CCA state
    + //!< 0: Idle
    + //!< 1: Busy
    + //!< 2: Invalid + uint8_t ccaCorr:2; //!< \brief Value of the current correlator based carrier sense CCA state
    + //!< 0: Idle
    + //!< 1: Busy
    + //!< 2: Invalid + uint8_t ccaSync:1; //!< \brief Value of the current sync found based carrier sense CCA state
    + //!< 0: Idle
    + //!< 1: Busy + } ccaInfo; +}; + +//! @} + +//! \addtogroup ieeeRxOutput +//! @{ +//! Output structure for CMD_IEEE_RX + +struct __RFC_STRUCT rfc_ieeeRxOutput_s { + uint8_t nTxAck; //!< Total number of transmitted ACK frames + uint8_t nRxBeacon; //!< Number of received beacon frames + uint8_t nRxData; //!< Number of received data frames + uint8_t nRxAck; //!< Number of received acknowledgement frames + uint8_t nRxMacCmd; //!< Number of received MAC command frames + uint8_t nRxReserved; //!< Number of received frames with reserved frame type + uint8_t nRxNok; //!< Number of received frames with CRC error + uint8_t nRxIgnored; //!< Number of frames received that are to be ignored + uint8_t nRxBufFull; //!< Number of received frames discarded because the Rx buffer was full + int8_t lastRssi; //!< RSSI of last received frame + int8_t maxRssi; //!< Highest RSSI observed in the operation + uint8_t __dummy0; + ratmr_t beaconTimeStamp; //!< Time stamp of last received beacon frame +}; + +//! @} + +//! \addtogroup shortAddrEntry +//! @{ +//! Structure for short address entries + +struct __RFC_STRUCT rfc_shortAddrEntry_s { + uint16_t shortAddr; //!< Short address + uint16_t panId; //!< PAN ID +}; + +//! @} + +//! \addtogroup ieeeRxCorrCrc +//! @{ +//! Receive status byte that may be appended to message in receive buffer + +struct __RFC_STRUCT rfc_ieeeRxCorrCrc_s { + struct { + uint8_t corr:6; //!< The correlation value + uint8_t bIgnore:1; //!< 1 if the packet should be rejected by frame filtering, 0 otherwise + uint8_t bCrcErr:1; //!< 1 if the packet was received with CRC error, 0 otherwise + } status; +}; + +//! @} + +//! @} +//! @} +#endif /* IEEE_CMD_H_ */ diff --git a/cpu/cc26xx-cc13xx/rf-core/api/ieee_mailbox.h b/cpu/cc26xx-cc13xx/rf-core/api/ieee_mailbox.h new file mode 100644 index 000000000..c6784da09 --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/api/ieee_mailbox.h @@ -0,0 +1,75 @@ +/****************************************************************************** +* Filename: ieee_mailbox.h +* Revised: $ $ +* Revision: $ $ +* +* Description: Definitions for IEEE 802.15.4 interface +* +* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* 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 Texas Instruments Incorporated 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 +* OWNER 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. +* +******************************************************************************/ + +#ifndef IEEE_MAILBOX_H_ +#define IEEE_MAILBOX_H_ + +#include "mailbox.h" + + +/// \name Radio operation status +///@{ +/// \name Operation not finished +///@{ +#define IEEE_SUSPENDED 0x2001 ///< Operation suspended +///@} +/// \name Operation finished normally +///@{ +#define IEEE_DONE_OK 0x2400 ///< Operation ended normally +#define IEEE_DONE_BUSY 0x2401 ///< CSMA-CA operation ended with failure +#define IEEE_DONE_STOPPED 0x2402 ///< Operation stopped after stop command +#define IEEE_DONE_ACK 0x2403 ///< ACK packet received with pending data bit cleared +#define IEEE_DONE_ACKPEND 0x2404 ///< ACK packet received with pending data bit set +#define IEEE_DONE_TIMEOUT 0x2405 ///< Operation ended due to timeout +#define IEEE_DONE_BGEND 0x2406 ///< FG operation ended because necessary background level + ///< operation ended +#define IEEE_DONE_ABORT 0x2407 ///< Operation aborted by command +///@} +/// \name Operation finished with error +///@{ +#define IEEE_ERROR_PAR 0x2800 ///< Illegal parameter +#define IEEE_ERROR_NO_SETUP 0x2801 ///< Operation using Rx or Tx attemted when not in 15.4 mode +#define IEEE_ERROR_NO_FS 0x2802 ///< Operation using Rx or Tx attemted without frequency synth configured +#define IEEE_ERROR_SYNTH_PROG 0x2803 ///< Synthesizer programming failed to complete on time +#define IEEE_ERROR_RXOVF 0x2804 ///< Receiver overflowed during operation +#define IEEE_ERROR_TXUNF 0x2805 ///< Transmitter underflowed during operation +///@} +///@} + +#endif /* IEEE_MAILBOX_H_ */ diff --git a/cpu/cc26xx-cc13xx/rf-core/api/mailbox.h b/cpu/cc26xx-cc13xx/rf-core/api/mailbox.h new file mode 100644 index 000000000..119565959 --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/api/mailbox.h @@ -0,0 +1,328 @@ +/****************************************************************************** +* Filename: mailbox.h +* Revised: 2015-06-29 12:59:58 +0200 (Mon, 29 Jun 2015) +* Revision: 44063 +* +* Description: Definitions for interface between system and radio CPU +* +* Copyright (c) 2015, Texas Instruments Incorporated +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1) Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2) 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. +* +* 3) Neither the name of the ORGANIZATION 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. +* +******************************************************************************/ + +#ifndef MAILBOX_H_ +#define MAILBOX_H_ + +#include +#include + +/// Type definition for RAT +typedef uint32_t ratmr_t; + + + +/// Type definition for a data queue +typedef struct { + uint8_t *pCurrEntry; ///< Pointer to the data queue entry to be used, NULL for an empty queue + uint8_t *pLastEntry; ///< Pointer to the last entry in the queue, NULL for a circular queue +} dataQueue_t; + + + +/// \name CPE interrupt definitions +/// Interrupt masks for the CPE interrupt in RDBELL. +///@{ +#define IRQN_COMMAND_DONE 0 ///< Radio operation command finished +#define IRQN_LAST_COMMAND_DONE 1 ///< Last radio operation command in a chain finished +#define IRQN_FG_COMMAND_DONE 2 ///< FG level Radio operation command finished +#define IRQN_LAST_FG_COMMAND_DONE 3 ///< Last FG level radio operation command in a chain finished +#define IRQN_TX_DONE 4 ///< Packet transmitted +#define IRQN_TX_ACK 5 ///< ACK packet transmitted +#define IRQN_TX_CTRL 6 ///< Control packet transmitted +#define IRQN_TX_CTRL_ACK 7 ///< Acknowledgement received on a transmitted control packet +#define IRQN_TX_CTRL_ACK_ACK 8 ///< Acknowledgement received on a transmitted control packet, and acknowledgement transmitted for that packet +#define IRQN_TX_RETRANS 9 ///< Packet retransmitted +#define IRQN_TX_ENTRY_DONE 10 ///< Tx queue data entry state changed to Finished +#define IRQN_TX_BUFFER_CHANGED 11 ///< A buffer change is complete +#define IRQN_RX_OK 16 ///< Packet received with CRC OK, payload, and not to be ignored +#define IRQN_RX_NOK 17 ///< Packet received with CRC error +#define IRQN_RX_IGNORED 18 ///< Packet received with CRC OK, but to be ignored +#define IRQN_RX_EMPTY 19 ///< Packet received with CRC OK, not to be ignored, no payload +#define IRQN_RX_CTRL 20 ///< Control packet received with CRC OK, not to be ignored +#define IRQN_RX_CTRL_ACK 21 ///< Control packet received with CRC OK, not to be ignored, then ACK sent +#define IRQN_RX_BUF_FULL 22 ///< Packet received that did not fit in the Rx queue +#define IRQN_RX_ENTRY_DONE 23 ///< Rx queue data entry changing state to Finished +#define IRQN_RX_DATA_WRITTEN 24 ///< Data written to partial read Rx buffer +#define IRQN_RX_N_DATA_WRITTEN 25 ///< Specified number of bytes written to partial read Rx buffer +#define IRQN_RX_ABORTED 26 ///< Packet reception stopped before packet was done +#define IRQN_RX_COLLISION_DETECTED 27 ///< A collision was indicated during packet reception +#define IRQN_SYNTH_NO_LOCK 28 ///< The synth has gone out of lock after calibration +#define IRQN_MODULES_UNLOCKED 29 ///< As part of the boot process, the CM0 has opened access to RF core modules and memories +#define IRQN_BOOT_DONE 30 ///< The RF core CPU boot is finished + +#define IRQN_INTERNAL_ERROR 31 ///< Internal error observed + +#define IRQ_COMMAND_DONE (1U << IRQN_COMMAND_DONE) +#define IRQ_LAST_COMMAND_DONE (1U << IRQN_LAST_COMMAND_DONE) +#define IRQ_FG_COMMAND_DONE (1U << IRQN_FG_COMMAND_DONE) +#define IRQ_LAST_FG_COMMAND_DONE (1U << IRQN_LAST_FG_COMMAND_DONE) + +#define IRQ_TX_DONE (1U << IRQN_TX_DONE) +#define IRQ_TX_ACK (1U << IRQN_TX_ACK) +#define IRQ_TX_CTRL (1U << IRQN_TX_CTRL) +#define IRQ_TX_CTRL_ACK (1U << IRQN_TX_CTRL_ACK) +#define IRQ_TX_CTRL_ACK_ACK (1U << IRQN_TX_CTRL_ACK_ACK) +#define IRQ_TX_RETRANS (1U << IRQN_TX_RETRANS) + +#define IRQ_TX_ENTRY_DONE (1U << IRQN_TX_ENTRY_DONE) +#define IRQ_TX_BUFFER_CHANGED (1U << IRQN_TX_BUFFER_CHANGED) + +#define IRQ_RX_OK (1U << IRQN_RX_OK) +#define IRQ_RX_NOK (1U << IRQN_RX_NOK) +#define IRQ_RX_IGNORED (1U << IRQN_RX_IGNORED) +#define IRQ_RX_EMPTY (1U << IRQN_RX_EMPTY) +#define IRQ_RX_CTRL (1U << IRQN_RX_CTRL) +#define IRQ_RX_CTRL_ACK (1U << IRQN_RX_CTRL_ACK) +#define IRQ_RX_BUF_FULL (1U << IRQN_RX_BUF_FULL) +#define IRQ_RX_ENTRY_DONE (1U << IRQN_RX_ENTRY_DONE) +#define IRQ_RX_DATA_WRITTEN (1U << IRQN_RX_DATA_WRITTEN) +#define IRQ_RX_N_DATA_WRITTEN (1U << IRQN_RX_N_DATA_WRITTEN) +#define IRQ_RX_ABORTED (1U << IRQN_RX_ABORTED) +#define IRQ_RX_COLLISION_DETECTED (1U << IRQN_RX_COLLISION_DETECTED) +#define IRQ_SYNTH_NO_LOCK (1U << IRQN_SYNTH_NO_LOCK) +#define IRQ_MODULES_UNLOCKED (1U << IRQN_MODULES_UNLOCKED) +#define IRQ_BOOT_DONE (1U << IRQN_BOOT_DONE) +#define IRQ_INTERNAL_ERROR (1U << IRQN_INTERNAL_ERROR) +///@} + + + +/// \name CMDSTA values +/// Values returned in result byte of CMDSTA +///@{ +#define CMDSTA_Pending 0x00 ///< The command has not yet been parsed +#define CMDSTA_Done 0x01 ///< Command successfully parsed + +#define CMDSTA_IllegalPointer 0x81 ///< The pointer signalled in CMDR is not valid +#define CMDSTA_UnknownCommand 0x82 ///< The command number in the command structure is unknown +#define CMDSTA_UnknownDirCommand 0x83 ///< The command number for a direct command is unknown, or the + ///< command is not a direct command +#define CMDSTA_ContextError 0x85 ///< An immediate or direct command was issued in a context + ///< where it is not supported +#define CMDSTA_SchedulingError 0x86 ///< A radio operation command was attempted to be scheduled + ///< while another operation was already running in the RF core +#define CMDSTA_ParError 0x87 ///< There were errors in the command parameters that are parsed + ///< on submission. +#define CMDSTA_QueueError 0x88 ///< An operation on a data entry queue was attempted that was + ///< not supported by the queue in its current state +#define CMDSTA_QueueBusy 0x89 ///< An operation on a data entry was attempted while that entry + ///< was busy +///@} + + + +/// \name Macros for sending direct commands +///@{ +/// Direct command with no parameter +#define CMDR_DIR_CMD(cmdId) (((cmdId) << 16) | 1) + +/// Direct command with 1-byte parameter +#define CMDR_DIR_CMD_1BYTE(cmdId, par) (((cmdId) << 16) | ((par) << 8) | 1) + +/// Direct command with 2-byte parameter +#define CMDR_DIR_CMD_2BYTE(cmdId, par) (((cmdId) << 16) | ((par) & 0xFFFC) | 1) + +///@} + + + +/// \name Definitions for trigger types +///@{ +#define TRIG_NOW 0 ///< Triggers immediately +#define TRIG_NEVER 1 ///< Never trigs +#define TRIG_ABSTIME 2 ///< Trigs at an absolute time +#define TRIG_REL_SUBMIT 3 ///< Trigs at a time relative to the command was submitted +#define TRIG_REL_START 4 ///< Trigs at a time relative to the command started +#define TRIG_REL_PREVSTART 5 ///< Trigs at a time relative to the previous command in the chain started +#define TRIG_REL_FIRSTSTART 6 ///< Trigs at a time relative to the first command in the chain started +#define TRIG_REL_PREVEND 7 ///< Trigs at a time relative to the previous command in the chain ended +#define TRIG_REL_EVT1 8 ///< Trigs at a time relative to the context defined "Event 1" +#define TRIG_REL_EVT2 9 ///< Trigs at a time relative to the context defined "Event 2" +#define TRIG_EXTERNAL 10 ///< Trigs at an external event to the radio timer +#define TRIG_PAST_BM 0x80 ///< Bitmask for setting pastTrig bit in order to trig immediately if + ///< trigger happened in the past +///@} + + +/// \name Definitions for conditional execution +///@{ +#define COND_ALWAYS 0 ///< Always run next command (except in case of Abort) +#define COND_NEVER 1 ///< Never run next command +#define COND_STOP_ON_FALSE 2 ///< Run next command if this command returned True, stop if it returned + ///< False +#define COND_STOP_ON_TRUE 3 ///< Stop if this command returned True, run next command if it returned + ///< False +#define COND_SKIP_ON_FALSE 4 ///< Run next command if this command returned True, skip a number of + ///< commands if it returned False +#define COND_SKIP_ON_TRUE 5 ///< Skip a number of commands if this command returned True, run next + ///< command if it returned False +///@} + + + +/// \name Radio operation status +///@{ +/// \name Operation not finished +///@{ +#define IDLE 0x0000 ///< Operation not started +#define PENDING 0x0001 ///< Start of command is pending +#define ACTIVE 0x0002 ///< Running +#define SKIPPED 0x0003 ///< Operation skipped due to condition in another command +///@} +/// \name Operation finished normally +///@{ +#define DONE_OK 0x0400 ///< Operation ended normally +#define DONE_COUNTDOWN 0x0401 ///< Counter reached zero +#define DONE_RXERR 0x0402 ///< Operation ended with CRC error +#define DONE_TIMEOUT 0x0403 ///< Operation ended with timeout +#define DONE_STOPPED 0x0404 ///< Operation stopped after CMD_STOP command +#define DONE_ABORT 0x0405 ///< Operation aborted by CMD_ABORT command +#define DONE_FAILED 0x0406 ///< Scheduled immediate command failed +///@} +/// \name Operation finished with error +///@{ +#define ERROR_PAST_START 0x0800 ///< The start trigger occurred in the past +#define ERROR_START_TRIG 0x0801 ///< Illegal start trigger parameter +#define ERROR_CONDITION 0x0802 ///< Illegal condition for next operation +#define ERROR_PAR 0x0803 ///< Error in a command specific parameter +#define ERROR_POINTER 0x0804 ///< Invalid pointer to next operation +#define ERROR_CMDID 0x0805 ///< Next operation has a command ID that is undefined or not a radio + ///< operation command +#define ERROR_WRONG_BG 0x0806 ///< FG level command not compatible with running BG level command +#define ERROR_NO_SETUP 0x0807 ///< Operation using Rx or Tx attempted without CMD_RADIO_SETUP +#define ERROR_NO_FS 0x0808 ///< Operation using Rx or Tx attempted without frequency synth configured +#define ERROR_SYNTH_PROG 0x0809 ///< Synthesizer calibration failed +#define ERROR_TXUNF 0x080A ///< Tx underflow observed +#define ERROR_RXOVF 0x080B ///< Rx overflow observed +#define ERROR_NO_RX 0x080C ///< Attempted to access data from Rx when no such data was yet received +#define ERROR_PENDING 0x080D ///< Command submitted in the future with another command at different level pending +///@} +///@} + + +/// \name Data entry types +///@{ +#define DATA_ENTRY_TYPE_GEN 0 ///< General type: Tx entry or single element Rx entry +#define DATA_ENTRY_TYPE_MULTI 1 ///< Multi-element Rx entry type +#define DATA_ENTRY_TYPE_PTR 2 ///< Pointer entry type +#define DATA_ENTRY_TYPE_PARTIAL 3 ///< Partial read entry type +///@ + + +/// \name Data entry statuses +///@{ +#define DATA_ENTRY_PENDING 0 ///< Entry not yet used +#define DATA_ENTRY_ACTIVE 1 ///< Entry in use by radio CPU +#define DATA_ENTRY_BUSY 2 ///< Entry being updated +#define DATA_ENTRY_FINISHED 3 ///< Radio CPU is finished accessing the entry +#define DATA_ENTRY_UNFINISHED 4 ///< Radio CPU is finished accessing the entry, but packet could not be finished +///@} + + + +/// \name Macros for RF register override +///@{ +/// Macro for ADI half-size value-mask combination +#define ADI_VAL_MASK(addr, mask, value) \ +(((addr) & 1) ? (((mask) & 0x0F) | (((value) & 0x0F) << 4)) : \ + ((((mask) & 0x0F) << 4) | ((value) & 0x0F))) +/// 32-bit write of 16-bit value +#define HW_REG_OVERRIDE(addr, val) ((((uintptr_t) (addr)) & 0xFFFC) | ((uint32_t)(val) << 16)) +/// ADI register, full-size write +#define ADI_REG_OVERRIDE(adiNo, addr, val) (2 | ((uint32_t)(val) << 16) | \ +(((addr) & 0x3F) << 24) | (((adiNo) ? 1U : 0) << 31)) +/// 2 ADI registers, full-size write +#define ADI_2REG_OVERRIDE(adiNo, addr, val, addr2, val2) \ +(2 | ((uint32_t)(val2) << 2) | (((addr2) & 0x3F) << 10) | ((uint32_t)(val) << 16) | \ +(((addr) & 0x3F) << 24) | (((adiNo) ? 1U : 0) << 31)) +/// ADI register, half-size read-modify-write +#define ADI_HALFREG_OVERRIDE(adiNo, addr, mask, val) (2 | (ADI_VAL_MASK(addr, mask, val) << 16) | \ +(((addr) & 0x3F) << 24) | (1U << 30) | (((adiNo) ? 1U : 0) << 31)) +/// 2 ADI registers, half-size read-modify-write +#define ADI_2HALFREG_OVERRIDE(adiNo, addr, mask, val, addr2, mask2, val2) \ +(2 | (ADI_VAL_MASK(addr2, mask2, val2) << 2) | (((addr2) & 0x3F) << 10) | \ +(ADI_VAL_MASK(addr, mask, val) << 16) | (((addr) & 0x3F) << 24) | (1U << 30) | (((adiNo) ? 1U : 0) << 31)) + +/// 16-bit SW register as defined in radio_par_def.txt +#define SW_REG_OVERRIDE(cmd, field, val) (3 | ((_POSITION_##cmd##_##field) << 4) | ((uint32_t)(val) << 16)) +/// SW register as defined in radio_par_def.txt with added index (for use with registers > 16 bits). +#define SW_REG_IND_OVERRIDE(cmd, field, offset, val) (3 | \ +(((_POSITION_##cmd##_##field) + ((offset) << 1)) << 4) | ((uint32_t)(val) << 16)) +/// 8-bit SW register as defined in radio_par_def.txt +#define SW_REG_BYTE_OVERRIDE(cmd, field, val) (0x8003 | ((_POSITION_##cmd##_##field) << 4) | \ +((uint32_t)(val) << 16)) +/// Two 8-bit SW registers as defined in radio_par_def.txt; the one given by field and the next byte. +#define SW_REG_2BYTE_OVERRIDE(cmd, field, val0, val1) (3 | (((_POSITION_##cmd##_##field) & 0xFFFE) << 4) | \ + (((uint32_t)(val0) << 16) & 0x00FF0000) | ((uint32_t)(val1) << 24)) +#define HW16_ARRAY_OVERRIDE(addr, length) (1 | (((uintptr_t) (addr)) & 0xFFFC) | ((uint32_t)(length) << 16)) +#define HW32_ARRAY_OVERRIDE(addr, length) (1 | (((uintptr_t) (addr)) & 0xFFFC) | \ +((uint32_t)(length) << 16) | (1U << 30)) +#define ADI_ARRAY_OVERRIDE(adiNo, addr, bHalfSize, length) (1 | ((((addr) & 0x3F) << 2)) | \ +((!!(bHalfSize)) << 8) | ((!!(adiNo)) << 9) | ((uint32_t)(length) << 16) | (2U << 30)) +#define SW_ARRAY_OVERRIDE(cmd, firstfield, length) (1 | (((_POSITION_##cmd##_##firstfield)) << 2) | \ +((uint32_t)(length) << 16) | (3U << 30)) +#define MCE_RFE_OVERRIDE(bMceRam, mceRomBank, mceMode, bRfeRam, rfeRomBank, rfeMode) \ + (7 | ((!!(bMceRam)) << 8) | (((mceRomBank) & 0x07) << 9) | ((!!(bRfeRam)) << 12) | (((rfeRomBank) & 0x07) << 13) | \ + (((mceMode) & 0x00FF) << 16) | (((rfeMode) & 0x00FF) << 24)) +#define NEW_OVERRIDE_SEGMENT(address) (((((uintptr_t)(address)) & 0x03FFFFFC) << 6) | 0x000F | \ + (((((uintptr_t)(address) >> 24) == 0x20) ? 0x01 : \ + (((uintptr_t)(address) >> 24) == 0x21) ? 0x02 : \ + (((uintptr_t)(address) >> 24) == 0xA0) ? 0x03 : \ + (((uintptr_t)(address) >> 24) == 0x00) ? 0x04 : \ + (((uintptr_t)(address) >> 24) == 0x10) ? 0x05 : \ + (((uintptr_t)(address) >> 24) == 0x11) ? 0x06 : \ + (((uintptr_t)(address) >> 24) == 0x40) ? 0x07 : \ + (((uintptr_t)(address) >> 24) == 0x50) ? 0x08 : \ + 0x09) << 4)) // Use illegal value for illegal address range +/// End of string for override register +#define END_OVERRIDE 0xFFFFFFFF + + +/// ADI address-value pair +#define ADI_ADDR_VAL(addr, value) ((((addr) & 0x7F) << 8) | ((value) & 0xFF)) +#define ADI_ADDR_VAL_MASK(addr, mask, value) ((((addr) & 0x7F) << 8) | ADI_VAL_MASK(addr, mask, value)) + +/// Low half-word +#define LOWORD(value) ((value) & 0xFFFF) +/// High half-word +#define HIWORD(value) ((value) >> 16) +///@} + + +#endif /* MAILBOX_H_ */ diff --git a/cpu/cc26xx-cc13xx/rf-core/api/prop_cmd.h b/cpu/cc26xx-cc13xx/rf-core/api/prop_cmd.h new file mode 100644 index 000000000..e0d0a0c35 --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/api/prop_cmd.h @@ -0,0 +1,596 @@ +/****************************************************************************** +* Filename: prop_cmd.h +* Revised: 2015-08-04 10:40:45 +0200 (Tue, 04 Aug 2015) +* Revision: 44326 +* +* Description: CC13xx API for Proprietary mode commands +* +* Copyright (c) 2015, Texas Instruments Incorporated +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1) Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2) 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. +* +* 3) Neither the name of the ORGANIZATION 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. +* +******************************************************************************/ + +#ifndef PROP_CMD_H_ +#define PROP_CMD_H_ + +#ifndef __RFC_STRUCT +#ifdef __GNUC__ +#define __RFC_STRUCT __attribute__ ((aligned (4))) +#else +#define __RFC_STRUCT +#endif +#endif + +//! \addtogroup rfc +//! @{ + +//! \addtogroup prop_cmd +//! @{ + +#include +#include "mailbox.h" +#include "common_cmd.h" + +typedef struct __RFC_STRUCT rfc_carrierSense_s rfc_carrierSense_t; +typedef struct __RFC_STRUCT rfc_CMD_PROP_TX_s rfc_CMD_PROP_TX_t; +typedef struct __RFC_STRUCT rfc_CMD_PROP_RX_s rfc_CMD_PROP_RX_t; +typedef struct __RFC_STRUCT rfc_CMD_PROP_TX_ADV_s rfc_CMD_PROP_TX_ADV_t; +typedef struct __RFC_STRUCT rfc_CMD_PROP_RX_ADV_s rfc_CMD_PROP_RX_ADV_t; +typedef struct __RFC_STRUCT rfc_CMD_PROP_RADIO_SETUP_s rfc_CMD_PROP_RADIO_SETUP_t; +typedef struct __RFC_STRUCT rfc_CMD_PROP_RADIO_DIV_SETUP_s rfc_CMD_PROP_RADIO_DIV_SETUP_t; +typedef struct __RFC_STRUCT rfc_CMD_PROP_SET_LEN_s rfc_CMD_PROP_SET_LEN_t; +typedef struct __RFC_STRUCT rfc_CMD_PROP_RESTART_RX_s rfc_CMD_PROP_RESTART_RX_t; +typedef struct __RFC_STRUCT rfc_propRxOutput_s rfc_propRxOutput_t; +typedef struct __RFC_STRUCT rfc_propRxStatus_s rfc_propRxStatus_t; + +//! \addtogroup carrierSense +//! @{ +struct __RFC_STRUCT rfc_carrierSense_s { + struct { + uint8_t bEnaRssi:1; //!< If 1, enable RSSI as a criterion + uint8_t bEnaCorr:1; //!< If 1, enable correlation as a criterion + uint8_t operation:1; //!< \brief 0: Busy if either RSSI or correlation indicates Busy
    + //!< 1: Busy if both RSSI and correlation indicates Busy + uint8_t busyOp:1; //!< \brief 0: Continue carrier sense on channel Busy
    + //!< 1: End carrier sense on channel Busy
    + //!< For an Rx command, the receiver will continue when carrier sense ends, but it will then not end if channel goes Idle + uint8_t idleOp:1; //!< \brief 0: Continue on channel Idle
    + //!< 1: End on channel Idle + uint8_t timeoutRes:1; //!< \brief 0: Timeout with channel state Invalid treated as Busy
    + //!< 1: Timeout with channel state Invalid treated as Idle + } csConf; + int8_t rssiThr; //!< RSSI threshold + uint8_t numRssiIdle; //!< \brief Number of consecutive RSSI measurements below the threshold needed before the channel is + //!< declared Idle + uint8_t numRssiBusy; //!< \brief Number of consecutive RSSI measurements above the threshold needed before the channel is + //!< declared Busy + uint16_t corrPeriod; //!< Number of RAT ticks for a correlation observation periods + struct { + uint8_t numCorrInv:4; //!< \brief Number of subsequent correlation tops with maximum corrPeriod RAT + //!< ticks between them needed to go from Idle to Invalid + uint8_t numCorrBusy:4; //!< \brief Number of subsequent correlation tops with maximum corrPeriod RAT + //!< ticks between them needed to go from Invalid to Busy + } corrConfig; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } csEndTrigger; //!< Trigger classifier for ending the carrier sense + ratmr_t csEndTime; //!< Time used together with csEndTrigger for ending the operation +}; + +//! @} + +//! \addtogroup CMD_PROP_TX +//! @{ +#define CMD_PROP_TX 0x3801 +struct __RFC_STRUCT rfc_CMD_PROP_TX_s { + uint16_t commandNo; //!< The command ID number 0x3801 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint8_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
    + //!< 1: Turn frequency synth off after command + uint8_t :2; + uint8_t bUseCrc:1; //!< \brief 0: Do not append CRC
    + //!< 1: Append CRC + uint8_t bVarLen:1; //!< \brief 0: Fixed length
    + //!< 1: Transmit length as first byte + } pktConf; + uint8_t pktLen; //!< Packet length + uint32_t syncWord; //!< Sync word to transmit + uint8_t* pPkt; //!< Pointer to packet +}; + +//! @} + +//! \addtogroup CMD_PROP_RX +//! @{ +#define CMD_PROP_RX 0x3802 +struct __RFC_STRUCT rfc_CMD_PROP_RX_s { + uint16_t commandNo; //!< The command ID number 0x3802 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint8_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
    + //!< 1: Turn frequency synth off after command + uint8_t bRepeatOk:1; //!< \brief 0: End operation after receiving a packet correctly
    + //!< 1: Go back to sync search after receiving a packet correctly + uint8_t bRepeatNok:1; //!< \brief 0: End operation after receiving a packet with CRC error
    + //!< 1: Go back to sync search after receiving a packet with CRC error + uint8_t bUseCrc:1; //!< \brief 0: Do not check CRC
    + //!< 1: Check CRC + uint8_t bVarLen:1; //!< \brief 0: Fixed length
    + //!< 1: Receive length as first byte + uint8_t bChkAddress:1; //!< \brief 0: No address check
    + //!< 1: Check address + uint8_t endType:1; //!< \brief 0: Packet is received to the end if end trigger happens after sync is obtained
    + //!< 1: Packet reception is stopped if end trigger happens + uint8_t filterOp:1; //!< \brief 0: Stop receiver and restart sync search on address mismatch
    + //!< 1: Receive packet and mark it as ignored on address mismatch + } pktConf; + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically discard ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically discard packets with CRC error from Rx queue + uint8_t :1; + uint8_t bIncludeHdr:1; //!< If 1, include the received header or length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + } rxConf; //!< Rx configuration + uint32_t syncWord; //!< Sync word to listen for + uint8_t maxPktLen; //!< \brief Packet length for fixed length, maximum packet length for variable length
    + //!< 0: Unlimited or unknown length + uint8_t address0; //!< Address + uint8_t address1; //!< \brief Address (set equal to address0 to accept only one address. If 0xFF, accept + //!< 0x00 as well) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger classifier for ending the operation + ratmr_t endTime; //!< Time used together with endTrigger for ending the operation + dataQueue_t* pQueue; //!< Pointer to receive queue + uint8_t* pOutput; //!< Pointer to output structure +}; + +//! @} + +//! \addtogroup CMD_PROP_TX_ADV +//! @{ +#define CMD_PROP_TX_ADV 0x3803 +struct __RFC_STRUCT rfc_CMD_PROP_TX_ADV_s { + uint16_t commandNo; //!< The command ID number 0x3803 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint8_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
    + //!< 1: Turn frequency synth off after command + uint8_t :2; + uint8_t bUseCrc:1; //!< \brief 0: Do not append CRC
    + //!< 1: Append CRC + uint8_t bCrcIncSw:1; //!< \brief 0:Do not include sync word in CRC calculation
    + //!< 1: Include sync word in CRC calculation + uint8_t bCrcIncHdr:1; //!< \brief 0: Do not include header in CRC calculation
    + //!< 1: Include header in CRC calculation + } pktConf; + uint8_t numHdrBits; //!< Number of bits in header (0–32) + uint16_t pktLen; //!< Packet length. 0: Unlimited + struct { + uint8_t bExtTxTrig:1; //!< \brief 0: Start packet on a fixed time from the command start trigger
    + //!< 1: Start packet on an external trigger (input event to RAT) + uint8_t inputMode:2; //!< \brief Input mode if external trigger is used for Tx start
    + //!< 0: Rising edge
    + //!< 1: Falling edge
    + //!< 2: Both edges
    + //!< 3: Reserved + uint8_t source:5; //!< RAT input event number used for capture if external trigger is used for Tx start + } startConf; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } preTrigger; //!< Trigger for transition from preamble to sync word + ratmr_t preTime; //!< \brief Time used together with preTrigger for transition from preamble to sync + //!< word. If preTrigger.triggerType is set to "now", one preamble as + //!< configured in the setup will be sent. Otherwise, the preamble will be repeated until + //!< this trigger is observed. + uint32_t syncWord; //!< Sync word to transmit + uint8_t* pPkt; //!< Pointer to packet, or Tx queue for unlimited length +}; + +//! @} + +//! \addtogroup CMD_PROP_RX_ADV +//! @{ +#define CMD_PROP_RX_ADV 0x3804 +struct __RFC_STRUCT rfc_CMD_PROP_RX_ADV_s { + uint16_t commandNo; //!< The command ID number 0x3804 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint8_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
    + //!< 1: Turn frequency synth off after command + uint8_t bRepeatOk:1; //!< \brief 0: End operation after receiving a packet correctly
    + //!< 1: Go back to sync search after receiving a packet correctly + uint8_t bRepeatNok:1; //!< \brief 0: End operation after receiving a packet with CRC error
    + //!< 1: Go back to sync search after receiving a packet with CRC error + uint8_t bUseCrc:1; //!< \brief 0: Do not check CRC
    + //!< 1: Check CRC + uint8_t bCrcIncSw:1; //!< \brief 0: Do not include sync word in CRC calculation
    + //!< 1: Include sync word in CRC calculation + uint8_t bCrcIncHdr:1; //!< \brief 0: Do not include header in CRC calculation
    + //!< 1: Include header in CRC calculation + uint8_t endType:1; //!< \brief 0: Packet is received to the end if end trigger happens after sync is obtained
    + //!< 1: Packet reception is stopped if end trigger happens + uint8_t filterOp:1; //!< \brief 0: Stop receiver and restart sync search on address mismatch
    + //!< 1: Receive packet and mark it as ignored on address mismatch + } pktConf; + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically discard ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically discard packets with CRC error from Rx queue + uint8_t :1; + uint8_t bIncludeHdr:1; //!< If 1, include the received header or length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + } rxConf; //!< Rx configuration + uint32_t syncWord0; //!< Sync word to listen for + uint32_t syncWord1; //!< Alternative sync word if non-zero + uint16_t maxPktLen; //!< \brief Packet length for fixed length, maximum packet length for variable length
    + //!< 0: Unlimited or unknown length + struct { + uint16_t numHdrBits:6; //!< Number of bits in header (0–32) + uint16_t lenPos:5; //!< Position of length field in header (0–31) + uint16_t numLenBits:5; //!< Number of bits in length field (0–16) + } hdrConf; + struct { + uint16_t addrType:1; //!< \brief 0: Address after header
    + //!< 1: Address in header + uint16_t addrSize:5; //!< \brief If addrType = 0: Address size in bytes
    + //!< If addrType = 1: Address size in bits + uint16_t addrPos:5; //!< \brief If addrType = 1: Bit position of address in header
    + //!< If addrType = 0: Non-zero to extend address with sync word identifier + uint16_t numAddr:5; //!< Number of addresses in address list + } addrConf; + int8_t lenOffset; //!< Signed value to add to length field + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger classifier for ending the operation + ratmr_t endTime; //!< Time used together with endTrigger for ending the operation + uint8_t* pAddr; //!< Pointer to address list + dataQueue_t* pQueue; //!< Pointer to receive queue + uint8_t* pOutput; //!< Pointer to output structure +}; + +//! @} + +//! \addtogroup CMD_PROP_RADIO_SETUP +//! @{ +#define CMD_PROP_RADIO_SETUP 0x3806 +struct __RFC_STRUCT rfc_CMD_PROP_RADIO_SETUP_s { + uint16_t commandNo; //!< The command ID number 0x3806 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint16_t modType:3; //!< \brief 0: FSK
    + //!< 1: GFSK
    + //!< Others: Reserved + uint16_t deviation:13; //!< Deviation (250 Hz steps) + } modulation; + struct { + uint32_t preScale:4; //!< Prescaler value + uint32_t :4; + uint32_t rateWord:21; //!< Rate word + } symbolRate; + uint8_t rxBw; //!< Receiver bandwidth + struct { + uint8_t nPreamBytes:6; //!< \brief 0–30: Number of preamble bytes
    + //!< 31: 4 preamble bits + uint8_t preamMode:2; //!< \brief 0: Send 0 as the first preamble bit
    + //!< 1: Send 1 as the first preamble bit
    + //!< 2: Send same first bit in preamble and sync word
    + //!< 3: Send different first bit in preamble and sync word + } preamConf; + struct { + uint16_t nSwBits:6; //!< Number of sync word bits (up to 32) + uint16_t bBitReversal:1; //!< \brief 0: Use positive deviation for 1
    + //!< 1: Use positive deviation for 0 + uint16_t bMsbFirst:1; //!< \brief 0: Least significant bit transmitted first
    + //!< 1: Most significant bit transmitted first + uint16_t fecMode:4; //!< \brief Select coding
    + //!< 0: Uncoded binary modulation
    + //!< 10: Manchester coded binary modulation
    + //!< Others: Reserved + uint16_t :1; + uint16_t whitenMode:3; //!< \brief 0: No whitening
    + //!< 1: CC1101/CC2500 compatible whitening
    + //!< 2: PN9 whitening without byte reversal
    + //!< 3: Reserved
    + //!< 4: No whitener, 32-bit IEEE 802.15.4g compatible CRC
    + //!< 5: IEEE 802.15.4g compatible whitener and 32-bit CRC
    + //!< 6: No whitener, dynamically IEEE 802.15.4g compatible 16-bit or 32-bit CRC
    + //!< 7: Dynamically IEEE 802.15.4g compatible whitener and 16-bit or 32-bit CRC + } formatConf; + struct { + uint16_t frontEndMode:3; //!< \brief 0x00: Differential mode
    + //!< 0x01: Single-ended mode RFP
    + //!< 0x02: Single-ended mode RFN
    + //!< 0x05 Single-ended mode RFP with external frontend control on RF pins (RFN and RXTX)
    + //!< 0x06 Single-ended mode RFN with external frontend control on RF pins (RFP and RXTX)
    + //!< Others: Reserved + uint16_t biasMode:1; //!< \brief 0: Internal bias
    + //!< 1: External bias + uint16_t :6; + uint16_t bNoFsPowerUp:1; //!< \brief 0: Power up frequency synth
    + //!< 1: Do not power up frequency synth + } config; //!< Configuration options + uint16_t txPower; //!< Transmit power + uint32_t* pRegOverride; //!< \brief Pointer to a list of hardware and configuration registers to override. If NULL, no + //!< override is used. +}; + +//! @} + +//! \addtogroup CMD_PROP_RADIO_DIV_SETUP +//! @{ +#define CMD_PROP_RADIO_DIV_SETUP 0x3807 +struct __RFC_STRUCT rfc_CMD_PROP_RADIO_DIV_SETUP_s { + uint16_t commandNo; //!< The command ID number 0x3807 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
    + //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
    + //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint16_t modType:3; //!< \brief 0: FSK
    + //!< 1: GFSK
    + //!< Others: Reserved + uint16_t deviation:13; //!< Deviation (250 Hz steps) + } modulation; + struct { + uint32_t preScale:4; //!< Prescaler value + uint32_t :4; + uint32_t rateWord:21; //!< Rate word + } symbolRate; + uint8_t rxBw; //!< Receiver bandwidth + struct { + uint8_t nPreamBytes:6; //!< \brief 0–30: Number of preamble bytes
    + //!< 31: 4 preamble bits + uint8_t preamMode:2; //!< \brief 0: Send 0 as the first preamble bit
    + //!< 1: Send 1 as the first preamble bit
    + //!< 2: Send same first bit in preamble and sync word
    + //!< 3: Send different first bit in preamble and sync word + } preamConf; + struct { + uint16_t nSwBits:6; //!< Number of sync word bits (up to 32) + uint16_t bBitReversal:1; //!< \brief 0: Use positive deviation for 1
    + //!< 1: Use positive deviation for 0 + uint16_t bMsbFirst:1; //!< \brief 0: Least significant bit transmitted first
    + //!< 1: Most significant bit transmitted first + uint16_t fecMode:4; //!< \brief Select coding
    + //!< 0: Uncoded binary modulation
    + //!< 10: Manchester coded binary modulation
    + //!< Others: Reserved + uint16_t :1; + uint16_t whitenMode:3; //!< \brief 0: No whitening
    + //!< 1: CC1101/CC2500 compatible whitening
    + //!< 2: PN9 whitening without byte reversal
    + //!< 3: Reserved
    + //!< 4: No whitener, 32-bit IEEE 802.15.4g compatible CRC
    + //!< 5: IEEE 802.15.4g compatible whitener and 32-bit CRC
    + //!< 6: No whitener, dynamically IEEE 802.15.4g compatible 16-bit or 32-bit CRC
    + //!< 7: Dynamically IEEE 802.15.4g compatible whitener and 16-bit or 32-bit CRC + } formatConf; + struct { + uint16_t frontEndMode:3; //!< \brief 0x00: Differential mode
    + //!< 0x01: Single-ended mode RFP
    + //!< 0x02: Single-ended mode RFN
    + //!< 0x05 Single-ended mode RFP with external frontend control on RF pins (RFN and RXTX)
    + //!< 0x06 Single-ended mode RFN with external frontend control on RF pins (RFP and RXTX)
    + //!< Others: Reserved + uint16_t biasMode:1; //!< \brief 0: Internal bias
    + //!< 1: External bias + uint16_t :6; + uint16_t bNoFsPowerUp:1; //!< \brief 0: Power up frequency synth
    + //!< 1: Do not power up frequency synth + } config; //!< Configuration options + uint16_t txPower; //!< Transmit power + uint32_t* pRegOverride; //!< \brief Pointer to a list of hardware and configuration registers to override. If NULL, no + //!< override is used. + uint16_t centerFreq; //!< \brief Center frequency of the frequency band used, in MHz; used for calculating some internal Tx and Rx parameters. + //!< For a single channel RF system, this should be set equal to the RF frequency used. + //!< For a multi channel RF system (e.g. frequency hopping spread spectrum), this should be set equal + //!< to the center frequency of the frequency band used. + int16_t intFreq; //!< \brief Intermediate frequency to use for Rx, in MHz on 4.12 signed format. Tx will use same + //!< intermediate frequency if supported, otherwise 0.
    + //!< 0x8000: Use default. + uint8_t loDivider; //!< LO frequency divider setting to use. Supported values: 2, 5, 6, 10, 12, 15, and 30 +}; + +//! @} + +//! \addtogroup CMD_PROP_SET_LEN +//! @{ +#define CMD_PROP_SET_LEN 0x3401 +struct __RFC_STRUCT rfc_CMD_PROP_SET_LEN_s { + uint16_t commandNo; //!< The command ID number 0x3401 + uint16_t rxLen; //!< Payload length to use +}; + +//! @} + +//! \addtogroup CMD_PROP_RESTART_RX +//! @{ +#define CMD_PROP_RESTART_RX 0x3402 +struct __RFC_STRUCT rfc_CMD_PROP_RESTART_RX_s { + uint16_t commandNo; //!< The command ID number 0x3402 +}; + +//! @} + +//! \addtogroup propRxOutput +//! @{ +//! Output structure for Rx operations + +struct __RFC_STRUCT rfc_propRxOutput_s { + uint16_t nRxOk; //!< Number of packets that have been received with payload, CRC OK and not ignored + uint16_t nRxNok; //!< Number of packets that have been received with CRC error + uint8_t nRxIgnored; //!< Number of packets that have been received with CRC OK and ignored due to address mismatch + uint8_t nRxStopped; //!< Number of packets not received due to illegal length or address mismatch with pktConf.filterOp = 1 + uint8_t nRxBufFull; //!< Number of packets that have been received and discarded due to lack of buffer space + int8_t lastRssi; //!< RSSI of last received packet + ratmr_t timeStamp; //!< Time stamp of last received packet +}; + +//! @} + +//! \addtogroup propRxStatus +//! @{ +//! Receive status byte that may be appended to message in receive buffer + +struct __RFC_STRUCT rfc_propRxStatus_s { + struct { + uint8_t addressInd:5; //!< Index of address found (0 if not applicable) + uint8_t syncWordId:1; //!< 0 for primary sync word, 1 for alternate sync word + uint8_t result:2; //!< \brief 0: Packet received correctly, not ignored
    + //!< 1: Packet received with CRC error
    + //!< 2: Packet received correctly, but can be ignored
    + //!< 3: Packet reception was aborted + } status; +}; + +//! @} + +//! @} +//! @} +#endif /* PROP_CMD_H_ */ diff --git a/cpu/cc26xx-cc13xx/rf-core/api/prop_mailbox.h b/cpu/cc26xx-cc13xx/rf-core/api/prop_mailbox.h new file mode 100644 index 000000000..ff7b6c25b --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/api/prop_mailbox.h @@ -0,0 +1,71 @@ +/****************************************************************************** +* Filename: prop_mailbox.h +* Revised: 2015-06-29 12:59:58 +0200 (Mon, 29 Jun 2015) +* Revision: 44063 +* +* Description: Definitions for proprietary mode radio interface +* +* Copyright (c) 2015, Texas Instruments Incorporated +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1) Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2) 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. +* +* 3) Neither the name of the ORGANIZATION 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. +* +******************************************************************************/ + +#ifndef PROP_MAILBOX_H_ +#define PROP_MAILBOX_H_ + +/// \name Radio operation status +///@{ +/// \name Operation finished normally +///@{ +#define PROP_DONE_OK 0x3400 ///< Operation ended normally +#define PROP_DONE_RXTIMEOUT 0x3401 ///< Operation stopped after end trigger while waiting for sync +#define PROP_DONE_BREAK 0x3402 ///< Rx stopped due to time out in the middle of a packet +#define PROP_DONE_ENDED 0x3403 ///< Operation stopped after end trigger during reception +#define PROP_DONE_STOPPED 0x3404 ///< Operation stopped after stop command +#define PROP_DONE_ABORT 0x3405 ///< Operation aborted by abort command +#define PROP_DONE_RXERR 0x3406 ///< Operation ended after receiving packet with CRC error +#define PROP_DONE_IDLE 0x3407 ///< Carrier sense operation ended because of idle channel +#define PROP_DONE_BUSY 0x3408 ///< Carrier sense operation ended because of busy channel +#define PROP_DONE_IDLETIMEOUT 0x3409 ///< Carrier sense operation ended because of time out with csConf.timeoutRes = 1 +#define PROP_DONE_BUSYTIMEOUT 0x340A ///< Carrier sense operation ended because of time out with csConf.timeoutRes = 0 + +///@} +/// \name Operation finished with error +///@{ +#define PROP_ERROR_PAR 0x3800 ///< Illegal parameter +#define PROP_ERROR_RXBUF 0x3801 ///< No available Rx buffer at the start of a packet +#define PROP_ERROR_RXFULL 0x3802 ///< Out of Rx buffer during reception in a partial read buffer +#define PROP_ERROR_NO_SETUP 0x3803 ///< Radio was not set up in proprietary mode +#define PROP_ERROR_NO_FS 0x3804 ///< Synth was not programmed when running Rx or Tx +#define PROP_ERROR_RXOVF 0x3805 ///< Rx overflow observed during operation +#define PROP_ERROR_TXUNF 0x3806 ///< Tx underflow observed during operation +///@} +///@} + +#endif /* PROP_MAILBOX_H_ */ diff --git a/cpu/cc26xx-cc13xx/rf-core/dot-15-4g.h b/cpu/cc26xx-cc13xx/rf-core/dot-15-4g.h new file mode 100644 index 000000000..30dc63367 --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/dot-15-4g.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup rf-core + * @{ + * + * \defgroup rf-core-15-4g-modes IEEE 802.15.4g Frequency Bands and Modes + * + * @{ + * + * \file + * Header file with descriptors for the various modes of operation defined in + * IEEE 802.15.4g + */ +/*---------------------------------------------------------------------------*/ +#ifndef DOT_15_4G_H_ +#define DOT_15_4G_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +/*---------------------------------------------------------------------------*/ +/* IEEE 802.15.4g frequency band identifiers (Table 68f) */ +#define DOT_15_4G_FREQUENCY_BAND_169 0 /* 169.400–169.475 (Europe) - 169 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_450 1 /* 450–470 (US FCC Part 22/90) - 450 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_470 2 /* 470–510 (China) - 470 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_780 3 /* 779–787 (China) - 780 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_863 4 /* 863–870 (Europe) - 863 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_896 5 /* 896–901 (US FCC Part 90) - 896 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_901 6 /* 901–902 (US FCC Part 24) - 901 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_915 7 /* 902–928 (US) - 915 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_917 8 /* 917–923.5 (Korea) - 917 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_920 9 /* 920–928 (Japan) - 920 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_928 10 /* 928–960 (US, non-contiguous) - 928 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_950 11 /* 950–958 (Japan) - 950 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_1427 12 /* 1427–1518 (US and Canada, non-contiguous) - 1427 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_2450 13 /* 2400–2483.5 2450 MHz band */ +/*---------------------------------------------------------------------------*/ +/* Default band selection to band 4 - 863MHz */ +#ifdef DOT_15_4G_CONF_FREQUENCY_BAND_ID +#define DOT_15_4G_FREQUENCY_BAND_ID DOT_15_4G_CONF_FREQUENCY_BAND_ID +#else +#define DOT_15_4G_FREQUENCY_BAND_ID DOT_15_4G_FREQUENCY_BAND_863 +#endif +/*---------------------------------------------------------------------------*/ +/* + * Channel count, spacing and other params relating to the selected band. We + * currently only support some of the bands defined in .15.4g and for those + * bands we only support operating mode #1 (Table 134). + * + * DOT_15_4G_CHAN0_FREQUENCY is specified here in KHz + */ +#if DOT_15_4G_FREQUENCY_BAND_ID==DOT_15_4G_FREQUENCY_BAND_470 +#define DOT_15_4G_CHANNEL_MAX 198 +#define DOT_15_4G_CHANNEL_SPACING 200 +#define DOT_15_4G_CHAN0_FREQUENCY 470200 +#define PROP_MODE_CONF_LO_DIVIDER 0x0A + +#elif DOT_15_4G_FREQUENCY_BAND_ID==DOT_15_4G_FREQUENCY_BAND_780 +#define DOT_15_4G_CHANNEL_MAX 38 +#define DOT_15_4G_CHANNEL_SPACING 200 +#define DOT_15_4G_CHAN0_FREQUENCY 779200 +#define PROP_MODE_CONF_LO_DIVIDER 0x06 + +#elif DOT_15_4G_FREQUENCY_BAND_ID==DOT_15_4G_FREQUENCY_BAND_863 +#define DOT_15_4G_CHANNEL_MAX 33 +#define DOT_15_4G_CHANNEL_SPACING 200 +#define DOT_15_4G_CHAN0_FREQUENCY 863125 +#define PROP_MODE_CONF_LO_DIVIDER 0x05 + +#elif DOT_15_4G_FREQUENCY_BAND_ID==DOT_15_4G_FREQUENCY_BAND_915 +#define DOT_15_4G_CHANNEL_MAX 128 +#define DOT_15_4G_CHANNEL_SPACING 200 +#define DOT_15_4G_CHAN0_FREQUENCY 902200 +#define PROP_MODE_CONF_LO_DIVIDER 0x05 + +#elif DOT_15_4G_FREQUENCY_BAND_ID==DOT_15_4G_FREQUENCY_BAND_920 +#define DOT_15_4G_CHANNEL_MAX 37 +#define DOT_15_4G_CHANNEL_SPACING 200 +#define DOT_15_4G_CHAN0_FREQUENCY 920600 +#define PROP_MODE_CONF_LO_DIVIDER 0x05 + +#elif DOT_15_4G_FREQUENCY_BAND_ID==DOT_15_4G_FREQUENCY_BAND_950 +#define DOT_15_4G_CHANNEL_MAX 32 +#define DOT_15_4G_CHANNEL_SPACING 200 +#define DOT_15_4G_CHAN0_FREQUENCY 951000 +#define PROP_MODE_CONF_LO_DIVIDER 0x05 + +#else +#error The selected frequency band is not supported +#endif +/*---------------------------------------------------------------------------*/ +#endif /* DOT_15_4G_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c new file mode 100644 index 000000000..08843d699 --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c @@ -0,0 +1,1619 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup rf-core + * @{ + * + * \defgroup rf-core-ieee CC13xx/CC26xx IEEE mode driver + * + * @{ + * + * \file + * Implementation of the CC13xx/CC26xx IEEE mode NETSTACK_RADIO driver + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/radio.h" +#include "dev/cc26xx-uart.h" +#include "dev/oscillators.h" +#include "net/packetbuf.h" +#include "net/rime/rimestats.h" +#include "net/linkaddr.h" +#include "net/netstack.h" +#include "sys/energest.h" +#include "sys/clock.h" +#include "sys/rtimer.h" +#include "sys/ctimer.h" +#include "sys/cc.h" +#include "lpm.h" +#include "ti-lib.h" +#include "rf-core/rf-core.h" +#include "rf-core/rf-ble.h" +/*---------------------------------------------------------------------------*/ +/* RF core and RF HAL API */ +#include "hw_rfc_dbell.h" +#include "hw_rfc_pwr.h" +/*---------------------------------------------------------------------------*/ +/* RF Core Mailbox API */ +#include "rf-core/api/mailbox.h" +#include "rf-core/api/common_cmd.h" +#include "rf-core/api/ieee_cmd.h" +#include "rf-core/api/data_entry.h" +#include "rf-core/api/ieee_mailbox.h" +/*---------------------------------------------------------------------------*/ +#include "smartrf-settings.h" +/*---------------------------------------------------------------------------*/ +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/* Configuration to enable/disable auto ACKs in IEEE mode */ +#ifdef IEEE_MODE_CONF_AUTOACK +#define IEEE_MODE_AUTOACK IEEE_MODE_CONF_AUTOACK +#else +#define IEEE_MODE_AUTOACK 1 +#endif /* IEEE_MODE_CONF_AUTOACK */ + +/* Configuration to enable/disable frame filtering in IEEE mode */ +#ifdef IEEE_MODE_CONF_PROMISCOUS +#define IEEE_MODE_PROMISCOUS IEEE_MODE_CONF_PROMISCOUS +#else +#define IEEE_MODE_PROMISCOUS 0 +#endif /* IEEE_MODE_CONF_PROMISCOUS */ + +#ifdef IEEE_MODE_CONF_RSSI_THRESHOLD +#define IEEE_MODE_RSSI_THRESHOLD IEEE_MODE_CONF_RSSI_THRESHOLD +#else +#define IEEE_MODE_RSSI_THRESHOLD 0xA6 +#endif /* IEEE_MODE_CONF_RSSI_THRESHOLD */ +/*---------------------------------------------------------------------------*/ +#define STATUS_CRC_OK 0x80 +#define STATUS_CORRELATION 0x7f +/*---------------------------------------------------------------------------*/ +/* Data entry status field constants */ +#define DATA_ENTRY_STATUS_PENDING 0x00 /* Not in use by the Radio CPU */ +#define DATA_ENTRY_STATUS_ACTIVE 0x01 /* Open for r/w by the radio CPU */ +#define DATA_ENTRY_STATUS_BUSY 0x02 /* Ongoing r/w */ +#define DATA_ENTRY_STATUS_FINISHED 0x03 /* Free to use and to free */ +#define DATA_ENTRY_STATUS_UNFINISHED 0x04 /* Partial RX entry */ +/*---------------------------------------------------------------------------*/ +/* RF stats data structure */ +static uint8_t rf_stats[16] = { 0 }; +/*---------------------------------------------------------------------------*/ +/* The size of the RF commands buffer */ +#define RF_CMD_BUFFER_SIZE 128 +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns the current status of a running Radio Op command + * \param a A pointer with the buffer used to initiate the command + * \return The value of the Radio Op buffer's status field + * + * This macro can be used to e.g. return the status of a previously + * initiated background operation, or of an immediate command + */ +#define RF_RADIO_OP_GET_STATUS(a) (((rfc_radioOp_t *)a)->status) +/*---------------------------------------------------------------------------*/ +/* Special value returned by CMD_IEEE_CCA_REQ when an RSSI is not available */ +#define RF_CMD_CCA_REQ_RSSI_UNKNOWN -128 + +/* Used for the return value of channel_clear */ +#define RF_CCA_CLEAR 1 +#define RF_CCA_BUSY 0 + +/* Used as an error return value for get_cca_info */ +#define RF_GET_CCA_INFO_ERROR 0xFF + +/* + * Values of the individual bits of the ccaInfo field in CMD_IEEE_CCA_REQ's + * status struct + */ +#define RF_CMD_CCA_REQ_CCA_STATE_IDLE 0 /* 00 */ +#define RF_CMD_CCA_REQ_CCA_STATE_BUSY 1 /* 01 */ +#define RF_CMD_CCA_REQ_CCA_STATE_INVALID 2 /* 10 */ + +#define RF_CMD_CCA_REQ_CCA_CORR_IDLE (0 << 4) +#define RF_CMD_CCA_REQ_CCA_CORR_BUSY (1 << 4) +#define RF_CMD_CCA_REQ_CCA_CORR_INVALID (3 << 4) +#define RF_CMD_CCA_REQ_CCA_CORR_MASK (3 << 4) + +#define RF_CMD_CCA_REQ_CCA_SYNC_BUSY (1 << 6) +/*---------------------------------------------------------------------------*/ +#define IEEE_MODE_CHANNEL_MIN 11 +#define IEEE_MODE_CHANNEL_MAX 26 +/*---------------------------------------------------------------------------*/ +/* How long to wait for an ongoing ACK TX to finish before starting frame TX */ +#define TX_WAIT_TIMEOUT (RTIMER_SECOND >> 11) + +/* How long to wait for the RF to enter RX in rf_cmd_ieee_rx */ +#define ENTER_RX_WAIT_TIMEOUT (RTIMER_SECOND >> 10) +/*---------------------------------------------------------------------------*/ +/* TX Power dBm lookup table - values from SmartRF Studio */ +typedef struct output_config { + radio_value_t dbm; + uint8_t register_ib; + uint8_t register_gc; + uint8_t temp_coeff; +} output_config_t; + +static const output_config_t output_power[] = { + { 5, 0x30, 0x00, 0x93 }, + { 4, 0x24, 0x00, 0x93 }, + { 3, 0x1c, 0x00, 0x5a }, + { 2, 0x18, 0x00, 0x4e }, + { 1, 0x14, 0x00, 0x42 }, + { 0, 0x21, 0x01, 0x31 }, + { -3, 0x18, 0x01, 0x25 }, + { -6, 0x11, 0x01, 0x1d }, + { -9, 0x0e, 0x01, 0x19 }, + {-12, 0x0b, 0x01, 0x14 }, + {-15, 0x0b, 0x03, 0x0c }, + {-18, 0x09, 0x03, 0x0c }, + {-21, 0x07, 0x03, 0x0c }, +}; + +#define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t)) + +/* Max and Min Output Power in dBm */ +#define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].dbm) +#define OUTPUT_POWER_MAX (output_power[0].dbm) +#define OUTPUT_POWER_UNKNOWN 0xFFFF + +/* Default TX Power - position in output_power[] */ +const output_config_t *tx_power_current = &output_power[0]; +/*---------------------------------------------------------------------------*/ +static volatile int8_t last_rssi = 0; +static volatile uint8_t last_corr_lqi = 0; + +extern int32_t rat_offset; + +/*---------------------------------------------------------------------------*/ +/* SFD timestamp in RTIMER ticks */ +static volatile uint32_t last_packet_timestamp = 0; +/* SFD timestamp in RAT ticks (but 64 bits) */ +static uint64_t last_rat_timestamp64 = 0; + +/* For RAT overflow handling */ +static struct ctimer rat_overflow_timer; +static uint32_t rat_overflow_counter = 0; +static rtimer_clock_t last_rat_overflow = 0; + +/* RAT has 32-bit register, overflows once 18 minutes */ +#define RAT_RANGE 4294967296ull +/* approximate value */ +#define RAT_OVERFLOW_PERIOD_SECONDS (60 * 18) + +/* XXX: don't know what exactly is this, looks like the time to Tx 3 octets */ +#define TIMESTAMP_OFFSET -(USEC_TO_RADIO(32 * 3) - 1) /* -95.75 usec */ +/*---------------------------------------------------------------------------*/ +/* Are we currently in poll mode? */ +static uint8_t poll_mode = 0; + +static rfc_CMD_IEEE_MOD_FILT_t filter_cmd; +/*---------------------------------------------------------------------------*/ +/* + * Buffers used to send commands to the RF core (generic and IEEE commands). + * Some of those buffers are re-usable, some are not. + * + * If you are uncertain, declare a new buffer. + */ +/* + * A buffer to send a CMD_IEEE_RX and to subsequently monitor its status + * Do not use this buffer for any commands other than CMD_IEEE_RX + */ +static uint8_t cmd_ieee_rx_buf[RF_CMD_BUFFER_SIZE] CC_ALIGN(4); +/*---------------------------------------------------------------------------*/ +#define DATA_ENTRY_LENSZ_NONE 0 +#define DATA_ENTRY_LENSZ_BYTE 1 +#define DATA_ENTRY_LENSZ_WORD 2 /* 2 bytes */ + +#define RX_BUF_SIZE 144 +/* Four receive buffers entries with room for 1 IEEE802.15.4 frame in each */ +static uint8_t rx_buf_0[RX_BUF_SIZE] CC_ALIGN(4); +static uint8_t rx_buf_1[RX_BUF_SIZE] CC_ALIGN(4); +static uint8_t rx_buf_2[RX_BUF_SIZE] CC_ALIGN(4); +static uint8_t rx_buf_3[RX_BUF_SIZE] CC_ALIGN(4); + +/* The RX Data Queue */ +static dataQueue_t rx_data_queue = { 0 }; + +/* Receive entry pointer to keep track of read items */ +volatile static uint8_t *rx_read_entry; +/*---------------------------------------------------------------------------*/ +/* The outgoing frame buffer */ +#define TX_BUF_PAYLOAD_LEN 180 +#define TX_BUF_HDR_LEN 2 + +static uint8_t tx_buf[TX_BUF_HDR_LEN + TX_BUF_PAYLOAD_LEN] CC_ALIGN(4); +/*---------------------------------------------------------------------------*/ +/* Overrides for IEEE 802.15.4, differential mode */ +static uint32_t ieee_overrides[] = { + 0x00354038, /* Synth: Set RTRIM (POTAILRESTRIM) to 5 */ + 0x4001402D, /* Synth: Correct CKVD latency setting (address) */ + 0x00608402, /* Synth: Correct CKVD latency setting (value) */ +// 0x4001405D, /* Synth: Set ANADIV DIV_BIAS_MODE to PG1 (address) */ +// 0x1801F800, /* Synth: Set ANADIV DIV_BIAS_MODE to PG1 (value) */ + 0x000784A3, /* Synth: Set FREF = 3.43 MHz (24 MHz / 7) */ + 0xA47E0583, /* Synth: Set loop bandwidth after lock to 80 kHz (K2) */ + 0xEAE00603, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, LSB) */ + 0x00010623, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, MSB) */ + 0x002B50DC, /* Adjust AGC DC filter */ + 0x05000243, /* Increase synth programming timeout */ + 0x002082C3, /* Increase synth programming timeout */ + 0xFFFFFFFF, /* End of override list */ +}; +/*---------------------------------------------------------------------------*/ +static int on(void); +static int off(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Checks whether the RFC domain is accessible and the RFC is in IEEE RX + * \return 1: RFC in RX mode (and therefore accessible too). 0 otherwise + */ +static uint8_t +rf_is_on(void) +{ + if(!rf_core_is_accessible()) { + return 0; + } + + return RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) == RF_CORE_RADIO_OP_STATUS_ACTIVE; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Check the RF's TX status + * \return 1 RF is transmitting + * \return 0 RF is not transmitting + * + * TX mode may be triggered either by a CMD_IEEE_TX or by the automatic + * transmission of an ACK frame. + */ +static uint8_t +transmitting(void) +{ + uint32_t cmd_status; + rfc_CMD_IEEE_CCA_REQ_t cmd; + + /* If we are off, we are not in TX */ + if(!rf_core_is_accessible()) { + return 0; + } + + memset(&cmd, 0x00, sizeof(cmd)); + + cmd.commandNo = CMD_IEEE_CCA_REQ; + + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_ERROR) { + PRINTF("transmitting: CMDSTA=0x%08lx\n", cmd_status); + return 0; + } + + if((cmd.currentRssi == RF_CMD_CCA_REQ_RSSI_UNKNOWN) && + (cmd.ccaInfo.ccaEnergy == RF_CMD_CCA_REQ_CCA_STATE_BUSY)) { + return 1; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns CCA information + * \return RF_GET_CCA_INFO_ERROR if the RF was not on + * \return On success, the return value is formatted as per the ccaInfo field + * of CMD_IEEE_CCA_REQ + * + * It is the caller's responsibility to make sure the RF is on. This function + * will return RF_GET_CCA_INFO_ERROR if the RF is off + * + * This function will in fact wait for a valid RSSI signal + */ +static uint8_t +get_cca_info(void) +{ + uint32_t cmd_status; + int8_t rssi; + rfc_CMD_IEEE_CCA_REQ_t cmd; + + if(!rf_is_on()) { + PRINTF("get_cca_info: Not on\n"); + return RF_GET_CCA_INFO_ERROR; + } + + rssi = RF_CMD_CCA_REQ_RSSI_UNKNOWN; + + while(rssi == RF_CMD_CCA_REQ_RSSI_UNKNOWN || rssi == 0) { + memset(&cmd, 0x00, sizeof(cmd)); + cmd.commandNo = CMD_IEEE_CCA_REQ; + + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_ERROR) { + PRINTF("get_cca_info: CMDSTA=0x%08lx\n", cmd_status); + + return RF_GET_CCA_INFO_ERROR; + } + + rssi = cmd.currentRssi; + } + + /* We have a valid RSSI signal. Return the CCA Info */ + return *((uint8_t *)&cmd.ccaInfo); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Reads the current signal strength (RSSI) + * \return The current RSSI in dBm or CMD_GET_RSSI_UNKNOWN + * + * This function reads the current RSSI on the currently configured + * channel. + */ +static radio_value_t +get_rssi(void) +{ + uint32_t cmd_status; + int8_t rssi; + uint8_t was_off = 0; + rfc_CMD_GET_RSSI_t cmd; + + /* If we are off, turn on first */ + if(!rf_is_on()) { + was_off = 1; + if(on() != RF_CORE_CMD_OK) { + PRINTF("get_rssi: on() failed\n"); + return RF_CMD_CCA_REQ_RSSI_UNKNOWN; + } + } + + memset(&cmd, 0x00, sizeof(cmd)); + cmd.commandNo = CMD_GET_RSSI; + + rssi = RF_CMD_CCA_REQ_RSSI_UNKNOWN; + + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_OK) { + /* Current RSSI in bits 23:16 of cmd_status */ + rssi = (cmd_status >> 16) & 0xFF; + } + + /* If we were off, turn back off */ + if(was_off) { + off(); + } + + return rssi; +} +/*---------------------------------------------------------------------------*/ +/* Returns the current TX power in dBm */ +static radio_value_t +get_tx_power(void) +{ + return tx_power_current->dbm; +} +/*---------------------------------------------------------------------------*/ +/* + * Set TX power to 'at least' power dBm + * This works with a lookup table. If the value of 'power' does not exist in + * the lookup table, TXPOWER will be set to the immediately higher available + * value + */ +static void +set_tx_power(radio_value_t power) +{ + uint32_t cmd_status; + int i; + rfc_CMD_SET_TX_POWER_t cmd; + + /* First, find the correct setting and save it */ + for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) { + if(power <= output_power[i].dbm) { + tx_power_current = &output_power[i]; + break; + } + } + + /* + * If the core is not accessible, the new setting will be applied next + * time we send CMD_RADIO_SETUP, so we don't need to do anything further. + * If the core is accessible, we can apply the new setting immediately with + * CMD_SET_TX_POWER + */ + if(rf_core_is_accessible() == RF_CORE_NOT_ACCESSIBLE) { + return; + } + + memset(&cmd, 0x00, sizeof(cmd)); + cmd.commandNo = CMD_SET_TX_POWER; + cmd.txPower.IB = output_power[i].register_ib; + cmd.txPower.GC = output_power[i].register_gc; + cmd.txPower.tempCoeff = output_power[i].temp_coeff; + + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_ERROR) { + PRINTF("set_tx_power: CMDSTA=0x%08lx\n", cmd_status); + } +} +/*---------------------------------------------------------------------------*/ +static uint8_t +rf_radio_setup() +{ + uint32_t cmd_status; + rfc_CMD_RADIO_SETUP_t cmd; + + /* Create radio setup command */ + rf_core_init_radio_op((rfc_radioOp_t *)&cmd, sizeof(cmd), CMD_RADIO_SETUP); + + cmd.txPower.IB = tx_power_current->register_ib; + cmd.txPower.GC = tx_power_current->register_gc; + cmd.txPower.tempCoeff = tx_power_current->temp_coeff; + cmd.pRegOverride = ieee_overrides; + cmd.mode = 1; + + /* Send Radio setup to RF Core */ + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("rf_radio_setup: CMD_RADIO_SETUP, CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd.status); + return RF_CORE_CMD_ERROR; + } + + /* Wait until radio setup is done */ + if(rf_core_wait_cmd_done(&cmd) != RF_CORE_CMD_OK) { + PRINTF("rf_radio_setup: CMD_RADIO_SETUP wait, CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd.status); + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Set up radio in IEEE802.15.4 RX mode + * + * \return RF_CORE_CMD_OK Succeeded + * \return RF_CORE_CMD_ERROR Failed + * + * This function assumes that cmd_ieee_rx_buf has been previously populated + * with correct values. This can be done through init_rf_params (sets defaults) + * or through Contiki's extended RF API (set_value, set_object) + */ +static uint8_t +rf_cmd_ieee_rx() +{ + uint32_t cmd_status; + rtimer_clock_t t0; + int ret; + + ret = rf_core_send_cmd((uint32_t)cmd_ieee_rx_buf, &cmd_status); + + if(ret != RF_CORE_CMD_OK) { + PRINTF("rf_cmd_ieee_rx: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", + ret, cmd_status, RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf)); + return RF_CORE_CMD_ERROR; + } + + t0 = RTIMER_NOW(); + + while(RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) != RF_CORE_RADIO_OP_STATUS_ACTIVE && + (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ENTER_RX_WAIT_TIMEOUT))); + + /* Wait to enter RX */ + if(RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) != RF_CORE_RADIO_OP_STATUS_ACTIVE) { + PRINTF("rf_cmd_ieee_rx: CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf)); + return RF_CORE_CMD_ERROR; + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static void +init_rx_buffers(void) +{ + rfc_dataEntry_t *entry; + + entry = (rfc_dataEntry_t *)rx_buf_0; + entry->pNextEntry = rx_buf_1; + entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE; + entry->length = sizeof(rx_buf_0) - 8; + + entry = (rfc_dataEntry_t *)rx_buf_1; + entry->pNextEntry = rx_buf_2; + entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE; + entry->length = sizeof(rx_buf_0) - 8; + + entry = (rfc_dataEntry_t *)rx_buf_2; + entry->pNextEntry = rx_buf_3; + entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE; + entry->length = sizeof(rx_buf_0) - 8; + + entry = (rfc_dataEntry_t *)rx_buf_3; + entry->pNextEntry = rx_buf_0; + entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE; + entry->length = sizeof(rx_buf_0) - 8; +} +/*---------------------------------------------------------------------------*/ +static void +init_rf_params(void) +{ + rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf; + + memset(cmd_ieee_rx_buf, 0x00, RF_CMD_BUFFER_SIZE); + + cmd->commandNo = CMD_IEEE_RX; + cmd->status = RF_CORE_RADIO_OP_STATUS_IDLE; + cmd->pNextOp = NULL; + cmd->startTime = 0x00000000; + cmd->startTrigger.triggerType = TRIG_NOW; + cmd->condition.rule = COND_NEVER; + cmd->channel = RF_CORE_CHANNEL; + + cmd->rxConfig.bAutoFlushCrc = 1; + cmd->rxConfig.bAutoFlushIgn = 0; + cmd->rxConfig.bIncludePhyHdr = 0; + cmd->rxConfig.bIncludeCrc = 1; + cmd->rxConfig.bAppendRssi = 1; + cmd->rxConfig.bAppendCorrCrc = 1; + cmd->rxConfig.bAppendSrcInd = 0; + cmd->rxConfig.bAppendTimestamp = 1; + + cmd->pRxQ = &rx_data_queue; + cmd->pOutput = (rfc_ieeeRxOutput_t *)rf_stats; + +#if IEEE_MODE_PROMISCOUS + cmd->frameFiltOpt.frameFiltEn = 0; +#else + cmd->frameFiltOpt.frameFiltEn = 1; +#endif + + cmd->frameFiltOpt.frameFiltStop = 1; + +#if IEEE_MODE_AUTOACK + cmd->frameFiltOpt.autoAckEn = 1; +#else + cmd->frameFiltOpt.autoAckEn = 0; +#endif + + cmd->frameFiltOpt.slottedAckEn = 0; + cmd->frameFiltOpt.autoPendEn = 0; + cmd->frameFiltOpt.defaultPend = 0; + cmd->frameFiltOpt.bPendDataReqOnly = 0; + cmd->frameFiltOpt.bPanCoord = 0; + cmd->frameFiltOpt.maxFrameVersion = 2; + cmd->frameFiltOpt.bStrictLenFilter = 0; + + /* Receive all frame types */ + cmd->frameTypes.bAcceptFt0Beacon = 1; + cmd->frameTypes.bAcceptFt1Data = 1; + cmd->frameTypes.bAcceptFt2Ack = 1; + cmd->frameTypes.bAcceptFt3MacCmd = 1; + cmd->frameTypes.bAcceptFt4Reserved = 1; + cmd->frameTypes.bAcceptFt5Reserved = 1; + cmd->frameTypes.bAcceptFt6Reserved = 1; + cmd->frameTypes.bAcceptFt7Reserved = 1; + + /* Configure CCA settings */ + cmd->ccaOpt.ccaEnEnergy = 1; + cmd->ccaOpt.ccaEnCorr = 1; + cmd->ccaOpt.ccaEnSync = 1; + cmd->ccaOpt.ccaCorrOp = 1; + cmd->ccaOpt.ccaSyncOp = 0; + cmd->ccaOpt.ccaCorrThr = 3; + + cmd->ccaRssiThr = IEEE_MODE_RSSI_THRESHOLD; + + cmd->numExtEntries = 0x00; + cmd->numShortEntries = 0x00; + cmd->pExtEntryList = 0; + cmd->pShortEntryList = 0; + + cmd->endTrigger.triggerType = TRIG_NEVER; + cmd->endTime = 0x00000000; + + /* set address filter command */ + filter_cmd.commandNo = CMD_IEEE_MOD_FILT; + memcpy(&filter_cmd.newFrameFiltOpt, &cmd->frameFiltOpt, sizeof(cmd->frameFiltOpt)); + memcpy(&filter_cmd.newFrameTypes, &cmd->frameTypes, sizeof(cmd->frameTypes)); +} +/*---------------------------------------------------------------------------*/ +static int +rx_on(void) +{ + int ret; + + /* Get status of running IEEE_RX (if any) */ + if(rf_is_on()) { + PRINTF("rx_on: We were on. PD=%u, RX=0x%04x \n", rf_core_is_accessible(), + RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf)); + return RF_CORE_CMD_OK; + } + + /* Put CPE in RX using the currently configured parameters */ + ret = rf_cmd_ieee_rx(); + + if(ret) { + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +rx_off(void) +{ + uint32_t cmd_status; + int ret; + + /* If we are off, do nothing */ + if(!rf_is_on()) { + return RF_CORE_CMD_OK; + } + + /* Wait for ongoing ACK TX to finish */ + while(transmitting()); + + /* Send a CMD_ABORT command to RF Core */ + if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("RX off: CMD_ABORT status=0x%08lx\n", cmd_status); + /* Continue nonetheless */ + } + + while(rf_is_on()); + + if(RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) == IEEE_DONE_STOPPED || + RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) == IEEE_DONE_ABORT) { + /* Stopped gracefully */ + ret = RF_CORE_CMD_OK; + } else { + PRINTF("RX off: BG status=0x%04x\n", RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf)); + ret = RF_CORE_CMD_ERROR; + } + + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + + return ret; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +request(void) +{ + /* + * We rely on the RDC layer to turn us on and off. Thus, if we are on we + * will only allow sleep, standby otherwise + */ + if(rf_is_on()) { + return LPM_MODE_SLEEP; + } + + return LPM_MODE_MAX_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +LPM_MODULE(cc26xx_rf_lpm_module, request, NULL, NULL, LPM_DOMAIN_NONE); +/*---------------------------------------------------------------------------*/ +static void +soft_off(void) +{ + uint32_t cmd_status; + volatile rfc_radioOp_t *cmd = rf_core_get_last_radio_op(); + + if(!rf_core_is_accessible()) { + return; + } + + PRINTF("soft_off: Aborting 0x%04x, Status=0x%04x\n", cmd->commandNo, + cmd->status); + + /* Send a CMD_ABORT command to RF Core */ + if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("soft_off: CMD_ABORT status=0x%08lx\n", cmd_status); + return; + } + + while((cmd->status & RF_CORE_RADIO_OP_MASKED_STATUS) == + RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING); +} +/*---------------------------------------------------------------------------*/ +static uint8_t +soft_on(void) +{ + if(rf_radio_setup() != RF_CORE_CMD_OK) { + PRINTF("on: radio_setup() failed\n"); + return RF_CORE_CMD_ERROR; + } + + return rx_on(); +} +/*---------------------------------------------------------------------------*/ +static const rf_core_primary_mode_t mode_ieee = { + soft_off, + soft_on, +}; +/*---------------------------------------------------------------------------*/ +static void +check_rat_overflow(bool first_time) +{ + static uint32_t last_value; + uint32_t current_value; + uint8_t interrupts_enabled; + + interrupts_enabled = ti_lib_int_master_disable(); + if(first_time) { + last_value = HWREG(RFC_RAT_BASE + RATCNT); + } else { + current_value = HWREG(RFC_RAT_BASE + RATCNT); + if(current_value + RAT_RANGE / 4 < last_value) { + /* overflow detected */ + last_rat_overflow = RTIMER_NOW(); + rat_overflow_counter++; + } + last_value = current_value; + } + if(interrupts_enabled) { + ti_lib_int_master_enable(); + } +} +/*---------------------------------------------------------------------------*/ +static void +handle_rat_overflow(void *unused) +{ + uint8_t was_off = 0; + + if(!rf_is_on()) { + was_off = 1; + if(on() != RF_CORE_CMD_OK) { + PRINTF("overflow: on() failed\n"); + ctimer_set(&rat_overflow_timer, RAT_OVERFLOW_PERIOD_SECONDS * CLOCK_SECOND / 2, + handle_rat_overflow, NULL); + return; + } + } + + check_rat_overflow(false); + + if(was_off) { + off(); + } + + ctimer_set(&rat_overflow_timer, RAT_OVERFLOW_PERIOD_SECONDS * CLOCK_SECOND / 2, + handle_rat_overflow, NULL); +} +/*---------------------------------------------------------------------------*/ +static int +init(void) +{ + lpm_register_module(&cc26xx_rf_lpm_module); + + rf_core_set_modesel(); + + /* Initialise RX buffers */ + memset(rx_buf_0, 0, RX_BUF_SIZE); + memset(rx_buf_1, 0, RX_BUF_SIZE); + memset(rx_buf_2, 0, RX_BUF_SIZE); + memset(rx_buf_3, 0, RX_BUF_SIZE); + + /* Set of RF Core data queue. Circular buffer, no last entry */ + rx_data_queue.pCurrEntry = rx_buf_0; + + rx_data_queue.pLastEntry = NULL; + + /* Initialize current read pointer to first element (used in ISR) */ + rx_read_entry = rx_buf_0; + + /* Populate the RF parameters data structure with default values */ + init_rf_params(); + + if(on() != RF_CORE_CMD_OK) { + PRINTF("init: on() failed\n"); + return RF_CORE_CMD_ERROR; + } + + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + + rf_core_primary_mode_register(&mode_ieee); + + check_rat_overflow(true); + ctimer_set(&rat_overflow_timer, RAT_OVERFLOW_PERIOD_SECONDS * CLOCK_SECOND / 2, + handle_rat_overflow, NULL); + + process_start(&rf_core_process, NULL); + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +prepare(const void *payload, unsigned short payload_len) +{ + int len = MIN(payload_len, TX_BUF_PAYLOAD_LEN); + + memcpy(&tx_buf[TX_BUF_HDR_LEN], payload, len); + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +transmit(unsigned short transmit_len) +{ + int ret; + uint8_t was_off = 0; + uint32_t cmd_status; + uint16_t stat; + uint8_t tx_active = 0; + rtimer_clock_t t0; + volatile rfc_CMD_IEEE_TX_t cmd; + uint8_t interrupts_enabled; + + if(!rf_is_on()) { + was_off = 1; + if(on() != RF_CORE_CMD_OK) { + PRINTF("transmit: on() failed\n"); + return RADIO_TX_ERR; + } + } + + /* + * We are certainly not TXing a frame as a result of CMD_IEEE_TX, but we may + * be in the process of TXing an ACK. In that case, wait for the TX to finish + * or return after approx TX_WAIT_TIMEOUT + */ + t0 = RTIMER_NOW(); + + do { + tx_active = transmitting(); + } while(tx_active == 1 && + (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + TX_WAIT_TIMEOUT))); + + if(tx_active) { + PRINTF("transmit: Already TXing and wait timed out\n"); + + if(was_off) { + off(); + } + + return RADIO_TX_COLLISION; + } + + /* Send the CMD_IEEE_TX command */ + rf_core_init_radio_op((rfc_radioOp_t *)&cmd, sizeof(cmd), CMD_IEEE_TX); + + cmd.payloadLen = transmit_len; + cmd.pPayload = &tx_buf[TX_BUF_HDR_LEN]; + + cmd.startTime = 0; + cmd.startTrigger.triggerType = TRIG_NOW; + + /* XXX: there seems to be no function that gets interrupt state w/o changing it */ + interrupts_enabled = ti_lib_int_master_disable(); + if(interrupts_enabled) { + ti_lib_int_master_enable(); + } + + /* Enable the LAST_FG_COMMAND_DONE interrupt, which will wake us up */ + if(interrupts_enabled) { + rf_core_cmd_done_en(true, poll_mode); + } + + ret = rf_core_send_cmd((uint32_t)&cmd, &cmd_status); + + if(ret) { + /* If we enter here, TX actually started */ + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); + + /* Idle away while the command is running */ + while((cmd.status & RF_CORE_RADIO_OP_MASKED_STATUS) + == RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING) { + /* Note: for now sleeping while Tx'ing in polling mode is disabled. + * To enable it: + * 1) make the `lpm_sleep()` call here unconditional; + * 2) change the radio ISR priority to allow radio ISR to interrupt rtimer ISR. + */ + if(interrupts_enabled) { + lpm_sleep(); + } + } + + stat = cmd.status; + + if(stat == RF_CORE_RADIO_OP_STATUS_IEEE_DONE_OK) { + /* Sent OK */ + RIMESTATS_ADD(lltx); + ret = RADIO_TX_OK; + } else { + /* Operation completed, but frame was not sent */ + PRINTF("transmit: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", ret, + cmd_status, stat); + ret = RADIO_TX_ERR; + } + } else { + /* Failure sending the CMD_IEEE_TX command */ + PRINTF("transmit: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", + ret, cmd_status, cmd.status); + + ret = RADIO_TX_ERR; + } + + /* + * Update ENERGEST state here, before a potential call to off(), which + * will correctly update it if required. + */ + ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + + if(interrupts_enabled) { + /* + * Disable LAST_FG_COMMAND_DONE interrupt. We don't really care about it + * except when we are transmitting + */ + rf_core_cmd_done_dis(poll_mode); + } + + if(was_off) { + off(); + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +send(const void *payload, unsigned short payload_len) +{ + prepare(payload, payload_len); + return transmit(payload_len); +} +/*---------------------------------------------------------------------------*/ +static void +release_data_entry(void) +{ + rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry; + + /* Clear the length byte */ + rx_read_entry[8] = 0; + + /* Set status to 0 "Pending" in element */ + entry->status = DATA_ENTRY_STATUS_PENDING; + rx_read_entry = entry->pNextEntry; +} +/*---------------------------------------------------------------------------*/ +static uint32_t +calc_last_packet_timestamp(uint32_t rat_timestamp) +{ + uint64_t rat_timestamp64; + uint32_t adjusted_overflow_counter = rat_overflow_counter; + + /* if the timestamp is large and the last oveflow was recently, + assume that the timestamp refers to the time before the overflow */ + if(rat_timestamp > (uint32_t)(RAT_RANGE * 3 / 4)) { + if(RTIMER_CLOCK_LT(RTIMER_NOW(), + last_rat_overflow + RAT_OVERFLOW_PERIOD_SECONDS * RTIMER_SECOND / 4)) { + adjusted_overflow_counter--; + } + } + + /* add the overflowed time to the timestamp */ + rat_timestamp64 = rat_timestamp + RAT_RANGE * adjusted_overflow_counter; + /* correct timestamp so that it refers to the end of the SFD */ + rat_timestamp64 += TIMESTAMP_OFFSET; + + last_rat_timestamp64 = rat_timestamp64 - rat_offset; + + return RADIO_TO_RTIMER(rat_timestamp64 - rat_offset); +} +/*---------------------------------------------------------------------------*/ +static int +read_frame(void *buf, unsigned short buf_len) +{ + int len = 0; + rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry; + uint32_t rat_timestamp; + + if(rf_is_on()) { + check_rat_overflow(false); + } + + /* wait for entry to become finished */ + rtimer_clock_t t0 = RTIMER_NOW(); + while(entry->status == DATA_ENTRY_STATUS_BUSY + && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (RTIMER_SECOND / 250))); + + if(entry->status != DATA_ENTRY_STATUS_FINISHED) { + /* No available data */ + return 0; + } + + if(rx_read_entry[8] < 4) { + PRINTF("RF: too short\n"); + RIMESTATS_ADD(tooshort); + + release_data_entry(); + return 0; + } + + len = rx_read_entry[8] - 8; + + if(len > buf_len) { + PRINTF("RF: too long\n"); + RIMESTATS_ADD(toolong); + + release_data_entry(); + return 0; + } + + memcpy(buf, (char *)&rx_read_entry[9], len); + + last_rssi = (int8_t)rx_read_entry[9 + len + 2]; + last_corr_lqi = (uint8_t)rx_read_entry[9 + len + 2] & STATUS_CORRELATION; + + /* get the timestamp */ + memcpy(&rat_timestamp, (char *)rx_read_entry + 9 + len + 4, 4); + + last_packet_timestamp = calc_last_packet_timestamp(rat_timestamp); + + if(!poll_mode) { + /* Not in poll mode: packetbuf should not be accessed in interrupt context. + * In poll mode, the last packet RSSI and link quality can be obtained through + * RADIO_PARAM_LAST_RSSI and RADIO_PARAM_LAST_LINK_QUALITY */ + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, last_rssi); + packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, last_corr_lqi); + } + RIMESTATS_ADD(llrx); + + release_data_entry(); + + return len; +} +/*---------------------------------------------------------------------------*/ +static int +channel_clear(void) +{ + uint8_t was_off = 0; + uint8_t cca_info; + int ret = RF_CCA_CLEAR; + + /* + * If we are in the middle of a BLE operation, we got called by ContikiMAC + * from within an interrupt context. Indicate a clear channel + */ + if(rf_ble_is_active() == RF_BLE_ACTIVE) { + PRINTF("channel_clear: Interrupt context but BLE in progress\n"); + return RF_CCA_CLEAR; + } + + if(rf_is_on()) { + /* + * Wait for potential leftover ACK still being sent. + * Strictly speaking, if we are TXing an ACK then the channel is not clear. + * However, channel_clear is only ever called to determine whether there is + * someone else's packet in the air, not ours. + * + * We could probably even simply return that the channel is clear + */ + while(transmitting()); + } else { + was_off = 1; + if(on() != RF_CORE_CMD_OK) { + PRINTF("channel_clear: on() failed\n"); + if(was_off) { + off(); + } + return RF_CCA_CLEAR; + } + } + + cca_info = get_cca_info(); + + if(cca_info == RF_GET_CCA_INFO_ERROR) { + PRINTF("channel_clear: CCA error\n"); + ret = RF_CCA_CLEAR; + } else { + /* + * cca_info bits 1:0 - ccaStatus + * Return 1 (clear) if idle or invalid. + */ + ret = (cca_info & 0x03) != RF_CMD_CCA_REQ_CCA_STATE_BUSY; + } + + if(was_off) { + off(); + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +receiving_packet(void) +{ + uint8_t cca_info; + + /* + * If we are in the middle of a BLE operation, we got called by ContikiMAC + * from within an interrupt context. We are not receiving + */ + if(rf_ble_is_active() == RF_BLE_ACTIVE) { + PRINTF("receiving_packet: Interrupt context but BLE in progress\n"); + return 0; + } + + /* If we are off, we are not receiving */ + if(!rf_is_on()) { + PRINTF("receiving_packet: We were off\n"); + return 0; + } + + /* If we are transmitting (can only be an ACK here), we are not receiving */ + if(transmitting()) { + PRINTF("receiving_packet: We were TXing\n"); + return 0; + } + + cca_info = get_cca_info(); + + /* If we can't read CCA info, return "not receiving" */ + if(cca_info == RF_GET_CCA_INFO_ERROR) { + return 0; + } + + /* If sync has been seen, return 1 (receiving) */ + if(cca_info & RF_CMD_CCA_REQ_CCA_SYNC_BUSY) { + return 1; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +pending_packet(void) +{ + volatile rfc_dataEntry_t *entry = (rfc_dataEntry_t *)rx_data_queue.pCurrEntry; + int rv = 0; + + /* Go through all RX buffers and check their status */ + do { + if(entry->status == DATA_ENTRY_STATUS_FINISHED + || entry->status == DATA_ENTRY_STATUS_BUSY) { + rv = 1; + if(!poll_mode) { + process_poll(&rf_core_process); + } + } + + entry = (rfc_dataEntry_t *)entry->pNextEntry; + } while(entry != (rfc_dataEntry_t *)rx_data_queue.pCurrEntry); + + /* If we didn't find an entry at status finished, no frames are pending */ + return rv; +} +/*---------------------------------------------------------------------------*/ +static int +on(void) +{ + /* + * If we are in the middle of a BLE operation, we got called by ContikiMAC + * from within an interrupt context. Abort, but pretend everything is OK. + */ + if(rf_ble_is_active() == RF_BLE_ACTIVE) { + PRINTF("on: Interrupt context but BLE in progress\n"); + return RF_CORE_CMD_OK; + } + +#if !CC2650_FAST_RADIO_STARTUP + /* + * Request the HF XOSC as the source for the HF clock. Needed before we can + * use the FS. This will only request, it will _not_ perform the switch. + */ + oscillators_request_hf_xosc(); +#endif + + if(rf_is_on()) { + PRINTF("on: We were on. PD=%u, RX=0x%04x \n", rf_core_is_accessible(), + RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf)); + return RF_CORE_CMD_OK; + } + + init_rx_buffers(); + + /* + * Trigger a switch to the XOSC, so that we can subsequently use the RF FS + * This will block until the XOSC is actually ready, but give how we + * requested it early on, this won't be too long a wait. + * This should be done before starting the RAT. + */ + oscillators_switch_to_hf_xosc(); + + if(rf_core_boot() != RF_CORE_CMD_OK) { + PRINTF("on: rf_core_boot() failed\n"); + return RF_CORE_CMD_ERROR; + } + + rf_core_setup_interrupts(poll_mode); + + if(rf_radio_setup() != RF_CORE_CMD_OK) { + PRINTF("on: radio_setup() failed\n"); + return RF_CORE_CMD_ERROR; + } + + return rx_on(); +} +/*---------------------------------------------------------------------------*/ +static int +off(void) +{ + /* + * If we are in the middle of a BLE operation, we got called by ContikiMAC + * from within an interrupt context. Abort, but pretend everything is OK. + */ + if(rf_ble_is_active() == RF_BLE_ACTIVE) { + PRINTF("off: Interrupt context but BLE in progress\n"); + return RF_CORE_CMD_OK; + } + + while(transmitting()); + + /* stopping the rx explicitly results in lower sleep-mode power usage */ + rx_off(); + rf_core_power_down(); + + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + +#if !CC2650_FAST_RADIO_STARTUP + /* Switch HF clock source to the RCOSC to preserve power. + * This must be done after stopping RAT. + */ + oscillators_switch_to_hf_rc(); +#endif + + /* We pulled the plug, so we need to restore the status manually */ + ((rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf)->status = RF_CORE_RADIO_OP_STATUS_IDLE; + + /* + * Just in case there was an ongoing RX (which started after we begun the + * shutdown sequence), we don't want to leave the buffer in state == ongoing + */ + if(((rfc_dataEntry_t *)rx_buf_0)->status == DATA_ENTRY_STATUS_BUSY) { + ((rfc_dataEntry_t *)rx_buf_0)->status = DATA_ENTRY_STATUS_PENDING; + } + if(((rfc_dataEntry_t *)rx_buf_1)->status == DATA_ENTRY_STATUS_BUSY) { + ((rfc_dataEntry_t *)rx_buf_1)->status = DATA_ENTRY_STATUS_PENDING; + } + if(((rfc_dataEntry_t *)rx_buf_2)->status == DATA_ENTRY_STATUS_BUSY) { + ((rfc_dataEntry_t *)rx_buf_2)->status = DATA_ENTRY_STATUS_PENDING; + } + if(((rfc_dataEntry_t *)rx_buf_3)->status == DATA_ENTRY_STATUS_BUSY) { + ((rfc_dataEntry_t *)rx_buf_3)->status = DATA_ENTRY_STATUS_PENDING; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +/* Enable or disable CCA before sending */ +static radio_result_t +set_send_on_cca(uint8_t enable) +{ + if(enable) { + /* this driver does not have support for CCA on Tx */ + return RADIO_RESULT_NOT_SUPPORTED; + } + return RADIO_RESULT_OK; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf; + + if(!value) { + return RADIO_RESULT_INVALID_VALUE; + } + + switch(param) { + case RADIO_PARAM_POWER_MODE: + /* On / off */ + *value = rf_is_on() ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF; + return RADIO_RESULT_OK; + case RADIO_PARAM_CHANNEL: + *value = (radio_value_t)cmd->channel; + return RADIO_RESULT_OK; + case RADIO_PARAM_PAN_ID: + *value = (radio_value_t)cmd->localPanID; + return RADIO_RESULT_OK; + case RADIO_PARAM_16BIT_ADDR: + *value = (radio_value_t)cmd->localShortAddr; + return RADIO_RESULT_OK; + case RADIO_PARAM_RX_MODE: + *value = 0; + if(cmd->frameFiltOpt.frameFiltEn) { + *value |= RADIO_RX_MODE_ADDRESS_FILTER; + } + if(cmd->frameFiltOpt.autoAckEn) { + *value |= RADIO_RX_MODE_AUTOACK; + } + if(poll_mode) { + *value |= RADIO_RX_MODE_POLL_MODE; + } + + return RADIO_RESULT_OK; + case RADIO_PARAM_TX_MODE: + *value = 0; + return RADIO_RESULT_OK; + case RADIO_PARAM_TXPOWER: + *value = get_tx_power(); + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + *value = cmd->ccaRssiThr; + return RADIO_RESULT_OK; + case RADIO_PARAM_RSSI: + *value = get_rssi(); + + if(*value == RF_CMD_CCA_REQ_RSSI_UNKNOWN) { + return RADIO_RESULT_ERROR; + } else { + return RADIO_RESULT_OK; + } + case RADIO_CONST_CHANNEL_MIN: + *value = IEEE_MODE_CHANNEL_MIN; + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MAX: + *value = IEEE_MODE_CHANNEL_MAX; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MIN: + *value = OUTPUT_POWER_MIN; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MAX: + *value = OUTPUT_POWER_MAX; + return RADIO_RESULT_OK; + case RADIO_PARAM_LAST_RSSI: + *value = last_rssi; + return RADIO_RESULT_OK; + case RADIO_PARAM_LAST_LINK_QUALITY: + *value = last_corr_lqi; + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + radio_result_t rv = RADIO_RESULT_OK; + rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf; + uint8_t old_poll_mode; + + switch(param) { + case RADIO_PARAM_POWER_MODE: + if(value == RADIO_POWER_MODE_ON) { + if(on() != RF_CORE_CMD_OK) { + PRINTF("set_value: on() failed (1)\n"); + return RADIO_RESULT_ERROR; + } + return RADIO_RESULT_OK; + } + if(value == RADIO_POWER_MODE_OFF) { + off(); + return RADIO_RESULT_OK; + } + return RADIO_RESULT_INVALID_VALUE; + case RADIO_PARAM_CHANNEL: + if(value < IEEE_MODE_CHANNEL_MIN || + value > IEEE_MODE_CHANNEL_MAX) { + return RADIO_RESULT_INVALID_VALUE; + } + + /* Note: this return may lead to long periods when RAT and RTC are not resynchronized */ + if(cmd->channel == (uint8_t)value) { + /* We already have that very same channel configured. + * Nothing to do here. */ + return RADIO_RESULT_OK; + } + + cmd->channel = (uint8_t)value; + break; + case RADIO_PARAM_PAN_ID: + cmd->localPanID = (uint16_t)value; + break; + case RADIO_PARAM_16BIT_ADDR: + cmd->localShortAddr = (uint16_t)value; + break; + case RADIO_PARAM_RX_MODE: + { + if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER | + RADIO_RX_MODE_AUTOACK | RADIO_RX_MODE_POLL_MODE)) { + return RADIO_RESULT_INVALID_VALUE; + } + + cmd->frameFiltOpt.frameFiltEn = (value & RADIO_RX_MODE_ADDRESS_FILTER) != 0; + cmd->frameFiltOpt.frameFiltStop = 1; + cmd->frameFiltOpt.autoAckEn = (value & RADIO_RX_MODE_AUTOACK) != 0; + cmd->frameFiltOpt.slottedAckEn = 0; + cmd->frameFiltOpt.autoPendEn = 0; + cmd->frameFiltOpt.defaultPend = 0; + cmd->frameFiltOpt.bPendDataReqOnly = 0; + cmd->frameFiltOpt.bPanCoord = 0; + cmd->frameFiltOpt.bStrictLenFilter = 0; + + old_poll_mode = poll_mode; + poll_mode = (value & RADIO_RX_MODE_POLL_MODE) != 0; + if(poll_mode == old_poll_mode) { + uint32_t cmd_status; + + /* do not turn the radio on and off, just send an update command */ + memcpy(&filter_cmd.newFrameFiltOpt, &cmd->frameFiltOpt, sizeof(cmd->frameFiltOpt)); + + if(rf_core_send_cmd((uint32_t)&filter_cmd, &cmd_status) == RF_CORE_CMD_ERROR) { + PRINTF("setting address filter failed: CMDSTA=0x%08lx\n", cmd_status); + return RADIO_RESULT_ERROR; + } + return RADIO_RESULT_OK; + } + break; + } + + case RADIO_PARAM_TX_MODE: + if(value & ~(RADIO_TX_MODE_SEND_ON_CCA)) { + return RADIO_RESULT_INVALID_VALUE; + } + return set_send_on_cca((value & RADIO_TX_MODE_SEND_ON_CCA) != 0); + + case RADIO_PARAM_TXPOWER: + if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) { + return RADIO_RESULT_INVALID_VALUE; + } + + set_tx_power(value); + + return RADIO_RESULT_OK; + + case RADIO_PARAM_CCA_THRESHOLD: + cmd->ccaRssiThr = (int8_t)value; + break; + + default: + return RADIO_RESULT_NOT_SUPPORTED; + } + + /* If off, the new configuration will be applied the next time radio is started */ + if(!rf_is_on()) { + return RADIO_RESULT_OK; + } + + /* If we reach here we had no errors. Apply new settings */ + if(rx_off() != RF_CORE_CMD_OK) { + PRINTF("set_value: rx_off() failed\n"); + rv = RADIO_RESULT_ERROR; + } + + /* Restart the radio timer (RAT). + This causes resynchronization between RAT and RTC: useful for TSCH. */ + rf_core_restart_rat(); + + check_rat_overflow(false); + + if(rx_on() != RF_CORE_CMD_OK) { + PRINTF("set_value: rx_on() failed\n"); + rv = RADIO_RESULT_ERROR; + } + + return rv; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + uint8_t *target; + uint8_t *src; + int i; + rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf; + + if(param == RADIO_PARAM_64BIT_ADDR) { + if(size != 8 || !dest) { + return RADIO_RESULT_INVALID_VALUE; + } + + target = dest; + src = (uint8_t *)(&cmd->localExtAddr); + + for(i = 0; i < 8; i++) { + target[i] = src[7 - i]; + } + + return RADIO_RESULT_OK; + } + + if(param == RADIO_PARAM_LAST_PACKET_TIMESTAMP) { + if(size != sizeof(rtimer_clock_t) || !dest) { + return RADIO_RESULT_INVALID_VALUE; + } + *(rtimer_clock_t *)dest = last_packet_timestamp; + + return RADIO_RESULT_OK; + } + + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + radio_result_t rv; + int i; + uint8_t *dst; + rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf; + + if(param == RADIO_PARAM_64BIT_ADDR) { + if(size != 8 || !src) { + return RADIO_RESULT_INVALID_VALUE; + } + + dst = (uint8_t *)(&cmd->localExtAddr); + + for(i = 0; i < 8; i++) { + dst[i] = ((uint8_t *)src)[7 - i]; + } + + /* If off, the new configuration will be applied the next time radio is started */ + if(!rf_is_on()) { + return RADIO_RESULT_OK; + } + + if(rx_off() != RF_CORE_CMD_OK) { + PRINTF("set_object: rx_off() failed\n"); + rv = RADIO_RESULT_ERROR; + } + + if(rx_on() != RF_CORE_CMD_OK) { + PRINTF("set_object: rx_on() failed\n"); + rv = RADIO_RESULT_ERROR; + } + + return rv; + } + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +const struct radio_driver ieee_mode_driver = { + init, + prepare, + transmit, + send, + read_frame, + channel_clear, + receiving_packet, + pending_packet, + on, + off, + get_value, + set_value, + get_object, + set_object, +}; +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/rf-core/prop-mode.c b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c new file mode 100644 index 000000000..94aef33b9 --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c @@ -0,0 +1,1152 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup rf-core + * @{ + * + * \defgroup rf-core-prop CC13xx Prop mode driver + * + * @{ + * + * \file + * Implementation of the CC13xx prop mode NETSTACK_RADIO driver + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/radio.h" +#include "dev/cc26xx-uart.h" +#include "dev/oscillators.h" +#include "dev/watchdog.h" +#include "net/packetbuf.h" +#include "net/rime/rimestats.h" +#include "net/linkaddr.h" +#include "net/netstack.h" +#include "sys/energest.h" +#include "sys/clock.h" +#include "sys/rtimer.h" +#include "sys/cc.h" +#include "lpm.h" +#include "ti-lib.h" +#include "rf-core/rf-core.h" +#include "rf-core/rf-ble.h" +#include "rf-core/dot-15-4g.h" +/*---------------------------------------------------------------------------*/ +/* RF core and RF HAL API */ +#include "hw_rfc_dbell.h" +#include "hw_rfc_pwr.h" +/*---------------------------------------------------------------------------*/ +/* RF Core Mailbox API */ +#include "rf-core/api/mailbox.h" +#include "rf-core/api/common_cmd.h" +#include "rf-core/api/data_entry.h" +#include "rf-core/api/prop_mailbox.h" +#include "rf-core/api/prop_cmd.h" +/*---------------------------------------------------------------------------*/ +/* CC13xxware patches */ +#include "rf_patches/rf_patch_cpe_genfsk.h" +/*---------------------------------------------------------------------------*/ +#include "rf-core/smartrf-settings.h" +/*---------------------------------------------------------------------------*/ +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +/* Data entry status field constants */ +#define DATA_ENTRY_STATUS_PENDING 0x00 /* Not in use by the Radio CPU */ +#define DATA_ENTRY_STATUS_ACTIVE 0x01 /* Open for r/w by the radio CPU */ +#define DATA_ENTRY_STATUS_BUSY 0x02 /* Ongoing r/w */ +#define DATA_ENTRY_STATUS_FINISHED 0x03 /* Free to use and to free */ +#define DATA_ENTRY_STATUS_UNFINISHED 0x04 /* Partial RX entry */ +/*---------------------------------------------------------------------------*/ +/* Data whitener. 1: Whitener, 0: No whitener */ +#ifdef PROP_MODE_CONF_DW +#define PROP_MODE_DW PROP_MODE_CONF_DW +#else +#define PROP_MODE_DW 0 +#endif + +#ifdef PROP_MODE_CONF_USE_CRC16 +#define PROP_MODE_USE_CRC16 PROP_MODE_CONF_USE_CRC16 +#else +#define PROP_MODE_USE_CRC16 0 +#endif +/*---------------------------------------------------------------------------*/ +#ifdef PROP_MODE_CONF_SNIFFER +#define PROP_MODE_SNIFFER PROP_MODE_CONF_SNIFFER +#else +#define PROP_MODE_SNIFFER 0 +#endif + +#if PROP_MODE_SNIFFER +static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; +#endif +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns the current status of a running Radio Op command + * \param a A pointer with the buffer used to initiate the command + * \return The value of the Radio Op buffer's status field + * + * This macro can be used to e.g. return the status of a previously + * initiated background operation, or of an immediate command + */ +#define RF_RADIO_OP_GET_STATUS(a) GET_FIELD_V(a, radioOp, status) +/*---------------------------------------------------------------------------*/ +/* Special value returned by CMD_IEEE_CCA_REQ when an RSSI is not available */ +#define RF_CMD_CCA_REQ_RSSI_UNKNOWN -128 + +/* Used for the return value of channel_clear */ +#define RF_CCA_CLEAR 1 +#define RF_CCA_BUSY 0 + +/* Used as an error return value for get_cca_info */ +#define RF_GET_CCA_INFO_ERROR 0xFF + +/* + * Values of the individual bits of the ccaInfo field in CMD_IEEE_CCA_REQ's + * status struct + */ +#define RF_CMD_CCA_REQ_CCA_STATE_IDLE 0 /* 00 */ +#define RF_CMD_CCA_REQ_CCA_STATE_BUSY 1 /* 01 */ +#define RF_CMD_CCA_REQ_CCA_STATE_INVALID 2 /* 10 */ + +#ifdef PROP_MODE_CONF_RSSI_THRESHOLD +#define PROP_MODE_RSSI_THRESHOLD PROP_MODE_CONF_RSSI_THRESHOLD +#else +#define PROP_MODE_RSSI_THRESHOLD 0xA6 +#endif + +static int8_t rssi_threshold = PROP_MODE_RSSI_THRESHOLD; +/*---------------------------------------------------------------------------*/ +static int on(void); +static int off(void); + +static rfc_propRxOutput_t rx_stats; +/*---------------------------------------------------------------------------*/ +/* Defines and variables related to the .15.4g PHY HDR */ +#define DOT_4G_MAX_FRAME_LEN 2047 +#define DOT_4G_PHR_LEN 2 + +/* PHY HDR bits */ +#define DOT_4G_PHR_CRC16 0x10 +#define DOT_4G_PHR_DW 0x08 + +#if PROP_MODE_USE_CRC16 +/* CRC16 */ +#define DOT_4G_PHR_CRC_BIT DOT_4G_PHR_CRC16 +#define CRC_LEN 2 +#else +/* CRC32 */ +#define DOT_4G_PHR_CRC_BIT 0 +#define CRC_LEN 4 +#endif + +#if PROP_MODE_DW +#define DOT_4G_PHR_DW_BIT DOT_4G_PHR_DW +#else +#define DOT_4G_PHR_DW_BIT 0 +#endif +/*---------------------------------------------------------------------------*/ +/* How long to wait for an ongoing ACK TX to finish before starting frame TX */ +#define TX_WAIT_TIMEOUT (RTIMER_SECOND >> 11) + +/* How long to wait for the RF to enter RX in rf_cmd_ieee_rx */ +#define ENTER_RX_WAIT_TIMEOUT (RTIMER_SECOND >> 10) +/*---------------------------------------------------------------------------*/ +/* TX Power dBm lookup table - values from SmartRF Studio */ +typedef struct output_config { + radio_value_t dbm; + uint16_t tx_power; /* Value for the PROP_DIV_RADIO_SETUP.txPower field */ +} output_config_t; + +static const output_config_t output_power[] = { + { 14, 0xa73f }, + { 13, 0xa73f }, /* 12.5 */ + { 12, 0xb818 }, + { 11, 0x50da }, + { 10, 0x38d3 }, + { 9, 0x2ccd }, + { 8, 0x24cb }, + { 7, 0x20c9 }, + { 6, 0x1cc7 }, + { 5, 0x18c6 }, + { 4, 0x18c5 }, + { 3, 0x14c4 }, + { 2, 0x1042 }, + { 1, 0x10c3 }, + { 0, 0x0041 }, + {-10, 0x08c0 }, +}; + +#define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t)) + +/* Max and Min Output Power in dBm */ +#define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].dbm) +#define OUTPUT_POWER_MAX (output_power[0].dbm) +#define OUTPUT_POWER_UNKNOWN 0xFFFF + +/* Default TX Power - position in output_power[] */ +const output_config_t *tx_power_current = &output_power[1]; +/*---------------------------------------------------------------------------*/ +#ifdef PROP_MODE_CONF_LO_DIVIDER +#define PROP_MODE_LO_DIVIDER PROP_MODE_CONF_LO_DIVIDER +#else +#define PROP_MODE_LO_DIVIDER 0x05 +#endif +/*---------------------------------------------------------------------------*/ +#define DATA_ENTRY_LENSZ_NONE 0 +#define DATA_ENTRY_LENSZ_BYTE 1 +#define DATA_ENTRY_LENSZ_WORD 2 /* 2 bytes */ + +#define RX_BUF_SIZE 140 +/* Receive buffers: 1 frame in each */ +static uint8_t rx_buf_0[RX_BUF_SIZE] CC_ALIGN(4); +static uint8_t rx_buf_1[RX_BUF_SIZE] CC_ALIGN(4); + +/* The RX Data Queue */ +static dataQueue_t rx_data_queue = { 0 }; + +/* Receive entry pointer to keep track of read items */ +volatile static uint8_t *rx_read_entry; +/*---------------------------------------------------------------------------*/ +/* The outgoing frame buffer */ +#define TX_BUF_PAYLOAD_LEN 180 +#define TX_BUF_HDR_LEN 2 + +static uint8_t tx_buf[TX_BUF_HDR_LEN + TX_BUF_PAYLOAD_LEN] CC_ALIGN(4); +/*---------------------------------------------------------------------------*/ +static uint8_t +rf_is_on(void) +{ + if(!rf_core_is_accessible()) { + return 0; + } + + return smartrf_settings_cmd_prop_rx_adv.status == RF_CORE_RADIO_OP_STATUS_ACTIVE; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +transmitting(void) +{ + return smartrf_settings_cmd_prop_tx_adv.status == RF_CORE_RADIO_OP_STATUS_ACTIVE; +} +/*---------------------------------------------------------------------------*/ +static radio_value_t +get_rssi(void) +{ + uint32_t cmd_status; + int8_t rssi; + uint8_t was_off = 0; + rfc_CMD_GET_RSSI_t cmd; + + /* If we are off, turn on first */ + if(!rf_is_on()) { + was_off = 1; + if(on() != RF_CORE_CMD_OK) { + PRINTF("get_rssi: on() failed\n"); + return RF_CMD_CCA_REQ_RSSI_UNKNOWN; + } + } + + memset(&cmd, 0x00, sizeof(cmd)); + cmd.commandNo = CMD_GET_RSSI; + + rssi = RF_CMD_CCA_REQ_RSSI_UNKNOWN; + + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_OK) { + /* Current RSSI in bits 23:16 of cmd_status */ + rssi = (cmd_status >> 16) & 0xFF; + } + + /* If we were off, turn back off */ + if(was_off) { + off(); + } + + return rssi; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +get_channel(void) +{ + uint32_t freq_khz; + + freq_khz = smartrf_settings_cmd_fs.frequency * 1000; + + /* + * For some channels, fractFreq * 1000 / 65536 will return 324.99xx. + * Casting the result to uint32_t will truncate decimals resulting in the + * function returning channel - 1 instead of channel. Thus, we do a quick + * positive integer round up. + */ + freq_khz += (((smartrf_settings_cmd_fs.fractFreq * 1000) + 65535) / 65536); + + return (freq_khz - DOT_15_4G_CHAN0_FREQUENCY) / DOT_15_4G_CHANNEL_SPACING; +} +/*---------------------------------------------------------------------------*/ +static void +set_channel(uint8_t channel) +{ + uint32_t new_freq; + uint16_t freq, frac; + + new_freq = DOT_15_4G_CHAN0_FREQUENCY + (channel * DOT_15_4G_CHANNEL_SPACING); + + freq = (uint16_t)(new_freq / 1000); + frac = (new_freq - (freq * 1000)) * 65536 / 1000; + + PRINTF("set_channel: %u = 0x%04x.0x%04x (%lu)\n", channel, freq, frac, + new_freq); + + smartrf_settings_cmd_prop_radio_div_setup.centerFreq = freq; + smartrf_settings_cmd_fs.frequency = freq; + smartrf_settings_cmd_fs.fractFreq = frac; +} +/*---------------------------------------------------------------------------*/ +/* Returns the current TX power in dBm */ +static radio_value_t +get_tx_power(void) +{ + return tx_power_current->dbm; +} +/*---------------------------------------------------------------------------*/ +/* + * The caller must make sure to send a new CMD_PROP_RADIO_DIV_SETP to the + * radio after calling this function. + */ +static void +set_tx_power(radio_value_t power) +{ + int i; + + for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) { + if(power <= output_power[i].dbm) { + /* + * Merely save the value. It will be used in all subsequent usages of + * CMD_PROP_RADIO_DIV_SETP, including one immediately after this function + * has returned + */ + tx_power_current = &output_power[i]; + + return; + } + } +} +/*---------------------------------------------------------------------------*/ +static int +prop_div_radio_setup(void) +{ + uint32_t cmd_status; + rfc_radioOp_t *cmd = (rfc_radioOp_t *)&smartrf_settings_cmd_prop_radio_div_setup; + + /* Adjust loDivider depending on the selected band */ + smartrf_settings_cmd_prop_radio_div_setup.loDivider = PROP_MODE_LO_DIVIDER; + + /* Update to the correct TX power setting */ + smartrf_settings_cmd_prop_radio_div_setup.txPower = tx_power_current->tx_power; + + /* Send Radio setup to RF Core */ + if(rf_core_send_cmd((uint32_t)cmd, &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("prop_div_radio_setup: DIV_SETUP, CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd->status); + return RF_CORE_CMD_ERROR; + } + + /* Wait until radio setup is done */ + if(rf_core_wait_cmd_done(cmd) != RF_CORE_CMD_OK) { + PRINTF("prop_div_radio_setup: DIV_SETUP wait, CMDSTA=0x%08lx," + "status=0x%04x\n", cmd_status, cmd->status); + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +rf_cmd_prop_rx() +{ + uint32_t cmd_status; + rtimer_clock_t t0; + volatile rfc_CMD_PROP_RX_ADV_t *cmd_rx_adv; + int ret; + + cmd_rx_adv = (rfc_CMD_PROP_RX_ADV_t *)&smartrf_settings_cmd_prop_rx_adv; + cmd_rx_adv->status = RF_CORE_RADIO_OP_STATUS_IDLE; + + /* + * Set the max Packet length. This is for the payload only, therefore + * 2047 - length offset + */ + cmd_rx_adv->maxPktLen = DOT_4G_MAX_FRAME_LEN - cmd_rx_adv->lenOffset; + + ret = rf_core_send_cmd((uint32_t)cmd_rx_adv, &cmd_status); + + if(ret != RF_CORE_CMD_OK) { + PRINTF("rf_cmd_prop_rx: send_cmd ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", + ret, cmd_status, cmd_rx_adv->status); + return RF_CORE_CMD_ERROR; + } + + t0 = RTIMER_NOW(); + + while(cmd_rx_adv->status != RF_CORE_RADIO_OP_STATUS_ACTIVE && + (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ENTER_RX_WAIT_TIMEOUT))); + + /* Wait to enter RX */ + if(cmd_rx_adv->status != RF_CORE_RADIO_OP_STATUS_ACTIVE) { + PRINTF("rf_cmd_prop_rx: CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd_rx_adv->status); + return RF_CORE_CMD_ERROR; + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +rx_on_prop(void) +{ + int ret; + + if(rf_is_on()) { + PRINTF("rx_on_prop: We were on. PD=%u, RX=0x%04x\n", + rf_core_is_accessible(), smartrf_settings_cmd_prop_rx_adv.status); + return RF_CORE_CMD_OK; + } + + /* Put CPE in RX using the currently configured parameters */ + ret = rf_cmd_prop_rx(); + + if(ret) { + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +rx_off_prop(void) +{ + uint32_t cmd_status; + int ret; + + /* If we are off, do nothing */ + if(!rf_is_on()) { + return RF_CORE_CMD_OK; + } + + /* Send a CMD_ABORT command to RF Core */ + if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("rx_off_prop: CMD_ABORT status=0x%08lx\n", cmd_status); + /* Continue nonetheless */ + } + + while(rf_is_on()); + + if(smartrf_settings_cmd_prop_rx_adv.status == PROP_DONE_STOPPED || + smartrf_settings_cmd_prop_rx_adv.status == PROP_DONE_ABORT) { + /* Stopped gracefully */ + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + ret = RF_CORE_CMD_OK; + } else { + PRINTF("rx_off_prop: status=0x%04x\n", + smartrf_settings_cmd_prop_rx_adv.status); + ret = RF_CORE_CMD_ERROR; + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +request(void) +{ + /* + * We rely on the RDC layer to turn us on and off. Thus, if we are on we + * will only allow sleep, standby otherwise + */ + if(rf_is_on()) { + return LPM_MODE_SLEEP; + } + + return LPM_MODE_MAX_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +LPM_MODULE(prop_lpm_module, request, NULL, NULL, LPM_DOMAIN_NONE); +/*---------------------------------------------------------------------------*/ +static int +prop_fs(void) +{ + uint32_t cmd_status; + rfc_radioOp_t *cmd = (rfc_radioOp_t *)&smartrf_settings_cmd_fs; + + /* Send the command to the RF Core */ + if(rf_core_send_cmd((uint32_t)cmd, &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("prop_fs: CMD_FS, CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd->status); + return RF_CORE_CMD_ERROR; + } + + /* Wait until the command is done */ + if(rf_core_wait_cmd_done(cmd) != RF_CORE_CMD_OK) { + PRINTF("prop_fs: CMD_FS wait, CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd->status); + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +static void +soft_off_prop(void) +{ + uint32_t cmd_status; + volatile rfc_radioOp_t *cmd = rf_core_get_last_radio_op(); + + if(!rf_core_is_accessible()) { + return; + } + + /* Send a CMD_ABORT command to RF Core */ + if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("soft_off_prop: CMD_ABORT status=0x%08lx\n", cmd_status); + return; + } + + while((cmd->status & RF_CORE_RADIO_OP_MASKED_STATUS) == + RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING); +} +/*---------------------------------------------------------------------------*/ +static uint8_t +soft_on_prop(void) +{ + if(prop_div_radio_setup() != RF_CORE_CMD_OK) { + PRINTF("soft_on_prop: prop_div_radio_setup() failed\n"); + return RF_CORE_CMD_ERROR; + } + + if(prop_fs() != RF_CORE_CMD_OK) { + PRINTF("soft_on_prop: prop_fs() failed\n"); + return RF_CORE_CMD_ERROR; + } + + return rx_on_prop(); +} +/*---------------------------------------------------------------------------*/ +static const rf_core_primary_mode_t mode_prop = { + soft_off_prop, + soft_on_prop, +}; +/*---------------------------------------------------------------------------*/ +static int +init(void) +{ + rfc_dataEntry_t *entry; + + lpm_register_module(&prop_lpm_module); + + if(ti_lib_chipinfo_chip_family_is_cc13xx() == false) { + return RF_CORE_CMD_ERROR; + } + + rf_core_set_modesel(); + + /* Initialise RX buffers */ + memset(rx_buf_0, 0, RX_BUF_SIZE); + memset(rx_buf_1, 0, RX_BUF_SIZE); + + entry = (rfc_dataEntry_t *)rx_buf_0; + entry->status = DATA_ENTRY_STATUS_PENDING; + entry->config.type = DATA_ENTRY_TYPE_GEN; + entry->config.lenSz = DATA_ENTRY_LENSZ_WORD; + entry->length = RX_BUF_SIZE - 8; + entry->pNextEntry = rx_buf_1; + + entry = (rfc_dataEntry_t *)rx_buf_1; + entry->status = DATA_ENTRY_STATUS_PENDING; + entry->config.type = DATA_ENTRY_TYPE_GEN; + entry->config.lenSz = DATA_ENTRY_LENSZ_WORD; + entry->length = RX_BUF_SIZE - 8; + entry->pNextEntry = rx_buf_0; + + /* Set of RF Core data queue. Circular buffer, no last entry */ + rx_data_queue.pCurrEntry = rx_buf_0; + rx_data_queue.pLastEntry = NULL; + + /* Initialize current read pointer to first element (used in ISR) */ + rx_read_entry = rx_buf_0; + + smartrf_settings_cmd_prop_rx_adv.pQueue = &rx_data_queue; + smartrf_settings_cmd_prop_rx_adv.pOutput = (uint8_t *)&rx_stats; + + set_channel(RF_CORE_CHANNEL); + + if(on() != RF_CORE_CMD_OK) { + PRINTF("init: on() failed\n"); + return RF_CORE_CMD_ERROR; + } + + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + + rf_core_primary_mode_register(&mode_prop); + + process_start(&rf_core_process, NULL); + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +prepare(const void *payload, unsigned short payload_len) +{ + int len = MIN(payload_len, TX_BUF_PAYLOAD_LEN); + + memcpy(&tx_buf[TX_BUF_HDR_LEN], payload, len); + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +transmit(unsigned short transmit_len) +{ + int ret; + uint8_t was_off = 0; + uint32_t cmd_status; + volatile rfc_CMD_PROP_TX_ADV_t *cmd_tx_adv; + + /* Length in .15.4g PHY HDR. Includes the CRC but not the HDR itself */ + uint16_t total_length; + + if(!rf_is_on()) { + was_off = 1; + if(on() != RF_CORE_CMD_OK) { + PRINTF("transmit: on() failed\n"); + return RADIO_TX_ERR; + } + } + + /* + * Prepare the .15.4g PHY header + * MS=0, Length MSBits=0, DW and CRC configurable + * Total length = transmit_len (payload) + CRC length + * + * The Radio will flip the bits around, so tx_buf[0] must have the length + * LSBs (PHR[15:8] and tx_buf[1] will have PHR[7:0] + */ + total_length = transmit_len + CRC_LEN; + + tx_buf[0] = total_length & 0xFF; + tx_buf[1] = (total_length >> 8) + DOT_4G_PHR_DW_BIT + DOT_4G_PHR_CRC_BIT; + + /* Prepare the CMD_PROP_TX_ADV command */ + cmd_tx_adv = (rfc_CMD_PROP_TX_ADV_t *)&smartrf_settings_cmd_prop_tx_adv; + + /* + * pktLen: Total number of bytes in the TX buffer, including the header if + * one exists, but not including the CRC (which is not present in the buffer) + */ + cmd_tx_adv->pktLen = transmit_len + DOT_4G_PHR_LEN; + cmd_tx_adv->pPkt = tx_buf; + + /* Abort RX */ + rx_off_prop(); + + /* Enable the LAST_COMMAND_DONE interrupt to wake us up */ + rf_core_cmd_done_en(false, false); + + ret = rf_core_send_cmd((uint32_t)cmd_tx_adv, &cmd_status); + + if(ret) { + /* If we enter here, TX actually started */ + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); + + watchdog_periodic(); + + /* Idle away while the command is running */ + while((cmd_tx_adv->status & RF_CORE_RADIO_OP_MASKED_STATUS) + == RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING) { + lpm_sleep(); + } + + if(cmd_tx_adv->status == RF_CORE_RADIO_OP_STATUS_PROP_DONE_OK) { + /* Sent OK */ + RIMESTATS_ADD(lltx); + ret = RADIO_TX_OK; + } else { + /* Operation completed, but frame was not sent */ + PRINTF("transmit: Not Sent OK status=0x%04x\n", + cmd_tx_adv->status); + ret = RADIO_TX_ERR; + } + } else { + /* Failure sending the CMD_PROP_TX command */ + PRINTF("transmit: PROP_TX_ERR ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", + ret, cmd_status, cmd_tx_adv->status); + ret = RADIO_TX_ERR; + } + + /* + * Update ENERGEST state here, before a potential call to off(), which + * will correctly update it if required. + */ + ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + + /* + * Disable LAST_FG_COMMAND_DONE interrupt. We don't really care about it + * except when we are transmitting + */ + rf_core_cmd_done_dis(false); + + /* Workaround. Set status to IDLE */ + cmd_tx_adv->status = RF_CORE_RADIO_OP_STATUS_IDLE; + + rx_on_prop(); + + if(was_off) { + off(); + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +send(const void *payload, unsigned short payload_len) +{ + prepare(payload, payload_len); + return transmit(payload_len); +} +/*---------------------------------------------------------------------------*/ +static int +read_frame(void *buf, unsigned short buf_len) +{ + rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry; + uint8_t *data_ptr = &entry->data; + int len = 0; + + if(entry->status == DATA_ENTRY_STATUS_FINISHED) { + + /* + * First 2 bytes in the data entry are the length. + * Our data entry consists of: Payload + RSSI (1 byte) + Status (1 byte) + * This length includes all of those. + */ + len = (*(uint16_t *)data_ptr); + data_ptr += 2; + len -= 2; + + if(len > 0) { + if(len <= buf_len) { + memcpy(buf, data_ptr, len); + } + + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, (int8_t)data_ptr[len]); + +#if PROP_MODE_SNIFFER + { + int i; + + cc26xx_uart_write_byte(magic[0]); + cc26xx_uart_write_byte(magic[1]); + cc26xx_uart_write_byte(magic[2]); + cc26xx_uart_write_byte(magic[3]); + + cc26xx_uart_write_byte(len + 2); + + for(i = 0; i < len; ++i) { + cc26xx_uart_write_byte(((uint8_t *)(buf))[i]); + } + + cc26xx_uart_write_byte((uint8_t)rx_stats.lastRssi); + cc26xx_uart_write_byte(0x80); + + while(cc26xx_uart_busy() == UART_BUSY); + } +#endif + } + + /* Move read entry pointer to next entry */ + rx_read_entry = entry->pNextEntry; + entry->status = DATA_ENTRY_STATUS_PENDING; + } + + return len; +} +/*---------------------------------------------------------------------------*/ +static int +channel_clear(void) +{ + uint8_t was_off = 0; + uint32_t cmd_status; + int8_t rssi = RF_CMD_CCA_REQ_RSSI_UNKNOWN; + + /* + * If we are in the middle of a BLE operation, we got called by ContikiMAC + * from within an interrupt context. Indicate a clear channel + */ + if(rf_ble_is_active() == RF_BLE_ACTIVE) { + return RF_CCA_CLEAR; + } + + if(!rf_core_is_accessible()) { + was_off = 1; + if(on() != RF_CORE_CMD_OK) { + PRINTF("channel_clear: on() failed\n"); + if(was_off) { + off(); + } + return RF_CCA_CLEAR; + } + } else { + if(transmitting()) { + PRINTF("channel_clear: called while in TX\n"); + return RF_CCA_CLEAR; + } + } + + while(rssi == RF_CMD_CCA_REQ_RSSI_UNKNOWN || rssi == 0) { + if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_GET_RSSI), &cmd_status) + != RF_CORE_CMD_OK) { + break; + } + /* Current RSSI in bits 23:16 of cmd_status */ + rssi = (cmd_status >> 16) & 0xFF; + } + + if(was_off) { + off(); + } + + if(rssi >= rssi_threshold) { + return RF_CCA_BUSY; + } + + return RF_CCA_CLEAR; +} +/*---------------------------------------------------------------------------*/ +static int +receiving_packet(void) +{ + if(!rf_is_on()) { + return 0; + } + + if(channel_clear() == RF_CCA_CLEAR) { + return 0; + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +pending_packet(void) +{ + int rv = 0; + volatile rfc_dataEntry_t *entry = (rfc_dataEntry_t *)rx_data_queue.pCurrEntry; + + /* Go through all RX buffers and check their status */ + do { + if(entry->status == DATA_ENTRY_STATUS_FINISHED) { + rv += 1; + process_poll(&rf_core_process); + } + + entry = (rfc_dataEntry_t *)entry->pNextEntry; + } while(entry != (rfc_dataEntry_t *)rx_data_queue.pCurrEntry); + + /* If we didn't find an entry at status finished, no frames are pending */ + return rv; +} +/*---------------------------------------------------------------------------*/ +static int +on(void) +{ + /* + * If we are in the middle of a BLE operation, we got called by ContikiMAC + * from within an interrupt context. Abort, but pretend everything is OK. + */ + if(rf_ble_is_active() == RF_BLE_ACTIVE) { + return RF_CORE_CMD_OK; + } + + /* + * Request the HF XOSC as the source for the HF clock. Needed before we can + * use the FS. This will only request, it will _not_ perform the switch. + */ + oscillators_request_hf_xosc(); + + if(rf_is_on()) { + PRINTF("on: We were on. PD=%u, RX=0x%04x \n", rf_core_is_accessible(), + smartrf_settings_cmd_prop_rx_adv.status); + return RF_CORE_CMD_OK; + } + + if(!rf_core_is_accessible()) { + if(rf_core_power_up() != RF_CORE_CMD_OK) { + PRINTF("on: rf_core_power_up() failed\n"); + + rf_core_power_down(); + + return RF_CORE_CMD_ERROR; + } + + rf_patch_cpe_genfsk(); + + if(rf_core_start_rat() != RF_CORE_CMD_OK) { + PRINTF("on: rf_core_start_rat() failed\n"); + + rf_core_power_down(); + + return RF_CORE_CMD_ERROR; + } + } + + rf_core_setup_interrupts(false); + + /* + * Trigger a switch to the XOSC, so that we can subsequently use the RF FS + * This will block until the XOSC is actually ready, but give how we + * requested it early on, this won't be too long a wait/ + */ + oscillators_switch_to_hf_xosc(); + + if(prop_div_radio_setup() != RF_CORE_CMD_OK) { + PRINTF("on: prop_div_radio_setup() failed\n"); + return RF_CORE_CMD_ERROR; + } + + if(prop_fs() != RF_CORE_CMD_OK) { + PRINTF("on: prop_fs() failed\n"); + return RF_CORE_CMD_ERROR; + } + + return rx_on_prop(); +} +/*---------------------------------------------------------------------------*/ +static int +off(void) +{ + rfc_dataEntry_t *entry; + + /* + * If we are in the middle of a BLE operation, we got called by ContikiMAC + * from within an interrupt context. Abort, but pretend everything is OK. + */ + if(rf_ble_is_active() == RF_BLE_ACTIVE) { + return RF_CORE_CMD_OK; + } + + rx_off_prop(); + rf_core_power_down(); + + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + + /* Switch HF clock source to the RCOSC to preserve power */ + oscillators_switch_to_hf_rc(); + + /* We pulled the plug, so we need to restore the status manually */ + smartrf_settings_cmd_prop_rx_adv.status = RF_CORE_RADIO_OP_STATUS_IDLE; + + entry = (rfc_dataEntry_t *)rx_buf_0; + entry->status = DATA_ENTRY_STATUS_PENDING; + + entry = (rfc_dataEntry_t *)rx_buf_1; + entry->status = DATA_ENTRY_STATUS_PENDING; + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + if(!value) { + return RADIO_RESULT_INVALID_VALUE; + } + + switch(param) { + case RADIO_PARAM_POWER_MODE: + /* On / off */ + *value = rf_is_on() ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF; + return RADIO_RESULT_OK; + case RADIO_PARAM_CHANNEL: + *value = (radio_value_t)get_channel(); + return RADIO_RESULT_OK; + case RADIO_PARAM_TXPOWER: + *value = get_tx_power(); + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + *value = rssi_threshold; + return RADIO_RESULT_OK; + case RADIO_PARAM_RSSI: + *value = get_rssi(); + + if(*value == RF_CMD_CCA_REQ_RSSI_UNKNOWN) { + return RADIO_RESULT_ERROR; + } else { + return RADIO_RESULT_OK; + } + case RADIO_CONST_CHANNEL_MIN: + *value = 0; + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MAX: + *value = DOT_15_4G_CHANNEL_MAX; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MIN: + *value = OUTPUT_POWER_MIN; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MAX: + *value = OUTPUT_POWER_MAX; + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + uint8_t was_off = 0; + radio_result_t rv = RADIO_RESULT_OK; + + switch(param) { + case RADIO_PARAM_POWER_MODE: + if(value == RADIO_POWER_MODE_ON) { + if(on() != RF_CORE_CMD_OK) { + PRINTF("set_value: on() failed (1)\n"); + return RADIO_RESULT_ERROR; + } + return RADIO_RESULT_OK; + } + if(value == RADIO_POWER_MODE_OFF) { + off(); + return RADIO_RESULT_OK; + } + return RADIO_RESULT_INVALID_VALUE; + case RADIO_PARAM_CHANNEL: + if(value < 0 || + value > DOT_15_4G_CHANNEL_MAX) { + return RADIO_RESULT_INVALID_VALUE; + } + + if(get_channel() == (uint8_t)value) { + /* We already have that very same channel configured. + * Nothing to do here. */ + return RADIO_RESULT_OK; + } + + set_channel((uint8_t)value); + break; + case RADIO_PARAM_TXPOWER: + if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) { + return RADIO_RESULT_INVALID_VALUE; + } + + soft_off_prop(); + + set_tx_power(value); + + if(soft_on_prop() != RF_CORE_CMD_OK) { + PRINTF("set_value: soft_on_prop() failed\n"); + rv = RADIO_RESULT_ERROR; + } + + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + rssi_threshold = (int8_t)value; + break; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } + + /* If we reach here we had no errors. Apply new settings */ + if(!rf_is_on()) { + was_off = 1; + if(on() != RF_CORE_CMD_OK) { + PRINTF("set_value: on() failed (2)\n"); + return RADIO_RESULT_ERROR; + } + } + + if(rx_off_prop() != RF_CORE_CMD_OK) { + PRINTF("set_value: rx_off_prop() failed\n"); + rv = RADIO_RESULT_ERROR; + } + + if(rx_on_prop() != RF_CORE_CMD_OK) { + PRINTF("set_value: rx_on_prop() failed\n"); + rv = RADIO_RESULT_ERROR; + } + + /* If we were off, turn back off */ + if(was_off) { + off(); + } + + return rv; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +const struct radio_driver prop_mode_driver = { + init, + prepare, + transmit, + send, + read_frame, + channel_clear, + receiving_packet, + pending_packet, + on, + off, + get_value, + set_value, + get_object, + set_object, +}; +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-ble.c b/cpu/cc26xx-cc13xx/rf-core/rf-ble.c new file mode 100644 index 000000000..48daba69f --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/rf-ble.c @@ -0,0 +1,395 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup rf-core-ble + * @{ + * + * \file + * Implementation of the CC13xx/CC26xx RF BLE driver + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "sys/process.h" +#include "sys/clock.h" +#include "sys/cc.h" +#include "sys/etimer.h" +#include "net/netstack.h" +#include "net/linkaddr.h" +#include "dev/oscillators.h" +#include "rf-core/rf-core.h" +#include "rf-core/rf-ble.h" +#include "rf-core/api/ble_cmd.h" +#include "rf-core/api/common_cmd.h" +#include "ti-lib.h" +/*---------------------------------------------------------------------------*/ +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +/* BLE Intervals: Send a burst of advertisements every BLE_ADV_INTERVAL secs */ +#define BLE_ADV_INTERVAL (CLOCK_SECOND * 5) +#define BLE_ADV_DUTY_CYCLE (CLOCK_SECOND / 10) +#define BLE_ADV_MESSAGES 10 + +/* BLE Advertisement-related macros */ +#define BLE_ADV_TYPE_DEVINFO 0x01 +#define BLE_ADV_TYPE_NAME 0x09 +#define BLE_ADV_TYPE_MANUFACTURER 0xFF +#define BLE_ADV_NAME_BUF_LEN 32 +#define BLE_ADV_PAYLOAD_BUF_LEN 64 +#define BLE_UUID_SIZE 16 +/*---------------------------------------------------------------------------*/ +static unsigned char ble_params_buf[32] CC_ALIGN(4); +static uint8_t ble_mode_on = RF_BLE_IDLE; +static struct etimer ble_adv_et; +static uint8_t payload[BLE_ADV_PAYLOAD_BUF_LEN]; +static int p = 0; +static int i; +/*---------------------------------------------------------------------------*/ +typedef struct default_ble_tx_power_s { + uint16_t ib:6; + uint16_t gc:2; + uint16_t boost:1; + uint16_t temp_coeff:7; +} default_ble_tx_power_t; + +static default_ble_tx_power_t tx_power = { 0x29, 0x00, 0x00, 0x00 }; +/*---------------------------------------------------------------------------*/ +/* BLE beacond config */ +static struct ble_beacond_config { + clock_time_t interval; + char adv_name[BLE_ADV_NAME_BUF_LEN]; +} beacond_config = { .interval = BLE_ADV_INTERVAL }; +/*---------------------------------------------------------------------------*/ +/* BLE overrides */ +static uint32_t ble_overrides[] = { + 0x00364038, /* Synth: Set RTRIM (POTAILRESTRIM) to 6 */ + 0x000784A3, /* Synth: Set FREF = 3.43 MHz (24 MHz / 7) */ + 0xA47E0583, /* Synth: Set loop bandwidth after lock to 80 kHz (K2) */ + 0xEAE00603, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, LSB) */ + 0x00010623, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, MSB) */ + 0x00456088, /* Adjust AGC reference level */ + 0xFFFFFFFF, /* End of override list */ +}; +/*---------------------------------------------------------------------------*/ +PROCESS(rf_ble_beacon_process, "CC13xx / CC26xx RF BLE Beacon Process"); +/*---------------------------------------------------------------------------*/ +static int +send_ble_adv_nc(int channel, uint8_t *adv_payload, int adv_payload_len) +{ + uint32_t cmd_status; + rfc_CMD_BLE_ADV_NC_t cmd; + rfc_bleAdvPar_t *params; + + params = (rfc_bleAdvPar_t *)ble_params_buf; + + /* Clear both buffers */ + memset(&cmd, 0x00, sizeof(cmd)); + memset(ble_params_buf, 0x00, sizeof(ble_params_buf)); + + /* Adv NC */ + cmd.commandNo = CMD_BLE_ADV_NC; + cmd.condition.rule = COND_NEVER; + cmd.whitening.bOverride = 0; + cmd.whitening.init = 0; + cmd.pParams = params; + cmd.channel = channel; + + /* Set up BLE Advertisement parameters */ + params->pDeviceAddress = (uint16_t *)&linkaddr_node_addr.u8[LINKADDR_SIZE - 2]; + params->endTrigger.triggerType = TRIG_NEVER; + params->endTime = TRIG_NEVER; + + /* Set up BLE Advertisement parameters */ + params = (rfc_bleAdvPar_t *)ble_params_buf; + params->advLen = adv_payload_len; + params->pAdvData = adv_payload; + + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_ERROR) { + PRINTF("send_ble_adv_nc: Chan=%d CMDSTA=0x%08lx, status=0x%04x\n", + channel, cmd_status, cmd.status); + return RF_CORE_CMD_ERROR; + } + + /* Wait until the command is done */ + if(rf_core_wait_cmd_done(&cmd) != RF_CORE_CMD_OK) { + PRINTF("send_ble_adv_nc: Chan=%d CMDSTA=0x%08lx, status=0x%04x\n", + channel, cmd_status, cmd.status); + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +void +rf_ble_beacond_config(clock_time_t interval, const char *name) +{ + if(RF_BLE_ENABLED == 0) { + return; + } + + if(name != NULL) { + if(strlen(name) == 0 || strlen(name) >= BLE_ADV_NAME_BUF_LEN) { + return; + } + + memset(beacond_config.adv_name, 0, BLE_ADV_NAME_BUF_LEN); + memcpy(beacond_config.adv_name, name, strlen(name)); + } + + if(interval != 0) { + beacond_config.interval = interval; + } +} +/*---------------------------------------------------------------------------*/ +uint8_t +rf_ble_beacond_start() +{ + if(RF_BLE_ENABLED == 0) { + return RF_CORE_CMD_ERROR; + } + + if(ti_lib_chipinfo_supports_ble() == false) { + return RF_CORE_CMD_ERROR; + } + + if(beacond_config.adv_name[0] == 0) { + return RF_CORE_CMD_ERROR; + } + + ble_mode_on = RF_BLE_IDLE; + + process_start(&rf_ble_beacon_process, NULL); + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +uint8_t +rf_ble_is_active() +{ + return ble_mode_on; +} +/*---------------------------------------------------------------------------*/ +void +rf_ble_beacond_stop() +{ + process_exit(&rf_ble_beacon_process); +} +/*---------------------------------------------------------------------------*/ +static uint8_t +rf_radio_setup() +{ + uint32_t cmd_status; + rfc_CMD_RADIO_SETUP_t cmd; + + /* Create radio setup command */ + rf_core_init_radio_op((rfc_radioOp_t *)&cmd, sizeof(cmd), CMD_RADIO_SETUP); + + cmd.txPower.IB = tx_power.ib; + cmd.txPower.GC = tx_power.gc; + cmd.txPower.tempCoeff = tx_power.temp_coeff; + cmd.txPower.boost = tx_power.boost; + cmd.pRegOverride = ble_overrides; + cmd.mode = 0; + + /* Send Radio setup to RF Core */ + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("rf_radio_setup: CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd.status); + return RF_CORE_CMD_ERROR; + } + + /* Wait until radio setup is done */ + if(rf_core_wait_cmd_done(&cmd) != RF_CORE_CMD_OK) { + PRINTF("rf_radio_setup: wait, CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd.status); + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(rf_ble_beacon_process, ev, data) +{ + uint8_t was_on; + int j; + uint32_t cmd_status; + bool interrupts_disabled; + + PROCESS_BEGIN(); + + while(1) { + etimer_set(&ble_adv_et, beacond_config.interval); + + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&ble_adv_et) || ev == PROCESS_EVENT_EXIT); + + if(ev == PROCESS_EVENT_EXIT) { + PROCESS_EXIT(); + } + + /* Set the adv payload each pass: The device name may have changed */ + p = 0; + + /* device info */ + memset(payload, 0, BLE_ADV_PAYLOAD_BUF_LEN); + payload[p++] = 0x02; /* 2 bytes */ + payload[p++] = BLE_ADV_TYPE_DEVINFO; + payload[p++] = 0x1a; /* LE general discoverable + BR/EDR */ + payload[p++] = 1 + strlen(beacond_config.adv_name); + payload[p++] = BLE_ADV_TYPE_NAME; + memcpy(&payload[p], beacond_config.adv_name, + strlen(beacond_config.adv_name)); + p += strlen(beacond_config.adv_name); + + for(i = 0; i < BLE_ADV_MESSAGES; i++) { + /* + * Under ContikiMAC, some IEEE-related operations will be called from an + * interrupt context. We need those to see that we are in BLE mode. + */ + interrupts_disabled = ti_lib_int_master_disable(); + ble_mode_on = RF_BLE_ACTIVE; + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } + + /* + * Send BLE_ADV_MESSAGES beacon bursts. Each burst on all three + * channels, with a BLE_ADV_DUTY_CYCLE interval between bursts + * + * First, determine our state: + * + * If we are running NullRDC, we are likely in IEEE RX mode. We need to + * abort the IEEE BG Op before entering BLE mode. + * If we are ContikiMAC, we are likely off, in which case we need to + * boot the CPE before entering BLE mode + */ + was_on = rf_core_is_accessible(); + + if(was_on) { + /* + * We were on: If we are in the process of receiving a frame, abort the + * BLE beacon burst. Otherwise, terminate the primary radio Op so we + * can switch to BLE mode + */ + if(NETSTACK_RADIO.receiving_packet()) { + PRINTF("rf_ble_beacon_process: We were receiving\n"); + + /* Abort this pass */ + break; + } + + rf_core_primary_mode_abort(); + } else { + /* Request the HF XOSC to source the HF clock. */ + oscillators_request_hf_xosc(); + + /* We were off: Boot the CPE */ + if(rf_core_boot() != RF_CORE_CMD_OK) { + PRINTF("rf_ble_beacon_process: rf_core_boot() failed\n"); + + /* Abort this pass */ + break; + } + + /* Trigger a switch to the XOSC, so that we can use the FS */ + oscillators_switch_to_hf_xosc(); + } + + /* Enter BLE mode */ + if(rf_radio_setup() != RF_CORE_CMD_OK) { + PRINTF("cc26xx_rf_ble_beacon_process: Error entering BLE mode\n"); + /* Continue so we can at least try to restore our previous state */ + } else { + /* Send advertising packets on all 3 advertising channels */ + for(j = 37; j <= 39; j++) { + if(send_ble_adv_nc(j, payload, p) != RF_CORE_CMD_OK) { + PRINTF("cc26xx_rf_ble_beacon_process: Channel=%d, " + "Error advertising\n", j); + /* Break the loop, but don't return just yet */ + break; + } + } + } + + /* Send a CMD_STOP command to RF Core */ + if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_STOP), &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("cc26xx_rf_ble_beacon_process: status=0x%08lx\n", cmd_status); + /* Continue... */ + } + + if(was_on) { + /* We were on, go back to previous primary mode */ + rf_core_primary_mode_restore(); + } else { + /* We were off. Shut back off */ + rf_core_power_down(); + + /* Switch HF clock source to the RCOSC to preserve power */ + oscillators_switch_to_hf_rc(); + } + etimer_set(&ble_adv_et, BLE_ADV_DUTY_CYCLE); + + interrupts_disabled = ti_lib_int_master_disable(); + + ble_mode_on = RF_BLE_IDLE; + + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } + + /* Wait unless this is the last burst */ + if(i < BLE_ADV_MESSAGES - 1) { + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&ble_adv_et)); + } + } + + interrupts_disabled = ti_lib_int_master_disable(); + + ble_mode_on = RF_BLE_IDLE; + + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-ble.h b/cpu/cc26xx-cc13xx/rf-core/rf-ble.h new file mode 100644 index 000000000..f26bd383e --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/rf-ble.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup rf-core + * @{ + * + * \defgroup rf-core-ble CC13xx/CC26xx BLE driver + * + * @{ + * + * \file + * Header file for the CC13xx/CC26xx BLE driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef RF_BLE_H_ +#define RF_BLE_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "rf-core/rf-core.h" + +#include +/*---------------------------------------------------------------------------*/ +#ifdef RF_BLE_CONF_ENABLED +#define RF_BLE_ENABLED RF_BLE_CONF_ENABLED +#else +#define RF_BLE_ENABLED 1 +#endif +/*---------------------------------------------------------------------------*/ +#define RF_BLE_IDLE 0 +#define RF_BLE_ACTIVE 1 +/*---------------------------------------------------------------------------*/ +/** + * \brief Set the device name to use with the BLE advertisement/beacon daemon + * \param interval The interval (ticks) between two consecutive beacon bursts + * \param name The device name to advertise + * + * If name is NULL it will be ignored. If interval==0 it will be ignored. Thus, + * this function can be used to configure a single parameter at a time if so + * desired. + */ +void rf_ble_beacond_config(clock_time_t interval, const char *name); + +/** + * \brief Start the BLE advertisement/beacon daemon + * \return RF_CORE_CMD_OK: Success, RF_CORE_CMD_ERROR: Failure + * + * Before calling this function, the name to advertise must first be set by + * calling rf_ble_beacond_config(). Otherwise, this function will return an + * error. + */ +uint8_t rf_ble_beacond_start(void); + +/** + * \brief Stop the BLE advertisement/beacon daemon + */ +void rf_ble_beacond_stop(void); + +/** + * \brief Check whether the BLE beacond is currently active + * \retval 1 The radio is in BLE mode + * \retval 0 The BLE daemon is not active, or disabled + */ +uint8_t rf_ble_is_active(void); +/*---------------------------------------------------------------------------*/ +#endif /* RF_BLE_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.c b/cpu/cc26xx-cc13xx/rf-core/rf-core.c new file mode 100644 index 000000000..15fc8e3bc --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.c @@ -0,0 +1,624 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup rf-core + * @{ + * + * \file + * Implementation of the CC13xx/CC26xx RF core driver + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "dev/watchdog.h" +#include "sys/process.h" +#include "sys/energest.h" +#include "sys/cc.h" +#include "net/netstack.h" +#include "net/packetbuf.h" +#include "net/rime/rimestats.h" +#include "rf-core/rf-core.h" +#include "ti-lib.h" +/*---------------------------------------------------------------------------*/ +/* RF core and RF HAL API */ +#include "hw_rfc_dbell.h" +#include "hw_rfc_pwr.h" +/*---------------------------------------------------------------------------*/ +/* RF Core Mailbox API */ +#include "rf-core/api/mailbox.h" +#include "rf-core/api/common_cmd.h" +#include "rf-core/api/ble_cmd.h" +#include "rf-core/api/ieee_cmd.h" +#include "rf-core/api/data_entry.h" +#include "rf-core/api/ble_mailbox.h" +#include "rf-core/api/ieee_mailbox.h" +#include "rf-core/api/prop_mailbox.h" +#include "rf-core/api/prop_cmd.h" +/*---------------------------------------------------------------------------*/ +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +#ifdef RF_CORE_CONF_DEBUG_CRC +#define RF_CORE_DEBUG_CRC RF_CORE_CONF_DEBUG_CRC +#else +#define RF_CORE_DEBUG_CRC DEBUG +#endif +/*---------------------------------------------------------------------------*/ +/* RF interrupts */ +#define RX_FRAME_IRQ IRQ_RX_ENTRY_DONE +#define ERROR_IRQ IRQ_INTERNAL_ERROR +#define RX_NOK_IRQ IRQ_RX_NOK + +/* Those IRQs are enabled all the time */ +#if RF_CORE_DEBUG_CRC +#define ENABLED_IRQS (RX_FRAME_IRQ | ERROR_IRQ | RX_NOK_IRQ) +#else +#define ENABLED_IRQS (RX_FRAME_IRQ | ERROR_IRQ) +#endif + +#define ENABLED_IRQS_POLL_MODE (ENABLED_IRQS & ~(RX_FRAME_IRQ | ERROR_IRQ)) + +#define cc26xx_rf_cpe0_isr RFCCPE0IntHandler +#define cc26xx_rf_cpe1_isr RFCCPE1IntHandler +/*---------------------------------------------------------------------------*/ +/* Remember the last Radio Op issued to the radio */ +static rfc_radioOp_t *last_radio_op = NULL; +/*---------------------------------------------------------------------------*/ +/* A struct holding pointers to the primary mode's abort() and restore() */ +static const rf_core_primary_mode_t *primary_mode = NULL; +/*---------------------------------------------------------------------------*/ +/* Radio timer (RAT) offset as compared to the rtimer counter (RTC) */ +int32_t rat_offset = 0; +static bool rat_offset_known = false; +/*---------------------------------------------------------------------------*/ +PROCESS(rf_core_process, "CC13xx / CC26xx RF driver"); +/*---------------------------------------------------------------------------*/ +#define RF_CORE_CLOCKS_MASK (RFC_PWR_PWMCLKEN_RFC_M | RFC_PWR_PWMCLKEN_CPE_M \ + | RFC_PWR_PWMCLKEN_CPERAM_M) +/*---------------------------------------------------------------------------*/ +uint8_t +rf_core_is_accessible() +{ + if(ti_lib_prcm_rf_ready()) { + return RF_CORE_ACCESSIBLE; + } + return RF_CORE_NOT_ACCESSIBLE; +} +/*---------------------------------------------------------------------------*/ +uint_fast8_t +rf_core_send_cmd(uint32_t cmd, uint32_t *status) +{ + uint32_t timeout_count = 0; + bool interrupts_disabled; + bool is_radio_op = false; + + /* + * If cmd is 4-byte aligned, then it's either a radio OP or an immediate + * command. Clear the status field if it's a radio OP + */ + if((cmd & 0x03) == 0) { + uint32_t cmd_type; + cmd_type = ((rfc_command_t *)cmd)->commandNo & RF_CORE_COMMAND_TYPE_MASK; + if(cmd_type == RF_CORE_COMMAND_TYPE_IEEE_FG_RADIO_OP || + cmd_type == RF_CORE_COMMAND_TYPE_RADIO_OP) { + is_radio_op = true; + ((rfc_radioOp_t *)cmd)->status = RF_CORE_RADIO_OP_STATUS_IDLE; + } + } + + /* + * Make sure ContikiMAC doesn't turn us off from within an interrupt while + * we are accessing RF Core registers + */ + interrupts_disabled = ti_lib_int_master_disable(); + + if(!rf_core_is_accessible()) { + PRINTF("rf_core_send_cmd: RF was off\n"); + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } + return RF_CORE_CMD_ERROR; + } + + if(is_radio_op) { + uint16_t command_no = ((rfc_radioOp_t *)cmd)->commandNo; + if((command_no & RF_CORE_COMMAND_PROTOCOL_MASK) != RF_CORE_COMMAND_PROTOCOL_COMMON && + (command_no & RF_CORE_COMMAND_TYPE_MASK) == RF_CORE_COMMAND_TYPE_RADIO_OP) { + last_radio_op = (rfc_radioOp_t *)cmd; + } + } + + HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDR) = cmd; + do { + *status = HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDSTA); + if(++timeout_count > 50000) { + PRINTF("rf_core_send_cmd: 0x%08lx Timeout\n", cmd); + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } + return RF_CORE_CMD_ERROR; + } + } while((*status & RF_CORE_CMDSTA_RESULT_MASK) == RF_CORE_CMDSTA_PENDING); + + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } + + /* + * If we reach here the command is no longer pending. It is either completed + * successfully or with error + */ + return (*status & RF_CORE_CMDSTA_RESULT_MASK) == RF_CORE_CMDSTA_DONE; +} +/*---------------------------------------------------------------------------*/ +uint_fast8_t +rf_core_wait_cmd_done(void *cmd) +{ + volatile rfc_radioOp_t *command = (rfc_radioOp_t *)cmd; + uint32_t timeout_cnt = 0; + + /* + * 0xn4nn=DONE, 0x0400=DONE_OK while all other "DONE" values means done + * but with some kind of error (ref. "Common radio operation status codes") + */ + do { + if(++timeout_cnt > 500000) { + return RF_CORE_CMD_ERROR; + } + } while((command->status & RF_CORE_RADIO_OP_MASKED_STATUS) + != RF_CORE_RADIO_OP_MASKED_STATUS_DONE); + + return (command->status & RF_CORE_RADIO_OP_MASKED_STATUS) + == RF_CORE_RADIO_OP_STATUS_DONE_OK; +} +/*---------------------------------------------------------------------------*/ +static int +fs_powerdown(void) +{ + rfc_CMD_FS_POWERDOWN_t cmd; + uint32_t cmd_status; + + rf_core_init_radio_op((rfc_radioOp_t *)&cmd, sizeof(cmd), CMD_FS_POWERDOWN); + + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("fs_powerdown: CMDSTA=0x%08lx\n", cmd_status); + return RF_CORE_CMD_ERROR; + } + + if(rf_core_wait_cmd_done(&cmd) != RF_CORE_CMD_OK) { + PRINTF("fs_powerdown: CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd.status); + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +int +rf_core_power_up() +{ + uint32_t cmd_status; + bool interrupts_disabled = ti_lib_int_master_disable(); + + ti_lib_int_pend_clear(INT_RF_CPE0); + ti_lib_int_pend_clear(INT_RF_CPE1); + ti_lib_int_disable(INT_RF_CPE0); + ti_lib_int_disable(INT_RF_CPE1); + + /* Enable RF Core power domain */ + ti_lib_prcm_power_domain_on(PRCM_DOMAIN_RFCORE); + while(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_RFCORE) + != PRCM_DOMAIN_POWER_ON); + + ti_lib_prcm_domain_enable(PRCM_DOMAIN_RFCORE); + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = 0x0; + ti_lib_int_enable(INT_RF_CPE0); + ti_lib_int_enable(INT_RF_CPE1); + + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } + + /* Let CPE boot */ + HWREG(RFC_PWR_NONBUF_BASE + RFC_PWR_O_PWMCLKEN) = RF_CORE_CLOCKS_MASK; + + /* Send ping (to verify RFCore is ready and alive) */ + if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_PING), &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("rf_core_power_up: CMD_PING fail, CMDSTA=0x%08lx\n", cmd_status); + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +uint8_t +rf_core_start_rat(void) +{ + uint32_t cmd_status; + rfc_CMD_SYNC_START_RAT_t cmd_start; + + /* Start radio timer (RAT) */ + rf_core_init_radio_op((rfc_radioOp_t *)&cmd_start, sizeof(cmd_start), CMD_SYNC_START_RAT); + + /* copy the value and send back */ + cmd_start.rat0 = rat_offset; + + if(rf_core_send_cmd((uint32_t)&cmd_start, &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("rf_core_get_rat_rtc_offset: SYNC_START_RAT fail, CMDSTA=0x%08lx\n", + cmd_status); + return RF_CORE_CMD_ERROR; + } + + /* Wait until done (?) */ + if(rf_core_wait_cmd_done(&cmd_start) != RF_CORE_CMD_OK) { + PRINTF("rf_core_cmd_ok: SYNC_START_RAT wait, CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd_start.status); + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +uint8_t +rf_core_stop_rat(void) +{ + rfc_CMD_SYNC_STOP_RAT_t cmd_stop; + uint32_t cmd_status; + + rf_core_init_radio_op((rfc_radioOp_t *)&cmd_stop, sizeof(cmd_stop), CMD_SYNC_STOP_RAT); + + int ret = rf_core_send_cmd((uint32_t)&cmd_stop, &cmd_status); + if(ret != RF_CORE_CMD_OK) { + PRINTF("rf_core_get_rat_rtc_offset: SYNC_STOP_RAT fail, ret %d CMDSTA=0x%08lx\n", + ret, cmd_status); + return ret; + } + + /* Wait until done */ + ret = rf_core_wait_cmd_done(&cmd_stop); + if(ret != RF_CORE_CMD_OK) { + PRINTF("rf_core_cmd_ok: SYNC_STOP_RAT wait, CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd_stop.status); + return ret; + } + + if(!rat_offset_known) { + /* save the offset, but only if this is the first time */ + rat_offset_known = true; + rat_offset = cmd_stop.rat0; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +void +rf_core_power_down() +{ + bool interrupts_disabled = ti_lib_int_master_disable(); + ti_lib_int_disable(INT_RF_CPE0); + ti_lib_int_disable(INT_RF_CPE1); + + if(rf_core_is_accessible()) { + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = 0x0; + + /* need to send FS_POWERDOWN or analog components will use power */ + fs_powerdown(); + } + + rf_core_stop_rat(); + + /* Shut down the RFCORE clock domain in the MCU VD */ + ti_lib_prcm_domain_disable(PRCM_DOMAIN_RFCORE); + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + /* Turn off RFCORE PD */ + ti_lib_prcm_power_domain_off(PRCM_DOMAIN_RFCORE); + while(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_RFCORE) + != PRCM_DOMAIN_POWER_OFF); + + ti_lib_int_pend_clear(INT_RF_CPE0); + ti_lib_int_pend_clear(INT_RF_CPE1); + ti_lib_int_enable(INT_RF_CPE0); + ti_lib_int_enable(INT_RF_CPE1); + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } +} +/*---------------------------------------------------------------------------*/ +uint8_t +rf_core_set_modesel() +{ + uint8_t rv = RF_CORE_CMD_ERROR; + + if(ti_lib_chipinfo_chip_family_is_cc26xx()) { + if(ti_lib_chipinfo_supports_ble() == true && + ti_lib_chipinfo_supports_ieee_802_15_4() == true) { + /* CC2650 */ + HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE5; + rv = RF_CORE_CMD_OK; + } else if(ti_lib_chipinfo_supports_ble() == false && + ti_lib_chipinfo_supports_ieee_802_15_4() == true) { + /* CC2630 */ + HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE2; + rv = RF_CORE_CMD_OK; + } + } else if(ti_lib_chipinfo_chip_family_is_cc13xx()) { + if(ti_lib_chipinfo_supports_ble() == false && + ti_lib_chipinfo_supports_ieee_802_15_4() == false) { + /* CC1310 */ + HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE3; + rv = RF_CORE_CMD_OK; + } + } + + return rv; +} +/*---------------------------------------------------------------------------*/ +uint8_t +rf_core_boot() +{ + if(rf_core_power_up() != RF_CORE_CMD_OK) { + PRINTF("rf_core_boot: rf_core_power_up() failed\n"); + + rf_core_power_down(); + + return RF_CORE_CMD_ERROR; + } + + if(rf_core_start_rat() != RF_CORE_CMD_OK) { + PRINTF("rf_core_boot: rf_core_start_rat() failed\n"); + + rf_core_power_down(); + + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +uint8_t +rf_core_restart_rat(void) +{ + if(rf_core_stop_rat() != RF_CORE_CMD_OK) { + PRINTF("rf_core_restart_rat: rf_core_stop_rat() failed\n"); + + return RF_CORE_CMD_ERROR; + } + + if(rf_core_start_rat() != RF_CORE_CMD_OK) { + PRINTF("rf_core_restart_rat: rf_core_start_rat() failed\n"); + + rf_core_power_down(); + + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +void +rf_core_setup_interrupts(bool poll_mode) +{ + bool interrupts_disabled; + const uint32_t enabled_irqs = poll_mode ? ENABLED_IRQS_POLL_MODE : ENABLED_IRQS; + + /* We are already turned on by the caller, so this should not happen */ + if(!rf_core_is_accessible()) { + PRINTF("setup_interrupts: No access\n"); + return; + } + + /* Disable interrupts */ + interrupts_disabled = ti_lib_int_master_disable(); + + /* Set all interrupt channels to CPE0 channel, error to CPE1 */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEISL) = ERROR_IRQ; + + /* Acknowledge configured interrupts */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = enabled_irqs; + + /* Clear interrupt flags, active low clear(?) */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; + + ti_lib_int_pend_clear(INT_RF_CPE0); + ti_lib_int_pend_clear(INT_RF_CPE1); + ti_lib_int_enable(INT_RF_CPE0); + ti_lib_int_enable(INT_RF_CPE1); + + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } +} +/*---------------------------------------------------------------------------*/ +void +rf_core_cmd_done_en(bool fg, bool poll_mode) +{ + uint32_t irq = fg ? IRQ_LAST_FG_COMMAND_DONE : IRQ_LAST_COMMAND_DONE; + const uint32_t enabled_irqs = poll_mode ? ENABLED_IRQS_POLL_MODE : ENABLED_IRQS; + + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = enabled_irqs; + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = enabled_irqs | irq; +} +/*---------------------------------------------------------------------------*/ +void +rf_core_cmd_done_dis(bool poll_mode) +{ + const uint32_t enabled_irqs = poll_mode ? ENABLED_IRQS_POLL_MODE : ENABLED_IRQS; + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = enabled_irqs; +} +/*---------------------------------------------------------------------------*/ +rfc_radioOp_t * +rf_core_get_last_radio_op() +{ + return last_radio_op; +} +/*---------------------------------------------------------------------------*/ +void +rf_core_init_radio_op(rfc_radioOp_t *op, uint16_t len, uint16_t command) +{ + memset(op, 0, len); + + op->commandNo = command; + op->condition.rule = COND_NEVER; +} +/*---------------------------------------------------------------------------*/ +void +rf_core_primary_mode_register(const rf_core_primary_mode_t *mode) +{ + primary_mode = mode; +} +/*---------------------------------------------------------------------------*/ +void +rf_core_primary_mode_abort() +{ + if(primary_mode) { + if(primary_mode->abort) { + primary_mode->abort(); + } + } +} +/*---------------------------------------------------------------------------*/ +uint8_t +rf_core_primary_mode_restore() +{ + if(primary_mode) { + if(primary_mode->restore) { + return primary_mode->restore(); + } + } + + return RF_CORE_CMD_ERROR; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(rf_core_process, ev, data) +{ + int len; + + PROCESS_BEGIN(); + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + do { + watchdog_periodic(); + packetbuf_clear(); + len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE); + + if(len > 0) { + packetbuf_set_datalen(len); + + NETSTACK_RDC.input(); + } + } while(len > 0); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +static void +rx_nok_isr(void) +{ + RIMESTATS_ADD(badcrc); + PRINTF("RF: Bad CRC\n"); +} +/*---------------------------------------------------------------------------*/ +void +cc26xx_rf_cpe1_isr(void) +{ + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + PRINTF("RF Error\n"); + + if(!rf_core_is_accessible()) { + if(rf_core_power_up() != RF_CORE_CMD_OK) { + return; + } + } + + /* Clear INTERNAL_ERROR interrupt flag */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x7FFFFFFF; + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +void +cc26xx_rf_cpe0_isr(void) +{ + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + if(!rf_core_is_accessible()) { + printf("RF ISR called but RF not ready... PANIC!!\n"); + if(rf_core_power_up() != RF_CORE_CMD_OK) { + PRINTF("rf_core_power_up() failed\n"); + return; + } + } + + ti_lib_int_master_disable(); + + if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & RX_FRAME_IRQ) { + /* Clear the RX_ENTRY_DONE interrupt flag */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFF7FFFFF; + process_poll(&rf_core_process); + } + + if(RF_CORE_DEBUG_CRC) { + if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & RX_NOK_IRQ) { + /* Clear the RX_NOK interrupt flag */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFFFDFFFF; + rx_nok_isr(); + } + } + + if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & + (IRQ_LAST_FG_COMMAND_DONE | IRQ_LAST_COMMAND_DONE)) { + /* Clear the two TX-related interrupt flags */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFFFFFFF5; + } + + ti_lib_int_master_enable(); + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.h b/cpu/cc26xx-cc13xx/rf-core/rf-core.h new file mode 100644 index 000000000..474de4a87 --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.h @@ -0,0 +1,441 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx + * @{ + * + * \defgroup rf-core CC13xx/CC26xx RF core + * + * Different flavours of chips of the CC13xx/CC26xx family have different + * radio capability. For example, the CC2650 can operate in IEEE 802.15.4 mode + * at 2.4GHz, but it can also operate in BLE mode. The CC1310 only supports + * sub-ghz mode. + * + * However, there are many radio functionalities that are identical across + * all chips. The rf-core driver provides support for this common functionality + * + * @{ + * + * \file + * Header file for the CC13xx/CC26xx RF core driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef RF_CORE_H_ +#define RF_CORE_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "rf-core/api/common_cmd.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/* The channel to use in IEEE or prop mode. */ +#ifdef RF_CORE_CONF_CHANNEL +#define RF_CORE_CHANNEL RF_CORE_CONF_CHANNEL +#else +#define RF_CORE_CHANNEL 25 +#endif /* RF_CORE_CONF_IEEE_MODE_CHANNEL */ +/*---------------------------------------------------------------------------*/ +#define RF_CORE_CMD_ERROR 0 +#define RF_CORE_CMD_OK 1 +/*---------------------------------------------------------------------------*/ +/** + * \brief A data strcuture representing the radio's primary mode of operation + * + * The CC13xx / CC26xx radio supports up to potentially 3 modes: IEEE, Prop and + * BLE. Within Contiki, we assume that the radio is by default in one of IEEE + * or Prop in order to support standard 6LoWPAN / .15.4 operation. The BLE + * mode interrupts this so called "primary" mode in order to send BLE adv + * messages. Once BLE is done advertising, we need to be able to restore the + * previous .15.4 mode. Unfortunately, the only way this can be done with + * NETSTACK_RADIO API is by fully power-cycling the radio, which is something + * we do not want to do. + * + * Thus, we declare a secondary data structure for primary mode drivers (IEEE + * or Prop). We use this data structure to issue "soft off" and "back on" + * commands. Soft off in this context means stopping RX (e.g. the respective + * IEEE RX operation), but without shutting down the RF core (which is what + * NETSTACK_RADIO.off() would have done). We then remember what mode we were + * using in order to be able to re-enter RX mode for this mode. + * + * A NETSTACK_RADIO driver will declare those two functions somewhere within + * its module of implementation. During its init() routine, it will notify + * the RF core module so that the latter can abort and restore operations. + */ +typedef struct rf_core_primary_mode_s { + /** + * \brief A pointer to a function used to abort the current radio op + */ + void (*abort)(void); + + /** + * \brief A pointer to a function that will restore the previous radio op + * \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR + */ + uint8_t (*restore)(void); +} rf_core_primary_mode_t; +/*---------------------------------------------------------------------------*/ +/* RF Command status constants - Correspond to values in the CMDSTA register */ +#define RF_CORE_CMDSTA_PENDING 0x00 +#define RF_CORE_CMDSTA_DONE 0x01 +#define RF_CORE_CMDSTA_ILLEGAL_PTR 0x81 +#define RF_CORE_CMDSTA_UNKNOWN_CMD 0x82 +#define RF_CORE_CMDSTA_UNKNOWN_DIR_CMD 0x83 +#define RF_CORE_CMDSTA_CONTEXT_ERR 0x85 +#define RF_CORE_CMDSTA_SCHEDULING_ERR 0x86 +#define RF_CORE_CMDSTA_PAR_ERR 0x87 +#define RF_CORE_CMDSTA_QUEUE_ERR 0x88 +#define RF_CORE_CMDSTA_QUEUE_BUSY 0x89 + +/* Status values starting with 0x8 correspond to errors */ +#define RF_CORE_CMDSTA_ERR_MASK 0x80 + +/* CMDSTA is 32-bits. Return value in bits 7:0 */ +#define RF_CORE_CMDSTA_RESULT_MASK 0xFF + +#define RF_CORE_RADIO_OP_STATUS_IDLE 0x0000 +/*---------------------------------------------------------------------------*/ +#define RF_CORE_NOT_ACCESSIBLE 0x00 +#define RF_CORE_ACCESSIBLE 0x01 +/*---------------------------------------------------------------------------*/ +/* RF Radio Op status constants. Field 'status' in Radio Op command struct */ +#define RF_CORE_RADIO_OP_STATUS_IDLE 0x0000 +#define RF_CORE_RADIO_OP_STATUS_PENDING 0x0001 +#define RF_CORE_RADIO_OP_STATUS_ACTIVE 0x0002 +#define RF_CORE_RADIO_OP_STATUS_SKIPPED 0x0003 +#define RF_CORE_RADIO_OP_STATUS_DONE_OK 0x0400 +#define RF_CORE_RADIO_OP_STATUS_DONE_COUNTDOWN 0x0401 +#define RF_CORE_RADIO_OP_STATUS_DONE_RXERR 0x0402 +#define RF_CORE_RADIO_OP_STATUS_DONE_TIMEOUT 0x0403 +#define RF_CORE_RADIO_OP_STATUS_DONE_STOPPED 0x0404 +#define RF_CORE_RADIO_OP_STATUS_DONE_ABORT 0x0405 +#define RF_CORE_RADIO_OP_STATUS_ERROR_PAST_START 0x0800 +#define RF_CORE_RADIO_OP_STATUS_ERROR_START_TRIG 0x0801 +#define RF_CORE_RADIO_OP_STATUS_ERROR_CONDITION 0x0802 +#define RF_CORE_RADIO_OP_STATUS_ERROR_PAR 0x0803 +#define RF_CORE_RADIO_OP_STATUS_ERROR_POINTER 0x0804 +#define RF_CORE_RADIO_OP_STATUS_ERROR_CMDID 0x0805 +#define RF_CORE_RADIO_OP_STATUS_ERROR_NO_SETUP 0x0807 +#define RF_CORE_RADIO_OP_STATUS_ERROR_NO_FS 0x0808 +#define RF_CORE_RADIO_OP_STATUS_ERROR_SYNTH_PROG 0x0809 + +/* Additional Op status values for IEEE mode */ +#define RF_CORE_RADIO_OP_STATUS_IEEE_SUSPENDED 0x2001 +#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_OK 0x2400 +#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_BUSY 0x2401 +#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_STOPPED 0x2402 +#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_ACK 0x2403 +#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_ACKPEND 0x2404 +#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_TIMEOUT 0x2405 +#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_BGEND 0x2406 +#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_ABORT 0x2407 +#define RF_CORE_RADIO_OP_STATUS_ERROR_WRONG_BG 0x0806 +#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_PAR 0x2800 +#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_NO_SETUP 0x2801 +#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_NO_FS 0x2802 +#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_SYNTH_PROG 0x2803 +#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_RXOVF 0x2804 +#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_TXUNF 0x2805 + +/* Op status values for BLE mode */ +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_OK 0x1400 +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_RXTIMEOUT 0x1401 +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_NOSYNC 0x1402 +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_RXERR 0x1403 +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_CONNECT 0x1404 +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_MAXNACK 0x1405 +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_ENDED 0x1406 +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_ABORT 0x1407 +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_STOPPED 0x1408 +#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_PAR 0x1800 +#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_RXBUF 0x1801 +#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_NO_SETUP 0x1802 +#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_NO_FS 0x1803 +#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_SYNTH_PROG 0x1804 +#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_RXOVF 0x1805 +#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_TXUNF 0x1806 + +/* Op status values for proprietary mode */ +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_OK 0x3400 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_RXTIMEOUT 0x3401 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_BREAK 0x3402 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_ENDED 0x3403 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_STOPPED 0x3404 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_ABORT 0x3405 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_RXERR 0x3406 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_IDLE 0x3407 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_BUSY 0x3408 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_IDLETIMEOUT 0x3409 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_BUSYTIMEOUT 0x340A +#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_PAR 0x3800 +#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_RXBUF 0x3801 +#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_RXFULL 0x3802 +#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_NO_SETUP 0x3803 +#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_NO_FS 0x3804 +#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_RXOVF 0x3805 +#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_TXUNF 0x3806 + +/* Bits 15:12 signify the protocol */ +#define RF_CORE_RADIO_OP_STATUS_PROTO_MASK 0xF000 +#define RF_CORE_RADIO_OP_STATUS_PROTO_GENERIC 0x0000 +#define RF_CORE_RADIO_OP_STATUS_PROTO_BLE 0x1000 +#define RF_CORE_RADIO_OP_STATUS_PROTO_IEEE 0x2000 +#define RF_CORE_RADIO_OP_STATUS_PROTO_PROP 0x3000 + +/* Bits 11:10 signify Running / Done OK / Done with error */ +#define RF_CORE_RADIO_OP_MASKED_STATUS 0x0C00 +#define RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING 0x0000 +#define RF_CORE_RADIO_OP_MASKED_STATUS_DONE 0x0400 +#define RF_CORE_RADIO_OP_MASKED_STATUS_ERROR 0x0800 +/*---------------------------------------------------------------------------*/ +/* Command Types */ +#define RF_CORE_COMMAND_TYPE_MASK 0x0C00 +#define RF_CORE_COMMAND_TYPE_RADIO_OP 0x0800 +#define RF_CORE_COMMAND_TYPE_IEEE_BG_RADIO_OP 0x0800 +#define RF_CORE_COMMAND_TYPE_IEEE_FG_RADIO_OP 0x0C00 + +#define RF_CORE_COMMAND_PROTOCOL_MASK 0x3000 +#define RF_CORE_COMMAND_PROTOCOL_COMMON 0x0000 +#define RF_CORE_COMMAND_PROTOCOL_BLE 0x1000 +#define RF_CORE_COMMAND_PROTOCOL_IEEE 0x2000 +#define RF_CORE_COMMAND_PROTOCOL_PROP 0x3000 +/*---------------------------------------------------------------------------*/ +/* Radio timer register */ +#define RATCNT 0x00000004 +/*---------------------------------------------------------------------------*/ +/* Make the main driver process visible to mode drivers */ +PROCESS_NAME(rf_core_process); +/*---------------------------------------------------------------------------*/ +/** + * \brief Check whether the RF core is accessible + * \retval RF_CORE_ACCESSIBLE The core is powered and ready for access + * \retval RF_CORE_NOT_ACCESSIBLE The core is not ready + * + * If this function returns RF_CORE_NOT_ACCESSIBLE, rf_core_power_up() must be + * called before any attempt to access the core. + */ +uint8_t rf_core_is_accessible(void); + +/** + * \brief Sends a command to the RF core. + * + * \param cmd The command value or a pointer to a command buffer + * \param status A pointer to a variable which will hold the status + * \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR + * + * This function supports all three types of command (Radio OP, immediate and + * direct) + * + * For immediate and Radio OPs, cmd is a pointer to the data structure + * containing the command and its parameters. This data structure must be + * 4-byte aligned. + * + * For direct commands, cmd contains the value of the command alongside its + * parameters. This value will be written to CMDSTA verbatim, so the command + * ID must be in the 16 high bits, and the 2 LS bits must be set to 01 by the + * caller. + * + * The caller is responsible of allocating and populating cmd for Radio OP and + * immediate commands + * + * The caller is responsible for allocating status + * + * For immediate commands and radio Ops, this function will set the command's + * status field to RF_CORE_RADIO_OP_STATUS_IDLE before sending it to the RF + */ +uint_fast8_t rf_core_send_cmd(uint32_t cmd, uint32_t *status); + +/** + * \brief Block and wait for a Radio op to complete + * \param cmd A pointer to any command's structure + * \retval RF_CORE_CMD_OK the command completed with status _DONE_OK + * \retval RF_CORE_CMD_ERROR Timeout exceeded or the command completed with + * status _DONE_xxx (e.g. RF_CORE_RADIO_OP_STATUS_DONE_TIMEOUT) + */ +uint_fast8_t rf_core_wait_cmd_done(void *cmd); + +/** + * \brief Turn on power to the RFC and boot it. + * \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR + */ +int rf_core_power_up(void); + +/** + * \brief Disable RFCORE clock domain in the MCU VD and turn off the RFCORE PD + */ +void rf_core_power_down(void); + +/** + * \brief Initialise RF APIs in the RF core + * \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR + * + * Depending on chip family and capability, this function will set the correct + * value to PRCM.RFCMODESEL + */ +uint8_t rf_core_set_modesel(void); + +/** + * \brief Start the CM0 RAT + * \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR + * + * This function must be called each time the CM0 boots. The boot sequence + * can be performed automatically by calling rf_core_boot() if patches are not + * required. If patches are required then the patches must be applied after + * power up and before calling this function. + */ +uint8_t rf_core_start_rat(void); + +/** + * \brief Stop the CM0 RAT synchronously + * \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR + * + * This function is not strictly necessary, but through calling it it's possibly + * to learn the RAT / RTC offset, which useful to get accurate radio timestamps. + */ +uint8_t rf_core_stop_rat(void); + +/** + * \brief Restart the CM0 RAT + * \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR + * + * This function restarts the CM0 RAT and therefore resynchornizes it with RTC. + * To achieve good timing accuracy, it should be called periodically. + */ +uint8_t rf_core_restart_rat(void); + +/** + * \brief Boot the RF Core + * \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR + * + * This function will perform the CM0 boot sequence. It will first power it up + * and then start the RAT. If a patch is required, then the mode driver must + * not call this function and perform the sequence manually, applying patches + * after boot and before calling rf_core_start_rat(). + * + * The function will return RF_CORE_CMD_ERROR if any of those steps fails. If + * the boot sequence fails to complete, the RF Core will be powered down. + */ +uint8_t rf_core_boot(void); + +/** + * \brief Setup RF core interrupts + */ +void rf_core_setup_interrupts(bool poll_mode); + +/** + * \brief Enable interrupt on command done. + * \param fg set true to enable irq on foreground command done and false for + * background commands or if not in ieee mode. + * \param poll_mode true if the driver is in poll mode + * + * This is used within TX routines in order to be able to sleep the CM3 and + * wake up after TX has finished + * + * \sa rf_core_cmd_done_dis() + */ +void rf_core_cmd_done_en(bool fg, bool poll_mode); + +/** + * \brief Disable the LAST_CMD_DONE and LAST_FG_CMD_DONE interrupts. + * + * This is used within TX routines after TX has completed + * + * \sa rf_core_cmd_done_en() + */ +void rf_core_cmd_done_dis(bool poll_mode); + +/** + * \brief Returns a pointer to the most recent proto-dependent Radio Op + * \return The pointer + * + * The RF Core driver will remember the most recent proto-dependent Radio OP + * issued, so that other modules can inspect its type and state at a subsequent + * stage. The assumption is that those commands will be issued by a function + * that will then return. The following commands will be "remembered" + * + * - All BLE Radio Ops (0x18nn) + * - All Prop Radio Ops (0x38nn) + * - IEEE BG Radio Ops (0x28nn) + * + * The following commands are assumed to be executed synchronously and will + * thus not be remembered by the core and not returned by this function: + * + * - Direct commands + * - Proto-independent commands (including Radio Ops and Immediate ones) + * - IEEE FG Radio Ops (0x2Cxx) + * + * This assumes that all commands will be sent to the radio using + * rf_core_send_cmd() + */ +rfc_radioOp_t *rf_core_get_last_radio_op(void); + +/** + * \brief Prepare a buffer to host a Radio Op + * \param buf A pointer to the buffer that will host the Radio Op + * \param len The buffer's length + * \param command The command ID + * + * The caller is responsible to allocate the buffer + * + * This function will not check whether the buffer is large enough to hold the + * command. This is the caller's responsibility + * + * This function will wipe out the buffer's contents. + */ +void rf_core_init_radio_op(rfc_radioOp_t *buf, uint16_t len, uint16_t command); + +/** + * \brief Register a primary mode for radio operation + * \param mode A pointer to the struct representing the mode + * + * A normal NESTACK_RADIO driver will normally register itself by calling + * this function during its own init(). + * + * \sa rf_core_primary_mode_t + */ +void rf_core_primary_mode_register(const rf_core_primary_mode_t *mode); + +/** + * \brief Abort the currently running primary radio op + */ +void rf_core_primary_mode_abort(void); + +/** + * \brief Abort the currently running primary radio op + */ +uint8_t rf_core_primary_mode_restore(void); +/*---------------------------------------------------------------------------*/ +#endif /* RF_CORE_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/rf-core/smartrf-settings.c b/cpu/cc26xx-cc13xx/rf-core/smartrf-settings.c new file mode 100644 index 000000000..8eedf23cb --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/smartrf-settings.c @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +#include "rf-core/api/mailbox.h" +#include "rf-core/api/common_cmd.h" +#include "rf-core/api/prop_cmd.h" +/*---------------------------------------------------------------------------*/ +/* Overrides for CMD_PROP_RADIO_DIV_SETUP */ +uint32_t overrides[] = +{ + /* override_synth.xml */ + HW32_ARRAY_OVERRIDE(0x6088, 1), + (uint32_t)0x0000001A, + ADI_HALFREG_OVERRIDE(0, 61, 0xF, 0xD), + HW32_ARRAY_OVERRIDE(0x4038, 1), + (uint32_t)0x0000003A, + HW_REG_OVERRIDE(0x4020, 0x7F00), + HW_REG_OVERRIDE(0x4064, 0x0040), + (uint32_t)0x684A3, + (uint32_t)0xC0040141, + (uint32_t)0x0533B107, + (uint32_t)0xA480583, + (uint32_t)0x7AB80603, + ADI_REG_OVERRIDE(1, 4, 0x1F), + ADI_HALFREG_OVERRIDE(1, 7, 0x4, 0x4), + HW_REG_OVERRIDE(0x6084, 0x35F1), + (uint32_t)0x00038883, + (uint32_t)0x00FB88A3, + /* TX power override */ + ADI_REG_OVERRIDE(0, 12, 0xF9), + + /* Overrides for CRC16 functionality */ + (uint32_t)0x943, + (uint32_t)0x963, + + (uint32_t)0xFFFFFFFF, +}; +/*---------------------------------------------------------------------------*/ +/* CMD_PROP_RADIO_DIV_SETUP */ +rfc_CMD_PROP_RADIO_DIV_SETUP_t smartrf_settings_cmd_prop_radio_div_setup = +{ + .commandNo = 0x3807, + .status = 0x0000, + .pNextOp = 0, + .startTime = 0x00000000, + .startTrigger.triggerType = 0x0, + .startTrigger.bEnaCmd = 0x0, + .startTrigger.triggerNo = 0x0, + .startTrigger.pastTrig = 0x0, + .condition.rule = 0x1, + .condition.nSkip = 0x0, + .modulation.modType = 0x1, + .modulation.deviation = 0x64, + .symbolRate.preScale = 0xf, + .symbolRate.rateWord = 0x8000, + .rxBw = 0x24, + .preamConf.nPreamBytes = 0x3, + .preamConf.preamMode = 0x0, + .formatConf.nSwBits = 0x18, + .formatConf.bBitReversal = 0x0, + .formatConf.bMsbFirst = 0x1, + .formatConf.fecMode = 0x0, + + /* 7: .4g mode with dynamic whitening and CRC choice */ + .formatConf.whitenMode = 0x7, + .config.frontEndMode = 0x0, /* Differential mode */ + .config.biasMode = 0x1, /* External bias*/ + .config.bNoFsPowerUp = 0x0, + .txPower = 0x00, /* Driver sets correct value */ + .pRegOverride = overrides, + .intFreq = 0x8000, + .centerFreq = 868, + .loDivider = 0x05, +}; +/*---------------------------------------------------------------------------*/ +/* CMD_FS */ +rfc_CMD_FS_t smartrf_settings_cmd_fs = +{ + .commandNo = 0x0803, + .status = 0x0000, + .pNextOp = 0, + .startTime = 0x00000000, + .startTrigger.triggerType = 0x0, + .startTrigger.bEnaCmd = 0x0, + .startTrigger.triggerNo = 0x0, + .startTrigger.pastTrig = 0x0, + .condition.rule = 0x1, + .condition.nSkip = 0x0, + .frequency = 868, + .fractFreq = 0x0000, + .synthConf.bTxMode = 0x0, + .synthConf.refFreq = 0x0, + .__dummy0 = 0x00, + .midPrecal = 0x00, + .ktPrecal = 0x00, + .tdcPrecal = 0x0000, +}; +/*---------------------------------------------------------------------------*/ +/* CMD_PROP_TX_ADV */ +rfc_CMD_PROP_TX_ADV_t smartrf_settings_cmd_prop_tx_adv = +{ + .commandNo = 0x3803, + .status = 0x0000, + .pNextOp = 0, + .startTime = 0x00000000, + .startTrigger.triggerType = 0x0, + .startTrigger.bEnaCmd = 0x0, + .startTrigger.triggerNo = 0x0, + .startTrigger.pastTrig = 0x0, + .condition.rule = 0x1, + .condition.nSkip = 0x0, + .pktConf.bFsOff = 0x0, + .pktConf.bUseCrc = 0x1, + .pktConf.bCrcIncSw = 0x0, /* .4g mode */ + .pktConf.bCrcIncHdr = 0x0, /* .4g mode */ + .numHdrBits = 0x10 /* 16: .4g mode */, + .pktLen = 0x0000, + .startConf.bExtTxTrig = 0x0, + .startConf.inputMode = 0x0, + .startConf.source = 0x0, + .preTrigger.triggerType = TRIG_REL_START, + .preTrigger.bEnaCmd = 0x0, + .preTrigger.triggerNo = 0x0, + .preTrigger.pastTrig = 0x1, + .preTime = 0x00000000, + .syncWord = 0x0055904e, + .pPkt = 0, +}; +/*---------------------------------------------------------------------------*/ +/* CMD_PROP_RX_ADV */ +rfc_CMD_PROP_RX_ADV_t smartrf_settings_cmd_prop_rx_adv = +{ + .commandNo = 0x3804, + .status = 0x0000, + .pNextOp = 0, + .startTime = 0x00000000, + .startTrigger.triggerType = 0x0, + .startTrigger.bEnaCmd = 0x0, + .startTrigger.triggerNo = 0x0, + .startTrigger.pastTrig = 0x0, + .condition.rule = 0x1, + .condition.nSkip = 0x0, + .pktConf.bFsOff = 0x0, + .pktConf.bRepeatOk = 0x1, + .pktConf.bRepeatNok = 0x1, + .pktConf.bUseCrc = 0x1, + .pktConf.bCrcIncSw = 0x0, /* .4g mode */ + .pktConf.bCrcIncHdr = 0x0, /* .4g mode */ + .pktConf.endType = 0x0, + .pktConf.filterOp = 0x1, + .rxConf.bAutoFlushIgnored = 0x1, + .rxConf.bAutoFlushCrcErr = 0x1, + .rxConf.bIncludeHdr = 0x0, + .rxConf.bIncludeCrc = 0x0, + .rxConf.bAppendRssi = 0x1, + .rxConf.bAppendTimestamp = 0x0, + .rxConf.bAppendStatus = 0x1, + .syncWord0 = 0x0055904e, + .syncWord1 = 0x00000000, + .maxPktLen = 0x0000, /* To be populated by the driver. */ + .hdrConf.numHdrBits = 0x10, /* 16: .4g mode */ + .hdrConf.lenPos = 0x0, /* .4g mode */ + .hdrConf.numLenBits = 0x0B, /* 11 = 0x0B .4g mode */ + .addrConf.addrType = 0x0, + .addrConf.addrSize = 0x0, + .addrConf.addrPos = 0x0, + .addrConf.numAddr = 0x0, + .lenOffset = -4, /* .4g mode */ + .endTrigger.triggerType = TRIG_NEVER, + .endTrigger.bEnaCmd = 0x0, + .endTrigger.triggerNo = 0x0, + .endTrigger.pastTrig = 0x0, + .endTime = 0x00000000, + .pAddr = 0, + .pQueue = 0, + .pOutput = 0, +}; +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc26xx-cc13xx/rf-core/smartrf-settings.h b/cpu/cc26xx-cc13xx/rf-core/smartrf-settings.h new file mode 100644 index 000000000..bd36ed6d0 --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/smartrf-settings.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +#ifndef SMARTRF_SETTINGS_H_ +#define SMARTRF_SETTINGS_H_ +/*---------------------------------------------------------------------------*/ +#include "rf-core/api/mailbox.h" +#include "rf-core/api/common_cmd.h" +#include "rf-core/api/prop_cmd.h" +/*---------------------------------------------------------------------------*/ +extern rfc_CMD_PROP_RADIO_DIV_SETUP_t smartrf_settings_cmd_prop_radio_div_setup; +extern rfc_CMD_FS_t smartrf_settings_cmd_fs; +extern rfc_CMD_PROP_TX_ADV_t smartrf_settings_cmd_prop_tx_adv; +extern rfc_CMD_PROP_RX_ADV_t smartrf_settings_cmd_prop_rx_adv; +/*---------------------------------------------------------------------------*/ +#endif // SMARTRF_SETTINGS_H_ +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc26xx-cc13xx/rtimer-arch.c b/cpu/cc26xx-cc13xx/rtimer-arch.c new file mode 100644 index 000000000..6d0505f47 --- /dev/null +++ b/cpu/cc26xx-cc13xx/rtimer-arch.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-rtimer + * @{ + * + * \file + * Implementation of the arch-specific rtimer functions for the CC13xx/CC26xx + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sys/energest.h" +#include "sys/rtimer.h" +#include "cpu.h" +#include "dev/soc-rtc.h" + +#include "ti-lib.h" + +#include +/*---------------------------------------------------------------------------*/ +/** + * \brief We don't need to do anything special here. The RTC is initialised + * elsewhere + */ +void +rtimer_arch_init(void) +{ + return; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Schedules an rtimer task to be triggered at time t + * \param t The time when the task will need executed. + * + * \e t is an absolute time, in other words the task will be executed AT + * time \e t, not IN \e t rtimer ticks. + * + * This function schedules a one-shot event with the AON RTC. + * + * This functions converts \e to a value suitable for the AON RTC. + */ +void +rtimer_arch_schedule(rtimer_clock_t t) +{ + /* Convert the rtimer tick value to a value suitable for the AON RTC */ + soc_rtc_schedule_one_shot(AON_RTC_CH0, t); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns the current real-time clock time + * \return The current rtimer time in ticks + * + * The value is read from the AON RTC counter and converted to a number of + * rtimer ticks + * + */ +rtimer_clock_t +rtimer_arch_now() +{ + return ti_lib_aon_rtc_current_compare_value_get(); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/cpu/cc26xx-cc13xx/rtimer-arch.h b/cpu/cc26xx-cc13xx/rtimer-arch.h new file mode 100644 index 000000000..128461c8d --- /dev/null +++ b/cpu/cc26xx-cc13xx/rtimer-arch.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-clocks + * @{ + * + * \defgroup cc26xx-rtimer CC13xx/CC26xx rtimer + * + * Implementation of the rtimer module for the CC13xx/CC26xx + * @{ + */ +/** + * \file + * Header file for the CC13xx/CC26xx rtimer driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef RTIMER_ARCH_H_ +#define RTIMER_ARCH_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +/*---------------------------------------------------------------------------*/ +#define RTIMER_ARCH_SECOND 65536 +/*---------------------------------------------------------------------------*/ +rtimer_clock_t rtimer_arch_now(void); + +/* HW oscillator frequency is 32 kHz, not 64 kHz and RTIMER_NOW() never returns + * an odd value; so US_TO_RTIMERTICKS always rounds to the nearest even number. + */ +#define US_TO_RTIMERTICKS(US) (2 * ((US) >= 0 ? \ + (((int32_t)(US) * (RTIMER_ARCH_SECOND / 2) + 500000) / 1000000L) : \ + ((int32_t)(US) * (RTIMER_ARCH_SECOND / 2) - 500000) / 1000000L)) + +#define RTIMERTICKS_TO_US(T) ((T) >= 0 ? \ + (((int32_t)(T) * 1000000L + ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND)) : \ + ((int32_t)(T) * 1000000L - ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND)) + +/* A 64-bit version because the 32-bit one cannot handle T >= 4295 ticks. + Intended only for positive values of T. */ +#define RTIMERTICKS_TO_US_64(T) ((uint32_t)(((uint64_t)(T) * 1000000 + ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND))) +/*---------------------------------------------------------------------------*/ +#endif /* RTIMER_ARCH_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/slip-arch.c b/cpu/cc26xx-cc13xx/slip-arch.c new file mode 100644 index 000000000..c1be6849f --- /dev/null +++ b/cpu/cc26xx-cc13xx/slip-arch.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-char-io + * @{ + * + * \file + * Arch-specific SLIP functions for the CC13xx/CC26xx + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "dev/cc26xx-uart.h" +#include "dev/slip.h" +/*---------------------------------------------------------------------------*/ +/** + * \brief Write a byte over SLIP + * \param c the byte + */ +void +slip_arch_writeb(unsigned char c) +{ + cc26xx_uart_write_byte(c); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialise the arch-specific SLIP driver + * \param ubr Ignored for the cc26xx + */ +void +slip_arch_init(unsigned long ubr) +{ + /* + * Enable an input handler. In doing so, the driver will make sure that UART + * RX stays operational during deep sleep + */ + cc26xx_uart_set_input(slip_input_byte); +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/cpu/cc26xx-cc13xx/ti-lib.h b/cpu/cc26xx-cc13xx/ti-lib.h new file mode 100644 index 000000000..c08d05ce3 --- /dev/null +++ b/cpu/cc26xx-cc13xx/ti-lib.h @@ -0,0 +1,710 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc26xx + * @{ + * + * \defgroup cc26xx-ti-lib TI CC26xxware/CC13xxware Glue + * + * Glue file which renames TI CC26xxware functions. Thus, for example, + * PowerCtrlIOFreezeDisable() becomes power_ctrl_io_freeze_disable() + * + * This is not strictly required and a call to the former will work perfectly + * correctly. However, in using those macros, we make the core of the Contiki + * port match the naming convention. + * + * Since all functions are prefixed with ti_lib, it also becomes clear to the + * reader that this is a call to TI driverlib's sources and not a call to a + * function inside Contiki + * + * @{ + * + * \file + * Header file with macros which rename TI CC26xxware functions. + */ +#ifndef TI_LIB_H_ +#define TI_LIB_H_ +/*---------------------------------------------------------------------------*/ +/* aon_batmon.h */ +#include "driverlib/aon_batmon.h" + +#define ti_lib_aon_batmon_enable(...) AONBatMonEnable(__VA_ARGS__) +#define ti_lib_aon_batmon_disable(...) AONBatMonDisable(__VA_ARGS__) +#define ti_lib_aon_batmon_temperature_get_deg_c(...) AONBatMonTemperatureGetDegC(__VA_ARGS__) +#define ti_lib_aon_batmon_battery_voltage_get(...) AONBatMonBatteryVoltageGet(__VA_ARGS__) +#define ti_lib_aon_batmon_new_battery_measure_ready(...) AONBatMonNewBatteryMeasureReady(__VA_ARGS__) +#define ti_lib_aon_batmon_new_temp_measure_ready(...) AONBatMonNewTempMeasureReady(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* aon_event.h */ +#include "driverlib/aon_event.h" + +#define ti_lib_aon_event_mcu_wake_up_set(...) AONEventMcuWakeUpSet(__VA_ARGS__) +#define ti_lib_aon_event_mcu_wake_up_get(...) AONEventMcuWakeUpGet(__VA_ARGS__) +#define ti_lib_aon_event_aux_wake_up_set(...) AONEventAuxWakeUpSet(__VA_ARGS__) +#define ti_lib_aon_event_aux_wake_up_get(...) AONEventAuxWakeUpGet(__VA_ARGS__) +#define ti_lib_aon_event_mcu_set(...) AONEventMcuSet(__VA_ARGS__) +#define ti_lib_aon_event_mcu_get(...) AONEventMcuGet(__VA_ARGS__) +#define ti_lib_aon_event_rtc_set(...) AONEventRtcSet(__VA_ARGS__) +#define ti_lib_aon_event_rtc_get(...) AONEventRtcGet(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* aon_ioc.h */ +#include "driverlib/aon_ioc.h" + +#define ti_lib_aon_ioc_drive_strength_set(...) AONIOCDriveStrengthSet(__VA_ARGS__) +#define ti_lib_aon_ioc_drive_strength_get(...) AONIOCDriveStrengthGet(__VA_ARGS__) +#define ti_lib_aon_ioc_freeze_enable(...) AONIOCFreezeEnable(__VA_ARGS__) +#define ti_lib_aon_ioc_freeze_disable(...) AONIOCFreezeDisable(__VA_ARGS__) +#define ti_lib_aon_ioc_32_khz_output_disable(...) AONIOC32kHzOutputDisable(__VA_ARGS__) +#define ti_lib_aon_ioc_32_khz_output_enable(...) AONIOC32kHzOutputEnable(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* aon_rtc.h */ +#include "driverlib/aon_rtc.h" + +#define ti_lib_aon_rtc_enable(...) AONRTCEnable(__VA_ARGS__) +#define ti_lib_aon_rtc_disable(...) AONRTCDisable(__VA_ARGS__) +#define ti_lib_aon_rtc_active(...) AONRTCActive(__VA_ARGS__) +#define ti_lib_aon_rtc_channel_active(...) AONRTCChannelActive(__VA_ARGS__) +#define ti_lib_aon_rtc_reset(...) AONRTCReset(__VA_ARGS__) +#define ti_lib_aon_rtc_delay_config(...) AONRTCDelayConfig(__VA_ARGS__) +#define ti_lib_aon_rtc_combined_event_config(...) AONRTCCombinedEventConfig(__VA_ARGS__) +#define ti_lib_aon_rtc_event_clear(...) AONRTCEventClear(__VA_ARGS__) +#define ti_lib_aon_rtc_event_get(...) AONRTCEventGet(__VA_ARGS__) +#define ti_lib_aon_rtc_sec_get(...) AONRTCSecGet(__VA_ARGS__) +#define ti_lib_aon_rtc_fraction_get(...) AONRTCFractionGet(__VA_ARGS__) +#define ti_lib_aon_rtc_sub_sec_incr_get(...) AONRTCSubSecIncrGet(__VA_ARGS__) +#define ti_lib_aon_rtc_mode_ch1_set(...) AONRTCModeCh1Set(__VA_ARGS__) +#define ti_lib_aon_rtc_mode_ch1_get(...) AONRTCModeCh1Get(__VA_ARGS__) +#define ti_lib_aon_rtc_mode_ch2_set(...) AONRTCModeCh2Set(__VA_ARGS__) +#define ti_lib_aon_rtc_mode_ch2_get(...) AONRTCModeCh2Get(__VA_ARGS__) +#define ti_lib_aon_rtc_channel_enable(...) AONRTCChannelEnable(__VA_ARGS__) +#define ti_lib_aon_rtc_channel_disable(...) AONRTCChannelDisable(__VA_ARGS__) +#define ti_lib_aon_rtc_compare_value_set(...) AONRTCCompareValueSet(__VA_ARGS__) +#define ti_lib_aon_rtc_compare_value_get(...) AONRTCCompareValueGet(__VA_ARGS__) +#define ti_lib_aon_rtc_current_compare_value_get(...) AONRTCCurrentCompareValueGet(__VA_ARGS__) +#define ti_lib_aon_rtc_current_64_bit_value_get(...) AONRTCCurrent64BitValueGet(__VA_ARGS__) +#define ti_lib_aon_rtc_inc_value_ch2_set(...) AONRTCIncValueCh2Set(__VA_ARGS__) +#define ti_lib_aon_rtc_inc_value_ch2_get(...) AONRTCIncValueCh2Get(__VA_ARGS__) +#define ti_lib_aon_rtc_capture_value_ch1_get(...) AONRTCCaptureValueCh1Get(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* aon_wuc.h */ +#include "driverlib/aon_wuc.h" + +#define ti_lib_aon_wuc_mcu_wake_up_config(...) AONWUCMcuWakeUpConfig(__VA_ARGS__) +#define ti_lib_aon_wuc_mcu_power_down_config(...) AONWUCMcuPowerDownConfig(__VA_ARGS__) +#define ti_lib_aon_wuc_mcu_power_off_config(...) AONWUCMcuPowerOffConfig(__VA_ARGS__) +#define ti_lib_aon_wuc_mcu_sram_config(...) AONWUCMcuSRamConfig(__VA_ARGS__) +#define ti_lib_aon_wuc_aux_clock_config_get(...) AONWUCAuxClockConfigGet(__VA_ARGS__) +#define ti_lib_aon_wuc_aux_power_down_config(...) AONWUCAuxPowerDownConfig(__VA_ARGS__) +#define ti_lib_aon_wuc_aux_wake_up_config(...) AONWUCAuxWakeUpConfig(__VA_ARGS__) +#define ti_lib_aon_wuc_aux_sram_config(...) AONWUCAuxSRamConfig(__VA_ARGS__) +#define ti_lib_aon_wuc_aux_wakeup_event(...) AONWUCAuxWakeupEvent(__VA_ARGS__) +#define ti_lib_aon_wuc_aux_image_valid(...) AONWUCAuxImageValid(__VA_ARGS__) +#define ti_lib_aon_wuc_aux_image_invalid(...) AONWUCAuxImageInvalid(__VA_ARGS__) +#define ti_lib_aon_wuc_aux_reset(...) AONWUCAuxReset(__VA_ARGS__) +#define ti_lib_aon_wuc_power_status_get(...) AONWUCPowerStatusGet(__VA_ARGS__) +#define ti_lib_aon_wuc_shut_down_enable(...) AONWUCShutDownEnable(__VA_ARGS__) +#define ti_lib_aon_wuc_domain_power_down_enable(...) AONWUCDomainPowerDownEnable(__VA_ARGS__) +#define ti_lib_aon_wuc_domain_power_down_disable(...) AONWUCDomainPowerDownDisable(__VA_ARGS__) +#define ti_lib_aon_wuc_mcu_reset_status_get(...) AONWUCMcuResetStatusGet(__VA_ARGS__) +#define ti_lib_aon_wuc_mcu_reset_clear(...) AONWUCMcuResetClear(__VA_ARGS__) +#define ti_lib_aon_wuc_recharge_ctrl_config_set(...) AONWUCRechargeCtrlConfigSet(__VA_ARGS__) +#define ti_lib_aon_wuc_recharge_ctrl_config_get(...) AONWUCRechargeCtrlConfigGet(__VA_ARGS__) +#define ti_lib_aon_wuc_osc_config(...) AONWUCOscConfig(__VA_ARGS__) +#define ti_lib_aon_wuc_jtag_power_off(...) AONWUCJtagPowerOff(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* aux_adc.h */ +#include "driverlib/aux_adc.h" + +#define ti_lib_aux_adc_disable(...) AUXADCDisable(__VA_ARGS__) +#define ti_lib_aux_adc_enable_async(...) AUXADCEnableAsync(__VA_ARGS__) +#define ti_lib_aux_adc_enable_sync(...) AUXADCEnableSync(__VA_ARGS__) +#define ti_lib_aux_adc_disable_input_scaling(...) AUXADCDisableInputScaling(__VA_ARGS__) +#define ti_lib_aux_adc_flush_fifo(...) AUXADCFlushFifo(__VA_ARGS__) +#define ti_lib_aux_adc_gen_manual_trigger(...) AUXADCGenManualTrigger(__VA_ARGS__) +#define ti_lib_aux_adc_get_fifo_status(...) AUXADCGetFifoStatus(__VA_ARGS__) +#define ti_lib_aux_adc_read_fifo(...) AUXADCReadFifo(__VA_ARGS__) +#define ti_lib_aux_adc_pop_fifo(...) AUXADCPopFifo(__VA_ARGS__) +#define ti_lib_aux_adc_select_input(...) AUXADCSelectInput(__VA_ARGS__) +#define ti_lib_aux_adc_get_adjustment_gain(...) AUXADCGetAdjustmentGain(__VA_ARGS__) +#define ti_lib_aux_adc_get_adjustment_offset(...) AUXADCGetAdjustmentOffset(__VA_ARGS__) +#define ti_lib_aux_adc_value_to_microvolts(...) AUXADCValueToMicrovolts(__VA_ARGS__) +#define ti_lib_aux_adc_microvolts_to_value(...) AUXADCMicrovoltsToValue(__VA_ARGS__) +#define ti_lib_aux_adc_adjust_value_for_gain_and_offset(...) AUXADCAdjustValueForGainAndOffset(__VA_ARGS__) +#define ti_lib_aux_adc_unadjust_value_for_gain_and_offset(...) AUXADCUnadjustValueForGainAndOffset(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* aux_wuc.h */ +#include "driverlib/aux_wuc.h" + +#define ti_lib_aux_wuc_clock_enable(...) AUXWUCClockEnable(__VA_ARGS__) +#define ti_lib_aux_wuc_clock_disable(...) AUXWUCClockDisable(__VA_ARGS__) +#define ti_lib_aux_wuc_clock_status(...) AUXWUCClockStatus(__VA_ARGS__) +#define ti_lib_aux_wuc_clock_freq_req(...) AUXWUCClockFreqReq(__VA_ARGS__) +#define ti_lib_aux_wuc_power_ctrl(...) AUXWUCPowerCtrl(__VA_ARGS__) +#define ti_lib_aux_wuc_freeze_enable(...) AUXWUCFreezeEnable(__VA_ARGS__) +#define ti_lib_aux_wuc_freeze_disable(...) AUXWUCFreezeDisable(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* cpu.h */ +#include "driverlib/cpu.h" + +#define ti_lib_cpu_cpsid(...) CPUcpsid(__VA_ARGS__) +#define ti_lib_cpu_cpsie(...) CPUcpsie(__VA_ARGS__) +#define ti_lib_cpu_primask(...) CPUprimask(__VA_ARGS__) +#define ti_lib_cpu_wfi(...) CPUwfi(__VA_ARGS__) +#define ti_lib_cpu_wfe(...) CPUwfe(__VA_ARGS__) +#define ti_lib_cpu_sev(...) CPUsev(__VA_ARGS__) +#define ti_lib_cpu_base_pri_get(...) CPUbasepriGet(__VA_ARGS__) +#define ti_lib_cpu_base_pri_set(...) CPUbasepriSet(__VA_ARGS__) +#define ti_lib_cpu_delay(...) CPUdelay(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* chipinfo.h */ +#include "driverlib/chipinfo.h" + +#define ti_lib_chipinfo_get_supported_protocol_bv(...) ChipInfo_GetSupportedProtocol_BV(__VA_ARGS__) +#define ti_lib_chipinfo_supports_ble(...) ChipInfo_SupportsBLE(__VA_ARGS__) +#define ti_lib_chipinfo_supports_ieee_802_15_4(...) ChipInfo_SupportsIEEE_802_15_4(__VA_ARGS__) +#define ti_lib_chipinfo_supports_proprietary(...) ChipInfo_SupportsPROPRIETARY(__VA_ARGS__) +#define ti_lib_chipinfo_get_package_type(...) ChipInfo_GetPackageType(__VA_ARGS__) +#define ti_lib_chipinfo_package_type_is_4x4(...) ChipInfo_PackageTypeIs4x4(__VA_ARGS__) +#define ti_lib_chipinfo_package_type_is_5x5(...) ChipInfo_PackageTypeIs5x5(__VA_ARGS__) +#define ti_lib_chipinfo_package_type_is_7x7(...) ChipInfo_PackageTypeIs7x7(__VA_ARGS__) +#define ti_lib_chipinfo_get_device_id_hw_rev_code(...) ChipInfo_GetDeviceIdHwRevCode(__VA_ARGS__) +#define ti_lib_chipinfo_get_chip_family(...) ChipInfo_GetChipFamily(__VA_ARGS__) +#define ti_lib_chipinfo_chip_family_is_cc26xx(...) ChipInfo_ChipFamilyIsCC26xx(__VA_ARGS__) +#define ti_lib_chipinfo_chip_family_is_cc13xx(...) ChipInfo_ChipFamilyIsCC13xx(__VA_ARGS__) +#define ti_lib_chipinfo_get_hw_revision(...) ChipInfo_GetHwRevision(__VA_ARGS__) +#define ti_lib_chipinfo_hw_revision_is_1_0(...) ChipInfo_HwRevisionIs_1_0(__VA_ARGS__) +#define ti_lib_chipinfo_hw_revision_is_gteq_2_0(...) ChipInfo_HwRevisionIs_GTEQ_2_0(__VA_ARGS__) +#define ti_lib_chipinfo_hw_revision_is_2_0(...) ChipInfo_HwRevisionIs_2_0(__VA_ARGS__) +#define ti_lib_chipinfo_hw_revision_is_2_1(...) ChipInfo_HwRevisionIs_2_1(__VA_ARGS__) +#define ti_lib_chipinfo_hw_revision_is_2_2(...) ChipInfo_HwRevisionIs_2_2(__VA_ARGS__) +#define ti_lib_chipinfo_hw_revision_is_gteq_2_2(...) ChipInfo_HwRevisionIs_GTEQ_2_2( __VA_ARGS__ ) +/*---------------------------------------------------------------------------*/ +/* ddi.h */ +#include "driverlib/ddi.h" + +#define ti_lib_aux_adi_ddi_safe_write(...) AuxAdiDdiSafeWrite(__VA_ARGS__) +#define ti_lib_aux_adi_ddi_safe_read(...) AuxAdiDdiSafeRead(__VA_ARGS__) +#define ti_lib_ddi_32_reg_write(...) DDI32RegWrite(__VA_ARGS__) +#define ti_lib_ddi_32_reg_read(...) DDI32RegRead(__VA_ARGS__) +#define ti_lib_ddi_32_bits_set(...) DDI32BitsSet(__VA_ARGS__) +#define ti_lib_ddi_32_bits_clear(...) DDI32BitsClear(__VA_ARGS__) +#define ti_lib_ddi_8_set_val_bit(...) DDI8SetValBit(__VA_ARGS__) +#define ti_lib_ddi_16_set_val_bit(...) DDI16SetValBit(__VA_ARGS__) +#define ti_lib_ddi_16_bit_write(...) DDI16BitWrite(__VA_ARGS__) +#define ti_lib_ddi_16_bit_field_write(...) DDI16BitfieldWrite(__VA_ARGS__) +#define ti_lib_ddi_16_bit_read(...) DDI16BitRead(__VA_ARGS__) +#define ti_lib_ddi_16_bitfield_read(...) DDI16BitfieldRead(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* gpio.h */ +#include "driverlib/gpio.h" + +#define ti_lib_gpio_dir_mode_set(...) GPIODirModeSet(__VA_ARGS__) +#define ti_lib_gpio_dir_mode_get(...) GPIODirModeGet(__VA_ARGS__) +#define ti_lib_gpio_pin_write(...) GPIOPinWrite(__VA_ARGS__) +#define ti_lib_gpio_pin_read(...) GPIOPinRead(__VA_ARGS__) +#define ti_lib_gpio_pin_clear(...) GPIOPinClear(__VA_ARGS__) +#define ti_lib_gpio_pin_toggle(...) GPIOPinToggle(__VA_ARGS__) +#define ti_lib_gpio_event_get(...) GPIOEventGet(__VA_ARGS__) +#define ti_lib_gpio_event_clear(...) GPIOEventClear(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* i2c.h */ +#include "driverlib/i2c.h" + +#define ti_lib_i2c_int_register(...) I2CIntRegister(__VA_ARGS__) +#define ti_lib_i2c_int_unregister(...) I2CIntUnregister(__VA_ARGS__) +#define ti_lib_i2c_master_bus_busy(...) I2CMasterBusBusy(__VA_ARGS__) +#define ti_lib_i2c_master_busy(...) I2CMasterBusy(__VA_ARGS__) +#define ti_lib_i2c_master_control(...) I2CMasterControl(__VA_ARGS__) +#define ti_lib_i2c_master_data_get(...) I2CMasterDataGet(__VA_ARGS__) +#define ti_lib_i2c_master_data_put(...) I2CMasterDataPut(__VA_ARGS__) +#define ti_lib_i2c_master_disable(...) I2CMasterDisable(__VA_ARGS__) +#define ti_lib_i2c_master_enable(...) I2CMasterEnable(__VA_ARGS__) +#define ti_lib_i2c_master_err(...) I2CMasterErr(__VA_ARGS__) +#define ti_lib_i2c_master_init_exp_clk(...) I2CMasterInitExpClk(__VA_ARGS__) +#define ti_lib_i2c_master_int_clear(...) I2CMasterIntClear(__VA_ARGS__) +#define ti_lib_i2c_master_int_disable(...) I2CMasterIntDisable(__VA_ARGS__) +#define ti_lib_i2c_master_int_enable(...) I2CMasterIntEnable(__VA_ARGS__) +#define ti_lib_i2c_master_int_status(...) I2CMasterIntStatus(__VA_ARGS__) +#define ti_lib_i2c_master_slave_addr_set(...) I2CMasterSlaveAddrSet(__VA_ARGS__) +#define ti_lib_i2c_slave_data_get(...) I2CSlaveDataGet(__VA_ARGS__) +#define ti_lib_i2c_slave_data_put(...) I2CSlaveDataPut(__VA_ARGS__) +#define ti_lib_i2c_slave_disable(...) I2CSlaveDisable(__VA_ARGS__) +#define ti_lib_i2c_slave_enable(...) I2CSlaveEnable(__VA_ARGS__) +#define ti_lib_i2c_slave_init(...) I2CSlaveInit(__VA_ARGS__) +#define ti_lib_i2c_slave_address_set(...) I2CSlaveAddressSet(__VA_ARGS__) +#define ti_lib_i2c_slave_int_clear(...) I2CSlaveIntClear(__VA_ARGS__) +#define ti_lib_i2c_slave_int_disable(...) I2CSlaveIntDisable(__VA_ARGS__) +#define ti_lib_i2c_slave_int_enable(...) I2CSlaveIntEnable(__VA_ARGS__) +#define ti_lib_i2c_slave_int_status(...) I2CSlaveIntStatus(__VA_ARGS__) +#define ti_lib_i2c_slave_status(...) I2CSlaveStatus(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* interrupt.h */ +#include "driverlib/interrupt.h" + +#define ti_lib_int_master_enable(...) IntMasterEnable(__VA_ARGS__) +#define ti_lib_int_master_disable(...) IntMasterDisable(__VA_ARGS__) +#define ti_lib_int_register(...) IntRegister(__VA_ARGS__); +#define ti_lib_int_unregsiter(...) IntUnregister(__VA_ARGS__) +#define ti_lib_int_priority_grouping_set(...) IntPriorityGroupingSet(__VA_ARGS__) +#define ti_lib_int_priority_grouping_get(...) IntPriorityGroupingGet(__VA_ARGS__) +#define ti_lib_int_priority_set(...) IntPrioritySet(__VA_ARGS__) +#define ti_lib_int_priority_get(...) IntPriorityGet(__VA_ARGS__) +#define ti_lib_int_enable(...) IntEnable(__VA_ARGS__) +#define ti_lib_int_disable(...) IntDisable(__VA_ARGS__) +#define ti_lib_int_pend_set(...) IntPendSet(__VA_ARGS__) +#define ti_lib_int_pend_get(...) IntPendGet(__VA_ARGS__) +#define ti_lib_int_pend_clear(...) IntPendClear(__VA_ARGS__) +#define ti_lib_int_mask_set(...) IntPriorityMaskSet(__VA_ARGS__) +#define ti_lib_int_mask_get(...) IntPriorityMaskGet(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* ioc.h */ +#include "driverlib/ioc.h" + +#define ti_lib_ioc_port_configure_set(...) IOCPortConfigureSet(__VA_ARGS__) +#define ti_lib_ioc_port_configure_get(...) IOCPortConfigureGet(__VA_ARGS__) +#define ti_lib_ioc_io_shutdown_set(...) IOCIOShutdownSet(__VA_ARGS__) +#define ti_lib_ioc_io_mode_set(...) IOCIOModeSet(__VA_ARGS__) +#define ti_lib_ioc_io_port_pull_set(...) IOCIOPortPullSet(__VA_ARGS__) +#define ti_lib_ioc_io_hyst_set(...) IOCIOHystSet(__VA_ARGS__) +#define ti_lib_ioc_io_input_set(...) IOCIOInputSet(__VA_ARGS__) +#define ti_lib_ioc_io_slew_ctrl_set(...) IOCIOSlewCtrlSet(__VA_ARGS__) +#define ti_lib_ioc_io_drv_strength_set(...) IOCIODrvStrengthSet(__VA_ARGS__) +#define ti_lib_ioc_io_port_id_set(...) IOCIOPortIdSet(__VA_ARGS__) +#define ti_lib_ioc_io_int_set(...) IOCIOIntSet(__VA_ARGS__) +#define ti_lib_ioc_int_register(...) IOCIntRegister(__VA_ARGS__); +#define ti_lib_ioc_int_unregister(...) IOCIntUnregister(__VA_ARGS__) +#define ti_lib_ioc_int_enable(...) IOCIntEnable(__VA_ARGS__) +#define ti_lib_ioc_int_disable(...) IOCIntDisable(__VA_ARGS__) +#define ti_lib_ioc_int_clear(...) IOCIntClear(__VA_ARGS__) +#define ti_lib_ioc_int_status(...) IOCIntStatus(__VA_ARGS__) +#define ti_lib_ioc_pin_type_gpio_input(...) IOCPinTypeGpioInput(__VA_ARGS__) +#define ti_lib_ioc_pin_type_gpio_output(...) IOCPinTypeGpioOutput(__VA_ARGS__) +#define ti_lib_ioc_pin_type_uart(...) IOCPinTypeUart(__VA_ARGS__) +#define ti_lib_ioc_pin_type_ssi_master(...) IOCPinTypeSsiMaster(__VA_ARGS__) +#define ti_lib_ioc_pin_type_ssi_slave(...) IOCPinTypeSsiSlave(__VA_ARGS__) +#define ti_lib_ioc_pin_type_i2c(...) IOCPinTypeI2c(__VA_ARGS__) +#define ti_lib_ioc_pin_type_aux(...) IOCPinTypeAux(__VA_ARGS__) +#define ti_lib_ioc_pin_type_spis(...) IOCPinTypeSpis(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* osc.h */ +#include "driverlib/osc.h" + +#define ti_lib_osc_xhf_power_mode_set(...) OSCXHfPowerModeSet(__VA_ARGS__) +#define ti_lib_osc_clock_source_set(...) OSCClockSourceSet(__VA_ARGS__) +#define ti_lib_osc_clock_source_get(...) OSCClockSourceGet(__VA_ARGS__) +#define ti_lib_osc_hf_source_ready(...) OSCHfSourceReady(__VA_ARGS__) +#define ti_lib_osc_hf_source_switch(...) OSCHfSourceSwitch(__VA_ARGS__) +#define ti_lib_osc_interface_enable(...) OSCInterfaceEnable(__VA_ARGS__) +#define ti_lib_osc_interface_disable(...) OSCInterfaceDisable(__VA_ARGS__) +#define ti_lib_osc_hf_get_startup_time(...) OSCHF_GetStartupTime(__VA_ARGS__) +#define ti_lib_osc_hf_turn_on_xosc(...) OSCHF_TurnOnXosc(__VA_ARGS__) +#define ti_lib_osc_hf_attempt_to_switch_to_xosc(...) OSCHF_AttemptToSwitchToXosc(__VA_ARGS__) +#define ti_lib_osc_hf_switch_to_rc_osc_turn_off_xosc(...) OSCHF_SwitchToRcOscTurnOffXosc(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* prcm.h */ +#include "driverlib/prcm.h" + +#define ti_lib_prcm_inf_clock_configure_set(...) PRCMInfClockConfigureSet(__VA_ARGS__) +#define ti_lib_prcm_inf_clock_configure_get(...) PRCMInfClockConfigureGet(__VA_ARGS__) +#define ti_lib_prcm_mcu_power_off(...) PRCMMcuPowerOff(__VA_ARGS__) +#define ti_lib_prcm_mcu_power_off_cancel(...) PRCMMcuPowerOffCancel(__VA_ARGS__) +#define ti_lib_prcm_mcu_uldo_configure(...) PRCMMcuUldoConfigure(__VA_ARGS__) +#define ti_lib_prcm_audio_clock_enable(...) PRCMAudioClockEnable(__VA_ARGS__) +#define ti_lib_prcm_audio_clock_disable(...) PRCMAudioClockDisable(__VA_ARGS__) +#define ti_lib_prcm_audio_clock_config_set(...) PRCMAudioClockConfigSet(__VA_ARGS__) +#define ti_lib_prcm_load_set(...) PRCMLoadSet(__VA_ARGS__) +#define ti_lib_prcm_load_get(...) PRCMLoadGet(__VA_ARGS__) +#define ti_lib_prcm_domain_enable(...) PRCMDomainEnable(__VA_ARGS__) +#define ti_lib_prcm_domain_disable(...) PRCMDomainDisable(__VA_ARGS__) +#define ti_lib_prcm_power_domain_on(...) PRCMPowerDomainOn(__VA_ARGS__) +#define ti_lib_prcm_power_domain_off(...) PRCMPowerDomainOff(__VA_ARGS__) +#define ti_lib_prcm_rf_power_down_when_idle(...) PRCMRfPowerDownWhenIdle(__VA_ARGS__) +#define ti_lib_prcm_peripheral_run_enable(...) PRCMPeripheralRunEnable(__VA_ARGS__) +#define ti_lib_prcm_peripheral_run_disable(...) PRCMPeripheralRunDisable(__VA_ARGS__) +#define ti_lib_prcm_peripheral_sleep_enable(...) PRCMPeripheralSleepEnable(__VA_ARGS__) +#define ti_lib_prcm_peripheral_sleep_disable(...) PRCMPeripheralSleepDisable(__VA_ARGS__) +#define ti_lib_prcm_peripheral_deep_sleep_enable(...) PRCMPeripheralDeepSleepEnable(__VA_ARGS__) +#define ti_lib_prcm_peripheral_deep_sleep_disable(...) PRCMPeripheralDeepSleepDisable(__VA_ARGS__) +#define ti_lib_prcm_power_domain_status(...) PRCMPowerDomainStatus(__VA_ARGS__) +#define ti_lib_prcm_rf_ready(...) PRCMRfReady(__VA_ARGS__) +#define ti_lib_prcm_sleep(...) PRCMSleep(__VA_ARGS__) +#define ti_lib_prcm_deep_sleep(...) PRCMDeepSleep(__VA_ARGS__) +#define ti_lib_prcm_cache_retention_enable(...) PRCMCacheRetentionEnable(__VA_ARGS__) +#define ti_lib_prcm_cache_retention_disable(...) PRCMCacheRetentionDisable(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* sys_ctrl.h */ +#include "driverlib/pwr_ctrl.h" + +#define ti_lib_pwr_ctrl_state_set(...) PowerCtrlStateSet(__VA_ARGS__) +#define ti_lib_pwr_ctrl_source_set(...) PowerCtrlSourceSet(__VA_ARGS__) +#define ti_lib_pwr_ctrl_source_get(...) PowerCtrlSourceGet(__VA_ARGS__) +#define ti_lib_pwr_ctrl_reset_source_get(...) PowerCtrlResetSourceGet(__VA_ARGS__) +#define ti_lib_pwr_ctrl_reset_source_clear(...) PowerCtrlResetSourceClear(__VA_ARGS__) +#define ti_lib_pwr_ctrl_io_freeze_enable(...) PowerCtrlIOFreezeEnable(__VA_ARGS__) +#define ti_lib_pwr_ctrl_io_freeze_disable(...) PowerCtrlIOFreezeDisable(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* rom.h */ +#include "driverlib/rom.h" + +/* AON API */ +#define ti_lib_rom_aon_event_mcu_wake_up_set ROM_AONEventMcuWakeUpSet +#define ti_lib_rom_aon_event_mcu_wake_up_get ROM_AONEventMcuWakeUpGet +#define ti_lib_rom_aon_event_aux_wake_up_set ROM_AONEventAuxWakeUpSet +#define ti_lib_rom_aon_event_aux_wake_up_get ROM_AONEventAuxWakeUpGet +#define ti_lib_rom_aon_event_mcu_set ROM_AONEventMcuSet +#define ti_lib_rom_aon_event_mcu_get ROM_AONEventMcuGet + +/* AON_IOC API */ +#define ti_lib_rom_aon_ioc_drive_strength_set ROM_AONIOCDriveStrengthSet +#define ti_lib_rom_aon_ioc_drive_strength_get ROM_AONIOCDriveStrengthGet + +/* AON_RTC API */ +#define ti_lib_rom_aon_rtc_status ROM_AONRTCStatus +#define ti_lib_rom_aon_rtc_event_clear ROM_AONRTCEventClear +#define ti_lib_rom_aon_rtc_event_get ROM_AONRTCEventGet +#define ti_lib_rom_aon_rtc_mode_ch1_set ROM_AONRTCModeCh1Set +#define ti_lib_rom_aon_rtc_mode_ch1_get ROM_AONRTCModeCh1Get +#define ti_lib_rom_aon_rtc_mode_ch2_set ROM_AONRTCModeCh2Set +#define ti_lib_rom_aon_rtc_mode_ch2_get ROM_AONRTCModeCh2Get +#define ti_lib_rom_aon_rtc_channel_enable ROM_AONRTCChannelEnable +#define ti_lib_rom_aon_rtc_channel_disable ROM_AONRTCChannelDisable +#define ti_lib_rom_aon_rtc_compare_value_set ROM_AONRTCCompareValueSet +#define ti_lib_rom_aon_rtc_compare_value_get ROM_AONRTCCompareValueGet +#define ti_lib_rom_aon_rtc_current_compare_value_get ROM_AONRTCCurrentCompareValueGet + +/* AON_WUC API */ +#define ti_lib_rom_aon_wuc_aux_s_ram_config ROM_AONWUCAuxSRamConfig +#define ti_lib_rom_aon_wuc_aux_wakeup_event ROM_AONWUCAuxWakeupEvent +#define ti_lib_rom_aon_wuc_aux_reset ROM_AONWUCAuxReset +#define ti_lib_rom_aon_wuc_recharge_ctrl_config_set ROM_AONWUCRechargeCtrlConfigSet +#define ti_lib_rom_aon_wuc_osc_config ROM_AONWUCOscConfig + +/* AUX_TDC API */ +#define ti_lib_rom_aux_tdc_config_set ROM_AUXTDCConfigSet +#define ti_lib_rom_aux_tdc_measurement_done ROM_AUXTDCMeasurementDone + +/* AUX_TIMER API */ +#define ti_lib_rom_aux_timer_configure ROM_AUXTimerConfigure +#define ti_lib_rom_aux_timer_start ROM_AUXTimerStart +#define ti_lib_rom_aux_timer_stop ROM_AUXTimerStop +#define ti_lib_rom_aux_timer_prescale_set ROM_AUXTimerPrescaleSet +#define ti_lib_rom_aux_timer_prescale_get ROM_AUXTimerPrescaleGet + +/* AUX_WUC API */ +#define ti_lib_rom_aux_wuc_clock_enable ROM_AUXWUCClockEnable +#define ti_lib_rom_aux_wuc_clock_disable ROM_AUXWUCClockDisable +#define ti_lib_rom_aux_wuc_clock_status ROM_AUXWUCClockStatus +#define ti_lib_rom_aux_wuc_power_ctrl ROM_AUXWUCPowerCtrl + +/* FLASH API */ +#define ti_lib_rom_flash_power_mode_get ROM_FlashPowerModeGet +#define ti_lib_rom_flash_protection_set ROM_FlashProtectionSet +#define ti_lib_rom_flash_protection_get ROM_FlashProtectionGet +#define ti_lib_rom_flash_protection_save ROM_FlashProtectionSave +#define ti_lib_rom_flash_efuse_read_row ROM_FlashEfuseReadRow +#define ti_lib_rom_flash_disable_sectors_for_write ROM_FlashDisableSectorsForWrite + +/* I2C API */ +#define ti_lib_rom_i2c_master_init_exp_clk ROM_I2CMasterInitExpClk +#define ti_lib_rom_i2c_master_err ROM_I2CMasterErr + +/* INTERRUPT API */ +#define ti_lib_rom_int_priority_grouping_set ROM_IntPriorityGroupingSet +#define ti_lib_rom_int_priority_grouping_get ROM_IntPriorityGroupingGet +#define ti_lib_rom_int_priority_set ROM_IntPrioritySet +#define ti_lib_rom_int_priority_get ROM_IntPriorityGet +#define ti_lib_rom_int_enable ROM_IntEnable +#define ti_lib_rom_int_disable ROM_IntDisable +#define ti_lib_rom_int_pend_set ROM_IntPendSet +#define ti_lib_rom_int_pend_get ROM_IntPendGet +#define ti_lib_rom_int_pend_clear ROM_IntPendClear + +/* IOC API */ +#define ti_lib_rom_ioc_port_configure_set ROM_IOCPortConfigureSet +#define ti_lib_rom_ioc_port_configure_get ROM_IOCPortConfigureGet +#define ti_lib_rom_ioc_io_shutdown_set ROM_IOCIOShutdownSet +#define ti_lib_rom_ioc_io_jtag_set ROM_IOCIOJTagSet +#define ti_lib_rom_ioc_io_mode_set ROM_IOCIOModeSet +#define ti_lib_rom_ioc_io_int_set ROM_IOCIOIntSet +#define ti_lib_rom_ioc_io_port_pull_set ROM_IOCIOPortPullSet +#define ti_lib_rom_ioc_io_hyst_set ROM_IOCIOHystSet +#define ti_lib_rom_ioc_io_input_set ROM_IOCIOInputSet +#define ti_lib_rom_ioc_io_slew_ctrl_set ROM_IOCIOSlewCtrlSet +#define ti_lib_rom_ioc_io_drv_strength_set ROM_IOCIODrvStrengthSet +#define ti_lib_rom_ioc_io_port_id_set ROM_IOCIOPortIdSet +#define ti_lib_rom_ioc_int_enable ROM_IOCIntEnable +#define ti_lib_rom_ioc_int_disable ROM_IOCIntDisable +#define ti_lib_rom_ioc_pin_type_gpio_input ROM_IOCPinTypeGpioInput +#define ti_lib_rom_ioc_pin_type_gpio_output ROM_IOCPinTypeGpioOutput +#define ti_lib_rom_ioc_pin_type_uart ROM_IOCPinTypeUart +#define ti_lib_rom_ioc_pin_type_ssi_master ROM_IOCPinTypeSsiMaster +#define ti_lib_rom_ioc_pin_type_ssi_slave ROM_IOCPinTypeSsiSlave +#define ti_lib_rom_ioc_pin_type_i2c ROM_IOCPinTypeI2c +#define ti_lib_rom_ioc_pin_type_spis ROM_IOCPinTypeSpis +#define ti_lib_rom_ioc_pin_type_aux ROM_IOCPinTypeAux + +/* PRCM API */ +#define ti_lib_rom_prcm_inf_clock_configure_set ROM_PRCMInfClockConfigureSet +#define ti_lib_rom_prcm_inf_clock_configure_get ROM_PRCMInfClockConfigureGet +#define ti_lib_rom_prcm_audio_clock_config_set ROM_PRCMAudioClockConfigSet +#define ti_lib_rom_prcm_power_domain_on ROM_PRCMPowerDomainOn +#define ti_lib_rom_prcm_power_domain_off ROM_PRCMPowerDomainOff +#define ti_lib_rom_prcm_peripheral_run_enable ROM_PRCMPeripheralRunEnable +#define ti_lib_rom_prcm_peripheral_run_disable ROM_PRCMPeripheralRunDisable +#define ti_lib_rom_prcm_peripheral_sleep_enable ROM_PRCMPeripheralSleepEnable +#define ti_lib_rom_prcm_peripheral_sleep_disable ROM_PRCMPeripheralSleepDisable +#define ti_lib_rom_prcm_peripheral_deep_sleep_enable ROM_PRCMPeripheralDeepSleepEnable +#define ti_lib_rom_prcm_peripheral_deep_sleep_disable ROM_PRCMPeripheralDeepSleepDisable +#define ti_lib_rom_prcm_power_domain_status ROM_PRCMPowerDomainStatus +#define ti_lib_rom_prcm_deep_sleep ROM_PRCMDeepSleep + +/* SMPH API */ +#define ti_lib_rom_smph_acquire ROM_SMPHAcquire + +/* SPIS API */ +#define ti_lib_rom_spis_data_put ROM_SPISDataPut +#define ti_lib_rom_spis_tx_get_value ROM_SPISTxGetValue +#define ti_lib_rom_spis_data_get ROM_SPISDataGet +#define ti_lib_rom_spis_rx_get_value ROM_SPISRxGetValue +#define ti_lib_rom_spis_int_status ROM_SPISIntStatus + +/* SSI API */ +#define ti_lib_rom_ssi_config_set_exp_clk ROM_SSIConfigSetExpClk +#define ti_lib_rom_ssi_data_put ROM_SSIDataPut +#define ti_lib_rom_ssi_data_put_non_blocking ROM_SSIDataPutNonBlocking +#define ti_lib_rom_ssi_data_get ROM_SSIDataGet +#define ti_lib_rom_ssi_data_get_non_blocking ROM_SSIDataGetNonBlocking + +/* TIMER API */ +#define ti_lib_rom_timer_configure ROM_TimerConfigure +#define ti_lib_rom_timer_level_control ROM_TimerLevelControl +#define ti_lib_rom_timer_trigger_control ROM_TimerTriggerControl +#define ti_lib_rom_timer_stall_control ROM_TimerStallControl +#define ti_lib_rom_timer_wait_on_trigger_control ROM_TimerWaitOnTriggerControl + +/* TRNG API */ +#define ti_lib_rom_trng_configure ROM_TRNGConfigure +#define ti_lib_rom_trng_number_get ROM_TRNGNumberGet + +/* UART API */ +#define ti_lib_rom_uart_fifo_level_get ROM_UARTFIFOLevelGet +#define ti_lib_rom_uart_config_set_exp_clk ROM_UARTConfigSetExpClk +#define ti_lib_rom_uart_config_get_exp_clk ROM_UARTConfigGetExpClk +#define ti_lib_rom_uart_disable ROM_UARTDisable +#define ti_lib_rom_uart_char_get_non_blocking ROM_UARTCharGetNonBlocking +#define ti_lib_rom_uart_char_get ROM_UARTCharGet +#define ti_lib_rom_uart_char_put_non_blocking ROM_UARTCharPutNonBlocking +#define ti_lib_rom_uart_char_put ROM_UARTCharPut + +/* UDMA API */ +#define ti_lib_rom_udma_channel_attribute_enable ROM_uDMAChannelAttributeEnable +#define ti_lib_rom_udma_channel_attribute_disable ROM_uDMAChannelAttributeDisable +#define ti_lib_rom_udma_channel_attribute_get ROM_uDMAChannelAttributeGet +#define ti_lib_rom_udma_channel_control_set ROM_uDMAChannelControlSet +#define ti_lib_rom_udma_channel_transfer_set ROM_uDMAChannelTransferSet +#define ti_lib_rom_udma_channel_scatter_gather_set ROM_uDMAChannelScatterGatherSet +#define ti_lib_rom_udma_channel_size_get ROM_uDMAChannelSizeGet +#define ti_lib_rom_udma_channel_mode_get ROM_uDMAChannelModeGet + +/* VIMS API */ +#define ti_lib_rom_vims_configure ROM_VIMSConfigure +#define ti_lib_rom_vims_mode_set ROM_VIMSModeSet +#define ti_lib_rom_vims_mode_get ROM_VIMSModeGet + +/* HAPI */ +#define ti_lib_hapi_crc32(a, b, c) HapiCrc32(a, b, c) +#define ti_lib_hapi_get_chip_id() HapiGetChipId() +#define ti_lib_hapi_reset_device() HapiResetDevice() +#define ti_lib_hapi_fletcher32(a, b, c) HapiFletcher32(a, b, c) +#define ti_lib_hapi_min_value(a, b) HapiMinValue(a,b) +#define ti_lib_hapi_max_value(a, b) HapiMaxValue(a,b) +#define ti_lib_hapi_mean_value(a, b) HapiMeanValue(a,b) +#define ti_lib_hapi_stand_deviation_value(a, b) HapiStandDeviationValue(a,b) +#define ti_lib_hapi_hf_source_safe_switch() HapiHFSourceSafeSwitch() +#define ti_lib_hapi_select_comp_a_input(a) HapiSelectCompAInput(a) +#define ti_lib_hapi_select_comp_a_ref(a) HapiSelectCompARef(a) +#define ti_lib_hapi_select_adc_comp_b_input(a) HapiSelectADCCompBInput(a) +#define ti_lib_hapi_select_comp_b_ref(a) HapiSelectCompBRef(a) +#define ti_lib_hapi_get_flash_size() HapiGetFlashSize() +#define ti_lib_hapi_sector_erase(a) HapiSectorErase(a) +#define ti_lib_hapi_program_flash(a, b, c) HapiProgramFlash(a, b, c) +/*---------------------------------------------------------------------------*/ +/* sys_ctrl.h */ +#include "driverlib/sys_ctrl.h" + +#define ti_lib_sys_ctrl_power_everything(...) SysCtrlPowerEverything(__VA_ARGS__) +#define ti_lib_sys_ctrl_powerdown(...) SysCtrlPowerdown(__VA_ARGS__) +#define ti_lib_sys_ctrl_standby(...) SysCtrlStandby(__VA_ARGS__) +#define ti_lib_sys_ctrl_shutdown(...) SysCtrlShutdown(__VA_ARGS__) +#define ti_lib_sys_ctrl_clock_get(...) SysCtrlClockGet(__VA_ARGS__) +#define ti_lib_sys_ctrl_aon_sync(...) SysCtrlAonSync(__VA_ARGS__) +#define ti_lib_sys_ctrl_aon_update(...) SysCtrlAonUpdate(__VA_ARGS__) +#define ti_lib_sys_ctrl_set_recharge_before_power_down(...) SysCtrlSetRechargeBeforePowerDown(__VA_ARGS__) +#define ti_lib_sys_ctrl_adjust_recharge_after_power_down(...) SysCtrlAdjustRechargeAfterPowerDown(__VA_ARGS__) +#define ti_lib_sys_ctrl_dcdc_voltage_conditional_control(...) SysCtrl_DCDC_VoltageConditionalControl(__VA_ARGS__) +#define ti_lib_sys_ctrl_reset_source_get(...) SysCtrlResetSourceGet(__VA_ARGS__) +#define ti_lib_sys_ctrl_system_reset(...) SysCtrlSystemReset(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* ssi.h */ +#include "driverlib/ssi.h" + +#define ti_lib_ssi_config_set_exp_clk(...) SSIConfigSetExpClk(__VA_ARGS__) +#define ti_lib_ssi_enable(...) SSIEnable(__VA_ARGS__) +#define ti_lib_ssi_disable(...) SSIDisable(__VA_ARGS__) +#define ti_lib_ssi_data_put(...) SSIDataPut(__VA_ARGS__) +#define ti_lib_ssi_data_put_non_blocking(...) SSIDataPutNonBlocking(__VA_ARGS__) +#define ti_lib_ssi_data_get(...) SSIDataGet(__VA_ARGS__) +#define ti_lib_ssi_data_get_non_blocking(...) SSIDataGetNonBlocking(__VA_ARGS__) +#define ti_lib_ssi_busy(...) SSIBusy(__VA_ARGS__) +#define ti_lib_ssi_status(...) SSIStatus(__VA_ARGS__) +#define ti_lib_ssi_int_register(...) SSIIntRegister(__VA_ARGS__) +#define ti_lib_ssi_int_unregister(...) SSIIntUnregister(__VA_ARGS__) +#define ti_lib_ssi_int_enable(...) SSIIntEnable(__VA_ARGS__) +#define ti_lib_ssi_int_disable(...) SSIIntDisable(__VA_ARGS__) +#define ti_lib_ssi_int_clear(...) SSIIntClear(__VA_ARGS__) +#define ti_lib_ssi_int_status(...) SSIIntStatus(__VA_ARGS__) +#define ti_lib_ssi_dma_enable(...) SSIDMAEnable(__VA_ARGS__) +#define ti_lib_ssi_dma_disable(...) SSIDMADisable(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* systick.h */ +#include "driverlib/systick.h" + +#define ti_lib_systick_enable(...) SysTickEnable(__VA_ARGS__) +#define ti_lib_systick_disable(...) SysTickDisable(__VA_ARGS__) +#define ti_lib_systick_int_register(...) SysTickIntRegister(__VA_ARGS__) +#define ti_lib_systick_int_unregister(...) SysTickIntUnregister(__VA_ARGS__) +#define ti_lib_systick_int_enable(...) SysTickIntEnable(__VA_ARGS__) +#define ti_lib_systick_int_disable(...) SysTickIntDisable(__VA_ARGS__) +#define ti_lib_systick_period_set(...) SysTickPeriodSet(__VA_ARGS__) +#define ti_lib_systick_period_get(...) SysTickPeriodGet(__VA_ARGS__) +#define ti_lib_systick_value_get(...) SysTickValueGet(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* timer.h */ +#include "driverlib/timer.h" + +#define ti_lib_timer_enable(...) TimerEnable(__VA_ARGS__) +#define ti_lib_timer_disable(...) TimerDisable(__VA_ARGS__) +#define ti_lib_timer_configure(...) TimerConfigure(__VA_ARGS__) +#define ti_lib_timer_level_control(...) TimerLevelControl(__VA_ARGS__) +#define ti_lib_timer_event_control(...) TimerEventControl(__VA_ARGS__) +#define ti_lib_timer_stall_control(...) TimerStallControl(__VA_ARGS__) +#define ti_lib_timer_wait_on_trigger_control(...) TimerWaitOnTriggerControl(__VA_ARGS__) +#define ti_lib_timer_rtc_enable(...) TimerRtcEnable(__VA_ARGS__) +#define ti_lib_timer_rtc_disable(...) TimerRtcDisable(__VA_ARGS__) +#define ti_lib_timer_prescale_set(...) TimerPrescaleSet(__VA_ARGS__) +#define ti_lib_timer_prescale_get(...) TimerPrescaleGet(__VA_ARGS__) +#define ti_lib_timer_prescale_match_set(...) TimerPrescaleMatchSet(__VA_ARGS__) +#define ti_lib_timer_prescale_match_get(...) TimerPrescaleMatchGet(__VA_ARGS__) +#define ti_lib_timer_load_set(...) TimerLoadSet(__VA_ARGS__) +#define ti_lib_timer_load_get(...) TimerLoadGet(__VA_ARGS__) +#define ti_lib_timer_value_get(...) TimerValueGet(__VA_ARGS__) +#define ti_lib_timer_match_set(...) TimerMatchSet(__VA_ARGS__) +#define ti_lib_timer_match_get(...) TimerMatchGet(__VA_ARGS__) +#define ti_lib_timer_int_register(...) TimerIntRegister(__VA_ARGS__) +#define ti_lib_timer_int_unregister(...) TimerIntUnregister(__VA_ARGS__) +#define ti_lib_timer_int_enable(...) TimerIntEnable(__VA_ARGS__) +#define ti_lib_timer_int_disable(...) TimerIntDisable(__VA_ARGS__) +#define ti_lib_timer_int_status(...) TimerIntStatus(__VA_ARGS__) +#define ti_lib_timer_int_clear(...) TimerIntClear(__VA_ARGS__) +#define ti_lib_timer_synchronize(...) TimerSynchronize(__VA_ARGS__) +#define ti_lib_timer_ccp_combine_enable(...) TimerCcpCombineEnable(__VA_ARGS__) +#define ti_lib_timer_ccp_combine_disable(...) TimerCcpCombineDisable(__VA_ARGS__) +#define ti_lib_timer_match_update_mode(...) TimerMatchUpdateMode(__VA_ARGS__) +#define ti_lib_timer_interval_load_mode(...) TimerIntervalLoadMode(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* uart.h */ +#include "driverlib/uart.h" + +#define ti_lib_uart_parity_mode_set(...) UARTParityModeSet(__VA_ARGS__) +#define ti_lib_uart_parity_mode_get(...) UARTParityModeGet(__VA_ARGS__) +#define ti_lib_uart_fifo_level_set(...) UARTFIFOLevelSet(__VA_ARGS__) +#define ti_lib_uart_fifo_level_get(...) UARTFIFOLevelGet(__VA_ARGS__) +#define ti_lib_uart_config_set_exp_clk(...) UARTConfigSetExpClk(__VA_ARGS__) +#define ti_lib_uart_config_get_exp_clk(...) UARTConfigGetExpClk(__VA_ARGS__) +#define ti_lib_uart_enable(...) UARTEnable(__VA_ARGS__) +#define ti_lib_uart_disable(...) UARTDisable(__VA_ARGS__) +#define ti_lib_uart_fifo_enable(...) UARTFIFOEnable(__VA_ARGS__) +#define ti_lib_uart_fifo_disable(...) UARTFIFODisable(__VA_ARGS__) +#define ti_lib_uart_chars_avail(...) UARTCharsAvail(__VA_ARGS__) +#define ti_lib_uart_space_avail(...) UARTSpaceAvail(__VA_ARGS__) +#define ti_lib_uart_char_get_non_blocking(...) UARTCharGetNonBlocking(__VA_ARGS__) +#define ti_lib_uart_char_get(...) UARTCharGet(__VA_ARGS__) +#define ti_lib_uart_char_put_non_blocking(...) UARTCharPutNonBlocking(__VA_ARGS__) +#define ti_lib_uart_char_put(...) UARTCharPut(__VA_ARGS__) +#define ti_lib_uart_break_ctl(...) UARTBreakCtl(__VA_ARGS__) +#define ti_lib_uart_busy(...) UARTBusy(__VA_ARGS__) +#define ti_lib_uart_int_register(...) UARTIntRegister(__VA_ARGS__) +#define ti_lib_uart_int_unregister(...) UARTIntUnregister(__VA_ARGS__) +#define ti_lib_uart_int_enable(...) UARTIntEnable(__VA_ARGS__) +#define ti_lib_uart_int_disable(...) UARTIntDisable(__VA_ARGS__) +#define ti_lib_uart_int_status(...) UARTIntStatus(__VA_ARGS__) +#define ti_lib_uart_int_clear(...) UARTIntClear(__VA_ARGS__) +#define ti_lib_uart_dma_enable(...) UARTDMAEnable(__VA_ARGS__) +#define ti_lib_uart_dma_disable(...) UARTDMADisable(__VA_ARGS__) +#define ti_lib_uart_rx_error_get(...) UARTRxErrorGet(__VA_ARGS__) +#define ti_lib_uart_rx_error_clear(...) UARTRxErrorClear(__VA_ARGS__) +#define ti_lib_uart_hw_flow_control_en(...) UARTHwFlowControlEnable(__VA_ARGS__) +#define ti_lib_uart_hw_flow_control_dis(...) UARTHwFlowControlDisable(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* vims.h */ +#include "driverlib/vims.h" + +#define ti_lib_vims_configure(...) VIMSConfigure(__VA_ARGS__) +#define ti_lib_vims_mode_set(...) VIMSModeSet(__VA_ARGS__) +#define ti_lib_vims_mode_get(...) VIMSModeGet(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/* watchdog.h */ +#include "driverlib/watchdog.h" + +#define ti_lib_watchdog_running(...) WatchdogRunning(__VA_ARGS__) +#define ti_lib_watchdog_enable(...) WatchdogEnable(__VA_ARGS__) +#define ti_lib_watchdog_reset_enable(...) WatchdogResetEnable(__VA_ARGS__) +#define ti_lib_watchdog_reset_disable(...) WatchdogResetDisable(__VA_ARGS__) +#define ti_lib_watchdog_lock(...) WatchdogLock(__VA_ARGS__) +#define ti_lib_watchdog_unlock(...) WatchdogUnlock(__VA_ARGS__) +#define ti_lib_watchdog_lock_state(...) WatchdogLockState(__VA_ARGS__) +#define ti_lib_watchdog_reload_set(...) WatchdogReloadSet(__VA_ARGS__) +#define ti_lib_watchdog_reload_get(...) WatchdogReloadGet(__VA_ARGS__) +#define ti_lib_watchdog_value_get(...) WatchdogValueGet(__VA_ARGS__) +#define ti_lib_watchdog_int_register(...) WatchdogIntRegister(__VA_ARGS__) +#define ti_lib_watchdog_int_unregister(...) WatchdogIntUnregister(__VA_ARGS__) +#define ti_lib_watchdog_int_enable(...) WatchdogIntEnable(__VA_ARGS__) +#define ti_lib_watchdog_int_status(...) WatchdogIntStatus(__VA_ARGS__) +#define ti_lib_watchdog_int_clear(...) WatchdogIntClear(__VA_ARGS__) +#define ti_lib_watchdog_int_type_set(...) WatchdogIntTypeSet(__VA_ARGS__) +#define ti_lib_watchdog_stall_enable(...) WatchdogStallEnable(__VA_ARGS__) +#define ti_lib_watchdog_stall_disable(...) WatchdogStallDisable(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +#endif /* TI_LIB_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/mc1322x/clock.c b/cpu/mc1322x/clock.c index 611a90251..0eb6dada0 100644 --- a/cpu/mc1322x/clock.c +++ b/cpu/mc1322x/clock.c @@ -90,6 +90,12 @@ clock_seconds(void) return seconds; } +void +clock_set_seconds(unsigned long sec) +{ + seconds = sec; +} + void clock_wait(clock_time_t t) { @@ -97,7 +103,7 @@ clock_wait(clock_time_t t) while ((signed long)(current_clock - endticks) < 0) {;} } /*---------------------------------------------------------------------------*/ -/** +/* * Delay the CPU for up to 65535 microseconds. * Use the 250KHz MACA clock for longer delays to avoid interrupt effects. * However that can't be used if the radio is being power cycled! @@ -118,7 +124,7 @@ clock_delay_usec(uint16_t howlong) while(--i); } /*---------------------------------------------------------------------------*/ -/** +/* * Delay the CPU for up to 65535 milliseconds. The watchdog is NOT disabled. */ void @@ -127,7 +133,7 @@ clock_delay_msec(uint16_t howlong) while(howlong--) clock_delay_usec(1000); } /*---------------------------------------------------------------------------*/ -/** +/* * Legacy delay. The original clock_delay for the msp430 used a granularity * of 2.83 usec. This approximates that delay for values up to 1456 usec. * (The largest core call in leds.c uses 400). @@ -139,7 +145,7 @@ clock_delay(unsigned int howlong) clock_delay_usec((283*howlong)/100); } /*---------------------------------------------------------------------------*/ -/** +/* * Adjust clock ticks after a cpu sleep. */ void clock_adjust_ticks(clock_time_t howmany) { diff --git a/cpu/mc1322x/contiki-maca.c b/cpu/mc1322x/contiki-maca.c index 7b05b7c1b..29357de28 100644 --- a/cpu/mc1322x/contiki-maca.c +++ b/cpu/mc1322x/contiki-maca.c @@ -79,6 +79,31 @@ int contiki_maca_channel_clear(void); int contiki_maca_receiving_packet(void); int contiki_maca_pending_packet(void); +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ const struct radio_driver contiki_maca_driver = { .init = contiki_maca_init, @@ -91,6 +116,10 @@ const struct radio_driver contiki_maca_driver = .channel_clear = contiki_maca_channel_clear, .on = contiki_maca_on_request, .off = contiki_maca_off_request, + .get_value = get_value, + .set_value = set_value, + .get_object = get_object, + .set_object = set_object }; static volatile uint8_t contiki_maca_request_on = 0; @@ -200,7 +229,7 @@ int contiki_maca_read(void *buf, unsigned short bufsize) { } #endif PRINTF("\n\r"); - free_packet(p); + maca_free_packet(p); return bufsize; } else { return 0; diff --git a/cpu/mc1322x/contiki-mc1322x-conf.h b/cpu/mc1322x/contiki-mc1322x-conf.h index e6c65df56..2dfb7e0f1 100644 --- a/cpu/mc1322x/contiki-mc1322x-conf.h +++ b/cpu/mc1322x/contiki-mc1322x-conf.h @@ -55,8 +55,8 @@ typedef unsigned short uip_stats_t; typedef uint32_t clock_time_t; -/* Core rtimer.h defaults to 16 bit timer unless RTIMER_CLOCK_LT is defined */ +/* Core rtimer.h defaults to 16 bit timer unless RTIMER_CLOCK_DIFF is defined */ typedef unsigned long rtimer_clock_t; -#define RTIMER_CLOCK_LT(a,b) ((signed long)((a)-(b)) < 0) +#define RTIMER_CLOCK_DIFF(a,b) ((signed long)((a)-(b))) #endif diff --git a/cpu/mc1322x/doc/rest-tutorial.md b/cpu/mc1322x/doc/rest-tutorial.md deleted file mode 100644 index c3c3e05f9..000000000 --- a/cpu/mc1322x/doc/rest-tutorial.md +++ /dev/null @@ -1,172 +0,0 @@ -Contiki REST/CoAP Quickstart using Econotags -====================================== - -Contiki has an implementation of the IETF CORE (Constrained RESTful -Environments) working group's CoAP layer (Constrained Application -Protocol). CoAP is a RESTful application layer that uses HTTP-like -methods (GET, POST, PUT, DELETE) to interact with constrained -networks. CoAP operates over UDP and supports reliable transmission. - -This tutorial will show you how to run Contiki's CoAP demo on Redwire -Econotags using an RPL border-router. - -1) Run a RPL border-router and tunnel ---------------------------------------------------------------- - -See [the RPL -HOWTO](http://mc1322x.devl.org/repos/contiki-mc1322x/cpu/mc1322x/doc/rpl-tutorial.md) -for details about running a RPL border-router. - -2) Build and run the `rest-server-example` on a second Econotag ----------------------------------------- - -__The following must be done on the contiki-mc1322x.git tree__ - - git clone git://git.devl.org/git/malvira/contiki-mc1322x.git - -__Contiki CVS is currently down and the new SCM system hasn't been set -up yet. The necessary changes will be pushed as soon as the new SCM is -available. - 6 Februrary 2011__ - -To build the rest-server-example: - - cd contiki-mc1322x/examples/rest-example - make TARGET=redbee-econotag - -This will produce the binary image -`rest-server-example_redbee-econotag.bin`, which you can load directly -on to an mc1322x and execute. - - mc1322x-load.pl -f rest-server-example_redbee-econotag.bin -t /dev/ttyUSB3 - -Then press the reset button to connect to the bootloader. - -In this example, we are loading the CoAP server on to the econotag on `/dev/ttyUSB3` - -You should see boot up messages similar to this: - - CONNECT - Size: 62096 bytes - Sending rest-server-example_redbee-econotag.bin - done sending files. - performing ring osc cal - crm_status: 0xc0000 - sys_cntl: 0x18 - ring osc cal complete - cal_count: 0x17e17e0 - cal factor: 100 - hib_wake_secs: 2000 - loading rime address from flash. - Rime started with address 00:50:C2:AB:C0:00:00:23 - nullmac nullrdc, channel check rate 100 Hz, radio channel 26 - Tentative link-local IPv6 address - fe80:0000:0000:0000:0250:c2ab:c000:0023 - Tentative global IPv6 address aaaa:0000:0000:0000:0250:c2ab:c000:0023 - Starting 'Rest Server Example' - COAP Server - -The last line indicates that the server will be using -COAP. As an alternative, you can build the server to use HTTP instead with: - - make TARGET=redbee-econotag WITH_COAP=0 - -3) Download and install the `Copper` Firefox Plugin ------------------------------------------------------ - -The `Copper` Plugin for Firefox provides the `coap:` URL access method -as well as an interface to easily send `coap` requests. - -Download and install the plugin from here: - -+ [Copper plugin homepage](http://people.inf.ethz.ch/~mkovatsc/) -+ Install link:[copper-0.3.0pre2.xpi](http://people.inf.ethz.ch/~mkovatsc/resources/copper/copper-0.3.0pre2.xpi) - -4) Open Copper --------------- - -Open a new Firefox tab and click on the orange CU button in the lower -right. - -[![Open CU](http://mc1322x.devl.org/files/coap-blanktab-t.png)](http://mc1322x.devl.org/files/coap-blanktab.png) - -The initial CU screen will look like this: - -[![CU startup](http://mc1322x.devl.org/files/coap-opencu-t.png)](http://mc1322x.devl.org/files/coap-opencu.png) - -Type in the the URL of the coap node with the default port number of -"61616": - -[![CU startup](http://mc1322x.devl.org/files/coap-url-t.png)](http://mc1322x.devl.org/files/coap-url.png) - -+ Don't forget the brackets ( [ ] ) in the URL - -+ Make sure to use the IPv6 address of your coap server. You can get - this from the boot up messages or from the webpage served by your - border-router. - -+ You must always press Enter after changing the URL. - -5) GET `.well-known/core` resources ------------------------------------- - -Now click on the red "./well-known/core" button: this changes the URL -to the `.well-known/core` resource. - -Then click GET to perform a get. You should see an acknowledgement -that the GET was successful (returns 200 OK). The payload should -return: - - ;n="HelloWorld",;n="LedControl",;n="Light - -Which is are the well-known resources that this node advertises; see -the [COAP -specification](https://datatracker.ietf.org/doc/draft-ietf-core-coap/) -for details. - -[![Open CU](http://mc1322x.devl.org/files/coap-wellknown-t.png)](http://mc1322x.devl.org/files/coap-wellknown.png) - -6) PUT,POST the `led` resource state ------------------------------------- - -You can PUT or POST to change the state of the LED. - -Type in the following URL and press enter: - - coap://[aaaa::250:c2ff:fea8:c48e]:61616/led?color=green - -Be sure to use the proper IP address. For this URL: we will perform -actions on the `led` resource with a query string of `color=green`. - -In the payload, type: - - mode=on - -That is the payload that will be PUT or POSTed. The COAP server -detects the mode string and activates the LED accordingly (with the -color chosen by the query string). - -Then click PUT or POST to perform the request. - -[![CU startup](http://mc1322x.devl.org/files/coap-led-t.png)](http://mc1322x.devl.org/files/coap-led.png) - -You should get a successful return code (200 OK) and the green LED -should turn on. If you PUT/POST `mode=off` the led will turn off. - -The econotag only has two LEDs: a green and a red. The red LED is used -to indicate radio transmission by default and so cannot be used in -this demo. The Coniki blue LED is connected to GPIO 43. You can toggle -it, but you won't see anything unless you hook something up to this -pin. - -7) Other resources ------------------- - -The `rest-server-example` also provides `helloworld` and `light` as -GETtable resources. - - coap://[aaaa::250:c2ff:fea8:c48e]:61616/helloworld - coap://[aaaa::250:c2ff:fea8:c48e]:61616/light - -The econotag does not have a light sensor. The light resource will -always return 0. At a latter date, this sensor will be connected to -one of the ADC pins. diff --git a/cpu/mc1322x/lib/include/crm.h b/cpu/mc1322x/lib/include/crm.h index 27c0adc53..36ee3099a 100644 --- a/cpu/mc1322x/lib/include/crm.h +++ b/cpu/mc1322x/lib/include/crm.h @@ -325,6 +325,17 @@ static const int XTAL32_EN = 0; #define pack_XTAL_CNTL(ctune4pf, ctune, ftune, ibias) \ (*CRM_XTAL_CNTL = ((ctune4pf << 25) | (ctune << 21) | ( ftune << 16) | (ibias << 8) | 0x52)) +#define soft_reset() \ + __asm__ __volatile__ ( \ + "ldr r0, [%[sw]] \n\t" \ + "str r0, [%[sw]] \n\t" \ + : /* out */ \ + : /* in */ \ + [sw] "l" (CRM_SW_RST) \ + : /* clobber list */ \ + "r0", "memory" \ + ); + #endif /* REG_NO_COMPAT */ #endif diff --git a/cpu/mc1322x/lib/include/maca.h b/cpu/mc1322x/lib/include/maca.h index 5f1083f38..29e74f319 100644 --- a/cpu/mc1322x/lib/include/maca.h +++ b/cpu/mc1322x/lib/include/maca.h @@ -71,7 +71,7 @@ extern volatile uint8_t prm_mode; void tx_packet(volatile packet_t *p); volatile packet_t* rx_packet(void); volatile packet_t* get_free_packet(void); -void free_packet(volatile packet_t *p); +void maca_free_packet(volatile packet_t *p); void free_all_packets(void); extern volatile packet_t *rx_head, *tx_head; diff --git a/cpu/mc1322x/lib/include/nvm.h b/cpu/mc1322x/lib/include/nvm.h index 65ba23d11..6bd8dfe0a 100644 --- a/cpu/mc1322x/lib/include/nvm.h +++ b/cpu/mc1322x/lib/include/nvm.h @@ -78,5 +78,6 @@ extern nvmErr_t (*nvm_write)(nvmInterface_t nvmInterface, nvmType_t nvmType ,voi /* SST flash has 32 sectors 4096 bytes each */ /* bit 0 is the first sector, bit 31 is the last */ extern nvmErr_t (*nvm_erase)(nvmInterface_t nvmInterface, nvmType_t nvmType ,uint32_t sectorBitfield); +extern nvmErr_t (*nvm_verify)(nvmInterface_t nvmInterface, nvmType_t nvmType, void *pSrc, uint32_t address, uint32_t numBytes); extern void(*nvm_setsvar)(uint32_t zero_for_awesome); #endif //NVM_H diff --git a/cpu/mc1322x/lib/maca.c b/cpu/mc1322x/lib/maca.c index c39b27ccb..92cf99b42 100644 --- a/cpu/mc1322x/lib/maca.c +++ b/cpu/mc1322x/lib/maca.c @@ -300,7 +300,7 @@ void bound_check(volatile packet_t *p) { /* public packet routines */ /* heads are to the right */ /* ends are to the left */ -void free_packet(volatile packet_t *p) { +void maca_free_packet(volatile packet_t *p) { safe_irq_disable(MACA); BOUND_CHECK(p); @@ -495,7 +495,7 @@ void free_all_packets(void) { free_head = 0; for(i=0; ileft; if(tx_head == 0) { tx_end = 0; } - free_packet(p); + maca_free_packet(p); // print_packets("free tx head"); irq_restore(); diff --git a/cpu/mc1322x/lib/nvm.c b/cpu/mc1322x/lib/nvm.c index 83dd8ecc7..569977c63 100644 --- a/cpu/mc1322x/lib/nvm.c +++ b/cpu/mc1322x/lib/nvm.c @@ -51,6 +51,10 @@ nvmErr_t (*nvm_erase) (nvmInterface_t nvmInterface, nvmType_t nvmType ,uint32_t sectorBitfield) = (void*) 0x00006e05; +nvmErr_t (*nvm_verify) +(nvmInterface_t nvmInterface, nvmType_t nvmType, void *pSrc, uint32_t address, uint32_t numBytes) += (void*) 0x00006f85; + void(*nvm_setsvar) (uint32_t zero_for_awesome) = (void *)0x00007085; diff --git a/cpu/mc1322x/lib/printf.c b/cpu/mc1322x/lib/printf.c index c716b5893..ad9a5b432 100644 --- a/cpu/mc1322x/lib/printf.c +++ b/cpu/mc1322x/lib/printf.c @@ -28,13 +28,13 @@ * SUCH DAMAGE. * * This file is part of libmc1322x: see http://mc1322x.devl.org - * for details. + * for details. * * */ /** - * \file printf-stdarg.c + * \file lib/printf.c * * \brief sprintf functions to replace newlib for AVR32 UC3. * diff --git a/cpu/mc1322x/slip-uart1.c b/cpu/mc1322x/slip-uart1.c index 542a690ba..99eacfdfe 100644 --- a/cpu/mc1322x/slip-uart1.c +++ b/cpu/mc1322x/slip-uart1.c @@ -57,7 +57,7 @@ slip_arch_writeb(unsigned char c) * */ /*---------------------------------------------------------------------------*/ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 int putchar(int c) { @@ -83,7 +83,7 @@ putchar(int c) return c; } -#endif +#endif /* NETSTACK_CONF_WITH_IPV4 */ /*---------------------------------------------------------------------------*/ /** * Initalize the RS232 port and the SLIP driver. diff --git a/cpu/mc1322x/tests/autoack-rx.c b/cpu/mc1322x/tests/autoack-rx.c index 03de59249..518e9ed7a 100644 --- a/cpu/mc1322x/tests/autoack-rx.c +++ b/cpu/mc1322x/tests/autoack-rx.c @@ -94,7 +94,7 @@ void main(void) { /* print and free the packet */ printf("autoack-rx --- "); print_packet(p); - free_packet(p); + maca_free_packet(p); } if(uart1_can_get()) { diff --git a/cpu/mc1322x/tests/autoack-tx.c b/cpu/mc1322x/tests/autoack-tx.c index 205c18a49..0a1d257f5 100644 --- a/cpu/mc1322x/tests/autoack-tx.c +++ b/cpu/mc1322x/tests/autoack-tx.c @@ -139,7 +139,7 @@ void main(void) { if(p) { printf("RX: "); print_packet(p); - free_packet(p); + maca_free_packet(p); } } diff --git a/cpu/mc1322x/tests/per.c b/cpu/mc1322x/tests/per.c index f3a795b96..4e21714a7 100644 --- a/cpu/mc1322x/tests/per.c +++ b/cpu/mc1322x/tests/per.c @@ -146,7 +146,7 @@ void main(void) { print_packet(p); type = get_packet_type((packet_t *) p); addr = 0; /* FIXME */ - free_packet(p); + maca_free_packet(p); /* pick a new address if someone else is using ours */ if(addr == my_addr) { my_addr = random_short_addr(); diff --git a/cpu/mc1322x/tests/rftest-rx.c b/cpu/mc1322x/tests/rftest-rx.c index 2f3d5cf71..a9e9062cf 100644 --- a/cpu/mc1322x/tests/rftest-rx.c +++ b/cpu/mc1322x/tests/rftest-rx.c @@ -87,7 +87,7 @@ void main(void) { /* print and free the packet */ printf("rftest-rx --- "); print_packet(p); - free_packet(p); + maca_free_packet(p); } if(uart1_can_get()) { diff --git a/cpu/mc1322x/tests/rftest-tx.c b/cpu/mc1322x/tests/rftest-tx.c index 4ac413902..25cd3a254 100644 --- a/cpu/mc1322x/tests/rftest-tx.c +++ b/cpu/mc1322x/tests/rftest-tx.c @@ -94,7 +94,7 @@ void main(void) { check_maca(); while((p = rx_packet())) { - if(p) free_packet(p); + if(p) maca_free_packet(p); } p = get_free_packet(); diff --git a/cpu/msp430/Makefile.msp430 b/cpu/msp430/Makefile.msp430 index d6a83df73..6d5370575 100644 --- a/cpu/msp430/Makefile.msp430 +++ b/cpu/msp430/Makefile.msp430 @@ -4,6 +4,8 @@ ifdef nodeid CFLAGS += -DNODEID=$(nodeid) endif +CFLAGS += -gstabs+ + .SUFFIXES: ### Define the CPU directory @@ -33,10 +35,21 @@ endif CONTIKI_CPU_DIRS = $(CONTIKI_CPU_FAM_DIR) . dev MSP430 = msp430.c flash.c clock.c leds.c leds-arch.c \ - watchdog.c lpm.c mtarch.c rtimer-arch.c + watchdog.c lpm.c rtimer-arch.c UIPDRIVERS = me.c me_tabs.c slip.c crc16.c ELFLOADER = elfloader.c elfloader-msp430.c symtab.c +ifndef CPU_HAS_MSP430X +# include mtarch.c only in the non-large memory model case, because +# the current implementation assumes 16-bit addresses (function pointers +# stored as "unsigned short"). +MSP430 += mtarch.c +endif + +ifeq ($(TARGET_MEMORY_MODEL),large) +ELFLOADER = elfloader-msp430x.c symtab.c +endif + CONTIKI_TARGET_SOURCEFILES += $(MSP430) \ $(SYSAPPS) $(ELFLOADER) \ $(UIPDRIVERS) @@ -145,6 +158,24 @@ ifndef CC_MCU CC_MCU := $(MCU) endif +### Checks for compiler version to enable 20-bit support +ifndef IAR +ifneq (,$(findstring 4.7.,$(shell msp430-gcc -dumpversion))) +ifdef CPU_HAS_MSP430X + ifeq ($(TARGET_MEMORY_MODEL),large) + CFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) + CFLAGS += -mcode-region=far -mdata-region=far -msr20 -mc20 -md20 + LDFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) -mcode-region=far -mdata-region=far -msr20 -mc20 -md20 + else + TARGET_MEMORY_MODEL = medium + CFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) + CFLAGS += -ffunction-sections -fdata-sections -mcode-region=any + LDFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) -Wl,-gc-sections + endif +endif +endif +endif + ifndef CFLAGSNO CFLAGSNO = -Wall -mmcu=$(CC_MCU) $(CFLAGSWERROR) endif diff --git a/cpu/msp430/cc2420-arch-sfd.c b/cpu/msp430/cc2420-arch-sfd.c index 49c979ce2..6cd7d2606 100644 --- a/cpu/msp430/cc2420-arch-sfd.c +++ b/cpu/msp430/cc2420-arch-sfd.c @@ -45,6 +45,8 @@ ISR(TIMERB1, cc2420_timerb1_interrupt) ENERGEST_ON(ENERGEST_TYPE_IRQ); /* always read TBIV to clear IFG */ tbiv = TBIV; + /* read and discard tbiv to avoid "variable set but not used" warning */ + (void)tbiv; if(CC2420_SFD_IS_1) { cc2420_sfd_counter++; cc2420_sfd_start_time = TBCCR1; @@ -59,7 +61,7 @@ void cc2420_arch_sfd_init(void) { /* Need to select the special function! */ - P4SEL = BV(CC2420_SFD_PIN); + CC2420_SFD_PORT(SEL) = BV(CC2420_SFD_PIN); /* start timer B - 32768 ticks per second */ TBCTL = TBSSEL_1 | TBCLR; diff --git a/cpu/msp430/cc2520-arch-sfd.c b/cpu/msp430/cc2520-arch-sfd.c index 5eb35cedb..5e7bee813 100644 --- a/cpu/msp430/cc2520-arch-sfd.c +++ b/cpu/msp430/cc2520-arch-sfd.c @@ -44,6 +44,8 @@ ISR(TIMERB1, cc2520_timerb1_interrupt) ENERGEST_ON(ENERGEST_TYPE_IRQ); /* always read TBIV to clear IFG */ tbiv = TBIV; + /* read and discard tbiv to avoid "variable set but not used" warning */ + (void)tbiv; if(CC2520_SFD_IS_1) { cc2520_sfd_counter++; cc2520_sfd_start_time = TBCCR1; @@ -58,7 +60,7 @@ void cc2520_arch_sfd_init(void) { /* Need to select the special function! */ - P4SEL = BV(CC2520_SFD_PIN); + CC2520_SFD_PORT(SEL) = BV(CC2520_SFD_PIN); /* start timer B - 32768 ticks per second */ TBCTL = TBSSEL_1 | TBCLR; diff --git a/cpu/msp430/dev/uart0-putchar.c b/cpu/msp430/dev/uart0-putchar.c index 819f627d2..96f24abf0 100644 --- a/cpu/msp430/dev/uart0-putchar.c +++ b/cpu/msp430/dev/uart0-putchar.c @@ -1,9 +1,11 @@ #include "dev/uart0.h" -#include +#if !NETSTACK_CONF_WITH_IPV4 +/* In case of IPv4: putchar() is defined by the SLIP driver */ int putchar(int c) { uart0_writeb((char)c); return c; } +#endif /* ! NETSTACK_CONF_WITH_IPV4 */ diff --git a/cpu/msp430/dev/uart1-putchar.c b/cpu/msp430/dev/uart1-putchar.c index 3d7f65c7b..5cb631190 100644 --- a/cpu/msp430/dev/uart1-putchar.c +++ b/cpu/msp430/dev/uart1-putchar.c @@ -1,9 +1,11 @@ -#include #include "dev/uart1.h" +#if !NETSTACK_CONF_WITH_IPV4 +/* In case of IPv4: putchar() is defined by the SLIP driver */ int putchar(int c) { uart1_writeb((char)c); return c; } +#endif /* ! NETSTACK_CONF_WITH_IPV4 */ diff --git a/cpu/msp430/f1xxx/clock.c b/cpu/msp430/f1xxx/clock.c index b17694f2a..9b2a7562b 100644 --- a/cpu/msp430/f1xxx/clock.c +++ b/cpu/msp430/f1xxx/clock.c @@ -41,12 +41,26 @@ #define MAX_TICKS (~((clock_time_t)0) / 2) +#define CLOCK_LT(a, b) ((int16_t)((a)-(b)) < 0) + static volatile unsigned long seconds; static volatile clock_time_t count = 0; /* last_tar is used for calculating clock_fine */ static volatile uint16_t last_tar = 0; /*---------------------------------------------------------------------------*/ +static inline uint16_t +read_tar(void) +{ + /* Same as clock_counter(), but can be inlined */ + uint16_t t1, t2; + do { + t1 = TAR; + t2 = TAR; + } while(t1 != t2); + return t1; +} +/*---------------------------------------------------------------------------*/ ISR(TIMERA1, timera1) { ENERGEST_ON(ENERGEST_TYPE_IRQ); @@ -57,28 +71,28 @@ ISR(TIMERA1, timera1) /* HW timer bug fix: Interrupt handler called before TR==CCR. * Occurs when timer state is toggled between STOP and CONT. */ - while(TACTL & MC1 && TACCR1 - TAR == 1); + while(TACTL & MC1 && TACCR1 - read_tar() == 1); + last_tar = read_tar(); /* Make sure interrupt time is future */ - do { + while(!CLOCK_LT(last_tar, TACCR1)) { TACCR1 += INTERVAL; ++count; /* Make sure the CLOCK_CONF_SECOND is a power of two, to ensure - that the modulo operation below becomes a logical and and not - an expensive divide. Algorithm from Wikipedia: - http://en.wikipedia.org/wiki/Power_of_two */ + that the modulo operation below becomes a logical and and not + an expensive divide. Algorithm from Wikipedia: + http://en.wikipedia.org/wiki/Power_of_two */ #if (CLOCK_CONF_SECOND & (CLOCK_CONF_SECOND - 1)) != 0 #error CLOCK_CONF_SECOND must be a power of two (i.e., 1, 2, 4, 8, 16, 32, 64, ...). #error Change CLOCK_CONF_SECOND in contiki-conf.h. #endif if(count % CLOCK_CONF_SECOND == 0) { - ++seconds; + ++seconds; energest_flush(); } - } while((TACCR1 - TAR) > INTERVAL); - - last_tar = TAR; + last_tar = read_tar(); + } if(etimer_pending() && (etimer_next_expiration_time() - count - 1) > MAX_TICKS) { @@ -181,7 +195,7 @@ clock_delay(unsigned int i) } } /*---------------------------------------------------------------------------*/ -/** +/* * Wait for a multiple of 10 ms. * */ diff --git a/cpu/msp430/f2xxx/msp430.c b/cpu/msp430/f2xxx/msp430.c index 8c21986c4..c6552e058 100644 --- a/cpu/msp430/f2xxx/msp430.c +++ b/cpu/msp430/f2xxx/msp430.c @@ -32,8 +32,12 @@ #include "contiki.h" #include "dev/watchdog.h" +/* dco_required set to 1 will cause the CPU not to go into + * sleep modes where the DCO clock stopped */ +int msp430_dco_required; + #if defined(__MSP430__) && defined(__GNUC__) -#define asmv(arg) __asm__ __volatile__(arg) +#define asmv(arg) __asm__ __volatile__ (arg) #endif /*---------------------------------------------------------------------------*/ @@ -42,8 +46,8 @@ void * w_memcpy(void *out, const void *in, size_t n) { uint8_t *src, *dest; - src = (uint8_t *) in; - dest = (uint8_t *) out; + src = (uint8_t *)in; + dest = (uint8_t *)out; while(n-- > 0) { *dest++ = *src++; } @@ -56,7 +60,7 @@ void * w_memset(void *out, int value, size_t n) { uint8_t *dest; - dest = (uint8_t *) out; + dest = (uint8_t *)out; while(n-- > 0) { *dest++ = value & 0xff; } @@ -152,10 +156,30 @@ init_ports(void) /*---------------------------------------------------------------------------*/ /* msp430-ld may align _end incorrectly. Workaround in cpu_init. */ #if defined(__MSP430__) && defined(__GNUC__) -extern int _end; /* Not in sys/unistd.h */ +extern int _end; /* Not in sys/unistd.h */ static char *cur_break = (char *)&_end; #endif +/*---------------------------------------------------------------------------*/ +/* add/remove_lpm_req - for requiring a specific LPM mode. currently Contiki */ +/* jumps to LPM3 to save power, but DMA will not work if DCO is not clocked */ +/* so some modules might need to enter their LPM requirements */ +/* NOTE: currently only works with LPM1 (e.g. DCO) requirements. */ +/*---------------------------------------------------------------------------*/ +void +msp430_add_lpm_req(int req) +{ + if(req <= MSP430_REQUIRE_LPM1) { + msp430_dco_required++; + } +} +void +msp430_remove_lpm_req(int req) +{ + if(req <= MSP430_REQUIRE_LPM1) { + msp430_dco_required--; + } +} void msp430_cpu_init(void) { @@ -164,7 +188,7 @@ msp430_cpu_init(void) init_ports(); /* set DCO to a reasonable default value (8MHz) */ msp430_init_dco(); - /* calibrate the DCO step-by-step */ + /* calibrate the DCO step-by-step */ msp430_sync_dco(); eint(); #if defined(__MSP430__) && defined(__GNUC__) @@ -172,6 +196,7 @@ msp430_cpu_init(void) cur_break++; } #endif + msp430_dco_required = 0; } /*---------------------------------------------------------------------------*/ @@ -191,7 +216,7 @@ splhigh_(void) asmv("mov r2, %0" : "=r" (sr)); asmv("bic %0, r2" : : "i" (GIE)); #endif - return sr & GIE; /* Ignore other sr bits. */ + return sr & GIE; /* Ignore other sr bits. */ } /*---------------------------------------------------------------------------*/ /* @@ -209,7 +234,8 @@ splhigh_(void) /* } */ /*---------------------------------------------------------------------------*/ #ifdef __IAR_SYSTEMS_ICC__ -int __low_level_init(void) +int +__low_level_init(void) { /* turn off watchdog so that C-init will run */ WDTCTL = WDTPW + WDTHOLD; @@ -224,7 +250,8 @@ int __low_level_init(void) #endif /*---------------------------------------------------------------------------*/ void -msp430_sync_dco(void) { +msp430_sync_dco(void) +{ uint16_t oldcapture; int16_t diff; /* DELTA_2 assumes an ACLK of 32768 Hz */ @@ -260,7 +287,7 @@ msp430_sync_dco(void) { if(DCOCTL == 0x00) { /* Did DCO roll over? */ BCSCTL1++; } - /* -> Select next higher RSEL */ + /* -> Select next higher RSEL */ } } diff --git a/cpu/msp430/f2xxx/uart0.c b/cpu/msp430/f2xxx/uart0.c index 0a17636fb..79c75f877 100644 --- a/cpu/msp430/f2xxx/uart0.c +++ b/cpu/msp430/f2xxx/uart0.c @@ -51,6 +51,11 @@ static volatile uint8_t transmitting; #define TX_WITH_INTERRUPT 1 #endif /* UART0_CONF_TX_WITH_INTERRUPT */ +#ifdef UART0_CONF_RX_WITH_DMA +#define RX_WITH_DMA UART0_CONF_RX_WITH_DMA +#else /* UART0_CONF_RX_WITH_DMA */ +#define RX_WITH_DMA 1 +#endif /* UART0_CONF_RX_WITH_DMA */ #if TX_WITH_INTERRUPT #define TXBUFSIZE 64 @@ -59,6 +64,30 @@ static struct ringbuf txbuf; static uint8_t txbuf_data[TXBUFSIZE]; #endif /* TX_WITH_INTERRUPT */ +#if RX_WITH_DMA +#define RXBUFSIZE 128 + +static uint8_t rxbuf[RXBUFSIZE]; +static uint16_t last_size; +static struct ctimer rxdma_timer; + +static void +handle_rxdma_timer(void *ptr) +{ + uint16_t size; + size = DMA0SZ; /* Note: loop requires that size is less or eq to RXBUFSIZE */ + while(last_size != size) { + uart0_input_handler((unsigned char)rxbuf[RXBUFSIZE - last_size]); + last_size--; + if(last_size == 0) { + last_size = RXBUFSIZE; + } + } + + ctimer_reset(&rxdma_timer); +} +#endif /* RX_WITH_DMA */ + /*---------------------------------------------------------------------------*/ uint8_t uart0_active(void) @@ -69,6 +98,9 @@ uart0_active(void) void uart0_set_input(int (*input)(unsigned char c)) { +#if RX_WITH_DMA /* This needs to be called after ctimer process is started */ + ctimer_set(&rxdma_timer, CLOCK_SECOND / 64, handle_rxdma_timer, NULL); +#endif uart0_input_handler = input; } /*---------------------------------------------------------------------------*/ @@ -100,8 +132,8 @@ uart0_writeb(unsigned char c) #endif /* TX_WITH_INTERRUPT */ } /*---------------------------------------------------------------------------*/ -#if ! WITH_UIP /* If WITH_UIP is defined, putchar() is defined by the SLIP driver */ -#endif /* ! WITH_UIP */ +#if !NETSTACK_CONF_WITH_IPV4 /* If NETSTACK_CONF_WITH_IPV4 is defined, putchar() is defined by the SLIP driver */ +#endif /* ! NETSTACK_CONF_WITH_IPV4 */ /*---------------------------------------------------------------------------*/ /** * Initalize the RS232 port. @@ -135,8 +167,24 @@ uart0_init(unsigned long ubr) ringbuf_init(&txbuf, txbuf_data, sizeof(txbuf_data)); IE2 |= UCA0TXIE; /* Enable UCA0 TX interrupt */ #endif /* TX_WITH_INTERRUPT */ + +#if RX_WITH_DMA + IE2 &= ~UCA0RXIE; /* disable USART0 RX interrupt */ + /* UART0_RX trigger */ + DMACTL0 = DMA0TSEL_3; + + /* source address = UCA0RXBUF */ + DMA0SA = (unsigned int)&UCA0RXBUF; + DMA0DA = (unsigned int)&rxbuf; + DMA0SZ = RXBUFSIZE; + last_size = RXBUFSIZE; + DMA0CTL = DMADT_4 + DMASBDB + DMADSTINCR_3 + DMAEN + DMAREQ; + + msp430_add_lpm_req(MSP430_REQUIRE_LPM1); +#endif /* RX_WITH_DMA */ } /*---------------------------------------------------------------------------*/ +#if !RX_WITH_DMA ISR(USCIAB0RX, uart0_rx_interrupt) { uint8_t c; @@ -148,18 +196,19 @@ ISR(USCIAB0RX, uart0_rx_interrupt) c = UCA0RXBUF; if(uart0_input_handler != NULL) { if(uart0_input_handler(c)) { - LPM4_EXIT; + LPM4_EXIT; } } } ENERGEST_OFF(ENERGEST_TYPE_IRQ); } +#endif /* !RX_WITH_DMA */ /*---------------------------------------------------------------------------*/ #if TX_WITH_INTERRUPT ISR(USCIAB0TX, uart0_tx_interrupt) { ENERGEST_ON(ENERGEST_TYPE_IRQ); - if((IFG2 & UCA0TXIFG)){ + if((IFG2 & UCA0TXIFG)) { if(ringbuf_elements(&txbuf) == 0) { transmitting = 0; diff --git a/cpu/msp430/f2xxx/uart1.c b/cpu/msp430/f2xxx/uart1.c index 3085663bf..42ba9b5b0 100644 --- a/cpu/msp430/f2xxx/uart1.c +++ b/cpu/msp430/f2xxx/uart1.c @@ -97,8 +97,8 @@ uart1_writeb(unsigned char c) #endif /* TX_WITH_INTERRUPT */ } /*---------------------------------------------------------------------------*/ -#if ! WITH_UIP /* If WITH_UIP is defined, putchar() is defined by the SLIP driver */ -#endif /* ! WITH_UIP */ +#if ! NETSTACK_CONF_WITH_IPV4 /* If NETSTACK_CONF_WITH_IPV4 is defined, putchar() is defined by the SLIP driver */ +#endif /* ! NETSTACK_CONF_WITH_IPV4 */ /*---------------------------------------------------------------------------*/ /** * Initalize the RS232 port. diff --git a/cpu/msp430/f5xxx/clock.c b/cpu/msp430/f5xxx/clock.c index 3cda89232..1def811e6 100644 --- a/cpu/msp430/f5xxx/clock.c +++ b/cpu/msp430/f5xxx/clock.c @@ -41,12 +41,26 @@ #define MAX_TICKS (~((clock_time_t)0) / 2) +#define CLOCK_LT(a, b) ((int16_t)((a)-(b)) < 0) + static volatile unsigned long seconds; static volatile clock_time_t count = 0; /* last_tar is used for calculating clock_fine, last_ccr might be better? */ static volatile uint16_t last_tar = 0; /*---------------------------------------------------------------------------*/ +static inline uint16_t +read_tar(void) +{ + /* Same as clock_counter(), but can be inlined */ + uint16_t t1, t2; + do { + t1 = TA1R; + t2 = TA1R; + } while(t1 != t2); + return t1; +} +/*---------------------------------------------------------------------------*/ ISR(TIMER1_A1, timera1) { ENERGEST_ON(ENERGEST_TYPE_IRQ); @@ -59,8 +73,9 @@ ISR(TIMER1_A1, timera1) * Occurs when timer state is toggled between STOP and CONT. */ while(TA1CTL & MC1 && TA1CCR1 - TA1R == 1); + last_tar = read_tar(); /* Make sure interrupt time is future */ - do { + while(!CLOCK_LT(last_tar, TA1CCR1)) { TA1CCR1 += INTERVAL; ++count; @@ -76,9 +91,8 @@ ISR(TIMER1_A1, timera1) ++seconds; energest_flush(); } - } while((TA1CCR1 - TA1R) > INTERVAL); - - last_tar = TA1R; + last_tar = read_tar(); + } if(etimer_pending() && (etimer_next_expiration_time() - count - 1) > MAX_TICKS) { @@ -178,7 +192,7 @@ clock_delay(unsigned int i) } } /*---------------------------------------------------------------------------*/ -/** +/* * Wait for a multiple of 10 ms. * */ diff --git a/cpu/msp430/f5xxx/uart1.c b/cpu/msp430/f5xxx/uart1.c index 8680b1867..4937ff025 100644 --- a/cpu/msp430/f5xxx/uart1.c +++ b/cpu/msp430/f5xxx/uart1.c @@ -44,6 +44,36 @@ static int (*uart1_input_handler)(unsigned char c); static volatile uint8_t transmitting; +#ifdef UART1_CONF_RX_WITH_DMA +#define RX_WITH_DMA UART1_CONF_RX_WITH_DMA +#else /* UART1_CONF_RX_WITH_DMA */ +#define RX_WITH_DMA 1 +#endif /* UART1_CONF_RX_WITH_DMA */ + +#if RX_WITH_DMA +#define RXBUFSIZE 128 + +static uint8_t rxbuf[RXBUFSIZE]; +static uint16_t last_size; +static struct ctimer rxdma_timer; + +static void +handle_rxdma_timer(void *ptr) +{ + uint16_t size; + size = DMA0SZ; /* Note: loop requires that size is less or eq to RXBUFSIZE */ + while(last_size != size) { + uart1_input_handler((unsigned char)rxbuf[RXBUFSIZE - last_size]); + last_size--; + if(last_size == 0) { + last_size = RXBUFSIZE; + } + } + + ctimer_reset(&rxdma_timer); +} +#endif /* RX_WITH_DMA */ + /*---------------------------------------------------------------------------*/ uint8_t uart1_active(void) @@ -54,6 +84,9 @@ uart1_active(void) void uart1_set_input(int (*input)(unsigned char c)) { +#if RX_WITH_DMA /* This needs to be called after ctimer process is started */ + ctimer_set(&rxdma_timer, CLOCK_SECOND / 64, handle_rxdma_timer, NULL); +#endif uart1_input_handler = input; } /*---------------------------------------------------------------------------*/ @@ -86,8 +119,8 @@ uart1_init(unsigned long ubr) UCA1MCTL = UCBRS_3; /* Modulation UCBRSx = 3 */ P4DIR |= BIT5; - P4OUT |= BIT5 ; - P5SEL |= BIT6|BIT7; // P5.6,7 = USCI_A1 TXD/RXD + P4OUT |= BIT5; + P5SEL |= BIT6 | BIT7; /* P5.6,7 = USCI_A1 TXD/RXD */ P4SEL |= BIT7; P4DIR |= BIT7; @@ -102,14 +135,30 @@ uart1_init(unsigned long ubr) UCA1CTL1 &= ~UCSWRST; /* Initialize USCI state machine **before** enabling interrupts */ UCA1IE |= UCRXIE; /* Enable UCA1 RX interrupt */ + +#if RX_WITH_DMA + UCA1IE &= ~UCRXIE; /* disable USART1 RX interrupt */ + /* UART1_RX trigger */ + DMACTL0 = DMA0TSEL_20; + + /* source address = RXBUF1 */ + DMA0SA = (unsigned int)&UCA1RXBUF; + DMA0DA = (unsigned int)&rxbuf; + DMA0SZ = RXBUFSIZE; + last_size = RXBUFSIZE; + DMA0CTL = DMADT_4 + DMASBDB + DMADSTINCR_3 + DMAEN + DMAREQ; + + msp430_add_lpm_req(MSP430_REQUIRE_LPM1); +#endif /* RX_WITH_DMA */ } /*---------------------------------------------------------------------------*/ +#if !RX_WITH_DMA ISR(USCI_A1, uart1_rx_interrupt) { uint8_t c; ENERGEST_ON(ENERGEST_TYPE_IRQ); - if (UCA1IV == 2) { + if(UCA1IV == 2) { if(UCA1STAT & UCRXERR) { c = UCA1RXBUF; /* Clear error flags by forcing a dummy read. */ } else { @@ -123,4 +172,5 @@ ISR(USCI_A1, uart1_rx_interrupt) } ENERGEST_OFF(ENERGEST_TYPE_IRQ); } +#endif /* !RX_WITH_DMA */ /*---------------------------------------------------------------------------*/ diff --git a/cpu/msp430/minileds.c b/cpu/msp430/minileds.c index 3a2a6eabf..ce5f97392 100644 --- a/cpu/msp430/minileds.c +++ b/cpu/msp430/minileds.c @@ -74,10 +74,5 @@ leds_off(unsigned char leds) void leds_toggle(unsigned char leds) { - /* - * Synonym: void leds_invert(unsigned char leds); - */ - asm(".global leds_invert\nleds_invert:\n"); - LEDS_PxOUT ^= l2p[leds & LEDS_ALL]; } diff --git a/cpu/msp430/rtimer-arch.h b/cpu/msp430/rtimer-arch.h index 446ef99e1..6063292b1 100644 --- a/cpu/msp430/rtimer-arch.h +++ b/cpu/msp430/rtimer-arch.h @@ -48,6 +48,20 @@ #define RTIMER_ARCH_SECOND (4096U*8) #endif +/* Do the math in 32bits to save precision. + * Round to nearest integer rather than truncate. */ +#define US_TO_RTIMERTICKS(US) ((US) >= 0 ? \ + (((int32_t)(US) * (RTIMER_ARCH_SECOND) + 500000) / 1000000L) : \ + ((int32_t)(US) * (RTIMER_ARCH_SECOND) - 500000) / 1000000L) + +#define RTIMERTICKS_TO_US(T) ((T) >= 0 ? \ + (((int32_t)(T) * 1000000L + ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND)) : \ + ((int32_t)(T) * 1000000L - ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND)) + +/* A 64-bit version because the 32-bit one cannot handle T >= 4295 ticks. + Intended only for positive values of T. */ +#define RTIMERTICKS_TO_US_64(T) ((uint32_t)(((uint64_t)(T) * 1000000 + ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND))) + rtimer_clock_t rtimer_arch_now(void); #endif /* RTIMER_ARCH_H_ */ diff --git a/cpu/msp430/slip_uart0.c b/cpu/msp430/slip_uart0.c index c7b003f06..f764176c5 100644 --- a/cpu/msp430/slip_uart0.c +++ b/cpu/msp430/slip_uart0.c @@ -49,7 +49,7 @@ slip_arch_writeb(unsigned char c) * */ /*---------------------------------------------------------------------------*/ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 int putchar(int c) { @@ -75,7 +75,7 @@ putchar(int c) return c; } -#endif +#endif /* NETSTACK_CONF_WITH_IPV4 */ /*---------------------------------------------------------------------------*/ /** * Initalize the RS232 port and the SLIP driver. diff --git a/cpu/msp430/slip_uart1.c b/cpu/msp430/slip_uart1.c index 3a4c238c9..9289521c2 100644 --- a/cpu/msp430/slip_uart1.c +++ b/cpu/msp430/slip_uart1.c @@ -49,7 +49,7 @@ slip_arch_writeb(unsigned char c) * */ /*---------------------------------------------------------------------------*/ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 int putchar(int c) { @@ -75,7 +75,7 @@ putchar(int c) return c; } -#endif +#endif /* NETSTACK_CONF_WITH_IPV4 */ /*---------------------------------------------------------------------------*/ /** * Initalize the RS232 port and the SLIP driver. diff --git a/cpu/native/Makefile.native b/cpu/native/Makefile.native index bf4e8ea47..2adb48070 100644 --- a/cpu/native/Makefile.native +++ b/cpu/native/Makefile.native @@ -14,10 +14,10 @@ NM ?= nm OBJCOPY ?= objcopy STRIP ?= strip ifdef WERROR -CFLAGSWERROR=-Werror -pedantic -std=c99 -Werror +CFLAGSWERROR=-Werror endif CFLAGSNO = -Wall -g -I/usr/local/include $(CFLAGSWERROR) -CFLAGS += $(CFLAGSNO) -O +CFLAGS += $(CFLAGSNO) ifeq ($(HOST_OS),Darwin) AROPTS = -r @@ -25,7 +25,7 @@ LDFLAGS += -Wl,-flat_namespace CFLAGS += -DHAVE_SNPRINTF=1 -U__ASSERT_USE_STDERR else ifeq ($(HOST_OS),Linux) -LDFLAGS = -Wl,-Map=contiki-$(TARGET).map,-export-dynamic +LDFLAGS += -Wl,-Map=contiki-$(TARGET).map,-export-dynamic endif endif diff --git a/cpu/native/net/linuxradio-drv.c b/cpu/native/net/linuxradio-drv.c new file mode 100644 index 000000000..a2be32940 --- /dev/null +++ b/cpu/native/net/linuxradio-drv.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2013, Google + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * Author: Vladimir Pouzanov + * + */ + +#include "contiki.h" +#include "contiki-conf.h" + +#if defined(linux) && NETSTACK_CONF_WITH_IPV6 + +#include "linuxradio-drv.h" + +#include "net/packetbuf.h" +#include "net/netstack.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +static int sockfd = -1; +static char *sockbuf; +static int buflen; + +#define MAX_PACKET_SIZE 256 + +static int +init(void) +{ + sockbuf = malloc(MAX_PACKET_SIZE); + if(sockbuf == 0) { + return 1; + } + return 0; +} +static int +prepare(const void *payload, unsigned short payload_len) +{ + if(payload_len > MAX_PACKET_SIZE) { + return 0; + } + memcpy(sockbuf, payload, payload_len); + buflen = payload_len; + + return 0; +} +static int +transmit(unsigned short transmit_len) +{ + int sent = 0; + sent = send(sockfd, sockbuf, buflen, 0); + if(sent < 0) { + perror("linuxradio send()"); + return RADIO_TX_ERR; + } + buflen = 0; + return RADIO_TX_OK; +} +static int +my_send(const void *payload, unsigned short payload_len) +{ + int ret = -1; + + if(prepare(payload, payload_len)) { + return ret; + } + + ret = transmit(payload_len); + + return ret; +} +static int +my_read(void *buf, unsigned short buf_len) +{ + return 0; +} +static int +channel_clear(void) +{ + return 1; +} +static int +receiving_packet(void) +{ + return 0; +} +static int +pending_packet(void) +{ + return 0; +} +static int +set_fd(fd_set *rset, fd_set *wset) +{ + FD_SET(sockfd, rset); + return 1; +} +static void +handle_fd(fd_set *rset, fd_set *wset) +{ + if(FD_ISSET(sockfd, rset)) { + int bytes = read(sockfd, sockbuf, MAX_PACKET_SIZE); + buflen = bytes; + memcpy(packetbuf_dataptr(), sockbuf, bytes); + packetbuf_set_datalen(bytes); + NETSTACK_RDC.input(); + } +} + +static const struct select_callback linuxradio_sock_callback = { set_fd, handle_fd }; + +static int +on(void) +{ + struct ifreq ifr; + int err; + struct sockaddr_ll sll; + + sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IEEE802154)); + if(sockfd < 0) { + perror("linuxradio socket()"); + return 0; + } else { + strncpy((char *)ifr.ifr_name, NETSTACK_CONF_LINUXRADIO_DEV, IFNAMSIZ); + err = ioctl(sockfd, SIOCGIFINDEX, &ifr); + if(err == -1) { + perror("linuxradio ioctl()"); + return 0; + } + sll.sll_family = AF_PACKET; + sll.sll_ifindex = ifr.ifr_ifindex; + sll.sll_protocol = htons(ETH_P_IEEE802154); + + if(bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) < 0) { + perror("linuxradio bind()"); + return 0; + } + + select_set_callback(sockfd, &linuxradio_sock_callback); + return 1; + } +} +static int +off(void) +{ + close(sockfd); + sockfd = -1; + return 1; +} +const struct radio_driver linuxradio_driver = +{ + init, + prepare, + transmit, + my_send, + my_read, + channel_clear, + receiving_packet, + pending_packet, + on, + off, +}; + +#endif diff --git a/cpu/native/net/linuxradio-drv.h b/cpu/native/net/linuxradio-drv.h new file mode 100644 index 000000000..fddf38d01 --- /dev/null +++ b/cpu/native/net/linuxradio-drv.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013, Google + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * Author: Vladimir Pouzanov + * + */ + +#ifndef __LINUXRADIO_DRV_H__ +#define __LINUXRADIO_DRV_H__ + +#include "dev/radio.h" + +extern const struct radio_driver linuxradio_driver; + +#endif diff --git a/cpu/native/net/tapdev-drv.c b/cpu/native/net/tapdev-drv.c index 0588030cb..d2d4a1ac0 100644 --- a/cpu/native/net/tapdev-drv.c +++ b/cpu/native/net/tapdev-drv.c @@ -34,11 +34,11 @@ #include "net/ip/uip.h" #include "net/ip/uipopt.h" -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #include "tapdev6.h" #else #include "tapdev.h" -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #include "tapdev-drv.h" @@ -48,7 +48,7 @@ PROCESS(tapdev_process, "TAP driver"); /*---------------------------------------------------------------------------*/ -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 uint8_t tapdev_output(void) { @@ -64,16 +64,16 @@ pollhandler(void) uip_len = tapdev_poll(); if(uip_len > 0) { -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) { tcpip_input(); } else -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) { uip_len -= sizeof(struct uip_eth_hdr); tcpip_input(); } else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) { -#if !UIP_CONF_IPV6 //math +#if !NETSTACK_CONF_WITH_IPV6 //math uip_arp_arpin(); /* If the above function invocation resulted in data that should be sent out on the network, the global variable @@ -83,7 +83,7 @@ pollhandler(void) } #endif } else { - uip_len = 0; + uip_clear_buf(); } } } @@ -95,7 +95,7 @@ PROCESS_THREAD(tapdev_process, ev, data) PROCESS_BEGIN(); tapdev_init(); -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 tcpip_set_outputfunc(tapdev_output); #else tcpip_set_outputfunc(tapdev_send); diff --git a/cpu/native/net/tapdev.c b/cpu/native/net/tapdev.c index 7ddf7ea10..b60cd1946 100644 --- a/cpu/native/net/tapdev.c +++ b/cpu/native/net/tapdev.c @@ -36,7 +36,7 @@ #include "net/ip/uip.h" #include "net/ip/uipopt.h" -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 #include #include @@ -93,8 +93,11 @@ static void remove_route(void) { char buf[1024]; + int ret; + snprintf(buf, sizeof(buf), "route delete -net 172.18.0.0"); - system(buf); + ret = system(buf); + fprintf(stderr, "ret %d\n", ret); fprintf(stderr, "%s\n", buf); } @@ -103,7 +106,8 @@ void tapdev_init(void) { char buf[1024]; - + int ret; + fd = open(DEVTAP, O_RDWR); if(fd == -1) { perror("tapdev: tapdev_init: open"); @@ -123,7 +127,8 @@ tapdev_init(void) #endif /* Linux */ snprintf(buf, sizeof(buf), "ifconfig tap0 inet 172.18.0.1/16"); - system(buf); + ret = system(buf); + fprintf(stderr, "ret %d\n", ret); fprintf(stderr, "%s\n", buf); #ifdef linux /* route add for linux */ @@ -132,8 +137,9 @@ tapdev_init(void) /* route add for freebsd */ snprintf(buf, sizeof(buf), "route add -net 172.18.0.0/16 -iface tap0"); #endif /* linux */ - - system(buf); + + ret = system(buf); + fprintf(stderr, "ret %d\n", ret); fprintf(stderr, "%s\n", buf); atexit(remove_route); @@ -204,4 +210,4 @@ tapdev_exit(void) } /*---------------------------------------------------------------------------*/ -#endif /* !UIP_CONF_IPV6 */ +#endif /* !NETSTACK_CONF_WITH_IPV6 */ diff --git a/cpu/native/net/tapdev6.c b/cpu/native/net/tapdev6.c index 41fbd7ae6..d69ac290e 100644 --- a/cpu/native/net/tapdev6.c +++ b/cpu/native/net/tapdev6.c @@ -36,7 +36,7 @@ #include "net/ip/uip.h" #include "net/ip/uipopt.h" -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #include #include @@ -331,7 +331,10 @@ tapdev_init(void) */ /* freebsd */ snprintf(buf, sizeof(buf), "ifconfig tap0 up"); - system(buf); + if(system(buf) == -1) { + perror("tapdev: system: ifconfig"); + return; + } printf("%s\n", buf); /* */ @@ -419,4 +422,4 @@ tapdev_exit(void) } /*---------------------------------------------------------------------------*/ -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ diff --git a/cpu/native/net/wpcap-drv.c b/cpu/native/net/wpcap-drv.c index 3362ec9c5..7ff8457b6 100644 --- a/cpu/native/net/wpcap-drv.c +++ b/cpu/native/net/wpcap-drv.c @@ -64,7 +64,7 @@ PROCESS(wpcap_process, "WinPcap driver"); /*---------------------------------------------------------------------------*/ -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 uint8_t wpcap_output(void) { @@ -73,7 +73,7 @@ wpcap_output(void) return 0; } -#endif /* !UIP_CONF_IPV6 */ +#endif /* !NETSTACK_CONF_WITH_IPV6 */ /*---------------------------------------------------------------------------*/ static void pollhandler(void) @@ -83,16 +83,16 @@ pollhandler(void) uip_len = wpcap_poll(); if(uip_len > 0) { -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) { // printf("wpcap poll calls tcpip"); tcpip_input(); } else -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) { uip_len -= sizeof(struct uip_eth_hdr); tcpip_input(); -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 } else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) { uip_arp_arpin(); //math /* If the above function invocation resulted in data that @@ -101,9 +101,9 @@ pollhandler(void) if(uip_len > 0) { wpcap_send(); } -#endif /* !UIP_CONF_IPV6 */ +#endif /* !NETSTACK_CONF_WITH_IPV6 */ } else { - uip_len = 0; + uip_clear_buf(); } } #endif @@ -125,16 +125,16 @@ pollhandler(void) tcpip_input(); } else goto bail; -#elif UIP_CONF_IPV6 +#elif NETSTACK_CONF_WITH_IPV6 if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) { tcpip_input(); } else goto bail; -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) { uip_len -= sizeof(struct uip_eth_hdr); tcpip_input(); -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 } else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) { uip_arp_arpin(); //math /* If the above function invocation resulted in data that @@ -143,10 +143,10 @@ pollhandler(void) if(uip_len > 0) { wfall_send(); } -#endif /* !UIP_CONF_IPV6 */ +#endif /* !NETSTACK_CONF_WITH_IPV6 */ } else { bail: - uip_len = 0; + uip_clear_buf(); } } #endif @@ -161,13 +161,13 @@ PROCESS_THREAD(wpcap_process, ev, data) wpcap_init(); -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 tcpip_set_outputfunc(wpcap_output); #else #if !FALLBACK_HAS_ETHERNET_HEADERS tcpip_set_outputfunc(wpcap_send); #endif -#endif /* !UIP_CONF_IPV6 */ +#endif /* !NETSTACK_CONF_WITH_IPV6 */ process_poll(&wpcap_process); diff --git a/cpu/native/net/wpcap.c b/cpu/native/net/wpcap.c index ddb698a05..301b07d91 100644 --- a/cpu/native/net/wpcap.c +++ b/cpu/native/net/wpcap.c @@ -68,7 +68,7 @@ #define FALLBACK_HAS_ETHERNET_HEADERS 1 #endif -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #include struct in6_addr addr6; char addr6str[64]; @@ -122,7 +122,7 @@ sprint_ip6addr(struct in6_addr addr, char * result) return (result - starting); } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #ifdef __CYGWIN__ @@ -158,7 +158,7 @@ static struct pcap *pcap; /* uip_lladdr is defined in uip.c. It is not used in uip6.c. * If needed for some purpose it can be defined here */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 //struct uip_eth_addr uip_lladdr; #endif @@ -174,7 +174,7 @@ static int (* pcap_sendpacket)(struct pcap *, unsigned char *, int); #ifdef UIP_FALLBACK_INTERFACE static struct pcap *pfall; struct in_addr addrfall; -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 struct in_addr6 addrfall6; #endif @@ -192,7 +192,7 @@ uint8_t wfall_send(const uip_lladdr_t *lladdr); static uip_ipaddr_t last_sender; #endif -static void +static int output(void) { #if FALLBACK_HAS_ETHERNET_HEADERS&&0 @@ -203,8 +203,8 @@ output(void) } uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr); #endif - PRINTF("FUT: %u\n", uip_len); - wfall_send(0); + PRINTF("FUT: %u\n", uip_len); + return wfall_send(0); } const struct uip_fallback_interface rpl_interface = { @@ -265,7 +265,7 @@ set_ethaddr(struct in_addr addr) adapters->PhysicalAddress[2], adapters->PhysicalAddress[3], adapters->PhysicalAddress[4], adapters->PhysicalAddress[5]); log_message("set_ethaddr: ethernetaddr: ", buffer); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 // int i;for (i=0;i<6;i++) uip_lladdr.addr[i] = adapters->PhysicalAddress[i]; #else uip_setethaddr((*(struct uip_eth_addr *)adapters->PhysicalAddress)); @@ -281,7 +281,7 @@ set_ethaddr(struct in_addr addr) } } -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /*---------------------------------------------------------------------------*/ static void set_ethaddr6(struct in_addr6 addr) @@ -327,7 +327,7 @@ set_ethaddr6(struct in_addr6 addr) adapters->PhysicalAddress[2], adapters->PhysicalAddress[3], adapters->PhysicalAddress[4], adapters->PhysicalAddress[5]); log_message("set_ethaddr: ethernetaddr: ", buffer); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 // int i;for (i=0;i<6;i++) uip_lladdr.addr[i] = adapters->PhysicalAddress[i]; //does this need doing? #else uip_setethaddr((*(struct uip_eth_addr *)adapters->PhysicalAddress)); @@ -396,7 +396,7 @@ init_pcap(struct in_addr addr) } #endif -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 } else if(paddr->addr != NULL && paddr->addr->sa_family == AF_INET6) { struct in6_addr interface_addr; @@ -431,7 +431,7 @@ init_pcap(struct in_addr addr) return; } #endif -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ } } } @@ -457,13 +457,13 @@ wpcap_init(void) #ifdef __CYGWIN__ if ((*__argv)[1]) { addr.s_addr = inet_addr((*__argv)[1]); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 uiplib_ipaddrconv((*__argv)[1],(uip_ipaddr_t*) &addr6.s6_addr); #endif #ifdef UIP_FALLBACK_INTERFACE if ((*__argv)[2]) { addrfall.s_addr = inet_addr((*__argv)[2]); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 uiplib_ipaddrconv((*__argv)[2],(uip_ipaddr_t*) &addrfall6.s6_addr); #endif } @@ -473,13 +473,13 @@ wpcap_init(void) #else /* __CYGWIN__ */ /* VC++ build on win32 platform. Currently the platform has no ipv6 support */ addr.s_addr = inet_addr(__argv[1]); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 if((__argv)[1]) uiplib_ipaddrconv((__argv)[1],(uip_ipaddr_t*) &addr6.s6_addr); #endif #ifdef UIP_FALLBACK_INTERFACE addrfall.s_addr = inet_addr(__argv[2]); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 if((__argv)[2]) uiplib_ipaddrconv((__argv)[2],(uip_ipaddr_t*) &addrfall6.s6_addr); #endif @@ -498,7 +498,7 @@ wpcap_init(void) #endif /* Use build defaults if not enough addresses passed */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #ifdef UIP_FALLBACK_INTERFACE if(addrfall.s_addr == INADDR_NONE) { @@ -525,7 +525,7 @@ wpcap_init(void) // } #else addr.s_addr = inet_addr("10.10.10.10"); //prefer ipv4 default for legacy compatibility -// uiplib_ipaddrconv("aaaa::1",(uip_ipaddr_t*) &addr6.s6_addr); +// uiplib_ipaddrconv("fd00::1",(uip_ipaddr_t*) &addr6.s6_addr); #endif #ifdef UIP_FALLBACK_INTERFACE @@ -561,7 +561,7 @@ wpcap_init(void) #endif log_message("usage: \n-->I'll try guessing ", inet_ntoa(addr)); } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #if DEBUG log_message("wpcap_init:Using ipv4 ", inet_ntoa(addr)); @@ -610,7 +610,7 @@ wpcap_poll(void) return 0; } -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /* Since pcap_setdirection(PCAP_D_IN) is not implemented in winpcap all outgoing packets * will be echoed back. The stack will ignore any packets not addressed to it, but initial * ipv6 neighbor solicitations are addressed to everyone and the echoed NS sent on startup @@ -649,7 +649,7 @@ wpcap_poll(void) } #endif -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ if(packet_header->caplen > UIP_BUFSIZE) { return 0; @@ -673,7 +673,7 @@ wfall_poll(void) case 0: return 0; } -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #if FALLBACK_HAS_ETHERNET_HEADERS #define ETHERNET_LLADDR_LEN 6 #else @@ -692,7 +692,7 @@ wfall_poll(void) PRINTF("Discarding echoed packet\n"); return 0; } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ if(packet_header->caplen > UIP_BUFSIZE) { return 0; @@ -706,7 +706,7 @@ wfall_poll(void) #endif /*---------------------------------------------------------------------------*/ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 uint8_t wpcap_send(const uip_lladdr_t *lladdr) { @@ -777,7 +777,7 @@ wfall_send(const uip_lladdr_t *lladdr) return 0; } #endif -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ void wpcap_send(void) { @@ -792,7 +792,7 @@ wpcap_send(void) error_exit("error on send\n"); } } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /*---------------------------------------------------------------------------*/ void wpcap_exit(void) diff --git a/cpu/native/net/wpcap.h b/cpu/native/net/wpcap.h index 964e6b0fc..6b943948c 100644 --- a/cpu/native/net/wpcap.h +++ b/cpu/native/net/wpcap.h @@ -38,7 +38,7 @@ void wpcap_init(void); uint16_t wpcap_poll(void); uint16_t wfall_poll(void); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 uint8_t wpcap_send(const uip_lladdr_t *lladdr); uint8_t wfall_send(const uip_lladdr_t *lladdr); #else diff --git a/cpu/nrf52832/Makefile.nrf52832 b/cpu/nrf52832/Makefile.nrf52832 new file mode 100644 index 000000000..f93f063f3 --- /dev/null +++ b/cpu/nrf52832/Makefile.nrf52832 @@ -0,0 +1,262 @@ +ifndef NRF52_SDK_ROOT + $(error NRF52_SDK_ROOT not defined! You must specify where nRF52 SDK resides!) +endif + +ifneq ($(filter %.flash erase,$(MAKECMDGOALS)),) +ifeq ($(NRF52_JLINK_PATH),) +NRF52_JLINK_PATH=$(shell location=$$(which JLinkExe) && dirname $$location) +endif +ifeq ($(NRF52_JLINK_PATH),) + $(error JLink not found in PATH and NRF52_JLINK_PATH path is not defined) +endif +endif + +ifeq ($(CONTIKI_WITH_RIME),1) + $(error Rime stack is not supported!) +endif + +ifneq ($(CONTIKI_WITH_IPV6),1) + $(error Only IPv6 stack is supported!) +endif + +$(info SDK: $(NRF52_SDK_ROOT)) + +ifeq ($(NRF52_DK_REVISION),) +NRF52_DK_REVISION=pca10040 +endif + +ifneq ($(NRF52_WITHOUT_SOFTDEVICE),1) + ifeq ($(NRF52_SOFTDEVICE),) + NRF52_SOFTDEVICE := $(shell find $(NRF52_SDK_ROOT) -name *iot*_softdevice.hex | head -n 1) + endif + $(info SoftDevice: $(NRF52_SOFTDEVICE)) + LINKER_SCRIPT := $(CONTIKI_CPU)/ld/nrf52-$(NRF52_DK_REVISION)-sd.ld +else + LINKER_SCRIPT := $(CONTIKI_CPU)/ld/nrf52.ld +endif + +OUTPUT_FILENAME := $(CONTIKI_PROJECT) +MAKEFILE_NAME := $(MAKEFILE_LIST) +MAKEFILE_DIR := $(dir $(MAKEFILE_NAME) ) + +TEMPLATE_PATH = $(NRF52_SDK_ROOT)/components/toolchain/gcc + +OBJECT_DIRECTORY = $(OBJECTDIR) +LISTING_DIRECTORY := $(OBJECTDIR) +OUTPUT_BINARY_DIRECTORY := bin_$(TARGET) + +MK := mkdir +RM := rm -rf + +# Toolchain commands +CC := arm-none-eabi-gcc +AS := arm-none-eabi-as +AR := arm-none-eabi-ar +LD := arm-none-eabi-ld +NM := arm-none-eabi-nm +OBJDUMP := arm-none-eabi-objdump +OBJCOPY := arm-none-eabi-objcopy +SIZE := arm-none-eabi-size + +# JLink +JLINK := $(NRF52_JLINK_PATH)/JLinkExe +JLINK_OPTS = -Device NRF52 -if swd -speed 1000 +ifneq ($(NRF52_JLINK_SN),) +JLINK_OPTS += -SelectEmuBySN $(NRF52_JLINK_SN) +endif + +#function for removing duplicates in a list +remduplicates = $(strip $(if $1,$(firstword $1) $(call remduplicates,$(filter-out $(firstword $1),$1)))) + +### CPU-dependent directories +CONTIKI_CPU_DIRS += . dev ble #compat + +### CPU-dependent source files +CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c uart0.c putchar.c watchdog.c + +ifneq ($(NRF52_WITHOUT_SOFTDEVICE),1) +CONTIKI_CPU_SOURCEFILES += ble-core.c ble-mac.c +endif + +CONTIKI_SOURCEFILES += $(CONTIKI_CPU_SOURCEFILES) + +#source common to all targets +C_SOURCE_FILES += $(NRF52_SDK_ROOT)/components/drivers_nrf/common/nrf_drv_common.c \ + $(NRF52_SDK_ROOT)/components/drivers_nrf/gpiote/nrf_drv_gpiote.c \ + $(NRF52_SDK_ROOT)/components/drivers_nrf/rtc/nrf_drv_rtc.c \ + $(NRF52_SDK_ROOT)/components/drivers_nrf/clock/nrf_drv_clock.c \ + $(NRF52_SDK_ROOT)/components/drivers_nrf/timer/nrf_drv_timer.c \ + $(NRF52_SDK_ROOT)/components/drivers_nrf/wdt/nrf_drv_wdt.c \ + $(NRF52_SDK_ROOT)/components/drivers_nrf/rng/nrf_drv_rng.c \ + $(NRF52_SDK_ROOT)/components/drivers_nrf/delay/nrf_delay.c \ + $(NRF52_SDK_ROOT)/components/drivers_nrf/uart/nrf_drv_uart.c \ + $(NRF52_SDK_ROOT)/components/libraries/util/app_error.c \ + $(NRF52_SDK_ROOT)/components/toolchain/system_nrf52.c + +ifneq ($(NRF52_WITHOUT_SOFTDEVICE),1) +C_SOURCE_FILES += $(NRF52_SDK_ROOT)/components/softdevice/common/softdevice_handler/softdevice_handler.c \ + $(NRF52_SDK_ROOT)/components/ble/common/ble_advdata.c +else +C_SOURCE_FILES += $(NRF52_SDK_ROOT)/components/libraries/fifo/app_fifo.c \ + $(NRF52_SDK_ROOT)/components/libraries/util/app_util_platform.c +endif + +#assembly files common to all targets +ASM_SOURCE_FILES = $(NRF52_SDK_ROOT)/components/toolchain/gcc/gcc_startup_nrf52.s + +#includes common to all targets +INC_PATHS += components/drivers_nrf/gpiote +INC_PATHS += components/drivers_nrf/hal +INC_PATHS += components/drivers_nrf/config +INC_PATHS += components/drivers_nrf/delay +INC_PATHS += components/drivers_nrf/uart +INC_PATHS += components/drivers_nrf/common +INC_PATHS += components/drivers_nrf/rtc +INC_PATHS += components/drivers_nrf/wdt +INC_PATHS += components/drivers_nrf/rng +INC_PATHS += components/drivers_nrf/clock +INC_PATHS += components/drivers_nrf/timer +INC_PATHS += components/libraries/util +INC_PATHS += components/libraries/timer +INC_PATHS += components/device +INC_PATHS += components/toolchain/gcc +INC_PATHS += components/toolchain +INC_PATHS += examples/bsp + +ifneq ($(NRF52_WITHOUT_SOFTDEVICE),1) +INC_PATHS += components/softdevice/s1xx_iot/headers +INC_PATHS += components/softdevice/s1xx_iot/headers/nrf52 +INC_PATHS += components/softdevice/common/softdevice_handler +INC_PATHS += components/ble/common +INC_PATHS += components/iot/common +INC_PATHS += components/iot/ble_ipsp +else +INC_PATHS += components/drivers_nrf/nrf_soc_nosd +INC_PATHS += components/libraries/fifo +endif + +EXTERNALDIRS += $(addprefix $(NRF52_SDK_ROOT)/, $(INC_PATHS)) + +# Sorting removes duplicates +BUILD_DIRECTORIES := $(sort $(OUTPUT_BINARY_DIRECTORY) $(LISTING_DIRECTORY)) + +# Clean files and directories +CLEAN += bin_$(TARGET) lst_$(TARGET) nrf52832.a *.elf *.hex + +#flags common to all targets +ifneq ($(NRF52_WITHOUT_SOFTDEVICE),1) +CFLAGS += -DSOFTDEVICE_PRESENT +CFLAGS += -DS132 +endif + +ifeq ($(SMALL),1) +CFLAGS += -Os +else +CFLAGS += -O2 +endif + +CFLAGS += -DNRF52 +CFLAGS += -DBOARD_$(shell echo $(NRF52_DK_REVISION) | tr a-z A-Z) +CFLAGS += -D__HEAP_SIZE=512 +CFLAGS += -DSWI_DISABLE0 +CFLAGS += -DCONFIG_GPIO_AS_PINRESET +CFLAGS += -DBLE_STACK_SUPPORT_REQD +CFLAGS += -mcpu=cortex-m4 +CFLAGS += -mthumb -mabi=aapcs --std=gnu99 +CFLAGS += -Wall -Werror +CFLAGS += -ggdb +CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 +# keep every function in separate section. This will allow linker to dump unused functions +CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing +CFLAGS += -fno-builtin --short-enums + +# keep every function in separate section. This will allow linker to dump unused functions +LDFLAGS += -Xlinker -Map=$(LISTING_DIRECTORY)/$(OUTPUT_FILENAME).map +LDFLAGS += -mthumb -mabi=aapcs -L $(TEMPLATE_PATH) -T$(LINKER_SCRIPT) +LDFLAGS += -mcpu=cortex-m4 +LDFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 +# let linker to dump unused sections +LDFLAGS += -Wl,--gc-sections +# use newlib in nano version +LDFLAGS += --specs=nano.specs -lc -lnosys + +# Assembler flags +ifneq ($(NRF52_WITHOUT_SOFTDEVICE),1) +ASMFLAGS += -DSOFTDEVICE_PRESENT +ASMFLAGS += -DS132 +endif +ASMFLAGS += -x assembler-with-cpp +ASMFLAGS += -DSWI_DISABLE0 +ASMFLAGS += -DNRF52 +ASMFLAGS += -DBOARD_$(shell echo $(NRF52_DK_REVISION) | tr a-z A-Z) +ASMFLAGS += -DCONFIG_GPIO_AS_PINRESET +ASMFLAGS += -DBLE_STACK_SUPPORT_REQD + +C_SOURCE_FILE_NAMES = $(notdir $(C_SOURCE_FILES)) +C_PATHS = $(call remduplicates, $(dir $(C_SOURCE_FILES) ) ) +C_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(C_SOURCE_FILE_NAMES:.c=.o) ) + +ASM_SOURCE_FILE_NAMES = $(notdir $(ASM_SOURCE_FILES)) +ASM_PATHS = $(call remduplicates, $(dir $(ASM_SOURCE_FILES) )) +ASM_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(ASM_SOURCE_FILE_NAMES:.s=.o) ) + +vpath %.c $(C_PATHS) +vpath %.s $(ASM_PATHS) + +OBJECTS = $(C_OBJECTS) $(ASM_OBJECTS) + +TARGET_LIBS= nrf52832.a $(NRF52_SDK_ROOT)/components/iot/ble_6lowpan/lib/ble_6lowpan.a + +### Don't treat the .elf as intermediate +.PRECIOUS: %.hex %.bin + +nrf52832.a: $(OBJECTS) + $(TRACE_AR) + $(Q)$(AR) $(AROPTS) $@ $^ + +### Compilation rules +CUSTOM_RULE_LINK=1 + +%.elf: $(TARGET_STARTFILES) %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a $(TARGET_LIBS) + $(TRACE_LD) + $(Q)$(CC) $(LDFLAGS) ${filter %o %.co %.a,$^} -o $@ + +# Assemble files +$(OBJECT_DIRECTORY)/%.o: %.s + @echo Compiling file: $(notdir $<) + $(Q)$(CC) $(ASMFLAGS) $(addprefix -I$(NRF52_SDK_ROOT)/, $(INC_PATHS)) -c -o $@ $< + +# Create binary file from the .out file +%.bin: %.elf + @echo Preparing: $@ + $(Q)$(OBJCOPY) -O binary $^ $@ + +# Create binary .hex file from the .out file +%.hex: %.elf + @echo Preparing: $@ + $(Q)$(OBJCOPY) -O ihex $^ $@ + +### We don't really need the .hex and .bin for the .$(TARGET) but let's make +### sure they get built +%.$(TARGET): %.elf %.hex %.bin + cp $*.elf $@ + $(Q)$(SIZE) $@ + +%.jlink: + sed -e 's/#OUTPUT_FILENAME#/$*.hex/' $(CONTIKI_CPU)/flash.jlink > $@ + +%.flash: %.hex %.jlink + @echo Flashing: $^ + $(JLINK) $(JLINK_OPTS) -CommanderScript $*.jlink + +softdevice.jlink: + sed -e 's,#OUTPUT_FILENAME#,$(NRF52_SOFTDEVICE),' $(CONTIKI_CPU)/flash.jlink > $@ + +softdevice.flash: softdevice.jlink + @echo Flashing: $(notdir $(NRF52_SOFTDEVICE)) + $(JLINK) $(JLINK_OPTS) -CommanderScript $^ + +erase: + $(JLINK) $(JLINK_OPTS) -CommanderScript $(CONTIKI_CPU)/erase.jlink + +.PHONY: softdevice.jlink diff --git a/cpu/nrf52832/ble/ble-core.c b/cpu/nrf52832/ble/ble-core.c new file mode 100644 index 000000000..cb3d4ce66 --- /dev/null +++ b/cpu/nrf52832/ble/ble-core.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \addtogroup cpu + * @{ + * + * \addtogroup nrf52832 + * @{ + * + * \addtogroup nrf52832-ble Bluetooth Low Energy drivers + * @{ + * + * \file + * Basic BLE functions. + * \author + * Wojciech Bober + * + */ +#include +#include +#include "boards.h" +#include "nordic_common.h" +#include "nrf_delay.h" +#include "nrf_sdm.h" +#include "ble_advdata.h" +#include "ble_srv_common.h" +#include "ble_ipsp.h" +#include "softdevice_handler.h" +#include "app_error.h" +#include "iot_defines.h" +#include "ble-core.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#define IS_SRVC_CHANGED_CHARACT_PRESENT 1 +#define APP_ADV_TIMEOUT 0 /**< Time for which the device must be advertising in non-connectable mode (in seconds). 0 disables timeout. */ +#define APP_ADV_ADV_INTERVAL MSEC_TO_UNITS(333, UNIT_0_625_MS) /**< The advertising interval. This value can vary between 100ms to 10.24s). */ + +static ble_gap_adv_params_t m_adv_params; /**< Parameters to be passed to the stack when starting advertising. */ + +static void +ble_evt_dispatch(ble_evt_t * p_ble_evt); +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize and enable the BLE stack. + */ +void +ble_stack_init(void) +{ + uint32_t err_code; + + // Enable BLE stack. + ble_enable_params_t ble_enable_params; + memset(&ble_enable_params, 0, sizeof(ble_enable_params)); + ble_enable_params.gatts_enable_params.attr_tab_size = + BLE_GATTS_ATTR_TAB_SIZE_DEFAULT; + ble_enable_params.gatts_enable_params.service_changed = + IS_SRVC_CHANGED_CHARACT_PRESENT; + err_code = sd_ble_enable(&ble_enable_params); + APP_ERROR_CHECK(err_code); + + // Register with the SoftDevice handler module for BLE events. + err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch); + APP_ERROR_CHECK(err_code); + + // Setup address + ble_gap_addr_t ble_addr; + err_code = sd_ble_gap_address_get(&ble_addr); + APP_ERROR_CHECK(err_code); + + ble_addr.addr[5] = 0x00; + ble_addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC; + + err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &ble_addr); + APP_ERROR_CHECK(err_code); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Return device EUI64 MAC address + * \param addr pointer to a buffer to store the address + */ +void +ble_get_mac(uint8_t addr[8]) +{ + uint32_t err_code; + ble_gap_addr_t ble_addr; + + err_code = sd_ble_gap_address_get(&ble_addr); + APP_ERROR_CHECK(err_code); + + IPV6_EUI64_CREATE_FROM_EUI48(addr, ble_addr.addr, ble_addr.addr_type); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize BLE advertising data. + * \param name Human readable device name that will be advertised + */ +void +ble_advertising_init(const char *name) +{ + uint32_t err_code; + ble_advdata_t advdata; + uint8_t flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; + ble_gap_conn_sec_mode_t sec_mode; + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); + + err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)name, + strlen(name)); + APP_ERROR_CHECK(err_code); + + ble_uuid_t adv_uuids[] = {{BLE_UUID_IPSP_SERVICE, BLE_UUID_TYPE_BLE}}; + + // Build and set advertising data. + memset(&advdata, 0, sizeof(advdata)); + + advdata.name_type = BLE_ADVDATA_FULL_NAME; + advdata.flags = flags; + advdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]); + advdata.uuids_complete.p_uuids = adv_uuids; + + err_code = ble_advdata_set(&advdata, NULL); + APP_ERROR_CHECK(err_code); + + // Initialize advertising parameters (used when starting advertising). + memset(&m_adv_params, 0, sizeof(m_adv_params)); + + m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; + m_adv_params.p_peer_addr = NULL; // Undirected advertisement. + m_adv_params.fp = BLE_GAP_ADV_FP_ANY; + m_adv_params.interval = APP_ADV_ADV_INTERVAL; + m_adv_params.timeout = APP_ADV_TIMEOUT; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Start BLE advertising. + */ +void +ble_advertising_start(void) +{ + uint32_t err_code; + + err_code = sd_ble_gap_adv_start(&m_adv_params); + APP_ERROR_CHECK(err_code); + + PRINTF("ble-core: advertising started\n"); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Print GAP address. + * \param addr a pointer to address + */ +void +ble_gap_addr_print(const ble_gap_addr_t *addr) +{ + unsigned int i; + for(i = 0; i < sizeof(addr->addr); i++) { + if(i > 0) { + PRINTF(":"); + }PRINTF("%02x", addr->addr[i]); + }PRINTF(" (%d)", addr->addr_type); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Function for handling the Application's BLE Stack events. + * \param[in] p_ble_evt Bluetooth stack event. + */ +static void +on_ble_evt(ble_evt_t *p_ble_evt) +{ + switch(p_ble_evt->header.evt_id) { + case BLE_GAP_EVT_CONNECTED: + PRINTF("ble-core: connected [handle:%d, peer: ", p_ble_evt->evt.gap_evt.conn_handle); + ble_gap_addr_print(&(p_ble_evt->evt.gap_evt.params.connected.peer_addr)); + PRINTF("]\n"); + sd_ble_gap_rssi_start(p_ble_evt->evt.gap_evt.conn_handle, + BLE_GAP_RSSI_THRESHOLD_INVALID, + 0); + break; + + case BLE_GAP_EVT_DISCONNECTED: + PRINTF("ble-core: disconnected [handle:%d]\n", p_ble_evt->evt.gap_evt.conn_handle); + ble_advertising_start(); + break; + default: + break; + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief SoftDevice BLE event callback. + * \param[in] p_ble_evt Bluetooth stack event. + */ +static void +ble_evt_dispatch(ble_evt_t *p_ble_evt) +{ + ble_ipsp_evt_handler(p_ble_evt); + on_ble_evt(p_ble_evt); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/cpu/nrf52832/ble/ble-core.h b/cpu/nrf52832/ble/ble-core.h new file mode 100644 index 000000000..84c181d2e --- /dev/null +++ b/cpu/nrf52832/ble/ble-core.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \addtogroup cpu + * @{ + * + * \addtogroup nrf52832 + * @{ + * + * \addtogroup nrf52832-ble Bluetooth Low Energy drivers + * @{ + * + * \file + * Basic BLE functions. + * \author + * Wojciech Bober + */ +#ifndef DEV_BLE_H_ +#define DEV_BLE_H_ + +#include + +void ble_stack_init(void); +void ble_advertising_init(const char *name); +void ble_advertising_start(void); +void ble_get_mac(uint8_t addr[8]); + +#endif /* DEV_BLE_H_ */ + +/** + * @} + * @} + * @} + */ diff --git a/cpu/nrf52832/ble/ble-mac.c b/cpu/nrf52832/ble/ble-mac.c new file mode 100644 index 000000000..6ffd87a82 --- /dev/null +++ b/cpu/nrf52832/ble/ble-mac.c @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \addtogroup nrf52832-ble + * @{ + * + * \file + * A MAC protocol implementation that uses nRF52 IPSP implementation + * as a link layer. + * \author + * Wojciech Bober + */ +#include +#include +#include "app_error.h" +#include "ble_ipsp.h" +#include "nrf_soc.h" +#include "iot_defines.h" + +#include "net/mac/nullmac.h" +#include "net/netstack.h" +#include "net/ip/uip.h" +#include "net/ip/tcpip.h" +#include "net/packetbuf.h" +#include "net/netstack.h" +#include "net/linkaddr.h" + +#include "dev/watchdog.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#ifndef BLE_MAC_MAX_INTERFACE_NUM +#define BLE_MAC_MAX_INTERFACE_NUM 1 /**< Maximum number of interfaces, i.e., connection to master devices */ +#endif + +/*---------------------------------------------------------------------------*/ +process_event_t ble_event_interface_added; /**< This event is broadcast when BLE connection is established */ +process_event_t ble_event_interface_deleted; /**< This event is broadcast when BLE connection is destroyed */ + +/*---------------------------------------------------------------------------*/ +PROCESS(ble_ipsp_process, "BLE IPSP process"); + +/*---------------------------------------------------------------------------*/ +/** + * \brief A structure that binds IPSP connection with a peer address. + */ +typedef struct { + eui64_t peer_addr; + ble_ipsp_handle_t handle; +} ble_mac_interface_t; + +static ble_mac_interface_t interfaces[BLE_MAC_MAX_INTERFACE_NUM]; + +static volatile int busy_tx; /**< Flag is set to 1 when the driver is busy transmitting a packet. */ +static volatile int busy_rx; /**< Flag is set to 1 when there is a received packet pending. */ + +struct { + eui64_t src; + uint8_t payload[PACKETBUF_SIZE]; + uint16_t len; + int8_t rssi; +} input_packet; + +static mac_callback_t mac_sent_cb; +static void *mac_sent_ptr; + +/*---------------------------------------------------------------------------*/ +/** + * \brief Lookup interface by IPSP connection. + * + * \param handle a pointer to IPSP handle. + * \retval a pointer to interface structure + * \retval NULL if no interface has been found for a given handle + */ +static ble_mac_interface_t * +ble_mac_interface_lookup(ble_ipsp_handle_t *handle) +{ + int i; + for(i = 0; i < BLE_MAC_MAX_INTERFACE_NUM; i++) { + if(interfaces[i].handle.conn_handle == handle->conn_handle && + interfaces[i].handle.cid == handle->cid) { + return &interfaces[i]; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Add IPSP connection to the interface table. + * + * This function binds IPSP connection with peer address. + * + * \param peer a pointer to eui64 address + * \param handle a pointer to IPSP handle + * + * \retval a pointer to an interface structure on success + * \retval NULL if interface table is full + */ +static ble_mac_interface_t * +ble_mac_interface_add(eui64_t *peer, ble_ipsp_handle_t *handle) +{ + int i; + for(i = 0; i < BLE_MAC_MAX_INTERFACE_NUM; i++) { + if(interfaces[i].handle.conn_handle == 0 && interfaces[i].handle.cid == 0) { + memcpy(&interfaces[i].handle, handle, sizeof(ble_ipsp_handle_t)); + memcpy(&interfaces[i].peer_addr, peer, sizeof(eui64_t)); + process_post(PROCESS_BROADCAST, ble_event_interface_added, NULL); + return &interfaces[i]; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Remove interface from the interface table. + * \param interface a pointer to interface + */ +static void +ble_mac_interface_delete(ble_mac_interface_t *interface) +{ + memset(interface, 0, sizeof(ble_mac_interface_t)); + process_post(PROCESS_BROADCAST, ble_event_interface_deleted, NULL); +} + +/*---------------------------------------------------------------------------*/ +/** + * \brief Callback registered with IPSP to receive asynchronous events from the module. + * \note This function is called from SoftDevice interrupt context. + * + * \param[in] p_handle Pointer to IPSP handle. + * \param[in] p_evt Pointer to specific event, generated by IPSP module. + * + * \return NRF_SUCCESS on success, otherwise NRF_ERROR_NO_MEM error. + */ +static uint32_t +ble_mac_ipsp_evt_handler_irq(ble_ipsp_handle_t *p_handle, ble_ipsp_evt_t *p_evt) +{ + uint32_t retval = NRF_SUCCESS; + + ble_mac_interface_t *p_instance = NULL; + p_instance = ble_mac_interface_lookup(p_handle); + + if(p_handle) { + PRINTF("ble-mac: IPSP event [handle:%d CID 0x%04X]\n", p_handle->conn_handle, p_handle->cid); + } + + switch(p_evt->evt_id) { + case BLE_IPSP_EVT_CHANNEL_CONNECTED: { + eui64_t peer_addr; + + PRINTF("ble-mac: channel connected\n"); + + IPV6_EUI64_CREATE_FROM_EUI48( + peer_addr.identifier, + p_evt->evt_param->params.ch_conn_request.peer_addr.addr, + p_evt->evt_param->params.ch_conn_request.peer_addr.addr_type); + + p_instance = ble_mac_interface_add(&peer_addr, p_handle); + + if(p_instance != NULL) { + PRINTF("ble-mac: added new IPSP interface\n"); + } else { + PRINTF("ble-mac: cannot add new interface. Table is full\n"); + ble_ipsp_disconnect(p_handle); + } + break; + } + + case BLE_IPSP_EVT_CHANNEL_DISCONNECTED: { + PRINTF("ble-mac: channel disconnected\n"); + if(p_instance != NULL) { + PRINTF("ble-mac: removed IPSP interface\n"); + ble_mac_interface_delete(p_instance); + } + break; + } + + case BLE_IPSP_EVT_CHANNEL_DATA_RX: { + PRINTF("ble-mac: data received\n"); + if(p_instance != NULL) { + if(busy_rx) { + PRINTF("ble-mac: packet dropped as input buffer is busy\n"); + break; + } + + if(p_evt->evt_param->params.ch_rx.len > PACKETBUF_SIZE) { + PRINTF("ble-mac: packet buffer is too small!\n"); + break; + } + + busy_rx = 1; + + input_packet.len = p_evt->evt_param->params.ch_rx.len; + memcpy(input_packet.payload, p_evt->evt_param->params.ch_rx.p_data, input_packet.len); + memcpy(input_packet.src.identifier, p_instance->peer_addr.identifier, sizeof(eui64_t)); + sd_ble_gap_rssi_get(p_handle->conn_handle, &input_packet.rssi); + + process_poll(&ble_ipsp_process); + } else { + PRINTF("ble-mac: got data to unknown interface!\n"); + } + break; + } + + case BLE_IPSP_EVT_CHANNEL_DATA_TX_COMPLETE: { + PRINTF("ble-mac: data transmitted\n"); + busy_tx = 0; + break; + } + } + + return retval; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(ble_ipsp_process, ev, data) +{ + PROCESS_BEGIN(); + + while(1) { + PROCESS_WAIT_EVENT(); + if(ev == PROCESS_EVENT_POLL) { + packetbuf_copyfrom(input_packet.payload, input_packet.len); + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, input_packet.rssi); + packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (const linkaddr_t *)input_packet.src.identifier); + packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &linkaddr_node_addr); + busy_rx = 0; + NETSTACK_LLSEC.input(); + } + } + + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +/** + * \brief Lookup IPSP handle by peer address. + * + * \param addr a pointer to eui64 address. + * \retval a pointer to IPSP handle on success + * \retval NULL if an IPSP handle for given address haven't been found + */ +static ble_ipsp_handle_t * +find_handle(const linkaddr_t *addr) +{ + int i; + for(i = 0; i < BLE_MAC_MAX_INTERFACE_NUM; i++) { + if(linkaddr_cmp((const linkaddr_t *)&interfaces[i].peer_addr, addr)) { + return &interfaces[i].handle; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Send packet on a given IPSP handle. + * + * \param handle a pointer to IPSP handle. + * \return 1 on success, 0 otherwise + */ +static int +send_to_peer(ble_ipsp_handle_t *handle) +{ + PRINTF("ble-mac: sending packet[GAP handle:%d CID:0x%04X]\n", handle->conn_handle, handle->cid); + return (ble_ipsp_send(handle, packetbuf_dataptr(), packetbuf_datalen()) == NRF_SUCCESS); +} +/*---------------------------------------------------------------------------*/ +static void +send_packet(mac_callback_t sent, void *ptr) +{ + int i; + const linkaddr_t *dest; + ble_ipsp_handle_t *handle; + int ret = 0; + + mac_sent_cb = sent; + mac_sent_ptr = ptr; + + dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER); + + if(linkaddr_cmp(dest, &linkaddr_null)) { + for(i = 0; i < BLE_MAC_MAX_INTERFACE_NUM; i++) { + if(interfaces[i].handle.cid != 0 && interfaces[i].handle.conn_handle != 0) { + ret = send_to_peer(&interfaces[i].handle); + watchdog_periodic(); + } + } + } else if((handle = find_handle(dest)) != NULL) { + ret = send_to_peer(handle); + } else { + PRINTF("ble-mac: no connection found for peer"); + } + + if(ret) { + busy_tx = 1; + while(busy_tx) { + watchdog_periodic(); + sd_app_evt_wait(); + } + mac_call_sent_callback(sent, ptr, MAC_TX_OK, 1); + } else { + mac_call_sent_callback(sent, ptr, MAC_TX_ERR, 1); + } +} +/*---------------------------------------------------------------------------*/ +static int +on(void) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +off(int keep_radio_on) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +static unsigned short +channel_check_interval(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ +// Initialize IPSP service + uint32_t err_code; + ble_ipsp_init_t ipsp_init_params; + + memset(&ipsp_init_params, 0, sizeof(ipsp_init_params)); + ipsp_init_params.evt_handler = ble_mac_ipsp_evt_handler_irq; + err_code = ble_ipsp_init(&ipsp_init_params); + APP_ERROR_CHECK(err_code); + + ble_event_interface_added = process_alloc_event(); + ble_event_interface_deleted = process_alloc_event(); + + process_start(&ble_ipsp_process, NULL); +} +/*---------------------------------------------------------------------------*/ +const struct mac_driver ble_ipsp_mac_driver = { + "nRF52 IPSP driver", + init, + send_packet, + NULL, + on, + off, + channel_check_interval, +}; +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/cpu/nrf52832/ble/ble-mac.h b/cpu/nrf52832/ble/ble-mac.h new file mode 100644 index 000000000..3dd9b82af --- /dev/null +++ b/cpu/nrf52832/ble/ble-mac.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \addtogroup nrf52832-ble + * @{ + * + * \file + * A MAC protocol implementation that uses nRF52 IPSP implementation + * as a link layer. + * \author + * Wojciech Bober + */ +#ifndef BLE_MAC_H_ +#define BLE_MAC_H_ + +#include "sys/process.h" +#include "net/mac/mac.h" + +extern const struct mac_driver ble_ipsp_mac_driver; /**< BLE over IPSP MAC driver structure */ +extern process_event_t ble_event_interface_added; /**< This event is broadcast when a new IPSP connection is established */ +extern process_event_t ble_event_interface_deleted; /**< This event is broadcast when a IPSP connection is deleted */ + +#endif /* BLE_MAC_H_ */ +/** + * @} + */ diff --git a/cpu/nrf52832/dev/clock.c b/cpu/nrf52832/dev/clock.c new file mode 100644 index 000000000..4ee09839d --- /dev/null +++ b/cpu/nrf52832/dev/clock.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ + +/** + * \addtogroup nrf52832 + * @{ + * + * \addtogroup nrf52832-dev Device drivers + * @{ + * + * \addtogroup nrf52832-clock Clock driver + * @{ + * + * \file + * Software clock implementation for the nRF52. + * \author + * Wojciech Bober + * + */ +/*---------------------------------------------------------------------------*/ +#include +#include +#include "nrf.h" +#include "nrf_drv_config.h" +#include "nrf_drv_rtc.h" +#include "nrf_drv_clock.h" +#include "nrf_delay.h" +#include "app_error.h" +#include "contiki.h" +#include "platform-conf.h" + +/*---------------------------------------------------------------------------*/ +const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE(PLATFORM_RTC_INSTANCE_ID); /**< RTC instance used for platform clock */ +/*---------------------------------------------------------------------------*/ +static volatile uint32_t ticks; +void clock_update(void); + +#define TICKS (RTC1_CONFIG_FREQUENCY/CLOCK_CONF_SECOND) + +/** + * \brief Function for handling the RTC0 interrupts + * \param int_type Type of interrupt to be handled + */ +static void +rtc_handler(nrf_drv_rtc_int_type_t int_type) +{ + if (int_type == NRF_DRV_RTC_INT_TICK) { + clock_update(); + } +} + +#ifndef SOFTDEVICE_PRESENT +/** \brief Function starting the internal LFCLK XTAL oscillator. + */ +static void +lfclk_config(void) +{ + ret_code_t err_code = nrf_drv_clock_init(NULL); + APP_ERROR_CHECK(err_code); + + nrf_drv_clock_lfclk_request(); +} +#endif + +/** + * \brief Function initialization and configuration of RTC driver instance. + */ +static void +rtc_config(void) +{ + uint32_t err_code; + + //Initialize RTC instance + err_code = nrf_drv_rtc_init(&rtc, NULL, rtc_handler); + APP_ERROR_CHECK(err_code); + + //Enable tick event & interrupt + nrf_drv_rtc_tick_enable(&rtc, true); + + //Power on RTC instance + nrf_drv_rtc_enable(&rtc); +} +/*---------------------------------------------------------------------------*/ +void +clock_init(void) +{ + ticks = 0; +#ifndef SOFTDEVICE_PRESENT + lfclk_config(); +#endif + rtc_config(); +} +/*---------------------------------------------------------------------------*/ +CCIF clock_time_t +clock_time(void) +{ + return (clock_time_t)(ticks & 0xFFFFFFFF); +} +/*---------------------------------------------------------------------------*/ +void +clock_update(void) +{ + ticks++; + if (etimer_pending()) { + etimer_request_poll(); + } +} +/*---------------------------------------------------------------------------*/ +CCIF unsigned long +clock_seconds(void) +{ + return (unsigned long)ticks/CLOCK_CONF_SECOND; +} +/*---------------------------------------------------------------------------*/ +void +clock_wait(clock_time_t i) +{ + clock_time_t start; + start = clock_time(); + while (clock_time() - start < (clock_time_t)i) { + __WFE(); + } +} +/*---------------------------------------------------------------------------*/ +void +clock_delay_usec(uint16_t dt) +{ + nrf_delay_us(dt); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Obsolete delay function but we implement it here since some code + * still uses it + */ +void +clock_delay(unsigned int i) +{ + clock_delay_usec(i); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/cpu/nrf52832/dev/lpm.h b/cpu/nrf52832/dev/lpm.h new file mode 100644 index 000000000..192165a49 --- /dev/null +++ b/cpu/nrf52832/dev/lpm.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \addtogroup nrf52832-dev Device drivers + * @{ + * + * \addtogroup nrf52832-lpm Low power mode functions + * @{ + * + * \file + * A header file for low power mode functions. + * \author + * Wojciech Bober + */ +#ifndef LPM_H +#define LPM_H + +#ifdef SOFTDEVICE_PRESENT +#include "nrf_soc.h" +#endif + +/** + * \brief Stop and wait for an event + * + */ +static inline void +lpm_drop(void) +{ +#ifdef SOFTDEVICE_PRESENT + sd_app_evt_wait(); +#else + __WFI(); +#endif +} + +#endif /* DEV_LPM_H_ */ +/** + * @} + * @} + */ diff --git a/platform/sensinode/dev/sensinode-sensors.c b/cpu/nrf52832/dev/random.c similarity index 59% rename from platform/sensinode/dev/sensinode-sensors.c rename to cpu/nrf52832/dev/random.c index c6dbbbfd5..d21bf18ff 100644 --- a/platform/sensinode/dev/sensinode-sensors.c +++ b/cpu/nrf52832/dev/random.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Loughborough University - Computer Science + * Copyright (c) 2015, Nordic Semiconductor * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,56 +26,65 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * This file is part of the Contiki operating system. */ - /** - * \file - * This module centrally controls all sensors on sensinode devices + * \addtogroup nrf52832 + * @{ * - * It respects configuration in contiki-conf.h + * \addtogroup nrf52832-dev Device drivers + * @{ + * + * \addtogroup nrf52832-rng Hardware random number generator + * @{ + * + * \file + * Random number generator routines exploiting the nRF52 hardware + * capabilities. + * + * This file overrides core/lib/random.c. * * \author - * George Oikonomou - + * Wojciech Bober */ - -#include "dev/sensinode-sensors.h" -#include "sys/energest.h" - -const struct sensors_sensor *sensors[] = { -#if ADC_SENSOR_ON - &adc_sensor, -#endif -#if BUTTON_SENSOR_ON - &button_1_sensor, - &button_2_sensor, -#endif - 0 -}; - -unsigned char sensors_flags[(sizeof(sensors) / sizeof(struct sensors_sensor *))]; - +#include +#include +#include "app_error.h" /*---------------------------------------------------------------------------*/ -void -sensinode_sensors_activate() +/** + * \brief Generates a new random number using the nRF52 RNG. + * \return a random number. + */ +unsigned short +random_rand(void) { - struct sensors_sensor *sensor; - sensor = sensors_first(); - while(sensor) { - sensor->configure(SENSORS_ACTIVE, 1); - sensor = sensors_next(sensor); - } - ENERGEST_ON(ENERGEST_TYPE_SENSORS); + unsigned short value = 42; + uint8_t available; + ret_code_t err_code; + + do { + nrf_drv_rng_bytes_available(&available); + } while (available < sizeof(value)); + + err_code = nrf_drv_rng_rand((uint8_t *)&value, sizeof(value)); + APP_ERROR_CHECK(err_code); + + return value; } /*---------------------------------------------------------------------------*/ +/** + * \brief Initialize the nRF52 random number generator. + * \param seed Ignored. It's here because the function prototype is in core. + * + */ void -sensinode_sensors_deactivate() +random_init(unsigned short seed) { - struct sensors_sensor *sensor; - sensor = sensors_first(); - while(sensor) { - sensor->configure(SENSORS_ACTIVE, 0); - sensor = sensors_next(sensor); - } - ENERGEST_OFF(ENERGEST_TYPE_SENSORS); + (void)seed; + ret_code_t err_code = nrf_drv_rng_init(NULL); + APP_ERROR_CHECK(err_code); } +/** + * @} + * @} + * @} + */ diff --git a/cpu/nrf52832/dev/uart0.c b/cpu/nrf52832/dev/uart0.c new file mode 100644 index 000000000..df9c7b9e3 --- /dev/null +++ b/cpu/nrf52832/dev/uart0.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \addtogroup nrf52832-dev Device drivers + * @{ + * + * \addtogroup nrf52832-uart UART driver + * @{ + * + * \file + * Contiki compatible UART driver. + * \author + * Wojciech Bober + */ +#include +#include "nrf.h" +#include "nrf_drv_config.h" +#include "nrf_drv_uart.h" +#include "app_util_platform.h" +#include "app_error.h" + +#include "contiki.h" +#include "dev/uart0.h" +#include "dev/watchdog.h" +#include "lib/ringbuf.h" + +#define TXBUFSIZE 128 +static uint8_t rx_buffer[1]; + +static int (*uart0_input_handler)(unsigned char c); + +static struct ringbuf txbuf; +static uint8_t txbuf_data[TXBUFSIZE]; + +/*---------------------------------------------------------------------------*/ +static void +uart_event_handler(nrf_drv_uart_event_t * p_event, void * p_context) +{ + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + if (p_event->type == NRF_DRV_UART_EVT_RX_DONE) { + if (uart0_input_handler != NULL) { + uart0_input_handler(p_event->data.rxtx.p_data[0]); + } + (void)nrf_drv_uart_rx(rx_buffer, 1); + } else if (p_event->type == NRF_DRV_UART_EVT_TX_DONE) { + if (ringbuf_elements(&txbuf) > 0) { + uint8_t c = ringbuf_get(&txbuf); + nrf_drv_uart_tx(&c, 1); + } + } + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +void +uart0_set_input(int (*input)(unsigned char c)) +{ + uart0_input_handler = input; +} +/*---------------------------------------------------------------------------*/ +void +uart0_writeb(unsigned char c) +{ + if (nrf_drv_uart_tx(&c, 1) == NRF_ERROR_BUSY) { + while (ringbuf_put(&txbuf, c) == 0) { + __WFE(); + } + } +} +/*---------------------------------------------------------------------------*/ +/** + * Initialize the RS232 port. + * + */ +void +uart0_init(unsigned long ubr) +{ + nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG; + ret_code_t retcode = nrf_drv_uart_init(&config, uart_event_handler); + APP_ERROR_CHECK(retcode); + + ringbuf_init(&txbuf, txbuf_data, sizeof(txbuf_data)); + + nrf_drv_uart_rx_enable(); + nrf_drv_uart_rx(rx_buffer, 1); +} +/** + * @} + * @} + */ diff --git a/cpu/nrf52832/dev/uart0.h b/cpu/nrf52832/dev/uart0.h new file mode 100644 index 000000000..c6b3938ea --- /dev/null +++ b/cpu/nrf52832/dev/uart0.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \addtogroup nrf52832-dev Device drivers + * @{ + * + * \addtogroup nrf52832-uart UART driver + * @{ + * + * \file + * A header file for Contiki compatible UART driver. + * \author + * Wojciech Bober + */ +#ifndef UART_0_H +#define UART_0_H + +#include +#include "contiki-conf.h" + +void uart0_init(); +void uart0_writeb(uint8_t byte); + +void uart0_set_input(int (* input)(unsigned char c)); + +#endif /* UART_0_H */ +/** + * @} + * @} + */ diff --git a/platform/sensinode/uip-debug.c b/cpu/nrf52832/dev/watchdog.c similarity index 62% rename from platform/sensinode/uip-debug.c rename to cpu/nrf52832/dev/watchdog.c index ee7942664..50e26d72b 100644 --- a/platform/sensinode/uip-debug.c +++ b/cpu/nrf52832/dev/watchdog.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Swedish Institute of Computer Science. + * Copyright (c) 2015, Nordic Semiconductor * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,56 +27,67 @@ * SUCH DAMAGE. * */ +/** + * \addtogroup nrf52832-dev Device drivers + * @{ + * + * \addtogroup nrf52832-watchdog Watchdog driver + * @{ + * + * \file + * Contiki compatible watchdog driver implementation. + * \author + * Wojciech Bober + */ +#include +#include "app_error.h" +#include "contiki-conf.h" + +static nrf_drv_wdt_channel_id wdt_channel_id; +static uint8_t wdt_initialized = 0; /** - * \file - * A set of debugging tools - * \author - * Nicolas Tsiftes - * Niclas Finne - * Joakim Eriksson + * \brief WDT events handler. */ +static void wdt_event_handler(void) +{ + LEDS_OFF(LEDS_MASK); +} -#include "net/ip/uip-debug.h" -#include "debug.h" /*---------------------------------------------------------------------------*/ void -uip_debug_ipaddr_print(const uip_ipaddr_t *addr) +watchdog_init(void) { -#if UIP_CONF_IPV6 - uint16_t a; - unsigned int i; - int f; - for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { - a = (addr->u8[i] << 8) + addr->u8[i + 1]; - if(a == 0 && f >= 0) { - if(f++ == 0) { - putstring("::"); - } - } else { - if(f > 0) { - f = -1; - } else if(i > 0) { - putstring(":"); - } - puthex(a >> 8); - puthex(a & 0xFF); - } - } -#else /* UIP_CONF_IPV6 */ - PRINTA("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]); -#endif /* UIP_CONF_IPV6 */ + ret_code_t err_code; + err_code = nrf_drv_wdt_init(NULL, &wdt_event_handler); + APP_ERROR_CHECK(err_code); + err_code = nrf_drv_wdt_channel_alloc(&wdt_channel_id); + APP_ERROR_CHECK(err_code); + wdt_initialized = 1; } /*---------------------------------------------------------------------------*/ void -uip_debug_lladdr_print(const uip_lladdr_t *addr) +watchdog_start(void) { - unsigned int i; - for(i = 0; i < sizeof(uip_lladdr_t); i++) { - if(i > 0) { - putstring(":"); - } - puthex(addr->addr[i]); + if(wdt_initialized) { + nrf_drv_wdt_enable(); } } /*---------------------------------------------------------------------------*/ +void +watchdog_periodic(void) +{ + if(wdt_initialized) { + nrf_drv_wdt_channel_feed(wdt_channel_id); + } +} +/*---------------------------------------------------------------------------*/ +void +watchdog_reboot(void) +{ + NVIC_SystemReset(); +} +/** + * @} + * @} + */ diff --git a/cpu/nrf52832/erase.jlink b/cpu/nrf52832/erase.jlink new file mode 100644 index 000000000..5f08d8d86 --- /dev/null +++ b/cpu/nrf52832/erase.jlink @@ -0,0 +1,2 @@ +erase +q \ No newline at end of file diff --git a/cpu/nrf52832/flash.jlink b/cpu/nrf52832/flash.jlink new file mode 100644 index 000000000..787670d55 --- /dev/null +++ b/cpu/nrf52832/flash.jlink @@ -0,0 +1,4 @@ +loadfile #OUTPUT_FILENAME# +r +g +q \ No newline at end of file diff --git a/cpu/nrf52832/ld/nrf52-pca10036-sd.ld b/cpu/nrf52832/ld/nrf52-pca10036-sd.ld new file mode 100644 index 000000000..455749e29 --- /dev/null +++ b/cpu/nrf52832/ld/nrf52-pca10036-sd.ld @@ -0,0 +1,12 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x1f000, LENGTH = 0x61000 + RAM (rwx) : ORIGIN = 0x08000000, LENGTH = 0x8000 +} + +INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/cpu/nrf52832/ld/nrf52-pca10040-sd.ld b/cpu/nrf52832/ld/nrf52-pca10040-sd.ld new file mode 100644 index 000000000..f30aad455 --- /dev/null +++ b/cpu/nrf52832/ld/nrf52-pca10040-sd.ld @@ -0,0 +1,12 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x1f000, LENGTH = 0x61000 + RAM (rwx) : ORIGIN = 0x20002800, LENGTH = 0xD800 +} + +INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/cpu/nrf52832/ld/nrf52.ld b/cpu/nrf52832/ld/nrf52.ld new file mode 100644 index 000000000..268794d04 --- /dev/null +++ b/cpu/nrf52832/ld/nrf52.ld @@ -0,0 +1,12 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x80000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x8000 +} + +INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/cpu/x86/mtarch.h b/cpu/nrf52832/mtarch.h similarity index 77% rename from cpu/x86/mtarch.h rename to cpu/nrf52832/mtarch.h index 9f982828a..4f696669d 100644 --- a/cpu/x86/mtarch.h +++ b/cpu/nrf52832/mtarch.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Adam Dunkels. + * Copyright (c) 2010, Loughborough University - Computer Science * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,22 +28,21 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ -#ifndef MTARCH_H_ -#define MTARCH_H_ - -#ifndef MTARCH_STACKSIZE -#define MTARCH_STACKSIZE 1024 -#endif /* MTARCH_STACKSIZE */ +/* + * \file + * Stub header file for multi-threading. It doesn't do anything, it + * just exists so that mt.c can compile cleanly. + * + * This is based on the original mtarch.h for z80 by Takahide Matsutsuka + * + * \author + * George Oikonomou - + */ +#ifndef __MTARCH_H__ +#define __MTARCH_H__ struct mtarch_thread { - /* Note: stack must be aligned on 4-byte boundary. */ - unsigned long stack[MTARCH_STACKSIZE]; - unsigned long sp; + unsigned char *sp; }; -struct mt_thread; - -int mtarch_stack_usage(struct mt_thread *t); - -#endif /* MTARCH_H_ */ - +#endif /* __MTARCH_H__ */ diff --git a/platform/iris/apps/mts310/light-test.c b/cpu/nrf52832/putchar.c similarity index 74% rename from platform/iris/apps/mts310/light-test.c rename to cpu/nrf52832/putchar.c index 8c24489a0..c4163ba3d 100644 --- a/platform/iris/apps/mts310/light-test.c +++ b/cpu/nrf52832/putchar.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, University of Colombo School of Computing + * Copyright (c) 2015, Nordic Semiconductor * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,35 +26,45 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * This file is part of the Contiki operating system. - * - * @(#)$$ */ - -#include "contiki.h" -#include "dev/sensors/mts300.h" -#include - +/** + * \addtogroup nrf52832 + * @{ + * + * \file + * Hardware specific implementation of putchar() and puts() functions. + * \author + * Wojciech Bober + * + */ /*---------------------------------------------------------------------------*/ -PROCESS(test_light_process, "light test"); -AUTOSTART_PROCESSES(&test_light_process); +#include +#include "dev/uart0.h" /*---------------------------------------------------------------------------*/ -PROCESS_THREAD(test_light_process, ev, data) +int +putchar(int c) { - static struct etimer et; - - PROCESS_BEGIN(); - - while(1) { - - printf("Light : %d\n",get_light()); - printf("Temp : %d\n",get_temp()); - - etimer_set(&et, CLOCK_SECOND / 2); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - - } - - PROCESS_END(); + uart0_writeb(c); + return c; } /*---------------------------------------------------------------------------*/ +int +puts(const char *str) +{ + int i; + + if (str == NULL) { + return 0; + } + + for (i = 0; i < strlen(str); i++) { + uart0_writeb(str[i]); + } + + uart0_writeb('\n'); + return i; +} +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/cpu/nrf52832/rtimer-arch.c b/cpu/nrf52832/rtimer-arch.c new file mode 100644 index 000000000..78f4790f2 --- /dev/null +++ b/cpu/nrf52832/rtimer-arch.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ + +/** + * \addtogroup nrf52832 + * @{ + * + * \file + * Implementation of the architecture dependent rtimer functions for the nRF52 + * + * \author + * Wojciech Bober + */ +/*---------------------------------------------------------------------------*/ +#include +#include +#include "nrf.h" +#include "nrf_drv_timer.h" +#include "app_error.h" +#include "contiki.h" +#include "platform-conf.h" + +static const nrf_drv_timer_t timer = NRF_DRV_TIMER_INSTANCE(PLATFORM_TIMER_INSTANCE_ID); /**< Timer instance used for rtimer */ + +/** + * \brief Handler for timer events. + * + * \param event_type type of an event that should be handled + * \param p_context opaque data pointer passed from nrf_drv_timer_init() + */ +static void +timer_event_handler(nrf_timer_event_t event_type, void* p_context) +{ + switch (event_type) { + case NRF_TIMER_EVENT_COMPARE1: + rtimer_run_next(); + break; + + default: + //Do nothing. + break; + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize platform rtimer + */ +void +rtimer_arch_init(void) +{ + ret_code_t err_code = nrf_drv_timer_init(&timer, NULL, timer_event_handler); + APP_ERROR_CHECK(err_code); + nrf_drv_timer_enable(&timer); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Schedules an rtimer task to be triggered at time t + * \param t The time when the task will need executed. + * + * \e t is an absolute time, in other words the task will be executed AT + * time \e t, not IN \e t rtimer ticks. + * + * This function schedules a one-shot event with the nRF RTC. + */ +void +rtimer_arch_schedule(rtimer_clock_t t) +{ + nrf_drv_timer_compare(&timer, NRF_TIMER_CC_CHANNEL1, t, true); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns the current real-time clock time + * \return The current rtimer time in ticks + * + */ +rtimer_clock_t +rtimer_arch_now() +{ + return nrf_drv_timer_capture(&timer, NRF_TIMER_CC_CHANNEL0); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/cpu/nrf52832/rtimer-arch.h b/cpu/nrf52832/rtimer-arch.h new file mode 100644 index 000000000..da709dae2 --- /dev/null +++ b/cpu/nrf52832/rtimer-arch.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \addtogroup nrf52832 nRF52832 + * @{ + * + * \file + * Architecture dependent rtimer implementation header file. + * \author + * Wojciech Bober + * + */ +/*---------------------------------------------------------------------------*/ +#ifndef RTIMER_ARCH_H_ +#define RTIMER_ARCH_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +/*---------------------------------------------------------------------------*/ +rtimer_clock_t rtimer_arch_now(void); +/*---------------------------------------------------------------------------*/ +#endif /* RTIMER_ARCH_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/cpu/pic32/clock.c b/cpu/pic32/clock.c index 1704467ba..c117718d9 100644 --- a/cpu/pic32/clock.c +++ b/cpu/pic32/clock.c @@ -1,13 +1,13 @@ /* * Contiki PIC32 Port project - * + * * Copyright (c) 2012, * Scuola Superiore Sant'Anna (http://www.sssup.it) and * Consorzio Nazionale Interuniversitario per le Telecomunicazioni * (http://www.cnit.it). * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -41,7 +41,7 @@ */ /** - * \file clock.c + * \file cpu/pic32/clock.c * \brief Clock routines. * \author Giovanni Pellerano * \author Daniele Alessandrelli @@ -129,7 +129,7 @@ clock_delay_usec(uint16_t dt) uint32_t stop; asm volatile("mfc0 %0, $9" : "=r"(now)); - + /* The Count register is incremented every two system clock (SYSCLK) cycles. */ stop = now + dt * ((pic32_clock_get_system_clock() / 1000000) / 2); diff --git a/cpu/pic32/debug-uart.c b/cpu/pic32/debug-uart.c index c2784e119..6161cdc9c 100644 --- a/cpu/pic32/debug-uart.c +++ b/cpu/pic32/debug-uart.c @@ -1,13 +1,13 @@ /* * Contiki PIC32 Port project - * + * * Copyright (c) 2012, * Scuola Superiore Sant'Anna (http://www.sssup.it) and * Consorzio Nazionale Interuniversitario per le Telecomunicazioni * (http://www.cnit.it). * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -41,7 +41,7 @@ */ /** - * \file debug-uart.h + * \file cpu/pic32/debug-uart.h * \brief Debug output redirection to uart. * \author Giovanni Pellerano * \date 2012-03-21 diff --git a/cpu/pic32/debug-uart.h b/cpu/pic32/debug-uart.h index b87b8d359..0c2b92360 100644 --- a/cpu/pic32/debug-uart.h +++ b/cpu/pic32/debug-uart.h @@ -1,13 +1,13 @@ /* * Contiki PIC32 Port project - * + * * Copyright (c) 2012, * Scuola Superiore Sant'Anna (http://www.sssup.it) and * Consorzio Nazionale Interuniversitario per le Telecomunicazioni * (http://www.cnit.it). * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -41,7 +41,7 @@ */ /** - * \file debug-uart.h + * \file cpu/pic32/debug-uart.h * \brief Debug output redirection to uart. * \author Giovanni Pellerano * \date 2012-03-21 diff --git a/cpu/pic32/dev/uart1.h b/cpu/pic32/dev/uart1.h index 11674c972..29cfa32db 100644 --- a/cpu/pic32/dev/uart1.h +++ b/cpu/pic32/dev/uart1.h @@ -1,13 +1,13 @@ /* * Contiki PIC32 Port project - * + * * Copyright (c) 2012, * Scuola Superiore Sant'Anna (http://www.sssup.it) and * Consorzio Nazionale Interuniversitario per le Telecomunicazioni * (http://www.cnit.it). * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -34,8 +34,8 @@ * */ -/** - * @file uart1.h +/** + * @file cpu/pic32/dev/uart1.h * @brief UART1 routines * @author Giovanni Pellerano * diff --git a/cpu/pic32/mtarch.h b/cpu/pic32/mtarch.h index 02e660a5f..e4af7951f 100644 --- a/cpu/pic32/mtarch.h +++ b/cpu/pic32/mtarch.h @@ -1,13 +1,13 @@ /* * Contiki PIC32 Port project - * + * * Copyright (c) 2012, * Scuola Superiore Sant'Anna (http://www.sssup.it) and * Consorzio Nazionale Interuniversitario per le Telecomunicazioni * (http://www.cnit.it). * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -40,8 +40,8 @@ * @{ */ -/** - * \file mtarch.h +/** + * \file cpu/pic32/mtarch.h * \brief Implementation of multithreading in PIC32. To be done. * \author Giovanni Pellerano * \date 2012-03-23 diff --git a/cpu/pic32/pic32.c b/cpu/pic32/pic32.c index f5a8ed796..6cb8329bf 100644 --- a/cpu/pic32/pic32.c +++ b/cpu/pic32/pic32.c @@ -1,13 +1,13 @@ /* * Contiki PIC32 Port project - * + * * Copyright (c) 2012, * Scuola Superiore Sant'Anna (http://www.sssup.it) and * Consorzio Nazionale Interuniversitario per le Telecomunicazioni * (http://www.cnit.it). * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -35,13 +35,13 @@ */ /** - * \addtogroup pic32-contiki-port PIC32 Contiki Port + * \addtogroup pic32 PIC32 Contiki Port * * @{ */ -/** - * \file mtarch.h +/** + * \file cpu/pic32/mtarch.h * \brief PIC32MX initialization routines * \author Giovanni Pellerano * \author Daniele Alessandrelli @@ -50,7 +50,7 @@ /* * PIC32MX795F512L - Specific Functions - * + * * All the functions in this part of the file are specific for the * pic32mx795f512l that is characterized by registers' name that differ from * the 3xx and 4xx families of the pic32mx. @@ -59,7 +59,7 @@ #include #include -#include +#include #include #include @@ -106,10 +106,10 @@ pic32_init(void) SYSKEY = 0; SYSKEY = 0xaa996655; SYSKEY = 0x556699aa; - + /* Enable Sleep Mode */ OSCCONCLR = 1 << _OSCCON_SLPEN_POSITION; - + SYSKEY = 0; ASM_EN_INT; @@ -125,7 +125,7 @@ _general_exception_handler(void) asm volatile ("mfc0 %0,$13":"=r" (cp0_exception_cause)); cp0_exception_code = (cp0_exception_cause >> 2) & 0x0000001F; - + leds_on(LEDS_ALL); while(1){ diff --git a/cpu/pic32/pic32.h b/cpu/pic32/pic32.h index 77a47c92c..013b3f40b 100644 --- a/cpu/pic32/pic32.h +++ b/cpu/pic32/pic32.h @@ -34,6 +34,10 @@ * */ +/** + * \addtogroup cpu + * @{ */ + /** * \defgroup pic32 PIC32 Contiki Port * @@ -97,3 +101,4 @@ void pic32_init(void); #endif /* INCLUDE_PIC32_PIC32_H_ */ /** @} */ +/** @} */ diff --git a/cpu/pic32/rtimer-arch.c b/cpu/pic32/rtimer-arch.c index 4a888dc8e..0334f7fc2 100644 --- a/cpu/pic32/rtimer-arch.c +++ b/cpu/pic32/rtimer-arch.c @@ -1,13 +1,13 @@ /* * Contiki PIC32 Port project - * + * * Copyright (c) 2012, * Scuola Superiore Sant'Anna (http://www.sssup.it) and * Consorzio Nazionale Interuniversitario per le Telecomunicazioni * (http://www.cnit.it). * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -41,7 +41,7 @@ */ /** - * \file rtimer-arch.c + * \file cpu/pic32/rtimer-arch.c * \brief PIC32MX RTIMER routines * \author Giovanni Pellerano * \date 2012-04-11 @@ -49,7 +49,7 @@ /* * PIC32MX795F512L - Specific Functions - * + * * All the functions in this part of the file are specific for the * pic32mx795f512l that is characterized by registers' name that differ from * the 3xx and 4xx families of the pic32mx. @@ -85,7 +85,7 @@ rtimer_arch_init(void) IPC3CLR = _IPC3_T3IP_MASK | _IPC3_T3IS_MASK; IPC3SET = (7 << _IPC3_T3IP_POSITION) | (3 << _IPC3_T3IS_POSITION); T2CON = 0; - T3CON = 0; + T3CON = 0; T2CONSET = _T2CON_T32_MASK | (TIMER_B_PRESCALE_256 << _T2CON_TCKPS_POSITION); PR2 = 0xFFFFFFFF; TMR2 = 0; diff --git a/cpu/pic32/rtimer-arch.h b/cpu/pic32/rtimer-arch.h index 0b0ad8657..a3f6febc7 100644 --- a/cpu/pic32/rtimer-arch.h +++ b/cpu/pic32/rtimer-arch.h @@ -1,13 +1,13 @@ /* * Contiki PIC32 Port project - * + * * Copyright (c) 2012, * Scuola Superiore Sant'Anna (http://www.sssup.it) and * Consorzio Nazionale Interuniversitario per le Telecomunicazioni * (http://www.cnit.it). * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -40,8 +40,8 @@ * @{ */ -/** - * \file rtimer-arch.h +/** + * \file cpu/pic32/rtimer-arch.h * \brief PIC32MX RTIMER routines * \author Giovanni Pellerano * \date 2012-04-11 diff --git a/cpu/pic32/watchdog.c b/cpu/pic32/watchdog.c index fd5654fe5..217302fee 100644 --- a/cpu/pic32/watchdog.c +++ b/cpu/pic32/watchdog.c @@ -1,13 +1,13 @@ /* * Contiki PIC32 Port project - * + * * Copyright (c) 2012, * Scuola Superiore Sant'Anna (http://www.sssup.it) and * Consorzio Nazionale Interuniversitario per le Telecomunicazioni * (http://www.cnit.it). * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -40,8 +40,8 @@ * @{ */ -/** - * \file watchdog.c +/** + * \file cpu/pic32/watchdog.c * \brief PIC32MX Watchdog routines * \author Giovanni Pellerano * \date 2012-03-23 @@ -83,7 +83,7 @@ void watchdog_reboot(void) { volatile int *p = (int *)&RSWRST; - + /* Unlock sequence */ ASM_DIS_INT; if(!(DMACONbits.SUSPEND)){ @@ -92,11 +92,11 @@ watchdog_reboot(void) ; // wait to be actually suspended } } - + SYSKEY = 0; SYSKEY = 0xaa996655; SYSKEY = 0x556699aa; - + RSWRSTSET=_RSWRST_SWRST_MASK; *p; diff --git a/cpu/rl78/Makefile.rl78 b/cpu/rl78/Makefile.rl78 index a20382b7f..d5b68af68 100755 --- a/cpu/rl78/Makefile.rl78 +++ b/cpu/rl78/Makefile.rl78 @@ -127,7 +127,7 @@ else STRIP = $(CROSS_COMPILE)strip ifdef WERROR - CFLAGSWERROR ?= -Werror -pedantic -std=c99 -Werror + CFLAGSWERROR ?= -Werror endif CFLAGSNO ?= -Wall -g $(CFLAGSWERROR) diff --git a/cpu/rl78/adf7023/ADF7023.c b/cpu/rl78/adf7023/ADF7023.c index c8f30be38..a82c1638d 100644 --- a/cpu/rl78/adf7023/ADF7023.c +++ b/cpu/rl78/adf7023/ADF7023.c @@ -45,6 +45,7 @@ #include "sfrs-ext.h" #include "contiki.h" /* for clock_wait() and CLOCK_SECOND. */ +#include "sys/cc.h" /******************************************************************************/ /*************************** Macros Definitions *******************************/ @@ -91,9 +92,6 @@ while(condition) { body; break_loop(); } \ } while(0) -#undef MIN -#define MIN(x, y) (((x) < (y)) ? (x) : (y)) - /******************************************************************************/ /************************ Variables Definitions *******************************/ /******************************************************************************/ diff --git a/cpu/rl78/adf7023/adf7023-contiki.c b/cpu/rl78/adf7023/adf7023-contiki.c index cf9b7d068..7fed45292 100644 --- a/cpu/rl78/adf7023/adf7023-contiki.c +++ b/cpu/rl78/adf7023/adf7023-contiki.c @@ -45,6 +45,31 @@ static unsigned char tx_buf[ADF7023_MAX_PACKET_SIZE]; static unsigned char rx_buf[ADF7023_MAX_PACKET_SIZE]; +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ const struct radio_driver adf7023_driver = { .init = adf7023_init, @@ -76,6 +101,11 @@ const struct radio_driver adf7023_driver = { /** Turn the radio off. */ .off = adf7023_off, + + .get_value = get_value, + .set_value = set_value, + .get_object = get_object, + .set_object = set_object }; int diff --git a/cpu/stm32w108/Makefile.stm32w108 b/cpu/stm32w108/Makefile.stm32w108 index 29e2f9c72..a51e0dbad 100644 --- a/cpu/stm32w108/Makefile.stm32w108 +++ b/cpu/stm32w108/Makefile.stm32w108 @@ -100,10 +100,12 @@ endif ifeq ($(STM32W_CPUREV), CC) LD-EXT=-stm32w108CC - ${warning "using stm32w108CC specific ld file"} + RAM_SIZE = 2*8192 + FLASH_SIZE = 2*128*1024 else ifeq ($(STM32W_CPUREV), xB) LD-EXT=-stm32w108xB - ${warning "using stm32w108xB specific ld file"} + RAM_SIZE = 8192 + FLASH_SIZE = 128*1024 else ${error "Bad STM32W_CPUREV value or no STM32W_CPUREV value specified. Cpu revision should be specified. Please read cpu/stm32w108/README.txt for more details."} endif @@ -207,8 +209,6 @@ endif ### Custom rules -OBJECTDIR = obj_$(TARGET) - ssubst = ${patsubst %.s,%.o,${patsubst %.s79,%.o,$(1)}} CONTIKI_OBJECTFILES += ${addprefix $(OBJECTDIR)/,${call ssubst, $(STM32W_S)}} @@ -229,18 +229,21 @@ endif CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 $(OBJECTDIR)/%.o: %.c | $(OBJECTDIR) - $(CC) $(CFLAGS) $< --dependencies=m $(@:.o=.P) -o $@ + $(TRACE_CC) + $(Q)$(CC) $(CFLAGS) $< --dependencies=m $(@:.o=.P) -o $@ @$(SEDCOMMAND); rm -f $(@:.o=.P) @$(FINALIZE_DEPENDENCY) CUSTOM_RULE_C_TO_CO = 1 %.co: %.c - $(CC) $(CFLAGS) -DAUTOSTART_ENABLE $< -o $@ + $(TRACE_CC) + $(Q)$(CC) $(CFLAGS) -DAUTOSTART_ENABLE $< -o $@ else #IAR CUSTOM_RULE_C_TO_CE = 1 %.ce: %.c - $(CC) $(CFLAGS) -fno-merge-constants -fno-function-sections -DAUTOSTART_ENABLE -c $< -o $@ + $(TRACE_CC) + $(Q)$(CC) $(CFLAGS) -fno-merge-constants -fno-function-sections -DAUTOSTART_ENABLE -c $< -o $@ $(STRIP) --strip-unneeded -g -x $@ CUSTOM_RULE_LINK = 1 @@ -259,12 +262,14 @@ symbols.c symbols.h: endif %.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a $(OBJECTDIR)/symbols.o - $(LD) $(LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} -Wl,-\( ${filter %.a,$^} $(TARGET_LIBFILES) -Wl,-\) -o $@ + $(TRACE_LD) + $(Q)$(LD) $(LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} -Wl,-\( ${filter %.a,$^} $(TARGET_LIBFILES) -Wl,-\) -o $@ @echo >> contiki-$(TARGET).map @$(SIZE) $(SIZEFLAGS) $@ >> contiki-$(TARGET).map #%.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) $(CONTIKI_OBJECTFILES) -# $(LD) $(LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} ${filter %.a,$^} $(TARGET_LIBFILES) -o $@ +# $(TRACE_LD) +# $(Q)$(LD) $(LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} ${filter %.a,$^} $(TARGET_LIBFILES) -o $@ # @echo "\n" >> contiki-$(TARGET).map # @$(SIZE) $(SIZEFLAGS) $@ >> contiki-$(TARGET).map @@ -283,10 +288,12 @@ stm-motes: @echo $(MOTES) $(OBJECTDIR)/%.o: %.s79 | $(OBJECTDIR) - $(AS) $(ASFLAGS) -o $@ $< + $(TRACE_AS) + $(Q)$(AS) $(ASFLAGS) -o $@ $< $(OBJECTDIR)/%.o: %.s | $(OBJECTDIR) - $(AS) $(ASFLAGS) -o $@ $< + $(TRACE_AS) + $(Q)$(AS) $(ASFLAGS) -o $@ $< %.bin: %.$(TARGET) $(OBJCOPY) $(OBJOPTS) $< $@ @@ -314,9 +321,13 @@ endif # a target that gives a user-friendly memory profile, taking into account the RAM # that is statically occupied by the stack as defined in cpu/stm32w108/gnu.ld -RAM_SIZE = 2*8192 -FLASH_SIZE = 2*128*1024 STACK_SIZE = 1280 +ifndef RAM_SIZE + ${error no ram size configured} +endif +ifndef FLASH_SIZE + ${error no flash size configured} +endif %.size: %.$(TARGET) @size -A $< | egrep "data|bss" | awk '{s+=$$2} END {s=s+$(STACK_SIZE); f=$(RAM_SIZE)-s; printf "[RAM] used %6d, free %6d\n",s,f;}' @size -A $< | egrep "text|isr_vector" | awk '{s+=$$2} END {f=$(FLASH_SIZE)-s; printf "[Flash] used %6d, free %6d\n",s,f;}' diff --git a/cpu/stm32w108/clock.c b/cpu/stm32w108/clock.c index f4a17ad53..5e3464d16 100644 --- a/cpu/stm32w108/clock.c +++ b/cpu/stm32w108/clock.c @@ -113,7 +113,7 @@ clock_delay(unsigned int i) } } /*---------------------------------------------------------------------------*/ -/** +/* * Wait for a multiple of 1 ms. */ void diff --git a/cpu/stm32w108/dev/stm32w-radio.c b/cpu/stm32w108/dev/stm32w-radio.c index 3e2d3c975..30bfa0ff2 100644 --- a/cpu/stm32w108/dev/stm32w-radio.c +++ b/cpu/stm32w108/dev/stm32w-radio.c @@ -72,6 +72,7 @@ #if RDC_CONF_DEBUG_LED #define LED_RDC RDC_CONF_DEBUG_LED +#undef LED_ACTIVITY #define LED_ACTIVITY 1 #else #define LED_RDC 0 @@ -117,6 +118,7 @@ #endif /* LED_ACTIVITY */ #if RDC_CONF_HARDWARE_CSMA +#undef MAC_RETRIES #define MAC_RETRIES 0 #endif /* RDC_CONF_HARDWARE_CSMA */ @@ -169,6 +171,7 @@ const RadioTransmitConfig radioTransmitConfig = { TRUE /* appendCrc; */ }; +#undef MAC_RETRIES #define MAC_RETRIES 0 /* @@ -264,6 +267,147 @@ static int stm32w_radio_off(void); static int add_to_rxbuf(uint8_t * src); static int read_from_rxbuf(void *dest, unsigned short len); + +/*--------------------------------------------------------------------------*/ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + if(!value) { + return RADIO_RESULT_INVALID_VALUE; + } + switch(param) { + case RADIO_PARAM_POWER_MODE: + *value = onoroff == ON ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF; + return RADIO_RESULT_OK; + case RADIO_PARAM_CHANNEL: + *value = ST_RadioGetChannel(); + return RADIO_RESULT_OK; + case RADIO_PARAM_PAN_ID: + *value = ST_RadioGetPanId(); + return RADIO_RESULT_OK; + case RADIO_PARAM_16BIT_ADDR: + *value = ST_RadioGetNodeId(); + return RADIO_RESULT_OK; + case RADIO_PARAM_RX_MODE: + *value = 0; + if(ST_RadioAddressFilteringEnabled()) { + *value |= RADIO_RX_MODE_ADDRESS_FILTER; + } + if(ST_RadioAutoAckEnabled()) { + *value |= RADIO_RX_MODE_AUTOACK; + } + return RADIO_RESULT_OK; + case RADIO_PARAM_TXPOWER: + *value = ST_RadioGetPower(); + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + *value = ST_RadioGetEdCcaThreshold(); + return RADIO_RESULT_OK; + case RADIO_PARAM_RSSI: + *value = ST_RadioEnergyDetection(); + return RADIO_RESULT_OK; + + case RADIO_CONST_CHANNEL_MIN: + *value = ST_MIN_802_15_4_CHANNEL_NUMBER; + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MAX: + *value = ST_MAX_802_15_4_CHANNEL_NUMBER; + return RADIO_RESULT_OK; + + case RADIO_CONST_TXPOWER_MIN: + *value = MIN_RADIO_POWER; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MAX: + *value = MAX_RADIO_POWER; + return RADIO_RESULT_OK; + + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} +/*--------------------------------------------------------------------------*/ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + switch(param) { + case RADIO_PARAM_POWER_MODE: + if(value == RADIO_POWER_MODE_ON) { + stm32w_radio_on(); + return RADIO_RESULT_OK; + } + if(value == RADIO_POWER_MODE_OFF) { + stm32w_radio_off(); + return RADIO_RESULT_OK; + } + return RADIO_RESULT_INVALID_VALUE; + case RADIO_PARAM_CHANNEL: + if(value < ST_MIN_802_15_4_CHANNEL_NUMBER || + value > ST_MAX_802_15_4_CHANNEL_NUMBER) { + return RADIO_RESULT_INVALID_VALUE; + } + if(ST_RadioSetChannel(value) != ST_SUCCESS) { + return RADIO_RESULT_ERROR; + } + return RADIO_RESULT_OK; + case RADIO_PARAM_PAN_ID: + ST_RadioSetPanId(value & 0xffff); + return RADIO_RESULT_OK; + case RADIO_PARAM_16BIT_ADDR: + ST_RadioSetNodeId(value & 0xffff); + return RADIO_RESULT_OK; + case RADIO_PARAM_RX_MODE: + if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER | + RADIO_RX_MODE_AUTOACK)) { + return RADIO_RESULT_INVALID_VALUE; + } + ST_RadioEnableAddressFiltering((value & RADIO_RX_MODE_ADDRESS_FILTER) != 0); + ST_RadioEnableAutoAck((value & RADIO_RX_MODE_AUTOACK) != 0); + return RADIO_RESULT_OK; + case RADIO_PARAM_TXPOWER: + if(value < MIN_RADIO_POWER || value > MAX_RADIO_POWER) { + return RADIO_RESULT_INVALID_VALUE; + } + if(ST_RadioSetPower((int8_t)value) != ST_SUCCESS) { + return RADIO_RESULT_INVALID_VALUE; + } + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + ST_RadioSetEdCcaThreshold((int8_t)value); + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} +/*--------------------------------------------------------------------------*/ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + const uint8_t *eui64; + uint8_t *target; + int i; + + if(param == RADIO_PARAM_64BIT_ADDR) { + if(size < 8 || !dest) { + return RADIO_RESULT_INVALID_VALUE; + } + eui64 = ST_RadioGetEui64(); + if(!eui64) { + return RADIO_RESULT_ERROR; + } + target = dest; + for(i = 0; i < 8; i++) { + target[i] = eui64[7 - i]; + } + return RADIO_RESULT_OK; + } + return RADIO_RESULT_NOT_SUPPORTED; +} +/*--------------------------------------------------------------------------*/ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} /*--------------------------------------------------------------------------*/ const struct radio_driver stm32w_radio_driver = { stm32w_radio_init, @@ -276,6 +420,10 @@ const struct radio_driver stm32w_radio_driver = { stm32w_radio_pending_packet, stm32w_radio_on, stm32w_radio_off, + get_value, + set_value, + get_object, + set_object }; /*---------------------------------------------------------------------------*/ static int diff --git a/cpu/stm32w108/dev/uart1.c b/cpu/stm32w108/dev/uart1.c index 87b05e4f6..f94d99d8c 100644 --- a/cpu/stm32w108/dev/uart1.c +++ b/cpu/stm32w108/dev/uart1.c @@ -120,9 +120,9 @@ uart1_writeb(unsigned char c) #endif /* TX_WITH_INTERRUPT */ } /*---------------------------------------------------------------------------*/ -#if ! WITH_UIP -/* If WITH_UIP is defined, putchar() is defined by the SLIP driver */ -#endif /* ! WITH_UIP */ +#if ! NETSTACK_CONF_WITH_IPV4 +/* If NETSTACK_CONF_WITH_IPV4 is defined, putchar() is defined by the SLIP driver */ +#endif /* ! NETSTACK_CONF_WITH_IPV4 */ /*---------------------------------------------------------------------------*/ /* * Initalize the RS232 port. diff --git a/cpu/stm32w108/hal/error-def.h b/cpu/stm32w108/hal/error-def.h index 15360085c..a3a38ed21 100644 --- a/cpu/stm32w108/hal/error-def.h +++ b/cpu/stm32w108/hal/error-def.h @@ -7,7 +7,11 @@ */ /** - * @addtogroup status_codes + * @addtogroup stm32w-cpu + * @{ */ + +/** + * @defgroup status_codes Status Codes * * Many StZNet API functions return an ::StStatus value to indicate * the success or failure of the call. @@ -30,8 +34,9 @@ /** * @name Generic Messages * These messages are system wide. + * + * @{ */ -//@{ #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @@ -106,13 +111,14 @@ DEFINE_ERROR(EEPROM_MFG_VERSION_MISMATCH, 0x06) DEFINE_ERROR(EEPROM_STACK_VERSION_MISMATCH, 0x07) #endif //DOXYGEN_SHOULD_SKIP_THIS -//@} // END Generic Messages +/** @} */ // END Generic Messages /** * @name Packet Buffer Module Errors + * + * @{ */ -//@{ #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @@ -123,12 +129,13 @@ DEFINE_ERROR(EEPROM_STACK_VERSION_MISMATCH, 0x07) DEFINE_ERROR(NO_BUFFERS, 0x18) #endif //DOXYGEN_SHOULD_SKIP_THIS -//@} / END Packet Buffer Module Errors +/** @} */ // END Packet Buffer Module Errors /** * @name Serial Manager Errors + * + * @{ */ -//@{ #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @@ -211,12 +218,13 @@ DEFINE_ERROR(SERIAL_RX_EMPTY, 0x26) DEFINE_ERROR(SERIAL_RX_OVERRUN_ERROR, 0x27) #endif //DOXYGEN_SHOULD_SKIP_THIS -//@} +/** @} */ /** * @name MAC Errors - */ -//@{ + * + * @{ + */ #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @@ -341,22 +349,23 @@ DEFINE_ERROR(MAC_NO_ACK_RECEIVED, 0x40) DEFINE_ERROR(MAC_INDIRECT_TIMEOUT, 0x42) #endif //DOXYGEN_SHOULD_SKIP_THIS -//@} +/** @} */ /** * @name Simulated EEPROM Errors - */ -//@{ + * + * @{ + */ #ifdef DOXYGEN_SHOULD_SKIP_THIS /** * @brief The Simulated EEPROM is telling the application that there * is at least one flash page to be erased. The GREEN status means the - * current page has not filled above the ::ERASE_CRITICAL_THRESHOLD. + * current page has not filled above the ERASE_CRITICAL_THRESHOLD. * - * The application should call the function ::halSimEepromErasePage() when it can + * The application should call the function halSimEepromErasePage() when it can * to erase a page. */ #define ST_SIM_EEPROM_ERASE_PAGE_GREEN(0x43) @@ -369,10 +378,10 @@ DEFINE_ERROR(SIM_EEPROM_ERASE_PAGE_GREEN, 0x43) /** * @brief The Simulated EEPROM is telling the application that there * is at least one flash page to be erased. The RED status means the - * current page has filled above the ::ERASE_CRITICAL_THRESHOLD. + * current page has filled above the ERASE_CRITICAL_THRESHOLD. * * Due to the shrinking availablity of write space, there is a danger of - * data loss. The application must call the function ::halSimEepromErasePage() + * data loss. The application must call the function halSimEepromErasePage() * as soon as possible to erase a page. */ #define ST_SIM_EEPROM_ERASE_PAGE_RED(0x44) @@ -385,9 +394,9 @@ DEFINE_ERROR(SIM_EEPROM_ERASE_PAGE_RED, 0x44) /** * @brief The Simulated EEPROM has run out of room to write any new data * and the data trying to be set has been lost. This error code is the - * result of ignoring the ::SIM_EEPROM_ERASE_PAGE_RED error code. + * result of ignoring the ::ST_SIM_EEPROM_ERASE_PAGE_RED error code. * - * The application must call the function ::halSimEepromErasePage() to make room for + * The application must call the function halSimEepromErasePage() to make room for * any further calls to set a token. */ #define ST_SIM_EEPROM_FULL(0x45) @@ -431,8 +440,8 @@ DEFINE_ERROR(SIM_EEPROM_INIT_2_FAILED, 0x49) /** * @brief Attempt 3 to initialize the Simulated EEPROM has failed. * - * This failure means one or both of the tokens ::TOKEN_MFG_NVDATA_VERSION or - * ::TOKEN_STACK_NVDATA_VERSION were incorrect and the token system failed to + * This failure means one or both of the tokens TOKEN_MFG_NVDATA_VERSION or + * TOKEN_STACK_NVDATA_VERSION were incorrect and the token system failed to * properly reload default tokens and reset the Simulated EEPROM. */ #define ST_SIM_EEPROM_INIT_3_FAILED(0x4A) @@ -440,13 +449,13 @@ DEFINE_ERROR(SIM_EEPROM_INIT_2_FAILED, 0x49) DEFINE_ERROR(SIM_EEPROM_INIT_3_FAILED, 0x4A) #endif //DOXYGEN_SHOULD_SKIP_THIS -//@} +/** @} */ /** * @name Flash Errors - */ -//@{ + * + * @{ */ #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @@ -477,7 +486,7 @@ DEFINE_ERROR(ERR_FLASH_VERIFY_FAILED, 0x47) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** - * @description A fatal error has occured while trying to write data to the + * @brief A fatal error has occured while trying to write data to the * flash, possibly due to write protection or an invalid address. The data in * the flash cannot be trusted after this error, and it is possible this error * is the result of exceeding the life cycles of the flash. @@ -490,7 +499,7 @@ DEFINE_ERROR(ERR_FLASH_PROG_FAIL, 0x4B) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** - * @description A fatal error has occured while trying to erase flash, possibly + * @brief A fatal error has occured while trying to erase flash, possibly * due to write protection. The data in the flash cannot be trusted after * this error, and it is possible this error is the result of exceeding the * life cycles of the flash. @@ -500,13 +509,14 @@ DEFINE_ERROR(ERR_FLASH_PROG_FAIL, 0x4B) DEFINE_ERROR(ERR_FLASH_ERASE_FAIL, 0x4C) #endif //DOXYGEN_SHOULD_SKIP_THIS -//@} +/** @} */ /** * @name Bootloader Errors - */ -//@{ + * + * @{ + */ #ifdef DOXYGEN_SHOULD_SKIP_THIS @@ -541,13 +551,14 @@ DEFINE_ERROR(ERR_BOOTLOADER_TRAP_UNKNOWN, 0x59) DEFINE_ERROR(ERR_BOOTLOADER_NO_IMAGE, 0x5A) #endif //DOXYGEN_SHOULD_SKIP_THIS -//@} +/** @} */ /** * @name Transport Errors - */ -//@{ + * + * @{ + */ #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @@ -615,7 +626,7 @@ DEFINE_ERROR(COST_NOT_KNOWN, 0x71) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** * @brief The maximum number of in-flight messages (i.e. - * ::ST_APS_UNICAST_MESSAGE_COUNT) has been reached. + * ST_APS_UNICAST_MESSAGE_COUNT) has been reached. */ #define ST_MAX_MESSAGE_LIMIT_REACHED(0x72) #else @@ -653,12 +664,13 @@ DEFINE_ERROR(BINDING_IS_ACTIVE, 0x75) DEFINE_ERROR(ADDRESS_TABLE_ENTRY_IS_ACTIVE, 0x76) #endif //DOXYGEN_SHOULD_SKIP_THIS -//@} +/** @} */ /** * @name HAL Module Errors - */ -//@{ + * + * @{ + */ #ifdef DOXYGEN_SHOULD_SKIP_THIS @@ -713,12 +725,13 @@ DEFINE_ERROR(ADC_NO_CONVERSION_PENDING, 0x84) DEFINE_ERROR(SLEEP_INTERRUPTED, 0x85) #endif //DOXYGEN_SHOULD_SKIP_THIS -//@} +/** @} */ /** * @name PHY Errors - */ -//@{ + * + * @{ + */ #ifdef DOXYGEN_SHOULD_SKIP_THIS @@ -803,13 +816,14 @@ DEFINE_ERROR(PHY_OSCILLATOR_CHECK_FAILED, 0x8E) DEFINE_ERROR(PHY_ACK_RECEIVED, 0x8F) #endif //DOXYGEN_SHOULD_SKIP_THIS -//@} +/** @} */ /** * @name Return Codes Passed to stStackStatusHandler() - * See also ::stStackStatusHandler(). + * See also stStackStatusHandler(). + * + * @{ */ -//@{ #ifdef DOXYGEN_SHOULD_SKIP_THIS @@ -868,7 +882,7 @@ DEFINE_ERROR(CANNOT_JOIN_AS_ROUTER, 0x98) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @brief The local node ID has changed. The application can obtain the new - * node ID by calling ::stGetNodeId(). + * node ID by calling stGetNodeId(). */ #define ST_NODE_ID_CHANGED(0x99) #else @@ -878,7 +892,7 @@ DEFINE_ERROR(NODE_ID_CHANGED, 0x99) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @brief The local PAN ID has changed. The application can obtain the new PAN - * ID by calling ::stGetPanId(). + * ID by calling stGetPanId(). */ #define ST_PAN_ID_CHANGED(0x9A) #else @@ -906,7 +920,7 @@ DEFINE_ERROR(NO_BEACONS, 0xAB) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @brief An attempt was made to join a Secured Network using a pre-configured * key, but the Trust Center sent back a Network Key in-the-clear when - * an encrypted Network Key was required. (::ST_REQUIRE_ENCRYPTED_KEY). + * an encrypted Network Key was required. (ST_REQUIRE_ENCRYPTED_KEY). */ #define ST_RECEIVED_KEY_IN_THE_CLEAR(0xAC) #else @@ -926,7 +940,7 @@ DEFINE_ERROR(NO_NETWORK_KEY_RECEIVED, 0xAD) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @brief After a device joined a Secured Network, a Link Key was requested - * (::ST_GET_LINK_KEY_WHEN_JOINING) but no response was ever received. + * (ST_GET_LINK_KEY_WHEN_JOINING) but no response was ever received. */ #define ST_NO_LINK_KEY_RECEIVED(0xAE) #else @@ -945,10 +959,12 @@ DEFINE_ERROR(PRECONFIGURED_KEY_REQUIRED, 0xAF) #endif -//@} +/** @} */ /** * @name Security Errors + * + * @{ */ #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @@ -962,7 +978,7 @@ DEFINE_ERROR(KEY_INVALID, 0xB2) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** - * @brief The chosen security level (the value of ::ST_SECURITY_LEVEL) + * @brief The chosen security level (the value of ST_SECURITY_LEVEL) * is not supported by the stack. */ #define ST_INVALID_SECURITY_LEVEL(0x95) @@ -995,7 +1011,7 @@ DEFINE_ERROR(INVALID_SECURITY_LEVEL, 0x95) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @brief There was an attempt to form or join a network with security - * without calling ::stSetInitialSecurityState() first. + * without calling stSetInitialSecurityState() first. */ #define ST_SECURITY_STATE_NOT_SET(0xA8) #else @@ -1057,14 +1073,14 @@ DEFINE_ERROR(SECURITY_CONFIGURATION_INVALID, 0xB7) #endif -//@} +/** @} */ /** * @name Miscellaneous Network Errors - */ -//@{ - + * + * @{ + */ #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @@ -1139,13 +1155,13 @@ DEFINE_ERROR(BINDING_HAS_CHANGED, 0xA4) #endif -//@} +/** @} */ /** * @name Miscellaneous Utility Errors - */ -//@{ - + * + * @{ + */ #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @@ -1209,13 +1225,14 @@ DEFINE_ERROR(LIBRARY_NOT_PRESENT, 0xB5) DEFINE_ERROR(OPERATION_IN_PROGRESS, 0xBA) #endif -//@} +/** @} */ /** * @name Application Errors * These error codes are available for application use. + * + * @{ */ -//@{ #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @@ -1257,7 +1274,9 @@ DEFINE_ERROR( APPLICATION_ERROR_14, 0xFE) DEFINE_ERROR( APPLICATION_ERROR_15, 0xFF) #endif //DOXYGEN_SHOULD_SKIP_THIS -//@} // END name group +/** @} */ + +/** @} END defgroup */ /** @} END addtogroup */ diff --git a/cpu/stm32w108/hal/error.h b/cpu/stm32w108/hal/error.h index 190b93e17..1a3dd36eb 100644 --- a/cpu/stm32w108/hal/error.h +++ b/cpu/stm32w108/hal/error.h @@ -1,21 +1,21 @@ /** - * @file error.h + * @file cpu/stm32w108/hal/error.h * @brief Return codes for API functions and module definitions. * * See @ref status_codes for documentation. - * + * * */ #ifndef ERRORS_H_ #define ERRORS_H_ +#ifndef __STSTATUS_TYPE__ +#define __STSTATUS_TYPE__ /** * @brief Return type for St functions. */ -#ifndef __STSTATUS_TYPE__ -#define __STSTATUS_TYPE__ - typedef uint8_t StStatus; +typedef uint8_t StStatus; #endif //__STSTATUS_TYPE__ /** @@ -27,8 +27,8 @@ * @brief Macro used by error-def.h to define all of the return codes. * * @param symbol The name of the constant being defined. All St returns - * begin with ST_. For example, ::ST_CONNECTION_OPEN. - * + * begin with ST_. For example, ::ST_ERR_FATAL. + * * @param value The value of the return code. For example, 0x61. */ #define DEFINE_ERROR(symbol, value) \ @@ -36,11 +36,9 @@ enum { -#ifndef DOXYGEN_SHOULD_SKIP_THIS #include "error-def.h" -#endif //DOXYGEN_SHOULD_SKIP_THIS - /** Gets defined as a count of all the possible return codes in the - * StZNet stack API. + /** Gets defined as a count of all the possible return codes in the + * StZNet stack API. */ ST_ERROR_CODE_COUNT @@ -52,5 +50,3 @@ enum { /**@} // End of addtogroup */ - - diff --git a/cpu/stm32w108/hal/micro/adc.h b/cpu/stm32w108/hal/micro/adc.h index 75d2eeeb5..26e2e0b36 100644 --- a/cpu/stm32w108/hal/micro/adc.h +++ b/cpu/stm32w108/hal/micro/adc.h @@ -3,8 +3,12 @@ * * */ -/** @addtogroup adc - * Sample A/D converter driver. + +/** + * @addtogroup stm32w-cpu + * @{ */ + +/** @defgroup adc Sample A/D converter driver. * * See adc.h for source code. * @@ -318,5 +322,5 @@ boolean halAdcGetRange(void); /** @} // END addtogroup */ - +/** @} */ diff --git a/cpu/stm32w108/hal/micro/cortexm3/adc.c b/cpu/stm32w108/hal/micro/cortexm3/adc.c index 67a8a8feb..07f9d6304 100644 --- a/cpu/stm32w108/hal/micro/cortexm3/adc.c +++ b/cpu/stm32w108/hal/micro/cortexm3/adc.c @@ -1,4 +1,4 @@ -/** @file adc.c +/** @file cpu/stm32w108/hal/micro/cortexm3/adc.c * @brief ADC HAL functions * * @@ -22,12 +22,12 @@ static uint16_t adcConfig[NUM_ADC_USERS]; static boolean adcCalibrated; static int16_t Nvss; static int16_t Nvdd; -/* Modified the original ADC driver for enabling the ADC extended range mode required for +/* Modified the original ADC driver for enabling the ADC extended range mode required for supporting the STLM20 temperature sensor. - NOTE: - The ADC extended range is inaccurate due to the high voltage mode bug of the general purpose ADC + NOTE: + The ADC extended range is inaccurate due to the high voltage mode bug of the general purpose ADC (see STM32W108 errata). As consequence, it is not reccomended to use this ADC driver for getting - the temperature values + the temperature values */ #ifdef ENABLE_ADC_EXTENDED_RANGE_BROKEN static int16_t Nvref; @@ -87,7 +87,7 @@ void halAdcIsr(void) if (BIT(i) & adcPendingRequests) { adcPendingConversion = i; // set pending conversion adcPendingRequests ^= BIT(i); //clear request: conversion is starting - ADC_CFG = adcConfig[i]; + ADC_CFG = adcConfig[i]; break; //conversion started, so we're done here (only one at a time) } } @@ -106,7 +106,7 @@ void halAdcIsr(void) ADCUser startNextConversion() { uint8_t i; - + ATOMIC ( // start the next requested conversion if any if (adcPendingRequests && !(ADC_CFG & ADC_ENABLE)) { @@ -160,7 +160,7 @@ StStatus halStartAdcConversion(ADCUser id, ADCChannelType channel, ADCRateType rate) { - + if(reference != ADC_REF_INT) return ST_ERR_FATAL; @@ -191,7 +191,7 @@ StStatus halRequestAdcData(ADCUser id, uint16_t *value) //Both the ADC interrupt and the global interrupt need to be enabled, //otherwise the ADC ISR cannot be serviced. boolean intsAreOff = ( INTERRUPTS_ARE_OFF() - || !(INT_CFGSET & INT_ADC) + || !(INT_CFGSET & INT_ADC) || !(INT_ADCCFG & INT_ADCULDFULL) ); StStatus stat; @@ -199,7 +199,7 @@ StStatus halRequestAdcData(ADCUser id, uint16_t *value) // If interupts are disabled but the flag is set, // manually run the isr... //FIXME -= is this valid??? - if( intsAreOff + if( intsAreOff && ( (INT_CFGSET & INT_ADC) && (INT_ADCCFG & INT_ADCULDFULL) )) { halAdcIsr(); } @@ -235,21 +235,21 @@ StStatus halReadAdcBlocking(ADCUser id, uint16_t *value) StStatus halAdcCalibrate(ADCUser id) { StStatus stat; -/* Modified the original ADC driver for enabling the ADC extended range mode required for +/* Modified the original ADC driver for enabling the ADC extended range mode required for supporting the STLM20 temperature sensor. - NOTE: - The ADC extended range is inaccurate due to the high voltage mode bug of the general purpose ADC + NOTE: + The ADC extended range is inaccurate due to the high voltage mode bug of the general purpose ADC (see STM32W108 errata). As consequence, it is not reccomended to use this ADC driver for getting - the temperature values + the temperature values */ #ifdef ENABLE_ADC_EXTENDED_RANGE_BROKEN if(halAdcGetRange()){ - + halStartAdcConversion(id, ADC_REF_INT, ADC_SOURCE_VREF_VREF2, ADC_CONVERSION_TIME_US_4096); - + stat = halReadAdcBlocking(id, (uint16_t *)(&Nvref)); if (stat == ST_ADC_CONVERSION_DONE) { halStartAdcConversion(id, @@ -264,9 +264,9 @@ StStatus halAdcCalibrate(ADCUser id) adcCalibrated = FALSE; stat = ST_ERR_FATAL; } - return stat; - - } + return stat; + + } #endif /* ENABLE_ADC_EXTENDED_RANGE_BROKEN */ halStartAdcConversion(id, ADC_REF_INT, @@ -294,7 +294,7 @@ StStatus halAdcCalibrate(ADCUser id) // to convert to 100uV units. // FIXME: support external Vref // use #define of Vref, ignore VDD_PADSA -// FIXME: support high voltage range +// FIXME: support high voltage range // use Vref-Vref/2 to calibrate // FIXME: check for mfg token specifying measured VDD_PADSA int16_t halConvertValueToVolts(uint16_t value) @@ -302,29 +302,29 @@ int16_t halConvertValueToVolts(uint16_t value) int32_t N; int16_t V; int32_t nvalue; - + if (!adcCalibrated) { halAdcCalibrate(ADC_USER_LQI); } if (adcCalibrated) { - /* Modified the original ADC driver for enabling the ADC extended range mode required for + /* Modified the original ADC driver for enabling the ADC extended range mode required for supporting the STLM20 temperature sensor. - NOTE: - The ADC extended range is inaccurate due to the high voltage mode bug of the general purpose ADC + NOTE: + The ADC extended range is inaccurate due to the high voltage mode bug of the general purpose ADC (see STM32W108 errata). As consequence, it is not reccomended to use this ADC driver for getting - the temperature values + the temperature values */ #ifdef ENABLE_ADC_EXTENDED_RANGE_BROKEN if(halAdcGetRange()){ // High range. - + N = (((int32_t)value + Nvref - 2*Nvref2) << 16)/(2*(Nvref-Nvref2)); // Calculate voltage with: V = (N * VREF) / (2^16) where VDD = 1.2 volts // Mutiplying by 1.2*10000 makes the result of this equation 100 uVolts V = (int16_t)((N*12000L) >> 16); if (V > 21000) { // VDD_PADS ? V = 21000; - } - + } + } else { #endif /* ENABLE_ADC_EXTENDED_RANGE_BROKEN */ @@ -340,9 +340,9 @@ int16_t halConvertValueToVolts(uint16_t value) if (V > 12000) { V = 12000; } - #ifdef ENABLE_ADC_EXTENDED_RANGE_BROKEN + #ifdef ENABLE_ADC_EXTENDED_RANGE_BROKEN } - #endif /* ENABLE_ADC_EXTENDED_RANGE_BROKEN */ + #endif /* ENABLE_ADC_EXTENDED_RANGE_BROKEN */ } else { V = -32768; } @@ -355,27 +355,27 @@ uint8_t halGetADCChannelFromGPIO(uint32_t io) { case PORTB_PIN(5): return ADC_MUX_ADC0; - + case PORTB_PIN(6): return ADC_MUX_ADC1; - + case PORTB_PIN(7): return ADC_MUX_ADC2; - + case PORTC_PIN(1): return ADC_MUX_ADC3; - + case PORTA_PIN(4): return ADC_MUX_ADC4; - + case PORTA_PIN(5): return ADC_MUX_ADC5; - + case PORTB_PIN(0): return ADC_MUX_VREF; - + default : return 0x0F; // Invalid analogue source - + } } diff --git a/cpu/stm32w108/hal/micro/cortexm3/board.c b/cpu/stm32w108/hal/micro/cortexm3/board.c index 62ef23c52..6b72dae5e 100644 --- a/cpu/stm32w108/hal/micro/cortexm3/board.c +++ b/cpu/stm32w108/hal/micro/cortexm3/board.c @@ -1,5 +1,5 @@ -/** @file board.c - * @brief Board file x STM32W108 Kits boards +/** @file cpu/stm32w108/hal/micro/cortexm3/board.c + * @brief Board file x STM32W108 Kits boards * * This file implements a software layer to support all the ST kits boards * and deal with the difference in leds, buttons and sensors connected to the board. @@ -138,22 +138,22 @@ const MemsResourceType memsSensor = { const BoardIOType ioMB851A = { LedsMB851A, - ButtonsMB851A, + ButtonsMB851A, }; const BoardIOType ioMB954A = { LedsMB954A, - ButtonsMB954A, + ButtonsMB954A, }; const BoardIOType ioMB950A = { LedsMB954A, - ButtonsMB950A, + ButtonsMB950A, }; const BoardIOType ioMB951A = { LedsMB954A, - ButtonsMB951A, + ButtonsMB951A, }; const BoardResourcesType MB851A = { @@ -264,7 +264,7 @@ void halBoardInit(void) i--; } - for (i = 0; i < (sizeof(boardList)/4) ; i++) + for (i = 0; i < (sizeof(boardList)/4) ; i++) if (strcmp(boardName, (boardList[i])->name) == 0) { boardDescription = (BoardResourcesType *) boardList[i]; break; diff --git a/cpu/stm32w108/hal/micro/cortexm3/compiler/gnu.h b/cpu/stm32w108/hal/micro/cortexm3/compiler/gnu.h index 66fee590c..ccdfa6199 100644 --- a/cpu/stm32w108/hal/micro/cortexm3/compiler/gnu.h +++ b/cpu/stm32w108/hal/micro/cortexm3/compiler/gnu.h @@ -3,7 +3,11 @@ * */ -/** @addtogroup gnu +/** + * @addtogroup stm32w-cpu + * @{ */ + +/** @defgroup gnu GNU * @brief Compiler and Platform specific definitions and typedefs for the * GNU C ARM compiler. * @@ -539,4 +543,5 @@ int abs(int I); #endif // GNU_H_ /** @} END addtogroup */ +/** @} */ diff --git a/cpu/stm32w108/hal/micro/cortexm3/compiler/iar.h b/cpu/stm32w108/hal/micro/cortexm3/compiler/iar.h index f9046cd32..a057d48ca 100644 --- a/cpu/stm32w108/hal/micro/cortexm3/compiler/iar.h +++ b/cpu/stm32w108/hal/micro/cortexm3/compiler/iar.h @@ -4,7 +4,11 @@ * */ -/** @addtogroup iar +/** + * @addtogroup stm32w-cpu + * @{ */ + +/** @defgroup iar IAR * @brief Compiler and Platform specific definitions and typedefs for the * IAR ARM C compiler. * @@ -532,4 +536,5 @@ int abs(int I); #endif // IAR_H_ /** @} END addtogroup */ +/** @} */ diff --git a/cpu/stm32w108/hal/micro/cortexm3/flash.h b/cpu/stm32w108/hal/micro/cortexm3/flash.h index 3404736f5..0bfa7a0f4 100644 --- a/cpu/stm32w108/hal/micro/cortexm3/flash.h +++ b/cpu/stm32w108/hal/micro/cortexm3/flash.h @@ -4,8 +4,13 @@ * */ -/** @addtogroup flash - * @brief Definition and description of public flash manipulation routines. +/** + * \addtogroup stm32w-cpu + * @{ + */ + +/** + * @defgroup flash Definition and description of public flash manipulation routines. * * @note * During an erase or a write the flash is not available, @@ -123,4 +128,5 @@ StStatus halInternalCibOptionByteWrite(uint8_t byte, uint8_t data); #endif //FLASH_H_ /** @} END addtogroup */ +/** @} */ diff --git a/cpu/stm32w108/hal/micro/cortexm3/mems.c b/cpu/stm32w108/hal/micro/cortexm3/mems.c index 4a0437feb..f06a4b7ab 100644 --- a/cpu/stm32w108/hal/micro/cortexm3/mems.c +++ b/cpu/stm32w108/hal/micro/cortexm3/mems.c @@ -1,4 +1,4 @@ -/** @file mems.c +/** @file cpu/stm32w108/hal/micro/cortexm3/mems.c * @brief MB851 MEMS drivers * * @@ -30,9 +30,9 @@ static uint8_t i2c_MEMS_Read (t_mems_data *mems_data); /* Functions -----------------------------------------------------------------*/ uint8_t mems_Init(void) -{ +{ uint8_t ret = 0; - + // GPIO assignments // PA1: SC2SDA (Serial Data) // PA2: SC2SCL (Serial Clock) @@ -43,27 +43,27 @@ uint8_t mems_Init(void) SC2_MODE = SC2_MODE_I2C; GPIO_PACFGL &= 0xFFFFF00F; GPIO_PACFGL |= 0x00000DD0; - + SC2_RATELIN = 14; // generates standard 100kbps or 400kbps SC2_RATEEXP = 1; // 3 yields 100kbps; 1 yields 400kbps SC2_TWICTRL1 = 0; // start from a clean state - SC2_TWICTRL2 = 0; // start from a clean state - + SC2_TWICTRL2 = 0; // start from a clean state + ret = i2c_MEMS_Init(); -//Add later if really needed -#ifdef ST_DBG +//Add later if really needed +#ifdef ST_DBG if (!ret) i2c_DeInit(MEMS_I2C); #endif - + return ret; }/* end mems_Init */ uint8_t mems_GetValue(t_mems_data *mems_data) { - uint8_t i; - i = i2c_MEMS_Read(mems_data); + uint8_t i; + i = i2c_MEMS_Read(mems_data); return i; }/* end mems_GetValue() */ @@ -72,7 +72,7 @@ uint8_t mems_GetValue(t_mems_data *mems_data) /******************************************************************************* * Function Name : i2c_Send_Frame -* Description : It sends I2C frame +* Description : It sends I2C frame * Input : DeviceAddress is the destination device address * pBUffer is the buffer data * NoOfBytes is the number of bytes @@ -85,24 +85,24 @@ static uint8_t i2c_Send_Frame (uint8_t DeviceAddress, uint8_t *pBuffer, uint8_t SC2_TWICTRL1 |= SC_TWISTART; // send start WAIT_CMD_FIN(); - + SEND_BYTE(DeviceAddress); // send the address low byte WAIT_TX_FIN(); - + // loop sending the data for (i=0; i 1) addr += REPETIR; - + SC2_TWICTRL1 |= SC_TWISTART; // send start WAIT_CMD_FIN(); - + SEND_BYTE(slave_addr | 0x00); // send the address low byte WAIT_TX_FIN(); - + SEND_BYTE(addr); WAIT_TX_FIN(); SC2_TWICTRL1 |= SC_TWISTART; // send start WAIT_CMD_FIN(); - + SEND_BYTE(slave_addr | 0x01); // send the address low byte WAIT_TX_FIN(); - + // loop receiving the data for (i=0;ioutx_h = i2c_buffer[0]; mems_data->outx_l = i2c_buffer[1]; diff --git a/cpu/stm32w108/hal/micro/cortexm3/mfg-token.c b/cpu/stm32w108/hal/micro/cortexm3/mfg-token.c index c6c0b532c..14d143bc7 100644 --- a/cpu/stm32w108/hal/micro/cortexm3/mfg-token.c +++ b/cpu/stm32w108/hal/micro/cortexm3/mfg-token.c @@ -50,10 +50,10 @@ void halInternalGetMfgTokenData(void *data, uint16_t ID, uint8_t index, uint8_t MEMCOPY(ram, eui64, 8 /*EUI64_SIZE*/); } else { //read from the Information Blocks. The token ID is only the - //bottom 16bits of the token's actual address. Since the info blocks - //exist in the range DATA_BIG_INFO_BASE-DATA_BIG_INFO_END, we need - //to OR the ID with DATA_BIG_INFO_BASE to get the real address. - uint32_t realAddress = (DATA_BIG_INFO_BASE|ID) + (len*index); + //DATA_BIG_INFO_BASE-relative 16-bit offset of the token. Since the + //info blocks exist in the range DATA_BIG_INFO_BASE-DATA_BIG_INFO_END, + //we need to add the ID to DATA_BIG_INFO_BASE to get the real address. + uint32_t realAddress = (DATA_BIG_INFO_BASE+ID) + (len*index); uint8_t *flash = (uint8_t *)realAddress; @@ -77,7 +77,7 @@ void halInternalGetMfgTokenData(void *data, uint16_t ID, uint8_t index, uint8_t void halInternalSetMfgTokenData(uint16_t token, void *data, uint8_t len) { StStatus flashStatus; - uint32_t realAddress = (DATA_BIG_INFO_BASE|token); + uint32_t realAddress = (DATA_BIG_INFO_BASE+token); uint8_t * flash = (uint8_t *)realAddress; uint32_t i; diff --git a/cpu/stm32w108/hal/micro/cortexm3/mfg-token.h b/cpu/stm32w108/hal/micro/cortexm3/mfg-token.h index f05ac216d..685a3bc72 100644 --- a/cpu/stm32w108/hal/micro/cortexm3/mfg-token.h +++ b/cpu/stm32w108/hal/micro/cortexm3/mfg-token.h @@ -1,12 +1,13 @@ -/** @file hal/micro/cortexm3/mfg-token.h - * @brief Cortex-M3 Manufacturing token system +/** \file cpu/stm32w108/hal/micro/cortexm3/mfg-token.h + * \brief Cortex-M3 Manufacturing token system * * */ - + #ifndef MFG_TOKEN_H_ #define MFG_TOKEN_H_ - + +#ifndef DOXYGEN_SHOULD_SKIP_THIS // The manufacturing tokens live in the Info Blocks, while all other tokens // live in the Simulated EEPROM. This requires the token names to be defined @@ -16,78 +17,91 @@ #define DEFINETOKENS /** - * @description Macro for translating token defs into address variables + * \brief Macro for translating token defs into address variables * that point to the correct location in the Info Blocks. (This is the * extern, the actual definition is found in hal/micro/cortexm3/token.c) * - * @param name: The name of the token. - * - * @param TOKEN_##name##_ADDRESS: The address in EEPROM at which the token - * will be stored. This parameter is generated with a macro above. + * \param name: The name of the token. + * \param creator: The manufacturing creators. + * \param iscnt: + * \param isidx: + * \param type: The token type. The types are found in token-stack.h. + * \param arraysize: The number of elements in an indexed token (arraysize=1 + * for scalar tokens). */ #define TOKEN_MFG(name,creator,iscnt,isidx,type,arraysize,...) \ extern const uint16_t TOKEN_##name; - #include "hal/micro/cortexm3/token-manufacturing.h" + #include "cpu/stm32w108/hal/micro/cortexm3/token-manufacturing.h" #undef TOKEN_MFG /** - * @description Macro for translating token definitions into size variables. + * \brief Macro for translating token definitions into size variables. * This provides a convenience for abstracting the 'sizeof(type)' anywhere. * - * @param name: The name of the token. - * - * @param type: The token type. The types are found in token-stack.h. + * \param name: The name of the token. + * \param creator: The manufacturing creators. + * \param iscnt: + * \param isidx: + * \param type: The token type. The types are found in token-stack.h. + * \param arraysize: The number of elements in an indexed token (arraysize=1 + * for scalar tokens). */ #define TOKEN_MFG(name,creator,iscnt,isidx,type,arraysize,...) \ TOKEN_##name##_SIZE = sizeof(type), enum { - #include "hal/micro/cortexm3/token-manufacturing.h" + #include "cpu/stm32w108/hal/micro/cortexm3/token-manufacturing.h" }; #undef TOKEN_MFG #undef TOKEN_DEF - + /** - * @description Macro for typedef'ing the CamelCase token type found in + * \brief Macro for typedef'ing the CamelCase token type found in * token-stack.h to a capitalized TOKEN style name that ends in _TYPE. - * This macro allows other macros below to use 'token##_TYPE' to declare + * This macro allows other macros below to use 'token\#\#_TYPE' to declare * a local copy of that token. * - * @param name: The name of the token. - * - * @param type: The token type. The types are found in token-stack.h. + * \param name: The name of the token. + * \param creator: The manufacturing creators. + * \param iscnt: + * \param isidx: + * \param type: The token type. The types are found in token-stack.h. + * \param arraysize: The number of elements in an indexed token (arraysize=1 + * for scalar tokens). */ #define TOKEN_MFG(name,creator,iscnt,isidx,type,arraysize,...) \ typedef type TOKEN_##name##_TYPE; - #include "hal/micro/cortexm3/token-manufacturing.h" + #include "cpu/stm32w108/hal/micro/cortexm3/token-manufacturing.h" #undef TOKEN_MFG -#undef TOKEN_NEXT_ADDRESS - +#undef TOKEN_NEXT_ADDRESS + #define DEFINEADDRESSES /** - * @description Macro for creating a 'region' element in the enum below. This + * \brief Macro for creating a 'region' element in the enum below. This * creates an element in the enum that provides a starting point (address) for * subsequent tokens to align against. ( See hal/micro/cortexm3/token.c for * the instances of TOKEN_NEXT_ADDRESS() ); * - * @param region: The name to give to the element in the address enum.. - * - * @param address: The address in EEPROM where the region begins. + * \param region: The name to give to the element in the address enum. + * \param address: The address in EEPROM where the region begins. */ #define TOKEN_NEXT_ADDRESS(region, address) \ TOKEN_##region##_NEXT_ADDRESS = ((address) - 1), /** - * @description Macro for creating ADDRESS and END elements for each token in + * \brief Macro for creating ADDRESS and END elements for each token in * the enum below. The ADDRESS element is linked to from the the normal - * TOKEN_##name macro and provides the value passed into the internal token + * TOKEN_\#\#name macro and provides the value passed into the internal token * system calls. The END element is a placeholder providing the starting * point for the ADDRESS of the next dynamically positioned token. * - * @param name: The name of the token. - * - * @param arraysize: The number of elements in an indexed token (arraysize=1 - * for scalar tokens). + * \param name: The name of the token. + * \param creator: The manufacturing creators. + * \param iscnt: + * \param isidx: + * \param type: The token type. The types are found in token-stack.h. + * \param arraysize: The number of elements in an indexed token (arraysize=1 + * for scalar tokens). */ #define TOKEN_MFG(name,creator,iscnt,isidx,type,arraysize,...) \ TOKEN_##name##_ADDRESS, \ @@ -95,7 +109,7 @@ (TOKEN_##name##_SIZE * arraysize) - 1, /** - * @description The enum that operates on the two macros above. Also provides + * \brief The enum that operates on the two macros above. Also provides * an indentifier so the address of the top of the token system can be known. */ enum { @@ -106,29 +120,27 @@ enum { #undef DEFINETOKENS - -#ifndef DOXYGEN_SHOULD_SKIP_THIS /** - * @description Copies the token value from non-volatile storage into a RAM + * \brief Copies the token value from non-volatile storage into a RAM * location. This is the internal function that the exposed API * (halCommonGetMfgToken) expands out to. The * API simplifies the access into this function by hiding the size parameter. * - * @param data: A pointer to where the data being read should be placed. + * \param data: A pointer to where the data being read should be placed. * - * @param token: The name of the token to get data from. On this platform + * \param token: The name of the token to get data from. On this platform * that name is defined as an address. * - * @param index: The index to access. If the token being accessed is not an + * \param index: The index to access. If the token being accessed is not an * indexed token, this parameter is set by the API to be 0x7F. * - * @param len: The length of the token being worked on. This value is + * \param len: The length of the token being worked on. This value is * automatically set by the API to be the size of the token. */ void halInternalGetMfgTokenData(void *data, uint16_t token, uint8_t index, uint8_t len); /** - * @description Sets the value of a token in non-volatile storage. This is + * \brief Sets the value of a token in non-volatile storage. This is * the internal function that the exposed API (halCommonSetMfgToken) * expands out to. The API simplifies the access into this function * by hiding the size parameter. @@ -139,12 +151,12 @@ void halInternalGetMfgTokenData(void *data, uint16_t token, uint8_t index, uint8 * REMEMBER: The flash hardware requires writing to 16bit aligned * addresses with a length that is multiples of 16bits. * - * @param token: The name of the token to get data from. On this platform + * \param token: The name of the token to get data from. On this platform * that name is defined as an address. * - * @param data: A pointer to the data being written. + * \param data: A pointer to the data being written. * - * @param len: The length of the token being worked on. This value is + * \param len: The length of the token being worked on. This value is * automatically set by the API to be the size of the token. */ void halInternalSetMfgTokenData(uint16_t token, void *data, uint8_t len); diff --git a/cpu/stm32w108/hal/micro/cortexm3/micro-common.h b/cpu/stm32w108/hal/micro/cortexm3/micro-common.h index de555a15b..ecc771bc1 100644 --- a/cpu/stm32w108/hal/micro/cortexm3/micro-common.h +++ b/cpu/stm32w108/hal/micro/cortexm3/micro-common.h @@ -56,8 +56,8 @@ /** * @brief Resets the watchdog timer. This function is pointed - * to by the macro ::halResetWatchdog(). - * @warning Be very careful when using this as you can easily get into an + * to by the macro ::halResetWatchdog(). + * @warning Be very careful when using this as you can easily get into an * infinite loop. */ void halInternalResetWatchDog( void ); @@ -162,13 +162,13 @@ void halInternalSearchForBiasTrim(void); * hardware peripherals. This function works by simply adding another * layer on top of halCommonDelayMicroseconds(). * - * @param ms The specified time, in milliseconds. + * @param ms The specified time, in milliseconds. */ void halCommonDelayMilliseconds(uint16_t ms); /** @brief Puts the microcontroller to sleep in a specified mode, allows - * the GPIO wake sources to be determined at runtime. This function + * the GPIO wake sources to be determined at runtime. This function * requires the GPIO wake sources to be defined at compile time in the board * file. * @@ -180,7 +180,7 @@ void halCommonDelayMilliseconds(uint16_t ms); * the chip from deep sleep. A high bit in the mask will enable waking * the chip if the corresponding GPIO changes state. bit0 is PA0, bit1 is * PA1, bit8 is PB0, bit16 is PCO, bit23 is PC7, bits[31:24] are ignored. - * + * * @sa ::SleepModes */ void halSleepWithOptions(SleepModes sleepMode, uint32_t gpioWakeBitMask); @@ -203,18 +203,16 @@ void halSleepWithOptions(SleepModes sleepMode, uint32_t gpioWakeBitMask); * to 48.5 days. Any sleep duration greater than this limit will wake up * briefly (e.g. 16 microseconds) to reenable another sleep cycle. * - * @nostackusage - * * @param duration The amount of time, expressed in quarter seconds, that the * micro should be placed into ::SLEEPMODE_WAKETIMER. When the function returns, * this parameter provides the amount of time remaining out of the original * sleep time request (normally the return value will be 0). - * + * * @param gpioWakeBitMask A bit mask of the GPIO that are allowed to wake * the chip from deep sleep. A high bit in the mask will enable waking * the chip if the corresponding GPIO changes state. bit0 is PA0, bit1 is * PA1, bit8 is PB0, bit16 is PCO, bit23 is PC7, bits[31:24] are ignored. - * + * * @return An StStatus value indicating the success or * failure of the command. */ @@ -248,7 +246,7 @@ void halInternalSleep(SleepModes sleepMode); * - [25] = PWRUP_SLEEPTMRCOMPB * - [24] = PWRUP_SLEEPTMRCOMPA * - [23:0] = corresponding GPIO activity - * + * * WakeInfoValid means that ::halSleepWithOptions (::halInternalSleep) has been called * at least once. Since the power on state clears the wake event info, * this bit says the sleep code has been called since power on. @@ -260,7 +258,7 @@ void halInternalSleep(SleepModes sleepMode); * signal is set). The net affect of skipping sleep is the Low Voltage * domain never goes through a power/reset cycle. * - * @return The events that caused the last wake from sleep. + * @return The events that caused the last wake from sleep. */ uint32_t halGetWakeInfo(void); diff --git a/cpu/stm32w108/hal/micro/cortexm3/nvm.h b/cpu/stm32w108/hal/micro/cortexm3/nvm.h index 8f9bea60d..6e65380ac 100644 --- a/cpu/stm32w108/hal/micro/cortexm3/nvm.h +++ b/cpu/stm32w108/hal/micro/cortexm3/nvm.h @@ -2,16 +2,19 @@ * @brief Cortex-M3 Non-Volatile Memory data storage system. * See @ref nvm for documentation. * - * The functions in this file return an ::StStatus value. + * The functions in this file return an ::StStatus value. * See error-def.h for definitions of all ::StStatus return values. * * See hal/micro/cortexm3/nvm.h for source code. * * */ - -/** @addtogroup nvm - * @brief Cortex-M3 Non-Volatile Memory data storage system. + +/** + * @addtogroup stm32w-cpu + * @{ */ + +/** @defgroup nvm Cortex-M3 Non-Volatile Memory data storage system. * * This header defines the API for NVM data storage. This header also * describes the algorithm behind the NVM data storage system with notes @@ -23,7 +26,7 @@ * that is a multiple of physical flash pages. There are two pages: LEFT * and RIGHT. The term "flash page" is used to refer to a page of * physical flash. - * + * * NVM data storage works by alternating between two pages: LEFT and RIGHT. * The basic algorithm is driven by a call to halCommonSaveToNvm(). It will: * - erase the inactive page @@ -54,35 +57,35 @@ * is LEFT then the state machine will advance until state 7 and then exit. * If "Read from" is RIGHT, then the state machine will advance until * state 3 and then exit. - * + * * @code * Starting from erased or invalid mgmt, write to LEFT - * State # 0 0 1 2 3 - * Reads from: x x e w L L L + * State # 0 0 1 2 3 + * Reads from: x x e w L L L * Valid xx|xx FF|FF r r 00|FF 00|FF 00|00 * Active xx|xx FF|FF a i 00|FF 00|FF 00|00 * Dead xx|xx FF|FF s t FF|FF FF|00 FF|00 * Spare xx|xx FF|FF e e FF|FF FF|FF FF|FF - * - * + * + * * Starting from LEFT page, transition to RIGHT page: - * State # 3 4 5 6 7 - * Reads from: L e L w R R R + * State # 3 4 5 6 7 + * Reads from: L e L w R R R * Valid 00|00 r 00|FF r 00|00 00|00 00|00 * Active 00|00 a 00|FF i 00|FF 00|FF 00|00 * Dead FF|00 s FF|FF t FF|FF 00|FF 00|FF * Spare FF|FF e FF|FF e FF|FF FF|FF FF|FF - * - * + * + * * Starting from RIGHT page, transition to LEFT page: - * State # 7 8 9 10 3 - * Reads from: R e R w L L L + * State # 7 8 9 10 3 + * Reads from: R e R w L L L * Valid 00|00 r FF|00 r 00|00 00|00 00|00 * Active 00|00 a FF|00 i FF|00 FF|00 00|00 * Dead 00|FF s FF|FF t FF|FF FF|00 FF|00 * Spare FF|FF e FF|FF e FF|FF FF|FF FF|FF * @endcode - * + * * Based on the 10 possible states, there are 5 valid 32bit mgmt words: * - 0xFFFFFFFF * - 0xFFFFFF00 @@ -91,7 +94,7 @@ * - 0xFF00FFFF * The algorithm determines the current state by using these 5 mgmt words * with the 10 possible combinations of LEFT mgmt and RIGHT mgmt. - * + * * Detailed State Description: * - State 0: * In this state the mgmt bytes do not conform to any of the other states @@ -131,8 +134,8 @@ * Once at these states, the current page is marked Valid and Active and * the old page is marked as Dead. The algorithm knows which page to * read from and which page needs to be erased on the next write to the NVM. - * - * + * + * * Notes on algorithm behavior: * - Refer to nvm-def.h for a list of offset/length that define the data * stored in NVM storage space. @@ -185,14 +188,14 @@ /** * @brief Copy the NVM data from flash into the provided RAM location. * It is illegal for the offset to be greater than NVM_DATA_SIZE_B. - * + * * @param data A (RAM) pointer to where the data should be copied. - * + * * @param offset The location from which the data should be copied. Must be * 16bit aligned. - * + * * @param length The length of the data in bytes. Must be 16bit aligned. - * + * * @return An StStatus value indicating the success of the function. * - ST_SUCCESS if the read completed cleanly. * - ST_ERR_FATAL if the NVM storage management indicated an invalid @@ -202,10 +205,10 @@ StStatus halCommonReadFromNvm(void *data, uint32_t offset, uint16_t length); /** * @brief Return the address of the token in NVM - * + * * @param offset The location offset from which the address should be returned - * - * + * + * * @return The address requested */ uint16_t *halCommonGetAddressFromNvm(uint32_t offset); @@ -213,14 +216,14 @@ uint16_t *halCommonGetAddressFromNvm(uint32_t offset); /** * @brief Write the NVM data from the provided location RAM into flash. * It is illegal for the offset to be greater than NVM_DATA_SIZE_B. - * + * * @param data A (RAM) pointer from where the data should be taken. - * + * * @param offset The location to which the data should be written. Must be * 16bit aligned. - * + * * @param length The length of the data in bytes. Must be 16bit aligned. - * + * * @return An StStatus value indicating the success of the function. * - ST_SUCCESS if the write completed cleanly. * - Any other status value is an error code generated by the low level @@ -274,6 +277,7 @@ StStatus halCommonWriteToNvm(const void *data, uint32_t offset, uint16_t length) #define NVM_MGMT_SIZE_B (4) /** @} END addtogroup */ +/** @} */ #endif // NVM_H_ diff --git a/cpu/stm32w108/hal/micro/cortexm3/stm32w108/board.h b/cpu/stm32w108/hal/micro/cortexm3/stm32w108/board.h index 1619ee81d..3839d69da 100644 --- a/cpu/stm32w108/hal/micro/cortexm3/stm32w108/board.h +++ b/cpu/stm32w108/hal/micro/cortexm3/stm32w108/board.h @@ -1,4 +1,4 @@ -/** @file board.h +/** @file cpu/stm32w108/hal/micro/cortexm3/stm32w108/board.h * @brief Header file x STM32W108 Kits boards abstraction. * See @ref board for documentation. * @@ -18,7 +18,7 @@ * See hal/micro/cortexm3/stm32w108/board.h for source code. *@{ */ - + /** * @brief Define the number of LEDs in the specific board revision */ @@ -134,7 +134,7 @@ typedef struct BoardIOStruct { /** Pointer to LED resources */ const LedResourceType *leds; /** Pointer to button resources */ - const ButtonResourceType *buttons; + const ButtonResourceType *buttons; } BoardIOType; /** @@ -227,7 +227,7 @@ extern BoardResourcesType const *boardDescription; /** @brief Return pointer to board description structure * - * + * * @return Pointer to board description structure */ BoardResourcesType const *halBoardGetDescription(void); diff --git a/cpu/stm32w108/hal/micro/cortexm3/temperature-sensor.c b/cpu/stm32w108/hal/micro/cortexm3/temperature-sensor.c index 152b3bd90..36727e0d6 100644 --- a/cpu/stm32w108/hal/micro/cortexm3/temperature-sensor.c +++ b/cpu/stm32w108/hal/micro/cortexm3/temperature-sensor.c @@ -1,5 +1,5 @@ -/**@file temperature-sensor.c - * @brief MB851 temperature sensor APIS +/**@file cpu/stm32w108/hal/micro/cortexm3/temperature-sensor.c + * @brief MB851 temperature sensor APIS * * * @@ -17,12 +17,12 @@ void temperatureSensor_Init(void) halGpioConfig(TEMPERATURE_SENSOR_GPIO,GPIOCFG_ANALOG); /* Init ADC driver */ halInternalInitAdc(); - + /* - NOTE: - The ADC extended range is inaccurate due to the high voltage mode bug of the general purpose ADC + NOTE: + The ADC extended range is inaccurate due to the high voltage mode bug of the general purpose ADC (see STM32W108 errata). As consequence, it is not reccomended to use this ADC driver for getting - the temperature values. + the temperature values. */ #ifdef ENABLE_ADC_EXTENDED_RANGE_BROKEN halAdcSetRange(TRUE); @@ -35,18 +35,18 @@ uint32_t temperatureSensor_GetValue(void) static int16_t volts; /* - NOTE: - The ADC extended range is inaccurate due to the high voltage mode bug of the general purpose ADC + NOTE: + The ADC extended range is inaccurate due to the high voltage mode bug of the general purpose ADC (see STM32W108 errata). As consequence, it is not reccomended to use this ADC driver for getting - the temperature values. + the temperature values. */ halStartAdcConversion(ADC_USER_APP, ADC_REF_INT, ADC_SOURCE(halGetADCChannelFromGPIO(TEMPERATURE_SENSOR_GPIO),ADC_MUX_VREF2), ADC_CONVERSION_TIME_US_4096); - + halReadAdcBlocking(ADC_USER_APP, &ADCvalue); // This blocks for a while, about 4ms. - + // 100 uVolts volts = halConvertValueToVolts(ADCvalue); - - return ((18641 - (int32_t)volts)*100)/1171; + + return ((18641 - (int32_t)volts)*100)/1171; }/* end temperatureSensor_GetValue() */ diff --git a/cpu/stm32w108/hal/micro/cortexm3/uart.h b/cpu/stm32w108/hal/micro/cortexm3/uart.h index c15bf051d..f0c418ac0 100644 --- a/cpu/stm32w108/hal/micro/cortexm3/uart.h +++ b/cpu/stm32w108/hal/micro/cortexm3/uart.h @@ -23,17 +23,17 @@ typedef enum /** * @brief Initialize the UART - * + * * @param baudrate The baudrate which will be used for communication. * Ex: 115200 - * + * * @param databits The number of data bits used for communication. * Valid values are 7 or 8 - * - * @param parity The type of parity used for communication. + * + * @param parity The type of parity used for communication. * See the SerialParity enum for possible values - * - * @return stopbits The number of stop bits used for communication. + * + * @param stopbits The number of stop bits used for communication. * Valid values are 1 or 2 */ void uartInit(uint32_t baudrate, uint8_t databits, SerialParity parity, uint8_t stopbits); @@ -45,9 +45,9 @@ void uartInit(uint32_t baudrate, uint8_t databits, SerialParity parity, uint8_t * instead which does not define fflush(). Therefore, we manually define * fflush() in the low level UART driver. This function simply redirects * to the __write() function with a NULL buffer, triggering a flush. - * + * * @param handle The output stream. Should be set to 'stdout' like normal. - * + * * @return Zero, indicating success. */ size_t fflush(int handle); @@ -61,7 +61,7 @@ size_t fflush(int handle); #define stdout _LLIO_STDOUT #endif /** - * @brief Read the input byte if any. + * @brief Read the input byte if any. */ boolean __io_getcharNonBlocking(uint8_t *data); void __io_putchar( char c ); diff --git a/cpu/stm32w108/hal/micro/generic/compiler/platform-common.h b/cpu/stm32w108/hal/micro/generic/compiler/platform-common.h index 92f65625c..0c9bd0cf3 100644 --- a/cpu/stm32w108/hal/micro/generic/compiler/platform-common.h +++ b/cpu/stm32w108/hal/micro/generic/compiler/platform-common.h @@ -1,6 +1,6 @@ -/** \addtogroup platform_common +/** * \brief Compiler and Platform specific definitions and typedefs common to - * all platforms. + * all platforms. * * platform-common.h provides PLATFORM_HEADER defaults and common definitions. * This head should never be included directly, it should only be included @@ -10,13 +10,17 @@ *@{ */ +/** + * @addtogroup stm32w-cpu + * @{ */ + /** \file hal/micro/generic/compiler/platform-common.h - * See \ref platform_common for detailed documentation. + * See platform_common.h for detailed documentation. * * */ - + #ifndef PLATCOMMONOKTOINCLUDE // This header should only be included by a PLATFORM_HEADER #error platform-common.h should not be included directly @@ -25,7 +29,7 @@ #ifndef PLATFORMCOMMON_H_ #define PLATFORMCOMMON_H_ //////////////////////////////////////////////////////////////////////////////// -// Many of the common definitions must be explicitly enabled by the +// Many of the common definitions must be explicitly enabled by the // particular PLATFORM_HEADER being used //////////////////////////////////////////////////////////////////////////////// @@ -65,16 +69,16 @@ //////////////////////////////////////////////////////////////////////////////// #ifdef _HAL_USE_COMMON_DIVMOD_ /** \name Divide and Modulus Operations - * Some platforms can perform divide and modulus operations on 32 bit + * Some platforms can perform divide and modulus operations on 32 bit * quantities more efficiently when the divisor is only a 16 bit quantity. * C compilers will always promote the divisor to 32 bits before performing the - * operation, so the following utility functions are instead required to take + * operation, so the following utility functions are instead required to take * advantage of this optimisation. */ //@{ /** * \brief Provide a portable name for the uint32_t by uint16_t division - * library function (which can perform the division with only a single + * library function (which can perform the division with only a single * assembly instruction on some platforms) */ #define halCommonUDiv32By16(x, y) ((uint16_t) (((uint32_t) (x)) / ((uint16_t) (y)))) @@ -107,12 +111,12 @@ #ifdef _HAL_USE_COMMON_MEMUTILS_ /** \name C Standard Library Memory Utilities * These should be used in place of the standard library functions. - * + * * These functions have the same parameters and expected results as their C * Standard Library equivalents but may take advantage of certain implementation * optimizations. - * - * Unless otherwise noted, these functions are utilized by the StStack and are + * + * Unless otherwise noted, these functions are utilized by the StStack and are * therefore required to be implemented in the HAL. Additionally, unless otherwise * noted, applications that find these functions useful may utilze them. */ @@ -208,22 +212,22 @@ #define SETBIT(reg, bit) reg |= BIT(bit) /** - * \brief Sets the bits in the \c reg register or the byte - * as specified in the bitmask \c bits. + * \brief Sets the bits in the \c reg register or the byte + * as specified in the bitmask \c bits. * @note This is never a single atomic operation. */ #define SETBITS(reg, bits) reg |= (bits) /** - * \brief Clears a bit in the \c reg register or byte. - * @note Assuming \c reg is an IO register, some platforms (such as the AVR) + * \brief Clears a bit in the \c reg register or byte. + * @note Assuming \c reg is an IO register, some platforms (such as the AVR) * can implement this in a single atomic operation. */ #define CLEARBIT(reg, bit) reg &= ~(BIT(bit)) /** - * \brief Clears the bits in the \c reg register or byte - * as specified in the bitmask \c bits. + * \brief Clears the bits in the \c reg register or byte + * as specified in the bitmask \c bits. * @note This is never a single atomic operation. */ #define CLEARBITS(reg, bits) reg &= ~(bits) @@ -234,7 +238,7 @@ #define READBIT(reg, bit) (reg & (BIT(bit))) /** - * \brief Returns the value of the bitmask \c bits within + * \brief Returns the value of the bitmask \c bits within * the register or byte \c reg. */ #define READBITS(reg, bits) (reg & (bits)) @@ -259,13 +263,13 @@ #define HIGH_BYTE(n) ((uint8_t)(LOW_BYTE((n) >> 8))) /** - * \brief Returns the value built from the two \c uint8_t + * \brief Returns the value built from the two \c uint8_t * values \c high and \c low. */ #define HIGH_LOW_TO_INT(high, low) ( \ (( (uint16_t) (high) ) << 8) + \ ( (uint16_t) ( (low) & 0xFF)) \ - ) + ) /** * \brief Returns the low byte of the 32-bit value \c n as an \c uint8_t. @@ -297,21 +301,21 @@ //@{ /** - * \brief Returns the elapsed time between two 8 bit values. + * \brief Returns the elapsed time between two 8 bit values. * Result may not be valid if the time samples differ by more than 127 */ #define elapsedTimeInt8u(oldTime, newTime) \ ((uint8_t) ((uint8_t)(newTime) - (uint8_t)(oldTime))) /** - * \brief Returns the elapsed time between two 16 bit values. + * \brief Returns the elapsed time between two 16 bit values. * Result may not be valid if the time samples differ by more than 32767 */ #define elapsedTimeInt16u(oldTime, newTime) \ ((uint16_t) ((uint16_t)(newTime) - (uint16_t)(oldTime))) /** - * \brief Returns the elapsed time between two 32 bit values. + * \brief Returns the elapsed time between two 32 bit values. * Result may not be valid if the time samples differ by more than 2147483647 */ #define elapsedTimeInt32u(oldTime, newTime) \ @@ -348,4 +352,5 @@ #endif //PLATFORMCOMMON_H_ /** @} END addtogroup */ +/** @} */ diff --git a/cpu/stm32w108/hal/micro/led.h b/cpu/stm32w108/hal/micro/led.h index c34fca1ff..69c5e9bac 100644 --- a/cpu/stm32w108/hal/micro/led.h +++ b/cpu/stm32w108/hal/micro/led.h @@ -4,8 +4,11 @@ * */ -/** @addtogroup led - * @brief Sample API funtions for controlling LEDs. +/** + * @addtogroup stm32w-cpu + * @{ */ + +/** @defgroup led Sample API funtions for controlling LEDs. * * When specifying an LED to use, always use the BOARDLEDx definitions that * are defined within the BOARD_HEADER. @@ -55,4 +58,4 @@ void halClearLed(HalBoardLed led); /** @} // END addtogroup */ - +/** @} */ diff --git a/cpu/stm32w108/hal/micro/mems.h b/cpu/stm32w108/hal/micro/mems.h index 5dc4e53d5..70bae7523 100644 --- a/cpu/stm32w108/hal/micro/mems.h +++ b/cpu/stm32w108/hal/micro/mems.h @@ -1,5 +1,5 @@ -/** @file mems.h - * @brief Header for MB851 mems APIS +/** @file cpu/stm32w108/hal/micro/mems.h + * @brief Header for MB851 mems APIS * * * @@ -11,7 +11,7 @@ #include "hal/micro/mems-regs.h" /** @brief Mems data type: three acceleration values each related to a specific direction - Watch out: only lower data values (e.g. those terminated by the _l) are + Watch out: only lower data values (e.g. those terminated by the _l) are currently used by the device */ typedef struct { diff --git a/cpu/stm32w108/hal/micro/micro-common.h b/cpu/stm32w108/hal/micro/micro-common.h index 6e43c2be0..7ca91a930 100644 --- a/cpu/stm32w108/hal/micro/micro-common.h +++ b/cpu/stm32w108/hal/micro/micro-common.h @@ -1,11 +1,15 @@ -/** @file micro-common.h +/** @file cpu/stm32w108/hal/micro/micro-common.h * @brief Minimal Hal functions common across all microcontroller-specific files. * See @ref micro for documentation. * * */ - -/** @addtogroup micro + +/** + * @addtogroup stm32w-cpu + * @{ */ + +/** @defgroup micro Micro * Many of the supplied example applications use these microcontroller functions. * See hal/micro/micro-common.h for source code. * @@ -41,10 +45,10 @@ void halPowerUp(void); */ void halPowerDown(void); -/** @brief The value that must be passed as the single parameter to - * ::halInternalDisableWatchDog() in order to sucessfully disable the watchdog +/** @brief The value that must be passed as the single parameter to + * ::halInternalDisableWatchDog() in order to sucessfully disable the watchdog * timer. - */ + */ #define MICRO_DISABLE_WATCH_DOG_KEY 0xA5 /** @brief Enables the watchdog timer. @@ -53,9 +57,9 @@ void halInternalEnableWatchDog(void); /** @brief Disables the watchdog timer. * - * @note To prevent the watchdog from being disabled accidentally, + * @note To prevent the watchdog from being disabled accidentally, * a magic key must be provided. - * + * * @param magicKey A value (::MICRO_DISABLE_WATCH_DOG_KEY) that enables the function. */ void halInternalDisableWatchDog(uint8_t magicKey); @@ -66,38 +70,43 @@ void halInternalDisableWatchDog(uint8_t magicKey); */ boolean halInternalWatchDogEnabled( void ); -#ifdef DOXYGEN_SHOULD_SKIP_THIS /** @brief Enumerations for the possible microcontroller sleep modes. - * - SLEEPMODE_RUNNING - * Everything is active and running. In practice this mode is not - * used, but it is defined for completeness of information. - * - SLEEPMODE_IDLE - * Only the CPU is idled. The rest of the chip continues runing - * normally. The chip will wake from any interrupt. - * - SLEEPMODE_WAKETIMER - * The sleep timer clock sources remain running. The RC is always - * running and the 32kHz XTAL depends on the board header. Wakeup - * is possible from both GPIO and the sleep timer. System time - * is maintained. The sleep timer is assumed to be configured - * properly for wake events. - * - SLEEPMODE_MAINTAINTIMER - * The sleep timer clock sources remain running. The RC is always - * running and the 32kHz XTAL depends on the board header. Wakeup - * is possible from only GPIO. System time is maintained. - * - SLEEPMODE_NOTIMER - * The sleep timer clock sources (both RC and XTAL) are turned off. - * Wakeup is possible from only GPIO. System time is lost. */ +#ifdef DOXYGEN_SHOULD_SKIP_THIS enum SleepModes #else typedef uint8_t SleepModes; enum #endif { + /** + * Everything is active and running. In practice this mode is not + * used, but it is defined for completeness of information. + */ SLEEPMODE_RUNNING = 0, + /** + * Oly the CPU is idled. The rest of the chip continues runing + * normally. The chip will wake from any interrupt. + */ SLEEPMODE_IDLE = 1, + /** + * The sleep timer clock sources remain running. The RC is always + * running and the 32kHz XTAL depends on the board header. Wakeup + * is possible from both GPIO and the sleep timer. System time + * is maintained. The sleep timer is assumed to be configured + * properly for wake events. + */ SLEEPMODE_WAKETIMER = 2, + /** + * The sleep timer clock sources remain running. The RC is always + * running and the 32kHz XTAL depends on the board header. Wakeup + * is possible from only GPIO. System time is maintained. + */ SLEEPMODE_MAINTAINTIMER = 3, + /** + * The sleep timer clock sources (both RC and XTAL) are turned off. + * Wakeup is possible from only GPIO. System time is lost. + */ SLEEPMODE_NOTIMER = 4, }; @@ -113,7 +122,7 @@ enum * be within 10us. If the micro is running off of another type of oscillator * (e.g. RC) the timing accuracy will potentially be much worse. * - * @param us The specified time, in microseconds. + * @param us The specified time, in microseconds. Values should be between 1 and 65535 microseconds. */ void halCommonDelayMicroseconds(uint16_t us); @@ -122,17 +131,17 @@ void halCommonDelayMicroseconds(uint16_t us); * * This function will check whwther the user flash contains the bootloader * and if yes it will jump into it according to the user parameters. - * * - * @param mode The bootloader mode, 0 UART mode, 1 RF mode. All other - * values are reserved + * + * @param mode The bootloader mode, 0 UART mode, 1 RF mode. All other + * values are reserved * @param channel The channel where the booloader will operate. 0 means - * default channel (only vaild for RF mode). - * @param panID The panID where the booloader will operate. 0xFFFF means - * default panID (only vaild for RF mode). + * default channel (only vaild for RF mode). + * @param panID The panID where the booloader will operate. 0xFFFF means + * default panID (only vaild for RF mode). * @return An error code or it will never return. */ -StStatus halBootloaderStart(uint8_t mode, uint8_t channel, uint16_t panId); +StStatus halBootloaderStart(uint8_t mode, uint8_t channel, uint16_t panID); #ifdef CORTEXM3_STM32F103 #include "micro/cortexm3/stm32f103ret/micro-specific.h" @@ -144,4 +153,4 @@ StStatus halBootloaderStart(uint8_t mode, uint8_t channel, uint16_t panId); #endif //MICRO_COMMON_H_ /** @} END micro group */ - +/** @} */ diff --git a/cpu/stm32w108/hal/micro/system-timer.h b/cpu/stm32w108/hal/micro/system-timer.h index 703a58fa7..8fd5ee91f 100644 --- a/cpu/stm32w108/hal/micro/system-timer.h +++ b/cpu/stm32w108/hal/micro/system-timer.h @@ -1,12 +1,16 @@ /** @file hal/micro/system-timer.h * @brief Header file for system_timer APIs - * + * * * */ -/** @addtogroup system_timer +/** + * @addtogroup stm32w-cpu + * @{ */ + +/** @defgroup system_timer System Timer * @brief Functions that provide access to the system clock. * * A single system tick (as returned by ::halCommonGetInt16uMillisecondTick() and @@ -35,7 +39,7 @@ /** * @brief Initializes the system tick. * - * @return Time to update the async registers after RTC is started (units of 100 + * @return Time to update the async registers after RTC is started (units of 100 * microseconds). */ uint16_t halInternalStartSystemTimer(void); @@ -54,9 +58,9 @@ uint16_t halCommonGetInt16uMillisecondTick(void); * @brief Returns the current system time in system ticks, as a 32-bit * value. * - * @nostackusage + * nostackusage * - * @return The least significant 32 bits of the current system time, in + * @return The least significant 32 bits of the current system time, in * system ticks. */ uint32_t halCommonGetInt32uMillisecondTick(void); @@ -65,7 +69,7 @@ uint32_t halCommonGetInt32uMillisecondTick(void); * @brief Returns the current system time in quarter second ticks, as a * 16-bit value. * - * @nostackusage + * nostackusage * * @return The least significant 16 bits of the current system time, in system * ticks multiplied by 256. @@ -74,9 +78,9 @@ uint16_t halCommonGetInt16uQuarterSecondTick(void); #endif //SYSTEM_TIMER_H_ -/**@} //END addtogroup +/**@} //END addtogroup */ - +/** @} */ diff --git a/cpu/stm32w108/hal/micro/temperature-sensor.h b/cpu/stm32w108/hal/micro/temperature-sensor.h index 7965e8a0f..f7ad8c1be 100644 --- a/cpu/stm32w108/hal/micro/temperature-sensor.h +++ b/cpu/stm32w108/hal/micro/temperature-sensor.h @@ -1,5 +1,5 @@ -/** @file temperature-sensor.h - * @brief Header for temperature sensor driver +/** @file cpu/stm32w108/hal/micro/temperature-sensor.h + * @brief Header for temperature sensor driver * * * @@ -15,11 +15,11 @@ /* Functions -----------------------------------------------------------------*/ -/** @brief Temperature Sensor Initialization function +/** @brief Temperature Sensor Initialization function */ void temperatureSensor_Init(void); -/** @brief Get temperature sensor value +/** @brief Get temperature sensor value */ uint32_t temperatureSensor_GetValue(void); diff --git a/cpu/x86/Makefile.x86 b/cpu/x86/Makefile.x86 deleted file mode 100644 index 0aececd4d..000000000 --- a/cpu/x86/Makefile.x86 +++ /dev/null @@ -1,32 +0,0 @@ -CONTIKI_CPU_DIRS = . - -CONTIKI_SOURCEFILES += mtarch.c elfloader-x86.c - -### Compiler definitions -CC = gcc -LD = gcc -AS = as -OBJCOPY = objcopy -STRIP = strip -CFLAGSNO = -Wall -g -I/usr/local/include -CFLAGS += $(CFLAGSNO) -ifeq ($(HOST_OS),Linux) - LDFLAGS = -Wl,-Map=contiki-$(TARGET).map,-export-dynamic -else - LDFLAGS = -Wl -endif - -### Compilation rules - -%.so: $(OBJECTDIR)/%.o - $(LD) -shared -o $@ $^ - -ifdef CORE -.PHONY: symbols.c symbols.h -symbols.c symbols.h: - $(NM) $(CORE) | awk -f $(CONTIKI)/tools/mknmlist > symbols.c -else -symbols.c symbols.h: - cp ${CONTIKI}/tools/empty-symbols.c symbols.c - cp ${CONTIKI}/tools/empty-symbols.h symbols.h -endif diff --git a/cpu/x86/Makefile.x86_common b/cpu/x86/Makefile.x86_common new file mode 100644 index 000000000..c27626815 --- /dev/null +++ b/cpu/x86/Makefile.x86_common @@ -0,0 +1,44 @@ +CONTIKI_CPU_DIRS += . init/common + +CONTIKI_SOURCEFILES += gdt.c helpers.S idt.c cpu.c + +CC = gcc +LD = $(CC) +# Use gcc to invoke the assembler so that the preprocessor will be run on each +# file first, enabling us to use macros within assembly language files: +AS = $(CC) +OBJCOPY = objcopy +SIZE = size +STRIP = strip + +# Omit exception handling unwind tables (see +# http://wiki.dwarfstd.org/index.php?title=Exception_Handling). Removing these +# tables saves space and has not caused any readily-apparent functional +# changes. +# +# Furthermore, the .eh_frame and .eh_frame_hdr sections that are otherwise +# generated are treated as code sections by the UEFI GenFw program, since they +# are read-only alloc sections. They get grouped with the actual code +# sections, ahead of the data sections. This perturbs symbols and complicates +# debugging. +# +# Synchronize the unwind table options here with the CFLAGS and CXXFLAGS in +# ./bsp/libc/build_newlib.sh. +CFLAGS += -Wall -fno-asynchronous-unwind-tables -fno-unwind-tables +LDFLAGS += -Wl,-Map=contiki-$(TARGET).map,--build-id=none + +ifeq ($(BUILD_RELEASE),1) + CFLAGS += -Os -fno-strict-aliasing -ffunction-sections -fdata-sections +# XXX: --gc-sections can be very tricky sometimes. If somehow the release +# binary seems to be broken, check if removing this option fixes the issue. +# Applying the --strip-all option to the UEFI build may induce an "Invalid operation" error. +# The UEFI GenFw program strips symbols. + MULTIBOOT_LDFLAGS += -Wl,--strip-all,--gc-sections +else + CFLAGS += -O0 + ifeq ($(findstring clang,$(CC)),clang) + CFLAGS += -g + else + CFLAGS += -ggdb3 + endif +endif diff --git a/cpu/x86/Makefile.x86_quarkX1000 b/cpu/x86/Makefile.x86_quarkX1000 new file mode 100644 index 000000000..1a8d3ac8e --- /dev/null +++ b/cpu/x86/Makefile.x86_quarkX1000 @@ -0,0 +1,93 @@ +# See mm/README.md for a description of available settings: +X86_CONF_PROT_DOMAINS ?= none + +include $(CONTIKI)/cpu/x86/Makefile.x86_common + +CONTIKI_CPU_DIRS += drivers/legacy_pc drivers/quarkX1000 init/legacy_pc net mm + +CONTIKI_SOURCEFILES += bootstrap_quarkX1000.S rtc.c pit.c pic.c irq.c nmi.c pci.c uart-16x50.c uart.c gpio.c i2c.c eth.c shared-isr.c +CONTIKI_SOURCEFILES += imr.c msg-bus.c +CONTIKI_SOURCEFILES += stacks.c + +ifneq ($(X86_CONF_PROT_DOMAINS),none) +CONTIKI_SOURCEFILES += prot-domains.c $(X86_CONF_PROT_DOMAINS)-prot-domains.c imr-conf.c + +ifeq ($(X86_CONF_PROT_DOMAINS),paging) +LINKERSCRIPT_SFX = _paging +X86_CONF_SYSCALLS_INT = 1 +ifeq ($(X86_CONF_USE_INVLPG),1) +CFLAGS += -DX86_CONF_USE_INVLPG +endif +# This matches the definition of X86_CONF_PROT_DOMAINS__PAGING in prot-domains.h: +CFLAGS += -DX86_CONF_PROT_DOMAINS=1 +else ifeq ($(X86_CONF_PROT_DOMAINS),tss) +# This matches the definition of X86_CONF_PROT_DOMAINS__TSS in prot-domains.h: +CFLAGS += -DX86_CONF_PROT_DOMAINS=2 +X86_CONF_MULTI_SEG = 1 +CONTIKI_SOURCEFILES += tss-prot-domains-asm.S +else ifeq ($(X86_CONF_PROT_DOMAINS),swseg) +# This matches the definition of X86_CONF_PROT_DOMAINS__SWSEG in prot-domains.h: +CFLAGS += -DX86_CONF_PROT_DOMAINS=3 +X86_CONF_SYSCALLS_INT = 1 +X86_CONF_MULTI_SEG = 1 +else +$(error Unrecognized setting for X86_CONF_PROT_DOMAINS: \ + $(X86_CONF_PROT_DOMAINS). See cpu/x86/mm/README.md for \ + descriptions of available settings) +endif + +ifeq ($(X86_CONF_SYSCALLS_INT),1) +CONTIKI_SOURCEFILES += syscalls-int-asm.S tss.c +endif + +ifeq ($(X86_CONF_MULTI_SEG),1) +LINKERSCRIPT_SFX = _multi_seg +CONTIKI_SOURCEFILES += multi-segment.c +# Due to the way the multi-segment implementation of protection domains define +# tightly-bounded stack segments, the base pointer register cannot be used as +# a general-purpose register in all circumstances. The stack segment is used +# by default for a data access that uses the base pointer as the base register +# to compute the address. If the data referenced by the base pointer is not +# on the stack, then the access will fail. Thus, it is necessary to disable +# the omit-frame-pointer optimization. See mm/README.md for more details of +# how multi-segment protection domains are implemented. +CFLAGS += -fno-omit-frame-pointer +endif + +endif + +CFLAGS += -m32 -march=i586 -mtune=i586 +LDFLAGS += -m32 -Xlinker -T -Xlinker $(CONTIKI)/cpu/x86/quarkX1000$(LINKERSCRIPT_SFX).ld +# The C compiler is used to invoke the assembler, so the CFLAGS should be +# passed to it on the command line: +ASFLAGS = -c $(CFLAGS) + +ifeq ($(X86_CONF_RESTRICT_DMA),1) +CONTIKI_SOURCEFILES += imr-conf.c +CFLAGS += -DX86_CONF_RESTRICT_DMA +LDFLAGS += -Xlinker -T -Xlinker $(CONTIKI)/cpu/x86/quarkX1000_dma.ld +endif + +### UEFI support + +UEFI_DIR = $(CONTIKI_CPU)/uefi + +ifndef EN_UEFI +# Include a Makefile generated by the build_uefi.sh script, if available. +# If that script was not run, then UEFI support will not be built. +-include $(UEFI_DIR)/Makefile.uefi +endif + +ifeq ($(EN_UEFI),1) + EDK2_DIR = $(UEFI_DIR)/edk2 + + GEN_FW = $(EDK2_DIR)/BaseTools/Source/C/bin/GenFw + + CONTIKI_CPU_DIRS += uefi + CONTIKI_SOURCEFILES += bootstrap_uefi.c + CFLAGS += -I$(EDK2_DIR)/MdePkg/Include -I$(EDK2_DIR)/MdePkg/Include/Ia32 +else + $(info Note: UEFI support is disabled.) + $(info To enable UEFI support, run $(CONTIKI_CPU)/uefi/build_uefi.sh prior) + $(info to building Contiki.) +endif diff --git a/cpu/x86/bootstrap_quarkX1000.S b/cpu/x86/bootstrap_quarkX1000.S new file mode 100644 index 000000000..622c9dab8 --- /dev/null +++ b/cpu/x86/bootstrap_quarkX1000.S @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "stacks.h" + +# Multiboot +.set MAGIC_NUMBER, 0x1BADB002 +.set FLAGS, 0x0 +.set CHECKSUM, -MAGIC_NUMBER + +.section .multiboot +.align 4 +.long MAGIC_NUMBER +.long FLAGS +.long CHECKSUM + +.section .boot_text +.global start +start: + cli +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS + /* TSS-based protection domains use a multi-segment model that defines + * tight bounds around stacks. That means that the bottom of the stack + * has an offset of 0, which is the address of the stacks_main symbol. + * The following code computes the physical load address of the top of + * the stack, which is what should be initially used as the stack + * pointer while the flat memory model is in use. + */ + lea _sdata_addr, %eax + lea (stacks_main + STACKS_SIZE_MAIN)(%eax), %esp +#else + mov $(stacks_main + STACKS_SIZE_MAIN), %esp +#endif + call cpu_boot_stage0 diff --git a/cpu/x86/dma.h b/cpu/x86/dma.h new file mode 100644 index 000000000..7a8d991b1 --- /dev/null +++ b/cpu/x86/dma.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_DMA_H_ +#define CPU_X86_DMA_H_ + +#include "prot-domains.h" + +#ifdef X86_CONF_RESTRICT_DMA +#define ATTR_BSS_DMA __attribute__((section(".dma_bss"))) +#else +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__NONE +#define ATTR_BSS_DMA +#else +#define ATTR_BSS_DMA ATTR_BSS_META +#endif +#endif + +extern int _ebss_pre_dma_addr, _sbss_dma_addr, _ebss_dma_addr; + +#endif /* CPU_X86_DMA_H_ */ diff --git a/cpu/x86/drivers/legacy_pc/nmi.c b/cpu/x86/drivers/legacy_pc/nmi.c new file mode 100644 index 000000000..e57d93325 --- /dev/null +++ b/cpu/x86/drivers/legacy_pc/nmi.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "helpers.h" + +#define NMI_ENABLE_PORT 0x70 + +void +nmi_enable(void) +{ + uint8_t value = inb(NMI_ENABLE_PORT); + outb(NMI_ENABLE_PORT, value & ~BIT(8)); +} +/*---------------------------------------------------------------------------*/ +void +nmi_disable(void) +{ + uint8_t value = inb(NMI_ENABLE_PORT); + outb(NMI_ENABLE_PORT, value | BIT(8)); +} diff --git a/cpu/x86/drivers/legacy_pc/nmi.h b/cpu/x86/drivers/legacy_pc/nmi.h new file mode 100644 index 000000000..3b5544cf0 --- /dev/null +++ b/cpu/x86/drivers/legacy_pc/nmi.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef NMI_H +#define NMI_H + +void nmi_enable(void); + +void nmi_disable(void); + +#endif /* NMI_H */ diff --git a/cpu/x86/drivers/legacy_pc/pci.c b/cpu/x86/drivers/legacy_pc/pci.c new file mode 100644 index 000000000..4584d454c --- /dev/null +++ b/cpu/x86/drivers/legacy_pc/pci.c @@ -0,0 +1,280 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include + +#include "pci.h" +#include "helpers.h" +#include "syscalls.h" + +/* I/O port for PCI configuration address */ +#define PCI_CONFIG_ADDR_PORT 0xCF8 +/* I/O port for PCI configuration data */ +#define PCI_CONFIG_DATA_PORT 0xCFC + +PROT_DOMAINS_ALLOC(dom_client_data_t, root_complex_drv); + +/*---------------------------------------------------------------------------*/ +/* Initialize PCI configuration register address in preparation for accessing + * the specified register. + */ +static void +set_addr(pci_config_addr_t addr) +{ + addr.en_mapping = 1; + + outl(PCI_CONFIG_ADDR_PORT, addr.raw); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Read from the specified PCI configuration register. + * \param addr Address of PCI configuration register. + * \return Value read from PCI configuration register. + */ +uint32_t +pci_config_read(pci_config_addr_t addr) +{ + set_addr(addr); + + return inl(PCI_CONFIG_DATA_PORT); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Write to the PCI configuration data port. + * \param addr Address of PCI configuration register. + * \param data Value to write. + */ +void +pci_config_write(pci_config_addr_t addr, uint32_t data) +{ + set_addr(addr); + + outl(PCI_CONFIG_DATA_PORT, data); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Enable PCI command bits of the specified PCI configuration + * register. + * \param addr Address of PCI configuration register. + * \param flags Flags used to enable PCI command bits. + */ +void +pci_command_enable(pci_config_addr_t addr, uint32_t flags) +{ + uint32_t data; + + addr.reg_off = 0x04; /* PCI COMMAND_REGISTER */ + + data = pci_config_read(addr); + pci_config_write(addr, data | flags); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Set current PIRQ to interrupt queue agent. PCI based interrupts + * PIRQ[A:H] are then available for consumption by either the 8259 + * PICs or the IO-APIC depending on configuration of the 8 PIRQx + * Routing Control Registers PIRQ[A:H]. See also pci_pirq_set_irq(). + * \param agent Interrupt Queue Agent to be used, IRQAGENT[0:3]. + * \param pin Interrupt Pin Route to be used, INT[A:D]. + * \param pirq PIRQ to be used, PIRQ[A:H]. + */ +SYSCALLS_DEFINE_SINGLETON(pci_irq_agent_set_pirq, + root_complex_drv, + IRQAGENT agent, INTR_PIN pin, PIRQ pirq) +{ + uint16_t value; + uint32_t rcba_addr, offset = 0; + + rcba_addr = PROT_DOMAINS_MMIO(root_complex_drv); + + assert(agent >= IRQAGENT0 && agent <= IRQAGENT3); + assert(pin >= INTA && pin <= INTD); + assert(pirq >= PIRQA && pirq <= PIRQH); + + switch(agent) { + case IRQAGENT0: + if(pin != INTA) { + halt(); + } + offset = 0x3140; + break; + case IRQAGENT1: + offset = 0x3142; + break; + case IRQAGENT2: + if(pin != INTA) { + halt(); + } + offset = 0x3144; + break; + case IRQAGENT3: + offset = 0x3146; + } + + prot_domains_enable_mmio(); + + MMIO_READW(value, *(uint16_t ATTR_MMIO_ADDR_SPACE *)(rcba_addr + offset)); + + /* clear interrupt pin route and set corresponding pirq. */ + switch(pin) { + case INTA: + value &= ~0xF; + value |= pirq; + break; + case INTB: + value &= ~0xF0; + value |= (pirq << 4); + break; + case INTC: + value &= ~0xF00; + value |= (pirq << 8); + break; + case INTD: + value &= ~0xF000; + value |= (pirq << 12); + } + + MMIO_WRITEW(*(uint16_t ATTR_MMIO_ADDR_SPACE *)(rcba_addr + offset), value); + + prot_domains_disable_mmio(); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Set current IRQ to PIRQ. The interrupt router can be + * programmed to allow PIRQ[A:H] to be routed internally + * to the 8259 as ISA compatible interrupts. See also + * pci_irq_agent_set_pirq(). + * \param pirq PIRQ to be used, PIRQ[A:H]. + * \param pin IRQ to be used, IRQ[0:15]. + * \param route_to_legacy Whether or not the interrupt should be routed to PIC 8259. + */ +void +pci_pirq_set_irq(PIRQ pirq, uint8_t irq, uint8_t route_to_legacy) +{ + pci_config_addr_t pci; + uint32_t value; + + assert(pirq >= PIRQA && pirq <= PIRQH); + assert(irq >= 0 && irq <= 0xF); + assert(route_to_legacy == 0 || route_to_legacy == 1); + + pci.raw = 0; + pci.bus = 0; + pci.dev = 31; + pci.func = 0; + pci.reg_off = (pirq <= PIRQD) ? 0x60 : 0x64; /* PABCDRC and PEFGHRC Registers */ + + value = pci_config_read(pci); + + switch(pirq) { + case PIRQA: + case PIRQE: + value &= ~0x8F; + value |= irq; + value |= (!route_to_legacy << 7); + break; + case PIRQB: + case PIRQF: + value &= ~0x8F00; + value |= (irq << 8); + value |= (!route_to_legacy << 15); + break; + case PIRQC: + case PIRQG: + value &= ~0x8F0000; + value |= (irq << 16); + value |= (!route_to_legacy << 23); + break; + case PIRQD: + case PIRQH: + value &= ~0x8F000000; + value |= (irq << 24); + value |= (!route_to_legacy << 31); + } + + set_addr(pci); + outl(PCI_CONFIG_DATA_PORT, value); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize a structure for a PCI device driver that performs + * MMIO to address range 0. Assumes that device has already + * been configured with an MMIO address range 0, e.g. by + * firmware. + * \param c_this Structure that will be initialized to represent the driver. + * \param pci_addr PCI base address of device. + * \param mmio_sz Size of MMIO region. + * \param meta Base address of optional driver-defined metadata. + * \param meta_sz Size of optional driver-defined metadata. + */ +void +pci_init(pci_driver_t ATTR_KERN_ADDR_SPACE *c_this, + pci_config_addr_t pci_addr, + size_t mmio_sz, + uintptr_t meta, + size_t meta_sz) +{ + uintptr_t mmio; + + /* The BAR value is masked to clear non-address bits. */ + mmio = pci_config_read(pci_addr) & ~0xFFF; + + prot_domains_reg(c_this, mmio, mmio_sz, meta, meta_sz, false); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize the PCI root complex driver. + */ +void +pci_root_complex_init(void) +{ + uint32_t rcba_addr; + pci_config_addr_t pci = { .raw = 0 }; + pci.dev = 31; + pci.reg_off = 0xF0; /* Root Complex Base Address Register */ + + /* masked to clear non-address bits. */ + rcba_addr = pci_config_read(pci) & ~0x3FFF; + + PROT_DOMAINS_INIT_ID(root_complex_drv); + prot_domains_reg(&root_complex_drv, rcba_addr, 0x4000, 0, 0, false); + SYSCALLS_INIT(pci_irq_agent_set_pirq); + SYSCALLS_AUTHZ(pci_irq_agent_set_pirq, root_complex_drv); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Prevent further invocations of pci_irq_agent_set_pirq. + */ +void +pci_root_complex_lock(void) +{ + SYSCALLS_DEAUTHZ(pci_irq_agent_set_pirq, root_complex_drv); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/drivers/legacy_pc/pci.h b/cpu/x86/drivers/legacy_pc/pci.h new file mode 100644 index 000000000..666b3c29e --- /dev/null +++ b/cpu/x86/drivers/legacy_pc/pci.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_DRIVERS_LEGACY_PC_PCI_H_ +#define CPU_X86_DRIVERS_LEGACY_PC_PCI_H_ + +#include +#include "helpers.h" +#include +#include "prot-domains.h" + +/** PCI configuration register identifier for Base Address Registers */ +#define PCI_CONFIG_REG_BAR0 0x10 +#define PCI_CONFIG_REG_BAR1 0x14 + +/** PCI Interrupt Routing is mapped using Interrupt Queue Agents */ +typedef enum { + IRQAGENT0, + IRQAGENT1, + IRQAGENT2, + IRQAGENT3 +} IRQAGENT; + +/** PCI Interupt Pins */ +typedef enum { + INTA, + INTB, + INTC, + INTD +} INTR_PIN; + +/** + * PCI based interrupts PIRQ[A:H] are then available for consumption by either + * the 8259 PICs or the IO-APIC. + */ +typedef enum { + PIRQA, + PIRQB, + PIRQC, + PIRQD, + PIRQE, + PIRQF, + PIRQG, + PIRQH, +} PIRQ; + +/** PCI command register bit to enable bus mastering */ +#define PCI_CMD_2_BUS_MST_EN BIT(2) +/** PCI command register bit to enable memory space */ +#define PCI_CMD_1_MEM_SPACE_EN BIT(1) + +/** + * PCI configuration address + * + * Refer to Intel Quark SoC X1000 Datasheet, Section 5.5 for more details on + * PCI configuration register access. + */ +typedef union pci_config_addr { + struct { + /** Register/offset number. Least-significant two bits should be zero. */ + uint32_t reg_off : 8; + uint32_t func : 3; /**< Function number */ + uint32_t dev : 5; /**< Device number */ + uint32_t bus : 8; /**< Bus number */ + uint32_t : 7; + /** Must be set to perform PCI configuration access. */ + uint32_t en_mapping : 1; + }; + uint32_t raw; +} pci_config_addr_t; + +uint32_t pci_config_read(pci_config_addr_t addr); +void pci_config_write(pci_config_addr_t addr, uint32_t data); +void pci_command_enable(pci_config_addr_t addr, uint32_t flags); + +typedef dom_client_data_t pci_driver_t; + +void pci_init(pci_driver_t ATTR_KERN_ADDR_SPACE *c_this, + pci_config_addr_t pci_addr, + size_t mmio_sz, + uintptr_t meta, + size_t meta_sz); +void pci_irq_agent_set_pirq(IRQAGENT agent, INTR_PIN pin, PIRQ pirq); +void pci_pirq_set_irq(PIRQ pirq, uint8_t irq, uint8_t route_to_legacy); +void pci_root_complex_init(void); +void pci_root_complex_lock(void); + +#define PCI_MMIO_READL(c_this, dest, reg_addr) \ + MMIO_READL(dest, \ + *((volatile uint32_t ATTR_MMIO_ADDR_SPACE *) \ + (((uintptr_t)PROT_DOMAINS_MMIO(c_this)) + (reg_addr)))) +#define PCI_MMIO_WRITEL(c_this, reg_addr, src) \ + MMIO_WRITEL(*((volatile uint32_t ATTR_MMIO_ADDR_SPACE *) \ + (((uintptr_t)PROT_DOMAINS_MMIO(c_this)) + (reg_addr))), \ + src) + +#endif /* CPU_X86_DRIVERS_LEGACY_PC_PCI_H_ */ diff --git a/cpu/x86/drivers/legacy_pc/pic.c b/cpu/x86/drivers/legacy_pc/pic.c new file mode 100644 index 000000000..1acb351d1 --- /dev/null +++ b/cpu/x86/drivers/legacy_pc/pic.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "drivers/legacy_pc/pic.h" + +#define PIC_ACK 0x20 + +void +pic_unmask_irq(unsigned int num) +{ + uint16_t port; + uint8_t bitmap; + + if(num <= 7) { + port = PIC1_DATA_PORT; + } else { + port = PIC2_DATA_PORT; + num -= 8; + } + + bitmap = inb(port); + outb(port, bitmap & ~BIT(num)); +} +/*---------------------------------------------------------------------------*/ +void +pic_eoi(unsigned int irq) +{ + if(irq >= 8) { + outb(PIC2_CMD_PORT, PIC_ACK); + } + + outb(PIC1_CMD_PORT, PIC_ACK); +} diff --git a/cpu/x86/drivers/legacy_pc/pic.h b/cpu/x86/drivers/legacy_pc/pic.h new file mode 100644 index 000000000..d39942438 --- /dev/null +++ b/cpu/x86/drivers/legacy_pc/pic.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef PIC_H +#define PIC_H + +#include "helpers.h" + +#define PIC1_CMD_PORT 0x20 +#define PIC1_DATA_PORT 0x21 +#define PIC2_CMD_PORT 0xA0 +#define PIC2_DATA_PORT 0xA1 +#define PIC1_OFFSET 0x20 +#define PIC2_OFFSET PIC1_OFFSET + 8 + +/* + * Returns the actual interrupt number of a given IRQ, + * no matter which PIC it is part of. + */ +#define PIC_INT(a) (a + PIC1_OFFSET) + +void pic_unmask_irq(unsigned int num); + +/* This function initializes the daisy-chained Master and Slave 8259 PICs. + * It is only called once, so let's give the compiler the option to inline it. + * For more information about the ICWs, please refer to http://stanislavs.org/helppc/8259.html. + */ +static inline void +pic_init(void) +{ + /* ICW1: Initialization. */ + outb(PIC1_CMD_PORT, 0x11); + outb(PIC2_CMD_PORT, 0x11); + + /* ICW2: Remap IRQs by setting an IDT Offset for each PIC. */ + outb(PIC1_DATA_PORT, PIC1_OFFSET); + outb(PIC2_DATA_PORT, PIC2_OFFSET); + + /* ICW3: Setup Slave to Master's IRQ2. */ + outb(PIC1_DATA_PORT, 0x04); + outb(PIC2_DATA_PORT, 0x02); + + /* ICW4: Environment setup. Set PIC1 as master and PIC2 as slave. */ + outb(PIC1_DATA_PORT, 0x01); + outb(PIC2_DATA_PORT, 0x01); + + /* Set the IMR register, masking all hardware interrupts but IRQ 2. + * We will have to unmask each IRQ when registering them. */ + outb(PIC1_DATA_PORT, 0xfb); + outb(PIC2_DATA_PORT, 0xff); +} + +/* + * This function sends an end-of-interrupt (EOI) to the correct PIC according + * to the IRQ line number. + */ +void pic_eoi(unsigned int irq); + +#endif /* PIC_H */ diff --git a/cpu/x86/drivers/legacy_pc/pit.c b/cpu/x86/drivers/legacy_pc/pit.c new file mode 100644 index 000000000..3d7b2816d --- /dev/null +++ b/cpu/x86/drivers/legacy_pc/pit.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include + +#include "drivers/legacy_pc/pic.h" +#include "drivers/legacy_pc/pit.h" +#include "helpers.h" +#include "interrupt.h" + +/* PCs usually provide an 8254 PIT chip with maximum clock of 1.193182 MHz. */ +#define PIT_CONTROL_PORT 0x43 +#define PIT_COUNTER0_PORT 0x40 +#define PIT_CLOCK_FREQUENCY 1193182 +#define PIT_IRQ 0 +#define PIT_INT PIC_INT(PIT_IRQ) + +static pit_int_callback interrupt_cb; + +static void +pit_int_handler(void) +{ + interrupt_cb(); + + pic_eoi(PIT_IRQ); +} +/*---------------------------------------------------------------------------*/ +void +pit_init(uint32_t ticks_rate, pit_int_callback cb) +{ + SET_INTERRUPT_HANDLER(PIT_INT, 0, pit_int_handler); + + interrupt_cb = cb; + + /* Calculate the 16bit divisor that can provide the chosen clock tick rate + * (CLOCK_CONF_SECOND in contiki-conf.h). For reference --> tick rate = clock frequency / divisor. + * If we provide an odd divisor to the Square Wave generator (Mode 3) of + * the Counter0, the duty cycle won't be exactly 50%, so we always round + * it to nearest even integer. + */ + uint16_t divisor = rint(PIT_CLOCK_FREQUENCY / ticks_rate); + + /* Setup Control register flags in a didactic way. */ + uint8_t flags = 0x30; /* Set bits 7:6 to select Counter0 and 5:4 to select "write 7:0 bits first". */ + flags |= 0x6; /* Set bits 3:1 to Mode 3 and bit 0 to BCD off. */ + + outb(PIT_CONTROL_PORT, flags); + + outb(PIT_COUNTER0_PORT, divisor & 0xFF); /* Write least significant bytes first. */ + outb(PIT_COUNTER0_PORT, (divisor >> 8) & 0xFF); + + pic_unmask_irq(PIT_IRQ); +} diff --git a/cpu/x86/drivers/legacy_pc/pit.h b/cpu/x86/drivers/legacy_pc/pit.h new file mode 100644 index 000000000..0a16b8929 --- /dev/null +++ b/cpu/x86/drivers/legacy_pc/pit.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef PIT_H +#define PIT_H + +#include + +typedef void (*pit_int_callback)(void); + +/** + * Initializes the 8254 Programmable Interrupt Timer chip (Counter 0 only). + * The PIT Interrupt callback is implemented by the driver's users. It is + * called from interrupt context, so it has to return as soon as possible. + */ +void pit_init(uint32_t ticks_rate, pit_int_callback c); + +#endif /* PIT_H */ diff --git a/cpu/x86/drivers/legacy_pc/rtc.c b/cpu/x86/drivers/legacy_pc/rtc.c new file mode 100644 index 000000000..cf059315b --- /dev/null +++ b/cpu/x86/drivers/legacy_pc/rtc.c @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "drivers/legacy_pc/rtc.h" +#include "drivers/legacy_pc/pic.h" +#include "drivers/legacy_pc/nmi.h" +#include "helpers.h" +#include "interrupt.h" + +#define RTC_INDEX_REGISTER 0x70 +#define RTC_TARGET_REGISTER 0x71 +#define RTC_IRQ 8 +#define RTC_INT PIC_INT(RTC_IRQ) + +static void (*user_callback)(void); + +static void +rtc_handler() +{ + user_callback(); + + /* Clear Register C otherwise interrupts will not happen again. + * Register C is automatically cleared when it is read so we do + * a dummy read to clear it. + */ + outb(RTC_INDEX_REGISTER, 0x0C); + inb(RTC_TARGET_REGISTER); + + /* Issue the End of Interrupt to PIC */ + pic_eoi(RTC_IRQ); +} +/*---------------------------------------------------------------------------*/ +/* Initialize the Real Time Clock. + * @frequency: RTC has very specific values for frequency. They are: 2, 4, 8, + * 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, and 8192 Hz. + * value otherwise it will not work properly. + * @callback: This callback is called every time the RTC IRQ is raised. + * It is executed in interrupt context. + */ +void +rtc_init(rtc_frequency_t frequency, void (*callback)(void)) +{ + uint8_t reg_a, reg_b; + + user_callback = callback; + + SET_INTERRUPT_HANDLER(RTC_INT, 0, rtc_handler); + + nmi_disable(); + + /* Select interrupt period to 7.8125 ms */ + outb(RTC_INDEX_REGISTER, 0x8A); + reg_a = inb(RTC_TARGET_REGISTER); + reg_a &= 0xF0; + reg_a |= frequency; + outb(RTC_INDEX_REGISTER, 0x8A); + outb(RTC_TARGET_REGISTER, reg_a); + + /* Enable periodic interrupt */ + outb(RTC_INDEX_REGISTER, 0x8B); + reg_b = inb(RTC_TARGET_REGISTER); + outb(RTC_INDEX_REGISTER, 0x8B); + outb(RTC_TARGET_REGISTER, reg_b | BIT(6)); + + nmi_enable(); + + pic_unmask_irq(RTC_IRQ); +} diff --git a/cpu/x86/drivers/legacy_pc/rtc.h b/cpu/x86/drivers/legacy_pc/rtc.h new file mode 100644 index 000000000..257accb43 --- /dev/null +++ b/cpu/x86/drivers/legacy_pc/rtc.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef RTC_H +#define RTC_H + +typedef enum { + RTC_8192_HZ = 2, + RTC_4096_HZ = 3, + RTC_2048_HZ = 4, + RTC_1024_HZ = 5, + RTC_512_HZ = 6, + RTC_256_HZ = 7, + RTC_128_HZ = 8, + RTC_64_HZ = 9, + RTC_32_HZ = 10, + RTC_16_HZ = 11, + RTC_8_HZ = 12, + RTC_4_HZ = 13, + RTC_2_HZ = 14, +} rtc_frequency_t; + +void rtc_init(rtc_frequency_t frequency, void (*callback)(void)); + +#endif /* RTC_H */ diff --git a/cpu/x86/drivers/legacy_pc/shared-isr.c b/cpu/x86/drivers/legacy_pc/shared-isr.c new file mode 100644 index 000000000..f04f6aba8 --- /dev/null +++ b/cpu/x86/drivers/legacy_pc/shared-isr.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include +#include "idt.h" +#include "interrupt.h" +#include "pic.h" +#include "shared-isr.h" + +/* Defined in linker script */ +extern shared_isr_client_t _sdata_shared_isr, _edata_shared_isr; + +static void __attribute__((used)) +shared_handler(void) +{ + shared_isr_client_t *client; + for(client = &_sdata_shared_isr; client < &_edata_shared_isr; client++) { + if(client->handler()) { + pic_eoi(client->irq); + return; + } + } +} + +/** + * \brief Initialize shared ISR by iterating through all of its clients and + * configuring their interrupts to route to the shared ISR. + */ +void +shared_isr_init(void) +{ + shared_isr_client_t *client = &_sdata_shared_isr; + shared_isr_client_t *consistency_check_client; + bool prev_conf; + + void shared_isr_stub(void); + __asm__ __volatile__ ( + ISR_STUB("shared_isr_stub", 0, "shared_handler", 0) + : + ); + + while(client < &_edata_shared_isr) { + consistency_check_client = &_sdata_shared_isr; + + prev_conf = false; + + while(consistency_check_client < client) { + if((client->irq == consistency_check_client->irq) || + (client->pin == consistency_check_client->pin) || + (client->pirq == consistency_check_client->pirq)) { + + prev_conf = true; + + /* This interrupt was previously configured. */ + break; + } + + consistency_check_client++; + } + + if(prev_conf) { + /* The requested configurations for each IRQ must be consistent. */ + assert((client->irq == consistency_check_client->irq) && + (client->agent == consistency_check_client->agent) && + (client->pin == consistency_check_client->pin) && + (client->pirq == consistency_check_client->pirq)); + } else { + idt_set_intr_gate_desc(PIC_INT(client->irq), (uint32_t)shared_isr_stub, + GDT_SEL_CODE_INT, PRIV_LVL_INT); + + pci_irq_agent_set_pirq(client->agent, client->pin, client->pirq); + + pci_pirq_set_irq(client->pirq, client->irq, 1); + + pic_unmask_irq(client->irq); + } + + client++; + } +} diff --git a/cpu/x86/drivers/legacy_pc/shared-isr.h b/cpu/x86/drivers/legacy_pc/shared-isr.h new file mode 100644 index 000000000..e8a92e442 --- /dev/null +++ b/cpu/x86/drivers/legacy_pc/shared-isr.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_DRIVERS_LEGACY_PC_SHARED_ISR_H_ +#define CPU_X86_DRIVERS_LEGACY_PC_SHARED_ISR_H_ + +#include +#include "pci.h" + +/** + * The handler function should return true if and only if it handled the + * interrupt. + */ +typedef bool (*shared_isr_handler_t)(void); + +typedef struct shared_isr_client { + uint8_t irq; + IRQAGENT agent; + INTR_PIN pin; + PIRQ pirq; + shared_isr_handler_t handler; +} shared_isr_client_t; + +/* Unlike a non-shared interrupt handler function, an individual interrupt + * handler for a shared interrupt must not issue an EOI. The EOI is issued by + * the shared-isr subsystem. + */ +#define DEFINE_SHARED_IRQ(irq_, agent_, pin_, pirq_, handler_) \ +static struct shared_isr_client \ + __attribute__((used, section(".shared_isr_data"))) _shared_irq_##irq_ = { \ + .irq = irq_, \ + .agent = agent_, \ + .pin = pin_, \ + .pirq = pirq_, \ + .handler = handler_ \ +} + +void shared_isr_init(void); + +#endif /* CPU_X86_DRIVERS_LEGACY_PC_SHARED_ISR_H_ */ diff --git a/cpu/x86/drivers/legacy_pc/uart-16x50.c b/cpu/x86/drivers/legacy_pc/uart-16x50.c new file mode 100644 index 000000000..d17e61498 --- /dev/null +++ b/cpu/x86/drivers/legacy_pc/uart-16x50.c @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include +#include "helpers.h" +#include "paging.h" +#include "prot-domains.h" +#include "syscalls.h" +#include "uart-16x50.h" + +/* Refer to Intel Quark SoC X1000 Datasheet, Chapter 18 for more details on + * UART operation. + */ + +/* Divisor Latch Access Bit (DLAB) mask for Line Control Register (LCR). + * + * When bit is set, enables access to divisor registers to set baud rate. When + * clear, enables access to other registers mapped to the same addresses as the + * divisor registers. + */ +#define UART_LCR_7_DLAB BIT(7) +/* Setting for LCR that configures the UART to operate with no parity, 1 stop + * bit, and eight bits per character. + */ +#define UART_LCR_8BITS 0x03 + +/* FIFO Control Register (FCR) bitmasks */ +#define UART_FCR_0_FIFOE BIT(0) /*< enable FIFOs */ +#define UART_FCR_1_RFIFOR BIT(1) /*< reset RX FIFO */ +#define UART_FCR_2_XFIFOR BIT(2) /*< reset TX FIFO */ + +/* Line Status Register (LSR) Transmit Holding Register Empty bitmask to check + * whether the Transmit Holding Register (THR) or TX FIFO is empty. + */ +#define UART_LSR_5_THRE BIT(5) + +/* MMIO registers for UART */ +typedef struct uart_16x50_regs { + volatile uint32_t rbr_thr_dll, ier_dlh, iir_fcr, lcr; + volatile uint32_t mcr, lsr, msr, scr, usr, htx, dmasa; +} uart_16x50_regs_t; + +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING +/* When paging-based protection domains are in use, at least one page of memory + * must be reserved to facilitate access to the MMIO region, since that is the + * smallest unit of memory that can be managed with paging: + */ +#define UART_MMIO_SZ MIN_PAGE_SIZE +#else +/* Multi-segment protection domain implementations can control memory with + * byte granularity. Thus, only the registers defined in the uart_16x50_regs + * structure are included in the MMIO region allocated for this protection + * domain: + */ +#define UART_MMIO_SZ sizeof(uart_16x50_regs_t) +#endif + +void uart_16x50_setup(uart_16x50_driver_t c_this, uint16_t dl); + +/*---------------------------------------------------------------------------*/ +SYSCALLS_DEFINE(uart_16x50_setup, uart_16x50_driver_t c_this, uint16_t dl) +{ + uart_16x50_regs_t ATTR_MMIO_ADDR_SPACE *regs = + (uart_16x50_regs_t ATTR_MMIO_ADDR_SPACE *)PROT_DOMAINS_MMIO(c_this); + + prot_domains_enable_mmio(); + + /* Set the DLAB bit to enable access to divisor settings. */ + MMIO_WRITEL(regs->lcr, UART_LCR_7_DLAB); + + /* The divisor settings configure the baud rate, and may need to be defined + * on a per-device basis. + */ + MMIO_WRITEL(regs->rbr_thr_dll, dl & UINT8_MAX); + MMIO_WRITEL(regs->ier_dlh, dl >> 8); + + /* Clear the DLAB bit to enable access to other settings and configure other + * UART parameters. + */ + MMIO_WRITEL(regs->lcr, UART_LCR_8BITS); + + /* Enable the FIFOs. */ + MMIO_WRITEL(regs->iir_fcr, + UART_FCR_0_FIFOE | UART_FCR_1_RFIFOR | UART_FCR_2_XFIFOR); + + prot_domains_disable_mmio(); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Transmit a character through a UART. + * \param c_this Initialized structure representing the device. + * \param c Character to be transmitted. + * + * This procedure will block indefinitely until the UART is ready + * to accept the character to be transmitted. + */ +SYSCALLS_DEFINE(uart_16x50_tx, uart_16x50_driver_t c_this, uint8_t c) +{ + uint32_t ready; + uart_16x50_regs_t ATTR_MMIO_ADDR_SPACE *regs = + (uart_16x50_regs_t ATTR_MMIO_ADDR_SPACE *)PROT_DOMAINS_MMIO(c_this); + + prot_domains_enable_mmio(); + + /* Wait for space in TX FIFO. */ + do { + MMIO_READL(ready, regs->lsr); + } while((ready & UART_LSR_5_THRE) == 0); + + /* Add character to TX FIFO. */ + MMIO_WRITEL(regs->rbr_thr_dll, c); + + prot_domains_disable_mmio(); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize an MMIO-programmable 16X50 UART. + * \param c_this Structure that will be initialized to represent the device. + * \param pci_addr PCI address of device. + * \param dl Divisor setting to configure the baud rate. + */ +void +uart_16x50_init(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this, + pci_config_addr_t pci_addr, + uint16_t dl) +{ + uart_16x50_driver_t loc_c_this; + + /* This assumes that the UART had an MMIO range assigned to it by the + * firmware during boot. + */ + pci_init(c_this, pci_addr, UART_MMIO_SZ, 0, 0); + SYSCALLS_INIT(uart_16x50_setup); + SYSCALLS_AUTHZ(uart_16x50_setup, *c_this); + SYSCALLS_INIT(uart_16x50_tx); + SYSCALLS_AUTHZ(uart_16x50_tx, *c_this); + + prot_domains_copy_dcd(&loc_c_this, c_this); + + uart_16x50_setup(loc_c_this, dl); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/drivers/legacy_pc/uart-16x50.h b/cpu/x86/drivers/legacy_pc/uart-16x50.h new file mode 100644 index 000000000..4a038b948 --- /dev/null +++ b/cpu/x86/drivers/legacy_pc/uart-16x50.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_DRIVERS_LEGACY_PC_UART_16X50_H_ +#define CPU_X86_DRIVERS_LEGACY_PC_UART_16X50_H_ + +#include "pci.h" + +typedef pci_driver_t uart_16x50_driver_t; + +void uart_16x50_init(uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *c_this, + pci_config_addr_t pci_addr, + uint16_t dl); + +void uart_16x50_tx(uart_16x50_driver_t c_this, uint8_t c); + +#endif /* CPU_X86_DRIVERS_LEGACY_PC_UART_16X50_H_ */ diff --git a/cpu/x86/drivers/quarkX1000/eth.c b/cpu/x86/drivers/quarkX1000/eth.c new file mode 100644 index 000000000..88782ebc2 --- /dev/null +++ b/cpu/x86/drivers/quarkX1000/eth.c @@ -0,0 +1,465 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include +#include +#include +#include "contiki-net.h" +#include "dma.h" +#include "eth.h" +#include "helpers.h" +#include "syscalls.h" +#include "net/ip/uip.h" +#include "pci.h" + +typedef pci_driver_t quarkX1000_eth_driver_t; + +/* Refer to Intel Quark SoC X1000 Datasheet, Chapter 15 for more details on + * Ethernet device operation. + * + * This driver puts the Ethernet device into a very simple and space-efficient + * mode of operation. It only allocates a single packet descriptor for each of + * the transmit and receive directions, computes checksums on the CPU, and + * enables store-and-forward mode for both transmit and receive directions. + */ + +/* Transmit descriptor */ +typedef struct quarkX1000_eth_tx_desc { + /* First word of transmit descriptor */ + union { + struct { + /* Only valid in half-duplex mode. */ + uint32_t deferred_bit : 1; + uint32_t err_underflow : 1; + uint32_t err_excess_defer : 1; + uint32_t coll_cnt_slot_num : 4; + uint32_t vlan_frm : 1; + uint32_t err_excess_coll : 1; + uint32_t err_late_coll : 1; + uint32_t err_no_carrier : 1; + uint32_t err_carrier_loss : 1; + uint32_t err_ip_payload : 1; + uint32_t err_frm_flushed : 1; + uint32_t err_jabber_tout : 1; + /* OR of all other error bits. */ + uint32_t err_summary : 1; + uint32_t err_ip_hdr : 1; + uint32_t tx_timestamp_stat : 1; + uint32_t vlan_ins_ctrl : 2; + uint32_t addr2_chained : 1; + uint32_t tx_end_of_ring : 1; + uint32_t chksum_ins_ctrl : 2; + uint32_t replace_crc : 1; + uint32_t tx_timestamp_en : 1; + uint32_t dis_pad : 1; + uint32_t dis_crc : 1; + uint32_t first_seg_in_frm : 1; + uint32_t last_seg_in_frm : 1; + uint32_t intr_on_complete : 1; + /* When set, descriptor is owned by DMA. */ + uint32_t own : 1; + }; + uint32_t tdes0; + }; + /* Second word of transmit descriptor */ + union { + struct { + uint32_t tx_buf1_sz : 13; + uint32_t : 3; + uint32_t tx_buf2_sz : 13; + uint32_t src_addr_ins_ctrl : 3; + }; + uint32_t tdes1; + }; + /* Pointer to frame data buffer */ + uint8_t *buf1_ptr; + /* Unused, since this driver initializes only a single descriptor for each + * direction. + */ + uint8_t *buf2_ptr; +} quarkX1000_eth_tx_desc_t; + +/* Transmit descriptor */ +typedef struct quarkX1000_eth_rx_desc { + /* First word of receive descriptor */ + union { + struct { + uint32_t ext_stat : 1; + uint32_t err_crc : 1; + uint32_t err_dribble_bit : 1; + uint32_t err_rx_mii : 1; + uint32_t err_rx_wdt : 1; + uint32_t frm_type : 1; + uint32_t err_late_coll : 1; + uint32_t giant_frm : 1; + uint32_t last_desc : 1; + uint32_t first_desc : 1; + uint32_t vlan_tag : 1; + uint32_t err_overflow : 1; + uint32_t length_err : 1; + uint32_t s_addr_filt_fail : 1; + uint32_t err_desc : 1; + uint32_t err_summary : 1; + uint32_t frm_len : 14; + uint32_t d_addr_filt_fail : 1; + uint32_t own : 1; + }; + uint32_t rdes0; + }; + /* Second word of receive descriptor */ + union { + struct { + uint32_t rx_buf1_sz : 13; + uint32_t : 1; + uint32_t addr2_chained : 1; + uint32_t rx_end_of_ring : 1; + uint32_t rx_buf2_sz : 13; + uint32_t : 2; + uint32_t dis_int_compl : 1; + }; + uint32_t rdes1; + }; + /* Pointer to frame data buffer */ + uint8_t *buf1_ptr; + /* Unused, since this driver initializes only a single descriptor for each + * direction. + */ + uint8_t *buf2_ptr; +} quarkX1000_eth_rx_desc_t; + +/* Driver metadata associated with each Ethernet device */ +typedef struct quarkX1000_eth_meta { + /* Transmit descriptor */ + volatile quarkX1000_eth_tx_desc_t tx_desc; + /* Transmit DMA packet buffer */ + volatile uint8_t tx_buf[ALIGN(UIP_BUFSIZE, 4)]; + /* Receive descriptor */ + volatile quarkX1000_eth_rx_desc_t rx_desc; + /* Receive DMA packet buffer */ + volatile uint8_t rx_buf[ALIGN(UIP_BUFSIZE, 4)]; + +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING + /* Domain-defined metadata must fill an even number of pages, since that is + * the minimum granularity of access control supported by paging. However, + * using the "aligned(4096)" attribute causes the alignment of the kernel + * data section to increase, which causes problems when generating UEFI + * binaries, as is described in the linker script. Thus, it is necessary + * to manually pad the structure to fill a page. This only works if the + * sizes of the actual fields of the structure are collectively less than a + * page. + */ + uint8_t pad[MIN_PAGE_SIZE - + (sizeof(quarkX1000_eth_tx_desc_t) + + ALIGN(UIP_BUFSIZE, 4) + + sizeof(quarkX1000_eth_rx_desc_t) + + ALIGN(UIP_BUFSIZE, 4))]; +#endif +} __attribute__((packed)) quarkX1000_eth_meta_t; + +#define LOG_PFX "quarkX1000_eth: " + +#define MMIO_SZ 0x2000 + +#define MAC_CONF_14_RMII_100M BIT(14) +#define MAC_CONF_11_DUPLEX BIT(11) +#define MAC_CONF_3_TX_EN BIT(3) +#define MAC_CONF_2_RX_EN BIT(2) + +#define OP_MODE_25_RX_STORE_N_FORWARD BIT(25) +#define OP_MODE_21_TX_STORE_N_FORWARD BIT(21) +#define OP_MODE_13_START_TX BIT(13) +#define OP_MODE_1_START_RX BIT(1) + +#define REG_ADDR_MAC_CONF 0x0000 +#define REG_ADDR_MACADDR_HI 0x0040 +#define REG_ADDR_MACADDR_LO 0x0044 +#define REG_ADDR_TX_POLL_DEMAND 0x1004 +#define REG_ADDR_RX_POLL_DEMAND 0x1008 +#define REG_ADDR_RX_DESC_LIST 0x100C +#define REG_ADDR_TX_DESC_LIST 0x1010 +#define REG_ADDR_DMA_OPERATION 0x1018 + +PROT_DOMAINS_ALLOC(quarkX1000_eth_driver_t, drv); +static quarkX1000_eth_meta_t ATTR_BSS_DMA meta; + +void quarkX1000_eth_setup(uintptr_t meta_phys_base); + +/*---------------------------------------------------------------------------*/ +SYSCALLS_DEFINE_SINGLETON(quarkX1000_eth_setup, drv, uintptr_t meta_phys_base) +{ + uip_eth_addr mac_addr; + uint32_t mac_tmp1, mac_tmp2; + quarkX1000_eth_rx_desc_t rx_desc; + quarkX1000_eth_tx_desc_t tx_desc; + quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *loc_meta = + (quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *)PROT_DOMAINS_META(drv); + + prot_domains_enable_mmio(); + + /* Read the MAC address from the device. */ + PCI_MMIO_READL(drv, mac_tmp1, REG_ADDR_MACADDR_HI); + PCI_MMIO_READL(drv, mac_tmp2, REG_ADDR_MACADDR_LO); + + prot_domains_disable_mmio(); + + /* Convert the data read from the device into the format expected by + * Contiki. + */ + mac_addr.addr[5] = (uint8_t)(mac_tmp1 >> 8); + mac_addr.addr[4] = (uint8_t)mac_tmp1; + mac_addr.addr[3] = (uint8_t)(mac_tmp2 >> 24); + mac_addr.addr[2] = (uint8_t)(mac_tmp2 >> 16); + mac_addr.addr[1] = (uint8_t)(mac_tmp2 >> 8); + mac_addr.addr[0] = (uint8_t)mac_tmp2; + + printf(LOG_PFX "MAC address = %02x:%02x:%02x:%02x:%02x:%02x.\n", + mac_addr.addr[0], + mac_addr.addr[1], + mac_addr.addr[2], + mac_addr.addr[3], + mac_addr.addr[4], + mac_addr.addr[5] + ); + + uip_setethaddr(mac_addr); + + /* Initialize transmit descriptor. */ + tx_desc.tdes0 = 0; + tx_desc.tdes1 = 0; + + tx_desc.tx_end_of_ring = 1; + tx_desc.first_seg_in_frm = 1; + tx_desc.last_seg_in_frm = 1; + tx_desc.tx_end_of_ring = 1; + + META_WRITEL(loc_meta->tx_desc.tdes0, tx_desc.tdes0); + META_WRITEL(loc_meta->tx_desc.tdes1, tx_desc.tdes1); + META_WRITEL(loc_meta->tx_desc.buf1_ptr, + (uint8_t *)PROT_DOMAINS_META_OFF_TO_PHYS( + (uintptr_t)&loc_meta->tx_buf, meta_phys_base)); + META_WRITEL(loc_meta->tx_desc.buf2_ptr, 0); + + /* Initialize receive descriptor. */ + rx_desc.rdes0 = 0; + rx_desc.rdes1 = 0; + + rx_desc.own = 1; + rx_desc.first_desc = 1; + rx_desc.last_desc = 1; + rx_desc.rx_buf1_sz = UIP_BUFSIZE; + rx_desc.rx_end_of_ring = 1; + + META_WRITEL(loc_meta->rx_desc.rdes0, rx_desc.rdes0); + META_WRITEL(loc_meta->rx_desc.rdes1, rx_desc.rdes1); + META_WRITEL(loc_meta->rx_desc.buf1_ptr, + (uint8_t *)PROT_DOMAINS_META_OFF_TO_PHYS( + (uintptr_t)&loc_meta->rx_buf, meta_phys_base)); + META_WRITEL(loc_meta->rx_desc.buf2_ptr, 0); + + prot_domains_enable_mmio(); + + /* Install transmit and receive descriptors. */ + PCI_MMIO_WRITEL(drv, REG_ADDR_RX_DESC_LIST, + PROT_DOMAINS_META_OFF_TO_PHYS( + (uintptr_t)&loc_meta->rx_desc, meta_phys_base)); + PCI_MMIO_WRITEL(drv, REG_ADDR_TX_DESC_LIST, + PROT_DOMAINS_META_OFF_TO_PHYS( + (uintptr_t)&loc_meta->tx_desc, meta_phys_base)); + + PCI_MMIO_WRITEL(drv, REG_ADDR_MAC_CONF, + /* Set the RMII speed to 100Mbps */ + MAC_CONF_14_RMII_100M | + /* Enable full-duplex mode */ + MAC_CONF_11_DUPLEX | + /* Enable transmitter */ + MAC_CONF_3_TX_EN | + /* Enable receiver */ + MAC_CONF_2_RX_EN); + + PCI_MMIO_WRITEL(drv, REG_ADDR_DMA_OPERATION, + /* Enable receive store-and-forward mode for simplicity. */ + OP_MODE_25_RX_STORE_N_FORWARD | + /* Enable transmit store-and-forward mode for simplicity. */ + OP_MODE_21_TX_STORE_N_FORWARD | + /* Place the transmitter state machine in the Running + state. */ + OP_MODE_13_START_TX | + /* Place the receiver state machine in the Running state. */ + OP_MODE_1_START_RX); + + prot_domains_disable_mmio(); + + printf(LOG_PFX "Enabled 100M full-duplex mode.\n"); +} + +/*---------------------------------------------------------------------------*/ +/** + * \brief Poll for a received Ethernet frame. + * \param frame_len Will be set to the size of the received Ethernet frame or + * zero if no frame is available. + * + * If a frame is received, this procedure copies it into the + * global uip_buf buffer. + */ +SYSCALLS_DEFINE_SINGLETON(quarkX1000_eth_poll, drv, uint16_t * frame_len) +{ + uint16_t *loc_frame_len; + uint16_t frm_len = 0; + quarkX1000_eth_rx_desc_t tmp_desc; + quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *loc_meta = + (quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *)PROT_DOMAINS_META(drv); + + PROT_DOMAINS_VALIDATE_PTR(loc_frame_len, frame_len, sizeof(*frame_len)); + + META_READL(tmp_desc.rdes0, loc_meta->rx_desc.rdes0); + + /* Check whether the RX descriptor is still owned by the device. If not, + * process the received frame or an error that may have occurred. + */ + if(tmp_desc.own == 0) { + META_READL(tmp_desc.rdes1, loc_meta->rx_desc.rdes1); + if(tmp_desc.err_summary) { + fprintf(stderr, + LOG_PFX "Error receiving frame: RDES0 = %08x, RDES1 = %08x.\n", + tmp_desc.rdes0, tmp_desc.rdes1); + assert(0); + } + + frm_len = tmp_desc.frm_len; + assert(frm_len <= UIP_BUFSIZE); + MEMCPY_FROM_META(uip_buf, loc_meta->rx_buf, frm_len); + + /* Return ownership of the RX descriptor to the device. */ + tmp_desc.own = 1; + + META_WRITEL(loc_meta->rx_desc.rdes0, tmp_desc.rdes0); + + prot_domains_enable_mmio(); + + /* Request that the device check for an available RX descriptor, since + * ownership of the descriptor was just transferred to the device. + */ + PCI_MMIO_WRITEL(drv, REG_ADDR_RX_POLL_DEMAND, 1); + + prot_domains_disable_mmio(); + } + + *loc_frame_len = frm_len; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Transmit the current Ethernet frame. + * + * This procedure will block indefinitely until the Ethernet device is + * ready to accept a new outgoing frame. It then copies the current + * Ethernet frame from the global uip_buf buffer to the device DMA + * buffer and signals to the device that a new frame is available to be + * transmitted. + */ +SYSCALLS_DEFINE_SINGLETON(quarkX1000_eth_send, drv) +{ + quarkX1000_eth_tx_desc_t tmp_desc; + quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *loc_meta = + (quarkX1000_eth_meta_t ATTR_META_ADDR_SPACE *)PROT_DOMAINS_META(drv); + + /* Wait until the TX descriptor is no longer owned by the device. */ + do { + META_READL(tmp_desc.tdes0, loc_meta->tx_desc.tdes0); + } while(tmp_desc.own == 1); + + META_READL(tmp_desc.tdes1, loc_meta->tx_desc.tdes1); + + /* Check whether an error occurred transmitting the previous frame. */ + if(tmp_desc.err_summary) { + fprintf(stderr, + LOG_PFX "Error transmitting frame: TDES0 = %08x, TDES1 = %08x.\n", + tmp_desc.tdes0, tmp_desc.tdes1); + assert(0); + } + + /* Transmit the next frame. */ + assert(uip_len <= UIP_BUFSIZE); + MEMCPY_TO_META(loc_meta->tx_buf, uip_buf, uip_len); + + tmp_desc.tx_buf1_sz = uip_len; + + META_WRITEL(loc_meta->tx_desc.tdes1, tmp_desc.tdes1); + + tmp_desc.own = 1; + + META_WRITEL(loc_meta->tx_desc.tdes0, tmp_desc.tdes0); + + prot_domains_enable_mmio(); + + /* Request that the device check for an available TX descriptor, since + * ownership of the descriptor was just transferred to the device. + */ + PCI_MMIO_WRITEL(drv, REG_ADDR_TX_POLL_DEMAND, 1); + + prot_domains_disable_mmio(); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize the first Quark X1000 Ethernet MAC. + * + * This procedure assumes that an MMIO range for the device was + * previously assigned, e.g. by firmware. + */ +void +quarkX1000_eth_init(void) +{ + pci_config_addr_t pci_addr = { .raw = 0 }; + + /* PCI address from section 15.4 of Intel Quark SoC X1000 Datasheet. */ + + pci_addr.dev = 20; + pci_addr.func = 6; + + /* Activate MMIO and DMA access. */ + pci_command_enable(pci_addr, PCI_CMD_2_BUS_MST_EN | PCI_CMD_1_MEM_SPACE_EN); + + printf(LOG_PFX "Activated MMIO and DMA access.\n"); + + pci_addr.reg_off = PCI_CONFIG_REG_BAR0; + + PROT_DOMAINS_INIT_ID(drv); + /* Configure the device MMIO range and initialize the driver structure. */ + pci_init(&drv, pci_addr, MMIO_SZ, + (uintptr_t)&meta, sizeof(quarkX1000_eth_meta_t)); + SYSCALLS_INIT(quarkX1000_eth_setup); + SYSCALLS_AUTHZ(quarkX1000_eth_setup, drv); + SYSCALLS_INIT(quarkX1000_eth_poll); + SYSCALLS_AUTHZ(quarkX1000_eth_poll, drv); + SYSCALLS_INIT(quarkX1000_eth_send); + SYSCALLS_AUTHZ(quarkX1000_eth_send, drv); + + quarkX1000_eth_setup(prot_domains_lookup_meta_phys_base(&drv)); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/drivers/quarkX1000/eth.h b/cpu/x86/drivers/quarkX1000/eth.h new file mode 100644 index 000000000..e94267466 --- /dev/null +++ b/cpu/x86/drivers/quarkX1000/eth.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_DRIVERS_QUARKX1000_ETH_H_ +#define CPU_X86_DRIVERS_QUARKX1000_ETH_H_ + +#include + +void quarkX1000_eth_init(void); +void quarkX1000_eth_poll(uint16_t *frame_len); +void quarkX1000_eth_send(void); + +#endif /* CPU_X86_DRIVERS_QUARKX1000_ETH_H_ */ diff --git a/cpu/x86/drivers/quarkX1000/gpio.c b/cpu/x86/drivers/quarkX1000/gpio.c new file mode 100644 index 000000000..ba825c090 --- /dev/null +++ b/cpu/x86/drivers/quarkX1000/gpio.c @@ -0,0 +1,292 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "gpio.h" + +#include +#include "helpers.h" +#include "paging.h" +#include "shared-isr.h" +#include "syscalls.h" + +/* GPIO Controler Registers */ +#define SWPORTA_DR 0x00 +#define SWPORTA_DDR 0x04 +#define INTEN 0x30 +#define INTMASK 0x34 +#define INTTYPE_LEVEL 0x38 +#define INT_POLARITY 0x3c +#define INTSTATUS 0x40 +#define RAW_INTSTATUS 0x44 +#define DEBOUNCE 0x48 +#define PORTA_EOI 0x4c +#define EXT_PORTA 0x50 +#define LS_SYNC 0x60 + +#define PINS 8 + +#define GPIO_IRQ 9 + +#define HIGHEST_REG LS_SYNC + +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING +#define MMIO_SZ MIN_PAGE_SIZE +#else +#define MMIO_SZ (HIGHEST_REG + 4) +#endif + +PROT_DOMAINS_ALLOC(pci_driver_t, drv); + +struct gpio_internal_data { + quarkX1000_gpio_callback callback; +}; + +static struct gpio_internal_data data; + +void quarkX1000_gpio_mmin(uint32_t offset, uint32_t *res); +SYSCALLS_DEFINE_SINGLETON(quarkX1000_gpio_mmin, drv, + uint32_t offset, uint32_t *res) +{ + uint32_t *loc_res; + + PROT_DOMAINS_VALIDATE_PTR(loc_res, res, sizeof(*res)); + if(HIGHEST_REG < offset) { + halt(); + } + + prot_domains_enable_mmio(); + PCI_MMIO_READL(drv, *loc_res, offset); + prot_domains_disable_mmio(); +} + +static inline uint32_t +read(uint32_t offset) +{ + uint32_t res; + quarkX1000_gpio_mmin(offset, &res); + return res; +} + +void quarkX1000_gpio_mmout(uint32_t offset, uint32_t val); +SYSCALLS_DEFINE_SINGLETON(quarkX1000_gpio_mmout, drv, + uint32_t offset, uint32_t val) +{ + if(HIGHEST_REG < offset) { + halt(); + } + + prot_domains_enable_mmio(); + PCI_MMIO_WRITEL(drv, offset, val); + prot_domains_disable_mmio(); +} + +static inline void +write(uint32_t offset, uint32_t val) +{ + quarkX1000_gpio_mmout(offset, val); +} + +/* value must be 0x0 or 0x1 */ +static void +set_bit(uint32_t offset, uint32_t bit, uint32_t value) +{ + uint32_t reg; + + reg = read(offset); + + reg &= ~BIT(bit); + reg |= value << bit; + + write(offset, reg); +} + +static bool +gpio_isr(void) +{ + uint32_t int_status; + + int_status = read(INTSTATUS); + + if(int_status == 0) { + return false; + } + + if (data.callback) + data.callback(int_status); + + write(PORTA_EOI, -1); + + return true; +} + +static void +gpio_interrupt_config(uint8_t pin, int flags) +{ + /* set as input */ + set_bit(SWPORTA_DDR, pin, 0); + + /* set interrupt enabled */ + set_bit(INTEN, pin, 1); + + /* unmask interrupt */ + set_bit(INTMASK, pin, 0); + + /* set active high/low */ + set_bit(INT_POLARITY, pin, !!(flags & QUARKX1000_GPIO_ACTIVE_HIGH)); + + /* set level/edge */ + set_bit(INTTYPE_LEVEL, pin, !!(flags & QUARKX1000_GPIO_EDGE)); + + /* set debounce */ + set_bit(DEBOUNCE, pin, !!(flags & QUARKX1000_GPIO_DEBOUNCE)); + + /* set clock synchronous */ + set_bit(LS_SYNC, 0, !!(flags & QUARKX1000_GPIO_CLOCK_SYNC)); +} + +int +quarkX1000_gpio_config(uint8_t pin, int flags) +{ + if (((flags & QUARKX1000_GPIO_IN) && (flags & QUARKX1000_GPIO_OUT)) || + ((flags & QUARKX1000_GPIO_INT) && (flags & QUARKX1000_GPIO_OUT))) { + return -1; + } + + if (flags & QUARKX1000_GPIO_INT) { + gpio_interrupt_config(pin, flags); + } else { + /* set direction */ + set_bit(SWPORTA_DDR, pin, !!(flags & QUARKX1000_GPIO_OUT)); + + /* set interrupt disabled */ + set_bit(INTEN, pin, 0); + } + + return 0; +} + +int +quarkX1000_gpio_config_port(int flags) +{ + uint8_t i; + + for (i = 0; i < PINS; i++) { + if (quarkX1000_gpio_config(i, flags) < 0) { + return -1; + } + } + + return 0; +} + +int +quarkX1000_gpio_read(uint8_t pin, uint8_t *value) +{ + uint32_t value32 = read(EXT_PORTA); + *value = !!(value32 & BIT(pin)); + + return 0; +} + +int +quarkX1000_gpio_write(uint8_t pin, uint8_t value) +{ + set_bit(SWPORTA_DR, pin, !!value); + return 0; +} + +int +quarkX1000_gpio_read_port(uint8_t *value) +{ + uint32_t value32 = read(EXT_PORTA); + *value = value32 & ~0xFFFFFF00; + + return 0; +} + +int +quarkX1000_gpio_write_port(uint8_t value) +{ + write(SWPORTA_DR, value); + return 0; +} + +int +quarkX1000_gpio_set_callback(quarkX1000_gpio_callback callback) +{ + data.callback = callback; + return 0; +} + +void +quarkX1000_gpio_clock_enable(void) +{ + set_bit(LS_SYNC, 0, 1); +} + +void +quarkX1000_gpio_clock_disable(void) +{ + set_bit(LS_SYNC, 0, 0); +} + +DEFINE_SHARED_IRQ(GPIO_IRQ, IRQAGENT3, INTC, PIRQC, gpio_isr); + +int +quarkX1000_gpio_init(void) +{ + pci_config_addr_t pci_addr; + + pci_addr.raw = 0; + pci_addr.bus = 0; + pci_addr.dev = 21; + pci_addr.func = 2; + pci_addr.reg_off = PCI_CONFIG_REG_BAR1; + + pci_command_enable(pci_addr, PCI_CMD_1_MEM_SPACE_EN); + + PROT_DOMAINS_INIT_ID(drv); + pci_init(&drv, pci_addr, MMIO_SZ, 0, 0); + SYSCALLS_INIT(quarkX1000_gpio_mmin); + SYSCALLS_AUTHZ(quarkX1000_gpio_mmin, drv); + SYSCALLS_INIT(quarkX1000_gpio_mmout); + SYSCALLS_AUTHZ(quarkX1000_gpio_mmout, drv); + + data.callback = 0; + + quarkX1000_gpio_clock_enable(); + + /* clear registers */ + write(INTEN, 0); + write(INTMASK, 0); + write(PORTA_EOI, 0); + + return 0; +} diff --git a/cpu/x86/drivers/quarkX1000/gpio.h b/cpu/x86/drivers/quarkX1000/gpio.h new file mode 100644 index 000000000..61ef11aab --- /dev/null +++ b/cpu/x86/drivers/quarkX1000/gpio.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_DRIVERS_QUARKX1000_GPIO_H_ +#define CPU_X86_DRIVERS_QUARKX1000_GPIO_H_ + +#include + +#include "pci.h" + +#define QUARKX1000_GPIO_IN (0 << 0) +#define QUARKX1000_GPIO_OUT (1 << 0) +#define QUARKX1000_GPIO_INT (1 << 1) +#define QUARKX1000_GPIO_ACTIVE_LOW (0 << 2) +#define QUARKX1000_GPIO_ACTIVE_HIGH (1 << 2) +#define QUARKX1000_GPIO_LEVEL (0 << 3) +#define QUARKX1000_GPIO_EDGE (1 << 3) +#define QUARKX1000_GPIO_DEBOUNCE (1 << 4) +#define QUARKX1000_GPIO_CLOCK_SYNC (1 << 5) +#define QUARKX1000_GPIO_POL_NORMAL (0 << 6) +#define QUARKX1000_GPIO_POL_INV (1 << 6) +#define QUARKX1000_GPIO_PUD_NORMAL (0 << 7) +#define QUARKX1000_GPIO_PUD_PULL_UP (1 << 7) +#define QUARKX1000_GPIO_PUD_PULL_DOWN (2 << 7) + +#define QUARKX1000_GPIO_DIR_MASK (1 << 0) +#define QUARKX1000_GPIO_POL_MASK (1 << 6) +#define QUARKX1000_GPIO_PUD_MASK (3 << 7) + +typedef void (*quarkX1000_gpio_callback)(uint32_t); + +int quarkX1000_gpio_init(void); + +int quarkX1000_gpio_config(uint8_t pin, int flags); +int quarkX1000_gpio_read(uint8_t pin, uint8_t *value); +int quarkX1000_gpio_write(uint8_t pin, uint8_t value); + +int quarkX1000_gpio_config_port(int flags); +int quarkX1000_gpio_read_port(uint8_t *value); +int quarkX1000_gpio_write_port(uint8_t value); + +int quarkX1000_gpio_set_callback(quarkX1000_gpio_callback callback); + +void quarkX1000_gpio_clock_enable(void); +void quarkX1000_gpio_clock_disable(void); + +#endif /* CPU_X86_DRIVERS_QUARKX1000_GPIO_H_ */ diff --git a/cpu/x86/drivers/quarkX1000/i2c-registers.h b/cpu/x86/drivers/quarkX1000/i2c-registers.h new file mode 100644 index 000000000..3ff7746ec --- /dev/null +++ b/cpu/x86/drivers/quarkX1000/i2c-registers.h @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_DRIVERS_QUARKX1000_I2C_REGISTERS_H_ +#define CPU_X86_DRIVERS_QUARKX1000_I2C_REGISTERS_H_ + +#define QUARKX1000_IC_CON 0x00 +#define QUARKX1000_IC_TAR 0x04 +#define QUARKX1000_IC_DATA_CMD 0x10 +#define QUARKX1000_IC_SS_SCL_HCNT 0x14 +#define QUARKX1000_IC_SS_SCL_LCNT 0x18 +#define QUARKX1000_IC_FS_SCL_HCNT 0x1C +#define QUARKX1000_IC_FS_SCL_LCNT 0x20 +#define QUARKX1000_IC_INTR_STAT 0x2C +#define QUARKX1000_IC_INTR_MASK 0x30 +#define QUARKX1000_IC_RAW_INTR_STAT 0x34 +#define QUARKX1000_IC_RX_TL 0x38 +#define QUARKX1000_IC_TX_TL 0x3C +#define QUARKX1000_IC_CLR_INTR 0x40 +#define QUARKX1000_IC_CLR_RX_UNDER 0x44 +#define QUARKX1000_IC_CLR_RX_OVER 0x48 +#define QUARKX1000_IC_CLR_TX_OVER 0x4C +#define QUARKX1000_IC_CLR_RD_REQ 0x50 +#define QUARKX1000_IC_CLR_TX_ABRT 0x54 +#define QUARKX1000_IC_CLR_ACTIVITY 0x5C +#define QUARKX1000_IC_CLR_STOP_DET 0x60 +#define QUARKX1000_IC_CLR_START_DET 0x64 +#define QUARKX1000_IC_ENABLE 0x6C +#define QUARKX1000_IC_STATUS 0x70 +#define QUARKX1000_IC_TXFLR 0x74 +#define QUARKX1000_IC_RXFLR 0x78 +#define QUARKX1000_IC_SDA_HOLD 0x7C +#define QUARKX1000_IC_TX_ABRT_SOURCE 0x80 +#define QUARKX1000_IC_ENABLE_STATUS 0x9C +#define QUARKX1000_IC_FS_SPKLEN 0xA0 + +#define QUARKX1000_IC_HIGHEST QUARKX1000_IC_FS_SPKLEN + +/* IC_CON */ +#define QUARKX1000_IC_CON_MASTER_MODE_SHIFT 0 +#define QUARKX1000_IC_CON_MASTER_MODE_MASK 0x01 +#define QUARKX1000_IC_CON_SPEED_SHIFT 1 +#define QUARKX1000_IC_CON_SPEED_MASK 0x06 +#define QUARKX1000_IC_CON_10BITADDR_MASTER_SHIFT 4 +#define QUARKX1000_IC_CON_10BITADDR_MASTER_MASK 0x10 +#define QUARKX1000_IC_CON_RESTART_EN_SHIFT 5 +#define QUARKX1000_IC_CON_RESTART_EN_MASK 0x20 + +/* IC_TAR */ +#define QUARKX1000_IC_TAR_SHIFT 0 +#define QUARKX1000_IC_TAR_MASK 0x3FF + +/* IC_DATA_CMD */ +#define QUARKX1000_IC_DATA_CMD_DAT_SHIFT 0 +#define QUARKX1000_IC_DATA_CMD_DAT_MASK 0x0FF +#define QUARKX1000_IC_DATA_CMD_CMD_SHIFT 8 +#define QUARKX1000_IC_DATA_CMD_CMD_MASK 0x100 +#define QUARKX1000_IC_DATA_CMD_STOP_SHIFT 9 +#define QUARKX1000_IC_DATA_CMD_STOP_MASK 0x200 +#define QUARKX1000_IC_DATA_CMD_RESTART_SHIFT 10 +#define QUARKX1000_IC_DATA_CMD_RESTART_MASK 0x400 + +/* IC_SS_SCL_HCNT */ +#define QUARKX1000_IC_SS_SCL_HCNT_SHIFT 0 +#define QUARKX1000_IC_SS_SCL_HCNT_MASK 0xFFFF + +/* IC_SS_SCL_LCNT */ +#define QUARKX1000_IC_SS_SCL_LCNT_SHIFT 0 +#define QUARKX1000_IC_SS_SCL_LCNT_MASK 0xFFFF + +/* IC_FS_SCL_HCNT */ +#define QUARKX1000_IC_FS_SCL_HCNT_SHIFT 0 +#define QUARKX1000_IC_FS_SCL_HCNT_MASK 0xFFFF + +/* IC_FS_SCL_LCNT */ +#define QUARKX1000_IC_FS_SCL_LCNT_SHIFT 0 +#define QUARKX1000_IC_FS_SCL_LCNT_MASK 0xFFFF + +/* IC_INTR_STAT */ +#define QUARKX1000_IC_INTR_STAT_RX_UNDER_SHIFT 0 +#define QUARKX1000_IC_INTR_STAT_RX_UNDER_MASK 0x001 +#define QUARKX1000_IC_INTR_STAT_RX_OVER_SHIFT 1 +#define QUARKX1000_IC_INTR_STAT_RX_OVER_MASK 0x002 +#define QUARKX1000_IC_INTR_STAT_RX_FULL_SHIFT 2 +#define QUARKX1000_IC_INTR_STAT_RX_FULL_MASK 0x004 +#define QUARKX1000_IC_INTR_STAT_TX_OVER_SHIFT 3 +#define QUARKX1000_IC_INTR_STAT_TX_OVER_MASK 0x008 +#define QUARKX1000_IC_INTR_STAT_TX_EMPTY_SHIFT 4 +#define QUARKX1000_IC_INTR_STAT_TX_EMPTY_MASK 0x010 +#define QUARKX1000_IC_INTR_STAT_RD_REQ_SHIFT 5 +#define QUARKX1000_IC_INTR_STAT_RD_REQ_MASK 0x020 +#define QUARKX1000_IC_INTR_STAT_TX_ABRT_SHIFT 6 +#define QUARKX1000_IC_INTR_STAT_TX_ABRT_MASK 0x040 +#define QUARKX1000_IC_INTR_STAT_ACTIVITY_SHIFT 8 +#define QUARKX1000_IC_INTR_STAT_ACTIVITY_MASK 0x100 +#define QUARKX1000_IC_INTR_STAT_STOP_DET_SHIFT 9 +#define QUARKX1000_IC_INTR_STAT_STOP_DET_MASK 0x200 +#define QUARKX1000_IC_INTR_STAT_START_DET_SHIFT 10 +#define QUARKX1000_IC_INTR_STAT_START_DET_MASK 0x400 + +/* IC_ENABLE */ +#define QUARKX1000_IC_ENABLE_SHIFT 0 +#define QUARKX1000_IC_ENABLE_MASK 0x01 + +/* IC_STATUS */ +#define QUARKX1000_IC_STATUS_ACTIVITY_SHIFT 0 +#define QUARKX1000_IC_STATUS_ACTIVITY_MASK 0x01 +#define QUARKX1000_IC_STATUS_TFNF_SHIFT 1 +#define QUARKX1000_IC_STATUS_TFNF_MASK 0x02 +#define QUARKX1000_IC_STATUS_TFE_SHIFT 2 +#define QUARKX1000_IC_STATUS_TFE_MASK 0x04 +#define QUARKX1000_IC_STATUS_RFNE_SHIFT 3 +#define QUARKX1000_IC_STATUS_RFNE_MASK 0x08 +#define QUARKX1000_IC_STATUS_RFF_SHIFT 4 +#define QUARKX1000_IC_STATUS_RFF_MASK 0x10 +#define QUARKX1000_IC_STATUS_MST_ACTIVITY_SHIFT 5 +#define QUARKX1000_IC_STATUS_MST_ACTIVITY_MASK 0x20 + +/* IC_TXFLR */ +#define QUARKX1000_IC_TXFLR_SHIFT 0 +#define QUARKX1000_IC_TXFLR_MASK 0x1F + +/* IC_RXFLR */ +#define QUARKX1000_IC_RXFLR_SHIFT 0 +#define QUARKX1000_IC_RXFLR_MASK 0x1F + +/* IC_FS_SPKLEN */ +#define QUARKX1000_IC_FS_SPKLEN_SHIFT 0 +#define QUARKX1000_IC_FS_SPKLEN_MASK 0xFF + +#endif /* CPU_X86_DRIVERS_QUARKX1000_I2C_REGISTERS_H_ */ diff --git a/cpu/x86/drivers/quarkX1000/i2c.c b/cpu/x86/drivers/quarkX1000/i2c.c new file mode 100644 index 000000000..9e233e89c --- /dev/null +++ b/cpu/x86/drivers/quarkX1000/i2c.c @@ -0,0 +1,575 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "contiki.h" +#include "i2c.h" + +#include "i2c-registers.h" +#include "paging.h" +#include "shared-isr.h" +#include "syscalls.h" + +#define I2C_CLOCK_SPEED 25 /* kHz */ +#define I2C_FIFO_DEPTH 16 + +#define I2C_STD_HCNT (I2C_CLOCK_SPEED * 4) +#define I2C_STD_LCNT (I2C_CLOCK_SPEED * 5) +#define I2C_FS_HCNT (I2C_CLOCK_SPEED) +#define I2C_FS_LCNT (I2C_CLOCK_SPEED) + +#define I2C_FS_SPKLEN_LCNT_OFFSET 8 +#define I2C_FS_SPKLEN_HCNT_OFFSET 6 + +#define I2C_POLLING_TIMEOUT (CLOCK_SECOND / 10) + +#define I2C_IRQ 9 + +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING +#define MMIO_SZ MIN_PAGE_SIZE +#else +#define MMIO_SZ (QUARKX1000_IC_HIGHEST + 4) +#endif + +typedef enum { + I2C_DIRECTION_READ, + I2C_DIRECTION_WRITE +} I2C_DIRECTION; + +PROT_DOMAINS_ALLOC(pci_driver_t, drv); + +struct quarkX1000_i2c_config { + QUARKX1000_I2C_SPEED speed; + QUARKX1000_I2C_ADDR_MODE addressing_mode; + + quarkX1000_i2c_callback cb_rx; + quarkX1000_i2c_callback cb_tx; + quarkX1000_i2c_callback cb_err; +}; + +struct i2c_internal_data { + struct quarkX1000_i2c_config config; + + I2C_DIRECTION direction; + + uint8_t rx_len; + uint8_t *rx_buffer; + uint8_t tx_len; + uint8_t *tx_buffer; + uint8_t rx_tx_len; + + uint32_t hcnt; + uint32_t lcnt; +}; + +static struct i2c_internal_data device; + +static int inited = 0; + +void quarkX1000_i2c_mmin(uint32_t offset, uint32_t *res); +SYSCALLS_DEFINE_SINGLETON(quarkX1000_i2c_mmin, drv, + uint32_t offset, uint32_t *res) +{ + uint32_t *loc_res; + + PROT_DOMAINS_VALIDATE_PTR(loc_res, res, sizeof(*res)); + if(QUARKX1000_IC_HIGHEST < offset) { + halt(); + } + + prot_domains_enable_mmio(); + PCI_MMIO_READL(drv, *loc_res, offset); + prot_domains_disable_mmio(); +} + +static inline uint32_t +read(uint32_t offset) +{ + uint32_t res; + quarkX1000_i2c_mmin(offset, &res); + + return res; +} + +void quarkX1000_i2c_mmout(uint32_t offset, uint32_t val); +SYSCALLS_DEFINE_SINGLETON(quarkX1000_i2c_mmout, drv, + uint32_t offset, uint32_t val) +{ + if(QUARKX1000_IC_HIGHEST < offset) { + halt(); + } + + prot_domains_enable_mmio(); + PCI_MMIO_WRITEL(drv, offset, val); + prot_domains_disable_mmio(); +} + +static inline void +write(uint32_t offset, uint32_t val) +{ + quarkX1000_i2c_mmout(offset, val); +} + +static uint32_t +get_value(uint32_t offset, uint32_t mask, uint32_t shift) +{ + uint32_t register_value = read(offset); + + register_value &= ~(0xFFFFFFFF - mask); + + return register_value >> shift; +} + +static void +set_value(uint32_t offset, uint32_t mask, uint32_t shift, uint32_t value) +{ + uint32_t register_value = read(offset); + + register_value &= ~mask; + register_value |= value << shift; + + write(offset, register_value); +} + +static void +i2c_data_read(void) +{ + uint8_t i, rx_cnt; + + if (device.rx_len == 0) + return; + + rx_cnt = get_value(QUARKX1000_IC_RXFLR, + QUARKX1000_IC_RXFLR_MASK, QUARKX1000_IC_RXFLR_SHIFT); + + if (rx_cnt > device.rx_len) + rx_cnt = device.rx_len; + + for (i = 0; i < rx_cnt; i++) { + device.rx_buffer[i] = get_value(QUARKX1000_IC_DATA_CMD, + QUARKX1000_IC_DATA_CMD_DAT_MASK, QUARKX1000_IC_DATA_CMD_DAT_SHIFT); + } + + device.rx_buffer += i; + device.rx_len -= i; +} + +static void +i2c_data_send(void) +{ + uint32_t data = 0; + uint8_t i, tx_cnt; + + if (device.rx_tx_len == 0) + return; + + tx_cnt = I2C_FIFO_DEPTH - get_value(QUARKX1000_IC_TXFLR, + QUARKX1000_IC_TXFLR_MASK, QUARKX1000_IC_TXFLR_SHIFT); + + if (tx_cnt > device.rx_tx_len) + tx_cnt = device.rx_tx_len; + + for (i = 0; i < tx_cnt; i++) { + if (device.tx_len > 0) { + data = device.tx_buffer[i]; + + if (device.tx_len == 1) + data |= (device.rx_len > 0) ? QUARKX1000_IC_DATA_CMD_RESTART_MASK : QUARKX1000_IC_DATA_CMD_STOP_MASK; + + device.tx_len -= 1; + } else { + data = QUARKX1000_IC_DATA_CMD_CMD_MASK; + + if (device.rx_tx_len == 1) + data |= QUARKX1000_IC_DATA_CMD_STOP_MASK; + } + + write(QUARKX1000_IC_DATA_CMD, data); + device.rx_tx_len -= 1; + } + + device.tx_buffer += i; +} + +static bool +i2c_isr(void) +{ + bool handled = false; + + if (read(QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_STOP_DET_MASK) { + i2c_data_read(); + + write(QUARKX1000_IC_INTR_MASK, 0); + read(QUARKX1000_IC_CLR_INTR); + + if (device.direction == I2C_DIRECTION_WRITE) { + if (device.config.cb_tx) + device.config.cb_tx(); + } else { + if (device.config.cb_rx) + device.config.cb_rx(); + } + + handled = true; + } + + if (read(QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_TX_EMPTY_MASK) { + i2c_data_send(); + if (device.rx_tx_len <= 0) { + set_value(QUARKX1000_IC_INTR_MASK, + QUARKX1000_IC_INTR_STAT_TX_EMPTY_MASK, QUARKX1000_IC_INTR_STAT_TX_EMPTY_SHIFT, 0); + set_value(QUARKX1000_IC_INTR_MASK, + QUARKX1000_IC_INTR_STAT_STOP_DET_MASK, QUARKX1000_IC_INTR_STAT_STOP_DET_SHIFT, 1); + } + + handled = true; + } + + if(read(QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_RX_FULL_MASK) { + i2c_data_read(); + + handled = true; + } + + if (read(QUARKX1000_IC_INTR_STAT) & (QUARKX1000_IC_INTR_STAT_TX_ABRT_MASK + | QUARKX1000_IC_INTR_STAT_TX_OVER_MASK | QUARKX1000_IC_INTR_STAT_RX_OVER_MASK + | QUARKX1000_IC_INTR_STAT_RX_UNDER_MASK)) { + write(QUARKX1000_IC_INTR_MASK, 0); + read(QUARKX1000_IC_CLR_INTR); + + if (device.config.cb_err) + device.config.cb_err(); + + handled = true; + } + + return handled; +} + +void +quarkX1000_i2c_configure(QUARKX1000_I2C_SPEED speed, + QUARKX1000_I2C_ADDR_MODE addressing_mode) +{ + uint32_t hcnt, lcnt; + uint8_t ic_fs_spklen; + + device.config.speed = speed; + device.config.addressing_mode = addressing_mode; + + if (device.config.speed == QUARKX1000_I2C_SPEED_STANDARD) { + lcnt = I2C_STD_LCNT; + hcnt = I2C_STD_HCNT; + } else { + lcnt = I2C_FS_LCNT; + hcnt = I2C_FS_HCNT; + } + + ic_fs_spklen = get_value(QUARKX1000_IC_FS_SPKLEN, + QUARKX1000_IC_FS_SPKLEN_MASK, QUARKX1000_IC_FS_SPKLEN_SHIFT); + + /* We adjust the Low Count and High Count based on the Spike Suppression Limit */ + device.lcnt = (lcnt < (ic_fs_spklen + I2C_FS_SPKLEN_LCNT_OFFSET)) ? ic_fs_spklen + I2C_FS_SPKLEN_LCNT_OFFSET : lcnt; + device.hcnt = (hcnt < (ic_fs_spklen + I2C_FS_SPKLEN_HCNT_OFFSET)) ? ic_fs_spklen + I2C_FS_SPKLEN_HCNT_OFFSET : hcnt; + + /* Clear interrupts. */ + read(QUARKX1000_IC_CLR_INTR); +} + +void +quarkX1000_i2c_set_callbacks(quarkX1000_i2c_callback rx, + quarkX1000_i2c_callback tx, + quarkX1000_i2c_callback err) +{ + device.config.cb_rx = rx; + device.config.cb_tx = tx; + device.config.cb_err = err; +} + +static int +i2c_setup(void) +{ + /* Clear all values */ + write(QUARKX1000_IC_CON, 0); + + /* Clear interrupts */ + read(QUARKX1000_IC_CLR_INTR); + + /* Quark X1000 SoC I2C only supports master mode. */ + set_value(QUARKX1000_IC_CON, + QUARKX1000_IC_CON_MASTER_MODE_MASK, QUARKX1000_IC_CON_MASTER_MODE_SHIFT, 1); + + /* Set restart enable */ + set_value(QUARKX1000_IC_CON, + QUARKX1000_IC_CON_RESTART_EN_MASK, QUARKX1000_IC_CON_RESTART_EN_SHIFT, 1); + + /* Set addressing mode */ + if (device.config.addressing_mode == QUARKX1000_I2C_ADDR_MODE_10BIT) { + set_value(QUARKX1000_IC_CON, + QUARKX1000_IC_CON_10BITADDR_MASTER_MASK, QUARKX1000_IC_CON_10BITADDR_MASTER_SHIFT, 1); + } + + if (device.config.speed == QUARKX1000_I2C_SPEED_STANDARD) { + set_value(QUARKX1000_IC_SS_SCL_LCNT, + QUARKX1000_IC_SS_SCL_LCNT_MASK, QUARKX1000_IC_SS_SCL_LCNT_SHIFT, device.lcnt); + set_value(QUARKX1000_IC_SS_SCL_HCNT, + QUARKX1000_IC_SS_SCL_HCNT_MASK, QUARKX1000_IC_SS_SCL_HCNT_SHIFT, device.hcnt); + set_value(QUARKX1000_IC_CON, + QUARKX1000_IC_CON_SPEED_MASK, QUARKX1000_IC_CON_SPEED_SHIFT, 0x1); + } else { + set_value(QUARKX1000_IC_FS_SCL_LCNT, + QUARKX1000_IC_FS_SCL_LCNT_MASK, QUARKX1000_IC_FS_SCL_LCNT_SHIFT, device.lcnt); + set_value(QUARKX1000_IC_FS_SCL_HCNT, + QUARKX1000_IC_FS_SCL_HCNT_MASK, QUARKX1000_IC_FS_SCL_HCNT_SHIFT, device.hcnt); + set_value(QUARKX1000_IC_CON, + QUARKX1000_IC_CON_SPEED_MASK, QUARKX1000_IC_CON_SPEED_SHIFT, 0x2); + } + + return 0; +} + +static void +i2c_operation_setup(uint8_t *write_buf, uint8_t write_len, + uint8_t *read_buf, uint8_t read_len, uint16_t addr) +{ + device.rx_len = read_len; + device.rx_buffer = read_buf; + device.tx_len = write_len; + device.tx_buffer = write_buf; + device.rx_tx_len = device.rx_len + device.tx_len; + + /* Disable controller */ + set_value(QUARKX1000_IC_ENABLE, + QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0); + + i2c_setup(); + + /* Disable interrupts */ + write(QUARKX1000_IC_INTR_MASK, 0); + + /* Clear interrupts */ + read(QUARKX1000_IC_CLR_INTR); + + /* Set address of target slave */ + set_value(QUARKX1000_IC_TAR, + QUARKX1000_IC_TAR_MASK, QUARKX1000_IC_TAR_SHIFT, addr); +} + +/* This is an interrupt based operation */ +static int +i2c_operation(uint8_t *write_buf, uint8_t write_len, + uint8_t *read_buf, uint8_t read_len, uint16_t addr) +{ + if (read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_ACTIVITY_MASK) + return -1; + + i2c_operation_setup(write_buf, write_len, read_buf, read_len, addr); + + /* Enable master TX and RX interrupts */ + set_value(QUARKX1000_IC_INTR_MASK, + QUARKX1000_IC_INTR_STAT_TX_OVER_MASK, QUARKX1000_IC_INTR_STAT_TX_OVER_SHIFT, 1); + set_value(QUARKX1000_IC_INTR_MASK, + QUARKX1000_IC_INTR_STAT_TX_EMPTY_MASK, QUARKX1000_IC_INTR_STAT_TX_EMPTY_SHIFT, 1); + set_value(QUARKX1000_IC_INTR_MASK, + QUARKX1000_IC_INTR_STAT_TX_ABRT_MASK, QUARKX1000_IC_INTR_STAT_TX_ABRT_SHIFT, 1); + set_value(QUARKX1000_IC_INTR_MASK, + QUARKX1000_IC_INTR_STAT_RX_UNDER_MASK, QUARKX1000_IC_INTR_STAT_RX_UNDER_SHIFT, 1); + set_value(QUARKX1000_IC_INTR_MASK, + QUARKX1000_IC_INTR_STAT_RX_OVER_MASK, QUARKX1000_IC_INTR_STAT_RX_OVER_SHIFT, 1); + set_value(QUARKX1000_IC_INTR_MASK, + QUARKX1000_IC_INTR_STAT_RX_FULL_MASK, QUARKX1000_IC_INTR_STAT_RX_FULL_SHIFT, 1); + set_value(QUARKX1000_IC_INTR_MASK, + QUARKX1000_IC_INTR_STAT_STOP_DET_MASK, QUARKX1000_IC_INTR_STAT_STOP_DET_SHIFT, 1); + + /* Enable controller */ + set_value(QUARKX1000_IC_ENABLE, + QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 1); + + return 0; +} + +/* This is an interrupt based write */ +int +quarkX1000_i2c_write(uint8_t *buf, uint8_t len, uint16_t addr) +{ + device.direction = I2C_DIRECTION_WRITE; + return i2c_operation(buf, len, 0, 0, addr); +} + +/* This is an interrupt based read */ +int +quarkX1000_i2c_read(uint8_t *buf, uint8_t len, uint16_t addr) +{ + device.direction = I2C_DIRECTION_READ; + return i2c_operation(0, 0, buf, len, addr); +} + +static int +i2c_polling_operation(uint8_t *write_buf, uint8_t write_len, + uint8_t *read_buf, uint8_t read_len, uint16_t addr) +{ + uint32_t start_time, intr_mask_stat; + + if (!(read(QUARKX1000_IC_CON) & QUARKX1000_IC_CON_MASTER_MODE_MASK)) + return -1; + + /* Wait i2c idle */ + start_time = clock_seconds(); + while (read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_ACTIVITY_MASK) { + if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) { + return -1; + } + } + + /* Get interrupt mask to restore in the end of polling operation */ + intr_mask_stat = read(QUARKX1000_IC_INTR_MASK); + + i2c_operation_setup(write_buf, write_len, read_buf, read_len, addr); + + /* Enable controller */ + set_value(QUARKX1000_IC_ENABLE, + QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 1); + + /* Transmit */ + if (device.tx_len != 0) { + while (device.tx_len > 0) { + start_time = clock_seconds(); + while (!(read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_TFNF_MASK)) { + if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) { + set_value(QUARKX1000_IC_ENABLE, + QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0); + return -1; + } + } + i2c_data_send(); + } + + start_time = clock_seconds(); + while (!(read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_TFE_MASK)) { + if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) { + set_value(QUARKX1000_IC_ENABLE, + QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0); + return -1; + } + } + } + + i2c_data_send(); + + /* Receive */ + if (device.rx_len != 0) { + while (device.rx_len > 0) { + start_time = clock_seconds(); + while (!(read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_RFNE_MASK)) { + if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) { + set_value(QUARKX1000_IC_ENABLE, + QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0); + return -1; + } + } + i2c_data_read(); + } + } + + /* Stop Det */ + start_time = clock_seconds(); + while (!(read(QUARKX1000_IC_RAW_INTR_STAT) & QUARKX1000_IC_INTR_STAT_STOP_DET_MASK)) { + if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) { + set_value(QUARKX1000_IC_ENABLE, + QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0); + return -1; + } + } + read(QUARKX1000_IC_CLR_STOP_DET); + + /* Wait i2c idle */ + start_time = clock_seconds(); + while (read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_ACTIVITY_MASK) { + if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) { + set_value(QUARKX1000_IC_ENABLE, + QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0); + return -1; + } + } + + /* Disable controller */ + set_value(QUARKX1000_IC_ENABLE, + QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0); + + /* Restore interrupt mask */ + write(QUARKX1000_IC_INTR_MASK, intr_mask_stat); + + return 0; +} + +int +quarkX1000_i2c_polling_write(uint8_t *buf, uint8_t len, uint16_t addr) +{ + device.direction = I2C_DIRECTION_WRITE; + return i2c_polling_operation(buf, len, 0, 0, addr); +} + +int +quarkX1000_i2c_polling_read(uint8_t *buf, uint8_t len, uint16_t addr) +{ + device.direction = I2C_DIRECTION_READ; + return i2c_polling_operation(0, 0, buf, len ,addr); +} + +int +quarkX1000_i2c_is_available(void) +{ + return inited; +} + +DEFINE_SHARED_IRQ(I2C_IRQ, IRQAGENT3, INTC, PIRQC, i2c_isr); + +int +quarkX1000_i2c_init(void) +{ + pci_config_addr_t pci_addr; + + pci_addr.raw = 0; + pci_addr.bus = 0; + pci_addr.dev = 21; + pci_addr.func = 2; + pci_addr.reg_off = PCI_CONFIG_REG_BAR0; + + pci_command_enable(pci_addr, PCI_CMD_1_MEM_SPACE_EN); + + PROT_DOMAINS_INIT_ID(drv); + pci_init(&drv, pci_addr, MMIO_SZ, 0, 0); + SYSCALLS_INIT(quarkX1000_i2c_mmin); + SYSCALLS_AUTHZ(quarkX1000_i2c_mmin, drv); + SYSCALLS_INIT(quarkX1000_i2c_mmout); + SYSCALLS_AUTHZ(quarkX1000_i2c_mmout, drv); + + inited = 1; + + return 0; +} diff --git a/cpu/x86/drivers/quarkX1000/i2c.h b/cpu/x86/drivers/quarkX1000/i2c.h new file mode 100644 index 000000000..ed2db18fb --- /dev/null +++ b/cpu/x86/drivers/quarkX1000/i2c.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_DRIVERS_QUARKX1000_I2C_H_ +#define CPU_X86_DRIVERS_QUARKX1000_I2C_H_ + +#include "pci.h" + +typedef enum { + QUARKX1000_I2C_SPEED_STANDARD, + QUARKX1000_I2C_SPEED_FAST +} QUARKX1000_I2C_SPEED; + +typedef enum { + QUARKX1000_I2C_ADDR_MODE_7BIT, + QUARKX1000_I2C_ADDR_MODE_10BIT +} QUARKX1000_I2C_ADDR_MODE; + +typedef void (*quarkX1000_i2c_callback)(void); + +int quarkX1000_i2c_init(void); +void quarkX1000_i2c_configure(QUARKX1000_I2C_SPEED speed, + QUARKX1000_I2C_ADDR_MODE addressing_mode); +void quarkX1000_i2c_set_callbacks(quarkX1000_i2c_callback rx, + quarkX1000_i2c_callback tx, + quarkX1000_i2c_callback err); +int quarkX1000_i2c_is_available(void); + +int quarkX1000_i2c_read(uint8_t *buf, uint8_t len, uint16_t addr); +int quarkX1000_i2c_write(uint8_t *buf, uint8_t len, uint16_t addr); + +int quarkX1000_i2c_polling_read(uint8_t *buf, uint8_t len, uint16_t addr); +int quarkX1000_i2c_polling_write(uint8_t *buf, uint8_t len, uint16_t addr); + +#endif /* CPU_X86_DRIVERS_QUARKX1000_I2C_H_ */ diff --git a/cpu/x86/drivers/quarkX1000/imr-conf.c b/cpu/x86/drivers/quarkX1000/imr-conf.c new file mode 100644 index 000000000..8c5b6703a --- /dev/null +++ b/cpu/x86/drivers/quarkX1000/imr-conf.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "dma.h" +#include "imr.h" +#include "msg-bus.h" + +/*---------------------------------------------------------------------------*/ +void +quarkX1000_imr_conf(void) +{ + quarkX1000_imr_t imr; + int imr_idx = 0; + + imr.lo.raw = 0; + imr.hi.raw = 0; + imr.rdmsk.raw = 0; + imr.wrmsk.raw = 0; + + imr.lo.lock = 1; + + imr.rdmsk.cpu0 = imr.rdmsk.cpu_0 = 1; + imr.wrmsk.cpu0 = imr.wrmsk.cpu_0 = 1; + + quarkX1000_msg_bus_init(); + + imr.lo.addr = 0; + imr.hi.addr = (((uint32_t)&_sbss_dma_addr) - 1) >> QUARKX1000_IMR_SHAMT; + quarkX1000_imr_write(imr_idx, imr); + imr_idx++; + + imr.lo.addr = ((uint32_t)&_ebss_dma_addr) >> QUARKX1000_IMR_SHAMT; + imr.hi.addr = ~0; + quarkX1000_imr_write(imr_idx, imr); + imr_idx++; + + imr.lo.addr = 0; + imr.hi.addr = 0; + imr.rdmsk.raw = ~0; + imr.wrmsk.raw = ~0; + + /* Lock the other IMRs open */ + while(imr_idx < QUARKX1000_IMR_CNT) { + quarkX1000_imr_write(imr_idx, imr); + imr_idx++; + } + +#ifndef DBG_IMRS + /* The IMRs are locked by the hardware, but the message bus could still + * provide access to other potentially-sensitive functionality. + */ + quarkX1000_msg_bus_lock(); +#endif +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/drivers/quarkX1000/imr-conf.h b/cpu/x86/drivers/quarkX1000/imr-conf.h new file mode 100644 index 000000000..a81888c29 --- /dev/null +++ b/cpu/x86/drivers/quarkX1000/imr-conf.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_DRIVERS_QUARKX1000_IMR_CONF_H_ +#define CPU_X86_DRIVERS_QUARKX1000_IMR_CONF_H_ + +void quarkX1000_imr_conf(void); + +#endif /* CPU_X86_DRIVERS_QUARKX1000_IMR_CONF_H_ */ diff --git a/cpu/x86/drivers/quarkX1000/imr.c b/cpu/x86/drivers/quarkX1000/imr.c new file mode 100644 index 000000000..03c43a0c0 --- /dev/null +++ b/cpu/x86/drivers/quarkX1000/imr.c @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include +#include "imr.h" +#include "msg-bus.h" + +#define MEM_MANAGER_PORT 5 + +#define IMR_BASE_OFFSET 0x40 +#define IMR_REG_COUNT 4 + +#define IMR_LO_OFFSET 0 +#define IMR_HI_OFFSET 1 +#define IMR_RDMSK_OFFSET 2 +#define IMR_WRMSK_OFFSET 3 + +/*---------------------------------------------------------------------------*/ +/** + * \brief Read the contents of the specified IMR. + */ +quarkX1000_imr_t +quarkX1000_imr_read(uint32_t imr_idx) +{ + quarkX1000_imr_t imr; + uint32_t reg_base = IMR_BASE_OFFSET + (IMR_REG_COUNT * imr_idx); + + assert(imr_idx < QUARKX1000_IMR_CNT); + + quarkX1000_msg_bus_read(MEM_MANAGER_PORT, + reg_base + IMR_LO_OFFSET, &imr.lo.raw); + quarkX1000_msg_bus_read(MEM_MANAGER_PORT, + reg_base + IMR_HI_OFFSET, &imr.hi.raw); + quarkX1000_msg_bus_read(MEM_MANAGER_PORT, + reg_base + IMR_RDMSK_OFFSET, &imr.rdmsk.raw); + quarkX1000_msg_bus_read(MEM_MANAGER_PORT, + reg_base + IMR_WRMSK_OFFSET, &imr.wrmsk.raw); + + return imr; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Overwrite the contents of the specified IMR. + */ +void +quarkX1000_imr_write(uint32_t imr_idx, quarkX1000_imr_t imr) +{ + uint32_t reg_base = IMR_BASE_OFFSET + (IMR_REG_COUNT * imr_idx); + + assert(imr_idx < QUARKX1000_IMR_CNT); + + quarkX1000_msg_bus_write(MEM_MANAGER_PORT, + reg_base + IMR_HI_OFFSET, imr.hi.raw); + quarkX1000_msg_bus_write(MEM_MANAGER_PORT, + reg_base + IMR_RDMSK_OFFSET, imr.rdmsk.raw); + quarkX1000_msg_bus_write(MEM_MANAGER_PORT, + reg_base + IMR_WRMSK_OFFSET, imr.wrmsk.raw); + /* This register must be programmed last, in case it sets the lock bit. */ + quarkX1000_msg_bus_write(MEM_MANAGER_PORT, + reg_base + IMR_LO_OFFSET, imr.lo.raw); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/drivers/quarkX1000/imr.h b/cpu/x86/drivers/quarkX1000/imr.h new file mode 100644 index 000000000..f5ddef3e2 --- /dev/null +++ b/cpu/x86/drivers/quarkX1000/imr.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_DRIVERS_QUARKX1000_IMR_H_ +#define CPU_X86_DRIVERS_QUARKX1000_IMR_H_ + +#include + +typedef union quarkX1000_imr_lo { + struct { + uint32_t : 2; + uint32_t addr : 22; + uint32_t : 7; + uint32_t lock : 1; + }; + uint32_t raw; +} quarkX1000_imr_lo_t; + +typedef union quarkX1000_imr_hi { + struct { + uint32_t : 2; + uint32_t addr : 22; + uint32_t : 8; + }; + uint32_t raw; +} quarkX1000_imr_hi_t; + +/* Amount to shift imr_lo/hi.addr left to obtain the bound address */ +#define QUARKX1000_IMR_SHAMT 10 + +typedef union quarkX1000_imr_rdmsk { + struct { + uint32_t cpu0 : 1; + uint32_t cpu_0 : 1; + uint32_t : 6; + uint32_t vc0_sai_id0 : 1; + uint32_t vc0_sai_id1 : 1; + uint32_t vc0_sai_id2 : 1; + uint32_t vc0_sai_id3 : 1; + uint32_t vc1_sai_id0 : 1; + uint32_t vc1_sai_id1 : 1; + uint32_t vc1_sai_id2 : 1; + uint32_t vc1_sai_id3 : 1; + uint32_t : 13; + uint32_t punit : 1; + uint32_t : 1; + uint32_t esram_flush_init : 1; + }; + uint32_t raw; +} quarkX1000_imr_rdmsk_t; + +typedef union quarkX1000_imr_wrmsk { + struct { + uint32_t cpu0 : 1; + uint32_t cpu_0 : 1; + uint32_t : 6; + uint32_t vc0_sai_id0 : 1; + uint32_t vc0_sai_id1 : 1; + uint32_t vc0_sai_id2 : 1; + uint32_t vc0_sai_id3 : 1; + uint32_t vc1_sai_id0 : 1; + uint32_t vc1_sai_id1 : 1; + uint32_t vc1_sai_id2 : 1; + uint32_t vc1_sai_id3 : 1; + uint32_t : 13; + uint32_t punit : 1; + uint32_t cpu_snoop : 1; + uint32_t esram_flush_init : 1; + }; + uint32_t raw; +} quarkX1000_imr_wrmsk_t; + +/* Refer to Intel Quark SoC X1000 Datasheet, Section 12.7.4 for more details on + * the IMR registers. + */ +typedef struct quarkX1000_imr { + quarkX1000_imr_lo_t lo; + quarkX1000_imr_hi_t hi; + quarkX1000_imr_rdmsk_t rdmsk; + quarkX1000_imr_wrmsk_t wrmsk; +} quarkX1000_imr_t; + +/* The Intel Quark SoC X1000 defines eight general IMRs. */ +#define QUARKX1000_IMR_CNT 8 + +/* Routines for accessing the Isolated Memory Region (IMR) feature. + * + * The Intel Quark X1000 SoC includes support for Isolated Memory Regions + * (IMRs), which are specified using range registers and associated + * control registers that are accessible via the message bus. + * + * Refer to Intel Quark SoC X1000 Datasheet, Section 12.2 for more information. + */ + +quarkX1000_imr_t quarkX1000_imr_read(uint32_t imr_idx); +void quarkX1000_imr_write(uint32_t imr_idx, quarkX1000_imr_t imr); + +#endif /* CPU_X86_DRIVERS_QUARKX1000_IMR_H_ */ diff --git a/cpu/x86/drivers/quarkX1000/msg-bus.c b/cpu/x86/drivers/quarkX1000/msg-bus.c new file mode 100644 index 000000000..fc64a6f8c --- /dev/null +++ b/cpu/x86/drivers/quarkX1000/msg-bus.c @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "msg-bus.h" +#include "pci.h" +#include "syscalls.h" + +PROT_DOMAINS_ALLOC(dom_client_data_t, quarkX1000_msg_bus); + +/** Message bus control register */ +#define MCR_PCI_REG_ADDR 0xD0 +/** Message data register */ +#define MDR_PCI_REG_ADDR 0xD4 +/** Message control register extension */ +#define MCRX_PCI_REG_ADDR 0xD8 + +typedef union mcr { + struct { + uint32_t : 4; + uint32_t byte_en : 4; + uint32_t reg_off : 8; + uint32_t port : 8; + uint32_t opcode : 8; + }; + uint32_t raw; +} mcr_t; + +typedef union mcrx { + struct { + uint32_t : 8; + uint32_t reg_off : 24; + }; + uint32_t raw; +} mcrx_t; + +/*---------------------------------------------------------------------------*/ +static void +request_op(uint8_t port, uint32_t reg_off, uint8_t opcode) +{ + pci_config_addr_t pci_addr = { .raw = 0 }; + mcr_t mcr = { .raw = 0 }; + mcrx_t mcrx = { .raw = 0 }; + + pci_addr.reg_off = MCR_PCI_REG_ADDR; + mcr.opcode = opcode; + mcr.byte_en = 0xF; + mcr.port = port; + mcr.reg_off = reg_off & 0xFF; + pci_config_write(pci_addr, mcr.raw); + + pci_addr.reg_off = MCRX_PCI_REG_ADDR; + mcrx.reg_off = reg_off >> 8; + pci_config_write(pci_addr, mcrx.raw); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Read from a message bus register. + * \param port Port of message bus register to be read. + * \param reg_off Register/offset identifier of message bus register to read. + * \param val Storage location for value that has been read. + */ +SYSCALLS_DEFINE_SINGLETON(quarkX1000_msg_bus_read, + quarkX1000_msg_bus, + uint8_t port, + uint32_t reg_off, + uint32_t *val) +{ + uint32_t *loc_val; + pci_config_addr_t pci_addr = { .raw = 0 }; + + PROT_DOMAINS_VALIDATE_PTR(loc_val, val, sizeof(*val)); + + request_op(port, reg_off, 0x10); + + pci_addr.reg_off = MDR_PCI_REG_ADDR; + *loc_val = pci_config_read(pci_addr); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Write to a message bus register. + * \param port Port of message bus register to be written. + * \param reg_off Register/offset identifier of message bus register to write. + * \param val Value to write. + */ +SYSCALLS_DEFINE_SINGLETON(quarkX1000_msg_bus_write, + quarkX1000_msg_bus, + uint8_t port, + uint32_t reg_off, + uint32_t val) +{ + pci_config_addr_t pci_addr = { .raw = 0 }; + + pci_addr.reg_off = MDR_PCI_REG_ADDR; + pci_config_write(pci_addr, val); + + request_op(port, reg_off, 0x11); +} +/*---------------------------------------------------------------------------*/ +void +quarkX1000_msg_bus_init(void) +{ + PROT_DOMAINS_INIT_ID(quarkX1000_msg_bus); + prot_domains_reg(&quarkX1000_msg_bus, 0, 0, 0, 0, true); + SYSCALLS_INIT(quarkX1000_msg_bus_read); + SYSCALLS_AUTHZ(quarkX1000_msg_bus_read, quarkX1000_msg_bus); + SYSCALLS_INIT(quarkX1000_msg_bus_write); + SYSCALLS_AUTHZ(quarkX1000_msg_bus_write, quarkX1000_msg_bus); +} +/*---------------------------------------------------------------------------*/ +void +quarkX1000_msg_bus_lock(void) +{ + SYSCALLS_DEAUTHZ(quarkX1000_msg_bus_read, quarkX1000_msg_bus); + SYSCALLS_DEAUTHZ(quarkX1000_msg_bus_write, quarkX1000_msg_bus); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/drivers/quarkX1000/msg-bus.h b/cpu/x86/drivers/quarkX1000/msg-bus.h new file mode 100644 index 000000000..11bab0849 --- /dev/null +++ b/cpu/x86/drivers/quarkX1000/msg-bus.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_DRIVERS_QUARKX1000_MSG_BUS_H_ +#define CPU_X86_DRIVERS_QUARKX1000_MSG_BUS_H_ + +#include + +/* Routines for accessing the message bus. + * + * The Intel Quark X1000 SoC includes a message bus that is accessible + * via PCI configuration registers. It communicates to various SoC + * components such as the Isolated Memory Region (IMR) registers and the + * Remote Management Unit. + * + * Refer to Intel Quark SoC X1000 Datasheet, Section 12.5 for more details on + * the message bus. + */ + +void quarkX1000_msg_bus_init(void); +void quarkX1000_msg_bus_lock(void); +void quarkX1000_msg_bus_read(uint8_t port, uint32_t reg_off, uint32_t *val); +void quarkX1000_msg_bus_write(uint8_t port, uint32_t reg_off, uint32_t val); + +#endif /* CPU_X86_DRIVERS_QUARKX1000_MSG_BUS_H_ */ diff --git a/cpu/x86/drivers/quarkX1000/uart.c b/cpu/x86/drivers/quarkX1000/uart.c new file mode 100644 index 000000000..341e31cf7 --- /dev/null +++ b/cpu/x86/drivers/quarkX1000/uart.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "uart.h" +#include "uart-16x50.h" +#include + +PROT_DOMAINS_ALLOC(uart_16x50_driver_t, quarkX1000_uart0); +PROT_DOMAINS_ALLOC(uart_16x50_driver_t, quarkX1000_uart1); + +/* Divisor setting for 115200 baud from section 18.2.2 of Intel Quark SoC + * X1000 Datasheet. + */ +#define QUARK_X1000_UART_DL_115200 24 + +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize a UART. + * \param dev Device to initialize. + */ +void +quarkX1000_uart_init(quarkX1000_uart_dev_t dev) +{ + pci_config_addr_t pci_addr; + uart_16x50_driver_t ATTR_KERN_ADDR_SPACE *drv; + + assert((dev == QUARK_X1000_UART_0) || (dev == QUARK_X1000_UART_1)); + + pci_addr.raw = 0; + + /* PCI addresses from section 18.4 of Intel Quark SoC X1000 Datasheet. */ + pci_addr.dev = 20; + pci_addr.func = (dev == QUARK_X1000_UART_0) ? 1 : 5; + pci_addr.reg_off = PCI_CONFIG_REG_BAR0; + + if(dev == QUARK_X1000_UART_0) { + drv = &quarkX1000_uart0; + PROT_DOMAINS_INIT_ID(quarkX1000_uart0); + } else { + drv = &quarkX1000_uart1; + PROT_DOMAINS_INIT_ID(quarkX1000_uart1); + } + uart_16x50_init(drv, pci_addr, QUARK_X1000_UART_DL_115200); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Transmit a character via a UART. + * \param dev Device to use. + * \param c Character to transmit. + */ +void +quarkX1000_uart_tx(quarkX1000_uart_dev_t dev, uint8_t c) +{ + uart_16x50_driver_t drv; + assert((dev == QUARK_X1000_UART_0) || (dev == QUARK_X1000_UART_1)); + prot_domains_copy_dcd(&drv, + (dev == QUARK_X1000_UART_0) ? + &quarkX1000_uart0 : &quarkX1000_uart1); + uart_16x50_tx(drv, c); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/drivers/quarkX1000/uart.h b/cpu/x86/drivers/quarkX1000/uart.h new file mode 100644 index 000000000..8b545d8cd --- /dev/null +++ b/cpu/x86/drivers/quarkX1000/uart.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_DRIVERS_QUARKX1000_UART_H_ +#define CPU_X86_DRIVERS_QUARKX1000_UART_H_ + +#include + +typedef enum { + QUARK_X1000_UART_0, + QUARK_X1000_UART_1 +} quarkX1000_uart_dev_t; + +void quarkX1000_uart_init(quarkX1000_uart_dev_t dev); +void quarkX1000_uart_tx(quarkX1000_uart_dev_t dev, uint8_t c); + +#endif /* CPU_X86_DRIVERS_QUARKX1000_UART_H_ */ diff --git a/cpu/x86/helpers.S b/cpu/x86/helpers.S new file mode 100644 index 000000000..c1c73130f --- /dev/null +++ b/cpu/x86/helpers.S @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +.text + +.global halt +halt: + cli +die: hlt + jmp die + +.global outb +outb: + mov 4(%esp), %dx + mov 8(%esp), %al + out %al, %dx + ret + +.global outl +outl: + mov 4(%esp), %dx + mov 8(%esp), %eax + out %eax, %dx + ret + +.global inb +inb: + mov 4(%esp), %dx + in %dx, %al + ret + +.global inl +inl: + mov 4(%esp), %dx + in %dx, %eax + ret diff --git a/cpu/x86/helpers.h b/cpu/x86/helpers.h new file mode 100644 index 000000000..1ef312e14 --- /dev/null +++ b/cpu/x86/helpers.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef HELPERS_H +#define HELPERS_H + +#include + +#define BIT(n) (1UL << (n)) + +void halt(void) __attribute__((__noreturn__)); + +#define STRINGIFY(x) #x +/* The C preprocessor will not expand macro arguments that are converted to + * strings in the macro body using the '#' operator. The EXP_STRINGIFY macro + * introduces an additional level of argument expansion for instances where + * the developer wishes to convert the expanded argument to a string. + */ +#define EXP_STRINGIFY(x) STRINGIFY(x) + +#define ALIGN(x, amt) \ + (((x) & ~((amt) - 1)) + ((((x) & ((amt) - 1)) == 0) ? 0 : (amt))) + +/** Wrappers for the assembly 'out' instruction. */ +void outb(uint16_t port, uint8_t val); +void outl(uint16_t port, uint32_t val); + +/** Wrappers for the assembly 'in' instruction */ +uint8_t inb(uint16_t port); +uint32_t inl(uint16_t port); + +#endif /* HELPERS_H */ diff --git a/cpu/x86/init/common/cpu.c b/cpu/x86/init/common/cpu.c new file mode 100644 index 000000000..dd58b96d5 --- /dev/null +++ b/cpu/x86/init/common/cpu.c @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "cpu.h" +#include "gdt.h" +#include "helpers.h" +#include "idt.h" +#include "interrupt.h" +#include "irq.h" +#include "stacks.h" + +static void +double_fault_handler(struct interrupt_context context) +{ + halt(); +} +/*---------------------------------------------------------------------------*/ +/* The OS has switched to its own segment descriptors. When multi-segment + * protection domain support is enabled, this routine runs with the + * necessary address translations configured to invoke other routines that + * require those translations to be in place. However, the protection domain + * support, if enabled, has not yet been fully activated. + */ +static void +boot_stage1(void) +{ + idt_init(); + + /* Set an interrupt handler for Double Fault exception. This way, we avoid + * the system to triple fault, leaving no trace about what happened. + */ + SET_EXCEPTION_HANDLER(8, 1, double_fault_handler); + + /* Initialize protection domain support, if enabled */ + prot_domains_init(); + + prot_domains_leave_boot_stage1(); +} +/*---------------------------------------------------------------------------*/ +int main(void); +/* This routine runs with the initial, flat address space, even if protection + * domain support is enabled. The goal behind the design of this routine is to + * keep it as short as possible, since it is unable to directly reference data + * and invoke functions that are intended to be accessible later after the + * system has booted when a multi-segment protection domain model is in use. + */ +void +cpu_boot_stage0(void) +{ + /* Reserve three stack slots for return addresses */ + uintptr_t top_of_stack = STACKS_INIT_TOP; + +#if X86_CONF_PROT_DOMAINS != X86_CONF_PROT_DOMAINS__NONE + uintptr_t *top_of_stack_ptr = + (uintptr_t *)DATA_OFF_TO_PHYS_ADDR(top_of_stack); + + top_of_stack_ptr[0] = (uintptr_t)prot_domains_launch_kernel; + top_of_stack_ptr[1] = (uintptr_t)prot_domains_launch_app; +#endif + + /* Perform common GDT initialization */ + gdt_init(); + + /* Switch all data segment registers to the newly-initialized flat data + * descriptor. + */ + __asm__( + "mov %0, %%ds\n\t" + "mov %0, %%es\n\t" + "mov %0, %%fs\n\t" + "mov %0, %%gs\n\t" + : + : "r" (GDT_SEL_DATA_FLAT) + ); + + /** + * Perform specific GDT initialization tasks for the protection domain + * implementation that is enabled, if any. + */ + prot_domains_gdt_init(); + + /* Do not pass memory operands to the asm block below, since it is + * switching from the flat address space to a multi-segment address space + * model if such a model is used by the enabled protection domain + * implementation, if any. + */ + __asm__( + "mov %[_ss_], %%ss\n\t" + "mov %[_esp_], %%esp\n\t" + "ljmp %[_cs_], %[_stage1_]\n\t" + : + : [_ss_] "r" (GDT_SEL_STK_EXC), + [_esp_] "r" (top_of_stack), + [_cs_] "i" ((uint16_t)GDT_SEL_CODE_EXC), + [_stage1_] "i" (boot_stage1) + ); +} diff --git a/cpu/x86/init/common/cpu.h b/cpu/x86/init/common/cpu.h new file mode 100644 index 000000000..4fd9b835b --- /dev/null +++ b/cpu/x86/init/common/cpu.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_H +#define CPU_H + +#include "prot-domains.h" + +void cpu_boot_stage0(void) ATTR_CODE_BOOT; + +#endif /* CPU_H */ diff --git a/cpu/x86/init/common/gdt.c b/cpu/x86/init/common/gdt.c new file mode 100644 index 000000000..f63767850 --- /dev/null +++ b/cpu/x86/init/common/gdt.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include +#include "gdt.h" +#include "gdt-layout.h" +#include "helpers.h" +#include "prot-domains.h" +#include "segmentation.h" + +#define GDT_MEM_PL0 (SEG_DESCTYPE_NSYS | SEG_GRAN_PAGE) +#define GDT_CODE_PL0 (GDT_MEM_PL0 | SEG_TYPE_CODE_EXRD) +#define GDT_DATA_PL0 (GDT_MEM_PL0 | SEG_TYPE_DATA_RDWR) + +typedef struct gdtr +{ + uint16_t limit; + uint32_t base; +} __attribute__((packed)) gdtr_t; + +/* From Intel Combined Manual, Vol. 3 , Section 3.5.1: The base addresses of + * the GDT should be aligned on an eight-byte boundary to yield the best + * processor performance. + */ +segment_desc_t __attribute__ ((aligned(8))) ATTR_BSS_GDT_START + gdt[GDT_NUM_FIXED_DESC]; + +#define GDT_LEN \ + ((((uintptr_t)&_ebss_gdt_addr) - \ + (uintptr_t)gdt)/sizeof(segment_desc_t)) + +/*---------------------------------------------------------------------------*/ +static void ATTR_CODE_BOOT +set_descriptor(unsigned int index, + uint32_t base, + uint32_t len, + uint16_t flag) +{ + segment_desc_t descriptor; + + if(GDT_LEN <= index) { + halt(); + } + + segment_desc_init(&descriptor, base, len, flag); + + /* Save descriptor into gdt */ + gdt_insert_boot(index, descriptor); +} +/*---------------------------------------------------------------------------*/ +void +gdt_copy_desc_change_dpl(unsigned int dest_idx, + unsigned int src_idx, + unsigned dpl) +{ + segment_desc_t desc; + + if((GDT_LEN <= dest_idx) || (GDT_LEN <= src_idx)) { + halt(); + } + + gdt_lookup(src_idx, &desc); + SEG_SET_FLAG(desc, DPL, dpl); + gdt_insert(dest_idx, desc); +} +/*---------------------------------------------------------------------------*/ +/* This function initializes the Global Descriptor Table. For simplicity, the + * memory is initially organized following the flat model. Thus, memory appears + * to Contiki as a single continuous address space. Code, data, and stack + * are all contained in this address space (so called linear address space). + * Certain protection domain implementations switch to a multi-segment memory + * model later during boot. + */ +void +gdt_init(void) +{ + gdtr_t gdtr; + + /* Initialize gdtr structure */ + gdtr.limit = sizeof(segment_desc_t) * GDT_LEN - 1; + gdtr.base = KERN_DATA_OFF_TO_PHYS_ADDR(gdt); + + /* Initialize descriptors */ + set_descriptor(GDT_IDX_NULL, 0, 0, 0); + set_descriptor(GDT_IDX_CODE_FLAT, 0, 0x100000, GDT_CODE_PL0); + set_descriptor(GDT_IDX_DATA_FLAT, 0, 0x100000, GDT_DATA_PL0); + + /* Load GDTR */ + __asm__ __volatile__ ("lgdt %0" :: "m" (gdtr)); +} +/*---------------------------------------------------------------------------*/ +void +gdt_insert_boot(unsigned int idx, segment_desc_t desc) +{ + ((segment_desc_t *)KERN_DATA_OFF_TO_PHYS_ADDR(gdt))[idx] = desc; +} +/*---------------------------------------------------------------------------*/ +void +gdt_insert(unsigned int idx, segment_desc_t desc) +{ + if(GDT_LEN <= idx) { + halt(); + } + + KERN_WRITEL(gdt[idx].raw_lo, desc.raw_lo); + KERN_WRITEL(gdt[idx].raw_hi, desc.raw_hi); +} +/*---------------------------------------------------------------------------*/ +void +gdt_lookup(unsigned int idx, segment_desc_t *desc) +{ + if((GDT_LEN <= idx) || (desc == NULL)) { + halt(); + } + + KERN_READL(desc->raw_lo, gdt[idx].raw_lo); + KERN_READL(desc->raw_hi, gdt[idx].raw_hi); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/init/common/gdt.h b/cpu/x86/init/common/gdt.h new file mode 100644 index 000000000..305e32716 --- /dev/null +++ b/cpu/x86/init/common/gdt.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef GDT_H +#define GDT_H + +#include "gdt-layout.h" +#include "prot-domains.h" +#include "segmentation.h" + +extern segment_desc_t ATTR_KERN_ADDR_SPACE gdt[]; +extern int ATTR_KERN_ADDR_SPACE _ebss_gdt_addr; + +#define GDT_IDX_OF_DESC(ptr) \ + ((((uintptr_t)(ptr)) - ((uintptr_t)&gdt))/ \ + sizeof(segment_desc_t)) + +typedef struct far_pointer { + /** Far pointer offset. */ + uint32_t offset; + /** Far pointer segment/gate selector. */ + uint16_t sel; + uint16_t pad; +} __attribute__((packed)) far_pointer_t; + +/** + * \brief Compute the selector for a GDT entry allocated somewhere besides gdt.c. + * \param ptr Pointer to GDT descriptor. + * \param rpl Requested Privilege Level. + */ +#define GDT_SEL_OF_DESC(ptr, rpl) GDT_SEL(GDT_IDX_OF_DESC(ptr), rpl) + +/* Section for fixed GDT entries */ +#define ATTR_BSS_GDT \ + __attribute__((section(".gdt_bss"))) ATTR_KERN_ADDR_SPACE +/* Section for TSS and LDT descriptors for protection domains */ +#define ATTR_BSS_GDT_MID \ + __attribute__((used, section(".gdt_bss_mid"))) ATTR_KERN_ADDR_SPACE +/* Section for other GDT entries */ +#define ATTR_BSS_GDT_START \ + __attribute__((section(".gdt_bss_start"))) ATTR_KERN_ADDR_SPACE + +void gdt_copy_desc_change_dpl(unsigned int dest_idx, + unsigned int src_idx, + unsigned dpl); +void gdt_init(void) ATTR_CODE_BOOT; +void gdt_insert(unsigned int idx, segment_desc_t desc); +void gdt_insert_boot(unsigned int idx, segment_desc_t desc) ATTR_CODE_BOOT; +void gdt_lookup(unsigned int idx, segment_desc_t *desc); + +#endif /* GDT_H */ diff --git a/cpu/x86/init/common/idt.c b/cpu/x86/init/common/idt.c new file mode 100644 index 000000000..c5de5ed25 --- /dev/null +++ b/cpu/x86/init/common/idt.c @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "gdt-layout.h" +#include "prot-domains.h" +#include + +#include "helpers.h" +#include "segmentation.h" +#include "idt.h" + +#define NUM_DESC 256 + +typedef struct idtr { + uint16_t limit; + uint32_t base; +} __attribute__((packed)) idtr_t; + +typedef union intr_gate_desc { + struct __attribute__((packed)) { + uint16_t offset_low; + uint16_t selector; /* Segment Selector for destination code segment */ + uint16_t fixed:11; + uint16_t d:1; /* Size of gate: 1 = 32 bits; 0 = 16 bits */ + uint16_t pad:1; + uint16_t dpl:2; /* Descriptor Privilege Level */ + uint16_t p:1; /* Segment Present flag */ + uint16_t offset_high; + }; + uint64_t raw; + struct { + uint32_t raw_lo; + uint32_t raw_hi; + }; +} intr_gate_desc_t; + +/* According to Intel Combined Manual, Vol. 3, Section 6.10, the base addresses + * of the IDT should be aligned on an 8-byte boundary to maximize performance + * of cache line fills. + */ +static intr_gate_desc_t __attribute__((aligned(8))) ATTR_BSS_KERN + idt[NUM_DESC]; + +/*---------------------------------------------------------------------------*/ +/* XXX: If you change this function prototype, make sure you fix the assembly + * code in SET_INT_EXC_HANDLER macro in interrupt.h. Otherwise, you might + * face a very-hard-to-find bug in the interrupt handling system. + */ +void +idt_set_intr_gate_desc(int intr_num, + uint32_t offset, + uint16_t cs, + uint16_t dpl) +{ + intr_gate_desc_t desc; + + desc.offset_low = offset & 0xFFFF; + desc.selector = cs; + desc.fixed = BIT(9) | BIT(10); + desc.pad = 0; + desc.d = 1; + desc.dpl = dpl; + desc.p = 1; + desc.offset_high = (offset >> 16) & 0xFFFF; + + KERN_WRITEL(idt[intr_num].raw_hi, desc.raw_hi); + KERN_WRITEL(idt[intr_num].raw_lo, desc.raw_lo); +} +/*---------------------------------------------------------------------------*/ +/* Initialize Interrupt Descriptor Table. The IDT is initialized with + * null descriptors. Therefore, any interrupt at this point will cause + * a triple fault. + */ +void +idt_init(void) +{ + idtr_t idtr; + + /* Initialize idtr structure */ + idtr.limit = (sizeof(intr_gate_desc_t) * NUM_DESC) - 1; + idtr.base = KERN_DATA_OFF_TO_PHYS_ADDR((uint32_t)idt); + + /* Load IDTR register */ + __asm__("lidt %0\n\t" :: "m" (idtr)); +} diff --git a/cpu/x86/init/common/idt.h b/cpu/x86/init/common/idt.h new file mode 100644 index 000000000..059e81705 --- /dev/null +++ b/cpu/x86/init/common/idt.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef IDT_H +#define IDT_H + +#include +#include "prot-domains.h" + +void idt_init(void); +void idt_set_intr_gate_desc(int intr_num, + uint32_t offset, + uint16_t cs, + uint16_t dpl); + +#endif /* IDT_H */ diff --git a/cpu/x86/init/common/interrupt.h b/cpu/x86/init/common/interrupt.h new file mode 100644 index 000000000..10b906be4 --- /dev/null +++ b/cpu/x86/init/common/interrupt.h @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef INTERRUPT_H +#define INTERRUPT_H + +#include +#include "gdt-layout.h" + +#include "idt.h" + +struct interrupt_context { + /* The general-purpose register values are saved by the pushal instruction in + * the interrupt dispatcher. Having access to these saved values may be + * useful in some future interrupt or exception handler, and saving and later + * restoring them also enables the ISR to freely overwrite the EAX, ECX, and + * EDX registers as is permitted by the cdecl calling convention. + */ + uint32_t edi; + uint32_t esi; + uint32_t ebp; + uint32_t esp; + uint32_t ebx; + uint32_t edx; + uint32_t ecx; + uint32_t eax; + /* These two values are pushed on the stack by the CPU when it delivers an + * exception with an associated error code. Currently, only the double fault + * handler accepts this structure as a parameter, and that type of exception + * does have an associated error code. + */ + uint32_t error_code; + uint32_t eip; + /* The CPU pushes additional values beyond these on the stack, specifically + * the code segment descriptor and flags. If a privilege-level change occurs + * during delivery, the CPU additionally pushes the stack pointer and stack + * segment descriptor. + */ +}; + +#define ISR_STUB(label_str, has_error_code, handler_str, exc) \ + "jmp 2f\n\t" \ + ".align 4\n\t" \ + label_str ":\n\t" \ + " pushal\n\t" \ + PROT_DOMAINS_ENTER_ISR(exc) \ + " call " handler_str "\n\t" \ + PROT_DOMAINS_LEAVE_ISR(exc) \ + " popal\n\t" \ + " .if " #has_error_code "\n\t" \ + " add $4, %%esp\n\t" \ + " .endif\n\t" \ + " iret\n\t" \ + "2:\n\t" + +/* Helper macro to register interrupt handler function. + * + * num: Interrupt number (0-255) + * has_error_code: 0 if interrupt doesn't push error code onto the + * stack. Otherwise, set this argument to 1. + * handler: Pointer to function that should be called once the + * interrupt is raised. In case has_error_code == 0 + * the function prototype should be the following: + * void handler(void) + * Otherwise, it should be: + * void handler(struct interrupt_context context) + * exc: 0 if this is an interrupt, which should be handled + * at the interrupt privilege level. 1 if this is an + * exception, which should be handled at the + * exception privilege level. + * dpl: Privilege level for IDT descriptor, which is the + * numerically-highest privilege level that can + * generate this interrupt with a software interrupt + * instruction. + * + * Since there is no easy way to write an Interrupt Service Routines + * (ISR) in C (for further information on this, see [1]), we provide + * this helper macro. It basically provides an assembly trampoline + * to a C function (handler parameter) which, indeed, handles the + * interrupt. + * + * [1] http://wiki.osdev.org/Interrupt_Service_Routines + */ +#define SET_INT_EXC_HANDLER(num, has_error_code, handler, exc, dpl) \ + do { \ + __asm__ __volatile__ ( \ + "pushl %[_dpl_]\n\t" \ + "pushl %[_cs_]\n\t" \ + "pushl $1f\n\t" \ + "pushl %[_isr_num_]\n\t" \ + "call idt_set_intr_gate_desc\n\t" \ + "add $16, %%esp\n\t" \ + ISR_STUB("1", has_error_code, "%P[_handler_]", exc) \ + : \ + : [_isr_num_] "g" (num), \ + [_handler_] "i" (handler), \ + [_cs_] "i" (exc ? GDT_SEL_CODE_EXC : GDT_SEL_CODE_INT), \ + [_dpl_] "i" (dpl) \ + /* the invocation of idt_set_intr_gate_desc may clobber */ \ + /* the caller-saved registers: */ \ + : "eax", "ecx", "edx" \ + ); \ + } while (0) +#define SET_INTERRUPT_HANDLER(num, has_error_code, handler) \ + SET_INT_EXC_HANDLER(num, has_error_code, handler, 0, PRIV_LVL_INT) +#define SET_EXCEPTION_HANDLER(num, has_error_code, handler) \ + SET_INT_EXC_HANDLER(num, has_error_code, handler, 1, PRIV_LVL_EXC) + +/* Disable maskable hardware interrupts */ +#define DISABLE_IRQ() \ + do { \ + __asm__ ("cli"); \ + } while (0) + +/* Enable maskable hardware interrupts */ +#define ENABLE_IRQ() \ + do { \ + __asm__ ("sti"); \ + } while (0) + +#endif /* INTERRUPT_H */ diff --git a/cpu/x86/init/common/irq.h b/cpu/x86/init/common/irq.h new file mode 100644 index 000000000..94af19b74 --- /dev/null +++ b/cpu/x86/init/common/irq.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef IRQ_H +#define IRQ_H + +void irq_init(void); + +#endif /* IRQ_H */ diff --git a/cpu/x86/init/legacy_pc/irq.c b/cpu/x86/init/legacy_pc/irq.c new file mode 100644 index 000000000..04cfa1c13 --- /dev/null +++ b/cpu/x86/init/legacy_pc/irq.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "drivers/legacy_pc/pic.h" +#include "interrupt.h" +#include "irq.h" + +#define IRQ7_INT PIC_INT(7) + +static void +spurious_irq7_handler(void) +{ + /* + * NOTE: Originally IRQ7 was used for the parallel port interrupts. Nowadays, + * though, it is only used if some other IRQ (i.e.: a PCIx interrupt) is + * mapped to it. In this case we will have to check the PIC ISR register in + * order to confirm this was a real interrupt. + * + * In case of a spurious interrupt, we should NEVER send an EOI here so the PIC + * doesn't trigger the next queued interrupt. + */ +} +/*---------------------------------------------------------------------------*/ +void +irq_init(void) +{ + pic_init(); + + /* Set a 'fake' handler for the Spurious IRQ7 interrupts. + * Refer to http://wiki.osdev.org/PIC . + */ + SET_INTERRUPT_HANDLER(IRQ7_INT, 0, spurious_irq7_handler); +} diff --git a/cpu/x86/mm/README.md b/cpu/x86/mm/README.md new file mode 100644 index 000000000..42c4070a7 --- /dev/null +++ b/cpu/x86/mm/README.md @@ -0,0 +1,997 @@ +X86 Lightweight Protection Domain Support for Contiki +===================================================== + +Introduction +------------ + +The X86 port of Contiki implements a simple, lightweight form of +protection domains using a pluggable framework. Currently, there are +three plugins available: + + - Flat memory model with paging. + - Multi-segment memory model with either hardware- or + software-switched segments. The hardware-switched segments + approach is based on Task-State Segment (TSS) structures. + +For an introduction to paging and TSS and possible ways in which they +can be used, refer to the following resources: + + - Intel Combined Manual (Intel 64 and IA-32 Architectures Software + Developer's Manual), Vol. 3, Chapter 4 + - Programming the 80386, by John H. Crawford and Patrick + P. Gelsinger, Chapter 5 + +The overall goal of a protection domain implementation within this +framework is to define a set of resources that should be accessible to +each protection domain and to prevent that protection domain from +accessing other resources. The details of each implementation of +protection domains may differ substantially, but they should all be +guided by the principle of least privilege [1]. However, that +idealized principle is balanced against the practical objectives of +limiting the number of relatively time-consuming context switches and +minimizing changes to existing code. In fact, no changes were made to +code outside of the CPU- and platform-specific code directories for +the initial plugins. + +Each protection domain can optionally be associated with a metadata +and/or MMIO region. The hardware can support additional regions per +protection domain, but that would increase complexity and is unneeded +for the existing protection domains. + +After boot, all code runs in the context of some protection domain. +Two default protection domains are implemented: + +- kern: Kernel protection domain that is more privileged than any + other protection domain. As little code as possible should be placed + in this protection domain. +- app: Application protection domain used whenever special privileges + are not required. + +Additional protection domains are defined as needed. For example, +each driver may reside in a separate protection domain, although not +all drivers require additional privileges beyond those available in +the relevant scheduling context in the app protection domain. The +Ethernet and UART drivers are assigned separate protection domains. +Non-driver protection domains can also be defined. Other drivers only +require access to programmed IO ports accessible via the IN* and OUT* +instructions, and such drivers do not require separate protection +domains. They run in the Contiki preemptive scheduling context and +the kernel protection domain, both of which are granted access to all +IO ports. + +Each protection domain may have associated system calls. A system +call transfers control from a client protection domain to a defined +entrypoint in a server protection domain. As their name suggests, +system calls adhere to a synchronous call-return model (rather than +some alternative such as an asynchronous message-passing model). To +invoke a system call, the client provides two identifiers to the +system call dispatcher. The first identifies the server domain and +the second identifies the system call to be invoked. The protection +domain implementation should associate allowable system calls with +particular server protection domains and reject any system call +requests that are not within that set of allowable system calls. The +system call implementations do not restrict the clients that are +permitted to invoke each system call. No modifications that the +client can make to the server domain and system call identifiers can +open up new entrypoints into the server domain. The entrypoints are +fixed at boot time. + +However, if the identifiers were stored in shared memory, it may be +possible for a protection domain to influence the system calls issued +by some other protection domain, which may be undesirable. Thus, the +server domain identifiers are stored in memory that can only be +written by the kernel protection domain and the system call +identifiers are embedded in the code. + +The system call dispatcher is responsible for reconfiguring the system +to enforce the appropriate resource access controls for the server +protection domain. It should then transfer control to the approved +entrypoint for the requested system call. + +Contiki defines a process concept that is orthogonal to protection +domains [2]. A single Contiki process may run code in multiple +protection domains at various points in time. Contiki processes run +in a cooperative scheduling context. Contiki also defines a +preemptive scheduling context for interrupt handlers and real-time +timers. When protection domain support is enabled, interrupts are +only enabled when the application protection domain is active and is +running code in the cooperative scheduling context. Code running in +the preemptive context may also invoke multiple protection domains. +Contiki can also support preemptive multithreading, but support for +that has not yet been added to the X86 port so we do not discuss it +further. + +A single stack is shared by all code that runs in the cooperative +scheduling context in all protection domains, and separate stacks are +defined for short interrupt dispatchers in the preemptive scheduling +context and for exception handlers and software system call +dispatchers. Except for the interrupt dispatchers, code in the +preemptive scheduling context also shares the same stack with the +cooperative scheduling context. All protection domains also share a +main data section, so similar considerations are also relevant to +that. + +Introducing multi-core support would complicate things further, since +another core running a protection domain that the first core never +invoked could access data from the protection domain on the first +core. It may be possible to adequately address such concerns by +allocating per-core stacks. + +Note that this stack arrangement means that a given protection domain +may read and write data written to the stack by some other protection +domain. For example, a protection domain B may push data onto the +stack and later pop that data off of the stack, but a protection +domain A that invoked protection domain B may still be able to read +the data that was pushed and popped to and from the stack, since +popping the data off of the stack does not automatically erase that +stack memory location. Another possibility is that protection domain +B may modify a stack entry pushed by protection domain A before it +invoked protection domain B, and protection domain A may later use the +modified value. Permitting legitimate accesses to callers' stacks is +in fact the primary motivation for this stack arrangement, in that it +makes it simple for A to pass data to and from B (on the shared stack) +when requesting services from B. A system call invocation is nearly +transparent to the developer, appearing almost identical to an +ordinary function call. However, B can access any data on the stack. +The third case is that A can read data placed on the stack by B after +B returns, unless B wipes that data from the stack before returning. +A related sub-case is that if an interrupt handler is invoked, it +pushes the current contents of the general-purpose registers onto the +stack, which may then be revealed to other protection domains besides +the one that was interrupted. However, interrupts are only actually +enabled in the application protection domain. + +Similarly, register contents may be accessed and modified across +protection domain boundaries in some protection domain +implementations. The TSS task switching mechanism automatically saves +and restores many registers to and from TSS data structures when +switching tasks, but the other protection domain implementations do +not perform analogous operations. + +For the reasons described above, each protection domain should only +invoke other protection domains that it trusts to properly handle data +on the stack. + +Design +------ + +### Boot Process + +The system boots in the following phases. + +#### UEFI Bootstrap + +Primary implementation sources: + + - cpu/x86/uefi/bootstrap_uefi.c + +When the OS is compiled as a UEFI binary, a short bootstrap phase that +is UEFI-compliant is run initially. It simply performs a minimal set +of functions to exit the UEFI boot services and then transfer control +to the Multiboot bootstrap phase. + +#### Multiboot Bootstrap + +Primary implementation sources: + + - cpu/x86/bootstrap_quarkX1000.S + +This phase disables interrupts, sets the stack pointer to the top of +the main stack, and then invokes boot stage 0. + +#### Boot Stage 0 + +Primary implementation sources: + + - cpu/x86/init/common/cpu.c + - cpu/x86/init/common/gdt.c + +The UEFI firmware or Multiboot-compliant bootloader should have +configured an initial Global Descriptor Table (GDT) with flat segments +and configured the CPU to operate in protected mode with paging +disabled. Flat segments each map the whole 4GiB physical memory +space. This is the state of the system when the OS enters boot stage +0. This stage is responsible for setting up a new GDT and loading the +segment registers with the appropriate descriptors from the new GDT to +enable boot stage 1 to run. Code in stage 1 for multi-segment +protection domain implementations require that the appropriate +segment-based address translations be configured. + +#### Boot Stage 1 + +Primary implementation sources: + + - cpu/x86/init/common/cpu.c + - cpu/x86/init/common/idt.c + - cpu/x86/mm/prot-domains.c + +Boot stage 1 intializes the Interrupt Descriptor Table (IDT) and +installs a handler for double-fault exceptions. Handlers for +additional interrupts and exceptions are installed later in boot +stages 1 and 2. + +This stage also initializes protection domain support and enters the +kernel protection domain. + +#### Boot Stage 2 + +Primary implementation sources: + + - cpu/x86/init/common/cpu.c + - platform/galileo/contiki-main.c + +The entrypoint for the kernel protection domain is 'main'. Boot stage +2 initializes hardware devices and associated interrupts. It then +transfers control to the application protection domain. Note that +this is a transfer of control, not a call that would be matched with +some future return. This is an important distinction, because +protection domains are not reentrant. Thus, if the kernel protection +domain called the application protection domain, it would not be +possible to invoke any kernel system calls until the system is reset, +since the application protection domain never exits/returns while the +system is running. There are not actually any kernel system calls +provided in the initial implementation of protection domains, but they +may be added in the future. + +The core protection domain configuration (e.g. allowable system calls +and entrypoints, registered protection domains, etc.) is frozen by the +conclusion of boot stage 2 to help prevent erroneous changes that +could reduce the robustness of the system. The way that it is frozen +is that there are no kernel system calls that are intended to permit +changes to the core protection domain configuration. Thus, once the +kernel protection domain has exited, the only way the core protection +domain configuration can change would be due to undesirable memory +manipulations (e.g. due to a faulty device driver). + +#### Boot Stage 3 + +Primary implementation sources: + + - platform/galileo/contiki-main.c + +Boot stage 3 performs initialization procedures that are less +tightly-coupled to hardware. For example, it launches Contiki +processes and invokes Contiki configuration routines. + +### Privilege Levels + +When protection domain support is inactive, all code runs at +ring/privilege level 0. When protection domain support is active, +only exception handlers and system call dispatchers (including +dispatchers for system call returns) run at ring level 0. Code in the +preemptive scheduling context runs at ring level 2 and code in the +cooperative scheduling context runs at ring level 3. Ring levels with +higher numbers are less privileged than those with lower numbers. +Ring level 1 is unused. + +### IO and Interrupt Privileges + +The kernel protection domain cooperative scheduling context needs +access to IO ports, for device initialization. Some other protection +domains also require such access. The IO Privilege Level (IOPL) that +is assigned to a protection domain using the relevant bits in the +EFLAGS field could be set according to whether IO port access is +required in that protection domain. This is straightforward for TSS, +which includes separate flags settings for each protection domain. +However, this would introduce additional complexity and overhead in +the critical system call and return dispatchers for other plugins. +Instead, the IOPL is always set to block IO access from the +cooperative scheduling context. Port IO instructions in that context +will then generate general protection faults, and the exception +handler decodes and emulates authorized port IO instructions. + +Interrupts are handled at ring level 2, since they do not use any +privileged instructions. They do cause the interrupt flag to be +cleared as they are delivered. The interrupt flag can only be +modified by instructions executing at a ring level that is numerically +less than or equal to the IOPL. Each interrupt handler needs to set +the interrupt flag using the IRET instruction when it returns. +Protection domains that require access to port IO (currently just the +kernel protection domain) are configured with an IOPL of 3 whereas +others are configured with an IOPL of 2. That is why interrupts are +configured to run at ring level 2. Interrupts are only enabled in the +application protection domain. + +Some interrupt handlers require access to port IO, and all are +permitted such access, since they need it anyway for restoring the +interrupt flag when returning. IO port access is a very powerful +privilege, since it can be used to remap MMIO regions of PCI devices, +reconfigure PCI devices, etc. Thus, further restricting access to IO +ports may improve the robustness of the system, but would increase +complexity and space requirements and possibly necessitate additional +context switches, since IO port access is controlled by the combined +settings of IOPL as well as an optional IO bitmap in the TSS. + +### Interrupt and Exception Dispatching + +Primary implementation sources: + - cpu/x86/init/common/interrupt.h + +Separate stacks are allocated for dispatching interrupts and +exceptions. However, to save space, the main bodies of some interrupt +and exception handlers are run on the main stack. A handler may +expect to have access to data from the interrupt or exception stack, +so the interrupt or exception dispatcher copies that data prior to +pivoting to the main stack and executing the handler. + +### Protection Domain Control Structures (PDCSes) + +Each protection domain is managed by the kernel and privileged +functions using a PDCS. The structure of the PDCS is partially +hardware-imposed in the cases of the two segment-based plugins, since +the PDCS contains the Local Descriptor Table (LDT) and the TSS, if +applicable. In the paging plugin, the PDCS structure is entirely +software-defined. None of the initial protection domain plugins +support re-entrant protection domains due to hardware-imposed +limitations of TSS and to simplify the implementation of the other +plugins by enabling domain-specific information (e.g. system call +return address) to be trivially stored in each PDCS. + +### Paging-Based Protection Domains + +Primary implementation sources: + + - cpu/x86/mm/paging-prot-domains.c + - cpu/x86/mm/syscalls-int.c + - cpu/x86/mm/syscalls-int-asm.S + +#### Introduction + +Only a single page table is used for all protection domains. A flat +memory model is used. Almost all linear-to-physical address mappings +are identity mappings, with the exceptions being the MMIO and metadata +regions. The X86 port of Contiki currently only supports at most one +MMIO and one metadata range per driver, and the paging-based +protection domain implementation always starts at particular linear +addresses when mapping an MMIO or metadata range. This may reduce +overhead, due to the way protection domain switches are implemented. + +#### System Call and Return Dispatching + +The system call dispatcher executes at ring level 0, since it uses the +privileged INVLPG or MOV CR3 instructions to invalidate TLB entries. +The dispatcher modifies page table entries to grant only the +permissions required by the protection domain being activated. It +then optionally uses the INVLPG instruction to invalidate any TLB +entries for any page table entries that were modified. If INVLPG is +not used to invalidate specific TLB entries, then CR3 is reloaded to +invalidate the entire TLB (global entries would be excluded, but they +are not used in this implementation). + +It is more efficient to always start at a particular linear address +when mapping an MMIO or metadata region, since the page table entries +for that region can be updated to unmap any previous region of that +type, map the new region, and then invalidated to cause the new +settings to take effect. The alternative using an identity +linear-to-physical address mapping for regions would be to unmap the +previous region by editing one set of page table entries and to then +map the new region by editing a different set of page table entries +and to finally perform invalidations for both sets of page table +entries. Another drawback of such an identity address mapping is that +additional page tables may need to be allocated to represent the +various MMIO regions, since page tables are indexed by linear address +and MMIO regions are often at high physical addresses. Note that this +is specific to MMIO regions, since metadata regions are not at +particularly high physical addresses. Additionally, if different base +linear addresses are used, it is necessary to communicate those to the +system call handler code so that the regions can be accessed. This +would require care to prevent an adversary from manipulating the +addresses and it may increase complexity. + +The overall process of handling a system call can be illustrated at a +high level as follows. Some minor steps are omitted in the interest +of clarity and brevity. + +``` + == BEGIN Client protection domain ========================================== + -- BEGIN Caller ------------------------------------------------------------ + 1. Call system call stub. + -- + 20. Continue execution... + -- END Caller -------------------------------------------------------------- + -- BEGIN System call stub -------------------------------------------------- + 2. Already in desired (server) protection domain? + - No: Issue software interrupt #100 to request system call. + - Yes: Jump to system call body. + -- END System call stub ---------------------------------------------------- + == END Client protection domain ============================================ + == BEGIN Ring level 0 ====================================================== + -- BEGIN System call dispatcher--------------------------------------------- + 3. Check that the requested system call is allowed. Get entrypoint. + 4. Check that the server protection domain is available (not yet present + in the protection domain call stack) and then mark it as busy. + 5. Save the caller return address from the main stack into the client + PDCS. + 6. Overwrite the caller return address on the main stack to point to + system call return stub. + 7. Push server protection domain onto protection domain call stack. + 8. Update the interrupt return stack EIP to start of system call body. + 9. Update and invalidate page table entries to grant only the permissions + required by the server protection domain. + 10. Update interrupt flag to disable interrupts, since interrupts are only + enabled in app protection domain, which exports no system calls. + 11. Perform interrupt return (IRET). + -- END System call dispatcher ---------------------------------------------- + -- BEGIN System call return dispatcher ------------------------------------- + 15. Mark protection domain on top of protection domain call stack as + available. + 16. Retrieve the caller return address from the kernel data structure for + the client protection domain and use it to overwrite the EIP in the + interrupt return stack. + 17. Update and invalidate page table entries to grant only the permissions + required by the client protection domain. + 18. Update interrupt flag to only enable interrupts if returning to app + protection domain cooperative scheduling context. + 19. Perform interrupt return (IRET). + -- END System call dispatcher ---------------------------------------------- + == END Ring level 0 ======================================================== + == BEGIN Server protection domain ========================================== + -- BEGIN System call body -------------------------------------------------- + 12. Execute the work for the requested system call. + 13. Return (to system call return stub, unless invoked from server + protection domain, in which case return is to caller). + -- END System call body ---------------------------------------------------- + -- BEGIN System call return stub ------------------------------------------- + 14. Issue software interrupt #101 to request system call return. + -- END System call return stub --------------------------------------------- + == END Server protection domain ============================================ +``` + +The first step in performing a system call is to invoke a system call +stub that actually issues the software interrupt to request a system +call dispatch. This approach reduces disruption to existing code, +since macros are used to generate separate stubs and corresponding +system call bodies with a single system call signature definition. + +#### Memory Layout + +The approximate memory layout of the system is depicted below, +starting with the highest physical addresses and proceeding to lower +physical addresses. Optional permissions are denoted with +parentheses. See cpu/x86/quarkX1000_paging.ld for details of how this +memory layout is implemented. + +``` + | Kernel | App | Other | + ... +--------+--------+--------+ + +------------------------------------------+ | | | | + | Domain X MMIO | | | | (RW) | + +------------------------------------------+ | | | | + ... | | | | + +------------------------------------------+ | | | | + | Domain X DMA-accessible metadata | | | | (RW) | + | (section .dma_bss) | | | | | + +------------------------------------------+ | | | | + +------------------------------------------+ | | | | + | Domain X metadata (section .meta_bss) | | | | (RW) | + +------------------------------------------+ | | | | + ... | | | | + +------------------------------------------+ | | | | + | Kernel-private data | | RW | | | + | (sections .prot_dom_bss, .gdt_bss, etc.) | | | | | + +------------------------------------------+ | | | | + +------------------------------------------+ | | | | + | System call data (section .syscall_bss) | | RW | R | R | + +------------------------------------------+ | | | | + +------------------------------------------+ | | | | + | Kernel-owned data (section .kern_bss) | | RW | R | R | + +------------------------------------------+ | | | | + +------------------------------------------+ | | | | + | Page-aligned, Kernel-owned data | | RW | R | R | + | (section .page_aligned_kern_bss) | | | | | + +------------------------------------------+ | | | | + +------------------------------------------+ | | | | + | Common data | | RW | RW | RW | + | (sections .data, .rodata*, .bss, etc.) | | | | | + +------------------------------------------+ | | | | + (not-present guard band page) | | | | + +------------------------------------------+ | | | | + | Exception stack | | RW | RW | RW | + | (section .exc_stack) | | | | | + +------------------------------------------+ | | | | + +------------------------------------------+ | | | | + | Interrupt stack | | RW | RW | RW | + | (section .int_stack) | | | | | + +------------------------------------------+ | | | | + +------------------------------------------+ | | | | + | Main stack (section .main_stack) | | RW | RW | RW | + +------------------------------------------+ | | | | + (not-present guard band page) | | | | + +------------------------------------------+ | | | | + | Main code (.text) | | RX | RX | RX | + +------------------------------------------+ | | | | + +------------------------------------------+ | | | | + | Bootstrap code (section .boot_text) | | | | | + +------------------------------------------+ | | | | + +------------------------------------------+ | | | | + | Multiboot header | | | | | + +------------------------------------------+ | | | | + ... +``` + +The only protection domain that is permitted to access kernel-owned +data is the kernel protection domain. Some devices can also be +instructed to perform DMA to kernel-owned data, although that is an +incorrect configuration. + +Paging only differentiates between memory accesses from ring 3 (user +level) and those from rings 0-2 (supervisor level). To avoid granting +code running in the preemptive scheduling context supervisory write +access to kernel data structures (including the page tables), those +structures are marked read-only (except when the kernel protection +domain is active) and the Write Protect (WP) bit in Control Register 0 +(CR0) is cleared only when it is necessary to update a write-protected +structure. Only ring 0 is allowed to modify CR0. + +Optional metadata for each protection domain is intended to only be +accessible from the associated protection domain and devices. + +Read accesses to executable code have not been observed to be needed +in at least a limited set of tests, but they are permitted, since +paging does not support an execute-only permission setting. On the +other hand, the Execute-Disable feature is used to prevent execution +of non-code memory regions. All non-startup code is mapped in all +protection domains. Limiting the code that is executable within each +protection domain to just the code that is actually needed within that +protection domain could improve the robustness of the system, but it +is challenging to determine all code that may be needed in a given +protection domain (e.g. all needed library routines). + +Stack accesses to non-stack memory are not needed, but they are +permitted. However, one page of unmapped linear address space is +placed above and below the stacks to detect erroneous stack accesses +to those linear address regions, which are the types of accesses most +likely to occur during a stack overflow or underflow condition. The +main stack is placed just below the interrupt stack, which is just +below the exception stack. Stack overflows are more common than stack +underflows, which motivates arranging the stacks such that an overflow +from a less-critical stack will not affect a more-critical stack. +Furthermore, the main stack is the most likely to overflow, since the +code that uses it is typically the most voluminous and difficult to +characterize. That provides additional motivation for positioning it +such that an overflow results in an immediate page fault. An +alternative design placing each stack on a separate group of +contiguous pages may improve the robustness of the system by +permitting the insertion of unmapped guard pages around them to +generate page faults in the event an overflow or underflow occurs on +any stack. However, that would consume additional memory. + +Data in the .rodata sections is marked read/write, even though it may +be possible to improve the robustness of the system by marking that +data as read-only. Doing so would introduce additional complexity +into the system. + +### Hardware-Switched Segment-Based Protection Domains + +Primary implementation sources: + + - cpu/x86/mm/tss-prot-domains.c + - cpu/x86/mm/tss-prot-domains-asm.S + +#### Introduction + +One TSS is allocated for each protection domain. Each one is +associated with its own dedicated LDT. The memory resources assigned +to each protection domain are represented as segment descriptors in +the LDT for the protection domain. Additional shared memory resources +are represented as segment descriptors in the GDT. + +#### System Call and Return Dispatching + +The system call dispatcher runs in the context of the server +protection domain. It is a common piece of code that is shared among +all protection domains. Thus, each TSS, except the application TSS, +has its EIP field initialized to the entrypoint for the system call +dispatcher so that will be the first code to run when the first switch +to that task is performed. + +The overall process of handling a system call can be illustrated at a +high level as follows. Some minor steps are omitted from this +illustration in the interest of clarity and brevity. + +``` + == BEGIN Client protection domain ========================================== + -- BEGIN Caller ------------------------------------------------------------ + 1. Call system call stub. + -- + 13. Continue execution... + -- END Caller -------------------------------------------------------------- + -- BEGIN System call stub -------------------------------------------------- + 2. Already in desired (server) protection domain? + - No: Request task switch to server protection domain. + - Yes: Jump to system call body. + -- + 12. Return to caller. + -- END System call stub ---------------------------------------------------- + == END Client protection domain ============================================ + == BEGIN Server protection domain ========================================== + -- BEGIN System call dispatcher--------------------------------------------- + 3. Check that the requested system call is allowed. Get entrypoint. + 4. Switch to the main stack. + 5. Pop the client return address off the stack to a callee-saved register. + 6. Push the address of the system call return dispatcher onto the stack. + 7. Jump to system call body. + -- + 10. Restore the client return address to the stack. + 11. Request task switch to client protection domain. + -- END System call dispatcher ---------------------------------------------- + -- BEGIN System call body -------------------------------------------------- + 8. Execute the work for the requested system call. + 9. Return (to system call return stub, unless invoked from server + protection domain, in which case return is to caller). + -- END System call body ---------------------------------------------------- + == END Server protection domain ============================================ +``` + +An additional exception handler is needed, for the "Device Not +Available" exception. The handler comprises just a CLTS and an IRET +instruction. The CLTS instruction is privileged, which is why it must +be run at ring level 0. This exception handler is invoked when a +floating point instruction is used following a task switch, and its +sole purpose is to enable the floating point instruction to execute +after the exception handler returns. See the TSS resources listed +above for more details regarding interactions between task switching +and floating point instructions. + +Each segment register may represent a different data region within +each protection domain, although the FS register is used for two +separate purposes at different times. The segments are defined as +follows: + + - CS (code segment) maps all non-startup code with execute-only + permissions in all protection domains. Limiting the code that is + executable within each protection domain to just the code that is + actually needed within that protection domain could improve the + robustness of the system, but it is challenging to determine all + code that may be needed in a given protection domain (e.g. all + needed library routines). Furthermore, that code may not all be + contiguous, and each segment descriptor can only map a contiguous + memory region. Finally, segment-based memory addressing is + relative to an offset of zero from the beginning of each segment, + introducing additional complexity if such fine-grained memory + management were to be used. + - DS (default data segment) typically maps the main stack and all + non-stack data memory that is accessible from all protection + domains. Limiting the data that is accessible via DS within each + protection domain to just the subset of the data that is actually + needed within that protection domain could improve the robustness + of the system, but it is challenging for similar reasons to those + that apply to CS. Access to the main stack via DS is supported so + that code that copies the stack pointer to a register and attempts + to access stack entries via DS works correctly. Disallowing access + to the main stack via DS could improve the robustness of the + system, but that may require modifying code that expects to be able + to access the stack via DS. + - ES is loaded with the same segment descriptor as DS so that string + operations (e.g. the MOVS instruction) work correctly. + - FS usually maps the kernel-owned data region. That region can only + be written via FS in the kernel protection domain. FS contains a + descriptor specifying a read-only mapping in all other protection + domains except the application protection domain, in which FS is + nullified. Requiring that code specifically request access to the + kernel-owned data region by using the FS segment may improve the + robustness of the system by blocking undesired accesses to the + kernel-owned data region via memory access instructions within the + kernel protection domain that implicitly access DS. The reason for + granting read-only access to the kernel-owned data region from most + protection domains is that the system call dispatcher runs in the + context of the server protection domain to minimize overhead, and + it requires access to the kernel-owned data region. It may improve + the robustness of the system to avoid this by running the system + call dispatcher in a more-privileged ring level (e.g. ring 1) + within the protection domain and just granting access to the + kernel-owned data region from that ring. However, that would + necessitate a ring level transition to ring 3 when dispatching the + system call, which would increase overhead. The application + protection domain does not export any system calls, so it does not + require access to the kernel-owned data region. + - FS is temporarily loaded with a segment descriptor that maps just + an MMIO region used by a driver protection domain when such a + driver needs to perform MMIO accesses. + - GS maps an optional region of readable and writable metadata that + can be associated with a protection domain. In protection domains + that are not associated with metadata, GS is nullified. + - SS usually maps just the main stack. This may improve the + robustness of the system by enabling immediate detection of stack + underflows and overflows rather than allowing such a condition to + result in silent data corruption. Interrupt handlers use a stack + segment that covers the main stack and also includes a region above + the main stack that is specifically for use by interrupt handlers. + In like manner, exception handlers use a stack segment that covers + both of the other stacks and includes an additional region. This + is to support the interrupt dispatchers that copy parameters from + the interrupt-specific stack region to the main stack prior to + pivoting to the main stack to execute an interrupt handler body. + +The approximate memory layout of the system is depicted below, +starting with the highest physical addresses and proceeding to lower +physical addresses. The memory ranges that are mapped at various +times by each of the segment registers are also depicted. Read the +descriptions of each segment above for more information about what +memory range may be mapped by each segment register at various times +with various protection domain configurations. Parenthetical notes +indicate the protection domains that can use each mapping. The suffix +[L] indicates that the descriptor is loaded from LDT. Optional +mappings are denoted by a '?' after the protection domain label. The +'other' protection domain label refers to protection domains other +than the application and kernel domains. + +``` + ... + +------------------------------------------+ \ + | Domain X MMIO | +- FS[L] + +------------------------------------------+ / (other?) + ... + +------------------------------------------+ \ + | Domain X DMA-accessible metadata | +- GS[L] (other?) + | (section .dma_bss) | | + +------------------------------------------+ / + +------------------------------------------+ \ + | Domain X metadata (section .meta_bss) | +- GS[L] (other?) + +------------------------------------------+ / + ... + +------------------------------------------+ \ + | Kernel-private data | | + | (sections .prot_dom_bss, .gdt_bss, etc.) | +- FS[L] (kern) + +------------------------------------------+ | + +------------------------------------------+ \ + | System call data (section .syscall_bss) | | + +------------------------------------------+ +- FS[L] (all) + +------------------------------------------+ | + | Kernel-owned data (section .kern_bss) | | + +------------------------------------------+ / + +------------------------------------------+ \ + | Common data | | + | (sections .data, .rodata*, .bss, etc.) | | + +------------------------------------------+ +- DS, ES + +------------------------------------------+ \ | (all) + | Exception stack (section .exc_stack) | | | + |+----------------------------------------+| \ | + || Interrupt stack (section .int_stack) || | | + ||+--------------------------------------+|| \ | + ||| Main stack (section .main_stack) ||| +- SS (all) | + +++--------------------------------------+++ / / + +------------------------------------------+ \ + | Main code (.text) | +- CS (all) + +------------------------------------------+ / + +------------------------------------------+ + | Bootstrap code (section .boot_text) | + +------------------------------------------+ + +------------------------------------------+ + | Multiboot header | + +------------------------------------------+ + ... +``` + +This memory layout is more efficient than the layout that is possible +with paging-based protection domains, since segments have byte +granularity, whereas the minimum unit of control supported by paging +is a 4KiB page. For example, this means that metadata may need to be +padded to be a multiple of the page size. This may also permit +potentially-undesirable accesses to padded areas of code and data +regions that do not entirely fill the pages that they occupy. + +Kernel data structure access, including to the descriptor tables +themselves, is normally restricted to the code running at ring level +0, specifically the exception handlers and the system call and return +dispatchers. It is also accessible from the cooperative scheduling +context in the kernel protection domain. Interrupt delivery is +disabled in the kernel protection domain, so the preemptive scheduling +context is not used. + +SS, DS, and ES all have the same base address, since the compiler may +assume that a flat memory model is in use. Memory accesses that use a +base register of SP/ESP or BP/EBP or that are generated by certain +other instructions (e.g. PUSH, RET, etc.) are directed to SS by +default, whereas other accesses are directed to DS or ES by default. +The compiler may use an instruction that directs an access to DS or ES +even if the data being accessed is on the stack, which is why these +three segments must use the same base address. However, it is +possible to use a lower limit for SS than for DS and ES for the +following reasons. Compilers commonly provide an option for +preventing the frame pointer, EBP, from being omitted and possibly +used to point to non-stack data. In our tests, compilers never used +ESP to point to non-stack data. + +Each task switch ends up saving and restoring more state than is +actually useful to us, but the implementation attempts to minimize +overhead by configuring the register values in each TSS to reduce the +number of register loads that are needed in the system call +dispatcher. Specifically, two callee-saved registers are populated +with base addresses used when computing addresses in the entrypoint +information table as well as a mask corresponding to the ID of the +server protection domain that is used to check whether the requested +system call is exported by the server protection domain. Callee-saved +registers are used, since the task return will update the saved +register values. + +Note that this implies that the intervening code run between the task +call and return can modify critical data used by the system call +dispatcher. However, this is analogous to the considerations +associated with sharing a single stack amongst all protection domains +and should be addressed similarly, by only invoking protection domains +that are trusted by the caller to not modify the saved critical +values. This consideration is specific to the TSS-based dispatcher +and is not shared by the ring 0 dispatcher used in the other +plugins. + +Data in the .rodata sections is marked read/write, even though it may +be possible to improve the robustness of the system by marking that +data as read-only. Doing so would introduce even more complexity into +the system than would be the case with paging-based protection +domains, since it would require allocating different segment +descriptors for the read-only vs. the read/write data. + +#### Supporting Null-Pointer Checks + +A lot of code considers a pointer value of 0 to be invalid. However, +segment offsets always start at 0. To accommodate the common software +behavior, at least the first byte of each segment is marked as +unusable. An exception to this is that the first byte of the stack +segments is usable. + +#### Interrupt and Exception Dispatching + +A distinctive challenge that occurs during interrupt and exception +dispatching is that the state of the segment registers when an +interrupt or exception occurs is somewhat unpredictable. For example, +an exception may occur while MMIO is being performed, meaning that FS +is loaded with the MMIO descriptor instead of the kernel descriptor. +Leaving the segment registers configured in that way could cause +incorrect interrupt or exception handler behavior. Thus, the +interrupt or exception dispatcher must save the current segment +configuration, switch to a configuration that is suitable for the +handler body, and then restore the saved segment configuration after +the handler body returns. Another motivation for this is that the +interrupted code may have corrupted the segment register configuration +in an unexpected manner, since segment register load instructions are +unprivileged. Similar segment register updates must be performed for +similar reasons when dispatching system calls. + +### Software-Switched Segment-Based Protection Domains + +Primary implementation sources: + + - cpu/x86/mm/swseg-prot-domains.c + +The requirement to allocate a TSS for each protection domain in the +hardware-switched segments plugin may consume a substantial amount of +space, since the size of each TSS is fixed by hardware to be at least +104 bytes. The software-switched segments plugin saves space by +defining a more compact PDCS. However, the layout and definitions of +the segments is identical to what was described above for the +hardware-switched segments plugin. + +The system call and return procedure is mostly identical to that for +paging-based protection domains. However, instead of updating and +invalidating page tables, the dispatchers update the LDT and some of +the segment registers. + +### Pointer Validation + +Primary implementation sources: + - cpu/x86/mm/syscalls.h + +At the beginning of each system call routine, it is necessary to check +that any untrusted pointer that could have been influenced by a caller +(i.e. a stack parameter or global variable) refers to a location above +the return address and to halt otherwise. This is to prevent a +protection domain from calling a different protection domain and +passing a pointer that references a location in the callee's stack +other than its parameters to influence the execution of the callee in +an unintended manner. For example, if an incoming pointer referenced +the return address, it could potentially redirect execution with the +privileges of the callee protection domain. + +When the paging-based plugin is in use, it is also necessary to check +that the pointer is either within the stack region or the shared data +region (or a guard band region, since that will generate a fault) to +prevent redirection of data accesses to MMIO or metadata regions. The +other plugins already configure segments to restrict accesses to DS to +just those regions. Pointers provided as inputs to system calls as +defined above should never be dereferenced in any segment other than +DS. + +The pointer is both validated and copied to a new storage location, +which must be within the callee's local stack region (excluding the +parameter region). This is to mitigate scenarios such as two pointers +being validated and an adversary later inducing a write through one of +the pointers to the other pointer to corrupt the latter pointer before +it is used. + +Any pointer whose value is fixed at link or load time does not need to +be validated prior to use, since no adversary within the defined +threat model is able to influence the link or load process. + +### DMA Restrictions + +Primary implementation sources: + - cpu/x86/drivers/quarkX1000/imr.c + - cpu/x86/drivers/quarkX1000/imr-conf.c + +The CPU is not the only agent with the ability to issue requests to +the interconnect within the SoC. For example, SoC peripherals such as +the Ethernet driver use DMA to efficiently access memory buffers. +This could introduce a risk that DMA could be used to bypass the +memory protections enforced on the CPU by segmentation or paging. For +example, a device driver could instruct a device to access a memory +region to which the kernel has not granted the driver's protection +domain permission to access. + +The Isolated Memory Region (IMR) feature is configured to restrict the +memory that can be accessed by system agents other than the CPU [3]. +It only allows those system agents to access portions of the Contiki +memory space that are specifically intended to be used with DMA. The +source code for each protection domain specifies that its optional +metadata region needs to be accessible from other system agents +besides the CPU by using ATTR_BSS_DMA instead of ATTR_BSS_META when +allocating storage for the metadata. + +Extending the Framework +----------------------- + +### Adding a New Protection Domain + +The following steps are required. See the existing device drivers for +examples of various types of protection domains and how they are +initialized. + + - Allocate storage for the PDCS and the corresponding + client-accessible data structure using the PROT_DOMAINS_ALLOC + macro. + - Apply the ATTR_BSS_META attribute to the metadata structure, if + applicable. Apply the ATTR_BSS_DMA attribute instead if the + metadata structure needs to be DMA-accessible. Pad the metadata + structure to completely fill an integer multiple of the minimum + page size, 4096, when paging-based protection domains are in use. + See the definition of quarkX1000_eth_meta_t for an example. + - Perform the following steps during boot stage 2: + - Initialize the protection domain ID in the client-accessible data + structure using the PROT_DOMAINS_INIT_ID macro. + - Register the domain. See prot-domains.c:prot_domains_init for an + example of registering a non-driver protection domain. See + cpu/x86/drivers/quarkX1000/eth.c:quarkX1000_eth_init for an + example of registering a PCI driver protection domain with an + MMIO region and a metadata region. + +### Adding a New System Call + +The following steps are required: + + - Define the system call procedure using the SYSCALLS_DEFINE or + SYSCALLS_DEFINE_SINGLETON macro. See + cpu/x86/drivers/legacy_pc/uart-16x50.c:uart_16x50_tx for an example + of a non-singleton system call. See + cpu/x86/drivers/quarkX1000/eth.c:quarkX1000_eth_send for an example + of a singleton system call. A singleton system call is one for + which at most one server protection domain will be associated with + it. + - During boot phase 2, associate the system call with one or more + server protection domains using the SYSCALLS_AUTHZ macro. + +Usage +----- + +To enable protection domain support, add "X86_CONF_PROT_DOMAINS=" to +the command line and specify one of the following options: + + - paging + - tss + - swseg + +The paging option accepts a sub-option to determine whether the TLB is +fully- or selectively-invalidated during protection domain switches. +By default, full invalidation is selected. Set the +X86_CONF_USE_INVLPG variable to 1 to override the default. + +References +---------- + +[1] J. H. Saltzer, "Protection and the Control of Information Sharing + in Multics," Commun. ACM, vol. 17, no. 7, pp. 388-402, Jul. 1974. + +[2] https://github.com/contiki-os/contiki/wiki/Processes + +[3] "Intel(R) Quark(TM) SoC X1000 Secure Boot Programmer's Reference + Manual," + http://www.intel.com/support/processors/quark/sb/CS-035228.htm diff --git a/cpu/x86/mm/gdt-layout.h b/cpu/x86/mm/gdt-layout.h new file mode 100644 index 000000000..b79c2b9ca --- /dev/null +++ b/cpu/x86/mm/gdt-layout.h @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_MM_GDT_LAYOUT_H_ +#define CPU_X86_MM_GDT_LAYOUT_H_ + +#include "prot-domains.h" + +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING +/** + * Number of fixed GDT descriptors. Additional descriptors may be defined + * outside of gdt.c. + */ +#define GDT_NUM_FIXED_DESC 7 +#elif X86_CONF_PROT_DOMAINS_MULTI_SEG +#define GDT_NUM_FIXED_DESC 11 +#else +#define GDT_NUM_FIXED_DESC 3 +#endif + +#define GDT_IDX_NULL 0 +/** + * Flat code segment, used at boot and also for the rest of the system's + * runtime when protection domains are disabled + */ +#define GDT_IDX_CODE_FLAT 1 +/** + * Flat data segment, used at boot and also for the rest of the system's + * runtime when protection domains are disabled + */ +#define GDT_IDX_DATA_FLAT 2 + +#if X86_CONF_PROT_DOMAINS != X86_CONF_PROT_DOMAINS__NONE +/** Default (post-boot) code segment */ +#define GDT_IDX_CODE 3 +/** + * Same bounds and permissions as default code segment, but at the interrupt + * handler privilege level + */ +#define GDT_IDX_CODE_INT 4 +/** Stack segment for interrupt handlers */ +#define GDT_IDX_STK_INT 5 + +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING +#define GDT_IDX_CODE_EXC GDT_IDX_CODE_FLAT +/** Default data segment used by code at all privilege levels */ +#define GDT_IDX_DATA 6 +#define GDT_IDX_STK GDT_IDX_DATA +#define GDT_IDX_STK_EXC GDT_IDX_DATA_FLAT +#else +/** + * Same bounds and permissions as default code segment, but at the exception + * handler privilege level + */ +#define GDT_IDX_CODE_EXC 6 +/** R/W kernel data descriptor used during boot stage 1 */ +#define GDT_IDX_DATA_KERN_EXC 7 +/** Default data segment used by code at all privilege levels */ +#define GDT_IDX_DATA 8 +/** + * Default stack segment, which overlaps with the beginning of the default data + * segment + */ +#define GDT_IDX_STK 9 +/** Stack segment for exception handlers */ +#define GDT_IDX_STK_EXC 10 + +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS +#define GDT_IDX_TSS(dom_id) (GDT_NUM_FIXED_DESC + (2 * (dom_id))) +#define GDT_IDX_LDT(dom_id) (GDT_NUM_FIXED_DESC + (2 * (dom_id)) + 1) +#else +#define GDT_IDX_LDT(dom_id) (GDT_NUM_FIXED_DESC + (dom_id)) +#endif + +#endif +#else +#define GDT_IDX_CODE GDT_IDX_CODE_FLAT +#define GDT_IDX_CODE_INT GDT_IDX_CODE_FLAT +#define GDT_IDX_CODE_EXC GDT_IDX_CODE_FLAT +#define GDT_IDX_DATA GDT_IDX_DATA_FLAT +#define GDT_IDX_STK GDT_IDX_DATA_FLAT +#define GDT_IDX_STK_INT GDT_IDX_DATA_FLAT +#define GDT_IDX_STK_EXC GDT_IDX_DATA_FLAT +#endif + +#define GDT_SEL(idx, rpl) (((idx) << 3) | (rpl)) + +#define DT_SEL_GET_IDX(sel) ((sel) >> 3) + +#define DT_SEL_GET_RPL(sel) ((sel) & 3) + +#define GDT_SEL_NULL GDT_SEL(GDT_IDX_NULL, 0) +#define GDT_SEL_CODE_FLAT GDT_SEL(GDT_IDX_CODE_FLAT, PRIV_LVL_EXC) +#define GDT_SEL_DATA_FLAT GDT_SEL(GDT_IDX_DATA_FLAT, PRIV_LVL_EXC) + +#define GDT_SEL_CODE GDT_SEL(GDT_IDX_CODE, PRIV_LVL_USER) +#define GDT_SEL_CODE_INT GDT_SEL(GDT_IDX_CODE_INT, PRIV_LVL_INT) +#define GDT_SEL_CODE_EXC GDT_SEL(GDT_IDX_CODE_EXC, PRIV_LVL_EXC) + +#define GDT_SEL_DATA GDT_SEL(GDT_IDX_DATA, PRIV_LVL_EXC) +#define GDT_SEL_DATA_KERN_EXC GDT_SEL(GDT_IDX_DATA_KERN_EXC, PRIV_LVL_EXC) + +#define GDT_SEL_STK GDT_SEL(GDT_IDX_STK, PRIV_LVL_USER) +#define GDT_SEL_STK_INT GDT_SEL(GDT_IDX_STK_INT, PRIV_LVL_INT) +#define GDT_SEL_STK_EXC GDT_SEL(GDT_IDX_STK_EXC, PRIV_LVL_EXC) + +#define GDT_SEL_TSS(dom_id) GDT_SEL(GDT_IDX_TSS(dom_id), PRIV_LVL_USER) +#define GDT_SEL_LDT(dom_id) GDT_SEL(GDT_IDX_LDT(dom_id), PRIV_LVL_USER) + +#endif /* CPU_X86_MM_GDT_LAYOUT_H_ */ + diff --git a/cpu/x86/mm/ldt-layout.h b/cpu/x86/mm/ldt-layout.h new file mode 100644 index 000000000..7c61054a5 --- /dev/null +++ b/cpu/x86/mm/ldt-layout.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_MM_LDT_LAYOUT_H_ +#define CPU_X86_MM_LDT_LAYOUT_H_ + +#include "gdt-layout.h" + +/* Each LDT can contain up to this many descriptors, but some protection + * domains may not use all of the slots. + */ +#define LDT_NUM_DESC 3 + +/** + * Provides access to kernel data. Most protection domains are granted at most + * read-only access, but the kernel protection domain is granted read/write + * access. + */ +#define LDT_IDX_KERN 0 +/** Maps a device MMIO range */ +#define LDT_IDX_MMIO 1 +/** Maps domain-defined metadata */ +#define LDT_IDX_META 2 + +#define LDT_SEL(idx, rpl) (GDT_SEL(idx, rpl) | (1 << 2)) + +#define LDT_SEL_KERN LDT_SEL(LDT_IDX_KERN, PRIV_LVL_USER) +#define LDT_SEL_MMIO LDT_SEL(LDT_IDX_MMIO, PRIV_LVL_USER) +#define LDT_SEL_META LDT_SEL(LDT_IDX_META, PRIV_LVL_USER) +#define LDT_SEL_STK LDT_SEL(LDT_IDX_STK, PRIV_LVL_USER) + +#endif /* CPU_X86_MM_LDT_LAYOUT_H_ */ diff --git a/cpu/x86/mm/multi-segment.c b/cpu/x86/mm/multi-segment.c new file mode 100644 index 000000000..6d3fd57f1 --- /dev/null +++ b/cpu/x86/mm/multi-segment.c @@ -0,0 +1,248 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "gdt.h" +#include "helpers.h" +#include "prot-domains.h" +#include "segmentation.h" +#include "stacks.h" + +/*---------------------------------------------------------------------------*/ +static uint32_t +segment_desc_compute_base(segment_desc_t desc) +{ + return (desc.base_hi << 24) | (desc.base_mid << 16) | desc.base_lo; +} +/*---------------------------------------------------------------------------*/ +void +prot_domains_reg_multi_seg(volatile struct dom_kern_data ATTR_KERN_ADDR_SPACE *dkd, + uintptr_t mmio, size_t mmio_sz, + uintptr_t meta, size_t meta_sz) +{ + segment_desc_t desc; + dom_id_t dom_id = PROT_DOMAINS_GET_DOM_ID(dkd); + uint32_t kern_data_len; + uint32_t tmp; + + if((dkd < prot_domains_kern_data) || + (prot_domains_kern_data_end <= dkd) || + (((((uintptr_t)dkd) - (uintptr_t)prot_domains_kern_data) % + sizeof(dom_kern_data_t)) != 0)) { + halt(); + } + + KERN_READL(tmp, dkd->ldt[DT_SEL_GET_IDX(LDT_SEL_KERN)].raw_hi); + if(tmp != 0) { + /* This PDCS was previously initialized, which is disallowed. */ + halt(); + } + + /* Initialize descriptors */ + + if(dom_id == DOM_ID_kern) { + kern_data_len = (uint32_t)&_ebss_kern_addr; + } else { + /* Non-kernel protection domains do not need to access the protection + * domain control structures, and they may contain saved register values + * that are private to each domain. + */ + kern_data_len = (uint32_t)&_ebss_syscall_addr; + } + kern_data_len -= (uint32_t)&_sbss_kern_addr; + + segment_desc_init(&desc, (uint32_t)&_sbss_kern_addr, kern_data_len, + /* Every protection domain requires at least read-only access to kernel + data to read dom_client_data structures and to support the system call + dispatcher, if applicable. Only the kernel protection domain is granted + read/write access to the kernel data. */ + ((dom_id == DOM_ID_kern) ? + SEG_TYPE_DATA_RDWR : + SEG_TYPE_DATA_RDONLY) | + SEG_FLAG(DPL, PRIV_LVL_USER) | + SEG_GRAN_BYTE | SEG_DESCTYPE_NSYS); + + KERN_WRITEL(dkd->ldt[LDT_IDX_KERN].raw_lo, desc.raw_lo); + KERN_WRITEL(dkd->ldt[LDT_IDX_KERN].raw_hi, desc.raw_hi); + + if(mmio_sz != 0) { + if(SEG_MAX_BYTE_GRAN_LEN < mmio_sz) { + halt(); + } + + segment_desc_init(&desc, mmio, mmio_sz, + SEG_FLAG(DPL, PRIV_LVL_USER) | SEG_GRAN_BYTE | + SEG_DESCTYPE_NSYS | SEG_TYPE_DATA_RDWR); + } else { + desc.raw = SEG_DESC_NOT_PRESENT; + } + + KERN_WRITEL(dkd->ldt[LDT_IDX_MMIO].raw_lo, desc.raw_lo); + KERN_WRITEL(dkd->ldt[LDT_IDX_MMIO].raw_hi, desc.raw_hi); + + if(meta_sz != 0) { + if(SEG_MAX_BYTE_GRAN_LEN < meta_sz) { + halt(); + } + + segment_desc_init(&desc, meta, meta_sz, + SEG_FLAG(DPL, PRIV_LVL_USER) | SEG_GRAN_BYTE | + SEG_DESCTYPE_NSYS | SEG_TYPE_DATA_RDWR); + } else { + desc.raw = SEG_DESC_NOT_PRESENT; + } + + KERN_WRITEL(dkd->ldt[LDT_IDX_META].raw_lo, desc.raw_lo); + KERN_WRITEL(dkd->ldt[LDT_IDX_META].raw_hi, desc.raw_hi); + + segment_desc_init(&desc, + KERN_DATA_OFF_TO_PHYS_ADDR(dkd->ldt), + sizeof(dkd->ldt), + SEG_FLAG(DPL, PRIV_LVL_USER) | SEG_GRAN_BYTE | + SEG_DESCTYPE_SYS | SEG_TYPE_LDT); + gdt_insert(GDT_IDX_LDT(dom_id), desc); +} +/*---------------------------------------------------------------------------*/ +void +prot_domains_gdt_init() +{ + int i; + segment_desc_t desc; + + segment_desc_init(&desc, + (uint32_t)&_stext_addr, + ((uint32_t)&_etext_addr) - (uint32_t)&_stext_addr, + SEG_FLAG(DPL, PRIV_LVL_EXC) | SEG_GRAN_BYTE | + SEG_DESCTYPE_NSYS | +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG + /* The general protection fault handler requires read access to CS */ + SEG_TYPE_CODE_EXRD +#else + SEG_TYPE_CODE_EX +#endif + ); + gdt_insert_boot(GDT_IDX_CODE_EXC, desc); + + segment_desc_init(&desc, + (uint32_t)&_sdata_addr, + ((uint32_t)&_edata_addr) - (uint32_t)&_sdata_addr, + SEG_FLAG(DPL, PRIV_LVL_USER) | SEG_GRAN_BYTE | + SEG_DESCTYPE_NSYS | SEG_TYPE_DATA_RDWR); + gdt_insert_boot(GDT_IDX_DATA, desc); + + segment_desc_init(&desc, + (uint32_t)&_sbss_kern_addr, + ((uint32_t)&_ebss_kern_addr) - + (uint32_t)&_sbss_kern_addr, + SEG_FLAG(DPL, PRIV_LVL_EXC) | SEG_GRAN_BYTE | + SEG_DESCTYPE_NSYS | SEG_TYPE_DATA_RDWR); + gdt_insert_boot(GDT_IDX_DATA_KERN_EXC, desc); + + segment_desc_init(&desc, + (uint32_t)DATA_OFF_TO_PHYS_ADDR(stacks_main), + STACKS_SIZE_MAIN, + SEG_FLAG(DPL, PRIV_LVL_USER) | SEG_GRAN_BYTE | + SEG_DESCTYPE_NSYS | SEG_TYPE_DATA_RDWR); + gdt_insert_boot(GDT_IDX_STK, desc); + + segment_desc_set_limit(&desc, STACKS_SIZE_MAIN + STACKS_SIZE_INT); + SEG_SET_FLAG(desc, DPL, PRIV_LVL_INT); + gdt_insert_boot(GDT_IDX_STK_INT, desc); + + segment_desc_set_limit(&desc, + STACKS_SIZE_MAIN + + STACKS_SIZE_INT + + STACKS_SIZE_EXC); + SEG_SET_FLAG(desc, DPL, PRIV_LVL_EXC); + gdt_insert_boot(GDT_IDX_STK_EXC, desc); + + /* Not all domains will necessarily be initialized, so this initially marks + * all per-domain descriptors not-present. + */ + desc.raw = SEG_DESC_NOT_PRESENT; + for(i = 0; i < PROT_DOMAINS_ACTUAL_CNT; i++) { +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS + gdt_insert_boot(GDT_IDX_TSS(i), desc); +#endif + gdt_insert_boot(GDT_IDX_LDT(i), desc); + } + + __asm__ __volatile__ ( + "mov %[_default_data_], %%ds\n\t" + "mov %[_default_data_], %%es\n\t" + "mov %[_kern_data_], %%" SEG_KERN "s\n\t" + : + : [_default_data_] "r"(GDT_SEL_DATA), + [_kern_data_] "r"(GDT_SEL_DATA_KERN_EXC)); +} +/*---------------------------------------------------------------------------*/ +void +multi_segment_launch_kernel(void) +{ + /* Update segment registers. */ + __asm__ __volatile__ ( + "mov %[_data_seg_], %%ds\n\t" + "mov %[_data_seg_], %%es\n\t" + "mov %[_kern_seg_], %%" SEG_KERN "s\n\t" + "mov %[_data_seg_], %%" SEG_META "s\n\t" + : + : [_data_seg_] "r" (GDT_SEL_DATA), + [_kern_seg_] "r" (LDT_SEL_KERN) + ); +} +/*---------------------------------------------------------------------------*/ +void +prot_domains_enable_mmio(void) +{ + __asm__ __volatile__ ("mov %0, %%" SEG_MMIO "s" :: "r" (LDT_SEL_MMIO)); +} +/*---------------------------------------------------------------------------*/ +void +prot_domains_disable_mmio(void) +{ + __asm__ __volatile__ ("mov %0, %%" SEG_KERN "s" :: "r" (LDT_SEL_KERN)); +} +/*---------------------------------------------------------------------------*/ +uintptr_t +prot_domains_lookup_meta_phys_base(dom_client_data_t ATTR_KERN_ADDR_SPACE *drv) +{ + dom_id_t dom_id; + segment_desc_t desc; + volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE *dkd; + + KERN_READL(dom_id, drv->dom_id); + + dkd = prot_domains_kern_data + dom_id; + + KERN_READL(desc.raw_lo, dkd->ldt[DT_SEL_GET_IDX(LDT_SEL_META)].raw_lo); + KERN_READL(desc.raw_hi, dkd->ldt[DT_SEL_GET_IDX(LDT_SEL_META)].raw_hi); + + return segment_desc_compute_base(desc); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/mm/multi-segment.h b/cpu/x86/mm/multi-segment.h new file mode 100644 index 000000000..baa28002b --- /dev/null +++ b/cpu/x86/mm/multi-segment.h @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_MM_MULTI_SEGMENT_H_ +#define CPU_X86_MM_MULTI_SEGMENT_H_ + +#include +#include +#include "helpers.h" +#include "ldt-layout.h" + +#ifdef __clang__ +#define __SEG_FS +#define __seg_fs __attribute__((address_space(257))) +#define __SEG_GS +#define __seg_gs __attribute__((address_space(256))) +#endif + +#ifdef __SEG_FS +#define ATTR_MMIO_ADDR_SPACE __seg_fs +#define ATTR_KERN_ADDR_SPACE __seg_fs +#else +#define ATTR_KERN_ADDR_SPACE +#endif +#ifdef __SEG_GS +#define ATTR_META_ADDR_SPACE __seg_gs +#endif + +void prot_domains_reg_multi_seg(volatile struct dom_kern_data ATTR_KERN_ADDR_SPACE *dkd, + uintptr_t mmio, size_t mmio_sz, + uintptr_t meta, size_t meta_sz); +void multi_segment_launch_kernel(void); + +#define MULTI_SEGMENT_ENTER_ISR(exc) \ + "mov $" EXP_STRINGIFY(GDT_SEL_DATA) ", %%eax\n\t" \ + /* Refresh DS and ES in case the userspace code corrupted them. */ \ + "mov %%eax, %%ds\n\t" \ + "mov %%eax, %%es\n\t" \ + /* Refresh SEG_KERN. */ \ + "mov $" EXP_STRINGIFY(LDT_SEL_KERN) ", %%eax\n\t" \ + "mov %%eax, %%" SEG_KERN "s\n\t" \ + ".if " #exc "\n\t" \ + /* It is possible that a routine performing MMIO is being interrupted. */ \ + /* Thus, it is necessary to save and restore the MMIO segment register */ \ + /* (in a callee-saved register). */ \ + "mov %%" SEG_MMIO "s, %%ebp\n\t" \ + "mov $" EXP_STRINGIFY(GDT_SEL_DATA_KERN_EXC) ", %%eax\n\t" \ + "mov %%eax, %%" SEG_KERN "s\n\t" \ + ".endif\n\t" +#define MULTI_SEGMENT_LEAVE_ISR(exc) \ + ".if " #exc "\n\t" \ + "mov %%ebp, %%" SEG_MMIO "s\n\t" \ + ".endif\n\t" + +/** + * The MMIO region is tightly bounded within a segment, so its base offset is + * always 0. + */ +#define PROT_DOMAINS_MMIO(dcd) 0 +/** + * The metadata region is tightly bounded within a segment, so its base offset + * is always 0. + */ +#define PROT_DOMAINS_META(dcd) 0 + +#define SEG_MMIO "f" /**< For MMIO accesses, when enabled. */ +#define SEG_KERN "f" /**< For kernel data accesses */ +#define SEG_META "g" /**< For metadata accesses */ + +#define _SEG_READL(seg, dst, src) \ + __asm__ __volatile__ ( \ + "movl %%" seg "s:%[src_], %[dst_]" : [dst_]"=r"(dst) : [src_]"m"(src)) + +#define _SEG_READW(seg, dst, src) \ + __asm__ __volatile__ ( \ + "movw %%" seg "s:%[src_], %[dst_]" : [dst_]"=r"(dst) : [src_]"m"(src)) + +#define _SEG_READB(seg, dst, src) \ + __asm__ __volatile__ ( \ + "movb %%" seg "s:%[src_], %[dst_]" : [dst_]"=q"(dst) : [src_]"m"(src)) + +#define _SEG_WRITEL(seg, dst, src) \ + __asm__ __volatile__ ( \ + "movl %[src_], %%" seg "s:%[dst_]" \ + : [dst_]"=m"(dst) : [src_]"r"((uint32_t)(src))) + +#define _SEG_WRITEW(seg, dst, src) \ + __asm__ __volatile__ ( \ + "movw %[src_], %%" seg "s:%[dst_]" \ + : [dst_]"=m"(dst) : [src_]"r"((uint16_t)(src))) + +#define _SEG_WRITEB(seg, dst, src) \ + __asm__ __volatile__ ( \ + "movb %[src_], %%" seg "s:%[dst_]" \ + : [dst_]"=m"(dst) : [src_]"q"((uint8_t)(src))) + +#ifndef __SEG_FS +#define MMIO_READL(dst, src) _SEG_READL(SEG_MMIO, dst, src) +#define MMIO_READW(dst, src) _SEG_READW(SEG_MMIO, dst, src) +#define MMIO_READB(dst, src) _SEG_READB(SEG_MMIO, dst, src) +#define MMIO_WRITEL(dst, src) _SEG_WRITEL(SEG_MMIO, dst, src) +#define MMIO_WRITEW(dst, src) _SEG_WRITEW(SEG_MMIO, dst, src) +#define MMIO_WRITEB(dst, src) _SEG_WRITEB(SEG_MMIO, dst, src) + +#define KERN_READL(dst, src) _SEG_READL(SEG_KERN, dst, src) +#define KERN_READW(dst, src) _SEG_READW(SEG_KERN, dst, src) +#define KERN_READB(dst, src) _SEG_READB(SEG_KERN, dst, src) +#define KERN_WRITEL(dst, src) _SEG_WRITEL(SEG_KERN, dst, src) +#define KERN_WRITEW(dst, src) _SEG_WRITEW(SEG_KERN, dst, src) +#define KERN_WRITEB(dst, src) _SEG_WRITEB(SEG_KERN, dst, src) +#endif + +#ifndef __SEG_GS +#define META_READL(dst, src) _SEG_READL(SEG_META, dst, src) +#define META_READW(dst, src) _SEG_READW(SEG_META, dst, src) +#define META_READB(dst, src) _SEG_READB(SEG_META, dst, src) +#define META_WRITEL(dst, src) _SEG_WRITEL(SEG_META, dst, src) +#define META_WRITEW(dst, src) _SEG_WRITEW(SEG_META, dst, src) +#define META_WRITEB(dst, src) _SEG_WRITEB(SEG_META, dst, src) +#endif + +#define MEMCPY_FROM_META(dst, src, sz) \ + { \ + uintptr_t __dst = (uintptr_t)(dst); \ + uintptr_t __src = (uintptr_t)(src); \ + size_t __sz = (size_t)(sz); \ + __asm__ __volatile__ ( \ + "rep movsb %%" SEG_META "s:(%%esi), %%es:(%%edi)\n\t" \ + : "+D"(__dst), "+S"(__src), "+c"(__sz)); \ + } + +#define MEMCPY_TO_META(dst, src, sz) \ + { \ + uintptr_t __dst = (uintptr_t)(dst); \ + uintptr_t __src = (uintptr_t)(src); \ + size_t __sz = (size_t)(sz); \ + __asm__ __volatile__ ( \ + "push %%es\n\t" \ + "push %%" SEG_META "s\n\t" \ + "pop %%es\n\t" \ + "rep movsb\n\t" \ + "pop %%es\n\t" \ + : "+D"(__dst), "+S"(__src), "+c"(__sz)); \ + } + +/** Compute physical address from offset into kernel data space */ +#define KERN_DATA_OFF_TO_PHYS_ADDR(x) \ + (((uintptr_t)&_sbss_kern_addr) + (uintptr_t)(x)) +/** Compute physical address from offset into default data space */ +#define DATA_OFF_TO_PHYS_ADDR(x) \ + (((uintptr_t)&_sdata_addr) + (uintptr_t)(x)) +/** Compute kernel data offset from physical address in kernel data space */ +#define PHYS_ADDR_TO_KERN_DATA_OFF(x) \ + (((uintptr_t)(x)) - (uintptr_t)&_sbss_kern_addr) + +/** + * In multi-segment protection domain implementations, it is sufficient to just + * compare incoming pointers against the frame pointer. All incoming pointers + * are dereferenced in the main data segment, which only maps the stacks and + * the shared data section. Since the shared data section is at a higher + * address range than the stacks, the frame pointer check is sufficient. + */ +#define PROT_DOMAINS_CHECK_INCOMING_PTR PROT_DOMAINS_CHECK_INCOMING_PTR_EBP + +void prot_domains_enable_mmio(void); +void prot_domains_disable_mmio(void); + +#endif /* CPU_X86_MM_MULTI_SEGMENT_H_ */ diff --git a/cpu/x86/mm/paging-prot-domains.c b/cpu/x86/mm/paging-prot-domains.c new file mode 100644 index 000000000..6c28c03e2 --- /dev/null +++ b/cpu/x86/mm/paging-prot-domains.c @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include +#include "dma.h" +#include "gdt.h" +#include "gdt-layout.h" +#include "helpers.h" +#include "idt.h" +#include "paging.h" +#include "prot-domains.h" +#include "segmentation.h" +#include "stacks.h" +#include "syscalls.h" +#include "tss.h" + +/*#define DBG_PAGE_ALLOC*/ + +/* Enable PAE-mode paging */ +#define CR4_PAE BIT(5) + +/* Extended Feature Enables MSR */ +#define MSR_EFER 0xC0000080 + +/* Enable Execute Disable bit support */ +#define EFER_NXE BIT(11) + +/* Root page-directory-pointer table */ +static pdpt_t root_pgtbl __attribute__((aligned(32))) ATTR_BSS_KERN; +/* Although the following page tables must be page-aligned, it is infeasible to + * apply the "aligned(4096)" attribute for the reasons described in the linker + * script. + */ +/* Second-level page directory */ +static page_table_t + second_lvl_pgtbl ATTR_BSS_KERN_PAGE_ALIGNED; +/* Leaf-level page table */ +static page_table_t leaf_pgtbl ATTR_BSS_KERN_PAGE_ALIGNED; + +#define LINEAR_ADDR_BOUND (MIN_PAGE_SIZE * ENTRIES_PER_PAGE_TABLE) + +/*---------------------------------------------------------------------------*/ +void +prot_domains_reg(dom_client_data_t *dcd, + uintptr_t mmio, + size_t mmio_sz, + uintptr_t meta, + size_t meta_sz, + bool pio) +{ + dom_id_t dom_id = dcd->dom_id; + volatile struct dom_kern_data *dkd = + prot_domains_kern_data + dom_id; + + /* All addresses and sizes must be page-aligned */ + if((PROT_DOMAINS_ACTUAL_CNT <= dom_id) || + ((mmio & (MIN_PAGE_SIZE - 1)) != 0) || + ((mmio_sz & (MIN_PAGE_SIZE - 1)) != 0) || + ((meta & (MIN_PAGE_SIZE - 1)) != 0) || + ((meta_sz & (MIN_PAGE_SIZE - 1)) != 0) || + (PROT_DOMAINS_MAX_MMIO_SZ < mmio_sz) || + (LINEAR_ADDR_BOUND < (PROT_DOMAINS_META_LINEAR_BASE + meta_sz))) { + halt(); + } + + if((dkd->flags & PROT_DOMAINS_FLAG_INITED) == PROT_DOMAINS_FLAG_INITED) { + halt(); + } + + dkd->mmio = mmio; + dkd->mmio_sz = mmio_sz; + dkd->meta = meta; + dkd->meta_sz = meta_sz; + dkd->flags = PROT_DOMAINS_FLAG_INITED; + if(pio) { + dkd->flags |= PROT_DOMAINS_FLAG_PIO; + } +} +/*---------------------------------------------------------------------------*/ +static void __attribute__((regparm(3))) +set_ptes(uintptr_t start_la, uintptr_t start_pa, uintptr_t end_pa, + pte_t template) +{ +#ifdef DBG_PAGE_ALLOC +#warning Checking page allocations at runtime. + + if(((start_la & (MIN_PAGE_SIZE - 1)) != 0) || + ((start_pa & (MIN_PAGE_SIZE - 1)) != 0) || + ((start_la & (MIN_PAGE_SIZE - 1)) != 0) || + ((end_pa & (MIN_PAGE_SIZE - 1)) != 0) || + (LINEAR_ADDR_BOUND <= (start_la + (end_pa - start_pa)))) { + halt(); + } +#endif + + while(start_pa < end_pa) { + template.addr = start_pa >> 12; + + leaf_pgtbl[start_la >> MIN_PAGE_SIZE_SHAMT] = template; + +#ifdef X86_CONF_USE_INVLPG + __asm__("invlpg %0" :: "m" (*(uint8_t *)start_la)); +#endif + + start_la += MIN_PAGE_SIZE; + start_pa += MIN_PAGE_SIZE; + } +} +/*---------------------------------------------------------------------------*/ +static void __attribute__((fastcall)) +set_ptes_identity_map(uintptr_t start_pa, uintptr_t end_pa, pte_t template) +{ + set_ptes(start_pa, start_pa, end_pa, template); +} +/*---------------------------------------------------------------------------*/ +static inline uint32_t __attribute__((always_inline)) +prot_domains_switch(dom_id_t from_id, dom_id_t to_id, + interrupt_stack_t *intr_stk) +{ + volatile dom_kern_data_t *from, *to; + + from = prot_domains_kern_data + from_id; + to = prot_domains_kern_data + to_id; + + if((from_id == DOM_ID_kern) || + (to_id == DOM_ID_kern)) { + pte_t to_kern_data_pte = { .raw = 0 }; + to_kern_data_pte.present = 1; + to_kern_data_pte.exec_disable = 1; + /* The kernel data region should always be accessible to supervisory code, + * but it is only accessible to user mode in the kernel protection domain. + */ + to_kern_data_pte.user_accessible = 1; + if(to_id == DOM_ID_kern) { + to_kern_data_pte.writable = 1; + } + + set_ptes_identity_map((uintptr_t)&_sbss_kern_addr, + (uintptr_t)&_ebss_syscall_addr, + to_kern_data_pte); + + if(to_id != DOM_ID_kern) { + to_kern_data_pte.user_accessible = 0; + to_kern_data_pte.writable = 0; + } + + set_ptes_identity_map((uintptr_t)&_ebss_syscall_addr, + (uintptr_t)&_ebss_kern_addr, + to_kern_data_pte); + } + + if(to->mmio_sz != 0) { + pte_t pte = { .raw = 0 }; + pte.present = 1; + pte.exec_disable = 1; + pte.user_accessible = 1; + pte.writable = 1; + /* disable caching of MMIO accesses */ + pte.pcd = 1; + + set_ptes(PROT_DOMAINS_MMIO_LINEAR_BASE, + to->mmio, + to->mmio + to->mmio_sz, + pte); + } + if(to->mmio_sz < from->mmio_sz) { + pte_t pte = { .raw = 0 }; + + set_ptes_identity_map(PROT_DOMAINS_MMIO_LINEAR_BASE + to->mmio_sz, + PROT_DOMAINS_MMIO_LINEAR_BASE + from->mmio_sz, + pte); + } + + if(to->meta_sz != 0) { + pte_t pte = { .raw = 0 }; + pte.present = 1; + pte.exec_disable = 1; + pte.user_accessible = 1; + pte.writable = 1; + + set_ptes(PROT_DOMAINS_META_LINEAR_BASE, + to->meta, + to->meta + to->meta_sz, + pte); + } + if(to->meta_sz < from->meta_sz) { + pte_t pte = { .raw = 0 }; + + set_ptes_identity_map(PROT_DOMAINS_META_LINEAR_BASE + to->mmio_sz, + PROT_DOMAINS_META_LINEAR_BASE + from->mmio_sz, + pte); + } + +#ifndef X86_CONF_USE_INVLPG + __asm__ __volatile__ ("mov %%cr3, %%eax\n\t" + "mov %%eax, %%cr3\n\t" ::: "eax"); +#endif + + return 0; +} +/*---------------------------------------------------------------------------*/ +void +prot_domains_gdt_init(void) +{ + gdt_copy_desc_change_dpl(GDT_IDX_DATA, GDT_IDX_DATA_FLAT, PRIV_LVL_USER); + gdt_copy_desc_change_dpl(GDT_IDX_STK_INT, GDT_IDX_STK_EXC, PRIV_LVL_INT); +} +/*---------------------------------------------------------------------------*/ +void +prot_domains_impl_init(void) +{ + pte_t pte = { .raw = 0 }; + + syscalls_int_init(); + + /* Initialize page table: */ + + pte.present = 1; + pte.addr = ((uint32_t)second_lvl_pgtbl) >> MIN_PAGE_SIZE_SHAMT; + + root_pgtbl[0] = pte; + + pte.writable = 1; + pte.user_accessible = 1; + pte.addr = ((uint32_t)leaf_pgtbl) >> MIN_PAGE_SIZE_SHAMT; + + second_lvl_pgtbl[0] = pte; + + /* Map code sections: */ + + pte.writable = 0; + set_ptes_identity_map((uintptr_t)&_stext_addr, (uintptr_t)&_etext_addr, pte); + + /* Map data sections: */ + + pte.writable = 1; + pte.exec_disable = 1; + set_ptes_identity_map((uintptr_t)stacks_main, + (uintptr_t)stacks_main + + STACKS_SIZE_MAIN + + STACKS_SIZE_EXC + + STACKS_SIZE_INT, + pte); + set_ptes_identity_map((uintptr_t)&_sdata_addr, (uintptr_t)&_edata_addr, pte); + + /* Enable XD bit support */ + __asm__ __volatile__ ("wrmsr" :: "c" (MSR_EFER), "a" (EFER_NXE), "d" (0)); + + /* Enable PAE */ + __asm__ __volatile__ ("mov %%cr4, %%eax\n\t" + "or %0, %%eax\n\t" + "mov %%eax, %%cr4\n\t" + : + : "r" (CR4_PAE) + : "eax"); + + /* Load CR3 */ + __asm__ __volatile__ ("mov %0, %%cr3" :: "r" (root_pgtbl)); +} +/*---------------------------------------------------------------------------*/ +uintptr_t +prot_domains_lookup_meta_phys_base(dom_client_data_t *drv) +{ + return prot_domains_kern_data[drv->dom_id].meta; +} +/*---------------------------------------------------------------------------*/ + +/* Enable inter-procedural optimization with procedures in the following file: + */ +#include "syscalls-int.c" diff --git a/cpu/x86/mm/paging-prot-domains.h b/cpu/x86/mm/paging-prot-domains.h new file mode 100644 index 000000000..0f7f54ea3 --- /dev/null +++ b/cpu/x86/mm/paging-prot-domains.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_MM_PAGING_PROT_DOMAINS_H_ +#define CPU_X86_MM_PAGING_PROT_DOMAINS_H_ + +#include +#include +#include +#include "dma.h" +#include "helpers.h" +#include "paging.h" +#include "syscalls-int.h" + +struct dom_kern_data { + /** Base physical address of optional MMIO region */ + uintptr_t mmio; + /** Number of (contiguous) pages in MMIO region */ + size_t mmio_sz; + /** Base physical address of optional metadata region */ + uintptr_t meta; + /** Number of (contiguous) pages in metadata region */ + size_t meta_sz; + /** Flags are defined with the prefix PROT_DOMAINS_FLAG in prot-domains.h */ + uint32_t flags; + /** + * Original return address from call stack when this protection domain + * invoked some other protection domain. This serves to control the return + * entrypoint. The callee is not permitted to modify this value (unless the + * callee is the kernel protection domain). + */ + uintptr_t orig_ret_addr; + + /* align to next-larger power of 2 to enable usage of shifting instead of + * multiplication to index an array of these structures. + */ +} __attribute__((aligned(32))); + +/** Linear base address at which to map the MMIO region. */ +#define PROT_DOMAINS_MMIO_LINEAR_BASE (MIN_PAGE_SIZE + (uintptr_t)&_ebss_kern_addr) + +/** Maximum supported size of MMIO region */ +#define PROT_DOMAINS_MAX_MMIO_SZ 0x4000 + +/** Linear base address at which to map the metadata region */ +#define PROT_DOMAINS_META_LINEAR_BASE \ + (MIN_PAGE_SIZE + (PROT_DOMAINS_MMIO_LINEAR_BASE + PROT_DOMAINS_MAX_MMIO_SZ)) + +#define PROT_DOMAINS_META_OFF_TO_PHYS(off, meta_phys_base) \ + ((meta_phys_base) + ((off) - PROT_DOMAINS_META_LINEAR_BASE)) + +/** Any MMIO region mapping always starts at a particular linear address. */ +#define PROT_DOMAINS_MMIO(dcd) PROT_DOMAINS_MMIO_LINEAR_BASE +/** + * Any metadata region mapping always starts at a particular linear address. + */ +#define PROT_DOMAINS_META(dcd) PROT_DOMAINS_META_LINEAR_BASE + +#define PROT_DOMAINS_ENTER_ISR(exc) \ + PROT_DOMAINS_ENTER_ISR_COMMON(exc) +#define PROT_DOMAINS_LEAVE_ISR(exc) PROT_DOMAINS_LEAVE_ISR_COMMON(exc) + +/* Enable paging */ +#define CR0_PG BIT(31) +/* Enable write protection in supervisor mode */ +#define CR0_WP BIT(16) +/* Enable protected mode */ +#define CR0_PE BIT(0) + +/** + * \brief Enable or disable write protection enforcement in supervisor mode. + * When disabled, supervisory code (i.e. code running at ring levels + * 0-2) is permitted to write to pages that are marked read-only in + * page tables. + * + * \param en Set to true to enable write protection enforcement. + */ +static inline void prot_domains_set_wp(bool en) +{ + uint32_t cr0_val = CR0_PG | CR0_PE; + if(en) { + cr0_val |= CR0_WP; + } + __asm__ __volatile__ ("mov %0, %%cr0" :: "r"(cr0_val)); +} + +#endif /* CPU_X86_MM_PAGING_PROT_DOMAINS_H_ */ diff --git a/cpu/x86/mm/paging.h b/cpu/x86/mm/paging.h new file mode 100644 index 000000000..7882ceab2 --- /dev/null +++ b/cpu/x86/mm/paging.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_MM_PAGING_H_ +#define CPU_X86_MM_PAGING_H_ + +#include + +/** + * Page table entry format for PAE mode page table. See Intel Combined Manual, + * Vol. 3, Section 4.4 for more details. + */ +typedef union pte { + struct { + uint64_t present : 1; + uint64_t writable : 1; + uint64_t user_accessible : 1; + uint64_t pwt : 1; /**< Specify write-through cache policy */ + uint64_t pcd : 1; /**< Disable caching */ + uint64_t accessed : 1; + uint64_t dirty : 1; + uint64_t : 5; + uint64_t addr : 51; + uint64_t exec_disable : 1; + }; + uint64_t raw; +} pte_t; + +#define ENTRIES_PER_PDPT 4 +#define ENTRIES_PER_PAGE_TABLE 512 + +typedef pte_t pdpt_t[ENTRIES_PER_PDPT]; +typedef pte_t page_table_t[ENTRIES_PER_PAGE_TABLE]; + +#define MIN_PAGE_SIZE_SHAMT 12 +#define MIN_PAGE_SIZE (1 << MIN_PAGE_SIZE_SHAMT) + +#endif /* CPU_X86_MM_PAGING_H_ */ diff --git a/cpu/x86/mm/prot-domains.c b/cpu/x86/mm/prot-domains.c new file mode 100644 index 000000000..56461b381 --- /dev/null +++ b/cpu/x86/mm/prot-domains.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "prot-domains.h" + +#include "gdt.h" +#include +#include "interrupt.h" +#include +#include +#include "syscalls.h" +#include "stacks.h" + +static dom_kern_data_t __attribute__((section(".kern_prot_dom_bss"))) + ATTR_KERN_ADDR_SPACE PROT_DOMAINS_PDCS_NM(kern_dcd); +PROT_DOMAINS_ALLOC_IMPL(kern_dcd); +static dom_client_data_t ATTR_BSS_KERN kern_dcd; +static dom_kern_data_t __attribute__((section(".app_prot_dom_bss"))) + ATTR_KERN_ADDR_SPACE PROT_DOMAINS_PDCS_NM(app_dcd); +PROT_DOMAINS_ALLOC_IMPL(app_dcd); +static dom_client_data_t ATTR_BSS_KERN app_dcd; + +/*---------------------------------------------------------------------------*/ +void +prot_domains_init(void) +{ + segment_desc_t desc; + + gdt_lookup(GDT_IDX_CODE_EXC, &desc); +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG + /* The exception code segment needs to be readable so that the general + * protection fault handler can decode instructions, but the interrupt and + * user level code segments should not be. + */ + SEG_SET_FLAG(desc, TYPE, SEG_TYPE_CODE_EX); +#endif + + SEG_SET_FLAG(desc, DPL, PRIV_LVL_INT); + gdt_insert(GDT_IDX_CODE_INT, desc); + + SEG_SET_FLAG(desc, DPL, PRIV_LVL_USER); + gdt_insert(GDT_IDX_CODE, desc); + + PROT_DOMAINS_INIT_ID(kern_dcd); + prot_domains_reg(&kern_dcd, 0, 0, 0, 0, true); + PROT_DOMAINS_INIT_ID(app_dcd); + prot_domains_reg(&app_dcd, 0, 0, 0, 0, false); + + prot_domains_impl_init(); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/mm/prot-domains.h b/cpu/x86/mm/prot-domains.h new file mode 100644 index 000000000..13062612b --- /dev/null +++ b/cpu/x86/mm/prot-domains.h @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_MM_PROT_DOMAINS_H_ +#define CPU_X86_MM_PROT_DOMAINS_H_ + +#if !__ASSEMBLER__ +#include +#include +#include +#include "helpers.h" +#endif + +#define X86_CONF_PROT_DOMAINS__NONE 0 +#define X86_CONF_PROT_DOMAINS__PAGING 1 +#define X86_CONF_PROT_DOMAINS__TSS 2 +#define X86_CONF_PROT_DOMAINS__SWSEG 3 + +#define X86_CONF_PROT_DOMAINS_MULTI_SEG \ + ((X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS) || \ + (X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG)) + +/** Privilege level (ring) for exception handlers and other supervisory code */ +#define PRIV_LVL_EXC 0 +#if X86_CONF_PROT_DOMAINS != X86_CONF_PROT_DOMAINS__NONE +/** Privilege level for interrupt handlers */ +#define PRIV_LVL_INT 2 +/** Default privilege level */ +#define PRIV_LVL_USER 3 +#else +#define PRIV_LVL_INT PRIV_LVL_EXC +#define PRIV_LVL_USER PRIV_LVL_EXC +#endif + +#define DOM_ID_kern 0 +#define DOM_ID_app 1 + +/** I/O Privilege Level */ +#define EFLAGS_IOPL(pl) ((pl) << 12) +/** Interrupt Enable Flag */ +#define EFLAGS_IF (1u << 9) + +#if !__ASSEMBLER__ + +/** Protection domain ID */ +typedef uint32_t dom_id_t; + +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING +#include "paging-prot-domains.h" +#elif X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS +#include "tss-prot-domains.h" +#elif X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG +#include "swseg-prot-domains.h" +#endif + +#ifndef ATTR_META_ADDR_SPACE +#define ATTR_META_ADDR_SPACE +#endif +#ifndef ATTR_MMIO_ADDR_SPACE +#define ATTR_MMIO_ADDR_SPACE +#endif +#ifndef ATTR_KERN_ADDR_SPACE +#define ATTR_KERN_ADDR_SPACE +#endif + +#ifndef MMIO_READL +#define MMIO_READL(dst, src) dst = (src) +#define MMIO_READW(dst, src) dst = (src) +#define MMIO_READB(dst, src) dst = (src) +#define MMIO_WRITEL(dst, src) MMIO_READL(dst, src) +#define MMIO_WRITEW(dst, src) MMIO_READW(dst, src) +#define MMIO_WRITEB(dst, src) MMIO_READB(dst, src) +#endif +#ifndef KERN_READL +#define KERN_READL(dst, src) dst = (src) +#define KERN_READW(dst, src) dst = (src) +#define KERN_READB(dst, src) dst = (src) +#define KERN_WRITEL(dst, src) KERN_READL(dst, src) +#define KERN_WRITEW(dst, src) KERN_READW(dst, src) +#define KERN_WRITEB(dst, src) KERN_READB(dst, src) +#endif +#ifndef META_READL +#define META_READL(dst, src) dst = (src) +#define META_READW(dst, src) dst = (src) +#define META_READB(dst, src) dst = (src) +#define META_WRITEL(dst, src) META_READL(dst, src) +#define META_WRITEW(dst, src) META_READw(dst, src) +#define META_WRITEB(dst, src) META_READB(dst, src) +#endif + +#ifndef MEMCPY_FROM_META +#define MEMCPY_FROM_META(dst, src, sz) \ + memcpy((void *)(dst), (const void *)(src), (sz)) +#define MEMCPY_TO_META(dst, src, sz) MEMCPY_FROM_META(dst, src, sz) +#endif + +/* The following symbols are defined in the linker script */ +/** Bounds for .text section */ +extern uint32_t _stext_addr, _etext_addr; + +#if X86_CONF_PROT_DOMAINS != X86_CONF_PROT_DOMAINS__NONE + +/** Metadata that should not be DMA-accessible */ +#define ATTR_BSS_META __attribute__((section(".meta_bss"))) ATTR_META_ADDR_SPACE +/** Kernel-owned data */ +#define ATTR_BSS_KERN __attribute__((section(".kern_bss"))) ATTR_KERN_ADDR_SPACE +/** Code that should only be executable during bootup */ +#define ATTR_CODE_BOOT __attribute__((section(".boot_text"))) + +/** + * Domain-defined metadata must be page-aligned, which is implemented by the + * linker script for variables with this attribute. + */ +#define ATTR_BSS_KERN_PAGE_ALIGNED \ + __attribute__((section(".page_aligned_kern_bss"))) + +/** Bounds for .kern_data, .syscall_data, and .prot_dom_data sections */ +extern uint32_t _sbss_kern_addr, _ebss_kern_addr; +/** End of .syscall_data section */ +extern uint32_t _ebss_syscall_addr; +/** Bounds for other data sections */ +extern uint32_t _sdata_addr, _edata_addr; + +#ifndef SEG_KERN +#define SEG_KERN "d" +#endif + +/** + * If set, this protection domain is already in the call stack and is not + * available for nested invocations. + */ +#define PROT_DOMAINS_FLAG_BUSY BIT(0) +/** If set, this protection domain requires port I/O access. */ +#define PROT_DOMAINS_FLAG_PIO BIT(1) +/** If set, this protection domain is initialized. */ +#define PROT_DOMAINS_FLAG_INITED BIT(2) + +/** + * Data associated with each protection domain that should be fully accessible + * only to the kernel, with limited accesses and modifications permitted from + * other domains. Includes storage for system data structures. + */ +typedef struct dom_kern_data dom_kern_data_t; + +extern volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE prot_domains_kern_data[]; +extern volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE prot_domains_kern_data_end[]; + +#define PROT_DOMAINS_ACTUAL_CNT \ + (prot_domains_kern_data_end - prot_domains_kern_data) + +#define PROT_DOMAINS_GET_DOM_ID(dkd) \ + ((dom_id_t)((dkd) - prot_domains_kern_data)) + +void prot_domains_syscall_dispatcher(void); + +#if X86_CONF_PROT_DOMAINS != X86_CONF_PROT_DOMAINS__TSS +/** + * Data associated with each protection domain that is owned by clients of that + * domain and used to identify the domain. + */ +struct dom_client_data { + dom_id_t dom_id; +} __attribute__((packed)); +#endif + +#ifndef PROT_DOMAINS_ALLOC_IMPL +#define PROT_DOMAINS_ALLOC_IMPL(nm) +#endif + +/** Allocate the client-owned protection domain data structure. */ +#define PROT_DOMAINS_PDCS_NM(nm) _pdcs_##nm +#define PROT_DOMAINS_ALLOC(typ, nm) \ + static dom_kern_data_t __attribute__((section(".prot_dom_bss"))) \ + ATTR_KERN_ADDR_SPACE PROT_DOMAINS_PDCS_NM(nm); \ + PROT_DOMAINS_ALLOC_IMPL(nm); \ + static typ ATTR_BSS_KERN nm +#define PROT_DOMAINS_INIT_ID(nm) \ + KERN_WRITEL((nm).dom_id, PROT_DOMAINS_GET_DOM_ID(&PROT_DOMAINS_PDCS_NM(nm))) + +/** + * Perform early initialization during boot stage 0 to prepare for boot stage 1 + */ +void prot_domains_gdt_init() ATTR_CODE_BOOT; +/** + * Perform initialization during boot stage 1 to prepare for kernel launch + */ +void prot_domains_init(); +void prot_domains_impl_init(); + +/* Return from cpu_boot_stage1 will invoke prot_domains_launch_kernel due to + * that return address being pushed on the stack by cpu_boot_stage0. + */ +#define prot_domains_leave_boot_stage1() + +/* Return from main will invoke prot_domains_launch_app due to that return + * address being pushed on the stack by cpu_boot_stage0. + */ +#define prot_domains_leave_main() + +void prot_domains_launch_kernel(void); + +/* Whenever changing this, update syscalls-int-asm.S:prot_domains_launch_kernel + * to match: + */ +#define PROT_DOMAINS_INIT_RET_ADDR_CNT 2 + +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS +void prot_domains_launch_app(void); +#else +void app_main(void); +#define prot_domains_launch_app app_main +#endif + +#else + +#define ATTR_BSS_META +#define ATTR_BSS_KERN +#define ATTR_CODE_BOOT + +struct dom_client_data { + uintptr_t mmio; /**< MMIO range base address */ + uintptr_t meta; /**< Domain-defined metadata base address */ +}; + +/** Retrieve the MMIO base address for the specified protection domain. */ +#define PROT_DOMAINS_MMIO(dcd) ((dcd).mmio) + +/** Retrieve the metadata base address for the specified protection domain. */ +#define PROT_DOMAINS_META(dcd) ((dcd).meta) + +#define PROT_DOMAINS_ALLOC(typ, nm) static typ nm +#define PROT_DOMAINS_INIT_ID(nm) + +#define prot_domains_gdt_init() + +#define prot_domains_init() + +int main(void); +#define prot_domains_leave_boot_stage1 main +#define prot_domains_leave_main ENABLE_IRQ(); app_main + +#define PROT_DOMAINS_INIT_RET_ADDR_CNT 0 + +#endif + +/** + * Protection domain data readable by the client. It is used to control + * execution, so it should be protected from modifications by clients. + * Otherwise, there is a risk that one client could modify one of these + * structures used by another client to issue a system call, which could then + * cause the latter client to perform an unintended system call. + */ +typedef struct dom_client_data dom_client_data_t; + +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__NONE +#define prot_domains_reg(dcd, mmio_, mmio_sz, meta_, meta_sz, pio) \ + (dcd)->mmio = (mmio_); \ + (dcd)->meta = (meta_) +#else +/** + * \brief Register a protection domain, which involves creating the + * necessary system data structures for it. + * + * \param dcd Client-accessible domain information + * \param mmio Optional base address for per-domain memory-mapped IO region + * \param mmio_sz Size of MMIO region + * \param meta Optional base address for per-domain metadata + * \param meta_sz Size of metadata + * \param pio Set to true if protection domain requires port IO access + */ +void prot_domains_reg(dom_client_data_t ATTR_KERN_ADDR_SPACE *dcd, + uintptr_t mmio, + size_t mmio_sz, + uintptr_t meta, + size_t meta_sz, + bool pio); +#endif + +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__NONE +#define prot_domains_copy_dcd(dst, src) *(dst) = *(src) +#else +static inline void +/** + * It is necessary to make a local copy of a dom_client_data structure when a + * multi-segment protection domain implementation is in use, segment attributes + * are not supported by the compiler, and a dom_client_data structure needs to + * be passed by value into some function. Otherwise, the compiler will not know + * to access the non-default segment in which *src is stored and will attempt + * to copy it out of the default data segment. + */ +prot_domains_copy_dcd(struct dom_client_data *dst, + struct dom_client_data ATTR_KERN_ADDR_SPACE *src) +{ + KERN_READL(dst->dom_id, src->dom_id); +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS + KERN_READL(dst->tss_sel, src->tss_sel); +#endif +} +#endif + +#if !X86_CONF_PROT_DOMAINS_MULTI_SEG +#define prot_domains_enable_mmio() +#define prot_domains_disable_mmio() + +#define KERN_DATA_OFF_TO_PHYS_ADDR(x) ((uintptr_t)(x)) +#define DATA_OFF_TO_PHYS_ADDR(x) ((uintptr_t)(x)) +#endif + +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__NONE +#define prot_domains_lookup_meta_phys_base(drv) 0 +#else +/** Lookup base physical address of metadata region for specified domain */ +uintptr_t prot_domains_lookup_meta_phys_base(dom_client_data_t ATTR_KERN_ADDR_SPACE *drv); +#endif + +#if X86_CONF_PROT_DOMAINS != X86_CONF_PROT_DOMAINS__PAGING +#define PROT_DOMAINS_META_OFF_TO_PHYS(off, meta_phys_base) \ + ((meta_phys_base) + (off)) +#endif + +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__NONE +#define PROT_DOMAINS_ENTER_ISR(...) +#define PROT_DOMAINS_LEAVE_ISR(...) +#else +#define PROT_DOMAINS_ENTER_ISR_COMMON(exc) \ + ".if !" #exc "\n\t" \ + /* Save the current stack pointer into a callee-saved register. */ \ + "mov %%esp, %%ebx\n\t" \ + /* Pivot to the main stack of the interrupted context. */ \ + /* Interrupts never have an error code, so the offset is always 44. */ \ + /* No interrupt handlers use anything from the original interrupt stack, */ \ + /* so there is no need to copy anything from it to the main stack. */ \ + "mov 44(%%esp), %%esp\n\t" \ + ".endif\n\t" +#define PROT_DOMAINS_LEAVE_ISR_COMMON(exc) \ + /* Restore the interrupt/exception stack pointer. */ \ + ".if !" #exc "\n\t" \ + "mov %%ebx, %%esp\n\t" \ + ".endif\n\t" +#endif + +#ifdef X86_CONF_PROT_DOMAINS_MULTI_SEG +/* include GDT section definitions used when allocating protection domains: */ +#include "gdt.h" +#endif + +#endif /* !__ASSEMBLER__ */ + +#endif /* CPU_X86_MM_PROT_DOMAINS_H_ */ diff --git a/cpu/x86/mm/segmentation.h b/cpu/x86/mm/segmentation.h new file mode 100644 index 000000000..71cd6beb6 --- /dev/null +++ b/cpu/x86/mm/segmentation.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_MM_SEGMENTATION_H_ +#define CPU_X86_MM_SEGMENTATION_H_ + +#include + +#define SEG_FLAG(lbl, val) \ + (((val) & (~0u >> (32 - SEG_WIDTH_##lbl))) << SEG_SHAMT_##lbl) + +#define SEG_SET_FLAG(desc, lbl, val) \ + (desc).flags = ((desc).flags & ~SEG_FLAG(lbl, ~0u)) | SEG_FLAG(lbl, val) + +#define SEG_WIDTH_TYPE 4 +#define SEG_SHAMT_TYPE 0 +#define SEG_WIDTH_DESCTYPE 1 +#define SEG_SHAMT_DESCTYPE 4 +#define SEG_WIDTH_DPL 2 +#define SEG_SHAMT_DPL 5 +#define SEG_WIDTH_PRESENT 1 +#define SEG_SHAMT_PRESENT 7 +#define SEG_WIDTH_LIMIT_HI 4 +#define SEG_SHAMT_LIMIT_HI 8 +#define SEG_WIDTH_AVL 1 +#define SEG_SHAMT_AVL 12 +#define SEG_WIDTH_LONG_MODE 1 +#define SEG_SHAMT_LONG_MODE 13 +/* also used to indicate default operand and address size */ +#define SEG_WIDTH_DIRECTION 1 +#define SEG_SHAMT_DIRECTION 14 +#define SEG_WIDTH_GRAN 1 +#define SEG_SHAMT_GRAN 15 + +#define SEG_TYPE_DATA_RDONLY SEG_FLAG(TYPE, 0x00) /* Read only */ +#define SEG_TYPE_DATA_RDWR SEG_FLAG(TYPE, 0x02) /* Read/Write */ +#define SEG_TYPE_CODE_EXRD SEG_FLAG(TYPE, 0x0A) /* Execute/Read */ +#define SEG_TYPE_CODE_EX SEG_FLAG(TYPE, 0x08) /* Execute only */ +#define SEG_TYPE_LDT SEG_FLAG(TYPE, 0x02) +#define SEG_TYPE_TSS32_AVAIL SEG_FLAG(TYPE, 0x09) + +#define SEG_DESCTYPE_SYS SEG_FLAG(DESCTYPE, 0) +#define SEG_DESCTYPE_NSYS SEG_FLAG(DESCTYPE, 1) + +#define SEG_PRESENT SEG_FLAG(PRESENT, 1) + +#define SEG_DEFL_OPSZ_32BIT SEG_FLAG(DIRECTION, 1) + +#define SEG_GRAN_BYTE SEG_FLAG(GRAN, 0) +#define SEG_GRAN_PAGE SEG_FLAG(GRAN, 1) + +/** + * Maximum length of segment that can be regulated with a byte-granularity + * segment limit. + */ +#define SEG_MAX_BYTE_GRAN_LEN (1 << 20) + +/** + * Segment descriptor. See Intel Combined Manual, + * Vol. 3, Section 3.4.5 for more details. + */ +typedef union segment_desc { + struct { + uint32_t lim_lo : 16; + uint32_t base_lo : 16; + uint32_t base_mid : 8; + uint32_t flags : 16; + uint32_t base_hi : 8; + }; + struct { + uint32_t raw_lo, raw_hi; + }; + uint64_t raw; +} segment_desc_t; + +#define SEG_DESC_NOT_PRESENT 0 + +/* The next two functions are invoked by boot code, so they must always be + * inlined to avoid being placed in a different address space than the initial, + * flat address space. + */ +static inline void __attribute__((always_inline)) +segment_desc_set_limit(segment_desc_t *c_this, uint32_t len) +{ + uint32_t limit = len - 1; + + SEG_SET_FLAG(*c_this, LIMIT_HI, limit >> 16); /* set limit bits 19:16 */ + c_this->lim_lo = limit; /* set limit bits 15:0 */ +} +/** + * \brief Initialize a segment descriptor. + * \param c_this Segment descriptor to be initialized. + * \param base Base address of region to be covered by segment descriptor. + * \param len Length to be specified by segment descriptor. The units may + * be bytes or pages, depending on the flags. + * \param flags Flags to be added to the default flags: present, default + * operand size of 32 bits, and high limit bits. + */ +static inline void __attribute__((always_inline)) +segment_desc_init(segment_desc_t *c_this, + uint32_t base, uint32_t len, uint16_t flags) +{ + c_this->raw = 0; + + /* Create the high 32 bit segment */ + c_this->base_mid = base >> 16; /* set base bits 23:16 */ + c_this->base_hi = base >> 24; /* set base bits 31:24 */ + + /* Create the low 32 bit segment */ + c_this->base_lo = base; /* set base bits 15:0 */ + + c_this->flags = SEG_FLAG(PRESENT, 1) | SEG_DEFL_OPSZ_32BIT | flags; + + /* This must be done after setting the other flags, or else it + * would be partially overridden. + */ + segment_desc_set_limit(c_this, len); +} +#endif /* CPU_X86_MM_SEGMENTATION_H_ */ diff --git a/cpu/x86/mm/stacks.c b/cpu/x86/mm/stacks.c new file mode 100644 index 000000000..60ccb0ebc --- /dev/null +++ b/cpu/x86/mm/stacks.c @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "stacks.h" + +uint8_t stacks_main[STACKS_SIZE_MAIN] + __attribute__((section(".main_stack"), aligned(4))); +#if X86_CONF_PROT_DOMAINS != X86_CONF_PROT_DOMAINS__NONE +uint8_t stacks_int[STACKS_SIZE_INT] + __attribute__((section(".int_stack"), aligned(4))); +uint8_t stacks_exc[STACKS_SIZE_EXC] + __attribute__((section(".exc_stack"), aligned(4))); +#endif diff --git a/cpu/x86/mm/stacks.h b/cpu/x86/mm/stacks.h new file mode 100644 index 000000000..327e75600 --- /dev/null +++ b/cpu/x86/mm/stacks.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_MM_STACKS_H_ +#define CPU_X86_MM_STACKS_H_ + +#include "prot-domains.h" + +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__NONE +#define STACKS_SIZE_INT 0 +#else +/** + * The necessary amount of space for the interrupt and exception stacks is + * determined by the amount of data pushed on the stack by the CPU when + * delivering an interrupt or exception, and by the additional data pushed + * on the stack by the interrupt dispatcher. See interrupt.h for more details. + */ +#define STACKS_SIZE_INT (14 * 4) +#endif + +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING +/** + * The system call and return dispatchers use this stack, so its size was + * determined by observing their behavior. It is possible that the dispatchers + * could overflow the stack and overwrite data on the other stacks. An + * alternative design that would facilitate detection of such overflows would + * place the exception handler stack on a separate page surrounded by guard + * bands, but that would consume a substantial amount of additional memory. + * + * All stack sizes should be a multiple of 4 to accommodate a 4-byte alignment. + */ +#ifdef __clang__ +#define STACKS_SIZE_EXC 512 +#else +#define STACKS_SIZE_EXC 256 +#endif +#elif X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG +#ifdef __clang__ +#define STACKS_SIZE_EXC 512 +#else +#define STACKS_SIZE_EXC 256 +#endif +#elif X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS +/** + * This should be large enough to execute the exception handler with the + * largest stack requirement: double_fault_handler: + * - 1 word for the return address from calling double_fault_handler + * - 1 word for the saved frame pointer in double_fault_handler + * - 2 words that GCC has been observed to skip on the stack to align it + * to a preferred boundary + * - 1 word for the return address for calling halt + */ +#define STACKS_SIZE_EXC (STACKS_SIZE_INT + (6 * 4)) +#else +#define STACKS_SIZE_EXC STACKS_SIZE_INT +#endif +/** + * The combined size of the stacks should be an even multiple of the 4K page + * size so that they precisely fill some number of pages when paging-based + * protection domains are in use. The stacks are arranged contiguously by + * the linker scripts. See those and README.md for more details. + */ +#define STACKS_SIZE_MAIN (8192 - (STACKS_SIZE_INT + STACKS_SIZE_EXC)) + +#if !__ASSEMBLER__ +/** + * Stack for exception handlers. Also used for system call and return + * dispatchers when paging-based protection domains are enabled. + */ +extern uint8_t stacks_exc[STACKS_SIZE_EXC]; +/** Stack for interrupt handlers. */ +extern uint8_t stacks_int[STACKS_SIZE_INT]; +/** Main C stack. */ +extern uint8_t stacks_main[STACKS_SIZE_MAIN]; + +#define STACKS_INIT_TOP \ + ((uintptr_t)stacks_main + STACKS_SIZE_MAIN - \ + (PROT_DOMAINS_INIT_RET_ADDR_CNT * sizeof(uintptr_t))) + +#endif + +#endif /* CPU_X86_MM_STACKS_H_ */ diff --git a/cpu/x86/mm/swseg-prot-domains.c b/cpu/x86/mm/swseg-prot-domains.c new file mode 100644 index 000000000..78a29aaf6 --- /dev/null +++ b/cpu/x86/mm/swseg-prot-domains.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "gdt.h" +#include "helpers.h" +#include "multi-segment.h" +#include "prot-domains.h" + +/*---------------------------------------------------------------------------*/ +void +prot_domains_reg(dom_client_data_t ATTR_KERN_ADDR_SPACE *dcd, + uintptr_t mmio, size_t mmio_sz, + uintptr_t meta, size_t meta_sz, + bool pio) +{ + volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE *dkd; + dom_id_t dom_id; + + KERN_READL(dom_id, dcd->dom_id); + + if(PROT_DOMAINS_ACTUAL_CNT <= dom_id) { + halt(); + } + + dkd = prot_domains_kern_data + dom_id; + + prot_domains_reg_multi_seg(dkd, mmio, mmio_sz, meta, meta_sz); + + KERN_WRITEL(dkd->flags, pio ? PROT_DOMAINS_FLAG_PIO : 0); +} +/*---------------------------------------------------------------------------*/ +static inline void __attribute__((always_inline)) +prot_domains_switch(dom_id_t from_id, dom_id_t to_id, + interrupt_stack_t *intr_stk) +{ + __asm__ __volatile__ ( + "lldt %[_ldt_]\n\t" + "mov %[_meta_seg_], %%eax\n\t" + "lsl %%eax, %%ecx\n\t" + "jz 1f\n\t" /* ZF will only be set if the segment descriptor is valid. */ + "xor %%eax, %%eax\n\t" /* Nullify metadata selector */ + "1: mov %%eax, %%" SEG_META "s\n\t" + "mov %[_kern_seg_], %%eax\n\t" + "mov %%eax, %%" SEG_KERN "s\n\t" + : + : [_ldt_] "r" ((uint16_t)GDT_SEL_LDT(to_id)), + [_meta_seg_] "i" (LDT_SEL_META), + [_kern_seg_] "i" (LDT_SEL_KERN) + : "cc", "eax", "ecx" + ); +} +/*---------------------------------------------------------------------------*/ + +/* Enable inter-procedural optimization with procedures in the following file: + */ +#include "syscalls-int.c" diff --git a/cpu/x86/mm/swseg-prot-domains.h b/cpu/x86/mm/swseg-prot-domains.h new file mode 100644 index 000000000..a503bc6db --- /dev/null +++ b/cpu/x86/mm/swseg-prot-domains.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_MM_SWSEG_PROT_DOMAINS_H_ +#define CPU_X86_MM_SWSEG_PROT_DOMAINS_H_ + +#include +#include +#include +#include "ldt-layout.h" +#include "paging.h" +#include "segmentation.h" +#include "syscalls-int.h" + +struct dom_kern_data { + /** Local Descriptor Table with per-domain descriptors */ + segment_desc_t ldt[LDT_NUM_DESC]; + /** Flags are defined with the prefix PROT_DOMAINS_FLAG in prot-domains.h */ + uint32_t flags; + /** + * Original return address from call stack when this protection domain + * invoked some other protection domain. This serves to control the return + * entrypoint. The callee is not permitted to modify this value (unless the + * callee is the kernel protection domain). + */ + uintptr_t orig_ret_addr; + + /* This structure is precisely 32 bytes in length, a power of 2. If its size + * changes, add an alignment attribute to keep it aligned at a power of 2 so + * that dereferencing arrays of these structures uses shift instructions + * instead of multiplication. Shifting is faster than multiplication. + */ +}; + +/* relies on dom_kern_data: */ +#include "multi-segment.h" + +#define PROT_DOMAINS_ENTER_ISR(exc) \ + MULTI_SEGMENT_ENTER_ISR(exc) \ + PROT_DOMAINS_ENTER_ISR_COMMON(exc) +#define PROT_DOMAINS_LEAVE_ISR(exc) \ + PROT_DOMAINS_LEAVE_ISR_COMMON(exc) \ + MULTI_SEGMENT_LEAVE_ISR(exc) + +#define prot_domains_impl_init syscalls_int_init + +#define prot_domains_set_wp(en) + +/* Allocate one additional GDT entry for each protection domain. Note that + * the particular storage allocated by this statement may actually be used for + * some other protection domain, depending on how the linker happens to arrange + * all of the GDT storage. The GDT_IDX_LDT macro in gdt-layout.h determine + * which storage is used for each protection domain. Thus, this storage should + * not be referenced directly by its variable name. + */ +#define PROT_DOMAINS_ALLOC_IMPL(nm) \ + static segment_desc_t ATTR_BSS_GDT_MID _gdt_storage_##nm + +#endif /* CPU_X86_MM_SWSEG_PROT_DOMAINS_H_ */ diff --git a/cpu/x86/mm/syscalls-int-asm.S b/cpu/x86/mm/syscalls-int-asm.S new file mode 100644 index 000000000..5c88c890b --- /dev/null +++ b/cpu/x86/mm/syscalls-int-asm.S @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "syscalls-int.h" +#include "prot-domains.h" +#include "gdt-layout.h" +#include "stacks.h" + +/* Must match definitions (plus the trailing 's') in multi-segment.h */ +#define SEG_MMIO fs +#define SEG_KERN fs + +.text + +/* Invoke the system call return dispatcher from the default privilege + * level + */ +.global prot_domains_sysret_stub +prot_domains_sysret_stub: + int $PROT_DOMAINS_SYSRET_DISPATCH_INT + +.macro save_segs +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG + /* Save (and restore, in restore_segs) MMIO segment register into + * callee-saved register in case a system call was invoked from a region in + * which MMIO is enabled. + */ + push %SEG_MMIO +#endif +.endm + +.macro restore_segs +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG + pop %SEG_MMIO +#endif +.endm + +/* Refresh most of the segment registers in case they were corrupted by + * userspace code to prevent that from corrupting the operation of the + * privileged code. + */ +.macro load_kern_segs +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG + mov $GDT_SEL_DATA, %eax + mov %eax, %ds + mov %eax, %es + mov $GDT_SEL_DATA_KERN_EXC, %eax + mov %eax, %SEG_KERN +#endif +.endm + +/* Invoke the system call dispatcher C routine */ +.global prot_domains_syscall_dispatcher +prot_domains_syscall_dispatcher: + mov %esp, %ecx /*< interrupt_stack_t *intr_stk */ + /* EDX already set to "dom_client_data_t to_dcd" by syscall stub */ + save_segs + push %eax /*< syscalls_entrypoint_t *syscall */ + load_kern_segs + call prot_domains_syscall_dispatcher_impl + /* fastcall convention, so callee pops arguments */ + restore_segs + iret + +/* Invoke the system call return dispatcher C routine */ +.global prot_domains_sysret_dispatcher +prot_domains_sysret_dispatcher: + mov %esp, %ecx /*< interrupt_stack_t *intr_stk */ + save_segs + load_kern_segs + call prot_domains_sysret_dispatcher_impl + restore_segs + /* Zero caller-saved registers in case they contain secrets. The system call + * handlers and dispatchers need to preserve the callee-saved registers. + */ + xor %eax, %eax + xor %ecx, %ecx + xor %edx, %edx + iret + +.global prot_domains_launch_kernel +prot_domains_launch_kernel: +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING + mov $GDT_SEL_DATA, %eax + mov %eax, %ds + mov %eax, %es + mov %eax, %fs + mov %eax, %gs +#else + mov $GDT_SEL_LDT(DOM_ID_kern), %eax + lldt %ax + call multi_segment_launch_kernel +#endif + /* init interrupt return stack: */ + pushl $GDT_SEL_STK + lea stacks_main, %eax + /* matches STACKS_INIT_TOP, plus 4 since an address has been consumed: */ + add $(STACKS_SIZE_MAIN - 4), %eax + pushl %eax + pushl $EFLAGS_IOPL(PRIV_LVL_INT) + pushl $GDT_SEL_CODE + pushl $0 /* will be overwritten by syscall_dispatcher_impl */ + /* fastcall convention: */ + mov %esp, %ecx + call prot_domains_launch_kernel_impl + iretl diff --git a/cpu/x86/mm/syscalls-int.c b/cpu/x86/mm/syscalls-int.c new file mode 100644 index 000000000..6820d3264 --- /dev/null +++ b/cpu/x86/mm/syscalls-int.c @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "prot-domains.h" +#include "tss.h" +#include "helpers.h" +#include "stacks.h" +#include "idt.h" +#include "syscalls.h" +#include "gdt.h" +#include "gdt-layout.h" +#include "interrupt.h" + +/** + * Current protection domain. Not protected, since it is just a convenience + * variable to avoid unneeded protection domain switches. + */ +dom_id_t cur_dom = DOM_ID_app; + +/* defined in syscalls-int-asm.S */ +void prot_domains_sysret_dispatcher(void); + +/* Maximum depth of inter-domain call stack */ +#define MAX_INTER_DOM_CALL_STK_SZ 4 + +/* Protected call stack for inter-domain system calls. The stack grows up. */ +static volatile dom_id_t ATTR_BSS_KERN + inter_dom_call_stk[MAX_INTER_DOM_CALL_STK_SZ]; + +/* Pointer to the next (free) slot in the inter-domain call stack */ +static int ATTR_BSS_KERN inter_dom_call_stk_ptr; + +/*---------------------------------------------------------------------------*/ +static inline void __attribute__((always_inline)) +update_eflags(dom_id_t from_id, dom_id_t to_id, interrupt_stack_t *intr_stk) +{ + if((to_id == DOM_ID_app) && + (DT_SEL_GET_RPL(intr_stk->cs) == PRIV_LVL_USER)) { + /* Only enable interrupts in the application protection domain cooperative + * scheduling context. + */ + intr_stk->eflags |= EFLAGS_IF; + } else { + intr_stk->eflags &= ~EFLAGS_IF; + } +} +/*---------------------------------------------------------------------------*/ +static inline void __attribute__((always_inline)) +dispatcher_tail(dom_id_t from_id, dom_id_t to_id, interrupt_stack_t *intr_stk) +{ + cur_dom = to_id; + + prot_domains_switch(from_id, to_id, intr_stk); + + prot_domains_set_wp(true); + + update_eflags(from_id, to_id, intr_stk); +} +/*---------------------------------------------------------------------------*/ +int main(void); +static inline void __attribute__((always_inline)) +syscall_dispatcher_tail(interrupt_stack_t *intr_stk, + dom_id_t to_id, + uint32_t syscall_eip) +{ + dom_id_t from_id; + uint32_t tmp; + volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE *from_dkd, *to_dkd; + + uint32_t loc_call_stk_ptr; + + to_dkd = prot_domains_kern_data + to_id; + + /* This implementation of protection domains is non-reentrant. For example, + * it stores the return address taken from the stack of a caller domain + * while dispatching a system call and stores it in a single field in the + * kernel data associated with that protection domain. That model does not + * permit reentrancy. + */ + KERN_READL(tmp, to_dkd->flags); + if((tmp & PROT_DOMAINS_FLAG_BUSY) == PROT_DOMAINS_FLAG_BUSY) { + halt(); + } + tmp |= PROT_DOMAINS_FLAG_BUSY; + KERN_WRITEL(to_dkd->flags, tmp); + + /* Update the interrupt stack so that the IRET instruction will return to the + * system call entrypoint. + */ + intr_stk->eip = syscall_eip; + + KERN_READL(loc_call_stk_ptr, inter_dom_call_stk_ptr); + /* Lookup the information for the caller */ + KERN_READL(from_id, inter_dom_call_stk[loc_call_stk_ptr - 1]); + from_dkd = prot_domains_kern_data + from_id; + + /* Save the current return address from the unprivileged stack to a protected + * location in the kernel-owned data structure. This enforces return + * entrypoint control. + */ + KERN_WRITEL(from_dkd->orig_ret_addr, *(uintptr_t *)intr_stk->esp); + /* Update the unprivileged stack so that when the system call body is + * complete, it will invoke the system call return stub. + */ + *((uintptr_t *)intr_stk->esp) = (uintptr_t)prot_domains_sysret_stub; + + if(MAX_INTER_DOM_CALL_STK_SZ <= loc_call_stk_ptr) { + halt(); + } + KERN_WRITEL(inter_dom_call_stk[loc_call_stk_ptr], to_id); + + loc_call_stk_ptr++; + KERN_WRITEL(inter_dom_call_stk_ptr, loc_call_stk_ptr); + + dispatcher_tail(from_id, to_id, intr_stk); +} +/*---------------------------------------------------------------------------*/ +void __attribute__((fastcall)) +prot_domains_syscall_dispatcher_impl(interrupt_stack_t *intr_stk, + dom_id_t to_id, + syscalls_entrypoint_t *syscall) +{ + uint32_t tmp; + uint32_t syscall_eip; + + if(PROT_DOMAINS_ACTUAL_CNT <= to_id) { + halt(); + } + + /* Get the approved entrypoint for the system call being invoked */ + + if(!((((uintptr_t)syscalls_entrypoints) <= (uintptr_t)syscall) && + (((uintptr_t)syscall) < (uintptr_t)syscalls_entrypoints_end) && + (((((uintptr_t)syscall) - (uintptr_t)syscalls_entrypoints) + % sizeof(syscalls_entrypoint_t)) == 0))) { + /* Assert is not usable when switching protection domains */ + halt(); + } + + KERN_READL(tmp, syscall->doms); + if((BIT(to_id) & tmp) == 0) { + halt(); + } + + KERN_READL(syscall_eip, syscall->entrypoint); + + prot_domains_set_wp(false); + + syscall_dispatcher_tail(intr_stk, to_id, syscall_eip); +} +/*---------------------------------------------------------------------------*/ +int main(void); +void __attribute__((fastcall)) +prot_domains_launch_kernel_impl(interrupt_stack_t *intr_stk) +{ + KERN_WRITEL(inter_dom_call_stk[0], DOM_ID_app); + + KERN_WRITEL(inter_dom_call_stk_ptr, 1); + + syscall_dispatcher_tail(intr_stk, DOM_ID_kern, (uint32_t)main); +} +/*---------------------------------------------------------------------------*/ +void __attribute__((fastcall)) +prot_domains_sysret_dispatcher_impl(interrupt_stack_t *intr_stk) +{ + dom_id_t from_id, to_id; + uint32_t loc_call_stk_ptr; + uint32_t flags; + + KERN_READL(loc_call_stk_ptr, inter_dom_call_stk_ptr); + if(loc_call_stk_ptr <= 1) { + halt(); + } + + KERN_READL(from_id, inter_dom_call_stk[loc_call_stk_ptr - 1]); + KERN_READL(to_id, inter_dom_call_stk[loc_call_stk_ptr - 2]); + + KERN_READL(intr_stk->eip, + prot_domains_kern_data[to_id].orig_ret_addr); + + prot_domains_set_wp(false); + + KERN_READL(flags, prot_domains_kern_data[from_id].flags); + flags &= ~PROT_DOMAINS_FLAG_BUSY; + KERN_WRITEL(prot_domains_kern_data[from_id].flags, flags); + + KERN_WRITEL(inter_dom_call_stk_ptr, loc_call_stk_ptr - 1); + + dispatcher_tail(from_id, to_id, intr_stk); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Lookup the current protection domain. + * \return Kernel data structure for the current protection domain. + */ +static volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE * +get_current_domain(void) +{ + uint32_t loc_call_stk_ptr; + dom_id_t id; + KERN_READL(loc_call_stk_ptr, inter_dom_call_stk_ptr); + KERN_READL(id, inter_dom_call_stk[loc_call_stk_ptr - 1]); + return prot_domains_kern_data + id; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Check whether the protection domain is authorized to perform port + * I/O from the cooperative scheduling context. + * \param dkd Protection domain to check + * \return Result of the check as a Boolean value + */ +static bool +needs_port_io(volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE *dkd) +{ + uint32_t dkd_flags; + KERN_READL(dkd_flags, dkd->flags); + return (dkd_flags & PROT_DOMAINS_FLAG_PIO) == PROT_DOMAINS_FLAG_PIO; +} +/*---------------------------------------------------------------------------*/ +/* Mark the context parameter as volatile so that writes to it will not get + * optimized out. This parameter is not handled like ordinary function + * parameters. It actually partially includes the contents of the exception + * stack, so updates to those locations can affect the operation of the + * subsequent interrupt return. + */ +static void +gp_fault_handler(volatile struct interrupt_context context) +{ + uint32_t cs_lim; + uint8_t opcode; + + volatile dom_kern_data_t ATTR_KERN_ADDR_SPACE *dkd = get_current_domain(); + if (needs_port_io(dkd)) { + __asm__ __volatile__ ( + "mov %%cs, %0\n\t" + "lsl %0, %0\n\t" + : "=r"(cs_lim)); + + if (cs_lim < context.eip) { + halt(); + } + + /* Load first byte of faulting instruction */ + __asm__ __volatile__ ( + "movb %%cs:%1, %0" + : "=q"(opcode) + : "m"(*(uint8_t *)context.eip)); + + switch (opcode) { + case 0xEC: /* inb */ + context.eax = (context.eax & ~0xFF) | inb((uint16_t)context.edx); + break; + case 0xED: /* inl */ + context.eax = inl((uint16_t)context.edx); + break; + case 0xEE: /* outb */ + outb((uint16_t)context.edx, (uint8_t)context.eax); + break; + case 0xEF: /* outl */ + outl((uint16_t)context.edx, context.eax); + break; + default: + halt(); + } + + /* Skip the faulting port I/O instruction that was emulated. */ + context.eip++; + } else { + halt(); + } +} +/*---------------------------------------------------------------------------*/ +void +syscalls_int_init(void) +{ + tss_init(); + + SET_EXCEPTION_HANDLER(13, 1, gp_fault_handler); + + /* Register system call dispatchers: */ + + idt_set_intr_gate_desc(PROT_DOMAINS_SYSCALL_DISPATCH_INT, + (uint32_t)prot_domains_syscall_dispatcher, + GDT_SEL_CODE_EXC, + PRIV_LVL_USER); + idt_set_intr_gate_desc(PROT_DOMAINS_SYSRET_DISPATCH_INT, + (uint32_t)prot_domains_sysret_dispatcher, + GDT_SEL_CODE_EXC, + PRIV_LVL_USER); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/mm/syscalls-int.h b/cpu/x86/mm/syscalls-int.h new file mode 100644 index 000000000..a5478d1c5 --- /dev/null +++ b/cpu/x86/mm/syscalls-int.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_MM_SYSCALLS_INT_H_ +#define CPU_X86_MM_SYSCALLS_INT_H_ + +/** Software interrupt number for dispatching a system call */ +#define PROT_DOMAINS_SYSCALL_DISPATCH_INT 100 +/** Software interrupt number for returning from a system call */ +#define PROT_DOMAINS_SYSRET_DISPATCH_INT 101 + +#if !__ASSEMBLER__ + +#include + +extern dom_id_t cur_dom; + +#define SYSCALLS_STUB_EPILOGUE(nm) \ + /* Load the system call identifier into EAX, as required by */ \ + /* prot_domains_syscall_dispatcher: */ \ + " mov $" EXP_STRINGIFY(_syscall_ent_##nm) ", %eax\n\t" \ + /* Check whether the server protection domain is already active: */ \ + " cmp %edx, cur_dom\n\t" \ + /* If so, skip the system call dispatcher and directly invoke the */ \ + /* system call body: */ \ + " je _syscall_" #nm "\n\t" \ + " int $" EXP_STRINGIFY(PROT_DOMAINS_SYSCALL_DISPATCH_INT) "\n\t" + +#define SYSCALLS_STUB(nm) \ + SYSCALLS_ALLOC_ENTRYPOINT(nm); \ + asm ( \ + ".text\n\t" \ + ".global " #nm "\n\t" \ + #nm ":\n\t" \ + /* First, load server protection domain ID into EDX, as required by */ \ + /* prot_domains_syscall_dispatcher: */ \ + /* Skip past return address on stack to obtain address of protection */ \ + /* domain ID parameter: */ \ + " mov 4(%esp), %edx\n\t" \ + SYSCALLS_STUB_EPILOGUE(nm)) + +#define SYSCALLS_STUB_SINGLETON(nm, dcd) \ + SYSCALLS_ALLOC_ENTRYPOINT(nm); \ + asm ( \ + ".text\n\t" \ + ".global " #nm "\n\t" \ + #nm ":\n\t" \ + /* First, load server protection domain ID into EDX, as required by */ \ + /* prot_domains_syscall_dispatcher: */ \ + " mov %" SEG_KERN "s:" #dcd ", %edx\n\t" \ + SYSCALLS_STUB_EPILOGUE(nm)) + +void syscalls_int_init(void); + +void prot_domains_sysret_stub(void); + +/* Inter-privilege level interrupt stack with no error code. */ +typedef struct interrupt_stack { + uint32_t eip; + uint32_t cs; + uint32_t eflags; + uint32_t esp; + uint32_t ss; +} interrupt_stack_t; + +#if 0 +/* Declaration only included for documentation purposes: */ +/** + * \brief Switch to a different protection domain. + * \param from_id Origin protection domain. + * \param to_id Destination protection domain. + * \return Segment selector for kernel data access (only used for + * multi-segment implementations). + */ +uint32_t prot_domains_switch(dom_id_t from_id, + dom_id_t to_id, + interrupt_stack_t *intr_stk); +#endif + +#endif + +#endif /* CPU_X86_MM_SYSCALLS_INT_H_ */ diff --git a/cpu/x86/mm/syscalls.h b/cpu/x86/mm/syscalls.h new file mode 100644 index 000000000..cae8ff2f5 --- /dev/null +++ b/cpu/x86/mm/syscalls.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_MM_SYSCALLS_H_ +#define CPU_X86_MM_SYSCALLS_H_ + +#include "helpers.h" +#include "prot-domains.h" +#include + +typedef uint32_t dom_id_bitmap_t; + +typedef struct syscalls_entrypoint { + uintptr_t entrypoint; + dom_id_bitmap_t doms; +} syscalls_entrypoint_t; +extern syscalls_entrypoint_t ATTR_KERN_ADDR_SPACE syscalls_entrypoints[]; +extern syscalls_entrypoint_t ATTR_KERN_ADDR_SPACE syscalls_entrypoints_end[]; + +#define SYSCALLS_ACTUAL_CNT (syscalls_entrypoints_end - syscalls_entrypoints) + +#if X86_CONF_PROT_DOMAINS != X86_CONF_PROT_DOMAINS__NONE + +#define SYSCALLS_ALLOC_ENTRYPOINT(nm) \ + syscalls_entrypoint_t __attribute__((section(".syscall_bss"))) \ + ATTR_KERN_ADDR_SPACE _syscall_ent_##nm + +#define SYSCALLS_INIT(nm) \ + KERN_WRITEL(_syscall_ent_##nm.entrypoint, (uintptr_t)_syscall_##nm); \ + KERN_WRITEL(_syscall_ent_##nm.doms, 0) + +#define SYSCALLS_DEFINE(nm, ...) \ + void _syscall_##nm(__VA_ARGS__); \ + SYSCALLS_STUB(nm); \ + void _syscall_##nm(__VA_ARGS__) + +#define SYSCALLS_DEFINE_SINGLETON(nm, dcd, ...) \ + void _syscall_##nm(__VA_ARGS__); \ + SYSCALLS_STUB_SINGLETON(nm, dcd); \ + void _syscall_##nm(__VA_ARGS__) + +#define SYSCALLS_AUTHZ_UPD(nm, drv, set) \ + { \ + dom_id_t _sc_tmp_id; \ + dom_id_bitmap_t _sc_tmp_bm; \ + KERN_READL(_sc_tmp_id, (drv).dom_id); \ + KERN_READL(_sc_tmp_bm, _syscall_ent_##nm.doms); \ + if(set) { \ + _sc_tmp_bm |= BIT(_sc_tmp_id); \ + } else { \ + _sc_tmp_bm &= ~BIT(_sc_tmp_id); \ + } \ + KERN_WRITEL(_syscall_ent_##nm.doms, _sc_tmp_bm); \ + } + +/** + * Check that any untrusted pointer that could have been influenced by a caller + * (i.e. a stack parameter or global variable) refers to a location at or above + * a certain stack boundary and halt otherwise. This is used to prevent a + * protection domain from calling a different protection domain and passing a + * pointer that references a location in the callee's stack other than its + * parameters. + * + * This also checks that the pointer is either within the stack region or the + * shared data region, which is important for preventing redirection of data + * accesses to MMIO or metadata regions. This check is omitted for multi- + * segment protection domain implementations, since the segment settings + * already enforce this property for pointers dereferenced in DS. Pointers + * that can be influenced by a caller should not be dereferenced in any other + * segment. + * + * The pointer is both validated and copied to a new storage location, which + * must be within the callee's local stack region (excluding the parameter + * region). This is to mitigate scenarios such as two pointers being validated + * and an adversary later inducing a write through one of the pointers to the + * other pointer to corrupt the latter pointer before it is used. + * + * The frame address is adjusted to account for the first word pushed on the + * local frame and the return address, since neither of those should ever be + * referenced by an incoming pointer. In particular, if an incoming pointer + * references the return address, it could potentially redirect execution with + * the privileges of the callee protection domain. + */ +#if X86_CONF_PROT_DOMAINS_MULTI_SEG +#define PROT_DOMAINS_VALIDATE_PTR(validated, untrusted, sz) \ + validated = untrusted; \ + if(((uintptr_t)(validated)) < \ + ((2 * sizeof(uintptr_t)) + (uintptr_t)__builtin_frame_address(0))) { \ + halt(); \ + } +#else +#define PROT_DOMAINS_VALIDATE_PTR(validated, untrusted, sz) \ + validated = untrusted; \ + if((((uintptr_t)(validated)) < \ + ((2 * sizeof(uintptr_t)) + (uintptr_t)__builtin_frame_address(0))) || \ + (((uintptr_t)&_edata_addr) <= (((uintptr_t)(validated)) + (sz)))) { \ + halt(); \ + } +#endif + +#else + +#define SYSCALLS_ALLOC_ENTRYPOINT(nm) +#define SYSCALLS_INIT(nm) +#define SYSCALLS_DEFINE(nm, ...) void nm(__VA_ARGS__) +#define SYSCALLS_DEFINE_SINGLETON(nm, dcd, ...) void nm(__VA_ARGS__) +#define SYSCALLS_AUTHZ_UPD(nm, drv, set) +#define PROT_DOMAINS_VALIDATE_PTR(validated, untrusted, sz) validated = untrusted + +#endif + +#define SYSCALLS_AUTHZ(nm, drv) SYSCALLS_AUTHZ_UPD(nm, drv, true) +#define SYSCALLS_DEAUTHZ(nm, drv) SYSCALLS_AUTHZ_UPD(nm, drv, false) + +#endif /* CPU_X86_MM_SYSCALLS_H_ */ diff --git a/cpu/x86/mm/tss-prot-domains-asm.S b/cpu/x86/mm/tss-prot-domains-asm.S new file mode 100644 index 000000000..45832a62c --- /dev/null +++ b/cpu/x86/mm/tss-prot-domains-asm.S @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +.text + +/* Initialize the TSS fields in prot_domains_reg accordingly: + * Note: Each of these must be a callee-saved register, so that they are + * restored to their original values prior to the task returning. This will + * result in the same values being loaded when the task is next invoked. + */ +#define CUR_DOM_ID_BITMAP esi + +/* Must match SEG_KERN (plus the trailing 's') in multi-segment.h */ +#define SEG_KERN fs + +.global prot_domains_syscall_dispatcher +prot_domains_syscall_dispatcher: +#define PROT_DOMAINS_SYSCALL eax + mov prot_domains_syscall, %PROT_DOMAINS_SYSCALL + cmp $syscalls_entrypoints, %PROT_DOMAINS_SYSCALL + jl halt + cmp $syscalls_entrypoints_end, %PROT_DOMAINS_SYSCALL + jnl halt +#define SYSCALLS_ENTRYPOINTS_ALIGN_MASK ebp + mov $3, %SYSCALLS_ENTRYPOINTS_ALIGN_MASK + and %PROT_DOMAINS_SYSCALL, %SYSCALLS_ENTRYPOINTS_ALIGN_MASK + jnz halt + + /* Compare allowed domains bitmask against current domain ID bitmap. If + * the check fails, then the current domain ID bitmap value will be zeroed + * out, which could cause incorrect behavior in the future. However, the + * response to a failed check is to halt the system, so destroying the + * current domain ID bitmap value will have no effect. + */ + and %SEG_KERN:4(%PROT_DOMAINS_SYSCALL), %CUR_DOM_ID_BITMAP + jz halt + + mov prot_domains_main_esp, %esp + + /* Must be a callee-saved register: */ +#define ORIG_RET_ADDR edi + /* Update the caller's stack to return back to here */ + pop %ORIG_RET_ADDR + push $sysret_dispatcher + /* Jump to the system call body */ + jmp *%SEG_KERN:(%PROT_DOMAINS_SYSCALL) + +sysret_dispatcher: + push %ORIG_RET_ADDR + + iret + + /* The task will resume here for the next system call, so it is necessary + * to jump back to the top. + */ + jmp prot_domains_syscall_dispatcher + +.global dev_not_avail_isr +dev_not_avail_isr: + clts + iret diff --git a/cpu/x86/mm/tss-prot-domains.c b/cpu/x86/mm/tss-prot-domains.c new file mode 100644 index 000000000..40041a6d1 --- /dev/null +++ b/cpu/x86/mm/tss-prot-domains.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include +#include +#include "gdt.h" +#include "helpers.h" +#include "idt.h" +#include "prot-domains.h" +#include "stacks.h" +#include "syscalls.h" +#include "tss.h" + +uint32_t prot_domains_main_esp; +syscalls_entrypoint_t ATTR_KERN_ADDR_SPACE *prot_domains_syscall; + +/*---------------------------------------------------------------------------*/ +void app_main(void); +void +prot_domains_reg(dom_client_data_t ATTR_KERN_ADDR_SPACE *dcd, + uintptr_t mmio, size_t mmio_sz, + uintptr_t meta, size_t meta_sz, + bool pio) +{ + segment_desc_t desc; + uint32_t eflags; + dom_id_t dom_id; + volatile struct dom_kern_data ATTR_KERN_ADDR_SPACE *dkd; + + KERN_READL(dom_id, dcd->dom_id); + + dkd = prot_domains_kern_data + dom_id; + + prot_domains_reg_multi_seg(dkd, mmio, mmio_sz, meta, meta_sz); + + /* Only the kernel protection domain requires port I/O access outside of the + * interrupt handlers. + */ + eflags = EFLAGS_IOPL(pio ? PRIV_LVL_USER : PRIV_LVL_INT); + if(dom_id == DOM_ID_app) { + eflags |= EFLAGS_IF; + } + + /* Keep this initialization in sync with the register definitions in + * tss-prot-domains-asm.S. + */ + KERN_WRITEL(dkd->tss.ebp, 0); + KERN_WRITEL(dkd->tss.ebx, 0); + KERN_WRITEL(dkd->tss.esi, BIT(dom_id)); + KERN_WRITEL(dkd->tss.eip, + (dom_id == DOM_ID_app) ? + (uint32_t)app_main : + (uint32_t)prot_domains_syscall_dispatcher); + KERN_WRITEL(dkd->tss.cs, GDT_SEL_CODE); + KERN_WRITEL(dkd->tss.ds, GDT_SEL_DATA); + KERN_WRITEL(dkd->tss.es, GDT_SEL_DATA); + KERN_WRITEL(dkd->tss.fs, LDT_SEL_KERN); + KERN_WRITEL(dkd->tss.gs, + (meta_sz == 0) ? GDT_SEL_NULL : LDT_SEL_META); + KERN_WRITEL(dkd->tss.ss, GDT_SEL_STK); + /* This stack pointer is only actually used in application protection domain. + * Other domains enter at system call dispatcher, which switches to main + * stack. + */ + KERN_WRITEL(dkd->tss.esp, + /* Two return addresses have been consumed: */ + STACKS_INIT_TOP + (2 * sizeof(uintptr_t))); + KERN_WRITEL(dkd->tss.eflags, eflags); + KERN_WRITEL(dkd->tss.ldt, GDT_SEL_LDT(dom_id)); + KERN_WRITEL(dkd->tss.esp2, STACKS_SIZE_MAIN + STACKS_SIZE_INT); + KERN_WRITEL(dkd->tss.ss2, GDT_SEL_STK_INT); + KERN_WRITEL(dkd->tss.esp0, + STACKS_SIZE_MAIN + STACKS_SIZE_INT + STACKS_SIZE_EXC); + KERN_WRITEL(dkd->tss.ss0, GDT_SEL_STK_EXC); + KERN_WRITEW(dkd->tss.t, 0); + KERN_WRITEW(dkd->tss.iomap_base, sizeof(tss_t)); + KERN_WRITEL(dkd->tss.cr3, 0); + + segment_desc_init(&desc, + KERN_DATA_OFF_TO_PHYS_ADDR((uint32_t)&(dkd->tss)), + sizeof(dkd->tss), + /* It should be possible for code at any privilege level to invoke the task's + * system call dispatcher. + */ + SEG_FLAG(DPL, PRIV_LVL_USER) | SEG_TYPE_TSS32_AVAIL); + + gdt_insert(GDT_IDX_TSS(dom_id), desc); + + KERN_WRITEW(dcd->tss_sel, GDT_SEL(GDT_IDX_TSS(dom_id), PRIV_LVL_USER)); +} +/*---------------------------------------------------------------------------*/ +void dev_not_avail_isr(void); +void +prot_domains_impl_init(void) +{ + __asm__ __volatile__ ("ltr %0" :: "r" ((uint16_t)GDT_SEL_TSS(DOM_ID_kern))); + __asm__ __volatile__ ("lldt %0" :: "r" ((uint16_t)GDT_SEL_LDT(DOM_ID_kern))); + + idt_set_intr_gate_desc(7, + (uint32_t)dev_not_avail_isr, + GDT_SEL_CODE_EXC, PRIV_LVL_EXC); +} +/*---------------------------------------------------------------------------*/ +int main(); +void +prot_domains_launch_kernel(void) +{ + multi_segment_launch_kernel(); + + /* Activate kernel protection domain, entering the kernel at main. */ + __asm__ __volatile__ ( + "pushl %[_ss_]\n\t" + "pushl %[_top_of_stk_]\n\t" + "pushl %[_eflags_]\n\t" + "pushl %[_cs_]\n\t" + "pushl %[_kern_start_]\n\t" + "iretl\n\t" + : + : [_ss_] "g" (GDT_SEL_STK), + [_eflags_] "g" (EFLAGS_IOPL(PRIV_LVL_USER)), + [_cs_] "g" (GDT_SEL_CODE), + [_kern_start_] "g" (main), + /* one address has already been consumed */ + [_top_of_stk_] "g" (STACKS_INIT_TOP + sizeof(uint32_t)) + ); +} +/*---------------------------------------------------------------------------*/ +void +prot_domains_launch_app() +{ + far_pointer_t app_ptr = { 0, GDT_SEL_TSS(DOM_ID_app) }; + __asm__ __volatile__ ("ljmp *%0" :: "m" (app_ptr)); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/mm/tss-prot-domains.h b/cpu/x86/mm/tss-prot-domains.h new file mode 100644 index 000000000..d61d97504 --- /dev/null +++ b/cpu/x86/mm/tss-prot-domains.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_MM_TSS_PROT_DOMAINS_H_ +#define CPU_X86_MM_TSS_PROT_DOMAINS_H_ + +#include +#include +#include +#include "ldt-layout.h" +#include "segmentation.h" +#include "tss.h" + +struct dom_kern_data { + /** Task State Segment */ + tss_t tss; + /** Local Descriptor Table with per-domain descriptors */ + segment_desc_t ldt[LDT_NUM_DESC]; +} __attribute__((packed)); + +/* relies on dom_kern_data: */ +#include "multi-segment.h" + +/* relies on ATTR_KERN_ADDR_SPACE: */ +#include "syscalls.h" + +/** + * Data associated with each protection domain that is owned by clients of that + * domain and used to identify the domain. + */ +struct dom_client_data { + dom_id_t dom_id; + /** The selector is only 16 bits, but it is padded to 32 bits. */ + uint32_t tss_sel; +}; + +extern uint32_t prot_domains_main_esp; + +#define SYSCALLS_STUB_MIDDLE(nm) \ + /* If already in the callee protection domain, skip the protection */ \ + /* domain switch and directly invoke the system call body */ \ + " je _syscall_" #nm "\n\t" \ + " movl $" EXP_STRINGIFY(_syscall_ent_##nm) ", prot_domains_syscall\n\t" \ + " mov %esp, prot_domains_main_esp\n\t" + +#define SYSCALLS_STUB(nm) \ + SYSCALLS_ALLOC_ENTRYPOINT(nm); \ + asm ( \ + ".text\n\t" \ + ".global " #nm "\n\t" \ + #nm ":\n\t" \ + " str %ax\n\t" \ + /* Compare current Task Register selector to selector for callee */ \ + /* protection domain, in tss_sel field of dom_client_data */ \ + " cmpw %ax, 8(%esp)\n\t" \ + SYSCALLS_STUB_MIDDLE(nm) \ + /* This will treat the dom_id field as the offset for the call, but */ \ + /* that is ignored when performing a far call to a task */ \ + " lcall *4(%esp)\n\t" \ + " ret\n\t") + +#define SYSCALLS_STUB_SINGLETON(nm, dcd) \ + SYSCALLS_ALLOC_ENTRYPOINT(nm); \ + asm ( \ + ".text\n\t" \ + ".global " #nm "\n\t" \ + #nm ":\n\t" \ + " str %ax\n\t" \ + /* Compare current Task Register selector to selector for callee */ \ + /* protection domain, in tss_sel field of dom_client_data */ \ + " cmpw %ax, %" SEG_KERN "s:(4 + " #dcd ")\n\t" \ + SYSCALLS_STUB_MIDDLE(nm) \ + /* This will treat the dom_id field as the offset for the call, but */ \ + /* that is ignored when performing a far call to a task */ \ + " lcall *%" SEG_KERN "s:" #dcd "\n\t" \ + " ret\n\t") + +#define PROT_DOMAINS_ENTER_ISR(exc) \ + MULTI_SEGMENT_ENTER_ISR(exc) \ + /* It is possible that the system call dispatcher is being interrupted, */ \ + /* and some interrupt handlers perform system calls. Thus, it is */ \ + /* necessary to save and restore the system call dispatcher parameters */ \ + /* (in callee-saved registers). */ \ + "mov prot_domains_main_esp, %%esi\n\t" \ + "mov prot_domains_syscall, %%edi\n\t" \ + PROT_DOMAINS_ENTER_ISR_COMMON(exc) +#define PROT_DOMAINS_LEAVE_ISR(exc) \ + PROT_DOMAINS_LEAVE_ISR_COMMON(exc) \ + "mov %%edi, prot_domains_syscall\n\t" \ + "mov %%esi, prot_domains_main_esp\n\t" \ + MULTI_SEGMENT_LEAVE_ISR(exc) + +/* Allocate two additional GDT entries for each protection domain. Note that + * the particular storage allocated by this statement may actually be used for + * some other protection domain, depending on how the linker happens to arrange + * all of the GDT storage. The GDT_IDX_TSS and GDT_IDX_LDT macros in + * gdt-layout.h determine which storage is used for each protection domain. + * Thus, this storage should not be referenced directly by its variable name. + */ +#define PROT_DOMAINS_ALLOC_IMPL(nm) \ + static segment_desc_t ATTR_BSS_GDT_MID _gdt_storage_##nm[2] + +#endif /* CPU_X86_MM_TSS_PROT_DOMAINS_H_ */ diff --git a/cpu/x86/mm/tss.c b/cpu/x86/mm/tss.c new file mode 100644 index 000000000..b6e0f3deb --- /dev/null +++ b/cpu/x86/mm/tss.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "gdt.h" +#include "gdt-layout.h" +#include "prot-domains.h" +#include "segmentation.h" +#include "stacks.h" +#include "tss.h" + +/* System-wide TSS */ +tss_t ATTR_BSS_KERN sys_tss; + +static segment_desc_t ATTR_BSS_GDT sys_tss_desc; + +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize system-wide TSS. + */ +void +tss_init(void) +{ + segment_desc_t seg_desc; + + /* Initialize TSS */ + KERN_WRITEW(sys_tss.iomap_base, sizeof(sys_tss)); + KERN_WRITEL(sys_tss.esp2, ((uint32_t)stacks_int) + STACKS_SIZE_INT); + KERN_WRITEL(sys_tss.ss2, GDT_SEL_STK_INT); + KERN_WRITEL(sys_tss.esp0, ((uint32_t)stacks_exc) + STACKS_SIZE_EXC); + KERN_WRITEL(sys_tss.ss0, GDT_SEL_STK_EXC); + + segment_desc_init(&seg_desc, + KERN_DATA_OFF_TO_PHYS_ADDR(&sys_tss), sizeof(sys_tss), + SEG_FLAG(DPL, PRIV_LVL_EXC) | + SEG_DESCTYPE_SYS | SEG_TYPE_TSS32_AVAIL); + gdt_insert(GDT_IDX_OF_DESC(&sys_tss_desc), seg_desc); + + __asm__ __volatile__ ( + "ltr %0" + : + : "r" ((uint16_t)GDT_SEL_OF_DESC(&sys_tss_desc, 0))); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/x86/mm/tss.h b/cpu/x86/mm/tss.h new file mode 100644 index 000000000..e8431d388 --- /dev/null +++ b/cpu/x86/mm/tss.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_MM_TSS_H_ +#define CPU_X86_MM_TSS_H_ + +#include + +/** + * Task State Segment. Used by the CPU to manage switching between + * different protection domains (tasks). The current task is referenced + * by the Task Register. When the CPU switches away from a task due to + * a far call, etc., it updates the associated in-memory TSS with the + * current state of the task. It then loads CPU state from the TSS for + * the new task. See Intel Combined Manual, Vol. 3, Chapter 7 for more + * details. + */ +typedef struct tss { + uint32_t prev_tsk; /**< The selector of the task that called this one, if applicable */ + uint32_t esp0; /**< Stack pointer for ring 0 code in this task */ + uint32_t ss0; /**< Stack segment selector for ring 0 code in this task */ + uint32_t esp1; /**< Stack pointer for ring 1 code in this task */ + uint32_t ss1; /**< Stack segment selector for ring 1 code in this task */ + uint32_t esp2; /**< Stack pointer for ring 2 code in this task */ + uint32_t ss2; /**< Stack segment selector for ring 2 code in this task */ + uint32_t cr3; /**< CR3 for this task when paging is enabled */ + uint32_t eip; /**< Stored instruction pointer value */ + uint32_t eflags; /**< Settings for EFLAGS register */ + /** General purpose register values */ + uint32_t eax, ecx, edx, ebx, esp, ebp, esi, edi; + /** Segment register selector values */ + uint32_t es, cs, ss, ds, fs, gs; + /** Selector for Local Descriptor Table */ + uint32_t ldt; + /** Debug-related flag */ + uint16_t t; + /** Offset from base of TSS to base of IO permission bitmap, if one is installed */ + uint16_t iomap_base; +} tss_t; + +void tss_init(void); + +#endif /* CPU_X86_TSS_H_ */ diff --git a/cpu/x86/mtarch.c b/cpu/x86/mtarch.c deleted file mode 100644 index 6dd72c61f..000000000 --- a/cpu/x86/mtarch.c +++ /dev/null @@ -1,187 +0,0 @@ - -#include -#include "sys/mt.h" - -#ifndef __WORDSIZE -#define __WORDSIZE 32 -#endif /* __WORDSIZE */ - -#ifndef ON_64BIT_ARCH -#if __WORDSIZE == 64 -#define ON_64BIT_ARCH 1 -#else /* ON_64BIT_ARCH */ -#define ON_64BIT_ARCH 0 -#endif /* __WORDSIZE == 64 */ -#endif /* ON_64BIT_ARCH */ - -struct frame { - unsigned long flags; -#if ON_64BIT_ARCH - unsigned long rbp; - unsigned long rdi; - unsigned long rsi; - unsigned long rdx; - unsigned long rcx; - unsigned long rbx; - unsigned long rax; -#else /* ON_64BIT_ARCH */ - unsigned long ebp; - unsigned long edi; - unsigned long esi; - unsigned long edx; - unsigned long ecx; - unsigned long ebx; - unsigned long eax; -#endif /* ON_64BIT_ARCH */ - unsigned long retaddr; - unsigned long retaddr2; - unsigned long data; -}; -/*--------------------------------------------------------------------------*/ -void -mtarch_init(void) -{ -} -/*--------------------------------------------------------------------------*/ -void -mtarch_start(struct mtarch_thread *t, - void (*function)(void *), void *data) -{ - struct frame *f = (struct frame *)&t->stack[MTARCH_STACKSIZE - sizeof(struct frame)/sizeof(unsigned long)]; - int i; - - for(i = 0; i < MTARCH_STACKSIZE; ++i) { - t->stack[i] = i; - } - - memset(f, 0, sizeof(struct frame)); - f->retaddr = (unsigned long)function; - f->data = (unsigned long)data; - t->sp = (unsigned long)&f->flags; -#if ON_64BIT_ARCH - f->rbp = (unsigned long)&f->rax; -#else /* ON_64BIT_ARCH */ - f->ebp = (unsigned long)&f->eax; -#endif /* ON_64BIT_ARCH */ -} -/*--------------------------------------------------------------------------*/ -static struct mtarch_thread *running_thread; -/*--------------------------------------------------------------------------*/ -static void -sw(void) -{ - /* Store registers */ -#if ON_64BIT_ARCH - __asm__ ( - "pushq %rax\n\t" - "pushq %rbx\n\t" - "pushq %rcx\n\t" - "pushq %rdx\n\t" - "pushq %rsi\n\t" - "pushq %rdi\n\t" - "pushq %rbp\n\t" - "pushq %rbp\n\t"); -#else /* ON_64BIT_ARCH */ - __asm__ ( - "pushl %eax\n\t" - "pushl %ebx\n\t" - "pushl %ecx\n\t" - "pushl %edx\n\t" - "pushl %esi\n\t" - "pushl %edi\n\t" - "pushl %ebp\n\t" - "pushl %ebp\n\t"); -#endif /* ON_64BIT_ARCH */ - - /* Switch stack pointer */ -#if ON_64BIT_ARCH - __asm__ ("movq %0, %%rax\n\t" : : "m" (running_thread)); - __asm__ ( - "movq (%rax), %rbx\n\t" - "movq %rsp, (%rax)\n\t" - "movq %rbx, %rsp\n\t" - ); -#else /* ON_64BIT_ARCH */ - __asm__ ("movl %0, %%eax\n\t" : : "m" (running_thread)); - __asm__ ( - "movl (%eax), %ebx\n\t" - "movl %esp, (%eax)\n\t" - "movl %ebx, %esp\n\t" - ); -#endif /* ON_64BIT_ARCH */ - - /* Restore previous registers */ -#if ON_64BIT_ARCH - __asm__ ( - "popq %rbp\n\t" - "popq %rbp\n\t" - "popq %rdi\n\t" - "popq %rsi\n\t" - "popq %rdx\n\t" - "popq %rcx\n\t" - "popq %rbx\n\t" - "popq %rax\n\t" - - "leave\n\t" - "ret\n\t" - ); -#else /* ON_64BIT_ARCH */ - __asm__ ( - "popl %ebp\n\t" - "popl %ebp\n\t" - "popl %edi\n\t" - "popl %esi\n\t" - "popl %edx\n\t" - "popl %ecx\n\t" - "popl %ebx\n\t" - "popl %eax\n\t" - - "leave\n\t" - "ret\n\t" - ); -#endif /* ON_64BIT_ARCH */ - -} - -/*--------------------------------------------------------------------------*/ -void -mtarch_exec(struct mtarch_thread *t) -{ - running_thread = t; - sw(); - running_thread = NULL; -} -/*--------------------------------------------------------------------------*/ -void -mtarch_remove(void) -{ -} -/*--------------------------------------------------------------------------*/ -void -mtarch_yield(void) -{ - sw(); -} -/*--------------------------------------------------------------------------*/ -void -mtarch_pstop(void) -{ -} -/*--------------------------------------------------------------------------*/ -void -mtarch_pstart(void) -{ -} -/*--------------------------------------------------------------------------*/ -int -mtarch_stack_usage(struct mt_thread *t) -{ - int i; - for(i = 0; i < MTARCH_STACKSIZE; ++i) { - if(t->thread.stack[i] != i) { - return MTARCH_STACKSIZE - i; - } - } - return -1; -} -/*--------------------------------------------------------------------------*/ diff --git a/cpu/x86/quarkX1000.ld b/cpu/x86/quarkX1000.ld new file mode 100644 index 000000000..d4ea66aa6 --- /dev/null +++ b/cpu/x86/quarkX1000.ld @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +OUTPUT_FORMAT("elf32-i386") + +ENTRY(start) + +SECTIONS { + /* + OS-Dev Wiki says it is common for kernels to start at 1M. Addresses before that + are used by BIOS/EFI, the bootloader and memory-mapped I/O. + + The UEFI GenFw program inserts a 0x220-byte offset between the image base and + the .text section. We add that same offset here to align the symbols in the + UEFI DLL with those in the final UEFI binary to make debugging easier. We also + apply 32-byte alignments to sections rather than more conventional 4K-byte + alignments to avoid symbols being shifted from the intermediate DLL to the + final UEFI image as would occur if the GenFw program shifted the .text section + from a higher, 4K-aligned offset to the 0x220-byte offset from the image base. + Such shifting may make debugging more difficult by preventing the DLL from + being a directly-useful source of symbol information. The debugging symbols + are not included in the final UEFI image. The GenFw program uses a minimum + section alignment of 32 bytes, so smaller alignment granularities may also + result in symbol perturbation. + */ + . = 1M + 0x220; + + .text ALIGN (32) : + { + KEEP(*(.multiboot)) + *(.boot_text) + *(.text*) + } + + .rodata ALIGN (32) : + { + *(.rodata*) + + _sdata_kern_startup_func = .; + KEEP(*(.kern_startup_func)) + _edata_kern_startup_func = .; + + _sdata_shared_isr = .; + KEEP(*(.shared_isr_data*)) + _edata_shared_isr = .; + } + + .data ALIGN (32) : + { + *(.data*) + } + + .bss ALIGN (32) : + { + *(COMMON) + *(.main_stack) + *(.bss*) + + *(.gdt_bss_start) + /* + The other GDT-related sections defined in gdt.h are only used when + protection domain support is enabled. Thus, they do not need to be + included here. + */ + _ebss_gdt_addr = .; + } + + _ebss_pre_dma_addr = ALIGN(32); +} diff --git a/cpu/x86/quarkX1000_dma.ld b/cpu/x86/quarkX1000_dma.ld new file mode 100644 index 000000000..4cecac839 --- /dev/null +++ b/cpu/x86/quarkX1000_dma.ld @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +SECTIONS { + + .bss.dma (NOLOAD) : AT(_ebss_pre_dma_addr) ALIGN (32) + { + /* IMRs are used to restrict DMA, and they require 1K physical address alignment. */ + . += ALIGN(_ebss_pre_dma_addr, 1K) - ALIGN(_ebss_pre_dma_addr, 32); + *(.dma_bss) + } + + _sbss_dma_addr = LOADADDR(.bss.dma) + ALIGN(_ebss_pre_dma_addr, 1K) - ALIGN(_ebss_pre_dma_addr, 32); + /* + Effectively pointing beyond the end of .bss.dma is acceptable, since + .bss.dma is the last section in memory. + */ + _ebss_dma_addr = ALIGN(LOADADDR(.bss.dma) + SIZEOF(.bss.dma), 1K); + +} diff --git a/cpu/x86/quarkX1000_multi_seg.ld b/cpu/x86/quarkX1000_multi_seg.ld new file mode 100644 index 000000000..c4e6293cf --- /dev/null +++ b/cpu/x86/quarkX1000_multi_seg.ld @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +OUTPUT_FORMAT("elf32-i386") + +ENTRY(start) + +/* + The TSS-based protection domain implementation does not explicitly reference + these symbols, so we list them here to prevent them from being garbage- + collected. +*/ +EXTERN(stacks_int) +EXTERN(stacks_exc) + +PHDRS { + boot_text PT_LOAD; + text PT_LOAD; + data PT_LOAD; +} + +SECTIONS { + /* + OS-Dev Wiki says it is common for kernels to start at 1M. Addresses before that + are used by BIOS/EFI, the bootloader and memory-mapped I/O. + + The UEFI GenFw program inserts a 0x220 byte offset between the image base and + the .text section. We add that same offset here to align the symbols in the + UEFI DLL with those in the final UEFI binary to make debugging easier. + */ + . = 1M + 0x220; + + /* + The GenFw program in the EDK2 UEFI toolchain outputs UEFI images with a + section alignment of at least 32 bytes. Thus, it is desirable to use at + least that alignment granularity to avoid symbols being shifted from the + intermediate DLL to the final UEFI image. Such shifting may make + debugging more difficult by preventing the DLL from being a useful + source of symbol information. The debugging symbols are not included in + the final UEFI image. + */ + .text.boot : ALIGN (32) + { + *(.multiboot) + /* + The initial bootstrap code expects to operate in a flat address + space with an identity mapping between linear and physical + addresses. + */ + *(.boot_text) + } :boot_text + + /* The post-boot code segments define tight bounds around the code + section, so this directive resets the virtual address to 0. */ + . = 0; + + /* The virtual address differs from the load address. */ + .text : AT(LOADADDR(.text.boot) + ALIGN(SIZEOF(.text.boot), 32)) ALIGN (32) + { + /* + These BYTE directives emit a UD2 instruction to cause execution to + halt if the control flow ever deviates to address 0. This also + prevents other code from being placed at address 0. Some code + considers a function pointer to address 0 to be a null function + pointer. + */ + BYTE(0x0F); + BYTE(0x0B); + *(.text*) + + /* + An alternative design to eliminate the need for ALIGN directives + within the AT directives in later sections could have padded + each section out to a 32-byte boundary. However, that would have + enabled unneeded software accesses to the padding past the end of actual + code/data in each section, since segments are also configured based on + the values of the SIZEOF expressions. As a general principle, accesses + should be as restricted as is feasible. + */ + } :text + + _stext_addr = LOADADDR(.text); + _etext_addr = LOADADDR(.text) + SIZEOF(.text); + + . = 0; + + .data : AT(ALIGN(_etext_addr, 32)) ALIGN (32) + { + *(.main_stack) + *(.int_stack) + *(.exc_stack) + *(.rodata*) + *(.data*) + + _sdata_kern_startup_func = .; + KEEP(*(.kern_startup_func)) + _edata_kern_startup_func = .; + + /* + These could alternatively be treated as read-only data to prevent tampering + from the user privilege level. + */ + _sdata_shared_isr = .; + KEEP(*(.shared_isr_data*)) + _edata_shared_isr = .; + } :data + + .bss : ALIGN (32) + { + *(COMMON) + *(.bss*) + } + + _sdata_addr = LOADADDR(.data); + _edata_addr = LOADADDR(.bss) + SIZEOF(.bss); + + . = 0; + + .bss.kern (NOLOAD) : AT(ALIGN(_edata_addr, 32)) ALIGN (32) + { + /* + This directive prevents any data from being allocated at address + zero, since the address 0 is commonly used to represent null + pointers. + */ + LONG(0); + *(.kern_bss) + + syscalls_entrypoints = .; + *(.syscall_bss) + syscalls_entrypoints_end = .; + } + + _ebss_syscall_addr = LOADADDR(.bss.kern) + SIZEOF(.bss.kern); + + .bss.kern_priv (NOLOAD) : ALIGN (32) + { + prot_domains_kern_data = .; + /* + The kernel and app protection domain control structures must always + be placed in the first two slots in this order, so that they have + well-known protection domain IDs: + */ + *(.kern_prot_dom_bss) + *(.app_prot_dom_bss) + *(.prot_dom_bss) + prot_domains_kern_data_end = .; + + *(.gdt_bss_start) + KEEP(*(.gdt_bss_mid)) + *(.gdt_bss) + _ebss_gdt_addr = .; + } + + _sbss_kern_addr = LOADADDR(.bss.kern); + _ebss_kern_addr = LOADADDR(.bss.kern_priv) + SIZEOF(.bss.kern_priv); + + . = _ebss_kern_addr; + + .bss.meta (NOLOAD) : AT(ALIGN(_ebss_kern_addr, 32)) ALIGN (32) + { + *(.meta_bss) + } + + /* .bss.meta may be empty, so this uses .bss.kern_priv as a base instead: */ + _ebss_pre_dma_addr = ALIGN(ALIGN(_ebss_kern_addr, 32) + SIZEOF(.bss.meta), 32); +} diff --git a/cpu/x86/quarkX1000_paging.ld b/cpu/x86/quarkX1000_paging.ld new file mode 100644 index 000000000..87c89ed8b --- /dev/null +++ b/cpu/x86/quarkX1000_paging.ld @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +OUTPUT_FORMAT("elf32-i386") + +ENTRY(start) + +SECTIONS { + /* + OS-Dev Wiki says it is common for kernels to start at 1M. Addresses before that + are used by BIOS/EFI, the bootloader and memory-mapped I/O. + + The UEFI GenFw program inserts a 0x220-byte offset between the image base and + the .text section. We add that same offset here to align the symbols in the + UEFI DLL with those in the final UEFI binary to make debugging easier. + */ + . = 1M + 0x220; + + .text.boot : ALIGN (32) + { + *(.multiboot) + *(.boot_text) + + /* + Fill out the section to the next 4K boundary so that the UEFI GenFw + program does not shift the following .text section forward into the + gap and perturb the symbols. This only works if the size of this + section is less than 4K - 0x220 bytes. + */ + . = 4K - 0x220; + } + + /* + It is actually desired that each of the following sections be page- + aligned. However, the UEFI GenFw program ratchets up its alignment + granularity to the maximum granularity discovered in its input file. + Using page-alignment perturbs the symbols, hindering debugging. Thus, + this file simply pads each section out to the desired page alignment and + declares a section alignment granularity of 32 bytes. + */ + + .text : ALIGN (32) + { + *(.text*) + + . = ALIGN(4K); + } + + _stext_addr = ADDR(.text); + _etext_addr = ADDR(.text) + SIZEOF(.text); + + .data.stack : ALIGN (32) + { + /* + Introduce a guard band page before the stacks to facilitate stack + overflow detection. This approach wastes a page of memory for each + guard band, but has the advantage of enabling an identity mapping + for all linear to physical addresses except those in the MMIO + regions. The guard bands are marked not-present in the page tables + to facilitate stack overflow detection. + + This padding must be placed inside of the section, or else it will + get dropped when the UEFI GenFw program generates the UEFI binary. + */ + . += 4K; + + /* + Place the main stack first so that an overflow is detected and does + not overwrite the interrupt or supervisor stacks. Usage of the + interrupt and stack is predictable, since it is only used by short + trampoline code sequences that quickly pivot to the main stack. + */ + *(.main_stack) + *(.int_stack) + *(.exc_stack) + + /* + The combined sizes of the stacks is an even multiple of 4K, so there + is no need to align the location counter here. + */ + + /* + Introduce a guard band page after the stacks to detect stack underflow. + Note that an underflow that only affects the interrupt and supervisor + stacks will not generate a page fault. Detecting such conditions by + placing the interrupt and supervisor stacks on separate pages would + substantially increase memory usage. + */ + . += 4K; + } + + .data : ALIGN (32) + { + /* + The UEFI GenFw program treats all sections that are alloc and read- + only as code sections. By that criteria, .rodata would be a code + section, but making such data executable is undesirable. Thus, this + script lumps in .rodata with other data. It may be desirable in the + future to actually write-protect this data. + */ + *(.rodata*) + *(.data*) + + _sdata_kern_startup_func = .; + KEEP(*(.kern_startup_func)) + _edata_kern_startup_func = .; + + /* + These could alternatively be treated as read-only data to prevent tampering + from the user privilege level. + */ + _sdata_shared_isr = .; + KEEP(*(.shared_isr_data*)) + _edata_shared_isr = .; + + . = ALIGN(4K); + } + + .bss : ALIGN (32) + { + *(COMMON) + *(.bss*) + + . = ALIGN(4K); + } + + _sdata_addr = ADDR(.data); + _edata_addr = ADDR(.bss) + SIZEOF(.bss); + + .bss.kern (NOLOAD) : ALIGN (32) + { + /* + Page-aligned data is output first. + It is infeasible to apply a page-alignment attribute to them in the + source code, because that increases the alignment of this section to + be page-aligned, which causes problems when generating a UEFI binary + as described above. + */ + *(.page_aligned_kern_bss) + *(.kern_bss) + + syscalls_entrypoints = .; + *(.syscall_bss) + syscalls_entrypoints_end = .; + + . = ALIGN(4K); + } + + _ebss_syscall_addr = ADDR(.bss.kern) + SIZEOF(.bss.kern); + + .bss.kern_priv (NOLOAD) : ALIGN (32) + { + prot_domains_kern_data = .; + /* + The kernel and app protection domain control structures must always + be placed in the first two slots in this order, so that they have + well-known protection domain IDs: + */ + *(.kern_prot_dom_bss) + *(.app_prot_dom_bss) + *(.prot_dom_bss) + prot_domains_kern_data_end = .; + + *(.gdt_bss_start) + *(.gdt_bss_mid) + *(.gdt_bss) + _ebss_gdt_addr = .; + + . = ALIGN(4K); + } + + _sbss_kern_addr = ADDR(.bss.kern); + _ebss_kern_addr = ADDR(.bss.kern_priv) + SIZEOF(.bss.kern_priv); + + .bss.meta (NOLOAD) : ALIGN (32) + { + *(.meta_bss) + + . = ALIGN(4K); + } + + _ebss_pre_dma_addr = ALIGN(32); +} diff --git a/cpu/x86/startup.h b/cpu/x86/startup.h new file mode 100644 index 000000000..56ad3b482 --- /dev/null +++ b/cpu/x86/startup.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_STARTUP_H_ +#define CPU_X86_STARTUP_H_ + +/** + * \brief Declare a function that will be automatically invoked from the kernel + * protection domain during boot, after all of the default device + * initialization has been completed. + */ +#define KERN_STARTUP_FUNC(f) \ +static void f(void); \ +static uintptr_t \ + __attribute__((used, section(".kern_startup_func"))) \ + __kern_startup_f = (uintptr_t)f; \ +static void f(void) + +#endif /* CPU_X86_STARTUP_H_ */ diff --git a/cpu/x86/uefi/bootstrap_uefi.c b/cpu/x86/uefi/bootstrap_uefi.c new file mode 100644 index 000000000..5ef778cca --- /dev/null +++ b/cpu/x86/uefi/bootstrap_uefi.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include +#include + +#define MAX_MEM_DESC 128 + +void start(void); + +/* The section attribute below is copied from ATTR_BOOT_CODE in prot-domains.h. + * prot-domains.h includes stdlib.h which defines NULL. The UEFI headers also + * define NULL, which induces a warning when the compiler detects the conflict. + * To avoid that, we avoid including prot-domains.h from this file. + */ +EFI_STATUS EFIAPI __attribute__((section(".boot_text"))) +uefi_start(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) +{ + EFI_MEMORY_DESCRIPTOR mem_map[MAX_MEM_DESC]; + UINTN mem_map_len = sizeof(mem_map); + UINTN mem_map_key; + UINTN mem_map_desc_sz; + UINT32 mem_map_rev; + + EFI_STATUS res; + + res = SystemTable->BootServices->GetMemoryMap(&mem_map_len, + mem_map, + &mem_map_key, + &mem_map_desc_sz, + &mem_map_rev); + if(res != EFI_SUCCESS) { + return EFI_ABORTED; + } + + res = SystemTable->BootServices->ExitBootServices(ImageHandle, mem_map_key); + if(res != EFI_SUCCESS) { + return EFI_ABORTED; + } + + start(); + + /* Should not be reachable: */ + return EFI_SUCCESS; +} diff --git a/cpu/x86/uefi/build_uefi.sh b/cpu/x86/uefi/build_uefi.sh new file mode 100755 index 000000000..c49718f93 --- /dev/null +++ b/cpu/x86/uefi/build_uefi.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) + +# This script will always run on its own basepath, no matter where you call it from. +pushd ${SCRIPT_DIR} + +if [ "$(uname -m)" = "x86_64" ]; then + export ARCH=X64 +fi + +# Download the UEFI tool and library sources: +if [ -e edk2 ]; then + make -C edk2/BaseTools/Source/C/Common clean + make -C edk2/BaseTools/Source/C/GenFw clean +else + git clone --depth=1 https://github.com/tianocore/edk2 || exit +fi +# Build common sources required by the GenFw tool: +make -C edk2/BaseTools/Source/C/Common || exit +# Build the GenFw tool that is used to generate UEFI binaries: +make -C edk2/BaseTools/Source/C/GenFw || exit +# Create a makefile that indicates to the Contiki build system that UEFI support +# should be built: +echo "EN_UEFI = 1" > Makefile.uefi + +popd diff --git a/dev/arduino/arduino-compat.h b/dev/arduino/arduino-compat.h index d3f9b58ac..d9bc62cd6 100644 --- a/dev/arduino/arduino-compat.h +++ b/dev/arduino/arduino-compat.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Ralf Schlatterbeck Open Source Consulting + * Copyright (c) 2014-15, Ralf Schlatterbeck Open Source Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -177,7 +177,6 @@ static inline uint32_t micros (void) * behaviour of arduino implementation. */ #define millis() (((uint32_t)clock_time())*1000L/CLOCK_SECOND) -#define micros() (clock_seconds()*1000L+ #define delay(ms) clock_delay_msec(ms) #define delayMicroseconds(us) clock_delay_usec(us) diff --git a/dev/cc1200/cc1200-802154g-863-870-fsk-50kbps.c b/dev/cc1200/cc1200-802154g-863-870-fsk-50kbps.c new file mode 100644 index 000000000..95fae730c --- /dev/null +++ b/dev/cc1200/cc1200-802154g-863-870-fsk-50kbps.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2015, Weptech elektronik GmbH Germany + * http://www.weptech.de + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + */ + +#include "cc1200-rf-cfg.h" +#include "cc1200-const.h" + +/* + * This is a setup for the following configuration: + * + * 802.15.4g + * ========= + * Table 68f: Frequency band identifier 4 (863-870 MHz) + * Table 68g: Modulation scheme identifier 0 (Filtered FSK) + * Table 68h: Mode #1 (50kbps) + */ + +/* Base frequency in kHz */ +#define RF_CFG_CHAN_CENTER_F0 863125 +/* Channel spacing in kHz */ +#define RF_CFG_CHAN_SPACING 200 +/* The minimum channel */ +#define RF_CFG_MIN_CHANNEL 0 +/* The maximum channel */ +#define RF_CFG_MAX_CHANNEL 33 +/* The maximum output power in dBm */ +#define RF_CFG_MAX_TXPOWER CC1200_CONST_TX_POWER_MAX +/* The carrier sense level used for CCA in dBm */ +#define RF_CFG_CCA_THRESHOLD (-91) +/*---------------------------------------------------------------------------*/ +static const char rf_cfg_descriptor[] = "802.15.4g 863-870MHz MR-FSK mode #1"; +/*---------------------------------------------------------------------------*/ +/* + * Register settings exported from SmartRF Studio using the standard template + * "trxEB RF Settings Performance Line". + */ + +// Modulation format = 2-GFSK +// Whitening = false +// Packet length = 255 +// Packet length mode = Variable +// Packet bit length = 0 +// Symbol rate = 50 +// Deviation = 24.948120 +// Carrier frequency = 867.999878 +// Device address = 0 +// Manchester enable = false +// Address config = No address check +// Bit rate = 50 +// RX filter BW = 104.166667 + +static const registerSetting_t preferredSettings[]= +{ + {CC1200_IOCFG2, 0x06}, + {CC1200_SYNC3, 0x6E}, + {CC1200_SYNC2, 0x4E}, + {CC1200_SYNC1, 0x90}, + {CC1200_SYNC0, 0x4E}, + {CC1200_SYNC_CFG1, 0xE5}, + {CC1200_SYNC_CFG0, 0x23}, + {CC1200_DEVIATION_M, 0x47}, + {CC1200_MODCFG_DEV_E, 0x0B}, + {CC1200_DCFILT_CFG, 0x56}, + + /* + * 18.1.1.1 Preamble field + * The Preamble field shall contain phyFSKPreambleLength (as defined in 9.3) + * multiples of the 8-bit sequence “01010101” for filtered 2FSK. + * The Preamble field shall contain phyFSKPreambleLength multiples of the + * 16-bit sequence “0111 0111 0111 0111” for filtered 4FSK. + * + * We need to define this in order to be able to compute e.g. timeouts for the + * MAC layer. According to 9.3, phyFSKPreambleLength can be configured between + * 4 and 1000. We set it to 4. Attention: Once we use a long wake-up preamble, + * the timing parameters have to change accordingly. Will we use a shorter + * preamble for an ACK in this case??? + */ + {CC1200_PREAMBLE_CFG1, 0x19}, + + {CC1200_PREAMBLE_CFG0, 0xBA}, + {CC1200_IQIC, 0xC8}, + {CC1200_CHAN_BW, 0x84}, + {CC1200_MDMCFG1, 0x42}, + {CC1200_MDMCFG0, 0x05}, + {CC1200_SYMBOL_RATE2, 0x94}, + {CC1200_SYMBOL_RATE1, 0x7A}, + {CC1200_SYMBOL_RATE0, 0xE1}, + {CC1200_AGC_REF, 0x27}, + {CC1200_AGC_CS_THR, 0xF1}, + {CC1200_AGC_CFG1, 0x11}, + {CC1200_AGC_CFG0, 0x90}, + {CC1200_FIFO_CFG, 0x00}, + {CC1200_FS_CFG, 0x12}, + {CC1200_PKT_CFG2, 0x24}, + {CC1200_PKT_CFG0, 0x20}, + {CC1200_PKT_LEN, 0xFF}, + {CC1200_IF_MIX_CFG, 0x18}, + {CC1200_TOC_CFG, 0x03}, + {CC1200_MDMCFG2, 0x02}, + {CC1200_FREQ2, 0x56}, + {CC1200_FREQ1, 0xCC}, + {CC1200_FREQ0, 0xCC}, + {CC1200_IF_ADC1, 0xEE}, + {CC1200_IF_ADC0, 0x10}, + {CC1200_FS_DIG1, 0x04}, + {CC1200_FS_DIG0, 0x50}, + {CC1200_FS_CAL1, 0x40}, + {CC1200_FS_CAL0, 0x0E}, + {CC1200_FS_DIVTWO, 0x03}, + {CC1200_FS_DSM0, 0x33}, + {CC1200_FS_DVC1, 0xF7}, + {CC1200_FS_DVC0, 0x0F}, + {CC1200_FS_PFD, 0x00}, + {CC1200_FS_PRE, 0x6E}, + {CC1200_FS_REG_DIV_CML, 0x1C}, + {CC1200_FS_SPARE, 0xAC}, + {CC1200_FS_VCO0, 0xB5}, + {CC1200_IFAMP, 0x05}, + {CC1200_XOSC5, 0x0E}, + {CC1200_XOSC1, 0x03}, +}; +/*---------------------------------------------------------------------------*/ +/* Global linkage: symbol name must be different in each exported file! */ +const cc1200_rf_cfg_t cc1200_802154g_863_870_fsk_50kbps = { + .cfg_descriptor = rf_cfg_descriptor, + .register_settings = preferredSettings, + .size_of_register_settings = sizeof(preferredSettings), + .tx_pkt_lifetime = (RTIMER_SECOND / 20), + .chan_center_freq0 = RF_CFG_CHAN_CENTER_F0, + .chan_spacing = RF_CFG_CHAN_SPACING, + .min_channel = RF_CFG_MIN_CHANNEL, + .max_channel = RF_CFG_MAX_CHANNEL, + .max_txpower = RF_CFG_MAX_TXPOWER, + .cca_threshold = RF_CFG_CCA_THRESHOLD, +}; +/*---------------------------------------------------------------------------*/ diff --git a/dev/cc1200/cc1200-arch.h b/dev/cc1200/cc1200-arch.h new file mode 100644 index 000000000..c48a8798d --- /dev/null +++ b/dev/cc1200/cc1200-arch.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2015, Weptech elektronik GmbH Germany + * http://www.weptech.de + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + */ + +#ifndef CC1200_ARCH_H +#define CC1200_ARCH_H + +#include +/*---------------------------------------------------------------------------*/ +/* + * Initialize SPI module & Pins. + * + * The function has to accomplish the following tasks: + * - Enable SPI and configure SPI (CPOL = 0, CPHA = 0) + * - Configure MISO, MOSI, SCLK accordingly + * - Configure GPIOx (input) + * - Configure RESET_N (output high) + * - Configure CSn (output high) + */ +void +cc1200_arch_init(void); +/*---------------------------------------------------------------------------*/ +/* Select CC1200 (pull down CSn pin). */ +void +cc1200_arch_spi_select(void); +/*---------------------------------------------------------------------------*/ +/* De-select CC1200 (release CSn pin). */ +void +cc1200_arch_spi_deselect(void); +/*---------------------------------------------------------------------------*/ +/* + * Configure port IRQ for GPIO0. + * If rising == 1: configure IRQ for rising edge, else falling edge + * Interrupt has to call cc1200_rx_interrupt()! + */ +void +cc1200_arch_gpio0_setup_irq(int rising); +/*---------------------------------------------------------------------------*/ +/* + * Configure port IRQ for GPIO2. + * + * GPIO2 might not be needed at all depending on the driver's + * configuration (see cc1200-conf.h) + * + * If rising == 1: configure IRQ for rising edge, else falling edge + * Interrupt has to call cc1200_rx_interrupt()! + */ +void +cc1200_arch_gpio2_setup_irq(int rising); +/*---------------------------------------------------------------------------*/ +/* Reset interrupt flag and enable GPIO0 port IRQ. */ +void +cc1200_arch_gpio0_enable_irq(void); +/*---------------------------------------------------------------------------*/ +/* Disable GPIO0 port IRQ. */ +void +cc1200_arch_gpio0_disable_irq(void); +/*---------------------------------------------------------------------------*/ +/* + * Reset interrupt flag and enable GPIO2 port IRQ + * + * GPIO2 might not be needed at all depending on the driver's + * configuration (see cc1200-conf.h) + */ +void +cc1200_arch_gpio2_enable_irq(void); +/*---------------------------------------------------------------------------*/ +/* + * Disable GPIO2 port IRQ. + * + * GPIO2 might not be needed at all depending on the driver's + * configuration (see cc1200-conf.h) + */ +void +cc1200_arch_gpio2_disable_irq(void); +/*---------------------------------------------------------------------------*/ +/* + * Read back the status of the GPIO0 pin. + * Returns 0 if the pin is low, otherwise 1 + */ +int +cc1200_arch_gpio0_read_pin(void); +/*---------------------------------------------------------------------------*/ +/* + * Read back the status of the GPIO2 pin. + * + * GPIO2 might not be needed at all depending on the driver's + * configuration (see cc1200-conf.h) + * + * Returns 0 if the pin is low, otherwise 1 + */ +int +cc1200_arch_gpio2_read_pin(void); +/*---------------------------------------------------------------------------*/ +/* + * Read back the status of the GPIO3 pin. + * + * Currently only used for rf test modes. + * + * Returns 0 if the pin is low, otherwise 1 + */ +int +cc1200_arch_gpio3_read_pin(void); +/*---------------------------------------------------------------------------*/ +/* Write a single byte via SPI, return response. */ +int +cc1200_arch_spi_rw_byte(uint8_t c); +/*---------------------------------------------------------------------------*/ +/* + * Write a sequence of bytes while reading back the response. + * Either read_buf or write_buf can be NULL. + */ +int +cc1200_arch_spi_rw(uint8_t *read_buf, + const uint8_t *write_buf, + uint16_t len); +/*---------------------------------------------------------------------------*/ +/* + * The CC1200 interrupt handler exported from the cc1200 driver. + * + * To be called by the hardware interrupt handler(s), + * which are defined as part of the cc1200-arch interface. + */ +int +cc1200_rx_interrupt(void); + +#endif /* CC1200_ARCH_H */ diff --git a/dev/cc1200/cc1200-conf.h b/dev/cc1200/cc1200-conf.h new file mode 100644 index 000000000..1e50cc828 --- /dev/null +++ b/dev/cc1200/cc1200-conf.h @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2015, Weptech elektronik GmbH Germany + * http://www.weptech.de + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + */ + +#ifndef CC1200_H_ +#define CC1200_H_ + +#include "contiki.h" + +/*---------------------------------------------------------------------------*/ +/* + * Can we use GPIO2 (in addition to GPIO0)? + * + * If this is the case, we can easily handle payloads > 125 bytes + * (and even > 127 bytes). If GPIO2 is available, we use it as an indicator + * pin for RX / TX FIFO threshold. + */ +#ifdef CC1200_CONF_USE_GPIO2 +#define CC1200_USE_GPIO2 CC1200_CONF_USE_GPIO2 +#else +#define CC1200_USE_GPIO2 1 +#endif +/*---------------------------------------------------------------------------*/ +/* + * The maximum payload length the driver can handle. + * + * - If CC1200_MAX_PAYLOAD_LEN <= 125 and CC1200_USE_GPIO2 == 0, we read + * out the RX FIFO at the end of the packet. RXOFF_MODE is set to RX in this + * case. + * - If 125 < CC1200_MAX_PAYLOAD_LEN <= 127 and CC1200_USE_GPIO2 == 0, we + * also read out the RX FIFO at the end of the packet, but read out + * RSSI + LQI "by hand". In this case, we also have to restart RX + * manually because RSSI + LQI are overwritten as soon as RX re-starts. + * This will lead to an increased RX/RX turnaround time. + * - If CC1200_USE_GPIO2 is set, we can use an arbitrary payload length + * (only limited by the payload length defined in the phy header). + * + * See below for 802.15.4g support. + */ +#ifdef CC1200_CONF_MAX_PAYLOAD_LEN +#define CC1200_MAX_PAYLOAD_LEN CC1200_CONF_MAX_PAYLOAD_LEN +#else +#define CC1200_MAX_PAYLOAD_LEN 127 +#endif +/*---------------------------------------------------------------------------*/ +/* + * The RX watchdog is used to check whether the radio is in RX mode at regular + * intervals (once per second). Can be used to improve reliability especially + * if NullRDC is used. Turned of by default. + */ +#ifdef CC1200_CONF_USE_RX_WATCHDOG +#define CC1200_USE_RX_WATCHDOG CC1200_CONF_USE_RX_WATCHDOG +#else +#define CC1200_USE_RX_WATCHDOG 0 +#endif +/*---------------------------------------------------------------------------*/ +/* + * Use 802.15.4g frame format? Supports frame lenghts up to 2047 bytes! + */ +#ifdef CC1200_CONF_802154G +#define CC1200_802154G CC1200_CONF_802154G +#else +#define CC1200_802154G 0 +#endif +/*---------------------------------------------------------------------------*/ +/* + * Do we use withening in 802.15.4g mode? Set to 1 if enabled, 0 otherwise. + */ +#ifdef CC1200_CONF_802154G_WHITENING +#define CC1200_802154G_WHITENING CC1200_CONF_802154G_WHITENING +#else +#define CC1200_802154G_WHITENING 0 +#endif +/*---------------------------------------------------------------------------*/ +/* + * Do we use CRC16 in 802.15.4g mode? Set to 1 if enabled, 0 otherwise. + * + * It set to 0, we use FCS type 0: CRC32. + */ +#ifdef CC1200_CONF_802154G_CRC16 +#define CC1200_802154G_CRC16 CC1200_CONF_802154G_CRC16 +#else +/* Use FCS type 0: CRC32 */ +#define CC1200_802154G_CRC16 0 +#endif +/*---------------------------------------------------------------------------*/ +/* The RF configuration to be used. */ +#ifdef CC1200_CONF_RF_CFG +#define CC1200_RF_CFG CC1200_CONF_RF_CFG +#else +#define CC1200_RF_CFG cc1200_802154g_863_870_fsk_50kbps +#endif +/*---------------------------------------------------------------------------*/ +/* + * The RSSI offset in dBm (int8_t) + * + * Might be hardware dependent, so we make it a configuration parameter. + * This parameter is written to AGC_GAIN_ADJUST.GAIN_ADJUSTMENT + */ +#ifdef CC1200_CONF_RSSI_OFFSET +#define CC1200_RSSI_OFFSET CC1200_CONF_RSSI_OFFSET +#else +#define CC1200_RSSI_OFFSET (-81) +#endif +/*---------------------------------------------------------------------------*/ +/* + * The frequency offset + * + * Might be hardware dependent (e.g. depending on crystal load capacitances), + * so we make it a configuration parameter. Written to FREQOFF1 / FREQOFF2. + * Signed 16 bit number, see cc1200 user's guide. + * + * TODO: Make it a parameter for set_value() / get_value() + */ +#ifdef CC1200_CONF_FREQ_OFFSET +#define CC1200_FREQ_OFFSET CC1200_CONF_FREQ_OFFSET +#else +#define CC1200_FREQ_OFFSET (0) +#endif +/*---------------------------------------------------------------------------*/ +/* + * The default channel to use. + * + * Permitted values depending on the data rate + band used are defined + * in the appropriate rf configuration file. Make sure the default value + * is within these limits! + */ +#ifdef CC1200_CONF_DEFAULT_CHANNEL +#define CC1200_DEFAULT_CHANNEL CC1200_CONF_DEFAULT_CHANNEL +#else +/* 868.325 MHz */ +#define CC1200_DEFAULT_CHANNEL 26 +#endif +/*---------------------------------------------------------------------------*/ +/* + * Wether to use auto calibration or not. + * + * If set to 0, calibration is performed manually when turning the radio + * on (on()), when transmitting (transmit()) or when changing the channel. + * Enabling auto calibration will increase turn around times + + * energy consumption. If enabled, we calibrate every time we go from + * IDLE to RX or TX. + * When RDC or channel hopping is used, there is no need to turn calibration + * on because either on() is called frequently or the channel is updated. + */ +#ifdef CC1200_CONF_AUTOCAL +#define CC1200_AUTOCAL CC1200_CONF_AUTOCAL +#else +#define CC1200_AUTOCAL 0 +#endif +/*---------------------------------------------------------------------------*/ +/* + * If CC1200_AUTOCAL is not set, we use this parameter to defer + * calibration until a certain amount of time has expired. + * + * This is what happens in detail: + * + * - We (manually) calibrate once after initialization + * - We (manually) calibrate every time we change the channel + * - We (manually) calibrate when the radio is turned on() only if + * the timeout has expired + * - We (manually) calibrate when transmitting only of the timeout has expired + * + * Set this parameter to 0 when this feature is not used. In this case we + * (manually) calibrate in all situations mentioned above. + */ +#ifdef CC1200_CONF_CAL_TIMEOUT_SECONDS +#define CC1200_CAL_TIMEOUT_SECONDS CC1200_CONF_CAL_TIMEOUT_SECONDS +#else +/* Calibrate at the latest every 15 minutes */ +#define CC1200_CAL_TIMEOUT_SECONDS 900 +#endif +/*---------------------------------------------------------------------------*/ +/* + * If defined, use these LEDS to indicate TX activity + * + * The LEDs are turned on once the radio enters TX mode + * (together with ENERGEST_ON(ENERGEST_TYPE_TRANSMIT), + * and turned of as soon as TX has completed. + */ +#ifdef CC1200_CONF_TX_LEDS +#define CC1200_TX_LEDS CC1200_CONF_TX_LEDS +#endif +/*---------------------------------------------------------------------------*/ +/* + * If defined, use these LEDS to indicate RX activity + * + * The LEDs are turned on as soon as the first byte is read out from + * the RX FIFO + */ +#ifdef CC1200_CONF_RX_LED +#define CC1200_RX_LEDS CC1200_CONF_RX_LEDS +#endif +/*---------------------------------------------------------------------------*/ +/* + * If set, enable sniff mode: turn radio on (and keep it on), disable + * address filter and auto ack + */ +#ifdef CC1200_CONF_SNIFFER +#define CC1200_SNIFFER CC1200_CONF_SNIFFER +#else +#define CC1200_SNIFFER 0 +#endif +/*---------------------------------------------------------------------------*/ + +#endif /* CC1200_H_ */ diff --git a/dev/cc1200/cc1200-const.h b/dev/cc1200/cc1200-const.h new file mode 100644 index 000000000..077ade559 --- /dev/null +++ b/dev/cc1200/cc1200-const.h @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2015, Weptech elektronik GmbH Germany + * http://www.weptech.de + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + */ + +#ifndef CC1200_CONST_H_ +#define CC1200_CONST_H_ + +/*---------------------------------------------------------------------------*/ +/* Register addresses exported from SmartRF Studio */ +#define CC1200_IOCFG3 0x0000 /* GPIO3 IO Pin Configuration */ +#define CC1200_IOCFG2 0x0001 /* GPIO2 IO Pin Configuration */ +#define CC1200_IOCFG1 0x0002 /* GPIO1 IO Pin Configuration */ +#define CC1200_IOCFG0 0x0003 /* GPIO0 IO Pin Configuration */ +#define CC1200_SYNC3 0x0004 /* Sync Word Configuration [31:24] */ +#define CC1200_SYNC2 0x0005 /* Sync Word Configuration [23:16] */ +#define CC1200_SYNC1 0x0006 /* Sync Word Configuration [15:8] */ +#define CC1200_SYNC0 0x0007 /* Sync Word Configuration [7:0] */ +#define CC1200_SYNC_CFG1 0x0008 /* Sync Word Detection Configuration Reg. 1 */ +#define CC1200_SYNC_CFG0 0x0009 /* Sync Word Detection Configuration Reg. 0 */ +#define CC1200_DEVIATION_M 0x000A /* Frequency Deviation Configuration */ +#define CC1200_MODCFG_DEV_E 0x000B /* Modulation Format and Frequency Deviation Configur.. */ +#define CC1200_DCFILT_CFG 0x000C /* Digital DC Removal Configuration */ +#define CC1200_PREAMBLE_CFG1 0x000D /* Preamble Length Configuration Reg. 1 */ +#define CC1200_PREAMBLE_CFG0 0x000E /* Preamble Detection Configuration Reg. 0 */ +#define CC1200_IQIC 0x000F /* Digital Image Channel Compensation Configuration */ +#define CC1200_CHAN_BW 0x0010 /* Channel Filter Configuration */ +#define CC1200_MDMCFG1 0x0011 /* General Modem Parameter Configuration Reg. 1 */ +#define CC1200_MDMCFG0 0x0012 /* General Modem Parameter Configuration Reg. 0 */ +#define CC1200_SYMBOL_RATE2 0x0013 /* Symbol Rate Configuration Exponent and Mantissa [1.. */ +#define CC1200_SYMBOL_RATE1 0x0014 /* Symbol Rate Configuration Mantissa [15:8] */ +#define CC1200_SYMBOL_RATE0 0x0015 /* Symbol Rate Configuration Mantissa [7:0] */ +#define CC1200_AGC_REF 0x0016 /* AGC Reference Level Configuration */ +#define CC1200_AGC_CS_THR 0x0017 /* Carrier Sense Threshold Configuration */ +#define CC1200_AGC_GAIN_ADJUST 0x0018 /* RSSI Offset Configuration */ +#define CC1200_AGC_CFG3 0x0019 /* Automatic Gain Control Configuration Reg. 3 */ +#define CC1200_AGC_CFG2 0x001A /* Automatic Gain Control Configuration Reg. 2 */ +#define CC1200_AGC_CFG1 0x001B /* Automatic Gain Control Configuration Reg. 1 */ +#define CC1200_AGC_CFG0 0x001C /* Automatic Gain Control Configuration Reg. 0 */ +#define CC1200_FIFO_CFG 0x001D /* FIFO Configuration */ +#define CC1200_DEV_ADDR 0x001E /* Device Address Configuration */ +#define CC1200_SETTLING_CFG 0x001F /* Frequency Synthesizer Calibration and Settling Con.. */ +#define CC1200_FS_CFG 0x0020 /* Frequency Synthesizer Configuration */ +#define CC1200_WOR_CFG1 0x0021 /* eWOR Configuration Reg. 1 */ +#define CC1200_WOR_CFG0 0x0022 /* eWOR Configuration Reg. 0 */ +#define CC1200_WOR_EVENT0_MSB 0x0023 /* Event 0 Configuration MSB */ +#define CC1200_WOR_EVENT0_LSB 0x0024 /* Event 0 Configuration LSB */ +#define CC1200_RXDCM_TIME 0x0025 /* RX Duty Cycle Mode Configuration */ +#define CC1200_PKT_CFG2 0x0026 /* Packet Configuration Reg. 2 */ +#define CC1200_PKT_CFG1 0x0027 /* Packet Configuration Reg. 1 */ +#define CC1200_PKT_CFG0 0x0028 /* Packet Configuration Reg. 0 */ +#define CC1200_RFEND_CFG1 0x0029 /* RFEND Configuration Reg. 1 */ +#define CC1200_RFEND_CFG0 0x002A /* RFEND Configuration Reg. 0 */ +#define CC1200_PA_CFG1 0x002B /* Power Amplifier Configuration Reg. 1 */ +#define CC1200_PA_CFG0 0x002C /* Power Amplifier Configuration Reg. 0 */ +#define CC1200_ASK_CFG 0x002D /* ASK Configuration */ +#define CC1200_PKT_LEN 0x002E /* Packet Length Configuration */ +#define CC1200_IF_MIX_CFG 0x2F00 /* IF Mix Configuration */ +#define CC1200_FREQOFF_CFG 0x2F01 /* Frequency Offset Correction Configuration */ +#define CC1200_TOC_CFG 0x2F02 /* Timing Offset Correction Configuration */ +#define CC1200_MARC_SPARE 0x2F03 /* MARC Spare */ +#define CC1200_ECG_CFG 0x2F04 /* External Clock Frequency Configuration */ +#define CC1200_MDMCFG2 0x2F05 /* General Modem Parameter Configuration Reg. 2 */ +#define CC1200_EXT_CTRL 0x2F06 /* External Control Configuration */ +#define CC1200_RCCAL_FINE 0x2F07 /* RC Oscillator Calibration Fine */ +#define CC1200_RCCAL_COARSE 0x2F08 /* RC Oscillator Calibration Coarse */ +#define CC1200_RCCAL_OFFSET 0x2F09 /* RC Oscillator Calibration Clock Offset */ +#define CC1200_FREQOFF1 0x2F0A /* Frequency Offset MSB */ +#define CC1200_FREQOFF0 0x2F0B /* Frequency Offset LSB */ +#define CC1200_FREQ2 0x2F0C /* Frequency Configuration [23:16] */ +#define CC1200_FREQ1 0x2F0D /* Frequency Configuration [15:8] */ +#define CC1200_FREQ0 0x2F0E /* Frequency Configuration [7:0] */ +#define CC1200_IF_ADC2 0x2F0F /* Analog to Digital Converter Configuration Reg. 2 */ +#define CC1200_IF_ADC1 0x2F10 /* Analog to Digital Converter Configuration Reg. 1 */ +#define CC1200_IF_ADC0 0x2F11 /* Analog to Digital Converter Configuration Reg. 0 */ +#define CC1200_FS_DIG1 0x2F12 /* Frequency Synthesizer Digital Reg. 1 */ +#define CC1200_FS_DIG0 0x2F13 /* Frequency Synthesizer Digital Reg. 0 */ +#define CC1200_FS_CAL3 0x2F14 /* Frequency Synthesizer Calibration Reg. 3 */ +#define CC1200_FS_CAL2 0x2F15 /* Frequency Synthesizer Calibration Reg. 2 */ +#define CC1200_FS_CAL1 0x2F16 /* Frequency Synthesizer Calibration Reg. 1 */ +#define CC1200_FS_CAL0 0x2F17 /* Frequency Synthesizer Calibration Reg. 0 */ +#define CC1200_FS_CHP 0x2F18 /* Frequency Synthesizer Charge Pump Configuration */ +#define CC1200_FS_DIVTWO 0x2F19 /* Frequency Synthesizer Divide by 2 */ +#define CC1200_FS_DSM1 0x2F1A /* FS Digital Synthesizer Module Configuration Reg. 1 */ +#define CC1200_FS_DSM0 0x2F1B /* FS Digital Synthesizer Module Configuration Reg. 0 */ +#define CC1200_FS_DVC1 0x2F1C /* Frequency Synthesizer Divider Chain Configuration .. */ +#define CC1200_FS_DVC0 0x2F1D /* Frequency Synthesizer Divider Chain Configuration .. */ +#define CC1200_FS_LBI 0x2F1E /* Frequency Synthesizer Local Bias Configuration */ +#define CC1200_FS_PFD 0x2F1F /* Frequency Synthesizer Phase Frequency Detector Con.. */ +#define CC1200_FS_PRE 0x2F20 /* Frequency Synthesizer Prescaler Configuration */ +#define CC1200_FS_REG_DIV_CML 0x2F21 /* Frequency Synthesizer Divider Regulator Configurat.. */ +#define CC1200_FS_SPARE 0x2F22 /* Frequency Synthesizer Spare */ +#define CC1200_FS_VCO4 0x2F23 /* FS Voltage Controlled Oscillator Configuration Reg.. */ +#define CC1200_FS_VCO3 0x2F24 /* FS Voltage Controlled Oscillator Configuration Reg.. */ +#define CC1200_FS_VCO2 0x2F25 /* FS Voltage Controlled Oscillator Configuration Reg.. */ +#define CC1200_FS_VCO1 0x2F26 /* FS Voltage Controlled Oscillator Configuration Reg.. */ +#define CC1200_FS_VCO0 0x2F27 /* FS Voltage Controlled Oscillator Configuration Reg.. */ +#define CC1200_GBIAS6 0x2F28 /* Global Bias Configuration Reg. 6 */ +#define CC1200_GBIAS5 0x2F29 /* Global Bias Configuration Reg. 5 */ +#define CC1200_GBIAS4 0x2F2A /* Global Bias Configuration Reg. 4 */ +#define CC1200_GBIAS3 0x2F2B /* Global Bias Configuration Reg. 3 */ +#define CC1200_GBIAS2 0x2F2C /* Global Bias Configuration Reg. 2 */ +#define CC1200_GBIAS1 0x2F2D /* Global Bias Configuration Reg. 1 */ +#define CC1200_GBIAS0 0x2F2E /* Global Bias Configuration Reg. 0 */ +#define CC1200_IFAMP 0x2F2F /* Intermediate Frequency Amplifier Configuration */ +#define CC1200_LNA 0x2F30 /* Low Noise Amplifier Configuration */ +#define CC1200_RXMIX 0x2F31 /* RX Mixer Configuration */ +#define CC1200_XOSC5 0x2F32 /* Crystal Oscillator Configuration Reg. 5 */ +#define CC1200_XOSC4 0x2F33 /* Crystal Oscillator Configuration Reg. 4 */ +#define CC1200_XOSC3 0x2F34 /* Crystal Oscillator Configuration Reg. 3 */ +#define CC1200_XOSC2 0x2F35 /* Crystal Oscillator Configuration Reg. 2 */ +#define CC1200_XOSC1 0x2F36 /* Crystal Oscillator Configuration Reg. 1 */ +#define CC1200_XOSC0 0x2F37 /* Crystal Oscillator Configuration Reg. 0 */ +#define CC1200_ANALOG_SPARE 0x2F38 /* Analog Spare */ +#define CC1200_PA_CFG3 0x2F39 /* Power Amplifier Configuration Reg. 3 */ +#define CC1200_WOR_TIME1 0x2F64 /* eWOR Timer Counter Value MSB */ +#define CC1200_WOR_TIME0 0x2F65 /* eWOR Timer Counter Value LSB */ +#define CC1200_WOR_CAPTURE1 0x2F66 /* eWOR Timer Capture Value MSB */ +#define CC1200_WOR_CAPTURE0 0x2F67 /* eWOR Timer Capture Value LSB */ +#define CC1200_BIST 0x2F68 /* MARC Built-In Self-Test */ +#define CC1200_DCFILTOFFSET_I1 0x2F69 /* DC Filter Offset I MSB */ +#define CC1200_DCFILTOFFSET_I0 0x2F6A /* DC Filter Offset I LSB */ +#define CC1200_DCFILTOFFSET_Q1 0x2F6B /* DC Filter Offset Q MSB */ +#define CC1200_DCFILTOFFSET_Q0 0x2F6C /* DC Filter Offset Q LSB */ +#define CC1200_IQIE_I1 0x2F6D /* IQ Imbalance Value I MSB */ +#define CC1200_IQIE_I0 0x2F6E /* IQ Imbalance Value I LSB */ +#define CC1200_IQIE_Q1 0x2F6F /* IQ Imbalance Value Q MSB */ +#define CC1200_IQIE_Q0 0x2F70 /* IQ Imbalance Value Q LSB */ +#define CC1200_RSSI1 0x2F71 /* Received Signal Strength Indicator Reg. 1 */ +#define CC1200_RSSI0 0x2F72 /* Received Signal Strength Indicator Reg.0 */ +#define CC1200_MARCSTATE 0x2F73 /* MARC State */ +#define CC1200_LQI_VAL 0x2F74 /* Link Quality Indicator Value */ +#define CC1200_PQT_SYNC_ERR 0x2F75 /* Preamble and Sync Word Error */ +#define CC1200_DEM_STATUS 0x2F76 /* Demodulator Status */ +#define CC1200_FREQOFF_EST1 0x2F77 /* Frequency Offset Estimate MSB */ +#define CC1200_FREQOFF_EST0 0x2F78 /* Frequency Offset Estimate LSB */ +#define CC1200_AGC_GAIN3 0x2F79 /* Automatic Gain Control Reg. 3 */ +#define CC1200_AGC_GAIN2 0x2F7A /* Automatic Gain Control Reg. 2 */ +#define CC1200_AGC_GAIN1 0x2F7B /* Automatic Gain Control Reg. 1 */ +#define CC1200_AGC_GAIN0 0x2F7C /* Automatic Gain Control Reg. 0 */ +#define CC1200_CFM_RX_DATA_OUT 0x2F7D /* Custom Frequency Modulation RX Data */ +#define CC1200_CFM_TX_DATA_IN 0x2F7E /* Custom Frequency Modulation TX Data */ +#define CC1200_ASK_SOFT_RX_DATA 0x2F7F /* ASK Soft Decision Output */ +#define CC1200_RNDGEN 0x2F80 /* Random Number Generator Value */ +#define CC1200_MAGN2 0x2F81 /* Signal Magnitude after CORDIC [16] */ +#define CC1200_MAGN1 0x2F82 /* Signal Magnitude after CORDIC [15:8] */ +#define CC1200_MAGN0 0x2F83 /* Signal Magnitude after CORDIC [7:0] */ +#define CC1200_ANG1 0x2F84 /* Signal Angular after CORDIC [9:8] */ +#define CC1200_ANG0 0x2F85 /* Signal Angular after CORDIC [7:0] */ +#define CC1200_CHFILT_I2 0x2F86 /* Channel Filter Data Real Part [16] */ +#define CC1200_CHFILT_I1 0x2F87 /* Channel Filter Data Real Part [15:8] */ +#define CC1200_CHFILT_I0 0x2F88 /* Channel Filter Data Real Part [7:0] */ +#define CC1200_CHFILT_Q2 0x2F89 /* Channel Filter Data Imaginary Part [16] */ +#define CC1200_CHFILT_Q1 0x2F8A /* Channel Filter Data Imaginary Part [15:8] */ +#define CC1200_CHFILT_Q0 0x2F8B /* Channel Filter Data Imaginary Part [7:0] */ +#define CC1200_GPIO_STATUS 0x2F8C /* General Purpose Input/Output Status */ +#define CC1200_FSCAL_CTRL 0x2F8D /* Frequency Synthesizer Calibration Control */ +#define CC1200_PHASE_ADJUST 0x2F8E /* Frequency Synthesizer Phase Adjust */ +#define CC1200_PARTNUMBER 0x2F8F /* Part Number */ +#define CC1200_PARTVERSION 0x2F90 /* Part Revision */ +#define CC1200_SERIAL_STATUS 0x2F91 /* Serial Status */ +#define CC1200_MODEM_STATUS1 0x2F92 /* Modem Status Reg. 1 */ +#define CC1200_MODEM_STATUS0 0x2F93 /* Modem Status Reg. 0 */ +#define CC1200_MARC_STATUS1 0x2F94 /* MARC Status Reg. 1 */ +#define CC1200_MARC_STATUS0 0x2F95 /* MARC Status Reg. 0 */ +#define CC1200_PA_IFAMP_TEST 0x2F96 /* Power Amplifier Intermediate Frequency Amplifier T.. */ +#define CC1200_FSRF_TEST 0x2F97 /* Frequency Synthesizer Test */ +#define CC1200_PRE_TEST 0x2F98 /* Frequency Synthesizer Prescaler Test */ +#define CC1200_PRE_OVR 0x2F99 /* Frequency Synthesizer Prescaler Override */ +#define CC1200_ADC_TEST 0x2F9A /* Analog to Digital Converter Test */ +#define CC1200_DVC_TEST 0x2F9B /* Digital Divider Chain Test */ +#define CC1200_ATEST 0x2F9C /* Analog Test */ +#define CC1200_ATEST_LVDS 0x2F9D /* Analog Test LVDS */ +#define CC1200_ATEST_MODE 0x2F9E /* Analog Test Mode */ +#define CC1200_XOSC_TEST1 0x2F9F /* Crystal Oscillator Test Reg. 1 */ +#define CC1200_XOSC_TEST0 0x2FA0 /* Crystal Oscillator Test Reg. 0 */ +#define CC1200_AES 0x2FA1 /* AES */ +#define CC1200_MDM_TEST 0x2FA2 /* MODEM Test */ +#define CC1200_RXFIRST 0x2FD2 /* RX FIFO Pointer First Entry */ +#define CC1200_TXFIRST 0x2FD3 /* TX FIFO Pointer First Entry */ +#define CC1200_RXLAST 0x2FD4 /* RX FIFO Pointer Last Entry */ +#define CC1200_TXLAST 0x2FD5 /* TX FIFO Pointer Last Entry */ +#define CC1200_NUM_TXBYTES 0x2FD6 /* TX FIFO Status */ +#define CC1200_NUM_RXBYTES 0x2FD7 /* RX FIFO Status */ +#define CC1200_FIFO_NUM_TXBYTES 0x2FD8 /* TX FIFO Status */ +#define CC1200_FIFO_NUM_RXBYTES 0x2FD9 /* RX FIFO Status */ +#define CC1200_RXFIFO_PRE_BUF 0x2FDA /* RX FIFO Status */ +#define CC1200_AES_KEY15 0x2FE0 /* Advanced Encryption Standard Key [127:120] */ +#define CC1200_AES_KEY14 0x2FE1 /* Advanced Encryption Standard Key [119:112] */ +#define CC1200_AES_KEY13 0x2FE2 /* Advanced Encryption Standard Key [111:104] */ +#define CC1200_AES_KEY12 0x2FE3 /* Advanced Encryption Standard Key [103:96] */ +#define CC1200_AES_KEY11 0x2FE4 /* Advanced Encryption Standard Key [95:88] */ +#define CC1200_AES_KEY10 0x2FE5 /* Advanced Encryption Standard Key [87:80] */ +#define CC1200_AES_KEY9 0x2FE6 /* Advanced Encryption Standard Key [79:72] */ +#define CC1200_AES_KEY8 0x2FE7 /* Advanced Encryption Standard Key [71:64] */ +#define CC1200_AES_KEY7 0x2FE8 /* Advanced Encryption Standard Key [63:56] */ +#define CC1200_AES_KEY6 0x2FE9 /* Advanced Encryption Standard Key [55:48] */ +#define CC1200_AES_KEY5 0x2FEA /* Advanced Encryption Standard Key [47:40] */ +#define CC1200_AES_KEY4 0x2FEB /* Advanced Encryption Standard Key [39:32] */ +#define CC1200_AES_KEY3 0x2FEC /* Advanced Encryption Standard Key [31:24] */ +#define CC1200_AES_KEY2 0x2FED /* Advanced Encryption Standard Key [23:16] */ +#define CC1200_AES_KEY1 0x2FEE /* Advanced Encryption Standard Key [15:8] */ +#define CC1200_AES_KEY0 0x2FEF /* Advanced Encryption Standard Key [7:0] */ +#define CC1200_AES_BUFFER15 0x2FF0 /* Advanced Encryption Standard Buffer [127:120] */ +#define CC1200_AES_BUFFER14 0x2FF1 /* Advanced Encryption Standard Buffer [119:112] */ +#define CC1200_AES_BUFFER13 0x2FF2 /* Advanced Encryption Standard Buffer [111:104] */ +#define CC1200_AES_BUFFER12 0x2FF3 /* Advanced Encryption Standard Buffer [103:93] */ +#define CC1200_AES_BUFFER11 0x2FF4 /* Advanced Encryption Standard Buffer [95:88] */ +#define CC1200_AES_BUFFER10 0x2FF5 /* Advanced Encryption Standard Buffer [87:80] */ +#define CC1200_AES_BUFFER9 0x2FF6 /* Advanced Encryption Standard Buffer [79:72] */ +#define CC1200_AES_BUFFER8 0x2FF7 /* Advanced Encryption Standard Buffer [71:64] */ +#define CC1200_AES_BUFFER7 0x2FF8 /* Advanced Encryption Standard Buffer [63:56] */ +#define CC1200_AES_BUFFER6 0x2FF9 /* Advanced Encryption Standard Buffer [55:48] */ +#define CC1200_AES_BUFFER5 0x2FFA /* Advanced Encryption Standard Buffer [47:40] */ +#define CC1200_AES_BUFFER4 0x2FFB /* Advanced Encryption Standard Buffer [39:32] */ +#define CC1200_AES_BUFFER3 0x2FFC /* Advanced Encryption Standard Buffer [31:24] */ +#define CC1200_AES_BUFFER2 0x2FFD /* Advanced Encryption Standard Buffer [23:16] */ +#define CC1200_AES_BUFFER1 0x2FFE /* Advanced Encryption Standard Buffer [15:8] */ +#define CC1200_AES_BUFFER0 0x2FFF /* Advanced Encryption Standard Buffer [7:0] */ +/*---------------------------------------------------------------------------*/ +/* Access to RX / TX FIFO */ +#define CC1200_TXFIFO 0x3F +#define CC1200_RXFIFO 0x3F +/*---------------------------------------------------------------------------*/ +/* MARC_STATE */ +#define CC1200_MARC_STATE_SLEEP 0x00 +#define CC1200_MARC_STATE_IDLE 0x01 +#define CC1200_MARC_STATE_RX 0x0D +#define CC1200_MARC_STATE_RX_FIFO_ERR 0x11 +#define CC1200_MARC_STATE_TX 0x13 +#define CC1200_MARC_STATE_TX_FIFO_ERR 0x16 +/*---------------------------------------------------------------------------*/ +/* Status byte */ +#define CC1200_STATUS_BYTE_IDLE (0 << 4) +#define CC1200_STATUS_BYTE_RX (1 << 4) +#define CC1200_STATUS_BYTE_TX (2 << 4) +#define CC1200_STATUS_BYTE_FSTXON (3 << 4) +#define CC1200_STATUS_BYTE_CALIBRATE (4 << 4) +#define CC1200_STATUS_BYTE_SETTLING (5 << 4) +#define CC1200_STATUS_BYTE_RX_FIFO_ERR (6 << 4) +#define CC1200_STATUS_BYTE_TX_FIFO_ERR (7 << 4) +/*---------------------------------------------------------------------------*/ +/* GPIO configuration */ +#define CC1200_IOCFG_RXFIFO_THR 0 +#define CC1200_IOCFG_RXFFIFO_THR_PKT 1 +#define CC1200_IOCFG_TXFIFO_THR 2 +#define CC1200_IOCFG_PKT_SYNC_RXTX 6 +#define CC1200_IOCFG_SERIAL_CLK 8 +#define CC1200_IOCFG_SERIAL_RX 9 +#define CC1200_IOCFG_CARRIER_SENSE 17 +#define CC1200_IOCFG_MARC_2PIN_STATUS_1 37 +#define CC1200_IOCFG_MARC_2PIN_STATUS_0 38 +#define CC1200_IOCFG_RXFIFO_CHIP_RDY_N 50 +/*---------------------------------------------------------------------------*/ +/* Command strobes */ +#define CC1200_SRES 0x30 +#define CC1200_SFSTXON 0x31 +#define CC1200_SXOFF 0x32 +#define CC1200_SCAL 0x33 +#define CC1200_SRX 0x34 +#define CC1200_STX 0x35 +#define CC1200_SIDLE 0x36 +#define CC1200_SPWD 0x39 +#define CC1200_SFRX 0x3A +#define CC1200_SFTX 0x3B +#define CC1200_SNOP 0x3D +/*---------------------------------------------------------------------------*/ +/* SPI access modifier */ +#define CC1200_WRITE_BIT 0x00 +#define CC1200_READ_BIT 0x80 +#define CC1200_BURST_BIT 0x40 +#define CC1200_EXTENDED_WRITE_CMD (0x2F | CC1200_WRITE_BIT) +#define CC1200_EXTENDED_BURST_WRITE_CMD \ + (0x2F | CC1200_BURST_BIT | CC1200_WRITE_BIT) +#define CC1200_EXTENDED_READ_CMD (0x2F | CC1200_READ_BIT) +#define CC1200_EXTENDED_BURST_READ_CMD \ + (0x2F | CC1200_BURST_BIT | CC1200_READ_BIT) +/*---------------------------------------------------------------------------*/ +#define CC1200_IS_EXTENDED_ADDR(x) (x & 0x2F00) +/*---------------------------------------------------------------------------*/ +/* RSSI0 register */ +#define CC1200_CARRIER_SENSE_VALID (1 << 1) +#define CC1200_CARRIER_SENSE (1 << 2) +/*---------------------------------------------------------------------------*/ +/* MODEM_STATUS1 register */ +#define CC1200_SYNC_FOUND (1 << 7) +#define CC1200_PQT_REACHED (1 << 1) +/*---------------------------------------------------------------------------*/ +#define CC1200_FIFO_SIZE 128 +/*---------------------------------------------------------------------------*/ +/* Output power in dBm */ +/* Up to now we don't handle the special power levels PA_POWER_RAMP < 3, hence + * the minimum tx power is -16. See update_txpower(). + */ +#define CC1200_CONST_TX_POWER_MIN (-16) +/* + * Maximum output power will propably depend on the band we use due to + * regulation issues + */ +#define CC1200_CONST_TX_POWER_MAX 14 +/*---------------------------------------------------------------------------*/ +/* CCA threshold in dBm */ +#define CC1200_CONST_CCA_THRESHOLD_MIN (-127) +#define CC1200_CONST_CCA_THRESHOLD_MAX 127 + +#endif /* CC1200_CONST_H_ */ diff --git a/dev/cc1200/cc1200-rf-cfg.h b/dev/cc1200/cc1200-rf-cfg.h new file mode 100644 index 000000000..c7ba53527 --- /dev/null +++ b/dev/cc1200/cc1200-rf-cfg.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2015, Weptech elektronik GmbH Germany + * http://www.weptech.de + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + */ + +#ifndef CC1200_RF_CFG_H +#define CC1200_RF_CFG_H + +#include "contiki.h" + +#include +#include + +/*---------------------------------------------------------------------------*/ +/* + * We export the register setup from SmartRF using the standard template + * "trxEB RF Settings Performance Line" and have therefore to typedef + * the following struct. + */ +typedef struct cc1200_registerSetting { + uint16_t addr; + uint8_t val; +} registerSetting_t; +/*---------------------------------------------------------------------------*/ +/* Map SmartRF typedef to reflect Contiki's naming conventions */ +typedef registerSetting_t cc1200_register_settings_t; +/*---------------------------------------------------------------------------*/ +/* This struct holds the complete configuration for a given mode */ +typedef struct cc1200_rf_cfg { + /* A string describing the mode */ + const char *cfg_descriptor; + /* A pointer to a register setup exported from SmartRF */ + const cc1200_register_settings_t *register_settings; + /* The size of the register setup */ + size_t size_of_register_settings; + /* + * TX packet lifetime. Maximum duration of a TX packet including preamble, + * synch word + phy header, payload + CRC. + */ + rtimer_clock_t tx_pkt_lifetime; + /* Base frequency in kHz */ + uint32_t chan_center_freq0; + /* Channel spacing in kHz */ + uint16_t chan_spacing; + /* The minimum channel */ + uint8_t min_channel; + /* The maximum channel */ + uint8_t max_channel; + /* The maximum output power in dBm */ + int8_t max_txpower; + /* + * The carrier sense level used for CCA in dBm (int8_t). Limited by + * CC1200_CONST_CCA_THRESHOLD_MIN and CC1200_CONST_CCA_THRESHOLD_MAX. + */ + int8_t cca_threshold; +} cc1200_rf_cfg_t; +/*---------------------------------------------------------------------------*/ +#endif /* CC1200_RF_CFG_H */ diff --git a/dev/cc1200/cc1200.c b/dev/cc1200/cc1200.c new file mode 100644 index 000000000..bed33c5b6 --- /dev/null +++ b/dev/cc1200/cc1200.c @@ -0,0 +1,2483 @@ +/* + * Copyright (c) 2015, Weptech elektronik GmbH Germany + * http://www.weptech.de + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + */ + +#include "cc1200-const.h" +#include "cc1200-conf.h" +#include "cc1200-arch.h" +#include "cc1200-rf-cfg.h" + +#include "net/netstack.h" +#include "net/packetbuf.h" +#include "net/rime/rimestats.h" + +#include "dev/leds.h" + +#include +#include + +/*---------------------------------------------------------------------------*/ +/* Various implementation specific defines */ +/*---------------------------------------------------------------------------*/ +/* + * The debug level to use + * - 0: No output at all + * - 1: Print errors (unrecoverable) + * - 2: Print errors + warnings (recoverable errors) + * - 3: Print errors + warnings + information (what's going on...) + */ +#define DEBUG_LEVEL 2 +/* + * RF test mode. Blocks inside "configure()". + * - Set this parameter to 1 in order to produce an modulated carrier (PN9) + * - Set this parameter to 2 in order to produce an unmodulated carrier + * - Set this parameter to 3 in order to switch to rx synchronous mode + * The channel is set according to CC1200_DEFAULT_CHANNEL + */ +#ifndef CC1200_RF_TESTMODE +#define CC1200_RF_TESTMODE 0 +#endif + +#if CC1200_RF_TESTMODE +#undef CC1200_RF_CFG +#if CC1200_RF_TESTMODE == 1 +#define CC1200_RF_CFG cc1200_802154g_863_870_fsk_50kbps +#elif CC1200_RF_TESTMODE == 2 +#define CC1200_RF_CFG cc1200_802154g_863_870_fsk_50kbps +#elif CC1200_RF_TESTMODE == 3 +#define CC1200_RF_CFG cc1200_802154g_863_870_fsk_50kbps +#endif +#endif +/* + * Set this parameter to 1 in order to use the MARC_STATE register when + * polling the chips's status. Else use the status byte returned when sending + * a NOP strobe. + * + * TODO: Option to be removed upon approval of the driver + */ +#define STATE_USES_MARC_STATE 0 +/* + * Set this parameter to 1 in order to speed up transmission by + * sending a FSTXON strobe before filling the FIFO. + * + * TODO: Option to be removed upon approval of the driver + */ +#define USE_SFSTXON 1 +/*---------------------------------------------------------------------------*/ +/* Phy header length */ +#if CC1200_802154G +/* Phy header = 2 byte */ +#define PHR_LEN 2 +#else +/* Phy header = length byte = 1 byte */ +#define PHR_LEN 1 +#endif /* #if CC1200_802154G */ +/*---------------------------------------------------------------------------*/ +/* Size of appendix (rssi + lqi) appended to the rx pkt */ +#define APPENDIX_LEN 2 +/*---------------------------------------------------------------------------*/ +/* Verify payload length */ +/*---------------------------------------------------------------------------*/ +#if CC1200_802154G +#if CC1200_USE_GPIO2 +#if CC1200_MAX_PAYLOAD_LEN > (2048 - PHR_LEN) +#error Payload length not supported by this driver +#endif +#else +#if CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN) +/* PHR_LEN = 2 -> we can only place 126 payload bytes bytes in the FIFO */ +#error Payload length not supported without GPIO2 +#endif +#endif /* #if CC1200_USE_GPIO2 */ +#else /* #if CC1200_802154G */ +#if CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN) +/* PHR_LEN = 1 -> we can only place 127 payload bytes bytes in the FIFO */ +#error Payload length not supported without enabling 802.15.4g mode +#endif +#endif /* #if CC1200_802154G */ +/*---------------------------------------------------------------------------*/ +/* Main driver configurations settings. Don't touch! */ +/*---------------------------------------------------------------------------*/ +#if CC1200_USE_GPIO2 +/* Use GPIO2 as RX / TX FIFO threshold indicator pin */ +#define GPIO2_IOCFG CC1200_IOCFG_RXFIFO_THR +/* This is the FIFO threshold we use */ +#define FIFO_THRESHOLD 32 +/* Turn on RX after packet reception */ +#define RXOFF_MODE_RX 1 +/* Let the CC1200 append RSSI + LQI */ +#define APPEND_STATUS 1 +#else +/* Arbitrary configuration for GPIO2 */ +#define GPIO2_IOCFG CC1200_IOCFG_MARC_2PIN_STATUS_0 +#if (CC1200_MAX_PAYLOAD_LEN <= (CC1200_FIFO_SIZE - PHR_LEN - APPENDIX_LEN)) +/* + * Read out RX FIFO at the end of the packet (GPIO0 falling edge). RX restarts + * automatically + */ +#define RXOFF_MODE_RX 1 +/* Let the CC1200 append RSSI + LQI */ +#define APPEND_STATUS 1 +#else +/* + * Read out RX FIFO at the end of the packet (GPIO0 falling edge). RX has + * to be started manually in this case + */ +#define RXOFF_MODE_RX 0 +/* No space for appendix in the RX FIFO. Read it out by hand */ +#define APPEND_STATUS 0 +#endif /* #if CC1200_MAX_PAYLOAD_LEN <= 125 */ +#endif /* #if CC1200_USE_GPIO2 */ + +/* Read out packet on falling edge of GPIO0 */ +#define GPIO0_IOCFG CC1200_IOCFG_PKT_SYNC_RXTX +/* Arbitrary configuration for GPIO3 */ +#define GPIO3_IOCFG CC1200_IOCFG_MARC_2PIN_STATUS_0 +/* Turn on RX automatically after TX */ +#define TXOFF_MODE_RX 1 +#if APPEND_STATUS +/* CC1200 places two bytes in the RX FIFO */ +#define CC_APPENDIX_LEN 2 +#else +/* CC1200 doesn't add appendix to RX FIFO */ +#define CC_APPENDIX_LEN 0 +#endif /* #if APPEND_STATUS */ +/*---------------------------------------------------------------------------*/ +/* RF configuration */ +/*---------------------------------------------------------------------------*/ +/* Import the rf configuration set by CC1200_RF_CFG */ +extern const cc1200_rf_cfg_t CC1200_RF_CFG; +/*---------------------------------------------------------------------------*/ +/* This defines the way we calculate the frequency registers */ +/*---------------------------------------------------------------------------*/ +/* XTAL frequency in kHz */ +#define XTAL_FREQ_KHZ 40000 +/* + * Divider + multiplier for calculation of FREQ registers + * f * 2^16 * 4 / 40000 = f * 2^12 / 625 (no overflow up to frequencies of + * 1048.576 MHz using uint32_t) + */ +#define LO_DIVIDER 4 +#if (XTAL_FREQ_KHZ == 40000) && (LO_DIVIDER == 4) +#define FREQ_DIVIDER 625 +#define FREQ_MULTIPLIER 4096 +#else +#error Invalid settings for frequency calculation +#endif +/*---------------------------------------------------------------------------*/ +#if STATE_USES_MARC_STATE +/* We use the MARC_STATE register to poll the chip's status */ +#define STATE_IDLE CC1200_MARC_STATE_IDLE +#define STATE_RX CC1200_MARC_STATE_RX +#define STATE_TX CC1200_MARC_STATE_TX +#define STATE_RX_FIFO_ERROR CC1200_MARC_STATE_RX_FIFO_ERR +#define STATE_TX_FIFO_ERROR CC1200_MARC_STATE_TX_FIFO_ERR +#else +/* We use the status byte read out using a NOP strobe */ +#define STATE_IDLE CC1200_STATUS_BYTE_IDLE +#define STATE_RX CC1200_STATUS_BYTE_RX +#define STATE_TX CC1200_STATUS_BYTE_TX +#define STATE_FSTXON CC1200_STATUS_BYTE_FSTXON +#define STATE_CALIBRATE CC1200_STATUS_BYTE_CALIBRATE +#define STATE_SETTLING CC1200_STATUS_BYTE_SETTLING +#define STATE_RX_FIFO_ERR CC1200_STATUS_BYTE_RX_FIFO_ERR +#define STATE_TX_FIFO_ERR CC1200_STATUS_BYTE_TX_FIFO_ERR +#endif /* #if STATE_USES_MARC_STATE */ +/*---------------------------------------------------------------------------*/ +/* Return values for addr_check_auto_ack() */ +/*---------------------------------------------------------------------------*/ +/* Frame cannot be parsed / is to short */ +#define INVALID_FRAME 0 +/* Address check failed */ +#define ADDR_CHECK_FAILED 1 +/* Address check succeeded */ +#define ADDR_CHECK_OK 2 +/* Address check succeeded and ACK was send */ +#define ADDR_CHECK_OK_ACK_SEND 3 +/*---------------------------------------------------------------------------*/ +/* Return values for set_channel() */ +/*---------------------------------------------------------------------------*/ +/* Channel update was performed */ +#define CHANNEL_UPDATE_SUCCEEDED 0 +/* Busy, channel update postponed */ +#define CHANNEL_UPDATE_POSTPONED 1 +/* Invalid channel */ +#define CHANNEL_OUT_OF_LIMITS 2 +/*---------------------------------------------------------------------------*/ +/* Various flags indicating the operating state of the radio. See rf_flags */ +/*---------------------------------------------------------------------------*/ +/* Radio was initialized (= init() was called) */ +#define RF_INITIALIZED 0x01 +/* The radio is on (= not in standby) */ +#define RF_ON 0x02 +/* An incoming packet was detected (at least payload length was received */ +#define RF_RX_PROCESSING_PKT 0x04 +/* TX is ongoing */ +#define RF_TX_ACTIVE 0x08 +/* Channel update required */ +#define RF_UPDATE_CHANNEL 0x10 +/* SPI was locked when calling RX interrupt, let the pollhandler do the job */ +#define RF_POLL_RX_INTERRUPT 0x20 +/* Force calibration in case we don't use CC1200 AUTOCAL + timeout */ +#if !CC1200_AUTOCAL +#if CC1200_CAL_TIMEOUT_SECONDS +#define RF_FORCE_CALIBRATION 0x40 +#endif +#endif +/*---------------------------------------------------------------------------*/ +/* Length of 802.15.4 ACK. We discard packets with a smaller size */ +#define ACK_LEN 3 +/*---------------------------------------------------------------------------*/ +/* This is the way we handle the LEDs */ +/*---------------------------------------------------------------------------*/ +#ifdef CC1200_TX_LEDS +#define TX_LEDS_ON() leds_on(CC1200_TX_LEDS) +#define TX_LEDS_OFF() leds_off(CC1200_TX_LEDS) +#else +#define TX_LEDS_ON() +#define TX_LEDS_OFF() +#endif /* #ifdef CC1200_TX_LEDS */ + +#ifdef CC1200_RX_LEDS +#define RX_LEDS_ON() leds_on(CC1200_RX_LEDS) +#define RX_LEDS_OFF() leds_off(CC1200_RX_LEDS) +#else +#define RX_LEDS_ON() +#define RX_LEDS_OFF() +#endif /* #ifdef CC1200_RX_LEDS */ +/*---------------------------------------------------------------------------*/ +/* + * We have to prevent duplicate SPI access. + * We therefore LOCK SPI in order to prevent the rx interrupt to + * interfere. + */ +#define LOCK_SPI() do { spi_locked++; } while(0) +#define SPI_IS_LOCKED() (spi_locked != 0) +#define RELEASE_SPI() do { spi_locked--; } while(0) +/*---------------------------------------------------------------------------*/ +#define BUSYWAIT_UNTIL(cond, max_time) \ + do { \ + rtimer_clock_t t0; \ + t0 = RTIMER_NOW(); \ + while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))) {} \ + } while(0) +/*---------------------------------------------------------------------------*/ +#if CC1200_USE_GPIO2 +/* Configure GPIO interrupts. GPIO0: falling, GPIO2: rising edge */ +#define SETUP_GPIO_INTERRUPTS() \ + do { \ + cc1200_arch_gpio0_setup_irq(0); \ + cc1200_arch_gpio2_setup_irq(1); \ + } while(0) +#define ENABLE_GPIO_INTERRUPTS() \ + do { \ + cc1200_arch_gpio0_enable_irq(); \ + cc1200_arch_gpio2_enable_irq(); \ + } while(0) +#define DISABLE_GPIO_INTERRUPTS() \ + do { \ + cc1200_arch_gpio0_disable_irq(); \ + cc1200_arch_gpio2_disable_irq(); \ + } while(0) +#else +#define SETUP_GPIO_INTERRUPTS() cc1200_arch_gpio0_setup_irq(0) +#define ENABLE_GPIO_INTERRUPTS() cc1200_arch_gpio0_enable_irq() +#define DISABLE_GPIO_INTERRUPTS() cc1200_arch_gpio0_disable_irq() +#endif /* #if CC1200_USE_GPIO2 */ +/*---------------------------------------------------------------------------*/ +/* Debug macros */ +/*---------------------------------------------------------------------------*/ +#if DEBUG_LEVEL > 0 +/* Show all kind of errors e.g. when passing invalid payload length */ +#define ERROR(...) printf(__VA_ARGS__) +#else +#define ERROR(...) +#endif + +#if DEBUG_LEVEL > 0 +/* This macro is used to check if the radio is in a valid state */ +#define RF_ASSERT(condition) \ + do { \ + if(!(condition)) { \ + printf("RF: Assertion failed in line %d\n", __LINE__); \ + } \ + } while(0) +#else +#define RF_ASSERT(condition) +#endif + +#if DEBUG_LEVEL > 1 +/* Show warnings e.g. for FIFO errors */ +#define WARNING(...) printf(__VA_ARGS__) +#else +#define WARNING(...) +#endif + +#if DEBUG_LEVEL > 2 +/* We just print out what's going on */ +#define INFO(...) printf(__VA_ARGS__) +#else +#define INFO(...) +#endif + +#if DEBUG_LEVEL > 0 +/* + * As BUSYWAIT_UNTIL was mainly used to test for a state transition, + * we define a separate macro for this adding the possibility to + * throw an error message when the timeout exceeds + */ +#define BUSYWAIT_UNTIL_STATE(s, t) \ + do { \ + rtimer_clock_t t0; \ + t0 = RTIMER_NOW(); \ + while((state() != s) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (t))) {} \ + if(!(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (t)))) { \ + printf("RF: Timeout exceeded in line %d!\n", __LINE__); \ + } \ + } while(0) +#else +#define BUSYWAIT_UNTIL_STATE(s, t) \ + do { \ + rtimer_clock_t t0; \ + t0 = RTIMER_NOW(); \ + while((state() != s) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (t))) {} \ + } while(0) +#endif +/*---------------------------------------------------------------------------*/ +/* Sniffer configuration */ +#if CC1200_SNIFFER +static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; +#include "dev/uart.h" +#define write_byte(b) uart_write_byte(CC1200_RF_CONF_SNIFFER_UART, b) +#define flush() +#else /* CC1200_SNIFFER */ +#define write_byte(b) +#define flush() +#endif /* CC1200_SNIFFER */ +/*---------------------------------------------------------------------------*/ +/* Variables */ +/*---------------------------------------------------------------------------*/ +/* Flag indicating whether non-interrupt routines are using SPI */ +static volatile uint8_t spi_locked = 0; +/* Packet buffer for transmission, filled within prepare() */ +static uint8_t tx_pkt[CC1200_MAX_PAYLOAD_LEN]; +/* The number of bytes waiting in tx_pkt */ +static uint16_t tx_pkt_len; +/* Packet buffer for reception */ +static uint8_t rx_pkt[CC1200_MAX_PAYLOAD_LEN + APPENDIX_LEN]; +/* The number of bytes placed in rx_pkt */ +static volatile uint16_t rx_pkt_len = 0; +/* + * The current channel in the range CC1200_RF_CHANNEL_MIN + * to CC1200_RF_CHANNEL_MAX + */ +static uint8_t rf_channel; +/* The next channel requested */ +static uint8_t new_rf_channel; +/* RADIO_PARAM_RX_MODE. Initialized in init() */ +static radio_value_t rx_mode_value; +/* RADIO_PARAM_RX_MODE. Initialized in init() */ +static radio_value_t tx_mode_value; +/* RADIO_PARAM_TXPOWER in dBm. Initialized in init() */ +static int8_t txpower; +static int8_t new_txpower; +/* RADIO_PARAM_CCA_THRESHOLD. Initialized in init() */ +static int8_t cca_threshold; +static int8_t new_cca_threshold; +/* The radio drivers state */ +static uint8_t rf_flags = 0; +#if !CC1200_AUTOCAL && CC1200_CAL_TIMEOUT_SECONDS +/* Use a timeout to decide when to calibrate */ +static unsigned long cal_timer; +#endif +#if CC1200_USE_RX_WATCHDOG +/* Timer used for RX watchdog */ +static struct etimer et; +#endif /* #if CC1200_USE_RX_WATCHDOG */ +/*---------------------------------------------------------------------------*/ +/* Prototypes for Netstack API radio driver functions */ +/*---------------------------------------------------------------------------*/ +/* Init the radio. */ +static int +init(void); +/* Prepare the radio with a packet to be sent. */ +static int +prepare(const void *payload, unsigned short payload_len); +/* Send the packet that has previously been prepared. */ +static int +transmit(unsigned short payload_len); +/* Prepare & transmit a packet. */ +static int +send(const void *payload, unsigned short payload_len); +/* Read a received packet into a buffer. */ +static int +read(void *buf, unsigned short bufsize); +/* + * Perform a Clear-Channel Assessment (CCA) to find out if there is + * a packet in the air or not. + */ +static int +channel_clear(void); +/* Check if the radio driver is currently receiving a packet. */ +static int +receiving_packet(void); +/* Check if the radio driver has just received a packet. */ +static int +pending_packet(void); +/* Turn the radio on. */ +static int +on(void); +/* Turn the radio off. */ +static int +off(void); +/* Get a radio parameter value. */ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value); +/* Set a radio parameter value. */ +static radio_result_t +set_value(radio_param_t param, radio_value_t value); +/* Get a radio parameter object. */ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size); +/* Set a radio parameter object. */ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size); +/*---------------------------------------------------------------------------*/ +/* The radio driver exported to contiki */ +/*---------------------------------------------------------------------------*/ +const struct radio_driver cc1200_driver = { + init, + prepare, + transmit, + send, + read, + channel_clear, + receiving_packet, + pending_packet, + on, + off, + get_value, + set_value, + get_object, + set_object +}; +/*---------------------------------------------------------------------------*/ +/* Prototypes for CC1200 low level function. All of these functions are + called by the radio driver functions or the rx interrupt, + so there is no need to lock SPI within these functions */ +/*---------------------------------------------------------------------------*/ +/* Send a command strobe. */ +static uint8_t +strobe(uint8_t strobe); +/* Reset CC1200. */ +static void +reset(void); +/* Write a single byte to the specified address. */ +static uint8_t +single_write(uint16_t addr, uint8_t value); +/* Read a single byte from the specified address. */ +static uint8_t +single_read(uint16_t addr); +/* Write a burst of bytes starting at the specified address. */ +static void +burst_write(uint16_t addr, const uint8_t *data, uint8_t data_len); +/* Read a burst of bytes starting at the specified address. */ +static void +burst_read(uint16_t addr, uint8_t *data, uint8_t data_len); +/* Write a list of register settings. */ +static void +write_reg_settings(const registerSetting_t *reg_settings, + uint16_t sizeof_reg_settings); +/* Configure the radio (write basic configuration). */ +static void +configure(void); +/* Return the radio's state. */ +static uint8_t +state(void); +#if !CC1200_AUTOCAL +/* Perform manual calibration. */ +static void +calibrate(void); +#endif +/* Enter IDLE state. */ +static void +idle(void); +/* Enter RX state. */ +static void +idle_calibrate_rx(void); +/* Restart RX from within RX interrupt. */ +static void +rx_rx(void); +/* Fill TX FIFO, start TX and wait for TX to complete (blocking!). */ +static int +idle_tx_rx(const uint8_t *payload, uint16_t payload_len); +/* Update TX power */ +static void +update_txpower(int8_t txpower_dbm); +/* Update CCA threshold */ +static void +update_cca_threshold(int8_t threshold_dbm); +/* Calculate FREQ register from channel */ +static uint32_t +calculate_freq(uint8_t channel); +/* Update rf channel if possible, else postpone it (-> pollhandler). */ +static int +set_channel(uint8_t channel); +#if !CC1200_SNIFFER +/* Check broadcast address. */ +static int +is_broadcast_addr(uint8_t mode, uint8_t *addr); +#endif /* CC1200_SNIFFER */ +/* Validate address and send ACK if requested. */ +static int +addr_check_auto_ack(uint8_t *frame, uint16_t frame_len); +/*---------------------------------------------------------------------------*/ +/* Handle tasks left over from rx interrupt or because SPI was locked */ +static void pollhandler(void); +/*---------------------------------------------------------------------------*/ +PROCESS(cc1200_process, "CC1200 driver"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(cc1200_process, ev, data) +{ + + PROCESS_POLLHANDLER(pollhandler()); + + PROCESS_BEGIN(); + +#if CC1200_USE_RX_WATCHDOG && !CC1200_SNIFFER + /* RX watchdog interferes with sniffer. Reason unknown... */ + while(1) { + + if((rf_flags & (RF_ON | RF_TX_ACTIVE)) == RF_ON) { + + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + + /* + * We are on and not in TX. As every function of this driver + * assures that we are in RX mode + * (using BUSYWAIT_UNTIL_STATE(STATE_RX, ...) construct) in + * either rx_rx(), idle_calibrate_rx() or transmit(), + * something probably went wrong in the rx interrupt handler + * if we are not in RX at this point. + */ + + if(cc1200_arch_gpio0_read_pin() == 0) { + + /* + * GPIO de-asserts as soon as we leave RX for what reason ever. No + * reason to check RX as long as it is asserted (we are receiving a + * packet). We should never interfere with the rx interrupt if we + * check GPIO0 in advance... + */ + + LOCK_SPI(); + if(state() != STATE_RX) { + WARNING("RF: RX watchdog triggered!\n"); + rx_rx(); + } + RELEASE_SPI(); + + } + + } else { + PROCESS_YIELD(); + } + + } +#endif /* #if CC1200_USE_RX_WATCHDOG */ + + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_EXIT); + + PROCESS_END(); + +} +/*---------------------------------------------------------------------------*/ +/* Handle tasks left over from rx interrupt or because SPI was locked */ +static void +pollhandler(void) +{ + + if((rf_flags & (RF_ON + RF_POLL_RX_INTERRUPT)) == + (RF_ON + RF_POLL_RX_INTERRUPT)) { + cc1200_rx_interrupt(); + } + + if(rf_flags & RF_UPDATE_CHANNEL) { + /* We couldn't set the channel because we were busy. Try again now. */ + set_channel(new_rf_channel); + } + + if(rx_pkt_len > 0) { + + int len; + + /* + * We received a valid packet. CRC was checked before, + * address filtering was performed (if configured) + * and ACK was send (if configured) + */ + + packetbuf_clear(); + len = read(packetbuf_dataptr(), PACKETBUF_SIZE); + + if(len > 0) { + packetbuf_set_datalen(len); + NETSTACK_RDC.input(); + } + + } + +} +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/* + * Netstack API radio driver functions + */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +/* Initialize radio. */ +static int +init(void) +{ + + INFO("RF: Init (%s)\n", CC1200_RF_CFG.cfg_descriptor); + + if(!(rf_flags & RF_INITIALIZED)) { + + LOCK_SPI(); + + /* Perform low level initialization */ + cc1200_arch_init(); + + /* Configure GPIO interrupts */ + SETUP_GPIO_INTERRUPTS(); + + /* Write initial configuration */ + configure(); + + /* Enable address filtering + auto ack */ + rx_mode_value = (RADIO_RX_MODE_AUTOACK | RADIO_RX_MODE_ADDRESS_FILTER); + + /* Enable CCA */ + tx_mode_value = (RADIO_TX_MODE_SEND_ON_CCA); + + /* Set output power */ + new_txpower = CC1200_RF_CFG.max_txpower; + update_txpower(new_txpower); + + /* Adjust CAA threshold */ + new_cca_threshold = CC1200_RF_CFG.cca_threshold; + update_cca_threshold(new_cca_threshold); + + process_start(&cc1200_process, NULL); + + /* We are on + initialized at this point */ + rf_flags |= (RF_INITIALIZED + RF_ON); + + RELEASE_SPI(); + + /* Set default channel. This will also force initial calibration! */ + set_channel(CC1200_DEFAULT_CHANNEL); + + /* + * We have to call off() before on() because on() relies on the + * configuration of the GPIO0 pin + */ + off(); + +/* #if CC1200_SNIFFER */ +/* on(); */ +/* #endif */ + + } + + return 1; + +} +/*---------------------------------------------------------------------------*/ +/* Prepare the radio with a packet to be sent. */ +static int +prepare(const void *payload, unsigned short payload_len) +{ + + INFO("RF: Prepare (%d)\n", payload_len); + + if((payload_len < ACK_LEN) || + (payload_len > CC1200_MAX_PAYLOAD_LEN)) { + ERROR("RF: Invalid payload length!\n"); + return RADIO_TX_ERR; + } + + tx_pkt_len = payload_len; + memcpy(tx_pkt, payload, tx_pkt_len); + + return RADIO_TX_OK; + +} +/*---------------------------------------------------------------------------*/ +/* Send the packet that has previously been prepared. */ +static int +transmit(unsigned short transmit_len) +{ + + uint8_t was_off = 0; + int ret = RADIO_TX_OK; + + INFO("RF: Transmit (%d)\n", transmit_len); + + if(transmit_len != tx_pkt_len) { + ERROR("RF: TX length mismatch!\n"); + return RADIO_TX_ERR; + } + + /* TX ongoing. Inhibit channel update & ACK as soon as possible */ + rf_flags |= RF_TX_ACTIVE; + + if(!(rf_flags & RF_ON)) { + /* Radio is off - turn it on */ + was_off = 1; + on(); + /* Radio is in RX now (and calibrated...) */ + } + + if(tx_mode_value & RADIO_TX_MODE_SEND_ON_CCA) { + /* Perform clear channel assessment */ + if(!channel_clear()) { + /* Channel occupied */ + RIMESTATS_ADD(contentiondrop); + if(was_off) { + off(); + } + rf_flags &= ~RF_TX_ACTIVE; + return RADIO_TX_COLLISION; + } + } + + /* + * Lock SPI here because "on()" and "channel_clear()" + * won't work if SPI is locked! + */ + LOCK_SPI(); + + /* + * Make sure we start from a sane state. idle() also disables + * the GPIO interrupt(s). + */ + idle(); + + /* Update output power */ + if(new_txpower != txpower) { + update_txpower(new_txpower); + } + +#if !CC1200_AUTOCAL + /* Perform manual calibration unless just turned on */ + if(!was_off) { + calibrate(); + } +#endif + + RIMESTATS_ADD(lltx); + + /* Send data using TX FIFO */ + if(idle_tx_rx((const uint8_t *)tx_pkt, tx_pkt_len) == RADIO_TX_OK) { + + /* + * TXOFF_MODE is set to RX, + * let's wait until we are in RX and turn on the GPIO IRQs + * again as they were turned off in idle() + */ + + BUSYWAIT_UNTIL_STATE(STATE_RX, + RTIMER_SECOND / 100); + + ENABLE_GPIO_INTERRUPTS(); + + } else { + + /* + * Something went wrong during TX, idle_tx_rx() returns in IDLE + * state in this case. + * Turn on RX again unless we turn off anyway + */ + + ret = RADIO_TX_ERR; + if(!was_off) { +#ifdef RF_FORCE_CALIBRATION + rf_flags |= RF_FORCE_CALIBRATION; +#endif + idle_calibrate_rx(); + } + } + + /* Release SPI here because "off()" won't work if SPI is locked! */ + RELEASE_SPI(); + + if(was_off) { + off(); + } + + /* TX completed */ + rf_flags &= ~RF_TX_ACTIVE; + + return ret; + +} +/*---------------------------------------------------------------------------*/ +/* Prepare & transmit a packet. */ +static int +send(const void *payload, unsigned short payload_len) +{ + + int ret; + + INFO("RF: Send (%d)\n", payload_len); + + /* payload_len checked within prepare() */ + if((ret = prepare(payload, payload_len)) == RADIO_TX_OK) { + ret = transmit(payload_len); + } + + return ret; + +} +/*---------------------------------------------------------------------------*/ +/* Read a received packet into a buffer. */ +static int +read(void *buf, unsigned short buf_len) +{ + + int len = 0; + + #if CC1200_SNIFFER + uint8_t i; + #endif + + if(rx_pkt_len > 0) { + + int8_t rssi = rx_pkt[rx_pkt_len - 2]; + /* CRC is already checked */ + uint8_t crc_lqi = rx_pkt[rx_pkt_len - 1]; + + len = rx_pkt_len - APPENDIX_LEN; + + if(len > buf_len) { + + ERROR("RF: Failed to read packet (too big)!\n"); + + } else { + + INFO("RF: Read (%d bytes, %d dBm)\n", len, rssi); + + memcpy((void *)buf, (const void *)rx_pkt, len); + + /* Release rx_pkt */ + rx_pkt_len = 0; + + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi); + /* Mask out CRC bit */ + packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, + crc_lqi & ~(1 << 7)); + + + #if CC1200_SNIFFER + write_byte(magic[0]); + write_byte(magic[1]); + write_byte(magic[2]); + write_byte(magic[3]); + write_byte(len + 2); + for(i = 0; i < len; ++i) { + write_byte(((unsigned char *)(buf))[i]); + } + write_byte(rssi); + write_byte(crc_lqi); + flush(); + #endif + + RIMESTATS_ADD(llrx); + } + + } + + return len; + +} +/*---------------------------------------------------------------------------*/ +/* + * Perform a Clear-Channel Assessment (CCA) to find out if there is a + * packet in the air or not. + */ +static int +channel_clear(void) +{ + + uint8_t cca, was_off = 0; + + if(SPI_IS_LOCKED()) { + /* Probably locked in rx interrupt. Return "channel occupied" */ + return 0; + } + + if(!(rf_flags & RF_ON)) { + /* We are off */ + was_off = 1; + on(); + } + + LOCK_SPI(); + + RF_ASSERT(state() == STATE_RX); + + /* + * At this point we should be in RX. If GPIO0 is set, we are currently + * receiving a packet, no need to check the RSSI. Or is there any situation + * when we want access the channel even if we are currently receiving a + * packet??? + */ + + if(cc1200_arch_gpio0_read_pin() == 1) { + /* Channel occupied */ + INFO("RF: CCA (0)\n"); + cca = 0; + } else { + + uint8_t rssi0; + + /* Update CCA threshold */ + if(new_cca_threshold != cca_threshold) { + update_cca_threshold(new_cca_threshold); + } + + /* Wait for CARRIER_SENSE_VALID signal */ + BUSYWAIT_UNTIL(((rssi0 = single_read(CC1200_RSSI0)) + & CC1200_CARRIER_SENSE_VALID), + RTIMER_SECOND / 100); + RF_ASSERT(rssi0 & CC1200_CARRIER_SENSE_VALID); + + if(rssi0 & CC1200_CARRIER_SENSE) { + /* Channel occupied */ + INFO("RF: CCA (0)\n"); + cca = 0; + } else { + /* Channel clear */ + INFO("RF: CCA (1)\n"); + cca = 1; + } + + } + + RELEASE_SPI(); + + if(was_off) { + off(); + } + + return cca; + +} +/*---------------------------------------------------------------------------*/ +/* + * Check if the radio driver is currently receiving a packet. + * + * nullrdc uses this function + * - to detect a collision before transmit() + * - to detect an incoming ACK + */ +static int +receiving_packet(void) +{ + + int ret = 0; + + if((rf_flags & (RF_ON | RF_TX_ACTIVE)) == RF_ON) { + /* We are on and not in TX */ + if((cc1200_arch_gpio0_read_pin() == 1) || (rx_pkt_len != 0)) { + + /* + * SYNC word found or packet just received. Changing the criteria + * for this event might make it necessary to review the MAC timing + * parameters! Instead of (or in addition to) using GPIO0 we could also + * read out MODEM_STATUS1 (e.g. PQT reached), but this would not change + * the situation at least for nullrdc as it uses two "blocking" timers + * (does not perform polling...). Therefore the overall timing + * of the ACK handling wouldn't change. It would just allow to detect an + * incoming packet a little bit earlier and help us with respect to + * collision avoidance (why not use channel_clear() in nullrdc + * at this point?). + */ + + ret = 1; + + } + } + + INFO("RF: Receiving (%d)\n", ret); + return ret; + +} +/*---------------------------------------------------------------------------*/ +/* Check if the radio driver has just received a packet. */ +static int +pending_packet(void) +{ + + INFO("RF: Pending (%d)\n", ((rx_pkt_len != 0) ? 1 : 0)); + return (rx_pkt_len != 0) ? 1 : 0; + +} +/*---------------------------------------------------------------------------*/ +/* Turn the radio on. */ +static int +on(void) +{ + + INFO("RF: On\n"); + + /* Don't turn on if we are on already */ + if(!(rf_flags & RF_ON)) { + + if(SPI_IS_LOCKED()) { + return 0; + } + + LOCK_SPI(); + + /* Wake-up procedure. Wait for GPIO0 to de-assert (CHIP_RDYn) */ + cc1200_arch_spi_select(); + BUSYWAIT_UNTIL((cc1200_arch_gpio0_read_pin() == 0), + RTIMER_SECOND / 100); + RF_ASSERT((cc1200_arch_gpio0_read_pin() == 0)); + cc1200_arch_spi_deselect(); + + rf_flags |= RF_ON; + + /* Radio is IDLE now, re-configure GPIO0 (modified inside off()) */ + single_write(CC1200_IOCFG0, GPIO0_IOCFG); + + /* Turn on RX */ + idle_calibrate_rx(); + + RELEASE_SPI(); + +#if CC1200_USE_RX_WATCHDOG + PROCESS_CONTEXT_BEGIN(&cc1200_process); + etimer_set(&et, CLOCK_SECOND); + PROCESS_CONTEXT_END(&cc1200_process); +#endif /* #if CC1200_USE_RX_WATCHDOG */ + + } else { + INFO("RF: Already on\n"); + } + + return 1; + +} +/*---------------------------------------------------------------------------*/ +/* Turn the radio off. */ +static int +off(void) +{ + + INFO("RF: Off\n"); + + /* Don't turn off if we are off already */ + if(rf_flags & RF_ON) { + + if(SPI_IS_LOCKED()) { + return 0; + } + + LOCK_SPI(); + + idle(); + + /* + * As we use GPIO as CHIP_RDYn signal on wake-up / on(), + * we re-configure it for CHIP_RDYn. + */ + single_write(CC1200_IOCFG0, CC1200_IOCFG_RXFIFO_CHIP_RDY_N); + + /* Say goodbye ... */ + strobe(CC1200_SPWD); + + /* Clear all but the initialized flag */ + rf_flags = RF_INITIALIZED; + + RELEASE_SPI(); + +#if CC1200_USE_RX_WATCHDOG + etimer_stop(&et); +#endif /* #if CC1200_USE_RX_WATCHDOG */ + + } else { + INFO("RF: Already off\n"); + } + + return 1; + +} +/*---------------------------------------------------------------------------*/ +/* Get a radio parameter value. */ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + + if(!value) { + return RADIO_RESULT_INVALID_VALUE; + } + + switch(param) { + case RADIO_PARAM_POWER_MODE: + + if(rf_flags & RF_ON) { + *value = (radio_value_t)RADIO_POWER_MODE_ON; + } else { + *value = (radio_value_t)RADIO_POWER_MODE_OFF; + } + return RADIO_RESULT_OK; + + case RADIO_PARAM_CHANNEL: + + *value = (radio_value_t)rf_channel; + return RADIO_RESULT_OK; + + case RADIO_PARAM_PAN_ID: + case RADIO_PARAM_16BIT_ADDR: + + return RADIO_RESULT_NOT_SUPPORTED; + + case RADIO_PARAM_RX_MODE: + + *value = (radio_value_t)rx_mode_value; + return RADIO_RESULT_OK; + + case RADIO_PARAM_TX_MODE: + + *value = (radio_value_t)tx_mode_value; + return RADIO_RESULT_OK; + + case RADIO_PARAM_TXPOWER: + + *value = (radio_value_t)txpower; + return RADIO_RESULT_OK; + + case RADIO_PARAM_CCA_THRESHOLD: + + *value = (radio_value_t)cca_threshold; + return RADIO_RESULT_OK; + + case RADIO_PARAM_RSSI: + case RADIO_PARAM_64BIT_ADDR: + + return RADIO_RESULT_NOT_SUPPORTED; + + case RADIO_CONST_CHANNEL_MIN: + + *value = (radio_value_t)CC1200_RF_CFG.min_channel; + return RADIO_RESULT_OK; + + case RADIO_CONST_CHANNEL_MAX: + + *value = (radio_value_t)CC1200_RF_CFG.max_channel; + return RADIO_RESULT_OK; + + case RADIO_CONST_TXPOWER_MIN: + + *value = (radio_value_t)CC1200_CONST_TX_POWER_MIN; + return RADIO_RESULT_OK; + + case RADIO_CONST_TXPOWER_MAX: + + *value = (radio_value_t)CC1200_RF_CFG.max_txpower; + return RADIO_RESULT_OK; + + default: + + return RADIO_RESULT_NOT_SUPPORTED; + + } + +} +/*---------------------------------------------------------------------------*/ +/* Set a radio parameter value. */ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + + switch(param) { + case RADIO_PARAM_POWER_MODE: + + if(value == RADIO_POWER_MODE_ON) { + on(); + return RADIO_RESULT_OK; + } + + if(value == RADIO_POWER_MODE_OFF) { + off(); + return RADIO_RESULT_OK; + } + + return RADIO_RESULT_INVALID_VALUE; + + case RADIO_PARAM_CHANNEL: + + if(set_channel(value) == CHANNEL_OUT_OF_LIMITS) { + return RADIO_RESULT_INVALID_VALUE; + } + + /* + * We always return OK here even if the channel update was + * postponed. rf_channel is NOT updated in this case until + * the channel update was performed. So reading back + * the channel using get_value() might return the "old" channel + * until the channel was actually changed + */ + + return RADIO_RESULT_OK; + + case RADIO_PARAM_PAN_ID: + case RADIO_PARAM_16BIT_ADDR: + + return RADIO_RESULT_NOT_SUPPORTED; + + case RADIO_PARAM_RX_MODE: + + rx_mode_value = value; + return RADIO_RESULT_OK; + + case RADIO_PARAM_TX_MODE: + + tx_mode_value = value; + return RADIO_RESULT_OK; + + case RADIO_PARAM_TXPOWER: + + if(value > (radio_value_t)CC1200_RF_CFG.max_txpower) { + value = (radio_value_t)CC1200_RF_CFG.max_txpower; + } + + if(value < (radio_value_t)CC1200_CONST_TX_POWER_MIN) { + value = (radio_value_t)CC1200_CONST_TX_POWER_MIN; + } + + /* We update the output power as soon as we transmit the next packet */ + new_txpower = (int8_t)value; + return RADIO_RESULT_OK; + + case RADIO_PARAM_CCA_THRESHOLD: + + if(value > (radio_value_t)CC1200_CONST_CCA_THRESHOLD_MAX) { + value = (radio_value_t)CC1200_CONST_CCA_THRESHOLD_MAX; + } + + if(value < (radio_value_t)CC1200_CONST_CCA_THRESHOLD_MIN) { + value = (radio_value_t)CC1200_CONST_CCA_THRESHOLD_MIN; + } + + /* When to update the threshold? Let's do it in channel_clear() ... */ + new_cca_threshold = (int8_t)value; + return RADIO_RESULT_OK; + + case RADIO_PARAM_RSSI: + case RADIO_PARAM_64BIT_ADDR: + + default: + + return RADIO_RESULT_NOT_SUPPORTED; + + } + +} +/*---------------------------------------------------------------------------*/ +/* Get a radio parameter object. */ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + + return RADIO_RESULT_NOT_SUPPORTED; + +} +/*---------------------------------------------------------------------------*/ +/* Set a radio parameter object. */ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + + return RADIO_RESULT_NOT_SUPPORTED; + +} +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/* + * CC1200 low level functions + */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +/* Send a command strobe. */ +static uint8_t +strobe(uint8_t strobe) +{ + + uint8_t ret; + + cc1200_arch_spi_select(); + ret = cc1200_arch_spi_rw_byte(strobe); + cc1200_arch_spi_deselect(); + + return ret; + +} +/*---------------------------------------------------------------------------*/ +/* Reset CC1200. */ +static void +reset(void) +{ + + cc1200_arch_spi_select(); + cc1200_arch_spi_rw_byte(CC1200_SRES); + /* + * Here we should wait for SO to go low again. + * As we don't have access to this pin we just wait for 100µs. + */ + clock_delay(100); + cc1200_arch_spi_deselect(); + +} +/*---------------------------------------------------------------------------*/ +/* Write a single byte to the specified address. */ +static uint8_t +single_write(uint16_t addr, uint8_t val) +{ + + uint8_t ret; + + cc1200_arch_spi_select(); + if(CC1200_IS_EXTENDED_ADDR(addr)) { + cc1200_arch_spi_rw_byte(CC1200_EXTENDED_WRITE_CMD); + cc1200_arch_spi_rw_byte((uint8_t)addr); + } else { + cc1200_arch_spi_rw_byte(addr | CC1200_WRITE_BIT); + } + ret = cc1200_arch_spi_rw_byte(val); + cc1200_arch_spi_deselect(); + + return ret; + +} +/*---------------------------------------------------------------------------*/ +/* Read a single byte from the specified address. */ +static uint8_t +single_read(uint16_t addr) +{ + + uint8_t ret; + + cc1200_arch_spi_select(); + if(CC1200_IS_EXTENDED_ADDR(addr)) { + cc1200_arch_spi_rw_byte(CC1200_EXTENDED_READ_CMD); + cc1200_arch_spi_rw_byte((uint8_t)addr); + } else { + cc1200_arch_spi_rw_byte(addr | CC1200_READ_BIT); + } + ret = cc1200_arch_spi_rw_byte(0); + cc1200_arch_spi_deselect(); + + return ret; + +} +/*---------------------------------------------------------------------------*/ +/* Write a burst of bytes starting at the specified address. */ +static void +burst_write(uint16_t addr, const uint8_t *data, uint8_t data_len) +{ + + cc1200_arch_spi_select(); + if(CC1200_IS_EXTENDED_ADDR(addr)) { + cc1200_arch_spi_rw_byte(CC1200_EXTENDED_BURST_WRITE_CMD); + cc1200_arch_spi_rw_byte((uint8_t)addr); + } else { + cc1200_arch_spi_rw_byte(addr | CC1200_WRITE_BIT | CC1200_BURST_BIT); + } + cc1200_arch_spi_rw(NULL, data, data_len); + cc1200_arch_spi_deselect(); + +} +/*---------------------------------------------------------------------------*/ +/* Read a burst of bytes starting at the specified address. */ +static void +burst_read(uint16_t addr, uint8_t *data, uint8_t data_len) +{ + + cc1200_arch_spi_select(); + if(CC1200_IS_EXTENDED_ADDR(addr)) { + cc1200_arch_spi_rw_byte(CC1200_EXTENDED_BURST_READ_CMD); + cc1200_arch_spi_rw_byte((uint8_t)addr); + } else { + cc1200_arch_spi_rw_byte(addr | CC1200_READ_BIT | CC1200_BURST_BIT); + } + cc1200_arch_spi_rw(data, NULL, data_len); + cc1200_arch_spi_deselect(); + +} +/*---------------------------------------------------------------------------*/ +/* Write a list of register settings. */ +static void +write_reg_settings(const registerSetting_t *reg_settings, + uint16_t sizeof_reg_settings) +{ + + int i = sizeof_reg_settings / sizeof(registerSetting_t); + + if(reg_settings != NULL) { + while(i--) { + single_write(reg_settings->addr, + reg_settings->val); + reg_settings++; + } + } + +} +/*---------------------------------------------------------------------------*/ +/* Configure the radio (write basic configuration). */ +static void +configure(void) +{ + + uint8_t reg; +#if CC1200_RF_TESTMODE + uint32_t freq; +#endif + + /* + * As we only write registers which are different from the chip's reset + * state, let's assure that the chip is in a clean state + */ + reset(); + + /* Write the configuration as exported from SmartRF Studio */ + write_reg_settings(CC1200_RF_CFG.register_settings, + CC1200_RF_CFG.size_of_register_settings); + + /* Write frequency offset */ +#if CC1200_FREQ_OFFSET + /* MSB */ + single_write(CC1200_FREQOFF1, (uint8_t)(CC1200_FREQ_OFFSET >> 8)); + /* LSB */ + single_write(CC1200_FREQOFF0, (uint8_t)(CC1200_FREQ_OFFSET)); +#endif + + /* RSSI offset */ + single_write(CC1200_AGC_GAIN_ADJUST, (int8_t)CC1200_RSSI_OFFSET); + + /*************************************************************************** + * RF test modes needed during hardware development + **************************************************************************/ + +#if (CC1200_RF_TESTMODE == 1) || (CC1200_RF_TESTMODE == 2) + + strobe(CC1200_SFTX); + single_write(CC1200_TXFIRST, 0); + single_write(CC1200_TXLAST, 0xFF); + update_txpower(CC1200_CONST_TX_POWER_MAX); + single_write(CC1200_PKT_CFG2, 0x02); + freq = calculate_freq(CC1200_DEFAULT_CHANNEL - CC1200_RF_CFG.min_channel); + single_write(CC1200_FREQ0, ((uint8_t *)&freq)[0]); + single_write(CC1200_FREQ1, ((uint8_t *)&freq)[1]); + single_write(CC1200_FREQ2, ((uint8_t *)&freq)[2]); + + printf("RF: Freq0 0x%02x\n", ((uint8_t *)&freq)[0]); + printf("RF: Freq1 0x%02x\n", ((uint8_t *)&freq)[1]); + printf("RF: Freq2 0x%02x\n", ((uint8_t *)&freq)[2]); + +#if (CC1200_RF_TESTMODE == 1) + single_write(CC1200_SYNC_CFG1, 0xE8); + single_write(CC1200_PREAMBLE_CFG1, 0x00); + single_write(CC1200_MDMCFG1, 0x46); + single_write(CC1200_PKT_CFG0, 0x40); + single_write(CC1200_FS_DIG1, 0x07); + single_write(CC1200_FS_DIG0, 0xAA); + single_write(CC1200_FS_DVC1, 0xFF); + single_write(CC1200_FS_DVC0, 0x17); +#endif + +#if (CC1200_RF_TESTMODE == 2) + single_write(CC1200_SYNC_CFG1, 0xE8); + single_write(CC1200_PREAMBLE_CFG1, 0x00); + single_write(CC1200_MDMCFG1, 0x06); + single_write(CC1200_PA_CFG1, 0x3F); + single_write(CC1200_MDMCFG2, 0x03); + single_write(CC1200_FS_DIG1, 0x07); + single_write(CC1200_FS_DIG0, 0xAA); + single_write(CC1200_FS_DVC0, 0x17); + single_write(CC1200_SERIAL_STATUS, 0x08); +#endif + + strobe(CC1200_STX); + + while(1) { +#if (CC1200_RF_TESTMODE == 1) + watchdog_periodic(); + BUSYWAIT_UNTIL(0, RTIMER_SECOND / 10); + leds_off(LEDS_YELLOW); + leds_on(LEDS_RED); + watchdog_periodic(); + BUSYWAIT_UNTIL(0, RTIMER_SECOND / 10); + leds_off(LEDS_RED); + leds_on(LEDS_YELLOW); +#else + watchdog_periodic(); + BUSYWAIT_UNTIL(0, RTIMER_SECOND / 10); + leds_off(LEDS_GREEN); + leds_on(LEDS_RED); + watchdog_periodic(); + BUSYWAIT_UNTIL(0, RTIMER_SECOND / 10); + leds_off(LEDS_RED); + leds_on(LEDS_GREEN); +#endif + } + +#elif (CC1200_RF_TESTMODE == 3) + + /* CS on GPIO3 */ + single_write(CC1200_IOCFG3, CC1200_IOCFG_CARRIER_SENSE); + single_write(CC1200_IOCFG2, CC1200_IOCFG_SERIAL_CLK); + single_write(CC1200_IOCFG0, CC1200_IOCFG_SERIAL_RX); + update_cca_threshold(CC1200_RF_CFG.cca_threshold); + freq = calculate_freq(CC1200_DEFAULT_CHANNEL - CC1200_RF_CFG.min_channel); + single_write(CC1200_FREQ0, ((uint8_t *)&freq)[0]); + single_write(CC1200_FREQ1, ((uint8_t *)&freq)[1]); + single_write(CC1200_FREQ2, ((uint8_t *)&freq)[2]); + strobe(CC1200_SRX); + + while(1) { + + watchdog_periodic(); + BUSYWAIT_UNTIL(0, RTIMER_SECOND / 10); + leds_off(LEDS_GREEN); + leds_on(LEDS_YELLOW); + watchdog_periodic(); + BUSYWAIT_UNTIL(0, RTIMER_SECOND / 10); + leds_off(LEDS_YELLOW); + leds_on(LEDS_GREEN); + clock_delay_usec(1000); + + /* CS on GPIO3 */ + if(cc1200_arch_gpio3_read_pin() == 1) { + leds_on(LEDS_RED); + } else { + leds_off(LEDS_RED); + } + + } + +#endif /* #if CC1200_RF_TESTMODE == ... */ + + /*************************************************************************** + * Set the stuff we need for this driver to work. Don't touch! + **************************************************************************/ + + /* GPIOx configuration */ + single_write(CC1200_IOCFG3, GPIO3_IOCFG); + single_write(CC1200_IOCFG2, GPIO2_IOCFG); + single_write(CC1200_IOCFG0, GPIO0_IOCFG); + + reg = single_read(CC1200_SETTLING_CFG); + /* + * Turn of auto calibration. This gives us better control + * over the timing (RX/TX & TX /RX turnaround!). We calibrate manually: + * - Upon wake-up (on()) + * - Before going to TX (transmit()) + * - When setting an new channel (set_channel()) + */ + reg &= ~(3 << 3); +#if CC1200_AUTOCAL + /* We calibrate when going from idle to RX or TX */ + reg |= (1 << 3); +#endif + single_write(CC1200_SETTLING_CFG, reg); + + /* Configure RXOFF_MODE */ + reg = single_read(CC1200_RFEND_CFG1); + reg &= ~(3 << 4); /* RXOFF_MODE = IDLE */ +#if RXOFF_MODE_RX + reg |= (3 << 4); /* RXOFF_MODE = RX */ +#endif + reg |= 0x0F; /* Disable RX timeout */ + single_write(CC1200_RFEND_CFG1, reg); + + /* Configure TXOFF_MODE */ + reg = single_read(CC1200_RFEND_CFG0); + reg &= ~(3 << 4); /* TXOFF_MODE = IDLE */ +#if TXOFF_MODE_RX + reg |= (3 << 4); /* TXOFF_MODE = RX */ +#endif + single_write(CC1200_RFEND_CFG0, reg); + + /* + * CCA Mode 0: Always give clear channel indication. + * CCA is done "by hand". Keep in mind: automatic CCA would also + * affect the transmission of the ACK and is not implemented yet! + */ +#if CC1200_802154G + single_write(CC1200_PKT_CFG2, (1 << 5)); +#else + single_write(CC1200_PKT_CFG2, 0x00); +#endif + + /* Configure appendix */ + reg = single_read(CC1200_PKT_CFG1); +#if APPEND_STATUS + reg |= (1 << 0); +#else + reg &= ~(1 << 0); +#endif + single_write(CC1200_PKT_CFG1, reg); + + /* Variable packet length mode */ + reg = single_read(CC1200_PKT_CFG0); + reg &= ~(3 << 5); + reg |= (1 << 5); + single_write(CC1200_PKT_CFG0, reg); + +#ifdef FIFO_THRESHOLD + /* FIFO threshold */ + single_write(CC1200_FIFO_CFG, FIFO_THRESHOLD); +#endif + +} +/*---------------------------------------------------------------------------*/ +/* Return the radio's state. */ +static uint8_t +state(void) +{ + +#if STATE_USES_MARC_STATE + return single_read(CC1200_MARCSTATE) & 0x1f; +#else + return strobe(CC1200_SNOP) & 0x70; +#endif + +} +/*---------------------------------------------------------------------------*/ +#if !CC1200_AUTOCAL +/* Perform manual calibration. */ +static void +calibrate(void) +{ + +#ifdef RF_FORCE_CALIBRATION + if (!(rf_flags & RF_FORCE_CALIBRATION) + && ((clock_seconds() - cal_timer) < CC1200_CAL_TIMEOUT_SECONDS)) { + /* Timeout not reached, defer calibration... */ + return; + } + rf_flags &= ~RF_FORCE_CALIBRATION; +#endif + + INFO("RF: Calibrate\n"); + + strobe(CC1200_SCAL); + BUSYWAIT_UNTIL_STATE(STATE_CALIBRATE, RTIMER_SECOND / 100); + BUSYWAIT_UNTIL_STATE(STATE_IDLE, RTIMER_SECOND / 100); + +#if CC1200_CAL_TIMEOUT_SECONDS + cal_timer = clock_seconds(); +#endif + +} +#endif +/*---------------------------------------------------------------------------*/ +/* Enter IDLE state. */ +static void +idle(void) +{ + + uint8_t s; + + DISABLE_GPIO_INTERRUPTS(); + + TX_LEDS_OFF(); + RX_LEDS_OFF(); + + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); + + s = state(); + + if(s == STATE_IDLE) { + return; + } else if(s == STATE_RX_FIFO_ERR) { + WARNING("RF: RX FIFO error!\n"); + strobe(CC1200_SFRX); + } else if(s == STATE_TX_FIFO_ERR) { + WARNING("RF: TX FIFO error!\n"); + strobe(CC1200_SFTX); + } + + strobe(CC1200_SIDLE); + BUSYWAIT_UNTIL_STATE(STATE_IDLE, RTIMER_SECOND / 100); + +} /* idle(), 21.05.2015 */ +/*---------------------------------------------------------------------------*/ +/* Enter RX state. */ +static void +idle_calibrate_rx(void) +{ + + RF_ASSERT(state() == STATE_IDLE); + +#if !CC1200_AUTOCAL + calibrate(); +#endif + + rf_flags &= ~RF_RX_PROCESSING_PKT; + strobe(CC1200_SFRX); + strobe(CC1200_SRX); + BUSYWAIT_UNTIL_STATE(STATE_RX, RTIMER_SECOND / 100); + + ENABLE_GPIO_INTERRUPTS(); + + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + +} +/*---------------------------------------------------------------------------*/ +/* Restart RX from within RX interrupt. */ +static void +rx_rx(void) +{ + + uint8_t s = state(); + + if(s == STATE_IDLE) { + /* Proceed to rx */ + } else if(s == STATE_RX_FIFO_ERR) { + WARNING("RF: RX FIFO error!\n"); + strobe(CC1200_SFRX); + } else if(s == STATE_TX_FIFO_ERR) { + WARNING("RF: TX FIFO error!\n"); + strobe(CC1200_SFTX); + } else { + strobe(CC1200_SIDLE); + BUSYWAIT_UNTIL_STATE(STATE_IDLE, + RTIMER_SECOND / 100); + } + + RX_LEDS_OFF(); + rf_flags &= ~RF_RX_PROCESSING_PKT; + + /* Clear pending GPIO interrupts */ + ENABLE_GPIO_INTERRUPTS(); + + strobe(CC1200_SFRX); + strobe(CC1200_SRX); + BUSYWAIT_UNTIL_STATE(STATE_RX, RTIMER_SECOND / 100); + +} +/*---------------------------------------------------------------------------*/ +/* Fill TX FIFO, start TX and wait for TX to complete (blocking!). */ +static int +idle_tx_rx(const uint8_t *payload, uint16_t payload_len) +{ + +#if (CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN)) + uint16_t bytes_left_to_write; + uint8_t to_write; + const uint8_t *p; +#endif + +#if CC1200_802154G + /* Prepare PHR for 802.15.4g frames */ + struct { + uint8_t phra; + uint8_t phrb; + } phr; +#if CC1200_802154G_CRC16 + payload_len += 2; +#else + payload_len += 4; +#endif + /* Frame length */ + phr.phrb = (uint8_t)(payload_len & 0x00FF); + phr.phra = (uint8_t)((payload_len >> 8) & 0x0007); +#if CC1200_802154G_WHITENING + /* Enable Whitening */ + phr.phra |= (1 << 3); +#endif /* #if CC1200_802154G_WHITENING */ +#if CC1200_802154G_CRC16 + /* FCS type 1, 2 Byte CRC */ + phr.phra |= (1 << 4); +#endif /* #if CC1200_802154G_CRC16 */ +#endif /* #if CC1200_802154G */ + + /* Prepare for RX */ + rf_flags &= ~RF_RX_PROCESSING_PKT; + strobe(CC1200_SFRX); + + /* Flush TX FIFO */ + strobe(CC1200_SFTX); + +#if USE_SFSTXON + /* + * Enable synthesizer. Saves us a few µs especially if it takes + * long enough to fill the FIFO. This strobe must not be + * send before SFTX! + */ + strobe(CC1200_SFSTXON); +#endif + + /* Configure GPIO0 to detect TX state */ + single_write(CC1200_IOCFG0, CC1200_IOCFG_MARC_2PIN_STATUS_0); + +#if (CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN)) + /* + * We already checked that GPIO2 is used if + * CC1200_MAX_PAYLOAD_LEN > 127 / 126 in the header of this file + */ + single_write(CC1200_IOCFG2, CC1200_IOCFG_TXFIFO_THR); +#endif + +#if CC1200_802154G + /* Write PHR */ + burst_write(CC1200_TXFIFO, (uint8_t *)&phr, PHR_LEN); +#else + /* Write length byte */ + burst_write(CC1200_TXFIFO, (uint8_t *)&payload_len, PHR_LEN); +#endif /* #if CC1200_802154G */ + + /* + * Fill FIFO with data. If SPI is slow it might make sense + * to divide this process into several chunks. + * The best solution would be to perform TX FIFO refill + * using an interrupt, but we are blocking here (= in TX) anyway... + */ + +#if (CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN)) + to_write = MIN(payload_len, (CC1200_FIFO_SIZE - PHR_LEN)); + burst_write(CC1200_TXFIFO, payload, to_write); + bytes_left_to_write = payload_len - to_write; + p = payload + to_write; +#else + burst_write(CC1200_TXFIFO, payload, payload_len); +#endif + +#if USE_SFSTXON + /* Wait for synthesizer to be ready */ + BUSYWAIT_UNTIL_STATE(STATE_FSTXON, RTIMER_SECOND / 100); +#endif + + /* Start TX */ + strobe(CC1200_STX); + + /* Wait for TX to start. */ + BUSYWAIT_UNTIL((cc1200_arch_gpio0_read_pin() == 1), RTIMER_SECOND / 100); + + /* Turned off at the latest in idle() */ + TX_LEDS_ON(); + + /* Turned off at the latest in idle() */ + ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); + + if((cc1200_arch_gpio0_read_pin() == 0) && + (single_read(CC1200_NUM_TXBYTES) != 0)) { + + /* + * TX didn't start in time. We also check NUM_TXBYES + * in case we missed the rising edge of the GPIO signal + */ + + ERROR("RF: TX doesn't start!\n"); +#if (CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN)) + single_write(CC1200_IOCFG2, GPIO2_IOCFG); +#endif + idle(); + + /* Re-configure GPIO0 */ + single_write(CC1200_IOCFG0, GPIO0_IOCFG); + + return RADIO_TX_ERR; + + } + +#if (CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN)) + if(bytes_left_to_write != 0) { + rtimer_clock_t t0; + uint8_t s; + t0 = RTIMER_NOW(); + do { + if((bytes_left_to_write != 0) && + (cc1200_arch_gpio2_read_pin() == 0)) { + /* TX TIFO is drained below FIFO_THRESHOLD. Re-fill... */ + to_write = MIN(bytes_left_to_write, FIFO_THRESHOLD); + burst_write(CC1200_TXFIFO, p, to_write); + bytes_left_to_write -= to_write; + p += to_write; + t0 += CC1200_RF_CFG.tx_pkt_lifetime; + } + } while((cc1200_arch_gpio0_read_pin() == 1) && + RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CC1200_RF_CFG.tx_pkt_lifetime)); + + /* + * At this point we either left TX or a timeout occurred. If all went + * well, we are in RX (or at least settling) now. + * If we didn't manage to refill the TX FIFO, an underflow might + * have occur-ed - the radio might be still in TX here! + */ + + s = state(); + if((s != STATE_RX) && (s != STATE_SETTLING)) { + + /* + * Something bad happened. Wait for radio to enter a + * stable state (in case of an error we are in TX here) + */ + + INFO("RF: TX failure!\n"); + BUSYWAIT_UNTIL((state() != STATE_TX), RTIMER_SECOND / 100); + /* Re-configure GPIO2 */ + single_write(CC1200_IOCFG2, GPIO2_IOCFG); + idle(); + + /* Re-configure GPIO0 */ + single_write(CC1200_IOCFG0, GPIO0_IOCFG); + + return RADIO_TX_ERR; + + } + + } else { + /* Wait for TX to complete */ + BUSYWAIT_UNTIL((cc1200_arch_gpio0_read_pin() == 0), + CC1200_RF_CFG.tx_pkt_lifetime); + } +#else + /* Wait for TX to complete */ + BUSYWAIT_UNTIL((cc1200_arch_gpio0_read_pin() == 0), + CC1200_RF_CFG.tx_pkt_lifetime); +#endif + + if(cc1200_arch_gpio0_read_pin() == 1) { + /* TX takes to long - abort */ + ERROR("RF: TX takes to long!\n"); +#if (CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN)) + /* Re-configure GPIO2 */ + single_write(CC1200_IOCFG2, GPIO2_IOCFG); +#endif + idle(); + + /* Re-configure GPIO0 */ + single_write(CC1200_IOCFG0, GPIO0_IOCFG); + + return RADIO_TX_ERR; + + } + +#if (CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN)) + /* Re-configure GPIO2 */ + single_write(CC1200_IOCFG2, GPIO2_IOCFG); +#endif + + /* Re-configure GPIO0 */ + single_write(CC1200_IOCFG0, GPIO0_IOCFG); + + TX_LEDS_OFF(); + + ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + + return RADIO_TX_OK; + +} +/*---------------------------------------------------------------------------*/ +/* Update TX power */ +static void +update_txpower(int8_t txpower_dbm) +{ + + uint8_t reg = single_read(CC1200_PA_CFG1); + + reg &= ~0x3F; + /* Up to now we don't handle the special power levels PA_POWER_RAMP < 3 */ + reg |= ((((txpower_dbm + 18) * 2) - 1) & 0x3F); + single_write(CC1200_PA_CFG1, reg); + + txpower = txpower_dbm; + +} +/*---------------------------------------------------------------------------*/ +/* Update CCA threshold */ +static void +update_cca_threshold(int8_t threshold_dbm) +{ + + single_write(CC1200_AGC_CS_THR, (uint8_t)threshold_dbm); + cca_threshold = threshold_dbm; + +} +/*---------------------------------------------------------------------------*/ +/* Calculate FREQ register from channel */ +static uint32_t +calculate_freq(uint8_t channel) +{ + + uint32_t freq; + + freq = CC1200_RF_CFG.chan_center_freq0 + channel * CC1200_RF_CFG.chan_spacing; + freq *= FREQ_MULTIPLIER; + freq /= FREQ_DIVIDER; + + return freq; + +} +/*---------------------------------------------------------------------------*/ +/* Update rf channel if possible, else postpone it (->pollhandler) */ +static int +set_channel(uint8_t channel) +{ + + uint8_t was_off = 0; + uint32_t freq; + +#if 0 + /* + * We explicitly allow a channel update even if the channel does not change. + * This feature can be used to manually force a calibration. + */ + if(channel == rf_channel) { + return rf_channel; + } +#endif + + if(channel < CC1200_RF_CFG.min_channel || + channel > CC1200_RF_CFG.max_channel) { + /* Invalid channel */ + return CHANNEL_OUT_OF_LIMITS; + } + + if(SPI_IS_LOCKED() || (rf_flags & RF_TX_ACTIVE) || receiving_packet()) { + + /* We are busy, postpone channel update */ + + new_rf_channel = channel; + rf_flags |= RF_UPDATE_CHANNEL; + process_poll(&cc1200_process); + INFO("RF: Channel update postponed\n"); + + return CHANNEL_UPDATE_POSTPONED; + + } + rf_flags &= ~RF_UPDATE_CHANNEL; + + INFO("RF: Channel update (%d)\n", channel); + + if(!(rf_flags & RF_ON)) { + was_off = 1; + on(); + } + + LOCK_SPI(); + + idle(); + + freq = calculate_freq(channel - CC1200_RF_CFG.min_channel); + single_write(CC1200_FREQ0, ((uint8_t *)&freq)[0]); + single_write(CC1200_FREQ1, ((uint8_t *)&freq)[1]); + single_write(CC1200_FREQ2, ((uint8_t *)&freq)[2]); + + rf_channel = channel; + + /* Turn on RX again unless we turn off anyway */ + if(!was_off) { +#ifdef RF_FORCE_CALIBRATION + rf_flags |= RF_FORCE_CALIBRATION; +#endif + idle_calibrate_rx(); + } + + RELEASE_SPI(); + + if(was_off) { + off(); + } + + return CHANNEL_UPDATE_SUCCEEDED; + +} +/*---------------------------------------------------------------------------*/ +/* Check broadcast address. */ +#if !CC1200_SNIFFER +static int +is_broadcast_addr(uint8_t mode, uint8_t *addr) +{ + + int i = mode == FRAME802154_SHORTADDRMODE ? 2 : 8; + + while(i-- > 0) { + if(addr[i] != 0xff) { + return 0; + } + } + + return 1; + +} +#endif /* CC12100_SNIFFER */ +/*---------------------------------------------------------------------------*/ +/* Validate address and send ACK if requested. */ +#if CC1200_SNIFFER +static int +addr_check_auto_ack(uint8_t *frame, uint16_t frame_len) +{ + + frame802154_t info154; + + if(frame802154_parse(frame, frame_len, &info154) != 0) { + + /* We accept all 802.15.4 frames ... */ + return ADDR_CHECK_OK; + + } else { + + /* .. and discard others. */ + return INVALID_FRAME; + + } + +} +#else /* CC1200_SNIFFER */ +static int +addr_check_auto_ack(uint8_t *frame, uint16_t frame_len) +{ + + frame802154_t info154; + + if(frame802154_parse(frame, frame_len, &info154) != 0) { + + /* We received a valid 802.15.4 frame */ + + if(!(rx_mode_value & RADIO_RX_MODE_ADDRESS_FILTER) || + info154.fcf.frame_type == FRAME802154_ACKFRAME || + is_broadcast_addr(info154.fcf.dest_addr_mode, + (uint8_t *)&info154.dest_addr) || + linkaddr_cmp((linkaddr_t *)&info154.dest_addr, + &linkaddr_node_addr)) { + + /* + * Address check succeeded or address filter disabled. + * We send an ACK in case a corresponding data frame + * is received even in promiscuous mode (if auto-ack is + * enabled)! + */ + + if((rx_mode_value & RADIO_RX_MODE_AUTOACK) && + info154.fcf.frame_type == FRAME802154_DATAFRAME && + info154.fcf.ack_required != 0 && + (!(rx_mode_value & RADIO_RX_MODE_ADDRESS_FILTER) || + linkaddr_cmp((linkaddr_t *)&info154.dest_addr, + &linkaddr_node_addr))) { + + /* + * Data frame destined for us & ACK request bit set -> send ACK. + * Make sure the preamble length is configured accordingly as + * MAC timing parameters rely on this! + */ + + uint8_t ack[ACK_LEN] = { FRAME802154_ACKFRAME, 0, info154.seq }; + +#if (RXOFF_MODE_RX == 1) + /* + * This turns off GPIOx interrupts. Make sure they are turned on + * in rx_rx() later on! + */ + idle(); +#endif + + idle_tx_rx((const uint8_t *)ack, ACK_LEN); + + /* rx_rx() will follow */ + + return ADDR_CHECK_OK_ACK_SEND; + + } + + return ADDR_CHECK_OK; + + } else { + + return ADDR_CHECK_FAILED; + + } + + } + + return INVALID_FRAME; + +} +#endif /* CC1200_SNIFFER */ +/*---------------------------------------------------------------------------*/ +/* + * The CC1200 interrupt handler: called by the hardware interrupt + * handler, which is defined as part of the cc1200-arch interface. + */ +int +cc1200_rx_interrupt(void) +{ + + /* The radio's state */ + uint8_t s; + /* The number of bytes in the RX FIFO waiting for read-out */ + uint8_t num_rxbytes; + /* The payload length read as the first byte from the RX FIFO */ + static uint16_t payload_len; + /* + * The number of bytes already read out and placed in the + * intermediate buffer + */ + static uint16_t bytes_read; + /* + * We use an intermediate buffer for the packet before + * we pass it to the next upper layer. We also place RSSI + + * LQI in this buffer + */ + static uint8_t buf[CC1200_MAX_PAYLOAD_LEN + APPENDIX_LEN]; + + if(SPI_IS_LOCKED()) { + + /* + * SPI is in use. Exit and make sure this + * function is called from the poll handler as soon + * as SPI is available again + */ + + rf_flags |= RF_POLL_RX_INTERRUPT; + process_poll(&cc1200_process); + return 1; + + } + rf_flags &= ~RF_POLL_RX_INTERRUPT; + + LOCK_SPI(); + + /* + * If CC1200_USE_GPIO2 is enabled, we come here either once RX FIFO + * threshold is reached (GPIO2 rising edge) + * or at the end of the packet (GPIO0 falling edge). + */ + + /* Make sure we are in a sane state. Sane means: either RX or IDLE */ + s = state(); + if((s == STATE_RX_FIFO_ERR) || (s == STATE_TX_FIFO_ERR)) { + + rx_rx(); + RELEASE_SPI(); + return 0; + + } + + num_rxbytes = single_read(CC1200_NUM_RXBYTES); + + if(num_rxbytes == 0) { + + /* + * This might happen from time to time because + * this function is also called by the pollhandler and / or + * from TWO interrupts which can occur at the same time. + */ + + INFO("RF: RX FIFO empty!\n"); + RELEASE_SPI(); + return 0; + + } + + if(!(rf_flags & RF_RX_PROCESSING_PKT)) { + +#if CC1200_802154G + struct { + uint8_t phra; + uint8_t phrb; + } + phr; + + if(num_rxbytes < PHR_LEN) { + + WARNING("RF: PHR incomplete!\n"); + rx_rx(); + RELEASE_SPI(); + return 0; + + } + + burst_read(CC1200_RXFIFO, + &phr, + PHR_LEN); + payload_len = (phr.phra & 0x07); + payload_len <<= 8; + payload_len += phr.phrb; + + if(phr.phra & (1 << 4)) { + /* CRC16, payload_len += 2 */ + payload_len -= 2; + } else { + /* CRC16, payload_len += 4 */ + payload_len -= 4; + } +#else + /* Read first byte in RX FIFO (payload length) */ + burst_read(CC1200_RXFIFO, + (uint8_t *)&payload_len, + PHR_LEN); +#endif + + if(payload_len < ACK_LEN) { + /* Packet to short. Discard it */ + WARNING("RF: Packet too short!\n"); + RIMESTATS_ADD(tooshort); + rx_rx(); + RELEASE_SPI(); + return 0; + } + + if(payload_len > CC1200_MAX_PAYLOAD_LEN) { + /* Packet to long. Discard it */ + WARNING("RF: Packet to long!\n"); + RIMESTATS_ADD(toolong); + rx_rx(); + RELEASE_SPI(); + return 0; + } + + RX_LEDS_ON(); + bytes_read = 0; + num_rxbytes -= PHR_LEN; + + rf_flags |= RF_RX_PROCESSING_PKT; + + /* Fall through... */ + + } + + if(rf_flags & RF_RX_PROCESSING_PKT) { + + /* + * Read out remaining bytes unless FIFO is empty. + * We have at least num_rxbytes in the FIFO to be read out. + */ + + if((num_rxbytes + bytes_read) > (payload_len + CC_APPENDIX_LEN)) { + + /* + * We have a mismatch between the number of bytes in the RX FIFO + * and the payload_len. This would lead to an buffer overflow, + * so we catch this error here. + */ + + WARNING("RF: RX length mismatch %d %d %d!\n", num_rxbytes, + bytes_read, + payload_len); + rx_rx(); + RELEASE_SPI(); + return 0; + + } + + burst_read(CC1200_RXFIFO, + &buf[bytes_read], + num_rxbytes); + + bytes_read += num_rxbytes; + num_rxbytes = 0; + + if(bytes_read == (payload_len + CC_APPENDIX_LEN)) { + + /* + * End of packet. Read appendix (if available), check CRC + * and copy the data from temporary buffer to rx_pkt + * RSSI offset already set using AGC_GAIN_ADJUST.GAIN_ADJUSTMENT + */ + +#if APPEND_STATUS + uint8_t crc_lqi = buf[bytes_read - 1]; +#else + int8_t rssi = single_read(CC1200_RSSI1); + uint8_t crc_lqi = single_read(CC1200_LQI_VAL); +#endif + + if(!(crc_lqi & (1 << 7))) { + /* CRC error. Drop the packet */ + INFO("RF: CRC error!\n"); + RIMESTATS_ADD(badcrc); + } else if(rx_pkt_len != 0) { + /* An old packet is pending. Drop the packet */ + WARNING("RF: Packet pending!\n"); + } else { + + int ret = addr_check_auto_ack(buf, bytes_read); + + if((ret == ADDR_CHECK_OK) || + (ret == ADDR_CHECK_OK_ACK_SEND)) { +#if APPEND_STATUS + /* RSSI + LQI already read out and placed into buf */ +#else + buf[bytes_read++] = (uint8_t)rssi; + buf[bytes_read++] = crc_lqi; +#endif + rx_pkt_len = bytes_read; + memcpy((void *)rx_pkt, buf, rx_pkt_len); + rx_rx(); + process_poll(&cc1200_process); + RELEASE_SPI(); + return 1; + + } else { + /* Invalid address. Drop the packet */ + } + + } + + /* Buffer full, address or CRC check failed */ + rx_rx(); + RELEASE_SPI(); + return 0; + + } /* if (bytes_read == payload_len) */ + + } + + RELEASE_SPI(); + return 0; + +} +/*---------------------------------------------------------------------------*/ diff --git a/dev/cc2420/cc2420-aes.c b/dev/cc2420/cc2420-aes.c deleted file mode 100644 index 3f0ad199c..000000000 --- a/dev/cc2420/cc2420-aes.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2008, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * AES encryption functions. - * \author - * Adam Dunkels - */ - -#include "contiki.h" -#include "cc2420.h" -#include "cc2420-aes.h" -#include "dev/spi.h" - -#define KEYLEN 16 -#define MAX_DATALEN 16 - -#define CC2420_WRITE_RAM_REV(buffer,adr,count) \ - do { \ - uint8_t i; \ - CC2420_SPI_ENABLE(); \ - SPI_WRITE_FAST(0x80 | (adr & 0x7f)); \ - SPI_WRITE_FAST((adr >> 1) & 0xc0); \ - for(i = (count); i > 0; i--) { \ - SPI_WRITE_FAST(((uint8_t*)(buffer))[i - 1]); \ - } \ - SPI_WAITFORTx_ENDED(); \ - CC2420_SPI_DISABLE(); \ - } while(0) - -#define MIN(a,b) ((a) < (b)? (a): (b)) - -/*---------------------------------------------------------------------------*/ -void -cc2420_aes_set_key(const uint8_t *key, int index) -{ - switch(index) { - case 0: - CC2420_WRITE_RAM_REV(key, CC2420RAM_KEY0, KEYLEN); - break; - case 1: - CC2420_WRITE_RAM_REV(key, CC2420RAM_KEY1, KEYLEN); - break; - } -} -/*---------------------------------------------------------------------------*/ -/* Encrypt at most 16 bytes of data. */ -static void -cipher16(uint8_t *data, int len) -{ - uint8_t status; - - len = MIN(len, MAX_DATALEN); - - CC2420_WRITE_RAM(data, CC2420RAM_SABUF, len); - CC2420_STROBE(CC2420_SAES); - /* Wait for the encryption to finish */ - do { - CC2420_GET_STATUS(status); - } while(status & BV(CC2420_ENC_BUSY)); - CC2420_READ_RAM(data, CC2420RAM_SABUF, len); -} -/*---------------------------------------------------------------------------*/ -void -cc2420_aes_cipher(uint8_t *data, int len, int key_index) -{ - int i; - uint16_t secctrl0; - - CC2420_READ_REG(CC2420_SECCTRL0, secctrl0); - - secctrl0 &= ~(CC2420_SECCTRL0_SAKEYSEL0 | CC2420_SECCTRL0_SAKEYSEL1); - - switch(key_index) { - case 0: - secctrl0 |= CC2420_SECCTRL0_SAKEYSEL0; - break; - case 1: - secctrl0 |= CC2420_SECCTRL0_SAKEYSEL1; - break; - } - CC2420_WRITE_REG(CC2420_SECCTRL0, secctrl0); - - for(i = 0; i < len; i = i + MAX_DATALEN) { - cipher16(data + i, MIN(len - i, MAX_DATALEN)); - } -} -/*---------------------------------------------------------------------------*/ diff --git a/dev/cc2420/cc2420-aes.h b/dev/cc2420/cc2420-aes.h deleted file mode 100644 index df54f97d2..000000000 --- a/dev/cc2420/cc2420-aes.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2008, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Interface to the CC2420 AES encryption/decryption functions - * \author - * Adam Dunkels - */ - -#ifndef CC2420_AES_H_ -#define CC2420_AES_H_ - -/** - * \brief Setup an AES key - * \param key A pointer to a 16-byte AES key - * \param index The key index: either 0 or 1. - * - * This function sets up an AES key with the CC2420 - * chip. The AES key can later be used with the - * cc2420_aes_cipher() function to encrypt or decrypt - * data. - * - * The CC2420 can store two separate keys in its - * memory. The keys are indexed as 0 or 1 and the key - * index is given by the 'index' parameter. - * - */ -void cc2420_aes_set_key(const uint8_t *key, int index); - - -/** - * \brief Encrypt/decrypt data with AES - * \param data A pointer to the data to be encrypted/decrypted - * \param len The length of the data to be encrypted/decrypted - * \param key_index The key to use. The key must have previously been set up with cc2420_aes_set_key(). - * - * This function encrypts/decrypts data with AES. A - * pointer to the data is passed as a parameter, and the - * function overwrites the data with the encrypted data. - * - */ -void cc2420_aes_cipher(uint8_t *data, int len, int key_index); - - -#endif /* CC2420_AES_H_ */ diff --git a/dev/cc2420/cc2420.c b/dev/cc2420/cc2420.c index f3f1cc7cf..1782aae06 100644 --- a/dev/cc2420/cc2420.c +++ b/dev/cc2420/cc2420.c @@ -52,12 +52,6 @@ #define WITH_SEND_CCA 1 -#define FOOTER_LEN 2 - -#ifndef CC2420_CONF_CHECKSUM -#define CC2420_CONF_CHECKSUM 0 -#endif /* CC2420_CONF_CHECKSUM */ - #ifndef CC2420_CONF_CHANNEL #define CC2420_CONF_CHANNEL 26 #endif /* CC2420_CONF_CHANNEL */ @@ -66,24 +60,29 @@ #define CC2420_CONF_CCA_THRESH -45 #endif /* CC2420_CONF_CCA_THRESH */ - #ifndef CC2420_CONF_AUTOACK #define CC2420_CONF_AUTOACK 0 #endif /* CC2420_CONF_AUTOACK */ -#if CC2420_CONF_CHECKSUM -#include "lib/crc16.h" -#define CHECKSUM_LEN 2 -#else -#define CHECKSUM_LEN 0 -#endif /* CC2420_CONF_CHECKSUM */ - -#define AUX_LEN (CHECKSUM_LEN + FOOTER_LEN) - - +#define CHECKSUM_LEN 2 +#define FOOTER_LEN 2 #define FOOTER1_CRC_OK 0x80 #define FOOTER1_CORRELATION 0x7f +#ifdef CC2420_CONF_RSSI_OFFSET +#define RSSI_OFFSET CC2420_CONF_RSSI_OFFSET +#else /* CC2420_CONF_RSSI_OFFSET */ +/* The RSSI_OFFSET is approximate -45 (see CC2420 specification) */ +#define RSSI_OFFSET -45 +#endif /* CC2420_CONF_RSSI_OFFSET */ + +enum write_ram_order { + /* Begin with writing the first given byte */ + WRITE_RAM_IN_ORDER, + /* Begin with writing the last given byte */ + WRITE_RAM_REVERSE +}; + #define DEBUG 0 #if DEBUG #include @@ -103,6 +102,28 @@ #define LEDS_OFF(x) #endif +/* Conversion map between PA_LEVEL and output power in dBm + (from table 9 in CC2420 specification). +*/ +struct output_config { + int8_t power; + uint8_t config; +}; + +static const struct output_config output_power[] = { + { 0, 31 }, /* 0xff */ + { -1, 27 }, /* 0xfb */ + { -3, 23 }, /* 0xf7 */ + { -5, 19 }, /* 0xf3 */ + { -7, 15 }, /* 0xef */ + {-10, 11 }, /* 0xeb */ + {-15, 7 }, /* 0xe7 */ + {-25, 3 }, /* 0xe3 */ +}; +#define OUTPUT_NUM (sizeof(output_power) / sizeof(struct output_config)) +#define OUTPUT_POWER_MAX 0 +#define OUTPUT_POWER_MIN -25 + void cc2420_arch_init(void); /* XXX hack: these will be made as Chameleon packet attributes */ @@ -110,17 +131,6 @@ rtimer_clock_t cc2420_time_of_arrival, cc2420_time_of_departure; int cc2420_authority_level_of_sender; -int cc2420_packets_seen, cc2420_packets_read; - -static uint8_t volatile pending; - -#define BUSYWAIT_UNTIL(cond, max_time) \ - do { \ - rtimer_clock_t t0; \ - t0 = RTIMER_NOW(); \ - while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))); \ - } while(0) - volatile uint8_t cc2420_sfd_counter; volatile uint16_t cc2420_sfd_start_time; volatile uint16_t cc2420_sfd_end_time; @@ -130,6 +140,13 @@ static volatile uint16_t last_packet_timestamp; PROCESS(cc2420_process, "CC2420 driver"); /*---------------------------------------------------------------------------*/ +#define AUTOACK (1 << 4) +#define AUTOCRC (1 << 5) +#define ADR_DECODE (1 << 11) +#define RXFIFO_PROTECTION (1 << 9) +#define CORR_THR(n) (((n) & 0x1f) << 6) +#define FIFOP_THR(n) ((n) & 0x7f) +#define RXBPF_LOCUR (1 << 13); int cc2420_on(void); int cc2420_off(void); @@ -142,12 +159,182 @@ static int cc2420_send(const void *data, unsigned short len); static int cc2420_receiving_packet(void); static int pending_packet(void); +static int get_cca_threshold(void); static int cc2420_cca(void); -/*static int detected_energy(void);*/ +static uint16_t getreg(enum cc2420_register regname); + +static void set_frame_filtering(uint8_t enable); +static void set_poll_mode(uint8_t enable); +static void set_send_on_cca(uint8_t enable); +static void set_auto_ack(uint8_t enable); signed char cc2420_last_rssi; uint8_t cc2420_last_correlation; +static uint8_t receive_on; +static int channel; + +/* Are we currently in poll mode? */ +static uint8_t volatile poll_mode = 0; +/* Do we perform a CCA before sending? */ +static uint8_t send_on_cca = WITH_SEND_CCA; + +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + int i, v; + + if(!value) { + return RADIO_RESULT_INVALID_VALUE; + } + switch(param) { + case RADIO_PARAM_POWER_MODE: + *value = receive_on ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF; + return RADIO_RESULT_OK; + case RADIO_PARAM_CHANNEL: + *value = cc2420_get_channel(); + return RADIO_RESULT_OK; + case RADIO_PARAM_RX_MODE: + *value = 0; + if(getreg(CC2420_MDMCTRL0) & ADR_DECODE) { + *value |= RADIO_RX_MODE_ADDRESS_FILTER; + } + if(getreg(CC2420_MDMCTRL0) & AUTOACK) { + *value |= RADIO_RX_MODE_AUTOACK; + } + if(poll_mode) { + *value |= RADIO_RX_MODE_POLL_MODE; + } + return RADIO_RESULT_OK; + case RADIO_PARAM_TX_MODE: + *value = 0; + if(send_on_cca) { + *value |= RADIO_TX_MODE_SEND_ON_CCA; + } + return RADIO_RESULT_OK; + case RADIO_PARAM_TXPOWER: + v = cc2420_get_txpower(); + *value = OUTPUT_POWER_MIN; + /* Find the actual estimated output power in conversion table */ + for(i = 0; i < OUTPUT_NUM; i++) { + if(v >= output_power[i].config) { + *value = output_power[i].power; + break; + } + } + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + *value = get_cca_threshold() + RSSI_OFFSET; + return RADIO_RESULT_OK; + case RADIO_PARAM_RSSI: + /* Return the RSSI value in dBm */ + *value = cc2420_rssi(); + return RADIO_RESULT_OK; + case RADIO_PARAM_LAST_RSSI: + /* RSSI of the last packet received */ + *value = cc2420_last_rssi; + return RADIO_RESULT_OK; + case RADIO_PARAM_LAST_LINK_QUALITY: + /* LQI of the last packet received */ + *value = cc2420_last_correlation; + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MIN: + *value = 11; + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MAX: + *value = 26; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MIN: + *value = OUTPUT_POWER_MIN; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MAX: + *value = OUTPUT_POWER_MAX; + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} + +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + int i; + + switch(param) { + case RADIO_PARAM_POWER_MODE: + if(value == RADIO_POWER_MODE_ON) { + cc2420_on(); + return RADIO_RESULT_OK; + } + if(value == RADIO_POWER_MODE_OFF) { + cc2420_off(); + return RADIO_RESULT_OK; + } + return RADIO_RESULT_INVALID_VALUE; + case RADIO_PARAM_CHANNEL: + if(value < 11 || value > 26) { + return RADIO_RESULT_INVALID_VALUE; + } + cc2420_set_channel(value); + return RADIO_RESULT_OK; + case RADIO_PARAM_RX_MODE: + if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER | + RADIO_RX_MODE_AUTOACK | RADIO_RX_MODE_POLL_MODE)) { + return RADIO_RESULT_INVALID_VALUE; + } + set_frame_filtering((value & RADIO_RX_MODE_ADDRESS_FILTER) != 0); + set_auto_ack((value & RADIO_RX_MODE_AUTOACK) != 0); + set_poll_mode((value & RADIO_RX_MODE_POLL_MODE) != 0); + return RADIO_RESULT_OK; + case RADIO_PARAM_TX_MODE: + if(value & ~(RADIO_TX_MODE_SEND_ON_CCA)) { + return RADIO_RESULT_INVALID_VALUE; + } + set_send_on_cca((value & RADIO_TX_MODE_SEND_ON_CCA) != 0); + return RADIO_RESULT_OK; + case RADIO_PARAM_TXPOWER: + if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) { + return RADIO_RESULT_INVALID_VALUE; + } + /* Find the closest higher PA_LEVEL for the desired output power */ + for(i = 1; i < OUTPUT_NUM; i++) { + if(value > output_power[i].power) { + break; + } + } + cc2420_set_txpower(output_power[i - 1].config); + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + cc2420_set_cca_threshold(value - RSSI_OFFSET); + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} + +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + if(param == RADIO_PARAM_LAST_PACKET_TIMESTAMP) { +#if CC2420_CONF_SFD_TIMESTAMPS + if(size != sizeof(rtimer_clock_t) || !dest) { + return RADIO_RESULT_INVALID_VALUE; + } + *(rtimer_clock_t*)dest = cc2420_sfd_start_time; + return RADIO_RESULT_OK; +#else + return RADIO_RESULT_NOT_SUPPORTED; +#endif + } + return RADIO_RESULT_NOT_SUPPORTED; +} + +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} + const struct radio_driver cc2420_driver = { cc2420_init, @@ -155,68 +342,191 @@ const struct radio_driver cc2420_driver = cc2420_transmit, cc2420_send, cc2420_read, - /* cc2420_set_channel, */ - /* detected_energy, */ cc2420_cca, cc2420_receiving_packet, pending_packet, cc2420_on, cc2420_off, + get_value, + set_value, + get_object, + set_object }; -static uint8_t receive_on; - -static int channel; - /*---------------------------------------------------------------------------*/ - +/* Sends a strobe */ static void -getrxdata(void *buf, int len) +strobe(enum cc2420_register regname) { - CC2420_READ_FIFO_BUF(buf, len); + CC2420_SPI_ENABLE(); + SPI_WRITE(regname); + CC2420_SPI_DISABLE(); } +/*---------------------------------------------------------------------------*/ +/* Reads a register */ +static uint16_t +getreg(enum cc2420_register regname) +{ + uint16_t value; + + CC2420_SPI_ENABLE(); + SPI_WRITE(regname | 0x40); + value = (uint8_t)SPI_RXBUF; + SPI_TXBUF = 0; + SPI_WAITFOREORx(); + value = SPI_RXBUF << 8; + SPI_TXBUF = 0; + SPI_WAITFOREORx(); + value |= SPI_RXBUF; + CC2420_SPI_DISABLE(); + + return value; +} +/*---------------------------------------------------------------------------*/ +/** + * Writes to a register. + * Note: the SPI_WRITE(0) seems to be needed for getting the + * write reg working on the Z1 / MSP430X platform + */ static void -getrxbyte(uint8_t *byte) +setreg(enum cc2420_register regname, uint16_t value) { - CC2420_READ_FIFO_BYTE(*byte); + CC2420_SPI_ENABLE(); + SPI_WRITE_FAST(regname); + SPI_WRITE_FAST((uint8_t) (value >> 8)); + SPI_WRITE_FAST((uint8_t) (value & 0xff)); + SPI_WAITFORTx_ENDED(); + SPI_WRITE(0); + CC2420_SPI_DISABLE(); } +/*---------------------------------------------------------------------------*/ +static void +read_ram(uint8_t *buffer, uint16_t adr, uint16_t count) +{ + uint8_t i; + + CC2420_SPI_ENABLE(); + SPI_WRITE(0x80 | ((adr) & 0x7f)); + SPI_WRITE((((adr) >> 1) & 0xc0) | 0x20); + SPI_RXBUF; + for(i = 0; i < count; i++) { + SPI_READ(((uint8_t*) buffer)[i]); + } + CC2420_SPI_DISABLE(); +} +/*---------------------------------------------------------------------------*/ +/* Write to RAM in the CC2420 */ +static void +write_ram(const uint8_t *buffer, + uint16_t adr, + uint16_t count, + enum write_ram_order order) +{ + uint8_t i; + + CC2420_SPI_ENABLE(); + SPI_WRITE_FAST(0x80 | (adr & 0x7f)); + SPI_WRITE_FAST((adr >> 1) & 0xc0); + if(order == WRITE_RAM_IN_ORDER) { + for(i = 0; i < count; i++) { + SPI_WRITE_FAST((buffer)[i]); + } + } else { + for(i = count; i > 0; i--) { + SPI_WRITE_FAST((buffer)[i - 1]); + } + } + SPI_WAITFORTx_ENDED(); + CC2420_SPI_DISABLE(); +} +/*---------------------------------------------------------------------------*/ +static void +write_fifo_buf(const uint8_t *buffer, uint16_t count) +{ + uint8_t i; + + CC2420_SPI_ENABLE(); + SPI_WRITE_FAST(CC2420_TXFIFO); + for(i = 0; i < count; i++) { + SPI_WRITE_FAST((buffer)[i]); + } + SPI_WAITFORTx_ENDED(); + CC2420_SPI_DISABLE(); +} +/*---------------------------------------------------------------------------*/ +/* Returns the current status */ +static uint8_t +get_status(void) +{ + uint8_t status; + + CC2420_SPI_ENABLE(); + SPI_WRITE(CC2420_SNOP); + status = SPI_RXBUF; + CC2420_SPI_DISABLE(); + + return status; +} +/*---------------------------------------------------------------------------*/ +static void +getrxdata(uint8_t *buffer, int count) +{ + uint8_t i; + + CC2420_SPI_ENABLE(); + SPI_WRITE(CC2420_RXFIFO | 0x40); + (void) SPI_RXBUF; + for(i = 0; i < count; i++) { + SPI_READ(buffer[i]); + } + clock_delay(1); + CC2420_SPI_DISABLE(); +} +/*---------------------------------------------------------------------------*/ static void flushrx(void) { uint8_t dummy; - CC2420_READ_FIFO_BYTE(dummy); - CC2420_STROBE(CC2420_SFLUSHRX); - CC2420_STROBE(CC2420_SFLUSHRX); + getrxdata(&dummy, 1); + strobe(CC2420_SFLUSHRX); + strobe(CC2420_SFLUSHRX); + if(dummy) { + /* avoid unused variable compiler warning */ + } } /*---------------------------------------------------------------------------*/ static void -strobe(enum cc2420_register regname) +wait_for_status(uint8_t status_bit) { - CC2420_STROBE(regname); + rtimer_clock_t t0; + t0 = RTIMER_NOW(); + while(!(get_status() & status_bit) + && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (RTIMER_SECOND / 10))); } /*---------------------------------------------------------------------------*/ -static unsigned int -status(void) +static void +wait_for_transmission(void) { - uint8_t status; - CC2420_GET_STATUS(status); - return status; + rtimer_clock_t t0; + t0 = RTIMER_NOW(); + while((get_status() & BV(CC2420_TX_ACTIVE)) + && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (RTIMER_SECOND / 10))); } /*---------------------------------------------------------------------------*/ -static uint8_t locked, lock_on, lock_off; - static void on(void) { - CC2420_ENABLE_FIFOP_INT(); - strobe(CC2420_SRXON); + if(!poll_mode) { + CC2420_ENABLE_FIFOP_INT(); + } - BUSYWAIT_UNTIL(status() & (BV(CC2420_XOSC16M_STABLE)), RTIMER_SECOND / 100); + strobe(CC2420_SRXON); ENERGEST_ON(ENERGEST_TYPE_LISTEN); receive_on = 1; } +/*---------------------------------------------------------------------------*/ static void off(void) { @@ -224,17 +534,20 @@ off(void) receive_on = 0; /* Wait for transmission to end before turning radio off. */ - BUSYWAIT_UNTIL(!(status() & BV(CC2420_TX_ACTIVE)), RTIMER_SECOND / 10); + wait_for_transmission(); ENERGEST_OFF(ENERGEST_TYPE_LISTEN); strobe(CC2420_SRFOFF); - CC2420_DISABLE_FIFOP_INT(); + if(!poll_mode) { + CC2420_DISABLE_FIFOP_INT(); + } if(!CC2420_FIFOP_IS_1) { flushrx(); } } /*---------------------------------------------------------------------------*/ +static uint8_t locked, lock_on, lock_off; #define GET_LOCK() locked++ static void RELEASE_LOCK(void) { if(locked == 1) { @@ -250,21 +563,48 @@ static void RELEASE_LOCK(void) { locked--; } /*---------------------------------------------------------------------------*/ -static unsigned -getreg(enum cc2420_register regname) +static void +init_security(void) { - unsigned reg; - CC2420_READ_REG(regname, reg); - return reg; + /* only use key 0 */ + setreg(CC2420_SECCTRL0, 0); + setreg(CC2420_SECCTRL1, 0); } /*---------------------------------------------------------------------------*/ static void -setreg(enum cc2420_register regname, unsigned value) +set_key(const uint8_t *key) { - CC2420_WRITE_REG(regname, value); + GET_LOCK(); + + write_ram(key, CC2420RAM_KEY0, 16, WRITE_RAM_REVERSE); + + RELEASE_LOCK(); } /*---------------------------------------------------------------------------*/ static void +encrypt(uint8_t *plaintext_and_result) +{ + GET_LOCK(); + + write_ram(plaintext_and_result, + CC2420RAM_SABUF, + 16, + WRITE_RAM_IN_ORDER); + + strobe(CC2420_SAES); + while(get_status() & BV(CC2420_ENC_BUSY)); + + read_ram(plaintext_and_result, CC2420RAM_SABUF, 16); + + RELEASE_LOCK(); +} +/*---------------------------------------------------------------------------*/ +const struct aes_128_driver cc2420_aes_128_driver = { + set_key, + encrypt +}; +/*---------------------------------------------------------------------------*/ +static void set_txpower(uint8_t power) { uint16_t reg; @@ -274,13 +614,6 @@ set_txpower(uint8_t power) setreg(CC2420_TXCTRL, reg); } /*---------------------------------------------------------------------------*/ -#define AUTOACK (1 << 4) -#define ADR_DECODE (1 << 11) -#define RXFIFO_PROTECTION (1 << 9) -#define CORR_THR(n) (((n) & 0x1f) << 6) -#define FIFOP_THR(n) ((n) & 0x7f) -#define RXBPF_LOCUR (1 << 13); -/*---------------------------------------------------------------------------*/ int cc2420_init(void) { @@ -304,15 +637,18 @@ cc2420_init(void) /* Turn on the crystal oscillator. */ strobe(CC2420_SXOSCON); + /* And wait until it stabilizes */ + wait_for_status(BV(CC2420_XOSC16M_STABLE)); - /* Turn on/off automatic packet acknowledgment and address decoding. */ + /* Set auto-ack and frame filtering */ + set_auto_ack(CC2420_CONF_AUTOACK); + set_frame_filtering(CC2420_CONF_AUTOACK); + + /* Enabling CRC in hardware; this is required by AUTOACK anyway + and provides us with RSSI and link quality indication (LQI) + information. */ reg = getreg(CC2420_MDMCTRL0); - -#if CC2420_CONF_AUTOACK - reg |= AUTOACK | ADR_DECODE; -#else - reg &= ~(AUTOACK | ADR_DECODE); -#endif /* CC2420_CONF_AUTOACK */ + reg |= AUTOCRC; setreg(CC2420_MDMCTRL0, reg); /* Set transmission turnaround time to the lower setting (8 symbols @@ -332,10 +668,7 @@ cc2420_init(void) /* Set the FIFOP threshold to maximum. */ setreg(CC2420_IOCFG0, FIFOP_THR(127)); - /* Turn off "Security enable" (page 32). */ - reg = getreg(CC2420_SECCTRL0); - reg &= ~RXFIFO_PROTECTION; - setreg(CC2420_SECCTRL0, reg); + init_security(); cc2420_set_pan_addr(0xffff, 0x0000, NULL); cc2420_set_channel(CC2420_CONF_CHANNEL); @@ -343,6 +676,8 @@ cc2420_init(void) flushrx(); + set_poll_mode(0); + process_start(&cc2420_process, NULL); return 1; } @@ -351,11 +686,7 @@ static int cc2420_transmit(unsigned short payload_len) { int i, txpower; - uint8_t total_len; -#if CC2420_CONF_CHECKSUM - uint16_t checksum; -#endif /* CC2420_CONF_CHECKSUM */ - + GET_LOCK(); txpower = 0; @@ -366,8 +697,6 @@ cc2420_transmit(unsigned short payload_len) set_txpower(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) - 1); } - total_len = payload_len + AUX_LEN; - /* The TX FIFO can only hold one packet. Make sure to not overrun * FIFO by waiting for transmission to start here and synchronizing * with the CC2420_TX_ACTIVE check in cc2420_send. @@ -381,26 +710,28 @@ cc2420_transmit(unsigned short payload_len) #define LOOP_20_SYMBOLS CC2420_CONF_SYMBOL_LOOP_COUNT #endif -#if WITH_SEND_CCA - strobe(CC2420_SRXON); - BUSYWAIT_UNTIL(status() & BV(CC2420_RSSI_VALID), RTIMER_SECOND / 10); - strobe(CC2420_STXONCCA); -#else /* WITH_SEND_CCA */ - strobe(CC2420_STXON); -#endif /* WITH_SEND_CCA */ + if(send_on_cca) { + strobe(CC2420_SRXON); + wait_for_status(BV(CC2420_RSSI_VALID)); + strobe(CC2420_STXONCCA); + } else { + strobe(CC2420_STXON); + } for(i = LOOP_20_SYMBOLS; i > 0; i--) { if(CC2420_SFD_IS_1) { +#if PACKETBUF_WITH_PACKET_TYPE { rtimer_clock_t sfd_timestamp; sfd_timestamp = cc2420_sfd_start_time; if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == PACKETBUF_ATTR_PACKET_TYPE_TIMESTAMP) { /* Write timestamp to last two bytes of packet in TXFIFO. */ - CC2420_WRITE_RAM(&sfd_timestamp, CC2420RAM_TXFIFO + payload_len - 1, 2); + write_ram((uint8_t *) &sfd_timestamp, CC2420RAM_TXFIFO + payload_len - 1, 2, WRITE_RAM_IN_ORDER); } } +#endif /* PACKETBUF_WITH_PACKET_TYPE */ - if(!(status() & BV(CC2420_TX_ACTIVE))) { + if(!(get_status() & BV(CC2420_TX_ACTIVE))) { /* SFD went high but we are not transmitting. This means that we just started receiving a packet, so we drop the transmission. */ @@ -413,7 +744,7 @@ cc2420_transmit(unsigned short payload_len) ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); /* We wait until transmission has ended so that we get an accurate measurement of the transmission time.*/ - BUSYWAIT_UNTIL(!(status() & BV(CC2420_TX_ACTIVE)), RTIMER_SECOND / 10); + wait_for_transmission(); #ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS ENERGEST_OFF_LEVEL(ENERGEST_TYPE_TRANSMIT,cc2420_get_txpower()); @@ -437,7 +768,7 @@ cc2420_transmit(unsigned short payload_len) } } - /* If we are using WITH_SEND_CCA, we get here if the packet wasn't + /* If we send with cca (cca_on_send), we get here if the packet wasn't transmitted because of other channel activity. */ RIMESTATS_ADD(contentiondrop); PRINTF("cc2420: do_send() transmission never started\n"); @@ -455,9 +786,7 @@ static int cc2420_prepare(const void *payload, unsigned short payload_len) { uint8_t total_len; -#if CC2420_CONF_CHECKSUM - uint16_t checksum; -#endif /* CC2420_CONF_CHECKSUM */ + GET_LOCK(); PRINTF("cc2420: sending %d bytes\n", payload_len); @@ -470,16 +799,10 @@ cc2420_prepare(const void *payload, unsigned short payload_len) /* Write packet to TX FIFO. */ strobe(CC2420_SFLUSHTX); -#if CC2420_CONF_CHECKSUM - checksum = crc16_data(payload, payload_len, 0); -#endif /* CC2420_CONF_CHECKSUM */ - total_len = payload_len + AUX_LEN; - CC2420_WRITE_FIFO_BUF(&total_len, 1); - CC2420_WRITE_FIFO_BUF(payload, payload_len); -#if CC2420_CONF_CHECKSUM - CC2420_WRITE_FIFO_BUF(&checksum, CHECKSUM_LEN); -#endif /* CC2420_CONF_CHECKSUM */ - + total_len = payload_len + CHECKSUM_LEN; + write_fifo_buf(&total_len, 1); + write_fifo_buf(payload, payload_len); + RELEASE_LOCK(); return 0; } @@ -512,7 +835,7 @@ cc2420_off(void) we don't actually switch the radio off now, but signal that the driver should switch off the radio once the packet has been received and processed, by setting the 'lock_off' variable. */ - if(status() & BV(CC2420_TX_ACTIVE)) { + if(get_status() & BV(CC2420_TX_ACTIVE)) { lock_off = 1; } else { off(); @@ -557,13 +880,9 @@ cc2420_set_channel(int c) channel = c; f = 5 * (c - 11) + 357 + 0x4000; - /* - * Writing RAM requires crystal oscillator to be stable. - */ - BUSYWAIT_UNTIL((status() & (BV(CC2420_XOSC16M_STABLE))), RTIMER_SECOND / 10); - + /* Wait for any transmission to end. */ - BUSYWAIT_UNTIL(!(status() & BV(CC2420_TX_ACTIVE)), RTIMER_SECOND / 10); + wait_for_transmission(); setreg(CC2420_FSCTRL, f); @@ -582,30 +901,13 @@ cc2420_set_pan_addr(unsigned pan, unsigned addr, const uint8_t *ieee_addr) { - uint16_t f = 0; - uint8_t tmp[2]; - GET_LOCK(); - /* - * Writing RAM requires crystal oscillator to be stable. - */ - BUSYWAIT_UNTIL(status() & (BV(CC2420_XOSC16M_STABLE)), RTIMER_SECOND / 10); - - tmp[0] = pan & 0xff; - tmp[1] = pan >> 8; - CC2420_WRITE_RAM(&tmp, CC2420RAM_PANID, 2); - - tmp[0] = addr & 0xff; - tmp[1] = addr >> 8; - CC2420_WRITE_RAM(&tmp, CC2420RAM_SHORTADDR, 2); + write_ram((uint8_t *) &pan, CC2420RAM_PANID, 2, WRITE_RAM_IN_ORDER); + write_ram((uint8_t *) &addr, CC2420RAM_SHORTADDR, 2, WRITE_RAM_IN_ORDER); + if(ieee_addr != NULL) { - uint8_t tmp_addr[8]; - /* LSB first, MSB last for 802.15.4 addresses in CC2420 */ - for (f = 0; f < 8; f++) { - tmp_addr[7 - f] = ieee_addr[f]; - } - CC2420_WRITE_RAM(tmp_addr, CC2420RAM_IEEEADDR, 8); + write_ram(ieee_addr, CC2420RAM_IEEEADDR, 8, WRITE_RAM_REVERSE); } RELEASE_LOCK(); } @@ -620,8 +922,6 @@ cc2420_interrupt(void) process_poll(&cc2420_process); last_packet_timestamp = cc2420_sfd_start_time; - pending++; - cc2420_packets_seen++; return 1; } /*---------------------------------------------------------------------------*/ @@ -633,7 +933,7 @@ PROCESS_THREAD(cc2420_process, ev, data) PRINTF("cc2420_process: started\n"); while(1) { - PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + PROCESS_YIELD_UNTIL(!poll_mode && ev == PROCESS_EVENT_POLL); PRINTF("cc2420_process: calling receiver callback\n"); @@ -652,99 +952,66 @@ PROCESS_THREAD(cc2420_process, ev, data) static int cc2420_read(void *buf, unsigned short bufsize) { - uint8_t footer[2]; + uint8_t footer[FOOTER_LEN]; uint8_t len; -#if CC2420_CONF_CHECKSUM - uint16_t checksum; -#endif /* CC2420_CONF_CHECKSUM */ if(!CC2420_FIFOP_IS_1) { return 0; } - /* if(!pending) { - return 0; - }*/ - - pending = 0; GET_LOCK(); - cc2420_packets_read++; - - getrxbyte(&len); + getrxdata(&len, 1); if(len > CC2420_MAX_PACKET_LEN) { /* Oops, we must be out of sync. */ - flushrx(); RIMESTATS_ADD(badsynch); - RELEASE_LOCK(); - return 0; - } - - if(len <= AUX_LEN) { - flushrx(); + } else if(len <= FOOTER_LEN) { RIMESTATS_ADD(tooshort); - RELEASE_LOCK(); - return 0; - } - - if(len - AUX_LEN > bufsize) { - flushrx(); + } else if(len - FOOTER_LEN > bufsize) { RIMESTATS_ADD(toolong); - RELEASE_LOCK(); - return 0; - } - - getrxdata(buf, len - AUX_LEN); -#if CC2420_CONF_CHECKSUM - getrxdata(&checksum, CHECKSUM_LEN); -#endif /* CC2420_CONF_CHECKSUM */ - getrxdata(footer, FOOTER_LEN); - -#if CC2420_CONF_CHECKSUM - if(checksum != crc16_data(buf, len - AUX_LEN, 0)) { - PRINTF("checksum failed 0x%04x != 0x%04x\n", - checksum, crc16_data(buf, len - AUX_LEN, 0)); - } - - if(footer[1] & FOOTER1_CRC_OK && - checksum == crc16_data(buf, len - AUX_LEN, 0)) { -#else - if(footer[1] & FOOTER1_CRC_OK) { -#endif /* CC2420_CONF_CHECKSUM */ - cc2420_last_rssi = footer[0]; - cc2420_last_correlation = footer[1] & FOOTER1_CORRELATION; - - - packetbuf_set_attr(PACKETBUF_ATTR_RSSI, cc2420_last_rssi); - packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, cc2420_last_correlation); - - RIMESTATS_ADD(llrx); - } else { - RIMESTATS_ADD(badcrc); - len = AUX_LEN; - } + getrxdata((uint8_t *) buf, len - FOOTER_LEN); + getrxdata(footer, FOOTER_LEN); + + if(footer[1] & FOOTER1_CRC_OK) { + cc2420_last_rssi = footer[0] + RSSI_OFFSET; + cc2420_last_correlation = footer[1] & FOOTER1_CORRELATION; + if(!poll_mode) { + /* Not in poll mode: packetbuf should not be accessed in interrupt context. + * In poll mode, the last packet RSSI and link quality can be obtained through + * RADIO_PARAM_LAST_RSSI and RADIO_PARAM_LAST_LINK_QUALITY */ + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, cc2420_last_rssi); + packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, cc2420_last_correlation); + } - if(CC2420_FIFOP_IS_1) { - if(!CC2420_FIFO_IS_1) { - /* Clean up in case of FIFO overflow! This happens for every - * full length frame and is signaled by FIFOP = 1 and FIFO = - * 0. */ - flushrx(); + RIMESTATS_ADD(llrx); } else { - /* Another packet has been received and needs attention. */ - process_poll(&cc2420_process); + RIMESTATS_ADD(badcrc); + len = FOOTER_LEN; } - } + if(!poll_mode) { + if(CC2420_FIFOP_IS_1) { + if(!CC2420_FIFO_IS_1) { + /* Clean up in case of FIFO overflow! This happens for every + * full length frame and is signaled by FIFOP = 1 and FIFO = + * 0. */ + flushrx(); + } else { + /* Another packet has been received and needs attention. */ + process_poll(&cc2420_process); + } + } + } + + RELEASE_LOCK(); + return len - FOOTER_LEN; + } + + flushrx(); RELEASE_LOCK(); - - if(len < AUX_LEN) { - return 0; - } - - return len - AUX_LEN; + return 0; } /*---------------------------------------------------------------------------*/ void @@ -781,9 +1048,10 @@ cc2420_rssi(void) radio_was_off = 1; cc2420_on(); } - BUSYWAIT_UNTIL(status() & BV(CC2420_RSSI_VALID), RTIMER_SECOND / 100); + wait_for_status(BV(CC2420_RSSI_VALID)); - rssi = (int)((signed char)getreg(CC2420_RSSI)); + rssi = (int)((signed char) getreg(CC2420_RSSI)); + rssi += RSSI_OFFSET; if(radio_was_off) { cc2420_off(); @@ -792,27 +1060,6 @@ cc2420_rssi(void) return rssi; } /*---------------------------------------------------------------------------*/ -/* -static int -detected_energy(void) -{ - return cc2420_rssi(); -} -*/ -/*---------------------------------------------------------------------------*/ -int -cc2420_cca_valid(void) -{ - int valid; - if(locked) { - return 1; - } - GET_LOCK(); - valid = !!(status() & BV(CC2420_RSSI_VALID)); - RELEASE_LOCK(); - return valid; -} -/*---------------------------------------------------------------------------*/ static int cc2420_cca(void) { @@ -842,7 +1089,7 @@ cc2420_cca(void) return 1; } - BUSYWAIT_UNTIL(status() & BV(CC2420_RSSI_VALID), RTIMER_SECOND / 100); + wait_for_status(BV(CC2420_RSSI_VALID)); cca = CC2420_CCA_IS_1; @@ -865,6 +1112,17 @@ pending_packet(void) return CC2420_FIFOP_IS_1; } /*---------------------------------------------------------------------------*/ +static int +get_cca_threshold(void) +{ + int value; + + GET_LOCK(); + value = (int8_t)(getreg(CC2420_RSSI) >> 8); + RELEASE_LOCK(); + return value; +} +/*---------------------------------------------------------------------------*/ void cc2420_set_cca_threshold(int value) { @@ -874,3 +1132,64 @@ cc2420_set_cca_threshold(int value) RELEASE_LOCK(); } /*---------------------------------------------------------------------------*/ +/* Set or unset frame autoack */ +static void +set_auto_ack(uint8_t enable) +{ + GET_LOCK(); + + uint16_t reg = getreg(CC2420_MDMCTRL0); + if(enable) { + reg |= AUTOACK; + } else { + reg &= ~(AUTOACK); + } + + setreg(CC2420_MDMCTRL0, reg); + RELEASE_LOCK(); +} +/*---------------------------------------------------------------------------*/ +/* Set or unset frame filtering */ +static void +set_frame_filtering(uint8_t enable) +{ + GET_LOCK(); + + /* Turn on/off address decoding. */ + uint16_t reg = getreg(CC2420_MDMCTRL0); + if(enable) { + reg |= ADR_DECODE; + } else { + reg &= ~(ADR_DECODE); + } + + setreg(CC2420_MDMCTRL0, reg); + RELEASE_LOCK(); +} +/*---------------------------------------------------------------------------*/ +/* Enable or disable radio interrupts (both FIFOP and SFD timer capture) */ +static void +set_poll_mode(uint8_t enable) +{ + GET_LOCK(); + poll_mode = enable; + if(enable) { + /* Disable FIFOP interrupt */ + CC2420_CLEAR_FIFOP_INT(); + CC2420_DISABLE_FIFOP_INT(); + } else { + /* Initialize and enable FIFOP interrupt */ + CC2420_FIFOP_INT_INIT(); + CC2420_ENABLE_FIFOP_INT(); + CC2420_CLEAR_FIFOP_INT(); + } + RELEASE_LOCK(); +} +/*---------------------------------------------------------------------------*/ +/* Enable or disable CCA before sending */ +static void +set_send_on_cca(uint8_t enable) +{ + send_on_cca = enable; +} +/*---------------------------------------------------------------------------*/ diff --git a/dev/cc2420/cc2420.h b/dev/cc2420/cc2420.h index 0aaacae27..985fc4213 100644 --- a/dev/cc2420/cc2420.h +++ b/dev/cc2420/cc2420.h @@ -36,6 +36,7 @@ * \author * Adam Dunkels * Joakim Eriksson + * Konrad Krentz */ #ifndef CC2420_H_ @@ -45,6 +46,7 @@ #include "dev/spi.h" #include "dev/radio.h" #include "cc2420_const.h" +#include "lib/aes-128.h" int cc2420_init(void); @@ -88,116 +90,6 @@ int cc2420_off(void); void cc2420_set_cca_threshold(int value); -/************************************************************************/ -/* Additional SPI Macros for the CC2420 */ -/************************************************************************/ -/* Send a strobe to the CC2420 */ -#define CC2420_STROBE(s) \ - do { \ - CC2420_SPI_ENABLE(); \ - SPI_WRITE(s); \ - CC2420_SPI_DISABLE(); \ - } while (0) - -/* Write to a register in the CC2420 */ -/* Note: the SPI_WRITE(0) seems to be needed for getting the */ -/* write reg working on the Z1 / MSP430X platform */ -#define CC2420_WRITE_REG(adr,data) \ - do { \ - CC2420_SPI_ENABLE(); \ - SPI_WRITE_FAST(adr); \ - SPI_WRITE_FAST((uint8_t)((data) >> 8)); \ - SPI_WRITE_FAST((uint8_t)(data & 0xff)); \ - SPI_WAITFORTx_ENDED(); \ - SPI_WRITE(0); \ - CC2420_SPI_DISABLE(); \ - } while(0) - -/* Read a register in the CC2420 */ -#define CC2420_READ_REG(adr,data) \ - do { \ - CC2420_SPI_ENABLE(); \ - SPI_WRITE(adr | 0x40); \ - data = (uint8_t)SPI_RXBUF; \ - SPI_TXBUF = 0; \ - SPI_WAITFOREORx(); \ - data = SPI_RXBUF << 8; \ - SPI_TXBUF = 0; \ - SPI_WAITFOREORx(); \ - data |= SPI_RXBUF; \ - CC2420_SPI_DISABLE(); \ - } while(0) - -#define CC2420_READ_FIFO_BYTE(data) \ - do { \ - CC2420_SPI_ENABLE(); \ - SPI_WRITE(CC2420_RXFIFO | 0x40); \ - (void)SPI_RXBUF; \ - SPI_READ(data); \ - clock_delay(1); \ - CC2420_SPI_DISABLE(); \ - } while(0) - -#define CC2420_READ_FIFO_BUF(buffer,count) \ - do { \ - uint8_t i; \ - CC2420_SPI_ENABLE(); \ - SPI_WRITE(CC2420_RXFIFO | 0x40); \ - (void)SPI_RXBUF; \ - for(i = 0; i < (count); i++) { \ - SPI_READ(((uint8_t *)(buffer))[i]); \ - } \ - clock_delay(1); \ - CC2420_SPI_DISABLE(); \ - } while(0) - -#define CC2420_WRITE_FIFO_BUF(buffer,count) \ - do { \ - uint8_t i; \ - CC2420_SPI_ENABLE(); \ - SPI_WRITE_FAST(CC2420_TXFIFO); \ - for(i = 0; i < (count); i++) { \ - SPI_WRITE_FAST(((uint8_t *)(buffer))[i]); \ - } \ - SPI_WAITFORTx_ENDED(); \ - CC2420_SPI_DISABLE(); \ - } while(0) - -/* Write to RAM in the CC2420 */ -#define CC2420_WRITE_RAM(buffer,adr,count) \ - do { \ - uint8_t i; \ - CC2420_SPI_ENABLE(); \ - SPI_WRITE_FAST(0x80 | ((adr) & 0x7f)); \ - SPI_WRITE_FAST(((adr) >> 1) & 0xc0); \ - for(i = 0; i < (count); i++) { \ - SPI_WRITE_FAST(((uint8_t*)(buffer))[i]); \ - } \ - SPI_WAITFORTx_ENDED(); \ - CC2420_SPI_DISABLE(); \ - } while(0) - -/* Read from RAM in the CC2420 */ -#define CC2420_READ_RAM(buffer,adr,count) \ - do { \ - uint8_t i; \ - CC2420_SPI_ENABLE(); \ - SPI_WRITE(0x80 | ((adr) & 0x7f)); \ - SPI_WRITE((((adr) >> 1) & 0xc0) | 0x20); \ - SPI_RXBUF; \ - for(i = 0; i < (count); i++) { \ - SPI_READ(((uint8_t*)(buffer))[i]); \ - } \ - CC2420_SPI_DISABLE(); \ - } while(0) - -/* Read status of the CC2420 */ -#define CC2420_GET_STATUS(s) \ - do { \ - CC2420_SPI_ENABLE(); \ - SPI_WRITE(CC2420_SNOP); \ - s = SPI_RXBUF; \ - CC2420_SPI_DISABLE(); \ - } while (0) +extern const struct aes_128_driver cc2420_aes_128_driver; #endif /* CC2420_H_ */ diff --git a/dev/cc2520/cc2520.c b/dev/cc2520/cc2520.c index 561236b08..e0dad1b6a 100644 --- a/dev/cc2520/cc2520.c +++ b/dev/cc2520/cc2520.c @@ -115,6 +115,70 @@ static int cc2520_cca(void); signed char cc2520_last_rssi; uint8_t cc2520_last_correlation; +static uint8_t receive_on; +static int channel; + +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + if(!value) { + return RADIO_RESULT_INVALID_VALUE; + } + switch(param) { + case RADIO_PARAM_POWER_MODE: + *value = receive_on ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF; + return RADIO_RESULT_OK; + case RADIO_PARAM_CHANNEL: + *value = cc2520_get_channel(); + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MIN: + *value = 11; + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MAX: + *value = 26; + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} + +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + switch(param) { + case RADIO_PARAM_POWER_MODE: + if(value == RADIO_POWER_MODE_ON) { + cc2520_on(); + return RADIO_RESULT_OK; + } + if(value == RADIO_POWER_MODE_OFF) { + cc2520_off(); + return RADIO_RESULT_OK; + } + return RADIO_RESULT_INVALID_VALUE; + case RADIO_PARAM_CHANNEL: + if(value < 11 || value > 26) { + return RADIO_RESULT_INVALID_VALUE; + } + cc2520_set_channel(value); + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} + +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} + +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} + const struct radio_driver cc2520_driver = { cc2520_init, @@ -129,12 +193,12 @@ const struct radio_driver cc2520_driver = pending_packet, cc2520_on, cc2520_off, + get_value, + set_value, + get_object, + set_object }; -static uint8_t receive_on; - -static int channel; - /*---------------------------------------------------------------------------*/ static void @@ -153,6 +217,8 @@ flushrx(void) uint8_t dummy; CC2520_READ_FIFO_BYTE(dummy); + /* read and discard dummy to avoid "variable set but not used" warning */ + (void)dummy; CC2520_STROBE(CC2520_INS_SFLUSHRX); CC2520_STROBE(CC2520_INS_SFLUSHRX); } @@ -371,6 +437,7 @@ cc2520_transmit(unsigned short payload_len) #endif /* WITH_SEND_CCA */ for(i = LOOP_20_SYMBOLS; i > 0; i--) { if(CC2520_SFD_IS_1) { +#if PACKETBUF_WITH_PACKET_TYPE { rtimer_clock_t sfd_timestamp; sfd_timestamp = cc2520_sfd_start_time; @@ -380,6 +447,7 @@ cc2520_transmit(unsigned short payload_len) CC2520_WRITE_RAM(&sfd_timestamp, CC2520RAM_TXFIFO + payload_len - 1, 2); } } +#endif /* PACKETBUF_WITH_PACKET_TYPE */ if(!(status() & BV(CC2520_TX_ACTIVE))) { /* SFD went high but we are not transmitting. This means that diff --git a/dev/cc2520/cc2520.h b/dev/cc2520/cc2520.h index 18a43649a..3c8e654ef 100644 --- a/dev/cc2520/cc2520.h +++ b/dev/cc2520/cc2520.h @@ -118,6 +118,7 @@ void cc2520_set_cca_threshold(int value); CC2520_SPI_ENABLE(); \ SPI_WRITE((CC2520_INS_MEMRD | ((adr>>8)&0xFF))); \ SPI_WRITE((adr & 0xFF)); \ + (void)SPI_RXBUF; \ SPI_READ(data); \ CC2520_SPI_DISABLE(); \ } while(0) diff --git a/dev/enc28j60/enc28j60-ip64-driver.c b/dev/enc28j60/enc28j60-ip64-driver.c new file mode 100644 index 000000000..71ed22739 --- /dev/null +++ b/dev/enc28j60/enc28j60-ip64-driver.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2012-2013, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + */ + +#include "contiki.h" +#include "enc28j60.h" +#include "enc28j60-ip64-driver.h" + +#include "ip64.h" +#include "ip64-eth.h" +#include "rime.h" + +#include +#include + +PROCESS(enc28j60_ip64_driver_process, "ENC28J60 IP64 driver"); + +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + uint8_t eui64[8]; + uint8_t macaddr[6]; + + /* Assume that linkaddr_node_addr holds the EUI64 of this device. */ + memcpy(eui64, &linkaddr_node_addr, sizeof(eui64)); + + /* Mangle the EUI64 into a 48-bit Ethernet address. */ + memcpy(&macaddr[0], &eui64[0], 3); + memcpy(&macaddr[3], &eui64[5], 3); + + /* In case the OUI happens to contain a broadcast bit, we mask that + out here. */ + macaddr[0] = (macaddr[0] & 0xfe); + + /* Set the U/L bit, in order to create a locally administered MAC address */ + macaddr[0] = (macaddr[0] | 0x02); + + memcpy(ip64_eth_addr.addr, macaddr, sizeof(macaddr)); + + printf("MAC addr %02x:%02x:%02x:%02x:%02x:%02x\n", + macaddr[0], macaddr[1], macaddr[2], + macaddr[3], macaddr[4], macaddr[5]); + enc28j60_init(macaddr); + process_start(&enc28j60_ip64_driver_process, NULL); +} +/*---------------------------------------------------------------------------*/ +static int +output(uint8_t *packet, uint16_t len) +{ + enc28j60_send(packet, len); + return len; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(enc28j60_ip64_driver_process, ev, data) +{ + static int len; + static struct etimer e; + PROCESS_BEGIN(); + + while(1) { + etimer_set(&e, 1); + PROCESS_WAIT_EVENT(); + len = enc28j60_read(ip64_packet_buffer, ip64_packet_buffer_maxlen); + if(len > 0) { + IP64_INPUT(ip64_packet_buffer, len); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +const struct ip64_driver enc28j60_ip64_driver = { + init, + output +}; +/*---------------------------------------------------------------------------*/ diff --git a/dev/enc28j60/enc28j60-ip64-driver.h b/dev/enc28j60/enc28j60-ip64-driver.h new file mode 100644 index 000000000..29d3ed5a4 --- /dev/null +++ b/dev/enc28j60/enc28j60-ip64-driver.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2012-2013, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + */ + +#ifndef ENC28J60_IP64_DRIVER_H +#define ENC28J60_IP64_DRIVER_H + +#include "ip64-driver.h" +extern const struct ip64_driver enc28j60_ip64_driver; + +#endif /* ENC28J60_IP64_DRIVER_H */ diff --git a/dev/enc28j60/enc28j60.c b/dev/enc28j60/enc28j60.c new file mode 100644 index 000000000..6d7704e7f --- /dev/null +++ b/dev/enc28j60/enc28j60.c @@ -0,0 +1,692 @@ +/* + * Copyright (c) 2012-2013, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + */ + +#include "contiki.h" +#include "enc28j60.h" +#include +#include + +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#define EIE 0x1b +#define EIR 0x1c +#define ESTAT 0x1d +#define ECON2 0x1e +#define ECON1 0x1f + +#define ESTAT_CLKRDY 0x01 +#define ESTAT_TXABRT 0x02 + +#define ECON1_RXEN 0x04 +#define ECON1_TXRTS 0x08 + +#define ECON2_AUTOINC 0x80 +#define ECON2_PKTDEC 0x40 + +#define EIR_TXIF 0x08 + +#define ERXTX_BANK 0x00 + +#define ERDPTL 0x00 +#define ERDPTH 0x01 +#define EWRPTL 0x02 +#define EWRPTH 0x03 +#define ETXSTL 0x04 +#define ETXSTH 0x05 +#define ETXNDL 0x06 +#define ETXNDH 0x07 +#define ERXSTL 0x08 +#define ERXSTH 0x09 +#define ERXNDL 0x0a +#define ERXNDH 0x0b +#define ERXRDPTL 0x0c +#define ERXRDPTH 0x0d + +#define RX_BUF_START 0x0000 +#define RX_BUF_END 0x0fff + +#define TX_BUF_START 0x1200 + +/* MACONx registers are in bank 2 */ +#define MACONX_BANK 0x02 + +#define MACON1 0x00 +#define MACON3 0x02 +#define MACON4 0x03 +#define MABBIPG 0x04 +#define MAIPGL 0x06 +#define MAIPGH 0x07 +#define MAMXFLL 0x0a +#define MAMXFLH 0x0b + +#define MACON1_TXPAUS 0x08 +#define MACON1_RXPAUS 0x04 +#define MACON1_MARXEN 0x01 + +#define MACON3_PADCFG_FULL 0xe0 +#define MACON3_TXCRCEN 0x10 +#define MACON3_FRMLNEN 0x02 +#define MACON3_FULDPX 0x01 + +#define MAX_MAC_LENGTH 1518 + +#define MAADRX_BANK 0x03 +#define MAADR1 0x04 /* MAADR<47:40> */ +#define MAADR2 0x05 /* MAADR<39:32> */ +#define MAADR3 0x02 /* MAADR<31:24> */ +#define MAADR4 0x03 /* MAADR<23:16> */ +#define MAADR5 0x00 /* MAADR<15:8> */ +#define MAADR6 0x01 /* MAADR<7:0> */ +#define MISTAT 0x0a +#define EREVID 0x12 + +#define EPKTCNT_BANK 0x01 +#define ERXFCON 0x18 +#define EPKTCNT 0x19 + +#define ERXFCON_UCEN 0x80 +#define ERXFCON_ANDOR 0x40 +#define ERXFCON_CRCEN 0x20 +#define ERXFCON_MCEN 0x02 +#define ERXFCON_BCEN 0x01 + + +PROCESS(enc_watchdog_process, "Enc28j60 watchdog"); + +static uint8_t initialized = 0; +static uint8_t bank = ERXTX_BANK; +static uint8_t enc_mac_addr[6]; +static int received_packets = 0; +static int sent_packets = 0; + +/*---------------------------------------------------------------------------*/ +static uint8_t +is_mac_mii_reg(uint8_t reg) +{ + /* MAC or MII register (otherwise, ETH register)? */ + switch(bank) { + case MACONX_BANK: + return reg < EIE; + case MAADRX_BANK: + return reg <= MAADR2 || reg == MISTAT; + case ERXTX_BANK: + case EPKTCNT_BANK: + default: + return 0; + } +} +/*---------------------------------------------------------------------------*/ +static uint8_t +readreg(uint8_t reg) +{ + uint8_t r; + enc28j60_arch_spi_select(); + enc28j60_arch_spi_write(0x00 | (reg & 0x1f)); + if(is_mac_mii_reg(reg)) { + /* MAC and MII registers require that a dummy byte be read first. */ + enc28j60_arch_spi_read(); + } + r = enc28j60_arch_spi_read(); + enc28j60_arch_spi_deselect(); + return r; +} +/*---------------------------------------------------------------------------*/ +static void +writereg(uint8_t reg, uint8_t data) +{ + enc28j60_arch_spi_select(); + enc28j60_arch_spi_write(0x40 | (reg & 0x1f)); + enc28j60_arch_spi_write(data); + enc28j60_arch_spi_deselect(); +} +/*---------------------------------------------------------------------------*/ +static void +setregbitfield(uint8_t reg, uint8_t mask) +{ + if(is_mac_mii_reg(reg)) { + writereg(reg, readreg(reg) | mask); + } else { + enc28j60_arch_spi_select(); + enc28j60_arch_spi_write(0x80 | (reg & 0x1f)); + enc28j60_arch_spi_write(mask); + enc28j60_arch_spi_deselect(); + } +} +/*---------------------------------------------------------------------------*/ +static void +clearregbitfield(uint8_t reg, uint8_t mask) +{ + if(is_mac_mii_reg(reg)) { + writereg(reg, readreg(reg) & ~mask); + } else { + enc28j60_arch_spi_select(); + enc28j60_arch_spi_write(0xa0 | (reg & 0x1f)); + enc28j60_arch_spi_write(mask); + enc28j60_arch_spi_deselect(); + } +} +/*---------------------------------------------------------------------------*/ +static void +setregbank(uint8_t new_bank) +{ + writereg(ECON1, (readreg(ECON1) & 0xfc) | (new_bank & 0x03)); + bank = new_bank; +} +/*---------------------------------------------------------------------------*/ +static void +writedata(const uint8_t *data, int datalen) +{ + int i; + enc28j60_arch_spi_select(); + /* The Write Buffer Memory (WBM) command is 0 1 1 1 1 0 1 0 */ + enc28j60_arch_spi_write(0x7a); + for(i = 0; i < datalen; i++) { + enc28j60_arch_spi_write(data[i]); + } + enc28j60_arch_spi_deselect(); +} +/*---------------------------------------------------------------------------*/ +static void +writedatabyte(uint8_t byte) +{ + writedata(&byte, 1); +} +/*---------------------------------------------------------------------------*/ +static int +readdata(uint8_t *buf, int len) +{ + int i; + enc28j60_arch_spi_select(); + /* THe Read Buffer Memory (RBM) command is 0 0 1 1 1 0 1 0 */ + enc28j60_arch_spi_write(0x3a); + for(i = 0; i < len; i++) { + buf[i] = enc28j60_arch_spi_read(); + } + enc28j60_arch_spi_deselect(); + return i; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +readdatabyte(void) +{ + uint8_t r; + readdata(&r, 1); + return r; +} +/*---------------------------------------------------------------------------*/ +static void +softreset(void) +{ + enc28j60_arch_spi_select(); + /* The System Command (soft reset) is 1 1 1 1 1 1 1 1 */ + enc28j60_arch_spi_write(0xff); + enc28j60_arch_spi_deselect(); + bank = ERXTX_BANK; +} +/*---------------------------------------------------------------------------*/ +#if DEBUG +static uint8_t +readrev(void) +{ + uint8_t rev; + setregbank(MAADRX_BANK); + rev = readreg(EREVID); + switch(rev) { + case 2: + return 1; + case 6: + return 7; + default: + return rev; + } +} +#endif +/*---------------------------------------------------------------------------*/ +static void +reset(void) +{ + PRINTF("enc28j60: resetting chip\n"); + + enc28j60_arch_spi_init(); + + /* + 6.0 INITIALIZATION + + Before the ENC28J60 can be used to transmit and receive packets, + certain device settings must be initialized. Depending on the + application, some configuration options may need to be + changed. Normally, these tasks may be accomplished once after + Reset and do not need to be changed thereafter. + + 6.1 Receive Buffer + + Before receiving any packets, the receive buffer must be + initialized by programming the ERXST and ERXND pointers. All + memory between and including the ERXST and ERXND addresses will be + dedicated to the receive hardware. It is recommended that the + ERXST pointer be programmed with an even address. + + Applications expecting large amounts of data and frequent packet + delivery may wish to allocate most of the memory as the receive + buffer. Applications that may need to save older packets or have + several packets ready for transmission should allocate less + memory. + + When programming the ERXST pointer, the ERXWRPT registers will + automatically be updated with the same values. The address in + ERXWRPT will be used as the starting location when the receive + hardware begins writing received data. For tracking purposes, the + ERXRDPT registers should additionally be programmed with the same + value. To program ERXRDPT, the host controller must write to + ERXRDPTL first, followed by ERXRDPTH. See Section 7.2.4 “Freeing + Receive Buffer Space for more information + + 6.2 Transmission Buffer + + All memory which is not used by the receive buffer is considered + the transmission buffer. Data which is to be transmitted should be + written into any unused space. After a packet is transmitted, + however, the hardware will write a seven-byte status vector into + memory after the last byte in the packet. Therefore, the host + controller should leave at least seven bytes between each packet + and the beginning of the receive buffer. No explicit action is + required to initialize the transmission buffer. + + 6.3 Receive Filters + + The appropriate receive filters should be enabled or disabled by + writing to the ERXFCON register. See Section 8.0 “Receive Filters + for information on how to configure it. + + 6.4 Waiting For OST + + If the initialization procedure is being executed immediately + following a Power-on Reset, the ESTAT.CLKRDY bit should be polled + to make certain that enough time has elapsed before proceeding to + modify the MAC and PHY registers. For more information on the OST, + see Section 2.2 “Oscillator Start-up Timer. + */ + + softreset(); + + /* Workaround for erratum #2. */ + clock_delay_usec(1000); + + /* Wait for OST */ + while((readreg(ESTAT) & ESTAT_CLKRDY) == 0); + + setregbank(ERXTX_BANK); + /* Set up receive buffer */ + writereg(ERXSTL, RX_BUF_START & 0xff); + writereg(ERXSTH, RX_BUF_START >> 8); + writereg(ERXNDL, RX_BUF_END & 0xff); + writereg(ERXNDH, RX_BUF_END >> 8); + writereg(ERDPTL, RX_BUF_START & 0xff); + writereg(ERDPTH, RX_BUF_START >> 8); + writereg(ERXRDPTL, RX_BUF_END & 0xff); + writereg(ERXRDPTH, RX_BUF_END >> 8); + + /* Receive filters */ + setregbank(EPKTCNT_BANK); + writereg(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_BCEN); + + /* + 6.5 MAC Initialization Settings + + Several of the MAC registers require configuration during + initialization. This only needs to be done once; the order of + programming is unimportant. + + 1. Set the MARXEN bit in MACON1 to enable the MAC to receive + frames. If using full duplex, most applications should also set + TXPAUS and RXPAUS to allow IEEE defined flow control to function. + + 2. Configure the PADCFG, TXCRCEN and FULDPX bits of MACON3. Most + applications should enable automatic padding to at least 60 bytes + and always append a valid CRC. For convenience, many applications + may wish to set the FRMLNEN bit as well to enable frame length + status reporting. The FULDPX bit should be set if the application + will be connected to a full-duplex configured remote node; + otherwise, it should be left clear. + + 3. Configure the bits in MACON4. For conformance to the IEEE 802.3 + standard, set the DEFER bit. + + 4. Program the MAMXFL registers with the maximum frame length to + be permitted to be received or transmitted. Normal network nodes + are designed to handle packets that are 1518 bytes or less. + + 5. Configure the Back-to-Back Inter-Packet Gap register, + MABBIPG. Most applications will program this register with 15h + when Full-Duplex mode is used and 12h when Half-Duplex mode is + used. + + 6. Configure the Non-Back-to-Back Inter-Packet Gap register low + byte, MAIPGL. Most applications will program this register with + 12h. + + 7. If half duplex is used, the Non-Back-to-Back Inter-Packet Gap + register high byte, MAIPGH, should be programmed. Most + applications will program this register to 0Ch. + + 8. If Half-Duplex mode is used, program the Retransmission and + Collision Window registers, MACLCON1 and MACLCON2. Most + applications will not need to change the default Reset values. If + the network is spread over exceptionally long cables, the default + value of MACLCON2 may need to be increased. + + 9. Program the local MAC address into the MAADR1:MAADR6 registers. + */ + + setregbank(MACONX_BANK); + + /* Turn on reception and IEEE-defined flow control */ + setregbitfield(MACON1, MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS); + + /* Set padding, crc, full duplex */ + setregbitfield(MACON3, MACON3_PADCFG_FULL | MACON3_TXCRCEN | MACON3_FULDPX | + MACON3_FRMLNEN); + + /* Don't modify MACON4 */ + + /* Set maximum frame length in MAMXFL */ + writereg(MAMXFLL, MAX_MAC_LENGTH & 0xff); + writereg(MAMXFLH, MAX_MAC_LENGTH >> 8); + + /* Set back-to-back inter packet gap */ + writereg(MABBIPG, 0x15); + + /* Set non-back-to-back packet gap */ + writereg(MAIPGL, 0x12); + + /* Set MAC address */ + setregbank(MAADRX_BANK); + writereg(MAADR6, enc_mac_addr[5]); + writereg(MAADR5, enc_mac_addr[4]); + writereg(MAADR4, enc_mac_addr[3]); + writereg(MAADR3, enc_mac_addr[2]); + writereg(MAADR2, enc_mac_addr[1]); + writereg(MAADR1, enc_mac_addr[0]); + + /* + 6.6 PHY Initialization Settings + + Depending on the application, bits in three of the PHY module’s + registers may also require configuration. The PHCON1.PDPXMD bit + partially controls the device’s half/full-duplex + configuration. Normally, this bit is initialized correctly by the + external circuitry (see Section 2.6 “LED Configuration). If the + external circuitry is not present or incorrect, however, the host + controller must program the bit properly. Alternatively, for an + externally configurable system, the PDPXMD bit may be read and the + FULDPX bit be programmed to match. + + For proper duplex operation, the PHCON1.PDPXMD bit must also match + the value of the MACON3.FULDPX bit. + + If using half duplex, the host controller may wish to set the + PHCON2.HDLDIS bit to prevent automatic loopback of the data which + is transmitted. The PHY register, PHLCON, controls the outputs of + LEDA and LEDB. If an application requires a LED configuration + other than the default, PHLCON must be altered to match the new + requirements. The settings for LED operation are discussed in + Section 2.6 “LED Configuration. The PHLCON register is shown in + Register 2-2 (page 9). + */ + + /* Don't worry about PHY configuration for now */ + + /* Turn on autoincrement for buffer access */ + setregbitfield(ECON2, ECON2_AUTOINC); + + /* Turn on reception */ + writereg(ECON1, ECON1_RXEN); +} +/*---------------------------------------------------------------------------*/ +void +enc28j60_init(const uint8_t *mac_addr) +{ + if(initialized) { + return; + } + + memcpy(enc_mac_addr, mac_addr, 6); + + /* Start watchdog process */ + process_start(&enc_watchdog_process, NULL); + + reset(); + + PRINTF("ENC28J60 rev. B%d\n", readrev()); + + initialized = 1; +} +/*---------------------------------------------------------------------------*/ +int +enc28j60_send(const uint8_t *data, uint16_t datalen) +{ + uint16_t dataend; + + if(!initialized) { + return -1; + } + + /* + 1. Appropriately program the ETXST pointer to point to an unused + location in memory. It will point to the per packet control + byte. In the example, it would be programmed to 0120h. It is + recommended that an even address be used for ETXST. + + 2. Use the WBM SPI command to write the per packet control byte, + the destination address, the source MAC address, the + type/length and the data payload. + + 3. Appropriately program the ETXND pointer. It should point to the + last byte in the data payload. In the example, it would be + programmed to 0156h. + + 4. Clear EIR.TXIF, set EIE.TXIE and set EIE.INTIE to enable an + interrupt when done (if desired). + + 5. Start the transmission process by setting + ECON1.TXRTS. + */ + + setregbank(ERXTX_BANK); + /* Set up the transmit buffer pointer */ + writereg(ETXSTL, TX_BUF_START & 0xff); + writereg(ETXSTH, TX_BUF_START >> 8); + writereg(EWRPTL, TX_BUF_START & 0xff); + writereg(EWRPTH, TX_BUF_START >> 8); + + /* Write the transmission control register as the first byte of the + output packet. We write 0x00 to indicate that the default + configuration (the values in MACON3) will be used. */ + writedatabyte(0x00); /* MACON3 */ + + writedata(data, datalen); + + /* Write a pointer to the last data byte. */ + dataend = TX_BUF_START + datalen; + writereg(ETXNDL, dataend & 0xff); + writereg(ETXNDH, dataend >> 8); + + /* Clear EIR.TXIF */ + clearregbitfield(EIR, EIR_TXIF); + + /* Don't care about interrupts for now */ + + /* Send the packet */ + setregbitfield(ECON1, ECON1_TXRTS); + while((readreg(ECON1) & ECON1_TXRTS) > 0); + +#if DEBUG + if((readreg(ESTAT) & ESTAT_TXABRT) != 0) { + uint16_t erdpt; + uint8_t tsv[7]; + erdpt = (readreg(ERDPTH) << 8) | readreg(ERDPTL); + writereg(ERDPTL, (dataend + 1) & 0xff); + writereg(ERDPTH, (dataend + 1) >> 8); + readdata(tsv, sizeof(tsv)); + writereg(ERDPTL, erdpt & 0xff); + writereg(ERDPTH, erdpt >> 8); + PRINTF("enc28j60: tx err: %d: %02x:%02x:%02x:%02x:%02x:%02x\n" + " tsv: %02x%02x%02x%02x%02x%02x%02x\n", datalen, + 0xff & data[0], 0xff & data[1], 0xff & data[2], + 0xff & data[3], 0xff & data[4], 0xff & data[5], + tsv[6], tsv[5], tsv[4], tsv[3], tsv[2], tsv[1], tsv[0]); + } else { + PRINTF("enc28j60: tx: %d: %02x:%02x:%02x:%02x:%02x:%02x\n", datalen, + 0xff & data[0], 0xff & data[1], 0xff & data[2], + 0xff & data[3], 0xff & data[4], 0xff & data[5]); + } +#endif + + sent_packets++; + PRINTF("enc28j60: sent_packets %d\n", sent_packets); + return datalen; +} +/*---------------------------------------------------------------------------*/ +int +enc28j60_read(uint8_t *buffer, uint16_t bufsize) +{ + int n, len, next, err; + + uint8_t nxtpkt[2]; + uint8_t status[2]; + uint8_t length[2]; + + if(!initialized) { + return -1; + } + + err = 0; + + setregbank(EPKTCNT_BANK); + n = readreg(EPKTCNT); + + if(n == 0) { + return 0; + } + + PRINTF("enc28j60: EPKTCNT 0x%02x\n", n); + + setregbank(ERXTX_BANK); + /* Read the next packet pointer */ + nxtpkt[0] = readdatabyte(); + nxtpkt[1] = readdatabyte(); + + PRINTF("enc28j60: nxtpkt 0x%02x%02x\n", nxtpkt[1], nxtpkt[0]); + + length[0] = readdatabyte(); + length[1] = readdatabyte(); + + PRINTF("enc28j60: length 0x%02x%02x\n", length[1], length[0]); + + status[0] = readdatabyte(); + status[1] = readdatabyte(); + + /* This statement is just to avoid a compiler warning: */ + status[0] = status[0]; + PRINTF("enc28j60: status 0x%02x%02x\n", status[1], status[0]); + + len = (length[1] << 8) + length[0]; + if(bufsize >= len) { + readdata(buffer, len); + } else { + uint16_t i; + + err = 1; + + /* flush rx fifo */ + for(i = 0; i < len; i++) { + readdatabyte(); + } + } + + /* Read an additional byte at odd lengths, to avoid FIFO corruption */ + if((len % 2) != 0) { + readdatabyte(); + } + + /* Errata #14 */ + next = (nxtpkt[1] << 8) + nxtpkt[0]; + if(next == RX_BUF_START) { + next = RX_BUF_END; + } else { + next = next - 1; + } + writereg(ERXRDPTL, next & 0xff); + writereg(ERXRDPTH, next >> 8); + + setregbitfield(ECON2, ECON2_PKTDEC); + + if(err) { + PRINTF("enc28j60: rx err: flushed %d\n", len); + return 0; + } + PRINTF("enc28j60: rx: %d: %02x:%02x:%02x:%02x:%02x:%02x\n", len, + 0xff & buffer[0], 0xff & buffer[1], 0xff & buffer[2], + 0xff & buffer[3], 0xff & buffer[4], 0xff & buffer[5]); + + received_packets++; + PRINTF("enc28j60: received_packets %d\n", received_packets); + return len; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(enc_watchdog_process, ev, data) +{ + static struct etimer et; + + PROCESS_BEGIN(); + + while(1) { +#define RESET_PERIOD (30 * CLOCK_SECOND) + etimer_set(&et, RESET_PERIOD); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + PRINTF("enc28j60: test received_packet %d > sent_packets %d\n", received_packets, sent_packets); + if(received_packets <= sent_packets) { + PRINTF("enc28j60: resetting chip\n"); + reset(); + } + received_packets = 0; + sent_packets = 0; + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/dev/enc28j60/enc28j60.h b/dev/enc28j60/enc28j60.h new file mode 100644 index 000000000..473cceca4 --- /dev/null +++ b/dev/enc28j60/enc28j60.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012-2013, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + */ + +#ifndef ENC28J60_H +#define ENC28J60_H + +void enc28j60_init(const uint8_t *mac_addr); + +int enc28j60_send(const uint8_t *data, uint16_t datalen); + +int enc28j60_read(uint8_t *buffer, uint16_t bufsize); + +/* ENC28J60 architecture-specific SPI functions that are called by the + enc28j60 driver and must be implemented by the platform code */ + +void enc28j60_arch_spi_init(void); +uint8_t enc28j60_arch_spi_write(uint8_t data); +uint8_t enc28j60_arch_spi_read(void); +void enc28j60_arch_spi_select(void); +void enc28j60_arch_spi_deselect(void); + + +#endif /* ENC28J60_H */ diff --git a/dev/sht11/sht11.c b/dev/sht11/sht11.c index f6780d0a0..670d10d91 100644 --- a/dev/sht11/sht11.c +++ b/dev/sht11/sht11.c @@ -215,7 +215,6 @@ sht11_init(void) This assumes the SDA/SCL pins passed in the -arch.h file are actually the same used for I2C operation, else comment out the following */ - #warning SHT11: DISABLING I2C BUS SHT11_PxSEL &= ~(BV(SHT11_ARCH_SDA) | BV(SHT11_ARCH_SCL)); #if defined(__MSP430_HAS_MSP430X_CPU__) || defined(__MSP430_HAS_MSP430XV2_CPU__) SHT11_PxREN &= ~(BV(SHT11_ARCH_SDA) | BV(SHT11_ARCH_SCL)); diff --git a/doc/Doxyfile b/doc/Doxyfile index cd6b1235b..056018d13 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -1,110 +1,129 @@ -# Doxyfile 1.8.1.2 +# Doxyfile 1.8.8 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # -# All text after a hash (#) is considered a comment and will be ignored. +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. # The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" "). +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 -# The PROJECT_NAME tag is a single word (or sequence of words) that should -# identify the project. Note that if you do not use Doxywizard you need -# to put quotes around the project name if it contains spaces. +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. PROJECT_NAME = "Contiki 3.x" -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. +# With the PROJECT_LOGO tag one can specify an logo or icon that is included in +# the documentation. The maximum height of the logo should not exceed 55 pixels +# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo +# to the output directory. PROJECT_LOGO = -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. OUTPUT_DIRECTORY = . -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. CREATE_SUBDIRS = NO +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. +# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. +# The default value is: YES. REPEAT_BRIEF = YES -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief +# doxygen will generate a detailed section even if there is only a brief # description. +# The default value is: NO. ALWAYS_DETAILED_SEC = NO @@ -112,169 +131,207 @@ ALWAYS_DETAILED_SEC = NO # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. +# The default value is: NO. INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. +# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. FULL_PATH_NAMES = YES -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = $(docroot) -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. STRIP_FROM_INC_PATH = $(docroot) -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. SHORT_NAMES = YES -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. JAVADOC_AUTOBRIEF = YES -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. QT_AUTOBRIEF = NO -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a +# new page for each member. If set to NO, the documentation of a member will be +# part of the file/class/namespace that contains it. +# The default value is: NO. SEPARATE_MEMBER_PAGES = NO -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 8 -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding -# "class=itcl::class" will allow you to use the command class in the -# itcl::class meaning. +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. TCL_SUBST = -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = YES -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this -# tag. The format is ext=language, where ext is a file extension, and language -# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, -# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions -# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. EXTENSION_MAPPING = -# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all -# comments according to the Markdown format, which allows for more readable +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you -# can mix doxygen, HTML, and XML commands with Markdown formatting. -# Disable only in case of backward compatibilities issues. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. MARKDOWN_SUPPORT = YES +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. +# The default value is: NO. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. +# The default value is: NO. CPP_CLI_SUPPORT = NO -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. SIP_SUPPORT = NO -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. IDL_PROPERTY_SUPPORT = YES @@ -282,67 +339,61 @@ IDL_PROPERTY_SUPPORT = YES # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. +# The default value is: NO. DISTRIBUTE_GROUP_DOC = NO -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. SUBGROUPING = YES -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. INLINE_GROUPED_CLASSES = NO -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and -# unions with only public data fields will be shown inline in the documentation -# of the scope in which they are defined (i.e. file, namespace, or group -# documentation), provided this scope is documented. If set to NO (the default), -# structs, classes, and unions are shown on a separate page (for HTML and Man -# pages) or section (for LaTeX and RTF). +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. INLINE_SIMPLE_STRUCTS = NO -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. TYPEDEF_HIDES_STRUCT = NO -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penalty. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will roughly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols. - -SYMBOL_CACHE_SIZE = 0 - -# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be -# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given -# their name and scope. Since this can be an expensive process and often the -# same symbol appear multiple times in the code, doxygen keeps a cache of -# pre-resolved symbols. If the cache is too small doxygen will become slower. -# If the cache is too large, memory is wasted. The cache size is given by this -# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols. +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 @@ -351,342 +402,392 @@ LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. EXTRACT_ALL = NO -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will +# be included in the documentation. +# The default value is: NO. EXTRACT_PRIVATE = NO -# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation. +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. EXTRACT_PACKAGE = NO -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. +# If the EXTRACT_STATIC tag is set to YES all static members of a file will be +# included in the documentation. +# The default value is: NO. -EXTRACT_STATIC = NO +EXTRACT_STATIC = YES -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. EXTRACT_LOCAL_CLASSES = NO -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. +# This flag is only useful for Objective-C code. When set to YES local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO only methods in the interface are +# included. +# The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. EXTRACT_ANON_NSPACES = NO -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. HIDE_UNDOC_MEMBERS = YES -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO these classes will be included in the various overviews. This option has +# no effect if EXTRACT_ALL is enabled. +# The default value is: NO. HIDE_UNDOC_CLASSES = YES -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO these declarations will be +# included in the documentation. +# The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. HIDE_IN_BODY_DOCS = NO -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. INTERNAL_DOCS = NO -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. +# The default value is: system dependent. CASE_SENSE_NAMES = YES -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES the +# scope will be hidden. +# The default value is: NO. HIDE_SCOPE_NAMES = NO -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. SHOW_INCLUDE_FILES = YES -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. FORCE_LOCAL_INCLUDES = NO -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. INLINE_INFO = YES -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. +# The default value is: YES. SORT_MEMBER_DOCS = YES -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. SORT_BRIEF_DOCS = NO -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. SORT_GROUP_NAMES = NO -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. SORT_BY_SCOPE_NAME = NO -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. STRICT_PROTO_MATCHING = NO -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. +# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the +# todo list. This list is created by putting \todo commands in the +# documentation. +# The default value is: YES. GENERATE_TODOLIST = YES -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. +# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the +# test list. This list is created by putting \test commands in the +# documentation. +# The default value is: YES. GENERATE_TESTLIST = YES -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. +# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. GENERATE_BUGLIST = NO -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. +# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. GENERATE_DEPRECATEDLIST= NO -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. ENABLED_SECTIONS = -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 30 -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES the list +# will mention the files that were used to generate the documentation. +# The default value is: YES. SHOW_USED_FILES = NO -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. SHOW_FILES = YES -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. LAYOUT_FILE = -# The CITE_BIB_FILES tag can be used to specify one or more bib files -# containing the references data. This must be a list of .bib files. The -# .bib extension is automatically appended if omitted. Using this command -# requires the bibtex tool to be installed. See also -# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style -# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this -# feature you need bibtex and perl available in the search path. +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- -# configuration options related to warning and progress messages +# Configuration options related to warning and progress messages #--------------------------------------------------------------------------- -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. +# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. WARNINGS = YES -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. +# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. WARN_IF_UNDOCUMENTED = NO -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. WARN_IF_DOC_ERROR = YES -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO doxygen will only warn about wrong or incomplete parameter +# documentation, but not about the absence of documentation. +# The default value is: NO. WARN_NO_PARAMDOC = NO -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). WARN_LOGFILE = doxygen.log #--------------------------------------------------------------------------- -# configuration options related to the input files +# Configuration options related to the input files #--------------------------------------------------------------------------- -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. +# Note: If this tag is empty the current directory is searched. INPUT = $(docsrc) # This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank the +# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, +# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, +# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, +# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, +# *.qsf, *.as and *.js. FILE_PATTERNS = *.h \ *.c \ *.doc.html \ *.txt -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. +# # Note that relative paths are relative to the directory from which doxygen is # run. @@ -695,773 +796,1102 @@ EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. +# The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = */cpu/cc26xx-cc13xx/lib/* \ + */cpu/cc26xx-cc13xx/rf-core/api/* \ + */platform/stm32nucleo-spirit1/stm32cube-lib/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). EXAMPLE_PATH = . \ ../examples/rime \ ../examples/multi-threading # If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. EXAMPLE_RECURSIVE = NO -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). IMAGE_PATH = pics # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). +# INPUT_FILTER ) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + #--------------------------------------------------------------------------- -# configuration options related to source browsing +# Configuration options related to source browsing #--------------------------------------------------------------------------- -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. SOURCE_BROWSER = YES -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. INLINE_SOURCES = NO -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C, C++ and Fortran comments will always remain visible. +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. STRIP_CODE_COMMENTS = NO -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. REFERENCED_BY_RELATION = YES -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. REFERENCES_RELATION = YES -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES, then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. REFERENCES_LINK_SOURCE = YES -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index +# Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. ALPHABETICAL_INDEX = YES -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. COLS_IN_ALPHA_INDEX = 5 -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- -# configuration options related to the HTML output +# Configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. +# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output +# The default value is: YES. GENERATE_HTML = YES -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is advised to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when -# changing the value of configuration settings such as GENERATE_TREEVIEW! +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# style sheet in the HTML output directory as well, or it will be erased! +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefor more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra stylesheet files is of importance (e.g. the last +# stylesheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the -# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the style sheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the stylesheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of -# entries shown in the various tree structured indices initially; the user -# can expand and collapse entries dynamically later on. Doxygen will expand -# the tree to such a level that at most the specified number of entries are -# visible (unless a fully collapsed tree already exceeds this amount). -# So setting the number of entries 1 will produce a full collapsed tree by -# default. 0 is a special value representing an infinite number of entries -# and will result in a full expanded tree by default. +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = YES -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be # written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler ( hhc.exe). If non-empty +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). +# The GENERATE_CHI flag controls if a separate .chi index file is generated ( +# YES) or that it should be included in the master .chm file ( NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = YES -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. +# The BINARY_TOC flag controls whether a binary table of contents is generated ( +# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = YES -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = YES # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = org.doxygen.Project -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project -# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) -# at top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. Since the tabs have the same information as the -# navigation tree you can set this option to NO if you already set -# GENERATE_TREEVIEW to YES. +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. -# Since the tree basically has the same information as the tab index you -# could consider to set DISABLE_INDEX to NO when enabling this option. +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. -GENERATE_TREEVIEW = YES +GENERATE_TREEVIEW = NO -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you may also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using prerendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to -# the MathJax Content Delivery Network so you can quickly see the result without -# installing MathJax. -# However, it is strongly recommended to install a local -# copy of MathJax from http://www.mathjax.org before deployment. +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest -# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension -# names that should be enabled during MathJax rendering. +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /
    "; +static const char config_div_right[] = "
    "; +static const char config_div_close[] = "
    "; +/*---------------------------------------------------------------------------*/ +static char generate_index(struct httpd_state *s); +static char generate_config(struct httpd_state *s); +/*---------------------------------------------------------------------------*/ +typedef struct page { + struct page *next; + char *filename; + char *title; + char (*script)(struct httpd_state *s); +} page_t; + +static page_t http_index_page = { + NULL, + "index.html", + "Index", + generate_index, +}; + +static page_t http_dev_cfg_page = { + NULL, + "config.html", + "Device Config", + generate_config, +}; + +#if CC26XX_WEB_DEMO_NET_UART +static char generate_net_uart_config(struct httpd_state *s); + +static page_t http_net_cfg_page = { + NULL, + "netu.html", + "Net-UART Config", + generate_net_uart_config, +}; +#endif + +#if CC26XX_WEB_DEMO_MQTT_CLIENT +static char generate_mqtt_config(struct httpd_state *s); + +static page_t http_mqtt_cfg_page = { + NULL, + "mqtt.html", + "MQTT/IBM Cloud Config", + generate_mqtt_config, +}; +#endif +/*---------------------------------------------------------------------------*/ +#define IBM_QUICKSTART_LINK_LEN 128 +static char http_mqtt_a[IBM_QUICKSTART_LINK_LEN]; +/*---------------------------------------------------------------------------*/ +static uint16_t numtimes; +static const httpd_simple_post_handler_t *handler; +/*---------------------------------------------------------------------------*/ +static uint8_t config_ok; +process_event_t httpd_simple_event_new_config; +/*---------------------------------------------------------------------------*/ +struct httpd_state; +typedef char (*httpd_simple_script_t)(struct httpd_state *s); + +struct httpd_state { + char buf[HTTPD_SIMPLE_MAIN_BUF_SIZE]; + char tmp_buf[TMP_BUF_SIZE]; + struct timer timer; + struct psock sin, sout; + int blen; + const char **ptr; + const cc26xx_web_demo_sensor_reading_t *reading; + const page_t *page; + uip_ds6_route_t *r; + uip_ds6_nbr_t *nbr; + httpd_simple_script_t script; + int content_length; + int tmp_buf_len; + int tmp_buf_copied; + char filename[HTTPD_PATHLEN]; + char inputbuf[HTTPD_INBUF_LEN]; + struct pt outputpt; + struct pt generate_pt; + struct pt top_matter_pt; + char state; + char request_type; + char return_code; +}; +/*---------------------------------------------------------------------------*/ +LIST(post_handlers); +LIST(pages_list); +MEMB(conns, struct httpd_state, CONNS); +/*---------------------------------------------------------------------------*/ +#define HEX_TO_INT(x) (isdigit(x) ? x - '0' : x - 'W') +static size_t +url_unescape(const char *src, size_t srclen, char *dst, size_t dstlen) +{ + size_t i, j; + int a, b; + + for(i = j = 0; i < srclen && j < dstlen - 1; i++, j++) { + if(src[i] == '%' && isxdigit(*(unsigned char *)(src + i + 1)) + && isxdigit(*(unsigned char *)(src + i + 2))) { + a = tolower(*(unsigned char *)(src + i + 1)); + b = tolower(*(unsigned char *)(src + i + 2)); + dst[j] = ((HEX_TO_INT(a) << 4) | HEX_TO_INT(b)) & 0xff; + i += 2; + } else if(src[i] == '+') { + dst[j] = ' '; + } else { + dst[j] = src[i]; + } + } + + dst[j] = '\0'; + + return i == srclen; +} +/*---------------------------------------------------------------------------*/ +void +httpd_simple_register_post_handler(httpd_simple_post_handler_t *h) +{ + list_add(post_handlers, h); +} +/*---------------------------------------------------------------------------*/ +static void +get_neighbour_state_text(char *buf, uint8_t state) +{ + switch(state) { + case NBR_INCOMPLETE: + memcpy(buf, "INCOMPLETE", strlen("INCOMPLETE")); + break; + case NBR_REACHABLE: + memcpy(buf, "REACHABLE", strlen("REACHABLE")); + break; + case NBR_STALE: + memcpy(buf, "STALE", strlen("STALE")); + break; + case NBR_DELAY: + memcpy(buf, "DELAY", strlen("DELAY")); + break; + case NBR_PROBE: + memcpy(buf, "NBR_PROBE", strlen("NBR_PROBE")); + break; + } +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(enqueue_chunk(struct httpd_state *s, uint8_t immediate, + const char *format, ...)) +{ + va_list ap; + + PSOCK_BEGIN(&s->sout); + + va_start(ap, format); + + s->tmp_buf_len = vsnprintf(s->tmp_buf, TMP_BUF_SIZE, format, ap); + + va_end(ap); + + if(s->blen + s->tmp_buf_len < HTTPD_SIMPLE_MAIN_BUF_SIZE) { + /* Enough space for the entire chunk. Copy over */ + memcpy(&s->buf[s->blen], s->tmp_buf, s->tmp_buf_len); + s->blen += s->tmp_buf_len; + } else { + memcpy(&s->buf[s->blen], s->tmp_buf, HTTPD_SIMPLE_MAIN_BUF_SIZE - s->blen); + s->tmp_buf_copied = HTTPD_SIMPLE_MAIN_BUF_SIZE - s->blen; + s->blen = HTTPD_SIMPLE_MAIN_BUF_SIZE; + PSOCK_SEND(&s->sout, (uint8_t *)s->buf, s->blen); + s->blen = 0; + if(s->tmp_buf_copied < s->tmp_buf_len) { + memcpy(s->buf, &s->tmp_buf[s->tmp_buf_copied], + s->tmp_buf_len - s->tmp_buf_copied); + s->blen += s->tmp_buf_len - s->tmp_buf_copied; + } + } + + if(immediate != 0 && s->blen > 0) { + PSOCK_SEND(&s->sout, (uint8_t *)s->buf, s->blen); + s->blen = 0; + } + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(generate_top_matter(struct httpd_state *s, const char *title, + const char **css)) +{ + + PT_BEGIN(&s->top_matter_pt); + + PT_WAIT_THREAD(&s->top_matter_pt, enqueue_chunk(s, 0, http_doctype)); + PT_WAIT_THREAD(&s->top_matter_pt, enqueue_chunk(s, 0, http_html_start)); + PT_WAIT_THREAD(&s->top_matter_pt, enqueue_chunk(s, 0, http_title_start)); + + PT_WAIT_THREAD(&s->top_matter_pt, enqueue_chunk(s, 0, title)); + PT_WAIT_THREAD(&s->top_matter_pt, enqueue_chunk(s, 0, http_title_end)); + + if(css != NULL) { + for(s->ptr = css; *(s->ptr) != NULL; s->ptr++) { + PT_WAIT_THREAD(&s->top_matter_pt, enqueue_chunk(s, 0, *(s->ptr))); + } + } + + PT_WAIT_THREAD(&s->top_matter_pt, enqueue_chunk(s, 0, http_head_charset)); + PT_WAIT_THREAD(&s->top_matter_pt, enqueue_chunk(s, 0, http_head_end)); + PT_WAIT_THREAD(&s->top_matter_pt, enqueue_chunk(s, 0, http_body_start)); + + /* Links */ + PT_WAIT_THREAD(&s->top_matter_pt, + enqueue_chunk(s, 0, SECTION_OPEN "

    ")); + + s->page = list_head(pages_list); + PT_WAIT_THREAD(&s->top_matter_pt, + enqueue_chunk(s, 0, "[ %s ]", + s->page->filename, s->page->title)); + + for(s->page = s->page->next; s->page != NULL; s->page = s->page->next) { + PT_WAIT_THREAD(&s->top_matter_pt, + enqueue_chunk(s, 0, " | [ %s ]", + s->page->filename, s->page->title)); + } + +#if CC26XX_WEB_DEMO_MQTT_CLIENT + PT_WAIT_THREAD(&s->top_matter_pt, + enqueue_chunk(s, 0, " | %s", http_mqtt_a)); +#endif + PT_WAIT_THREAD(&s->top_matter_pt, + enqueue_chunk(s, 0, "

    " SECTION_CLOSE)); + + PT_END(&s->top_matter_pt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(generate_index(struct httpd_state *s)) +{ + char ipaddr_buf[IPADDR_BUF_LEN]; /* Intentionally on stack */ + + PT_BEGIN(&s->generate_pt); + + /* Generate top matter (doctype, title, nav links etc) */ + PT_WAIT_THREAD(&s->generate_pt, + generate_top_matter(s, http_index_page.title, NULL)); + + /* ND Cache */ + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, SECTION_OPEN "Neighbors" CONTENT_OPEN)); + + for(s->nbr = nbr_table_head(ds6_neighbors); s->nbr != NULL; + s->nbr = nbr_table_next(ds6_neighbors, s->nbr)) { + + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, "\n")); + + memset(ipaddr_buf, 0, IPADDR_BUF_LEN); + cc26xx_web_demo_ipaddr_sprintf(ipaddr_buf, IPADDR_BUF_LEN, &s->nbr->ipaddr); + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, "%s", ipaddr_buf)); + + memset(ipaddr_buf, 0, IPADDR_BUF_LEN); + get_neighbour_state_text(ipaddr_buf, s->nbr->state); + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, " %s", ipaddr_buf)); + } + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, CONTENT_CLOSE SECTION_CLOSE)); + + /* Default Route */ + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, + SECTION_OPEN "Default Route" CONTENT_OPEN)); + + memset(ipaddr_buf, 0, IPADDR_BUF_LEN); + cc26xx_web_demo_ipaddr_sprintf(ipaddr_buf, IPADDR_BUF_LEN, + uip_ds6_defrt_choose()); + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, "%s", ipaddr_buf)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, CONTENT_CLOSE SECTION_CLOSE)); + + /* Routes */ + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, SECTION_OPEN "Routes" CONTENT_OPEN)); + + for(s->r = uip_ds6_route_head(); s->r != NULL; + s->r = uip_ds6_route_next(s->r)) { + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, "\n")); + + memset(ipaddr_buf, 0, IPADDR_BUF_LEN); + cc26xx_web_demo_ipaddr_sprintf(ipaddr_buf, IPADDR_BUF_LEN, &s->r->ipaddr); + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, "%s", ipaddr_buf)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, " / %u via ", s->r->length)); + + memset(ipaddr_buf, 0, IPADDR_BUF_LEN); + cc26xx_web_demo_ipaddr_sprintf(ipaddr_buf, IPADDR_BUF_LEN, + uip_ds6_route_nexthop(s->r)); + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, "%s", ipaddr_buf)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, + ", lifetime=%lus", s->r->state.lifetime)); + } + + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, + CONTENT_CLOSE SECTION_CLOSE)); + + /* Sensors */ + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, SECTION_OPEN "Sensors" CONTENT_OPEN)); + + for(s->reading = cc26xx_web_demo_sensor_first(); + s->reading != NULL; s->reading = s->reading->next) { + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "\n%s = %s %s", s->reading->descr, + s->reading->publish ? s->reading->converted : "N/A", + s->reading->units)); + } + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, CONTENT_CLOSE SECTION_CLOSE)); + + /* Footer */ + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, SECTION_OPEN)); + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, "Page hits: %u
    ", + ++numtimes)); + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, "Uptime: %lu secs
    ", + clock_seconds())); + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, SECTION_CLOSE)); + + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 1, http_bottom)); + + PT_END(&s->generate_pt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(generate_config(struct httpd_state *s)) +{ + PT_BEGIN(&s->generate_pt); + + /* Generate top matter (doctype, title, nav links etc) */ + PT_WAIT_THREAD(&s->generate_pt, + generate_top_matter(s, http_dev_cfg_page.title, + http_config_css)); + + /* Sensor Settings */ + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "

    Sensors

    ")); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, + "
    generate_pt, + enqueue_chunk(s, 0, "method=\"post\" enctype=\"")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "application/x-www-form-urlencoded\" ")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "accept-charset=\"UTF-8\">")); + + for(s->reading = cc26xx_web_demo_sensor_first(); + s->reading != NULL; s->reading = s->reading->next) { + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%s%s:%s%s", config_div_left, + s->reading->descr, config_div_close, + config_div_right)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "generate_pt, + enqueue_chunk(s, 0, "title=\"On\" name=\"%s\"%s>", + s->reading->form_field, + s->reading->publish ? " Checked" : "")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "generate_pt, + enqueue_chunk(s, 0, "title=\"Off\" name=\"%s\"%s>%s", + s->reading->form_field, + s->reading->publish ? "" : " Checked", + config_div_close)); + } + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, + "")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "
    ")); + + /* RSSI measurements */ +#if CC26XX_WEB_DEMO_READ_PARENT_RSSI + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "

    RSSI Probing

    ")); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, + "
    generate_pt, + enqueue_chunk(s, 0, "method=\"post\" enctype=\"")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "application/x-www-form-urlencoded\" ")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "accept-charset=\"UTF-8\">")); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sPeriod (secs):%s", + config_div_left, config_div_close)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sgenerate_pt, + enqueue_chunk(s, 0, "value=\"%lu\" ", + (clock_time_t) + (cc26xx_web_demo_config.def_rt_ping_interval + / CLOCK_SECOND))); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, + "min=\"" RSSI_INT_MIN "\" " + "max=\"" RSSI_INT_MAX "\" " + "name=\"ping_interval\">%s", + config_div_close)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, + "")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "
    ")); +#endif + + /* Actions */ + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, "

    Actions

    ")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, + "
    generate_pt, + enqueue_chunk(s, 0, "method=\"post\" enctype=\"")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "application/x-www-form-urlencoded\" ")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "accept-charset=\"UTF-8\">")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "
    ")); + + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 1, http_bottom)); + + PT_END(&s->generate_pt); +} +/*---------------------------------------------------------------------------*/ +#if CC26XX_WEB_DEMO_MQTT_CLIENT +static +PT_THREAD(generate_mqtt_config(struct httpd_state *s)) +{ + PT_BEGIN(&s->generate_pt); + + /* Generate top matter (doctype, title, nav links etc) */ + PT_WAIT_THREAD(&s->generate_pt, + generate_top_matter(s, http_mqtt_cfg_page.title, + http_config_css)); + + /* MQTT client settings */ + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "

    %s

    ", http_mqtt_cfg_page.title)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, + "
    generate_pt, + enqueue_chunk(s, 0, "method=\"post\" enctype=\"")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "application/x-www-form-urlencoded\" ")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "accept-charset=\"UTF-8\">")); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sType ID:%s", config_div_left, + config_div_close)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sgenerate_pt, + enqueue_chunk(s, 0, "value=\"%s\" ", + cc26xx_web_demo_config.mqtt_config.type_id)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "name=\"type_id\">%s", config_div_close)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sOrg ID:%s", config_div_left, + config_div_close)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sgenerate_pt, + enqueue_chunk(s, 0, "value=\"%s\" ", + cc26xx_web_demo_config.mqtt_config.org_id)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "name=\"org_id\">%s", config_div_close)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sAuth Token:%s", config_div_left, + config_div_close)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sgenerate_pt, + enqueue_chunk(s, 0, "value=\"\" ")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "name=\"auth_token\">%s", + config_div_close)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sCommand Type:%s", config_div_left, + config_div_close)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sgenerate_pt, + enqueue_chunk(s, 0, "value=\"%s\" ", + cc26xx_web_demo_config.mqtt_config.cmd_type)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "name=\"cmd_type\">%s", + config_div_close)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sEvent Type ID:%s", config_div_left, + config_div_close)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sgenerate_pt, + enqueue_chunk(s, 0, "value=\"%s\" ", + cc26xx_web_demo_config.mqtt_config.event_type_id)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "name=\"event_type_id\">%s", + config_div_close)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sInterval (secs):%s", + config_div_left, config_div_close)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sgenerate_pt, + enqueue_chunk(s, 0, "value=\"%lu\" ", + (clock_time_t) + (cc26xx_web_demo_config.mqtt_config.pub_interval + / CLOCK_SECOND))); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, + "min=\"" PUB_INT_MIN "\" " + "max=\"" PUB_INT_MAX "\" " + "name=\"interval\">%s", + config_div_close)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sBroker IP:%s", config_div_left, + config_div_close)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sgenerate_pt, + enqueue_chunk(s, 0, "value=\"%s\" ", + cc26xx_web_demo_config.mqtt_config.broker_ip)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "name=\"broker_ip\">%s", + config_div_close)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sBroker Port:%s", config_div_left, + config_div_close)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sgenerate_pt, + enqueue_chunk(s, 0, "value=\"%d\" ", + cc26xx_web_demo_config.mqtt_config.broker_port)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "min=\"1\" max=\"65535\" " + "name=\"broker_port\">%s", + config_div_close)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, + "")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "
    ")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, + "
    generate_pt, + enqueue_chunk(s, 0, "method=\"post\" enctype=\"")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "application/x-www-form-urlencoded\" ")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "accept-charset=\"UTF-8\">")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "
    ")); + + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 1, http_bottom)); + + PT_END(&s->generate_pt); +} +#endif +/*---------------------------------------------------------------------------*/ +#if CC26XX_WEB_DEMO_NET_UART +static +PT_THREAD(generate_net_uart_config(struct httpd_state *s)) +{ + + PT_BEGIN(&s->generate_pt); + + /* Generate top matter (doctype, title, nav links etc) */ + PT_WAIT_THREAD(&s->generate_pt, + generate_top_matter(s, http_net_cfg_page.title, + http_config_css)); + + /* Net-UART settings */ + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "

    %s

    ", http_net_cfg_page.title)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, + "
    generate_pt, + enqueue_chunk(s, 0, "method=\"post\" enctype=\"")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "application/x-www-form-urlencoded\" ")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "accept-charset=\"UTF-8\">")); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sRemote IPv6:%s", config_div_left, + config_div_close)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sgenerate_pt, + enqueue_chunk(s, 0, "value=\"%s\" ", + cc26xx_web_demo_config.net_uart.remote_address)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "name=\"net_uart_ip\">%s", + config_div_close)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sRemote Port:%s", config_div_left, + config_div_close)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sgenerate_pt, + enqueue_chunk(s, 0, "value=\"%u\" ", + cc26xx_web_demo_config.net_uart.remote_port)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "min=\"1\" max=\"65535\" " + "name=\"net_uart_port\">%s", + config_div_close)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%s%s:%s%s", config_div_left, + "Enable", config_div_close, + config_div_right)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "generate_pt, + enqueue_chunk(s, 0, "title=\"On\" name=\"net_uart_on\"%s>", + cc26xx_web_demo_config.net_uart.enable ? + " Checked" : "")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "generate_pt, + enqueue_chunk(s, 0, "title=\"Off\" name=\"net_uart_on\"" + "%s>%s", + cc26xx_web_demo_config.net_uart.enable ? + "" : " Checked", config_div_close)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, + "")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "
    ")); + + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 1, http_bottom)); + + PT_END(&s->generate_pt); +} +#endif +/*---------------------------------------------------------------------------*/ +static void +lock_obtain(struct httpd_state *s) +{ + if(lock == NULL) { + lock = s; + } +} +/*---------------------------------------------------------------------------*/ +static void +lock_release(struct httpd_state *s) +{ + if(lock == s) { + lock = NULL; + } +} +/*---------------------------------------------------------------------------*/ +static void +parse_post_request_chunk(char *buf, int buf_len, int last_chunk) +{ + int i; + int finish; + + for(i = 0; i < buf_len; i++) { + switch(state) { + case PARSE_POST_STATE_INIT: + state = PARSE_POST_STATE_MORE; + /* continue */ + case PARSE_POST_STATE_MORE: + memset(key, 0, PARSE_POST_BUF_SIZES); + memset(val, 0, PARSE_POST_BUF_SIZES); + memset(val_escaped, 0, PARSE_POST_BUF_SIZES); + key_len = 0; + val_len = 0; + state = PARSE_POST_STATE_READING_KEY; + /* continue */ + case PARSE_POST_STATE_READING_KEY: + if(buf[i] == ISO_equal) { + state = PARSE_POST_STATE_READING_VAL; + } else if(buf[i] == ISO_amp) { + /* Don't accept an amp while reading a key */ + state = PARSE_POST_STATE_ERROR; + } else { + /* Make sure we don't overshoot key's boundary */ + if(key_len <= PARSE_POST_MAX_POS) { + key[key_len] = buf[i]; + key_len++; + } else { + /* Not enough space for the key. Abort */ + state = PARSE_POST_STATE_ERROR; + } + } + break; + case PARSE_POST_STATE_READING_VAL: + finish = 0; + if(buf[i] == ISO_amp) { + finish = 1; + } else if(buf[i] == ISO_equal) { + /* Don't accept an '=' while reading a val */ + state = PARSE_POST_STATE_ERROR; + } else { + /* Make sure we don't overshoot key's boundary */ + if(val_len <= PARSE_POST_MAX_POS) { + val[val_len] = buf[i]; + val_len++; + /* Last character of the last chunk */ + if((i == buf_len - 1) && (last_chunk == 1)) { + finish = 1; + } + } else { + /* Not enough space for the value. Abort */ + state = PARSE_POST_STATE_ERROR; + } + } + + if(finish == 1) { + /* + * Done reading a key=value pair, either because we encountered an amp + * or because we reached the end of the message body. + * + * First, unescape the value. + * + * Then invoke handlers. We will bail out with PARSE_POST_STATE_ERROR, + * unless the key-val gets correctly processed + */ + url_unescape(val, val_len, val_escaped, PARSE_POST_BUF_SIZES); + val_len = strlen(val_escaped); + + for(handler = list_head(post_handlers); handler != NULL; + handler = list_item_next((void *)handler)) { + if(handler->handler != NULL) { + finish = handler->handler(key, key_len, val_escaped, val_len); + } + if(finish == HTTPD_SIMPLE_POST_HANDLER_ERROR) { + state = PARSE_POST_STATE_ERROR; + break; + } else if(finish == HTTPD_SIMPLE_POST_HANDLER_OK) { + /* Restart the state machine to expect the next pair */ + state = PARSE_POST_STATE_MORE; + + /* + * At least one handler returned OK, therefore we must generate a + * new config event when we're done. + */ + config_ok = 1; + break; + } + /* Else, continue */ + } + } + break; + case PARSE_POST_STATE_ERROR: + /* If we entered the error state earlier, do nothing */ + return; + default: + break; + } + } +} +/*---------------------------------------------------------------------------*/ +static httpd_simple_script_t +get_script(const char *name) +{ + page_t *page; + + for(page = list_head(pages_list); page != NULL; + page = list_item_next(page)) { + if(strncmp(name, page->filename, strlen(page->filename)) == 0) { + return page->script; + } + } + + return NULL; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_string(struct httpd_state *s, const char *str)) +{ + PSOCK_BEGIN(&s->sout); + + SEND_STRING(&s->sout, str); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr, + const char *content_type, const char *redir, + const char **additional)) +{ + PT_BEGIN(&s->generate_pt); + + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, statushdr)); + + for(s->ptr = http_header_srv_str; *(s->ptr) != NULL; s->ptr++) { + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, *(s->ptr))); + } + + if(redir) { + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "Location: %s\r\n", redir)); + } + + if(additional) { + for(s->ptr = additional; *(s->ptr) != NULL; s->ptr++) { + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, *(s->ptr))); + } + } + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "Content-type: %s; ", content_type)); + + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 1, "charset=UTF-8\r\n\r\n")); + + PT_END(&s->generate_pt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_output(struct httpd_state *s)) +{ + PT_BEGIN(&s->outputpt); + + s->script = NULL; + + PT_INIT(&s->generate_pt); + PT_INIT(&s->top_matter_pt); + + if(s->request_type == REQUEST_TYPE_POST) { + if(s->return_code == RETURN_CODE_OK) { + PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_302, + http_content_type_plain, + s->filename, + NULL)); + } else if(s->return_code == RETURN_CODE_LR) { + PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_411, + http_content_type_plain, + NULL, + http_header_con_close)); + PT_WAIT_THREAD(&s->outputpt, send_string(s, "Content-Length Required\n")); + } else if(s->return_code == RETURN_CODE_TL) { + PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_413, + http_content_type_plain, + NULL, + http_header_con_close)); + PT_WAIT_THREAD(&s->outputpt, send_string(s, "Content-Length too Large\n")); + } else if(s->return_code == RETURN_CODE_SU) { + PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_503, + http_content_type_plain, + NULL, + http_header_con_close)); + PT_WAIT_THREAD(&s->outputpt, send_string(s, "Service Unavailable\n")); + } else { + PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_400, + http_content_type_plain, + NULL, + http_header_con_close)); + PT_WAIT_THREAD(&s->outputpt, send_string(s, "Bad Request\n")); + } + } else if(s->request_type == REQUEST_TYPE_GET) { + s->script = get_script(&s->filename[1]); + if(s->script == NULL) { + strncpy(s->filename, "/notfound.html", sizeof(s->filename)); + PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_404, + http_content_type_html, + NULL, + http_header_con_close)); + PT_WAIT_THREAD(&s->outputpt, + send_string(s, NOT_FOUND)); + uip_close(); + PT_EXIT(&s->outputpt); + } else { + PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_200, + http_content_type_html, + NULL, + http_header_con_close)); + PT_WAIT_THREAD(&s->outputpt, s->script(s)); + } + } + s->script = NULL; + PSOCK_CLOSE(&s->sout); + PT_END(&s->outputpt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_input(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sin); + + PSOCK_READTO(&s->sin, ISO_space); + + if(strncasecmp(s->inputbuf, http_get, 4) == 0) { + s->request_type = REQUEST_TYPE_GET; + PSOCK_READTO(&s->sin, ISO_space); + + if(s->inputbuf[0] != ISO_slash) { + PSOCK_CLOSE_EXIT(&s->sin); + } + + if(s->inputbuf[1] == ISO_space) { + strncpy(s->filename, http_index_html, sizeof(s->filename)); + } else { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + strncpy(s->filename, s->inputbuf, sizeof(s->filename)); + } + } else if(strncasecmp(s->inputbuf, http_post, 5) == 0) { + s->request_type = REQUEST_TYPE_POST; + PSOCK_READTO(&s->sin, ISO_space); + + if(s->inputbuf[0] != ISO_slash) { + PSOCK_CLOSE_EXIT(&s->sin); + } + + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + strncpy(s->filename, s->inputbuf, sizeof(s->filename)); + + /* POST: Read out the rest of the line and ignore it */ + PSOCK_READTO(&s->sin, ISO_nl); + + /* + * Start parsing headers. We look for Content-Length and ignore everything + * else until we hit the start of the message body. + * + * We will return 411 if the client doesn't send Content-Length and 413 + * if Content-Length is too high + */ + s->content_length = 0; + s->return_code = RETURN_CODE_LR; + do { + s->inputbuf[PSOCK_DATALEN(&s->sin)] = 0; + /* We anticipate a content length */ + if((PSOCK_DATALEN(&s->sin) > 14) && + strncasecmp(s->inputbuf, "Content-Length:", 15) == 0) { + char *val_start = &s->inputbuf[15]; + s->content_length = atoi(val_start); + + /* So far so good */ + s->return_code = RETURN_CODE_OK; + } + PSOCK_READTO(&s->sin, ISO_nl); + } while(PSOCK_DATALEN(&s->sin) != 2); + + /* + * Done reading headers. + * Reject content length greater than CONTENT_LENGTH_MAX bytes + */ + if(s->content_length > CONTENT_LENGTH_MAX) { + s->content_length = 0; + s->return_code = RETURN_CODE_TL; + } + + if(s->return_code == RETURN_CODE_OK) { + /* Acceptable Content Length. Try to obtain a lock */ + lock_obtain(s); + + if(lock == s) { + state = PARSE_POST_STATE_INIT; + } else { + s->return_code = RETURN_CODE_SU; + } + } + + /* Parse the message body, unless we have detected an error. */ + while(s->content_length > 0 && lock == s && + s->return_code == RETURN_CODE_OK) { + PSOCK_READBUF_LEN(&s->sin, s->content_length); + s->content_length -= PSOCK_DATALEN(&s->sin); + + /* Parse the message body */ + parse_post_request_chunk(s->inputbuf, PSOCK_DATALEN(&s->sin), + (s->content_length == 0)); + if(state == PARSE_POST_STATE_ERROR) { + /* Could not parse: Bad Request and stop parsing */ + s->return_code = RETURN_CODE_BR; + } + } + + /* + * Done. If our return code is OK but the state machine is not in + * STATE_MORE, it means that the message body ended half-way reading a key + * or value. Set 'Bad Request' + */ + if(s->return_code == RETURN_CODE_OK && state != PARSE_POST_STATE_MORE) { + s->return_code = RETURN_CODE_BR; + } + + /* If the flag is set, we had at least 1 configuration value accepted */ + if(config_ok) { + process_post(PROCESS_BROADCAST, httpd_simple_event_new_config, NULL); + } + config_ok = 0; + + lock_release(s); + } else { + PSOCK_CLOSE_EXIT(&s->sin); + } + + s->state = STATE_OUTPUT; + + while(1) { + PSOCK_READTO(&s->sin, ISO_nl); + } + + PSOCK_END(&s->sin); +} +/*---------------------------------------------------------------------------*/ +static void +handle_connection(struct httpd_state *s) +{ + handle_input(s); + if(s->state == STATE_OUTPUT) { + handle_output(s); + } +} +/*---------------------------------------------------------------------------*/ +static void +appcall(void *state) +{ + struct httpd_state *s = (struct httpd_state *)state; + + if(uip_closed() || uip_aborted() || uip_timedout()) { + if(s != NULL) { + s->script = NULL; + s->blen = 0; + s->tmp_buf_len = 0; + memb_free(&conns, s); + } + } else if(uip_connected()) { + s = (struct httpd_state *)memb_alloc(&conns); + if(s == NULL) { + uip_abort(); + return; + } + tcp_markconn(uip_conn, s); + PSOCK_INIT(&s->sin, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PSOCK_INIT(&s->sout, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PT_INIT(&s->outputpt); + s->script = NULL; + s->state = STATE_WAITING; + timer_set(&s->timer, CLOCK_SECOND * 10); + handle_connection(s); + } else if(s != NULL) { + if(uip_poll()) { + if(timer_expired(&s->timer)) { + uip_abort(); + s->script = NULL; + memb_free(&conns, s); + } + } else { + timer_restart(&s->timer); + } + handle_connection(s); + } else { + uip_abort(); + } +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + tcp_listen(UIP_HTONS(80)); + memb_init(&conns); + + list_add(pages_list, &http_index_page); + list_add(pages_list, &http_dev_cfg_page); + +#if CC26XX_WEB_DEMO_NET_UART + list_add(pages_list, &http_net_cfg_page); +#endif + +#if CC26XX_WEB_DEMO_MQTT_CLIENT + list_add(pages_list, &http_mqtt_cfg_page); +#endif +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(httpd_simple_process, ev, data) +{ + PROCESS_BEGIN(); + + printf("CC26XX Web Server\n"); + + httpd_simple_event_new_config = process_alloc_event(); + + init(); + + snprintf(http_mqtt_a, IBM_QUICKSTART_LINK_LEN, + "[ IBM Quickstart ]", + linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1], + linkaddr_node_addr.u8[2], linkaddr_node_addr.u8[5], + linkaddr_node_addr.u8[6], linkaddr_node_addr.u8[7]); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); + appcall(data); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/examples/cc26xx/cc26xx-web-demo/httpd-simple.h b/examples/cc26xx/cc26xx-web-demo/httpd-simple.h new file mode 100644 index 000000000..25b8db3e5 --- /dev/null +++ b/examples/cc26xx/cc26xx-web-demo/httpd-simple.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \file + * Header file for the HTTPD of the cc26xx web demo example. + * \author + * Adam Dunkels + * Niclas Finne + * Joakim Eriksson + * Texas Instruments Incorporated - http://www.ti.com/ + */ +/*---------------------------------------------------------------------------*/ +#ifndef HTTPD_SIMPLE_H_ +#define HTTPD_SIMPLE_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki-net.h" +#include "sys/process.h" +#include "cc26xx-web-demo.h" +/*---------------------------------------------------------------------------*/ +/* Ideally a multiple of TCP_MSS */ +#ifdef HTTPD_SIMPLE_CONF_MAIN_BUF_SIZE +#define HTTPD_SIMPLE_MAIN_BUF_SIZE HTTPD_SIMPLE_CONF_MAIN_BUF_SIZE +#else +#define HTTPD_SIMPLE_MAIN_BUF_SIZE UIP_TCP_MSS +#endif +/*---------------------------------------------------------------------------*/ +#define HTTPD_PATHLEN 16 +#define HTTPD_INBUF_LEN (HTTPD_PATHLEN + 10) + +#define TMP_BUF_SIZE (UIP_TCP_MSS + 1) +/*---------------------------------------------------------------------------*/ +/* POST request handlers */ +#define HTTPD_SIMPLE_POST_HANDLER_OK 1 +#define HTTPD_SIMPLE_POST_HANDLER_UNKNOWN 0 +#define HTTPD_SIMPLE_POST_HANDLER_ERROR 0xFFFFFFFF + +/** + * \brief Datatype for a handler which can process incoming POST requests + * \param key The configuration key to be updated + * \param key_len The length of the key argument + * \param val The new configuration value for key + * \param val_len The length of the value argument + * + * \return 1: HTTPD_SIMPLE_POST_HANDLER_OK if the function can handle the + * request, HTTPD_SIMPLE_POST_HANDLER_UNKNOWN if it does not know how to handle + * it. HTTPD_SIMPLE_POST_HANDLER_ERROR if it does know how to handle it but + * the request was malformed. + */ +typedef struct httpd_simple_post_handler { + struct httpd_simple_post_handler *next; + int (*handler)(char *key, int key_len, char *val, int val_len); +} httpd_simple_post_handler_t; + +/* Declare a handler */ +#define HTTPD_SIMPLE_POST_HANDLER(name, fp) \ + httpd_simple_post_handler_t name##_handler = { NULL, fp } + +/** + * \brief Register a handler for POST requests + * \param h A pointer to the handler structure + */ +void httpd_simple_register_post_handler(httpd_simple_post_handler_t *h); +/*---------------------------------------------------------------------------*/ +/* + * An event generated by the HTTPD when a new configuration request has been + * received + */ +extern process_event_t httpd_simple_event_new_config; +/*---------------------------------------------------------------------------*/ +PROCESS_NAME(httpd_simple_process); +/*---------------------------------------------------------------------------*/ +#endif /* HTTPD_SIMPLE_H_ */ diff --git a/examples/cc26xx/cc26xx-web-demo/img/6lbr-web.png b/examples/cc26xx/cc26xx-web-demo/img/6lbr-web.png new file mode 100644 index 000000000..5308c412b Binary files /dev/null and b/examples/cc26xx/cc26xx-web-demo/img/6lbr-web.png differ diff --git a/examples/cc26xx/cc26xx-web-demo/img/coap-resources.png b/examples/cc26xx/cc26xx-web-demo/img/coap-resources.png new file mode 100644 index 000000000..c71c934fe Binary files /dev/null and b/examples/cc26xx/cc26xx-web-demo/img/coap-resources.png differ diff --git a/examples/cc26xx/cc26xx-web-demo/img/quickstart-sensortag.png b/examples/cc26xx/cc26xx-web-demo/img/quickstart-sensortag.png new file mode 100644 index 000000000..a7ce7dabe Binary files /dev/null and b/examples/cc26xx/cc26xx-web-demo/img/quickstart-sensortag.png differ diff --git a/examples/cc26xx/cc26xx-web-demo/img/sensor-readings-config.png b/examples/cc26xx/cc26xx-web-demo/img/sensor-readings-config.png new file mode 100644 index 000000000..79c8e61e3 Binary files /dev/null and b/examples/cc26xx/cc26xx-web-demo/img/sensor-readings-config.png differ diff --git a/examples/cc26xx/cc26xx-web-demo/img/well-known-core.png b/examples/cc26xx/cc26xx-web-demo/img/well-known-core.png new file mode 100644 index 000000000..93552e502 Binary files /dev/null and b/examples/cc26xx/cc26xx-web-demo/img/well-known-core.png differ diff --git a/examples/cc26xx/cc26xx-web-demo/mqtt-client.c b/examples/cc26xx/cc26xx-web-demo/mqtt-client.c new file mode 100644 index 000000000..cf60d6c63 --- /dev/null +++ b/examples/cc26xx/cc26xx-web-demo/mqtt-client.c @@ -0,0 +1,915 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc26xx-web-demo + * @{ + * + * \file + * MQTT/IBM cloud service client for the CC26XX web demo. + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "rpl/rpl-private.h" +#include "mqtt.h" +#include "net/rpl/rpl.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-icmp6.h" +#include "sys/etimer.h" +#include "sys/ctimer.h" +#include "lib/sensors.h" +#include "button-sensor.h" +#include "board-peripherals.h" +#include "cc26xx-web-demo.h" +#include "dev/leds.h" +#include "mqtt-client.h" +#include "httpd-simple.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/* + * IBM server: messaging.quickstart.internetofthings.ibmcloud.com + * (184.172.124.189) mapped in an NAT64 (prefix 64:ff9b::/96) IPv6 address + * Note: If not able to connect; lookup the IP address again as it may change. + * + * If the node has a broker IP setting saved on flash, this value here will + * get ignored + */ +static const char *broker_ip = "0064:ff9b:0000:0000:0000:0000:b8ac:7cbd"; +/*---------------------------------------------------------------------------*/ +/* + * A timeout used when waiting for something to happen (e.g. to connect or to + * disconnect) + */ +#define STATE_MACHINE_PERIODIC (CLOCK_SECOND >> 1) +/*---------------------------------------------------------------------------*/ +/* Provide visible feedback via LEDS during various states */ +/* When connecting to broker */ +#define CONNECTING_LED_DURATION (CLOCK_SECOND >> 3) + +/* Each time we try to publish */ +#define PUBLISH_LED_ON_DURATION (CLOCK_SECOND) +/*---------------------------------------------------------------------------*/ +/* Connections and reconnections */ +#define RETRY_FOREVER 0xFF +#define RECONNECT_INTERVAL (CLOCK_SECOND * 2) + +/* + * Number of times to try reconnecting to the broker. + * Can be a limited number (e.g. 3, 10 etc) or can be set to RETRY_FOREVER + */ +#define RECONNECT_ATTEMPTS 5 +#define CONNECTION_STABLE_TIME (CLOCK_SECOND * 5) +#define NEW_CONFIG_WAIT_INTERVAL (CLOCK_SECOND * 20) +static struct timer connection_life; +static uint8_t connect_attempt; +/*---------------------------------------------------------------------------*/ +/* Various states */ +static uint8_t state; +#define MQTT_CLIENT_STATE_INIT 0 +#define MQTT_CLIENT_STATE_REGISTERED 1 +#define MQTT_CLIENT_STATE_CONNECTING 2 +#define MQTT_CLIENT_STATE_CONNECTED 3 +#define MQTT_CLIENT_STATE_PUBLISHING 4 +#define MQTT_CLIENT_STATE_DISCONNECTED 5 +#define MQTT_CLIENT_STATE_NEWCONFIG 6 +#define MQTT_CLIENT_STATE_CONFIG_ERROR 0xFE +#define MQTT_CLIENT_STATE_ERROR 0xFF +/*---------------------------------------------------------------------------*/ +/* Maximum TCP segment size for outgoing segments of our socket */ +#define MQTT_CLIENT_MAX_SEGMENT_SIZE 32 +/*---------------------------------------------------------------------------*/ +/* + * Buffers for Client ID and Topic. + * Make sure they are large enough to hold the entire respective string + * + * d:quickstart:status:EUI64 is 32 bytes long + * iot-2/evt/status/fmt/json is 25 bytes + * We also need space for the null termination + */ +#define BUFFER_SIZE 64 +static char client_id[BUFFER_SIZE]; +static char pub_topic[BUFFER_SIZE]; +static char sub_topic[BUFFER_SIZE]; +/*---------------------------------------------------------------------------*/ +/* + * The main MQTT buffers. + * We will need to increase if we start publishing more data. + */ +#define APP_BUFFER_SIZE 512 +static struct mqtt_connection conn; +static char app_buffer[APP_BUFFER_SIZE]; +/*---------------------------------------------------------------------------*/ +#define QUICKSTART "quickstart" +/*---------------------------------------------------------------------------*/ +static struct mqtt_message *msg_ptr = 0; +static struct etimer publish_periodic_timer; +static struct ctimer ct; +static char *buf_ptr; +static uint16_t seq_nr_value = 0; +/*---------------------------------------------------------------------------*/ +static uip_ip6addr_t def_route; +/*---------------------------------------------------------------------------*/ +/* Parent RSSI functionality */ +extern int def_rt_rssi; +/*---------------------------------------------------------------------------*/ +const static cc26xx_web_demo_sensor_reading_t *reading; +/*---------------------------------------------------------------------------*/ +mqtt_client_config_t *conf; +/*---------------------------------------------------------------------------*/ +PROCESS(mqtt_client_process, "CC26XX MQTT Client"); +/*---------------------------------------------------------------------------*/ +static void +publish_led_off(void *d) +{ + leds_off(CC26XX_WEB_DEMO_STATUS_LED); +} +/*---------------------------------------------------------------------------*/ +static void +new_net_config(void) +{ + /* + * We got a new configuration over the net. + * + * Disconnect from the current broker and stop the periodic timer. + * + * When the source of the new configuration is done, we will get notified + * via an event. + */ + if(state == MQTT_CLIENT_STATE_NEWCONFIG) { + return; + } + + state = MQTT_CLIENT_STATE_NEWCONFIG; + + etimer_stop(&publish_periodic_timer); + mqtt_disconnect(&conn); +} +/*---------------------------------------------------------------------------*/ +static int +org_id_post_handler(char *key, int key_len, char *val, int val_len) +{ + int rv = HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + if(key_len != strlen("org_id") || + strncasecmp(key, "org_id", strlen("org_id")) != 0) { + /* Not ours */ + return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + } + + if(val_len > MQTT_CLIENT_CONFIG_ORG_ID_LEN) { + /* Ours but bad value */ + rv = HTTPD_SIMPLE_POST_HANDLER_ERROR; + } else { + memset(conf->org_id, 0, MQTT_CLIENT_CONFIG_ORG_ID_LEN); + memcpy(conf->org_id, val, val_len); + + rv = HTTPD_SIMPLE_POST_HANDLER_OK; + } + + new_net_config(); + + return rv; +} +/*---------------------------------------------------------------------------*/ +static int +type_id_post_handler(char *key, int key_len, char *val, int val_len) +{ + int rv = HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + if(key_len != strlen("type_id") || + strncasecmp(key, "type_id", strlen("type_id")) != 0) { + /* Not ours */ + return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + } + + if(val_len > MQTT_CLIENT_CONFIG_TYPE_ID_LEN) { + /* Ours but bad value */ + rv = HTTPD_SIMPLE_POST_HANDLER_ERROR; + } else { + memset(conf->type_id, 0, MQTT_CLIENT_CONFIG_TYPE_ID_LEN); + memcpy(conf->type_id, val, val_len); + + rv = HTTPD_SIMPLE_POST_HANDLER_OK; + } + + new_net_config(); + + return rv; +} +/*---------------------------------------------------------------------------*/ +static int +event_type_id_post_handler(char *key, int key_len, char *val, int val_len) +{ + int rv = HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + if(key_len != strlen("event_type_id") || + strncasecmp(key, "event_type_id", strlen("event_type_id")) != 0) { + /* Not ours */ + return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + } + + if(val_len > MQTT_CLIENT_CONFIG_EVENT_TYPE_ID_LEN) { + /* Ours but bad value */ + rv = HTTPD_SIMPLE_POST_HANDLER_ERROR; + } else { + memset(conf->event_type_id, 0, MQTT_CLIENT_CONFIG_EVENT_TYPE_ID_LEN); + memcpy(conf->event_type_id, val, val_len); + + rv = HTTPD_SIMPLE_POST_HANDLER_OK; + } + + new_net_config(); + + return rv; +} +/*---------------------------------------------------------------------------*/ +static int +cmd_type_post_handler(char *key, int key_len, char *val, int val_len) +{ + int rv = HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + if(key_len != strlen("cmd_type") || + strncasecmp(key, "cmd_type", strlen("cmd_type")) != 0) { + /* Not ours */ + return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + } + + if(val_len > MQTT_CLIENT_CONFIG_CMD_TYPE_LEN) { + /* Ours but bad value */ + rv = HTTPD_SIMPLE_POST_HANDLER_ERROR; + } else { + memset(conf->cmd_type, 0, MQTT_CLIENT_CONFIG_CMD_TYPE_LEN); + memcpy(conf->cmd_type, val, val_len); + + rv = HTTPD_SIMPLE_POST_HANDLER_OK; + } + + new_net_config(); + + return rv; +} +/*---------------------------------------------------------------------------*/ +static int +auth_token_post_handler(char *key, int key_len, char *val, int val_len) +{ + int rv = HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + if(key_len != strlen("auth_token") || + strncasecmp(key, "auth_token", strlen("auth_token")) != 0) { + /* Not ours */ + return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + } + + if(val_len > MQTT_CLIENT_CONFIG_AUTH_TOKEN_LEN) { + /* Ours but bad value */ + rv = HTTPD_SIMPLE_POST_HANDLER_ERROR; + } else { + memset(conf->auth_token, 0, MQTT_CLIENT_CONFIG_AUTH_TOKEN_LEN); + memcpy(conf->auth_token, val, val_len); + + rv = HTTPD_SIMPLE_POST_HANDLER_OK; + } + + new_net_config(); + + return rv; +} +/*---------------------------------------------------------------------------*/ +static int +interval_post_handler(char *key, int key_len, char *val, int val_len) +{ + int rv = 0; + + if(key_len != strlen("interval") || + strncasecmp(key, "interval", strlen("interval")) != 0) { + /* Not ours */ + return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + } + + rv = atoi(val); + + if(rv < MQTT_CLIENT_PUBLISH_INTERVAL_MIN || + rv > MQTT_CLIENT_PUBLISH_INTERVAL_MAX) { + return HTTPD_SIMPLE_POST_HANDLER_ERROR; + } + + conf->pub_interval = rv * CLOCK_SECOND; + + return HTTPD_SIMPLE_POST_HANDLER_OK; +} +/*---------------------------------------------------------------------------*/ +static int +port_post_handler(char *key, int key_len, char *val, int val_len) +{ + int rv = 0; + + if(key_len != strlen("broker_port") || + strncasecmp(key, "broker_port", strlen("broker_port")) != 0) { + /* Not ours */ + return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + } + + rv = atoi(val); + + if(rv <= 65535 && rv > 0) { + conf->broker_port = rv; + } else { + return HTTPD_SIMPLE_POST_HANDLER_ERROR; + } + + new_net_config(); + + return HTTPD_SIMPLE_POST_HANDLER_OK; +} +/*---------------------------------------------------------------------------*/ +static int +ip_addr_post_handler(char *key, int key_len, char *val, int val_len) +{ + int rv = HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + + if(key_len != strlen("broker_ip") || + strncasecmp(key, "broker_ip", strlen("broker_ip")) != 0) { + /* Not ours */ + return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + } + + if(val_len > MQTT_CLIENT_CONFIG_IP_ADDR_STR_LEN) { + /* Ours but bad value */ + rv = HTTPD_SIMPLE_POST_HANDLER_ERROR; + } else { + memset(conf->broker_ip, 0, MQTT_CLIENT_CONFIG_IP_ADDR_STR_LEN); + memcpy(conf->broker_ip, val, val_len); + + rv = HTTPD_SIMPLE_POST_HANDLER_OK; + } + + new_net_config(); + + return rv; +} +/*---------------------------------------------------------------------------*/ +static int +reconnect_post_handler(char *key, int key_len, char *val, int val_len) +{ + if(key_len != strlen("reconnect") || + strncasecmp(key, "reconnect", strlen("reconnect")) != 0) { + /* Not ours */ + return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + } + + new_net_config(); + + return HTTPD_SIMPLE_POST_HANDLER_OK; +} +/*---------------------------------------------------------------------------*/ +HTTPD_SIMPLE_POST_HANDLER(org_id, org_id_post_handler); +HTTPD_SIMPLE_POST_HANDLER(type_id, type_id_post_handler); +HTTPD_SIMPLE_POST_HANDLER(event_type_id, event_type_id_post_handler); +HTTPD_SIMPLE_POST_HANDLER(cmd_type, cmd_type_post_handler); +HTTPD_SIMPLE_POST_HANDLER(auth_token, auth_token_post_handler); +HTTPD_SIMPLE_POST_HANDLER(ip_addr, ip_addr_post_handler); +HTTPD_SIMPLE_POST_HANDLER(port, port_post_handler); +HTTPD_SIMPLE_POST_HANDLER(interval, interval_post_handler); +HTTPD_SIMPLE_POST_HANDLER(reconnect, reconnect_post_handler); +/*---------------------------------------------------------------------------*/ +static void +pub_handler(const char *topic, uint16_t topic_len, const uint8_t *chunk, + uint16_t chunk_len) +{ + DBG("Pub Handler: topic='%s' (len=%u), chunk_len=%u\n", topic, topic_len, + chunk_len); + + /* If we don't like the length, ignore */ + if(topic_len != 23 || chunk_len != 1) { + printf("Incorrect topic or chunk len. Ignored\n"); + return; + } + + /* If the format != json, ignore */ + if(strncmp(&topic[topic_len - 4], "json", 4) != 0) { + printf("Incorrect format\n"); + } + + if(strncmp(&topic[10], "leds", 4) == 0) { + if(chunk[0] == '1') { + leds_on(LEDS_RED); + } else if(chunk[0] == '0') { + leds_off(LEDS_RED); + } + return; + } + +#if BOARD_SENSORTAG + if(strncmp(&topic[10], "buzz", 4) == 0) { + if(chunk[0] == '1') { + buzzer_start(1000); + } else if(chunk[0] == '0') { + buzzer_stop(); + } + return; + } +#endif +} +/*---------------------------------------------------------------------------*/ +static void +mqtt_event(struct mqtt_connection *m, mqtt_event_t event, void *data) +{ + switch(event) { + case MQTT_EVENT_CONNECTED: { + DBG("APP - Application has a MQTT connection\n"); + timer_set(&connection_life, CONNECTION_STABLE_TIME); + state = MQTT_CLIENT_STATE_CONNECTED; + break; + } + case MQTT_EVENT_DISCONNECTED: { + DBG("APP - MQTT Disconnect. Reason %u\n", *((mqtt_event_t *)data)); + + /* Do nothing if the disconnect was the result of an incoming config */ + if(state != MQTT_CLIENT_STATE_NEWCONFIG) { + state = MQTT_CLIENT_STATE_DISCONNECTED; + process_poll(&mqtt_client_process); + } + break; + } + case MQTT_EVENT_PUBLISH: { + msg_ptr = data; + + /* Implement first_flag in publish message? */ + if(msg_ptr->first_chunk) { + msg_ptr->first_chunk = 0; + DBG("APP - Application received a publish on topic '%s'. Payload " + "size is %i bytes. Content:\n\n", + msg_ptr->topic, msg_ptr->payload_length); + } + + pub_handler(msg_ptr->topic, strlen(msg_ptr->topic), msg_ptr->payload_chunk, + msg_ptr->payload_length); + break; + } + case MQTT_EVENT_SUBACK: { + DBG("APP - Application is subscribed to topic successfully\n"); + break; + } + case MQTT_EVENT_UNSUBACK: { + DBG("APP - Application is unsubscribed to topic successfully\n"); + break; + } + case MQTT_EVENT_PUBACK: { + DBG("APP - Publishing complete.\n"); + break; + } + default: + DBG("APP - Application got a unhandled MQTT event: %i\n", event); + break; + } +} +/*---------------------------------------------------------------------------*/ +static int +construct_pub_topic(void) +{ + int len = snprintf(pub_topic, BUFFER_SIZE, "iot-2/evt/%s/fmt/json", + conf->event_type_id); + + /* len < 0: Error. Len >= BUFFER_SIZE: Buffer too small */ + if(len < 0 || len >= BUFFER_SIZE) { + printf("Pub Topic: %d, Buffer %d\n", len, BUFFER_SIZE); + return 0; + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +construct_sub_topic(void) +{ + int len = snprintf(sub_topic, BUFFER_SIZE, "iot-2/cmd/%s/fmt/json", + conf->cmd_type); + + /* len < 0: Error. Len >= BUFFER_SIZE: Buffer too small */ + if(len < 0 || len >= BUFFER_SIZE) { + printf("Sub Topic: %d, Buffer %d\n", len, BUFFER_SIZE); + return 0; + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +construct_client_id(void) +{ + int len = snprintf(client_id, BUFFER_SIZE, "d:%s:%s:%02x%02x%02x%02x%02x%02x", + conf->org_id, conf->type_id, + linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1], + linkaddr_node_addr.u8[2], linkaddr_node_addr.u8[5], + linkaddr_node_addr.u8[6], linkaddr_node_addr.u8[7]); + + /* len < 0: Error. Len >= BUFFER_SIZE: Buffer too small */ + if(len < 0 || len >= BUFFER_SIZE) { + printf("Client ID: %d, Buffer %d\n", len, BUFFER_SIZE); + return 0; + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +static void +update_config(void) +{ + if(construct_client_id() == 0) { + /* Fatal error. Client ID larger than the buffer */ + state = MQTT_CLIENT_STATE_CONFIG_ERROR; + return; + } + + if(construct_sub_topic() == 0) { + /* Fatal error. Topic larger than the buffer */ + state = MQTT_CLIENT_STATE_CONFIG_ERROR; + return; + } + + if(construct_pub_topic() == 0) { + /* Fatal error. Topic larger than the buffer */ + state = MQTT_CLIENT_STATE_CONFIG_ERROR; + return; + } + + /* Reset the counter */ + seq_nr_value = 0; + + state = MQTT_CLIENT_STATE_INIT; + + /* + * Schedule next timer event ASAP + * + * If we entered an error state then we won't do anything when it fires. + * + * Since the error at this stage is a config error, we will only exit this + * error state if we get a new config. + */ + etimer_set(&publish_periodic_timer, 0); + + return; +} +/*---------------------------------------------------------------------------*/ +static int +init_config() +{ + /* Populate configuration with default values */ + memset(conf, 0, sizeof(mqtt_client_config_t)); + + memcpy(conf->org_id, CC26XX_WEB_DEMO_DEFAULT_ORG_ID, 11); + memcpy(conf->type_id, CC26XX_WEB_DEMO_DEFAULT_TYPE_ID, 7); + memcpy(conf->event_type_id, CC26XX_WEB_DEMO_DEFAULT_EVENT_TYPE_ID, 7); + memcpy(conf->broker_ip, broker_ip, strlen(broker_ip)); + memcpy(conf->cmd_type, CC26XX_WEB_DEMO_DEFAULT_SUBSCRIBE_CMD_TYPE, 1); + + conf->broker_port = CC26XX_WEB_DEMO_DEFAULT_BROKER_PORT; + conf->pub_interval = CC26XX_WEB_DEMO_DEFAULT_PUBLISH_INTERVAL; + + return 1; +} +/*---------------------------------------------------------------------------*/ +static void +register_http_post_handlers(void) +{ + httpd_simple_register_post_handler(&org_id_handler); + httpd_simple_register_post_handler(&type_id_handler); + httpd_simple_register_post_handler(&event_type_id_handler); + httpd_simple_register_post_handler(&cmd_type_handler); + httpd_simple_register_post_handler(&auth_token_handler); + httpd_simple_register_post_handler(&interval_handler); + httpd_simple_register_post_handler(&port_handler); + httpd_simple_register_post_handler(&ip_addr_handler); + httpd_simple_register_post_handler(&reconnect_handler); +} +/*---------------------------------------------------------------------------*/ +static void +subscribe(void) +{ + /* Publish MQTT topic in IBM quickstart format */ + mqtt_status_t status; + + status = mqtt_subscribe(&conn, NULL, sub_topic, MQTT_QOS_LEVEL_0); + + DBG("APP - Subscribing!\n"); + if(status == MQTT_STATUS_OUT_QUEUE_FULL) { + DBG("APP - Tried to subscribe but command queue was full!\n"); + } +} +/*---------------------------------------------------------------------------*/ +static void +publish(void) +{ + /* Publish MQTT topic in IBM quickstart format */ + int len; + int remaining = APP_BUFFER_SIZE; + char def_rt_str[64]; + + seq_nr_value++; + + buf_ptr = app_buffer; + + len = snprintf(buf_ptr, remaining, + "{" + "\"d\":{" + "\"myName\":\"%s\"," + "\"Seq #\":%d," + "\"Uptime (sec)\":%lu", + BOARD_STRING, seq_nr_value, clock_seconds()); + + if(len < 0 || len >= remaining) { + printf("Buffer too short. Have %d, need %d + \\0\n", remaining, len); + return; + } + + remaining -= len; + buf_ptr += len; + + /* Put our Default route's string representation in a buffer */ + memset(def_rt_str, 0, sizeof(def_rt_str)); + cc26xx_web_demo_ipaddr_sprintf(def_rt_str, sizeof(def_rt_str), + uip_ds6_defrt_choose()); + + len = snprintf(buf_ptr, remaining, ",\"Def Route\":\"%s\",\"RSSI (dBm)\":%d", + def_rt_str, def_rt_rssi); + + if(len < 0 || len >= remaining) { + printf("Buffer too short. Have %d, need %d + \\0\n", remaining, len); + return; + } + remaining -= len; + buf_ptr += len; + + memcpy(&def_route, uip_ds6_defrt_choose(), sizeof(uip_ip6addr_t)); + + for(reading = cc26xx_web_demo_sensor_first(); + reading != NULL; reading = reading->next) { + if(reading->publish && reading->raw != CC26XX_SENSOR_READING_ERROR) { + len = snprintf(buf_ptr, remaining, + ",\"%s (%s)\":%s", reading->descr, reading->units, + reading->converted); + + if(len < 0 || len >= remaining) { + printf("Buffer too short. Have %d, need %d + \\0\n", remaining, len); + return; + } + remaining -= len; + buf_ptr += len; + } + } + + len = snprintf(buf_ptr, remaining, "}}"); + + if(len < 0 || len >= remaining) { + printf("Buffer too short. Have %d, need %d + \\0\n", remaining, len); + return; + } + + mqtt_publish(&conn, NULL, pub_topic, (uint8_t *)app_buffer, + strlen(app_buffer), MQTT_QOS_LEVEL_0, MQTT_RETAIN_OFF); + + DBG("APP - Publish!\n"); +} +/*---------------------------------------------------------------------------*/ +static void +connect_to_broker(void) +{ + /* Connect to MQTT server */ + mqtt_connect(&conn, conf->broker_ip, conf->broker_port, + conf->pub_interval * 3); + + state = MQTT_CLIENT_STATE_CONNECTING; +} +/*---------------------------------------------------------------------------*/ +static void +state_machine(void) +{ + switch(state) { + case MQTT_CLIENT_STATE_INIT: + /* If we have just been configured register MQTT connection */ + mqtt_register(&conn, &mqtt_client_process, client_id, mqtt_event, + MQTT_CLIENT_MAX_SEGMENT_SIZE); + + /* + * If we are not using the quickstart service (thus we are an IBM + * registered device), we need to provide user name and password + */ + if(strncasecmp(conf->org_id, QUICKSTART, strlen(conf->org_id)) != 0) { + if(strlen(conf->auth_token) == 0) { + printf("User name set, but empty auth token\n"); + state = MQTT_CLIENT_STATE_ERROR; + break; + } else { + mqtt_set_username_password(&conn, "use-token-auth", + conf->auth_token); + } + } + + /* _register() will set auto_reconnect. We don't want that. */ + conn.auto_reconnect = 0; + connect_attempt = 1; + + /* + * Wipe out the default route so we'll republish it every time we switch to + * a new broker + */ + memset(&def_route, 0, sizeof(def_route)); + + state = MQTT_CLIENT_STATE_REGISTERED; + DBG("Init\n"); + /* Continue */ + case MQTT_CLIENT_STATE_REGISTERED: + if(uip_ds6_get_global(ADDR_PREFERRED) != NULL) { + /* Registered and with a public IP. Connect */ + DBG("Registered. Connect attempt %u\n", connect_attempt); + connect_to_broker(); + } + etimer_set(&publish_periodic_timer, CC26XX_WEB_DEMO_NET_CONNECT_PERIODIC); + return; + break; + case MQTT_CLIENT_STATE_CONNECTING: + leds_on(CC26XX_WEB_DEMO_STATUS_LED); + ctimer_set(&ct, CONNECTING_LED_DURATION, publish_led_off, NULL); + /* Not connected yet. Wait */ + DBG("Connecting (%u)\n", connect_attempt); + break; + case MQTT_CLIENT_STATE_CONNECTED: + /* Don't subscribe unless we are a registered device */ + if(strncasecmp(conf->org_id, QUICKSTART, strlen(conf->org_id)) == 0) { + DBG("Using 'quickstart': Skipping subscribe\n"); + state = MQTT_CLIENT_STATE_PUBLISHING; + } + /* Continue */ + case MQTT_CLIENT_STATE_PUBLISHING: + /* If the timer expired, the connection is stable. */ + if(timer_expired(&connection_life)) { + /* + * Intentionally using 0 here instead of 1: We want RECONNECT_ATTEMPTS + * attempts if we disconnect after a successful connect + */ + connect_attempt = 0; + } + + if(mqtt_ready(&conn) && conn.out_buffer_sent) { + /* Connected. Publish */ + if(state == MQTT_CLIENT_STATE_CONNECTED) { + subscribe(); + state = MQTT_CLIENT_STATE_PUBLISHING; + } else { + leds_on(CC26XX_WEB_DEMO_STATUS_LED); + ctimer_set(&ct, PUBLISH_LED_ON_DURATION, publish_led_off, NULL); + publish(); + } + etimer_set(&publish_periodic_timer, conf->pub_interval); + + DBG("Publishing\n"); + /* Return here so we don't end up rescheduling the timer */ + return; + } else { + /* + * Our publish timer fired, but some MQTT packet is already in flight + * (either not sent at all, or sent but not fully ACKd). + * + * This can mean that we have lost connectivity to our broker or that + * simply there is some network delay. In both cases, we refuse to + * trigger a new message and we wait for TCP to either ACK the entire + * packet after retries, or to timeout and notify us. + */ + DBG("Publishing... (MQTT state=%d, q=%u)\n", conn.state, + conn.out_queue_full); + } + break; + case MQTT_CLIENT_STATE_DISCONNECTED: + DBG("Disconnected\n"); + if(connect_attempt < RECONNECT_ATTEMPTS || + RECONNECT_ATTEMPTS == RETRY_FOREVER) { + /* Disconnect and backoff */ + clock_time_t interval; + mqtt_disconnect(&conn); + connect_attempt++; + + interval = connect_attempt < 3 ? RECONNECT_INTERVAL << connect_attempt : + RECONNECT_INTERVAL << 3; + + DBG("Disconnected. Attempt %u in %lu ticks\n", connect_attempt, interval); + + etimer_set(&publish_periodic_timer, interval); + + state = MQTT_CLIENT_STATE_REGISTERED; + return; + } else { + /* Max reconnect attempts reached. Enter error state */ + state = MQTT_CLIENT_STATE_ERROR; + DBG("Aborting connection after %u attempts\n", connect_attempt - 1); + } + break; + case MQTT_CLIENT_STATE_NEWCONFIG: + /* Only update config after we have disconnected */ + if(conn.state == MQTT_CONN_STATE_NOT_CONNECTED) { + update_config(); + DBG("New config\n"); + + /* update_config() scheduled next pass. Return */ + return; + } + break; + case MQTT_CLIENT_STATE_CONFIG_ERROR: + /* Idle away. The only way out is a new config */ + printf("Bad configuration.\n"); + return; + case MQTT_CLIENT_STATE_ERROR: + default: + leds_on(CC26XX_WEB_DEMO_STATUS_LED); + /* + * 'default' should never happen. + * + * If we enter here it's because of some error. Stop timers. The only thing + * that can bring us out is a new config event + */ + printf("Default case: State=0x%02x\n", state); + return; + } + + /* If we didn't return so far, reschedule ourselves */ + etimer_set(&publish_periodic_timer, STATE_MACHINE_PERIODIC); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(mqtt_client_process, ev, data) +{ + + PROCESS_BEGIN(); + + printf("CC26XX MQTT Client Process\n"); + + conf = &cc26xx_web_demo_config.mqtt_config; + if(init_config() != 1) { + PROCESS_EXIT(); + } + + register_http_post_handlers(); + + update_config(); + + /* Main loop */ + while(1) { + + PROCESS_YIELD(); + + if(ev == sensors_event && data == CC26XX_WEB_DEMO_MQTT_PUBLISH_TRIGGER) { + if(state == MQTT_CLIENT_STATE_ERROR) { + connect_attempt = 1; + state = MQTT_CLIENT_STATE_REGISTERED; + } + } + + if(ev == httpd_simple_event_new_config) { + /* + * Schedule next pass in a while. When HTTPD sends us this event, it is + * also in the process of sending the config page. Wait a little before + * reconnecting, so as to not cause congestion. + */ + etimer_set(&publish_periodic_timer, NEW_CONFIG_WAIT_INTERVAL); + } + + if((ev == PROCESS_EVENT_TIMER && data == &publish_periodic_timer) || + ev == PROCESS_EVENT_POLL || + ev == cc26xx_web_demo_publish_event || + (ev == sensors_event && data == CC26XX_WEB_DEMO_MQTT_PUBLISH_TRIGGER)) { + state_machine(); + } + + if(ev == cc26xx_web_demo_load_config_defaults) { + init_config(); + etimer_set(&publish_periodic_timer, NEW_CONFIG_WAIT_INTERVAL); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/examples/cc26xx/cc26xx-web-demo/mqtt-client.h b/examples/cc26xx/cc26xx-web-demo/mqtt-client.h new file mode 100644 index 000000000..ab7c08227 --- /dev/null +++ b/examples/cc26xx/cc26xx-web-demo/mqtt-client.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc26xx-web-demo + * @{ + * + * \file + * Header file for the CC26xx web demo MQTT client functionality + */ +/*---------------------------------------------------------------------------*/ +#ifndef MQTT_CLIENT_H_ +#define MQTT_CLIENT_H_ +/*---------------------------------------------------------------------------*/ +#define MQTT_CLIENT_CONFIG_ORG_ID_LEN 32 +#define MQTT_CLIENT_CONFIG_TYPE_ID_LEN 32 +#define MQTT_CLIENT_CONFIG_AUTH_TOKEN_LEN 32 +#define MQTT_CLIENT_CONFIG_EVENT_TYPE_ID_LEN 32 +#define MQTT_CLIENT_CONFIG_CMD_TYPE_LEN 8 +#define MQTT_CLIENT_CONFIG_IP_ADDR_STR_LEN 64 +/*---------------------------------------------------------------------------*/ +#define MQTT_CLIENT_PUBLISH_INTERVAL_MAX 86400 /* secs: 1 day */ +#define MQTT_CLIENT_PUBLISH_INTERVAL_MIN 5 /* secs */ +/*---------------------------------------------------------------------------*/ +PROCESS_NAME(mqtt_client_process); +/*---------------------------------------------------------------------------*/ +/** + * \brief Data structure declaration for the MQTT client configuration + */ +typedef struct mqtt_client_config { + char org_id[MQTT_CLIENT_CONFIG_ORG_ID_LEN]; + char type_id[MQTT_CLIENT_CONFIG_TYPE_ID_LEN]; + char auth_token[MQTT_CLIENT_CONFIG_AUTH_TOKEN_LEN]; + char event_type_id[MQTT_CLIENT_CONFIG_EVENT_TYPE_ID_LEN]; + char broker_ip[MQTT_CLIENT_CONFIG_IP_ADDR_STR_LEN]; + char cmd_type[MQTT_CLIENT_CONFIG_CMD_TYPE_LEN]; + clock_time_t pub_interval; + uint16_t broker_port; +} mqtt_client_config_t; +/*---------------------------------------------------------------------------*/ +#endif /* MQTT_CLIENT_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/examples/cc26xx/cc26xx-web-demo/net-uart.c b/examples/cc26xx/cc26xx-web-demo/net-uart.c new file mode 100644 index 000000000..c3ddf0977 --- /dev/null +++ b/examples/cc26xx/cc26xx-web-demo/net-uart.c @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc26xx-web-demo + * @{ + * + * \file + * A process which receives data over UART and transmits them over UDP + * to a pre-defined IPv6 address and port. It also listens on the same UDP + * port for messages, which it prints out over UART. + * + * For this example to work, you will have to modify the destination IPv6 + * address by adjusting the set_dest_addr() macro below. + * + * To listen on your linux or OS X box: + * nc -6ulkw 1 REMOTE_PORT + * + * (REMOTE_PORT should be the actual value of the define below, e.g. 7777) + * + * Once netcat is up and listening, type something to the CC26xx's terminal + * Bear in mind that the datagram will only be sent after a 0x0a (LF) char + * has been received. Therefore, if you are on Win, do NOT use PuTTY for + * this purpose, since it does not send 0x0a as part of the line end. On + * Win XP use hyperterm. On Win 7 use some other software (e.g. Tera Term, + * which can be configured to send CRLF on enter keystrokes). + * + * To send data in the other direction from your linux or OS X box: + * + * nc -6u \ REMOTE_PORT + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "sys/process.h" +#include "dev/serial-line.h" +#include "dev/cc26xx-uart.h" +#include "net/ip/uip.h" +#include "net/ip/uip-udp-packet.h" +#include "net/ip/uiplib.h" +#include "net-uart.h" +#include "httpd-simple.h" +#include "sys/cc.h" + +#include "ti-lib.h" + +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" +/*---------------------------------------------------------------------------*/ +#define REMOTE_PORT 7777 +#define MAX_MSG_SIZE 100 + +#define set_dest_addr() uip_ip6addr(&remote_addr, \ + 0xBBBB, 0x0000, 0x0000, 0x0000, \ + 0x3E07, 0x54FF, 0xFE74, 0x4885); +/*---------------------------------------------------------------------------*/ +#define ADDRESS_CONVERSION_OK 1 +#define ADDRESS_CONVERSION_ERROR 0 +/*---------------------------------------------------------------------------*/ +static struct uip_udp_conn *udp_conn = NULL; + +static uint8_t buffer[MAX_MSG_SIZE]; +static uint8_t msg_len; +static uip_ip6addr_t remote_addr; +/*---------------------------------------------------------------------------*/ +#define IPV6_ADDR_STR_LEN 64 +/*---------------------------------------------------------------------------*/ +PROCESS(net_uart_process, "Net UART Process"); +/*---------------------------------------------------------------------------*/ +/* + * \brief Attempts to convert a string representation of an IPv6 address to a + * numeric one. + * \param buf The buffer with the string to be converted. + * \return ADDRESS_CONVERSION_OK or ADDRESS_CONVERSION_ERROR + * + * ToDo: Add support for NAT64 conversion in case the incoming address is a v4 + * This is now supported in the current master, so when we pull it in this will + * be very straightforward. + */ +static int +set_new_ip_address(char *buf) +{ + /* + * uiplib_ip6addrconv will immediately start writing into the supplied buffer + * even if it subsequently fails. Thus, pass an intermediate buffer + */ + uip_ip6addr_t tmp_addr; + + int rv = uiplib_ip6addrconv(buf, &tmp_addr); + + if(rv == ADDRESS_CONVERSION_OK) { + /* Conversion OK, copy to our main buffer */ + memcpy(&remote_addr, &tmp_addr, sizeof(remote_addr)); + + PRINTF("Updated remote address "); + PRINT6ADDR(&remote_addr); + PRINTF("\n"); + } + + return rv; +} +/*---------------------------------------------------------------------------*/ +static void +net_input(void) +{ + if(uip_newdata()) { + memset(buffer, 0, MAX_MSG_SIZE); + msg_len = MIN(uip_datalen(), MAX_MSG_SIZE - 1); + + /* Copy data */ + memcpy(buffer, uip_appdata, msg_len); + printf("%s", (char *)buffer); + } + + return; +} +/*---------------------------------------------------------------------------*/ +static void +release_uart(void) +{ + cc26xx_uart_set_input(NULL); +} +/*---------------------------------------------------------------------------*/ +static void +keep_uart_on(void) +{ + cc26xx_uart_set_input(serial_line_input_byte); +} +/*---------------------------------------------------------------------------*/ +static int +remote_port_post_handler(char *key, int key_len, char *val, int val_len) +{ + int rv; + + if(key_len != strlen("net_uart_port") || + strncasecmp(key, "net_uart_port", strlen("net_uart_port")) != 0) { + /* Not ours */ + return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + } + + rv = atoi(val); + + if(rv <= 65535 && rv > 0) { + cc26xx_web_demo_config.net_uart.remote_port = (uint16_t)rv; + } else { + return HTTPD_SIMPLE_POST_HANDLER_ERROR; + } + + return HTTPD_SIMPLE_POST_HANDLER_OK; +} +/*---------------------------------------------------------------------------*/ +static int +remote_ipv6_post_handler(char *key, int key_len, char *val, int val_len) +{ + int rv = HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + + if(key_len != strlen("net_uart_ip") || + strncasecmp(key, "net_uart_ip", strlen("net_uart_ip")) != 0) { + /* Not ours */ + return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + } + + if(val_len > IPV6_ADDR_STR_LEN) { + /* Ours but bad value */ + rv = HTTPD_SIMPLE_POST_HANDLER_ERROR; + } else { + if(set_new_ip_address(val)) { + memset(cc26xx_web_demo_config.net_uart.remote_address, 0, + NET_UART_IP_ADDR_STRLEN); + memcpy(cc26xx_web_demo_config.net_uart.remote_address, val, val_len); + rv = HTTPD_SIMPLE_POST_HANDLER_OK; + } + } + + return rv; +} +/*---------------------------------------------------------------------------*/ +static int +on_off_post_handler(char *key, int key_len, char *val, int val_len) +{ + int rv; + + if(key_len != strlen("net_uart_on") || + strncasecmp(key, "net_uart_on", strlen("net_uart_on")) != 0) { + /* Not ours */ + return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + } + + rv = atoi(val); + + /* Be pedantic: only accept 0 and 1, not just any non-zero value */ + if(rv == 0) { + cc26xx_web_demo_config.net_uart.enable = 0; + release_uart(); + } else if(rv == 1) { + cc26xx_web_demo_config.net_uart.enable = 1; + keep_uart_on(); + } else { + return HTTPD_SIMPLE_POST_HANDLER_ERROR; + } + + return HTTPD_SIMPLE_POST_HANDLER_OK; +} +/*---------------------------------------------------------------------------*/ +HTTPD_SIMPLE_POST_HANDLER(remote_port, remote_port_post_handler); +HTTPD_SIMPLE_POST_HANDLER(remote_ipv6, remote_ipv6_post_handler); +HTTPD_SIMPLE_POST_HANDLER(on_off, on_off_post_handler); +/*---------------------------------------------------------------------------*/ +static void +set_config_defaults(void) +{ + /* Set a hard-coded destination address to start with */ + set_dest_addr(); + + /* Set config defaults */ + cc26xx_web_demo_ipaddr_sprintf(cc26xx_web_demo_config.net_uart.remote_address, + NET_UART_IP_ADDR_STRLEN, &remote_addr); + cc26xx_web_demo_config.net_uart.remote_port = REMOTE_PORT; + cc26xx_web_demo_config.net_uart.enable = 1; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(net_uart_process, ev, data) +{ + PROCESS_BEGIN(); + + printf("CC26XX Net UART Process\n"); + + set_config_defaults(); + + udp_conn = udp_new(NULL, UIP_HTONS(0), NULL); + udp_bind(udp_conn, UIP_HTONS(REMOTE_PORT)); + + if(udp_conn == NULL) { + printf("No UDP connection available, exiting the process!\n"); + PROCESS_EXIT(); + } + + httpd_simple_register_post_handler(&remote_port_handler); + httpd_simple_register_post_handler(&remote_ipv6_handler); + httpd_simple_register_post_handler(&on_off_handler); + + while(1) { + + PROCESS_YIELD(); + + if(ev == serial_line_event_message) { + /* + * If the message contains a new IP address, save it and go back to + * waiting. + */ + if(set_new_ip_address((char *)data) == ADDRESS_CONVERSION_ERROR) { + /* Not an IP address in the message. Send to current destination */ + memset(buffer, 0, MAX_MSG_SIZE); + + /* We need to add a line feed, thus never fill the entire buffer */ + msg_len = MIN(strlen(data), MAX_MSG_SIZE - 1); + memcpy(buffer, data, msg_len); + + /* Add a line feed */ + buffer[msg_len] = 0x0A; + msg_len++; + + uip_udp_packet_sendto( + udp_conn, buffer, msg_len, &remote_addr, + UIP_HTONS(cc26xx_web_demo_config.net_uart.remote_port)); + } + } else if(ev == tcpip_event) { + net_input(); + } else if(ev == cc26xx_web_demo_config_loaded_event) { + /* + * New config. Check if it's possible to update the remote address. + * The port will have been updated already + */ + set_new_ip_address(cc26xx_web_demo_config.net_uart.remote_address); + + if(cc26xx_web_demo_config.net_uart.enable == 1) { + keep_uart_on(); + } + } else if(ev == cc26xx_web_demo_load_config_defaults) { + set_config_defaults(); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/examples/cc26xx/cc26xx-web-demo/net-uart.h b/examples/cc26xx/cc26xx-web-demo/net-uart.h new file mode 100644 index 000000000..5c4201672 --- /dev/null +++ b/examples/cc26xx/cc26xx-web-demo/net-uart.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +#ifndef NET_UART_H_ +#define NET_UART_H_ +/*---------------------------------------------------------------------------*/ +#include "net/ip/uip.h" + +#include +/*---------------------------------------------------------------------------*/ +#define NET_UART_IP_ADDR_STRLEN 64 +/*---------------------------------------------------------------------------*/ +PROCESS_NAME(net_uart_process); +/*---------------------------------------------------------------------------*/ +typedef struct net_uart_config_s { + char remote_address[NET_UART_IP_ADDR_STRLEN]; + uint16_t remote_port; + uint8_t enable; +} net_uart_config_t; +/*---------------------------------------------------------------------------*/ +#endif /* NET_UART_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/cc26xx/cc26xx-web-demo/project-conf.h b/examples/cc26xx/cc26xx-web-demo/project-conf.h new file mode 100644 index 000000000..ee77b125f --- /dev/null +++ b/examples/cc26xx/cc26xx-web-demo/project-conf.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ +/*---------------------------------------------------------------------------*/ +/* Change to match your configuration */ +#define IEEE802154_CONF_PANID 0xABCD +#define RF_CORE_CONF_CHANNEL 25 +#define RF_BLE_CONF_ENABLED 1 +/*---------------------------------------------------------------------------*/ +/* Enable/Disable Components of this Demo */ +#define CC26XX_WEB_DEMO_CONF_MQTT_CLIENT 1 +#define CC26XX_WEB_DEMO_CONF_6LBR_CLIENT 1 +#define CC26XX_WEB_DEMO_CONF_COAP_SERVER 1 +#define CC26XX_WEB_DEMO_CONF_NET_UART 1 +/*---------------------------------------------------------------------------*/ +/* + * Shrink the size of the uIP buffer, routing table and ND cache. + * Set the TCP MSS + */ +#define UIP_CONF_BUFFER_SIZE 900 +#define NBR_TABLE_CONF_MAX_NEIGHBORS 8 +#define UIP_CONF_MAX_ROUTES 8 +#define UIP_CONF_TCP_MSS 128 +/*---------------------------------------------------------------------------*/ +#endif /* PROJECT_CONF_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/cc26xx/cc26xx-web-demo/resources/res-ble-advd.c b/examples/cc26xx/cc26xx-web-demo/resources/res-ble-advd.c new file mode 100644 index 000000000..68693b737 --- /dev/null +++ b/examples/cc26xx/cc26xx-web-demo/resources/res-ble-advd.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-web-demo + * @{ + * + * \file + * CoAP resource to start/stop/configure BLE advertisements + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "rest-engine.h" +#include "er-coap.h" +#include "rf-core/rf-ble.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define BLE_NAME_BUF_LEN 32 +/*---------------------------------------------------------------------------*/ +const char *forbidden_payload = "Name to advertise unspecified.\n" + "Use name= in the request"; +/*---------------------------------------------------------------------------*/ +static void +res_ble_post_put_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + size_t len = 0; + const char *text = NULL; + char name[BLE_NAME_BUF_LEN]; + int success = 0; + int rv; + + memset(name, 0, BLE_NAME_BUF_LEN); + + len = REST.get_post_variable(request, "name", &text); + + if(len > 0 && len < BLE_NAME_BUF_LEN) { + memcpy(name, text, len); + rf_ble_beacond_config(0, name); + success = 1; + } + + len = REST.get_post_variable(request, "interval", &text); + + rv = atoi(text); + + if(rv > 0) { + rf_ble_beacond_config((clock_time_t)(rv * CLOCK_SECOND), NULL); + success = 1; + } + + len = REST.get_post_variable(request, "mode", &text); + + if(len) { + if(strncmp(text, "on", len) == 0) { + if(rf_ble_beacond_start()) { + success = 1; + } else { + REST.set_response_status(response, REST.status.FORBIDDEN); + REST.set_response_payload(response, forbidden_payload, + strlen(forbidden_payload)); + return; + } + } else if(strncmp(text, "off", len) == 0) { + rf_ble_beacond_stop(); + success = 1; + } else { + success = 0; + } + } + + if(!success) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} +/*---------------------------------------------------------------------------*/ +RESOURCE(res_ble_advd, + "title=\"BLE advd config: POST/PUT name=&mode=on|off" + "&interval=\";rt=\"Control\"", + NULL, + res_ble_post_put_handler, + res_ble_post_put_handler, + NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/examples/cc26xx/cc26xx-web-demo/resources/res-device.c b/examples/cc26xx/cc26xx-web-demo/resources/res-device.c new file mode 100644 index 000000000..62e8dc6dc --- /dev/null +++ b/examples/cc26xx/cc26xx-web-demo/resources/res-device.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-web-demo + * @{ + * + * \file + * CoAP resource handler for CC26XX software and hardware version + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "rest-engine.h" +#include "er-coap.h" +#include "sys/clock.h" +#include "coap-server.h" +#include "cc26xx-web-demo.h" + +#include "ti-lib.h" + +#include +/*---------------------------------------------------------------------------*/ +static uint16_t +detect_chip(void) +{ + if(ti_lib_chipinfo_chip_family_is_cc26xx()) { + if(ti_lib_chipinfo_supports_ieee_802_15_4() == true) { + if(ti_lib_chipinfo_supports_ble() == true) { + return 2650; + } else { + return 2630; + } + } else { + return 2640; + } + } else if(ti_lib_chipinfo_chip_family_is_cc13xx()) { + if(ti_lib_chipinfo_supports_ble() == false && + ti_lib_chipinfo_supports_ieee_802_15_4() == false) { + return 1310; + } else if(ti_lib_chipinfo_supports_ble() == true && + ti_lib_chipinfo_supports_ieee_802_15_4() == true) { + return 1350; + } + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +res_get_handler_hw(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + uint16_t chip = detect_chip(); + + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s on CC%u", BOARD_STRING, + chip); + + REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"HW Ver\":\"%s on CC%u\"}", + BOARD_STRING, chip); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_XML) { + REST.set_header_content_type(response, REST.type.APPLICATION_XML); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "", BOARD_STRING, + chip); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, coap_server_supported_msg, + strlen(coap_server_supported_msg)); + } +} +/*---------------------------------------------------------------------------*/ +static void +res_get_handler_sw(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", CONTIKI_VERSION_STRING); + + REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"SW Ver\":\"%s\"}", + CONTIKI_VERSION_STRING); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_XML) { + REST.set_header_content_type(response, REST.type.APPLICATION_XML); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "", CONTIKI_VERSION_STRING); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, coap_server_supported_msg, + strlen(coap_server_supported_msg)); + } +} +/*---------------------------------------------------------------------------*/ +static void +res_get_handler_uptime(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%lu", clock_seconds()); + + REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"uptime\":%lu}", + clock_seconds()); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_XML) { + REST.set_header_content_type(response, REST.type.APPLICATION_XML); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "", clock_seconds()); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, coap_server_supported_msg, + strlen(coap_server_supported_msg)); + } +} +/*---------------------------------------------------------------------------*/ +static void +res_post_handler_cfg_reset(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + cc26xx_web_demo_restore_defaults(); +} +/*---------------------------------------------------------------------------*/ +RESOURCE(res_device_sw, + "title=\"Software version\";rt=\"text\"", + res_get_handler_sw, + NULL, + NULL, + NULL); +/*---------------------------------------------------------------------------*/ +RESOURCE(res_device_uptime, + "title=\"Uptime\";rt=\"seconds\"", + res_get_handler_uptime, + NULL, + NULL, + NULL); +/*---------------------------------------------------------------------------*/ +RESOURCE(res_device_hw, + "title=\"Hardware version\";rt=\"text\"", + res_get_handler_hw, + NULL, + NULL, + NULL); +/*---------------------------------------------------------------------------*/ +RESOURCE(res_device_cfg_reset, + "title=\"Reset Device Config: POST\";rt=\"Control\"", + NULL, res_post_handler_cfg_reset, NULL, NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/examples/cc26xx/cc26xx-web-demo/resources/res-leds.c b/examples/cc26xx/cc26xx-web-demo/resources/res-leds.c new file mode 100644 index 000000000..85ce353b5 --- /dev/null +++ b/examples/cc26xx/cc26xx-web-demo/resources/res-leds.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-web-demo + * @{ + * + * \file + * CoAP resource handler for the CC26xx LEDs. Slightly modified copy of + * the one found in Contiki's original CoAP example. + * \author + * Matthias Kovatsch (original) + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "rest-engine.h" +#include "dev/leds.h" + +#include +/*---------------------------------------------------------------------------*/ +static void +res_post_put_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + size_t len = 0; + const char *color = NULL; + const char *mode = NULL; + uint8_t led = 0; + int success = 1; + + if((len = REST.get_query_variable(request, "color", &color))) { + if(strncmp(color, "r", len) == 0) { + led = LEDS_RED; + } else if(strncmp(color, "g", len) == 0) { + led = LEDS_GREEN; +#if BOARD_SMARTRF06EB + } else if(strncmp(color, "y", len) == 0) { + led = LEDS_YELLOW; + } else if(strncmp(color, "o", len) == 0) { + led = LEDS_ORANGE; +#endif + } else { + success = 0; + } + } else { + success = 0; + } + + if(success && (len = REST.get_post_variable(request, "mode", &mode))) { + if(strncmp(mode, "on", len) == 0) { + leds_on(led); + } else if(strncmp(mode, "off", len) == 0) { + leds_off(led); + } else { + success = 0; + } + } else { + success = 0; + } + + if(!success) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} +/*---------------------------------------------------------------------------*/ +/* + * A simple actuator example, depending on the color query parameter and post + * variable mode, corresponding led is activated or deactivated + */ +#if BOARD_SENSORTAG || BOARD_LAUNCHPAD +#define RESOURCE_PARAMS "r|g" +#elif BOARD_SMARTRF06EB +#define RESOURCE_PARAMS "r|g|y|o" +#endif + +RESOURCE(res_leds, + "title=\"LEDs: ?color=" RESOURCE_PARAMS ", POST/PUT mode=on|off\";rt=\"Control\"", + NULL, + res_post_put_handler, + res_post_put_handler, + NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/examples/cc26xx/cc26xx-web-demo/resources/res-net.c b/examples/cc26xx/cc26xx-web-demo/resources/res-net.c new file mode 100644 index 000000000..1a5ce7b81 --- /dev/null +++ b/examples/cc26xx/cc26xx-web-demo/resources/res-net.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-web-demo + * @{ + * + * \file + * CoAP resource handler for network-related resources + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "rest-engine.h" +#include "er-coap.h" +#include "coap-server.h" +#include "cc26xx-web-demo.h" + +#include "ti-lib.h" + +#include +/*---------------------------------------------------------------------------*/ +extern int def_rt_rssi; +/*---------------------------------------------------------------------------*/ +static void +res_get_handler_parent_rssi(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", def_rt_rssi); + + REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"Parent RSSI\":\"%d\"}", + def_rt_rssi); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_XML) { + REST.set_header_content_type(response, REST.type.APPLICATION_XML); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "", def_rt_rssi); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, coap_server_supported_msg, + strlen(coap_server_supported_msg)); + } +} +/*---------------------------------------------------------------------------*/ +static void +res_get_handler_pref_parent(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + char def_rt_str[64]; + + REST.get_header_accept(request, &accept); + + memset(def_rt_str, 0, sizeof(def_rt_str)); + cc26xx_web_demo_ipaddr_sprintf(def_rt_str, sizeof(def_rt_str), + uip_ds6_defrt_choose()); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", def_rt_str); + + REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"Parent\":\"%s\"}", + def_rt_str); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_XML) { + REST.set_header_content_type(response, REST.type.APPLICATION_XML); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "", def_rt_str); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, coap_server_supported_msg, + strlen(coap_server_supported_msg)); + } +} +/*---------------------------------------------------------------------------*/ +RESOURCE(res_parent_rssi, "title=\"Parent RSSI\";rt=\"dBm\"", + res_get_handler_parent_rssi, NULL, NULL, NULL); +/*---------------------------------------------------------------------------*/ +RESOURCE(res_parent_ip, "title=\"Preferred Parent\";rt=\"IPv6 address\"", + res_get_handler_pref_parent, NULL, NULL, NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/examples/cc26xx/cc26xx-web-demo/resources/res-sensors.c b/examples/cc26xx/cc26xx-web-demo/resources/res-sensors.c new file mode 100644 index 000000000..277c29c05 --- /dev/null +++ b/examples/cc26xx/cc26xx-web-demo/resources/res-sensors.c @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-web-demo + * @{ + * + * \file + * CoAP resource handler for the Sensortag-CC26xx sensors + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "rest-engine.h" +#include "er-coap.h" +#include "cc26xx-web-demo.h" +#include "coap-server.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +/* + * Generic resource handler for any sensor in this example. Ultimately gets + * called by all handlers and populates the CoAP response + */ +static void +res_get_handler_all(int sens_type, void *request, void *response, + uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + const cc26xx_web_demo_sensor_reading_t *reading; + + reading = cc26xx_web_demo_sensor_lookup(sens_type); + + if(reading == NULL) { + REST.set_response_status(response, REST.status.NOT_FOUND); + REST.set_response_payload(response, coap_server_not_found_msg, + strlen(coap_server_not_found_msg)); + return; + } + + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", reading->converted); + + REST.set_response_payload(response, (uint8_t *)buffer, + strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"%s\":%s}", + reading->descr, reading->converted); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_XML) { + REST.set_header_content_type(response, REST.type.APPLICATION_XML); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "<%s val=\"%s\" unit=\"%s\"/>", reading->xml_element, + reading->converted, reading->units); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, coap_server_supported_msg, + strlen(coap_server_supported_msg)); + } +} +/*---------------------------------------------------------------------------*/ +/* BatMon resources and handler: Temperature, Voltage */ +static void +res_get_handler_batmon_temp(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_BATMON_TEMP, request, response, + buffer, preferred_size, offset); +} +/*---------------------------------------------------------------------------*/ +static void +res_get_handler_batmon_volt(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_BATMON_VOLT, request, response, + buffer, preferred_size, offset); +} +/*---------------------------------------------------------------------------*/ +RESOURCE(res_batmon_temp, "title=\"Battery Temp\";rt=\"C\"", + res_get_handler_batmon_temp, NULL, NULL, NULL); +/*---------------------------------------------------------------------------*/ +RESOURCE(res_batmon_volt, "title=\"Battery Voltage\";rt=\"mV\"", + res_get_handler_batmon_volt, NULL, NULL, NULL); +/*---------------------------------------------------------------------------*/ +#if BOARD_SENSORTAG +/*---------------------------------------------------------------------------*/ +/* MPU resources and handler: Accelerometer and Gyro */ +static void +res_get_handler_mpu_acc_x(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_MPU_ACC_X, request, response, + buffer, preferred_size, offset); +} +/*---------------------------------------------------------------------------*/ +static void +res_get_handler_mpu_acc_y(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_MPU_ACC_Y, request, response, + buffer, preferred_size, offset); +} +/*---------------------------------------------------------------------------*/ +static void +res_get_handler_mpu_acc_z(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_MPU_ACC_Z, request, response, + buffer, preferred_size, offset); +} +/*---------------------------------------------------------------------------*/ +static void +res_get_handler_mpu_gyro_x(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_MPU_GYRO_X, request, response, + buffer, preferred_size, offset); +} +/*---------------------------------------------------------------------------*/ +static void +res_get_handler_mpu_gyro_y(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_MPU_GYRO_Y, request, response, + buffer, preferred_size, offset); +} +/*---------------------------------------------------------------------------*/ +static void +res_get_handler_mpu_gyro_z(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_MPU_GYRO_Z, request, response, + buffer, preferred_size, offset); +} +/*---------------------------------------------------------------------------*/ +RESOURCE(res_mpu_acc_x, "title=\"Acc X\";rt=\"G\"", res_get_handler_mpu_acc_x, + NULL, NULL, NULL); +RESOURCE(res_mpu_acc_y, "title=\"Acc Y\";rt=\"G\"", res_get_handler_mpu_acc_y, + NULL, NULL, NULL); +RESOURCE(res_mpu_acc_z, "title=\"Acc Z\";rt=\"G\"", res_get_handler_mpu_acc_z, + NULL, NULL, NULL); + +RESOURCE(res_mpu_gyro_x, "title=\"Gyro X\";rt=\"deg/sec\"", + res_get_handler_mpu_gyro_x, NULL, NULL, NULL); +RESOURCE(res_mpu_gyro_y, "title=\"Gyro Y\";rt=\"deg/sec\"", + res_get_handler_mpu_gyro_y, NULL, NULL, NULL); +RESOURCE(res_mpu_gyro_z, "title=\"Gyro Z\";rt=\"deg/sec\"", + res_get_handler_mpu_gyro_z, NULL, NULL, NULL); +/*---------------------------------------------------------------------------*/ +/* TMP sensor resources and handlers: Object, Ambient */ +static void +res_get_handler_obj_temp(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_TMP_OBJECT, request, response, + buffer, preferred_size, offset); +} +/*---------------------------------------------------------------------------*/ +static void +res_get_handler_amb_temp(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_TMP_AMBIENT, request, response, + buffer, preferred_size, offset); +} +/*---------------------------------------------------------------------------*/ +RESOURCE(res_tmp007_obj, "title=\"Temperature (Object)\";rt=\"C\"", + res_get_handler_obj_temp, NULL, NULL, NULL); + +RESOURCE(res_tmp007_amb, "title=\"Temperature (Ambient)\";rt=\"C\"", + res_get_handler_amb_temp, NULL, NULL, NULL); +/*---------------------------------------------------------------------------*/ +/* BMP sensor resources: Temperature, Pressure */ +static void +res_get_handler_bmp_temp(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_BMP_TEMP, request, response, + buffer, preferred_size, offset); +} +/*---------------------------------------------------------------------------*/ +static void +res_get_handler_bmp_press(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_BMP_PRES, request, response, + buffer, preferred_size, offset); +} +/*---------------------------------------------------------------------------*/ +RESOURCE(res_bmp280_temp, "title=\"Barometer (Temperature)\";rt=\"C\"", + res_get_handler_bmp_temp, NULL, NULL, NULL); + +RESOURCE(res_bmp280_press, + "title=\"Barometer (Pressure)\";rt=\"hPa (hectopascal / millibar)\"", + res_get_handler_bmp_press, NULL, NULL, NULL); +/*---------------------------------------------------------------------------*/ +/* HDC1000 sensor resources and handler: Temperature, Pressure */ +static void +res_get_handler_hdc_temp(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_HDC_TEMP, request, response, + buffer, preferred_size, offset); +} +/*---------------------------------------------------------------------------*/ +static void +res_get_handler_hdc_humidity(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_HDC_HUMIDITY, request, response, + buffer, preferred_size, offset); +} +/*---------------------------------------------------------------------------*/ +RESOURCE(res_hdc1000_temp, "title=\"Temperature\";rt=\"C\"", + res_get_handler_hdc_temp, NULL, NULL, NULL); + +RESOURCE(res_hdc1000_hum, "title=\"Humidity\";rt=\"%RH\"", + res_get_handler_hdc_humidity, NULL, NULL, NULL); +/*---------------------------------------------------------------------------*/ +/* Illuminance resources and handler */ +static void +res_get_handler_opt(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_OPT_LIGHT, request, response, + buffer, preferred_size, offset); +} +/*---------------------------------------------------------------------------*/ +RESOURCE(res_opt3001_light, "title=\"Illuminance\";rt=\"Lux\"", + res_get_handler_opt, NULL, NULL, NULL); +/*---------------------------------------------------------------------------*/ +#endif /* BOARD_SENSORTAG */ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/examples/cc26xx/cc26xx-web-demo/resources/res-toggle-leds.c b/examples/cc26xx/cc26xx-web-demo/resources/res-toggle-leds.c new file mode 100644 index 000000000..2fb424a03 --- /dev/null +++ b/examples/cc26xx/cc26xx-web-demo/resources/res-toggle-leds.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-web-demo + * @{ + * + * \file + * CoAP resource to toggle LEDs. Slightly modified copy of the one found + * in Contiki's original CoAP example. + * \author + * Matthias Kovatsch (original) + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "rest-engine.h" +#include "dev/leds.h" + +#include +/*---------------------------------------------------------------------------*/ +static void +res_post_handler_red(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + leds_toggle(LEDS_RED); +} +/*---------------------------------------------------------------------------*/ +static void +res_post_handler_green(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + leds_toggle(LEDS_GREEN); +} +/*---------------------------------------------------------------------------*/ +/* Toggles the red led */ +RESOURCE(res_toggle_red, + "title=\"Red LED\";rt=\"Control\"", + NULL, + res_post_handler_red, + NULL, + NULL); + +/* Toggles the green led */ +RESOURCE(res_toggle_green, + "title=\"Green LED\";rt=\"Control\"", + NULL, + res_post_handler_green, + NULL, + NULL); +/*---------------------------------------------------------------------------*/ +/* An additional 2 LEDs on the Srf */ +#if BOARD_SMARTRF06EB +/*---------------------------------------------------------------------------*/ +static void +res_post_handler_yellow(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + leds_toggle(LEDS_YELLOW); +} +/*---------------------------------------------------------------------------*/ +static void +res_post_handler_orange(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + leds_toggle(LEDS_ORANGE); +} +/*---------------------------------------------------------------------------*/ +/* Toggles the yellow led */ +RESOURCE(res_toggle_yellow, + "title=\"Yellow LED\";rt=\"Control\"", + NULL, + res_post_handler_yellow, + NULL, + NULL); + +/* Toggles the orange led */ +RESOURCE(res_toggle_orange, + "title=\"Orange LED\";rt=\"Control\"", + NULL, + res_post_handler_orange, + NULL, + NULL); +#endif +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/examples/cc26xx/project-conf.h b/examples/cc26xx/project-conf.h new file mode 100644 index 000000000..7c1363c16 --- /dev/null +++ b/examples/cc26xx/project-conf.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ +/*---------------------------------------------------------------------------*/ +/* Disable button shutdown functionality */ +#define BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN 0 +/*---------------------------------------------------------------------------*/ +/* Change to match your configuration */ +#define IEEE802154_CONF_PANID 0xABCD +#define RF_CORE_CONF_CHANNEL 25 +#define RF_BLE_CONF_ENABLED 1 +/*---------------------------------------------------------------------------*/ +#endif /* PROJECT_CONF_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/cc26xx/very-sleepy-demo/Makefile b/examples/cc26xx/very-sleepy-demo/Makefile new file mode 100644 index 000000000..a1e794957 --- /dev/null +++ b/examples/cc26xx/very-sleepy-demo/Makefile @@ -0,0 +1,12 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" +CONTIKI_PROJECT = very-sleepy-demo + +all: $(CONTIKI_PROJECT) + +CONTIKI_WITH_IPV6 = 1 + +APPS += er-coap +APPS += rest-engine + +CONTIKI = ../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/cc26xx/very-sleepy-demo/Makefile.target b/examples/cc26xx/very-sleepy-demo/Makefile.target new file mode 100644 index 000000000..15890aa6a --- /dev/null +++ b/examples/cc26xx/very-sleepy-demo/Makefile.target @@ -0,0 +1 @@ +TARGET = srf06-cc26xx diff --git a/examples/cc26xx/very-sleepy-demo/README.md b/examples/cc26xx/very-sleepy-demo/README.md new file mode 100644 index 000000000..fcdedf77f --- /dev/null +++ b/examples/cc26xx/very-sleepy-demo/README.md @@ -0,0 +1,91 @@ +# CC13xx/CC26xx Very Sleepy Demo + +This example demonstrates a way of deploying a very low-consuming, very sleepy +node. The node has two modes of operation: + +* Normal: ContikiMAC duty-cycles the radio as usual. The node is reachable. +* Very Sleepy: Radio cycling mostly off, except when we need to perform network + maintenance tasks. In this mode, the node is unreachable for most of the time. + +The node will operate in RPL leaf mode. This means that it will be reachable +downwards, but it will not advertise the DODAG and it will not participate in +routing. + +After booting, the node will enter "normal" mode. + +The node exposes an OBSERVEable CoAP resource. It will notify subscribers with +a new value for this resource every `interval` seconds. It will then stay in +normal mode for `duration` seconds. During this time window, it will be +reachable over the network in order to e.g. receive a new configuration. +When this time window expires, the node will switch back to very sleepy mode. +This will only happen if very sleepy mode has been enabled by setting `mode=1` +as per the instructions below. + +When the node is duty-cycling the radio, either because it is in normal mode or +because network maintenance is taking place, it will keep its green LED on thus +providing an indication that it is reachable. + +A normal mode stint can be manually triggered by pressing the left button. + +## Requirements + +To run this example you will need: + +* A border router operating with the same RDC, same channel, same radio mode + (e.g. IEEE or sub-ghz), same PAN ID. Alternatively, you can + use [6lbr](https://github.com/cetic/6lbr) with a suitable slip-radio. +* The [Copper (Cu)](https://addons.mozilla.org/en-US/firefox/addon/copper-270430/) + addon for Firefox + +## Configuration + +To configure the node, send a CoAP POST message to the `very_sleepy_config` +resource. The POST message's payload must specify _at least one_ of: + +* `mode=0|1`: Send `mode=1` to enable very sleepy mode, `mode=0` to disable it. +* `interval=n` where `n` is the number of seconds between two consecutive normal + mode periods. This interval also dictates the OBSERVEr notification period. +* `duration=n` where `n` is the number of seconds that the node will stay in + normal mode before dropping to very sleepy mode. This value is only relevant + if `mode==1`. + +A POST request must contain at least one of the above, but they are otherwise +all optional. So, for example, a POST may simply specify `interval=n`. To send +multiple values, delimit them with `&`. So you can send something like +`mode=1&interval=60&duration=20` + +The current running configuration can be retrieved by sending a GET request to +the same CoAP resource. + +## Running the example + +* Deploy your border router or 6lbr +* Turn on the very sleepy node. +* Fire up the Copper addon +* Select `.well-known/core` and hit `GET` +* Configure very sleepy operation: + * Select the `very_sleepy_config` resource + * In the `Outgoing` pane, type your POST payload as per the instructions + above. For example, you can type: `mode=1&interval=30&duration=10` + * Hit `POST` +* Select the `sen/readings` resource and hit `OBSERVE` + +## Caveats + +If you click on a resource in the Copper resources tree while you are observing +a different resource, the OBSERVEr for the latter will be stopped without +notifying the CoAP server. This will result in the server sending out OBSERVE +notifications that will be responded to with port unreachable ICMPv6 messages. +This will continue for quite a while, until the server detects that the +OBSERVEr has been lost (a test currently performed once every 20 notifications). +In order to prevent this from happening, hit the "Cancel" button for the +OBSERVE before switching views to a different resource. This will unregister +the observer. + +In very sleepy mode, the radio is not truly always off. The contiki core needs +to perform other periodic tasks in order to maintain network connectivity. For +that reason, this example will allow the radio to turn on periodically even +while in very sleepy mode. Thus, you may see that the node becomes briefly +reachable every now and then. However, do not count on those periods of +reachability to perform any tasks, as they will be brief and will be disrupted +without warning. diff --git a/examples/cc26xx/very-sleepy-demo/project-conf.h b/examples/cc26xx/very-sleepy-demo/project-conf.h new file mode 100644 index 000000000..477a535bf --- /dev/null +++ b/examples/cc26xx/very-sleepy-demo/project-conf.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ +/*---------------------------------------------------------------------------*/ +/* Change to match your configuration */ +#define IEEE802154_CONF_PANID 0xABCD +#define RF_CORE_CONF_CHANNEL 25 +/*---------------------------------------------------------------------------*/ +/* For very sleepy operation */ +#define RF_BLE_CONF_ENABLED 0 +#define UIP_DS6_CONF_PERIOD CLOCK_SECOND +#define UIP_CONF_TCP 0 +#define RPL_CONF_LEAF_ONLY 1 + +/* + * We'll fail without RPL probing, so turn it on explicitly even though it's + * on by default + */ +#define RPL_CONF_WITH_PROBING 1 +/*---------------------------------------------------------------------------*/ +#endif /* PROJECT_CONF_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/cc26xx/very-sleepy-demo/very-sleepy-demo.c b/examples/cc26xx/very-sleepy-demo/very-sleepy-demo.c new file mode 100644 index 000000000..5719e11ce --- /dev/null +++ b/examples/cc26xx/very-sleepy-demo/very-sleepy-demo.c @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sys/etimer.h" +#include "sys/stimer.h" +#include "sys/process.h" +#include "dev/leds.h" +#include "dev/watchdog.h" +#include "button-sensor.h" +#include "batmon-sensor.h" +#include "board-peripherals.h" +#include "net/netstack.h" +#include "net/ipv6/uip-ds6-nbr.h" +#include "net/ipv6/uip-ds6-route.h" +#include "net/rpl/rpl.h" +#include "net/rpl/rpl-private.h" +#include "rest-engine.h" +#include "er-coap.h" + +#include "ti-lib.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +/* Normal mode duration params in seconds */ +#define NORMAL_OP_DURATION_DEFAULT 10 +#define NORMAL_OP_DURATION_MIN 10 +#define NORMAL_OP_DURATION_MAX 60 +/*---------------------------------------------------------------------------*/ +/* Observer notification period params in seconds */ +#define PERIODIC_INTERVAL_DEFAULT 30 +#define PERIODIC_INTERVAL_MIN 30 +#define PERIODIC_INTERVAL_MAX 86400 /* 1 day */ +/*---------------------------------------------------------------------------*/ +#define VERY_SLEEPY_MODE_OFF 0 +#define VERY_SLEEPY_MODE_ON 1 +/*---------------------------------------------------------------------------*/ +#define MAC_CAN_BE_TURNED_OFF 0 +#define MAC_MUST_STAY_ON 1 + +#define KEEP_MAC_ON_MIN_PERIOD 10 /* secs */ +/*---------------------------------------------------------------------------*/ +#define PERIODIC_INTERVAL CLOCK_SECOND +/*---------------------------------------------------------------------------*/ +#define POST_STATUS_BAD 0x80 +#define POST_STATUS_HAS_MODE 0x40 +#define POST_STATUS_HAS_DURATION 0x20 +#define POST_STATUS_HAS_INTERVAL 0x10 +#define POST_STATUS_NONE 0x00 +/*---------------------------------------------------------------------------*/ +typedef struct sleepy_config_s { + unsigned long interval; + unsigned long duration; + uint8_t mode; +} sleepy_config_t; + +sleepy_config_t config; +/*---------------------------------------------------------------------------*/ +#define STATE_NORMAL 0 +#define STATE_NOTIFY_OBSERVERS 1 +#define STATE_VERY_SLEEPY 2 +/*---------------------------------------------------------------------------*/ +static struct stimer st_duration; +static struct stimer st_interval; +static struct stimer st_min_mac_on_duration; +static struct etimer et_periodic; +static process_event_t event_new_config; +static uint8_t state; +/*---------------------------------------------------------------------------*/ +const char *not_supported_msg = "Supported:text/plain,application/json"; +/*---------------------------------------------------------------------------*/ +PROCESS(very_sleepy_demo_process, "CC13xx/CC26xx very sleepy process"); +AUTOSTART_PROCESSES(&very_sleepy_demo_process); +/*---------------------------------------------------------------------------*/ +static void +readings_get_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + int temp; + int voltage; + + if(request != NULL) { + REST.get_header_accept(request, &accept); + } + + temp = batmon_sensor.value(BATMON_SENSOR_TYPE_TEMP); + + voltage = batmon_sensor.value(BATMON_SENSOR_TYPE_VOLT); + + if(accept == -1 || accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "{\"temp\":{\"v\":%d,\"u\":\"C\"}," + "\"voltage\":{\"v\":%d,\"u\":\"mV\"}}", + temp, (voltage * 125) >> 5); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "Temp=%dC, Voltage=%dmV", + temp, (voltage * 125) >> 5); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, not_supported_msg, + strlen(not_supported_msg)); + } +} +/*---------------------------------------------------------------------------*/ +RESOURCE(readings_resource, "title=\"Sensor Readings\";obs", + readings_get_handler, NULL, NULL, NULL); +/*---------------------------------------------------------------------------*/ +static void +conf_get_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + + if(request != NULL) { + REST.get_header_accept(request, &accept); + } + + if(accept == -1 || accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "{\"config\":{\"mode\":%u,\"duration\":%lu,\"interval\":%lu}}", + config.mode, config.duration, config.interval); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "Mode=%u, Duration=%lusecs, Interval=%lusecs", + config.mode, config.duration, config.interval); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, not_supported_msg, + strlen(not_supported_msg)); + } +} +/*---------------------------------------------------------------------------*/ +static void +conf_post_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + const char *ptr = NULL; + char tmp_buf[16]; + unsigned long interval = 0; + unsigned long duration = 0; + uint8_t mode = VERY_SLEEPY_MODE_OFF; + uint8_t post_status = POST_STATUS_NONE; + int rv; + + rv = REST.get_post_variable(request, "mode", &ptr); + if(rv && rv < 16) { + memset(tmp_buf, 0, sizeof(tmp_buf)); + memcpy(tmp_buf, ptr, rv); + rv = atoi(tmp_buf); + + if(rv == 1) { + mode = VERY_SLEEPY_MODE_ON; + post_status |= POST_STATUS_HAS_MODE; + } else if(rv == 0) { + mode = VERY_SLEEPY_MODE_OFF; + post_status |= POST_STATUS_HAS_MODE; + } else { + post_status = POST_STATUS_BAD; + } + } + + rv = REST.get_post_variable(request, "duration", &ptr); + if(rv && rv < 16) { + memset(tmp_buf, 0, sizeof(tmp_buf)); + memcpy(tmp_buf, ptr, rv); + rv = atoi(tmp_buf); + + duration = (unsigned long)rv; + if(duration < NORMAL_OP_DURATION_MIN || duration > NORMAL_OP_DURATION_MAX) { + post_status = POST_STATUS_BAD; + } else { + post_status |= POST_STATUS_HAS_DURATION; + } + } + + rv = REST.get_post_variable(request, "interval", &ptr); + if(rv && rv < 16) { + memset(tmp_buf, 0, sizeof(tmp_buf)); + memcpy(tmp_buf, ptr, rv); + rv = atoi(tmp_buf); + interval = (unsigned long)rv; + if(interval < PERIODIC_INTERVAL_MIN || interval > PERIODIC_INTERVAL_MAX) { + post_status = POST_STATUS_BAD; + } else { + post_status |= POST_STATUS_HAS_INTERVAL; + } + } + + if((post_status & POST_STATUS_BAD) == POST_STATUS_BAD || + post_status == POST_STATUS_NONE) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "mode=0|1&duration=[%u,%u]&interval=[%u,%u]", + NORMAL_OP_DURATION_MIN, NORMAL_OP_DURATION_MAX, + PERIODIC_INTERVAL_MIN, PERIODIC_INTERVAL_MAX); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + return; + } + + /* Values are sane. Update the config and notify the process */ + if(post_status & POST_STATUS_HAS_MODE) { + config.mode = mode; + } + + if(post_status & POST_STATUS_HAS_INTERVAL) { + config.interval = interval; + } + + if(post_status & POST_STATUS_HAS_DURATION) { + config.duration = duration; + } + + process_post(&very_sleepy_demo_process, event_new_config, NULL); +} +/*---------------------------------------------------------------------------*/ +RESOURCE(very_sleepy_conf, + "title=\"Very sleepy conf: " + "GET|POST mode=0|1&interval=&duration=\";rt=\"Control\"", + conf_get_handler, conf_post_handler, NULL, NULL); +/*---------------------------------------------------------------------------*/ +/* + * If our preferred parent is not NBR_REACHABLE in the ND cache, NUD will send + * a unicast NS and wait for NA. If NA fails then the neighbour will be removed + * from the ND cache and the default route will be deleted. To prevent this, + * keep the MAC on until the parent becomes NBR_REACHABLE. We also keep the MAC + * on if we are about to do RPL probing. + * + * In all cases, the radio will be locked on for KEEP_MAC_ON_MIN_PERIOD secs + */ +static uint8_t +keep_mac_on(void) +{ + uip_ds6_nbr_t *nbr; + uint8_t rv = MAC_CAN_BE_TURNED_OFF; + + if(!stimer_expired(&st_min_mac_on_duration)) { + return MAC_MUST_STAY_ON; + } + +#if RPL_WITH_PROBING + /* Determine if we are about to send a RPL probe */ + if(CLOCK_LT(etimer_expiration_time( + &rpl_get_default_instance()->probing_timer.etimer), + (clock_time() + PERIODIC_INTERVAL))) { + rv = MAC_MUST_STAY_ON; + } +#endif + + /* It's OK to pass a NULL pointer, the callee checks and returns NULL */ + nbr = uip_ds6_nbr_lookup(uip_ds6_defrt_choose()); + + if(nbr == NULL) { + /* We don't have a default route, or it's not reachable (NUD likely). */ + rv = MAC_MUST_STAY_ON; + } else { + if(nbr->state != NBR_REACHABLE) { + rv = MAC_MUST_STAY_ON; + } + } + + if(rv == MAC_MUST_STAY_ON && stimer_expired(&st_min_mac_on_duration)) { + stimer_set(&st_min_mac_on_duration, KEEP_MAC_ON_MIN_PERIOD); + } + + return rv; +} +/*---------------------------------------------------------------------------*/ +static void +switch_to_normal(void) +{ + state = STATE_NOTIFY_OBSERVERS; + + /* + * Stay in normal mode for 'duration' secs. + * Transition back to normal in 'interval' secs, _including_ 'duration' + */ + stimer_set(&st_duration, config.duration); + stimer_set(&st_interval, config.interval); +} +/*---------------------------------------------------------------------------*/ +static void +switch_to_very_sleepy(void) +{ + state = STATE_VERY_SLEEPY; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(very_sleepy_demo_process, ev, data) +{ + uint8_t mac_keep_on; + + PROCESS_BEGIN(); + + SENSORS_ACTIVATE(batmon_sensor); + + config.mode = VERY_SLEEPY_MODE_OFF; + config.interval = PERIODIC_INTERVAL_DEFAULT; + config.duration = NORMAL_OP_DURATION_DEFAULT; + + state = STATE_NORMAL; + + event_new_config = process_alloc_event(); + + rest_init_engine(); + + readings_resource.flags += IS_OBSERVABLE; + rest_activate_resource(&readings_resource, "sen/readings"); + rest_activate_resource(&very_sleepy_conf, "very_sleepy_config"); + + printf("Very Sleepy Demo Process\n"); + + switch_to_normal(); + + etimer_set(&et_periodic, PERIODIC_INTERVAL); + + while(1) { + + PROCESS_YIELD(); + + if(ev == sensors_event && data == &button_left_sensor) { + switch_to_normal(); + } + + if(ev == event_new_config) { + stimer_set(&st_interval, config.interval); + stimer_set(&st_duration, config.duration); + } + + if((ev == PROCESS_EVENT_TIMER && data == &et_periodic) || + (ev == sensors_event && data == &button_left_sensor) || + (ev == event_new_config)) { + + /* + * Determine if the stack is about to do essential network maintenance + * and, if so, keep the MAC layer on + */ + mac_keep_on = keep_mac_on(); + + if(mac_keep_on == MAC_MUST_STAY_ON || state != STATE_VERY_SLEEPY) { + leds_on(LEDS_GREEN); + NETSTACK_MAC.on(); + } + + /* + * Next, switch between normal and very sleepy mode depending on config, + * send notifications to observers as required. + */ + if(state == STATE_NOTIFY_OBSERVERS) { + REST.notify_subscribers(&readings_resource); + state = STATE_NORMAL; + } + + if(state == STATE_NORMAL) { + if(stimer_expired(&st_duration)) { + stimer_set(&st_duration, config.duration); + if(config.mode == VERY_SLEEPY_MODE_ON) { + switch_to_very_sleepy(); + } + } + } else if(state == STATE_VERY_SLEEPY) { + if(stimer_expired(&st_interval)) { + switch_to_normal(); + } + } + + if(mac_keep_on == MAC_CAN_BE_TURNED_OFF && state == STATE_VERY_SLEEPY) { + leds_off(LEDS_GREEN); + NETSTACK_MAC.off(0); + } else { + leds_on(LEDS_GREEN); + NETSTACK_MAC.on(); + } + + /* Schedule next pass */ + etimer_set(&et_periodic, PERIODIC_INTERVAL); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/cfs-coffee/Makefile b/examples/cfs-coffee/Makefile new file mode 100644 index 000000000..0e1fe1b13 --- /dev/null +++ b/examples/cfs-coffee/Makefile @@ -0,0 +1,12 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" +CONTIKI = ../.. + +all: test-cfs test-coffee example-coffee + +CONTIKI_WITH_RIME = 1 + +ifeq ($(TARGET),avr-raven) + COFFEE_FILES = 4 +endif + +include $(CONTIKI)/Makefile.include diff --git a/examples/cfs-coffee/README.md b/examples/cfs-coffee/README.md new file mode 100644 index 000000000..991e9583b --- /dev/null +++ b/examples/cfs-coffee/README.md @@ -0,0 +1,29 @@ +Contiki File System (CFS) and Coffee Examples +============================================= + +Coffee is a very simple, relatively small and easy to use file system that you +are most likely going to be very familiar with if you have done any C file +access in the past. The notion is the same as on a normal PC: you open a file, +read and write to it and close it. Contiki will take care of the underlying +flash memory, giving you more time to focus on the real issues. + +Coffee is a full implementation of the CFS API. + +An extended explanation on CFS and Coffee internals and how they work can be +found at the [CFS](https://github.com/contiki-os/contiki/wiki/File-systems) and +[Coffee](https://github.com/contiki-os/contiki/wiki/Coffee-filesystem-example) +wiki pages. + +Supported Hardware (tested or known to work) +-------------------------------------------- +* sky +* z1 +* wismote +* avr-raven +* cc2538dk +* openmote-cc2538 +* zoul + +The examples are known to build for the 'avr-raven' platform. However, +some of them currently fail at runtime due to file system overflow. +Tweaking the file sizes in the examples is necessary. diff --git a/examples/sky/example-coffee.c b/examples/cfs-coffee/example-coffee.c similarity index 89% rename from examples/sky/example-coffee.c rename to examples/cfs-coffee/example-coffee.c index ee77849e4..7adc8d62c 100644 --- a/examples/sky/example-coffee.c +++ b/examples/cfs-coffee/example-coffee.c @@ -28,31 +28,31 @@ * * This file is part of the Contiki operating system. */ - +/*---------------------------------------------------------------------------*/ /** * \file * Example on how to use CFS/Coffee. * \author * Nicolas Tsiftes */ - +/*---------------------------------------------------------------------------*/ #include - +#include #include "contiki.h" #include "cfs/cfs.h" #include "cfs/cfs-coffee.h" - +/*---------------------------------------------------------------------------*/ PROCESS(example_coffee_process, "Coffee example"); AUTOSTART_PROCESSES(&example_coffee_process); - +/*---------------------------------------------------------------------------*/ #define FILENAME "test" -/* Formatting is needed if the storage device is in an unknown state; +/* Formatting is needed if the storage device is in an unknown state; e.g., when using Coffee on the storage device for the first time. */ #ifndef NEED_FORMATTING #define NEED_FORMATTING 0 #endif - +/*---------------------------------------------------------------------------*/ static int file_test(const char *filename, char *msg) { @@ -65,12 +65,12 @@ file_test(const char *filename, char *msg) } record; /* - * Coffee determines the file length by finding the last non-zero byte - * of the file. This I/O semantic requires that each record should end - * with a non-zero, if we are writing multiple records and closing the + * Coffee determines the file length by finding the last non-zero byte + * of the file. This I/O semantic requires that each record should end + * with a non-zero, if we are writing multiple records and closing the * file descriptor in between. * - * In this example, in which the file_test function can be called + * In this example, in which the file_test function can be called * multiple times, we ensure that the sequence counter starts at 1. */ @@ -84,7 +84,7 @@ file_test(const char *filename, char *msg) record.message[sizeof(record.message) - 1] = '\0'; record.sequence = sequence; - /* Obtain a file descriptor for the file, capable of handling both + /* Obtain a file descriptor for the file, capable of handling both reads and writes. */ fd = cfs_open(FILENAME, CFS_WRITE | CFS_APPEND | CFS_READ); if(fd < 0) { @@ -103,7 +103,7 @@ file_test(const char *filename, char *msg) printf("Wrote message \"%s\", sequence %u\n", record.message, record.sequence); - /* To read back the message, we need to move the file pointer to the + /* To read back the message, we need to move the file pointer to the beginning of the file. */ if(cfs_seek(fd, 0, CFS_SEEK_SET) != 0) { printf("seek failed\n"); @@ -133,7 +133,7 @@ file_test(const char *filename, char *msg) return 1; } - +/*---------------------------------------------------------------------------*/ static int dir_test(void) { @@ -156,7 +156,7 @@ dir_test(void) return 1; } - +/*---------------------------------------------------------------------------*/ PROCESS_THREAD(example_coffee_process, ev, data) { PROCESS_BEGIN(); diff --git a/examples/cfs-coffee/project-conf.h b/examples/cfs-coffee/project-conf.h new file mode 100644 index 000000000..4dd98edcb --- /dev/null +++ b/examples/cfs-coffee/project-conf.h @@ -0,0 +1,40 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ +/*---------------------------------------------------------------------------*/ +#if CONTIKI_TARGET_CC2538DK || CONTIKI_TARGET_OPENMOTE_CC2538 || \ + CONTIKI_TARGET_ZOUL +#define COFFEE_CONF_SIZE (CC2538_DEV_FLASH_SIZE / 2) +#define COFFEE_CONF_MICRO_LOGS 1 +#define COFFEE_CONF_APPEND_ONLY 0 +#endif /* CONTIKI_TARGET_CC2538DK || CONTIKI_TARGET_ZOUL */ + +#endif /* PROJECT_CONF_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/sky/test-cfs.c b/examples/cfs-coffee/test-cfs.c similarity index 94% rename from examples/sky/test-cfs.c rename to examples/cfs-coffee/test-cfs.c index 68c91e720..2d44b6696 100644 --- a/examples/sky/test-cfs.c +++ b/examples/cfs-coffee/test-cfs.c @@ -29,19 +29,18 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * A quick program for testing the CFS xmem driver * \author * Adam Dunkels */ - +/*---------------------------------------------------------------------------*/ #include "contiki.h" #include "cfs/cfs.h" - #include - +/*---------------------------------------------------------------------------*/ PROCESS(cfs_process, "Test CFS process"); AUTOSTART_PROCESSES(&cfs_process); /*---------------------------------------------------------------------------*/ @@ -55,6 +54,7 @@ PROCESS_THREAD(cfs_process, ev, data) uint16_t filesize = 65000; #define CHUNKSIZE 128 + cfs_remove("hej"); fd = cfs_open("hej", CFS_WRITE); if(fd < 0) { printf("could not open file for writing, aborting\n"); diff --git a/examples/sky/test-coffee.c b/examples/cfs-coffee/test-coffee.c similarity index 84% rename from examples/sky/test-coffee.c rename to examples/cfs-coffee/test-coffee.c index b4152b2a8..3fcc40cfd 100644 --- a/examples/sky/test-coffee.c +++ b/examples/cfs-coffee/test-coffee.c @@ -29,14 +29,14 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * Basic test for CFS/Coffee. * \author * Nicolas Tsiftes */ - +/*---------------------------------------------------------------------------*/ #include "contiki.h" #include "cfs/cfs.h" #include "cfs/cfs-coffee.h" @@ -45,14 +45,12 @@ #include #include - +/*---------------------------------------------------------------------------*/ PROCESS(testcoffee_process, "Test CFS/Coffee process"); AUTOSTART_PROCESSES(&testcoffee_process); - -#define FAIL(x) error = (x); goto end; - +/*---------------------------------------------------------------------------*/ +#define TEST_FAIL(x) error = (x); goto end; #define FILE_SIZE 4096 - /*---------------------------------------------------------------------------*/ static int coffee_test_basic(void) @@ -62,8 +60,6 @@ coffee_test_basic(void) unsigned char buf[256]; int r; - cfs_remove("T1"); - wfd = rfd = afd = -1; for(r = 0; r < sizeof(buf); r++) { @@ -73,64 +69,64 @@ coffee_test_basic(void) /* Test 1: Open for writing. */ wfd = cfs_open("T1", CFS_WRITE); if(wfd < 0) { - FAIL(1); + TEST_FAIL(1); } /* Test 2 and 3: Write buffer. */ r = cfs_write(wfd, buf, sizeof(buf)); if(r < 0) { - FAIL(2); + TEST_FAIL(2); } else if(r < sizeof(buf)) { - FAIL(3); + TEST_FAIL(3); } /* Test 4: Deny reading. */ r = cfs_read(wfd, buf, sizeof(buf)); if(r >= 0) { - FAIL(4); + TEST_FAIL(4); } /* Test 5: Open for reading. */ rfd = cfs_open("T1", CFS_READ); if(rfd < 0) { - FAIL(5); + TEST_FAIL(5); } /* Test 6: Write to read-only file. */ r = cfs_write(rfd, buf, sizeof(buf)); if(r >= 0) { - FAIL(6); + TEST_FAIL(6); } /* Test 7 and 8: Read the buffer written in Test 2. */ memset(buf, 0, sizeof(buf)); r = cfs_read(rfd, buf, sizeof(buf)); if(r < 0) { - FAIL(7); + TEST_FAIL(7); } else if(r < sizeof(buf)) { printf("r=%d\n", r); - FAIL(8); + TEST_FAIL(8); } /* Test 9: Verify that the buffer is correct. */ for(r = 0; r < sizeof(buf); r++) { if(buf[r] != r) { printf("r=%d. buf[r]=%d\n", r, buf[r]); - FAIL(9); + TEST_FAIL(9); } } /* Test 10: Seek to beginning. */ if(cfs_seek(wfd, 0, CFS_SEEK_SET) != 0) { - FAIL(10); + TEST_FAIL(10); } /* Test 11 and 12: Write to the log. */ r = cfs_write(wfd, buf, sizeof(buf)); if(r < 0) { - FAIL(11); + TEST_FAIL(11); } else if(r < sizeof(buf)) { - FAIL(12); + TEST_FAIL(12); } /* Test 13 and 14: Read the data from the log. */ @@ -138,15 +134,15 @@ coffee_test_basic(void) memset(buf, 0, sizeof(buf)); r = cfs_read(rfd, buf, sizeof(buf)); if(r < 0) { - FAIL(14); + TEST_FAIL(13); } else if(r < sizeof(buf)) { - FAIL(15); + TEST_FAIL(14); } /* Test 16: Verify that the data is correct. */ for(r = 0; r < sizeof(buf); r++) { if(buf[r] != r) { - FAIL(16); + TEST_FAIL(15); } } @@ -155,16 +151,16 @@ coffee_test_basic(void) buf[r] = sizeof(buf) - r - 1; } if(cfs_seek(wfd, 0, CFS_SEEK_SET) != 0) { - FAIL(17); + TEST_FAIL(16); } r = cfs_write(wfd, buf, sizeof(buf)); if(r < 0) { - FAIL(18); + TEST_FAIL(17); } else if(r < sizeof(buf)) { - FAIL(19); + TEST_FAIL(18); } if(cfs_seek(rfd, 0, CFS_SEEK_SET) != 0) { - FAIL(20); + TEST_FAIL(19); } /* Test 21 and 22: Read the reversed buffer. */ @@ -172,16 +168,16 @@ coffee_test_basic(void) memset(buf, 0, sizeof(buf)); r = cfs_read(rfd, buf, sizeof(buf)); if(r < 0) { - FAIL(21); + TEST_FAIL(20); } else if(r < sizeof(buf)) { printf("r = %d\n", r); - FAIL(22); + TEST_FAIL(21); } /* Test 23: Verify that the data is correct. */ for(r = 0; r < sizeof(buf); r++) { if(buf[r] != sizeof(buf) - r - 1) { - FAIL(23); + TEST_FAIL(22); } } @@ -189,6 +185,7 @@ coffee_test_basic(void) end: cfs_close(wfd); cfs_close(rfd); + cfs_remove("T1"); return error; } /*---------------------------------------------------------------------------*/ @@ -202,50 +199,49 @@ coffee_test_append(void) #define APPEND_BYTES 1000 #define BULK_SIZE 10 - cfs_remove("T2"); - /* Test 1 and 2: Append data to the same file many times. */ for(i = 0; i < APPEND_BYTES; i += BULK_SIZE) { - afd = cfs_open("T3", CFS_WRITE | CFS_APPEND); + afd = cfs_open("T2", CFS_WRITE | CFS_APPEND); if(afd < 0) { - FAIL(1); + TEST_FAIL(1); } for(j = 0; j < BULK_SIZE; j++) { buf[j] = 1 + ((i + j) & 0x7f); } if((r = cfs_write(afd, buf, BULK_SIZE)) != BULK_SIZE) { printf("r=%d\n", r); - FAIL(2); + TEST_FAIL(2); } cfs_close(afd); } - /* Test 3-6: Read back the data written previously and verify that it + /* Test 3-6: Read back the data written previously and verify that it is correct. */ - afd = cfs_open("T3", CFS_READ); + afd = cfs_open("T2", CFS_READ); if(afd < 0) { - FAIL(3); + TEST_FAIL(3); } total_read = 0; while((r = cfs_read(afd, buf2, sizeof(buf2))) > 0) { for(j = 0; j < r; j++) { if(buf2[j] != 1 + ((total_read + j) & 0x7f)) { - FAIL(4); + TEST_FAIL(4); } } total_read += r; } if(r < 0) { - FAIL(5); + TEST_FAIL(5); } if(total_read != APPEND_BYTES) { - FAIL(6); + TEST_FAIL(6); } cfs_close(afd); error = 0; end: cfs_close(afd); + cfs_remove("T2"); return error; } /*---------------------------------------------------------------------------*/ @@ -258,58 +254,60 @@ coffee_test_modify(void) int r, i; unsigned offset; - cfs_remove("T3"); wfd = -1; if(cfs_coffee_reserve("T3", FILE_SIZE) < 0) { - FAIL(1); + TEST_FAIL(1); } if(cfs_coffee_configure_log("T3", FILE_SIZE / 2, 11) < 0) { - FAIL(2); + TEST_FAIL(2); } /* Test 16: Test multiple writes at random offset. */ for(r = 0; r < 100; r++) { - wfd = cfs_open("T2", CFS_WRITE | CFS_READ); + wfd = cfs_open("T3", CFS_WRITE | CFS_READ); if(wfd < 0) { - FAIL(3); + TEST_FAIL(3); } offset = random_rand() % FILE_SIZE; - for(r = 0; r < sizeof(buf); r++) { - buf[r] = r; + for(i = 0; i < sizeof(buf); i++) { + buf[i] = i; } if(cfs_seek(wfd, offset, CFS_SEEK_SET) != offset) { - FAIL(4); + TEST_FAIL(4); } if(cfs_write(wfd, buf, sizeof(buf)) != sizeof(buf)) { - FAIL(5); + TEST_FAIL(5); } if(cfs_seek(wfd, offset, CFS_SEEK_SET) != offset) { - FAIL(6); + TEST_FAIL(6); } memset(buf, 0, sizeof(buf)); if(cfs_read(wfd, buf, sizeof(buf)) != sizeof(buf)) { - FAIL(7); + TEST_FAIL(7); } for(i = 0; i < sizeof(buf); i++) { if(buf[i] != i) { printf("buf[%d] != %d\n", i, buf[i]); - FAIL(8); + TEST_FAIL(8); } } + + cfs_close(wfd); } error = 0; end: cfs_close(wfd); + cfs_remove("T3"); return error; } /*---------------------------------------------------------------------------*/ @@ -318,21 +316,17 @@ coffee_test_gc(void) { int i; - cfs_remove("alpha"); - cfs_remove("beta"); - - for (i = 0; i < 100; i++) { if (i & 1) { - if(cfs_coffee_reserve("alpha", random_rand() & 0xffff) < 0) { - return i; - } - cfs_remove("beta"); - } else { - if(cfs_coffee_reserve("beta", 93171) < 0) { + if(cfs_coffee_reserve("beta", random_rand() & 0xffff) < 0) { return i; } cfs_remove("alpha"); + } else { + if(cfs_coffee_reserve("alpha", 93171) < 0) { + return i; + } + cfs_remove("beta"); } } @@ -376,7 +370,7 @@ PROCESS_THREAD(testcoffee_process, ev, data) result = coffee_test_gc(); print_result("Garbage collection", result); - printf("Coffee test finished. Duration: %d seconds\n", + printf("Coffee test finished. Duration: %d seconds\n", (int)(clock_seconds() - start)); PROCESS_END(); diff --git a/examples/collect/Makefile b/examples/collect/Makefile index 4e535f711..f2f88e074 100644 --- a/examples/collect/Makefile +++ b/examples/collect/Makefile @@ -4,4 +4,5 @@ all: $(CONTIKI_PROJECT) APPS = serial-shell powertrace collect-view CONTIKI = ../.. +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/collect/example-collect-view.csc b/examples/collect/example-collect-view.csc index c32a73f51..6eac3e9d5 100644 --- a/examples/collect/example-collect-view.csc +++ b/examples/collect/example-collect-view.csc @@ -1,439 +1,439 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - CollectView - Demo - 0 - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Collect View Shell #sky1 - [CONTIKI_DIR]/examples/collect/collect-view-shell.c - make collect-view-shell.sky TARGET=sky - [CONTIKI_DIR]/examples/collect/collect-view-shell.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 47.447589188296796 - 6.493794191652634 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 31.354300798086324 - 27.956947207632854 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 74.3829989341562 - 30.580648313490777 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 112.16429485851025 - 44.22389406395196 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 68.61085650126878 - 84.62889109416392 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 56.15423831110357 - 64.07252546725537 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 87.73274591684346 - 60.66871896134617 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 7 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - -2.2290733568950474 - 33.204349419348695 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 8 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 38.7006638944885 - 92.49999441173767 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 9 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 15.612094162938806 - 63.639282247300564 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 10 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 141.5408533420652 - 115.36621659194348 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 11 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 147.32188967700637 - 142.49261785589826 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 12 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 120.89539128042348 - 87.32905614555476 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 13 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 103.7684513197649 - 131.3307707784349 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 14 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - -11.674397337983558 - 68.36194423784482 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 15 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - -43.897004478740314 - 75.78835245273079 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 16 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 95.12464106933497 - 96.12882451031668 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 17 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 31.354300798086324 - 121.88544679734638 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 18 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 121.97426882380275 - 155.38877583384397 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 19 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - -32.139265963675335 - 109.81642171039995 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 20 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - -47.35673237765127 - 142.87505564420977 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 21 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - -32.66400618484692 - 168.06258626044578 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 22 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 21.38423659582623 - 155.99356117349936 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 23 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 88.0262446846174 - 154.9440807311562 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 24 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 146.27240923466323 - 176.9831700203627 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 25 - - sky1 - - - - org.contikios.cooja.plugins.SimControl - 259 - 1 - 205 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 2.5200269517125586 0.0 0.0 2.5200269517125586 163.78987943671984 3.0766125491598224 - - 577 - 0 - 523 - 526 - 0 - - - org.contikios.cooja.plugins.LogListener - - - - 1103 - 3 - 300 - 0 - 522 - - - org.contikios.cooja.plugins.collectview.CollectView - 0 - 270 - 2 - 81 - 258 - 1 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + CollectView - Demo + 0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Collect View Shell #sky1 + [CONTIKI_DIR]/examples/collect/collect-view-shell.c + make collect-view-shell.sky TARGET=sky + [CONTIKI_DIR]/examples/collect/collect-view-shell.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 47.447589188296796 + 6.493794191652634 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 31.354300798086324 + 27.956947207632854 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 74.3829989341562 + 30.580648313490777 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 112.16429485851025 + 44.22389406395196 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 68.61085650126878 + 84.62889109416392 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 56.15423831110357 + 64.07252546725537 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 87.73274591684346 + 60.66871896134617 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + -2.2290733568950474 + 33.204349419348695 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 38.7006638944885 + 92.49999441173767 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 15.612094162938806 + 63.639282247300564 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 141.5408533420652 + 115.36621659194348 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 11 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 147.32188967700637 + 142.49261785589826 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 12 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 120.89539128042348 + 87.32905614555476 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 13 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 103.7684513197649 + 131.3307707784349 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 14 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + -11.674397337983558 + 68.36194423784482 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 15 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + -43.897004478740314 + 75.78835245273079 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 16 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 95.12464106933497 + 96.12882451031668 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 17 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 31.354300798086324 + 121.88544679734638 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 18 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 121.97426882380275 + 155.38877583384397 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 19 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + -32.139265963675335 + 109.81642171039995 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 20 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + -47.35673237765127 + 142.87505564420977 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 21 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + -32.66400618484692 + 168.06258626044578 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 22 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 21.38423659582623 + 155.99356117349936 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 23 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 88.0262446846174 + 154.9440807311562 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 24 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 146.27240923466323 + 176.9831700203627 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 25 + + sky1 + + + + org.contikios.cooja.plugins.SimControl + 259 + 1 + 205 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 2.5200269517125586 0.0 0.0 2.5200269517125586 163.78987943671984 3.0766125491598224 + + 577 + 0 + 523 + 526 + 0 + + + org.contikios.cooja.plugins.LogListener + + + + 1103 + 3 + 300 + 0 + 522 + + + org.contikios.cooja.plugins.collectview.CollectView + 0 + 270 + 2 + 81 + 258 + 1 + + + diff --git a/examples/econotag-ecc-test/Makefile b/examples/econotag-ecc-test/Makefile new file mode 100644 index 000000000..bfc3cf2c8 --- /dev/null +++ b/examples/econotag-ecc-test/Makefile @@ -0,0 +1,8 @@ +CONTIKI = ../.. +TARGET = econotag + +all: econotag-ecc-test + +APPS += ecc + +include $(CONTIKI)/Makefile.include diff --git a/examples/econotag-ecc-test/econotag-ecc-test.c b/examples/econotag-ecc-test/econotag-ecc-test.c new file mode 100644 index 000000000..e1675a390 --- /dev/null +++ b/examples/econotag-ecc-test/econotag-ecc-test.c @@ -0,0 +1,2182 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * ECC algorithm test + * + * This file contains tests for ECC calculations + * + * \author + * Lars Schmertmann + */ + +#include "ecc.h" +#include "contiki.h" + +#include +#include +#include + +/*---------------------------------------------------------------------------*/ + +/* Test vectors from https://github.com/iSECPartners/nano-ecc */ +uint32_t ecc_data[][7][8] = { { + { 0x01dcc6de, 0x6c8f8d3e, 0xe2612dd2, 0xdd3c4440, 0x3fee4131, 0xf02322c5, 0x4059c2ab, 0x751f7f74 }, + { 0x9a623445, 0xb27e2e17, 0xba50e608, 0x21b65597, 0x09d67258, 0xff5df02a, 0x03ca8c17, 0x698388c3 }, + { 0x26518fc8, 0x3235d8c5, 0x18ecb8fe, 0xebdb3791, 0xc0633d8b, 0x6c0dbf13, 0xe971273b, 0x5d56f932 }, + { 0x19a2428a, 0x1bdf8fdd, 0x418342e4, 0x67ff1a26, 0x309b7a46, 0x3a86104e, 0x0a6aea35, 0xe6f12ea2 }, + { 0x3ddbac31, 0xb2275232, 0x8b2abe7a, 0xd0d0bd74, 0x80d4f48a, 0x7a263898, 0x2d901339, 0xc53afd8d }, + { 0x24c5bd75, 0x2fe8b15b, 0x1a7983d9, 0x314984ea, 0xc453199e, 0x9c6a1083, 0x04441728, 0x77e815e3 }, + { 0x623cc072, 0xa3e5f3a2, 0x96a3b696, 0x83ca161d, 0x549145d3, 0x227369fb, 0xccf3a85c, 0xb97a69bc } + }, { + { 0x0d2cf2f4, 0x0d21f5f2, 0xfac9aca1, 0x840ab553, 0xec0dcf69, 0x4be4cecb, 0x128a0c0a, 0xa7f8b38f }, + { 0xf59800f2, 0x60a3a8d2, 0x819f2edb, 0xf2776dd0, 0x9f61d8d9, 0x8d7eb569, 0x4c4ec6ce, 0x07c4cdfa }, + { 0x8743783b, 0xd9eb95a6, 0xd27f08a8, 0xc9022285, 0x79b842b6, 0x03eb2d8b, 0x79f4baa4, 0x29036424 }, + { 0x5afd98e4, 0x0124388b, 0x15c3334f, 0xca6831e1, 0x14f32098, 0xf34ee3a6, 0x6dd6bc20, 0xde338482 }, + { 0x65db89d0, 0x7a975020, 0x1374d49b, 0xea8761b0, 0x99287467, 0xcdb741c5, 0x07640ee0, 0xbd00bef4 }, + { 0x700808f1, 0xf583f9f2, 0xd5ab6476, 0xb9470da3, 0x95447300, 0x1112ebbe, 0xaed5373f, 0x96060cb5 }, + { 0xbfaf6509, 0xaa24f83a, 0x5d18f3f5, 0x6b51122c, 0xdac95e1f, 0xb7e1f089, 0xf08bbed0, 0x3f1b874e } + }, { + { 0x33b5f336, 0x59e0d59b, 0x95601007, 0x3ec65a9b, 0x1854b42d, 0x74bdac00, 0xe6074168, 0xf5226a9b }, + { 0x494fabf0, 0xd1b5a4d4, 0xc0fabd37, 0x3d58ae63, 0x40356339, 0xcdd8a1d2, 0x2b96bd7f, 0xf309c0ad }, + { 0xac2aed2b, 0x2b8f5476, 0x0a65c8a2, 0x721de0e4, 0x77064eb6, 0x607e8f27, 0x4cb86d6f, 0x3aa4ec20 }, + { 0xce83cb4b, 0xbc8af90d, 0x91322d14, 0x58191442, 0x2a6387a6, 0x13fcaec4, 0xab0a4f92, 0xff990a1e }, + { 0x71669ba0, 0x939cceac, 0xce8d1d9a, 0xbbb4c801, 0x9904ace3, 0x04b7b8ef, 0x6657c7ff, 0xb6abb68b }, + { 0x3e5aa24f, 0x5ca3c331, 0x5139f40d, 0xe20ed654, 0xbe462e8e, 0x2707caf0, 0x24477db8, 0xd1bef9b1 }, + { 0x14d05b05, 0xd63c1f53, 0x47e3adcc, 0x70f5b519, 0xdbfcfc98, 0x02173932, 0xa0b0b921, 0x8a214dbd } + }, { + { 0xd262ce98, 0x2c116c77, 0xfa6a5ee7, 0x79152505, 0xb91f74a6, 0xd0db6ac0, 0x1ab4d986, 0xf53947fc }, + { 0xeadb841a, 0xda614f41, 0x0b7da371, 0x646d15ae, 0x159f7cc8, 0x4a2a43f2, 0x7ac27c91, 0xcee899f2 }, + { 0x78f156d2, 0x693bd20d, 0xfbc1e011, 0xf09e8a7c, 0x4e0d5823, 0x359a4595, 0x794303b4, 0xf8bef042 }, + { 0x9af1f222, 0x3d684941, 0xd6e56d92, 0x7b68ba32, 0xc0948cb2, 0x568a9354, 0x7aea45fb, 0xa1294a0b }, + { 0x5089a211, 0x826e1094, 0x974d4237, 0x90b08a0e, 0x62b66725, 0x99bb9dd2, 0x26569adc, 0x64ca5b7f }, + { 0x737f3039, 0xf0dbfaaa, 0x246f5559, 0x46326009, 0x26913709, 0x0048b096, 0xa95b088e, 0xefaf0be3 }, + { 0x4a1e8607, 0xef0181d3, 0x77cc4301, 0x1b708962, 0x61522020, 0x6db10e6c, 0x9e216660, 0xa2967953 } + }, { + { 0x6aefadbd, 0x6a96bab7, 0xc235e509, 0xb063b919, 0xc66f222b, 0x67f98a65, 0x0ea41576, 0xf8526e6b }, + { 0x77e50fde, 0x66f58ff3, 0x95d72a86, 0xe7f8ee13, 0xb43437f4, 0xf719f833, 0x4af4915d, 0xcb5c6d2d }, + { 0x8fbeef09, 0x24af00e4, 0x303b1db8, 0xbbf1dae7, 0xa1dab5cf, 0x7b22a089, 0x6cc93dee, 0x0cba7aa2 }, + { 0x26af27b4, 0x2684c828, 0x729ad7b0, 0x8ef161eb, 0xc12ac74d, 0x928ac3b4, 0xac9499da, 0xfe1c57c0 }, + { 0x15bc7280, 0xbe29a6d6, 0xe57bf1bd, 0xe68893d0, 0xc1312fcb, 0x3efae48b, 0x0c691973, 0x694fdc1d }, + { 0x05e64712, 0xa9669dea, 0xfa71f8b7, 0xb6de4567, 0xa2cc36e3, 0x889f5e34, 0xcc94f1fe, 0x2646763e }, + { 0xce756758, 0x0d9b6b53, 0x66a4d864, 0x8c4a3aa9, 0x99d5b022, 0x91a4dd18, 0x400612d0, 0x9f8b72d8 } + }, { + { 0xed3a3660, 0x5080a6e8, 0x6b95ca21, 0xa23d9aa2, 0xb3949551, 0xb9f2d46b, 0x26535847, 0xb8c62b06 }, + { 0x05405ae9, 0xb61b8454, 0x9aa94bf2, 0x7a2e5ac1, 0xea772505, 0x614a5a28, 0xf563a10a, 0xd4d45bd7 }, + { 0x6a80cf8c, 0xe725b198, 0xc371ee43, 0x4a8047e2, 0xc6f58553, 0xffa3c341, 0x2f4a9713, 0x0c6b7d0b }, + { 0x96283c3e, 0x9355c40b, 0x4f02e8b5, 0x6a62c4dc, 0x9e4da9aa, 0xbad8207d, 0x5e67afaf, 0x26fc0530 }, + { 0x25cefc44, 0xa29b4451, 0x404e8418, 0x5aab901d, 0xf6d0a1a5, 0x8a8438b1, 0x4b4964a2, 0x1704792c }, + { 0x02af9562, 0x948d3fe4, 0x4ca218e4, 0x3fb57e0d, 0x57f6e2d7, 0x7c3db023, 0x8cbe424e, 0xc9dd9b16 }, + { 0xc656a582, 0x157d2ef5, 0xe292e1f1, 0x1a368124, 0xe05b3093, 0xeab74f3b, 0x2196cb68, 0x57c6f1a5 } + }, { + { 0xb19e4c50, 0xee52bcd7, 0x4834dbb6, 0x03e721b5, 0x32108a97, 0xc575e528, 0x5ccbfe1d, 0x099c5d8e }, + { 0xb119ab54, 0xcfe14a69, 0x456bc938, 0xdafd4059, 0xb904aca1, 0x1a861997, 0x6374580d, 0x71354259 }, + { 0xa0a9a344, 0x6dde4baa, 0x57d7644d, 0xad71af57, 0x9154c72d, 0xa5426581, 0x6d501f29, 0x3dcc0c53 }, + { 0xd5d55773, 0xa48d40e7, 0x4c299836, 0xa3c3aa27, 0xb7060b27, 0x4c0b55f7, 0x190ffb64, 0x0a3e5fae }, + { 0xf7197092, 0xb06b1445, 0xdec8c324, 0x84a10310, 0xf8ffe96b, 0x16bfc375, 0xe3857b4b, 0x2dcf6157 }, + { 0x3ed661df, 0x69128ce4, 0x4863697b, 0xf846460d, 0xa6087ea7, 0x51e4db88, 0xe4dd1b45, 0x3dc4bdef }, + { 0x29fb38a0, 0xb69a329f, 0x7fed93cc, 0xd1ec8509, 0xf3907fd8, 0xf8ab1ff0, 0x19950850, 0xaa9a03c1 } + }, { + { 0x361859ce, 0x867cba28, 0xa39a5255, 0xf70d11f8, 0xb9fc2131, 0x7cd59204, 0xbe14e485, 0x7d0f4b93 }, + { 0x41bcb98a, 0x1f281f64, 0x61c98305, 0xf066bd0f, 0xd6ada91a, 0x8cfb9f1d, 0x328c8d89, 0x753932c8 }, + { 0xe474b0ae, 0x4a7e981b, 0x7cf03f2b, 0xec09086e, 0x805a8546, 0x5b0ddacf, 0xe8f06c37, 0xbf7452ce }, + { 0xc0a55fe4, 0x0c8d529f, 0x19d763f7, 0x7454ff5e, 0xb4964f9f, 0x8ced59fa, 0x06e12800, 0xabb82b0b }, + { 0x0069d9cc, 0x8b2d3165, 0x54088fec, 0x9ea2b828, 0xacfad6ec, 0x330d6ce2, 0x2efc0264, 0x33737dae }, + { 0x7c7c1d79, 0xbb3640d2, 0xea6a1ae9, 0x3f925a78, 0xd71afcb0, 0x58d88d2a, 0x17ae8765, 0x38c058a9 }, + { 0xd7829d16, 0x3f9504c0, 0x1b1fec7e, 0xc8322d3a, 0x405fd919, 0x3225b4af, 0xc94b8eb9, 0x0fcffc22 } + }, { + { 0x8655a5f6, 0x4aa2ad7a, 0x545dea85, 0x33e98fd2, 0x353b4c5b, 0x17a3c2aa, 0xd04879e0, 0x3c129174 }, + { 0xb42400f9, 0xfd85dd35, 0xec4df9ad, 0x57802e1e, 0xeb1af871, 0x037c50c8, 0xef3c2339, 0x1ae01102 }, + { 0x64d7235c, 0x41f8e7c3, 0xf608d9a5, 0xe5d05986, 0x07a2e704, 0x73a4b0f5, 0x9aeae4b9, 0xc924967b }, + { 0xd3d01754, 0x1ca13de8, 0x6fb9c8f2, 0x66ced741, 0xd20c7f74, 0x2ab0a7b5, 0x4484930d, 0xe8eeaf3a }, + { 0x05a267c6, 0x29394c78, 0x212dc594, 0xe2f65cfb, 0x911e9f22, 0x066d4ca0, 0xc691a4e0, 0xbe6a4ec2 }, + { 0x7093c8c0, 0x46c84938, 0xf948d5a9, 0xaff0ada0, 0xd941397d, 0xf5e08f06, 0xd6c02942, 0x34cf551c }, + { 0x8862a919, 0xb9e5cec5, 0x2e1b13f6, 0xaa2a6a08, 0x9d795333, 0x13f0b2ea, 0x1542db97, 0xdd4df512 } + }, { + { 0xc81f9a77, 0xfc19cdc2, 0x2546465a, 0x128ec4b7, 0x413334d2, 0xebe931ab, 0x99d8658d, 0x2b7c0a40 }, + { 0xcd7479af, 0x46380c5d, 0x761c619c, 0x60fd22d6, 0x594e72c8, 0x9ebb5a68, 0x860f40df, 0xc385724e }, + { 0xec92c524, 0xaa5beb2c, 0xfd54d0e6, 0x90fb0745, 0xb693dea8, 0xfab2f691, 0x7d031158, 0x2292be51 }, + { 0x302085b6, 0x59f3a3d6, 0x0e2d8a11, 0xb58b4afd, 0x3f0a3eb2, 0xdbbd2dad, 0x34f12533, 0x1443a29f }, + { 0xbacaa933, 0x9e9d317b, 0x571f930e, 0x4925d01e, 0x4e7804ae, 0x0a26a382, 0xe6b26cb6, 0x15d77189 }, + { 0xa98fba79, 0xb8b92d81, 0x699c2149, 0x32f18c0a, 0xb7563138, 0xb749e717, 0x19b29021, 0x13ab89f9 }, + { 0x2d5e713e, 0x8e989661, 0x4c2c3ec1, 0x4337676c, 0xb03b6c5d, 0x5ac054e3, 0xc3e56a9d, 0x970b9d95 } + }, { + { 0x1abd6f4b, 0xb3a17958, 0x82284674, 0x7a0b7df9, 0x37c5a4d8, 0xf1e1fc30, 0x4ab90c08, 0xc17c937d }, + { 0xd6dcea60, 0xc2c4845d, 0xdd9d9b99, 0x0f4a1c13, 0x5a1c1e7a, 0x1bc5f66a, 0x3d7a5006, 0x6c506acd }, + { 0xdd31b410, 0xf791a74c, 0x709e9c04, 0x125812db, 0x202083bb, 0xf9f703c3, 0x83a3c36a, 0x93c33b97 }, + { 0x0769506e, 0xa2f38940, 0x79535a97, 0xe635be24, 0x7d355188, 0x1082cff4, 0xa92a5187, 0x1b1b2773 }, + { 0x1c03bc37, 0xce06e83d, 0xf420fc7f, 0x0d259634, 0xeb02658d, 0x08621d54, 0x6d959a64, 0x7ff42395 }, + { 0x5eb329e9, 0xb6b53979, 0xbd5a1d15, 0xf9a26522, 0xf006b31f, 0xd796af76, 0x4eaa60a1, 0xe94f9ad9 }, + { 0xefd27c6b, 0x3f4bee0e, 0x398eff6e, 0x35a01d32, 0x079eb392, 0xb32900cd, 0x2153cb34, 0x969a7076 } + }, { + { 0x75f895fb, 0x14d958f0, 0xe630bc01, 0x5d5d2240, 0x151194d9, 0xadef3378, 0xbb8cac52, 0x4bf9af4c }, + { 0xa87b27a1, 0x66443fad, 0x6e8eb69d, 0xdcf3c748, 0x81024d3d, 0x045793ff, 0x55e91a99, 0xa5fb10f6 }, + { 0x8016a291, 0xc992ae17, 0x10c19198, 0xb2148762, 0xb81df852, 0x08004fe2, 0xd5accd8a, 0x6b2ffe51 }, + { 0xdb89df5c, 0x7c88902c, 0xaed170c1, 0xa57d6ade, 0x034ff768, 0xeb4d868b, 0xed4434f8, 0xb3317c76 }, + { 0x00dd9f1c, 0xc464871a, 0x51b3483d, 0x9091cdd6, 0x3a4ad976, 0x6e9957d9, 0x1982a72f, 0x539d53f4 }, + { 0xacf47c87, 0x6b75d11e, 0x8f5c2887, 0xc7b097f8, 0x861ca1de, 0x2e6fa5b9, 0x6073fa84, 0xa78c4fa2 }, + { 0x32b1393c, 0x3221d47e, 0xd23a49cd, 0x0f11554b, 0x9ceebe9b, 0xab0b03b7, 0x4b6e7441, 0x26c7cda9 } + }, { + { 0x94c472bf, 0x79da14f4, 0xcc7848ce, 0xd0a3f41d, 0x06692f58, 0x4c2db546, 0xd9dbf932, 0xc1873d4d }, + { 0xf1906c69, 0x7df54ee0, 0x8229c4d6, 0x8ad15c28, 0x49adb482, 0xd673baf4, 0xd1db16a7, 0xa8e5e3ea }, + { 0xde6cc806, 0x22aa1c57, 0xb1353c4a, 0x76b84f31, 0x1a54c746, 0x323fd3fa, 0x2ea2b234, 0xe8817ff5 }, + { 0x91c7de40, 0x0271b83f, 0xdb959719, 0xd42ad457, 0x685e5648, 0x9003a4b0, 0xd0a74933, 0x19cb6b56 }, + { 0xe4ec2b1d, 0x8c213e97, 0x0f84c083, 0xd987fb55, 0xb4cd0072, 0xc8e3ede3, 0x298da8c9, 0xed46c25f }, + { 0x52cdd5e3, 0xf9eb66b2, 0x715e0f8b, 0xeeab3d77, 0x5fe40b70, 0x9543e0b6, 0xc4e98491, 0x82a6190f }, + { 0xa274e4bc, 0xbe247bc6, 0x34ec15d0, 0x0550ab13, 0x0ae696fd, 0xfa7d477f, 0xf4c953bb, 0xb0b9d3e2 } + }, { + { 0x450db8f1, 0x5f43bce3, 0x4d82e2cb, 0xfd76bae4, 0xd1712a7a, 0xf745fd41, 0x38a3776a, 0xbdd475bf }, + { 0x93097997, 0xbce94d70, 0x307cd38e, 0x8d2f50a4, 0xf43d073a, 0x838ebc02, 0x74bcf139, 0x75eccfc4 }, + { 0x29bf5a6e, 0x51ff4baf, 0xb786841f, 0x50a26fb0, 0xb73b2eee, 0x15c99855, 0xef2ec068, 0x69c52545 }, + { 0x7783df8e, 0xbd77d58e, 0x53789b31, 0xdb34aded, 0x073bd783, 0x01f53d6f, 0x9ee77ea0, 0x1e5db59b }, + { 0xfc4ffb2a, 0x33485ace, 0x448f0cdb, 0x67baf446, 0x8d897cf5, 0x0558b4ea, 0xc03c0449, 0x90185cdd }, + { 0x4b55aef5, 0x391325fa, 0x0eb13f3b, 0x6d1936f9, 0xd79ab56a, 0xe4677bb1, 0xcf233bee, 0x7cae3f82 }, + { 0x60bca032, 0xef59cbdf, 0xca93d74b, 0xdcaaf290, 0x89499e43, 0xb0000c61, 0xfda7c34c, 0xa8a303a5 } + }, { + { 0xf563f0b8, 0xea7610d1, 0x8d35a2da, 0xb75964a1, 0xe68fe2f6, 0x11eec908, 0x35c5ba6d, 0xd6a264d9 }, + { 0x0561f684, 0xc0304119, 0xb8fa5656, 0x0eb431c4, 0x5b30409b, 0x6c9ef75e, 0xf77afccb, 0xf1fb796e }, + { 0xdd7e958a, 0xd3d873e3, 0x0854439c, 0xae1e4223, 0x7167987a, 0xcd1d8467, 0x523be4eb, 0x796a28e7 }, + { 0x21ad1d15, 0xe52ece62, 0xe19ab217, 0xdbb11c18, 0x3ffb82cf, 0x33a51615, 0xb427bdf2, 0x593e3959 }, + { 0x3b665341, 0x390035fe, 0xffcd92d2, 0x5d565393, 0xecf2c92a, 0xb65c0cb1, 0xf7968ae8, 0x04f2d373 }, + { 0x1191b1aa, 0x56df60fe, 0x4a28623d, 0xdc443bcb, 0x2bf1f915, 0x17906493, 0x0d66b04f, 0x7b97fcb0 }, + { 0xb74a031a, 0xf312938a, 0xa083ad85, 0x2b1902b4, 0xf763fba8, 0x32ceddd3, 0x79b4526f, 0x04a3ad56 } + }, { + { 0xefff17a2, 0x2f2fce3d, 0xd3700c90, 0x7ee9eb35, 0x5ef6198c, 0xbdc9bb0a, 0x26a22d3c, 0x300b2fb8 }, + { 0x81a4d10d, 0xa5e708c5, 0x2dce5f47, 0xaa2012a0, 0xa9ae2095, 0x1eeb4b4d, 0x457aa9d9, 0xeb1ee001 }, + { 0x342eecc2, 0xb5c66a57, 0x0c4ee139, 0x8793343d, 0xa4d8642b, 0x833284c5, 0xabe83fbb, 0x11f08d72 }, + { 0x4fc2206b, 0x41c7b511, 0xf05cc17b, 0x528ffd59, 0x062c9124, 0xbf03c9d4, 0xd978af38, 0x8d0d85ea }, + { 0x87b8ba22, 0xd91e6a06, 0x6169070d, 0xc50f39fe, 0xd270229f, 0x1d72f559, 0x7d0a1762, 0x463ab03f }, + { 0xa4393a4f, 0x9987b543, 0x6f1b03ab, 0x71096fda, 0x9f6dd1d2, 0xf6abc382, 0x35815067, 0x5c365f18 }, + { 0xacdfbfbd, 0x09c57c49, 0xb1afd6ce, 0x2b5821fa, 0xe5997374, 0x35bd8649, 0x22d95b9b, 0x25f30fad } + }, { + { 0xa90802ef, 0xfbcf614d, 0x762de0e6, 0x48c13c66, 0xfa232910, 0x79599693, 0x2c2e26e7, 0xdfefa34e }, + { 0xc0dd8a96, 0x4f1aa0d6, 0x6b8b515a, 0xf27d261d, 0xbc6ee470, 0x5f85a545, 0xfea1cff4, 0xa8b192a1 }, + { 0xd30b6441, 0xb58b28bd, 0x3fac92c9, 0x52fdc9ee, 0xe5297d14, 0xcbd886a1, 0x7252175e, 0x9a165e66 }, + { 0x3dacc04f, 0x98d69b1e, 0x60881c32, 0x501798eb, 0x7184054c, 0x0eec61ae, 0x15585572, 0x7ce7bcc3 }, + { 0x26e4c3bf, 0xc3db64e9, 0x04c85398, 0xb05a43ef, 0x287760dc, 0x5f9c4fd9, 0xa9546cf3, 0xeb64d6d9 }, + { 0x9f56a099, 0xf4464509, 0x666f89fd, 0x3cf27dbc, 0xf78f4ebd, 0x15a92221, 0x1c5f18b4, 0x4ef8d6ed }, + { 0xb9032db3, 0x14df48da, 0x90822fcc, 0x34a687d3, 0xd0c9cbce, 0x49f5523f, 0x57d75028, 0x4d2b7b81 } + }, { + { 0x7a7db3d6, 0x4ce01deb, 0x8d46d28e, 0x0598389c, 0x02496d36, 0x6a946efe, 0x48d76b64, 0x0b398fdb }, + { 0x96dac371, 0xf0e94574, 0xabaeb1f3, 0x464f352e, 0xa538a1b2, 0xaf0839e8, 0x264e3def, 0x70ccb6c0 }, + { 0x8b633b83, 0x9f1fa614, 0xf229f235, 0x18968cfd, 0x1d2be847, 0x47ac9867, 0xc4f32121, 0xa08f2485 }, + { 0x9b553f9b, 0x6939d623, 0xbb578ffb, 0x3de56d02, 0x8d0288c2, 0x4295788d, 0xb53e60ea, 0xbfe08468 }, + { 0x15e12986, 0xbd19316b, 0xfd84a08e, 0x6fde5356, 0xec8dabcc, 0x78c17332, 0x46dbfd97, 0x21e6adf3 }, + { 0xdaf2f1be, 0x6d3d5236, 0x5e95911b, 0xe0571ed2, 0x402aa279, 0x04bc377f, 0xed587a14, 0x9c2db51f }, + { 0xb4a6e3b8, 0x71d06437, 0xbe20faa6, 0x1276fb1c, 0x28103b47, 0x31f900d8, 0x8494dc65, 0x994daf04 } + }, { + { 0x292eb381, 0xb7ccadef, 0x33e7512b, 0x0dfdeb69, 0xc7ee08b9, 0x39a4fbc7, 0xd764a890, 0x7ab00e4e }, + { 0xf7586ade, 0xa3b4d9dc, 0xf789c47e, 0x48beadb2, 0x8a45db69, 0x2e9b595d, 0xfff2a7fa, 0x06ffc027 }, + { 0x19009f8b, 0x88199f63, 0xc306713d, 0x54eae017, 0x7868c7c1, 0xb21b75d4, 0x2236bda7, 0x5277b103 }, + { 0x9d7f35d5, 0x10da1900, 0x79c91037, 0x9f2775fb, 0x2e45ba78, 0x92bc5da3, 0x48b1946e, 0x2b45cb34 }, + { 0x1f6d90ed, 0xaa688d80, 0xfd190719, 0xc1dcd836, 0xb7de1894, 0x5cd7e515, 0x87bb48cf, 0x94bf41c7 }, + { 0x35f36e1b, 0x0da6b6b8, 0xd381a23c, 0x60659705, 0x6c319695, 0x27279409, 0x69130c41, 0xe1fa08ff }, + { 0x8844af91, 0xf2d47dfa, 0xde6ea7b0, 0x2f156a2b, 0x86f8ec0b, 0x38f9d722, 0x7cff87e4, 0x9ab38e0e } + }, { + { 0xb01fd34c, 0x3885168b, 0xa35130d9, 0x8e01a5ca, 0xe6d2d65f, 0xc724f8a0, 0x2e0ef604, 0xfed3c171 }, + { 0x151c057c, 0x9fa733ef, 0x825ba0da, 0x6e283e59, 0x77c4880a, 0xfd107591, 0x3fb3b4e7, 0x274fed9e }, + { 0x3a32979a, 0x29a9b49f, 0xec8e3c5c, 0x3e0ef290, 0x4e3716e2, 0xbfc82d3e, 0x6c250829, 0x3abab9a7 }, + { 0x012addb9, 0x47841e2b, 0x61f0a516, 0x6ba10a6e, 0xfecba910, 0x90a3ef22, 0xfdcf969f, 0x2128f99b }, + { 0x9b81a4e9, 0x57c34d33, 0x026d2762, 0xafd4a1fa, 0x61ea2467, 0x29a81c62, 0x85350d61, 0xe2e0f0c5 }, + { 0x0bf92a10, 0x23e4f7e1, 0x975e75db, 0xb97b6285, 0x7728a26d, 0xa6525408, 0x063a2419, 0x397410be }, + { 0x4ea96c8b, 0xfa56724d, 0xff16421c, 0x7ed6477a, 0xd1e48c81, 0xdb4a93a2, 0x5c4951c3, 0xc0b4a685 } + }, { + { 0x397e460f, 0x89a93121, 0x72092100, 0xbfe312f7, 0xf1a58537, 0xa4d5dcfe, 0x37af5042, 0xf35b1b01 }, + { 0x2ff60f87, 0xfe9a309f, 0xc472ccd3, 0x8d7eeb71, 0xb3739e44, 0x1ca9869d, 0x42da241b, 0x6c858419 }, + { 0xb9d40ae5, 0x5d4e2313, 0xa9c468b0, 0x3d3ddbeb, 0x09906625, 0x50d61c42, 0x2c46d732, 0x3446aa5a }, + { 0x564aa504, 0x96b85cc6, 0x7ef4907c, 0xcd581ab9, 0x65c3841d, 0x865a4915, 0xf7ee2a16, 0x22235ea8 }, + { 0x6cd307e2, 0xb1b22b38, 0x95032608, 0x31598c90, 0xd537604d, 0x97c7e413, 0x73b456e4, 0x6a2df38c }, + { 0x58d9d79f, 0x5aa00b5b, 0x060dd287, 0xc29d346a, 0x8ca763d7, 0xf9f60c66, 0xba6b25a3, 0xa012e14f }, + { 0xe5b626d8, 0x01e19b5e, 0xcbe01ee7, 0x025d6cef, 0x03b6541e, 0x8df0d079, 0x4d4b5178, 0xe7c9c2d1 } + }, { + { 0x09b93266, 0xe2769374, 0x213ce748, 0xbdfa1677, 0x0833c4c0, 0x41241dd0, 0x5bd71904, 0xbe1be728 }, + { 0x280dfedf, 0x6c83f463, 0xba81c79f, 0x78451dfb, 0x3cd12106, 0x044baeb6, 0x77de78f8, 0x036d574c }, + { 0xbd4314fa, 0xd2fb4774, 0xa0b9198c, 0x075e9aae, 0xf99cb714, 0x06bad8ce, 0x17ac87dd, 0x6bf39045 }, + { 0x05af7421, 0x59dc4c4e, 0x66815303, 0x09410376, 0x1d71e342, 0x1a353ad2, 0x7a3196ac, 0x187fe364 }, + { 0xe600765d, 0x070cc12f, 0xd81e74d8, 0x826ee687, 0x6db09ba2, 0x6b88cec1, 0xecca0bf8, 0x0036f362 }, + { 0x5ed8ab47, 0x2fd14208, 0x5aa133bf, 0x7aa529c9, 0xbe424f8b, 0x37c853a8, 0x8afbf260, 0x1bde2671 }, + { 0x5cd6392c, 0x3cdc089a, 0x71d39600, 0x4bcc77d8, 0x0f8df2a0, 0x7566744e, 0x494c12fc, 0x387dee4a } + }, { + { 0x4f51085f, 0xf2b90e78, 0x6f68ce61, 0x1c4787f2, 0x4fbf6b17, 0x004a475a, 0xedfdd2b8, 0x3ef4e7d0 }, + { 0x003f3477, 0x6e0b73e7, 0xf67c90c9, 0x6566374a, 0x0c97fd0d, 0x8be541c5, 0xc2f93b18, 0xf55abff5 }, + { 0x4f03151d, 0x83d50b54, 0x8feae836, 0xe1a91a33, 0xeafb00d6, 0xdfea4420, 0xf9db7e56, 0xbf34289f }, + { 0x6dfb6bdd, 0xd7cc8039, 0x7b0d4aa7, 0xf2f2a14f, 0xab9dd117, 0xff4c8602, 0x9cce7b21, 0x40b2e4a9 }, + { 0x72fa24e4, 0xe2616778, 0x5c058a57, 0x00ba3342, 0x2347e305, 0x8c67fdf0, 0xb967b82a, 0x9fe9b032 }, + { 0x6f4635cc, 0x638b3c73, 0x2e4df741, 0xf7898209, 0xfb573977, 0x59145c96, 0x1af9c653, 0x7b9e3a69 }, + { 0xae9393f7, 0x21f731be, 0x21d894a3, 0x5499a86b, 0xbf841bcf, 0xe947043c, 0x2d75eb05, 0xa72f2458 } + }, { + { 0x8849feed, 0x0516788b, 0xc3ba6cab, 0x73b37f89, 0xe1c59baf, 0xb9065f21, 0x42db6705, 0x83d1eef0 }, + { 0xd6e2fbd7, 0xfa08de4d, 0x3295a08a, 0x948df703, 0xab891657, 0x0940ef31, 0x56d8465d, 0x440d4979 }, + { 0x6ba6d91c, 0x5d5a992d, 0x4089007d, 0xc20f2ad3, 0x548b65f4, 0xdbcff879, 0xe76c77b7, 0x1ad4bd47 }, + { 0xe6dbd3a4, 0x0ddc5764, 0x50227b93, 0xfc70d526, 0xa782abeb, 0xb1eacd16, 0xa6d1d6c7, 0x3eb2fc3e }, + { 0xca7f5ec6, 0x027a6535, 0xf2c08c93, 0x5ab506be, 0x1034a638, 0x91f473e6, 0xc1843ed8, 0x1900ee1f }, + { 0x7a60c3a9, 0x50a3c756, 0xfc5ad1c7, 0xfb5297ce, 0xf06994f8, 0x8736d618, 0x15973fad, 0x87288eed }, + { 0x9eb55603, 0x574a3dc8, 0x66b34637, 0xe38ada16, 0x208710ad, 0x821c2d3a, 0x4d0d95e4, 0x492d3e98 } + }, { + { 0x5c6da280, 0x7b503d23, 0x7a7ff562, 0x13eca08b, 0x9b2ec963, 0x20b5c43e, 0xb9875398, 0xd1588b1d }, + { 0x3898e3db, 0x5d0c38a5, 0xab945ab3, 0x3017f692, 0xa71d187f, 0x62a32ce9, 0xbd51abff, 0x44106aaa }, + { 0x332bbd9a, 0xbc614c8e, 0x50796b90, 0x75ad5cc0, 0xa416a2e1, 0xff24e815, 0x8b0dc6ec, 0xe49b3860 }, + { 0x2c8930f3, 0x73ff7c6d, 0xd0de16d7, 0x7a8d3740, 0xfdb757d4, 0x1f438bbc, 0x27415f95, 0x256f557b }, + { 0x8f7179e9, 0x4ac99a49, 0xcabae259, 0x8b195d21, 0xb444b039, 0xe6dc2b14, 0x3dff8dbe, 0x435c99ad }, + { 0xbde84be4, 0xa5e876ea, 0x79ffb62e, 0xb4b59c38, 0x88474d8d, 0xaaeb867e, 0x6f541557, 0xf0edbe11 }, + { 0xa9b295f7, 0xe65bbcee, 0x6a129fac, 0x2f007beb, 0xcd3dcf72, 0xf5dcc782, 0x38d93d56, 0xecd192f2 } + }, { + { 0xf9e3f55f, 0x9fbcfb77, 0x711a6f90, 0xeb9dfffe, 0x8c0b2e1f, 0x0fdc1b0a, 0xc7ff8085, 0xb8f994c9 }, + { 0xfbd63e55, 0xa26d2623, 0x65c74567, 0x3fda2143, 0x4f91bd40, 0xd183574f, 0x48d6f79c, 0x895b0dc6 }, + { 0x68b4c229, 0x1a1ccfbf, 0xb901211c, 0xb2411c8c, 0xf352f648, 0x875e1f1b, 0x15fc10cd, 0xfb8c6b28 }, + { 0x15f45949, 0x502f1ab6, 0x0c528ede, 0xd4ff8187, 0x6485d018, 0xc367d6ff, 0xe766718b, 0xd5aeb78e }, + { 0x1ab4be9a, 0xe85536f8, 0x4031015d, 0xd579d758, 0xceaa2e0d, 0xace63c6b, 0x9018cae2, 0x2a5fd965 }, + { 0xfc5471e7, 0xe66d169b, 0x98fe8a88, 0xdc3c54cd, 0xe481ae77, 0xbf3ea393, 0x110b856b, 0x825aec5c }, + { 0x714d79f9, 0x3f8328fa, 0x530498cb, 0xf76d4af6, 0x2c983912, 0x89c1f5ce, 0xd8d09111, 0xeb685633 } + }, { + { 0x2d8f63c0, 0xbe538b20, 0x48f219be, 0x62f010cd, 0xe2aa9574, 0x1bb947a3, 0xeca72434, 0x3a3e6c51 }, + { 0xd81b0439, 0x103a616d, 0x044bdfd9, 0x87261d91, 0xcfaef2b0, 0x1a9e9305, 0xd168a778, 0x042fd256 }, + { 0x6565adcb, 0x82794aed, 0x7e4288d1, 0x72106045, 0xbdea5832, 0x09d2a9d3, 0x2f19d1c7, 0xbb94dac2 }, + { 0x4b1affe2, 0xc4127dbc, 0x7d4c045e, 0x0fcddbb7, 0x4da68575, 0x8cba23ed, 0x6015087f, 0x11682c09 }, + { 0x6533bc5b, 0xd2980fad, 0xbadc2f6a, 0x9e008030, 0x47e95fb8, 0x40c381f2, 0xd44c6c4d, 0x70331467 }, + { 0xc33ea1dd, 0xc834cd9c, 0x0fe19999, 0xa813b867, 0x993eddc6, 0x9ba575ba, 0x004aa894, 0xdba239ba }, + { 0x252aa22c, 0x44c17e93, 0x44290993, 0xd9a1173c, 0xe1ad9624, 0xd807429a, 0x532cd975, 0x12e0b42e } + }, { + { 0xfdb70d4d, 0x249e6468, 0xb794eb31, 0xb4cda501, 0x05d2df03, 0x26ab2206, 0x43194da6, 0xa4892a63 }, + { 0x42db2d46, 0x53017669, 0xc77e5314, 0xa9683da9, 0xfb498122, 0xddac9a38, 0xa2d4aab4, 0x4e0122b2 }, + { 0x13967236, 0x68646a6d, 0x513d4c57, 0x1aea2842, 0x093e446c, 0x298d4327, 0x0d900798, 0x9ad6c44b }, + { 0xe91847cd, 0x3df8d5da, 0x46769a8f, 0x3ad7f4d4, 0x2dc96116, 0x547f08e8, 0x840cf77a, 0xb6f0ce2e }, + { 0xfb4ea959, 0xa67079f4, 0x21e663d1, 0x10dafde7, 0xdc0ea2d6, 0x373974ca, 0x1c1cc126, 0x6dcdc5f2 }, + { 0x6808c423, 0x6f4342bd, 0x9276497d, 0x0c7fc6ce, 0x9a9e5ae3, 0x86634270, 0xdf81f26a, 0x47d913a2 }, + { 0x64337517, 0xa3a009e5, 0x98b72802, 0x4d0035e4, 0x1715ab1c, 0xae2e2a92, 0x113b2c57, 0x9a85326c } + }, { + { 0xd301c714, 0x9b6306bc, 0xa0719561, 0x98c1c165, 0x73787133, 0xecadf261, 0x64f89540, 0x5c5fa46b }, + { 0xf565ee58, 0x05263bbd, 0x88df1939, 0xf4347f95, 0xbfcfa374, 0x583ecd77, 0x7c1bfc76, 0xe6d28c42 }, + { 0xadb4b3c0, 0x146b1371, 0x58a96e94, 0x9b000315, 0xc41f4de7, 0xea787c29, 0x30c1134d, 0x6d65f20c }, + { 0xc026d6ec, 0xe96ebb42, 0x24aba2c1, 0x650a4043, 0x9ecf024e, 0xbbaf6c1e, 0x9be6b48f, 0x89e859fe }, + { 0x51de4cbd, 0x204fc586, 0x54d88ac3, 0x2da8027e, 0x47aee04e, 0x4ed28825, 0x5d773f1d, 0xc44f931b }, + { 0xced4dd07, 0xf60b6c8e, 0x80dbcd9a, 0xa8a6a7c0, 0x2320d406, 0x99043ee5, 0xe7fb777b, 0x66e1f534 }, + { 0x6ec8e251, 0x09d9982d, 0x33699ebc, 0x631c7077, 0xd2a8af8d, 0xed7b6d3b, 0xf13e160f, 0x7c03e997 } + }, { + { 0x33c4d79e, 0x898f1b11, 0x44482aac, 0x8dacba1e, 0x41e4c65d, 0x373ce7b9, 0xcc21ed0a, 0x1425aacb }, + { 0xd42df634, 0x2c0d59c2, 0x00d29c49, 0x02711b1e, 0x033e4a85, 0x5269c575, 0x383e490f, 0xaeac042d }, + { 0x033f1689, 0xc8181373, 0x957bd9cc, 0x45b8a400, 0xb9f5ccf4, 0x3f34af98, 0xad3b249a, 0x8e096a78 }, + { 0x62144bde, 0xee9c9ee3, 0x55e7d9f4, 0x2183bea5, 0x12787270, 0x3a070f24, 0x54854d06, 0x1f230a8c }, + { 0x98c2a493, 0xade86d34, 0xc4926805, 0xd2f4047d, 0x6aac8a8b, 0x845802bd, 0x279b27ec, 0xe5b61e60 }, + { 0x24f3ca82, 0xa2d5aada, 0x9ec9c6d7, 0xdabf2c25, 0x1e210f57, 0x92ad1840, 0xdec763c3, 0x078a670d }, + { 0x7533c951, 0x4b3509f2, 0xae7b17a2, 0x7fb46453, 0x095c06cd, 0xfe0f182f, 0x3bbee6bf, 0x18a14cfe } + }, { + { 0x0e2781a1, 0xe97035be, 0x7732ac33, 0x6e02ec7a, 0x9ba7d4ab, 0x2418f146, 0xfdb027b0, 0x3f16c517 }, + { 0x076864ce, 0x94754806, 0x04edbc89, 0xf79f8406, 0xbb43b69e, 0xae037547, 0xf2bd3d49, 0xa721d01c }, + { 0xc9ff1983, 0xf2c3d29f, 0xf18dd754, 0x8f547f44, 0xcfdd1ae5, 0xe2de86e7, 0xb5a20324, 0xa4929edd }, + { 0x3a5908ce, 0x228ff251, 0xa72b0116, 0x7faf015b, 0x5e47a8e5, 0x1c1769aa, 0x2f9c2b9f, 0xfdbbba49 }, + { 0xfa194cce, 0x5e55687a, 0xa888e170, 0x5b900365, 0xab7308e9, 0x1195c7bc, 0xe7e1fd36, 0xc563c595 }, + { 0xa44757e6, 0xe4824c46, 0x8f0575aa, 0xe897ef25, 0xe36d0d97, 0x87bc45ee, 0xd12fa819, 0xfb9b89e2 }, + { 0x48b3e1fc, 0xae563712, 0x0dc01dfc, 0xa055c68f, 0x52606591, 0x9546e1ef, 0x178700a8, 0x9c87b5bb } + }, { + { 0xde4ff097, 0xb76497ad, 0x41691d4d, 0xbd4ac0df, 0xd4db2a81, 0xcc3048e1, 0x2cffe546, 0x6120d83f }, + { 0xb03b5a0e, 0x374ab1f3, 0x1b4e0c82, 0x9b0eb479, 0x6e6558e0, 0xe8b9cf4b, 0x0c436779, 0x64b4cae1 }, + { 0x2aa9eec0, 0x0419fb6a, 0xec8fc744, 0xd3b8c697, 0x24f24eee, 0xbf05ce66, 0xf6bcf4e4, 0xeafe8e61 }, + { 0x9a9dd013, 0xbfe8d389, 0x32fa363a, 0xda38d629, 0x07b584d7, 0x2a843374, 0x1b08df96, 0x415c4739 }, + { 0xd1164fd5, 0x669ab97d, 0xd1886cc9, 0xe23ba6f7, 0xd897d70a, 0x212dac1b, 0x43580802, 0xbb4b44df }, + { 0xdde96bb2, 0xa665cc57, 0xc422df91, 0x28627b38, 0xe32b9043, 0xac856b0e, 0x44d1cc14, 0xd75f6e24 }, + { 0xe5bd8a60, 0x305e17b4, 0x1f9ef0a2, 0x6ee010ed, 0xacab6d31, 0xa7bdc581, 0xa0344638, 0x792c1ab6 } + /*}, { Not enough memory for more test values + { 0x28a402a1, 0x369bdeb7, 0x4d9929e5, 0x3cfdc35b, 0x99c68de9, 0x9b6b006e, 0x3f242273, 0xcf37d576 }, + { 0x6872dd61, 0xe87e9923, 0x8e8655ab, 0x67715999, 0xa60933ca, 0x641e96e4, 0x44600c84, 0xea3a4950 }, + { 0xadd02acc, 0x35f0de97, 0xecddc84f, 0x0a9dc8c6, 0xd5b537b4, 0xf7c27994, 0x75d0b679, 0xde9b4aef }, + { 0x9d6f7170, 0x2ecd6906, 0xd37b167a, 0x225544a3, 0xea804fad, 0x8e21f9f9, 0x600cc5d9, 0x9acec1db }, + { 0x30736fdb, 0x484f20b0, 0x8f237526, 0x8e2bac97, 0xe655a922, 0xba6033b2, 0x5c12ce66, 0xfd986542 }, + { 0x3fb7d59c, 0x6a2d0274, 0xb32bb0f8, 0x66420444, 0xe02c099c, 0xcb82f762, 0xf2b0ffff, 0x39925401 }, + { 0xb4904e77, 0x6aee6579, 0x6afa1fcb, 0x16c64c1f, 0xe727f962, 0xe0eac572, 0x0889748a, 0x67f2b130 } + }, { + { 0x5a4cc087, 0xc8f6a8b0, 0x1993e8f6, 0xac9cb15f, 0x445a34d1, 0xcb11c435, 0x5eba923d, 0x2032b0f8 }, + { 0xbc3487ad, 0x248e8b06, 0x34c09be8, 0x5f02e184, 0x1e170443, 0x6dd2ec7b, 0x7692ce10, 0x16c6bf1a }, + { 0x12938c14, 0x41ddff40, 0xc2d9bb7a, 0x29039e61, 0xa5ed3581, 0xc67f062e, 0x58d10b6d, 0x6c72d42f }, + { 0xe2d58c4d, 0xeb378fc2, 0x6ba88b23, 0xa07c418f, 0x13d143d3, 0xed55b235, 0x5f84d338, 0x52e2c3db }, + { 0x69e1205f, 0x4f96c4f7, 0xf79a860c, 0xef1542ec, 0xf23440e0, 0x4c66e965, 0xd60efbbb, 0x6e8f8b92 }, + { 0x824a38a3, 0xe1eafa00, 0x154e26d6, 0x78d00313, 0x20b89e9f, 0xaa788ca9, 0x19e318de, 0x6fcbb039 }, + { 0x9c23b1b2, 0x853180ef, 0x8d2961a4, 0x4f0c4086, 0xb22be3db, 0x1e900ef0, 0x9d76df53, 0x5d4c468c } + }, { + { 0x20b627c2, 0x9be7dc8e, 0x64c974d9, 0x5d4f49d3, 0xbbb2c618, 0x8ebc012d, 0x11de15e3, 0x500c8265 }, + { 0xfb78e338, 0x58caf269, 0xb2664ca1, 0xa16ff7b9, 0xd5c2a2ea, 0x59d06298, 0xcaea674b, 0x0059ff48 }, + { 0x14bd4018, 0x24070094, 0x169f4ee8, 0x8255fe21, 0x47881c1e, 0xe205f0d3, 0xe4ad2e99, 0xb51d8e3d }, + { 0xf3dbb59c, 0x0cb4edc1, 0x275400f7, 0x98d8295e, 0xd214a339, 0x99fd8ebc, 0x8acb2217, 0xf6a68389 }, + { 0x33d7751d, 0x8fb40299, 0x2b6f32f6, 0x2b2b3692, 0xa83a6091, 0x57052ba3, 0x667f9ec4, 0xb3d2f097 }, + { 0xe37fd38e, 0x13c2b82d, 0x9d913405, 0x5d2c7a55, 0x6390a8f4, 0x9fdc5f4c, 0x853e3b1b, 0x8034410a }, + { 0xfd9edeff, 0xc62d6110, 0x31567b91, 0xc7d0527b, 0x48d0742b, 0x57b3147c, 0x8f9291e5, 0x7d82cfbf } + }, { + { 0x7c63bde3, 0xaac4548c, 0x9954854e, 0xd67f0b4c, 0x04add2ab, 0xd88a2671, 0x7f2171df, 0x0d0f23c8 }, + { 0x5cf6c809, 0xd23f9751, 0xf79294c6, 0xf6019524, 0x7aa39681, 0xb8e3d988, 0x3c8c962f, 0x5d173fd4 }, + { 0x47f3efe5, 0x6d09cd2e, 0x330a8acb, 0xcfe181d2, 0xa48d9fc6, 0x4e988ccb, 0x821f042b, 0x6b5d6c84 }, + { 0x64c52567, 0x10ef805e, 0x173e3c5e, 0x3aacf828, 0x38510c01, 0x48a7ec10, 0xa3506ab6, 0x36220329 }, + { 0x5377bb61, 0x68c1f7ee, 0xe7a81b3c, 0xb43c58f9, 0xd72cb6f9, 0xd81dea3d, 0x7ae1468b, 0x55ac4f26 }, + { 0x5f731a47, 0xe3e19cfb, 0xf45410ed, 0xfba8ccc0, 0xf0c63a7b, 0x9ce539ae, 0x37e562b8, 0x180c6b70 }, + { 0x91a3cd39, 0x5ed053af, 0x09dc142b, 0x74f4a3c1, 0xa2180c04, 0x481bfb15, 0x37bfabed, 0x062e5fe9 } + }, { + { 0x28164987, 0x3c79131e, 0xd586a38a, 0x0dcbd921, 0x11f5a23a, 0x10a64e80, 0xb232f8a4, 0x9a82c6e5 }, + { 0x7b31e67d, 0x1e818e13, 0x097cd563, 0xbe4b6ea4, 0x1d7a3f57, 0x15f686de, 0x9bce46c9, 0x760756da }, + { 0x3960cfd4, 0x75bb04c5, 0x407c84d4, 0x9c625b7e, 0x7191b584, 0xb67878c1, 0x0e1fe6f6, 0x0eb1fa47 }, + { 0x271fd0fd, 0x404080f2, 0x97009534, 0x046c3515, 0x65ab41f9, 0xeb7d7922, 0x2d6499e9, 0x9c899500 }, + { 0x419f9d54, 0x0502c3c4, 0x8149723e, 0xd7b2d502, 0x20236144, 0xaa3b83a9, 0x769631be, 0x15f1e2e0 }, + { 0x601c6fea, 0x5119d153, 0x7d992c1d, 0x94836009, 0x3e7879f0, 0x9086a342, 0x803b925a, 0x4fd645ff }, + { 0xa49bc82f, 0xe14d1519, 0x1d12d5dd, 0xab10a0bf, 0x54f5e7a3, 0x90933da3, 0x21d62740, 0x1d33d0f6 } + }, { + { 0xa36e4642, 0x48c6f79d, 0x955654f3, 0x93b8d1ea, 0x6ba29e14, 0x551ad31f, 0xa99cd6a5, 0x8ccff1ad }, + { 0xcec5d3bd, 0x788fa022, 0xa65d7f7c, 0xd3f37c9e, 0xcce12026, 0x3cd4770d, 0x6ddfea77, 0x6ad3c080 }, + { 0xe81c88a4, 0xbc7bad3b, 0x3068f251, 0x18ada085, 0xa33faaf1, 0x0b797e20, 0x7a97a834, 0x8e782d5e }, + { 0xf51dde3a, 0x6db8ee9b, 0x7aa32969, 0xf2d6eec7, 0x993273e8, 0x11db4e21, 0x7a7088ae, 0x4da2d705 }, + { 0xfc7f198b, 0x86661fe5, 0x29824ae5, 0x0bb639b1, 0xc610a7c8, 0x62a3340e, 0xf591a187, 0xe265a886 }, + { 0x5f303123, 0x47f52dec, 0x34cdd38f, 0x4c7f811a, 0xc9afc901, 0xd222f90a, 0x9e172313, 0xee1b0572 }, + { 0x4a2bcd87, 0x18e236cb, 0xe5e581cd, 0xe29a6a43, 0x6a7213b8, 0xc675d970, 0x536317bd, 0x96b8b310 } + }, { + { 0xad80bed2, 0xc2f4598d, 0x4e0e6b1a, 0x9bc787bd, 0x63150672, 0x2c364163, 0xb601596a, 0xad670a5a }, + { 0x5c818829, 0xa1a6f437, 0x8d07faf3, 0xbe095484, 0x5fcd6a0e, 0xe8153a60, 0x7ab38539, 0x2ec01d0c }, + { 0xf10716f7, 0x44fd8ad0, 0xf5eb5bd9, 0x6bf45e03, 0xb71db435, 0xf3bed1f2, 0xab5c78fb, 0xe739dff4 }, + { 0xe0442ca5, 0x6096f428, 0xae68050b, 0x5040c22c, 0x38145576, 0x879ef275, 0x16ee9eb4, 0xf3c87da4 }, + { 0xf8fcd22d, 0xa7b97f06, 0xc24747b0, 0xe551e501, 0x5d5ed8b0, 0xf34f091e, 0xcafe3402, 0xb13219e3 }, + { 0x6310481d, 0x48a0e061, 0xc634d04a, 0x194efd1d, 0x4bd0f859, 0xae14caf3, 0xaccc7f18, 0x6f07f30d }, + { 0xffce35a4, 0x10d857a7, 0x1e9e7485, 0x97b41d7b, 0x69d5f637, 0x82789997, 0xa51b2cf6, 0x02014738 } + }, { + { 0xdec05e64, 0xa4305211, 0x7308530c, 0xd0382cb5, 0xa921a607, 0xc7562dc3, 0xb1411342, 0xdd40222a }, + { 0x972caa85, 0xf01a419e, 0xfd78e685, 0x03ba1374, 0x8f9bfc0f, 0x261a4f34, 0xb49fd99d, 0x24859598 }, + { 0xf016dab1, 0x4c50d39e, 0xfb46c5b7, 0x249fea28, 0xb05e1503, 0x0e350a32, 0x2dcf1792, 0x61a75e0a }, + { 0x7fd4d35a, 0xab08244b, 0xbbcd7d53, 0xd42b211d, 0x2334426b, 0x9a8be30f, 0xe15e1b27, 0x6700bb18 }, + { 0x81e463e1, 0x637b4877, 0xb6047da1, 0xb05fd377, 0x96a012ff, 0xbb5379f1, 0xac42f5c8, 0x5dba484c }, + { 0x0714b7ef, 0xba6f8b10, 0xf245d72b, 0x1ec0e0a2, 0xa30de08d, 0x606bc646, 0x7eb95591, 0x6cf9c5e8 }, + { 0xf15d21fe, 0xee367937, 0x37ca63eb, 0x38cb30dd, 0xb5edebde, 0xb6355078, 0xbb62f2ee, 0xdd48e81d } + }, { + { 0x321bf4dc, 0x678db650, 0xd85439e4, 0x7b6aea4f, 0xc5625ee3, 0xab2b9fca, 0xb9e6140d, 0xfbe4313b }, + { 0x077bcae6, 0x63858c36, 0x2baa791d, 0xc55acb58, 0x843aa75c, 0x20b25d1d, 0x86778175, 0xe4454679 }, + { 0xddfb82f4, 0xcf34b84e, 0xbc573a41, 0x8684bb95, 0x9165bee9, 0x01e96a7b, 0xdd8a5c36, 0x9bc63a4b }, + { 0x175f0270, 0x85daa416, 0x8ee7aea3, 0xfa9b3ce0, 0x9b300d7a, 0xda4ef944, 0xfc1e20b8, 0xb33f81df }, + { 0x2346a3ca, 0x842c59ec, 0xdae0db05, 0xefe15ef0, 0x2cb166d5, 0xb7d24593, 0x7e2e55aa, 0x8aba26dc }, + { 0x6c7c1a83, 0x1e49e02d, 0x7a3f46c2, 0x86e7d519, 0x255db209, 0xb47bec27, 0x69be2738, 0x982cb66d }, + { 0x9798ef0d, 0x216cf79a, 0xc8c8e509, 0xc73f1221, 0x684b472f, 0x8f58a334, 0x3d97a615, 0x4d6508bd } + }, { + { 0xa6333ddd, 0x0fe1133e, 0x690a745d, 0x62d04786, 0x50809359, 0xa30d43f2, 0x37a3078c, 0x31ad4ced }, + { 0x54dc6b53, 0xaa5dd46d, 0xef5f2911, 0x0818c5ca, 0x36c062aa, 0x044f58d4, 0x95dde443, 0x8004fc36 }, + { 0xd02db1b3, 0x1aac3560, 0x0a8deed4, 0x80e1145a, 0xbe53d775, 0xc6fe4194, 0x324c5b8d, 0x280dd8f8 }, + { 0x8e1dba30, 0x1d3218a2, 0xc63f7a0d, 0xc5be3354, 0x216a2233, 0x46508c32, 0x4762d05c, 0xf447d7dc }, + { 0x287d15ec, 0x5718b4d8, 0x890dea30, 0x918a4efd, 0x0b7d66b0, 0x26d2760c, 0xb003f19b, 0xa20a16af }, + { 0x0a67c579, 0xf114428b, 0x30826097, 0xa82d8115, 0x42e433da, 0x79952e07, 0xf761af54, 0x2509ce73 }, + { 0xe06a143c, 0x7671a5c7, 0x57ad02b0, 0x1e7922b3, 0xa79d9cf2, 0x23c7d736, 0x27a71a9f, 0xf20a7a98 } + }, { + { 0x85ab3b20, 0xcda3876c, 0xe3eb55a6, 0xa78bd139, 0x3eda09c0, 0x3f3cec06, 0x1ecee3b7, 0xa6ea50d1 }, + { 0x1fea79d6, 0x6a8467c1, 0x3607cbbe, 0x9667f95a, 0xef3c2d31, 0x81f98f91, 0x7ce8153d, 0x4c72445f }, + { 0x921d1a7b, 0xc675bde6, 0x60c66243, 0x7eaa7a71, 0x6c23d2ea, 0x1d734a2f, 0xd453c205, 0xb981e1c1 }, + { 0xea8ad813, 0x9cf1aafe, 0x1c0e04a7, 0x3d925777, 0x621348ba, 0x2df1c440, 0xee62c9aa, 0x3d927ddf }, + { 0x34b4ed37, 0x5bb5d025, 0x8c3af0c9, 0x38085638, 0xa5e93103, 0xd89a0a69, 0xc26f52e9, 0xa146e16e }, + { 0xec07d11b, 0xf96005cb, 0x9b88036c, 0x9bf2d66b, 0xba9d4dd1, 0x5cf3afda, 0x36a2c753, 0xa2b39387 }, + { 0xc9681d87, 0xf2606e31, 0x1cad2ccb, 0x4c46cc46, 0xbc055d18, 0x76477020, 0xf36b1469, 0x222bd6a8 } + }, { + { 0xf01f1457, 0xf38b5224, 0x938e42d0, 0x5f4b2a89, 0x97f7b8e2, 0x6af0624a, 0xdc87e23b, 0x78351bcc }, + { 0x42d5a5c9, 0x63244e3b, 0x27cabb02, 0x68dcecd9, 0xb6b45aae, 0xb9e29eff, 0x783d06b0, 0x5f00cd05 }, + { 0x8822ba95, 0xb1c77282, 0xa7528cbf, 0x5b642abe, 0x11a09888, 0xe3bf0072, 0x6f195fc5, 0x1c5a644a }, + { 0xdad7cadb, 0x236ab60e, 0xb12b2346, 0x5ef033c9, 0xed8442c2, 0x0caa95cf, 0x1de955f2, 0x746e58f8 }, + { 0x5b80c6a6, 0xdf45e092, 0x000098e8, 0x567a2745, 0x637947a9, 0xaa28306c, 0x17414875, 0x7a116532 }, + { 0xa82a0347, 0x26da21cd, 0xe887b642, 0x03a2d7cc, 0x7b89910b, 0xb41a2258, 0x749c621f, 0x8f9580a5 }, + { 0x0dbbd2d7, 0xd4d781b2, 0xe3e8cd9a, 0xf38d6295, 0xf19f54cf, 0x43f2a094, 0x07baf4df, 0x20ba116f } + }, { + { 0x58e6a0ac, 0x5dc19add, 0x888009e9, 0x1dd6e61a, 0x56712abd, 0xdff594cc, 0xf87aeb88, 0x53a8fa9f }, + { 0x289deff2, 0x9ccaf9f0, 0xee65aa45, 0x45d0d0ca, 0x2c200e70, 0x76b2e8a5, 0x00a36a1c, 0x85e09bd0 }, + { 0xb144adcf, 0xb57dc77d, 0x997bbd40, 0x29fa695a, 0xa9bd6eb5, 0x197994fb, 0x545a1fb1, 0x6acbdf57 }, + { 0x0b14bff6, 0xe3fde283, 0x421a86b3, 0x84a2ed64, 0x4903f0cd, 0x4882a5b0, 0x99dc11a5, 0x7cd4ba5d }, + { 0x5384a828, 0x7f092d00, 0xcbf8bb8f, 0x875822bc, 0x78bb00d4, 0x3684b2f3, 0x639cc3bd, 0x8c66e4ba }, + { 0x6c1cdd98, 0x1822b0c9, 0x325de314, 0xc9943d1b, 0x7f44eb80, 0x51f99a28, 0x799bad7b, 0x2c775463 }, + { 0x9b9db476, 0x38529ecc, 0xe2b08177, 0xe87f3a4b, 0x434f17d6, 0xd60a939d, 0x987d398c, 0xf09c407c } + }, { + { 0x85a57b94, 0x96e34ac3, 0x7c1fcb0e, 0xcec52171, 0x6851d813, 0x24406843, 0xe4e27111, 0x68e8ed5c }, + { 0xe9d17c83, 0xb192f6fd, 0x222db69c, 0x1e76270f, 0xc0481209, 0x302b015d, 0x09c03864, 0xef48b70e }, + { 0x2e9c8690, 0xdbbd87ca, 0xb0bf73f3, 0xe68b1bd3, 0xf91e354c, 0xd21a5bda, 0x6d40f59d, 0x2f709c0e }, + { 0xa9e83d82, 0xcccc43c1, 0xbb82d5a7, 0x5e0d485e, 0x351b6e06, 0xa1b01407, 0x1d0db76f, 0x73b99761 }, + { 0x4aac3b84, 0x29a2d54f, 0x4da423f6, 0x9d89d842, 0x3e999040, 0x2e7c2611, 0xfe378ca4, 0x442800a5 }, + { 0x260d5c19, 0x76eb2a52, 0x4a5b47ff, 0xf7e6fabb, 0xd2d7860f, 0xe6abe0ea, 0xafcdd3d6, 0x681ea9a9 }, + { 0x68720507, 0x2a37b22c, 0xff8984a3, 0xf7e0d12e, 0x4df3f317, 0x7040e3cb, 0xfacd634d, 0x796c96a2 } + }, { + { 0x5352f0a5, 0x55ad43e3, 0x06bf6b14, 0x99b934a9, 0x3a6cbadf, 0x1cc14e10, 0x59350db9, 0x146f6718 }, + { 0x9da0de05, 0x1d33e78b, 0x8e1d427a, 0x30c4bd07, 0xf26567cc, 0xbf5547f5, 0x9dcc1f2c, 0x920485a1 }, + { 0xd38119ca, 0xe9db0638, 0x6ddd7130, 0x5e3f5363, 0xf7d34a3a, 0x63f0143c, 0x3a76f6ea, 0xfac3efc0 }, + { 0x877d6bbf, 0xf15c6e46, 0x412c55cb, 0xd24f3b80, 0x6f6d20a2, 0x55428f45, 0xeb4ff919, 0x38049698 }, + { 0x482afc56, 0x67146e20, 0xdf564d52, 0xee6b3feb, 0x944c2574, 0x40708097, 0x0219eafd, 0x4fdcd685 }, + { 0x2b8fea18, 0xb6299087, 0x9558121f, 0x8bdf9ac2, 0x2b5f47d8, 0x5facf5c2, 0x67fa9cd1, 0x0eb09dd7 }, + { 0x61cd8815, 0x09b4cb25, 0x404633df, 0xc5d34a09, 0xf1ead406, 0x9b7808dd, 0x6e442c61, 0xf87fe2c0 } + }, { + { 0x9ba10f2d, 0xddba6810, 0xc6e336c0, 0xcc0e40fb, 0x4a3bf613, 0xeabe6581, 0xadfac597, 0x0ef51d0d }, + { 0x136a13b1, 0x7cf08dab, 0x35cc34b4, 0x882e8b95, 0x12866965, 0x91042194, 0xcff4fb1f, 0xd9e7137c }, + { 0xf2103c58, 0x91dde4d5, 0x20c6244b, 0x2b2c026e, 0xd668b18a, 0x68e4f0cf, 0xe9937ae0, 0x54bd314c }, + { 0x10095a94, 0xee6ac09f, 0xd4869250, 0x59df6838, 0xef6b63aa, 0xca0e62f9, 0xffc6516f, 0x3e001f77 }, + { 0x6d5ae56e, 0x9ce44f0a, 0x7f224c8b, 0xdc153a44, 0xf2000c2d, 0x4ebe91d6, 0x4053387f, 0x3296f38e }, + { 0x55e286e4, 0xa2320b46, 0x4c196112, 0x43f1de21, 0x6c7429be, 0x007408ba, 0x5773d9dd, 0x91e9cc9e }, + { 0x3b06341c, 0xead96907, 0x30eedea2, 0xd69c6d23, 0x302f6f92, 0x052a5e79, 0x183fc11e, 0xb24a1d78 } + }, { + { 0xda957c47, 0x5dcbbff8, 0xc7994c1d, 0xef6aa305, 0xcc8adc07, 0x2055ef7b, 0xcfab4417, 0xab2a094c }, + { 0x86d1cd26, 0x834de2b5, 0xa7e5c491, 0x611e130b, 0xe8b6197b, 0x73c03065, 0x53b2b4a3, 0x2cfff0d2 }, + { 0x8a0f2ef0, 0x1d8a0aab, 0xc09c0529, 0xf16f58d6, 0x8255bb71, 0xcba02e81, 0x50da60d3, 0x4020039a }, + { 0x2918bfbf, 0xb4974ba9, 0x0b671f29, 0xaf45f2ce, 0xf95e9145, 0xcaf7bc2e, 0x6315709e, 0x7d433a11 }, + { 0xb607f4dc, 0x2d28a67f, 0xe054622d, 0xfd7ad1e8, 0x6fff4cc5, 0xb817dfe3, 0x7f610798, 0xc2a04709 }, + { 0xd6709af6, 0xafc3d127, 0x13c73760, 0x87ba5160, 0xfb2f15ed, 0x16845096, 0x082587a9, 0xd8163ac4 }, + { 0x7760ac0d, 0xff325b36, 0x06187a59, 0xe30aed0c, 0x6ad23dc7, 0xed972adf, 0xb43917a6, 0x75e08234 } + }, { + { 0x47425229, 0xb152561c, 0x424c8f3e, 0xbebff689, 0x5aa3745e, 0xc887858a, 0x0a80522d, 0xb07417a2 }, + { 0x964a13ec, 0x7a38907b, 0x982b2e8a, 0x556372c2, 0xa6535de2, 0x9183958d, 0x41393d50, 0x3ae0ff85 }, + { 0xb7751cba, 0xe3158d80, 0xce83731b, 0x08fea730, 0xec4329a7, 0xc56417c1, 0x7814056f, 0x24a5b025 }, + { 0x92ccdf79, 0x57948abd, 0x6da546bb, 0x97387365, 0x6372286f, 0xab4ec166, 0xf41327d8, 0x99145807 }, + { 0x90477a42, 0x2fb03ec6, 0xae58212e, 0x7f2fbfec, 0x4551b819, 0x2a31a33d, 0xd4a2b6d2, 0x885f3a45 }, + { 0xe691d16b, 0xff1d8f20, 0xb5c52fe2, 0xd7d8d5aa, 0x0a4e63e8, 0x5055221d, 0xc1667dc8, 0x7507670e }, + { 0xc8c64690, 0xf96e7838, 0x7e2c9296, 0xab5d22df, 0x3e46e338, 0xfaf7e6d0, 0x9d002e41, 0xfcd23f54 } + }, { + { 0xf35d4936, 0x665f0735, 0x1bcd71c3, 0x5a6e41bf, 0x12b48199, 0xed9b7113, 0x261ea2a7, 0xf4b6742e }, + { 0x0f8e6f12, 0x9304c346, 0x5a93e4c1, 0x07e2093b, 0xbcf80811, 0x3fec2744, 0xd2676f19, 0x04eab869 }, + { 0x7c00eb7a, 0xdd7dec8b, 0x985bf83f, 0xc0de6b34, 0x30ff77c1, 0x998ac2ae, 0x8df4d5f7, 0xd1d47538 }, + { 0x274b0adf, 0xb5cd2f9f, 0xaa995e75, 0x70c443d3, 0xd0fe6e3c, 0x5db8f6c8, 0xa36e9826, 0x29d198c4 }, + { 0x36594cd4, 0x63117bef, 0x9bc7ab17, 0x99a59efa, 0xb4563e58, 0x1d83ae87, 0x62adcb06, 0x685d0aaa }, + { 0xe4f93710, 0x95348ee4, 0x5027940c, 0x96b83cbf, 0x801fa811, 0x46032811, 0x7249910e, 0x0878692c }, + { 0x14bf9817, 0xd127a27c, 0xf2975482, 0xeda61089, 0x3f017d6b, 0x415fe209, 0x44e4b5d4, 0x108dd3ba } + }, { + { 0x9ca4a419, 0xbd205087, 0x67e09af4, 0x413207b2, 0xb12fa7ab, 0x993be0b7, 0xf311f156, 0x56c54bd5 }, + { 0x5e86639d, 0xa3e6476a, 0x3fcc442e, 0x0dcf9138, 0x57b35b7f, 0x11185891, 0x8f835e60, 0x79b6bcb1 }, + { 0x26262fdc, 0xb1a499db, 0xa2bfe1e3, 0x552e6f66, 0x7939bd03, 0xc3eb7083, 0x66ea8877, 0x22151649 }, + { 0xc7f00291, 0x9801f66e, 0xa90c690c, 0x2f8e37c8, 0xe12b4fb6, 0xc94fe0c1, 0x3b1eb773, 0x41323147 }, + { 0x9afc5c6c, 0xb82cea10, 0xbd95f5bf, 0x4616565c, 0xc306b422, 0xbc312687, 0x10df3428, 0x91f6fda4 }, + { 0xdf566054, 0xd69362d4, 0x74bc3bad, 0x0c48ac9a, 0x6ebd7fb6, 0xd57b706d, 0x38520c15, 0xbf2dd2a7 }, + { 0x430fc0a0, 0xbf37d40b, 0x0af82928, 0x33df1e63, 0xec5fc8f5, 0x9ed64256, 0xee78a46a, 0xf6ffe8fb } + }, { + { 0x2aeb1de6, 0x443aceb9, 0x97a4ba87, 0x7fdb5be8, 0xfda17dba, 0x43bfdc7b, 0xc7435808, 0xf56491a9 }, + { 0x81961723, 0xd9b859a9, 0x94a90e21, 0xe1941143, 0xf4c3f277, 0x83e8cb49, 0xeb919a5d, 0xc7344af0 }, + { 0xb9183a6f, 0x91c76f0b, 0x2bab1eff, 0x7bbb4384, 0x1ee2e225, 0xe5324e3f, 0x49e0f743, 0x699dcfca }, + { 0xa72d9c94, 0xb82fe67b, 0x5260f168, 0xd7d549cb, 0xf5f4297d, 0x19c5e734, 0x13cb084b, 0xd92902ca }, + { 0x0abc9207, 0xb9aa8e11, 0x98267f2e, 0x047679cf, 0xc1629efb, 0x112546e4, 0xa6962729, 0x204d1b1d }, + { 0xdfccb5b1, 0xb0d3511e, 0x97f071c5, 0xff3ffc4e, 0x78aac259, 0xa62c0afd, 0x7e85609d, 0xc8f54f39 }, + { 0xa1118851, 0x0efdd2d0, 0x05e6797d, 0x3516c425, 0xe10e036b, 0x8c0bbce9, 0x6cc72e90, 0x72fcd49c } + }, { + { 0x471c0c97, 0xd2e41f86, 0xea6d86ad, 0x68f2fb9a, 0x76bcd3d0, 0x0990222e, 0xaf654d4c, 0x592f2c03 }, + { 0x7bd3a2d4, 0x79376fe0, 0x6cfd5f8c, 0x35f9db39, 0x3c49abb5, 0x822f0d7d, 0xb4b39340, 0x6ac0faaa }, + { 0x1e9744ab, 0x054e047c, 0xb6a7b851, 0x2ee0cd9d, 0x78d17a51, 0x4cd4430f, 0x237fd847, 0x849fcbe5 }, + { 0xb0c891ca, 0x6c8d5bfb, 0x3b0a93ed, 0xc7af0a71, 0xff2465f3, 0xef2a126c, 0x5ee2020c, 0x3b173750 }, + { 0x0dbac1e9, 0x450b4dac, 0xe08aeed9, 0x38991ff5, 0x6a552d43, 0x54b62def, 0x7c02b4e6, 0x29f22f0f }, + { 0x015b4120, 0x3bc1586a, 0x5691b289, 0x67477921, 0xd653ee32, 0x772b4273, 0xec197c81, 0x3e129524 }, + { 0xc5c00da5, 0x0df9326c, 0x433929c3, 0x6f5890a2, 0x7290f5a8, 0xd81844a2, 0xf27efcfd, 0x126566c6 } + }, { + { 0x2cbcb9ea, 0x8b5f07ea, 0xbe48fbe5, 0x0f7db757, 0xb222db10, 0xdba776d4, 0x18a96d40, 0x971f3692 }, + { 0xed073116, 0x7357cabf, 0x067b5d3e, 0xfe3cb788, 0x58aa92ae, 0x5b798361, 0x32097de0, 0xd06717c5 }, + { 0x92ee08ed, 0x18760464, 0x754f8f42, 0xda1dd7ff, 0x19342cb1, 0x5eb6b2a5, 0x81b07d3c, 0xaea3de22 }, + { 0x3571beb9, 0x2276e664, 0xacc949bd, 0xce5ca268, 0xc56df87b, 0x82bf433f, 0x669be89b, 0x4fa11773 }, + { 0x1873eacd, 0xb73a9a5b, 0x592c8e91, 0x2654636e, 0xbc6d1a47, 0x7afdcb9d, 0xea020c0e, 0x1efec521 }, + { 0xcef4c7bd, 0x67df729d, 0x0addb2f3, 0xa3c0ec1a, 0xc97dbc57, 0x40b6eb21, 0x47507cf5, 0x1018a2bf }, + { 0x9a4e2559, 0x7bbdf790, 0xe67e693c, 0xd9dece5d, 0xcbf89212, 0x05182c20, 0x44d35392, 0x0831858d } + }, { + { 0x92bf7ad8, 0xac7d3871, 0x79f9506f, 0x5a520b2d, 0x6d684da3, 0x751eaf8c, 0x1f3e81b0, 0x6049f480 }, + { 0x1c05bc11, 0xc9773c3b, 0x5985a938, 0x8ff45a03, 0x6818d96f, 0xf9ca15b7, 0x1a2cac49, 0x6f48e280 }, + { 0x738b797a, 0x573546d5, 0x9ea830f5, 0x3d4a8258, 0x08c9d14e, 0x588b5783, 0xf0aa4a89, 0x206efda7 }, + { 0x9055cb57, 0xdeca9dc8, 0xb851d1c3, 0x973a947f, 0x2b95673d, 0x8ef5fc5a, 0x65a6210e, 0x46fceb43 }, + { 0x03c863a4, 0x49050543, 0x9f6b31b9, 0xa18686e8, 0xe892f2da, 0x4fe3a2e5, 0x2d42a25a, 0xb05e7117 }, + { 0x49bfd4dc, 0xb9e76ab8, 0x2ccaf142, 0xf6e658ed, 0xd8da5bc3, 0x43c590cc, 0x23ee8dc6, 0x847deefa }, + { 0xaf873d1d, 0xeec773e6, 0x367aa3ff, 0x631c11b8, 0x1f0c4164, 0xb1ea88ef, 0x22667a9c, 0x4f3058af } + }, { + { 0x962f57ea, 0x81e5fc32, 0x0081c8c4, 0xadc7fee7, 0xba552a5f, 0x0474668e, 0x15a30945, 0xe96d0d57 }, + { 0x42ba07b4, 0x01b6ba42, 0xe9ce2618, 0x8974c5ae, 0x703f4b0b, 0xfae91532, 0xc0d2f5d4, 0x5b2597ef }, + { 0xadce03e1, 0xfaf36703, 0x382ab5c1, 0xf1840c65, 0x28f76134, 0xc6a72567, 0xbad3e27a, 0x35b24ed7 }, + { 0x5ff63ee3, 0xdbf4abd6, 0x340396a7, 0x8da6e184, 0x84f18556, 0x83d2ef1f, 0xd6318694, 0x01e66e20 }, + { 0x657c0e18, 0xe8e96d61, 0xfb5ae696, 0x31e9dcfa, 0xb3551eea, 0x4ed0254d, 0xd5a176e5, 0x21f6af2f }, + { 0x55d573ce, 0x10605518, 0xde2ec80e, 0x98aba416, 0x37642d6e, 0x71cd5677, 0x71d8a8c8, 0x9e026d46 }, + { 0xe78e54d1, 0xd5f17dee, 0xe021ef02, 0x1b40b24a, 0x2f11ba75, 0x335fa32b, 0x2e8fd8f4, 0x237f8ba0 } + }, { + { 0xed0d1650, 0xea2bae2a, 0x634c7bea, 0x6a3f1453, 0x7a9b247e, 0xf9bdd947, 0x0fcba804, 0x9b0d0cd6 }, + { 0x9b71b442, 0xb740ef03, 0xcaa45dd8, 0x333b16d5, 0x6940cee0, 0x0a2efb3e, 0xa1ebb1a7, 0x465f93cd }, + { 0x0253e6b5, 0xca44e155, 0xf89d1f3f, 0x1bf46b6d, 0x8266ad12, 0xa45e0b16, 0xb9488761, 0x8ba01181 }, + { 0xdc95381d, 0xd26cc252, 0x0a2b707f, 0xc0e0cb57, 0x9ee4eeae, 0x0a9df423, 0x400b1fee, 0x650a95e9 }, + { 0x61cb3f98, 0x08ee7eed, 0x71cd9edf, 0x5d924366, 0xed6915c5, 0xf6ed6c49, 0xd18c26b8, 0xae28feec }, + { 0xdd899b79, 0x9eee5680, 0xc1183ea5, 0x9646b52a, 0x8c11f519, 0x3decaa47, 0x6071c964, 0xc27ded8f }, + { 0xe4a5b241, 0x851bca37, 0xc6aa5428, 0x79831ce3, 0xd22215cd, 0x38d58f7a, 0x08df4817, 0x85fe05b3 } + }, { + { 0x11f97d16, 0xb9d32fd7, 0xf4c7861e, 0x39b3be77, 0x3d9195dc, 0xcdca9c19, 0x6949650f, 0x3f39d9fc }, + { 0xaffd5f80, 0x9ea527f9, 0x059e0467, 0xe8e176f1, 0xccccff47, 0xcb3045f7, 0x45dd9987, 0x92b3eef5 }, + { 0x56d610d4, 0x25a5e55b, 0x7dd274f1, 0x5206ac55, 0xa896fa4b, 0xeb1ce606, 0x6b62ca4f, 0x50e0f6c9 }, + { 0x22d55988, 0xaf4dac6a, 0x39fbf645, 0x68edce96, 0xd85ad56c, 0xcae1ba73, 0x01860e94, 0x678203f3 }, + { 0x4dea4902, 0x3f8c687d, 0x93c3baec, 0x387b7671, 0xd5cb1818, 0xaa45d1e6, 0x5a652f0f, 0x851a2d41 }, + { 0xce2e1a8d, 0x40213d61, 0xe1cb5c2e, 0xee2dfdb7, 0x1b4aa378, 0xc0daf98b, 0x797c4053, 0xbef4a202 }, + { 0xfcc877be, 0x02e4b377, 0xf2cf8150, 0xe72206d5, 0x9717a04e, 0xbc7369f3, 0x37d99625, 0xbbb3af4d } + }, { + { 0x7b817df7, 0x8540e578, 0x37a88677, 0x9ac5c9a9, 0x9a2cea74, 0x1077a7d5, 0xf74d5738, 0xcd49e631 }, + { 0xc887a1d4, 0xebcfc759, 0x840c3b94, 0x9d7c5067, 0xbc8d4139, 0x165dbe1d, 0xb20727aa, 0x048b6d62 }, + { 0x48291e94, 0x8af5b98e, 0x6b7a9afd, 0x45e28fd8, 0xed98dbea, 0x67aa3b1d, 0xea306382, 0x9cef4397 }, + { 0xe2577d82, 0x3e4a6a53, 0x122fb3cf, 0x34cdd88f, 0x07fac0c8, 0x688702bc, 0x6715187c, 0x870471ed }, + { 0x8f5993ac, 0x22d7aad0, 0x58de6d25, 0x76fc4098, 0x18d9d372, 0x945b97e8, 0x3e3140a9, 0x5034761e }, + { 0xd8a83ad4, 0x3f81fe2c, 0x6e2ee5c0, 0x6f18c51b, 0xdec7eb75, 0x433a442d, 0x2e97537c, 0x5c97338e }, + { 0xa3401399, 0x4099382d, 0xa315b75c, 0xa1af232a, 0xc06804b4, 0xa5a1ecf5, 0xb7502e4c, 0x4af05d96 } + }, { + { 0xa4292161, 0x64de8a51, 0x8b32577a, 0xb69defe7, 0xb3f258fb, 0x3b507f07, 0x3d34d323, 0xb72be5a9 }, + { 0x7d2b9c9c, 0x07b0618a, 0x92b9a7b4, 0xb8073cca, 0x622df393, 0x04ca0a0d, 0x5cb29f45, 0x65a800c4 }, + { 0xafd63ad4, 0xf3b45556, 0x3e5f9f0c, 0x596d7f10, 0x1e445890, 0xdc732db8, 0xa1457516, 0x2c11685c }, + { 0x106d1adb, 0xbfd505ac, 0xd17d09c8, 0xcff3de70, 0x5ed21587, 0x26601bc7, 0x266c8357, 0x38e427c2 }, + { 0xab583ac8, 0x18e6a293, 0x2a4b1251, 0x683932d2, 0x1d191544, 0x25ee6dbe, 0x686c3985, 0xdf85767a }, + { 0x07d9277b, 0xf431323e, 0x23e27bed, 0xd57330bd, 0xd3a5a46a, 0xc40134a0, 0xb51a1916, 0x920d225f }, + { 0xff6a045f, 0x0219c728, 0xd19c51ca, 0x90d6f91e, 0x008df777, 0xdcbb0ca5, 0x351b7ccd, 0xa17de1be } + }, { + { 0x61c98b18, 0x4ff26086, 0x9f69f5de, 0xf9ad9780, 0xb3c863df, 0x16b6b073, 0xa1261d6a, 0x61ea337c }, + { 0xfa3d55c1, 0x6deb841e, 0xd18b3890, 0x6eb95aef, 0x46758d3f, 0x95c054b0, 0x169c1ea1, 0x8c9f7b67 }, + { 0xca4c006e, 0xb8f74551, 0x232cde8b, 0x45e3386c, 0xa53e5941, 0xf1a18ad1, 0x3d65cbd3, 0x71aa1845 }, + { 0x7a5a38c1, 0xc71ea8f4, 0x2eb7c43d, 0x8231f36f, 0x30d09ec6, 0x108d8080, 0xc1168829, 0x7fe7c39b }, + { 0xff16554e, 0x3ab8ca07, 0xbbe6872f, 0x569c05ae, 0x7d82e670, 0x73a3e51d, 0xb46e72e4, 0x5f4bde67 }, + { 0x6ddaa6b7, 0xddf2adba, 0x55094566, 0x12f25856, 0xbc6068b8, 0x0706c7d2, 0x18190f2c, 0x46248f58 }, + { 0x1c720640, 0x821f0744, 0xf950970f, 0x2b9d5a7d, 0xce4f69ae, 0x99594043, 0xc095e4c7, 0xfabaf4e9 } + }, { + { 0x2ca85619, 0x35b831f3, 0x359db80d, 0x1d390bc3, 0x787df3c4, 0x0083aa53, 0x4ea26f41, 0xdeafe94c }, + { 0x34d01dc5, 0x0818d2c1, 0xd62430a2, 0x17369f1f, 0x433db5dd, 0x017c1bc3, 0x4acd2660, 0x9aa96604 }, + { 0x8692005a, 0x639dc9c2, 0x6183c4c2, 0xc44f9407, 0xeacb0c33, 0x5008b57f, 0xa399ae39, 0xc4a9d096 }, + { 0xce140b42, 0xcb62b5f8, 0xc49ab307, 0x09f39be2, 0xea8b2591, 0xd9dffaf0, 0x66a9fa58, 0xac6758fc }, + { 0xddc748c5, 0xd5a8a65d, 0x0ffb9a2f, 0x4181a5b6, 0x78754b79, 0xcef03b2f, 0x65868ec7, 0x9f5b6485 }, + { 0x090377f1, 0xefe4e64d, 0x8f758f90, 0xc62973bd, 0xaa48dc9f, 0x072c9b20, 0xc13b0d8e, 0x89f4518e }, + { 0xc6406788, 0x020f2cf5, 0xa59b4d0e, 0x938a2230, 0x49f79f50, 0x90f2e0c8, 0xcfb38e27, 0x53887c8e } + }, { + { 0x0e8fedc6, 0x6f70a211, 0xde1fa17e, 0x600ab256, 0xf3f84ddd, 0xc2ec2357, 0x3f079f76, 0x3ea773ec }, + { 0xc4d854bf, 0xf2dbe1aa, 0x6a339ef7, 0xbc001595, 0xe2187ebc, 0xb6c3d803, 0xaa303fb5, 0xfc6aee1c }, + { 0x7cc4a485, 0x32966e96, 0x1c24d146, 0xb8c2fbfe, 0x1df0e50f, 0x5f25ae39, 0x17947bb1, 0xe769787e }, + { 0xa0a47d6f, 0x5ba5e912, 0x351f2987, 0xdf007baa, 0x179bdfd8, 0xe2d10433, 0xc46bf7f2, 0x8f1661cd }, + { 0x1081d07f, 0xec89c7ce, 0xff7bd73c, 0x443ca90e, 0x62ca731f, 0x8cdade11, 0x3c2f428a, 0xc8f6a3b5 }, + { 0x29e1b992, 0x36cb06cf, 0x09a6d481, 0x1a5f36ee, 0xa9be4195, 0xbc9d79ef, 0xfb5d9cc5, 0xd5f1a502 }, + { 0x4efb9d6e, 0x6cd3c3d1, 0xd7a571ad, 0x094fa1cd, 0x215f0d89, 0x7ee33093, 0x211569ce, 0xe0978f7f } + }, { + { 0xf2e250a6, 0x644dc9c8, 0x03024346, 0xb4bc6847, 0xcc69fe0e, 0x02e802b0, 0x596a3d96, 0xca7ea4f8 }, + { 0x78431789, 0x2ac18055, 0x8f33a60f, 0x7e4d6ee7, 0x5f4381de, 0xcac16f1a, 0x4b181312, 0xdd2f7c1a }, + { 0xc17902fe, 0x8bb54080, 0xb2d8be3c, 0x5d756d91, 0xf5a477f9, 0xc395f213, 0x7c041dfb, 0x46f78589 }, + { 0xf1b0a53b, 0xe10e5ff8, 0x73062e01, 0x25f6dc31, 0x54d816cb, 0x5e6f7a4c, 0xa5de14bd, 0xb8b75786 }, + { 0xdac58db9, 0x7b14d7d0, 0xd9484ccb, 0x6714640d, 0xb600f2e6, 0xcc79c746, 0x1b6cad87, 0x7dcf33d8 }, + { 0x017b8d5e, 0x70eae2d3, 0x38f82a36, 0xb5a8077b, 0x5e010181, 0x3e128a3b, 0x75064a21, 0xd94d14b8 }, + { 0x7a0b5ab0, 0xee95230f, 0xe43198ef, 0x1812e8c0, 0xa4e9aff4, 0xaddbbfb5, 0x6974ffd0, 0xdf0b3e39 } + }, { + { 0x73eb8444, 0xd1b0cbd7, 0x84e02b0f, 0xbb790db4, 0x551b5168, 0xefe3bab0, 0x560e32eb, 0x7d5331f5 }, + { 0x5ec864ed, 0x405e7816, 0x00623c17, 0x7372c617, 0x57ff0c2c, 0xaa8e0e25, 0x8ba27e38, 0x15a7b3ed }, + { 0x6b5f8a03, 0x1f8147db, 0x0c9fc9ed, 0x0142bb78, 0xa8ec0704, 0x09524387, 0xdd504764, 0x25df06c0 }, + { 0xf3454093, 0x1af74eed, 0xc710995d, 0x8d6db26b, 0x097fc18c, 0x0130721a, 0x7b01c796, 0x2024686e }, + { 0x2f5058e1, 0x9c610371, 0x82bd715b, 0x364bc316, 0x7aa700b3, 0xf83145be, 0x279dace7, 0x82e8d269 }, + { 0xf968b736, 0x16095a7a, 0x57135ac0, 0x8baf2414, 0x584014ec, 0x76700cd8, 0x1d2d52f9, 0xcbfb7a46 }, + { 0x4f476f6c, 0x7aa51699, 0x70bd6f1a, 0x2c9a4124, 0x69af47de, 0xbb6b03f8, 0xe1f829cf, 0x7ce1137c } + }, { + { 0x529cb309, 0xc8aea28e, 0xd098438a, 0x2ae46f3b, 0x9412c6e4, 0x070c8c6b, 0x86e3d599, 0x6f637d52 }, + { 0x83bc496a, 0x5fee475a, 0x3c57d57c, 0x3d73802b, 0x43487150, 0x54628ac1, 0x2b7caab8, 0xc076d88c }, + { 0x8ac9ecaa, 0xe302536d, 0x01dcab9b, 0xd402ed11, 0xd2cda0e5, 0x38d52eb3, 0x7bc46a8d, 0x20f2b18d }, + { 0x3177ead6, 0x2c3e38b1, 0xc1fedd11, 0x1d61cf39, 0xa270a03d, 0x97927029, 0x01949d10, 0xca432255 }, + { 0xa752f732, 0x4e8a93d2, 0xa550cb22, 0xb76bbf17, 0x038cef04, 0xcf7425ed, 0x6ae3268f, 0x3c6cf564 }, + { 0xe3b0ec46, 0x70d0fe76, 0x59e8d363, 0xeab1cd4b, 0x9b30c6bf, 0x848d7004, 0x45beb655, 0x2b92f24b }, + { 0xd56d857a, 0x68b415c6, 0x88aa3c8f, 0xe7974251, 0xb186344c, 0x6b4e3a32, 0x154a94fa, 0xff9956e9 } + }, { + { 0x4757c9b1, 0x525ad554, 0xca91d9ce, 0x18c6c4ef, 0x90284f11, 0xe863f01b, 0x9a6e1466, 0x933653d8 }, + { 0x82eeecd5, 0x0338835b, 0xa5e276ac, 0x07fee98f, 0xa4e36ae8, 0x9d4e0917, 0xb5515e01, 0x9cb0f560 }, + { 0xfd75e016, 0xfc2509dc, 0x43884277, 0x173b4524, 0x666341b9, 0x14986d6c, 0x9da3cf7e, 0x3ff34c72 }, + { 0x1df8ed20, 0x197d99c7, 0x80d6f0a0, 0x29e40b59, 0x0bb39c17, 0x5733d550, 0xb68f6e8b, 0x4e407471 }, + { 0x74cf47dc, 0x123386ec, 0x8832fd00, 0xa6da4f17, 0x6be7b728, 0xb8ccc057, 0xa00880d7, 0x47ae5fc6 }, + { 0x773f18a1, 0x739953a2, 0xcff6d9a8, 0x58da9a84, 0x68d99953, 0xcef069a6, 0x26a8617c, 0x762c6ae0 }, + { 0x6a1057ba, 0xa6faae33, 0xe1c7df27, 0x8d1592e7, 0xb080e22b, 0x867c0f0a, 0x50d5f05f, 0x5345865f } + }, { + { 0x979b7cbb, 0x52d0bbf0, 0x174a5d8e, 0xe95c9c90, 0x23e8dea1, 0xa1a797db, 0x34f765a4, 0xbde08c6e }, + { 0xac591286, 0x981475ad, 0x9b6c3e57, 0xca87b92e, 0xd8a63a98, 0x9ca3f9ab, 0x5701c152, 0x17caa9d0 }, + { 0x9260eb87, 0xba139238, 0xc41ff15f, 0xb6a963fe, 0xa12432e7, 0x0cd72d7b, 0x545d1f7a, 0xf06027f7 }, + { 0xd08ad069, 0xb724815f, 0xd40637a9, 0x93b37f1d, 0xf68d49fe, 0x6d27ebea, 0x3d293972, 0x988cd20e }, + { 0x9a48bf01, 0x6f004e75, 0xaf950a9f, 0x763ce18b, 0x30e5459a, 0xded520fb, 0x60854a98, 0xf92136e0 }, + { 0xabd4a523, 0x21cd10fd, 0x4984edaf, 0x7b52b56a, 0x9e878a51, 0x92cc4dfa, 0xaed4a5e0, 0x01b56dcc }, + { 0x20adbaea, 0x867dba2a, 0xff3f992f, 0xec7b3339, 0x3129e416, 0x1e956b88, 0xc8fab6b0, 0xfbff47ae } + }, { + { 0x3a65aa61, 0xd2c7a476, 0xc4e5be20, 0xbcaaf45c, 0x5c64c66a, 0x608f56f6, 0x34cdd4bc, 0xcb8226c6 }, + { 0x3626a049, 0x26bab677, 0xcfc23c44, 0xd0fa390c, 0x27ecf606, 0x65a43120, 0x57db6f38, 0x8d9b2bda }, + { 0x8b7bb63c, 0x9bb0515a, 0xc9ac3e76, 0x2b0f69f2, 0xd51117ad, 0xb239c124, 0xc62a5122, 0x2841f4fb }, + { 0x44cc9ec0, 0xd14489ef, 0xc67359c8, 0xb711a35f, 0x1d35fdb4, 0xfda767fc, 0xa568fa7f, 0xde40be22 }, + { 0x121c113a, 0x5de996ca, 0x74125b5f, 0x2f14fbf5, 0x748a2f09, 0x4168c096, 0x0a174256, 0xbed59fcb }, + { 0xd92c10a4, 0xb7ba89b8, 0x15266226, 0x9df26909, 0x5a7db5fd, 0xf9283633, 0x4b3b1a2b, 0x761c86d2 }, + { 0xfc576cf6, 0xf4bc912a, 0x48efe0f9, 0x79700f51, 0x2a67c504, 0xb317b87c, 0x8a78a015, 0x5b19bd6a } + }, { + { 0x9ce6fd52, 0xae988a65, 0xd239a70a, 0xd004bee0, 0x4ea5ffe9, 0xad1ecc35, 0xa2185261, 0xb4d0fde1 }, + { 0x89dab155, 0x4d4133d0, 0x4f5c5737, 0xb383d021, 0x52b3bbc4, 0x6a98fe0d, 0x2e9fd34d, 0x89405235 }, + { 0x795dae31, 0xb7bd5e23, 0xcbe89d94, 0xa3a740d7, 0xd4016020, 0xb3d74d8c, 0x0af08d29, 0xf6c5b76d }, + { 0x64113dfb, 0xad4ce42a, 0x504c363f, 0x811530d1, 0x739d6cfb, 0x10433b5e, 0x6786fd93, 0xb2af4a85 }, + { 0x58516d01, 0xba449a0c, 0xaf379ec5, 0xc0d26a3e, 0x08a58d86, 0xb11a0670, 0xe6c2cc1e, 0x022a6c16 }, + { 0x903fe291, 0xef96473d, 0xeed4251e, 0xb47da874, 0xc0164aca, 0x0df05201, 0xe8ccc6d6, 0x3dbdd5ba }, + { 0x7daf34e8, 0xa81a914c, 0x87ccc1ae, 0x7d69446d, 0x7b26ca90, 0xbfc7fdf9, 0x9b79c4e8, 0xcd690626 } + }, { + { 0xbca2ce97, 0x9b768b00, 0x9e16c4a2, 0xbe369915, 0x33623ac2, 0x87d332dc, 0xf4cbf437, 0xc696b087 }, + { 0xb8b56e67, 0x60e96d84, 0xd737e72b, 0x617b72f8, 0xde1bbd44, 0x215077f0, 0x660d9b1e, 0xe1d46f38 }, + { 0x13ecfb64, 0x89381f89, 0xef8bf735, 0x3c1974b3, 0x59cbf321, 0x1274909c, 0x4d30a822, 0x5a284c16 }, + { 0x773c79fe, 0x345c0f6a, 0x1d7025ad, 0x09b49300, 0x9a4c9d84, 0x7998e71d, 0xfc4fcaa4, 0x14ab640e }, + { 0xa6582ab7, 0x924ce8b9, 0x15d99e33, 0xf1670d4b, 0xde7a8209, 0x3c63c030, 0x9597ec1e, 0x9381e27c }, + { 0xe0485717, 0x102c7659, 0xc5056bf6, 0x70f64f6a, 0xa57c9793, 0x59aa7c61, 0x7eb3322e, 0xab2c367e }, + { 0x39147b0d, 0x047d17af, 0xbb554ea8, 0x18259d17, 0x413a232b, 0xda2d6aa3, 0xbb280068, 0xf431d932 } + }, { + { 0xa5e23d43, 0x5433f6ec, 0xa243e230, 0x202a9049, 0xeca5c2b7, 0x5f3a244f, 0x54f555b7, 0x5abf558e }, + { 0x726d36d7, 0xbaa745ff, 0xc0995cbc, 0xe155fd2f, 0x908477b0, 0x3bfdafc3, 0x627e2400, 0x9b54d5ae }, + { 0x54943314, 0x6cd13b0c, 0xf7017cb0, 0xf354f7f6, 0x913a712f, 0x32396464, 0x7f5c8b77, 0xda9aa1a6 }, + { 0x57b1488e, 0xfd85c443, 0x6c760ad5, 0xec30418d, 0xdb2df81f, 0x4fe380b9, 0xfef3c46e, 0x546ed177 }, + { 0xec5bf376, 0x3c6ead59, 0x06df80e6, 0x9b4b63b2, 0xea891560, 0x96d61ec4, 0xec69c54d, 0x2a7094e3 }, + { 0xa5034915, 0xfddde2e7, 0xc2a96fe0, 0x7e514b5e, 0xcc097a6e, 0x8f87beb4, 0x2d2098da, 0x492e1023 }, + { 0x1f64f72e, 0x29a4940f, 0x28bb3d9b, 0x176986dd, 0xccf75334, 0xdb8baaec, 0xc2eac5cc, 0xdc1a63c1 } + }, { + { 0x8f2794ef, 0x67575956, 0x1df0226b, 0x1ac6f8d8, 0x9b783a25, 0x9afe2930, 0x3b57d6ba, 0x426e6e12 }, + { 0x9b586e94, 0x1fc66975, 0x3d745205, 0xac997cdf, 0x2b694840, 0xd61b8df9, 0xfe0d78f5, 0x138d90b5 }, + { 0x90c898ff, 0x5e593efc, 0x436815fb, 0x32a7b5dc, 0xdb5b7d3d, 0x86f4e320, 0x4e0a555c, 0xe8c07c34 }, + { 0x8238df97, 0x980ca2c9, 0x0c856467, 0xaf327325, 0x485f8c16, 0xdc401567, 0xf863daf6, 0xd760430f }, + { 0x6279f57f, 0xbdf707af, 0x166d212c, 0xb92b9bb4, 0x8c74bd79, 0x22154973, 0xc470ce5c, 0xad8317d1 }, + { 0x7740154c, 0x194543f0, 0x59f7335a, 0x98410013, 0x52012f57, 0x1716897b, 0xf74d6dc4, 0x920c3d1a }, + { 0xd141f302, 0xbc892c49, 0x05d1784d, 0x45eb8135, 0xa3e3f86a, 0x5a48f596, 0xcf7fa50d, 0xfd9d90e8 } + }, { + { 0x83a24eeb, 0x8a47b928, 0x3ba8e0a0, 0x9fdba245, 0xd8599e21, 0x907c9c19, 0x396bc65c, 0x1d1e0efe }, + { 0x37555f5d, 0x52d01015, 0xc65384f4, 0xa57da19f, 0xd5306533, 0xd7b40e56, 0x72ad0f47, 0x7c463cec }, + { 0x6f4e44e9, 0x310385e9, 0x17bd47d1, 0x3e06f1e2, 0xa3c53f42, 0xe8c5ffce, 0xc0915716, 0xe703ea48 }, + { 0xc8e9d3e8, 0x1792eb84, 0xf8738a9d, 0x5083d677, 0xa87b30ee, 0x65206897, 0x96c4ba90, 0xf7367023 }, + { 0x062845ea, 0x182a3f5f, 0x4700f73a, 0x1aee7fb8, 0x4186ab9b, 0x942b1004, 0xfe7e50e5, 0x49009e1f }, + { 0xfc0edb54, 0xb83b9629, 0x065a4e14, 0x8404f2e0, 0xfe17335c, 0xe3be3e9e, 0x99b97830, 0xa65573bb }, + { 0x01c71188, 0xeb92c6e8, 0x92080971, 0xa067cbc8, 0x11515ae3, 0xf27a2a4b, 0x0e596ec5, 0x74f3a154 } + }, { + { 0x023dc0d3, 0x6c525ee7, 0x2366e438, 0x6288d6e8, 0xb6db7004, 0x86c55b06, 0x87be2921, 0xa020e924 }, + { 0x1b75b092, 0x801cce95, 0x6239b657, 0xfbe5ca56, 0xd2170dd4, 0x1044cc30, 0xae853426, 0x15cd4efe }, + { 0xdac66376, 0xda15eda2, 0x0006896f, 0x676dcd6f, 0xc5da044e, 0xa06ba4f9, 0xc386d189, 0x9bf6cb3d }, + { 0x74baef5c, 0x00483f33, 0xa0af1221, 0x023ad520, 0x926f98ce, 0x86ccc136, 0x97594487, 0xe16d04a0 }, + { 0xc5e45462, 0xafa2ed28, 0x62dc0741, 0xf6674ab3, 0x284d77ba, 0x63df1d80, 0x0cf56abe, 0x09c095b0 }, + { 0x1365da70, 0x47e9a1bb, 0x75416e08, 0x6cdba8c8, 0x57d96832, 0xd8dc4e82, 0xc8cba9b3, 0x9807f9f0 }, + { 0x57b922c9, 0x5ba15559, 0x8ca5ead3, 0x048d1837, 0x661f403d, 0xc3838fff, 0xa6b13fdf, 0x30a36976 } + }, { + { 0x6f343137, 0xc71f6cb6, 0x199ef59c, 0xa712741d, 0x9524f6d7, 0x8d1555e6, 0x8c9f53ff, 0x276d1f2f }, + { 0xa7f1e394, 0x5e521804, 0x563610c7, 0x7c024762, 0x41a42037, 0xaacc31a9, 0xd4649e65, 0x956ae82f }, + { 0xde2b0553, 0xd301a8b2, 0x8910a586, 0x07b70f75, 0x9ea074d8, 0x2ac99ebf, 0x3500a973, 0x70061496 }, + { 0xbdf31fe7, 0x1dfc3c82, 0x38ff32b8, 0xa7b9cc7b, 0xa04abd8e, 0xf3adb0ff, 0x9e1dd522, 0xd892d61d }, + { 0xd212402e, 0xeca19b28, 0xdc57b6fe, 0xf38a9c79, 0xb5e8cda0, 0xf6345667, 0x597a1b97, 0xc1c3a56e }, + { 0x824385d8, 0x22b0212a, 0x9899bc5a, 0x6ed1c299, 0x918d2a02, 0x9a289373, 0x13aaaf90, 0x0968ff32 }, + { 0x5a9f7e49, 0x08d06a6b, 0xffd8665d, 0xb0d5eb0e, 0xd1163dcb, 0x78c81372, 0x8f015345, 0x8e24ff90 } + }, { + { 0xd825b02a, 0xa1c1a9a6, 0x2785f074, 0x6ee72c66, 0xf7a49f4c, 0x022916fb, 0x354c0c2d, 0xc1924d55 }, + { 0x82e9ff41, 0x113e9821, 0x4cf83df8, 0x6d611dce, 0x8fd78367, 0x553e22dc, 0x5ba302b4, 0xe8f78af5 }, + { 0xefb42468, 0x3e234cbb, 0x981eecfc, 0x71bdfa61, 0xb36943d7, 0x01f43387, 0x60ff5cdc, 0x352bc3b6 }, + { 0x66274b0b, 0x92030f39, 0x2386916e, 0x4670eff3, 0xe8fc5588, 0x5bcad593, 0xa20ecf35, 0x08a876de }, + { 0xb55b797a, 0xad4fcf1a, 0x4b0e291a, 0xb96c1313, 0x9c835c7c, 0x844765d9, 0x941e5f83, 0x0e183698 }, + { 0x4afdf51e, 0xae43348f, 0xaaa25912, 0xfa6d9e00, 0x6672c7da, 0x4964c1b6, 0xf2204e3c, 0x6c658967 }, + { 0xd4cdf1cd, 0xe3bea464, 0xd8796a72, 0x2e8d783d, 0x220e00ba, 0x43fea0bd, 0x2b779464, 0x525705f0 } + }, { + { 0xaf5b8804, 0xb9a2d2fa, 0xba9e2f01, 0x4a17e91d, 0xf1f74dbd, 0xfc44f3ee, 0x9c3c3657, 0x8501c1df }, + { 0xb27ec27f, 0x542c2b7f, 0xe187c5f6, 0xed95129b, 0x9b003bfc, 0x83fcb74d, 0x1a31262f, 0x11d2ba32 }, + { 0x55eec6b2, 0x44db580d, 0x28d35e79, 0x51ffd002, 0xd22b8b40, 0x736f34fb, 0x625996ee, 0xc00a1771 }, + { 0x28e1ecaf, 0x6e85a928, 0x9a8af450, 0x66215ac7, 0x5611494c, 0xd4d3d6b9, 0x0c50091d, 0x1569724c }, + { 0x0c6ceb1e, 0xff59b251, 0x64826d6f, 0x673b32c3, 0x4f570efa, 0x91793dab, 0x924d6d11, 0xbb83d65b }, + { 0xa92cb756, 0x14277b65, 0xb50f3296, 0x205a1431, 0x0d9d90ce, 0x11cfaeb9, 0x94b3273a, 0x1cc9bae7 }, + { 0xdec67f79, 0x2f8a8c5a, 0x9d1a5120, 0xf4c99b33, 0x396ac1ba, 0x766f0d02, 0x4ec810a0, 0xfe08aca1 } + }, { + { 0x0131b134, 0x15796ccb, 0xfc2e0ea2, 0x56f02b8c, 0x83ac831f, 0xa1ddef8e, 0xe7005095, 0x337b4e53 }, + { 0x45543891, 0xaa518b81, 0x1536899a, 0xe34f23cc, 0x108fe8ac, 0x11e67a04, 0xb324c31c, 0xceba6fc5 }, + { 0x48231dcd, 0xcb30908b, 0xb87d5cfc, 0x3393a816, 0xb95bc198, 0x43a21173, 0x79b091dd, 0xc0f861d1 }, + { 0x4046e619, 0xd009e0fe, 0x71348ebc, 0x91852d76, 0xae24c807, 0xb5114a2a, 0xea3ec5a4, 0xf3526498 }, + { 0x7a56bf44, 0x9ae8d236, 0x23853b91, 0x35bf10b7, 0x8144d3fd, 0xcf5f5539, 0x6bf4df17, 0x7fb436ff }, + { 0x6e05ac83, 0x6f758fb8, 0x19a7a888, 0x31074e59, 0x85716904, 0x1806aabc, 0x0a537aed, 0x44e55275 }, + { 0x05145291, 0xf0ceb958, 0x0206e3e6, 0x5fbf32d2, 0x1af252aa, 0x098a0fbd, 0x6e6f8300, 0x4a2a29e6 } + }, { + { 0x612be6a8, 0xe9aea7ea, 0xef3ff8fd, 0xa990e3d9, 0xf8415655, 0x4eab193c, 0x578ad9a0, 0x459dd7b9 }, + { 0x9cdc742b, 0x219812ec, 0x0052acf9, 0x725dae4a, 0xf1071874, 0xe15d87dc, 0x26a5366d, 0x047861b1 }, + { 0x33944b57, 0x4972efdd, 0xd826fce6, 0x0819711c, 0xe16670f8, 0xf380fe07, 0x355f7a03, 0x9107bb25 }, + { 0xa43b8097, 0x6c74f35a, 0x2e863685, 0xbad4f784, 0x9da535e8, 0xb92adf2b, 0xb869a73a, 0xb087d580 }, + { 0x7517802e, 0xafb74a90, 0x599c6696, 0xb38d060a, 0xf373d7e6, 0x966167dd, 0xcf3253fa, 0x6f99c5fd }, + { 0x1e46b7d7, 0x7eff0e55, 0xed683a89, 0xc71c9917, 0x48b3830f, 0xf0c79c1a, 0x7a8fa8b1, 0x218955ee }, + { 0x48aae412, 0x691b9818, 0x874fcb5c, 0x995a04fa, 0xb76abb4a, 0x5c309126, 0x69a6ccb6, 0x368a1ced } + }, { + { 0x408cb62c, 0x3b70922a, 0x7f264aac, 0x5c0df94d, 0x17969dd9, 0x0d88f627, 0x7e248f32, 0x95a4a489 }, + { 0x10e7ac8b, 0xaaa31b4f, 0xf2ff5fbc, 0x5b6ac8aa, 0x24e3080f, 0x28e9d8c4, 0xb148a773, 0xfa090c9d }, + { 0x4408a0c1, 0x7b759542, 0xee0535f8, 0x03692e42, 0xe04077b9, 0x3aa9f80c, 0x216f3ffd, 0xf8667e9a }, + { 0x6091af81, 0x26b4bade, 0x50b5a448, 0xbd257d5e, 0x96b6b6fb, 0x4d06387a, 0x859dc5db, 0x2550dd24 }, + { 0xb4083f98, 0xb1712124, 0x4ffa6bbe, 0xac4fe1fa, 0xe4ea2c22, 0x3b21ea99, 0xaa4b378f, 0xef780957 }, + { 0xfea65c32, 0x2630886b, 0x516a93c3, 0xa87b2079, 0x531884c9, 0xaa72533d, 0xa003b3f4, 0x7bb17437 }, + { 0x34032994, 0x4cef72a0, 0xc5158925, 0x638a0d1d, 0x8c037715, 0xc6be1b0b, 0x0ead0c61, 0xc9459550 } + }, { + { 0xffdf8f7e, 0xf5a20dab, 0x70cb0082, 0x4ffca11b, 0x58416505, 0xfc559602, 0x29e66eae, 0xf8ae5a5e }, + { 0x41ee1d29, 0xaaa43231, 0x2776fdee, 0x0c2dff3d, 0x612b8623, 0xebf527d7, 0x3cf0fca2, 0x47c6123b }, + { 0x06a75db6, 0x8261c1be, 0x7c591d8e, 0x47fac27c, 0x6c36484d, 0x90527c8f, 0x58c65a30, 0xa5e11279 }, + { 0xfc782a50, 0x60b8899b, 0xf9dbf259, 0x0bcc0a40, 0xa229bda1, 0x168a8855, 0xb5d87956, 0x61d6bb9d }, + { 0x7378236c, 0x865619ab, 0x8ca6923f, 0xebe429b6, 0x24ba5add, 0x39e49415, 0x124814b9, 0x7c8fd18c }, + { 0x3517965f, 0xf54f73dd, 0xcfdefd0a, 0x0c98c3a1, 0x8d36dc2a, 0xcdd00d1d, 0x3937c88d, 0x64529779 }, + { 0x464d8478, 0xbc935aa2, 0x26bd0fcc, 0xf30d7b12, 0xa31a5d33, 0x708eecbc, 0x0acb787e, 0xfc79571b } + }, { + { 0x11550d4e, 0xa4d0ccaf, 0xb896078d, 0xf01f8639, 0xfea676c7, 0x7352e8f3, 0x11ace0b3, 0xc7f937e0 }, + { 0xf264b4d3, 0x4214ae8c, 0x550cf3fa, 0x2b3c82e5, 0xe24f889a, 0xc795d879, 0x5dac9a62, 0xc7044d9b }, + { 0xd2108d16, 0x3c0ffeb2, 0x2042ef98, 0x0d9c0fa6, 0x2ab92f4a, 0xb8884755, 0x4cda4dca, 0x8fb003a1 }, + { 0x6f6a7527, 0x6e321481, 0x3f346e27, 0xa70a9d2d, 0x8ee9a6f8, 0x2790b3b7, 0xb424d205, 0x91e63115 }, + { 0x959639bf, 0xf23f1feb, 0xc1994d08, 0x30976c9d, 0x80861d2d, 0xe3ac17a6, 0x75b71833, 0x65e96015 }, + { 0xbbaef34b, 0x3244b505, 0xab6b79a1, 0x809ccbe5, 0x4e2e445c, 0x7eb74fce, 0x3aa41027, 0xab1a1c5c }, + { 0x2fea4ca5, 0x406aa1bf, 0xdaaf707e, 0xc34462ac, 0x4ccb6551, 0x961fcdf8, 0x973acb5c, 0x7c6692b1 } + }, { + { 0xddbefaca, 0xc7a81f45, 0x8bcc1241, 0xb55c925a, 0x20b696c8, 0xd7913c17, 0x78f2e0a3, 0x6c261c77 }, + { 0x3cc8f994, 0x2661bd75, 0xb10a1e3b, 0x8ba28cad, 0x48657169, 0xbbeb9d3e, 0x602a84a6, 0x4c96aa25 }, + { 0x692964ce, 0x216afb2b, 0xd18a5a66, 0xcf150236, 0x64c21fca, 0x0d5eecc1, 0x9e978005, 0xd33fd368 }, + { 0xeafb4b37, 0xe21a3766, 0xf11ab1ad, 0xc6064ae0, 0x94e270e0, 0x184088aa, 0x10d4497d, 0xde991adb }, + { 0xe0685dd4, 0x6d0de3e2, 0x7935ae7c, 0x73b9ff49, 0x81f42fcf, 0xc76a9928, 0x906fd865, 0x655dcb96 }, + { 0x59e43594, 0x70854bd2, 0x6aea3da6, 0xc20978d7, 0x2d6633a0, 0xa64f39d9, 0x6ff5782f, 0x4061fa9b }, + { 0x7306b6a1, 0xdc469610, 0xd4a5ab68, 0xa44ce836, 0xffe8b99e, 0xe18dbd67, 0x4deefdf6, 0x1dbf2916 } + }, { + { 0xbcd7b9f7, 0xaecb0569, 0x65e859ab, 0xbb1deaad, 0xef21dbd1, 0x6d0bd332, 0x915707d1, 0xe70e63e5 }, + { 0x961ffcd9, 0x1c391c9b, 0x81905c90, 0x0936283d, 0xe9dc5aa6, 0xfb3b7def, 0x56454ad4, 0x5c8bb15e }, + { 0xc03e6457, 0x16f9c3d2, 0xec96ed35, 0x60faf8f3, 0xf4514e87, 0xda3f4673, 0xd5be8d5d, 0xbb12df1b }, + { 0x12f736e8, 0x2187a39e, 0xa63feafe, 0x66bfdb1d, 0x3c468d50, 0xeae0d268, 0xacc10ee9, 0xf2718cd3 }, + { 0x659b476a, 0x10a498db, 0xa084c566, 0x15ec323b, 0x8e6de570, 0x660dc72f, 0x01814c7e, 0x93c79470 }, + { 0x087812d6, 0xd0dc9e9a, 0x0381bb07, 0x971946b2, 0x88c203a6, 0xa91dfc9a, 0x5a83a3d2, 0x96b736c6 }, + { 0xd0393e6b, 0x92e03ba4, 0xa9b367b6, 0xfb67d737, 0x00e4d2e3, 0xec1d8a37, 0x80fd078d, 0x94ebbabd } + }, { + { 0x7e29e692, 0x8b41a6d4, 0xde0b857f, 0x352e05e7, 0xd74b3544, 0x89a110e7, 0xf3a27efe, 0xf24598f5 }, + { 0xc79d4566, 0x7c582951, 0x8dd6043f, 0xd561a6b9, 0xd99ddf41, 0xd1e971db, 0xc0d536d4, 0x8ea54c01 }, + { 0x39b19219, 0xaee37d55, 0x4fcf989e, 0x23baba4f, 0x49a91d6d, 0x1a35612e, 0x3e7607dd, 0x0ba6e33e }, + { 0x5a33d17b, 0xdded811c, 0x9dd4bdc5, 0x6774c7f8, 0xbd3f291b, 0xa0009061, 0x11e43fcf, 0xdd17292d }, + { 0x8acb55a3, 0x1d66e5c4, 0xbf641c0f, 0x18c07e1b, 0x76c41aa1, 0x80aefccd, 0xff8a45fb, 0xec91341d }, + { 0xe0d8ca1e, 0xe1b5c0b6, 0x42cbb935, 0x93cabccc, 0x1db92c60, 0x251e3f97, 0x18707d3c, 0x15169cdc }, + { 0xebe45526, 0x757adc21, 0xa048e0e0, 0x00be0c92, 0x07b67816, 0x2412eb5f, 0xb7227c6a, 0xaf986aa4 } + }, { + { 0x3567e5e7, 0xedba1c4c, 0xc1ee61b3, 0xf6168ff0, 0x548ac0c6, 0x5df95013, 0x70486381, 0x0f747265 }, + { 0xde2b9737, 0xbb011054, 0xf3ee8541, 0x2b3fd083, 0xfc3a47f7, 0xd634eb57, 0x66ab37f5, 0x234f914e }, + { 0x10090602, 0xf5070df0, 0xdca526b5, 0x3dc0c2a0, 0xe76c9a3e, 0x7216cef1, 0xc8e9c887, 0xf500c617 }, + { 0xd3084a95, 0xb4f44838, 0x16ccdd29, 0x9e0b70be, 0x721e544a, 0xed3e26df, 0xc3439ab4, 0x1320c54b }, + { 0xc1075933, 0xf0b15ef9, 0x4872b3c1, 0x47b9d658, 0xc162ca79, 0x5a42a927, 0xa37688e7, 0x0b6b44c7 }, + { 0x9d604460, 0x45808dad, 0x5f880d48, 0x5c1ecb45, 0x4b097d4b, 0xc95aaba1, 0xbe7af65f, 0xfa3eda1f }, + { 0xc58306b1, 0x6753afb9, 0xb4937fce, 0x8f82b06e, 0xdf8ff4d4, 0x124c3399, 0x8fac1caa, 0x6e9ab004 } + }, { + { 0x8e3a58b3, 0x9745bf71, 0x2a0ea73c, 0xad04b1bc, 0xd8338c7d, 0x0cb4b5c5, 0x8cc70a60, 0xaec8922c }, + { 0xab22f041, 0x8747644e, 0x08e1e2d9, 0x201ad2b6, 0xfccc9550, 0xb4f599b6, 0x39400a06, 0x10ec0d9d }, + { 0x93ffda08, 0xa3c65492, 0xdb32ed20, 0x5e5044da, 0xc853b537, 0x4d0962c3, 0x3e818e62, 0x6d9ef9a4 }, + { 0xdf34b2d6, 0xb52a6261, 0x2c02d7c9, 0xc80dfe97, 0xbe920358, 0xb3b54fe0, 0x928dd474, 0x9ac6c076 }, + { 0x4f79e512, 0x11776041, 0xbd99a47d, 0xdceac08d, 0xec0accf1, 0x823ef812, 0x6ead6214, 0x9e9e456d }, + { 0xf93d4427, 0x35c065c7, 0xb0568cc4, 0x89438bd0, 0x483d9e29, 0xed66d3b2, 0x4cd1f22e, 0x5ce685de }, + { 0x70afbe9b, 0xdcee3d63, 0xef23056d, 0xab95553c, 0x7241a4d7, 0xd750aa8e, 0x2db4e162, 0x32c7020e } + }, { + { 0xb6b1b931, 0x1dbeeb55, 0x57a55d88, 0x683f65b7, 0x6b74e649, 0x9b0d0ce5, 0x857acdce, 0x09dce13f }, + { 0x8471d8eb, 0x21e20325, 0x8343904b, 0x6bb37b48, 0x574673bb, 0x5bbd2cbc, 0xb8d3f709, 0x9e1ee313 }, + { 0x0e9dc340, 0x78d53ca0, 0x35e7af7a, 0xc9ee9192, 0xced09087, 0xf514ba34, 0x0bd092c0, 0x0ab8a37d }, + { 0x474466b0, 0x3f129bff, 0xc9ded430, 0x0bd038d9, 0xaeebf28f, 0x38eedcd6, 0xa283275a, 0x1b0eb1f1 }, + { 0x9e29c456, 0x09a38f37, 0x2479b134, 0x33c7b328, 0xfe878206, 0x51343036, 0xd5072add, 0xc772a79d }, + { 0xb4af6277, 0xf237e01b, 0x570a70c3, 0x96f28e25, 0xfb7a6283, 0xf2636f78, 0x42d809b9, 0x635e94a6 }, + { 0x193c6c51, 0xe4b6373c, 0xcd568c2a, 0x6daef406, 0x788b6b4c, 0x24eb8436, 0xd37b5e3a, 0xf9af2d97 } + }, { + { 0xf0e7a919, 0x682262bc, 0x8250498f, 0x328f0e3c, 0xcf0adbaa, 0x5898dd65, 0x3e9417f7, 0xf29f140e }, + { 0xa6ef5bd9, 0x8349746c, 0x4cbf85f5, 0xa7e87dc6, 0x902aea74, 0x443891df, 0xee3c434c, 0xec095e47 }, + { 0x51cc666c, 0x7c75d10d, 0xd243b46f, 0xd8de941c, 0x61ca586a, 0x00aaa203, 0xf3ec602b, 0xa9067d07 }, + { 0x1aaec03a, 0x8db8a17e, 0x40535325, 0xaca2ef8b, 0xdbbb2199, 0x4032f003, 0x94dfc342, 0xe02f2b75 }, + { 0x8c4e3f5a, 0xa3e555f5, 0xdad1c8d1, 0xa8d51378, 0x86d4e833, 0x7dd44060, 0x1b340aad, 0x3173876b }, + { 0xe183dc08, 0xa6a7af82, 0xc24ff5ba, 0x74ccea39, 0x33907bde, 0x5027c815, 0xf1ea964a, 0x6e580a0e }, + { 0x3ebfa215, 0x5154cccc, 0x3859eaf5, 0xb616c4d1, 0x2536af1c, 0x5c801c9a, 0x7125da28, 0xaba781e4 } + }, { + { 0xb0aa611b, 0xf329813e, 0x09974675, 0xefb0648c, 0x86ad19fe, 0x18bb7a31, 0xabae10e5, 0x157db901 }, + { 0x945c8d18, 0x866b5833, 0xcec48495, 0x0637bc92, 0x3d144da6, 0xd20aa2fb, 0xcd739471, 0xc679534d }, + { 0x6914a513, 0x1e3be68e, 0x801023c4, 0xa18a0432, 0xbcb8ef1d, 0x287b8c4c, 0xb5c557b4, 0x227aafd0 }, + { 0x8134290a, 0xb43672bb, 0x3219e038, 0x3b3586be, 0xd4192484, 0x057863d5, 0x5af03283, 0xfa43a7ab }, + { 0xdd1d983d, 0x00a9ee12, 0xb87294ae, 0x788f17f7, 0x5d09a7e0, 0x203f7024, 0x9eb9516e, 0x0ad3e70e }, + { 0x61c95583, 0x0157aeeb, 0x8a560ae2, 0xbcc0e328, 0xd6b15e89, 0xf1fb72ba, 0x3d7a86bd, 0xefe07ff5 }, + { 0xae8b1ad2, 0xe8b0e341, 0x75c128e7, 0x4b855983, 0x2823f704, 0x7308179c, 0x924b47b2, 0x5bc4534d } + }, { + { 0x51ef7276, 0x1b386f50, 0x640057b8, 0xfad54d72, 0x97ffbb98, 0x152cc738, 0x758e39ac, 0xa7009aef }, + { 0xf8bf8307, 0x0e37dc8c, 0xaec3f156, 0x0995c10b, 0xaea1f4c6, 0xa3669a12, 0xeff47fdd, 0x28c58bf5 }, + { 0x2d27cb3d, 0x2e315c21, 0x16fb415f, 0xc194f707, 0xb5ad8069, 0xa54beef4, 0x4cb7fc78, 0x21546e26 }, + { 0x0cab6d99, 0xdd54447e, 0x10e0f16a, 0x2bf19811, 0x05fe702f, 0x595c5bf1, 0xaa99303c, 0x63b1a01e }, + { 0xe2eab432, 0xed5f4d99, 0x2368bbc1, 0x076a4211, 0xe77a3fcb, 0xc10f8e8d, 0x22acaca9, 0xd98d2316 }, + { 0xb30f302c, 0x553f357d, 0xe50a2533, 0x611bd13d, 0x08c4f88b, 0xfa7a9454, 0x26f24bbe, 0xcf1a9c58 }, + { 0xd9d6e2f3, 0x65329309, 0x24ab8dca, 0x5666ec08, 0x5b4c9c7a, 0xdc02919a, 0x47984f20, 0x5d10c10c } + }, { + { 0x4172dfcb, 0x48c4ee08, 0xe9ed6a57, 0x28f46959, 0xc1aa0ca5, 0x589b1201, 0x60e69889, 0xfb8be6d4 }, + { 0x0ffcbd23, 0x5302612d, 0xf5c6667b, 0xddf2ff98, 0x5cfa10f4, 0x705ff345, 0xc5d3be38, 0xc594850e }, + { 0x4e02c9ea, 0x7d78f9fc, 0x62431ae9, 0x409b735e, 0xab4ea6cf, 0x044946e3, 0x51496c16, 0x6b7f7546 }, + { 0x0cc243c7, 0x77231247, 0xc5f880dd, 0x536a556d, 0x6abe6f11, 0x3b0d7ee8, 0xb1e27e25, 0xa82ecefb }, + { 0xc4de7eef, 0x42608a74, 0x961a25bf, 0xb92b4d87, 0x5df7f8fa, 0x895c6218, 0x7b7227e9, 0xe6cca312 }, + { 0x1c8998ca, 0xea030927, 0x2997ffb8, 0x479279b1, 0x9d1c52d7, 0x06558fdb, 0x1325c1b9, 0xb4cef32c }, + { 0x885f479b, 0xc3cf6268, 0x1a77920d, 0xbd734982, 0xfa230527, 0xdf1c5465, 0x5ea6fa44, 0x3d963df2 } + }, { + { 0x15124d6f, 0x5bee8048, 0x5e7eeda3, 0x75385c1e, 0x4645a6b1, 0xd173672b, 0x8dd8f848, 0x947388ea }, + { 0x28ff84bd, 0x5d22f09e, 0x3240ffc2, 0x07097e29, 0xcb467d4d, 0x3a59c380, 0x4f2b4ead, 0x06c8331e }, + { 0x2c20ca5e, 0xa382ed3f, 0x63ed7858, 0xe637b728, 0x3e4269fa, 0xe0525ff4, 0x2ef2fc4d, 0xaa7c5b01 }, + { 0x72214e0c, 0xdaeb4dc4, 0xa3716f9f, 0x8478f832, 0xbd92995a, 0x8dcc007e, 0x89a24795, 0xdeee784f }, + { 0x501f8504, 0x790f4562, 0x7f646f8b, 0x3d38fefc, 0x90ab3450, 0x1884861f, 0xba10e16a, 0xf2c30349 }, + { 0xcec4f4b4, 0x6b923857, 0x12b72f4c, 0x2c3a4615, 0xc8886df8, 0xbfa753e7, 0x12166500, 0xcb0e06b8 }, + { 0x75a0cd60, 0x509452c2, 0x5009d6e0, 0xd08342a5, 0x57b6a30d, 0xf5d729fd, 0x037eb8f2, 0x7f8b37b5 } + }, { + { 0x603c8c13, 0x138a1e54, 0x645bb6d1, 0x8edfd612, 0x6555876f, 0xbe3ded27, 0x9463b0f7, 0xc5b43a0c }, + { 0x12fa6f80, 0xf77f6d18, 0xa5c05bcb, 0x49c1838a, 0x64183c24, 0xfbe20136, 0x62684de6, 0xa73208d4 }, + { 0x2dc70f79, 0x497fa780, 0xd9c1c81e, 0x7001f268, 0x75e76073, 0xa6ca0f6d, 0xb31cc76c, 0x152f9314 }, + { 0xaf35c9cf, 0x2fa27244, 0x52515468, 0x5b81ee48, 0x8ee84d9f, 0x7874f56c, 0x399f8e67, 0x0832a2db }, + { 0x1d4d84c8, 0xdd7051fc, 0xd1acabcd, 0xac8627ba, 0xe7728ae5, 0x87d3f1ac, 0x1930599a, 0x8b40e1f6 }, + { 0x8a3e0607, 0xdc86f37d, 0xd23d06f2, 0xab6ddcf0, 0x5e59320b, 0x56f7f0e6, 0x4826df9b, 0x1147f821 }, + { 0x9a2a5095, 0x37f84839, 0x8cb8c19c, 0xc723fca5, 0xb887fbd6, 0x648752be, 0x77c89802, 0x3bdf2bd4 } + }, { + { 0xe95fe2eb, 0xa5d641ef, 0xe1d5a4cb, 0xfcb6daa2, 0x93979a0d, 0xb4bb6da9, 0x127a76e8, 0x8df8945b }, + { 0xc1ea6447, 0xcf97c564, 0xb0f80528, 0x880e15d5, 0x37af7e10, 0x1e681462, 0xfbdf3db6, 0x587956f9 }, + { 0xef96a767, 0xde2d5fb3, 0xf1234cf0, 0x83ac6d2f, 0x14accc8c, 0xfe417ada, 0xe23c40e5, 0x7c167928 }, + { 0x4c207eb1, 0x1a2dfe96, 0xb68bfd29, 0x291f61bc, 0x6de72c84, 0x11f7da6a, 0x01e1eb6d, 0xc5e3816d }, + { 0x46073f01, 0xfa43db13, 0x83f36681, 0xedd9b5f0, 0x2ea57fb9, 0x517d52e1, 0x6a2daf24, 0x839a9057 }, + { 0x0152191d, 0x4740c750, 0x6ca4c9ca, 0x0204e7ce, 0x82231e7c, 0xdf4f5a1c, 0x6ba616c6, 0x7dfa2702 }, + { 0x846580db, 0xd8d0ed19, 0x56b83e33, 0x11e3a461, 0xbab0919c, 0x9b6c6b68, 0xd8a9b891, 0x9c306d9b } + }, { + { 0x739ba36e, 0x7a618ef1, 0x71076864, 0x7ffcb45e, 0xd5691757, 0xf069a107, 0x4be359e8, 0x3eaf0c62 }, + { 0x4c0597b9, 0xdd7424fa, 0x23087c7e, 0x2227a301, 0x7ddd34c6, 0x8e4d0d68, 0x4ebc55d3, 0xd9b5e6ae }, + { 0xcfb176fe, 0xd0454851, 0x403b9da3, 0xa80736d7, 0xd253d30e, 0x6bbb21a0, 0x81e58b09, 0xce51d245 }, + { 0x2f3d0bbb, 0xdb5540db, 0x7d589168, 0x84323951, 0xf180b0f1, 0xff44bfc4, 0x8fcaa903, 0x252f8705 }, + { 0xd628ea85, 0x701207a8, 0xf31d41fa, 0xa8f09523, 0x8a299618, 0x88e1f3c7, 0xc5427df9, 0x5aa1d861 }, + { 0x30e1fc2b, 0x40f302be, 0xa63b3b01, 0x2be3ac29, 0x056645e7, 0x7acc9bbd, 0xd230ce9a, 0x7d252c2f }, + { 0xd600bd13, 0x086c07c9, 0x029cec65, 0x8d599f6c, 0x4d25e448, 0x4e9bade3, 0x0c33da84, 0xbe9e056a } + }, { + { 0xec2c110e, 0xbe7c5905, 0x3d6b6ad4, 0xbf5ef109, 0x940723c6, 0xd0bc7636, 0xe45a396a, 0x6b3d8de2 }, + { 0xb7797ba6, 0x2a61063e, 0x6b5b2af8, 0x9705e437, 0xae799118, 0x80b9e5ac, 0xa524ea11, 0xd25993d7 }, + { 0x952418a0, 0xe52ea7fb, 0x5b851a60, 0x6a3d38f5, 0x7d76b217, 0x87d90655, 0x9351da3d, 0x8fea872b }, + { 0xa284f90b, 0xfed726ec, 0xcafc31d0, 0x8752f8fc, 0x8aecc6f9, 0xd71c0300, 0xdb700ebb, 0x2d234e4e }, + { 0x1255759c, 0x437e2721, 0x384eff34, 0xb49f1b47, 0x24b7d68c, 0x5677b98b, 0xc515b120, 0xd6d9fd20 }, + { 0xae16e75b, 0x8673ec67, 0xa1200f9b, 0xea6c1b43, 0xeea2218b, 0x3cd180c3, 0x761e1363, 0x1ba1263c }, + { 0x1fbac7da, 0x75d3c884, 0xcb97f364, 0x35e26bfc, 0xc958ac3c, 0x8209fbc8, 0x53ae71e1, 0x370d7647 } + }, { + { 0x44e5978a, 0x3c1c94db, 0x5812bb5f, 0x2792ab44, 0x0d072532, 0x3b6d3cbe, 0xab461bd3, 0x9cf81039 }, + { 0xb1b260c7, 0x9fd1ff0f, 0xce0a9c02, 0xd4e51cb3, 0xbb1283d8, 0x57376e34, 0x8c71591d, 0x055e92aa }, + { 0xe6bd5fd5, 0xfcc32cb1, 0xd7981038, 0xd98280fb, 0xece72c01, 0xde205008, 0x3995ad35, 0xbac90603 }, + { 0xfc5a9baa, 0xb00eee66, 0xab77bb87, 0xf777e3b6, 0xa3cb2f72, 0x05fb033a, 0x55d2cc9c, 0xf4bdae1f }, + { 0xd86e998d, 0x84e2624a, 0x8d1ef040, 0x19723c11, 0xec28489e, 0x2eaff7d2, 0xe3590133, 0x8a88d5a9 }, + { 0x832d5f4d, 0xd9489ab0, 0xa6c2601e, 0x6142906f, 0x10fad62b, 0xf6e2ed88, 0x77e39a72, 0xabd76faa }, + { 0x889c76e3, 0x0536b496, 0xbbb356e8, 0xe4db3548, 0x5c3fd0fa, 0x5b737f0c, 0x40931679, 0x6309963f } + }, { + { 0x40ee3a4a, 0x65909d90, 0x5925ec41, 0xe417e4c2, 0x6aa21fc9, 0x225a98f8, 0x53731c19, 0x2a85fbb4 }, + { 0x675dbced, 0x74d40ed6, 0xf6bb4283, 0x6ca6edf2, 0xab30d2f2, 0x11337c7b, 0x555c0f69, 0x670be54d }, + { 0x34d48b9f, 0x0a2af5ec, 0x71dfde84, 0x9a90919a, 0xaad1d2d1, 0x9a2d9fef, 0xb5ecf242, 0x7d065fab }, + { 0xa204eb7d, 0xb8d431d9, 0x782f3120, 0xdc5c6fcc, 0x81952fe9, 0x94e0e2a8, 0xe16b4870, 0x4590fe0b }, + { 0xcee0f906, 0x2d2e89e2, 0x5e52b5f9, 0x6bbdde65, 0xb7aff920, 0xdf304d13, 0x9657d288, 0x3829da86 }, + { 0xa2112a51, 0xcdbe59af, 0xa319b39c, 0x60b0f0f8, 0xf52da966, 0x5f1426b2, 0xd99020d5, 0x76f4ddf0 }, + { 0x85d5a9a3, 0x173e2a26, 0x6877031c, 0xf03affcb, 0x7a906fcb, 0xa24c9477, 0xd2b80f61, 0x5638c07d } + }, { + { 0x0e8f35a3, 0x4b06e823, 0xd47ed3b7, 0xf5509c22, 0x334cf6ec, 0x47d90946, 0x8ed63e06, 0x38f2c469 }, + { 0x1ee1ff9f, 0x469ee972, 0xe0ad7063, 0x50189047, 0x854ba00a, 0x857c9cbc, 0xbb161a5f, 0xb59ef60a }, + { 0x2cd66ff6, 0xb26af70b, 0xd50b921d, 0x2e817dec, 0xf121337a, 0xe2505355, 0x428634c7, 0x6ae831e1 }, + { 0x2619396d, 0xc2a33b43, 0xb7a69b41, 0x33911e3e, 0xea449720, 0xbf8e9980, 0xf05cc544, 0x3aa5efec }, + { 0x102bfe77, 0x62d7b4df, 0x8404e57b, 0x1e3545b3, 0x2f8ee644, 0xf2f4207c, 0x099c8785, 0xa228d753 }, + { 0xf6616f86, 0x69fc2f9c, 0x9a1782d7, 0xdb2f5406, 0x487d8aa1, 0x6ddae044, 0x6c90fed9, 0x1d380818 }, + { 0x56e70139, 0x2e6b471d, 0x76cb34b2, 0x7e9f9e9a, 0x811e573e, 0xaaf6ae4b, 0x82ca972c, 0xf5bea0cf } + }, { + { 0xa5dd88d7, 0x8dee56e6, 0xbb58ec74, 0x089b7971, 0x7fd5e416, 0x21542b2e, 0xdc673df2, 0x4029f024 }, + { 0x3be7e0f7, 0x960c1440, 0xeb62e51b, 0xac4afc53, 0x240d6a0d, 0xd0657374, 0xb6689044, 0x5c9aae75 }, + { 0x8326ca3f, 0xe625d457, 0xf15b1126, 0xcfa38cf8, 0xc2406d10, 0x5a921204, 0x776a8a3b, 0x878e5e34 }, + { 0x6a12d797, 0x9e0dfa96, 0xfe5b2bc2, 0xed8fe49e, 0x020cab8d, 0x5c17c09c, 0x7aaf3675, 0xcb32efd2 }, + { 0xe8a325c5, 0xdea7c0b6, 0xe6dd55ef, 0xa8b99be5, 0x129cfc09, 0x6b763ca0, 0xa830552b, 0x569b464d }, + { 0xc96c9651, 0x1f19b94c, 0x660758ab, 0x9508816e, 0xa19d2eed, 0xf1ae2c78, 0x8bc5fed5, 0x00fd09d7 }, + { 0x22701aef, 0x57666716, 0x08421b2d, 0xcdcd5760, 0x543206f3, 0x6097f88e, 0x693b42f9, 0xdfc5085e } + }, { + { 0xc2664a19, 0x620331d3, 0x48889f76, 0xa44e061a, 0x282678ed, 0x36f0288b, 0x3763e871, 0x3e596769 }, + { 0x2498cad7, 0x50a838ca, 0xe791ab2d, 0x0754f6f2, 0x5cdca55d, 0xc9bafd41, 0x24afdc8d, 0x23665d35 }, + { 0x26894e5e, 0xbe4c1593, 0xb6d29b4a, 0x5fa3f8ca, 0x8d2aac65, 0xd2bc3e96, 0x00fe77fb, 0xcb198ce9 }, + { 0x7331d5e0, 0x768df63e, 0x82f1722e, 0x1b985f9c, 0xefa77f96, 0x1bb90013, 0x9e08f1ee, 0x7fca2a70 }, + { 0xed96ed08, 0xaa96fe7a, 0x5f879c42, 0x0c196850, 0xca6bddce, 0x86962640, 0xb008b923, 0x0c685470 }, + { 0xc8ec4adf, 0x6dfd64de, 0x24d3255f, 0xc3e21106, 0x25c129f9, 0xa50cc5ac, 0x4436f72d, 0xf4e12400 }, + { 0xbbbf713e, 0xfcb809b9, 0xb1c8191d, 0x412abbae, 0x2bd280f7, 0x72ac974e, 0x7ed0cf44, 0x07877eb5 } + }, { + { 0x65aafe11, 0x1fa428b7, 0x22341c0b, 0xa2b636fa, 0x0660cd16, 0x26385884, 0x18560714, 0x8a078be6 }, + { 0xf37b1f40, 0x518efb3f, 0x3cea578c, 0x0996b9fd, 0x534ed631, 0xd1d649fb, 0x2ce5334f, 0x1bfb56e4 }, + { 0x31ed147c, 0xf0045d66, 0x79601217, 0x0c961d24, 0x890b6028, 0x316d5b08, 0x0a4dd963, 0x74293c6c }, + { 0x084cb1eb, 0x9346da73, 0x213d7cdc, 0x033beadc, 0x48427ebe, 0xf45f1a1e, 0x22a46790, 0x284de933 }, + { 0x241ca2c6, 0xb8da323c, 0xaa49b8c1, 0x30fccc6a, 0x69d79b4e, 0x30bc1c59, 0x0c503411, 0xd1942fdd }, + { 0x06695ca3, 0xb25c2fab, 0x6b3ca61f, 0xf047e54e, 0x51dec03b, 0xdfd29b84, 0x4e975532, 0x08361d04 }, + { 0xcba0a713, 0xf0232fc3, 0x4b2eeee9, 0x66ee4b7e, 0xb78b0036, 0xa32b7db3, 0xe2f30b39, 0xd4dec14c } + }, { + { 0xd36a7ab2, 0x67f4ed43, 0xc817db01, 0x2f28e486, 0x5c05b744, 0x3d1f43f1, 0x3d9e7bbb, 0x8f180f0e }, + { 0x3c2b5219, 0xb5c4f016, 0x3ecfadd1, 0xd5199480, 0x2ea1b120, 0xfe00a929, 0x725cb579, 0x10776088 }, + { 0x73ca411a, 0x2d52dc92, 0x1f8468ac, 0x49f9e29c, 0x4ae29ea6, 0x88242e06, 0xe735e8b3, 0x214bf098 }, + { 0x6dea30de, 0x81bfb45c, 0x0066cd3c, 0x2ef9f054, 0x661e01c0, 0x42f761ad, 0x57336603, 0x992d508b }, + { 0x28fe1b7a, 0x7ef83cdc, 0xf6cd53ec, 0x5f433d1d, 0xa6f298b2, 0x82c6fd51, 0xae40ca01, 0xa3289f64 }, + { 0x1ed7f9e2, 0xb34f93fa, 0x35c9d484, 0x02210a89, 0x8ffb4860, 0x1f3bad52, 0x4a04e4e4, 0x7f240d8b }, + { 0xb167e24b, 0x2b7b93fe, 0x90187e34, 0xa7fff549, 0x04632894, 0xafcabcfa, 0x560ad9ab, 0xdaf1e573 } + }, { + { 0xd2d02250, 0x1cfdb459, 0xa7be1444, 0x4517d059, 0x2a4924d3, 0xf987d56a, 0x3f0396a3, 0xe8a2a6a6 }, + { 0xac4c610b, 0xd10dc62d, 0x7171da3d, 0x266f2b5f, 0xaf934d11, 0xc07ee64d, 0xcd1f0757, 0x141f4bf0 }, + { 0x7ecb87a7, 0xdb0d272f, 0x818ace78, 0x59398fa7, 0x25c3d879, 0xd3df1c98, 0x63549da0, 0x74ec65f7 }, + { 0xaac37051, 0x948a92fb, 0x896fbb6c, 0x0444eccc, 0x369ff36d, 0xc5b38cab, 0xe5dbda92, 0x9afff36c }, + { 0x464aa944, 0x373ce36c, 0xb4ff97f0, 0x238f6df3, 0x84aa4167, 0x2aeb497f, 0x4117d17c, 0x60e545ce }, + { 0x6f440a4d, 0xf770a96c, 0xeb9230c5, 0xed4ed9b5, 0xcfb56dfa, 0x81d07cef, 0xb696436d, 0x7f99e9c2 }, + { 0xf45c6592, 0x274ad3be, 0x3a91c2df, 0x6dc9d9c5, 0xd3411a03, 0x027282e1, 0x7675402f, 0xe1987a93 } + }, { + { 0x6d8fa21f, 0x170d86f4, 0x74a8d1e5, 0x6097209e, 0x3aaaad94, 0x594fc661, 0x6174d88d, 0x9f14f1a1 }, + { 0xc3c4af2f, 0xd8d7dd7b, 0x3c80cbde, 0x1c5aeba1, 0xe4edbeb8, 0x57ecf240, 0xb503fa1c, 0xda69c2f6 }, + { 0xf962d73b, 0xa5f276ff, 0x1d88db47, 0x3f7801a3, 0xca4861a0, 0xd116075e, 0x457c2d1b, 0xb6e249c5 }, + { 0x8b44add4, 0x9f3d7bd7, 0xdd635ed9, 0xc1101393, 0x31e8b807, 0x4642036b, 0xff891aba, 0xd792b1f0 }, + { 0xdebe280a, 0x77f5be94, 0xfc19b696, 0xdd0ffe97, 0xe7ce196d, 0x958acc04, 0xb47125dc, 0x2c9069cc }, + { 0x9a642368, 0x07ab659b, 0xeb99ec37, 0xddfb12fd, 0x54413d00, 0x0dbc2637, 0xcf98c7ba, 0xf2f07e46 }, + { 0x9d83d826, 0xda1be20c, 0xe2c21d53, 0x23569607, 0x8dfadb0d, 0x07eaed28, 0x6587c111, 0xac48baf1 } + }, { + { 0x81ae76d9, 0xfb3bfc8b, 0x88e191ba, 0xccf551af, 0x71ac053c, 0x0860809c, 0x9908dadf, 0x320797e6 }, + { 0x4a97c663, 0xd6e091cb, 0xb480faea, 0x1bacb1d0, 0x8e3046e0, 0xee6090b2, 0x085033a1, 0xc805d682 }, + { 0xfe98733e, 0xc4ff804a, 0x360a2923, 0x941ca38a, 0x3e4e6d8a, 0x3d70b663, 0x62c31590, 0xb317e43b }, + { 0x02274140, 0x6f02a50a, 0xeb3cd539, 0x07a9b5c9, 0xf80801c9, 0x4c2f5e39, 0x6c8a7eb2, 0xaa52caa9 }, + { 0x6ff7956e, 0x584d5993, 0x5cd3d0c4, 0x6c1bec6f, 0xdf3ad54a, 0x0634085d, 0xe6edad76, 0x0632db1d }, + { 0xc0daedce, 0x6fb5fc04, 0x76cd6752, 0xbd0ebd60, 0xaa171a2a, 0x87271e80, 0xb32cf4ff, 0xcfd5f1ea }, + { 0xf4eae25b, 0x1066c3e2, 0xc66efd8a, 0x5771607b, 0x4a1103e1, 0xc72b19d6, 0x85f6005d, 0x16270c65 } + }, { + { 0xadfd2c36, 0xd5d9a3e6, 0x1c5ded49, 0x794b0b23, 0x2b3dd153, 0x85212727, 0x7e8378ce, 0x62a6c24a }, + { 0x177a0f49, 0x990dfb5d, 0x2a7cbb31, 0x81dd7508, 0x0a2076ee, 0x5b23bfb5, 0x92f9cfd5, 0x09a5afc5 }, + { 0x1f7bc827, 0x079b2d8e, 0x5bdc1ac7, 0x673ec43e, 0x657f62d1, 0xf9468988, 0x02c231f0, 0x248a73fb }, + { 0xe32bbbf5, 0x9643176f, 0xaa007d1c, 0x1b31fe7b, 0xe6d7493c, 0x6f0544be, 0xc2a166eb, 0x96553372 }, + { 0x4cd86349, 0xf93cba6f, 0x80330f59, 0xdbd48996, 0xa04d3d1f, 0x814c4343, 0x6b4e6bd8, 0x130b061f }, + { 0x488259de, 0xca5f861d, 0xb1f3befa, 0x2fb3ecd1, 0xb75c2a80, 0x13e0054c, 0x68f7b652, 0x46705c85 }, + { 0xb56c48d8, 0x919f2305, 0x0597d41e, 0x283c8849, 0x97acf524, 0x600d53eb, 0xb58af268, 0xb6055293 } + }, { + { 0x93b58020, 0xc92b9cca, 0x68fc5c38, 0x65cfa237, 0x4f772567, 0x0bee599b, 0x67bc9a37, 0xcb552a96 }, + { 0xc792e9d9, 0x88e62b19, 0x4f905a50, 0x9a2f679a, 0xce1a0f3f, 0x1612b9e3, 0xf468578f, 0x49366e99 }, + { 0x42d446d0, 0xbc66a584, 0xc13f0b96, 0x9a459cb3, 0xd370cafe, 0x74cb1ed7, 0x33ff0f32, 0xdcd2b0ea }, + { 0xb0a3e5ce, 0x04b267c7, 0xfcb3b440, 0x17ac5acb, 0x1447fcd8, 0x49c52474, 0xd697d5ce, 0x7772aaa0 }, + { 0x50f93339, 0x11a673da, 0xe65ac850, 0x06e92d28, 0x29e97ce8, 0x2232b5f2, 0x94f7facc, 0xdf282447 }, + { 0x092291d4, 0x6a117ef7, 0x7a34fe0d, 0xf83e4c59, 0xd3330de6, 0x832f0923, 0xfaf4f12b, 0xf6faa6d4 }, + { 0xe81ae317, 0xc3b9d4c1, 0x9e64153f, 0x5c1d9fdd, 0x7d6e1738, 0x58feec0a, 0x0fa3da99, 0x3d715281 } + }, { + { 0xecdff5a7, 0x6676ea5b, 0x2c726a48, 0x407d9721, 0xa1599ebb, 0xb0db1f6f, 0xbcf2a1f6, 0x7d2660c9 }, + { 0x3c9ddc23, 0xb272fda3, 0xfa08d13c, 0x33bcb2c8, 0xcc9780b7, 0xe59248dc, 0xa53ef623, 0xcdb54aea }, + { 0x0a891eee, 0xedb5537a, 0x73fef228, 0x2f8afdf8, 0x21937ce5, 0x2bfa6881, 0x19e4cab7, 0x51111ed4 }, + { 0x8463613c, 0x1e08ff5b, 0x3619d2c5, 0x6c5bc71a, 0xa5617229, 0x7a84f5a0, 0xd70ec7a2, 0x096c3012 }, + { 0xa543ff79, 0x5d9dc2d6, 0xccbd15d2, 0x4ca14491, 0xf6712929, 0xa48759e0, 0x1a8d2f9b, 0xf75b299d }, + { 0xf741280d, 0x27b522e6, 0x8b9120d6, 0xde442033, 0x4a45f300, 0x1ab5c184, 0xb3529b73, 0x78ae6f43 }, + { 0xb7e6405d, 0x96e14656, 0xf6f5af96, 0x2484964b, 0x4cc985c1, 0x30c5c4f7, 0x9348dcb2, 0x451fd6b7 } + }, { + { 0x847b441f, 0x64e2d0af, 0xe296fad7, 0xf04c1410, 0xfbb26f59, 0x4c9b5399, 0x4b4549ab, 0xda5bc6eb }, + { 0xe0f825d1, 0x823baf0b, 0x5a5daa63, 0x70afe524, 0x8a3d5f5c, 0x6a579433, 0x19ec18c6, 0xcc022f88 }, + { 0x69549970, 0xc6a94cd6, 0x39c448c0, 0xccd1e4fa, 0xd3e51cbc, 0x2daa4ded, 0x641f113c, 0xefcb15ea }, + { 0xc769f45a, 0xe8b9f6b7, 0x6c171cf7, 0xe51aa6bb, 0xf6e8a7cf, 0x550d9ec8, 0x70b6fc14, 0x93d25399 }, + { 0x1b38ee7f, 0xc2ca1522, 0x2f02f4b4, 0x64e5e77e, 0xaf807936, 0xfd52a2b4, 0x0b945830, 0xf32ddabf }, + { 0xdcfb6efd, 0x9e827b96, 0xee3fdcff, 0x9927330b, 0x1ca19690, 0x05751282, 0xe894714f, 0xb753e4a4 }, + { 0xe4aa50a3, 0x0f2932d5, 0xf2ee250c, 0x7909c7e5, 0xf520966a, 0x8e6d6fd6, 0x362ff7aa, 0x4f1ffedf } + }, { + { 0xba4aa7fe, 0x23acf2fe, 0x750c8802, 0x479c8ae9, 0xefb8b28f, 0xb225382e, 0x4a822fc2, 0x9d19ba9e }, + { 0x25f06167, 0x4e836183, 0x16f9c419, 0x9c6a3ce2, 0x65d799ee, 0x2dcff663, 0x7435d69c, 0x62722923 }, + { 0xdb0d51b9, 0x4386ddbb, 0x13928624, 0x00b1c86a, 0xfbed33ef, 0xc89cb5f9, 0xf69a263b, 0x436e3d90 }, + { 0x2e9e445d, 0x6fddb749, 0xfe91e5f5, 0x2e0f2b83, 0xa1dc12de, 0x9ad1eab8, 0xfc46cca9, 0x9f1a0808 }, + { 0xa7b20d80, 0xcd7e5fb7, 0xa105a519, 0x329a760d, 0xb43e6e56, 0x890d9bdc, 0x0f62a234, 0x69ff9f73 }, + { 0xd2c9bf82, 0x11c2c774, 0x85e8c80e, 0x3dc16926, 0x0cf8524e, 0x3eba8078, 0x76e9f4ad, 0xc6c1e37d }, + { 0x650bba35, 0xb54cddf1, 0x7a6f3d6a, 0xc497117f, 0xd1668578, 0x67ae4fed, 0x3602d187, 0xd01f5242 } + }, { + { 0x1f57f29d, 0x029905f8, 0x0510bd9c, 0xce7df4c2, 0xb1a011cc, 0xb9e62d2e, 0xf104bb52, 0x9efc1af5 }, + { 0x931d0402, 0xe2ae2229, 0x95f50a92, 0x6dc64703, 0xb69f1789, 0xb480484b, 0x86d45dcf, 0xa232393e }, + { 0xe721772b, 0x6fef8146, 0xc5f37a01, 0x9771768a, 0x00755258, 0x081831ae, 0xdcf6cc8b, 0xf863dc4b }, + { 0xa3598f7d, 0x43c603ca, 0x9e9e35f5, 0xc0b63782, 0x407121dc, 0xa34cdee0, 0x8e53452c, 0x55701ddc }, + { 0x7a4ac01e, 0xcad82682, 0x44fbc5e6, 0x892e51ea, 0xf6d7dc96, 0xd822163f, 0xb29d330f, 0xd19358d7 }, + { 0x8e697e6b, 0x923d1214, 0x33b221de, 0x6e8af382, 0xb972588f, 0x0501ad9e, 0xeab37b31, 0xf03b3f88 }, + { 0x12c94189, 0x2ab9caa6, 0xcdf48f4d, 0xb95c7e34, 0xf87491db, 0x91363766, 0x96f22251, 0x84317056 } + }, { + { 0x7cbba542, 0x72173553, 0x0c0a7a35, 0xc6f4eb31, 0x82bb8315, 0x6f0b5c5d, 0xa04d85dd, 0x3af4cac8 }, + { 0x3cd5253d, 0xc62d4aa6, 0xd70751d7, 0x429b3bc6, 0x48fdc01f, 0xdf33a9a5, 0xbff66b75, 0xa7834e5f }, + { 0xff19bdb6, 0x0659727b, 0x94ed27e1, 0x6761817a, 0xa8dd8727, 0xd11d0798, 0x1e8b20e2, 0x502497bd }, + { 0x5ae9a48f, 0x29d1b18f, 0x1ebef3de, 0x51a8970b, 0xf1593ab9, 0x105438e4, 0xb8adac0b, 0xd6c4fee5 }, + { 0xc928984f, 0x46d28d26, 0xf341ada7, 0xb90279c7, 0x30fcb818, 0x92732b54, 0xbc4af11d, 0xb886260c }, + { 0x5223cd70, 0x6c8e9c6d, 0x0f074d15, 0x75b02f03, 0xf01e807b, 0xb90dc474, 0x2a4222fd, 0xf7e22b4e }, + { 0x13f4a74a, 0x81d4be59, 0x2841a6b6, 0x58db0cd2, 0xb51bda0a, 0x99fe44a1, 0x525627bc, 0x41383547 } + }, { + { 0x8b01f37e, 0x206300f8, 0xcac9203b, 0xca044f48, 0x9f55b65c, 0x8687785e, 0xcaa26e97, 0xd70e84f7 }, + { 0x4896d8e5, 0x08aed1be, 0xf44e6b99, 0xf3d85e8d, 0x1542f062, 0xfb686b8a, 0x66c5e1ac, 0x81de583e }, + { 0xcf9bb018, 0xa03a9704, 0x283f8f67, 0x44ae7b5a, 0x39cb8ae9, 0xba5de384, 0x513f7a33, 0x4d93b2bf }, + { 0xca9e5603, 0xeda4a5cc, 0xcb1400b7, 0xdf20ab93, 0x42afbb75, 0x59b5082d, 0xdcf8fdab, 0x626e4301 }, + { 0x4757c591, 0x20281a53, 0x5745e75f, 0x934ab502, 0x45702ab6, 0xea024398, 0xaa157702, 0x5b95d5b8 }, + { 0xfb4667d5, 0x688f1212, 0x8c13309e, 0xebe42bb8, 0x597635ee, 0x82dab4e4, 0x28452d5b, 0x8de3ec58 }, + { 0x37b5319d, 0xab7a3ae0, 0x285a102c, 0x4d4d6609, 0x00ceacb7, 0x859ef2ea, 0x7a9baf1e, 0xa7d1e1ec } + }, { + { 0x4262d31f, 0xc6bfde90, 0xe4879507, 0xad2c75c5, 0x330ef914, 0xdc0091cc, 0x8144ffd2, 0x593f522e }, + { 0xfeb34417, 0xe940b63a, 0x54b1ed6a, 0x7ca15220, 0x26d78116, 0x4304fd1c, 0xf8a028a8, 0x93fc1330 }, + { 0x1b9255ad, 0x50ce1933, 0x23801901, 0xb265abe8, 0x04f25868, 0x4b6825cd, 0x257a49a9, 0x2508d0a0 }, + { 0x0d554186, 0x4c3ea649, 0x26db83a6, 0x88950115, 0x6479edc4, 0xcc4090f8, 0x50c50406, 0xbbd7a030 }, + { 0xdbdc389c, 0x5eb8199f, 0xcf74a9a2, 0xcf3d8afe, 0x422dec42, 0x4bc45fc3, 0xcb777bfa, 0x70267343 }, + { 0x634e0b8f, 0xfe8050bc, 0x6d104e04, 0x6fb0865a, 0xce0fd7ff, 0x99b58711, 0xd297351d, 0x55a4b0be }, + { 0xcbc61aaa, 0xfccf89c0, 0x1dffca73, 0x7501e2a0, 0x9060e461, 0x212e84b5, 0x2961348b, 0x6075ff35 } + }, { + { 0x1971479e, 0xf1030877, 0x5e164bc5, 0x7b62d972, 0x7c79fc3b, 0xf7f0f07e, 0x8eff6729, 0x4922bb00 }, + { 0xf329ae40, 0xb38599d1, 0x3e9b0544, 0xd54e5643, 0x4091b5c5, 0x6a6dd0d1, 0x83d67840, 0xf82fb50c }, + { 0x1557f7cb, 0x6658ca2f, 0x35eacc2c, 0x47f3a958, 0xa498919d, 0x111cf62a, 0xc8035aae, 0xb7cad54a }, + { 0x4f02a442, 0xa40631dd, 0xefcba983, 0xdd7c3993, 0xee1226bb, 0x6294df26, 0x9529ae54, 0x7a634024 }, + { 0x5d9171eb, 0x05e32a3b, 0x68a836bd, 0x55b4b02b, 0x4c748bbe, 0x00f15133, 0x95266a50, 0xdf18fc19 }, + { 0xe066eda6, 0x9e04b489, 0x57b29169, 0x8ee40a42, 0x701813f3, 0x892d824b, 0xc6ece8ef, 0x6a46a762 }, + { 0x21e51d9b, 0x7fdce794, 0x053ed79f, 0x3884dfa5, 0x3dbb2f0b, 0x21897155, 0x54c823a2, 0xfda148e9 } + }, { + { 0x66f558b2, 0x2d6a44f1, 0x49017c74, 0x58e64303, 0xfbb8ccf8, 0x2755a4b7, 0x38483726, 0x7efb7c5d }, + { 0x6b9782d2, 0xf249694c, 0x7809f73a, 0x039be4f2, 0xa84b112d, 0x7ce459be, 0x20ceb8f6, 0x024162eb }, + { 0x67ea0190, 0x2fe4203b, 0x45ab91f8, 0xa0356d3c, 0x25c94692, 0xa9fac370, 0x593459da, 0xf41dde5e }, + { 0x457d0f83, 0xdc722eda, 0xfc2d6748, 0x17b1fa53, 0xb504bf7b, 0xb2ec3539, 0xcda65159, 0xac11254d }, + { 0x4f7b4295, 0x8682638d, 0xccd438f0, 0x864298f3, 0xccbf0c14, 0x1f0efcf2, 0x9cef2954, 0x6997b446 }, + { 0x736a3b6e, 0xd74b6514, 0xf891a59a, 0xc9c1c3df, 0xe6d5953f, 0xdbfd4970, 0x3cb2c56b, 0x4f29b2bf }, + { 0xf5449706, 0x0b298e81, 0xad160a61, 0x48e4a2a6, 0xb38e2277, 0xda0b2997, 0xcccda1fd, 0x663628fa } + }, { + { 0x88461e31, 0xcf3888a1, 0x099f1db2, 0x6811d294, 0x000b1c12, 0x18717a0c, 0xf4c08ad1, 0xd43dd554 }, + { 0x4566b0fb, 0x8de6f13d, 0xf378de4d, 0xc9ad32e2, 0x410608b7, 0x426a0852, 0x1ba93f7f, 0x1e3c19ec }, + { 0x86dada84, 0xd21501e4, 0xc085a31a, 0xae40a4e8, 0xb3aceee2, 0x4867f51c, 0xa54200d2, 0x07d31bfc }, + { 0x983dabeb, 0x7ac24dd1, 0x55aca5f3, 0x5cd65a17, 0x48cd118e, 0xb2f87539, 0x82161971, 0x39692cd8 }, + { 0x1d8b1be8, 0xefb57822, 0xf0df6722, 0x73d364b5, 0xa94828c2, 0x796774c7, 0x93fd74fc, 0xb357a489 }, + { 0x95505349, 0xc7a46174, 0x6fa24c02, 0x16efb6fe, 0x740008aa, 0xb6d9917b, 0x9da5de0c, 0x853c7241 }, + { 0x7f437191, 0xe15dc8a6, 0x5cd38fd9, 0xe92b2720, 0x5e9e5325, 0x951a7f9b, 0x0baf1cea, 0xa22710e1 } + }, { + { 0x7c260aa8, 0xd4c5a15e, 0xfd8cda34, 0x8c160df4, 0x17b599b8, 0x230d03d5, 0x1efea373, 0x91735454 }, + { 0xc1b07120, 0x37d0e5c0, 0x7b4efd27, 0x484b4d39, 0x2cf880a3, 0x508fb7dd, 0xaff7f179, 0x8c7b602d }, + { 0xfaf6f189, 0x908e9151, 0x8b9e20df, 0xd3bf4837, 0xb6491aa9, 0x7cf456a6, 0xecbcb69f, 0xfad87a22 }, + { 0x8d76fcad, 0x4485d0cd, 0x61f1e566, 0x4e3393d6, 0xa77e206b, 0x6a6aa22e, 0xefd341e6, 0x4156e065 }, + { 0x769cb145, 0x784032b3, 0x8c7d62e2, 0xa4812bbd, 0x34fcfb15, 0x5ae0fcc2, 0x71c975fc, 0x4d494fc9 }, + { 0x422a6172, 0xebb52112, 0xa30e16ba, 0xc33ed85f, 0x4ace3d27, 0x3c40b4a1, 0x4438d53e, 0x0f0f9d86 }, + { 0xaca70e84, 0x01e02a49, 0x639cb433, 0x7e065289, 0xd9c1557f, 0x52fc1006, 0x124252aa, 0x7fa52809 } + }, { + { 0xc2b2f5aa, 0x474ffe2e, 0xeef7d3a3, 0x5398e0d0, 0x77332d60, 0x3d421034, 0x6f2c7505, 0x7577f7f4 }, + { 0x24c40f8d, 0x0aa30a28, 0x5c7b4d5f, 0x7328f598, 0x3389c312, 0x286a2ab4, 0xdebc62f3, 0xd07734be }, + { 0xb725f710, 0xfbbc5bb4, 0x7e22dce9, 0x03140fbb, 0x81e57058, 0xab4a0910, 0xd4424761, 0xbd860106 }, + { 0x7beae8e5, 0x19d325d3, 0x58f7ad0e, 0x7bc8d35e, 0x3d52d5ec, 0xb676a92c, 0x659043b7, 0xdba74980 }, + { 0xc027c5fa, 0xc7a41e0b, 0x75ee6876, 0xf42a649f, 0x210e2949, 0x752e2748, 0x70cda457, 0xda935595 }, + { 0xfe0a1aeb, 0xe91527d4, 0x745ac60b, 0x8ab847c1, 0xa0cb829f, 0x6807edb3, 0x75786719, 0x5c0a7958 }, + { 0x49994b67, 0x3aadfd2f, 0xb93d4a77, 0xa47521f4, 0x003eaf27, 0x5b9259ea, 0xf45befdc, 0x331d4aaf } + }, { + { 0xecf05a78, 0x5b0dccea, 0xbe596791, 0xed74ae92, 0x777bfc4c, 0x561c0875, 0x07bbfa03, 0x579b232e }, + { 0x6c42cfac, 0x24f610e0, 0xdcf35c44, 0x1b9577c1, 0xe2bbd5ea, 0xd5f823b5, 0x9aa4298d, 0x6b66d59e }, + { 0x5d954b63, 0x53148e48, 0x74fa648a, 0x0e0d480b, 0x2fc671d9, 0x2fd95107, 0xe70ab4fb, 0x7976b80d }, + { 0x8ef41049, 0x018013ac, 0x7550be64, 0x34b310c8, 0xee330770, 0x82344b45, 0x6d46e81c, 0x5ddc8719 }, + { 0xf255471a, 0x2833052b, 0x72f5a69a, 0xf5ff80d9, 0xacffa4eb, 0x60b8e894, 0x5265bb17, 0xf6db3173 }, + { 0x29bc7929, 0xbfc100b5, 0xf24ede85, 0x7ae1d4a5, 0x447c4bc9, 0xccc2aa08, 0xd5745d7c, 0x053457a2 }, + { 0xfa514633, 0xfb59f89d, 0x90ca6394, 0x3fedf89d, 0xc2cffe6d, 0xd2b55ee1, 0xa5df8867, 0xbb7c2efc } + }, { + { 0x1dd251ac, 0xf30df07d, 0xd8136997, 0xbb300cbb, 0x9bb0f617, 0x097b4ad6, 0xaba0ef4e, 0x59465f3e }, + { 0xc67a54d8, 0x2d751c35, 0xf8e886e4, 0x60ed22d6, 0xdced76ae, 0x4317daee, 0x27c2efa5, 0xb5eec930 }, + { 0x2ab454a1, 0xac5b9d89, 0xec2dac35, 0xb7c2d85b, 0x6c74c4ac, 0x3d28f854, 0x0901addc, 0x7d29d165 }, + { 0x19099d92, 0xc8d38c91, 0xc43dbf7d, 0xe1af968b, 0x7ed8cf43, 0x4054cb18, 0x0a9668a3, 0x1cc65a8d }, + { 0x5836c214, 0xdb773225, 0x5fde14a6, 0xdc947ecc, 0x6b3e8419, 0x5708a87e, 0x347206dc, 0x32160dcd }, + { 0x1ce13b9e, 0xb816fb8c, 0x198329b9, 0x9d3caeff, 0xbd3b5abd, 0xe4d3eeb9, 0xb77864a6, 0xaf3bf0a9 }, + { 0xf485d47f, 0x51b08c2c, 0xb42daa90, 0xb41a9590, 0xb6362e88, 0x42bd5caa, 0xeb7391f1, 0x688ad9b4 } + }, { + { 0x8b55b285, 0x42aa6486, 0xd9268c13, 0x0a03572b, 0x4d504508, 0x5494ff44, 0x220e34dd, 0x63981d88 }, + { 0x9b8ee0b9, 0xaa0cee25, 0x284f22a6, 0xacfc09d0, 0xcf8ac884, 0x9f034053, 0x02c06625, 0x1093543b }, + { 0x6cb3b436, 0x40a03d9a, 0x070dda52, 0xbea1abf9, 0x96852da5, 0xb53ca963, 0xe87a92f9, 0x58cca1dd }, + { 0x91870369, 0x42e0fdb1, 0x038c4b19, 0x055e8e19, 0x6dc8bd5e, 0x1b6cabbc, 0xa5e2bb46, 0xcb466075 }, + { 0x60eb94ed, 0x51464ace, 0x142290e2, 0xf4a44743, 0x2c708010, 0xc5250cc2, 0x6b769c44, 0xaf7e0bc6 }, + { 0x427ce9a3, 0x643b6665, 0xf5825e83, 0x71c078e5, 0x80c12986, 0x468c2c31, 0x66fc2010, 0x8d883193 }, + { 0xeec6896d, 0x5bc850a7, 0x0043b164, 0xb68fa17a, 0x42a90bf0, 0x66f032ef, 0xd2a793da, 0x8365050f } + }, { + { 0x4bcf37fe, 0xdfbdfcfd, 0x2656f67e, 0x99743980, 0x5c56a240, 0xad4a9dab, 0x8265a41d, 0xa8898339 }, + { 0xa7605856, 0x24112f36, 0x66231ab2, 0x1174e49f, 0xa28fd7e8, 0xb2c571be, 0x78e2c98f, 0x64e2a488 }, + { 0x55cdcfbc, 0x335f2de2, 0xc1f667a3, 0xcae99a95, 0x13bc9290, 0x2b5cad96, 0x6b64e4ff, 0xed8785f6 }, + { 0x3e337610, 0xf3167171, 0x204cba94, 0x148aa7c9, 0x22dd312c, 0x413db12a, 0x64e10df1, 0x8cc14934 }, + { 0x3996e4b5, 0x82fa4d52, 0x1e2948b4, 0xa41861d6, 0x04f0a3cc, 0x19e28afb, 0x7854e850, 0x6da4d3ca }, + { 0x3ebc0883, 0x5b7a6a1f, 0xbc847133, 0xdacac476, 0xe7b5ee09, 0xcc407e9b, 0xc9f984b4, 0x4413fb47 }, + { 0x25af56f3, 0x9ee31133, 0x3a5d6608, 0xc1633547, 0xa1340283, 0xa51a0e30, 0x6abb1afa, 0x57509d93 } + }, { + { 0x02af6488, 0xc6f1f442, 0x6c639ff4, 0x08c7cd76, 0x76c9ab1d, 0x18d2048a, 0x676010db, 0x902497a7 }, + { 0xfc8ae3de, 0xab96eb36, 0xb9a8f7f0, 0x271c4873, 0xce390db7, 0x01690929, 0xe5ceb856, 0xd3bd1b2f }, + { 0x761a431f, 0xb09b8568, 0xceff9c70, 0x03addb33, 0x5ef69616, 0xa9c10c4f, 0x7885f524, 0x062db25f }, + { 0xaccf6587, 0xbcc93419, 0x4f35cdcb, 0xdb908d87, 0x0bbdffa6, 0x597084bd, 0xadd758ed, 0xa2f123fb }, + { 0x7c0739dc, 0x3ec7f3e3, 0x1713fbd4, 0xb36b947b, 0xc710c44e, 0x91353fb2, 0x0ad4c33c, 0x6567ee87 }, + { 0x258e7cb7, 0xd87421ec, 0x5d2b094a, 0xd761d2f7, 0xf46c39fe, 0x7571ae0e, 0x36ab8436, 0x98bc9c83 }, + { 0x025c1dbd, 0x76b4d07c, 0xc54e9cc8, 0xcdf720e6, 0x0020d4bd, 0x83c0bdb8, 0x20f92ff2, 0x271b6102 } + }, { + { 0xe6514ab2, 0x13b3fd1a, 0x8c679366, 0x1c128246, 0x7af4b686, 0xf4b704a4, 0x9cd82805, 0x12d4d6b7 }, + { 0xeeb985ae, 0x864faad7, 0x6963fda2, 0x89ae62c8, 0xdaa9b739, 0xb1749fe4, 0x8316ca7e, 0x0993a340 }, + { 0x8c5bf7b5, 0x1ee4e43f, 0x31d8fdfa, 0x2f99bbba, 0x210e181f, 0x3960ac90, 0x5d957a72, 0xba1652ee }, + { 0x79f6eb31, 0x30e4a088, 0xa0f2cb92, 0x591f7c8b, 0x50684126, 0x944e9c6e, 0xd189c11d, 0xcc30853d }, + { 0x1dcb040f, 0xd26ba641, 0x84fe1aa5, 0xa003b00e, 0x262cd9bc, 0xd0094575, 0x8555ee7c, 0x8287eac9 }, + { 0x63afa921, 0x328e2fc8, 0xbffcdcc8, 0xd42ce069, 0x4da61fcd, 0x971689b8, 0xd2629581, 0xe42b7b9f }, + { 0x83200806, 0x2c3cb0eb, 0x3184b87e, 0xad40c129, 0xefd20ec3, 0x6a77e260, 0x9d2b8de5, 0x361606b2 } + }, { + { 0xce3b9040, 0x462efa2b, 0xdca78d45, 0x83214df5, 0x98943be1, 0x674e1042, 0x2cbc7fe0, 0x0e972c36 }, + { 0xfa580698, 0xbb9417ec, 0xa5e6d40b, 0x17a77d66, 0xd3ae0c56, 0x6668f565, 0x3a1a3ccc, 0x16b81eeb }, + { 0x14a5c135, 0x33d9759d, 0xabff04e7, 0x58105133, 0x70e2396b, 0x893802ce, 0x284f4dba, 0x9486e2ff }, + { 0x9caca6a2, 0x7d23e8d9, 0xdf6c431e, 0x20853c78, 0xe6ff2b00, 0x9fc61c8e, 0xff9b2556, 0x995a4727 }, + { 0x66f7d234, 0x41fc08a2, 0x1d58a09d, 0xa0c6403a, 0xe7165329, 0x5ad4d532, 0x13898a2c, 0xc34da70d }, + { 0x30ac7de9, 0xdbf84ec0, 0x387e7290, 0xda58f0f8, 0x8c384fd8, 0x657605e6, 0x9168aa87, 0x80cda5a2 }, + { 0xd5e18650, 0x75dcea96, 0x2ea0bfa4, 0x643ae8a1, 0xde6f2b15, 0x2afe461f, 0xe3303295, 0x9377dd5f } + }, { + { 0xc322777e, 0x544fd7a0, 0x5e3bd3dc, 0x04838268, 0x29c9ecaf, 0xc04d9c43, 0xa14ac3b3, 0x9e9569fb }, + { 0xaa42e5a4, 0xbb8de644, 0xe2fbad26, 0xb4f18e48, 0x41a01be5, 0xcc95bfb6, 0x6e290d98, 0x54ef8bb9 }, + { 0x557d2b0f, 0xc03e88e6, 0x31a790c3, 0x3e5b6c76, 0x384f0b3e, 0x5ecb5bfb, 0x3d1eebfa, 0x5a577c70 }, + { 0xefa29a64, 0xaeb96331, 0xb2506e50, 0x0265949b, 0x3661408d, 0xee4c9b95, 0x566514f6, 0x992efa98 }, + { 0xb857ab5f, 0x7344d3c3, 0x19c63a4c, 0xe300cddb, 0xd035ef79, 0x3896caf6, 0xe158c43e, 0x8dbc225d }, + { 0x068826a8, 0xd11ee115, 0xaa0ab267, 0x048465b3, 0x83182d94, 0xc85a7925, 0xbc9d9148, 0x210b0520 }, + { 0x3e3a9c6b, 0x58154277, 0x69480d33, 0x8b127ac6, 0x9695e140, 0xbd936635, 0x25598547, 0xe30bd43f } + }, { + { 0x7cad6446, 0x95a8b12a, 0x7e99a163, 0x4e37e1af, 0xaedd8c8f, 0x48e82405, 0x02760ae2, 0x052e92ad }, + { 0xd42bd45b, 0x852604cf, 0xc82662e7, 0x8a7beec6, 0x3f9c480b, 0xceb76563, 0x55618792, 0x1d15b81b }, + { 0xc1e2c23a, 0xbbc03599, 0xb40bf076, 0xa7d81174, 0x55ecc4a5, 0x8f835e17, 0x97cc9058, 0x1f4ecbe2 }, + { 0x36e56936, 0xfc602ae6, 0xe4a1f50b, 0xca0d76f6, 0xb9231453, 0x88142240, 0x91fb92dd, 0xfaa0f736 }, + { 0xb11e5cf7, 0x4bbf80a4, 0x83fbdd5a, 0x629f9d4f, 0x70d3c5d3, 0xa4eff842, 0xb125d786, 0x451c95c6 }, + { 0xa0f9942d, 0xe7d77dd5, 0xa6ce3b5e, 0xad6fcb24, 0x1539fa38, 0x2e5d0014, 0x5647ff4a, 0x423a9cb4 }, + { 0x24328e01, 0x70060c5f, 0x9b5a2980, 0xd50c0456, 0x438b644e, 0xa6218f3e, 0xa8d29a0f, 0x55422c30 } + }, { + { 0xeb474cf0, 0xafbf75b9, 0xc178f2dd, 0x013eba8d, 0xae6078ae, 0x2f7148ac, 0x04d72dd3, 0x3b32798d }, + { 0x1c9f7c13, 0x2e631041, 0x2e4eee2c, 0x9aeeda94, 0x4377bcf4, 0x61803184, 0xe391eba9, 0x96f42e58 }, + { 0x0eebe52d, 0xc91b4fc4, 0x5529752a, 0x2911a0a8, 0x6883a4e1, 0x51d04140, 0x9d01d854, 0xf444746b }, + { 0x8ac7d066, 0xa5a93de8, 0xe336fdc2, 0x2b761cce, 0x2cb54674, 0xab52a8e5, 0xb7dc527d, 0xe28ebf7d }, + { 0x3ca84f2d, 0xdc63706d, 0x26604804, 0x0e2c42f1, 0x80c296c8, 0xc4a2dfbe, 0xeccef3f8, 0xdab00a20 }, + { 0x8891ba41, 0x3e0e1b3c, 0xa09a5bb9, 0xd9b10dc7, 0x12b39656, 0x681e834e, 0xb9464ce3, 0x7192d163 }, + { 0x555ccac0, 0x1b00b0a1, 0x747895e5, 0x5a4d1735, 0x685e8c2c, 0xd71cabd1, 0xc3f9edcc, 0x8f605d24 } + }, { + { 0x5d113432, 0x14505ae6, 0x7e65171d, 0xe5be1eb8, 0x09be54bd, 0x351bcff1, 0xee556201, 0x4320d056 }, + { 0xc7b6fe77, 0x7142a781, 0xd495ce94, 0x5ccd5b51, 0x097a7639, 0xd1b25366, 0x0b825916, 0x1f260e3a }, + { 0x6720ef61, 0x0d59a364, 0x06701add, 0xa51e08d6, 0x4db86dfe, 0x851fec4d, 0x137632c7, 0xcb292d71 }, + { 0x6608db77, 0x05c12056, 0x9b6b9b8e, 0x663d1ca1, 0xea7ebbc4, 0x564ddea8, 0x846212b1, 0x00b2e9a2 }, + { 0x57bba25b, 0xac6c79dc, 0x219f6138, 0x0507e8ae, 0xdaf7cf28, 0x315ab3d5, 0x32b289fa, 0xf2454aeb }, + { 0x345627e9, 0x277f5979, 0x7a570d80, 0x17d5be7b, 0xc1440ddc, 0x658d2d8f, 0xe6b2b033, 0xd3602918 }, + { 0x17266765, 0x63ddc898, 0x0b05da78, 0xe152732f, 0xbc07c329, 0x87308d49, 0x3533e92c, 0x13eef96b } + }, { + { 0xa6c74d3d, 0x5d63a5aa, 0x51ae38db, 0x3d664af6, 0xcca792ec, 0xe791594e, 0x5be4e8e4, 0x99f0af24 }, + { 0x66b45eff, 0x7d379b93, 0x35d9b9a7, 0x16f91660, 0x4c956d91, 0x28713dd3, 0xb0eb8f4d, 0x2b032bfe }, + { 0xc62649d0, 0x00df64e5, 0xa2da756e, 0x860f7c30, 0x9981d44a, 0x01eafed5, 0x51c2e658, 0x32b5df2c }, + { 0x56b139b3, 0x646f9505, 0xc046145a, 0xa89967b8, 0xfae495e5, 0x270d71ef, 0x477609f8, 0xc0130ada }, + { 0x82b8424b, 0x859a29d6, 0xfb1eab86, 0x682ce815, 0x4b094923, 0x2dfe7331, 0xd8e76c85, 0xcde77a35 }, + { 0x9e54ae94, 0x094dea2f, 0x6c4c1390, 0x99533a59, 0x10bff3d9, 0x45519ab8, 0x4e2b992b, 0xd6176a5c }, + { 0x95af2c5c, 0x49f92253, 0x967d73bc, 0x0f61c08b, 0x7e9cec0b, 0xa7b307b4, 0xfb7b21a3, 0xbe14ff9a } + }, { + { 0x8723d3ae, 0x0685750c, 0x019ac1cc, 0xd8de6a78, 0x5245a0fa, 0xbffc9e9c, 0x54167623, 0x807b1fef }, + { 0x81d8ad6b, 0x1bc10c9f, 0x33dda32b, 0x9812cf0f, 0x118e61e8, 0xab7e63f9, 0x1ae26ae1, 0x2af400e7 }, + { 0x3ba2ba53, 0x1d5846e7, 0x6e0065a0, 0x65bc2ef2, 0x50c29f8b, 0xca56af02, 0x94db5052, 0x7faf0110 }, + { 0x9340b038, 0xdaf2d479, 0x5cf279d7, 0x5300ad9e, 0x9a8df77c, 0x8fd4d109, 0xab00e821, 0xd13741ec }, + { 0xbf78239c, 0x7a6294b1, 0xd0905760, 0xd081bc37, 0x9a80f393, 0x4409d5f5, 0xa335c219, 0x7534be30 }, + { 0x97bac5b6, 0x714065e0, 0xe34b0574, 0xb0113634, 0xb0e83f51, 0x68290903, 0x111c481f, 0x570c6a9a }, + { 0xedf21139, 0x210b3de6, 0x6328dd9d, 0xb9ed6795, 0xf1949875, 0x0896ccba, 0x49526c34, 0xced20c3c } + }, { + { 0x50d016f3, 0x35841280, 0x0d682f63, 0xda54752a, 0x7416aaf8, 0x8ffc7525, 0x05d9e6a0, 0x5fe2c49b }, + { 0x5b84a3ed, 0x57737bb5, 0x58d8cf79, 0xe7ae800f, 0x5dc807da, 0x8b0864dc, 0x85c4aabb, 0x737e8715 }, + { 0x6e369e4b, 0x7d12c140, 0x11cef4c4, 0x026e1284, 0xd1297fea, 0x143dd929, 0x8ae3107f, 0xdfd92b43 }, + { 0xb68776fa, 0x5c43271a, 0x5bfb7545, 0x20115576, 0xec463b15, 0x5716ac16, 0x0a742f44, 0xdc10394c }, + { 0x93ebe0b4, 0x31cab089, 0xf703d6de, 0x8ddb986c, 0x029d5034, 0xf5919be6, 0x344acce1, 0xa7178be9 }, + { 0x02393f14, 0xcd4bd587, 0xe49523e6, 0x45b76377, 0x3189378b, 0x129a5480, 0x596844a4, 0x13bd0af1 }, + { 0xc1fbf5e3, 0x20b83b42, 0x94c122b4, 0xea35bbef, 0xa84afaca, 0xc7cede92, 0x2aa55379, 0x4e715526 } + }, { + { 0x191d8c25, 0xedf49bef, 0xccb166d9, 0xd31bb302, 0xd1394fc0, 0xbc7ac47f, 0x4ff9b145, 0xb2286167 }, + { 0x3cc6005d, 0x5af08c2d, 0xf0d13ff7, 0x086b72bb, 0xc23601a7, 0x34382607, 0x7a191b49, 0xb5e8eca3 }, + { 0x1256e971, 0x3ca1f021, 0x2a9fba8a, 0x2efffe72, 0xf8893912, 0x88287c58, 0x3047063e, 0x0ce6dbfe }, + { 0x0f596308, 0xdce19d18, 0x0b3aed5f, 0xe1b34628, 0x3c5e3471, 0xc610c449, 0x013b0569, 0x13d206c6 }, + { 0x7b5b0c08, 0xafa73f2c, 0x1afe34cb, 0x8e4352ef, 0xf0c9a492, 0xb1dd9c52, 0x8a3dbe85, 0x511b2068 }, + { 0xd0f7eeb5, 0x3cb65baf, 0x1ec371a6, 0x2652143b, 0x029c4b2c, 0xf4395f73, 0x070a8617, 0x1a41bd3a }, + { 0xe38ce7ed, 0x0999053d, 0x539b38c4, 0xe4a4ddb8, 0xfc3a29fe, 0x79ab63ab, 0xcd7bef5a, 0x39d51032 } + }, { + { 0x99ffd9e0, 0x6a7b6286, 0xd372442d, 0x2609ce72, 0x31b21b14, 0x1982853b, 0x0253796f, 0x4195e147 }, + { 0x94cf706f, 0x4219043d, 0x4948bae6, 0x4975184d, 0x51e72be6, 0xd00e181d, 0x5532c4bd, 0xe3e3d1bf }, + { 0x3a9511a4, 0xbce6a9d0, 0x322e27d5, 0xebed073a, 0x475bc71d, 0x77886f89, 0x57e25cfd, 0x0b8783f7 }, + { 0x86101a79, 0x88593c55, 0xc4d0aaf7, 0x66d0eb32, 0x559782e8, 0x3c738012, 0x779a44ce, 0x464b4901 }, + { 0x02334709, 0xdcd39abb, 0xbd4ba210, 0x1259e2ab, 0xcd81b73b, 0x41f02297, 0x5455c8a1, 0xf93e9f8b }, + { 0x9b00ec09, 0xcd936d0a, 0x6a99eff8, 0xa61b4818, 0x0f3fdab9, 0x924a0e43, 0xb6578638, 0x8f7e2f6f }, + { 0x863b5269, 0xd6873003, 0xd55ba719, 0x478fbd50, 0x06ad456e, 0x753ac81f, 0x2523b4dc, 0xa6c0aaa3 } + }, { + { 0x4c66c5e5, 0x24d70030, 0x1c778675, 0x01e610dc, 0x3318b68a, 0xb1a85bbb, 0xbd8dcced, 0x8386e37b }, + { 0x9a60c9ec, 0xab294812, 0xb9321b39, 0x10c50f2b, 0x583ce8dd, 0x5357d7c9, 0x60982c4b, 0x159157c4 }, + { 0x565dd84b, 0x9711aa2f, 0x7f6aed97, 0x6902c3eb, 0x73e93be7, 0x906585b1, 0xd908564a, 0x13f487d9 }, + { 0x23b1ed6d, 0xa7c43c99, 0xebbfa924, 0xb39c41be, 0x7a6352ba, 0x95747a3e, 0x2b5860f1, 0x7532934a }, + { 0x5eae3d04, 0xd2635222, 0xd1fe4098, 0xc6e2916e, 0xc86209a3, 0x51614200, 0x257b2adb, 0x951c5adc }, + { 0xcdceaa75, 0x7fb1fdd7, 0x891322a6, 0xca72927c, 0x8c2fccfa, 0xd80edf3a, 0x5cefd1e2, 0xbdd2eed8 }, + { 0x7e05a769, 0x81a4e29f, 0x89ef922a, 0x67a9d483, 0x1cab721c, 0x6f5c205f, 0xd102f502, 0x62fcb92d } + }, { + { 0x0e898ea2, 0x276be8c6, 0x20cbd93a, 0x91925795, 0xcc0e1426, 0x52ba9f4a, 0xe229d987, 0x04a4c65d }, + { 0x2985be68, 0x156e43f4, 0xf7e79720, 0x28a8cc8b, 0x1b90a8bc, 0x7acfe7c1, 0x7f2c38f7, 0xb6acd5c6 }, + { 0x11c48ff4, 0x6aaa0281, 0x61d4ecfb, 0x56e5946c, 0x09e507dc, 0x8e28097f, 0xb6e01d0b, 0xec5d2e6e }, + { 0xa9092e2a, 0x8030b6ee, 0xa62c0fdc, 0xe6fd7208, 0x3dae3e4e, 0x8b132548, 0xeef7b14d, 0xbb3e0df3 }, + { 0x366ae70b, 0x8af54a4b, 0x38695196, 0x490f3290, 0x69a4e783, 0xc25128be, 0x776ae4c7, 0xf3432d51 }, + { 0xf46709e8, 0x54b6f97e, 0xebe5ad72, 0x87f1ff2e, 0x2887b42d, 0xef0920c9, 0x9b2c4aa6, 0xaff35ba3 }, + { 0x980fd7f9, 0x4ec40a2f, 0xc67267ef, 0x084fea1b, 0xdc1f9357, 0xc82e5a6c, 0x6a1314d1, 0x2cf10f74 } + }, { + { 0x99e26c1a, 0x21d728e5, 0xa3bf7072, 0x1f867719, 0x9fc2a99a, 0xb3646233, 0xae028ed4, 0x58749d76 }, + { 0x84e31247, 0x3db47c77, 0x71b4ac32, 0x5e017ab1, 0x0cb3a997, 0xe9f22d8f, 0x61b71801, 0x80c3a383 }, + { 0x4fc8b9ac, 0x2c302d55, 0xc43ebde7, 0xafb2c409, 0x3e770688, 0x1ea75355, 0x42fb4ab4, 0x4b3ee41d }, + { 0x75f59943, 0x265beb42, 0x8552f918, 0x33b4cd5c, 0xbbc7e514, 0x4403f804, 0x592622c3, 0xa6c2788c }, + { 0x93954d46, 0x98102530, 0x65ee2172, 0x7c669b58, 0x48acf56c, 0xf12d22d8, 0x613faf21, 0x17cf04cf }, + { 0xa19fc70f, 0x1573fcc0, 0x0ecd8919, 0xafd79ffa, 0xb4b2bb85, 0x396c25e5, 0xd66fe1dd, 0xb2f73398 }, + { 0x175eeff6, 0x49ad4452, 0x393fbedd, 0xa09a5ec5, 0x4e71b848, 0x213bb3fa, 0x5865f497, 0xe0cc2250 } + }, { + { 0xb8c94934, 0x670b1bef, 0x09b597bf, 0xe95bc31e, 0x8f008206, 0xacfdc6b9, 0x697e0984, 0xc8f165d1 }, + { 0x9d1dee97, 0xc2639598, 0x30852fd5, 0x6fa62d83, 0x26fea39f, 0xb79aefaf, 0xf4ed4686, 0xf51bbba0 }, + { 0xbe4a0e85, 0x26aa35ec, 0x4ccb842a, 0x4daffff4, 0x0d0d6c5a, 0xde22570e, 0xda5b8f9a, 0xfb267bf6 }, + { 0x04684f26, 0xc2bc45b7, 0x78a5abe7, 0xd06d768e, 0x6609fb81, 0x10e0ae3d, 0xa939e5f0, 0x5a6caa84 }, + { 0x60e1f53e, 0xe0498ee1, 0x5a7bd7fe, 0x0e9d8a8b, 0xaea7dbe6, 0x78962259, 0xb56982ac, 0xb48924a9 }, + { 0x61f4f72f, 0x877a9b23, 0x80b8fdd2, 0x25076f3a, 0x3cfc165d, 0xb1a27de7, 0x7901f5fa, 0xaca74205 }, + { 0xbacf2caa, 0x2ffd287a, 0x5334c494, 0x6fc2dd9b, 0x8385ff11, 0x8ef2cd26, 0x3c700c5a, 0x883f96e1 } + }, { + { 0x01051c4e, 0xe171a853, 0x1a86285a, 0x54f10ef4, 0x1da6c980, 0x52622da3, 0x543efe3c, 0x5db30908 }, + { 0xd416105c, 0xae023365, 0x6991f58c, 0x6ca8442d, 0xdeebb86f, 0xfe4209c8, 0xdedbc33b, 0xfac9d4c5 }, + { 0x8befef55, 0x7e737cd6, 0x4d15fe13, 0xbd26464e, 0x80a01d45, 0xfd68913d, 0xd8cd8cb6, 0xc4e3c0a7 }, + { 0x96b72ffe, 0x2f8a3b29, 0x6293afcf, 0xaba930cb, 0x73d7bb5b, 0x07785741, 0x0d2b7174, 0x4a90d234 }, + { 0x05399790, 0x4a1f41fd, 0x9a2aedbe, 0xad926eb9, 0x534d3b8c, 0x8fccb936, 0x3ec3f1b2, 0x7bfffd7c }, + { 0x1d78b2c3, 0x88487362, 0x90ef131b, 0xb3e194c7, 0xd644719c, 0x63d94bf2, 0x57a07ca7, 0x3b7393c9 }, + { 0x3b1e3b26, 0xeed89619, 0x1d59f4b1, 0x8f21179b, 0xd2f5636b, 0x3760b2a7, 0xb8cba8a9, 0xe4781ce5 } + }, { + { 0xcdf29b38, 0xcd3ad590, 0xb60b0c91, 0x717c05c8, 0x67187a81, 0xf5e64622, 0x5fe4db15, 0x7caf92c3 }, + { 0x128e22f7, 0x33401a74, 0xbb73f3f7, 0xca39e2a2, 0x6bdbba61, 0x479c43e5, 0x45e71e88, 0x4a7fe7b9 }, + { 0x2bd5149e, 0x6b60080c, 0xa186e4d2, 0x32b3b160, 0x396411f3, 0x498814c7, 0x32af3f37, 0x914e1778 }, + { 0x52021b68, 0xf3f6d466, 0x05127da6, 0x4652a49d, 0xc04af790, 0x5f744134, 0x5469473c, 0x83443869 }, + { 0x3c789666, 0x55706cd2, 0xfb801295, 0x64be40b3, 0x9234d81c, 0x6a10f4d3, 0xe093b370, 0x3119207c }, + { 0x6512ad28, 0xf1762e3d, 0x89252d67, 0x319a33a5, 0x7047d72d, 0xc0cf8110, 0xe1f6a910, 0x5f181a3f }, + { 0xe0df2b52, 0xeccfde41, 0x71b6f228, 0x29a61ba6, 0xc18c6c45, 0xf6c491b0, 0xae634299, 0x60617efc } + }, { + { 0x932a9292, 0xeff3d35b, 0x0b3ffe45, 0x500946d9, 0xba2b8141, 0xf3aef5fb, 0x7fb73803, 0x5dcbed2f }, + { 0x92f928f8, 0xc45cb998, 0x3de973d3, 0x22258ee9, 0x01d0608b, 0x4abfd656, 0x4d05fbd5, 0xd0b317c2 }, + { 0x78a3e9c6, 0x1217d5fe, 0x37e07393, 0xfb4a2b36, 0x20fd014a, 0x9f430875, 0x7b7c72da, 0xe7826c88 }, + { 0x9e05b5fc, 0xc501e9e3, 0xfa5247cc, 0xff84de04, 0x19481bd8, 0xfd63637a, 0xf3aa923b, 0x18ddfc58 }, + { 0x6ff205cf, 0xd79bec07, 0xa0605213, 0x3fb90ac6, 0x38681ef7, 0xcecb097a, 0x992aaef8, 0x3f20406b }, + { 0x675ab4f9, 0x0384623e, 0x120f1482, 0x648bc836, 0xc275984d, 0x80248b73, 0x6343b511, 0x4f498daa }, + { 0xcba41f00, 0x41f24ff8, 0xe0d541d4, 0x2ad5b9db, 0x29fd8686, 0xf9247faa, 0x02dc9f0c, 0xa105f2af } + }, { + { 0x81314e68, 0x2e1bdcf1, 0xf262a0e0, 0xec3cc01a, 0x8b3b992d, 0x85186126, 0xa01b4c80, 0xf68996e9 }, + { 0x6c059760, 0x7cef4355, 0x94b55ae5, 0x46ebb21a, 0xc9652a93, 0xd00edbb9, 0x138854b4, 0x870e9c03 }, + { 0x2c878846, 0x5068ee62, 0x57504c0b, 0xd9992813, 0xad65db9d, 0x7c0540f1, 0xa51cca28, 0xe3f6585f }, + { 0xaae62fec, 0xf80c3b51, 0x1b8612b1, 0x4e1b799b, 0x122e7614, 0x9817a555, 0x076716bc, 0x26989d58 }, + { 0x082f3b0d, 0x2586ecaa, 0x3a68da4c, 0x2ec3a18e, 0x8322210d, 0x5db56d50, 0x21376298, 0x4f059417 }, + { 0xb9591105, 0xe37840ed, 0x65c2316b, 0x54328158, 0x9cb5600f, 0x25ca8e8e, 0xa3a5e15f, 0x490db5ac }, + { 0x0e25fe77, 0x1beb7f0b, 0x9700b7f6, 0x581f5695, 0x5f52081a, 0xf6c0c4b3, 0x4f23c5d2, 0x716b92a8 } + }, { + { 0x0b783206, 0x97197b11, 0x4466fc8d, 0x51e8e947, 0x529a9831, 0xbce64097, 0x84f78505, 0xdec144e7 }, + { 0xebadc492, 0x5c26fd40, 0x55a0109c, 0x22dd0942, 0x62869e2d, 0xdd67b5b3, 0x8dbad1b3, 0x74764f31 }, + { 0x63a0093d, 0x7361b487, 0xc4f3ec81, 0x73d62b5e, 0xf6443a90, 0xca47e3ff, 0x7fbf1f12, 0xe0d6064e }, + { 0x64b54365, 0xc74d838e, 0xd1a72c2b, 0x0cd37608, 0xba5a2b7e, 0x24af5dac, 0x7934ed42, 0x41f1d7f7 }, + { 0xa50c28eb, 0x7c8fccd8, 0x991d713d, 0x56143506, 0x83019cbf, 0x3e5e8c40, 0x268e8649, 0x42b96750 }, + { 0x115f1a44, 0xda6af568, 0x5818c25f, 0x7cb2cd39, 0xc41f0b4d, 0xb1d5c52b, 0x9d334364, 0x4b5c5bf8 }, + { 0x2887d927, 0x4cb784ae, 0x3f6be83a, 0xdc299f50, 0xa76bf296, 0x059ca3dc, 0x3387ce95, 0x24032c4a } + }, { + { 0x646c61ba, 0xc00dcebd, 0xffe8d48e, 0x1d5ef5fa, 0xdd03068d, 0x945c4a55, 0xc21478e5, 0x6516f79a }, + { 0x51081670, 0xc9480411, 0x45a2ac72, 0xfbe68ae9, 0x4dd25a6e, 0xb6901f20, 0x3fe634d3, 0x1109ba3a }, + { 0xaa1a199e, 0x4ce5679d, 0xc61856b5, 0xaad329ce, 0x888fed04, 0x54a92ce4, 0xec166331, 0x3cdcee30 }, + { 0x9b37df4b, 0xc643bb79, 0xf74d8080, 0x383f1d8d, 0x97ad1010, 0x6beccfca, 0x80835164, 0x57f51a36 }, + { 0x5ee2f501, 0x17c2f152, 0x985fb43a, 0xdf1a3cd0, 0xe332791c, 0xdff602d3, 0x579b3d44, 0x0f92d59e }, + { 0xa6dde8a6, 0x17dc2f83, 0x264d9a36, 0xe850c137, 0x8998dbe7, 0xc815c3a7, 0x5464c2b6, 0x41b6fddf }, + { 0xf1aa98e6, 0xa0b61792, 0x66788403, 0x75ce08b9, 0x705eba7e, 0x1cc8f43f, 0x8eead44a, 0x1effb035 } + }, { + { 0x63c1a59c, 0x3bb92ed9, 0xd993927e, 0x9115e792, 0xb999dbd2, 0x8f704232, 0x1809f9c6, 0x58568b74 }, + { 0x843124b6, 0x3c5ac0ef, 0x72e5d4ce, 0x846f817a, 0x6406ae45, 0xb2fe706d, 0xfb578605, 0xd86d22f5 }, + { 0x18938e86, 0xb285e7b3, 0x3ac87243, 0xbf1034e3, 0x2935a723, 0x442238df, 0xf189475f, 0xf485ec70 }, + { 0x794c2f0b, 0xd9aa1f95, 0x6e5cd411, 0xe1a66971, 0x42c32329, 0x4c25c3cb, 0x7786e163, 0x157466bf }, + { 0x97c86d73, 0xbf0a1063, 0x78b33005, 0x533de701, 0x34465c03, 0x39a03557, 0xddaa24eb, 0x3f68ca61 }, + { 0x0942210a, 0x8d29e6db, 0x0838c1c3, 0xe56b9e13, 0x781aec92, 0x49b12a6a, 0x33822b38, 0xcc81a41b }, + { 0xef40d172, 0x258f6a46, 0x7ab0a0ab, 0xd11b65e4, 0xa96ab13d, 0x6071d3f9, 0x6367b09b, 0xaf81b190 } + }, { + { 0x1b12c93a, 0xb2dd19c3, 0xc0baacf6, 0x9ac0736f, 0xa783871e, 0xab4c0c38, 0x512aef74, 0xd99a41ce }, + { 0x532aa8f2, 0x84ca4f04, 0x9f0d7c8d, 0xc529d10b, 0xa1a50d2c, 0x3dfc8bab, 0x156082d3, 0x031047a0 }, + { 0xf4f340e0, 0x8b2c1235, 0x758ad17d, 0x371b86f7, 0xcdd54fb6, 0x66df8eec, 0xd9790d57, 0xe484bc36 }, + { 0x00ff11ea, 0xa18fc2fb, 0xd897f75d, 0x81e0aaf1, 0x14326937, 0x7ea19d16, 0xd7980e5a, 0x8fc84e35 }, + { 0x14085ef0, 0xbed40a19, 0xa51cfb5c, 0x60f36e68, 0xdf33b423, 0xa612b2c7, 0x92c9a789, 0x061ba596 }, + { 0xb825a48b, 0x1c8d8307, 0x8adab13c, 0x8ffefbb8, 0x4fd180ae, 0xd7fc5b87, 0xddd5e548, 0x6af66526 }, + { 0xa8e14ddd, 0x78386471, 0xb9e89d93, 0x55e2f08a, 0xc2940906, 0xf1f8c9c5, 0x5352536d, 0xdf4d29c4 } + }, { + { 0x1a65e954, 0xa7c05781, 0xa622c36e, 0x39d1ae36, 0x3555bdac, 0xde1e7007, 0x499ab88a, 0x26e6758c }, + { 0x2423409c, 0x59f027d6, 0x53c01054, 0x99470ade, 0xf0445032, 0x42440709, 0x5762f300, 0xaf3f6e9a }, + { 0xfafe7169, 0x3821c260, 0xefe2db29, 0xad298c75, 0xa234e203, 0xaad5d774, 0xded608d3, 0xfc0a9d07 }, + { 0x6a8dc5ef, 0x0b50ff0b, 0xaa1e37df, 0xac63532f, 0x60cc05e3, 0x4a17918a, 0x3e498676, 0xdb55dbbf }, + { 0x3d2e8493, 0x858c6360, 0x1291fa48, 0x9da94500, 0x0575d135, 0x17b22353, 0x8755aeb8, 0x3a36fa91 }, + { 0x235ffbc9, 0x37884622, 0xc0b1a257, 0x2f4e75bc, 0x48b33b2c, 0x4e94a5fb, 0x57e26314, 0xca8db664 }, + { 0x76223077, 0xaae3cbc6, 0xb53e20bc, 0xf021fca7, 0xf4f70531, 0xdd3e20a1, 0x018908ee, 0x6ac4e5ec } + }, { + { 0x4bab2a03, 0xa4c894ad, 0x0718b9f6, 0x76505aa9, 0xa704a1ab, 0xe31d6d72, 0xe0b7d7e8, 0x82335d70 }, + { 0x9248c598, 0x05d14ef5, 0xb22196b6, 0x104dacfa, 0x5eb00a04, 0x65e5780f, 0x553d2bcf, 0x9a6faf4e }, + { 0xe7a84b80, 0x21ac8ab2, 0x0a97b8a2, 0xaa6c8ab8, 0x85d6ca44, 0x4912fc2f, 0x8ce532e7, 0xfd1ec6f5 }, + { 0xe0a3214d, 0x8b83e16d, 0xda1c1077, 0x6ecfd613, 0x6c44d10f, 0xa0ed0247, 0xbe6524e7, 0x9906e540 }, + { 0x6b901287, 0xff9fc5c9, 0xa169de09, 0x5aa704b5, 0x0c9a1708, 0x853969ef, 0x02a6a2c5, 0xfd22434b }, + { 0x011df8ab, 0x933987be, 0x4d8e33cb, 0x8a75575e, 0xa0df5ed3, 0x4afedf40, 0x72d973b4, 0xf0d715e5 }, + { 0xc649a341, 0x8c8ec585, 0x09e36ffc, 0xcae85482, 0x604b9358, 0x503619cb, 0x1838af3d, 0x9d311908 } + }, { + { 0xf992ef53, 0x3cc38b82, 0x484ac38b, 0x9cc29b5b, 0xad102612, 0x7167bdd8, 0x65013993, 0xcd0b9518 }, + { 0xc068a679, 0xdbd71611, 0x84c06e92, 0x9a66ae57, 0xb777ed35, 0x86279007, 0xd7297091, 0x70281626 }, + { 0x568a2bb1, 0xc2fc8f0a, 0xbeeb279f, 0x40e630bf, 0xd56a039b, 0x2a9e70a0, 0xc887842a, 0x22ad73ae }, + { 0x9f78ad15, 0x7320e353, 0xb005eebb, 0x7421e0da, 0xc04ddf75, 0x6f86e369, 0x6c43d7f5, 0xe8fe1ced }, + { 0x7745d97e, 0x0f4a15dd, 0xbc58b766, 0xa4ece092, 0x145a85f5, 0x617ef632, 0x5c29cc7f, 0x88f2ebe9 }, + { 0xa90241df, 0x69968208, 0xca3d5230, 0x260eacca, 0xa30ed8b1, 0x5065816a, 0x23a7b3bc, 0x08ffa2cb }, + { 0x1343e3b3, 0xf7ec9a56, 0xf6b95938, 0x9d75ab58, 0x4b919a32, 0xd0990f77, 0xeb3d0c3c, 0x03393c17 } + }, { + { 0x10404354, 0x24f4c527, 0x3bb936db, 0xe43c0af9, 0xcfdfae66, 0xd0c59040, 0x87c94698, 0xb1dfe449 }, + { 0x862620a3, 0x5a6bd6f3, 0x6715861e, 0x1794e287, 0x6f547703, 0xca52a892, 0x66b712ae, 0x92cedadf }, + { 0x5f632648, 0x07ed8aaa, 0xebc99ea7, 0x67e35f3e, 0x45df92b2, 0xf810d6db, 0x6594292b, 0x719dc0df }, + { 0x02517129, 0xc066cf91, 0xfee400ed, 0xe5a33177, 0x2451fc04, 0x8716cc17, 0x0e85aea9, 0x830b89a4 }, + { 0xc21ba7c2, 0x5cef1caf, 0xee257ad9, 0x4f17bc91, 0xd401c758, 0xae51df62, 0xa9dc2ebc, 0xb3b40e36 }, + { 0x9719e474, 0xe8d19d46, 0x00a43966, 0xb200e08c, 0xfb39eb35, 0x059d9c51, 0x8330589c, 0xdd55cfc1 }, + { 0x3816a521, 0x2b5440f8, 0x58a9d434, 0x38a1a222, 0x4299eeae, 0x4656a036, 0x178a14b7, 0xd8f66ba6 } + }, { + { 0x8e53e611, 0x0f80a4ec, 0x75cfc563, 0x7700369f, 0xeecfd38e, 0x4a84d294, 0x5fadff27, 0xedf0779d }, + { 0xd96a8adc, 0x824055e9, 0x73bde8d0, 0x28d6d0ce, 0xed5e9eac, 0x5a9d9c29, 0x3abbd71a, 0xf12ca86d }, + { 0x9a2903fb, 0x6fe15fef, 0xec292d65, 0x5ae89ee4, 0x07fb2b6a, 0x5e351b88, 0x5f3e661b, 0x3ea971b1 }, + { 0x4fb07aeb, 0xb3b1a129, 0x2e472f43, 0x4b931c8a, 0xe068fde9, 0x62c838e0, 0xb39f7053, 0xe38fb1fa }, + { 0xe8cfca5d, 0x5ee9bd31, 0x7bfcbd2c, 0x072b9b2a, 0x066bc2b3, 0xc90fcd92, 0xd7591916, 0x70bc9042 }, + { 0x7334d25e, 0x061f383c, 0x2ca2313d, 0x7c17e1ba, 0x95d4650f, 0xc323f32a, 0xf356fcba, 0xd7487659 }, + { 0x3de5961a, 0x1a9c3578, 0x5ab5e3a6, 0x332485f5, 0x81a763fe, 0xa1732747, 0xe00167bd, 0x9827e68d } + }, { + { 0xaefa11d9, 0xb23ae1b4, 0x6c5daa24, 0x466f709f, 0xdc2135de, 0x529c6d42, 0xd855a0d3, 0x01264bd5 }, + { 0xc61834ee, 0x61bc622d, 0x1e80ccdc, 0xa99991bf, 0x8ad8d302, 0xcb03b0bc, 0x51c27a3c, 0x61b7310a }, + { 0xf5aeb48b, 0xfce399cc, 0xbc6a2065, 0x9cdbe1d2, 0x4a5fb6f8, 0x6a0c024d, 0x666405ad, 0xe9c533c8 }, + { 0xf25d6ba5, 0x5a1e5f60, 0x9a760f26, 0x9a9ccfe7, 0xcbf1a84e, 0x11156e2a, 0x1ec8bad5, 0xa1abd1cd }, + { 0x429af8ce, 0x2b48afbd, 0x37c15970, 0x206a828e, 0xc1329c16, 0xab26ea1f, 0x079d8f0a, 0x040b51a4 }, + { 0xb1ce4771, 0xf0cad81c, 0xa50f6d62, 0x4e99cf63, 0x3d8949a0, 0x0d4fcb9b, 0x95f934f5, 0xa415e3e1 }, + { 0x2bdd8d6e, 0x566864c5, 0x73b6ec02, 0xb4272efb, 0x49a004e8, 0xd1149d77, 0x4cebcc5a, 0x456af3c1 } + }, { + { 0x081a5e5c, 0xbf7b8d4c, 0x8a34b5a9, 0xcdab3950, 0x7c623160, 0xc109ba89, 0x7bdb53aa, 0x9d5746c3 }, + { 0xa7176883, 0x41412b90, 0x474c53f8, 0x38c66dde, 0xcb6d77d1, 0x6f0a0c72, 0xb176acf4, 0x84750024 }, + { 0xe7d61ac6, 0xd53fce6d, 0x9d9d8914, 0x7276e969, 0x4a22f072, 0x0d3c37dd, 0xafbe355a, 0x85a80a9b }, + { 0xea5b16bd, 0x74126074, 0xad6a0091, 0xda26ae8d, 0x98119213, 0x4ed94ccb, 0xf91293e7, 0x83f0444e }, + { 0xd977cdc4, 0xbb396ccf, 0x156a3abc, 0x5049c8cb, 0x97e3fc76, 0x22ca279b, 0x6e6c56eb, 0x4a40aafe }, + { 0xcbbad741, 0x653712ab, 0xedee190c, 0xd65124f7, 0x35cfcf9e, 0xb8e45ecd, 0x247c0f70, 0x92d9f67a }, + { 0xf1078520, 0x62a505c4, 0x386d72e7, 0x4379a48a, 0x5c861e43, 0x82f93962, 0x0612ab98, 0x8e762b88 } + }, { + { 0x2b76d2f9, 0x219985b5, 0x48931209, 0x61e9b92c, 0x61b7df20, 0x3a5a19c7, 0xfb1cae89, 0x86e6fe6f }, + { 0x17a9e8bb, 0x24a69d1e, 0xb5fffedf, 0x645c05ee, 0xe465a371, 0x1cf0922f, 0x8e388d71, 0x6f7fb175 }, + { 0x539bb5ba, 0xa74025bc, 0x73a17687, 0x7e4034e7, 0x36a340a3, 0x3fc47343, 0x38c42333, 0x28e0a705 }, + { 0x60047445, 0x9b413b57, 0x22ad7abe, 0xd001a44f, 0x38564b8b, 0x3e430299, 0xa338d922, 0x3fdc8bae }, + { 0x10d5667c, 0x4b20b75a, 0x05c9d00d, 0x2436660e, 0x6d7bf446, 0xa8e4ab1e, 0x6ebc7ad2, 0xa80f7b71 }, + { 0xf82ad2d3, 0xdc4e138c, 0xb95a5c58, 0x135a2af7, 0x90e78650, 0xa05971b3, 0xfa7654e6, 0xeb040cb5 }, + { 0x7e55a09c, 0xa598b530, 0x66e2e492, 0x007cfbdd, 0x2a7340a3, 0x49eded4a, 0x8a2c5120, 0x745aec01 } + }, { + { 0x4ccdf6a1, 0x21cf2074, 0x70ee181c, 0x37614987, 0xdce26256, 0x388e8a20, 0x82e33a58, 0x1f8871a0 }, + { 0x9ac567f4, 0x2cab290a, 0x7a2940dd, 0x9d2921cf, 0xa7212702, 0xdba2aba3, 0x7b042b48, 0x2ea6c00e }, + { 0xb6602eca, 0xf1ccffc9, 0xa427b9e3, 0xce865444, 0xe955470c, 0x5c35353d, 0x886cd178, 0xb1154347 }, + { 0xbd7ee6c7, 0x986f0ceb, 0x515006d4, 0x928a9ef0, 0x3e19b199, 0x9e2b9d82, 0x2ba5734d, 0x78d35037 }, + { 0x8dfc34f4, 0x736270df, 0xae0c15e3, 0x039845bb, 0xdc0cdd6d, 0x8d629822, 0x115f4087, 0x0e40c8d1 }, + { 0x02d5be7f, 0x3b52feb2, 0xfdeb0f90, 0xf335fe9b, 0xc4ee02d1, 0xe1b0a73b, 0x973b1c29, 0x28608143 }, + { 0xd64024fe, 0x07bfee3d, 0x958b2586, 0x20c30d61, 0xfff7a1be, 0x1424dbb0, 0x41d63aea, 0xa7d2d7a5 } + }, { + { 0xc98697f2, 0x27a9da0e, 0xbe1c3c3a, 0x6015249f, 0x43310088, 0x25551fd1, 0x9ed53bc8, 0x01a59dbd }, + { 0x43b36f5f, 0x14d0c574, 0xb004b813, 0x0b342110, 0x8d8821bf, 0x2d460e2d, 0xdb423121, 0xe38d515a }, + { 0x0c48988e, 0xc75214a1, 0xe2d41374, 0x914e23e3, 0xffa76150, 0xf4d0d7a0, 0xf91f0d58, 0x5dbe80f6 }, + { 0xa1717fdb, 0x83473287, 0x5d83adb2, 0xce07c3f5, 0xd7b4bfd8, 0x802e2d18, 0xbd8d8aeb, 0x2a615f35 }, + { 0x281f4fc6, 0x3234cada, 0x034c9096, 0xad333584, 0x9e3d1089, 0x8d67adc8, 0xc73bb490, 0xb96d864c }, + { 0x81dfe927, 0xda7658b5, 0xe2b7deba, 0x28e959d4, 0xf976f0a4, 0x87efc7ad, 0xc8427d0d, 0x90ffa985 }, + { 0xce2e2e31, 0xdea7ac97, 0xe7d99d04, 0xb7b80fa3, 0x40c3196a, 0xa23ec559, 0xeec1dd8b, 0x50e94257 } + }, { + { 0x16823e73, 0x25e516fc, 0x9dd99658, 0xc3b2403c, 0xe96ada4c, 0x9445eea9, 0x0574f922, 0x8b0e0b50 }, + { 0x170a5242, 0xd545ee9e, 0x335d861c, 0x8a625319, 0xd06d63c0, 0xc1c65bea, 0xb289999c, 0x97fb323e }, + { 0xbdbf594b, 0x4563538b, 0xf6f5cb1f, 0xc3e7a6a1, 0x1de4a672, 0xca09428d, 0x5ad346d9, 0x5295de9c }, + { 0x7142b211, 0x6bf87d2a, 0xe77b09ce, 0x555dbb4d, 0x06b5dc50, 0x173c489a, 0x1b505203, 0x4fe9fd5e }, + { 0xd1eca554, 0xdbf55b7f, 0x4c58cf78, 0x57fd262d, 0x911d6812, 0x2dfe41cf, 0x09568fda, 0xb43f0161 }, + { 0x79e9f3ba, 0x7dc0c6f0, 0xca803919, 0xf2466fef, 0x71940a16, 0xc7d5d56c, 0xf379bba3, 0x8bbeb5e8 }, + { 0x6d78f71f, 0x57474240, 0xed1d6588, 0x0272b8fa, 0x42e317d1, 0xa6fe3539, 0x034ea5de, 0x91253223 } + }, { + { 0x6ce8fe52, 0x4ee4b0ba, 0x269731c9, 0xb1a91780, 0xc17611d4, 0x69ccbe77, 0xac119be5, 0x9761c6cc }, + { 0x800ebc6c, 0xd6d229c3, 0x66224169, 0x43ce27ee, 0x4e06d545, 0xd69a4e2e, 0xbe60d266, 0x2fbc0760 }, + { 0x04c13deb, 0xddcc671e, 0x940baff6, 0xed011b83, 0x1c65639e, 0xbf75ebb5, 0xdc29f3a9, 0x948a6594 }, + { 0xb6723312, 0xec575e5e, 0xc920d4da, 0xea1221c4, 0xa1c8f1ae, 0x6574c37f, 0x521325a4, 0xe5630b6f }, + { 0x9be8b91a, 0x34e5bae6, 0x94b150e1, 0x0a37a2fe, 0x93bc6749, 0xdc446168, 0xbd31bfdf, 0xea785db9 }, + { 0x433d561c, 0x1d8f451c, 0xd6821c12, 0x4cceace7, 0xd9f909d7, 0x05e270ae, 0xd959db7d, 0x26018b37 }, + { 0x78fbfb74, 0x864c7746, 0x7e96fc07, 0x3d73ae5e, 0x37117671, 0xab04044a, 0x7b2f215d, 0x5d34c951 } + }, { + { 0xd6e67082, 0xed83d10d, 0xf9b603c4, 0x330f14a0, 0xa2348071, 0x3d51d623, 0xbf803f9c, 0xf5c3a860 }, + { 0xdbf2e1fb, 0x3b9073d2, 0xa397706e, 0xaf6e444e, 0xd8be2c7a, 0x50917c13, 0xa6c15612, 0x1d2d723e }, + { 0xaedff564, 0x41062f20, 0xddbf7f08, 0x8ebe5ab0, 0xd2624d9b, 0x558c4f3f, 0x4fc8fdda, 0x030d8626 }, + { 0xe9f80171, 0xd04fc302, 0xc1a18b1f, 0x5175f1b0, 0x6b31de78, 0x489a4108, 0xc0f2a21b, 0x1da22bc9 }, + { 0x69c0783f, 0x468e72e1, 0x539684b0, 0x6eb35caf, 0xb2c8491d, 0x3461d505, 0x4008c3b8, 0x950079cc }, + { 0xf430e5f9, 0xc4af2bc3, 0x27a623de, 0x30b9f603, 0x9583a5d3, 0x0fe2d753, 0xb7192a77, 0x7672f83c }, + { 0xea036fc5, 0x8f910668, 0xfbb488e2, 0x4df1da0a, 0xcc8f5f0c, 0xe9cf02d8, 0x4ea68b8b, 0x92930726 } + }, { + { 0x4aafdde7, 0xad1e6f18, 0x6fc2b1f4, 0xc3c3bfbf, 0x28158ddf, 0xcab597d3, 0x0ee80ca7, 0xad689ef2 }, + { 0x31cef4a5, 0x2a0ac024, 0xba8befc7, 0x323bd99f, 0x0d4adee2, 0x741edb95, 0xc38ebf1e, 0x2e4bf40a }, + { 0x54731b39, 0x9c520b83, 0xd236cfc2, 0x8d28fed1, 0x595920b7, 0x9e64833a, 0xf9033166, 0xb791aa52 }, + { 0xb973e426, 0x031a763a, 0xc8a491a7, 0xf971a850, 0x29a57431, 0x9f98ab85, 0xe810c441, 0x1aaa9b17 }, + { 0xe07a56bd, 0x5b3a650e, 0x8524c1bf, 0x581b9853, 0x620e2528, 0xcbd9f18c, 0x464e0c76, 0xe8a8757b }, + { 0x4ba36244, 0x8dc29cab, 0x82dd5d98, 0x2e00d727, 0x1b403304, 0xcfb9ef02, 0xb23c2e18, 0x53272334 }, + { 0x85b8badc, 0xd3f3460a, 0x1f2d54d8, 0x6be53442, 0x4d3a4c57, 0xc6178f09, 0xdaac120d, 0xa21d32b5 } + }, { + { 0x5e7eec3c, 0x6882c2c4, 0xf71e281e, 0xee5a05db, 0x49160328, 0xa581f536, 0x999bcfc1, 0xa32183f4 }, + { 0x4d495226, 0x1d7fba98, 0xd63e0443, 0x1d3bbc2b, 0x63efb7b6, 0xb8fb692c, 0xf439fdd7, 0xb57cb60b }, + { 0xacbf8e52, 0x9b63af75, 0x555229a2, 0x01bff2cd, 0xf58b87f3, 0xb3665332, 0xc46db843, 0x522862e9 }, + { 0xeb3dd86e, 0x85cb0d88, 0x252ac387, 0x2c647271, 0x64f64274, 0x8aa0d8fe, 0x24c5c742, 0x6ba50abc }, + { 0xc049057d, 0xf1c1679b, 0x75366f81, 0x61691771, 0xef711e26, 0xb656c670, 0xd81e2e48, 0xf0e4b55b }, + { 0x8762038d, 0xc80e0c4f, 0xf30b867e, 0x19fadbdb, 0x9a6eb859, 0xc9901d8f, 0xa8c35c86, 0x7ab2b2d9 }, + { 0x3338cff5, 0x71256102, 0x5bbc92b0, 0xec61ecb6, 0xf8d91011, 0x085ae7d4, 0x8fd0eb3a, 0xe8afda76 } + }, { + { 0xc79d0663, 0x2dd58140, 0x0aa57d16, 0xf29eb584, 0xebffc367, 0xb5aaf495, 0x5f301fbd, 0x51ad05f3 }, + { 0x5d9e5289, 0x1f286da7, 0x1a8c5a78, 0x1981633d, 0xf535283c, 0x558fd1c4, 0x10042322, 0x694cf23d }, + { 0xb1b46bc1, 0xa366e94a, 0x432e1e2d, 0x29bd0258, 0x4c4a1386, 0xee6519ea, 0x8c1e7b8b, 0xe581d895 }, + { 0xf10c0f6e, 0x8b6ae220, 0x013190cc, 0x00648767, 0x3b7eaecf, 0xbd665c98, 0xcd8bb5e5, 0xcdca837c }, + { 0x855b26dd, 0xa4b21f40, 0x55f19d81, 0x683941bd, 0xe9d853f7, 0x5a251186, 0x8e63352d, 0xd93882fc }, + { 0x50196950, 0x3cc10d94, 0xdf247d3f, 0x7d6cd59d, 0xe2bdcfb9, 0x502f37e3, 0xf78c2b7a, 0xa29b4210 }, + { 0x82240993, 0x12a37c93, 0x9dce0ce4, 0xe532a6f4, 0xfcd872f2, 0x1e744eaa, 0xb68ded30, 0xa6e98a08 } + }, { + { 0x214bb8bd, 0x59052c09, 0xe306850e, 0x61426107, 0xcae574dd, 0x6f0d63ef, 0x36b7f4e6, 0xc4b1972e }, + { 0x44a5854e, 0x37506e54, 0xe43b0c19, 0xd89f4371, 0xad9b0797, 0xdae323b6, 0xfb38db63, 0x343a5bbc }, + { 0x4c3a1778, 0x38f81b63, 0x41e50711, 0x3273fbdb, 0x6cf133ab, 0x5fdbafc5, 0x7e62f53d, 0x8337b5d3 }, + { 0x577cc2c0, 0xf1740a61, 0x195f8d70, 0xc1be9818, 0xf6f046a7, 0xb22ff8be, 0x70434280, 0x9e969483 }, + { 0x7f54aff4, 0x29b2c1db, 0xb7932d31, 0x0e26725c, 0xa4ce3e46, 0xb8d03f15, 0xc1961766, 0xcbecbdfb }, + { 0x7b1da3e3, 0xd7091ce2, 0xd960bd1a, 0x24e3ee4b, 0xbccb3083, 0x9947ae94, 0x995b66c3, 0xfecdca8b }, + { 0x9efdb08e, 0xe6dd1bb1, 0x8afc22ba, 0x689c98ca, 0x5aa1d1e6, 0x9280486b, 0x1a06ff70, 0x35f3bd61 } + }, { + { 0x94a57dda, 0x34e514cb, 0xdba2cc3a, 0x5f80b789, 0x567d9dd8, 0x8e42abfe, 0xda4ed86d, 0xc3d85a78 }, + { 0x643a54ab, 0x64f1459d, 0xbe4f3752, 0x78e0c1fa, 0xd308c46d, 0x79e906cc, 0x9ee16ad9, 0x077f4792 }, + { 0xb17b2cb4, 0x7b1893a0, 0xd513db0f, 0xd05a576f, 0xc0cb40f5, 0x4d7f6b17, 0x89869ade, 0x3ef3f6ae }, + { 0xa8f1033f, 0xb5fd68fd, 0x8b1a8db3, 0xb191a33e, 0x353afd73, 0xeab792ce, 0x2ccac580, 0x3901d267 }, + { 0xe945d74a, 0x5a35669a, 0xa3e4a8ce, 0x7c09320a, 0x9d6a6e73, 0x839886a0, 0x0e87039a, 0xd4afcfe7 }, + { 0x35cd99c9, 0xd0e5ea21, 0x7aaf6e80, 0x28a91f14, 0x0441f916, 0x3bcd7836, 0x5f8c06b8, 0xf6d2804b }, + { 0xab421ed4, 0xf564b8c9, 0x03a9e168, 0x98c0e130, 0x9cd0b92d, 0x3c212ef7, 0xcd6eab71, 0x295b1bd6 } + }, { + { 0xe3e9bef3, 0xd7078eb9, 0xfa2d0da2, 0xfaebbc87, 0x4d66df4f, 0xd1655e36, 0xa6b5f78a, 0x3f7c7c98 }, + { 0x1e7cddbc, 0x17a3975a, 0xde48e2b9, 0xab04c4a3, 0xbf5bc034, 0xf7a44143, 0x5ae8fa9c, 0x3cb216d4 }, + { 0xa019805f, 0xa77c68ee, 0xf27890d8, 0xd67c0c27, 0x06cd297b, 0x525f68e9, 0xd994da58, 0x8672b823 }, + { 0x25936f1d, 0x764ff4c3, 0x89a06966, 0x2a1f98bf, 0x075af8ea, 0xa404022e, 0x959f5c8d, 0xa3959fd1 }, + { 0x9000b509, 0xe18ff73a, 0x7baefdee, 0xec7a734e, 0xb432ea34, 0x8ef1f3d5, 0x2e367966, 0xfcc949cd }, + { 0x414a9e4e, 0xddffb7d9, 0xa4b135c0, 0x08df6e92, 0x7f7978fc, 0x94231a01, 0x38020d36, 0xfd92eba4 }, + { 0x759e8e7a, 0xbd0732bd, 0xbddea280, 0x58540b21, 0x7dc30c3e, 0x3d973558, 0xaf1b393f, 0x51aef09f } + }, { + { 0xd42396dd, 0xe4fc4aba, 0x65bc2ccd, 0xbf3304ca, 0x102ba45d, 0xcece783d, 0xe822c515, 0x20ac124a }, + { 0xe3a2ed92, 0x540fbdcd, 0x3f9dbd6d, 0x9433f437, 0x397752e1, 0x405d2a30, 0x39fdda96, 0xef8289f9 }, + { 0xca813a68, 0xa7ddb8c6, 0x547fb559, 0x34e56453, 0xa126ff41, 0x17de4c37, 0xf5dbee4b, 0xaf01f51a }, + { 0x7076cd0c, 0x5f821a2a, 0x04d3eea6, 0xb2337628, 0x5007b53b, 0x99aba859, 0xfe51ab35, 0x84947d16 }, + { 0x49c1c968, 0x4c48f0f3, 0xed1bfa43, 0xfb7d0f41, 0xf0ae229c, 0x89da4d80, 0x6dd79b29, 0x5e00c5ed }, + { 0xb0082f0a, 0xfa0f5285, 0x7283e3b2, 0xb0525247, 0xa6891967, 0xca18af05, 0xd39acddb, 0x8b6dcece }, + { 0x75bd1834, 0x2370c61a, 0x97219a21, 0x1e1d5e8c, 0xd2c13a0b, 0x5118e51a, 0xf0c505cc, 0x375a4fe0 } + }, { + { 0x3d5b5b5b, 0x0589f6d5, 0xa3c37341, 0xd670ef28, 0x9b9fdb69, 0x645e417e, 0x34b4aae4, 0xf765eab9 }, + { 0x4624f839, 0x15dad0fc, 0x9111f388, 0x55c88aaa, 0x442ffbd8, 0xbe495f3d, 0x44ae469c, 0x30de013b }, + { 0xaac2eb7c, 0xe5794d57, 0xa0ca448b, 0x6a1210e0, 0x7c679e81, 0xf7ffbea7, 0xde3946f2, 0xa9eca4ee }, + { 0xc9f4e052, 0xf416895a, 0x0cb616bc, 0x12e5cfc1, 0x92ed36ab, 0x7c81330e, 0x4f0efa6c, 0xe2c49453 }, + { 0x6c459920, 0x62714bf8, 0xb8a261e3, 0x053756e7, 0xa42cc894, 0x9eb30492, 0x56800cac, 0xb907900a }, + { 0x5f24390c, 0xd7e25199, 0x092cd43f, 0xfe2e825c, 0x9fff7769, 0x09b2696b, 0xd9a104d4, 0xc27fc111 }, + { 0x8adb1b35, 0x12a267f9, 0x4523b897, 0x66eaaa9d, 0xb9676202, 0x46367165, 0x866f6ddc, 0x8a8578df } + }, { + { 0xd973534a, 0x9229bdd9, 0xf870bc7c, 0xaa8aee13, 0xa10181a1, 0x10f5d3e1, 0xb70bcaba, 0x8af542e4 }, + { 0xdc2609ae, 0x5efaa091, 0x36bde5f7, 0x6f6562fe, 0x847fac9b, 0xd4e11101, 0xcdd8ba8b, 0xe0314e9e }, + { 0xcb64a375, 0x8b1d9dc1, 0x63e83023, 0xae29b9b0, 0xdc501c4a, 0x526ebc1f, 0xb4cb680a, 0xe55b8753 }, + { 0xd06b0247, 0x84203428, 0xcf2f04c3, 0x30e549ea, 0x07526bef, 0x4e70b090, 0xf8eff8e7, 0x247c5e1d }, + { 0xe3ac7058, 0xcc88d2d2, 0x1b34d2e2, 0xb6f23bd8, 0x6087dcfe, 0x329cc986, 0xd03984a0, 0xd10a2c00 }, + { 0xb3c8a556, 0x332e4152, 0xe06e0545, 0x3bb6b291, 0x2eeb5851, 0xaa1f5c5c, 0x869490cc, 0xa895bb2a }, + { 0x1d7fcbfd, 0xb9c86437, 0x641aceaf, 0x30e395db, 0x43cd9993, 0xed4a0f7f, 0x05a4ade1, 0x8a174e00 } + }, { + { 0x06f6c8f5, 0xaa7b65e7, 0x824883d1, 0x0426a4de, 0x17eb4593, 0x582897a3, 0x0d97066d, 0x4d6a6207 }, + { 0x7b6c49c5, 0x8a8cf0c1, 0x7cfe2755, 0xf3107513, 0xf6f4810b, 0x3e4e07bc, 0x1d8f6691, 0xebabbe33 }, + { 0xcfefe6f2, 0x85c9c6fa, 0x8627fefe, 0x51f8f2b6, 0xae0b9e9d, 0xe9ec84ae, 0xa5eee553, 0x8c89d70b }, + { 0xf46e9a45, 0x79319572, 0x6deab445, 0xfd1d2456, 0x7bb0ee16, 0xdb4bb4f4, 0x90f34afd, 0x5504ecf4 }, + { 0xcdffaea5, 0xdce1d9ca, 0x7c1a656a, 0xeab322a7, 0x38cc7850, 0xcdf0ae68, 0x91eba6bb, 0xc3422707 }, + { 0xb707b5c7, 0x51aa0c8a, 0x0d3915d5, 0xd5d3a321, 0x17eca512, 0x711135b9, 0x02a41edf, 0x0730519b }, + { 0xb6a57c9d, 0x00832995, 0x2cfb27e7, 0xfe9ada6a, 0x7b53f507, 0x934fad67, 0x040ea387, 0x32b1d122 } + }, { + { 0x869f3699, 0xb7a0f364, 0x2a224e69, 0x219fa3df, 0xbb5b43db, 0x85a3ee48, 0x0f3b20d3, 0x530b39b1 }, + { 0xce48e6b2, 0x5eb8caef, 0x906856ed, 0x10015a5b, 0xde1a90ae, 0xc5e20921, 0x535a150f, 0xd598d4df }, + { 0xb8f11262, 0x58784fb1, 0x65de8c60, 0x181f3950, 0x5eff1757, 0x2307d418, 0xf435b9a7, 0x3b480d73 }, + { 0x887329c1, 0x0fe1c5fc, 0xe5343697, 0x3b8f7c71, 0x9d796838, 0xb60ac1fe, 0x3efb57ad, 0x1a3cafc9 }, + { 0x33e228b4, 0xc45a4a97, 0x5c0d163f, 0x4723ff85, 0x901ee6e8, 0xa556fcd5, 0x653dacbe, 0xcb039bba }, + { 0x1c1a4895, 0xddbd9d3b, 0x6305c0f5, 0xfcdb872e, 0x1c8cf92c, 0xc905dcdb, 0xd12f12b3, 0x8a08cf36 }, + { 0x36366045, 0x1b00aa3d, 0x275996ef, 0x185a2d1e, 0xf1a5d3aa, 0x097b2a88, 0x316a8a21, 0x3e88ecd2 } + }, { + { 0x04dfd426, 0xd8457dcb, 0x611c6c3f, 0xab0594cf, 0xb56df625, 0x46d51ff2, 0x76322d50, 0x00661fde }, + { 0x0117c123, 0x4a1234e4, 0xdaceaaef, 0xda0de23b, 0x4c68554c, 0x89708fd9, 0xb515bb8a, 0x303e5c75 }, + { 0x74349f95, 0x0ddaf2c2, 0x2ab299e0, 0x4fcb2065, 0x6f93ade4, 0x61258430, 0xd2a529ab, 0x66831f66 }, + { 0xf0823bc7, 0xc4b97ff5, 0xd4654764, 0x488ddf0b, 0x00bb1d8b, 0x40e80366, 0x33f7997b, 0xf0022f6f }, + { 0xcad79cd9, 0xf77b16db, 0xadd94936, 0xf8a210e9, 0xde1f34ae, 0xa9b09c22, 0xf934bbdc, 0x76891837 }, + { 0x9b543cd4, 0x46aeee91, 0xda445bd1, 0xedcf72fb, 0x86b1e7e2, 0x214a30fd, 0x5f67a563, 0xe77fd81c }, + { 0x56ac0d36, 0x84f516fc, 0x548bc83e, 0x62e00da0, 0x9736c949, 0x4a62c624, 0x254f3bcb, 0xa63e272b } + }, { + { 0x4ce55c56, 0x52e60ad7, 0xeb3194ce, 0x50384fed, 0xaa0b71be, 0x5aec83a4, 0xb2e5bb6d, 0x5f4b87b5 }, + { 0xfb6bf270, 0x989eefb7, 0xbe447eb2, 0xee56d6b2, 0x0fb602cb, 0x74dc6a16, 0x6708393e, 0x299cfcce }, + { 0x5983adae, 0x7170c129, 0x5ffd2fe4, 0xc7c51be4, 0xab4db93d, 0x9b13f8a1, 0x0576e1d5, 0x0133b97f }, + { 0xd330c619, 0x97cefae3, 0x08a51e25, 0xff52936b, 0x2bb317e6, 0x8e410395, 0xa2abe512, 0xe560f31e }, + { 0x91e0085c, 0x707fb7a8, 0xe5e921b9, 0x75f44359, 0x3a7d4dcf, 0x1d8c9b2c, 0x4f0beacb, 0x7f47a8af }, + { 0x3c39c379, 0x3844ef9b, 0x980fcd5b, 0x1f827adc, 0x3606cc65, 0x027406aa, 0xbb92a12a, 0x4d820976 }, + { 0x61c9b499, 0x0af292b3, 0x4dc48844, 0xd75639ec, 0x6b47ba27, 0xe9b8232f, 0xec2bfc5d, 0xd48772c3 } + }, { + { 0xaa3a7768, 0xa9923913, 0xc9a4253f, 0xf9d54a62, 0xb461a77d, 0xca4cffa1, 0xcc7d6220, 0x7bbe40c3 }, + { 0xcb7b1279, 0x4e37b168, 0x0e2fc824, 0xe0bba404, 0x045bfb7e, 0x9c058a66, 0x7b76ad22, 0x4f4fa3ce }, + { 0xc1e03d01, 0xd6dc7650, 0x3d4d4b28, 0x255b5d53, 0x3cbf2f49, 0x8dfeac4f, 0x86b7cb23, 0xb6d9cef3 }, + { 0x402b43ed, 0x39c30e4f, 0x09c662c9, 0x04e9881b, 0xf70d86c2, 0x9b1a752a, 0xb8a59b39, 0x29885a2d }, + { 0x035473c5, 0x2ed39e06, 0x86c4bffd, 0xdd4ffb36, 0xfd87b924, 0xc420e0d8, 0xed1e4957, 0x7c8100a5 }, + { 0xacc88481, 0x143f7290, 0x2448e118, 0x923bd5cc, 0x0c41c4f2, 0xdf9301d1, 0xce90119c, 0xcbdc928c }, + { 0x4780f6d0, 0xc6c88d50, 0xb28ed989, 0x675eb0a9, 0x8006b4d8, 0xd4c94d1a, 0xc708fbfa, 0x558611e9 } + }, { + { 0xcafcb6c5, 0x742d27cf, 0x326d8490, 0x0c932a56, 0xc6fa5228, 0xf9a43400, 0x9c15e051, 0xfaf1d7db }, + { 0xacf2dcbc, 0x85abeee9, 0x0ec49808, 0xfe7dc863, 0x1e263e23, 0x04d681c6, 0x98a9b7b3, 0x2ad596c5 }, + { 0x0caa2751, 0x846dcb5c, 0x04b85d6b, 0xe8b0bf65, 0xe45cbd45, 0xe65f8e88, 0x62162b5f, 0xf7b03b5b }, + { 0x7e02448e, 0xc18cbf2e, 0xa8f00089, 0x1297fd3c, 0x224dec7e, 0x985bc5d0, 0x014f4cc1, 0x02344936 }, + { 0x7470bf5a, 0x5d4f9515, 0x8877fc67, 0x6af5878a, 0x06004ece, 0xf846c5be, 0xa27d7ba8, 0xcc1b1636 }, + { 0x8a6f7afd, 0x9e55b768, 0x1abbef11, 0xe2dc66cc, 0xb4fb3c41, 0xbccdc9f8, 0xa94bab38, 0xfe515287 }, + { 0x54eccc0f, 0x7d33ca23, 0x616aab17, 0xad32de5b, 0x24823796, 0x5348c258, 0x5143c9d6, 0x55941476 } + }, { + { 0xff926d03, 0xdfe6bd0b, 0x7133d012, 0x1730d8d4, 0x4e2a9b71, 0xf42bd662, 0x2babb7fa, 0x75b93b24 }, + { 0x25c6bb3a, 0xfd0de901, 0x06bfe425, 0x5476eceb, 0x9a8e9974, 0xab6eb44a, 0x01d3d3c7, 0x6ab3381c }, + { 0x897fd029, 0x92aa33fc, 0x636c8893, 0x45bfa236, 0x9e494c98, 0xaad0920d, 0xce1e1ad0, 0x0ec52f2d }, + { 0x05da4481, 0xef53168b, 0x589201bd, 0x27c04b7c, 0xfae00f06, 0x226672f8, 0xd2a24848, 0xdb48b2a5 }, + { 0xaf1e6e52, 0xc0d66eb6, 0x716f6f84, 0x2f993a9f, 0xe08a9bf1, 0x0ba346bb, 0x07796a53, 0xa90c0e4b }, + { 0x30eca339, 0x1f6171b3, 0x513e7e27, 0xab1a77bb, 0xde3c1c49, 0x2696bd6f, 0x91631039, 0x3b8a1b4a }, + { 0xb8384d6c, 0x856458a6, 0x8ca3805a, 0xae1937b4, 0x7a23ec5b, 0x24237653, 0xf7dd0b6f, 0x1e6b5437 } + }, { + { 0xdd201ef5, 0xc7bbae08, 0x04aa9b04, 0xda770b53, 0x1dc59e72, 0xd1055c4e, 0x0db15e0e, 0x8e5ea443 }, + { 0x629137a5, 0xbc9f5510, 0xc526680d, 0xd1be741f, 0x578e2a7c, 0x6297930a, 0xa9ef7a5a, 0x81607f43 }, + { 0x4f322772, 0xb6c64f9c, 0x5d99f6c8, 0xf2b683e6, 0x50f7add0, 0xa31cc440, 0x46688ddf, 0x87e0b044 }, + { 0x19ba3b0f, 0x9c252df5, 0x2b3c7363, 0x22f61964, 0x7ec403a5, 0xf60b0224, 0x6b32ccf0, 0xca66258e }, + { 0xb1c7df24, 0x82ba09e4, 0xefd34517, 0xa137d1c1, 0xbf986d1b, 0x632567ac, 0x10af96e8, 0xd3619154 }, + { 0xac8e70e8, 0xf51bb0b8, 0x9cb7a9b5, 0x4e154450, 0xd1cdf7a1, 0xd3cc4aeb, 0xa3be7bdb, 0xbc602064 }, + { 0xa727791f, 0x4c937102, 0xac298cd8, 0x1ca7a882, 0xf4ad2dbd, 0xa1226327, 0x37d216ab, 0x1963ff50 } + }, { + { 0x883173da, 0x23e6fde8, 0x5cb323a4, 0x7f64be00, 0x904d3e49, 0x50bf674e, 0x6a5d7369, 0x271c1ac8 }, + { 0x6d12d716, 0x1e4aa290, 0x83148617, 0x4a57d1b2, 0xd2d2eb56, 0xfa59047b, 0xcc42aa9c, 0xe75139be }, + { 0x4ce3057f, 0xa14696c9, 0x3df0a01f, 0x0a4347ce, 0x0e761790, 0x56107292, 0x4237b7c4, 0x8bc97af6 }, + { 0x1e8fe687, 0x0827af6c, 0xce989c8c, 0x5625e561, 0xd3fd9e62, 0x24c80381, 0xd393ffc8, 0x26156972 }, + { 0x9cec5f14, 0xb1d5591e, 0x740ef0ee, 0xcb0582c0, 0x84db94ac, 0xc9d0550d, 0x23974ba9, 0xfd225a78 }, + { 0xfc02f9db, 0xc65d470f, 0x4af43a3f, 0x048f5be8, 0x8844b325, 0xc224c1ff, 0x29a88a71, 0xae3bbe8d }, + { 0x14577832, 0x9b6e8d7a, 0x424c193c, 0x6c8ec12f, 0x648e40a5, 0xb3072ba8, 0x952a1e03, 0x01a41c9c } + }, { + { 0x4f9e89c9, 0x059bd6bc, 0xe1724241, 0xb8390db8, 0x6264bd07, 0x7286e102, 0xafe24351, 0xec4d8f15 }, + { 0x1efb82dc, 0xb2d37a8a, 0xae9d98db, 0x22b12e63, 0x2f2f20f1, 0x0671e722, 0x602efc49, 0x285e1eb6 }, + { 0x36ae4c87, 0xa69d53e9, 0xc7e9a3d1, 0x9392a787, 0xeda31c1e, 0xebdced8a, 0x1bb574ed, 0xfc0ffba5 }, + { 0xadaf5b7e, 0x3cbec253, 0x08d4e073, 0xa6ca7185, 0x817749c2, 0x08e552e1, 0x89478771, 0x09fac11a }, + { 0x4d1b95e6, 0x19ab29b6, 0x0df3377e, 0x49df1272, 0xf574298a, 0x5cdeb60f, 0x8b97defc, 0x7da8ffa9 }, + { 0xe22919aa, 0x2b102fea, 0xd6de0fa7, 0xd82fd943, 0xad3fb73e, 0xf314097e, 0x3ffbcb8d, 0x2a2b479c }, + { 0x5c11cdd8, 0x367b92f4, 0x6b4ee87e, 0x81f554b2, 0x046b41d1, 0x4985a82a, 0xc004855f, 0xad1de15a } + }, { + { 0xe7169f5c, 0xbd1ba144, 0xc149b708, 0x7f54185e, 0xbc204785, 0xef6fbccc, 0x68fd45b8, 0xe8932dfd }, + { 0x698b48ce, 0xd2108117, 0x0e82895e, 0x2e1e0f83, 0xbe2640fe, 0x24264ae9, 0x480d9483, 0x058f8811 }, + { 0x0745c2c0, 0xa5de3147, 0xbe466299, 0xd749825a, 0x0d3cb5de, 0xf85ed138, 0x64c07737, 0x95ce0552 }, + { 0x1ff9c508, 0x3afd6c4e, 0xb7158c82, 0xb388f9f0, 0x2a7ff5c4, 0x99a6689a, 0xb4af8235, 0xb1054152 }, + { 0x2b457c79, 0xec319ebd, 0x3b0dfef1, 0x27bbe811, 0xc9088a0f, 0x0156537c, 0x3d0c8922, 0x31004ac8 }, + { 0x182fe7e2, 0x4aa600b3, 0x9380201d, 0xc7c52130, 0x96539850, 0x79e9742a, 0x2046af9e, 0x5bf607c1 }, + { 0xd96c4bb2, 0xcffd6dec, 0xab6b7d91, 0x4180ad19, 0x608ffe33, 0xdf7806d1, 0x7591cf11, 0xb77318d8 } + }, { + { 0xbd0c6ae1, 0xb0c0d491, 0xe6879544, 0x84d9d47e, 0x0a3c547a, 0x31c255ee, 0x5d8cf93a, 0x51e796eb }, + { 0x7ed47493, 0x47b333f8, 0x13c4aa35, 0x3f50b35e, 0x67d9770b, 0x481196b0, 0xe6169cbd, 0x0822fad8 }, + { 0x373cab1d, 0x414bb7bc, 0x4fcf49ff, 0xba1470dc, 0x52fda29d, 0x28fee38e, 0x2f09b1a1, 0xac6bf20f }, + { 0x018deff9, 0xd940e676, 0xde860481, 0x1ed81388, 0x2e321995, 0xd381c800, 0xae39aec6, 0x5c1e0964 }, + { 0xc4f62878, 0xa400869a, 0xf29f2e90, 0x9ac2b169, 0xe64aed0d, 0x68f182cd, 0x4e71336f, 0x4e647b8a }, + { 0x0b500d5e, 0xbac12fa9, 0x96544435, 0x04b74dab, 0xab2d04cb, 0x241588b2, 0xa111b1bc, 0xa36bf9f2 }, + { 0x19dcc2a1, 0xf91ff95e, 0x17d421f3, 0x35834062, 0x1a52ab19, 0xfc73404f, 0xcd4face9, 0x4e65a9d0 } + }, { + { 0x7d905776, 0x7fa64df4, 0x819bf900, 0x46b0febb, 0x9c3b9149, 0x20faae1c, 0x9a93a9f0, 0x4823f136 }, + { 0xdee292fa, 0xee9dbcf7, 0x77d20122, 0xad71d94c, 0xc5f8156d, 0x415f40ad, 0x15ce83fb, 0x55d7c6aa }, + { 0x31ec30aa, 0x722c93e8, 0x68b618a3, 0x1a9e450d, 0x10f91b46, 0xa1ae7c50, 0x36d06874, 0x19cbca27 }, + { 0x3006b80c, 0xd07fc788, 0x0a3b47ed, 0xd52f127b, 0x54588daa, 0x946a4177, 0xa72ec354, 0x1a420308 }, + { 0x8eb890c5, 0x3627eb6d, 0xbfc0dbea, 0xa7a0ca38, 0xe150be82, 0xbebac52c, 0x2fe40cc8, 0x68014ffc }, + { 0x4baaeec0, 0x959d80a2, 0xa4d3c4be, 0xc8020043, 0x5d3789ee, 0x9de0226e, 0x7ec985f6, 0x7a1729f4 }, + { 0x1ffcc6d1, 0xce7d6162, 0x589492e2, 0x774eb246, 0x7f84649b, 0x1f30ad87, 0xebd3736d, 0x66b45d24 } + }, { + { 0x2bfdc739, 0x4435ff09, 0x5abf9a09, 0xa09ba351, 0x23039ed1, 0xf08274f3, 0x44366513, 0xd145df3f }, + { 0x54e6ed6b, 0x5560f57e, 0xe7b1923c, 0x9a1bd173, 0x8257b048, 0x8c391d84, 0x71d63d0e, 0xc43c537e }, + { 0xaad32313, 0x8effced3, 0x1be1fbde, 0xb6810c2a, 0x1d05f895, 0x78785c2b, 0xb3e93cac, 0xcb1a970e }, + { 0xcc379fef, 0x53ba81f1, 0x4479294b, 0x82f4602b, 0xd7bb3747, 0x28218975, 0xa21d5880, 0x1c5e6a04 }, + { 0x96d20a1d, 0x17472cfd, 0xfdd4feb4, 0x7b2e351e, 0x294d3cca, 0xac0a72cb, 0xff199aa4, 0x897afb32 }, + { 0x00eb79ed, 0x86b45ac1, 0x1c661135, 0x39ce9c2b, 0xbe5d6bee, 0xdac61f22, 0x92b80578, 0x94e611b7 }, + { 0xd2e5ca47, 0x520e5d56, 0xca015d2e, 0x17682243, 0x44fa80d4, 0x7fcb5ed9, 0x93b5da78, 0xbe5a1e6a } + }, { + { 0xf64e7bb2, 0xf1b40d71, 0xdb95a0cf, 0xa7427a13, 0x00eeb19f, 0xbfe4dfc8, 0x81c86d91, 0x5dea2b64 }, + { 0xb4a2432f, 0xd6b9ac8b, 0x40edf752, 0x34c85473, 0x460084d7, 0x8f057c59, 0xfc69f8d1, 0x1a5821ec }, + { 0x30c6d9e9, 0x4592b470, 0x015100a6, 0x6088ca9a, 0x9078c364, 0x3f74ce1e, 0xe3a99e5b, 0x49ff4ed1 }, + { 0x2c22243a, 0x76105001, 0xc5dedf8b, 0x5899cee5, 0x0fc4aa65, 0x8cea7e5b, 0xbad31416, 0x9fd5e8cf }, + { 0xffde96b8, 0x2cb2513f, 0x69bdcb75, 0xadda751a, 0xfc878284, 0x41eeec31, 0x32be6996, 0xf338aa41 }, + { 0x08afd0b8, 0xf634fc79, 0xedfdecb7, 0x189835f8, 0xf36edfa9, 0x1bc64382, 0xa9d0062b, 0x48c5ca1e }, + { 0x74828ae8, 0x61347f83, 0x8d1184e9, 0x8ce93f98, 0x77063d03, 0x25d91ee2, 0x734dda1e, 0x0bffe123 } + }, { + { 0x48cd2249, 0xda5e265a, 0xea457dde, 0xfab3845d, 0x07c87c47, 0xf142b310, 0x619974eb, 0x3fda1991 }, + { 0x32deee86, 0x7d3c5f5f, 0xe6083af6, 0x712a9911, 0x02e92d1c, 0xa867c00f, 0x60448c43, 0x94d3ed65 }, + { 0xaa7c3f13, 0xa6da91ef, 0xa90d6687, 0x00750ad2, 0x077fe68f, 0xac66be1c, 0x4700d554, 0xb5f6b43c }, + { 0xb7a0240b, 0xe2e23986, 0xc9475212, 0xc601e7f2, 0x7da3f5b2, 0x0bd4f294, 0x88d75e02, 0xd20e2a9d }, + { 0xf4afece9, 0xb9be01f4, 0x4010957c, 0x8047cd65, 0x81e53b5c, 0xb5bdd825, 0x67f2ed52, 0x09f6c6d5 }, + { 0x838d9fd0, 0x0f0d2641, 0x90a2f8af, 0xf32ec1fa, 0x5bc2d3a9, 0xf8aab816, 0x31e03159, 0x9b74c12c }, + { 0xea6777b6, 0x4ffc3392, 0x62588020, 0x12d1984b, 0x0b5ee289, 0xa9328408, 0xc2f7c7f9, 0x024d72fa } + }, { + { 0x2e4869ab, 0xc983b221, 0x53e81011, 0x40971816, 0xef018c8e, 0x899ef941, 0xb57ad0d6, 0x4623643d }, + { 0x844ca100, 0xf6f30c97, 0x4e55c01c, 0xfc33b704, 0x80032170, 0x87f69c86, 0x0bd0351a, 0x1cae03fb }, + { 0x8c7fde9e, 0xb35c205b, 0x713bfa73, 0x18ce5013, 0x224e587e, 0x7384805a, 0xf74734c0, 0xaae6e9a8 }, + { 0x4b901787, 0x9ea2deb2, 0x2318f61a, 0x7cb7fd28, 0xed12db62, 0x0404e851, 0x4a40222d, 0x923c2bb9 }, + { 0x3857637e, 0x56e215f6, 0x0de5907e, 0xbef391b3, 0xa3a6b9a7, 0x4b69f44f, 0xff010423, 0x234456b0 }, + { 0x849d6444, 0x28a7d0ee, 0x56ec8fed, 0x949f5897, 0x78ae1368, 0x1603c679, 0xfc15c6e8, 0xc2684a29 }, + { 0xdcf9a449, 0xa31c2276, 0xd678c269, 0xba89cd2f, 0x6b0d0715, 0x4b83c765, 0x6daef79d, 0xf4924608 } + }, { + { 0x4815cda0, 0xbdb17fc1, 0x09ea48d1, 0x882839be, 0x17ac3f03, 0xe1991523, 0xc4a38292, 0x8fa8750d }, + { 0xf409da81, 0x804715e9, 0x69ee1c33, 0xee5eed67, 0x4be92654, 0xfbc93307, 0x8538da2e, 0x8e0ae979 }, + { 0x5db8c378, 0xfecf36f9, 0x438c7445, 0x4b4a9cc9, 0x4367e325, 0xcbb85d85, 0x8d072360, 0x2b3080ae }, + { 0x0d2f6168, 0xbc3e881e, 0xd99d9a78, 0xf68f3a05, 0x3d5ac3ce, 0x5b16c5a7, 0x53401e75, 0x30800a49 }, + { 0xe037731a, 0xbea53cd0, 0x5d9da59f, 0xae83f24e, 0xb38823c4, 0xa09a0710, 0x34c2013b, 0x968d9192 }, + { 0x2755ef23, 0xfbb66fef, 0x5535a324, 0x6bb8de77, 0x79b3663a, 0x67c99d31, 0x550e7333, 0x7681b6d2 }, + { 0x7bb74e2d, 0x621c9ae6, 0xd2b20ed1, 0xc5df49b1, 0xb8f9304f, 0x56d1addd, 0x3d72cdba, 0xa35798dc } + }, { + { 0x5f50103c, 0x3b5a6c15, 0x3b70314e, 0xace5e6fc, 0x4d252093, 0xb059d352, 0xb46aba2e, 0x4e72733d }, + { 0xe59b2322, 0x17c297db, 0xf5e29f26, 0x54468a74, 0x2b764c9b, 0xb5f79e65, 0x965b9355, 0x5800a03f }, + { 0x4cf1dc9e, 0xab50c859, 0x446a4dd5, 0x42bc5ad8, 0x446b5c6a, 0x386b2e7c, 0x026357c9, 0x6ad6f0cb }, + { 0x004569f1, 0x24848ddd, 0xced6a93d, 0x2d3f3706, 0x22e40924, 0x039c749b, 0x8f2c5ea8, 0x3f95eb08 }, + { 0x50000280, 0xc814deba, 0x22afacb7, 0x408b4d3b, 0x759bf8b8, 0x3b41eee8, 0xdac665ce, 0xd0780982 }, + { 0xba30fb96, 0x2d94c9ec, 0x9ef85da1, 0xdd074fab, 0xda4e3e35, 0x14634d91, 0x23cbcf31, 0xbba66b2f }, + { 0x0b3ba8d0, 0x7a1aebd5, 0x7638bf10, 0x19e733a7, 0xe34ff3bb, 0x50261a8a, 0xb20d5612, 0xfe940b6e } + }, { + { 0xd63a19ea, 0xeb41d895, 0x876b5431, 0x86fbf81d, 0xfc6f5595, 0x950fff97, 0x267557cc, 0x92c57011 }, + { 0xecdb9bb9, 0x92ad8656, 0x93a731f6, 0xb9a97049, 0xf38abb8a, 0x4f131ffe, 0x755c3348, 0x16e2e197 }, + { 0x426f4d85, 0x85128517, 0x47457713, 0xf2a15d59, 0xa4bf5ecc, 0xbd44e847, 0xbaa98231, 0x0955ee08 }, + { 0x2e922b59, 0x8c0c392a, 0x1ef50af9, 0x45b3e3de, 0x02b73ed8, 0x2716a4e1, 0xd23635ec, 0x4062053f }, + { 0xfaa7f367, 0xd78f6c19, 0xdde9b489, 0xaf6513e0, 0xa724dadd, 0x202f5a3f, 0x76c9ad50, 0x62881aa2 }, + { 0xcb824d3d, 0x706148c1, 0x03231057, 0x61d54219, 0xed6e6793, 0x87eefe17, 0x72fce986, 0x562a33f9 }, + { 0x436c7be4, 0x547594e3, 0x845d596e, 0x782ba5b6, 0xefda9b4e, 0xf6c210be, 0x1796b5b8, 0x0444e2fb } + }, { + { 0x8541ab7f, 0xd1b0e586, 0xf12ea8a1, 0x4f291370, 0x39de3b5c, 0x63e42dca, 0xef998a83, 0x1bb2333e }, + { 0x130b07b5, 0x8a38e897, 0x99a0eb59, 0x778e5692, 0x57afb592, 0x5f85e4c7, 0xb7875c51, 0x71cf79fa }, + { 0x3c6d915e, 0x0e17fed7, 0xbc4514c9, 0x2c31f4bd, 0xea4aefa7, 0xfc78db3d, 0x502629fa, 0x41f3ff82 }, + { 0xc327b68d, 0x4db9d88d, 0x5afee674, 0xd4b26a8c, 0x6b7db1c6, 0x7966ee34, 0xbd07f9c4, 0x28f71f45 }, + { 0x3f5870f1, 0xe2c1b710, 0x36feaab9, 0x32382d56, 0xf69eb850, 0x954f57e0, 0x1a7a366b, 0x3358d575 }, + { 0x4d0a3a33, 0x54021251, 0xf441d96a, 0xd494e299, 0xc9c0be8a, 0x933c0b97, 0x39ad3fc1, 0xb8840efb }, + { 0x11674a29, 0x967f5f77, 0xb9c38bf8, 0xff62f9f1, 0xb54850ad, 0xbfd48d6c, 0x0a97a581, 0x692dc8a1 } + }, { + { 0x2f63b101, 0x517395d8, 0xdc9b2abb, 0x37356f76, 0xfdac7227, 0xeee6410d, 0x9def4dc6, 0x0beade21 }, + { 0x457c3793, 0x20e82c09, 0x110010b6, 0xa91cab27, 0x6dfc2639, 0xd3afca3b, 0x025a8857, 0xf0c763fc }, + { 0x9ebc194b, 0x72548a07, 0x3cca529d, 0x66cb1887, 0x7604a020, 0x4aa9790f, 0x12f87e77, 0x7d067c60 }, + { 0x4d00b201, 0x219844d9, 0x6d629485, 0x490e8962, 0x44b0d0ee, 0x6e97d450, 0xf0f86ba9, 0x5dd95c69 }, + { 0x0b62933b, 0x9c5100a0, 0x13bcb065, 0x3ed52fc5, 0x07663012, 0xda3a999f, 0x902748f3, 0x00122aef }, + { 0x1eabbd9d, 0xb9d236e6, 0x42512a95, 0x025ede3a, 0xf8cc871b, 0xbb908f25, 0xee0d53bc, 0x8dc61a47 }, + { 0x6dea9030, 0x1374c6e6, 0x1ee4bbf7, 0xf9c87cad, 0x3cb23226, 0x94a5b971, 0xe1b6378d, 0xeae9e8e6 } + }, { + { 0x580441d9, 0x9115b553, 0x473673b1, 0xa9e2dee3, 0x180ca19d, 0x76add331, 0x765b9d1f, 0x31bebcca }, + { 0xae91ef72, 0x88473150, 0x27a2d0b8, 0x7cbaf4ed, 0xf8df02ce, 0x0ed3df2c, 0x43c44705, 0x53ad24d0 }, + { 0x65800c15, 0xe25c9cc2, 0x1688a12a, 0xba273e00, 0xb5d40545, 0xf40d9922, 0x5919440e, 0x1f2149db }, + { 0x7ef462d1, 0x74e7c831, 0x37a741e1, 0x628960ed, 0x80104d78, 0xcd38a637, 0xacb12572, 0xf7128b8d }, + { 0xbc21c9a7, 0x602802ed, 0xa37de205, 0xf1dac32f, 0x5428ae64, 0xb7078118, 0x614dfb16, 0xaffa6b2d }, + { 0x4d7d48e3, 0x2a0122b7, 0xdac6e5a9, 0x33159bdc, 0x02d660a7, 0xf7939283, 0x81458649, 0xdb9b7684 }, + { 0x12315172, 0x04a82fd2, 0x940f14ff, 0x6e4ab43a, 0xbe2736f9, 0xd0dd1cc3, 0xea0746d5, 0x3eee16ae } + }, { + { 0x1a033ac0, 0x515cf68c, 0x98e00589, 0x3946f914, 0x14802c73, 0x1ecdaaea, 0xc570c750, 0x5829a29d }, + { 0x18fc9df1, 0x345c921f, 0xfe4a264e, 0x04de69fb, 0x3f28160d, 0xd43b01f7, 0x9fc3e5aa, 0xbe97f595 }, + { 0x6538a7ff, 0x797e9d4c, 0x80e8a24a, 0x8badff53, 0xd08aec53, 0x69d90f45, 0x054f1516, 0x16b96c75 }, + { 0xc8ba209f, 0x74a0139a, 0x4168ce4f, 0x93ae49bf, 0xbae11904, 0xed3c3e8e, 0x46607253, 0x15983c08 }, + { 0x7655cdd9, 0xc65c5ce0, 0x3567a4da, 0xb4428791, 0xf72683fe, 0x1de327d4, 0x735b1f92, 0x0b58c466 }, + { 0xf2a5be47, 0x02d072e6, 0x8ff791a9, 0x6cb3a717, 0xd204b478, 0x36e168db, 0x5656617e, 0x8cc69c8c }, + { 0x710fd80e, 0xe836406d, 0xf534da77, 0xa3151cab, 0x89326bd5, 0xe9ba2877, 0x4fe8ea31, 0xd4cea8ce } + }, { + { 0xc584b6f9, 0x8839cb26, 0x169e9d7b, 0x3b591bfa, 0x3340bdf0, 0xa3734a4d, 0xaf75417c, 0x5d690ffb }, + { 0xf644ffb3, 0xf9734c9e, 0x09737ce9, 0x554814e6, 0xd877fae4, 0xaa710bd0, 0x12d668bf, 0xda2c7036 }, + { 0xd1863def, 0xd09c5ff8, 0xd6294b22, 0x2f6213eb, 0xe64b4010, 0x31865ed7, 0x6143de06, 0xdb7391f1 }, + { 0xed981388, 0x6e43fc01, 0xc8c71f20, 0x51903b55, 0xc9d5074b, 0x94bc02ba, 0xf1cc290e, 0xfbe19f16 }, + { 0xefff1c3e, 0x67e02565, 0x3fce573d, 0xc0acced9, 0xe907485b, 0xb700abb8, 0x504e7b77, 0xb858bff1 }, + { 0xb06f7471, 0x39f8b9b7, 0x95ae227c, 0x23bfe932, 0x741b18ff, 0x9370926e, 0xe9785c7d, 0x5d30c235 }, + { 0x50ca57f9, 0x38dd2adf, 0xf613fc5d, 0x8c294ed7, 0xb2426ea9, 0x5596e0e6, 0x2ad84875, 0x350ad8ca } + }, { + { 0x5f8264f0, 0x64167ec0, 0xd90cd567, 0x57d8268f, 0x51c08f23, 0xdde1cf3a, 0x3cb0e091, 0x5410f3f0 }, + { 0x721bda50, 0x950ba07d, 0xb60d4508, 0x06363cf3, 0xa4601369, 0x445c6e45, 0xbcd5187c, 0x614be58b }, + { 0x7912d9b3, 0xea239835, 0x0cfb3934, 0x31f688ac, 0x22bdb30e, 0x528daed5, 0x1e894f9b, 0x706e0395 }, + { 0x1819c1b1, 0x32af07f8, 0x86a9525a, 0xef48b2fc, 0xe0f66330, 0xb191ddfb, 0x5da891c2, 0xd83f78ad }, + { 0x05f6bd22, 0x2b245f57, 0x8610bcd9, 0x6e412ae2, 0xa4dc56c9, 0xd335d60d, 0x7bf503a2, 0xb21bdbcc }, + { 0x4c715050, 0xb2dde657, 0x147ef33f, 0x36352fd1, 0x4bc3b8ed, 0x9c4c12ed, 0x662d3d49, 0x1d3698d6 }, + { 0x2efffdfc, 0x2eb6f5e6, 0x62dde0c8, 0x9d26bcb4, 0x84e61323, 0x7e70a82e, 0xb32e941f, 0xa254113b } + }, { + { 0xa6ff1777, 0x27d251d8, 0x8540a329, 0x0741430b, 0xc7391e0e, 0x3550c395, 0x2fec9b1c, 0xe86fa21b }, + { 0xe2fe7267, 0x33201f35, 0x6cc96327, 0x289298de, 0x62cb490a, 0xa4f2aa86, 0x69875564, 0xc844cb9f }, + { 0x3e2aa917, 0x6b047dab, 0x96b2cb67, 0xd09ba594, 0xafbac62a, 0x0add2957, 0xd448ec45, 0x39812842 }, + { 0x7233ec1f, 0x67bff4cc, 0x34fc2efc, 0x6ab6d126, 0x83fb8efa, 0xb488edac, 0x8a4b8bcb, 0x6234fb79 }, + { 0x0fecd72e, 0x3c3335f7, 0xeb5d72f7, 0xa8ebea41, 0xbb3829b5, 0xe2c9f088, 0x5e37b940, 0x48162648 }, + { 0xf1c5cca2, 0xfefc97be, 0x37496eba, 0xe4c9c004, 0x8f896225, 0x02cd923f, 0xb68be2a3, 0xfa4f4b65 }, + { 0x314331d8, 0x70a8d9d0, 0x0c922187, 0x951be164, 0xd716d74d, 0xc1cb6b67, 0x647c2a9f, 0x1594601a } + }, { + { 0x94203d96, 0xf446beab, 0x0f8b20bc, 0x389c59ef, 0x242d503a, 0x1baf43c8, 0x3600cf74, 0x1de5e5ef }, + { 0x97a63b7c, 0x3477df53, 0x98cd129d, 0x386c7fd6, 0x820b196e, 0x4eb81e8b, 0x205bd83c, 0xc0286a83 }, + { 0xe89c538c, 0xaf6aae3c, 0x8104897d, 0x65453323, 0xef8fc678, 0x80e12904, 0x66939201, 0x5e9ba64f }, + { 0x9c8f7951, 0xf6e54589, 0x687be629, 0x648ba88c, 0x520841c5, 0x302871a0, 0xc25a7137, 0xbc0a9da6 }, + { 0x94a51875, 0x39699a79, 0xaa4a5339, 0xbba551a6, 0x7be6c38c, 0xc7593768, 0x799d2123, 0xcfba86ec }, + { 0x9514f3f1, 0xe4f7e94a, 0x5f051133, 0xcdb33cb2, 0x9a7cff38, 0xe5e1b54a, 0xd69d469c, 0x486dbd33 }, + { 0x897924a3, 0xe2765105, 0x25436a0d, 0x363607d0, 0x2599633d, 0xfeb62269, 0xe3915522, 0xe5578e01 } + }, { + { 0xf7c8d214, 0x4bd95e57, 0x3a9f3a70, 0x93167d4d, 0x7f35b392, 0x7e459e00, 0x1bd8cbfd, 0xa2ba311b }, + { 0xc3b4afa4, 0xb2666351, 0x5a2790f0, 0x6a9bd3c0, 0xf4656b2b, 0x57a7d3dd, 0xc1cb2779, 0x8ac87671 }, + { 0x22fa1ac7, 0xd8a47088, 0xfa7a7ac6, 0x60e6c97a, 0x0f6e93a4, 0xb34a3b69, 0xae5ca04d, 0x121396b9 }, + { 0x9e5056b3, 0x91208a5e, 0x77f6a5bf, 0x65d8ce69, 0x57d8e680, 0x4a724283, 0xd622ffc6, 0x470969b6 }, + { 0x9c10a010, 0x93b62255, 0xde58d702, 0xec0d4d4a, 0x01b2f957, 0x86f0b84f, 0xa06604fa, 0xddea1447 }, + { 0xeca81c4c, 0x0212f154, 0x91e85b88, 0x5de81230, 0x76f2fed7, 0x93d938fa, 0x1a9064ad, 0x843e29c3 }, + { 0x6d511162, 0x673545e9, 0x6273f869, 0xea9b2d81, 0x66cefe10, 0x858e956f, 0x020d1fd8, 0xaca8b918 } + }, { + { 0xb215047f, 0xb9cad797, 0x115a2022, 0xac8c2cfe, 0x137eb97d, 0x31db80f8, 0x63e24c78, 0xe4c82b42 }, + { 0x3a87484b, 0x3bb2bbee, 0x2d21e574, 0xd8951ba9, 0x5d145a36, 0x26128d8f, 0x192584dd, 0x304ac2a1 }, + { 0x81663073, 0xb3f6ac8f, 0xfb22388b, 0x146fad89, 0x2f7e9fef, 0x094601e8, 0xb146faa0, 0x45e9b342 }, + { 0x8d01f6bc, 0x3b482017, 0xd83071fd, 0x658d6b53, 0x82a395fa, 0xb39b15a1, 0x7802c350, 0x9fe99597 }, + { 0xb9595963, 0x9724da84, 0xdd078337, 0x6f36029f, 0xa4b75a7f, 0x539abc90, 0x972fb4a7, 0xff29f0e7 }, + { 0x3f2b4a48, 0x1b096082, 0x800144af, 0xa3cd3f29, 0x7f4ddf99, 0xaeaf6abd, 0x585faf54, 0xc6abb2e5 }, + { 0xd4c10800, 0x4e4d76dd, 0x41a1a77a, 0x7a696586, 0x48deff36, 0x6c547df2, 0xd8f94c62, 0x4425b8c8 } + }, { + { 0xc253f1fd, 0x837f3b31, 0x0b5ccb2c, 0xe3191c69, 0xef0262dc, 0x7a36afc3, 0xe2aac82c, 0xeb8b48d9 }, + { 0xdb01f19c, 0x94a9b1f1, 0xe45b89be, 0xd967f07c, 0xda369655, 0x4b4fde39, 0x50301229, 0xa999282d }, + { 0x5c451b88, 0xa8ed1424, 0x1f28a883, 0x21e8058c, 0x36945b83, 0x825d76ff, 0xa767e753, 0x65ec9f62 }, + { 0x797e3bc8, 0xc1e87948, 0x39a0a9c7, 0x10cba850, 0xc107360a, 0x64c93e68, 0xb40d111c, 0x809e4b58 }, + { 0x22d23cf3, 0x5adbd67a, 0xbd94048f, 0x3bcfb5b4, 0xc0b7b35c, 0x778fa0f9, 0x9482d523, 0x0ae3280e }, + { 0x69fe1cc8, 0x464dcbd2, 0x5f11c964, 0x1d8b0886, 0x5b9cef4a, 0xee230459, 0xaf385e86, 0xfbd94ab7 }, + { 0x3953c1ea, 0x32adcdd4, 0xb958d003, 0x870cf263, 0xa99378de, 0xe7e4d956, 0x7acb3b61, 0xe790b88e } + }, { + { 0x829ef43e, 0x619388f0, 0xb3a1aff6, 0xdfe0a153, 0xd06fd2e2, 0xa81a36fb, 0xc55c4bef, 0xb3fdd022 }, + { 0x4e6b3c8f, 0xd69af789, 0xdfdc14e9, 0x549f2d8b, 0xfd67b5f4, 0x76794a70, 0x6e126224, 0x88fd42f2 }, + { 0xf7047035, 0xa905db3f, 0x49b4e963, 0xa3759c8f, 0x89a78818, 0x2c50346d, 0x8e2d5e83, 0x127915e4 }, + { 0xf48078e8, 0x1a4ca7ef, 0xfc4ee78e, 0xdd6f7982, 0xe4afd40c, 0x73cada61, 0x6547c764, 0x1c17d44c }, + { 0x8f6d2fc3, 0xda86e5b9, 0x93fd6d0d, 0xd0b1f0b2, 0x0a6909f4, 0xdc3b5e24, 0x90fced49, 0xf624b0cb }, + { 0xb4266815, 0x4f8ee3cd, 0x53c7dc14, 0x029ad9b3, 0x8188c70c, 0x4ed0d4a7, 0xfab23b81, 0x68c3f9cb }, + { 0x3fdd8763, 0x39c6e87a, 0xfda0dd8b, 0xef70ca8c, 0xe75125c0, 0xb2cd8fb4, 0x08eb626e, 0xdde63074 } + }, { + { 0x17b23292, 0x606c1866, 0x9c18cca3, 0xee3a27fb, 0x3995b5c6, 0xdd3302e4, 0x9e27dc11, 0x5fbc67c7 }, + { 0xcb105782, 0x34c7b524, 0xe3d46ab3, 0x66d18f3d, 0x3548dcf4, 0x68f6e040, 0xb60411df, 0x078b5f25 }, + { 0xac587cd1, 0xf32c95ba, 0x7cdee74a, 0x1dcc3fcf, 0xc36d8ac3, 0x53bee54b, 0xf0ac4193, 0xe65bd8f3 }, + { 0x479b1639, 0xe50a52f1, 0x53d42f44, 0x27897116, 0x428a3068, 0x74779849, 0xcab2a9c6, 0xf0f83a6b }, + { 0x9b45bd8d, 0x557e0d6f, 0x8102e9fc, 0x934ab0f9, 0xa15136dc, 0x0553e370, 0xaf9e4586, 0x96dda777 }, + { 0x1b13233d, 0x8782b3c7, 0xf6c35a78, 0xc3cb451a, 0x335bda6a, 0xc7052bd0, 0x5ac4f651, 0xe693e88c }, + { 0x7c055aa1, 0x8c3b1ba6, 0x8d63f4b3, 0x2947c116, 0x0047b9db, 0x445c1a9f, 0x68f88f78, 0x942cb5ef } + }, { + { 0xd805f7b7, 0x5a8dcc40, 0x553ecc20, 0xfb603dd2, 0x39753deb, 0x548a6f28, 0x67ed99aa, 0x78fd3ed0 }, + { 0xe50049f0, 0xde3fadfe, 0x3c87dc57, 0xead7b0ee, 0xae277a2a, 0x0cfbb0a6, 0x3847a513, 0xc69acd80 }, + { 0xb1d5dc3c, 0x66e9b52f, 0xfa9d4ed9, 0x4e29e3cf, 0x0d463727, 0xfd384d8f, 0x65c48f17, 0xbb2aa27d }, + { 0x76ac355c, 0x003f9aff, 0xdee49cf5, 0xbcc92cf6, 0x46778f2e, 0xb914ed52, 0x0b5019c8, 0xde41e619 }, + { 0x63c34226, 0x931232a8, 0x3b02c1ce, 0xda47aada, 0x761aadbd, 0xf8922f26, 0x428154ee, 0x54a868c2 }, + { 0x71b944af, 0x831b381f, 0x6c540c8b, 0xf63eafd5, 0x52cd4dc0, 0x9d1cd861, 0x2d581bc3, 0x7a668bcc }, + { 0xc0471789, 0xa99aa85e, 0x4180c9f0, 0xc2d74dc5, 0x3da366da, 0x2be54eeb, 0x7f112a06, 0x7cadbfed } + }, { + { 0xaae29aa0, 0xfaf5e052, 0x36eaf2dd, 0x109bbcf6, 0x7a32f80a, 0xdcd774b9, 0xa73cc8cb, 0x020120f2 }, + { 0x35dbdb7c, 0x1df8d6c9, 0x9d31e334, 0x474ca376, 0x85d72d99, 0x9d5891d4, 0xac6bc84c, 0xef1edc41 }, + { 0xa0a12ae0, 0x39087695, 0xce7be7de, 0x4f4cc09f, 0x2ce6e6c8, 0xe302f577, 0xd1bf201b, 0x4c67b486 }, + { 0x0482e45a, 0x8c588bcd, 0xa1784b77, 0x01e5afab, 0x385ff123, 0xb9048cf6, 0x5b64b460, 0x82beae14 }, + { 0x53bdad3e, 0x71e76e58, 0xa33e2a3d, 0xf04c957f, 0xbcac35c3, 0xc13b0d6d, 0x5aa18177, 0x5376c3f8 }, + { 0x8fd59904, 0x1ac23373, 0xa7d95104, 0x4ea0e6b4, 0xc9751244, 0x21291029, 0x39ba0a58, 0x03ff99b3 }, + { 0x27ce22c1, 0x61a59a1c, 0xecb951b1, 0xbec43d3c, 0x6f1b816f, 0x71031ad6, 0xa831c3bd, 0xfd563429 } + }, { + { 0xc1c4a945, 0xc5e5fa84, 0x428871d5, 0x64e0cdfb, 0x8a437645, 0x3891bff3, 0xca4a09dd, 0x34a1f315 }, + { 0x1d11a401, 0x2c203bbf, 0x1af265b9, 0x13d6e524, 0xaa82fc1c, 0x79158bb6, 0x04504769, 0x56998ddc }, + { 0xdcb5ce82, 0xd7f016bc, 0xf7ac3b8f, 0x01a80e14, 0xeb67b2d6, 0x3a7164e5, 0x697e95fc, 0x48e71fb4 }, + { 0xa97977ac, 0xa53a014f, 0xa340a5eb, 0x2582fbaa, 0x07bab09d, 0x946a7d59, 0xb0663162, 0xaec8e0c7 }, + { 0xe77e366b, 0xaeb9162a, 0xcca11a3d, 0x6e277e42, 0xc622d3df, 0xec6c75d3, 0x486f5ebf, 0x6569c183 }, + { 0x038ad1a1, 0x92ebd412, 0x02ecb91e, 0x5c328807, 0xf83da629, 0x889f30a8, 0x9f64ef2a, 0x753083b0 }, + { 0x0e3f90dc, 0x136957cc, 0xb90ee7cb, 0xad918b75, 0xd8f30259, 0x070fb929, 0x970da771, 0x10dd6e58 } + }, { + { 0x7fff17bb, 0x7d0fb982, 0x64fb1d31, 0x801ae173, 0xc5494808, 0x82f639b3, 0xb08f8be7, 0xe177e1aa }, + { 0x22fac75d, 0xe296fdc7, 0xc7ea5f7c, 0x543d75ac, 0x0aa41471, 0x0de52abe, 0xc5be0766, 0xb69b3cc9 }, + { 0x58a6837d, 0x86d09580, 0xc888ae86, 0x59a9dbfd, 0xbc6822b9, 0x00408db7, 0xa8f132cf, 0x35f53d02 }, + { 0x4adb8be1, 0x78ab1d2b, 0x58eaecca, 0xe6fdb954, 0x086292c5, 0x929e83c3, 0x49cee217, 0x30f798ae }, + { 0x11902b99, 0x2f9d30f1, 0x065f1519, 0xe924a28d, 0x5f6ed7ed, 0x5e3070af, 0x922f3bd8, 0x33ca22cc }, + { 0x16bccb3f, 0x083bc5db, 0x2717bdfd, 0x1cb44f6b, 0x04eb1d12, 0xd68fb3ff, 0xf18f5279, 0x02617755 }, + { 0x1f4f07e0, 0xae0ed9e7, 0xac4583d9, 0x5c846729, 0x6c8b8ca4, 0x64c0f711, 0xef2c6393, 0xd7736f0f } + }, { + { 0xbccaea79, 0x916d9cca, 0x6f6c174b, 0xa509bea0, 0xfd98ca6b, 0x798ed2a0, 0xa13c12f8, 0x24c09419 }, + { 0x45b0805a, 0x4534727c, 0xa7330146, 0x66202e8d, 0x18b0aaec, 0x497d6dff, 0x377e3e4e, 0xc4aa4662 }, + { 0xdf113db8, 0x2a5f3151, 0x9e231c7d, 0xf2cbabc1, 0x904432de, 0xe572ade2, 0xda149538, 0x764ec80a }, + { 0xd3e4743f, 0xad3cb3b9, 0xe4de5a8c, 0x362a1644, 0x27b0cd95, 0xc99fb49f, 0x28113b09, 0x4d512283 }, + { 0x614b8768, 0xcd42c400, 0x0e4b8e42, 0xbc4287c9, 0x8761ba46, 0xa01acb20, 0x26632b54, 0x0d1755cd }, + { 0xa4de3dfb, 0x6cf5d931, 0x2b40375a, 0xb9ac1ad0, 0x4e2a7093, 0x9940fb7d, 0x4a526d30, 0x7c5ef62b }, + { 0x372cf61d, 0xf6d5fcf7, 0x1d14bd8d, 0x94579792, 0x34aa397c, 0x5ca62a08, 0x35a86b02, 0x14c75383 } + }, { + { 0xae683995, 0x3e84150e, 0xe0d3b2a0, 0xa992c8ae, 0xe9e7b33b, 0x76ede638, 0x3c686061, 0x36216c8d }, + { 0x0a90129f, 0xb462da31, 0xd50d3633, 0x1214fb62, 0xe5161a97, 0xb06c0d3e, 0xaf89e3f4, 0x9e107830 }, + { 0xf6bfb46e, 0xb16b9ed1, 0x493b6514, 0xa7dff787, 0xdf8e488f, 0xc8ce8222, 0x8fd52f6a, 0xa6b4afee }, + { 0x00e0900c, 0x74f6faa8, 0x38fe0714, 0x11d68e12, 0xb2be4db0, 0xc50baf27, 0xc2a971df, 0xfcc60b2c }, + { 0x558997c0, 0x2e9f279e, 0xc7da06f7, 0xb2d5a66c, 0x888961dc, 0xc0716af3, 0x465afda8, 0x9563cf7e }, + { 0x8aa01158, 0xaa3a11b2, 0xbc46eddd, 0xe4d30f46, 0x2c48ad46, 0x2f697c2e, 0xb052aa2f, 0x4258d424 }, + { 0x900a7e76, 0xc9e24e68, 0xd103e0b2, 0x905e8357, 0xef994df5, 0x19d19bef, 0x91177797, 0x817a5f93 } + }, { + { 0xf0680a39, 0x56ec06e4, 0xc276f5bd, 0x375ef775, 0xe4e31ffb, 0x335fae5e, 0xd0540873, 0x6d6a91d8 }, + { 0xa6e75e8c, 0x3eaed6c6, 0x7d1aad1d, 0x431fa0bc, 0xe7dc54cf, 0x7d01a58e, 0x9b373b3b, 0x05972443 }, + { 0x2240d9e7, 0x0a99f104, 0x9e7b0d87, 0xe3dd4ec1, 0xbe262434, 0xcd7e9368, 0xda172b64, 0x0c80f89f }, + { 0x8a32479b, 0x813870f4, 0x9602215f, 0xf473b93c, 0xf3bd2430, 0x1c18aa53, 0xa89a2bbf, 0x07e846ae }, + { 0x723b2e62, 0xf5ade945, 0xcdd2acf2, 0x910e35e9, 0xdc538032, 0xc147e3b1, 0x15204ed3, 0xe69493e0 }, + { 0x51271a23, 0x1d4c5b74, 0xa0e926fd, 0xa00e2971, 0x70287ae1, 0x29115d0b, 0xf3489230, 0xbcf17a85 }, + { 0x09b3414d, 0x1d165016, 0xc6ec18d5, 0x9ea6765b, 0xe63744ac, 0x88cc920d, 0x816b6d20, 0xb749526e } + }, { + { 0xa9558de9, 0x563a30c3, 0xf131a8dd, 0xfc83e745, 0xfddb8c80, 0x5d119a00, 0xddd1b73f, 0xb7b0e877 }, + { 0x94f78ac0, 0xe1912c33, 0xbbe07a7d, 0x27b76ab6, 0x299f434e, 0x02e155db, 0x518eec1b, 0xcb5ae470 }, + { 0x7e337565, 0x38ef431d, 0xe513ef75, 0xf56f508d, 0xe9feb1c8, 0x99ae4d92, 0x4abae804, 0x2fe114ba }, + { 0x9e083058, 0xbb7c0f1d, 0x69efff2a, 0x17f3f27a, 0x6411414a, 0x82ff5fcb, 0x7e8c4eaa, 0x2f89d135 }, + { 0xa4246ea7, 0x803aff5e, 0xfc1d9c26, 0x2e425c19, 0x71852375, 0xf9900481, 0x317571d0, 0x512de239 }, + { 0x27278683, 0x2f50a60d, 0x0fec7db6, 0x81d67782, 0x6be16992, 0x0289ac47, 0x72ac7cb0, 0x011060bd }, + { 0x51561a11, 0x6e1d88c1, 0x8d63898e, 0xb6302a29, 0x45508af7, 0x7ab02923, 0x3300b64c, 0x18657075 } + }, { + { 0x93f705e7, 0x0b147235, 0x4579614e, 0x7955dfd5, 0x859d3964, 0xcb02ffd0, 0x91eb2e37, 0xf21aa087 }, + { 0x9cd1ba88, 0xfdf4f40d, 0xa5d82ffa, 0x402f925e, 0x02410072, 0xe9ab67ce, 0x57489af6, 0xa5c28f89 }, + { 0xdf5c6569, 0x6f6b4a1c, 0xeba0b602, 0x52c4d57e, 0x873757fa, 0x211ecd13, 0x325220ff, 0x17684f9b }, + { 0xbf48a26b, 0x1164e929, 0x68f2aa93, 0x2ae3ff90, 0x2fca69ce, 0x46ea779f, 0x149abe71, 0xf037d66d }, + { 0x2f692586, 0xc4786748, 0x022ed0d8, 0x35b30c7a, 0x4d42960f, 0xab8f12e6, 0xf1583d9a, 0x648650b5 }, + { 0x879b353f, 0x39d49315, 0x59a5e626, 0xa0536bd4, 0xc14eae98, 0x590e874f, 0xb3facb2e, 0xf40c444a }, + { 0x87f06816, 0x73316158, 0x8e8994ce, 0xc72cdabc, 0x98b88662, 0x51a7ca8e, 0x4bc81e4e, 0xf35ae046 } + }, { + { 0x3b5b086e, 0x6f799891, 0xf152c74f, 0x8ad181d5, 0x7057c78a, 0x6c289635, 0x3ce24060, 0x722c288d }, + { 0x1006d5aa, 0xabcec468, 0x82d3529d, 0x53da6135, 0xc62d75f7, 0x15421578, 0x271025ff, 0xad983b85 }, + { 0x39e3822a, 0x6ded14ca, 0x6c14077f, 0x923e1de4, 0x5c26dcca, 0x0ca1fae8, 0x9144978c, 0x3aa5ffaf }, + { 0x6a606b33, 0xbaf2a768, 0x6b05c4f8, 0x9de48ab4, 0xb5bd4d6d, 0xa8c57a5c, 0x429d6625, 0x035270c5 }, + { 0x44ec8799, 0x9faf6948, 0x15a7ccf2, 0x8ca09a6b, 0xe5c2a350, 0x7b14fdbc, 0x757e7d54, 0x8beefdfe }, + { 0x6404be41, 0xf3602368, 0x0a2388d1, 0xe309fac3, 0xbf1b9363, 0x349b5d55, 0xc97fd510, 0x7bb679c3 }, + { 0xbf51ea31, 0x7cfcec24, 0xb0fe8f2b, 0x0189b700, 0x29f06aa5, 0x614623e3, 0x19c3fd69, 0x6507077a } + }, { + { 0x33544daa, 0x4eb55b5d, 0xb9ba06a8, 0x7a1779de, 0xaac53436, 0x15d46ddb, 0xc20829a6, 0x4def4316 }, + { 0xa8433bf8, 0xfa3b3cc7, 0x2553a9a9, 0x62c92d3f, 0xbd133110, 0x92394b6a, 0x773b28ef, 0x7f278998 }, + { 0xe98ed40c, 0x70dd13f0, 0xa1fed2d8, 0x32999d19, 0x99b6bdc8, 0xb6c50812, 0x09d4cef6, 0xff970739 }, + { 0x7a05b868, 0x3b70b170, 0xb2c5ae8f, 0x99d39a25, 0x588d1612, 0x7affbd2f, 0x3223c05a, 0xbf4a2ff9 }, + { 0x14b1dd73, 0x2fd2c36a, 0xbe7e3cd9, 0xef1a83dd, 0x6b5ebac0, 0xf664740b, 0xf770ad79, 0x916afecc }, + { 0xe7b72067, 0x8a299277, 0x7ceeb323, 0x1d0a35b3, 0x963158c5, 0xf34dcdd5, 0x7d51e045, 0xf0cba700 }, + { 0xbc2e26da, 0x2d7cf4d2, 0xb1fe2ec7, 0x739c726b, 0x56f096a9, 0x304a33af, 0xfad91e73, 0xa052219a } + }, { + { 0xbeeda331, 0xeb9064fa, 0x826ecbd7, 0x350672d4, 0xf3e89f89, 0xa6b8bf8b, 0x770ec306, 0x3d6ec7d0 }, + { 0xe6d4084b, 0xa98ef16c, 0xf5d90c69, 0xd8ff6cf1, 0x40515d2d, 0xa66e0a26, 0xc5026f42, 0x49b8bd57 }, + { 0xcec0399f, 0xb5ca3155, 0xa97efc2f, 0x026a1550, 0x74bcb8b7, 0x4ea20409, 0x8626edcf, 0x981007ac }, + { 0x30bc8d63, 0x72fab04d, 0xdde894fc, 0xbf7de506, 0x96c87efb, 0xb2d34273, 0x240ac85c, 0x8acc1c1c }, + { 0x52968b7c, 0x0557f36f, 0x0ae5f576, 0x3e62a412, 0xb2664dd4, 0xaef0f476, 0x7c548e2a, 0x530a4f59 }, + { 0xcd106992, 0x4a3c4f25, 0x34f20563, 0xb76f3555, 0x6b7464f7, 0xec4f76eb, 0x0bd8c988, 0x49c492b1 }, + { 0x92fa08f2, 0x144d3f7d, 0x7d58ced2, 0xd22b7cf5, 0xf0187b42, 0x55d861e8, 0xcd019afe, 0xe9a1f11d } + }, { + { 0x9a436489, 0xebb996cc, 0x58762ba9, 0x675ba671, 0x3493bdab, 0x7e0ea401, 0x44f724b1, 0xd6024b8c }, + { 0x4e1846b2, 0x5181068b, 0x1a54b8e7, 0x9646ded0, 0xfe456268, 0xd1b00fad, 0x05dbc6c2, 0xea34ecbd }, + { 0xf7d502f0, 0x1d3aa8c1, 0x58d37b4b, 0x694d554c, 0x2b6076f2, 0x8748bc5f, 0xf8d82aa7, 0xa8c4c813 }, + { 0x2e751abd, 0xf08fac6e, 0xd35325a7, 0xcc47fc1b, 0xca975ec8, 0xbb331169, 0xb990cb9f, 0x24573b56 }, + { 0x22e24f5d, 0x90161c2e, 0x9f6f29b8, 0x64a3b6c6, 0x0b014332, 0xdd078178, 0xd0af41d7, 0xe8c2e047 }, + { 0xca6768e5, 0x9e824241, 0x8b232668, 0xb5b62a53, 0xcbe29e50, 0x52f4a2fe, 0x79ae4a35, 0xda534d00 }, + { 0x167387d5, 0xeb0490e9, 0x95090fb2, 0xca19e74a, 0x1c04dfa9, 0xc5f38f5b, 0xe00cabff, 0x0c17ba81 } + }, { + { 0x6631fc79, 0x52c30423, 0xe639f29b, 0xffcb6692, 0x85a3327a, 0xd5401982, 0xcc87e1a8, 0xdb1114b6 }, + { 0xa1b081bb, 0xd244bdd8, 0x17445435, 0x11600396, 0x4fc04562, 0xb7b8d8c1, 0x3dd9e83d, 0x5388fc2c }, + { 0xbf922504, 0x57f8841f, 0x130a604e, 0xe5eaa7e0, 0xd5ab1d0b, 0xf245fcdb, 0x5513cac3, 0xedbd9ec7 }, + { 0x49f054b6, 0x9f3afcaf, 0xa2ffd2a2, 0xab25bc2d, 0xe5c78937, 0x95feba83, 0xba62ccf6, 0x8f0be368 }, + { 0xa767cab3, 0x994803d8, 0xbde221df, 0x8e1e71c6, 0x8b78c799, 0x91f0aef0, 0x36c2fc52, 0x3161862e }, + { 0xff6f24fc, 0xa69ff27c, 0x119104a0, 0x51d902e8, 0xf7b6be77, 0x5ce92ecc, 0xaaad6af3, 0x1da6fff2 }, + { 0xffd1c2c7, 0x5da2b662, 0x9d5eebb2, 0xae3ec072, 0xa91996c3, 0xa53a8d2e, 0xf2407c14, 0xb22af9a7 } + }, { + { 0xc5714cb5, 0x8591b545, 0xd2db5bdb, 0x9e9b936c, 0x124db819, 0x2bf9b440, 0x7708843d, 0x7436f47f }, + { 0x74d277af, 0x7a09629f, 0x2c400241, 0x081b6e23, 0xc0195a28, 0xb5aeaff4, 0xb567feb5, 0x3c12ee9f }, + { 0xbda7c475, 0x07c805ba, 0x461488ee, 0x41494226, 0xa7533642, 0x55341d3d, 0x42d59e76, 0xdcaba05f }, + { 0x55ebdbd6, 0xe07b35da, 0x00737a47, 0xf5538726, 0x4e150f89, 0x47581944, 0x16d60f6c, 0x7d50492a }, + { 0x2d678829, 0x33c9861d, 0xe7419c54, 0x963b2e25, 0x0919ffb8, 0x2e7418c6, 0x00f595dc, 0x1b2734b3 }, + { 0xfa8c3a83, 0xa182c951, 0x203a4716, 0x10994d1a, 0x97234f60, 0x779a3fc0, 0xa2f72c49, 0x4811ae01 }, + { 0x926de2e3, 0xc9d02e7d, 0xe745b89b, 0x7210a4fa, 0x58228e67, 0x974bb00b, 0x8df1b6a6, 0x474d3460 } + }, { + { 0x8d63e29b, 0x37da4019, 0xadbce1ae, 0x8f13b4a0, 0x6485458e, 0x005d7952, 0x11129a0a, 0xa5b7661e }, + { 0x297c58be, 0x3d5b7465, 0x33012b97, 0x61e9f795, 0xabd3a260, 0xa7df3f4a, 0x9907dbd1, 0xfe9d06c7 }, + { 0x4bfe1dfa, 0x7f7c44d6, 0xbdb02117, 0x584c21f0, 0x0a3e923a, 0x0a3faf1a, 0xf3e5a5bf, 0xdda49418 }, + { 0xcb187d93, 0x3dd4bbf6, 0x656bdf5c, 0x818e19a1, 0x2917357d, 0x3116cff0, 0x464b0326, 0x0c261132 }, + { 0xb656ca93, 0xa28cc08b, 0x277bf86e, 0xd4f5ad69, 0x2e9a1c82, 0xa5ee39f9, 0x3f71d611, 0xd3ea2e11 }, + { 0xa2f104c3, 0x45ebae69, 0xdeddfa82, 0x3d4249ee, 0xbcfb51d1, 0x867ea762, 0x48e8a89d, 0x2844d5c1 }, + { 0x82ebbae2, 0x05adaa3a, 0xc0a3f7b5, 0x7b293b80, 0xa94e765f, 0x4120818a, 0xc50b274d, 0x22688c9a } + }, { + { 0xc3fc0b44, 0x8bcd8873, 0xfd4fb8e5, 0x6a9efb07, 0xaf2d5eb8, 0x995aae51, 0xa1521e70, 0x52774766 }, + { 0x7b54eba5, 0x6668a386, 0x75ab18e1, 0xdc4d0e40, 0xee4b3387, 0x17b838e0, 0xc8f32068, 0x8f50d4b5 }, + { 0x09204da6, 0x9ef60809, 0xbc8000cf, 0x337a67fa, 0x9ca7108c, 0xc757cd3a, 0xeb08ba82, 0x7e6be6d4 }, + { 0xc5a39182, 0xb0620854, 0x8015feed, 0x995d6017, 0xd0360d35, 0x3a814e7c, 0xe6573534, 0x59710baf }, + { 0xf99bacff, 0x3d3b0b0a, 0xbe43aa97, 0x5fb0a3ae, 0x3d2df3b8, 0x853dc3b9, 0xafd2a5a2, 0x4f1af404 }, + { 0x61ae5f7d, 0x44573fab, 0x90121a80, 0x3f0f4088, 0xc2123f61, 0x11abc7af, 0xa359b722, 0xddbfb1e5 }, + { 0xa8225e73, 0xcd094275, 0x4f4d1009, 0xb870665e, 0x2656e309, 0x63613320, 0x9da8e9e2, 0x5bf17a9a } + }, { + { 0x63307f75, 0x20e71142, 0xf2edd250, 0x489c3aef, 0xa00a6f57, 0x5d10c01c, 0x324b9253, 0x93835be0 }, + { 0xa174b176, 0xf1acf07c, 0x0638fe83, 0xcdf6812d, 0x76a8fe28, 0xc8fb9566, 0x61b2de0f, 0xe7e572db }, + { 0xa70101cd, 0xd58fcb3c, 0xa08d7a92, 0x707f7a51, 0x087f7394, 0x52ec367f, 0x4ad2575f, 0xcf0d9422 }, + { 0x99f9db0e, 0xd63b7d0b, 0x87714087, 0x32f4d997, 0x02ae8cba, 0x6c162b9f, 0x17c6c72e, 0x6870a1ff }, + { 0x1d859421, 0x0cad1862, 0xcc75b1b9, 0x3e7cffb2, 0x2284bd70, 0x3863341e, 0x1963063d, 0x4d37d33e }, + { 0xd612cd20, 0x43d28fc6, 0x0233b726, 0xaa330aa2, 0x01201406, 0xd4d58e80, 0x214f84c6, 0x2b1ab302 }, + { 0x04a91c83, 0x53597fe5, 0xaf7019d6, 0x8fb705d4, 0xd6bff9a0, 0x41220802, 0x7b7733a4, 0x97e00d32 } + }, { + { 0x40595c86, 0xf6930099, 0xbd743c7e, 0x052b2a49, 0x520434cc, 0xe84013cc, 0xb4b3b5b7, 0x2145a47c }, + { 0x1bbec7a8, 0x51054b48, 0x4540c4ce, 0x410ea37e, 0x22d77338, 0x53ea7838, 0xed1cc935, 0xb53c4e11 }, + { 0x1ca8445c, 0x68dbb70e, 0xb9edffbe, 0x798d10b0, 0x1173177c, 0x8c46979f, 0x7a25f06d, 0x8df73f0d }, + { 0x868e48ed, 0x0c4dec3e, 0xf0fc84f4, 0x935291c2, 0x8513c611, 0xbc49b63e, 0x4a51f7fa, 0x8c447a51 }, + { 0x037d699e, 0x0a093b32, 0xc2ec9f29, 0x5e90f49a, 0x855f3c1c, 0x36674b9d, 0x6414d645, 0x128eb019 }, + { 0x64d6e74a, 0x65fa3cce, 0x09c472a5, 0xa17ee5f5, 0xdffb9e45, 0x7a9c4595, 0x4d07da7f, 0x6fed21dc }, + { 0x81842845, 0xfc184cbb, 0x441f1fba, 0xf06543f1, 0xc8ec2559, 0xc0414db3, 0x59add3e1, 0xeedcba8e } + }, { + { 0x8d5f1cb1, 0xdd5cc734, 0x97b66085, 0x1f2aeb4e, 0x49fc4df3, 0x8c4647df, 0x020d8f8f, 0xfb3e30a6 }, + { 0xdc5dd9fe, 0xce57f180, 0x24dd9046, 0xc375884e, 0x869faec3, 0xbca83934, 0x71d1943b, 0xb1eaf24e }, + { 0x571eab92, 0x30538228, 0x5be3247b, 0x045cca2f, 0xa504a51c, 0xf5493a6c, 0x18fef6d0, 0x6f0f0e6c }, + { 0x9bea0233, 0x80dc3ce3, 0x59ec7d4a, 0x76dafb6b, 0xbdbc4040, 0xcffa68d9, 0xc156af96, 0x1b17111d }, + { 0xcfc30870, 0x623df507, 0x9fd6056e, 0x58b5a009, 0x3addc588, 0x01bf2d7f, 0xfd70e9b5, 0x454451fc }, + { 0xa291458a, 0x4526adc5, 0x367c6943, 0xec7c457d, 0x2983a292, 0x93f5a287, 0x38f480d2, 0xd4de9db7 }, + { 0xa6a97c24, 0x51a0e0ba, 0x1f639439, 0x950eed3e, 0x45f0c8ba, 0x7f6752ca, 0xc0c4af72, 0xb785824e } + }, { + { 0xb0cb4422, 0x0c5dcdcb, 0xb1d133c1, 0x1865317a, 0x2614b1c4, 0x484a4f81, 0x8cdbcbb7, 0xec2d0728 }, + { 0x7d9cf77e, 0x61770bc4, 0xa3eb1843, 0xc5ba899d, 0xce974e91, 0x4adcd05f, 0xeb21acfd, 0xf962c2b3 }, + { 0x213950f4, 0xf2a8b184, 0x3de16761, 0x2a9ee270, 0xe04388a0, 0x678bd048, 0x3982af74, 0xb79829c3 }, + { 0x2a57e1ae, 0xf96bcaa4, 0x58342aaf, 0x8662da2f, 0x7bfe6e15, 0x94249242, 0xda56a0c8, 0x610fdc7d }, + { 0x35f0876d, 0xf5151109, 0x6e95020d, 0xe2ca2d86, 0xc5f859ef, 0x6349c00e, 0x483a09d2, 0x3d793ad1 }, + { 0x48d650c8, 0x792cd02d, 0x96dd5dfb, 0x0ad306bf, 0x0865afae, 0x9984bc0a, 0xab9e4821, 0xf3977f17 }, + { 0x91ce8b28, 0x14759678, 0x8fb3eefb, 0x187d0f53, 0xc5d183b0, 0x0a3ff48d, 0xd30b2d9e, 0x7d34ee4f } + }, { + { 0x00bcde15, 0xcccd7271, 0xb895c848, 0x1c86d357, 0xbd8ee9b0, 0xd063775d, 0xb3f130fd, 0xd2ca1c14 }, + { 0x3c9857c9, 0xc6a9decd, 0xca1f2b65, 0x3d2b10a7, 0xb947c90f, 0xefcb8523, 0xca03778a, 0xd5d42cfd }, + { 0x5c73f4ce, 0xf8262f6a, 0x3ce264bc, 0x2df69850, 0x4a4bb3bc, 0x381e591c, 0xb9fb0145, 0x9996df80 }, + { 0xa379c4f2, 0xda0b13b2, 0xfb1b3cad, 0xb370772c, 0x6ded2ab8, 0xcc98e438, 0xd4ef7629, 0x3330f2c2 }, + { 0xc0d41786, 0x537ea8c7, 0x3b441a76, 0xdb1195bd, 0x3ce092d1, 0xb484de42, 0x8a853c14, 0x39e1d707 }, + { 0x871a31a0, 0x80623383, 0x3ad8e04b, 0x6d1e706d, 0xc99687b9, 0x4661e7ee, 0xeae02eb9, 0x73b29bdb }, + { 0x36816855, 0xf1440803, 0xed9581f5, 0xa42bf12c, 0xc085f0f5, 0x700c5480, 0x6092c0ad, 0xc1952028 } + }, { + { 0x61f3d76c, 0xb619f830, 0xb3c1aabe, 0xdfe516c8, 0x9de4137b, 0xa7cdfdcc, 0x8ae83950, 0xa824756c }, + { 0xa5234d7c, 0x9f7fc888, 0x02c47a29, 0x5675deb6, 0x03797a1b, 0xbd9f84f2, 0x49496ab5, 0xb3a92c12 }, + { 0x1459774e, 0x0587b246, 0x0e4c44f8, 0xeadc3dfc, 0x756d0677, 0xe5528ce8, 0x9d2a09d6, 0x4cbc59ec }, + { 0xca73670e, 0x55bb1710, 0x1e22a6a0, 0x70a8c976, 0xdb4045bc, 0x0bae4004, 0xdf481fa0, 0x98ebe4dc }, + { 0x85fb6d61, 0x56f856ad, 0xbf0842c3, 0xc5251773, 0xcd853b0e, 0xe4bfdb13, 0xba69a18a, 0x59e25dcd }, + { 0x83f1b479, 0x02285602, 0xec4d5e52, 0x126f80dc, 0x41737c1d, 0xfb739e71, 0xca819d35, 0x23402f41 }, + { 0x5a761f56, 0x70dba9fc, 0x898b6f07, 0x3c0a95e2, 0x4877c927, 0xd340a6cb, 0x53927787, 0x5bbc2f70 } + }, { + { 0x6f55de46, 0x80b41750, 0xe79726ae, 0x7e4430a4, 0x15016ede, 0x3cb704f6, 0x29d17376, 0xb1daf0a9 }, + { 0x1d106948, 0x09e71e47, 0xdeca7038, 0xcc4b19b9, 0x9aa4cb6c, 0xa5b51694, 0x50843372, 0x6f9bc50e }, + { 0x7da1905b, 0xcbae73bc, 0xc3ddc084, 0x7335d06e, 0xdf340f40, 0x25db1010, 0xeb287817, 0x0f8c91b7 }, + { 0xc91a7359, 0x5b5d748a, 0xbe2cd22a, 0x3c2e3298, 0x6c4247ef, 0x9a47c570, 0x2ddfa616, 0xd4bf75e0 }, + { 0x96ba5256, 0x9d2c3f03, 0x308d95e6, 0xcfc9ec0f, 0xa0961055, 0x392c377c, 0x66bafd5c, 0x7380bcd9 }, + { 0xe7c67ec8, 0xb9d05682, 0xa799e0b2, 0x32b89eb8, 0xf33da47b, 0x59ac7d9e, 0x931e2025, 0x3643c04c }, + { 0x565309d2, 0xfe24877e, 0x57202f59, 0x3d46b5a8, 0x8e00c15b, 0x8f0b8dea, 0x396d22c4, 0xe6fc1a15 } + }, { + { 0x5b18a044, 0x2c1b66b4, 0xe14c7f03, 0xd02553b6, 0x8d6b85f3, 0x6402dc7c, 0x39c64fe6, 0x02fd8601 }, + { 0x94c5a100, 0xbf83bf04, 0xe071aae4, 0xb8fcdb16, 0x76963764, 0x7b3b7bbb, 0x917c4f2e, 0x6f2932b0 }, + { 0xc891a1ca, 0xdec32e1c, 0x7f894b1d, 0x5a783287, 0x2b4d8375, 0x8d0d30b1, 0x49c9e792, 0x2588847b }, + { 0xb0f4d7fe, 0x7d03d93e, 0x1633bbb3, 0x30524f45, 0xc1513f85, 0x686ace4c, 0xfed101f7, 0xc6640982 }, + { 0x3f2a6442, 0xc8fe2cdd, 0xe7374831, 0xfa1df37a, 0xebac64c1, 0x9abc3ac5, 0x8ab69757, 0x83956b7f }, + { 0xb28bc15c, 0x1e8e0ef1, 0xc29a5af2, 0xc3b8ae0a, 0x421d84e3, 0xb96ecd43, 0x3d552bdc, 0xeb44d0bb }, + { 0x24c2ea0c, 0x5d58e6d9, 0x370c1ca7, 0x41bffc37, 0x9186bb55, 0x5c001f6f, 0x647cdabb, 0x3343829a } + }, { + { 0xf4738f06, 0xef7954b1, 0xd81ee33d, 0x09fd6120, 0x310b9f60, 0x69241d5d, 0x6735f0d9, 0x0d653f5b }, + { 0x730f85c3, 0xd46deb06, 0xa073f3d0, 0xe718eb2f, 0xd5106bde, 0x27cdc4f0, 0x54770105, 0x350d3345 }, + { 0x9baad4c3, 0xee4f1897, 0x77608e68, 0x8af945c1, 0xc8afcc2d, 0xdea35e92, 0x819d7b60, 0x5c226478 }, + { 0xf9943da0, 0xf57e8d09, 0x6ed04a45, 0x086a56fa, 0x2513abe7, 0x8cf5ad6f, 0xa09e2673, 0x9611b1f9 }, + { 0xe100bbf2, 0x51ffcbcf, 0x8bb1e6ae, 0x9065d124, 0x9d72a7ad, 0x58365309, 0x63c1fca4, 0x64f3846c }, + { 0xf1290554, 0x4bbf674c, 0x38714bb7, 0xa2f29af0, 0xd603228b, 0x340e638a, 0x76992250, 0x596bc1cc }, + { 0xf0466f92, 0xbfb91931, 0x2a515d34, 0x2d2d9b8e, 0x57374071, 0xbd9ba285, 0x54c663b4, 0x9c2db914 } + }, { + { 0xc78b3299, 0x19ae1f1b, 0x100a0503, 0x6a5de262, 0x78193f1c, 0x8c9b6cfe, 0x397c349d, 0x9d31efc8 }, + { 0xc5dee2c6, 0x665ef976, 0x49d296eb, 0x6770fbb8, 0xe94a419c, 0x86996440, 0x1f544088, 0xc4a61825 }, + { 0x5d56dcbd, 0xf4f21e5e, 0x64658bca, 0x7f0b0c4f, 0x4ba19309, 0xed866b32, 0x049d1ebd, 0xdc3c5e75 }, + { 0xfa0e70d5, 0xbe3df75a, 0x5b52fba6, 0x40d73380, 0xb032ec4c, 0xf352439a, 0x771a22db, 0x5f9e1c36 }, + { 0xc60ac075, 0xe963f257, 0xbbd1c424, 0x490424bc, 0xd0eef259, 0xfcaa1e74, 0x94f4a76f, 0x57f670bd }, + { 0x9dccdbb2, 0x51b2f921, 0x2fbbb2f2, 0x7501b147, 0x9a2cebed, 0xe638333d, 0xbca1e7a6, 0x830fa987 }, + { 0x5ced560d, 0x5f98d3f6, 0x8d505a5d, 0xcf80da1c, 0x2a2d3452, 0xc1c3d2d4, 0x2a137278, 0x66988098 } + }, { + { 0x19368995, 0xce79360b, 0x65811279, 0xb0b64791, 0x17e4c897, 0x0e9c2981, 0xa7ddf31c, 0x24e877e3 }, + { 0xcc3fdfff, 0x49ed6f65, 0xd6a549ce, 0x63e1eacf, 0xebb20c85, 0x4c726c08, 0xb34d4234, 0x29d229d0 }, + { 0x67dbe937, 0xe59d747a, 0xbb2c26a5, 0x2c45b745, 0xa8974eb3, 0x06fe9413, 0xceff61f6, 0x183a19ee }, + { 0x69e6b994, 0x6c78299a, 0x5aed6f64, 0xb704b816, 0xf62dac7b, 0xb8750ccf, 0xa4975752, 0x02a5c370 }, + { 0x3081edca, 0xd7da0bff, 0x8c3be568, 0x7720044c, 0xa04922bb, 0x044ca349, 0xe929aeba, 0xb1f5c7ec }, + { 0xe2ee4d48, 0x3a344c1e, 0xa3f119b1, 0xc9316169, 0xb4960665, 0x2ec02476, 0x8d09a4ef, 0x2b3f7b4c }, + { 0x64dc05ac, 0x917e0f8d, 0x8767f59a, 0xa7b63c85, 0x7410472a, 0xf2febd16, 0x33b4fa6f, 0x2047f63f } + }, { + { 0x03493b94, 0x1a055118, 0x21981d06, 0xe619c011, 0x8067bf4d, 0x36e9f2bd, 0x7232c291, 0xa85fa403 }, + { 0x7da6e24d, 0x67eeec49, 0xf9d0b55b, 0xa0180fe0, 0xcef8de77, 0x7ab8b5b9, 0xfae6b9f9, 0x29ccf5ca }, + { 0x3608267f, 0x7a52e5c6, 0x9fdbd947, 0xcfba3e80, 0x4717c548, 0x5b608fdf, 0x33f2e088, 0x4ab88fbb }, + { 0x700a2ce0, 0x6f749bc9, 0x0ac79a52, 0x1131876f, 0x48ebcc95, 0x35d07e1f, 0xb9d74ba9, 0xd7921b16 }, + { 0x51a46b75, 0xc766b3c6, 0x48578341, 0xc3bc878e, 0xc66bbea3, 0x2fda0dee, 0xb8e1515d, 0x22418556 }, + { 0xf4e952f5, 0xd8bc0295, 0x8b8d38aa, 0x0454ab5f, 0x10ac6bff, 0x9e943f6b, 0x6d8261dc, 0x808848fa }, + { 0x08676a25, 0x53a51c13, 0x1499e10b, 0xd9a4b7f3, 0xed75250d, 0xafeff9bf, 0x7088a313, 0x10705dcc } + }, { + { 0xda4d4156, 0x2310acc4, 0x8796c548, 0x535057b7, 0x5f291ff3, 0x0ab20f35, 0x93677dbd, 0x8c69b6ff }, + { 0x8b23e30e, 0x377e12f7, 0x84fe2f73, 0xa0ec919d, 0xdfda6326, 0x364f7fbb, 0x49c45f6e, 0x8c07d4a6 }, + { 0xb0eb8c22, 0x6dbd3002, 0xe34f84e6, 0xe3c366d3, 0x5fc72e10, 0xf49caec5, 0x6f4011e3, 0x7038c38d }, + { 0x378ce4e5, 0xe32c4022, 0x5c14ed02, 0xba91e88a, 0x4851e798, 0x9b4f98a3, 0x42f08b90, 0x0fb74b93 }, + { 0x8ab2da23, 0x84b2842d, 0xf1a40d04, 0x9f7c214f, 0x4b8002b6, 0x6ce4980c, 0x126b27ca, 0xed7175f4 }, + { 0x197f7299, 0xd688ac97, 0x9beb4279, 0x98ba1391, 0xb3719aec, 0xb964a1f8, 0x978a9485, 0x4ca9040a }, + { 0x15a808bb, 0xbe72c01e, 0x2877ef97, 0x0ed78b1d, 0x5fdb6fda, 0x726d3364, 0xc27b0380, 0x03409578 } + }, { + { 0x79bc7204, 0x64526abc, 0x40af0d1a, 0xd11bd441, 0xdf5687c5, 0xbbeb13cf, 0x74ca0025, 0x3dd9bede }, + { 0x465c164f, 0x372e1d94, 0x1a462c98, 0x4e6403e1, 0x7df3d03d, 0x4783848b, 0xec8ef487, 0x1f061ad4 }, + { 0x47c833fd, 0xe27fbe58, 0xa294b457, 0x4cd1a6c5, 0x0c2cdbc2, 0xff516fc0, 0xed81d321, 0x026947cf }, + { 0x64801488, 0xd4be8cd3, 0x9ec4f1af, 0x2600e44b, 0x0851e417, 0x6b51068e, 0xafb6bbd8, 0x8208ae65 }, + { 0x22b24c03, 0xc7e6448f, 0x716e08f2, 0x7e796d97, 0xec9bef1b, 0x66e5667f, 0x5f9b745b, 0xdf228f44 }, + { 0xd8070eed, 0x7531be15, 0x2efd3d7a, 0xecaa0ad0, 0xc0972df5, 0xf776df8a, 0x9da8ab27, 0xf0b42ef2 }, + { 0x27bafa4a, 0x341a81c9, 0x2e360782, 0x7800401d, 0x7f594e2e, 0x80317127, 0x155af896, 0x2b098834 } + }, { + { 0x50ac8c98, 0xc821317d, 0xe30b6dea, 0x23732d03, 0xa22d2f11, 0x9108913c, 0x0e0c2e17, 0x80349b40 }, + { 0x4f6a1487, 0x7ee752e6, 0xa9a0b434, 0x2f14c67f, 0xa55c2d40, 0x659d83d5, 0x3f17486e, 0xac616a2a }, + { 0xe0d22f8c, 0x277371d7, 0xaeb933ff, 0xe5cd5a56, 0x07e8825b, 0xf521096e, 0xb055b9e1, 0x622f69fa }, + { 0x2428cf8a, 0x96d714c1, 0x58b73416, 0x272fc42b, 0x874dd8ab, 0x205d1af2, 0xb9bccc72, 0x52ebd7b0 }, + { 0xea28c322, 0x01162702, 0xc9086e8f, 0x10a1f1a4, 0x2b4ae4c0, 0xe95c95fb, 0x10ef8e49, 0xf033dba1 }, + { 0xaca39e67, 0x98d59def, 0x3d199fba, 0x93cc0046, 0x41389dab, 0x38150fc2, 0x989a4d46, 0x9b427328 }, + { 0x555f6fcd, 0x187aac65, 0x237ea7ba, 0x411845bb, 0x257ecc96, 0xa6d2b9a9, 0x186cd758, 0x745f3c59 } + }, { + { 0xd8bd778b, 0x2c224db8, 0x9cf37266, 0x92c241da, 0xef9a0dc7, 0xa0141780, 0xd85304c7, 0xc1778012 }, + { 0x0cdf909b, 0xd6e1b56b, 0x60844342, 0x0012b99b, 0x5069f160, 0xa8759687, 0x9408dadb, 0xa651525e }, + { 0xe24e6ac1, 0xffb01991, 0xa84ae5e6, 0xe3e71b0d, 0xd1af4e76, 0x014d0563, 0xbcbda8f5, 0x47931fcf }, + { 0xf3f7b396, 0x5b45d64a, 0xef5e27ef, 0x04134034, 0x4ea4b384, 0x0c55b7ac, 0x02877644, 0x7f08a13b }, + { 0x3ed1b355, 0x89d6f5bc, 0x9d48cc98, 0xa0759109, 0x82673778, 0xae7c9a53, 0x516c3cba, 0xa817b9b7 }, + { 0x44d407ce, 0x3866b2a0, 0x16966a1e, 0x1430f251, 0x37b831f0, 0xd52ce3d4, 0x78e95a9f, 0x59cf28c6 }, + { 0x3e4f2155, 0x7156e7b3, 0x1b86f8db, 0x42f7566f, 0x3e56da90, 0xf030b29f, 0xec85e66b, 0xcc52db57 } + }, { + { 0x7e6c0017, 0x413ffb3f, 0xb0eef332, 0x00c4654f, 0xd22aa38b, 0xa5efdb30, 0x5764e3b2, 0x30492695 }, + { 0x7147830a, 0xc93791b6, 0x90db318f, 0x59f91408, 0xf1ce4428, 0xa5ed3cc1, 0xc9e3126f, 0x3e65f4be }, + { 0xc9a52997, 0x98ec0cec, 0x845090c0, 0x972e21c7, 0xbec7b346, 0xc5a51cd5, 0xc2bc2364, 0x6feb2a2a }, + { 0x8c502344, 0xa133bc9b, 0x12e631f5, 0x1fad16db, 0xd9bc4a2a, 0x3ad8ef7f, 0xfa5e4e06, 0xf413547b }, + { 0x9d70f033, 0x9be7e0c8, 0xceaf3e95, 0xabeb2be0, 0xd6968817, 0xd3e5bff7, 0xc70e1698, 0x7dae7c15 }, + { 0x16bd8319, 0x45e55117, 0x4034e356, 0xf10d487f, 0xa76f4fdd, 0xf10370e7, 0x167a2453, 0x0422ab4f }, + { 0x7ad6b216, 0x238eb324, 0xc6461eeb, 0x807aa6b5, 0x162573a4, 0x7f90891c, 0xf78a4770, 0xee33693e } + }, { + { 0x85a61667, 0x3292f30e, 0x9d1df8cb, 0xe79682a4, 0xd306be03, 0xb1ecf6fd, 0xace14759, 0x0ecafaaa }, + { 0x88ba8325, 0x5da8e735, 0xf88401d1, 0x3a0b86eb, 0xca737832, 0x21d368fa, 0xa2131889, 0xf0bc2442 }, + { 0xd9cf985f, 0x4a150996, 0xab65117e, 0xbe002181, 0x08d679b9, 0x34f40192, 0x64e2a998, 0x1aeea04e }, + { 0xd12d7f84, 0xad3018df, 0x9c1f731a, 0xd6a1dc24, 0x855ded20, 0x0eda9d64, 0xb17fc497, 0x796fbdf7 }, + { 0x67abd4af, 0x9cf4fdd7, 0x1e56babd, 0x503eee44, 0x170363e2, 0x5693fd28, 0x51540b37, 0x05abe4c4 }, + { 0x2dbcd044, 0x2981a934, 0x73082781, 0xdd97b6b6, 0x64c3c92d, 0x421073bf, 0xe7ab4219, 0x23ede5ff }, + { 0x62112ae9, 0xe15f3626, 0x038a6317, 0x97a7f32e, 0xce90123d, 0xf02d754e, 0x6b218ea1, 0xa3c38d14 } + }, { + { 0x004fdc93, 0x4b7c873a, 0x95be1cc9, 0x7c5432d9, 0x6204127d, 0xed04d3d3, 0xfb64984a, 0x93d731b4 }, + { 0x6f366d43, 0xc3a3b935, 0x5963fb76, 0x268cd779, 0x192cd883, 0x7a64e33b, 0xd6034f31, 0x89e7e743 }, + { 0x3b30e2ca, 0x4a02b442, 0x69056f99, 0xce9b2bd3, 0xb4e7a87f, 0xc1d230ae, 0x3c6dfd11, 0xadaecce2 }, + { 0x33b83f9a, 0x6c0ad79b, 0x1322b694, 0x8d3f9e24, 0xf8fafbaa, 0xc6223143, 0x3f7c6091, 0xecb5943c }, + { 0x8d2da3dd, 0x5390be12, 0xb6cb6db1, 0x60743204, 0x48971e41, 0x887cd9fb, 0x1ade9d31, 0x8bc76839 }, + { 0xa9ce25de, 0xaea01431, 0xee284648, 0x0f997777, 0x9bad14ca, 0x68c4b3b4, 0xa3c32b11, 0x0bb9f4a5 }, + { 0x4ce7cbba, 0x930c6ce6, 0x1473d7e2, 0x5211cccf, 0x4bf9f56c, 0x608d15a9, 0x5471a71f, 0x9e4e1357 } + }, { + { 0xc4d4250a, 0xa90b2ff6, 0x997f0ad2, 0x313ed353, 0x1e270e78, 0x4d7bada7, 0xe504aed6, 0xeafcebb4 }, + { 0xb182f670, 0x1c0c6022, 0x002f8917, 0x94e9c583, 0x244640a1, 0x8f114879, 0xcbde6210, 0x25675f69 }, + { 0x0e5a14c7, 0x074528d1, 0xdc2eff1c, 0xfecb81e0, 0xe4331fb5, 0x8810cb7b, 0x3d824831, 0x9d9ed1fd }, + { 0x416b6738, 0x2bbbd78b, 0xaa4012a6, 0xeb2fd98b, 0x585477c8, 0x702e595a, 0xb322d949, 0xbe2d3a24 }, + { 0x111432d9, 0xd9b07718, 0xc0d6e5f3, 0x1c36e961, 0xd6090a73, 0xd1e819ff, 0xbaa7e4ff, 0x63968570 }, + { 0x9e470151, 0xb3d468a1, 0x9260b722, 0x13b5fa98, 0x5659a528, 0x9d28f8a5, 0x85adec37, 0xc606ba8d }, + { 0x3decc870, 0x6bd5556b, 0x6f7f7797, 0xd1b74770, 0x662aeb0c, 0x9be1606f, 0xa6aac5f5, 0xf85b350f } + }, { + { 0x9463a868, 0x960e8462, 0x4fa2b9d2, 0x178547e9, 0x50e71617, 0xd0d08216, 0x0c79d64f, 0x027df2d8 }, + { 0x5207ee10, 0xcf7670db, 0x2793abbb, 0x4cd968e9, 0x54e3fb50, 0x37d47190, 0x9b8e5703, 0x69bb7ec9 }, + { 0x627d9958, 0x55b42a06, 0xeba7f98d, 0x853170d7, 0xb54ca419, 0x69668fe7, 0x73cc969a, 0x10e096e6 }, + { 0x4c669696, 0x6232f551, 0x295b5a25, 0xd98e6e6c, 0x1b045ecc, 0xca537442, 0xd63dec57, 0x67e5a619 }, + { 0xb13e1282, 0xc06b8335, 0xe41b1193, 0xf3a2297d, 0xcf435007, 0x2fc34631, 0x42e4890c, 0xd3e85862 }, + { 0x160f81d9, 0xf12f48b1, 0x80668974, 0x1950027d, 0x58fe5eb0, 0x08db8df6, 0x70864927, 0x80dab7b3 }, + { 0x293bd8ba, 0xddaf78c7, 0x59d74859, 0x3e8ccc1f, 0xab08d45e, 0xed90a269, 0x800f365d, 0x8c05ec5d } + }, { + { 0x9f5f3ef3, 0x2d06c644, 0xb7ddb6d2, 0x950116f7, 0x81d0f434, 0x7fbfe324, 0x99cfa463, 0x477b1d3f }, + { 0x9ad80019, 0x67c3a9f1, 0x610da4c5, 0x90954ce4, 0x0e1f8a78, 0xf1763ba4, 0xbbf73d7c, 0x713419a7 }, + { 0xabda8eda, 0x14be0d15, 0x98601e48, 0x0b327788, 0xdfadef27, 0x4d6eddd5, 0x2012e79c, 0x53ea34cb }, + { 0x26c758c6, 0xa962c123, 0xb1c5450f, 0x3f6130f7, 0xd65a9947, 0x822f1cec, 0x2f8ca7fd, 0x8885d745 }, + { 0xfb8d48d8, 0x26b785b6, 0xb67ce850, 0x688eb713, 0x6fcb4007, 0xa4218806, 0x826c9739, 0x867b567a }, + { 0xb6d72f91, 0xb4dffd3c, 0xf35f61df, 0x8ca0924d, 0x5f4f3ed7, 0xaf3a604d, 0xbad24bb6, 0x4d6bca16 }, + { 0x0af40433, 0xb22010f7, 0x84fff4b4, 0xbb531995, 0x6e7f6aa6, 0x702b82b7, 0xc314eff3, 0x45c6ace3 } + }, { + { 0x38c8eb70, 0x2f7a7d96, 0x425f1213, 0xa9d56023, 0x686f2536, 0x07d95255, 0x03efb3d3, 0x6e3c2be9 }, + { 0x8ccf431c, 0x005f2155, 0x9e8a76f3, 0x3302280a, 0x1f626419, 0xfebd98fa, 0x0d7dbeb5, 0xed228f84 }, + { 0xc7755f65, 0xcc789750, 0x80422eeb, 0xb70e3300, 0x3800488e, 0x66a47b99, 0x80fe5bcd, 0x810df768 }, + { 0x58a9e2b8, 0x6ace6cd2, 0xa26dc819, 0x9da0d6fd, 0xf57318e5, 0xbb2a6cde, 0x00f88e64, 0x45988afc }, + { 0x2db24f74, 0x8e84b606, 0xdd85891e, 0xbaf24e72, 0xae366b70, 0xfc18da2c, 0xe1937d7c, 0xc7edf94e }, + { 0x30f8d51c, 0x431a2e5e, 0x318780b1, 0x90c156f8, 0x7f325d96, 0x92cd03b5, 0x408db8b8, 0x3e2e340e }, + { 0xb5fb3838, 0x5226821f, 0xadbb4294, 0xff433812, 0x03075206, 0x386d18f7, 0xddc08239, 0xeb3a3609 } + }, { + { 0x1deb0d7b, 0x486e7970, 0x528c5c8b, 0xc4ddea85, 0x65c479ca, 0xb2564b35, 0xd106470c, 0xc6e35fb4 }, + { 0xf289ae55, 0xde118bf3, 0x84673fb0, 0x7ed5665d, 0xf2e4e8b5, 0xfc0244ef, 0x76dd77b7, 0x4ac503f2 }, + { 0x0e420397, 0x7e9632d7, 0xa0bda73b, 0x2458b8f3, 0xc2fbafbd, 0x582c46ee, 0x06d1d65c, 0x037da5f2 }, + { 0x8b9f4092, 0x5843804a, 0x8bedf071, 0x2f5315ce, 0x9373f07a, 0xebdcc2ef, 0xb0b2a12f, 0xbdfcf2ef }, + { 0xd2495e4d, 0x04d95d4a, 0x510f2342, 0x68606545, 0x19de4d07, 0xd71ca9aa, 0x3b06212e, 0xf56f82a2 }, + { 0x1e58fff3, 0xbfbdfaa3, 0x3e0c674c, 0x8e03a28b, 0x37ae6d19, 0xf92f3944, 0x5135fbc5, 0xbe4b52f3 }, + { 0x50d0f9af, 0xde678fe8, 0xb238077d, 0x177dba54, 0xa139d3f3, 0xe9e8df29, 0x3f63742f, 0x312b32de } + }, { + { 0x20c56647, 0x8707018f, 0x3b9ba5d0, 0x300bf55c, 0x8d003323, 0xf98aac6b, 0x583300fd, 0xba8bbc8b }, + { 0xb1545d91, 0x254a8fe3, 0xd49bcfd4, 0xacfee11d, 0xf10d406e, 0x64fcfcde, 0x027e13a9, 0x8aa5595c }, + { 0x512d3bdc, 0xcbc66bb2, 0x9908c828, 0xca5b4f81, 0x97deef7d, 0xb796061b, 0xb7ceff8c, 0xeecf09d9 }, + { 0x2d27dfaa, 0x4738165d, 0x28e7a55f, 0x420813e3, 0xaa8440a4, 0xeef99bfb, 0x71666ba2, 0x86a51a80 }, + { 0xd7791222, 0x692bc41b, 0x3bdbac31, 0x82cb05cd, 0x5b4b3744, 0x4b665815, 0x1762b639, 0xa878d6ea }, + { 0x854b7d2e, 0x8fc1d536, 0x9ce4db12, 0xe32bf6c4, 0xb0290fba, 0x0faaf22e, 0xfece04ff, 0x4474f689 }, + { 0x049f5deb, 0x94fc8dbd, 0x905a535b, 0xc429ceed, 0xfbb317ac, 0xac96fdf2, 0x7e3b05ff, 0x4860d996 } + }, { + { 0xe50c69fb, 0x0fa77338, 0xf79fca72, 0x3e0d30ba, 0x598ada93, 0x2e435d52, 0x3d70cfcb, 0x22182bb3 }, + { 0x67ecc251, 0x18318183, 0x5b1696e1, 0xc13a2c4c, 0x086c6392, 0x72273fd6, 0xe20aaf30, 0x301201b3 }, + { 0x54b990a1, 0xafa6328d, 0xe63abcb1, 0xc78f2775, 0x1fb1d8ce, 0x4747f283, 0x8359e523, 0xf469ed88 }, + { 0x152b5010, 0x806afb62, 0xb91dc4e0, 0x7c018a3e, 0xbc7a0eed, 0x23dfe690, 0xfe576b7d, 0xfdf38e7e }, + { 0x8072da71, 0xd96c2ee9, 0x62f4f37c, 0xf03b9d8b, 0x15b73a44, 0xfe52a7a2, 0xb9917a0a, 0xbdafea91 }, + { 0xdbb7e37d, 0xc70465f7, 0xfcc5723f, 0xdaf07719, 0x65d54e8e, 0x3136c077, 0xfcc41d56, 0x07484576 }, + { 0x9947b804, 0xc1b2266f, 0xed448fa2, 0x3522089b, 0x0bf4534a, 0xdbbbf3e1, 0xc7f929be, 0x9515c273 } + }, { + { 0xa83022c6, 0xdb2ba386, 0x31b8e1d9, 0xba05e0c5, 0x94d029ac, 0x7f9578b5, 0x09a69555, 0xb8166017 }, + { 0xaf323459, 0x6ecdb983, 0x636b45aa, 0x66e075ee, 0x5483eec4, 0x96aa3f50, 0x08ddc9f1, 0x7e31f4ce }, + { 0x255b7d94, 0x231d7a81, 0x6b9df41e, 0xb8968891, 0xce185a87, 0x1fe0e0be, 0x0df6fc87, 0xc18d383f }, + { 0xdcf87a84, 0xe0e68384, 0xbb49e230, 0x481ba3be, 0x84748f2a, 0xb00aab60, 0xfc179e9d, 0x857bf2d0 }, + { 0x468c6a70, 0x17f68dbc, 0xf05e454c, 0x0bf04d87, 0xf7a98200, 0x34985943, 0xd4fff833, 0xf2cc253c }, + { 0xeb13b6bc, 0x2abf96a3, 0x4b7201e1, 0x625b4424, 0x3c3b2563, 0xca66a69c, 0x7394f29b, 0xcdb92b85 }, + { 0x087361bf, 0x616d40cd, 0x560b5746, 0x09434f03, 0xdc133705, 0xe050c7f1, 0xc7506a47, 0xcdf0be50 } + }, { + { 0x31691ebe, 0xed7a1f62, 0x1d69e367, 0x3dcbe08d, 0x975e71fd, 0xe8bc4d75, 0xaf7a2810, 0x3d73950c }, + { 0x7fbea22e, 0x381d20eb, 0xf0431b54, 0xa3e5c8d3, 0xbeebc5f7, 0xb5095b34, 0xf45251e1, 0x88b5d9b1 }, + { 0xc349242a, 0x14d7252d, 0x2a93b81e, 0x054d16ea, 0x60c50aeb, 0x276e8239, 0xf503cbea, 0x77592aa0 }, + { 0x8c68a879, 0xa959997a, 0x128f9d7c, 0x0618dc7a, 0xca0be3f4, 0x9d2ac2de, 0xadea324d, 0x5152f278 }, + { 0x7ba250da, 0x94183f87, 0x7019ad76, 0x69075f7d, 0x393cd782, 0xfd52b891, 0x00d8292c, 0x8c3b2734 }, + { 0xe0c3a509, 0x77a7350d, 0xa83ccc53, 0xb9e8244d, 0x8a5ef941, 0x66d5acf8, 0x6180cea4, 0x885eae04 }, + { 0x33a9c3dc, 0x01868bc2, 0x58c61de7, 0x7a93fa06, 0x4cd9f562, 0x9e8a0747, 0x32ba8e08, 0x3780b278 } + }, { + { 0x47db582e, 0xcd9cf0ad, 0x42101761, 0x077c78e6, 0x9c974652, 0x58e18de7, 0x72feea9d, 0x8372f246 }, + { 0xa45c7958, 0xc3223948, 0x059a7b58, 0xa433e03e, 0x6e478fb3, 0xbc6e5186, 0x5f0167ff, 0x61aa9962 }, + { 0xd297083a, 0x237b9355, 0x16b460e9, 0xd4cf70b8, 0x4906f286, 0xa5062552, 0xb472874b, 0x8f8c7562 }, + { 0x2d990849, 0xa8418e55, 0xce78dfe3, 0xe7ad865d, 0x617900a0, 0x83b88f64, 0xc27917ea, 0x81ea7038 }, + { 0x215656ee, 0x78aff999, 0x32b79d72, 0x1d8dc5e7, 0x5f629263, 0xc73af887, 0xd1ebc2ca, 0x77175169 }, + { 0x7ecaa5e2, 0x82a28565, 0x3eaf012b, 0x1f5dd8a3, 0x25574e50, 0x7fda2c4e, 0xd1bec96d, 0x8d1493d8 }, + { 0x450ac92b, 0xb6dac065, 0x5252896a, 0xea9055a2, 0x2bff2eda, 0x0b71a456, 0xb20bc57e, 0x5ebd3e5a } + }, { + { 0x06c28b5e, 0x6b9af341, 0xe09f4468, 0x9d2942b7, 0xf206afe2, 0x0898c6d7, 0xce1e17b7, 0xfaf50486 }, + { 0xc086eb33, 0xfb2b6a81, 0xbd4ef528, 0xf7e2d3cf, 0x9f2e3896, 0x15837e91, 0x310fb58a, 0xe009f48a }, + { 0xd005ba52, 0x522d35b6, 0x15f76f74, 0x75fbe015, 0x8d2e6b40, 0x3fc9317c, 0x4012e5a2, 0xe1fedc4c }, + { 0x074e5abb, 0x25793158, 0x022c125d, 0x1cfddb5d, 0xba7d82a7, 0xde9481a9, 0x2d356f09, 0x4be7edfb }, + { 0x92519f67, 0x66d2c133, 0x74d7190b, 0xe4b1a9dd, 0xa9e0885b, 0xb658ca08, 0xeca0c4f2, 0x9fdd88af }, + { 0x4975562d, 0x84b67be0, 0x4891487e, 0xd2fa6000, 0x38c919df, 0x0d2b7e56, 0x2b5ee426, 0x6f440a1e }, + { 0xbbb1339d, 0x7f5e833c, 0x735df589, 0xa4339e2e, 0x7eb48658, 0x080d8e72, 0xc3a7c99b, 0x43ca835b } + }, { + { 0x3dda52d9, 0xf2307b82, 0x07f1fc1c, 0x59143e86, 0x954e4d90, 0x966cf48a, 0xd9b0d66b, 0xc427b10d }, + { 0x4eb94575, 0xf29126c3, 0x81ea3d87, 0xe06246ca, 0x505883b1, 0xc5bc93ce, 0x358bd5f6, 0xe72a8c73 }, + { 0xdd3b93c6, 0x2767b96b, 0x60dd053f, 0x10cfa310, 0x4abd4f8c, 0x5372a39c, 0x5d54a330, 0xab1867e5 }, + { 0x62c948d4, 0x0b47f1b0, 0xad0ea37e, 0x4efbb4b4, 0x1716ebc5, 0x4ee5e170, 0xbbaca4d8, 0x43e62ff2 }, + { 0xf7d0b782, 0xf1e49ad1, 0xeadeed67, 0x99c2da1b, 0x00894847, 0x90dfa1f7, 0xaf6daa4f, 0x7b4829b6 }, + { 0xde5d8713, 0x35a5b31b, 0xb748800a, 0xdac38349, 0xde103af5, 0xe1d73ccc, 0x46ba0ddc, 0x39306645 }, + { 0x3a06b9a1, 0x160b972a, 0x521c321f, 0xa004069e, 0x83a16ede, 0x98b00b31, 0x60f9f83c, 0x1f35d1c1 } + }, { + { 0xd597421f, 0x2d9b1d10, 0xf4980375, 0xa24461bc, 0x82196094, 0xa0ab2368, 0xf9a7cb16, 0x388ad687 }, + { 0xe38b6868, 0xfbeed35b, 0xe06b3c03, 0x4c8c1665, 0x9eab9ce9, 0x7bc8d118, 0x812d2907, 0x440b0c84 }, + { 0x3deb66a1, 0x197f9e3d, 0x0f19712a, 0xeacb42bd, 0xc83f1bba, 0x86c68e82, 0xbe6fa356, 0x597095e0 }, + { 0x8f291e99, 0xcaba9ad8, 0x2f7dedc7, 0xb5b6f892, 0xc616aa71, 0x263f9cc4, 0x57016837, 0x64a8c843 }, + { 0xa20493f4, 0x53ab7293, 0xf991fbdc, 0xb999d658, 0x72479e76, 0x6e506638, 0x22cf1ace, 0x15063027 }, + { 0xd083da24, 0xfe918278, 0x0d92f48b, 0x6f9957b8, 0x5d7cdfd2, 0xa98cbc77, 0x958b6fa5, 0x00d75485 }, + { 0xb1ac8616, 0x0bc3844a, 0x47346240, 0x639d46b0, 0x81ac702b, 0x0f4a717f, 0x13fc3167, 0x2163fe2d } + }, { + { 0xe9f3460c, 0x2f82243d, 0x0f6e44bd, 0x04bbb112, 0x975dc2aa, 0x0df79c3b, 0xa615c4b5, 0x1fbf4268 }, + { 0x46df1de0, 0xbf6a680f, 0xd832e15c, 0xb61b8fa1, 0x4bac69a6, 0xd0eed295, 0x452d9e96, 0x2e1e63d6 }, + { 0xd6c9f2e4, 0x57cd73e4, 0xb946d1a1, 0x1bdb407c, 0x4ad02a64, 0x04340e80, 0x0898a05c, 0x9a339f6a }, + { 0xe28c995d, 0xda871bd6, 0x734c3b3d, 0x624eb50c, 0x6eb8b37f, 0x06ab1aee, 0x819da6da, 0x2ccd5f1f }, + { 0x610813ba, 0x1c4a8420, 0xa489796e, 0x864a3542, 0x81a25499, 0x070bd68b, 0x742e1f71, 0x1e667a0b }, + { 0x0df38684, 0x47a20eaa, 0xad42ba4d, 0xe3c176da, 0xd33439dc, 0x3aea032f, 0x61bc2c8f, 0xc6fb92ff }, + { 0x991932d7, 0xc28287b1, 0x844ceb4f, 0x691a97fc, 0x40e4d88a, 0xb10977da, 0x8b8aa1d9, 0x9691909a }*/ + } }; + +#define SEC1 0 +#define PUB1_X 1 +#define PUB1_Y 2 +#define SEC2 3 +#define PUB2_X 4 +#define PUB2_Y 5 +#define SHARED 6 + +uint32_t ecc_keys[][9] = { + { 0xFC632550, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 1 }, + { 0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0 }, + { 0xFC632552, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0 } +}; + +/*---------------------------------------------------------------------------*/ + +void +test_ecc() +{ + uint32_t i; + + uint32_t order[8] = { 0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF }; + for(i = 0; i < 3; i++) { + printf("ECC valid key test %d/3 - %s\n", i + 1, (ecc_is_valid_key(ecc_keys[i], order) == ecc_keys[i][8] ? "Succeed" : " Failed")); + } + + uint32_t base_x[8] = { 0xd898c296, 0xf4a13945, 0x2deb33a0, 0x77037d81, 0x63a440f2, 0xf8bce6e5, 0xe12c4247, 0x6b17d1f2 }; + uint32_t base_y[8] = { 0x37bf51f5, 0xcbb64068, 0x6b315ece, 0x2bce3357, 0x7c0f9e16, 0x8ee7eb4a, 0xfe1a7f9b, 0x4fe342e2 }; + uint32_t test_x[8]; + uint32_t test_y[8]; + for(i = 0; i < 32; i++) { + uint32_t time; + uint32_t checkvar; + + printf("Starting ECC test %d/221:\n", i + 1); + + time = *MACA_CLK; + ecc_ec_mult(test_x, test_y, base_x, base_y, ecc_data[i][SEC1]); + time = *MACA_CLK - time; + checkvar = 0; + checkvar += memcmp(ecc_data[i][PUB1_X], test_x, 32); + checkvar += memcmp(ecc_data[i][PUB1_Y], test_y, 32); + printf(" 1/4 finished after % 4u ms - %s\n", time / 250, (checkvar ? " Failed" : "Succeed")); + + time = *MACA_CLK; + ecc_ec_mult(test_x, test_y, ecc_data[i][PUB1_X], ecc_data[i][PUB1_Y], ecc_data[i][SEC2]); + time = *MACA_CLK - time; + checkvar = 0; + checkvar += memcmp(ecc_data[i][SHARED], test_x, 32); + printf(" 2/4 finished after % 4u ms - %s\n", time / 250, (checkvar ? " Failed" : "Succeed")); + + time = *MACA_CLK; + ecc_ec_mult(test_x, test_y, base_x, base_y, ecc_data[i][SEC2]); + time = *MACA_CLK - time; + checkvar = 0; + checkvar += memcmp(ecc_data[i][PUB2_X], test_x, 32); + checkvar += memcmp(ecc_data[i][PUB2_Y], test_y, 32); + printf(" 3/4 finished after % 4u ms - %s\n", time / 250, (checkvar ? " Failed" : "Succeed")); + + time = *MACA_CLK; + ecc_ec_mult(test_x, test_y, ecc_data[i][PUB2_X], ecc_data[i][PUB2_Y], ecc_data[i][SEC1]); + time = *MACA_CLK - time; + checkvar = 0; + checkvar += memcmp(ecc_data[i][SHARED], test_x, 32); + printf(" 4/4 finished after % 4u ms - %s\n", time / 250, (checkvar ? " Failed" : "Succeed")); + } +} +/* Start Process */ +PROCESS(server_firmware, "Server Firmware"); +AUTOSTART_PROCESSES(&server_firmware); + +PROCESS_THREAD(server_firmware, ev, data) { + PROCESS_BEGIN(); + + test_ecc(); + + PROCESS_END(); +} diff --git a/examples/econotag-flash-test/Makefile b/examples/econotag-flash-test/Makefile new file mode 100644 index 000000000..82905440e --- /dev/null +++ b/examples/econotag-flash-test/Makefile @@ -0,0 +1,31 @@ +CONTIKI = ../.. +LIBMC1322X = ../../../libmc1322x + +CONTIKI_PROJECT = econotag-flash-test +TARGET = econotag +CLEAN = *.d $(CONTIKI_PROJECT)_e_$(TARGET).bin $(CONTIKI_PROJECT)_e_$(TARGET).txt $(CONTIKI_PROJECT)_e_$(TARGET).pbm + +all: $(CONTIKI_PROJECT) blast + +CFLAGS += -DFLASH_CONF_B1=30 +CFLAGS += -DFLASH_CONF_B2=10 + +APPS += flash + +flash: + $(LIBMC1322X)/tools/mc1322x-load \ + -f $(LIBMC1322X)/tests/flasher_$(TARGET).bin \ + -s $(CONTIKI_PROJECT)_e_$(TARGET).bin \ + -c 'sudo $(LIBMC1322X)/tools/ftditools/bbmc -l $(TARGET) -i 0 reset' \ + -t /dev/ttyUSB1 -l + +clear: + $(LIBMC1322X)/tools/ftditools/bbmc -l $(TARGET) -i 0 erase + +blast: $(CONTIKI)/tools/blaster/blaster + $(CONTIKI)/tools/blaster/blaster $(CONTIKI_PROJECT).cfg + +$(CONTIKI)/tools/blaster/blaster: $(CONTIKI)/tools/blaster/blaster.c + (cd $(CONTIKI)/tools/blaster && $(MAKE)) + +include $(CONTIKI)/Makefile.include diff --git a/examples/econotag-flash-test/README b/examples/econotag-flash-test/README new file mode 100644 index 000000000..ee8aa7d3d --- /dev/null +++ b/examples/econotag-flash-test/README @@ -0,0 +1,6 @@ +Its important to use -l as a flash parameter for mc1322xload. + +Use "make flash" to start upload. Maybe u need +to change the location of libmc1322x in Makefile. + +With "make clear" you can erase all flash data. diff --git a/examples/econotag-flash-test/econotag-flash-test.c b/examples/econotag-flash-test/econotag-flash-test.c new file mode 100644 index 000000000..04ef42d8f --- /dev/null +++ b/examples/econotag-flash-test/econotag-flash-test.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Flash test + * + * This file contains tests for econotag flash app + * + * \author + * Lars Schmertmann + */ + +#include "flash.h" +#include "contiki.h" + +#include +#include +#include + +#include "../../tools/blaster/blaster.h" +#include "econotag-flash-test.h" + +void +output_result(uint32_t i, uint32_t fail) +{ + if(fail) { + printf(" Test %u failed!\n", i); + } else { printf(" Test %u succeed!\n", i); + } +} +void +test_flash_1() +{ + uint8_t buffer[12]; + uint32_t check_int, my_int = 12345678; + + flash_setVar("Hello World!", RES_MY_STRING_1, LEN_MY_STRING_1); + + flash_getVar(buffer, RES_MY_STRING_1, LEN_MY_STRING_1); + output_result(1, memcmp(buffer, "Hello World!", 12)); + + flash_setVar("Heureka!", RES_MY_STRING_2, LEN_MY_STRING_2); + + flash_getVar(buffer, RES_MY_STRING_1, LEN_MY_STRING_1); + output_result(2, memcmp(buffer, "Hello World!", 12)); + + flash_getVar(buffer, RES_MY_STRING_2, LEN_MY_STRING_2); + output_result(3, memcmp(buffer, "Heureka!", 8)); + + flash_setVar(&my_int, RES_MY_INTEGER, LEN_MY_INTEGER); + + flash_getVar(&check_int, RES_MY_INTEGER, LEN_MY_INTEGER); + output_result(4, check_int != my_int); + + flash_getVar(buffer, RES_MY_STRING_1, LEN_MY_STRING_1); + output_result(5, memcmp(buffer, "Hello World!", 12)); + + flash_getVar(buffer, RES_MY_STRING_2, LEN_MY_STRING_2); + output_result(6, memcmp(buffer, "Heureka!", 8)); +} +void +test_flash_2() +{ + uint8_t buffer[12]; + uint32_t check_int, my_int = 12345678; + + flash_getVar(&check_int, RES_MY_INTEGER, LEN_MY_INTEGER); + output_result(1, check_int != my_int); + + flash_getVar(buffer, RES_MY_STRING_1, LEN_MY_STRING_1); + output_result(2, memcmp(buffer, "Hello World!", 12)); + + flash_getVar(buffer, RES_MY_STRING_2, LEN_MY_STRING_2); + output_result(3, memcmp(buffer, "Heureka!", 8)); + + /* Block 1 max usage is 30 Byte -> Optimisation in Makefile */ + output_result(4, flash_setVar("test", 0, 1) != gNvmErrInvalidPointer_c); + output_result(5, flash_setVar("test", 30, 1) != gNvmErrInvalidPointer_c); + output_result(6, flash_setVar("test", 29, 2) != gNvmErrAddressSpaceOverflow_c); + + /* Block 2 max usage is 10 Byte -> Optimisation in Makefile */ + output_result(7, flash_setVar("test", 4096, 1) != gNvmErrInvalidPointer_c); + output_result(8, flash_setVar("test", 4096 + 10, 1) != gNvmErrInvalidPointer_c); + output_result(9, flash_setVar("test", 4096 + 9, 2) != gNvmErrAddressSpaceOverflow_c); +} +void +test_flash_blaster() +{ + uint8_t buffer[64]; + + flash_getVar(buffer, RES_NAME, LEN_NAME); + output_result(1, memcmp(buffer, "Econotag Flash Test Device", 27)); + + flash_getVar(buffer, RES_MODEL, LEN_MODEL); + output_result(2, memcmp(buffer, "Model 1234 for testing purposes only", 37)); +} +void +test_flash_stack() +{ + uint8_t buffer[32]; + flash_stack_init(); + + output_result(1, flash_stack_size() != 0); + + flash_stack_push("Hello World!", 12); + output_result(2, flash_stack_size() != 12); + + flash_stack_read(buffer, 0, 12); + output_result(3, memcmp(buffer, "Hello World!", 12)); + + flash_stack_push("I love Contiki!", 15); + output_result(4, flash_stack_size() != 27); + + flash_stack_read(buffer, 0, 12); + output_result(5, memcmp(buffer, "Hello World!", 12)); + + flash_stack_read(buffer, 12, 15); + output_result(6, memcmp(buffer, "I love Contiki!", 15)); + + flash_stack_init(); + output_result(7, flash_stack_size() != 0); + + uint32_t i; + for(i = 1; i < 256; i++) { + flash_stack_push("I love Contiki! ", 16); + } + output_result(8, flash_stack_size() != 4080); + + output_result(9, flash_stack_push("1I love Contiki! ", 17) != gNvmErrAddressSpaceOverflow_c); +} +/* Start Process */ +PROCESS(server_firmware, "Server Firmware"); +AUTOSTART_PROCESSES(&server_firmware); + +PROCESS_THREAD(server_firmware, ev, data) { + PROCESS_BEGIN(); + + if(flash_cmp("\001", RES_DONTCLEAR, LEN_DONTCLEAR)) { + printf("Initializing flash ... "); + flash_init(); + printf("DONE\n"); + flash_setVar("\001", RES_DONTCLEAR, LEN_DONTCLEAR); + printf("Starting flash tests 1:\n"); + test_flash_1(); + int i; + for(i = 0; i < 1024; i++) { + printf("Reboot ...\r"); + } + soft_reset(); + } else { + printf("Initialization not wished\n"); + } + printf("Starting flash tests 2:\n"); + test_flash_2(); + + printf("Starting flash stack tests:\n"); + test_flash_stack(); + + printf("Starting flash blaster tests:\n"); + test_flash_blaster(); + + PROCESS_END(); +} diff --git a/examples/econotag-flash-test/econotag-flash-test.cfg b/examples/econotag-flash-test/econotag-flash-test.cfg new file mode 100644 index 000000000..9b26c4adb --- /dev/null +++ b/examples/econotag-flash-test/econotag-flash-test.cfg @@ -0,0 +1,7 @@ +input = "econotag-flash-test_econotag"; +output = "econotag-flash-test_e_econotag"; +eui = [ 0x2, 0x0, 0x0, 0x0, 0x12, 0x34, 0x56, 0x78 ]; +uuid = "cbf9889f-dc0e-4c18-9aa9-93509a6c102a"; +psk = "yCh0OXnSkFT-eXKE"; +name = "Econotag Flash Test Device"; +model = "Model 1234 for testing purposes only"; diff --git a/examples/econotag-flash-test/econotag-flash-test.h b/examples/econotag-flash-test/econotag-flash-test.h new file mode 100644 index 000000000..469d93faa --- /dev/null +++ b/examples/econotag-flash-test/econotag-flash-test.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Flash Management + * + * This file contains Pointers for manual flash management. + * + * \author + * Lars Schmertmann + */ + +#ifndef ECONOTAG_FLASH_TEST_H_ +#define ECONOTAG_FLASH_TEST_H_ + +/* Pointer for Block 1 --------------- */ + +#define RES_DONTCLEAR 1 +#define LEN_DONTCLEAR 1 + +#define RES_MY_STRING_1 2 +#define LEN_MY_STRING_1 12 + +#define RES_MY_STRING_2 14 +#define LEN_MY_STRING_2 8 + +/* Pointer for Block 2 --------------- */ + +#define RES_MY_INTEGER (4096 + 1) +#define LEN_MY_INTEGER 4 + +/* ------------------------------------ */ + +#endif /* ECONOTAG_FLASH_TEST_H_ */ diff --git a/examples/eeprom-test/Makefile b/examples/eeprom-test/Makefile index 46c909138..a99ce8944 100644 --- a/examples/eeprom-test/Makefile +++ b/examples/eeprom-test/Makefile @@ -3,4 +3,5 @@ all: $(CONTIKI_PROJECT) TARGET=mbxxx CONTIKI = ../.. +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/email/Makefile b/examples/email/Makefile index 0c466edfd..3adf8d847 100644 --- a/examples/email/Makefile +++ b/examples/email/Makefile @@ -4,4 +4,5 @@ all: $(CONTIKI_PROJECT) APPS = email CONTIKI = ../.. +CONTIKI_WITH_IPV4 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/email/Makefile.apple2enh.defines b/examples/email/Makefile.apple2enh.defines deleted file mode 100644 index 05a72fd5d..000000000 --- a/examples/email/Makefile.apple2enh.defines +++ /dev/null @@ -1 +0,0 @@ -DEFINES = WITH_CLIENT,WITH_DNS,WITH_GUI,WITH_MOUSE,WITH_PFS diff --git a/examples/email/Makefile.atarixl.defines b/examples/email/Makefile.atarixl.defines deleted file mode 100644 index 5a292701b..000000000 --- a/examples/email/Makefile.atarixl.defines +++ /dev/null @@ -1 +0,0 @@ -DEFINES = WITH_CLIENT,WITH_DNS,WITH_GUI,WITH_MOUSE diff --git a/examples/email/Makefile.c128.defines b/examples/email/Makefile.c128.defines deleted file mode 100644 index 688d85113..000000000 --- a/examples/email/Makefile.c128.defines +++ /dev/null @@ -1 +0,0 @@ -DEFINES = WITH_CLIENT,WITH_DNS,WITH_GUI,WITH_PFS diff --git a/examples/email/Makefile.c64.defines b/examples/email/Makefile.c64.defines deleted file mode 100644 index 05a72fd5d..000000000 --- a/examples/email/Makefile.c64.defines +++ /dev/null @@ -1 +0,0 @@ -DEFINES = WITH_CLIENT,WITH_DNS,WITH_GUI,WITH_MOUSE,WITH_PFS diff --git a/examples/er-rest-example-raven/Makefile b/examples/er-rest-example-raven/Makefile new file mode 100644 index 000000000..02cfb3c18 --- /dev/null +++ b/examples/er-rest-example-raven/Makefile @@ -0,0 +1,15 @@ +TARGET=avr-raven + +APPS += raven-lcd-interface + +export + +CONTIKI=../.. + +ER_REST_EXAMPLE=$(CONTIKI)/examples/er-rest-example + +all %: + @(cd $(ER_REST_EXAMPLE) && $(MAKE) $@) + @echo + @echo "*** Binaries can be found in $(ER_REST_EXAMPLE) ***" + diff --git a/examples/er-rest-example/Makefile b/examples/er-rest-example/Makefile index 9a72bf63a..817a83b9d 100644 --- a/examples/er-rest-example/Makefile +++ b/examples/er-rest-example/Makefile @@ -1,78 +1,49 @@ all: er-example-server er-example-client -# use this target explicitly if requried: er-plugtest-server - - -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 - - -# for some platforms -UIP_CONF_IPV6=1 -# IPv6 make config disappeared completely -CFLAGS += -DUIP_CONF_IPV6=1 +# use target "er-plugtest-server" explicitly when requried CONTIKI=../.. + CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" -# variable for Makefile.include -ifneq ($(TARGET), minimal-net) -CFLAGS += -DUIP_CONF_IPV6_RPL=1 +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +ifndef TARGET +REST_RESOURCES_FILES = $(notdir $(shell find $(REST_RESOURCES_DIR) -name '*.c')) else -# minimal-net does not support RPL under Linux and is mostly used to test CoAP only -${info INFO: compiling without RPL} -CFLAGS += -DUIP_CONF_IPV6_RPL=0 -CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" -${info INFO: compiling with large buffers} -CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048 -CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 -CFLAGS += -DCOAP_MAX_HEADER_SIZE=640 +ifeq ($(TARGET), native) +REST_RESOURCES_FILES = $(notdir $(shell find $(REST_RESOURCES_DIR) -name '*.c')) +else +REST_RESOURCES_FILES = $(notdir $(shell find $(REST_RESOURCES_DIR) -name '*.c' ! -name 'res-plugtest*')) endif +endif + +PROJECTDIRS += $(REST_RESOURCES_DIR) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) # linker optimizations SMALL=1 -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif - -APPS += erbium +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine # optional rules to get assembly #CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 #CUSTOM_RULE_S_TO_OBJECTDIR_O = 1 +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include +# minimal-net target is currently broken in Contiki +ifeq ($(TARGET), minimal-net) +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: er-example compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=1300 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=176 +CONTIKI_WITH_RPL=0 +endif + # optional rules to get assembly #$(OBJECTDIR)/%.o: asmdir/%.S # $(CC) $(CFLAGS) -MMD -c $< -o $@ @@ -86,10 +57,13 @@ $(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c (cd $(CONTIKI)/tools && $(MAKE) tunslip6) connect-router: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + sudo $(CONTIKI)/tools/tunslip6 fd00::1/64 connect-router-cooja: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 -p 60001 fd00::1/64 + +connect-router-native: $(CONTIKI)/examples/ipv6/native-border-router/border-router.native + sudo $(CONTIKI)/exmples/ipv6/native-border-router/border-router.native -a 127.0.0.1 -p 60001 fd00::1/64 connect-minimal: - sudo ip address add fdfd::1/64 dev tap0 + sudo ip address add fdfd::1/64 dev tap0 diff --git a/examples/er-rest-example/README.md b/examples/er-rest-example/README.md index 1aa35b091..25abd60e4 100644 --- a/examples/er-rest-example/README.md +++ b/examples/er-rest-example/README.md @@ -21,9 +21,10 @@ PRELIMINARIES You can disable RDC in border-router project-conf.h (not really required as BR keeps radio turned on). #undef NETSTACK_CONF_RDC #define NETSTACK_CONF_RDC nullrdc_driver +- Alternatively, you can use the native-border-router together with the slip-radio. - For convenience, define the Cooja addresses in /etc/hosts - aaaa::0212:7401:0001:0101 cooja1 - aaaa::0212:7402:0002:0202 cooja2 + fd00::0212:7401:0001:0101 cooja1 + fd00::0212:7402:0002:0202 cooja2 ... - Get the Copper (Cu) CoAP user-agent from [https://addons.mozilla.org/en-US/firefox/addon/copper-270430](https://addons.mozilla.org/en-US/firefox/addon/copper-270430) @@ -81,11 +82,11 @@ TMOTES HOWTO 3. Start Copper and discover resources at: - coap://[aaaa::____:____:____:____]:5683/ + coap://[fd00::____:____:____:____]:5683/ ### Add a client: -1. Change the hard-coded server address in er-example-client.c to aaaa::____:____:____:____ +1. Change the hard-coded server address in er-example-client.c to fd00::____:____:____:____ 2. Connect a third Tmote Sky make TARGET=sky er-example-client.upload MOTE=3 @@ -125,10 +126,10 @@ Under Windows/Cygwin, WPCAP might need a patch in DETAILS ------- -Erbium currently implements draft 13. Central features are commented in -er-example-server.c. In general, apps/er-coap-13 supports: +Erbium implements the Proposed Standard of CoAP. Central features are commented +in er-example-server.c. In general, apps/er-coap supports: -- All draft 13 header options +- All draft-18 header options - CON Retransmissions (note COAP_MAX_OPEN_TRANSACTIONS) - Blockwise Transfers (note REST_MAX_CHUNK_SIZE, see er-plugtest-server.c for Block1 uploads) @@ -138,24 +139,6 @@ er-example-server.c. In general, apps/er-coap-13 supports: - Observing Resources (see EVENT_ and PRERIODIC_RESOURCE, note COAP_MAX_OBSERVERS) -REST IMPLEMENTATIONS --------------------- - -The Makefile uses WITH_COAP to configure different implementations for the -Erbium (Er) REST Engine. - -- WITH_COAP=13 uses Erbium CoAP 13 apps/er-coap-13/. The default port for - coap-13 is 5683. -- WITH_COAP=12 uses Erbium CoAP 12 apps/er-coap-12/. The default port for - coap-12 is 5683. -- WITH_COAP=7 uses Erbium CoAP 08 apps/er-coap-07/. The default port for - coap-07/-08 is 5683. -- WITH_COAP=3 uses Erbium CoAP 03 apps/er-coap-03/. The default port for - coap-03 is 61616. er-coap-03 produces some warnings, as it not fully - maintained anymore. -- WITH_COAP=0 is a stub to link an Erbium HTTP engine that uses the same - resource abstraction (REST.x() functions and RESOURCE macros. - TODOs ----- diff --git a/examples/er-rest-example/er-example-client.c b/examples/er-rest-example/er-example-client.c index d177bbe54..fa3df6a22 100644 --- a/examples/er-rest-example/er-example-client.c +++ b/examples/er-rest-example/er-example-client.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Matthias Kovatsch + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,7 +31,7 @@ /** * \file - * Erbium (Er) CoAP client example + * Erbium (Er) CoAP client example. * \author * Matthias Kovatsch */ @@ -39,49 +39,34 @@ #include #include #include - #include "contiki.h" #include "contiki-net.h" - +#include "er-coap-engine.h" #include "dev/button-sensor.h" -#if WITH_COAP == 3 -#include "er-coap-03-engine.h" -#elif WITH_COAP == 6 -#include "er-coap-06-engine.h" -#elif WITH_COAP == 7 -#include "er-coap-07-engine.h" -#elif WITH_COAP == 12 -#include "er-coap-12-engine.h" -#elif WITH_COAP == 13 -#include "er-coap-13-engine.h" -#else -#error "CoAP version defined by WITH_COAP not implemented" -#endif - - #define DEBUG 0 #if DEBUG +#include #define PRINTF(...) printf(__VA_ARGS__) #define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) #else #define PRINTF(...) #define PRINT6ADDR(addr) #define PRINTLLADDR(addr) #endif -/* TODO: This server address is hard-coded for Cooja. */ -#define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xaaaa, 0, 0, 0, 0x0212, 0x7402, 0x0002, 0x0202) /* cooja2 */ +/* FIXME: This server address is hard-coded for Cooja and link-local for unconnected border router. */ +#define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0212, 0x7402, 0x0002, 0x0202) /* cooja2 */ +/* #define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xbbbb, 0, 0, 0, 0, 0, 0, 0x1) */ -#define LOCAL_PORT UIP_HTONS(COAP_DEFAULT_PORT+1) +#define LOCAL_PORT UIP_HTONS(COAP_DEFAULT_PORT + 1) #define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT) #define TOGGLE_INTERVAL 10 -PROCESS(coap_client_example, "COAP Client Example"); -AUTOSTART_PROCESSES(&coap_client_example); - +PROCESS(er_example_client, "Erbium Example Client"); +AUTOSTART_PROCESSES(&er_example_client); uip_ipaddr_t server_ipaddr; static struct etimer et; @@ -89,7 +74,8 @@ static struct etimer et; /* Example URIs that can be queried. */ #define NUMBER_OF_URLS 4 /* leading and ending slashes only for demo purposes, get cropped automatically when setting the Uri-Path */ -char* service_urls[NUMBER_OF_URLS] = {".well-known/core", "/actuators/toggle", "battery/", "error/in//path"}; +char *service_urls[NUMBER_OF_URLS] = +{ ".well-known/core", "/actuators/toggle", "battery/", "error/in//path" }; #if PLATFORM_HAS_BUTTON static int uri_switch = 0; #endif @@ -101,19 +87,19 @@ client_chunk_handler(void *response) const uint8_t *chunk; int len = coap_get_payload(response, &chunk); + printf("|%.*s", len, (char *)chunk); } - - -PROCESS_THREAD(coap_client_example, ev, data) +PROCESS_THREAD(er_example_client, ev, data) { PROCESS_BEGIN(); - static coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ + static coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ + SERVER_NODE(&server_ipaddr); /* receives all CoAP messages */ - coap_receiver_init(); + coap_init_engine(); etimer_set(&et, TOGGLE_INTERVAL * CLOCK_SECOND); @@ -125,28 +111,29 @@ PROCESS_THREAD(coap_client_example, ev, data) while(1) { PROCESS_YIELD(); - if (etimer_expired(&et)) { + if(etimer_expired(&et)) { printf("--Toggle timer--\n"); /* prepare request, TID is set by COAP_BLOCKING_REQUEST() */ - coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0 ); + coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0); coap_set_header_uri_path(request, service_urls[1]); const char msg[] = "Toggle!"; - coap_set_payload(request, (uint8_t *)msg, sizeof(msg)-1); + coap_set_payload(request, (uint8_t *)msg, sizeof(msg) - 1); PRINT6ADDR(&server_ipaddr); PRINTF(" : %u\n", UIP_HTONS(REMOTE_PORT)); - COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, client_chunk_handler); + COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, + client_chunk_handler); printf("\n--Done--\n"); etimer_reset(&et); #if PLATFORM_HAS_BUTTON - } else if (ev == sensors_event && data == &button_sensor) { + } else if(ev == sensors_event && data == &button_sensor) { /* send a request to notify the end of the process */ @@ -158,13 +145,13 @@ PROCESS_THREAD(coap_client_example, ev, data) PRINT6ADDR(&server_ipaddr); PRINTF(" : %u\n", UIP_HTONS(REMOTE_PORT)); - COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, client_chunk_handler); + COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, + client_chunk_handler); printf("\n--Done--\n"); - uri_switch = (uri_switch+1) % NUMBER_OF_URLS; + uri_switch = (uri_switch + 1) % NUMBER_OF_URLS; #endif - } } diff --git a/examples/er-rest-example/er-example-observe-client.c b/examples/er-rest-example/er-example-observe-client.c new file mode 100644 index 000000000..c950fdfd7 --- /dev/null +++ b/examples/er-rest-example/er-example-observe-client.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2014, Daniele Alessandrelli. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Erbium (Er) CoAP observe client example. + * \author + * Daniele Alessandrelli + */ + +#include +#include +#include +#include "contiki.h" +#include "contiki-net.h" +#include "er-coap-engine.h" +#include "dev/button-sensor.h" + +/*----------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINTFLN(format, ...) printf(format "\n", ##__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:" \ + "%02x%02x:%02x%02x:%02x%02x:%02x%02x]", \ + ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], \ + ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], \ + ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], \ + ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], \ + ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], \ + ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], \ + ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], \ + ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTFLN(...) +#endif + +/*----------------------------------------------------------------------------*/ +/* FIXME: This server address is hard-coded for Cooja */ +#define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0212, \ + 0x7402, 0x0002, 0x0202) +#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT) +/* Toggle interval in seconds */ +#define TOGGLE_INTERVAL 30 +/* The path of the resource to observe */ +#define OBS_RESOURCE_URI "test/push" + +/*----------------------------------------------------------------------------*/ +static uip_ipaddr_t server_ipaddr[1]; /* holds the server ip address */ +static coap_observee_t *obs; + +/*----------------------------------------------------------------------------*/ +PROCESS(er_example_observe_client, "Erbium Coap Observe Client Example"); +AUTOSTART_PROCESSES(&er_example_observe_client); + +/*----------------------------------------------------------------------------*/ +/* + * Handle the response to the observe request and the following notifications + */ +static void +notification_callback(coap_observee_t *obs, void *notification, + coap_notification_flag_t flag) +{ + int len = 0; + const uint8_t *payload = NULL; + + printf("Notification handler\n"); + printf("Observee URI: %s\n", obs->url); + if(notification) { + len = coap_get_payload(notification, &payload); + } + switch(flag) { + case NOTIFICATION_OK: + printf("NOTIFICATION OK: %*s\n", len, (char *)payload); + break; + case OBSERVE_OK: /* server accepeted observation request */ + printf("OBSERVE_OK: %*s\n", len, (char *)payload); + break; + case OBSERVE_NOT_SUPPORTED: + printf("OBSERVE_NOT_SUPPORTED: %*s\n", len, (char *)payload); + obs = NULL; + break; + case ERROR_RESPONSE_CODE: + printf("ERROR_RESPONSE_CODE: %*s\n", len, (char *)payload); + obs = NULL; + break; + case NO_REPLY_FROM_SERVER: + printf("NO_REPLY_FROM_SERVER: " + "removing observe registration with token %x%x\n", + obs->token[0], obs->token[1]); + obs = NULL; + break; + } +} +/*----------------------------------------------------------------------------*/ +/* + * Toggle the observation of the remote resource + */ +void +toggle_observation(void) +{ + if(obs) { + printf("Stopping observation\n"); + coap_obs_remove_observee(obs); + obs = NULL; + } else { + printf("Starting observation\n"); + obs = coap_obs_request_registration(server_ipaddr, REMOTE_PORT, + OBS_RESOURCE_URI, notification_callback, NULL); + } +} +/*----------------------------------------------------------------------------*/ +/* + * The main (proto-)thread. It starts/stops the observation of the remote + * resource every time the timer elapses or the button (if available) is + * pressed + */ +PROCESS_THREAD(er_example_observe_client, ev, data) +{ + PROCESS_BEGIN(); + + static struct etimer et; + + /* store server address in server_ipaddr */ + SERVER_NODE(server_ipaddr); + /* receives all CoAP messages */ + coap_init_engine(); + /* init timer and button (if available) */ + etimer_set(&et, TOGGLE_INTERVAL * CLOCK_SECOND); +#if PLATFORM_HAS_BUTTON + SENSORS_ACTIVATE(button_sensor); + printf("Press a button to start/stop observation of remote resource\n"); +#endif + /* toggle observation every time the timer elapses or the button is pressed */ + while(1) { + PROCESS_YIELD(); + if(etimer_expired(&et)) { + printf("--Toggle timer--\n"); + toggle_observation(); + printf("\n--Done--\n"); + etimer_reset(&et); +#if PLATFORM_HAS_BUTTON + } else if(ev == sensors_event && data == &button_sensor) { + printf("--Toggle tutton--\n"); + toggle_observation(); + printf("\n--Done--\n"); +#endif + } + } + PROCESS_END(); +} diff --git a/examples/er-rest-example/er-example-server.c b/examples/er-rest-example/er-example-server.c index f5d9ea9a6..d8e1c79b2 100644 --- a/examples/er-rest-example/er-example-server.c +++ b/examples/er-rest-example/er-example-server.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Matthias Kovatsch + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,7 +31,7 @@ /** * \file - * Erbium (Er) REST Engine example (with CoAP-specific code) + * Erbium (Er) REST Engine example. * \author * Matthias Kovatsch */ @@ -41,757 +41,74 @@ #include #include "contiki.h" #include "contiki-net.h" +#include "rest-engine.h" - -/* Define which resources to include to meet memory constraints. */ -#define REST_RES_HELLO 0 -#define REST_RES_CHUNKS 1 -#define REST_RES_SEPARATE 1 -#define REST_RES_PUSHING 1 -#define REST_RES_EVENT 1 -#define REST_RES_SUB 1 -#define REST_RES_LEDS 0 -#define REST_RES_TOGGLE 1 -#define REST_RES_LIGHT 0 -#define REST_RES_BATTERY 0 -#define REST_RES_RADIO 0 -#define REST_RES_MIRROR 0 /* causes largest code size */ - - - -#include "erbium.h" - - -#if defined (PLATFORM_HAS_BUTTON) +#if PLATFORM_HAS_BUTTON #include "dev/button-sensor.h" #endif -#if defined (PLATFORM_HAS_LEDS) -#include "dev/leds.h" -#endif -#if defined (PLATFORM_HAS_LIGHT) -#include "dev/light-sensor.h" -#endif -#if defined (PLATFORM_HAS_BATTERY) -#include "dev/battery-sensor.h" -#endif -#if defined (PLATFORM_HAS_SHT11) -#include "dev/sht11/sht11-sensor.h" -#endif -#if defined (PLATFORM_HAS_RADIO) -#include "dev/radio-sensor.h" -#endif - - -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP == 3 -#include "er-coap-03.h" -#elif WITH_COAP == 7 -#include "er-coap-07.h" -#elif WITH_COAP == 12 -#include "er-coap-12.h" -#elif WITH_COAP == 13 -#include "er-coap-13.h" -#else -#warning "Erbium example without CoAP-specifc functionality" -#endif /* CoAP-specific example */ #define DEBUG 0 #if DEBUG +#include #define PRINTF(...) printf(__VA_ARGS__) #define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) #else #define PRINTF(...) #define PRINT6ADDR(addr) #define PRINTLLADDR(addr) #endif -/******************************************************************************/ -#if REST_RES_HELLO /* - * Resources are defined by the RESOURCE macro. - * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). + * Resources to be activated need to be imported through the extern keyword. + * The build system automatically compiles the resources in the corresponding sub-directory. */ -RESOURCE(helloworld, METHOD_GET, "hello", "title=\"Hello world: ?len=0..\";rt=\"Text\""); - -/* - * A handler function named [resource name]_handler must be implemented for each RESOURCE. - * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore - * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. - * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. - */ -void -helloworld_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - const char *len = NULL; - /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ - char const * const message = "Hello World! ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy"; - int length = 12; /* |<-------->| */ - - /* The query string can be retrieved by rest_get_query() or parsed for its key-value pairs. */ - if (REST.get_query_variable(request, "len", &len)) { - length = atoi(len); - if (length<0) length = 0; - if (length>REST_MAX_CHUNK_SIZE) length = REST_MAX_CHUNK_SIZE; - memcpy(buffer, message, length); - } else { - memcpy(buffer, message, length); - } - - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); /* text/plain is the default, hence this option could be omitted. */ - REST.set_header_etag(response, (uint8_t *) &length, 1); - REST.set_response_payload(response, buffer, length); -} +extern resource_t + res_hello, + res_mirror, + res_chunks, + res_separate, + res_push, + res_event, + res_sub, + res_b1_sep_b2; +#if PLATFORM_HAS_LEDS +extern resource_t res_leds, res_toggle; #endif - -/******************************************************************************/ -#if REST_RES_MIRROR -/* This resource mirrors the incoming request. It shows how to access the options and how to set them for the response. */ -RESOURCE(mirror, METHOD_GET | METHOD_POST | METHOD_PUT | METHOD_DELETE, "debug/mirror", "title=\"Returns your decoded message\";rt=\"Debug\""); - -void -mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - /* The ETag and Token is copied to the header. */ - uint8_t opaque[] = {0x0A, 0xBC, 0xDE}; - - /* Strings are not copied, so use static string buffers or strings in .text memory (char *str = "string in .text";). */ - static char location[] = {'/','f','/','a','?','k','&','e', 0}; - - /* Getter for the header option Content-Type. If the option is not set, text/plain is returned by default. */ - unsigned int content_type = REST.get_header_content_type(request); - - /* The other getters copy the value (or string/array pointer) to the given pointers and return 1 for success or the length of strings/arrays. */ - uint32_t max_age_and_size = 0; - const char *str = NULL; - uint32_t observe = 0; - const uint8_t *bytes = NULL; - uint32_t block_num = 0; - uint8_t block_more = 0; - uint16_t block_size = 0; - const char *query = ""; - int len = 0; - - /* Mirror the received header options in the response payload. Unsupported getters (e.g., rest_get_header_observe() with HTTP) will return 0. */ - - int strpos = 0; - /* snprintf() counts the terminating '\0' to the size parameter. - * The additional byte is taken care of by allocating REST_MAX_CHUNK_SIZE+1 bytes in the REST framework. - * Add +1 to fill the complete buffer, as the payload does not need a terminating '\0'. */ - if (content_type!=-1) - { - strpos += snprintf((char *)buffer, REST_MAX_CHUNK_SIZE+1, "CT %u\n", content_type); - } - - /* Some getters such as for ETag or Location are omitted, as these options should not appear in a request. - * Max-Age might appear in HTTP requests or used for special purposes in CoAP. */ - if (strpos<=REST_MAX_CHUNK_SIZE && REST.get_header_max_age(request, &max_age_and_size)) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "MA %lu\n", max_age_and_size); - } - /* For HTTP this is the Length option, for CoAP it is the Size option. */ - if (strpos<=REST_MAX_CHUNK_SIZE && REST.get_header_length(request, &max_age_and_size)) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "SZ %lu\n", max_age_and_size); - } - - if (strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_header_host(request, &str))) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "UH %.*s\n", len, str); - } - -/* CoAP-specific example: actions not required for normal RESTful Web service. */ -#if WITH_COAP > 1 - if (strpos<=REST_MAX_CHUNK_SIZE && coap_get_header_observe(request, &observe)) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "Ob %lu\n", observe); - } - if (strpos<=REST_MAX_CHUNK_SIZE && (len = coap_get_header_token(request, &bytes))) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "To 0x"); - int index = 0; - for (index = 0; index 03 */ -#endif /* CoAP-specific example */ - - if (strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_query(request, &query))) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "Qu %.*s\n", len, query); - } - if (strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_request_payload(request, &bytes))) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "%.*s", len, bytes); - } - - if (strpos >= REST_MAX_CHUNK_SIZE) - { - buffer[REST_MAX_CHUNK_SIZE-1] = 0xBB; /* '»' to indicate truncation */ - } - - REST.set_response_payload(response, buffer, strpos); - - PRINTF("/mirror options received: %s\n", buffer); - - /* Set dummy header options for response. Like getters, some setters are not implemented for HTTP and have no effect. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_header_max_age(response, 17); /* For HTTP, browsers will not re-request the page for 17 seconds. */ - REST.set_header_etag(response, opaque, 2); - REST.set_header_location(response, location); /* Initial slash is omitted by framework */ - REST.set_header_length(response, strpos); /* For HTTP, browsers will not re-request the page for 10 seconds. CoAP action depends on the client. */ - -/* CoAP-specific example: actions not required for normal RESTful Web service. */ -#if WITH_COAP > 1 - coap_set_header_uri_host(response, "tiki"); - coap_set_header_observe(response, 10); -#if WITH_COAP == 3 - coap_set_header_block(response, 42, 0, 64); /* The block option might be overwritten by the framework when blockwise transfer is requested. */ -#else - coap_set_header_proxy_uri(response, "ftp://x"); - coap_set_header_block2(response, 42, 0, 64); /* The block option might be overwritten by the framework when blockwise transfer is requested. */ - coap_set_header_block1(response, 23, 0, 16); - coap_set_header_accept(response, TEXT_PLAIN); - coap_set_header_if_none_match(response); -#endif /* CoAP > 03 */ -#endif /* CoAP-specific example */ -} -#endif /* REST_RES_MIRROR */ - -/******************************************************************************/ -#if REST_RES_CHUNKS -/* - * For data larger than REST_MAX_CHUNK_SIZE (e.g., stored in flash) resources must be aware of the buffer limitation - * and split their responses by themselves. To transfer the complete resource through a TCP stream or CoAP's blockwise transfer, - * the byte offset where to continue is provided to the handler as int32_t pointer. - * These chunk-wise resources must set the offset value to its new position or -1 of the end is reached. - * (The offset for CoAP's blockwise transfer can go up to 2'147'481'600 = ~2047 M for block size 2048 (reduced to 1024 in observe-03.) - */ -RESOURCE(chunks, METHOD_GET, "test/chunks", "title=\"Blockwise demo\";rt=\"Data\""); - -#define CHUNKS_TOTAL 2050 - -void -chunks_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int32_t strpos = 0; - - /* Check the offset for boundaries of the resource data. */ - if (*offset>=CHUNKS_TOTAL) - { - REST.set_response_status(response, REST.status.BAD_OPTION); - /* A block error message should not exceed the minimum block size (16). */ - - const char *error_msg = "BlockOutOfScope"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - /* Generate data until reaching CHUNKS_TOTAL. */ - while (strpos preferred_size) - { - strpos = preferred_size; - } - - /* Truncate if above CHUNKS_TOTAL bytes. */ - if (*offset+(int32_t)strpos > CHUNKS_TOTAL) - { - strpos = CHUNKS_TOTAL - *offset; - } - - REST.set_response_payload(response, buffer, strpos); - - /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ - *offset += strpos; - - /* Signal end of resource representation. */ - if (*offset>=CHUNKS_TOTAL) - { - *offset = -1; - } -} +#if PLATFORM_HAS_LIGHT +#include "dev/light-sensor.h" +extern resource_t res_light; #endif - -/******************************************************************************/ -#if REST_RES_SEPARATE && defined (PLATFORM_HAS_BUTTON) && WITH_COAP > 3 -/* Required to manually (=not by the engine) handle the response transaction. */ -#if WITH_COAP == 7 -#include "er-coap-07-separate.h" -#include "er-coap-07-transactions.h" -#elif WITH_COAP == 12 -#include "er-coap-12-separate.h" -#include "er-coap-12-transactions.h" -#elif WITH_COAP == 13 -#include "er-coap-13-separate.h" -#include "er-coap-13-transactions.h" +#if PLATFORM_HAS_BATTERY +#include "dev/battery-sensor.h" +extern resource_t res_battery; +#endif +#if PLATFORM_HAS_TEMPERATURE +#include "dev/temperature-sensor.h" +extern resource_t res_temperature; #endif /* - * CoAP-specific example for separate responses. - * Note the call "rest_set_pre_handler(&resource_separate, coap_separate_handler);" in the main process. - * The pre-handler takes care of the empty ACK and updates the MID and message type for CON requests. - * The resource handler must store all information that required to finalize the response later. - */ -RESOURCE(separate, METHOD_GET, "test/separate", "title=\"Separate demo\""); - -/* A structure to store the required information */ -typedef struct application_separate_store { - /* Provided by Erbium to store generic request information such as remote address and token. */ - coap_separate_t request_metadata; - /* Add fields for addition information to be stored for finalizing, e.g.: */ - char buffer[16]; -} application_separate_store_t; - -static uint8_t separate_active = 0; -static application_separate_store_t separate_store[1]; - -void -separate_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - /* - * Example allows only one open separate response. - * For multiple, the application must manage the list of stores. - */ - if (separate_active) - { - coap_separate_reject(); - } - else - { - separate_active = 1; - - /* Take over and skip response by engine. */ - coap_separate_accept(request, &separate_store->request_metadata); - /* Be aware to respect the Block2 option, which is also stored in the coap_separate_t. */ - - /* - * At the moment, only the minimal information is stored in the store (client address, port, token, MID, type, and Block2). - * Extend the store, if the application requires additional information from this handler. - * buffer is an example field for custom information. - */ - snprintf(separate_store->buffer, sizeof(separate_store->buffer), "StoredInfo"); - } -} - -void -separate_finalize_handler() -{ - if (separate_active) - { - coap_transaction_t *transaction = NULL; - if ( (transaction = coap_new_transaction(separate_store->request_metadata.mid, &separate_store->request_metadata.addr, separate_store->request_metadata.port)) ) - { - coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */ - - /* Restore the request information for the response. */ - coap_separate_resume(response, &separate_store->request_metadata, REST.status.OK); - - coap_set_payload(response, separate_store->buffer, strlen(separate_store->buffer)); - - /* - * Be aware to respect the Block2 option, which is also stored in the coap_separate_t. - * As it is a critical option, this example resource pretends to handle it for compliance. - */ - coap_set_header_block2(response, separate_store->request_metadata.block2_num, 0, separate_store->request_metadata.block2_size); - - /* Warning: No check for serialization error. */ - transaction->packet_len = coap_serialize_message(response, transaction->packet); - coap_send_transaction(transaction); - /* The engine will clear the transaction (right after send for NON, after acked for CON). */ - - separate_active = 0; - } - else - { - /* - * Set timer for retry, send error message, ... - * The example simply waits for another button press. - */ - } - } /* if (separate_active) */ -} +extern resource_t res_battery; #endif - -/******************************************************************************/ -#if REST_RES_PUSHING -/* - * Example for a periodic resource. - * It takes an additional period parameter, which defines the interval to call [name]_periodic_handler(). - * A default post_handler takes care of subscriptions by managing a list of subscribers to notify. - */ -PERIODIC_RESOURCE(pushing, METHOD_GET, "test/push", "title=\"Periodic demo\";obs", 5*CLOCK_SECOND); - -void -pushing_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - - /* Usually, a CoAP server would response with the resource representation matching the periodic_handler. */ - const char *msg = "It's periodic!"; - REST.set_response_payload(response, msg, strlen(msg)); - - /* A post_handler that handles subscriptions will be called for periodic resources by the REST framework. */ -} - -/* - * Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE. - * It will be called by the REST manager process with the defined period. - */ -void -pushing_periodic_handler(resource_t *r) -{ - static uint16_t obs_counter = 0; - static char content[11]; - - ++obs_counter; - - PRINTF("TICK %u for /%s\n", obs_counter, r->url); - - /* Build notification. */ - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_NON, REST.status.OK, 0 ); - coap_set_payload(notification, content, snprintf(content, sizeof(content), "TICK %u", obs_counter)); - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(r, obs_counter, notification); -} +#if PLATFORM_HAS_RADIO +#include "dev/radio-sensor.h" +extern resource_t res_radio; #endif - -/******************************************************************************/ -#if REST_RES_EVENT && defined (PLATFORM_HAS_BUTTON) -/* - * Example for an event resource. - * Additionally takes a period parameter that defines the interval to call [name]_periodic_handler(). - * A default post_handler takes care of subscriptions and manages a list of subscribers to notify. - */ -EVENT_RESOURCE(event, METHOD_GET, "sensors/button", "title=\"Event demo\";obs"); - -void -event_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - /* Usually, a CoAP server would response with the current resource representation. */ - const char *msg = "It's eventful!"; - REST.set_response_payload(response, (uint8_t *)msg, strlen(msg)); - - /* A post_handler that handles subscriptions/observing will be called for periodic resources by the framework. */ -} - -/* Additionally, a handler function named [resource name]_event_handler must be implemented for each EVENT_RESOURCE defined. - * It will be called by the REST manager process with the defined period. */ -void -event_event_handler(resource_t *r) -{ - static uint16_t event_counter = 0; - static char content[12]; - - ++event_counter; - - PRINTF("TICK %u for /%s\n", event_counter, r->url); - - /* Build notification. */ - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_CON, REST.status.OK, 0 ); - coap_set_payload(notification, content, snprintf(content, sizeof(content), "EVENT %u", event_counter)); - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(r, event_counter, notification); -} -#endif /* PLATFORM_HAS_BUTTON */ - -/******************************************************************************/ -#if REST_RES_SUB -/* - * Example for a resource that also handles all its sub-resources. - * Use REST.get_url() to multiplex the handling of the request depending on the Uri-Path. - */ -RESOURCE(sub, METHOD_GET | HAS_SUB_RESOURCES, "test/path", "title=\"Sub-resource demo\""); - -void -sub_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - - const char *uri_path = NULL; - int len = REST.get_url(request, &uri_path); - int base_len = strlen(resource_sub.url); - - if (len==base_len) - { - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "Request any sub-resource of /%s", resource_sub.url); - } - else - { - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, ".%.*s", len-base_len, uri_path+base_len); - } - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); -} +#if PLATFORM_HAS_SHT11 +#include "dev/sht11/sht11-sensor.h" +extern resource_t res_sht11; #endif +*/ -/******************************************************************************/ -#if defined (PLATFORM_HAS_LEDS) -/******************************************************************************/ -#if REST_RES_LEDS -/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -RESOURCE(leds, METHOD_POST | METHOD_PUT , "actuators/leds", "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\""); +PROCESS(er_example_server, "Erbium Example Server"); +AUTOSTART_PROCESSES(&er_example_server); -void -leds_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - size_t len = 0; - const char *color = NULL; - const char *mode = NULL; - uint8_t led = 0; - int success = 1; - - if ((len=REST.get_query_variable(request, "color", &color))) { - PRINTF("color %.*s\n", len, color); - - if (strncmp(color, "r", len)==0) { - led = LEDS_RED; - } else if(strncmp(color,"g", len)==0) { - led = LEDS_GREEN; - } else if (strncmp(color,"b", len)==0) { - led = LEDS_BLUE; - } else { - success = 0; - } - } else { - success = 0; - } - - if (success && (len=REST.get_post_variable(request, "mode", &mode))) { - PRINTF("mode %s\n", mode); - - if (strncmp(mode, "on", len)==0) { - leds_on(led); - } else if (strncmp(mode, "off", len)==0) { - leds_off(led); - } else { - success = 0; - } - } else { - success = 0; - } - - if (!success) { - REST.set_response_status(response, REST.status.BAD_REQUEST); - } -} -#endif - -/******************************************************************************/ -#if REST_RES_TOGGLE -/* A simple actuator example. Toggles the red led */ -RESOURCE(toggle, METHOD_POST, "actuators/toggle", "title=\"Red LED\";rt=\"Control\""); -void -toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - leds_toggle(LEDS_RED); -} -#endif -#endif /* PLATFORM_HAS_LEDS */ - -/******************************************************************************/ -#if REST_RES_LIGHT && defined (PLATFORM_HAS_LIGHT) -/* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(light, METHOD_GET, "sensors/light", "title=\"Photosynthetic and solar light (supports JSON)\";rt=\"LightSensor\""); -void -light_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - uint16_t light_photosynthetic = light_sensor.value(LIGHT_SENSOR_PHOTOSYNTHETIC); - uint16_t light_solar = light_sensor.value(LIGHT_SENSOR_TOTAL_SOLAR); - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%u;%u", light_photosynthetic, light_solar); - - REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_XML)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_XML); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "", light_photosynthetic, light_solar); - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'light':{'photosynthetic':%u,'solar':%u}}", light_photosynthetic, light_solar); - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain, application/xml, and application/json"; - REST.set_response_payload(response, msg, strlen(msg)); - } -} -#endif /* PLATFORM_HAS_LIGHT */ - -/******************************************************************************/ -#if REST_RES_BATTERY && defined (PLATFORM_HAS_BATTERY) -/* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(battery, METHOD_GET, "sensors/battery", "title=\"Battery status\";rt=\"Battery\""); -void -battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int battery = battery_sensor.value(0); - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", battery); - - REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'battery':%d}", battery); - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain and application/json"; - REST.set_response_payload(response, msg, strlen(msg)); - } -} -#endif /* PLATFORM_HAS_BATTERY */ - - -#if defined (PLATFORM_HAS_RADIO) && REST_RES_RADIO -/* A simple getter example. Returns the reading of the rssi/lqi from radio sensor */ -RESOURCE(radio, METHOD_GET, "sensor/radio", "title=\"RADIO: ?p=lqi|rssi\";rt=\"RadioSensor\""); - -void -radio_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - size_t len = 0; - const char *p = NULL; - uint8_t param = 0; - int success = 1; - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((len=REST.get_query_variable(request, "p", &p))) { - PRINTF("p %.*s\n", len, p); - if (strncmp(p, "lqi", len)==0) { - param = RADIO_SENSOR_LAST_VALUE; - } else if(strncmp(p,"rssi", len)==0) { - param = RADIO_SENSOR_LAST_PACKET; - } else { - success = 0; - } - } else { - success = 0; - } - - if (success) { - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", radio_sensor.value(param)); - - REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - - if (param == RADIO_SENSOR_LAST_VALUE) { - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'lqi':%d}", radio_sensor.value(param)); - } else if (param == RADIO_SENSOR_LAST_PACKET) { - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'rssi':%d}", radio_sensor.value(param)); - } - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain and application/json"; - REST.set_response_payload(response, msg, strlen(msg)); - } - } else { - REST.set_response_status(response, REST.status.BAD_REQUEST); - } -} -#endif - - - -PROCESS(rest_server_example, "Erbium Example Server"); -AUTOSTART_PROCESSES(&rest_server_example); - -PROCESS_THREAD(rest_server_example, ev, data) +PROCESS_THREAD(er_example_server, ev, data) { PROCESS_BEGIN(); + PROCESS_PAUSE(); + PRINTF("Starting Erbium Example Server\n"); #ifdef RF_CHANNEL @@ -809,70 +126,61 @@ PROCESS_THREAD(rest_server_example, ev, data) /* Initialize the REST engine. */ rest_init_engine(); - /* Activate the application-specific resources. */ -#if REST_RES_HELLO - rest_activate_resource(&resource_helloworld); + /* + * Bind the resources to their Uri-Path. + * WARNING: Activating twice only means alternate path, not two instances! + * All static variables are the same for each URI path. + */ + rest_activate_resource(&res_hello, "test/hello"); +/* rest_activate_resource(&res_mirror, "debug/mirror"); */ +/* rest_activate_resource(&res_chunks, "test/chunks"); */ +/* rest_activate_resource(&res_separate, "test/separate"); */ + rest_activate_resource(&res_push, "test/push"); +/* rest_activate_resource(&res_event, "sensors/button"); */ +/* rest_activate_resource(&res_sub, "test/sub"); */ +/* rest_activate_resource(&res_b1_sep_b2, "test/b1sepb2"); */ +#if PLATFORM_HAS_LEDS +/* rest_activate_resource(&res_leds, "actuators/leds"); */ + rest_activate_resource(&res_toggle, "actuators/toggle"); #endif -#if REST_RES_MIRROR - rest_activate_resource(&resource_mirror); +#if PLATFORM_HAS_LIGHT + rest_activate_resource(&res_light, "sensors/light"); + SENSORS_ACTIVATE(light_sensor); #endif -#if REST_RES_CHUNKS - rest_activate_resource(&resource_chunks); +#if PLATFORM_HAS_BATTERY + rest_activate_resource(&res_battery, "sensors/battery"); + SENSORS_ACTIVATE(battery_sensor); #endif -#if REST_RES_PUSHING - rest_activate_periodic_resource(&periodic_resource_pushing); +#if PLATFORM_HAS_TEMPERATURE + rest_activate_resource(&res_temperature, "sensors/temperature"); + SENSORS_ACTIVATE(temperature_sensor); #endif -#if defined (PLATFORM_HAS_BUTTON) && REST_RES_EVENT - rest_activate_event_resource(&resource_event); +/* +#if PLATFORM_HAS_RADIO + rest_activate_resource(&res_radio, "sensors/radio"); + SENSORS_ACTIVATE(radio_sensor); #endif -#if defined (PLATFORM_HAS_BUTTON) && REST_RES_SEPARATE && WITH_COAP > 3 - /* No pre-handler anymore, user coap_separate_accept() and coap_separate_reject(). */ - rest_activate_resource(&resource_separate); -#endif -#if defined (PLATFORM_HAS_BUTTON) && (REST_RES_EVENT || (REST_RES_SEPARATE && WITH_COAP > 3)) - SENSORS_ACTIVATE(button_sensor); -#endif -#if REST_RES_SUB - rest_activate_resource(&resource_sub); -#endif -#if defined (PLATFORM_HAS_LEDS) -#if REST_RES_LEDS - rest_activate_resource(&resource_leds); -#endif -#if REST_RES_TOGGLE - rest_activate_resource(&resource_toggle); -#endif -#endif /* PLATFORM_HAS_LEDS */ -#if defined (PLATFORM_HAS_LIGHT) && REST_RES_LIGHT - SENSORS_ACTIVATE(light_sensor); - rest_activate_resource(&resource_light); -#endif -#if defined (PLATFORM_HAS_BATTERY) && REST_RES_BATTERY - SENSORS_ACTIVATE(battery_sensor); - rest_activate_resource(&resource_battery); -#endif -#if defined (PLATFORM_HAS_RADIO) && REST_RES_RADIO - SENSORS_ACTIVATE(radio_sensor); - rest_activate_resource(&resource_radio); +#if PLATFORM_HAS_SHT11 + rest_activate_resource(&res_sht11, "sensors/sht11"); + SENSORS_ACTIVATE(sht11_sensor); #endif +*/ /* Define application-specific events here. */ while(1) { PROCESS_WAIT_EVENT(); -#if defined (PLATFORM_HAS_BUTTON) - if (ev == sensors_event && data == &button_sensor) { - PRINTF("BUTTON\n"); -#if REST_RES_EVENT +#if PLATFORM_HAS_BUTTON + if(ev == sensors_event && data == &button_sensor) { + PRINTF("*******BUTTON*******\n"); + /* Call the event_handler for this application-specific event. */ - event_event_handler(&resource_event); -#endif -#if REST_RES_SEPARATE && WITH_COAP>3 + res_event.trigger(); + /* Also call the separate response example handler. */ - separate_finalize_handler(); -#endif + res_separate.resume(); } #endif /* PLATFORM_HAS_BUTTON */ - } /* while (1) */ + } /* while (1) */ PROCESS_END(); } diff --git a/examples/er-rest-example/er-plugtest-server.c b/examples/er-rest-example/er-plugtest-server.c index 5a791a09c..ae637dc4c 100644 --- a/examples/er-rest-example/er-plugtest-server.c +++ b/examples/er-rest-example/er-plugtest-server.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Matthias Kovatsch + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,7 +31,7 @@ /** * \file - * Server for the ETSI IoT CoAP Plugtests, Paris, France, 24 - 25 March 2012 + * Server for the ETSI IoT CoAP Plugtests, Las Vegas, NV, USA, Nov 2013. * \author * Matthias Kovatsch */ @@ -41,1179 +41,37 @@ #include #include "contiki.h" #include "contiki-net.h" - -#define MAX_PLUGFEST_PAYLOAD 64+1 /* +1 for the terminating zero, which is not transmitted */ -#define MAX_PLUGFEST_BODY 2048 -#define CHUNKS_TOTAL 2012 - -/* Define which resources to include to meet memory constraints. */ -#define REST_RES_TEST 1 -#define REST_RES_LONG 1 -#define REST_RES_QUERY 1 -#define REST_RES_LOC_QUERY 1 -#define REST_RES_MULTI 1 -#define REST_RES_LINKS 1 -#define REST_RES_PATH 1 -#define REST_RES_SEPARATE 1 -#define REST_RES_LARGE 1 -#define REST_RES_LARGE_UPDATE 1 -#define REST_RES_LARGE_CREATE 1 -#define REST_RES_OBS 1 - -#define REST_RES_MIRROR 1 - - - -#if !defined (CONTIKI_TARGET_MINIMAL_NET) -#warning "Should only be compiled for minimal-net!" -#endif - - - -#include "erbium.h" - -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP==7 -#include "er-coap-07.h" -#elif WITH_COAP == 12 -#include "er-coap-12.h" -#elif WITH_COAP == 13 -#include "er-coap-13.h" -#else -#error "Plugtests server without CoAP" -#endif /* CoAP-specific example */ - -#define DEBUG 1 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - - -#if REST_RES_TEST -/* - * Default test resource - */ -RESOURCE(test, METHOD_GET|METHOD_POST|METHOD_PUT|METHOD_DELETE, "test", "title=\"Default test resource\""); - -static uint8_t test_etag[8] = {0}; -static uint8_t test_etag_len = 1; -static uint8_t test_change = 1; -static uint8_t test_none_match_okay = 1; - -static -void -test_update_etag() -{ - int i; - test_etag_len = (random_rand() % 8) + 1; - for (i=0; i0 && len==test_etag_len && memcmp(test_etag, bytes, len)==0) - { - PRINTF("validate "); - REST.set_response_status(response, REST.status.NOT_MODIFIED); - REST.set_header_etag(response, test_etag, test_etag_len); - - test_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } - else - { - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_header_etag(response, test_etag, test_etag_len); - REST.set_header_max_age(response, 30); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); - } - } - else if (method & METHOD_POST) - { - PRINTF("POST "); - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "/location1/location2/location3"); - } - else if (method & METHOD_PUT) - { - PRINTF("PUT "); - - if (coap_get_header_if_none_match(request)) - { - if (test_none_match_okay) - { - REST.set_response_status(response, REST.status.CREATED); - - test_none_match_okay = 0; - PRINTF("### SERVER ACTION ### If-None-Match will FAIL\n"); - } - else - { - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - - test_none_match_okay = 1; - PRINTF("### SERVER ACTION ### If-None-Match will SUCCEED\n"); - } - } - else if (((len = coap_get_header_if_match(request, &bytes))>0 && (len==test_etag_len && memcmp(test_etag, bytes, len)==0)) || len==0) - { - test_update_etag(); - REST.set_header_etag(response, test_etag, test_etag_len); - - REST.set_response_status(response, REST.status.CHANGED); - - if (len>0) - { - test_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } - } - else - { - - PRINTF("Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X] ", len, test_etag_len, - bytes[0], - bytes[1], - bytes[2], - bytes[3], - bytes[4], - bytes[5], - bytes[6], - bytes[7], - test_etag[0], - test_etag[1], - test_etag[2], - test_etag[3], - test_etag[4], - test_etag[5], - test_etag[6], - test_etag[7] ); - - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } - else if (method & METHOD_DELETE) - { - PRINTF("DELETE "); - REST.set_response_status(response, REST.status.DELETED); - } - - PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); -} - - -RESOURCE(create1, METHOD_PUT|METHOD_DELETE, "create1", "title=\"Default test resource\""); - -static uint8_t create1_exists = 0; - -void -create1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - uint8_t method = REST.get_method_type(request); - - if (test_change) - { - test_update_etag(); - } - - PRINTF("/create1 "); - - if (method & METHOD_PUT) - { - PRINTF("PUT "); - - if (coap_get_header_if_none_match(request)) - { - if (!create1_exists) - { - REST.set_response_status(response, REST.status.CREATED); - - create1_exists = 1; - } - else - { - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } - else - { - REST.set_response_status(response, REST.status.CHANGED); - } - } - else if (method & METHOD_DELETE) - { - PRINTF("DELETE "); - REST.set_response_status(response, REST.status.DELETED); - - create1_exists = 0; - } -} - -RESOURCE(create2, METHOD_POST, "create2", "title=\"Creates on POST\""); - -void -create2_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - if (test_change) - { - test_update_etag(); - } - - PRINTF("/create2 "); - - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "/location1/location2/location3"); -} - -RESOURCE(create3, METHOD_PUT|METHOD_DELETE, "create3", "title=\"Default test resource\""); - -static uint8_t create3_exists = 0; - -void -create3_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - uint8_t method = REST.get_method_type(request); - - if (test_change) - { - test_update_etag(); - } - - PRINTF("/create3 "); - - if (method & METHOD_PUT) - { - PRINTF("PUT "); - - if (coap_get_header_if_none_match(request)) - { - if (!create3_exists) - { - REST.set_response_status(response, REST.status.CREATED); - - create3_exists = 1; - } - else - { - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } - else - { - REST.set_response_status(response, REST.status.CHANGED); - } - } - else if (method & METHOD_DELETE) - { - PRINTF("DELETE "); - REST.set_response_status(response, REST.status.DELETED); - - create3_exists = 0; - } -} - - - - - -RESOURCE(validate, METHOD_GET|METHOD_PUT, "validate", "title=\"Default test resource\""); - -static uint8_t validate_etag[8] = {0}; -static uint8_t validate_etag_len = 1; -static uint8_t validate_change = 1; - -static -void -validate_update_etag() -{ - int i; - validate_etag_len = (random_rand() % 8) + 1; - for (i=0; i0 && len==validate_etag_len && memcmp(validate_etag, bytes, len)==0) - { - PRINTF("validate "); - REST.set_response_status(response, REST.status.NOT_MODIFIED); - REST.set_header_etag(response, validate_etag, validate_etag_len); - - validate_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } - else - { - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_header_etag(response, validate_etag, validate_etag_len); - REST.set_header_max_age(response, 30); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); - } - } - else if (method & METHOD_PUT) - { - PRINTF("PUT "); - - if (((len = coap_get_header_if_match(request, &bytes))>0 && (len==validate_etag_len && memcmp(validate_etag, bytes, len)==0)) || len==0) - { - validate_update_etag(); - REST.set_header_etag(response, validate_etag, validate_etag_len); - - REST.set_response_status(response, REST.status.CHANGED); - - if (len>0) - { - validate_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } - } - else - { - PRINTF("Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X] ", len, validate_etag_len, - bytes[0], - bytes[1], - bytes[2], - bytes[3], - bytes[4], - bytes[5], - bytes[6], - bytes[7], - validate_etag[0], - validate_etag[1], - validate_etag[2], - validate_etag[3], - validate_etag[4], - validate_etag[5], - validate_etag[6], - validate_etag[7] ); - - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } - - PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); -} -#endif - -#if REST_RES_LONG -/* - * Long path resource - */ -RESOURCE(longpath, METHOD_GET, "seg1/seg2/seg3", "title=\"Long path resource\""); - -void -longpath_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - uint8_t method = REST.get_method_type(request); - - PRINTF("/seg1/seg2/seg3 "); - if (method & METHOD_GET) - { - PRINTF("GET "); - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); - } - PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); -} -#endif - -#if REST_RES_QUERY -/* - * Resource accepting query parameters - */ -RESOURCE(query, METHOD_GET, "query", "title=\"Resource accepting query parameters\""); - -void -query_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - int len = 0; - const char *query = NULL; - - PRINTF("/query GET (%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); - - if ((len = REST.get_query(request, &query))) - { - PRINTF("Query: %.*s\n", len, query); - } - - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u\nQuery: %.*s", coap_req->type, coap_req->code, coap_req->mid, len, query)); -} -#endif - -#if REST_RES_LOC_QUERY -/* - * Resource accepting query parameters - */ -RESOURCE(locquery, METHOD_POST, "location-query", "title=\"Resource accepting query parameters\""); - -void -locquery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - PRINTF("/location-query POST (%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); - - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "?first=1&second=2"); -} -#endif - -#if REST_RES_MULTI -/* - * Resource providing text/plain and application/xml - */ -RESOURCE(multi, METHOD_GET, "multi-format", "title=\"Resource providing text/plain and application/xml\";ct=\"0 41\""); -void -multi_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - PRINTF("/multi-format GET (%s %u) %d\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid, num); - - if (num==0 || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u%s", coap_req->type, coap_req->code, coap_req->mid, num ? "\nAccept: 0" : "")); -PRINTF("PLAIN\n"); - } - else if (num && (accept[0]==REST.type.APPLICATION_XML)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_XML); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "", coap_req->type, coap_req->code, coap_req->mid, accept[0])); -PRINTF("XML\n"); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain and application/xml"; - REST.set_response_payload(response, msg, strlen(msg)); - PRINTF("ERROR\n"); - } -} -#endif - -#if REST_RES_LINKS -/* - * Resources providing text/plain and application/xml - */ -RESOURCE(link1, METHOD_GET, "link1", "rt=\"Type1 Type2\";if=\"If1\""); -SUB_RESOURCE(link2, METHOD_GET, "link2", "rt=\"Type2 Type3\";if=\"If2\"", link1); -SUB_RESOURCE(link3, METHOD_GET, "link3", "rt=\"Type1 Type3\";if=\"foo\"", link1); - -void -link1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - const char *msg = "Dummy link"; - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, msg, strlen(msg)); -} -#endif - -#if REST_RES_PATH -/* - * Resources providing text/plain and application/xml - */ -RESOURCE(path, METHOD_GET | HAS_SUB_RESOURCES, "path", "ct=\"40\""); - -void -path_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - - const char *uri_path = NULL; - int len = REST.get_url(request, &uri_path); - int base_len = strlen(resource_path.url); - - if (len==base_len) - { - REST.set_header_content_type(response, REST.type.APPLICATION_LINK_FORMAT); - snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, ",,"); - } - else - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "/%.*s", len, uri_path); - } - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); -} -#endif - -#if REST_RES_SEPARATE -/* Required to manually (=not by the engine) handle the response transaction. */ -#if WITH_COAP == 7 -#include "er-coap-07-separate.h" -#include "er-coap-07-transactions.h" -#elif WITH_COAP == 12 -#include "er-coap-12-separate.h" -#include "er-coap-12-transactions.h" -#elif WITH_COAP == 13 -#include "er-coap-13-separate.h" -#include "er-coap-13-transactions.h" -#endif -/* - * Resource which cannot be served immediately and which cannot be acknowledged in a piggy-backed way - */ -PERIODIC_RESOURCE(separate, METHOD_GET, "separate", "title=\"Resource which cannot be served immediately and which cannot be acknowledged in a piggy-backed way\"", 3*CLOCK_SECOND); - -/* A structure to store the required information */ -typedef struct application_separate_store { - /* Provided by Erbium to store generic request information such as remote address and token. */ - coap_separate_t request_metadata; - /* Add fields for addition information to be stored for finalizing, e.g.: */ - char buffer[MAX_PLUGFEST_PAYLOAD]; -} application_separate_store_t; - -static uint8_t separate_active = 0; -static application_separate_store_t separate_store[1]; - -void -separate_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - PRINTF("/separate "); - if (separate_active) - { - PRINTF("REJECTED "); - coap_separate_reject(); - } - else - { - PRINTF("STORED "); - separate_active = 1; - - /* Take over and skip response by engine. */ - coap_separate_accept(request, &separate_store->request_metadata); - /* Be aware to respect the Block2 option, which is also stored in the coap_separate_t. */ - - snprintf(separate_store->buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid); - } - - PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); -} - -void -separate_periodic_handler(resource_t *resource) -{ - if (separate_active) - { - PRINTF("/separate "); - coap_transaction_t *transaction = NULL; - if ( (transaction = coap_new_transaction(separate_store->request_metadata.mid, &separate_store->request_metadata.addr, separate_store->request_metadata.port)) ) - { - PRINTF("RESPONSE (%s %u)\n", separate_store->request_metadata.type==COAP_TYPE_CON?"CON":"NON", separate_store->request_metadata.mid); - - coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */ - - /* Restore the request information for the response. */ - coap_separate_resume(response, &separate_store->request_metadata, CONTENT_2_05); - - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - coap_set_payload(response, separate_store->buffer, strlen(separate_store->buffer)); - - /* - * Be aware to respect the Block2 option, which is also stored in the coap_separate_t. - * As it is a critical option, this example resource pretends to handle it for compliance. - */ - coap_set_header_block2(response, separate_store->request_metadata.block2_num, 0, separate_store->request_metadata.block2_size); - - /* Warning: No check for serialization error. */ - transaction->packet_len = coap_serialize_message(response, transaction->packet); - coap_send_transaction(transaction); - /* The engine will clear the transaction (right after send for NON, after acked for CON). */ - - separate_active = 0; - } else { - PRINTF("ERROR (transaction)\n"); - } - } /* if (separate_active) */ -} -#endif - -#if REST_RES_LARGE - -/* double expansion */ -#define TO_STRING2(x) #x -#define TO_STRING(x) TO_STRING2(x) +#include "er-coap.h" +#include "er-coap-transactions.h" +#include "er-coap-separate.h" +#include "rest-engine.h" +#include "er-plugtest.h" /* - * Large resource + * Resources to be activated need to be imported through the extern keyword. + * The build system automatically compiles the resources in the corresponding + * sub-directory. */ -RESOURCE(large, METHOD_GET, "large", "title=\"Large resource\";rt=\"block\";sz=\"" TO_STRING(CHUNKS_TOTAL) "\""); - -void -large_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int32_t strpos = 0; - - /* Check the offset for boundaries of the resource data. */ - if (*offset>=CHUNKS_TOTAL) - { - REST.set_response_status(response, REST.status.BAD_OPTION); - /* A block error message should not exceed the minimum block size (16). */ - - const char *error_msg = "BlockOutOfScope"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - /* Generate data until reaching CHUNKS_TOTAL. */ - while (strpos preferred_size) - { - strpos = preferred_size; - } - - /* Truncate if above CHUNKS_TOTAL bytes. */ - if (*offset+(int32_t)strpos > CHUNKS_TOTAL) - { - strpos = CHUNKS_TOTAL - *offset; - } - - REST.set_response_payload(response, buffer, strpos); - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - - /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ - *offset += strpos; - - /* Signal end of resource representation. */ - if (*offset>=CHUNKS_TOTAL) - { - *offset = -1; - } -} -#endif - -#if REST_RES_LARGE_UPDATE -/* - * Large resource that can be updated using PUT method - */ -RESOURCE(large_update, METHOD_GET|METHOD_PUT, "large-update", "title=\"Large resource that can be updated using PUT method\";rt=\"block\";sz=\"" TO_STRING(MAX_PLUGFEST_BODY) "\""); - -static int32_t large_update_size = 0; -static uint8_t large_update_store[MAX_PLUGFEST_BODY] = {0}; -static unsigned int large_update_ct = -1; - -void -large_update_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - uint8_t method = REST.get_method_type(request); - - if (method & METHOD_GET) - { - /* Check the offset for boundaries of the resource data. */ - if (*offset>=large_update_size) - { - REST.set_response_status(response, REST.status.BAD_OPTION); - /* A block error message should not exceed the minimum block size (16). */ - - const char *error_msg = "BlockOutOfScope"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - REST.set_response_payload(response, large_update_store+*offset, MIN(large_update_size - *offset, preferred_size)); - REST.set_header_content_type(response, large_update_ct); - - /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ - *offset += preferred_size; - - /* Signal end of resource representation. */ - if (*offset>=large_update_size) - { - *offset = -1; - } - } else { - uint8_t *incoming = NULL; - size_t len = 0; - - unsigned int ct = REST.get_header_content_type(request); - if (ct==-1) - { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoContentType"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - if ((len = REST.get_request_payload(request, (const uint8_t **) &incoming))) - { - if (coap_req->block1_num*coap_req->block1_size+len <= sizeof(large_update_store)) - { - memcpy(large_update_store+coap_req->block1_num*coap_req->block1_size, incoming, len); - large_update_size = coap_req->block1_num*coap_req->block1_size+len; - large_update_ct = REST.get_header_content_type(request); - - REST.set_response_status(response, REST.status.CHANGED); - coap_set_header_block1(response, coap_req->block1_num, 0, coap_req->block1_size); - } - else - { - REST.set_response_status(response, REST.status.REQUEST_ENTITY_TOO_LARGE); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "%uB max.", sizeof(large_update_store))); - return; - } - } - else - { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoPayload"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - } -} -#endif - -#if REST_RES_LARGE_CREATE -/* - * Large resource that can be created using POST method - */ -RESOURCE(large_create, METHOD_POST, "large-create", "title=\"Large resource that can be created using POST method\";rt=\"block\""); - -void -large_create_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - uint8_t *incoming = NULL; - size_t len = 0; - - unsigned int ct = REST.get_header_content_type(request); - if (ct==-1) - { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoContentType"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - if ((len = REST.get_request_payload(request, (const uint8_t **) &incoming))) - { - if (coap_req->block1_num*coap_req->block1_size+len <= 2048) - { - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "/nirvana"); - coap_set_header_block1(response, coap_req->block1_num, 0, coap_req->block1_size); - } - else - { - REST.set_response_status(response, REST.status.REQUEST_ENTITY_TOO_LARGE); - const char *error_msg = "2048B max."; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - } - else - { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoPayload"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } -} -#endif - -#if REST_RES_OBS - -#if WITH_COAP == 12 -#include "er-coap-12-observing.h" -#elif WITH_COAP == 13 -#include "er-coap-13-observing.h" -#endif -/* - * Observable resource which changes every 5 seconds - */ -PERIODIC_RESOURCE(obs, METHOD_GET|METHOD_PUT|METHOD_DELETE, "obs", "title=\"Observable resource which changes every 5 seconds\";obs", 5*CLOCK_SECOND); - -static uint16_t obs_counter = 0; -static char obs_content[MAX_PLUGFEST_BODY]; -static size_t obs_content_len = 0; -static unsigned int obs_format = 0; - -static char obs_status = 0; - -static -void -obs_purge_list() -{ - PRINTF("### SERVER ACTION ### Purging obs list"); - coap_remove_observer_by_url(NULL, 0, resource_obs.url); -} - -void -obs_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - uint8_t method = request==NULL ? METHOD_GET : REST.get_method_type(request); - - /* Keep server log clean from ticking events */ - if (request!=NULL) - { - PRINTF("/obs "); - } - - if (method & METHOD_GET) - { - /* Keep server log clean from ticking events */ - if (request!=NULL) - { - PRINTF("GET "); - } - - REST.set_header_content_type(response, obs_format); - REST.set_header_max_age(response, 5); - - if (obs_content_len) - { - REST.set_header_content_type(response, obs_format); - REST.set_response_payload(response, obs_content, obs_content_len); - } - else - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, obs_content, snprintf(obs_content, MAX_PLUGFEST_PAYLOAD, "TICK %lu", obs_counter)); - } - /* A post_handler that handles subscriptions will be called for periodic resources by the REST framework. */ - } - else if (method & METHOD_PUT) - { - uint8_t *incoming = NULL; - unsigned int ct = REST.get_header_content_type(request); - - PRINTF("PUT "); - - if (ct!=obs_format) - { - obs_status = 1; - - obs_format = ct; - } else { - - obs_format = ct; - obs_content_len = REST.get_request_payload(request, (const uint8_t **) &incoming); - memcpy(obs_content, incoming, obs_content_len); - obs_periodic_handler(&resource_obs); - } - - REST.set_response_status(response, REST.status.CHANGED); - } - else if (method & METHOD_DELETE) - { - PRINTF("DELETE "); - - obs_status = 2; - - REST.set_response_status(response, REST.status.DELETED); - } - - /* Keep server log clean from ticking events */ - if (request!=NULL) - { - PRINTF("\n"); - } -} - -/* - * Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE. - * It will be called by the REST manager process with the defined period. - */ -void -obs_periodic_handler(resource_t *r) -{ - ++obs_counter; - - //PRINTF("TICK %u for /%s\n", obs_counter, r->url); - - if (obs_status==1) - { - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_NON, INTERNAL_SERVER_ERROR_5_00, 0 ); - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(&resource_obs, -1, notification); - - PRINTF("######### sending 5.00\n"); - - obs_purge_list(); - } - else if (obs_status==2) - { - - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_NON, NOT_FOUND_4_04, 0 ); - - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(&resource_obs, -1, notification); - - obs_purge_list(); - - obs_counter = 0; - obs_content_len = 0; - } - else - { - /* Build notification. */ - /*TODO: REST.new_response() */ - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_NON, CONTENT_2_05, 0 ); - - /* Better use a generator function for both handlers that only takes *resonse. */ - obs_handler(NULL, notification, NULL, 0, NULL); - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(r, obs_counter, notification); - } - obs_status = 0; -} -#endif - -#if REST_RES_MIRROR -/* This resource mirrors the incoming request. It shows how to access the options and how to set them for the response. */ -RESOURCE(mirror, METHOD_GET | METHOD_POST | METHOD_PUT | METHOD_DELETE, "debug/mirror", "title=\"Returns your decoded message\";rt=\"Debug\""); - -void -mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - /* The ETag and Token is copied to the header. */ - uint8_t opaque[] = {0x0A, 0xBC, 0xDE}; - - /* Strings are not copied, so use static string buffers or strings in .text memory (char *str = "string in .text";). */ - static char location[] = {'/','f','/','a','?','k','&','e', 0}; - - /* Getter for the header option Content-Type. If the option is not set, text/plain is returned by default. */ - unsigned int content_type = REST.get_header_content_type(request); - - /* The other getters copy the value (or string/array pointer) to the given pointers and return 1 for success or the length of strings/arrays. */ - uint32_t max_age_and_size = 0; - const char *str = NULL; - uint32_t observe = 0; - const uint8_t *bytes = NULL; - const uint16_t *words = NULL; - uint32_t block_num = 0; - uint8_t block_more = 0; - uint16_t block_size = 0; - const char *query = ""; - int len = 0; - - /* Mirror the received header options in the response payload. Unsupported getters (e.g., rest_get_header_observe() with HTTP) will return 0. */ - - int strpos = 0; - /* snprintf() counts the terminating '\0' to the size parameter. - * The additional byte is taken care of by allocating REST_MAX_CHUNK_SIZE+1 bytes in the REST framework. - * Add +1 to fill the complete buffer, as the payload does not need a terminating '\0'. */ - - - if (strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_header_if_match(request, &bytes))) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "If-Match 0x"); - int index = 0; - for (index = 0; index= REST_MAX_CHUNK_SIZE) - { - buffer[REST_MAX_CHUNK_SIZE-1] = 0xBB; /* '»' to indicate truncation */ - } - - REST.set_response_payload(response, buffer, strpos); - - PRINTF("/mirror options received: %s\n", buffer); - - /* Set dummy header options for response. Like getters, some setters are not implemented for HTTP and have no effect. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_header_max_age(response, 17); /* For HTTP, browsers will not re-request the page for 17 seconds. */ - REST.set_header_etag(response, opaque, 2); - REST.set_header_location(response, location); /* Initial slash is omitted by framework */ - REST.set_header_length(response, strpos); /* For HTTP, browsers will not re-request the page for 10 seconds. CoAP action depends on the client. */ - -/* CoAP-specific example: actions not required for normal RESTful Web service. */ - coap_set_header_uri_host(response, "Contiki"); - coap_set_header_observe(response, 10); - coap_set_header_proxy_uri(response, "ftp://x"); - //coap_set_header_block2(response, 42, 0, 64); - //coap_set_header_block1(response, 23, 0, 16); - coap_set_header_accept(response, APPLICATION_XML); - coap_set_header_accept(response, APPLICATION_ATOM_XML); - coap_set_header_if_none_match(response); -} -#endif /* REST_RES_MIRROR */ - - - - +extern resource_t + res_plugtest_test, + res_plugtest_validate, + res_plugtest_create1, + res_plugtest_create2, + res_plugtest_create3, + res_plugtest_longpath, + res_plugtest_query, + res_plugtest_locquery, + res_plugtest_multi, + res_plugtest_link1, + res_plugtest_link2, + res_plugtest_link3, + res_plugtest_path, + res_plugtest_separate, + res_plugtest_large, + res_plugtest_large_update, + res_plugtest_large_create, + res_plugtest_obs, + res_mirror; PROCESS(plugtest_server, "PlugtestServer"); AUTOSTART_PROCESSES(&plugtest_server); @@ -1240,59 +98,31 @@ PROCESS_THREAD(plugtest_server, ev, data) rest_init_engine(); /* Activate the application-specific resources. */ -#if REST_RES_TEST - rest_activate_resource(&resource_test); - rest_activate_resource(&resource_validate); - rest_activate_resource(&resource_create1); - rest_activate_resource(&resource_create2); - rest_activate_resource(&resource_create3); -#endif -#if REST_RES_LONG - rest_activate_resource(&resource_longpath); -#endif -#if REST_RES_QUERY - rest_activate_resource(&resource_query); -#endif -#if REST_RES_LOC_QUERY - rest_activate_resource(&resource_locquery); -#endif -#if REST_RES_MULTI - rest_activate_resource(&resource_multi); -#endif -#if REST_RES_LINKS - rest_activate_resource(&resource_link1); - rest_activate_resource(&resource_link2); - rest_activate_resource(&resource_link3); -#endif -#if REST_RES_PATH - rest_activate_resource(&resource_path); -#endif -#if REST_RES_SEPARATE - rest_activate_periodic_resource(&periodic_resource_separate); -#endif -#if REST_RES_LARGE - rest_activate_resource(&resource_large); -#endif -#if REST_RES_LARGE_UPDATE - large_update_ct = REST.type.APPLICATION_OCTET_STREAM; - rest_activate_resource(&resource_large_update); -#endif -#if REST_RES_LARGE_CREATE - rest_activate_resource(&resource_large_create); -#endif -#if REST_RES_OBS - rest_activate_periodic_resource(&periodic_resource_obs); -#endif + rest_activate_resource(&res_plugtest_test, "test"); + rest_activate_resource(&res_plugtest_validate, "validate"); + rest_activate_resource(&res_plugtest_create1, "create1"); + rest_activate_resource(&res_plugtest_create2, "create2"); + rest_activate_resource(&res_plugtest_create3, "create3"); + rest_activate_resource(&res_plugtest_longpath, "seg1/seg2/seg3"); + rest_activate_resource(&res_plugtest_query, "query"); + rest_activate_resource(&res_plugtest_locquery, "location-query"); + rest_activate_resource(&res_plugtest_multi, "multi-format"); + rest_activate_resource(&res_plugtest_link1, "link1"); + rest_activate_resource(&res_plugtest_link2, "link2"); + rest_activate_resource(&res_plugtest_link3, "link3"); + rest_activate_resource(&res_plugtest_path, "path"); + rest_activate_resource(&res_plugtest_separate, "separate"); + rest_activate_resource(&res_plugtest_large, "large"); + rest_activate_resource(&res_plugtest_large_update, "large-update"); + rest_activate_resource(&res_plugtest_large_create, "large-create"); + rest_activate_resource(&res_plugtest_obs, "obs"); -#if REST_RES_MIRROR - rest_activate_resource(&resource_mirror); -#endif + rest_activate_resource(&res_mirror, "mirror"); /* Define application-specific events here. */ while(1) { PROCESS_WAIT_EVENT(); - - } /* while (1) */ + } /* while (1) */ PROCESS_END(); } diff --git a/examples/er-rest-example/er-plugtest.h b/examples/er-rest-example/er-plugtest.h new file mode 100644 index 000000000..0b156656a --- /dev/null +++ b/examples/er-rest-example/er-plugtest.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Erbium (Er) CoAP client example + * \author + * Matthias Kovatsch + */ + +#ifndef __ER_PLUGTEST_H__ +#define __ER_PLUGTEST_H__ + +#if !defined(CONTIKI_TARGET_NATIVE) +#warning "Should only be compiled for native!" +#endif + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +/* double expansion */ +#define TO_STRING2(x) # x +#define TO_STRING(x) TO_STRING2(x) + +#define MAX_PLUGFEST_PAYLOAD 64 + 1 /* +1 for the terminating zero, which is not transmitted */ +#define MAX_PLUGFEST_BODY 2048 +#define CHUNKS_TOTAL 2012 + +#endif /* __ER_PLUGTEST_H__ */ diff --git a/examples/er-rest-example/project-conf.h b/examples/er-rest-example/project-conf.h index 128ccd0b2..adcb75ee1 100644 --- a/examples/er-rest-example/project-conf.h +++ b/examples/er-rest-example/project-conf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Matthias Kovatsch + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,63 +26,83 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * + * This file is part of the Contiki operating system. */ -#ifndef PROJECT_ERBIUM_CONF_H_ -#define PROJECT_ERBIUM_CONF_H_ +/** + * \file + * Erbium (Er) example project configuration. + * \author + * Matthias Kovatsch + */ -/* Some platforms have weird includes. */ -#undef IEEE802154_CONF_PANID +#ifndef __PROJECT_ERBIUM_CONF_H__ +#define __PROJECT_ERBIUM_CONF_H__ -/* Disabling RDC for demo purposes. Core updates often require more memory. */ -/* For projects, optimize memory and enable RDC again. */ +/* Custom channel and PAN ID configuration for your project. */ +/* + #undef RF_CHANNEL + #define RF_CHANNEL 26 + + #undef IEEE802154_CONF_PANID + #define IEEE802154_CONF_PANID 0xABCD + */ + +/* IP buffer size must match all other hops, in particular the border router. */ +/* + #undef UIP_CONF_BUFFER_SIZE + #define UIP_CONF_BUFFER_SIZE 256 + */ + +/* Disabling RDC and CSMA for demo purposes. Core updates often + require more memory. */ +/* For projects, optimize memory and enable RDC and CSMA again. */ #undef NETSTACK_CONF_RDC -#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_RDC nullrdc_driver + +#undef RPL_CONF_MAX_DAG_PER_INSTANCE +#define RPL_CONF_MAX_DAG_PER_INSTANCE 1 + +/* Disabling TCP on CoAP nodes. */ +#undef UIP_CONF_TCP +#define UIP_CONF_TCP 0 + +#undef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC nullmac_driver /* Increase rpl-border-router IP-buffer when using more than 64. */ #undef REST_MAX_CHUNK_SIZE -#define REST_MAX_CHUNK_SIZE 64 +#define REST_MAX_CHUNK_SIZE 48 /* Estimate your header size, especially when using Proxy-Uri. */ /* -#undef COAP_MAX_HEADER_SIZE -#define COAP_MAX_HEADER_SIZE 70 -*/ - -/* The IP buffer size must fit all other hops, in particular the border router. */ -/* -#undef UIP_CONF_BUFFER_SIZE -#define UIP_CONF_BUFFER_SIZE 1280 -*/ + #undef COAP_MAX_HEADER_SIZE + #define COAP_MAX_HEADER_SIZE 70 + */ /* Multiplies with chunk size, be aware of memory constraints. */ #undef COAP_MAX_OPEN_TRANSACTIONS -#define COAP_MAX_OPEN_TRANSACTIONS 4 +#define COAP_MAX_OPEN_TRANSACTIONS 4 -/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* Must be <= open transactions, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ /* -#undef COAP_MAX_OBSERVERS -#define COAP_MAX_OBSERVERS 2 -*/ + #undef COAP_MAX_OBSERVERS + #define COAP_MAX_OBSERVERS 2 + */ /* Filtering .well-known/core per query can be disabled to save space. */ -/* #undef COAP_LINK_FORMAT_FILTERING -#define COAP_LINK_FORMAT_FILTERING 0 -*/ +#define COAP_LINK_FORMAT_FILTERING 0 +#undef COAP_PROXY_OPTION_PROCESSING +#define COAP_PROXY_OPTION_PROCESSING 0 -/* Save some memory for the sky platform. */ -#undef NBR_TABLE_CONF_MAX_NEIGHBORS -#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 -#undef UIP_CONF_MAX_ROUTES -#define UIP_CONF_MAX_ROUTES 10 +/* Turn of DAO ACK to make code smaller */ +#undef RPL_CONF_WITH_DAO_ACK +#define RPL_CONF_WITH_DAO_ACK 0 -/* Reduce 802.15.4 frame queue to save RAM. */ -#undef QUEUEBUF_CONF_NUM -#define QUEUEBUF_CONF_NUM 4 +#undef RPL_CONF_OF +#define RPL_CONF_OF rpl_of0 -#undef SICSLOWPAN_CONF_FRAG -#define SICSLOWPAN_CONF_FRAG 1 - -#endif /* PROJECT_ERBIUM_CONF_H_ */ +/* Enable client-side support for COAP observe */ +#define COAP_OBSERVE_CLIENT 1 +#endif /* __PROJECT_ERBIUM_CONF_H__ */ diff --git a/examples/er-rest-example/resources/res-b1-sep-b2.c b/examples/er-rest-example/resources/res-b1-sep-b2.c new file mode 100644 index 000000000..7dcbdd0ca --- /dev/null +++ b/examples/er-rest-example/resources/res-b1-sep-b2.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Lars Schmertmann + */ + +#include +#include "rest-engine.h" +#include "er-coap-block1.h" +#include "er-coap-separate.h" +#include "er-coap-transactions.h" + +static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +SEPARATE_RESOURCE(res_b1_sep_b2, "title=\"Block1 + Separate + Block2 demo\"", NULL, res_post_handler, NULL, NULL, NULL); + +#define MAX_DATA_LEN 256 + +static uint8_t big_msg[MAX_DATA_LEN]; +static size_t big_msg_len = 0; +static coap_separate_t request_metadata; + +static void +res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* Example allows only one request on time. There are no checks for multiply access !!! */ + if(*offset == 0) { + /* Incoming Data */ + if(coap_block1_handler(request, response, big_msg, &big_msg_len, MAX_DATA_LEN)) { + /* More Blocks will follow. Example waits for + * the last block and stores data into big_msg. + */ + return; + } + /* Last block was received. */ + coap_separate_accept(request, &request_metadata); + + /* Need Time for calculation now */ + unsigned i; + for(i = 0; i <= 4096; i++) { + printf("\r%4u\r", i); + } + printf("\n"); + + /* Send first block */ + coap_transaction_t *transaction = NULL; + if((transaction = coap_new_transaction(request_metadata.mid, &request_metadata.addr, request_metadata.port))) { + coap_packet_t resp[1]; /* This way the packet can be treated as pointer as usual. */ + + /* Restore the request information for the response. */ + coap_separate_resume(resp, &request_metadata, CONTENT_2_05); + + /* Set payload and block info */ + coap_set_payload(resp, big_msg, big_msg_len > request_metadata.block2_size ? request_metadata.block2_size : big_msg_len); + if(big_msg_len > request_metadata.block2_size) { + coap_set_header_block2(resp, 0, 1, request_metadata.block2_size); + } + + /* Warning: No check for serialization error. */ + transaction->packet_len = coap_serialize_message(resp, transaction->packet); + coap_send_transaction(transaction); + } + } else { + /* request for more blocks */ + if(*offset >= big_msg_len) { + coap_set_status_code(response, BAD_OPTION_4_02); + coap_set_payload(response, "BlockOutOfScope", 15); + return; + } + + memcpy(buffer, big_msg + *offset, 32); + if(big_msg_len - *offset < preferred_size) { + preferred_size = big_msg_len - *offset; + *offset = -1; + } else { + *offset += preferred_size; + } + coap_set_payload(response, buffer, preferred_size); + } +} diff --git a/examples/er-rest-example/resources/res-battery.c b/examples/er-rest-example/resources/res-battery.c new file mode 100644 index 000000000..b82523594 --- /dev/null +++ b/examples/er-rest-example/resources/res-battery.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include "contiki.h" + +#if PLATFORM_HAS_BATTERY + +#include +#include "rest-engine.h" +#include "dev/battery-sensor.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from light sensor with a simple etag */ +RESOURCE(res_battery, + "title=\"Battery status\";rt=\"Battery\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + int battery = battery_sensor.value(0); + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", battery); + + REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'battery':%d}", battery); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} +#endif /* PLATFORM_HAS_BATTERY */ diff --git a/examples/er-rest-example/resources/res-chunks.c b/examples/er-rest-example/resources/res-chunks.c new file mode 100644 index 000000000..79ad55094 --- /dev/null +++ b/examples/er-rest-example/resources/res-chunks.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* + * For data larger than REST_MAX_CHUNK_SIZE (e.g., when stored in flash) resources must be aware of the buffer limitation + * and split their responses by themselves. To transfer the complete resource through a TCP stream or CoAP's blockwise transfer, + * the byte offset where to continue is provided to the handler as int32_t pointer. + * These chunk-wise resources must set the offset value to its new position or -1 of the end is reached. + * (The offset for CoAP's blockwise transfer can go up to 2'147'481'600 = ~2047 M for block size 2048 (reduced to 1024 in observe-03.) + */ +RESOURCE(res_chunks, + "title=\"Blockwise demo\";rt=\"Data\"", + res_get_handler, + NULL, + NULL, + NULL); + +#define CHUNKS_TOTAL 2050 + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + int32_t strpos = 0; + + /* Check the offset for boundaries of the resource data. */ + if(*offset >= CHUNKS_TOTAL) { + REST.set_response_status(response, REST.status.BAD_OPTION); + /* A block error message should not exceed the minimum block size (16). */ + + const char *error_msg = "BlockOutOfScope"; + REST.set_response_payload(response, error_msg, strlen(error_msg)); + return; + } + + /* Generate data until reaching CHUNKS_TOTAL. */ + while(strpos < preferred_size) { + strpos += snprintf((char *)buffer + strpos, preferred_size - strpos + 1, "|%ld|", *offset); + } + + /* snprintf() does not adjust return value if truncated by size. */ + if(strpos > preferred_size) { + strpos = preferred_size; + /* Truncate if above CHUNKS_TOTAL bytes. */ + } + if(*offset + (int32_t)strpos > CHUNKS_TOTAL) { + strpos = CHUNKS_TOTAL - *offset; + } + REST.set_response_payload(response, buffer, strpos); + + /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ + *offset += strpos; + + /* Signal end of resource representation. */ + if(*offset >= CHUNKS_TOTAL) { + *offset = -1; + } +} diff --git a/examples/er-rest-example/resources/res-event.c b/examples/er-rest-example/resources/res-event.c new file mode 100644 index 000000000..7524d2ad2 --- /dev/null +++ b/examples/er-rest-example/resources/res-event.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_event_handler(void); + +/* + * Example for an event resource. + * Additionally takes a period parameter that defines the interval to call [name]_periodic_handler(). + * A default post_handler takes care of subscriptions and manages a list of subscribers to notify. + */ +EVENT_RESOURCE(res_event, + "title=\"Event demo\";obs", + res_get_handler, + NULL, + NULL, + NULL, + res_event_handler); + +/* + * Use local resource state that is accessed by res_get_handler() and altered by res_event_handler() or PUT or POST. + */ +static int32_t event_counter = 0; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "EVENT %lu", event_counter)); + + /* A post_handler that handles subscriptions/observing will be called for periodic resources by the framework. */ +} +/* + * Additionally, res_event_handler must be implemented for each EVENT_RESOURCE. + * It is called through .trigger(), usually from the server process. + */ +static void +res_event_handler(void) +{ + /* Do the update triggered by the event here, e.g., sampling a sensor. */ + ++event_counter; + + /* Usually a condition is defined under with subscribers are notified, e.g., event was above a threshold. */ + if(1) { + PRINTF("TICK %u for /%s\n", event_counter, res_event.url); + + /* Notify the registered observers which will trigger the res_get_handler to create the response. */ + REST.notify_subscribers(&res_event); + } +} diff --git a/examples/er-rest-example/resources/res-hello.c b/examples/er-rest-example/resources/res-hello.c new file mode 100644 index 000000000..9208f8b74 --- /dev/null +++ b/examples/er-rest-example/resources/res-hello.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include +#include "rest-engine.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* + * A handler function named [resource name]_handler must be implemented for each RESOURCE. + * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore + * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. + * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. + */ +RESOURCE(res_hello, + "title=\"Hello world: ?len=0..\";rt=\"Text\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const char *len = NULL; + /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ + char const *const message = "Hello World! ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy"; + int length = 12; /* |<-------->| */ + + /* The query string can be retrieved by rest_get_query() or parsed for its key-value pairs. */ + if(REST.get_query_variable(request, "len", &len)) { + length = atoi(len); + if(length < 0) { + length = 0; + } + if(length > REST_MAX_CHUNK_SIZE) { + length = REST_MAX_CHUNK_SIZE; + } + memcpy(buffer, message, length); + } else { + memcpy(buffer, message, length); + } REST.set_header_content_type(response, REST.type.TEXT_PLAIN); /* text/plain is the default, hence this option could be omitted. */ + REST.set_header_etag(response, (uint8_t *)&length, 1); + REST.set_response_payload(response, buffer, length); +} diff --git a/examples/er-rest-example/resources/res-leds.c b/examples/er-rest-example/resources/res-leds.c new file mode 100644 index 000000000..5fbcf6c77 --- /dev/null +++ b/examples/er-rest-example/resources/res-leds.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include "contiki.h" + +#if PLATFORM_HAS_LEDS + +#include +#include "rest-engine.h" +#include "dev/leds.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +static void res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ +RESOURCE(res_leds, + "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\"", + NULL, + res_post_put_handler, + res_post_put_handler, + NULL); + +static void +res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + size_t len = 0; + const char *color = NULL; + const char *mode = NULL; + uint8_t led = 0; + int success = 1; + + if((len = REST.get_query_variable(request, "color", &color))) { + PRINTF("color %.*s\n", len, color); + + if(strncmp(color, "r", len) == 0) { + led = LEDS_RED; + } else if(strncmp(color, "g", len) == 0) { + led = LEDS_GREEN; + } else if(strncmp(color, "b", len) == 0) { + led = LEDS_BLUE; + } else { + success = 0; + } + } else { + success = 0; + } if(success && (len = REST.get_post_variable(request, "mode", &mode))) { + PRINTF("mode %s\n", mode); + + if(strncmp(mode, "on", len) == 0) { + leds_on(led); + } else if(strncmp(mode, "off", len) == 0) { + leds_off(led); + } else { + success = 0; + } + } else { + success = 0; + } if(!success) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} +#endif /* PLATFORM_HAS_LEDS */ diff --git a/examples/er-rest-example/resources/res-light.c b/examples/er-rest-example/resources/res-light.c new file mode 100644 index 000000000..226d814bb --- /dev/null +++ b/examples/er-rest-example/resources/res-light.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include "contiki.h" + +#if PLATFORM_HAS_LIGHT + +#include +#include "rest-engine.h" +#include "dev/light-sensor.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from light sensor with a simple etag */ +RESOURCE(res_light, + "title=\"Photosynthetic and solar light (supports JSON)\";rt=\"LightSensor\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + uint16_t light_photosynthetic = light_sensor.value(LIGHT_SENSOR_PHOTOSYNTHETIC); + uint16_t light_solar = light_sensor.value(LIGHT_SENSOR_TOTAL_SOLAR); + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%u;%u", light_photosynthetic, light_solar); + + REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_XML) { + REST.set_header_content_type(response, REST.type.APPLICATION_XML); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "", light_photosynthetic, light_solar); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'light':{'photosynthetic':%u,'solar':%u}}", light_photosynthetic, light_solar); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain, application/xml, and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} +#endif /* PLATFORM_HAS_LIGHT */ diff --git a/examples/er-rest-example/resources/res-mirror.c b/examples/er-rest-example/resources/res-mirror.c new file mode 100644 index 000000000..e33bda6d3 --- /dev/null +++ b/examples/er-rest-example/resources/res-mirror.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +static void res_any_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* This resource mirrors the incoming request. It shows how to access the options and how to set them for the response. */ +RESOURCE(res_mirror, + "title=\"Returns your decoded message\";rt=\"Debug\"", + res_any_handler, + res_any_handler, + res_any_handler, + res_any_handler); + +static void +res_any_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* The ETag and Token is copied to the header. */ + uint8_t opaque[] = { 0x0A, 0xBC, 0xDE }; + + /* Strings are not copied, so use static string buffers or strings in .text memory (char *str = "string in .text";). */ + static char location[] = { '/', 'f', '/', 'a', '?', 'k', '&', 'e', 0 }; + + /* No default my be assumed for the Content-Format. (Unsigned -1 means all bits set.) */ + unsigned int content_format = -1; + + /* The other getters copy the value (or string/array pointer) to the given pointers and return 1 for success or the length of strings/arrays. */ + uint32_t longint = 0; + const char *str = NULL; + const uint8_t *bytes = NULL; + uint32_t block_num = 0; + uint8_t block_more = 0; + uint16_t block_size = 0; + int len = 0; + + /* Mirror the received header options in the response payload. Unsupported getters (e.g., rest_get_header_observe() with HTTP) will return 0. */ + + int strpos = 0; + /* snprintf() counts the terminating '\0' to the size parameter. + * The additional byte is taken care of by allocating REST_MAX_CHUNK_SIZE+1 bytes in the REST framework. + * Add +1 to fill the complete buffer, as the payload does not need a terminating '\0'. */ + if(REST.get_header_content_type(request, &content_format)) { + strpos += snprintf((char *)buffer, REST_MAX_CHUNK_SIZE + 1, "CF %u\n", content_format); + } + if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_header_accept(request, &content_format))) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "Ac %u\n", content_format); + /* Some getters such as for ETag or Location are omitted, as these options should not appear in a request. + * Max-Age might appear in HTTP requests or used for special purposes in CoAP. */ + } + if(strpos <= REST_MAX_CHUNK_SIZE && REST.get_header_max_age(request, &longint)) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "MA %lu\n", longint); + /* For HTTP this is the Length option, for CoAP it is the Size option. */ + } + if(strpos <= REST_MAX_CHUNK_SIZE && REST.get_header_length(request, &longint)) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "SZ %lu\n", longint); + } + if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_header_host(request, &str))) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "UH %.*s\n", len, str); + } + if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_url(request, &str))) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "UP %.*s\n", len, str); + } + if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_query(request, &str))) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "UQ %.*s\n", len, str); + /* Undefined request options for debugging: actions not required for normal RESTful Web service. */ + } + if(strpos <= REST_MAX_CHUNK_SIZE && (len = coap_get_header_location_path(request, &str))) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "LP %.*s\n", len, str); + } + if(strpos <= REST_MAX_CHUNK_SIZE && (len = coap_get_header_location_query(request, &str))) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "LQ %.*s\n", len, str); + /* CoAP-specific example: actions not required for normal RESTful Web service. */ + } + coap_packet_t *const coap_pkt = (coap_packet_t *)request; + + if(strpos <= REST_MAX_CHUNK_SIZE && coap_pkt->token_len > 0) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "To 0x"); + int index = 0; + for(index = 0; index < coap_pkt->token_len; ++index) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "%02X", coap_pkt->token[index]); + } + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "\n"); + } + + if(strpos <= REST_MAX_CHUNK_SIZE && IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "Ob %lu\n", coap_pkt->observe); + } + if(strpos <= REST_MAX_CHUNK_SIZE && IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "ET 0x"); + int index = 0; + for(index = 0; index < coap_pkt->etag_len; ++index) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "%02X", coap_pkt->etag[index]); + } + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "\n"); + } + if(strpos <= REST_MAX_CHUNK_SIZE && coap_get_header_block2(request, &block_num, &block_more, &block_size, NULL)) { /* This getter allows NULL pointers to get only a subset of the block parameters. */ + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "B2 %lu%s (%u)\n", block_num, block_more ? "+" : "", block_size); + } + if(strpos <= REST_MAX_CHUNK_SIZE && coap_get_header_block1(request, &block_num, &block_more, &block_size, NULL)) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "B1 %lu%s (%u)\n", block_num, block_more ? "+" : "", block_size); + } + if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_request_payload(request, &bytes))) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "%.*s", len, bytes); + } + if(strpos >= REST_MAX_CHUNK_SIZE) { + buffer[REST_MAX_CHUNK_SIZE - 1] = 0xBB; /* '»' to indicate truncation */ + } + REST.set_response_payload(response, buffer, strpos); + + PRINTF("/mirror options received: %s\n", buffer); + + /* Set dummy header options for response. Like getters, some setters are not implemented for HTTP and have no effect. */ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_header_max_age(response, 17); /* For HTTP, browsers will not re-request the page for 17 seconds. */ + REST.set_header_etag(response, opaque, 2); + REST.set_header_location(response, location); /* Initial slash is omitted by framework */ + REST.set_header_length(response, strpos); /* For HTTP, browsers will not re-request the page for 10 seconds. CoAP action depends on the client. */ + +/* CoAP-specific example: actions not required for normal RESTful Web service. */ + coap_set_header_uri_host(response, "tiki"); + coap_set_header_observe(response, 10); + coap_set_header_proxy_uri(response, "ftp://x"); + coap_set_header_block2(response, 42, 0, 64); /* The block option might be overwritten by the framework when blockwise transfer is requested. */ + coap_set_header_block1(response, 23, 0, 16); + coap_set_header_accept(response, TEXT_PLAIN); + coap_set_header_if_none_match(response); +} diff --git a/apps/er-coap-07/er-coap-07-transactions.h b/examples/er-rest-example/resources/res-plugtest-create1.c similarity index 55% rename from apps/er-coap-07/er-coap-07-transactions.h rename to examples/er-rest-example/resources/res-plugtest-create1.c index 0301ec13d..4ba5f6181 100644 --- a/apps/er-coap-07/er-coap-07-transactions.h +++ b/examples/er-rest-example/resources/res-plugtest-create1.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,48 +31,50 @@ /** * \file - * CoAP module for reliable transport + * ETSI Plugtest resource * \author * Matthias Kovatsch */ -#ifndef COAP_TRANSACTIONS_H_ -#define COAP_TRANSACTIONS_H_ +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" -#include "er-coap-07.h" +static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); -/* - * The number of concurrent messages that can be stored for retransmission in the transaction layer. - */ -#ifndef COAP_MAX_OPEN_TRANSACTIONS -#define COAP_MAX_OPEN_TRANSACTIONS 4 -#endif /* COAP_MAX_OPEN_TRANSACTIONS */ +RESOURCE(res_plugtest_create1, + "title=\"Creates on PUT\"", + NULL, + NULL, + res_put_handler, + res_delete_handler); -/* container for transactions with message buffer and retransmission info */ -typedef struct coap_transaction { - struct coap_transaction *next; /* for LIST */ +static uint8_t create1_exists = 0; - uint16_t mid; - struct etimer retrans_timer; - uint8_t retrans_counter; +static void +res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + PRINTF("/create1 PUT"); - uip_ipaddr_t addr; - uint16_t port; + if(coap_get_header_if_none_match(request)) { + if(!create1_exists) { + REST.set_response_status(response, REST.status.CREATED); - restful_response_handler callback; - void *callback_data; + create1_exists = 1; + } else { + REST.set_response_status(response, PRECONDITION_FAILED_4_12); + } + } else { + REST.set_response_status(response, REST.status.CHANGED); + } +} +static void +res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + PRINTF("/create1 DELETE "); + REST.set_response_status(response, REST.status.DELETED); - uint16_t packet_len; - uint8_t packet[COAP_MAX_PACKET_SIZE+1]; /* +1 for the terminating '\0' to simply and savely use snprintf(buf, len+1, "", ...) in the resource handler. */ -} coap_transaction_t; - -void coap_register_as_transaction_handler(); - -coap_transaction_t *coap_new_transaction(uint16_t mid, uip_ipaddr_t *addr, uint16_t port); -void coap_send_transaction(coap_transaction_t *t); -void coap_clear_transaction(coap_transaction_t *t); -coap_transaction_t *coap_get_transaction_by_mid(uint16_t mid); - -void coap_check_transactions(); - -#endif /* COAP_TRANSACTIONS_H_ */ + create1_exists = 0; +} diff --git a/examples/er-rest-example/resources/res-plugtest-create2.c b/examples/er-rest-example/resources/res-plugtest-create2.c new file mode 100644 index 000000000..25877ac70 --- /dev/null +++ b/examples/er-rest-example/resources/res-plugtest-create2.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_create2, + "title=\"Creates on POST\"", + NULL, + res_post_handler, + NULL, + NULL); + +static void +res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + PRINTF("/create2 "); + + REST.set_response_status(response, REST.status.CREATED); + REST.set_header_location(response, "/location1/location2/location3"); +} diff --git a/examples/er-rest-example/resources/res-plugtest-create3.c b/examples/er-rest-example/resources/res-plugtest-create3.c new file mode 100644 index 000000000..2498c065a --- /dev/null +++ b/examples/er-rest-example/resources/res-plugtest-create3.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_create3, + "title=\"Default test resource\"", + NULL, + NULL, + res_put_handler, + res_delete_handler); + +static uint8_t create3_exists = 0; + +static void +res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + PRINTF("/create3 PUT "); + + if(coap_get_header_if_none_match(request)) { + if(!create3_exists) { + REST.set_response_status(response, REST.status.CREATED); + + create3_exists = 1; + } else { + REST.set_response_status(response, PRECONDITION_FAILED_4_12); + } + } else { + REST.set_response_status(response, REST.status.CHANGED); + } +} +static void +res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + PRINTF("/create3 DELETE "); + REST.set_response_status(response, REST.status.DELETED); + + create3_exists = 0; +} diff --git a/examples/er-rest-example/resources/res-plugtest-large-create.c b/examples/er-rest-example/resources/res-plugtest-large-create.c new file mode 100644 index 000000000..888dfaa31 --- /dev/null +++ b/examples/er-rest-example/resources/res-plugtest-large-create.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* + * Large resource that can be created using POST method + */ +RESOURCE(res_plugtest_large_create, + "title=\"Large resource that can be created using POST method\";rt=\"block\"", + NULL, + res_post_handler, + NULL, + NULL); + +static void +res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + uint8_t *incoming = NULL; + size_t len = 0; + + unsigned int ct = -1; + + if(!REST.get_header_content_type(request, &ct)) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + const char *error_msg = "NoContentType"; + REST.set_response_payload(response, error_msg, strlen(error_msg)); + return; + } + + if((len = REST.get_request_payload(request, (const uint8_t **)&incoming))) { + if(coap_req->block1_num * coap_req->block1_size + len <= 2048) { + REST.set_response_status(response, REST.status.CREATED); + REST.set_header_location(response, "/nirvana"); + coap_set_header_block1(response, coap_req->block1_num, 0, + coap_req->block1_size); + } else { + REST.set_response_status(response, REST.status.REQUEST_ENTITY_TOO_LARGE); + const char *error_msg = "2048B max."; + REST.set_response_payload(response, error_msg, strlen(error_msg)); + return; + } + } else { + REST.set_response_status(response, REST.status.BAD_REQUEST); + const char *error_msg = "NoPayload"; + REST.set_response_payload(response, error_msg, strlen(error_msg)); + return; + } +} diff --git a/examples/er-rest-example/resources/res-plugtest-large-update.c b/examples/er-rest-example/resources/res-plugtest-large-update.c new file mode 100644 index 000000000..12c7d1e9f --- /dev/null +++ b/examples/er-rest-example/resources/res-plugtest-large-update.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "sys/cc.h" +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE( + res_plugtest_large_update, + "title=\"Large resource that can be updated using PUT method\";rt=\"block\";sz=\"" TO_STRING(MAX_PLUGFEST_BODY) "\"", + res_get_handler, + NULL, + res_put_handler, + NULL); + +static int32_t large_update_size = 0; +static uint8_t large_update_store[MAX_PLUGFEST_BODY] = { 0 }; +static unsigned int large_update_ct = APPLICATION_OCTET_STREAM; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* Check the offset for boundaries of the resource data. */ + if(*offset >= large_update_size) { + REST.set_response_status(response, REST.status.BAD_OPTION); + /* A block error message should not exceed the minimum block size (16). */ + + const char *error_msg = "BlockOutOfScope"; + REST.set_response_payload(response, error_msg, strlen(error_msg)); + return; + } + + REST.set_response_payload(response, large_update_store + *offset, + MIN(large_update_size - *offset, preferred_size)); + REST.set_header_content_type(response, large_update_ct); + + /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ + *offset += preferred_size; + + /* Signal end of resource representation. */ + if(*offset >= large_update_size) { + *offset = -1; + } +} +static void +res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + uint8_t *incoming = NULL; + size_t len = 0; + + unsigned int ct = -1; + + if(!REST.get_header_content_type(request, &ct)) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + const char *error_msg = "NoContentType"; + REST.set_response_payload(response, error_msg, strlen(error_msg)); + return; + } + + if((len = REST.get_request_payload(request, (const uint8_t **)&incoming))) { + if(coap_req->block1_num * coap_req->block1_size + len <= sizeof(large_update_store)) { + memcpy( + large_update_store + coap_req->block1_num * coap_req->block1_size, + incoming, len); + large_update_size = coap_req->block1_num * coap_req->block1_size + len; + large_update_ct = ct; + + REST.set_response_status(response, REST.status.CHANGED); + coap_set_header_block1(response, coap_req->block1_num, 0, + coap_req->block1_size); + } else { + REST.set_response_status(response, + REST.status.REQUEST_ENTITY_TOO_LARGE); + REST.set_response_payload( + response, + buffer, + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "%uB max.", + sizeof(large_update_store))); + return; + } + } else { + REST.set_response_status(response, REST.status.BAD_REQUEST); + const char *error_msg = "NoPayload"; + REST.set_response_payload(response, error_msg, strlen(error_msg)); + return; + } +} diff --git a/examples/er-rest-example/resources/res-plugtest-large.c b/examples/er-rest-example/resources/res-plugtest-large.c new file mode 100644 index 000000000..d997dd927 --- /dev/null +++ b/examples/er-rest-example/resources/res-plugtest-large.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_large, + "title=\"Large resource\";rt=\"block\";sz=\"" TO_STRING(CHUNKS_TOTAL) "\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + int32_t strpos = 0; + + /* Check the offset for boundaries of the resource data. */ + if(*offset >= CHUNKS_TOTAL) { + REST.set_response_status(response, REST.status.BAD_OPTION); + /* A block error message should not exceed the minimum block size (16). */ + + const char *error_msg = "BlockOutOfScope"; + REST.set_response_payload(response, error_msg, strlen(error_msg)); + return; + } + + /* Generate data until reaching CHUNKS_TOTAL. */ + while(strpos < preferred_size) { + strpos += snprintf((char *)buffer + strpos, preferred_size - strpos + 1, + "|%ld|", *offset); + } + + /* snprintf() does not adjust return value if truncated by size. */ + if(strpos > preferred_size) { + strpos = preferred_size; + /* Truncate if above CHUNKS_TOTAL bytes. */ + } + if(*offset + (int32_t)strpos > CHUNKS_TOTAL) { + strpos = CHUNKS_TOTAL - *offset; + } + REST.set_response_payload(response, buffer, strpos); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + + /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ + *offset += strpos; + + /* Signal end of resource representation. */ + if(*offset >= CHUNKS_TOTAL) { + *offset = -1; + } +} diff --git a/examples/er-rest-example/resources/res-plugtest-links.c b/examples/er-rest-example/resources/res-plugtest-links.c new file mode 100644 index 000000000..be68aadf7 --- /dev/null +++ b/examples/er-rest-example/resources/res-plugtest-links.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_link1, + "rt=\"Type1 Type2\";if=\"If1\"", + res_get_handler, + NULL, + NULL, + NULL); +RESOURCE(res_plugtest_link2, + "rt=\"Type2 Type3\";if=\"If2\"", + res_get_handler, + NULL, + NULL, + NULL); +RESOURCE(res_plugtest_link3, + "rt=\"Type1 Type3\";if=\"foo\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const char *msg = "Dummy link"; + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, msg, strlen(msg)); +} diff --git a/examples/er-rest-example/resources/res-plugtest-locquery.c b/examples/er-rest-example/resources/res-plugtest-locquery.c new file mode 100644 index 000000000..64e79ff25 --- /dev/null +++ b/examples/er-rest-example/resources/res-plugtest-locquery.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_locquery, + "title=\"Resource accepting query parameters\"", + NULL, + res_post_handler, + NULL, + NULL); + +static void +res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + PRINTF( + "/location-query POST (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + REST.set_response_status(response, REST.status.CREATED); + REST.set_header_location(response, "?first=1&second=2"); +} diff --git a/examples/er-rest-example/resources/res-plugtest-longpath.c b/examples/er-rest-example/resources/res-plugtest-longpath.c new file mode 100644 index 000000000..d6c4fb855 --- /dev/null +++ b/examples/er-rest-example/resources/res-plugtest-longpath.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_longpath, + "title=\"Long path resource\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + PRINTF("/seg1/seg2/seg3 GET "); + /* Code 2.05 CONTENT is default. */ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload( + response, + buffer, + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, + "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); + + PRINTF("(%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); +} diff --git a/examples/er-rest-example/resources/res-plugtest-multi.c b/examples/er-rest-example/resources/res-plugtest-multi.c new file mode 100644 index 000000000..281a2268f --- /dev/null +++ b/examples/er-rest-example/resources/res-plugtest-multi.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_multi, + "title=\"Resource providing text/plain and application/xml\";ct=\"0 41\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + PRINTF("/multi-format GET (%s %u) ", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload( + response, + buffer, + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, + "Type: %u\nCode: %u\nMID: %u%s", coap_req->type, coap_req->code, + coap_req->mid, accept != -1 ? "\nAccept: 0" : "")); + PRINTF("PLAIN\n"); + } else if(accept == REST.type.APPLICATION_XML) { + REST.set_header_content_type(response, REST.type.APPLICATION_XML); + REST.set_response_payload( + response, + buffer, + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, + "", + coap_req->type, coap_req->code, coap_req->mid, accept)); + PRINTF("XML\n"); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/xml"; + REST.set_response_payload(response, msg, strlen(msg)); + PRINTF("ERROR\n"); + } +} diff --git a/examples/er-rest-example/resources/res-plugtest-obs.c b/examples/er-rest-example/resources/res-plugtest-obs.c new file mode 100644 index 000000000..e202c2043 --- /dev/null +++ b/examples/er-rest-example/resources/res-plugtest-obs.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-coap-observe.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_periodic_handler(void); + +PERIODIC_RESOURCE(res_plugtest_obs, + "title=\"Observable resource which changes every 5 seconds\";obs", + res_get_handler, + NULL, + res_put_handler, + res_delete_handler, + 5 * CLOCK_SECOND, + res_periodic_handler); + +static int32_t obs_counter = 0; +static char obs_content[MAX_PLUGFEST_BODY]; +static size_t obs_content_len = 0; +static unsigned int obs_format = 0; + +static char obs_status = 0; + +static void +obs_purge_list() +{ + PRINTF("### SERVER ACTION ### Purging obs list"); + coap_remove_observer_by_uri(NULL, 0, res_plugtest_obs.url); +} +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* Keep server log clean from ticking events */ + if(request != NULL) { + PRINTF("/obs GET\n"); + } + REST.set_header_content_type(response, obs_format); + REST.set_header_max_age(response, 5); + + if(obs_content_len) { + REST.set_header_content_type(response, obs_format); + REST.set_response_payload(response, obs_content, obs_content_len); + } else { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, obs_content, + snprintf(obs_content, MAX_PLUGFEST_PAYLOAD, "TICK %lu", obs_counter)); + } + /* A post_handler that handles subscriptions will be called for periodic resources by the REST framework. */ +} +static void +res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + uint8_t *incoming = NULL; + unsigned int ct = -1; + + REST.get_header_content_type(request, &ct); + + PRINTF("/obs PUT\n"); + + if(ct != obs_format) { + obs_status = 1; + obs_format = ct; + } else { + obs_content_len = REST.get_request_payload(request, + (const uint8_t **)&incoming); + memcpy(obs_content, incoming, obs_content_len); + res_periodic_handler(); + } + + REST.set_response_status(response, REST.status.CHANGED); +} +static void +res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + PRINTF("/obs DELETE\n"); + + obs_status = 2; + + REST.set_response_status(response, REST.status.DELETED); +} +/* + * Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE. + * It will be called by the REST manager process with the defined period. + */ +static void +res_periodic_handler() +{ + ++obs_counter; + + /* PRINTF("TICK %u for /%s\n", obs_counter, r->url); */ + + if(obs_status == 1) { + + /* Notify the registered observers with the given message type, observe option, and payload. */ + REST.notify_subscribers(&res_plugtest_obs); + + PRINTF("######### sending 5.00\n"); + + obs_purge_list(); + } else if(obs_status == 2) { + + /* Notify the registered observers with the given message type, observe option, and payload. */ + REST.notify_subscribers(&res_plugtest_obs); + + obs_purge_list(); + + obs_counter = 0; + obs_content_len = 0; + } else { + /* Notify the registered observers with the given message type, observe option, and payload. */ + REST.notify_subscribers(&res_plugtest_obs); + } obs_status = 0; +} diff --git a/examples/er-rest-example/resources/res-plugtest-path.c b/examples/er-rest-example/resources/res-plugtest-path.c new file mode 100644 index 000000000..3566a51b9 --- /dev/null +++ b/examples/er-rest-example/resources/res-plugtest-path.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +PARENT_RESOURCE(res_plugtest_path, + "title=\"Path test resource\";ct=\"40\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + + const char *uri_path = NULL; + int len = REST.get_url(request, &uri_path); + int base_len = strlen(res_plugtest_path.url); + + if(len == base_len) { + REST.set_header_content_type(response, REST.type.APPLICATION_LINK_FORMAT); + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, + ",,"); + } else { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "/%.*s", len, uri_path); + } + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); +} diff --git a/examples/er-rest-example/resources/res-plugtest-query.c b/examples/er-rest-example/resources/res-plugtest-query.c new file mode 100644 index 000000000..538646c6e --- /dev/null +++ b/examples/er-rest-example/resources/res-plugtest-query.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_query, + "title=\"Resource accepting query parameters\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + int len = 0; + const char *query = NULL; + + PRINTF( + "/query GET (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + if((len = REST.get_query(request, &query))) { + PRINTF("Query: %.*s\n", len, query); + /* Code 2.05 CONTENT is default. */ + } + REST.set_header_content_type(response, + REST.type.TEXT_PLAIN); + REST.set_response_payload( + response, + buffer, + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, + "Type: %u\nCode: %u\nMID: %u\nQuery: %.*s", coap_req->type, + coap_req->code, coap_req->mid, len, query)); +} diff --git a/examples/er-rest-example/resources/res-plugtest-separate.c b/examples/er-rest-example/resources/res-plugtest-separate.c new file mode 100644 index 000000000..a32311bba --- /dev/null +++ b/examples/er-rest-example/resources/res-plugtest-separate.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-coap-transactions.h" +#include "er-coap-separate.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_resume_handler(void); + +PERIODIC_RESOURCE(res_plugtest_separate, + "title=\"Resource which cannot be served immediately and which cannot be acknowledged in a piggy-backed way\"", + res_get_handler, + NULL, + NULL, + NULL, + 3 * CLOCK_SECOND, + res_resume_handler); + +/* A structure to store the required information */ +typedef struct application_separate_store { + /* Provided by Erbium to store generic request information such as remote address and token. */ + coap_separate_t request_metadata; + /* Add fields for addition information to be stored for finalizing, e.g.: */ + char buffer[MAX_PLUGFEST_PAYLOAD]; +} application_separate_store_t; + +static uint8_t separate_active = 0; +static application_separate_store_t separate_store[1]; + +void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + PRINTF("/separate "); + if(separate_active) { + PRINTF("REJECTED "); + coap_separate_reject(); + } else { + PRINTF("STORED "); + separate_active = 1; + + /* Take over and skip response by engine. */ + coap_separate_accept(request, &separate_store->request_metadata); + /* Be aware to respect the Block2 option, which is also stored in the coap_separate_t. */ + + snprintf(separate_store->buffer, MAX_PLUGFEST_PAYLOAD, + "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, + coap_req->mid); + } + + PRINTF("(%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); +} +static void +res_resume_handler() +{ + if(separate_active) { + PRINTF("/separate "); + coap_transaction_t *transaction = NULL; + if((transaction = coap_new_transaction(separate_store->request_metadata.mid, + &separate_store->request_metadata.addr, + separate_store->request_metadata.port))) { + PRINTF( + "RESPONSE (%s %u)\n", separate_store->request_metadata.type == COAP_TYPE_CON ? "CON" : "NON", separate_store->request_metadata.mid); + + coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */ + + /* Restore the request information for the response. */ + coap_separate_resume(response, &separate_store->request_metadata, CONTENT_2_05); + + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + coap_set_payload(response, separate_store->buffer, + strlen(separate_store->buffer)); + + /* + * Be aware to respect the Block2 option, which is also stored in the coap_separate_t. + * As it is a critical option, this example resource pretends to handle it for compliance. + */ + coap_set_header_block2(response, + separate_store->request_metadata.block2_num, 0, + separate_store->request_metadata.block2_size); + + /* Warning: No check for serialization error. */ + transaction->packet_len = coap_serialize_message(response, + transaction->packet); + coap_send_transaction(transaction); + /* The engine will clear the transaction (right after send for NON, after acked for CON). */ + + separate_active = 0; + } else { + PRINTF("ERROR (transaction)\n"); + } + } /* if (separate_active) */ +} diff --git a/examples/er-rest-example/resources/res-plugtest-test.c b/examples/er-rest-example/resources/res-plugtest-test.c new file mode 100644 index 000000000..27bba1f3b --- /dev/null +++ b/examples/er-rest-example/resources/res-plugtest-test.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_test, "title=\"Default test resource\"", res_get_handler, res_post_handler, res_put_handler, res_delete_handler); + +static uint8_t test_etag[8] = { 0 }; +static uint8_t test_etag_len = 1; +static uint8_t test_change = 1; +static uint8_t test_none_match_okay = 1; + +static const uint8_t *bytes = NULL; +static size_t len = 0; + +static void +test_update_etag() +{ + int i; + test_etag_len = (random_rand() % 8) + 1; + for(i = 0; i < test_etag_len; ++i) { + test_etag[i] = random_rand(); + } + test_change = 0; + + PRINTF("### SERVER ACTION ### Changed ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", test_etag_len, test_etag[0], test_etag[1], test_etag[2], test_etag[3], test_etag[4], test_etag[5], test_etag[6], test_etag[7]); +} +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + if(test_change) { + test_update_etag(); + } + PRINTF("/test GET (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + if((len = coap_get_header_etag(request, &bytes)) > 0 + && len == test_etag_len + && memcmp(test_etag, bytes, len) == 0) { + PRINTF("validate "); + REST.set_response_status(response, REST.status.NOT_MODIFIED); + REST.set_header_etag(response, test_etag, test_etag_len); + + test_change = 1; + PRINTF("### SERVER ACTION ### Resource will change\n"); + } else { + /* Code 2.05 CONTENT is default. */ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_header_etag(response, test_etag, test_etag_len); + REST.set_header_max_age(response, 30); + REST.set_response_payload( + response, + buffer, + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); + } +} +static void +res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + PRINTF("/test POST (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + REST.set_response_status(response, REST.status.CREATED); + REST.set_header_location(response, "/location1/location2/location3"); +} +static void +res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + PRINTF("/test PUT (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + if(coap_get_header_if_none_match(request)) { + if(test_none_match_okay) { + REST.set_response_status(response, REST.status.CREATED); + + test_none_match_okay = 0; + PRINTF("### SERVER ACTION ### If-None-Match will FAIL\n"); + } else { + REST.set_response_status(response, PRECONDITION_FAILED_4_12); + + test_none_match_okay = 1; + PRINTF("### SERVER ACTION ### If-None-Match will SUCCEED\n"); + } + } else if(((len = coap_get_header_if_match(request, &bytes)) > 0 + && (len == test_etag_len + && memcmp(test_etag, bytes, len) == 0)) + || len == 0) { + test_update_etag(); + REST.set_header_etag(response, test_etag, test_etag_len); + + REST.set_response_status(response, REST.status.CHANGED); + + if(len > 0) { + test_change = 1; + PRINTF("### SERVER ACTION ### Resource will change\n"); + } + } else { + PRINTF("Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", + len, + test_etag_len, + bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], + test_etag[0], test_etag[1], test_etag[2], test_etag[3], test_etag[4], test_etag[5], test_etag[6], test_etag[7]); + + REST.set_response_status(response, PRECONDITION_FAILED_4_12); + } +} +static void +res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + PRINTF("/test DELETE (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + REST.set_response_status(response, REST.status.DELETED); +} diff --git a/examples/er-rest-example/resources/res-plugtest-validate.c b/examples/er-rest-example/resources/res-plugtest-validate.c new file mode 100644 index 000000000..b92ffe74d --- /dev/null +++ b/examples/er-rest-example/resources/res-plugtest-validate.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_validate, + "title=\"Validation test resource\"", + res_get_handler, + NULL, + res_put_handler, + NULL); + +static uint8_t validate_etag[8] = { 0 }; +static uint8_t validate_etag_len = 1; +static uint8_t validate_change = 1; + +static const uint8_t *bytes = NULL; +static size_t len = 0; + +static void +validate_update_etag() +{ + int i; + validate_etag_len = (random_rand() % 8) + 1; + for(i = 0; i < validate_etag_len; ++i) { + validate_etag[i] = random_rand(); + } + validate_change = 0; + + PRINTF("### SERVER ACTION ### Changed ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", + validate_etag_len, validate_etag[0], validate_etag[1], validate_etag[2], validate_etag[3], validate_etag[4], validate_etag[5], validate_etag[6], validate_etag[7]); +} +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + if(validate_change) { + validate_update_etag(); + } + PRINTF("/validate GET"); + PRINTF("(%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + if((len = coap_get_header_etag(request, &bytes)) > 0 + && len == validate_etag_len && memcmp(validate_etag, bytes, len) == 0) { + PRINTF("validate "); + REST.set_response_status(response, REST.status.NOT_MODIFIED); + REST.set_header_etag(response, validate_etag, validate_etag_len); + + validate_change = 1; + PRINTF("### SERVER ACTION ### Resouce will change\n"); + } else { + /* Code 2.05 CONTENT is default. */ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_header_etag(response, validate_etag, validate_etag_len); + REST.set_header_max_age(response, 30); + REST.set_response_payload( + response, + buffer, + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, + "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, + coap_req->mid)); + } +} +static void +res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + PRINTF("/validate PUT "); + PRINTF("(%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + if(((len = coap_get_header_if_match(request, &bytes)) > 0 + && (len == validate_etag_len + && memcmp(validate_etag, bytes, len) == 0)) + || len == 0) { + validate_update_etag(); + REST.set_header_etag(response, validate_etag, validate_etag_len); + + REST.set_response_status(response, REST.status.CHANGED); + + if(len > 0) { + validate_change = 1; + PRINTF("### SERVER ACTION ### Resouce will change\n"); + } + } else { + PRINTF( + "Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X] ", + len, + validate_etag_len, + bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], + validate_etag[0], validate_etag[1], validate_etag[2], validate_etag[3], validate_etag[4], validate_etag[5], validate_etag[6], validate_etag[7]); + + REST.set_response_status(response, PRECONDITION_FAILED_4_12); + } +} diff --git a/examples/er-rest-example/resources/res-push.c b/examples/er-rest-example/resources/res-push.c new file mode 100644 index 000000000..c169b407c --- /dev/null +++ b/examples/er-rest-example/resources/res-push.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_periodic_handler(void); + +PERIODIC_RESOURCE(res_push, + "title=\"Periodic demo\";obs", + res_get_handler, + NULL, + NULL, + NULL, + 5 * CLOCK_SECOND, + res_periodic_handler); + +/* + * Use local resource state that is accessed by res_get_handler() and altered by res_periodic_handler() or PUT or POST. + */ +static int32_t event_counter = 0; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* + * For minimal complexity, request query and options should be ignored for GET on observable resources. + * Otherwise the requests must be stored with the observer list and passed by REST.notify_subscribers(). + * This would be a TODO in the corresponding files in contiki/apps/erbium/! + */ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_header_max_age(response, res_push.periodic->period / CLOCK_SECOND); + REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "VERY LONG EVENT %lu", event_counter)); + + /* The REST.subscription_handler() will be called for observable resources by the REST framework. */ +} +/* + * Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE. + * It will be called by the REST manager process with the defined period. + */ +static void +res_periodic_handler() +{ + /* Do a periodic task here, e.g., sampling a sensor. */ + ++event_counter; + + /* Usually a condition is defined under with subscribers are notified, e.g., large enough delta in sensor reading. */ + if(1) { + /* Notify the registered observers which will trigger the res_get_handler to create the response. */ + REST.notify_subscribers(&res_push); + } +} diff --git a/examples/er-rest-example/resources/res-radio.c b/examples/er-rest-example/resources/res-radio.c new file mode 100644 index 000000000..ac09319a3 --- /dev/null +++ b/examples/er-rest-example/resources/res-radio.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include "contiki.h" + +#if PLATFORM_HAS_RADIO + +#include +#include "rest-engine.h" +#include "dev/radio-sensor.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading of the rssi/lqi from radio sensor */ +RESOURCE(res_radio, + "title=\"RADIO: ?p=lqi|rssi\";rt=\"RadioSensor\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + size_t len = 0; + const char *p = NULL; + uint8_t param = 0; + int success = 1; + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if((len = REST.get_query_variable(request, "p", &p))) { + if(strncmp(p, "lqi", len) == 0) { + param = RADIO_SENSOR_LAST_VALUE; + } else if(strncmp(p, "rssi", len) == 0) { + param = RADIO_SENSOR_LAST_PACKET; + } else { + success = 0; + } + } else { + success = 0; + } if(success) { + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", radio_sensor.value(param)); + + REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + + if(param == RADIO_SENSOR_LAST_VALUE) { + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'lqi':%d}", radio_sensor.value(param)); + } else if(param == RADIO_SENSOR_LAST_PACKET) { + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'rssi':%d}", radio_sensor.value(param)); + } + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } + } else { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} +#endif /* PLATFORM_HAS_RADIO */ diff --git a/examples/er-rest-example/resources/res-separate.c b/examples/er-rest-example/resources/res-separate.c new file mode 100644 index 000000000..bb2248c92 --- /dev/null +++ b/examples/er-rest-example/resources/res-separate.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap-separate.h" +#include "er-coap-transactions.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_resume_handler(void); + +SEPARATE_RESOURCE(res_separate, + "title=\"Separate demo\"", + res_get_handler, + NULL, + NULL, + NULL, + res_resume_handler); + +/* A structure to store the information required for the separate handler */ +typedef struct application_separate_store { + + /* Provided by Erbium to store generic request information such as remote address and token. */ + coap_separate_t request_metadata; + + /* Add fields for addition information to be stored for finalizing, e.g.: */ + char buffer[16]; +} application_separate_store_t; + +#define COAP_MAX_OPEN_SEPARATE 2 + +static uint8_t separate_active = 0; +static application_separate_store_t separate_store[COAP_MAX_OPEN_SEPARATE]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* + * Example allows only one open separate response. + * For multiple, the application must manage the list of stores. + */ + if(separate_active >= COAP_MAX_OPEN_SEPARATE) { + coap_separate_reject(); + } else { + ++separate_active; + + /* Take over and skip response by engine. */ + coap_separate_accept(request, &separate_store->request_metadata); + /* Be aware to respect the Block2 option, which is also stored in the coap_separate_t. */ + + /* + * At the moment, only the minimal information is stored in the store (client address, port, token, MID, type, and Block2). + * Extend the store, if the application requires additional information from this handler. + * buffer is an example field for custom information. + */ + snprintf(separate_store->buffer, sizeof(separate_store->buffer), "StoredInfo"); + } +} +static void +res_resume_handler() +{ + if(separate_active) { + coap_transaction_t *transaction = NULL; + if((transaction = coap_new_transaction(separate_store->request_metadata.mid, &separate_store->request_metadata.addr, separate_store->request_metadata.port))) { + coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */ + + /* Restore the request information for the response. */ + coap_separate_resume(response, &separate_store->request_metadata, REST.status.OK); + + coap_set_payload(response, separate_store->buffer, strlen(separate_store->buffer)); + + /* + * Be aware to respect the Block2 option, which is also stored in the coap_separate_t. + * As it is a critical option, this example resource pretends to handle it for compliance. + */ + coap_set_header_block2(response, separate_store->request_metadata.block2_num, 0, separate_store->request_metadata.block2_size); + + /* Warning: No check for serialization error. */ + transaction->packet_len = coap_serialize_message(response, transaction->packet); + coap_send_transaction(transaction); + /* The engine will clear the transaction (right after send for NON, after acked for CON). */ + + /* FIXME there could me more! */ + separate_active = 0; + } else { + /* + * Set timer for retry, send error message, ... + * The example simply waits for another button press. + */ + } + } /* if (separate_active) */ +} diff --git a/examples/er-rest-example/resources/res-sht11.c b/examples/er-rest-example/resources/res-sht11.c new file mode 100644 index 000000000..56ed86c01 --- /dev/null +++ b/examples/er-rest-example/resources/res-sht11.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2014, Nimbus Centre for Embedded Systems Research, Cork Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * SHT11 Sensor Resource + * + * This is a simple GET resource that returns the temperature in Celsius + * and the humidity reading from the SHT11. + * \author + * Pablo Corbalan + */ + +#include "contiki.h" + +#if PLATFORM_HAS_SHT11 + +#include +#include "rest-engine.h" +#include "dev/sht11/sht11-sensor.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* Get Method Example. Returns the reading from temperature and humidity sensors. */ +RESOURCE(res_sht11, + "title=\"Temperature and Humidity\";rt=\"Sht11\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* Temperature in Celsius (t in 14 bits resolution at 3 Volts) + * T = -39.60 + 0.01*t + */ + uint16_t temperature = ((sht11_sensor.value(SHT11_SENSOR_TEMP) / 10) - 396) / 10; + /* Relative Humidity in percent (h in 12 bits resolution) + * RH = -4 + 0.0405*h - 2.8e-6*(h*h) + */ + uint16_t rh = sht11_sensor.value(SHT11_SENSOR_HUMIDITY); + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%u;%u", temperature, rh); + + REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_XML) { + REST.set_header_content_type(response, REST.type.APPLICATION_XML); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "", temperature, rh); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'Sht11':{'Temperature':%u,'Humidity':%u}}", temperature, rh); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain, application/xml, and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} +#endif /* PLATFORM_HAS_SHT11 */ diff --git a/examples/er-rest-example/resources/res-sub.c b/examples/er-rest-example/resources/res-sub.c new file mode 100644 index 000000000..1d6f17aeb --- /dev/null +++ b/examples/er-rest-example/resources/res-sub.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* + * Example for a resource that also handles all its sub-resources. + * Use REST.get_url() to multiplex the handling of the request depending on the Uri-Path. + */ +PARENT_RESOURCE(res_sub, + "title=\"Sub-resource demo\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + + const char *uri_path = NULL; + int len = REST.get_url(request, &uri_path); + int base_len = strlen(res_sub.url); + + if(len == base_len) { + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "Request any sub-resource of /%s", res_sub.url); + } else { + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, ".%.*s", len - base_len, uri_path + base_len); + } REST.set_response_payload(response, buffer, strlen((char *)buffer)); +} diff --git a/examples/er-rest-example/resources/res-temperature.c b/examples/er-rest-example/resources/res-temperature.c new file mode 100644 index 000000000..c8bce8ba8 --- /dev/null +++ b/examples/er-rest-example/resources/res-temperature.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example of an observable "on-change" temperature resource + * \author + * Matthias Kovatsch + * \author + * Cristiano De Alti + */ + +#include "contiki.h" + +#if PLATFORM_HAS_TEMPERATURE + +#include +#include +#include +#include "rest-engine.h" +#include "dev/temperature-sensor.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_periodic_handler(void); + +#define MAX_AGE 60 +#define INTERVAL_MIN 5 +#define INTERVAL_MAX (MAX_AGE - 1) +#define CHANGE 1 + +static int32_t interval_counter = INTERVAL_MIN; +static int temperature_old = INT_MIN; + +PERIODIC_RESOURCE(res_temperature, + "title=\"Temperature\";rt=\"Temperature\";obs", + res_get_handler, + NULL, + NULL, + NULL, + CLOCK_SECOND, + res_periodic_handler); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* + * For minimal complexity, request query and options should be ignored for GET on observable resources. + * Otherwise the requests must be stored with the observer list and passed by REST.notify_subscribers(). + * This would be a TODO in the corresponding files in contiki/apps/erbium/! + */ + + int temperature = temperature_sensor.value(0); + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", temperature); + + REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%d}", temperature); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } + + REST.set_header_max_age(response, MAX_AGE); + + /* The REST.subscription_handler() will be called for observable resources by the REST framework. */ +} + +/* + * Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE. + * It will be called by the REST manager process with the defined period. + */ +static void +res_periodic_handler() +{ + int temperature = temperature_sensor.value(0); + + ++interval_counter; + + if((abs(temperature - temperature_old) >= CHANGE && interval_counter >= INTERVAL_MIN) || + interval_counter >= INTERVAL_MAX) { + interval_counter = 0; + temperature_old = temperature; + /* Notify the registered observers which will trigger the res_get_handler to create the response. */ + REST.notify_subscribers(&res_temperature); + } +} +#endif /* PLATFORM_HAS_TEMPERATURE */ diff --git a/apps/er-coap-07/er-coap-07-separate.h b/examples/er-rest-example/resources/res-toggle.c similarity index 68% rename from apps/er-coap-07/er-coap-07-separate.h rename to examples/er-rest-example/resources/res-toggle.c index 896485d42..d8a773306 100644 --- a/apps/er-coap-07/er-coap-07-separate.h +++ b/examples/er-rest-example/resources/res-toggle.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,36 +31,33 @@ /** * \file - * CoAP module for separate responses + * Example resource * \author * Matthias Kovatsch */ -#ifndef COAP_SEPARATE_H_ -#define COAP_SEPARATE_H_ +#include "contiki.h" -#include "er-coap-07.h" +#if PLATFORM_HAS_LEDS -typedef struct coap_separate { +#include +#include "contiki.h" +#include "rest-engine.h" +#include "dev/leds.h" - uip_ipaddr_t addr; - uint16_t port; +static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); - coap_message_type_t type; - uint16_t mid; +/* A simple actuator example. Toggles the red led */ +RESOURCE(res_toggle, + "title=\"Red LED\";rt=\"Control\"", + NULL, + res_post_handler, + NULL, + NULL); - uint8_t token_len; - uint8_t token[COAP_TOKEN_LEN]; - - /* separate + blockwise is untested! */ - uint32_t block2_num; - uint16_t block2_size; - -} coap_separate_t; - -int coap_separate_handler(resource_t *resource, void *request, void *response); -void coap_separate_reject(); -int coap_separate_accept(void *request, coap_separate_t *separate_store); -void coap_separate_resume(void *response, coap_separate_t *separate_store, uint8_t code); - -#endif /* COAP_SEPARATE_H_ */ +static void +res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + leds_toggle(LEDS_RED); +} +#endif /* PLATFORM_HAS_LEDS */ diff --git a/examples/er-rest-example/server-client-native.csc b/examples/er-rest-example/server-client-native.csc new file mode 100644 index 000000000..12162c689 --- /dev/null +++ b/examples/er-rest-example/server-client-native.csc @@ -0,0 +1,231 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + REST with RPL router + 1.0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + slipradio + Sky SLIP radio + [CONTIKI_DIR]/examples/ipv6/slip-radio/slip-radio.c + make slip-radio.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/slip-radio/slip-radio.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + client + Erbium Client + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c + make er-example-client.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 30.303994886410642 + 17.22128424003353 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + slipradio + + + + + org.contikios.cooja.interfaces.Position + 46.57186415376375 + 37.25589203828498 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + + org.contikios.cooja.interfaces.Position + 18.194682268367348 + 50.210548118402656 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + client + + + + org.contikios.cooja.plugins.SimControl + 259 + 0 + 179 + 1 + 2 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + org.contikios.cooja.plugins.skins.LEDVisualizerSkin + org.contikios.cooja.plugins.skins.AddressVisualizerSkin + 2.255467003316979 0.0 0.0 2.255467003316979 59.30641698643764 -13.478401994502008 + + 300 + 2 + 178 + 262 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 762 + 4 + 491 + 2 + 182 + + + org.contikios.cooja.plugins.RadioLogger + + 150 + + false + false + + + 451 + -1 + 305 + 73 + 140 + true + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + + + + + 25.49079397896416 + + 1624 + 5 + 252 + 6 + 712 + + + org.contikios.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 853 + 3 + 491 + 765 + 182 + + + org.contikios.cooja.serialsocket.SerialSocketServer + 0 + 422 + 1 + 82 + 606 + 51 + + + diff --git a/examples/rest-example/rest-server-example.csc b/examples/er-rest-example/server-client-observe.csc similarity index 58% rename from examples/rest-example/rest-server-example.csc rename to examples/er-rest-example/server-client-observe.csc index 31b45e4ef..5d006056a 100644 --- a/examples/rest-example/rest-server-example.csc +++ b/examples/er-rest-example/server-client-observe.csc @@ -1,185 +1,203 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - - REST with RPL router - -2147483648 - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - skyweb - Rest - [CONTIKI_DIR]/examples/rest-example/rest-server-example.c - make rest-server-example.sky TARGET=sky - [CONTIKI_DIR]/examples/rest-example/rest-server-example.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - org.contikios.cooja.interfaces.Position - 62.239287566073514 - 34.43810269527116 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - skyweb - - - - - org.contikios.cooja.interfaces.Position - 47.68359039801751 - 47.26544238238854 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - skyweb - - - - org.contikios.cooja.plugins.SimControl - 259 - 1 - 179 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - org.contikios.cooja.plugins.skins.AttributeVisualizerSkin - 10.505309204322225 0.0 0.0 10.505309204322225 -249.89475921566975 -141.01191150973983 - - 819 - 5 - 563 - 35 - 306 - - - org.contikios.cooja.plugins.LogListener - - - - 762 - 0 - 326 - 36 - 296 - - - org.contikios.cooja.plugins.RadioLogger - - 150 - - - 815 - 4 - 385 - 255 - 8 - - - SerialSocketServer - 0 - 422 - 3 - 74 - 1234 - 93 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - - - - - 125 - 25.49079397896416 - - 1624 - 2 - 252 - 166 - 699 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + REST with RPL router + 1.0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + client + Erbium Client + [CONTIKI_DIR]/examples/er-rest-example/er-example-observe-client.c + make er-example-observe-client.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-observe-client.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + org.contikios.cooja.interfaces.Position + 54.537149936813485 + 51.51086225537906 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + + org.contikios.cooja.interfaces.Position + 77.97942851220571 + 67.86182390447284 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + client + + + + org.contikios.cooja.plugins.SimControl + 259 + 3 + 179 + 2 + 1 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + org.contikios.cooja.plugins.skins.LEDVisualizerSkin + org.contikios.cooja.plugins.skins.AddressVisualizerSkin + 2.092412892721766 0.0 0.0 2.092412892721766 34.70057915472623 -45.606066372444175 + + 300 + 4 + 178 + 261 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 762 + 0 + 491 + 2 + 182 + + + org.contikios.cooja.plugins.RadioLogger + + 167 + + false + false + + + 560 + 1 + 492 + 764 + 181 + + + org.contikios.cooja.serialsocket.SerialSocketServer + 0 + + 60001 + true + + 362 + 2 + 116 + 561 + 1 + + + diff --git a/examples/er-rest-example/server-client.csc b/examples/er-rest-example/server-client.csc index b655fcbc9..adc621a39 100644 --- a/examples/er-rest-example/server-client.csc +++ b/examples/er-rest-example/server-client.csc @@ -1,227 +1,231 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - REST with RPL router - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - client - Erbium Client - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c - make er-example-client.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - org.contikios.cooja.interfaces.Position - 46.57186415376375 - 40.35946215910942 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - - org.contikios.cooja.interfaces.Position - 18.638049428485125 - 47.55034515769599 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - client - - - - org.contikios.cooja.plugins.SimControl - 259 - 0 - 179 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - org.contikios.cooja.plugins.skins.AttributeVisualizerSkin - org.contikios.cooja.plugins.skins.LEDVisualizerSkin - org.contikios.cooja.plugins.skins.AddressVisualizerSkin - 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 - - 300 - 2 - 178 - 261 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - 762 - 3 - 491 - 2 - 182 - - - org.contikios.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 4 - 74 - 578 - 18 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - 2 - - - - - 125 - 25.49079397896416 - - 1624 - 5 - 252 - 6 - 712 - - - org.contikios.cooja.plugins.MoteInterfaceViewer - 2 - - Serial port - 0,0 - - 853 - 1 - 491 - 765 - 182 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + REST with RPL router + 1.0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + client + Erbium Client + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c + make er-example-client.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + org.contikios.cooja.interfaces.Position + 46.57186415376375 + 40.35946215910942 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + + org.contikios.cooja.interfaces.Position + 18.638049428485125 + 47.55034515769599 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + client + + + + org.contikios.cooja.plugins.SimControl + 259 + 0 + 179 + 2 + 1 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + org.contikios.cooja.plugins.skins.LEDVisualizerSkin + org.contikios.cooja.plugins.skins.AddressVisualizerSkin + 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 + + 300 + 2 + 178 + 261 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 762 + 3 + 491 + 2 + 182 + + + org.contikios.cooja.plugins.RadioLogger + + 150 + + false + false + + + 451 + -1 + 305 + 73 + 140 + true + + + org.contikios.cooja.serialsocket.SerialSocketServer + 0 + 422 + 4 + 74 + 578 + 18 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + + + + + 25.49079397896416 + + 1624 + 5 + 252 + 6 + 712 + + + org.contikios.cooja.plugins.MoteInterfaceViewer + 2 + + Serial port + 0,0 + + 853 + 1 + 491 + 765 + 182 + + + diff --git a/examples/er-rest-example/server-only.csc b/examples/er-rest-example/server-only.csc index 97cb8ffb5..9bbea40bd 100644 --- a/examples/er-rest-example/server-only.csc +++ b/examples/er-rest-example/server-only.csc @@ -1,189 +1,193 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - REST with RPL router - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - org.contikios.cooja.interfaces.Position - 35.100895239785295 - 39.70574552287428 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - org.contikios.cooja.plugins.SimControl - 259 - 0 - 179 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - org.contikios.cooja.plugins.skins.AttributeVisualizerSkin - org.contikios.cooja.plugins.skins.LEDVisualizerSkin - org.contikios.cooja.plugins.skins.AddressVisualizerSkin - 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 - - 300 - 5 - 175 - 263 - 3 - - - org.contikios.cooja.plugins.LogListener - - - - - 560 - 2 - 326 - 1 - 293 - - - org.contikios.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 3 - 74 - 39 - 199 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - - - - - 125 - 25.49079397896416 - - 1624 - 4 - 252 - 4 - 622 - - - org.contikios.cooja.plugins.MoteInterfaceViewer - 1 - - Serial port - 0,0 - - 702 - 1 - 646 - 564 - 2 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + REST with RPL router + 1.0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + org.contikios.cooja.interfaces.Position + 35.100895239785295 + 39.70574552287428 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + org.contikios.cooja.plugins.SimControl + 259 + 0 + 179 + 2 + 1 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + org.contikios.cooja.plugins.skins.LEDVisualizerSkin + org.contikios.cooja.plugins.skins.AddressVisualizerSkin + 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 + + 300 + 1 + 175 + 262 + 2 + + + org.contikios.cooja.plugins.LogListener + + + + + + 560 + 3 + 326 + 1 + 293 + + + org.contikios.cooja.plugins.RadioLogger + + 150 + + false + false + + + 451 + -1 + 305 + 73 + 140 + true + + + org.contikios.cooja.serialsocket.SerialSocketServer + 0 + 422 + 4 + 74 + 39 + 199 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + + + + + 25.49079397896416 + + 1624 + 5 + 252 + 4 + 622 + + + org.contikios.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 702 + 2 + 646 + 564 + 2 + + + diff --git a/examples/example-shell/Makefile b/examples/example-shell/Makefile index eaf62548f..9849e6092 100644 --- a/examples/example-shell/Makefile +++ b/examples/example-shell/Makefile @@ -3,5 +3,6 @@ all: $(CONTIKI_PROJECT) APPS = serial-shell CONTIKI = ../.. - +CONTIKI_WITH_RIME = 1 +CONTIKI_WITH_IPV4 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/example-shell/example-shell.c b/examples/example-shell/example-shell.c index 24b7c2a05..a8c7c74b6 100644 --- a/examples/example-shell/example-shell.c +++ b/examples/example-shell/example-shell.c @@ -66,7 +66,6 @@ PROCESS_THREAD(example_shell_process, ev, data) shell_file_init(); shell_httpd_init(); shell_irc_init(); - shell_netfile_init(); /*shell_ping_init();*/ /* uIP ping */ shell_power_init(); /*shell_profile_init();*/ diff --git a/examples/extended-rf-api/Makefile b/examples/extended-rf-api/Makefile new file mode 100644 index 000000000..b18e4b642 --- /dev/null +++ b/examples/extended-rf-api/Makefile @@ -0,0 +1,9 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" + +CONTIKI_PROJECT = extended-rf-api + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../.. +CONTIKI_WITH_RIME = 1 +include $(CONTIKI)/Makefile.include diff --git a/examples/extended-rf-api/extended-rf-api.c b/examples/extended-rf-api/extended-rf-api.c new file mode 100644 index 000000000..d02fe5546 --- /dev/null +++ b/examples/extended-rf-api/extended-rf-api.c @@ -0,0 +1,510 @@ +/* + * Copyright (c) 2014, George Oikonomou (george@contiki-os.org) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/** + * Example project demonstrating the extended RF API functionality + */ +#include "contiki.h" +#include "net/netstack.h" +#include "dev/radio.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +struct rf_consts { + radio_value_t channel_min; + radio_value_t channel_max; + radio_value_t txpower_min; + radio_value_t txpower_max; +}; + +static struct rf_consts consts; + +static radio_value_t value; +static uint8_t ext_addr[8]; +/*---------------------------------------------------------------------------*/ +PROCESS(extended_rf_api_process, "Extended RF API demo process"); +AUTOSTART_PROCESSES(&extended_rf_api_process); +/*---------------------------------------------------------------------------*/ +static void +print_64bit_addr(const uint8_t *addr) +{ + unsigned int i; + for(i = 0; i < 7; i++) { + printf("%02x:", addr[i]); + } + printf("%02x (network order)\n", addr[7]); +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + radio_result_t rv; + + rv = NETSTACK_RADIO.get_object(param, dest, size); + + switch(rv) { + case RADIO_RESULT_ERROR: + printf("Radio returned an error\n"); + break; + case RADIO_RESULT_INVALID_VALUE: + printf("Value is invalid\n"); + break; + case RADIO_RESULT_NOT_SUPPORTED: + printf("Param %u not supported\n", param); + break; + case RADIO_RESULT_OK: + break; + default: + printf("Unknown return value\n"); + break; + } + + return rv; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_object(radio_param_t param, void *src, size_t size) +{ + radio_result_t rv; + + rv = NETSTACK_RADIO.set_object(param, src, size); + + switch(rv) { + case RADIO_RESULT_ERROR: + printf("Radio returned an error\n"); + break; + case RADIO_RESULT_INVALID_VALUE: + printf("Value is invalid\n"); + break; + case RADIO_RESULT_NOT_SUPPORTED: + printf("Param %u not supported\n", param); + break; + case RADIO_RESULT_OK: + break; + default: + printf("Unknown return value\n"); + break; + } + + return rv; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_param(radio_param_t param, radio_value_t *value) +{ + radio_result_t rv; + + rv = NETSTACK_RADIO.get_value(param, value); + + switch(rv) { + case RADIO_RESULT_ERROR: + printf("Radio returned an error\n"); + break; + case RADIO_RESULT_INVALID_VALUE: + printf("Value %d is invalid\n", *value); + break; + case RADIO_RESULT_NOT_SUPPORTED: + printf("Param %u not supported\n", param); + break; + case RADIO_RESULT_OK: + break; + default: + printf("Unknown return value\n"); + break; + } + + return rv; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_param(radio_param_t param, radio_value_t value) +{ + radio_result_t rv; + + rv = NETSTACK_RADIO.set_value(param, value); + + switch(rv) { + case RADIO_RESULT_ERROR: + printf("Radio returned an error\n"); + break; + case RADIO_RESULT_INVALID_VALUE: + printf("Value %d is invalid\n", value); + break; + case RADIO_RESULT_NOT_SUPPORTED: + printf("Param %u not supported\n", param); + break; + case RADIO_RESULT_OK: + break; + default: + printf("Unknown return value\n"); + break; + } + + return rv; +} +/*---------------------------------------------------------------------------*/ +static void +get_rf_consts(void) +{ + printf("====================================\n"); + printf("RF Constants\n"); + printf("Min Channel : "); + if(get_param(RADIO_CONST_CHANNEL_MIN, &consts.channel_min) == RADIO_RESULT_OK) { + printf("%3d\n", consts.channel_min); + } + + printf("Max Channel : "); + if(get_param(RADIO_CONST_CHANNEL_MAX, &consts.channel_max) == RADIO_RESULT_OK) { + printf("%3d\n", consts.channel_max); + } + + printf("Min TX Power: "); + if(get_param(RADIO_CONST_TXPOWER_MIN, &consts.txpower_min) == RADIO_RESULT_OK) { + printf("%3d dBm\n", consts.txpower_min); + } + + printf("Max TX Power: "); + if(get_param(RADIO_CONST_TXPOWER_MAX, &consts.txpower_max) == RADIO_RESULT_OK) { + printf("%3d dBm\n", consts.txpower_max); + } +} +/*---------------------------------------------------------------------------*/ +static void +test_off_on(void) +{ + printf("====================================\n"); + printf("Power mode Test: Off, then On\n"); + + printf("Power mode is : "); + if(get_param(RADIO_PARAM_POWER_MODE, &value) == RADIO_RESULT_OK) { + if(value == RADIO_POWER_MODE_ON) { + printf("On\n"); + } else if(value == RADIO_POWER_MODE_OFF) { + printf("Off\n"); + } + } + + printf("Turning Off : "); + value = RADIO_POWER_MODE_OFF; + set_param(RADIO_PARAM_POWER_MODE, value); + if(get_param(RADIO_PARAM_POWER_MODE, &value) == RADIO_RESULT_OK) { + if(value == RADIO_POWER_MODE_ON) { + printf("On\n"); + } else if(value == RADIO_POWER_MODE_OFF) { + printf("Off\n"); + } + } + + printf("Turning On : "); + value = RADIO_POWER_MODE_ON; + set_param(RADIO_PARAM_POWER_MODE, value); + if(get_param(RADIO_PARAM_POWER_MODE, &value) == RADIO_RESULT_OK) { + if(value == RADIO_POWER_MODE_ON) { + printf("On\n"); + } else if(value == RADIO_POWER_MODE_OFF) { + printf("Off\n"); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +test_channels(void) +{ + int i; + + printf("====================================\n"); + printf("Channel Test: [%u , %u]\n", consts.channel_min, consts.channel_max); + + for(i = consts.channel_min; i <= consts.channel_max; i++) { + value = i; + printf("Switch to: %d, Now: ", value); + set_param(RADIO_PARAM_CHANNEL, value); + if(get_param(RADIO_PARAM_CHANNEL, &value) == RADIO_RESULT_OK) { + printf("%d\n", value); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +test_rx_modes(void) +{ + int i; + + printf("====================================\n"); + printf("RX Modes Test: [0 , 3]\n"); + + for(i = 0; i <= 3; i++) { + value = i; + printf("Switch to: %d, Now: ", value); + set_param(RADIO_PARAM_RX_MODE, value); + if(get_param(RADIO_PARAM_RX_MODE, &value) == RADIO_RESULT_OK) { + printf("Address Filtering is "); + if(value & RADIO_RX_MODE_ADDRESS_FILTER) { + printf("On, "); + } else { + printf("Off, "); + } + printf("Auto ACK is "); + if(value & RADIO_RX_MODE_AUTOACK) { + printf("On, "); + } else { + printf("Off, "); + } + + printf("(value=%d)\n", value); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +test_tx_powers(void) +{ + int i; + + printf("====================================\n"); + printf("TX Power Test: [%d , %d]\n", consts.txpower_min, consts.txpower_max); + + for(i = consts.txpower_min; i <= consts.txpower_max; i += 5) { + value = i; + printf("Switch to: %3d dBm, Now: ", value); + set_param(RADIO_PARAM_TXPOWER, value); + if(get_param(RADIO_PARAM_TXPOWER, &value) == RADIO_RESULT_OK) { + printf("%3d dBm\n", value); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +test_cca_thresholds(void) +{ + printf("====================================\n"); + printf("CCA Thres. Test: -105, then -81\n"); + + value = -105; + printf("Switch to: %4d dBm, Now: ", value); + set_param(RADIO_PARAM_CCA_THRESHOLD, value); + if(get_param(RADIO_PARAM_CCA_THRESHOLD, &value) == RADIO_RESULT_OK) { + printf("%4d dBm [0x%04x]\n", value, (uint16_t)value); + } + + value = -81; + printf("Switch to: %4d dBm, Now: ", value); + set_param(RADIO_PARAM_CCA_THRESHOLD, value); + if(get_param(RADIO_PARAM_CCA_THRESHOLD, &value) == RADIO_RESULT_OK) { + printf("%4d dBm [0x%04x]\n", value, (uint16_t)value); + } +} +/*---------------------------------------------------------------------------*/ +static void +test_pan_id(void) +{ + radio_value_t new_val; + + printf("====================================\n"); + printf("PAN ID Test: Flip bytes and back\n"); + + printf("PAN ID is: "); + if(get_param(RADIO_PARAM_PAN_ID, &value) == RADIO_RESULT_OK) { + printf("0x%02x%02x\n", (value >> 8) & 0xFF, value & 0xFF); + } + + new_val = (value >> 8) & 0xFF; + new_val |= (value & 0xFF) << 8; + printf("Switch to: 0x%02x%02x, Now: ", (new_val >> 8) & 0xFF, new_val & 0xFF); + set_param(RADIO_PARAM_PAN_ID, new_val); + if(get_param(RADIO_PARAM_PAN_ID, &value) == RADIO_RESULT_OK) { + printf("0x%02x%02x\n", (value >> 8) & 0xFF, value & 0xFF); + } + + new_val = (value >> 8) & 0xFF; + new_val |= (value & 0xFF) << 8; + printf("Switch to: 0x%02x%02x, Now: ", (new_val >> 8) & 0xFF, new_val & 0xFF); + set_param(RADIO_PARAM_PAN_ID, new_val); + if(get_param(RADIO_PARAM_PAN_ID, &value) == RADIO_RESULT_OK) { + printf("0x%02x%02x\n", (value >> 8) & 0xFF, value & 0xFF); + } +} +/*---------------------------------------------------------------------------*/ +static void +test_16bit_addr(void) +{ + radio_value_t new_val; + + printf("====================================\n"); + printf("16-bit Address Test: Flip bytes and back\n"); + + printf("16-bit Address is: "); + if(get_param(RADIO_PARAM_16BIT_ADDR, &value) == RADIO_RESULT_OK) { + printf("0x%02x%02x\n", (value >> 8) & 0xFF, value & 0xFF); + } + + new_val = (value >> 8) & 0xFF; + new_val |= (value & 0xFF) << 8; + printf("Switch to: 0x%02x%02x, Now: ", (new_val >> 8) & 0xFF, new_val & 0xFF); + set_param(RADIO_PARAM_16BIT_ADDR, new_val); + if(get_param(RADIO_PARAM_16BIT_ADDR, &value) == RADIO_RESULT_OK) { + printf("0x%02x%02x\n", (value >> 8) & 0xFF, value & 0xFF); + } + + new_val = (value >> 8) & 0xFF; + new_val |= (value & 0xFF) << 8; + printf("Switch to: 0x%02x%02x, Now: ", (new_val >> 8) & 0xFF, new_val & 0xFF); + set_param(RADIO_PARAM_16BIT_ADDR, new_val); + if(get_param(RADIO_PARAM_16BIT_ADDR, &value) == RADIO_RESULT_OK) { + printf("0x%02x%02x\n", (value >> 8) & 0xFF, value & 0xFF); + } +} +/*---------------------------------------------------------------------------*/ +static void +test_64bit_addr(void) +{ + int i; + uint8_t new_val[8]; + + printf("====================================\n"); + printf("64-bit Address Test: Invert byte order\n"); + + printf("64-bit Address is: "); + if(get_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8) == RADIO_RESULT_OK) { + print_64bit_addr(ext_addr); + } + + for(i = 0; i <= 7; i++) { + new_val[7 - i] = ext_addr[i]; + } + + printf("Setting to : "); + print_64bit_addr(new_val); + + printf("64-bit Address is: "); + set_object(RADIO_PARAM_64BIT_ADDR, new_val, 8); + if(get_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8) == RADIO_RESULT_OK) { + print_64bit_addr(ext_addr); + } +} +/*---------------------------------------------------------------------------*/ +static void +print_rf_values(void) +{ + printf("====================================\n"); + printf("RF Values\n"); + + printf("Power: "); + if(get_param(RADIO_PARAM_POWER_MODE, &value) == RADIO_RESULT_OK) { + if(value == RADIO_POWER_MODE_ON) { + printf("On\n"); + } else if(value == RADIO_POWER_MODE_OFF) { + printf("Off\n"); + } + } + + printf("Channel: "); + if(get_param(RADIO_PARAM_CHANNEL, &value) == RADIO_RESULT_OK) { + printf("%d\n", value); + } + + printf("PAN ID: "); + if(get_param(RADIO_PARAM_PAN_ID, &value) == RADIO_RESULT_OK) { + printf("0x%02x%02x\n", (value >> 8) & 0xFF, value & 0xFF); + } + + printf("16-bit Address: "); + if(get_param(RADIO_PARAM_16BIT_ADDR, &value) == RADIO_RESULT_OK) { + printf("0x%02x%02x\n", (value >> 8) & 0xFF, value & 0xFF); + } + + printf("64-bit Address: "); + if(get_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8) == RADIO_RESULT_OK) { + print_64bit_addr(ext_addr); + } + + printf("RX Mode: "); + if(get_param(RADIO_PARAM_RX_MODE, &value) == RADIO_RESULT_OK) { + printf("Address Filtering is "); + if(value & RADIO_RX_MODE_ADDRESS_FILTER) { + printf("On, "); + } else { + printf("Off, "); + } + printf("Auto ACK is "); + if(value & RADIO_RX_MODE_AUTOACK) { + printf("On, "); + } else { + printf("Off, "); + } + + printf("(value=%d)\n", value); + } + + printf("TX Mode: "); + if(get_param(RADIO_PARAM_TX_MODE, &value) == RADIO_RESULT_OK) { + printf("%d\n", value); + } + + printf("TX Power: "); + if(get_param(RADIO_PARAM_TXPOWER, &value) == RADIO_RESULT_OK) { + printf("%d dBm [0x%04x]\n", value, (uint16_t)value); + } + + printf("CCA Threshold: "); + if(get_param(RADIO_PARAM_CCA_THRESHOLD, &value) == RADIO_RESULT_OK) { + printf("%d dBm [0x%04x]\n", value, (uint16_t)value); + } + + printf("RSSI: "); + if(get_param(RADIO_PARAM_RSSI, &value) == RADIO_RESULT_OK) { + printf("%d dBm [0x%04x]\n", value, (uint16_t)value); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(extended_rf_api_process, ev, data) +{ + + PROCESS_BEGIN(); + + get_rf_consts(); + print_rf_values(); + + test_off_on(); + test_channels(); + test_rx_modes(); + test_tx_powers(); + test_cca_thresholds(); + test_pan_id(); + test_16bit_addr(); + test_64bit_addr(); + + printf("Done\n"); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/extended-rf-api/project-conf.h b/examples/extended-rf-api/project-conf.h new file mode 100644 index 000000000..2fc561e46 --- /dev/null +++ b/examples/extended-rf-api/project-conf.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014, George Oikonomou (george@contiki-os.org) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nullrdc_driver + +#endif /* PROJECT_CONF_H_ */ diff --git a/examples/ftp/Makefile b/examples/ftp/Makefile index 1504495f4..ff671c9bf 100644 --- a/examples/ftp/Makefile +++ b/examples/ftp/Makefile @@ -4,4 +4,5 @@ all: $(CONTIKI_PROJECT) APPS = ftp CONTIKI = ../.. +CONTIKI_WITH_IPV4 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/ftp/Makefile.apple2enh.defines b/examples/ftp/Makefile.apple2enh.defines deleted file mode 100644 index 5a292701b..000000000 --- a/examples/ftp/Makefile.apple2enh.defines +++ /dev/null @@ -1 +0,0 @@ -DEFINES = WITH_CLIENT,WITH_DNS,WITH_GUI,WITH_MOUSE diff --git a/examples/ftp/Makefile.atarixl.defines b/examples/ftp/Makefile.atarixl.defines deleted file mode 100644 index 5a292701b..000000000 --- a/examples/ftp/Makefile.atarixl.defines +++ /dev/null @@ -1 +0,0 @@ -DEFINES = WITH_CLIENT,WITH_DNS,WITH_GUI,WITH_MOUSE diff --git a/examples/ftp/Makefile.c128.defines b/examples/ftp/Makefile.c128.defines deleted file mode 100644 index 7f438d1d1..000000000 --- a/examples/ftp/Makefile.c128.defines +++ /dev/null @@ -1 +0,0 @@ -DEFINES = WITH_CLIENT,WITH_DNS,WITH_GUI diff --git a/examples/ftp/Makefile.c64.defines b/examples/ftp/Makefile.c64.defines deleted file mode 100644 index 05a72fd5d..000000000 --- a/examples/ftp/Makefile.c64.defines +++ /dev/null @@ -1 +0,0 @@ -DEFINES = WITH_CLIENT,WITH_DNS,WITH_GUI,WITH_MOUSE,WITH_PFS diff --git a/examples/galileo/Makefile b/examples/galileo/Makefile new file mode 100644 index 000000000..0852fe085 --- /dev/null +++ b/examples/galileo/Makefile @@ -0,0 +1,26 @@ +TARGET=galileo + +KNOWN_EXAMPLES = gpio-input gpio-output gpio-interrupt i2c-LSM9DS0 i2c-callbacks print-imr prot-domain-switch-latency + +ifeq ($(filter $(EXAMPLE),$(KNOWN_EXAMPLES)),) + $(info Set the variable EXAMPLE to one of the following Galileo-specific examples:) + $(foreach EXAMPLE,$(KNOWN_EXAMPLES),$(info - $(EXAMPLE))) + $(error Unable to proceed) +endif + +ifeq ($(EXAMPLE),print-imr) + CFLAGS += -DDBG_IMRS +endif + +ifeq ($(EXAMPLE),prot-domain-switch-latency) +ifeq ($(SAMPLE_METADATA),1) +CFLAGS += -DSAMPLE_METADATA=1 +endif +endif + +CONTIKI_PROJECT = $(EXAMPLE) + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/galileo/README.md b/examples/galileo/README.md new file mode 100644 index 000000000..8f3217f05 --- /dev/null +++ b/examples/galileo/README.md @@ -0,0 +1,111 @@ +Galileo Specific Examples +========================= + +This directory contains galileo-specific example applications to illustrate +how to use galileo APIs. + +In order to build a application, you should set the EXAMPLE environment +variable to the name of the application you want to build. For instance, if +you want to build gpio-output application, run the following command: + +``` +$ make TARGET=galileo EXAMPLE=gpio-output +``` + +The corresponding EXAMPLE variable setting for each application is +listed to the right of its heading. + +GPIO +---- + +### GPIO Output (EXAMPLE=gpio-output) + +This application shows how to use the GPIO driver APIs to manipulate output +pins. This application sets the GPIO 5 pin as output pin and toggles its +state at every half second. + +For a visual effect, you should wire shield pin IO2 to a led in a protoboard. +Once the application is running, you should see a blinking LED. + +### GPIO Input (EXAMPLE=gpio-input) + +This application shows how to use the GPIO driver APIs to manipulate +input pins. This application uses default galileo pinmux +initialization and sets the GPIO 5 (shield pin IO2) as output pin and +GPIO 6 (shield pin IO3) as input. A jumper should be used to connect +the two pins. The application toggles the output pin state at every +half second and checks the value on input pin. + +### GPIO Interrupt (EXAMPLE=gpio-interrupt) + +This application shows how to use the GPIO driver APIs to manipulate +interrupt pins. This application uses default galileo pinmux +initialization and sets the GPIO 5 (shield pin IO2) as output pin and +GPIO 6 (shield pin IO3) as interrupt. A jumper should be used to +connect the two pins. It toggles the output pin stat at every half +second in order to emulate an interrupt. This triggers an interrupt +and the application callback is called. You can confirm that though +the UART output. + +I2C +--- + +### I2C LSM9DS0 (EXAMPLE=i2c-LSM9DS0) + +This application shows how to use I2C driver APIs to configure I2C +Master controller and communicate with an LSM9DS0 sensor if one has +been connected as described below. At every 5 seconds, the application +reads the "who am I" register from gyroscope sensor and prints if the +register value matches the expected value described in the spec [1]. + +According to the sensor spec, to read the value in "who am I" register, we +should first perform an i2c write operation to select the register we want +to read from and then we perform the i2c read operation to actually read +the register contents. + +The wiring setup is as follows (left column from Galileo and right column from LSM9DS0): +- 3.3v and Vin +- GND and GND +- GND and SDOG +- 3.3v and CSG +- SDA and SDA +- SCL and SCL + +### I2C Callbacks (EXAMPLE=i2c-callbacks) + +This application is very similar to the previous one in that it also +shows how to use I2C callback functionality, but it can be run without +attaching any additional sensors to the platform since it simply +communicates with a built-in PWM controller. + +Every five seconds, the application reads the current value of the +MODE1 register, which should have previously been initialized to the +value 0x20. The test verifies that this expected value is returned by +the read. + +Isolated Memory Regions +----------------------- + +### Print IMR info (EXAMPLE=print-imr) + +This application prints out information about the configuration of the +Intel Quark X1000 SoC Isolated Memory Regions (IMRs), the Host System +Management Mode Controls register, and the Host Memory I/O Boundary +register. + +Protection Domains +------------------ + +### Protection Domain Switch Latency (EXAMPLE=prot-domain-switch-latency) + +This application measures and prints the average latency of repeatedly +switching from one protection domain to another and back, in ping-pong +fashion. It can optionally perform memory accesses to metadata +associated with the destination protection domain. This feature can +be enabled by specifying SAMPLE_METADATA=1 on the build command line. + +References +---------- + +[1] http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00087365.pdf + diff --git a/examples/galileo/gpio-input.c b/examples/galileo/gpio-input.c new file mode 100644 index 000000000..196ea9193 --- /dev/null +++ b/examples/galileo/gpio-input.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include + +#include "contiki.h" +#include "sys/ctimer.h" + +#include "gpio.h" + +#define PIN_OUTPUT 5 +#define PIN_INPUT 6 + +static uint32_t value; +static struct ctimer timer; + +PROCESS(gpio_input_process, "GPIO Input Process"); +AUTOSTART_PROCESSES(&gpio_input_process); +/*---------------------------------------------------------------------------*/ +static void +timeout(void *data) +{ + uint8_t value_in; + + /* toggle pin state */ + value = !value; + quarkX1000_gpio_write(PIN_OUTPUT, value); + + quarkX1000_gpio_read(PIN_INPUT, &value_in); + + if (value == value_in) + printf("GPIO pin value match!\n"); + else + printf("GPIO pin value DOESN'T match!\n"); + + ctimer_reset(&timer); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(gpio_input_process, ev, data) +{ + PROCESS_BEGIN(); + + quarkX1000_gpio_config(PIN_OUTPUT, QUARKX1000_GPIO_OUT); + quarkX1000_gpio_config(PIN_INPUT, QUARKX1000_GPIO_IN); + + quarkX1000_gpio_clock_enable(); + + ctimer_set(&timer, CLOCK_SECOND / 2, timeout, NULL); + + printf("GPIO input example is running\n"); + PROCESS_YIELD(); + + quarkX1000_gpio_clock_disable(); + + PROCESS_END(); +} diff --git a/examples/galileo/gpio-interrupt.c b/examples/galileo/gpio-interrupt.c new file mode 100644 index 000000000..04fb4cc1b --- /dev/null +++ b/examples/galileo/gpio-interrupt.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include + +#include "contiki.h" +#include "sys/ctimer.h" + +#include "gpio.h" + +#define PIN_OUTPUT 5 +#define PIN_INTR 6 + +static struct ctimer timer; + +PROCESS(gpio_interrupt_process, "GPIO Interrupt Process"); +AUTOSTART_PROCESSES(&gpio_interrupt_process); +/*---------------------------------------------------------------------------*/ +static void +timeout(void *data) +{ + /* emulate an interrupt */ + quarkX1000_gpio_write(PIN_OUTPUT, 0); + quarkX1000_gpio_write(PIN_OUTPUT, 1); + + ctimer_reset(&timer); +} +/*---------------------------------------------------------------------------*/ +static void +callback(uint32_t status) +{ + printf("GPIO interrupt callback called, status: %d\n", status); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(gpio_interrupt_process, ev, data) +{ + PROCESS_BEGIN(); + + quarkX1000_gpio_config(PIN_OUTPUT, QUARKX1000_GPIO_OUT); + quarkX1000_gpio_config(PIN_INTR, QUARKX1000_GPIO_INT | QUARKX1000_GPIO_ACTIVE_HIGH | QUARKX1000_GPIO_EDGE); + + quarkX1000_gpio_set_callback(callback); + + quarkX1000_gpio_clock_enable(); + + ctimer_set(&timer, CLOCK_SECOND / 2, timeout, NULL); + + printf("GPIO interrupt example is running\n"); + PROCESS_YIELD(); + + quarkX1000_gpio_clock_disable(); + + PROCESS_END(); +} diff --git a/examples/galileo/gpio-output.c b/examples/galileo/gpio-output.c new file mode 100644 index 000000000..4dad7d684 --- /dev/null +++ b/examples/galileo/gpio-output.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include + +#include "contiki.h" +#include "sys/ctimer.h" + +#include "gpio.h" + +#define PIN 5 /* IO2 */ + +static uint32_t value; +static struct ctimer timer; + +PROCESS(gpio_output_process, "GPIO Output Process"); +AUTOSTART_PROCESSES(&gpio_output_process); +/*---------------------------------------------------------------------------*/ +static void +timeout(void *data) +{ + /* toggle pin state */ + value = !value; + quarkX1000_gpio_write(PIN, value); + + ctimer_reset(&timer); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(gpio_output_process, ev, data) +{ + PROCESS_BEGIN(); + + quarkX1000_gpio_config(PIN, QUARKX1000_GPIO_OUT); + + quarkX1000_gpio_clock_enable(); + + ctimer_set(&timer, CLOCK_SECOND / 2, timeout, NULL); + + printf("GPIO output example is running\n"); + PROCESS_YIELD(); + + quarkX1000_gpio_clock_disable(); + + PROCESS_END(); +} diff --git a/examples/galileo/i2c-LSM9DS0.c b/examples/galileo/i2c-LSM9DS0.c new file mode 100644 index 000000000..03d61a2a4 --- /dev/null +++ b/examples/galileo/i2c-LSM9DS0.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include +#include + +#include "contiki.h" +#include "sys/ctimer.h" + +#include "i2c.h" + +#define LSM9DS0_I2C_ADDR 0x6A +#define WHO_AM_I_ADDR 0x0F +#define WHO_AM_I_ANSWER 0xD4 + +static uint8_t tx_data = WHO_AM_I_ADDR; +static uint8_t rx_data = 0; +static struct ctimer timer; + +PROCESS(i2c_lsm9ds0_process, "I2C LSM9DS0 Who Am I Process"); +AUTOSTART_PROCESSES(&i2c_lsm9ds0_process); +/*---------------------------------------------------------------------------*/ +static void +rx(void) +{ + if (rx_data == WHO_AM_I_ANSWER) + printf("Who am I register value match!\n"); + else + printf("Who am I register value DOESN'T match! %u\n", rx_data); +} +/*---------------------------------------------------------------------------*/ +static void +tx(void) +{ + rx_data = 0; + + quarkX1000_i2c_read(&rx_data, sizeof(rx_data), LSM9DS0_I2C_ADDR); +} +/*---------------------------------------------------------------------------*/ +static void +err(void) +{ + printf("Something went wrong. err() callback has been called.\n"); +} +/*---------------------------------------------------------------------------*/ +static void +timeout(void *data) +{ + quarkX1000_i2c_write(&tx_data, sizeof(tx_data), LSM9DS0_I2C_ADDR); + + ctimer_reset(&timer); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(i2c_lsm9ds0_process, ev, data) +{ + PROCESS_BEGIN(); + + quarkX1000_i2c_set_callbacks(rx, tx, err); + + ctimer_set(&timer, CLOCK_SECOND * 5, timeout, NULL); + + printf("I2C LSM9DS0 example is running\n"); + + PROCESS_YIELD(); + + PROCESS_END(); +} diff --git a/examples/galileo/i2c-callbacks.c b/examples/galileo/i2c-callbacks.c new file mode 100644 index 000000000..d97c6b448 --- /dev/null +++ b/examples/galileo/i2c-callbacks.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include +#include + +#include "contiki.h" +#include "sys/ctimer.h" + +#include "i2c.h" + +#define PWM_PCA9685_0_I2C_ADDR 0x47 +#define MODE1_ADDR 0x00 + +static uint8_t tx_data = MODE1_ADDR; +static uint8_t rx_data = 0; +static struct ctimer timer; + +PROCESS(i2c_callbacks_process, "I2C Callbacks Example Process"); +AUTOSTART_PROCESSES(&i2c_callbacks_process); +/*---------------------------------------------------------------------------*/ +static void +rx(void) +{ + /* The value below is programmed into this register in pwm_pca9685_init(). */ + printf("%s expected value: %x\n", + (rx_data == (1 << 5)) ? "Received" : "Did not receive", + (unsigned)rx_data); +} +/*---------------------------------------------------------------------------*/ +static void +tx(void) +{ + rx_data = 0; + + quarkX1000_i2c_read(&rx_data, sizeof(rx_data), PWM_PCA9685_0_I2C_ADDR); +} +/*---------------------------------------------------------------------------*/ +static void +err(void) +{ + printf("Something went wrong. err() callback has been called.\n"); +} +/*---------------------------------------------------------------------------*/ +static void +timeout(void *data) +{ + quarkX1000_i2c_write(&tx_data, sizeof(tx_data), PWM_PCA9685_0_I2C_ADDR); + + ctimer_reset(&timer); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(i2c_callbacks_process, ev, data) +{ + PROCESS_BEGIN(); + + quarkX1000_i2c_set_callbacks(rx, tx, err); + + ctimer_set(&timer, CLOCK_SECOND * 5, timeout, NULL); + + printf("I2C callbacks example is running\n"); + + PROCESS_YIELD(); + + PROCESS_END(); +} diff --git a/examples/galileo/print-imr.c b/examples/galileo/print-imr.c new file mode 100644 index 000000000..07cd89fed --- /dev/null +++ b/examples/galileo/print-imr.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include + +#include "contiki.h" + +#include "imr.h" +#include "msg-bus.h" + +#define HOST_BRIGE_PORT 3 + +#define HSMMCTL_OFFSET 4 + +#define HMBOUND_OFFSET 8 + +/* Refer to Intel Quark SoC X1000 Datasheet, Section 12.7.2.2 for more details + * on the Host System Management Mode Controls register. + */ +typedef union hsmmctl { + struct { + uint32_t lock : 1; + uint32_t rd_open : 1; + uint32_t wr_open : 1; + uint32_t : 1; + uint32_t start : 12; + uint32_t : 1; + uint32_t non_host_rd_open : 1; + uint32_t non_host_wr_open : 1; + uint32_t : 1; + uint32_t end : 12; + }; + uint32_t raw; +} hsmmctl_t; + +/* Amount to shift hsmmctl.start/end left to obtain the bound address */ +#define HSMMCTL_SHAMT 20 + +/* Refer to Intel Quark SoC X1000 Datasheet, Section 12.7.2.3 for more details + * on the Host Memory I/O Boundary register. + */ +typedef union hmbound { + struct { + uint32_t lock : 1; + uint32_t io_dis : 1; + uint32_t : 10; + uint32_t io_bnd : 20; + }; + uint32_t raw; +} hmbound_t; + +/* Amount to shift hmbound.io_bnd left to obtain the bound address */ +#define HMBOUND_SHAMT 12 + +PROCESS(imr_process, "IMR Process"); +AUTOSTART_PROCESSES(&imr_process); +/*---------------------------------------------------------------------------*/ +static hsmmctl_t +hsmmctl_read(void) +{ + hsmmctl_t hsmm; + + quarkX1000_msg_bus_read(HOST_BRIGE_PORT, HSMMCTL_OFFSET, &hsmm.raw); + + return hsmm; +} +/*---------------------------------------------------------------------------*/ +static void +hsmmctl_print(hsmmctl_t hsmm) +{ + printf("[%08x, %08x) %slocked, non-SMM host: %c%c, non-host: %c%c", + hsmm.start << HSMMCTL_SHAMT, hsmm.end << HSMMCTL_SHAMT, + hsmm.lock ? "" : "un", + hsmm.rd_open ? 'R' : '-', hsmm.wr_open ? 'W' : '-', + hsmm.non_host_rd_open ? 'R' : '-', hsmm.non_host_wr_open ? 'W' : '-'); +} +/*---------------------------------------------------------------------------*/ +static hmbound_t +hmbound_read(void) +{ + hmbound_t hmb; + + quarkX1000_msg_bus_read(HOST_BRIGE_PORT, HMBOUND_OFFSET, &hmb.raw); + + return hmb; +} +/*---------------------------------------------------------------------------*/ +static void +hmbound_print(hmbound_t hmb) +{ + printf("%08x %slocked, IO %sabled", + hmb.io_bnd << HMBOUND_SHAMT, + hmb.lock ? "" : "un", + hmb.io_dis ? "dis" : "en"); +} +/*---------------------------------------------------------------------------*/ +static void +imr_print(quarkX1000_imr_t imr) +{ + printf("[%08x, %08x) %slocked, rdmsk: %08x, wrmsk: %08x", + imr.lo.addr << QUARKX1000_IMR_SHAMT, + imr.hi.addr << QUARKX1000_IMR_SHAMT, + imr.lo.lock ? "" : "un", imr.rdmsk.raw, imr.wrmsk.raw); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(imr_process, ev, data) +{ + int i; + quarkX1000_imr_t imr; + hsmmctl_t hsmm; + hmbound_t hmb; + + PROCESS_BEGIN(); + + fputs("Host SMM Controls: ", stdout); + hsmm = hsmmctl_read(); + hsmmctl_print(hsmm); + fputs("\nHost Memory IO Boundary: ", stdout); + hmb = hmbound_read(); + hmbound_print(hmb); + puts("\nIsolated Memory Regions:"); + for(i = 0; i < QUARKX1000_IMR_CNT; i++) { + printf(" - #%d: ", i); + imr = quarkX1000_imr_read(i); + imr_print(imr); + puts(""); + } + + PROCESS_END(); +} diff --git a/examples/galileo/prot-domain-switch-latency.c b/examples/galileo/prot-domain-switch-latency.c new file mode 100644 index 000000000..9b6908a2f --- /dev/null +++ b/examples/galileo/prot-domain-switch-latency.c @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include +#include +#include + +#include "contiki.h" +#include "prot-domains.h" +#include "startup.h" +#include "syscalls.h" + +#define CPU_FREQ (400 * 1000 * 1000) +/* Run the test for approximately eight seconds. + * + * Duration expressed as shift amount to avoid integer overflow. + */ +#define DURATION_SECONDS_SHAMT 3 + +#ifdef SAMPLE_METADATA +typedef struct sample_meta { + int cnt; + +#if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING + /** + * See the comment on the padding in the metadata for the Intel Quark X1000 + * Ethernet driver for an explanation of why it is sized and structured like + * this. + */ + uint8_t pad[MIN_PAGE_SIZE - sizeof(int)]; +#endif +} __attribute__((packed)) sample_meta_t; + +static sample_meta_t ATTR_BSS_META meta = { .cnt = 0 }; +#endif + +PROT_DOMAINS_ALLOC(dom_client_data_t, ping_dcd); +PROT_DOMAINS_ALLOC(dom_client_data_t, pong_dcd); + +PROCESS(prot_domain_latency_process, "Ping-Pong Process"); +AUTOSTART_PROCESSES(&prot_domain_latency_process); +/*---------------------------------------------------------------------------*/ +void pong(uint64_t *mid, int *cnt); +SYSCALLS_DEFINE_SINGLETON(pong, pong_dcd, + uint64_t *mid, int *cnt) +{ +#ifdef SAMPLE_METADATA + sample_meta_t *loc_meta = (sample_meta_t *)PROT_DOMAINS_META(pong_dcd); +#endif + + *mid = _rdtsc(); + +#ifdef SAMPLE_METADATA + META_READL(*cnt, loc_meta->cnt); + META_WRITEL(loc_meta->cnt, *cnt + 1); +#endif +} +/*---------------------------------------------------------------------------*/ +void ping(void); +SYSCALLS_DEFINE_SINGLETON(ping, ping_dcd) +{ + uint64_t start, mid, end; + uint64_t diff1 = 0, diff2 = 0; + double diff1_d, diff2_d; + int i = 0; + int cnt; + + while(((diff1 + diff2) >> DURATION_SECONDS_SHAMT) < CPU_FREQ) { + start = _rdtsc(); + pong(&mid, &cnt); + end = _rdtsc(); + +#ifdef SAMPLE_METADATA + assert(cnt == i); +#endif + + /* exclude the warm-up round */ + if(i != 0) { + diff1 += mid - start; + diff2 += end - mid; + } + + i++; + } + + diff1_d = diff1; + diff2_d = diff2; + + diff1_d /= i - 1; + diff2_d /= i - 1; + + puts( "Sample protection domain ping-pong switching latency measurements:"); + printf(" %u iterations\n", i - 1); + printf(" Avg. # cycles ping -> pong: %.2f\n", diff1_d); + printf(" + Avg. # cycles pong -> ping: %.2f\n", diff2_d); + puts( " ----------------------------------------"); + printf(" Avg. # cycles round-trip: %.2f\n", diff1_d + diff2_d); +} +/*---------------------------------------------------------------------------*/ +KERN_STARTUP_FUNC(sample_domain_init) +{ + PROT_DOMAINS_INIT_ID(ping_dcd); + prot_domains_reg(&ping_dcd, 0, 0, 0, 0, false); + SYSCALLS_INIT(ping); + SYSCALLS_AUTHZ(ping, ping_dcd); + + PROT_DOMAINS_INIT_ID(pong_dcd); + prot_domains_reg(&pong_dcd, 0, 0, +#ifdef SAMPLE_METADATA + (uintptr_t)&meta, sizeof(meta), false); +#else + 0, 0, false); +#endif + SYSCALLS_INIT(pong); + SYSCALLS_AUTHZ(pong, pong_dcd); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(prot_domain_latency_process, ev, data) +{ + PROCESS_BEGIN(); + + /* Run the latency test from the ping domain so that interrupts + * are disabled during the test. + */ + ping(); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/hello-world/Makefile b/examples/hello-world/Makefile index fc17d7ae6..0a79167ae 100644 --- a/examples/hello-world/Makefile +++ b/examples/hello-world/Makefile @@ -1,7 +1,5 @@ CONTIKI_PROJECT = hello-world all: $(CONTIKI_PROJECT) -#UIP_CONF_IPV6=1 - CONTIKI = ../.. include $(CONTIKI)/Makefile.include diff --git a/examples/hello-world/README.md b/examples/hello-world/README.md index c4cbd2c6e..a92c242ab 100644 --- a/examples/hello-world/README.md +++ b/examples/hello-world/README.md @@ -34,7 +34,7 @@ For example, using a loopback interface with the minimal-net platform: make UIP_CONF_IPV6=1 TARGET=minimal-net ./hello-world.minimal-net Hello, world - IPV6 Address: [aaaa::206:98ff:fe00:232] + IPV6 Address: [fd00::206:98ff:fe00:232] IPV6 Address: [fe80::206:98ff:fe00:232] ^C diff --git a/examples/hello-world/hello-world-example.csc b/examples/hello-world/hello-world-example.csc index d937a468b..2fe722c97 100644 --- a/examples/hello-world/hello-world-example.csc +++ b/examples/hello-world/hello-world-example.csc @@ -1,126 +1,126 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/native_gateway - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - /home/user/contikiprojects/sics.se/mobility - [CONTIKI_DIR]/tools/cooja/apps/collect-view - /home/user/contikiprojects/sics.se/powertracker - - Hello world example - 0 - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Hello world sky - [CONTIKI_DIR]/examples/hello-world/hello-world.c - make hello-world.sky TARGET=sky - [CONTIKI_DIR]/examples/hello-world/hello-world.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.avrmote.MicaZMoteType - micaz1 - Hello world micaz - [CONTIKI_DIR]/examples/hello-world/hello-world.c - make hello-world.elf TARGET=micaz - [CONTIKI_DIR]/examples/hello-world/hello-world.elf - org.contikios.cooja.interfaces.Position - org.contikios.cooja.avrmote.interfaces.MicaZID - org.contikios.cooja.avrmote.interfaces.MicaZLED - org.contikios.cooja.avrmote.interfaces.MicaZRadio - org.contikios.cooja.avrmote.interfaces.MicaClock - org.contikios.cooja.avrmote.interfaces.MicaSerial - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - - - - - org.contikios.cooja.interfaces.Position - 93.1576842462532 - 12.110654409141041 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - org.contikios.cooja.interfaces.Position - 24.27184344020801 - 51.304686914739605 - 0.0 - - - org.contikios.cooja.avrmote.interfaces.MicaZID - 2 - - micaz1 - - - - org.contikios.cooja.plugins.SimControl - 318 - 0 - 192 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 3.8271488095595365 0.0 0.0 3.8271488095595365 -79.7101385461893 -0.34997402775074654 - - 300 - 1 - 300 - 435 - 4 - - - org.contikios.cooja.plugins.LogListener - - - - 738 - 2 - 356 - 0 - 224 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/native_gateway + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + /home/user/contikiprojects/sics.se/mobility + [CONTIKI_DIR]/tools/cooja/apps/collect-view + /home/user/contikiprojects/sics.se/powertracker + + Hello world example + 0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Hello world sky + [CONTIKI_DIR]/examples/hello-world/hello-world.c + make hello-world.sky TARGET=sky + [CONTIKI_DIR]/examples/hello-world/hello-world.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.avrmote.MicaZMoteType + micaz1 + Hello world micaz + [CONTIKI_DIR]/examples/hello-world/hello-world.c + make hello-world.elf TARGET=micaz + [CONTIKI_DIR]/examples/hello-world/hello-world.elf + org.contikios.cooja.interfaces.Position + org.contikios.cooja.avrmote.interfaces.MicaZID + org.contikios.cooja.avrmote.interfaces.MicaZLED + org.contikios.cooja.avrmote.interfaces.MicaZRadio + org.contikios.cooja.avrmote.interfaces.MicaClock + org.contikios.cooja.avrmote.interfaces.MicaSerial + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + + + + + org.contikios.cooja.interfaces.Position + 93.1576842462532 + 12.110654409141041 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + org.contikios.cooja.interfaces.Position + 24.27184344020801 + 51.304686914739605 + 0.0 + + + org.contikios.cooja.avrmote.interfaces.MicaZID + 2 + + micaz1 + + + + org.contikios.cooja.plugins.SimControl + 318 + 0 + 192 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 3.8271488095595365 0.0 0.0 3.8271488095595365 -79.7101385461893 -0.34997402775074654 + + 300 + 1 + 300 + 435 + 4 + + + org.contikios.cooja.plugins.LogListener + + + + 738 + 2 + 356 + 0 + 224 + + + diff --git a/examples/http-socket/Makefile b/examples/http-socket/Makefile new file mode 100644 index 000000000..b1d95efe0 --- /dev/null +++ b/examples/http-socket/Makefile @@ -0,0 +1,7 @@ +all: http-example +CONTIKI=../.. +MODULES += core/net/http-socket + +include $(CONTIKI)/Makefile.include + + diff --git a/examples/http-socket/http-example.c b/examples/http-socket/http-example.c new file mode 100644 index 000000000..21aff094d --- /dev/null +++ b/examples/http-socket/http-example.c @@ -0,0 +1,62 @@ +#include "contiki-net.h" +#include "http-socket.h" +#include "ip64-addr.h" + +#include + +static struct http_socket s; +static int bytes_received = 0; + +/*---------------------------------------------------------------------------*/ +PROCESS(http_example_process, "HTTP Example"); +AUTOSTART_PROCESSES(&http_example_process); +/*---------------------------------------------------------------------------*/ +static void +callback(struct http_socket *s, void *ptr, + http_socket_event_t e, + const uint8_t *data, uint16_t datalen) +{ + if(e == HTTP_SOCKET_ERR) { + printf("HTTP socket error\n"); + } else if(e == HTTP_SOCKET_TIMEDOUT) { + printf("HTTP socket error: timed out\n"); + } else if(e == HTTP_SOCKET_ABORTED) { + printf("HTTP socket error: aborted\n"); + } else if(e == HTTP_SOCKET_HOSTNAME_NOT_FOUND) { + printf("HTTP socket error: hostname not found\n"); + } else if(e == HTTP_SOCKET_CLOSED) { + printf("HTTP socket closed, %d bytes received\n", bytes_received); + } else if(e == HTTP_SOCKET_DATA) { + bytes_received += datalen; + printf("HTTP socket received %d bytes of data\n", datalen); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(http_example_process, ev, data) +{ + static struct etimer et; + uip_ip4addr_t ip4addr; + uip_ip6addr_t ip6addr; + + PROCESS_BEGIN(); + + uip_ipaddr(&ip4addr, 8,8,8,8); + ip64_addr_4to6(&ip4addr, &ip6addr); + uip_nameserver_update(&ip6addr, UIP_NAMESERVER_INFINITE_LIFETIME); + + etimer_set(&et, CLOCK_SECOND * 60); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + http_socket_init(&s); + http_socket_get(&s, "http://www.contiki-os.org/", 0, 0, + callback, NULL); + + etimer_set(&et, CLOCK_SECOND); + while(1) { + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/ip64-router/Makefile b/examples/ip64-router/Makefile new file mode 100644 index 000000000..c44c677ad --- /dev/null +++ b/examples/ip64-router/Makefile @@ -0,0 +1,5 @@ +all: ip64-router +CONTIKI=../.. + +include $(CONTIKI)/Makefile.include + diff --git a/examples/ip64-router/ip64-router.c b/examples/ip64-router/ip64-router.c new file mode 100644 index 000000000..391b5038b --- /dev/null +++ b/examples/ip64-router/ip64-router.c @@ -0,0 +1,27 @@ +#include "contiki.h" +#include "contiki-net.h" +#include "ip64.h" +#include "net/netstack.h" + +/*---------------------------------------------------------------------------*/ +PROCESS(router_node_process, "Router node"); +AUTOSTART_PROCESSES(&router_node_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(router_node_process, ev, data) +{ + PROCESS_BEGIN(); + + /* Set us up as a RPL root node. */ + rpl_dag_root_init_dag(); + + /* Initialize the IP64 module so we'll start translating packets */ + ip64_init(); + + /* ... and do nothing more. */ + while(1) { + PROCESS_WAIT_EVENT(); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/ip64-router/project-conf.h b/examples/ip64-router/project-conf.h new file mode 100644 index 000000000..e69de29bb diff --git a/examples/ipso-objects/Makefile b/examples/ipso-objects/Makefile new file mode 100644 index 000000000..8f620741c --- /dev/null +++ b/examples/ipso-objects/Makefile @@ -0,0 +1,29 @@ +CONTIKI_PROJECT = example-ipso-objects + +CONTIKI_SOURCEFILES += serial-protocol.c example-ipso-temperature.c + +all: $(CONTIKI_PROJECT) + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +APPS += rest-engine +APPS += er-coap +APPS += oma-lwm2m +APPS += ipso-objects + +CONTIKI=../.. +CONTIKI_WITH_IPV6 = 1 +include $(CONTIKI)/Makefile.include + +# border router rules +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + (cd $(CONTIKI)/tools && $(MAKE) tunslip6) + +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 -p 60001 aaaa::1/64 + +connect-router-native: $(CONTIKI)/examples/ipv6/native-border-router/border-router.native + sudo $(CONTIKI)/exmples/ipv6/native-border-router/border-router.native -a 127.0.0.1 -p 60001 aaaa::1/64 diff --git a/examples/ipso-objects/README.md b/examples/ipso-objects/README.md new file mode 100644 index 000000000..e9be82dcb --- /dev/null +++ b/examples/ipso-objects/README.md @@ -0,0 +1,48 @@ +IPSO Objects Example +============================================ + +This is an example of how to make use of the IPSO Object and LWM2M +implementation in Contiki. + +The LWM2M implementation is based on the Erbium CoAP implementation +and consists of two apps: lwm2m-engine and ipso-objects. The +lwm2m-engine handle the specifics of LWM2M including bootstrapping and +how read/writes of objects and resources are handled. The ipso-objects +contains implementations of some of the IPSO Smart Objects. + +The implementation was used during the IPSO Interop in May 2015, +Kista, Sweden, and was successfully tested with other +implementations. + +The examples use some of the basic IPSO object for controlling LEDs on +Contiki devices and for reading out temperature. + +##Testing IPSO-objects with Leshan + +First program a device with the examples/ipso-objects/example-ipso-objects.c + +```bash +>make example-ipso-objects.upload TARGET=zoul +>... +``` + +After that start up a native-border router or other border router on fd00::1/64 +or another prefix - NOTE: if you use another prefix you will need to change LWM2M_SERVER_ADDRESS for which the device will register - in project-conf.h: +``` +#define LWM2M_SERVER_ADDRESS "fd00::1" +``` + +Then when everything is setup you can download a Leshan and use that to +test controlling LEDs of the device. + +###Starting Leshan +```bash +wget https://hudson.eclipse.org/leshan/job/leshan/lastSuccessfulBuild/artifact/leshan-standalone.jar +java -jar ./leshan-standalone.jar +``` +Browse to leshans device page with http://127.0.0.1:8080 . + +When you have started the border-router and also Leshan you should now +start (or reboot) your IPSO Object enabled device. Within 30 seconds +you should be able to see it on the Leshan device page. + diff --git a/examples/ipso-objects/cooja-example-ipso-objects.csc b/examples/ipso-objects/cooja-example-ipso-objects.csc new file mode 100644 index 000000000..d8dc44876 --- /dev/null +++ b/examples/ipso-objects/cooja-example-ipso-objects.csc @@ -0,0 +1,171 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + LWM2M & IPSO Objects Example + 1.0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.WismoteMoteType + wismote1 + Wismote Border Router #border-router + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.wismote TARGET=wismote DEFINES=NETSTACK_RDC=nullrdc_driver,NETSTACK_MAC=nullmac_driver + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.wismote + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.WismoteMoteType + wismote2 + Wismote IPSO Objects #ipso-example + [CONTIKI_DIR]/examples/ipso-objects/example-ipso-objects.c + make example-ipso-objects.wismote TARGET=wismote + [CONTIKI_DIR]/examples/ipso-objects/example-ipso-objects.wismote + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 56.362361976162035 + 11.826023799100883 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + wismote1 + + + + + org.contikios.cooja.interfaces.Position + 60.1539674439426 + 11.827942168467365 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + wismote2 + + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.LEDVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 53.336918739504526 0.0 0.0 53.336918739504526 -2924.9161170527295 -473.3614543395965 + + 400 + 4 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + ID:2 + + + + 1286 + 1 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.Notes + + OMA LWM2M & IPSO Object example + +1. Start a LWM2M server, for example Leshan +2. Run the example and bridge Cooja using tunslip with the prefix aaaa::1/64: + (cd contiki/examples/ipso-objects && make connect-router-cooja) + +After a short time, the example node should register with the LWM2M server at [aaaa::1]:5683. + true + + 1006 + 0 + 160 + 680 + 0 + + + org.contikios.cooja.serialsocket.SerialSocketServer + 0 + + 60001 + true + + 362 + 3 + 116 + 1 + 399 + + + diff --git a/examples/ipso-objects/cooja-example-router-node.csc b/examples/ipso-objects/cooja-example-router-node.csc new file mode 100644 index 000000000..a261b1747 --- /dev/null +++ b/examples/ipso-objects/cooja-example-router-node.csc @@ -0,0 +1,187 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + OMA LWM2M and IPSO Object example + 2.0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 500.0 + 500.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.WismoteMoteType + wismote1 + Wismote Router #wismote1 + [CONTIKI_DIR]/examples/ipso-objects/example-server.c + make example-server.wismote TARGET=wismote + [CONTIKI_DIR]/examples/ipso-objects/example-server.wismote + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.WismoteMoteType + wismote2 + Wismote Mote Type #wismote2 + [CONTIKI_DIR]/examples/ipso-objects/example-ipso-objects.c + make example-ipso-objects.wismote TARGET=wismote + [CONTIKI_DIR]/examples/ipso-objects/example-ipso-objects.wismote + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 30.243188653185154 + 29.963547412144486 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + s aaaa::200:0:0:3 /3311/0/5850 0~;s aaaa::200:0:0:3 /3311/0/5850 1~;g aaaa::200:0:0:3 /3311/1/5850~;g aaaa::200:0:0:3 /3311/0/5850~;g aaaa::200:0:0:3 /3311/1/5850~;g aaaa::200:0:0:3 /3311/0/5850~;s aaaa::200:0:0:3 /3311/0/5850 1~;s aaaa::200:0:0:2 /3311/0/5850 1~;h~;s aaaa::200:0:0:2 /3311/0/5850 1~;s aaaa::200:0:0:2 /3311/0/5850 0~;g aaaa::200:0:0:2 /3311/0/5850~;g aaaa::200:0:0:2 /3311/1/5850~;g aaaa::200:0:0:2 /3311/2/5850~;l~; + + wismote1 + + + + + org.contikios.cooja.interfaces.Position + 59.75123136831088 + 29.84506209179908 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + wismote2 + + + + + org.contikios.cooja.interfaces.Position + 60.30742753391745 + 59.35092511889063 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + wismote2 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.LEDVisualizerSkin + 4.593848158957425 0.0 0.0 4.593848158957425 13.734375417550426 -121.37641081710846 + + 400 + 3 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 959 + 2 + 447 + 400 + 160 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 679 + 1 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.MoteInterfaceViewer + 0 + + Serial port + 0,0 + + 579 + 4 + 300 + 49 + 414 + + + diff --git a/examples/ipso-objects/example-ipso-objects.c b/examples/ipso-objects/example-ipso-objects.c new file mode 100644 index 000000000..bbb7aa464 --- /dev/null +++ b/examples/ipso-objects/example-ipso-objects.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 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. + * + */ + +/** + * \file + * OMA LWM2M and IPSO Objects example. + * \author + * Joakim Eriksson, joakime@sics.se + * Niclas Finne, nfi@sics.se + */ + +#include "contiki.h" +#include "lwm2m-engine.h" +#include "ipso-objects.h" + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +#ifndef REGISTER_WITH_LWM2M_BOOTSTRAP_SERVER +#define REGISTER_WITH_LWM2M_BOOTSTRAP_SERVER 0 +#endif + +#ifndef REGISTER_WITH_LWM2M_SERVER +#define REGISTER_WITH_LWM2M_SERVER 1 +#endif + +#ifndef LWM2M_SERVER_ADDRESS +#define LWM2M_SERVER_ADDRESS "fd00::1" +#endif + +PROCESS(example_ipso_objects, "IPSO object example"); +AUTOSTART_PROCESSES(&example_ipso_objects); +/*---------------------------------------------------------------------------*/ +static void +setup_lwm2m_servers(void) +{ +#ifdef LWM2M_SERVER_ADDRESS + uip_ipaddr_t addr; + if(uiplib_ipaddrconv(LWM2M_SERVER_ADDRESS, &addr)) { + lwm2m_engine_register_with_bootstrap_server(&addr, 0); + lwm2m_engine_register_with_server(&addr, 0); + } +#endif /* LWM2M_SERVER_ADDRESS */ + + lwm2m_engine_use_bootstrap_server(REGISTER_WITH_LWM2M_BOOTSTRAP_SERVER); + lwm2m_engine_use_registration_server(REGISTER_WITH_LWM2M_SERVER); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(example_ipso_objects, ev, data) +{ + PROCESS_BEGIN(); + + PROCESS_PAUSE(); + + PRINTF("Starting IPSO objects example\n"); + + /* Initialize the OMA LWM2M engine */ + lwm2m_engine_init(); + + /* Register default LWM2M objects */ + lwm2m_engine_register_default_objects(); + + /* Register default IPSO objects */ + ipso_objects_init(); + + setup_lwm2m_servers(); + + while(1) { + PROCESS_WAIT_EVENT(); + } + + PROCESS_END(); +} diff --git a/examples/ipso-objects/example-ipso-temperature.c b/examples/ipso-objects/example-ipso-temperature.c new file mode 100644 index 000000000..30f320640 --- /dev/null +++ b/examples/ipso-objects/example-ipso-temperature.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 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. + */ + +/** + * \file + * An dummy temperature driver as example + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "ipso-objects.h" +#include "lib/random.h" + +static int32_t last_value = 27000; +/*---------------------------------------------------------------------------*/ +static int +read_value(int32_t *value) +{ + last_value = last_value + (random_rand() % 1000) - 500; + if(last_value < 18000) { + last_value = 18000; + } else if(last_value > 35000) { + last_value = 35000; + } + *value = last_value; + return 0; +} +/*---------------------------------------------------------------------------*/ +const struct ipso_objects_sensor example_ipso_temperature = { + .read_value = read_value +}; +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipso-objects/example-server.c b/examples/ipso-objects/example-server.c new file mode 100644 index 000000000..605e3295a --- /dev/null +++ b/examples/ipso-objects/example-server.c @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 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. + * + */ + +/** + * \file + * IPSO Objects and OMA LWM2M example. + * \author + * Joakim Eriksson, joakime@sics.se + * Niclas Finne, nfi@sics.se + */ + +#include "contiki.h" +#include "net/ip/uip.h" +#include "net/rpl/rpl.h" +#include "net/netstack.h" +#include "er-coap-constants.h" +#include "er-coap-engine.h" +#include "lwm2m-engine.h" +#include "oma-tlv.h" +#include "dev/serial-line.h" +#include "serial-protocol.h" + +#if CONTIKI_TARGET_WISMOTE +#include "dev/uart1.h" +#endif + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT) + +#define URL_WELL_KNOWN ".well-known/core" +#define URL_DEVICE_MODEL "/3/0/1" +#define URL_DEVICE_FIRMWARE_VERSION "/3/0/3" +#define URL_LIGHT_CONTROL "/3311/0/5850" +#define URL_POWER_CONTROL "/3312/0/5850" + +#define MAX_NODES 10 + +#define NODE_HAS_TYPE (1 << 0) + +struct node { + uip_ipaddr_t ipaddr; + char type[32]; + uint8_t flags; + uint8_t retries; +}; + +static struct node nodes[MAX_NODES]; +static uint8_t node_count; + +static struct node *current_target; +static char current_uri[32] = URL_LIGHT_CONTROL; +static char current_value[32] = "1"; +static int current_request = COAP_PUT; +static uint8_t fetching_type = 0; + +PROCESS(router_process, "router process"); +AUTOSTART_PROCESSES(&router_process); +/*---------------------------------------------------------------------------*/ +static struct node * +add_node(const uip_ipaddr_t *addr) +{ + int i; + for(i = 0; i < node_count; i++) { + if(uip_ipaddr_cmp(&nodes[i].ipaddr, addr)) { + /* Node already added */ + return &nodes[i]; + } + } + if(node_count < MAX_NODES) { + uip_ipaddr_copy(&nodes[node_count].ipaddr, addr); + return &nodes[node_count++]; + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +void +set_value(const uip_ipaddr_t *addr, char *uri, char *value) +{ + int i; + printf("#set value "); + uip_debug_ipaddr_print(addr); + printf(" URI: %s Value: %s\n", uri, value); + + for(i = 0; i < node_count; i++) { + if(uip_ipaddr_cmp(&nodes[i].ipaddr, addr)) { + /* setup command */ + current_target = &nodes[i]; + current_request = COAP_PUT; + strncpy(current_uri, uri, sizeof(current_uri) - 1); + strncpy(current_value, value, sizeof(current_value) - 1); + process_poll(&router_process); + break; + } + } +} +/*---------------------------------------------------------------------------*/ +void +get_value(const uip_ipaddr_t *addr, char *uri) +{ + int i; + printf("#get value "); + uip_debug_ipaddr_print(addr); + printf(" URI: %s\n", uri); + + for(i = 0; i < node_count; i++) { + if(uip_ipaddr_cmp(&nodes[i].ipaddr, addr)) { + /* setup command */ + current_target = &nodes[i]; + current_request = COAP_GET; + strncpy(current_uri, uri, sizeof(current_uri) - 1); + current_value[0] = 0; + process_poll(&router_process); + break; + } + } +} +/*---------------------------------------------------------------------------*/ +void +print_node_list(void) +{ + int i; + int out = 0; + for(i = 0; i < node_count; i++) { + if(nodes[i].flags & NODE_HAS_TYPE) { + if(out++) { + printf(";"); + } + printf("%s,", nodes[i].type); + uip_debug_ipaddr_print(&nodes[i].ipaddr); + } + } + printf("\n"); +} +/*---------------------------------------------------------------------------*/ +/** + * This function is will be passed to COAP_BLOCKING_REQUEST() to + * handle responses. + */ +static void +client_chunk_handler(void *response) +{ + const uint8_t *chunk; + unsigned int format; + int len = coap_get_payload(response, &chunk); + coap_get_header_content_format(response, &format); + + /* if(len > 0) { */ + /* printf("|%.*s (%d,%d)", len, (char *)chunk, len, format); */ + /* } */ + if(current_target != NULL && fetching_type) { + if(len > sizeof(current_target->type) - 1) { + len = sizeof(current_target->type) - 1; + } + memcpy(current_target->type, chunk, len); + current_target->type[len] = 0; + current_target->flags |= NODE_HAS_TYPE; + + PRINTF("\nNODE "); + PRINT6ADDR(¤t_target->ipaddr); + PRINTF(" HAS TYPE %s\n", current_target->type); + } else { + /* otherwise update the current value */ + if(format == LWM2M_TLV) { + oma_tlv_t tlv; + /* we can only read int32 for now ? */ + if(oma_tlv_read(&tlv, chunk, len) > 0) { + /* printf("TLV.type=%d len=%d id=%d value[0]=%d\n", */ + /* tlv.type, tlv.length, tlv.id, tlv.value[0]); */ + + int value = oma_tlv_get_int32(&tlv); + snprintf(current_value, sizeof(current_value), "%d", value); + } + } else { + if(len > sizeof(current_value) - 1) { + len = sizeof(current_value) - 1; + } + memcpy(current_value, chunk, len); + current_value[len] = 0; + } + } +} +/*---------------------------------------------------------------------------*/ +static void +setup_network(void) +{ + uip_ipaddr_t ipaddr; + struct uip_ds6_addr *root_if; + rpl_dag_t *dag; + int i; + uint8_t state; + +#if CONTIKI_TARGET_WISMOTE + uart1_set_input(serial_line_input_byte); + serial_line_init(); +#endif + +#if UIP_CONF_ROUTER +/** + * The choice of server address determines its 6LoWPAN header compression. + * Obviously the choice made here must also be selected in udp-client.c. + * + * For correct Wireshark decoding using a sniffer, add the /64 prefix to the 6LowPAN protocol preferences, + * e.g. set Context 0 to fd00::. At present Wireshark copies Context/128 and then overwrites it. + * (Setting Context 0 to fd00::1111:2222:3333:4444 will report a 16 bit compressed address of fd00::1111:22ff:fe33:xxxx) + * Note Wireshark's IPCMV6 checksum verification depends on the correct uncompressed addresses. + */ +#if 0 +/* Mode 1 - 64 bits inline */ + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 1); +#elif 1 +/* Mode 2 - 16 bits inline */ + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0x00ff, 0xfe00, 1); +#else +/* Mode 3 - derived from link local (MAC) address */ + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); +#endif + + uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL); + root_if = uip_ds6_addr_lookup(&ipaddr); + if(root_if != NULL) { + dag = rpl_set_root(RPL_DEFAULT_INSTANCE, &ipaddr); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); + rpl_set_prefix(dag, &ipaddr, 64); + PRINTF("created a new RPL dag\n"); + } else { + PRINTF("failed to create a new RPL DAG\n"); + } +#endif /* UIP_CONF_ROUTER */ + + PRINTF("IPv6 addresses: "); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(state == ADDR_TENTATIVE || state == ADDR_PREFERRED) { + PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); + PRINTF("\n"); + /* hack to make address "final" */ + if (state == ADDR_TENTATIVE) { + uip_ds6_if.addr_list[i].state = ADDR_PREFERRED; + } + } + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(router_process, ev, data) +{ + /* This way the packet can be treated as pointer as usual. */ + static coap_packet_t request[1]; + static struct etimer timer; + uip_ds6_route_t *r; + uip_ipaddr_t *nexthop; + int n; + + PROCESS_BEGIN(); + + PROCESS_PAUSE(); + + /* receives all CoAP messages */ + coap_init_engine(); + + setup_network(); + + /* The data sink runs with a 100% duty cycle in order to ensure high + packet reception rates. */ + NETSTACK_MAC.off(1); + + while(1) { + etimer_set(&timer, CLOCK_SECOND * 5); + PROCESS_YIELD(); + + /* Handle serial line input */ + if(ev == serial_line_event_message) { + serial_protocol_input((char *) data); + } + + if(etimer_expired(&timer)) { + current_target = NULL; + n = 0; + for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { + current_target = add_node(&r->ipaddr); + if(current_target == NULL || + (current_target->flags & NODE_HAS_TYPE) != 0 || + current_target->retries > 5) { + continue; + } + PRINTF(" "); + PRINT6ADDR(&r->ipaddr); + PRINTF(" -> "); + nexthop = uip_ds6_route_nexthop(r); + if(nexthop != NULL) { + PRINT6ADDR(nexthop); + PRINTF("\n"); + } else { + PRINTF("-"); + } + PRINTF("\n"); + n++; + break; + } + } + + /* This is a node type discovery */ + if(current_target != NULL && + (current_target->flags & NODE_HAS_TYPE) == 0 && + current_target->retries < 6) { + + /* prepare request, TID is set by COAP_BLOCKING_REQUEST() */ + coap_init_message(request, COAP_TYPE_CON, COAP_GET, 0); + coap_set_header_uri_path(request, URL_DEVICE_MODEL); + + current_target->retries++; + + PRINTF("CoAP request to ["); + PRINT6ADDR(¤t_target->ipaddr); + PRINTF("]:%u (%u tx)\n", UIP_HTONS(REMOTE_PORT), + current_target->retries); + + fetching_type = 1; + COAP_BLOCKING_REQUEST(¤t_target->ipaddr, REMOTE_PORT, request, + client_chunk_handler); + fetching_type = 0; + strncpy(current_uri, URL_LIGHT_CONTROL, sizeof(current_uri)); + printf("\n--Done--\n"); + } + + /* If having a type this is another type of request */ + if(current_target != NULL && + (current_target->flags & NODE_HAS_TYPE) && strlen(current_uri) > 0) { + /* prepare request, TID is set by COAP_BLOCKING_REQUEST() */ + coap_init_message(request, COAP_TYPE_CON, current_request, 0); + coap_set_header_uri_path(request, current_uri); + + if(strlen(current_value) > 0) { + coap_set_payload(request, (uint8_t *)current_value, + strlen(current_value)); + } + + PRINTF("CoAP request to ["); + PRINT6ADDR(¤t_target->ipaddr); + PRINTF("]:%u %s\n", UIP_HTONS(REMOTE_PORT), current_uri); + + COAP_BLOCKING_REQUEST(¤t_target->ipaddr, REMOTE_PORT, request, + client_chunk_handler); + + /* print out result of command */ + if(current_request == COAP_PUT) { + printf("s "); + } else { + printf("g "); + } + uip_debug_ipaddr_print(¤t_target->ipaddr); + printf(" %s %s\n", current_uri, current_value); + + current_target = NULL; + current_uri[0] = 0; + current_value[0] = 0; + + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipso-objects/project-conf.h b/examples/ipso-objects/project-conf.h new file mode 100644 index 000000000..49e049bbd --- /dev/null +++ b/examples/ipso-objects/project-conf.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 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. + */ + +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#ifdef BOARD_STRING +#define LWM2M_DEVICE_MODEL_NUMBER BOARD_STRING +#elif defined(CONTIKI_TARGET_WISMOTE) +#include "dev/watchdog.h" +#define LWM2M_DEVICE_MODEL_NUMBER "wismote" +#define LWM2M_DEVICE_MANUFACTURER "Arago Systems" +#define LWM2M_DEVICE_SERIAL_NO "001" +#define PLATFORM_REBOOT watchdog_reboot +#endif + +#define IPSO_TEMPERATURE example_ipso_temperature + +/** + * Disabling RDC and CSMA to save memory on constrained devices. + */ +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nullrdc_driver + +#undef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC nullmac_driver + +/* Disabling TCP on CoAP nodes. */ +#undef UIP_CONF_TCP +#define UIP_CONF_TCP 0 + +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 64 + +/* Multiplies with chunk size, be aware of memory constraints. */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +/* Filtering .well-known/core per query can be disabled to save space. */ +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +#undef COAP_PROXY_OPTION_PROCESSING +#define COAP_PROXY_OPTION_PROCESSING 0 + +/* Enable client-side support for COAP observe */ +#define COAP_OBSERVE_CLIENT 1 + +#endif /* PROJECT_CONF_H_ */ diff --git a/examples/ipso-objects/serial-protocol.c b/examples/ipso-objects/serial-protocol.c new file mode 100644 index 000000000..f0c2cb1a0 --- /dev/null +++ b/examples/ipso-objects/serial-protocol.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 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. + */ + +/** + * \file + * Simple serial protocol to list and interact with devices + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "contiki.h" +#include "net/ip/uip.h" +#include "net/ip/uiplib.h" +#include + +void print_node_list(void); +void set_value(const uip_ipaddr_t *addr, char *uri, char *value); +void get_value(const uip_ipaddr_t *addr, char *uri); +/*---------------------------------------------------------------------------*/ +int +find_next_sep(const char *str, char sep, int pos) +{ + char c; + while((c = str[pos]) != 0) { + if(c == sep) { + return pos + 1; + } + pos++; + } + return -1; +} +/*---------------------------------------------------------------------------*/ +/* + * l - list all discovered devices + * s - set + * d - get + */ +void +serial_protocol_input(char *data) +{ + /* We assume that we have a string here */ + char cmd = data[0]; + int pos = 0; + + switch(cmd) { + case 'l': + /* list devices */ + print_node_list(); + break; + case 's': { + uip_ip6addr_t ipaddr; + char *uri; + char *value; + pos = find_next_sep(data, ' ', pos); + if(pos > 0) { + /* start of IP */ + int start = pos; + pos = find_next_sep(data, ' ', pos); + if(pos == -1) { + return; + } + data[pos - 1] = 0; + if(uiplib_ip6addrconv(&data[start], &ipaddr) == 0) { + printf("* Error not valid IP\n"); + } + uri = &data[pos]; + pos = find_next_sep(data, ' ', pos); + if(pos == -1) return; + data[pos - 1] = 0; + value = &data[pos]; + /* set the value at the specified node */ + set_value(&ipaddr, uri, value); + } + break; + } + case 'g': { + uip_ip6addr_t ipaddr; + char *uri; + pos = find_next_sep(data, ' ', pos); + if(pos > 0) { + /* start of IP */ + int start = pos; + pos = find_next_sep(data, ' ', pos); + if(pos == -1) return; + data[pos - 1] = 0; + if(uiplib_ip6addrconv((const char *) &data[start], &ipaddr) == 0) { + printf("* Error not valid IP\n"); + } + uri = &data[pos]; + /* get the value at the specified node */ + get_value(&ipaddr, uri); + } + break; + } + default: + printf("Unknown command\n"); + } +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipso-objects/serial-protocol.h b/examples/ipso-objects/serial-protocol.h new file mode 100644 index 000000000..a6dfcc129 --- /dev/null +++ b/examples/ipso-objects/serial-protocol.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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 HOLDER 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 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. + */ + +/** + * \file + * Simple serial protocol to list and interact with devices + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef SERIAL_PROTOCOL_H_ +#define SERIAL_PROTOCOL_H_ + +void serial_protocol_input(char *data); + +#endif /* SERIAL_PROTOCOL_H_ */ diff --git a/examples/ipv6/json-ws/Makefile b/examples/ipv6/json-ws/Makefile index 2f1ba6582..d8619097d 100644 --- a/examples/ipv6/json-ws/Makefile +++ b/examples/ipv6/json-ws/Makefile @@ -1,6 +1,5 @@ CONTIKI=../../.. -UIP_CONF_IPV6=1 SMALL=1 PROJECT_SOURCEFILES += json-ws.c @@ -26,4 +25,5 @@ ifneq ($(TARGET),) all: websense-$(TARGET) endif +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/ipv6/json-ws/json-ws.c b/examples/ipv6/json-ws/json-ws.c index 6c6177f16..6a290a194 100644 --- a/examples/ipv6/json-ws/json-ws.c +++ b/examples/ipv6/json-ws/json-ws.c @@ -78,7 +78,7 @@ static const char http_content_type_json[] = "application/json"; /* Maximum 40 chars in host name?: 5 x 8 */ -static char callback_host[40] = "[aaaa::1]"; +static char callback_host[40] = "[fd00::1]"; static uint16_t callback_port = CALLBACK_PORT; static uint16_t callback_interval = SEND_INTERVAL; static char callback_path[80] = "/debug/"; diff --git a/examples/ipv6/multicast/Makefile b/examples/ipv6/multicast/Makefile index 4bd9ce515..dca6f7e72 100644 --- a/examples/ipv6/multicast/Makefile +++ b/examples/ipv6/multicast/Makefile @@ -1,5 +1,4 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" -UIP_CONF_IPV6=1 CONTIKI_PROJECT = root intermediate sink all: $(CONTIKI_PROJECT) @@ -8,4 +7,5 @@ CONTIKI = ../../.. MODULES += core/net/ipv6/multicast +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/ipv6/multicast/intermediate.c b/examples/ipv6/multicast/intermediate.c index 6d8f27284..a17b7393c 100644 --- a/examples/ipv6/multicast/intermediate.c +++ b/examples/ipv6/multicast/intermediate.c @@ -47,9 +47,9 @@ #include "contiki-net.h" #include "net/ipv6/multicast/uip-mcast6.h" -#if !UIP_CONF_IPV6 || !UIP_CONF_ROUTER || !UIP_CONF_IPV6_MULTICAST || !UIP_CONF_IPV6_RPL +#if !NETSTACK_CONF_WITH_IPV6 || !UIP_CONF_ROUTER || !UIP_IPV6_MULTICAST || !UIP_CONF_IPV6_RPL #error "This example can not work with the current contiki configuration" -#error "Check the values of: UIP_CONF_IPV6, UIP_CONF_ROUTER, UIP_CONF_IPV6_RPL" +#error "Check the values of: NETSTACK_CONF_WITH_IPV6, UIP_CONF_ROUTER, UIP_CONF_IPV6_RPL" #endif /*---------------------------------------------------------------------------*/ PROCESS(mcast_intermediate_process, "Intermediate Process"); diff --git a/examples/ipv6/multicast/multicast.csc b/examples/ipv6/multicast/multicast.csc index 5339f0351..a0857c13b 100644 --- a/examples/ipv6/multicast/multicast.csc +++ b/examples/ipv6/multicast/multicast.csc @@ -1,257 +1,257 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - Example of a uIPv6 network with multicast support - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - root - [CONTIKI_DIR]/examples/ipv6/multicast/root.c - make root.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/multicast/root.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - sky2 - intermediate - [CONTIKI_DIR]/examples/ipv6/multicast/intermediate.c - make intermediate.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/multicast/intermediate.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - sky3 - sink - [CONTIKI_DIR]/examples/ipv6/multicast/sink.c - make sink.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/multicast/sink.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 5.995813174969022 - 34.43129455447824 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 40.70237155931961 - 16.396742420332068 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 100.3720728044051 - 70.93197095432518 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky3 - - - - - org.contikios.cooja.interfaces.Position - 81.7376718406712 - 28.854291358797 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky3 - - - - - org.contikios.cooja.interfaces.Position - -26.161520836433183 - 8.116006415286686 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky3 - - - - - org.contikios.cooja.interfaces.Position - -34.57705675553882 - 92.87247531485058 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - sky3 - - - - - org.contikios.cooja.interfaces.Position - 39.86312587077661 - 59.603125741056246 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 7 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 1.4345607604759194 - 75.2481773153879 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 8 - - sky2 - - - - org.contikios.cooja.plugins.SimControl - 318 - 0 - 192 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.AddressVisualizerSkin - 3.914959956760176 0.0 0.0 3.914959956760176 300.2075734071477 -15.682931033747009 - - 869 - 3 - 441 - 320 - 3 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1281 - 2 - 213 - -1 - 714 - - - org.contikios.cooja.plugins.RadioLogger - - 117 - - false - false - - - 1280 - 1 - 268 - 0 - 445 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + Example of a uIPv6 network with multicast support + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + root + [CONTIKI_DIR]/examples/ipv6/multicast/root.c + make root.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/multicast/root.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + sky2 + intermediate + [CONTIKI_DIR]/examples/ipv6/multicast/intermediate.c + make intermediate.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/multicast/intermediate.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + sky3 + sink + [CONTIKI_DIR]/examples/ipv6/multicast/sink.c + make sink.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/multicast/sink.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 5.995813174969022 + 34.43129455447824 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 40.70237155931961 + 16.396742420332068 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 100.3720728044051 + 70.93197095432518 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky3 + + + + + org.contikios.cooja.interfaces.Position + 81.7376718406712 + 28.854291358797 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky3 + + + + + org.contikios.cooja.interfaces.Position + -26.161520836433183 + 8.116006415286686 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky3 + + + + + org.contikios.cooja.interfaces.Position + -34.57705675553882 + 92.87247531485058 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky3 + + + + + org.contikios.cooja.interfaces.Position + 39.86312587077661 + 59.603125741056246 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 1.4345607604759194 + 75.2481773153879 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky2 + + + + org.contikios.cooja.plugins.SimControl + 318 + 0 + 192 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.AddressVisualizerSkin + 3.914959956760176 0.0 0.0 3.914959956760176 300.2075734071477 -15.682931033747009 + + 869 + 3 + 441 + 320 + 3 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1281 + 2 + 213 + -1 + 714 + + + org.contikios.cooja.plugins.RadioLogger + + 117 + + false + false + + + 1280 + 1 + 268 + 0 + 445 + + + diff --git a/examples/ipv6/multicast/project-conf.h b/examples/ipv6/multicast/project-conf.h index 84686ce21..8df6d01b4 100644 --- a/examples/ipv6/multicast/project-conf.h +++ b/examples/ipv6/multicast/project-conf.h @@ -52,7 +52,6 @@ #undef UIP_CONF_IPV6_RPL #undef UIP_CONF_ND6_SEND_RA #undef UIP_CONF_ROUTER -#define UIP_CONF_IPV6_RPL 1 #define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_ROUTER 1 #define UIP_MCAST6_ROUTE_CONF_ROUTES 1 diff --git a/examples/ipv6/multicast/root.c b/examples/ipv6/multicast/root.c index 1c70ed388..f10e140d2 100644 --- a/examples/ipv6/multicast/root.c +++ b/examples/ipv6/multicast/root.c @@ -63,9 +63,9 @@ static struct uip_udp_conn * mcast_conn; static char buf[MAX_PAYLOAD_LEN]; static uint32_t seq_id; -#if !UIP_CONF_IPV6 || !UIP_CONF_ROUTER || !UIP_CONF_IPV6_MULTICAST || !UIP_CONF_IPV6_RPL +#if !NETSTACK_CONF_WITH_IPV6 || !UIP_CONF_ROUTER || !UIP_IPV6_MULTICAST || !UIP_CONF_IPV6_RPL #error "This example can not work with the current contiki configuration" -#error "Check the values of: UIP_CONF_IPV6, UIP_CONF_ROUTER, UIP_CONF_IPV6_RPL" +#error "Check the values of: NETSTACK_CONF_WITH_IPV6, UIP_CONF_ROUTER, UIP_CONF_IPV6_RPL" #endif /*---------------------------------------------------------------------------*/ PROCESS(rpl_root_process, "RPL ROOT, Multicast Sender"); @@ -111,7 +111,7 @@ set_own_addresses(void) rpl_dag_t *dag; uip_ipaddr_t ipaddr; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); diff --git a/examples/ipv6/multicast/sink.c b/examples/ipv6/multicast/sink.c index 455e94441..4e795e9de 100644 --- a/examples/ipv6/multicast/sink.c +++ b/examples/ipv6/multicast/sink.c @@ -57,9 +57,9 @@ static uint16_t count; #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#if !UIP_CONF_IPV6 || !UIP_CONF_ROUTER || !UIP_CONF_IPV6_MULTICAST || !UIP_CONF_IPV6_RPL +#if !NETSTACK_CONF_WITH_IPV6 || !UIP_CONF_ROUTER || !UIP_IPV6_MULTICAST || !UIP_CONF_IPV6_RPL #error "This example can not work with the current contiki configuration" -#error "Check the values of: UIP_CONF_IPV6, UIP_CONF_ROUTER, UIP_CONF_IPV6_RPL" +#error "Check the values of: NETSTACK_CONF_WITH_IPV6, UIP_CONF_ROUTER, UIP_CONF_IPV6_RPL" #endif /*---------------------------------------------------------------------------*/ PROCESS(mcast_sink_process, "Multicast Sink"); @@ -84,7 +84,7 @@ join_mcast_group(void) uip_ds6_maddr_t *rv; /* First, set our v6 global */ - uip_ip6addr(&addr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&addr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&addr, &uip_lladdr); uip_ds6_addr_add(&addr, 0, ADDR_AUTOCONF); diff --git a/examples/ipv6/native-border-router/Makefile b/examples/ipv6/native-border-router/Makefile index 191d9c819..dc60e18d9 100644 --- a/examples/ipv6/native-border-router/Makefile +++ b/examples/ipv6/native-border-router/Makefile @@ -4,9 +4,6 @@ APPS = slip-cmd CONTIKI=../../.. -UIP_CONF_IPV6=1 -CFLAGS+= -DUIP_CONF_IPV6_RPL -DUIP_CONF_IPV6 -DWITH_UIP6 - #linker optimizations SMALL=1 @@ -23,7 +20,8 @@ APPS += $(WITH_WEBSERVER) CFLAGS += -DWEBSERVER=2 endif +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include connect-router: border-router.native - sudo ./border-router.native aaaa::1/64 + sudo ./border-router.native fd00::1/64 diff --git a/examples/ipv6/native-border-router/README.md b/examples/ipv6/native-border-router/README.md new file mode 100644 index 000000000..03174972f --- /dev/null +++ b/examples/ipv6/native-border-router/README.md @@ -0,0 +1,28 @@ +This code connects a 802.15.4 radio over TTY with the full uIPv6 stack of +Contiki including 6LoWPAN and 802.15.4 framing / parsing. The native border +router also acts as a RPL Root and handles the routing and maintains the RPL +network. Finally the native border router connects the full 6LoWPAN/RPL +network to the host (linux/os-x) network stack making it possible for +applications on the host to transparently reach all the nodes in the +6LoWPAN/RPL network. + +This is designed to interact with the a ../slip-radio example running on a +mote that is either directly USB/TTY connected, or is remote via a TCP +connect. What's on the SLIP interface is really not Serial Line IP, but SLIP +framed 15.4 packets. + +The border router supports a number of commands on it's stdin. +Each are prefixed by !: +* !G - global RPL repair root. +* !M - set MAC address (if coming from RADIO, i.e. SLIP link) +* !C - show channel (if coming from RADIO, i.e. SLIP link) +* !D - sensor data received +* !Q - exit + +Queries are prefixed by ?: +* ?M is used for requesting the MAC address from the radio in order to use it for uIP6 and its stateless address auto configuration of its IPv6 address. This will make the native border router have the address that correspond to the MAC address of the slip-radio. (response is !M from the slip-radio) + +* ?C is used for requesting the currently used channel for the slip-radio. The response is !C with a channel number (from the slip-radio). + +* !C is used for setting the channel of the slip-radio (useful if the motes are using another channel than the one used in the slip-radio). + diff --git a/examples/ipv6/native-border-router/border-router.c b/examples/ipv6/native-border-router/border-router.c index 4a69b3d70..fe8d7fbf5 100644 --- a/examples/ipv6/native-border-router/border-router.c +++ b/examples/ipv6/native-border-router/border-router.c @@ -61,8 +61,6 @@ #define MAX_SENSORS 4 -uint16_t dag_id[] = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011}; - extern long slip_sent; extern long slip_received; @@ -290,6 +288,7 @@ border_router_set_sensors(const char *data, int len) static void set_prefix_64(const uip_ipaddr_t *prefix_64) { + rpl_dag_t *dag; uip_ipaddr_t ipaddr; memcpy(&prefix, prefix_64, 16); memcpy(&ipaddr, prefix_64, 16); @@ -297,12 +296,17 @@ set_prefix_64(const uip_ipaddr_t *prefix_64) prefix_set = 1; uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); + + dag = rpl_set_root(RPL_DEFAULT_INSTANCE, &ipaddr); + if(dag != NULL) { + rpl_set_prefix(dag, &prefix, 64); + PRINTF("created a new RPL dag\n"); + } } /*---------------------------------------------------------------------------*/ PROCESS_THREAD(border_router_process, ev, data) { static struct etimer et; - rpl_dag_t *dag; PROCESS_BEGIN(); prefix_set = 0; @@ -336,12 +340,6 @@ PROCESS_THREAD(border_router_process, ev, data) } } - dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)dag_id); - if(dag != NULL) { - rpl_set_prefix(dag, &prefix, 64); - PRINTF("created a new RPL dag\n"); - } - #if DEBUG print_local_addresses(); #endif diff --git a/examples/ipv6/native-border-router/slip-config.c b/examples/ipv6/native-border-router/slip-config.c index 84d256127..d6b6e0660 100644 --- a/examples/ipv6/native-border-router/slip-config.c +++ b/examples/ipv6/native-border-router/slip-config.c @@ -67,7 +67,7 @@ int slip_config_handle_arguments(int argc, char **argv) { const char *prog; - char c; + int c; int baudrate = 115200; slip_config_verbose = 0; @@ -125,7 +125,7 @@ slip_config_handle_arguments(int argc, char **argv) case 'h': default: fprintf(stderr,"usage: %s [options] ipaddress\n", prog); -fprintf(stderr,"example: border-router.native -L -v2 -s ttyUSB1 aaaa::1/64\n"); +fprintf(stderr,"example: border-router.native -L -v2 -s ttyUSB1 fd00::1/64\n"); fprintf(stderr,"Options are:\n"); #ifdef linux fprintf(stderr," -B baudrate 9600,19200,38400,57600,115200,921600 (default 115200)\n"); diff --git a/examples/ipv6/native-border-router/tun-bridge.c b/examples/ipv6/native-border-router/tun-bridge.c index 22cb4289b..711f17dec 100644 --- a/examples/ipv6/native-border-router/tun-bridge.c +++ b/examples/ipv6/native-border-router/tun-bridge.c @@ -222,13 +222,15 @@ tun_init() } /*---------------------------------------------------------------------------*/ -void +static int tun_output(uint8_t *data, int len) { /* fprintf(stderr, "*** Writing to tun...%d\n", len); */ if(write(tunfd, data, len) != len) { err(1, "serial_to_tun: write"); + return -1; } + return 0; } /*---------------------------------------------------------------------------*/ int @@ -246,13 +248,14 @@ init(void) { } /*---------------------------------------------------------------------------*/ -static void +static int output(void) { PRINTF("SUT: %u\n", uip_len); if(uip_len > 0) { - tun_output(&uip_buf[UIP_LLH_LEN], uip_len); + return tun_output(&uip_buf[UIP_LLH_LEN], uip_len); } + return 0; } diff --git a/examples/ipv6/rpl-border-router/Makefile b/examples/ipv6/rpl-border-router/Makefile index f296b0bb3..d325918ec 100644 --- a/examples/ipv6/rpl-border-router/Makefile +++ b/examples/ipv6/rpl-border-router/Makefile @@ -3,9 +3,6 @@ all: $(CONTIKI_PROJECT) CONTIKI=../../.. -UIP_CONF_IPV6=1 -CFLAGS+= -DUIP_CONF_IPV6_RPL - #linker optimizations SMALL=1 @@ -24,19 +21,26 @@ PROJECT_SOURCEFILES += slip-bridge.c #of the slip connection. Large MSS together with low baud rates without flow #control will overrun the transmit buffer when the style sheet is requested. +ifeq ($(MAKE_WITH_NON_STORING),1) +CFLAGS += -DWITH_NON_STORING=1 +endif + WITH_WEBSERVER=1 ifeq ($(WITH_WEBSERVER),1) +CFLAGS += -DUIP_CONF_TCP=1 CFLAGS += -DWEBSERVER=1 PROJECT_SOURCEFILES += httpd-simple.c else ifneq ($(WITH_WEBSERVER), 0) APPS += $(WITH_WEBSERVER) +CFLAGS += -DUIP_CONF_TCP=1 CFLAGS += -DWEBSERVER=2 endif ifeq ($(PREFIX),) - PREFIX = aaaa::1/64 + PREFIX = fd00::1/64 endif +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include $(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c diff --git a/examples/ipv6/rpl-border-router/border-router.c b/examples/ipv6/rpl-border-router/border-router.c index 53f5c230e..84943e68f 100644 --- a/examples/ipv6/rpl-border-router/border-router.c +++ b/examples/ipv6/rpl-border-router/border-router.c @@ -54,8 +54,6 @@ #define DEBUG DEBUG_NONE #include "net/ip/uip-debug.h" -uint16_t dag_id[] = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011}; - static uip_ipaddr_t prefix; static uint8_t prefix_set; @@ -101,7 +99,7 @@ PROCESS_THREAD(webserver_nogui_process, ev, data) PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); httpd_appcall(data); } - + PROCESS_END(); } AUTOSTART_PROCESSES(&border_router_process,&webserver_nogui_process); @@ -145,7 +143,6 @@ ipaddr_add(const uip_ipaddr_t *addr) static PT_THREAD(generate_routes(struct httpd_state *s)) { - static int i; static uip_ds6_route_t *r; static uip_ds6_nbr_t *nbr; #if BUF_USES_STACK @@ -178,7 +175,7 @@ PT_THREAD(generate_routes(struct httpd_state *s)) switch (nbr->state) { case NBR_INCOMPLETE: ADD(" INCOMPLETE");break; case NBR_REACHABLE: ADD(" REACHABLE");break; - case NBR_STALE: ADD(" STALE");break; + case NBR_STALE: ADD(" STALE");break; case NBR_DELAY: ADD(" DELAY");break; case NBR_PROBE: ADD(" NBR_PROBE");break; } @@ -190,7 +187,7 @@ PT_THREAD(generate_routes(struct httpd_state *s)) switch (nbr->state) { case NBR_INCOMPLETE: ADD(" INCOMPLETE");break; case NBR_REACHABLE: ADD(" REACHABLE");break; - case NBR_STALE: ADD(" STALE");break; + case NBR_STALE: ADD(" STALE");break; case NBR_DELAY: ADD(" DELAY");break; case NBR_PROBE: ADD(" NBR_PROBE");break; } @@ -249,7 +246,7 @@ PT_THREAD(generate_routes(struct httpd_state *s)) ADD("/%u (via ", r->length); ipaddr_add(uip_ds6_route_nexthop(r)); if(1 || (r->state.lifetime < 600)) { - ADD(") %lus\n", r->state.lifetime); + ADD(") %lus\n", (unsigned long)r->state.lifetime); } else { ADD(")\n"); } @@ -314,29 +311,35 @@ request_prefix(void) uip_buf[1] = 'P'; uip_len = 2; slip_send(); - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ void set_prefix_64(uip_ipaddr_t *prefix_64) { + rpl_dag_t *dag; uip_ipaddr_t ipaddr; memcpy(&prefix, prefix_64, 16); memcpy(&ipaddr, prefix_64, 16); prefix_set = 1; uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); + + dag = rpl_set_root(RPL_DEFAULT_INSTANCE, &ipaddr); + if(dag != NULL) { + rpl_set_prefix(dag, &prefix, 64); + PRINTF("created a new RPL dag\n"); + } } /*---------------------------------------------------------------------------*/ PROCESS_THREAD(border_router_process, ev, data) { static struct etimer et; - rpl_dag_t *dag; PROCESS_BEGIN(); /* While waiting for the prefix to be sent through the SLIP connection, the future - * border router can join an existing DAG as a parent or child, or acquire a default + * border router can join an existing DAG as a parent or child, or acquire a default * router that will later take precedence over the SLIP fallback interface. * Prevent that by turning the radio off until we are initialized as a DAG root. */ @@ -355,7 +358,7 @@ PROCESS_THREAD(border_router_process, ev, data) cpu will interfere with establishing the SLIP connection */ NETSTACK_MAC.off(1); #endif - + /* Request prefix until it has been received */ while(!prefix_set) { etimer_set(&et, CLOCK_SECOND); @@ -363,17 +366,11 @@ PROCESS_THREAD(border_router_process, ev, data) PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); } - dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)dag_id); - if(dag != NULL) { - rpl_set_prefix(dag, &prefix, 64); - PRINTF("created a new RPL dag\n"); - } - /* Now turn the radio on, but disable radio duty cycling. * Since we are the DAG root, reception delays would constrain mesh throughbut. */ NETSTACK_MAC.off(1); - + #if DEBUG || 1 print_local_addresses(); #endif diff --git a/examples/ipv6/rpl-border-router/project-conf.h b/examples/ipv6/rpl-border-router/project-conf.h index 9d9116795..ec3eb3f00 100644 --- a/examples/ipv6/rpl-border-router/project-conf.h +++ b/examples/ipv6/rpl-border-router/project-conf.h @@ -31,6 +31,19 @@ #ifndef PROJECT_ROUTER_CONF_H_ #define PROJECT_ROUTER_CONF_H_ +#ifndef WITH_NON_STORING +#define WITH_NON_STORING 0 /* Set this to run with non-storing mode */ +#endif /* WITH_NON_STORING */ + +#if WITH_NON_STORING +#undef RPL_NS_CONF_LINK_NUM +#define RPL_NS_CONF_LINK_NUM 40 /* Number of links maintained at the root */ +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 0 /* No need for routes */ +#undef RPL_CONF_MOP +#define RPL_CONF_MOP RPL_MOP_NON_STORING /* Mode of operation*/ +#endif /* WITH_NON_STORING */ + #ifndef UIP_FALLBACK_INTERFACE #define UIP_FALLBACK_INTERFACE rpl_interface #endif diff --git a/examples/ipv6/rpl-border-router/slip-bridge.c b/examples/ipv6/rpl-border-router/slip-bridge.c index 52b4a4060..62940d5ef 100644 --- a/examples/ipv6/rpl-border-router/slip-bridge.c +++ b/examples/ipv6/rpl-border-router/slip-bridge.c @@ -59,7 +59,7 @@ slip_input_callback(void) // PRINTF("SIN: %u\n", uip_len); if(uip_buf[0] == '!') { PRINTF("Got configuration message of type %c\n", uip_buf[1]); - uip_len = 0; + uip_clear_buf(); if(uip_buf[1] == 'P') { uip_ipaddr_t prefix; /* Here we set a prefix !!! */ @@ -85,7 +85,7 @@ slip_input_callback(void) slip_send(); } - uip_len = 0; + uip_clear_buf(); } /* Save the last sender received over SLIP to avoid bouncing the packet back if no route is found */ @@ -100,7 +100,7 @@ init(void) slip_set_input_callback(slip_input_callback); } /*---------------------------------------------------------------------------*/ -static void +static int output(void) { if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) { @@ -115,6 +115,7 @@ output(void) // PRINTF("SUT: %u\n", uip_len); slip_send(); } + return 0; } /*---------------------------------------------------------------------------*/ diff --git a/examples/ipv6/rpl-collect/Makefile b/examples/ipv6/rpl-collect/Makefile index 7ed3f6ae1..13813ed44 100644 --- a/examples/ipv6/rpl-collect/Makefile +++ b/examples/ipv6/rpl-collect/Makefile @@ -3,8 +3,11 @@ APPS = powertrace collect-view CONTIKI_PROJECT = udp-sender udp-sink PROJECT_SOURCEFILES += collect-common.c -UIP_CONF_IPV6=1 -CFLAGS+= -DUIP_CONF_IPV6_RPL +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +ifeq ($(MAKE_WITH_NON_STORING),1) +CFLAGS += -DWITH_NON_STORING=1 +endif ifdef PERIOD CFLAGS=-DPERIOD=$(PERIOD) @@ -12,5 +15,5 @@ endif all: $(CONTIKI_PROJECT) +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include - diff --git a/examples/ipv6/rpl-collect/collect-tree-dense-noloss.csc b/examples/ipv6/rpl-collect/collect-tree-dense-noloss.csc index 0d33f1a40..efaf533ff 100644 --- a/examples/ipv6/rpl-collect/collect-tree-dense-noloss.csc +++ b/examples/ipv6/rpl-collect/collect-tree-dense-noloss.csc @@ -1,503 +1,503 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - My simulation - 0 - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 100.0 - 120.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Sky Mote Type #sky1 - [CONFIG_DIR]/udp-sink.c - make udp-sink.sky TARGET=sky - [CONFIG_DIR]/udp-sink.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - sky2 - Sky Mote Type #sky2 - [CONFIG_DIR]/udp-sender.c - make udp-sender.sky TARGET=sky - [CONFIG_DIR]/udp-sender.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 242.83184008074136 - -88.93434685786869 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 223.5175954004352 - -69.05842098947238 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 250.51864863077387 - -59.2420165357677 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 294.4736028715864 - -63.23792146675066 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 188.6638305152632 - -41.28432709660093 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 222.54731411389315 - -32.869043991280165 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 273.694897230475 - -29.672320046493798 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 7 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 321.64575640227054 - -33.66822497747676 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 8 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 159.4120162043624 - -2.500166515809672 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 9 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 196.97352255560222 - -0.10262355721989598 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 10 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 252.91619158936365 - 1.495738415173288 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 11 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 301.66623174735577 - -0.10262355721989598 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 12 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 346.4203669743649 - 1.495738415173288 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 13 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 124.24805281171236 - 22.27444405628468 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 14 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 180.1907218454738 - 35.86052082162674 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 15 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 224.14567608628633 - 30.266253918250598 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 16 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 276.0924401890648 - 35.86052082162674 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 17 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 351.2154528915445 - 37.45888279401993 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 18 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 89.08408941906231 - 47.04905462837903 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 19 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 180.1907218454738 - 75.02038914525976 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 20 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 245.7235627135943 - 66.22939829709723 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 21 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 290.4776979406035 - 67.82776026949043 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 22 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 370.3957965602627 - 64.63103632470406 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 23 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 93.07999435004527 - 82.21301802102909 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 24 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 204.16615143137156 - 106.18844760692684 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 25 - - sky2 - - - - org.contikios.cooja.plugins.SimControl - 259 - 2 - 184 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.AttributeVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 1.836243522352668 0.0 0.0 1.836243522352668 -93.43273668589363 192.8080782058222 - - 666 - 0 - 510 - 369 - -8 - - - org.contikios.cooja.plugins.LogListener - - - - 1347 - 4 - 150 - 0 - 438 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 - 22 - 23 - 24 - - - - 109 - 500.0 - - 1347 - 3 - 150 - 0 - 588 - - - org.contikios.cooja.plugins.collectview.CollectView - 0 - 203 - 1 - 75 - 33 - 188 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + My simulation + 0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 100.0 + 120.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Sky Mote Type #sky1 + [CONFIG_DIR]/udp-sink.c + make udp-sink.sky TARGET=sky + [CONFIG_DIR]/udp-sink.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + sky2 + Sky Mote Type #sky2 + [CONFIG_DIR]/udp-sender.c + make udp-sender.sky TARGET=sky + [CONFIG_DIR]/udp-sender.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 242.83184008074136 + -88.93434685786869 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 223.5175954004352 + -69.05842098947238 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 250.51864863077387 + -59.2420165357677 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 294.4736028715864 + -63.23792146675066 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 188.6638305152632 + -41.28432709660093 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 222.54731411389315 + -32.869043991280165 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 273.694897230475 + -29.672320046493798 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 321.64575640227054 + -33.66822497747676 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 159.4120162043624 + -2.500166515809672 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 196.97352255560222 + -0.10262355721989598 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 252.91619158936365 + 1.495738415173288 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 11 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 301.66623174735577 + -0.10262355721989598 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 12 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 346.4203669743649 + 1.495738415173288 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 13 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 124.24805281171236 + 22.27444405628468 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 14 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 180.1907218454738 + 35.86052082162674 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 15 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 224.14567608628633 + 30.266253918250598 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 16 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 276.0924401890648 + 35.86052082162674 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 17 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 351.2154528915445 + 37.45888279401993 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 18 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 89.08408941906231 + 47.04905462837903 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 19 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 180.1907218454738 + 75.02038914525976 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 20 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 245.7235627135943 + 66.22939829709723 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 21 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 290.4776979406035 + 67.82776026949043 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 22 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 370.3957965602627 + 64.63103632470406 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 23 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 93.07999435004527 + 82.21301802102909 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 24 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 204.16615143137156 + 106.18844760692684 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 25 + + sky2 + + + + org.contikios.cooja.plugins.SimControl + 259 + 2 + 184 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 1.836243522352668 0.0 0.0 1.836243522352668 -93.43273668589363 192.8080782058222 + + 666 + 0 + 510 + 369 + -8 + + + org.contikios.cooja.plugins.LogListener + + + + 1347 + 4 + 150 + 0 + 438 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + + + + 109 + 500.0 + + 1347 + 3 + 150 + 0 + 588 + + + org.contikios.cooja.plugins.collectview.CollectView + 0 + 203 + 1 + 75 + 33 + 188 + + + diff --git a/examples/ipv6/rpl-collect/collect-tree-sparse-lossy.csc b/examples/ipv6/rpl-collect/collect-tree-sparse-lossy.csc index a7c056c98..0af9c2e6e 100644 --- a/examples/ipv6/rpl-collect/collect-tree-sparse-lossy.csc +++ b/examples/ipv6/rpl-collect/collect-tree-sparse-lossy.csc @@ -1,501 +1,501 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - My simulation - 0 - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 70.0 - 90.0 - 1.0 - 0.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Sky Mote Type #sky1 - [CONFIG_DIR]/udp-sink.c - make udp-sink.sky TARGET=sky - [CONFIG_DIR]/udp-sink.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - sky2 - Sky Mote Type #sky2 - [CONFIG_DIR]/udp-sender.c - make udp-sender.sky TARGET=sky - [CONFIG_DIR]/udp-sender.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 242.83184008074136 - -88.93434685786869 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 205.7645134037647 - -62.438740480554074 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 250.51864863077387 - -59.2420165357677 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 294.4736028715864 - -63.23792146675066 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 176.19481691449084 - -35.26658694986995 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 222.54731411389315 - -32.869043991280165 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 273.694897230475 - -29.672320046493798 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 7 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 321.64575640227054 - -33.66822497747676 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 8 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 159.4120162043624 - -2.500166515809672 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 9 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 196.97352255560222 - -0.10262355721989598 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 10 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 252.91619158936365 - 1.495738415173288 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 11 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 301.66623174735577 - -0.10262355721989598 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 12 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 346.4203669743649 - 1.495738415173288 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 13 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 124.24805281171236 - 22.27444405628468 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 14 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 180.1907218454738 - 35.86052082162674 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 15 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 224.14567608628633 - 30.266253918250598 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 16 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 276.0924401890648 - 35.86052082162674 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 17 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 351.2154528915445 - 37.45888279401993 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 18 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 89.08408941906231 - 47.04905462837903 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 19 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 180.1907218454738 - 75.02038914525976 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 20 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 245.7235627135943 - 66.22939829709723 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 21 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 290.4776979406035 - 67.82776026949043 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 22 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 370.3957965602627 - 64.63103632470406 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 23 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 93.07999435004527 - 82.21301802102909 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 24 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 204.16615143137156 - 106.18844760692684 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 25 - - sky2 - - - - org.contikios.cooja.plugins.SimControl - 259 - 3 - 184 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.AttributeVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 1.836243522352668 0.0 0.0 1.836243522352668 -124.43273668589376 177.8080782058222 - - 610 - 2 - 482 - 420 - -2 - - - org.contikios.cooja.plugins.LogListener - - - - 1347 - 4 - 150 - 0 - 438 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 - 22 - 23 - 24 - - 109 - 500.0 - - 1347 - 0 - 150 - 0 - 588 - - - org.contikios.cooja.plugins.collectview.CollectView - 0 - 203 - 1 - 75 - 120 - 120 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + My simulation + 0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 70.0 + 90.0 + 1.0 + 0.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Sky Mote Type #sky1 + [CONFIG_DIR]/udp-sink.c + make udp-sink.sky TARGET=sky + [CONFIG_DIR]/udp-sink.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + sky2 + Sky Mote Type #sky2 + [CONFIG_DIR]/udp-sender.c + make udp-sender.sky TARGET=sky + [CONFIG_DIR]/udp-sender.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 242.83184008074136 + -88.93434685786869 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 205.7645134037647 + -62.438740480554074 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 250.51864863077387 + -59.2420165357677 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 294.4736028715864 + -63.23792146675066 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 176.19481691449084 + -35.26658694986995 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 222.54731411389315 + -32.869043991280165 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 273.694897230475 + -29.672320046493798 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 321.64575640227054 + -33.66822497747676 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 159.4120162043624 + -2.500166515809672 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 196.97352255560222 + -0.10262355721989598 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 252.91619158936365 + 1.495738415173288 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 11 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 301.66623174735577 + -0.10262355721989598 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 12 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 346.4203669743649 + 1.495738415173288 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 13 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 124.24805281171236 + 22.27444405628468 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 14 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 180.1907218454738 + 35.86052082162674 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 15 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 224.14567608628633 + 30.266253918250598 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 16 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 276.0924401890648 + 35.86052082162674 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 17 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 351.2154528915445 + 37.45888279401993 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 18 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 89.08408941906231 + 47.04905462837903 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 19 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 180.1907218454738 + 75.02038914525976 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 20 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 245.7235627135943 + 66.22939829709723 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 21 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 290.4776979406035 + 67.82776026949043 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 22 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 370.3957965602627 + 64.63103632470406 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 23 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 93.07999435004527 + 82.21301802102909 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 24 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 204.16615143137156 + 106.18844760692684 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 25 + + sky2 + + + + org.contikios.cooja.plugins.SimControl + 259 + 3 + 184 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 1.836243522352668 0.0 0.0 1.836243522352668 -124.43273668589376 177.8080782058222 + + 610 + 2 + 482 + 420 + -2 + + + org.contikios.cooja.plugins.LogListener + + + + 1347 + 4 + 150 + 0 + 438 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + + 109 + 500.0 + + 1347 + 0 + 150 + 0 + 588 + + + org.contikios.cooja.plugins.collectview.CollectView + 0 + 203 + 1 + 75 + 120 + 120 + + + diff --git a/examples/ipv6/rpl-collect/project-conf.h b/examples/ipv6/rpl-collect/project-conf.h new file mode 100644 index 000000000..a143b07cd --- /dev/null +++ b/examples/ipv6/rpl-collect/project-conf.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#ifndef WITH_NON_STORING +#define WITH_NON_STORING 0 /* Set this to run with non-storing mode */ +#endif /* WITH_NON_STORING */ + +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#undef UIP_CONF_MAX_ROUTES + +#ifdef TEST_MORE_ROUTES +/* configure number of neighbors and routes */ +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#define UIP_CONF_MAX_ROUTES 30 +#else +/* configure number of neighbors and routes */ +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#define UIP_CONF_MAX_ROUTES 10 +#endif /* TEST_MORE_ROUTES */ + +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nullrdc_driver +#undef NULLRDC_CONF_802154_AUTOACK +#define NULLRDC_CONF_802154_AUTOACK 1 + +/* Define as minutes */ +#define RPL_CONF_DEFAULT_LIFETIME_UNIT 60 + +/* 10 minutes lifetime of routes */ +#define RPL_CONF_DEFAULT_LIFETIME 10 + +#define RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME 1 + +/* Save some ROM */ +#undef UIP_CONF_TCP +#define UIP_CONF_TCP 0 + +#undef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 0 + +#if WITH_NON_STORING +#undef RPL_NS_CONF_LINK_NUM +#define RPL_NS_CONF_LINK_NUM 40 /* Number of links maintained at the root. Can be set to 0 at non-root nodes. */ +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 0 /* No need for routes */ +#undef RPL_CONF_MOP +#define RPL_CONF_MOP RPL_MOP_NON_STORING /* Mode of operation*/ +#endif /* WITH_NON_STORING */ + +#endif /* PROJECT_CONF_H_ */ diff --git a/examples/ipv6/rpl-collect/udp-sender.c b/examples/ipv6/rpl-collect/udp-sender.c index f216cbdcc..469d5e6f0 100644 --- a/examples/ipv6/rpl-collect/udp-sender.c +++ b/examples/ipv6/rpl-collect/udp-sender.c @@ -137,7 +137,7 @@ collect_common_send(void) /* Use parts of the IPv6 address as the parent address, in reversed byte order. */ parent.u8[LINKADDR_SIZE - 1] = nbr->ipaddr.u8[sizeof(uip_ipaddr_t) - 2]; parent.u8[LINKADDR_SIZE - 2] = nbr->ipaddr.u8[sizeof(uip_ipaddr_t) - 1]; - parent_etx = rpl_get_parent_rank((linkaddr_t *) uip_ds6_nbr_get_ll(nbr)) / 2; + parent_etx = rpl_get_parent_rank((uip_lladdr_t *) uip_ds6_nbr_get_ll(nbr)) / 2; } } rtmetric = dag->rank; @@ -195,12 +195,12 @@ set_global_address(void) { uip_ipaddr_t ipaddr; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); /* set server address */ - uip_ip6addr(&server_ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1); + uip_ip6addr(&server_ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 1); } /*---------------------------------------------------------------------------*/ diff --git a/examples/ipv6/rpl-collect/udp-sink.c b/examples/ipv6/rpl-collect/udp-sink.c index dbdde2d01..7834c7cbc 100644 --- a/examples/ipv6/rpl-collect/udp-sink.c +++ b/examples/ipv6/rpl-collect/udp-sink.c @@ -145,14 +145,14 @@ PROCESS_THREAD(udp_server_process, ev, data) PRINTF("UDP server started\n"); #if UIP_CONF_ROUTER - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 1); /* uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); */ uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL); root_if = uip_ds6_addr_lookup(&ipaddr); if(root_if != NULL) { rpl_dag_t *dag; dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)&ipaddr); - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); rpl_set_prefix(dag, &ipaddr, 64); PRINTF("created a new RPL dag\n"); } else { diff --git a/examples/ipv6/rpl-tsch/Makefile b/examples/ipv6/rpl-tsch/Makefile new file mode 100644 index 000000000..734c1499e --- /dev/null +++ b/examples/ipv6/rpl-tsch/Makefile @@ -0,0 +1,22 @@ +CONTIKI_PROJECT = node +all: $(CONTIKI_PROJECT) + +CONTIKI=../../.. +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +CONTIKI_WITH_IPV6 = 1 +MAKE_WITH_ORCHESTRA ?= 0 # force Orchestra from command line +MAKE_WITH_SECURITY ?= 0 # force Security from command line + +APPS += orchestra +MODULES += core/net/mac/tsch + +ifeq ($(MAKE_WITH_ORCHESTRA),1) +CFLAGS += -DWITH_ORCHESTRA=1 +endif + +ifeq ($(MAKE_WITH_SECURITY),1) +CFLAGS += -DWITH_SECURITY=1 +endif + +include $(CONTIKI)/Makefile.include diff --git a/examples/ipv6/rpl-tsch/README.md b/examples/ipv6/rpl-tsch/README.md new file mode 100644 index 000000000..e82db3d63 --- /dev/null +++ b/examples/ipv6/rpl-tsch/README.md @@ -0,0 +1,10 @@ +A RPL+TSCH node. Will act as basic node by default, but can be configured at startup +using the user button and following instructions from the log output. Every press +of a button toggles the mode as 6ln, 6dr or 6dr-sec (detailled next). After 10s with +no button press, the node starts in the last setting. The modes are: +* 6ln (default): 6lowpan node, will join a RPL+TSCH network and act as router. +* 6dr: 6lowpan DAG Root, will start its own RPL+TSCH network. Note this is not a +border router, i.e. it does not have a serial interface with connection to +the Internet. For a border router, see ../border-router. +* 6dr-sec: 6lowpan DAG Root, starting a RPL+TSCH network with link-layer security +enabled. 6ln nodes are able to join both non-secured or secured networks. diff --git a/examples/ipv6/rpl-tsch/node.c b/examples/ipv6/rpl-tsch/node.c new file mode 100644 index 000000000..35852b608 --- /dev/null +++ b/examples/ipv6/rpl-tsch/node.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \file + * A RPL+TSCH node able to act as either a simple node (6ln), + * DAG Root (6dr) or DAG Root with security (6dr-sec) + * Press use button at startup to configure. + * + * \author Simon Duquennoy + */ + +#include "contiki.h" +#include "node-id.h" +#include "net/rpl/rpl.h" +#include "net/ipv6/uip-ds6-route.h" +#include "net/mac/tsch/tsch.h" +#if WITH_ORCHESTRA +#include "orchestra.h" +#endif /* WITH_ORCHESTRA */ + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +#define CONFIG_VIA_BUTTON PLATFORM_HAS_BUTTON +#if CONFIG_VIA_BUTTON +#include "button-sensor.h" +#endif /* CONFIG_VIA_BUTTON */ + +/*---------------------------------------------------------------------------*/ +PROCESS(node_process, "RPL Node"); +#if CONFIG_VIA_BUTTON +AUTOSTART_PROCESSES(&node_process, &sensors_process); +#else /* CONFIG_VIA_BUTTON */ +AUTOSTART_PROCESSES(&node_process); +#endif /* CONFIG_VIA_BUTTON */ + +/*---------------------------------------------------------------------------*/ +static void +print_network_status(void) +{ + int i; + uint8_t state; + uip_ds6_defrt_t *default_route; + uip_ds6_route_t *route; + + PRINTA("--- Network status ---\n"); + + /* Our IPv6 addresses */ + PRINTA("- Server IPv6 addresses:\n"); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && + (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { + PRINTA("-- "); + uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr); + PRINTA("\n"); + } + } + + /* Our default route */ + PRINTA("- Default route:\n"); + default_route = uip_ds6_defrt_lookup(uip_ds6_defrt_choose()); + if(default_route != NULL) { + PRINTA("-- "); + uip_debug_ipaddr_print(&default_route->ipaddr); + PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)default_route->lifetime.interval); + } else { + PRINTA("-- None\n"); + } + + /* Our routing entries */ + PRINTA("- Routing entries (%u in total):\n", uip_ds6_route_num_routes()); + route = uip_ds6_route_head(); + while(route != NULL) { + PRINTA("-- "); + uip_debug_ipaddr_print(&route->ipaddr); + PRINTA(" via "); + uip_debug_ipaddr_print(uip_ds6_route_nexthop(route)); + PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)route->state.lifetime); + route = uip_ds6_route_next(route); + } + + PRINTA("----------------------\n"); +} +/*---------------------------------------------------------------------------*/ +static void +net_init(uip_ipaddr_t *br_prefix) +{ + uip_ipaddr_t global_ipaddr; + + if(br_prefix) { /* We are RPL root. Will be set automatically + as TSCH pan coordinator via the tsch-rpl module */ + memcpy(&global_ipaddr, br_prefix, 16); + uip_ds6_set_addr_iid(&global_ipaddr, &uip_lladdr); + uip_ds6_addr_add(&global_ipaddr, 0, ADDR_AUTOCONF); + rpl_set_root(RPL_DEFAULT_INSTANCE, &global_ipaddr); + rpl_set_prefix(rpl_get_any_dag(), br_prefix, 64); + rpl_repair_root(RPL_DEFAULT_INSTANCE); + } + + NETSTACK_MAC.on(); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(node_process, ev, data) +{ + static struct etimer et; + PROCESS_BEGIN(); + + /* 3 possible roles: + * - role_6ln: simple node, will join any network, secured or not + * - role_6dr: DAG root, will advertise (unsecured) beacons + * - role_6dr_sec: DAG root, will advertise secured beacons + * */ + static int is_coordinator = 0; + static enum { role_6ln, role_6dr, role_6dr_sec } node_role; + node_role = role_6ln; + + /* Set node with MAC address c1:0c:00:00:00:00:01 as coordinator, + * convenient in cooja for regression tests using z1 nodes + * */ + +#ifdef CONTIKI_TARGET_Z1 + extern unsigned char node_mac[8]; + unsigned char coordinator_mac[8] = { 0xc1, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; + + if(memcmp(node_mac, coordinator_mac, 8) == 0) { + if(LLSEC802154_ENABLED) { + node_role = role_6dr_sec; + } else { + node_role = role_6dr; + } + } else { + node_role = role_6ln; + } +#endif + +#if CONFIG_VIA_BUTTON + { +#define CONFIG_WAIT_TIME 5 + + SENSORS_ACTIVATE(button_sensor); + etimer_set(&et, CLOCK_SECOND * CONFIG_WAIT_TIME); + + while(!etimer_expired(&et)) { + printf("Init: current role: %s. Will start in %u seconds. Press user button to toggle mode.\n", + node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec", + CONFIG_WAIT_TIME); + PROCESS_WAIT_EVENT_UNTIL(((ev == sensors_event) && + (data == &button_sensor) && button_sensor.value(0) > 0) + || etimer_expired(&et)); + if(ev == sensors_event && data == &button_sensor && button_sensor.value(0) > 0) { + node_role = (node_role + 1) % 3; + if(LLSEC802154_ENABLED == 0 && node_role == role_6dr_sec) { + node_role = (node_role + 1) % 3; + } + etimer_restart(&et); + } + } + } + +#endif /* CONFIG_VIA_BUTTON */ + + printf("Init: node starting with role %s\n", + node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec"); + + tsch_set_pan_secured(LLSEC802154_ENABLED && (node_role == role_6dr_sec)); + is_coordinator = node_role > role_6ln; + + if(is_coordinator) { + uip_ipaddr_t prefix; + uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); + net_init(&prefix); + } else { + net_init(NULL); + } + +#if WITH_ORCHESTRA + orchestra_init(); +#endif /* WITH_ORCHESTRA */ + + /* Print out routing tables every minute */ + etimer_set(&et, CLOCK_SECOND * 60); + while(1) { + print_network_status(); + PROCESS_YIELD_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipv6/rpl-tsch/project-conf.h b/examples/ipv6/rpl-tsch/project-conf.h new file mode 100644 index 000000000..8ac0a93b6 --- /dev/null +++ b/examples/ipv6/rpl-tsch/project-conf.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \author Simon Duquennoy + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +/* Set to run orchestra */ +#ifndef WITH_ORCHESTRA +#define WITH_ORCHESTRA 0 +#endif /* WITH_ORCHESTRA */ + +/* Set to enable TSCH security */ +#ifndef WITH_SECURITY +#define WITH_SECURITY 0 +#endif /* WITH_SECURITY */ + +/*******************************************************/ +/********************* Enable TSCH *********************/ +/*******************************************************/ + +/* Netstack layers */ +#undef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC tschmac_driver +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nordc_driver +#undef NETSTACK_CONF_FRAMER +#define NETSTACK_CONF_FRAMER framer_802154 + +/* IEEE802.15.4 frame version */ +#undef FRAME802154_CONF_VERSION +#define FRAME802154_CONF_VERSION FRAME802154_IEEE802154E_2012 + +/* TSCH and RPL callbacks */ +#define RPL_CALLBACK_PARENT_SWITCH tsch_rpl_callback_parent_switch +#define RPL_CALLBACK_NEW_DIO_INTERVAL tsch_rpl_callback_new_dio_interval +#define TSCH_CALLBACK_JOINING_NETWORK tsch_rpl_callback_joining_network +#define TSCH_CALLBACK_LEAVING_NETWORK tsch_rpl_callback_leaving_network + +/* Needed for CC2538 platforms only */ +/* For TSCH we have to use the more accurate crystal oscillator + * by default the RC oscillator is activated */ +#undef SYS_CTRL_CONF_OSC32K_USE_XTAL +#define SYS_CTRL_CONF_OSC32K_USE_XTAL 1 + +/* Needed for cc2420 platforms only */ +/* Disable DCO calibration (uses timerB) */ +#undef DCOSYNCH_CONF_ENABLED +#define DCOSYNCH_CONF_ENABLED 0 +/* Enable SFD timestamps (uses timerB) */ +#undef CC2420_CONF_SFD_TIMESTAMPS +#define CC2420_CONF_SFD_TIMESTAMPS 1 + +/*******************************************************/ +/******************* Configure TSCH ********************/ +/*******************************************************/ + +/* TSCH logging. 0: disabled. 1: basic log. 2: with delayed + * log messages from interrupt */ +#undef TSCH_LOG_CONF_LEVEL +#define TSCH_LOG_CONF_LEVEL 2 + +/* IEEE802.15.4 PANID */ +#undef IEEE802154_CONF_PANID +#define IEEE802154_CONF_PANID 0xabcd + +/* Do not start TSCH at init, wait for NETSTACK_MAC.on() */ +#undef TSCH_CONF_AUTOSTART +#define TSCH_CONF_AUTOSTART 0 + +/* 6TiSCH minimal schedule length. + * Larger values result in less frequent active slots: reduces capacity and saves energy. */ +#undef TSCH_SCHEDULE_CONF_DEFAULT_LENGTH +#define TSCH_SCHEDULE_CONF_DEFAULT_LENGTH 3 + +#if WITH_SECURITY + +/* Enable security */ +#undef LLSEC802154_CONF_ENABLED +#define LLSEC802154_CONF_ENABLED 1 +/* TSCH uses explicit keys to identify k1 and k2 */ +#undef LLSEC802154_CONF_USES_EXPLICIT_KEYS +#define LLSEC802154_CONF_USES_EXPLICIT_KEYS 1 +/* TSCH uses the ASN rather than frame counter to construct the Nonce */ +#undef LLSEC802154_CONF_USES_FRAME_COUNTER +#define LLSEC802154_CONF_USES_FRAME_COUNTER 0 + +#endif /* WITH_SECURITY */ + +#if WITH_ORCHESTRA + +/* See apps/orchestra/README.md for more Orchestra configuration options */ +#define TSCH_SCHEDULE_CONF_WITH_6TISCH_MINIMAL 0 /* No 6TiSCH minimal schedule */ +#define TSCH_CONF_WITH_LINK_SELECTOR 1 /* Orchestra requires per-packet link selection */ +/* Orchestra callbacks */ +#define TSCH_CALLBACK_NEW_TIME_SOURCE orchestra_callback_new_time_source +#define TSCH_CALLBACK_PACKET_READY orchestra_callback_packet_ready +#define NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK orchestra_callback_child_added +#define NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK orchestra_callback_child_removed + +#endif /* WITH_ORCHESTRA */ + +/*******************************************************/ +/************* Other system configuration **************/ +/*******************************************************/ + +#if CONTIKI_TARGET_Z1 +/* Save some space to fit the limited RAM of the z1 */ +#undef UIP_CONF_TCP +#define UIP_CONF_TCP 0 +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 3 +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 8 +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 8 +#undef UIP_CONF_ND6_SEND_NA +#define UIP_CONF_ND6_SEND_NA 0 +#undef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 0 + +#if WITH_SECURITY +/* Note: on sky or z1 in cooja, crypto operations are done in S/W and + * cannot be accommodated in normal slots. Use 65ms slots instead, and + * a very short 6TiSCH minimal schedule length */ +#undef TSCH_CONF_DEFAULT_TIMESLOT_LENGTH +#define TSCH_CONF_DEFAULT_TIMESLOT_LENGTH 65000 +#undef TSCH_SCHEDULE_CONF_DEFAULT_LENGTH +#define TSCH_SCHEDULE_CONF_DEFAULT_LENGTH 2 +/* Reduce log level to make space for security on z1 */ +#undef TSCH_LOG_CONF_LEVEL +#define TSCH_LOG_CONF_LEVEL 0 +#endif /* WITH_SECURITY */ + +#endif /* CONTIKI_TARGET_Z1 */ + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/ipv6/rpl-tsch/rpl-tsch-z1.csc b/examples/ipv6/rpl-tsch/rpl-tsch-z1.csc new file mode 100644 index 000000000..90bee7525 --- /dev/null +++ b/examples/ipv6/rpl-tsch/rpl-tsch-z1.csc @@ -0,0 +1,267 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + RPL+TSCH + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Z1MoteType + z11 + Z1 Mote Type #z11 + [CONFIG_DIR]/node.c + make node.z1 TARGET=z1 + [CONFIG_DIR]/node.z1 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + -1.285769821276336 + 38.58045647334346 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + z11 + + + + + org.contikios.cooja.interfaces.Position + -19.324109516886306 + 76.23135780254927 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 5.815501305791592 + 76.77463755494317 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 31.920697784030082 + 50.5212265977149 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 47.21747673247198 + 30.217765340599726 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 10.622284947035123 + 109.81862399725188 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 52.41150716335335 + 109.93228340481916 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 70.18727461718498 + 70.06861701541145 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 80.29870484201041 + 99.37351603835938 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + z11 + + + + org.contikios.cooja.plugins.SimControl + 242 + 3 + 160 + 11 + 241 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 1.7405603810040515 0.0 0.0 1.7405603810040515 47.95980153208088 -42.576134155447555 + + 236 + 2 + 230 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + ID:1 + + + + 1031 + 0 + 394 + 273 + 6 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + + + + 16529.88882215865 + + 1304 + 1 + 311 + 0 + 412 + + + diff --git a/examples/ipv6/rpl-udp/Makefile b/examples/ipv6/rpl-udp/Makefile index 6dfe77c47..d7330821a 100644 --- a/examples/ipv6/rpl-udp/Makefile +++ b/examples/ipv6/rpl-udp/Makefile @@ -1,10 +1,7 @@ all: udp-client udp-server -APPS=servreg-hack CONTIKI=../../.. -UIP_CONF_IPV6=1 - -CFLAGS+= -DUIP_CONF_IPV6_RPL +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" ifdef WITH_COMPOWER APPS+=powertrace @@ -18,4 +15,9 @@ ifdef PERIOD CFLAGS+=-DPERIOD=$(PERIOD) endif +ifeq ($(MAKE_WITH_NON_STORING),1) +CFLAGS += -DWITH_NON_STORING=1 +endif + +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/ipv6/rpl-udp/project-conf.h b/examples/ipv6/rpl-udp/project-conf.h new file mode 100644 index 000000000..794897a46 --- /dev/null +++ b/examples/ipv6/rpl-udp/project-conf.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2015, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#ifndef WITH_NON_STORING +#define WITH_NON_STORING 0 /* Set this to run with non-storing mode */ +#endif /* WITH_NON_STORING */ + +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#undef UIP_CONF_MAX_ROUTES + +#ifdef TEST_MORE_ROUTES +/* configure number of neighbors and routes */ +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#define UIP_CONF_MAX_ROUTES 30 +#else +/* configure number of neighbors and routes */ +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#define UIP_CONF_MAX_ROUTES 10 +#endif /* TEST_MORE_ROUTES */ + +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nullrdc_driver +#undef NULLRDC_CONF_802154_AUTOACK +#define NULLRDC_CONF_802154_AUTOACK 1 + +/* Define as minutes */ +#define RPL_CONF_DEFAULT_LIFETIME_UNIT 60 + +/* 10 minutes lifetime of routes */ +#define RPL_CONF_DEFAULT_LIFETIME 10 + +#define RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME 1 + +#ifndef RPL_CONF_WITH_NON_STORING +#define RPL_CONF_WITH_NON_STORING 0 /* Set this to run with non-storing mode */ +#endif /* RPL_CONF_WITH_NON_STORING */ + +#if WITH_NON_STORING +#undef RPL_NS_CONF_LINK_NUM +#define RPL_NS_CONF_LINK_NUM 40 /* Number of links maintained at the root. Can be set to 0 at non-root nodes. */ +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 0 /* No need for routes */ +#undef RPL_CONF_MOP +#define RPL_CONF_MOP RPL_MOP_NON_STORING /* Mode of operation*/ +#endif /* WITH_NON_STORING */ + +#endif diff --git a/examples/ipv6/rpl-udp/rpl-udp-powertrace.csc b/examples/ipv6/rpl-udp/rpl-udp-powertrace.csc index e85b17393..c92dc0800 100644 --- a/examples/ipv6/rpl-udp/rpl-udp-powertrace.csc +++ b/examples/ipv6/rpl-udp/rpl-udp-powertrace.csc @@ -1,584 +1,584 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/mobility - - Data collection network using IPv6 and RPL - 0 - generated - 5000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Sky Mote Type #sky1 - [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.c - make udp-server.sky TARGET=sky WITH_COMPOWER=1 - [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - sky2 - Sky Mote Type #sky2 - [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.c - make udp-client.sky TARGET=sky WITH_COMPOWER=1 - [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 48.435974731198804 - -66.16503914182063 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 4.049356309774755 - 98.28771308774003 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 127.9689727848476 - 91.71883780610729 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 57.897299848739024 - 92.47229665488265 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 47.34887596588397 - -30.341495695501195 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 47.13486576528276 - 32.944481932122315 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -11.42091423859419 - 17.879870626121914 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 7 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 118.92746659954325 - 57.05973076244069 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 8 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 53.68872892015448 - 59.887319605093715 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 9 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 16.45706316609417 - 23.9075414163248 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 10 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -18.9555027263478 - 75.14274313304935 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 11 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 29.265863595275306 - 85.6911670159044 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 12 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -39.298891643282545 - -3.9704359883635574 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 13 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 66.93880603404335 - -42.39683727590697 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 14 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 94.81678343873172 - 26.921376811426246 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 15 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -43.06618588715935 - 30.68867105530305 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 16 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -34.02467970185502 - -24.313824905298304 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 17 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -28.750467760427494 - 48.01822457713635 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 18 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 124.95513738974614 - 20.140247172447996 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 19 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 15.703604317318808 - -47.6710492173345 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 20 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -40.05235049205791 - 92.47229665488265 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 21 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 121.18784314586934 - -24.313824905298304 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 22 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 88.03565379975346 - -44.657213822233054 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 23 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 24.745110502623138 - -1.7100594420374744 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 24 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 94.06332458995635 - -2.4635182908128352 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 25 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -4.639784599615941 - -9.998106778566445 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 26 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -13.681290784920272 - -50.684884612435944 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 27 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 103.10483077526068 - 96.99304974753483 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 28 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 8.922474678340558 - 59.320107308766765 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 29 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 58.650758697514384 - 2.8106936506146916 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 30 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 90.59867707439 - 67.97632874312737 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 31 - - sky2 - - - - org.contikios.cooja.plugins.SimControl - 259 - 1 - 184 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.AttributeVisualizerSkin - 2.349818846983307 0.0 0.0 2.349818846983307 150.19773526533348 176.95275613586946 - - 520 - 3 - 523 - 269 - 14 - - - org.contikios.cooja.plugins.LogListener - - - - 937 - 0 - 213 - 21 - 464 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - 2 - 700 - 665 - 6 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/mobility + + Data collection network using IPv6 and RPL + 0 + generated + 5000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Sky Mote Type #sky1 + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.c + make udp-server.sky TARGET=sky WITH_COMPOWER=1 + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + sky2 + Sky Mote Type #sky2 + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.c + make udp-client.sky TARGET=sky WITH_COMPOWER=1 + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 48.435974731198804 + -66.16503914182063 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 4.049356309774755 + 98.28771308774003 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 127.9689727848476 + 91.71883780610729 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 57.897299848739024 + 92.47229665488265 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 47.34887596588397 + -30.341495695501195 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 47.13486576528276 + 32.944481932122315 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -11.42091423859419 + 17.879870626121914 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 118.92746659954325 + 57.05973076244069 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 53.68872892015448 + 59.887319605093715 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 16.45706316609417 + 23.9075414163248 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -18.9555027263478 + 75.14274313304935 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 11 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 29.265863595275306 + 85.6911670159044 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 12 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -39.298891643282545 + -3.9704359883635574 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 13 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 66.93880603404335 + -42.39683727590697 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 14 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 94.81678343873172 + 26.921376811426246 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 15 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -43.06618588715935 + 30.68867105530305 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 16 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -34.02467970185502 + -24.313824905298304 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 17 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -28.750467760427494 + 48.01822457713635 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 18 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 124.95513738974614 + 20.140247172447996 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 19 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 15.703604317318808 + -47.6710492173345 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 20 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -40.05235049205791 + 92.47229665488265 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 21 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 121.18784314586934 + -24.313824905298304 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 22 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 88.03565379975346 + -44.657213822233054 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 23 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 24.745110502623138 + -1.7100594420374744 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 24 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 94.06332458995635 + -2.4635182908128352 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 25 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -4.639784599615941 + -9.998106778566445 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 26 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -13.681290784920272 + -50.684884612435944 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 27 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 103.10483077526068 + 96.99304974753483 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 28 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 8.922474678340558 + 59.320107308766765 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 29 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 58.650758697514384 + 2.8106936506146916 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 30 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 90.59867707439 + 67.97632874312737 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 31 + + sky2 + + + + org.contikios.cooja.plugins.SimControl + 259 + 1 + 184 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + 2.349818846983307 0.0 0.0 2.349818846983307 150.19773526533348 176.95275613586946 + + 520 + 3 + 523 + 269 + 14 + + + org.contikios.cooja.plugins.LogListener + + + + 937 + 0 + 213 + 21 + 464 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 2 + 700 + 665 + 6 + + + diff --git a/examples/ipv6/rpl-udp/rpl-udp-scale-wismote.csc b/examples/ipv6/rpl-udp/rpl-udp-scale-wismote.csc new file mode 100644 index 000000000..3aea07ab0 --- /dev/null +++ b/examples/ipv6/rpl-udp/rpl-udp-scale-wismote.csc @@ -0,0 +1,721 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + RPL up and downstream scaleability test network using IPv6 and RPL + generated + 5000000 + + org.contikios.cooja.radiomediums.UDGM + 150.0 + 150.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.WismoteMoteType + sky1 + WisMote Type #sky1 + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.c + make SERVER_REPLY=1 clean udp-server.wismote TARGET=wismote DEFINES=TEST_MORE_ROUTES=1 + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.wismote + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.WismoteMoteType + sky2 + WisMote Type #sky2 + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.c + make SERVER_REPLY=1 clean udp-client.wismote TARGET=wismote + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.wismote + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 48.435974731198804 + -66.16503914182063 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + -65.3176930733124 + 17.4304162608286 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 127.9689727848476 + 91.71883780610729 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 154.92605604103275 + 40.97896551774433 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 47.34887596588397 + -30.341495695501195 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 47.13486576528276 + 32.944481932122315 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -11.42091423859419 + 17.879870626121914 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 118.92746659954325 + 57.05973076244069 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 56.66768196114595 + 74.35652008990945 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 16.45706316609417 + 23.9075414163248 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -13.423161364506493 + -38.483037144768275 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 11 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -9.034961217472201 + 44.411389162165406 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 12 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 35.60049910164592 + 87.95154356223047 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 13 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 66.93880603404335 + -42.39683727590697 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 14 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 94.81678343873172 + 26.921376811426246 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 15 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -49.449656689283934 + 57.924813144367945 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 16 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -34.02467970185502 + -24.313824905298304 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 17 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -28.750467760427494 + 48.01822457713635 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 18 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 124.95513738974614 + 20.140247172447996 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 19 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 14.85247487703553 + -34.478542892943686 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 20 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 154.43072661267115 + -3.279765376986134 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 21 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 99.90960713878738 + -21.76043658444847 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 22 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 88.4612185198951 + -49.763990463932714 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 23 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 24.745110502623138 + -1.7100594420374744 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 24 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 94.06332458995635 + -2.4635182908128352 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 25 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -4.639784599615941 + -10.849236218849724 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 26 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 2.4901685804620115 + -60.89843789583528 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 27 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 100.55144245441083 + 97.41861446767646 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 28 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -12.355761328741393 + 82.72616691655692 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 29 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 57.79962925723111 + 0.6828700499064966 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 30 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 76.5550413097159 + 77.33875258624342 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 31 + + sky2 + + + + org.contikios.cooja.plugins.SimControl + 289 + 4 + 184 + 31 + 41 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + 2.349818846983307 0.0 0.0 2.349818846983307 187.19773526533345 190.95275613586946 + + 659 + 2 + 622 + 296 + 11 + + + org.contikios.cooja.plugins.LogListener + + ID:22.*DAO + + + + 937 + 3 + 442 + 20 + 297 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 5 + 700 + 946 + 6 + + + org.contikios.cooja.plugins.MoteInterfaceViewer + 3 + + Position + 0,0 + + 350 + 6 + 300 + 976 + 36 + + + diff --git a/examples/ipv6/rpl-udp/rpl-udp-scale.csc b/examples/ipv6/rpl-udp/rpl-udp-scale.csc new file mode 100644 index 000000000..292e442c1 --- /dev/null +++ b/examples/ipv6/rpl-udp/rpl-udp-scale.csc @@ -0,0 +1,729 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + RPL up and downstream scaleability test network using IPv6 and RPL + generated + 5000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Sky Mote Type #sky1 + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.c + make SERVER_REPLY=1 clean udp-server.sky TARGET=sky DEFINES=TEST_MORE_ROUTES=1 + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + sky2 + Sky Mote Type #sky2 + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.c + make SERVER_REPLY=1 clean udp-client.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 48.435974731198804 + -66.16503914182063 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + -39.78380986481406 + -48.10655064098382 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 127.9689727848476 + 91.71883780610729 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 154.92605604103275 + 40.97896551774433 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + + org.contikios.cooja.mspmote.interfaces.MspSerial + r~; + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 47.34887596588397 + -30.341495695501195 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 47.13486576528276 + 32.944481932122315 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -11.42091423859419 + 17.879870626121914 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 118.92746659954325 + 57.05973076244069 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 53.68872892015448 + 59.887319605093715 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 16.45706316609417 + 23.9075414163248 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -13.423161364506493 + -38.483037144768275 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 11 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -9.034961217472201 + 44.411389162165406 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 12 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -39.298891643282545 + -3.9704359883635574 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 13 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 66.93880603404335 + -42.39683727590697 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 14 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 94.81678343873172 + 26.921376811426246 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 15 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -43.06618588715935 + 30.68867105530305 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 16 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -34.02467970185502 + -24.313824905298304 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 17 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -28.750467760427494 + 48.01822457713635 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 18 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 124.95513738974614 + 20.140247172447996 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 19 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 15.703604317318808 + -47.6710492173345 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 20 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 154.43072661267115 + -3.279765376986134 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 21 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 121.18784314586934 + -24.313824905298304 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 22 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 88.4612185198951 + -49.763990463932714 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 23 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 24.745110502623138 + -1.7100594420374744 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 24 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 94.06332458995635 + -2.4635182908128352 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 25 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -4.639784599615941 + -9.998106778566445 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 26 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 2.4901685804620115 + -60.89843789583528 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 27 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 103.10483077526068 + 96.99304974753483 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 28 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 8.922474678340558 + 59.320107308766765 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 29 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 58.650758697514384 + 2.8106936506146916 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 30 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 90.59867707439 + 67.97632874312737 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 31 + + sky2 + + + + org.contikios.cooja.plugins.SimControl + 289 + 1 + 184 + 31 + 41 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + 2.349818846983307 0.0 0.0 2.349818846983307 187.19773526533345 190.95275613586946 + + 659 + 3 + 523 + 296 + 11 + + + org.contikios.cooja.plugins.LogListener + + + + + + 937 + 4 + 349 + 21 + 464 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 0 + 700 + 946 + 6 + + + org.contikios.cooja.plugins.MoteInterfaceViewer + 3 + + Serial port + 0,0 + + 350 + 2 + 300 + 976 + 36 + + diff --git a/examples/ipv6/rpl-udp/rpl-udp.csc b/examples/ipv6/rpl-udp/rpl-udp.csc index 5ee97f4d4..3aa9b270e 100644 --- a/examples/ipv6/rpl-udp/rpl-udp.csc +++ b/examples/ipv6/rpl-udp/rpl-udp.csc @@ -1,584 +1,711 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/mobility - - Data collection network using IPv6 and RPL - 0 - generated - 5000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Sky Mote Type #sky1 - [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.c - make udp-server.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - sky2 - Sky Mote Type #sky2 - [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.c - make udp-client.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 48.435974731198804 - -66.16503914182063 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 4.049356309774755 - 98.28771308774003 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 127.9689727848476 - 91.71883780610729 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 57.897299848739024 - 92.47229665488265 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 47.34887596588397 - -30.341495695501195 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 47.13486576528276 - 32.944481932122315 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -11.42091423859419 - 17.879870626121914 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 7 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 118.92746659954325 - 57.05973076244069 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 8 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 53.68872892015448 - 59.887319605093715 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 9 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 16.45706316609417 - 23.9075414163248 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 10 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -18.9555027263478 - 75.14274313304935 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 11 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 29.265863595275306 - 85.6911670159044 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 12 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -39.298891643282545 - -3.9704359883635574 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 13 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 66.93880603404335 - -42.39683727590697 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 14 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 94.81678343873172 - 26.921376811426246 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 15 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -43.06618588715935 - 30.68867105530305 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 16 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -34.02467970185502 - -24.313824905298304 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 17 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -28.750467760427494 - 48.01822457713635 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 18 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 124.95513738974614 - 20.140247172447996 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 19 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 15.703604317318808 - -47.6710492173345 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 20 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -40.05235049205791 - 92.47229665488265 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 21 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 121.18784314586934 - -24.313824905298304 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 22 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 88.03565379975346 - -44.657213822233054 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 23 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 24.745110502623138 - -1.7100594420374744 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 24 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 94.06332458995635 - -2.4635182908128352 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 25 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -4.639784599615941 - -9.998106778566445 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 26 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - -13.681290784920272 - -50.684884612435944 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 27 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 103.10483077526068 - 96.99304974753483 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 28 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 8.922474678340558 - 59.320107308766765 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 29 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 58.650758697514384 - 2.8106936506146916 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 30 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 90.59867707439 - 67.97632874312737 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 31 - - sky2 - - - - org.contikios.cooja.plugins.SimControl - 259 - 1 - 184 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.AttributeVisualizerSkin - 2.349818846983307 0.0 0.0 2.349818846983307 150.19773526533348 176.95275613586946 - - 520 - 3 - 523 - 269 - 14 - - - org.contikios.cooja.plugins.LogListener - - - - 937 - 0 - 213 - 21 - 464 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - 2 - 700 - 665 - 6 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + Data collection network using IPv6 and RPL + generated + 5000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Sky Mote Type #sky1 + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.c + make clean udp-server.sky TARGET=sky DEFINES=TEST_MORE_ROUTES=1 + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + sky2 + Sky Mote Type #sky2 + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.c + make clean udp-client.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 48.435974731198804 + -66.16503914182063 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 4.049356309774755 + 98.28771308774003 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 127.9689727848476 + 91.71883780610729 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 57.897299848739024 + 92.47229665488265 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 47.34887596588397 + -30.341495695501195 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 47.13486576528276 + 32.944481932122315 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -11.42091423859419 + 17.879870626121914 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 118.92746659954325 + 57.05973076244069 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 53.68872892015448 + 59.887319605093715 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 16.45706316609417 + 23.9075414163248 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -18.9555027263478 + 75.14274313304935 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 11 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 29.265863595275306 + 85.6911670159044 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 12 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -39.298891643282545 + -3.9704359883635574 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 13 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 66.93880603404335 + -42.39683727590697 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 14 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 94.81678343873172 + 26.921376811426246 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 15 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -43.06618588715935 + 30.68867105530305 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 16 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -34.02467970185502 + -24.313824905298304 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 17 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -28.750467760427494 + 48.01822457713635 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 18 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 124.95513738974614 + 20.140247172447996 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 19 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 15.703604317318808 + -47.6710492173345 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 20 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -40.05235049205791 + 92.47229665488265 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 21 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 121.18784314586934 + -24.313824905298304 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 22 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 88.03565379975346 + -44.657213822233054 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 23 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 24.745110502623138 + -1.7100594420374744 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 24 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 94.06332458995635 + -2.4635182908128352 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 25 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -4.639784599615941 + -9.998106778566445 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 26 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + -13.681290784920272 + -50.684884612435944 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 27 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 103.10483077526068 + 96.99304974753483 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 28 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 8.922474678340558 + 59.320107308766765 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 29 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 58.650758697514384 + 2.8106936506146916 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 30 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 90.59867707439 + 67.97632874312737 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 31 + + sky2 + + + + org.contikios.cooja.plugins.SimControl + 259 + 3 + 184 + 3 + 15 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + 2.349818846983307 0.0 0.0 2.349818846983307 150.19773526533348 176.95275613586946 + + 520 + 2 + 523 + 14 + 210 + + + org.contikios.cooja.plugins.LogListener + + + + + + 937 + 0 + 213 + 265 + 16 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 651 + 1 + 550 + 547 + 181 + + + diff --git a/examples/ipv6/rpl-udp/udp-client.c b/examples/ipv6/rpl-udp/udp-client.c index c16b0ba48..e5339fc3d 100644 --- a/examples/ipv6/rpl-udp/udp-client.c +++ b/examples/ipv6/rpl-udp/udp-client.c @@ -40,12 +40,17 @@ #include #include +/* Only for TMOTE Sky? */ +#include "dev/serial-line.h" +#include "dev/uart1.h" +#include "net/ipv6/uip-ds6-route.h" + #define UDP_CLIENT_PORT 8765 #define UDP_SERVER_PORT 5678 #define UDP_EXAMPLE_ID 190 -#define DEBUG DEBUG_PRINT +#define DEBUG DEBUG_FULL #include "net/ip/uip-debug.h" #ifndef PERIOD @@ -64,6 +69,9 @@ static uip_ipaddr_t server_ipaddr; PROCESS(udp_client_process, "UDP client process"); AUTOSTART_PROCESSES(&udp_client_process); /*---------------------------------------------------------------------------*/ +static int seq_id; +static int reply; + static void tcpip_handler(void) { @@ -72,16 +80,32 @@ tcpip_handler(void) if(uip_newdata()) { str = uip_appdata; str[uip_datalen()] = '\0'; - printf("DATA recv '%s'\n", str); + reply++; + printf("DATA recv '%s' (s:%d, r:%d)\n", str, seq_id, reply); } } /*---------------------------------------------------------------------------*/ static void send_packet(void *ptr) { - static int seq_id; char buf[MAX_PAYLOAD_LEN]; +#ifdef SERVER_REPLY + uint8_t num_used = 0; + uip_ds6_nbr_t *nbr; + + nbr = nbr_table_head(ds6_neighbors); + while(nbr != NULL) { + nbr = nbr_table_next(ds6_neighbors, nbr); + num_used++; + } + + if(seq_id > 0) { + ANNOTATE("#A r=%d/%d,color=%s,n=%d %d\n", reply, seq_id, + reply == seq_id ? "GREEN" : "RED", uip_ds6_route_num_routes(), num_used); + } +#endif /* SERVER_REPLY */ + seq_id++; PRINTF("DATA send to %d 'Hello %d'\n", server_ipaddr.u8[sizeof(server_ipaddr.u8) - 1], seq_id); @@ -116,7 +140,7 @@ set_global_address(void) { uip_ipaddr_t ipaddr; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); @@ -125,21 +149,21 @@ set_global_address(void) * Obviously the choice made here must also be selected in udp-server.c. * * For correct Wireshark decoding using a sniffer, add the /64 prefix to the 6LowPAN protocol preferences, - * e.g. set Context 0 to aaaa::. At present Wireshark copies Context/128 and then overwrites it. - * (Setting Context 0 to aaaa::1111:2222:3333:4444 will report a 16 bit compressed address of aaaa::1111:22ff:fe33:xxxx) + * e.g. set Context 0 to fd00::. At present Wireshark copies Context/128 and then overwrites it. + * (Setting Context 0 to fd00::1111:2222:3333:4444 will report a 16 bit compressed address of fd00::1111:22ff:fe33:xxxx) * * Note the IPCMV6 checksum verification depends on the correct uncompressed addresses. */ #if 0 /* Mode 1 - 64 bits inline */ - uip_ip6addr(&server_ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1); + uip_ip6addr(&server_ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 1); #elif 1 /* Mode 2 - 16 bits inline */ - uip_ip6addr(&server_ipaddr, 0xaaaa, 0, 0, 0, 0, 0x00ff, 0xfe00, 1); + uip_ip6addr(&server_ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0x00ff, 0xfe00, 1); #else /* Mode 3 - derived from server link-local (MAC) address */ - uip_ip6addr(&server_ipaddr, 0xaaaa, 0, 0, 0, 0x0250, 0xc2ff, 0xfea8, 0xcd1a); //redbee-econotag + uip_ip6addr(&server_ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0x0250, 0xc2ff, 0xfea8, 0xcd1a); //redbee-econotag #endif } /*---------------------------------------------------------------------------*/ @@ -156,8 +180,9 @@ PROCESS_THREAD(udp_client_process, ev, data) PROCESS_PAUSE(); set_global_address(); - - PRINTF("UDP client process started\n"); + + PRINTF("UDP client process started nbr:%d routes:%d\n", + NBR_TABLE_CONF_MAX_NEIGHBORS, UIP_CONF_MAX_ROUTES); print_local_addresses(); @@ -174,6 +199,11 @@ PROCESS_THREAD(udp_client_process, ev, data) PRINTF(" local/remote port %u/%u\n", UIP_HTONS(client_conn->lport), UIP_HTONS(client_conn->rport)); + /* initialize serial line */ + uart1_set_input(serial_line_input_byte); + serial_line_init(); + + #if WITH_COMPOWER powertrace_sniff(POWERTRACE_ON); #endif @@ -184,7 +214,41 @@ PROCESS_THREAD(udp_client_process, ev, data) if(ev == tcpip_event) { tcpip_handler(); } - + + if(ev == serial_line_event_message && data != NULL) { + char *str; + str = data; + if(str[0] == 'r') { + uip_ds6_route_t *r; + uip_ipaddr_t *nexthop; + uip_ds6_defrt_t *defrt; + uip_ipaddr_t *ipaddr; + defrt = NULL; + if((ipaddr = uip_ds6_defrt_choose()) != NULL) { + defrt = uip_ds6_defrt_lookup(ipaddr); + } + if(defrt != NULL) { + PRINTF("DefRT: :: -> %02d", defrt->ipaddr.u8[15]); + PRINTF(" lt:%lu inf:%d\n", stimer_remaining(&defrt->lifetime), + defrt->isinfinite); + } else { + PRINTF("DefRT: :: -> NULL\n"); + } + + for(r = uip_ds6_route_head(); + r != NULL; + r = uip_ds6_route_next(r)) { + nexthop = uip_ds6_route_nexthop(r); + PRINTF("Route: %02d -> %02d", r->ipaddr.u8[15], nexthop->u8[15]); + /* PRINT6ADDR(&r->ipaddr); */ + /* PRINTF(" -> "); */ + /* PRINT6ADDR(nexthop); */ + PRINTF(" lt:%lu\n", r->state.lifetime); + + } + } + } + if(etimer_expired(&periodic)) { etimer_reset(&periodic); ctimer_set(&backoff_timer, SEND_TIME, send_packet, NULL); diff --git a/examples/ipv6/rpl-udp/udp-server.c b/examples/ipv6/rpl-udp/udp-server.c index b735d3bb2..ce87d3b8f 100644 --- a/examples/ipv6/rpl-udp/udp-server.c +++ b/examples/ipv6/rpl-udp/udp-server.c @@ -107,27 +107,28 @@ PROCESS_THREAD(udp_server_process, ev, data) SENSORS_ACTIVATE(button_sensor); - PRINTF("UDP server started\n"); + PRINTF("UDP server started. nbr:%d routes:%d\n", + NBR_TABLE_CONF_MAX_NEIGHBORS, UIP_CONF_MAX_ROUTES); #if UIP_CONF_ROUTER /* The choice of server address determines its 6LoPAN header compression. * Obviously the choice made here must also be selected in udp-client.c. * * For correct Wireshark decoding using a sniffer, add the /64 prefix to the 6LowPAN protocol preferences, - * e.g. set Context 0 to aaaa::. At present Wireshark copies Context/128 and then overwrites it. - * (Setting Context 0 to aaaa::1111:2222:3333:4444 will report a 16 bit compressed address of aaaa::1111:22ff:fe33:xxxx) + * e.g. set Context 0 to fd00::. At present Wireshark copies Context/128 and then overwrites it. + * (Setting Context 0 to fd00::1111:2222:3333:4444 will report a 16 bit compressed address of fd00::1111:22ff:fe33:xxxx) * Note Wireshark's IPCMV6 checksum verification depends on the correct uncompressed addresses. */ #if 0 /* Mode 1 - 64 bits inline */ - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 1); #elif 1 /* Mode 2 - 16 bits inline */ - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0x00ff, 0xfe00, 1); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0x00ff, 0xfe00, 1); #else /* Mode 3 - derived from link local (MAC) address */ - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); #endif @@ -136,7 +137,7 @@ PROCESS_THREAD(udp_server_process, ev, data) if(root_if != NULL) { rpl_dag_t *dag; dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)&ipaddr); - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); rpl_set_prefix(dag, &ipaddr, 64); PRINTF("created a new RPL dag\n"); } else { diff --git a/examples/ipv6/simple-udp-rpl/Makefile b/examples/ipv6/simple-udp-rpl/Makefile index 9cc51e534..72e0cda32 100644 --- a/examples/ipv6/simple-udp-rpl/Makefile +++ b/examples/ipv6/simple-udp-rpl/Makefile @@ -2,7 +2,5 @@ all: broadcast-example unicast-sender unicast-receiver APPS=servreg-hack CONTIKI=../../.. -UIP_CONF_IPV6=1 -CFLAGS+= -DUIP_CONF_IPV6_RPL - +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/ipv6/simple-udp-rpl/broadcast-example.csc b/examples/ipv6/simple-udp-rpl/broadcast-example.csc index 042ea0eb8..72bc733d0 100644 --- a/examples/ipv6/simple-udp-rpl/broadcast-example.csc +++ b/examples/ipv6/simple-udp-rpl/broadcast-example.csc @@ -1,248 +1,248 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/native_gateway - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - /home/user/contikiprojects/sics.se/mobility - [CONTIKI_DIR]/tools/cooja/apps/collect-view - /home/user/nes/papers/smartip-paper/code/cooja_qr - - Simple UDP broadcast example - 0 - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Broadcast example - [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/broadcast-example.c - make broadcast-example.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/broadcast-example.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 64.1956818968534 - 28.591062627059372 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 51.81261061627534 - 24.647047255346667 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 9.068527629624546 - 46.26817786392282 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 87.5626508274206 - 4.896101751816129 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 55.15853460164762 - 3.4681662067903796 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 99.33682438963966 - 49.73072195748186 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 61.26294736288044 - 61.845254356789646 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 7 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 70.4693668755668 - 52.43101713632271 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 8 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 33.5789440978246 - 48.10557568631877 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 9 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 62.6079314243491 - 76.96581640898913 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 10 - - sky1 - - - - org.contikios.cooja.plugins.SimControl - 318 - 3 - 192 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 2.9205864417411154 0.0 0.0 2.9205864417411154 -13.303600659817928 3.5428004585568913 - - 300 - 2 - 300 - 1122 - 0 - - - org.contikios.cooja.plugins.LogListener - - - - 1422 - 0 - 236 - -1 - 302 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - - - 125 - 500.0 - - 1422 - 1 - 190 - 0 - 539 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/native_gateway + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + /home/user/contikiprojects/sics.se/mobility + [CONTIKI_DIR]/tools/cooja/apps/collect-view + /home/user/nes/papers/smartip-paper/code/cooja_qr + + Simple UDP broadcast example + 0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Broadcast example + [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/broadcast-example.c + make broadcast-example.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/broadcast-example.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 64.1956818968534 + 28.591062627059372 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 51.81261061627534 + 24.647047255346667 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 9.068527629624546 + 46.26817786392282 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 87.5626508274206 + 4.896101751816129 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 55.15853460164762 + 3.4681662067903796 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 99.33682438963966 + 49.73072195748186 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 61.26294736288044 + 61.845254356789646 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 70.4693668755668 + 52.43101713632271 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 33.5789440978246 + 48.10557568631877 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 62.6079314243491 + 76.96581640898913 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky1 + + + + org.contikios.cooja.plugins.SimControl + 318 + 3 + 192 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 2.9205864417411154 0.0 0.0 2.9205864417411154 -13.303600659817928 3.5428004585568913 + + 300 + 2 + 300 + 1122 + 0 + + + org.contikios.cooja.plugins.LogListener + + + + 1422 + 0 + 236 + -1 + 302 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + + + 125 + 500.0 + + 1422 + 1 + 190 + 0 + 539 + + + diff --git a/examples/ipv6/simple-udp-rpl/unicast-example.csc b/examples/ipv6/simple-udp-rpl/unicast-example.csc index 08de63603..60bd834bb 100644 --- a/examples/ipv6/simple-udp-rpl/unicast-example.csc +++ b/examples/ipv6/simple-udp-rpl/unicast-example.csc @@ -1,287 +1,287 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/native_gateway - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - /home/user/contikiprojects/sics.se/mobility - [CONTIKI_DIR]/tools/cooja/apps/collect-view - /home/user/nes/papers/smartip-paper/code/cooja_qr - - Simple UDP unicast example - 0 - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - UDP receiver - [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/unicast-receiver.c - make unicast-receiver.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/unicast-receiver.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - sky2 - UDP sender - [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/unicast-sender.c - make unicast-sender.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/unicast-sender.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 82.45117687053667 - 90.0660093026363 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 44.53120632368774 - 89.83566130147413 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 91.76407203945963 - 8.764533976596468 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 10.771554112657956 - 16.155558894723033 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 40.99108749529099 - 33.68910640819968 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 49.762281669516085 - 15.219756237459913 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 26.209078576184762 - 97.71885344901867 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 7 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 96.30596045236783 - 3.353548431613529 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 8 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 52.22023117695779 - 56.516553603970586 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 9 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 57.92282771739404 - 34.17317501704098 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 10 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 3.8628214275088335 - 52.90298303308778 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 11 - - sky2 - - - - org.contikios.cooja.plugins.SimControl - 318 - 3 - 192 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 2.3409990660057263 0.0 0.0 2.3409990660057263 27.752487588138713 2.6948007992423 - - 300 - 2 - 300 - 1122 - 0 - - - org.contikios.cooja.plugins.LogListener - - - - 1422 - 1 - 239 - 0 - 293 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - - - 125 - 500.0 - - 1422 - 0 - 198 - 0 - 531 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/native_gateway + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + /home/user/contikiprojects/sics.se/mobility + [CONTIKI_DIR]/tools/cooja/apps/collect-view + /home/user/nes/papers/smartip-paper/code/cooja_qr + + Simple UDP unicast example + 0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + UDP receiver + [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/unicast-receiver.c + make unicast-receiver.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/unicast-receiver.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + sky2 + UDP sender + [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/unicast-sender.c + make unicast-sender.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/unicast-sender.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 82.45117687053667 + 90.0660093026363 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 44.53120632368774 + 89.83566130147413 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 91.76407203945963 + 8.764533976596468 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 10.771554112657956 + 16.155558894723033 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 40.99108749529099 + 33.68910640819968 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 49.762281669516085 + 15.219756237459913 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 26.209078576184762 + 97.71885344901867 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 96.30596045236783 + 3.353548431613529 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 52.22023117695779 + 56.516553603970586 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 57.92282771739404 + 34.17317501704098 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 3.8628214275088335 + 52.90298303308778 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 11 + + sky2 + + + + org.contikios.cooja.plugins.SimControl + 318 + 3 + 192 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 2.3409990660057263 0.0 0.0 2.3409990660057263 27.752487588138713 2.6948007992423 + + 300 + 2 + 300 + 1122 + 0 + + + org.contikios.cooja.plugins.LogListener + + + + 1422 + 1 + 239 + 0 + 293 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + + + 125 + 500.0 + + 1422 + 0 + 198 + 0 + 531 + + + diff --git a/examples/ipv6/simple-udp-rpl/unicast-receiver.c b/examples/ipv6/simple-udp-rpl/unicast-receiver.c index 1100886b4..7c6205dab 100644 --- a/examples/ipv6/simple-udp-rpl/unicast-receiver.c +++ b/examples/ipv6/simple-udp-rpl/unicast-receiver.c @@ -80,7 +80,7 @@ set_global_address(void) int i; uint8_t state; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); @@ -109,7 +109,7 @@ create_rpl_dag(uip_ipaddr_t *ipaddr) rpl_set_root(RPL_DEFAULT_INSTANCE, ipaddr); dag = rpl_get_any_dag(); - uip_ip6addr(&prefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); rpl_set_prefix(dag, &prefix, 64); PRINTF("created a new RPL dag\n"); } else { diff --git a/examples/ipv6/simple-udp-rpl/unicast-sender.c b/examples/ipv6/simple-udp-rpl/unicast-sender.c index 60cb91204..f441ec728 100644 --- a/examples/ipv6/simple-udp-rpl/unicast-sender.c +++ b/examples/ipv6/simple-udp-rpl/unicast-sender.c @@ -78,7 +78,7 @@ set_global_address(void) int i; uint8_t state; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); diff --git a/examples/ipv6/sky-websense/Makefile b/examples/ipv6/sky-websense/Makefile index 21fee6e7c..7096128a4 100644 --- a/examples/ipv6/sky-websense/Makefile +++ b/examples/ipv6/sky-websense/Makefile @@ -2,9 +2,6 @@ all: sky-websense CONTIKI=../../.. -UIP_CONF_IPV6=1 -CFLAGS+= -DUIP_CONF_IPV6_RPL - APPS += webbrowser CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" @@ -12,13 +9,14 @@ CONTIKI_SOURCEFILES += wget.c PROJECTDIRS += ../rpl-border-router PROJECT_SOURCEFILES += httpd-simple.c +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include $(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c (cd $(CONTIKI)/tools && $(MAKE) tunslip6) connect-router: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + sudo $(CONTIKI)/tools/tunslip6 fd00::1/64 connect-router-cooja: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 fd00::1/64 diff --git a/examples/ipv6/sky-websense/README.md b/examples/ipv6/sky-websense/README.md index 64e566b17..ab644f887 100644 --- a/examples/ipv6/sky-websense/README.md +++ b/examples/ipv6/sky-websense/README.md @@ -17,8 +17,8 @@ To test the example in COOJA under Linux make connect-router-cooja 3. You should now be able to browse to the nodes using your web browser: - Router: http://[aaaa::0212:7401:0001:0101]/ - Node 2: http://[aaaa::0212:7402:0002:0202]/ + Router: http://[fd00::0212:7401:0001:0101]/ + Node 2: http://[fd00::0212:7402:0002:0202]/ To run the example on real nodes under Linux diff --git a/examples/ipv6/sky-websense/example-sky-websense.csc b/examples/ipv6/sky-websense/example-sky-websense.csc index 53696c5f2..f226357e1 100644 --- a/examples/ipv6/sky-websense/example-sky-websense.csc +++ b/examples/ipv6/sky-websense/example-sky-websense.csc @@ -1,207 +1,207 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - - Sky Websense with RPL router - 0 - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - skyweb - Sky Websense - [CONTIKI_DIR]/examples/ipv6/sky-websense/sky-websense.c - make sky-websense.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/sky-websense/sky-websense.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - org.contikios.cooja.interfaces.Position - 62.239287566073514 - 34.43810269527116 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - skyweb - - - - - org.contikios.cooja.interfaces.Position - 56.71945435107925 - 20.293530081848317 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - skyweb - - - - - org.contikios.cooja.interfaces.Position - 75.34889145168493 - 24.43340499309403 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - skyweb - - - - - org.contikios.cooja.interfaces.Position - 92.59837024854205 - 38.57797760651687 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - skyweb - - - - - org.contikios.cooja.interfaces.Position - 47.68359039801751 - 47.26544238238854 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - skyweb - - - - org.contikios.cooja.plugins.SimControl - 259 - 4 - 179 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 2.898638306051894 0.0 0.0 2.898638306051894 -68.40918308040007 -27.82360366026197 - - 258 - 2 - 209 - 0 - 178 - - - org.contikios.cooja.plugins.LogListener - - - - 1024 - 3 - 311 - 0 - 385 - - - org.contikios.cooja.plugins.RadioLogger - - 150 - - - 769 - 0 - 342 - 255 - -1 - - - SerialSocketServer - 0 - 422 - 1 - 74 - 601 - 310 - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + + Sky Websense with RPL router + 0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + skyweb + Sky Websense + [CONTIKI_DIR]/examples/ipv6/sky-websense/sky-websense.c + make sky-websense.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/sky-websense/sky-websense.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + org.contikios.cooja.interfaces.Position + 62.239287566073514 + 34.43810269527116 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + skyweb + + + + + org.contikios.cooja.interfaces.Position + 56.71945435107925 + 20.293530081848317 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + skyweb + + + + + org.contikios.cooja.interfaces.Position + 75.34889145168493 + 24.43340499309403 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + skyweb + + + + + org.contikios.cooja.interfaces.Position + 92.59837024854205 + 38.57797760651687 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + skyweb + + + + + org.contikios.cooja.interfaces.Position + 47.68359039801751 + 47.26544238238854 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + skyweb + + + + org.contikios.cooja.plugins.SimControl + 259 + 4 + 179 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.898638306051894 0.0 0.0 2.898638306051894 -68.40918308040007 -27.82360366026197 + + 258 + 2 + 209 + 0 + 178 + + + org.contikios.cooja.plugins.LogListener + + + + 1024 + 3 + 311 + 0 + 385 + + + org.contikios.cooja.plugins.RadioLogger + + 150 + + + 769 + 0 + 342 + 255 + -1 + + + org.contikios.cooja.serialsocket.SerialSocketServer + 0 + 422 + 1 + 74 + 601 + 310 + + diff --git a/examples/ipv6/sky-websense/websense-remote.c b/examples/ipv6/sky-websense/websense-remote.c index 75737b484..76fc7d0a7 100644 --- a/examples/ipv6/sky-websense/websense-remote.c +++ b/examples/ipv6/sky-websense/websense-remote.c @@ -44,13 +44,13 @@ #include /* The address of the server to register the services for this node */ -#define SERVER "[aaaa::1]" +#define SERVER "[fd00::1]" /* This command registers two services (/0 and /1) to turn the leds on or off */ #define REGISTER_COMMAND "/r?p=0&d=Turn%20off%20leds&p=1&d=Turn%20on%20leds" /* The address of the other node to control */ -#define OTHER_NODE "[aaaa::1]" +#define OTHER_NODE "[fd00::1]" /* The commands to send to the other node */ #define SET_LEDS_ON "/1" diff --git a/examples/ipv6/slip-radio/Makefile b/examples/ipv6/slip-radio/Makefile index 5456466ab..9d6f8ca88 100644 --- a/examples/ipv6/slip-radio/Makefile +++ b/examples/ipv6/slip-radio/Makefile @@ -8,9 +8,6 @@ endif CONTIKI=../../.. -UIP_CONF_IPV6=1 -UIP_CONF_RPL=0 - #linker optimizations SMALL=1 @@ -26,4 +23,6 @@ ifeq ($(TARGET),econotag) PROJECT_SOURCEFILES += slip-radio-mc1322x.c endif +CONTIKI_WITH_RPL = 0 +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/ipv6/slip-radio/README.md b/examples/ipv6/slip-radio/README.md new file mode 100644 index 000000000..5e3e0a5f6 --- /dev/null +++ b/examples/ipv6/slip-radio/README.md @@ -0,0 +1,6 @@ +This project is intended to run on a mode that is connected to a native host system +by SLIP. The SLIP is really SERIAL LINE 15.4, as this just turns the mote into a smart +radio, running the RPL and 6lowpan stack on the Host. This goes with native-border-router. + + + diff --git a/examples/ipv6/slip-radio/no-framer.c b/examples/ipv6/slip-radio/no-framer.c index afbaffb65..69f4b7e98 100644 --- a/examples/ipv6/slip-radio/no-framer.c +++ b/examples/ipv6/slip-radio/no-framer.c @@ -76,6 +76,13 @@ is_broadcast_addr(uint8_t mode, uint8_t *addr) } /*---------------------------------------------------------------------------*/ static int +hdr_length(void) +{ + /* never adds any header */ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int create(void) { /* nothing extra... */ @@ -102,8 +109,7 @@ parse(void) } packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr); packetbuf_set_attr(PACKETBUF_ATTR_PENDING, frame.fcf.frame_pending); - /* packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, frame.fcf.ack_required);*/ - packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, frame.seq); + packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, frame.seq); PRINTF("15.4-IN: %2X", frame.fcf.frame_type); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); @@ -116,5 +122,7 @@ parse(void) } /*---------------------------------------------------------------------------*/ const struct framer no_framer = { - create, parse + hdr_length, + create, + parse }; diff --git a/examples/ipv6/slip-radio/project-conf.h b/examples/ipv6/slip-radio/project-conf.h index 4a2950c59..66cd61cbc 100644 --- a/examples/ipv6/slip-radio/project-conf.h +++ b/examples/ipv6/slip-radio/project-conf.h @@ -39,9 +39,6 @@ #undef UIP_CONF_ROUTER #define UIP_CONF_ROUTER 0 -#undef UIP_CONF_IPV6_RPL -#define UIP_CONF_IPV6_RPL 0 - #define CMD_CONF_OUTPUT slip_radio_cmd_output /* add the cmd_handler_cc2420 + some sensors if TARGET_SKY */ diff --git a/examples/ipv6/slip-radio/slip-radio-rf230.c b/examples/ipv6/slip-radio/slip-radio-rf230.c index 1f254386d..67c3ecc33 100644 --- a/examples/ipv6/slip-radio/slip-radio-rf230.c +++ b/examples/ipv6/slip-radio/slip-radio-rf230.c @@ -1,72 +1,72 @@ -/* - * Copyright (c) 2011, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - * Sets up some commands for the RF230 radio. - */ - -#include "contiki.h" -#include "cmd.h" - -#include "radio/rf230/radio.h" -#include "radio/rf230bb/rf230bb.h" - - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) -#define PRINTSHORT(FORMAT,args...) printf_P(PSTR(FORMAT),##args) -#else -#define PRINTF(...) -#define PRINTSHORT(...) -#endif - -int -cmd_handler_rf230(const uint8_t *data, int len) -{ - if(data[0] == '!') { - if(data[1] == 'C') { - PRINTF("CMD: Setting channel: %d\n", data[2]); - rf230_set_channel(data[2]); - return 1; - } - } else if(data[0] == '?') { - if(data[1] == 'C') { - uint8_t buf[4]; - PRINTF("CMD: Getting channel: %d\n", data[2]); - buf[0] = '!'; - buf[1] = 'C'; - buf[2] = rf230_get_channel(); - cmd_send(buf, 3); - return 1; - } - } - return 0; -} +/* + * Copyright (c) 2011, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * Sets up some commands for the RF230 radio. + */ + +#include "contiki.h" +#include "cmd.h" + +#include "radio/rf230/radio.h" +#include "radio/rf230bb/rf230bb.h" + + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#define PRINTSHORT(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTF(...) +#define PRINTSHORT(...) +#endif + +int +cmd_handler_rf230(const uint8_t *data, int len) +{ + if(data[0] == '!') { + if(data[1] == 'C') { + PRINTF("CMD: Setting channel: %d\n", data[2]); + rf230_set_channel(data[2]); + return 1; + } + } else if(data[0] == '?') { + if(data[1] == 'C') { + uint8_t buf[4]; + PRINTF("CMD: Getting channel: %d\n", data[2]); + buf[0] = '!'; + buf[1] = 'C'; + buf[2] = rf230_get_channel(); + cmd_send(buf, 3); + return 1; + } + } + return 0; +} diff --git a/examples/ipv6/slip-radio/slip-radio.c b/examples/ipv6/slip-radio/slip-radio.c index 5223d57a6..b20e559ec 100644 --- a/examples/ipv6/slip-radio/slip-radio.c +++ b/examples/ipv6/slip-radio/slip-radio.c @@ -125,7 +125,7 @@ slip_radio_cmd_handler(const uint8_t *data, int len) /* parse frame before sending to get addresses, etc. */ no_framer.parse(); - NETSTACK_MAC.send(packet_sent, &packet_ids[packet_pos]); + NETSTACK_LLSEC.send(packet_sent, &packet_ids[packet_pos]); packet_pos++; if(packet_pos >= sizeof(packet_ids)) { @@ -162,7 +162,7 @@ slip_input_callback(void) { PRINTF("SR-SIN: %u '%c%c'\n", uip_len, uip_buf[0], uip_buf[1]); cmd_input(uip_buf, uip_len); - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ static void diff --git a/examples/irc-80col/Makefile b/examples/irc-80col/Makefile new file mode 100644 index 000000000..bad574e70 --- /dev/null +++ b/examples/irc-80col/Makefile @@ -0,0 +1,8 @@ +CONTIKI_PROJECT = irc-client +all: $(CONTIKI_PROJECT) + +APPS = irc + +CONTIKI = ../.. +CONTIKI_WITH_IPV4 = 1 +include $(CONTIKI)/Makefile.include diff --git a/examples/irc-80col/Makefile.apple2enh.defines b/examples/irc-80col/Makefile.apple2enh.defines new file mode 100644 index 000000000..71fb932e2 --- /dev/null +++ b/examples/irc-80col/Makefile.apple2enh.defines @@ -0,0 +1 @@ +DEFINES = WITH_CLIENT,WITH_DNS,WITH_80COL,WITH_GUI,WITH_MOUSE,WITH_PFS diff --git a/examples/irc-80col/Makefile.atarixl.defines b/examples/irc-80col/Makefile.atarixl.defines new file mode 100644 index 000000000..962070b58 --- /dev/null +++ b/examples/irc-80col/Makefile.atarixl.defines @@ -0,0 +1 @@ +DEFINES = WITH_CLIENT,WITH_DNS,WITH_80COL,WITH_GUI,WITH_MOUSE diff --git a/examples/irc-80col/Makefile.c128.defines b/examples/irc-80col/Makefile.c128.defines new file mode 100644 index 000000000..32efc32ba --- /dev/null +++ b/examples/irc-80col/Makefile.c128.defines @@ -0,0 +1 @@ +DEFINES = WITH_CLIENT,WITH_DNS,WITH_80COL,WITH_GUI,WITH_PFS,MTU_SIZE=900 diff --git a/examples/irc-80col/Makefile.c64.defines b/examples/irc-80col/Makefile.c64.defines new file mode 100644 index 000000000..71fb932e2 --- /dev/null +++ b/examples/irc-80col/Makefile.c64.defines @@ -0,0 +1 @@ +DEFINES = WITH_CLIENT,WITH_DNS,WITH_80COL,WITH_GUI,WITH_MOUSE,WITH_PFS diff --git a/examples/irc-80col/Makefile.native.defines b/examples/irc-80col/Makefile.native.defines new file mode 100644 index 000000000..1b5caf200 --- /dev/null +++ b/examples/irc-80col/Makefile.native.defines @@ -0,0 +1 @@ +DEFINES = WITH_GUI diff --git a/examples/irc-80col/Makefile.win32.defines b/examples/irc-80col/Makefile.win32.defines new file mode 100644 index 000000000..1b5caf200 --- /dev/null +++ b/examples/irc-80col/Makefile.win32.defines @@ -0,0 +1 @@ +DEFINES = WITH_GUI diff --git a/examples/irc-80col/irc-client.c b/examples/irc-80col/irc-client.c new file mode 100644 index 000000000..da28f9440 --- /dev/null +++ b/examples/irc-80col/irc-client.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#include "contiki-net.h" +#include "irc.h" + +/*---------------------------------------------------------------------------*/ +AUTOSTART_PROCESSES(&irc_process); +/*---------------------------------------------------------------------------*/ diff --git a/examples/irc/Makefile b/examples/irc/Makefile index 842bbb0b1..bad574e70 100644 --- a/examples/irc/Makefile +++ b/examples/irc/Makefile @@ -4,4 +4,5 @@ all: $(CONTIKI_PROJECT) APPS = irc CONTIKI = ../.. +CONTIKI_WITH_IPV4 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/irc/Makefile.c128.defines b/examples/irc/Makefile.c128.defines index 688d85113..2924f4709 100644 --- a/examples/irc/Makefile.c128.defines +++ b/examples/irc/Makefile.c128.defines @@ -1 +1 @@ -DEFINES = WITH_CLIENT,WITH_DNS,WITH_GUI,WITH_PFS +DEFINES = WITH_CLIENT,WITH_DNS,WITH_GUI,WITH_PFS,MTU_SIZE=900 diff --git a/examples/jn516x/README.md b/examples/jn516x/README.md new file mode 100644 index 000000000..0a7c6bb9e --- /dev/null +++ b/examples/jn516x/README.md @@ -0,0 +1,5 @@ +Examples for the JN516x platform. +* dr1175: simple Contiki application for the DR1175 evaluation board. Prints out sensor values periodically. +* rime: simple Rime example. Works with ContikiMAC (default) or NullRDC +* RPL: RPL examples, including border router, simple node, and coap resources. More information under rpl/README.md +* tsch: Examples of applications using TSCH \ No newline at end of file diff --git a/examples/jn516x/dr1175-sensors/Makefile b/examples/jn516x/dr1175-sensors/Makefile new file mode 100644 index 000000000..3fbf3a246 --- /dev/null +++ b/examples/jn516x/dr1175-sensors/Makefile @@ -0,0 +1,12 @@ +CONTIKI=../../.. +CONTIKI_PROJECT = node +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +TARGET ?= jn516x +JN516x_WITH_DR1175 = 1 + +CONTIKI_WITH_RIME = 1 + +all: $(CONTIKI_PROJECT) + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/dr1175-sensors/README.md b/examples/jn516x/dr1175-sensors/README.md new file mode 100644 index 000000000..0b49024c2 --- /dev/null +++ b/examples/jn516x/dr1175-sensors/README.md @@ -0,0 +1,2 @@ +Sensor test for DR1175 evaluation board (light + temp/humidity). +Reads and prints out various sensor samples every second. diff --git a/examples/jn516x/dr1175-sensors/node.c b/examples/jn516x/dr1175-sensors/node.c new file mode 100644 index 000000000..e30bfea3d --- /dev/null +++ b/examples/jn516x/dr1175-sensors/node.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \author Atis Elsts + * \file + * Sensor test for DR1175 evaluation board (light + temp/humidity). + */ + +#include "contiki.h" + +#include "light-sensor.h" +#include "ht-sensor.h" +#include "leds.h" +#include "leds-extension.h" + +/*---------------------------------------------------------------------------*/ +PROCESS(test_process, "Sensor test process"); +AUTOSTART_PROCESSES(&test_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_process, ev, data) +{ + static struct etimer et; + static uint8_t led_status; + uint8_t r, g, b; + int val; + + PROCESS_BEGIN(); + + puts("initializing sensors..."); + + /* Make sensor active for measuring */ + SENSORS_ACTIVATE(light_sensor); + SENSORS_ACTIVATE(ht_sensor); + + /* Set level for LEDSs */ + leds_set_level(255, LEDS_RED | LEDS_GREEN | LEDS_BLUE | LEDS_WHITE); + + while(1) { + etimer_set(&et, CLOCK_SECOND * 1); + + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + puts("reading sensors..."); + + val = ht_sensor.value(HT_SENSOR_HUM); + printf("humidity: %d\n", val); + + val = ht_sensor.value(HT_SENSOR_TEMP); + printf("temperature: %d\n", val); + + led_status++; + r = ((led_status & 0x1) ? LEDS_RED : 0); + g = ((led_status & 0x2) ? LEDS_GREEN : 0); + b = ((led_status & 0x4) ? LEDS_BLUE : 0); + + leds_toggle((leds_get() ^ (r | g | b)) | LEDS_WHITE); + + puts(""); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/dr1175-sensors/project-conf.h b/examples/jn516x/dr1175-sensors/project-conf.h new file mode 100644 index 000000000..906efff45 --- /dev/null +++ b/examples/jn516x/dr1175-sensors/project-conf.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \author Atis Elsts + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#undef NETSTACK_CONF_RDC +#undef NETSTACK_CONF_FRAMER +#undef NETSTACK_CONF_MAC +#undef NETSTACK_CONF_NETWORK + +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_FRAMER framer_802154 +#define NETSTACK_CONF_MAC csma_driver +#define NETSTACK_CONF_NETWORK rime_driver + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/rime/Makefile b/examples/jn516x/rime/Makefile new file mode 100644 index 000000000..02262937e --- /dev/null +++ b/examples/jn516x/rime/Makefile @@ -0,0 +1,11 @@ +CONTIKI=../../.. +CONTIKI_PROJECT = node +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +TARGET ?= jn516x + +CONTIKI_WITH_RIME = 1 + +all: $(CONTIKI_PROJECT) + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/rime/README.md b/examples/jn516x/rime/README.md new file mode 100644 index 000000000..1f693c6ae --- /dev/null +++ b/examples/jn516x/rime/README.md @@ -0,0 +1 @@ +A simple Rime + ContikiMAC code example. diff --git a/examples/jn516x/rime/node.c b/examples/jn516x/rime/node.c new file mode 100644 index 000000000..dd8fd37b7 --- /dev/null +++ b/examples/jn516x/rime/node.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \author Atis Elsts + * \file + * ContikiMAC + Rime stack test for JN516x platform. + */ + +#include "contiki-conf.h" +#include "net/rime/rime.h" + +#if 0 +#define RX_ADDR1 140 +#define RX_ADDR2 228 +#else +#define RX_ADDR1 7 +#define RX_ADDR2 0 +#endif + +#define MAX_RETRANSMISSIONS 4 + +/*---------------------------------------------------------------------------*/ +PROCESS(unicast_test_process, "ContikiMAC Node"); +AUTOSTART_PROCESSES(&unicast_test_process); + +static void +recv_runicast(struct runicast_conn *c, const linkaddr_t *from, uint8_t seqno) +{ + printf("runicast message received from %d.%d, seqno %d, len %d: '%s'\n", + from->u8[0], from->u8[1], seqno, packetbuf_datalen(), (char *)packetbuf_dataptr()); +} +static void +sent_runicast(struct runicast_conn *c, const linkaddr_t *to, uint8_t retransmissions) +{ + printf("runicast message sent to %d.%d, retransmissions %d\n", + to->u8[0], to->u8[1], retransmissions); +} +static void +timedout_runicast(struct runicast_conn *c, const linkaddr_t *to, uint8_t retransmissions) +{ + printf("runicast message timed out when sending to %d.%d, retransmissions %d\n", + to->u8[0], to->u8[1], retransmissions); +} +static const struct runicast_callbacks runicast_callbacks = { recv_runicast, + sent_runicast, + timedout_runicast }; +static struct runicast_conn runicast; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(unicast_test_process, ev, data) +{ + PROCESS_BEGIN(); + + puts("unicast test start"); + + runicast_open(&runicast, 144, &runicast_callbacks); + + /* Receiver node: do nothing */ + if(linkaddr_node_addr.u8[0] == RX_ADDR1 && + linkaddr_node_addr.u8[1] == RX_ADDR2) { + puts("wait forever"); + } + while(1) { + static struct etimer et; + static int seqno; + + etimer_set(&et, CLOCK_SECOND * 5); + + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + if(linkaddr_node_addr.u8[0] == RX_ADDR1 && + linkaddr_node_addr.u8[1] == RX_ADDR2) { + puts("tick..."); + continue; + } + + if(!runicast_is_transmitting(&runicast)) { + static char buffer[100] = "hello"; + linkaddr_t recv; + + memset(&recv, 0, LINKADDR_SIZE); + packetbuf_copyfrom(buffer, sizeof(buffer)); + recv.u8[0] = RX_ADDR1; + recv.u8[1] = RX_ADDR2; + + printf("%u.%u: sending runicast to address %u.%u\n", + linkaddr_node_addr.u8[0], + linkaddr_node_addr.u8[1], + recv.u8[0], + recv.u8[1]); + + packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, ++seqno); + runicast_send(&runicast, &recv, MAX_RETRANSMISSIONS); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/rime/project-conf.h b/examples/jn516x/rime/project-conf.h new file mode 100644 index 000000000..3a7b0c44c --- /dev/null +++ b/examples/jn516x/rime/project-conf.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \author Atis Elsts + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#undef NETSTACK_CONF_RDC +#undef NETSTACK_CONF_FRAMER +#undef NETSTACK_CONF_MAC +#undef NETSTACK_CONF_NETWORK + +#if 1 +#define NETSTACK_CONF_RDC contikimac_driver +#define NETSTACK_CONF_FRAMER contikimac_framer +#else +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_FRAMER framer_802154 +#endif + +#define NETSTACK_CONF_MAC csma_driver +#define NETSTACK_CONF_NETWORK rime_driver + +#undef UIP_CONF_IPV6 +#define UIP_CONF_IPV6 0 + +#undef MICROMAC_CONF_CHANNEL +#define MICROMAC_CONF_CHANNEL 25 + +#undef MICROMAC_CONF_AUTOACK +#define MICROMAC_CONF_AUTOACK 1 + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/rpl/README.md b/examples/jn516x/rpl/README.md new file mode 100644 index 000000000..fb8cd49b4 --- /dev/null +++ b/examples/jn516x/rpl/README.md @@ -0,0 +1,43 @@ +# HOWTO - Setting up the RPL Border router and other nodes + +In this folder we have a fully functional demonstrator with the components: + +1. **RPL border router**: to start the wireless network and connect it to other networks. +2. and a **wireless node** that acts as a basic RPL node by default (but can optionally be used configured as DAG Root) + +## RICH RPL Border Router + +Setup the UART flow-control mode for the router from border-router/project-conf.h + +* Enable either **HW flow control** +```C +#define UART_HW_FLOW_CTRL 1 +#define UART_XONXOFF_FLOW_CTRL 0 +``` +* or **SW flow control** +```C +#define UART_HW_FLOW_CTRL 0 +#define UART_XONXOFF_FLOW_CTRL 1 +``` +* You can disable both, but it is not recommended. + +Compile and flash a node with the rpl-border-router.jn516x.bin image. Either a USB dongle or a dev-board would work. + +From a Linux terminal, go to `contiki/examples/jn516x/rpl/border-router` and do either +`make connect-router-hw` if you have **HW flow control** +or `make connect-router-sw` if you have **SW flow control** + +This will start a tunnel interface (tun0) on the host machine. +All traffic towards our network (prefix fd00::1/64) will now be routed to the border router. + +## RPL Node + +The directory contiki-private/examples/jn516x/rpl/node contains a basic RICH node running TSCH and RPL. +You can compile and program more NXP nodes to run this, forming a larger network. +You should be able to ping the nodes (you can obtain their IPv6 address either directly from their log output +or by enabling DEBUG output in rpl-icmp6.c and looking at DAO prefixes being added. + +## RPL+CoAP Nodes + +coap-*-node are example nodes that expose their sensors as CoAP resources. See README.md files from the sub-directories +for more details. diff --git a/examples/jn516x/rpl/border-router/Makefile b/examples/jn516x/rpl/border-router/Makefile new file mode 100644 index 000000000..1904e5ce8 --- /dev/null +++ b/examples/jn516x/rpl/border-router/Makefile @@ -0,0 +1,32 @@ +CONTIKI_PROJECT = border-router +all: $(CONTIKI_PROJECT) + +TARGET ?= jn516x + +CONTIKI=../../../.. + +CONTIKI_WITH_IPV6 = 1 + +MODULES += core/net/mac/tsch +PROJECTDIRS += .. ../tools +PROJECT_SOURCEFILES += rpl-tools.c +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +PROJECT_SOURCEFILES += slip-bridge.c slip.c + +ifeq ($(PREFIX),) + PREFIX = fd00::1/64 +endif + +include $(CONTIKI)/Makefile.include + +#using XON/XOFF flow control +connect-router-sw: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -X -B 1000000 $(PREFIX) + +#using hw flow control +connect-router-hw: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -H -B 1000000 $(PREFIX) + +#using no flow control +connect-router-no: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -B 1000000 $(PREFIX) diff --git a/examples/jn516x/rpl/border-router/README.md b/examples/jn516x/rpl/border-router/README.md new file mode 100644 index 000000000..c2af3f3b6 --- /dev/null +++ b/examples/jn516x/rpl/border-router/README.md @@ -0,0 +1,10 @@ +A RPL border router. +To indicate the hardware target for the border router, add one of the following +options in the command line: +If rpl-border-router runs on dongle: +JN516x_WITH_DONGLE=1 +If rpl-border-router runs on DR1174: +JN516x_WITH_DR1174=1 +If building for a new platform, first execute : make clean + +See ../README.md for more. \ No newline at end of file diff --git a/examples/jn516x/rpl/border-router/border-router.c b/examples/jn516x/rpl/border-router/border-router.c new file mode 100644 index 000000000..a55a3241e --- /dev/null +++ b/examples/jn516x/rpl/border-router/border-router.c @@ -0,0 +1,106 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#include "contiki.h" +#include "dev/slip.h" +#include "net/rpl/rpl.h" +#include "tools/rpl-tools.h" + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +static uip_ipaddr_t prefix; +static uint8_t prefix_set; + +PROCESS(border_router_process, "Border router process"); + +AUTOSTART_PROCESSES(&border_router_process); + +/*---------------------------------------------------------------------------*/ +void +request_prefix(void) +{ + /* mess up uip_buf with a dirty request... */ + uip_buf[0] = '?'; + uip_buf[1] = 'P'; +/* uip_buf[2] = '\n'; */ + uip_len = 2; + slip_send(); + uip_len = 0; +} +/*---------------------------------------------------------------------------*/ +void +set_prefix_64(uip_ipaddr_t *prefix_64) +{ + memcpy(&prefix, prefix_64, 16); + prefix_set = 1; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(border_router_process, ev, data) +{ + static struct etimer et; + + PROCESS_BEGIN(); + +/* While waiting for the prefix to be sent through the SLIP connection, the future + * border router can join an existing DAG as a parent or child, or acquire a default + * router that will later take precedence over the SLIP fallback interface. + * Prevent that by turning the radio off until we are initialized as a DAG root. + */ + prefix_set = 0; + + PROCESS_PAUSE(); + + PRINTF("RPL-Border router started\n"); + + /* Request prefix until it has been received */ + while(!prefix_set) { + etimer_set(&et, CLOCK_SECOND); + request_prefix(); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + PRINTF("Waiting for prefix\n"); + } + + PRINTF("Obtained prefix: "); + uip_debug_ipaddr_print(&prefix); + PRINTF("\n"); + + rpl_tools_init(&prefix); + + /* Print out routing tables every minute */ + etimer_set(&et, CLOCK_SECOND * 60); + while(1) { + print_network_status(); + PROCESS_YIELD_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/rpl/border-router/project-conf.h b/examples/jn516x/rpl/border-router/project-conf.h new file mode 100644 index 000000000..2489905a6 --- /dev/null +++ b/examples/jn516x/rpl/border-router/project-conf.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \author Simon Duquennoy + */ + +#ifndef BR_PROJECT_CONF_H_ +#define BR_PROJECT_CONF_H_ + +#ifndef UIP_FALLBACK_INTERFACE +#define UIP_FALLBACK_INTERFACE rpl_interface +#endif + +/* Needed for slip-bridge */ +#undef SLIP_BRIDGE_CONF_NO_PUTCHAR +#define SLIP_BRIDGE_CONF_NO_PUTCHAR 0 + +#include "../common-conf.h" + +#endif /* PROJECT_CONF_H_ */ diff --git a/examples/jn516x/rpl/border-router/slip-bridge.c b/examples/jn516x/rpl/border-router/slip-bridge.c new file mode 100644 index 000000000..a2721facd --- /dev/null +++ b/examples/jn516x/rpl/border-router/slip-bridge.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2010, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file + * Slip fallback interface + * \author + * Niclas Finne + * Joakim Eriksson + * Joel Hoglund + * Nicolas Tsiftes + */ + +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "dev/slip.h" +#if CONTIKI_TARGET_JN516X +#include "dev/uart0.h" +#else +#include "dev/uart1.h" +#endif +#include + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +#ifndef BAUD2UBR +#define BAUD2UBR(X) (X) +#endif + +void set_prefix_64(uip_ipaddr_t *); + +static uip_ipaddr_t last_sender; +/*---------------------------------------------------------------------------*/ +static void +slip_input_callback(void) +{ + PRINTF("SIN: %u\n", uip_len); + if(uip_buf[0] == '!') { + PRINTF("Got configuration message of type %c\n", uip_buf[1]); + uip_len = 0; + if(uip_buf[1] == 'P') { + uip_ipaddr_t prefix; + /* Here we set a prefix !!! */ + memset(&prefix, 0, 16); + memcpy(&prefix, &uip_buf[2], 8); + PRINTF("Setting prefix "); + PRINT6ADDR(&prefix); + PRINTF("\n"); + set_prefix_64(&prefix); + } + } else if(uip_buf[0] == '?') { + PRINTF("Got request message of type %c\n", uip_buf[1]); + if(uip_buf[1] == 'M') { + char *hexchar = "0123456789abcdef"; + int j; + /* this is just a test so far... just to see if it works */ + uip_buf[0] = '!'; + for(j = 0; j < 8; j++) { + uip_buf[2 + j * 2] = hexchar[uip_lladdr.addr[j] >> 4]; + uip_buf[3 + j * 2] = hexchar[uip_lladdr.addr[j] & 15]; + } + uip_len = 18; + slip_send(); + } + uip_len = 0; + } + /* Save the last sender received over SLIP to avoid bouncing the + packet back if no route is found */ + uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr); +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + slip_arch_init(BAUD2UBR(115200)); + process_start(&slip_process, NULL); + slip_set_input_callback(slip_input_callback); +} +/*---------------------------------------------------------------------------*/ +static int +output(void) +{ + if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) { + /* Do not bounce packets back over SLIP if the packet was received + over SLIP */ + PRINTF("slip-bridge: Destination off-link but no route src="); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF(" dst="); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("\n"); + } else { + PRINTF("SUT: %u\n", uip_len); + slip_send(); + } + return 0; +} +/*---------------------------------------------------------------------------*/ +#if !SLIP_BRIDGE_CONF_NO_PUTCHAR +#undef putchar +int +putchar(int c) +{ +#define SLIP_END 0300 + static char debug_frame = 0; + + if(!debug_frame) { /* Start of debug output */ + slip_arch_writeb(SLIP_END); + slip_arch_writeb('\r'); /* Type debug line == '\r' */ + debug_frame = 1; + } + + /* Need to also print '\n' because for example COOJA will not show + any output before line end */ + slip_arch_writeb((char)c); + + /* + * Line buffered output, a newline marks the end of debug output and + * implicitly flushes debug output. + */ + if(c == '\n') { + slip_arch_writeb(SLIP_END); + debug_frame = 0; + } + return c; +} +#endif +/*---------------------------------------------------------------------------*/ +const struct uip_fallback_interface rpl_interface = { + init, output +}; +/*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/rpl/coap-dongle-node/Makefile b/examples/jn516x/rpl/coap-dongle-node/Makefile new file mode 100644 index 000000000..747331845 --- /dev/null +++ b/examples/jn516x/rpl/coap-dongle-node/Makefile @@ -0,0 +1,22 @@ +CONTIKI_PROJECT = dongle-node +all: $(CONTIKI_PROJECT) + +TARGET ?= jn516x +JN516x_WITH_DONGLE = 1 + +CONTIKI=../../../.. + +CONTIKI_WITH_IPV6 = 1 + +MODULES += core/net/mac/tsch +PROJECTDIRS += .. ../tools +PROJECT_SOURCEFILES += rpl-tools.c +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +CFLAGS += -DWITH_COAP +CFLAGS += -DUIP_CONF_TCP=0 +APPS = json +APPS += er-coap +APPS += rest-engine + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/rpl/coap-dongle-node/README.md b/examples/jn516x/rpl/coap-dongle-node/README.md new file mode 100644 index 000000000..2a4ed6183 --- /dev/null +++ b/examples/jn516x/rpl/coap-dongle-node/README.md @@ -0,0 +1,16 @@ +dongle-node is an example of a RICH node containing a JN516x microcontroller on a USB dongle. +The dongle is part of the NXP JN516x Evaluation Kit (see http://www.nxp.com/documents/leaflet/75017368.pdf) +The dongle-node connects to the network in the same way as described in `examples\jn5168/rpl/README.md` + +The dongle contains 2 LEDs that are available as a CoAP resource. They can be accessed via a CoAP client at the IPv6 interface +of the border router (e.g. via Copper plug-in on Firefox). +The following list gives an overview of the resources: + +URI Description +--- ----------- +Dongle\LED-toggle When doing a PUT/POST method on this resource (no payload needed), the LEDs will run through + the following states with wrap-around: + - GREEN LED on + - RED LED on + - All LEDs off + - RED and GREEN LED alternatively on with 1 sec period time diff --git a/examples/jn516x/rpl/coap-dongle-node/dongle-node.c b/examples/jn516x/rpl/coap-dongle-node/dongle-node.c new file mode 100644 index 000000000..233834610 --- /dev/null +++ b/examples/jn516x/rpl/coap-dongle-node/dongle-node.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "tools/rpl-tools.h" +#include "rest-engine.h" +#include "sys/ctimer.h" +#include +#include "dev/leds.h" + +static void ct_callback(void *ptr); +static void put_post_led_toggle_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +static char content[REST_MAX_CHUNK_SIZE]; +static int content_len = 0; +static struct ctimer ct; + +#define CONTENT_PRINTF(...) { if(content_len < sizeof(content)) { content_len += snprintf(content + content_len, sizeof(content) - content_len, __VA_ARGS__); } } + +/* On dongle, LEDs are connected anti-parallel to DIO pins. */ + +#define TOGGLE_TIME CLOCK_SECOND +/*---------------------------------------------------------------------------*/ +PROCESS(start_app, "START_APP"); +AUTOSTART_PROCESSES(&start_app); +/*---------------------------------------------------------------------------*/ + +/* Call back for led toggle timer to toggle leds */ +static void +ct_callback(void *ptr) +{ + static uint8 toggle_status = 0; + if(toggle_status) { + leds_set(LEDS_RED); + } else { + leds_set(LEDS_GREEN); + } ctimer_restart(&ct); + toggle_status ^= 0x01; +} +/*********** CoAP sensor/ resource ************************************************/ +RESOURCE(resource_led_toggle, + "title=\"Led_toggle\"", + NULL, + put_post_led_toggle_handler, + put_post_led_toggle_handler, + NULL); +static void +put_post_led_toggle_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + static int led_state = 0; + unsigned int accept = -1; + + /* Given the way the LEDs are connected to the DIO ports, the LEDs are controlled via direct DIO access. */ + content_len = 0; + switch(led_state) { + case (0): + ctimer_stop(&ct); + leds_set(LEDS_GREEN); /* Only LEDS_GREEN on */ + CONTENT_PRINTF("Message from resource: Green LED on"); + led_state = 1; + break; + case (1): + leds_set(LEDS_RED); /* Only LEDS_RED on */ + CONTENT_PRINTF("Message from resource: Red LED on"); + led_state = 2; + break; + case (2): + leds_set(0); /* All LEDS off */ + CONTENT_PRINTF("Message from resource: All LEDs off"); + led_state = 3; + break; + case 3: + /* Both leds toggle */ + CONTENT_PRINTF("Message from resource: LEDs toggle"); + ctimer_restart(&ct); + led_state = 0; + default: + break; + } + /* Return message */ + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(start_app, ev, data) +{ + PROCESS_BEGIN(); + static int is_coordinator = 0; + + /* Switch off dongle leds */ + + /* Initialise ct timer, but don't let it run yet */ + ctimer_set(&ct, TOGGLE_TIME, ct_callback, NULL); + ctimer_stop(&ct); + + /* Start net stack */ + if(is_coordinator) { + uip_ipaddr_t prefix; + uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); + rpl_tools_init(&prefix); + } else { + rpl_tools_init(NULL); + } printf("Starting RPL node\n"); + + rest_init_engine(); + rest_activate_resource(&resource_led_toggle, "Dongle/LED-toggle"); + + PROCESS_END(); +} diff --git a/examples/jn516x/rpl/coap-dongle-node/project-conf.h b/examples/jn516x/rpl/coap-dongle-node/project-conf.h new file mode 100644 index 000000000..4c2ecd648 --- /dev/null +++ b/examples/jn516x/rpl/coap-dongle-node/project-conf.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \author Simon Duquennoy + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#include "../common-conf.h" + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/rpl/coap-dr1175-node/Makefile b/examples/jn516x/rpl/coap-dr1175-node/Makefile new file mode 100644 index 000000000..d00fc9b9c --- /dev/null +++ b/examples/jn516x/rpl/coap-dr1175-node/Makefile @@ -0,0 +1,22 @@ +CONTIKI_PROJECT = dr1175-node +all: $(CONTIKI_PROJECT) + +TARGET ?= jn516x +JN516x_WITH_DR1175 = 1 + +CONTIKI=../../../.. + +CONTIKI_WITH_IPV6 = 1 + +MODULES += core/net/mac/tsch +PROJECTDIRS += .. ../tools +PROJECT_SOURCEFILES += rpl-tools.c +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +CFLAGS += -DWITH_COAP +CFLAGS += -DUIP_CONF_TCP=0 +APPS = json +APPS += er-coap +APPS += rest-engine + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/rpl/coap-dr1175-node/README.md b/examples/jn516x/rpl/coap-dr1175-node/README.md new file mode 100644 index 000000000..6be19ab6d --- /dev/null +++ b/examples/jn516x/rpl/coap-dr1175-node/README.md @@ -0,0 +1,24 @@ +dr1175-node is an example of a RICH node containing a JN516x microcontroller on a DR1174 baseboard. +A DR1175 shield is mounted on the baseboard. +The boards are part of the NXP JN516x Evaluation Kit (see http://www.nxp.com/documents/leaflet/75017368.pdf) +The dr1175-node connects to the network in the same way as described in `examples\jn5168/rpl/README.md` + +The resources on the DR1175 are available as CoAP resources. They can be accessed via a CoAP client at the IPv6 interface +of the border router (e.g. via Copper plug-in on Firefox). +The following list gives an overview of the resources: + +URI Description +--- ----------- +DR1175\AllSensors This is an observable resource that shows the status of the humidity, light and temperature sensor. + The resource is automatically updated when a change in the value of the sensor data occurs. +DR1175\ColorLED\RGBValue With this resource, the level and color of the RGB LED can be set. + The output is set as 3 numbers (R, G and B) from 0..255, separated with a space +DR1175\Humidity\Unit This resource will return the unit of the humidity sensor +DR1175\Humidity\Value This resource will return the value of the humidity sensor +DR1175\LightSensor\Unit This resource will return the unit of the light sensor +DR1175\LightSensor\Value This resource will return the value of the light sensor +DR1175\Temperature\Unit This resource will return the unit of the temperature sensor +DR1175\Temperature\Value This resource will return the value of the temperature sensor +DR1175\WhiteLED This resource will set the level of 3 white power LEDs. Level is from 0..255 +DR1174\D3On1174 This resource control LED D3 on the base board +DR1174\D6On1174 This resource control LED D6 on the base board \ No newline at end of file diff --git a/examples/jn516x/rpl/coap-dr1175-node/dr1175-node.c b/examples/jn516x/rpl/coap-dr1175-node/dr1175-node.c new file mode 100644 index 000000000..641f3eca5 --- /dev/null +++ b/examples/jn516x/rpl/coap-dr1175-node/dr1175-node.c @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ + +#include "contiki.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "tools/rpl-tools.h" +#include "rest-engine.h" +#include "light-sensor.h" +#include "ht-sensor.h" +#include "dev/leds.h" +#include "dev/leds-extension.h" +#include "sys/etimer.h" +#include +#include + +static void event_sensors_dr1175_handler(void); +static void get_sensors_dr1175_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_light_sensor_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_light_sensor_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_temperature_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_temperature_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_humidity_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_humidity_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_white_led_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_rgb_led_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_led_d3_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_led_d6_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +static char content[REST_MAX_CHUNK_SIZE]; +static int content_len = 0; + +#define CONTENT_PRINTF(...) { if(content_len < sizeof(content)) { content_len += snprintf(content + content_len, sizeof(content) - content_len, __VA_ARGS__); } } + +#define CLIP(value, level) if(value > level) { \ + value = level; \ +} +#define SET_LED(LED) if(atoi((const char *)request_content) != 0) { \ + leds_on(LED); \ + } else { \ + leds_off(LED); \ + } +/*---------------------------------------------------------------------------*/ +PROCESS(start_app, "START_APP"); +AUTOSTART_PROCESSES(&start_app, &sensors_process); + +/*---------------------------------------------------------------------------*/ + +/*********** CoAP sensor/ resource *************************************************/ + +/*******************************************************************/ +/* Observable resource and event handler to obtain all sensor data */ +/*******************************************************************/ +EVENT_RESOURCE(resource_sensors_dr1175, /* name */ + "obs;title=\"All_DR1175_sensors\"", /* attributes */ + get_sensors_dr1175_handler, /* GET handler */ + NULL, /* POST handler */ + NULL, /* PUT handler */ + NULL, /* DELETE handler */ + event_sensors_dr1175_handler); /* event handler */ +static void +get_sensors_dr1175_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.APPLICATION_JSON) { + content_len = 0; + CONTENT_PRINTF("{\"DR1175\":["); + CONTENT_PRINTF("{\"Humidity\":\"%d\"},", ht_sensor.value(HT_SENSOR_HUM)); + CONTENT_PRINTF("{\"Light\":\"%d\"},", light_sensor.value(0)); + CONTENT_PRINTF("{\"Temp\":\"%d\"}", ht_sensor.value(HT_SENSOR_TEMP)); + CONTENT_PRINTF("]}"); + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +static void +event_sensors_dr1175_handler() +{ + /* Registered observers are notified and will trigger the GET handler to create the response. */ + REST.notify_subscribers(&resource_sensors_dr1175); +} +/*****************************************************/ +/* Resource and handler to obtain light sensor value */ +/*****************************************************/ +RESOURCE(resource_light_sensor_value, + "title=\"light sensor value\"", + get_light_sensor_value_handler, + NULL, + NULL, + NULL); +static void +get_light_sensor_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + CONTENT_PRINTF("%d", light_sensor.value(0)); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/***************************************************/ +/* Resource and handler to obtain light unit value */ +/***************************************************/ +RESOURCE(resource_light_sensor_unit, + "title=\"light sensor unit\"", + get_light_sensor_unit_handler, + NULL, + NULL, + NULL); +static void +get_light_sensor_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + CONTENT_PRINTF("Lux"); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/***********************************************************/ +/* Resource and handler to obtain temperature sensor value */ +/***********************************************************/ +RESOURCE(resource_temperature_value, + "title=\"temperature value\"", + get_temperature_value_handler, + NULL, + NULL, + NULL); +static void +get_temperature_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + CONTENT_PRINTF("%d", ht_sensor.value(HT_SENSOR_TEMP)); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/*********************************************************/ +/* Resource and handler to obtain temperature unit value */ +/*********************************************************/ +RESOURCE(resource_temperature_unit, + "title=\"temperature unit\"", + get_temperature_unit_handler, + NULL, + NULL, + NULL); +static void +get_temperature_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + CONTENT_PRINTF("degrees C"); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/********************************************************/ +/* Resource and handler to obtain humidity sensor value */ +/********************************************************/ +RESOURCE(resource_humidity_value, + "title=\"humidity value\"", + get_humidity_value_handler, + NULL, + NULL, + NULL); +static void +get_humidity_value_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + CONTENT_PRINTF("%d", ht_sensor.value(HT_SENSOR_HUM)); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/******************************************************/ +/* Resource and handler to obtain humidity unit value */ +/******************************************************/ +RESOURCE(resource_humidity_unit, + "title=\"humidity unit\"", + get_humidity_unit_handler, + NULL, + NULL, + NULL); +static void +get_humidity_unit_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + CONTENT_PRINTF("relative %%"); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/***************************************************/ +/* Resource and handler to control White LED level */ +/***************************************************/ +RESOURCE(resource_white_led, + "title=\"WhiteLED <[0..255]>\"", + NULL, + put_post_white_led_handler, + put_post_white_led_handler, + NULL); +static void +put_post_white_led_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content = NULL; + int level; + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.get_request_payload(request, &request_content); + level = atoi((const char *)request_content); + CLIP(level, 255) + leds_set_level(level, LEDS_WHITE); + } +} +/*************************************************/ +/* Resource and handler to control RGB LED level */ +/*************************************************/ +RESOURCE(resource_rgb_led, + "title=\"RGB LED <[0..255] [0..255] [0..255]>\"", + NULL, + put_post_rgb_led_handler, + put_post_rgb_led_handler, + NULL); +static void +put_post_rgb_led_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content = NULL; + char *pch; + int RGB[] = { 0, 0, 0 }; + int index = 0; + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.get_request_payload(request, &request_content); + pch = strtok((char *)request_content, " "); + while((pch != NULL) && (index != sizeof(RGB) / sizeof(int))) { + /* Convert token to int */ + RGB[index] = atoi(pch); + CLIP(RGB[index], 255) + index++; + /* Get next token */ + pch = strtok(NULL, " "); + } + leds_set_level(RGB[0], LEDS_RED); + leds_set_level(RGB[1], LEDS_GREEN); + leds_set_level(RGB[2], LEDS_BLUE); + } +} +/************************************************/ +/* Resource and handler to control D3 on DR1174 */ +/************************************************/ +RESOURCE(resource_led_d3_1174, + "title=\"LED D3 1174<[0,1]>\"", + NULL, + put_post_led_d3_1174_handler, + put_post_led_d3_1174_handler, + NULL); +static void +put_post_led_d3_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.get_request_payload(request, &request_content); + SET_LED(LEDS_GP0); + } +} +/************************************************/ +/* Resource and handler to control D6 on DR1174 */ +/************************************************/ +RESOURCE(resource_led_d6_1174, + "title=\"LED D6 1174<[0,1]>\"", + NULL, + put_post_led_d6_1174_handler, + put_post_led_d6_1174_handler, + NULL); +static void +put_post_led_d6_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.get_request_payload(request, &request_content); + SET_LED(LEDS_GP1); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(start_app, ev, data) +{ + PROCESS_BEGIN(); + + static int is_coordinator = 0; + static struct etimer et; + + /* Make sensor active for measuring */ + SENSORS_ACTIVATE(light_sensor); + SENSORS_ACTIVATE(ht_sensor); + + /* Start net stack */ + if(is_coordinator) { + uip_ipaddr_t prefix; + uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); + rpl_tools_init(&prefix); + } else { + rpl_tools_init(NULL); + } printf("Starting RPL node\n"); + + rest_init_engine(); + rest_activate_resource(&resource_light_sensor_value, "DR1175/LightSensor/Value"); + rest_activate_resource(&resource_light_sensor_unit, "DR1175/LightSensor/Unit"); + rest_activate_resource(&resource_temperature_unit, "DR1175/Temperature/Unit"); + rest_activate_resource(&resource_temperature_value, "DR1175/Temperature/Value"); + rest_activate_resource(&resource_humidity_unit, "DR1175/Humidity/Unit"); + rest_activate_resource(&resource_humidity_value, "DR1175/Humidity/Value"); + rest_activate_resource(&resource_white_led, "DR1175/WhiteLED"); + rest_activate_resource(&resource_rgb_led, "DR1175/ColorLED/RGBValue"); + rest_activate_resource(&resource_led_d3_1174, "DR1175/LED/D3On1174"); + rest_activate_resource(&resource_led_d6_1174, "DR1175/LED/D6On1174"); + rest_activate_resource(&resource_sensors_dr1175, "DR1175/AllSensors"); + + /* Level of LEDS=0, so no light after start-up */ + leds_on(LEDS_WHITE | LEDS_RED | LEDS_GREEN | LEDS_BLUE); + + /* contiki-jn516x-main switches all leds off after process start-up. + Switch on required leds after rescheduling, otherwise level change needs to be + accompanied with leds_on() at least once in resource handler. */ + etimer_set(&et, CLOCK_SECOND / 10); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + /* Level of LEDS=0, so no light after start-up. However, they are enabled + A level change will directly be visible. */ + leds_on(LEDS_WHITE | LEDS_RED | LEDS_GREEN | LEDS_BLUE); + + /* If sensor process generates an event, call event_handler of resource. + This will make this resource observable by the client */ + while(1) { + PROCESS_WAIT_EVENT_UNTIL((ev == sensors_event) && + ((data == &light_sensor) || (data == &ht_sensor))); + event_sensors_dr1175_handler(); + } + + PROCESS_END(); +} diff --git a/examples/jn516x/rpl/coap-dr1175-node/project-conf.h b/examples/jn516x/rpl/coap-dr1175-node/project-conf.h new file mode 100644 index 000000000..4c2ecd648 --- /dev/null +++ b/examples/jn516x/rpl/coap-dr1175-node/project-conf.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \author Simon Duquennoy + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#include "../common-conf.h" + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/rpl/coap-dr1199-node/Makefile b/examples/jn516x/rpl/coap-dr1199-node/Makefile new file mode 100644 index 000000000..9dc391e52 --- /dev/null +++ b/examples/jn516x/rpl/coap-dr1199-node/Makefile @@ -0,0 +1,22 @@ +CONTIKI_PROJECT = dr1199-node +all: $(CONTIKI_PROJECT) + +TARGET ?= jn516x +JN516x_WITH_DR1199 = 1 + +CONTIKI=../../../.. + +CONTIKI_WITH_IPV6 = 1 + +MODULES += core/net/mac/tsch +PROJECTDIRS += .. ../tools +PROJECT_SOURCEFILES += rpl-tools.c +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +CFLAGS += -DWITH_COAP +CFLAGS += -DUIP_CONF_TCP=0 +APPS = json +APPS += er-coap +APPS += rest-engine + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/rpl/coap-dr1199-node/README.md b/examples/jn516x/rpl/coap-dr1199-node/README.md new file mode 100644 index 000000000..e9a6ee66b --- /dev/null +++ b/examples/jn516x/rpl/coap-dr1199-node/README.md @@ -0,0 +1,33 @@ +dr1199-node is an example of a RICH node containing a JN516x microcontroller on a DR1174 baseboard. +A DR1199 shield is mounted on the baseboard. +The boards are part of the NXP JN516x Evaluation Kit (see http://www.nxp.com/documents/leaflet/75017368.pdf) +The dr1199-node connects to the network in the same way as described in `examples\jn5168/rpl/README.md` + +The resources on the DR1199 are available as CoAP resources. They can be accessed via a CoAP client at the IPv6 interface +of the border router (e.g. via Copper plug-in on Firefox). +The following list gives an overview of the resources: + +URI Description +--- ----------- +DR1199\AllSensors This is an observable resource that shows the status of all switches and the potentiometer on the board + The resource is automatically updated when a change of the status/value of the switches and potentiometer + takes place. +DR1199\LED\All When writing a '1', LEDs D1..D3 will switch ON + When writing a '0', LEDs D1..D3 will switch OFF +DR1199\LED\D1 When writing a '1', LED D1 will switch ON + When writing a '0', LED D1 will switch OFF +DR1199\LED\D2 When writing a '1', LED D2 will switch ON + When writing a '0', LED D2 will switch OFF +DR1199\LED\D3 When writing a '1', LED D3 will switch ON + When writing a '0', LED D3 will switch OFF +DR1199\D3On1174 This resource control LED D3 on the base board +DR1199\D6On1174 This resource control LED D6 on the base board +DR1199\Potentiometer The resource will show the value of the potentiometer +DR1199\Switch\DIO8 This resource shows the status of the DIO8 switch (on DR1174) +DR1199\Switch\SW1 This resource shows the status of the SW1 switch +DR1199\Switch\SW2 This resource shows the status of the SW2 switch +DR1199\Switch\SW3 This resource shows the status of the SW3 switch +DR1199\Switch\SW4 This resource shows the status of the SW4 switch + + + diff --git a/examples/jn516x/rpl/coap-dr1199-node/dr1199-node.c b/examples/jn516x/rpl/coap-dr1199-node/dr1199-node.c new file mode 100644 index 000000000..933b247d6 --- /dev/null +++ b/examples/jn516x/rpl/coap-dr1199-node/dr1199-node.c @@ -0,0 +1,385 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "tools/rpl-tools.h" +#include "rest-engine.h" +#include "dev/leds.h" +#include "button-sensor.h" +#include "pot-sensor.h" +#include +#include + +static char content[REST_MAX_CHUNK_SIZE]; +static int content_len = 0; + +static void event_sensors_dr1199_handler(); +static void get_sensors_dr1199_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_switch_sw1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_switch_sw2_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_switch_sw3_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_switch_sw4_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_switch_dio8_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_pot_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_led_d1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_led_d2_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_led_d3_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_led_d3_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_led_d6_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void put_post_led_all_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +#define CONTENT_PRINTF(...) { if(content_len < sizeof(content)) { content_len += snprintf(content + content_len, sizeof(content) - content_len, __VA_ARGS__); } } + +#define PARSE_SWITCH(POSITION) if(button_sensor.value(0) & (1 << POSITION)) { \ + CONTENT_PRINTF("PRESSED"); \ + } else { \ + CONTENT_PRINTF("RELEASED"); \ + } + +#define SET_LED(LED) if(atoi((const char *)request_content) != 0) { \ + leds_on(LED); \ + } else { \ + leds_off(LED); \ + } + +/*---------------------------------------------------------------------------*/ +PROCESS(start_app, "START_APP"); +AUTOSTART_PROCESSES(&sensors_process, &start_app); + +/*---------------------------------------------------------------------------*/ + +/*********** CoAP sensor/ resource *************************************************/ + +/*******************************************************************/ +/* Observable resource and event handler to obtain all sensor data */ +/*******************************************************************/ +EVENT_RESOURCE(resource_sensors_dr1199, /* name */ + "obs;title=\"All_DR1199_sensors\"", /* attributes */ + get_sensors_dr1199_handler, /* GET handler */ + NULL, /* POST handler */ + NULL, /* PUT handler */ + NULL, /* DELETE handler */ + event_sensors_dr1199_handler); /* event handler */ +static void +get_sensors_dr1199_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.APPLICATION_JSON) { + content_len = 0; + CONTENT_PRINTF("{\"DR1199\":["); + CONTENT_PRINTF("{\"Switch\":\"0x%X\"},", button_sensor.value(0)); + CONTENT_PRINTF("{\"Pot\":\"%d\"}", pot_sensor.value(0)); + CONTENT_PRINTF("]}"); + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +static void +event_sensors_dr1199_handler() +{ + /* Registered observers are notified and will trigger the GET handler to create the response. */ + REST.notify_subscribers(&resource_sensors_dr1199); +} +/***********************************************/ +/* Resource and handler to obtain switch value */ +/***********************************************/ +RESOURCE(resource_switch_sw1, + "title=\"SW1\"", + get_switch_sw1_handler, + NULL, + NULL, + NULL); +static void +get_switch_sw1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + content_len = 0; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + PARSE_SWITCH(1) + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +RESOURCE(resource_switch_sw2, + "title=\"SW2\"", + get_switch_sw2_handler, + NULL, + NULL, + NULL); +static void +get_switch_sw2_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + content_len = 0; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + PARSE_SWITCH(2) + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +RESOURCE(resource_switch_sw3, + "title=\"SW3\"", + get_switch_sw3_handler, + NULL, + NULL, + NULL); +static void +get_switch_sw3_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + content_len = 0; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + PARSE_SWITCH(3) + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +RESOURCE(resource_switch_sw4, + "title=\"SW4\"", + get_switch_sw4_handler, + NULL, + NULL, + NULL); +static void +get_switch_sw4_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + content_len = 0; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + PARSE_SWITCH(4) + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +RESOURCE(resource_switch_dio8, + "title=\"DIO8\"", + get_switch_dio8_handler, + NULL, + NULL, + NULL); +static void +get_switch_dio8_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + content_len = 0; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + PARSE_SWITCH(0) + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/*******************************************************/ +/* Resource and handler to obtain potentiometer value */ +/*******************************************************/ +RESOURCE(resource_pot, + "title=\"Potentiometer\"", + get_pot_handler, + NULL, + NULL, + NULL); +static void +get_pot_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + content_len = 0; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + CONTENT_PRINTF("%d", pot_sensor.value(0)); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/************************************/ +/* Resource and handler to set leds */ +/************************************/ +RESOURCE(resource_led_d1, + "title=\"LED D1 <[0,1]>\"", + NULL, + put_post_led_d1_handler, + put_post_led_d1_handler, + NULL); +static void +put_post_led_d1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.get_request_payload(request, &request_content); + SET_LED(LEDS_GREEN) + } +} +RESOURCE(resource_led_d2, + "title=\"LED D2 <[0,1]>\"", + NULL, + put_post_led_d2_handler, + put_post_led_d2_handler, + NULL); +static void +put_post_led_d2_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.get_request_payload(request, &request_content); + SET_LED(LEDS_BLUE) + } +} +RESOURCE(resource_led_d3, + "title=\"LED D3 <[0,1]>\"", + NULL, + put_post_led_d3_handler, + put_post_led_d3_handler, + NULL); +static void +put_post_led_d3_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.get_request_payload(request, &request_content); + SET_LED(LEDS_RED) + } +} +RESOURCE(resource_led_d3_1174, + "title=\"LED D3 1174<[0,1]>\"", + NULL, + put_post_led_d3_1174_handler, + put_post_led_d3_1174_handler, + NULL); +static void +put_post_led_d3_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.get_request_payload(request, &request_content); + SET_LED(LEDS_GP0); + } +} +RESOURCE(resource_led_d6_1174, + "title=\"LED D6 1174<[0,1]>\"", + NULL, + put_post_led_d6_1174_handler, + put_post_led_d6_1174_handler, + NULL); +static void +put_post_led_d6_1174_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.get_request_payload(request, &request_content); + SET_LED(LEDS_GP1); + } +} +RESOURCE(resource_led_all, + "title=\"LED All <[0,1]>\"", + NULL, + put_post_led_all_handler, + put_post_led_all_handler, + NULL); +static void +put_post_led_all_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.get_request_payload(request, &request_content); + if(atoi((const char *)request_content) != 0) { + leds_on(LEDS_ALL); + } else { + leds_off(LEDS_ALL); + } + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(start_app, ev, data) +{ + PROCESS_BEGIN(); + + static int is_coordinator = 0; + + /* is_coordinator = node_id == 1; */ + + /* Make sensor active for measuring */ + SENSORS_ACTIVATE(button_sensor); + SENSORS_ACTIVATE(pot_sensor); + + /* Start net stack */ + if(is_coordinator) { + uip_ipaddr_t prefix; + uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); + rpl_tools_init(&prefix); + } else { + rpl_tools_init(NULL); + } printf("Starting RPL node\n"); + + rest_init_engine(); + rest_activate_resource(&resource_switch_sw1, "DR1199/Switch/SW1"); + rest_activate_resource(&resource_switch_sw2, "DR1199/Switch/SW2"); + rest_activate_resource(&resource_switch_sw3, "DR1199/Switch/SW3"); + rest_activate_resource(&resource_switch_sw4, "DR1199/Switch/SW4"); + rest_activate_resource(&resource_switch_dio8, "DR1199/Switch/DIO8"); + rest_activate_resource(&resource_pot, "DR1199/Potentiometer"); + rest_activate_resource(&resource_led_d1, "DR1199/LED/D1"); + rest_activate_resource(&resource_led_d2, "DR1199/LED/D2"); + rest_activate_resource(&resource_led_d3, "DR1199/LED/D3"); + rest_activate_resource(&resource_led_d3_1174, "DR1199/LED/D3On1174"); + rest_activate_resource(&resource_led_d6_1174, "DR1199/LED/D6On1174"); + rest_activate_resource(&resource_led_all, "DR1199/LED/All"); + rest_activate_resource(&resource_sensors_dr1199, "DR1199/AllSensors"); + /* If sensor process generates an event, call event_handler of resource. + This will make this resource observable by the client */ + while(1) { + PROCESS_WAIT_EVENT_UNTIL((ev == sensors_event) && + ((data == &button_sensor) || (data == &pot_sensor))); + event_sensors_dr1199_handler(); + } + + PROCESS_END(); +} + diff --git a/examples/jn516x/rpl/coap-dr1199-node/project-conf.h b/examples/jn516x/rpl/coap-dr1199-node/project-conf.h new file mode 100644 index 000000000..4c2ecd648 --- /dev/null +++ b/examples/jn516x/rpl/coap-dr1199-node/project-conf.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \author Simon Duquennoy + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#include "../common-conf.h" + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/rpl/common-conf.h b/examples/jn516x/rpl/common-conf.h new file mode 100644 index 000000000..bef5407d5 --- /dev/null +++ b/examples/jn516x/rpl/common-conf.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \author Simon Duquennoy + */ + +#ifndef __COMMON_CONF_H__ +#define __COMMON_CONF_H__ + +#define MAC_CONFIG_NULLRDC 0 +#define MAC_CONFIG_CONTIKIMAC 1 +#define MAC_CONFIG_TSCH 2 +/* Select a MAC configuration */ +#define MAC_CONFIG MAC_CONFIG_TSCH + +#undef NETSTACK_CONF_MAC +#undef NETSTACK_CONF_RDC +#undef NETSTACK_CONF_FRAMER + +#if MAC_CONFIG == MAC_CONFIG_NULLRDC + +#define NETSTACK_CONF_MAC csma_driver +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_FRAMER framer_802154 + +#elif MAC_CONFIG == MAC_CONFIG_CONTIKIMAC + +#define NETSTACK_CONF_MAC csma_driver +#define NETSTACK_CONF_RDC contikimac_driver +#define NETSTACK_CONF_FRAMER contikimac_framer +#undef MICROMAC_CONF_AUTOACK +#define MICROMAC_CONF_AUTOACK 1 + +#elif MAC_CONFIG == MAC_CONFIG_TSCH + +/* Set to run orchestra */ +#ifndef WITH_ORCHESTRA +#define WITH_ORCHESTRA 0 +#endif /* WITH_ORCHESTRA */ + +/* Set to enable TSCH security */ +#ifndef WITH_SECURITY +#define WITH_SECURITY 0 +#endif /* WITH_SECURITY */ + +#define NETSTACK_CONF_MAC tschmac_driver +#define NETSTACK_CONF_RDC nordc_driver +#define NETSTACK_CONF_FRAMER framer_802154 + +/* IEEE802.15.4 frame version */ +#undef FRAME802154_CONF_VERSION +#define FRAME802154_CONF_VERSION FRAME802154_IEEE802154E_2012 + +/* TSCH and RPL callbacks */ +#define RPL_CALLBACK_PARENT_SWITCH tsch_rpl_callback_parent_switch +#define RPL_CALLBACK_NEW_DIO_INTERVAL tsch_rpl_callback_new_dio_interval +#define TSCH_CALLBACK_JOINING_NETWORK tsch_rpl_callback_joining_network +#define TSCH_CALLBACK_LEAVING_NETWORK tsch_rpl_callback_leaving_network + +/* TSCH logging. 0: disabled. 1: basic log. 2: with delayed + * log messages from interrupt */ +#undef TSCH_LOG_CONF_LEVEL +#define TSCH_LOG_CONF_LEVEL 2 + +/* Do not start TSCH at init, wait for NETSTACK_MAC.on() */ +#undef TSCH_CONF_AUTOSTART +#define TSCH_CONF_AUTOSTART 0 + +/* 6TiSCH minimal schedule length. + * Larger values result in less frequent active slots: reduces capacity and saves energy. */ +#undef TSCH_SCHEDULE_CONF_DEFAULT_LENGTH +#define TSCH_SCHEDULE_CONF_DEFAULT_LENGTH 3 + +#if WITH_SECURITY + +/* Enable security */ +#undef LLSEC802154_CONF_SECURITY_LEVEL +#define LLSEC802154_CONF_SECURITY_LEVEL 1 +/* TSCH uses explicit keys to identify k1 and k2 */ +#undef LLSEC802154_CONF_USES_EXPLICIT_KEYS +#define LLSEC802154_CONF_USES_EXPLICIT_KEYS 1 +/* TSCH uses the ASN rather than frame counter to construct the Nonce */ +#undef LLSEC802154_CONF_USES_FRAME_COUNTER +#define LLSEC802154_CONF_USES_FRAME_COUNTER 0 + +#endif /* WITH_SECURITY */ + +#if WITH_ORCHESTRA + +/* See apps/orchestra/README.md for more Orchestra configuration options */ +#define TSCH_SCHEDULE_CONF_WITH_6TISCH_MINIMAL 0 /* No 6TiSCH minimal schedule */ +#define TSCH_CONF_WITH_LINK_SELECTOR 1 /* Orchestra requires per-packet link selection */ +/* Orchestra callbacks */ +#define TSCH_CALLBACK_NEW_TIME_SOURCE orchestra_callback_new_time_source +#define TSCH_CALLBACK_PACKET_READY orchestra_callback_packet_ready +#define NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK orchestra_callback_child_added +#define NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK orchestra_callback_child_removed + +#endif /* WITH_ORCHESTRA */ + + +#else + +#error Unsupported MAC configuration + +#endif /* MAC_CONFIG */ + +/* IEEE802.15.4 PANID and channel */ + +#undef IEEE802154_CONF_PANID +#define IEEE802154_CONF_PANID 0xabcd + +#undef MICROMAC_CONF_CHANNEL +#define MICROMAC_CONF_CHANNEL 26 + +/* UART Configuration */ + +#undef UART_HW_FLOW_CTRL +#define UART_HW_FLOW_CTRL 0 + +#undef UART_XONXOFF_FLOW_CTRL +#define UART_XONXOFF_FLOW_CTRL 1 + +#undef UART_BAUD_RATE +#define UART_BAUD_RATE UART_RATE_1000000 + +#endif /* __COMMON_CONF_H__ */ diff --git a/examples/jn516x/rpl/node/Makefile b/examples/jn516x/rpl/node/Makefile new file mode 100644 index 000000000..44cd68d8d --- /dev/null +++ b/examples/jn516x/rpl/node/Makefile @@ -0,0 +1,15 @@ +CONTIKI_PROJECT = node +all: $(CONTIKI_PROJECT) + +TARGET ?= jn516x + +CONTIKI=../../../.. + +CONTIKI_WITH_IPV6 = 1 + +MODULES += core/net/mac/tsch +PROJECTDIRS += .. ../tools +PROJECT_SOURCEFILES += rpl-tools.c +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/rpl/node/README.md b/examples/jn516x/rpl/node/README.md new file mode 100644 index 000000000..e9bded1d6 --- /dev/null +++ b/examples/jn516x/rpl/node/README.md @@ -0,0 +1,18 @@ +A RPL node. Will act as basic node by default, but can be configured at startup +using the user button and following instructions from the log output. Every press +of a button toggles the mode as 6ln and 6dr. After 10s with no button press, +the node starts in the last setting. The modes are: +* 6ln (default): 6lowpan node, will join a RPL network and act as router. +* 6dr: 6lowpan DAG Root, will start its own RPL network. Note this is not a +border router, i.e. it does not have a serial interface with connection to +the Internet. For a border router, see ../border-router. + +To indicate the hardware target for the node, add one of the following +options in the command line: +If rpl-border-router runs on dongle: +JN516x_WITH_DONGLE=1 +If rpl-border-router runs on DR1174: +JN516x_WITH_DR1174=1 +If building for a new platform, first execute : make clean + +For more information, see ../README.md. diff --git a/examples/jn516x/rpl/node/node.c b/examples/jn516x/rpl/node/node.c new file mode 100644 index 000000000..b6a6f3096 --- /dev/null +++ b/examples/jn516x/rpl/node/node.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \file + * A RPL node able to act as either DAG Root (6dr) or simple node (6ln). + * Press use button at startup to configure. + * + * \author Simon Duquennoy + */ + +#include "contiki.h" +#include "net/ipv6/uip-ds6.h" +#include "net/rpl/rpl.h" +#include "tools/rpl-tools.h" + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +#define CONFIG_VIA_BUTTON PLATFORM_HAS_BUTTON +#if CONFIG_VIA_BUTTON +#include "button-sensor.h" +#endif /* CONFIG_VIA_BUTTON */ + +/*---------------------------------------------------------------------------*/ +PROCESS(node_process, "RPL Node"); +#if CONFIG_VIA_BUTTON +AUTOSTART_PROCESSES(&node_process, &sensors_process); +#else /* CONFIG_VIA_BUTTON */ +AUTOSTART_PROCESSES(&node_process); +#endif /* CONFIG_VIA_BUTTON */ + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(node_process, ev, data) +{ + static struct etimer et; + PROCESS_BEGIN(); + + /* 3 possible roles: + * - role_6ln: simple node, will join any network, secured or not + * - role_6dg: DAG root, will advertise (unsecured) beacons + * */ + static int is_coordinator = 0; + static enum { role_6ln, role_6dr } node_role; + node_role = role_6ln; + +#if CONFIG_VIA_BUTTON + { +#define CONFIG_WAIT_TIME 5 + SENSORS_ACTIVATE(button_sensor); + etimer_set(&et, CLOCK_SECOND * CONFIG_WAIT_TIME); + + while(!etimer_expired(&et)) { + printf("Init: current role: %s. Will start in %u seconds.\n", + node_role == role_6ln ? "6ln" : "6dr", + CONFIG_WAIT_TIME); + PROCESS_WAIT_EVENT_UNTIL(((ev == sensors_event) && + (data == &button_sensor) && button_sensor.value(0) > 0) + || etimer_expired(&et)); + if(ev == sensors_event && data == &button_sensor && button_sensor.value(0) > 0) { + node_role = (node_role + 1) % 2; + etimer_restart(&et); + } + } + } + +#endif /* CONFIG_VIA_BUTTON */ + + printf("Init: node starting with role %s\n", + node_role == role_6ln ? "6ln" : "6dr"); + + is_coordinator = node_role > role_6ln; + + if(is_coordinator) { + uip_ipaddr_t prefix; + uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); + rpl_tools_init(&prefix); + } else { + rpl_tools_init(NULL); + } + + /* Print out routing tables every minute */ + etimer_set(&et, CLOCK_SECOND * 60); + while(1) { + print_network_status(); + PROCESS_YIELD_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/rpl/node/project-conf.h b/examples/jn516x/rpl/node/project-conf.h new file mode 100644 index 000000000..9db6f0229 --- /dev/null +++ b/examples/jn516x/rpl/node/project-conf.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \author Simon Duquennoy + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#include "../common-conf.h" + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/rpl/tools/rpl-tools.c b/examples/jn516x/rpl/tools/rpl-tools.c new file mode 100644 index 000000000..dff045ab6 --- /dev/null +++ b/examples/jn516x/rpl/tools/rpl-tools.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \file + * + * \author Simon Duquennoy + */ + +#include "contiki-conf.h" +#include "contiki-net.h" +#include "net/ip/uip.h" +#include "net/rpl/rpl.h" +#include +#include + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +/*---------------------------------------------------------------------------*/ +void +print_network_status(void) +{ + int i; + uint8_t state; + uip_ds6_defrt_t *default_route; + uip_ds6_route_t *route; + + PRINTA("--- Network status ---\n"); + + /* Our IPv6 addresses */ + PRINTA("- Server IPv6 addresses:\n"); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && + (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { + PRINTA("-- "); + uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr); + PRINTA("\n"); + } + } + + /* Our default route */ + PRINTA("- Default route:\n"); + default_route = uip_ds6_defrt_lookup(uip_ds6_defrt_choose()); + if(default_route != NULL) { + PRINTA("-- "); + uip_debug_ipaddr_print(&default_route->ipaddr);; + PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)default_route->lifetime.interval); + } else { + PRINTA("-- None\n"); + } + + /* Our routing entries */ + PRINTA("- Routing entries (%u in total):\n", uip_ds6_route_num_routes()); + route = uip_ds6_route_head(); + while(route != NULL) { + PRINTA("-- "); + uip_debug_ipaddr_print(&route->ipaddr); + PRINTA(" via "); + uip_debug_ipaddr_print(uip_ds6_route_nexthop(route)); + PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)route->state.lifetime); + route = uip_ds6_route_next(route); + } + + PRINTA("----------------------\n"); +} +/*---------------------------------------------------------------------------*/ +static void +print_local_addresses(void) +{ + int i; + uint8_t state; + + PRINTA("Server IPv6 addresses:\n"); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && + (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { + PRINTA(" "); + uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr); + PRINTA("\n"); + } + } +} +/*---------------------------------------------------------------------------*/ +void +rpl_tools_init(uip_ipaddr_t *br_prefix) +{ + uip_ipaddr_t global_ipaddr; + + if(br_prefix) { /* We are root */ + NETSTACK_RDC.off(1); + memcpy(&global_ipaddr, br_prefix, 16); + uip_ds6_set_addr_iid(&global_ipaddr, &uip_lladdr); + uip_ds6_addr_add(&global_ipaddr, 0, ADDR_AUTOCONF); + rpl_set_root(RPL_DEFAULT_INSTANCE, &global_ipaddr); + rpl_set_prefix(rpl_get_any_dag(), br_prefix, 64); + rpl_repair_root(RPL_DEFAULT_INSTANCE); + } + + NETSTACK_MAC.on(); + + print_local_addresses(); +} diff --git a/examples/jn516x/rpl/tools/rpl-tools.h b/examples/jn516x/rpl/tools/rpl-tools.h new file mode 100644 index 000000000..f14ec1d86 --- /dev/null +++ b/examples/jn516x/rpl/tools/rpl-tools.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + + * \author Simon Duquennoy + */ + +void rpl_tools_init(uip_ipaddr_t *br_prefix); +void print_network_status(void); diff --git a/examples/jn516x/tsch/README.md b/examples/jn516x/tsch/README.md new file mode 100644 index 000000000..2bfcc036a --- /dev/null +++ b/examples/jn516x/tsch/README.md @@ -0,0 +1,8 @@ +Examples for tsch on jn516x + +simple-sensor-network: This example shows a simple sensor network consisting of node(s),an rpl-border-router and a host connected to +the IPv6 network. +tx-power-verfication: Example on TX power control and RSSI reading on JN516x. Resource available on coap client. +uart1-test-node: Example on exposing uart1 of JN516x node to a coap client + + \ No newline at end of file diff --git a/examples/jn516x/tsch/common-conf-jn516x.h b/examples/jn516x/tsch/common-conf-jn516x.h new file mode 100644 index 000000000..53773e702 --- /dev/null +++ b/examples/jn516x/tsch/common-conf-jn516x.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2014, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \author Simon Duquennoy + */ + +#ifndef __COMMON_CONF_JN516X_H__ +#define __COMMON_CONF_JN516X_H__ + +/* Shall we restart after exception, or stall? + * in production code we should restart, so set this to 0 */ +#undef EXCEPTION_STALLS_SYSTEM +#define EXCEPTION_STALLS_SYSTEM 1 + + /* CoAP */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 256 + +/* Network config */ +#undef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +#undef UIP_CONF_BUFFER_SIZE +//#define UIP_CONF_BUFFER_SIZE (REST_MAX_CHUNK_SIZE + UIP_LLH_LEN + UIP_IPUDPH_LEN + COAP_MAX_HEADER_SIZE) +//#define UIP_CONF_BUFFER_SIZE (REST_MAX_CHUNK_SIZE + 0 + 48 + 70) +#define UIP_CONF_BUFFER_SIZE 1280 /* ipv6 required minimum */ +#undef UIP_CONF_UDP_CONNS +#define UIP_CONF_UDP_CONNS 8 + +/* No IPv6 reassembly */ +#undef UIP_CONF_IPV6_REASSEMBLY +#define UIP_CONF_IPV6_REASSEMBLY 0 + +/* Timeout for packet reassembly at the 6lowpan layer (should be < 60s) */ +#undef SICSLOWPAN_CONF_MAXAGE +#define SICSLOWPAN_CONF_MAXAGE 10 + +/* Queues */ +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 32 + +#undef TSCH_QUEUE_CONF_NUM_PER_NEIGHBOR +#define TSCH_QUEUE_CONF_NUM_PER_NEIGHBOR 32 + +#undef TSCH_CONF_DEQUEUED_ARRAY_SIZE +#define TSCH_CONF_DEQUEUED_ARRAY_SIZE 32 + +#undef TSCH_QUEUE_CONF_MAX_NEIGHBOR_QUEUES +#define TSCH_QUEUE_CONF_MAX_NEIGHBOR_QUEUES 8 + +/* The neighbor table size */ +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 8 + +/* The routing table size */ +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 28 + +/* Radio */ + +#undef ENABLE_COOJA_DEBUG +#define ENABLE_COOJA_DEBUG 0 + +/* max 3, min 0 */ + +#undef UART_HW_FLOW_CTRL +#define UART_HW_FLOW_CTRL 0 + +#undef UART_XONXOFF_FLOW_CTRL +#define UART_XONXOFF_FLOW_CTRL 1 + +#undef UART_BAUD_RATE +#define UART_BAUD_RATE UART_RATE_1000000 + +#endif /* __COMMON_CONF_JN516X_H__ */ diff --git a/examples/jn516x/tsch/common-conf.h b/examples/jn516x/tsch/common-conf.h new file mode 100644 index 000000000..91037c794 --- /dev/null +++ b/examples/jn516x/tsch/common-conf.h @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2014, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \author Simon Duquennoy + */ + +#ifndef __COMMON_CONF_H__ +#define __COMMON_CONF_H__ + +/* Global config flags */ + +#define WITH_TSCH 1 +#define WITH_TSCH_SECURITY 0 +#define TSCH_LOG_CONF_LEVEL 2 +#define WITH_COAP_RESOURCES 0 + +#undef ENABLE_COOJA_DEBUG +#define ENABLE_COOJA_DEBUG 0 + +#undef IEEE802154_CONF_PANID +#define IEEE802154_CONF_PANID 0x5254 + +#undef TSCH_CONF_DEFAULT_HOPPING_SEQUENCE +#define TSCH_HOPPING_SEQUENCE_MY_SEQUENCE (uint8_t[]){17, 23, 15, 25, 19, 11, 13, 21} +#define TSCH_CONF_DEFAULT_HOPPING_SEQUENCE TSCH_HOPPING_SEQUENCE_MY_SEQUENCE + +#undef TSCH_CONF_JOIN_MY_PANID_ONLY +#define TSCH_CONF_JOIN_MY_PANID_ONLY 1 + +#undef TSCH_CONF_AUTOSTART +#define TSCH_CONF_AUTOSTART 0 + +#define RPL_CALLBACK_PARENT_SWITCH tsch_rpl_callback_parent_switch +#define RPL_CALLBACK_NEW_DIO_INTERVAL tsch_rpl_callback_new_dio_interval + +/* RPL Trickle timer tuning */ +#undef RPL_CONF_DIO_INTERVAL_MIN +#define RPL_CONF_DIO_INTERVAL_MIN 12 /* 4.096 s */ + +#undef RPL_CONF_DIO_INTERVAL_DOUBLINGS +#define RPL_CONF_DIO_INTERVAL_DOUBLINGS 2 /* Max factor: x4. 4.096 s * 4 = 16.384 s */ + +#define TSCH_CONF_EB_PERIOD (4 * CLOCK_SECOND) +#define TSCH_CONF_KEEPALIVE_TIMEOUT (24 * CLOCK_SECOND) + +#define TSCH_SCHEDULE_CONF_WITH_6TISCH_MINIMAL 0 +#define TSCH_CONF_WITH_LINK_SELECTOR 1 +#define TSCH_CALLBACK_NEW_TIME_SOURCE orchestra_callback_new_time_source +#define TSCH_CALLBACK_PACKET_READY orchestra_callback_packet_ready +#define NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK orchestra_callback_child_added +#define NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK orchestra_callback_child_removed + +/* Dimensioning */ +#define ORCHESTRA_CONF_EBSF_PERIOD 41 +#define ORCHESTRA_CONF_COMMON_SHARED_PERIOD 7 /* Common shared slot, 7 is a very short slotframe (high energy, high capacity). Must be prime and at least equal to number of nodes (incl. BR) */ +#define ORCHESTRA_CONF_UNICAST_PERIOD 11 /* First prime greater than 10 */ + +/* Use sender-based slots */ +#define ORCHESTRA_CONF_UNICAST_SENDER_BASED 1 +/* Our "hash" is collision-free */ +#define ORCHESTRA_CONF_COLLISION_FREE_HASH 1 +/* Max hash value */ +#define ORCHESTRA_CONF_MAX_HASH (ORCHESTRA_CONF_UNICAST_PERIOD - 1) + +/* RPL probing */ +#define RPL_CONF_PROBING_INTERVAL (5 * CLOCK_SECOND) +#define RPL_CONF_PROBING_EXPIRATION_TIME (2 * 60 * CLOCK_SECOND) + +/* CoAP */ + +#undef COAP_SERVER_PORT +#define COAP_SERVER_PORT 5684 + +#undef COAP_OBSERVE_RETURNS_REPRESENTATION +#define COAP_OBSERVE_RETURNS_REPRESENTATION 1 + +/* RPL */ +#undef UIP_CONF_ROUTER +#define UIP_CONF_ROUTER 1 + +/* RPL storing mode */ +#undef RPL_CONF_MOP +#define RPL_CONF_MOP RPL_MOP_STORING_NO_MULTICAST + +/* Default link metric */ +#undef RPL_CONF_INIT_LINK_METRIC +#define RPL_CONF_INIT_LINK_METRIC 2 /* default 5 */ + +#define RPL_CONF_MAX_INSTANCES 1 /* default 1 */ +#define RPL_CONF_MAX_DAG_PER_INSTANCE 1 /* default 2 */ + +/* No RA, No NA */ +#undef UIP_CONF_ND6_SEND_NA +#define UIP_CONF_ND6_SEND_NA 0 + +#undef UIP_CONF_ND6_SEND_RA +#define UIP_CONF_ND6_SEND_RA 0 + +#undef UIP_CONF_TCP +#define UIP_CONF_TCP 0 +#undef UIP_CONF_DS6_ADDR_NBU +#define UIP_CONF_DS6_ADDR_NBU 1 +#undef UIP_CONF_FWCACHE_SIZE +#define UIP_CONF_FWCACHE_SIZE 1 +#undef UIP_CONF_UDP_CHECKSUMS +#define UIP_CONF_UDP_CHECKSUMS 1 + +/* Link-layer security */ + +/* Even when link-layer security is needed, we do not use a LLSEC layer, as it does not + * allow to secure MAC-layer packets, nor can run encrypt/decrupt from interrupt. + * Instead, we call AES-CCM* primitives directly from TSCH */ +#undef NETSTACK_CONF_LLSEC +#define NETSTACK_CONF_LLSEC nullsec_driver + +#if WITH_TSCH_SECURITY +/* Set security level to the maximum, even if unused, to all crypto code */ +#define LLSEC802154_CONF_ENABLED 1 +/* Attempt to associate from both secured and non-secured EBs */ +#define TSCH_CONF_JOIN_SECURED_ONLY 0 +/* We need explicit keys to identify k1 and k2 */ +#undef LLSEC802154_CONF_USES_EXPLICIT_KEYS +#define LLSEC802154_CONF_USES_EXPLICIT_KEYS 1 +/* TSCH uses the ASN to construct the Nonce */ +#undef LLSEC802154_CONF_USES_FRAME_COUNTER +#define LLSEC802154_CONF_USES_FRAME_COUNTER 0 +#endif /* WITH_TSCH_SECURITY */ + +#if WITH_TSCH + +#undef FRAME802154_CONF_VERSION +#define FRAME802154_CONF_VERSION FRAME802154_IEEE802154E_2012 + +/* Contiki netstack: MAC */ +#undef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC tschmac_driver + +/* Contiki netstack: RDC */ +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nordc_driver + +#else /* No TSCH, use Csma+NullRDC with ACK */ + +/* Contiki netstack: MAC */ +#undef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC csma_driver + +/* Contiki netstack: RDC */ +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nullrdc_driver + +#undef MICROMAC_CONF_CHANNEL +#define MICROMAC_CONF_CHANNEL 26 + +#undef MICROMAC_CONF_AUTOACK +#define MICROMAC_CONF_AUTOACK 1 + +/* increase internal radio buffering */ +#undef MIRCOMAC_CONF_BUF_NUM +#define MIRCOMAC_CONF_BUF_NUM 4 + +#endif + +#undef CONTIKI_VERSION_STRING +#define CONTIKI_VERSION_STRING "Contiki 3.x" + +#include "common-conf-jn516x.h" + +#endif /* __COMMON_CONF_H__ */ diff --git a/examples/jn516x/tsch/simple-sensor-network/README.md b/examples/jn516x/tsch/simple-sensor-network/README.md new file mode 100644 index 000000000..b9bf2588c --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/README.md @@ -0,0 +1,25 @@ +This example shows a simple sensor network consisting of node(s),an rpl-border-router and a host connected to +the IPv6 network. The nodes (see also node/README.md) regularly transmit simulated sensor data to the host. +The host visualises the received data. + +The Python script tools/Output-Visualisation.py visualises the received data from the nodes. +The script runs on Python27 and uses gnuplot for visualisation. +The following installations are needed (tested with Win32 versions: +- Python 27 (https://www.python.org/download/releases/2.7/) +- gnuplot (http://sourceforge.net/projects/gnuplot/files/gnuplot/) +- gnuplot.py (http://gnuplot-py.sourceforge.net/) +- numpy.py (e.g. http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy) +Manual modification: +Python27\Lib\site-packages\Gnuplot\gp_win32.py +Modify gnuplot_command as in example below + gnuplot_command = r'"C:\Program Files (x86)\gnuplot\bin\gnuplot.exe"' + +- The IPv6 addresses of nodes need to be entered in the dictionary "node_data" of tools/Output-Visualisation.py + A user name for the node can be entered in this table as well. +- The script will send a ping message to the next node in the list every 5 seconds. The nodes will obtain + the IPv6 address from this message and start sending "sensor" data to the host. +- Received sensor data is plotted. When no data has been received for more than 30seconds, the plot line + will be dashed. +- Plots are updated once per second. + + \ No newline at end of file diff --git a/examples/jn516x/tsch/simple-sensor-network/node/Makefile b/examples/jn516x/tsch/simple-sensor-network/node/Makefile new file mode 100644 index 000000000..2df54d578 --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/node/Makefile @@ -0,0 +1,25 @@ +CONTIKI_PROJECT = node + +TARGET ?= jn516x +JN516x_WITH_DONGLE = 1 + +CONTIKI=../../../../.. + +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +PROJECTDIRS += .. ../../tools +PROJECT_SOURCEFILES += rpl-tools.c +CFLAGS += -DWITH_COAP +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += orchestra +APPS += json +APPS += er-coap +APPS += rest-engine + +MODULES += core/net/mac/tsch + +all: $(CONTIKI_PROJECT) + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/tsch/simple-sensor-network/node/README.md b/examples/jn516x/tsch/simple-sensor-network/node/README.md new file mode 100644 index 000000000..a49a8970c --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/node/README.md @@ -0,0 +1,10 @@ +Node is part of Simple-Sensor-Network +When node is connected to border-router (TSCH), it will wait to be addressed by a host +on port 8185. +When addressed, IPv6 address of host is acquired. Node will start to transmit samples of +a waveform ("simulated" sensor data) to the host on port 8186 at a rate of once per +10 seconds. Type of waveform and phase depend on mac address of node in order to better +distinguish the waveforms at the host side. +LED is flashed every time a sample is transmitted. +Nodes are tested with configuration JN516x_WITH_DONGLE=1 + diff --git a/examples/jn516x/tsch/simple-sensor-network/node/node.c b/examples/jn516x/tsch/simple-sensor-network/node/node.c new file mode 100644 index 000000000..561df6a47 --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/node/node.c @@ -0,0 +1,241 @@ +/* +* Copyright (c) 2015 NXP B.V. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. 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. +* 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. +* +* This file is part of the Contiki operating system. +* +* Author: Theo van Daele +* +*/ + +#include "contiki-conf.h" +#include "net/netstack.h" +#include "net/mac/tsch/tsch-schedule.h" +#include "net/mac/tsch/tsch.h" +#include "net/mac/tsch/tsch-private.h" +#include "net/rpl/rpl-private.h" +#include "net/mac/tsch/tsch-schedule.h" +#include "net/ip/uip-debug.h" +#include "lib/random.h" +#include "rpl-tools.h" +#include "node-id.h" +#include "waveform.h" +#include "leds.h" +#include "net/ip/uiplib.h" +#include "net/ip/uip-udp-packet.h" +#include +#include +#include + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#define INTERVAL (10) +#define BLINK_TIME (CLOCK_SECOND/4) + +typedef enum { + WAVEFORM_SIN = 0, + WAVEFORM_TRIANGLE = 1, + WAVEFORM_POS_SAWTOOTH = 2, + WAVEFORM_NEG_SAWTOOTH = 3, + NUMBER_OF_WAVEFORMS = 4 +} waveform_t; + +typedef struct { + const int8 * table; + char * str; +} wave_t; + +static const wave_t waveform_table[] = { {sin_table, "SINE"}, /* WAVEFORM_SIN */ + {triangle_table, "TRIANGLE"}, /* WAVEFORM_TRIANGLE */ + {pos_sawtooth_table, "POS-SAWTOOTH"}, /* WAVEFORM_POS_SAWTOOTH */ + {neg_sawtooth_table, "NEG_SAWTOOTH"}}; /* WAVEFORM_NEG_SAWTOOTH */ + +static int total_time = 0; +static int selected_waveform = 0; + +static void udp_rx_handler(void); +static void my_sprintf(char * udp_buf, int8_t value); + +static struct uip_udp_conn *udp_conn_rx; +static struct uip_udp_conn *udp_conn_tx; +static uip_ip6addr_t ip6addr_host; +static int host_found = 0; +static char udp_buf[120]; +static char *post_mssg = "Trigger"; + +/*******************************************************************************/ +/* Local functions */ +/*******************************************************************************/ +static void +udp_rx_handler(void) +{ + if(uip_newdata()) { + ((char *)uip_appdata)[uip_datalen()] = '\0'; + printf("UDP data from host: %s\n", (char *)uip_appdata); + if (!host_found) { + /* Create socket to talk back to host */ + uip_ipaddr_copy(&ip6addr_host, &UIP_IP_BUF->srcipaddr); + udp_conn_tx = udp_new(&ip6addr_host, UIP_HTONS(8186), NULL); + host_found = 1; + } + } +} + +static void +my_sprintf(char * udp_buf, int8_t value) +{ + /* Fill the buffer with 4 ASCII chars */ + if (value < 0) { + *udp_buf++ = '-'; + } else { + *udp_buf++ = '+'; + } + value = abs(value); + *udp_buf++ = value/100 + '0'; + value %= 100; + *udp_buf++ = value/10 + '0'; + value %= 10; + *udp_buf++ = value + '0'; + *udp_buf = 0; +} + +/*---------------------------------------------------------------------------*/ +PROCESS(node_process, "Node"); +PROCESS(led_process, "LED"); +AUTOSTART_PROCESSES(&node_process); + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(node_process, ev, data) +{ + PROCESS_BEGIN(); + + static int sample_count = 0; + static struct etimer et; + extern unsigned char node_mac[8]; + + leds_init(); + + /* 3 possible roles: + * - role_6ln: simple node, will join any network, secured or not + * - role_6dr: DAG root, will advertise (unsecured) beacons + * - role_6dr_sec: DAG root, will advertise secured beacons + * */ + static int is_coordinator = 0; + static enum { role_6ln, role_6dr, role_6dr_sec } node_role; + + /* Set node with ID == 1 as coordinator, handy in Cooja. */ + if(node_id == 1) { + if(LLSEC802154_ENABLED) { + node_role = role_6dr_sec; + } else { + node_role = role_6dr; + } + } else { + node_role = role_6ln; + } + + printf("Init: node starting with role %s\n", + node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec"); + +#if WITH_TSCH + tsch_set_pan_secured(LLSEC802154_ENABLED && (node_role == role_6dr_sec)); +#endif /* WITH_TSCH */ + is_coordinator = node_role > role_6ln; + + if(is_coordinator) { + uip_ipaddr_t prefix; + uip_ip6addr(&prefix, 0xbbbb, 0, 0, 0, 0, 0, 0, 0); + rpl_tools_init(&prefix); + } else { + rpl_tools_init(NULL); + } + + /* Selected waveform depends on LS byte of MAC */ + selected_waveform = node_mac[7] % NUMBER_OF_WAVEFORMS; + printf("LS-Byte=0x%x; waveform=%d\n", node_mac[7], selected_waveform); + + process_start(&led_process, NULL); + + /* Listen to any host on 8185 */ + udp_conn_rx = udp_new(NULL, 0, NULL); + udp_bind(udp_conn_rx, UIP_HTONS(8185)); + + /* Wait for timer event + On timer event, handle next sample */ + etimer_set(&et, INTERVAL*CLOCK_SECOND); + while(1) { + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et) || (ev == tcpip_event)); + if (ev == tcpip_event) { + udp_rx_handler(); + } + if (etimer_expired(&et) ) { + /* Restart timer */ + total_time += INTERVAL; + if (host_found) { + /* Make sample count dependent on asn. After a disconnect, waveforms remain + synchronous. Use node_mac to create phase offset between waveforms in different nodes */ + sample_count = ((current_asn.ls4b/((1000/(TSCH_CONF_DEFAULT_TIMESLOT_LENGTH/1000)))/INTERVAL)+node_mac[7]) % (SIZE_OF_WAVEFORM-1); + printf("%d sec. waveform=%s. cnt=%d. value=%d\n", total_time, waveform_table[selected_waveform].str, sample_count, waveform_table[selected_waveform].table[sample_count]); + my_sprintf(udp_buf, waveform_table[selected_waveform].table[sample_count]); + uip_udp_packet_send(udp_conn_tx, udp_buf, strlen(udp_buf)); + /* Switch LED on and start blink timer (callback timer) */ + process_post(&led_process, PROCESS_EVENT_CONTINUE, post_mssg); + } else { + printf("No host\n"); + } + etimer_restart(&et); + if (total_time%60 == 0) { + /* Print network status once per minute */ + print_network_status(); + } + } + } + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(led_process, ev, data) +{ + PROCESS_BEGIN(); + + /* Switch on leds for 0.25msec after event posted. */ + static struct etimer led_et; + + while(1) { + PROCESS_WAIT_EVENT_UNTIL((ev == PROCESS_EVENT_CONTINUE) && (!strcmp(data, post_mssg))); + leds_on(LEDS_RED); + etimer_set(&led_et, CLOCK_SECOND/4); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&led_et)); + etimer_stop(&led_et); + leds_off(LEDS_RED); + } + PROCESS_END(); +} + diff --git a/examples/jn516x/tsch/simple-sensor-network/node/project-conf.h b/examples/jn516x/tsch/simple-sensor-network/node/project-conf.h new file mode 100644 index 000000000..4e08f561c --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/node/project-conf.h @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2015 NXP B.V. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. 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. +* 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. +* +* This file is part of the Contiki operating system. +* +* Author: Theo van Daele +* +*/ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#include "../../common-conf.h" + +#undef UART_BAUD_RATE +#define UART_BAUD_RATE UART_RATE_115200 + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/tsch/simple-sensor-network/node/waveform.h b/examples/jn516x/tsch/simple-sensor-network/node/waveform.h new file mode 100644 index 000000000..a171ff54a --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/node/waveform.h @@ -0,0 +1,214 @@ +/* +* Copyright (c) 2015 NXP B.V. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. 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. +* 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. +* +* This file is part of the Contiki operating system. +* +* Author: Theo van Daele +* +*/ + + +/* This file contains arrays with waveforms. + The arrays are of type int8. No limit on size, but for convenience of demonstrating take care that sample + period may be 10secs or more. Size for all tables should be equal !! */ + +#define SIZE_OF_WAVEFORM 40 + +static const int8 sin_table[] = { +0, +19, +39, +57, +74, +89, +102, +113, +120, +125, +127, +125, +120, +113, +102, +89, +74, +57, +39, +19, +0, +-20, +-40, +-58, +-75, +-90, +-103, +-114, +-121, +-126, +-127, +-126, +-121, +-114, +-103, +-90, +-75, +-58, +-40, +-20 +}; + +static const int8 triangle_table[] = { +-127, +-114, +-101, +-87, +-74, +-61, +-47, +-34, +-21, +-7, +6, +20, +33, +46, +60, +73, +86, +100, +113, +127, +127, +113, +100, +86, +73, +60, +46, +33, +20, +6, +-7, +-21, +-34, +-47, +-61, +-74, +-87, +-101, +-114, +-127 +}; + +static const int8 pos_sawtooth_table[] = { +-127, +-121, +-115, +-108, +-102, +-96, +-89, +-83, +-76, +-70, +-64, +-57, +-51, +-45, +-38, +-32, +-25, +-19, +-13, +-6, +0, +6, +13, +19, +26, +32, +38, +45, +51, +57, +64, +70, +77, +83, +89, +96, +102, +108, +115, +121 +}; + +static const int8 neg_sawtooth_table[] = { +127, +120, +114, +107, +101, +95, +88, +82, +76, +69, +63, +56, +50, +44, +37, +31, +25, +18, +12, +5, +-1, +-7, +-14, +-20, +-26, +-33, +-39, +-46, +-52, +-58, +-65, +-71, +-77, +-84, +-90, +-97, +-103, +-109, +-116, +-122 +}; + + diff --git a/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/Makefile b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/Makefile new file mode 100644 index 000000000..1598632ef --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/Makefile @@ -0,0 +1,49 @@ +CONTIKI_PROJECT=border-router + +TARGET ?= jn516x +JN516x_WITH_DONGLE = 1 +CONTIKI=../../../../.. + +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +PROJECT_SOURCEFILES += slip-bridge.c slip.c + +PROJECTDIRS += .. ../../tools +PROJECT_SOURCEFILES += rpl-tools.c + +CFLAGS += -DWITH_COAP +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += orchestra +APPS += json +APPS += er-coap +APPS += rest-engine + +MODULES += core/net/mac/tsch + +all: $(CONTIKI_PROJECT) +include $(CONTIKI)/Makefile.include + +ifeq ($(PREFIX),) + PREFIX = bbbb::1/64 +endif + +#no flow control +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -v1 -B 1000000 $(PREFIX) + +#using XON/XOFF flow control +connect-router-sw: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -v1 -X -B 1000000 $(PREFIX) + +#using hw flow control +connect-router-hw: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -v1 -H -B 1000000 $(PREFIX) + +#using no flow control +connect-router-no: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -v1 -B 1000000 $(PREFIX) + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 $(PREFIX) diff --git a/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/README.md b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/README.md new file mode 100644 index 000000000..da1bc21ff --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/README.md @@ -0,0 +1,2 @@ +rpl-border-router has been configured and tested to run on a JN5168-dongle in combination +with the NXP IoT Gateway. This requires the baud rate to be configured on 230400Bd. diff --git a/examples/sensinode/border-router/border-router.c b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/border-router.c similarity index 55% rename from examples/sensinode/border-router/border-router.c rename to examples/jn516x/tsch/simple-sensor-network/rpl-border-router/border-router.c index 028a2f770..7657dc190 100644 --- a/examples/sensinode/border-router/border-router.c +++ b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/border-router.c @@ -26,64 +26,45 @@ * This file is part of the Contiki operating system. * */ +/** + * \file + * border-router + * \author + * Niclas Finne + * Joakim Eriksson + * Nicolas Tsiftes + */ #include "contiki.h" #include "contiki-lib.h" #include "contiki-net.h" - -#include - -#define DEBUG DEBUG_PRINT -#include "net/ip/uip-debug.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" #include "net/rpl/rpl.h" -#include "dev/watchdog.h" +#include "simple-udp.h" +#include "net/mac/tsch/tsch.h" +#include "net/mac/tsch/tsch-schedule.h" +#include "net/netstack.h" #include "dev/slip.h" -#include "dev/leds.h" -#include "dev/cc2430_rf.h" -#include "debug.h" +#include "rpl-tools.h" +#include +#include +#include +#include + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +static uip_ipaddr_t prefix; static uint8_t prefix_set; -#if DEBUG -#define PUTSTRING(...) putstring(__VA_ARGS__) -#define PUTHEX(...) puthex(__VA_ARGS__) -#define PUTBIN(...) putbin(__VA_ARGS__) -#define PUTDEC(...) putdec(__VA_ARGS__) -#define PUTCHAR(...) putchar(__VA_ARGS__) -#else -#define PUTSTRING(...) -#define PUTHEX(...) -#define PUTBIN(...) -#define PUTDEC(...) -#define PUTCHAR(...) -#endif -/*---------------------------------------------------------------------------*/ -PROCESS(border_router_process, "Border Router process"); +PROCESS(border_router_process, "Border router process"); + AUTOSTART_PROCESSES(&border_router_process); /*---------------------------------------------------------------------------*/ -static void -print_local_addresses(void) CC_NON_BANKED -{ - int i; - uint8_t state; - - PUTSTRING("Router's IPv6 addresses:\n"); - for(i = 0; i < UIP_DS6_ADDR_NB; i++) { - state = uip_ds6_if.addr_list[i].state; - if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state - == ADDR_PREFERRED)) { - PUTSTRING(" "); - PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); - PUTCHAR('\n'); - if(state == ADDR_TENTATIVE) { - uip_ds6_if.addr_list[i].state = ADDR_PREFERRED; - } - } - } -} -/*---------------------------------------------------------------------------*/ -static void -request_prefix(void) CC_NON_BANKED +void +request_prefix(void) { /* mess up uip_buf with a dirty request... */ uip_buf[0] = '?'; @@ -93,25 +74,11 @@ request_prefix(void) CC_NON_BANKED uip_len = 0; } /*---------------------------------------------------------------------------*/ -/* Set our prefix when we receive one over SLIP */ void set_prefix_64(uip_ipaddr_t *prefix_64) { - rpl_dag_t *dag; - uip_ipaddr_t ipaddr; - memcpy(&ipaddr, prefix_64, 16); + memcpy(&prefix, prefix_64, 16); prefix_set = 1; - uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); - uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); - - /* Become root of a new DODAG with ID our global v6 address */ - dag = rpl_set_root(RPL_DEFAULT_INSTANCE, &ipaddr); - if(dag != NULL) { - rpl_set_prefix(dag, &ipaddr, 64); - PUTSTRING("Created a new RPL dag with ID: "); - PRINT6ADDR(&dag->dag_id); - PUTCHAR('\n'); - } } /*---------------------------------------------------------------------------*/ PROCESS_THREAD(border_router_process, ev, data) @@ -119,32 +86,39 @@ PROCESS_THREAD(border_router_process, ev, data) static struct etimer et; PROCESS_BEGIN(); - PUTSTRING("Border Router started\n"); + +/* While waiting for the prefix to be sent through the SLIP connection, the future + * border router can join an existing DAG as a parent or child, or acquire a default + * router that will later take precedence over the SLIP fallback interface. + * Prevent that by turning the radio off until we are initialized as a DAG root. + */ prefix_set = 0; - leds_on(LEDS_RED); + PROCESS_PAUSE(); + PRINTF("RPL-Border router started\n"); + + /* Request prefix until it has been received */ while(!prefix_set) { - leds_on(LEDS_GREEN); - PUTSTRING("Prefix request.\n"); etimer_set(&et, CLOCK_SECOND); request_prefix(); - leds_off(LEDS_GREEN); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + PRINTF("Waiting for prefix\n"); } - /* We have created a new DODAG when we reach here */ - PUTSTRING("On Channel "); - PUTDEC(cc2430_rf_channel_get()); - PUTCHAR('\n'); + PRINTF("Obtained prefix: "); + uip_debug_ipaddr_print(&prefix); + PRINTF("\n"); - print_local_addresses(); - - leds_off(LEDS_RED); - - PROCESS_EXIT(); + rpl_tools_init(&prefix); + etimer_set(&et, CLOCK_SECOND * 60); + while(1) { + print_network_status(); + PROCESS_YIELD_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + } PROCESS_END(); } /*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/project-conf.h b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/project-conf.h new file mode 100644 index 000000000..de5e4bdd6 --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/project-conf.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +#ifndef BR_PROJECT_ROUTER_CONF_H_ +#define BR_PROJECT_ROUTER_CONF_H_ + +#ifndef UIP_FALLBACK_INTERFACE +#define UIP_FALLBACK_INTERFACE rpl_interface +#endif + +/* Needed for slip-bridge */ +#undef SLIP_BRIDGE_CONF_NO_PUTCHAR +#define SLIP_BRIDGE_CONF_NO_PUTCHAR 0 + +#include "../../common-conf.h" + +#undef UART_BAUD_RATE +#define UART_BAUD_RATE UART_RATE_230400 + + +#endif /* PROJECT_ROUTER_CONF_H_ */ diff --git a/examples/sensinode/border-router/slip-bridge.c b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/slip-bridge.c similarity index 66% rename from examples/sensinode/border-router/slip-bridge.c rename to examples/jn516x/tsch/simple-sensor-network/rpl-border-router/slip-bridge.c index fc9f95a28..e4239a8e9 100644 --- a/examples/sensinode/border-router/slip-bridge.c +++ b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/slip-bridge.c @@ -40,9 +40,12 @@ #include "net/ip/uip.h" #include "net/ipv6/uip-ds6.h" -#include "net/rpl/rpl.h" #include "dev/slip.h" +#if CONTIKI_TARGET_JN516X +#include "dev/uart0.h" +#else #include "dev/uart1.h" +#endif #include #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) @@ -50,6 +53,10 @@ #define DEBUG DEBUG_NONE #include "net/ip/uip-debug.h" +#ifndef BAUD2UBR +#define BAUD2UBR(X) (X) +#endif + void set_prefix_64(uip_ipaddr_t *); static uip_ipaddr_t last_sender; @@ -58,10 +65,10 @@ static void slip_input_callback(void) { PRINTF("SIN: %u\n", uip_len); - if((char)uip_buf[0] == '!') { + if(uip_buf[0] == '!') { PRINTF("Got configuration message of type %c\n", uip_buf[1]); uip_len = 0; - if((char)uip_buf[1] == 'P') { + if(uip_buf[1] == 'P') { uip_ipaddr_t prefix; /* Here we set a prefix !!! */ memset(&prefix, 0, 16); @@ -71,6 +78,22 @@ slip_input_callback(void) PRINTF("\n"); set_prefix_64(&prefix); } + } else if (uip_buf[0] == '?') { + PRINTF("Got request message of type %c\n", uip_buf[1]); + if(uip_buf[1] == 'M') { + char* hexchar = "0123456789abcdef"; + int j; + /* this is just a test so far... just to see if it works */ + uip_buf[0] = '!'; + for(j = 0; j < 8; j++) { + uip_buf[2 + j * 2] = hexchar[uip_lladdr.addr[j] >> 4]; + uip_buf[3 + j * 2] = hexchar[uip_lladdr.addr[j] & 15]; + } + uip_len = 18; + slip_send(); + + } + uip_len = 0; } /* Save the last sender received over SLIP to avoid bouncing the packet back if no route is found */ @@ -80,24 +103,62 @@ slip_input_callback(void) static void init(void) { + slip_arch_init(BAUD2UBR(115200)); process_start(&slip_process, NULL); slip_set_input_callback(slip_input_callback); } /*---------------------------------------------------------------------------*/ -static void +static int output(void) { if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) { /* Do not bounce packets back over SLIP if the packet was received over SLIP */ - PRINTF("slip-bridge: Destination off-link but no route\n"); + PRINTF("slip-bridge: Destination off-link but no route src="); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF(" dst="); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("\n"); } else { PRINTF("SUT: %u\n", uip_len); slip_send(); + printf("\n"); } + return 0; } + /*---------------------------------------------------------------------------*/ -const struct uip_fallback_interface slip_interface = { +#if !SLIP_BRIDGE_CONF_NO_PUTCHAR +#undef putchar +int +putchar(int c) +{ +#define SLIP_END 0300 + static char debug_frame = 0; + + if(!debug_frame) { /* Start of debug output */ + slip_arch_writeb(SLIP_END); + slip_arch_writeb('\r'); /* Type debug line == '\r' */ + debug_frame = 1; + } + + /* Need to also print '\n' because for example COOJA will not show + any output before line end */ + slip_arch_writeb((char)c); + + /* + * Line buffered output, a newline marks the end of debug output and + * implicitly flushes debug output. + */ + if(c == '\n') { + slip_arch_writeb(SLIP_END); + debug_frame = 0; + } + return c; +} +#endif +/*---------------------------------------------------------------------------*/ +const struct uip_fallback_interface rpl_interface = { init, output }; /*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/tsch/simple-sensor-network/script/Output-Visualisation.py b/examples/jn516x/tsch/simple-sensor-network/script/Output-Visualisation.py new file mode 100644 index 000000000..4e1699d53 --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/script/Output-Visualisation.py @@ -0,0 +1,148 @@ +# +# Copyright (c) 2015 NXP B.V. +# All rights reserved. +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. 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. +# 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. +# +# This file is part of the Contiki operating system. +# +# Author: Theo van Daele +# +# + +import sys +import time +import socket +import thread +import numpy as np +import Gnuplot + +# Plot buffer length for each node buffer +SIZE_NODE_DATA = 600 + +# Repeat time for connect watchdog and ping +TICK = 5 +# Connect watchdog. Unit: [TICK] +CONNECT_WATCHDOG = 30/TICK + +TX_PORT = 8185 +RX_PORT = 8186 + +last_sample_value = 0 +x_range = np.arange(SIZE_NODE_DATA) +dummy_data = np.zeros(SIZE_NODE_DATA, dtype=np.int) +plot = Gnuplot.Data(x_range,dummy_data) +g = Gnuplot.Gnuplot() + +# Attention: Skip leading zero's in IPv6 address list, otherwise address comparison with received UDP packet address goes wrong +NODE_ALIAS = 0 # node name in plot +NODE_DATA = 1 # Time line with data to plot +NODE_CONNECTED = 2 # If 0, not connected, else connect_watchdog value +NODE_LAST_DATA = 3 # Storage for received sample +NODE_PLOT = 4 # Plot instance +node_data = {"bbbb::215:8d00:36:180" : ["NODE-001", np.zeros(SIZE_NODE_DATA, dtype=np.int), 0, last_sample_value, plot], + "bbbb::215:8d00:36:892" : ["NODE-196", np.zeros(SIZE_NODE_DATA, dtype=np.int), 0, last_sample_value, plot], + "bbbb::215:8d00:36:8b1" : ["NODE-193", np.zeros(SIZE_NODE_DATA, dtype=np.int), 0, last_sample_value, plot], + "bbbb::215:8d00:36:8b3" : ["NODE-198", np.zeros(SIZE_NODE_DATA, dtype=np.int), 0, last_sample_value, plot]} + +# List of all nodes derived from node_data list +node_list = node_data.keys() + +def initPlots(): + for node in range(len(node_list)): + node_data_key = node_data[node_list[node]] + g.title('Sensor Network Output') + g.ylabel('Value') + g.xlabel('Time-Span[s]') + g("set yrange [-150:150]") + g("set xrange [0:"+str(SIZE_NODE_DATA)+"]") + node_data_key[NODE_PLOT] = Gnuplot.Data(x_range,node_data_key[NODE_DATA], title=node_data_key[NODE_ALIAS] , with_='lines lw 2') + nodes = [ node_data[node_list[i]][NODE_PLOT] for i in xrange(len(node_list)) ] + g.plot(*nodes) + + + +def udpReceive(): + """RUNS ON SEPARATE THREAD """ + while True: + data, addr = s_rx.recvfrom(128) + data = data.replace("\"","").strip("\0") # strip termination byte and possible + node_data_key = node_data[addr[0]] + # Indicate node is connected + node_data_key[NODE_CONNECTED] = CONNECT_WATCHDOG + print addr[0] + ' (' + node_data_key[NODE_ALIAS] + ') : ' + data + # Write new data at index in data buffer. Data buffer is view of plot + data_lock.acquire() + node_data_key[NODE_LAST_DATA] = int(data) + data_lock.release() + +def plotGraphs(): + while True: + data_lock.acquire() + for node in range(len(node_list)): + node_data_key = node_data[node_list[node]] + for k in range(1,SIZE_NODE_DATA,1): + node_data_key[NODE_DATA][k-1] = node_data_key[NODE_DATA][k] + node_data_key[NODE_DATA][SIZE_NODE_DATA-1] = node_data_key[NODE_LAST_DATA] + if node_data_key[NODE_CONNECTED] == 0: + node_data_key[NODE_PLOT] = Gnuplot.Data(x_range,node_data_key[NODE_DATA], title=node_data_key[NODE_ALIAS], with_='dots') + else: + node_data_key[NODE_PLOT] = Gnuplot.Data(x_range,node_data_key[NODE_DATA], title=node_data_key[NODE_ALIAS], with_='lines lw 2') + nodes = [ node_data[node_list[i]][NODE_PLOT] for i in xrange(len(node_list)) ] + g.plot(*nodes) + data_lock.release() + time.sleep(1) + + +##### MAIN ##### +s_tx = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) +s_rx = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) +s_rx.bind(('', RX_PORT)) +initPlots() +data_lock = thread.allocate_lock() +thread.start_new_thread(udpReceive, ()) +thread.start_new_thread(plotGraphs, ()) +ping_node_index = 0 +ping_msg = "ping" +while True: + # Every 5 secs, one node of the list in pinged + if (ping_node_index >=len(node_list)): + ping_node_index = 0; + try: + print "ping " + node_data[node_list[ping_node_index]][NODE_ALIAS] + s_tx.sendto(ping_msg, (node_list[ping_node_index], TX_PORT)) + except: + print 'Failed to send to ' + node_list[ping_node_index] + ping_node_index += 1 + # Update connect watchdog + for node in range(len(node_list)): + node_data_key = node_data[node_list[node]] + if (node_data_key[NODE_CONNECTED] > 0): + node_data_key[NODE_CONNECTED] -= 1 + time.sleep(TICK) + + + + + diff --git a/examples/jn516x/tsch/tools/rpl-tools.c b/examples/jn516x/tsch/tools/rpl-tools.c new file mode 100644 index 000000000..b61c693c2 --- /dev/null +++ b/examples/jn516x/tsch/tools/rpl-tools.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2014, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \file + * + * \author Simon Duquennoy + */ + +#include "contiki-conf.h" +#include "contiki-net.h" +#include "net/ip/uip.h" +#include "net/rpl/rpl.h" +#include "orchestra.h" +#include +#include + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +void +print_network_status(void) +{ + int i; + uint8_t state; + uip_ds6_defrt_t *default_route; + uip_ds6_route_t *route; + PRINTA("--- Network status ---\n"); + /* Our IPv6 addresses */ + PRINTA("- Server IPv6 addresses:\n"); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && + (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { + PRINTA("-- "); + uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr); + PRINTA("\n"); + } + } + /* Our default route */ + PRINTA("- Default route:\n"); + default_route = uip_ds6_defrt_lookup(uip_ds6_defrt_choose()); + if(default_route != NULL) { + PRINTA("-- "); + uip_debug_ipaddr_print(&default_route->ipaddr);; + PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)default_route->lifetime.interval); + } else { + PRINTA("-- None\n"); + } + /* Our routing entries */ + PRINTA("- Routing entries (%u in total):\n", uip_ds6_route_num_routes()); + route = uip_ds6_route_head(); + while(route != NULL) { + PRINTA("-- "); + uip_debug_ipaddr_print(&route->ipaddr); + PRINTA(" via "); + uip_debug_ipaddr_print(uip_ds6_route_nexthop(route)); + PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)route->state.lifetime); + route = uip_ds6_route_next(route); + } + PRINTA("----------------------\n"); +} +/*---------------------------------------------------------------------------*/ +static void +print_local_addresses(void) +{ + int i; + uint8_t state; + + PRINTA("Server IPv6 addresses:\n"); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && + (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { + PRINTA(" "); + uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr); + PRINTA("\n"); + } + } +} +/*---------------------------------------------------------------------------*/ +void +rpl_tools_init(uip_ipaddr_t *br_prefix) +{ + uip_ipaddr_t global_ipaddr; + +#if TSCH_CONFIG == TSCH_CONFIG_ORCHESTRA + orchestra_init(); +#endif + if(br_prefix) { /* We are root */ + /* If an RDC layer is used, turn it off (i.e. keep the radio on at the root). */ + NETSTACK_RDC.off(1); + memcpy(&global_ipaddr, br_prefix, 16); + uip_ds6_set_addr_iid(&global_ipaddr, &uip_lladdr); + uip_ds6_addr_add(&global_ipaddr, 0, ADDR_AUTOCONF); + rpl_set_root(RPL_DEFAULT_INSTANCE, &global_ipaddr); + rpl_set_prefix(rpl_get_any_dag(), br_prefix, 64); + rpl_repair_root(RPL_DEFAULT_INSTANCE); + } + + /* Start TSCH */ + NETSTACK_MAC.on(); + print_local_addresses(); +} diff --git a/examples/jn516x/tsch/tools/rpl-tools.h b/examples/jn516x/tsch/tools/rpl-tools.h new file mode 100644 index 000000000..b04cdb712 --- /dev/null +++ b/examples/jn516x/tsch/tools/rpl-tools.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + + * \author Simon Duquennoy + */ + +void rpl_tools_init(uip_ipaddr_t *br_prefix); +void print_network_status(void); diff --git a/examples/jn516x/tsch/tx-power-verification/README.md b/examples/jn516x/tsch/tx-power-verification/README.md new file mode 100644 index 000000000..8a3f7e008 --- /dev/null +++ b/examples/jn516x/tsch/tx-power-verification/README.md @@ -0,0 +1,13 @@ +The tx-power-control example can be used to check the link between a node and an rpl-border-router. +After a link is established, the following coap rresources are exposed: + +node: +Set-Tx-Power: a PUT/POST resource to set the TX power of the device. The firmware in the device will set the + TX power to the nearest available value. +Get-Tx-Power: a GET resource to retrieve the actual Tx power that is set. + + +rpl-border-router: +Get-RSSI: a GET resource that shows the detected energy level +Get-Last-RSSI:a GET resource that shows the RSSI of the last received packet. When there is only 1 node, Get-Last-RSSI will + show the effect of changing the TX power level on that node. diff --git a/examples/jn516x/tsch/tx-power-verification/node/Makefile b/examples/jn516x/tsch/tx-power-verification/node/Makefile new file mode 100644 index 000000000..0cb2d4bcb --- /dev/null +++ b/examples/jn516x/tsch/tx-power-verification/node/Makefile @@ -0,0 +1,25 @@ +CONTIKI_PROJECT = node + +TARGET ?= jn516x +JN516x_WITH_DONGLE = 1 + +CONTIKI=../../../../.. +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +PROJECTDIRS += .. ../../tools +PROJECT_SOURCEFILES += rpl-tools.c + +CFLAGS += -DWITH_COAP +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += orchestra +APPS += json +APPS += er-coap +APPS += rest-engine + +MODULES += core/net/mac/tsch + +all: $(CONTIKI_PROJECT) + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/tsch/tx-power-verification/node/node.c b/examples/jn516x/tsch/tx-power-verification/node/node.c new file mode 100644 index 000000000..85b19fa10 --- /dev/null +++ b/examples/jn516x/tsch/tx-power-verification/node/node.c @@ -0,0 +1,121 @@ +/* +* Copyright (c) 2015 NXP B.V. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. 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. +* 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. +* +* This file is part of the Contiki operating system. +* +* Author: Theo van Daele +* +*/ +#include "contiki.h" +#include "net/ipv6/uip-ds6.h" +#include "net/netstack.h" +#include "net/ip/uip.h" +#include "net/linkaddr.h" +#include "rpl-tools.h" +#include "rest-engine.h" +#include +#include +#include + +static void set_tx_power_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_tx_power_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +static char content[REST_MAX_CHUNK_SIZE]; +static int content_len = 0; + +#define CONTENT_PRINTF(...) { if(content_len < sizeof(content)) content_len += snprintf(content+content_len, sizeof(content)-content_len, __VA_ARGS__); } + +/*---------------------------------------------------------------------------*/ +PROCESS(start_app, "START_APP"); +AUTOSTART_PROCESSES(&start_app); +/*---------------------------------------------------------------------------*/ + +/*********** sensor/ resource ************************************************/ +RESOURCE(resource_set_tx_power, + "title=\"Set TX Power\"", + NULL, + set_tx_power_handler, + set_tx_power_handler, + NULL); +static void +set_tx_power_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content = NULL; + int tx_level; + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.get_request_payload(request, &request_content); + tx_level = atoi((const char *)request_content); + NETSTACK_RADIO.set_value(RADIO_PARAM_TXPOWER, tx_level); + } +} + +RESOURCE(resource_get_tx_power, + "title=\"Get TX Power\"", + get_tx_power_handler, + NULL, + NULL, + NULL); +static void +get_tx_power_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + int tx_level; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + NETSTACK_RADIO.get_value(RADIO_PARAM_TXPOWER, &tx_level); + CONTENT_PRINTF("%d", tx_level); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(start_app, ev, data) +{ + PROCESS_BEGIN(); + static int is_coordinator = 0; + + /* Start network stack */ + if(is_coordinator) { + uip_ipaddr_t prefix; + uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); + rpl_tools_init(&prefix); + } else { + rpl_tools_init(NULL); + } + printf("Starting RPL node\n"); + + rest_init_engine(); + rest_activate_resource(&resource_set_tx_power, "Set-TX-Power"); + rest_activate_resource(&resource_get_tx_power, "Get-TX-Power"); + + PROCESS_END(); +} diff --git a/examples/jn516x/tsch/tx-power-verification/node/project-conf.h b/examples/jn516x/tsch/tx-power-verification/node/project-conf.h new file mode 100644 index 000000000..77890c46e --- /dev/null +++ b/examples/jn516x/tsch/tx-power-verification/node/project-conf.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \author Simon Duquennoy + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#include "../../common-conf.h" + +#undef UART_BAUD_RATE +#define UART_BAUD_RATE UART_RATE_115200 + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/tsch/tx-power-verification/rpl-border-router/Makefile b/examples/jn516x/tsch/tx-power-verification/rpl-border-router/Makefile new file mode 100644 index 000000000..15c5da2a2 --- /dev/null +++ b/examples/jn516x/tsch/tx-power-verification/rpl-border-router/Makefile @@ -0,0 +1,50 @@ +CONTIKI_PROJECT=rpl-border-router + +TARGET ?= jn516x +JN516x_WITH_DONGLE = 1 + +CONTIKI=../../../../.. + +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +PROJECT_SOURCEFILES += slip-bridge.c slip.c + +PROJECTDIRS += .. ../../tools +PROJECT_SOURCEFILES += rpl-tools.c + +CFLAGS += -DWITH_COAP +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += orchestra +APPS += json +APPS += er-coap +APPS += rest-engine + +MODULES += core/net/mac/tsch + +all: $(CONTIKI_PROJECT) +include $(CONTIKI)/Makefile.include + +ifeq ($(PREFIX),) + PREFIX = aaaa::1/64 +endif + +#no flow control +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -v1 -B 1000000 $(PREFIX) + +#using XON/XOFF flow control +connect-router-sw: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -v1 -X -B 1000000 $(PREFIX) + +#using hw flow control +connect-router-hw: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -v1 -H -B 1000000 $(PREFIX) + +#using no flow control +connect-router-no: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -v1 -B 1000000 $(PREFIX) + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 $(PREFIX) diff --git a/examples/jn516x/tsch/tx-power-verification/rpl-border-router/project-conf.h b/examples/jn516x/tsch/tx-power-verification/rpl-border-router/project-conf.h new file mode 100644 index 000000000..f40b47809 --- /dev/null +++ b/examples/jn516x/tsch/tx-power-verification/rpl-border-router/project-conf.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +#ifndef BR_PROJECT_ROUTER_CONF_H_ +#define BR_PROJECT_ROUTER_CONF_H_ + +#ifndef UIP_FALLBACK_INTERFACE +#define UIP_FALLBACK_INTERFACE rpl_interface +#endif + +/* Needed for slip-bridge */ +#undef SLIP_BRIDGE_CONF_NO_PUTCHAR +#define SLIP_BRIDGE_CONF_NO_PUTCHAR 0 + +#include "../../common-conf.h" + +/* Configuration to reduce RAM */ +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 + +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 14 + +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 16 + +#undef TSCH_QUEUE_CONF_MAX_NEIGHBOR_QUEUES +#define TSCH_QUEUE_CONF_MAX_NEIGHBOR_QUEUES 8 + +#endif /* PROJECT_ROUTER_CONF_H_ */ diff --git a/examples/jn516x/tsch/tx-power-verification/rpl-border-router/rpl-border-router.c b/examples/jn516x/tsch/tx-power-verification/rpl-border-router/rpl-border-router.c new file mode 100644 index 000000000..cd9e2e2a2 --- /dev/null +++ b/examples/jn516x/tsch/tx-power-verification/rpl-border-router/rpl-border-router.c @@ -0,0 +1,169 @@ +/* +* Copyright (c) 2015 NXP B.V. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. 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. +* 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. +* +* This file is part of the Contiki operating system. +* +* Author: Theo van Daele +* +*/ +#include "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "net/rpl/rpl.h" +#include "simple-udp.h" +#include "net/mac/tsch/tsch.h" +#include "net/mac/tsch/tsch-schedule.h" +#include "net/netstack.h" +#include "dev/slip.h" +#include "rest-engine.h" +#include "rpl-tools.h" + +#include +#include +#include +#include + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +static uip_ipaddr_t prefix; +static uint8_t prefix_set; + +static void get_rssi_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_last_rssi_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +static char content[REST_MAX_CHUNK_SIZE]; +static int content_len = 0; + +#define CONTENT_PRINTF(...) { if(content_len < sizeof(content)) content_len += snprintf(content+content_len, sizeof(content)-content_len, __VA_ARGS__); } + +PROCESS(border_router_process, "Border router process"); +AUTOSTART_PROCESSES(&border_router_process); + +RESOURCE(resource_get_rssi, + "title=\"Get RSSI\"", + get_rssi_handler, + NULL, + NULL, + NULL); +static void +get_rssi_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + int rssi_level; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + NETSTACK_RADIO.get_value(RADIO_PARAM_RSSI, &rssi_level); + CONTENT_PRINTF("%d", rssi_level); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} + +RESOURCE(resource_get_last_rssi, + "title=\"Get last RSSI\"", + get_last_rssi_handler, + NULL, + NULL, + NULL); +static void +get_last_rssi_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + int last_rssi_level; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + NETSTACK_RADIO.get_value(RADIO_PARAM_LAST_RSSI, &last_rssi_level); + CONTENT_PRINTF("%d", last_rssi_level); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} + +/*---------------------------------------------------------------------------*/ +void +request_prefix(void) +{ + /* mess up uip_buf with a dirty request... */ + uip_buf[0] = '?'; + uip_buf[1] = 'P'; + uip_len = 2; + slip_send(); + uip_len = 0; +} +/*---------------------------------------------------------------------------*/ +void +set_prefix_64(uip_ipaddr_t *prefix_64) +{ + memcpy(&prefix, prefix_64, 16); + prefix_set = 1; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(border_router_process, ev, data) +{ + static struct etimer et; + + PROCESS_BEGIN(); + +/* While waiting for the prefix to be sent through the SLIP connection, the future + * border router can join an existing DAG as a parent or child, or acquire a default + * router that will later take precedence over the SLIP fallback interface. + * Prevent that by turning the radio off until we are initialized as a DAG root. + */ + prefix_set = 0; + + PROCESS_PAUSE(); + + PRINTF("RPL-Border router started\n"); + + /* Request prefix until it has been received */ + while(!prefix_set) { + etimer_set(&et, CLOCK_SECOND); + request_prefix(); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + PRINTF("Waiting for prefix\n"); + } + + PRINTF("Obtained prefix: "); + uip_debug_ipaddr_print(&prefix); + PRINTF("\n"); + + rpl_tools_init(&prefix); + + rest_init_engine(); + rest_activate_resource(&resource_get_rssi, "Get-RSSI"); + rest_activate_resource(&resource_get_last_rssi, "Get-Last-RSSI"); + + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/tsch/tx-power-verification/rpl-border-router/slip-bridge.c b/examples/jn516x/tsch/tx-power-verification/rpl-border-router/slip-bridge.c new file mode 100644 index 000000000..e4239a8e9 --- /dev/null +++ b/examples/jn516x/tsch/tx-power-verification/rpl-border-router/slip-bridge.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file + * Slip fallback interface + * \author + * Niclas Finne + * Joakim Eriksson + * Joel Hoglund + * Nicolas Tsiftes + */ + +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "dev/slip.h" +#if CONTIKI_TARGET_JN516X +#include "dev/uart0.h" +#else +#include "dev/uart1.h" +#endif +#include + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +#ifndef BAUD2UBR +#define BAUD2UBR(X) (X) +#endif + +void set_prefix_64(uip_ipaddr_t *); + +static uip_ipaddr_t last_sender; +/*---------------------------------------------------------------------------*/ +static void +slip_input_callback(void) +{ + PRINTF("SIN: %u\n", uip_len); + if(uip_buf[0] == '!') { + PRINTF("Got configuration message of type %c\n", uip_buf[1]); + uip_len = 0; + if(uip_buf[1] == 'P') { + uip_ipaddr_t prefix; + /* Here we set a prefix !!! */ + memset(&prefix, 0, 16); + memcpy(&prefix, &uip_buf[2], 8); + PRINTF("Setting prefix "); + PRINT6ADDR(&prefix); + PRINTF("\n"); + set_prefix_64(&prefix); + } + } else if (uip_buf[0] == '?') { + PRINTF("Got request message of type %c\n", uip_buf[1]); + if(uip_buf[1] == 'M') { + char* hexchar = "0123456789abcdef"; + int j; + /* this is just a test so far... just to see if it works */ + uip_buf[0] = '!'; + for(j = 0; j < 8; j++) { + uip_buf[2 + j * 2] = hexchar[uip_lladdr.addr[j] >> 4]; + uip_buf[3 + j * 2] = hexchar[uip_lladdr.addr[j] & 15]; + } + uip_len = 18; + slip_send(); + + } + uip_len = 0; + } + /* Save the last sender received over SLIP to avoid bouncing the + packet back if no route is found */ + uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr); +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + slip_arch_init(BAUD2UBR(115200)); + process_start(&slip_process, NULL); + slip_set_input_callback(slip_input_callback); +} +/*---------------------------------------------------------------------------*/ +static int +output(void) +{ + if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) { + /* Do not bounce packets back over SLIP if the packet was received + over SLIP */ + PRINTF("slip-bridge: Destination off-link but no route src="); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF(" dst="); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("\n"); + } else { + PRINTF("SUT: %u\n", uip_len); + slip_send(); + printf("\n"); + } + return 0; +} + +/*---------------------------------------------------------------------------*/ +#if !SLIP_BRIDGE_CONF_NO_PUTCHAR +#undef putchar +int +putchar(int c) +{ +#define SLIP_END 0300 + static char debug_frame = 0; + + if(!debug_frame) { /* Start of debug output */ + slip_arch_writeb(SLIP_END); + slip_arch_writeb('\r'); /* Type debug line == '\r' */ + debug_frame = 1; + } + + /* Need to also print '\n' because for example COOJA will not show + any output before line end */ + slip_arch_writeb((char)c); + + /* + * Line buffered output, a newline marks the end of debug output and + * implicitly flushes debug output. + */ + if(c == '\n') { + slip_arch_writeb(SLIP_END); + debug_frame = 0; + } + return c; +} +#endif +/*---------------------------------------------------------------------------*/ +const struct uip_fallback_interface rpl_interface = { + init, output +}; +/*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/tsch/uart1-test-node/Makefile b/examples/jn516x/tsch/uart1-test-node/Makefile new file mode 100644 index 000000000..76a3d6252 --- /dev/null +++ b/examples/jn516x/tsch/uart1-test-node/Makefile @@ -0,0 +1,26 @@ +CONTIKI_PROJECT = uart1-test-node + +TARGET = jn516x +JN516x_WITH_DR1174 = 1 +TARGET_WITH_UART1 = 1 + +CONTIKI=../../../.. +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +PROJECTDIRS += .. ../tools +PROJECT_SOURCEFILES += rpl-tools.c + +CFLAGS += -DWITH_COAP +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += orchestra +APPS += json +APPS += er-coap +APPS += rest-engine + +MODULES += core/net/mac/tsch + +all: $(CONTIKI_PROJECT) + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/tsch/uart1-test-node/README.md b/examples/jn516x/tsch/uart1-test-node/README.md new file mode 100644 index 000000000..73eefd1ac --- /dev/null +++ b/examples/jn516x/tsch/uart1-test-node/README.md @@ -0,0 +1,16 @@ +This example is a simple TSCH node used to test uart1 functionality of a JN516x on a node. +Note: uart0 is usually configured as serial port for flashing the JN516x and for logging and debug output. + +The TX output of uart1 is represented as a PUT/POST resource for a Coap client. +A string entered on a Coap plug-in of a browser will be forwarded over the wireless TSCH network to the +the TX output of UART1. + +The RX input of uart1 is represented as an OBSERVABLE resource for a Coap client. +If a string is entered on uart1 that is terminated with a Line Feed or Carriage Return, +a Coap event will notify Coap clients to issue a GET event. +This will make string available at the Coap client side. + +The example has been verified on a DR1174 evaluation board + + + \ No newline at end of file diff --git a/examples/jn516x/tsch/uart1-test-node/project-conf.h b/examples/jn516x/tsch/uart1-test-node/project-conf.h new file mode 100644 index 000000000..f72569a3c --- /dev/null +++ b/examples/jn516x/tsch/uart1-test-node/project-conf.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \author Simon Duquennoy + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#include "../common-conf.h" + +#undef UART_BAUD_RATE +#define UART_BAUD_RATE UART_RATE_115200 + +#undef UART1_BAUD_RATE +#define UART1_BAUD_RATE UART_RATE_115200 + +#undef UART1_CONF_TX_BUFFER_SIZE +#define UART1_CONF_TX_BUFFER_SIZE 32 + +#undef UART1_CONF_RX_BUFFER_SIZE +#define UART1_CONF_RX_BUFFER_SIZE 32 + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/tsch/uart1-test-node/uart1-test-node.c b/examples/jn516x/tsch/uart1-test-node/uart1-test-node.c new file mode 100644 index 000000000..4accd3dc4 --- /dev/null +++ b/examples/jn516x/tsch/uart1-test-node/uart1-test-node.c @@ -0,0 +1,259 @@ +/* +* Copyright (c) 2015 NXP B.V. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. 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. +* 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. +* +* This file is part of the Contiki operating system. +* +* Author: Theo van Daele +* +*/ +#include "contiki.h" +#include "net/ipv6/uip-ds6.h" +#include "net/ip/uip.h" +#include "net/linkaddr.h" +#include "rpl-tools.h" +#include "rest-engine.h" +#include "sys/ctimer.h" +#include "dev/uart-driver.h" +#include "uart1.h" +#include + +static void get_coap_rx_uart1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void event_coap_rx_uart1_handler(void); +static void put_post_tx_uart1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void string2uart1(uint8_t *c); +static int handleRxChar(uint8_t c); +static int get_ringbuf(uint8_t *c); +static int put_ringbuf(uint8_t c); + +/* COAP helpers */ +static char content[REST_MAX_CHUNK_SIZE]; +static int content_len = 0; +#define CONTENT_PRINTF(...) { if(content_len < sizeof(content)) content_len += snprintf(content+content_len, sizeof(content)-content_len, __VA_ARGS__); } + +/* Ringbuf: written to by uart isr. Size must be power of 2 */ +#define RINGBUF_SIZE 32 +#define RINGBUF_MAX_INDEX (RINGBUF_SIZE-1) +static char ringbuf[RINGBUF_SIZE]; +static int head_index = 1; /* index to write next data */ +static int tail_index = 0; /* index where last read took place */ + +/* String aligned buffer */ +#define RX_BUFFER_SIZE RINGBUF_SIZE +static uint8_t rx_buf[RX_BUFFER_SIZE+1]; +static uint8_t rx_buf_index = 0; /* index for rx_buf */ + +/*---------------------------------------------------------------------------*/ +PROCESS(start_app, "START_APP"); +PROCESS(rx_data_process, "RX_DATA"); +AUTOSTART_PROCESSES(&start_app, &rx_data_process); +/*---------------------------------------------------------------------------*/ + +/*********** COAP resources *************************************************/ +/*****************************************************************************/ +/* Observable resource and event handler to obtain terminal input from UART1 */ +/*****************************************************************************/ +EVENT_RESOURCE(resource_coap_rx_uart1, /* name */ + "obs;title=\"rx_uart1\"", /* attributes */ + get_coap_rx_uart1_handler, /* GET handler */ + NULL, /* POST handler */ + NULL, /* PUT handler */ + NULL, /* DELETE handler */ + event_coap_rx_uart1_handler); /* event handler */ +static void +get_coap_rx_uart1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + CONTENT_PRINTF("%s", rx_buf); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} + +static void +event_coap_rx_uart1_handler(void) +{ + /* Registered observers are notified and will trigger the GET handler to create the response. */ + REST.notify_subscribers(&resource_coap_rx_uart1); +} + +/*****************************************************************************/ +/* GET/PUT resource to send data to terminal on UART1 */ +/*****************************************************************************/ +RESOURCE(resource_coap_tx_uart1, /* name */ + "obs;title=\"tx_uart1\"", /* attributes */ + NULL, /* GET handler */ + put_post_tx_uart1_handler, /* POST handler */ + put_post_tx_uart1_handler, /* PUT handler */ + NULL); /* DELETE handler */ + +static void +put_post_tx_uart1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content = NULL; + unsigned int accept = -1; + + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.get_request_payload(request, &request_content); + string2uart1((uint8_t *)request_content); + } +} + + +/*********** End COAP resources *********************************************/ + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(start_app, ev, data) +{ + PROCESS_BEGIN(); + static int is_coordinator = 0; + + memset(rx_buf, '\0', sizeof(rx_buf)); + /* Define process that handles data */ + process_start(&rx_data_process ,NULL); + /* Initialise UART1 */ + uart1_init(UART1_BAUD_RATE); + /* Callback received byte */ + uart1_set_input(handleRxChar); + + /* Start network stack */ + if(is_coordinator) { + uip_ipaddr_t prefix; + uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); + rpl_tools_init(&prefix); + } else { + rpl_tools_init(NULL); + } + printf("Starting RPL node\n"); + + rest_init_engine(); + rest_activate_resource(&resource_coap_rx_uart1, "UART1-RX"); + rest_activate_resource(&resource_coap_tx_uart1, "UART1-TX"); + + PROCESS_END(); +} + + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(rx_data_process, ev, data) +{ + PROCESS_BEGIN(); + + /* Process is polled whenever data is available from uart isr */ + uint8_t c; + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + /* Read RX ringbuffer. ASCII chars Output when LF is seen. + If overflowed, strings are skipped */ + do { + if (get_ringbuf(&c) == -1) { + break; /* No more rx char's in ringbuffer */ + } else { + if (rx_buf_index == RX_BUFFER_SIZE) { /* Skip current content if buffer full */ + rx_buf_index = 0; + } + rx_buf[rx_buf_index++] = c; + if ((c == '\n')||(c == '\r')) { + rx_buf[rx_buf_index] = '\0'; + printf("RX on UART1: %s", rx_buf); + /* Signal event to coap clients. + Demo assumes data is consumed before new data comes in */ + event_coap_rx_uart1_handler(); + rx_buf_index = 0; + } + } + } while (1); + } + PROCESS_END(); +} + +/*************************************************************************/ +/* Local test functions */ +/*************************************************************************/ +/* TX function for UART1 */ +static void +string2uart1(uint8_t *c) +{ + while (*c!= '\0') { + uart1_writeb(*c); + c++; + } +} + +/* handleRxChar runs on uart isr */ +static int +handleRxChar(uint8_t c) +{ + if (put_ringbuf(c) == -1) { + printf("Ringbuf full. Skip char\n"); + } else { + /* Send event to rx data handler */ + process_poll(&rx_data_process); + } + return 0; +} + +/* Simple ringbuffer + if tail==head, no data has been written yet on that position. So, empty buffer + is also initial state */ +static int +get_ringbuf(uint8_t *c) +{ + int return_val = 0; + + uart1_disable_interrupts(); + if (head_index != ((tail_index + 1)&RINGBUF_MAX_INDEX)) { + tail_index = ((tail_index + 1)& RINGBUF_MAX_INDEX); + *c = ringbuf[tail_index]; + } else { + return_val = -1; + } + uart1_enable_interrupts(); + return return_val; +} + +static int +put_ringbuf(uint8_t c) +{ + int return_val = 0; + + uart1_disable_interrupts(); + if (head_index != tail_index) { + ringbuf[head_index] = c; + head_index = ((head_index+1)&RINGBUF_MAX_INDEX); + } else { + return_val = -1; + } + uart1_enable_interrupts(); + return return_val; +} + diff --git a/examples/llsec/ccm-star-tests/encryption/Makefile b/examples/llsec/ccm-star-tests/encryption/Makefile new file mode 100644 index 000000000..078714794 --- /dev/null +++ b/examples/llsec/ccm-star-tests/encryption/Makefile @@ -0,0 +1,11 @@ +CONTIKI_PROJECT = tests +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../../.. +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +#linker optimizations +SMALL=1 + +CONTIKI_WITH_IPV6 = 1 +include $(CONTIKI)/Makefile.include diff --git a/platform/iris/dev/adc.h b/examples/llsec/ccm-star-tests/encryption/project-conf.h similarity index 89% rename from platform/iris/dev/adc.h rename to examples/llsec/ccm-star-tests/encryption/project-conf.h index a51b3cebe..55e4e35d4 100644 --- a/platform/iris/dev/adc.h +++ b/examples/llsec/ccm-star-tests/encryption/project-conf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, University of Colombo School of Computing + * Copyright (c) 2013, Hasso-Plattner-Institut. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,11 +30,11 @@ * */ -#ifndef ADC_H_ -#define ADC_H_ +/** + * \file + * Testing CTR + * \author + * Konrad Krentz + */ -void adc_init(); - -uint16_t get_adc(int channel); - -#endif /* ADC_H_ */ +#define LLSEC802154_CONF_ENABLED 1 diff --git a/examples/llsec/ccm-star-tests/encryption/tests.c b/examples/llsec/ccm-star-tests/encryption/tests.c new file mode 100644 index 000000000..0ef158960 --- /dev/null +++ b/examples/llsec/ccm-star-tests/encryption/tests.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2013, Hasso-Plattner-Institut. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Testing CTR + * \author + * Konrad Krentz + */ + +#include "contiki.h" +#include "net/packetbuf.h" +#include "net/netstack.h" +#include "net/llsec/llsec802154.h" +#include "lib/ccm-star.h" +#include "net/llsec/ccm-star-packetbuf.h" +#include "net/mac/frame802154.h" +#include +#include + +#define SEC_LVL 6 +#define MIC_LEN LLSEC802154_MIC_LEN(6) + +/*---------------------------------------------------------------------------*/ +/* Test vector C.2.1.2 from IEEE 802.15.4-2006 */ +static void +test_sec_lvl_6() +{ + uint8_t key[16] = { 0xC0 , 0xC1 , 0xC2 , 0xC3 , + 0xC4 , 0xC5 , 0xC6 , 0xC7 , + 0xC8 , 0xC9 , 0xCA , 0xCB , + 0xCC , 0xCD , 0xCE , 0xCF }; + linkaddr_t source_address = {{ 0xAC , 0xDE , 0x48 , 0x00 , + 0x00 , 0x00 , 0x00 , 0x01 }}; + uint8_t data[30] = { 0x2B , 0xDC , 0x84 , 0x21 , 0x43 , + /* Destination Address */ + 0x02 , 0x00 , 0x00 , 0x00 , 0x00 , 0x48 , 0xDE , 0xAC , + /* PAN-ID */ + 0xFF , 0xFF , + /* Source Address */ + 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x48 , 0xDE , 0xAC , + /* Security Level */ + 0x06 , + /* Frame Counter */ + 0x05 , 0x00 , 0x00 , 0x00 , + 0x01 , 0xCE }; + uint8_t oracle[MIC_LEN] = { 0x4F , 0xDE , 0x52 , 0x90 , + 0x61 , 0xF9 , 0xC6 , 0xF1 }; + uint8_t nonce[13]; + frame802154_frame_counter_t counter; + + printf("Testing verification ... "); + + linkaddr_copy(&linkaddr_node_addr, &source_address); + packetbuf_clear(); + packetbuf_set_datalen(30); + memcpy(packetbuf_hdrptr(), data, 30); + counter.u32 = 5; + packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, counter.u16[0]); + packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, counter.u16[1]); + packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, SEC_LVL); + packetbuf_hdrreduce(29); + + CCM_STAR.set_key(key); + ccm_star_packetbuf_set_nonce(nonce, 1); + CCM_STAR.aead(nonce, + packetbuf_dataptr(), packetbuf_datalen(), + packetbuf_hdrptr(), packetbuf_hdrlen(), + ((uint8_t *) packetbuf_hdrptr()) + 30, MIC_LEN, + 1); + + if(memcmp(((uint8_t *) packetbuf_hdrptr()) + 30, oracle, MIC_LEN) == 0) { + printf("Success\n"); + } else { + printf("Failure\n"); + } + + printf("Testing encryption ... "); + + if(((uint8_t *) packetbuf_hdrptr())[29] == 0xD8) { + printf("Success\n"); + } else { + printf("Failure\n"); + } + + printf("Testing decryption ... "); + packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &source_address); + ccm_star_packetbuf_set_nonce(nonce, 0); + CCM_STAR.aead(nonce, + packetbuf_dataptr(), packetbuf_datalen(), + packetbuf_hdrptr(), packetbuf_hdrlen(), + ((uint8_t *) packetbuf_hdrptr()) + 30, MIC_LEN, + 0); + if(((uint8_t *) packetbuf_hdrptr())[29] == 0xCE) { + printf("Success\n"); + } else { + printf("Failure\n"); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS(ccm_star_tests_process, "CCM* tests process"); +AUTOSTART_PROCESSES(&ccm_star_tests_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(ccm_star_tests_process, ev, data) +{ + PROCESS_BEGIN(); + + test_sec_lvl_6(); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/llsec/ccm-star-tests/verification/Makefile b/examples/llsec/ccm-star-tests/verification/Makefile new file mode 100644 index 000000000..078714794 --- /dev/null +++ b/examples/llsec/ccm-star-tests/verification/Makefile @@ -0,0 +1,11 @@ +CONTIKI_PROJECT = tests +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../../.. +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +#linker optimizations +SMALL=1 + +CONTIKI_WITH_IPV6 = 1 +include $(CONTIKI)/Makefile.include diff --git a/platform/iris/dev/ds2401.h b/examples/llsec/ccm-star-tests/verification/project-conf.h similarity index 89% rename from platform/iris/dev/ds2401.h rename to examples/llsec/ccm-star-tests/verification/project-conf.h index bdabb41b1..3d7e42488 100644 --- a/platform/iris/dev/ds2401.h +++ b/examples/llsec/ccm-star-tests/verification/project-conf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, University of Colombo School of Computing + * Copyright (c) 2013, Hasso-Plattner-Institut. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,10 +30,11 @@ * */ -#ifndef DS2401_H -#define DS2401_H +/** + * \file + * Testing CCM* MICs + * \author + * Konrad Krentz + */ -extern unsigned char ds2401_id[8]; -extern int ds2401_init(); - -#endif /* DS2401_H */ +#define LLSEC802154_CONF_ENABLED 1 diff --git a/examples/llsec/ccm-star-tests/verification/tests.c b/examples/llsec/ccm-star-tests/verification/tests.c new file mode 100644 index 000000000..3c981552d --- /dev/null +++ b/examples/llsec/ccm-star-tests/verification/tests.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2013, Hasso-Plattner-Institut. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Testing CCM*-MICs + * \author + * Konrad Krentz + */ + +#include "contiki.h" +#include "net/packetbuf.h" +#include "net/netstack.h" +#include "net/llsec/llsec802154.h" +#include "net/llsec/ccm-star-packetbuf.h" +#include "net/mac/frame802154.h" +#include "lib/aes-128.h" +#include "lib/ccm-star.h" +#include +#include + +#define SEC_LVL 2 +#define MIC_LEN LLSEC802154_MIC_LEN(2) + +/*---------------------------------------------------------------------------*/ +/* Test vector C.1 from FIPS Pub 197 */ +static void +test_aes_128() +{ + uint8_t key[16] = { 0x00 , 0x01 , 0x02 , 0x03 , + 0x04 , 0x05 , 0x06 , 0x07 , + 0x08 , 0x09 , 0x0A , 0x0B , + 0x0C , 0x0D , 0x0E , 0x0F }; + uint8_t data[16] = { 0x00 , 0x11 , 0x22 , 0x33 , + 0x44 , 0x55 , 0x66 , 0x77 , + 0x88 , 0x99 , 0xAA , 0xBB , + 0xCC , 0xDD , 0xEE , 0xFF }; + uint8_t oracle[16] = { 0x69 , 0xC4 , 0xE0 , 0xD8 , + 0x6A , 0x7B , 0x04 , 0x30 , + 0xD8 , 0xCD , 0xB7 , 0x80 , + 0x70 , 0xB4 , 0xC5 , 0x5A }; + + printf("Testing AES-128 ... "); + + AES_128.set_key(key); + AES_128.encrypt(data); + + if(memcmp(data, oracle, 16) == 0) { + printf("Success\n"); + } else { + printf("Failure\n"); + } +} +/*---------------------------------------------------------------------------*/ +/* Test vector C.2.1.2 from IEEE 802.15.4-2006 */ +static void +test_sec_lvl_2() +{ + uint8_t key[16] = { 0xC0 , 0xC1 , 0xC2 , 0xC3 , + 0xC4 , 0xC5 , 0xC6 , 0xC7 , + 0xC8 , 0xC9 , 0xCA , 0xCB , + 0xCC , 0xCD , 0xCE , 0xCF }; + linkaddr_t source_address = {{ 0xAC , 0xDE , 0x48 , 0x00 , + 0x00 , 0x00 , 0x00 , 0x01 }}; + uint8_t data[26] = { 0x08 , 0xD0 , 0x84 , 0x21 , 0x43 , + /* Source Address */ + 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x48 , 0xDE , 0xAC , + /* Security Level*/ + 0x02 , + /* Frame Counter */ + 0x05 , 0x00 , 0x00 , 0x00 , + /* Payload */ + 0x55 , 0xCF , 0x00 , 0x00 , 0x51 , 0x52 , 0x53 , 0x54 }; + uint8_t oracle[MIC_LEN] = { 0x22 , 0x3B , 0xC1 , 0xEC , + 0x84 , 0x1A , 0xB5 , 0x53 }; + frame802154_frame_counter_t counter; + uint8_t mic[MIC_LEN]; + uint8_t nonce[13]; + + printf("Testing verification ... "); + + linkaddr_copy(&linkaddr_node_addr, &source_address); + packetbuf_clear(); + packetbuf_set_datalen(26); + memcpy(packetbuf_hdrptr(), data, 26); + counter.u32 = 5; + packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, counter.u16[0]); + packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, counter.u16[1]); + packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, SEC_LVL); + packetbuf_hdrreduce(18); + + CCM_STAR.set_key(key); + ccm_star_packetbuf_set_nonce(nonce, 1); + CCM_STAR.aead(nonce, + NULL, 0, + packetbuf_hdrptr(), packetbuf_totlen(), + ((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen(), MIC_LEN, + 1); + + if(memcmp(((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen(), oracle, MIC_LEN) == 0) { + printf("Success\n"); + } else { + printf("Failure\n"); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS(ccm_star_tests_process, "CCM* tests process"); +AUTOSTART_PROCESSES(&ccm_star_tests_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(ccm_star_tests_process, ev, data) +{ + PROCESS_BEGIN(); + + test_aes_128(); + test_sec_lvl_2(); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/mbxxx/acc-sensor/Makefile b/examples/mbxxx/acc-sensor/Makefile index 1e332446c..e3b40cde8 100644 --- a/examples/mbxxx/acc-sensor/Makefile +++ b/examples/mbxxx/acc-sensor/Makefile @@ -3,4 +3,5 @@ CONTIKI_PROJECT = acc-example all: $(CONTIKI_PROJECT) CONTIKI = ../../.. +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/mbxxx/button/Makefile b/examples/mbxxx/button/Makefile index 25d0441de..303ec7e5e 100644 --- a/examples/mbxxx/button/Makefile +++ b/examples/mbxxx/button/Makefile @@ -3,4 +3,5 @@ CONTIKI_PROJECT = test-button all: $(CONTIKI_PROJECT) CONTIKI = ../../.. +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/mbxxx/coffee-test/Makefile b/examples/mbxxx/coffee-test/Makefile index 1962568bd..3e72baacd 100644 --- a/examples/mbxxx/coffee-test/Makefile +++ b/examples/mbxxx/coffee-test/Makefile @@ -4,4 +4,5 @@ all: $(CONTIKI_PROJECT) COFFEE=1 CONTIKI = ../../.. +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/mbxxx/mbxxx-shell/Makefile b/examples/mbxxx/mbxxx-shell/Makefile index 08d2e6541..93de19bda 100644 --- a/examples/mbxxx/mbxxx-shell/Makefile +++ b/examples/mbxxx/mbxxx-shell/Makefile @@ -9,4 +9,5 @@ PROJECT_SOURCEFILES = shell-sensors.c all: $(CONTIKI_PROJECT) CONTIKI = ../../.. +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/mbxxx/mbxxx-websense/Makefile b/examples/mbxxx/mbxxx-websense/Makefile index a1d4b3af9..accb4e412 100644 --- a/examples/mbxxx/mbxxx-websense/Makefile +++ b/examples/mbxxx/mbxxx-websense/Makefile @@ -2,8 +2,6 @@ all: mbxxx-websense CONTIKI=../../.. -UIP_CONF_IPV6=1 - APPS += webserver webbrowser CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" @@ -11,13 +9,14 @@ CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" PROJECTDIRS += ../../ipv6/rpl-border-router PROJECT_SOURCEFILES += httpd-simple.c +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include $(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c (cd $(CONTIKI)/tools && $(MAKE) tunslip6) connect-router: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + sudo $(CONTIKI)/tools/tunslip6 fd00::1/64 connect-router-cooja: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 fd00::1/64 diff --git a/examples/mbxxx/shell-exec/Makefile b/examples/mbxxx/shell-exec/Makefile index 763e2e003..f9110f058 100644 --- a/examples/mbxxx/shell-exec/Makefile +++ b/examples/mbxxx/shell-exec/Makefile @@ -11,6 +11,7 @@ APPS = serial-shell PROJECT_SOURCEFILES = shell-exec.c CONTIKI = ../../.. +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include %.shell-upload: %.ce diff --git a/examples/mbxxx/telnet-server/Makefile b/examples/mbxxx/telnet-server/Makefile index 122054910..6322d4c8c 100644 --- a/examples/mbxxx/telnet-server/Makefile +++ b/examples/mbxxx/telnet-server/Makefile @@ -1,6 +1,4 @@ CONTIKI_PROJECT = telnet-server - -UIP_CONF_IPV6=1 APPS = telnetd @@ -11,4 +9,5 @@ PROJECT_SOURCEFILES = shell-sensors.c all: $(CONTIKI_PROJECT) CONTIKI = ../../.. +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/mbxxx/temperature/Makefile b/examples/mbxxx/temperature/Makefile index 7b1518efd..82fc9b4b1 100644 --- a/examples/mbxxx/temperature/Makefile +++ b/examples/mbxxx/temperature/Makefile @@ -3,4 +3,5 @@ CONTIKI_PROJECT = temp-sensor all: $(CONTIKI_PROJECT) CONTIKI = ../../.. +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/mbxxx/udp-ipv6-sleep/Makefile b/examples/mbxxx/udp-ipv6-sleep/Makefile index 476065d4a..53d35ce9a 100644 --- a/examples/mbxxx/udp-ipv6-sleep/Makefile +++ b/examples/mbxxx/udp-ipv6-sleep/Makefile @@ -1,8 +1,7 @@ all: udp-server udp-client -UIP_CONF_IPV6=1 - DEFINES=UIP_CONF_ND6_REACHABLE_TIME=0xffffffff CONTIKI = ../../.. +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/mbxxx/udp-ipv6-sleep/udp-client.c b/examples/mbxxx/udp-ipv6-sleep/udp-client.c index 4408a2c19..3c6f7934d 100644 --- a/examples/mbxxx/udp-ipv6-sleep/udp-client.c +++ b/examples/mbxxx/udp-ipv6-sleep/udp-client.c @@ -107,7 +107,7 @@ set_global_address(void) { uip_ipaddr_t ipaddr; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); } @@ -123,7 +123,7 @@ set_connection_address(uip_ipaddr_t *ipaddr) PRINTF("UDP client failed to parse address '%s'\n", QUOTEME(UDP_CONNECTION_ADDR)); } #elif UIP_CONF_ROUTER - uip_ip6addr(ipaddr,0xaaaa,0,0,0,0x0280,0xe102,0x0000,0x008a); + uip_ip6addr(ipaddr,UIP_DS6_DEFAULT_PREFIX,0,0,0,0x0280,0xe102,0x0000,0x008a); #else uip_ip6addr(ipaddr,0xfe80,0,0,0,0x0280,0xe102,0x0000,0x008a); #endif /* UDP_CONNECTION_ADDR */ diff --git a/examples/mbxxx/udp-ipv6-sleep/udp-server.c b/examples/mbxxx/udp-ipv6-sleep/udp-server.c index 68fc1915c..78c6f9d3a 100644 --- a/examples/mbxxx/udp-ipv6-sleep/udp-server.c +++ b/examples/mbxxx/udp-ipv6-sleep/udp-server.c @@ -95,7 +95,7 @@ PROCESS_THREAD(udp_server_process, ev, data) PRINTF("UDP server started\n"); #if UIP_CONF_ROUTER - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); #endif /* UIP_CONF_ROUTER */ diff --git a/examples/mbxxx/webserver-ajax/Makefile b/examples/mbxxx/webserver-ajax/Makefile index 06962bae8..c579c7a3f 100644 --- a/examples/mbxxx/webserver-ajax/Makefile +++ b/examples/mbxxx/webserver-ajax/Makefile @@ -2,16 +2,13 @@ CONTIKI_PROJECT = mbxxx-webserver all: $(CONTIKI_PROJECT) DEFINES=PROJECT_CONF_H=\"webserver-ajax-conf.h\" -UIP_CONF_IPV6=1 #APPS = webserver PROJECTDIRS = . $(CONTIKI)/apps/webserver PROJECT_SOURCEFILES = ajax-cgi.c httpd-fs.c http-strings.c \ httpd.c webserver-dsc.c webserver-nogui.c - - - CONTIKI = ../../.. +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/mbxxx/webserver-ajax/ajax-cgi.c b/examples/mbxxx/webserver-ajax/ajax-cgi.c index 3d482b376..e1b3ec4b0 100644 --- a/examples/mbxxx/webserver-ajax/ajax-cgi.c +++ b/examples/mbxxx/webserver-ajax/ajax-cgi.c @@ -164,7 +164,7 @@ make_neighbor(void *arg) return 0; } -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 return snprintf((char *)uip_appdata, uip_mss(), "
  • %d.%d\r\n", n->addr.u8[0], n->addr.u8[1], @@ -212,7 +212,7 @@ make_neighbor(void *arg) n->addr.u8[6], n->addr.u8[7]); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ } /*---------------------------------------------------------------------------*/ static diff --git a/examples/multi-threading/Makefile b/examples/multi-threading/Makefile index c6371bafa..30a68e393 100644 --- a/examples/multi-threading/Makefile +++ b/examples/multi-threading/Makefile @@ -2,4 +2,5 @@ CONTIKI_PROJECT = multi-threading all: $(CONTIKI_PROJECT) CONTIKI = ../.. +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/netperf/Makefile b/examples/netperf/Makefile index 8a6461d87..007dcc4bf 100644 --- a/examples/netperf/Makefile +++ b/examples/netperf/Makefile @@ -3,4 +3,5 @@ all: $(CONTIKI_PROJECT) APPS=serial-shell CONTIKI = ../.. +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/netperf/netperf-sky.csc b/examples/netperf/netperf-sky.csc index 4f5fe755c..c3f48c6fe 100644 --- a/examples/netperf/netperf-sky.csc +++ b/examples/netperf/netperf-sky.csc @@ -1,143 +1,143 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/native_gateway - - My simulation - 0 - generated - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - netperf shell - [CONTIKI_DIR]/examples/netperf/netperf-shell.c - make netperf-shell.sky TARGET=sky - [CONTIKI_DIR]/examples/netperf/netperf-shell.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.SkySerial - org.contikios.cooja.mspmote.interfaces.SkyLED - - - org.contikios.cooja.mspmote.SkyMote - sky1 - - - org.contikios.cooja.interfaces.Position - 49.48292285385544 - 97.67000744426045 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - - - org.contikios.cooja.mspmote.SkyMote - sky1 - - - org.contikios.cooja.interfaces.Position - 80.21380569499377 - 98.51039574575084 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - - - - org.contikios.cooja.plugins.SimControl - 290 - 2 - 172 - 0 - 0 - false - - - org.contikios.cooja.plugins.LogListener - - - - 1024 - 0 - 377 - 0 - 171 - false - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - - - - 118 - 9 - - 1024 - 1 - 150 - 0 - 548 - false - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - -1 - 476 - 399 - 154 - true - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/native_gateway + + My simulation + 0 + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + netperf shell + [CONTIKI_DIR]/examples/netperf/netperf-shell.c + make netperf-shell.sky TARGET=sky + [CONTIKI_DIR]/examples/netperf/netperf-shell.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.SkySerial + org.contikios.cooja.mspmote.interfaces.SkyLED + + + org.contikios.cooja.mspmote.SkyMote + sky1 + + + org.contikios.cooja.interfaces.Position + 49.48292285385544 + 97.67000744426045 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + + + org.contikios.cooja.mspmote.SkyMote + sky1 + + + org.contikios.cooja.interfaces.Position + 80.21380569499377 + 98.51039574575084 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + + + + org.contikios.cooja.plugins.SimControl + 290 + 2 + 172 + 0 + 0 + false + + + org.contikios.cooja.plugins.LogListener + + + + 1024 + 0 + 377 + 0 + 171 + false + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + + + + 118 + 9 + + 1024 + 1 + 150 + 0 + 548 + false + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + -1 + 476 + 399 + 154 + true + + + diff --git a/examples/nrf52dk/blink-hello/Makefile b/examples/nrf52dk/blink-hello/Makefile new file mode 100644 index 000000000..5b056a518 --- /dev/null +++ b/examples/nrf52dk/blink-hello/Makefile @@ -0,0 +1,9 @@ +CONTIKI_PROJECT = blink-hello + +CONTIKI_WITH_RPL=0 +NRF52_WITHOUT_SOFTDEVICE=1 + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/nrf52dk/blink-hello/README.md b/examples/nrf52dk/blink-hello/README.md new file mode 100644 index 000000000..00064f993 --- /dev/null +++ b/examples/nrf52dk/blink-hello/README.md @@ -0,0 +1,14 @@ +Blink Hello example +=================== +This example shows basic usage of DK's buttons and LEDs. It also shows basic +usage of Contiki's processes. The application autostarts 5 processes: 4 processes +for button and LED control and 1 to display current temperature to the console. + +A process reacts to a press of a respective button (process 1 reacts to button 1, etc.) +and doubles the current blinking frequency. The cycle restarts for beginning when blinking +frequency is greater than 8Hz. + +The example requires one DK and it doesn't use SoftDevice. To compile and flash the +example run: + + make TARGET=nrf52dk blink-hello.flash \ No newline at end of file diff --git a/examples/nrf52dk/blink-hello/blink-hello.c b/examples/nrf52dk/blink-hello/blink-hello.c new file mode 100644 index 000000000..ebc1e451c --- /dev/null +++ b/examples/nrf52dk/blink-hello/blink-hello.c @@ -0,0 +1,182 @@ +/* This is a very simple hello_world program. + * It aims to demonstrate the co-existence of two processes: + * One of them prints a hello world message and the other blinks the LEDs + * + * It is largely based on hello_world in $(CONTIKI)/examples/sensinode + * + * Author: George Oikonomou - + */ + +/** + * \addtogroup nrf52dk nRF52 Development Kit + * @{ + * + * \addtogroup nrf52dk-examples Demo projects for nRF52 DK + * @{ + * + * \defgroup nrf52dk-blink-hello Basic sensors and LEDs demo + * @{ + * + * This demo demonstrates use of Contiki processes, sensors, and LEDs + * on nRF52 DK. Pressing a button will start a timer that blinks a + * respective LED (e.g., button 1 controls LED 1). Each time the button + * is pressed blinking frequency is doubled. On 4th press the LED is + * switched off and the sequence can be started from the beginning. + * + * \file Main file for Basic sensors and LEDs demo. + */ +#include /* For printf() */ +#include +#include "contiki.h" +#include "dev/leds.h" +#include "dev/temperature-sensor.h" +#include "lib/sensors.h" +#include "button-sensor.h" + +/*---------------------------------------------------------------------------*/ +PROCESS(blink_process_1, "LED1 blink process"); +PROCESS(blink_process_2, "LED2 blink process"); +PROCESS(blink_process_3, "LED3 blink process"); +PROCESS(blink_process_4, "LED4 blink process"); +PROCESS(temp, "Temperautre"); + +AUTOSTART_PROCESSES( + &blink_process_1, + &blink_process_2, + &blink_process_3, + &blink_process_4, + &temp +); + +struct blink_process_ctx { + struct etimer et_blink; + unsigned char c; + const struct sensors_sensor *button; + unsigned char led; +}; + +static void handle_event(process_event_t ev, process_data_t data, struct blink_process_ctx *ctx) +{ + if (ev == PROCESS_EVENT_TIMER && etimer_expired(&ctx->et_blink)) { + leds_toggle(ctx->led); + etimer_set(&ctx->et_blink, CLOCK_SECOND / ctx->c); + printf("Blink %d\n", ctx->led); + } else if (ev == sensors_event && data == ctx->button) { + if (ctx->button->value(BUTTON_SENSOR_VALUE_STATE) == 0) { + if (ctx->c == 0) { + ctx->c = 1; + } else if (ctx->c < 8){ + ctx->c <<= 1; + } else { + ctx->c = 0; + leds_off(ctx->led); + } + if (ctx->c) { + etimer_set(&ctx->et_blink, CLOCK_SECOND / ctx->c); + } else { + etimer_stop(&ctx->et_blink); + } + } + } +} + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(blink_process_1, ev, data) +{ + static struct blink_process_ctx ctx; + + PROCESS_BEGIN(); + + ctx.button = &button_1; + ctx.c = 0; + ctx.led = LEDS_1; + ctx.button->configure(SENSORS_ACTIVE, 1); + + while (1) { + PROCESS_WAIT_EVENT(); + handle_event(ev, data, &ctx); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(blink_process_2, ev, data) +{ + static struct blink_process_ctx ctx; + + PROCESS_BEGIN(); + + ctx.button = &button_2; + ctx.c = 0; + ctx.led = LEDS_2; + ctx.button->configure(SENSORS_ACTIVE, 1); + + while (1) { + PROCESS_WAIT_EVENT(); + handle_event(ev, data, &ctx); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(blink_process_3, ev, data) +{ + static struct blink_process_ctx ctx; + + PROCESS_BEGIN(); + + ctx.button = &button_3; + ctx.c = 0; + ctx.led = LEDS_3; + ctx.button->configure(SENSORS_ACTIVE, 1); + + while (1) { + PROCESS_WAIT_EVENT(); + handle_event(ev, data, &ctx); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(blink_process_4, ev, data) +{ + static struct blink_process_ctx ctx; + + PROCESS_BEGIN(); + + ctx.button = &button_4; + ctx.c = 0; + ctx.led = LEDS_4; + ctx.button->configure(SENSORS_ACTIVE, 1); + + while (1) { + PROCESS_WAIT_EVENT(); + handle_event(ev, data, &ctx); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(temp, ev, data) +{ + static struct etimer tick; + PROCESS_BEGIN(); + + etimer_set(&tick, CLOCK_SECOND); + + while (1) { + PROCESS_WAIT_EVENT(); + if (ev == PROCESS_EVENT_TIMER && etimer_expired(&tick)) { + int32_t temp = temperature_sensor.value(0); + printf("temp: %"PRId32".%02"PRId32"\n", temp >> 2, (temp & 0x03)*25); + etimer_reset(&tick); + } + } + + PROCESS_END(); +} +/** + * @} + * @} + * @} + */ diff --git a/examples/nrf52dk/coap-demo/Makefile b/examples/nrf52dk/coap-demo/Makefile new file mode 100644 index 000000000..077e469be --- /dev/null +++ b/examples/nrf52dk/coap-demo/Makefile @@ -0,0 +1,35 @@ +CONTIKI=../../.. +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +ifeq ($(MAKECMDGOALS),) +$(error Please specify whether coap-client or coap-server should be built) +endif + +ifneq ($(filter coap-client coap-client.flash, $(MAKECMDGOALS)),) +ifeq ($(SERVER_IPV6_ADDR),) +$(error Please define SERVER_IPV6_ADDR=) +else +CFLAGS += -DSERVER_IPV6_ADDR=\"$(SERVER_IPV6_ADDR)\" +CFLAGS += -DDEVICE_NAME=\"nRF52_DK_CoAP_Client\" +endif +else +CFLAGS += -DDEVICE_NAME=\"nRF52-DK-CoAP-Server\" +endif + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_FILES = $(notdir $(shell find $(REST_RESOURCES_DIR) -name '*.c' ! -name 'res-plugtest*')) + +PROJECTDIRS += $(REST_RESOURCES_DIR) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) + +# linker optimizations +SMALL=1 + +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine + +CONTIKI_WITH_RPL = 0 + +include $(CONTIKI)/Makefile.include diff --git a/examples/nrf52dk/coap-demo/README.md b/examples/nrf52dk/coap-demo/README.md new file mode 100644 index 000000000..1262ce114 --- /dev/null +++ b/examples/nrf52dk/coap-demo/README.md @@ -0,0 +1,63 @@ +A CoAP demo for nRF52 DK +======================== +This demo contains two applications: coap-server and coap-client which are similar to +[Coap Observable Server] and [Coap Observer Client] examples provided by the nRF5 IoT SDK. + +Note that before any CoAP requests can be made you'll need to configure an IPv6 connection +to the device and assign a routable IPv6 address. + +For details how to do this please refer to sections 'Establishing an IPv6 connection' +and 'Distributing routable IPv6 prefix' in `platform/nrf52dk/README-BLE-6LoWPAN.md`. + +CoAP Server +=========== +The server exposes the following resources: + + host + |-- .well-known + | `-- core + `-- lights + `-- led3 + +The state of LED 3 can be set and queried via CoAP through the observable resource `lights/led3`. Current +state of LED 3 is returned as a text string in the payload. The value 0 means that LED 3 is off, 1 otherwise. + +Button 1 can be used to toggle state of the LED 3. This will cause a notification to be sent to +any subscriber observing `lights/led3`. The state of the resource can also be changed by using POST/PUT to +the resource with desired state encoded as a text in the payload. Send 1 to switch on and 0 to switch off. + +In order to compile and flash the CoAP server to a DK execute: + + make TARGET=nrf52dk coap-server.flash + +Note, if you haven't previously used a given device with Contiki it is recommended +to erase the device and flash SoftDevice before flashing CoAP application, i.e., + + make TARGET=nrf52dk erase + make TARGET=nrf52dk softdevice.flash + +Please refer to the *Testing* and *Python Example* sections of [Coap Observable Server] tutorial for detailed description how to query the Coap Server using a PC. + +CoAP Client +=========== +CoAP client compliments the CoAP server application. When Button 1 on the DK is pressed the the +client subscribes to `lights/led3` resource. If successful the LED 4 will blink briefly. From this moment +any change of the `lights/led3` resource will be automatically reflected by the client's LED 3. + +Note that the client must know the server's IPv6 address. The address is specified as a make variable +during compliation. + +In order to compile and flash the CoAP client to DK execute: + + make TARGET=nrf52dk SERVER_IPV6_ADDR= coap-client.flash + +Note, that you can use `NRF52_JLINK_SN=` to select a particular devkit in a case when +you have more than one boards connected to PC. Please refer to `platform/README.md` for +details. + +Please refer to the *Testing* and *Python Server Example* sections of [Coap Observer Client] tutorial for detailed description how to use CoAP client demo with a PC. + +Resources +========= +[Coap Observable Server] http://developer.nordicsemi.com/nRF5_IoT_SDK/doc/0.9.0/html/a00054.html +[Coap Observer Client] http://developer.nordicsemi.com/nRF5_IoT_SDK/doc/0.9.0/html/a00051.html diff --git a/examples/nrf52dk/coap-demo/coap-client.c b/examples/nrf52dk/coap-demo/coap-client.c new file mode 100644 index 000000000..2ec1f5ab1 --- /dev/null +++ b/examples/nrf52dk/coap-demo/coap-client.c @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2014, Daniele Alessandrelli. + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \addtogroup nrf52dk-examples Demo projects for nRF52 DK + * @{ + * + * \defgroup nrf52dk-coap-demo CoAP demo for nRF52 DK + * @{ + * + * \file + * Erbium (Er) CoAP observe client example. + * \author + * Daniele Alessandrelli + * \author + * Wojciech Bober + */ + +#include +#include +#include +#include "contiki.h" +#include "contiki-net.h" +#include "er-coap-engine.h" +#include "dev/button-sensor.h" +#include "dev/leds.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/*----------------------------------------------------------------------------*/ +#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT) +#define OBS_RESOURCE_URI "lights/led3" +#define SUBS_LED LEDS_4 +#define OBS_LED LEDS_3 + +/*----------------------------------------------------------------------------*/ +static uip_ipaddr_t server_ipaddr[1]; /* holds the server ip address */ +static coap_observee_t *obs; +static struct ctimer ct; +/*----------------------------------------------------------------------------*/ +PROCESS(er_example_observe_client, "nRF52 DK Coap Observer Client"); +AUTOSTART_PROCESSES(&er_example_observe_client); +/*----------------------------------------------------------------------------*/ +static void +observe_led_off(void *d) +{ + leds_off(SUBS_LED); +} +/*----------------------------------------------------------------------------*/ +/* + * Handle the response to the observe request and the following notifications + */ +static void +notification_callback(coap_observee_t *obs, void *notification, + coap_notification_flag_t flag) +{ + int len = 0; + const uint8_t *payload = NULL; + + + PRINTF("Notification handler\n"); + PRINTF("Observee URI: %s\n", obs->url); + + if (notification) { + len = coap_get_payload(notification, &payload); + } + + (void)len; + + switch (flag) { + case NOTIFICATION_OK: + PRINTF("NOTIFICATION OK: %*s\n", len, (char *)payload); + if (*payload == '1') { + leds_on(OBS_LED); + } else { + leds_off(OBS_LED); + } + break; + case OBSERVE_OK: /* server accepeted observation request */ + PRINTF("OBSERVE_OK: %*s\n", len, (char *)payload); + if (*payload == '1') { + leds_on(OBS_LED); + } else { + leds_off(OBS_LED); + } + leds_on(SUBS_LED); + ctimer_set(&ct, CLOCK_SECOND, observe_led_off, NULL); + break; + case OBSERVE_NOT_SUPPORTED: + PRINTF("OBSERVE_NOT_SUPPORTED: %*s\n", len, (char *)payload); + obs = NULL; + break; + case ERROR_RESPONSE_CODE: + PRINTF("ERROR_RESPONSE_CODE: %*s\n", len, (char *)payload); + obs = NULL; + break; + case NO_REPLY_FROM_SERVER: + PRINTF("NO_REPLY_FROM_SERVER: " + "removing observe registration with token %x%x\n", + obs->token[0], obs->token[1]); + obs = NULL; + break; + } +} +/*----------------------------------------------------------------------------*/ +/* + * The main (proto-)thread. It starts/stops the observation of the remote + * resource every time the timer elapses or the button (if available) is + * pressed + */ +PROCESS_THREAD(er_example_observe_client, ev, data) +{ + PROCESS_BEGIN(); + + uiplib_ipaddrconv(SERVER_IPV6_ADDR, server_ipaddr); + + /* receives all CoAP messages */ + coap_init_engine(); + +#if PLATFORM_HAS_BUTTON + SENSORS_ACTIVATE(button_1); + SENSORS_ACTIVATE(button_2); +#endif + + /* toggle observation every time the timer elapses or the button is pressed */ + while (1) { + PROCESS_YIELD(); +#if PLATFORM_HAS_BUTTON + if (ev == sensors_event) { + if (data == &button_1 && button_1.value(BUTTON_SENSOR_VALUE_STATE) == 0) { + PRINTF("Starting observation\n"); + obs = coap_obs_request_registration(server_ipaddr, REMOTE_PORT, + OBS_RESOURCE_URI, notification_callback, + NULL); + } + if (data == &button_2 && button_2.value(BUTTON_SENSOR_VALUE_STATE) == 0) { + PRINTF("Stopping observation\n"); + coap_obs_remove_observee(obs); + obs = NULL; + } + } +#endif + } + PROCESS_END(); +} + +/** + * @} + * @} + */ diff --git a/examples/nrf52dk/coap-demo/coap-server.c b/examples/nrf52dk/coap-demo/coap-server.c new file mode 100644 index 000000000..9bab7e60d --- /dev/null +++ b/examples/nrf52dk/coap-demo/coap-server.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * Copyright (c) 2015, Nordic Semiconductor + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \addtogroup nrf52dk-examples Demo projects for nRF52 DK + * @{ + * + * \defgroup nrf52dk-coap-demo CoAP demo for nRF52dk + * @{ + * + * \file + * Erbium (Er) REST Engine example. + * \author + * Matthias Kovatsch + * \author + * Wojciech Bober + */ + +#include +#include +#include +#include "contiki.h" +#include "contiki-net.h" +#include "rest-engine.h" +#include "uip.h" +#include "dev/button-sensor.h" +#include "dev/leds.h" + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +/* + * Resources to be activated need to be imported through the extern keyword. + * The build system automatically compiles the resources in the corresponding sub-directory. + */ +extern resource_t res_led3; + +static void +print_local_addresses(void) +{ + int i; + uint8_t state; + + PRINTF("Server IPv6 addresses:\n"); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state + == ADDR_PREFERRED)) { + PRINTF(" "); + PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); + PRINTF("\n"); + if(state == ADDR_TENTATIVE) { + uip_ds6_if.addr_list[i].state = ADDR_PREFERRED; + } + } + } +} + +PROCESS(er_example_server, "nRF52 DK Coap Server"); +AUTOSTART_PROCESSES(&er_example_server); + +PROCESS_THREAD(er_example_server, ev, data) +{ + PROCESS_BEGIN(); + PROCESS_PAUSE(); + + PRINTF("Starting Erbium Example Server\n"); + + PRINTF("uIP buffer: %u\n", UIP_BUFSIZE); + PRINTF("LL header: %u\n", UIP_LLH_LEN); + PRINTF("IP+UDP header: %u\n", UIP_IPUDPH_LEN); + PRINTF("REST max chunk: %u\n", REST_MAX_CHUNK_SIZE); + + print_local_addresses(); + + /* Initialize the REST engine. */ + rest_init_engine(); + rest_activate_resource(&res_led3, "lights/led3"); + + SENSORS_ACTIVATE(button_1); + + /* Define application-specific events here. */ + while (1) { + PROCESS_WAIT_EVENT(); + + if (ev == sensors_event) { + if (data == &button_1 && button_1.value(BUTTON_SENSOR_VALUE_STATE) == 0) { + leds_toggle(LEDS_3); + res_led3.trigger(); + } + } + } + + PROCESS_END(); +} + +/** + * @} + * @} + */ diff --git a/examples/nrf52dk/coap-demo/project-conf.h b/examples/nrf52dk/coap-demo/project-conf.h new file mode 100644 index 000000000..2b097e8a8 --- /dev/null +++ b/examples/nrf52dk/coap-demo/project-conf.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \addtogroup nrf52dk-examples Demo projects for nRF52 DK + * @{ + * + * \defgroup nrf52dk-coap-demo CoAP demo for nRF52dk + * @{ + * + * \file + * Erbium (Er) example project configuration. + * \author + * Matthias Kovatsch + */ + +#ifndef __PROJECT_ERBIUM_CONF_H__ +#define __PROJECT_ERBIUM_CONF_H__ + +/* Disabling TCP on CoAP nodes. */ +#undef UIP_CONF_TCP +#define UIP_CONF_TCP 0 + +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 48 + +/* Estimate your header size, especially when using Proxy-Uri. */ +/* + #undef COAP_MAX_HEADER_SIZE + #define COAP_MAX_HEADER_SIZE 70 + */ + +/* Multiplies with chunk size, be aware of memory constraints. */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +/* Must be <= open transactions, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* + #undef COAP_MAX_OBSERVERS + #define COAP_MAX_OBSERVERS 2 + */ + +/* Filtering .well-known/core per query can be disabled to save space. */ +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +#undef COAP_PROXY_OPTION_PROCESSING +#define COAP_PROXY_OPTION_PROCESSING 0 + +/* Enable client-side support for COAP observe */ +#define COAP_OBSERVE_CLIENT 1 +#endif /* __PROJECT_ERBIUM_CONF_H__ */ + +/** + * @} + * @} + */ diff --git a/examples/nrf52dk/coap-demo/resources/res-leds.c b/examples/nrf52dk/coap-demo/resources/res-leds.c new file mode 100644 index 000000000..468a165bf --- /dev/null +++ b/examples/nrf52dk/coap-demo/resources/res-leds.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + * \author + * Wojciech Bober + */ + +#include +#include "contiki.h" +#include "rest-engine.h" +#include "dev/leds.h" + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +static void +res_post_put_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset); + +static void +res_event_handler(); + +/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ +EVENT_RESOURCE(res_led3, + "title=\"LED3\"; obs", + res_get_handler, + res_post_put_handler, + res_post_put_handler, + NULL, + res_event_handler + ); + +static void +res_post_put_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *payload; + REST.get_request_payload(request, &payload); + + if (*payload == '0' || *payload == '1') { + if (*payload == '1') { + leds_on(LEDS_3); + } else { + leds_off(LEDS_3); + } + REST.notify_subscribers(&res_led3); + REST.set_response_status(response, REST.status.CHANGED); + } else { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "%d", (leds_get() & LEDS_3) ? 1 : 0)); +} + +/* + * Additionally, res_event_handler must be implemented for each EVENT_RESOURCE. + * It is called through .trigger(), usually from the server process. + */ +static void +res_event_handler() +{ + /* Notify the registered observers which will trigger the res_get_handler to create the response. */ + REST.notify_subscribers(&res_led3); +} diff --git a/examples/nrf52dk/mqtt-demo/Makefile b/examples/nrf52dk/mqtt-demo/Makefile new file mode 100644 index 000000000..bfdeccfb7 --- /dev/null +++ b/examples/nrf52dk/mqtt-demo/Makefile @@ -0,0 +1,11 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" + +all: mqtt-demo + +CONTIKI_WITH_IPV6 = 1 +CONTIKI_WITH_RPL = 0 + +APPS += mqtt + +CONTIKI=../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/nrf52dk/mqtt-demo/README.md b/examples/nrf52dk/mqtt-demo/README.md new file mode 100644 index 000000000..a4a9a6ff1 --- /dev/null +++ b/examples/nrf52dk/mqtt-demo/README.md @@ -0,0 +1,74 @@ +MQTT Demo +========= +The MQTT client can be used to: + +* Publish sensor readings to an MQTT broker. +* Subscribe to a topic and receive commands from an MQTT broker + +The demo will give some visual feedback with the green LED: +* Very fast blinking: Searching for a network +* Fast blinking: Connecting to broker +* Slow, long blinking: Sending a publish message + +Note that before any MQTT messages can be sent or received you'll +need to configure an IPv6 connection to the device and assign a routable +IPv6 address. + +For details how to do this please refer to sections 'Establishing an IPv6 connection' +and 'Distributing routable IPv6 prefix' in `platform/nrf52dk/README-BLE-6LoWPAN.md`. + +Broker setup +------------ +By default the example will attempt to publish readings to an MQTT broker +running on the IPv6 address specified as `MQTT_DEMO_BROKER_IP_ADDR` in +`project-conf.h`. This functionality was tested successfully with +[mosquitto](http://mosquitto.org/). + +On Ubuntu you can install and run mosquitto broker using the following +commands: + + apt-get install mosquitto mosquitto_clients + killall mosquitto + mosquitto -p 1883 -v + +Publishing +---------- +The publish messages include sensor readings but also some other information, +such as device uptime in seconds and a message sequence number. The demo will +publish to topic `iot-2/evt/status/fmt/json`. The device will connect using +client-id `d:quickstart:cc2538:`, where `` gets +constructed from the device's IEEE address. + +Subscribing +----------- +You can also subscribe to topics and receive commands, but this will only +work if you use "Org ID" != 'quickstart'. To achieve this, you will need to +change 'Org ID' (`DEFAULT_ORG_ID`). In this scenario, the device will subscribe +to: + +`iot-2/cmd/+/fmt/json` + +You can then use this to toggle LEDs. To do this, you can for example +use mosquitto client to publish to `iot-2/cmd/leds/fmt/json`. So, to change +the state of an LED, you would do this: + +`mosquitto_pub -h -m "1" -t iot-2/cmd/leds/fmt/json` + +Where `broker IP` should be replaced with the IP address of your mosquitto +broker (the one where you device has subscribed). Replace `-m "1'` with `-m "0"` +to turn the LED back off. + +Bear in mind that, even though the topic suggests that messages are of json +format, they are in fact not. This was done in order to avoid linking a json +parser into the firmware. This comment only applies to parsing incoming +messages, outgoing publish messages use proper json payload. + +IBM Quickstart Service +---------------------- +It is also possible to publish to IBM's quickstart service. To do so, you need +to undefine `MQTT_DEMO_BROKER_IP_ADDR`. + +If you want to use IBM's cloud service with a registered device, change +'Org ID' (`DEFAULT_ORG_ID`) and provide the 'Auth Token' (`DEFAULT_AUTH_TOKEN`), +which acts as a 'password', but bear in mind that it gets transported in clear +text. \ No newline at end of file diff --git a/examples/nrf52dk/mqtt-demo/mqtt-demo.c b/examples/nrf52dk/mqtt-demo/mqtt-demo.c new file mode 100644 index 000000000..6a3482073 --- /dev/null +++ b/examples/nrf52dk/mqtt-demo/mqtt-demo.c @@ -0,0 +1,721 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup nrf52dk-examples Demo projects for nRF52 DK + * @{ + * + * \defgroup nrf52dk-mqtt-demo nRF52 DK MQTT Demo Project + * + * Demonstrates MQTT functionality. Works with mosquitto. + * @{ + * + * \file + * An MQTT example for the nrf52dk platform + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "mqtt.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-icmp6.h" +#include "net/ipv6/sicslowpan.h" +#include "sys/etimer.h" +#include "sys/ctimer.h" +#include "lib/sensors.h" +#include "dev/button-sensor.h" +#include "dev/temperature-sensor.h" +#include "dev/leds.h" + +#include +/*---------------------------------------------------------------------------*/ +/* + * IBM server: quickstart.messaging.internetofthings.ibmcloud.com + * (184.172.124.189) mapped in an NAT64 (prefix 64:ff9b::/96) IPv6 address + * Note: If not able to connect; lookup the IP address again as it may change. + * + * Alternatively, publish to a local MQTT broker (e.g. mosquitto) running on + * the node that hosts your border router + */ +#ifdef MQTT_DEMO_BROKER_IP_ADDR +static const char *broker_ip = MQTT_DEMO_BROKER_IP_ADDR; +#define DEFAULT_ORG_ID "mqtt-demo" +#else +static const char *broker_ip = "0064:ff9b:0000:0000:0000:0000:b8ac:7cbd"; +#define DEFAULT_ORG_ID "quickstart" +#endif +/*---------------------------------------------------------------------------*/ +/* + * A timeout used when waiting for something to happen (e.g. to connect or to + * disconnect) + */ +#define STATE_MACHINE_PERIODIC (CLOCK_SECOND >> 1) +/*---------------------------------------------------------------------------*/ +/* Provide visible feedback via LEDS during various states */ +/* When connecting to broker */ +#define CONNECTING_LED_DURATION (CLOCK_SECOND >> 2) + +/* Each time we try to publish */ +#define PUBLISH_LED_ON_DURATION (CLOCK_SECOND) +/*---------------------------------------------------------------------------*/ +/* Connections and reconnections */ +#define RETRY_FOREVER 0xFF +#define RECONNECT_INTERVAL (CLOCK_SECOND * 2) + +/* + * Number of times to try reconnecting to the broker. + * Can be a limited number (e.g. 3, 10 etc) or can be set to RETRY_FOREVER + */ +#define RECONNECT_ATTEMPTS RETRY_FOREVER +#define CONNECTION_STABLE_TIME (CLOCK_SECOND * 5) +static struct timer connection_life; +static uint8_t connect_attempt; +/*---------------------------------------------------------------------------*/ +/* Various states */ +static uint8_t state; +#define STATE_INIT 0 +#define STATE_REGISTERED 1 +#define STATE_CONNECTING 2 +#define STATE_CONNECTED 3 +#define STATE_PUBLISHING 4 +#define STATE_DISCONNECTED 5 +#define STATE_NEWCONFIG 6 +#define STATE_CONFIG_ERROR 0xFE +#define STATE_ERROR 0xFF +/*---------------------------------------------------------------------------*/ +#define CONFIG_ORG_ID_LEN 32 +#define CONFIG_TYPE_ID_LEN 32 +#define CONFIG_AUTH_TOKEN_LEN 32 +#define CONFIG_EVENT_TYPE_ID_LEN 32 +#define CONFIG_CMD_TYPE_LEN 8 +#define CONFIG_IP_ADDR_STR_LEN 64 +/*---------------------------------------------------------------------------*/ +#define RSSI_MEASURE_INTERVAL_MAX 86400 /* secs: 1 day */ +#define RSSI_MEASURE_INTERVAL_MIN 5 /* secs */ +#define PUBLISH_INTERVAL_MAX 86400 /* secs: 1 day */ +#define PUBLISH_INTERVAL_MIN 5 /* secs */ +/*---------------------------------------------------------------------------*/ +/* A timeout used when waiting to connect to a network */ +#define NET_CONNECT_PERIODIC CLOCK_SECOND +#define NO_NET_LED_DURATION (NET_CONNECT_PERIODIC >> 1) +/*---------------------------------------------------------------------------*/ +/* Default configuration values */ +#define DEFAULT_TYPE_ID "nrf52dk" +#define DEFAULT_AUTH_TOKEN "AUTHZ" +#define DEFAULT_EVENT_TYPE_ID "status" +#define DEFAULT_SUBSCRIBE_CMD_TYPE "+" +#define DEFAULT_BROKER_PORT 1883 +#define DEFAULT_PUBLISH_INTERVAL (30 * CLOCK_SECOND) +#define DEFAULT_KEEP_ALIVE_TIMER 60 +#define DEFAULT_RSSI_MEAS_INTERVAL (CLOCK_SECOND * 30) +/*---------------------------------------------------------------------------*/ +/* Take a sensor reading on button press */ +#define PUBLISH_TRIGGER (&button_sensor) + +/* Payload length of ICMPv6 echo requests used to measure RSSI with def rt */ +#define ECHO_REQ_PAYLOAD_LEN 20 +/*---------------------------------------------------------------------------*/ +PROCESS_NAME(mqtt_demo_process); +AUTOSTART_PROCESSES(&mqtt_demo_process); +/*---------------------------------------------------------------------------*/ +/** + * \brief Data structure declaration for the MQTT client configuration + */ +typedef struct mqtt_client_config { + char org_id[CONFIG_ORG_ID_LEN]; + char type_id[CONFIG_TYPE_ID_LEN]; + char auth_token[CONFIG_AUTH_TOKEN_LEN]; + char event_type_id[CONFIG_EVENT_TYPE_ID_LEN]; + char broker_ip[CONFIG_IP_ADDR_STR_LEN]; + char cmd_type[CONFIG_CMD_TYPE_LEN]; + clock_time_t pub_interval; + int def_rt_ping_interval; + uint16_t broker_port; +} mqtt_client_config_t; +/*---------------------------------------------------------------------------*/ +/* Maximum TCP segment size for outgoing segments of our socket */ +#define MAX_TCP_SEGMENT_SIZE 32 +/*---------------------------------------------------------------------------*/ +#define STATUS_LED LEDS_GREEN +/*---------------------------------------------------------------------------*/ +/* + * Buffers for Client ID and Topic. + * Make sure they are large enough to hold the entire respective string + * + * d:quickstart:status:EUI64 is 32 bytes long + * iot-2/evt/status/fmt/json is 25 bytes + * We also need space for the null termination + */ +#define BUFFER_SIZE 64 +static char client_id[BUFFER_SIZE]; +static char pub_topic[BUFFER_SIZE]; +static char sub_topic[BUFFER_SIZE]; +/*---------------------------------------------------------------------------*/ +/* + * The main MQTT buffers. + * We will need to increase if we start publishing more data. + */ +#define APP_BUFFER_SIZE 128 +static struct mqtt_connection conn; +static char app_buffer[APP_BUFFER_SIZE]; +/*---------------------------------------------------------------------------*/ +#define QUICKSTART "quickstart" +/*---------------------------------------------------------------------------*/ +static struct mqtt_message *msg_ptr = 0; +static struct etimer publish_periodic_timer; +static struct ctimer ct; +static char *buf_ptr; +static uint16_t seq_nr_value = 0; +/*---------------------------------------------------------------------------*/ +/* Parent RSSI functionality */ +static struct uip_icmp6_echo_reply_notification echo_reply_notification; +static struct etimer echo_request_timer; +static int def_rt_rssi = 0; +/*---------------------------------------------------------------------------*/ +static mqtt_client_config_t conf; +/*---------------------------------------------------------------------------*/ +PROCESS(mqtt_demo_process, "MQTT Demo"); +/*---------------------------------------------------------------------------*/ +int +ipaddr_sprintf(char *buf, uint8_t buf_len, const uip_ipaddr_t *addr) +{ + uint16_t a; + uint8_t len = 0; + int i, f; + for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { + a = (addr->u8[i] << 8) + addr->u8[i + 1]; + if(a == 0 && f >= 0) { + if(f++ == 0) { + len += snprintf(&buf[len], buf_len - len, "::"); + } + } else { + if(f > 0) { + f = -1; + } else if(i > 0) { + len += snprintf(&buf[len], buf_len - len, ":"); + } + len += snprintf(&buf[len], buf_len - len, "%x", a); + } + } + + return len; +} +/*---------------------------------------------------------------------------*/ +static void +echo_reply_handler(uip_ipaddr_t *source, uint8_t ttl, uint8_t *data, + uint16_t datalen) +{ + if(uip_ip6addr_cmp(source, uip_ds6_defrt_choose())) { + def_rt_rssi = sicslowpan_get_last_rssi(); + } +} +/*---------------------------------------------------------------------------*/ +static void +publish_led_off(void *d) +{ + leds_off(STATUS_LED); +} +/*---------------------------------------------------------------------------*/ +static void +pub_handler(const char *topic, uint16_t topic_len, const uint8_t *chunk, + uint16_t chunk_len) +{ + DBG("Pub Handler: topic='%s' (len=%u), chunk_len=%u\n", topic, topic_len, + chunk_len); + + /* If we don't like the length, ignore */ + if(topic_len != 23 || chunk_len != 1) { + printf("Incorrect topic or chunk len. Ignored\n"); + return; + } + + /* If the format != json, ignore */ + if(strncmp(&topic[topic_len - 4], "json", 4) != 0) { + printf("Incorrect format\n"); + } + + if(strncmp(&topic[10], "leds", 4) == 0) { + if(chunk[0] == '1') { + leds_on(LEDS_RED); + } else if(chunk[0] == '0') { + leds_off(LEDS_RED); + } + return; + } +} +/*---------------------------------------------------------------------------*/ +static void +mqtt_event(struct mqtt_connection *m, mqtt_event_t event, void *data) +{ + switch(event) { + case MQTT_EVENT_CONNECTED: { + DBG("APP - Application has a MQTT connection\n"); + timer_set(&connection_life, CONNECTION_STABLE_TIME); + state = STATE_CONNECTED; + break; + } + case MQTT_EVENT_DISCONNECTED: { + DBG("APP - MQTT Disconnect. Reason %u\n", *((mqtt_event_t *)data)); + + state = STATE_DISCONNECTED; + process_poll(&mqtt_demo_process); + break; + } + case MQTT_EVENT_PUBLISH: { + msg_ptr = data; + + /* Implement first_flag in publish message? */ + if(msg_ptr->first_chunk) { + msg_ptr->first_chunk = 0; + DBG("APP - Application received a publish on topic '%s'. Payload " + "size is %i bytes. Content:\n\n", + msg_ptr->topic, msg_ptr->payload_length); + } + + pub_handler(msg_ptr->topic, strlen(msg_ptr->topic), msg_ptr->payload_chunk, + msg_ptr->payload_length); + break; + } + case MQTT_EVENT_SUBACK: { + DBG("APP - Application is subscribed to topic successfully\n"); + break; + } + case MQTT_EVENT_UNSUBACK: { + DBG("APP - Application is unsubscribed to topic successfully\n"); + break; + } + case MQTT_EVENT_PUBACK: { + DBG("APP - Publishing complete\n"); + break; + } + default: + DBG("APP - Application got a unhandled MQTT event: %i\n", event); + break; + } +} +/*---------------------------------------------------------------------------*/ +static int +construct_pub_topic(void) +{ + int len = snprintf(pub_topic, BUFFER_SIZE, "iot-2/evt/%s/fmt/json", + conf.event_type_id); + + /* len < 0: Error. Len >= BUFFER_SIZE: Buffer too small */ + if(len < 0 || len >= BUFFER_SIZE) { + printf("Pub Topic: %d, Buffer %d\n", len, BUFFER_SIZE); + return 0; + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +construct_sub_topic(void) +{ + int len = snprintf(sub_topic, BUFFER_SIZE, "iot-2/cmd/%s/fmt/json", + conf.cmd_type); + + /* len < 0: Error. Len >= BUFFER_SIZE: Buffer too small */ + if(len < 0 || len >= BUFFER_SIZE) { + printf("Sub Topic: %d, Buffer %d\n", len, BUFFER_SIZE); + return 0; + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +construct_client_id(void) +{ + int len = snprintf(client_id, BUFFER_SIZE, "d:%s:%s:%02x%02x%02x%02x%02x%02x", + conf.org_id, conf.type_id, + linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1], + linkaddr_node_addr.u8[2], linkaddr_node_addr.u8[5], + linkaddr_node_addr.u8[6], linkaddr_node_addr.u8[7]); + + /* len < 0: Error. Len >= BUFFER_SIZE: Buffer too small */ + if(len < 0 || len >= BUFFER_SIZE) { + printf("Client ID: %d, Buffer %d\n", len, BUFFER_SIZE); + return 0; + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +static void +update_config(void) +{ + if(construct_client_id() == 0) { + /* Fatal error. Client ID larger than the buffer */ + state = STATE_CONFIG_ERROR; + return; + } + + if(construct_sub_topic() == 0) { + /* Fatal error. Topic larger than the buffer */ + state = STATE_CONFIG_ERROR; + return; + } + + if(construct_pub_topic() == 0) { + /* Fatal error. Topic larger than the buffer */ + state = STATE_CONFIG_ERROR; + return; + } + + /* Reset the counter */ + seq_nr_value = 0; + + state = STATE_INIT; + + /* + * Schedule next timer event ASAP + * + * If we entered an error state then we won't do anything when it fires. + * + * Since the error at this stage is a config error, we will only exit this + * error state if we get a new config. + */ + etimer_set(&publish_periodic_timer, 0); + + return; +} +/*---------------------------------------------------------------------------*/ +static int +init_config() +{ + /* Populate configuration with default values */ + memset(&conf, 0, sizeof(mqtt_client_config_t)); + + memcpy(conf.org_id, DEFAULT_ORG_ID, strlen(DEFAULT_ORG_ID)); + memcpy(conf.type_id, DEFAULT_TYPE_ID, strlen(DEFAULT_TYPE_ID)); + memcpy(conf.auth_token, DEFAULT_AUTH_TOKEN, strlen(DEFAULT_AUTH_TOKEN)); + memcpy(conf.event_type_id, DEFAULT_EVENT_TYPE_ID, + strlen(DEFAULT_EVENT_TYPE_ID)); + memcpy(conf.broker_ip, broker_ip, strlen(broker_ip)); + memcpy(conf.cmd_type, DEFAULT_SUBSCRIBE_CMD_TYPE, 1); + + conf.broker_port = DEFAULT_BROKER_PORT; + conf.pub_interval = DEFAULT_PUBLISH_INTERVAL; + conf.def_rt_ping_interval = DEFAULT_RSSI_MEAS_INTERVAL; + + return 1; +} +/*---------------------------------------------------------------------------*/ +static void +subscribe(void) +{ + /* Publish MQTT topic in IBM quickstart format */ + mqtt_status_t status; + + status = mqtt_subscribe(&conn, NULL, sub_topic, MQTT_QOS_LEVEL_0); + + DBG("APP - Subscribing!\n"); + if(status == MQTT_STATUS_OUT_QUEUE_FULL) { + DBG("APP - Tried to subscribe but command queue was full!\n"); + } +} +/*---------------------------------------------------------------------------*/ +static void +publish(void) +{ + /* Publish MQTT topic in IBM quickstart format */ + int len; + int remaining = APP_BUFFER_SIZE; + + seq_nr_value++; + + buf_ptr = app_buffer; + + len = snprintf(buf_ptr, remaining, + "{" + "\"d\":{" + "\"Seq #\":%d," + "\"Uptime (sec)\":%lu", seq_nr_value, clock_seconds()); + + if(len < 0 || len >= remaining) { + printf("Buffer too short. Have %d, need %d + \\0\n", remaining, len); + return; + } + + remaining -= len; + buf_ptr += len; + + /* Put our Default route's string representation in a buffer */ + char def_rt_str[64]; + memset(def_rt_str, 0, sizeof(def_rt_str)); + ipaddr_sprintf(def_rt_str, sizeof(def_rt_str), uip_ds6_defrt_choose()); + + len = snprintf(buf_ptr, remaining, ",\"Def Route\":\"%s\",\"RSSI (dBm)\":%d", + def_rt_str, def_rt_rssi); + + if(len < 0 || len >= remaining) { + printf("Buffer too short. Have %d, need %d + \\0\n", remaining, len); + return; + } + remaining -= len; + buf_ptr += len; + + len = snprintf(buf_ptr, remaining, ",\"On-Chip Temp (deg.C)\":%d", + temperature_sensor.value(0)); + + if(len < 0 || len >= remaining) { + printf("Buffer too short. Have %d, need %d + \\0\n", remaining, len); + return; + } + remaining -= len; + buf_ptr += len; + + len = snprintf(buf_ptr, remaining, "}}"); + + if(len < 0 || len >= remaining) { + printf("Buffer too short. Have %d, need %d + \\0\n", remaining, len); + return; + } + + mqtt_publish(&conn, NULL, pub_topic, (uint8_t *)app_buffer, + strlen(app_buffer), MQTT_QOS_LEVEL_0, MQTT_RETAIN_OFF); + + DBG("APP - Publish!\n"); +} +/*---------------------------------------------------------------------------*/ +static void +connect_to_broker(void) +{ + /* Connect to MQTT server */ + mqtt_connect(&conn, conf.broker_ip, conf.broker_port, + conf.pub_interval * 3); + + state = STATE_CONNECTING; +} +/*---------------------------------------------------------------------------*/ +static void +ping_parent(void) +{ + if(uip_ds6_get_global(ADDR_PREFERRED) == NULL) { + return; + } + + uip_icmp6_send(uip_ds6_defrt_choose(), ICMP6_ECHO_REQUEST, 0, + ECHO_REQ_PAYLOAD_LEN); +} +/*---------------------------------------------------------------------------*/ +static void +state_machine(void) +{ + switch(state) { + case STATE_INIT: + /* If we have just been configured register MQTT connection */ + mqtt_register(&conn, &mqtt_demo_process, client_id, mqtt_event, + MAX_TCP_SEGMENT_SIZE); + + /* + * If we are not using the quickstart service (thus we are an IBM + * registered device), we need to provide user name and password + */ + if(strncasecmp(conf.org_id, QUICKSTART, strlen(conf.org_id)) != 0) { + if(strlen(conf.auth_token) == 0) { + printf("User name set, but empty auth token\n"); + state = STATE_ERROR; + break; + } else { + mqtt_set_username_password(&conn, "use-token-auth", + conf.auth_token); + } + } + + /* _register() will set auto_reconnect. We don't want that. */ + conn.auto_reconnect = 0; + connect_attempt = 1; + + state = STATE_REGISTERED; + DBG("Init\n"); + /* Continue */ + case STATE_REGISTERED: + if(uip_ds6_get_global(ADDR_PREFERRED) != NULL) { + /* Registered and with a public IP. Connect */ + DBG("Registered. Connect attempt %u\n", connect_attempt); + ping_parent(); + connect_to_broker(); + } else { + leds_on(STATUS_LED); + ctimer_set(&ct, NO_NET_LED_DURATION, publish_led_off, NULL); + } + etimer_set(&publish_periodic_timer, NET_CONNECT_PERIODIC); + return; + break; + case STATE_CONNECTING: + leds_on(STATUS_LED); + ctimer_set(&ct, CONNECTING_LED_DURATION, publish_led_off, NULL); + /* Not connected yet. Wait */ + DBG("Connecting (%u)\n", connect_attempt); + break; + case STATE_CONNECTED: + /* Don't subscribe unless we are a registered device */ + if(strncasecmp(conf.org_id, QUICKSTART, strlen(conf.org_id)) == 0) { + DBG("Using 'quickstart': Skipping subscribe\n"); + state = STATE_PUBLISHING; + } + /* Continue */ + case STATE_PUBLISHING: + /* If the timer expired, the connection is stable. */ + if(timer_expired(&connection_life)) { + /* + * Intentionally using 0 here instead of 1: We want RECONNECT_ATTEMPTS + * attempts if we disconnect after a successful connect + */ + connect_attempt = 0; + } + + if(mqtt_ready(&conn) && conn.out_buffer_sent) { + /* Connected. Publish */ + if(state == STATE_CONNECTED) { + subscribe(); + state = STATE_PUBLISHING; + } else { + leds_on(STATUS_LED); + ctimer_set(&ct, PUBLISH_LED_ON_DURATION, publish_led_off, NULL); + publish(); + } + etimer_set(&publish_periodic_timer, conf.pub_interval); + + DBG("Publishing\n"); + /* Return here so we don't end up rescheduling the timer */ + return; + } else { + /* + * Our publish timer fired, but some MQTT packet is already in flight + * (either not sent at all, or sent but not fully ACKd). + * + * This can mean that we have lost connectivity to our broker or that + * simply there is some network delay. In both cases, we refuse to + * trigger a new message and we wait for TCP to either ACK the entire + * packet after retries, or to timeout and notify us. + */ + DBG("Publishing... (MQTT state=%d, q=%u)\n", conn.state, + conn.out_queue_full); + } + break; + case STATE_DISCONNECTED: + DBG("Disconnected\n"); + if(connect_attempt < RECONNECT_ATTEMPTS || + RECONNECT_ATTEMPTS == RETRY_FOREVER) { + /* Disconnect and backoff */ + clock_time_t interval; + mqtt_disconnect(&conn); + connect_attempt++; + + interval = connect_attempt < 3 ? RECONNECT_INTERVAL << connect_attempt : + RECONNECT_INTERVAL << 3; + + DBG("Disconnected. Attempt %u in %lu ticks\n", connect_attempt, interval); + + etimer_set(&publish_periodic_timer, interval); + + state = STATE_REGISTERED; + return; + } else { + /* Max reconnect attempts reached. Enter error state */ + state = STATE_ERROR; + DBG("Aborting connection after %u attempts\n", connect_attempt - 1); + } + break; + case STATE_CONFIG_ERROR: + /* Idle away. The only way out is a new config */ + printf("Bad configuration\n"); + return; + case STATE_ERROR: + default: + leds_on(STATUS_LED); + /* + * 'default' should never happen. + * + * If we enter here it's because of some error. Stop timers. The only thing + * that can bring us out is a new config event + */ + printf("Default case: State=0x%02x\n", state); + return; + } + + /* If we didn't return so far, reschedule ourselves */ + etimer_set(&publish_periodic_timer, STATE_MACHINE_PERIODIC); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(mqtt_demo_process, ev, data) +{ + + PROCESS_BEGIN(); + + printf("MQTT Demo Process\n"); + + if(init_config() != 1) { + PROCESS_EXIT(); + } + + update_config(); + + def_rt_rssi = 0x8000000; + uip_icmp6_echo_reply_callback_add(&echo_reply_notification, + echo_reply_handler); + etimer_set(&echo_request_timer, conf.def_rt_ping_interval); + + PUBLISH_TRIGGER->configure(SENSORS_ACTIVE, 1); + + /* Main loop */ + while(1) { + + PROCESS_YIELD(); + + if(ev == sensors_event && data == PUBLISH_TRIGGER) { + if(state == STATE_ERROR) { + connect_attempt = 1; + state = STATE_REGISTERED; + } + } + + if((ev == PROCESS_EVENT_TIMER && data == &publish_periodic_timer) || + ev == PROCESS_EVENT_POLL || + (ev == sensors_event && data == PUBLISH_TRIGGER && PUBLISH_TRIGGER->value(BUTTON_SENSOR_VALUE_STATE) == 0)) { + state_machine(); + } + + if(ev == PROCESS_EVENT_TIMER && data == &echo_request_timer) { + ping_parent(); + etimer_set(&echo_request_timer, conf.def_rt_ping_interval); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/examples/nrf52dk/mqtt-demo/project-conf.h b/examples/nrf52dk/mqtt-demo/project-conf.h new file mode 100644 index 000000000..b52e1a48f --- /dev/null +++ b/examples/nrf52dk/mqtt-demo/project-conf.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc2538-mqtt-demo + * @{ + * + * \file + * Project specific configuration defines for the MQTT demo + */ +/*---------------------------------------------------------------------------*/ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ +/*---------------------------------------------------------------------------*/ +/* User configuration */ +#define MQTT_DEMO_STATUS_LED LEDS_GREEN + +/* If undefined, the demo will attempt to connect to IBM's quickstart */ +#define MQTT_DEMO_BROKER_IP_ADDR "fd00::215:83ff:fed2:dbd7" +/*---------------------------------------------------------------------------*/ +#endif /* PROJECT_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/examples/nrf52dk/timer-test/Makefile b/examples/nrf52dk/timer-test/Makefile new file mode 100644 index 000000000..ac89a34a4 --- /dev/null +++ b/examples/nrf52dk/timer-test/Makefile @@ -0,0 +1,9 @@ +CONTIKI_PROJECT = timer-test + +CONTIKI_WITH_RPL=0 +NRF52_WITHOUT_SOFTDEVICE=1 + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/nrf52dk/timer-test/README.md b/examples/nrf52dk/timer-test/README.md new file mode 100644 index 000000000..9ce7cad94 --- /dev/null +++ b/examples/nrf52dk/timer-test/README.md @@ -0,0 +1,20 @@ +Timers test +=========== +Timers test is an application allows for testing clocks implementation for nRF52 DK. +The results of different tests are output to the console. + +There are 4 tests performed: + + 1) TEST clock_delay_usec() - measures duration of a NOP delay using rtimer. It's expected + that difference is close to 0. + + 2) TEST rtimer - schedules an rtimer callback after 1 second. Prints actual time difference + in rtimer and clock ticks. It's expected that both values are close to 0. + + 3) TEST etimer - schedules an event timer and measures time difference. It is expected that + the value is close to 0. + +The example requires one DK and it doesn't use SoftDevice. To compile and flash the +example run: + + make TARGET=nrf52dk timer-test.flash \ No newline at end of file diff --git a/examples/sensinode/timer-test.c b/examples/nrf52dk/timer-test/timer-test.c similarity index 60% rename from examples/sensinode/timer-test.c rename to examples/nrf52dk/timer-test/timer-test.c index df954bccc..e0ced7293 100644 --- a/examples/sensinode/timer-test.c +++ b/examples/nrf52dk/timer-test/timer-test.c @@ -6,20 +6,26 @@ * \author * Zach Shelby (Original) * George Oikonomou - (rtimer code) + * Wojciech Bober (nRF52 DK adaptation) * */ +/** + * \addtogroup nrf52dk-examples Demo projects for nRF52 DK + * @{ + */ #include "contiki.h" #include "sys/clock.h" #include "sys/rtimer.h" #include "dev/leds.h" +#include "nrf_delay.h" + #include /*---------------------------------------------------------------------------*/ #define TEST_CLOCK_DELAY_USEC 1 #define TEST_RTIMER 1 #define TEST_ETIMER 1 -#define TEST_CLOCK_SECONDS 1 /*---------------------------------------------------------------------------*/ static struct etimer et; @@ -27,18 +33,17 @@ static struct etimer et; static rtimer_clock_t start_count, end_count, diff; #endif -#if TEST_CLOCK_SECONDS -static unsigned long sec; -#endif - #if TEST_ETIMER static clock_time_t count; #endif #if TEST_RTIMER static struct rtimer rt; -rtimer_clock_t rt_now, rt_for; -static clock_time_t ct; +static clock_time_t ct_now; +rtimer_clock_t rt_now, rt_until; + +static volatile rtimer_clock_t rt_now_cb; +static volatile clock_time_t ct_cb; #endif static uint8_t i; @@ -50,9 +55,8 @@ AUTOSTART_PROCESSES(&clock_test_process); void rt_callback(struct rtimer *t, void *ptr) { - rt_now = RTIMER_NOW(); - ct = clock_time(); - printf("Task called at %u (clock = %u)\n", rt_now, ct); + rt_now_cb = RTIMER_NOW(); + ct_cb = clock_time(); } #endif /*---------------------------------------------------------------------------*/ @@ -60,74 +64,59 @@ PROCESS_THREAD(clock_test_process, ev, data) { PROCESS_BEGIN(); - etimer_set(&et, 2 * CLOCK_SECOND); - PROCESS_YIELD(); + printf("RTIMER_SECOND=%d CLOCK_SECOND=%d\n", RTIMER_SECOND, CLOCK_SECOND); + #if TEST_CLOCK_DELAY_USEC - printf("clock_delay_usec test, (10,000 x i) usec:\n"); + printf("=======================\n"); + printf("TEST clock_delay_usec()\n"); + printf("=======================\n"); i = 1; while(i < 7) { start_count = RTIMER_NOW(); clock_delay_usec(10000 * i); end_count = RTIMER_NOW(); diff = end_count - start_count; - printf("Requested: %u usec, Real: %u rtimer ticks = ~%u us\n", - 10000 * i, diff, diff * 64); + printf("difference [usec]: %ld\n", 10000 * i - (diff*(1000000/RTIMER_SECOND))); i++; } #endif #if TEST_RTIMER - printf("Rtimer Test, 1 sec (%u rtimer ticks):\n", RTIMER_SECOND); + printf("=======================\n"); + printf("TEST rtimer\n"); + printf("=======================\n"); i = 0; while(i < 5) { etimer_set(&et, 2 * CLOCK_SECOND); - printf("=======================\n"); - ct = clock_time(); rt_now = RTIMER_NOW(); - rt_for = rt_now + RTIMER_SECOND; - printf("Now=%u (clock = %u) - For=%u\n", rt_now, ct, rt_for); - if(rtimer_set(&rt, rt_for, 1, (rtimer_callback_t) rt_callback, NULL) != - RTIMER_OK) { + ct_now = clock_time(); + rt_until = rt_now + RTIMER_SECOND; + printf("now [ticks]: %lu until[ticks]: %lu\n", rt_now, rt_until); + if (rtimer_set(&rt, rt_until, 1, rt_callback, NULL) != RTIMER_OK) { printf("Error setting\n"); } - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + printf("rtimer difference [ticks]: %ld\n", RTIMER_SECOND - (rt_now_cb - rt_now)); + printf("clock difference [ticks]: %ld\n", CLOCK_SECOND - (ct_cb - ct_now)); i++; } #endif #if TEST_ETIMER - printf("Clock tick and etimer test, 1 sec (%u clock ticks):\n", - CLOCK_SECOND); + printf("=======================\n"); + printf("TEST etimer\n"); + printf("=======================\n"); i = 0; - while(i < 10) { - etimer_set(&et, CLOCK_SECOND); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - etimer_reset(&et); - + while(i < 5) { + etimer_set(&et, i*CLOCK_SECOND); count = clock_time(); - printf("%u ticks\n", count); - - leds_toggle(LEDS_RED); - i++; - } -#endif - -#if TEST_CLOCK_SECONDS - printf("Clock seconds test (5s):\n"); - i = 0; - while(i < 10) { - etimer_set(&et, 5 * CLOCK_SECOND); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); etimer_reset(&et); - - sec = clock_seconds(); - printf("%lu seconds\n", sec); - - leds_toggle(LEDS_GREEN); + printf("difference [ticks]: %lu\n", i*CLOCK_SECOND - (clock_time() - count)); + leds_toggle(LEDS_RED); i++; } #endif @@ -137,3 +126,6 @@ PROCESS_THREAD(clock_test_process, ev, data) PROCESS_END(); } /*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/examples/openmote-cc2538/Makefile b/examples/openmote-cc2538/Makefile new file mode 100644 index 000000000..e5e5eb4f3 --- /dev/null +++ b/examples/openmote-cc2538/Makefile @@ -0,0 +1,9 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" + +CONTIKI_PROJECT = openmote-demo + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../.. +CONTIKI_WITH_RIME = 1 +include $(CONTIKI)/Makefile.include diff --git a/examples/openmote-cc2538/openmote-demo.c b/examples/openmote-cc2538/openmote-demo.c new file mode 100644 index 000000000..393203a0c --- /dev/null +++ b/examples/openmote-cc2538/openmote-demo.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-cc2538 + * @{ + * + * \defgroup openmote-examples OpenMote-CC2538 Example Projects + * @{ + * + * Example project demonstrating the OpenMote-CC2538 functionality + * + * @{ + * + * \file + * Example demonstrating the OpenMote-CC2538 platform + * \author + * Pere Tuset + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "cpu.h" +#include "sys/etimer.h" +#include "dev/leds.h" +#include "dev/uart.h" +#include "dev/button-sensor.h" +#include "dev/serial-line.h" +#include "dev/sys-ctrl.h" +#include "net/rime/broadcast.h" + +#include "dev/adxl346.h" +#include "dev/max44009.h" +#include "dev/sht21.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define BROADCAST_CHANNEL 129 +/*---------------------------------------------------------------------------*/ +PROCESS(openmote_demo_process, "OpenMote-CC2538 demo process"); +AUTOSTART_PROCESSES(&openmote_demo_process); +/*---------------------------------------------------------------------------*/ +static void +broadcast_recv(struct broadcast_conn *c, const linkaddr_t *from) +{ + leds_toggle(LEDS_GREEN); + printf("Received %u bytes: '0x%04x'\n", packetbuf_datalen(), + *(uint16_t *)packetbuf_dataptr()); +} +/*---------------------------------------------------------------------------*/ +static const struct broadcast_callbacks bc_rx = { broadcast_recv }; +static struct broadcast_conn bc; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(openmote_demo_process, ev, data) +{ + static struct etimer et; + static int16_t counter; + static uint16_t adxl346_present, sht21_present, max44009_present; + static int16_t accel, light, temperature, humidity; + + PROCESS_EXITHANDLER(broadcast_close(&bc)) + + PROCESS_BEGIN(); + + /* Initialize and calibrate the ADXL346 sensor */ + adxl346_present = SENSORS_ACTIVATE(adxl346); + if(adxl346_present == ADXL346_ERROR) { + printf("ADXL346 sensor is NOT present!\n"); + leds_on(LEDS_YELLOW); + } else { + adxl346.configure(ADXL346_CALIB_OFFSET, 0); + } + + /* Initialize the MAX44009 sensor */ + max44009_present = SENSORS_ACTIVATE(max44009); + if(max44009_present == MAX44009_ERROR) { + printf("MAX44009 sensor is NOT present!\n"); + leds_on(LEDS_ORANGE); + } + + /* Initialize the SHT21 sensor */ + sht21_present = SENSORS_ACTIVATE(sht21); + if(sht21_present == SHT21_ERROR) { + printf("SHT21 sensor is NOT present!\n"); + leds_on(LEDS_RED); + } + + counter = 0; + broadcast_open(&bc, BROADCAST_CHANNEL, &bc_rx); + + printf("****************************************\n"); + + while(1) { + etimer_set(&et, CLOCK_SECOND); + + PROCESS_YIELD(); + + if(ev == PROCESS_EVENT_TIMER) { + if(adxl346_present != ADXL346_ERROR) { + leds_on(LEDS_YELLOW); + accel = adxl346.value(ADXL346_READ_X_mG); + printf("X Acceleration: %d.%u G\n", accel / 1000, accel % 1000); + accel = adxl346.value(ADXL346_READ_Y_mG); + printf("Y Acceleration: %d.%u G\n", accel / 1000, accel % 1000); + accel = adxl346.value(ADXL346_READ_Z_mG); + printf("Z Acceleration: %d.%u G\n", accel / 1000, accel % 1000); + leds_off(LEDS_YELLOW); + } + + if(max44009_present != MAX44009_ERROR) { + leds_on(LEDS_ORANGE); + light = max44009.value(MAX44009_READ_LIGHT); + printf("Light: %u.%ulux\n", light / 100, light % 100); + leds_off(LEDS_ORANGE); + } + + if(sht21_present != SHT21_ERROR) { + leds_on(LEDS_RED); + temperature = sht21.value(SHT21_READ_TEMP); + printf("Temperature: %u.%uC\n", temperature / 100, temperature % 100); + humidity = sht21.value(SHT21_READ_RHUM); + printf("Rel. humidity: %u.%u%%\n", humidity / 100, humidity % 100); + leds_off(LEDS_RED); + } + + printf("****************************************\n"); + } + + if(ev == sensors_event) { + if(data == &button_sensor) { + if(button_sensor.value(BUTTON_SENSOR_VALUE_TYPE_LEVEL) == + BUTTON_SENSOR_PRESSED_LEVEL) { + leds_toggle(LEDS_GREEN); + packetbuf_copyfrom(&counter, sizeof(counter)); + broadcast_send(&bc); + } + } + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/examples/openmote-cc2538/openmote-demo.gdb b/examples/openmote-cc2538/openmote-demo.gdb new file mode 100644 index 000000000..43cbb5530 --- /dev/null +++ b/examples/openmote-cc2538/openmote-demo.gdb @@ -0,0 +1,10 @@ +target remote localhost:2331 +monitor interface JTAG +monitor endian little +monitor speed auto +monitor flash device = CC2538SF53 +monitor flash breakpoints = 1 +monitor flash download = 1 +monitor reset +load +continue diff --git a/examples/openmote-cc2538/project-conf.h b/examples/openmote-cc2538/project-conf.h new file mode 100644 index 000000000..718ce668d --- /dev/null +++ b/examples/openmote-cc2538/project-conf.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup remote-examples + * @{ + * + * \file + * Project specific configuration defines for the basic RE-Mote examples + */ +/*---------------------------------------------------------------------------*/ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ +/*---------------------------------------------------------------------------*/ +#define BROADCAST_CHANNEL 129 +#define NETSTACK_CONF_RDC nullrdc_driver +/*---------------------------------------------------------------------------*/ +#endif /* PROJECT_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/examples/osd/.gitignore b/examples/osd/.gitignore index d21857f07..179e9fe4c 100644 --- a/examples/osd/.gitignore +++ b/examples/osd/.gitignore @@ -1,2 +1,4 @@ *.osd-merkur *.eep +*.osd-merkur-128 +*.osd-merkur-256 diff --git a/examples/osd/6lowpan-tk/Makefile b/examples/osd/6lowpan-tk/Makefile deleted file mode 100644 index 391be1dc9..000000000 --- a/examples/osd/6lowpan-tk/Makefile +++ /dev/null @@ -1,90 +0,0 @@ -all: er-example-server -# Use this target explicitly if requried: er-plugtest-server - -CONTIKI=../../.. -CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" - -# for static routing, if enabled -ifneq ($(TARGET), minimal-net) -ifneq ($(TARGET), native) -ifneq ($(findstring avr,$(TARGET)), avr) -PROJECT_SOURCEFILES += static-routing.c -endif -endif -endif -# intkey -PROJECT_SOURCEFILES += intkey.c - -# variable for root Makefile.include -WITH_UIP6=1 -# for some platforms -UIP_CONF_IPV6=1 - -# variable for this Makefile -# configure CoAP implementation (3|7) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=7 - -# new variable since slip-radio -ifneq ($(TARGET), minimal-net) -UIP_CONF_RPL=1 -else -# minimal-net does not support RPL under Linux and is mostly used to test CoAP only -${info INFO: compiling without RPL} -UIP_CONF_RPL=0 -CFLAGS += -DUIP_CONF_ND6_DEF_MAXDADNS=0 -CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" -CFLAGS += -DUIP_CONF_BUFFER_SIZE=1280 -endif - -# linker optimizations -SMALL=1 - -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif - -APPS += erbium - -# optional rules to get assembly -#CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 -#CUSTOM_RULE_S_TO_OBJECTDIR_O = 1 - -include $(CONTIKI)/Makefile.include - -# optional rules to get assembly -#$(OBJECTDIR)/%.o: asmdir/%.S -# $(CC) $(CFLAGS) -MMD -c $< -o $@ -# @$(FINALIZE_DEPENDENCY) -# -#asmdir/%.S: %.c -# $(CC) $(CFLAGS) -MMD -S $< -o $@ - -# border router rules -$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c - (cd $(CONTIKI)/tools && $(MAKE) tunslip6) - -connect-router: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 - -connect-router-cooja: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 - -tap0up: - sudo ip address add fdfd::1/64 dev tap0 diff --git a/examples/osd/6lowpan-tk/README b/examples/osd/6lowpan-tk/README deleted file mode 100644 index 84d7dd2f4..000000000 --- a/examples/osd/6lowpan-tk/README +++ /dev/null @@ -1,76 +0,0 @@ -A Quick Introduction to the Erbium (Er) REST Engine -=================================================== -Compile the Example -------------------- -./run.sh - -OSD-Merkur Board ----------------------- -write the images to the OSD-Merkur Board: - -./flash.sh - -EXAMPLE FILES -------------- -er-example-server.c: A RESTful server example showing how to use the REST layer to develop server-side applications (at the moment only CoAP is implemented for the REST Engine). -er-example-client.c: A CoAP client that polls the /actuators/toggle resource every 10 seconds and cycles through 4 resources on button press (target address is hard-coded). -er-plugtest-server.c: The server used for draft compliance testing at ETSI IoT CoAP Plugtest in Paris, France, March 2012 (configured for minimal-net). - -PRELIMINARIES -------------- -- Make sure rpl-border-router has the same stack and fits into mote memory: - You can disable RDC in border-router project-conf.h (not really required as BR keeps radio turned on). - #undef NETSTACK_CONF_RDC - #define NETSTACK_CONF_RDC nullrdc_driver -- For convenience, define the Cooja addresses in /etc/hosts - aaaa::0212:7401:0001:0101 cooja1 - aaaa::0212:7402:0002:0202 cooja2 - ... -- Get the Copper (Cu) CoAP user-agent from https://addons.mozilla.org/en-US/firefox/addon/copper-270430/ -- Optional: Save your target as default target - $ make TARGET=sky savetarget - -COOJA HOWTO ------------ -Server only: -1) $ make TARGET=cooja server-only.csc -2) Open new terminal -3) $ make connect-router-cooja -4) Start Copper and discover resources at coap://cooja2:5683/ -- Choose "Click button on Sky 2" from the context menu of mote 2 (server) after requesting /test/separate -- Do the same when observing /test/event - -With client: -1) $ make TARGET=cooja server-client.csc -2) Open new terminal -3) $ make connect-router-cooja -4) Wait until red LED toggles on mote 2 (server) -5) Choose "Click button on Sky 3" from the context menu of mote 3 (client) and watch serial output - -DETAILS -------- -Erbium currently implements draft 08 (name "er-coap-07" stems from last technical draft changes). -Central features are commented in er-example-server.c. -In general, apps/er-coap-07 supports: -* All draft 08 header options -* CON Retransmissions (note COAP_MAX_OPEN_TRANSACTIONS) -* Blockwise Transfers (note REST_MAX_CHUNK_SIZE, see er-plugtest-server.c for Block1 uploads) -* Separate Responses (no rest_set_pre_handler() required anymore, note coap_separate_accept(), _reject(), and _resume()) -* Resource Discovery -* Observing Resources (see EVENT_ and PRERIODIC_RESOURCE, note COAP_MAX_OBSERVERS) - -REST IMPLEMENTATIONS --------------------- -The Makefile uses WITH_COAP to configure different implementations for the Erbium (Er) REST Engine. -* WITH_COAP=7 uses Erbium CoAP 08 apps/er-coap-07/. - The default port for coap-07/-08 is 5683. -* WITH_COAP=3 uses Erbium CoAP 03 apps/er-coap-03/. - The default port for coap-03 is 61616. - er-coap-03 produces some warnings, as it not fully maintained anymore. -* WITH_COAP=0 is a stub to link an Erbium HTTP engine that uses the same resource abstraction (REST.x() functions and RESOURCE macros. - -TODOs ------ -* Observe client -* Multiple If-Match ETags -* (Message deduplication) diff --git a/examples/osd/6lowpan-tk/er-example-server.c b/examples/osd/6lowpan-tk/er-example-server.c deleted file mode 100644 index f850940b1..000000000 --- a/examples/osd/6lowpan-tk/er-example-server.c +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright (c) 2011, Matthias Kovatsch and other contributors. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Erbium (Er) PIR REST Engine example (with CoAP-specific code) - * \author - * Matthias Kovatsch - * Harald Pichler - */ - -#include -#include -#include -#include "contiki.h" -#include "contiki-net.h" - - -/* Define which resources to include to meet memory constraints. */ -#define REST_RES_INFO 1 -#define REST_RES_TEMPERATURE 0 -//#define REST_RES_EVENT 1 -#define REST_RES_LEDS 1 -#define REST_RES_TOGGLE 1 -#define REST_RES_BATTERY 1 - -#if !UIP_CONF_IPV6_RPL && !defined (CONTIKI_TARGET_MINIMAL_NET) && !defined (CONTIKI_TARGET_NATIVE) -#warning "Compiling with static routing!" -#include "static-routing.h" -#endif - -#include "erbium.h" -#include "intkey.h" - -#include "dev/led.h" -#if defined (PLATFORM_HAS_BUTTON) -#include "dev/button-sensor.h" -#endif -#if defined (PLATFORM_HAS_LEDS) -#include "dev/leds.h" -#endif -#if defined (PLATFORM_HAS_TEMPERATURE) -#include "dev/temperature-sensor.h" -#endif -#if defined (PLATFORM_HAS_BATTERY) -#include "dev/battery-sensor.h" -#endif - - -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP == 3 -#include "er-coap-03.h" -#elif WITH_COAP == 7 -#include "er-coap-07.h" -#else -#warning "Erbium example without CoAP-specifc functionality" -#endif /* CoAP-specific example */ - -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - -/******************************************************************************/ - -#if REST_RES_INFO -/* - * Resources are defined by the RESOURCE macro. - * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). - */ -RESOURCE(info, METHOD_GET, "info", "title=\"Info\";rt=\"text\""); - -/* - * A handler function named [resource name]_handler must be implemented for each RESOURCE. - * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore - * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. - * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. - */ -void -info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - char message[100]; - int index = 0; - int length = 0; /* |<-------->| */ - - /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ - // jSON Format - index += sprintf(message + index,"{\n \"Version\" : \"V1.0pre1\",\n"); - index += sprintf(message + index," \"name\" : \"6lowpan-tk\"\n"); - index += sprintf(message + index,"}\n"); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - REST.set_response_payload(response, buffer, length); -} -#endif - -// pcintkey_ext -/*A simple actuator example. read the key button status*/ -RESOURCE(extbutton, METHOD_GET | METHOD_PUT , "sensors/extbutton", "title=\"ext.Button\";rt=\"Text\""); -void -extbutton_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - static char bname1[17]="reed1"; - static char bname2[17]="reed2"; - static char bname3[17]="sabotage"; - int success = 1; - - char temp[100]; - int index = 0; - int length = 0; /* |<-------->| */ - const char *name = NULL; - size_t len = 0; - - switch(REST.get_method_type(request)){ - case METHOD_GET: - // jSON Format - index += sprintf(temp + index,"{\n \"%s\" : ",bname1); - if(is_reed1()) - index += sprintf(temp + index,"\"on\",\n"); - else - index += sprintf(temp + index,"\"off\",\n"); - index += sprintf(temp + index,"\n \"%s\" : ",bname2); - if(is_reed2()) - index += sprintf(temp + index,"\"on\",\n"); - else - index += sprintf(temp + index,"\"off\",\n"); - index += sprintf(temp + index," \"%s\" : ",bname3); - if(is_sabotage()) - index += sprintf(temp + index,"\"on\"\n"); - else - index += sprintf(temp + index,"\"off\"\n"); - index += sprintf(temp + index,"}\n"); - - length = strlen(temp); - memcpy(buffer, temp,length ); - - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - REST.set_response_payload(response, buffer, length); - - break; - case METHOD_PUT: - - if (success && (len=REST.get_post_variable(request, "name", &name))) { - PRINTF("name %s\n", name); - memcpy(bname1, name,len); - bname1[len]=0; - } else { - success = 0; - } - break; - default: - success = 0; - } - if (!success) { - REST.set_response_status(response, REST.status.BAD_REQUEST); - } -} - -/******************************************************************************/ -#if REST_RES_EVENT -/* - * Example for an event resource. - * Additionally takes a period parameter that defines the interval to call [name]_periodic_handler(). - * A default post_handler takes care of subscriptions and manages a list of subscribers to notify. - */ -EVENT_RESOURCE(reed1, METHOD_GET, "sensors/reed1", "title=\"Event demo\";obs"); - -void -reed1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - /* Usually, a CoAP server would response with the current resource representation. */ - const char *msg = "It's eventful!"; - REST.set_response_payload(response, (uint8_t *)msg, strlen(msg)); - - /* A post_handler that handles subscriptions/observing will be called for periodic resources by the framework. */ -} - -/* Additionally, a handler function named [resource name]_event_handler must be implemented for each PERIODIC_RESOURCE defined. - * It will be called by the REST manager process with the defined period. */ -void -reed1_event_handler(resource_t *r) -{ - static uint16_t event_counter = 0; - static char content[12]; - - ++event_counter; - - PRINTF("REED1 TICK %u for /%s\n", event_counter, r->url); - - /* Build notification. */ - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_CON, CONTENT_2_05, 0 ); - coap_set_payload(notification, content, snprintf(content, sizeof(content), "EVENT %u", event_counter)); - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(r, event_counter, notification); -} -#endif /* PLATFORM_HAS_EVENT */ - -/******************************************************************************/ -#if defined (PLATFORM_HAS_LEDS) -/******************************************************************************/ -#if REST_RES_LEDS -/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -RESOURCE(leds, METHOD_POST | METHOD_PUT , "actuators/leds", "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\""); - -void -leds_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - size_t len = 0; - const char *color = NULL; - const char *mode = NULL; - uint8_t led = 0; - int success = 1; - - if ((len=REST.get_query_variable(request, "color", &color))) { - PRINTF("color %.*s\n", len, color); - - if (strncmp(color, "r", len)==0) { - led = LEDS_RED; - } else if(strncmp(color,"g", len)==0) { - led = LEDS_GREEN; - } else if (strncmp(color,"b", len)==0) { - led = LEDS_BLUE; - } else { - success = 0; - } - } else { - success = 0; - } - - if (success && (len=REST.get_post_variable(request, "mode", &mode))) { - PRINTF("mode %s\n", mode); - - if (strncmp(mode, "on", len)==0) { - leds_on(led); - } else if (strncmp(mode, "off", len)==0) { - leds_off(led); - } else { - success = 0; - } - } else { - success = 0; - } - - if (!success) { - REST.set_response_status(response, REST.status.BAD_REQUEST); - } -} -#endif - -/******************************************************************************/ -#if REST_RES_TOGGLE -/* A simple actuator example. Toggles the red led */ -RESOURCE(toggle, METHOD_GET | METHOD_PUT | METHOD_POST, "actuators/toggle", "title=\"Red LED\";rt=\"Control\""); -void -toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - leds_toggle(LEDS_RED); -} -#endif -#endif /* PLATFORM_HAS_LEDS */ - -/******************************************************************************/ - -/******************************************************************************/ -#if REST_RES_TEMPERATURE && defined (PLATFORM_HAS_TEMPERATURE) -/* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(temperature, METHOD_GET, "sensors/cputemp", "title=\"Temperature status\";rt=\"temperature-c\""); -void -temperature_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int temperature = temperature_sensor.value(0); - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", temperature); - - REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%d}", temperature); - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else - { - REST.set_response_status(response, REST.status.UNSUPPORTED_MEDIA_TYPE); - const char *msg = "Supporting content-types text/plain and application/json"; - REST.set_response_payload(response, msg, strlen(msg)); - } -} -#endif /* PLATFORM_HAS_TEMPERATURE */ - -/******************************************************************************/ -#if REST_RES_BATTERY && defined (PLATFORM_HAS_BATTERY) -/* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(battery, METHOD_GET, "sensors/battery", "title=\"Battery status\";rt=\"battery-mV\""); -void -battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int battery = battery_sensor.value(0); - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", battery); - - REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'battery':%d}", battery); - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else - { - REST.set_response_status(response, REST.status.UNSUPPORTED_MEDIA_TYPE); - const char *msg = "Supporting content-types text/plain and application/json"; - REST.set_response_payload(response, msg, strlen(msg)); - } -} -#endif /* PLATFORM_HAS_BATTERY */ -/******************************************************************************/ - -void -hw_init() -{ - leds_off(LEDS_RED); - intkey_init(); -} - -PROCESS(rest_server_example, "Erbium Example Server"); - -AUTOSTART_PROCESSES(&rest_server_example, &sensors_process); - -PROCESS_THREAD(rest_server_example, ev, data) -{ - PROCESS_BEGIN(); - PRINTF("Starting Erbium Example Server\n"); - -#ifdef RF_CHANNEL - PRINTF("RF channel: %u\n", RF_CHANNEL); -#endif -#ifdef IEEE802154_PANID - PRINTF("PAN ID: 0x%04X\n", IEEE802154_PANID); -#endif - - PRINTF("uIP buffer: %u\n", UIP_BUFSIZE); - PRINTF("LL header: %u\n", UIP_LLH_LEN); - PRINTF("IP+UDP header: %u\n", UIP_IPUDPH_LEN); - PRINTF("REST max chunk: %u\n", REST_MAX_CHUNK_SIZE); - -/* if static routes are used rather than RPL */ -#if !UIP_CONF_IPV6_RPL && !defined (CONTIKI_TARGET_MINIMAL_NET) && !defined (CONTIKI_TARGET_NATIVE) - set_global_address(); - configure_routing(); -#endif - - /* Initialize the OSD Hardware. */ - hw_init(); - /* Initialize the REST engine. */ - rest_init_engine(); - - /* Activate the application-specific resources. */ - rest_activate_resource(&resource_extbutton); -#if REST_RES_INFO - rest_activate_resource(&resource_info); -#endif - /* Activate the application-specific resources. */ -#if defined (REST_RES_EVENT) -// SENSORS_ACTIVATE(reed1_sensor); - rest_activate_event_resource(&resource_reed1); - PRINTF("ACTIVATE REED1\n"); -#endif -#if defined (PLATFORM_HAS_LEDS) -#if REST_RES_LEDS - rest_activate_resource(&resource_leds); -#endif -#if REST_RES_TOGGLE - rest_activate_resource(&resource_toggle); -#endif -#endif /* PLATFORM_HAS_LEDS */ -#if defined (PLATFORM_HAS_TEMPERATURE) && REST_RES_TEMPERATURE - SENSORS_ACTIVATE(temperature_sensor); - rest_activate_resource(&resource_temperature); -#endif -#if defined (PLATFORM_HAS_BATTERY) && REST_RES_BATTERY - SENSORS_ACTIVATE(battery_sensor); - rest_activate_resource(&resource_battery); -#endif - - /* Define application-specific events here. */ - while(1) { - PROCESS_WAIT_EVENT(); -#if defined (REST_RES_EVENT) - if (ev == sensors_event ) { - PRINTF("EVENT\n"); - if (data == &reed1_sensor) { - PRINTF("REED1 EVENT\n"); - /* Call the event_handler for this application-specific event. */ - reed1_event_handler(&resource_reed1); - PRINTF("CALL EVENT HANDLER\n"); - } - } -#endif /* REST_RES_EVENT */ - } /* while (1) */ - - PROCESS_END(); -} diff --git a/examples/osd/6lowpan-tk/flash.sh b/examples/osd/6lowpan-tk/flash.sh deleted file mode 100755 index e92d472f6..000000000 --- a/examples/osd/6lowpan-tk/flash.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-server.osd-merkur.hex:a -U eeprom:w:er-example-server.osd-merkur.eep:a diff --git a/examples/osd/6lowpan-tk/run.sh b/examples/osd/6lowpan-tk/run.sh deleted file mode 100755 index 2efd2cf48..000000000 --- a/examples/osd/6lowpan-tk/run.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size -C --mcu=MCU=atmega128rfa1 er-example-server.osd-merkur -avr-objcopy -j .text -j .data -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.eep diff --git a/examples/osd/6lowpan-tk/server-client.csc b/examples/osd/6lowpan-tk/server-client.csc deleted file mode 100644 index 8c45fdf02..000000000 --- a/examples/osd/6lowpan-tk/server-client.csc +++ /dev/null @@ -1,227 +0,0 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - client - Erbium Client - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c - make er-example-client.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 46.57186415376375 - 40.35946215910942 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - - se.sics.cooja.interfaces.Position - 18.638049428485125 - 47.55034515769599 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 3 - - client - - - - se.sics.cooja.plugins.SimControl - 259 - 0 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 - - 300 - 2 - 178 - 261 - 1 - - - se.sics.cooja.plugins.LogListener - - - - - 762 - 3 - 491 - 2 - 182 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 4 - 74 - 578 - 18 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - 2 - - - - - 125 - 25.49079397896416 - - 1624 - 5 - 252 - 6 - 712 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 2 - - Serial port - 0,0 - - 853 - 1 - 491 - 765 - 182 - - - diff --git a/examples/osd/6lowpan-tk/server-only.csc b/examples/osd/6lowpan-tk/server-only.csc deleted file mode 100644 index d5eee34d6..000000000 --- a/examples/osd/6lowpan-tk/server-only.csc +++ /dev/null @@ -1,189 +0,0 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 35.100895239785295 - 39.70574552287428 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - se.sics.cooja.plugins.SimControl - 259 - 5 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 - - 300 - 4 - 175 - 263 - 3 - - - se.sics.cooja.plugins.LogListener - - - - - 560 - 1 - 326 - 1 - 293 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 2 - 74 - 39 - 199 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - - - - - 125 - 25.49079397896416 - - 1624 - 3 - 252 - 4 - 622 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 1 - - Serial port - 0,0 - - 702 - 0 - 646 - 564 - 2 - - - diff --git a/examples/osd/6lowpan-tk/static-routing.c b/examples/osd/6lowpan-tk/static-routing.c deleted file mode 100644 index 628594892..000000000 --- a/examples/osd/6lowpan-tk/static-routing.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * static-routing.c - * - * Created on: Oct 12, 2010 - * Author: simonduq - */ - -#include -#include "static-routing.h" - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - -#include "contiki-net.h" -#include "node-id.h" - -int node_rank; - -struct id_to_addrs { - int id; - uint32_t addr; -}; - -const struct id_to_addrs motes_addrs[] = { -/* - * Static routing requires a map nodeid => address. - * The nodeid can be programmed with the sky-shell. - * The addresses should also be added to /etc/hosts. - * - * aaaa::212:7400:1160:f62d sky1 - * aaaa::212:7400:0da0:d748 sky2 - * aaaa::212:7400:116e:c325 sky3 - * aaaa::212:7400:116e:c444 sky4 - * aaaa::212:7400:115e:b717 sky5 - * - * Add the nodeid and last 4 bytes of the address to the map. - */ - {1, 0x1160f62d}, - {2, 0x0da0d748}, - {3, 0x116ec325}, - {4, 0x116ec444}, - {5, 0x115eb717}, -}; -/* Define the size of the map. */ -#define NODES_IN_MAP 5 - -uint32_t get_mote_suffix(int rank) { - if(--rank >=0 && rank<(sizeof(motes_addrs)/sizeof(struct id_to_addrs))) { - return motes_addrs[rank].addr; - } - return 0; -} - -int get_mote_id(uint32_t suffix) { -#if IN_COOJA - return suffix & 0xff; -#else - int i; - for(i=0; i<(sizeof(motes_addrs)/sizeof(struct id_to_addrs)); i++) { - if(suffix == motes_addrs[i].addr) { - return motes_addrs[i].id; - } - } - return 0; -#endif -} - -void set_global_address(void) { - uip_ipaddr_t ipaddr; - - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); - uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); - uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); -} - -static void add_route_ext(int dest, int next) { - PRINTF("add route ext %d %d\n", dest, next); - uip_ipaddr_t ipaddr_dest, ipaddr_next; - uip_ip6addr(&ipaddr_dest, 0xaaaa, 0, 0, 0, 0, 0, 0, dest); -#if IN_COOJA - uip_ip6addr(&ipaddr_next, 0xfe80, 0, 0, 0, 0x0212, 0x7400 | next, next, next<<8 | next); -#else - uint32_t next_suffix = get_mote_suffix(next); - uip_ip6addr(&ipaddr_next, 0xfe80, 0, 0, 0, 0x0212, 0x7400, (next_suffix >> 16) & 0xffff, next_suffix & 0xffff); -#endif - uip_ds6_route_add(&ipaddr_dest, 128, &ipaddr_next, 0); -} - -void add_route(int dest, int next) { - PRINTF("add route %d %d\n", dest, next); - uip_ipaddr_t ipaddr_dest, ipaddr_next; -#if IN_COOJA - uip_ip6addr(&ipaddr_dest, 0xaaaa, 0, 0, 0, 0x0212, 0x7400 | dest, dest, dest<<8 | dest); - uip_ip6addr(&ipaddr_next, 0xfe80, 0, 0, 0, 0x0212, 0x7400 | next, next, next<<8 | next); -#else - uint32_t dest_suffix = get_mote_suffix(dest); - uint32_t next_suffix = get_mote_suffix(next); - uip_ip6addr(&ipaddr_dest, 0xaaaa, 0, 0, 0, 0x0212, 0x7400, (dest_suffix >> 16) & 0xffff, dest_suffix & 0xffff); - uip_ip6addr(&ipaddr_next, 0xfe80, 0, 0, 0, 0x0212, 0x7400, (next_suffix >> 16) & 0xffff, next_suffix & 0xffff); -#endif - uip_ds6_route_add(&ipaddr_dest, 128, &ipaddr_next, 0); -} - -void configure_routing(void) { - int i; -#if IN_COOJA - node_rank = node_id; -#else - node_rank = -1; - for(i=0; i<(sizeof(motes_addrs)/sizeof(struct id_to_addrs)); ++i) { - if(node_id == motes_addrs[i].id) { - node_rank = i+1; - break; - } - } - - if(node_rank == -1) { - printf("unable to configure routing, node_id=%d\n", node_id); - return; - } -#endif - - printf("configure_routing, node_id=%d, node_rank %d\n", node_id, node_rank); - - if (node_rank == 1) { /* border router #1 */ - add_route_ext(2, 2); - for(i=2; i<=NODES_IN_MAP; ++i) { - add_route(i, 2); - } - } else if (node_rank < NODES_IN_MAP) { /* other node */ - add_route_ext(1, node_rank-1); - add_route_ext(2, node_rank+1); - for(i=1; i<=NODES_IN_MAP; ++i) { - if(inode_rank) { - add_route(i, node_rank+1); - } - } - } else if (node_rank == NODES_IN_MAP) { /* 2nd border router */ - add_route_ext(1, NODES_IN_MAP-1); - for(i=1; i<=NODES_IN_MAP-1; ++i) { - add_route(i, NODES_IN_MAP-1); - } - } -} diff --git a/examples/osd/6lowpan-tk/static-routing.h b/examples/osd/6lowpan-tk/static-routing.h deleted file mode 100644 index 0dff0b7ba..000000000 --- a/examples/osd/6lowpan-tk/static-routing.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * static-routing.h - * - * Created on: Oct 12, 2010 - * Author: simonduq - */ - -#ifndef STATICROUTING_H_ -#define STATICROUTING_H_ - -#include "contiki.h" - -extern int node_rank; -extern uint32_t get_mote_suffix(int id); -extern int get_mote_id(uint32_t suffix); -extern void add_route(int dest, int next); -extern void set_global_address(void); -extern void configure_routing(void); - -#endif /* STATICROUTING_H_ */ diff --git a/examples/osd/arduino-bh1750/BH1750FVI-master/.gitattributes b/examples/osd/arduino-bh1750/BH1750FVI-master/.gitattributes new file mode 100644 index 000000000..412eeda78 --- /dev/null +++ b/examples/osd/arduino-bh1750/BH1750FVI-master/.gitattributes @@ -0,0 +1,22 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/examples/osd/arduino-bh1750/BH1750FVI-master/.gitignore b/examples/osd/arduino-bh1750/BH1750FVI-master/.gitignore new file mode 100644 index 000000000..6dae74742 --- /dev/null +++ b/examples/osd/arduino-bh1750/BH1750FVI-master/.gitignore @@ -0,0 +1,36 @@ +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# ========================= +# Operating System Files +# ========================= + +# OSX +# ========================= + +.DS_Store +.AppleDouble +.LSOverride + +# Icon must ends with two \r. +Icon + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes diff --git a/examples/osd/arduino-bh1750/BH1750FVI-master/BH1750FVI.cpp b/examples/osd/arduino-bh1750/BH1750FVI-master/BH1750FVI.cpp new file mode 100644 index 000000000..600905394 --- /dev/null +++ b/examples/osd/arduino-bh1750/BH1750FVI-master/BH1750FVI.cpp @@ -0,0 +1,209 @@ +#include "BH1750FVI.h" +#if ARDUINO >= 100 + #include "Arduino.h" +#else + #include "WProgram.h" +#endif + +#include + +void BH1750FVI::begin(byte mode, byte addr, double sens, int pin){ + if(pin>=0 && pin<55){ + pinMode(pin, OUTPUT); + if(addr==BH_AddrL) digitalWrite(pin, LOW); + if(addr==BH_AddrH) digitalWrite(pin, HIGH); + } + byte sensitivity; + if(sens> 5); + MTreg_loByte = BH_MTrLb | (sensitivity & 0b00011111); + switch(mode){ + case BH_ContL: + case BH_ContH: + case BH_Conth: + startOngoingSamples(mode); + break; + case BH_SingH: + case BH_Singh: + case BH_SingL: + startSingleSample(mode); + break; + default: + mode = BH_EasyH; + startOngoingSamples(mode); + break; + } + sampleUnseen = false; + lastSampleStart = 0; +} + +word BH1750FVI::startOngoingSamples(char mode){ + if(mode==BH_NoMod) mode=currentMode; + byte lowLevelMode = mode; + if(lowLevelMode==BH_EasyH) lowLevelMode=BH_ContH; + switch(mode){ + case BH_EasyH: + case BH_ContH: + case BH_Conth: + case BH_ContL: + i2cWrite(BH_PowOn); + i2cWrite(MTreg_hiByte); + i2cWrite(MTreg_loByte); + i2cWrite(lowLevelMode); + lastSampleStart = millis(); + currentMode = mode; + return setSensitivity(currentSensitivity); + break; + default: + return 0; + } +} + +word BH1750FVI::startSingleSample(char mode){ + if(mode==BH_NoMod){ + mode=currentMode; + } + switch(mode){ + case BH_SingH: + case BH_Singh: + case BH_SingL: + i2cWrite(BH_PowOn); + i2cWrite(MTreg_hiByte); + i2cWrite(MTreg_loByte); + i2cWrite(mode); + lastSampleStart = millis(); + currentMode = mode; + return setSensitivity(currentSensitivity); + break; + default: + return 0; + } +} + +bool BH1750FVI::sampleIsFresh(){ + if(sampleUnseen) return true; + else if((millis() > (lastSampleStart+currentSamplingTime))){ + sampleUnseen = true; + return true; + } + else return false; +} + +word BH1750FVI::getLightLevel(char mode){ + unsigned long int Intensity_value; + sampleUnseen = false; + Intensity_value = i2cRead(); + if(mode!='r'){ + Intensity_value = (Intensity_value*5)/6; + if(mode!='c'){ + Intensity_value = (Intensity_value*69)/currentSensitivity; + } + /*this next adjustment is not useful in practice. if you're using + a half-scale mode, you want the extra sensitivity. I'm leaving it + here for reference. + switch(currentMode){ + case BH_Singh: + case BH_Conth: + Intensity_value /= 2; + }*/ + Intensity_value = constrain(Intensity_value, 0, 65535); + } + switch(currentMode){ + case BH_ContH: + case BH_Conth: + case BH_ContL: + case BH_EasyH: + //this is a fake previous sample time that will keep pace with + //the actual BH1750FVI's sampling rate, but isn't necessarily + //synchronized to the earliest time each new sample is available. + //if you want true synchronized timing, use a single-sample mode. + lastSampleStart = millis(); + } + return (word)Intensity_value; +} + +word BH1750FVI::setSensitivity(double sens){ + if(sens<((double)(BH_MinSv/2))){ + sens = constrain(sens, + ((double)BH_MinSv/(double)BH_DefSv), + ((double)BH_MaxSv/(double)BH_DefSv) + ); + sens = sens*(double)BH_DefSv; + } + else{ + sens = constrain(sens, (double)BH_MinSv, (double)BH_MaxSv); + } + return setSensitivity((byte)round(sens)); +} + +word BH1750FVI::setSensitivity(float sens){ + return setSensitivity((double)sens); +} + +word BH1750FVI::setSensitivity(int sens){ + sens = constrain(sens, 1, BH_MaxSv); + return setSensitivity((byte)sens); +} + +word BH1750FVI::setSensitivity(byte sens){ + if(sens<(BH_MinSv/2)){ + sens = BH_DefSv*(constrain(sens, (byte)1, (byte)3)); + } + else{ + sens = constrain(sens, BH_MinSv, BH_MaxSv); + } + switch(currentMode){ + case BH_ContL: + case BH_SingL: + currentSamplingTime = (word)((BH_FastD*(unsigned long int)sens)/BH_DefSv); + break; + default: + currentSamplingTime = (word)((((unsigned long int)BH_SlowD)*((unsigned long int)sens))/BH_DefSv); + break; + } + MTreg_hiByte = BH_MTrHb | (sens >> 5); + MTreg_loByte = BH_MTrLb | (sens & 0b00011111); + currentSensitivity = sens; + sampleUnseen = false; + return currentSamplingTime; +} + +void BH1750FVI::powerDown(){ + i2cWrite(BH_PowOf); +} + +/*I2C INTERFACE + These two functions were originally based on code written by + https://github.com/claws/ and + https://github.com/Genotronex/ +*/ +void BH1750FVI::i2cWrite(byte dataToSend){ + Wire.beginTransmission(address); + Wire.write(dataToSend); + Wire.endTransmission(); +} + +word BH1750FVI::i2cRead(){ + word value; + Wire.beginTransmission(address); + Wire.requestFrom(address, (byte)2); + if(Wire.available()){ + value = Wire.read(); + if(Wire.available()){ + value <<= 8; + value |= Wire.read(); + } + else value=0; + } + else value=0; + Wire.endTransmission(); + return value; +} \ No newline at end of file diff --git a/examples/osd/arduino-bh1750/BH1750FVI-master/BH1750FVI.h b/examples/osd/arduino-bh1750/BH1750FVI-master/BH1750FVI.h new file mode 100644 index 000000000..4a7dc9866 --- /dev/null +++ b/examples/osd/arduino-bh1750/BH1750FVI-master/BH1750FVI.h @@ -0,0 +1,115 @@ +#ifndef BH1750FVI_h +#define BH1750FVI_h + +#if ARDUINO >= 100 + #include "Arduino.h" +#else + #include "WProgram.h" +#endif + +#include + +//device address options +#define BH_AddrL 0x23 // Device address when addr pin is LOW +#define BH_AddrH 0x5C // Device address when addr pin is HIGH + +//power codes +#define BH_PowOf 0x00 // power-off code +#define BH_PowOn 0x01 // power-on code +#define BH_Reset 0x07 // code to reset the light reading register to zero + +//mode codes +#define BH_NoMod 0x02 // No mode specified. Keeps mode the same as before. +#define BH_EasyH 0x03 // 'easy' mode. basically the same as ContH +#define BH_ContH 0x10 // continuous full-scale, high-resolution sampling +#define BH_Conth 0x11 // continuous with twice the resolution but half the max value +#define BH_ContL 0x13 // continuous full-scale, low-resolution sampling. faster. +#define BH_SingH 0x20 // take one high-resolution, full-scale sample then turn off +#define BH_Singh 0x21 // take one high-resolution, half-scale sample then turn off +#define BH_SingL 0x23 // take one low-resolution, full-scale sample then turn off + // (happens to be the same as the low address value) + +//sensitivity codes +#define BH_MTrHb 0x40 // last 3 bits must be masked to 3 MSB of desired value +#define BH_MTrLb 0x60 // last 5 bits must be masked to 5 LSB of desired value +#define BH_MinSv 31 // minimum sensitivity register value, yields Lux * 0.45 +#define BH_MaxSv 254 // maximum sensitivity register value, yields Lux * 3.68 +#define BH_DefSv 69 // default sensitivity register value, yields Lux * 1.00 + +//timing delays. they're actually longer than the datasheet says. +#define BH_FastD 18 // basic delay in microseconds for a fast sample +#define BH_SlowD 125 // basic delay in microseconds for a slow sample + +class BH1750FVI { + public: + /*BEGIN + this is intended to be as error-tolerant as possible. if you don't supply + a mode, the default mode will be 'easy'. the sensitivity obviously defaults + to 1.0 (byte value of 69). Default address selection is LOW, which is how + the BH1750FVI should default if you don't connect anything to its ADDR pin. + */void begin(byte mode=BH_EasyH, byte addr=BH_AddrL, double sens=BH_DefSv, int addrPin=-1); + + /*FRESH SAMPLE POLLING + Check whether you have already looked at the current sample. + */bool sampleIsFresh(); + + /*ACTUALLY GET A READING FROM THE SENSOR + This is probably all you wanted from this library. Return value is an + unsigned 16 bit integer with units of Lux. There are three possible modes: + 'r' raw numerical reading, no units, you get what you get + 'c' convert units to Lux or half-Lux, depending on the mode, but don't + compensate for the sensitivity setting. This allows sensitivity to + be used as enclosure optics calibration/compensation. + 't' true Lux (or half-Lux) reading, regardless of sensitivity settings. + */word getLightLevel(char adjustments='c'); + + word retrieveSample(); + + /*CONTINUOUS SAMPLING + Return value of this start function is the delay time between refreshes of + the ambient light reading. After you call this function, you can use getLightLevel() + to read the most recent ambient light level. If you try to run this ongoing start + function with a one-time mode argument, it will do nothing and return 0. + */word startOngoingSamples(char mode=BH_NoMod); + + /*ONE-TIME SAMPLE START + Return value of this start function is the delay time before the new ambient + light reading will be available. You can check whether the new sample is ready + yet using sampleIsFresh(). Retrieve that single sample with getLightLevel(). + If you give this one-time start function a continuous mode argument, it will + do nothing and return 0. + */word startSingleSample(char mode=BH_NoMod); + + /*SENSITIVITY SETTINGS + This function lets you change the 'sensitivity' of the BH1750FVI by changing + its sampling time up or down. The sensitivity is stored as a number between + 31 and 254, with a default value of 69. This is intended to compensate for + having the chip installed in an enclosure that blocks some ambient light. + The floating point versions of the function allow the sensitivity to be + given as a ratio between ~0.45 and ~3.68. The return value is the number of + milliseconds that the chip will take to create a new light level reading. + */word setSensitivity(double sens); + word setSensitivity(float sens); + word setSensitivity(int sens); + word setSensitivity(byte sens=BH_DefSv); + + /*POWERDOWN FUNCTION + In case you want to turn off the BH1750FVI to save power. Other commands will wake + the chip back up. Single sample modes automatically turn off the chip after sampling, + but you can still read the value from it without waking it up. + */void powerDown(); + + private: + void init(byte mode, byte addr, byte sens); + void i2cWrite(byte dataToSend); + word i2cRead(); + byte address; + byte currentMode; + byte currentSensitivity; + bool sampleUnseen; + byte MTreg_hiByte; + byte MTreg_loByte; + unsigned long int lastSampleStart; + word currentSamplingTime; +}; +#endif \ No newline at end of file diff --git a/examples/osd/arduino-bh1750/BH1750FVI-master/BasicDemo/BasicDemo.ino b/examples/osd/arduino-bh1750/BH1750FVI-master/BasicDemo/BasicDemo.ino new file mode 100644 index 000000000..3625f5202 --- /dev/null +++ b/examples/osd/arduino-bh1750/BH1750FVI-master/BasicDemo/BasicDemo.ino @@ -0,0 +1,23 @@ +#include +#include + +BH1750FVI eye; +word maxLux = 0; + +void setup() { + Wire.begin(); + Serial.begin(115200); + //most basic setup with all default options + eye.begin(); +} + +void loop() { + //take a sensor reading, with units of Lux + word value = eye.getLightLevel(); + byte spaces; + if(value>maxLux) maxLux=value; + spaces=map(value, 0, maxLux, 0, 32); + for(int i=0; i +#include + +BH1750FVI eye; + +void setup() { + Wire.begin(); + Serial.begin(115200); + //setup with continuous sampling, using the low address and double sensitivity + eye.begin(BH_ContH, BH_AddrL, 2.0); +} + +void loop() { + //test if the sensor has had time to produce a new reading + if(eye.sampleIsFresh()){ + //read the calibration-adjusted value, according to the sensitivity setting + word value = eye.getLightLevel('c'); + logarithmicGraphing(value); + Serial.println(value); + } +} + + + + +void logarithmicGraphing(word value){ + int i=0; + while(value>>i){ + i++; + Serial.print(" "); + } + if(i>=2){ + i=i-2; + if(value&(1<= 100 + #include "Arduino.h" +//#else +// #include "WProgram.h" +//#endif + +#include + +void BH1750FVI::begin(byte mode, byte addr, double sens, int pin){ + if(pin>=0 && pin<55){ + pinMode(pin, OUTPUT); + if(addr==BH_AddrL) digitalWrite(pin, LOW); + if(addr==BH_AddrH) digitalWrite(pin, HIGH); + } + byte sensitivity; + if(sens> 5); + MTreg_loByte = BH_MTrLb | (sensitivity & 0b00011111); + switch(mode){ + case BH_ContL: + case BH_ContH: + case BH_Conth: + startOngoingSamples(mode); + break; + case BH_SingH: + case BH_Singh: + case BH_SingL: + startSingleSample(mode); + break; + default: + mode = BH_EasyH; + startOngoingSamples(mode); + break; + } + sampleUnseen = false; + lastSampleStart = 0; +} + +word BH1750FVI::startOngoingSamples(char mode){ + if(mode==BH_NoMod) mode=currentMode; + byte lowLevelMode = mode; + if(lowLevelMode==BH_EasyH) lowLevelMode=BH_ContH; + switch(mode){ + case BH_EasyH: + case BH_ContH: + case BH_Conth: + case BH_ContL: + i2cWrite(BH_PowOn); + i2cWrite(MTreg_hiByte); + i2cWrite(MTreg_loByte); + i2cWrite(lowLevelMode); + lastSampleStart = millis(); + currentMode = mode; + return setSensitivity(currentSensitivity); + break; + default: + return 0; + } +} + +word BH1750FVI::startSingleSample(char mode){ + if(mode==BH_NoMod){ + mode=currentMode; + } + switch(mode){ + case BH_SingH: + case BH_Singh: + case BH_SingL: + i2cWrite(BH_PowOn); + i2cWrite(MTreg_hiByte); + i2cWrite(MTreg_loByte); + i2cWrite(mode); + lastSampleStart = millis(); + currentMode = mode; + return setSensitivity(currentSensitivity); + break; + default: + return 0; + } +} + +bool BH1750FVI::sampleIsFresh(){ + if(sampleUnseen) return true; + else if((millis() > (lastSampleStart+currentSamplingTime))){ + sampleUnseen = true; + return true; + } + else return false; +} + +word BH1750FVI::getLightLevel(char mode){ + unsigned long int Intensity_value; + sampleUnseen = false; + Intensity_value = i2cRead(); + if(mode!='r'){ + Intensity_value = (Intensity_value*5)/6; + if(mode!='c'){ + Intensity_value = (Intensity_value*69)/currentSensitivity; + } + /*this next adjustment is not useful in practice. if you're using + a half-scale mode, you want the extra sensitivity. I'm leaving it + here for reference. + switch(currentMode){ + case BH_Singh: + case BH_Conth: + Intensity_value /= 2; + }*/ + Intensity_value = constrain(Intensity_value, 0, 65535); + } + switch(currentMode){ + case BH_ContH: + case BH_Conth: + case BH_ContL: + case BH_EasyH: + //this is a fake previous sample time that will keep pace with + //the actual BH1750FVI's sampling rate, but isn't necessarily + //synchronized to the earliest time each new sample is available. + //if you want true synchronized timing, use a single-sample mode. + lastSampleStart = millis(); + } + return (word)Intensity_value; +} + +word BH1750FVI::setSensitivity(double sens){ + if(sens<((double)(BH_MinSv/2))){ + sens = constrain(sens, + ((double)BH_MinSv/(double)BH_DefSv), + ((double)BH_MaxSv/(double)BH_DefSv) + ); + sens = sens*(double)BH_DefSv; + } + else{ + sens = constrain(sens, (double)BH_MinSv, (double)BH_MaxSv); + } + return setSensitivity((byte)round(sens)); +} + +word BH1750FVI::setSensitivity(float sens){ + return setSensitivity((double)sens); +} + +word BH1750FVI::setSensitivity(int sens){ + sens = constrain(sens, 1, BH_MaxSv); + return setSensitivity((byte)sens); +} + +word BH1750FVI::setSensitivity(byte sens){ + if(sens<(BH_MinSv/2)){ + sens = BH_DefSv*(constrain(sens, (byte)1, (byte)3)); + } + else{ + sens = constrain(sens, BH_MinSv, BH_MaxSv); + } + switch(currentMode){ + case BH_ContL: + case BH_SingL: + currentSamplingTime = (word)((BH_FastD*(unsigned long int)sens)/BH_DefSv); + break; + default: + currentSamplingTime = (word)((((unsigned long int)BH_SlowD)*((unsigned long int)sens))/BH_DefSv); + break; + } + MTreg_hiByte = BH_MTrHb | (sens >> 5); + MTreg_loByte = BH_MTrLb | (sens & 0b00011111); + currentSensitivity = sens; + sampleUnseen = false; + return currentSamplingTime; +} + +void BH1750FVI::powerDown(){ + i2cWrite(BH_PowOf); +} + +/*I2C INTERFACE + These two functions were originally based on code written by + https://github.com/claws/ and + https://github.com/Genotronex/ +*/ +void BH1750FVI::i2cWrite(byte dataToSend){ + Wire.beginTransmission(address); + Wire.write(dataToSend); + Wire.endTransmission(); +} + +word BH1750FVI::i2cRead(){ + word value; + Wire.beginTransmission(address); + Wire.requestFrom(address, (byte)2); + if(Wire.available()){ + value = Wire.read(); + if(Wire.available()){ + value <<= 8; + value |= Wire.read(); + } + else value=0; + } + else value=0; + Wire.endTransmission(); + return value; +} diff --git a/examples/osd/arduino-bh1750/BH1750FVI.h b/examples/osd/arduino-bh1750/BH1750FVI.h new file mode 100644 index 000000000..acdf62102 --- /dev/null +++ b/examples/osd/arduino-bh1750/BH1750FVI.h @@ -0,0 +1,115 @@ +#ifndef BH1750FVI_h +#define BH1750FVI_h + +//#if ARDUINO >= 100 + #include "Arduino.h" +//#else +// #include "WProgram.h" +//#endif + +#include + +//device address options +#define BH_AddrL 0x23 // Device address when addr pin is LOW +#define BH_AddrH 0x5C // Device address when addr pin is HIGH + +//power codes +#define BH_PowOf 0x00 // power-off code +#define BH_PowOn 0x01 // power-on code +#define BH_Reset 0x07 // code to reset the light reading register to zero + +//mode codes +#define BH_NoMod 0x02 // No mode specified. Keeps mode the same as before. +#define BH_EasyH 0x03 // 'easy' mode. basically the same as ContH +#define BH_ContH 0x10 // continuous full-scale, high-resolution sampling +#define BH_Conth 0x11 // continuous with twice the resolution but half the max value +#define BH_ContL 0x13 // continuous full-scale, low-resolution sampling. faster. +#define BH_SingH 0x20 // take one high-resolution, full-scale sample then turn off +#define BH_Singh 0x21 // take one high-resolution, half-scale sample then turn off +#define BH_SingL 0x23 // take one low-resolution, full-scale sample then turn off + // (happens to be the same as the low address value) + +//sensitivity codes +#define BH_MTrHb 0x40 // last 3 bits must be masked to 3 MSB of desired value +#define BH_MTrLb 0x60 // last 5 bits must be masked to 5 LSB of desired value +#define BH_MinSv 31 // minimum sensitivity register value, yields Lux * 0.45 +#define BH_MaxSv 254 // maximum sensitivity register value, yields Lux * 3.68 +#define BH_DefSv 69 // default sensitivity register value, yields Lux * 1.00 + +//timing delays. they're actually longer than the datasheet says. +#define BH_FastD 18 // basic delay in microseconds for a fast sample +#define BH_SlowD 125 // basic delay in microseconds for a slow sample + +class BH1750FVI { + public: + /*BEGIN + this is intended to be as error-tolerant as possible. if you don't supply + a mode, the default mode will be 'easy'. the sensitivity obviously defaults + to 1.0 (byte value of 69). Default address selection is LOW, which is how + the BH1750FVI should default if you don't connect anything to its ADDR pin. + */void begin(byte mode=BH_EasyH, byte addr=BH_AddrL, double sens=BH_DefSv, int addrPin=-1); + + /*FRESH SAMPLE POLLING + Check whether you have already looked at the current sample. + */bool sampleIsFresh(); + + /*ACTUALLY GET A READING FROM THE SENSOR + This is probably all you wanted from this library. Return value is an + unsigned 16 bit integer with units of Lux. There are three possible modes: + 'r' raw numerical reading, no units, you get what you get + 'c' convert units to Lux or half-Lux, depending on the mode, but don't + compensate for the sensitivity setting. This allows sensitivity to + be used as enclosure optics calibration/compensation. + 't' true Lux (or half-Lux) reading, regardless of sensitivity settings. + */word getLightLevel(char adjustments='c'); + + word retrieveSample(); + + /*CONTINUOUS SAMPLING + Return value of this start function is the delay time between refreshes of + the ambient light reading. After you call this function, you can use getLightLevel() + to read the most recent ambient light level. If you try to run this ongoing start + function with a one-time mode argument, it will do nothing and return 0. + */word startOngoingSamples(char mode=BH_NoMod); + + /*ONE-TIME SAMPLE START + Return value of this start function is the delay time before the new ambient + light reading will be available. You can check whether the new sample is ready + yet using sampleIsFresh(). Retrieve that single sample with getLightLevel(). + If you give this one-time start function a continuous mode argument, it will + do nothing and return 0. + */word startSingleSample(char mode=BH_NoMod); + + /*SENSITIVITY SETTINGS + This function lets you change the 'sensitivity' of the BH1750FVI by changing + its sampling time up or down. The sensitivity is stored as a number between + 31 and 254, with a default value of 69. This is intended to compensate for + having the chip installed in an enclosure that blocks some ambient light. + The floating point versions of the function allow the sensitivity to be + given as a ratio between ~0.45 and ~3.68. The return value is the number of + milliseconds that the chip will take to create a new light level reading. + */word setSensitivity(double sens); + word setSensitivity(float sens); + word setSensitivity(int sens); + word setSensitivity(byte sens=BH_DefSv); + + /*POWERDOWN FUNCTION + In case you want to turn off the BH1750FVI to save power. Other commands will wake + the chip back up. Single sample modes automatically turn off the chip after sampling, + but you can still read the value from it without waking it up. + */void powerDown(); + + private: + void init(byte mode, byte addr, byte sens); + void i2cWrite(byte dataToSend); + word i2cRead(); + byte address; + byte currentMode; + byte currentSensitivity; + bool sampleUnseen; + byte MTreg_hiByte; + byte MTreg_loByte; + unsigned long int lastSampleStart; + word currentSamplingTime; +}; +#endif diff --git a/examples/osd/arduino-bh1750/Makefile b/examples/osd/arduino-bh1750/Makefile new file mode 100644 index 000000000..201eeac72 --- /dev/null +++ b/examples/osd/arduino-bh1750/Makefile @@ -0,0 +1,71 @@ +# Set this to the name of your sketch (without extension .pde) +SKETCH=sketch +EXE=arduino-example + +all: $(EXE) + +CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +LFLAGS += -lm + +PROJECT_SOURCEFILES += ${SKETCH}.cpp BH1750FVI.cpp + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) + +# variable for Makefile.include +ifneq ($(TARGET), minimal-net) +CFLAGS += -DUIP_CONF_IPV6_RPL=1 +else +# minimal-net does not support RPL under Linux and is mostly used to test CoAP only +${info INFO: compiling without RPL} +CFLAGS += -DUIP_CONF_IPV6_RPL=0 +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=640 +endif + +# linker optimizations +SMALL=1 + + +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += arduino + +include $(CONTIKI)/Makefile.include +include $(CONTIKI)/apps/arduino/Makefile.include + +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + (cd $(CONTIKI)/tools && $(MAKE) tunslip6) + +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + +connect-minimal: + sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/arduino-bh1750/README.md b/examples/osd/arduino-bh1750/README.md new file mode 100644 index 000000000..e1490ed05 --- /dev/null +++ b/examples/osd/arduino-bh1750/README.md @@ -0,0 +1,11 @@ +Arduino compatibility example +============================= + +This example shows that it is now possible to re-use arduino sketches in +Contiki. This example documents the necessary magic. Arduino specifies +two routines, `setup` and `loop`. Before `setup` is called, the +framework initializes hardware. In original Arduino, all this is done in +a `main` function (in C). For contiki we define a process that does the +same. + +See the documentation file in apps/contiki-compat/README.md diff --git a/examples/osd/arduino-bh1750/arduino-example.c b/examples/osd/arduino-bh1750/arduino-example.c new file mode 100644 index 000000000..ea74dd8b8 --- /dev/null +++ b/examples/osd/arduino-bh1750/arduino-example.c @@ -0,0 +1,2 @@ +#include +AUTOSTART_PROCESSES(&arduino_sketch); diff --git a/examples/osd/arduino-bh1750/flash.sh b/examples/osd/arduino-bh1750/flash.sh new file mode 100755 index 000000000..e82962073 --- /dev/null +++ b/examples/osd/arduino-bh1750/flash.sh @@ -0,0 +1,2 @@ +#!/bin/bash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/arduino-bh1750/project-conf.h b/examples/osd/arduino-bh1750/project-conf.h new file mode 100644 index 000000000..e25aed53c --- /dev/null +++ b/examples/osd/arduino-bh1750/project-conf.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ + +#ifndef PROJECT_RPL_WEB_CONF_H_ +#define PROJECT_RPL_WEB_CONF_H_ + +#define PLATFORM_HAS_LEDS 1 +//#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_BATTERY 1 + +#define SICSLOWPAN_CONF_FRAG 1 + +#define LOOP_INTERVAL (10 * CLOCK_SECOND) + +/* Save energy */ +//#define RDC_CONF_PT_YIELD_OFF + +/* For Debug: Dont allow MCU sleeping between channel checks */ +//#undef RDC_CONF_MCU_SLEEP +//#define RDC_CONF_MCU_SLEEP 0 + +/* Disabling RDC for demo purposes. Core updates often require more memory. */ +/* For projects, optimize memory and enable RDC again. */ +// #undef NETSTACK_CONF_RDC +//#define NETSTACK_CONF_RDC nullrdc_driver + +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 64 + +/* Estimate your header size, especially when using Proxy-Uri. */ +/* +#undef COAP_MAX_HEADER_SIZE +#define COAP_MAX_HEADER_SIZE 70 +*/ + +/* The IP buffer size must fit all other hops, in particular the border router. */ + +#undef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 256 + + +/* Multiplies with chunk size, be aware of memory constraints. */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* +#undef COAP_MAX_OBSERVERS +#define COAP_MAX_OBSERVERS 2 +*/ + +/* Filtering .well-known/core per query can be disabled to save space. */ +/* +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +*/ + +/* Save some memory for the sky platform. */ +/* +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 10 +*/ + +/* Reduce 802.15.4 frame queue to save RAM. */ +/* +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 +*/ + +/* +#undef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +*/ + +#endif /* PROJECT_RPL_WEB_CONF_H_ */ diff --git a/examples/osd/arduino-bh1750/resources/res-bh1750.c b/examples/osd/arduino-bh1750/resources/res-bh1750.c new file mode 100644 index 000000000..ae47f07a5 --- /dev/null +++ b/examples/osd/arduino-bh1750/resources/res-bh1750.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Moisture resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_bh1750, + "title=\"Lux status\";rt=\"Lux\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern uint16_t lux; + + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", lux); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'lux':%d}", lux); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-bh1750/run.sh b/examples/osd/arduino-bh1750/run.sh new file mode 100755 index 000000000..5d5cbbbb4 --- /dev/null +++ b/examples/osd/arduino-bh1750/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/arduino-bh1750/sketch.pde b/examples/osd/arduino-bh1750/sketch.pde new file mode 100644 index 000000000..775b96bce --- /dev/null +++ b/examples/osd/arduino-bh1750/sketch.pde @@ -0,0 +1,50 @@ +/* + * Sample arduino sketch using contiki features. + * We turn the LED off + * We allow read the moisture sensor + * Unfortunately sleeping for long times in loop() isn't currently + * possible, something turns off the CPU (including PWM outputs) if a + * Proto-Thread is taking too long. We need to find out how to sleep in + * a Contiki-compatible way. + * Note that for a normal arduino sketch you won't have to include any + * of the contiki-specific files here, the sketch should just work. + */ + +#include +#include "BH1750FVI.h" + +extern "C" { +#include "arduino-process.h" +#include "rest-engine.h" + +BH1750FVI lightMeter; + +extern resource_t res_bh1750, res_battery; +uint16_t lux; + +#define LED_PIN 4 +} + +void setup (void) +{ + // switch off the led + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, HIGH); + // BH1750 sensor + Wire.begin(); + lightMeter.begin(); + // init coap resourcen + rest_init_engine (); + rest_activate_resource (&res_bh1750, "s/lux"); + rest_activate_resource (&res_battery, "s/battery"); +} + +// at project-conf.h +// LOOP_INTERVAL (10 * CLOCK_SECOND) +void loop (void) +{ + mcu_sleep_off(); + lux = lightMeter.getLightLevel(); + printf("Lux: %d\n",lux); + mcu_sleep_on(); +} diff --git a/examples/osd/arduino-bmp085/Barometer.cpp b/examples/osd/arduino-bmp085/Barometer.cpp new file mode 100644 index 000000000..ec8b294a8 --- /dev/null +++ b/examples/osd/arduino-bmp085/Barometer.cpp @@ -0,0 +1,175 @@ +/* + Barometer library V1.0 + 2010 Copyright (c) Seeed Technology Inc. All right reserved. + + Original Author: LG + + 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 +*/ +#include "Barometer.h" +#include +#include + +void Barometer::init(void) +{ + Wire.begin(); +// Serial.print("Temperaturet: "); + ac1 = bmp085ReadInt(0xAA); + ac2 = bmp085ReadInt(0xAC); + ac3 = bmp085ReadInt(0xAE); + ac4 = bmp085ReadInt(0xB0); + ac5 = bmp085ReadInt(0xB2); + ac6 = bmp085ReadInt(0xB4); + b1 = bmp085ReadInt(0xB6); + b2 = bmp085ReadInt(0xB8); + mb = bmp085ReadInt(0xBA); + mc = bmp085ReadInt(0xBC); + md = bmp085ReadInt(0xBE); +// Serial.print("Temperaturet2: "); +} +// Read 1 byte from the BMP085 at 'address' +// Return: the read byte; +char Barometer::bmp085Read(unsigned char address) +{ + //Wire.begin(); + //unsigned char data; + Wire.beginTransmission(BMP085_ADDRESS); + Wire.write(address); + Wire.endTransmission(); + + Wire.requestFrom(BMP085_ADDRESS, 1); + while(!Wire.available()); + return Wire.read(); +} +// Read 2 bytes from the BMP085 +// First byte will be from 'address' +// Second byte will be from 'address'+1 +int Barometer::bmp085ReadInt(unsigned char address) +{ + unsigned char msb, lsb; + Wire.beginTransmission(BMP085_ADDRESS); + Wire.write(address); + Wire.endTransmission(); + Wire.requestFrom(BMP085_ADDRESS, 2); + while(Wire.available()<2); + msb = Wire.read(); + lsb = Wire.read(); + return (int) msb<<8 | lsb; +} +// Read the uncompensated temperature value +unsigned int Barometer::bmp085ReadUT() +{ + unsigned int ut; + Wire.beginTransmission(BMP085_ADDRESS); + Wire.write(0xF4); + Wire.write(0x2E); + Wire.endTransmission(); + delay(5); + ut = bmp085ReadInt(0xF6); + return ut; +} +// Read the uncompensated pressure value +unsigned long Barometer::bmp085ReadUP() +{ + unsigned char msb, lsb, xlsb; + unsigned long up = 0; + Wire.beginTransmission(BMP085_ADDRESS); + Wire.write(0xF4); + Wire.write(0x34 + (OSS<<6)); + Wire.endTransmission(); + delay(2 + (3<> (8-OSS); + return up; +} +void Barometer::writeRegister(int deviceAddress, byte address, byte val) +{ + Wire.beginTransmission(deviceAddress); // start transmission to device + Wire.write(address); // send register address + Wire.write(val); // send value to write + Wire.endTransmission(); // end transmission +} +int Barometer::readRegister(int deviceAddress, byte address) +{ + int v; + Wire.beginTransmission(deviceAddress); + Wire.write(address); // register to read + Wire.endTransmission(); + + Wire.requestFrom(deviceAddress, 1); // read a byte + + while(!Wire.available()) { + // waiting + } + + v = Wire.read(); + return v; +} +float Barometer::calcAltitude(float pressure) +{ + float A = pressure/101325; + float B = 1/5.25588; + float C = pow(A,B); + C = 1 - C; + C = C /0.0000225577; + return C; +} +float Barometer::bmp085GetTemperature(unsigned int ut) +{ + long x1, x2; + + x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15; + x2 = ((long)mc << 11)/(x1 + md); + PressureCompensate = x1 + x2; + + float temp = ((PressureCompensate + 8)>>4); + temp = temp /10; + + return temp; +} +long Barometer::bmp085GetPressure(unsigned long up) +{ + long x1, x2, x3, b3, b6, p; + unsigned long b4, b7; + b6 = PressureCompensate - 4000; + x1 = (b2 * (b6 * b6)>>12)>>11; + x2 = (ac2 * b6)>>11; + x3 = x1 + x2; + b3 = (((((long)ac1)*4 + x3)<>2; + + // Calculate B4 + x1 = (ac3 * b6)>>13; + x2 = (b1 * ((b6 * b6)>>12))>>16; + x3 = ((x1 + x2) + 2)>>2; + b4 = (ac4 * (unsigned long)(x3 + 32768))>>15; + + b7 = ((unsigned long)(up - b3) * (50000>>OSS)); + if (b7 < 0x80000000) + p = (b7<<1)/b4; + else + p = (b7/b4)<<1; + + x1 = (p>>8) * (p>>8); + x1 = (x1 * 3038)>>16; + x2 = (-7357 * p)>>16; + p += (x1 + x2 + 3791)>>4; + + long temp = p; + return temp; +} diff --git a/examples/osd/arduino-bmp085/Barometer.h b/examples/osd/arduino-bmp085/Barometer.h new file mode 100644 index 000000000..161702718 --- /dev/null +++ b/examples/osd/arduino-bmp085/Barometer.h @@ -0,0 +1,58 @@ +/* + Barometer library V1.0 + 2010 Copyright (c) Seeed Technology Inc. All right reserved. + + Original Author: LG + + 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 __BAROMETER_H__ +#define __BAROMETER_H__ + +#include +#include + +const unsigned char OSS = 0; +#define BMP085_ADDRESS 0x77 +class Barometer +{ +public: + void init(void); + long PressureCompensate; + float bmp085GetTemperature(unsigned int ut); + long bmp085GetPressure(unsigned long up); + float calcAltitude(float pressure); + unsigned int bmp085ReadUT(void); + unsigned long bmp085ReadUP(void); + +private: + int ac1; + int ac2; + int ac3; + unsigned int ac4; + unsigned int ac5; + unsigned int ac6; + int b1; + int b2; + int mb; + int mc; + int md; + char bmp085Read(unsigned char address); + int bmp085ReadInt(unsigned char address); + void writeRegister(int deviceAddress, byte address, byte val); + int readRegister(int deviceAddress, byte address); +}; + +#endif diff --git a/examples/osd/arduino-bmp085/Barometer_Sensor/Barometer.cpp b/examples/osd/arduino-bmp085/Barometer_Sensor/Barometer.cpp new file mode 100644 index 000000000..208f8b5a5 --- /dev/null +++ b/examples/osd/arduino-bmp085/Barometer_Sensor/Barometer.cpp @@ -0,0 +1,175 @@ +/* + Barometer library V1.0 + 2010 Copyright (c) Seeed Technology Inc. All right reserved. + + Original Author: LG + + 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 +*/ +#include "Barometer.h" +#include +#include + +void Barometer::init(void) +{ + Wire.begin(); + Serial.print("Temperaturet: "); + ac1 = bmp085ReadInt(0xAA); + ac2 = bmp085ReadInt(0xAC); + ac3 = bmp085ReadInt(0xAE); + ac4 = bmp085ReadInt(0xB0); + ac5 = bmp085ReadInt(0xB2); + ac6 = bmp085ReadInt(0xB4); + b1 = bmp085ReadInt(0xB6); + b2 = bmp085ReadInt(0xB8); + mb = bmp085ReadInt(0xBA); + mc = bmp085ReadInt(0xBC); + md = bmp085ReadInt(0xBE); + Serial.print("Temperaturet2: "); +} +// Read 1 byte from the BMP085 at 'address' +// Return: the read byte; +char Barometer::bmp085Read(unsigned char address) +{ + //Wire.begin(); + unsigned char data; + Wire.beginTransmission(BMP085_ADDRESS); + Wire.write(address); + Wire.endTransmission(); + + Wire.requestFrom(BMP085_ADDRESS, 1); + while(!Wire.available()); + return Wire.read(); +} +// Read 2 bytes from the BMP085 +// First byte will be from 'address' +// Second byte will be from 'address'+1 +int Barometer::bmp085ReadInt(unsigned char address) +{ + unsigned char msb, lsb; + Wire.beginTransmission(BMP085_ADDRESS); + Wire.write(address); + Wire.endTransmission(); + Wire.requestFrom(BMP085_ADDRESS, 2); + while(Wire.available()<2); + msb = Wire.read(); + lsb = Wire.read(); + return (int) msb<<8 | lsb; +} +// Read the uncompensated temperature value +unsigned int Barometer::bmp085ReadUT() +{ + unsigned int ut; + Wire.beginTransmission(BMP085_ADDRESS); + Wire.write(0xF4); + Wire.write(0x2E); + Wire.endTransmission(); + delay(5); + ut = bmp085ReadInt(0xF6); + return ut; +} +// Read the uncompensated pressure value +unsigned long Barometer::bmp085ReadUP() +{ + unsigned char msb, lsb, xlsb; + unsigned long up = 0; + Wire.beginTransmission(BMP085_ADDRESS); + Wire.write(0xF4); + Wire.write(0x34 + (OSS<<6)); + Wire.endTransmission(); + delay(2 + (3<> (8-OSS); + return up; +} +void Barometer::writeRegister(int deviceAddress, byte address, byte val) +{ + Wire.beginTransmission(deviceAddress); // start transmission to device + Wire.write(address); // send register address + Wire.write(val); // send value to write + Wire.endTransmission(); // end transmission +} +int Barometer::readRegister(int deviceAddress, byte address) +{ + int v; + Wire.beginTransmission(deviceAddress); + Wire.write(address); // register to read + Wire.endTransmission(); + + Wire.requestFrom(deviceAddress, 1); // read a byte + + while(!Wire.available()) { + // waiting + } + + v = Wire.read(); + return v; +} +float Barometer::calcAltitude(float pressure) +{ + float A = pressure/101325; + float B = 1/5.25588; + float C = pow(A,B); + C = 1 - C; + C = C /0.0000225577; + return C; +} +float Barometer::bmp085GetTemperature(unsigned int ut) +{ + long x1, x2; + + x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15; + x2 = ((long)mc << 11)/(x1 + md); + PressureCompensate = x1 + x2; + + float temp = ((PressureCompensate + 8)>>4); + temp = temp /10; + + return temp; +} +long Barometer::bmp085GetPressure(unsigned long up) +{ + long x1, x2, x3, b3, b6, p; + unsigned long b4, b7; + b6 = PressureCompensate - 4000; + x1 = (b2 * (b6 * b6)>>12)>>11; + x2 = (ac2 * b6)>>11; + x3 = x1 + x2; + b3 = (((((long)ac1)*4 + x3)<>2; + + // Calculate B4 + x1 = (ac3 * b6)>>13; + x2 = (b1 * ((b6 * b6)>>12))>>16; + x3 = ((x1 + x2) + 2)>>2; + b4 = (ac4 * (unsigned long)(x3 + 32768))>>15; + + b7 = ((unsigned long)(up - b3) * (50000>>OSS)); + if (b7 < 0x80000000) + p = (b7<<1)/b4; + else + p = (b7/b4)<<1; + + x1 = (p>>8) * (p>>8); + x1 = (x1 * 3038)>>16; + x2 = (-7357 * p)>>16; + p += (x1 + x2 + 3791)>>4; + + long temp = p; + return temp; +} diff --git a/examples/osd/arduino-bmp085/Barometer_Sensor/Barometer.h b/examples/osd/arduino-bmp085/Barometer_Sensor/Barometer.h new file mode 100644 index 000000000..161702718 --- /dev/null +++ b/examples/osd/arduino-bmp085/Barometer_Sensor/Barometer.h @@ -0,0 +1,58 @@ +/* + Barometer library V1.0 + 2010 Copyright (c) Seeed Technology Inc. All right reserved. + + Original Author: LG + + 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 __BAROMETER_H__ +#define __BAROMETER_H__ + +#include +#include + +const unsigned char OSS = 0; +#define BMP085_ADDRESS 0x77 +class Barometer +{ +public: + void init(void); + long PressureCompensate; + float bmp085GetTemperature(unsigned int ut); + long bmp085GetPressure(unsigned long up); + float calcAltitude(float pressure); + unsigned int bmp085ReadUT(void); + unsigned long bmp085ReadUP(void); + +private: + int ac1; + int ac2; + int ac3; + unsigned int ac4; + unsigned int ac5; + unsigned int ac6; + int b1; + int b2; + int mb; + int mc; + int md; + char bmp085Read(unsigned char address); + int bmp085ReadInt(unsigned char address); + void writeRegister(int deviceAddress, byte address, byte val); + int readRegister(int deviceAddress, byte address); +}; + +#endif diff --git a/examples/osd/arduino-bmp085/Barometer_Sensor/examples/Barometer_Sensor/Barometer_Sensor.ino b/examples/osd/arduino-bmp085/Barometer_Sensor/examples/Barometer_Sensor/Barometer_Sensor.ino new file mode 100644 index 000000000..7fe3b3ec5 --- /dev/null +++ b/examples/osd/arduino-bmp085/Barometer_Sensor/examples/Barometer_Sensor/Barometer_Sensor.ino @@ -0,0 +1,49 @@ +/* Barometer demo V1.0 +* Based largely on code by Jim Lindblom +* Get pressure, altitude, and temperature from the BMP085. +* Serial.print it out at 9600 baud to serial monitor. +* +* By:http://www.seeedstudio.com +*/ +#include "Barometer.h" +#include +float temperature; +float pressure; +float atm; +float altitude; +Barometer myBarometer; +void setup(){ + Serial.begin(9600); + myBarometer.init(); + +} + +void loop() +{ + temperature = myBarometer.bmp085GetTemperature(myBarometer.bmp085ReadUT()); //Get the temperature, bmp085ReadUT MUST be called first + pressure = myBarometer.bmp085GetPressure(myBarometer.bmp085ReadUP());//Get the temperature + altitude = myBarometer.calcAltitude(pressure); //Uncompensated caculation - in Meters + atm = pressure / 101325; + + Serial.print("Temperature: "); + Serial.print(temperature, 2); //display 2 decimal places + Serial.println("deg C"); + + Serial.print("Pressure: "); + Serial.print(pressure, 0); //whole number only. + Serial.println(" Pa"); + + Serial.print("Ralated Atmosphere: "); + Serial.println(atm, 4); //display 4 decimal places + + Serial.print("Altitude: "); + Serial.print(altitude, 2); //display 2 decimal places + Serial.println(" m"); + + Serial.println(); + + delay(1000); //wait a second and get values again. +} + + + diff --git a/examples/osd/arduino-bmp085/Makefile b/examples/osd/arduino-bmp085/Makefile new file mode 100644 index 000000000..b74569ff2 --- /dev/null +++ b/examples/osd/arduino-bmp085/Makefile @@ -0,0 +1,71 @@ +# Set this to the name of your sketch (without extension .pde) +SKETCH=sketch +EXE=arduino-example + +all: $(EXE) + +CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +LFLAGS += -lm + +PROJECT_SOURCEFILES += ${SKETCH}.cpp Barometer.cpp + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) + +# variable for Makefile.include +ifneq ($(TARGET), minimal-net) +CFLAGS += -DUIP_CONF_IPV6_RPL=1 +else +# minimal-net does not support RPL under Linux and is mostly used to test CoAP only +${info INFO: compiling without RPL} +CFLAGS += -DUIP_CONF_IPV6_RPL=0 +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=640 +endif + +# linker optimizations +SMALL=1 + + +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += arduino + +include $(CONTIKI)/Makefile.include +include $(CONTIKI)/apps/arduino/Makefile.include + +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + (cd $(CONTIKI)/tools && $(MAKE) tunslip6) + +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + +connect-minimal: + sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/arduino-bmp085/README.md b/examples/osd/arduino-bmp085/README.md new file mode 100644 index 000000000..e1490ed05 --- /dev/null +++ b/examples/osd/arduino-bmp085/README.md @@ -0,0 +1,11 @@ +Arduino compatibility example +============================= + +This example shows that it is now possible to re-use arduino sketches in +Contiki. This example documents the necessary magic. Arduino specifies +two routines, `setup` and `loop`. Before `setup` is called, the +framework initializes hardware. In original Arduino, all this is done in +a `main` function (in C). For contiki we define a process that does the +same. + +See the documentation file in apps/contiki-compat/README.md diff --git a/examples/osd/arduino-bmp085/arduino-example.c b/examples/osd/arduino-bmp085/arduino-example.c new file mode 100644 index 000000000..ea74dd8b8 --- /dev/null +++ b/examples/osd/arduino-bmp085/arduino-example.c @@ -0,0 +1,2 @@ +#include +AUTOSTART_PROCESSES(&arduino_sketch); diff --git a/examples/osd/arduino-bmp085/flash.sh b/examples/osd/arduino-bmp085/flash.sh new file mode 100755 index 000000000..e82962073 --- /dev/null +++ b/examples/osd/arduino-bmp085/flash.sh @@ -0,0 +1,2 @@ +#!/bin/bash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/arduino-bmp085/project-conf.h b/examples/osd/arduino-bmp085/project-conf.h new file mode 100644 index 000000000..e25aed53c --- /dev/null +++ b/examples/osd/arduino-bmp085/project-conf.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ + +#ifndef PROJECT_RPL_WEB_CONF_H_ +#define PROJECT_RPL_WEB_CONF_H_ + +#define PLATFORM_HAS_LEDS 1 +//#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_BATTERY 1 + +#define SICSLOWPAN_CONF_FRAG 1 + +#define LOOP_INTERVAL (10 * CLOCK_SECOND) + +/* Save energy */ +//#define RDC_CONF_PT_YIELD_OFF + +/* For Debug: Dont allow MCU sleeping between channel checks */ +//#undef RDC_CONF_MCU_SLEEP +//#define RDC_CONF_MCU_SLEEP 0 + +/* Disabling RDC for demo purposes. Core updates often require more memory. */ +/* For projects, optimize memory and enable RDC again. */ +// #undef NETSTACK_CONF_RDC +//#define NETSTACK_CONF_RDC nullrdc_driver + +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 64 + +/* Estimate your header size, especially when using Proxy-Uri. */ +/* +#undef COAP_MAX_HEADER_SIZE +#define COAP_MAX_HEADER_SIZE 70 +*/ + +/* The IP buffer size must fit all other hops, in particular the border router. */ + +#undef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 256 + + +/* Multiplies with chunk size, be aware of memory constraints. */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* +#undef COAP_MAX_OBSERVERS +#define COAP_MAX_OBSERVERS 2 +*/ + +/* Filtering .well-known/core per query can be disabled to save space. */ +/* +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +*/ + +/* Save some memory for the sky platform. */ +/* +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 10 +*/ + +/* Reduce 802.15.4 frame queue to save RAM. */ +/* +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 +*/ + +/* +#undef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +*/ + +#endif /* PROJECT_RPL_WEB_CONF_H_ */ diff --git a/examples/osd/arduino-bmp085/resources/res-bmp085alt.c b/examples/osd/arduino-bmp085/resources/res-bmp085alt.c new file mode 100644 index 000000000..de90eae4f --- /dev/null +++ b/examples/osd/arduino-bmp085/resources/res-bmp085alt.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Barometer resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_bmp085alt, + "title=\"alt status\";rt=\"alt\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern char bmp085alt_s[8]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", bmp085alt_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%s}", bmp085alt_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-bmp085/resources/res-bmp085atm.c b/examples/osd/arduino-bmp085/resources/res-bmp085atm.c new file mode 100644 index 000000000..b97cffe6e --- /dev/null +++ b/examples/osd/arduino-bmp085/resources/res-bmp085atm.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Barometer resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_bmp085atm, + "title=\"atm status\";rt=\"atm\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern char bmp085atm_s[8]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", bmp085atm_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%s}", bmp085atm_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-bmp085/resources/res-bmp085press.c b/examples/osd/arduino-bmp085/resources/res-bmp085press.c new file mode 100644 index 000000000..6a02f4bf0 --- /dev/null +++ b/examples/osd/arduino-bmp085/resources/res-bmp085press.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Barometer resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_bmp085press, + "title=\"pressure status\";rt=\"pressure\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern char bmp085press_s[8]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", bmp085press_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'pressure':%s}", bmp085press_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-bmp085/resources/res-bmp085temp.c b/examples/osd/arduino-bmp085/resources/res-bmp085temp.c new file mode 100644 index 000000000..f0e45f810 --- /dev/null +++ b/examples/osd/arduino-bmp085/resources/res-bmp085temp.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Barometer resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_bmp085temp, + "title=\"Temperature status\";rt=\"Temperatur\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern char bmp085temp_s[8]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", bmp085temp_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%s}", bmp085temp_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-bmp085/run.sh b/examples/osd/arduino-bmp085/run.sh new file mode 100755 index 000000000..5d5cbbbb4 --- /dev/null +++ b/examples/osd/arduino-bmp085/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/arduino-bmp085/sketch.pde b/examples/osd/arduino-bmp085/sketch.pde new file mode 100644 index 000000000..c84a488a9 --- /dev/null +++ b/examples/osd/arduino-bmp085/sketch.pde @@ -0,0 +1,86 @@ +/* + * Sample arduino sketch using contiki features. + * We turn the LED off + * We allow read the moisture sensor + * Unfortunately sleeping for long times in loop() isn't currently + * possible, something turns off the CPU (including PWM outputs) if a + * Proto-Thread is taking too long. We need to find out how to sleep in + * a Contiki-compatible way. + * Note that for a normal arduino sketch you won't have to include any + * of the contiki-specific files here, the sketch should just work. + */ + +#include +#include "Barometer.h" + +extern "C" { +#include "arduino-process.h" +#include "rest-engine.h" + +extern resource_t res_bmp085temp,res_bmp085press,res_bmp085atm,res_bmp085alt, res_battery; + +float bmp085temp; +float bmp085press; +float bmp085atm; +float bmp085alt; +char bmp085temp_s[8]; +char bmp085press_s[8]; +char bmp085atm_s[8]; +char bmp085alt_s[8]; + +Barometer myBarometer; + +#define LED_PIN 4 +} + +void setup (void) +{ + // switch off the led + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, HIGH); + // BMP085 sensor + myBarometer.init(); + // init coap resourcen + rest_init_engine (); + rest_activate_resource (&res_bmp085temp, "s/temp"); + rest_activate_resource (&res_bmp085press, "s/press"); + rest_activate_resource (&res_bmp085atm, "s/atm"); + rest_activate_resource (&res_bmp085alt, "s/alt"); + rest_activate_resource (&res_battery, "s/battery"); +} + +// at project-conf.h +// LOOP_INTERVAL (10 * CLOCK_SECOND) +void loop (void) +{ + mcu_sleep_off(); + bmp085temp = myBarometer.bmp085GetTemperature(myBarometer.bmp085ReadUT()); //Get the temperature, bmp085ReadUT MUST be called first + bmp085press = myBarometer.bmp085GetPressure(myBarometer.bmp085ReadUP());//Get the temperature + bmp085alt = myBarometer.calcAltitude(bmp085press); //Uncompensated caculation - in Meters + bmp085atm = bmp085press / 101325; + + dtostrf(bmp085temp , 6, 2, bmp085temp_s ); + dtostrf(bmp085press , 6, 2, bmp085press_s ); + dtostrf(bmp085alt , 6, 2, bmp085alt_s ); + dtostrf(bmp085atm , 6, 2, bmp085atm_s ); + // remove space + if(bmp085temp_s[0]==' '){ + memcpy (bmp085temp_s,bmp085temp_s+1,strlen(bmp085temp_s)+1); + } + if(bmp085press_s[0]==' '){ + memcpy (bmp085press_s,bmp085press_s+1,strlen(bmp085press_s)+1); + } + if(bmp085alt_s[0]==' '){ + memcpy (bmp085alt_s,bmp085alt_s+1,strlen(bmp085alt_s)+1); + } + if(bmp085atm_s[0]==' '){ + memcpy (bmp085atm_s,bmp085atm_s+1,strlen(bmp085atm_s)+1); + } + +// Debug Print + printf("Temp: %s",bmp085temp_s); + printf("\t\tPress: %s\n",bmp085press_s); + printf("\t\tAltitude: %s\n",bmp085alt_s); + printf("\t\tatm: %s\n",bmp085atm_s); + mcu_sleep_on(); +} diff --git a/examples/osd/arduino-climate3/Adafruit_HTU21DF.cpp b/examples/osd/arduino-climate3/Adafruit_HTU21DF.cpp new file mode 100644 index 000000000..84bbeb066 --- /dev/null +++ b/examples/osd/arduino-climate3/Adafruit_HTU21DF.cpp @@ -0,0 +1,100 @@ +/*************************************************** + This is a library for the HTU21DF Humidity & Temp Sensor + + Designed specifically to work with the HTU21DF sensor from Adafruit + ----> https://www.adafruit.com/products/1899 + + These displays use I2C to communicate, 2 pins are required to + interface + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ****************************************************/ + +#include "Adafruit_HTU21DF.h" +#if defined(__AVR__) +#include +#endif + +Adafruit_HTU21DF::Adafruit_HTU21DF() { +} + + +boolean Adafruit_HTU21DF::begin(void) { + Wire.begin(); + + reset(); + + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_READREG); + Wire.endTransmission(); + Wire.requestFrom(HTU21DF_I2CADDR, 1); + return (Wire.read() == 0x2); // after reset should be 0x2 +} + +void Adafruit_HTU21DF::reset(void) { + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_RESET); + Wire.endTransmission(); + delay(15); +} + + +float Adafruit_HTU21DF::readTemperature(void) { + + // OK lets ready! + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_READTEMP); + Wire.endTransmission(); + + delay(50); // add delay between request and actual read! + + Wire.requestFrom(HTU21DF_I2CADDR, 3); + while (!Wire.available()) {} + + uint16_t t = Wire.read(); + t <<= 8; + t |= Wire.read(); + + uint8_t crc = Wire.read(); + + float temp = t; + temp *= 175.72; + temp /= 65536; + temp -= 46.85; + + return temp; +} + + +float Adafruit_HTU21DF::readHumidity(void) { + // OK lets ready! + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_READHUM); + Wire.endTransmission(); + + delay(50); // add delay between request and actual read! + + Wire.requestFrom(HTU21DF_I2CADDR, 3); + while (!Wire.available()) {} + + uint16_t h = Wire.read(); + h <<= 8; + h |= Wire.read(); + + uint8_t crc = Wire.read(); + + float hum = h; + hum *= 125; + hum /= 65536; + hum -= 6; + + return hum; +} + + + +/*********************************************************************/ diff --git a/examples/osd/arduino-climate3/Adafruit_HTU21DF.h b/examples/osd/arduino-climate3/Adafruit_HTU21DF.h new file mode 100644 index 000000000..fe8870e39 --- /dev/null +++ b/examples/osd/arduino-climate3/Adafruit_HTU21DF.h @@ -0,0 +1,44 @@ +/*************************************************** + This is a library for the HTU21D-F Humidity & Temp Sensor + + Designed specifically to work with the HTU21D-F sensor from Adafruit + ----> https://www.adafruit.com/products/1899 + + These displays use I2C to communicate, 2 pins are required to + interface + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ****************************************************/ + +//#if (ARDUINO >= 100) + #include "Arduino.h" +//#else +// #include "WProgram.h" +//#endif +#include "Wire.h" + +#define HTU21DF_I2CADDR 0x40 +#define HTU21DF_READTEMP 0xE3 +#define HTU21DF_READHUM 0xE5 +#define HTU21DF_WRITEREG 0xE6 +#define HTU21DF_READREG 0xE7 +#define HTU21DF_RESET 0xFE + + + +class Adafruit_HTU21DF { + public: + Adafruit_HTU21DF(); + boolean begin(void); + float readTemperature(void); + float readHumidity(void); + void reset(void); + private: + boolean readData(void); + float humidity, temp; +}; + diff --git a/examples/osd/arduino-climate3/Adafruit_HTU21DF_Library-master/Adafruit_HTU21DF.cpp b/examples/osd/arduino-climate3/Adafruit_HTU21DF_Library-master/Adafruit_HTU21DF.cpp new file mode 100644 index 000000000..84bbeb066 --- /dev/null +++ b/examples/osd/arduino-climate3/Adafruit_HTU21DF_Library-master/Adafruit_HTU21DF.cpp @@ -0,0 +1,100 @@ +/*************************************************** + This is a library for the HTU21DF Humidity & Temp Sensor + + Designed specifically to work with the HTU21DF sensor from Adafruit + ----> https://www.adafruit.com/products/1899 + + These displays use I2C to communicate, 2 pins are required to + interface + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ****************************************************/ + +#include "Adafruit_HTU21DF.h" +#if defined(__AVR__) +#include +#endif + +Adafruit_HTU21DF::Adafruit_HTU21DF() { +} + + +boolean Adafruit_HTU21DF::begin(void) { + Wire.begin(); + + reset(); + + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_READREG); + Wire.endTransmission(); + Wire.requestFrom(HTU21DF_I2CADDR, 1); + return (Wire.read() == 0x2); // after reset should be 0x2 +} + +void Adafruit_HTU21DF::reset(void) { + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_RESET); + Wire.endTransmission(); + delay(15); +} + + +float Adafruit_HTU21DF::readTemperature(void) { + + // OK lets ready! + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_READTEMP); + Wire.endTransmission(); + + delay(50); // add delay between request and actual read! + + Wire.requestFrom(HTU21DF_I2CADDR, 3); + while (!Wire.available()) {} + + uint16_t t = Wire.read(); + t <<= 8; + t |= Wire.read(); + + uint8_t crc = Wire.read(); + + float temp = t; + temp *= 175.72; + temp /= 65536; + temp -= 46.85; + + return temp; +} + + +float Adafruit_HTU21DF::readHumidity(void) { + // OK lets ready! + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_READHUM); + Wire.endTransmission(); + + delay(50); // add delay between request and actual read! + + Wire.requestFrom(HTU21DF_I2CADDR, 3); + while (!Wire.available()) {} + + uint16_t h = Wire.read(); + h <<= 8; + h |= Wire.read(); + + uint8_t crc = Wire.read(); + + float hum = h; + hum *= 125; + hum /= 65536; + hum -= 6; + + return hum; +} + + + +/*********************************************************************/ diff --git a/examples/osd/arduino-climate3/Adafruit_HTU21DF_Library-master/Adafruit_HTU21DF.h b/examples/osd/arduino-climate3/Adafruit_HTU21DF_Library-master/Adafruit_HTU21DF.h new file mode 100644 index 000000000..b80698cb8 --- /dev/null +++ b/examples/osd/arduino-climate3/Adafruit_HTU21DF_Library-master/Adafruit_HTU21DF.h @@ -0,0 +1,44 @@ +/*************************************************** + This is a library for the HTU21D-F Humidity & Temp Sensor + + Designed specifically to work with the HTU21D-F sensor from Adafruit + ----> https://www.adafruit.com/products/1899 + + These displays use I2C to communicate, 2 pins are required to + interface + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ****************************************************/ + +#if (ARDUINO >= 100) + #include "Arduino.h" +#else + #include "WProgram.h" +#endif +#include "Wire.h" + +#define HTU21DF_I2CADDR 0x40 +#define HTU21DF_READTEMP 0xE3 +#define HTU21DF_READHUM 0xE5 +#define HTU21DF_WRITEREG 0xE6 +#define HTU21DF_READREG 0xE7 +#define HTU21DF_RESET 0xFE + + + +class Adafruit_HTU21DF { + public: + Adafruit_HTU21DF(); + boolean begin(void); + float readTemperature(void); + float readHumidity(void); + void reset(void); + private: + boolean readData(void); + float humidity, temp; +}; + diff --git a/examples/osd/arduino-climate3/Adafruit_HTU21DF_Library-master/README.txt b/examples/osd/arduino-climate3/Adafruit_HTU21DF_Library-master/README.txt new file mode 100644 index 000000000..5d41f6d26 --- /dev/null +++ b/examples/osd/arduino-climate3/Adafruit_HTU21DF_Library-master/README.txt @@ -0,0 +1,24 @@ +This is a library for the HTU21D-F Humidity + Temp sensor + +Designed specifically to work with the HTU21D-F in the Adafruit shop + ----> https://www.adafruit.com/products/1899 + +These displays use I2C to communicate, 2 pins are required to interface +Adafruit invests time and resources providing this open source code, +please support Adafruit and open-source hardware by purchasing +products from Adafruit! + +Written by Limor Fried/Ladyada for Adafruit Industries. +BSD license, all text above must be included in any redistribution + +Check out the links above for our tutorials and wiring diagrams + +To download. click the ZIP button in the top-middle navbar, +rename the uncompressed folder Adafruit_HTU21DF. +Check that the Adafruit_HTU21DF folder contains Adafruit_HTU21DF.cpp and Adafruit_HTU21DF.h + +Place the Adafruit_HTU21DF library folder your arduinosketchfolder/libraries/ folder. +You may need to create the libraries subfolder if its your first library. Restart the IDE. + +We also have a great tutorial on Arduino library installation at: +http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use \ No newline at end of file diff --git a/examples/osd/arduino-climate3/Adafruit_HTU21DF_Library-master/examples/HTU21DFtest/HTU21DFtest.ino b/examples/osd/arduino-climate3/Adafruit_HTU21DF_Library-master/examples/HTU21DFtest/HTU21DFtest.ino new file mode 100644 index 000000000..543a1fe5e --- /dev/null +++ b/examples/osd/arduino-climate3/Adafruit_HTU21DF_Library-master/examples/HTU21DFtest/HTU21DFtest.ino @@ -0,0 +1,36 @@ +/*************************************************** + This is an example for the HTU21D-F Humidity & Temp Sensor + + Designed specifically to work with the HTU21D-F sensor from Adafruit + ----> https://www.adafruit.com/products/1899 + + These displays use I2C to communicate, 2 pins are required to + interface + ****************************************************/ + +#include +#include "Adafruit_HTU21DF.h" + +// Connect Vin to 3-5VDC +// Connect GND to ground +// Connect SCL to I2C clock pin (A5 on UNO) +// Connect SDA to I2C data pin (A4 on UNO) + +Adafruit_HTU21DF htu = Adafruit_HTU21DF(); + +void setup() { + Serial.begin(9600); + Serial.println("HTU21D-F test"); + + if (!htu.begin()) { + Serial.println("Couldn't find sensor!"); + while (1); + } +} + + +void loop() { + Serial.print("Temp: "); Serial.print(htu.readTemperature()); + Serial.print("\t\tHum: "); Serial.println(htu.readHumidity()); + delay(500); +} \ No newline at end of file diff --git a/examples/osd/arduino-climate3/Adafruit_HTU21DF_Library-master/library.properties b/examples/osd/arduino-climate3/Adafruit_HTU21DF_Library-master/library.properties new file mode 100644 index 000000000..a8c8478ae --- /dev/null +++ b/examples/osd/arduino-climate3/Adafruit_HTU21DF_Library-master/library.properties @@ -0,0 +1,9 @@ +name=Adafruit HTU21DF Library +version=1.0.0 +author=Adafruit +maintainer=Adafruit +sentence=Arduino library for the HTU21D-F sensors in the Adafruit shop +paragraph=Arduino library for the HTU21D-F sensors in the Adafruit shop +category=Sensors +url=https://github.com/adafruit/Adafruit_HTU21DF_Library +architectures=* diff --git a/examples/osd/arduino-climate3/DallasTemperature.cpp b/examples/osd/arduino-climate3/DallasTemperature.cpp new file mode 100644 index 000000000..ea5b1e571 --- /dev/null +++ b/examples/osd/arduino-climate3/DallasTemperature.cpp @@ -0,0 +1,618 @@ +// 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. + +#include "DallasTemperature.h" + +extern "C" { + #include "Arduino.h" +} + +DallasTemperature::DallasTemperature(OneWire* _oneWire) + #if REQUIRESALARMS + : _AlarmHandler(&defaultAlarmHandler) + #endif +{ + _wire = _oneWire; + devices = 0; + parasite = false; + conversionDelay = TEMP_9_BIT; +} + +// initialize the bus +void DallasTemperature::begin(void) +{ + DeviceAddress deviceAddress; + + _wire->reset_search(); + devices = 0; // Reset the number of devices when we enumerate wire devices + + while (_wire->search(deviceAddress)) + { + if (validAddress(deviceAddress)) + { + if (!parasite && readPowerSupply(deviceAddress)) parasite = true; + + ScratchPad scratchPad; + + readScratchPad(deviceAddress, scratchPad); + + if (deviceAddress[0] == DS18S20MODEL) conversionDelay = TEMP_12_BIT; // 750 ms + else if (scratchPad[CONFIGURATION] > conversionDelay) conversionDelay = scratchPad[CONFIGURATION]; + + devices++; + } + } +} + +// returns the number of devices found on the bus +uint8_t DallasTemperature::getDeviceCount(void) +{ + return devices; +} + +// returns true if address is valid +bool DallasTemperature::validAddress(uint8_t* deviceAddress) +{ + return (_wire->crc8(deviceAddress, 7) == deviceAddress[7]); +} + +// finds an address at a given index on the bus +// returns true if the device was found +bool DallasTemperature::getAddress(uint8_t* deviceAddress, uint8_t index) +{ + uint8_t depth = 0; + + _wire->reset_search(); + + while (depth <= index && _wire->search(deviceAddress)) + { + if (depth == index && validAddress(deviceAddress)) return true; + depth++; + } + + return false; +} + +// attempt to determine if the device at the given address is connected to the bus +bool DallasTemperature::isConnected(uint8_t* deviceAddress) +{ + ScratchPad scratchPad; + return isConnected(deviceAddress, scratchPad); +} + +// attempt to determine if the device at the given address is connected to the bus +// also allows for updating the read scratchpad +bool DallasTemperature::isConnected(uint8_t* deviceAddress, uint8_t* scratchPad) +{ + readScratchPad(deviceAddress, scratchPad); + return (_wire->crc8(scratchPad, 8) == scratchPad[SCRATCHPAD_CRC]); +} + +// read device's scratch pad +void DallasTemperature::readScratchPad(uint8_t* deviceAddress, uint8_t* scratchPad) +{ + // send the command + _wire->reset(); + _wire->select(deviceAddress); + _wire->write(READSCRATCH); + + // read the response + + // byte 0: temperature LSB + scratchPad[TEMP_LSB] = _wire->read(); + + // byte 1: temperature MSB + scratchPad[TEMP_MSB] = _wire->read(); + + // byte 2: high alarm temp + scratchPad[HIGH_ALARM_TEMP] = _wire->read(); + + // byte 3: low alarm temp + scratchPad[LOW_ALARM_TEMP] = _wire->read(); + + // byte 4: + // DS18S20: store for crc + // DS18B20 & DS1822: configuration register + scratchPad[CONFIGURATION] = _wire->read(); + + // byte 5: + // internal use & crc + scratchPad[INTERNAL_BYTE] = _wire->read(); + + // byte 6: + // DS18S20: COUNT_REMAIN + // DS18B20 & DS1822: store for crc + scratchPad[COUNT_REMAIN] = _wire->read(); + + // byte 7: + // DS18S20: COUNT_PER_C + // DS18B20 & DS1822: store for crc + scratchPad[COUNT_PER_C] = _wire->read(); + + // byte 8: + // SCTRACHPAD_CRC + scratchPad[SCRATCHPAD_CRC] = _wire->read(); + + _wire->reset(); +} + +// writes device's scratch pad +void DallasTemperature::writeScratchPad(uint8_t* deviceAddress, const uint8_t* scratchPad) +{ + _wire->reset(); + _wire->select(deviceAddress); + _wire->write(WRITESCRATCH); + _wire->write(scratchPad[HIGH_ALARM_TEMP]); // high alarm temp + _wire->write(scratchPad[LOW_ALARM_TEMP]); // low alarm temp + // DS18S20 does not use the configuration register + if (deviceAddress[0] != DS18S20MODEL) _wire->write(scratchPad[CONFIGURATION]); // configuration + _wire->reset(); + // save the newly written values to eeprom + _wire->write(COPYSCRATCH, parasite); + if (parasite) delay(10); // 10ms delay + _wire->reset(); +} + +// reads the device's power requirements +bool DallasTemperature::readPowerSupply(uint8_t* deviceAddress) +{ + bool ret = false; + _wire->reset(); + _wire->select(deviceAddress); + _wire->write(READPOWERSUPPLY); + if (_wire->read_bit() == 0) ret = true; + _wire->reset(); + return ret; +} + +// returns the current resolution, 9-12 +uint8_t DallasTemperature::getResolution(uint8_t* deviceAddress) +{ + if (deviceAddress[0] == DS18S20MODEL) return 9; // this model has a fixed resolution + + ScratchPad scratchPad; + readScratchPad(deviceAddress, scratchPad); + switch (scratchPad[CONFIGURATION]) + { + case TEMP_12_BIT: + return 12; + break; + case TEMP_11_BIT: + return 11; + break; + case TEMP_10_BIT: + return 10; + break; + case TEMP_9_BIT: + return 9; + break; + } +} + +// set resolution of a device to 9, 10, 11, or 12 bits +void DallasTemperature::setResolution(uint8_t* deviceAddress, uint8_t newResolution) +{ + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) + { + // DS18S20 has a fixed 9-bit resolution + if (deviceAddress[0] != DS18S20MODEL) + { + switch (newResolution) + { + case 12: + scratchPad[CONFIGURATION] = TEMP_12_BIT; + break; + case 11: + scratchPad[CONFIGURATION] = TEMP_11_BIT; + break; + case 10: + scratchPad[CONFIGURATION] = TEMP_10_BIT; + break; + case 9: + default: + scratchPad[CONFIGURATION] = TEMP_9_BIT; + break; + } + writeScratchPad(deviceAddress, scratchPad); + } + } +} + +// sends command for all devices on the bus to perform a temperature +void DallasTemperature::requestTemperatures(void) +{ + _wire->reset(); + _wire->skip(); + _wire->write(STARTCONVO, parasite); + + switch (conversionDelay) + { + case TEMP_9_BIT: + delay(94); + break; + case TEMP_10_BIT: + delay(188); + break; + case TEMP_11_BIT: + delay(375); + break; + case TEMP_12_BIT: + default: + delay(750); + break; + } +} + +// sends command for one device to perform a temperature by address +void DallasTemperature::requestTemperaturesByAddress(uint8_t* deviceAddress) +{ + _wire->reset(); + _wire->select(deviceAddress); + _wire->write(STARTCONVO, parasite); + + switch (conversionDelay) + { + case TEMP_9_BIT: + delay(94); + break; + case TEMP_10_BIT: + delay(188); + break; + case TEMP_11_BIT: + delay(375); + break; + case TEMP_12_BIT: + default: + delay(750); + break; + } +} + +// sends command for one device to perform a temp conversion by index +void DallasTemperature::requestTemperaturesByIndex(uint8_t deviceIndex) +{ + DeviceAddress deviceAddress; + getAddress(deviceAddress, deviceIndex); + requestTemperaturesByAddress(deviceAddress); +} + + +// Fetch temperature for device index +float DallasTemperature::getTempCByIndex(uint8_t deviceIndex) +{ + DeviceAddress deviceAddress; + getAddress(deviceAddress, deviceIndex); + return getTempC((uint8_t*)deviceAddress); +} + +// Fetch temperature for device index +float DallasTemperature::getTempFByIndex(uint8_t deviceIndex) +{ + return DallasTemperature::toFahrenheit(getTempCByIndex(deviceIndex)); +} + +// reads scratchpad and returns the temperature in degrees C +float DallasTemperature::calculateTemperature(uint8_t* deviceAddress, uint8_t* scratchPad) +{ + int16_t rawTemperature = (((int16_t)scratchPad[TEMP_MSB]) << 8) | scratchPad[TEMP_LSB]; + + switch (deviceAddress[0]) + { + case DS18B20MODEL: + case DS1822MODEL: + switch (scratchPad[CONFIGURATION]) + { + case TEMP_12_BIT: + return (float)rawTemperature * 0.0625; + break; + case TEMP_11_BIT: + return (float)(rawTemperature >> 1) * 0.125; + break; + case TEMP_10_BIT: + return (float)(rawTemperature >> 2) * 0.25; + break; + case TEMP_9_BIT: + return (float)(rawTemperature >> 3) * 0.5; + break; + } + break; + case DS18S20MODEL: + /* + + Resolutions greater than 9 bits can be calculated using the data from + the temperature, COUNT REMAIN and COUNT PER C registers in the + scratchpad. Note that the COUNT PER C register is hard-wired to 16 + (10h). After reading the scratchpad, the TEMP_READ value is obtained + by truncating the 0.5C bit (bit 0) from the temperature data. The + extended resolution temperature can then be calculated using the + following equation: + + COUNT_PER_C - COUNT_REMAIN + TEMPERATURE = TEMP_READ - 0.25 + -------------------------- + COUNT_PER_C + */ + + // Good spot. Thanks Nic Johns for your contribution + return (float)(rawTemperature >> 1) - 0.25 +((float)(scratchPad[COUNT_PER_C] - scratchPad[COUNT_REMAIN]) / (float)scratchPad[COUNT_PER_C] ); + break; + } +} + +// returns temperature in degrees C or DEVICE_DISCONNECTED if the +// device's scratch pad cannot be read successfully. +// the numeric value of DEVICE_DISCONNECTED is defined in +// DallasTemperature.h. it is a large negative number outside the +// operating range of the device +float DallasTemperature::getTempC(uint8_t* deviceAddress) +{ + // TODO: Multiple devices (up to 64) on the same bus may take some time to negotiate a response + // What happens in case of collision? + + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) return calculateTemperature(deviceAddress, scratchPad); + return DEVICE_DISCONNECTED; +} + +// returns temperature in degrees F +float DallasTemperature::getTempF(uint8_t* deviceAddress) +{ + return toFahrenheit(getTempC(deviceAddress)); +} + +// returns true if the bus requires parasite power +bool DallasTemperature::isParasitePowerMode(void) +{ + return parasite; +} + +#if REQUIRESALARMS + +/* + +ALARMS: + +TH and TL Register Format + +BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 + S 2^6 2^5 2^4 2^3 2^2 2^1 2^0 + +Only bits 11 through 4 of the temperature register are used +in the TH and TL comparison since TH and TL are 8-bit +registers. If the measured temperature is lower than or equal +to TL or higher than or equal to TH, an alarm condition exists +and an alarm flag is set inside the DS18B20. This flag is +updated after every temperature measurement; therefore, if the +alarm condition goes away, the flag will be turned off after +the next temperature conversion. + +*/ + +// sets the high alarm temperature for a device in degrees celsius +// accepts a float, but the alarm resolution will ignore anything +// after a decimal point. valid range is -55C - 125C +void DallasTemperature::setHighAlarmTemp(uint8_t* deviceAddress, char celsius) +{ + // make sure the alarm temperature is within the device's range + if (celsius > 125) celsius = 125; + else if (celsius < -55) celsius = -55; + + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) + { + scratchPad[HIGH_ALARM_TEMP] = (uint8_t)celsius; + writeScratchPad(deviceAddress, scratchPad); + } +} + +// sets the low alarm temperature for a device in degreed celsius +// accepts a float, but the alarm resolution will ignore anything +// after a decimal point. valid range is -55C - 125C +void DallasTemperature::setLowAlarmTemp(uint8_t* deviceAddress, char celsius) +{ + // make sure the alarm temperature is within the device's range + if (celsius > 125) celsius = 125; + else if (celsius < -55) celsius = -55; + + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) + { + scratchPad[LOW_ALARM_TEMP] = (uint8_t)celsius; + writeScratchPad(deviceAddress, scratchPad); + } +} + +// returns a char with the current high alarm temperature or +// DEVICE_DISCONNECTED for an address +char DallasTemperature::getHighAlarmTemp(uint8_t* deviceAddress) +{ + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) return (char)scratchPad[HIGH_ALARM_TEMP]; + return DEVICE_DISCONNECTED; +} + +// returns a char with the current low alarm temperature or +// DEVICE_DISCONNECTED for an address +char DallasTemperature::getLowAlarmTemp(uint8_t* deviceAddress) +{ + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) return (char)scratchPad[LOW_ALARM_TEMP]; + return DEVICE_DISCONNECTED; +} + +// resets internal variables used for the alarm search +void DallasTemperature::resetAlarmSearch() +{ + alarmSearchJunction = -1; + alarmSearchExhausted = 0; + for(uint8_t i = 0; i < 7; i++) + alarmSearchAddress[i] = 0; +} + +// This is a modified version of the OneWire::search method. +// +// Also added the OneWire search fix documented here: +// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295 +// +// Perform an alarm search. If this function returns a '1' then it has +// enumerated the next device and you may retrieve the ROM from the +// OneWire::address variable. If there are no devices, no further +// devices, or something horrible happens in the middle of the +// enumeration then a 0 is returned. If a new device is found then +// its address is copied to newAddr. Use +// DallasTemperature::resetAlarmSearch() to start over. +bool DallasTemperature::alarmSearch(uint8_t* newAddr) +{ + uint8_t i; + char lastJunction = -1; + uint8_t done = 1; + + if (alarmSearchExhausted) return false; + if (!_wire->reset()) return false; + + // send the alarm search command + _wire->write(0xEC, 0); + + for(i = 0; i < 64; i++) + { + uint8_t a = _wire->read_bit( ); + uint8_t nota = _wire->read_bit( ); + uint8_t ibyte = i / 8; + uint8_t ibit = 1 << (i & 7); + + // I don't think this should happen, this means nothing responded, but maybe if + // something vanishes during the search it will come up. + if (a && nota) return false; + + if (!a && !nota) + { + if (i == alarmSearchJunction) + { + // this is our time to decide differently, we went zero last time, go one. + a = 1; + alarmSearchJunction = lastJunction; + } + else if (i < alarmSearchJunction) + { + // take whatever we took last time, look in address + if (alarmSearchAddress[ibyte] & ibit) a = 1; + else + { + // Only 0s count as pending junctions, we've already exhasuted the 0 side of 1s + a = 0; + done = 0; + lastJunction = i; + } + } + else + { + // we are blazing new tree, take the 0 + a = 0; + alarmSearchJunction = i; + done = 0; + } + // OneWire search fix + // See: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295 + } + + if (a) alarmSearchAddress[ibyte] |= ibit; + else alarmSearchAddress[ibyte] &= ~ibit; + + _wire->write_bit(a); + } + + if (done) alarmSearchExhausted = 1; + for (i = 0; i < 8; i++) newAddr[i] = alarmSearchAddress[i]; + return true; +} + +// returns true if device address has an alarm condition +bool DallasTemperature::hasAlarm(uint8_t* deviceAddress) +{ + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) + { + float temp = calculateTemperature(deviceAddress, scratchPad); + + // check low alarm + if ((char)temp <= (char)scratchPad[LOW_ALARM_TEMP]) return true; + + // check high alarm + if ((char)temp >= (char)scratchPad[HIGH_ALARM_TEMP]) return true; + } + + // no alarm + return false; +} + +// returns true if any device is reporting an alarm condition on the bus +bool DallasTemperature::hasAlarm(void) +{ + DeviceAddress deviceAddress; + resetAlarmSearch(); + return alarmSearch(deviceAddress); +} + +// runs the alarm handler for all devices returned by alarmSearch() +void DallasTemperature::processAlarms(void) +{ + resetAlarmSearch(); + DeviceAddress alarmAddr; + + while (alarmSearch(alarmAddr)) + { + if (validAddress(alarmAddr)) + _AlarmHandler(alarmAddr); + } +} + +// sets the alarm handler +void DallasTemperature::setAlarmHandler(AlarmHandler *handler) +{ + _AlarmHandler = handler; +} + +// The default alarm handler +void DallasTemperature::defaultAlarmHandler(uint8_t* deviceAddress) +{ +} + +#endif + +// Convert float celsius to fahrenheit +float DallasTemperature::toFahrenheit(float celsius) +{ + return (celsius * 1.8) + 32; +} + +// Convert float fahrenheit to celsius +float DallasTemperature::toCelsius(float fahrenheit) +{ + return (fahrenheit - 32) / 1.8; +} + +#if REQUIRESNEW + +// MnetCS - Allocates memory for DallasTemperature. Allows us to instance a new object +void* DallasTemperature::operator new(unsigned int size) // Implicit NSS obj size +{ + void * p; // void pointer + p = malloc(size); // Allocate memory + memset((DallasTemperature*)p,0,size); // Initalise memory + + //!!! CANT EXPLICITLY CALL CONSTRUCTOR - workaround by using an init() methodR - workaround by using an init() method + return (DallasTemperature*) p; // Cast blank region to NSS pointer +} + +// MnetCS 2009 - Unallocates the memory used by this instance +void DallasTemperature::operator delete(void* p) +{ + DallasTemperature* pNss = (DallasTemperature*) p; // Cast to NSS pointer + pNss->~DallasTemperature(); // Destruct the object + + free(p); // Free the memory +} + +#endif diff --git a/examples/osd/arduino-climate3/DallasTemperature.h b/examples/osd/arduino-climate3/DallasTemperature.h new file mode 100644 index 000000000..daf4ad1c2 --- /dev/null +++ b/examples/osd/arduino-climate3/DallasTemperature.h @@ -0,0 +1,213 @@ +#ifndef DallasTemperature_h +#define DallasTemperature_h + +// 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. + +// set to true to include code for new and delete operators +#ifndef REQUIRESNEW +#define REQUIRESNEW false +#endif + +// set to true to include code implementing alarm search functions +#ifndef REQUIRESALARMS +#define REQUIRESALARMS true +#endif + +#include +#include + +// Model IDs +#define DS18S20MODEL 0x10 +#define DS18B20MODEL 0x28 +#define DS1822MODEL 0x22 + +// OneWire commands +#define STARTCONVO 0x44 // Tells device to take a temperature reading and put it on the scratchpad +#define COPYSCRATCH 0x48 // Copy EEPROM +#define READSCRATCH 0xBE // Read EEPROM +#define WRITESCRATCH 0x4E // Write to EEPROM +#define RECALLSCRATCH 0xB8 // Reload from last known +#define READPOWERSUPPLY 0xB4 // Determine if device needs parasite power +#define ALARMSEARCH 0xEC // Query bus for devices with an alarm condition + +// Scratchpad locations +#define TEMP_LSB 0 +#define TEMP_MSB 1 +#define HIGH_ALARM_TEMP 2 +#define LOW_ALARM_TEMP 3 +#define CONFIGURATION 4 +#define INTERNAL_BYTE 5 +#define COUNT_REMAIN 6 +#define COUNT_PER_C 7 +#define SCRATCHPAD_CRC 8 + +// Device resolution +#define TEMP_9_BIT 0x1F // 9 bit +#define TEMP_10_BIT 0x3F // 10 bit +#define TEMP_11_BIT 0x5F // 11 bit +#define TEMP_12_BIT 0x7F // 12 bit + +// Error Codes +#define DEVICE_DISCONNECTED -127 + +typedef uint8_t DeviceAddress[8]; + +class DallasTemperature +{ + public: + + DallasTemperature(OneWire*); + + // initalize bus + void begin(void); + + // returns the number of devices found on the bus + uint8_t getDeviceCount(void); + + // returns true if address is valid + bool validAddress(uint8_t*); + + // finds an address at a given index on the bus + bool getAddress(uint8_t*, const uint8_t); + + // attempt to determine if the device at the given address is connected to the bus + bool isConnected(uint8_t*); + + // attempt to determine if the device at the given address is connected to the bus + // also allows for updating the read scratchpad + bool isConnected(uint8_t*, uint8_t*); + + // read device's scratchpad + void readScratchPad(uint8_t*, uint8_t*); + + // write device's scratchpad + void writeScratchPad(uint8_t*, const uint8_t*); + + // read device's power requirements + bool readPowerSupply(uint8_t*); + + // returns the current resolution, 9-12 + uint8_t getResolution(uint8_t*); + + // set resolution of a device to 9, 10, 11, or 12 bits + void setResolution(uint8_t*, uint8_t); + + // sends command for all devices on the bus to perform a temperature conversion + void requestTemperatures(void); + + // sends command for one device to perform a temperature conversion by address + void requestTemperaturesByAddress(uint8_t*); + + // sends command for one device to perform a temperature conversion by index + void requestTemperaturesByIndex(uint8_t); + + // returns temperature in degrees C + float getTempC(uint8_t*); + + // returns temperature in degrees F + float getTempF(uint8_t*); + + // Get temperature for device index (slow) + float getTempCByIndex(uint8_t); + + // Get temperature for device index (slow) + float getTempFByIndex(uint8_t); + + // returns true if the bus requires parasite power + bool isParasitePowerMode(void); + + #if REQUIRESALARMS + + typedef void AlarmHandler(uint8_t*); + + // sets the high alarm temperature for a device + // accepts a char. valid range is -55C - 125C + void setHighAlarmTemp(uint8_t*, const char); + + // sets the low alarm temperature for a device + // accepts a char. valid range is -55C - 125C + void setLowAlarmTemp(uint8_t*, const char); + + // returns a signed char with the current high alarm temperature for a device + // in the range -55C - 125C + char getHighAlarmTemp(uint8_t*); + + // returns a signed char with the current low alarm temperature for a device + // in the range -55C - 125C + char getLowAlarmTemp(uint8_t*); + + // resets internal variables used for the alarm search + void resetAlarmSearch(void); + + // search the wire for devices with active alarms + bool alarmSearch(uint8_t*); + + // returns true if ia specific device has an alarm + bool hasAlarm(uint8_t*); + + // returns true if any device is reporting an alarm on the bus + bool hasAlarm(void); + + // runs the alarm handler for all devices returned by alarmSearch() + void processAlarms(void); + + // sets the alarm handler + void setAlarmHandler(AlarmHandler *); + + // The default alarm handler + static void defaultAlarmHandler(uint8_t*); + + #endif + + // convert from celcius to farenheit + static float toFahrenheit(const float); + + // convert from farenheit to celsius + static float toCelsius(const float); + + #if REQUIRESNEW + + // initalize memory area + void* operator new (unsigned int); + + // delete memory reference + void operator delete(void*); + + #endif + + private: + typedef uint8_t ScratchPad[9]; + + // parasite power on or off + bool parasite; + + // used to determine the delay amount needed to allow for the + // temperature conversion to take place + int conversionDelay; + + // count of devices on the bus + uint8_t devices; + + // Take a pointer to one wire instance + OneWire* _wire; + + // reads scratchpad and returns the temperature in degrees C + float calculateTemperature(uint8_t*, uint8_t*); + + #if REQUIRESALARMS + + // required for alarmSearch + uint8_t alarmSearchAddress[8]; + char alarmSearchJunction; + uint8_t alarmSearchExhausted; + + // the alarm handler function pointer + AlarmHandler *_AlarmHandler; + + #endif + +}; +#endif diff --git a/examples/osd/arduino-climate3/Makefile b/examples/osd/arduino-climate3/Makefile new file mode 100644 index 000000000..540913919 --- /dev/null +++ b/examples/osd/arduino-climate3/Makefile @@ -0,0 +1,54 @@ +# Set this to the name of your sketch (without extension .pde) +SKETCH=sketch +EXE=arduino-example + +all: $(EXE) + +CONTIKI=../../.. + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +LFLAGS += -lm + +PROJECT_SOURCEFILES += ${SKETCH}.cpp Adafruit_HTU21DF.cpp OneWire.cpp DallasTemperature.cpp + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) + +# linker optimizations +SMALL=1 + +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += arduino + +CONTIKI_WITH_IPV6 = 1 +include $(CONTIKI)/Makefile.include +include $(CONTIKI)/apps/arduino/Makefile.include + +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + (cd $(CONTIKI)/tools && $(MAKE) tunslip6) + +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + +connect-minimal: + sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/arduino-climate3/OneWire.cpp b/examples/osd/arduino-climate3/OneWire.cpp new file mode 100644 index 000000000..6d55de0bf --- /dev/null +++ b/examples/osd/arduino-climate3/OneWire.cpp @@ -0,0 +1,563 @@ +/* +Copyright (c) 2007, Jim Studt (original old version - many contributors since) + +The latest version of this library may be found at: + http://www.pjrc.com/teensy/td_libs_OneWire.html + +OneWire has been maintained by Paul Stoffregen (paul@pjrc.com) since +January 2010. At the time, it was in need of many bug fixes, but had +been abandoned the original author (Jim Studt). None of the known +contributors were interested in maintaining OneWire. Paul typically +works on OneWire every 6 to 12 months. Patches usually wait that +long. If anyone is interested in more actively maintaining OneWire, +please contact Paul. + +Version 2.3: + Unknonw chip fallback mode, Roger Clark + Teensy-LC compatibility, Paul Stoffregen + Search bug fix, Love Nystrom + +Version 2.2: + Teensy 3.0 compatibility, Paul Stoffregen, paul@pjrc.com + Arduino Due compatibility, http://arduino.cc/forum/index.php?topic=141030 + Fix DS18B20 example negative temperature + Fix DS18B20 example's low res modes, Ken Butcher + Improve reset timing, Mark Tillotson + Add const qualifiers, Bertrik Sikken + Add initial value input to crc16, Bertrik Sikken + Add target_search() function, Scott Roberts + +Version 2.1: + Arduino 1.0 compatibility, Paul Stoffregen + Improve temperature example, Paul Stoffregen + DS250x_PROM example, Guillermo Lovato + PIC32 (chipKit) compatibility, Jason Dangel, dangel.jason AT gmail.com + Improvements from Glenn Trewitt: + - crc16() now works + - check_crc16() does all of calculation/checking work. + - Added read_bytes() and write_bytes(), to reduce tedious loops. + - Added ds2408 example. + Delete very old, out-of-date readme file (info is here) + +Version 2.0: Modifications by Paul Stoffregen, January 2010: +http://www.pjrc.com/teensy/td_libs_OneWire.html + Search fix from Robin James + http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27 + Use direct optimized I/O in all cases + Disable interrupts during timing critical sections + (this solves many random communication errors) + Disable interrupts during read-modify-write I/O + Reduce RAM consumption by eliminating unnecessary + variables and trimming many to 8 bits + Optimize both crc8 - table version moved to flash + +Modified to work with larger numbers of devices - avoids loop. +Tested in Arduino 11 alpha with 12 sensors. +26 Sept 2008 -- Robin James +http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27 + +Updated to work with arduino-0008 and to include skip() as of +2007/07/06. --RJL20 + +Modified to calculate the 8-bit CRC directly, avoiding the need for +the 256-byte lookup table to be loaded in RAM. Tested in arduino-0010 +-- Tom Pollard, Jan 23, 2008 + +Jim Studt's original library was modified by Josh Larios. + +Tom Pollard, pollard@alum.mit.edu, contributed around May 20, 2008 + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Much of the code was inspired by Derek Yerger's code, though I don't +think much of that remains. In any event that was.. + (copyleft) 2006 by Derek Yerger - Free to distribute freely. + +The CRC code was excerpted and inspired by the Dallas Semiconductor +sample code bearing this copyright. +//--------------------------------------------------------------------------- +// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES +// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// Except as contained in this notice, the name of Dallas Semiconductor +// shall not be used except as stated in the Dallas Semiconductor +// Branding Policy. +//-------------------------------------------------------------------------- +*/ + +#include "OneWire.h" + + +OneWire::OneWire(uint8_t pin) +{ + pinMode(pin, INPUT); + bitmask = PIN_TO_BITMASK(pin); + baseReg = PIN_TO_BASEREG(pin); +#if ONEWIRE_SEARCH + reset_search(); +#endif +} + + +// Perform the onewire reset function. We will wait up to 250uS for +// the bus to come high, if it doesn't then it is broken or shorted +// and we return a 0; +// +// Returns 1 if a device asserted a presence pulse, 0 otherwise. +// +uint8_t OneWire::reset(void) +{ + IO_REG_TYPE mask = bitmask; + volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg; + uint8_t r; + uint8_t retries = 125; + + noInterrupts(); + DIRECT_MODE_INPUT(reg, mask); + interrupts(); + // wait until the wire is high... just in case + do { + if (--retries == 0) return 0; + delayMicroseconds(2); + } while ( !DIRECT_READ(reg, mask)); + + noInterrupts(); + DIRECT_WRITE_LOW(reg, mask); + DIRECT_MODE_OUTPUT(reg, mask); // drive output low + interrupts(); + delayMicroseconds(480); + noInterrupts(); + DIRECT_MODE_INPUT(reg, mask); // allow it to float + delayMicroseconds(70); + r = !DIRECT_READ(reg, mask); + interrupts(); + delayMicroseconds(410); + return r; +} + +// +// Write a bit. Port and bit is used to cut lookup time and provide +// more certain timing. +// +void OneWire::write_bit(uint8_t v) +{ + IO_REG_TYPE mask=bitmask; + volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg; + + if (v & 1) { + noInterrupts(); + DIRECT_WRITE_LOW(reg, mask); + DIRECT_MODE_OUTPUT(reg, mask); // drive output low + delayMicroseconds(10); + DIRECT_WRITE_HIGH(reg, mask); // drive output high + interrupts(); + delayMicroseconds(55); + } else { + noInterrupts(); + DIRECT_WRITE_LOW(reg, mask); + DIRECT_MODE_OUTPUT(reg, mask); // drive output low + delayMicroseconds(65); + DIRECT_WRITE_HIGH(reg, mask); // drive output high + interrupts(); + delayMicroseconds(5); + } +} + +// +// Read a bit. Port and bit is used to cut lookup time and provide +// more certain timing. +// +uint8_t OneWire::read_bit(void) +{ + IO_REG_TYPE mask=bitmask; + volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg; + uint8_t r; + + noInterrupts(); + DIRECT_MODE_OUTPUT(reg, mask); + DIRECT_WRITE_LOW(reg, mask); + delayMicroseconds(3); + DIRECT_MODE_INPUT(reg, mask); // let pin float, pull up will raise + delayMicroseconds(10); + r = DIRECT_READ(reg, mask); + interrupts(); + delayMicroseconds(53); + return r; +} + +// +// Write a byte. The writing code uses the active drivers to raise the +// pin high, if you need power after the write (e.g. DS18S20 in +// parasite power mode) then set 'power' to 1, otherwise the pin will +// go tri-state at the end of the write to avoid heating in a short or +// other mishap. +// +void OneWire::write(uint8_t v, uint8_t power /* = 0 */) { + uint8_t bitMask; + + for (bitMask = 0x01; bitMask; bitMask <<= 1) { + OneWire::write_bit( (bitMask & v)?1:0); + } + if ( !power) { + noInterrupts(); + DIRECT_MODE_INPUT(baseReg, bitmask); + DIRECT_WRITE_LOW(baseReg, bitmask); + interrupts(); + } +} + +void OneWire::write_bytes(const uint8_t *buf, uint16_t count, bool power /* = 0 */) { + for (uint16_t i = 0 ; i < count ; i++) + write(buf[i]); + if (!power) { + noInterrupts(); + DIRECT_MODE_INPUT(baseReg, bitmask); + DIRECT_WRITE_LOW(baseReg, bitmask); + interrupts(); + } +} + +// +// Read a byte +// +uint8_t OneWire::read() { + uint8_t bitMask; + uint8_t r = 0; + + for (bitMask = 0x01; bitMask; bitMask <<= 1) { + if ( OneWire::read_bit()) r |= bitMask; + } + return r; +} + +void OneWire::read_bytes(uint8_t *buf, uint16_t count) { + for (uint16_t i = 0 ; i < count ; i++) + buf[i] = read(); +} + +// +// Do a ROM select +// +void OneWire::select(const uint8_t rom[8]) +{ + uint8_t i; + + write(0x55); // Choose ROM + + for (i = 0; i < 8; i++) write(rom[i]); +} + +// +// Do a ROM skip +// +void OneWire::skip() +{ + write(0xCC); // Skip ROM +} + +void OneWire::depower() +{ + noInterrupts(); + DIRECT_MODE_INPUT(baseReg, bitmask); + interrupts(); +} + +#if ONEWIRE_SEARCH + +// +// You need to use this function to start a search again from the beginning. +// You do not need to do it for the first search, though you could. +// +void OneWire::reset_search() +{ + // reset the search state + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + for(int i = 7; ; i--) { + ROM_NO[i] = 0; + if ( i == 0) break; + } +} + +// Setup the search to find the device type 'family_code' on the next call +// to search(*newAddr) if it is present. +// +void OneWire::target_search(uint8_t family_code) +{ + // set the search state to find SearchFamily type devices + ROM_NO[0] = family_code; + for (uint8_t i = 1; i < 8; i++) + ROM_NO[i] = 0; + LastDiscrepancy = 64; + LastFamilyDiscrepancy = 0; + LastDeviceFlag = FALSE; +} + +// +// Perform a search. If this function returns a '1' then it has +// enumerated the next device and you may retrieve the ROM from the +// OneWire::address variable. If there are no devices, no further +// devices, or something horrible happens in the middle of the +// enumeration then a 0 is returned. If a new device is found then +// its address is copied to newAddr. Use OneWire::reset_search() to +// start over. +// +// --- Replaced by the one from the Dallas Semiconductor web site --- +//-------------------------------------------------------------------------- +// Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing +// search state. +// Return TRUE : device found, ROM number in ROM_NO buffer +// FALSE : device not found, end of search +// +uint8_t OneWire::search(uint8_t *newAddr) +{ + uint8_t id_bit_number; + uint8_t last_zero, rom_byte_number, search_result; + uint8_t id_bit, cmp_id_bit; + + unsigned char rom_byte_mask, search_direction; + + // initialize for search + id_bit_number = 1; + last_zero = 0; + rom_byte_number = 0; + rom_byte_mask = 1; + search_result = 0; + + // if the last call was not the last one + if (!LastDeviceFlag) + { + // 1-Wire reset + if (!reset()) + { + // reset the search + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + return FALSE; + } + + // issue the search command + write(0xF0); + + // loop to do the search + do + { + // read a bit and its complement + id_bit = read_bit(); + cmp_id_bit = read_bit(); + + // check for no devices on 1-wire + if ((id_bit == 1) && (cmp_id_bit == 1)) + break; + else + { + // all devices coupled have 0 or 1 + if (id_bit != cmp_id_bit) + search_direction = id_bit; // bit write value for search + else + { + // if this discrepancy if before the Last Discrepancy + // on a previous next then pick the same as last time + if (id_bit_number < LastDiscrepancy) + search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0); + else + // if equal to last pick 1, if not then pick 0 + search_direction = (id_bit_number == LastDiscrepancy); + + // if 0 was picked then record its position in LastZero + if (search_direction == 0) + { + last_zero = id_bit_number; + + // check for Last discrepancy in family + if (last_zero < 9) + LastFamilyDiscrepancy = last_zero; + } + } + + // set or clear the bit in the ROM byte rom_byte_number + // with mask rom_byte_mask + if (search_direction == 1) + ROM_NO[rom_byte_number] |= rom_byte_mask; + else + ROM_NO[rom_byte_number] &= ~rom_byte_mask; + + // serial number search direction write bit + write_bit(search_direction); + + // increment the byte counter id_bit_number + // and shift the mask rom_byte_mask + id_bit_number++; + rom_byte_mask <<= 1; + + // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask + if (rom_byte_mask == 0) + { + rom_byte_number++; + rom_byte_mask = 1; + } + } + } + while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 + + // if the search was successful then + if (!(id_bit_number < 65)) + { + // search successful so set LastDiscrepancy,LastDeviceFlag,search_result + LastDiscrepancy = last_zero; + + // check for last device + if (LastDiscrepancy == 0) + LastDeviceFlag = TRUE; + + search_result = TRUE; + } + } + + // if no device found then reset counters so next 'search' will be like a first + if (!search_result || !ROM_NO[0]) + { + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + search_result = FALSE; + } else { + for (int i = 0; i < 8; i++) newAddr[i] = ROM_NO[i]; + } + return search_result; + } + +#endif + +#if ONEWIRE_CRC +// The 1-Wire CRC scheme is described in Maxim Application Note 27: +// "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products" +// + +#if ONEWIRE_CRC8_TABLE +// This table comes from Dallas sample code where it is freely reusable, +// though Copyright (C) 2000 Dallas Semiconductor Corporation +static const uint8_t PROGMEM dscrc_table[] = { + 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, + 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, + 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, + 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, + 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, + 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, + 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, + 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, + 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, + 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, + 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, + 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, + 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, + 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, + 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, + 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53}; + +// +// Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM +// and the registers. (note: this might better be done without to +// table, it would probably be smaller and certainly fast enough +// compared to all those delayMicrosecond() calls. But I got +// confused, so I use this table from the examples.) +// +uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len) +{ + uint8_t crc = 0; + + while (len--) { + crc = pgm_read_byte(dscrc_table + (crc ^ *addr++)); + } + return crc; +} +#else +// +// Compute a Dallas Semiconductor 8 bit CRC directly. +// this is much slower, but much smaller, than the lookup table. +// +uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len) +{ + uint8_t crc = 0; + + while (len--) { + uint8_t inbyte = *addr++; + for (uint8_t i = 8; i; i--) { + uint8_t mix = (crc ^ inbyte) & 0x01; + crc >>= 1; + if (mix) crc ^= 0x8C; + inbyte >>= 1; + } + } + return crc; +} +#endif + +#if ONEWIRE_CRC16 +bool OneWire::check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc) +{ + crc = ~crc16(input, len, crc); + return (crc & 0xFF) == inverted_crc[0] && (crc >> 8) == inverted_crc[1]; +} + +uint16_t OneWire::crc16(const uint8_t* input, uint16_t len, uint16_t crc) +{ + static const uint8_t oddparity[16] = + { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; + + for (uint16_t i = 0 ; i < len ; i++) { + // Even though we're just copying a byte from the input, + // we'll be doing 16-bit computation with it. + uint16_t cdata = input[i]; + cdata = (cdata ^ crc) & 0xff; + crc >>= 8; + + if (oddparity[cdata & 0x0F] ^ oddparity[cdata >> 4]) + crc ^= 0xC001; + + cdata <<= 6; + crc ^= cdata; + cdata <<= 1; + crc ^= cdata; + } + return crc; +} +#endif + +#endif diff --git a/examples/osd/arduino-climate3/OneWire.h b/examples/osd/arduino-climate3/OneWire.h new file mode 100644 index 000000000..3aac70636 --- /dev/null +++ b/examples/osd/arduino-climate3/OneWire.h @@ -0,0 +1,250 @@ +#ifndef OneWire_h +#define OneWire_h + +#include + +//#if ARDUINO >= 100 +#include "Arduino.h" // for delayMicroseconds, digitalPinToBitMask, etc +//#else +//#include "WProgram.h" // for delayMicroseconds +//#include "pins_arduino.h" // for digitalPinToBitMask, etc +//#endif + +// You can exclude certain features from OneWire. In theory, this +// might save some space. In practice, the compiler automatically +// removes unused code (technically, the linker, using -fdata-sections +// and -ffunction-sections when compiling, and Wl,--gc-sections +// when linking), so most of these will not result in any code size +// reduction. Well, unless you try to use the missing features +// and redesign your program to not need them! ONEWIRE_CRC8_TABLE +// is the exception, because it selects a fast but large algorithm +// or a small but slow algorithm. + +// you can exclude onewire_search by defining that to 0 +#ifndef ONEWIRE_SEARCH +#define ONEWIRE_SEARCH 1 +#endif + +// You can exclude CRC checks altogether by defining this to 0 +#ifndef ONEWIRE_CRC +#define ONEWIRE_CRC 1 +#endif + +// Select the table-lookup method of computing the 8-bit CRC +// by setting this to 1. The lookup table enlarges code size by +// about 250 bytes. It does NOT consume RAM (but did in very +// old versions of OneWire). If you disable this, a slower +// but very compact algorithm is used. +#ifndef ONEWIRE_CRC8_TABLE +#define ONEWIRE_CRC8_TABLE 1 +#endif + +// You can allow 16-bit CRC checks by defining this to 1 +// (Note that ONEWIRE_CRC must also be 1.) +#ifndef ONEWIRE_CRC16 +#define ONEWIRE_CRC16 1 +#endif + +#define FALSE 0 +#define TRUE 1 + +// Platform specific I/O definitions + +#if defined(__AVR__) +#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) +#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) +#define IO_REG_TYPE uint8_t +#define IO_REG_ASM asm("r30") +#define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) +#define DIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask)) +#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask)) +#define DIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask)) +#define DIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) + +#elif defined(__MK20DX128__) || defined(__MK20DX256__) +#define PIN_TO_BASEREG(pin) (portOutputRegister(pin)) +#define PIN_TO_BITMASK(pin) (1) +#define IO_REG_TYPE uint8_t +#define IO_REG_ASM +#define DIRECT_READ(base, mask) (*((base)+512)) +#define DIRECT_MODE_INPUT(base, mask) (*((base)+640) = 0) +#define DIRECT_MODE_OUTPUT(base, mask) (*((base)+640) = 1) +#define DIRECT_WRITE_LOW(base, mask) (*((base)+256) = 1) +#define DIRECT_WRITE_HIGH(base, mask) (*((base)+128) = 1) + +#elif defined(__MKL26Z64__) +#define PIN_TO_BASEREG(pin) (portOutputRegister(pin)) +#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) +#define IO_REG_TYPE uint8_t +#define IO_REG_ASM +#define DIRECT_READ(base, mask) ((*((base)+16) & (mask)) ? 1 : 0) +#define DIRECT_MODE_INPUT(base, mask) (*((base)+20) &= ~(mask)) +#define DIRECT_MODE_OUTPUT(base, mask) (*((base)+20) |= (mask)) +#define DIRECT_WRITE_LOW(base, mask) (*((base)+8) = (mask)) +#define DIRECT_WRITE_HIGH(base, mask) (*((base)+4) = (mask)) + +#elif defined(__SAM3X8E__) +// Arduino 1.5.1 may have a bug in delayMicroseconds() on Arduino Due. +// http://arduino.cc/forum/index.php/topic,141030.msg1076268.html#msg1076268 +// If you have trouble with OneWire on Arduino Due, please check the +// status of delayMicroseconds() before reporting a bug in OneWire! +#define PIN_TO_BASEREG(pin) (&(digitalPinToPort(pin)->PIO_PER)) +#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) +#define IO_REG_TYPE uint32_t +#define IO_REG_ASM +#define DIRECT_READ(base, mask) (((*((base)+15)) & (mask)) ? 1 : 0) +#define DIRECT_MODE_INPUT(base, mask) ((*((base)+5)) = (mask)) +#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+4)) = (mask)) +#define DIRECT_WRITE_LOW(base, mask) ((*((base)+13)) = (mask)) +#define DIRECT_WRITE_HIGH(base, mask) ((*((base)+12)) = (mask)) +#ifndef PROGMEM +#define PROGMEM +#endif +#ifndef pgm_read_byte +#define pgm_read_byte(addr) (*(const uint8_t *)(addr)) +#endif + +#elif defined(__PIC32MX__) +#define PIN_TO_BASEREG(pin) (portModeRegister(digitalPinToPort(pin))) +#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) +#define IO_REG_TYPE uint32_t +#define IO_REG_ASM +#define DIRECT_READ(base, mask) (((*(base+4)) & (mask)) ? 1 : 0) //PORTX + 0x10 +#define DIRECT_MODE_INPUT(base, mask) ((*(base+2)) = (mask)) //TRISXSET + 0x08 +#define DIRECT_MODE_OUTPUT(base, mask) ((*(base+1)) = (mask)) //TRISXCLR + 0x04 +#define DIRECT_WRITE_LOW(base, mask) ((*(base+8+1)) = (mask)) //LATXCLR + 0x24 +#define DIRECT_WRITE_HIGH(base, mask) ((*(base+8+2)) = (mask)) //LATXSET + 0x28 + +#else +#define PIN_TO_BASEREG(pin) (0) +#define PIN_TO_BITMASK(pin) (pin) +#define IO_REG_TYPE unsigned int +#define IO_REG_ASM +#define DIRECT_READ(base, pin) digitalRead(pin) +#define DIRECT_WRITE_LOW(base, pin) digitalWrite(pin, LOW) +#define DIRECT_WRITE_HIGH(base, pin) digitalWrite(pin, HIGH) +#define DIRECT_MODE_INPUT(base, pin) pinMode(pin,INPUT) +#define DIRECT_MODE_OUTPUT(base, pin) pinMode(pin,OUTPUT) +#warning "OneWire. Fallback mode. Using API calls for pinMode,digitalRead and digitalWrite. Operation of this library is not guaranteed on this architecture." + +#endif + + +class OneWire +{ + private: + IO_REG_TYPE bitmask; + volatile IO_REG_TYPE *baseReg; + +#if ONEWIRE_SEARCH + // global search state + unsigned char ROM_NO[8]; + uint8_t LastDiscrepancy; + uint8_t LastFamilyDiscrepancy; + uint8_t LastDeviceFlag; +#endif + + public: + OneWire( uint8_t pin); + + // Perform a 1-Wire reset cycle. Returns 1 if a device responds + // with a presence pulse. Returns 0 if there is no device or the + // bus is shorted or otherwise held low for more than 250uS + uint8_t reset(void); + + // Issue a 1-Wire rom select command, you do the reset first. + void select(const uint8_t rom[8]); + + // Issue a 1-Wire rom skip command, to address all on bus. + void skip(void); + + // Write a byte. If 'power' is one then the wire is held high at + // the end for parasitically powered devices. You are responsible + // for eventually depowering it by calling depower() or doing + // another read or write. + void write(uint8_t v, uint8_t power = 0); + + void write_bytes(const uint8_t *buf, uint16_t count, bool power = 0); + + // Read a byte. + uint8_t read(void); + + void read_bytes(uint8_t *buf, uint16_t count); + + // Write a bit. The bus is always left powered at the end, see + // note in write() about that. + void write_bit(uint8_t v); + + // Read a bit. + uint8_t read_bit(void); + + // Stop forcing power onto the bus. You only need to do this if + // you used the 'power' flag to write() or used a write_bit() call + // and aren't about to do another read or write. You would rather + // not leave this powered if you don't have to, just in case + // someone shorts your bus. + void depower(void); + +#if ONEWIRE_SEARCH + // Clear the search state so that if will start from the beginning again. + void reset_search(); + + // Setup the search to find the device type 'family_code' on the next call + // to search(*newAddr) if it is present. + void target_search(uint8_t family_code); + + // Look for the next device. Returns 1 if a new address has been + // returned. A zero might mean that the bus is shorted, there are + // no devices, or you have already retrieved all of them. It + // might be a good idea to check the CRC to make sure you didn't + // get garbage. The order is deterministic. You will always get + // the same devices in the same order. + uint8_t search(uint8_t *newAddr); +#endif + +#if ONEWIRE_CRC + // Compute a Dallas Semiconductor 8 bit CRC, these are used in the + // ROM and scratchpad registers. + static uint8_t crc8(const uint8_t *addr, uint8_t len); + +#if ONEWIRE_CRC16 + // Compute the 1-Wire CRC16 and compare it against the received CRC. + // Example usage (reading a DS2408): + // // Put everything in a buffer so we can compute the CRC easily. + // uint8_t buf[13]; + // buf[0] = 0xF0; // Read PIO Registers + // buf[1] = 0x88; // LSB address + // buf[2] = 0x00; // MSB address + // WriteBytes(net, buf, 3); // Write 3 cmd bytes + // ReadBytes(net, buf+3, 10); // Read 6 data bytes, 2 0xFF, 2 CRC16 + // if (!CheckCRC16(buf, 11, &buf[11])) { + // // Handle error. + // } + // + // @param input - Array of bytes to checksum. + // @param len - How many bytes to use. + // @param inverted_crc - The two CRC16 bytes in the received data. + // This should just point into the received data, + // *not* at a 16-bit integer. + // @param crc - The crc starting value (optional) + // @return True, iff the CRC matches. + static bool check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc = 0); + + // Compute a Dallas Semiconductor 16 bit CRC. This is required to check + // the integrity of data received from many 1-Wire devices. Note that the + // CRC computed here is *not* what you'll get from the 1-Wire network, + // for two reasons: + // 1) The CRC is transmitted bitwise inverted. + // 2) Depending on the endian-ness of your processor, the binary + // representation of the two-byte return value may have a different + // byte order than the two bytes you get from 1-Wire. + // @param input - Array of bytes to checksum. + // @param len - How many bytes to use. + // @param crc - The crc starting value (optional) + // @return The CRC16, as defined by Dallas Semiconductor. + static uint16_t crc16(const uint8_t* input, uint16_t len, uint16_t crc = 0); +#endif +#endif +}; + +#endif diff --git a/examples/osd/arduino-climate3/README.md b/examples/osd/arduino-climate3/README.md new file mode 100644 index 000000000..e1490ed05 --- /dev/null +++ b/examples/osd/arduino-climate3/README.md @@ -0,0 +1,11 @@ +Arduino compatibility example +============================= + +This example shows that it is now possible to re-use arduino sketches in +Contiki. This example documents the necessary magic. Arduino specifies +two routines, `setup` and `loop`. Before `setup` is called, the +framework initializes hardware. In original Arduino, all this is done in +a `main` function (in C). For contiki we define a process that does the +same. + +See the documentation file in apps/contiki-compat/README.md diff --git a/examples/osd/arduino-climate3/arduino-example.c b/examples/osd/arduino-climate3/arduino-example.c new file mode 100644 index 000000000..ea74dd8b8 --- /dev/null +++ b/examples/osd/arduino-climate3/arduino-example.c @@ -0,0 +1,2 @@ +#include +AUTOSTART_PROCESSES(&arduino_sketch); diff --git a/examples/osd/arduino-climate3/flash.sh b/examples/osd/arduino-climate3/flash.sh new file mode 100755 index 000000000..e82962073 --- /dev/null +++ b/examples/osd/arduino-climate3/flash.sh @@ -0,0 +1,2 @@ +#!/bin/bash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/arduino-climate3/project-conf.h b/examples/osd/arduino-climate3/project-conf.h new file mode 100644 index 000000000..e25aed53c --- /dev/null +++ b/examples/osd/arduino-climate3/project-conf.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ + +#ifndef PROJECT_RPL_WEB_CONF_H_ +#define PROJECT_RPL_WEB_CONF_H_ + +#define PLATFORM_HAS_LEDS 1 +//#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_BATTERY 1 + +#define SICSLOWPAN_CONF_FRAG 1 + +#define LOOP_INTERVAL (10 * CLOCK_SECOND) + +/* Save energy */ +//#define RDC_CONF_PT_YIELD_OFF + +/* For Debug: Dont allow MCU sleeping between channel checks */ +//#undef RDC_CONF_MCU_SLEEP +//#define RDC_CONF_MCU_SLEEP 0 + +/* Disabling RDC for demo purposes. Core updates often require more memory. */ +/* For projects, optimize memory and enable RDC again. */ +// #undef NETSTACK_CONF_RDC +//#define NETSTACK_CONF_RDC nullrdc_driver + +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 64 + +/* Estimate your header size, especially when using Proxy-Uri. */ +/* +#undef COAP_MAX_HEADER_SIZE +#define COAP_MAX_HEADER_SIZE 70 +*/ + +/* The IP buffer size must fit all other hops, in particular the border router. */ + +#undef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 256 + + +/* Multiplies with chunk size, be aware of memory constraints. */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* +#undef COAP_MAX_OBSERVERS +#define COAP_MAX_OBSERVERS 2 +*/ + +/* Filtering .well-known/core per query can be disabled to save space. */ +/* +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +*/ + +/* Save some memory for the sky platform. */ +/* +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 10 +*/ + +/* Reduce 802.15.4 frame queue to save RAM. */ +/* +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 +*/ + +/* +#undef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +*/ + +#endif /* PROJECT_RPL_WEB_CONF_H_ */ diff --git a/examples/osd/arduino-climate3/resources/res-dtemp1.c b/examples/osd/arduino-climate3/resources/res-dtemp1.c new file mode 100644 index 000000000..f19889774 --- /dev/null +++ b/examples/osd/arduino-climate3/resources/res-dtemp1.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Moisture resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" +#include "sketch.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_dtemp1, + "title=\"Temperature status\";rt=\"Temperature\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern char d_temp_s[8]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", d_temp_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%s}", d_temp_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-climate3/resources/res-htu21dhum.c b/examples/osd/arduino-climate3/resources/res-htu21dhum.c new file mode 100644 index 000000000..f66c71c74 --- /dev/null +++ b/examples/osd/arduino-climate3/resources/res-htu21dhum.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Moisture resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_htu21dhum, + "title=\"Moisture status\";rt=\"Moisture\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern char htu21d_hum_s[8]; + + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", htu21d_hum_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'moisture':%s}", htu21d_hum_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-climate3/resources/res-htu21dtemp.c b/examples/osd/arduino-climate3/resources/res-htu21dtemp.c new file mode 100644 index 000000000..cdc9a9a7d --- /dev/null +++ b/examples/osd/arduino-climate3/resources/res-htu21dtemp.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Moisture resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_htu21dtemp, + "title=\"Temperature status\";rt=\"Temperatur\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern char htu21d_temp_s[8]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", htu21d_temp_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%s}", htu21d_temp_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-climate3/run.sh b/examples/osd/arduino-climate3/run.sh new file mode 100755 index 000000000..5d5cbbbb4 --- /dev/null +++ b/examples/osd/arduino-climate3/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/arduino-climate3/sketch.h b/examples/osd/arduino-climate3/sketch.h new file mode 100644 index 000000000..b48e13237 --- /dev/null +++ b/examples/osd/arduino-climate3/sketch.h @@ -0,0 +1,10 @@ +#ifndef Sketch_h +#define Sketch_h + +struct dstemp{ + float ftemp; + char stemp[8]; +}; +extern struct dstemp ds1820[7]; + +#endif diff --git a/examples/osd/arduino-climate3/sketch.pde b/examples/osd/arduino-climate3/sketch.pde new file mode 100644 index 000000000..9f9cb22d7 --- /dev/null +++ b/examples/osd/arduino-climate3/sketch.pde @@ -0,0 +1,158 @@ +/* + * Sample arduino sketch using contiki features. + * We turn the LED off + * We allow read the moisture sensor + * Unfortunately sleeping for long times in loop() isn't currently + * possible, something turns off the CPU (including PWM outputs) if a + * Proto-Thread is taking too long. We need to find out how to sleep in + * a Contiki-compatible way. + * Note that for a normal arduino sketch you won't have to include any + * of the contiki-specific files here, the sketch should just work. + */ + +#include +#include "Adafruit_HTU21DF.h" +#include +#include "DallasTemperature.h" + +extern "C" { + +#include "arduino-process.h" +#include "rest-engine.h" +#include "sketch.h" + +// Data wire is plugged into port 2 on the Arduino +#define ONE_WIRE_BUS 3 +#define TEMPERATURE_PRECISION 9 + +// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) +OneWire oneWire(ONE_WIRE_BUS); + +// Pass our oneWire reference to Dallas Temperature. +DallasTemperature dsensors(&oneWire); + +// arrays to hold device addresses +DeviceAddress outsideThermometer; + +Adafruit_HTU21DF htu = Adafruit_HTU21DF(); + +extern resource_t res_htu21dtemp, res_htu21dhum, res_dtemp1, res_battery; +float htu21d_hum; +float htu21d_temp; +char htu21d_hum_s[8]; +char htu21d_temp_s[8]; + +float d_temp; +char d_temp_s[8]; +// sketch.h +struct dstemp ds1820[7]; + +#define LED_PIN 4 +} +// main functions to print information about a device +void printAddress(uint8_t* adress) +{ + printf("%02X",adress[0]); + printf("%02X",adress[1]); + printf("%02X",adress[2]); + printf("%02X",adress[3]); + printf("%02X",adress[4]); + printf("%02X",adress[5]); + printf("%02X",adress[6]); + printf("%02X",adress[7]); +} + +// function to print the temperature for a device +void printTemperature(DeviceAddress deviceAddress,int index) +{ + d_temp = dsensors.getTempC(deviceAddress); + dtostrf(d_temp , 6, 2, d_temp_s ); + printf("Temp C: "); + printf("%s",d_temp_s); + // copy to structure + ds1820[index].ftemp=d_temp; + strcpy(ds1820[index].stemp, d_temp_s); +} + +void printData(DeviceAddress deviceAddress, int index) +{ + printf("Device Address: "); + printAddress(deviceAddress); + printf(" "); + printTemperature(deviceAddress,index); + printf("\n"); +} + +void setup (void) +{ + // switch off the led + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, HIGH); + // ds1820 sensor + printf("Dallas Temperature IC Control Library Demo"); + // Start up the library + dsensors.begin(); + // locate devices on the bus + printf("Locating devices...\n"); + printf("Found "); + printf("%d",dsensors.getDeviceCount()); + printf(" devices.\n"); + // report parasite power requirements + printf("Parasite power is: "); + if (dsensors.isParasitePowerMode()) printf("ON\n"); + else printf("OFF\n"); + if (!dsensors.getAddress(outsideThermometer, 0)) printf("Unable to find address for Device 0\n"); + // show the addresses we found on the bus + printf("Device 0 Address: "); + printAddress(outsideThermometer); + printf("\n"); + // set the resolution to 9 bit + dsensors.setResolution(outsideThermometer, 9); + printf("Device 0 Resolution: "); + printf("%d",dsensors.getResolution(outsideThermometer)); + printf("\n"); + + // htu21d sensor + if (!htu.begin()) { + printf("Couldn't find sensor!"); + } + // init coap resourcen + rest_init_engine (); + rest_activate_resource (&res_htu21dtemp, "s/temp"); + rest_activate_resource (&res_htu21dhum, "s/hum"); + rest_activate_resource (&res_dtemp1, "s/t1/temp"); + rest_activate_resource (&res_battery, "s/battery"); +} + +// at project-conf.h +// LOOP_INTERVAL (20 * CLOCK_SECOND) +void loop (void) +{ + mcu_sleep_off(); + // call sensors.requestTemperatures() to issue a global temperature + // request to all devices on the bus +// printf("Requesting temperatures..."); + dsensors.requestTemperatures(); +// printf("DONE\n"); + // print the device information + printData(outsideThermometer,0); + + htu21d_temp = htu.readTemperature(); + htu21d_hum = htu.readHumidity(); + + dtostrf(htu21d_temp , 6, 2, htu21d_temp_s ); + dtostrf(htu21d_hum , 6, 2, htu21d_hum_s ); + // remove space + if(htu21d_temp_s[0]==' '){ + memcpy (htu21d_temp_s,htu21d_temp_s+1,strlen(htu21d_temp_s)+1); + } + if(htu21d_hum_s[0]==' '){ + memcpy (htu21d_hum_s,htu21d_hum_s+1,strlen(htu21d_hum_s)+1); + } + +// debug only + printf("Temp: %s",htu21d_temp_s); + printf("\t\tHum: %s\n",htu21d_hum_s); + + mcu_sleep_on(); +} diff --git a/examples/osd/arduino-dallastemp/DallasTemperature.cpp b/examples/osd/arduino-dallastemp/DallasTemperature.cpp new file mode 100644 index 000000000..ea5b1e571 --- /dev/null +++ b/examples/osd/arduino-dallastemp/DallasTemperature.cpp @@ -0,0 +1,618 @@ +// 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. + +#include "DallasTemperature.h" + +extern "C" { + #include "Arduino.h" +} + +DallasTemperature::DallasTemperature(OneWire* _oneWire) + #if REQUIRESALARMS + : _AlarmHandler(&defaultAlarmHandler) + #endif +{ + _wire = _oneWire; + devices = 0; + parasite = false; + conversionDelay = TEMP_9_BIT; +} + +// initialize the bus +void DallasTemperature::begin(void) +{ + DeviceAddress deviceAddress; + + _wire->reset_search(); + devices = 0; // Reset the number of devices when we enumerate wire devices + + while (_wire->search(deviceAddress)) + { + if (validAddress(deviceAddress)) + { + if (!parasite && readPowerSupply(deviceAddress)) parasite = true; + + ScratchPad scratchPad; + + readScratchPad(deviceAddress, scratchPad); + + if (deviceAddress[0] == DS18S20MODEL) conversionDelay = TEMP_12_BIT; // 750 ms + else if (scratchPad[CONFIGURATION] > conversionDelay) conversionDelay = scratchPad[CONFIGURATION]; + + devices++; + } + } +} + +// returns the number of devices found on the bus +uint8_t DallasTemperature::getDeviceCount(void) +{ + return devices; +} + +// returns true if address is valid +bool DallasTemperature::validAddress(uint8_t* deviceAddress) +{ + return (_wire->crc8(deviceAddress, 7) == deviceAddress[7]); +} + +// finds an address at a given index on the bus +// returns true if the device was found +bool DallasTemperature::getAddress(uint8_t* deviceAddress, uint8_t index) +{ + uint8_t depth = 0; + + _wire->reset_search(); + + while (depth <= index && _wire->search(deviceAddress)) + { + if (depth == index && validAddress(deviceAddress)) return true; + depth++; + } + + return false; +} + +// attempt to determine if the device at the given address is connected to the bus +bool DallasTemperature::isConnected(uint8_t* deviceAddress) +{ + ScratchPad scratchPad; + return isConnected(deviceAddress, scratchPad); +} + +// attempt to determine if the device at the given address is connected to the bus +// also allows for updating the read scratchpad +bool DallasTemperature::isConnected(uint8_t* deviceAddress, uint8_t* scratchPad) +{ + readScratchPad(deviceAddress, scratchPad); + return (_wire->crc8(scratchPad, 8) == scratchPad[SCRATCHPAD_CRC]); +} + +// read device's scratch pad +void DallasTemperature::readScratchPad(uint8_t* deviceAddress, uint8_t* scratchPad) +{ + // send the command + _wire->reset(); + _wire->select(deviceAddress); + _wire->write(READSCRATCH); + + // read the response + + // byte 0: temperature LSB + scratchPad[TEMP_LSB] = _wire->read(); + + // byte 1: temperature MSB + scratchPad[TEMP_MSB] = _wire->read(); + + // byte 2: high alarm temp + scratchPad[HIGH_ALARM_TEMP] = _wire->read(); + + // byte 3: low alarm temp + scratchPad[LOW_ALARM_TEMP] = _wire->read(); + + // byte 4: + // DS18S20: store for crc + // DS18B20 & DS1822: configuration register + scratchPad[CONFIGURATION] = _wire->read(); + + // byte 5: + // internal use & crc + scratchPad[INTERNAL_BYTE] = _wire->read(); + + // byte 6: + // DS18S20: COUNT_REMAIN + // DS18B20 & DS1822: store for crc + scratchPad[COUNT_REMAIN] = _wire->read(); + + // byte 7: + // DS18S20: COUNT_PER_C + // DS18B20 & DS1822: store for crc + scratchPad[COUNT_PER_C] = _wire->read(); + + // byte 8: + // SCTRACHPAD_CRC + scratchPad[SCRATCHPAD_CRC] = _wire->read(); + + _wire->reset(); +} + +// writes device's scratch pad +void DallasTemperature::writeScratchPad(uint8_t* deviceAddress, const uint8_t* scratchPad) +{ + _wire->reset(); + _wire->select(deviceAddress); + _wire->write(WRITESCRATCH); + _wire->write(scratchPad[HIGH_ALARM_TEMP]); // high alarm temp + _wire->write(scratchPad[LOW_ALARM_TEMP]); // low alarm temp + // DS18S20 does not use the configuration register + if (deviceAddress[0] != DS18S20MODEL) _wire->write(scratchPad[CONFIGURATION]); // configuration + _wire->reset(); + // save the newly written values to eeprom + _wire->write(COPYSCRATCH, parasite); + if (parasite) delay(10); // 10ms delay + _wire->reset(); +} + +// reads the device's power requirements +bool DallasTemperature::readPowerSupply(uint8_t* deviceAddress) +{ + bool ret = false; + _wire->reset(); + _wire->select(deviceAddress); + _wire->write(READPOWERSUPPLY); + if (_wire->read_bit() == 0) ret = true; + _wire->reset(); + return ret; +} + +// returns the current resolution, 9-12 +uint8_t DallasTemperature::getResolution(uint8_t* deviceAddress) +{ + if (deviceAddress[0] == DS18S20MODEL) return 9; // this model has a fixed resolution + + ScratchPad scratchPad; + readScratchPad(deviceAddress, scratchPad); + switch (scratchPad[CONFIGURATION]) + { + case TEMP_12_BIT: + return 12; + break; + case TEMP_11_BIT: + return 11; + break; + case TEMP_10_BIT: + return 10; + break; + case TEMP_9_BIT: + return 9; + break; + } +} + +// set resolution of a device to 9, 10, 11, or 12 bits +void DallasTemperature::setResolution(uint8_t* deviceAddress, uint8_t newResolution) +{ + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) + { + // DS18S20 has a fixed 9-bit resolution + if (deviceAddress[0] != DS18S20MODEL) + { + switch (newResolution) + { + case 12: + scratchPad[CONFIGURATION] = TEMP_12_BIT; + break; + case 11: + scratchPad[CONFIGURATION] = TEMP_11_BIT; + break; + case 10: + scratchPad[CONFIGURATION] = TEMP_10_BIT; + break; + case 9: + default: + scratchPad[CONFIGURATION] = TEMP_9_BIT; + break; + } + writeScratchPad(deviceAddress, scratchPad); + } + } +} + +// sends command for all devices on the bus to perform a temperature +void DallasTemperature::requestTemperatures(void) +{ + _wire->reset(); + _wire->skip(); + _wire->write(STARTCONVO, parasite); + + switch (conversionDelay) + { + case TEMP_9_BIT: + delay(94); + break; + case TEMP_10_BIT: + delay(188); + break; + case TEMP_11_BIT: + delay(375); + break; + case TEMP_12_BIT: + default: + delay(750); + break; + } +} + +// sends command for one device to perform a temperature by address +void DallasTemperature::requestTemperaturesByAddress(uint8_t* deviceAddress) +{ + _wire->reset(); + _wire->select(deviceAddress); + _wire->write(STARTCONVO, parasite); + + switch (conversionDelay) + { + case TEMP_9_BIT: + delay(94); + break; + case TEMP_10_BIT: + delay(188); + break; + case TEMP_11_BIT: + delay(375); + break; + case TEMP_12_BIT: + default: + delay(750); + break; + } +} + +// sends command for one device to perform a temp conversion by index +void DallasTemperature::requestTemperaturesByIndex(uint8_t deviceIndex) +{ + DeviceAddress deviceAddress; + getAddress(deviceAddress, deviceIndex); + requestTemperaturesByAddress(deviceAddress); +} + + +// Fetch temperature for device index +float DallasTemperature::getTempCByIndex(uint8_t deviceIndex) +{ + DeviceAddress deviceAddress; + getAddress(deviceAddress, deviceIndex); + return getTempC((uint8_t*)deviceAddress); +} + +// Fetch temperature for device index +float DallasTemperature::getTempFByIndex(uint8_t deviceIndex) +{ + return DallasTemperature::toFahrenheit(getTempCByIndex(deviceIndex)); +} + +// reads scratchpad and returns the temperature in degrees C +float DallasTemperature::calculateTemperature(uint8_t* deviceAddress, uint8_t* scratchPad) +{ + int16_t rawTemperature = (((int16_t)scratchPad[TEMP_MSB]) << 8) | scratchPad[TEMP_LSB]; + + switch (deviceAddress[0]) + { + case DS18B20MODEL: + case DS1822MODEL: + switch (scratchPad[CONFIGURATION]) + { + case TEMP_12_BIT: + return (float)rawTemperature * 0.0625; + break; + case TEMP_11_BIT: + return (float)(rawTemperature >> 1) * 0.125; + break; + case TEMP_10_BIT: + return (float)(rawTemperature >> 2) * 0.25; + break; + case TEMP_9_BIT: + return (float)(rawTemperature >> 3) * 0.5; + break; + } + break; + case DS18S20MODEL: + /* + + Resolutions greater than 9 bits can be calculated using the data from + the temperature, COUNT REMAIN and COUNT PER C registers in the + scratchpad. Note that the COUNT PER C register is hard-wired to 16 + (10h). After reading the scratchpad, the TEMP_READ value is obtained + by truncating the 0.5C bit (bit 0) from the temperature data. The + extended resolution temperature can then be calculated using the + following equation: + + COUNT_PER_C - COUNT_REMAIN + TEMPERATURE = TEMP_READ - 0.25 + -------------------------- + COUNT_PER_C + */ + + // Good spot. Thanks Nic Johns for your contribution + return (float)(rawTemperature >> 1) - 0.25 +((float)(scratchPad[COUNT_PER_C] - scratchPad[COUNT_REMAIN]) / (float)scratchPad[COUNT_PER_C] ); + break; + } +} + +// returns temperature in degrees C or DEVICE_DISCONNECTED if the +// device's scratch pad cannot be read successfully. +// the numeric value of DEVICE_DISCONNECTED is defined in +// DallasTemperature.h. it is a large negative number outside the +// operating range of the device +float DallasTemperature::getTempC(uint8_t* deviceAddress) +{ + // TODO: Multiple devices (up to 64) on the same bus may take some time to negotiate a response + // What happens in case of collision? + + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) return calculateTemperature(deviceAddress, scratchPad); + return DEVICE_DISCONNECTED; +} + +// returns temperature in degrees F +float DallasTemperature::getTempF(uint8_t* deviceAddress) +{ + return toFahrenheit(getTempC(deviceAddress)); +} + +// returns true if the bus requires parasite power +bool DallasTemperature::isParasitePowerMode(void) +{ + return parasite; +} + +#if REQUIRESALARMS + +/* + +ALARMS: + +TH and TL Register Format + +BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 + S 2^6 2^5 2^4 2^3 2^2 2^1 2^0 + +Only bits 11 through 4 of the temperature register are used +in the TH and TL comparison since TH and TL are 8-bit +registers. If the measured temperature is lower than or equal +to TL or higher than or equal to TH, an alarm condition exists +and an alarm flag is set inside the DS18B20. This flag is +updated after every temperature measurement; therefore, if the +alarm condition goes away, the flag will be turned off after +the next temperature conversion. + +*/ + +// sets the high alarm temperature for a device in degrees celsius +// accepts a float, but the alarm resolution will ignore anything +// after a decimal point. valid range is -55C - 125C +void DallasTemperature::setHighAlarmTemp(uint8_t* deviceAddress, char celsius) +{ + // make sure the alarm temperature is within the device's range + if (celsius > 125) celsius = 125; + else if (celsius < -55) celsius = -55; + + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) + { + scratchPad[HIGH_ALARM_TEMP] = (uint8_t)celsius; + writeScratchPad(deviceAddress, scratchPad); + } +} + +// sets the low alarm temperature for a device in degreed celsius +// accepts a float, but the alarm resolution will ignore anything +// after a decimal point. valid range is -55C - 125C +void DallasTemperature::setLowAlarmTemp(uint8_t* deviceAddress, char celsius) +{ + // make sure the alarm temperature is within the device's range + if (celsius > 125) celsius = 125; + else if (celsius < -55) celsius = -55; + + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) + { + scratchPad[LOW_ALARM_TEMP] = (uint8_t)celsius; + writeScratchPad(deviceAddress, scratchPad); + } +} + +// returns a char with the current high alarm temperature or +// DEVICE_DISCONNECTED for an address +char DallasTemperature::getHighAlarmTemp(uint8_t* deviceAddress) +{ + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) return (char)scratchPad[HIGH_ALARM_TEMP]; + return DEVICE_DISCONNECTED; +} + +// returns a char with the current low alarm temperature or +// DEVICE_DISCONNECTED for an address +char DallasTemperature::getLowAlarmTemp(uint8_t* deviceAddress) +{ + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) return (char)scratchPad[LOW_ALARM_TEMP]; + return DEVICE_DISCONNECTED; +} + +// resets internal variables used for the alarm search +void DallasTemperature::resetAlarmSearch() +{ + alarmSearchJunction = -1; + alarmSearchExhausted = 0; + for(uint8_t i = 0; i < 7; i++) + alarmSearchAddress[i] = 0; +} + +// This is a modified version of the OneWire::search method. +// +// Also added the OneWire search fix documented here: +// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295 +// +// Perform an alarm search. If this function returns a '1' then it has +// enumerated the next device and you may retrieve the ROM from the +// OneWire::address variable. If there are no devices, no further +// devices, or something horrible happens in the middle of the +// enumeration then a 0 is returned. If a new device is found then +// its address is copied to newAddr. Use +// DallasTemperature::resetAlarmSearch() to start over. +bool DallasTemperature::alarmSearch(uint8_t* newAddr) +{ + uint8_t i; + char lastJunction = -1; + uint8_t done = 1; + + if (alarmSearchExhausted) return false; + if (!_wire->reset()) return false; + + // send the alarm search command + _wire->write(0xEC, 0); + + for(i = 0; i < 64; i++) + { + uint8_t a = _wire->read_bit( ); + uint8_t nota = _wire->read_bit( ); + uint8_t ibyte = i / 8; + uint8_t ibit = 1 << (i & 7); + + // I don't think this should happen, this means nothing responded, but maybe if + // something vanishes during the search it will come up. + if (a && nota) return false; + + if (!a && !nota) + { + if (i == alarmSearchJunction) + { + // this is our time to decide differently, we went zero last time, go one. + a = 1; + alarmSearchJunction = lastJunction; + } + else if (i < alarmSearchJunction) + { + // take whatever we took last time, look in address + if (alarmSearchAddress[ibyte] & ibit) a = 1; + else + { + // Only 0s count as pending junctions, we've already exhasuted the 0 side of 1s + a = 0; + done = 0; + lastJunction = i; + } + } + else + { + // we are blazing new tree, take the 0 + a = 0; + alarmSearchJunction = i; + done = 0; + } + // OneWire search fix + // See: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295 + } + + if (a) alarmSearchAddress[ibyte] |= ibit; + else alarmSearchAddress[ibyte] &= ~ibit; + + _wire->write_bit(a); + } + + if (done) alarmSearchExhausted = 1; + for (i = 0; i < 8; i++) newAddr[i] = alarmSearchAddress[i]; + return true; +} + +// returns true if device address has an alarm condition +bool DallasTemperature::hasAlarm(uint8_t* deviceAddress) +{ + ScratchPad scratchPad; + if (isConnected(deviceAddress, scratchPad)) + { + float temp = calculateTemperature(deviceAddress, scratchPad); + + // check low alarm + if ((char)temp <= (char)scratchPad[LOW_ALARM_TEMP]) return true; + + // check high alarm + if ((char)temp >= (char)scratchPad[HIGH_ALARM_TEMP]) return true; + } + + // no alarm + return false; +} + +// returns true if any device is reporting an alarm condition on the bus +bool DallasTemperature::hasAlarm(void) +{ + DeviceAddress deviceAddress; + resetAlarmSearch(); + return alarmSearch(deviceAddress); +} + +// runs the alarm handler for all devices returned by alarmSearch() +void DallasTemperature::processAlarms(void) +{ + resetAlarmSearch(); + DeviceAddress alarmAddr; + + while (alarmSearch(alarmAddr)) + { + if (validAddress(alarmAddr)) + _AlarmHandler(alarmAddr); + } +} + +// sets the alarm handler +void DallasTemperature::setAlarmHandler(AlarmHandler *handler) +{ + _AlarmHandler = handler; +} + +// The default alarm handler +void DallasTemperature::defaultAlarmHandler(uint8_t* deviceAddress) +{ +} + +#endif + +// Convert float celsius to fahrenheit +float DallasTemperature::toFahrenheit(float celsius) +{ + return (celsius * 1.8) + 32; +} + +// Convert float fahrenheit to celsius +float DallasTemperature::toCelsius(float fahrenheit) +{ + return (fahrenheit - 32) / 1.8; +} + +#if REQUIRESNEW + +// MnetCS - Allocates memory for DallasTemperature. Allows us to instance a new object +void* DallasTemperature::operator new(unsigned int size) // Implicit NSS obj size +{ + void * p; // void pointer + p = malloc(size); // Allocate memory + memset((DallasTemperature*)p,0,size); // Initalise memory + + //!!! CANT EXPLICITLY CALL CONSTRUCTOR - workaround by using an init() methodR - workaround by using an init() method + return (DallasTemperature*) p; // Cast blank region to NSS pointer +} + +// MnetCS 2009 - Unallocates the memory used by this instance +void DallasTemperature::operator delete(void* p) +{ + DallasTemperature* pNss = (DallasTemperature*) p; // Cast to NSS pointer + pNss->~DallasTemperature(); // Destruct the object + + free(p); // Free the memory +} + +#endif diff --git a/examples/osd/arduino-dallastemp/DallasTemperature.h b/examples/osd/arduino-dallastemp/DallasTemperature.h new file mode 100644 index 000000000..daf4ad1c2 --- /dev/null +++ b/examples/osd/arduino-dallastemp/DallasTemperature.h @@ -0,0 +1,213 @@ +#ifndef DallasTemperature_h +#define DallasTemperature_h + +// 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. + +// set to true to include code for new and delete operators +#ifndef REQUIRESNEW +#define REQUIRESNEW false +#endif + +// set to true to include code implementing alarm search functions +#ifndef REQUIRESALARMS +#define REQUIRESALARMS true +#endif + +#include +#include + +// Model IDs +#define DS18S20MODEL 0x10 +#define DS18B20MODEL 0x28 +#define DS1822MODEL 0x22 + +// OneWire commands +#define STARTCONVO 0x44 // Tells device to take a temperature reading and put it on the scratchpad +#define COPYSCRATCH 0x48 // Copy EEPROM +#define READSCRATCH 0xBE // Read EEPROM +#define WRITESCRATCH 0x4E // Write to EEPROM +#define RECALLSCRATCH 0xB8 // Reload from last known +#define READPOWERSUPPLY 0xB4 // Determine if device needs parasite power +#define ALARMSEARCH 0xEC // Query bus for devices with an alarm condition + +// Scratchpad locations +#define TEMP_LSB 0 +#define TEMP_MSB 1 +#define HIGH_ALARM_TEMP 2 +#define LOW_ALARM_TEMP 3 +#define CONFIGURATION 4 +#define INTERNAL_BYTE 5 +#define COUNT_REMAIN 6 +#define COUNT_PER_C 7 +#define SCRATCHPAD_CRC 8 + +// Device resolution +#define TEMP_9_BIT 0x1F // 9 bit +#define TEMP_10_BIT 0x3F // 10 bit +#define TEMP_11_BIT 0x5F // 11 bit +#define TEMP_12_BIT 0x7F // 12 bit + +// Error Codes +#define DEVICE_DISCONNECTED -127 + +typedef uint8_t DeviceAddress[8]; + +class DallasTemperature +{ + public: + + DallasTemperature(OneWire*); + + // initalize bus + void begin(void); + + // returns the number of devices found on the bus + uint8_t getDeviceCount(void); + + // returns true if address is valid + bool validAddress(uint8_t*); + + // finds an address at a given index on the bus + bool getAddress(uint8_t*, const uint8_t); + + // attempt to determine if the device at the given address is connected to the bus + bool isConnected(uint8_t*); + + // attempt to determine if the device at the given address is connected to the bus + // also allows for updating the read scratchpad + bool isConnected(uint8_t*, uint8_t*); + + // read device's scratchpad + void readScratchPad(uint8_t*, uint8_t*); + + // write device's scratchpad + void writeScratchPad(uint8_t*, const uint8_t*); + + // read device's power requirements + bool readPowerSupply(uint8_t*); + + // returns the current resolution, 9-12 + uint8_t getResolution(uint8_t*); + + // set resolution of a device to 9, 10, 11, or 12 bits + void setResolution(uint8_t*, uint8_t); + + // sends command for all devices on the bus to perform a temperature conversion + void requestTemperatures(void); + + // sends command for one device to perform a temperature conversion by address + void requestTemperaturesByAddress(uint8_t*); + + // sends command for one device to perform a temperature conversion by index + void requestTemperaturesByIndex(uint8_t); + + // returns temperature in degrees C + float getTempC(uint8_t*); + + // returns temperature in degrees F + float getTempF(uint8_t*); + + // Get temperature for device index (slow) + float getTempCByIndex(uint8_t); + + // Get temperature for device index (slow) + float getTempFByIndex(uint8_t); + + // returns true if the bus requires parasite power + bool isParasitePowerMode(void); + + #if REQUIRESALARMS + + typedef void AlarmHandler(uint8_t*); + + // sets the high alarm temperature for a device + // accepts a char. valid range is -55C - 125C + void setHighAlarmTemp(uint8_t*, const char); + + // sets the low alarm temperature for a device + // accepts a char. valid range is -55C - 125C + void setLowAlarmTemp(uint8_t*, const char); + + // returns a signed char with the current high alarm temperature for a device + // in the range -55C - 125C + char getHighAlarmTemp(uint8_t*); + + // returns a signed char with the current low alarm temperature for a device + // in the range -55C - 125C + char getLowAlarmTemp(uint8_t*); + + // resets internal variables used for the alarm search + void resetAlarmSearch(void); + + // search the wire for devices with active alarms + bool alarmSearch(uint8_t*); + + // returns true if ia specific device has an alarm + bool hasAlarm(uint8_t*); + + // returns true if any device is reporting an alarm on the bus + bool hasAlarm(void); + + // runs the alarm handler for all devices returned by alarmSearch() + void processAlarms(void); + + // sets the alarm handler + void setAlarmHandler(AlarmHandler *); + + // The default alarm handler + static void defaultAlarmHandler(uint8_t*); + + #endif + + // convert from celcius to farenheit + static float toFahrenheit(const float); + + // convert from farenheit to celsius + static float toCelsius(const float); + + #if REQUIRESNEW + + // initalize memory area + void* operator new (unsigned int); + + // delete memory reference + void operator delete(void*); + + #endif + + private: + typedef uint8_t ScratchPad[9]; + + // parasite power on or off + bool parasite; + + // used to determine the delay amount needed to allow for the + // temperature conversion to take place + int conversionDelay; + + // count of devices on the bus + uint8_t devices; + + // Take a pointer to one wire instance + OneWire* _wire; + + // reads scratchpad and returns the temperature in degrees C + float calculateTemperature(uint8_t*, uint8_t*); + + #if REQUIRESALARMS + + // required for alarmSearch + uint8_t alarmSearchAddress[8]; + char alarmSearchJunction; + uint8_t alarmSearchExhausted; + + // the alarm handler function pointer + AlarmHandler *_AlarmHandler; + + #endif + +}; +#endif diff --git a/examples/osd/arduino-dallastemp/Makefile b/examples/osd/arduino-dallastemp/Makefile new file mode 100644 index 000000000..f1741488c --- /dev/null +++ b/examples/osd/arduino-dallastemp/Makefile @@ -0,0 +1,71 @@ +# Set this to the name of your sketch (without extension .pde) +SKETCH=sketch +EXE=arduino-example + +all: $(EXE) + +CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +LFLAGS += -lm + +PROJECT_SOURCEFILES += ${SKETCH}.cpp OneWire.cpp DallasTemperature.cpp + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) + +# variable for Makefile.include +ifneq ($(TARGET), minimal-net) +CFLAGS += -DUIP_CONF_IPV6_RPL=1 +else +# minimal-net does not support RPL under Linux and is mostly used to test CoAP only +${info INFO: compiling without RPL} +CFLAGS += -DUIP_CONF_IPV6_RPL=0 +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=640 +endif + +# linker optimizations +SMALL=1 + + +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += arduino + +include $(CONTIKI)/Makefile.include +include $(CONTIKI)/apps/arduino/Makefile.include + +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + (cd $(CONTIKI)/tools && $(MAKE) tunslip6) + +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + +connect-minimal: + sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/arduino-dallastemp/OneWire.cpp b/examples/osd/arduino-dallastemp/OneWire.cpp new file mode 100644 index 000000000..6d55de0bf --- /dev/null +++ b/examples/osd/arduino-dallastemp/OneWire.cpp @@ -0,0 +1,563 @@ +/* +Copyright (c) 2007, Jim Studt (original old version - many contributors since) + +The latest version of this library may be found at: + http://www.pjrc.com/teensy/td_libs_OneWire.html + +OneWire has been maintained by Paul Stoffregen (paul@pjrc.com) since +January 2010. At the time, it was in need of many bug fixes, but had +been abandoned the original author (Jim Studt). None of the known +contributors were interested in maintaining OneWire. Paul typically +works on OneWire every 6 to 12 months. Patches usually wait that +long. If anyone is interested in more actively maintaining OneWire, +please contact Paul. + +Version 2.3: + Unknonw chip fallback mode, Roger Clark + Teensy-LC compatibility, Paul Stoffregen + Search bug fix, Love Nystrom + +Version 2.2: + Teensy 3.0 compatibility, Paul Stoffregen, paul@pjrc.com + Arduino Due compatibility, http://arduino.cc/forum/index.php?topic=141030 + Fix DS18B20 example negative temperature + Fix DS18B20 example's low res modes, Ken Butcher + Improve reset timing, Mark Tillotson + Add const qualifiers, Bertrik Sikken + Add initial value input to crc16, Bertrik Sikken + Add target_search() function, Scott Roberts + +Version 2.1: + Arduino 1.0 compatibility, Paul Stoffregen + Improve temperature example, Paul Stoffregen + DS250x_PROM example, Guillermo Lovato + PIC32 (chipKit) compatibility, Jason Dangel, dangel.jason AT gmail.com + Improvements from Glenn Trewitt: + - crc16() now works + - check_crc16() does all of calculation/checking work. + - Added read_bytes() and write_bytes(), to reduce tedious loops. + - Added ds2408 example. + Delete very old, out-of-date readme file (info is here) + +Version 2.0: Modifications by Paul Stoffregen, January 2010: +http://www.pjrc.com/teensy/td_libs_OneWire.html + Search fix from Robin James + http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27 + Use direct optimized I/O in all cases + Disable interrupts during timing critical sections + (this solves many random communication errors) + Disable interrupts during read-modify-write I/O + Reduce RAM consumption by eliminating unnecessary + variables and trimming many to 8 bits + Optimize both crc8 - table version moved to flash + +Modified to work with larger numbers of devices - avoids loop. +Tested in Arduino 11 alpha with 12 sensors. +26 Sept 2008 -- Robin James +http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27 + +Updated to work with arduino-0008 and to include skip() as of +2007/07/06. --RJL20 + +Modified to calculate the 8-bit CRC directly, avoiding the need for +the 256-byte lookup table to be loaded in RAM. Tested in arduino-0010 +-- Tom Pollard, Jan 23, 2008 + +Jim Studt's original library was modified by Josh Larios. + +Tom Pollard, pollard@alum.mit.edu, contributed around May 20, 2008 + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Much of the code was inspired by Derek Yerger's code, though I don't +think much of that remains. In any event that was.. + (copyleft) 2006 by Derek Yerger - Free to distribute freely. + +The CRC code was excerpted and inspired by the Dallas Semiconductor +sample code bearing this copyright. +//--------------------------------------------------------------------------- +// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES +// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// Except as contained in this notice, the name of Dallas Semiconductor +// shall not be used except as stated in the Dallas Semiconductor +// Branding Policy. +//-------------------------------------------------------------------------- +*/ + +#include "OneWire.h" + + +OneWire::OneWire(uint8_t pin) +{ + pinMode(pin, INPUT); + bitmask = PIN_TO_BITMASK(pin); + baseReg = PIN_TO_BASEREG(pin); +#if ONEWIRE_SEARCH + reset_search(); +#endif +} + + +// Perform the onewire reset function. We will wait up to 250uS for +// the bus to come high, if it doesn't then it is broken or shorted +// and we return a 0; +// +// Returns 1 if a device asserted a presence pulse, 0 otherwise. +// +uint8_t OneWire::reset(void) +{ + IO_REG_TYPE mask = bitmask; + volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg; + uint8_t r; + uint8_t retries = 125; + + noInterrupts(); + DIRECT_MODE_INPUT(reg, mask); + interrupts(); + // wait until the wire is high... just in case + do { + if (--retries == 0) return 0; + delayMicroseconds(2); + } while ( !DIRECT_READ(reg, mask)); + + noInterrupts(); + DIRECT_WRITE_LOW(reg, mask); + DIRECT_MODE_OUTPUT(reg, mask); // drive output low + interrupts(); + delayMicroseconds(480); + noInterrupts(); + DIRECT_MODE_INPUT(reg, mask); // allow it to float + delayMicroseconds(70); + r = !DIRECT_READ(reg, mask); + interrupts(); + delayMicroseconds(410); + return r; +} + +// +// Write a bit. Port and bit is used to cut lookup time and provide +// more certain timing. +// +void OneWire::write_bit(uint8_t v) +{ + IO_REG_TYPE mask=bitmask; + volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg; + + if (v & 1) { + noInterrupts(); + DIRECT_WRITE_LOW(reg, mask); + DIRECT_MODE_OUTPUT(reg, mask); // drive output low + delayMicroseconds(10); + DIRECT_WRITE_HIGH(reg, mask); // drive output high + interrupts(); + delayMicroseconds(55); + } else { + noInterrupts(); + DIRECT_WRITE_LOW(reg, mask); + DIRECT_MODE_OUTPUT(reg, mask); // drive output low + delayMicroseconds(65); + DIRECT_WRITE_HIGH(reg, mask); // drive output high + interrupts(); + delayMicroseconds(5); + } +} + +// +// Read a bit. Port and bit is used to cut lookup time and provide +// more certain timing. +// +uint8_t OneWire::read_bit(void) +{ + IO_REG_TYPE mask=bitmask; + volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg; + uint8_t r; + + noInterrupts(); + DIRECT_MODE_OUTPUT(reg, mask); + DIRECT_WRITE_LOW(reg, mask); + delayMicroseconds(3); + DIRECT_MODE_INPUT(reg, mask); // let pin float, pull up will raise + delayMicroseconds(10); + r = DIRECT_READ(reg, mask); + interrupts(); + delayMicroseconds(53); + return r; +} + +// +// Write a byte. The writing code uses the active drivers to raise the +// pin high, if you need power after the write (e.g. DS18S20 in +// parasite power mode) then set 'power' to 1, otherwise the pin will +// go tri-state at the end of the write to avoid heating in a short or +// other mishap. +// +void OneWire::write(uint8_t v, uint8_t power /* = 0 */) { + uint8_t bitMask; + + for (bitMask = 0x01; bitMask; bitMask <<= 1) { + OneWire::write_bit( (bitMask & v)?1:0); + } + if ( !power) { + noInterrupts(); + DIRECT_MODE_INPUT(baseReg, bitmask); + DIRECT_WRITE_LOW(baseReg, bitmask); + interrupts(); + } +} + +void OneWire::write_bytes(const uint8_t *buf, uint16_t count, bool power /* = 0 */) { + for (uint16_t i = 0 ; i < count ; i++) + write(buf[i]); + if (!power) { + noInterrupts(); + DIRECT_MODE_INPUT(baseReg, bitmask); + DIRECT_WRITE_LOW(baseReg, bitmask); + interrupts(); + } +} + +// +// Read a byte +// +uint8_t OneWire::read() { + uint8_t bitMask; + uint8_t r = 0; + + for (bitMask = 0x01; bitMask; bitMask <<= 1) { + if ( OneWire::read_bit()) r |= bitMask; + } + return r; +} + +void OneWire::read_bytes(uint8_t *buf, uint16_t count) { + for (uint16_t i = 0 ; i < count ; i++) + buf[i] = read(); +} + +// +// Do a ROM select +// +void OneWire::select(const uint8_t rom[8]) +{ + uint8_t i; + + write(0x55); // Choose ROM + + for (i = 0; i < 8; i++) write(rom[i]); +} + +// +// Do a ROM skip +// +void OneWire::skip() +{ + write(0xCC); // Skip ROM +} + +void OneWire::depower() +{ + noInterrupts(); + DIRECT_MODE_INPUT(baseReg, bitmask); + interrupts(); +} + +#if ONEWIRE_SEARCH + +// +// You need to use this function to start a search again from the beginning. +// You do not need to do it for the first search, though you could. +// +void OneWire::reset_search() +{ + // reset the search state + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + for(int i = 7; ; i--) { + ROM_NO[i] = 0; + if ( i == 0) break; + } +} + +// Setup the search to find the device type 'family_code' on the next call +// to search(*newAddr) if it is present. +// +void OneWire::target_search(uint8_t family_code) +{ + // set the search state to find SearchFamily type devices + ROM_NO[0] = family_code; + for (uint8_t i = 1; i < 8; i++) + ROM_NO[i] = 0; + LastDiscrepancy = 64; + LastFamilyDiscrepancy = 0; + LastDeviceFlag = FALSE; +} + +// +// Perform a search. If this function returns a '1' then it has +// enumerated the next device and you may retrieve the ROM from the +// OneWire::address variable. If there are no devices, no further +// devices, or something horrible happens in the middle of the +// enumeration then a 0 is returned. If a new device is found then +// its address is copied to newAddr. Use OneWire::reset_search() to +// start over. +// +// --- Replaced by the one from the Dallas Semiconductor web site --- +//-------------------------------------------------------------------------- +// Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing +// search state. +// Return TRUE : device found, ROM number in ROM_NO buffer +// FALSE : device not found, end of search +// +uint8_t OneWire::search(uint8_t *newAddr) +{ + uint8_t id_bit_number; + uint8_t last_zero, rom_byte_number, search_result; + uint8_t id_bit, cmp_id_bit; + + unsigned char rom_byte_mask, search_direction; + + // initialize for search + id_bit_number = 1; + last_zero = 0; + rom_byte_number = 0; + rom_byte_mask = 1; + search_result = 0; + + // if the last call was not the last one + if (!LastDeviceFlag) + { + // 1-Wire reset + if (!reset()) + { + // reset the search + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + return FALSE; + } + + // issue the search command + write(0xF0); + + // loop to do the search + do + { + // read a bit and its complement + id_bit = read_bit(); + cmp_id_bit = read_bit(); + + // check for no devices on 1-wire + if ((id_bit == 1) && (cmp_id_bit == 1)) + break; + else + { + // all devices coupled have 0 or 1 + if (id_bit != cmp_id_bit) + search_direction = id_bit; // bit write value for search + else + { + // if this discrepancy if before the Last Discrepancy + // on a previous next then pick the same as last time + if (id_bit_number < LastDiscrepancy) + search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0); + else + // if equal to last pick 1, if not then pick 0 + search_direction = (id_bit_number == LastDiscrepancy); + + // if 0 was picked then record its position in LastZero + if (search_direction == 0) + { + last_zero = id_bit_number; + + // check for Last discrepancy in family + if (last_zero < 9) + LastFamilyDiscrepancy = last_zero; + } + } + + // set or clear the bit in the ROM byte rom_byte_number + // with mask rom_byte_mask + if (search_direction == 1) + ROM_NO[rom_byte_number] |= rom_byte_mask; + else + ROM_NO[rom_byte_number] &= ~rom_byte_mask; + + // serial number search direction write bit + write_bit(search_direction); + + // increment the byte counter id_bit_number + // and shift the mask rom_byte_mask + id_bit_number++; + rom_byte_mask <<= 1; + + // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask + if (rom_byte_mask == 0) + { + rom_byte_number++; + rom_byte_mask = 1; + } + } + } + while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 + + // if the search was successful then + if (!(id_bit_number < 65)) + { + // search successful so set LastDiscrepancy,LastDeviceFlag,search_result + LastDiscrepancy = last_zero; + + // check for last device + if (LastDiscrepancy == 0) + LastDeviceFlag = TRUE; + + search_result = TRUE; + } + } + + // if no device found then reset counters so next 'search' will be like a first + if (!search_result || !ROM_NO[0]) + { + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + search_result = FALSE; + } else { + for (int i = 0; i < 8; i++) newAddr[i] = ROM_NO[i]; + } + return search_result; + } + +#endif + +#if ONEWIRE_CRC +// The 1-Wire CRC scheme is described in Maxim Application Note 27: +// "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products" +// + +#if ONEWIRE_CRC8_TABLE +// This table comes from Dallas sample code where it is freely reusable, +// though Copyright (C) 2000 Dallas Semiconductor Corporation +static const uint8_t PROGMEM dscrc_table[] = { + 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, + 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, + 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, + 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, + 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, + 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, + 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, + 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, + 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, + 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, + 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, + 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, + 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, + 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, + 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, + 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53}; + +// +// Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM +// and the registers. (note: this might better be done without to +// table, it would probably be smaller and certainly fast enough +// compared to all those delayMicrosecond() calls. But I got +// confused, so I use this table from the examples.) +// +uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len) +{ + uint8_t crc = 0; + + while (len--) { + crc = pgm_read_byte(dscrc_table + (crc ^ *addr++)); + } + return crc; +} +#else +// +// Compute a Dallas Semiconductor 8 bit CRC directly. +// this is much slower, but much smaller, than the lookup table. +// +uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len) +{ + uint8_t crc = 0; + + while (len--) { + uint8_t inbyte = *addr++; + for (uint8_t i = 8; i; i--) { + uint8_t mix = (crc ^ inbyte) & 0x01; + crc >>= 1; + if (mix) crc ^= 0x8C; + inbyte >>= 1; + } + } + return crc; +} +#endif + +#if ONEWIRE_CRC16 +bool OneWire::check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc) +{ + crc = ~crc16(input, len, crc); + return (crc & 0xFF) == inverted_crc[0] && (crc >> 8) == inverted_crc[1]; +} + +uint16_t OneWire::crc16(const uint8_t* input, uint16_t len, uint16_t crc) +{ + static const uint8_t oddparity[16] = + { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; + + for (uint16_t i = 0 ; i < len ; i++) { + // Even though we're just copying a byte from the input, + // we'll be doing 16-bit computation with it. + uint16_t cdata = input[i]; + cdata = (cdata ^ crc) & 0xff; + crc >>= 8; + + if (oddparity[cdata & 0x0F] ^ oddparity[cdata >> 4]) + crc ^= 0xC001; + + cdata <<= 6; + crc ^= cdata; + cdata <<= 1; + crc ^= cdata; + } + return crc; +} +#endif + +#endif diff --git a/examples/osd/arduino-dallastemp/OneWire.h b/examples/osd/arduino-dallastemp/OneWire.h new file mode 100644 index 000000000..3aac70636 --- /dev/null +++ b/examples/osd/arduino-dallastemp/OneWire.h @@ -0,0 +1,250 @@ +#ifndef OneWire_h +#define OneWire_h + +#include + +//#if ARDUINO >= 100 +#include "Arduino.h" // for delayMicroseconds, digitalPinToBitMask, etc +//#else +//#include "WProgram.h" // for delayMicroseconds +//#include "pins_arduino.h" // for digitalPinToBitMask, etc +//#endif + +// You can exclude certain features from OneWire. In theory, this +// might save some space. In practice, the compiler automatically +// removes unused code (technically, the linker, using -fdata-sections +// and -ffunction-sections when compiling, and Wl,--gc-sections +// when linking), so most of these will not result in any code size +// reduction. Well, unless you try to use the missing features +// and redesign your program to not need them! ONEWIRE_CRC8_TABLE +// is the exception, because it selects a fast but large algorithm +// or a small but slow algorithm. + +// you can exclude onewire_search by defining that to 0 +#ifndef ONEWIRE_SEARCH +#define ONEWIRE_SEARCH 1 +#endif + +// You can exclude CRC checks altogether by defining this to 0 +#ifndef ONEWIRE_CRC +#define ONEWIRE_CRC 1 +#endif + +// Select the table-lookup method of computing the 8-bit CRC +// by setting this to 1. The lookup table enlarges code size by +// about 250 bytes. It does NOT consume RAM (but did in very +// old versions of OneWire). If you disable this, a slower +// but very compact algorithm is used. +#ifndef ONEWIRE_CRC8_TABLE +#define ONEWIRE_CRC8_TABLE 1 +#endif + +// You can allow 16-bit CRC checks by defining this to 1 +// (Note that ONEWIRE_CRC must also be 1.) +#ifndef ONEWIRE_CRC16 +#define ONEWIRE_CRC16 1 +#endif + +#define FALSE 0 +#define TRUE 1 + +// Platform specific I/O definitions + +#if defined(__AVR__) +#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) +#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) +#define IO_REG_TYPE uint8_t +#define IO_REG_ASM asm("r30") +#define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) +#define DIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask)) +#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask)) +#define DIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask)) +#define DIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) + +#elif defined(__MK20DX128__) || defined(__MK20DX256__) +#define PIN_TO_BASEREG(pin) (portOutputRegister(pin)) +#define PIN_TO_BITMASK(pin) (1) +#define IO_REG_TYPE uint8_t +#define IO_REG_ASM +#define DIRECT_READ(base, mask) (*((base)+512)) +#define DIRECT_MODE_INPUT(base, mask) (*((base)+640) = 0) +#define DIRECT_MODE_OUTPUT(base, mask) (*((base)+640) = 1) +#define DIRECT_WRITE_LOW(base, mask) (*((base)+256) = 1) +#define DIRECT_WRITE_HIGH(base, mask) (*((base)+128) = 1) + +#elif defined(__MKL26Z64__) +#define PIN_TO_BASEREG(pin) (portOutputRegister(pin)) +#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) +#define IO_REG_TYPE uint8_t +#define IO_REG_ASM +#define DIRECT_READ(base, mask) ((*((base)+16) & (mask)) ? 1 : 0) +#define DIRECT_MODE_INPUT(base, mask) (*((base)+20) &= ~(mask)) +#define DIRECT_MODE_OUTPUT(base, mask) (*((base)+20) |= (mask)) +#define DIRECT_WRITE_LOW(base, mask) (*((base)+8) = (mask)) +#define DIRECT_WRITE_HIGH(base, mask) (*((base)+4) = (mask)) + +#elif defined(__SAM3X8E__) +// Arduino 1.5.1 may have a bug in delayMicroseconds() on Arduino Due. +// http://arduino.cc/forum/index.php/topic,141030.msg1076268.html#msg1076268 +// If you have trouble with OneWire on Arduino Due, please check the +// status of delayMicroseconds() before reporting a bug in OneWire! +#define PIN_TO_BASEREG(pin) (&(digitalPinToPort(pin)->PIO_PER)) +#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) +#define IO_REG_TYPE uint32_t +#define IO_REG_ASM +#define DIRECT_READ(base, mask) (((*((base)+15)) & (mask)) ? 1 : 0) +#define DIRECT_MODE_INPUT(base, mask) ((*((base)+5)) = (mask)) +#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+4)) = (mask)) +#define DIRECT_WRITE_LOW(base, mask) ((*((base)+13)) = (mask)) +#define DIRECT_WRITE_HIGH(base, mask) ((*((base)+12)) = (mask)) +#ifndef PROGMEM +#define PROGMEM +#endif +#ifndef pgm_read_byte +#define pgm_read_byte(addr) (*(const uint8_t *)(addr)) +#endif + +#elif defined(__PIC32MX__) +#define PIN_TO_BASEREG(pin) (portModeRegister(digitalPinToPort(pin))) +#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) +#define IO_REG_TYPE uint32_t +#define IO_REG_ASM +#define DIRECT_READ(base, mask) (((*(base+4)) & (mask)) ? 1 : 0) //PORTX + 0x10 +#define DIRECT_MODE_INPUT(base, mask) ((*(base+2)) = (mask)) //TRISXSET + 0x08 +#define DIRECT_MODE_OUTPUT(base, mask) ((*(base+1)) = (mask)) //TRISXCLR + 0x04 +#define DIRECT_WRITE_LOW(base, mask) ((*(base+8+1)) = (mask)) //LATXCLR + 0x24 +#define DIRECT_WRITE_HIGH(base, mask) ((*(base+8+2)) = (mask)) //LATXSET + 0x28 + +#else +#define PIN_TO_BASEREG(pin) (0) +#define PIN_TO_BITMASK(pin) (pin) +#define IO_REG_TYPE unsigned int +#define IO_REG_ASM +#define DIRECT_READ(base, pin) digitalRead(pin) +#define DIRECT_WRITE_LOW(base, pin) digitalWrite(pin, LOW) +#define DIRECT_WRITE_HIGH(base, pin) digitalWrite(pin, HIGH) +#define DIRECT_MODE_INPUT(base, pin) pinMode(pin,INPUT) +#define DIRECT_MODE_OUTPUT(base, pin) pinMode(pin,OUTPUT) +#warning "OneWire. Fallback mode. Using API calls for pinMode,digitalRead and digitalWrite. Operation of this library is not guaranteed on this architecture." + +#endif + + +class OneWire +{ + private: + IO_REG_TYPE bitmask; + volatile IO_REG_TYPE *baseReg; + +#if ONEWIRE_SEARCH + // global search state + unsigned char ROM_NO[8]; + uint8_t LastDiscrepancy; + uint8_t LastFamilyDiscrepancy; + uint8_t LastDeviceFlag; +#endif + + public: + OneWire( uint8_t pin); + + // Perform a 1-Wire reset cycle. Returns 1 if a device responds + // with a presence pulse. Returns 0 if there is no device or the + // bus is shorted or otherwise held low for more than 250uS + uint8_t reset(void); + + // Issue a 1-Wire rom select command, you do the reset first. + void select(const uint8_t rom[8]); + + // Issue a 1-Wire rom skip command, to address all on bus. + void skip(void); + + // Write a byte. If 'power' is one then the wire is held high at + // the end for parasitically powered devices. You are responsible + // for eventually depowering it by calling depower() or doing + // another read or write. + void write(uint8_t v, uint8_t power = 0); + + void write_bytes(const uint8_t *buf, uint16_t count, bool power = 0); + + // Read a byte. + uint8_t read(void); + + void read_bytes(uint8_t *buf, uint16_t count); + + // Write a bit. The bus is always left powered at the end, see + // note in write() about that. + void write_bit(uint8_t v); + + // Read a bit. + uint8_t read_bit(void); + + // Stop forcing power onto the bus. You only need to do this if + // you used the 'power' flag to write() or used a write_bit() call + // and aren't about to do another read or write. You would rather + // not leave this powered if you don't have to, just in case + // someone shorts your bus. + void depower(void); + +#if ONEWIRE_SEARCH + // Clear the search state so that if will start from the beginning again. + void reset_search(); + + // Setup the search to find the device type 'family_code' on the next call + // to search(*newAddr) if it is present. + void target_search(uint8_t family_code); + + // Look for the next device. Returns 1 if a new address has been + // returned. A zero might mean that the bus is shorted, there are + // no devices, or you have already retrieved all of them. It + // might be a good idea to check the CRC to make sure you didn't + // get garbage. The order is deterministic. You will always get + // the same devices in the same order. + uint8_t search(uint8_t *newAddr); +#endif + +#if ONEWIRE_CRC + // Compute a Dallas Semiconductor 8 bit CRC, these are used in the + // ROM and scratchpad registers. + static uint8_t crc8(const uint8_t *addr, uint8_t len); + +#if ONEWIRE_CRC16 + // Compute the 1-Wire CRC16 and compare it against the received CRC. + // Example usage (reading a DS2408): + // // Put everything in a buffer so we can compute the CRC easily. + // uint8_t buf[13]; + // buf[0] = 0xF0; // Read PIO Registers + // buf[1] = 0x88; // LSB address + // buf[2] = 0x00; // MSB address + // WriteBytes(net, buf, 3); // Write 3 cmd bytes + // ReadBytes(net, buf+3, 10); // Read 6 data bytes, 2 0xFF, 2 CRC16 + // if (!CheckCRC16(buf, 11, &buf[11])) { + // // Handle error. + // } + // + // @param input - Array of bytes to checksum. + // @param len - How many bytes to use. + // @param inverted_crc - The two CRC16 bytes in the received data. + // This should just point into the received data, + // *not* at a 16-bit integer. + // @param crc - The crc starting value (optional) + // @return True, iff the CRC matches. + static bool check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc = 0); + + // Compute a Dallas Semiconductor 16 bit CRC. This is required to check + // the integrity of data received from many 1-Wire devices. Note that the + // CRC computed here is *not* what you'll get from the 1-Wire network, + // for two reasons: + // 1) The CRC is transmitted bitwise inverted. + // 2) Depending on the endian-ness of your processor, the binary + // representation of the two-byte return value may have a different + // byte order than the two bytes you get from 1-Wire. + // @param input - Array of bytes to checksum. + // @param len - How many bytes to use. + // @param crc - The crc starting value (optional) + // @return The CRC16, as defined by Dallas Semiconductor. + static uint16_t crc16(const uint8_t* input, uint16_t len, uint16_t crc = 0); +#endif +#endif +}; + +#endif diff --git a/examples/osd/arduino-dallastemp/README.md b/examples/osd/arduino-dallastemp/README.md new file mode 100644 index 000000000..e1490ed05 --- /dev/null +++ b/examples/osd/arduino-dallastemp/README.md @@ -0,0 +1,11 @@ +Arduino compatibility example +============================= + +This example shows that it is now possible to re-use arduino sketches in +Contiki. This example documents the necessary magic. Arduino specifies +two routines, `setup` and `loop`. Before `setup` is called, the +framework initializes hardware. In original Arduino, all this is done in +a `main` function (in C). For contiki we define a process that does the +same. + +See the documentation file in apps/contiki-compat/README.md diff --git a/examples/osd/arduino-dallastemp/arduino-example.c b/examples/osd/arduino-dallastemp/arduino-example.c new file mode 100644 index 000000000..ea74dd8b8 --- /dev/null +++ b/examples/osd/arduino-dallastemp/arduino-example.c @@ -0,0 +1,2 @@ +#include +AUTOSTART_PROCESSES(&arduino_sketch); diff --git a/examples/osd/arduino-dallastemp/flash.sh b/examples/osd/arduino-dallastemp/flash.sh new file mode 100755 index 000000000..e82962073 --- /dev/null +++ b/examples/osd/arduino-dallastemp/flash.sh @@ -0,0 +1,2 @@ +#!/bin/bash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/arduino-dallastemp/project-conf.h b/examples/osd/arduino-dallastemp/project-conf.h new file mode 100644 index 000000000..e25aed53c --- /dev/null +++ b/examples/osd/arduino-dallastemp/project-conf.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ + +#ifndef PROJECT_RPL_WEB_CONF_H_ +#define PROJECT_RPL_WEB_CONF_H_ + +#define PLATFORM_HAS_LEDS 1 +//#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_BATTERY 1 + +#define SICSLOWPAN_CONF_FRAG 1 + +#define LOOP_INTERVAL (10 * CLOCK_SECOND) + +/* Save energy */ +//#define RDC_CONF_PT_YIELD_OFF + +/* For Debug: Dont allow MCU sleeping between channel checks */ +//#undef RDC_CONF_MCU_SLEEP +//#define RDC_CONF_MCU_SLEEP 0 + +/* Disabling RDC for demo purposes. Core updates often require more memory. */ +/* For projects, optimize memory and enable RDC again. */ +// #undef NETSTACK_CONF_RDC +//#define NETSTACK_CONF_RDC nullrdc_driver + +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 64 + +/* Estimate your header size, especially when using Proxy-Uri. */ +/* +#undef COAP_MAX_HEADER_SIZE +#define COAP_MAX_HEADER_SIZE 70 +*/ + +/* The IP buffer size must fit all other hops, in particular the border router. */ + +#undef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 256 + + +/* Multiplies with chunk size, be aware of memory constraints. */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* +#undef COAP_MAX_OBSERVERS +#define COAP_MAX_OBSERVERS 2 +*/ + +/* Filtering .well-known/core per query can be disabled to save space. */ +/* +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +*/ + +/* Save some memory for the sky platform. */ +/* +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 10 +*/ + +/* Reduce 802.15.4 frame queue to save RAM. */ +/* +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 +*/ + +/* +#undef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +*/ + +#endif /* PROJECT_RPL_WEB_CONF_H_ */ diff --git a/examples/osd/arduino-dallastemp/resources/res-dtemp1.c b/examples/osd/arduino-dallastemp/resources/res-dtemp1.c new file mode 100644 index 000000000..e8e36c656 --- /dev/null +++ b/examples/osd/arduino-dallastemp/resources/res-dtemp1.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Moisture resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" +#include "sketch.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_dtemp1, + "title=\"Temperature status\";rt=\"Temperature\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", ds1820[0].stemp); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%s}", ds1820[0].stemp); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-dallastemp/resources/res-dtemp2.c b/examples/osd/arduino-dallastemp/resources/res-dtemp2.c new file mode 100644 index 000000000..7d5050cac --- /dev/null +++ b/examples/osd/arduino-dallastemp/resources/res-dtemp2.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Moisture resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" +#include "sketch.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_dtemp2, + "title=\"Temperature status\";rt=\"Temperature\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", ds1820[1].stemp); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%s}", ds1820[1].stemp); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-dallastemp/run.sh b/examples/osd/arduino-dallastemp/run.sh new file mode 100755 index 000000000..5d5cbbbb4 --- /dev/null +++ b/examples/osd/arduino-dallastemp/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/arduino-dallastemp/sketch.h b/examples/osd/arduino-dallastemp/sketch.h new file mode 100644 index 000000000..b48e13237 --- /dev/null +++ b/examples/osd/arduino-dallastemp/sketch.h @@ -0,0 +1,10 @@ +#ifndef Sketch_h +#define Sketch_h + +struct dstemp{ + float ftemp; + char stemp[8]; +}; +extern struct dstemp ds1820[7]; + +#endif diff --git a/examples/osd/arduino-dallastemp/sketch.pde b/examples/osd/arduino-dallastemp/sketch.pde new file mode 100644 index 000000000..37f5c4413 --- /dev/null +++ b/examples/osd/arduino-dallastemp/sketch.pde @@ -0,0 +1,177 @@ +/* + * Sample arduino sketch using contiki features. + * We turn the LED off + * We allow read the moisture sensor + * Unfortunately sleeping for long times in loop() isn't currently + * possible, something turns off the CPU (including PWM outputs) if a + * Proto-Thread is taking too long. We need to find out how to sleep in + * a Contiki-compatible way. + * Note that for a normal arduino sketch you won't have to include any + * of the contiki-specific files here, the sketch should just work. + */ + +#include +#include "DallasTemperature.h" + +extern "C" { + +#include "arduino-process.h" +#include "rest-engine.h" +#include "sketch.h" + +extern volatile uint8_t mcusleepcycle; // default 16 + +// Data wire is plugged into port 2 on the Arduino +#define ONE_WIRE_BUS 3 +#define TEMPERATURE_PRECISION 9 + +// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) +OneWire oneWire(ONE_WIRE_BUS); + +// Pass our oneWire reference to Dallas Temperature. +DallasTemperature dsensors(&oneWire); + +// arrays to hold device addresses +DeviceAddress insideThermometer, outsideThermometer; + +extern resource_t res_dtemp1, res_dtemp2, res_battery; +float d_temp; +char d_temp_s[8]; + +// sketch.h +struct dstemp ds1820[7]; + +#define LED_PIN 4 +} + +// main functions to print information about a device +void printAddress(uint8_t* adress) +{ + printf("%02X",adress[0]); + printf("%02X",adress[1]); + printf("%02X",adress[2]); + printf("%02X",adress[3]); + printf("%02X",adress[4]); + printf("%02X",adress[5]); + printf("%02X",adress[6]); + printf("%02X",adress[7]); +} + +// function to print the temperature for a device +void printTemperature(DeviceAddress deviceAddress,int index) +{ + d_temp = dsensors.getTempC(deviceAddress); + dtostrf(d_temp , 6, 2, d_temp_s ); + printf("Temp C: "); + printf("%s",d_temp_s); + // copy to structure + ds1820[index].ftemp=d_temp; + strcpy(ds1820[index].stemp, d_temp_s); +} + +void printData(DeviceAddress deviceAddress, int index) +{ + printf("Device Address: "); + printAddress(deviceAddress); + printf(" "); + printTemperature(deviceAddress,index); + printf("\n"); +} + +void setup (void) +{ + // switch off the led + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, HIGH); + + printf("Dallas Temperature IC Control Library Demo"); + + // Start up the library + dsensors.begin(); + + // locate devices on the bus + printf("Locating devices...\n"); + printf("Found "); + printf("%d",dsensors.getDeviceCount()); + printf(" devices.\n"); + + // report parasite power requirements + printf("Parasite power is: "); + if (dsensors.isParasitePowerMode()) printf("ON\n"); + else printf("OFF\n"); + + // assign address manually. the addresses below will beed to be changed + // to valid device addresses on your bus. device address can be retrieved + // by using either oneWire.search(deviceAddress) or individually via + // dsensors.getAddress(deviceAddress, index) + //insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 }; + //outsideThermometer = { 0x28, 0x3F, 0x1C, 0x31, 0x2, 0x0, 0x0, 0x2 }; + + // search for devices on the bus and assign based on an index. ideally, + // you would do this to initially discover addresses on the bus and then + // use those addresses and manually assign them (see above) once you know + // the devices on your bus (and assuming they don't change). + // + // method 1: by index + if (!dsensors.getAddress(insideThermometer, 0)) printf("Unable to find address for Device 0\n"); + if (!dsensors.getAddress(outsideThermometer, 1)) printf("Unable to find address for Device 1\n"); + + // method 2: search() + // search() looks for the next device. Returns 1 if a new address has been + // returned. A zero might mean that the bus is shorted, there are no devices, + // or you have already retrieved all of them. It might be a good idea to + // check the CRC to make sure you didn't get garbage. The order is + // deterministic. You will always get the same devices in the same order + // + // Must be called before search() + //oneWire.reset_search(); + // assigns the first address found to insideThermometer + //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer"); + // assigns the seconds address found to outsideThermometer + //if (!oneWire.search(outsideThermometer)) Serial.println("Unable to find address for outsideThermometer"); + + // show the addresses we found on the bus + printf("Device 0 Address: "); + printAddress(insideThermometer); + printf("\n"); + + printf("Device 1 Address: "); + printAddress(outsideThermometer); + printf("\n"); + + // set the resolution to 9 bit + dsensors.setResolution(insideThermometer, 9); + dsensors.setResolution(outsideThermometer, 9); + + printf("Device 0 Resolution: "); + printf("%d",dsensors.getResolution(insideThermometer)); + printf("\n"); + + printf("Device 1 Resolution: "); + printf("%d",dsensors.getResolution(outsideThermometer)); + printf("\n"); + // init coap resourcen + rest_init_engine (); + rest_activate_resource (&res_dtemp1, "s/t1/temp"); + rest_activate_resource (&res_dtemp2, "s/t2/temp"); + rest_activate_resource (&res_battery, "s/batter"); +} + +// at project-conf.h +// LOOP_INTERVAL (10 * CLOCK_SECOND) +void loop (void) +{ + mcu_sleep_off(); + // call sensors.requestTemperatures() to issue a global temperature + // request to all devices on the bus + printf("Requesting temperatures..."); + dsensors.requestTemperatures(); + printf("DONE\n"); + + // print the device information + printData(insideThermometer,0); + printData(outsideThermometer,1); + mcu_sleep_on(); + +// debug only +} diff --git a/examples/osd/arduino-distance/Makefile b/examples/osd/arduino-distance/Makefile new file mode 100644 index 000000000..5a017eac0 --- /dev/null +++ b/examples/osd/arduino-distance/Makefile @@ -0,0 +1,70 @@ +# Set this to the name of your sketch (without extension .pde) +SKETCH=sketch +EXE=arduino-example + +all: $(EXE) + +CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +PROJECT_SOURCEFILES += ${SKETCH}.cpp + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) + +# variable for Makefile.include +ifneq ($(TARGET), minimal-net) +CFLAGS += -DUIP_CONF_IPV6_RPL=1 +else +# minimal-net does not support RPL under Linux and is mostly used to test CoAP only +${info INFO: compiling without RPL} +CFLAGS += -DUIP_CONF_IPV6_RPL=0 +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=640 +endif + +# linker optimizations +SMALL=1 + + +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += arduino + +include $(CONTIKI)/Makefile.include +include $(CONTIKI)/apps/arduino/Makefile.include + +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + (cd $(CONTIKI)/tools && $(MAKE) tunslip6) + +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + +connect-minimal: + sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/arduino-distance/README.md b/examples/osd/arduino-distance/README.md new file mode 100644 index 000000000..e1490ed05 --- /dev/null +++ b/examples/osd/arduino-distance/README.md @@ -0,0 +1,11 @@ +Arduino compatibility example +============================= + +This example shows that it is now possible to re-use arduino sketches in +Contiki. This example documents the necessary magic. Arduino specifies +two routines, `setup` and `loop`. Before `setup` is called, the +framework initializes hardware. In original Arduino, all this is done in +a `main` function (in C). For contiki we define a process that does the +same. + +See the documentation file in apps/contiki-compat/README.md diff --git a/examples/osd/arduino-distance/arduino-example.c b/examples/osd/arduino-distance/arduino-example.c new file mode 100644 index 000000000..ea74dd8b8 --- /dev/null +++ b/examples/osd/arduino-distance/arduino-example.c @@ -0,0 +1,2 @@ +#include +AUTOSTART_PROCESSES(&arduino_sketch); diff --git a/examples/osd/arduino-distance/flash.sh b/examples/osd/arduino-distance/flash.sh new file mode 100755 index 000000000..e82962073 --- /dev/null +++ b/examples/osd/arduino-distance/flash.sh @@ -0,0 +1,2 @@ +#!/bin/bash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/arduino-distance/project-conf.h b/examples/osd/arduino-distance/project-conf.h new file mode 100644 index 000000000..e9408e312 --- /dev/null +++ b/examples/osd/arduino-distance/project-conf.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ + +#ifndef PROJECT_RPL_WEB_CONF_H_ +#define PROJECT_RPL_WEB_CONF_H_ + +#define PLATFORM_HAS_LEDS 1 +//#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_BATTERY 1 + +#define SICSLOWPAN_CONF_FRAG 1 + +/* For Debug: Dont allow MCU sleeping between channel checks */ +//#undef RDC_CONF_MCU_SLEEP +//#define RDC_CONF_MCU_SLEEP 0 + +/* Disabling RDC for demo purposes. Core updates often require more memory. */ +/* For projects, optimize memory and enable RDC again. */ +// #undef NETSTACK_CONF_RDC +//#define NETSTACK_CONF_RDC nullrdc_driver + +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 64 + +/* Estimate your header size, especially when using Proxy-Uri. */ +/* +#undef COAP_MAX_HEADER_SIZE +#define COAP_MAX_HEADER_SIZE 70 +*/ + +/* The IP buffer size must fit all other hops, in particular the border router. */ + +#undef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 256 + + +/* Multiplies with chunk size, be aware of memory constraints. */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* +#undef COAP_MAX_OBSERVERS +#define COAP_MAX_OBSERVERS 2 +*/ + +/* Filtering .well-known/core per query can be disabled to save space. */ +/* +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +*/ + +/* Save some memory for the sky platform. */ +/* +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 10 +*/ + +/* Reduce 802.15.4 frame queue to save RAM. */ +/* +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 +*/ + +/* +#undef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +*/ + +#endif /* PROJECT_RPL_WEB_CONF_H_ */ diff --git a/examples/osd/arduino-distance/resources/res-distance.c b/examples/osd/arduino-distance/resources/res-distance.c new file mode 100644 index 000000000..71dffc49c --- /dev/null +++ b/examples/osd/arduino-distance/resources/res-distance.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Moisture resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" +#include "sketch.h" + + +#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) +#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) +#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) + +unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) +{ + // cache the port and bit of the pin in order to speed up the + // pulse width measuring loop and achieve finer resolution. calling + // digitalRead() instead yields much coarser resolution. + uint8_t bit = digitalPinToBitMask(pin); + uint8_t port = digitalPinToPort(pin); + uint8_t stateMask = (state ? bit : 0); + unsigned long width = 0; // keep initialization out of time critical area + + // convert the timeout from microseconds to a number of times through + // the initial loop; it takes 16 clock cycles per iteration. + unsigned long numloops = 0; + unsigned long maxloops = microsecondsToClockCycles(timeout) / 16; + + // wait for any previous pulse to end + while ((*portInputRegister(port) & bit) == stateMask) + if (numloops++ == maxloops) + return 0; + // wait for the pulse to start + while ((*portInputRegister(port) & bit) != stateMask) + if (numloops++ == maxloops) + return 0; + + // wait for the pulse to stop + while ((*portInputRegister(port) & bit) == stateMask) + width++; + + // convert the reading to microseconds. The loop has been determined + // to be 10 clock cycles long and have about 16 clocks between the edge + // and the start of the loop. There will be some error introduced by + // the interrupt handlers. + return clockCyclesToMicroseconds(width * 10 + 16); +} + + + + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_distance, + "title=\"Distance status\";rt=\"Distance\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + long duration, distance; + + digitalWrite(TRIG_PIN, LOW); + delayMicroseconds(2); + digitalWrite(TRIG_PIN, HIGH); + delayMicroseconds(20); + digitalWrite(TRIG_PIN, LOW); + + duration = pulseIn(ECHO_PIN, HIGH, 500000); + + // found this computation in some arduino examples + //distance = (duration/2) / 29.1; + // to get millimeters (duration -20) / 3.18 is a good approach + distance = (duration-20)/3.18; + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%ld", distance); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'distance':%ld}", distance); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} + diff --git a/examples/osd/arduino-distance/run.sh b/examples/osd/arduino-distance/run.sh new file mode 100755 index 000000000..5d5cbbbb4 --- /dev/null +++ b/examples/osd/arduino-distance/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/arduino-distance/sketch.h b/examples/osd/arduino-distance/sketch.h new file mode 100644 index 000000000..411062cd7 --- /dev/null +++ b/examples/osd/arduino-distance/sketch.h @@ -0,0 +1,17 @@ +#ifndef Sketch_h +#define Sketch_h + +// HC-SR04 Ultrasonic Ranging Module has 4 pins + +// HC-SR04 pin Vcc (needs 5v) + +// HC-SR04 pin Trig (3.3v input = Merkurboard output) +#define TRIG_PIN 19 + +// HC-SR04 pin Echo (3.3v output = Merkurboard input) +#define ECHO_PIN 20 + +// HC-SR04 pin Gnd + +#endif + diff --git a/examples/osd/arduino-distance/sketch.pde b/examples/osd/arduino-distance/sketch.pde new file mode 100644 index 000000000..11d268b1c --- /dev/null +++ b/examples/osd/arduino-distance/sketch.pde @@ -0,0 +1,46 @@ +/* + * Sample arduino sketch using contiki features. + * We turn the LED off + * We allow read the moisture sensor + * Unfortunately sleeping for long times in loop() isn't currently + * possible, something turns off the CPU (including PWM outputs) if a + * Proto-Thread is taking too long. We need to find out how to sleep in + * a Contiki-compatible way. + * Note that for a normal arduino sketch you won't have to include any + * of the contiki-specific files here, the sketch should just work. + */ + +extern "C" { +#include "arduino-process.h" +#include "sketch.h" +#include "rest-engine.h" +#include "net/netstack.h" + +extern resource_t res_battery, res_distance; +#define LED_PIN 4 /* LED Pin */ + +} + +void setup (void) +{ + NETSTACK_MAC.off(1); + + // switch off the led + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, HIGH); + // init coap resourcen + rest_init_engine (); + rest_activate_resource (&res_battery, "s/battery"); + rest_activate_resource (&res_distance, "s/distance"); + + pinMode(TRIG_PIN, OUTPUT); + pinMode(ECHO_PIN, INPUT); +} + +void loop (void) +{ + mcu_sleep_off(); + + mcu_sleep_on(); +} + diff --git a/examples/osd/arduino-dooralert/Makefile b/examples/osd/arduino-dooralert/Makefile index b8584f8f2..5a017eac0 100644 --- a/examples/osd/arduino-dooralert/Makefile +++ b/examples/osd/arduino-dooralert/Makefile @@ -1,22 +1,28 @@ # Set this to the name of your sketch (without extension .pde) SKETCH=sketch +EXE=arduino-example -all: arduino-example \ - arduino-example.osd-merkur.hex arduino-example.osd-merkur.eep - -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 - -# for some platforms -UIP_CONF_IPV6=1 -# IPv6 make config disappeared completely -CFLAGS += -DUIP_CONF_IPV6=1 +all: $(EXE) CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" -PROJECT_SOURCEFILES += resource_door.c ${SKETCH}.cpp +PROJECT_SOURCEFILES += ${SKETCH}.cpp + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) # variable for Makefile.include ifneq ($(TARGET), minimal-net) @@ -35,60 +41,15 @@ endif # linker optimizations SMALL=1 -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif -APPS += erbium time json arduino json-resource +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += arduino include $(CONTIKI)/Makefile.include include $(CONTIKI)/apps/arduino/Makefile.include -arduino-example.osd-merkur.hex: arduino-example.osd-merkur - avr-objcopy -j .text -j .data -O ihex arduino-example.osd-merkur \ - arduino-example.osd-merkur.hex - -arduino-example.osd-merkur.eep: arduino-example.osd-merkur - avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O ihex \ - arduino-example.osd-merkur arduino-example.osd-merkur.eep - -flash: arduino-example.osd-merkur.hex arduino-example.osd-merkur.eep - avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U \ - flash:w:arduino-example.osd-merkur.hex:a -U \ - eeprom:w:arduino-example.osd-merkur.eep:a - -.PHONY: flash - $(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c (cd $(CONTIKI)/tools && $(MAKE) tunslip6) @@ -100,3 +61,10 @@ connect-router-cooja: $(CONTIKI)/tools/tunslip6 connect-minimal: sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/arduino-dooralert/flash.sh b/examples/osd/arduino-dooralert/flash.sh index e9cb40bfc..e82962073 100755 --- a/examples/osd/arduino-dooralert/flash.sh +++ b/examples/osd/arduino-dooralert/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -make TARGET=osd-merkur flash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/arduino-dooralert/resource_door.c b/examples/osd/arduino-dooralert/resource_door.c deleted file mode 100644 index bda4a0afa..000000000 --- a/examples/osd/arduino-dooralert/resource_door.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * \file - * Resource for Arduino analog read - * \author - * Harald Pichler - * - * \brief get/put pwm and period for LED pin - * - */ - -#include -#include -#include -#include "contiki.h" -#include "jsonparse.h" -/* Only coap 13 for now */ -#include "er-coap-13.h" -#include "generic_resource.h" -#include "resource_door.h" -#include "Arduino.h" - -size_t -door_v (const char *name, uint8_t is_json, char *buf, size_t bufsize) -{ - door_value = digitalRead(door_pin); - return snprintf - (buf, bufsize, "%d", door_value); -} - -GENERIC_RESOURCE \ - ( door, METHOD_GET - , "door/v" - , Moisture value - , V - , NULL - , door_v - ); - -/* - * VI settings, see coding style - * ex:ts=8:et:sw=2 - */ diff --git a/examples/osd/arduino-dooralert/resource_door.h b/examples/osd/arduino-dooralert/resource_door.h deleted file mode 100644 index 951b75959..000000000 --- a/examples/osd/arduino-dooralert/resource_door.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - * \defgroup Arduino LED PWM example - * - * Resource definition for Arduino LED PWM module - * - * @{ - */ - -/** - * \file - * Resource definitions for the Arduino LED PWM module - * - * \author - * Ralf Schlatterbeck - */ - -#ifndef door_h -#define door_h -#include "contiki.h" -#include "contiki-net.h" -#include "erbium.h" -#include "er-coap-13.h" - -extern uint8_t door_pin; -extern uint16_t door_value; - -extern resource_t resource_door; - -#endif // door_h -/** @} */ diff --git a/examples/osd/arduino-dooralert/resources/res-door.c b/examples/osd/arduino-dooralert/resources/res-door.c new file mode 100644 index 000000000..97a5e9b72 --- /dev/null +++ b/examples/osd/arduino-dooralert/resources/res-door.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Door resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_door, + "title=\"Moisture status\";rt=\"Moisture\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern uint8_t door_pin; +extern uint8_t door_status; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + door_status = digitalRead(door_pin); + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", door_status); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'door':%d}", door_status); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-dooralert/run.sh b/examples/osd/arduino-dooralert/run.sh index 295a9ab1d..5d5cbbbb4 100755 --- a/examples/osd/arduino-dooralert/run.sh +++ b/examples/osd/arduino-dooralert/run.sh @@ -1,5 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/arduino-dooralert/sketch.pde b/examples/osd/arduino-dooralert/sketch.pde index a2f439ce8..d7de583c8 100644 --- a/examples/osd/arduino-dooralert/sketch.pde +++ b/examples/osd/arduino-dooralert/sketch.pde @@ -1,7 +1,7 @@ /* * Sample arduino sketch using contiki features. * We turn the LED off - * We allow read the water sensor + * We allow read the moisture sensor * Unfortunately sleeping for long times in loop() isn't currently * possible, something turns off the CPU (including PWM outputs) if a * Proto-Thread is taking too long. We need to find out how to sleep in @@ -11,24 +11,31 @@ */ extern "C" { -#include -#include "resource_door.h" +#include "arduino-process.h" +#include "rest-engine.h" + +extern resource_t res_door, res_battery; +uint8_t door_pin = 3; +uint8_t door_status = 0; #define LED_PIN 4 - -uint8_t door_pin = A5; -uint16_t door_value = 0; } void setup (void) { + // switch off the led pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, HIGH); + // init coap resourcen rest_init_engine (); - rest_activate_resource (&resource_door); + rest_activate_resource (&res_door, "s/door"); + rest_activate_resource (&res_battery, "s/battery"); + // NETSTACK_MAC.off(1); } void loop (void) { - + mcu_sleep_off(); + + mcu_sleep_on(); } diff --git a/examples/osd/arduino-htu21/Adafruit_HTU21DF.cpp b/examples/osd/arduino-htu21/Adafruit_HTU21DF.cpp new file mode 100644 index 000000000..84bbeb066 --- /dev/null +++ b/examples/osd/arduino-htu21/Adafruit_HTU21DF.cpp @@ -0,0 +1,100 @@ +/*************************************************** + This is a library for the HTU21DF Humidity & Temp Sensor + + Designed specifically to work with the HTU21DF sensor from Adafruit + ----> https://www.adafruit.com/products/1899 + + These displays use I2C to communicate, 2 pins are required to + interface + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ****************************************************/ + +#include "Adafruit_HTU21DF.h" +#if defined(__AVR__) +#include +#endif + +Adafruit_HTU21DF::Adafruit_HTU21DF() { +} + + +boolean Adafruit_HTU21DF::begin(void) { + Wire.begin(); + + reset(); + + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_READREG); + Wire.endTransmission(); + Wire.requestFrom(HTU21DF_I2CADDR, 1); + return (Wire.read() == 0x2); // after reset should be 0x2 +} + +void Adafruit_HTU21DF::reset(void) { + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_RESET); + Wire.endTransmission(); + delay(15); +} + + +float Adafruit_HTU21DF::readTemperature(void) { + + // OK lets ready! + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_READTEMP); + Wire.endTransmission(); + + delay(50); // add delay between request and actual read! + + Wire.requestFrom(HTU21DF_I2CADDR, 3); + while (!Wire.available()) {} + + uint16_t t = Wire.read(); + t <<= 8; + t |= Wire.read(); + + uint8_t crc = Wire.read(); + + float temp = t; + temp *= 175.72; + temp /= 65536; + temp -= 46.85; + + return temp; +} + + +float Adafruit_HTU21DF::readHumidity(void) { + // OK lets ready! + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_READHUM); + Wire.endTransmission(); + + delay(50); // add delay between request and actual read! + + Wire.requestFrom(HTU21DF_I2CADDR, 3); + while (!Wire.available()) {} + + uint16_t h = Wire.read(); + h <<= 8; + h |= Wire.read(); + + uint8_t crc = Wire.read(); + + float hum = h; + hum *= 125; + hum /= 65536; + hum -= 6; + + return hum; +} + + + +/*********************************************************************/ diff --git a/examples/osd/arduino-htu21/Adafruit_HTU21DF.h b/examples/osd/arduino-htu21/Adafruit_HTU21DF.h new file mode 100644 index 000000000..fe8870e39 --- /dev/null +++ b/examples/osd/arduino-htu21/Adafruit_HTU21DF.h @@ -0,0 +1,44 @@ +/*************************************************** + This is a library for the HTU21D-F Humidity & Temp Sensor + + Designed specifically to work with the HTU21D-F sensor from Adafruit + ----> https://www.adafruit.com/products/1899 + + These displays use I2C to communicate, 2 pins are required to + interface + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ****************************************************/ + +//#if (ARDUINO >= 100) + #include "Arduino.h" +//#else +// #include "WProgram.h" +//#endif +#include "Wire.h" + +#define HTU21DF_I2CADDR 0x40 +#define HTU21DF_READTEMP 0xE3 +#define HTU21DF_READHUM 0xE5 +#define HTU21DF_WRITEREG 0xE6 +#define HTU21DF_READREG 0xE7 +#define HTU21DF_RESET 0xFE + + + +class Adafruit_HTU21DF { + public: + Adafruit_HTU21DF(); + boolean begin(void); + float readTemperature(void); + float readHumidity(void); + void reset(void); + private: + boolean readData(void); + float humidity, temp; +}; + diff --git a/examples/osd/arduino-htu21/Adafruit_HTU21DF_Library-master/Adafruit_HTU21DF.cpp b/examples/osd/arduino-htu21/Adafruit_HTU21DF_Library-master/Adafruit_HTU21DF.cpp new file mode 100644 index 000000000..84bbeb066 --- /dev/null +++ b/examples/osd/arduino-htu21/Adafruit_HTU21DF_Library-master/Adafruit_HTU21DF.cpp @@ -0,0 +1,100 @@ +/*************************************************** + This is a library for the HTU21DF Humidity & Temp Sensor + + Designed specifically to work with the HTU21DF sensor from Adafruit + ----> https://www.adafruit.com/products/1899 + + These displays use I2C to communicate, 2 pins are required to + interface + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ****************************************************/ + +#include "Adafruit_HTU21DF.h" +#if defined(__AVR__) +#include +#endif + +Adafruit_HTU21DF::Adafruit_HTU21DF() { +} + + +boolean Adafruit_HTU21DF::begin(void) { + Wire.begin(); + + reset(); + + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_READREG); + Wire.endTransmission(); + Wire.requestFrom(HTU21DF_I2CADDR, 1); + return (Wire.read() == 0x2); // after reset should be 0x2 +} + +void Adafruit_HTU21DF::reset(void) { + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_RESET); + Wire.endTransmission(); + delay(15); +} + + +float Adafruit_HTU21DF::readTemperature(void) { + + // OK lets ready! + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_READTEMP); + Wire.endTransmission(); + + delay(50); // add delay between request and actual read! + + Wire.requestFrom(HTU21DF_I2CADDR, 3); + while (!Wire.available()) {} + + uint16_t t = Wire.read(); + t <<= 8; + t |= Wire.read(); + + uint8_t crc = Wire.read(); + + float temp = t; + temp *= 175.72; + temp /= 65536; + temp -= 46.85; + + return temp; +} + + +float Adafruit_HTU21DF::readHumidity(void) { + // OK lets ready! + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_READHUM); + Wire.endTransmission(); + + delay(50); // add delay between request and actual read! + + Wire.requestFrom(HTU21DF_I2CADDR, 3); + while (!Wire.available()) {} + + uint16_t h = Wire.read(); + h <<= 8; + h |= Wire.read(); + + uint8_t crc = Wire.read(); + + float hum = h; + hum *= 125; + hum /= 65536; + hum -= 6; + + return hum; +} + + + +/*********************************************************************/ diff --git a/examples/osd/arduino-htu21/Adafruit_HTU21DF_Library-master/Adafruit_HTU21DF.h b/examples/osd/arduino-htu21/Adafruit_HTU21DF_Library-master/Adafruit_HTU21DF.h new file mode 100644 index 000000000..b80698cb8 --- /dev/null +++ b/examples/osd/arduino-htu21/Adafruit_HTU21DF_Library-master/Adafruit_HTU21DF.h @@ -0,0 +1,44 @@ +/*************************************************** + This is a library for the HTU21D-F Humidity & Temp Sensor + + Designed specifically to work with the HTU21D-F sensor from Adafruit + ----> https://www.adafruit.com/products/1899 + + These displays use I2C to communicate, 2 pins are required to + interface + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ****************************************************/ + +#if (ARDUINO >= 100) + #include "Arduino.h" +#else + #include "WProgram.h" +#endif +#include "Wire.h" + +#define HTU21DF_I2CADDR 0x40 +#define HTU21DF_READTEMP 0xE3 +#define HTU21DF_READHUM 0xE5 +#define HTU21DF_WRITEREG 0xE6 +#define HTU21DF_READREG 0xE7 +#define HTU21DF_RESET 0xFE + + + +class Adafruit_HTU21DF { + public: + Adafruit_HTU21DF(); + boolean begin(void); + float readTemperature(void); + float readHumidity(void); + void reset(void); + private: + boolean readData(void); + float humidity, temp; +}; + diff --git a/examples/osd/arduino-htu21/Adafruit_HTU21DF_Library-master/README.txt b/examples/osd/arduino-htu21/Adafruit_HTU21DF_Library-master/README.txt new file mode 100644 index 000000000..5d41f6d26 --- /dev/null +++ b/examples/osd/arduino-htu21/Adafruit_HTU21DF_Library-master/README.txt @@ -0,0 +1,24 @@ +This is a library for the HTU21D-F Humidity + Temp sensor + +Designed specifically to work with the HTU21D-F in the Adafruit shop + ----> https://www.adafruit.com/products/1899 + +These displays use I2C to communicate, 2 pins are required to interface +Adafruit invests time and resources providing this open source code, +please support Adafruit and open-source hardware by purchasing +products from Adafruit! + +Written by Limor Fried/Ladyada for Adafruit Industries. +BSD license, all text above must be included in any redistribution + +Check out the links above for our tutorials and wiring diagrams + +To download. click the ZIP button in the top-middle navbar, +rename the uncompressed folder Adafruit_HTU21DF. +Check that the Adafruit_HTU21DF folder contains Adafruit_HTU21DF.cpp and Adafruit_HTU21DF.h + +Place the Adafruit_HTU21DF library folder your arduinosketchfolder/libraries/ folder. +You may need to create the libraries subfolder if its your first library. Restart the IDE. + +We also have a great tutorial on Arduino library installation at: +http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use \ No newline at end of file diff --git a/examples/osd/arduino-htu21/Adafruit_HTU21DF_Library-master/examples/HTU21DFtest/HTU21DFtest.ino b/examples/osd/arduino-htu21/Adafruit_HTU21DF_Library-master/examples/HTU21DFtest/HTU21DFtest.ino new file mode 100644 index 000000000..543a1fe5e --- /dev/null +++ b/examples/osd/arduino-htu21/Adafruit_HTU21DF_Library-master/examples/HTU21DFtest/HTU21DFtest.ino @@ -0,0 +1,36 @@ +/*************************************************** + This is an example for the HTU21D-F Humidity & Temp Sensor + + Designed specifically to work with the HTU21D-F sensor from Adafruit + ----> https://www.adafruit.com/products/1899 + + These displays use I2C to communicate, 2 pins are required to + interface + ****************************************************/ + +#include +#include "Adafruit_HTU21DF.h" + +// Connect Vin to 3-5VDC +// Connect GND to ground +// Connect SCL to I2C clock pin (A5 on UNO) +// Connect SDA to I2C data pin (A4 on UNO) + +Adafruit_HTU21DF htu = Adafruit_HTU21DF(); + +void setup() { + Serial.begin(9600); + Serial.println("HTU21D-F test"); + + if (!htu.begin()) { + Serial.println("Couldn't find sensor!"); + while (1); + } +} + + +void loop() { + Serial.print("Temp: "); Serial.print(htu.readTemperature()); + Serial.print("\t\tHum: "); Serial.println(htu.readHumidity()); + delay(500); +} \ No newline at end of file diff --git a/examples/osd/arduino-htu21/Adafruit_HTU21DF_Library-master/library.properties b/examples/osd/arduino-htu21/Adafruit_HTU21DF_Library-master/library.properties new file mode 100644 index 000000000..a8c8478ae --- /dev/null +++ b/examples/osd/arduino-htu21/Adafruit_HTU21DF_Library-master/library.properties @@ -0,0 +1,9 @@ +name=Adafruit HTU21DF Library +version=1.0.0 +author=Adafruit +maintainer=Adafruit +sentence=Arduino library for the HTU21D-F sensors in the Adafruit shop +paragraph=Arduino library for the HTU21D-F sensors in the Adafruit shop +category=Sensors +url=https://github.com/adafruit/Adafruit_HTU21DF_Library +architectures=* diff --git a/examples/osd/arduino-htu21/Makefile b/examples/osd/arduino-htu21/Makefile new file mode 100644 index 000000000..b44ef11f1 --- /dev/null +++ b/examples/osd/arduino-htu21/Makefile @@ -0,0 +1,71 @@ +# Set this to the name of your sketch (without extension .pde) +SKETCH=sketch +EXE=arduino-example + +all: $(EXE) + +CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +LFLAGS += -lm + +PROJECT_SOURCEFILES += ${SKETCH}.cpp Adafruit_HTU21DF.cpp + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) + +# variable for Makefile.include +ifneq ($(TARGET), minimal-net) +CFLAGS += -DUIP_CONF_IPV6_RPL=1 +else +# minimal-net does not support RPL under Linux and is mostly used to test CoAP only +${info INFO: compiling without RPL} +CFLAGS += -DUIP_CONF_IPV6_RPL=0 +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=640 +endif + +# linker optimizations +SMALL=1 + + +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += arduino + +include $(CONTIKI)/Makefile.include +include $(CONTIKI)/apps/arduino/Makefile.include + +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + (cd $(CONTIKI)/tools && $(MAKE) tunslip6) + +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + +connect-minimal: + sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/arduino-htu21/README.md b/examples/osd/arduino-htu21/README.md new file mode 100644 index 000000000..e1490ed05 --- /dev/null +++ b/examples/osd/arduino-htu21/README.md @@ -0,0 +1,11 @@ +Arduino compatibility example +============================= + +This example shows that it is now possible to re-use arduino sketches in +Contiki. This example documents the necessary magic. Arduino specifies +two routines, `setup` and `loop`. Before `setup` is called, the +framework initializes hardware. In original Arduino, all this is done in +a `main` function (in C). For contiki we define a process that does the +same. + +See the documentation file in apps/contiki-compat/README.md diff --git a/examples/osd/arduino-htu21/arduino-example.c b/examples/osd/arduino-htu21/arduino-example.c new file mode 100644 index 000000000..ea74dd8b8 --- /dev/null +++ b/examples/osd/arduino-htu21/arduino-example.c @@ -0,0 +1,2 @@ +#include +AUTOSTART_PROCESSES(&arduino_sketch); diff --git a/examples/osd/arduino-htu21/flash.sh b/examples/osd/arduino-htu21/flash.sh new file mode 100755 index 000000000..e82962073 --- /dev/null +++ b/examples/osd/arduino-htu21/flash.sh @@ -0,0 +1,2 @@ +#!/bin/bash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/arduino-htu21/project-conf.h b/examples/osd/arduino-htu21/project-conf.h new file mode 100644 index 000000000..e25aed53c --- /dev/null +++ b/examples/osd/arduino-htu21/project-conf.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ + +#ifndef PROJECT_RPL_WEB_CONF_H_ +#define PROJECT_RPL_WEB_CONF_H_ + +#define PLATFORM_HAS_LEDS 1 +//#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_BATTERY 1 + +#define SICSLOWPAN_CONF_FRAG 1 + +#define LOOP_INTERVAL (10 * CLOCK_SECOND) + +/* Save energy */ +//#define RDC_CONF_PT_YIELD_OFF + +/* For Debug: Dont allow MCU sleeping between channel checks */ +//#undef RDC_CONF_MCU_SLEEP +//#define RDC_CONF_MCU_SLEEP 0 + +/* Disabling RDC for demo purposes. Core updates often require more memory. */ +/* For projects, optimize memory and enable RDC again. */ +// #undef NETSTACK_CONF_RDC +//#define NETSTACK_CONF_RDC nullrdc_driver + +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 64 + +/* Estimate your header size, especially when using Proxy-Uri. */ +/* +#undef COAP_MAX_HEADER_SIZE +#define COAP_MAX_HEADER_SIZE 70 +*/ + +/* The IP buffer size must fit all other hops, in particular the border router. */ + +#undef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 256 + + +/* Multiplies with chunk size, be aware of memory constraints. */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* +#undef COAP_MAX_OBSERVERS +#define COAP_MAX_OBSERVERS 2 +*/ + +/* Filtering .well-known/core per query can be disabled to save space. */ +/* +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +*/ + +/* Save some memory for the sky platform. */ +/* +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 10 +*/ + +/* Reduce 802.15.4 frame queue to save RAM. */ +/* +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 +*/ + +/* +#undef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +*/ + +#endif /* PROJECT_RPL_WEB_CONF_H_ */ diff --git a/examples/osd/arduino-htu21/resources/res-htu21dhum.c b/examples/osd/arduino-htu21/resources/res-htu21dhum.c new file mode 100644 index 000000000..f66c71c74 --- /dev/null +++ b/examples/osd/arduino-htu21/resources/res-htu21dhum.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Moisture resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_htu21dhum, + "title=\"Moisture status\";rt=\"Moisture\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern char htu21d_hum_s[8]; + + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", htu21d_hum_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'moisture':%s}", htu21d_hum_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-htu21/resources/res-htu21dtemp.c b/examples/osd/arduino-htu21/resources/res-htu21dtemp.c new file mode 100644 index 000000000..cdc9a9a7d --- /dev/null +++ b/examples/osd/arduino-htu21/resources/res-htu21dtemp.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Moisture resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_htu21dtemp, + "title=\"Temperature status\";rt=\"Temperatur\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern char htu21d_temp_s[8]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", htu21d_temp_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%s}", htu21d_temp_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-htu21/run.sh b/examples/osd/arduino-htu21/run.sh new file mode 100755 index 000000000..5d5cbbbb4 --- /dev/null +++ b/examples/osd/arduino-htu21/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/arduino-htu21/sketch.pde b/examples/osd/arduino-htu21/sketch.pde new file mode 100644 index 000000000..4ea3500ea --- /dev/null +++ b/examples/osd/arduino-htu21/sketch.pde @@ -0,0 +1,68 @@ +/* + * Sample arduino sketch using contiki features. + * We turn the LED off + * We allow read the moisture sensor + * Unfortunately sleeping for long times in loop() isn't currently + * possible, something turns off the CPU (including PWM outputs) if a + * Proto-Thread is taking too long. We need to find out how to sleep in + * a Contiki-compatible way. + * Note that for a normal arduino sketch you won't have to include any + * of the contiki-specific files here, the sketch should just work. + */ + +#include +#include "Adafruit_HTU21DF.h" + +extern "C" { +#include "arduino-process.h" +#include "rest-engine.h" + +Adafruit_HTU21DF htu = Adafruit_HTU21DF(); + +extern resource_t res_htu21dtemp, res_htu21dhum, res_battery; +float htu21d_hum; +float htu21d_temp; +char htu21d_hum_s[8]; +char htu21d_temp_s[8]; + +#define LED_PIN 4 +} + +void setup (void) +{ + // switch off the led + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, HIGH); + // htu21d sensor + if (!htu.begin()) { + printf("Couldn't find sensor!"); + } + // init coap resourcen + rest_init_engine (); + rest_activate_resource (&res_htu21dtemp, "s/temp"); + rest_activate_resource (&res_htu21dhum, "s/hum"); + rest_activate_resource (&res_battery, "s/battery"); +} + +// at project-conf.h +// LOOP_INTERVAL (10 * CLOCK_SECOND) +void loop (void) +{ + mcu_sleep_off(); + htu21d_temp = htu.readTemperature(); + htu21d_hum = htu.readHumidity(); + mcu_sleep_on(); + dtostrf(htu21d_temp , 6, 2, htu21d_temp_s ); + dtostrf(htu21d_hum , 6, 2, htu21d_hum_s ); + // remove space + if(htu21d_temp_s[0]==' '){ + memcpy (htu21d_temp_s,htu21d_temp_s+1,strlen(htu21d_temp_s)+1); + } + if(htu21d_hum_s[0]==' '){ + memcpy (htu21d_hum_s,htu21d_hum_s+1,strlen(htu21d_hum_s)+1); + } + +// debug only +// printf("Temp: %s",htu21d_temp_s); +// printf("\t\tHum: %s\n",htu21d_hum_s); +} diff --git a/examples/osd/arduino-ledstrip/LEDStripDriver/README.txt b/examples/osd/arduino-ledstrip/LEDStripDriver/README.txt new file mode 100644 index 000000000..0e8aab949 --- /dev/null +++ b/examples/osd/arduino-ledstrip/LEDStripDriver/README.txt @@ -0,0 +1,16 @@ +//*********************************************************************** +// +// Name:LEDStripDriver liararies v0.9b for Grove - LED Strip Driver v0.9b +// Author:Frankie.Chu at Seeed Studio. +// Date:March 9,2012 +// Version:0.9b +// Software platform:Arduino-1.0 +// Hardware platform:Arduino UNO/Seeeduino/Arduino Mega + +// Grove - LED Strip Driver v0.9b +// Demo code: +// DualLEDStrip:Light the two LED strips with two driver. +// SingleLEDStrip:Light the single LED strip. +// DemoForWhiteLEDStrip:Light the White LED Flexi-Strip. +// Default:"-"pin of it is connected to "B" of the driver. +// +//*********************************************************************** \ No newline at end of file diff --git a/examples/osd/arduino-ledstrip/LEDStripDriver/RGBdriver.cpp b/examples/osd/arduino-ledstrip/LEDStripDriver/RGBdriver.cpp new file mode 100644 index 000000000..9f3e85307 --- /dev/null +++ b/examples/osd/arduino-ledstrip/LEDStripDriver/RGBdriver.cpp @@ -0,0 +1,107 @@ +// 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 +// Modified Record: +/***************************************************************************/ +#include "RGBdriver.h" +RGBdriver::RGBdriver(uint8_t Clk, uint8_t Data) +{ + Clkpin = Clk; + Datapin = Data; + pinMode(Datapin, OUTPUT); + pinMode(Clkpin, OUTPUT); +} + +void RGBdriver::begin(void) +{ + Send32Zero(); +} + +void RGBdriver::end(void) +{ + Send32Zero(); +} + +void RGBdriver::ClkRise(void) +{ + digitalWrite(Clkpin, LOW); + delayMicroseconds(20); + digitalWrite(Clkpin, HIGH); + delayMicroseconds(20); +} + +void RGBdriver::Send32Zero(void) +{ + unsigned char i; + + for (i=0; i<32; i++) + { + digitalWrite(Datapin, LOW); + ClkRise(); + } +} + +uint8_t RGBdriver::TakeAntiCode(uint8_t dat) +{ + uint8_t tmp = 0; + + if ((dat & 0x80) == 0) + { + tmp |= 0x02; + } + + if ((dat & 0x40) == 0) + { + tmp |= 0x01; + } + + return tmp; +} + +// gray data +void RGBdriver::DatSend(uint32_t dx) +{ + uint8_t i; + + for (i=0; i<32; i++) + { + if ((dx & 0x80000000) != 0) + { + digitalWrite(Datapin, HIGH); + } + else + { + digitalWrite(Datapin, LOW); + } + + dx <<= 1; + ClkRise(); + } +} + +// Set color +void RGBdriver::SetColor(uint8_t Red,uint8_t Green,uint8_t Blue) +{ + uint32_t dx = 0; + + dx |= (uint32_t)0x03 << 30; // highest two bits 1,flag bits + dx |= (uint32_t)TakeAntiCode(Blue) << 28; + dx |= (uint32_t)TakeAntiCode(Green) << 26; + dx |= (uint32_t)TakeAntiCode(Red) << 24; + + dx |= (uint32_t)Blue << 16; + dx |= (uint32_t)Green << 8; + dx |= Red; + + DatSend(dx); +} diff --git a/examples/osd/arduino-ledstrip/LEDStripDriver/RGBdriver.h b/examples/osd/arduino-ledstrip/LEDStripDriver/RGBdriver.h new file mode 100644 index 000000000..58fb5385c --- /dev/null +++ b/examples/osd/arduino-ledstrip/LEDStripDriver/RGBdriver.h @@ -0,0 +1,20 @@ +#ifndef RGB_DRIVER_H +#define RGB_DRIVER_H +#include +#include +class RGBdriver +{ + public: + RGBdriver(uint8_t, uint8_t); + void begin(void); + void end(void); + void ClkRise(void); + void Send32Zero(void); + uint8_t TakeAntiCode(uint8_t dat); + void DatSend(uint32_t dx); + void SetColor(uint8_t Red,uint8_t Green,uint8_t Blue); + private: + uint8_t Clkpin; + uint8_t Datapin; +}; +#endif diff --git a/examples/osd/arduino-ledstrip/LEDStripDriver/examples/DemoForWhiteLEDStrip/DemoForWhiteLEDStrip.ino b/examples/osd/arduino-ledstrip/LEDStripDriver/examples/DemoForWhiteLEDStrip/DemoForWhiteLEDStrip.ino new file mode 100644 index 000000000..78901bed1 --- /dev/null +++ b/examples/osd/arduino-ledstrip/LEDStripDriver/examples/DemoForWhiteLEDStrip/DemoForWhiteLEDStrip.ino @@ -0,0 +1,44 @@ +// Author:Frankie.Chu +// Date:March 9,2012 +// 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 +/***************************************************************************/ +#include "RGBdriver.h" +#define CLK 2//pins definitions for the driver +#define DIO 3 +RGBdriver Driver(CLK,DIO); +void setup() +{ + +} +void loop() +{ + unsigned int i; + while(1){ + for(i = 0;i < 256;i ++) + { + Driver.begin(); // begin + Driver.SetColor(0,0,i); //Blue. First node data. SetColor(R,G,B) + Driver.end(); + delay(10); + } + for(i = 255;i > 0;i --) + { + Driver.begin(); // begin + Driver.SetColor(0,0,i); //Blue. first node data + Driver.end(); + delay(10); + } + } +} diff --git a/examples/osd/arduino-ledstrip/LEDStripDriver/examples/DualLEDStrip/DualLEDStrip.ino b/examples/osd/arduino-ledstrip/LEDStripDriver/examples/DualLEDStrip/DualLEDStrip.ino new file mode 100644 index 000000000..f07ff7221 --- /dev/null +++ b/examples/osd/arduino-ledstrip/LEDStripDriver/examples/DualLEDStrip/DualLEDStrip.ino @@ -0,0 +1,42 @@ +// Author:Frankie.Chu +// Date:March 9,2012 +// 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 +/***************************************************************************/ +#include "RGBdriver.h" +#define CLK 2//pins definitions for the driver +#define DIO 3 +RGBdriver Driver(CLK,DIO); +void setup() +{ + +} +void loop() +{ + Driver.begin(); // begin + Driver.SetColor(255, 0, 0); //Red. first node data + Driver.SetColor(0, 0, 255); //Blue. second node data + Driver.end(); + delay(500); + Driver.begin(); // begin + Driver.SetColor(0, 0, 255); //Blue. first node data + Driver.SetColor(0, 255, 0); //Green. second node data + Driver.end(); + delay(500); + Driver.begin(); // begin + Driver.SetColor(0, 255, 0); //Green. first node data + Driver.SetColor(255, 0, 0); //Red. second node data + Driver.end(); + delay(500); +} diff --git a/examples/osd/arduino-ledstrip/LEDStripDriver/examples/SingleLEDStrip/SingleLEDStrip.ino b/examples/osd/arduino-ledstrip/LEDStripDriver/examples/SingleLEDStrip/SingleLEDStrip.ino new file mode 100644 index 000000000..55800336f --- /dev/null +++ b/examples/osd/arduino-ledstrip/LEDStripDriver/examples/SingleLEDStrip/SingleLEDStrip.ino @@ -0,0 +1,39 @@ +// Author:Frankie.Chu +// Date:March 9,2012 +// 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 +/***************************************************************************/ +#include "RGBdriver.h" +#define CLK 2//pins definitions for the driver +#define DIO 3 +RGBdriver Driver(CLK,DIO); +void setup() +{ + +} +void loop() +{ + Driver.begin(); // begin + Driver.SetColor(255, 0, 0); //Red. first node data + Driver.end(); + delay(500); + Driver.begin(); // begin + Driver.SetColor(0, 255, 0); //Green. first node data + Driver.end(); + delay(500); + Driver.begin(); // begin + Driver.SetColor(0, 0, 255);//Blue. first node data + Driver.end(); + delay(500); +} diff --git a/examples/osd/arduino-ledstrip/Makefile b/examples/osd/arduino-ledstrip/Makefile new file mode 100644 index 000000000..f03fdfc85 --- /dev/null +++ b/examples/osd/arduino-ledstrip/Makefile @@ -0,0 +1,71 @@ +# Set this to the name of your sketch (without extension .pde) +SKETCH=sketch +EXE=arduino-example + +all: $(EXE) + +CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +PROJECT_SOURCEFILES += ${SKETCH}.cpp RGBdriver.cpp + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) + +# variable for Makefile.include +ifneq ($(TARGET), minimal-net) +CFLAGS += -DUIP_CONF_IPV6_RPL=1 +else +# minimal-net does not support RPL under Linux and is mostly used to test CoAP only +${info INFO: compiling without RPL} +CFLAGS += -DUIP_CONF_IPV6_RPL=0 +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=640 +endif + +# linker optimizations +SMALL=1 + + +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += arduino +APPS += json json-resource + +include $(CONTIKI)/Makefile.include +include $(CONTIKI)/apps/arduino/Makefile.include + +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + (cd $(CONTIKI)/tools && $(MAKE) tunslip6) + +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + +connect-minimal: + sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/arduino-ledstrip/README.md b/examples/osd/arduino-ledstrip/README.md new file mode 100644 index 000000000..e1490ed05 --- /dev/null +++ b/examples/osd/arduino-ledstrip/README.md @@ -0,0 +1,11 @@ +Arduino compatibility example +============================= + +This example shows that it is now possible to re-use arduino sketches in +Contiki. This example documents the necessary magic. Arduino specifies +two routines, `setup` and `loop`. Before `setup` is called, the +framework initializes hardware. In original Arduino, all this is done in +a `main` function (in C). For contiki we define a process that does the +same. + +See the documentation file in apps/contiki-compat/README.md diff --git a/examples/osd/arduino-ledstrip/README.txt b/examples/osd/arduino-ledstrip/README.txt new file mode 100644 index 000000000..0e8aab949 --- /dev/null +++ b/examples/osd/arduino-ledstrip/README.txt @@ -0,0 +1,16 @@ +//*********************************************************************** +// +// Name:LEDStripDriver liararies v0.9b for Grove - LED Strip Driver v0.9b +// Author:Frankie.Chu at Seeed Studio. +// Date:March 9,2012 +// Version:0.9b +// Software platform:Arduino-1.0 +// Hardware platform:Arduino UNO/Seeeduino/Arduino Mega + +// Grove - LED Strip Driver v0.9b +// Demo code: +// DualLEDStrip:Light the two LED strips with two driver. +// SingleLEDStrip:Light the single LED strip. +// DemoForWhiteLEDStrip:Light the White LED Flexi-Strip. +// Default:"-"pin of it is connected to "B" of the driver. +// +//*********************************************************************** \ No newline at end of file diff --git a/examples/osd/arduino-ledstrip/RGBdriver.cpp b/examples/osd/arduino-ledstrip/RGBdriver.cpp new file mode 100644 index 000000000..510a8f0ab --- /dev/null +++ b/examples/osd/arduino-ledstrip/RGBdriver.cpp @@ -0,0 +1,116 @@ +// 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 +// Modified Record: +/***************************************************************************/ +#include "RGBdriver.h" + +RGBdriver::RGBdriver(uint8_t Clk, uint8_t Data) +{ + Clkpin = Clk; + Datapin = Data; + pinMode(Datapin, OUTPUT); + pinMode(Clkpin, OUTPUT); +} + +void RGBdriver::begin(void) +{ + Send32Zero(); +} + +void RGBdriver::end(void) +{ + Send32Zero(); +} + +void RGBdriver::ClkRise(void) +{ + + digitalWrite(Clkpin, LOW); + delayMicroseconds(20); + digitalWrite(Clkpin, HIGH); + delayMicroseconds(20); + +} + +void RGBdriver::Send32Zero(void) +{ + unsigned char i; + uint8_t volatile sreg; + sreg = SREG; /* Save status register before disabling interrupts. */ + cli(); /* Disable interrupts. */ + for (i=0; i<32; i++) + { + digitalWrite(Datapin, LOW); + ClkRise(); + } + SREG = sreg; /* Enable interrupts. */ +} + +uint8_t RGBdriver::TakeAntiCode(uint8_t dat) +{ + uint8_t tmp = 0; + + if ((dat & 0x80) == 0) + { + tmp |= 0x02; + } + + if ((dat & 0x40) == 0) + { + tmp |= 0x01; + } + + return tmp; +} + +// gray data +void RGBdriver::DatSend(uint32_t dx) +{ + uint8_t i; + uint8_t volatile sreg; + sreg = SREG; /* Save status register before disabling interrupts. */ + cli(); /* Disable interrupts. */ + for (i=0; i<32; i++) + { + if ((dx & 0x80000000) != 0) + { + digitalWrite(Datapin, HIGH); + } + else + { + digitalWrite(Datapin, LOW); + } + + dx <<= 1; + ClkRise(); + } + SREG = sreg; /* Enable interrupts. */ +} + +// Set color +void RGBdriver::SetColor(uint8_t Red,uint8_t Green,uint8_t Blue) +{ + uint32_t dx = 0; + + dx |= (uint32_t)0x03 << 30; // highest two bits 1,flag bits + dx |= (uint32_t)TakeAntiCode(Blue) << 28; + dx |= (uint32_t)TakeAntiCode(Green) << 26; + dx |= (uint32_t)TakeAntiCode(Red) << 24; + + dx |= (uint32_t)Blue << 16; + dx |= (uint32_t)Green << 8; + dx |= Red; + + DatSend(dx); +} diff --git a/examples/osd/arduino-ledstrip/RGBdriver.h b/examples/osd/arduino-ledstrip/RGBdriver.h new file mode 100644 index 000000000..58fb5385c --- /dev/null +++ b/examples/osd/arduino-ledstrip/RGBdriver.h @@ -0,0 +1,20 @@ +#ifndef RGB_DRIVER_H +#define RGB_DRIVER_H +#include +#include +class RGBdriver +{ + public: + RGBdriver(uint8_t, uint8_t); + void begin(void); + void end(void); + void ClkRise(void); + void Send32Zero(void); + uint8_t TakeAntiCode(uint8_t dat); + void DatSend(uint32_t dx); + void SetColor(uint8_t Red,uint8_t Green,uint8_t Blue); + private: + uint8_t Clkpin; + uint8_t Datapin; +}; +#endif diff --git a/examples/osd/arduino-ledstrip/arduino-example.c b/examples/osd/arduino-ledstrip/arduino-example.c new file mode 100644 index 000000000..ea74dd8b8 --- /dev/null +++ b/examples/osd/arduino-ledstrip/arduino-example.c @@ -0,0 +1,2 @@ +#include +AUTOSTART_PROCESSES(&arduino_sketch); diff --git a/examples/osd/arduino-ledstrip/flash.sh b/examples/osd/arduino-ledstrip/flash.sh new file mode 100755 index 000000000..e82962073 --- /dev/null +++ b/examples/osd/arduino-ledstrip/flash.sh @@ -0,0 +1,2 @@ +#!/bin/bash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/arduino-ledstrip/project-conf.h b/examples/osd/arduino-ledstrip/project-conf.h new file mode 100644 index 000000000..e9408e312 --- /dev/null +++ b/examples/osd/arduino-ledstrip/project-conf.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ + +#ifndef PROJECT_RPL_WEB_CONF_H_ +#define PROJECT_RPL_WEB_CONF_H_ + +#define PLATFORM_HAS_LEDS 1 +//#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_BATTERY 1 + +#define SICSLOWPAN_CONF_FRAG 1 + +/* For Debug: Dont allow MCU sleeping between channel checks */ +//#undef RDC_CONF_MCU_SLEEP +//#define RDC_CONF_MCU_SLEEP 0 + +/* Disabling RDC for demo purposes. Core updates often require more memory. */ +/* For projects, optimize memory and enable RDC again. */ +// #undef NETSTACK_CONF_RDC +//#define NETSTACK_CONF_RDC nullrdc_driver + +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 64 + +/* Estimate your header size, especially when using Proxy-Uri. */ +/* +#undef COAP_MAX_HEADER_SIZE +#define COAP_MAX_HEADER_SIZE 70 +*/ + +/* The IP buffer size must fit all other hops, in particular the border router. */ + +#undef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 256 + + +/* Multiplies with chunk size, be aware of memory constraints. */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* +#undef COAP_MAX_OBSERVERS +#define COAP_MAX_OBSERVERS 2 +*/ + +/* Filtering .well-known/core per query can be disabled to save space. */ +/* +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +*/ + +/* Save some memory for the sky platform. */ +/* +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 10 +*/ + +/* Reduce 802.15.4 frame queue to save RAM. */ +/* +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 +*/ + +/* +#undef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +*/ + +#endif /* PROJECT_RPL_WEB_CONF_H_ */ diff --git a/examples/osd/arduino-ledstrip/run.sh b/examples/osd/arduino-ledstrip/run.sh new file mode 100755 index 000000000..5d5cbbbb4 --- /dev/null +++ b/examples/osd/arduino-ledstrip/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/arduino-ledstrip/sketch.pde b/examples/osd/arduino-ledstrip/sketch.pde new file mode 100644 index 000000000..cd8f8d42d --- /dev/null +++ b/examples/osd/arduino-ledstrip/sketch.pde @@ -0,0 +1,138 @@ +/* + * Sample arduino sketch using contiki features. + * We turn the LED off + * We allow read the moisture sensor + * Unfortunately sleeping for long times in loop() isn't currently + * possible, something turns off the CPU (including PWM outputs) if a + * Proto-Thread is taking too long. We need to find out how to sleep in + * a Contiki-compatible way. + * Note that for a normal arduino sketch you won't have to include any + * of the contiki-specific files here, the sketch should just work. + */ + +#include "RGBdriver.h" + +#define CLK 3//pins definitions for the driver +#define DIO 14 +RGBdriver Driver(CLK,DIO); + +extern "C" { +#include +#include +#include +#include +#include "contiki.h" +#include "contiki-net.h" +#include "rest-engine.h" +#include "generic_resource.h" +#include "net/netstack.h" + +extern volatile uint8_t mcusleepcycle; // default 16 + +#define LED_PIN 4 +} + +uint8_t color_rgb [3] = {0, 0, 0}; + +static uint8_t name_to_offset (const char * name) +{ + uint8_t offset = 0; + if (0 == strcmp (name, "green")) { + offset = 1; + } else if (0 == strcmp (name, "blue")) { + offset = 2; + } + return offset; +} + +static size_t +color_to_string (const char *name, const char *uri, char *buf, size_t bsize) +{ + return snprintf (buf, bsize, "%d", color_rgb [name_to_offset (name)]); +} + +int color_from_string (const char *name, const char *uri, const char *s) +{ + color_rgb [name_to_offset (name)] = atoi (s); + Driver.begin(); + Driver.SetColor(color_rgb [0], color_rgb [1], color_rgb [2]); + Driver.end(); + return 0; +} + +GENERIC_RESOURCE + ( red + , RED_LED + , s + , 1 + , color_from_string + , color_to_string + ); + +GENERIC_RESOURCE + ( green + , GREEN_LED + , s + , 1 + , color_from_string + , color_to_string + ); + +GENERIC_RESOURCE + ( blue + , BLUE_LED + , s + , 1 + , color_from_string + , color_to_string + ); + +void setup (void) +{ + // switch off the led + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, HIGH); + // init coap resourcen + rest_init_engine (); + + NETSTACK_MAC.off(1); + + rest_activate_resource (&res_red, "led/R"); + rest_activate_resource (&res_green, "led/G"); + rest_activate_resource (&res_blue, "led/B"); + + Driver.begin(); + Driver.SetColor(color_rgb [0], color_rgb [1], color_rgb [2]); + Driver.end(); +} + +void loop (void) +{ + +/* // Test + + static int a=1; + + switch(a) { + case 1: printf("red\n"); + Driver.begin(); + Driver.SetColor(255, 0, 0); + Driver.end(); + a++; + break; + case 2: printf("green\n"); + Driver.begin(); + Driver.SetColor(0, 255, 0); + Driver.end(); + a++; + break; + case 3: printf("blue\n"); + Driver.begin(); + Driver.SetColor(0, 0, 255); + Driver.end(); + a=1; + break; + default: printf("a ist irgendwas\n"); break; + } +*/ +} diff --git a/examples/osd/arduino-merkurboard/Makefile b/examples/osd/arduino-merkurboard/Makefile index 39d79b8e1..5a017eac0 100644 --- a/examples/osd/arduino-merkurboard/Makefile +++ b/examples/osd/arduino-merkurboard/Makefile @@ -1,19 +1,28 @@ -all: er-example-server er-example-client -# use this target explicitly if requried: er-plugtest-server +# Set this to the name of your sketch (without extension .pde) +SKETCH=sketch +EXE=arduino-example - -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 - -# for some platforms -UIP_CONF_IPV6=1 -# IPv6 make config disappeared completely -CFLAGS += -DUIP_CONF_IPV6=1 +all: $(EXE) CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +PROJECT_SOURCEFILES += ${SKETCH}.cpp + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) # variable for Makefile.include ifneq ($(TARGET), minimal-net) @@ -32,64 +41,30 @@ endif # linker optimizations SMALL=1 -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif -APPS += erbium - -# optional rules to get assembly -#CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 -#CUSTOM_RULE_S_TO_OBJECTDIR_O = 1 +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += arduino include $(CONTIKI)/Makefile.include +include $(CONTIKI)/apps/arduino/Makefile.include -# optional rules to get assembly -#$(OBJECTDIR)/%.o: asmdir/%.S -# $(CC) $(CFLAGS) -MMD -c $< -o $@ -# @$(FINALIZE_DEPENDENCY) -# -#asmdir/%.S: %.c -# $(CC) $(CFLAGS) -MMD -S $< -o $@ - -# border router rules -$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c (cd $(CONTIKI)/tools && $(MAKE) tunslip6) -connect-router: $(CONTIKI)/tools/tunslip6 +connect-router: $(CONTIKI)/tools/tunslip6 sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 -connect-router-cooja: $(CONTIKI)/tools/tunslip6 +connect-router-cooja: $(CONTIKI)/tools/tunslip6 sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 connect-minimal: sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/arduino-merkurboard/README b/examples/osd/arduino-merkurboard/README deleted file mode 100644 index 84d7dd2f4..000000000 --- a/examples/osd/arduino-merkurboard/README +++ /dev/null @@ -1,76 +0,0 @@ -A Quick Introduction to the Erbium (Er) REST Engine -=================================================== -Compile the Example -------------------- -./run.sh - -OSD-Merkur Board ----------------------- -write the images to the OSD-Merkur Board: - -./flash.sh - -EXAMPLE FILES -------------- -er-example-server.c: A RESTful server example showing how to use the REST layer to develop server-side applications (at the moment only CoAP is implemented for the REST Engine). -er-example-client.c: A CoAP client that polls the /actuators/toggle resource every 10 seconds and cycles through 4 resources on button press (target address is hard-coded). -er-plugtest-server.c: The server used for draft compliance testing at ETSI IoT CoAP Plugtest in Paris, France, March 2012 (configured for minimal-net). - -PRELIMINARIES -------------- -- Make sure rpl-border-router has the same stack and fits into mote memory: - You can disable RDC in border-router project-conf.h (not really required as BR keeps radio turned on). - #undef NETSTACK_CONF_RDC - #define NETSTACK_CONF_RDC nullrdc_driver -- For convenience, define the Cooja addresses in /etc/hosts - aaaa::0212:7401:0001:0101 cooja1 - aaaa::0212:7402:0002:0202 cooja2 - ... -- Get the Copper (Cu) CoAP user-agent from https://addons.mozilla.org/en-US/firefox/addon/copper-270430/ -- Optional: Save your target as default target - $ make TARGET=sky savetarget - -COOJA HOWTO ------------ -Server only: -1) $ make TARGET=cooja server-only.csc -2) Open new terminal -3) $ make connect-router-cooja -4) Start Copper and discover resources at coap://cooja2:5683/ -- Choose "Click button on Sky 2" from the context menu of mote 2 (server) after requesting /test/separate -- Do the same when observing /test/event - -With client: -1) $ make TARGET=cooja server-client.csc -2) Open new terminal -3) $ make connect-router-cooja -4) Wait until red LED toggles on mote 2 (server) -5) Choose "Click button on Sky 3" from the context menu of mote 3 (client) and watch serial output - -DETAILS -------- -Erbium currently implements draft 08 (name "er-coap-07" stems from last technical draft changes). -Central features are commented in er-example-server.c. -In general, apps/er-coap-07 supports: -* All draft 08 header options -* CON Retransmissions (note COAP_MAX_OPEN_TRANSACTIONS) -* Blockwise Transfers (note REST_MAX_CHUNK_SIZE, see er-plugtest-server.c for Block1 uploads) -* Separate Responses (no rest_set_pre_handler() required anymore, note coap_separate_accept(), _reject(), and _resume()) -* Resource Discovery -* Observing Resources (see EVENT_ and PRERIODIC_RESOURCE, note COAP_MAX_OBSERVERS) - -REST IMPLEMENTATIONS --------------------- -The Makefile uses WITH_COAP to configure different implementations for the Erbium (Er) REST Engine. -* WITH_COAP=7 uses Erbium CoAP 08 apps/er-coap-07/. - The default port for coap-07/-08 is 5683. -* WITH_COAP=3 uses Erbium CoAP 03 apps/er-coap-03/. - The default port for coap-03 is 61616. - er-coap-03 produces some warnings, as it not fully maintained anymore. -* WITH_COAP=0 is a stub to link an Erbium HTTP engine that uses the same resource abstraction (REST.x() functions and RESOURCE macros. - -TODOs ------ -* Observe client -* Multiple If-Match ETags -* (Message deduplication) diff --git a/examples/osd/arduino-merkurboard/README.md b/examples/osd/arduino-merkurboard/README.md index 1aa35b091..e1490ed05 100644 --- a/examples/osd/arduino-merkurboard/README.md +++ b/examples/osd/arduino-merkurboard/README.md @@ -1,166 +1,11 @@ -A Quick Introduction to the Erbium (Er) REST Engine -=================================================== +Arduino compatibility example +============================= -EXAMPLE FILES -------------- +This example shows that it is now possible to re-use arduino sketches in +Contiki. This example documents the necessary magic. Arduino specifies +two routines, `setup` and `loop`. Before `setup` is called, the +framework initializes hardware. In original Arduino, all this is done in +a `main` function (in C). For contiki we define a process that does the +same. -- er-example-server.c: A RESTful server example showing how to use the REST - layer to develop server-side applications (at the moment only CoAP is - implemented for the REST Engine). -- er-example-client.c: A CoAP client that polls the /actuators/toggle resource - every 10 seconds and cycles through 4 resources on button press (target - address is hard-coded). -- er-plugtest-server.c: The server used for draft compliance testing at ETSI - IoT CoAP Plugtests. Erbium (Er) participated in Paris, France, March 2012 and - Sophia-Antipolis, France, November 2012 (configured for minimal-net). - -PRELIMINARIES -------------- - -- Make sure rpl-border-router has the same stack and fits into mote memory: - You can disable RDC in border-router project-conf.h (not really required as BR keeps radio turned on). - #undef NETSTACK_CONF_RDC - #define NETSTACK_CONF_RDC nullrdc_driver -- For convenience, define the Cooja addresses in /etc/hosts - aaaa::0212:7401:0001:0101 cooja1 - aaaa::0212:7402:0002:0202 cooja2 - ... -- Get the Copper (Cu) CoAP user-agent from - [https://addons.mozilla.org/en-US/firefox/addon/copper-270430](https://addons.mozilla.org/en-US/firefox/addon/copper-270430) -- Optional: Save your target as default target - make TARGET=sky savetarget - -COOJA HOWTO ------------ - -###Server only: - - make TARGET=cooja server-only.csc - -Open new terminal - - make connect-router-cooja - -- Start Copper and discover resources at coap://cooja2:5683/ -- Choose "Click button on Sky 2" from the context menu of mote 2 (server) after - requesting /test/separate -- Do the same when observing /test/event - -###With client: - - make TARGET=cooja server-client.csc - -Open new terminal - - make connect-router-cooja - -- Wait until red LED toggles on mote 2 (server) -- Choose "Click button on Sky 3" from the context menu of mote 3 (client) and - watch serial output - -TMOTES HOWTO ------------- - -###Server: - -1. Connect two Tmote Skys (check with $ make TARGET=sky sky-motelist) - - make TARGET=sky er-example-server.upload MOTE=2 - make TARGET=sky login MOTE=2 - -2. Press reset button, get address, abort with Ctrl+C: - Line: "Tentative link-local IPv6 address fe80:0000:0000:0000:____:____:____:____" - - cd ../ipv6/rpl-border-router/ - make TARGET=sky border-router.upload MOTE=1 - make connect-router - - For a BR tty other than USB0: - - make connect-router-port PORT=X - -3. Start Copper and discover resources at: - - coap://[aaaa::____:____:____:____]:5683/ - -### Add a client: - -1. Change the hard-coded server address in er-example-client.c to aaaa::____:____:____:____ -2. Connect a third Tmote Sky - - make TARGET=sky er-example-client.upload MOTE=3 - -MINIMAL-NET HOWTO ------------------ - -With the target minimal-net you can test your CoAP applications without -constraints, i.e., with large buffers, debug output, memory protection, etc. -The er-plugtest-server is thought for the minimal-net platform, as it requires -an 1280-byte IP buffer and 1024-byte blocks. - - make TARGET=minimal-net er-plugtest-server - sudo ./er-plugtest-server.minimal-net - -Open new terminal - - make connect-minimal - -- Start Copper and discover resources at coap://[fdfd::ff:fe00:10]:5683/ -- You can enable the ETSI Plugtest menu in Copper's preferences - -Under Windows/Cygwin, WPCAP might need a patch in -\usr\include\w32api\in6addr.h: - - 21,23c21 - < #ifdef __INSIDE_CYGWIN__ - < uint32_t __s6_addr32[4]; - < #endif - --- - > u_int __s6_addr32[4]; - 36d33 - < #ifdef __INSIDE_CYGWIN__ - 39d35 - < #endif - -DETAILS -------- - -Erbium currently implements draft 13. Central features are commented in -er-example-server.c. In general, apps/er-coap-13 supports: - -- All draft 13 header options -- CON Retransmissions (note COAP_MAX_OPEN_TRANSACTIONS) -- Blockwise Transfers (note REST_MAX_CHUNK_SIZE, see er-plugtest-server.c for - Block1 uploads) -- Separate Responses (no rest_set_pre_handler() required anymore, note - coap_separate_accept(), _reject(), and _resume()) -- Resource Discovery -- Observing Resources (see EVENT_ and PRERIODIC_RESOURCE, note - COAP_MAX_OBSERVERS) - -REST IMPLEMENTATIONS --------------------- - -The Makefile uses WITH_COAP to configure different implementations for the -Erbium (Er) REST Engine. - -- WITH_COAP=13 uses Erbium CoAP 13 apps/er-coap-13/. The default port for - coap-13 is 5683. -- WITH_COAP=12 uses Erbium CoAP 12 apps/er-coap-12/. The default port for - coap-12 is 5683. -- WITH_COAP=7 uses Erbium CoAP 08 apps/er-coap-07/. The default port for - coap-07/-08 is 5683. -- WITH_COAP=3 uses Erbium CoAP 03 apps/er-coap-03/. The default port for - coap-03 is 61616. er-coap-03 produces some warnings, as it not fully - maintained anymore. -- WITH_COAP=0 is a stub to link an Erbium HTTP engine that uses the same - resource abstraction (REST.x() functions and RESOURCE macros. - -TODOs ------ - -- Dedicated Observe buffers -- Optimize message struct variable access (directly access struct without copying) -- Observe client -- Multiple If-Match ETags -- (Message deduplication) +See the documentation file in apps/contiki-compat/README.md diff --git a/examples/osd/arduino-merkurboard/arduino-example.c b/examples/osd/arduino-merkurboard/arduino-example.c new file mode 100644 index 000000000..ea74dd8b8 --- /dev/null +++ b/examples/osd/arduino-merkurboard/arduino-example.c @@ -0,0 +1,2 @@ +#include +AUTOSTART_PROCESSES(&arduino_sketch); diff --git a/examples/osd/arduino-merkurboard/er-example-client.c b/examples/osd/arduino-merkurboard/er-example-client.c deleted file mode 100644 index 14b5a291a..000000000 --- a/examples/osd/arduino-merkurboard/er-example-client.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2013, Matthias Kovatsch - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Erbium (Er) CoAP client example - * \author - * Matthias Kovatsch - */ - -#include -#include -#include - -#include "contiki.h" -#include "contiki-net.h" - -#include "dev/button-sensor.h" -#include "dev/leds.h" - -#if WITH_COAP == 3 -#include "er-coap-03-engine.h" -#elif WITH_COAP == 6 -#include "er-coap-06-engine.h" -#elif WITH_COAP == 7 -#include "er-coap-07-engine.h" -#elif WITH_COAP == 12 -#include "er-coap-12-engine.h" -#elif WITH_COAP == 13 -#include "er-coap-13-engine.h" -#else -#error "CoAP version defined by WITH_COAP not implemented" -#endif - - -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - -/* TODO: This server address is hard-coded for Cooja. */ -#define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0221, 0x2eff, 0xff00, 0x26e6) /* cooja2 */ - -#define LOCAL_PORT UIP_HTONS(COAP_DEFAULT_PORT+1) -#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT) - -PROCESS(coap_client_example, "COAP Client Example"); -AUTOSTART_PROCESSES(&coap_client_example); - - -uip_ipaddr_t server_ipaddr; - -/* Example URIs that can be queried. */ -#define NUMBER_OF_URLS 4 -/* leading and ending slashes only for demo purposes, get cropped automatically when setting the Uri-Path */ -char* service_urls[NUMBER_OF_URLS] = {".well-known/core", "/actuators/toggle", "battery/", "error/in//path"}; - -/* This function is will be passed to COAP_BLOCKING_REQUEST() to handle responses. */ -void -client_chunk_handler(void *response) -{ - const uint8_t *chunk; - - int len = coap_get_payload(response, &chunk); - printf("|%.*s", len, (char *)chunk); -} - - -PROCESS_THREAD(coap_client_example, ev, data) -{ - PROCESS_BEGIN(); - - leds_off(LEDS_RED); - - static coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ - SERVER_NODE(&server_ipaddr); - - /* receives all CoAP messages */ - coap_receiver_init(); - -#if PLATFORM_HAS_BUTTON - SENSORS_ACTIVATE(button_sensor); - PRINTF("Press a button to request %s\n", service_urls[1]); -#endif - - while(1) { - PROCESS_YIELD(); - -#if PLATFORM_HAS_BUTTON - if (ev == sensors_event && data == &button_sensor) { - - /* send a request to notify the end of the process */ - - PRINTF("--Toggle --\n"); - leds_toggle(LEDS_RED); - /* prepare request, TID is set by COAP_BLOCKING_REQUEST() */ - coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0 ); - coap_set_header_uri_path(request, service_urls[1]); - - const char msg[] = "Toggle!"; - coap_set_payload(request, (uint8_t *)msg, sizeof(msg)-1); - - - PRINT6ADDR(&server_ipaddr); - PRINTF(" : %u\n", UIP_HTONS(REMOTE_PORT)); - - COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, client_chunk_handler); - - PRINTF("\n--Done--\n"); - } -#endif - } - - PROCESS_END(); -} diff --git a/examples/osd/arduino-merkurboard/er-example-server.c b/examples/osd/arduino-merkurboard/er-example-server.c deleted file mode 100644 index 1f68d6bce..000000000 --- a/examples/osd/arduino-merkurboard/er-example-server.c +++ /dev/null @@ -1,543 +0,0 @@ -/* - * Copyright (c) 2013, Matthias Kovatsch - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/* -From: -http://tools.ietf.org/id/draft-ietf-core-interfaces-01.txt - -Appendix A. Profile example - - The following is a short definition of simple profile. This - simplistic profile is for use in the examples of this document. - - +--------------------+-----------+------------+---------+ - | Function Set | Root Path | RT | IF | - +--------------------+-----------+------------+---------+ - | Device Description | /d | simple.dev | core.ll | - | Sensors | /s | simple.sen | core.b | - | Actuators | /a | simple.act | core.b | - +--------------------+-----------+------------+---------+ - - List of Function Sets - - +-------+----------+----------------+---------+------------+ - | Type | Path | RT | IF | Data Type | - +-------+----------+----------------+---------+------------+ - | Name | /d/name | simple.dev.n | core.p | xsd:string | - | Model | /d/model | simple.dev.mdl | core.rp | xsd:string | - +-------+----------+----------------+---------+------------+ - - Device Description Function Set - - +-------------+-------------+----------------+--------+-------------+ - | Type | Path | RT | IF | Data Type | - +-------------+-------------+----------------+--------+-------------+ - | Light | /s/light | simple.sen.lt | core.s | xsd:decimal | - | | | | | (lux) | - | Humidity | /s/humidity | simple.sen.hum | core.s | xsd:decimal | - | | | | | (%RH) | - | Temperature | /s/temp | simple.sen.tmp | core.s | xsd:decimal | - | | | | | (degC) | - +-------------+-------------+----------------+--------+-------------+ - - Sensors Function Set - - +------+------------+----------------+--------+-------------+ - | Type | Path | RT | IF | Data Type | - +------+------------+----------------+--------+-------------+ - | LED | /a/{#}/led | simple.act.led | core.a | xsd:boolean | - +------+------------+----------------+--------+-------------+ - - Actuators Function Set -*/ - -/** - * \file - * Erbium (Er) REST Engine example (with CoAP-specific code) - * \author - * Matthias Kovatsch - */ - -#include -#include -#include -#include "contiki.h" -#include "contiki-net.h" -#include - - -/* Define which resources to include to meet memory constraints. */ -#define REST_RES_MODEL 1 -#define REST_RES_NAME 1 -#define REST_RES_SW 1 -#define REST_RES_EVENT 1 -#define REST_RES_LED 1 -#define REST_RES_TOGGLE 1 -#define REST_RES_BATTERY 1 -#define REST_RES_TEMPERATURE 1 - -#include "erbium.h" - -#include "dev/Arduino.h" - -#if defined (PLATFORM_HAS_BUTTON) -#include "dev/button-sensor.h" -#endif -#if defined (PLATFORM_HAS_LED) -#include "dev/leds.h" -#endif -#if defined (PLATFORM_HAS_BATTERY) -#include "dev/battery-sensor.h" -#endif -#if defined (PLATFORM_HAS_TEMPERATURE) -#include "dev/temperature-sensor.h" -#endif - -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP == 3 -#include "er-coap-03.h" -#elif WITH_COAP == 7 -#include "er-coap-07.h" -#elif WITH_COAP == 12 -#include "er-coap-12.h" -#elif WITH_COAP == 13 -#include "er-coap-13.h" -#else -#warning "Erbium example without CoAP-specifc functionality" -#endif /* CoAP-specific example */ - -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - - -/******************************************************************************/ -#if REST_RES_MODEL -/* - * Resources are defined by the RESOURCE macro. - * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). - */ -RESOURCE(model, METHOD_GET, "p/model", "title=\"model\";rt=\"simple.dev.mdl\""); - -/* - * A handler function named [resource name]_handler must be implemented for each RESOURCE. - * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore - * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. - * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. - */ -void -model_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - char message[100]; - int index = 0; - int length = 0; /* |<-------->| */ - - /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ - // jSON Format - index += sprintf(message + index,"{\n \"model\" : \"Merkurboard\"\n"); - index += sprintf(message + index,"}\n"); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - REST.set_response_payload(response, buffer, length); -} -#endif - -/******************************************************************************/ -#if REST_RES_SW -/* - * Resources are defined by the RESOURCE macro. - * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). - */ -RESOURCE(sw, METHOD_GET, "p/sw", "title=\"Software Version\";rt=\"simple.dev.sv\""); - -/* - * A handler function named [resource name]_handler must be implemented for each RESOURCE. - * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore - * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. - * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. - */ -void -sw_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - char message[100]; - int index = 0; - int length = 0; /* |<-------->| */ - - /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ - // jSON Format - index += sprintf(message + index,"{\n \"sw\" : \"V0.8\"\n"); - index += sprintf(message + index,"}\n"); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - REST.set_response_payload(response, buffer, length); -} -#endif - -/******************************************************************************/ -#if REST_RES_NAME -/* - * Resources are defined by the RESOURCE macro. - * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). - */ -RESOURCE(name, METHOD_POST | METHOD_GET, "p/name", "title=\"name\";rt=\"simple.dev.n\""); -/* eeprom space */ -#define P_NAME "Testboard" -#define P_NAME_MAX 17 -uint8_t eemem_p_name[P_NAME_MAX] EEMEM = P_NAME; - -/* - * A handler function named [resource name]_handler must be implemented for each RESOURCE. - * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore - * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. - * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. - */ -void -name_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - uint8_t eebuffer[32]; - char message[100]; - int index = 0; - int length = 0; /* |<-------->| */ - const char *name = NULL; - int success = 1; - - switch(REST.get_method_type(request)){ - case METHOD_GET: - cli(); - eeprom_read_block (eebuffer, &eemem_p_name, sizeof(eemem_p_name)); - sei(); - /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ - // jSON Format - index += sprintf(message + index,"{\n \"name\" : \"%s\"\n",eebuffer); - index += sprintf(message + index,"}\n"); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - REST.set_response_payload(response, buffer, length); - break; - - case METHOD_POST: - if (success && (length=REST.get_post_variable(request, "name", &name))) { - PRINTF("name %s\n", name); - if (length < P_NAME_MAX) { - memcpy(&eebuffer, name,length); - eebuffer[length]=0; - cli(); - eeprom_write_block(&eebuffer, &eemem_p_name, sizeof(eemem_p_name)); - sei(); - } else { - success = 0; - } - } else { - success = 0; - } - break; - default: - success = 0; - } - if (!success) { - REST.set_response_status(response, REST.status.BAD_REQUEST); - } -} -#endif - -/******************************************************************************/ -#if REST_RES_EVENT && defined (PLATFORM_HAS_BUTTON) -/* - * Example for an event resource. - * Additionally takes a period parameter that defines the interval to call [name]_periodic_handler(). - * A default post_handler takes care of subscriptions and manages a list of subscribers to notify. - */ -EVENT_RESOURCE(event, METHOD_GET, "s/button", "title=\"Event demo\";obs"); - -void -event_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - char message[100]; - int index = 0; - int length = 0; /* |<-------->| */ - int button = button_sensor.value(0); - - index += sprintf(message + index,"%d",button); - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, buffer, length); - - /* A post_handler that handles subscriptions/observing will be called for periodic resources by the framework. */ -} - -/* Additionally, a handler function named [resource name]_event_handler must be implemented for each PERIODIC_RESOURCE defined. - * It will be called by the REST manager process with the defined period. */ -void -event_event_handler(resource_t *r) -{ - static uint16_t event_counter = 0; - static char content[12]; - - ++event_counter; - - PRINTF("TICK %u for /%s\n", event_counter, r->url); - - /* Build notification. */ - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_CON, REST.status.OK, 0 ); - coap_set_payload(notification, content, snprintf(content, sizeof(content), "EVENT %u", event_counter)); - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(r, event_counter, notification); -} -#endif /* PLATFORM_HAS_BUTTON */ - - -/******************************************************************************/ -#if defined (PLATFORM_HAS_LED) -/******************************************************************************/ -#if REST_RES_LED -/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -RESOURCE(led, METHOD_POST | METHOD_PUT , "a/led", "title=\"LED: POST/PUT mode=on|off\";rt=\"simple.act.led\""); - -void -led_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - size_t len = 0; - const char *mode = NULL; - uint8_t led = 0; - int success = 1; - - led = LEDS_RED; - - if (success && (len=REST.get_post_variable(request, "mode", &mode))) { - PRINTF("mode %s\n", mode); - - if (strncmp(mode, "on", len)==0) { - leds_on(led); - } else if (strncmp(mode, "off", len)==0) { - leds_off(led); - } else { - success = 0; - } - } else { - success = 0; - } - - if (!success) { - REST.set_response_status(response, REST.status.BAD_REQUEST); - } -} -#endif - -/******************************************************************************/ -#if REST_RES_TOGGLE -/* A simple actuator example. Toggles the red led */ -RESOURCE(toggle, METHOD_POST, "a/toggle", "title=\"Red LED\";rt=\"Control\""); -void -toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - leds_toggle(LEDS_RED); -} -#endif -#endif /* PLATFORM_HAS_LED */ - -/******************************************************************************/ -#if REST_RES_BATTERY && defined (PLATFORM_HAS_BATTERY) -/* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(battery, METHOD_GET, "s/battery", "title=\"Battery status\";rt=\"Battery\""); -void -battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int battery = battery_sensor.value(0); - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d.%02d", battery/1000, battery % 1000); - - REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"battery\":%d.%02d}", battery/1000, battery % 1000); - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain and application/json"; - REST.set_response_payload(response, msg, strlen(msg)); - } -} -#endif /* PLATFORM_HAS_BATTERY */ - -/******************************************************************************/ -#if REST_RES_TEMPERATURE && defined (PLATFORM_HAS_TEMPERATURE) -/* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(temperature, METHOD_GET, "s/cputemp", "title=\"CPU Temperature\";rt=\"simple.sen.tmp\""); -void -temperature_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int temperature = temperature_sensor.value(0); - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d.%02d", temperature/100, temperature % 100); - - REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%d.%02d}", temperature/100, temperature % 100); - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain and application/json"; - REST.set_response_payload(response, msg, strlen(msg)); - } -} -#endif /* PLATFORM_HAS_TEMPERATURE */ - -void -hw_init() -{ -#if defined (PLATFORM_HAS_LED) -// leds_off(LEDS_RED); -// Pin 4 has an LED connected on the Merkurboard. -// give it a name: -int led = 4; - - pinMode(led, OUTPUT); - digitalWrite(led, HIGH); - -#endif -} - -PROCESS(rest_server_example, "Erbium Example Server"); -AUTOSTART_PROCESSES(&rest_server_example); - -PROCESS_THREAD(rest_server_example, ev, data) -{ - PROCESS_BEGIN(); - - PRINTF("Starting Erbium Example Server\n"); - -#ifdef RF_CHANNEL - PRINTF("RF channel: %u\n", RF_CHANNEL); -#endif -#ifdef IEEE802154_PANID - PRINTF("PAN ID: 0x%04X\n", IEEE802154_PANID); -#endif - - PRINTF("uIP buffer: %u\n", UIP_BUFSIZE); - PRINTF("LL header: %u\n", UIP_LLH_LEN); - PRINTF("IP+UDP header: %u\n", UIP_IPUDPH_LEN); - PRINTF("REST max chunk: %u\n", REST_MAX_CHUNK_SIZE); - - /* Initialize the OSD Hardware. */ - hw_init(); - /* Initialize the REST engine. */ - rest_init_engine(); - - /* Activate the application-specific resources. */ -#if REST_RES_MODEL - rest_activate_resource(&resource_model); -#endif -#if REST_RES_SW - rest_activate_resource(&resource_sw); -#endif -#if REST_RES_NAME - rest_activate_resource(&resource_name); -#endif -#if defined (PLATFORM_HAS_BUTTON) && REST_RES_EVENT - rest_activate_event_resource(&resource_event); - SENSORS_ACTIVATE(button_sensor); -#endif -#if defined (PLATFORM_HAS_LED) -#if REST_RES_LED - rest_activate_resource(&resource_led); -#endif -#if REST_RES_TOGGLE - rest_activate_resource(&resource_toggle); -#endif -#endif /* PLATFORM_HAS_LED */ -#if defined (PLATFORM_HAS_BATTERY) && REST_RES_BATTERY - SENSORS_ACTIVATE(battery_sensor); - rest_activate_resource(&resource_battery); -#endif -#if defined (PLATFORM_HAS_TEMPERATURE) && REST_RES_TEMPERATURE - SENSORS_ACTIVATE(temperature_sensor); - rest_activate_resource(&resource_temperature); -#endif - - /* Define application-specific events here. */ - while(1) { - PROCESS_WAIT_EVENT(); -#if defined (PLATFORM_HAS_BUTTON) - if (ev == sensors_event && data == &button_sensor) { - PRINTF("BUTTON\n"); -#if REST_RES_EVENT - /* Call the event_handler for this application-specific event. */ - event_event_handler(&resource_event); -#endif - } -#endif /* PLATFORM_HAS_BUTTON */ - } /* while (1) */ - - PROCESS_END(); -} diff --git a/examples/osd/arduino-merkurboard/er-plugtest-server.c b/examples/osd/arduino-merkurboard/er-plugtest-server.c deleted file mode 100644 index 5a791a09c..000000000 --- a/examples/osd/arduino-merkurboard/er-plugtest-server.c +++ /dev/null @@ -1,1298 +0,0 @@ -/* - * Copyright (c) 2013, Matthias Kovatsch - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Server for the ETSI IoT CoAP Plugtests, Paris, France, 24 - 25 March 2012 - * \author - * Matthias Kovatsch - */ - -#include -#include -#include -#include "contiki.h" -#include "contiki-net.h" - -#define MAX_PLUGFEST_PAYLOAD 64+1 /* +1 for the terminating zero, which is not transmitted */ -#define MAX_PLUGFEST_BODY 2048 -#define CHUNKS_TOTAL 2012 - -/* Define which resources to include to meet memory constraints. */ -#define REST_RES_TEST 1 -#define REST_RES_LONG 1 -#define REST_RES_QUERY 1 -#define REST_RES_LOC_QUERY 1 -#define REST_RES_MULTI 1 -#define REST_RES_LINKS 1 -#define REST_RES_PATH 1 -#define REST_RES_SEPARATE 1 -#define REST_RES_LARGE 1 -#define REST_RES_LARGE_UPDATE 1 -#define REST_RES_LARGE_CREATE 1 -#define REST_RES_OBS 1 - -#define REST_RES_MIRROR 1 - - - -#if !defined (CONTIKI_TARGET_MINIMAL_NET) -#warning "Should only be compiled for minimal-net!" -#endif - - - -#include "erbium.h" - -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP==7 -#include "er-coap-07.h" -#elif WITH_COAP == 12 -#include "er-coap-12.h" -#elif WITH_COAP == 13 -#include "er-coap-13.h" -#else -#error "Plugtests server without CoAP" -#endif /* CoAP-specific example */ - -#define DEBUG 1 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - - -#if REST_RES_TEST -/* - * Default test resource - */ -RESOURCE(test, METHOD_GET|METHOD_POST|METHOD_PUT|METHOD_DELETE, "test", "title=\"Default test resource\""); - -static uint8_t test_etag[8] = {0}; -static uint8_t test_etag_len = 1; -static uint8_t test_change = 1; -static uint8_t test_none_match_okay = 1; - -static -void -test_update_etag() -{ - int i; - test_etag_len = (random_rand() % 8) + 1; - for (i=0; i0 && len==test_etag_len && memcmp(test_etag, bytes, len)==0) - { - PRINTF("validate "); - REST.set_response_status(response, REST.status.NOT_MODIFIED); - REST.set_header_etag(response, test_etag, test_etag_len); - - test_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } - else - { - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_header_etag(response, test_etag, test_etag_len); - REST.set_header_max_age(response, 30); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); - } - } - else if (method & METHOD_POST) - { - PRINTF("POST "); - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "/location1/location2/location3"); - } - else if (method & METHOD_PUT) - { - PRINTF("PUT "); - - if (coap_get_header_if_none_match(request)) - { - if (test_none_match_okay) - { - REST.set_response_status(response, REST.status.CREATED); - - test_none_match_okay = 0; - PRINTF("### SERVER ACTION ### If-None-Match will FAIL\n"); - } - else - { - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - - test_none_match_okay = 1; - PRINTF("### SERVER ACTION ### If-None-Match will SUCCEED\n"); - } - } - else if (((len = coap_get_header_if_match(request, &bytes))>0 && (len==test_etag_len && memcmp(test_etag, bytes, len)==0)) || len==0) - { - test_update_etag(); - REST.set_header_etag(response, test_etag, test_etag_len); - - REST.set_response_status(response, REST.status.CHANGED); - - if (len>0) - { - test_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } - } - else - { - - PRINTF("Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X] ", len, test_etag_len, - bytes[0], - bytes[1], - bytes[2], - bytes[3], - bytes[4], - bytes[5], - bytes[6], - bytes[7], - test_etag[0], - test_etag[1], - test_etag[2], - test_etag[3], - test_etag[4], - test_etag[5], - test_etag[6], - test_etag[7] ); - - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } - else if (method & METHOD_DELETE) - { - PRINTF("DELETE "); - REST.set_response_status(response, REST.status.DELETED); - } - - PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); -} - - -RESOURCE(create1, METHOD_PUT|METHOD_DELETE, "create1", "title=\"Default test resource\""); - -static uint8_t create1_exists = 0; - -void -create1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - uint8_t method = REST.get_method_type(request); - - if (test_change) - { - test_update_etag(); - } - - PRINTF("/create1 "); - - if (method & METHOD_PUT) - { - PRINTF("PUT "); - - if (coap_get_header_if_none_match(request)) - { - if (!create1_exists) - { - REST.set_response_status(response, REST.status.CREATED); - - create1_exists = 1; - } - else - { - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } - else - { - REST.set_response_status(response, REST.status.CHANGED); - } - } - else if (method & METHOD_DELETE) - { - PRINTF("DELETE "); - REST.set_response_status(response, REST.status.DELETED); - - create1_exists = 0; - } -} - -RESOURCE(create2, METHOD_POST, "create2", "title=\"Creates on POST\""); - -void -create2_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - if (test_change) - { - test_update_etag(); - } - - PRINTF("/create2 "); - - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "/location1/location2/location3"); -} - -RESOURCE(create3, METHOD_PUT|METHOD_DELETE, "create3", "title=\"Default test resource\""); - -static uint8_t create3_exists = 0; - -void -create3_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - uint8_t method = REST.get_method_type(request); - - if (test_change) - { - test_update_etag(); - } - - PRINTF("/create3 "); - - if (method & METHOD_PUT) - { - PRINTF("PUT "); - - if (coap_get_header_if_none_match(request)) - { - if (!create3_exists) - { - REST.set_response_status(response, REST.status.CREATED); - - create3_exists = 1; - } - else - { - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } - else - { - REST.set_response_status(response, REST.status.CHANGED); - } - } - else if (method & METHOD_DELETE) - { - PRINTF("DELETE "); - REST.set_response_status(response, REST.status.DELETED); - - create3_exists = 0; - } -} - - - - - -RESOURCE(validate, METHOD_GET|METHOD_PUT, "validate", "title=\"Default test resource\""); - -static uint8_t validate_etag[8] = {0}; -static uint8_t validate_etag_len = 1; -static uint8_t validate_change = 1; - -static -void -validate_update_etag() -{ - int i; - validate_etag_len = (random_rand() % 8) + 1; - for (i=0; i0 && len==validate_etag_len && memcmp(validate_etag, bytes, len)==0) - { - PRINTF("validate "); - REST.set_response_status(response, REST.status.NOT_MODIFIED); - REST.set_header_etag(response, validate_etag, validate_etag_len); - - validate_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } - else - { - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_header_etag(response, validate_etag, validate_etag_len); - REST.set_header_max_age(response, 30); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); - } - } - else if (method & METHOD_PUT) - { - PRINTF("PUT "); - - if (((len = coap_get_header_if_match(request, &bytes))>0 && (len==validate_etag_len && memcmp(validate_etag, bytes, len)==0)) || len==0) - { - validate_update_etag(); - REST.set_header_etag(response, validate_etag, validate_etag_len); - - REST.set_response_status(response, REST.status.CHANGED); - - if (len>0) - { - validate_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } - } - else - { - PRINTF("Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X] ", len, validate_etag_len, - bytes[0], - bytes[1], - bytes[2], - bytes[3], - bytes[4], - bytes[5], - bytes[6], - bytes[7], - validate_etag[0], - validate_etag[1], - validate_etag[2], - validate_etag[3], - validate_etag[4], - validate_etag[5], - validate_etag[6], - validate_etag[7] ); - - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } - - PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); -} -#endif - -#if REST_RES_LONG -/* - * Long path resource - */ -RESOURCE(longpath, METHOD_GET, "seg1/seg2/seg3", "title=\"Long path resource\""); - -void -longpath_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - uint8_t method = REST.get_method_type(request); - - PRINTF("/seg1/seg2/seg3 "); - if (method & METHOD_GET) - { - PRINTF("GET "); - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); - } - PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); -} -#endif - -#if REST_RES_QUERY -/* - * Resource accepting query parameters - */ -RESOURCE(query, METHOD_GET, "query", "title=\"Resource accepting query parameters\""); - -void -query_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - int len = 0; - const char *query = NULL; - - PRINTF("/query GET (%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); - - if ((len = REST.get_query(request, &query))) - { - PRINTF("Query: %.*s\n", len, query); - } - - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u\nQuery: %.*s", coap_req->type, coap_req->code, coap_req->mid, len, query)); -} -#endif - -#if REST_RES_LOC_QUERY -/* - * Resource accepting query parameters - */ -RESOURCE(locquery, METHOD_POST, "location-query", "title=\"Resource accepting query parameters\""); - -void -locquery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - PRINTF("/location-query POST (%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); - - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "?first=1&second=2"); -} -#endif - -#if REST_RES_MULTI -/* - * Resource providing text/plain and application/xml - */ -RESOURCE(multi, METHOD_GET, "multi-format", "title=\"Resource providing text/plain and application/xml\";ct=\"0 41\""); -void -multi_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - PRINTF("/multi-format GET (%s %u) %d\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid, num); - - if (num==0 || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u%s", coap_req->type, coap_req->code, coap_req->mid, num ? "\nAccept: 0" : "")); -PRINTF("PLAIN\n"); - } - else if (num && (accept[0]==REST.type.APPLICATION_XML)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_XML); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "", coap_req->type, coap_req->code, coap_req->mid, accept[0])); -PRINTF("XML\n"); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain and application/xml"; - REST.set_response_payload(response, msg, strlen(msg)); - PRINTF("ERROR\n"); - } -} -#endif - -#if REST_RES_LINKS -/* - * Resources providing text/plain and application/xml - */ -RESOURCE(link1, METHOD_GET, "link1", "rt=\"Type1 Type2\";if=\"If1\""); -SUB_RESOURCE(link2, METHOD_GET, "link2", "rt=\"Type2 Type3\";if=\"If2\"", link1); -SUB_RESOURCE(link3, METHOD_GET, "link3", "rt=\"Type1 Type3\";if=\"foo\"", link1); - -void -link1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - const char *msg = "Dummy link"; - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, msg, strlen(msg)); -} -#endif - -#if REST_RES_PATH -/* - * Resources providing text/plain and application/xml - */ -RESOURCE(path, METHOD_GET | HAS_SUB_RESOURCES, "path", "ct=\"40\""); - -void -path_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - - const char *uri_path = NULL; - int len = REST.get_url(request, &uri_path); - int base_len = strlen(resource_path.url); - - if (len==base_len) - { - REST.set_header_content_type(response, REST.type.APPLICATION_LINK_FORMAT); - snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, ",,"); - } - else - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "/%.*s", len, uri_path); - } - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); -} -#endif - -#if REST_RES_SEPARATE -/* Required to manually (=not by the engine) handle the response transaction. */ -#if WITH_COAP == 7 -#include "er-coap-07-separate.h" -#include "er-coap-07-transactions.h" -#elif WITH_COAP == 12 -#include "er-coap-12-separate.h" -#include "er-coap-12-transactions.h" -#elif WITH_COAP == 13 -#include "er-coap-13-separate.h" -#include "er-coap-13-transactions.h" -#endif -/* - * Resource which cannot be served immediately and which cannot be acknowledged in a piggy-backed way - */ -PERIODIC_RESOURCE(separate, METHOD_GET, "separate", "title=\"Resource which cannot be served immediately and which cannot be acknowledged in a piggy-backed way\"", 3*CLOCK_SECOND); - -/* A structure to store the required information */ -typedef struct application_separate_store { - /* Provided by Erbium to store generic request information such as remote address and token. */ - coap_separate_t request_metadata; - /* Add fields for addition information to be stored for finalizing, e.g.: */ - char buffer[MAX_PLUGFEST_PAYLOAD]; -} application_separate_store_t; - -static uint8_t separate_active = 0; -static application_separate_store_t separate_store[1]; - -void -separate_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - PRINTF("/separate "); - if (separate_active) - { - PRINTF("REJECTED "); - coap_separate_reject(); - } - else - { - PRINTF("STORED "); - separate_active = 1; - - /* Take over and skip response by engine. */ - coap_separate_accept(request, &separate_store->request_metadata); - /* Be aware to respect the Block2 option, which is also stored in the coap_separate_t. */ - - snprintf(separate_store->buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid); - } - - PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); -} - -void -separate_periodic_handler(resource_t *resource) -{ - if (separate_active) - { - PRINTF("/separate "); - coap_transaction_t *transaction = NULL; - if ( (transaction = coap_new_transaction(separate_store->request_metadata.mid, &separate_store->request_metadata.addr, separate_store->request_metadata.port)) ) - { - PRINTF("RESPONSE (%s %u)\n", separate_store->request_metadata.type==COAP_TYPE_CON?"CON":"NON", separate_store->request_metadata.mid); - - coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */ - - /* Restore the request information for the response. */ - coap_separate_resume(response, &separate_store->request_metadata, CONTENT_2_05); - - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - coap_set_payload(response, separate_store->buffer, strlen(separate_store->buffer)); - - /* - * Be aware to respect the Block2 option, which is also stored in the coap_separate_t. - * As it is a critical option, this example resource pretends to handle it for compliance. - */ - coap_set_header_block2(response, separate_store->request_metadata.block2_num, 0, separate_store->request_metadata.block2_size); - - /* Warning: No check for serialization error. */ - transaction->packet_len = coap_serialize_message(response, transaction->packet); - coap_send_transaction(transaction); - /* The engine will clear the transaction (right after send for NON, after acked for CON). */ - - separate_active = 0; - } else { - PRINTF("ERROR (transaction)\n"); - } - } /* if (separate_active) */ -} -#endif - -#if REST_RES_LARGE - -/* double expansion */ -#define TO_STRING2(x) #x -#define TO_STRING(x) TO_STRING2(x) - -/* - * Large resource - */ -RESOURCE(large, METHOD_GET, "large", "title=\"Large resource\";rt=\"block\";sz=\"" TO_STRING(CHUNKS_TOTAL) "\""); - -void -large_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int32_t strpos = 0; - - /* Check the offset for boundaries of the resource data. */ - if (*offset>=CHUNKS_TOTAL) - { - REST.set_response_status(response, REST.status.BAD_OPTION); - /* A block error message should not exceed the minimum block size (16). */ - - const char *error_msg = "BlockOutOfScope"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - /* Generate data until reaching CHUNKS_TOTAL. */ - while (strpos preferred_size) - { - strpos = preferred_size; - } - - /* Truncate if above CHUNKS_TOTAL bytes. */ - if (*offset+(int32_t)strpos > CHUNKS_TOTAL) - { - strpos = CHUNKS_TOTAL - *offset; - } - - REST.set_response_payload(response, buffer, strpos); - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - - /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ - *offset += strpos; - - /* Signal end of resource representation. */ - if (*offset>=CHUNKS_TOTAL) - { - *offset = -1; - } -} -#endif - -#if REST_RES_LARGE_UPDATE -/* - * Large resource that can be updated using PUT method - */ -RESOURCE(large_update, METHOD_GET|METHOD_PUT, "large-update", "title=\"Large resource that can be updated using PUT method\";rt=\"block\";sz=\"" TO_STRING(MAX_PLUGFEST_BODY) "\""); - -static int32_t large_update_size = 0; -static uint8_t large_update_store[MAX_PLUGFEST_BODY] = {0}; -static unsigned int large_update_ct = -1; - -void -large_update_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - uint8_t method = REST.get_method_type(request); - - if (method & METHOD_GET) - { - /* Check the offset for boundaries of the resource data. */ - if (*offset>=large_update_size) - { - REST.set_response_status(response, REST.status.BAD_OPTION); - /* A block error message should not exceed the minimum block size (16). */ - - const char *error_msg = "BlockOutOfScope"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - REST.set_response_payload(response, large_update_store+*offset, MIN(large_update_size - *offset, preferred_size)); - REST.set_header_content_type(response, large_update_ct); - - /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ - *offset += preferred_size; - - /* Signal end of resource representation. */ - if (*offset>=large_update_size) - { - *offset = -1; - } - } else { - uint8_t *incoming = NULL; - size_t len = 0; - - unsigned int ct = REST.get_header_content_type(request); - if (ct==-1) - { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoContentType"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - if ((len = REST.get_request_payload(request, (const uint8_t **) &incoming))) - { - if (coap_req->block1_num*coap_req->block1_size+len <= sizeof(large_update_store)) - { - memcpy(large_update_store+coap_req->block1_num*coap_req->block1_size, incoming, len); - large_update_size = coap_req->block1_num*coap_req->block1_size+len; - large_update_ct = REST.get_header_content_type(request); - - REST.set_response_status(response, REST.status.CHANGED); - coap_set_header_block1(response, coap_req->block1_num, 0, coap_req->block1_size); - } - else - { - REST.set_response_status(response, REST.status.REQUEST_ENTITY_TOO_LARGE); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "%uB max.", sizeof(large_update_store))); - return; - } - } - else - { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoPayload"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - } -} -#endif - -#if REST_RES_LARGE_CREATE -/* - * Large resource that can be created using POST method - */ -RESOURCE(large_create, METHOD_POST, "large-create", "title=\"Large resource that can be created using POST method\";rt=\"block\""); - -void -large_create_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - uint8_t *incoming = NULL; - size_t len = 0; - - unsigned int ct = REST.get_header_content_type(request); - if (ct==-1) - { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoContentType"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - if ((len = REST.get_request_payload(request, (const uint8_t **) &incoming))) - { - if (coap_req->block1_num*coap_req->block1_size+len <= 2048) - { - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "/nirvana"); - coap_set_header_block1(response, coap_req->block1_num, 0, coap_req->block1_size); - } - else - { - REST.set_response_status(response, REST.status.REQUEST_ENTITY_TOO_LARGE); - const char *error_msg = "2048B max."; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - } - else - { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoPayload"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } -} -#endif - -#if REST_RES_OBS - -#if WITH_COAP == 12 -#include "er-coap-12-observing.h" -#elif WITH_COAP == 13 -#include "er-coap-13-observing.h" -#endif -/* - * Observable resource which changes every 5 seconds - */ -PERIODIC_RESOURCE(obs, METHOD_GET|METHOD_PUT|METHOD_DELETE, "obs", "title=\"Observable resource which changes every 5 seconds\";obs", 5*CLOCK_SECOND); - -static uint16_t obs_counter = 0; -static char obs_content[MAX_PLUGFEST_BODY]; -static size_t obs_content_len = 0; -static unsigned int obs_format = 0; - -static char obs_status = 0; - -static -void -obs_purge_list() -{ - PRINTF("### SERVER ACTION ### Purging obs list"); - coap_remove_observer_by_url(NULL, 0, resource_obs.url); -} - -void -obs_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - uint8_t method = request==NULL ? METHOD_GET : REST.get_method_type(request); - - /* Keep server log clean from ticking events */ - if (request!=NULL) - { - PRINTF("/obs "); - } - - if (method & METHOD_GET) - { - /* Keep server log clean from ticking events */ - if (request!=NULL) - { - PRINTF("GET "); - } - - REST.set_header_content_type(response, obs_format); - REST.set_header_max_age(response, 5); - - if (obs_content_len) - { - REST.set_header_content_type(response, obs_format); - REST.set_response_payload(response, obs_content, obs_content_len); - } - else - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, obs_content, snprintf(obs_content, MAX_PLUGFEST_PAYLOAD, "TICK %lu", obs_counter)); - } - /* A post_handler that handles subscriptions will be called for periodic resources by the REST framework. */ - } - else if (method & METHOD_PUT) - { - uint8_t *incoming = NULL; - unsigned int ct = REST.get_header_content_type(request); - - PRINTF("PUT "); - - if (ct!=obs_format) - { - obs_status = 1; - - obs_format = ct; - } else { - - obs_format = ct; - obs_content_len = REST.get_request_payload(request, (const uint8_t **) &incoming); - memcpy(obs_content, incoming, obs_content_len); - obs_periodic_handler(&resource_obs); - } - - REST.set_response_status(response, REST.status.CHANGED); - } - else if (method & METHOD_DELETE) - { - PRINTF("DELETE "); - - obs_status = 2; - - REST.set_response_status(response, REST.status.DELETED); - } - - /* Keep server log clean from ticking events */ - if (request!=NULL) - { - PRINTF("\n"); - } -} - -/* - * Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE. - * It will be called by the REST manager process with the defined period. - */ -void -obs_periodic_handler(resource_t *r) -{ - ++obs_counter; - - //PRINTF("TICK %u for /%s\n", obs_counter, r->url); - - if (obs_status==1) - { - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_NON, INTERNAL_SERVER_ERROR_5_00, 0 ); - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(&resource_obs, -1, notification); - - PRINTF("######### sending 5.00\n"); - - obs_purge_list(); - } - else if (obs_status==2) - { - - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_NON, NOT_FOUND_4_04, 0 ); - - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(&resource_obs, -1, notification); - - obs_purge_list(); - - obs_counter = 0; - obs_content_len = 0; - } - else - { - /* Build notification. */ - /*TODO: REST.new_response() */ - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_NON, CONTENT_2_05, 0 ); - - /* Better use a generator function for both handlers that only takes *resonse. */ - obs_handler(NULL, notification, NULL, 0, NULL); - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(r, obs_counter, notification); - } - obs_status = 0; -} -#endif - -#if REST_RES_MIRROR -/* This resource mirrors the incoming request. It shows how to access the options and how to set them for the response. */ -RESOURCE(mirror, METHOD_GET | METHOD_POST | METHOD_PUT | METHOD_DELETE, "debug/mirror", "title=\"Returns your decoded message\";rt=\"Debug\""); - -void -mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - /* The ETag and Token is copied to the header. */ - uint8_t opaque[] = {0x0A, 0xBC, 0xDE}; - - /* Strings are not copied, so use static string buffers or strings in .text memory (char *str = "string in .text";). */ - static char location[] = {'/','f','/','a','?','k','&','e', 0}; - - /* Getter for the header option Content-Type. If the option is not set, text/plain is returned by default. */ - unsigned int content_type = REST.get_header_content_type(request); - - /* The other getters copy the value (or string/array pointer) to the given pointers and return 1 for success or the length of strings/arrays. */ - uint32_t max_age_and_size = 0; - const char *str = NULL; - uint32_t observe = 0; - const uint8_t *bytes = NULL; - const uint16_t *words = NULL; - uint32_t block_num = 0; - uint8_t block_more = 0; - uint16_t block_size = 0; - const char *query = ""; - int len = 0; - - /* Mirror the received header options in the response payload. Unsupported getters (e.g., rest_get_header_observe() with HTTP) will return 0. */ - - int strpos = 0; - /* snprintf() counts the terminating '\0' to the size parameter. - * The additional byte is taken care of by allocating REST_MAX_CHUNK_SIZE+1 bytes in the REST framework. - * Add +1 to fill the complete buffer, as the payload does not need a terminating '\0'. */ - - - if (strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_header_if_match(request, &bytes))) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "If-Match 0x"); - int index = 0; - for (index = 0; index= REST_MAX_CHUNK_SIZE) - { - buffer[REST_MAX_CHUNK_SIZE-1] = 0xBB; /* '»' to indicate truncation */ - } - - REST.set_response_payload(response, buffer, strpos); - - PRINTF("/mirror options received: %s\n", buffer); - - /* Set dummy header options for response. Like getters, some setters are not implemented for HTTP and have no effect. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_header_max_age(response, 17); /* For HTTP, browsers will not re-request the page for 17 seconds. */ - REST.set_header_etag(response, opaque, 2); - REST.set_header_location(response, location); /* Initial slash is omitted by framework */ - REST.set_header_length(response, strpos); /* For HTTP, browsers will not re-request the page for 10 seconds. CoAP action depends on the client. */ - -/* CoAP-specific example: actions not required for normal RESTful Web service. */ - coap_set_header_uri_host(response, "Contiki"); - coap_set_header_observe(response, 10); - coap_set_header_proxy_uri(response, "ftp://x"); - //coap_set_header_block2(response, 42, 0, 64); - //coap_set_header_block1(response, 23, 0, 16); - coap_set_header_accept(response, APPLICATION_XML); - coap_set_header_accept(response, APPLICATION_ATOM_XML); - coap_set_header_if_none_match(response); -} -#endif /* REST_RES_MIRROR */ - - - - - -PROCESS(plugtest_server, "PlugtestServer"); -AUTOSTART_PROCESSES(&plugtest_server); - -PROCESS_THREAD(plugtest_server, ev, data) -{ - PROCESS_BEGIN(); - - PRINTF("ETSI IoT CoAP Plugtests Server\n"); - -#ifdef RF_CHANNEL - PRINTF("RF channel: %u\n", RF_CHANNEL); -#endif -#ifdef IEEE802154_PANID - PRINTF("PAN ID: 0x%04X\n", IEEE802154_PANID); -#endif - - PRINTF("uIP buffer: %u\n", UIP_BUFSIZE); - PRINTF("LL header: %u\n", UIP_LLH_LEN); - PRINTF("IP+UDP header: %u\n", UIP_IPUDPH_LEN); - PRINTF("REST max chunk: %u\n", REST_MAX_CHUNK_SIZE); - - /* Initialize the REST engine. */ - rest_init_engine(); - - /* Activate the application-specific resources. */ -#if REST_RES_TEST - rest_activate_resource(&resource_test); - rest_activate_resource(&resource_validate); - rest_activate_resource(&resource_create1); - rest_activate_resource(&resource_create2); - rest_activate_resource(&resource_create3); -#endif -#if REST_RES_LONG - rest_activate_resource(&resource_longpath); -#endif -#if REST_RES_QUERY - rest_activate_resource(&resource_query); -#endif -#if REST_RES_LOC_QUERY - rest_activate_resource(&resource_locquery); -#endif -#if REST_RES_MULTI - rest_activate_resource(&resource_multi); -#endif -#if REST_RES_LINKS - rest_activate_resource(&resource_link1); - rest_activate_resource(&resource_link2); - rest_activate_resource(&resource_link3); -#endif -#if REST_RES_PATH - rest_activate_resource(&resource_path); -#endif -#if REST_RES_SEPARATE - rest_activate_periodic_resource(&periodic_resource_separate); -#endif -#if REST_RES_LARGE - rest_activate_resource(&resource_large); -#endif -#if REST_RES_LARGE_UPDATE - large_update_ct = REST.type.APPLICATION_OCTET_STREAM; - rest_activate_resource(&resource_large_update); -#endif -#if REST_RES_LARGE_CREATE - rest_activate_resource(&resource_large_create); -#endif -#if REST_RES_OBS - rest_activate_periodic_resource(&periodic_resource_obs); -#endif - -#if REST_RES_MIRROR - rest_activate_resource(&resource_mirror); -#endif - - /* Define application-specific events here. */ - while(1) { - PROCESS_WAIT_EVENT(); - - } /* while (1) */ - - PROCESS_END(); -} diff --git a/examples/osd/arduino-merkurboard/flash.sh b/examples/osd/arduino-merkurboard/flash.sh index e92d472f6..e82962073 100755 --- a/examples/osd/arduino-merkurboard/flash.sh +++ b/examples/osd/arduino-merkurboard/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-server.osd-merkur.hex:a -U eeprom:w:er-example-server.osd-merkur.eep:a +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/arduino-merkurboard/flashclient.sh b/examples/osd/arduino-merkurboard/flashclient.sh deleted file mode 100755 index 30979eed4..000000000 --- a/examples/osd/arduino-merkurboard/flashclient.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-client.osd-merkur.hex:a -U eeprom:w:er-example-client.osd-merkur.eep:a diff --git a/examples/osd/arduino-merkurboard/in6addr.patch b/examples/osd/arduino-merkurboard/in6addr.patch deleted file mode 100644 index 92ca106cf..000000000 --- a/examples/osd/arduino-merkurboard/in6addr.patch +++ /dev/null @@ -1,10 +0,0 @@ -21,23c21 -< #ifdef __INSIDE_CYGWIN__ -< uint32_t __s6_addr32[4]; -< #endif ---- -> u_int __s6_addr32[4]; -36d33 -< #ifdef __INSIDE_CYGWIN__ -39d35 -< #endif diff --git a/examples/osd/arduino-merkurboard/project-conf.h b/examples/osd/arduino-merkurboard/project-conf.h index c85939445..e0b72b6dc 100644 --- a/examples/osd/arduino-merkurboard/project-conf.h +++ b/examples/osd/arduino-merkurboard/project-conf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Matthias Kovatsch + * Copyright (c) 2010, Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,26 +29,22 @@ * */ -#ifndef PROJECT_ERBIUM_CONF_H_ -#define PROJECT_ERBIUM_CONF_H_ +#ifndef PROJECT_RPL_WEB_CONF_H_ +#define PROJECT_RPL_WEB_CONF_H_ -#define PLATFORM_HAS_LED 1 -#define PLATFORM_HAS_BUTTON 1 -#define PLATFORM_HAS_TEMPERATURE 1 +#define PLATFORM_HAS_LEDS 1 +//#define PLATFORM_HAS_BUTTON 1 #define PLATFORM_HAS_BATTERY 1 -/* Some platforms have weird includes. */ -// #undef IEEE802154_CONF_PANID -// #define IEEE802154_CONF_PANID 0xAAAA +/* For Debug: Dont allow MCU sleeping between channel checks */ +//#undef RDC_CONF_MCU_SLEEP +//#define RDC_CONF_MCU_SLEEP 0 /* Disabling RDC for demo purposes. Core updates often require more memory. */ /* For projects, optimize memory and enable RDC again. */ -// #undef NETSTACK_CONF_RDC +//#undef NETSTACK_CONF_RDC //#define NETSTACK_CONF_RDC nullrdc_driver -// enabel LEAF-NODE mode -//#define RPL_CONF_LEAF_ONLY 1 - /* Increase rpl-border-router IP-buffer when using more than 64. */ #undef REST_MAX_CHUNK_SIZE #define REST_MAX_CHUNK_SIZE 64 @@ -81,22 +77,10 @@ #define COAP_LINK_FORMAT_FILTERING 0 */ -/* Save some memory for the sky platform. */ -/* -#undef NBR_TABLE_CONF_MAX_NEIGHBORS -#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 -#undef UIP_CONF_MAX_ROUTES -#define UIP_CONF_MAX_ROUTES 10 -*/ -/* Reduce 802.15.4 frame queue to save RAM. */ -/* -#undef QUEUEBUF_CONF_NUM -#define QUEUEBUF_CONF_NUM 4 -*/ -/* -#undef SICSLOWPAN_CONF_FRAG -#define SICSLOWPAN_CONF_FRAG 1 -*/ -#endif /* PROJECT_ERBIUM_CONF_H_ */ + + + + +#endif /* PROJECT_RPL_WEB_CONF_H_ */ diff --git a/examples/osd/arduino-merkurboard/resources/res-led.c b/examples/osd/arduino-merkurboard/resources/res-led.c new file mode 100644 index 000000000..fb0fa138f --- /dev/null +++ b/examples/osd/arduino-merkurboard/resources/res-led.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Door resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_led, + "title=\"LED: , POST/PUT mode=on|off\";rt=\"Control\"", + res_get_handler, + res_post_put_handler, + res_post_put_handler, + NULL); + +extern uint8_t led_pin; +extern uint8_t led_status; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", led_status); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'led':%d}", led_status); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} + +static void +res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + size_t len = 0; + const char *mode = NULL; + int success = 1; + + if(success && (len = REST.get_post_variable(request, "mode", &mode))) { + if(strncmp(mode, "on", len) == 0) { + digitalWrite(led_pin, LOW); + led_status=1; + } else if(strncmp(mode, "off", len) == 0) { + digitalWrite(led_pin, HIGH); + led_status=0; + } else { + success = 0; + } + } else { + success = 0; + } if(!success) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} diff --git a/examples/osd/arduino-merkurboard/run.sh b/examples/osd/arduino-merkurboard/run.sh index 2efd2cf48..5d5cbbbb4 100755 --- a/examples/osd/arduino-merkurboard/run.sh +++ b/examples/osd/arduino-merkurboard/run.sh @@ -1,8 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size -C --mcu=MCU=atmega128rfa1 er-example-server.osd-merkur -avr-objcopy -j .text -j .data -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.eep +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/arduino-merkurboard/runclient.sh b/examples/osd/arduino-merkurboard/runclient.sh deleted file mode 100755 index 70dcea0e5..000000000 --- a/examples/osd/arduino-merkurboard/runclient.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size -C --mcu=MCU=atmega128rfa1 er-example-client.osd-merkur -avr-objcopy -j .text -j .data -O ihex er-example-client.osd-merkur er-example-client.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex er-example-client.osd-merkur er-example-client.osd-merkur.eep diff --git a/examples/osd/arduino-merkurboard/server-client.csc b/examples/osd/arduino-merkurboard/server-client.csc deleted file mode 100644 index 0c09f41b5..000000000 --- a/examples/osd/arduino-merkurboard/server-client.csc +++ /dev/null @@ -1,227 +0,0 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - REST with RPL router - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.Msp802154Radio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.Msp802154Radio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - client - Erbium Client - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c - make er-example-client.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.Msp802154Radio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 46.57186415376375 - 40.35946215910942 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - - se.sics.cooja.interfaces.Position - 18.638049428485125 - 47.55034515769599 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 3 - - client - - - - se.sics.cooja.plugins.SimControl - 259 - 0 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 - - 300 - 2 - 178 - 261 - 1 - - - se.sics.cooja.plugins.LogListener - - - - - 762 - 3 - 491 - 2 - 182 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 4 - 74 - 578 - 18 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - 2 - - - - - 125 - 25.49079397896416 - - 1624 - 5 - 252 - 6 - 712 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 2 - - Serial port - 0,0 - - 853 - 1 - 491 - 765 - 182 - - - diff --git a/examples/osd/arduino-merkurboard/server-only.csc b/examples/osd/arduino-merkurboard/server-only.csc deleted file mode 100644 index 935bd6e79..000000000 --- a/examples/osd/arduino-merkurboard/server-only.csc +++ /dev/null @@ -1,189 +0,0 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - REST with RPL router - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.Msp802154Radio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.Msp802154Radio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 35.100895239785295 - 39.70574552287428 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - se.sics.cooja.plugins.SimControl - 259 - 0 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 - - 300 - 5 - 175 - 263 - 3 - - - se.sics.cooja.plugins.LogListener - - - - - 560 - 2 - 326 - 1 - 293 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 3 - 74 - 39 - 199 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - - - - - 125 - 25.49079397896416 - - 1624 - 4 - 252 - 4 - 622 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 1 - - Serial port - 0,0 - - 702 - 1 - 646 - 564 - 2 - - - diff --git a/examples/osd/arduino-merkurboard/sketch.pde b/examples/osd/arduino-merkurboard/sketch.pde new file mode 100644 index 000000000..41df5a847 --- /dev/null +++ b/examples/osd/arduino-merkurboard/sketch.pde @@ -0,0 +1,44 @@ +/* + * Sample arduino sketch using contiki features. + * We turn the LED off + * We allow read the moisture sensor + * Unfortunately sleeping for long times in loop() isn't currently + * possible, something turns off the CPU (including PWM outputs) if a + * Proto-Thread is taking too long. We need to find out how to sleep in + * a Contiki-compatible way. + * Note that for a normal arduino sketch you won't have to include any + * of the contiki-specific files here, the sketch should just work. + */ + +extern "C" { +#include "arduino-process.h" +#include "rest-engine.h" +#include "net/netstack.h" + +extern resource_t res_led, res_battery, res_cputemp; + +uint8_t led_pin=4; +uint8_t led_status; +} + +void setup (void) +{ + // switch off the led + pinMode(led_pin, OUTPUT); + digitalWrite(led_pin, HIGH); + led_status=0; + // init coap resourcen + rest_init_engine (); + rest_activate_resource (&res_led, "s/led"); + rest_activate_resource (&res_battery, "s/battery"); + rest_activate_resource (&res_cputemp, "s/cputemp"); + + // NETSTACK_MAC.off(1); +} + +void loop (void) +{ + mcu_sleep_off(); + + mcu_sleep_on(); +} diff --git a/examples/osd/arduino-plantobserving/Makefile b/examples/osd/arduino-plantobserving/Makefile index 6ac0fc001..5a017eac0 100644 --- a/examples/osd/arduino-plantobserving/Makefile +++ b/examples/osd/arduino-plantobserving/Makefile @@ -1,22 +1,28 @@ # Set this to the name of your sketch (without extension .pde) SKETCH=sketch +EXE=arduino-example -all: arduino-example \ - arduino-example.osd-merkur.hex arduino-example.osd-merkur.eep - -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 - -# for some platforms -UIP_CONF_IPV6=1 -# IPv6 make config disappeared completely -CFLAGS += -DUIP_CONF_IPV6=1 +all: $(EXE) CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" -PROJECT_SOURCEFILES += resource_moisture.c ${SKETCH}.cpp +PROJECT_SOURCEFILES += ${SKETCH}.cpp + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) # variable for Makefile.include ifneq ($(TARGET), minimal-net) @@ -35,60 +41,15 @@ endif # linker optimizations SMALL=1 -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif -APPS += erbium time json arduino json-resource +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += arduino include $(CONTIKI)/Makefile.include include $(CONTIKI)/apps/arduino/Makefile.include -arduino-example.osd-merkur.hex: arduino-example.osd-merkur - avr-objcopy -j .text -j .data -O ihex arduino-example.osd-merkur \ - arduino-example.osd-merkur.hex - -arduino-example.osd-merkur.eep: arduino-example.osd-merkur - avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O ihex \ - arduino-example.osd-merkur arduino-example.osd-merkur.eep - -flash: arduino-example.osd-merkur.hex arduino-example.osd-merkur.eep - avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U \ - flash:w:arduino-example.osd-merkur.hex:a -U \ - eeprom:w:arduino-example.osd-merkur.eep:a - -.PHONY: flash - $(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c (cd $(CONTIKI)/tools && $(MAKE) tunslip6) @@ -100,3 +61,10 @@ connect-router-cooja: $(CONTIKI)/tools/tunslip6 connect-minimal: sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/arduino-plantobserving/flash.sh b/examples/osd/arduino-plantobserving/flash.sh index e9cb40bfc..e82962073 100755 --- a/examples/osd/arduino-plantobserving/flash.sh +++ b/examples/osd/arduino-plantobserving/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -make TARGET=osd-merkur flash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/arduino-plantobserving/moisture.h b/examples/osd/arduino-plantobserving/moisture.h deleted file mode 100644 index 4542f5d53..000000000 --- a/examples/osd/arduino-plantobserving/moisture.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - * \defgroup Arduino LED PWM example - * - * Resource definition for Arduino LED PWM module - * - * @{ - */ - -/** - * \file - * Resource definitions for the Arduino LED PWM module - * - * \author - * Ralf Schlatterbeck - */ - -#ifndef moisture_h -#define moisture_h -#include "contiki.h" -#include "contiki-net.h" -#include "erbium.h" -#include "er-coap-13.h" - -extern uint8_t moisture_pin; -extern uint16_t moisture_voltage; - -extern resource_t resource_moisture; - -#endif // moisture_h -/** @} */ diff --git a/examples/osd/arduino-plantobserving/project-conf.h b/examples/osd/arduino-plantobserving/project-conf.h index e9408e312..ffd707acd 100644 --- a/examples/osd/arduino-plantobserving/project-conf.h +++ b/examples/osd/arduino-plantobserving/project-conf.h @@ -38,6 +38,9 @@ #define SICSLOWPAN_CONF_FRAG 1 +/* Save energy */ +#define RDC_CONF_PT_YIELD_OFF + /* For Debug: Dont allow MCU sleeping between channel checks */ //#undef RDC_CONF_MCU_SLEEP //#define RDC_CONF_MCU_SLEEP 0 diff --git a/examples/osd/arduino-plantobserving/resource_moisture.c b/examples/osd/arduino-plantobserving/resource_moisture.c deleted file mode 100644 index 764021073..000000000 --- a/examples/osd/arduino-plantobserving/resource_moisture.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * \file - * Resource for Arduino PWM - * \author - * Ralf Schlatterbeck - * - * \brief get/put pwm and period for LED pin - * - */ - -#include -#include -#include -#include "contiki.h" -#include "jsonparse.h" -/* Only coap 13 for now */ -#include "er-coap-13.h" -#include "generic_resource.h" -#include "moisture.h" -#include "Arduino.h" - -size_t -moisture_v (const char *name, uint8_t is_json, char *buf, size_t bufsize) -{ - moisture_voltage = analogRead(moisture_pin); - return snprintf - (buf, bufsize, "%d", moisture_voltage); -} - -GENERIC_RESOURCE \ - ( moisture, METHOD_GET - , "moisture/v" - , Moisture voltage - , V - , NULL - , moisture_v - ); - -/* - * VI settings, see coding style - * ex:ts=8:et:sw=2 - */ diff --git a/examples/osd/arduino-plantobserving/resources/res-moisture.c b/examples/osd/arduino-plantobserving/resources/res-moisture.c new file mode 100644 index 000000000..17b5b10d6 --- /dev/null +++ b/examples/osd/arduino-plantobserving/resources/res-moisture.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Moisture resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_moisture, + "title=\"Moisture status\";rt=\"Moisture\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern uint8_t moisture_pin; +extern uint8_t moisture_vcc; +extern uint16_t moisture_voltage; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + int a=0; + for(a=0;a<10;a++){ + digitalWrite(moisture_vcc, HIGH); + digitalWrite(moisture_vcc, LOW); + } + digitalWrite(moisture_vcc, HIGH); + moisture_voltage = analogRead(moisture_pin); + digitalWrite(moisture_vcc, LOW); + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", moisture_voltage); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'moisture':%d}", moisture_voltage); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-plantobserving/run.sh b/examples/osd/arduino-plantobserving/run.sh index 295a9ab1d..5d5cbbbb4 100755 --- a/examples/osd/arduino-plantobserving/run.sh +++ b/examples/osd/arduino-plantobserving/run.sh @@ -1,5 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/arduino-plantobserving/sketch.pde b/examples/osd/arduino-plantobserving/sketch.pde index 439c62061..3db9a2ad1 100644 --- a/examples/osd/arduino-plantobserving/sketch.pde +++ b/examples/osd/arduino-plantobserving/sketch.pde @@ -11,21 +11,28 @@ */ extern "C" { -#include -#include "moisture.h" +#include "rest-engine.h" + +extern resource_t res_moisture, res_battery; +uint8_t moisture_pin = A5; +uint8_t moisture_vcc = 19; +uint16_t moisture_voltage = 0; #define LED_PIN 4 - -uint8_t moisture_pin = A5; -uint16_t moisture_voltage = 0; } void setup (void) { + // switch off the led pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, HIGH); + // init moisture sensor + pinMode(moisture_vcc, OUTPUT); + digitalWrite(moisture_vcc, LOW); + // init coap resourcen rest_init_engine (); - rest_activate_resource (&resource_moisture); + rest_activate_resource (&res_moisture, "s/moisture"); + rest_activate_resource (&res_battery, "s/battery"); } void loop (void) diff --git a/examples/osd/arduino-roller/Makefile b/examples/osd/arduino-roller/Makefile new file mode 100644 index 000000000..5ffe58cad --- /dev/null +++ b/examples/osd/arduino-roller/Makefile @@ -0,0 +1,70 @@ +# Set this to the name of your sketch (without extension .pde) +SKETCH=sketch +EXE=arduino-example + +all: $(EXE) + +CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +PROJECT_SOURCEFILES += ${SKETCH}.cpp kexp.c + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) + +# variable for Makefile.include +ifneq ($(TARGET), minimal-net) +CFLAGS += -DUIP_CONF_IPV6_RPL=1 +else +# minimal-net does not support RPL under Linux and is mostly used to test CoAP only +${info INFO: compiling without RPL} +CFLAGS += -DUIP_CONF_IPV6_RPL=0 +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=640 +endif + +# linker optimizations +SMALL=1 + + +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += arduino + +include $(CONTIKI)/Makefile.include +include $(CONTIKI)/apps/arduino/Makefile.include + +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + (cd $(CONTIKI)/tools && $(MAKE) tunslip6) + +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + +connect-minimal: + sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/arduino-roller/README.md b/examples/osd/arduino-roller/README.md new file mode 100644 index 000000000..e1490ed05 --- /dev/null +++ b/examples/osd/arduino-roller/README.md @@ -0,0 +1,11 @@ +Arduino compatibility example +============================= + +This example shows that it is now possible to re-use arduino sketches in +Contiki. This example documents the necessary magic. Arduino specifies +two routines, `setup` and `loop`. Before `setup` is called, the +framework initializes hardware. In original Arduino, all this is done in +a `main` function (in C). For contiki we define a process that does the +same. + +See the documentation file in apps/contiki-compat/README.md diff --git a/examples/osd/arduino-roller/arduino-example.c b/examples/osd/arduino-roller/arduino-example.c new file mode 100644 index 000000000..ea74dd8b8 --- /dev/null +++ b/examples/osd/arduino-roller/arduino-example.c @@ -0,0 +1,2 @@ +#include +AUTOSTART_PROCESSES(&arduino_sketch); diff --git a/examples/osd/arduino-roller/flash.sh b/examples/osd/arduino-roller/flash.sh new file mode 100755 index 000000000..e82962073 --- /dev/null +++ b/examples/osd/arduino-roller/flash.sh @@ -0,0 +1,2 @@ +#!/bin/bash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/arduino-roller/klin.c b/examples/osd/arduino-roller/klin.c new file mode 100644 index 000000000..924c15f95 --- /dev/null +++ b/examples/osd/arduino-roller/klin.c @@ -0,0 +1,1040 @@ +#include "klin.h" + +/** autogenerated lookup table */ +const uint16_t g_LOOKUP_Daumengas[] PROGMEM = +{ + /* 0 */ 0, + /* 1 */ 1, + /* 2 */ 2, + /* 3 */ 3, + /* 4 */ 4, + /* 5 */ 5, + /* 6 */ 6, + /* 7 */ 7, + /* 8 */ 8, + /* 9 */ 9, + /* 10 */ 10, + /* 11 */ 11, + /* 12 */ 12, + /* 13 */ 13, + /* 14 */ 14, + /* 15 */ 15, + /* 16 */ 16, + /* 17 */ 17, + /* 18 */ 18, + /* 19 */ 19, + /* 20 */ 20, + /* 21 */ 21, + /* 22 */ 22, + /* 23 */ 23, + /* 24 */ 24, + /* 25 */ 25, + /* 26 */ 26, + /* 27 */ 27, + /* 28 */ 28, + /* 29 */ 29, + /* 30 */ 30, + /* 31 */ 31, + /* 32 */ 32, + /* 33 */ 33, + /* 34 */ 34, + /* 35 */ 35, + /* 36 */ 36, + /* 37 */ 37, + /* 38 */ 38, + /* 39 */ 39, + /* 40 */ 40, + /* 41 */ 41, + /* 42 */ 42, + /* 43 */ 43, + /* 44 */ 44, + /* 45 */ 45, + /* 46 */ 46, + /* 47 */ 47, + /* 48 */ 48, + /* 49 */ 49, + /* 50 */ 50, + /* 51 */ 51, + /* 52 */ 52, + /* 53 */ 53, + /* 54 */ 54, + /* 55 */ 55, + /* 56 */ 56, + /* 57 */ 57, + /* 58 */ 58, + /* 59 */ 59, + /* 60 */ 60, + /* 61 */ 61, + /* 62 */ 62, + /* 63 */ 63, + /* 64 */ 64, + /* 65 */ 65, + /* 66 */ 66, + /* 67 */ 67, + /* 68 */ 68, + /* 69 */ 69, + /* 70 */ 70, + /* 71 */ 71, + /* 72 */ 72, + /* 73 */ 73, + /* 74 */ 74, + /* 75 */ 75, + /* 76 */ 76, + /* 77 */ 77, + /* 78 */ 78, + /* 79 */ 79, + /* 80 */ 80, + /* 81 */ 81, + /* 82 */ 82, + /* 83 */ 83, + /* 84 */ 84, + /* 85 */ 85, + /* 86 */ 86, + /* 87 */ 87, + /* 88 */ 88, + /* 89 */ 89, + /* 90 */ 90, + /* 91 */ 91, + /* 92 */ 92, + /* 93 */ 93, + /* 94 */ 94, + /* 95 */ 95, + /* 96 */ 96, + /* 97 */ 97, + /* 98 */ 98, + /* 99 */ 99, + /* 100 */ 100, + /* 101 */ 101, + /* 102 */ 102, + /* 103 */ 103, + /* 104 */ 104, + /* 105 */ 105, + /* 106 */ 106, + /* 107 */ 107, + /* 108 */ 108, + /* 109 */ 109, + /* 110 */ 110, + /* 111 */ 111, + /* 112 */ 112, + /* 113 */ 113, + /* 114 */ 114, + /* 115 */ 115, + /* 116 */ 116, + /* 117 */ 117, + /* 118 */ 118, + /* 119 */ 119, + /* 120 */ 120, + /* 121 */ 121, + /* 122 */ 122, + /* 123 */ 123, + /* 124 */ 124, + /* 125 */ 125, + /* 126 */ 126, + /* 127 */ 127, + /* 128 */ 128, + /* 129 */ 129, + /* 130 */ 130, + /* 131 */ 131, + /* 132 */ 132, + /* 133 */ 133, + /* 134 */ 134, + /* 135 */ 135, + /* 136 */ 136, + /* 137 */ 137, + /* 138 */ 138, + /* 139 */ 139, + /* 140 */ 140, + /* 141 */ 141, + /* 142 */ 142, + /* 143 */ 143, + /* 144 */ 144, + /* 145 */ 145, + /* 146 */ 146, + /* 147 */ 147, + /* 148 */ 148, + /* 149 */ 149, + /* 150 */ 150, + /* 151 */ 151, + /* 152 */ 152, + /* 153 */ 153, + /* 154 */ 154, + /* 155 */ 155, + /* 156 */ 156, + /* 157 */ 157, + /* 158 */ 158, + /* 159 */ 159, + /* 160 */ 160, + /* 161 */ 161, + /* 162 */ 162, + /* 163 */ 163, + /* 164 */ 164, + /* 165 */ 165, + /* 166 */ 166, + /* 167 */ 167, + /* 168 */ 168, + /* 169 */ 169, + /* 170 */ 170, + /* 171 */ 171, + /* 172 */ 172, + /* 173 */ 173, + /* 174 */ 174, + /* 175 */ 175, + /* 176 */ 176, + /* 177 */ 177, + /* 178 */ 178, + /* 179 */ 179, + /* 180 */ 180, + /* 181 */ 181, + /* 182 */ 182, + /* 183 */ 183, + /* 184 */ 184, + /* 185 */ 185, + /* 186 */ 186, + /* 187 */ 187, + /* 188 */ 188, + /* 189 */ 189, + /* 190 */ 190, + /* 191 */ 191, + /* 192 */ 192, + /* 193 */ 193, + /* 194 */ 194, + /* 195 */ 195, + /* 196 */ 196, + /* 197 */ 197, + /* 198 */ 198, + /* 199 */ 199, + /* 200 */ 200, + /* 201 */ 201, + /* 202 */ 202, + /* 203 */ 203, + /* 204 */ 204, + /* 205 */ 205, + /* 206 */ 206, + /* 207 */ 207, + /* 208 */ 208, + /* 209 */ 209, + /* 210 */ 210, + /* 211 */ 211, + /* 212 */ 212, + /* 213 */ 213, + /* 214 */ 214, + /* 215 */ 215, + /* 216 */ 216, + /* 217 */ 217, + /* 218 */ 218, + /* 219 */ 219, + /* 220 */ 220, + /* 221 */ 221, + /* 222 */ 222, + /* 223 */ 223, + /* 224 */ 224, + /* 225 */ 225, + /* 226 */ 226, + /* 227 */ 227, + /* 228 */ 228, + /* 229 */ 229, + /* 230 */ 230, + /* 231 */ 231, + /* 232 */ 232, + /* 233 */ 233, + /* 234 */ 234, + /* 235 */ 235, + /* 236 */ 236, + /* 237 */ 237, + /* 238 */ 238, + /* 239 */ 239, + /* 240 */ 240, + /* 241 */ 241, + /* 242 */ 242, + /* 243 */ 243, + /* 244 */ 244, + /* 245 */ 245, + /* 246 */ 246, + /* 247 */ 247, + /* 248 */ 248, + /* 249 */ 249, + /* 250 */ 250, + /* 251 */ 251, + /* 252 */ 252, + /* 253 */ 253, + /* 254 */ 254, + /* 255 */ 255, + /* 256 */ 256, + /* 257 */ 257, + /* 258 */ 258, + /* 259 */ 259, + /* 260 */ 260, + /* 261 */ 261, + /* 262 */ 262, + /* 263 */ 263, + /* 264 */ 264, + /* 265 */ 265, + /* 266 */ 266, + /* 267 */ 267, + /* 268 */ 268, + /* 269 */ 269, + /* 270 */ 270, + /* 271 */ 271, + /* 272 */ 272, + /* 273 */ 273, + /* 274 */ 274, + /* 275 */ 275, + /* 276 */ 276, + /* 277 */ 277, + /* 278 */ 278, + /* 279 */ 279, + /* 280 */ 280, + /* 281 */ 281, + /* 282 */ 282, + /* 283 */ 283, + /* 284 */ 284, + /* 285 */ 285, + /* 286 */ 286, + /* 287 */ 287, + /* 288 */ 288, + /* 289 */ 289, + /* 290 */ 290, + /* 291 */ 291, + /* 292 */ 292, + /* 293 */ 293, + /* 294 */ 294, + /* 295 */ 295, + /* 296 */ 296, + /* 297 */ 297, + /* 298 */ 298, + /* 299 */ 299, + /* 300 */ 300, + /* 301 */ 301, + /* 302 */ 302, + /* 303 */ 303, + /* 304 */ 304, + /* 305 */ 305, + /* 306 */ 306, + /* 307 */ 307, + /* 308 */ 308, + /* 309 */ 309, + /* 310 */ 310, + /* 311 */ 311, + /* 312 */ 312, + /* 313 */ 313, + /* 314 */ 314, + /* 315 */ 315, + /* 316 */ 316, + /* 317 */ 317, + /* 318 */ 318, + /* 319 */ 319, + /* 320 */ 320, + /* 321 */ 321, + /* 322 */ 322, + /* 323 */ 323, + /* 324 */ 324, + /* 325 */ 325, + /* 326 */ 326, + /* 327 */ 327, + /* 328 */ 328, + /* 329 */ 329, + /* 330 */ 330, + /* 331 */ 331, + /* 332 */ 332, + /* 333 */ 333, + /* 334 */ 334, + /* 335 */ 335, + /* 336 */ 336, + /* 337 */ 337, + /* 338 */ 338, + /* 339 */ 339, + /* 340 */ 340, + /* 341 */ 341, + /* 342 */ 342, + /* 343 */ 343, + /* 344 */ 344, + /* 345 */ 345, + /* 346 */ 346, + /* 347 */ 347, + /* 348 */ 348, + /* 349 */ 349, + /* 350 */ 350, + /* 351 */ 351, + /* 352 */ 352, + /* 353 */ 353, + /* 354 */ 354, + /* 355 */ 355, + /* 356 */ 356, + /* 357 */ 357, + /* 358 */ 358, + /* 359 */ 359, + /* 360 */ 360, + /* 361 */ 361, + /* 362 */ 362, + /* 363 */ 363, + /* 364 */ 364, + /* 365 */ 365, + /* 366 */ 366, + /* 367 */ 367, + /* 368 */ 368, + /* 369 */ 369, + /* 370 */ 370, + /* 371 */ 371, + /* 372 */ 372, + /* 373 */ 373, + /* 374 */ 374, + /* 375 */ 375, + /* 376 */ 376, + /* 377 */ 377, + /* 378 */ 378, + /* 379 */ 379, + /* 380 */ 380, + /* 381 */ 381, + /* 382 */ 382, + /* 383 */ 383, + /* 384 */ 384, + /* 385 */ 385, + /* 386 */ 386, + /* 387 */ 387, + /* 388 */ 388, + /* 389 */ 389, + /* 390 */ 390, + /* 391 */ 391, + /* 392 */ 392, + /* 393 */ 393, + /* 394 */ 394, + /* 395 */ 395, + /* 396 */ 396, + /* 397 */ 397, + /* 398 */ 398, + /* 399 */ 399, + /* 400 */ 400, + /* 401 */ 401, + /* 402 */ 402, + /* 403 */ 403, + /* 404 */ 404, + /* 405 */ 405, + /* 406 */ 406, + /* 407 */ 407, + /* 408 */ 408, + /* 409 */ 409, + /* 410 */ 410, + /* 411 */ 411, + /* 412 */ 412, + /* 413 */ 413, + /* 414 */ 414, + /* 415 */ 415, + /* 416 */ 416, + /* 417 */ 417, + /* 418 */ 418, + /* 419 */ 419, + /* 420 */ 420, + /* 421 */ 421, + /* 422 */ 422, + /* 423 */ 423, + /* 424 */ 424, + /* 425 */ 425, + /* 426 */ 426, + /* 427 */ 427, + /* 428 */ 428, + /* 429 */ 429, + /* 430 */ 430, + /* 431 */ 431, + /* 432 */ 432, + /* 433 */ 433, + /* 434 */ 434, + /* 435 */ 435, + /* 436 */ 436, + /* 437 */ 437, + /* 438 */ 438, + /* 439 */ 439, + /* 440 */ 440, + /* 441 */ 441, + /* 442 */ 442, + /* 443 */ 443, + /* 444 */ 444, + /* 445 */ 445, + /* 446 */ 446, + /* 447 */ 447, + /* 448 */ 448, + /* 449 */ 449, + /* 450 */ 450, + /* 451 */ 451, + /* 452 */ 452, + /* 453 */ 453, + /* 454 */ 454, + /* 455 */ 455, + /* 456 */ 456, + /* 457 */ 457, + /* 458 */ 458, + /* 459 */ 459, + /* 460 */ 460, + /* 461 */ 461, + /* 462 */ 462, + /* 463 */ 463, + /* 464 */ 464, + /* 465 */ 465, + /* 466 */ 466, + /* 467 */ 467, + /* 468 */ 468, + /* 469 */ 469, + /* 470 */ 470, + /* 471 */ 471, + /* 472 */ 472, + /* 473 */ 473, + /* 474 */ 474, + /* 475 */ 475, + /* 476 */ 476, + /* 477 */ 477, + /* 478 */ 478, + /* 479 */ 479, + /* 480 */ 480, + /* 481 */ 481, + /* 482 */ 482, + /* 483 */ 483, + /* 484 */ 484, + /* 485 */ 485, + /* 486 */ 486, + /* 487 */ 487, + /* 488 */ 488, + /* 489 */ 489, + /* 490 */ 490, + /* 491 */ 491, + /* 492 */ 492, + /* 493 */ 493, + /* 494 */ 494, + /* 495 */ 495, + /* 496 */ 496, + /* 497 */ 497, + /* 498 */ 498, + /* 499 */ 499, + /* 500 */ 500, + /* 501 */ 501, + /* 502 */ 502, + /* 503 */ 503, + /* 504 */ 504, + /* 505 */ 505, + /* 506 */ 506, + /* 507 */ 507, + /* 508 */ 508, + /* 509 */ 509, + /* 510 */ 510, + /* 511 */ 511, + /* 512 */ 512, + /* 513 */ 513, + /* 514 */ 514, + /* 515 */ 515, + /* 516 */ 516, + /* 517 */ 517, + /* 518 */ 518, + /* 519 */ 519, + /* 520 */ 520, + /* 521 */ 521, + /* 522 */ 522, + /* 523 */ 523, + /* 524 */ 524, + /* 525 */ 525, + /* 526 */ 526, + /* 527 */ 527, + /* 528 */ 528, + /* 529 */ 529, + /* 530 */ 530, + /* 531 */ 531, + /* 532 */ 532, + /* 533 */ 533, + /* 534 */ 534, + /* 535 */ 535, + /* 536 */ 536, + /* 537 */ 537, + /* 538 */ 538, + /* 539 */ 539, + /* 540 */ 540, + /* 541 */ 541, + /* 542 */ 542, + /* 543 */ 543, + /* 544 */ 544, + /* 545 */ 545, + /* 546 */ 546, + /* 547 */ 547, + /* 548 */ 548, + /* 549 */ 549, + /* 550 */ 550, + /* 551 */ 551, + /* 552 */ 552, + /* 553 */ 553, + /* 554 */ 554, + /* 555 */ 555, + /* 556 */ 556, + /* 557 */ 557, + /* 558 */ 558, + /* 559 */ 559, + /* 560 */ 560, + /* 561 */ 561, + /* 562 */ 562, + /* 563 */ 563, + /* 564 */ 564, + /* 565 */ 565, + /* 566 */ 566, + /* 567 */ 567, + /* 568 */ 568, + /* 569 */ 569, + /* 570 */ 570, + /* 571 */ 571, + /* 572 */ 572, + /* 573 */ 573, + /* 574 */ 574, + /* 575 */ 575, + /* 576 */ 576, + /* 577 */ 577, + /* 578 */ 578, + /* 579 */ 579, + /* 580 */ 580, + /* 581 */ 581, + /* 582 */ 582, + /* 583 */ 583, + /* 584 */ 584, + /* 585 */ 585, + /* 586 */ 586, + /* 587 */ 587, + /* 588 */ 588, + /* 589 */ 589, + /* 590 */ 590, + /* 591 */ 591, + /* 592 */ 592, + /* 593 */ 593, + /* 594 */ 594, + /* 595 */ 595, + /* 596 */ 596, + /* 597 */ 597, + /* 598 */ 598, + /* 599 */ 599, + /* 600 */ 600, + /* 601 */ 601, + /* 602 */ 602, + /* 603 */ 603, + /* 604 */ 604, + /* 605 */ 605, + /* 606 */ 606, + /* 607 */ 607, + /* 608 */ 608, + /* 609 */ 609, + /* 610 */ 610, + /* 611 */ 611, + /* 612 */ 612, + /* 613 */ 613, + /* 614 */ 614, + /* 615 */ 615, + /* 616 */ 616, + /* 617 */ 617, + /* 618 */ 618, + /* 619 */ 619, + /* 620 */ 620, + /* 621 */ 621, + /* 622 */ 622, + /* 623 */ 623, + /* 624 */ 624, + /* 625 */ 625, + /* 626 */ 626, + /* 627 */ 627, + /* 628 */ 628, + /* 629 */ 629, + /* 630 */ 630, + /* 631 */ 631, + /* 632 */ 632, + /* 633 */ 633, + /* 634 */ 634, + /* 635 */ 635, + /* 636 */ 636, + /* 637 */ 637, + /* 638 */ 638, + /* 639 */ 639, + /* 640 */ 640, + /* 641 */ 641, + /* 642 */ 642, + /* 643 */ 643, + /* 644 */ 644, + /* 645 */ 645, + /* 646 */ 646, + /* 647 */ 647, + /* 648 */ 648, + /* 649 */ 649, + /* 650 */ 650, + /* 651 */ 651, + /* 652 */ 652, + /* 653 */ 653, + /* 654 */ 654, + /* 655 */ 655, + /* 656 */ 656, + /* 657 */ 657, + /* 658 */ 658, + /* 659 */ 659, + /* 660 */ 660, + /* 661 */ 661, + /* 662 */ 662, + /* 663 */ 663, + /* 664 */ 664, + /* 665 */ 665, + /* 666 */ 666, + /* 667 */ 667, + /* 668 */ 668, + /* 669 */ 669, + /* 670 */ 670, + /* 671 */ 671, + /* 672 */ 672, + /* 673 */ 673, + /* 674 */ 674, + /* 675 */ 675, + /* 676 */ 676, + /* 677 */ 677, + /* 678 */ 678, + /* 679 */ 679, + /* 680 */ 680, + /* 681 */ 681, + /* 682 */ 682, + /* 683 */ 683, + /* 684 */ 684, + /* 685 */ 685, + /* 686 */ 686, + /* 687 */ 687, + /* 688 */ 688, + /* 689 */ 689, + /* 690 */ 690, + /* 691 */ 691, + /* 692 */ 692, + /* 693 */ 693, + /* 694 */ 694, + /* 695 */ 695, + /* 696 */ 696, + /* 697 */ 697, + /* 698 */ 698, + /* 699 */ 699, + /* 700 */ 700, + /* 701 */ 701, + /* 702 */ 702, + /* 703 */ 703, + /* 704 */ 704, + /* 705 */ 705, + /* 706 */ 706, + /* 707 */ 707, + /* 708 */ 708, + /* 709 */ 709, + /* 710 */ 710, + /* 711 */ 711, + /* 712 */ 712, + /* 713 */ 713, + /* 714 */ 714, + /* 715 */ 715, + /* 716 */ 716, + /* 717 */ 717, + /* 718 */ 718, + /* 719 */ 719, + /* 720 */ 720, + /* 721 */ 721, + /* 722 */ 722, + /* 723 */ 723, + /* 724 */ 724, + /* 725 */ 725, + /* 726 */ 726, + /* 727 */ 727, + /* 728 */ 728, + /* 729 */ 729, + /* 730 */ 730, + /* 731 */ 731, + /* 732 */ 732, + /* 733 */ 733, + /* 734 */ 734, + /* 735 */ 735, + /* 736 */ 736, + /* 737 */ 737, + /* 738 */ 738, + /* 739 */ 739, + /* 740 */ 740, + /* 741 */ 741, + /* 742 */ 742, + /* 743 */ 743, + /* 744 */ 744, + /* 745 */ 745, + /* 746 */ 746, + /* 747 */ 747, + /* 748 */ 748, + /* 749 */ 749, + /* 750 */ 750, + /* 751 */ 751, + /* 752 */ 752, + /* 753 */ 753, + /* 754 */ 754, + /* 755 */ 755, + /* 756 */ 756, + /* 757 */ 757, + /* 758 */ 758, + /* 759 */ 759, + /* 760 */ 760, + /* 761 */ 761, + /* 762 */ 762, + /* 763 */ 763, + /* 764 */ 764, + /* 765 */ 765, + /* 766 */ 766, + /* 767 */ 767, + /* 768 */ 768, + /* 769 */ 769, + /* 770 */ 770, + /* 771 */ 771, + /* 772 */ 772, + /* 773 */ 773, + /* 774 */ 774, + /* 775 */ 775, + /* 776 */ 776, + /* 777 */ 777, + /* 778 */ 778, + /* 779 */ 779, + /* 780 */ 780, + /* 781 */ 781, + /* 782 */ 782, + /* 783 */ 783, + /* 784 */ 784, + /* 785 */ 785, + /* 786 */ 786, + /* 787 */ 787, + /* 788 */ 788, + /* 789 */ 789, + /* 790 */ 790, + /* 791 */ 791, + /* 792 */ 792, + /* 793 */ 793, + /* 794 */ 794, + /* 795 */ 795, + /* 796 */ 796, + /* 797 */ 797, + /* 798 */ 798, + /* 799 */ 799, + /* 800 */ 800, + /* 801 */ 801, + /* 802 */ 802, + /* 803 */ 803, + /* 804 */ 804, + /* 805 */ 805, + /* 806 */ 806, + /* 807 */ 807, + /* 808 */ 808, + /* 809 */ 809, + /* 810 */ 810, + /* 811 */ 811, + /* 812 */ 812, + /* 813 */ 813, + /* 814 */ 814, + /* 815 */ 815, + /* 816 */ 816, + /* 817 */ 817, + /* 818 */ 818, + /* 819 */ 819, + /* 820 */ 820, + /* 821 */ 821, + /* 822 */ 822, + /* 823 */ 823, + /* 824 */ 824, + /* 825 */ 825, + /* 826 */ 826, + /* 827 */ 827, + /* 828 */ 828, + /* 829 */ 829, + /* 830 */ 830, + /* 831 */ 831, + /* 832 */ 832, + /* 833 */ 833, + /* 834 */ 834, + /* 835 */ 835, + /* 836 */ 836, + /* 837 */ 837, + /* 838 */ 838, + /* 839 */ 839, + /* 840 */ 840, + /* 841 */ 841, + /* 842 */ 842, + /* 843 */ 843, + /* 844 */ 844, + /* 845 */ 845, + /* 846 */ 846, + /* 847 */ 847, + /* 848 */ 848, + /* 849 */ 849, + /* 850 */ 850, + /* 851 */ 851, + /* 852 */ 852, + /* 853 */ 853, + /* 854 */ 854, + /* 855 */ 855, + /* 856 */ 856, + /* 857 */ 857, + /* 858 */ 858, + /* 859 */ 859, + /* 860 */ 860, + /* 861 */ 861, + /* 862 */ 862, + /* 863 */ 863, + /* 864 */ 864, + /* 865 */ 865, + /* 866 */ 866, + /* 867 */ 867, + /* 868 */ 868, + /* 869 */ 869, + /* 870 */ 870, + /* 871 */ 871, + /* 872 */ 872, + /* 873 */ 873, + /* 874 */ 874, + /* 875 */ 875, + /* 876 */ 876, + /* 877 */ 877, + /* 878 */ 878, + /* 879 */ 879, + /* 880 */ 880, + /* 881 */ 881, + /* 882 */ 882, + /* 883 */ 883, + /* 884 */ 884, + /* 885 */ 885, + /* 886 */ 886, + /* 887 */ 887, + /* 888 */ 888, + /* 889 */ 889, + /* 890 */ 890, + /* 891 */ 891, + /* 892 */ 892, + /* 893 */ 893, + /* 894 */ 894, + /* 895 */ 895, + /* 896 */ 896, + /* 897 */ 897, + /* 898 */ 898, + /* 899 */ 899, + /* 900 */ 900, + /* 901 */ 901, + /* 902 */ 902, + /* 903 */ 903, + /* 904 */ 904, + /* 905 */ 905, + /* 906 */ 906, + /* 907 */ 907, + /* 908 */ 908, + /* 909 */ 909, + /* 910 */ 910, + /* 911 */ 911, + /* 912 */ 912, + /* 913 */ 913, + /* 914 */ 914, + /* 915 */ 915, + /* 916 */ 916, + /* 917 */ 917, + /* 918 */ 918, + /* 919 */ 919, + /* 920 */ 920, + /* 921 */ 921, + /* 922 */ 922, + /* 923 */ 923, + /* 924 */ 924, + /* 925 */ 925, + /* 926 */ 926, + /* 927 */ 927, + /* 928 */ 928, + /* 929 */ 929, + /* 930 */ 930, + /* 931 */ 931, + /* 932 */ 932, + /* 933 */ 933, + /* 934 */ 934, + /* 935 */ 935, + /* 936 */ 936, + /* 937 */ 937, + /* 938 */ 938, + /* 939 */ 939, + /* 940 */ 940, + /* 941 */ 941, + /* 942 */ 942, + /* 943 */ 943, + /* 944 */ 944, + /* 945 */ 945, + /* 946 */ 946, + /* 947 */ 947, + /* 948 */ 948, + /* 949 */ 949, + /* 950 */ 950, + /* 951 */ 951, + /* 952 */ 952, + /* 953 */ 953, + /* 954 */ 954, + /* 955 */ 955, + /* 956 */ 956, + /* 957 */ 957, + /* 958 */ 958, + /* 959 */ 959, + /* 960 */ 960, + /* 961 */ 961, + /* 962 */ 962, + /* 963 */ 963, + /* 964 */ 964, + /* 965 */ 965, + /* 966 */ 966, + /* 967 */ 967, + /* 968 */ 968, + /* 969 */ 969, + /* 970 */ 970, + /* 971 */ 971, + /* 972 */ 972, + /* 973 */ 973, + /* 974 */ 974, + /* 975 */ 975, + /* 976 */ 976, + /* 977 */ 977, + /* 978 */ 978, + /* 979 */ 979, + /* 980 */ 980, + /* 981 */ 981, + /* 982 */ 982, + /* 983 */ 983, + /* 984 */ 984, + /* 985 */ 985, + /* 986 */ 986, + /* 987 */ 987, + /* 988 */ 988, + /* 989 */ 989, + /* 990 */ 990, + /* 991 */ 991, + /* 992 */ 992, + /* 993 */ 993, + /* 994 */ 994, + /* 995 */ 995, + /* 996 */ 996, + /* 997 */ 997, + /* 998 */ 998, + /* 999 */ 999, + /* 1000 */ 1000, + /* 1001 */ 1001, + /* 1002 */ 1002, + /* 1003 */ 1003, + /* 1004 */ 1004, + /* 1005 */ 1005, + /* 1006 */ 1006, + /* 1007 */ 1007, + /* 1008 */ 1008, + /* 1009 */ 1009, + /* 1010 */ 1010, + /* 1011 */ 1011, + /* 1012 */ 1012, + /* 1013 */ 1013, + /* 1014 */ 1014, + /* 1015 */ 1015, + /* 1016 */ 1016, + /* 1017 */ 1017, + /* 1018 */ 1018, + /* 1019 */ 1019, + /* 1020 */ 1020, + /* 1021 */ 1021, + /* 1022 */ 1022, + /* 1023 */ 1023, +}; + +uint16_t lookup_Daumengas(uint16_t i) +{ + if (i <= 1023) + return pgm_read_word(&g_LOOKUP_Daumengas[i]); + else + return 6666; /* #HighValue */ +} + + diff --git a/examples/osd/arduino-roller/klin.h b/examples/osd/arduino-roller/klin.h new file mode 100644 index 000000000..a2056fc73 --- /dev/null +++ b/examples/osd/arduino-roller/klin.h @@ -0,0 +1,15 @@ +#ifndef klin_h_ +#define klin_h_ + +#include +#include + +/** + * autogenerated lookup function for Daumengas + * @param i x value + * @return f(i), or 6666 if i is out of range + */ +uint16_t lookup_Daumengas(uint16_t i); + +#endif /* klin_h_ */ + diff --git a/examples/osd/arduino-roller/project-conf.h b/examples/osd/arduino-roller/project-conf.h new file mode 100644 index 000000000..9557123e4 --- /dev/null +++ b/examples/osd/arduino-roller/project-conf.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ + +#ifndef PROJECT_RPL_WEB_CONF_H_ +#define PROJECT_RPL_WEB_CONF_H_ + +#define PLATFORM_HAS_LEDS 1 +//#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_BATTERY 1 + +#define SICSLOWPAN_CONF_FRAG 1 + +/* Save energy */ +//#define RDC_CONF_PT_YIELD_OFF + +/* For Debug: Dont allow MCU sleeping between channel checks */ +#undef RDC_CONF_MCU_SLEEP +#define RDC_CONF_MCU_SLEEP 0 + +#define LOOP_INTERVAL (CLOCK_SECOND / 10) +/* Disabling RDC for demo purposes. Core updates often require more memory. */ +/* For projects, optimize memory and enable RDC again. */ +// #undef NETSTACK_CONF_RDC +//#define NETSTACK_CONF_RDC nullrdc_driver + +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 64 + +/* Estimate your header size, especially when using Proxy-Uri. */ +/* +#undef COAP_MAX_HEADER_SIZE +#define COAP_MAX_HEADER_SIZE 70 +*/ + +/* The IP buffer size must fit all other hops, in particular the border router. */ + +#undef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 256 + + +/* Multiplies with chunk size, be aware of memory constraints. */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* +#undef COAP_MAX_OBSERVERS +#define COAP_MAX_OBSERVERS 2 +*/ + +/* Filtering .well-known/core per query can be disabled to save space. */ +/* +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +*/ + +/* Save some memory for the sky platform. */ +/* +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 10 +*/ + +/* Reduce 802.15.4 frame queue to save RAM. */ +/* +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 +*/ + +/* +#undef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +*/ + +#endif /* PROJECT_RPL_WEB_CONF_H_ */ diff --git a/examples/osd/arduino-roller/resources/res-poti.c b/examples/osd/arduino-roller/resources/res-poti.c new file mode 100644 index 000000000..a05a05b32 --- /dev/null +++ b/examples/osd/arduino-roller/resources/res-poti.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Moisture resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_poti, + "title=\"Moisture status\";rt=\"Moisture\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern uint8_t poti_pin; +extern uint16_t poti_voltage; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", poti_voltage); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'poti':%d}", poti_voltage); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-roller/run.sh b/examples/osd/arduino-roller/run.sh new file mode 100755 index 000000000..5d5cbbbb4 --- /dev/null +++ b/examples/osd/arduino-roller/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/arduino-roller/sketch.pde b/examples/osd/arduino-roller/sketch.pde new file mode 100644 index 000000000..f836a8b92 --- /dev/null +++ b/examples/osd/arduino-roller/sketch.pde @@ -0,0 +1,63 @@ +/* + * Sample arduino sketch using contiki features. + * We turn the LED off + * We allow read the poti sensor + * Unfortunately sleeping for long times in loop() isn't currently + * possible, something turns off the CPU (including PWM outputs) if a + * Proto-Thread is taking too long. We need to find out how to sleep in + * a Contiki-compatible way. + * Note that for a normal arduino sketch you won't have to include any + * of the contiki-specific files here, the sketch should just work. + */ + +extern "C" { +#include "rest-engine.h" +#include "dev/servo.h" +#include "kexp.h" // exponential values lookup table + +extern resource_t res_poti, res_battery; +uint8_t poti_pin = A5; +uint16_t poti_voltage = 0; + +uint16_t servo_min= 1000; +uint16_t servo_max= 2000; + +#define LED_PIN 4 +} + +//**********************scale********************************** + + int scale (int in_min, int in_max, int out_min, int out_max, int wert) + { + int abc; + + abc = ((long)out_max - (long)out_min)* ((long)wert-(long)in_min) / ( (long)in_max - (long)in_min); + abc = abc + out_min; + + return (abc); + } + +void setup (void) +{ + // switch off the led + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, HIGH); + // init servo + servo_init(); + // init coap resourcen + rest_init_engine (); + rest_activate_resource (&res_poti, "s/poti"); + rest_activate_resource (&res_battery, "s/battery"); +} + +void loop (void) +{ + int value; + int vlookup; + poti_voltage = analogRead(poti_pin); + value=scale (345,868,servo_min,servo_max,poti_voltage); + vlookup=lookup_Daumengas(value-servo_min)+servo_min; + servo_set(1,vlookup); +// servo_set(1,value); + printf("%d,%d,%d\n",poti_voltage,value,vlookup); +} diff --git a/examples/osd/arduino-roller/tools/1.c b/examples/osd/arduino-roller/tools/1.c new file mode 100644 index 000000000..1dd9e74ca --- /dev/null +++ b/examples/osd/arduino-roller/tools/1.c @@ -0,0 +1,1040 @@ +#include "1.h" + +/** autogenerated lookup table */ +const uint16_t g_LOOKUP_MyFavoriteSensor[] PROGMEM = +{ + /* 0 */ 5, + /* 1 */ 6, + /* 2 */ 7, + /* 3 */ 8, + /* 4 */ 9, + /* 5 */ 10, + /* 6 */ 11, + /* 7 */ 12, + /* 8 */ 13, + /* 9 */ 14, + /* 10 */ 15, + /* 11 */ 16, + /* 12 */ 17, + /* 13 */ 18, + /* 14 */ 19, + /* 15 */ 20, + /* 16 */ 21, + /* 17 */ 22, + /* 18 */ 23, + /* 19 */ 24, + /* 20 */ 25, + /* 21 */ 26, + /* 22 */ 27, + /* 23 */ 28, + /* 24 */ 29, + /* 25 */ 30, + /* 26 */ 31, + /* 27 */ 32, + /* 28 */ 33, + /* 29 */ 34, + /* 30 */ 35, + /* 31 */ 36, + /* 32 */ 37, + /* 33 */ 38, + /* 34 */ 39, + /* 35 */ 40, + /* 36 */ 41, + /* 37 */ 42, + /* 38 */ 43, + /* 39 */ 44, + /* 40 */ 45, + /* 41 */ 46, + /* 42 */ 47, + /* 43 */ 48, + /* 44 */ 49, + /* 45 */ 50, + /* 46 */ 51, + /* 47 */ 52, + /* 48 */ 53, + /* 49 */ 54, + /* 50 */ 55, + /* 51 */ 56, + /* 52 */ 57, + /* 53 */ 58, + /* 54 */ 59, + /* 55 */ 60, + /* 56 */ 61, + /* 57 */ 62, + /* 58 */ 63, + /* 59 */ 64, + /* 60 */ 65, + /* 61 */ 66, + /* 62 */ 67, + /* 63 */ 68, + /* 64 */ 69, + /* 65 */ 70, + /* 66 */ 71, + /* 67 */ 72, + /* 68 */ 73, + /* 69 */ 74, + /* 70 */ 75, + /* 71 */ 76, + /* 72 */ 77, + /* 73 */ 78, + /* 74 */ 79, + /* 75 */ 80, + /* 76 */ 81, + /* 77 */ 82, + /* 78 */ 83, + /* 79 */ 84, + /* 80 */ 85, + /* 81 */ 86, + /* 82 */ 87, + /* 83 */ 88, + /* 84 */ 89, + /* 85 */ 90, + /* 86 */ 91, + /* 87 */ 92, + /* 88 */ 93, + /* 89 */ 94, + /* 90 */ 95, + /* 91 */ 96, + /* 92 */ 97, + /* 93 */ 98, + /* 94 */ 99, + /* 95 */ 100, + /* 96 */ 101, + /* 97 */ 102, + /* 98 */ 103, + /* 99 */ 104, + /* 100 */ 105, + /* 101 */ 106, + /* 102 */ 107, + /* 103 */ 108, + /* 104 */ 109, + /* 105 */ 110, + /* 106 */ 111, + /* 107 */ 112, + /* 108 */ 113, + /* 109 */ 114, + /* 110 */ 115, + /* 111 */ 116, + /* 112 */ 117, + /* 113 */ 118, + /* 114 */ 119, + /* 115 */ 120, + /* 116 */ 121, + /* 117 */ 122, + /* 118 */ 123, + /* 119 */ 124, + /* 120 */ 125, + /* 121 */ 126, + /* 122 */ 127, + /* 123 */ 128, + /* 124 */ 129, + /* 125 */ 130, + /* 126 */ 131, + /* 127 */ 132, + /* 128 */ 133, + /* 129 */ 134, + /* 130 */ 135, + /* 131 */ 136, + /* 132 */ 137, + /* 133 */ 138, + /* 134 */ 139, + /* 135 */ 140, + /* 136 */ 141, + /* 137 */ 142, + /* 138 */ 143, + /* 139 */ 144, + /* 140 */ 145, + /* 141 */ 146, + /* 142 */ 147, + /* 143 */ 148, + /* 144 */ 149, + /* 145 */ 150, + /* 146 */ 151, + /* 147 */ 152, + /* 148 */ 153, + /* 149 */ 154, + /* 150 */ 155, + /* 151 */ 156, + /* 152 */ 157, + /* 153 */ 158, + /* 154 */ 159, + /* 155 */ 160, + /* 156 */ 161, + /* 157 */ 162, + /* 158 */ 163, + /* 159 */ 164, + /* 160 */ 165, + /* 161 */ 166, + /* 162 */ 167, + /* 163 */ 168, + /* 164 */ 169, + /* 165 */ 170, + /* 166 */ 171, + /* 167 */ 172, + /* 168 */ 173, + /* 169 */ 174, + /* 170 */ 175, + /* 171 */ 176, + /* 172 */ 177, + /* 173 */ 178, + /* 174 */ 179, + /* 175 */ 180, + /* 176 */ 181, + /* 177 */ 182, + /* 178 */ 183, + /* 179 */ 184, + /* 180 */ 185, + /* 181 */ 186, + /* 182 */ 187, + /* 183 */ 188, + /* 184 */ 189, + /* 185 */ 190, + /* 186 */ 191, + /* 187 */ 192, + /* 188 */ 193, + /* 189 */ 194, + /* 190 */ 195, + /* 191 */ 196, + /* 192 */ 197, + /* 193 */ 198, + /* 194 */ 199, + /* 195 */ 200, + /* 196 */ 201, + /* 197 */ 202, + /* 198 */ 203, + /* 199 */ 204, + /* 200 */ 205, + /* 201 */ 206, + /* 202 */ 207, + /* 203 */ 208, + /* 204 */ 209, + /* 205 */ 210, + /* 206 */ 211, + /* 207 */ 212, + /* 208 */ 213, + /* 209 */ 214, + /* 210 */ 215, + /* 211 */ 216, + /* 212 */ 217, + /* 213 */ 218, + /* 214 */ 219, + /* 215 */ 220, + /* 216 */ 221, + /* 217 */ 222, + /* 218 */ 223, + /* 219 */ 224, + /* 220 */ 225, + /* 221 */ 226, + /* 222 */ 227, + /* 223 */ 228, + /* 224 */ 229, + /* 225 */ 230, + /* 226 */ 231, + /* 227 */ 232, + /* 228 */ 233, + /* 229 */ 234, + /* 230 */ 235, + /* 231 */ 236, + /* 232 */ 237, + /* 233 */ 238, + /* 234 */ 239, + /* 235 */ 240, + /* 236 */ 241, + /* 237 */ 242, + /* 238 */ 243, + /* 239 */ 244, + /* 240 */ 245, + /* 241 */ 246, + /* 242 */ 247, + /* 243 */ 248, + /* 244 */ 249, + /* 245 */ 250, + /* 246 */ 251, + /* 247 */ 252, + /* 248 */ 253, + /* 249 */ 254, + /* 250 */ 255, + /* 251 */ 256, + /* 252 */ 257, + /* 253 */ 258, + /* 254 */ 259, + /* 255 */ 260, + /* 256 */ 261, + /* 257 */ 262, + /* 258 */ 263, + /* 259 */ 264, + /* 260 */ 265, + /* 261 */ 266, + /* 262 */ 267, + /* 263 */ 268, + /* 264 */ 269, + /* 265 */ 270, + /* 266 */ 271, + /* 267 */ 272, + /* 268 */ 273, + /* 269 */ 274, + /* 270 */ 275, + /* 271 */ 276, + /* 272 */ 277, + /* 273 */ 278, + /* 274 */ 279, + /* 275 */ 280, + /* 276 */ 281, + /* 277 */ 282, + /* 278 */ 283, + /* 279 */ 284, + /* 280 */ 285, + /* 281 */ 286, + /* 282 */ 287, + /* 283 */ 288, + /* 284 */ 289, + /* 285 */ 290, + /* 286 */ 291, + /* 287 */ 292, + /* 288 */ 293, + /* 289 */ 294, + /* 290 */ 295, + /* 291 */ 296, + /* 292 */ 297, + /* 293 */ 298, + /* 294 */ 299, + /* 295 */ 300, + /* 296 */ 301, + /* 297 */ 302, + /* 298 */ 303, + /* 299 */ 304, + /* 300 */ 305, + /* 301 */ 306, + /* 302 */ 307, + /* 303 */ 308, + /* 304 */ 309, + /* 305 */ 310, + /* 306 */ 311, + /* 307 */ 312, + /* 308 */ 313, + /* 309 */ 314, + /* 310 */ 315, + /* 311 */ 316, + /* 312 */ 317, + /* 313 */ 318, + /* 314 */ 319, + /* 315 */ 320, + /* 316 */ 321, + /* 317 */ 322, + /* 318 */ 323, + /* 319 */ 324, + /* 320 */ 325, + /* 321 */ 326, + /* 322 */ 327, + /* 323 */ 328, + /* 324 */ 329, + /* 325 */ 330, + /* 326 */ 331, + /* 327 */ 332, + /* 328 */ 333, + /* 329 */ 334, + /* 330 */ 335, + /* 331 */ 336, + /* 332 */ 337, + /* 333 */ 338, + /* 334 */ 339, + /* 335 */ 340, + /* 336 */ 341, + /* 337 */ 342, + /* 338 */ 343, + /* 339 */ 344, + /* 340 */ 345, + /* 341 */ 346, + /* 342 */ 347, + /* 343 */ 348, + /* 344 */ 349, + /* 345 */ 350, + /* 346 */ 351, + /* 347 */ 352, + /* 348 */ 353, + /* 349 */ 354, + /* 350 */ 355, + /* 351 */ 356, + /* 352 */ 357, + /* 353 */ 358, + /* 354 */ 359, + /* 355 */ 360, + /* 356 */ 361, + /* 357 */ 362, + /* 358 */ 363, + /* 359 */ 364, + /* 360 */ 365, + /* 361 */ 366, + /* 362 */ 367, + /* 363 */ 368, + /* 364 */ 369, + /* 365 */ 370, + /* 366 */ 371, + /* 367 */ 372, + /* 368 */ 373, + /* 369 */ 374, + /* 370 */ 375, + /* 371 */ 376, + /* 372 */ 377, + /* 373 */ 378, + /* 374 */ 379, + /* 375 */ 380, + /* 376 */ 381, + /* 377 */ 382, + /* 378 */ 383, + /* 379 */ 384, + /* 380 */ 385, + /* 381 */ 386, + /* 382 */ 387, + /* 383 */ 388, + /* 384 */ 389, + /* 385 */ 390, + /* 386 */ 391, + /* 387 */ 392, + /* 388 */ 393, + /* 389 */ 394, + /* 390 */ 395, + /* 391 */ 396, + /* 392 */ 397, + /* 393 */ 398, + /* 394 */ 399, + /* 395 */ 400, + /* 396 */ 401, + /* 397 */ 402, + /* 398 */ 403, + /* 399 */ 404, + /* 400 */ 405, + /* 401 */ 406, + /* 402 */ 407, + /* 403 */ 408, + /* 404 */ 409, + /* 405 */ 410, + /* 406 */ 411, + /* 407 */ 412, + /* 408 */ 413, + /* 409 */ 414, + /* 410 */ 415, + /* 411 */ 416, + /* 412 */ 417, + /* 413 */ 418, + /* 414 */ 419, + /* 415 */ 420, + /* 416 */ 421, + /* 417 */ 422, + /* 418 */ 423, + /* 419 */ 424, + /* 420 */ 425, + /* 421 */ 426, + /* 422 */ 427, + /* 423 */ 428, + /* 424 */ 429, + /* 425 */ 430, + /* 426 */ 431, + /* 427 */ 432, + /* 428 */ 433, + /* 429 */ 434, + /* 430 */ 435, + /* 431 */ 436, + /* 432 */ 437, + /* 433 */ 438, + /* 434 */ 439, + /* 435 */ 440, + /* 436 */ 441, + /* 437 */ 442, + /* 438 */ 443, + /* 439 */ 444, + /* 440 */ 445, + /* 441 */ 446, + /* 442 */ 447, + /* 443 */ 448, + /* 444 */ 449, + /* 445 */ 450, + /* 446 */ 451, + /* 447 */ 452, + /* 448 */ 453, + /* 449 */ 454, + /* 450 */ 455, + /* 451 */ 456, + /* 452 */ 457, + /* 453 */ 458, + /* 454 */ 459, + /* 455 */ 460, + /* 456 */ 461, + /* 457 */ 462, + /* 458 */ 463, + /* 459 */ 464, + /* 460 */ 465, + /* 461 */ 466, + /* 462 */ 467, + /* 463 */ 468, + /* 464 */ 469, + /* 465 */ 470, + /* 466 */ 471, + /* 467 */ 472, + /* 468 */ 473, + /* 469 */ 474, + /* 470 */ 475, + /* 471 */ 476, + /* 472 */ 477, + /* 473 */ 478, + /* 474 */ 479, + /* 475 */ 480, + /* 476 */ 481, + /* 477 */ 482, + /* 478 */ 483, + /* 479 */ 484, + /* 480 */ 485, + /* 481 */ 486, + /* 482 */ 487, + /* 483 */ 488, + /* 484 */ 489, + /* 485 */ 490, + /* 486 */ 491, + /* 487 */ 492, + /* 488 */ 493, + /* 489 */ 494, + /* 490 */ 495, + /* 491 */ 496, + /* 492 */ 497, + /* 493 */ 498, + /* 494 */ 499, + /* 495 */ 500, + /* 496 */ 501, + /* 497 */ 502, + /* 498 */ 503, + /* 499 */ 504, + /* 500 */ 505, + /* 501 */ 506, + /* 502 */ 507, + /* 503 */ 508, + /* 504 */ 509, + /* 505 */ 510, + /* 506 */ 511, + /* 507 */ 512, + /* 508 */ 513, + /* 509 */ 514, + /* 510 */ 515, + /* 511 */ 516, + /* 512 */ 517, + /* 513 */ 518, + /* 514 */ 519, + /* 515 */ 520, + /* 516 */ 521, + /* 517 */ 522, + /* 518 */ 523, + /* 519 */ 524, + /* 520 */ 525, + /* 521 */ 526, + /* 522 */ 527, + /* 523 */ 528, + /* 524 */ 529, + /* 525 */ 530, + /* 526 */ 531, + /* 527 */ 532, + /* 528 */ 533, + /* 529 */ 534, + /* 530 */ 535, + /* 531 */ 536, + /* 532 */ 537, + /* 533 */ 538, + /* 534 */ 539, + /* 535 */ 540, + /* 536 */ 541, + /* 537 */ 542, + /* 538 */ 543, + /* 539 */ 544, + /* 540 */ 545, + /* 541 */ 546, + /* 542 */ 547, + /* 543 */ 548, + /* 544 */ 549, + /* 545 */ 550, + /* 546 */ 551, + /* 547 */ 552, + /* 548 */ 553, + /* 549 */ 554, + /* 550 */ 555, + /* 551 */ 556, + /* 552 */ 557, + /* 553 */ 558, + /* 554 */ 559, + /* 555 */ 560, + /* 556 */ 561, + /* 557 */ 562, + /* 558 */ 563, + /* 559 */ 564, + /* 560 */ 565, + /* 561 */ 566, + /* 562 */ 567, + /* 563 */ 568, + /* 564 */ 569, + /* 565 */ 570, + /* 566 */ 571, + /* 567 */ 572, + /* 568 */ 573, + /* 569 */ 574, + /* 570 */ 575, + /* 571 */ 576, + /* 572 */ 577, + /* 573 */ 578, + /* 574 */ 579, + /* 575 */ 580, + /* 576 */ 581, + /* 577 */ 582, + /* 578 */ 583, + /* 579 */ 584, + /* 580 */ 585, + /* 581 */ 586, + /* 582 */ 587, + /* 583 */ 588, + /* 584 */ 589, + /* 585 */ 590, + /* 586 */ 591, + /* 587 */ 592, + /* 588 */ 593, + /* 589 */ 594, + /* 590 */ 595, + /* 591 */ 596, + /* 592 */ 597, + /* 593 */ 598, + /* 594 */ 599, + /* 595 */ 600, + /* 596 */ 601, + /* 597 */ 602, + /* 598 */ 603, + /* 599 */ 604, + /* 600 */ 605, + /* 601 */ 606, + /* 602 */ 607, + /* 603 */ 608, + /* 604 */ 609, + /* 605 */ 610, + /* 606 */ 611, + /* 607 */ 612, + /* 608 */ 613, + /* 609 */ 614, + /* 610 */ 615, + /* 611 */ 616, + /* 612 */ 617, + /* 613 */ 618, + /* 614 */ 619, + /* 615 */ 620, + /* 616 */ 621, + /* 617 */ 622, + /* 618 */ 623, + /* 619 */ 624, + /* 620 */ 625, + /* 621 */ 626, + /* 622 */ 627, + /* 623 */ 628, + /* 624 */ 629, + /* 625 */ 630, + /* 626 */ 631, + /* 627 */ 632, + /* 628 */ 633, + /* 629 */ 634, + /* 630 */ 635, + /* 631 */ 636, + /* 632 */ 637, + /* 633 */ 638, + /* 634 */ 639, + /* 635 */ 640, + /* 636 */ 641, + /* 637 */ 642, + /* 638 */ 643, + /* 639 */ 644, + /* 640 */ 645, + /* 641 */ 646, + /* 642 */ 647, + /* 643 */ 648, + /* 644 */ 649, + /* 645 */ 650, + /* 646 */ 651, + /* 647 */ 652, + /* 648 */ 653, + /* 649 */ 654, + /* 650 */ 655, + /* 651 */ 656, + /* 652 */ 657, + /* 653 */ 658, + /* 654 */ 659, + /* 655 */ 660, + /* 656 */ 661, + /* 657 */ 662, + /* 658 */ 663, + /* 659 */ 664, + /* 660 */ 665, + /* 661 */ 666, + /* 662 */ 667, + /* 663 */ 668, + /* 664 */ 669, + /* 665 */ 670, + /* 666 */ 671, + /* 667 */ 672, + /* 668 */ 673, + /* 669 */ 674, + /* 670 */ 675, + /* 671 */ 676, + /* 672 */ 677, + /* 673 */ 678, + /* 674 */ 679, + /* 675 */ 680, + /* 676 */ 681, + /* 677 */ 682, + /* 678 */ 683, + /* 679 */ 684, + /* 680 */ 685, + /* 681 */ 686, + /* 682 */ 687, + /* 683 */ 688, + /* 684 */ 689, + /* 685 */ 690, + /* 686 */ 691, + /* 687 */ 692, + /* 688 */ 693, + /* 689 */ 694, + /* 690 */ 695, + /* 691 */ 696, + /* 692 */ 697, + /* 693 */ 698, + /* 694 */ 699, + /* 695 */ 700, + /* 696 */ 701, + /* 697 */ 702, + /* 698 */ 703, + /* 699 */ 704, + /* 700 */ 705, + /* 701 */ 706, + /* 702 */ 707, + /* 703 */ 708, + /* 704 */ 709, + /* 705 */ 710, + /* 706 */ 711, + /* 707 */ 712, + /* 708 */ 713, + /* 709 */ 714, + /* 710 */ 715, + /* 711 */ 716, + /* 712 */ 717, + /* 713 */ 718, + /* 714 */ 719, + /* 715 */ 720, + /* 716 */ 721, + /* 717 */ 722, + /* 718 */ 723, + /* 719 */ 724, + /* 720 */ 725, + /* 721 */ 726, + /* 722 */ 727, + /* 723 */ 728, + /* 724 */ 729, + /* 725 */ 730, + /* 726 */ 731, + /* 727 */ 732, + /* 728 */ 733, + /* 729 */ 734, + /* 730 */ 735, + /* 731 */ 736, + /* 732 */ 737, + /* 733 */ 738, + /* 734 */ 739, + /* 735 */ 740, + /* 736 */ 741, + /* 737 */ 742, + /* 738 */ 743, + /* 739 */ 744, + /* 740 */ 745, + /* 741 */ 746, + /* 742 */ 747, + /* 743 */ 748, + /* 744 */ 749, + /* 745 */ 750, + /* 746 */ 751, + /* 747 */ 752, + /* 748 */ 753, + /* 749 */ 754, + /* 750 */ 755, + /* 751 */ 756, + /* 752 */ 757, + /* 753 */ 758, + /* 754 */ 759, + /* 755 */ 760, + /* 756 */ 761, + /* 757 */ 762, + /* 758 */ 763, + /* 759 */ 764, + /* 760 */ 765, + /* 761 */ 766, + /* 762 */ 767, + /* 763 */ 768, + /* 764 */ 769, + /* 765 */ 770, + /* 766 */ 771, + /* 767 */ 772, + /* 768 */ 773, + /* 769 */ 774, + /* 770 */ 775, + /* 771 */ 776, + /* 772 */ 777, + /* 773 */ 778, + /* 774 */ 779, + /* 775 */ 780, + /* 776 */ 781, + /* 777 */ 782, + /* 778 */ 783, + /* 779 */ 784, + /* 780 */ 785, + /* 781 */ 786, + /* 782 */ 787, + /* 783 */ 788, + /* 784 */ 789, + /* 785 */ 790, + /* 786 */ 791, + /* 787 */ 792, + /* 788 */ 793, + /* 789 */ 794, + /* 790 */ 795, + /* 791 */ 796, + /* 792 */ 797, + /* 793 */ 798, + /* 794 */ 799, + /* 795 */ 800, + /* 796 */ 801, + /* 797 */ 802, + /* 798 */ 803, + /* 799 */ 804, + /* 800 */ 805, + /* 801 */ 806, + /* 802 */ 807, + /* 803 */ 808, + /* 804 */ 809, + /* 805 */ 810, + /* 806 */ 811, + /* 807 */ 812, + /* 808 */ 813, + /* 809 */ 814, + /* 810 */ 815, + /* 811 */ 816, + /* 812 */ 817, + /* 813 */ 818, + /* 814 */ 819, + /* 815 */ 820, + /* 816 */ 821, + /* 817 */ 822, + /* 818 */ 823, + /* 819 */ 824, + /* 820 */ 825, + /* 821 */ 826, + /* 822 */ 827, + /* 823 */ 828, + /* 824 */ 829, + /* 825 */ 830, + /* 826 */ 831, + /* 827 */ 832, + /* 828 */ 833, + /* 829 */ 834, + /* 830 */ 835, + /* 831 */ 836, + /* 832 */ 837, + /* 833 */ 838, + /* 834 */ 839, + /* 835 */ 840, + /* 836 */ 841, + /* 837 */ 842, + /* 838 */ 843, + /* 839 */ 844, + /* 840 */ 845, + /* 841 */ 846, + /* 842 */ 847, + /* 843 */ 848, + /* 844 */ 849, + /* 845 */ 850, + /* 846 */ 851, + /* 847 */ 852, + /* 848 */ 853, + /* 849 */ 854, + /* 850 */ 855, + /* 851 */ 856, + /* 852 */ 857, + /* 853 */ 858, + /* 854 */ 859, + /* 855 */ 860, + /* 856 */ 861, + /* 857 */ 862, + /* 858 */ 863, + /* 859 */ 864, + /* 860 */ 865, + /* 861 */ 866, + /* 862 */ 867, + /* 863 */ 868, + /* 864 */ 869, + /* 865 */ 870, + /* 866 */ 871, + /* 867 */ 872, + /* 868 */ 873, + /* 869 */ 874, + /* 870 */ 875, + /* 871 */ 876, + /* 872 */ 877, + /* 873 */ 878, + /* 874 */ 879, + /* 875 */ 880, + /* 876 */ 881, + /* 877 */ 882, + /* 878 */ 883, + /* 879 */ 884, + /* 880 */ 885, + /* 881 */ 886, + /* 882 */ 887, + /* 883 */ 888, + /* 884 */ 889, + /* 885 */ 890, + /* 886 */ 891, + /* 887 */ 892, + /* 888 */ 893, + /* 889 */ 894, + /* 890 */ 895, + /* 891 */ 896, + /* 892 */ 897, + /* 893 */ 898, + /* 894 */ 899, + /* 895 */ 900, + /* 896 */ 901, + /* 897 */ 902, + /* 898 */ 903, + /* 899 */ 904, + /* 900 */ 905, + /* 901 */ 906, + /* 902 */ 907, + /* 903 */ 908, + /* 904 */ 909, + /* 905 */ 910, + /* 906 */ 911, + /* 907 */ 912, + /* 908 */ 913, + /* 909 */ 914, + /* 910 */ 915, + /* 911 */ 916, + /* 912 */ 917, + /* 913 */ 918, + /* 914 */ 919, + /* 915 */ 920, + /* 916 */ 921, + /* 917 */ 922, + /* 918 */ 923, + /* 919 */ 924, + /* 920 */ 925, + /* 921 */ 926, + /* 922 */ 927, + /* 923 */ 928, + /* 924 */ 929, + /* 925 */ 930, + /* 926 */ 931, + /* 927 */ 932, + /* 928 */ 933, + /* 929 */ 934, + /* 930 */ 935, + /* 931 */ 936, + /* 932 */ 937, + /* 933 */ 938, + /* 934 */ 939, + /* 935 */ 940, + /* 936 */ 941, + /* 937 */ 942, + /* 938 */ 943, + /* 939 */ 944, + /* 940 */ 945, + /* 941 */ 946, + /* 942 */ 947, + /* 943 */ 948, + /* 944 */ 949, + /* 945 */ 950, + /* 946 */ 951, + /* 947 */ 952, + /* 948 */ 953, + /* 949 */ 954, + /* 950 */ 955, + /* 951 */ 956, + /* 952 */ 957, + /* 953 */ 958, + /* 954 */ 959, + /* 955 */ 960, + /* 956 */ 961, + /* 957 */ 962, + /* 958 */ 963, + /* 959 */ 964, + /* 960 */ 965, + /* 961 */ 966, + /* 962 */ 967, + /* 963 */ 968, + /* 964 */ 969, + /* 965 */ 970, + /* 966 */ 971, + /* 967 */ 972, + /* 968 */ 973, + /* 969 */ 974, + /* 970 */ 975, + /* 971 */ 976, + /* 972 */ 977, + /* 973 */ 978, + /* 974 */ 979, + /* 975 */ 980, + /* 976 */ 981, + /* 977 */ 982, + /* 978 */ 983, + /* 979 */ 984, + /* 980 */ 985, + /* 981 */ 986, + /* 982 */ 987, + /* 983 */ 988, + /* 984 */ 989, + /* 985 */ 990, + /* 986 */ 991, + /* 987 */ 992, + /* 988 */ 993, + /* 989 */ 994, + /* 990 */ 995, + /* 991 */ 996, + /* 992 */ 997, + /* 993 */ 998, + /* 994 */ 999, + /* 995 */ 1000, + /* 996 */ 1001, + /* 997 */ 1002, + /* 998 */ 1003, + /* 999 */ 1004, + /* 1000 */ 1005, + /* 1001 */ 1006, + /* 1002 */ 1007, + /* 1003 */ 1008, + /* 1004 */ 1009, + /* 1005 */ 1010, + /* 1006 */ 1011, + /* 1007 */ 1012, + /* 1008 */ 1013, + /* 1009 */ 1014, + /* 1010 */ 1015, + /* 1011 */ 1016, + /* 1012 */ 1017, + /* 1013 */ 1018, + /* 1014 */ 1019, + /* 1015 */ 1020, + /* 1016 */ 1021, + /* 1017 */ 1022, + /* 1018 */ 1023, + /* 1019 */ 1024, + /* 1020 */ 1025, + /* 1021 */ 1026, + /* 1022 */ 1027, + /* 1023 */ 1028, +}; + +uint16_t lookup_MyFavoriteSensor(uint16_t i) +{ + if (i <= 1023) + return pgm_read_word(&g_LOOKUP_MyFavoriteSensor[i]); + else + return 6666; /* #HighValue */ +} + + diff --git a/examples/osd/arduino-roller/tools/1.h b/examples/osd/arduino-roller/tools/1.h new file mode 100644 index 000000000..221b3af79 --- /dev/null +++ b/examples/osd/arduino-roller/tools/1.h @@ -0,0 +1,15 @@ +#ifndef 1_h_ +#define 1_h_ + +#include +#include + +/** + * autogenerated lookup function for MyFavoriteSensor + * @param i x value + * @return f(i), or 6666 if i is out of range + */ +uint16_t lookup_MyFavoriteSensor(uint16_t i); + +#endif /* 1_h_ */ + diff --git a/examples/osd/arduino-roller/tools/README b/examples/osd/arduino-roller/tools/README new file mode 100644 index 000000000..509f6ae85 --- /dev/null +++ b/examples/osd/arduino-roller/tools/README @@ -0,0 +1,15 @@ + + +Hallo , + +Für ein ähnliches Problem habe ich einen csv zu C Konverter in Python +geschrieben. +Aus dem csv im Anhang habe ich mit + +python lookuptable.py example.csv 1.h 1.c + +das .c und .h erzeugt. Ohne Gewähr, evtl. hilft es. + +link: + +http://www.mikrocontroller.net/topic/232722 diff --git a/examples/osd/arduino-roller/tools/example.csv b/examples/osd/arduino-roller/tools/example.csv new file mode 100644 index 000000000..4175536f1 --- /dev/null +++ b/examples/osd/arduino-roller/tools/example.csv @@ -0,0 +1,1029 @@ +"#LowValue";12345 +"#HighValue";6666 +"#DataType";"uint16_t" +"#IndexType";"uint16_t" +"#ArrayName";"MyFavoriteSensor" +0;5 +1;6 +2;7 +3;8 +4;9 +5;10 +6;11 +7;12 +8;13 +9;14 +10;15 +11;16 +12;17 +13;18 +14;19 +15;20 +16;21 +17;22 +18;23 +19;24 +20;25 +21;26 +22;27 +23;28 +24;29 +25;30 +26;31 +27;32 +28;33 +29;34 +30;35 +31;36 +32;37 +33;38 +34;39 +35;40 +36;41 +37;42 +38;43 +39;44 +40;45 +41;46 +42;47 +43;48 +44;49 +45;50 +46;51 +47;52 +48;53 +49;54 +50;55 +51;56 +52;57 +53;58 +54;59 +55;60 +56;61 +57;62 +58;63 +59;64 +60;65 +61;66 +62;67 +63;68 +64;69 +65;70 +66;71 +67;72 +68;73 +69;74 +70;75 +71;76 +72;77 +73;78 +74;79 +75;80 +76;81 +77;82 +78;83 +79;84 +80;85 +81;86 +82;87 +83;88 +84;89 +85;90 +86;91 +87;92 +88;93 +89;94 +90;95 +91;96 +92;97 +93;98 +94;99 +95;100 +96;101 +97;102 +98;103 +99;104 +100;105 +101;106 +102;107 +103;108 +104;109 +105;110 +106;111 +107;112 +108;113 +109;114 +110;115 +111;116 +112;117 +113;118 +114;119 +115;120 +116;121 +117;122 +118;123 +119;124 +120;125 +121;126 +122;127 +123;128 +124;129 +125;130 +126;131 +127;132 +128;133 +129;134 +130;135 +131;136 +132;137 +133;138 +134;139 +135;140 +136;141 +137;142 +138;143 +139;144 +140;145 +141;146 +142;147 +143;148 +144;149 +145;150 +146;151 +147;152 +148;153 +149;154 +150;155 +151;156 +152;157 +153;158 +154;159 +155;160 +156;161 +157;162 +158;163 +159;164 +160;165 +161;166 +162;167 +163;168 +164;169 +165;170 +166;171 +167;172 +168;173 +169;174 +170;175 +171;176 +172;177 +173;178 +174;179 +175;180 +176;181 +177;182 +178;183 +179;184 +180;185 +181;186 +182;187 +183;188 +184;189 +185;190 +186;191 +187;192 +188;193 +189;194 +190;195 +191;196 +192;197 +193;198 +194;199 +195;200 +196;201 +197;202 +198;203 +199;204 +200;205 +201;206 +202;207 +203;208 +204;209 +205;210 +206;211 +207;212 +208;213 +209;214 +210;215 +211;216 +212;217 +213;218 +214;219 +215;220 +216;221 +217;222 +218;223 +219;224 +220;225 +221;226 +222;227 +223;228 +224;229 +225;230 +226;231 +227;232 +228;233 +229;234 +230;235 +231;236 +232;237 +233;238 +234;239 +235;240 +236;241 +237;242 +238;243 +239;244 +240;245 +241;246 +242;247 +243;248 +244;249 +245;250 +246;251 +247;252 +248;253 +249;254 +250;255 +251;256 +252;257 +253;258 +254;259 +255;260 +256;261 +257;262 +258;263 +259;264 +260;265 +261;266 +262;267 +263;268 +264;269 +265;270 +266;271 +267;272 +268;273 +269;274 +270;275 +271;276 +272;277 +273;278 +274;279 +275;280 +276;281 +277;282 +278;283 +279;284 +280;285 +281;286 +282;287 +283;288 +284;289 +285;290 +286;291 +287;292 +288;293 +289;294 +290;295 +291;296 +292;297 +293;298 +294;299 +295;300 +296;301 +297;302 +298;303 +299;304 +300;305 +301;306 +302;307 +303;308 +304;309 +305;310 +306;311 +307;312 +308;313 +309;314 +310;315 +311;316 +312;317 +313;318 +314;319 +315;320 +316;321 +317;322 +318;323 +319;324 +320;325 +321;326 +322;327 +323;328 +324;329 +325;330 +326;331 +327;332 +328;333 +329;334 +330;335 +331;336 +332;337 +333;338 +334;339 +335;340 +336;341 +337;342 +338;343 +339;344 +340;345 +341;346 +342;347 +343;348 +344;349 +345;350 +346;351 +347;352 +348;353 +349;354 +350;355 +351;356 +352;357 +353;358 +354;359 +355;360 +356;361 +357;362 +358;363 +359;364 +360;365 +361;366 +362;367 +363;368 +364;369 +365;370 +366;371 +367;372 +368;373 +369;374 +370;375 +371;376 +372;377 +373;378 +374;379 +375;380 +376;381 +377;382 +378;383 +379;384 +380;385 +381;386 +382;387 +383;388 +384;389 +385;390 +386;391 +387;392 +388;393 +389;394 +390;395 +391;396 +392;397 +393;398 +394;399 +395;400 +396;401 +397;402 +398;403 +399;404 +400;405 +401;406 +402;407 +403;408 +404;409 +405;410 +406;411 +407;412 +408;413 +409;414 +410;415 +411;416 +412;417 +413;418 +414;419 +415;420 +416;421 +417;422 +418;423 +419;424 +420;425 +421;426 +422;427 +423;428 +424;429 +425;430 +426;431 +427;432 +428;433 +429;434 +430;435 +431;436 +432;437 +433;438 +434;439 +435;440 +436;441 +437;442 +438;443 +439;444 +440;445 +441;446 +442;447 +443;448 +444;449 +445;450 +446;451 +447;452 +448;453 +449;454 +450;455 +451;456 +452;457 +453;458 +454;459 +455;460 +456;461 +457;462 +458;463 +459;464 +460;465 +461;466 +462;467 +463;468 +464;469 +465;470 +466;471 +467;472 +468;473 +469;474 +470;475 +471;476 +472;477 +473;478 +474;479 +475;480 +476;481 +477;482 +478;483 +479;484 +480;485 +481;486 +482;487 +483;488 +484;489 +485;490 +486;491 +487;492 +488;493 +489;494 +490;495 +491;496 +492;497 +493;498 +494;499 +495;500 +496;501 +497;502 +498;503 +499;504 +500;505 +501;506 +502;507 +503;508 +504;509 +505;510 +506;511 +507;512 +508;513 +509;514 +510;515 +511;516 +512;517 +513;518 +514;519 +515;520 +516;521 +517;522 +518;523 +519;524 +520;525 +521;526 +522;527 +523;528 +524;529 +525;530 +526;531 +527;532 +528;533 +529;534 +530;535 +531;536 +532;537 +533;538 +534;539 +535;540 +536;541 +537;542 +538;543 +539;544 +540;545 +541;546 +542;547 +543;548 +544;549 +545;550 +546;551 +547;552 +548;553 +549;554 +550;555 +551;556 +552;557 +553;558 +554;559 +555;560 +556;561 +557;562 +558;563 +559;564 +560;565 +561;566 +562;567 +563;568 +564;569 +565;570 +566;571 +567;572 +568;573 +569;574 +570;575 +571;576 +572;577 +573;578 +574;579 +575;580 +576;581 +577;582 +578;583 +579;584 +580;585 +581;586 +582;587 +583;588 +584;589 +585;590 +586;591 +587;592 +588;593 +589;594 +590;595 +591;596 +592;597 +593;598 +594;599 +595;600 +596;601 +597;602 +598;603 +599;604 +600;605 +601;606 +602;607 +603;608 +604;609 +605;610 +606;611 +607;612 +608;613 +609;614 +610;615 +611;616 +612;617 +613;618 +614;619 +615;620 +616;621 +617;622 +618;623 +619;624 +620;625 +621;626 +622;627 +623;628 +624;629 +625;630 +626;631 +627;632 +628;633 +629;634 +630;635 +631;636 +632;637 +633;638 +634;639 +635;640 +636;641 +637;642 +638;643 +639;644 +640;645 +641;646 +642;647 +643;648 +644;649 +645;650 +646;651 +647;652 +648;653 +649;654 +650;655 +651;656 +652;657 +653;658 +654;659 +655;660 +656;661 +657;662 +658;663 +659;664 +660;665 +661;666 +662;667 +663;668 +664;669 +665;670 +666;671 +667;672 +668;673 +669;674 +670;675 +671;676 +672;677 +673;678 +674;679 +675;680 +676;681 +677;682 +678;683 +679;684 +680;685 +681;686 +682;687 +683;688 +684;689 +685;690 +686;691 +687;692 +688;693 +689;694 +690;695 +691;696 +692;697 +693;698 +694;699 +695;700 +696;701 +697;702 +698;703 +699;704 +700;705 +701;706 +702;707 +703;708 +704;709 +705;710 +706;711 +707;712 +708;713 +709;714 +710;715 +711;716 +712;717 +713;718 +714;719 +715;720 +716;721 +717;722 +718;723 +719;724 +720;725 +721;726 +722;727 +723;728 +724;729 +725;730 +726;731 +727;732 +728;733 +729;734 +730;735 +731;736 +732;737 +733;738 +734;739 +735;740 +736;741 +737;742 +738;743 +739;744 +740;745 +741;746 +742;747 +743;748 +744;749 +745;750 +746;751 +747;752 +748;753 +749;754 +750;755 +751;756 +752;757 +753;758 +754;759 +755;760 +756;761 +757;762 +758;763 +759;764 +760;765 +761;766 +762;767 +763;768 +764;769 +765;770 +766;771 +767;772 +768;773 +769;774 +770;775 +771;776 +772;777 +773;778 +774;779 +775;780 +776;781 +777;782 +778;783 +779;784 +780;785 +781;786 +782;787 +783;788 +784;789 +785;790 +786;791 +787;792 +788;793 +789;794 +790;795 +791;796 +792;797 +793;798 +794;799 +795;800 +796;801 +797;802 +798;803 +799;804 +800;805 +801;806 +802;807 +803;808 +804;809 +805;810 +806;811 +807;812 +808;813 +809;814 +810;815 +811;816 +812;817 +813;818 +814;819 +815;820 +816;821 +817;822 +818;823 +819;824 +820;825 +821;826 +822;827 +823;828 +824;829 +825;830 +826;831 +827;832 +828;833 +829;834 +830;835 +831;836 +832;837 +833;838 +834;839 +835;840 +836;841 +837;842 +838;843 +839;844 +840;845 +841;846 +842;847 +843;848 +844;849 +845;850 +846;851 +847;852 +848;853 +849;854 +850;855 +851;856 +852;857 +853;858 +854;859 +855;860 +856;861 +857;862 +858;863 +859;864 +860;865 +861;866 +862;867 +863;868 +864;869 +865;870 +866;871 +867;872 +868;873 +869;874 +870;875 +871;876 +872;877 +873;878 +874;879 +875;880 +876;881 +877;882 +878;883 +879;884 +880;885 +881;886 +882;887 +883;888 +884;889 +885;890 +886;891 +887;892 +888;893 +889;894 +890;895 +891;896 +892;897 +893;898 +894;899 +895;900 +896;901 +897;902 +898;903 +899;904 +900;905 +901;906 +902;907 +903;908 +904;909 +905;910 +906;911 +907;912 +908;913 +909;914 +910;915 +911;916 +912;917 +913;918 +914;919 +915;920 +916;921 +917;922 +918;923 +919;924 +920;925 +921;926 +922;927 +923;928 +924;929 +925;930 +926;931 +927;932 +928;933 +929;934 +930;935 +931;936 +932;937 +933;938 +934;939 +935;940 +936;941 +937;942 +938;943 +939;944 +940;945 +941;946 +942;947 +943;948 +944;949 +945;950 +946;951 +947;952 +948;953 +949;954 +950;955 +951;956 +952;957 +953;958 +954;959 +955;960 +956;961 +957;962 +958;963 +959;964 +960;965 +961;966 +962;967 +963;968 +964;969 +965;970 +966;971 +967;972 +968;973 +969;974 +970;975 +971;976 +972;977 +973;978 +974;979 +975;980 +976;981 +977;982 +978;983 +979;984 +980;985 +981;986 +982;987 +983;988 +984;989 +985;990 +986;991 +987;992 +988;993 +989;994 +990;995 +991;996 +992;997 +993;998 +994;999 +995;1000 +996;1001 +997;1002 +998;1003 +999;1004 +1000;1005 +1001;1006 +1002;1007 +1003;1008 +1004;1009 +1005;1010 +1006;1011 +1007;1012 +1008;1013 +1009;1014 +1010;1015 +1011;1016 +1012;1017 +1013;1018 +1014;1019 +1015;1020 +1016;1021 +1017;1022 +1018;1023 +1019;1024 +1020;1025 +1021;1026 +1022;1027 +1023;1028 diff --git a/examples/osd/arduino-roller/tools/example.ods b/examples/osd/arduino-roller/tools/example.ods new file mode 100644 index 000000000..3b867dde6 Binary files /dev/null and b/examples/osd/arduino-roller/tools/example.ods differ diff --git a/examples/osd/arduino-roller/tools/lookuptable.py b/examples/osd/arduino-roller/tools/lookuptable.py new file mode 100644 index 000000000..531313509 --- /dev/null +++ b/examples/osd/arduino-roller/tools/lookuptable.py @@ -0,0 +1,176 @@ +#!/usr/bin/python + + +""" + Benutzung: +python lookuptable.py bla.csv bla.h bla.c +liest bla.csv aus, interpoliert das ganze und schreibt eine tabelle in bla.c und bla.h +Achtung, bla.c und bla.h werden brutal ueberschrieben! + +Das csv muss tabs, kommas oder semikolons als trenner haben und folgende felder enthalten: + +#LowValue + wird als y fuer alle x-werte, die kleiner als der kleinste x-Wert im csv sind, benutzt +#HighValue + wird als y fuer alle x-werte, die groesser als der groesste x-Wert im csv sind, benutzt +#DataType + Datentyp der y-Werte (uint16_t oder uint8_t) +#IndexType + Datentyp der x-Werte (uint16_t oder uint8_t) +#ArrayName + Name des Arrays + +Siehe example.csv!! + + +Benutzung auf eigene Gefahr. +""" + + +import fileinput +import re +import os +import sys + +# bei bedarf ergaezen. +AdditionalIncludes = [ '', '' ] + + +def create_printable_table(table, dataType, arrayName): + """ returns a string with the table in *.c format """ + result = '/** autogenerated lookup table */\n' + result += 'const ' + dataType + " g_LOOKUP_" + arrayName + '[] PROGMEM =\n' + result += '{\n' + for x in sorted(table.keys()): + y = table[x] + result += ' /* ' + repr(x).rjust(12) + ' */ ' + repr(y).rjust(12) + ',\n' + result += '};' + return result + + +def create_lookup_function(dataType, indexType, arrayName, biggestKey, highValue): + header = '' + body = '' + + header += '/**\n' + header += ' * autogenerated lookup function for ' + arrayName + "\n" + header += ' * @param i x value\n' + header += ' * @return f(i), or ' + str(highValue) + ' if i is out of range\n' + header += ' */\n' + header += dataType + ' lookup_' + arrayName + '(' + indexType + ' i);' + + body += dataType + ' lookup_' + arrayName + '(' + indexType + ' i)\n' + body += '{\n' + body += ' if (i <= ' + str(biggestKey) + ')\n' + body += ' return ' + if dataType == 'uint16_t': + body += 'pgm_read_word(&g_LOOKUP_' + arrayName + '[i]);\n' + elif dataType == 'uint8_t': + body += 'pgm_read_byte(&g_LOOKUP_' + arrayName + '[i]);\n' + else: + body += 'ERROR: no suitable datatype\n' + body += ' else\n' + body += ' return ' + str(highValue) + '; /* #HighValue */\n' + body += '}\n' + return header, body + + +def interpolate_lookup_table(table, lowValue): + #sortieren, durchgehen und interpolieren. + oldX = 0 + for nextX in sorted(table.keys()): + if not oldX in table.keys(): + if oldX == 0: + startY = lowValue + nextY = lowValue + else: + startY = table[oldX] + nextY = table[nextX] + for thisX in range(oldX, nextX): # die punkte zwischen den stuetzstellen durchgehen + thisY = startY + (nextY - startY) * (thisX - oldX) / (nextX - oldX) # lin. interpol. + table[thisX] = thisY + oldX = nextX + return table + + +def parse_csv(filename): + dataType = 'uint16_t' + indexType = 'uint8_t' + arrayName = 'TestArray' + lowestKey = 'ERROR' + biggestKey = 'ERROR' + highValue = 'ERROR' + lowValue = 'ERROR' + data = {} + csvFile = open(filename, 'r') + for line in csvFile: + zeile = line.strip().strip('"') + if re.match('\#', zeile): + myLine = re.split('[\t ;,]+', zeile) + if re.match('\#LowValue', myLine[0]): + lowValue = int(myLine[1].strip('"')) + elif re.match('\#HighValue', myLine[0]): + highValue = int(myLine[1].strip('"')) + elif re.match('\#DataType', myLine[0]): + dataType = str(myLine[1].strip('"')) + elif re.match('\#IndexType', myLine[0]): + indexType = str(myLine[1].strip('"')) + elif re.match('\#ArrayName', myLine[0]): + arrayName = str(myLine[1].strip('"')) + elif re.match('[0-9]+[,;\t]+[0-9]+', zeile): + myLine = re.split('[\t ;,]+', zeile) + data[int(myLine[0])] = int(myLine[1]) + lowestKey = min(data.keys()); + biggestKey = max(data.keys()); + return dataType, indexType, arrayName, biggestKey, lowestKey, highValue, lowValue, data + + +def write_header_file(filename, content, additionalIncludes): + headerfile = open(filename, 'w') + includeGuard = re.sub('\.', '_', filename) + '_' + headerfile.write('#ifndef ' + includeGuard + '\n') + headerfile.write('#define ' + includeGuard + '\n\n') + for h in additionalIncludes: + headerfile.write('#include ' + h + '\n') + headerfile.write('\n') + headerfile.write(content) + headerfile.write('\n\n#endif /* ' + includeGuard + ' */\n\n') + headerfile.close() + return + + +def write_body_file(bodyFileName, headerFileName, table, funct): + bodyfile = open(bodyFileName, 'w') + bodyfile.write('#include "' + headerFileName + '"\n\n') + bodyfile.write(table) + bodyfile.write('\n\n') + bodyfile.write(funct) + bodyfile.write('\n\n') + bodyfile.close() + return + + +def print_usage(): + print "MOEP: Benutzung python", sys.argv[0], "bla.csv bla.h bla.c" + print "bla.csv muss existieren, bla.h und bla.c werden ueberschrieben" + + + +if len(sys.argv) < 4: + print_usage() + sys.exit() + + +csvFile = sys.argv[1] +headerFileName = sys.argv[2] +bodyFileName = sys.argv[3] + + +dataType, indexType, arrayName, biggestKey, lowestKey, highValue, lowValue, data = parse_csv(csvFile) +fullTable = interpolate_lookup_table(data, lowValue) +header, body = create_lookup_function(dataType, indexType, arrayName, biggestKey, highValue) + +write_header_file(headerFileName, header, AdditionalIncludes) +write_body_file(bodyFileName, headerFileName, create_printable_table(fullTable, dataType, arrayName), body) + +sys.exit() diff --git a/examples/osd/arduino-roller/tools/test2.csv b/examples/osd/arduino-roller/tools/test2.csv new file mode 100644 index 000000000..0a56a21be --- /dev/null +++ b/examples/osd/arduino-roller/tools/test2.csv @@ -0,0 +1,1029 @@ +"#LowValue";0 +"#HighValue";1023 +"#DataType";"uint16_t" +"#IndexType";"uint16_t" +"#ArrayName";"Daumengas" +0;0 +1;1 +2;2 +3;3 +4;4 +5;5 +6;6 +7;7 +8;8 +9;9 +10;10 +11;11 +12;12 +13;13 +14;14 +15;15 +16;16 +17;17 +18;18 +19;19 +20;20 +21;21 +22;22 +23;23 +24;24 +25;25 +26;26 +27;27 +28;28 +29;29 +30;30 +31;31 +32;32 +33;33 +34;34 +35;35 +36;36 +37;37 +38;38 +39;39 +40;40 +41;41 +42;42 +43;43 +44;44 +45;45 +46;46 +47;47 +48;48 +49;49 +50;50 +51;51 +52;52 +53;53 +54;54 +55;55 +56;56 +57;57 +58;58 +59;59 +60;60 +61;61 +62;62 +63;63 +64;64 +65;65 +66;66 +67;67 +68;68 +69;69 +70;70 +71;71 +72;72 +73;73 +74;74 +75;75 +76;76 +77;77 +78;78 +79;79 +80;80 +81;81 +82;82 +83;83 +84;84 +85;85 +86;86 +87;87 +88;88 +89;89 +90;90 +91;91 +92;92 +93;93 +94;94 +95;95 +96;96 +97;97 +98;98 +99;99 +100;100 +101;101 +102;102 +103;103 +104;104 +105;105 +106;106 +107;107 +108;108 +109;109 +110;110 +111;111 +112;112 +113;113 +114;114 +115;115 +116;116 +117;117 +118;118 +119;119 +120;120 +121;121 +122;122 +123;123 +124;124 +125;125 +126;126 +127;127 +128;128 +129;129 +130;130 +131;131 +132;132 +133;133 +134;134 +135;135 +136;136 +137;137 +138;138 +139;139 +140;140 +141;141 +142;142 +143;143 +144;144 +145;145 +146;146 +147;147 +148;148 +149;149 +150;150 +151;151 +152;152 +153;153 +154;154 +155;155 +156;156 +157;157 +158;158 +159;159 +160;160 +161;161 +162;162 +163;163 +164;164 +165;165 +166;166 +167;167 +168;168 +169;169 +170;170 +171;171 +172;172 +173;173 +174;174 +175;175 +176;176 +177;177 +178;178 +179;179 +180;180 +181;181 +182;182 +183;183 +184;184 +185;185 +186;186 +187;187 +188;188 +189;189 +190;190 +191;191 +192;192 +193;193 +194;194 +195;195 +196;196 +197;197 +198;198 +199;199 +200;200 +201;201 +202;202 +203;203 +204;204 +205;205 +206;206 +207;207 +208;208 +209;209 +210;210 +211;211 +212;212 +213;213 +214;214 +215;215 +216;216 +217;217 +218;218 +219;219 +220;220 +221;221 +222;222 +223;223 +224;224 +225;225 +226;226 +227;227 +228;228 +229;229 +230;230 +231;231 +232;232 +233;233 +234;234 +235;235 +236;236 +237;237 +238;238 +239;239 +240;240 +241;241 +242;242 +243;243 +244;244 +245;245 +246;246 +247;247 +248;248 +249;249 +250;250 +251;251 +252;252 +253;253 +254;254 +255;255 +256;256 +257;257 +258;258 +259;259 +260;260 +261;261 +262;262 +263;263 +264;264 +265;265 +266;266 +267;267 +268;268 +269;269 +270;270 +271;271 +272;272 +273;273 +274;274 +275;275 +276;276 +277;277 +278;278 +279;279 +280;280 +281;281 +282;282 +283;283 +284;284 +285;285 +286;286 +287;287 +288;288 +289;289 +290;290 +291;291 +292;292 +293;293 +294;294 +295;295 +296;296 +297;297 +298;298 +299;299 +300;300 +301;301 +302;302 +303;303 +304;304 +305;305 +306;306 +307;307 +308;308 +309;309 +310;310 +311;311 +312;312 +313;313 +314;314 +315;315 +316;316 +317;317 +318;318 +319;319 +320;320 +321;321 +322;322 +323;323 +324;324 +325;325 +326;326 +327;327 +328;328 +329;329 +330;330 +331;331 +332;332 +333;333 +334;334 +335;335 +336;336 +337;337 +338;338 +339;339 +340;340 +341;341 +342;342 +343;343 +344;344 +345;345 +346;346 +347;347 +348;348 +349;349 +350;350 +351;351 +352;352 +353;353 +354;354 +355;355 +356;356 +357;357 +358;358 +359;359 +360;360 +361;361 +362;362 +363;363 +364;364 +365;365 +366;366 +367;367 +368;368 +369;369 +370;370 +371;371 +372;372 +373;373 +374;374 +375;375 +376;376 +377;377 +378;378 +379;379 +380;380 +381;381 +382;382 +383;383 +384;384 +385;385 +386;386 +387;387 +388;388 +389;389 +390;390 +391;391 +392;392 +393;393 +394;394 +395;395 +396;396 +397;397 +398;398 +399;399 +400;400 +401;401 +402;402 +403;403 +404;404 +405;405 +406;406 +407;407 +408;408 +409;409 +410;410 +411;411 +412;412 +413;413 +414;414 +415;415 +416;416 +417;417 +418;418 +419;419 +420;420 +421;421 +422;422 +423;423 +424;424 +425;425 +426;426 +427;427 +428;428 +429;429 +430;430 +431;431 +432;432 +433;433 +434;434 +435;435 +436;436 +437;437 +438;438 +439;439 +440;440 +441;441 +442;442 +443;443 +444;444 +445;445 +446;446 +447;447 +448;448 +449;449 +450;450 +451;451 +452;452 +453;453 +454;454 +455;455 +456;456 +457;457 +458;458 +459;459 +460;460 +461;461 +462;462 +463;463 +464;464 +465;465 +466;466 +467;467 +468;468 +469;469 +470;470 +471;471 +472;472 +473;473 +474;474 +475;475 +476;476 +477;477 +478;478 +479;479 +480;480 +481;481 +482;482 +483;483 +484;484 +485;485 +486;486 +487;487 +488;488 +489;489 +490;490 +491;491 +492;492 +493;493 +494;494 +495;495 +496;496 +497;497 +498;498 +499;499 +500;500 +501;501 +502;502 +503;503 +504;504 +505;505 +506;506 +507;507 +508;508 +509;509 +510;510 +511;511 +512;512 +513;513 +514;514 +515;515 +516;516 +517;517 +518;518 +519;519 +520;520 +521;521 +522;522 +523;523 +524;524 +525;525 +526;526 +527;527 +528;528 +529;529 +530;530 +531;531 +532;532 +533;533 +534;534 +535;535 +536;536 +537;537 +538;538 +539;539 +540;540 +541;541 +542;542 +543;543 +544;544 +545;545 +546;546 +547;547 +548;548 +549;549 +550;550 +551;551 +552;552 +553;553 +554;554 +555;555 +556;556 +557;557 +558;558 +559;559 +560;560 +561;561 +562;562 +563;563 +564;564 +565;565 +566;566 +567;567 +568;568 +569;569 +570;570 +571;571 +572;572 +573;573 +574;574 +575;575 +576;576 +577;577 +578;578 +579;579 +580;580 +581;581 +582;582 +583;583 +584;584 +585;585 +586;586 +587;587 +588;588 +589;589 +590;590 +591;591 +592;592 +593;593 +594;594 +595;595 +596;596 +597;597 +598;598 +599;599 +600;600 +601;601 +602;602 +603;603 +604;604 +605;605 +606;606 +607;607 +608;608 +609;609 +610;610 +611;611 +612;612 +613;613 +614;614 +615;615 +616;616 +617;617 +618;618 +619;619 +620;620 +621;621 +622;622 +623;623 +624;624 +625;625 +626;626 +627;627 +628;628 +629;629 +630;630 +631;631 +632;632 +633;633 +634;634 +635;635 +636;636 +637;637 +638;638 +639;639 +640;640 +641;641 +642;642 +643;643 +644;644 +645;645 +646;646 +647;647 +648;648 +649;649 +650;650 +651;651 +652;652 +653;653 +654;654 +655;655 +656;656 +657;657 +658;658 +659;659 +660;660 +661;661 +662;662 +663;663 +664;664 +665;665 +666;666 +667;667 +668;668 +669;669 +670;670 +671;671 +672;672 +673;673 +674;674 +675;675 +676;676 +677;677 +678;678 +679;679 +680;680 +681;681 +682;682 +683;683 +684;684 +685;685 +686;686 +687;687 +688;688 +689;689 +690;690 +691;691 +692;692 +693;693 +694;694 +695;695 +696;696 +697;697 +698;698 +699;699 +700;700 +701;701 +702;702 +703;703 +704;704 +705;705 +706;706 +707;707 +708;708 +709;709 +710;710 +711;711 +712;712 +713;713 +714;714 +715;715 +716;716 +717;717 +718;718 +719;719 +720;720 +721;721 +722;722 +723;723 +724;724 +725;725 +726;726 +727;727 +728;728 +729;729 +730;730 +731;731 +732;732 +733;733 +734;734 +735;735 +736;736 +737;737 +738;738 +739;739 +740;740 +741;741 +742;742 +743;743 +744;744 +745;745 +746;746 +747;747 +748;748 +749;749 +750;750 +751;751 +752;752 +753;753 +754;754 +755;755 +756;756 +757;757 +758;758 +759;759 +760;760 +761;761 +762;762 +763;763 +764;764 +765;765 +766;766 +767;767 +768;768 +769;769 +770;770 +771;771 +772;772 +773;773 +774;774 +775;775 +776;776 +777;777 +778;778 +779;779 +780;780 +781;781 +782;782 +783;783 +784;784 +785;785 +786;786 +787;787 +788;788 +789;789 +790;790 +791;791 +792;792 +793;793 +794;794 +795;795 +796;796 +797;797 +798;798 +799;799 +800;800 +801;801 +802;802 +803;803 +804;804 +805;805 +806;806 +807;807 +808;808 +809;809 +810;810 +811;811 +812;812 +813;813 +814;814 +815;815 +816;816 +817;817 +818;818 +819;819 +820;820 +821;821 +822;822 +823;823 +824;824 +825;825 +826;826 +827;827 +828;828 +829;829 +830;830 +831;831 +832;832 +833;833 +834;834 +835;835 +836;836 +837;837 +838;838 +839;839 +840;840 +841;841 +842;842 +843;843 +844;844 +845;845 +846;846 +847;847 +848;848 +849;849 +850;850 +851;851 +852;852 +853;853 +854;854 +855;855 +856;856 +857;857 +858;858 +859;859 +860;860 +861;861 +862;862 +863;863 +864;864 +865;865 +866;866 +867;867 +868;868 +869;869 +870;870 +871;871 +872;872 +873;873 +874;874 +875;875 +876;876 +877;877 +878;878 +879;879 +880;880 +881;881 +882;882 +883;883 +884;884 +885;885 +886;886 +887;887 +888;888 +889;889 +890;890 +891;891 +892;892 +893;893 +894;894 +895;895 +896;896 +897;897 +898;898 +899;899 +900;900 +901;901 +902;902 +903;903 +904;904 +905;905 +906;906 +907;907 +908;908 +909;909 +910;910 +911;911 +912;912 +913;913 +914;914 +915;915 +916;916 +917;917 +918;918 +919;919 +920;920 +921;921 +922;922 +923;923 +924;924 +925;925 +926;926 +927;927 +928;928 +929;929 +930;930 +931;931 +932;932 +933;933 +934;934 +935;935 +936;936 +937;937 +938;938 +939;939 +940;940 +941;941 +942;942 +943;943 +944;944 +945;945 +946;946 +947;947 +948;948 +949;949 +950;950 +951;951 +952;952 +953;953 +954;954 +955;955 +956;956 +957;957 +958;958 +959;959 +960;960 +961;961 +962;962 +963;963 +964;964 +965;965 +966;966 +967;967 +968;968 +969;969 +970;970 +971;971 +972;972 +973;973 +974;974 +975;975 +976;976 +977;977 +978;978 +979;979 +980;980 +981;981 +982;982 +983;983 +984;984 +985;985 +986;986 +987;987 +988;988 +989;989 +990;990 +991;991 +992;992 +993;993 +994;994 +995;995 +996;996 +997;997 +998;998 +999;999 +1000;1000 +1001;1001 +1002;1002 +1003;1003 +1004;1004 +1005;1005 +1006;1006 +1007;1007 +1008;1008 +1009;1009 +1010;1010 +1011;1011 +1012;1012 +1013;1013 +1014;1014 +1015;1015 +1016;1016 +1017;1017 +1018;1018 +1019;1019 +1020;1020 +1021;1021 +1022;1022 +1023;1023 diff --git a/examples/osd/arduino-roomalert/Makefile b/examples/osd/arduino-roomalert/Makefile index 3df5d4a2a..fad4a2b73 100644 --- a/examples/osd/arduino-roomalert/Makefile +++ b/examples/osd/arduino-roomalert/Makefile @@ -1,22 +1,29 @@ # Set this to the name of your sketch (without extension .pde) SKETCH=sketch +EXE=arduino-example -all: arduino-example \ - arduino-example.osd-merkur.hex arduino-example.osd-merkur.eep - -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 - -# for some platforms -UIP_CONF_IPV6=1 -# IPv6 make config disappeared completely -CFLAGS += -DUIP_CONF_IPV6=1 +all: $(EXE) CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" -PROJECT_SOURCEFILES += resource_pir.c ${SKETCH}.cpp +PROJECT_SOURCEFILES += ${SKETCH}.cpp + + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) # variable for Makefile.include ifneq ($(TARGET), minimal-net) @@ -35,60 +42,15 @@ endif # linker optimizations SMALL=1 -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif -APPS += erbium time json arduino json-resource +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += arduino include $(CONTIKI)/Makefile.include include $(CONTIKI)/apps/arduino/Makefile.include -arduino-example.osd-merkur.hex: arduino-example.osd-merkur - avr-objcopy -j .text -j .data -O ihex arduino-example.osd-merkur \ - arduino-example.osd-merkur.hex - -arduino-example.osd-merkur.eep: arduino-example.osd-merkur - avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O ihex \ - arduino-example.osd-merkur arduino-example.osd-merkur.eep - -flash: arduino-example.osd-merkur.hex arduino-example.osd-merkur.eep - avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U \ - flash:w:arduino-example.osd-merkur.hex:a -U \ - eeprom:w:arduino-example.osd-merkur.eep:a - -.PHONY: flash - $(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c (cd $(CONTIKI)/tools && $(MAKE) tunslip6) @@ -100,3 +62,10 @@ connect-router-cooja: $(CONTIKI)/tools/tunslip6 connect-minimal: sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/arduino-roomalert/flash.sh b/examples/osd/arduino-roomalert/flash.sh index e9cb40bfc..e82962073 100755 --- a/examples/osd/arduino-roomalert/flash.sh +++ b/examples/osd/arduino-roomalert/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -make TARGET=osd-merkur flash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/arduino-roomalert/resource_pir.c b/examples/osd/arduino-roomalert/resource_pir.c deleted file mode 100644 index e109e2254..000000000 --- a/examples/osd/arduino-roomalert/resource_pir.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * \file - * Resource for Arduino analog read - * \author - * Harald Pichler - * - * \brief get/put pwm and period for LED pin - * - */ - -#include -#include -#include -#include "contiki.h" -#include "jsonparse.h" -/* Only coap 13 for now */ -#include "er-coap-13.h" -#include "generic_resource.h" -#include "resource_pir.h" -#include "Arduino.h" - -size_t -pir_v (const char *name, uint8_t is_json, char *buf, size_t bufsize) -{ - pir_value = digitalRead(pir_pin); - return snprintf - (buf, bufsize, "%d", pir_value); -} - -GENERIC_RESOURCE \ - ( pir, METHOD_GET - , "pir/v" - , Moisture value - , V - , NULL - , pir_v - ); - -/* - * VI settings, see coding style - * ex:ts=8:et:sw=2 - */ diff --git a/examples/osd/arduino-roomalert/resource_pir.h b/examples/osd/arduino-roomalert/resource_pir.h deleted file mode 100644 index 8bac1b61e..000000000 --- a/examples/osd/arduino-roomalert/resource_pir.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - * \defgroup Arduino LED PWM example - * - * Resource definition for Arduino LED PWM module - * - * @{ - */ - -/** - * \file - * Resource definitions for the Arduino LED PWM module - * - * \author - * Ralf Schlatterbeck - */ - -#ifndef pir_h -#define pir_h -#include "contiki.h" -#include "contiki-net.h" -#include "erbium.h" -#include "er-coap-13.h" - -extern uint8_t pir_pin; -extern uint16_t pir_value; - -extern resource_t resource_pir; - -#endif // pir_h -/** @} */ diff --git a/examples/osd/arduino-roomalert/resources/res-room.c b/examples/osd/arduino-roomalert/resources/res-room.c new file mode 100644 index 000000000..f51596a9a --- /dev/null +++ b/examples/osd/arduino-roomalert/resources/res-room.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * room resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_room, + "title=\"Moisture status\";rt=\"Moisture\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern uint8_t room_pin; +extern uint8_t room_status; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + room_status = digitalRead(room_pin); + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", room_status); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'room':%d}", room_status); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-roomalert/run.sh b/examples/osd/arduino-roomalert/run.sh index 295a9ab1d..5d5cbbbb4 100755 --- a/examples/osd/arduino-roomalert/run.sh +++ b/examples/osd/arduino-roomalert/run.sh @@ -1,5 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/arduino-roomalert/sketch.pde b/examples/osd/arduino-roomalert/sketch.pde index 4d11f6085..c17ae7f81 100644 --- a/examples/osd/arduino-roomalert/sketch.pde +++ b/examples/osd/arduino-roomalert/sketch.pde @@ -1,7 +1,7 @@ /* * Sample arduino sketch using contiki features. * We turn the LED off - * We allow read the water sensor + * We allow read the moisture sensor * Unfortunately sleeping for long times in loop() isn't currently * possible, something turns off the CPU (including PWM outputs) if a * Proto-Thread is taking too long. We need to find out how to sleep in @@ -11,21 +11,24 @@ */ extern "C" { -#include -#include "resource_pir.h" +#include "rest-engine.h" + +extern resource_t res_room, res_battery; +uint8_t room_pin = 3; +uint8_t room_status = 0; #define LED_PIN 4 - -uint8_t pir_pin = A5; -uint16_t pir_value = 0; } void setup (void) { + // switch off the led pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, HIGH); + // init coap resourcen rest_init_engine (); - rest_activate_resource (&resource_pir); + rest_activate_resource (&res_room, "s/room"); + rest_activate_resource (&res_battery, "s/battery"); } void loop (void) diff --git a/examples/osd/arduino-sketch/Makefile b/examples/osd/arduino-sketch/Makefile index a9eadafb7..d54e087b2 100644 --- a/examples/osd/arduino-sketch/Makefile +++ b/examples/osd/arduino-sketch/Makefile @@ -1,19 +1,14 @@ # Set this to the name of your sketch (without extension .pde) SKETCH=sketch +EXE=arduino-example -all: arduino-example \ - arduino-example.osd-merkur.hex arduino-example.osd-merkur.eep - -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 - -# for some platforms -UIP_CONF_IPV6=1 -# IPv6 make config disappeared completely -CFLAGS += -DUIP_CONF_IPV6=1 +all: $(EXE) CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" PROJECT_SOURCEFILES += resource_led_pwm.c ${SKETCH}.cpp @@ -35,60 +30,14 @@ endif # linker optimizations SMALL=1 -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif - -APPS += erbium time json arduino json-resource +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += time json arduino json-resource include $(CONTIKI)/Makefile.include include $(CONTIKI)/apps/arduino/Makefile.include -arduino-example.osd-merkur.hex: arduino-example.osd-merkur - avr-objcopy -j .text -j .data -O ihex arduino-example.osd-merkur \ - arduino-example.osd-merkur.hex - -arduino-example.osd-merkur.eep: arduino-example.osd-merkur - avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O ihex \ - arduino-example.osd-merkur arduino-example.osd-merkur.eep - -flash: arduino-example.osd-merkur.hex arduino-example.osd-merkur.eep - avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U \ - flash:w:arduino-example.osd-merkur.hex:a -U \ - eeprom:w:arduino-example.osd-merkur.eep:a - -.PHONY: flash - $(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c (cd $(CONTIKI)/tools && $(MAKE) tunslip6) @@ -100,3 +49,10 @@ connect-router-cooja: $(CONTIKI)/tools/tunslip6 connect-minimal: sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/arduino-sketch/flash.sh b/examples/osd/arduino-sketch/flash.sh index e9cb40bfc..e82962073 100755 --- a/examples/osd/arduino-sketch/flash.sh +++ b/examples/osd/arduino-sketch/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -make TARGET=osd-merkur flash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/arduino-sketch/led_pwm.h b/examples/osd/arduino-sketch/led_pwm.h index 5931bdc50..a51939af5 100644 --- a/examples/osd/arduino-sketch/led_pwm.h +++ b/examples/osd/arduino-sketch/led_pwm.h @@ -18,18 +18,17 @@ #define led_pwm_h #include "contiki.h" #include "contiki-net.h" -#include "erbium.h" -#include "er-coap-13.h" +#include "er-coap.h" extern uint8_t pwm; extern uint8_t period_100ms; extern uint16_t analog2_voltage; extern uint16_t analog5_voltage; -extern resource_t resource_led_pwm; -extern resource_t resource_led_period; -extern resource_t resource_analog2_voltage; -extern resource_t resource_analog5_voltage; +extern resource_t res_led_pwm; +extern resource_t res_led_period; +extern resource_t res_analog2_voltage; +extern resource_t res_analog5_voltage; #endif // led_pwm_h /** @} */ diff --git a/examples/osd/arduino-sketch/resource_led_pwm.c b/examples/osd/arduino-sketch/resource_led_pwm.c index a7c1e1182..2dbfa0611 100644 --- a/examples/osd/arduino-sketch/resource_led_pwm.c +++ b/examples/osd/arduino-sketch/resource_led_pwm.c @@ -13,36 +13,36 @@ #include #include "contiki.h" #include "jsonparse.h" -/* Only coap 13 for now */ -#include "er-coap-13.h" +#include "er-coap.h" #include "generic_resource.h" #include "led_pwm.h" -void pwm_from_string (const char *name, const char *s) +int pwm_from_string (const char *name, const char *uri, const char *s) { uint32_t tmp = strtoul (s, NULL, 10); if (tmp > 255) { tmp = 255; } pwm = tmp; + return 0; } size_t -pwm_to_string (const char *name, uint8_t is_json, char *buf, size_t bufsize) +pwm_to_string (const char *name, const char *uri, char *buf, size_t bufsize) { return snprintf (buf, bufsize, "%d", pwm); } GENERIC_RESOURCE \ - ( led_pwm, METHOD_GET | METHOD_PUT - , "led/pwm" + ( led_pwm , LED PWM , duty-cycle + , 0 , pwm_from_string , pwm_to_string ); -void period_from_string (const char *name, const char *s) +int period_from_string (const char *name, const char *uri, const char *s) { uint32_t tmp = (strtoul (s, NULL, 10) + 50) / 100; if (tmp > 10) { @@ -52,51 +52,52 @@ void period_from_string (const char *name, const char *s) tmp = 1; } period_100ms = tmp; + return 0; } size_t -period_to_string (const char *name, uint8_t is_json, char *buf, size_t bufsize) +period_to_string (const char *name, const char *uri, char *buf, size_t bufsize) { return snprintf (buf, bufsize, "%d", period_100ms * 100); } GENERIC_RESOURCE \ - ( led_period, METHOD_GET | METHOD_PUT - , "led/period" + ( led_period , LED Period , ms + , 0 , period_from_string , period_to_string ); size_t -analog2_v (const char *name, uint8_t is_json, char *buf, size_t bufsize) +analog2_v (const char *name, const char *uri, char *buf, size_t bufsize) { return snprintf (buf, bufsize, "%d.%03d", analog2_voltage / 1000, analog2_voltage % 1000); } GENERIC_RESOURCE \ - ( analog2_voltage, METHOD_GET - , "analog/2" + ( analog2_voltage , Analog 2 voltage , V + , 0 , NULL , analog2_v ); size_t -analog5_v (const char *name, uint8_t is_json, char *buf, size_t bufsize) +analog5_v (const char *name, const char *uri, char *buf, size_t bufsize) { return snprintf (buf, bufsize, "%d.%03d", analog5_voltage / 1000, analog5_voltage % 1000); } GENERIC_RESOURCE \ - ( analog5_voltage, METHOD_GET - , "analog/5" + ( analog5_voltage , Analog 5 voltage , V + , 0 , NULL , analog5_v ); diff --git a/examples/osd/arduino-sketch/run.sh b/examples/osd/arduino-sketch/run.sh index 295a9ab1d..5d5cbbbb4 100755 --- a/examples/osd/arduino-sketch/run.sh +++ b/examples/osd/arduino-sketch/run.sh @@ -1,5 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/arduino-sketch/sketch.pde b/examples/osd/arduino-sketch/sketch.pde index 8874c056a..60bf3af42 100644 --- a/examples/osd/arduino-sketch/sketch.pde +++ b/examples/osd/arduino-sketch/sketch.pde @@ -23,11 +23,12 @@ uint16_t analog5_voltage = 0; void setup (void) { + arduino_pwm_timer_init (); rest_init_engine (); - rest_activate_resource (&resource_led_pwm); - rest_activate_resource (&resource_led_period); - rest_activate_resource (&resource_analog2_voltage); - rest_activate_resource (&resource_analog5_voltage); + rest_activate_resource (&res_led_pwm, "led/pwm"); + rest_activate_resource (&res_led_period, "led/period"); + rest_activate_resource (&res_analog2_voltage, "analog/2"); + rest_activate_resource (&res_analog5_voltage, "analog/5"); } void loop (void) diff --git a/examples/osd/arduino-wateralert/Makefile b/examples/osd/arduino-wateralert/Makefile index 96ed4e242..5a017eac0 100644 --- a/examples/osd/arduino-wateralert/Makefile +++ b/examples/osd/arduino-wateralert/Makefile @@ -1,22 +1,28 @@ # Set this to the name of your sketch (without extension .pde) SKETCH=sketch +EXE=arduino-example -all: arduino-example \ - arduino-example.osd-merkur.hex arduino-example.osd-merkur.eep - -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 - -# for some platforms -UIP_CONF_IPV6=1 -# IPv6 make config disappeared completely -CFLAGS += -DUIP_CONF_IPV6=1 +all: $(EXE) CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" -PROJECT_SOURCEFILES += resource_water.c ${SKETCH}.cpp +PROJECT_SOURCEFILES += ${SKETCH}.cpp + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) # variable for Makefile.include ifneq ($(TARGET), minimal-net) @@ -35,60 +41,15 @@ endif # linker optimizations SMALL=1 -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif -APPS += erbium time json arduino json-resource +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += arduino include $(CONTIKI)/Makefile.include include $(CONTIKI)/apps/arduino/Makefile.include -arduino-example.osd-merkur.hex: arduino-example.osd-merkur - avr-objcopy -j .text -j .data -O ihex arduino-example.osd-merkur \ - arduino-example.osd-merkur.hex - -arduino-example.osd-merkur.eep: arduino-example.osd-merkur - avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O ihex \ - arduino-example.osd-merkur arduino-example.osd-merkur.eep - -flash: arduino-example.osd-merkur.hex arduino-example.osd-merkur.eep - avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U \ - flash:w:arduino-example.osd-merkur.hex:a -U \ - eeprom:w:arduino-example.osd-merkur.eep:a - -.PHONY: flash - $(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c (cd $(CONTIKI)/tools && $(MAKE) tunslip6) @@ -100,3 +61,10 @@ connect-router-cooja: $(CONTIKI)/tools/tunslip6 connect-minimal: sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/arduino-wateralert/flash.sh b/examples/osd/arduino-wateralert/flash.sh index e9cb40bfc..e82962073 100755 --- a/examples/osd/arduino-wateralert/flash.sh +++ b/examples/osd/arduino-wateralert/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -make TARGET=osd-merkur flash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/arduino-wateralert/resource_water.c b/examples/osd/arduino-wateralert/resource_water.c deleted file mode 100644 index 9e7cf1ee5..000000000 --- a/examples/osd/arduino-wateralert/resource_water.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * \file - * Resource for Arduino analog read - * \author - * Harald Pichler - * - * \brief get/put pwm and period for LED pin - * - */ - -#include -#include -#include -#include "contiki.h" -#include "jsonparse.h" -/* Only coap 13 for now */ -#include "er-coap-13.h" -#include "generic_resource.h" -#include "resource_water.h" -#include "Arduino.h" - -size_t -water_v (const char *name, uint8_t is_json, char *buf, size_t bufsize) -{ - water_voltage = analogRead(water_pin); - return snprintf - (buf, bufsize, "%d", water_voltage); -} - -GENERIC_RESOURCE \ - ( water, METHOD_GET - , "water/v" - , Moisture voltage - , V - , NULL - , water_v - ); - -/* - * VI settings, see coding style - * ex:ts=8:et:sw=2 - */ diff --git a/examples/osd/arduino-wateralert/resource_water.h b/examples/osd/arduino-wateralert/resource_water.h deleted file mode 100644 index d5836b187..000000000 --- a/examples/osd/arduino-wateralert/resource_water.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - * \defgroup Arduino LED PWM example - * - * Resource definition for Arduino LED PWM module - * - * @{ - */ - -/** - * \file - * Resource definitions for the Arduino LED PWM module - * - * \author - * Ralf Schlatterbeck - */ - -#ifndef water_h -#define water_h -#include "contiki.h" -#include "contiki-net.h" -#include "erbium.h" -#include "er-coap-13.h" - -extern uint8_t water_pin; -extern uint16_t water_voltage; - -extern resource_t resource_water; - -#endif // water_h -/** @} */ diff --git a/examples/osd/arduino-wateralert/resources/res-moisture.c b/examples/osd/arduino-wateralert/resources/res-moisture.c new file mode 100644 index 000000000..b57f96514 --- /dev/null +++ b/examples/osd/arduino-wateralert/resources/res-moisture.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Moisture resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_moisture, + "title=\"Moisture status\";rt=\"Moisture\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern uint8_t moisture_pin; +extern uint16_t moisture_voltage; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + moisture_voltage = analogRead(moisture_pin); + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", moisture_voltage); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'moisture':%d}", moisture_voltage); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-wateralert/run.sh b/examples/osd/arduino-wateralert/run.sh index 295a9ab1d..5d5cbbbb4 100755 --- a/examples/osd/arduino-wateralert/run.sh +++ b/examples/osd/arduino-wateralert/run.sh @@ -1,5 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/arduino-wateralert/sketch.pde b/examples/osd/arduino-wateralert/sketch.pde index d55c95d74..22aaa864f 100644 --- a/examples/osd/arduino-wateralert/sketch.pde +++ b/examples/osd/arduino-wateralert/sketch.pde @@ -1,7 +1,7 @@ /* * Sample arduino sketch using contiki features. * We turn the LED off - * We allow read the water sensor + * We allow read the moisture sensor * Unfortunately sleeping for long times in loop() isn't currently * possible, something turns off the CPU (including PWM outputs) if a * Proto-Thread is taking too long. We need to find out how to sleep in @@ -11,24 +11,39 @@ */ extern "C" { -#include -#include "resource_water.h" +#include "arduino-process.h" +#include "rest-engine.h" -#define LED_PIN 4 - -uint8_t water_pin = A5; -uint16_t water_voltage = 0; +extern volatile uint8_t mcusleepcycle; // default 16 +extern resource_t res_moisture, res_battery; +uint8_t moisture_pin = A5; +uint16_t moisture_voltage = 0; +#define BUZZER_PIN 3 /* sig pin of the buzzer */ +#define LED_PIN 4 /* LED Pin */ } void setup (void) { + // switch off the led pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, HIGH); + // setup Buzzer + pinMode(BUZZER_PIN, OUTPUT); + digitalWrite(BUZZER_PIN, LOW); + // init coap resourcen rest_init_engine (); - rest_activate_resource (&resource_water); + rest_activate_resource (&res_moisture, "s/moisture"); + rest_activate_resource (&res_battery, "s/battery"); } void loop (void) { - + mcu_sleep_off(); + moisture_voltage = analogRead(moisture_pin); + if(moisture_voltage < 800){ + digitalWrite(BUZZER_PIN, LOW); + }else{ + digitalWrite(BUZZER_PIN, HIGH); + } + mcu_sleep_on(); } diff --git a/examples/osd/arduino-weather/Adafruit_HTU21DF.cpp b/examples/osd/arduino-weather/Adafruit_HTU21DF.cpp new file mode 100644 index 000000000..84bbeb066 --- /dev/null +++ b/examples/osd/arduino-weather/Adafruit_HTU21DF.cpp @@ -0,0 +1,100 @@ +/*************************************************** + This is a library for the HTU21DF Humidity & Temp Sensor + + Designed specifically to work with the HTU21DF sensor from Adafruit + ----> https://www.adafruit.com/products/1899 + + These displays use I2C to communicate, 2 pins are required to + interface + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ****************************************************/ + +#include "Adafruit_HTU21DF.h" +#if defined(__AVR__) +#include +#endif + +Adafruit_HTU21DF::Adafruit_HTU21DF() { +} + + +boolean Adafruit_HTU21DF::begin(void) { + Wire.begin(); + + reset(); + + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_READREG); + Wire.endTransmission(); + Wire.requestFrom(HTU21DF_I2CADDR, 1); + return (Wire.read() == 0x2); // after reset should be 0x2 +} + +void Adafruit_HTU21DF::reset(void) { + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_RESET); + Wire.endTransmission(); + delay(15); +} + + +float Adafruit_HTU21DF::readTemperature(void) { + + // OK lets ready! + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_READTEMP); + Wire.endTransmission(); + + delay(50); // add delay between request and actual read! + + Wire.requestFrom(HTU21DF_I2CADDR, 3); + while (!Wire.available()) {} + + uint16_t t = Wire.read(); + t <<= 8; + t |= Wire.read(); + + uint8_t crc = Wire.read(); + + float temp = t; + temp *= 175.72; + temp /= 65536; + temp -= 46.85; + + return temp; +} + + +float Adafruit_HTU21DF::readHumidity(void) { + // OK lets ready! + Wire.beginTransmission(HTU21DF_I2CADDR); + Wire.write(HTU21DF_READHUM); + Wire.endTransmission(); + + delay(50); // add delay between request and actual read! + + Wire.requestFrom(HTU21DF_I2CADDR, 3); + while (!Wire.available()) {} + + uint16_t h = Wire.read(); + h <<= 8; + h |= Wire.read(); + + uint8_t crc = Wire.read(); + + float hum = h; + hum *= 125; + hum /= 65536; + hum -= 6; + + return hum; +} + + + +/*********************************************************************/ diff --git a/examples/osd/arduino-weather/Adafruit_HTU21DF.h b/examples/osd/arduino-weather/Adafruit_HTU21DF.h new file mode 100644 index 000000000..fe8870e39 --- /dev/null +++ b/examples/osd/arduino-weather/Adafruit_HTU21DF.h @@ -0,0 +1,44 @@ +/*************************************************** + This is a library for the HTU21D-F Humidity & Temp Sensor + + Designed specifically to work with the HTU21D-F sensor from Adafruit + ----> https://www.adafruit.com/products/1899 + + These displays use I2C to communicate, 2 pins are required to + interface + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ****************************************************/ + +//#if (ARDUINO >= 100) + #include "Arduino.h" +//#else +// #include "WProgram.h" +//#endif +#include "Wire.h" + +#define HTU21DF_I2CADDR 0x40 +#define HTU21DF_READTEMP 0xE3 +#define HTU21DF_READHUM 0xE5 +#define HTU21DF_WRITEREG 0xE6 +#define HTU21DF_READREG 0xE7 +#define HTU21DF_RESET 0xFE + + + +class Adafruit_HTU21DF { + public: + Adafruit_HTU21DF(); + boolean begin(void); + float readTemperature(void); + float readHumidity(void); + void reset(void); + private: + boolean readData(void); + float humidity, temp; +}; + diff --git a/examples/osd/arduino-weather/BH1750FVI.cpp b/examples/osd/arduino-weather/BH1750FVI.cpp new file mode 100644 index 000000000..fd871371a --- /dev/null +++ b/examples/osd/arduino-weather/BH1750FVI.cpp @@ -0,0 +1,209 @@ +#include "BH1750FVI.h" +//#if ARDUINO >= 100 + #include "Arduino.h" +//#else +// #include "WProgram.h" +//#endif + +#include + +void BH1750FVI::begin(byte mode, byte addr, double sens, int pin){ + if(pin>=0 && pin<55){ + pinMode(pin, OUTPUT); + if(addr==BH_AddrL) digitalWrite(pin, LOW); + if(addr==BH_AddrH) digitalWrite(pin, HIGH); + } + byte sensitivity; + if(sens> 5); + MTreg_loByte = BH_MTrLb | (sensitivity & 0b00011111); + switch(mode){ + case BH_ContL: + case BH_ContH: + case BH_Conth: + startOngoingSamples(mode); + break; + case BH_SingH: + case BH_Singh: + case BH_SingL: + startSingleSample(mode); + break; + default: + mode = BH_EasyH; + startOngoingSamples(mode); + break; + } + sampleUnseen = false; + lastSampleStart = 0; +} + +word BH1750FVI::startOngoingSamples(char mode){ + if(mode==BH_NoMod) mode=currentMode; + byte lowLevelMode = mode; + if(lowLevelMode==BH_EasyH) lowLevelMode=BH_ContH; + switch(mode){ + case BH_EasyH: + case BH_ContH: + case BH_Conth: + case BH_ContL: + i2cWrite(BH_PowOn); + i2cWrite(MTreg_hiByte); + i2cWrite(MTreg_loByte); + i2cWrite(lowLevelMode); + lastSampleStart = millis(); + currentMode = mode; + return setSensitivity(currentSensitivity); + break; + default: + return 0; + } +} + +word BH1750FVI::startSingleSample(char mode){ + if(mode==BH_NoMod){ + mode=currentMode; + } + switch(mode){ + case BH_SingH: + case BH_Singh: + case BH_SingL: + i2cWrite(BH_PowOn); + i2cWrite(MTreg_hiByte); + i2cWrite(MTreg_loByte); + i2cWrite(mode); + lastSampleStart = millis(); + currentMode = mode; + return setSensitivity(currentSensitivity); + break; + default: + return 0; + } +} + +bool BH1750FVI::sampleIsFresh(){ + if(sampleUnseen) return true; + else if((millis() > (lastSampleStart+currentSamplingTime))){ + sampleUnseen = true; + return true; + } + else return false; +} + +word BH1750FVI::getLightLevel(char mode){ + unsigned long int Intensity_value; + sampleUnseen = false; + Intensity_value = i2cRead(); + if(mode!='r'){ + Intensity_value = (Intensity_value*5)/6; + if(mode!='c'){ + Intensity_value = (Intensity_value*69)/currentSensitivity; + } + /*this next adjustment is not useful in practice. if you're using + a half-scale mode, you want the extra sensitivity. I'm leaving it + here for reference. + switch(currentMode){ + case BH_Singh: + case BH_Conth: + Intensity_value /= 2; + }*/ + Intensity_value = constrain(Intensity_value, 0, 65535); + } + switch(currentMode){ + case BH_ContH: + case BH_Conth: + case BH_ContL: + case BH_EasyH: + //this is a fake previous sample time that will keep pace with + //the actual BH1750FVI's sampling rate, but isn't necessarily + //synchronized to the earliest time each new sample is available. + //if you want true synchronized timing, use a single-sample mode. + lastSampleStart = millis(); + } + return (word)Intensity_value; +} + +word BH1750FVI::setSensitivity(double sens){ + if(sens<((double)(BH_MinSv/2))){ + sens = constrain(sens, + ((double)BH_MinSv/(double)BH_DefSv), + ((double)BH_MaxSv/(double)BH_DefSv) + ); + sens = sens*(double)BH_DefSv; + } + else{ + sens = constrain(sens, (double)BH_MinSv, (double)BH_MaxSv); + } + return setSensitivity((byte)round(sens)); +} + +word BH1750FVI::setSensitivity(float sens){ + return setSensitivity((double)sens); +} + +word BH1750FVI::setSensitivity(int sens){ + sens = constrain(sens, 1, BH_MaxSv); + return setSensitivity((byte)sens); +} + +word BH1750FVI::setSensitivity(byte sens){ + if(sens<(BH_MinSv/2)){ + sens = BH_DefSv*(constrain(sens, (byte)1, (byte)3)); + } + else{ + sens = constrain(sens, BH_MinSv, BH_MaxSv); + } + switch(currentMode){ + case BH_ContL: + case BH_SingL: + currentSamplingTime = (word)((BH_FastD*(unsigned long int)sens)/BH_DefSv); + break; + default: + currentSamplingTime = (word)((((unsigned long int)BH_SlowD)*((unsigned long int)sens))/BH_DefSv); + break; + } + MTreg_hiByte = BH_MTrHb | (sens >> 5); + MTreg_loByte = BH_MTrLb | (sens & 0b00011111); + currentSensitivity = sens; + sampleUnseen = false; + return currentSamplingTime; +} + +void BH1750FVI::powerDown(){ + i2cWrite(BH_PowOf); +} + +/*I2C INTERFACE + These two functions were originally based on code written by + https://github.com/claws/ and + https://github.com/Genotronex/ +*/ +void BH1750FVI::i2cWrite(byte dataToSend){ + Wire.beginTransmission(address); + Wire.write(dataToSend); + Wire.endTransmission(); +} + +word BH1750FVI::i2cRead(){ + word value; + Wire.beginTransmission(address); + Wire.requestFrom(address, (byte)2); + if(Wire.available()){ + value = Wire.read(); + if(Wire.available()){ + value <<= 8; + value |= Wire.read(); + } + else value=0; + } + else value=0; + Wire.endTransmission(); + return value; +} diff --git a/examples/osd/arduino-weather/BH1750FVI.h b/examples/osd/arduino-weather/BH1750FVI.h new file mode 100644 index 000000000..acdf62102 --- /dev/null +++ b/examples/osd/arduino-weather/BH1750FVI.h @@ -0,0 +1,115 @@ +#ifndef BH1750FVI_h +#define BH1750FVI_h + +//#if ARDUINO >= 100 + #include "Arduino.h" +//#else +// #include "WProgram.h" +//#endif + +#include + +//device address options +#define BH_AddrL 0x23 // Device address when addr pin is LOW +#define BH_AddrH 0x5C // Device address when addr pin is HIGH + +//power codes +#define BH_PowOf 0x00 // power-off code +#define BH_PowOn 0x01 // power-on code +#define BH_Reset 0x07 // code to reset the light reading register to zero + +//mode codes +#define BH_NoMod 0x02 // No mode specified. Keeps mode the same as before. +#define BH_EasyH 0x03 // 'easy' mode. basically the same as ContH +#define BH_ContH 0x10 // continuous full-scale, high-resolution sampling +#define BH_Conth 0x11 // continuous with twice the resolution but half the max value +#define BH_ContL 0x13 // continuous full-scale, low-resolution sampling. faster. +#define BH_SingH 0x20 // take one high-resolution, full-scale sample then turn off +#define BH_Singh 0x21 // take one high-resolution, half-scale sample then turn off +#define BH_SingL 0x23 // take one low-resolution, full-scale sample then turn off + // (happens to be the same as the low address value) + +//sensitivity codes +#define BH_MTrHb 0x40 // last 3 bits must be masked to 3 MSB of desired value +#define BH_MTrLb 0x60 // last 5 bits must be masked to 5 LSB of desired value +#define BH_MinSv 31 // minimum sensitivity register value, yields Lux * 0.45 +#define BH_MaxSv 254 // maximum sensitivity register value, yields Lux * 3.68 +#define BH_DefSv 69 // default sensitivity register value, yields Lux * 1.00 + +//timing delays. they're actually longer than the datasheet says. +#define BH_FastD 18 // basic delay in microseconds for a fast sample +#define BH_SlowD 125 // basic delay in microseconds for a slow sample + +class BH1750FVI { + public: + /*BEGIN + this is intended to be as error-tolerant as possible. if you don't supply + a mode, the default mode will be 'easy'. the sensitivity obviously defaults + to 1.0 (byte value of 69). Default address selection is LOW, which is how + the BH1750FVI should default if you don't connect anything to its ADDR pin. + */void begin(byte mode=BH_EasyH, byte addr=BH_AddrL, double sens=BH_DefSv, int addrPin=-1); + + /*FRESH SAMPLE POLLING + Check whether you have already looked at the current sample. + */bool sampleIsFresh(); + + /*ACTUALLY GET A READING FROM THE SENSOR + This is probably all you wanted from this library. Return value is an + unsigned 16 bit integer with units of Lux. There are three possible modes: + 'r' raw numerical reading, no units, you get what you get + 'c' convert units to Lux or half-Lux, depending on the mode, but don't + compensate for the sensitivity setting. This allows sensitivity to + be used as enclosure optics calibration/compensation. + 't' true Lux (or half-Lux) reading, regardless of sensitivity settings. + */word getLightLevel(char adjustments='c'); + + word retrieveSample(); + + /*CONTINUOUS SAMPLING + Return value of this start function is the delay time between refreshes of + the ambient light reading. After you call this function, you can use getLightLevel() + to read the most recent ambient light level. If you try to run this ongoing start + function with a one-time mode argument, it will do nothing and return 0. + */word startOngoingSamples(char mode=BH_NoMod); + + /*ONE-TIME SAMPLE START + Return value of this start function is the delay time before the new ambient + light reading will be available. You can check whether the new sample is ready + yet using sampleIsFresh(). Retrieve that single sample with getLightLevel(). + If you give this one-time start function a continuous mode argument, it will + do nothing and return 0. + */word startSingleSample(char mode=BH_NoMod); + + /*SENSITIVITY SETTINGS + This function lets you change the 'sensitivity' of the BH1750FVI by changing + its sampling time up or down. The sensitivity is stored as a number between + 31 and 254, with a default value of 69. This is intended to compensate for + having the chip installed in an enclosure that blocks some ambient light. + The floating point versions of the function allow the sensitivity to be + given as a ratio between ~0.45 and ~3.68. The return value is the number of + milliseconds that the chip will take to create a new light level reading. + */word setSensitivity(double sens); + word setSensitivity(float sens); + word setSensitivity(int sens); + word setSensitivity(byte sens=BH_DefSv); + + /*POWERDOWN FUNCTION + In case you want to turn off the BH1750FVI to save power. Other commands will wake + the chip back up. Single sample modes automatically turn off the chip after sampling, + but you can still read the value from it without waking it up. + */void powerDown(); + + private: + void init(byte mode, byte addr, byte sens); + void i2cWrite(byte dataToSend); + word i2cRead(); + byte address; + byte currentMode; + byte currentSensitivity; + bool sampleUnseen; + byte MTreg_hiByte; + byte MTreg_loByte; + unsigned long int lastSampleStart; + word currentSamplingTime; +}; +#endif diff --git a/examples/osd/arduino-weather/Barometer.cpp b/examples/osd/arduino-weather/Barometer.cpp new file mode 100644 index 000000000..ec8b294a8 --- /dev/null +++ b/examples/osd/arduino-weather/Barometer.cpp @@ -0,0 +1,175 @@ +/* + Barometer library V1.0 + 2010 Copyright (c) Seeed Technology Inc. All right reserved. + + Original Author: LG + + 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 +*/ +#include "Barometer.h" +#include +#include + +void Barometer::init(void) +{ + Wire.begin(); +// Serial.print("Temperaturet: "); + ac1 = bmp085ReadInt(0xAA); + ac2 = bmp085ReadInt(0xAC); + ac3 = bmp085ReadInt(0xAE); + ac4 = bmp085ReadInt(0xB0); + ac5 = bmp085ReadInt(0xB2); + ac6 = bmp085ReadInt(0xB4); + b1 = bmp085ReadInt(0xB6); + b2 = bmp085ReadInt(0xB8); + mb = bmp085ReadInt(0xBA); + mc = bmp085ReadInt(0xBC); + md = bmp085ReadInt(0xBE); +// Serial.print("Temperaturet2: "); +} +// Read 1 byte from the BMP085 at 'address' +// Return: the read byte; +char Barometer::bmp085Read(unsigned char address) +{ + //Wire.begin(); + //unsigned char data; + Wire.beginTransmission(BMP085_ADDRESS); + Wire.write(address); + Wire.endTransmission(); + + Wire.requestFrom(BMP085_ADDRESS, 1); + while(!Wire.available()); + return Wire.read(); +} +// Read 2 bytes from the BMP085 +// First byte will be from 'address' +// Second byte will be from 'address'+1 +int Barometer::bmp085ReadInt(unsigned char address) +{ + unsigned char msb, lsb; + Wire.beginTransmission(BMP085_ADDRESS); + Wire.write(address); + Wire.endTransmission(); + Wire.requestFrom(BMP085_ADDRESS, 2); + while(Wire.available()<2); + msb = Wire.read(); + lsb = Wire.read(); + return (int) msb<<8 | lsb; +} +// Read the uncompensated temperature value +unsigned int Barometer::bmp085ReadUT() +{ + unsigned int ut; + Wire.beginTransmission(BMP085_ADDRESS); + Wire.write(0xF4); + Wire.write(0x2E); + Wire.endTransmission(); + delay(5); + ut = bmp085ReadInt(0xF6); + return ut; +} +// Read the uncompensated pressure value +unsigned long Barometer::bmp085ReadUP() +{ + unsigned char msb, lsb, xlsb; + unsigned long up = 0; + Wire.beginTransmission(BMP085_ADDRESS); + Wire.write(0xF4); + Wire.write(0x34 + (OSS<<6)); + Wire.endTransmission(); + delay(2 + (3<> (8-OSS); + return up; +} +void Barometer::writeRegister(int deviceAddress, byte address, byte val) +{ + Wire.beginTransmission(deviceAddress); // start transmission to device + Wire.write(address); // send register address + Wire.write(val); // send value to write + Wire.endTransmission(); // end transmission +} +int Barometer::readRegister(int deviceAddress, byte address) +{ + int v; + Wire.beginTransmission(deviceAddress); + Wire.write(address); // register to read + Wire.endTransmission(); + + Wire.requestFrom(deviceAddress, 1); // read a byte + + while(!Wire.available()) { + // waiting + } + + v = Wire.read(); + return v; +} +float Barometer::calcAltitude(float pressure) +{ + float A = pressure/101325; + float B = 1/5.25588; + float C = pow(A,B); + C = 1 - C; + C = C /0.0000225577; + return C; +} +float Barometer::bmp085GetTemperature(unsigned int ut) +{ + long x1, x2; + + x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15; + x2 = ((long)mc << 11)/(x1 + md); + PressureCompensate = x1 + x2; + + float temp = ((PressureCompensate + 8)>>4); + temp = temp /10; + + return temp; +} +long Barometer::bmp085GetPressure(unsigned long up) +{ + long x1, x2, x3, b3, b6, p; + unsigned long b4, b7; + b6 = PressureCompensate - 4000; + x1 = (b2 * (b6 * b6)>>12)>>11; + x2 = (ac2 * b6)>>11; + x3 = x1 + x2; + b3 = (((((long)ac1)*4 + x3)<>2; + + // Calculate B4 + x1 = (ac3 * b6)>>13; + x2 = (b1 * ((b6 * b6)>>12))>>16; + x3 = ((x1 + x2) + 2)>>2; + b4 = (ac4 * (unsigned long)(x3 + 32768))>>15; + + b7 = ((unsigned long)(up - b3) * (50000>>OSS)); + if (b7 < 0x80000000) + p = (b7<<1)/b4; + else + p = (b7/b4)<<1; + + x1 = (p>>8) * (p>>8); + x1 = (x1 * 3038)>>16; + x2 = (-7357 * p)>>16; + p += (x1 + x2 + 3791)>>4; + + long temp = p; + return temp; +} diff --git a/examples/osd/arduino-weather/Barometer.h b/examples/osd/arduino-weather/Barometer.h new file mode 100644 index 000000000..161702718 --- /dev/null +++ b/examples/osd/arduino-weather/Barometer.h @@ -0,0 +1,58 @@ +/* + Barometer library V1.0 + 2010 Copyright (c) Seeed Technology Inc. All right reserved. + + Original Author: LG + + 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 __BAROMETER_H__ +#define __BAROMETER_H__ + +#include +#include + +const unsigned char OSS = 0; +#define BMP085_ADDRESS 0x77 +class Barometer +{ +public: + void init(void); + long PressureCompensate; + float bmp085GetTemperature(unsigned int ut); + long bmp085GetPressure(unsigned long up); + float calcAltitude(float pressure); + unsigned int bmp085ReadUT(void); + unsigned long bmp085ReadUP(void); + +private: + int ac1; + int ac2; + int ac3; + unsigned int ac4; + unsigned int ac5; + unsigned int ac6; + int b1; + int b2; + int mb; + int mc; + int md; + char bmp085Read(unsigned char address); + int bmp085ReadInt(unsigned char address); + void writeRegister(int deviceAddress, byte address, byte val); + int readRegister(int deviceAddress, byte address); +}; + +#endif diff --git a/examples/osd/arduino-weather/Makefile b/examples/osd/arduino-weather/Makefile new file mode 100644 index 000000000..79a367a8c --- /dev/null +++ b/examples/osd/arduino-weather/Makefile @@ -0,0 +1,71 @@ +# Set this to the name of your sketch (without extension .pde) +SKETCH=sketch +EXE=arduino-example + +all: $(EXE) + +CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +LFLAGS += -lm + +PROJECT_SOURCEFILES += ${SKETCH}.cpp Barometer.cpp BH1750FVI.cpp Adafruit_HTU21DF.cpp + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) + +# variable for Makefile.include +ifneq ($(TARGET), minimal-net) +CFLAGS += -DUIP_CONF_IPV6_RPL=1 +else +# minimal-net does not support RPL under Linux and is mostly used to test CoAP only +${info INFO: compiling without RPL} +CFLAGS += -DUIP_CONF_IPV6_RPL=0 +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=640 +endif + +# linker optimizations +SMALL=1 + + +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += arduino + +include $(CONTIKI)/Makefile.include +include $(CONTIKI)/apps/arduino/Makefile.include + +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + (cd $(CONTIKI)/tools && $(MAKE) tunslip6) + +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + +connect-minimal: + sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/arduino-weather/README.md b/examples/osd/arduino-weather/README.md new file mode 100644 index 000000000..e1490ed05 --- /dev/null +++ b/examples/osd/arduino-weather/README.md @@ -0,0 +1,11 @@ +Arduino compatibility example +============================= + +This example shows that it is now possible to re-use arduino sketches in +Contiki. This example documents the necessary magic. Arduino specifies +two routines, `setup` and `loop`. Before `setup` is called, the +framework initializes hardware. In original Arduino, all this is done in +a `main` function (in C). For contiki we define a process that does the +same. + +See the documentation file in apps/contiki-compat/README.md diff --git a/examples/osd/arduino-weather/arduino-example.c b/examples/osd/arduino-weather/arduino-example.c new file mode 100644 index 000000000..ea74dd8b8 --- /dev/null +++ b/examples/osd/arduino-weather/arduino-example.c @@ -0,0 +1,2 @@ +#include +AUTOSTART_PROCESSES(&arduino_sketch); diff --git a/examples/osd/arduino-weather/flash.sh b/examples/osd/arduino-weather/flash.sh new file mode 100755 index 000000000..e82962073 --- /dev/null +++ b/examples/osd/arduino-weather/flash.sh @@ -0,0 +1,2 @@ +#!/bin/bash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/arduino-weather/project-conf.h b/examples/osd/arduino-weather/project-conf.h new file mode 100644 index 000000000..e25aed53c --- /dev/null +++ b/examples/osd/arduino-weather/project-conf.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ + +#ifndef PROJECT_RPL_WEB_CONF_H_ +#define PROJECT_RPL_WEB_CONF_H_ + +#define PLATFORM_HAS_LEDS 1 +//#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_BATTERY 1 + +#define SICSLOWPAN_CONF_FRAG 1 + +#define LOOP_INTERVAL (10 * CLOCK_SECOND) + +/* Save energy */ +//#define RDC_CONF_PT_YIELD_OFF + +/* For Debug: Dont allow MCU sleeping between channel checks */ +//#undef RDC_CONF_MCU_SLEEP +//#define RDC_CONF_MCU_SLEEP 0 + +/* Disabling RDC for demo purposes. Core updates often require more memory. */ +/* For projects, optimize memory and enable RDC again. */ +// #undef NETSTACK_CONF_RDC +//#define NETSTACK_CONF_RDC nullrdc_driver + +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 64 + +/* Estimate your header size, especially when using Proxy-Uri. */ +/* +#undef COAP_MAX_HEADER_SIZE +#define COAP_MAX_HEADER_SIZE 70 +*/ + +/* The IP buffer size must fit all other hops, in particular the border router. */ + +#undef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 256 + + +/* Multiplies with chunk size, be aware of memory constraints. */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* +#undef COAP_MAX_OBSERVERS +#define COAP_MAX_OBSERVERS 2 +*/ + +/* Filtering .well-known/core per query can be disabled to save space. */ +/* +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +*/ + +/* Save some memory for the sky platform. */ +/* +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 10 +*/ + +/* Reduce 802.15.4 frame queue to save RAM. */ +/* +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 +*/ + +/* +#undef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +*/ + +#endif /* PROJECT_RPL_WEB_CONF_H_ */ diff --git a/examples/osd/arduino-weather/resources/res-bh1750.c b/examples/osd/arduino-weather/resources/res-bh1750.c new file mode 100644 index 000000000..ae47f07a5 --- /dev/null +++ b/examples/osd/arduino-weather/resources/res-bh1750.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Moisture resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_bh1750, + "title=\"Lux status\";rt=\"Lux\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern uint16_t lux; + + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", lux); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'lux':%d}", lux); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-weather/resources/res-bmp085alt.c b/examples/osd/arduino-weather/resources/res-bmp085alt.c new file mode 100644 index 000000000..de90eae4f --- /dev/null +++ b/examples/osd/arduino-weather/resources/res-bmp085alt.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Barometer resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_bmp085alt, + "title=\"alt status\";rt=\"alt\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern char bmp085alt_s[8]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", bmp085alt_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%s}", bmp085alt_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-weather/resources/res-bmp085atm.c b/examples/osd/arduino-weather/resources/res-bmp085atm.c new file mode 100644 index 000000000..b97cffe6e --- /dev/null +++ b/examples/osd/arduino-weather/resources/res-bmp085atm.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Barometer resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_bmp085atm, + "title=\"atm status\";rt=\"atm\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern char bmp085atm_s[8]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", bmp085atm_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%s}", bmp085atm_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-weather/resources/res-bmp085press.c b/examples/osd/arduino-weather/resources/res-bmp085press.c new file mode 100644 index 000000000..6a02f4bf0 --- /dev/null +++ b/examples/osd/arduino-weather/resources/res-bmp085press.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Barometer resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_bmp085press, + "title=\"pressure status\";rt=\"pressure\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern char bmp085press_s[8]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", bmp085press_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'pressure':%s}", bmp085press_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-weather/resources/res-htu21dhum.c b/examples/osd/arduino-weather/resources/res-htu21dhum.c new file mode 100644 index 000000000..f66c71c74 --- /dev/null +++ b/examples/osd/arduino-weather/resources/res-htu21dhum.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Moisture resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_htu21dhum, + "title=\"Moisture status\";rt=\"Moisture\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern char htu21d_hum_s[8]; + + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", htu21d_hum_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'moisture':%s}", htu21d_hum_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-weather/resources/res-htu21dtemp.c b/examples/osd/arduino-weather/resources/res-htu21dtemp.c new file mode 100644 index 000000000..cdc9a9a7d --- /dev/null +++ b/examples/osd/arduino-weather/resources/res-htu21dtemp.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Moisture resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_htu21dtemp, + "title=\"Temperature status\";rt=\"Temperatur\"", + res_get_handler, + NULL, + NULL, + NULL); + +extern char htu21d_temp_s[8]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", htu21d_temp_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%s}", htu21d_temp_s); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} diff --git a/examples/osd/arduino-weather/run.sh b/examples/osd/arduino-weather/run.sh new file mode 100755 index 000000000..5d5cbbbb4 --- /dev/null +++ b/examples/osd/arduino-weather/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/arduino-weather/sketch.pde b/examples/osd/arduino-weather/sketch.pde new file mode 100644 index 000000000..e83fd2b8c --- /dev/null +++ b/examples/osd/arduino-weather/sketch.pde @@ -0,0 +1,128 @@ +/* + * Sample arduino sketch using contiki features. + * We turn the LED off + * We allow read the moisture sensor + * Unfortunately sleeping for long times in loop() isn't currently + * possible, something turns off the CPU (including PWM outputs) if a + * Proto-Thread is taking too long. We need to find out how to sleep in + * a Contiki-compatible way. + * Note that for a normal arduino sketch you won't have to include any + * of the contiki-specific files here, the sketch should just work. + */ + +#include +#include "Barometer.h" +#include "Adafruit_HTU21DF.h" +#include "BH1750FVI.h" + +extern "C" { +#include "arduino-process.h" +#include "rest-engine.h" + +extern resource_t res_bh1750, res_htu21dtemp, res_htu21dhum, res_bmp085press,res_bmp085atm,res_bmp085alt, res_battery; + +float bmp085temp; +float bmp085press; +float bmp085atm; +float bmp085alt; +char bmp085temp_s[8]; +char bmp085press_s[8]; +char bmp085atm_s[8]; +char bmp085alt_s[8]; + +Barometer myBarometer; + +float htu21d_hum; +float htu21d_temp; +char htu21d_hum_s[8]; +char htu21d_temp_s[8]; + +Adafruit_HTU21DF htu = Adafruit_HTU21DF(); + +uint16_t lux; + +BH1750FVI lightMeter; + +#define LED_PIN 4 +} + +void setup (void) +{ + // switch off the led + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, HIGH); + // BH1750 sensor + Wire.begin(); + lightMeter.begin(); + // BMP085 sensor + myBarometer.init(); + // htu21d sensor + if (!htu.begin()) { + printf("Couldn't find sensor htu21d !"); + } + // init coap resourcen + rest_init_engine (); + rest_activate_resource (&res_bmp085press, "s/press"); + rest_activate_resource (&res_bmp085atm, "s/atm"); + rest_activate_resource (&res_bmp085alt, "s/alt"); + rest_activate_resource (&res_htu21dtemp, "s/temp"); + rest_activate_resource (&res_htu21dhum, "s/hum"); + rest_activate_resource (&res_bh1750, "s/lux"); + rest_activate_resource (&res_battery, "s/battery"); +} + +// at project-conf.h +// LOOP_INTERVAL (10 * CLOCK_SECOND) +void loop (void) +{ + mcu_sleep_off(); + // BMP085 Sensor + bmp085temp = myBarometer.bmp085GetTemperature(myBarometer.bmp085ReadUT()); //Get the temperature, bmp085ReadUT MUST be called first + bmp085press = myBarometer.bmp085GetPressure(myBarometer.bmp085ReadUP());//Get the temperature + bmp085alt = myBarometer.calcAltitude(bmp085press); //Uncompensated caculation - in Meters + bmp085atm = bmp085press / 101325; + + dtostrf(bmp085temp , 6, 2, bmp085temp_s ); + dtostrf(bmp085press , 6, 2, bmp085press_s ); + dtostrf(bmp085alt , 6, 2, bmp085alt_s ); + dtostrf(bmp085atm , 6, 2, bmp085atm_s ); + // remove space + if(bmp085temp_s[0]==' '){ + memcpy (bmp085temp_s,bmp085temp_s+1,strlen(bmp085temp_s)+1); + } + if(bmp085press_s[0]==' '){ + memcpy (bmp085press_s,bmp085press_s+1,strlen(bmp085press_s)+1); + } + if(bmp085alt_s[0]==' '){ + memcpy (bmp085alt_s,bmp085alt_s+1,strlen(bmp085alt_s)+1); + } + if(bmp085atm_s[0]==' '){ + memcpy (bmp085atm_s,bmp085atm_s+1,strlen(bmp085atm_s)+1); + } + // HTU21d Sensor + htu21d_temp = htu.readTemperature(); + htu21d_hum = htu.readHumidity(); + dtostrf(htu21d_temp , 6, 2, htu21d_temp_s ); + dtostrf(htu21d_hum , 6, 2, htu21d_hum_s ); + // remove space + if(htu21d_temp_s[0]==' '){ + memcpy (htu21d_temp_s,htu21d_temp_s+1,strlen(htu21d_temp_s)+1); + } + if(htu21d_hum_s[0]==' '){ + memcpy (htu21d_hum_s,htu21d_hum_s+1,strlen(htu21d_hum_s)+1); + } + // BH1750 + lux = lightMeter.getLightLevel(); + +// Debug Print + printf("BMP085\n"); + printf("Press: %s\n",bmp085press_s); + printf("Altitude: %s\n",bmp085alt_s); + printf("atm: %s\n",bmp085atm_s); + printf("HTU21d\n"); + printf("Temp: %s\n",htu21d_temp_s); + printf("Hum: %s\n",htu21d_hum_s); + printf("BH1750\n"); + printf("Lux: %d\n",lux); + mcu_sleep_on(); +} diff --git a/examples/osd/climate/Makefile b/examples/osd/climate/Makefile index e12d01b5c..211ea0c1c 100644 --- a/examples/osd/climate/Makefile +++ b/examples/osd/climate/Makefile @@ -1,74 +1,33 @@ -all: er-example-server -# use this target explicitly if requried: er-plugtest-server - - -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 - - -# variable for Makefile.include -WITH_UIP6=1 -# for some platforms -UIP_CONF_IPV6=1 -# IPv6 make config disappeared completely -CFLAGS += -DUIP_CONF_IPV6 -CFLAGS += -DUIP_CONF_IPV6_RPL +EXE=er-example-server +all: $(EXE) CONTIKI=../../.. + +# Contiki IPv6 configuration +WITH_UIP6=1 +UIP_CONF_IPV6=1 +CFLAGS += -DUIP_CONF_IPV6=1 +CFLAGS += -DUIP_CONF_IPV6_RPL=1 + CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" -# variable for Makefile.include -ifneq ($(TARGET), minimal-net) -CFLAGS += -DUIP_CONF_IPV6_RPL=1 -else -# minimal-net does not support RPL under Linux and is mostly used to test CoAP only -${info INFO: compiling without RPL} -CFLAGS += -DUIP_CONF_IPV6_RPL=0 -CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" -${info INFO: compiling with large buffers} -CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048 -CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 -CFLAGS += -DCOAP_MAX_HEADER_SIZE=640 -endif +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) # linker optimizations SMALL=1 -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif - -APPS += erbium +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine # optional rules to get assembly #CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 @@ -76,6 +35,16 @@ APPS += erbium include $(CONTIKI)/Makefile.include +# minimal-net target is currently broken in Contiki +ifeq ($(TARGET), minimal-net) +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: er-example compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=1300 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=176 +CFLAGS += -DUIP_CONF_IPV6_RPL=0 +endif + # optional rules to get assembly #$(OBJECTDIR)/%.o: asmdir/%.S # $(CC) $(CFLAGS) -MMD -c $< -o $@ @@ -92,7 +61,17 @@ connect-router: $(CONTIKI)/tools/tunslip6 sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 connect-router-cooja: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 -p 60001 aaaa::1/64 + +connect-router-native: $(CONTIKI)/examples/ipv6/native-border-router/border-router.native + sudo $(CONTIKI)/exmples/ipv6/native-border-router/border-router.native -a 127.0.0.1 -p 60001 aaaa::1/64 connect-minimal: - sudo ip address add fdfd::1/64 dev tap0 + sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/climate/er-example-server.c b/examples/osd/climate/er-example-server.c index ee744ce68..f5c42c4b8 100644 --- a/examples/osd/climate/er-example-server.c +++ b/examples/osd/climate/er-example-server.c @@ -42,56 +42,7 @@ #include #include "contiki.h" #include "contiki-net.h" - - -/* Define which resources to include to meet memory constraints. */ -#define REST_RES_INFO 1 -#define REST_RES_DS1820 0 -#define REST_RES_DHT11 1 -#define REST_RES_DHT11TEMP 1 -#define REST_RES_LEDS 1 -#define REST_RES_TOGGLE 0 -#define REST_RES_BATTERY 1 - -#include "erbium.h" - -#if REST_RES_DS1820 -#include "dev/ds1820.h" -#endif -#if REST_RES_DHT11 -#include "dev/dht11.h" -uint16_t dht11_temp=0, dht11_hum=0; -#endif - -#if defined (PLATFORM_HAS_BUTTON) -#include "dev/button-sensor.h" -#endif -#if defined (PLATFORM_HAS_LEDS) -#include "dev/leds.h" -#endif -#if defined (PLATFORM_HAS_TEMPERATURE) -#include "dev/temperature-sensor.h" -#endif -#if defined (PLATFORM_HAS_BATTERY) -#include "dev/battery-sensor.h" -#endif -#if defined (PLATFORM_HAS_SHT11) -#include "dev/sht11-sensor.h" -#endif - - -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP == 3 -#include "er-coap-03.h" -#elif WITH_COAP == 7 -#include "er-coap-07.h" -#elif WITH_COAP == 12 -#include "er-coap-12.h" -#elif WITH_COAP == 13 -#include "er-coap-13.h" -#else -#warning "Erbium example without CoAP-specifc functionality" -#endif /* CoAP-specific example */ +#include "rest-engine.h" #define DEBUG 0 #if DEBUG @@ -104,282 +55,49 @@ uint16_t dht11_temp=0, dht11_hum=0; #define PRINTLLADDR(addr) #endif - -/******************************************************************************/ - -#if REST_RES_INFO /* - * Resources are defined by the RESOURCE macro. - * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). + * Resources to be activated need to be imported through the extern keyword. + * The build system automatically compiles the resources in the corresponding sub-directory. */ -RESOURCE(info, METHOD_GET, "info", "title=\"Info\";rt=\"text\""); - -/* - * A handler function named [resource name]_handler must be implemented for each RESOURCE. - * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore - * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. - * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. - */ -void -info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - char message[100]; - int index = 0; - int length = 0; /* |<-------->| */ - - /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ - // jSON Format - index += sprintf(message + index,"{\n \"version\" : \"V0.4.3\",\n"); - index += sprintf(message + index," \"name\" : \"6lowpan-climate\"\n"); - index += sprintf(message + index,"}\n"); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - REST.set_response_payload(response, buffer, length); -} + +#if defined (PLATFORM_HAS_INFO) +extern resource_t res_info; #endif -#if REST_RES_DS1820 -/* A simple getter example. Returns the reading from ds1820 sensor */ -#define DS1820_TEMP_LSB 0 -#define DS1820_TEMP_MSB 1 -#define DS1820_COUNT_REMAIN 6 -#define DS1820_COUNT_PER_C 7 -RESOURCE(ds1820, METHOD_GET, "s/temp", "title=\"Temperatur DS1820\";rt=\"temperature-c\""); -void -ds1820_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ +#if PLATFORM_HAS_DHT11 +uint16_t dht11_hum=0; +uint16_t dht11_temp=0; +#endif - char message[100]; - int length = 0; /* |<-------->| */ - union temp_raw { - int16_t s_int16; - uint16_t u_int16; - } temp_raw; - double temp_c; - int temp_integral; - int temp_centi; +#if PLATFORM_HAS_DHT11HUM +#include "dev/dht11.h" +extern resource_t res_dht11hum; +#endif - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); +#if PLATFORM_HAS_DHT11TEMP +#include "dev/dht11.h" +extern resource_t res_dht11temp; +#endif - // temp = temp_read - 0.25°C + (count_per_c - count_remain) / count_per_c; - temp_raw.u_int16 = ds1820_ok[DS1820_TEMP_MSB] << 8 | ds1820_ok[DS1820_TEMP_LSB]; - temp_c = temp_raw.s_int16 / 2.0 - - 0.25 - + ((double) ds1820_ok[DS1820_COUNT_PER_C] - (double) ds1820_ok[DS1820_COUNT_REMAIN]) - / (double) ds1820_ok[DS1820_COUNT_PER_C]; - temp_integral = (int) temp_c; - temp_centi = (int) (fabs (temp_c - (int) temp_c) * 100.0); +#if defined (PLATFORM_HAS_DS1820) +#include "dev/ds1820.h" +extern resource_t res_ds1820; +#endif - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf(message, REST_MAX_CHUNK_SIZE, "%d.%02d C", temp_integral, temp_centi); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_response_payload(response, buffer, length); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf(message, REST_MAX_CHUNK_SIZE, "{\"temp\":\"%d.%02d\"}", temp_integral, temp_centi); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_response_payload(response, buffer, length); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - REST.set_response_payload(response, (uint8_t *)"Supporting content-types text/plain and application/json", 56); - } -} -#endif //REST_RES_DS1820 - -#if REST_RES_DHT11TEMP -/*A simple getter example. Returns the reading from dhtxx sensor*/ -RESOURCE(dht11temp, METHOD_GET, "s/temp", "title=\"Temperatur DHTxx\";rt=\"temperature-c\""); -void -dht11temp_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - char message[100]; - int length = 0; /* |<-------->| */ - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf(message, REST_MAX_CHUNK_SIZE, "%d.%02d",dht11_temp/100, dht11_temp % 100); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_response_payload(response, buffer, length); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf(message, REST_MAX_CHUNK_SIZE, "{\"temp\":\"%d.%02d\"}",dht11_temp/100, dht11_temp % 100); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_response_payload(response, buffer, length); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - REST.set_response_payload(response, (uint8_t *)"Supporting content-types text/plain and application/json", 56); - } -} -#endif //REST_RES_DHT11TEMP - -#if REST_RES_DHT11 -/*A simple getter example. Returns the reading from dhtxx sensor*/ -RESOURCE(dht11, METHOD_GET, "s/hum", "title=\"Humidity DHTxx\";rt=\"humidity-%\""); -void -dht11_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - char message[100]; - int length = 0; /* |<-------->| */ - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf(message, REST_MAX_CHUNK_SIZE, "%d.%02d",dht11_hum/100, dht11_hum % 100); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_response_payload(response, buffer, length); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf(message, REST_MAX_CHUNK_SIZE, "{\"hum\":\"%d.%02d\"}",dht11_hum/100, dht11_hum % 100); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_response_payload(response, buffer, length); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - REST.set_response_payload(response, (uint8_t *)"Supporting content-types text/plain and application/json", 56); - } -} -#endif //REST_RES_DHT11 - -/******************************************************************************/ #if defined (PLATFORM_HAS_LEDS) -/******************************************************************************/ -#if REST_RES_LEDS -/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -RESOURCE(leds, METHOD_POST | METHOD_PUT , "a/leds", "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\""); - -void -leds_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - size_t len = 0; - const char *color = NULL; - const char *mode = NULL; - uint8_t led = 0; - int success = 1; - - if ((len=REST.get_query_variable(request, "color", &color))) { - PRINTF("color %.*s\n", len, color); - - if (strncmp(color, "r", len)==0) { - led = LEDS_RED; - } else if(strncmp(color,"g", len)==0) { - led = LEDS_GREEN; - } else if (strncmp(color,"b", len)==0) { - led = LEDS_BLUE; - } else { - success = 0; - } - } else { - success = 0; - } - - if (success && (len=REST.get_post_variable(request, "mode", &mode))) { - PRINTF("mode %s\n", mode); - - if (strncmp(mode, "on", len)==0) { - leds_on(led); - } else if (strncmp(mode, "off", len)==0) { - leds_off(led); - } else { - success = 0; - } - } else { - success = 0; - } - - if (!success) { - REST.set_response_status(response, REST.status.BAD_REQUEST); - } -} +#include "dev/leds.h" +extern resource_t res_leds; #endif -/******************************************************************************/ -#if REST_RES_TOGGLE -/* A simple actuator example. Toggles the red led */ -RESOURCE(toggle, METHOD_GET | METHOD_PUT | METHOD_POST, "a/toggle", "title=\"Red LED\";rt=\"Control\""); -void -toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - leds_toggle(LEDS_RED); -} +#if PLATFORM_HAS_BATTERY +#include "dev/battery-sensor.h" +extern resource_t res_battery; #endif -#endif /* PLATFORM_HAS_LEDS */ -/******************************************************************************/ -#if REST_RES_BATTERY && defined (PLATFORM_HAS_BATTERY) -/* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(battery, METHOD_GET, "s/battery", "title=\"Battery status\";rt=\"battery-mV\""); -void -battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int battery = battery_sensor.value(0); - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d.%02d", battery/1000, battery % 1000); - - REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'battery':%d.%02d}", battery/1000, battery % 1000); - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain and application/json"; - REST.set_response_payload(response, msg, strlen(msg)); - } -} -#endif /* PLATFORM_HAS_BATTERY */ +#if PLATFORM_HAS_RADIO +#include "dev/radio-sensor.h" +extern resource_t res_radio; +#endif void hw_init() @@ -387,13 +105,14 @@ hw_init() #if defined (PLATFORM_HAS_LEDS) leds_off(LEDS_RED); #endif -#if REST_RES_DS1820 +#if PLATFORM_HAS_DS1820 ds1820_temp(); #endif -#if REST_RES_DHT11 +#if PLATFORM_HAS_DHT11 //DHT_INIT(); DHT_Read_Data(&dht11_temp, &dht11_hum); #endif + NETSTACK_MAC.off(1); } #define MESURE_INTERVAL (20 * CLOCK_SECOND) #define READ_TIME ( 2 * CLOCK_SECOND) @@ -404,7 +123,7 @@ AUTOSTART_PROCESSES(&rest_server_example); PROCESS_THREAD(rest_server_example, ev, data) { static struct etimer ds_periodic_timer; -#if REST_RES_DS1820 +#if PLATFORM_HAS_DS1820 static struct etimer ds_read_timer; #endif @@ -437,33 +156,28 @@ PROCESS_THREAD(rest_server_example, ev, data) rest_init_engine(); /* Activate the application-specific resources. */ -#if REST_RES_DS1820 - rest_activate_resource(&resource_ds1820); +#if PLATFORM_HAS_DS1820 + rest_activate_resource(&res_ds1820,"s/temp"); #endif -#if REST_RES_DHT11 - rest_activate_resource(&resource_dht11); +#if PLATFORM_HAS_DHT11HUM + rest_activate_resource(&res_dht11hum,"s/hum"); #endif -#if REST_RES_DHT11TEMP - rest_activate_resource(&resource_dht11temp); +#if PLATFORM_HAS_DHT11TEMP + rest_activate_resource(&res_dht11temp,"s/temp"); #endif -#if REST_RES_INFO - rest_activate_resource(&resource_info); -#endif -#if defined (PLATFORM_HAS_LEDS) -#if REST_RES_LEDS - rest_activate_resource(&resource_leds); -#endif -#if REST_RES_TOGGLE - rest_activate_resource(&resource_toggle); +#if PLATFORM_HAS_INFO + rest_activate_resource(&res_info,"info"); #endif +#if PLATFORM_HAS_LEDS + rest_activate_resource(&res_leds,"a/leds"); #endif /* PLATFORM_HAS_LEDS */ -#if defined (PLATFORM_HAS_TEMPERATURE) && REST_RES_TEMPERATURE +#if PLATFORM_HAS_TEMPERATURE SENSORS_ACTIVATE(temperature_sensor); rest_activate_resource(&resource_temperature); #endif -#if defined (PLATFORM_HAS_BATTERY) && REST_RES_BATTERY +#if PLATFORM_HAS_BATTERY SENSORS_ACTIVATE(battery_sensor); - rest_activate_resource(&resource_battery); + rest_activate_resource(&res_battery,"s/battery"); #endif /* Define application-specific events here. */ @@ -478,17 +192,17 @@ PROCESS_THREAD(rest_server_example, ev, data) if(etimer_expired(&ds_periodic_timer)) { PRINTF("Periodic\n"); etimer_reset(&ds_periodic_timer); -#if REST_RES_DHT11 +#if PLATFORM_HAS_DHT11 // DHT_Read_Data(&dht11_temp, &dht11_hum); DHT_Read_Data(&dht11_temp, &dht11_hum); #endif -#if REST_RES_DS1820 +#if PLATFORM_HAS_DS1820 if(ds1820_convert()){ etimer_set(&ds_read_timer, READ_TIME); } #endif } -#if REST_RES_DS1820 +#if PLATFORM_HAS_DS1820 if(etimer_expired(&ds_read_timer)) { PRINTF("DS1820_Read\n"); ds1820_read(); diff --git a/examples/osd/climate/er-example-server.osd-merkur.eep b/examples/osd/climate/er-example-server.osd-merkur.eep deleted file mode 100644 index 1996e8fde..000000000 --- a/examples/osd/climate/er-example-server.osd-merkur.eep +++ /dev/null @@ -1 +0,0 @@ -:00000001FF diff --git a/examples/osd/climate/flash.sh b/examples/osd/climate/flash.sh index e92d472f6..e82962073 100755 --- a/examples/osd/climate/flash.sh +++ b/examples/osd/climate/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-server.osd-merkur.hex:a -U eeprom:w:er-example-server.osd-merkur.eep:a +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/climate/lall.txt b/examples/osd/climate/lall.txt deleted file mode 100644 index af5ccaf63..000000000 --- a/examples/osd/climate/lall.txt +++ /dev/null @@ -1,132 +0,0 @@ -INFO: compiling with CoAP-08 -rm -f *~ *core core *.srec \ - *.lst *.map \ - *.cprg *.bin *.data contiki*.a *.firmware core-labels.S *.ihex *.ini \ - *.ce *.co -rm -rf obj_osd-merkur -INFO: compiling with CoAP-08 -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rime/rimeaddr.c -o obj_osd-merkur/rimeaddr.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rime/timesynch.c -o obj_osd-merkur/timesynch.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rime/rimestats.c -o obj_osd-merkur/rimestats.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/cxmac.c -o obj_osd-merkur/cxmac.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/xmac.c -o obj_osd-merkur/xmac.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/nullmac.c -o obj_osd-merkur/nullmac.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/lpp.c -o obj_osd-merkur/lpp.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/frame802154.c -o obj_osd-merkur/frame802154.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/sicslowmac.c -o obj_osd-merkur/sicslowmac.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/nullrdc.c -o obj_osd-merkur/nullrdc.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/nullrdc-noframer.c -o obj_osd-merkur/nullrdc-noframer.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/mac.c -o obj_osd-merkur/mac.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/framer-nullmac.c -o obj_osd-merkur/framer-nullmac.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/framer-802154.c -o obj_osd-merkur/framer-802154.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/csma.c -o obj_osd-merkur/csma.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/contikimac.c -o obj_osd-merkur/contikimac.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/phase.c -o obj_osd-merkur/phase.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rpl/rpl.c -o obj_osd-merkur/rpl.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rpl/rpl-dag.c -o obj_osd-merkur/rpl-dag.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rpl/rpl-icmp6.c -o obj_osd-merkur/rpl-icmp6.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rpl/rpl-timers.c -o obj_osd-merkur/rpl-timers.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rpl/rpl-of-etx.c -o obj_osd-merkur/rpl-of-etx.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rpl/rpl-ext-header.c -o obj_osd-merkur/rpl-ext-header.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/process.c -o obj_osd-merkur/process.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/procinit.c -o obj_osd-merkur/procinit.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/autostart.c -o obj_osd-merkur/autostart.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/loader/elfloader.c -o obj_osd-merkur/elfloader.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/profile.c -o obj_osd-merkur/profile.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/timetable.c -o obj_osd-merkur/timetable.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/timetable-aggregate.c -o obj_osd-merkur/timetable-aggregate.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/compower.c -o obj_osd-merkur/compower.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/dev/serial-line.c -o obj_osd-merkur/serial-line.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/memb.c -o obj_osd-merkur/memb.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/mmem.c -o obj_osd-merkur/mmem.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/timer.c -o obj_osd-merkur/timer.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/list.c -o obj_osd-merkur/list.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/etimer.c -o obj_osd-merkur/etimer.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/ctimer.c -o obj_osd-merkur/ctimer.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/energest.c -o obj_osd-merkur/energest.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/rtimer.c -o obj_osd-merkur/rtimer.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/stimer.c -o obj_osd-merkur/stimer.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/print-stats.c -o obj_osd-merkur/print-stats.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/ifft.c -o obj_osd-merkur/ifft.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/crc16.c -o obj_osd-merkur/crc16.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/random.c -o obj_osd-merkur/random.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/checkpoint.c -o obj_osd-merkur/checkpoint.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/ringbuf.c -o obj_osd-merkur/ringbuf.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/netstack.c -o obj_osd-merkur/netstack.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip-debug.c -o obj_osd-merkur/uip-debug.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/packetbuf.c -o obj_osd-merkur/packetbuf.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/queuebuf.c -o obj_osd-merkur/queuebuf.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/packetqueue.c -o obj_osd-merkur/packetqueue.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip6.c -o obj_osd-merkur/uip6.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/tcpip.c -o obj_osd-merkur/tcpip.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/psock.c -o obj_osd-merkur/psock.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip-udp-packet.c -o obj_osd-merkur/uip-udp-packet.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip-split.c -o obj_osd-merkur/uip-split.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/resolv.c -o obj_osd-merkur/resolv.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/tcpdump.c -o obj_osd-merkur/tcpdump.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uiplib.c -o obj_osd-merkur/uiplib.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/simple-udp.c -o obj_osd-merkur/simple-udp.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip-icmp6.c -o obj_osd-merkur/uip-icmp6.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip-nd6.c -o obj_osd-merkur/uip-nd6.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip-packetqueue.c -o obj_osd-merkur/uip-packetqueue.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/sicslowpan.c -o obj_osd-merkur/sicslowpan.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/neighbor-attr.c -o obj_osd-merkur/neighbor-attr.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/neighbor-info.c -o obj_osd-merkur/neighbor-info.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip-ds6.c -o obj_osd-merkur/uip-ds6.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip-ds6-route.c -o obj_osd-merkur/uip-ds6-route.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/mt.c -o obj_osd-merkur/mt.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/dev/nullradio.c -o obj_osd-merkur/nullradio.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../apps/er-coap-07/er-coap-07-engine.c -o obj_osd-merkur/er-coap-07-engine.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../apps/er-coap-07/er-coap-07.c -o obj_osd-merkur/er-coap-07.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../apps/er-coap-07/er-coap-07-transactions.c -o obj_osd-merkur/er-coap-07-transactions.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../apps/er-coap-07/er-coap-07-observing.c -o obj_osd-merkur/er-coap-07-observing.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../apps/er-coap-07/er-coap-07-separate.c -o obj_osd-merkur/er-coap-07-separate.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../apps/erbium/erbium.c -o obj_osd-merkur/erbium.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/./contiki-main.c -o obj_osd-merkur/contiki-main.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/./params.c -o obj_osd-merkur/params.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/./node-id.c -o obj_osd-merkur/node-id.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/temperature-sensor.c -o obj_osd-merkur/temperature-sensor.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/adc.c -o obj_osd-merkur/adc.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/led.c -o obj_osd-merkur/led.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/sensors.c -o obj_osd-merkur/sensors.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/./slip_uart0.c -o obj_osd-merkur/slip_uart0.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/dev/slip.c -o obj_osd-merkur/slip.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/button-sensor.c -o obj_osd-merkur/button-sensor.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/dht11.c -o obj_osd-merkur/dht11.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/ds1820.c -o obj_osd-merkur/ds1820.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/battery-sensor.c -o obj_osd-merkur/battery-sensor.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/pir-sensor.c -o obj_osd-merkur/pir-sensor.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/dev/clock.c -o obj_osd-merkur/clock.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/./mtarch.c -o obj_osd-merkur/mtarch.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/dev/eeprom.c -o obj_osd-merkur/eeprom.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/dev/flash.c -o obj_osd-merkur/flash.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/dev/rs232.c -o obj_osd-merkur/rs232.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/leds-arch.c -o obj_osd-merkur/leds-arch.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/./watchdog.c -o obj_osd-merkur/watchdog.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/./rtimer-arch.c -o obj_osd-merkur/rtimer-arch.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/./bootloader.c -o obj_osd-merkur/bootloader.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/./settings.c -o obj_osd-merkur/settings.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/loader/elfloader-avr.c -o obj_osd-merkur/elfloader-avr.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/loader/symtab-avr.c -o obj_osd-merkur/symtab-avr.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/dev/leds.c -o obj_osd-merkur/leds.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/radio/rf230bb/rf230bb.c -o obj_osd-merkur/rf230bb.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/radio/rf230bb/halbb.c -o obj_osd-merkur/halbb.o -avr-ar rcf contiki-osd-merkur.a obj_osd-merkur/rimeaddr.o obj_osd-merkur/timesynch.o obj_osd-merkur/rimestats.o obj_osd-merkur/cxmac.o obj_osd-merkur/xmac.o obj_osd-merkur/nullmac.o obj_osd-merkur/lpp.o obj_osd-merkur/frame802154.o obj_osd-merkur/sicslowmac.o obj_osd-merkur/nullrdc.o obj_osd-merkur/nullrdc-noframer.o obj_osd-merkur/mac.o obj_osd-merkur/framer-nullmac.o obj_osd-merkur/framer-802154.o obj_osd-merkur/csma.o obj_osd-merkur/contikimac.o obj_osd-merkur/phase.o obj_osd-merkur/rpl.o obj_osd-merkur/rpl-dag.o obj_osd-merkur/rpl-icmp6.o obj_osd-merkur/rpl-timers.o obj_osd-merkur/rpl-of-etx.o obj_osd-merkur/rpl-ext-header.o obj_osd-merkur/process.o obj_osd-merkur/procinit.o obj_osd-merkur/autostart.o obj_osd-merkur/elfloader.o obj_osd-merkur/profile.o obj_osd-merkur/timetable.o obj_osd-merkur/timetable-aggregate.o obj_osd-merkur/compower.o obj_osd-merkur/serial-line.o obj_osd-merkur/memb.o obj_osd-merkur/mmem.o obj_osd-merkur/timer.o obj_osd-merkur/list.o obj_osd-merkur/etimer.o obj_osd-merkur/ctimer.o obj_osd-merkur/energest.o obj_osd-merkur/rtimer.o obj_osd-merkur/stimer.o obj_osd-merkur/print-stats.o obj_osd-merkur/ifft.o obj_osd-merkur/crc16.o obj_osd-merkur/random.o obj_osd-merkur/checkpoint.o obj_osd-merkur/ringbuf.o obj_osd-merkur/netstack.o obj_osd-merkur/uip-debug.o obj_osd-merkur/packetbuf.o obj_osd-merkur/queuebuf.o obj_osd-merkur/packetqueue.o obj_osd-merkur/uip6.o obj_osd-merkur/tcpip.o obj_osd-merkur/psock.o obj_osd-merkur/uip-udp-packet.o obj_osd-merkur/uip-split.o obj_osd-merkur/resolv.o obj_osd-merkur/tcpdump.o obj_osd-merkur/uiplib.o obj_osd-merkur/simple-udp.o obj_osd-merkur/uip-icmp6.o obj_osd-merkur/uip-nd6.o obj_osd-merkur/uip-packetqueue.o obj_osd-merkur/sicslowpan.o obj_osd-merkur/neighbor-attr.o obj_osd-merkur/neighbor-info.o obj_osd-merkur/uip-ds6.o obj_osd-merkur/uip-ds6-route.o obj_osd-merkur/mt.o obj_osd-merkur/nullradio.o obj_osd-merkur/er-coap-07-engine.o obj_osd-merkur/er-coap-07.o obj_osd-merkur/er-coap-07-transactions.o obj_osd-merkur/er-coap-07-observing.o obj_osd-merkur/er-coap-07-separate.o obj_osd-merkur/erbium.o obj_osd-merkur/contiki-main.o obj_osd-merkur/params.o obj_osd-merkur/node-id.o obj_osd-merkur/temperature-sensor.o obj_osd-merkur/adc.o obj_osd-merkur/led.o obj_osd-merkur/sensors.o obj_osd-merkur/slip_uart0.o obj_osd-merkur/slip.o obj_osd-merkur/button-sensor.o obj_osd-merkur/dht11.o obj_osd-merkur/ds1820.o obj_osd-merkur/battery-sensor.o obj_osd-merkur/pir-sensor.o obj_osd-merkur/clock.o obj_osd-merkur/mtarch.o obj_osd-merkur/eeprom.o obj_osd-merkur/flash.o obj_osd-merkur/rs232.o obj_osd-merkur/leds-arch.o obj_osd-merkur/watchdog.o obj_osd-merkur/rtimer-arch.o obj_osd-merkur/bootloader.o obj_osd-merkur/settings.o obj_osd-merkur/elfloader-avr.o obj_osd-merkur/symtab-avr.o obj_osd-merkur/leds.o obj_osd-merkur/rf230bb.o obj_osd-merkur/halbb.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -DAUTOSTART_ENABLE -c er-example-server.c -o er-example-server.co -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c static-routing.c -o obj_osd-merkur/static-routing.o -avr-gcc -mmcu=atmega128rfa1 -Wl,-Map=contiki-osd-merkur.map -Wl,--section-start=.bootloader=0x1F000 er-example-server.co obj_osd-merkur/static-routing.o contiki-osd-merkur.a -o er-example-server.osd-merkur -rm obj_osd-merkur/static-routing.o er-example-server.co -AVR Memory Usage ----------------- -Device: Unknown - -Program: 73000 bytes -(.text + .data + .bootloader) - -Data: 12592 bytes -(.data + .bss + .noinit) - -EEPROM: 41 bytes -(.eeprom) - - diff --git a/examples/osd/climate/project-conf.h b/examples/osd/climate/project-conf.h index ba521f078..a7a502f08 100644 --- a/examples/osd/climate/project-conf.h +++ b/examples/osd/climate/project-conf.h @@ -32,9 +32,13 @@ #ifndef PROJECT_ERBIUM_CONF_H_ #define PROJECT_ERBIUM_CONF_H_ +#define DHT11 1 +#define PLATFORM_HAS_DHT11 1 +#define PLATFORM_HAS_INFO 1 #define PLATFORM_HAS_BATTERY 1 -//#define PLATFORM_HAS_DS1820 1 -#define PLATFORM_HAS_DHT11 1 +#define PLATFORM_HAS_DS1820 1 +#define PLATFORM_HAS_DHT11HUM 1 +//#define PLATFORM_HAS_DHT11TEMP 1 #define PLATFORM_HAS_LEDS 1 diff --git a/examples/osd/climate/resources/res-dht11hum.c b/examples/osd/climate/resources/res-dht11hum.c new file mode 100644 index 000000000..392456203 --- /dev/null +++ b/examples/osd/climate/resources/res-dht11hum.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, OSDomotics, Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * dht11hum Sensor Resource + * + * This is a simple GET resource that returns the humidity in % rel. + * + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#if PLATFORM_HAS_DHT11HUM + +#include +#include +#include +#include +#include +#include "rest-engine.h" +#include "dev/dht11.h" + +/*A simple getter example. Returns the reading from dhtxx sensor*/ +static void res_get_dht11hum_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_dht11hum, + "title=\"Humidity DHTxx\";rt=\"humidity %\"", + res_get_dht11hum_handler, + NULL, + NULL, + NULL); + +extern uint16_t dht11_hum; + +static void +res_get_dht11hum_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + char message[100]; + int length = 0; /* |<-------->| */ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) + { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf(message, REST_MAX_CHUNK_SIZE, "%d.%02d",dht11_hum/100, dht11_hum % 100); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_response_payload(response, buffer, length); + } + else if (accept == REST.type.APPLICATION_JSON) + { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf(message, REST_MAX_CHUNK_SIZE, "{\"hum\":\"%d.%02d\"}",dht11_hum/100, dht11_hum % 100); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_response_payload(response, buffer, length); + } + else + { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, (uint8_t *)"Supporting content-types text/plain and application/json", 56); + } +} +#endif /* PLATFORM_HAS_DS1820 */ diff --git a/examples/osd/climate/resources/res-dht11temp.c b/examples/osd/climate/resources/res-dht11temp.c new file mode 100644 index 000000000..3f55de8d9 --- /dev/null +++ b/examples/osd/climate/resources/res-dht11temp.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2014, OSDomotics, Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * DHT11temp Sensor Resource + * + * This is a simple GET resource that returns the temperature in Celsius + * + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#if PLATFORM_HAS_DHT11TEMP + +#include +#include +#include +#include +#include +#include "rest-engine.h" +#include "dev/dht11.h" + +/*A simple getter example. Returns the reading from dhtxx sensor*/ +//RESOURCE(dht11temp, METHOD_GET, "s/temp", "title=\"Temperatur DHTxx\";rt=\"temperature-c\""); + +static void res_get_dht11temp_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from light sensor with a simple etag */ +RESOURCE(res_dht11temp, + "title=\"Temperature DHTxx\";rt=\"temperature c\"", + res_get_dht11temp_handler, + NULL, + NULL, + NULL); + +extern uint16_t dht11_temp; + +static void +res_get_dht11temp_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + char message[100]; + int length = 0; /* |<-------->| */ + + const uint16_t *accept = NULL; + int num = REST.get_header_accept(request, &accept); + + if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) + { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf(message, REST_MAX_CHUNK_SIZE, "%d.%02d",dht11_temp/100, dht11_temp % 100); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_response_payload(response, buffer, length); + } + else if (num && (accept[0]==REST.type.APPLICATION_JSON)) + { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf(message, REST_MAX_CHUNK_SIZE, "{\"temp\":\"%d.%02d\"}",dht11_temp/100, dht11_temp % 100); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_response_payload(response, buffer, length); + } + else + { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, (uint8_t *)"Supporting content-types text/plain and application/json", 56); + } +} +#endif /* PLATFORM_HAS_DS1820 */ diff --git a/examples/osd/climate/resources/res-ds1820.c b/examples/osd/climate/resources/res-ds1820.c new file mode 100644 index 000000000..4d059bb5f --- /dev/null +++ b/examples/osd/climate/resources/res-ds1820.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2014, OSDomotics, Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * DS1820 Sensor Resource + * + * This is a simple GET resource that returns the temperature in Celsius + * + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#if PLATFORM_HAS_DS1820 + +#include +#include +#include +#include +#include +#include "rest-engine.h" +#include "dev/ds1820.h" + +/* A simple getter example. Returns the reading from ds1820 sensor */ +#define DS1820_TEMP_LSB 0 +#define DS1820_TEMP_MSB 1 +#define DS1820_COUNT_REMAIN 6 +#define DS1820_COUNT_PER_C 7 + +//RESOURCE(ds1820, METHOD_GET, "s/temp", "title=\"Temperatur DS1820\";rt=\"temperature-c\""); +static void res_get_ds1820_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from light sensor with a simple etag */ +RESOURCE(res_ds1820, + "title=\"Temperature DHTxx\";rt=\"temperature c\"", + res_get_ds1820_handler, + NULL, + NULL, + NULL); + +static void +res_get_ds1820_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + char message[100]; + int length = 0; /* |<-------->| */ + union temp_raw { + int16_t s_int16; + uint16_t u_int16; + } temp_raw; + double temp_c; + int temp_integral; + int temp_centi; + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + // temp = temp_read - 0.25°C + (count_per_c - count_remain) / count_per_c; + temp_raw.u_int16 = ds1820_ok[DS1820_TEMP_MSB] << 8 | ds1820_ok[DS1820_TEMP_LSB]; + temp_c = temp_raw.s_int16 / 2.0 + - 0.25 + + ((double) ds1820_ok[DS1820_COUNT_PER_C] - (double) ds1820_ok[DS1820_COUNT_REMAIN]) + / (double) ds1820_ok[DS1820_COUNT_PER_C]; + temp_integral = (int) temp_c; + temp_centi = (int) (fabs (temp_c - (int) temp_c) * 100.0); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) + { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf(message, REST_MAX_CHUNK_SIZE, "%d.%02d C", temp_integral, temp_centi); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_response_payload(response, buffer, length); + } + else if (accept == REST.type.APPLICATION_JSON) + { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf(message, REST_MAX_CHUNK_SIZE, "{\"temp\":\"%d.%02d\"}", temp_integral, temp_centi); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_response_payload(response, buffer, length); + } + else + { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, (uint8_t *)"Supporting content-types text/plain and application/json", 56); + } +} +#endif /* PLATFORM_HAS_DS1820 */ diff --git a/examples/osd/climate/resources/res-info.c b/examples/osd/climate/resources/res-info.c new file mode 100644 index 000000000..8d3232ead --- /dev/null +++ b/examples/osd/climate/resources/res-info.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, OSDomotics, Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Info Resource + * + * This is a simple GET resource that returns Information + * + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#if PLATFORM_HAS_INFO + +#include +#include +#include +#include "rest-engine.h" + +static void res_get_info_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from light sensor with a simple etag */ +RESOURCE(res_info, + "title=\"Info\";rt=\"text\"", + res_get_info_handler, + NULL, + NULL, + NULL); +/* + * A handler function named [resource name]_handler must be implemented for each RESOURCE. + * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore + * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. + * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. + */ +static void +res_get_info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + char message[100]; + int index = 0; + int length = 0; /* |<-------->| */ + + /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ + // jSON Format + index += sprintf(message + index,"{\n \"version\" : \"V0.4.3\",\n"); + index += sprintf(message + index," \"name\" : \"6lowpan-climate\"\n"); + index += sprintf(message + index,"}\n"); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + REST.set_response_payload(response, buffer, length); +} +#endif /* PLATFORM_HAS_INFO */ diff --git a/examples/osd/climate/run.sh b/examples/osd/climate/run.sh index 2efd2cf48..5d5cbbbb4 100755 --- a/examples/osd/climate/run.sh +++ b/examples/osd/climate/run.sh @@ -1,8 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size -C --mcu=MCU=atmega128rfa1 er-example-server.osd-merkur -avr-objcopy -j .text -j .data -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.eep +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/climate/server-client.csc b/examples/osd/climate/server-client.csc deleted file mode 100644 index 8c45fdf02..000000000 --- a/examples/osd/climate/server-client.csc +++ /dev/null @@ -1,227 +0,0 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - client - Erbium Client - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c - make er-example-client.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 46.57186415376375 - 40.35946215910942 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - - se.sics.cooja.interfaces.Position - 18.638049428485125 - 47.55034515769599 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 3 - - client - - - - se.sics.cooja.plugins.SimControl - 259 - 0 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 - - 300 - 2 - 178 - 261 - 1 - - - se.sics.cooja.plugins.LogListener - - - - - 762 - 3 - 491 - 2 - 182 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 4 - 74 - 578 - 18 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - 2 - - - - - 125 - 25.49079397896416 - - 1624 - 5 - 252 - 6 - 712 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 2 - - Serial port - 0,0 - - 853 - 1 - 491 - 765 - 182 - - - diff --git a/examples/osd/climate/server-only.csc b/examples/osd/climate/server-only.csc index d5eee34d6..1b0fe28bf 100644 --- a/examples/osd/climate/server-only.csc +++ b/examples/osd/climate/server-only.csc @@ -1,189 +1,189 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 35.100895239785295 - 39.70574552287428 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - se.sics.cooja.plugins.SimControl - 259 - 5 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 - - 300 - 4 - 175 - 263 - 3 - - - se.sics.cooja.plugins.LogListener - - - - - 560 - 1 - 326 - 1 - 293 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 2 - 74 - 39 - 199 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - - - - - 125 - 25.49079397896416 - - 1624 - 3 - 252 - 4 - 622 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 1 - - Serial port - 0,0 - - 702 - 0 - 646 - 564 - 2 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + REST with RPL router + -2147483648 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + se.sics.cooja.interfaces.Position + 35.100895239785295 + 39.70574552287428 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + se.sics.cooja.plugins.SimControl + 259 + 5 + 179 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.AttributeVisualizerSkin + se.sics.cooja.plugins.skins.LEDVisualizerSkin + se.sics.cooja.plugins.skins.AddressVisualizerSkin + 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 + + 300 + 4 + 175 + 263 + 3 + + + se.sics.cooja.plugins.LogListener + + + + + 560 + 1 + 326 + 1 + 293 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 2 + 74 + 39 + 199 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + + + + + 125 + 25.49079397896416 + + 1624 + 3 + 252 + 4 + 622 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 702 + 0 + 646 + 564 + 2 + + + diff --git a/examples/osd/climate2/Makefile b/examples/osd/climate2/Makefile index e12d01b5c..ee3981b6a 100644 --- a/examples/osd/climate2/Makefile +++ b/examples/osd/climate2/Makefile @@ -1,74 +1,35 @@ -all: er-example-server -# use this target explicitly if requried: er-plugtest-server +EXE=er-example-server - -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 - - -# variable for Makefile.include -WITH_UIP6=1 -# for some platforms -UIP_CONF_IPV6=1 -# IPv6 make config disappeared completely -CFLAGS += -DUIP_CONF_IPV6 -CFLAGS += -DUIP_CONF_IPV6_RPL +all: $(EXE) +# use target "er-plugtest-server" explicitly when requried CONTIKI=../../.. + +# Contiki IPv6 configuration +WITH_UIP6=1 +UIP_CONF_IPV6=1 +CFLAGS += -DUIP_CONF_IPV6=1 +CFLAGS += -DUIP_CONF_IPV6_RPL=1 + CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" -# variable for Makefile.include -ifneq ($(TARGET), minimal-net) -CFLAGS += -DUIP_CONF_IPV6_RPL=1 -else -# minimal-net does not support RPL under Linux and is mostly used to test CoAP only -${info INFO: compiling without RPL} -CFLAGS += -DUIP_CONF_IPV6_RPL=0 -CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" -${info INFO: compiling with large buffers} -CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048 -CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 -CFLAGS += -DCOAP_MAX_HEADER_SIZE=640 -endif +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) # linker optimizations SMALL=1 -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif - -APPS += erbium +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine # optional rules to get assembly #CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 @@ -76,6 +37,16 @@ APPS += erbium include $(CONTIKI)/Makefile.include +# minimal-net target is currently broken in Contiki +ifeq ($(TARGET), minimal-net) +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: er-example compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=1300 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=176 +CFLAGS += -DUIP_CONF_IPV6_RPL=0 +endif + # optional rules to get assembly #$(OBJECTDIR)/%.o: asmdir/%.S # $(CC) $(CFLAGS) -MMD -c $< -o $@ @@ -92,7 +63,17 @@ connect-router: $(CONTIKI)/tools/tunslip6 sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 connect-router-cooja: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 -p 60001 aaaa::1/64 + +connect-router-native: $(CONTIKI)/examples/ipv6/native-border-router/border-router.native + sudo $(CONTIKI)/exmples/ipv6/native-border-router/border-router.native -a 127.0.0.1 -p 60001 aaaa::1/64 connect-minimal: - sudo ip address add fdfd::1/64 dev tap0 + sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/climate2/er-example-server.c b/examples/osd/climate2/er-example-server.c index ee744ce68..c3342c9e3 100644 --- a/examples/osd/climate2/er-example-server.c +++ b/examples/osd/climate2/er-example-server.c @@ -42,56 +42,7 @@ #include #include "contiki.h" #include "contiki-net.h" - - -/* Define which resources to include to meet memory constraints. */ -#define REST_RES_INFO 1 -#define REST_RES_DS1820 0 -#define REST_RES_DHT11 1 -#define REST_RES_DHT11TEMP 1 -#define REST_RES_LEDS 1 -#define REST_RES_TOGGLE 0 -#define REST_RES_BATTERY 1 - -#include "erbium.h" - -#if REST_RES_DS1820 -#include "dev/ds1820.h" -#endif -#if REST_RES_DHT11 -#include "dev/dht11.h" -uint16_t dht11_temp=0, dht11_hum=0; -#endif - -#if defined (PLATFORM_HAS_BUTTON) -#include "dev/button-sensor.h" -#endif -#if defined (PLATFORM_HAS_LEDS) -#include "dev/leds.h" -#endif -#if defined (PLATFORM_HAS_TEMPERATURE) -#include "dev/temperature-sensor.h" -#endif -#if defined (PLATFORM_HAS_BATTERY) -#include "dev/battery-sensor.h" -#endif -#if defined (PLATFORM_HAS_SHT11) -#include "dev/sht11-sensor.h" -#endif - - -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP == 3 -#include "er-coap-03.h" -#elif WITH_COAP == 7 -#include "er-coap-07.h" -#elif WITH_COAP == 12 -#include "er-coap-12.h" -#elif WITH_COAP == 13 -#include "er-coap-13.h" -#else -#warning "Erbium example without CoAP-specifc functionality" -#endif /* CoAP-specific example */ +#include "rest-engine.h" #define DEBUG 0 #if DEBUG @@ -104,282 +55,46 @@ uint16_t dht11_temp=0, dht11_hum=0; #define PRINTLLADDR(addr) #endif - -/******************************************************************************/ - -#if REST_RES_INFO /* - * Resources are defined by the RESOURCE macro. - * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). + * Resources to be activated need to be imported through the extern keyword. + * The build system automatically compiles the resources in the corresponding sub-directory. */ -RESOURCE(info, METHOD_GET, "info", "title=\"Info\";rt=\"text\""); - -/* - * A handler function named [resource name]_handler must be implemented for each RESOURCE. - * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore - * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. - * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. - */ -void -info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - char message[100]; - int index = 0; - int length = 0; /* |<-------->| */ - - /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ - // jSON Format - index += sprintf(message + index,"{\n \"version\" : \"V0.4.3\",\n"); - index += sprintf(message + index," \"name\" : \"6lowpan-climate\"\n"); - index += sprintf(message + index,"}\n"); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - REST.set_response_payload(response, buffer, length); -} + +#if defined (PLATFORM_HAS_INFO) +extern resource_t res_info; #endif -#if REST_RES_DS1820 -/* A simple getter example. Returns the reading from ds1820 sensor */ -#define DS1820_TEMP_LSB 0 -#define DS1820_TEMP_MSB 1 -#define DS1820_COUNT_REMAIN 6 -#define DS1820_COUNT_PER_C 7 -RESOURCE(ds1820, METHOD_GET, "s/temp", "title=\"Temperatur DS1820\";rt=\"temperature-c\""); -void -ds1820_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ +#if PLATFORM_HAS_DHT11HUM +#include "dev/dht11.h" +extern resource_t res_dht11hum; +extern uint16_t dht11_hum; +#endif - char message[100]; - int length = 0; /* |<-------->| */ - union temp_raw { - int16_t s_int16; - uint16_t u_int16; - } temp_raw; - double temp_c; - int temp_integral; - int temp_centi; +#if PLATFORM_HAS_DHT11TEMP +#include "dev/dht11.h" +extern resource_t res_dht11temp; +extern uint16_t dht11_temp; +#endif - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); +#if defined (PLATFORM_HAS_DS1820) +#include "dev/ds1820.h" +extern resource_t res_ds1820; +#endif - // temp = temp_read - 0.25°C + (count_per_c - count_remain) / count_per_c; - temp_raw.u_int16 = ds1820_ok[DS1820_TEMP_MSB] << 8 | ds1820_ok[DS1820_TEMP_LSB]; - temp_c = temp_raw.s_int16 / 2.0 - - 0.25 - + ((double) ds1820_ok[DS1820_COUNT_PER_C] - (double) ds1820_ok[DS1820_COUNT_REMAIN]) - / (double) ds1820_ok[DS1820_COUNT_PER_C]; - temp_integral = (int) temp_c; - temp_centi = (int) (fabs (temp_c - (int) temp_c) * 100.0); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf(message, REST_MAX_CHUNK_SIZE, "%d.%02d C", temp_integral, temp_centi); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_response_payload(response, buffer, length); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf(message, REST_MAX_CHUNK_SIZE, "{\"temp\":\"%d.%02d\"}", temp_integral, temp_centi); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_response_payload(response, buffer, length); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - REST.set_response_payload(response, (uint8_t *)"Supporting content-types text/plain and application/json", 56); - } -} -#endif //REST_RES_DS1820 - -#if REST_RES_DHT11TEMP -/*A simple getter example. Returns the reading from dhtxx sensor*/ -RESOURCE(dht11temp, METHOD_GET, "s/temp", "title=\"Temperatur DHTxx\";rt=\"temperature-c\""); -void -dht11temp_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - char message[100]; - int length = 0; /* |<-------->| */ - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf(message, REST_MAX_CHUNK_SIZE, "%d.%02d",dht11_temp/100, dht11_temp % 100); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_response_payload(response, buffer, length); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf(message, REST_MAX_CHUNK_SIZE, "{\"temp\":\"%d.%02d\"}",dht11_temp/100, dht11_temp % 100); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_response_payload(response, buffer, length); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - REST.set_response_payload(response, (uint8_t *)"Supporting content-types text/plain and application/json", 56); - } -} -#endif //REST_RES_DHT11TEMP - -#if REST_RES_DHT11 -/*A simple getter example. Returns the reading from dhtxx sensor*/ -RESOURCE(dht11, METHOD_GET, "s/hum", "title=\"Humidity DHTxx\";rt=\"humidity-%\""); -void -dht11_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - char message[100]; - int length = 0; /* |<-------->| */ - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf(message, REST_MAX_CHUNK_SIZE, "%d.%02d",dht11_hum/100, dht11_hum % 100); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_response_payload(response, buffer, length); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf(message, REST_MAX_CHUNK_SIZE, "{\"hum\":\"%d.%02d\"}",dht11_hum/100, dht11_hum % 100); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_response_payload(response, buffer, length); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - REST.set_response_payload(response, (uint8_t *)"Supporting content-types text/plain and application/json", 56); - } -} -#endif //REST_RES_DHT11 - -/******************************************************************************/ #if defined (PLATFORM_HAS_LEDS) -/******************************************************************************/ -#if REST_RES_LEDS -/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -RESOURCE(leds, METHOD_POST | METHOD_PUT , "a/leds", "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\""); - -void -leds_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - size_t len = 0; - const char *color = NULL; - const char *mode = NULL; - uint8_t led = 0; - int success = 1; - - if ((len=REST.get_query_variable(request, "color", &color))) { - PRINTF("color %.*s\n", len, color); - - if (strncmp(color, "r", len)==0) { - led = LEDS_RED; - } else if(strncmp(color,"g", len)==0) { - led = LEDS_GREEN; - } else if (strncmp(color,"b", len)==0) { - led = LEDS_BLUE; - } else { - success = 0; - } - } else { - success = 0; - } - - if (success && (len=REST.get_post_variable(request, "mode", &mode))) { - PRINTF("mode %s\n", mode); - - if (strncmp(mode, "on", len)==0) { - leds_on(led); - } else if (strncmp(mode, "off", len)==0) { - leds_off(led); - } else { - success = 0; - } - } else { - success = 0; - } - - if (!success) { - REST.set_response_status(response, REST.status.BAD_REQUEST); - } -} +#include "dev/leds.h" +extern resource_t res_leds; #endif -/******************************************************************************/ -#if REST_RES_TOGGLE -/* A simple actuator example. Toggles the red led */ -RESOURCE(toggle, METHOD_GET | METHOD_PUT | METHOD_POST, "a/toggle", "title=\"Red LED\";rt=\"Control\""); -void -toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - leds_toggle(LEDS_RED); -} +#if PLATFORM_HAS_BATTERY +#include "dev/battery-sensor.h" +extern resource_t res_battery; #endif -#endif /* PLATFORM_HAS_LEDS */ -/******************************************************************************/ -#if REST_RES_BATTERY && defined (PLATFORM_HAS_BATTERY) -/* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(battery, METHOD_GET, "s/battery", "title=\"Battery status\";rt=\"battery-mV\""); -void -battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int battery = battery_sensor.value(0); - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d.%02d", battery/1000, battery % 1000); - - REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'battery':%d.%02d}", battery/1000, battery % 1000); - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain and application/json"; - REST.set_response_payload(response, msg, strlen(msg)); - } -} -#endif /* PLATFORM_HAS_BATTERY */ +#if PLATFORM_HAS_RADIO +#include "dev/radio-sensor.h" +extern resource_t res_radio; +#endif void hw_init() @@ -387,11 +102,10 @@ hw_init() #if defined (PLATFORM_HAS_LEDS) leds_off(LEDS_RED); #endif -#if REST_RES_DS1820 +#if PLATFORM_HAS_DS1820 ds1820_temp(); #endif -#if REST_RES_DHT11 - //DHT_INIT(); +#if PLATFORM_HAS_DHT11HUM DHT_Read_Data(&dht11_temp, &dht11_hum); #endif } @@ -404,7 +118,7 @@ AUTOSTART_PROCESSES(&rest_server_example); PROCESS_THREAD(rest_server_example, ev, data) { static struct etimer ds_periodic_timer; -#if REST_RES_DS1820 +#if PLATFORM_HAS_DS1820 static struct etimer ds_read_timer; #endif @@ -437,33 +151,28 @@ PROCESS_THREAD(rest_server_example, ev, data) rest_init_engine(); /* Activate the application-specific resources. */ -#if REST_RES_DS1820 - rest_activate_resource(&resource_ds1820); +#if PLATFORM_HAS_DS1820 + rest_activate_resource(&res_ds1820,"s/temp"); #endif -#if REST_RES_DHT11 - rest_activate_resource(&resource_dht11); +#if PLATFORM_HAS_DHT11HUM + rest_activate_resource(&res_dht11hum,"s/hum"); #endif -#if REST_RES_DHT11TEMP - rest_activate_resource(&resource_dht11temp); +#if PLATFORM_HAS_DHT11TEMP + rest_activate_resource(&res_dht11temp,"s/temp"); #endif -#if REST_RES_INFO - rest_activate_resource(&resource_info); -#endif -#if defined (PLATFORM_HAS_LEDS) -#if REST_RES_LEDS - rest_activate_resource(&resource_leds); -#endif -#if REST_RES_TOGGLE - rest_activate_resource(&resource_toggle); +#if PLATFORM_HAS_INFO + rest_activate_resource(&res_info,"info"); #endif +#if PLATFORM_HAS_LEDS + rest_activate_resource(&res_leds,"a/leds"); #endif /* PLATFORM_HAS_LEDS */ -#if defined (PLATFORM_HAS_TEMPERATURE) && REST_RES_TEMPERATURE +#if PLATFORM_HAS_TEMPERATURE SENSORS_ACTIVATE(temperature_sensor); rest_activate_resource(&resource_temperature); #endif -#if defined (PLATFORM_HAS_BATTERY) && REST_RES_BATTERY +#if PLATFORM_HAS_BATTERY SENSORS_ACTIVATE(battery_sensor); - rest_activate_resource(&resource_battery); + rest_activate_resource(&res_battery,"s/battery"); #endif /* Define application-specific events here. */ @@ -478,17 +187,16 @@ PROCESS_THREAD(rest_server_example, ev, data) if(etimer_expired(&ds_periodic_timer)) { PRINTF("Periodic\n"); etimer_reset(&ds_periodic_timer); -#if REST_RES_DHT11 - // DHT_Read_Data(&dht11_temp, &dht11_hum); +#if PLATFORM_HAS_DHT11HUM DHT_Read_Data(&dht11_temp, &dht11_hum); #endif -#if REST_RES_DS1820 +#if PLATFORM_HAS_DS1820 if(ds1820_convert()){ etimer_set(&ds_read_timer, READ_TIME); } #endif } -#if REST_RES_DS1820 +#if PLATFORM_HAS_DS1820 if(etimer_expired(&ds_read_timer)) { PRINTF("DS1820_Read\n"); ds1820_read(); diff --git a/examples/osd/climate2/flash.sh b/examples/osd/climate2/flash.sh index e92d472f6..e82962073 100755 --- a/examples/osd/climate2/flash.sh +++ b/examples/osd/climate2/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-server.osd-merkur.hex:a -U eeprom:w:er-example-server.osd-merkur.eep:a +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/climate2/lall.txt b/examples/osd/climate2/lall.txt deleted file mode 100644 index af5ccaf63..000000000 --- a/examples/osd/climate2/lall.txt +++ /dev/null @@ -1,132 +0,0 @@ -INFO: compiling with CoAP-08 -rm -f *~ *core core *.srec \ - *.lst *.map \ - *.cprg *.bin *.data contiki*.a *.firmware core-labels.S *.ihex *.ini \ - *.ce *.co -rm -rf obj_osd-merkur -INFO: compiling with CoAP-08 -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rime/rimeaddr.c -o obj_osd-merkur/rimeaddr.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rime/timesynch.c -o obj_osd-merkur/timesynch.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rime/rimestats.c -o obj_osd-merkur/rimestats.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/cxmac.c -o obj_osd-merkur/cxmac.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/xmac.c -o obj_osd-merkur/xmac.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/nullmac.c -o obj_osd-merkur/nullmac.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/lpp.c -o obj_osd-merkur/lpp.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/frame802154.c -o obj_osd-merkur/frame802154.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/sicslowmac.c -o obj_osd-merkur/sicslowmac.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/nullrdc.c -o obj_osd-merkur/nullrdc.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/nullrdc-noframer.c -o obj_osd-merkur/nullrdc-noframer.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/mac.c -o obj_osd-merkur/mac.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/framer-nullmac.c -o obj_osd-merkur/framer-nullmac.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/framer-802154.c -o obj_osd-merkur/framer-802154.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/csma.c -o obj_osd-merkur/csma.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/contikimac.c -o obj_osd-merkur/contikimac.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/mac/phase.c -o obj_osd-merkur/phase.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rpl/rpl.c -o obj_osd-merkur/rpl.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rpl/rpl-dag.c -o obj_osd-merkur/rpl-dag.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rpl/rpl-icmp6.c -o obj_osd-merkur/rpl-icmp6.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rpl/rpl-timers.c -o obj_osd-merkur/rpl-timers.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rpl/rpl-of-etx.c -o obj_osd-merkur/rpl-of-etx.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/rpl/rpl-ext-header.c -o obj_osd-merkur/rpl-ext-header.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/process.c -o obj_osd-merkur/process.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/procinit.c -o obj_osd-merkur/procinit.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/autostart.c -o obj_osd-merkur/autostart.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/loader/elfloader.c -o obj_osd-merkur/elfloader.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/profile.c -o obj_osd-merkur/profile.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/timetable.c -o obj_osd-merkur/timetable.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/timetable-aggregate.c -o obj_osd-merkur/timetable-aggregate.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/compower.c -o obj_osd-merkur/compower.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/dev/serial-line.c -o obj_osd-merkur/serial-line.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/memb.c -o obj_osd-merkur/memb.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/mmem.c -o obj_osd-merkur/mmem.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/timer.c -o obj_osd-merkur/timer.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/list.c -o obj_osd-merkur/list.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/etimer.c -o obj_osd-merkur/etimer.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/ctimer.c -o obj_osd-merkur/ctimer.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/energest.c -o obj_osd-merkur/energest.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/rtimer.c -o obj_osd-merkur/rtimer.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/stimer.c -o obj_osd-merkur/stimer.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/print-stats.c -o obj_osd-merkur/print-stats.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/ifft.c -o obj_osd-merkur/ifft.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/crc16.c -o obj_osd-merkur/crc16.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/random.c -o obj_osd-merkur/random.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/checkpoint.c -o obj_osd-merkur/checkpoint.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/ringbuf.c -o obj_osd-merkur/ringbuf.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/netstack.c -o obj_osd-merkur/netstack.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip-debug.c -o obj_osd-merkur/uip-debug.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/packetbuf.c -o obj_osd-merkur/packetbuf.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/queuebuf.c -o obj_osd-merkur/queuebuf.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/packetqueue.c -o obj_osd-merkur/packetqueue.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip6.c -o obj_osd-merkur/uip6.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/tcpip.c -o obj_osd-merkur/tcpip.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/psock.c -o obj_osd-merkur/psock.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip-udp-packet.c -o obj_osd-merkur/uip-udp-packet.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip-split.c -o obj_osd-merkur/uip-split.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/resolv.c -o obj_osd-merkur/resolv.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/tcpdump.c -o obj_osd-merkur/tcpdump.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uiplib.c -o obj_osd-merkur/uiplib.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/simple-udp.c -o obj_osd-merkur/simple-udp.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip-icmp6.c -o obj_osd-merkur/uip-icmp6.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip-nd6.c -o obj_osd-merkur/uip-nd6.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip-packetqueue.c -o obj_osd-merkur/uip-packetqueue.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/sicslowpan.c -o obj_osd-merkur/sicslowpan.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/neighbor-attr.c -o obj_osd-merkur/neighbor-attr.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/neighbor-info.c -o obj_osd-merkur/neighbor-info.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip-ds6.c -o obj_osd-merkur/uip-ds6.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/net/uip-ds6-route.c -o obj_osd-merkur/uip-ds6-route.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/sys/mt.c -o obj_osd-merkur/mt.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/dev/nullradio.c -o obj_osd-merkur/nullradio.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../apps/er-coap-07/er-coap-07-engine.c -o obj_osd-merkur/er-coap-07-engine.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../apps/er-coap-07/er-coap-07.c -o obj_osd-merkur/er-coap-07.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../apps/er-coap-07/er-coap-07-transactions.c -o obj_osd-merkur/er-coap-07-transactions.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../apps/er-coap-07/er-coap-07-observing.c -o obj_osd-merkur/er-coap-07-observing.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../apps/er-coap-07/er-coap-07-separate.c -o obj_osd-merkur/er-coap-07-separate.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../apps/erbium/erbium.c -o obj_osd-merkur/erbium.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/./contiki-main.c -o obj_osd-merkur/contiki-main.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/./params.c -o obj_osd-merkur/params.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/./node-id.c -o obj_osd-merkur/node-id.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/temperature-sensor.c -o obj_osd-merkur/temperature-sensor.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/adc.c -o obj_osd-merkur/adc.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/led.c -o obj_osd-merkur/led.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/lib/sensors.c -o obj_osd-merkur/sensors.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/./slip_uart0.c -o obj_osd-merkur/slip_uart0.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/dev/slip.c -o obj_osd-merkur/slip.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/button-sensor.c -o obj_osd-merkur/button-sensor.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/dht11.c -o obj_osd-merkur/dht11.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/ds1820.c -o obj_osd-merkur/ds1820.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/battery-sensor.c -o obj_osd-merkur/battery-sensor.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/pir-sensor.c -o obj_osd-merkur/pir-sensor.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/dev/clock.c -o obj_osd-merkur/clock.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/./mtarch.c -o obj_osd-merkur/mtarch.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/dev/eeprom.c -o obj_osd-merkur/eeprom.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/dev/flash.c -o obj_osd-merkur/flash.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/dev/rs232.c -o obj_osd-merkur/rs232.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../platform/osd-merkur/dev/leds-arch.c -o obj_osd-merkur/leds-arch.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/./watchdog.c -o obj_osd-merkur/watchdog.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/./rtimer-arch.c -o obj_osd-merkur/rtimer-arch.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/./bootloader.c -o obj_osd-merkur/bootloader.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/./settings.c -o obj_osd-merkur/settings.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/loader/elfloader-avr.c -o obj_osd-merkur/elfloader-avr.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/loader/symtab-avr.c -o obj_osd-merkur/symtab-avr.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../core/dev/leds.c -o obj_osd-merkur/leds.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/radio/rf230bb/rf230bb.c -o obj_osd-merkur/rf230bb.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c ../../../cpu/avr/radio/rf230bb/halbb.c -o obj_osd-merkur/halbb.o -avr-ar rcf contiki-osd-merkur.a obj_osd-merkur/rimeaddr.o obj_osd-merkur/timesynch.o obj_osd-merkur/rimestats.o obj_osd-merkur/cxmac.o obj_osd-merkur/xmac.o obj_osd-merkur/nullmac.o obj_osd-merkur/lpp.o obj_osd-merkur/frame802154.o obj_osd-merkur/sicslowmac.o obj_osd-merkur/nullrdc.o obj_osd-merkur/nullrdc-noframer.o obj_osd-merkur/mac.o obj_osd-merkur/framer-nullmac.o obj_osd-merkur/framer-802154.o obj_osd-merkur/csma.o obj_osd-merkur/contikimac.o obj_osd-merkur/phase.o obj_osd-merkur/rpl.o obj_osd-merkur/rpl-dag.o obj_osd-merkur/rpl-icmp6.o obj_osd-merkur/rpl-timers.o obj_osd-merkur/rpl-of-etx.o obj_osd-merkur/rpl-ext-header.o obj_osd-merkur/process.o obj_osd-merkur/procinit.o obj_osd-merkur/autostart.o obj_osd-merkur/elfloader.o obj_osd-merkur/profile.o obj_osd-merkur/timetable.o obj_osd-merkur/timetable-aggregate.o obj_osd-merkur/compower.o obj_osd-merkur/serial-line.o obj_osd-merkur/memb.o obj_osd-merkur/mmem.o obj_osd-merkur/timer.o obj_osd-merkur/list.o obj_osd-merkur/etimer.o obj_osd-merkur/ctimer.o obj_osd-merkur/energest.o obj_osd-merkur/rtimer.o obj_osd-merkur/stimer.o obj_osd-merkur/print-stats.o obj_osd-merkur/ifft.o obj_osd-merkur/crc16.o obj_osd-merkur/random.o obj_osd-merkur/checkpoint.o obj_osd-merkur/ringbuf.o obj_osd-merkur/netstack.o obj_osd-merkur/uip-debug.o obj_osd-merkur/packetbuf.o obj_osd-merkur/queuebuf.o obj_osd-merkur/packetqueue.o obj_osd-merkur/uip6.o obj_osd-merkur/tcpip.o obj_osd-merkur/psock.o obj_osd-merkur/uip-udp-packet.o obj_osd-merkur/uip-split.o obj_osd-merkur/resolv.o obj_osd-merkur/tcpdump.o obj_osd-merkur/uiplib.o obj_osd-merkur/simple-udp.o obj_osd-merkur/uip-icmp6.o obj_osd-merkur/uip-nd6.o obj_osd-merkur/uip-packetqueue.o obj_osd-merkur/sicslowpan.o obj_osd-merkur/neighbor-attr.o obj_osd-merkur/neighbor-info.o obj_osd-merkur/uip-ds6.o obj_osd-merkur/uip-ds6-route.o obj_osd-merkur/mt.o obj_osd-merkur/nullradio.o obj_osd-merkur/er-coap-07-engine.o obj_osd-merkur/er-coap-07.o obj_osd-merkur/er-coap-07-transactions.o obj_osd-merkur/er-coap-07-observing.o obj_osd-merkur/er-coap-07-separate.o obj_osd-merkur/erbium.o obj_osd-merkur/contiki-main.o obj_osd-merkur/params.o obj_osd-merkur/node-id.o obj_osd-merkur/temperature-sensor.o obj_osd-merkur/adc.o obj_osd-merkur/led.o obj_osd-merkur/sensors.o obj_osd-merkur/slip_uart0.o obj_osd-merkur/slip.o obj_osd-merkur/button-sensor.o obj_osd-merkur/dht11.o obj_osd-merkur/ds1820.o obj_osd-merkur/battery-sensor.o obj_osd-merkur/pir-sensor.o obj_osd-merkur/clock.o obj_osd-merkur/mtarch.o obj_osd-merkur/eeprom.o obj_osd-merkur/flash.o obj_osd-merkur/rs232.o obj_osd-merkur/leds-arch.o obj_osd-merkur/watchdog.o obj_osd-merkur/rtimer-arch.o obj_osd-merkur/bootloader.o obj_osd-merkur/settings.o obj_osd-merkur/elfloader-avr.o obj_osd-merkur/symtab-avr.o obj_osd-merkur/leds.o obj_osd-merkur/rf230bb.o obj_osd-merkur/halbb.o -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -DAUTOSTART_ENABLE -c er-example-server.c -o er-example-server.co -avr-gcc -DPROJECT_CONF_H=\"project-conf.h\" -DWITH_COAP=7 -DREST=coap_rest_implementation -DUIP_CONF_TCP=0 -DCONTIKI=1 -DCONTIKI_TARGET_OSD_MERKUR=1 -DUIP_CONF_IPV6=1 -DUIP_CONF_IPV6_RPL=1 -Wall -mmcu=atmega128rfa1 -gdwarf-2 -fno-strict-aliasing -I../../../platform/osd-merkur -I. -I../../../core -I../../../cpu/avr -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -Os -DRF230BB -I. -I../../../platform/osd-merkur/. -I../../../platform/osd-merkur/dev -I../../../platform/osd-merkur/apps -I../../../platform/osd-merkur/net -I../../../platform/osd-merkur/loader -I../../../cpu/avr/. -I../../../cpu/avr/dev -I../../../cpu/avr/radio/rf230bb -I../../../core/dev -I../../../core/lib -I../../../core/net -I../../../core/net/mac -I../../../core/net/rime -I../../../core/net/rpl -I../../../core/sys -I../../../core/cfs -I../../../core/ctk -I../../../core/lib/ctk -I../../../core/loader -I../../../core/. -I../../../apps/er-coap-07 -I../../../apps/erbium -I../../../platform/osd-merkur/ -DCONTIKI_VERSION_STRING=\"Contiki-2.6-335-gbbd7649\" -MMD -c static-routing.c -o obj_osd-merkur/static-routing.o -avr-gcc -mmcu=atmega128rfa1 -Wl,-Map=contiki-osd-merkur.map -Wl,--section-start=.bootloader=0x1F000 er-example-server.co obj_osd-merkur/static-routing.o contiki-osd-merkur.a -o er-example-server.osd-merkur -rm obj_osd-merkur/static-routing.o er-example-server.co -AVR Memory Usage ----------------- -Device: Unknown - -Program: 73000 bytes -(.text + .data + .bootloader) - -Data: 12592 bytes -(.data + .bss + .noinit) - -EEPROM: 41 bytes -(.eeprom) - - diff --git a/examples/osd/climate2/project-conf.h b/examples/osd/climate2/project-conf.h index ba521f078..11c9b1dd4 100644 --- a/examples/osd/climate2/project-conf.h +++ b/examples/osd/climate2/project-conf.h @@ -32,15 +32,21 @@ #ifndef PROJECT_ERBIUM_CONF_H_ #define PROJECT_ERBIUM_CONF_H_ +#define PLATFORM_HAS_INFO 1 #define PLATFORM_HAS_BATTERY 1 //#define PLATFORM_HAS_DS1820 1 -#define PLATFORM_HAS_DHT11 1 +#define PLATFORM_HAS_DHT11HUM 1 +#define PLATFORM_HAS_DHT11TEMP 1 #define PLATFORM_HAS_LEDS 1 /* Some platforms have weird includes. */ #undef IEEE802154_CONF_PANID + +/* Save energy */ +#define RDC_CONF_PT_YIELD_OFF + /* Disabling RDC for demo purposes. Core updates often require more memory. */ /* For projects, optimize memory and enable RDC again. */ // #undef NETSTACK_CONF_RDC diff --git a/examples/osd/climate2/resources/res-dht11hum.c b/examples/osd/climate2/resources/res-dht11hum.c new file mode 100644 index 000000000..6ba5de2f8 --- /dev/null +++ b/examples/osd/climate2/resources/res-dht11hum.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, OSDomotics, Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * dht11hum Sensor Resource + * + * This is a simple GET resource that returns the humidity in % rel. + * + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#if PLATFORM_HAS_DHT11HUM + +#include +#include +#include +#include +#include +#include "rest-engine.h" +#include "dev/dht11.h" + +/*A simple getter example. Returns the reading from dhtxx sensor*/ +static void res_get_dht11hum_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_dht11hum, + "title=\"Humidity DHTxx\";rt=\"humidity %\"", + res_get_dht11hum_handler, + NULL, + NULL, + NULL); + +uint16_t dht11_hum=0; + +static void +res_get_dht11hum_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + char message[100]; + int length = 0; /* |<-------->| */ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) + { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf(message, REST_MAX_CHUNK_SIZE, "%d.%02d",dht11_hum/100, dht11_hum % 100); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_response_payload(response, buffer, length); + } + else if (accept == REST.type.APPLICATION_JSON) + { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf(message, REST_MAX_CHUNK_SIZE, "{\"hum\":\"%d.%02d\"}",dht11_hum/100, dht11_hum % 100); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_response_payload(response, buffer, length); + } + else + { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, (uint8_t *)"Supporting content-types text/plain and application/json", 56); + } +} +#endif /* PLATFORM_HAS_DHT11HUM */ diff --git a/examples/osd/climate2/resources/res-dht11temp.c b/examples/osd/climate2/resources/res-dht11temp.c new file mode 100644 index 000000000..187e4a11f --- /dev/null +++ b/examples/osd/climate2/resources/res-dht11temp.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, OSDomotics, Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * DHT11temp Sensor Resource + * + * This is a simple GET resource that returns the temperature in Celsius + * + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#if PLATFORM_HAS_DHT11TEMP + +#include +#include +#include +#include +#include +#include "rest-engine.h" +#include "dev/dht11.h" + +/*A simple getter example. Returns the reading from dhtxx sensor*/ +//RESOURCE(dht11temp, METHOD_GET, "s/temp", "title=\"Temperatur DHTxx\";rt=\"temperature-c\""); + +static void res_get_dht11temp_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from light sensor with a simple etag */ +RESOURCE(res_dht11temp, + "title=\"Temperature DHTxx\";rt=\"temperature c\"", + res_get_dht11temp_handler, + NULL, + NULL, + NULL); + +uint16_t dht11_temp=0; + +static void +res_get_dht11temp_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + char message[100]; + int length = 0; /* |<-------->| */ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN){ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf(message, REST_MAX_CHUNK_SIZE, "%d.%02d",dht11_temp/100, dht11_temp % 100); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_response_payload(response, buffer, length); + } + else if (accept == REST.type.APPLICATION_JSON) + { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf(message, REST_MAX_CHUNK_SIZE, "{\"temp\":\"%d.%02d\"}",dht11_temp/100, dht11_temp % 100); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_response_payload(response, buffer, length); + } + else + { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, (uint8_t *)"Supporting content-types text/plain and application/json", 56); + } +} +#endif /* PLATFORM_HAS_DS1820 */ diff --git a/examples/osd/climate2/resources/res-ds1820.c b/examples/osd/climate2/resources/res-ds1820.c new file mode 100644 index 000000000..4d059bb5f --- /dev/null +++ b/examples/osd/climate2/resources/res-ds1820.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2014, OSDomotics, Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * DS1820 Sensor Resource + * + * This is a simple GET resource that returns the temperature in Celsius + * + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#if PLATFORM_HAS_DS1820 + +#include +#include +#include +#include +#include +#include "rest-engine.h" +#include "dev/ds1820.h" + +/* A simple getter example. Returns the reading from ds1820 sensor */ +#define DS1820_TEMP_LSB 0 +#define DS1820_TEMP_MSB 1 +#define DS1820_COUNT_REMAIN 6 +#define DS1820_COUNT_PER_C 7 + +//RESOURCE(ds1820, METHOD_GET, "s/temp", "title=\"Temperatur DS1820\";rt=\"temperature-c\""); +static void res_get_ds1820_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from light sensor with a simple etag */ +RESOURCE(res_ds1820, + "title=\"Temperature DHTxx\";rt=\"temperature c\"", + res_get_ds1820_handler, + NULL, + NULL, + NULL); + +static void +res_get_ds1820_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + char message[100]; + int length = 0; /* |<-------->| */ + union temp_raw { + int16_t s_int16; + uint16_t u_int16; + } temp_raw; + double temp_c; + int temp_integral; + int temp_centi; + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + // temp = temp_read - 0.25°C + (count_per_c - count_remain) / count_per_c; + temp_raw.u_int16 = ds1820_ok[DS1820_TEMP_MSB] << 8 | ds1820_ok[DS1820_TEMP_LSB]; + temp_c = temp_raw.s_int16 / 2.0 + - 0.25 + + ((double) ds1820_ok[DS1820_COUNT_PER_C] - (double) ds1820_ok[DS1820_COUNT_REMAIN]) + / (double) ds1820_ok[DS1820_COUNT_PER_C]; + temp_integral = (int) temp_c; + temp_centi = (int) (fabs (temp_c - (int) temp_c) * 100.0); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) + { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf(message, REST_MAX_CHUNK_SIZE, "%d.%02d C", temp_integral, temp_centi); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_response_payload(response, buffer, length); + } + else if (accept == REST.type.APPLICATION_JSON) + { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf(message, REST_MAX_CHUNK_SIZE, "{\"temp\":\"%d.%02d\"}", temp_integral, temp_centi); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_response_payload(response, buffer, length); + } + else + { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, (uint8_t *)"Supporting content-types text/plain and application/json", 56); + } +} +#endif /* PLATFORM_HAS_DS1820 */ diff --git a/examples/osd/climate2/resources/res-info.c b/examples/osd/climate2/resources/res-info.c new file mode 100644 index 000000000..55a780772 --- /dev/null +++ b/examples/osd/climate2/resources/res-info.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, OSDomotics, Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Info Resource + * + * This is a simple GET resource that returns Information + * + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#if PLATFORM_HAS_INFO + +#include +#include +#include +#include "rest-engine.h" + +static void res_get_info_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from light sensor with a simple etag */ +RESOURCE(res_info, + "title=\"Info\";rt=\"text\"", + res_get_info_handler, + NULL, + NULL, + NULL); +/* + * A handler function named [resource name]_handler must be implemented for each RESOURCE. + * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore + * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. + * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. + */ +static void +res_get_info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + char message[100]; + int index = 0; + int length = 0; /* |<-------->| */ + + /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ + // jSON Format + index += sprintf(message + index,"{\n \"version\" : \"V0.5.0\",\n"); + index += sprintf(message + index," \"name\" : \"6lowpan-climate2\"\n"); + index += sprintf(message + index,"}\n"); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + REST.set_response_payload(response, buffer, length); +} +#endif /* PLATFORM_HAS_INFO */ diff --git a/examples/osd/climate2/run.sh b/examples/osd/climate2/run.sh index 2efd2cf48..5d5cbbbb4 100755 --- a/examples/osd/climate2/run.sh +++ b/examples/osd/climate2/run.sh @@ -1,8 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size -C --mcu=MCU=atmega128rfa1 er-example-server.osd-merkur -avr-objcopy -j .text -j .data -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.eep +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/climate2/server-client.csc b/examples/osd/climate2/server-client.csc deleted file mode 100644 index 8c45fdf02..000000000 --- a/examples/osd/climate2/server-client.csc +++ /dev/null @@ -1,227 +0,0 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - client - Erbium Client - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c - make er-example-client.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 46.57186415376375 - 40.35946215910942 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - - se.sics.cooja.interfaces.Position - 18.638049428485125 - 47.55034515769599 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 3 - - client - - - - se.sics.cooja.plugins.SimControl - 259 - 0 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 - - 300 - 2 - 178 - 261 - 1 - - - se.sics.cooja.plugins.LogListener - - - - - 762 - 3 - 491 - 2 - 182 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 4 - 74 - 578 - 18 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - 2 - - - - - 125 - 25.49079397896416 - - 1624 - 5 - 252 - 6 - 712 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 2 - - Serial port - 0,0 - - 853 - 1 - 491 - 765 - 182 - - - diff --git a/examples/osd/climate2/server-only.csc b/examples/osd/climate2/server-only.csc index d5eee34d6..1b0fe28bf 100644 --- a/examples/osd/climate2/server-only.csc +++ b/examples/osd/climate2/server-only.csc @@ -1,189 +1,189 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 35.100895239785295 - 39.70574552287428 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - se.sics.cooja.plugins.SimControl - 259 - 5 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 - - 300 - 4 - 175 - 263 - 3 - - - se.sics.cooja.plugins.LogListener - - - - - 560 - 1 - 326 - 1 - 293 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 2 - 74 - 39 - 199 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - - - - - 125 - 25.49079397896416 - - 1624 - 3 - 252 - 4 - 622 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 1 - - Serial port - 0,0 - - 702 - 0 - 646 - 564 - 2 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + REST with RPL router + -2147483648 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + se.sics.cooja.interfaces.Position + 35.100895239785295 + 39.70574552287428 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + se.sics.cooja.plugins.SimControl + 259 + 5 + 179 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.AttributeVisualizerSkin + se.sics.cooja.plugins.skins.LEDVisualizerSkin + se.sics.cooja.plugins.skins.AddressVisualizerSkin + 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 + + 300 + 4 + 175 + 263 + 3 + + + se.sics.cooja.plugins.LogListener + + + + + 560 + 1 + 326 + 1 + 293 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 2 + 74 + 39 + 199 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + + + + + 125 + 25.49079397896416 + + 1624 + 3 + 252 + 4 + 622 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 702 + 0 + 646 + 564 + 2 + + + diff --git a/examples/osd/dual-rgbw-actor/Makefile b/examples/osd/dual-rgbw-actor/Makefile index 1305e71b9..d0e207dcf 100644 --- a/examples/osd/dual-rgbw-actor/Makefile +++ b/examples/osd/dual-rgbw-actor/Makefile @@ -1,5 +1,6 @@ -all: er-example-server -# use this target explicitly if requried: er-plugtest-server +EXE=er-example-server + +all: $(EXE) # variable for this Makefile # configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) @@ -91,3 +92,10 @@ connect-router-cooja: $(CONTIKI)/tools/tunslip6 connect-minimal: sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/dual-rgbw-actor/flash.sh b/examples/osd/dual-rgbw-actor/flash.sh index b91668634..e82962073 100755 --- a/examples/osd/dual-rgbw-actor/flash.sh +++ b/examples/osd/dual-rgbw-actor/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-server.osd-merkur.hex:a -U eeprom:w:er-example-server.osd-merkur.eep:a +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/dual-rgbw-actor/run.sh b/examples/osd/dual-rgbw-actor/run.sh index c65c87c3a..7b3a1dc9f 100755 --- a/examples/osd/dual-rgbw-actor/run.sh +++ b/examples/osd/dual-rgbw-actor/run.sh @@ -1,8 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -#make clean TARGET=osd-merkur -make -j TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -#avr-size -C --mcu=MCU=atmega128rfa1 er-example-server.osd-merkur -avr-objcopy -j .text -j .data -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.eep +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make -j TARGET=osd-merkur-128 diff --git a/examples/osd/dual-rgbw-actor/server-client.csc b/examples/osd/dual-rgbw-actor/server-client.csc index 8c45fdf02..02aefd730 100644 --- a/examples/osd/dual-rgbw-actor/server-client.csc +++ b/examples/osd/dual-rgbw-actor/server-client.csc @@ -1,227 +1,227 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - client - Erbium Client - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c - make er-example-client.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 46.57186415376375 - 40.35946215910942 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - - se.sics.cooja.interfaces.Position - 18.638049428485125 - 47.55034515769599 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 3 - - client - - - - se.sics.cooja.plugins.SimControl - 259 - 0 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 - - 300 - 2 - 178 - 261 - 1 - - - se.sics.cooja.plugins.LogListener - - - - - 762 - 3 - 491 - 2 - 182 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 4 - 74 - 578 - 18 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - 2 - - - - - 125 - 25.49079397896416 - - 1624 - 5 - 252 - 6 - 712 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 2 - - Serial port - 0,0 - - 853 - 1 - 491 - 765 - 182 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + REST with RPL router + -2147483648 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + client + Erbium Client + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c + make er-example-client.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + se.sics.cooja.interfaces.Position + 46.57186415376375 + 40.35946215910942 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + + se.sics.cooja.interfaces.Position + 18.638049428485125 + 47.55034515769599 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 3 + + client + + + + se.sics.cooja.plugins.SimControl + 259 + 0 + 179 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.AttributeVisualizerSkin + se.sics.cooja.plugins.skins.LEDVisualizerSkin + se.sics.cooja.plugins.skins.AddressVisualizerSkin + 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 + + 300 + 2 + 178 + 261 + 1 + + + se.sics.cooja.plugins.LogListener + + + + + 762 + 3 + 491 + 2 + 182 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 4 + 74 + 578 + 18 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + 2 + + + + + 125 + 25.49079397896416 + + 1624 + 5 + 252 + 6 + 712 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 2 + + Serial port + 0,0 + + 853 + 1 + 491 + 765 + 182 + + + diff --git a/examples/osd/dual-rgbw-actor/server-only.csc b/examples/osd/dual-rgbw-actor/server-only.csc index d5eee34d6..1b0fe28bf 100644 --- a/examples/osd/dual-rgbw-actor/server-only.csc +++ b/examples/osd/dual-rgbw-actor/server-only.csc @@ -1,189 +1,189 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 35.100895239785295 - 39.70574552287428 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - se.sics.cooja.plugins.SimControl - 259 - 5 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 - - 300 - 4 - 175 - 263 - 3 - - - se.sics.cooja.plugins.LogListener - - - - - 560 - 1 - 326 - 1 - 293 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 2 - 74 - 39 - 199 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - - - - - 125 - 25.49079397896416 - - 1624 - 3 - 252 - 4 - 622 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 1 - - Serial port - 0,0 - - 702 - 0 - 646 - 564 - 2 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + REST with RPL router + -2147483648 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + se.sics.cooja.interfaces.Position + 35.100895239785295 + 39.70574552287428 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + se.sics.cooja.plugins.SimControl + 259 + 5 + 179 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.AttributeVisualizerSkin + se.sics.cooja.plugins.skins.LEDVisualizerSkin + se.sics.cooja.plugins.skins.AddressVisualizerSkin + 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 + + 300 + 4 + 175 + 263 + 3 + + + se.sics.cooja.plugins.LogListener + + + + + 560 + 1 + 326 + 1 + 293 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 2 + 74 + 39 + 199 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + + + + + 125 + 25.49079397896416 + + 1624 + 3 + 252 + 4 + 622 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 702 + 0 + 646 + 564 + 2 + + + diff --git a/examples/osd/embedd-vm-merkurboard/Makefile b/examples/osd/embedd-vm-merkurboard/Makefile index e11ebef28..6e69fd76f 100644 --- a/examples/osd/embedd-vm-merkurboard/Makefile +++ b/examples/osd/embedd-vm-merkurboard/Makefile @@ -1,16 +1,14 @@ -all: embedd-vm-server +EXE=embedd-vm-server + +all: $(EXE) # use this target explicitly if requried: er-plugtest-server # variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 -# for some platforms -UIP_CONF_IPV6=1 -# IPv6 make config disappeared completely -CFLAGS += -DUIP_CONF_IPV6=1 CONTIKI=../../.. +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" PROJECT_SOURCEFILES += embedvm.c @@ -33,39 +31,10 @@ endif SMALL=1 # REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine -APPS += erbium # optional rules to get assembly #CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 @@ -93,3 +62,10 @@ connect-router-cooja: $(CONTIKI)/tools/tunslip6 connect-minimal: sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/embedd-vm-merkurboard/embedd-vm-server.c b/examples/osd/embedd-vm-merkurboard/embedd-vm-server.c index 09ffe7927..fc93d41cb 100644 --- a/examples/osd/embedd-vm-merkurboard/embedd-vm-server.c +++ b/examples/osd/embedd-vm-merkurboard/embedd-vm-server.c @@ -41,6 +41,7 @@ #include #include "contiki.h" #include "contiki-net.h" +#include "rest-engine.h" /* Define which resources to include to meet memory constraints. */ @@ -50,7 +51,6 @@ #define REST_RES_LEDS 1 #define REST_RES_TOGGLE 1 -#include "erbium.h" #if defined (PLATFORM_HAS_BUTTON) #include "dev/button-sensor.h" @@ -65,18 +65,6 @@ // embedd-vm #include "embedvm.h" -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP == 3 -#include "er-coap-03.h" -#elif WITH_COAP == 7 -#include "er-coap-07.h" -#elif WITH_COAP == 12 -#include "er-coap-12.h" -#elif WITH_COAP == 13 -#include "er-coap-13.h" -#else -#warning "Erbium example without CoAP-specifc functionality" -#endif /* CoAP-specific example */ #define DEBUG 1 #if DEBUG @@ -97,7 +85,6 @@ * Resources are defined by the RESOURCE macro. * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). */ -RESOURCE(info, METHOD_GET, "info", "title=\"Info\";rt=\"Text\""); /* * A handler function named [resource name]_handler must be implemented for each RESOURCE. @@ -106,7 +93,7 @@ RESOURCE(info, METHOD_GET, "info", "title=\"Info\";rt=\"Text\""); * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. */ void -info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +info_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { char message[100]; int index = 0; @@ -124,6 +111,7 @@ info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_ REST.set_header_content_type(response, REST.type.APPLICATION_JSON); REST.set_response_payload(response, buffer, length); } +RESOURCE(res_info, "title=\"Info\";rt=\"text\"", info_get_handler, NULL, NULL, NULL); #endif /******************************************************************************/ @@ -131,7 +119,6 @@ info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_ /******************************************************************************/ #if REST_RES_LEDS /*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -RESOURCE(leds, METHOD_POST | METHOD_PUT , "actuators/leds", "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\""); void leds_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) @@ -176,41 +163,39 @@ leds_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_ REST.set_response_status(response, REST.status.BAD_REQUEST); } } +RESOURCE(res_leds, "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\"", NULL, leds_handler, leds_handler, NULL); #endif /******************************************************************************/ #if REST_RES_TOGGLE /* A simple actuator example. Toggles the red led */ -RESOURCE(toggle, METHOD_GET | METHOD_PUT | METHOD_POST, "actuators/toggle", "title=\"Red LED\";rt=\"Control\""); void toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { leds_toggle(LEDS_RED); } +RESOURCE(res_toggle, "title=\"Red LED\";rt=\"Control\"", toggle_handler, toggle_handler, leds_handler, NULL); #endif #endif /* PLATFORM_HAS_LEDS */ /******************************************************************************/ #if REST_RES_BATTERY && defined (PLATFORM_HAS_BATTERY) /* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(battery, METHOD_GET, "sensors/battery", "title=\"Battery status\";rt=\"Battery\""); void battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { int battery = battery_sensor.value(0); - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); + unsigned int accept = -1; + REST.get_header_accept(request, &accept); - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { REST.set_header_content_type(response, REST.type.TEXT_PLAIN); snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", battery); REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { + else if (accept == REST.type.APPLICATION_JSON) { REST.set_header_content_type(response, REST.type.APPLICATION_JSON); snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'battery':%d}", battery); @@ -223,6 +208,7 @@ battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr REST.set_response_payload(response, msg, strlen(msg)); } } +RESOURCE(res_battery, "title=\"Battery status\";rt=\"battery-mV\"", battery_handler, NULL, NULL, NULL); #endif /* PLATFORM_HAS_BATTERY */ #include "vmcode.hdr" @@ -238,8 +224,6 @@ struct embedvm_s vm = { }; /******************************************************************************/ #if REST_RES_EVM /*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -RESOURCE(evm, METHOD_GET | METHOD_POST | METHOD_PUT , "evm", "title=\"Embedd-VM, POST/PUT player=0/9999\";rt=\"Embedd-VM\""); - void evm_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { @@ -249,7 +233,6 @@ evm_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_s //int length = 0; /* |<-------->| */ int16_t val = 0; uint16_t old_ip=0; - const uint16_t *accept = NULL; switch(REST.get_method_type(request)){ case METHOD_GET: @@ -279,9 +262,10 @@ evm_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_s default: success = 0; } - int num = REST.get_header_accept(request, &accept); - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { if(success){ //length = strlen(gmessage); memcpy(buffer, gmessage,gindex ); @@ -299,6 +283,7 @@ evm_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_s REST.set_response_payload(response, msg, strlen(msg)); } } +RESOURCE(res_evm, "title=\"Embedd-VM, POST/PUT player=0/9999\";rt=\"Embedd-VM\"", evm_handler, evm_handler, evm_handler, NULL); #endif #endif @@ -434,22 +419,22 @@ PROCESS_THREAD(rest_server_example, ev, data) /* Activate the application-specific resources. */ #if REST_RES_INFO - rest_activate_resource(&resource_info); + rest_activate_resource(&res_info, "info"); #endif #if defined (PLATFORM_HAS_LEDS) #if REST_RES_LEDS - rest_activate_resource(&resource_leds); + rest_activate_resource(&res_leds,"a/leds"); #endif #if REST_RES_TOGGLE - rest_activate_resource(&resource_toggle); + rest_activate_resource(&res_toggle,"a/toggle"); #endif #endif /* PLATFORM_HAS_LEDS */ #if REST_RES_EVM - rest_activate_resource(&resource_evm); + rest_activate_resource(&res_evm,"a/evm"); #endif #if defined (PLATFORM_HAS_BATTERY) && REST_RES_BATTERY SENSORS_ACTIVATE(battery_sensor); - rest_activate_resource(&resource_battery); + rest_activate_resource(&res_battery,"s/battery"); #endif while(1) { diff --git a/examples/osd/embedd-vm-merkurboard/embedd-vm-server.osd-merkur.eep b/examples/osd/embedd-vm-merkurboard/embedd-vm-server.osd-merkur.eep deleted file mode 100644 index 1996e8fde..000000000 --- a/examples/osd/embedd-vm-merkurboard/embedd-vm-server.osd-merkur.eep +++ /dev/null @@ -1 +0,0 @@ -:00000001FF diff --git a/examples/osd/embedd-vm-merkurboard/flash.sh b/examples/osd/embedd-vm-merkurboard/flash.sh index fe0d83f0d..e82962073 100755 --- a/examples/osd/embedd-vm-merkurboard/flash.sh +++ b/examples/osd/embedd-vm-merkurboard/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:embedd-vm-server.osd-merkur.hex:a -U eeprom:w:embedd-vm-server.osd-merkur.eep:a +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/embedd-vm-merkurboard/run.sh b/examples/osd/embedd-vm-merkurboard/run.sh index a634126e4..5d5cbbbb4 100755 --- a/examples/osd/embedd-vm-merkurboard/run.sh +++ b/examples/osd/embedd-vm-merkurboard/run.sh @@ -1,8 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size -C --mcu=MCU=atmega128rfa1 embedd-vm-server.osd-merkur -avr-objcopy -j .text -j .data -O ihex embedd-vm-server.osd-merkur embedd-vm-server.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex embedd-vm-server.osd-merkur embedd-vm-server.osd-merkur.eep +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/embedd-vm-merkurboard/server-only.csc b/examples/osd/embedd-vm-merkurboard/server-only.csc index d5eee34d6..1b0fe28bf 100644 --- a/examples/osd/embedd-vm-merkurboard/server-only.csc +++ b/examples/osd/embedd-vm-merkurboard/server-only.csc @@ -1,189 +1,189 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 35.100895239785295 - 39.70574552287428 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - se.sics.cooja.plugins.SimControl - 259 - 5 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 - - 300 - 4 - 175 - 263 - 3 - - - se.sics.cooja.plugins.LogListener - - - - - 560 - 1 - 326 - 1 - 293 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 2 - 74 - 39 - 199 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - - - - - 125 - 25.49079397896416 - - 1624 - 3 - 252 - 4 - 622 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 1 - - Serial port - 0,0 - - 702 - 0 - 646 - 564 - 2 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + REST with RPL router + -2147483648 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + se.sics.cooja.interfaces.Position + 35.100895239785295 + 39.70574552287428 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + se.sics.cooja.plugins.SimControl + 259 + 5 + 179 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.AttributeVisualizerSkin + se.sics.cooja.plugins.skins.LEDVisualizerSkin + se.sics.cooja.plugins.skins.AddressVisualizerSkin + 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 + + 300 + 4 + 175 + 263 + 3 + + + se.sics.cooja.plugins.LogListener + + + + + 560 + 1 + 326 + 1 + 293 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 2 + 74 + 39 + 199 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + + + + + 125 + 25.49079397896416 + + 1624 + 3 + 252 + 4 + 622 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 702 + 0 + 646 + 564 + 2 + + + diff --git a/examples/osd/er-rest-example-merkurboard/Makefile b/examples/osd/er-rest-example-merkurboard/Makefile index 60d971598..21cc867a2 100644 --- a/examples/osd/er-rest-example-merkurboard/Makefile +++ b/examples/osd/er-rest-example-merkurboard/Makefile @@ -1,77 +1,57 @@ -all: er-example-server er-example-client -# use this target explicitly if requried: er-plugtest-server +EXE=er-example-client er-example-server +all: $(EXE) -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 - -# for some platforms -UIP_CONF_IPV6=1 -# IPv6 make config disappeared completely -CFLAGS += -DUIP_CONF_IPV6=1 +# use target "er-plugtest-server" explicitly when requried CONTIKI=../../.. + CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" -# variable for Makefile.include -ifneq ($(TARGET), minimal-net) -CFLAGS += -DUIP_CONF_IPV6_RPL=1 +# automatically build RESTful resources including common resources +ifndef TARGET + REST_EXCLUDE= else -# minimal-net does not support RPL under Linux and is mostly used to test CoAP only -${info INFO: compiling without RPL} -CFLAGS += -DUIP_CONF_IPV6_RPL=0 -CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" -${info INFO: compiling with large buffers} -CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048 -CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 -CFLAGS += -DCOAP_MAX_HEADER_SIZE=640 +ifeq ($(TARGET), native) + REST_EXCLUDE= +else + REST_EXCLUDE= ! -name 'res-plugtest*' endif +endif +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES = $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c' $(REST_EXCLUDE)) \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) # linker optimizations SMALL=1 -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif - -APPS += erbium +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine # optional rules to get assembly #CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 #CUSTOM_RULE_S_TO_OBJECTDIR_O = 1 +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include +# minimal-net target is currently broken in Contiki +ifeq ($(TARGET), minimal-net) +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: er-example compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=1300 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=176 +CONTIKI_WITH_RPL=0 +endif + # optional rules to get assembly #$(OBJECTDIR)/%.o: asmdir/%.S # $(CC) $(CFLAGS) -MMD -c $< -o $@ @@ -88,7 +68,23 @@ connect-router: $(CONTIKI)/tools/tunslip6 sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 connect-router-cooja: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 -p 60001 aaaa::1/64 + +connect-router-native: $(CONTIKI)/examples/ipv6/native-border-router/border-router.native + sudo $(CONTIKI)/exmples/ipv6/native-border-router/border-router.native -a 127.0.0.1 -p 60001 aaaa::1/64 connect-minimal: - sudo ip address add fdfd::1/64 dev tap0 + sudo ip address add fdfd::1/64 dev tap0 + +avr-size-server: er-example-server.$(TARGET).sz + +avr-size-client: er-example-server.$(TARGET).sz + +flash-server: er-example-server.$(TARGET).u er-example-server.$(TARGET).eu + +flash-client: er-example-client.$(TARGET).u er-example-client.$(TARGET).eu + +.PHONY: flash-client avr-size-client flash-server avr-size-server +.PRECIOUS: er-example-server.$(TARGET).hex er-example-server.$(TARGET).eep \ + er-example-client.$(TARGET).hex er-example-client.$(TARGET).eep + diff --git a/examples/osd/er-rest-example-merkurboard/README.md b/examples/osd/er-rest-example-merkurboard/README.md index 1aa35b091..fe82ed9b5 100644 --- a/examples/osd/er-rest-example-merkurboard/README.md +++ b/examples/osd/er-rest-example-merkurboard/README.md @@ -21,6 +21,7 @@ PRELIMINARIES You can disable RDC in border-router project-conf.h (not really required as BR keeps radio turned on). #undef NETSTACK_CONF_RDC #define NETSTACK_CONF_RDC nullrdc_driver +- Alternatively, you can use the native-border-router together with the slip-radio. - For convenience, define the Cooja addresses in /etc/hosts aaaa::0212:7401:0001:0101 cooja1 aaaa::0212:7402:0002:0202 cooja2 @@ -125,10 +126,10 @@ Under Windows/Cygwin, WPCAP might need a patch in DETAILS ------- -Erbium currently implements draft 13. Central features are commented in -er-example-server.c. In general, apps/er-coap-13 supports: +Erbium implements the Proposed Standard of CoAP. Central features are commented +in er-example-server.c. In general, apps/er-coap supports: -- All draft 13 header options +- All draft-18 header options - CON Retransmissions (note COAP_MAX_OPEN_TRANSACTIONS) - Blockwise Transfers (note REST_MAX_CHUNK_SIZE, see er-plugtest-server.c for Block1 uploads) @@ -138,24 +139,6 @@ er-example-server.c. In general, apps/er-coap-13 supports: - Observing Resources (see EVENT_ and PRERIODIC_RESOURCE, note COAP_MAX_OBSERVERS) -REST IMPLEMENTATIONS --------------------- - -The Makefile uses WITH_COAP to configure different implementations for the -Erbium (Er) REST Engine. - -- WITH_COAP=13 uses Erbium CoAP 13 apps/er-coap-13/. The default port for - coap-13 is 5683. -- WITH_COAP=12 uses Erbium CoAP 12 apps/er-coap-12/. The default port for - coap-12 is 5683. -- WITH_COAP=7 uses Erbium CoAP 08 apps/er-coap-07/. The default port for - coap-07/-08 is 5683. -- WITH_COAP=3 uses Erbium CoAP 03 apps/er-coap-03/. The default port for - coap-03 is 61616. er-coap-03 produces some warnings, as it not fully - maintained anymore. -- WITH_COAP=0 is a stub to link an Erbium HTTP engine that uses the same - resource abstraction (REST.x() functions and RESOURCE macros. - TODOs ----- diff --git a/examples/osd/er-rest-example-merkurboard/er-example-client.c b/examples/osd/er-rest-example-merkurboard/er-example-client.c index 14b5a291a..fa3df6a22 100644 --- a/examples/osd/er-rest-example-merkurboard/er-example-client.c +++ b/examples/osd/er-rest-example-merkurboard/er-example-client.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Matthias Kovatsch + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,7 +31,7 @@ /** * \file - * Erbium (Er) CoAP client example + * Erbium (Er) CoAP client example. * \author * Matthias Kovatsch */ @@ -39,55 +39,46 @@ #include #include #include - #include "contiki.h" #include "contiki-net.h" - +#include "er-coap-engine.h" #include "dev/button-sensor.h" -#include "dev/leds.h" - -#if WITH_COAP == 3 -#include "er-coap-03-engine.h" -#elif WITH_COAP == 6 -#include "er-coap-06-engine.h" -#elif WITH_COAP == 7 -#include "er-coap-07-engine.h" -#elif WITH_COAP == 12 -#include "er-coap-12-engine.h" -#elif WITH_COAP == 13 -#include "er-coap-13-engine.h" -#else -#error "CoAP version defined by WITH_COAP not implemented" -#endif - #define DEBUG 0 #if DEBUG +#include #define PRINTF(...) printf(__VA_ARGS__) #define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) #else #define PRINTF(...) #define PRINT6ADDR(addr) #define PRINTLLADDR(addr) #endif -/* TODO: This server address is hard-coded for Cooja. */ -#define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0221, 0x2eff, 0xff00, 0x26e6) /* cooja2 */ +/* FIXME: This server address is hard-coded for Cooja and link-local for unconnected border router. */ +#define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0212, 0x7402, 0x0002, 0x0202) /* cooja2 */ +/* #define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xbbbb, 0, 0, 0, 0, 0, 0, 0x1) */ -#define LOCAL_PORT UIP_HTONS(COAP_DEFAULT_PORT+1) +#define LOCAL_PORT UIP_HTONS(COAP_DEFAULT_PORT + 1) #define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT) -PROCESS(coap_client_example, "COAP Client Example"); -AUTOSTART_PROCESSES(&coap_client_example); +#define TOGGLE_INTERVAL 10 +PROCESS(er_example_client, "Erbium Example Client"); +AUTOSTART_PROCESSES(&er_example_client); uip_ipaddr_t server_ipaddr; +static struct etimer et; /* Example URIs that can be queried. */ #define NUMBER_OF_URLS 4 /* leading and ending slashes only for demo purposes, get cropped automatically when setting the Uri-Path */ -char* service_urls[NUMBER_OF_URLS] = {".well-known/core", "/actuators/toggle", "battery/", "error/in//path"}; +char *service_urls[NUMBER_OF_URLS] = +{ ".well-known/core", "/actuators/toggle", "battery/", "error/in//path" }; +#if PLATFORM_HAS_BUTTON +static int uri_switch = 0; +#endif /* This function is will be passed to COAP_BLOCKING_REQUEST() to handle responses. */ void @@ -96,53 +87,72 @@ client_chunk_handler(void *response) const uint8_t *chunk; int len = coap_get_payload(response, &chunk); + printf("|%.*s", len, (char *)chunk); } - - -PROCESS_THREAD(coap_client_example, ev, data) +PROCESS_THREAD(er_example_client, ev, data) { PROCESS_BEGIN(); - leds_off(LEDS_RED); + static coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ - static coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ SERVER_NODE(&server_ipaddr); /* receives all CoAP messages */ - coap_receiver_init(); + coap_init_engine(); + + etimer_set(&et, TOGGLE_INTERVAL * CLOCK_SECOND); #if PLATFORM_HAS_BUTTON SENSORS_ACTIVATE(button_sensor); - PRINTF("Press a button to request %s\n", service_urls[1]); + printf("Press a button to request %s\n", service_urls[uri_switch]); #endif while(1) { PROCESS_YIELD(); -#if PLATFORM_HAS_BUTTON - if (ev == sensors_event && data == &button_sensor) { + if(etimer_expired(&et)) { + printf("--Toggle timer--\n"); - /* send a request to notify the end of the process */ - - PRINTF("--Toggle --\n"); - leds_toggle(LEDS_RED); /* prepare request, TID is set by COAP_BLOCKING_REQUEST() */ - coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0 ); + coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0); coap_set_header_uri_path(request, service_urls[1]); const char msg[] = "Toggle!"; - coap_set_payload(request, (uint8_t *)msg, sizeof(msg)-1); + coap_set_payload(request, (uint8_t *)msg, sizeof(msg) - 1); PRINT6ADDR(&server_ipaddr); PRINTF(" : %u\n", UIP_HTONS(REMOTE_PORT)); - COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, client_chunk_handler); + COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, + client_chunk_handler); - PRINTF("\n--Done--\n"); - } + printf("\n--Done--\n"); + + etimer_reset(&et); + +#if PLATFORM_HAS_BUTTON + } else if(ev == sensors_event && data == &button_sensor) { + + /* send a request to notify the end of the process */ + + coap_init_message(request, COAP_TYPE_CON, COAP_GET, 0); + coap_set_header_uri_path(request, service_urls[uri_switch]); + + printf("--Requesting %s--\n", service_urls[uri_switch]); + + PRINT6ADDR(&server_ipaddr); + PRINTF(" : %u\n", UIP_HTONS(REMOTE_PORT)); + + COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, + client_chunk_handler); + + printf("\n--Done--\n"); + + uri_switch = (uri_switch + 1) % NUMBER_OF_URLS; #endif + } } PROCESS_END(); diff --git a/examples/osd/er-rest-example-merkurboard/er-example-client.osd-merkur.eep b/examples/osd/er-rest-example-merkurboard/er-example-client.osd-merkur.eep deleted file mode 100644 index 16392b886..000000000 --- a/examples/osd/er-rest-example-merkurboard/er-example-client.osd-merkur.eep +++ /dev/null @@ -1,4 +0,0 @@ -:1000000000212EFFFF001EFB41544D454741313278 -:100010003872666131006C6F63616C686F73740075 -:0900200000001AE5CDAB00000060 -:00000001FF diff --git a/examples/osd/er-rest-example-merkurboard/er-example-server.c b/examples/osd/er-rest-example-merkurboard/er-example-server.c index 48b320f26..4b0d559c7 100644 --- a/examples/osd/er-rest-example-merkurboard/er-example-server.c +++ b/examples/osd/er-rest-example-merkurboard/er-example-server.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Matthias Kovatsch + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,7 +31,7 @@ /** * \file - * Erbium (Er) REST Engine example (with CoAP-specific code) + * Erbium (Er) REST Engine example. * \author * Matthias Kovatsch */ @@ -41,747 +41,59 @@ #include #include "contiki.h" #include "contiki-net.h" +#include "rest-engine.h" - -/* Define which resources to include to meet memory constraints. */ -#define REST_RES_INFO 1 -#define REST_RES_HELLO 0 -#define REST_RES_MIRROR 0 /* causes largest code size */ -#define REST_RES_CHUNKS 1 -#define REST_RES_SEPARATE 0 -#define REST_RES_PUSHING 0 -#define REST_RES_EVENT 1 -#define REST_RES_SUB 0 -#define REST_RES_LEDS 1 -#define REST_RES_TOGGLE 1 -#define REST_RES_LIGHT 0 -#define REST_RES_BATTERY 1 -#define REST_RES_RADIO 0 - - -#include "erbium.h" - - -#if defined (PLATFORM_HAS_BUTTON) +#if PLATFORM_HAS_BUTTON #include "dev/button-sensor.h" #endif -#if defined (PLATFORM_HAS_LEDS) -#include "dev/leds.h" -#endif -#if defined (PLATFORM_HAS_LIGHT) -#include "dev/light-sensor.h" -#endif -#if defined (PLATFORM_HAS_BATTERY) -#include "dev/battery-sensor.h" -#endif -#if defined (PLATFORM_HAS_SHT11) -#include "dev/sht11-sensor.h" -#endif -#if defined (PLATFORM_HAS_RADIO) -#include "dev/radio-sensor.h" -#endif - - -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP == 3 -#include "er-coap-03.h" -#elif WITH_COAP == 7 -#include "er-coap-07.h" -#elif WITH_COAP == 12 -#include "er-coap-12.h" -#elif WITH_COAP == 13 -#include "er-coap-13.h" -#else -#warning "Erbium example without CoAP-specifc functionality" -#endif /* CoAP-specific example */ #define DEBUG 0 #if DEBUG +#include #define PRINTF(...) printf(__VA_ARGS__) #define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) #else #define PRINTF(...) #define PRINT6ADDR(addr) #define PRINTLLADDR(addr) #endif -/******************************************************************************/ -#if REST_RES_HELLO /* - * Resources are defined by the RESOURCE macro. - * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). + * Resources to be activated need to be imported through the extern keyword. + * The build system automatically compiles the resources in the corresponding sub-directory. */ -RESOURCE(helloworld, METHOD_GET, "hello", "title=\"Hello world: ?len=0..\";rt=\"Text\""); - -/* - * A handler function named [resource name]_handler must be implemented for each RESOURCE. - * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore - * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. - * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. - */ -void -helloworld_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - const char *len = NULL; - /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ - char const * const message = "Hello World! ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy"; - int length = 12; /* |<-------->| */ - - /* The query string can be retrieved by rest_get_query() or parsed for its key-value pairs. */ - if (REST.get_query_variable(request, "len", &len)) { - length = atoi(len); - if (length<0) length = 0; - if (length>REST_MAX_CHUNK_SIZE) length = REST_MAX_CHUNK_SIZE; - memcpy(buffer, message, length); - } else { - memcpy(buffer, message, length); - } - - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); /* text/plain is the default, hence this option could be omitted. */ - REST.set_header_etag(response, (uint8_t *) &length, 1); - REST.set_response_payload(response, buffer, length); -} +extern resource_t + res_hello, + res_mirror, + res_chunks, + res_separate, + res_push, + res_event, + res_sub, + res_b1_sep_b2; +#if PLATFORM_HAS_LEDS +#include "dev/leds.h" +extern resource_t res_leds, res_toggle; #endif - -/******************************************************************************/ -#if REST_RES_MIRROR -/* This resource mirrors the incoming request. It shows how to access the options and how to set them for the response. */ -RESOURCE(mirror, METHOD_GET | METHOD_POST | METHOD_PUT | METHOD_DELETE, "debug/mirror", "title=\"Returns your decoded message\";rt=\"Debug\""); - -void -mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - /* The ETag and Token is copied to the header. */ - uint8_t opaque[] = {0x0A, 0xBC, 0xDE}; - - /* Strings are not copied, so use static string buffers or strings in .text memory (char *str = "string in .text";). */ - static char location[] = {'/','f','/','a','?','k','&','e', 0}; - - /* Getter for the header option Content-Type. If the option is not set, text/plain is returned by default. */ - unsigned int content_type = REST.get_header_content_type(request); - - /* The other getters copy the value (or string/array pointer) to the given pointers and return 1 for success or the length of strings/arrays. */ - uint32_t max_age_and_size = 0; - const char *str = NULL; - uint32_t observe = 0; - const uint8_t *bytes = NULL; - uint32_t block_num = 0; - uint8_t block_more = 0; - uint16_t block_size = 0; - const char *query = ""; - int len = 0; - - /* Mirror the received header options in the response payload. Unsupported getters (e.g., rest_get_header_observe() with HTTP) will return 0. */ - - int strpos = 0; - /* snprintf() counts the terminating '\0' to the size parameter. - * The additional byte is taken care of by allocating REST_MAX_CHUNK_SIZE+1 bytes in the REST framework. - * Add +1 to fill the complete buffer, as the payload does not need a terminating '\0'. */ - if (content_type!=-1) - { - strpos += snprintf((char *)buffer, REST_MAX_CHUNK_SIZE+1, "CT %u\n", content_type); - } - - /* Some getters such as for ETag or Location are omitted, as these options should not appear in a request. - * Max-Age might appear in HTTP requests or used for special purposes in CoAP. */ - if (strpos<=REST_MAX_CHUNK_SIZE && REST.get_header_max_age(request, &max_age_and_size)) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "MA %lu\n", max_age_and_size); - } - /* For HTTP this is the Length option, for CoAP it is the Size option. */ - if (strpos<=REST_MAX_CHUNK_SIZE && REST.get_header_length(request, &max_age_and_size)) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "SZ %lu\n", max_age_and_size); - } - - if (strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_header_host(request, &str))) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "UH %.*s\n", len, str); - } - -/* CoAP-specific example: actions not required for normal RESTful Web service. */ -#if WITH_COAP > 1 - if (strpos<=REST_MAX_CHUNK_SIZE && coap_get_header_observe(request, &observe)) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "Ob %lu\n", observe); - } - if (strpos<=REST_MAX_CHUNK_SIZE && (len = coap_get_header_token(request, &bytes))) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "To 0x"); - int index = 0; - for (index = 0; index 03 */ -#endif /* CoAP-specific example */ - - if (strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_query(request, &query))) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "Qu %.*s\n", len, query); - } - if (strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_request_payload(request, &bytes))) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "%.*s", len, bytes); - } - - if (strpos >= REST_MAX_CHUNK_SIZE) - { - buffer[REST_MAX_CHUNK_SIZE-1] = 0xBB; /* '»' to indicate truncation */ - } - - REST.set_response_payload(response, buffer, strpos); - - PRINTF("/mirror options received: %s\n", buffer); - - /* Set dummy header options for response. Like getters, some setters are not implemented for HTTP and have no effect. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_header_max_age(response, 17); /* For HTTP, browsers will not re-request the page for 17 seconds. */ - REST.set_header_etag(response, opaque, 2); - REST.set_header_location(response, location); /* Initial slash is omitted by framework */ - REST.set_header_length(response, strpos); /* For HTTP, browsers will not re-request the page for 10 seconds. CoAP action depends on the client. */ - -/* CoAP-specific example: actions not required for normal RESTful Web service. */ -#if WITH_COAP > 1 - coap_set_header_uri_host(response, "tiki"); - coap_set_header_observe(response, 10); -#if WITH_COAP == 3 - coap_set_header_block(response, 42, 0, 64); /* The block option might be overwritten by the framework when blockwise transfer is requested. */ -#else - coap_set_header_proxy_uri(response, "ftp://x"); - coap_set_header_block2(response, 42, 0, 64); /* The block option might be overwritten by the framework when blockwise transfer is requested. */ - coap_set_header_block1(response, 23, 0, 16); - coap_set_header_accept(response, TEXT_PLAIN); - coap_set_header_if_none_match(response); -#endif /* CoAP > 03 */ -#endif /* CoAP-specific example */ -} -#endif /* REST_RES_MIRROR */ - -/******************************************************************************/ -#if REST_RES_CHUNKS -/* - * For data larger than REST_MAX_CHUNK_SIZE (e.g., stored in flash) resources must be aware of the buffer limitation - * and split their responses by themselves. To transfer the complete resource through a TCP stream or CoAP's blockwise transfer, - * the byte offset where to continue is provided to the handler as int32_t pointer. - * These chunk-wise resources must set the offset value to its new position or -1 of the end is reached. - * (The offset for CoAP's blockwise transfer can go up to 2'147'481'600 = ~2047 M for block size 2048 (reduced to 1024 in observe-03.) - */ -RESOURCE(chunks, METHOD_GET, "test/chunks", "title=\"Blockwise demo\";rt=\"Data\""); - -#define CHUNKS_TOTAL 2050 - -void -chunks_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int32_t strpos = 0; - - /* Check the offset for boundaries of the resource data. */ - if (*offset>=CHUNKS_TOTAL) - { - REST.set_response_status(response, REST.status.BAD_OPTION); - /* A block error message should not exceed the minimum block size (16). */ - - const char *error_msg = "BlockOutOfScope"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - /* Generate data until reaching CHUNKS_TOTAL. */ - while (strpos preferred_size) - { - strpos = preferred_size; - } - - /* Truncate if above CHUNKS_TOTAL bytes. */ - if (*offset+(int32_t)strpos > CHUNKS_TOTAL) - { - strpos = CHUNKS_TOTAL - *offset; - } - - REST.set_response_payload(response, buffer, strpos); - - /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ - *offset += strpos; - - /* Signal end of resource representation. */ - if (*offset>=CHUNKS_TOTAL) - { - *offset = -1; - } -} +#if PLATFORM_HAS_LIGHT +#include "dev/light-sensor.h" +extern resource_t res_light; #endif - -/******************************************************************************/ -#if REST_RES_SEPARATE && defined (PLATFORM_HAS_BUTTON) && WITH_COAP > 3 -/* Required to manually (=not by the engine) handle the response transaction. */ -#if WITH_COAP == 7 -#include "er-coap-07-separate.h" -#include "er-coap-07-transactions.h" -#elif WITH_COAP == 12 -#include "er-coap-12-separate.h" -#include "er-coap-12-transactions.h" -#elif WITH_COAP == 13 -#include "er-coap-13-separate.h" -#include "er-coap-13-transactions.h" +#if PLATFORM_HAS_BATTERY +#include "dev/battery-sensor.h" +extern resource_t res_battery; #endif /* - * CoAP-specific example for separate responses. - * Note the call "rest_set_pre_handler(&resource_separate, coap_separate_handler);" in the main process. - * The pre-handler takes care of the empty ACK and updates the MID and message type for CON requests. - * The resource handler must store all information that required to finalize the response later. - */ -RESOURCE(separate, METHOD_GET, "test/separate", "title=\"Separate demo\""); - -/* A structure to store the required information */ -typedef struct application_separate_store { - /* Provided by Erbium to store generic request information such as remote address and token. */ - coap_separate_t request_metadata; - /* Add fields for addition information to be stored for finalizing, e.g.: */ - char buffer[16]; -} application_separate_store_t; - -static uint8_t separate_active = 0; -static application_separate_store_t separate_store[1]; - -void -separate_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - /* - * Example allows only one open separate response. - * For multiple, the application must manage the list of stores. - */ - if (separate_active) - { - coap_separate_reject(); - } - else - { - separate_active = 1; - - /* Take over and skip response by engine. */ - coap_separate_accept(request, &separate_store->request_metadata); - /* Be aware to respect the Block2 option, which is also stored in the coap_separate_t. */ - - /* - * At the moment, only the minimal information is stored in the store (client address, port, token, MID, type, and Block2). - * Extend the store, if the application requires additional information from this handler. - * buffer is an example field for custom information. - */ - snprintf(separate_store->buffer, sizeof(separate_store->buffer), "StoredInfo"); - } -} - -void -separate_finalize_handler() -{ - if (separate_active) - { - coap_transaction_t *transaction = NULL; - if ( (transaction = coap_new_transaction(separate_store->request_metadata.mid, &separate_store->request_metadata.addr, separate_store->request_metadata.port)) ) - { - coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */ - - /* Restore the request information for the response. */ - coap_separate_resume(response, &separate_store->request_metadata, REST.status.OK); - - coap_set_payload(response, separate_store->buffer, strlen(separate_store->buffer)); - - /* - * Be aware to respect the Block2 option, which is also stored in the coap_separate_t. - * As it is a critical option, this example resource pretends to handle it for compliance. - */ - coap_set_header_block2(response, separate_store->request_metadata.block2_num, 0, separate_store->request_metadata.block2_size); - - /* Warning: No check for serialization error. */ - transaction->packet_len = coap_serialize_message(response, transaction->packet); - coap_send_transaction(transaction); - /* The engine will clear the transaction (right after send for NON, after acked for CON). */ - - separate_active = 0; - } - else - { - /* - * Set timer for retry, send error message, ... - * The example simply waits for another button press. - */ - } - } /* if (separate_active) */ -} +#if PLATFORM_HAS_RADIO +#include "dev/radio-sensor.h" +extern resource_t res_radio; #endif - -/******************************************************************************/ -#if REST_RES_PUSHING -/* - * Example for a periodic resource. - * It takes an additional period parameter, which defines the interval to call [name]_periodic_handler(). - * A default post_handler takes care of subscriptions by managing a list of subscribers to notify. - */ -PERIODIC_RESOURCE(pushing, METHOD_GET, "test/push", "title=\"Periodic demo\";obs", 5*CLOCK_SECOND); - -void -pushing_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - - /* Usually, a CoAP server would response with the resource representation matching the periodic_handler. */ - const char *msg = "It's periodic!"; - REST.set_response_payload(response, msg, strlen(msg)); - - /* A post_handler that handles subscriptions will be called for periodic resources by the REST framework. */ -} - -/* - * Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE. - * It will be called by the REST manager process with the defined period. - */ -void -pushing_periodic_handler(resource_t *r) -{ - static uint16_t obs_counter = 0; - static char content[11]; - - ++obs_counter; - - PRINTF("TICK %u for /%s\n", obs_counter, r->url); - - /* Build notification. */ - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_NON, REST.status.OK, 0 ); - coap_set_payload(notification, content, snprintf(content, sizeof(content), "TICK %u", obs_counter)); - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(r, obs_counter, notification); -} -#endif - -/******************************************************************************/ -#if REST_RES_EVENT && defined (PLATFORM_HAS_BUTTON) -/* - * Example for an event resource. - * Additionally takes a period parameter that defines the interval to call [name]_periodic_handler(). - * A default post_handler takes care of subscriptions and manages a list of subscribers to notify. - */ -EVENT_RESOURCE(event, METHOD_GET, "sensors/button", "title=\"Event demo\";obs"); - -void -event_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - /* Usually, a CoAP server would response with the current resource representation. */ - const char *msg = "It's eventful!"; - REST.set_response_payload(response, (uint8_t *)msg, strlen(msg)); - - /* A post_handler that handles subscriptions/observing will be called for periodic resources by the framework. */ -} - -/* Additionally, a handler function named [resource name]_event_handler must be implemented for each PERIODIC_RESOURCE defined. - * It will be called by the REST manager process with the defined period. */ -void -event_event_handler(resource_t *r) -{ - static uint16_t event_counter = 0; - static char content[12]; - - ++event_counter; - - PRINTF("TICK %u for /%s\n", event_counter, r->url); - - /* Build notification. */ - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_CON, REST.status.OK, 0 ); - coap_set_payload(notification, content, snprintf(content, sizeof(content), "EVENT %u", event_counter)); - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(r, event_counter, notification); -} -#endif /* PLATFORM_HAS_BUTTON */ - -/******************************************************************************/ -#if REST_RES_SUB -/* - * Example for a resource that also handles all its sub-resources. - * Use REST.get_url() to multiplex the handling of the request depending on the Uri-Path. - */ -RESOURCE(sub, METHOD_GET | HAS_SUB_RESOURCES, "test/path", "title=\"Sub-resource demo\""); - -void -sub_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - - const char *uri_path = NULL; - int len = REST.get_url(request, &uri_path); - int base_len = strlen(resource_sub.url); - - if (len==base_len) - { - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "Request any sub-resource of /%s", resource_sub.url); - } - else - { - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, ".%.*s", len-base_len, uri_path+base_len); - } - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); -} -#endif - -/******************************************************************************/ -#if defined (PLATFORM_HAS_LEDS) -/******************************************************************************/ -#if REST_RES_LEDS -/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -RESOURCE(leds, METHOD_POST | METHOD_PUT , "actuators/leds", "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\""); - -void -leds_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - size_t len = 0; - const char *color = NULL; - const char *mode = NULL; - uint8_t led = 0; - int success = 1; - - if ((len=REST.get_query_variable(request, "color", &color))) { - PRINTF("color %.*s\n", len, color); - - if (strncmp(color, "r", len)==0) { - led = LEDS_RED; - } else if(strncmp(color,"g", len)==0) { - led = LEDS_GREEN; - } else if (strncmp(color,"b", len)==0) { - led = LEDS_BLUE; - } else { - success = 0; - } - } else { - success = 0; - } - - if (success && (len=REST.get_post_variable(request, "mode", &mode))) { - PRINTF("mode %s\n", mode); - - if (strncmp(mode, "on", len)==0) { - leds_on(led); - } else if (strncmp(mode, "off", len)==0) { - leds_off(led); - } else { - success = 0; - } - } else { - success = 0; - } - - if (!success) { - REST.set_response_status(response, REST.status.BAD_REQUEST); - } -} -#endif - -/******************************************************************************/ -#if REST_RES_TOGGLE -/* A simple actuator example. Toggles the red led */ -RESOURCE(toggle, METHOD_POST, "actuators/toggle", "title=\"Red LED\";rt=\"Control\""); -void -toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - leds_toggle(LEDS_RED); -} -#endif -#endif /* PLATFORM_HAS_LEDS */ - -/******************************************************************************/ -#if REST_RES_LIGHT && defined (PLATFORM_HAS_LIGHT) -/* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(light, METHOD_GET, "sensors/light", "title=\"Photosynthetic and solar light (supports JSON)\";rt=\"LightSensor\""); -void -light_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - uint16_t light_photosynthetic = light_sensor.value(LIGHT_SENSOR_PHOTOSYNTHETIC); - uint16_t light_solar = light_sensor.value(LIGHT_SENSOR_TOTAL_SOLAR); - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%u;%u", light_photosynthetic, light_solar); - - REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_XML)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_XML); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "", light_photosynthetic, light_solar); - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'light':{'photosynthetic':%u,'solar':%u}}", light_photosynthetic, light_solar); - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain, application/xml, and application/json"; - REST.set_response_payload(response, msg, strlen(msg)); - } -} -#endif /* PLATFORM_HAS_LIGHT */ - -/******************************************************************************/ -#if REST_RES_BATTERY && defined (PLATFORM_HAS_BATTERY) -/* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(battery, METHOD_GET, "sensors/battery", "title=\"Battery status\";rt=\"Battery\""); -void -battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int battery = battery_sensor.value(0); - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", battery); - - REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'battery':%d}", battery); - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain and application/json"; - REST.set_response_payload(response, msg, strlen(msg)); - } -} -#endif /* PLATFORM_HAS_BATTERY */ - - -#if defined (PLATFORM_HAS_RADIO) && REST_RES_RADIO -/* A simple getter example. Returns the reading of the rssi/lqi from radio sensor */ -RESOURCE(radio, METHOD_GET, "sensor/radio", "title=\"RADIO: ?p=lqi|rssi\";rt=\"RadioSensor\""); - -void -radio_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - size_t len = 0; - const char *p = NULL; - uint8_t param = 0; - int success = 1; - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((len=REST.get_query_variable(request, "p", &p))) { - PRINTF("p %.*s\n", len, p); - if (strncmp(p, "lqi", len)==0) { - param = RADIO_SENSOR_LAST_VALUE; - } else if(strncmp(p,"rssi", len)==0) { - param = RADIO_SENSOR_LAST_PACKET; - } else { - success = 0; - } - } else { - success = 0; - } - - if (success) { - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", radio_sensor.value(param)); - - REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - - if (param == RADIO_SENSOR_LAST_VALUE) { - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'lqi':%d}", radio_sensor.value(param)); - } else if (param == RADIO_SENSOR_LAST_PACKET) { - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'rssi':%d}", radio_sensor.value(param)); - } - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain and application/json"; - REST.set_response_payload(response, msg, strlen(msg)); - } - } else { - REST.set_response_status(response, REST.status.BAD_REQUEST); - } -} +#if PLATFORM_HAS_SHT11 +#include "dev/sht11/sht11-sensor.h" +extern resource_t res_sht11; #endif +*/ void hw_init() @@ -791,13 +103,15 @@ hw_init() #endif } -PROCESS(rest_server_example, "Erbium Example Server"); -AUTOSTART_PROCESSES(&rest_server_example); +PROCESS(er_example_server, "Erbium Example Server"); +AUTOSTART_PROCESSES(&er_example_server); -PROCESS_THREAD(rest_server_example, ev, data) +PROCESS_THREAD(er_example_server, ev, data) { PROCESS_BEGIN(); + PROCESS_PAUSE(); + PRINTF("Starting Erbium Example Server\n"); #ifdef RF_CHANNEL @@ -812,75 +126,62 @@ PROCESS_THREAD(rest_server_example, ev, data) PRINTF("IP+UDP header: %u\n", UIP_IPUDPH_LEN); PRINTF("REST max chunk: %u\n", REST_MAX_CHUNK_SIZE); - /* Initialize the OSD Hardware. */ hw_init(); /* Initialize the REST engine. */ rest_init_engine(); - /* Activate the application-specific resources. */ -#if REST_RES_HELLO - rest_activate_resource(&resource_helloworld); + /* + * Bind the resources to their Uri-Path. + * WARNING: Activating twice only means alternate path, not two instances! + * All static variables are the same for each URI path. + */ + rest_activate_resource(&res_hello, "test/hello"); +/* rest_activate_resource(&res_mirror, "debug/mirror"); */ +/* rest_activate_resource(&res_chunks, "test/chunks"); */ +/* rest_activate_resource(&res_separate, "test/separate"); */ + rest_activate_resource(&res_push, "test/push"); +/* rest_activate_resource(&res_event, "s/button"); */ +/* rest_activate_resource(&res_sub, "test/sub"); */ +/* rest_activate_resource(&res_b1_sep_b2, "test/b1sepb2"); */ +#if PLATFORM_HAS_LEDS +/* rest_activate_resource(&res_leds, "a/leds"); */ + rest_activate_resource(&res_toggle, "a/toggle"); #endif -#if REST_RES_MIRROR - rest_activate_resource(&resource_mirror); +#if PLATFORM_HAS_LIGHT + rest_activate_resource(&res_light, "s/light"); + SENSORS_ACTIVATE(light_sensor); #endif -#if REST_RES_CHUNKS - rest_activate_resource(&resource_chunks); + +#if PLATFORM_HAS_BATTERY + rest_activate_resource(&res_battery, "s/battery"); + SENSORS_ACTIVATE(battery_sensor); #endif -#if REST_RES_PUSHING - rest_activate_periodic_resource(&periodic_resource_pushing); +/* +#if PLATFORM_HAS_RADIO + rest_activate_resource(&res_radio, "s/radio"); + SENSORS_ACTIVATE(radio_sensor); #endif -#if defined (PLATFORM_HAS_BUTTON) && REST_RES_EVENT - rest_activate_event_resource(&resource_event); -#endif -#if defined (PLATFORM_HAS_BUTTON) && REST_RES_SEPARATE && WITH_COAP > 3 - /* No pre-handler anymore, user coap_separate_accept() and coap_separate_reject(). */ - rest_activate_resource(&resource_separate); -#endif -#if defined (PLATFORM_HAS_BUTTON) && (REST_RES_EVENT || (REST_RES_SEPARATE && WITH_COAP > 3)) - SENSORS_ACTIVATE(button_sensor); -#endif -#if REST_RES_SUB - rest_activate_resource(&resource_sub); -#endif -#if defined (PLATFORM_HAS_LEDS) -#if REST_RES_LEDS - rest_activate_resource(&resource_leds); -#endif -#if REST_RES_TOGGLE - rest_activate_resource(&resource_toggle); -#endif -#endif /* PLATFORM_HAS_LEDS */ -#if defined (PLATFORM_HAS_LIGHT) && REST_RES_LIGHT - SENSORS_ACTIVATE(light_sensor); - rest_activate_resource(&resource_light); -#endif -#if defined (PLATFORM_HAS_BATTERY) && REST_RES_BATTERY - SENSORS_ACTIVATE(battery_sensor); - rest_activate_resource(&resource_battery); -#endif -#if defined (PLATFORM_HAS_RADIO) && REST_RES_RADIO - SENSORS_ACTIVATE(radio_sensor); - rest_activate_resource(&resource_radio); +#if PLATFORM_HAS_SHT11 + rest_activate_resource(&res_sht11, "s/sht11"); + SENSORS_ACTIVATE(sht11_sensor); #endif +*/ /* Define application-specific events here. */ while(1) { PROCESS_WAIT_EVENT(); -#if defined (PLATFORM_HAS_BUTTON) - if (ev == sensors_event && data == &button_sensor) { - PRINTF("BUTTON\n"); -#if REST_RES_EVENT +#if PLATFORM_HAS_BUTTON + if(ev == sensors_event && data == &button_sensor) { + PRINTF("*******BUTTON*******\n"); + /* Call the event_handler for this application-specific event. */ - event_event_handler(&resource_event); -#endif -#if REST_RES_SEPARATE && WITH_COAP>3 + res_event.trigger(); + /* Also call the separate response example handler. */ - separate_finalize_handler(); -#endif + res_separate.resume(); } #endif /* PLATFORM_HAS_BUTTON */ - } /* while (1) */ + } /* while (1) */ PROCESS_END(); } diff --git a/examples/osd/er-rest-example-merkurboard/er-example-server.osd-merkur.eep b/examples/osd/er-rest-example-merkurboard/er-example-server.osd-merkur.eep deleted file mode 100644 index 1996e8fde..000000000 --- a/examples/osd/er-rest-example-merkurboard/er-example-server.osd-merkur.eep +++ /dev/null @@ -1 +0,0 @@ -:00000001FF diff --git a/examples/osd/er-rest-example-merkurboard/er-plugtest-server.c b/examples/osd/er-rest-example-merkurboard/er-plugtest-server.c index 5a791a09c..ae637dc4c 100644 --- a/examples/osd/er-rest-example-merkurboard/er-plugtest-server.c +++ b/examples/osd/er-rest-example-merkurboard/er-plugtest-server.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Matthias Kovatsch + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,7 +31,7 @@ /** * \file - * Server for the ETSI IoT CoAP Plugtests, Paris, France, 24 - 25 March 2012 + * Server for the ETSI IoT CoAP Plugtests, Las Vegas, NV, USA, Nov 2013. * \author * Matthias Kovatsch */ @@ -41,1179 +41,37 @@ #include #include "contiki.h" #include "contiki-net.h" - -#define MAX_PLUGFEST_PAYLOAD 64+1 /* +1 for the terminating zero, which is not transmitted */ -#define MAX_PLUGFEST_BODY 2048 -#define CHUNKS_TOTAL 2012 - -/* Define which resources to include to meet memory constraints. */ -#define REST_RES_TEST 1 -#define REST_RES_LONG 1 -#define REST_RES_QUERY 1 -#define REST_RES_LOC_QUERY 1 -#define REST_RES_MULTI 1 -#define REST_RES_LINKS 1 -#define REST_RES_PATH 1 -#define REST_RES_SEPARATE 1 -#define REST_RES_LARGE 1 -#define REST_RES_LARGE_UPDATE 1 -#define REST_RES_LARGE_CREATE 1 -#define REST_RES_OBS 1 - -#define REST_RES_MIRROR 1 - - - -#if !defined (CONTIKI_TARGET_MINIMAL_NET) -#warning "Should only be compiled for minimal-net!" -#endif - - - -#include "erbium.h" - -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP==7 -#include "er-coap-07.h" -#elif WITH_COAP == 12 -#include "er-coap-12.h" -#elif WITH_COAP == 13 -#include "er-coap-13.h" -#else -#error "Plugtests server without CoAP" -#endif /* CoAP-specific example */ - -#define DEBUG 1 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - - -#if REST_RES_TEST -/* - * Default test resource - */ -RESOURCE(test, METHOD_GET|METHOD_POST|METHOD_PUT|METHOD_DELETE, "test", "title=\"Default test resource\""); - -static uint8_t test_etag[8] = {0}; -static uint8_t test_etag_len = 1; -static uint8_t test_change = 1; -static uint8_t test_none_match_okay = 1; - -static -void -test_update_etag() -{ - int i; - test_etag_len = (random_rand() % 8) + 1; - for (i=0; i0 && len==test_etag_len && memcmp(test_etag, bytes, len)==0) - { - PRINTF("validate "); - REST.set_response_status(response, REST.status.NOT_MODIFIED); - REST.set_header_etag(response, test_etag, test_etag_len); - - test_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } - else - { - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_header_etag(response, test_etag, test_etag_len); - REST.set_header_max_age(response, 30); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); - } - } - else if (method & METHOD_POST) - { - PRINTF("POST "); - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "/location1/location2/location3"); - } - else if (method & METHOD_PUT) - { - PRINTF("PUT "); - - if (coap_get_header_if_none_match(request)) - { - if (test_none_match_okay) - { - REST.set_response_status(response, REST.status.CREATED); - - test_none_match_okay = 0; - PRINTF("### SERVER ACTION ### If-None-Match will FAIL\n"); - } - else - { - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - - test_none_match_okay = 1; - PRINTF("### SERVER ACTION ### If-None-Match will SUCCEED\n"); - } - } - else if (((len = coap_get_header_if_match(request, &bytes))>0 && (len==test_etag_len && memcmp(test_etag, bytes, len)==0)) || len==0) - { - test_update_etag(); - REST.set_header_etag(response, test_etag, test_etag_len); - - REST.set_response_status(response, REST.status.CHANGED); - - if (len>0) - { - test_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } - } - else - { - - PRINTF("Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X] ", len, test_etag_len, - bytes[0], - bytes[1], - bytes[2], - bytes[3], - bytes[4], - bytes[5], - bytes[6], - bytes[7], - test_etag[0], - test_etag[1], - test_etag[2], - test_etag[3], - test_etag[4], - test_etag[5], - test_etag[6], - test_etag[7] ); - - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } - else if (method & METHOD_DELETE) - { - PRINTF("DELETE "); - REST.set_response_status(response, REST.status.DELETED); - } - - PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); -} - - -RESOURCE(create1, METHOD_PUT|METHOD_DELETE, "create1", "title=\"Default test resource\""); - -static uint8_t create1_exists = 0; - -void -create1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - uint8_t method = REST.get_method_type(request); - - if (test_change) - { - test_update_etag(); - } - - PRINTF("/create1 "); - - if (method & METHOD_PUT) - { - PRINTF("PUT "); - - if (coap_get_header_if_none_match(request)) - { - if (!create1_exists) - { - REST.set_response_status(response, REST.status.CREATED); - - create1_exists = 1; - } - else - { - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } - else - { - REST.set_response_status(response, REST.status.CHANGED); - } - } - else if (method & METHOD_DELETE) - { - PRINTF("DELETE "); - REST.set_response_status(response, REST.status.DELETED); - - create1_exists = 0; - } -} - -RESOURCE(create2, METHOD_POST, "create2", "title=\"Creates on POST\""); - -void -create2_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - if (test_change) - { - test_update_etag(); - } - - PRINTF("/create2 "); - - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "/location1/location2/location3"); -} - -RESOURCE(create3, METHOD_PUT|METHOD_DELETE, "create3", "title=\"Default test resource\""); - -static uint8_t create3_exists = 0; - -void -create3_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - uint8_t method = REST.get_method_type(request); - - if (test_change) - { - test_update_etag(); - } - - PRINTF("/create3 "); - - if (method & METHOD_PUT) - { - PRINTF("PUT "); - - if (coap_get_header_if_none_match(request)) - { - if (!create3_exists) - { - REST.set_response_status(response, REST.status.CREATED); - - create3_exists = 1; - } - else - { - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } - else - { - REST.set_response_status(response, REST.status.CHANGED); - } - } - else if (method & METHOD_DELETE) - { - PRINTF("DELETE "); - REST.set_response_status(response, REST.status.DELETED); - - create3_exists = 0; - } -} - - - - - -RESOURCE(validate, METHOD_GET|METHOD_PUT, "validate", "title=\"Default test resource\""); - -static uint8_t validate_etag[8] = {0}; -static uint8_t validate_etag_len = 1; -static uint8_t validate_change = 1; - -static -void -validate_update_etag() -{ - int i; - validate_etag_len = (random_rand() % 8) + 1; - for (i=0; i0 && len==validate_etag_len && memcmp(validate_etag, bytes, len)==0) - { - PRINTF("validate "); - REST.set_response_status(response, REST.status.NOT_MODIFIED); - REST.set_header_etag(response, validate_etag, validate_etag_len); - - validate_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } - else - { - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_header_etag(response, validate_etag, validate_etag_len); - REST.set_header_max_age(response, 30); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); - } - } - else if (method & METHOD_PUT) - { - PRINTF("PUT "); - - if (((len = coap_get_header_if_match(request, &bytes))>0 && (len==validate_etag_len && memcmp(validate_etag, bytes, len)==0)) || len==0) - { - validate_update_etag(); - REST.set_header_etag(response, validate_etag, validate_etag_len); - - REST.set_response_status(response, REST.status.CHANGED); - - if (len>0) - { - validate_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } - } - else - { - PRINTF("Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X] ", len, validate_etag_len, - bytes[0], - bytes[1], - bytes[2], - bytes[3], - bytes[4], - bytes[5], - bytes[6], - bytes[7], - validate_etag[0], - validate_etag[1], - validate_etag[2], - validate_etag[3], - validate_etag[4], - validate_etag[5], - validate_etag[6], - validate_etag[7] ); - - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } - - PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); -} -#endif - -#if REST_RES_LONG -/* - * Long path resource - */ -RESOURCE(longpath, METHOD_GET, "seg1/seg2/seg3", "title=\"Long path resource\""); - -void -longpath_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - uint8_t method = REST.get_method_type(request); - - PRINTF("/seg1/seg2/seg3 "); - if (method & METHOD_GET) - { - PRINTF("GET "); - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); - } - PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); -} -#endif - -#if REST_RES_QUERY -/* - * Resource accepting query parameters - */ -RESOURCE(query, METHOD_GET, "query", "title=\"Resource accepting query parameters\""); - -void -query_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - int len = 0; - const char *query = NULL; - - PRINTF("/query GET (%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); - - if ((len = REST.get_query(request, &query))) - { - PRINTF("Query: %.*s\n", len, query); - } - - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u\nQuery: %.*s", coap_req->type, coap_req->code, coap_req->mid, len, query)); -} -#endif - -#if REST_RES_LOC_QUERY -/* - * Resource accepting query parameters - */ -RESOURCE(locquery, METHOD_POST, "location-query", "title=\"Resource accepting query parameters\""); - -void -locquery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - PRINTF("/location-query POST (%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); - - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "?first=1&second=2"); -} -#endif - -#if REST_RES_MULTI -/* - * Resource providing text/plain and application/xml - */ -RESOURCE(multi, METHOD_GET, "multi-format", "title=\"Resource providing text/plain and application/xml\";ct=\"0 41\""); -void -multi_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - PRINTF("/multi-format GET (%s %u) %d\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid, num); - - if (num==0 || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u%s", coap_req->type, coap_req->code, coap_req->mid, num ? "\nAccept: 0" : "")); -PRINTF("PLAIN\n"); - } - else if (num && (accept[0]==REST.type.APPLICATION_XML)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_XML); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "", coap_req->type, coap_req->code, coap_req->mid, accept[0])); -PRINTF("XML\n"); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain and application/xml"; - REST.set_response_payload(response, msg, strlen(msg)); - PRINTF("ERROR\n"); - } -} -#endif - -#if REST_RES_LINKS -/* - * Resources providing text/plain and application/xml - */ -RESOURCE(link1, METHOD_GET, "link1", "rt=\"Type1 Type2\";if=\"If1\""); -SUB_RESOURCE(link2, METHOD_GET, "link2", "rt=\"Type2 Type3\";if=\"If2\"", link1); -SUB_RESOURCE(link3, METHOD_GET, "link3", "rt=\"Type1 Type3\";if=\"foo\"", link1); - -void -link1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - const char *msg = "Dummy link"; - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, msg, strlen(msg)); -} -#endif - -#if REST_RES_PATH -/* - * Resources providing text/plain and application/xml - */ -RESOURCE(path, METHOD_GET | HAS_SUB_RESOURCES, "path", "ct=\"40\""); - -void -path_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - - const char *uri_path = NULL; - int len = REST.get_url(request, &uri_path); - int base_len = strlen(resource_path.url); - - if (len==base_len) - { - REST.set_header_content_type(response, REST.type.APPLICATION_LINK_FORMAT); - snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, ",,"); - } - else - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "/%.*s", len, uri_path); - } - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); -} -#endif - -#if REST_RES_SEPARATE -/* Required to manually (=not by the engine) handle the response transaction. */ -#if WITH_COAP == 7 -#include "er-coap-07-separate.h" -#include "er-coap-07-transactions.h" -#elif WITH_COAP == 12 -#include "er-coap-12-separate.h" -#include "er-coap-12-transactions.h" -#elif WITH_COAP == 13 -#include "er-coap-13-separate.h" -#include "er-coap-13-transactions.h" -#endif -/* - * Resource which cannot be served immediately and which cannot be acknowledged in a piggy-backed way - */ -PERIODIC_RESOURCE(separate, METHOD_GET, "separate", "title=\"Resource which cannot be served immediately and which cannot be acknowledged in a piggy-backed way\"", 3*CLOCK_SECOND); - -/* A structure to store the required information */ -typedef struct application_separate_store { - /* Provided by Erbium to store generic request information such as remote address and token. */ - coap_separate_t request_metadata; - /* Add fields for addition information to be stored for finalizing, e.g.: */ - char buffer[MAX_PLUGFEST_PAYLOAD]; -} application_separate_store_t; - -static uint8_t separate_active = 0; -static application_separate_store_t separate_store[1]; - -void -separate_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - PRINTF("/separate "); - if (separate_active) - { - PRINTF("REJECTED "); - coap_separate_reject(); - } - else - { - PRINTF("STORED "); - separate_active = 1; - - /* Take over and skip response by engine. */ - coap_separate_accept(request, &separate_store->request_metadata); - /* Be aware to respect the Block2 option, which is also stored in the coap_separate_t. */ - - snprintf(separate_store->buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid); - } - - PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); -} - -void -separate_periodic_handler(resource_t *resource) -{ - if (separate_active) - { - PRINTF("/separate "); - coap_transaction_t *transaction = NULL; - if ( (transaction = coap_new_transaction(separate_store->request_metadata.mid, &separate_store->request_metadata.addr, separate_store->request_metadata.port)) ) - { - PRINTF("RESPONSE (%s %u)\n", separate_store->request_metadata.type==COAP_TYPE_CON?"CON":"NON", separate_store->request_metadata.mid); - - coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */ - - /* Restore the request information for the response. */ - coap_separate_resume(response, &separate_store->request_metadata, CONTENT_2_05); - - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - coap_set_payload(response, separate_store->buffer, strlen(separate_store->buffer)); - - /* - * Be aware to respect the Block2 option, which is also stored in the coap_separate_t. - * As it is a critical option, this example resource pretends to handle it for compliance. - */ - coap_set_header_block2(response, separate_store->request_metadata.block2_num, 0, separate_store->request_metadata.block2_size); - - /* Warning: No check for serialization error. */ - transaction->packet_len = coap_serialize_message(response, transaction->packet); - coap_send_transaction(transaction); - /* The engine will clear the transaction (right after send for NON, after acked for CON). */ - - separate_active = 0; - } else { - PRINTF("ERROR (transaction)\n"); - } - } /* if (separate_active) */ -} -#endif - -#if REST_RES_LARGE - -/* double expansion */ -#define TO_STRING2(x) #x -#define TO_STRING(x) TO_STRING2(x) +#include "er-coap.h" +#include "er-coap-transactions.h" +#include "er-coap-separate.h" +#include "rest-engine.h" +#include "er-plugtest.h" /* - * Large resource + * Resources to be activated need to be imported through the extern keyword. + * The build system automatically compiles the resources in the corresponding + * sub-directory. */ -RESOURCE(large, METHOD_GET, "large", "title=\"Large resource\";rt=\"block\";sz=\"" TO_STRING(CHUNKS_TOTAL) "\""); - -void -large_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int32_t strpos = 0; - - /* Check the offset for boundaries of the resource data. */ - if (*offset>=CHUNKS_TOTAL) - { - REST.set_response_status(response, REST.status.BAD_OPTION); - /* A block error message should not exceed the minimum block size (16). */ - - const char *error_msg = "BlockOutOfScope"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - /* Generate data until reaching CHUNKS_TOTAL. */ - while (strpos preferred_size) - { - strpos = preferred_size; - } - - /* Truncate if above CHUNKS_TOTAL bytes. */ - if (*offset+(int32_t)strpos > CHUNKS_TOTAL) - { - strpos = CHUNKS_TOTAL - *offset; - } - - REST.set_response_payload(response, buffer, strpos); - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - - /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ - *offset += strpos; - - /* Signal end of resource representation. */ - if (*offset>=CHUNKS_TOTAL) - { - *offset = -1; - } -} -#endif - -#if REST_RES_LARGE_UPDATE -/* - * Large resource that can be updated using PUT method - */ -RESOURCE(large_update, METHOD_GET|METHOD_PUT, "large-update", "title=\"Large resource that can be updated using PUT method\";rt=\"block\";sz=\"" TO_STRING(MAX_PLUGFEST_BODY) "\""); - -static int32_t large_update_size = 0; -static uint8_t large_update_store[MAX_PLUGFEST_BODY] = {0}; -static unsigned int large_update_ct = -1; - -void -large_update_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - uint8_t method = REST.get_method_type(request); - - if (method & METHOD_GET) - { - /* Check the offset for boundaries of the resource data. */ - if (*offset>=large_update_size) - { - REST.set_response_status(response, REST.status.BAD_OPTION); - /* A block error message should not exceed the minimum block size (16). */ - - const char *error_msg = "BlockOutOfScope"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - REST.set_response_payload(response, large_update_store+*offset, MIN(large_update_size - *offset, preferred_size)); - REST.set_header_content_type(response, large_update_ct); - - /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ - *offset += preferred_size; - - /* Signal end of resource representation. */ - if (*offset>=large_update_size) - { - *offset = -1; - } - } else { - uint8_t *incoming = NULL; - size_t len = 0; - - unsigned int ct = REST.get_header_content_type(request); - if (ct==-1) - { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoContentType"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - if ((len = REST.get_request_payload(request, (const uint8_t **) &incoming))) - { - if (coap_req->block1_num*coap_req->block1_size+len <= sizeof(large_update_store)) - { - memcpy(large_update_store+coap_req->block1_num*coap_req->block1_size, incoming, len); - large_update_size = coap_req->block1_num*coap_req->block1_size+len; - large_update_ct = REST.get_header_content_type(request); - - REST.set_response_status(response, REST.status.CHANGED); - coap_set_header_block1(response, coap_req->block1_num, 0, coap_req->block1_size); - } - else - { - REST.set_response_status(response, REST.status.REQUEST_ENTITY_TOO_LARGE); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "%uB max.", sizeof(large_update_store))); - return; - } - } - else - { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoPayload"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - } -} -#endif - -#if REST_RES_LARGE_CREATE -/* - * Large resource that can be created using POST method - */ -RESOURCE(large_create, METHOD_POST, "large-create", "title=\"Large resource that can be created using POST method\";rt=\"block\""); - -void -large_create_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - uint8_t *incoming = NULL; - size_t len = 0; - - unsigned int ct = REST.get_header_content_type(request); - if (ct==-1) - { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoContentType"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - if ((len = REST.get_request_payload(request, (const uint8_t **) &incoming))) - { - if (coap_req->block1_num*coap_req->block1_size+len <= 2048) - { - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "/nirvana"); - coap_set_header_block1(response, coap_req->block1_num, 0, coap_req->block1_size); - } - else - { - REST.set_response_status(response, REST.status.REQUEST_ENTITY_TOO_LARGE); - const char *error_msg = "2048B max."; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - } - else - { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoPayload"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } -} -#endif - -#if REST_RES_OBS - -#if WITH_COAP == 12 -#include "er-coap-12-observing.h" -#elif WITH_COAP == 13 -#include "er-coap-13-observing.h" -#endif -/* - * Observable resource which changes every 5 seconds - */ -PERIODIC_RESOURCE(obs, METHOD_GET|METHOD_PUT|METHOD_DELETE, "obs", "title=\"Observable resource which changes every 5 seconds\";obs", 5*CLOCK_SECOND); - -static uint16_t obs_counter = 0; -static char obs_content[MAX_PLUGFEST_BODY]; -static size_t obs_content_len = 0; -static unsigned int obs_format = 0; - -static char obs_status = 0; - -static -void -obs_purge_list() -{ - PRINTF("### SERVER ACTION ### Purging obs list"); - coap_remove_observer_by_url(NULL, 0, resource_obs.url); -} - -void -obs_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - uint8_t method = request==NULL ? METHOD_GET : REST.get_method_type(request); - - /* Keep server log clean from ticking events */ - if (request!=NULL) - { - PRINTF("/obs "); - } - - if (method & METHOD_GET) - { - /* Keep server log clean from ticking events */ - if (request!=NULL) - { - PRINTF("GET "); - } - - REST.set_header_content_type(response, obs_format); - REST.set_header_max_age(response, 5); - - if (obs_content_len) - { - REST.set_header_content_type(response, obs_format); - REST.set_response_payload(response, obs_content, obs_content_len); - } - else - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, obs_content, snprintf(obs_content, MAX_PLUGFEST_PAYLOAD, "TICK %lu", obs_counter)); - } - /* A post_handler that handles subscriptions will be called for periodic resources by the REST framework. */ - } - else if (method & METHOD_PUT) - { - uint8_t *incoming = NULL; - unsigned int ct = REST.get_header_content_type(request); - - PRINTF("PUT "); - - if (ct!=obs_format) - { - obs_status = 1; - - obs_format = ct; - } else { - - obs_format = ct; - obs_content_len = REST.get_request_payload(request, (const uint8_t **) &incoming); - memcpy(obs_content, incoming, obs_content_len); - obs_periodic_handler(&resource_obs); - } - - REST.set_response_status(response, REST.status.CHANGED); - } - else if (method & METHOD_DELETE) - { - PRINTF("DELETE "); - - obs_status = 2; - - REST.set_response_status(response, REST.status.DELETED); - } - - /* Keep server log clean from ticking events */ - if (request!=NULL) - { - PRINTF("\n"); - } -} - -/* - * Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE. - * It will be called by the REST manager process with the defined period. - */ -void -obs_periodic_handler(resource_t *r) -{ - ++obs_counter; - - //PRINTF("TICK %u for /%s\n", obs_counter, r->url); - - if (obs_status==1) - { - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_NON, INTERNAL_SERVER_ERROR_5_00, 0 ); - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(&resource_obs, -1, notification); - - PRINTF("######### sending 5.00\n"); - - obs_purge_list(); - } - else if (obs_status==2) - { - - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_NON, NOT_FOUND_4_04, 0 ); - - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(&resource_obs, -1, notification); - - obs_purge_list(); - - obs_counter = 0; - obs_content_len = 0; - } - else - { - /* Build notification. */ - /*TODO: REST.new_response() */ - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_NON, CONTENT_2_05, 0 ); - - /* Better use a generator function for both handlers that only takes *resonse. */ - obs_handler(NULL, notification, NULL, 0, NULL); - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(r, obs_counter, notification); - } - obs_status = 0; -} -#endif - -#if REST_RES_MIRROR -/* This resource mirrors the incoming request. It shows how to access the options and how to set them for the response. */ -RESOURCE(mirror, METHOD_GET | METHOD_POST | METHOD_PUT | METHOD_DELETE, "debug/mirror", "title=\"Returns your decoded message\";rt=\"Debug\""); - -void -mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - /* The ETag and Token is copied to the header. */ - uint8_t opaque[] = {0x0A, 0xBC, 0xDE}; - - /* Strings are not copied, so use static string buffers or strings in .text memory (char *str = "string in .text";). */ - static char location[] = {'/','f','/','a','?','k','&','e', 0}; - - /* Getter for the header option Content-Type. If the option is not set, text/plain is returned by default. */ - unsigned int content_type = REST.get_header_content_type(request); - - /* The other getters copy the value (or string/array pointer) to the given pointers and return 1 for success or the length of strings/arrays. */ - uint32_t max_age_and_size = 0; - const char *str = NULL; - uint32_t observe = 0; - const uint8_t *bytes = NULL; - const uint16_t *words = NULL; - uint32_t block_num = 0; - uint8_t block_more = 0; - uint16_t block_size = 0; - const char *query = ""; - int len = 0; - - /* Mirror the received header options in the response payload. Unsupported getters (e.g., rest_get_header_observe() with HTTP) will return 0. */ - - int strpos = 0; - /* snprintf() counts the terminating '\0' to the size parameter. - * The additional byte is taken care of by allocating REST_MAX_CHUNK_SIZE+1 bytes in the REST framework. - * Add +1 to fill the complete buffer, as the payload does not need a terminating '\0'. */ - - - if (strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_header_if_match(request, &bytes))) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "If-Match 0x"); - int index = 0; - for (index = 0; index= REST_MAX_CHUNK_SIZE) - { - buffer[REST_MAX_CHUNK_SIZE-1] = 0xBB; /* '»' to indicate truncation */ - } - - REST.set_response_payload(response, buffer, strpos); - - PRINTF("/mirror options received: %s\n", buffer); - - /* Set dummy header options for response. Like getters, some setters are not implemented for HTTP and have no effect. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_header_max_age(response, 17); /* For HTTP, browsers will not re-request the page for 17 seconds. */ - REST.set_header_etag(response, opaque, 2); - REST.set_header_location(response, location); /* Initial slash is omitted by framework */ - REST.set_header_length(response, strpos); /* For HTTP, browsers will not re-request the page for 10 seconds. CoAP action depends on the client. */ - -/* CoAP-specific example: actions not required for normal RESTful Web service. */ - coap_set_header_uri_host(response, "Contiki"); - coap_set_header_observe(response, 10); - coap_set_header_proxy_uri(response, "ftp://x"); - //coap_set_header_block2(response, 42, 0, 64); - //coap_set_header_block1(response, 23, 0, 16); - coap_set_header_accept(response, APPLICATION_XML); - coap_set_header_accept(response, APPLICATION_ATOM_XML); - coap_set_header_if_none_match(response); -} -#endif /* REST_RES_MIRROR */ - - - - +extern resource_t + res_plugtest_test, + res_plugtest_validate, + res_plugtest_create1, + res_plugtest_create2, + res_plugtest_create3, + res_plugtest_longpath, + res_plugtest_query, + res_plugtest_locquery, + res_plugtest_multi, + res_plugtest_link1, + res_plugtest_link2, + res_plugtest_link3, + res_plugtest_path, + res_plugtest_separate, + res_plugtest_large, + res_plugtest_large_update, + res_plugtest_large_create, + res_plugtest_obs, + res_mirror; PROCESS(plugtest_server, "PlugtestServer"); AUTOSTART_PROCESSES(&plugtest_server); @@ -1240,59 +98,31 @@ PROCESS_THREAD(plugtest_server, ev, data) rest_init_engine(); /* Activate the application-specific resources. */ -#if REST_RES_TEST - rest_activate_resource(&resource_test); - rest_activate_resource(&resource_validate); - rest_activate_resource(&resource_create1); - rest_activate_resource(&resource_create2); - rest_activate_resource(&resource_create3); -#endif -#if REST_RES_LONG - rest_activate_resource(&resource_longpath); -#endif -#if REST_RES_QUERY - rest_activate_resource(&resource_query); -#endif -#if REST_RES_LOC_QUERY - rest_activate_resource(&resource_locquery); -#endif -#if REST_RES_MULTI - rest_activate_resource(&resource_multi); -#endif -#if REST_RES_LINKS - rest_activate_resource(&resource_link1); - rest_activate_resource(&resource_link2); - rest_activate_resource(&resource_link3); -#endif -#if REST_RES_PATH - rest_activate_resource(&resource_path); -#endif -#if REST_RES_SEPARATE - rest_activate_periodic_resource(&periodic_resource_separate); -#endif -#if REST_RES_LARGE - rest_activate_resource(&resource_large); -#endif -#if REST_RES_LARGE_UPDATE - large_update_ct = REST.type.APPLICATION_OCTET_STREAM; - rest_activate_resource(&resource_large_update); -#endif -#if REST_RES_LARGE_CREATE - rest_activate_resource(&resource_large_create); -#endif -#if REST_RES_OBS - rest_activate_periodic_resource(&periodic_resource_obs); -#endif + rest_activate_resource(&res_plugtest_test, "test"); + rest_activate_resource(&res_plugtest_validate, "validate"); + rest_activate_resource(&res_plugtest_create1, "create1"); + rest_activate_resource(&res_plugtest_create2, "create2"); + rest_activate_resource(&res_plugtest_create3, "create3"); + rest_activate_resource(&res_plugtest_longpath, "seg1/seg2/seg3"); + rest_activate_resource(&res_plugtest_query, "query"); + rest_activate_resource(&res_plugtest_locquery, "location-query"); + rest_activate_resource(&res_plugtest_multi, "multi-format"); + rest_activate_resource(&res_plugtest_link1, "link1"); + rest_activate_resource(&res_plugtest_link2, "link2"); + rest_activate_resource(&res_plugtest_link3, "link3"); + rest_activate_resource(&res_plugtest_path, "path"); + rest_activate_resource(&res_plugtest_separate, "separate"); + rest_activate_resource(&res_plugtest_large, "large"); + rest_activate_resource(&res_plugtest_large_update, "large-update"); + rest_activate_resource(&res_plugtest_large_create, "large-create"); + rest_activate_resource(&res_plugtest_obs, "obs"); -#if REST_RES_MIRROR - rest_activate_resource(&resource_mirror); -#endif + rest_activate_resource(&res_mirror, "mirror"); /* Define application-specific events here. */ while(1) { PROCESS_WAIT_EVENT(); - - } /* while (1) */ + } /* while (1) */ PROCESS_END(); } diff --git a/examples/osd/er-rest-example-merkurboard/er-plugtest.h b/examples/osd/er-rest-example-merkurboard/er-plugtest.h new file mode 100644 index 000000000..0b156656a --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/er-plugtest.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Erbium (Er) CoAP client example + * \author + * Matthias Kovatsch + */ + +#ifndef __ER_PLUGTEST_H__ +#define __ER_PLUGTEST_H__ + +#if !defined(CONTIKI_TARGET_NATIVE) +#warning "Should only be compiled for native!" +#endif + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +/* double expansion */ +#define TO_STRING2(x) # x +#define TO_STRING(x) TO_STRING2(x) + +#define MAX_PLUGFEST_PAYLOAD 64 + 1 /* +1 for the terminating zero, which is not transmitted */ +#define MAX_PLUGFEST_BODY 2048 +#define CHUNKS_TOTAL 2012 + +#endif /* __ER_PLUGTEST_H__ */ diff --git a/examples/osd/er-rest-example-merkurboard/flash.sh b/examples/osd/er-rest-example-merkurboard/flash.sh index e92d472f6..e82962073 100755 --- a/examples/osd/er-rest-example-merkurboard/flash.sh +++ b/examples/osd/er-rest-example-merkurboard/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-server.osd-merkur.hex:a -U eeprom:w:er-example-server.osd-merkur.eep:a +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/er-rest-example-merkurboard/flashclient.sh b/examples/osd/er-rest-example-merkurboard/flashclient.sh index 30979eed4..a0fb33cf7 100755 --- a/examples/osd/er-rest-example-merkurboard/flashclient.sh +++ b/examples/osd/er-rest-example-merkurboard/flashclient.sh @@ -1,2 +1,2 @@ #!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-client.osd-merkur.hex:a -U eeprom:w:er-example-client.osd-merkur.eep:a +sudo make flash-client diff --git a/examples/osd/er-rest-example-merkurboard/project-conf.h b/examples/osd/er-rest-example-merkurboard/project-conf.h index 2187b48c7..cc76cc181 100644 --- a/examples/osd/er-rest-example-merkurboard/project-conf.h +++ b/examples/osd/er-rest-example-merkurboard/project-conf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Matthias Kovatsch + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,74 +26,74 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * + * This file is part of the Contiki operating system. */ -#ifndef PROJECT_ERBIUM_CONF_H_ -#define PROJECT_ERBIUM_CONF_H_ +/** + * \file + * Erbium (Er) example project configuration. + * \author + * Matthias Kovatsch + */ -#define PLATFORM_HAS_LEDS 1 -#define PLATFORM_HAS_BUTTON 1 -#define PLATFORM_HAS_TEMPERATURE 1 -#define PLATFORM_HAS_BATTERY 1 +#ifndef __PROJECT_ERBIUM_CONF_H__ +#define __PROJECT_ERBIUM_CONF_H__ -/* Some platforms have weird includes. */ -// #undef IEEE802154_CONF_PANID -// #define IEEE802154_CONF_PANID 0xAAAA + #define PLATFORM_HAS_LEDS 1 + #define PLATFORM_HAS_BATTERY 1 -/* Disabling RDC for demo purposes. Core updates often require more memory. */ -/* For projects, optimize memory and enable RDC again. */ -// #undef NETSTACK_CONF_RDC -//#define NETSTACK_CONF_RDC nullrdc_driver +/* Custom channel and PAN ID configuration for your project. */ +/* + #undef RF_CHANNEL + #define RF_CHANNEL 26 + + #undef IEEE802154_CONF_PANID + #define IEEE802154_CONF_PANID 0xABCD + */ + +/* IP buffer size must match all other hops, in particular the border router. */ + + #undef UIP_CONF_BUFFER_SIZE + #define UIP_CONF_BUFFER_SIZE 256 + + +/* Disabling RDC and CSMA for demo purposes. Core updates often + require more memory. */ +/* For projects, optimize memory and enable RDC and CSMA again. */ +//#undef NETSTACK_CONF_RDC +//#define NETSTACK_CONF_RDC nullrdc_driver + +/* Disabling TCP on CoAP nodes. */ +#undef UIP_CONF_TCP +#define UIP_CONF_TCP 0 + +//#undef NETSTACK_CONF_MAC +//#define NETSTACK_CONF_MAC nullmac_driver /* Increase rpl-border-router IP-buffer when using more than 64. */ #undef REST_MAX_CHUNK_SIZE -#define REST_MAX_CHUNK_SIZE 64 +#define REST_MAX_CHUNK_SIZE 64 /* Estimate your header size, especially when using Proxy-Uri. */ /* -#undef COAP_MAX_HEADER_SIZE -#define COAP_MAX_HEADER_SIZE 70 -*/ - -/* The IP buffer size must fit all other hops, in particular the border router. */ - -#undef UIP_CONF_BUFFER_SIZE -#define UIP_CONF_BUFFER_SIZE 256 - + #undef COAP_MAX_HEADER_SIZE + #define COAP_MAX_HEADER_SIZE 70 + */ /* Multiplies with chunk size, be aware of memory constraints. */ #undef COAP_MAX_OPEN_TRANSACTIONS -#define COAP_MAX_OPEN_TRANSACTIONS 4 +#define COAP_MAX_OPEN_TRANSACTIONS 4 -/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* Must be <= open transactions, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ /* -#undef COAP_MAX_OBSERVERS -#define COAP_MAX_OBSERVERS 2 -*/ + #undef COAP_MAX_OBSERVERS + #define COAP_MAX_OBSERVERS 2 + */ /* Filtering .well-known/core per query can be disabled to save space. */ -/* #undef COAP_LINK_FORMAT_FILTERING -#define COAP_LINK_FORMAT_FILTERING 0 -*/ +#define COAP_LINK_FORMAT_FILTERING 0 +#undef COAP_PROXY_OPTION_PROCESSING +#define COAP_PROXY_OPTION_PROCESSING 0 -/* Save some memory for the sky platform. */ -/* -#undef NBR_TABLE_CONF_MAX_NEIGHBORS -#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 -#undef UIP_CONF_MAX_ROUTES -#define UIP_CONF_MAX_ROUTES 10 -*/ - -/* Reduce 802.15.4 frame queue to save RAM. */ -/* -#undef QUEUEBUF_CONF_NUM -#define QUEUEBUF_CONF_NUM 4 -*/ - -/* -#undef SICSLOWPAN_CONF_FRAG -#define SICSLOWPAN_CONF_FRAG 1 -*/ -#endif /* PROJECT_ERBIUM_CONF_H_ */ +#endif /* __PROJECT_ERBIUM_CONF_H__ */ diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-b1-sep-b2.c b/examples/osd/er-rest-example-merkurboard/resources/res-b1-sep-b2.c new file mode 100644 index 000000000..be4d8f943 --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-b1-sep-b2.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Lars Schmertmann + */ + +#include +#include "rest-engine.h" +#include "er-coap-block1.h" +#include "er-coap-separate.h" +#include "er-coap-transactions.h" + +static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +SEPARATE_RESOURCE(res_b1_sep_b2, "title=\"Block1 + Separate + Block2 demo\"", NULL, res_post_handler, NULL, NULL, NULL); + +#define MAX_DATA_LEN 256 + +static uint8_t big_msg[MAX_DATA_LEN]; +static size_t big_msg_len = 0; +static coap_separate_t request_metadata; + +static void +res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* Example allows only one request on time. There are no checks for multiply access !!! */ + if(*offset == 0) { + /* Incoming Data */ + if(coap_block1_handler(request, response, big_msg, &big_msg_len, MAX_DATA_LEN)) { + /* More Blocks will follow. Example waits for + * the last block and stores data into big_msg. + */ + return; + } + /* Last block was received. */ + coap_separate_accept(request, &request_metadata); + + /* Need Time for calculation now */ + uint32_t i; + for(i = 0; i <= 4096; i++) { + printf("\r% 4u\r", i); + } + printf("\n"); + + /* Send first block */ + coap_transaction_t *transaction = NULL; + if((transaction = coap_new_transaction(request_metadata.mid, &request_metadata.addr, request_metadata.port))) { + coap_packet_t resp[1]; /* This way the packet can be treated as pointer as usual. */ + + /* Restore the request information for the response. */ + coap_separate_resume(resp, &request_metadata, CONTENT_2_05); + + /* Set payload and block info */ + coap_set_payload(resp, big_msg, big_msg_len > request_metadata.block2_size ? request_metadata.block2_size : big_msg_len); + if(big_msg_len > request_metadata.block2_size) { + coap_set_header_block2(resp, 0, 1, request_metadata.block2_size); + } + + /* Warning: No check for serialization error. */ + transaction->packet_len = coap_serialize_message(resp, transaction->packet); + coap_send_transaction(transaction); + } + } else { + /* request for more blocks */ + if(*offset >= big_msg_len) { + coap_set_status_code(response, BAD_OPTION_4_02); + coap_set_payload(response, "BlockOutOfScope", 15); + return; + } + + memcpy(buffer, big_msg + *offset, 32); + if(big_msg_len - *offset < preferred_size) { + preferred_size = big_msg_len - *offset; + *offset = -1; + } else { + *offset += preferred_size; + } + coap_set_payload(response, buffer, preferred_size); + } +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-chunks.c b/examples/osd/er-rest-example-merkurboard/resources/res-chunks.c new file mode 100644 index 000000000..79ad55094 --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-chunks.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* + * For data larger than REST_MAX_CHUNK_SIZE (e.g., when stored in flash) resources must be aware of the buffer limitation + * and split their responses by themselves. To transfer the complete resource through a TCP stream or CoAP's blockwise transfer, + * the byte offset where to continue is provided to the handler as int32_t pointer. + * These chunk-wise resources must set the offset value to its new position or -1 of the end is reached. + * (The offset for CoAP's blockwise transfer can go up to 2'147'481'600 = ~2047 M for block size 2048 (reduced to 1024 in observe-03.) + */ +RESOURCE(res_chunks, + "title=\"Blockwise demo\";rt=\"Data\"", + res_get_handler, + NULL, + NULL, + NULL); + +#define CHUNKS_TOTAL 2050 + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + int32_t strpos = 0; + + /* Check the offset for boundaries of the resource data. */ + if(*offset >= CHUNKS_TOTAL) { + REST.set_response_status(response, REST.status.BAD_OPTION); + /* A block error message should not exceed the minimum block size (16). */ + + const char *error_msg = "BlockOutOfScope"; + REST.set_response_payload(response, error_msg, strlen(error_msg)); + return; + } + + /* Generate data until reaching CHUNKS_TOTAL. */ + while(strpos < preferred_size) { + strpos += snprintf((char *)buffer + strpos, preferred_size - strpos + 1, "|%ld|", *offset); + } + + /* snprintf() does not adjust return value if truncated by size. */ + if(strpos > preferred_size) { + strpos = preferred_size; + /* Truncate if above CHUNKS_TOTAL bytes. */ + } + if(*offset + (int32_t)strpos > CHUNKS_TOTAL) { + strpos = CHUNKS_TOTAL - *offset; + } + REST.set_response_payload(response, buffer, strpos); + + /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ + *offset += strpos; + + /* Signal end of resource representation. */ + if(*offset >= CHUNKS_TOTAL) { + *offset = -1; + } +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-event.c b/examples/osd/er-rest-example-merkurboard/resources/res-event.c new file mode 100644 index 000000000..d20f0caa9 --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-event.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_event_handler(); + +/* + * Example for an event resource. + * Additionally takes a period parameter that defines the interval to call [name]_periodic_handler(). + * A default post_handler takes care of subscriptions and manages a list of subscribers to notify. + */ +EVENT_RESOURCE(res_event, + "title=\"Event demo\";obs", + res_get_handler, + NULL, + NULL, + NULL, + res_event_handler); + +/* + * Use local resource state that is accessed by res_get_handler() and altered by res_event_handler() or PUT or POST. + */ +static int32_t event_counter = 0; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "EVENT %lu", event_counter)); + + /* A post_handler that handles subscriptions/observing will be called for periodic resources by the framework. */ +} +/* + * Additionally, res_event_handler must be implemented for each EVENT_RESOURCE. + * It is called through .trigger(), usually from the server process. + */ +static void +res_event_handler() +{ + /* Do the update triggered by the event here, e.g., sampling a sensor. */ + ++event_counter; + + /* Usually a condition is defined under with subscribers are notified, e.g., event was above a threshold. */ + if(1) { + PRINTF("TICK %u for /%s\n", event_counter, res_event.url); + + /* Notify the registered observers which will trigger the res_get_handler to create the response. */ + REST.notify_subscribers(&res_event); + } +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-hello.c b/examples/osd/er-rest-example-merkurboard/resources/res-hello.c new file mode 100644 index 000000000..9208f8b74 --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-hello.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include +#include "rest-engine.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* + * A handler function named [resource name]_handler must be implemented for each RESOURCE. + * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore + * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. + * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. + */ +RESOURCE(res_hello, + "title=\"Hello world: ?len=0..\";rt=\"Text\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const char *len = NULL; + /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ + char const *const message = "Hello World! ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy"; + int length = 12; /* |<-------->| */ + + /* The query string can be retrieved by rest_get_query() or parsed for its key-value pairs. */ + if(REST.get_query_variable(request, "len", &len)) { + length = atoi(len); + if(length < 0) { + length = 0; + } + if(length > REST_MAX_CHUNK_SIZE) { + length = REST_MAX_CHUNK_SIZE; + } + memcpy(buffer, message, length); + } else { + memcpy(buffer, message, length); + } REST.set_header_content_type(response, REST.type.TEXT_PLAIN); /* text/plain is the default, hence this option could be omitted. */ + REST.set_header_etag(response, (uint8_t *)&length, 1); + REST.set_response_payload(response, buffer, length); +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-light.c b/examples/osd/er-rest-example-merkurboard/resources/res-light.c new file mode 100644 index 000000000..226d814bb --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-light.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include "contiki.h" + +#if PLATFORM_HAS_LIGHT + +#include +#include "rest-engine.h" +#include "dev/light-sensor.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from light sensor with a simple etag */ +RESOURCE(res_light, + "title=\"Photosynthetic and solar light (supports JSON)\";rt=\"LightSensor\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + uint16_t light_photosynthetic = light_sensor.value(LIGHT_SENSOR_PHOTOSYNTHETIC); + uint16_t light_solar = light_sensor.value(LIGHT_SENSOR_TOTAL_SOLAR); + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%u;%u", light_photosynthetic, light_solar); + + REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_XML) { + REST.set_header_content_type(response, REST.type.APPLICATION_XML); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "", light_photosynthetic, light_solar); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'light':{'photosynthetic':%u,'solar':%u}}", light_photosynthetic, light_solar); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain, application/xml, and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} +#endif /* PLATFORM_HAS_LIGHT */ diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-mirror.c b/examples/osd/er-rest-example-merkurboard/resources/res-mirror.c new file mode 100644 index 000000000..e33bda6d3 --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-mirror.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +static void res_any_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* This resource mirrors the incoming request. It shows how to access the options and how to set them for the response. */ +RESOURCE(res_mirror, + "title=\"Returns your decoded message\";rt=\"Debug\"", + res_any_handler, + res_any_handler, + res_any_handler, + res_any_handler); + +static void +res_any_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* The ETag and Token is copied to the header. */ + uint8_t opaque[] = { 0x0A, 0xBC, 0xDE }; + + /* Strings are not copied, so use static string buffers or strings in .text memory (char *str = "string in .text";). */ + static char location[] = { '/', 'f', '/', 'a', '?', 'k', '&', 'e', 0 }; + + /* No default my be assumed for the Content-Format. (Unsigned -1 means all bits set.) */ + unsigned int content_format = -1; + + /* The other getters copy the value (or string/array pointer) to the given pointers and return 1 for success or the length of strings/arrays. */ + uint32_t longint = 0; + const char *str = NULL; + const uint8_t *bytes = NULL; + uint32_t block_num = 0; + uint8_t block_more = 0; + uint16_t block_size = 0; + int len = 0; + + /* Mirror the received header options in the response payload. Unsupported getters (e.g., rest_get_header_observe() with HTTP) will return 0. */ + + int strpos = 0; + /* snprintf() counts the terminating '\0' to the size parameter. + * The additional byte is taken care of by allocating REST_MAX_CHUNK_SIZE+1 bytes in the REST framework. + * Add +1 to fill the complete buffer, as the payload does not need a terminating '\0'. */ + if(REST.get_header_content_type(request, &content_format)) { + strpos += snprintf((char *)buffer, REST_MAX_CHUNK_SIZE + 1, "CF %u\n", content_format); + } + if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_header_accept(request, &content_format))) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "Ac %u\n", content_format); + /* Some getters such as for ETag or Location are omitted, as these options should not appear in a request. + * Max-Age might appear in HTTP requests or used for special purposes in CoAP. */ + } + if(strpos <= REST_MAX_CHUNK_SIZE && REST.get_header_max_age(request, &longint)) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "MA %lu\n", longint); + /* For HTTP this is the Length option, for CoAP it is the Size option. */ + } + if(strpos <= REST_MAX_CHUNK_SIZE && REST.get_header_length(request, &longint)) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "SZ %lu\n", longint); + } + if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_header_host(request, &str))) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "UH %.*s\n", len, str); + } + if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_url(request, &str))) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "UP %.*s\n", len, str); + } + if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_query(request, &str))) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "UQ %.*s\n", len, str); + /* Undefined request options for debugging: actions not required for normal RESTful Web service. */ + } + if(strpos <= REST_MAX_CHUNK_SIZE && (len = coap_get_header_location_path(request, &str))) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "LP %.*s\n", len, str); + } + if(strpos <= REST_MAX_CHUNK_SIZE && (len = coap_get_header_location_query(request, &str))) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "LQ %.*s\n", len, str); + /* CoAP-specific example: actions not required for normal RESTful Web service. */ + } + coap_packet_t *const coap_pkt = (coap_packet_t *)request; + + if(strpos <= REST_MAX_CHUNK_SIZE && coap_pkt->token_len > 0) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "To 0x"); + int index = 0; + for(index = 0; index < coap_pkt->token_len; ++index) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "%02X", coap_pkt->token[index]); + } + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "\n"); + } + + if(strpos <= REST_MAX_CHUNK_SIZE && IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "Ob %lu\n", coap_pkt->observe); + } + if(strpos <= REST_MAX_CHUNK_SIZE && IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "ET 0x"); + int index = 0; + for(index = 0; index < coap_pkt->etag_len; ++index) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "%02X", coap_pkt->etag[index]); + } + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "\n"); + } + if(strpos <= REST_MAX_CHUNK_SIZE && coap_get_header_block2(request, &block_num, &block_more, &block_size, NULL)) { /* This getter allows NULL pointers to get only a subset of the block parameters. */ + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "B2 %lu%s (%u)\n", block_num, block_more ? "+" : "", block_size); + } + if(strpos <= REST_MAX_CHUNK_SIZE && coap_get_header_block1(request, &block_num, &block_more, &block_size, NULL)) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "B1 %lu%s (%u)\n", block_num, block_more ? "+" : "", block_size); + } + if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_request_payload(request, &bytes))) { + strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "%.*s", len, bytes); + } + if(strpos >= REST_MAX_CHUNK_SIZE) { + buffer[REST_MAX_CHUNK_SIZE - 1] = 0xBB; /* '»' to indicate truncation */ + } + REST.set_response_payload(response, buffer, strpos); + + PRINTF("/mirror options received: %s\n", buffer); + + /* Set dummy header options for response. Like getters, some setters are not implemented for HTTP and have no effect. */ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_header_max_age(response, 17); /* For HTTP, browsers will not re-request the page for 17 seconds. */ + REST.set_header_etag(response, opaque, 2); + REST.set_header_location(response, location); /* Initial slash is omitted by framework */ + REST.set_header_length(response, strpos); /* For HTTP, browsers will not re-request the page for 10 seconds. CoAP action depends on the client. */ + +/* CoAP-specific example: actions not required for normal RESTful Web service. */ + coap_set_header_uri_host(response, "tiki"); + coap_set_header_observe(response, 10); + coap_set_header_proxy_uri(response, "ftp://x"); + coap_set_header_block2(response, 42, 0, 64); /* The block option might be overwritten by the framework when blockwise transfer is requested. */ + coap_set_header_block1(response, 23, 0, 16); + coap_set_header_accept(response, TEXT_PLAIN); + coap_set_header_if_none_match(response); +} diff --git a/apps/er-coap-03/er-coap-03-transactions.h b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-create1.c similarity index 55% rename from apps/er-coap-03/er-coap-03-transactions.h rename to examples/osd/er-rest-example-merkurboard/resources/res-plugtest-create1.c index b109fa992..4ba5f6181 100644 --- a/apps/er-coap-03/er-coap-03-transactions.h +++ b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-create1.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Institute for Pervasive Computing, ETH Zurich + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,48 +31,50 @@ /** * \file - * CoAP module for reliable transport + * ETSI Plugtest resource * \author * Matthias Kovatsch */ -#ifndef COAP_TRANSACTIONS_H_ -#define COAP_TRANSACTIONS_H_ +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" -#include "er-coap-03.h" +static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); -/* - * The number of concurrent messages that can be stored for retransmission in the transaction layer. - */ -#ifndef COAP_MAX_OPEN_TRANSACTIONS -#define COAP_MAX_OPEN_TRANSACTIONS 4 -#endif /* COAP_MAX_OPEN_TRANSACTIONS */ +RESOURCE(res_plugtest_create1, + "title=\"Creates on PUT\"", + NULL, + NULL, + res_put_handler, + res_delete_handler); -/* container for transactions with message buffer and retransmission info */ -typedef struct coap_transaction { - struct coap_transaction *next; /* for LIST */ +static uint8_t create1_exists = 0; - uint16_t tid; - struct etimer retrans_timer; - uint8_t retrans_counter; +static void +res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + PRINTF("/create1 PUT"); - uip_ipaddr_t addr; - uint16_t port; + if(coap_get_header_if_none_match(request)) { + if(!create1_exists) { + REST.set_response_status(response, REST.status.CREATED); - restful_response_handler callback; - void *callback_data; + create1_exists = 1; + } else { + REST.set_response_status(response, PRECONDITION_FAILED_4_12); + } + } else { + REST.set_response_status(response, REST.status.CHANGED); + } +} +static void +res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + PRINTF("/create1 DELETE "); + REST.set_response_status(response, REST.status.DELETED); - uint16_t packet_len; - uint8_t packet[COAP_MAX_PACKET_SIZE+1]; /* +1 for the terminating '\0' to simply and savely use snprintf(buf, len+1, "", ...) in the resource handler. */ -} coap_transaction_t; - -void coap_register_as_transaction_handler(); - -coap_transaction_t *coap_new_transaction(uint16_t tid, uip_ipaddr_t *addr, uint16_t port); -void coap_send_transaction(coap_transaction_t *t); -void coap_clear_transaction(coap_transaction_t *t); -coap_transaction_t *coap_get_transaction_by_tid(uint16_t tid); - -void coap_check_transactions(); - -#endif /* COAP_TRANSACTIONS_H_ */ + create1_exists = 0; +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-create2.c b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-create2.c new file mode 100644 index 000000000..25877ac70 --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-create2.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_create2, + "title=\"Creates on POST\"", + NULL, + res_post_handler, + NULL, + NULL); + +static void +res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + PRINTF("/create2 "); + + REST.set_response_status(response, REST.status.CREATED); + REST.set_header_location(response, "/location1/location2/location3"); +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-create3.c b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-create3.c new file mode 100644 index 000000000..2498c065a --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-create3.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_create3, + "title=\"Default test resource\"", + NULL, + NULL, + res_put_handler, + res_delete_handler); + +static uint8_t create3_exists = 0; + +static void +res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + PRINTF("/create3 PUT "); + + if(coap_get_header_if_none_match(request)) { + if(!create3_exists) { + REST.set_response_status(response, REST.status.CREATED); + + create3_exists = 1; + } else { + REST.set_response_status(response, PRECONDITION_FAILED_4_12); + } + } else { + REST.set_response_status(response, REST.status.CHANGED); + } +} +static void +res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + PRINTF("/create3 DELETE "); + REST.set_response_status(response, REST.status.DELETED); + + create3_exists = 0; +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-large-create.c b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-large-create.c new file mode 100644 index 000000000..888dfaa31 --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-large-create.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* + * Large resource that can be created using POST method + */ +RESOURCE(res_plugtest_large_create, + "title=\"Large resource that can be created using POST method\";rt=\"block\"", + NULL, + res_post_handler, + NULL, + NULL); + +static void +res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + uint8_t *incoming = NULL; + size_t len = 0; + + unsigned int ct = -1; + + if(!REST.get_header_content_type(request, &ct)) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + const char *error_msg = "NoContentType"; + REST.set_response_payload(response, error_msg, strlen(error_msg)); + return; + } + + if((len = REST.get_request_payload(request, (const uint8_t **)&incoming))) { + if(coap_req->block1_num * coap_req->block1_size + len <= 2048) { + REST.set_response_status(response, REST.status.CREATED); + REST.set_header_location(response, "/nirvana"); + coap_set_header_block1(response, coap_req->block1_num, 0, + coap_req->block1_size); + } else { + REST.set_response_status(response, REST.status.REQUEST_ENTITY_TOO_LARGE); + const char *error_msg = "2048B max."; + REST.set_response_payload(response, error_msg, strlen(error_msg)); + return; + } + } else { + REST.set_response_status(response, REST.status.BAD_REQUEST); + const char *error_msg = "NoPayload"; + REST.set_response_payload(response, error_msg, strlen(error_msg)); + return; + } +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-large-update.c b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-large-update.c new file mode 100644 index 000000000..e48d08b5f --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-large-update.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE( + res_plugtest_large_update, + "title=\"Large resource that can be updated using PUT method\";rt=\"block\";sz=\"" TO_STRING(MAX_PLUGFEST_BODY) "\"", + res_get_handler, + NULL, + res_put_handler, + NULL); + +static int32_t large_update_size = 0; +static uint8_t large_update_store[MAX_PLUGFEST_BODY] = { 0 }; +static unsigned int large_update_ct = APPLICATION_OCTET_STREAM; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* Check the offset for boundaries of the resource data. */ + if(*offset >= large_update_size) { + REST.set_response_status(response, REST.status.BAD_OPTION); + /* A block error message should not exceed the minimum block size (16). */ + + const char *error_msg = "BlockOutOfScope"; + REST.set_response_payload(response, error_msg, strlen(error_msg)); + return; + } + + REST.set_response_payload(response, large_update_store + *offset, + MIN(large_update_size - *offset, preferred_size)); + REST.set_header_content_type(response, large_update_ct); + + /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ + *offset += preferred_size; + + /* Signal end of resource representation. */ + if(*offset >= large_update_size) { + *offset = -1; + } +} +static void +res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + uint8_t *incoming = NULL; + size_t len = 0; + + unsigned int ct = -1; + + if(!REST.get_header_content_type(request, &ct)) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + const char *error_msg = "NoContentType"; + REST.set_response_payload(response, error_msg, strlen(error_msg)); + return; + } + + if((len = REST.get_request_payload(request, (const uint8_t **)&incoming))) { + if(coap_req->block1_num * coap_req->block1_size + len <= sizeof(large_update_store)) { + memcpy( + large_update_store + coap_req->block1_num * coap_req->block1_size, + incoming, len); + large_update_size = coap_req->block1_num * coap_req->block1_size + len; + large_update_ct = ct; + + REST.set_response_status(response, REST.status.CHANGED); + coap_set_header_block1(response, coap_req->block1_num, 0, + coap_req->block1_size); + } else { + REST.set_response_status(response, + REST.status.REQUEST_ENTITY_TOO_LARGE); + REST.set_response_payload( + response, + buffer, + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "%uB max.", + sizeof(large_update_store))); + return; + } + } else { + REST.set_response_status(response, REST.status.BAD_REQUEST); + const char *error_msg = "NoPayload"; + REST.set_response_payload(response, error_msg, strlen(error_msg)); + return; + } +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-large.c b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-large.c new file mode 100644 index 000000000..d997dd927 --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-large.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_large, + "title=\"Large resource\";rt=\"block\";sz=\"" TO_STRING(CHUNKS_TOTAL) "\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + int32_t strpos = 0; + + /* Check the offset for boundaries of the resource data. */ + if(*offset >= CHUNKS_TOTAL) { + REST.set_response_status(response, REST.status.BAD_OPTION); + /* A block error message should not exceed the minimum block size (16). */ + + const char *error_msg = "BlockOutOfScope"; + REST.set_response_payload(response, error_msg, strlen(error_msg)); + return; + } + + /* Generate data until reaching CHUNKS_TOTAL. */ + while(strpos < preferred_size) { + strpos += snprintf((char *)buffer + strpos, preferred_size - strpos + 1, + "|%ld|", *offset); + } + + /* snprintf() does not adjust return value if truncated by size. */ + if(strpos > preferred_size) { + strpos = preferred_size; + /* Truncate if above CHUNKS_TOTAL bytes. */ + } + if(*offset + (int32_t)strpos > CHUNKS_TOTAL) { + strpos = CHUNKS_TOTAL - *offset; + } + REST.set_response_payload(response, buffer, strpos); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + + /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ + *offset += strpos; + + /* Signal end of resource representation. */ + if(*offset >= CHUNKS_TOTAL) { + *offset = -1; + } +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-links.c b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-links.c new file mode 100644 index 000000000..be68aadf7 --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-links.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_link1, + "rt=\"Type1 Type2\";if=\"If1\"", + res_get_handler, + NULL, + NULL, + NULL); +RESOURCE(res_plugtest_link2, + "rt=\"Type2 Type3\";if=\"If2\"", + res_get_handler, + NULL, + NULL, + NULL); +RESOURCE(res_plugtest_link3, + "rt=\"Type1 Type3\";if=\"foo\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const char *msg = "Dummy link"; + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, msg, strlen(msg)); +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-locquery.c b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-locquery.c new file mode 100644 index 000000000..64e79ff25 --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-locquery.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_locquery, + "title=\"Resource accepting query parameters\"", + NULL, + res_post_handler, + NULL, + NULL); + +static void +res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + PRINTF( + "/location-query POST (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + REST.set_response_status(response, REST.status.CREATED); + REST.set_header_location(response, "?first=1&second=2"); +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-longpath.c b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-longpath.c new file mode 100644 index 000000000..d6c4fb855 --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-longpath.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_longpath, + "title=\"Long path resource\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + PRINTF("/seg1/seg2/seg3 GET "); + /* Code 2.05 CONTENT is default. */ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload( + response, + buffer, + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, + "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); + + PRINTF("(%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-multi.c b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-multi.c new file mode 100644 index 000000000..281a2268f --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-multi.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_multi, + "title=\"Resource providing text/plain and application/xml\";ct=\"0 41\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + PRINTF("/multi-format GET (%s %u) ", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload( + response, + buffer, + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, + "Type: %u\nCode: %u\nMID: %u%s", coap_req->type, coap_req->code, + coap_req->mid, accept != -1 ? "\nAccept: 0" : "")); + PRINTF("PLAIN\n"); + } else if(accept == REST.type.APPLICATION_XML) { + REST.set_header_content_type(response, REST.type.APPLICATION_XML); + REST.set_response_payload( + response, + buffer, + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, + "", + coap_req->type, coap_req->code, coap_req->mid, accept)); + PRINTF("XML\n"); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/xml"; + REST.set_response_payload(response, msg, strlen(msg)); + PRINTF("ERROR\n"); + } +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-obs.c b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-obs.c new file mode 100644 index 000000000..e202c2043 --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-obs.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-coap-observe.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_periodic_handler(void); + +PERIODIC_RESOURCE(res_plugtest_obs, + "title=\"Observable resource which changes every 5 seconds\";obs", + res_get_handler, + NULL, + res_put_handler, + res_delete_handler, + 5 * CLOCK_SECOND, + res_periodic_handler); + +static int32_t obs_counter = 0; +static char obs_content[MAX_PLUGFEST_BODY]; +static size_t obs_content_len = 0; +static unsigned int obs_format = 0; + +static char obs_status = 0; + +static void +obs_purge_list() +{ + PRINTF("### SERVER ACTION ### Purging obs list"); + coap_remove_observer_by_uri(NULL, 0, res_plugtest_obs.url); +} +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* Keep server log clean from ticking events */ + if(request != NULL) { + PRINTF("/obs GET\n"); + } + REST.set_header_content_type(response, obs_format); + REST.set_header_max_age(response, 5); + + if(obs_content_len) { + REST.set_header_content_type(response, obs_format); + REST.set_response_payload(response, obs_content, obs_content_len); + } else { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, obs_content, + snprintf(obs_content, MAX_PLUGFEST_PAYLOAD, "TICK %lu", obs_counter)); + } + /* A post_handler that handles subscriptions will be called for periodic resources by the REST framework. */ +} +static void +res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + uint8_t *incoming = NULL; + unsigned int ct = -1; + + REST.get_header_content_type(request, &ct); + + PRINTF("/obs PUT\n"); + + if(ct != obs_format) { + obs_status = 1; + obs_format = ct; + } else { + obs_content_len = REST.get_request_payload(request, + (const uint8_t **)&incoming); + memcpy(obs_content, incoming, obs_content_len); + res_periodic_handler(); + } + + REST.set_response_status(response, REST.status.CHANGED); +} +static void +res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + PRINTF("/obs DELETE\n"); + + obs_status = 2; + + REST.set_response_status(response, REST.status.DELETED); +} +/* + * Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE. + * It will be called by the REST manager process with the defined period. + */ +static void +res_periodic_handler() +{ + ++obs_counter; + + /* PRINTF("TICK %u for /%s\n", obs_counter, r->url); */ + + if(obs_status == 1) { + + /* Notify the registered observers with the given message type, observe option, and payload. */ + REST.notify_subscribers(&res_plugtest_obs); + + PRINTF("######### sending 5.00\n"); + + obs_purge_list(); + } else if(obs_status == 2) { + + /* Notify the registered observers with the given message type, observe option, and payload. */ + REST.notify_subscribers(&res_plugtest_obs); + + obs_purge_list(); + + obs_counter = 0; + obs_content_len = 0; + } else { + /* Notify the registered observers with the given message type, observe option, and payload. */ + REST.notify_subscribers(&res_plugtest_obs); + } obs_status = 0; +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-path.c b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-path.c new file mode 100644 index 000000000..3566a51b9 --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-path.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +PARENT_RESOURCE(res_plugtest_path, + "title=\"Path test resource\";ct=\"40\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + + const char *uri_path = NULL; + int len = REST.get_url(request, &uri_path); + int base_len = strlen(res_plugtest_path.url); + + if(len == base_len) { + REST.set_header_content_type(response, REST.type.APPLICATION_LINK_FORMAT); + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, + ",,"); + } else { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "/%.*s", len, uri_path); + } + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-query.c b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-query.c new file mode 100644 index 000000000..538646c6e --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-query.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_query, + "title=\"Resource accepting query parameters\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + int len = 0; + const char *query = NULL; + + PRINTF( + "/query GET (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + if((len = REST.get_query(request, &query))) { + PRINTF("Query: %.*s\n", len, query); + /* Code 2.05 CONTENT is default. */ + } + REST.set_header_content_type(response, + REST.type.TEXT_PLAIN); + REST.set_response_payload( + response, + buffer, + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, + "Type: %u\nCode: %u\nMID: %u\nQuery: %.*s", coap_req->type, + coap_req->code, coap_req->mid, len, query)); +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-separate.c b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-separate.c new file mode 100644 index 000000000..a32311bba --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-separate.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-coap-transactions.h" +#include "er-coap-separate.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_resume_handler(void); + +PERIODIC_RESOURCE(res_plugtest_separate, + "title=\"Resource which cannot be served immediately and which cannot be acknowledged in a piggy-backed way\"", + res_get_handler, + NULL, + NULL, + NULL, + 3 * CLOCK_SECOND, + res_resume_handler); + +/* A structure to store the required information */ +typedef struct application_separate_store { + /* Provided by Erbium to store generic request information such as remote address and token. */ + coap_separate_t request_metadata; + /* Add fields for addition information to be stored for finalizing, e.g.: */ + char buffer[MAX_PLUGFEST_PAYLOAD]; +} application_separate_store_t; + +static uint8_t separate_active = 0; +static application_separate_store_t separate_store[1]; + +void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + PRINTF("/separate "); + if(separate_active) { + PRINTF("REJECTED "); + coap_separate_reject(); + } else { + PRINTF("STORED "); + separate_active = 1; + + /* Take over and skip response by engine. */ + coap_separate_accept(request, &separate_store->request_metadata); + /* Be aware to respect the Block2 option, which is also stored in the coap_separate_t. */ + + snprintf(separate_store->buffer, MAX_PLUGFEST_PAYLOAD, + "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, + coap_req->mid); + } + + PRINTF("(%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); +} +static void +res_resume_handler() +{ + if(separate_active) { + PRINTF("/separate "); + coap_transaction_t *transaction = NULL; + if((transaction = coap_new_transaction(separate_store->request_metadata.mid, + &separate_store->request_metadata.addr, + separate_store->request_metadata.port))) { + PRINTF( + "RESPONSE (%s %u)\n", separate_store->request_metadata.type == COAP_TYPE_CON ? "CON" : "NON", separate_store->request_metadata.mid); + + coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */ + + /* Restore the request information for the response. */ + coap_separate_resume(response, &separate_store->request_metadata, CONTENT_2_05); + + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + coap_set_payload(response, separate_store->buffer, + strlen(separate_store->buffer)); + + /* + * Be aware to respect the Block2 option, which is also stored in the coap_separate_t. + * As it is a critical option, this example resource pretends to handle it for compliance. + */ + coap_set_header_block2(response, + separate_store->request_metadata.block2_num, 0, + separate_store->request_metadata.block2_size); + + /* Warning: No check for serialization error. */ + transaction->packet_len = coap_serialize_message(response, + transaction->packet); + coap_send_transaction(transaction); + /* The engine will clear the transaction (right after send for NON, after acked for CON). */ + + separate_active = 0; + } else { + PRINTF("ERROR (transaction)\n"); + } + } /* if (separate_active) */ +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-test.c b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-test.c new file mode 100644 index 000000000..27bba1f3b --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-test.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_test, "title=\"Default test resource\"", res_get_handler, res_post_handler, res_put_handler, res_delete_handler); + +static uint8_t test_etag[8] = { 0 }; +static uint8_t test_etag_len = 1; +static uint8_t test_change = 1; +static uint8_t test_none_match_okay = 1; + +static const uint8_t *bytes = NULL; +static size_t len = 0; + +static void +test_update_etag() +{ + int i; + test_etag_len = (random_rand() % 8) + 1; + for(i = 0; i < test_etag_len; ++i) { + test_etag[i] = random_rand(); + } + test_change = 0; + + PRINTF("### SERVER ACTION ### Changed ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", test_etag_len, test_etag[0], test_etag[1], test_etag[2], test_etag[3], test_etag[4], test_etag[5], test_etag[6], test_etag[7]); +} +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + if(test_change) { + test_update_etag(); + } + PRINTF("/test GET (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + if((len = coap_get_header_etag(request, &bytes)) > 0 + && len == test_etag_len + && memcmp(test_etag, bytes, len) == 0) { + PRINTF("validate "); + REST.set_response_status(response, REST.status.NOT_MODIFIED); + REST.set_header_etag(response, test_etag, test_etag_len); + + test_change = 1; + PRINTF("### SERVER ACTION ### Resource will change\n"); + } else { + /* Code 2.05 CONTENT is default. */ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_header_etag(response, test_etag, test_etag_len); + REST.set_header_max_age(response, 30); + REST.set_response_payload( + response, + buffer, + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); + } +} +static void +res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + PRINTF("/test POST (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + REST.set_response_status(response, REST.status.CREATED); + REST.set_header_location(response, "/location1/location2/location3"); +} +static void +res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + PRINTF("/test PUT (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + if(coap_get_header_if_none_match(request)) { + if(test_none_match_okay) { + REST.set_response_status(response, REST.status.CREATED); + + test_none_match_okay = 0; + PRINTF("### SERVER ACTION ### If-None-Match will FAIL\n"); + } else { + REST.set_response_status(response, PRECONDITION_FAILED_4_12); + + test_none_match_okay = 1; + PRINTF("### SERVER ACTION ### If-None-Match will SUCCEED\n"); + } + } else if(((len = coap_get_header_if_match(request, &bytes)) > 0 + && (len == test_etag_len + && memcmp(test_etag, bytes, len) == 0)) + || len == 0) { + test_update_etag(); + REST.set_header_etag(response, test_etag, test_etag_len); + + REST.set_response_status(response, REST.status.CHANGED); + + if(len > 0) { + test_change = 1; + PRINTF("### SERVER ACTION ### Resource will change\n"); + } + } else { + PRINTF("Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", + len, + test_etag_len, + bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], + test_etag[0], test_etag[1], test_etag[2], test_etag[3], test_etag[4], test_etag[5], test_etag[6], test_etag[7]); + + REST.set_response_status(response, PRECONDITION_FAILED_4_12); + } +} +static void +res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + PRINTF("/test DELETE (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + REST.set_response_status(response, REST.status.DELETED); +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-validate.c b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-validate.c new file mode 100644 index 000000000..b92ffe74d --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-plugtest-validate.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * ETSI Plugtest resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "er-plugtest.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +RESOURCE(res_plugtest_validate, + "title=\"Validation test resource\"", + res_get_handler, + NULL, + res_put_handler, + NULL); + +static uint8_t validate_etag[8] = { 0 }; +static uint8_t validate_etag_len = 1; +static uint8_t validate_change = 1; + +static const uint8_t *bytes = NULL; +static size_t len = 0; + +static void +validate_update_etag() +{ + int i; + validate_etag_len = (random_rand() % 8) + 1; + for(i = 0; i < validate_etag_len; ++i) { + validate_etag[i] = random_rand(); + } + validate_change = 0; + + PRINTF("### SERVER ACTION ### Changed ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", + validate_etag_len, validate_etag[0], validate_etag[1], validate_etag[2], validate_etag[3], validate_etag[4], validate_etag[5], validate_etag[6], validate_etag[7]); +} +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + if(validate_change) { + validate_update_etag(); + } + PRINTF("/validate GET"); + PRINTF("(%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + if((len = coap_get_header_etag(request, &bytes)) > 0 + && len == validate_etag_len && memcmp(validate_etag, bytes, len) == 0) { + PRINTF("validate "); + REST.set_response_status(response, REST.status.NOT_MODIFIED); + REST.set_header_etag(response, validate_etag, validate_etag_len); + + validate_change = 1; + PRINTF("### SERVER ACTION ### Resouce will change\n"); + } else { + /* Code 2.05 CONTENT is default. */ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_header_etag(response, validate_etag, validate_etag_len); + REST.set_header_max_age(response, 30); + REST.set_response_payload( + response, + buffer, + snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, + "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, + coap_req->mid)); + } +} +static void +res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + coap_packet_t *const coap_req = (coap_packet_t *)request; + + PRINTF("/validate PUT "); + PRINTF("(%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid); + + if(((len = coap_get_header_if_match(request, &bytes)) > 0 + && (len == validate_etag_len + && memcmp(validate_etag, bytes, len) == 0)) + || len == 0) { + validate_update_etag(); + REST.set_header_etag(response, validate_etag, validate_etag_len); + + REST.set_response_status(response, REST.status.CHANGED); + + if(len > 0) { + validate_change = 1; + PRINTF("### SERVER ACTION ### Resouce will change\n"); + } + } else { + PRINTF( + "Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X] ", + len, + validate_etag_len, + bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], + validate_etag[0], validate_etag[1], validate_etag[2], validate_etag[3], validate_etag[4], validate_etag[5], validate_etag[6], validate_etag[7]); + + REST.set_response_status(response, PRECONDITION_FAILED_4_12); + } +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-push.c b/examples/osd/er-rest-example-merkurboard/resources/res-push.c new file mode 100644 index 000000000..c169b407c --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-push.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_periodic_handler(void); + +PERIODIC_RESOURCE(res_push, + "title=\"Periodic demo\";obs", + res_get_handler, + NULL, + NULL, + NULL, + 5 * CLOCK_SECOND, + res_periodic_handler); + +/* + * Use local resource state that is accessed by res_get_handler() and altered by res_periodic_handler() or PUT or POST. + */ +static int32_t event_counter = 0; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* + * For minimal complexity, request query and options should be ignored for GET on observable resources. + * Otherwise the requests must be stored with the observer list and passed by REST.notify_subscribers(). + * This would be a TODO in the corresponding files in contiki/apps/erbium/! + */ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_header_max_age(response, res_push.periodic->period / CLOCK_SECOND); + REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "VERY LONG EVENT %lu", event_counter)); + + /* The REST.subscription_handler() will be called for observable resources by the REST framework. */ +} +/* + * Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE. + * It will be called by the REST manager process with the defined period. + */ +static void +res_periodic_handler() +{ + /* Do a periodic task here, e.g., sampling a sensor. */ + ++event_counter; + + /* Usually a condition is defined under with subscribers are notified, e.g., large enough delta in sensor reading. */ + if(1) { + /* Notify the registered observers which will trigger the res_get_handler to create the response. */ + REST.notify_subscribers(&res_push); + } +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-separate.c b/examples/osd/er-rest-example-merkurboard/resources/res-separate.c new file mode 100644 index 000000000..bb2248c92 --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-separate.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap-separate.h" +#include "er-coap-transactions.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_resume_handler(void); + +SEPARATE_RESOURCE(res_separate, + "title=\"Separate demo\"", + res_get_handler, + NULL, + NULL, + NULL, + res_resume_handler); + +/* A structure to store the information required for the separate handler */ +typedef struct application_separate_store { + + /* Provided by Erbium to store generic request information such as remote address and token. */ + coap_separate_t request_metadata; + + /* Add fields for addition information to be stored for finalizing, e.g.: */ + char buffer[16]; +} application_separate_store_t; + +#define COAP_MAX_OPEN_SEPARATE 2 + +static uint8_t separate_active = 0; +static application_separate_store_t separate_store[COAP_MAX_OPEN_SEPARATE]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* + * Example allows only one open separate response. + * For multiple, the application must manage the list of stores. + */ + if(separate_active >= COAP_MAX_OPEN_SEPARATE) { + coap_separate_reject(); + } else { + ++separate_active; + + /* Take over and skip response by engine. */ + coap_separate_accept(request, &separate_store->request_metadata); + /* Be aware to respect the Block2 option, which is also stored in the coap_separate_t. */ + + /* + * At the moment, only the minimal information is stored in the store (client address, port, token, MID, type, and Block2). + * Extend the store, if the application requires additional information from this handler. + * buffer is an example field for custom information. + */ + snprintf(separate_store->buffer, sizeof(separate_store->buffer), "StoredInfo"); + } +} +static void +res_resume_handler() +{ + if(separate_active) { + coap_transaction_t *transaction = NULL; + if((transaction = coap_new_transaction(separate_store->request_metadata.mid, &separate_store->request_metadata.addr, separate_store->request_metadata.port))) { + coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */ + + /* Restore the request information for the response. */ + coap_separate_resume(response, &separate_store->request_metadata, REST.status.OK); + + coap_set_payload(response, separate_store->buffer, strlen(separate_store->buffer)); + + /* + * Be aware to respect the Block2 option, which is also stored in the coap_separate_t. + * As it is a critical option, this example resource pretends to handle it for compliance. + */ + coap_set_header_block2(response, separate_store->request_metadata.block2_num, 0, separate_store->request_metadata.block2_size); + + /* Warning: No check for serialization error. */ + transaction->packet_len = coap_serialize_message(response, transaction->packet); + coap_send_transaction(transaction); + /* The engine will clear the transaction (right after send for NON, after acked for CON). */ + + /* FIXME there could me more! */ + separate_active = 0; + } else { + /* + * Set timer for retry, send error message, ... + * The example simply waits for another button press. + */ + } + } /* if (separate_active) */ +} diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-sht11.c b/examples/osd/er-rest-example-merkurboard/resources/res-sht11.c new file mode 100644 index 000000000..56ed86c01 --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-sht11.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2014, Nimbus Centre for Embedded Systems Research, Cork Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * SHT11 Sensor Resource + * + * This is a simple GET resource that returns the temperature in Celsius + * and the humidity reading from the SHT11. + * \author + * Pablo Corbalan + */ + +#include "contiki.h" + +#if PLATFORM_HAS_SHT11 + +#include +#include "rest-engine.h" +#include "dev/sht11/sht11-sensor.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* Get Method Example. Returns the reading from temperature and humidity sensors. */ +RESOURCE(res_sht11, + "title=\"Temperature and Humidity\";rt=\"Sht11\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* Temperature in Celsius (t in 14 bits resolution at 3 Volts) + * T = -39.60 + 0.01*t + */ + uint16_t temperature = ((sht11_sensor.value(SHT11_SENSOR_TEMP) / 10) - 396) / 10; + /* Relative Humidity in percent (h in 12 bits resolution) + * RH = -4 + 0.0405*h - 2.8e-6*(h*h) + */ + uint16_t rh = sht11_sensor.value(SHT11_SENSOR_HUMIDITY); + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%u;%u", temperature, rh); + + REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_XML) { + REST.set_header_content_type(response, REST.type.APPLICATION_XML); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "", temperature, rh); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'Sht11':{'Temperature':%u,'Humidity':%u}}", temperature, rh); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain, application/xml, and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} +#endif /* PLATFORM_HAS_SHT11 */ diff --git a/examples/osd/er-rest-example-merkurboard/resources/res-sub.c b/examples/osd/er-rest-example-merkurboard/resources/res-sub.c new file mode 100644 index 000000000..1d6f17aeb --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/resources/res-sub.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* + * Example for a resource that also handles all its sub-resources. + * Use REST.get_url() to multiplex the handling of the request depending on the Uri-Path. + */ +PARENT_RESOURCE(res_sub, + "title=\"Sub-resource demo\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + + const char *uri_path = NULL; + int len = REST.get_url(request, &uri_path); + int base_len = strlen(res_sub.url); + + if(len == base_len) { + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "Request any sub-resource of /%s", res_sub.url); + } else { + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, ".%.*s", len - base_len, uri_path + base_len); + } REST.set_response_payload(response, buffer, strlen((char *)buffer)); +} diff --git a/apps/er-coap-12/er-coap-12-separate.h b/examples/osd/er-rest-example-merkurboard/resources/res-toggle.c similarity index 68% rename from apps/er-coap-12/er-coap-12-separate.h rename to examples/osd/er-rest-example-merkurboard/resources/res-toggle.c index 7277cb0f0..d8a773306 100644 --- a/apps/er-coap-12/er-coap-12-separate.h +++ b/examples/osd/er-rest-example-merkurboard/resources/res-toggle.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Institute for Pervasive Computing, ETH Zurich + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,36 +31,33 @@ /** * \file - * CoAP module for separate responses + * Example resource * \author * Matthias Kovatsch */ -#ifndef COAP_SEPARATE_H_ -#define COAP_SEPARATE_H_ +#include "contiki.h" -#include "er-coap-12.h" +#if PLATFORM_HAS_LEDS -typedef struct coap_separate { +#include +#include "contiki.h" +#include "rest-engine.h" +#include "dev/leds.h" - uip_ipaddr_t addr; - uint16_t port; +static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); - coap_message_type_t type; - uint16_t mid; +/* A simple actuator example. Toggles the red led */ +RESOURCE(res_toggle, + "title=\"Red LED\";rt=\"Control\"", + NULL, + res_post_handler, + NULL, + NULL); - uint8_t token_len; - uint8_t token[COAP_TOKEN_LEN]; - - /* separate + blockwise is untested! */ - uint32_t block2_num; - uint16_t block2_size; - -} coap_separate_t; - -int coap_separate_handler(resource_t *resource, void *request, void *response); -void coap_separate_reject(); -int coap_separate_accept(void *request, coap_separate_t *separate_store); -void coap_separate_resume(void *response, coap_separate_t *separate_store, uint8_t code); - -#endif /* COAP_SEPARATE_H_ */ +static void +res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + leds_toggle(LEDS_RED); +} +#endif /* PLATFORM_HAS_LEDS */ diff --git a/examples/osd/er-rest-example-merkurboard/run.sh b/examples/osd/er-rest-example-merkurboard/run.sh index 2efd2cf48..5d5cbbbb4 100755 --- a/examples/osd/er-rest-example-merkurboard/run.sh +++ b/examples/osd/er-rest-example-merkurboard/run.sh @@ -1,8 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size -C --mcu=MCU=atmega128rfa1 er-example-server.osd-merkur -avr-objcopy -j .text -j .data -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.eep +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/er-rest-example-merkurboard/runclient.sh b/examples/osd/er-rest-example-merkurboard/runclient.sh index 70dcea0e5..0fceb01ce 100755 --- a/examples/osd/er-rest-example-merkurboard/runclient.sh +++ b/examples/osd/er-rest-example-merkurboard/runclient.sh @@ -1,8 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size -C --mcu=MCU=atmega128rfa1 er-example-client.osd-merkur -avr-objcopy -j .text -j .data -O ihex er-example-client.osd-merkur er-example-client.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex er-example-client.osd-merkur er-example-client.osd-merkur.eep +make TARGET=osd-merkur diff --git a/examples/osd/er-rest-example-merkurboard/server-client-native.csc b/examples/osd/er-rest-example-merkurboard/server-client-native.csc new file mode 100644 index 000000000..2bc180592 --- /dev/null +++ b/examples/osd/er-rest-example-merkurboard/server-client-native.csc @@ -0,0 +1,231 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + REST with RPL router + 1.0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + slipradio + Sky SLIP radio + [CONTIKI_DIR]/examples/ipv6/slip-radio/slip-radio.c + make slip-radio.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/slip-radio/slip-radio.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + client + Erbium Client + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c + make er-example-client.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 30.303994886410642 + 17.22128424003353 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + slipradio + + + + + org.contikios.cooja.interfaces.Position + 46.57186415376375 + 37.25589203828498 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + + org.contikios.cooja.interfaces.Position + 18.194682268367348 + 50.210548118402656 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + client + + + + org.contikios.cooja.plugins.SimControl + 259 + 0 + 179 + 1 + 2 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + org.contikios.cooja.plugins.skins.LEDVisualizerSkin + org.contikios.cooja.plugins.skins.AddressVisualizerSkin + 2.255467003316979 0.0 0.0 2.255467003316979 59.30641698643764 -13.478401994502008 + + 300 + 2 + 178 + 262 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 762 + 4 + 491 + 2 + 182 + + + org.contikios.cooja.plugins.RadioLogger + + 150 + + false + false + + + 451 + -1 + 305 + 73 + 140 + true + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + + + + + 25.49079397896416 + + 1624 + 5 + 252 + 6 + 712 + + + org.contikios.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 853 + 3 + 491 + 765 + 182 + + + SerialSocketServer + 0 + 422 + 1 + 82 + 606 + 51 + + + diff --git a/examples/osd/er-rest-example-merkurboard/server-client.csc b/examples/osd/er-rest-example-merkurboard/server-client.csc index 0c09f41b5..802a40cc0 100644 --- a/examples/osd/er-rest-example-merkurboard/server-client.csc +++ b/examples/osd/er-rest-example-merkurboard/server-client.csc @@ -1,227 +1,231 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - REST with RPL router - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.Msp802154Radio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.Msp802154Radio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - client - Erbium Client - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c - make er-example-client.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.Msp802154Radio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 46.57186415376375 - 40.35946215910942 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - - se.sics.cooja.interfaces.Position - 18.638049428485125 - 47.55034515769599 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 3 - - client - - - - se.sics.cooja.plugins.SimControl - 259 - 0 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 - - 300 - 2 - 178 - 261 - 1 - - - se.sics.cooja.plugins.LogListener - - - - - 762 - 3 - 491 - 2 - 182 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 4 - 74 - 578 - 18 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - 2 - - - - - 125 - 25.49079397896416 - - 1624 - 5 - 252 - 6 - 712 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 2 - - Serial port - 0,0 - - 853 - 1 - 491 - 765 - 182 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + REST with RPL router + 1.0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + client + Erbium Client + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c + make er-example-client.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + org.contikios.cooja.interfaces.Position + 46.57186415376375 + 40.35946215910942 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + + org.contikios.cooja.interfaces.Position + 18.638049428485125 + 47.55034515769599 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + client + + + + org.contikios.cooja.plugins.SimControl + 259 + 0 + 179 + 2 + 1 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + org.contikios.cooja.plugins.skins.LEDVisualizerSkin + org.contikios.cooja.plugins.skins.AddressVisualizerSkin + 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 + + 300 + 2 + 178 + 261 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 762 + 3 + 491 + 2 + 182 + + + org.contikios.cooja.plugins.RadioLogger + + 150 + + false + false + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 4 + 74 + 578 + 18 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + + + + + 25.49079397896416 + + 1624 + 5 + 252 + 6 + 712 + + + org.contikios.cooja.plugins.MoteInterfaceViewer + 2 + + Serial port + 0,0 + + 853 + 1 + 491 + 765 + 182 + + + diff --git a/examples/osd/er-rest-example-merkurboard/server-only.csc b/examples/osd/er-rest-example-merkurboard/server-only.csc index 935bd6e79..0557a29f9 100644 --- a/examples/osd/er-rest-example-merkurboard/server-only.csc +++ b/examples/osd/er-rest-example-merkurboard/server-only.csc @@ -1,189 +1,193 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - REST with RPL router - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.Msp802154Radio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.Msp802154Radio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 35.100895239785295 - 39.70574552287428 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - se.sics.cooja.plugins.SimControl - 259 - 0 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 - - 300 - 5 - 175 - 263 - 3 - - - se.sics.cooja.plugins.LogListener - - - - - 560 - 2 - 326 - 1 - 293 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 3 - 74 - 39 - 199 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - - - - - 125 - 25.49079397896416 - - 1624 - 4 - 252 - 4 - 622 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 1 - - Serial port - 0,0 - - 702 - 1 - 646 - 564 - 2 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + REST with RPL router + 1.0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + org.contikios.cooja.interfaces.Position + 35.100895239785295 + 39.70574552287428 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + org.contikios.cooja.plugins.SimControl + 259 + 0 + 179 + 2 + 1 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + org.contikios.cooja.plugins.skins.LEDVisualizerSkin + org.contikios.cooja.plugins.skins.AddressVisualizerSkin + 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 + + 300 + 1 + 175 + 262 + 2 + + + org.contikios.cooja.plugins.LogListener + + + + + + 560 + 3 + 326 + 1 + 293 + + + org.contikios.cooja.plugins.RadioLogger + + 150 + + false + false + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 4 + 74 + 39 + 199 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + + + + + 25.49079397896416 + + 1624 + 5 + 252 + 4 + 622 + + + org.contikios.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 702 + 2 + 646 + 564 + 2 + + + diff --git a/examples/osd/light-actor/Makefile b/examples/osd/light-actor/Makefile index 23ea7e7ac..881d7002c 100644 --- a/examples/osd/light-actor/Makefile +++ b/examples/osd/light-actor/Makefile @@ -1,21 +1,17 @@ -all: er-example-server -# use this target explicitly if requried: er-plugtest-server +EXE=er-example-server - -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 - -# for some platforms -UIP_CONF_IPV6=1 -# IPv6 make config disappeared completely -CFLAGS += -DUIP_CONF_IPV6=1 +all: $(EXE) CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" # pcintkey PROJECT_SOURCEFILES += pcintkey.c +PROJECT_SOURCEFILES += statusled.c # variable for Makefile.include ifneq ($(TARGET), minimal-net) @@ -34,64 +30,28 @@ endif # linker optimizations SMALL=1 -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif - -APPS += erbium - -# optional rules to get assembly -#CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 -#CUSTOM_RULE_S_TO_OBJECTDIR_O = 1 +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += json json-resource include $(CONTIKI)/Makefile.include -# optional rules to get assembly -#$(OBJECTDIR)/%.o: asmdir/%.S -# $(CC) $(CFLAGS) -MMD -c $< -o $@ -# @$(FINALIZE_DEPENDENCY) -# -#asmdir/%.S: %.c -# $(CC) $(CFLAGS) -MMD -S $< -o $@ - -# border router rules -$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c (cd $(CONTIKI)/tools && $(MAKE) tunslip6) -connect-router: $(CONTIKI)/tools/tunslip6 +connect-router: $(CONTIKI)/tools/tunslip6 sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 -connect-router-cooja: $(CONTIKI)/tools/tunslip6 +connect-router-cooja: $(CONTIKI)/tools/tunslip6 sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 connect-minimal: sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/light-actor/er-example-server.c b/examples/osd/light-actor/er-example-server.c index 431e54ceb..7fb540e5f 100644 --- a/examples/osd/light-actor/er-example-server.c +++ b/examples/osd/light-actor/er-example-server.c @@ -42,25 +42,34 @@ #include #include "contiki.h" #include "contiki-net.h" +#include +#include "rest-engine.h" + +#define PLATFORM_HAS_LED 1 +//#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_OPTRIAC 1 +#define PLATFORM_HAS_TEMPERATURE 1 +#define PLATFORM_HAS_BATTERY 1 /* Define which resources to include to meet memory constraints. */ -#define REST_RES_INFO 1 +#define REST_RES_MODEL 1 +#define REST_RES_NAME 1 +#define REST_RES_SW 1 +#define REST_RES_RESET 1 +#define REST_RES_TIMER 1 #define REST_RES_OPTRIAC 1 #define REST_RES_TEMPERATURE 1 -#define REST_RES_EVENT 0 -#define REST_RES_LEDS 0 -#define REST_RES_TOGGLE 0 +#define REST_RES_LED 1 #define REST_RES_BATTERY 1 -#include "erbium.h" #include "pcintkey.h" +#include "statusled.h" -#include "dev/led.h" #if defined (PLATFORM_HAS_BUTTON) #include "dev/button-sensor.h" #endif -#if defined (PLATFORM_HAS_LEDS) +#if defined (PLATFORM_HAS_LED) #include "dev/leds.h" #endif #if defined (PLATFORM_HAS_OPTRIAC) @@ -73,20 +82,7 @@ #include "dev/battery-sensor.h" #endif -#include "dev/optriac.h" -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP == 3 -#include "er-coap-03.h" -#elif WITH_COAP == 7 -#include "er-coap-07.h" -#elif WITH_COAP == 12 -#include "er-coap-12.h" -#elif WITH_COAP == 13 -#include "er-coap-13.h" -#else -#warning "Erbium example without CoAP-specifc functionality" -#endif /* CoAP-specific example */ #define DEBUG 1 #if DEBUG @@ -100,13 +96,15 @@ #endif /******************************************************************************/ +uint8_t g_triac_a = 0; +uint8_t g_triac_b = 0; -#if REST_RES_INFO +/******************************************************************************/ +#if REST_RES_MODEL /* * Resources are defined by the RESOURCE macro. * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). */ -RESOURCE(info, METHOD_GET, "info", "title=\"Info\";rt=\"text\""); /* * A handler function named [resource name]_handler must be implemented for each RESOURCE. @@ -115,7 +113,7 @@ RESOURCE(info, METHOD_GET, "info", "title=\"Info\";rt=\"text\""); * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. */ void -info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +model_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { char message[100]; int index = 0; @@ -123,8 +121,7 @@ info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_ /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ // jSON Format - index += sprintf(message + index,"{\n \"Version\" : \"V1.0pre2\",\n"); - index += sprintf(message + index," \"name\" : \"light-actor\"\n"); + index += sprintf(message + index,"{\n \"model\" : \"LightActor\"\n"); index += sprintf(message + index,"}\n"); length = strlen(message); @@ -133,11 +130,270 @@ info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_ REST.set_header_content_type(response, REST.type.APPLICATION_JSON); REST.set_response_payload(response, buffer, length); } +RESOURCE(res_model, "title=\"model\";rt=\"simple.dev.md\"", model_get_handler, NULL, NULL, NULL); + #endif +/******************************************************************************/ +#if REST_RES_SW +/* + * Resources are defined by the RESOURCE macro. + * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). + */ + +/* + * A handler function named [resource name]_handler must be implemented for each RESOURCE. + * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore + * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. + * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. + */ +void +sw_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + char message[100]; + int index = 0; + int length = 0; /* |<-------->| */ + + /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ + // jSON Format + index += sprintf(message + index,"{\n \"sw\" : \"V1.0\"\n"); + index += sprintf(message + index,"}\n"); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + REST.set_response_payload(response, buffer, length); +} +RESOURCE(res_sw, "title=\"Software Version\";rt=\"simple.dev.sv\"", sw_get_handler, NULL, NULL, NULL); +#endif + +/******************************************************************************/ +#if REST_RES_NAME +/* + * Resources are defined by the RESOURCE macro. + * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). + */ + +/* eeprom space */ +#define P_NAME "Testboard" +#define P_NAME_MAX 17 +uint8_t eemem_p_name[P_NAME_MAX] EEMEM = P_NAME; + +/* + * A handler function named [resource name]_handler must be implemented for each RESOURCE. + * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore + * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. + * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. + */ +void +name_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + uint8_t eebuffer[32]; + char message[100]; + int index = 0; + int length = 0; /* |<-------->| */ + const char *name = NULL; + int success = 1; + + switch(REST.get_method_type(request)){ + case METHOD_GET: + cli(); + eeprom_read_block (eebuffer, &eemem_p_name, sizeof(eemem_p_name)); + sei(); + /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ + // jSON Format + index += sprintf(message + index,"{\n \"name\" : \"%s\"\n",eebuffer); + index += sprintf(message + index,"}\n"); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + REST.set_response_payload(response, buffer, length); + break; + + case METHOD_POST: + if (success && (length=REST.get_post_variable(request, "name", &name))) { + PRINTF("name %s\n", name); + if (length < P_NAME_MAX) { + memcpy(&eebuffer, name,length); + eebuffer[length]=0; + cli(); + eeprom_write_block(&eebuffer, &eemem_p_name, sizeof(eemem_p_name)); + sei(); + } else { + success = 0; + } + } else { + success = 0; + } + break; + default: + success = 0; + } + if (!success) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} +RESOURCE(res_name, "title=\"name\";rt=\"simple.dev.n\"", name_handler, NULL, name_handler, NULL ); +#endif + + +/******************************************************************************/ +#if REST_RES_TIMER +/*A simple actuator example*/ + +/* eeprom space */ +#define P_TIMER "60" +#define P_TIMER_MAX 10 +uint8_t eemem_p_timer[P_TIMER_MAX] EEMEM = P_TIMER; + +int gtimer_read(){ + uint8_t eebuffer[32]; + + cli(); + eeprom_read_block (eebuffer, &eemem_p_timer, sizeof(eemem_p_timer)); + sei(); + return atoi((const char *)eebuffer); +} + +void +timer_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + uint8_t eebuffer[32]; + const char *timer = NULL; + char message[100]; + int length = 0; /* |<-------->| */ + int index = 0; + int success = 1; + + switch(REST.get_method_type(request)){ + + case METHOD_GET: + cli(); + eeprom_read_block (eebuffer, &eemem_p_timer, sizeof(eemem_p_timer)); + sei(); + /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ + // jSON Format + index += sprintf(message + index,"{\n \"timer\" : \"%s\"\n",eebuffer); + index += sprintf(message + index,"}\n"); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + REST.set_response_payload(response, buffer, length); + break; + + case METHOD_POST: + if (success && (length=REST.get_post_variable(request, "timer", &timer))) { + PRINTF("name %s\n", timer); + if (length < P_TIMER_MAX) { + memcpy(&eebuffer, timer,length); + eebuffer[length]=0; + cli(); + eeprom_write_block(&eebuffer, &eemem_p_timer, sizeof(eemem_p_timer)); + sei(); + } else { + success = 0; + } + } else { + success = 0; + } + break; + default: + success = 0; + } + if (!success) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} +RESOURCE(res_timer, "title=\"timer\";rt=\"timer\"", timer_handler, NULL, timer_handler, NULL ); +#endif + +/******************************************************************************/ +#if REST_RES_RESET +/*A simple actuator example*/ + +/* eeprom space */ +#define P_RESET "0" +#define P_RESET_MAX 10 +uint8_t eemem_p_reset[P_RESET_MAX] EEMEM = P_RESET; + +void +reset_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + uint8_t eebuffer[32]; + const char *mode = NULL; + char message[100]; + int length = 0; /* |<-------->| */ + int index = 0; + int reset = 0; + size_t len = 0; + int success = 1; + + switch(REST.get_method_type(request)){ + + case METHOD_GET: + cli(); + eeprom_read_block (eebuffer, &eemem_p_reset, sizeof(eemem_p_reset)); + sei(); + /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ + // jSON Format + index += sprintf(message + index,"{\n \"reset\" : \"%s\"\n",eebuffer); + index += sprintf(message + index,"}\n"); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + REST.set_response_payload(response, buffer, length); + break; + + case METHOD_POST: + if (success && (len=REST.get_post_variable(request, "mode", &mode))) { + PRINTF("mode %s\n", mode); + if (strncmp(mode, "on", len)==0) { + length=strlen(P_NAME); + memcpy(&eebuffer, P_NAME,length); + eebuffer[length]=0; + cli(); + eeprom_write_block(&eebuffer, &eemem_p_name, sizeof(eemem_p_name)); + sei(); + length=strlen(P_TIMER); + memcpy(&eebuffer, P_TIMER,length); + eebuffer[length]=0; + cli(); + eeprom_write_block(&eebuffer, &eemem_p_timer, sizeof(eemem_p_timer)); + eeprom_read_block (eebuffer, &eemem_p_reset, sizeof(eemem_p_reset)); + sei(); + reset= atoi((char*)eebuffer) + 1; + length=sprintf((char*)eebuffer,"%d",reset); + cli(); + eeprom_write_block(&eebuffer, &eemem_p_reset, sizeof(eemem_p_reset)); + sei(); + } else { + success = 0; + } + } else { + success = 0; + } + break; + default: + success = 0; + } + if (!success) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} +RESOURCE(res_reset, "title=\"reset\";rt=\"reset\"", reset_handler, NULL, reset_handler, NULL ); +#endif + +/******************************************************************************/ // pcintkey_ext /*A simple actuator example. read the key button status*/ -RESOURCE(extbutton, METHOD_GET | METHOD_PUT , "sensors/extbutton", "title=\"ext.Button\";rt=\"Text\""); + void extbutton_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { @@ -179,7 +435,7 @@ extbutton_handler(void* request, void* response, uint8_t *buffer, uint16_t prefe REST.set_response_payload(response, buffer, length); break; - case METHOD_PUT: + case METHOD_POST: if (success && (len=REST.get_post_variable(request, "name", &name))) { PRINTF("name %s\n", name); @@ -196,192 +452,21 @@ extbutton_handler(void* request, void* response, uint8_t *buffer, uint16_t prefe REST.set_response_status(response, REST.status.BAD_REQUEST); } } -/*A simple actuator example, post variable mode, relay is activated or deactivated*/ -RESOURCE(led1, METHOD_GET | METHOD_PUT , "actuators/led1", "title=\"Led1\";rt=\"led\""); +RESOURCE(res_extbutton, "title=\"button\";rt=\"button\"", extbutton_handler, NULL, extbutton_handler, NULL ); + +/******************************************************************************/ +#if REST_RES_LED +/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ + void led1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { - char mode[10]; - static uint8_t led1 = 0; - static char name[17]="led1"; - int success = 1; - - char temp[100]; - int index = 0; size_t len = 0; - - const char *pmode = NULL; - const char *pname = NULL; - - switch(REST.get_method_type(request)){ - case METHOD_GET: - // jSON Format - index += sprintf(temp + index,"{\n \"name\" : \"%s\",\n",name); - if(led1 == 0) - index += sprintf(temp + index," \"mode\" : \"off\"\n"); - if(led1 == 1) - index += sprintf(temp + index," \"mode\" : \"on\"\n"); - index += sprintf(temp + index,"}\n"); - - len = strlen(temp); - memcpy(buffer, temp,len ); - - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - REST.set_response_payload(response, buffer, len); - break; - case METHOD_POST: - success = 0; - break; - case METHOD_PUT: - if (success && (len=REST.get_post_variable(request, "mode", &pmode))) { - PRINTF("name %s\n", mode); - memcpy(mode, pmode,len); - mode[len]=0; - if (!strcmp(mode, "on")) { - led1_on(); - led1 = 1; - } else if (!strcmp(mode, "off")) { - led1_off(); - led1 = 0; - } else { - success = 0; - } - } else if (success && (len=REST.get_post_variable(request, "name", &pname))) { - PRINTF("name %s\n", name); - memcpy(name, pname,len); - name[len]=0; - } else { - success = 0; - } - break; - default: - success = 0; - } - - if (!success) { - REST.set_response_status(response, REST.status.BAD_REQUEST); - } -} - -/******************************************************************************/ -#if defined (PLATFORM_HAS_OPTRIAC) -/******************************************************************************/ -#if REST_RES_OPTRIAC -/*A simple actuator example*/ -RESOURCE(optriac, METHOD_GET | METHOD_POST | METHOD_PUT , "actuators/optriac", "title=\"TRIAC: ?type=a|b, POST/PUT mode=on|off\";rt=\"Control\""); - -void -optriac_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - const char *type = NULL; - const char *mode = NULL; - static char namea[17]="Triac-a"; - static char nameb[17]="Triac-b"; - - char temp[100]; - int index = 0; - size_t len = 0; - - uint8_t triac = 0; - int success = 1; - switch(REST.get_method_type(request)){ - case METHOD_GET: - // jSON Format - index += sprintf(temp + index,"{\n \"%s\" : ",namea); - if(optriac_sensor.value(OPTRIAC_SENSOR_A) == 0) - index += sprintf(temp + index,"\"off\",\n"); - if(optriac_sensor.value(OPTRIAC_SENSOR_A) == 1) - index += sprintf(temp + index,"\"on\",\n"); - index += sprintf(temp + index," \"%s\" : ",nameb); - if(optriac_sensor.value(OPTRIAC_SENSOR_B) == 0) - index += sprintf(temp + index,"\"off\"\n"); - if(optriac_sensor.value(OPTRIAC_SENSOR_B) == 1) - index += sprintf(temp + index,"\"on\"\n"); - index += sprintf(temp + index,"}\n"); - - len = strlen(temp); - memcpy(buffer, temp,len ); - - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - REST.set_response_payload(response, buffer, len); - break; - - case METHOD_POST: - success = 0; - break; - case METHOD_PUT: - if ((len=REST.get_query_variable(request, "type", &type))) { - PRINTF("type %.*s\n", len, type); - - if (strncmp(type, "a", len)==0) { - triac = OPTRIAC_SENSOR_A; - } else if(strncmp(type,"b", len)==0) { - triac = OPTRIAC_SENSOR_B; - } else { - triac = OPTRIAC_SENSOR_A; - } - } else { - success = 0; - } - - if (success && (len=REST.get_post_variable(request, "mode", &mode))) { - PRINTF("mode %s\n", mode); - - if (strncmp(mode, "on", len)==0) { - led1_on(); // Debug - optriac_sensor.configure(triac,1); - } else if (strncmp(mode, "off", len)==0) { - optriac_sensor.configure(triac,0); - led1_off(); // Debug - } else { - success = 0; - } - } else { - success = 0; - } - break; - default: - success = 0; - } - if (!success) { - REST.set_response_status(response, REST.status.BAD_REQUEST); - } -} -#endif -/******************************************************************************/ -#endif /* PLATFORM_HAS_OPTRIAC */ - -/******************************************************************************/ -#if defined (PLATFORM_HAS_LEDS) -/******************************************************************************/ -#if REST_RES_LEDS -/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -RESOURCE(leds, METHOD_POST | METHOD_PUT , "actuators/leds", "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\""); - -void -leds_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - size_t len = 0; - const char *color = NULL; const char *mode = NULL; uint8_t led = 0; int success = 1; - if ((len=REST.get_query_variable(request, "color", &color))) { - PRINTF("color %.*s\n", len, color); - - if (strncmp(color, "r", len)==0) { - led = LEDS_RED; - } else if(strncmp(color,"g", len)==0) { - led = LEDS_GREEN; - } else if (strncmp(color,"b", len)==0) { - led = LEDS_BLUE; - } else { - success = 0; - } - } else { - success = 0; - } + led = LEDS_RED; if (success && (len=REST.get_post_variable(request, "mode", &mode))) { PRINTF("mode %s\n", mode); @@ -401,45 +486,128 @@ leds_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_ REST.set_response_status(response, REST.status.BAD_REQUEST); } } -#endif +RESOURCE(res_led1, "title=\"LED: PUT mode=on|off\";rt=\"simple.act.led\"", led1_handler, NULL, led1_handler, NULL ); + +/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -/******************************************************************************/ -#if REST_RES_TOGGLE -/* A simple actuator example. Toggles the red led */ -RESOURCE(toggle, METHOD_GET | METHOD_PUT | METHOD_POST, "actuators/toggle", "title=\"Red LED\";rt=\"Control\""); void -toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +led2_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { - leds_toggle(LEDS_RED); -} -#endif -#endif /* PLATFORM_HAS_LEDS */ + size_t len = 0; + const char *mode = NULL; + int success = 1; -/******************************************************************************/ + + if (success && (len=REST.get_post_variable(request, "mode", &mode))) { + PRINTF("mode %s\n", mode); + + if (strncmp(mode, "on", len)==0) { + statusled_on(); + } else if (strncmp(mode, "off", len)==0) { + statusled_off(); + } else { + success = 0; + } + } else { + success = 0; + } + + if (!success) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} +RESOURCE(res_led2, "title=\"LED: PUT mode=on|off\";rt=\"simple.act.led\"", led2_handler, NULL, led2_handler, NULL ); +#endif + +#if REST_RES_OPTRIAC +/*A simple actuator example*/ + +void +optriac_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const char *mode = NULL; + static char namea[17]="Triac-a"; + static char nameb[17]="Triac-b"; + + char temp[100]; + int index = 0; + size_t len = 0; + int success = 1; + + switch(REST.get_method_type(request)){ + case METHOD_GET: + // jSON Format + index += sprintf(temp + index,"{\n \"%s\" : ",namea); + if(optriac_sensor.value(OPTRIAC_SENSOR_1) == 0) + index += sprintf(temp + index,"\"off\",\n"); + if(optriac_sensor.value(OPTRIAC_SENSOR_1) == 1) + index += sprintf(temp + index,"\"on\",\n"); + index += sprintf(temp + index," \"%s\" : ",nameb); + if(optriac_sensor.value(OPTRIAC_SENSOR_2) == 0) + index += sprintf(temp + index,"\"off\"\n"); + if(optriac_sensor.value(OPTRIAC_SENSOR_2) == 1) + index += sprintf(temp + index,"\"on\"\n"); + index += sprintf(temp + index,"}\n"); + + len = strlen(temp); + memcpy(buffer, temp,len ); + + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + REST.set_response_payload(response, buffer, len); + break; + + case METHOD_PUT: + if (success && (len=REST.get_post_variable(request, "mode", &mode))) { + PRINTF("mode %s\n", mode); + if (strncmp(mode, "on", len)==0) { + optriac_sensor.configure(OPTRIAC_SENSOR_1,1); + optriac_sensor.configure(OPTRIAC_SENSOR_2,1); + statusled_on(); + } else if (strncmp(mode, "off", len)==0) { + optriac_sensor.configure(OPTRIAC_SENSOR_1,0); + optriac_sensor.configure(OPTRIAC_SENSOR_2,0); + statusled_off(); + } else { + success = 0; + } + } else { + success = 0; + } + break; + default: + success = 0; + } + if (!success) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} +RESOURCE(res_optriac, "title=\"TRIAC, PUT mode=on|off\";rt=\"simple.act.triac\"", optriac_handler, NULL, optriac_handler, NULL ); +#endif /* PLATFORM_HAS_OPTRIAC */ /******************************************************************************/ #if REST_RES_TEMPERATURE && defined (PLATFORM_HAS_TEMPERATURE) /* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(temperature, METHOD_GET, "sensors/cputemp", "title=\"Temperature status\";rt=\"temperature-c\""); + void temperature_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { - int temperature = temperature_sensor.value(0); + int temperature = temperature_sensor.value(0); + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", temperature); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d.%02d", temperature/100, temperature % 100); + REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) + else if (accept == REST.type.APPLICATION_JSON) { REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%d}", temperature); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%d.%02d}", temperature/100, temperature % 100); REST.set_response_payload(response, buffer, strlen((char *)buffer)); } @@ -450,32 +618,33 @@ temperature_handler(void* request, void* response, uint8_t *buffer, uint16_t pre REST.set_response_payload(response, msg, strlen(msg)); } } +RESOURCE(res_temperature, "title=\"Temperature status\";rt=\"temperature-c\"", temperature_handler, NULL, NULL, NULL ); #endif /* PLATFORM_HAS_TEMPERATURE */ /******************************************************************************/ #if REST_RES_BATTERY && defined (PLATFORM_HAS_BATTERY) /* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(battery, METHOD_GET, "sensors/battery", "title=\"Battery status\";rt=\"battery-mV\""); + void battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { int battery = battery_sensor.value(0); + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", battery); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d.%02d", battery/1000, battery % 1000); REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) + else if (accept == REST.type.APPLICATION_JSON) { REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'battery':%d}", battery); - + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"battery\":%d.%02d}", battery/1000, battery % 1000); + REST.set_response_payload(response, buffer, strlen((char *)buffer)); } else @@ -485,6 +654,8 @@ battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr REST.set_response_payload(response, msg, strlen(msg)); } } +RESOURCE(res_battery, "title=\"Battery status\";rt=\"battery-mV\"", battery_handler, NULL, NULL, NULL ); + #endif /* PLATFORM_HAS_BATTERY */ /******************************************************************************/ @@ -493,7 +664,8 @@ battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr void hw_init() { - led1_off(); + leds_off(LEDS_RED); + statusledinit(); key_init(); } @@ -541,36 +713,41 @@ PROCESS_THREAD(rest_server_example, ev, data) rest_init_engine(); /* Activate the application-specific resources. */ - rest_activate_resource(&resource_led1); - rest_activate_resource(&resource_extbutton); -#if REST_RES_INFO - rest_activate_resource(&resource_info); +#if REST_RES_MODEL + rest_activate_resource(&res_model,"p/model"); #endif +#if REST_RES_SW + rest_activate_resource(&res_sw,"p/sw"); +#endif +#if REST_RES_NAME + rest_activate_resource(&res_name,"p/name"); +#endif +#if REST_RES_RESET + rest_activate_resource(&res_reset,"p/reset"); +#endif +#if REST_RES_TIMER + rest_activate_resource(&res_timer,"a/timer"); +#endif + + rest_activate_resource(&res_extbutton,"s/extbutton"); /* Activate the application-specific resources. */ #if REST_RES_OPTRIAC SENSORS_ACTIVATE(optriac_sensor); - rest_activate_resource(&resource_optriac); + rest_activate_resource(&res_optriac,"a/optriac"); #endif -#if defined (PLATFORM_HAS_PIR) && (REST_RES_EVENT) - SENSORS_ACTIVATE(pir_sensor); - rest_activate_event_resource(&resource_pir); - PRINTF("ACTIVATE PIR\n"); +#if defined (PLATFORM_HAS_LED) +#if REST_RES_LED + rest_activate_resource(&res_led1,"a/led1"); + rest_activate_resource(&res_led2,"a/led2"); #endif -#if defined (PLATFORM_HAS_LEDS) -#if REST_RES_LEDS - rest_activate_resource(&resource_leds); -#endif -#if REST_RES_TOGGLE - rest_activate_resource(&resource_toggle); -#endif -#endif /* PLATFORM_HAS_LEDS */ +#endif /* PLATFORM_HAS_LED */ #if defined (PLATFORM_HAS_TEMPERATURE) && REST_RES_TEMPERATURE SENSORS_ACTIVATE(temperature_sensor); - rest_activate_resource(&resource_temperature); + rest_activate_resource(&res_temperature,"s/cputemp"); #endif #if defined (PLATFORM_HAS_BATTERY) && REST_RES_BATTERY SENSORS_ACTIVATE(battery_sensor); - rest_activate_resource(&resource_battery); + rest_activate_resource(&res_battery,"s/battery"); #endif etimer_set(&ds_periodic_timer, MESURE_INTERVAL); @@ -597,11 +774,11 @@ PROCESS_THREAD(rest_server_example, ev, data) ext5 = is_button_ext5(); PRINTF("Toggle Triac A\n"); // Toggle Triac A - if(optriac_sensor.value(OPTRIAC_SENSOR_A) == 0){ - optriac_sensor.configure(OPTRIAC_SENSOR_A,1); + if(optriac_sensor.value(OPTRIAC_SENSOR_1) == 0){ + optriac_sensor.configure(OPTRIAC_SENSOR_1,1); led1_on(); }else{ - optriac_sensor.configure(OPTRIAC_SENSOR_A,0); + optriac_sensor.configure(OPTRIAC_SENSOR_1,0); led1_off(); } } @@ -609,11 +786,11 @@ PROCESS_THREAD(rest_server_example, ev, data) ext6 = is_button_ext6(); PRINTF("Toggle Triac B\n"); // Toggle Triac B - if(optriac_sensor.value(OPTRIAC_SENSOR_B) == 0){ - optriac_sensor.configure(OPTRIAC_SENSOR_B,1); + if(optriac_sensor.value(OPTRIAC_SENSOR_2) == 0){ + optriac_sensor.configure(OPTRIAC_SENSOR_2,1); led2_on(); }else{ - optriac_sensor.configure(OPTRIAC_SENSOR_B,0); + optriac_sensor.configure(OPTRIAC_SENSOR_2,0); led2_off(); } } diff --git a/examples/osd/light-actor/flash.sh b/examples/osd/light-actor/flash.sh index e92d472f6..e82962073 100755 --- a/examples/osd/light-actor/flash.sh +++ b/examples/osd/light-actor/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-server.osd-merkur.hex:a -U eeprom:w:er-example-server.osd-merkur.eep:a +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/light-actor/pcintkey.c b/examples/osd/light-actor/pcintkey.c index 3da35669d..f9553efd4 100644 --- a/examples/osd/light-actor/pcintkey.c +++ b/examples/osd/light-actor/pcintkey.c @@ -55,21 +55,44 @@ ISR(PCINT0_vect) // } // } } + +/* Compatibility of old vs new definitions in io.h */ +#ifndef DDE0 +#define DDE0 DDRE0 +#define DDE1 DDRE1 +#define DDE2 DDRE2 +#define DDE3 DDRE3 +#define DDE4 DDRE4 +#define DDE5 DDRE5 +#define DDE6 DDRE6 +#define DDE7 DDRE7 +#endif +#ifndef DDF0 +#define DDF0 DDRF0 +#define DDF1 DDRF1 +#define DDF2 DDRF2 +#define DDF3 DDRF3 +#define DDF4 DDRF4 +#define DDF5 DDRF5 +#define DDF6 DDRF6 +#define DDF7 DDRF7 +#endif + /** * \brief This will intialize the KEY for button readings. -*/ + */ void key_init(void) { // Pairing Button - PORTB |= (1< - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - client - Erbium Client - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c - make er-example-client.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 46.57186415376375 - 40.35946215910942 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - - se.sics.cooja.interfaces.Position - 18.638049428485125 - 47.55034515769599 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 3 - - client - - - - se.sics.cooja.plugins.SimControl - 259 - 0 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 - - 300 - 2 - 178 - 261 - 1 - - - se.sics.cooja.plugins.LogListener - - - - - 762 - 3 - 491 - 2 - 182 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 4 - 74 - 578 - 18 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - 2 - - - - - 125 - 25.49079397896416 - - 1624 - 5 - 252 - 6 - 712 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 2 - - Serial port - 0,0 - - 853 - 1 - 491 - 765 - 182 - - - diff --git a/examples/osd/light-actor/server-only.csc b/examples/osd/light-actor/server-only.csc index d5eee34d6..1b0fe28bf 100644 --- a/examples/osd/light-actor/server-only.csc +++ b/examples/osd/light-actor/server-only.csc @@ -1,189 +1,189 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 35.100895239785295 - 39.70574552287428 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - se.sics.cooja.plugins.SimControl - 259 - 5 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 - - 300 - 4 - 175 - 263 - 3 - - - se.sics.cooja.plugins.LogListener - - - - - 560 - 1 - 326 - 1 - 293 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 2 - 74 - 39 - 199 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - - - - - 125 - 25.49079397896416 - - 1624 - 3 - 252 - 4 - 622 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 1 - - Serial port - 0,0 - - 702 - 0 - 646 - 564 - 2 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + REST with RPL router + -2147483648 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + se.sics.cooja.interfaces.Position + 35.100895239785295 + 39.70574552287428 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + se.sics.cooja.plugins.SimControl + 259 + 5 + 179 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.AttributeVisualizerSkin + se.sics.cooja.plugins.skins.LEDVisualizerSkin + se.sics.cooja.plugins.skins.AddressVisualizerSkin + 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 + + 300 + 4 + 175 + 263 + 3 + + + se.sics.cooja.plugins.LogListener + + + + + 560 + 1 + 326 + 1 + 293 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 2 + 74 + 39 + 199 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + + + + + 125 + 25.49079397896416 + + 1624 + 3 + 252 + 4 + 622 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 702 + 0 + 646 + 564 + 2 + + + diff --git a/examples/osd/light-actor/statusled.c b/examples/osd/light-actor/statusled.c new file mode 100644 index 000000000..a5a02005d --- /dev/null +++ b/examples/osd/light-actor/statusled.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014 harald pichler + * All rights reserved. + * + * 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 + * 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 OWNER 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. + */ +/** + * \file + * + * \brief + * This file provides Raven LED support. + * + * \author + * Harald Pichler harald@the-develop.net + * + */ + +#include "statusled.h" + +/** + * \addtogroup statusled + * \{ +*/ +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialisation Staus led +*/ +void +statusledinit(void) +{ + uint8_t temp; + + /* Get MCUCR */ + temp = MCUCR; + /* disable jtag */ + MCUCR = temp|(1< + +/** @name LED Functions */ +/** @{ */ +void statusledinit(void); +void statusled_on(void); +void statusled_off(void); +/** @} */ + +#endif /* __STATUSLED_H__ */ diff --git a/examples/osd/light-shutter-control/Makefile b/examples/osd/light-shutter-control/Makefile index 7a3466655..340032d58 100644 --- a/examples/osd/light-shutter-control/Makefile +++ b/examples/osd/light-shutter-control/Makefile @@ -1,6 +1,6 @@ -all: er-example-server -# use this target explicitly if requried: er-plugtest-server +EXE=er-example-server +all: $(EXE) # variable for this Makefile # configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) @@ -96,3 +96,10 @@ connect-router-cooja: $(CONTIKI)/tools/tunslip6 connect-minimal: sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/light-shutter-control/flash.sh b/examples/osd/light-shutter-control/flash.sh index e92d472f6..e82962073 100755 --- a/examples/osd/light-shutter-control/flash.sh +++ b/examples/osd/light-shutter-control/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-server.osd-merkur.hex:a -U eeprom:w:er-example-server.osd-merkur.eep:a +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/light-shutter-control/pcintkey.c b/examples/osd/light-shutter-control/pcintkey.c index a6e90afa5..8bbf5fcee 100644 --- a/examples/osd/light-shutter-control/pcintkey.c +++ b/examples/osd/light-shutter-control/pcintkey.c @@ -55,9 +55,32 @@ ISR(PCINT0_vect) // } // } } + +/* Compatibility of old vs new definitions in io.h */ +#ifndef DDE0 +#define DDE0 DDRE0 +#define DDE1 DDRE1 +#define DDE2 DDRE2 +#define DDE3 DDRE3 +#define DDE4 DDRE4 +#define DDE5 DDRE5 +#define DDE6 DDRE6 +#define DDE7 DDRE7 +#endif +#ifndef DDF0 +#define DDF0 DDRF0 +#define DDF1 DDRF1 +#define DDF2 DDRF2 +#define DDF3 DDRF3 +#define DDF4 DDRF4 +#define DDF5 DDRF5 +#define DDF6 DDRF6 +#define DDF7 DDRF7 +#endif + /** * \brief This will intialize the KEY for button readings. -*/ + */ void key_init(void) { diff --git a/examples/osd/light-shutter-control/run.sh b/examples/osd/light-shutter-control/run.sh index 2efd2cf48..5d5cbbbb4 100755 --- a/examples/osd/light-shutter-control/run.sh +++ b/examples/osd/light-shutter-control/run.sh @@ -1,8 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size -C --mcu=MCU=atmega128rfa1 er-example-server.osd-merkur -avr-objcopy -j .text -j .data -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.eep +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/light-shutter-control/server-only.csc b/examples/osd/light-shutter-control/server-only.csc index d5eee34d6..1b0fe28bf 100644 --- a/examples/osd/light-shutter-control/server-only.csc +++ b/examples/osd/light-shutter-control/server-only.csc @@ -1,189 +1,189 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 35.100895239785295 - 39.70574552287428 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - se.sics.cooja.plugins.SimControl - 259 - 5 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 - - 300 - 4 - 175 - 263 - 3 - - - se.sics.cooja.plugins.LogListener - - - - - 560 - 1 - 326 - 1 - 293 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 2 - 74 - 39 - 199 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - - - - - 125 - 25.49079397896416 - - 1624 - 3 - 252 - 4 - 622 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 1 - - Serial port - 0,0 - - 702 - 0 - 646 - 564 - 2 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + REST with RPL router + -2147483648 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + se.sics.cooja.interfaces.Position + 35.100895239785295 + 39.70574552287428 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + se.sics.cooja.plugins.SimControl + 259 + 5 + 179 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.AttributeVisualizerSkin + se.sics.cooja.plugins.skins.LEDVisualizerSkin + se.sics.cooja.plugins.skins.AddressVisualizerSkin + 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 + + 300 + 4 + 175 + 263 + 3 + + + se.sics.cooja.plugins.LogListener + + + + + 560 + 1 + 326 + 1 + 293 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 2 + 74 + 39 + 199 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + + + + + 125 + 25.49079397896416 + + 1624 + 3 + 252 + 4 + 622 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 702 + 0 + 646 + 564 + 2 + + + diff --git a/examples/osd/maclayertest/Makefile b/examples/osd/maclayertest/Makefile new file mode 100644 index 000000000..ffb8d687e --- /dev/null +++ b/examples/osd/maclayertest/Makefile @@ -0,0 +1,78 @@ +EXE=maclayertest + +all: $(EXE) + +CONTIKI=../../.. + +# Contiki IPv6 configuration +WITH_UIP6=1 +UIP_CONF_IPV6=1 +CFLAGS += -DUIP_CONF_IPV6=1 +CFLAGS += -DUIP_CONF_IPV6_RPL=1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) + +# linker optimizations +SMALL=1 + +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += json json-resource + +# optional rules to get assembly +#CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 +#CUSTOM_RULE_S_TO_OBJECTDIR_O = 1 + +include $(CONTIKI)/Makefile.include + +# minimal-net target is currently broken in Contiki +ifeq ($(TARGET), minimal-net) +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=1300 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=176 +CFLAGS += -DUIP_CONF_IPV6_RPL=0 +endif + +# optional rules to get assembly +#$(OBJECTDIR)/%.o: asmdir/%.S +# $(CC) $(CFLAGS) -MMD -c $< -o $@ +# @$(FINALIZE_DEPENDENCY) +# +#asmdir/%.S: %.c +# $(CC) $(CFLAGS) -MMD -S $< -o $@ + +# border router rules +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + (cd $(CONTIKI)/tools && $(MAKE) tunslip6) + +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 -p 60001 aaaa::1/64 + +connect-router-native: $(CONTIKI)/examples/ipv6/native-border-router/border-router.native + sudo $(CONTIKI)/exmples/ipv6/native-border-router/border-router.native -a 127.0.0.1 -p 60001 aaaa::1/64 + +connect-minimal: + sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/maclayertest/README.md b/examples/osd/maclayertest/README.md new file mode 100644 index 000000000..0a02cf8e6 --- /dev/null +++ b/examples/osd/maclayertest/README.md @@ -0,0 +1,14 @@ +Potentiometer Driver +==================== + +This App allows sending potentiometer values to a remote node. This is +currently used to change colors of the led-strip app but the resource +used and the IP address are configurable -- so we can use it for any +other destination. + +The app sends its value to the remote only if the value has changed. In +addition it has a retransmit interval (in seconds) that can retransmit +the value after a timeout if the value has not changed. Setting this +retransmit interval to 0 will turn off the retransmit feature. Note that +we sample the value only every second: We don't want to use up the whole +bandwidth for this app alone. diff --git a/examples/osd/maclayertest/flash.sh b/examples/osd/maclayertest/flash.sh new file mode 100755 index 000000000..e82962073 --- /dev/null +++ b/examples/osd/maclayertest/flash.sh @@ -0,0 +1,2 @@ +#!/bin/bash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/maclayertest/maclayertest.c b/examples/osd/maclayertest/maclayertest.c new file mode 100644 index 000000000..177eebc1b --- /dev/null +++ b/examples/osd/maclayertest/maclayertest.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2015, Ralf Schlatterbeck Open Source Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Potentiometer for regulating LED-strip brightness per color + * \author + * Ralf Schlatterbeck + */ + +#include +#include +#include +#include +#include "contiki.h" +#include "contiki-net.h" +#include "rest-engine.h" +#include "er-coap-engine.h" +#include "uiplib.h" +#include "generic_resource.h" +#include "Arduino.h" + +/* + * Resources to be activated need to be imported through the extern keyword. + * The build system automatically compiles the resources in the + * corresponding sub-directory. + */ + +#if PLATFORM_HAS_BATTERY +#include "dev/battery-sensor.h" +extern resource_t res_battery; +#endif + +#if PLATFORM_HAS_RADIO +#include "dev/radio-sensor.h" +extern resource_t res_radio; +#endif + +#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT) +// should be the same :-) +#define UIP_NTOHS(x) UIP_HTONS(x) +#define SERVER_NODE(ip) \ + uip_ip6addr(ip,0xfe80,0,0,0,0x0221,0x2eff,0xff00,0x665a) + /*uip_ip6addr(ip,0x2001,0xdb8,0xc001,0xf00d,0x22e,0xffff,0x34,0xa600)*/ +#define LOOP_INTERVAL (2 * CLOCK_SECOND) + +uip_ipaddr_t server_ipaddr, tmp_addr; +char server_resource [20] = "s/led"; +int interval = 2; /* Retransmit interval after no change in value */ + +uint8_t led_pin=4; +uint8_t led_status; + + +static size_t +ip_to_string (const char *name, const char *uri, char *buf, size_t bsize) +{ + #define IP(x) UIP_NTOHS(server_ipaddr.u16[x]) + return snprintf + ( buf, bsize, "%x:%x:%x:%x:%x:%x:%x:%x" + , IP(0), IP(1), IP(2), IP(3), IP(4), IP(5), IP(6), IP(7) + ); +} + +int ip_from_string (const char *name, const char *uri, const char *s) +{ + /* Returns 1 if successful, only copy valid address */ + if (uiplib_ip6addrconv (s, &tmp_addr)) { + uip_ip6addr_copy (&server_ipaddr, &tmp_addr); + return 0; + } + return -1; +} + +GENERIC_RESOURCE + ( server_ip + , ip + , ipv6_address + , 1 + , ip_from_string + , ip_to_string + ); + +static size_t +resource_to_string (const char *name, const char *uri, char *buf, size_t bsize) +{ + return snprintf (buf, bsize, "%s", server_resource); +} + +int resource_from_string (const char *name, const char *uri, const char *s) +{ + strncpy (server_resource, s, sizeof (server_resource)); + server_resource [sizeof (server_resource) - 1] = 0; + return 0; +} + +GENERIC_RESOURCE + ( server_resource + , led-resource + , resource-name + , 1 + , resource_from_string + , resource_to_string + ); + +static size_t +interval_to_string (const char *name, const char *uri, char *buf, size_t bsize) +{ + return snprintf (buf, bsize, "%d", interval); +} + +int interval_from_string (const char *name, const char *uri, const char *s) +{ + interval = atoi (s); + return 0; +} + +GENERIC_RESOURCE + ( interval + , interval + , s + , 0 + , interval_from_string + , interval_to_string + ); + +/* Passed to COAP_BLOCKING_REQUEST to handle responses */ +void chunk_handler (void *response) +{ + const uint8_t *chunk; + int len = coap_get_payload (response, &chunk); + printf ("|%.*s", len, (char *)chunk); +} + +PROCESS(poti, "Potentiometer"); +AUTOSTART_PROCESSES(&poti); + +PROCESS_THREAD(poti, ev, data) +{ + + static struct etimer loop_timer; + PROCESS_BEGIN(); + + /* Initialize the REST engine. */ + rest_init_engine (); + SERVER_NODE (&server_ipaddr); + + // switch off the led + pinMode(led_pin, OUTPUT); + digitalWrite(led_pin, HIGH); + led_status=0; + + /* Activate the application-specific resources. */ +#if PLATFORM_HAS_BATTERY + SENSORS_ACTIVATE(battery_sensor); + rest_activate_resource (&res_battery, "s/battery"); +#endif + rest_activate_resource (&res_server_ip, "poti/ip"); + rest_activate_resource (&res_server_resource, "poti/resource"); + rest_activate_resource (&res_interval, "poti/interval"); + + etimer_set (&loop_timer, LOOP_INTERVAL); + /* Define application-specific events here. */ + while(1) { + static coap_packet_t request [1]; /* Array: treat as pointer */ + static uint8_t val = 0; + + PROCESS_WAIT_EVENT(); + if (etimer_expired (&loop_timer)) { + + if (1) { + char buf [9]; + coap_transaction_t *transaction; + if(val==0){ + sprintf (buf, "mode=%s", "on"); + val=1; + digitalWrite(led_pin, LOW); + led_status=1; + }else{ + sprintf (buf, "mode=%s", "off"); + val=0; + digitalWrite(led_pin, HIGH); + led_status=0; + } + printf ("%s\n", buf); + coap_init_message (request, COAP_TYPE_NON, COAP_PUT, 0); + coap_set_header_uri_path (request, server_resource); + coap_set_header_content_format (request, REST.type.TEXT_PLAIN); + coap_set_payload (request, buf, strlen (buf)); + request->mid = coap_get_mid (); + transaction = coap_new_transaction + (request->mid, &server_ipaddr, REMOTE_PORT); + transaction->packet_len = coap_serialize_message + (request, transaction->packet); + coap_send_transaction (transaction); + } + etimer_reset (&loop_timer); + } + } /* while (1) */ + + PROCESS_END(); +} diff --git a/examples/osd/maclayertest/project-conf.h b/examples/osd/maclayertest/project-conf.h new file mode 100644 index 000000000..ab46b9879 --- /dev/null +++ b/examples/osd/maclayertest/project-conf.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013, Matthias Kovatsch + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ + +#ifndef PROJECT_ERBIUM_CONF_H_ +#define PROJECT_ERBIUM_CONF_H_ + +#define PLATFORM_HAS_INFO 1 +#define PLATFORM_HAS_BATTERY 1 +#define PLATFORM_HAS_DS1820 1 +#define PLATFORM_HAS_DHT11HUM 1 +//#define PLATFORM_HAS_DHT11TEMP 1 +#define PLATFORM_HAS_LEDS 1 + + +/* Some platforms have weird includes. */ +#undef IEEE802154_CONF_PANID + +/* Disabling RDC for demo purposes. Core updates often require more memory. */ +/* For projects, optimize memory and enable RDC again. */ +// #undef NETSTACK_CONF_RDC +//#define NETSTACK_CONF_RDC nullrdc_driver + +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 64 + +/* Estimate your header size, especially when using Proxy-Uri. */ +/* +#undef COAP_MAX_HEADER_SIZE +#define COAP_MAX_HEADER_SIZE 70 +*/ + +/* The IP buffer size must fit all other hops, in particular the border router. */ + +#undef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 256 + + +/* Multiplies with chunk size, be aware of memory constraints. */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* +#undef COAP_MAX_OBSERVERS +#define COAP_MAX_OBSERVERS 2 +*/ + +/* Filtering .well-known/core per query can be disabled to save space. */ +/* +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +*/ + +/* Save some memory for the sky platform. */ +/* +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 10 +*/ + +/* Reduce 802.15.4 frame queue to save RAM. */ +/* +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 +*/ + +/* +#undef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +*/ + +/* For Debug: Dont allow MCU sleeping between channel checks */ +#undef RDC_CONF_MCU_SLEEP +#define RDC_CONF_MCU_SLEEP 0 + +#endif /* PROJECT_ERBIUM_CONF_H_ */ diff --git a/examples/osd/maclayertest/run.sh b/examples/osd/maclayertest/run.sh new file mode 100755 index 000000000..5d5cbbbb4 --- /dev/null +++ b/examples/osd/maclayertest/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/merkurboard/Makefile b/examples/osd/merkurboard/Makefile index 60d971598..9cd7198da 100644 --- a/examples/osd/merkurboard/Makefile +++ b/examples/osd/merkurboard/Makefile @@ -1,77 +1,46 @@ -all: er-example-server er-example-client -# use this target explicitly if requried: er-plugtest-server +EXE=er-example-server er-example-client - -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 - -# for some platforms -UIP_CONF_IPV6=1 -# IPv6 make config disappeared completely -CFLAGS += -DUIP_CONF_IPV6=1 +all: $(EXE) CONTIKI=../../.. + CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" -# variable for Makefile.include -ifneq ($(TARGET), minimal-net) -CFLAGS += -DUIP_CONF_IPV6_RPL=1 -else -# minimal-net does not support RPL under Linux and is mostly used to test CoAP only -${info INFO: compiling without RPL} -CFLAGS += -DUIP_CONF_IPV6_RPL=0 -CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" -${info INFO: compiling with large buffers} -CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048 -CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 -CFLAGS += -DCOAP_MAX_HEADER_SIZE=640 -endif +# automatically build RESTful resources including common resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES = $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) # linker optimizations SMALL=1 -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif - -APPS += erbium +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine # optional rules to get assembly #CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 #CUSTOM_RULE_S_TO_OBJECTDIR_O = 1 +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include +# minimal-net target is currently broken in Contiki +ifeq ($(TARGET), minimal-net) +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: er-example compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=1300 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=176 +CONTIKI_WITH_RPL=0 +endif + # optional rules to get assembly #$(OBJECTDIR)/%.o: asmdir/%.S # $(CC) $(CFLAGS) -MMD -c $< -o $@ @@ -88,7 +57,23 @@ connect-router: $(CONTIKI)/tools/tunslip6 sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 connect-router-cooja: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 -p 60001 aaaa::1/64 + +connect-router-native: $(CONTIKI)/examples/ipv6/native-border-router/border-router.native + sudo $(CONTIKI)/exmples/ipv6/native-border-router/border-router.native -a 127.0.0.1 -p 60001 aaaa::1/64 connect-minimal: - sudo ip address add fdfd::1/64 dev tap0 + sudo ip address add fdfd::1/64 dev tap0 + +avr-size-server: er-example-server.$(TARGET).sz + +avr-size-client: er-example-server.$(TARGET).sz + +flash-server: er-example-server.$(TARGET).u er-example-server.$(TARGET).eu + +flash-client: er-example-client.$(TARGET).u er-example-client.$(TARGET).eu + +.PHONY: flash-client avr-size-client flash-server avr-size-server +.PRECIOUS: er-example-server.$(TARGET).hex er-example-server.$(TARGET).eep \ + er-example-client.$(TARGET).hex er-example-client.$(TARGET).eep + diff --git a/examples/osd/merkurboard/README.md b/examples/osd/merkurboard/README.md index 1aa35b091..fe82ed9b5 100644 --- a/examples/osd/merkurboard/README.md +++ b/examples/osd/merkurboard/README.md @@ -21,6 +21,7 @@ PRELIMINARIES You can disable RDC in border-router project-conf.h (not really required as BR keeps radio turned on). #undef NETSTACK_CONF_RDC #define NETSTACK_CONF_RDC nullrdc_driver +- Alternatively, you can use the native-border-router together with the slip-radio. - For convenience, define the Cooja addresses in /etc/hosts aaaa::0212:7401:0001:0101 cooja1 aaaa::0212:7402:0002:0202 cooja2 @@ -125,10 +126,10 @@ Under Windows/Cygwin, WPCAP might need a patch in DETAILS ------- -Erbium currently implements draft 13. Central features are commented in -er-example-server.c. In general, apps/er-coap-13 supports: +Erbium implements the Proposed Standard of CoAP. Central features are commented +in er-example-server.c. In general, apps/er-coap supports: -- All draft 13 header options +- All draft-18 header options - CON Retransmissions (note COAP_MAX_OPEN_TRANSACTIONS) - Blockwise Transfers (note REST_MAX_CHUNK_SIZE, see er-plugtest-server.c for Block1 uploads) @@ -138,24 +139,6 @@ er-example-server.c. In general, apps/er-coap-13 supports: - Observing Resources (see EVENT_ and PRERIODIC_RESOURCE, note COAP_MAX_OBSERVERS) -REST IMPLEMENTATIONS --------------------- - -The Makefile uses WITH_COAP to configure different implementations for the -Erbium (Er) REST Engine. - -- WITH_COAP=13 uses Erbium CoAP 13 apps/er-coap-13/. The default port for - coap-13 is 5683. -- WITH_COAP=12 uses Erbium CoAP 12 apps/er-coap-12/. The default port for - coap-12 is 5683. -- WITH_COAP=7 uses Erbium CoAP 08 apps/er-coap-07/. The default port for - coap-07/-08 is 5683. -- WITH_COAP=3 uses Erbium CoAP 03 apps/er-coap-03/. The default port for - coap-03 is 61616. er-coap-03 produces some warnings, as it not fully - maintained anymore. -- WITH_COAP=0 is a stub to link an Erbium HTTP engine that uses the same - resource abstraction (REST.x() functions and RESOURCE macros. - TODOs ----- diff --git a/examples/osd/merkurboard/er-example-client.c b/examples/osd/merkurboard/er-example-client.c index 14b5a291a..40c6f353b 100644 --- a/examples/osd/merkurboard/er-example-client.c +++ b/examples/osd/merkurboard/er-example-client.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Matthias Kovatsch + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,7 +31,7 @@ /** * \file - * Erbium (Er) CoAP client example + * Erbium (Er) CoAP client example. * \author * Matthias Kovatsch */ @@ -39,55 +39,46 @@ #include #include #include - #include "contiki.h" #include "contiki-net.h" - +#include "er-coap-engine.h" #include "dev/button-sensor.h" -#include "dev/leds.h" - -#if WITH_COAP == 3 -#include "er-coap-03-engine.h" -#elif WITH_COAP == 6 -#include "er-coap-06-engine.h" -#elif WITH_COAP == 7 -#include "er-coap-07-engine.h" -#elif WITH_COAP == 12 -#include "er-coap-12-engine.h" -#elif WITH_COAP == 13 -#include "er-coap-13-engine.h" -#else -#error "CoAP version defined by WITH_COAP not implemented" -#endif - #define DEBUG 0 #if DEBUG +#include #define PRINTF(...) printf(__VA_ARGS__) #define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) #else #define PRINTF(...) #define PRINT6ADDR(addr) #define PRINTLLADDR(addr) #endif -/* TODO: This server address is hard-coded for Cooja. */ -#define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0221, 0x2eff, 0xff00, 0x26e6) /* cooja2 */ +/* FIXME: This server address is hard-coded for Cooja and link-local for unconnected border router. */ +#define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0221, 0x2eff, 0xff00, 0x3305) /* cooja2 */ +/* #define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xbbbb, 0, 0, 0, 0, 0, 0, 0x1) */ -#define LOCAL_PORT UIP_HTONS(COAP_DEFAULT_PORT+1) +#define LOCAL_PORT UIP_HTONS(COAP_DEFAULT_PORT + 1) #define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT) -PROCESS(coap_client_example, "COAP Client Example"); -AUTOSTART_PROCESSES(&coap_client_example); +#define TOGGLE_INTERVAL 10 +PROCESS(er_example_client, "Erbium Example Client"); +AUTOSTART_PROCESSES(&er_example_client); uip_ipaddr_t server_ipaddr; +static struct etimer et; /* Example URIs that can be queried. */ #define NUMBER_OF_URLS 4 /* leading and ending slashes only for demo purposes, get cropped automatically when setting the Uri-Path */ -char* service_urls[NUMBER_OF_URLS] = {".well-known/core", "/actuators/toggle", "battery/", "error/in//path"}; +char *service_urls[NUMBER_OF_URLS] = +{ ".well-known/core", "/a/toggle", "/s/battery/", "error/in//path" }; +#if PLATFORM_HAS_BUTTON +static int uri_switch = 1; +#endif /* This function is will be passed to COAP_BLOCKING_REQUEST() to handle responses. */ void @@ -96,53 +87,48 @@ client_chunk_handler(void *response) const uint8_t *chunk; int len = coap_get_payload(response, &chunk); + printf("|%.*s", len, (char *)chunk); } - - -PROCESS_THREAD(coap_client_example, ev, data) +PROCESS_THREAD(er_example_client, ev, data) { PROCESS_BEGIN(); - leds_off(LEDS_RED); + static coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ - static coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ SERVER_NODE(&server_ipaddr); /* receives all CoAP messages */ - coap_receiver_init(); + coap_init_engine(); + + etimer_set(&et, TOGGLE_INTERVAL * CLOCK_SECOND); #if PLATFORM_HAS_BUTTON SENSORS_ACTIVATE(button_sensor); - PRINTF("Press a button to request %s\n", service_urls[1]); + printf("Press a button to request %s\n", service_urls[uri_switch]); #endif while(1) { PROCESS_YIELD(); -#if PLATFORM_HAS_BUTTON - if (ev == sensors_event && data == &button_sensor) { + if(ev == sensors_event && data == &button_sensor) { /* send a request to notify the end of the process */ + coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0); + coap_set_header_uri_path(request, service_urls[uri_switch]); - PRINTF("--Toggle --\n"); - leds_toggle(LEDS_RED); - /* prepare request, TID is set by COAP_BLOCKING_REQUEST() */ - coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0 ); - coap_set_header_uri_path(request, service_urls[1]); - - const char msg[] = "Toggle!"; - coap_set_payload(request, (uint8_t *)msg, sizeof(msg)-1); - + printf("--Requesting %s--\n", service_urls[uri_switch]); PRINT6ADDR(&server_ipaddr); PRINTF(" : %u\n", UIP_HTONS(REMOTE_PORT)); - COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, client_chunk_handler); + COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, + client_chunk_handler); + + printf("\n--Done--\n"); + - PRINTF("\n--Done--\n"); } -#endif } PROCESS_END(); diff --git a/examples/osd/merkurboard/er-example-server.c b/examples/osd/merkurboard/er-example-server.c index 5e79f8468..01686bcd4 100644 --- a/examples/osd/merkurboard/er-example-server.c +++ b/examples/osd/merkurboard/er-example-server.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Matthias Kovatsch + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,59 +29,9 @@ * This file is part of the Contiki operating system. */ -/* -From: -http://tools.ietf.org/id/draft-ietf-core-interfaces-01.txt - -Appendix A. Profile example - - The following is a short definition of simple profile. This - simplistic profile is for use in the examples of this document. - - +--------------------+-----------+------------+---------+ - | Function Set | Root Path | RT | IF | - +--------------------+-----------+------------+---------+ - | Device Description | /d | simple.dev | core.ll | - | Sensors | /s | simple.sen | core.b | - | Actuators | /a | simple.act | core.b | - +--------------------+-----------+------------+---------+ - - List of Function Sets - - +-------+----------+----------------+---------+------------+ - | Type | Path | RT | IF | Data Type | - +-------+----------+----------------+---------+------------+ - | Name | /d/name | simple.dev.n | core.p | xsd:string | - | Model | /d/model | simple.dev.mdl | core.rp | xsd:string | - +-------+----------+----------------+---------+------------+ - - Device Description Function Set - - +-------------+-------------+----------------+--------+-------------+ - | Type | Path | RT | IF | Data Type | - +-------------+-------------+----------------+--------+-------------+ - | Light | /s/light | simple.sen.lt | core.s | xsd:decimal | - | | | | | (lux) | - | Humidity | /s/humidity | simple.sen.hum | core.s | xsd:decimal | - | | | | | (%RH) | - | Temperature | /s/temp | simple.sen.tmp | core.s | xsd:decimal | - | | | | | (degC) | - +-------------+-------------+----------------+--------+-------------+ - - Sensors Function Set - - +------+------------+----------------+--------+-------------+ - | Type | Path | RT | IF | Data Type | - +------+------------+----------------+--------+-------------+ - | LED | /a/{#}/led | simple.act.led | core.a | xsd:boolean | - +------+------------+----------------+--------+-------------+ - - Actuators Function Set -*/ - /** * \file - * Erbium (Er) REST Engine example (with CoAP-specific code) + * Erbium (Er) REST Engine example. * \author * Matthias Kovatsch */ @@ -91,380 +41,71 @@ Appendix A. Profile example #include #include "contiki.h" #include "contiki-net.h" -#include +#include "rest-engine.h" -/* Define which resources to include to meet memory constraints. */ -#define REST_RES_MODEL 1 -#define REST_RES_NAME 1 -#define REST_RES_SW 1 -#define REST_RES_EVENT 1 -#define REST_RES_LED 1 -#define REST_RES_TOGGLE 1 -#define REST_RES_BATTERY 1 -#define REST_RES_TEMPERATURE 1 - -#include "erbium.h" - -#if defined (PLATFORM_HAS_BUTTON) +#if PLATFORM_HAS_BUTTON #include "dev/button-sensor.h" #endif -#if defined (PLATFORM_HAS_LED) -#include "dev/leds.h" -#endif -#if defined (PLATFORM_HAS_BATTERY) -#include "dev/battery-sensor.h" -#endif -#if defined (PLATFORM_HAS_TEMPERATURE) -#include "dev/temperature-sensor.h" -#endif - -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP == 3 -#include "er-coap-03.h" -#elif WITH_COAP == 7 -#include "er-coap-07.h" -#elif WITH_COAP == 12 -#include "er-coap-12.h" -#elif WITH_COAP == 13 -#include "er-coap-13.h" -#else -#warning "Erbium example without CoAP-specifc functionality" -#endif /* CoAP-specific example */ #define DEBUG 0 #if DEBUG +#include #define PRINTF(...) printf(__VA_ARGS__) #define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) #else #define PRINTF(...) #define PRINT6ADDR(addr) #define PRINTLLADDR(addr) #endif - -/******************************************************************************/ -#if REST_RES_MODEL /* - * Resources are defined by the RESOURCE macro. - * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). + * Resources to be activated need to be imported through the extern keyword. + * The build system automatically compiles the resources in the corresponding sub-directory. */ -RESOURCE(model, METHOD_GET, "p/model", "title=\"model\";rt=\"simple.dev.mdl\""); - -/* - * A handler function named [resource name]_handler must be implemented for each RESOURCE. - * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore - * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. - * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. - */ -void -model_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - char message[100]; - int index = 0; - int length = 0; /* |<-------->| */ - - /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ - // jSON Format - index += sprintf(message + index,"{\n \"model\" : \"Merkurboard\"\n"); - index += sprintf(message + index,"}\n"); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - REST.set_response_payload(response, buffer, length); -} +extern resource_t + res_hello, + res_mirror, + res_separate, + res_push, + res_event, + res_sub; +#if PLATFORM_HAS_LEDS +#include "dev/leds.h" +extern resource_t res_leds, res_toggle; #endif - -/******************************************************************************/ -#if REST_RES_SW -/* - * Resources are defined by the RESOURCE macro. - * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). - */ -RESOURCE(sw, METHOD_GET, "p/sw", "title=\"Software Version\";rt=\"simple.dev.sv\""); - -/* - * A handler function named [resource name]_handler must be implemented for each RESOURCE. - * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore - * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. - * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. - */ -void -sw_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - char message[100]; - int index = 0; - int length = 0; /* |<-------->| */ - - /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ - // jSON Format - index += sprintf(message + index,"{\n \"sw\" : \"V0.8\"\n"); - index += sprintf(message + index,"}\n"); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - REST.set_response_payload(response, buffer, length); -} +#if PLATFORM_HAS_LIGHT +#include "dev/light-sensor.h" +extern resource_t res_light; #endif - -/******************************************************************************/ -#if REST_RES_NAME -/* - * Resources are defined by the RESOURCE macro. - * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). - */ -RESOURCE(name, METHOD_POST | METHOD_GET, "p/name", "title=\"name\";rt=\"simple.dev.n\""); -/* eeprom space */ -#define P_NAME "Testboard" -#define P_NAME_MAX 17 -uint8_t eemem_p_name[P_NAME_MAX] EEMEM = P_NAME; - -/* - * A handler function named [resource name]_handler must be implemented for each RESOURCE. - * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore - * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. - * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. - */ -void -name_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - uint8_t eebuffer[32]; - char message[100]; - int index = 0; - int length = 0; /* |<-------->| */ - const char *name = NULL; - int success = 1; - - switch(REST.get_method_type(request)){ - case METHOD_GET: - cli(); - eeprom_read_block (eebuffer, &eemem_p_name, sizeof(eemem_p_name)); - sei(); - /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ - // jSON Format - index += sprintf(message + index,"{\n \"name\" : \"%s\"\n",eebuffer); - index += sprintf(message + index,"}\n"); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - REST.set_response_payload(response, buffer, length); - break; - - case METHOD_POST: - if (success && (length=REST.get_post_variable(request, "name", &name))) { - PRINTF("name %s\n", name); - if (length < P_NAME_MAX) { - memcpy(&eebuffer, name,length); - eebuffer[length]=0; - cli(); - eeprom_write_block(&eebuffer, &eemem_p_name, sizeof(eemem_p_name)); - sei(); - } else { - success = 0; - } - } else { - success = 0; - } - break; - default: - success = 0; - } - if (!success) { - REST.set_response_status(response, REST.status.BAD_REQUEST); - } -} +#if PLATFORM_HAS_BATTERY +#include "dev/battery-sensor.h" +extern resource_t res_battery; #endif - -/******************************************************************************/ -#if REST_RES_EVENT && defined (PLATFORM_HAS_BUTTON) /* - * Example for an event resource. - * Additionally takes a period parameter that defines the interval to call [name]_periodic_handler(). - * A default post_handler takes care of subscriptions and manages a list of subscribers to notify. - */ -EVENT_RESOURCE(event, METHOD_GET, "s/button", "title=\"Event demo\";obs"); - -void -event_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - char message[100]; - int index = 0; - int length = 0; /* |<-------->| */ - int button = button_sensor.value(0); - - index += sprintf(message + index,"%d",button); - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, buffer, length); - - /* A post_handler that handles subscriptions/observing will be called for periodic resources by the framework. */ -} - -/* Additionally, a handler function named [resource name]_event_handler must be implemented for each PERIODIC_RESOURCE defined. - * It will be called by the REST manager process with the defined period. */ -void -event_event_handler(resource_t *r) -{ - static uint16_t event_counter = 0; - static char content[12]; - - ++event_counter; - - PRINTF("TICK %u for /%s\n", event_counter, r->url); - - /* Build notification. */ - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_CON, REST.status.OK, 0 ); - coap_set_payload(notification, content, snprintf(content, sizeof(content), "EVENT %u", event_counter)); - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(r, event_counter, notification); -} -#endif /* PLATFORM_HAS_BUTTON */ - - -/******************************************************************************/ -#if defined (PLATFORM_HAS_LED) -/******************************************************************************/ -#if REST_RES_LED -/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -RESOURCE(led, METHOD_POST | METHOD_PUT , "a/led", "title=\"LED: POST/PUT mode=on|off\";rt=\"simple.act.led\""); - -void -led_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - size_t len = 0; - const char *mode = NULL; - uint8_t led = 0; - int success = 1; - - led = LEDS_RED; - - if (success && (len=REST.get_post_variable(request, "mode", &mode))) { - PRINTF("mode %s\n", mode); - - if (strncmp(mode, "on", len)==0) { - leds_on(led); - } else if (strncmp(mode, "off", len)==0) { - leds_off(led); - } else { - success = 0; - } - } else { - success = 0; - } - - if (!success) { - REST.set_response_status(response, REST.status.BAD_REQUEST); - } -} +#if PLATFORM_HAS_RADIO +#include "dev/radio-sensor.h" +extern resource_t res_radio; #endif - -/******************************************************************************/ -#if REST_RES_TOGGLE -/* A simple actuator example. Toggles the red led */ -RESOURCE(toggle, METHOD_POST, "a/toggle", "title=\"Red LED\";rt=\"Control\""); -void -toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - leds_toggle(LEDS_RED); -} -#endif -#endif /* PLATFORM_HAS_LED */ - -/******************************************************************************/ -#if REST_RES_BATTERY && defined (PLATFORM_HAS_BATTERY) -/* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(battery, METHOD_GET, "s/battery", "title=\"Battery status\";rt=\"Battery\""); -void -battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int battery = battery_sensor.value(0); - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d.%02d", battery/1000, battery % 1000); - - REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"battery\":%d.%02d}", battery/1000, battery % 1000); - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain and application/json"; - REST.set_response_payload(response, msg, strlen(msg)); - } -} -#endif /* PLATFORM_HAS_BATTERY */ - -/******************************************************************************/ -#if REST_RES_TEMPERATURE && defined (PLATFORM_HAS_TEMPERATURE) -/* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(temperature, METHOD_GET, "s/cputemp", "title=\"CPU Temperature\";rt=\"simple.sen.tmp\""); -void -temperature_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int temperature = temperature_sensor.value(0); - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d.%02d", temperature/100, temperature % 100); - - REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%d.%02d}", temperature/100, temperature % 100); - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain and application/json"; - REST.set_response_payload(response, msg, strlen(msg)); - } -} -#endif /* PLATFORM_HAS_TEMPERATURE */ +*/ void hw_init() { -#if defined (PLATFORM_HAS_LED) +#if defined (PLATFORM_HAS_LEDS) leds_off(LEDS_RED); #endif } -PROCESS(rest_server_example, "Erbium Example Server"); -AUTOSTART_PROCESSES(&rest_server_example); +PROCESS(er_example_server, "Erbium Example Server"); +AUTOSTART_PROCESSES(&er_example_server); -PROCESS_THREAD(rest_server_example, ev, data) +PROCESS_THREAD(er_example_server, ev, data) { PROCESS_BEGIN(); + PROCESS_PAUSE(); + PRINTF("Starting Erbium Example Server\n"); #ifdef RF_CHANNEL @@ -479,55 +120,53 @@ PROCESS_THREAD(rest_server_example, ev, data) PRINTF("IP+UDP header: %u\n", UIP_IPUDPH_LEN); PRINTF("REST max chunk: %u\n", REST_MAX_CHUNK_SIZE); - /* Initialize the OSD Hardware. */ hw_init(); /* Initialize the REST engine. */ rest_init_engine(); - /* Activate the application-specific resources. */ -#if REST_RES_MODEL - rest_activate_resource(&resource_model); + /* + * Bind the resources to their Uri-Path. + * WARNING: Activating twice only means alternate path, not two instances! + * All static variables are the same for each URI path. + */ + rest_activate_resource(&res_hello, "test/hello"); + rest_activate_resource(&res_push, "test/push"); + rest_activate_resource(&res_event, "s/button"); +#if PLATFORM_HAS_LEDS + rest_activate_resource(&res_leds, "a/leds"); + rest_activate_resource(&res_toggle, "a/toggle"); #endif -#if REST_RES_SW - rest_activate_resource(&resource_sw); +#if PLATFORM_HAS_LIGHT + rest_activate_resource(&res_light, "s/light"); + SENSORS_ACTIVATE(light_sensor); #endif -#if REST_RES_NAME - rest_activate_resource(&resource_name); + +#if PLATFORM_HAS_BATTERY + rest_activate_resource(&res_battery, "s/battery"); + SENSORS_ACTIVATE(battery_sensor); #endif -#if defined (PLATFORM_HAS_BUTTON) && REST_RES_EVENT - rest_activate_event_resource(&resource_event); - SENSORS_ACTIVATE(button_sensor); -#endif -#if defined (PLATFORM_HAS_LED) -#if REST_RES_LED - rest_activate_resource(&resource_led); -#endif -#if REST_RES_TOGGLE - rest_activate_resource(&resource_toggle); -#endif -#endif /* PLATFORM_HAS_LED */ -#if defined (PLATFORM_HAS_BATTERY) && REST_RES_BATTERY - SENSORS_ACTIVATE(battery_sensor); - rest_activate_resource(&resource_battery); -#endif -#if defined (PLATFORM_HAS_TEMPERATURE) && REST_RES_TEMPERATURE - SENSORS_ACTIVATE(temperature_sensor); - rest_activate_resource(&resource_temperature); +/* +#if PLATFORM_HAS_RADIO + rest_activate_resource(&res_radio, "s/radio"); + SENSORS_ACTIVATE(radio_sensor); #endif +*/ /* Define application-specific events here. */ while(1) { PROCESS_WAIT_EVENT(); -#if defined (PLATFORM_HAS_BUTTON) - if (ev == sensors_event && data == &button_sensor) { - PRINTF("BUTTON\n"); -#if REST_RES_EVENT +#if PLATFORM_HAS_BUTTON + if(ev == sensors_event && data == &button_sensor) { + PRINTF("*******BUTTON*******\n"); + /* Call the event_handler for this application-specific event. */ - event_event_handler(&resource_event); -#endif + res_event.trigger(); + + /* Also call the separate response example handler. */ + res_separate.resume(); } #endif /* PLATFORM_HAS_BUTTON */ - } /* while (1) */ + } /* while (1) */ PROCESS_END(); } diff --git a/examples/osd/merkurboard/er-plugtest-server.c b/examples/osd/merkurboard/er-plugtest-server.c index 5a791a09c..ae637dc4c 100644 --- a/examples/osd/merkurboard/er-plugtest-server.c +++ b/examples/osd/merkurboard/er-plugtest-server.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Matthias Kovatsch + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,7 +31,7 @@ /** * \file - * Server for the ETSI IoT CoAP Plugtests, Paris, France, 24 - 25 March 2012 + * Server for the ETSI IoT CoAP Plugtests, Las Vegas, NV, USA, Nov 2013. * \author * Matthias Kovatsch */ @@ -41,1179 +41,37 @@ #include #include "contiki.h" #include "contiki-net.h" - -#define MAX_PLUGFEST_PAYLOAD 64+1 /* +1 for the terminating zero, which is not transmitted */ -#define MAX_PLUGFEST_BODY 2048 -#define CHUNKS_TOTAL 2012 - -/* Define which resources to include to meet memory constraints. */ -#define REST_RES_TEST 1 -#define REST_RES_LONG 1 -#define REST_RES_QUERY 1 -#define REST_RES_LOC_QUERY 1 -#define REST_RES_MULTI 1 -#define REST_RES_LINKS 1 -#define REST_RES_PATH 1 -#define REST_RES_SEPARATE 1 -#define REST_RES_LARGE 1 -#define REST_RES_LARGE_UPDATE 1 -#define REST_RES_LARGE_CREATE 1 -#define REST_RES_OBS 1 - -#define REST_RES_MIRROR 1 - - - -#if !defined (CONTIKI_TARGET_MINIMAL_NET) -#warning "Should only be compiled for minimal-net!" -#endif - - - -#include "erbium.h" - -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP==7 -#include "er-coap-07.h" -#elif WITH_COAP == 12 -#include "er-coap-12.h" -#elif WITH_COAP == 13 -#include "er-coap-13.h" -#else -#error "Plugtests server without CoAP" -#endif /* CoAP-specific example */ - -#define DEBUG 1 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - - -#if REST_RES_TEST -/* - * Default test resource - */ -RESOURCE(test, METHOD_GET|METHOD_POST|METHOD_PUT|METHOD_DELETE, "test", "title=\"Default test resource\""); - -static uint8_t test_etag[8] = {0}; -static uint8_t test_etag_len = 1; -static uint8_t test_change = 1; -static uint8_t test_none_match_okay = 1; - -static -void -test_update_etag() -{ - int i; - test_etag_len = (random_rand() % 8) + 1; - for (i=0; i0 && len==test_etag_len && memcmp(test_etag, bytes, len)==0) - { - PRINTF("validate "); - REST.set_response_status(response, REST.status.NOT_MODIFIED); - REST.set_header_etag(response, test_etag, test_etag_len); - - test_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } - else - { - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_header_etag(response, test_etag, test_etag_len); - REST.set_header_max_age(response, 30); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); - } - } - else if (method & METHOD_POST) - { - PRINTF("POST "); - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "/location1/location2/location3"); - } - else if (method & METHOD_PUT) - { - PRINTF("PUT "); - - if (coap_get_header_if_none_match(request)) - { - if (test_none_match_okay) - { - REST.set_response_status(response, REST.status.CREATED); - - test_none_match_okay = 0; - PRINTF("### SERVER ACTION ### If-None-Match will FAIL\n"); - } - else - { - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - - test_none_match_okay = 1; - PRINTF("### SERVER ACTION ### If-None-Match will SUCCEED\n"); - } - } - else if (((len = coap_get_header_if_match(request, &bytes))>0 && (len==test_etag_len && memcmp(test_etag, bytes, len)==0)) || len==0) - { - test_update_etag(); - REST.set_header_etag(response, test_etag, test_etag_len); - - REST.set_response_status(response, REST.status.CHANGED); - - if (len>0) - { - test_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } - } - else - { - - PRINTF("Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X] ", len, test_etag_len, - bytes[0], - bytes[1], - bytes[2], - bytes[3], - bytes[4], - bytes[5], - bytes[6], - bytes[7], - test_etag[0], - test_etag[1], - test_etag[2], - test_etag[3], - test_etag[4], - test_etag[5], - test_etag[6], - test_etag[7] ); - - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } - else if (method & METHOD_DELETE) - { - PRINTF("DELETE "); - REST.set_response_status(response, REST.status.DELETED); - } - - PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); -} - - -RESOURCE(create1, METHOD_PUT|METHOD_DELETE, "create1", "title=\"Default test resource\""); - -static uint8_t create1_exists = 0; - -void -create1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - uint8_t method = REST.get_method_type(request); - - if (test_change) - { - test_update_etag(); - } - - PRINTF("/create1 "); - - if (method & METHOD_PUT) - { - PRINTF("PUT "); - - if (coap_get_header_if_none_match(request)) - { - if (!create1_exists) - { - REST.set_response_status(response, REST.status.CREATED); - - create1_exists = 1; - } - else - { - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } - else - { - REST.set_response_status(response, REST.status.CHANGED); - } - } - else if (method & METHOD_DELETE) - { - PRINTF("DELETE "); - REST.set_response_status(response, REST.status.DELETED); - - create1_exists = 0; - } -} - -RESOURCE(create2, METHOD_POST, "create2", "title=\"Creates on POST\""); - -void -create2_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - if (test_change) - { - test_update_etag(); - } - - PRINTF("/create2 "); - - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "/location1/location2/location3"); -} - -RESOURCE(create3, METHOD_PUT|METHOD_DELETE, "create3", "title=\"Default test resource\""); - -static uint8_t create3_exists = 0; - -void -create3_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - uint8_t method = REST.get_method_type(request); - - if (test_change) - { - test_update_etag(); - } - - PRINTF("/create3 "); - - if (method & METHOD_PUT) - { - PRINTF("PUT "); - - if (coap_get_header_if_none_match(request)) - { - if (!create3_exists) - { - REST.set_response_status(response, REST.status.CREATED); - - create3_exists = 1; - } - else - { - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } - else - { - REST.set_response_status(response, REST.status.CHANGED); - } - } - else if (method & METHOD_DELETE) - { - PRINTF("DELETE "); - REST.set_response_status(response, REST.status.DELETED); - - create3_exists = 0; - } -} - - - - - -RESOURCE(validate, METHOD_GET|METHOD_PUT, "validate", "title=\"Default test resource\""); - -static uint8_t validate_etag[8] = {0}; -static uint8_t validate_etag_len = 1; -static uint8_t validate_change = 1; - -static -void -validate_update_etag() -{ - int i; - validate_etag_len = (random_rand() % 8) + 1; - for (i=0; i0 && len==validate_etag_len && memcmp(validate_etag, bytes, len)==0) - { - PRINTF("validate "); - REST.set_response_status(response, REST.status.NOT_MODIFIED); - REST.set_header_etag(response, validate_etag, validate_etag_len); - - validate_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } - else - { - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_header_etag(response, validate_etag, validate_etag_len); - REST.set_header_max_age(response, 30); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); - } - } - else if (method & METHOD_PUT) - { - PRINTF("PUT "); - - if (((len = coap_get_header_if_match(request, &bytes))>0 && (len==validate_etag_len && memcmp(validate_etag, bytes, len)==0)) || len==0) - { - validate_update_etag(); - REST.set_header_etag(response, validate_etag, validate_etag_len); - - REST.set_response_status(response, REST.status.CHANGED); - - if (len>0) - { - validate_change = 1; - PRINTF("### SERVER ACTION ### Resouce will change\n"); - } - } - else - { - PRINTF("Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X] ", len, validate_etag_len, - bytes[0], - bytes[1], - bytes[2], - bytes[3], - bytes[4], - bytes[5], - bytes[6], - bytes[7], - validate_etag[0], - validate_etag[1], - validate_etag[2], - validate_etag[3], - validate_etag[4], - validate_etag[5], - validate_etag[6], - validate_etag[7] ); - - REST.set_response_status(response, PRECONDITION_FAILED_4_12); - } - } - - PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); -} -#endif - -#if REST_RES_LONG -/* - * Long path resource - */ -RESOURCE(longpath, METHOD_GET, "seg1/seg2/seg3", "title=\"Long path resource\""); - -void -longpath_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - uint8_t method = REST.get_method_type(request); - - PRINTF("/seg1/seg2/seg3 "); - if (method & METHOD_GET) - { - PRINTF("GET "); - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid)); - } - PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); -} -#endif - -#if REST_RES_QUERY -/* - * Resource accepting query parameters - */ -RESOURCE(query, METHOD_GET, "query", "title=\"Resource accepting query parameters\""); - -void -query_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - int len = 0; - const char *query = NULL; - - PRINTF("/query GET (%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); - - if ((len = REST.get_query(request, &query))) - { - PRINTF("Query: %.*s\n", len, query); - } - - /* Code 2.05 CONTENT is default. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u\nQuery: %.*s", coap_req->type, coap_req->code, coap_req->mid, len, query)); -} -#endif - -#if REST_RES_LOC_QUERY -/* - * Resource accepting query parameters - */ -RESOURCE(locquery, METHOD_POST, "location-query", "title=\"Resource accepting query parameters\""); - -void -locquery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - PRINTF("/location-query POST (%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); - - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "?first=1&second=2"); -} -#endif - -#if REST_RES_MULTI -/* - * Resource providing text/plain and application/xml - */ -RESOURCE(multi, METHOD_GET, "multi-format", "title=\"Resource providing text/plain and application/xml\";ct=\"0 41\""); -void -multi_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - PRINTF("/multi-format GET (%s %u) %d\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid, num); - - if (num==0 || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u%s", coap_req->type, coap_req->code, coap_req->mid, num ? "\nAccept: 0" : "")); -PRINTF("PLAIN\n"); - } - else if (num && (accept[0]==REST.type.APPLICATION_XML)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_XML); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "", coap_req->type, coap_req->code, coap_req->mid, accept[0])); -PRINTF("XML\n"); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain and application/xml"; - REST.set_response_payload(response, msg, strlen(msg)); - PRINTF("ERROR\n"); - } -} -#endif - -#if REST_RES_LINKS -/* - * Resources providing text/plain and application/xml - */ -RESOURCE(link1, METHOD_GET, "link1", "rt=\"Type1 Type2\";if=\"If1\""); -SUB_RESOURCE(link2, METHOD_GET, "link2", "rt=\"Type2 Type3\";if=\"If2\"", link1); -SUB_RESOURCE(link3, METHOD_GET, "link3", "rt=\"Type1 Type3\";if=\"foo\"", link1); - -void -link1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - const char *msg = "Dummy link"; - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, msg, strlen(msg)); -} -#endif - -#if REST_RES_PATH -/* - * Resources providing text/plain and application/xml - */ -RESOURCE(path, METHOD_GET | HAS_SUB_RESOURCES, "path", "ct=\"40\""); - -void -path_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - - const char *uri_path = NULL; - int len = REST.get_url(request, &uri_path); - int base_len = strlen(resource_path.url); - - if (len==base_len) - { - REST.set_header_content_type(response, REST.type.APPLICATION_LINK_FORMAT); - snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, ",,"); - } - else - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "/%.*s", len, uri_path); - } - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); -} -#endif - -#if REST_RES_SEPARATE -/* Required to manually (=not by the engine) handle the response transaction. */ -#if WITH_COAP == 7 -#include "er-coap-07-separate.h" -#include "er-coap-07-transactions.h" -#elif WITH_COAP == 12 -#include "er-coap-12-separate.h" -#include "er-coap-12-transactions.h" -#elif WITH_COAP == 13 -#include "er-coap-13-separate.h" -#include "er-coap-13-transactions.h" -#endif -/* - * Resource which cannot be served immediately and which cannot be acknowledged in a piggy-backed way - */ -PERIODIC_RESOURCE(separate, METHOD_GET, "separate", "title=\"Resource which cannot be served immediately and which cannot be acknowledged in a piggy-backed way\"", 3*CLOCK_SECOND); - -/* A structure to store the required information */ -typedef struct application_separate_store { - /* Provided by Erbium to store generic request information such as remote address and token. */ - coap_separate_t request_metadata; - /* Add fields for addition information to be stored for finalizing, e.g.: */ - char buffer[MAX_PLUGFEST_PAYLOAD]; -} application_separate_store_t; - -static uint8_t separate_active = 0; -static application_separate_store_t separate_store[1]; - -void -separate_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - PRINTF("/separate "); - if (separate_active) - { - PRINTF("REJECTED "); - coap_separate_reject(); - } - else - { - PRINTF("STORED "); - separate_active = 1; - - /* Take over and skip response by engine. */ - coap_separate_accept(request, &separate_store->request_metadata); - /* Be aware to respect the Block2 option, which is also stored in the coap_separate_t. */ - - snprintf(separate_store->buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid); - } - - PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid); -} - -void -separate_periodic_handler(resource_t *resource) -{ - if (separate_active) - { - PRINTF("/separate "); - coap_transaction_t *transaction = NULL; - if ( (transaction = coap_new_transaction(separate_store->request_metadata.mid, &separate_store->request_metadata.addr, separate_store->request_metadata.port)) ) - { - PRINTF("RESPONSE (%s %u)\n", separate_store->request_metadata.type==COAP_TYPE_CON?"CON":"NON", separate_store->request_metadata.mid); - - coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */ - - /* Restore the request information for the response. */ - coap_separate_resume(response, &separate_store->request_metadata, CONTENT_2_05); - - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - coap_set_payload(response, separate_store->buffer, strlen(separate_store->buffer)); - - /* - * Be aware to respect the Block2 option, which is also stored in the coap_separate_t. - * As it is a critical option, this example resource pretends to handle it for compliance. - */ - coap_set_header_block2(response, separate_store->request_metadata.block2_num, 0, separate_store->request_metadata.block2_size); - - /* Warning: No check for serialization error. */ - transaction->packet_len = coap_serialize_message(response, transaction->packet); - coap_send_transaction(transaction); - /* The engine will clear the transaction (right after send for NON, after acked for CON). */ - - separate_active = 0; - } else { - PRINTF("ERROR (transaction)\n"); - } - } /* if (separate_active) */ -} -#endif - -#if REST_RES_LARGE - -/* double expansion */ -#define TO_STRING2(x) #x -#define TO_STRING(x) TO_STRING2(x) +#include "er-coap.h" +#include "er-coap-transactions.h" +#include "er-coap-separate.h" +#include "rest-engine.h" +#include "er-plugtest.h" /* - * Large resource + * Resources to be activated need to be imported through the extern keyword. + * The build system automatically compiles the resources in the corresponding + * sub-directory. */ -RESOURCE(large, METHOD_GET, "large", "title=\"Large resource\";rt=\"block\";sz=\"" TO_STRING(CHUNKS_TOTAL) "\""); - -void -large_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int32_t strpos = 0; - - /* Check the offset for boundaries of the resource data. */ - if (*offset>=CHUNKS_TOTAL) - { - REST.set_response_status(response, REST.status.BAD_OPTION); - /* A block error message should not exceed the minimum block size (16). */ - - const char *error_msg = "BlockOutOfScope"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - /* Generate data until reaching CHUNKS_TOTAL. */ - while (strpos preferred_size) - { - strpos = preferred_size; - } - - /* Truncate if above CHUNKS_TOTAL bytes. */ - if (*offset+(int32_t)strpos > CHUNKS_TOTAL) - { - strpos = CHUNKS_TOTAL - *offset; - } - - REST.set_response_payload(response, buffer, strpos); - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - - /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ - *offset += strpos; - - /* Signal end of resource representation. */ - if (*offset>=CHUNKS_TOTAL) - { - *offset = -1; - } -} -#endif - -#if REST_RES_LARGE_UPDATE -/* - * Large resource that can be updated using PUT method - */ -RESOURCE(large_update, METHOD_GET|METHOD_PUT, "large-update", "title=\"Large resource that can be updated using PUT method\";rt=\"block\";sz=\"" TO_STRING(MAX_PLUGFEST_BODY) "\""); - -static int32_t large_update_size = 0; -static uint8_t large_update_store[MAX_PLUGFEST_BODY] = {0}; -static unsigned int large_update_ct = -1; - -void -large_update_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - uint8_t method = REST.get_method_type(request); - - if (method & METHOD_GET) - { - /* Check the offset for boundaries of the resource data. */ - if (*offset>=large_update_size) - { - REST.set_response_status(response, REST.status.BAD_OPTION); - /* A block error message should not exceed the minimum block size (16). */ - - const char *error_msg = "BlockOutOfScope"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - REST.set_response_payload(response, large_update_store+*offset, MIN(large_update_size - *offset, preferred_size)); - REST.set_header_content_type(response, large_update_ct); - - /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ - *offset += preferred_size; - - /* Signal end of resource representation. */ - if (*offset>=large_update_size) - { - *offset = -1; - } - } else { - uint8_t *incoming = NULL; - size_t len = 0; - - unsigned int ct = REST.get_header_content_type(request); - if (ct==-1) - { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoContentType"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - if ((len = REST.get_request_payload(request, (const uint8_t **) &incoming))) - { - if (coap_req->block1_num*coap_req->block1_size+len <= sizeof(large_update_store)) - { - memcpy(large_update_store+coap_req->block1_num*coap_req->block1_size, incoming, len); - large_update_size = coap_req->block1_num*coap_req->block1_size+len; - large_update_ct = REST.get_header_content_type(request); - - REST.set_response_status(response, REST.status.CHANGED); - coap_set_header_block1(response, coap_req->block1_num, 0, coap_req->block1_size); - } - else - { - REST.set_response_status(response, REST.status.REQUEST_ENTITY_TOO_LARGE); - REST.set_response_payload(response, buffer, snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "%uB max.", sizeof(large_update_store))); - return; - } - } - else - { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoPayload"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - } -} -#endif - -#if REST_RES_LARGE_CREATE -/* - * Large resource that can be created using POST method - */ -RESOURCE(large_create, METHOD_POST, "large-create", "title=\"Large resource that can be created using POST method\";rt=\"block\""); - -void -large_create_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - coap_packet_t *const coap_req = (coap_packet_t *) request; - - uint8_t *incoming = NULL; - size_t len = 0; - - unsigned int ct = REST.get_header_content_type(request); - if (ct==-1) - { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoContentType"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - if ((len = REST.get_request_payload(request, (const uint8_t **) &incoming))) - { - if (coap_req->block1_num*coap_req->block1_size+len <= 2048) - { - REST.set_response_status(response, REST.status.CREATED); - REST.set_header_location(response, "/nirvana"); - coap_set_header_block1(response, coap_req->block1_num, 0, coap_req->block1_size); - } - else - { - REST.set_response_status(response, REST.status.REQUEST_ENTITY_TOO_LARGE); - const char *error_msg = "2048B max."; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - } - else - { - REST.set_response_status(response, REST.status.BAD_REQUEST); - const char *error_msg = "NoPayload"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } -} -#endif - -#if REST_RES_OBS - -#if WITH_COAP == 12 -#include "er-coap-12-observing.h" -#elif WITH_COAP == 13 -#include "er-coap-13-observing.h" -#endif -/* - * Observable resource which changes every 5 seconds - */ -PERIODIC_RESOURCE(obs, METHOD_GET|METHOD_PUT|METHOD_DELETE, "obs", "title=\"Observable resource which changes every 5 seconds\";obs", 5*CLOCK_SECOND); - -static uint16_t obs_counter = 0; -static char obs_content[MAX_PLUGFEST_BODY]; -static size_t obs_content_len = 0; -static unsigned int obs_format = 0; - -static char obs_status = 0; - -static -void -obs_purge_list() -{ - PRINTF("### SERVER ACTION ### Purging obs list"); - coap_remove_observer_by_url(NULL, 0, resource_obs.url); -} - -void -obs_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - uint8_t method = request==NULL ? METHOD_GET : REST.get_method_type(request); - - /* Keep server log clean from ticking events */ - if (request!=NULL) - { - PRINTF("/obs "); - } - - if (method & METHOD_GET) - { - /* Keep server log clean from ticking events */ - if (request!=NULL) - { - PRINTF("GET "); - } - - REST.set_header_content_type(response, obs_format); - REST.set_header_max_age(response, 5); - - if (obs_content_len) - { - REST.set_header_content_type(response, obs_format); - REST.set_response_payload(response, obs_content, obs_content_len); - } - else - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_response_payload(response, obs_content, snprintf(obs_content, MAX_PLUGFEST_PAYLOAD, "TICK %lu", obs_counter)); - } - /* A post_handler that handles subscriptions will be called for periodic resources by the REST framework. */ - } - else if (method & METHOD_PUT) - { - uint8_t *incoming = NULL; - unsigned int ct = REST.get_header_content_type(request); - - PRINTF("PUT "); - - if (ct!=obs_format) - { - obs_status = 1; - - obs_format = ct; - } else { - - obs_format = ct; - obs_content_len = REST.get_request_payload(request, (const uint8_t **) &incoming); - memcpy(obs_content, incoming, obs_content_len); - obs_periodic_handler(&resource_obs); - } - - REST.set_response_status(response, REST.status.CHANGED); - } - else if (method & METHOD_DELETE) - { - PRINTF("DELETE "); - - obs_status = 2; - - REST.set_response_status(response, REST.status.DELETED); - } - - /* Keep server log clean from ticking events */ - if (request!=NULL) - { - PRINTF("\n"); - } -} - -/* - * Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE. - * It will be called by the REST manager process with the defined period. - */ -void -obs_periodic_handler(resource_t *r) -{ - ++obs_counter; - - //PRINTF("TICK %u for /%s\n", obs_counter, r->url); - - if (obs_status==1) - { - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_NON, INTERNAL_SERVER_ERROR_5_00, 0 ); - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(&resource_obs, -1, notification); - - PRINTF("######### sending 5.00\n"); - - obs_purge_list(); - } - else if (obs_status==2) - { - - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_NON, NOT_FOUND_4_04, 0 ); - - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(&resource_obs, -1, notification); - - obs_purge_list(); - - obs_counter = 0; - obs_content_len = 0; - } - else - { - /* Build notification. */ - /*TODO: REST.new_response() */ - coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ - coap_init_message(notification, COAP_TYPE_NON, CONTENT_2_05, 0 ); - - /* Better use a generator function for both handlers that only takes *resonse. */ - obs_handler(NULL, notification, NULL, 0, NULL); - - /* Notify the registered observers with the given message type, observe option, and payload. */ - REST.notify_subscribers(r, obs_counter, notification); - } - obs_status = 0; -} -#endif - -#if REST_RES_MIRROR -/* This resource mirrors the incoming request. It shows how to access the options and how to set them for the response. */ -RESOURCE(mirror, METHOD_GET | METHOD_POST | METHOD_PUT | METHOD_DELETE, "debug/mirror", "title=\"Returns your decoded message\";rt=\"Debug\""); - -void -mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - /* The ETag and Token is copied to the header. */ - uint8_t opaque[] = {0x0A, 0xBC, 0xDE}; - - /* Strings are not copied, so use static string buffers or strings in .text memory (char *str = "string in .text";). */ - static char location[] = {'/','f','/','a','?','k','&','e', 0}; - - /* Getter for the header option Content-Type. If the option is not set, text/plain is returned by default. */ - unsigned int content_type = REST.get_header_content_type(request); - - /* The other getters copy the value (or string/array pointer) to the given pointers and return 1 for success or the length of strings/arrays. */ - uint32_t max_age_and_size = 0; - const char *str = NULL; - uint32_t observe = 0; - const uint8_t *bytes = NULL; - const uint16_t *words = NULL; - uint32_t block_num = 0; - uint8_t block_more = 0; - uint16_t block_size = 0; - const char *query = ""; - int len = 0; - - /* Mirror the received header options in the response payload. Unsupported getters (e.g., rest_get_header_observe() with HTTP) will return 0. */ - - int strpos = 0; - /* snprintf() counts the terminating '\0' to the size parameter. - * The additional byte is taken care of by allocating REST_MAX_CHUNK_SIZE+1 bytes in the REST framework. - * Add +1 to fill the complete buffer, as the payload does not need a terminating '\0'. */ - - - if (strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_header_if_match(request, &bytes))) - { - strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "If-Match 0x"); - int index = 0; - for (index = 0; index= REST_MAX_CHUNK_SIZE) - { - buffer[REST_MAX_CHUNK_SIZE-1] = 0xBB; /* '»' to indicate truncation */ - } - - REST.set_response_payload(response, buffer, strpos); - - PRINTF("/mirror options received: %s\n", buffer); - - /* Set dummy header options for response. Like getters, some setters are not implemented for HTTP and have no effect. */ - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - REST.set_header_max_age(response, 17); /* For HTTP, browsers will not re-request the page for 17 seconds. */ - REST.set_header_etag(response, opaque, 2); - REST.set_header_location(response, location); /* Initial slash is omitted by framework */ - REST.set_header_length(response, strpos); /* For HTTP, browsers will not re-request the page for 10 seconds. CoAP action depends on the client. */ - -/* CoAP-specific example: actions not required for normal RESTful Web service. */ - coap_set_header_uri_host(response, "Contiki"); - coap_set_header_observe(response, 10); - coap_set_header_proxy_uri(response, "ftp://x"); - //coap_set_header_block2(response, 42, 0, 64); - //coap_set_header_block1(response, 23, 0, 16); - coap_set_header_accept(response, APPLICATION_XML); - coap_set_header_accept(response, APPLICATION_ATOM_XML); - coap_set_header_if_none_match(response); -} -#endif /* REST_RES_MIRROR */ - - - - +extern resource_t + res_plugtest_test, + res_plugtest_validate, + res_plugtest_create1, + res_plugtest_create2, + res_plugtest_create3, + res_plugtest_longpath, + res_plugtest_query, + res_plugtest_locquery, + res_plugtest_multi, + res_plugtest_link1, + res_plugtest_link2, + res_plugtest_link3, + res_plugtest_path, + res_plugtest_separate, + res_plugtest_large, + res_plugtest_large_update, + res_plugtest_large_create, + res_plugtest_obs, + res_mirror; PROCESS(plugtest_server, "PlugtestServer"); AUTOSTART_PROCESSES(&plugtest_server); @@ -1240,59 +98,31 @@ PROCESS_THREAD(plugtest_server, ev, data) rest_init_engine(); /* Activate the application-specific resources. */ -#if REST_RES_TEST - rest_activate_resource(&resource_test); - rest_activate_resource(&resource_validate); - rest_activate_resource(&resource_create1); - rest_activate_resource(&resource_create2); - rest_activate_resource(&resource_create3); -#endif -#if REST_RES_LONG - rest_activate_resource(&resource_longpath); -#endif -#if REST_RES_QUERY - rest_activate_resource(&resource_query); -#endif -#if REST_RES_LOC_QUERY - rest_activate_resource(&resource_locquery); -#endif -#if REST_RES_MULTI - rest_activate_resource(&resource_multi); -#endif -#if REST_RES_LINKS - rest_activate_resource(&resource_link1); - rest_activate_resource(&resource_link2); - rest_activate_resource(&resource_link3); -#endif -#if REST_RES_PATH - rest_activate_resource(&resource_path); -#endif -#if REST_RES_SEPARATE - rest_activate_periodic_resource(&periodic_resource_separate); -#endif -#if REST_RES_LARGE - rest_activate_resource(&resource_large); -#endif -#if REST_RES_LARGE_UPDATE - large_update_ct = REST.type.APPLICATION_OCTET_STREAM; - rest_activate_resource(&resource_large_update); -#endif -#if REST_RES_LARGE_CREATE - rest_activate_resource(&resource_large_create); -#endif -#if REST_RES_OBS - rest_activate_periodic_resource(&periodic_resource_obs); -#endif + rest_activate_resource(&res_plugtest_test, "test"); + rest_activate_resource(&res_plugtest_validate, "validate"); + rest_activate_resource(&res_plugtest_create1, "create1"); + rest_activate_resource(&res_plugtest_create2, "create2"); + rest_activate_resource(&res_plugtest_create3, "create3"); + rest_activate_resource(&res_plugtest_longpath, "seg1/seg2/seg3"); + rest_activate_resource(&res_plugtest_query, "query"); + rest_activate_resource(&res_plugtest_locquery, "location-query"); + rest_activate_resource(&res_plugtest_multi, "multi-format"); + rest_activate_resource(&res_plugtest_link1, "link1"); + rest_activate_resource(&res_plugtest_link2, "link2"); + rest_activate_resource(&res_plugtest_link3, "link3"); + rest_activate_resource(&res_plugtest_path, "path"); + rest_activate_resource(&res_plugtest_separate, "separate"); + rest_activate_resource(&res_plugtest_large, "large"); + rest_activate_resource(&res_plugtest_large_update, "large-update"); + rest_activate_resource(&res_plugtest_large_create, "large-create"); + rest_activate_resource(&res_plugtest_obs, "obs"); -#if REST_RES_MIRROR - rest_activate_resource(&resource_mirror); -#endif + rest_activate_resource(&res_mirror, "mirror"); /* Define application-specific events here. */ while(1) { PROCESS_WAIT_EVENT(); - - } /* while (1) */ + } /* while (1) */ PROCESS_END(); } diff --git a/examples/osd/merkurboard/er-plugtest.h b/examples/osd/merkurboard/er-plugtest.h new file mode 100644 index 000000000..0b156656a --- /dev/null +++ b/examples/osd/merkurboard/er-plugtest.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Erbium (Er) CoAP client example + * \author + * Matthias Kovatsch + */ + +#ifndef __ER_PLUGTEST_H__ +#define __ER_PLUGTEST_H__ + +#if !defined(CONTIKI_TARGET_NATIVE) +#warning "Should only be compiled for native!" +#endif + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +/* double expansion */ +#define TO_STRING2(x) # x +#define TO_STRING(x) TO_STRING2(x) + +#define MAX_PLUGFEST_PAYLOAD 64 + 1 /* +1 for the terminating zero, which is not transmitted */ +#define MAX_PLUGFEST_BODY 2048 +#define CHUNKS_TOTAL 2012 + +#endif /* __ER_PLUGTEST_H__ */ diff --git a/examples/osd/merkurboard/flash.sh b/examples/osd/merkurboard/flash.sh index e92d472f6..824d375a0 100755 --- a/examples/osd/merkurboard/flash.sh +++ b/examples/osd/merkurboard/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-server.osd-merkur.hex:a -U eeprom:w:er-example-server.osd-merkur.eep:a +make TARGET=osd-merkur-128 flash-server diff --git a/examples/osd/merkurboard/flashclient.sh b/examples/osd/merkurboard/flashclient.sh index 30979eed4..a0fb33cf7 100755 --- a/examples/osd/merkurboard/flashclient.sh +++ b/examples/osd/merkurboard/flashclient.sh @@ -1,2 +1,2 @@ #!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-client.osd-merkur.hex:a -U eeprom:w:er-example-client.osd-merkur.eep:a +sudo make flash-client diff --git a/examples/osd/merkurboard/project-conf.h b/examples/osd/merkurboard/project-conf.h index c85939445..0b694e71b 100644 --- a/examples/osd/merkurboard/project-conf.h +++ b/examples/osd/merkurboard/project-conf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Matthias Kovatsch + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,77 +26,80 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * + * This file is part of the Contiki operating system. */ -#ifndef PROJECT_ERBIUM_CONF_H_ -#define PROJECT_ERBIUM_CONF_H_ +/** + * \file + * Erbium (Er) example project configuration. + * \author + * Matthias Kovatsch + */ -#define PLATFORM_HAS_LED 1 -#define PLATFORM_HAS_BUTTON 1 -#define PLATFORM_HAS_TEMPERATURE 1 -#define PLATFORM_HAS_BATTERY 1 +#ifndef __PROJECT_ERBIUM_CONF_H__ +#define __PROJECT_ERBIUM_CONF_H__ -/* Some platforms have weird includes. */ -// #undef IEEE802154_CONF_PANID -// #define IEEE802154_CONF_PANID 0xAAAA + #define PLATFORM_HAS_LEDS 1 + #define PLATFORM_HAS_BATTERY 1 + #define PLATFORM_HAS_BUTTON 1 -/* Disabling RDC for demo purposes. Core updates often require more memory. */ -/* For projects, optimize memory and enable RDC again. */ -// #undef NETSTACK_CONF_RDC -//#define NETSTACK_CONF_RDC nullrdc_driver +/* Custom channel and PAN ID configuration for your project. */ +/* + #undef RF_CHANNEL + #define RF_CHANNEL 26 -// enabel LEAF-NODE mode -//#define RPL_CONF_LEAF_ONLY 1 + #undef IEEE802154_CONF_PANID + #define IEEE802154_CONF_PANID 0xABCD + */ + + +/* For Debug: Dont allow MCU sleeping between channel checks */ +//#undef RDC_CONF_MCU_SLEEP +//#define RDC_CONF_MCU_SLEEP 0 + +/* IP buffer size must match all other hops, in particular the border router. */ + + #undef UIP_CONF_BUFFER_SIZE + #define UIP_CONF_BUFFER_SIZE 256 + + +/* Disabling RDC and CSMA for demo purposes. Core updates often + require more memory. */ +/* For projects, optimize memory and enable RDC and CSMA again. */ +//#undef NETSTACK_CONF_RDC +//#define NETSTACK_CONF_RDC nullrdc_driver + +/* Disabling TCP on CoAP nodes. */ +#undef UIP_CONF_TCP +#define UIP_CONF_TCP 0 + +//#undef NETSTACK_CONF_MAC +//#define NETSTACK_CONF_MAC nullmac_driver /* Increase rpl-border-router IP-buffer when using more than 64. */ #undef REST_MAX_CHUNK_SIZE -#define REST_MAX_CHUNK_SIZE 64 +#define REST_MAX_CHUNK_SIZE 64 /* Estimate your header size, especially when using Proxy-Uri. */ /* -#undef COAP_MAX_HEADER_SIZE -#define COAP_MAX_HEADER_SIZE 70 -*/ - -/* The IP buffer size must fit all other hops, in particular the border router. */ - -#undef UIP_CONF_BUFFER_SIZE -#define UIP_CONF_BUFFER_SIZE 256 - + #undef COAP_MAX_HEADER_SIZE + #define COAP_MAX_HEADER_SIZE 70 + */ /* Multiplies with chunk size, be aware of memory constraints. */ #undef COAP_MAX_OPEN_TRANSACTIONS -#define COAP_MAX_OPEN_TRANSACTIONS 4 +#define COAP_MAX_OPEN_TRANSACTIONS 4 -/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* Must be <= open transactions, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ /* -#undef COAP_MAX_OBSERVERS -#define COAP_MAX_OBSERVERS 2 -*/ + #undef COAP_MAX_OBSERVERS + #define COAP_MAX_OBSERVERS 2 + */ /* Filtering .well-known/core per query can be disabled to save space. */ -/* #undef COAP_LINK_FORMAT_FILTERING -#define COAP_LINK_FORMAT_FILTERING 0 -*/ +#define COAP_LINK_FORMAT_FILTERING 0 +#undef COAP_PROXY_OPTION_PROCESSING +#define COAP_PROXY_OPTION_PROCESSING 0 -/* Save some memory for the sky platform. */ -/* -#undef NBR_TABLE_CONF_MAX_NEIGHBORS -#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 -#undef UIP_CONF_MAX_ROUTES -#define UIP_CONF_MAX_ROUTES 10 -*/ - -/* Reduce 802.15.4 frame queue to save RAM. */ -/* -#undef QUEUEBUF_CONF_NUM -#define QUEUEBUF_CONF_NUM 4 -*/ - -/* -#undef SICSLOWPAN_CONF_FRAG -#define SICSLOWPAN_CONF_FRAG 1 -*/ -#endif /* PROJECT_ERBIUM_CONF_H_ */ +#endif /* __PROJECT_ERBIUM_CONF_H__ */ diff --git a/examples/osd/merkurboard/resources/res-event.c b/examples/osd/merkurboard/resources/res-event.c new file mode 100644 index 000000000..d20f0caa9 --- /dev/null +++ b/examples/osd/merkurboard/resources/res-event.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_event_handler(); + +/* + * Example for an event resource. + * Additionally takes a period parameter that defines the interval to call [name]_periodic_handler(). + * A default post_handler takes care of subscriptions and manages a list of subscribers to notify. + */ +EVENT_RESOURCE(res_event, + "title=\"Event demo\";obs", + res_get_handler, + NULL, + NULL, + NULL, + res_event_handler); + +/* + * Use local resource state that is accessed by res_get_handler() and altered by res_event_handler() or PUT or POST. + */ +static int32_t event_counter = 0; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "EVENT %lu", event_counter)); + + /* A post_handler that handles subscriptions/observing will be called for periodic resources by the framework. */ +} +/* + * Additionally, res_event_handler must be implemented for each EVENT_RESOURCE. + * It is called through .trigger(), usually from the server process. + */ +static void +res_event_handler() +{ + /* Do the update triggered by the event here, e.g., sampling a sensor. */ + ++event_counter; + + /* Usually a condition is defined under with subscribers are notified, e.g., event was above a threshold. */ + if(1) { + PRINTF("TICK %u for /%s\n", event_counter, res_event.url); + + /* Notify the registered observers which will trigger the res_get_handler to create the response. */ + REST.notify_subscribers(&res_event); + } +} diff --git a/examples/osd/merkurboard/resources/res-hello.c b/examples/osd/merkurboard/resources/res-hello.c new file mode 100644 index 000000000..9208f8b74 --- /dev/null +++ b/examples/osd/merkurboard/resources/res-hello.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include +#include "rest-engine.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* + * A handler function named [resource name]_handler must be implemented for each RESOURCE. + * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore + * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. + * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. + */ +RESOURCE(res_hello, + "title=\"Hello world: ?len=0..\";rt=\"Text\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const char *len = NULL; + /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ + char const *const message = "Hello World! ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy"; + int length = 12; /* |<-------->| */ + + /* The query string can be retrieved by rest_get_query() or parsed for its key-value pairs. */ + if(REST.get_query_variable(request, "len", &len)) { + length = atoi(len); + if(length < 0) { + length = 0; + } + if(length > REST_MAX_CHUNK_SIZE) { + length = REST_MAX_CHUNK_SIZE; + } + memcpy(buffer, message, length); + } else { + memcpy(buffer, message, length); + } REST.set_header_content_type(response, REST.type.TEXT_PLAIN); /* text/plain is the default, hence this option could be omitted. */ + REST.set_header_etag(response, (uint8_t *)&length, 1); + REST.set_response_payload(response, buffer, length); +} diff --git a/examples/osd/merkurboard/resources/res-push.c b/examples/osd/merkurboard/resources/res-push.c new file mode 100644 index 000000000..c169b407c --- /dev/null +++ b/examples/osd/merkurboard/resources/res-push.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_periodic_handler(void); + +PERIODIC_RESOURCE(res_push, + "title=\"Periodic demo\";obs", + res_get_handler, + NULL, + NULL, + NULL, + 5 * CLOCK_SECOND, + res_periodic_handler); + +/* + * Use local resource state that is accessed by res_get_handler() and altered by res_periodic_handler() or PUT or POST. + */ +static int32_t event_counter = 0; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* + * For minimal complexity, request query and options should be ignored for GET on observable resources. + * Otherwise the requests must be stored with the observer list and passed by REST.notify_subscribers(). + * This would be a TODO in the corresponding files in contiki/apps/erbium/! + */ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_header_max_age(response, res_push.periodic->period / CLOCK_SECOND); + REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "VERY LONG EVENT %lu", event_counter)); + + /* The REST.subscription_handler() will be called for observable resources by the REST framework. */ +} +/* + * Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE. + * It will be called by the REST manager process with the defined period. + */ +static void +res_periodic_handler() +{ + /* Do a periodic task here, e.g., sampling a sensor. */ + ++event_counter; + + /* Usually a condition is defined under with subscribers are notified, e.g., large enough delta in sensor reading. */ + if(1) { + /* Notify the registered observers which will trigger the res_get_handler to create the response. */ + REST.notify_subscribers(&res_push); + } +} diff --git a/examples/osd/merkurboard/resources/res-separate.c b/examples/osd/merkurboard/resources/res-separate.c new file mode 100644 index 000000000..bb2248c92 --- /dev/null +++ b/examples/osd/merkurboard/resources/res-separate.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap-separate.h" +#include "er-coap-transactions.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_resume_handler(void); + +SEPARATE_RESOURCE(res_separate, + "title=\"Separate demo\"", + res_get_handler, + NULL, + NULL, + NULL, + res_resume_handler); + +/* A structure to store the information required for the separate handler */ +typedef struct application_separate_store { + + /* Provided by Erbium to store generic request information such as remote address and token. */ + coap_separate_t request_metadata; + + /* Add fields for addition information to be stored for finalizing, e.g.: */ + char buffer[16]; +} application_separate_store_t; + +#define COAP_MAX_OPEN_SEPARATE 2 + +static uint8_t separate_active = 0; +static application_separate_store_t separate_store[COAP_MAX_OPEN_SEPARATE]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* + * Example allows only one open separate response. + * For multiple, the application must manage the list of stores. + */ + if(separate_active >= COAP_MAX_OPEN_SEPARATE) { + coap_separate_reject(); + } else { + ++separate_active; + + /* Take over and skip response by engine. */ + coap_separate_accept(request, &separate_store->request_metadata); + /* Be aware to respect the Block2 option, which is also stored in the coap_separate_t. */ + + /* + * At the moment, only the minimal information is stored in the store (client address, port, token, MID, type, and Block2). + * Extend the store, if the application requires additional information from this handler. + * buffer is an example field for custom information. + */ + snprintf(separate_store->buffer, sizeof(separate_store->buffer), "StoredInfo"); + } +} +static void +res_resume_handler() +{ + if(separate_active) { + coap_transaction_t *transaction = NULL; + if((transaction = coap_new_transaction(separate_store->request_metadata.mid, &separate_store->request_metadata.addr, separate_store->request_metadata.port))) { + coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */ + + /* Restore the request information for the response. */ + coap_separate_resume(response, &separate_store->request_metadata, REST.status.OK); + + coap_set_payload(response, separate_store->buffer, strlen(separate_store->buffer)); + + /* + * Be aware to respect the Block2 option, which is also stored in the coap_separate_t. + * As it is a critical option, this example resource pretends to handle it for compliance. + */ + coap_set_header_block2(response, separate_store->request_metadata.block2_num, 0, separate_store->request_metadata.block2_size); + + /* Warning: No check for serialization error. */ + transaction->packet_len = coap_serialize_message(response, transaction->packet); + coap_send_transaction(transaction); + /* The engine will clear the transaction (right after send for NON, after acked for CON). */ + + /* FIXME there could me more! */ + separate_active = 0; + } else { + /* + * Set timer for retry, send error message, ... + * The example simply waits for another button press. + */ + } + } /* if (separate_active) */ +} diff --git a/examples/osd/merkurboard/resources/res-toggle.c b/examples/osd/merkurboard/resources/res-toggle.c new file mode 100644 index 000000000..d8a773306 --- /dev/null +++ b/examples/osd/merkurboard/resources/res-toggle.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include "contiki.h" + +#if PLATFORM_HAS_LEDS + +#include +#include "contiki.h" +#include "rest-engine.h" +#include "dev/leds.h" + +static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple actuator example. Toggles the red led */ +RESOURCE(res_toggle, + "title=\"Red LED\";rt=\"Control\"", + NULL, + res_post_handler, + NULL, + NULL); + +static void +res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + leds_toggle(LEDS_RED); +} +#endif /* PLATFORM_HAS_LEDS */ diff --git a/examples/osd/merkurboard/run.sh b/examples/osd/merkurboard/run.sh index 2efd2cf48..5d5cbbbb4 100755 --- a/examples/osd/merkurboard/run.sh +++ b/examples/osd/merkurboard/run.sh @@ -1,8 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size -C --mcu=MCU=atmega128rfa1 er-example-server.osd-merkur -avr-objcopy -j .text -j .data -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.eep +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/merkurboard/runclient.sh b/examples/osd/merkurboard/runclient.sh index 70dcea0e5..0fceb01ce 100755 --- a/examples/osd/merkurboard/runclient.sh +++ b/examples/osd/merkurboard/runclient.sh @@ -1,8 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size -C --mcu=MCU=atmega128rfa1 er-example-client.osd-merkur -avr-objcopy -j .text -j .data -O ihex er-example-client.osd-merkur er-example-client.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex er-example-client.osd-merkur er-example-client.osd-merkur.eep +make TARGET=osd-merkur diff --git a/examples/osd/merkurboard/server-client.csc b/examples/osd/merkurboard/server-client.csc deleted file mode 100644 index 0c09f41b5..000000000 --- a/examples/osd/merkurboard/server-client.csc +++ /dev/null @@ -1,227 +0,0 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - REST with RPL router - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.Msp802154Radio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.Msp802154Radio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - client - Erbium Client - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c - make er-example-client.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.Msp802154Radio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 46.57186415376375 - 40.35946215910942 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - - se.sics.cooja.interfaces.Position - 18.638049428485125 - 47.55034515769599 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 3 - - client - - - - se.sics.cooja.plugins.SimControl - 259 - 0 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 - - 300 - 2 - 178 - 261 - 1 - - - se.sics.cooja.plugins.LogListener - - - - - 762 - 3 - 491 - 2 - 182 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 4 - 74 - 578 - 18 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - 2 - - - - - 125 - 25.49079397896416 - - 1624 - 5 - 252 - 6 - 712 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 2 - - Serial port - 0,0 - - 853 - 1 - 491 - 765 - 182 - - - diff --git a/examples/osd/merkurboard/server-only.csc b/examples/osd/merkurboard/server-only.csc deleted file mode 100644 index 935bd6e79..000000000 --- a/examples/osd/merkurboard/server-only.csc +++ /dev/null @@ -1,189 +0,0 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - REST with RPL router - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.Msp802154Radio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.Msp802154Radio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 35.100895239785295 - 39.70574552287428 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - se.sics.cooja.plugins.SimControl - 259 - 0 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 - - 300 - 5 - 175 - 263 - 3 - - - se.sics.cooja.plugins.LogListener - - - - - 560 - 2 - 326 - 1 - 293 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 3 - 74 - 39 - 199 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - - - - - 125 - 25.49079397896416 - - 1624 - 4 - 252 - 4 - 622 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 1 - - Serial port - 0,0 - - 702 - 1 - 646 - 564 - 2 - - - diff --git a/examples/osd/native-border-router/Makefile b/examples/osd/native-border-router/Makefile index 69412170d..442a39e78 100644 --- a/examples/osd/native-border-router/Makefile +++ b/examples/osd/native-border-router/Makefile @@ -1,24 +1,9 @@ -CONTIKI_PROJECT=border-router -all: $(CONTIKI_PROJECT) +EXE=border-router +all: $(EXE) APPS = slip-cmd CONTIKI=../../.. -WITH_UIP6=1 -UIP_CONF_IPV6=1 -CFLAGS+= -DUIP_CONF_IPV6_RPL - -WITH_COAP=7 - -ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -#CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -APPS+=erbium -endif - #linker optimizations SMALL=1 @@ -26,7 +11,7 @@ CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" PROJECT_SOURCEFILES += border-router-cmds.c tun-bridge.c border-router-rdc.c \ slip-config.c slip-dev.c -WITH_WEBSERVER=0 +WITH_WEBSERVER=1 ifeq ($(WITH_WEBSERVER),1) CFLAGS += -DWEBSERVER=1 PROJECT_SOURCEFILES += httpd-simple.c @@ -35,7 +20,16 @@ APPS += $(WITH_WEBSERVER) CFLAGS += -DWEBSERVER=2 endif +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include connect-router: border-router.native sudo ./border-router.native aaaa::1/64 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep + diff --git a/examples/osd/native-border-router/README.md b/examples/osd/native-border-router/README.md new file mode 100644 index 000000000..255f5a97b --- /dev/null +++ b/examples/osd/native-border-router/README.md @@ -0,0 +1,34 @@ +This code connects a 802.15.4 radio over TTY with the full uIPv6 stack of +Contiki including 6LoWPAN and 802.15.4 framing / parsing. The native border +router also acts as a RPL Root and handles the routing and maintains the RPL +network. Finally the native border router connects the full 6LoWPAN/RPL +network to the host (linux/os-x) network stack making it possible for +applications on the host to transparently reach all the nodes in the +6LoWPAN/RPL network. + +This is designed to interact with the a ../slip-radio example running on a +mote that is either directly USB/TTY connected, or is remote via a TCP +connect. What's on the SLIP interface is really not Serial Line IP, but SLIP +framed 15.4 packets. + +The border router supports a number of commands on it's stdin. +Each are prefixed by !: +* !G - global RPL repair root. +* !M - set MAC address (if coming from RADIO, i.e. SLIP link) +* !C - show channel (if coming from RADIO, i.e. SLIP link) +* !D - sensor data received +* !Q - exit + +Queries are prefixed by ?: +* ?M is used for requesting the MAC address from the radio in order to use it for uIP6 and its stateless address auto configuration of its IPv6 address. This will make the native border router have the address that correspond to the MAC address of the slip-radio. (response is !M from the slip-radio) + +* ?C is used for requesting the currently used channel for the slip-radio. The response is !C with a channel number (from the slip-radio). + +* !C is used for setting the channel of the slip-radio (useful if the motes are using another channel than the one used in the slip-radio). + +Linux: +apt-get install ncurses-dev +make + +sudo ./border-router.native -B 38400 -s /dev/ttyUSB0 aaaa::/64 + diff --git a/examples/osd/native-border-router/border-router-cmds.c b/examples/osd/native-border-router/border-router-cmds.c index eec4646ab..68f7af48c 100644 --- a/examples/osd/native-border-router/border-router-cmds.c +++ b/examples/osd/native-border-router/border-router-cmds.c @@ -41,11 +41,11 @@ #include "border-router-cmds.h" #include "dev/serial-line.h" #include "net/rpl/rpl.h" -#include "net/uiplib.h" +#include "net/ip/uiplib.h" #include #define DEBUG DEBUG_NONE -#include "net/uip-debug.h" +#include "net/ip/uip-debug.h" uint8_t command_context; diff --git a/examples/osd/native-border-router/border-router-cmds.h b/examples/osd/native-border-router/border-router-cmds.h index 38fc92111..6dcef36a0 100644 --- a/examples/osd/native-border-router/border-router-cmds.h +++ b/examples/osd/native-border-router/border-router-cmds.h @@ -35,8 +35,8 @@ * Joakim Eriksson */ -#ifndef __BORDER_ROUTER_CMDS_H__ -#define __BORDER_ROUTER_CMDS_H__ +#ifndef BORDER_ROUTER_CMDS_H_ +#define BORDER_ROUTER_CMDS_H_ #define CMD_CONTEXT_RADIO 0 #define CMD_CONTEXT_STDIO 1 @@ -45,4 +45,4 @@ extern uint8_t command_context; PROCESS_NAME(border_router_cmd_process); -#endif /* __BORDER_ROUTER_CMDS_H__ */ +#endif /* BORDER_ROUTER_CMDS_H_ */ diff --git a/examples/osd/native-border-router/border-router-rdc.c b/examples/osd/native-border-router/border-router-rdc.c index 78699122f..4aae30e5e 100644 --- a/examples/osd/native-border-router/border-router-rdc.c +++ b/examples/osd/native-border-router/border-router-rdc.c @@ -105,7 +105,7 @@ send_packet(mac_callback_t sent, void *ptr) uint8_t buf[PACKETBUF_NUM_ATTRS * 3 + PACKETBUF_SIZE + 3]; uint8_t sid; - packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr); + packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &linkaddr_node_addr); /* ack or not ? */ packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); diff --git a/examples/osd/native-border-router/border-router.c b/examples/osd/native-border-router/border-router.c index 83fbe9ac7..fe8d7fbf5 100644 --- a/examples/osd/native-border-router/border-router.c +++ b/examples/osd/native-border-router/border-router.c @@ -36,16 +36,14 @@ * Niclas Finne * Joakim Eriksson * Nicolas Tsiftes - * Andreas Reder */ #include "contiki.h" #include "contiki-lib.h" #include "contiki-net.h" -#include "net/uip.h" -#include "net/uip-ds6.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" #include "net/rpl/rpl.h" -#include "net/mac/framer-802154.h" #include "net/netstack.h" #include "dev/slip.h" @@ -59,34 +57,10 @@ #include #define DEBUG DEBUG_FULL -#include "net/uip-debug.h" - -#include "erbium.h" -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP == 3 -#include "er-coap-03.h" -#elif WITH_COAP == 7 -#include "er-coap-07.h" -#else -#warning "Erbium example without CoAP-specifc functionality" -#endif /* CoAP-specific example */ - - +#include "net/ip/uip-debug.h" #define MAX_SENSORS 4 -#define IPV6_ADDR_LEN 40 -#define RPL_TABLE_SIZE 25000 -char rpl_table[RPL_TABLE_SIZE]; -int rpl_table_len; - - - -uint16_t dag_id[] = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011}; - -extern uip_ds6_nbr_t uip_ds6_nbr_cache[]; -extern uip_ds6_route_t uip_ds6_routing_table[]; - extern long slip_sent; extern long slip_received; @@ -106,87 +80,139 @@ extern const char *slip_config_ipaddr; CMD_HANDLERS(border_router_cmd_handler); PROCESS(border_router_process, "Border router process"); -PROCESS(rest_server, "Erbium Coap Server"); -AUTOSTART_PROCESSES(&border_router_process,&border_router_cmd_process, &rest_server); +#if WEBSERVER==0 +/* No webserver */ +AUTOSTART_PROCESSES(&border_router_process,&border_router_cmd_process); +#elif WEBSERVER>1 +/* Use an external webserver application */ +#include "webserver-nogui.h" +AUTOSTART_PROCESSES(&border_router_process,&border_router_cmd_process, + &webserver_nogui_process); +#else +/* Use simple webserver with only one page */ +#include "httpd-simple.h" +PROCESS(webserver_nogui_process, "Web server"); +PROCESS_THREAD(webserver_nogui_process, ev, data) +{ + PROCESS_BEGIN(); + httpd_init(); -static int create_ipv6_addr_str(const uip_ipaddr_t *addr, char *ptr){ - int len = 0; - int i, f; + while(1) { + PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); + httpd_appcall(data); + } + + PROCESS_END(); +} +AUTOSTART_PROCESSES(&border_router_process,&border_router_cmd_process, + &webserver_nogui_process); + +static const char *TOP = "ContikiRPL\n"; +static const char *BOTTOM = "\n"; +static char buf[128]; +static int blen; +#define ADD(...) do { \ + blen += snprintf(&buf[blen], sizeof(buf) - blen, __VA_ARGS__); \ + } while(0) +/*---------------------------------------------------------------------------*/ +static void +ipaddr_add(const uip_ipaddr_t *addr) +{ uint16_t a; - - uip_debug_ipaddr_print(addr); + int i, f; for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { a = (addr->u8[i] << 8) + addr->u8[i + 1]; if(a == 0 && f >= 0) { - if(f++ == 0){ - ptr[len++] = ':'; - ptr[len++] = ':'; + if(f++ == 0 && sizeof(buf) - blen >= 2) { + buf[blen++] = ':'; + buf[blen++] = ':'; } } else { if(f > 0) { - f = -1; - } else if(i > 0) { - ptr[len++] = ':'; + f = -1; + } else if(i > 0 && blen < sizeof(buf)) { + buf[blen++] = ':'; } - len += snprintf(&ptr[len], IPV6_ADDR_LEN - len, "%x", a); + ADD("%x", a); } - } - return len; + } +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(generate_routes(struct httpd_state *s)) +{ + static int i; + static uip_ds6_route_t *r; + static uip_ds6_nbr_t *nbr; + + PSOCK_BEGIN(&s->sout); + + SEND_STRING(&s->sout, TOP); + + blen = 0; + ADD("Neighbors
    ");
    +  for(nbr = nbr_table_head(ds6_neighbors);
    +      nbr != NULL;
    +      nbr = nbr_table_next(ds6_neighbors, nbr)) {
    +    ipaddr_add(&nbr->ipaddr);
    +    ADD("\n");
    +    if(blen > sizeof(buf) - 45) {
    +      SEND_STRING(&s->sout, buf);
    +      blen = 0;
    +    }
    +  }
    +
    +  ADD("
    Routes
    ");
    +  SEND_STRING(&s->sout, buf);
    +  blen = 0;
    +  for(r = uip_ds6_route_head();
    +      r != NULL;
    +      r = uip_ds6_route_next(r)) {
    +    ipaddr_add(&r->ipaddr);
    +    ADD("/%u (via ", r->length);
    +    ipaddr_add(uip_ds6_route_nexthop(r));
    +    if(r->state.lifetime < 600) {
    +      ADD(") %lus\n", (unsigned long)r->state.lifetime);
    +    } else {
    +      ADD(")\n");
    +    }
    +    SEND_STRING(&s->sout, buf);
    +    blen = 0;
    +  }
    +  ADD("
    "); +//if(blen > 0) { + SEND_STRING(&s->sout, buf); +// blen = 0; +//} + + if(sensor_count > 0) { + ADD("Sensors
    ");
    +    SEND_STRING(&s->sout, buf);
    +    blen = 0;
    +    for(i = 0; i < sensor_count; i++) {
    +      ADD("%s\n", sensors[i]);
    +      SEND_STRING(&s->sout, buf);
    +      blen = 0;
    +    }
    +    ADD("
    "); + SEND_STRING(&s->sout, buf); + } + + + SEND_STRING(&s->sout, BOTTOM); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +httpd_simple_script_t +httpd_simple_get_script(const char *name) +{ + return generate_routes; } -/*---------------------------------------------------------------------------*/ -//create JSON RPL Table -static void -generate_rpl_table(){ - char a[IPV6_ADDR_LEN]; - int addresses; - static uip_ds6_route_t *r; - int i; - - rpl_table_len = 0; - // Start JSON - rpl_table_len += snprintf(&rpl_table[rpl_table_len], RPL_TABLE_SIZE - rpl_table_len, "{\n"); - - // add title - rpl_table_len += snprintf(&rpl_table[rpl_table_len], RPL_TABLE_SIZE - rpl_table_len, "\"title\": \"RPL Table\",\n"); - - rpl_table_len += snprintf(&rpl_table[rpl_table_len], RPL_TABLE_SIZE - rpl_table_len, "\"Neighbors\": [ "); - - addresses = 0; - for(i = 0; i < UIP_DS6_NBR_NB; i++) { - if(uip_ds6_nbr_cache[i].isused) { - addresses += 1; - create_ipv6_addr_str(&uip_ds6_nbr_cache[i].ipaddr, a); - rpl_table_len += snprintf(&rpl_table[rpl_table_len], RPL_TABLE_SIZE - rpl_table_len, "\"%s\", ", a); - } - } - if(addresses > 0){ - //delete last coma - rpl_table_len -= 2; - } - rpl_table_len += snprintf(&rpl_table[rpl_table_len], RPL_TABLE_SIZE - rpl_table_len, "],\n"); - - rpl_table_len += snprintf(&rpl_table[rpl_table_len], RPL_TABLE_SIZE - rpl_table_len, "\"Routes\": [ "); - - addresses = 0; - for(r = uip_ds6_route_list_head(); r != NULL; r = list_item_next(r)) { - addresses += 1; - create_ipv6_addr_str(&r->ipaddr, a); - rpl_table_len += snprintf(&rpl_table[rpl_table_len], RPL_TABLE_SIZE - rpl_table_len, "\"%s via ", a); - create_ipv6_addr_str(&r->nexthop, a); - rpl_table_len += snprintf(&rpl_table[rpl_table_len], RPL_TABLE_SIZE - rpl_table_len, "%s\", ", a); - } - if(addresses > 0){ - //delete last coma - rpl_table_len -= 2; - } - rpl_table_len += snprintf(&rpl_table[rpl_table_len], RPL_TABLE_SIZE - rpl_table_len, "]\n"); - - // End JSON - rpl_table_len += snprintf(&rpl_table[rpl_table_len], RPL_TABLE_SIZE - rpl_table_len, "}\n"); -} +#endif /* WEBSERVER */ /*---------------------------------------------------------------------------*/ static void @@ -217,7 +243,7 @@ void border_router_set_mac(const uint8_t *data) { memcpy(uip_lladdr.addr, data, sizeof(uip_lladdr.addr)); - rimeaddr_set_node_addr((rimeaddr_t *)uip_lladdr.addr); + linkaddr_set_node_addr((linkaddr_t *)uip_lladdr.addr); /* is this ok - should instead remove all addresses and add them back again - a bit messy... ?*/ @@ -262,6 +288,7 @@ border_router_set_sensors(const char *data, int len) static void set_prefix_64(const uip_ipaddr_t *prefix_64) { + rpl_dag_t *dag; uip_ipaddr_t ipaddr; memcpy(&prefix, prefix_64, 16); memcpy(&ipaddr, prefix_64, 16); @@ -269,12 +296,17 @@ set_prefix_64(const uip_ipaddr_t *prefix_64) prefix_set = 1; uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); + + dag = rpl_set_root(RPL_DEFAULT_INSTANCE, &ipaddr); + if(dag != NULL) { + rpl_set_prefix(dag, &prefix, 64); + PRINTF("created a new RPL dag\n"); + } } /*---------------------------------------------------------------------------*/ PROCESS_THREAD(border_router_process, ev, data) { static struct etimer et; - rpl_dag_t *dag; PROCESS_BEGIN(); prefix_set = 0; @@ -308,12 +340,6 @@ PROCESS_THREAD(border_router_process, ev, data) } } - dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)dag_id); - if(dag != NULL) { - rpl_set_prefix(dag, &prefix, 64); - PRINTF("created a new RPL dag\n"); - } - #if DEBUG print_local_addresses(); #endif @@ -323,191 +349,11 @@ PROCESS_THREAD(border_router_process, ev, data) NETSTACK_MAC.off(1); while(1) { - // etimer_set(&et, CLOCK_SECOND * 2); - // PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - PROCESS_YIELD(); + etimer_set(&et, CLOCK_SECOND * 2); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); /* do anything here??? */ } PROCESS_END(); } /*---------------------------------------------------------------------------*/ - -/* -* Resources are defined by the RESOURCE macro. -* Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). -*/ -RESOURCE(rpl, METHOD_GET, "rpl", "title=\"rpl routing table\";rt=\"application/json\""); - -/* -* A handler function named [resource name]_handler must be implemented for each RESOURCE. -* A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore -* preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. -* If a smaller block size is requested for CoAP, the REST framework automatically splits the data. -*/ - -void -rpl_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int32_t strpos = 0; - int i; - - if(*offset == 0){ - generate_rpl_table(); - } - - /* Check the offset for boundaries of the resource data. */ - if (*offset>=rpl_table_len) - { - REST.set_response_status(response, REST.status.BAD_OPTION); - /* A block error message should not exceed the minimum block size (16). */ - - const char *error_msg = "BlockOutOfScope"; - REST.set_response_payload(response, error_msg, strlen(error_msg)); - return; - } - - /* Generate data until reaching CHUNKS_TOTAL. */ - while (strpos preferred_size) - { - strpos = preferred_size; - } - - /* Truncate if above CHUNKS_TOTAL bytes. */ - if (*offset+(int32_t)strpos > rpl_table_len) - { - strpos = rpl_table_len - *offset; - } - - REST.set_response_payload(response, buffer, strpos); - - /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */ - *offset += strpos; - - /* Signal end of resource representation. */ - if (*offset>=rpl_table_len) - { - *offset = -1; - } -} - - -RESOURCE(info, METHOD_GET, "info", "title=\"Info\";rt=\"application/json\""); - -/* -* A handler function named [resource name]_handler must be implemented for each RESOURCE. -* A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore -* preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. -* If a smaller block size is requested for CoAP, the REST framework automatically splits the data. -*/ -void -info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - char message[100]; - int index = 0; - int length = 0; /* |<-------->| */ - - /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ - index += sprintf(message + index,"{\n \"version\" : \"V0.2\",\n"); - index += sprintf(message + index," \"name\" : \"native coap border router\"\n"); - index += sprintf(message + index,"}\n"); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - REST.set_response_payload(response, buffer, length); -} - - -RESOURCE(network, METHOD_GET | METHOD_PUT, "network", "title=\"osd configs\"; rt=\"application/json\""); -void -network_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - char message[100]; - uint8_t buf[10]; - int index = 0; - int length = 0; /* |<-------->| */ - const char* strg; - uint16_t panid; - - if((length = REST.get_post_variable(request, "panid", &strg))){ - // parse panid - panid = (uint16_t)atoi(strg); - // set framer panid - framer_802154_set_panid(panid); - //set radio panid - buf[0] = '?'; - buf[1] = 'P'; - buf[2] = panid >> 8; - buf[3] = panid; - write_to_slip(buf, 4); - - }else if((length = REST.get_post_variable(request, "channel", &strg))){ - REST.set_response_status(response, REST.status.BAD_REQUEST); - return; - } - - index += sprintf(message + index, "{\n"); - index += sprintf(message + index, "\"panid\": \"%u\",\n", framer_802154_get_panid()); - //index += sprintf(message + index, "\"channel\": \"%u\",\n", //params_get_channel()); - index += sprintf(message + index, "}\n"); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - REST.set_response_payload(response, buffer, length); -} - - -/*---------------------------------------------------------------------------*/ - -PROCESS_THREAD(rest_server, ev, data) -{ - - PROCESS_BEGIN(); - - - - PRINTF("Starting Erbium Coap Server\n"); - -#ifdef RF_CHANNEL - PRINTF("RF channel: %u\n", RF_CHANNEL); -#endif -#ifdef IEEE802154_PANID - PRINTF("PAN ID: 0x%04X\n", IEEE802154_PANID); -#endif - - PRINTF("uIP buffer: %u\n", UIP_BUFSIZE); - PRINTF("LL header: %u\n", UIP_LLH_LEN); - PRINTF("IP+UDP header: %u\n", UIP_IPUDPH_LEN); - PRINTF("REST max chunk: %u\n", REST_MAX_CHUNK_SIZE); - - /* Initialize the REST engine. */ - rest_init_engine(); - - /* Activate the application-specific resources. */ - rest_activate_resource(&resource_rpl); - rest_activate_resource(&resource_network); - rest_activate_resource(&resource_info); - - while(1) { - PROCESS_YIELD(); - } - - - PROCESS_END(); -} - - - diff --git a/examples/osd/native-border-router/border-router.h b/examples/osd/native-border-router/border-router.h index b6a2f2ab2..68420320d 100644 --- a/examples/osd/native-border-router/border-router.h +++ b/examples/osd/native-border-router/border-router.h @@ -34,11 +34,11 @@ * Joakim Eriksson */ -#ifndef __BORDER_ROUTER_H__ -#define __BORDER_ROUTER_H__ +#ifndef BORDER_ROUTER_H_ +#define BORDER_ROUTER_H_ #include "contiki.h" -#include "net/uip.h" +#include "net/ip/uip.h" #include int border_router_cmd_handler(const uint8_t *data, int len); @@ -56,4 +56,4 @@ int slip_init(void); int slip_set_fd(int maxfd, fd_set *rset, fd_set *wset); void slip_handle_fd(fd_set *rset, fd_set *wset); -#endif /* __BORDER_ROUTER_H__ */ +#endif /* BORDER_ROUTER_H_ */ diff --git a/examples/osd/native-border-router/httpd-simple.c b/examples/osd/native-border-router/httpd-simple.c new file mode 100644 index 000000000..115e54d45 --- /dev/null +++ b/examples/osd/native-border-router/httpd-simple.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file + * A simple web server forwarding page generation to a protothread + * \author + * Adam Dunkels + * Niclas Finne + * Joakim Eriksson + */ + +#include +#include + +#include "contiki-net.h" + +//#include "urlconv.h" + +#include "httpd-simple.h" +#define webserver_log_file(...) +#define webserver_log(...) + +#ifndef WEBSERVER_CONF_CFS_CONNS +#define CONNS UIP_CONNS +#else /* WEBSERVER_CONF_CFS_CONNS */ +#define CONNS WEBSERVER_CONF_CFS_CONNS +#endif /* WEBSERVER_CONF_CFS_CONNS */ + +#ifndef WEBSERVER_CONF_CFS_URLCONV +#define URLCONV 0 +#else /* WEBSERVER_CONF_CFS_URLCONV */ +#define URLCONV WEBSERVER_CONF_CFS_URLCONV +#endif /* WEBSERVER_CONF_CFS_URLCONV */ + +#define STATE_WAITING 0 +#define STATE_OUTPUT 1 + +MEMB(conns, struct httpd_state, CONNS); + +#define ISO_nl 0x0a +#define ISO_space 0x20 +#define ISO_period 0x2e +#define ISO_slash 0x2f + +/*---------------------------------------------------------------------------*/ +static const char *NOT_FOUND = "" +"
    " +"

    404 - file not found

    " +"
    " +"" +""; +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_string(struct httpd_state *s, const char *str)) +{ + PSOCK_BEGIN(&s->sout); + + SEND_STRING(&s->sout, str); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +const char http_content_type_html[] = "Content-type: text/html\r\n\r\n"; +static +PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr)) +{ + /* char *ptr; */ + + PSOCK_BEGIN(&s->sout); + + SEND_STRING(&s->sout, statushdr); + + /* ptr = strrchr(s->filename, ISO_period); */ + /* if(ptr == NULL) { */ + /* s->ptr = http_content_type_plain; */ + /* } else if(strcmp(http_html, ptr) == 0) { */ + /* s->ptr = http_content_type_html; */ + /* } else if(strcmp(http_css, ptr) == 0) { */ + /* s->ptr = http_content_type_css; */ + /* } else if(strcmp(http_png, ptr) == 0) { */ + /* s->ptr = http_content_type_png; */ + /* } else if(strcmp(http_gif, ptr) == 0) { */ + /* s->ptr = http_content_type_gif; */ + /* } else if(strcmp(http_jpg, ptr) == 0) { */ + /* s->ptr = http_content_type_jpg; */ + /* } else { */ + /* s->ptr = http_content_type_binary; */ + /* } */ + /* SEND_STRING(&s->sout, s->ptr); */ + SEND_STRING(&s->sout, http_content_type_html); + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +const char http_header_200[] = "HTTP/1.0 200 OK\r\nServer: Contiki/2.4 http://www.sics.se/contiki/\r\nConnection: close\r\n"; +const char http_header_404[] = "HTTP/1.0 404 Not found\r\nServer: Contiki/2.4 http://www.sics.se/contiki/\r\nConnection: close\r\n"; +static +PT_THREAD(handle_output(struct httpd_state *s)) +{ + PT_BEGIN(&s->outputpt); + + s->script = NULL; + s->script = httpd_simple_get_script(&s->filename[1]); + if(s->script == NULL) { + strncpy(s->filename, "/notfound.html", sizeof(s->filename)); + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, http_header_404)); + PT_WAIT_THREAD(&s->outputpt, + send_string(s, NOT_FOUND)); + uip_close(); + webserver_log_file(&uip_conn->ripaddr, "404 - not found"); + PT_EXIT(&s->outputpt); + } else { + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, http_header_200)); + PT_WAIT_THREAD(&s->outputpt, s->script(s)); + } + s->script = NULL; + PSOCK_CLOSE(&s->sout); + PT_END(&s->outputpt); +} +/*---------------------------------------------------------------------------*/ +const char http_get[] = "GET "; +const char http_index_html[] = "/index.html"; +//const char http_referer[] = "Referer:" +static +PT_THREAD(handle_input(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sin); + + PSOCK_READTO(&s->sin, ISO_space); + + if(strncmp(s->inputbuf, http_get, 4) != 0) { + PSOCK_CLOSE_EXIT(&s->sin); + } + PSOCK_READTO(&s->sin, ISO_space); + + if(s->inputbuf[0] != ISO_slash) { + PSOCK_CLOSE_EXIT(&s->sin); + } + +#if URLCONV + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + urlconv_tofilename(s->filename, s->inputbuf, sizeof(s->filename)); +#else /* URLCONV */ + if(s->inputbuf[1] == ISO_space) { + strncpy(s->filename, http_index_html, sizeof(s->filename)); + } else { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + strncpy(s->filename, s->inputbuf, sizeof(s->filename)); + } +#endif /* URLCONV */ + + webserver_log_file(&uip_conn->ripaddr, s->filename); + + s->state = STATE_OUTPUT; + + while(1) { + PSOCK_READTO(&s->sin, ISO_nl); +#if 0 + if(strncmp(s->inputbuf, http_referer, 8) == 0) { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0; + webserver_log(s->inputbuf); + } +#endif + } + + PSOCK_END(&s->sin); +} +/*---------------------------------------------------------------------------*/ +static void +handle_connection(struct httpd_state *s) +{ + handle_input(s); + if(s->state == STATE_OUTPUT) { + handle_output(s); + } +} + +/*---------------------------------------------------------------------------*/ +void +httpd_appcall(void *state) +{ + struct httpd_state *s = (struct httpd_state *)state; + + if(uip_closed() || uip_aborted() || uip_timedout()) { + if(s != NULL) { + s->script = NULL; + memb_free(&conns, s); + } + } else if(uip_connected()) { + s = (struct httpd_state *)memb_alloc(&conns); + if(s == NULL) { + uip_abort(); + webserver_log_file(&uip_conn->ripaddr, "reset (no memory block)"); + return; + } + tcp_markconn(uip_conn, s); + PSOCK_INIT(&s->sin, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PSOCK_INIT(&s->sout, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PT_INIT(&s->outputpt); + s->script = NULL; + s->state = STATE_WAITING; + timer_set(&s->timer, CLOCK_SECOND * 10); + handle_connection(s); + } else if(s != NULL) { + if(uip_poll()) { + if(timer_expired(&s->timer)) { + uip_abort(); + s->script = NULL; + memb_free(&conns, s); + webserver_log_file(&uip_conn->ripaddr, "reset (timeout)"); + } + } else { + timer_restart(&s->timer); + } + handle_connection(s); + } else { + uip_abort(); + } +} + +/*---------------------------------------------------------------------------*/ +void +httpd_init(void) +{ + + tcp_listen(UIP_HTONS(80)); + memb_init(&conns); +#if URLCONV + urlconv_init(); +#endif /* URLCONV */ +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/osd/native-border-router/httpd-simple.h b/examples/osd/native-border-router/httpd-simple.h new file mode 100644 index 000000000..a16dbd99e --- /dev/null +++ b/examples/osd/native-border-router/httpd-simple.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file + * A simple webserver + * \author + * Adam Dunkels + * Niclas Finne + * Joakim Eriksson + */ + +#ifndef HTTPD_SIMPLE_H_ +#define HTTPD_SIMPLE_H_ + +#include "contiki-net.h" + +/* The current internal border router webserver ignores the requested file name */ +/* and needs no per-connection output buffer, so save some RAM */ +#ifndef WEBSERVER_CONF_CFS_PATHLEN +#define HTTPD_PATHLEN 2 +#else /* WEBSERVER_CONF_CFS_CONNS */ +#define HTTPD_PATHLEN WEBSERVER_CONF_CFS_PATHLEN +#endif /* WEBSERVER_CONF_CFS_CONNS */ + +struct httpd_state; +typedef char (* httpd_simple_script_t)(struct httpd_state *s); + +struct httpd_state { + struct timer timer; + struct psock sin, sout; + struct pt outputpt; + char inputbuf[HTTPD_PATHLEN + 24]; +/*char outputbuf[UIP_TCP_MSS]; */ + char filename[HTTPD_PATHLEN]; + httpd_simple_script_t script; + char state; +}; + +void httpd_init(void); +void httpd_appcall(void *state); + +httpd_simple_script_t httpd_simple_get_script(const char *name); + +#define SEND_STRING(s, str) PSOCK_SEND(s, (uint8_t *)str, strlen(str)) + +#endif /* HTTPD_SIMPLE_H_ */ diff --git a/examples/osd/native-border-router/project-conf.h b/examples/osd/native-border-router/project-conf.h index 494264b58..4ef217fcb 100644 --- a/examples/osd/native-border-router/project-conf.h +++ b/examples/osd/native-border-router/project-conf.h @@ -27,8 +27,8 @@ * SUCH DAMAGE. */ -#ifndef __PROJECT_ROUTER_CONF_H__ -#define __PROJECT_ROUTER_CONF_H__ +#ifndef PROJECT_ROUTER_CONF_H_ +#define PROJECT_ROUTER_CONF_H_ #undef UIP_FALLBACK_INTERFACE #define UIP_FALLBACK_INTERFACE rpl_interface @@ -57,4 +57,4 @@ /* used by wpcap (see /cpu/native/net/wpcap-drv.c) */ #define SELECT_CALLBACK 1 -#endif /* __PROJECT_ROUTER_CONF_H__ */ +#endif /* PROJECT_ROUTER_CONF_H_ */ diff --git a/examples/osd/native-border-router/run.sh b/examples/osd/native-border-router/run.sh deleted file mode 100755 index 768ad2e82..000000000 --- a/examples/osd/native-border-router/run.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -make clean TARGET=native -make TARGET=native -mv border-router.native border-router - diff --git a/examples/osd/native-border-router/slip-config.c b/examples/osd/native-border-router/slip-config.c index 9d93afa7a..84d256127 100644 --- a/examples/osd/native-border-router/slip-config.c +++ b/examples/osd/native-border-router/slip-config.c @@ -67,7 +67,7 @@ int slip_config_handle_arguments(int argc, char **argv) { const char *prog; - signed char c; + char c; int baudrate = 115200; slip_config_verbose = 0; diff --git a/examples/osd/native-border-router/slip-dev.c b/examples/osd/native-border-router/slip-dev.c index a38c6a0c3..8aabbe528 100644 --- a/examples/osd/native-border-router/slip-dev.c +++ b/examples/osd/native-border-router/slip-dev.c @@ -176,7 +176,7 @@ slip_packet_input(unsigned char *data, int len) void serial_input(FILE *inslip) { - unsigned char inbuf[2048]; + static unsigned char inbuf[2048]; static int inbufptr = 0; int ret,i; unsigned char c; diff --git a/examples/osd/native-border-router/tun-bridge.c b/examples/osd/native-border-router/tun-bridge.c index 970b4cc79..711f17dec 100644 --- a/examples/osd/native-border-router/tun-bridge.c +++ b/examples/osd/native-border-router/tun-bridge.c @@ -33,8 +33,8 @@ * Joakim Eriksson */ -#include "net/uip.h" -#include "net/uip-ds6.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" #include #include #include @@ -52,7 +52,7 @@ #define DEBUG DEBUG_NONE -#include "net/uip-debug.h" +#include "net/ip/uip-debug.h" #ifdef linux #include @@ -222,13 +222,15 @@ tun_init() } /*---------------------------------------------------------------------------*/ -void +static int tun_output(uint8_t *data, int len) { /* fprintf(stderr, "*** Writing to tun...%d\n", len); */ if(write(tunfd, data, len) != len) { err(1, "serial_to_tun: write"); + return -1; } + return 0; } /*---------------------------------------------------------------------------*/ int @@ -246,13 +248,14 @@ init(void) { } /*---------------------------------------------------------------------------*/ -static void +static int output(void) { PRINTF("SUT: %u\n", uip_len); if(uip_len > 0) { - tun_output(&uip_buf[UIP_LLH_LEN], uip_len); + return tun_output(&uip_buf[UIP_LLH_LEN], uip_len); } + return 0; } diff --git a/examples/osd/pingtheplug/Makefile b/examples/osd/pingtheplug/Makefile index 7a3466655..881d7002c 100644 --- a/examples/osd/pingtheplug/Makefile +++ b/examples/osd/pingtheplug/Makefile @@ -1,17 +1,12 @@ -all: er-example-server -# use this target explicitly if requried: er-plugtest-server +EXE=er-example-server - -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 - -# for some platforms -UIP_CONF_IPV6=1 -# IPv6 make config disappeared completely -CFLAGS += -DUIP_CONF_IPV6=1 +all: $(EXE) CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" # pcintkey @@ -35,64 +30,28 @@ endif # linker optimizations SMALL=1 -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif - -APPS += erbium - -# optional rules to get assembly -#CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 -#CUSTOM_RULE_S_TO_OBJECTDIR_O = 1 +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += json json-resource include $(CONTIKI)/Makefile.include -# optional rules to get assembly -#$(OBJECTDIR)/%.o: asmdir/%.S -# $(CC) $(CFLAGS) -MMD -c $< -o $@ -# @$(FINALIZE_DEPENDENCY) -# -#asmdir/%.S: %.c -# $(CC) $(CFLAGS) -MMD -S $< -o $@ - -# border router rules -$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c (cd $(CONTIKI)/tools && $(MAKE) tunslip6) -connect-router: $(CONTIKI)/tools/tunslip6 +connect-router: $(CONTIKI)/tools/tunslip6 sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 -connect-router-cooja: $(CONTIKI)/tools/tunslip6 +connect-router-cooja: $(CONTIKI)/tools/tunslip6 sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 connect-minimal: sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/pingtheplug/er-example-server.c b/examples/osd/pingtheplug/er-example-server.c index 72b75e859..2b62e47ec 100644 --- a/examples/osd/pingtheplug/er-example-server.c +++ b/examples/osd/pingtheplug/er-example-server.c @@ -43,7 +43,7 @@ #include "contiki.h" #include "contiki-net.h" #include - +#include "rest-engine.h" #define PLATFORM_HAS_LED 1 //#define PLATFORM_HAS_BUTTON 1 @@ -63,7 +63,6 @@ #define REST_RES_LED 1 #define REST_RES_BATTERY 1 -#include "erbium.h" #include "pcintkey.h" #include "statusled.h" @@ -84,18 +83,6 @@ #endif -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP == 3 -#include "er-coap-03.h" -#elif WITH_COAP == 7 -#include "er-coap-07.h" -#elif WITH_COAP == 12 -#include "er-coap-12.h" -#elif WITH_COAP == 13 -#include "er-coap-13.h" -#else -#warning "Erbium example without CoAP-specifc functionality" -#endif /* CoAP-specific example */ #define DEBUG 1 #if DEBUG @@ -118,7 +105,6 @@ uint8_t g_triac_b = 0; * Resources are defined by the RESOURCE macro. * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). */ -RESOURCE(model, METHOD_GET, "p/model", "title=\"model\";rt=\"simple.dev.mdl\""); /* * A handler function named [resource name]_handler must be implemented for each RESOURCE. @@ -127,7 +113,7 @@ RESOURCE(model, METHOD_GET, "p/model", "title=\"model\";rt=\"simple.dev.mdl\""); * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. */ void -model_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +model_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { char message[100]; int index = 0; @@ -144,6 +130,8 @@ model_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred REST.set_header_content_type(response, REST.type.APPLICATION_JSON); REST.set_response_payload(response, buffer, length); } +RESOURCE(res_model, "title=\"model\";rt=\"simple.dev.md\"", model_get_handler, NULL, NULL, NULL); + #endif /******************************************************************************/ @@ -152,7 +140,6 @@ model_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred * Resources are defined by the RESOURCE macro. * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). */ -RESOURCE(sw, METHOD_GET, "p/sw", "title=\"Software Version\";rt=\"simple.dev.sv\""); /* * A handler function named [resource name]_handler must be implemented for each RESOURCE. @@ -161,7 +148,7 @@ RESOURCE(sw, METHOD_GET, "p/sw", "title=\"Software Version\";rt=\"simple.dev.sv\ * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. */ void -sw_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +sw_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { char message[100]; int index = 0; @@ -169,7 +156,7 @@ sw_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_si /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ // jSON Format - index += sprintf(message + index,"{\n \"sw\" : \"V0.9\"\n"); + index += sprintf(message + index,"{\n \"sw\" : \"V1.0\"\n"); index += sprintf(message + index,"}\n"); length = strlen(message); @@ -178,6 +165,7 @@ sw_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_si REST.set_header_content_type(response, REST.type.APPLICATION_JSON); REST.set_response_payload(response, buffer, length); } +RESOURCE(res_sw, "title=\"Software Version\";rt=\"simple.dev.sv\"", sw_get_handler, NULL, NULL, NULL); #endif /******************************************************************************/ @@ -186,7 +174,7 @@ sw_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_si * Resources are defined by the RESOURCE macro. * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). */ -RESOURCE(name, METHOD_POST | METHOD_GET, "p/name", "title=\"name\";rt=\"simple.dev.n\""); + /* eeprom space */ #define P_NAME "Testboard" #define P_NAME_MAX 17 @@ -248,13 +236,14 @@ name_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_ REST.set_response_status(response, REST.status.BAD_REQUEST); } } +RESOURCE(res_name, "title=\"name\";rt=\"simple.dev.n\"", name_handler, NULL, name_handler, NULL ); #endif /******************************************************************************/ #if REST_RES_TIMER /*A simple actuator example*/ -RESOURCE(timer, METHOD_GET | METHOD_POST , "a/timer", "title=\"TIMER, POST timer=XXX\";rt=\"Control\""); + /* eeprom space */ #define P_TIMER "60" #define P_TIMER_MAX 10 @@ -320,12 +309,13 @@ timer_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred REST.set_response_status(response, REST.status.BAD_REQUEST); } } +RESOURCE(res_timer, "title=\"timer\";rt=\"timer\"", timer_handler, NULL, timer_handler, NULL ); #endif /******************************************************************************/ #if REST_RES_RESET /*A simple actuator example*/ -RESOURCE(reset, METHOD_GET | METHOD_POST , "p/reset", "title=\"RESET, POST mode=on\";rt=\"Control\""); + /* eeprom space */ #define P_RESET "0" #define P_RESET_MAX 10 @@ -397,12 +387,13 @@ reset_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred REST.set_response_status(response, REST.status.BAD_REQUEST); } } +RESOURCE(res_reset, "title=\"reset\";rt=\"reset\"", reset_handler, NULL, reset_handler, NULL ); #endif /******************************************************************************/ // pcintkey_ext /*A simple actuator example. read the key button status*/ -RESOURCE(extbutton, METHOD_GET | METHOD_POST , "s/extbutton", "title=\"ext.Button\";rt=\"Text\""); + void extbutton_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { @@ -461,11 +452,11 @@ extbutton_handler(void* request, void* response, uint8_t *buffer, uint16_t prefe REST.set_response_status(response, REST.status.BAD_REQUEST); } } +RESOURCE(res_extbutton, "title=\"button\";rt=\"button\"", extbutton_handler, NULL, extbutton_handler, NULL ); /******************************************************************************/ #if REST_RES_LED /*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -RESOURCE(led1, METHOD_POST | METHOD_PUT , "a/led1", "title=\"LED: POST/PUT mode=on|off\";rt=\"simple.act.led\""); void led1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) @@ -495,9 +486,9 @@ led1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_ REST.set_response_status(response, REST.status.BAD_REQUEST); } } +RESOURCE(res_led1, "title=\"LED: PUT mode=on|off\";rt=\"simple.act.led\"", led1_handler, NULL, led1_handler, NULL ); /*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -RESOURCE(led2, METHOD_POST | METHOD_PUT , "a/led2", "title=\"LED: POST/PUT mode=on|off\";rt=\"simple.act.led\""); void led2_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) @@ -525,11 +516,11 @@ led2_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_ REST.set_response_status(response, REST.status.BAD_REQUEST); } } +RESOURCE(res_led2, "title=\"LED: PUT mode=on|off\";rt=\"simple.act.led\"", led2_handler, NULL, led2_handler, NULL ); #endif #if REST_RES_OPTRIAC /*A simple actuator example*/ -RESOURCE(optriac, METHOD_GET | METHOD_POST | METHOD_PUT , "a/optriac", "title=\"TRIAC, POST/PUT mode=on|off\";rt=\"Control\""); void optriac_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) @@ -566,9 +557,6 @@ optriac_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr break; case METHOD_PUT: - success = 0; - break; - case METHOD_POST: if (success && (len=REST.get_post_variable(request, "mode", &mode))) { PRINTF("mode %s\n", mode); if (strncmp(mode, "on", len)==0) { @@ -593,21 +581,22 @@ optriac_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr REST.set_response_status(response, REST.status.BAD_REQUEST); } } +RESOURCE(res_optriac, "title=\"TRIAC, PUT mode=on|off\";rt=\"simple.act.triac\"", optriac_handler, NULL, optriac_handler, NULL ); #endif /* PLATFORM_HAS_OPTRIAC */ /******************************************************************************/ #if REST_RES_TEMPERATURE && defined (PLATFORM_HAS_TEMPERATURE) /* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(temperature, METHOD_GET, "s/cputemp", "title=\"Temperature status\";rt=\"temperature-c\""); + void temperature_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { - int temperature = temperature_sensor.value(0); + int temperature = temperature_sensor.value(0); + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { REST.set_header_content_type(response, REST.type.TEXT_PLAIN); snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d.%02d", temperature/100, temperature % 100); @@ -615,7 +604,7 @@ temperature_handler(void* request, void* response, uint8_t *buffer, uint16_t pre REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) + else if (accept == REST.type.APPLICATION_JSON) { REST.set_header_content_type(response, REST.type.APPLICATION_JSON); snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%d.%02d}", temperature/100, temperature % 100); @@ -629,28 +618,29 @@ temperature_handler(void* request, void* response, uint8_t *buffer, uint16_t pre REST.set_response_payload(response, msg, strlen(msg)); } } +RESOURCE(res_temperature, "title=\"Temperature status\";rt=\"temperature-c\"", temperature_handler, NULL, NULL, NULL ); #endif /* PLATFORM_HAS_TEMPERATURE */ /******************************************************************************/ #if REST_RES_BATTERY && defined (PLATFORM_HAS_BATTERY) /* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(battery, METHOD_GET, "s/battery", "title=\"Battery status\";rt=\"battery-mV\""); + void battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { int battery = battery_sensor.value(0); + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { REST.set_header_content_type(response, REST.type.TEXT_PLAIN); snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d.%02d", battery/1000, battery % 1000); REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) + else if (accept == REST.type.APPLICATION_JSON) { REST.set_header_content_type(response, REST.type.APPLICATION_JSON); snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"battery\":%d.%02d}", battery/1000, battery % 1000); @@ -664,6 +654,8 @@ battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr REST.set_response_payload(response, msg, strlen(msg)); } } +RESOURCE(res_battery, "title=\"Battery status\";rt=\"battery-mV\"", battery_handler, NULL, NULL, NULL ); + #endif /* PLATFORM_HAS_BATTERY */ /******************************************************************************/ @@ -686,7 +678,7 @@ AUTOSTART_PROCESSES(&rest_server_example, &sensors_process); PROCESS_THREAD(rest_server_example, ev, data) { static struct etimer ds_periodic_timer; - static int ext4=0; +// static int ext4=0; static int ext5=0; static int ext6=0; // ext4 = is_button_ext4(); @@ -722,40 +714,40 @@ PROCESS_THREAD(rest_server_example, ev, data) /* Activate the application-specific resources. */ #if REST_RES_MODEL - rest_activate_resource(&resource_model); + rest_activate_resource(&res_model,"p/model"); #endif #if REST_RES_SW - rest_activate_resource(&resource_sw); + rest_activate_resource(&res_sw,"p/sw"); #endif #if REST_RES_NAME - rest_activate_resource(&resource_name); + rest_activate_resource(&res_name,"p/name"); #endif #if REST_RES_RESET - rest_activate_resource(&resource_reset); + rest_activate_resource(&res_reset,"p/reset"); #endif #if REST_RES_TIMER - rest_activate_resource(&resource_timer); + rest_activate_resource(&res_timer,"a/timer"); #endif - rest_activate_resource(&resource_extbutton); + rest_activate_resource(&res_extbutton,"s/extbutton"); /* Activate the application-specific resources. */ #if REST_RES_OPTRIAC SENSORS_ACTIVATE(optriac_sensor); - rest_activate_resource(&resource_optriac); + rest_activate_resource(&res_optriac,"a/optriac"); #endif #if defined (PLATFORM_HAS_LED) #if REST_RES_LED - rest_activate_resource(&resource_led1); - rest_activate_resource(&resource_led2); + rest_activate_resource(&res_led1,"a/led1"); + rest_activate_resource(&res_led2,"a/led2"); #endif #endif /* PLATFORM_HAS_LED */ #if defined (PLATFORM_HAS_TEMPERATURE) && REST_RES_TEMPERATURE SENSORS_ACTIVATE(temperature_sensor); - rest_activate_resource(&resource_temperature); + rest_activate_resource(&res_temperature,"s/cputemp"); #endif #if defined (PLATFORM_HAS_BATTERY) && REST_RES_BATTERY SENSORS_ACTIVATE(battery_sensor); - rest_activate_resource(&resource_battery); + rest_activate_resource(&res_battery,"s/battery"); #endif etimer_set(&ds_periodic_timer, MESURE_INTERVAL); diff --git a/examples/osd/pingtheplug/flash.sh b/examples/osd/pingtheplug/flash.sh index e92d472f6..e82962073 100755 --- a/examples/osd/pingtheplug/flash.sh +++ b/examples/osd/pingtheplug/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-server.osd-merkur.hex:a -U eeprom:w:er-example-server.osd-merkur.eep:a +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/pingtheplug/pcintkey.c b/examples/osd/pingtheplug/pcintkey.c index 5fc065e24..f9553efd4 100644 --- a/examples/osd/pingtheplug/pcintkey.c +++ b/examples/osd/pingtheplug/pcintkey.c @@ -55,9 +55,32 @@ ISR(PCINT0_vect) // } // } } + +/* Compatibility of old vs new definitions in io.h */ +#ifndef DDE0 +#define DDE0 DDRE0 +#define DDE1 DDRE1 +#define DDE2 DDRE2 +#define DDE3 DDRE3 +#define DDE4 DDRE4 +#define DDE5 DDRE5 +#define DDE6 DDRE6 +#define DDE7 DDRE7 +#endif +#ifndef DDF0 +#define DDF0 DDRF0 +#define DDF1 DDRF1 +#define DDF2 DDRF2 +#define DDF3 DDRF3 +#define DDF4 DDRF4 +#define DDF5 DDRF5 +#define DDF6 DDRF6 +#define DDF7 DDRF7 +#endif + /** * \brief This will intialize the KEY for button readings. -*/ + */ void key_init(void) { diff --git a/examples/osd/pingtheplug/run.sh b/examples/osd/pingtheplug/run.sh index 2efd2cf48..5d5cbbbb4 100755 --- a/examples/osd/pingtheplug/run.sh +++ b/examples/osd/pingtheplug/run.sh @@ -1,8 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size -C --mcu=MCU=atmega128rfa1 er-example-server.osd-merkur -avr-objcopy -j .text -j .data -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.eep +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/pingtheplug/server-only.csc b/examples/osd/pingtheplug/server-only.csc index d5eee34d6..1b0fe28bf 100644 --- a/examples/osd/pingtheplug/server-only.csc +++ b/examples/osd/pingtheplug/server-only.csc @@ -1,189 +1,189 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 35.100895239785295 - 39.70574552287428 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - se.sics.cooja.plugins.SimControl - 259 - 5 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 - - 300 - 4 - 175 - 263 - 3 - - - se.sics.cooja.plugins.LogListener - - - - - 560 - 1 - 326 - 1 - 293 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 2 - 74 - 39 - 199 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - - - - - 125 - 25.49079397896416 - - 1624 - 3 - 252 - 4 - 622 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 1 - - Serial port - 0,0 - - 702 - 0 - 646 - 564 - 2 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + REST with RPL router + -2147483648 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + se.sics.cooja.interfaces.Position + 35.100895239785295 + 39.70574552287428 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + se.sics.cooja.plugins.SimControl + 259 + 5 + 179 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.AttributeVisualizerSkin + se.sics.cooja.plugins.skins.LEDVisualizerSkin + se.sics.cooja.plugins.skins.AddressVisualizerSkin + 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 + + 300 + 4 + 175 + 263 + 3 + + + se.sics.cooja.plugins.LogListener + + + + + 560 + 1 + 326 + 1 + 293 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 2 + 74 + 39 + 199 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + + + + + 125 + 25.49079397896416 + + 1624 + 3 + 252 + 4 + 622 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 702 + 0 + 646 + 564 + 2 + + + diff --git a/examples/osd/pir-sensor/Makefile b/examples/osd/pir-sensor/Makefile index 8a253c40d..0675e5538 100644 --- a/examples/osd/pir-sensor/Makefile +++ b/examples/osd/pir-sensor/Makefile @@ -1,6 +1,6 @@ -all: er-example-server -# use this target explicitly if requried: er-plugtest-server +EXE=er-example-server +all: $(EXE) # variable for this Makefile # configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) @@ -92,3 +92,10 @@ connect-router-cooja: $(CONTIKI)/tools/tunslip6 connect-minimal: sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/pir-sensor/flash.sh b/examples/osd/pir-sensor/flash.sh index e92d472f6..e82962073 100755 --- a/examples/osd/pir-sensor/flash.sh +++ b/examples/osd/pir-sensor/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-server.osd-merkur.hex:a -U eeprom:w:er-example-server.osd-merkur.eep:a +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/pir-sensor/run.sh b/examples/osd/pir-sensor/run.sh index 2efd2cf48..5d5cbbbb4 100755 --- a/examples/osd/pir-sensor/run.sh +++ b/examples/osd/pir-sensor/run.sh @@ -1,8 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size -C --mcu=MCU=atmega128rfa1 er-example-server.osd-merkur -avr-objcopy -j .text -j .data -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.eep +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/pir-sensor/server-client.csc b/examples/osd/pir-sensor/server-client.csc index 8c45fdf02..02aefd730 100644 --- a/examples/osd/pir-sensor/server-client.csc +++ b/examples/osd/pir-sensor/server-client.csc @@ -1,227 +1,227 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - client - Erbium Client - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c - make er-example-client.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 46.57186415376375 - 40.35946215910942 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - - se.sics.cooja.interfaces.Position - 18.638049428485125 - 47.55034515769599 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 3 - - client - - - - se.sics.cooja.plugins.SimControl - 259 - 0 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 - - 300 - 2 - 178 - 261 - 1 - - - se.sics.cooja.plugins.LogListener - - - - - 762 - 3 - 491 - 2 - 182 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 4 - 74 - 578 - 18 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - 2 - - - - - 125 - 25.49079397896416 - - 1624 - 5 - 252 - 6 - 712 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 2 - - Serial port - 0,0 - - 853 - 1 - 491 - 765 - 182 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + REST with RPL router + -2147483648 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + client + Erbium Client + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c + make er-example-client.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + se.sics.cooja.interfaces.Position + 46.57186415376375 + 40.35946215910942 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + + se.sics.cooja.interfaces.Position + 18.638049428485125 + 47.55034515769599 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 3 + + client + + + + se.sics.cooja.plugins.SimControl + 259 + 0 + 179 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.AttributeVisualizerSkin + se.sics.cooja.plugins.skins.LEDVisualizerSkin + se.sics.cooja.plugins.skins.AddressVisualizerSkin + 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 + + 300 + 2 + 178 + 261 + 1 + + + se.sics.cooja.plugins.LogListener + + + + + 762 + 3 + 491 + 2 + 182 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 4 + 74 + 578 + 18 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + 2 + + + + + 125 + 25.49079397896416 + + 1624 + 5 + 252 + 6 + 712 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 2 + + Serial port + 0,0 + + 853 + 1 + 491 + 765 + 182 + + + diff --git a/examples/osd/pir-sensor/server-only.csc b/examples/osd/pir-sensor/server-only.csc index d5eee34d6..1b0fe28bf 100644 --- a/examples/osd/pir-sensor/server-only.csc +++ b/examples/osd/pir-sensor/server-only.csc @@ -1,189 +1,189 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 35.100895239785295 - 39.70574552287428 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - se.sics.cooja.plugins.SimControl - 259 - 5 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 - - 300 - 4 - 175 - 263 - 3 - - - se.sics.cooja.plugins.LogListener - - - - - 560 - 1 - 326 - 1 - 293 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 2 - 74 - 39 - 199 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - - - - - 125 - 25.49079397896416 - - 1624 - 3 - 252 - 4 - 622 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 1 - - Serial port - 0,0 - - 702 - 0 - 646 - 564 - 2 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + REST with RPL router + -2147483648 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + se.sics.cooja.interfaces.Position + 35.100895239785295 + 39.70574552287428 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + se.sics.cooja.plugins.SimControl + 259 + 5 + 179 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.AttributeVisualizerSkin + se.sics.cooja.plugins.skins.LEDVisualizerSkin + se.sics.cooja.plugins.skins.AddressVisualizerSkin + 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 + + 300 + 4 + 175 + 263 + 3 + + + se.sics.cooja.plugins.LogListener + + + + + 560 + 1 + 326 + 1 + 293 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 2 + 74 + 39 + 199 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + + + + + 125 + 25.49079397896416 + + 1624 + 3 + 252 + 4 + 622 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 702 + 0 + 646 + 564 + 2 + + + diff --git a/examples/osd/poti/Makefile b/examples/osd/poti/Makefile new file mode 100644 index 000000000..8593b01cb --- /dev/null +++ b/examples/osd/poti/Makefile @@ -0,0 +1,78 @@ +EXE=poti + +all: $(EXE) + +CONTIKI=../../.. + +# Contiki IPv6 configuration +WITH_UIP6=1 +UIP_CONF_IPV6=1 +CFLAGS += -DUIP_CONF_IPV6=1 +CFLAGS += -DUIP_CONF_IPV6_RPL=1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) + +# linker optimizations +SMALL=1 + +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += json json-resource + +# optional rules to get assembly +#CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 +#CUSTOM_RULE_S_TO_OBJECTDIR_O = 1 + +include $(CONTIKI)/Makefile.include + +# minimal-net target is currently broken in Contiki +ifeq ($(TARGET), minimal-net) +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=1300 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=176 +CFLAGS += -DUIP_CONF_IPV6_RPL=0 +endif + +# optional rules to get assembly +#$(OBJECTDIR)/%.o: asmdir/%.S +# $(CC) $(CFLAGS) -MMD -c $< -o $@ +# @$(FINALIZE_DEPENDENCY) +# +#asmdir/%.S: %.c +# $(CC) $(CFLAGS) -MMD -S $< -o $@ + +# border router rules +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + (cd $(CONTIKI)/tools && $(MAKE) tunslip6) + +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 -p 60001 aaaa::1/64 + +connect-router-native: $(CONTIKI)/examples/ipv6/native-border-router/border-router.native + sudo $(CONTIKI)/exmples/ipv6/native-border-router/border-router.native -a 127.0.0.1 -p 60001 aaaa::1/64 + +connect-minimal: + sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/poti/README.md b/examples/osd/poti/README.md new file mode 100644 index 000000000..0a02cf8e6 --- /dev/null +++ b/examples/osd/poti/README.md @@ -0,0 +1,14 @@ +Potentiometer Driver +==================== + +This App allows sending potentiometer values to a remote node. This is +currently used to change colors of the led-strip app but the resource +used and the IP address are configurable -- so we can use it for any +other destination. + +The app sends its value to the remote only if the value has changed. In +addition it has a retransmit interval (in seconds) that can retransmit +the value after a timeout if the value has not changed. Setting this +retransmit interval to 0 will turn off the retransmit feature. Note that +we sample the value only every second: We don't want to use up the whole +bandwidth for this app alone. diff --git a/examples/osd/poti/flash.sh b/examples/osd/poti/flash.sh new file mode 100755 index 000000000..e82962073 --- /dev/null +++ b/examples/osd/poti/flash.sh @@ -0,0 +1,2 @@ +#!/bin/bash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/poti/poti.c b/examples/osd/poti/poti.c new file mode 100644 index 000000000..2e7c82143 --- /dev/null +++ b/examples/osd/poti/poti.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2015, Ralf Schlatterbeck Open Source Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Potentiometer for regulating LED-strip brightness per color + * \author + * Ralf Schlatterbeck + */ + +#include +#include +#include +#include +#include "contiki.h" +#include "contiki-net.h" +#include "rest-engine.h" +#include "er-coap-engine.h" +#include "uiplib.h" +#include "generic_resource.h" +#include "Arduino.h" + +/* + * Resources to be activated need to be imported through the extern keyword. + * The build system automatically compiles the resources in the + * corresponding sub-directory. + */ + +#if PLATFORM_HAS_BATTERY +#include "dev/battery-sensor.h" +extern resource_t res_battery; +#endif + +#if PLATFORM_HAS_RADIO +#include "dev/radio-sensor.h" +extern resource_t res_radio; +#endif + +#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT) +// should be the same :-) +#define UIP_NTOHS(x) UIP_HTONS(x) +#define SERVER_NODE(ip) \ + uip_ip6addr(ip,0xfe80,0,0,0,0x22e,0xffff,0x34,0xa600) + /*uip_ip6addr(ip,0x2001,0xdb8,0xc001,0xf00d,0x22e,0xffff,0x34,0xa600)*/ +#define LOOP_INTERVAL (1 * CLOCK_SECOND) + +uip_ipaddr_t server_ipaddr, tmp_addr; +char server_resource [20] = "led/G"; +int interval = 10; /* Retransmit interval after no change in value */ + +static size_t +ip_to_string (const char *name, const char *uri, char *buf, size_t bsize) +{ + #define IP(x) UIP_NTOHS(server_ipaddr.u16[x]) + return snprintf + ( buf, bsize, "%x:%x:%x:%x:%x:%x:%x:%x" + , IP(0), IP(1), IP(2), IP(3), IP(4), IP(5), IP(6), IP(7) + ); +} + +int ip_from_string (const char *name, const char *uri, const char *s) +{ + /* Returns 1 if successful, only copy valid address */ + if (uiplib_ip6addrconv (s, &tmp_addr)) { + uip_ip6addr_copy (&server_ipaddr, &tmp_addr); + return 0; + } + return -1; +} + +GENERIC_RESOURCE + ( server_ip + , ip + , ipv6_address + , 1 + , ip_from_string + , ip_to_string + ); + +static size_t +resource_to_string (const char *name, const char *uri, char *buf, size_t bsize) +{ + return snprintf (buf, bsize, "%s", server_resource); +} + +int resource_from_string (const char *name, const char *uri, const char *s) +{ + strncpy (server_resource, s, sizeof (server_resource)); + server_resource [sizeof (server_resource) - 1] = 0; + return 0; +} + +GENERIC_RESOURCE + ( server_resource + , led-resource + , resource-name + , 1 + , resource_from_string + , resource_to_string + ); + +static size_t +interval_to_string (const char *name, const char *uri, char *buf, size_t bsize) +{ + return snprintf (buf, bsize, "%d", interval); +} + +int interval_from_string (const char *name, const char *uri, const char *s) +{ + interval = atoi (s); + return 0; +} + +GENERIC_RESOURCE + ( interval + , interval + , s + , 0 + , interval_from_string + , interval_to_string + ); + +/* Passed to COAP_BLOCKING_REQUEST to handle responses */ +void chunk_handler (void *response) +{ + const uint8_t *chunk; + int len = coap_get_payload (response, &chunk); + printf ("|%.*s", len, (char *)chunk); +} + +PROCESS(poti, "Potentiometer"); +AUTOSTART_PROCESSES(&poti); + +PROCESS_THREAD(poti, ev, data) +{ + + static struct etimer loop_timer; + PROCESS_BEGIN(); + + /* Initialize the REST engine. */ + rest_init_engine (); + SERVER_NODE (&server_ipaddr); + adc_init (); + + /* Activate the application-specific resources. */ +#if PLATFORM_HAS_BATTERY + SENSORS_ACTIVATE(battery_sensor); + rest_activate_resource (&res_battery, "s/battery"); +#endif + rest_activate_resource (&res_server_ip, "poti/ip"); + rest_activate_resource (&res_server_resource, "poti/resource"); + rest_activate_resource (&res_interval, "poti/interval"); + + etimer_set (&loop_timer, LOOP_INTERVAL); + /* Define application-specific events here. */ + while(1) { + static int count = 0; + static int lastval = -1; + static coap_packet_t request [1]; /* Array: treat as pointer */ + uint8_t val = 127; + + PROCESS_WAIT_EVENT(); + if (etimer_expired (&loop_timer)) { + uint16_t sum = 0; + int i; + count++; + adc_setup (ADC_DEFAULT, A5); + for (i=0; i<5; i++) { + sum += adc_read (); + clock_delay_usec (50); + } + adc_fin (); + val = (sum / 5) >> 2; + if ((interval > 0 && count > interval) || (val != lastval)) { + char buf [4]; + coap_transaction_t *transaction; + + sprintf (buf, "%d", val); + lastval = val; + printf ("Sending Value: %s\n", buf); + coap_init_message (request, COAP_TYPE_NON, COAP_PUT, 0); + coap_set_header_uri_path (request, server_resource); + coap_set_header_content_format (request, REST.type.TEXT_PLAIN); + coap_set_payload (request, buf, strlen (buf)); + request->mid = coap_get_mid (); + transaction = coap_new_transaction + (request->mid, &server_ipaddr, REMOTE_PORT); + transaction->packet_len = coap_serialize_message + (request, transaction->packet); + coap_send_transaction (transaction); + count = 0; + } + etimer_reset (&loop_timer); + } + } /* while (1) */ + + PROCESS_END(); +} diff --git a/examples/osd/poti/project-conf.h b/examples/osd/poti/project-conf.h new file mode 100644 index 000000000..ab46b9879 --- /dev/null +++ b/examples/osd/poti/project-conf.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013, Matthias Kovatsch + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ + +#ifndef PROJECT_ERBIUM_CONF_H_ +#define PROJECT_ERBIUM_CONF_H_ + +#define PLATFORM_HAS_INFO 1 +#define PLATFORM_HAS_BATTERY 1 +#define PLATFORM_HAS_DS1820 1 +#define PLATFORM_HAS_DHT11HUM 1 +//#define PLATFORM_HAS_DHT11TEMP 1 +#define PLATFORM_HAS_LEDS 1 + + +/* Some platforms have weird includes. */ +#undef IEEE802154_CONF_PANID + +/* Disabling RDC for demo purposes. Core updates often require more memory. */ +/* For projects, optimize memory and enable RDC again. */ +// #undef NETSTACK_CONF_RDC +//#define NETSTACK_CONF_RDC nullrdc_driver + +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 64 + +/* Estimate your header size, especially when using Proxy-Uri. */ +/* +#undef COAP_MAX_HEADER_SIZE +#define COAP_MAX_HEADER_SIZE 70 +*/ + +/* The IP buffer size must fit all other hops, in particular the border router. */ + +#undef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 256 + + +/* Multiplies with chunk size, be aware of memory constraints. */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* +#undef COAP_MAX_OBSERVERS +#define COAP_MAX_OBSERVERS 2 +*/ + +/* Filtering .well-known/core per query can be disabled to save space. */ +/* +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +*/ + +/* Save some memory for the sky platform. */ +/* +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 10 +*/ + +/* Reduce 802.15.4 frame queue to save RAM. */ +/* +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 +*/ + +/* +#undef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +*/ + +/* For Debug: Dont allow MCU sleeping between channel checks */ +#undef RDC_CONF_MCU_SLEEP +#define RDC_CONF_MCU_SLEEP 0 + +#endif /* PROJECT_ERBIUM_CONF_H_ */ diff --git a/examples/osd/poti/run.sh b/examples/osd/poti/run.sh new file mode 100755 index 000000000..5d5cbbbb4 --- /dev/null +++ b/examples/osd/poti/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/powerbox/Makefile b/examples/osd/powerbox/Makefile index d99c2db03..72ffc56e5 100644 --- a/examples/osd/powerbox/Makefile +++ b/examples/osd/powerbox/Makefile @@ -1,15 +1,11 @@ -all: er-example-server -# use this target explicitly if requried: er-plugtest-server +EXE=er-example-server - -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 +all: $(EXE) # for some platforms UIP_CONF_IPV6=1 # IPv6 make config disappeared completely -CFLAGS += -DUIP_CONF_IPV6 +CFLAGS += -DUIP_CONF_IPV6=1 CONTIKI=../../.. CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" @@ -31,40 +27,9 @@ endif # linker optimizations SMALL=1 -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif -APPS += erbium +APPS += er-coap +APPS += rest-engine # optional rules to get assembly #CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 @@ -92,3 +57,10 @@ connect-router-cooja: $(CONTIKI)/tools/tunslip6 connect-minimal: sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/powerbox/er-example-server.c b/examples/osd/powerbox/er-example-server.c index 253705154..09259b075 100644 --- a/examples/osd/powerbox/er-example-server.c +++ b/examples/osd/powerbox/er-example-server.c @@ -42,16 +42,15 @@ #include #include "contiki.h" #include "contiki-net.h" +#include "er-coap.h" /* Define which resources to include to meet memory constraints. */ #define REST_RES_INFO 1 #define REST_RES_RELAY 1 #define REST_RES_LEDS 1 -#define REST_RES_TOGGLE 1 #define REST_RES_BATTERY 1 -#include "erbium.h" #if defined (PLATFORM_HAS_BUTTON) #include "dev/button-sensor.h" @@ -67,19 +66,6 @@ #endif -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP == 3 -#include "er-coap-03.h" -#elif WITH_COAP == 7 -#include "er-coap-07.h" -#elif WITH_COAP == 12 -#include "er-coap-12.h" -#elif WITH_COAP == 13 -#include "er-coap-13.h" -#else -#warning "Erbium example without CoAP-specifc functionality" -#endif /* CoAP-specific example */ - #define DEBUG 0 #if DEBUG #define PRINTF(...) printf(__VA_ARGS__) @@ -92,13 +78,7 @@ #endif /******************************************************************************/ - #if REST_RES_INFO -/* - * Resources are defined by the RESOURCE macro. - * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). - */ -RESOURCE(info, METHOD_GET, "info", "title=\"Info\";rt=\"text\""); /* * A handler function named [resource name]_handler must be implemented for each RESOURCE. @@ -107,7 +87,7 @@ RESOURCE(info, METHOD_GET, "info", "title=\"Info\";rt=\"text\""); * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. */ void -info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +info_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { char message[100]; int index = 0; @@ -125,14 +105,17 @@ info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_ REST.set_header_content_type(response, REST.type.APPLICATION_JSON); REST.set_response_payload(response, buffer, length); } +/* + * Resources are defined by the RESOURCE macro. + * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). + */ +RESOURCE(res_info, "title=\"Info\";rt=\"text\"", info_get_handler, NULL, NULL, NULL); #endif /******************************************************************************/ #if defined (PLATFORM_HAS_RELAY) /******************************************************************************/ #if REST_RES_RELAY -/*A simple actuator example*/ -RESOURCE(relay, METHOD_GET | METHOD_POST | METHOD_PUT , "actuators/relay", "title=\"RELAY: ?type=1|2|3|4, POST/PUT, POST/PUT mode=on|off\";rt=\"Control\""); void relay_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) @@ -183,9 +166,6 @@ relay_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred break; case METHOD_POST: - success = 0; - break; - case METHOD_PUT: if ((len=REST.get_query_variable(request, "type", &type))) { PRINTF("type %.*s\n", len, type); if (strncmp(type, "1", len)==0) { @@ -224,6 +204,8 @@ relay_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred REST.set_response_status(response, REST.status.BAD_REQUEST); } } +/*A simple actuator example*/ +RESOURCE(res_relay, "title=\"RELAY: ?type=1|2|3|4, POST/PUT, POST/PUT mode=on|off\";rt=\"Control\"", relay_handler, NULL, relay_handler, NULL); #endif /******************************************************************************/ #endif /* PLATFORM_HAS_RELAY */ @@ -232,8 +214,6 @@ relay_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred #if defined (PLATFORM_HAS_LEDS) /******************************************************************************/ #if REST_RES_LEDS -/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -RESOURCE(leds, METHOD_POST | METHOD_PUT , "actuators/leds", "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\""); void leds_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) @@ -278,18 +258,10 @@ leds_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_ REST.set_response_status(response, REST.status.BAD_REQUEST); } } +/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ +RESOURCE(res_leds, "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\"", NULL, leds_handler, leds_handler, NULL); #endif -/******************************************************************************/ -#if REST_RES_TOGGLE -/* A simple actuator example. Toggles the red led */ -RESOURCE(toggle, METHOD_GET | METHOD_PUT | METHOD_POST, "actuators/toggle", "title=\"Red LED\";rt=\"Control\""); -void -toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - leds_toggle(LEDS_RED); -} -#endif #endif /* PLATFORM_HAS_LEDS */ /******************************************************************************/ @@ -297,7 +269,6 @@ toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre /******************************************************************************/ #if REST_RES_TEMPERATURE && defined (PLATFORM_HAS_TEMPERATURE) /* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(temperature, METHOD_GET, "sensors/cputemp", "title=\"Temperature status\";rt=\"temperature-c\""); void temperature_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { @@ -327,29 +298,26 @@ temperature_handler(void* request, void* response, uint8_t *buffer, uint16_t pre REST.set_response_payload(response, msg, strlen(msg)); } } +RESOURCE(res_temperature, "title=\"Temperature status\";rt=\"temperature-c\"", temperature_handler, NULL, NULL, NULL); #endif /* PLATFORM_HAS_TEMPERATURE */ /******************************************************************************/ #if REST_RES_BATTERY && defined (PLATFORM_HAS_BATTERY) /* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(battery, METHOD_GET, "sensors/battery", "title=\"Battery status\";rt=\"battery-mV\""); void battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { int battery = battery_sensor.value(0); - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { REST.set_header_content_type(response, REST.type.TEXT_PLAIN); snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", battery); REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { + else if(accept == REST.type.APPLICATION_JSON) { REST.set_header_content_type(response, REST.type.APPLICATION_JSON); snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'battery':%d}", battery); @@ -362,6 +330,8 @@ battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr REST.set_response_payload(response, msg, strlen(msg)); } } +RESOURCE(res_battery, "title=\"Battery status\";rt=\"battery-mV\"", battery_handler, NULL, NULL, NULL); + #endif /* PLATFORM_HAS_BATTERY */ /******************************************************************************/ @@ -401,24 +371,21 @@ PROCESS_THREAD(rest_server_example, ev, data) /* Activate the application-specific resources. */ #if REST_RES_INFO - rest_activate_resource(&resource_info); + rest_activate_resource(&res_info, "info"); #endif /* Activate the application-specific resources. */ #if REST_RES_RELAY SENSORS_ACTIVATE(relay_sensor); - rest_activate_resource(&resource_relay); + rest_activate_resource(&res_relay, "a/relay"); #endif #if defined (PLATFORM_HAS_LEDS) #if REST_RES_LEDS - rest_activate_resource(&resource_leds); -#endif -#if REST_RES_TOGGLE - rest_activate_resource(&resource_toggle); + rest_activate_resource(&res_leds, "a/leds"); #endif #endif /* PLATFORM_HAS_LEDS */ #if defined (PLATFORM_HAS_BATTERY) && REST_RES_BATTERY SENSORS_ACTIVATE(battery_sensor); - rest_activate_resource(&resource_battery); + rest_activate_resource(&res_battery, "s/battery"); #endif /* Define application-specific events here. */ diff --git a/examples/osd/powerbox/flash.sh b/examples/osd/powerbox/flash.sh index e92d472f6..e82962073 100755 --- a/examples/osd/powerbox/flash.sh +++ b/examples/osd/powerbox/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-server.osd-merkur.hex:a -U eeprom:w:er-example-server.osd-merkur.eep:a +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/powerbox/run.sh b/examples/osd/powerbox/run.sh index 2efd2cf48..5d5cbbbb4 100755 --- a/examples/osd/powerbox/run.sh +++ b/examples/osd/powerbox/run.sh @@ -1,8 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size -C --mcu=MCU=atmega128rfa1 er-example-server.osd-merkur -avr-objcopy -j .text -j .data -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.eep +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/powerbox/server-client.csc b/examples/osd/powerbox/server-client.csc deleted file mode 100644 index 8c45fdf02..000000000 --- a/examples/osd/powerbox/server-client.csc +++ /dev/null @@ -1,227 +0,0 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - client - Erbium Client - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c - make er-example-client.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 46.57186415376375 - 40.35946215910942 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - - se.sics.cooja.interfaces.Position - 18.638049428485125 - 47.55034515769599 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 3 - - client - - - - se.sics.cooja.plugins.SimControl - 259 - 0 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 - - 300 - 2 - 178 - 261 - 1 - - - se.sics.cooja.plugins.LogListener - - - - - 762 - 3 - 491 - 2 - 182 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 4 - 74 - 578 - 18 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - 2 - - - - - 125 - 25.49079397896416 - - 1624 - 5 - 252 - 6 - 712 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 2 - - Serial port - 0,0 - - 853 - 1 - 491 - 765 - 182 - - - diff --git a/examples/osd/powerbox/server-only.csc b/examples/osd/powerbox/server-only.csc index d5eee34d6..1b0fe28bf 100644 --- a/examples/osd/powerbox/server-only.csc +++ b/examples/osd/powerbox/server-only.csc @@ -1,189 +1,189 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 35.100895239785295 - 39.70574552287428 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - se.sics.cooja.plugins.SimControl - 259 - 5 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 - - 300 - 4 - 175 - 263 - 3 - - - se.sics.cooja.plugins.LogListener - - - - - 560 - 1 - 326 - 1 - 293 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 2 - 74 - 39 - 199 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - - - - - 125 - 25.49079397896416 - - 1624 - 3 - 252 - 4 - 622 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 1 - - Serial port - 0,0 - - 702 - 0 - 646 - 564 - 2 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + REST with RPL router + -2147483648 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + se.sics.cooja.interfaces.Position + 35.100895239785295 + 39.70574552287428 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + se.sics.cooja.plugins.SimControl + 259 + 5 + 179 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.AttributeVisualizerSkin + se.sics.cooja.plugins.skins.LEDVisualizerSkin + se.sics.cooja.plugins.skins.AddressVisualizerSkin + 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 + + 300 + 4 + 175 + 263 + 3 + + + se.sics.cooja.plugins.LogListener + + + + + 560 + 1 + 326 + 1 + 293 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 2 + 74 + 39 + 199 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + + + + + 125 + 25.49079397896416 + + 1624 + 3 + 252 + 4 + 622 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 702 + 0 + 646 + 564 + 2 + + + diff --git a/examples/osd/pwm-example/Makefile b/examples/osd/pwm-example/Makefile index 8d5ffbb3e..c10f7ff31 100644 --- a/examples/osd/pwm-example/Makefile +++ b/examples/osd/pwm-example/Makefile @@ -1,17 +1,12 @@ -all: er-example-server \ - er-example-server.osd-merkur.hex er-example-server.osd-merkur.eep -# use this target explicitly if requried: er-plugtest-server +EXE=er-example-server -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 - -# for some platforms -UIP_CONF_IPV6=1 -# IPv6 make config disappeared completely -CFLAGS += -DUIP_CONF_IPV6=1 +all: $(EXE) CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" PROJECT_SOURCEFILES += resource_led_pwm.c @@ -33,59 +28,13 @@ endif # linker optimizations SMALL=1 -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif - -APPS += erbium json json-resource +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += json json-resource include $(CONTIKI)/Makefile.include -er-example-server.osd-merkur.hex: er-example-server.osd-merkur - avr-objcopy -j .text -j .data -O ihex er-example-server.osd-merkur \ - er-example-server.osd-merkur.hex - -er-example-server.osd-merkur.eep: er-example-server.osd-merkur - avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O ihex \ - er-example-server.osd-merkur er-example-server.osd-merkur.eep - -flash: er-example-server.osd-merkur.hex er-example-server.osd-merkur.eep - avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U \ - flash:w:er-example-server.osd-merkur.hex:a -U \ - eeprom:w:er-example-server.osd-merkur.eep:a - -.PHONY: flash - $(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c (cd $(CONTIKI)/tools && $(MAKE) tunslip6) @@ -97,3 +46,10 @@ connect-router-cooja: $(CONTIKI)/tools/tunslip6 connect-minimal: sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/pwm-example/er-example-server.c b/examples/osd/pwm-example/er-example-server.c index 6f6fddbbb..4b7836a67 100644 --- a/examples/osd/pwm-example/er-example-server.c +++ b/examples/osd/pwm-example/er-example-server.c @@ -43,9 +43,7 @@ #include "contiki.h" #include "contiki-net.h" #include "jsonparse.h" - -#include "erbium.h" -#include "er-coap-13.h" +#include "er-coap.h" #include "led_pwm.h" @@ -58,44 +56,6 @@ /******************************************************************************/ -/* - * Resources are defined by the RESOURCE macro. - * Signature: resource name, the RESTful methods it handles, and its URI - * path (omitting the leading slash). - */ -RESOURCE(info, METHOD_GET, "info", "title=\"Info\";rt=\"text\""); - -/* - * A handler function named [resource name]_handler must be implemented - * for each RESOURCE. A buffer for the response payload is provided - * through the buffer pointer. Simple resources can ignore - * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE - * limit for the buffer. If a smaller block size is requested for CoAP, - * the REST framework automatically splits the data. - */ -void -info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - char message[100]; - int index = 0; - int length = 0; /* |<-------->| */ - - /* - * Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, - * see the chunk resource. - */ - // jSON Format - index += sprintf(message + index,"{\n \"Version\" : \"V1.0pre1\",\n"); - index += sprintf(message + index," \"name\" : \"PWM\"\n"); - index += sprintf(message + index,"}\n"); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - REST.set_response_payload(response, buffer, length); -} - void hw_init() { @@ -137,8 +97,7 @@ PROCESS_THREAD(rest_server_example, ev, data) rest_init_engine(); /* Activate the application-specific resources. */ - rest_activate_resource(&resource_info); - rest_activate_resource(&resource_led_pwm); + rest_activate_resource(&res_led_pwm, "led/pwm"); /* Define application-specific events here. */ while(1) { diff --git a/examples/osd/pwm-example/flash.sh b/examples/osd/pwm-example/flash.sh index e9cb40bfc..e82962073 100755 --- a/examples/osd/pwm-example/flash.sh +++ b/examples/osd/pwm-example/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -make TARGET=osd-merkur flash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/pwm-example/led_pwm.h b/examples/osd/pwm-example/led_pwm.h index b93008136..b3a2e8868 100644 --- a/examples/osd/pwm-example/led_pwm.h +++ b/examples/osd/pwm-example/led_pwm.h @@ -17,9 +17,8 @@ #ifndef led_pwm_h #define led_pwm_h #include "contiki.h" -#include "erbium.h" -extern resource_t resource_led_pwm; +extern resource_t res_led_pwm; extern void led_pwm_init (void); #endif // led_pwm_h diff --git a/examples/osd/pwm-example/resource_led_pwm.c b/examples/osd/pwm-example/resource_led_pwm.c index deee9e3b4..a6d4b58a8 100644 --- a/examples/osd/pwm-example/resource_led_pwm.c +++ b/examples/osd/pwm-example/resource_led_pwm.c @@ -12,8 +12,7 @@ #include #include "contiki.h" #include "jsonparse.h" -/* Only coap 13 for now */ -#include "er-coap-13.h" +#include "er-coap.h" #include "hw_timer.h" #include "generic_resource.h" @@ -59,8 +58,7 @@ size_t pwm_to_string (const char *n, uint8_t is_json, char *buf, size_t bufsize) } GENERIC_RESOURCE \ - ( led_pwm, METHOD_GET | METHOD_PUT - , "led/pwm" + ( led_pwm , LED PWM , duty-cycle , pwm_from_string diff --git a/examples/osd/pwm-example/run.sh b/examples/osd/pwm-example/run.sh index 295a9ab1d..5d5cbbbb4 100755 --- a/examples/osd/pwm-example/run.sh +++ b/examples/osd/pwm-example/run.sh @@ -1,5 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/resources-common/res-battery.c b/examples/osd/resources-common/res-battery.c new file mode 100644 index 000000000..c7a025d38 --- /dev/null +++ b/examples/osd/resources-common/res-battery.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include "contiki.h" + +#if PLATFORM_HAS_BATTERY + +#include +#include "rest-engine.h" +#include "dev/battery-sensor.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from light sensor with a simple etag */ +RESOURCE(res_battery, + "title=\"Battery status\";rt=\"Battery\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + int battery = battery_sensor.value(0); + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d.%02d", battery/1000, battery % 1000); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'battery':%d.%02d}", battery/1000, battery % 1000); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} +#endif /* PLATFORM_HAS_BATTERY */ diff --git a/examples/osd/resources-common/res-cputemp.c b/examples/osd/resources-common/res-cputemp.c new file mode 100644 index 000000000..8a748b74d --- /dev/null +++ b/examples/osd/resources-common/res-cputemp.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Moisture resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_cputemp, + "title=\"CPU temperature status\";rt=\"Temperature\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + int cputemp = readInternalTemp(); + int f_integral = (int)(cputemp/100); + int f_centi = cputemp - f_integral*100; + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d.%02d", f_integral, f_centi); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'cputemp':%d.%02d}", f_integral, f_centi); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} + diff --git a/examples/osd/resources-common/res-leds.c b/examples/osd/resources-common/res-leds.c new file mode 100644 index 000000000..5fbcf6c77 --- /dev/null +++ b/examples/osd/resources-common/res-leds.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include "contiki.h" + +#if PLATFORM_HAS_LEDS + +#include +#include "rest-engine.h" +#include "dev/leds.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +static void res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ +RESOURCE(res_leds, + "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\"", + NULL, + res_post_put_handler, + res_post_put_handler, + NULL); + +static void +res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + size_t len = 0; + const char *color = NULL; + const char *mode = NULL; + uint8_t led = 0; + int success = 1; + + if((len = REST.get_query_variable(request, "color", &color))) { + PRINTF("color %.*s\n", len, color); + + if(strncmp(color, "r", len) == 0) { + led = LEDS_RED; + } else if(strncmp(color, "g", len) == 0) { + led = LEDS_GREEN; + } else if(strncmp(color, "b", len) == 0) { + led = LEDS_BLUE; + } else { + success = 0; + } + } else { + success = 0; + } if(success && (len = REST.get_post_variable(request, "mode", &mode))) { + PRINTF("mode %s\n", mode); + + if(strncmp(mode, "on", len) == 0) { + leds_on(led); + } else if(strncmp(mode, "off", len) == 0) { + leds_off(led); + } else { + success = 0; + } + } else { + success = 0; + } if(!success) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} +#endif /* PLATFORM_HAS_LEDS */ diff --git a/examples/osd/resources-common/res-radio.c b/examples/osd/resources-common/res-radio.c new file mode 100644 index 000000000..ac09319a3 --- /dev/null +++ b/examples/osd/resources-common/res-radio.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include "contiki.h" + +#if PLATFORM_HAS_RADIO + +#include +#include "rest-engine.h" +#include "dev/radio-sensor.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading of the rssi/lqi from radio sensor */ +RESOURCE(res_radio, + "title=\"RADIO: ?p=lqi|rssi\";rt=\"RadioSensor\"", + res_get_handler, + NULL, + NULL, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + size_t len = 0; + const char *p = NULL; + uint8_t param = 0; + int success = 1; + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if((len = REST.get_query_variable(request, "p", &p))) { + if(strncmp(p, "lqi", len) == 0) { + param = RADIO_SENSOR_LAST_VALUE; + } else if(strncmp(p, "rssi", len) == 0) { + param = RADIO_SENSOR_LAST_PACKET; + } else { + success = 0; + } + } else { + success = 0; + } if(success) { + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", radio_sensor.value(param)); + + REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + + if(param == RADIO_SENSOR_LAST_VALUE) { + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'lqi':%d}", radio_sensor.value(param)); + } else if(param == RADIO_SENSOR_LAST_PACKET) { + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'rssi':%d}", radio_sensor.value(param)); + } + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } + } else { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} +#endif /* PLATFORM_HAS_RADIO */ diff --git a/examples/osd/rpl-border-router/Makefile b/examples/osd/rpl-border-router/Makefile index f296b0bb3..e57591e80 100644 --- a/examples/osd/rpl-border-router/Makefile +++ b/examples/osd/rpl-border-router/Makefile @@ -1,11 +1,8 @@ -CONTIKI_PROJECT=border-router -all: $(CONTIKI_PROJECT) +EXE=border-router +all: $(EXE) CONTIKI=../../.. -UIP_CONF_IPV6=1 -CFLAGS+= -DUIP_CONF_IPV6_RPL - #linker optimizations SMALL=1 @@ -26,10 +23,12 @@ PROJECT_SOURCEFILES += slip-bridge.c WITH_WEBSERVER=1 ifeq ($(WITH_WEBSERVER),1) +CFLAGS += -DUIP_CONF_TCP=1 CFLAGS += -DWEBSERVER=1 PROJECT_SOURCEFILES += httpd-simple.c else ifneq ($(WITH_WEBSERVER), 0) APPS += $(WITH_WEBSERVER) +CFLAGS += -DUIP_CONF_TCP=1 CFLAGS += -DWEBSERVER=2 endif @@ -37,6 +36,7 @@ ifeq ($(PREFIX),) PREFIX = aaaa::1/64 endif +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include $(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c @@ -47,3 +47,10 @@ connect-router: $(CONTIKI)/tools/tunslip6 connect-router-cooja: $(CONTIKI)/tools/tunslip6 sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 $(PREFIX) + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/rpl-border-router/border-router.c b/examples/osd/rpl-border-router/border-router.c index 91cd0e380..5e5717d90 100644 --- a/examples/osd/rpl-border-router/border-router.c +++ b/examples/osd/rpl-border-router/border-router.c @@ -50,14 +50,11 @@ #include #include #include - #include "dev/leds.h" #define DEBUG DEBUG_NONE #include "net/ip/uip-debug.h" -uint16_t dag_id[] = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011}; - static uip_ipaddr_t prefix; static uint8_t prefix_set; @@ -103,7 +100,7 @@ PROCESS_THREAD(webserver_nogui_process, ev, data) PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); httpd_appcall(data); } - + PROCESS_END(); } AUTOSTART_PROCESSES(&border_router_process,&webserver_nogui_process); @@ -147,7 +144,6 @@ ipaddr_add(const uip_ipaddr_t *addr) static PT_THREAD(generate_routes(struct httpd_state *s)) { - static int i; static uip_ds6_route_t *r; static uip_ds6_nbr_t *nbr; #if BUF_USES_STACK @@ -180,7 +176,7 @@ PT_THREAD(generate_routes(struct httpd_state *s)) switch (nbr->state) { case NBR_INCOMPLETE: ADD(" INCOMPLETE");break; case NBR_REACHABLE: ADD(" REACHABLE");break; - case NBR_STALE: ADD(" STALE");break; + case NBR_STALE: ADD(" STALE");break; case NBR_DELAY: ADD(" DELAY");break; case NBR_PROBE: ADD(" NBR_PROBE");break; } @@ -192,7 +188,7 @@ PT_THREAD(generate_routes(struct httpd_state *s)) switch (nbr->state) { case NBR_INCOMPLETE: ADD(" INCOMPLETE");break; case NBR_REACHABLE: ADD(" REACHABLE");break; - case NBR_STALE: ADD(" STALE");break; + case NBR_STALE: ADD(" STALE");break; case NBR_DELAY: ADD(" DELAY");break; case NBR_PROBE: ADD(" NBR_PROBE");break; } @@ -251,7 +247,7 @@ PT_THREAD(generate_routes(struct httpd_state *s)) ADD("/%u (via ", r->length); ipaddr_add(uip_ds6_route_nexthop(r)); if(1 || (r->state.lifetime < 600)) { - ADD(") %lus\n", r->state.lifetime); + ADD(") %lus\n", (unsigned long)r->state.lifetime); } else { ADD(")\n"); } @@ -316,29 +312,36 @@ request_prefix(void) uip_buf[1] = 'P'; uip_len = 2; slip_send(); - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ void set_prefix_64(uip_ipaddr_t *prefix_64) { + rpl_dag_t *dag; uip_ipaddr_t ipaddr; memcpy(&prefix, prefix_64, 16); memcpy(&ipaddr, prefix_64, 16); prefix_set = 1; uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); + + dag = rpl_set_root(RPL_DEFAULT_INSTANCE, &ipaddr); + if(dag != NULL) { + rpl_set_prefix(dag, &prefix, 64); + PRINTF("created a new RPL dag\n"); + } } /*---------------------------------------------------------------------------*/ PROCESS_THREAD(border_router_process, ev, data) { static struct etimer et; - rpl_dag_t *dag; PROCESS_BEGIN(); leds_off(LEDS_RED); + /* While waiting for the prefix to be sent through the SLIP connection, the future - * border router can join an existing DAG as a parent or child, or acquire a default + * border router can join an existing DAG as a parent or child, or acquire a default * router that will later take precedence over the SLIP fallback interface. * Prevent that by turning the radio off until we are initialized as a DAG root. */ @@ -357,7 +360,7 @@ PROCESS_THREAD(border_router_process, ev, data) cpu will interfere with establishing the SLIP connection */ NETSTACK_MAC.off(1); #endif - + /* Request prefix until it has been received */ while(!prefix_set) { etimer_set(&et, CLOCK_SECOND); @@ -365,17 +368,11 @@ PROCESS_THREAD(border_router_process, ev, data) PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); } - dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)dag_id); - if(dag != NULL) { - rpl_set_prefix(dag, &prefix, 64); - PRINTF("created a new RPL dag\n"); - } - /* Now turn the radio on, but disable radio duty cycling. * Since we are the DAG root, reception delays would constrain mesh throughbut. */ NETSTACK_MAC.off(1); - + #if DEBUG || 1 print_local_addresses(); #endif diff --git a/examples/osd/rpl-border-router/flash.sh b/examples/osd/rpl-border-router/flash.sh index 07cfc9a65..e82962073 100755 --- a/examples/osd/rpl-border-router/flash.sh +++ b/examples/osd/rpl-border-router/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:border-router.osd-merkur.hex:a -U eeprom:w:border-router.osd-merkur.eep:a +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/rpl-border-router/project-conf.h b/examples/osd/rpl-border-router/project-conf.h index 20c6652df..d02caa0f1 100644 --- a/examples/osd/rpl-border-router/project-conf.h +++ b/examples/osd/rpl-border-router/project-conf.h @@ -38,9 +38,14 @@ /* Save some memory for the sky platform. */ #undef NBR_TABLE_CONF_MAX_NEIGHBORS #define NBR_TABLE_CONF_MAX_NEIGHBORS 20 + #undef UIP_CONF_MAX_ROUTES #define UIP_CONF_MAX_ROUTES 20 +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 64 + #ifndef QUEUEBUF_CONF_NUM #define QUEUEBUF_CONF_NUM 4 #endif diff --git a/examples/osd/rpl-border-router/run.sh b/examples/osd/rpl-border-router/run.sh index 2bcaa03ef..dc2b12de9 100755 --- a/examples/osd/rpl-border-router/run.sh +++ b/examples/osd/rpl-border-router/run.sh @@ -1,8 +1,6 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size -C --mcu=MCU=atmega128rfa1 border-router.osd-merkur -avr-objcopy -j .text -j .data -O ihex border-router.osd-merkur border-router.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex border-router.osd-merkur border-router.osd-merkur.eep +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 avr-size diff --git a/examples/osd/rpl-border-router/slip-bridge.c b/examples/osd/rpl-border-router/slip-bridge.c index 52b4a4060..62940d5ef 100644 --- a/examples/osd/rpl-border-router/slip-bridge.c +++ b/examples/osd/rpl-border-router/slip-bridge.c @@ -59,7 +59,7 @@ slip_input_callback(void) // PRINTF("SIN: %u\n", uip_len); if(uip_buf[0] == '!') { PRINTF("Got configuration message of type %c\n", uip_buf[1]); - uip_len = 0; + uip_clear_buf(); if(uip_buf[1] == 'P') { uip_ipaddr_t prefix; /* Here we set a prefix !!! */ @@ -85,7 +85,7 @@ slip_input_callback(void) slip_send(); } - uip_len = 0; + uip_clear_buf(); } /* Save the last sender received over SLIP to avoid bouncing the packet back if no route is found */ @@ -100,7 +100,7 @@ init(void) slip_set_input_callback(slip_input_callback); } /*---------------------------------------------------------------------------*/ -static void +static int output(void) { if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) { @@ -115,6 +115,7 @@ output(void) // PRINTF("SUT: %u\n", uip_len); slip_send(); } + return 0; } /*---------------------------------------------------------------------------*/ diff --git a/examples/osd/runall.sh b/examples/osd/runall.sh index ab9e9ca92..a07abaf23 100755 --- a/examples/osd/runall.sh +++ b/examples/osd/runall.sh @@ -1,12 +1,5 @@ #!/bin/bash -# er-rest-example-merkurboard -echo "merkurboard" -cd ./merkurboard -./run.sh -cd .. -echo "done (merkurboard)" - # er-rest-example-merkurboard echo "er-rest-example-merkurboard" cd ./er-rest-example-merkurboard @@ -21,6 +14,13 @@ cd ./climate cd .. echo "done (Climate)" +# Climate2 +echo "Climate2" +cd ./climate2 +./run.sh +cd .. +echo "done (Climate2)" + # Embeddvm echo "Embedded-VM" cd ./embedd-vm-merkurboard @@ -42,12 +42,6 @@ cd ./pingtheplug cd .. echo "done (Pingtheplug)" -# 6lowpan-tk -#echo "6loWPAN-Tür/Fenster Kontakt" -#cd ./6lowpan-tk -#./run.sh -#cd .. -#echo "done (6loWPAN-Tür/Fenster Kontakt)" # PIR-Sensor #echo "PIR-Sensor" diff --git a/examples/osd/servo-sensor/Makefile b/examples/osd/servo-sensor/Makefile index 8a253c40d..72ffc56e5 100644 --- a/examples/osd/servo-sensor/Makefile +++ b/examples/osd/servo-sensor/Makefile @@ -1,10 +1,6 @@ -all: er-example-server -# use this target explicitly if requried: er-plugtest-server +EXE=er-example-server - -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 +all: $(EXE) # for some platforms UIP_CONF_IPV6=1 @@ -31,40 +27,9 @@ endif # linker optimizations SMALL=1 -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif -APPS += erbium +APPS += er-coap +APPS += rest-engine # optional rules to get assembly #CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 @@ -92,3 +57,10 @@ connect-router-cooja: $(CONTIKI)/tools/tunslip6 connect-minimal: sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/servo-sensor/er-example-server.c b/examples/osd/servo-sensor/er-example-server.c index 8522e256d..87ad90c6e 100644 --- a/examples/osd/servo-sensor/er-example-server.c +++ b/examples/osd/servo-sensor/er-example-server.c @@ -42,17 +42,17 @@ #include #include "contiki.h" #include "contiki-net.h" +#include "rest-engine.h" /* Define which resources to include to meet memory constraints. */ #define REST_RES_INFO 1 -#define REST_RES_T4_SERVO 1 +#define REST_RES_SERVO 1 +#define REST_RES_T4_SERVO 0 #define REST_RES_LEDS 0 #define REST_RES_TOGGLE 0 #define REST_RES_BATTERY 1 -#include "erbium.h" - #if defined (PLATFORM_HAS_BUTTON) #include "dev/button-sensor.h" #endif @@ -73,19 +73,6 @@ #endif -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP == 3 -#include "er-coap-03.h" -#elif WITH_COAP == 7 -#include "er-coap-07.h" -#elif WITH_COAP == 12 -#include "er-coap-12.h" -#elif WITH_COAP == 13 -#include "er-coap-13.h" -#else -#warning "Erbium example without CoAP-specifc functionality" -#endif /* CoAP-specific example */ - #define DEBUG 0 #if DEBUG #define PRINTF(...) printf(__VA_ARGS__) @@ -100,12 +87,6 @@ /******************************************************************************/ #if REST_RES_INFO -/* - * Resources are defined by the RESOURCE macro. - * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). - */ -RESOURCE(info, METHOD_GET, "info", "title=\"Info\";rt=\"text\""); - /* * A handler function named [resource name]_handler must be implemented for each RESOURCE. * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore @@ -113,7 +94,7 @@ RESOURCE(info, METHOD_GET, "info", "title=\"Info\";rt=\"text\""); * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. */ void -info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +info_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { char message[100]; int index = 0; @@ -131,11 +112,17 @@ info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_ REST.set_header_content_type(response, REST.type.APPLICATION_JSON); REST.set_response_payload(response, buffer, length); } + +/* + * Resources are defined by the RESOURCE macro. + * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). + */ +RESOURCE(res_info, "title=\"Info\";rt=\"text\"", info_get_handler, NULL, NULL, NULL); + #endif #if defined (PLATFORM_HAS_SERVO) /*A simple actuator example. read the servo status*/ -RESOURCE(servo, METHOD_GET | METHOD_PUT , "actuators/servo", "title=\"Servo\";rt=\"servo\""); void servo_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { @@ -186,10 +173,10 @@ servo_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred REST.set_response_status(response, REST.status.BAD_REQUEST); } } +RESOURCE(res_servo, "title=\"Servo\";rt=\"servo\"", servo_handler, NULL, servo_handler, NULL ); #endif #if defined (PLATFORM_HAS_T4_SERVO) -RESOURCE(t4_servo, METHOD_GET | METHOD_PUT , "actuators/t4_servo", "title=\"Timer4Servo\";rt=\"t4_servo\""); void t4_servo_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { @@ -265,6 +252,7 @@ t4_servo_handler(void* request, void* response, uint8_t *buffer, uint16_t prefer REST.set_response_status(response, REST.status.BAD_REQUEST); } } +RESOURCE(res_t4_servo,"title=\"Timer4Servo\";rt=\"t4_servo\"", t4_servo_handler, te4_servo_handler, te4_servo_handler, NULL ); #endif @@ -273,8 +261,6 @@ t4_servo_handler(void* request, void* response, uint8_t *buffer, uint16_t prefer /******************************************************************************/ #if REST_RES_LEDS /*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -RESOURCE(leds, METHOD_POST | METHOD_PUT , "actuators/leds", "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\""); - void leds_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { @@ -318,17 +304,18 @@ leds_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_ REST.set_response_status(response, REST.status.BAD_REQUEST); } } +RESOURCE(res_leds, "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\"", NULL, leds_handler, leds_handler, NULL); #endif /******************************************************************************/ #if REST_RES_TOGGLE /* A simple actuator example. Toggles the red led */ -RESOURCE(toggle, METHOD_GET | METHOD_PUT | METHOD_POST, "actuators/toggle", "title=\"Red LED\";rt=\"Control\""); void toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { leds_toggle(LEDS_RED); } +RESOURCE(res_toggle, "title=\"Red LED\";rt=\"Control\"", toggle_handler, toggle_handler, toggle_handler, NULL); #endif #endif /* PLATFORM_HAS_LEDS */ @@ -337,7 +324,6 @@ toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre /******************************************************************************/ #if REST_RES_TEMPERATURE && defined (PLATFORM_HAS_TEMPERATURE) /* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(temperature, METHOD_GET, "sensors/cputemp", "title=\"Temperature status\";rt=\"temperature-c\""); void temperature_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { @@ -367,41 +353,37 @@ temperature_handler(void* request, void* response, uint8_t *buffer, uint16_t pre REST.set_response_payload(response, msg, strlen(msg)); } } +RESOURCE(res_temperature, "title=\"Temperature status\";rt=\"temperature-c\"", temperature_handler, NULL, NULL, NULL); #endif /* PLATFORM_HAS_TEMPERATURE */ /******************************************************************************/ #if REST_RES_BATTERY && defined (PLATFORM_HAS_BATTERY) /* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(battery, METHOD_GET, "sensors/battery", "title=\"Battery status\";rt=\"battery-mV\""); void battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { int battery = battery_sensor.value(0); - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); + unsigned int accept = -1; + REST.get_header_accept(request, &accept); - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", battery); - - REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'battery':%d}", battery); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d.%02d", battery/1000, battery % 1000); REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else - { + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'battery':%d.%02d}", battery/1000, battery % 1000); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); const char *msg = "Supporting content-types text/plain and application/json"; REST.set_response_payload(response, msg, strlen(msg)); } } +RESOURCE(res_battery, "title=\"Battery status\";rt=\"battery-mV\"", battery_handler, NULL, NULL, NULL); #endif /* PLATFORM_HAS_BATTERY */ /******************************************************************************/ @@ -447,27 +429,31 @@ PROCESS_THREAD(rest_server_example, ev, data) /* Activate the application-specific resources. */ #if REST_RES_INFO - rest_activate_resource(&resource_info); + rest_activate_resource(&res_info, "info"); #endif #if defined (PLATFORM_HAS_LEDS) #if REST_RES_LEDS - rest_activate_resource(&resource_leds); + rest_activate_resource(&res_leds, "actuators/leds"); #endif #if REST_RES_TOGGLE - rest_activate_resource(&resource_toggle); + rest_activate_resource(&res_toggle, "actuators/toggle"); #endif #endif /* PLATFORM_HAS_LEDS */ #if defined (PLATFORM_HAS_TEMPERATURE) && REST_RES_TEMPERATURE SENSORS_ACTIVATE(temperature_sensor); - rest_activate_resource(&resource_temperature); + rest_activate_resource(&res_temperature, "sensors/cputemp"); #endif #if defined (PLATFORM_HAS_BATTERY) && REST_RES_BATTERY SENSORS_ACTIVATE(battery_sensor); - rest_activate_resource(&resource_battery); + rest_activate_resource(&res_battery, "sensors/battery"); +#endif +#if defined (PLATFORM_HAS_SERVO) && REST_RES_SERVO + SENSORS_ACTIVATE(servo_sensor); + rest_activate_resource(&res_servo, "actuators/servo"); #endif #if defined (PLATFORM_HAS_T4_SERVO) && REST_RES_T4_SERVO SENSORS_ACTIVATE(t4_servo_sensor); - rest_activate_resource(&resource_t4_servo); + rest_activate_resource(&res_t4_servo, "actuators/t4_servo"); #endif /* Define application-specific events here. */ diff --git a/examples/osd/servo-sensor/flash.sh b/examples/osd/servo-sensor/flash.sh index b91668634..e82962073 100755 --- a/examples/osd/servo-sensor/flash.sh +++ b/examples/osd/servo-sensor/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-server.osd-merkur.hex:a -U eeprom:w:er-example-server.osd-merkur.eep:a +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/servo-sensor/project-conf.h b/examples/osd/servo-sensor/project-conf.h index 7f2b57d02..31ff68aa3 100644 --- a/examples/osd/servo-sensor/project-conf.h +++ b/examples/osd/servo-sensor/project-conf.h @@ -34,7 +34,8 @@ //#define PLATFORM_HAS_LEDS 1 //#define PLATFORM_HAS_BUTTON 1 -#define PLATFORM_HAS_T4_SERVO 1 +#define PLATFORM_HAS_SERVO +//#define PLATFORM_HAS_T4_SERVO 1 #define PLATFORM_HAS_BATTERY 1 #define SICSLOWPAN_CONF_FRAG 1 @@ -46,11 +47,6 @@ /* Some platforms have weird includes. */ #undef IEEE802154_CONF_PANID -/* Disabling RDC for demo purposes. Core updates often require more memory. */ -/* For projects, optimize memory and enable RDC again. */ -// #undef NETSTACK_CONF_RDC -//#define NETSTACK_CONF_RDC nullrdc_driver - /* Increase rpl-border-router IP-buffer when using more than 64. */ #undef REST_MAX_CHUNK_SIZE #define REST_MAX_CHUNK_SIZE 64 @@ -83,22 +79,5 @@ #define COAP_LINK_FORMAT_FILTERING 0 */ -/* Save some memory for the sky platform. */ -/* -#undef NBR_TABLE_CONF_MAX_NEIGHBORS -#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 -#undef UIP_CONF_MAX_ROUTES -#define UIP_CONF_MAX_ROUTES 10 -*/ -/* Reduce 802.15.4 frame queue to save RAM. */ -/* -#undef QUEUEBUF_CONF_NUM -#define QUEUEBUF_CONF_NUM 4 -*/ - -/* -#undef SICSLOWPAN_CONF_FRAG -#define SICSLOWPAN_CONF_FRAG 1 -*/ #endif /* PROJECT_ERBIUM_CONF_H_ */ diff --git a/examples/osd/servo-sensor/run.sh b/examples/osd/servo-sensor/run.sh index 2efd2cf48..5d5cbbbb4 100755 --- a/examples/osd/servo-sensor/run.sh +++ b/examples/osd/servo-sensor/run.sh @@ -1,8 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size -C --mcu=MCU=atmega128rfa1 er-example-server.osd-merkur -avr-objcopy -j .text -j .data -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.eep +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/servo-sensor/server-client.csc b/examples/osd/servo-sensor/server-client.csc index 8c45fdf02..02aefd730 100644 --- a/examples/osd/servo-sensor/server-client.csc +++ b/examples/osd/servo-sensor/server-client.csc @@ -1,227 +1,227 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - client - Erbium Client - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c - make er-example-client.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 46.57186415376375 - 40.35946215910942 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - - se.sics.cooja.interfaces.Position - 18.638049428485125 - 47.55034515769599 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 3 - - client - - - - se.sics.cooja.plugins.SimControl - 259 - 0 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 - - 300 - 2 - 178 - 261 - 1 - - - se.sics.cooja.plugins.LogListener - - - - - 762 - 3 - 491 - 2 - 182 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 4 - 74 - 578 - 18 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - 2 - - - - - 125 - 25.49079397896416 - - 1624 - 5 - 252 - 6 - 712 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 2 - - Serial port - 0,0 - - 853 - 1 - 491 - 765 - 182 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + REST with RPL router + -2147483648 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + client + Erbium Client + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c + make er-example-client.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + se.sics.cooja.interfaces.Position + 46.57186415376375 + 40.35946215910942 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + + se.sics.cooja.interfaces.Position + 18.638049428485125 + 47.55034515769599 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 3 + + client + + + + se.sics.cooja.plugins.SimControl + 259 + 0 + 179 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.AttributeVisualizerSkin + se.sics.cooja.plugins.skins.LEDVisualizerSkin + se.sics.cooja.plugins.skins.AddressVisualizerSkin + 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 + + 300 + 2 + 178 + 261 + 1 + + + se.sics.cooja.plugins.LogListener + + + + + 762 + 3 + 491 + 2 + 182 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 4 + 74 + 578 + 18 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + 2 + + + + + 125 + 25.49079397896416 + + 1624 + 5 + 252 + 6 + 712 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 2 + + Serial port + 0,0 + + 853 + 1 + 491 + 765 + 182 + + + diff --git a/examples/osd/servo-sensor/server-only.csc b/examples/osd/servo-sensor/server-only.csc index d5eee34d6..1b0fe28bf 100644 --- a/examples/osd/servo-sensor/server-only.csc +++ b/examples/osd/servo-sensor/server-only.csc @@ -1,189 +1,189 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 35.100895239785295 - 39.70574552287428 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - se.sics.cooja.plugins.SimControl - 259 - 5 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 - - 300 - 4 - 175 - 263 - 3 - - - se.sics.cooja.plugins.LogListener - - - - - 560 - 1 - 326 - 1 - 293 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 2 - 74 - 39 - 199 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - - - - - 125 - 25.49079397896416 - - 1624 - 3 - 252 - 4 - 622 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 1 - - Serial port - 0,0 - - 702 - 0 - 646 - 564 - 2 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + REST with RPL router + -2147483648 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + se.sics.cooja.interfaces.Position + 35.100895239785295 + 39.70574552287428 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + se.sics.cooja.plugins.SimControl + 259 + 5 + 179 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.AttributeVisualizerSkin + se.sics.cooja.plugins.skins.LEDVisualizerSkin + se.sics.cooja.plugins.skins.AddressVisualizerSkin + 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 + + 300 + 4 + 175 + 263 + 3 + + + se.sics.cooja.plugins.LogListener + + + + + 560 + 1 + 326 + 1 + 293 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 2 + 74 + 39 + 199 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + + + + + 125 + 25.49079397896416 + + 1624 + 3 + 252 + 4 + 622 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 702 + 0 + 646 + 564 + 2 + + + diff --git a/examples/osd/slip-radio/Makefile b/examples/osd/slip-radio/Makefile index f7a755961..d6bb0802c 100644 --- a/examples/osd/slip-radio/Makefile +++ b/examples/osd/slip-radio/Makefile @@ -1,12 +1,12 @@ -CONTIKI_PROJECT=slip-radio -all: $(CONTIKI_PROJECT) +EXE=slip-radio +all: $(EXE) APPS = slip-cmd -CONTIKI=../../.. +ifeq ($(TARGET),) + -include Makefile.target +endif -WITH_UIP6=1 -UIP_CONF_IPV6=1 -UIP_CONF_RPL=0 +CONTIKI=../../.. #linker optimizations SMALL=1 @@ -16,5 +16,20 @@ PROJECT_SOURCEFILES += slip-net.c no-framer.c ifeq ($(TARGET),sky) PROJECT_SOURCEFILES += slip-radio-cc2420.c slip-radio-sky-sensors.c endif +ifeq ($(TARGET),nooliberry) + PROJECT_SOURCEFILES += slip-radio-rf230.c +endif +ifeq ($(TARGET),econotag) + PROJECT_SOURCEFILES += slip-radio-mc1322x.c +endif +CONTIKI_WITH_RPL = 0 +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/slip-radio/README.md b/examples/osd/slip-radio/README.md new file mode 100644 index 000000000..5e3e0a5f6 --- /dev/null +++ b/examples/osd/slip-radio/README.md @@ -0,0 +1,6 @@ +This project is intended to run on a mode that is connected to a native host system +by SLIP. The SLIP is really SERIAL LINE 15.4, as this just turns the mote into a smart +radio, running the RPL and 6lowpan stack on the Host. This goes with native-border-router. + + + diff --git a/examples/osd/slip-radio/flash.sh b/examples/osd/slip-radio/flash.sh index 633f3f434..e82962073 100755 --- a/examples/osd/slip-radio/flash.sh +++ b/examples/osd/slip-radio/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:slip-radio.osd-merkur.hex:a -U eeprom:w:slip-radio.osd-merkur.eep:a +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/slip-radio/no-framer.c b/examples/osd/slip-radio/no-framer.c index d0935db1f..69f4b7e98 100644 --- a/examples/osd/slip-radio/no-framer.c +++ b/examples/osd/slip-radio/no-framer.c @@ -40,7 +40,7 @@ #include "net/packetbuf.h" #include -#define DEBUG 2 +#define DEBUG 0 #if DEBUG #include @@ -76,6 +76,13 @@ is_broadcast_addr(uint8_t mode, uint8_t *addr) } /*---------------------------------------------------------------------------*/ static int +hdr_length(void) +{ + /* never adds any header */ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int create(void) { /* nothing extra... */ @@ -90,14 +97,19 @@ parse(void) len = packetbuf_datalen(); if(frame802154_parse(packetbuf_dataptr(), len, &frame)) { if(frame.fcf.dest_addr_mode) { + if(frame.dest_pid != mac_src_pan_id && + frame.dest_pid != FRAME802154_BROADCASTPANDID) { + /* Packet to another PAN */ + PRINTF("15.4: for another pan %u\n", frame.dest_pid); + return 0; + } if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { - packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (rimeaddr_t *)&frame.dest_addr); + packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr); } } - packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (rimeaddr_t *)&frame.src_addr); + packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr); packetbuf_set_attr(PACKETBUF_ATTR_PENDING, frame.fcf.frame_pending); - /* packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, frame.fcf.ack_required);*/ - packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, frame.seq); + packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, frame.seq); PRINTF("15.4-IN: %2X", frame.fcf.frame_type); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); @@ -110,5 +122,7 @@ parse(void) } /*---------------------------------------------------------------------------*/ const struct framer no_framer = { - create, parse + hdr_length, + create, + parse }; diff --git a/examples/osd/slip-radio/project-conf.h b/examples/osd/slip-radio/project-conf.h index 3555f527b..66cd61cbc 100644 --- a/examples/osd/slip-radio/project-conf.h +++ b/examples/osd/slip-radio/project-conf.h @@ -27,8 +27,8 @@ * SUCH DAMAGE. */ -#ifndef __PROJECT_CONF_H__ -#define __PROJECT_CONF_H__ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ #undef QUEUEBUF_CONF_NUM #define QUEUEBUF_CONF_NUM 4 @@ -39,15 +39,17 @@ #undef UIP_CONF_ROUTER #define UIP_CONF_ROUTER 0 -#undef UIP_CONF_IPV6_RPL -#define UIP_CONF_IPV6_RPL 0 - #define CMD_CONF_OUTPUT slip_radio_cmd_output /* add the cmd_handler_cc2420 + some sensors if TARGET_SKY */ #ifdef CONTIKI_TARGET_SKY #define CMD_CONF_HANDLERS slip_radio_cmd_handler,cmd_handler_cc2420 #define SLIP_RADIO_CONF_SENSORS slip_radio_sky_sensors +/* add the cmd_handler_rf230 if TARGET_NOOLIBERRY. Other RF230 platforms can be added */ +#elif CONTIKI_TARGET_NOOLIBERRY +#define CMD_CONF_HANDLERS slip_radio_cmd_handler,cmd_handler_rf230 +#elif CONTIKI_TARGET_ECONOTAG +#define CMD_CONF_HANDLERS slip_radio_cmd_handler,cmd_handler_mc1322x #else #define CMD_CONF_HANDLERS slip_radio_cmd_handler #endif @@ -55,7 +57,7 @@ /* configuration for the slipradio/network driver */ #undef NETSTACK_CONF_MAC -#define NETSTACK_CONF_MAC csma_driver +#define NETSTACK_CONF_MAC nullmac_driver #undef NETSTACK_CONF_RDC /* #define NETSTACK_CONF_RDC nullrdc_noframer_driver */ @@ -73,4 +75,4 @@ #undef UART1_CONF_RX_WITH_DMA #define UART1_CONF_RX_WITH_DMA 1 -#endif /* __PROJECT_CONF_H__ */ +#endif /* PROJECT_CONF_H_ */ diff --git a/examples/osd/slip-radio/run.sh b/examples/osd/slip-radio/run.sh index 94e36daac..5d5cbbbb4 100755 --- a/examples/osd/slip-radio/run.sh +++ b/examples/osd/slip-radio/run.sh @@ -1,8 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size slip-radio.osd-merkur -avr-objcopy -j .text -j .data -O ihex slip-radio.osd-merkur slip-radio.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex slip-radio.osd-merkur slip-radio.osd-merkur.eep +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/slip-radio/slip-net.c b/examples/osd/slip-radio/slip-net.c index 68b2aebc0..1482aefed 100644 --- a/examples/osd/slip-radio/slip-net.c +++ b/examples/osd/slip-radio/slip-net.c @@ -29,7 +29,7 @@ #include "contiki.h" #include "net/netstack.h" -#include "net/uip.h" +#include "net/ip/uip.h" #include "net/packetbuf.h" #include "dev/slip.h" #include diff --git a/examples/osd/slip-radio/slip-radio-cc2420.c b/examples/osd/slip-radio/slip-radio-cc2420.c index 7d7676e1f..f49e3c4e9 100644 --- a/examples/osd/slip-radio/slip-radio-cc2420.c +++ b/examples/osd/slip-radio/slip-radio-cc2420.c @@ -32,7 +32,7 @@ */ #include "contiki.h" -#include "dev/cc2420.h" +#include "cc2420.h" #include "cmd.h" #include diff --git a/examples/osd/slip-radio/slip-radio-mc1322x.c b/examples/osd/slip-radio/slip-radio-mc1322x.c new file mode 100644 index 000000000..da518b11c --- /dev/null +++ b/examples/osd/slip-radio/slip-radio-mc1322x.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * Sets up some commands for the MC1322x radio chip. + */ + +#include "contiki.h" +#include "mc1322x.h" +#include "cmd.h" +#include + +int +cmd_handler_mc1322x(const uint8_t *data, int len) +{ + if(data[0] == '!') { + if(data[1] == 'C') { + printf("mc1322x_cmd: setting channel: %d\n", data[2]); + set_channel(data[2]-11); + return 1; + } + } else if(data[0] == '?') { + if(data[1] == 'C') { + uint8_t buf[4]; + printf("mc1322x_cmd: getting channel: %d\n", data[2]); + buf[0] = '!'; + buf[1] = 'C'; + //Not implemented in MACA driver + buf[2] = 0; + cmd_send(buf, 3); + return 1; + } + } + return 0; +} diff --git a/examples/osd/slip-radio/slip-radio-rf230.c b/examples/osd/slip-radio/slip-radio-rf230.c new file mode 100644 index 000000000..67c3ecc33 --- /dev/null +++ b/examples/osd/slip-radio/slip-radio-rf230.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * Sets up some commands for the RF230 radio. + */ + +#include "contiki.h" +#include "cmd.h" + +#include "radio/rf230/radio.h" +#include "radio/rf230bb/rf230bb.h" + + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#define PRINTSHORT(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTF(...) +#define PRINTSHORT(...) +#endif + +int +cmd_handler_rf230(const uint8_t *data, int len) +{ + if(data[0] == '!') { + if(data[1] == 'C') { + PRINTF("CMD: Setting channel: %d\n", data[2]); + rf230_set_channel(data[2]); + return 1; + } + } else if(data[0] == '?') { + if(data[1] == 'C') { + uint8_t buf[4]; + PRINTF("CMD: Getting channel: %d\n", data[2]); + buf[0] = '!'; + buf[1] = 'C'; + buf[2] = rf230_get_channel(); + cmd_send(buf, 3); + return 1; + } + } + return 0; +} diff --git a/examples/osd/slip-radio/slip-radio-sky-sensors.c b/examples/osd/slip-radio/slip-radio-sky-sensors.c index a88d7b9d3..9cf238741 100644 --- a/examples/osd/slip-radio/slip-radio-sky-sensors.c +++ b/examples/osd/slip-radio/slip-radio-sky-sensors.c @@ -29,7 +29,7 @@ #include "contiki.h" #include "lib/sensors.h" -#include "dev/sht11-sensor.h" +#include "dev/sht11/sht11-sensor.h" #include "slip-radio.h" #include "cmd.h" #include diff --git a/examples/osd/slip-radio/slip-radio.c b/examples/osd/slip-radio/slip-radio.c index f8baec682..b20e559ec 100644 --- a/examples/osd/slip-radio/slip-radio.c +++ b/examples/osd/slip-radio/slip-radio.c @@ -33,29 +33,21 @@ * \author * Niclas Finne * Joakim Eriksson - * Andreas Reder */ #include "contiki.h" -#include "net/uip.h" -#include "net/uip-ds6.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" #include "dev/slip.h" #include #include "net/netstack.h" #include "net/packetbuf.h" #define DEBUG DEBUG_NONE -#include "net/uip-debug.h" +#include "net/ip/uip-debug.h" #include "cmd.h" #include "slip-radio.h" #include "packetutils.h" -#include -#include "watchdog.h" -#include "params.h" - -extern uint16_t eemem_panid EEMEM; -extern uint8_t eemem_channel[] EEMEM; - #ifdef SLIP_RADIO_CONF_SENSORS extern const struct slip_radio_sensors SLIP_RADIO_CONF_SENSORS; #endif @@ -67,7 +59,15 @@ uint8_t packet_ids[16]; int packet_pos; static int slip_radio_cmd_handler(const uint8_t *data, int len); + +#if CONTIKI_TARGET_NOOLIBERRY +int cmd_handler_rf230(const uint8_t *data, int len); +#elif CONTIKI_TARGET_ECONOTAG +int cmd_handler_mc1322x(const uint8_t *data, int len); +#else /* Leave CC2420 as default */ int cmd_handler_cc2420(const uint8_t *data, int len); +#endif /* CONTIKI_TARGET */ + /*---------------------------------------------------------------------------*/ #ifdef CMD_CONF_HANDLERS CMD_HANDLERS(CMD_CONF_HANDLERS); @@ -99,8 +99,6 @@ static int slip_radio_cmd_handler(const uint8_t *data, int len) { int i; - uint16_t panid; - if(data[0] == '!') { /* should send out stuff to the radio - ignore it as IP */ /* --- s e n d --- */ @@ -127,7 +125,7 @@ slip_radio_cmd_handler(const uint8_t *data, int len) /* parse frame before sending to get addresses, etc. */ no_framer.parse(); - NETSTACK_MAC.send(packet_sent, &packet_ids[packet_pos]); + NETSTACK_LLSEC.send(packet_sent, &packet_ids[packet_pos]); packet_pos++; if(packet_pos >= sizeof(packet_ids)) { @@ -148,14 +146,7 @@ slip_radio_cmd_handler(const uint8_t *data, int len) uip_len = 10; cmd_send(uip_buf, uip_len); return 1; - } else if( data[1] == 'P'){ - panid = (data[2] << 8) + data[3]; - printf("slip-radio: received change panid command, new panid %u\n", panid); - cli(); - eeprom_write_word(&eemem_panid, panid); - sei(); - //watchdog_reboot(); - } + } } return 0; } @@ -171,7 +162,7 @@ slip_input_callback(void) { PRINTF("SR-SIN: %u '%c%c'\n", uip_len, uip_buf[0], uip_buf[1]); cmd_input(uip_buf, uip_len); - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ static void diff --git a/examples/osd/slip-radio/slip-radio.h b/examples/osd/slip-radio/slip-radio.h index 8aad5da20..a80e81c4f 100644 --- a/examples/osd/slip-radio/slip-radio.h +++ b/examples/osd/slip-radio/slip-radio.h @@ -28,8 +28,8 @@ * */ -#ifndef __SLIP_RADIO_H__ -#define __SLIP_RADIO_H__ +#ifndef SLIP_RADIO_H_ +#define SLIP_RADIO_H_ struct slip_radio_sensors { /** Initialize the driver */ @@ -38,4 +38,4 @@ struct slip_radio_sensors { void (* send)(void); }; -#endif /* __SLIP_RADIO_H__ */ +#endif /* SLIP_RADIO_H_ */ diff --git a/examples/osd/triggerbaord/Makefile b/examples/osd/triggerbaord/Makefile new file mode 100644 index 000000000..5a017eac0 --- /dev/null +++ b/examples/osd/triggerbaord/Makefile @@ -0,0 +1,70 @@ +# Set this to the name of your sketch (without extension .pde) +SKETCH=sketch +EXE=arduino-example + +all: $(EXE) + +CONTIKI=../../.. + +# Contiki IPv6 configuration +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +PROJECT_SOURCEFILES += ${SKETCH}.cpp + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR) -name '*.c') \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) + +# variable for Makefile.include +ifneq ($(TARGET), minimal-net) +CFLAGS += -DUIP_CONF_IPV6_RPL=1 +else +# minimal-net does not support RPL under Linux and is mostly used to test CoAP only +${info INFO: compiling without RPL} +CFLAGS += -DUIP_CONF_IPV6_RPL=0 +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=640 +endif + +# linker optimizations +SMALL=1 + + +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += arduino + +include $(CONTIKI)/Makefile.include +include $(CONTIKI)/apps/arduino/Makefile.include + +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + (cd $(CONTIKI)/tools && $(MAKE) tunslip6) + +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + +connect-minimal: + sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +flash: $(EXE).$(TARGET).u $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/triggerbaord/README.md b/examples/osd/triggerbaord/README.md new file mode 100644 index 000000000..e1490ed05 --- /dev/null +++ b/examples/osd/triggerbaord/README.md @@ -0,0 +1,11 @@ +Arduino compatibility example +============================= + +This example shows that it is now possible to re-use arduino sketches in +Contiki. This example documents the necessary magic. Arduino specifies +two routines, `setup` and `loop`. Before `setup` is called, the +framework initializes hardware. In original Arduino, all this is done in +a `main` function (in C). For contiki we define a process that does the +same. + +See the documentation file in apps/contiki-compat/README.md diff --git a/examples/osd/triggerbaord/arduino-example.c b/examples/osd/triggerbaord/arduino-example.c new file mode 100644 index 000000000..ea74dd8b8 --- /dev/null +++ b/examples/osd/triggerbaord/arduino-example.c @@ -0,0 +1,2 @@ +#include +AUTOSTART_PROCESSES(&arduino_sketch); diff --git a/examples/osd/triggerbaord/flash.sh b/examples/osd/triggerbaord/flash.sh new file mode 100755 index 000000000..e82962073 --- /dev/null +++ b/examples/osd/triggerbaord/flash.sh @@ -0,0 +1,2 @@ +#!/bin/bash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/6lowpan-tk/project-conf.h b/examples/osd/triggerbaord/project-conf.h similarity index 63% rename from examples/osd/6lowpan-tk/project-conf.h rename to examples/osd/triggerbaord/project-conf.h index 106789103..510c66786 100644 --- a/examples/osd/6lowpan-tk/project-conf.h +++ b/examples/osd/triggerbaord/project-conf.h @@ -29,44 +29,63 @@ * */ -#ifndef __PROJECT_RPL_WEB_CONF_H__ -#define __PROJECT_RPL_WEB_CONF_H__ +#ifndef PROJECT_RPL_WEB_CONF_H_ +#define PROJECT_RPL_WEB_CONF_H_ #define PLATFORM_HAS_LEDS 1 -//#define PLATFORM_HAS_BUTTON 1 -//#define PLATFORM_HAS_TEMPERATURE 1 +#define PLATFORM_HAS_BUTTON 1 #define PLATFORM_HAS_BATTERY 1 -#define SICSLOWPAN_CONF_FRAG 1 +#define LOOP_INTERVAL (10 * CLOCK_SECOND) + +/* For Debug: Dont allow MCU sleeping between channel checks */ +//#undef RDC_CONF_MCU_SLEEP +//#define RDC_CONF_MCU_SLEEP 0 + +/* Save energy */ +//#define RDC_CONF_PT_YIELD_OFF /* Disabling RDC for demo purposes. Core updates often require more memory. */ /* For projects, optimize memory and enable RDC again. */ //#undef NETSTACK_CONF_RDC //#define NETSTACK_CONF_RDC nullrdc_driver -/* Save some memory for the sky platform. */ -#undef UIP_CONF_DS6_NBR_NBU -#define UIP_CONF_DS6_NBR_NBU 10 -#undef UIP_CONF_DS6_ROUTE_NBU -#define UIP_CONF_DS6_ROUTE_NBU 10 - -/* Increase rpl-border-router IP-buffer when using 128. */ -#ifndef REST_MAX_CHUNK_SIZE +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE #define REST_MAX_CHUNK_SIZE 64 -#endif + +/* Estimate your header size, especially when using Proxy-Uri. */ +/* +#undef COAP_MAX_HEADER_SIZE +#define COAP_MAX_HEADER_SIZE 70 +*/ + +/* The IP buffer size must fit all other hops, in particular the border router. */ + +#undef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 256 + /* Multiplies with chunk size, be aware of memory constraints. */ -#ifndef COAP_MAX_OPEN_TRANSACTIONS -#define COAP_MAX_OPEN_TRANSACTIONS 2 -#endif +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 -/* Must be <= open transaction number. */ -#ifndef COAP_MAX_OBSERVERS -#define COAP_MAX_OBSERVERS COAP_MAX_OPEN_TRANSACTIONS-1 -#endif +/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* +#undef COAP_MAX_OBSERVERS +#define COAP_MAX_OBSERVERS 2 +*/ -/* Reduce 802.15.4 frame queue to save RAM. */ -#undef QUEUEBUF_CONF_NUM -#define QUEUEBUF_CONF_NUM 4 +/* Filtering .well-known/core per query can be disabled to save space. */ +/* +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +*/ -#endif /* __PROJECT_RPL_WEB_CONF_H__ */ + + + + + + +#endif /* PROJECT_RPL_WEB_CONF_H_ */ diff --git a/examples/osd/triggerbaord/resources/res-event.c b/examples/osd/triggerbaord/resources/res-event.c new file mode 100644 index 000000000..7524d2ad2 --- /dev/null +++ b/examples/osd/triggerbaord/resources/res-event.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_event_handler(void); + +/* + * Example for an event resource. + * Additionally takes a period parameter that defines the interval to call [name]_periodic_handler(). + * A default post_handler takes care of subscriptions and manages a list of subscribers to notify. + */ +EVENT_RESOURCE(res_event, + "title=\"Event demo\";obs", + res_get_handler, + NULL, + NULL, + NULL, + res_event_handler); + +/* + * Use local resource state that is accessed by res_get_handler() and altered by res_event_handler() or PUT or POST. + */ +static int32_t event_counter = 0; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "EVENT %lu", event_counter)); + + /* A post_handler that handles subscriptions/observing will be called for periodic resources by the framework. */ +} +/* + * Additionally, res_event_handler must be implemented for each EVENT_RESOURCE. + * It is called through .trigger(), usually from the server process. + */ +static void +res_event_handler(void) +{ + /* Do the update triggered by the event here, e.g., sampling a sensor. */ + ++event_counter; + + /* Usually a condition is defined under with subscribers are notified, e.g., event was above a threshold. */ + if(1) { + PRINTF("TICK %u for /%s\n", event_counter, res_event.url); + + /* Notify the registered observers which will trigger the res_get_handler to create the response. */ + REST.notify_subscribers(&res_event); + } +} diff --git a/examples/osd/triggerbaord/resources/res-led.c b/examples/osd/triggerbaord/resources/res-led.c new file mode 100644 index 000000000..fb0fa138f --- /dev/null +++ b/examples/osd/triggerbaord/resources/res-led.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Door resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_led, + "title=\"LED: , POST/PUT mode=on|off\";rt=\"Control\"", + res_get_handler, + res_post_put_handler, + res_post_put_handler, + NULL); + +extern uint8_t led_pin; +extern uint8_t led_status; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", led_status); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'led':%d}", led_status); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} + +static void +res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + size_t len = 0; + const char *mode = NULL; + int success = 1; + + if(success && (len = REST.get_post_variable(request, "mode", &mode))) { + if(strncmp(mode, "on", len) == 0) { + digitalWrite(led_pin, LOW); + led_status=1; + } else if(strncmp(mode, "off", len) == 0) { + digitalWrite(led_pin, HIGH); + led_status=0; + } else { + success = 0; + } + } else { + success = 0; + } if(!success) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} diff --git a/examples/osd/triggerbaord/resources/res-separate.c b/examples/osd/triggerbaord/resources/res-separate.c new file mode 100644 index 000000000..bb2248c92 --- /dev/null +++ b/examples/osd/triggerbaord/resources/res-separate.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap-separate.h" +#include "er-coap-transactions.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_resume_handler(void); + +SEPARATE_RESOURCE(res_separate, + "title=\"Separate demo\"", + res_get_handler, + NULL, + NULL, + NULL, + res_resume_handler); + +/* A structure to store the information required for the separate handler */ +typedef struct application_separate_store { + + /* Provided by Erbium to store generic request information such as remote address and token. */ + coap_separate_t request_metadata; + + /* Add fields for addition information to be stored for finalizing, e.g.: */ + char buffer[16]; +} application_separate_store_t; + +#define COAP_MAX_OPEN_SEPARATE 2 + +static uint8_t separate_active = 0; +static application_separate_store_t separate_store[COAP_MAX_OPEN_SEPARATE]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* + * Example allows only one open separate response. + * For multiple, the application must manage the list of stores. + */ + if(separate_active >= COAP_MAX_OPEN_SEPARATE) { + coap_separate_reject(); + } else { + ++separate_active; + + /* Take over and skip response by engine. */ + coap_separate_accept(request, &separate_store->request_metadata); + /* Be aware to respect the Block2 option, which is also stored in the coap_separate_t. */ + + /* + * At the moment, only the minimal information is stored in the store (client address, port, token, MID, type, and Block2). + * Extend the store, if the application requires additional information from this handler. + * buffer is an example field for custom information. + */ + snprintf(separate_store->buffer, sizeof(separate_store->buffer), "StoredInfo"); + } +} +static void +res_resume_handler() +{ + if(separate_active) { + coap_transaction_t *transaction = NULL; + if((transaction = coap_new_transaction(separate_store->request_metadata.mid, &separate_store->request_metadata.addr, separate_store->request_metadata.port))) { + coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */ + + /* Restore the request information for the response. */ + coap_separate_resume(response, &separate_store->request_metadata, REST.status.OK); + + coap_set_payload(response, separate_store->buffer, strlen(separate_store->buffer)); + + /* + * Be aware to respect the Block2 option, which is also stored in the coap_separate_t. + * As it is a critical option, this example resource pretends to handle it for compliance. + */ + coap_set_header_block2(response, separate_store->request_metadata.block2_num, 0, separate_store->request_metadata.block2_size); + + /* Warning: No check for serialization error. */ + transaction->packet_len = coap_serialize_message(response, transaction->packet); + coap_send_transaction(transaction); + /* The engine will clear the transaction (right after send for NON, after acked for CON). */ + + /* FIXME there could me more! */ + separate_active = 0; + } else { + /* + * Set timer for retry, send error message, ... + * The example simply waits for another button press. + */ + } + } /* if (separate_active) */ +} diff --git a/examples/osd/triggerbaord/run.sh b/examples/osd/triggerbaord/run.sh new file mode 100755 index 000000000..5d5cbbbb4 --- /dev/null +++ b/examples/osd/triggerbaord/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/triggerbaord/sketch.pde b/examples/osd/triggerbaord/sketch.pde new file mode 100644 index 000000000..73aeb00f7 --- /dev/null +++ b/examples/osd/triggerbaord/sketch.pde @@ -0,0 +1,55 @@ +/* + * Sample arduino sketch using contiki features. + * We turn the LED off + * We allow read the moisture sensor + * Unfortunately sleeping for long times in loop() isn't currently + * possible, something turns off the CPU (including PWM outputs) if a + * Proto-Thread is taking too long. We need to find out how to sleep in + * a Contiki-compatible way. + * Note that for a normal arduino sketch you won't have to include any + * of the contiki-specific files here, the sketch should just work. + */ + +extern "C" { +#include "arduino-process.h" +#include "rest-engine.h" +#include "net/netstack.h" +#include "dev/button-sensor.h" + + + +extern resource_t + res_led, + res_battery, + res_cputemp, + res_event, + res_separate, + res_server; + +uint8_t led_pin=4; +uint8_t led_status; +} + +void setup (void) +{ + // switch off the led + pinMode(led_pin, OUTPUT); + digitalWrite(led_pin, HIGH); + led_status=0; + // sensors + SENSORS_ACTIVATE(button_sensor); + // init coap resourcen + rest_init_engine (); + rest_activate_resource (&res_led, "s/led"); + rest_activate_resource (&res_battery, "s/battery"); + rest_activate_resource (&res_cputemp, "s/cputemp"); + rest_activate_resource(&res_event, "s/button"); +// rest_activate_resource (&res_battery, "p/server"); + +// NETSTACK_MAC.off(1); +} + +void loop (void) +{ + +} diff --git a/examples/osd/wallclock-time/Makefile b/examples/osd/wallclock-time/Makefile index 5bbc98a82..46d8e4625 100644 --- a/examples/osd/wallclock-time/Makefile +++ b/examples/osd/wallclock-time/Makefile @@ -1,99 +1,48 @@ -all: er-example-server \ - er-example-server.osd-merkur.hex er-example-server.osd-merkur.eep -# use this target explicitly if requried: er-plugtest-server +EXE=wallclock -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 - -# for some platforms -UIP_CONF_IPV6=1 -# IPv6 make config disappeared completely -CFLAGS += -DUIP_CONF_IPV6=1 +all: $(EXE) CONTIKI=../../.. + CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" -PROJECT_SOURCEFILES += +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) -# variable for Makefile.include -ifneq ($(TARGET), minimal-net) -CFLAGS += -DUIP_CONF_IPV6_RPL=1 -else -# minimal-net does not support RPL under Linux and is mostly used to test CoAP only -${info INFO: compiling without RPL} -CFLAGS += -DUIP_CONF_IPV6_RPL=0 -CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" -${info INFO: compiling with large buffers} -CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048 -CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 -CFLAGS += -DCOAP_MAX_HEADER_SIZE=640 -endif +PROJECTDIRS += $(REST_RESOURCES_DIR) $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) # linker optimizations SMALL=1 -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif - -APPS += erbium time json json-resource +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += json json-resource time +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include -er-example-server.osd-merkur.hex: er-example-server.osd-merkur - avr-objcopy -j .text -j .data -O ihex er-example-server.osd-merkur \ - er-example-server.osd-merkur.hex - -er-example-server.osd-merkur.eep: er-example-server.osd-merkur - avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O ihex \ - er-example-server.osd-merkur er-example-server.osd-merkur.eep - -flash: er-example-server.osd-merkur.hex er-example-server.osd-merkur.eep - avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U \ - flash:w:er-example-server.osd-merkur.hex:a -U \ - eeprom:w:er-example-server.osd-merkur.eep:a - -.PHONY: flash - -$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c (cd $(CONTIKI)/tools && $(MAKE) tunslip6) connect-router: $(CONTIKI)/tools/tunslip6 sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 -connect-router-cooja: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 -p 60001 aaaa::1/64 connect-minimal: sudo ip address add fdfd::1/64 dev tap0 + +avr-size: $(EXE).$(TARGET).sz + +# At some point we may want to include the eeprom file +flash: $(EXE).$(TARGET).u # $(EXE).$(TARGET).eu + +.PHONY: flash avr-size +.PRECIOUS: $(EXE).$(TARGET).hex $(EXE).$(TARGET).eep diff --git a/examples/osd/wallclock-time/er-example-server.c b/examples/osd/wallclock-time/er-example-server.c deleted file mode 100644 index 636519c02..000000000 --- a/examples/osd/wallclock-time/er-example-server.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (C) 2011, Matthias Kovatsch and other contributors. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Erbium (Er) Wallclock REST Engine example (with CoAP-specific code) - * \author - * Matthias Kovatsch - * Ralf Schlatterbeck - */ - -#include -#include -#include -#include "contiki.h" -#include "contiki-net.h" -#include "time.h" -#include "time_resource.h" -#include "jsonparse.h" - -/* Define which resources to include to meet memory constraints. */ -#define REST_RES_INFO 1 -#define REST_RES_LEDS 1 -#define REST_RES_TOGGLE 0 -#define REST_RES_BATTERY 1 - -#include "erbium.h" - -#if defined (PLATFORM_HAS_BUTTON) -#include "dev/button-sensor.h" -#endif -#if defined (PLATFORM_HAS_LEDS) -#include "dev/leds.h" -#endif -#if defined (PLATFORM_HAS_BATTERY) -#include "dev/battery-sensor.h" -#endif - - -/* For CoAP-specific example: not required for normal RESTful Web service. */ -#if WITH_COAP == 3 -#include "er-coap-03.h" -#elif WITH_COAP == 7 -#include "er-coap-07.h" -#elif WITH_COAP == 12 -#include "er-coap-12.h" -#elif WITH_COAP == 13 -#include "er-coap-13.h" -#else -#warning "Erbium example without CoAP-specifc functionality" -#endif /* CoAP-specific example */ - -#define DEBUG 1 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - -/******************************************************************************/ - -#if REST_RES_INFO -/* - * Resources are defined by the RESOURCE macro. - * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). - */ -RESOURCE(info, METHOD_GET, "info", "title=\"Info\";rt=\"text\""); - -/* - * A handler function named [resource name]_handler must be implemented for each RESOURCE. - * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore - * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. - * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. - */ -void -info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - char message[100]; - int index = 0; - int length = 0; /* |<-------->| */ - - /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ - // jSON Format - index += sprintf(message + index,"{\n \"Version\" : \"V1.0pre1\",\n"); - index += sprintf(message + index," \"name\" : \"Wallclock-time\"\n"); - index += sprintf(message + index,"}\n"); - - length = strlen(message); - memcpy(buffer, message,length ); - - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - REST.set_response_payload(response, buffer, length); -} -#endif - -/******************************************************************************/ -#if defined (PLATFORM_HAS_LEDS) -/******************************************************************************/ -#if REST_RES_LEDS -/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -RESOURCE(leds, METHOD_POST | METHOD_PUT , "actuators/leds", "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\""); - -void -leds_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - size_t len = 0; - const char *color = NULL; - const char *mode = NULL; - uint8_t led = 0; - int success = 1; - - if ((len=REST.get_query_variable(request, "color", &color))) { - PRINTF("color %.*s\n", len, color); - - if (strncmp(color, "r", len)==0) { - led = LEDS_RED; - } else if(strncmp(color,"g", len)==0) { - led = LEDS_GREEN; - } else if (strncmp(color,"b", len)==0) { - led = LEDS_BLUE; - } else { - success = 0; - } - } else { - success = 0; - } - - if (success && (len=REST.get_post_variable(request, "mode", &mode))) { - PRINTF("mode %s\n", mode); - - if (strncmp(mode, "on", len)==0) { - leds_on(led); - } else if (strncmp(mode, "off", len)==0) { - leds_off(led); - } else { - success = 0; - } - } else { - success = 0; - } - - if (!success) { - REST.set_response_status(response, REST.status.BAD_REQUEST); - } -} -#endif - -/******************************************************************************/ -#if REST_RES_TOGGLE -/* A simple actuator example. Toggles the red led */ -RESOURCE(toggle, METHOD_GET | METHOD_PUT | METHOD_POST, "actuators/toggle", "title=\"Red LED\";rt=\"Control\""); -void -toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - leds_toggle(LEDS_RED); -} -#endif -#endif /* PLATFORM_HAS_LEDS */ - -/******************************************************************************/ - -/******************************************************************************/ -/******************************************************************************/ -#if REST_RES_BATTERY && defined (PLATFORM_HAS_BATTERY) -/* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(battery, METHOD_GET, "sensors/battery", "title=\"Battery status\";rt=\"battery-mV\""); -void -battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) -{ - int battery = battery_sensor.value(0); - - const uint16_t *accept = NULL; - int num = REST.get_header_accept(request, &accept); - - if ((num==0) || (num && accept[0]==REST.type.TEXT_PLAIN)) - { - REST.set_header_content_type(response, REST.type.TEXT_PLAIN); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", battery); - - REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); - } - else if (num && (accept[0]==REST.type.APPLICATION_JSON)) - { - REST.set_header_content_type(response, REST.type.APPLICATION_JSON); - snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'battery':%d}", battery); - - REST.set_response_payload(response, buffer, strlen((char *)buffer)); - } - else - { - REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); - const char *msg = "Supporting content-types text/plain and application/json"; - REST.set_response_payload(response, msg, strlen(msg)); - } -} -#endif /* PLATFORM_HAS_BATTERY */ -/******************************************************************************/ - -void -hw_init() -{ -#if defined (PLATFORM_HAS_LEDS) - leds_off(LEDS_RED); -#endif -} - -PROCESS(rest_server_example, "Erbium Example Server"); - -AUTOSTART_PROCESSES(&rest_server_example, &sensors_process); - -PROCESS_THREAD(rest_server_example, ev, data) -{ - PROCESS_BEGIN(); - PRINTF("Starting Erbium Example Server\n"); - -#ifdef RF_CHANNEL - PRINTF("RF channel: %u\n", RF_CHANNEL); -#endif -#ifdef IEEE802154_PANID - PRINTF("PAN ID: 0x%04X\n", IEEE802154_PANID); -#endif - - PRINTF("uIP buffer: %u\n", UIP_BUFSIZE); - PRINTF("LL header: %u\n", UIP_LLH_LEN); - PRINTF("IP+UDP header: %u\n", UIP_IPUDPH_LEN); - PRINTF("REST max chunk: %u\n", REST_MAX_CHUNK_SIZE); - -/* if static routes are used rather than RPL */ -#if !UIP_CONF_IPV6_RPL && !defined (CONTIKI_TARGET_MINIMAL_NET) && !defined (CONTIKI_TARGET_NATIVE) - set_global_address(); - configure_routing(); -#endif - - /* Initialize the OSD Hardware. */ - hw_init(); - /* Initialize the REST engine. */ - rest_init_engine(); - - /* Activate the application-specific resources. */ -#if REST_RES_INFO - rest_activate_resource(&resource_info); -#endif -#if defined (PLATFORM_HAS_LEDS) -#if REST_RES_LEDS - rest_activate_resource(&resource_leds); -#endif -#if REST_RES_TOGGLE - rest_activate_resource(&resource_toggle); -#endif -#endif /* PLATFORM_HAS_LEDS */ -#if defined (PLATFORM_HAS_BATTERY) && REST_RES_BATTERY - SENSORS_ACTIVATE(battery_sensor); - rest_activate_resource(&resource_battery); -#endif - rest_activate_resource(&resource_timestamp); - rest_activate_resource(&resource_localtime); - rest_activate_resource(&resource_utc); - - /* Define application-specific events here. */ - while(1) { - PROCESS_WAIT_EVENT(); - } /* while (1) */ - - PROCESS_END(); -} diff --git a/examples/osd/wallclock-time/flash.sh b/examples/osd/wallclock-time/flash.sh index e9cb40bfc..e82962073 100755 --- a/examples/osd/wallclock-time/flash.sh +++ b/examples/osd/wallclock-time/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -make TARGET=osd-merkur flash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/wallclock-time/run.sh b/examples/osd/wallclock-time/run.sh index 295a9ab1d..5d5cbbbb4 100755 --- a/examples/osd/wallclock-time/run.sh +++ b/examples/osd/wallclock-time/run.sh @@ -1,5 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/wallclock-time/wallclock.c b/examples/osd/wallclock-time/wallclock.c new file mode 100644 index 000000000..9e0013b78 --- /dev/null +++ b/examples/osd/wallclock-time/wallclock.c @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2016, Ralf Schlatterbeck and other contributors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Erbium (Er) Wallclock REST Engine example (with CoAP-specific code) + * \author + * Matthias Kovatsch + * Ralf Schlatterbeck + */ + +#include +#include +#include +#include "contiki.h" +#include "contiki-net.h" +#include "er-coap-engine.h" +#include "xtime.h" +#include "cron.h" +#include "time_resource.h" +#include "jsonparse.h" +#include "Arduino.h" + +#if PLATFORM_HAS_BUTTON +#include "dev/button-sensor.h" +#endif + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +#if PLATFORM_HAS_LEDS +#include "dev/leds.h" +extern resource_t res_leds, res_toggle; +#endif + +#if PLATFORM_HAS_BATTERY +#include "dev/battery-sensor.h" +extern resource_t res_battery; +#endif +/* +#if PLATFORM_HAS_RADIO +#include "dev/radio-sensor.h" +extern resource_t res_radio; +#endif +*/ + +//******************************************************************************/ + +void +hw_init () +{ +#if defined (PLATFORM_HAS_LEDS) + leds_off(LEDS_RED); +#endif +} + +PROCESS(rest_server_example, "Erbium Example Server"); + +AUTOSTART_PROCESSES(&rest_server_example, &sensors_process); + +#define LED_PIN 4 +#define LOOP_INTERVAL (30 * CLOCK_SECOND) + +/* + * Set led to on or off, we abuse the given pointer to simply carry the + * on/off flag. + */ +void led_set (void *onoff) +{ + int status = (int)onoff; + digitalWrite (LED_PIN, (status ? 0 : 1)); +} + +PROCESS_THREAD(rest_server_example, ev, data) +{ + static struct etimer loop_periodic_timer; + PROCESS_BEGIN(); + PRINTF("Starting Erbium Example Server\n"); + +#ifdef RF_CHANNEL + PRINTF("RF channel: %u\n", RF_CHANNEL); +#endif +#ifdef IEEE802154_PANID + PRINTF("PAN ID: 0x%04X\n", IEEE802154_PANID); +#endif + + PRINTF("uIP buffer: %u\n", UIP_BUFSIZE); + PRINTF("LL header: %u\n", UIP_LLH_LEN); + PRINTF("IP+UDP header: %u\n", UIP_IPUDPH_LEN); + PRINTF("REST max chunk: %u\n", REST_MAX_CHUNK_SIZE); + +/* if static routes are used rather than RPL */ +#if !UIP_CONF_IPV6_RPL && !defined (CONTIKI_TARGET_MINIMAL_NET) && !defined (CONTIKI_TARGET_NATIVE) + set_global_address (); + configure_routing (); +#endif + + /* Initialize the OSD Hardware. */ + hw_init (); + led_set (0); + /* Initialize the REST engine. */ + rest_init_engine (); + + /* Activate the application-specific resources. */ + rest_activate_resource (&res_leds, "s/leds"); + + +#if defined (PLATFORM_HAS_BATTERY) && REST_RES_BATTERY + SENSORS_ACTIVATE(battery_sensor); + rest_activate_resource (&res_battery, "s/battery"); +#endif + + rest_activate_resource (&res_timestamp, "clock/timestamp"); + rest_activate_resource (&res_timezone, "clock/timezone"); + rest_activate_resource (&res_localtime, "clock/localtime"); + rest_activate_resource (&res_utc, "clock/utc"); + + /* Register callback function(s) */ + cron_register_command ("led_on", led_set, (void *)1); + cron_register_command ("led_off", led_set, (void *)0); + + /* Allocate all cron entries and the necessary resources */ + activate_cron_resources (); + + /* Define application-specific events here. + * We need to call cron every 30 seconds or so (at least once a + * minute) + */ + etimer_set (&loop_periodic_timer, LOOP_INTERVAL); + while (1) { + PROCESS_WAIT_EVENT(); + if (etimer_expired (&loop_periodic_timer)) { + cron (); + etimer_reset (&loop_periodic_timer); + } + } /* while (1) */ + + PROCESS_END(); +} diff --git a/examples/osd/wirelessplug/Makefile b/examples/osd/wirelessplug/Makefile index 17792e430..aeaa5e2ad 100644 --- a/examples/osd/wirelessplug/Makefile +++ b/examples/osd/wirelessplug/Makefile @@ -1,11 +1,6 @@ -all: er-example-server er-example-client -# use this target explicitly if requried: er-plugtest-server - - -# variable for this Makefile -# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) -WITH_COAP=13 +EXE=er-example-server er-example-client +all: $(EXE) # variable for Makefile.include WITH_UIP6=1 @@ -95,3 +90,16 @@ connect-router-cooja: $(CONTIKI)/tools/tunslip6 connect-minimal: sudo ip address add fdfd::1/64 dev tap0 + +avr-size-server: er-example-server.$(TARGET).sz + +avr-size-client: er-example-server.$(TARGET).sz + +flash-server: er-example-server.$(TARGET).u er-example-server.$(TARGET).eu + +flash-client: er-example-client.$(TARGET).u er-example-client.$(TARGET).eu + +.PHONY: flash-client avr-size-client flash-server avr-size-server +.PRECIOUS: er-example-server.$(TARGET).hex er-example-server.$(TARGET).eep \ + er-example-client.$(TARGET).hex er-example-client.$(TARGET).eep + diff --git a/examples/osd/wirelessplug/flash.sh b/examples/osd/wirelessplug/flash.sh index e92d472f6..e82962073 100755 --- a/examples/osd/wirelessplug/flash.sh +++ b/examples/osd/wirelessplug/flash.sh @@ -1,2 +1,2 @@ #!/bin/bash -sudo avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-server.osd-merkur.hex:a -U eeprom:w:er-example-server.osd-merkur.eep:a +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/wirelessplug/run.sh b/examples/osd/wirelessplug/run.sh index 2efd2cf48..5d5cbbbb4 100755 --- a/examples/osd/wirelessplug/run.sh +++ b/examples/osd/wirelessplug/run.sh @@ -1,8 +1,5 @@ #!/bin/bash -# For the new bootloader (using a jump-table) you want to use -# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) -make clean TARGET=osd-merkur -make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0 -avr-size -C --mcu=MCU=atmega128rfa1 er-example-server.osd-merkur -avr-objcopy -j .text -j .data -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.hex -avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.eep +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/wirelessplug/server-client.csc b/examples/osd/wirelessplug/server-client.csc index 8c45fdf02..02aefd730 100644 --- a/examples/osd/wirelessplug/server-client.csc +++ b/examples/osd/wirelessplug/server-client.csc @@ -1,227 +1,227 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - client - Erbium Client - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c - make er-example-client.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 46.57186415376375 - 40.35946215910942 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - - se.sics.cooja.interfaces.Position - 18.638049428485125 - 47.55034515769599 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 3 - - client - - - - se.sics.cooja.plugins.SimControl - 259 - 0 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 - - 300 - 2 - 178 - 261 - 1 - - - se.sics.cooja.plugins.LogListener - - - - - 762 - 3 - 491 - 2 - 182 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 4 - 74 - 578 - 18 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - 2 - - - - - 125 - 25.49079397896416 - - 1624 - 5 - 252 - 6 - 712 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 2 - - Serial port - 0,0 - - 853 - 1 - 491 - 765 - 182 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + REST with RPL router + -2147483648 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + client + Erbium Client + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c + make er-example-client.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + se.sics.cooja.interfaces.Position + 46.57186415376375 + 40.35946215910942 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + + se.sics.cooja.interfaces.Position + 18.638049428485125 + 47.55034515769599 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 3 + + client + + + + se.sics.cooja.plugins.SimControl + 259 + 0 + 179 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.AttributeVisualizerSkin + se.sics.cooja.plugins.skins.LEDVisualizerSkin + se.sics.cooja.plugins.skins.AddressVisualizerSkin + 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 + + 300 + 2 + 178 + 261 + 1 + + + se.sics.cooja.plugins.LogListener + + + + + 762 + 3 + 491 + 2 + 182 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 4 + 74 + 578 + 18 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + 2 + + + + + 125 + 25.49079397896416 + + 1624 + 5 + 252 + 6 + 712 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 2 + + Serial port + 0,0 + + 853 + 1 + 491 + 765 + 182 + + + diff --git a/examples/osd/wirelessplug/server-only.csc b/examples/osd/wirelessplug/server-only.csc index d5eee34d6..1b0fe28bf 100644 --- a/examples/osd/wirelessplug/server-only.csc +++ b/examples/osd/wirelessplug/server-only.csc @@ -1,189 +1,189 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - REST with RPL router - -2147483648 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - server - Erbium Server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - se.sics.cooja.interfaces.Position - 35.100895239785295 - 39.70574552287428 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - server - - - - se.sics.cooja.plugins.SimControl - 259 - 5 - 179 - 0 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin - se.sics.cooja.plugins.skins.AttributeVisualizerSkin - se.sics.cooja.plugins.skins.LEDVisualizerSkin - se.sics.cooja.plugins.skins.AddressVisualizerSkin - 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 - - 300 - 4 - 175 - 263 - 3 - - - se.sics.cooja.plugins.LogListener - - - - - 560 - 1 - 326 - 1 - 293 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - - 451 - -1 - 305 - 73 - 140 - true - - - SerialSocketServer - 0 - 422 - 2 - 74 - 39 - 199 - - - se.sics.cooja.plugins.TimeLine - - 0 - 1 - - - - - 125 - 25.49079397896416 - - 1624 - 3 - 252 - 4 - 622 - - - se.sics.cooja.plugins.MoteInterfaceViewer - 1 - - Serial port - 0,0 - - 702 - 0 - 646 - 564 - 2 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + REST with RPL router + -2147483648 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + se.sics.cooja.interfaces.Position + 35.100895239785295 + 39.70574552287428 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + se.sics.cooja.plugins.SimControl + 259 + 5 + 179 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.AttributeVisualizerSkin + se.sics.cooja.plugins.skins.LEDVisualizerSkin + se.sics.cooja.plugins.skins.AddressVisualizerSkin + 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 + + 300 + 4 + 175 + 263 + 3 + + + se.sics.cooja.plugins.LogListener + + + + + 560 + 1 + 326 + 1 + 293 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 2 + 74 + 39 + 199 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + + + + + 125 + 25.49079397896416 + + 1624 + 3 + 252 + 4 + 622 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 702 + 0 + 646 + 564 + 2 + + + diff --git a/examples/ping-ipv6/Makefile b/examples/ping-ipv6/Makefile index 91dc81a4e..b500dd409 100644 --- a/examples/ping-ipv6/Makefile +++ b/examples/ping-ipv6/Makefile @@ -1,7 +1,6 @@ all: example-ping6 APPS=ping6 -UIP_CONF_IPV6=1 - CONTIKI = ../.. +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/powertrace/Makefile b/examples/powertrace/Makefile index 0eeeeb177..93816ff82 100644 --- a/examples/powertrace/Makefile +++ b/examples/powertrace/Makefile @@ -3,4 +3,5 @@ APPS+=powertrace all: $(CONTIKI_PROJECT) CONTIKI = ../.. +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/ravenusbstick/Makefile.ravenusbstick b/examples/ravenusbstick/Makefile.ravenusbstick index 9f8bc1ef0..27b244b11 100644 --- a/examples/ravenusbstick/Makefile.ravenusbstick +++ b/examples/ravenusbstick/Makefile.ravenusbstick @@ -1,16 +1,14 @@ all: ravenusbstick #Define CONTIKI_NO_NET=1 for a passthrough ipv6/6lowpan interface using fakeuip.c -#Define UIP_CONF_IPV6=1 to include the uip6 stack (for rpl, internal webserver) +#Define CONTIKI_WITH_IPV6 = 1 to include the uip6 stack (for rpl, internal webserver) #Do make clean when switching to remove the duplicate library modules CONTIKI_NO_NET=1 -#UIP_CONF_IPV6=1 - -CFLAGS=-DUIP_CONF_IPV6=0 -DUIP_CONF_IPV6_RPL=0 +CONTIKI_WITH_IPV6=0 CONTIKI = ../.. -MODULES+=core/net/mac/sicslowmac core/net/mac +MODULES+=core/net/mac/sicslowmac core/net core/net/mac core/net/llsec PROJECT_SOURCEFILES += fakeuip.c diff --git a/examples/ravenusbstick/fakeuip.c b/examples/ravenusbstick/fakeuip.c index a1e980aab..1f7232a64 100644 --- a/examples/ravenusbstick/fakeuip.c +++ b/examples/ravenusbstick/fakeuip.c @@ -13,6 +13,8 @@ uip_buf_t uip_aligned_buf; uint16_t uip_len; +uint8_t uip_ext_len; + struct uip_stats uip_stat; uip_lladdr_t uip_lladdr; diff --git a/examples/rest-example/Makefile b/examples/rest-example/Makefile deleted file mode 100644 index bd020537c..000000000 --- a/examples/rest-example/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -all: rest-server-example coap-client-example - -ifndef TARGET -TARGET=sky -endif - -CONTIKI=../.. - -UIP_CONF_IPV6=1 - -WITH_COAP = 1 - -CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" - -ifeq ($(WITH_COAP), 1) -CFLAGS += -DWITH_COAP -APPS += rest-coap -else -CFLAGS += -DWITH_HTTP -APPS += rest-http -endif - -include $(CONTIKI)/Makefile.include - -$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c - (cd $(CONTIKI)/tools && $(MAKE) tunslip6) - -connect-router: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 - -connect-router-cooja: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 diff --git a/examples/rest-example/README.md b/examples/rest-example/README.md deleted file mode 100644 index 1fd391653..000000000 --- a/examples/rest-example/README.md +++ /dev/null @@ -1,137 +0,0 @@ -REST example -============ - -Open a terminal and go to "/examples/rest-example/" directory. - -MAIN EXAMPLE: rest-server-example.c : A RESTful server example showing how to -use the REST layer to develop server-side applications (possible to run it over -either COAP or HTTP) To use COAP as the underlying application protocol, one -should define WITH_COAP = 1 in rest-example/Makefile. Otherwise, HTTP is used. -Look at the source code to see which resources are available. (check the -RESOURCE macros in the code). Each resource has a handler function which is -called by the REST layer to serve the request. (i.e. "helloworld" resource has -a handler function named "helloworld_handler" which is called when a web -service request is received for "helloworld" resource.) - - -To run REST examples in COOJA on Linux --------------------------------------------- - -Accessing the server from outside: - -1. Start COOJA and load the simulation "rest-server-example.csc" by the following command. - - make TARGET=cooja rest-server-example.csc - -2. After loading the COOJA file, open another another terminal pointing to the - same directory and connect to the COOJA simulation using tunslip6: - - make connect-router-cooja - -3. You need to use a COAP or HTTP client to interact with the COOJA nodes - running REST code. In this setting, two servers are available: IP addresses - are aaaa::0212:7402:0002:0202 and aaaa::0212:7403:0003:0303. COAP uses - 61616, whereas HTTP uses 8080 port in default configuration. First, ping - the COOJA nodes to test the connectivity. - - ping6 aaaa::0212:7402:0002:0202 - ping6 aaaa::0212:7403:0003:0303 - -HTTP Examples -------------- - -You can use curl as an http client to interact with the COOJA motes running -REST code. - - curl -H "User-Agent: curl" aaaa::0212:7402:0002:0202:8080/helloworld #get helloworld plain text - curl -H "User-Agent: curl" aaaa::0212:7402:0002:0202:8080/led?color=green -d mode=off -i #turn off the green led - curl -H "User-Agent: curl" aaaa::0212:7402:0002:0202:8080/.well-known/core -i - curl -X POST -H "User-Agent: curl" aaaa::0212:7402:0002:0202:8080/helloworld #method not allowed - -COAP Examples -------------- - -You should run a COAP client on your computer. You can use the URLs and methods -provided above in HTTP examples to test the COAP Server. For example, Matthias -Kovatsch has developed a CoAP Firefox plug-in which is accessible via -[http://people.inf.ethz.ch/mkovatsc/#pro](http://people.inf.ethz.ch/mkovatsc/#pro) - -Accessing the server inside the sensor network: (Note: Provided only for COAP -implementation) Start COOJA and load the simulation -"coap-client-server-example.csc" by the following command. - - make TARGET=cooja coap-client-server-example.csc - -coap-client-server-example.csc : Runs rest-server-example.c as the server (over -COAP) (IP:aaaa::0212:7401:0001:0101) in one node and coap-client-example.c as -the client (IP: aaaa::0212:7402:0002:0202) in another node. Client -periodically accesses resources of server and prints the payload. - -Note: If the generated binary is bigger than the MOTE code size, then you will -get a "region text is full" error. Right now, REST+HTTP example uses (Contiki -& ContikiMAC & uIPv6 & RPL & HTTP Server & REST Layer) which does not fit in -Tmote Sky memory. To save same code space and make the example fit, you can -define static routes rather than using RPL or use nullrdc rather than -ContikiMAC. If border router does not fit, then first try to update the -Makefile of border router in /examples/ipv6/rpl-border-router by -setting WITH_WEBSERVER=0. - -To run REST server on real nodes (i.e. tmote sky) --------------------------------------------- - -1. Program the nodes with the rest-server-example - - make TARGET=sky rest-server-example.upload - -2. Disconnect the nodes and program one node with the RPL border router - - cd ../ipv6/rpl-border-router && make TARGET=sky border-router.upload - -3. Connect to the border router using tunslip6: - - make connect-router - -4. Reconnect the motes, open new terminal for each mote and run the following - command to note their IP addresses (after running the command reset the - corresponding mote to get IP address printed) - - make login TARGET=sky MOTE=2 #Shows the prints for first mote - make login TARGET=sky MOTE=3 #For second mote and so on. - -5. Test the connectivity by pinging them. - - ping6 - -6. Remaining parts are the same with the COOJA example. (i.e. if it is a COAP - Server, it's available at :61616) - - -To run REST server with minimal-net on Linux --------------------------------------------- -1. Compile with minimal-net setting. - - make rest-server-example TARGET=minimal-net - -2. Run the generated executable with sudo and note the IP address of the server - which will be printed right after. - - sudo ./rest-server-example.minimal-net - -3. How to access and test the server is same with the other settings. (i.e. if - it is a COAP Server, it's available at :61616 and if - it's a HTTP Server it is available at :8080) - -TODO ----- - -- Better option handling needed - ex: critical options are not differentiated - for now. Need to add support for some such as Tokens. Also, C/E difference - should be added. -- Reilable message sending is missing. i.e. client example should resend - request in case ACK does not arrive. Same for server pushing (in case of - subscriptions) -- Add Block transfer example -- Add Subscription example -- Add an Android/Java COAP Client to Contikiprojects to be able to interact - with Contiki. -- COAP-specific Method Codes diff --git a/examples/rest-example/coap-client-example.c b/examples/rest-example/coap-client-example.c deleted file mode 100644 index e5772f103..000000000 --- a/examples/rest-example/coap-client-example.c +++ /dev/null @@ -1,123 +0,0 @@ -#include -#include -#include -#include "contiki.h" -#include "contiki-net.h" -#include "rest.h" -#include "buffer.h" - -#define DEBUG 1 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF("%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - -#define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0212, 0x7401, 0x0001, 0x0101) -#define LOCAL_PORT 61617 -#define REMOTE_PORT 61616 - -char temp[100]; -int xact_id; -static uip_ipaddr_t server_ipaddr; -static struct uip_udp_conn *client_conn; -static struct etimer et; -#define MAX_PAYLOAD_LEN 100 - -#define NUMBER_OF_URLS 3 -char* service_urls[NUMBER_OF_URLS] = {"light", ".well-known/core", "helloworld"}; - -static void -response_handler(coap_packet_t* response) -{ - uint16_t payload_len = 0; - uint8_t* payload = NULL; - payload_len = coap_get_payload(response, &payload); - - PRINTF("Response transaction id: %u", response->tid); - if (payload) { - memcpy(temp, payload, payload_len); - temp[payload_len] = 0; - PRINTF(" payload: %s\n", temp); - } -} - -static void -send_data(void) -{ - char buf[MAX_PAYLOAD_LEN]; - - if (init_buffer(COAP_DATA_BUFF_SIZE)) { - int data_size = 0; - int service_id = random_rand() % NUMBER_OF_URLS; - coap_packet_t* request = (coap_packet_t*)allocate_buffer(sizeof(coap_packet_t)); - init_packet(request); - - coap_set_method(request, COAP_GET); - request->tid = xact_id++; - request->type = MESSAGE_TYPE_CON; - coap_set_header_uri(request, service_urls[service_id]); - - data_size = serialize_packet(request, buf); - - PRINTF("Client sending request to:["); - PRINT6ADDR(&client_conn->ripaddr); - PRINTF("]:%u/%s\n", (uint16_t)REMOTE_PORT, service_urls[service_id]); - uip_udp_packet_send(client_conn, buf, data_size); - - delete_buffer(); - } -} - -static void -handle_incoming_data() -{ - PRINTF("Incoming packet size: %u \n", (uint16_t)uip_datalen()); - if (init_buffer(COAP_DATA_BUFF_SIZE)) { - if (uip_newdata()) { - coap_packet_t* response = (coap_packet_t*)allocate_buffer(sizeof(coap_packet_t)); - if (response) { - parse_message(response, uip_appdata, uip_datalen()); - response_handler(response); - } - } - delete_buffer(); - } -} - -PROCESS(coap_client_example, "COAP Client Example"); -AUTOSTART_PROCESSES(&coap_client_example); - -PROCESS_THREAD(coap_client_example, ev, data) -{ - PROCESS_BEGIN(); - - SERVER_NODE(&server_ipaddr); - - /* new connection with server */ - client_conn = udp_new(&server_ipaddr, UIP_HTONS(REMOTE_PORT), NULL); - udp_bind(client_conn, UIP_HTONS(LOCAL_PORT)); - - PRINTF("Created a connection with the server "); - PRINT6ADDR(&client_conn->ripaddr); - PRINTF(" local/remote port %u/%u\n", - UIP_HTONS(client_conn->lport), UIP_HTONS(client_conn->rport)); - - etimer_set(&et, 5 * CLOCK_SECOND); - while(1) { - PROCESS_YIELD(); - if (etimer_expired(&et)) { - send_data(); - etimer_reset(&et); - } else if (ev == tcpip_event) { - handle_incoming_data(); - } - } - - PROCESS_END(); -} diff --git a/examples/rest-example/coap-client-server-example.csc b/examples/rest-example/coap-client-server-example.csc deleted file mode 100644 index 72a77ac27..000000000 --- a/examples/rest-example/coap-client-server-example.csc +++ /dev/null @@ -1,147 +0,0 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - - coap-client-server-example - -2147483648 - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - CoapServer - [CONTIKI_DIR]/examples/rest-example/rest-server-example.c - make rest-server-example.sky TARGET=sky - [CONTIKI_DIR]/examples/rest-example/rest-server-example.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - sky2 - CoapClient - [CONTIKI_DIR]/examples/rest-example/coap-client-example.c - make coap-client-example.sky TARGET=sky - [CONTIKI_DIR]/examples/rest-example/coap-client-example.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 54.5338749671737 - 36.41934631024719 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 49.41583327244326 - 52.00647916206431 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky2 - - - - org.contikios.cooja.plugins.SimControl - 318 - 2 - 172 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.AddressVisualizerSkin - 3.686023978928717 0.0 0.0 3.686023978928717 -20.14794638096936 -127.69712925102564 - - 271 - 0 - 211 - 666 - 41 - - - org.contikios.cooja.plugins.LogListener - - - - 1263 - 1 - 199 - 0 - 339 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - - - - 125 - 500.0 - - 1263 - 3 - 150 - 0 - 538 - - - diff --git a/examples/rest-example/rest-server-example.c b/examples/rest-example/rest-server-example.c deleted file mode 100644 index 24b33ff15..000000000 --- a/examples/rest-example/rest-server-example.c +++ /dev/null @@ -1,180 +0,0 @@ -#include -#include -#include -#include "contiki.h" -#include "contiki-net.h" -#include "rest.h" - -#if defined (PLATFORM_HAS_LIGHT) -#include "dev/light-sensor.h" -#endif -#if defined (PLATFORM_HAS_BATT) -#include "dev/battery-sensor.h" -#endif -#if defined (PLATFORM_HAS_SHT11) -#include "dev/sht11/sht11-sensor.h" -#endif -#if defined (PLATFORM_HAS_LEDS) -#include "dev/leds.h" -#endif - -#define DEBUG 1 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif - -char temp[100]; - -/* Resources are defined by RESOURCE macro, signature: resource name, the http methods it handles and its url*/ -RESOURCE(helloworld, METHOD_GET, "helloworld"); - -/* For each resource defined, there corresponds an handler method which should be defined too. - * Name of the handler method should be [resource name]_handler - * */ -void -helloworld_handler(REQUEST* request, RESPONSE* response) -{ - sprintf(temp,"Hello World!\n"); - - rest_set_header_content_type(response, TEXT_PLAIN); - rest_set_response_payload(response, (uint8_t*)temp, strlen(temp)); -} - -RESOURCE(discover, METHOD_GET, ".well-known/core"); -void -discover_handler(REQUEST* request, RESPONSE* response) -{ - char temp[100]; - int index = 0; - index += sprintf(temp + index, "%s,", ";n=\"HelloWorld\""); -#if defined (PLATFORM_HAS_LEDS) - index += sprintf(temp + index, "%s,", ";n=\"LedControl\""); -#endif -#if defined (PLATFORM_HAS_LIGHT) - index += sprintf(temp + index, "%s", "
    ;n=\"Light\""); -#endif - - rest_set_response_payload(response, (uint8_t*)temp, strlen(temp)); - rest_set_header_content_type(response, APPLICATION_LINK_FORMAT); -} - -#if defined (PLATFORM_HAS_LIGHT) -uint16_t light_photosynthetic; -uint16_t light_solar; - -void -read_light_sensor(uint16_t* light_1, uint16_t* light_2) -{ - *light_1 = light_sensor.value(LIGHT_SENSOR_PHOTOSYNTHETIC); - *light_2 = light_sensor.value(LIGHT_SENSOR_TOTAL_SOLAR); -} - -/*A simple getter example. Returns the reading from light sensor with a simple etag*/ -RESOURCE(light, METHOD_GET, "light"); -void -light_handler(REQUEST* request, RESPONSE* response) -{ - read_light_sensor(&light_photosynthetic, &light_solar); - sprintf(temp,"%u;%u", light_photosynthetic, light_solar); - - char etag[4] = "ABCD"; - rest_set_header_content_type(response, TEXT_PLAIN); - rest_set_header_etag(response, etag, sizeof(etag)); - rest_set_response_payload(response, temp, strlen(temp)); -} -#endif /*PLATFORM_HAS_LIGHT*/ - -#if defined (PLATFORM_HAS_LEDS) -/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -RESOURCE(led, METHOD_POST | METHOD_PUT , "led"); - -void -led_handler(REQUEST* request, RESPONSE* response) -{ - char color[10]; - char mode[10]; - uint8_t led = 0; - int success = 1; - - if (rest_get_query_variable(request, "color", color, 10)) { - PRINTF("color %s\n", color); - - if (!strcmp(color,"red")) { - led = LEDS_RED; - } else if(!strcmp(color,"green")) { - led = LEDS_GREEN; - } else if ( !strcmp(color,"blue") ) { - led = LEDS_BLUE; - } else { - success = 0; - } - } else { - success = 0; - } - - if (success && rest_get_post_variable(request, "mode", mode, 10)) { - PRINTF("mode %s\n", mode); - - if (!strcmp(mode, "on")) { - leds_on(led); - } else if (!strcmp(mode, "off")) { - leds_off(led); - } else { - success = 0; - } - } else { - success = 0; - } - - if (!success) { - rest_set_response_status(response, BAD_REQUEST_400); - } -} - - -/*A simple actuator example. Toggles the red led*/ -RESOURCE(toggle, METHOD_GET | METHOD_PUT | METHOD_POST, "toggle"); -void -toggle_handler(REQUEST* request, RESPONSE* response) -{ - leds_toggle(LEDS_RED); -} -#endif /*defined (CONTIKI_HAS_LEDS)*/ - - -PROCESS(rest_server_example, "Rest Server Example"); -AUTOSTART_PROCESSES(&rest_server_example); - -PROCESS_THREAD(rest_server_example, ev, data) -{ - PROCESS_BEGIN(); - -#ifdef WITH_COAP - PRINTF("COAP Server\n"); -#else - PRINTF("HTTP Server\n"); -#endif - - rest_init(); - -#if defined (PLATFORM_HAS_LIGHT) - SENSORS_ACTIVATE(light_sensor); - rest_activate_resource(&resource_light); -#endif -#if defined (PLATFORM_HAS_LEDS) - rest_activate_resource(&resource_led); - rest_activate_resource(&resource_toggle); -#endif /*defined (PLATFORM_HAS_LEDS)*/ - - rest_activate_resource(&resource_helloworld); - rest_activate_resource(&resource_discover); - - PROCESS_END(); -} diff --git a/examples/rime/Makefile b/examples/rime/Makefile index df4cb3af1..f46fc2fbf 100644 --- a/examples/rime/Makefile +++ b/examples/rime/Makefile @@ -1,7 +1,8 @@ CONTIKI = ../.. all: example-abc example-mesh example-collect example-trickle example-polite \ - example-rudolph0 example-rudolph1 example-rudolph2 example-rucb \ + example-rudolph1 example-rudolph2 example-rucb \ example-runicast example-unicast example-neighbors +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/rime/example-broadcast.csc b/examples/rime/example-broadcast.csc index 1aaf8f52d..11feb30db 100644 --- a/examples/rime/example-broadcast.csc +++ b/examples/rime/example-broadcast.csc @@ -1,248 +1,248 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/native_gateway - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - /home/user/contikiprojects/sics.se/mobility - [CONTIKI_DIR]/tools/cooja/apps/collect-view - /home/user/contikiprojects/sics.se/powertracker - - Broadcast example - 0 - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Broadcast example - [CONTIKI_DIR]/examples/rime/example-broadcast.c - make example-broadcast.sky TARGET=sky - [CONTIKI_DIR]/examples/rime/example-broadcast.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 37.5366545201821 - 20.133438936240488 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 50.05393308569106 - 3.886106972235548 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 53.50011157471555 - 48.16869587128244 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 12.542870357677295 - 50.15965479801062 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 45.30496839108535 - 49.347800977978565 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 74.7539300728242 - 28.371269772953212 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 51.968753134087585 - 77.76059892362437 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 7 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 63.365939830655286 - 24.573727672975103 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 8 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 21.82676295937117 - 84.86468902217199 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 9 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 8.668640141529082 - 21.113338033999675 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 10 - - sky1 - - - - org.contikios.cooja.plugins.SimControl - 318 - 3 - 192 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.AddressVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 2.6322285313650773 0.0 0.0 2.6322285313650773 36.20636526098638 1.3163328971993926 - - 300 - 1 - 300 - 528 - -2 - - - org.contikios.cooja.plugins.LogListener - - - - 827 - 2 - 218 - 1 - 197 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - - - 125 - 500.0 - - 828 - 0 - 138 - 0 - 414 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/native_gateway + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + /home/user/contikiprojects/sics.se/mobility + [CONTIKI_DIR]/tools/cooja/apps/collect-view + /home/user/contikiprojects/sics.se/powertracker + + Broadcast example + 0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Broadcast example + [CONTIKI_DIR]/examples/rime/example-broadcast.c + make example-broadcast.sky TARGET=sky + [CONTIKI_DIR]/examples/rime/example-broadcast.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 37.5366545201821 + 20.133438936240488 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 50.05393308569106 + 3.886106972235548 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 53.50011157471555 + 48.16869587128244 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 12.542870357677295 + 50.15965479801062 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 45.30496839108535 + 49.347800977978565 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 74.7539300728242 + 28.371269772953212 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 51.968753134087585 + 77.76059892362437 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 63.365939830655286 + 24.573727672975103 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 21.82676295937117 + 84.86468902217199 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 8.668640141529082 + 21.113338033999675 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky1 + + + + org.contikios.cooja.plugins.SimControl + 318 + 3 + 192 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.AddressVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 2.6322285313650773 0.0 0.0 2.6322285313650773 36.20636526098638 1.3163328971993926 + + 300 + 1 + 300 + 528 + -2 + + + org.contikios.cooja.plugins.LogListener + + + + 827 + 2 + 218 + 1 + 197 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + + + 125 + 500.0 + + 828 + 0 + 138 + 0 + 414 + + + diff --git a/examples/rime/example-collect.csc b/examples/rime/example-collect.csc index 5d7e6a85a..f62b57703 100644 --- a/examples/rime/example-collect.csc +++ b/examples/rime/example-collect.csc @@ -1,397 +1,397 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/native_gateway - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - /home/user/contikiprojects/sics.se/mobility - [CONTIKI_DIR]/tools/cooja/apps/collect-view - /home/user/contikiprojects/sics.se/powertracker - - Data collection example - 0 - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Example collect node - [CONTIKI_DIR]/examples/rime/example-collect.c - make example-collect.sky TARGET=sky - [CONTIKI_DIR]/examples/rime/example-collect.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 65.8935940755176 - 14.594950283135312 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 47.56630509016557 - 51.132236067167604 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 40.93494312024828 - 11.883845068265275 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 77.1251293927618 - 63.96476780063865 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 34.176936162571266 - 81.7759518046417 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 86.36132335500719 - 81.54179387349707 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 8.431276662440911 - 19.467241269096913 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 7 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 68.04527746863809 - 30.658199043821188 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 8 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 19.419170252458517 - 11.342055898031656 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 9 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 67.24618929801707 - 78.05087610981025 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 10 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 31.300913760017014 - 63.65669310098622 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 11 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 45.92507013405063 - 74.06071519244233 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 12 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 24.4718977171667 - 55.69738781271142 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 13 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 97.40535813382874 - 79.53018482049097 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 14 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 90.26570665508994 - 84.64525225408181 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 15 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 56.39117393990196 - 36.50957906187927 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 16 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 35.7941361611345 - 59.7284533249923 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 17 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 41.48471209234133 - 8.567545636380459 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 18 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 43.33967640673231 - 63.09025681148592 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 19 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 97.76077344510439 - 82.71896818588284 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 20 - - sky1 - - - - org.contikios.cooja.plugins.SimControl - 318 - 2 - 192 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 2.903729630273725 0.0 0.0 2.903729630273725 -9.17650119839569 -14.332381577625736 - - 300 - 0 - 300 - 491 - 0 - - - org.contikios.cooja.plugins.LogListener - - - - 791 - 3 - 198 - 1 - 194 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - - - 125 - 1871.7106886304318 - - 791 - 1 - 149 - 1 - 389 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/native_gateway + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + /home/user/contikiprojects/sics.se/mobility + [CONTIKI_DIR]/tools/cooja/apps/collect-view + /home/user/contikiprojects/sics.se/powertracker + + Data collection example + 0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Example collect node + [CONTIKI_DIR]/examples/rime/example-collect.c + make example-collect.sky TARGET=sky + [CONTIKI_DIR]/examples/rime/example-collect.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 65.8935940755176 + 14.594950283135312 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 47.56630509016557 + 51.132236067167604 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 40.93494312024828 + 11.883845068265275 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 77.1251293927618 + 63.96476780063865 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 34.176936162571266 + 81.7759518046417 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 86.36132335500719 + 81.54179387349707 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 8.431276662440911 + 19.467241269096913 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 68.04527746863809 + 30.658199043821188 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 19.419170252458517 + 11.342055898031656 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 67.24618929801707 + 78.05087610981025 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 31.300913760017014 + 63.65669310098622 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 11 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 45.92507013405063 + 74.06071519244233 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 12 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 24.4718977171667 + 55.69738781271142 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 13 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 97.40535813382874 + 79.53018482049097 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 14 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 90.26570665508994 + 84.64525225408181 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 15 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 56.39117393990196 + 36.50957906187927 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 16 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 35.7941361611345 + 59.7284533249923 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 17 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 41.48471209234133 + 8.567545636380459 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 18 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 43.33967640673231 + 63.09025681148592 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 19 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 97.76077344510439 + 82.71896818588284 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 20 + + sky1 + + + + org.contikios.cooja.plugins.SimControl + 318 + 2 + 192 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 2.903729630273725 0.0 0.0 2.903729630273725 -9.17650119839569 -14.332381577625736 + + 300 + 0 + 300 + 491 + 0 + + + org.contikios.cooja.plugins.LogListener + + + + 791 + 3 + 198 + 1 + 194 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + + + 125 + 1871.7106886304318 + + 791 + 1 + 149 + 1 + 389 + + + diff --git a/examples/rime/example-rucb.c b/examples/rime/example-rucb.c index 7bf5d3b1d..e3d291c52 100644 --- a/examples/rime/example-rucb.c +++ b/examples/rime/example-rucb.c @@ -89,7 +89,7 @@ read_chunk(struct rucb_conn *c, int offset, char *to, int maxsize) bytecount += size; if(bytecount == FILESIZE) { - printf("Completion time %lu / %u\n", (unsigned long)clock_time() - start_time, CLOCK_SECOND); + printf("Completion time %lu / %u\n", (unsigned long)clock_time() - start_time, (unsigned int)CLOCK_SECOND); print_stats(); } diff --git a/examples/rime/example-rudolph0.c b/examples/rime/example-rudolph0.c deleted file mode 100644 index 196340f1c..000000000 --- a/examples/rime/example-rudolph0.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Testing the rudolph0 code in Rime - * \author - * Adam Dunkels - */ - -#include "contiki.h" -#include "cfs/cfs.h" -#include "net/rime/rudolph0.h" - -#include "dev/button-sensor.h" - -#include "dev/leds.h" - -#include - -#define FILESIZE 200 - -/*---------------------------------------------------------------------------*/ -PROCESS(example_rudolph0_process, "Rudolph0 example"); -AUTOSTART_PROCESSES(&example_rudolph0_process); -/*---------------------------------------------------------------------------*/ -static void -write_chunk(struct rudolph0_conn *c, int offset, int flag, - uint8_t *data, int datalen) -{ - int fd; - - if(flag == RUDOLPH0_FLAG_NEWFILE) { - /* printf("+++ rudolph0 new file incoming at %lu\n", clock_time());*/ - leds_on(LEDS_RED); - fd = cfs_open("codeprop.out", CFS_WRITE); - } else { - fd = cfs_open("codeprop.out", CFS_WRITE + CFS_APPEND); - } - - if(datalen > 0) { - int ret; - cfs_seek(fd, offset, CFS_SEEK_SET); - ret = cfs_write(fd, data, datalen); - /* printf("write_chunk wrote %d bytes at %d, %d\n", ret, offset, (unsigned char)data[0]);*/ - } - - cfs_close(fd); - - if(flag == RUDOLPH0_FLAG_LASTCHUNK) { - int i; - /* printf("+++ rudolph0 entire file received at %lu\n", clock_time());*/ - leds_off(LEDS_RED); - leds_on(LEDS_YELLOW); - fd = cfs_open("hej", CFS_READ); - for(i = 0; i < FILESIZE; ++i) { - unsigned char buf; - cfs_read(fd, &buf, 1); - if(buf != (unsigned char)i) { - printf("error: diff at %d, %d != %d\n", i, i, buf); - break; - } - } - cfs_close(fd); - } -} -static int -read_chunk(struct rudolph0_conn *c, int offset, uint8_t *to, int maxsize) -{ - int fd; - int ret; - - fd = cfs_open("hej", CFS_READ); - - cfs_seek(fd, offset, CFS_SEEK_SET); - ret = cfs_read(fd, to, maxsize); - /* printf("read_chunk %d bytes at %d, %d\n", ret, offset, (unsigned char)to[0]);*/ - cfs_close(fd); - return ret; -} -const static struct rudolph0_callbacks rudolph0_call = {write_chunk, - read_chunk}; -static struct rudolph0_conn rudolph0; -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(example_rudolph0_process, ev, data) -{ - static int fd; - - PROCESS_EXITHANDLER(rudolph0_close(&rudolph0);) - - PROCESS_BEGIN(); - - PROCESS_PAUSE(); - - - rudolph0_open(&rudolph0, 138, &rudolph0_call); - SENSORS_ACTIVATE(button_sensor); - - while(1) { - PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event && - data == &button_sensor); - { - int i; - - fd = cfs_open("hej", CFS_WRITE); - for(i = 0; i < FILESIZE; i++) { - unsigned char buf = i; - cfs_write(fd, &buf, 1); - } - cfs_close(fd); - } - rudolph0_send(&rudolph0, CLOCK_SECOND / 4); - - PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event && - data == &button_sensor); - rudolph0_stop(&rudolph0); - - } - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/rime/example-rudolph1.c b/examples/rime/example-rudolph1.c index ebdf8a4cd..1dcf4b0af 100644 --- a/examples/rime/example-rudolph1.c +++ b/examples/rime/example-rudolph1.c @@ -83,9 +83,8 @@ write_chunk(struct rudolph1_conn *c, int offset, int flag, } if(datalen > 0) { - int ret; cfs_seek(fd, offset, CFS_SEEK_SET); - ret = cfs_write(fd, data, datalen); + cfs_write(fd, data, datalen); } cfs_close(fd); diff --git a/examples/rime/example-rudolph2.c b/examples/rime/example-rudolph2.c index 3b97d1857..fe9afd0dc 100644 --- a/examples/rime/example-rudolph2.c +++ b/examples/rime/example-rudolph2.c @@ -82,9 +82,8 @@ write_chunk(struct rudolph2_conn *c, int offset, int flag, } if(datalen > 0) { - int ret; cfs_seek(fd, offset, CFS_SEEK_SET); - ret = cfs_write(fd, data, datalen); + cfs_write(fd, data, datalen); printf("+++ rudolph2 offset %d, length %d\n", offset, datalen); } diff --git a/examples/rime/example-unicast.c b/examples/rime/example-unicast.c index 5d28ef66f..7ee764a54 100644 --- a/examples/rime/example-unicast.c +++ b/examples/rime/example-unicast.c @@ -39,11 +39,6 @@ #include "contiki.h" #include "net/rime/rime.h" - -#include "dev/button-sensor.h" - -#include "dev/leds.h" - #include /*---------------------------------------------------------------------------*/ @@ -56,7 +51,19 @@ recv_uc(struct unicast_conn *c, const linkaddr_t *from) printf("unicast message received from %d.%d\n", from->u8[0], from->u8[1]); } -static const struct unicast_callbacks unicast_callbacks = {recv_uc}; +/*---------------------------------------------------------------------------*/ +static void +sent_uc(struct unicast_conn *c, int status, int num_tx) +{ + const linkaddr_t *dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER); + if(linkaddr_cmp(dest, &linkaddr_null)) { + return; + } + printf("unicast message sent to %d.%d: status %d num_tx %d\n", + dest->u8[0], dest->u8[1], status, num_tx); +} +/*---------------------------------------------------------------------------*/ +static const struct unicast_callbacks unicast_callbacks = {recv_uc, sent_uc}; static struct unicast_conn uc; /*---------------------------------------------------------------------------*/ PROCESS_THREAD(example_unicast_process, ev, data) diff --git a/examples/rssi-scanner/Makefile b/examples/rssi-scanner/Makefile new file mode 100644 index 000000000..2513eba11 --- /dev/null +++ b/examples/rssi-scanner/Makefile @@ -0,0 +1,23 @@ +DEFINES=PROJECT_CONF_H=\"project-conf.h\" + +ifndef TARGET +TARGET = z1 +endif + +CONTIKI = ../.. + +CONTIKI_PROJECT = rssi-scanner-cc2420 + +all: $(CONTIKI_PROJECT) + +%.class: %.java + javac $(basename $<).java + +viewrssi3d: ViewRSSI3D.class + make login | java ViewRSSI3D + +viewrssi: ViewRSSI.class + make login | java ViewRSSI + +include $(CONTIKI)/Makefile.include + diff --git a/examples/z1/rssi_scanner/ViewRSSI.java b/examples/rssi-scanner/ViewRSSI.java similarity index 77% rename from examples/z1/rssi_scanner/ViewRSSI.java rename to examples/rssi-scanner/ViewRSSI.java index e768594b6..deb17dc8d 100644 --- a/examples/z1/rssi_scanner/ViewRSSI.java +++ b/examples/rssi-scanner/ViewRSSI.java @@ -1,155 +1,161 @@ -/* - * Copyright (c) 2010, University of Luebeck, Germany. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * Author: Carlo Alberto Boano , Joakim Eriksson, - * - */ - -import javax.swing.*; -import java.awt.*; -import java.io.*; - -public class ViewRSSI extends JPanel{ - // Constants - public static int TOTAL = 86; // Number of channel of 1 MHz sampled - public static int DECREASE_RSSI = 2; // How many dBm the grey RSSI falls each sample - public static int RSSI_MAX_VALUE = 100; // Maximum value obtainable from RSSI readings of CC2420. - public static int MARGIN_BOTTOM = 20; // Margin from the bottom - public static int MARGIN_RIGHT = 75; // Margin from the right - public static int MARGIN_TOP = 12; // Margin from the top - public static int INTERFERED_CHANNEL = 24; // Interfered channel - - public InputStream inputstr; - private int[] rssi = new int[TOTAL]; // Array of current Noise floor values (black line) - private int[] rssiMax = new int[TOTAL]; // Array with past Noise floor values (grey line) - - - public ViewRSSI() { - } - - public void paint(Graphics g) { - Graphics2D g2 = (Graphics2D) g; - int h = getHeight(); - int w = getWidth(); - double factor = (h - (MARGIN_BOTTOM*1.0)) / RSSI_MAX_VALUE; - double sSpacing = (w - MARGIN_RIGHT) / (TOTAL*1.0); - int sWidth = (int) (sSpacing - 1); - if (sWidth == 0) sWidth = 1; - - // Set white background in the plot - g.setColor(Color.white); - g.fillRect(0, 0, w, h); - - // Gradient example (ytics background) - GradientPaint greytowhite = new GradientPaint(w-MARGIN_RIGHT,0,Color.WHITE,w, 0,Color.lightGray, false); - g2.setPaint(greytowhite); - g2.fillRect(w-MARGIN_RIGHT, 0, w, h); - - // Draw the light grey channels from 11 to 26 - double xpos = 10; - for(int i=4;i rssiMax[i]) rssiMax[i] = rssi[i]; - else if (rssiMax[i] > 0) rssiMax[i] = rssiMax[i] - DECREASE_RSSI; - } - } catch (Exception e) { - e.printStackTrace(); /* Report error, but do not fail... */ - } - repaint(); - } - } - } - - - public static void main(String[] args) throws IOException { - JFrame win = new JFrame("RSSI Viewer"); - ViewRSSI panel; - win.setBounds(10, 10, 590, 590); - win.getContentPane().add(panel = new ViewRSSI()); - win.setVisible(true); - win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - panel.handleInput(); - } - -} +/* + * Copyright (c) 2007, Swedish Institute of Computer Science. + * Copyright (c) 2010, University of Luebeck, Germany. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +/** + * \file + * ViewRSSI java application + * \author + * Joakim Eriksson + * Carlo Alberto Boano + */ + +import javax.swing.*; +import java.awt.*; +import java.io.*; + +public class ViewRSSI extends JPanel{ + // Constants + public static int TOTAL = 86; // Number of channel of 1 MHz sampled + public static int DECREASE_RSSI = 2; // How many dBm the grey RSSI falls each sample + public static int RSSI_MAX_VALUE = 100; // Maximum value obtainable from RSSI readings of CC2420. + public static int MARGIN_BOTTOM = 20; // Margin from the bottom + public static int MARGIN_RIGHT = 75; // Margin from the right + public static int MARGIN_TOP = 12; // Margin from the top + public static int INTERFERED_CHANNEL = 24; // Interfered channel + + public InputStream inputstr; + private int[] rssi = new int[TOTAL]; // Array of current Noise floor values (black line) + private int[] rssiMax = new int[TOTAL]; // Array with past Noise floor values (grey line) + + + public ViewRSSI() { + } + + public void paint(Graphics g) { + Graphics2D g2 = (Graphics2D) g; + int h = getHeight(); + int w = getWidth(); + double factor = (h - (MARGIN_BOTTOM*1.0)) / RSSI_MAX_VALUE; + double sSpacing = (w - MARGIN_RIGHT) / (TOTAL*1.0); + int sWidth = (int) (sSpacing - 1); + if (sWidth == 0) sWidth = 1; + + // Set white background in the plot + g.setColor(Color.white); + g.fillRect(0, 0, w, h); + + // Gradient example (ytics background) + GradientPaint greytowhite = new GradientPaint(w-MARGIN_RIGHT,0,Color.WHITE,w, 0,Color.lightGray, false); + g2.setPaint(greytowhite); + g2.fillRect(w-MARGIN_RIGHT, 0, w, h); + + // Draw the light grey channels from 11 to 26 + double xpos = 10; + for(int i=4;i rssiMax[i]) rssiMax[i] = rssi[i]; + else if (rssiMax[i] > 0) rssiMax[i] = rssiMax[i] - DECREASE_RSSI; + } + } catch (Exception e) { + e.printStackTrace(); /* Report error, but do not fail... */ + } + repaint(); + } + } + } + + + public static void main(String[] args) throws IOException { + JFrame win = new JFrame("RSSI Viewer"); + ViewRSSI panel; + win.setBounds(10, 10, 590, 590); + win.getContentPane().add(panel = new ViewRSSI()); + win.setVisible(true); + win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + panel.handleInput(); + } + +} diff --git a/examples/z1/rssi_scanner/ViewRSSI3D.java b/examples/rssi-scanner/ViewRSSI3D.java similarity index 98% rename from examples/z1/rssi_scanner/ViewRSSI3D.java rename to examples/rssi-scanner/ViewRSSI3D.java index 425d1a276..2defe6bcb 100644 --- a/examples/z1/rssi_scanner/ViewRSSI3D.java +++ b/examples/rssi-scanner/ViewRSSI3D.java @@ -1,7 +1,7 @@ /** * 3D RSSI Viewer - view RSSI values of 802.15.4 channels * --------------------------------------------------- - * Note: run the rssi-scanner on a Sky or sentilla node connected to USB + * Note: run the rssi-scanner on a Sky, Z1 or sentilla node connected to USB * then start with * make login | java ViewRSSI3D * diff --git a/examples/z1/rssi_scanner/project-conf.h b/examples/rssi-scanner/project-conf.h similarity index 100% rename from examples/z1/rssi_scanner/project-conf.h rename to examples/rssi-scanner/project-conf.h diff --git a/examples/z1/rssi_scanner/rssi-scanner.c b/examples/rssi-scanner/rssi-scanner-cc2420.c similarity index 85% rename from examples/z1/rssi_scanner/rssi-scanner.c rename to examples/rssi-scanner/rssi-scanner-cc2420.c index bbca9cdb6..94c9056b9 100644 --- a/examples/z1/rssi_scanner/rssi-scanner.c +++ b/examples/rssi-scanner/rssi-scanner-cc2420.c @@ -54,15 +54,22 @@ static void set_frq(int c) { int f; - // We can read even other channels with CC2420! - // Fc = 2048 + FSCTRL ; Fc = 2405 + 5(k-11) MHz, k=11,12, ... , 26 - f = c + 352; // Start from 2400 MHz to 2485 MHz, - //FASTSPI_SETREG(CC2420_FSCTRL, f); - //FASTSPI_STROBE(CC2420_SRXON); - CC2420_WRITE_REG(CC2420_FSCTRL, f); - CC2420_STROBE(CC2420_SRXON); -} + /* We can read even other channels with CC2420! */ + /* Fc = 2048 + FSCTRL ; Fc = 2405 + 5(k-11) MHz, k=11,12, ... , 26 */ + f = c + 352; /* Start from 2400 MHz to 2485 MHz, */ + /* Write the new channel value */ + CC2420_SPI_ENABLE(); + SPI_WRITE_FAST(CC2420_FSCTRL); + SPI_WRITE_FAST((uint8_t)(f >> 8)); + SPI_WRITE_FAST((uint8_t)(f & 0xff)); + SPI_WAITFORTx_ENDED(); + SPI_WRITE(0); + + /* Send the strobe */ + SPI_WRITE(CC2420_SRXON); + CC2420_SPI_DISABLE(); +} static void do_rssi(void) { @@ -70,11 +77,10 @@ do_rssi(void) printf("RSSI:"); for(channel = 0; channel <= 85; ++channel) { set_frq(channel); - printf("%d ", cc2420_rssi() + 55); + printf("%d ", cc2420_rssi() + 100); } printf("\n"); } - /*---------------------------------------------------------------------------*/ PROCESS(scanner_process, "RSSI Scanner"); AUTOSTART_PROCESSES(&scanner_process); diff --git a/examples/seedeye/powerswitch/Makefile b/examples/seedeye/powerswitch/Makefile index a7b4c9fbe..683da4226 100644 --- a/examples/seedeye/powerswitch/Makefile +++ b/examples/seedeye/powerswitch/Makefile @@ -7,46 +7,8 @@ all: remotepowerswitch CONTIKI=../../../ CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" -# for some platforms -UIP_CONF_IPV6=1 - -WITH_COAP=13 - -UIP_CONF_RPL=1 - -# REST framework, requires WITH_COAP -ifeq ($(WITH_COAP), 13) -${info INFO: compiling with CoAP-13} -CFLAGS += -DWITH_COAP=13 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-13 -else ifeq ($(WITH_COAP), 12) -${info INFO: compiling with CoAP-12} -CFLAGS += -DWITH_COAP=12 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-12 -else ifeq ($(WITH_COAP), 7) -${info INFO: compiling with CoAP-08} -CFLAGS += -DWITH_COAP=7 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-07 -else ifeq ($(WITH_COAP), 3) -${info INFO: compiling with CoAP-03} -CFLAGS += -DWITH_COAP=3 -CFLAGS += -DREST=coap_rest_implementation -CFLAGS += -DUIP_CONF_TCP=0 -APPS += er-coap-03 -else -${info INFO: compiling with HTTP} -CFLAGS += -DWITH_HTTP -CFLAGS += -DREST=http_rest_implementation -CFLAGS += -DUIP_CONF_TCP=1 -APPS += er-http-engine -endif - -APPS += erbium +APPS += er-coap +APPS += rest-engine +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/seedeye/powerswitch/remotepowerswitch.c b/examples/seedeye/powerswitch/remotepowerswitch.c index 3bcfb10f3..04d3ea3c5 100644 --- a/examples/seedeye/powerswitch/remotepowerswitch.c +++ b/examples/seedeye/powerswitch/remotepowerswitch.c @@ -1,13 +1,13 @@ /* * Remote Power Switch Example for the Seed-Eye Board * Copyright (c) 2013, Giovanni Pellerano - * + * * Ownership: Scuola Superiore Sant'Anna (http://www.sssup.it) and * Consorzio Nazionale Interuniversitario per le Telecomunicazioni * (http://www.cnit.it). * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -33,7 +33,7 @@ * SUCH DAMAGE. * */ - + /** * \addtogroup Remote Power Switch Example for the Seed-Eye Board * @@ -55,20 +55,21 @@ #include "contiki.h" #include "contiki-net.h" -#include "erbium.h" +#include "rest-engine.h" #include "dev/leds.h" #include -RESOURCE(toggle, METHOD_GET | METHOD_PUT | METHOD_POST, "actuators/powerswitch", "title=\"Red LED\";rt=\"Control\""); void toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { leds_toggle(LEDS_RED); - + PORTEbits.RE0 = !PORTEbits.RE0; } +RESOURCE(resource_toggle, "title=\"Red LED\";rt=\"Control\"", toggle_handler, toggle_handler, toggle_handler, NULL); + PROCESS(remote_power_switch, "Remote Power Switch"); @@ -79,11 +80,11 @@ PROCESS_THREAD(remote_power_switch, ev, data) PROCESS_BEGIN(); rest_init_engine(); - + TRISEbits.TRISE0 = 0; PORTEbits.RE0 = 0; - rest_activate_resource(&resource_toggle); + rest_activate_resource(&resource_toggle, "actuators/powerswitch"); while(1) { PROCESS_WAIT_EVENT(); diff --git a/examples/sensinode/Makefile b/examples/sensinode/Makefile deleted file mode 100644 index 773998539..000000000 --- a/examples/sensinode/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740 - -# These examples don't need code banking so we turn it off -#HAVE_BANKING=1 - -CONTIKI_PROJECT += timer-test blink-hello broadcast-rime - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../.. -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/README.md b/examples/sensinode/README.md deleted file mode 100644 index 5168ff692..000000000 --- a/examples/sensinode/README.md +++ /dev/null @@ -1,60 +0,0 @@ -Sensinode platform example and test applications -================================================ - -by Zach Shelby - -Some more examples by George Oikonomou - -Loughborough University - -cc2431-location-engine, udp-ipv6, broadcast-rime blink-hello, event-post, -timer-test - -This directory contains example and test applications for Sensinode CC2430 -based devices. By default it is set to use the sensinode platform: - -/platform/sensinode -/cpu/cc2430 - -To build an application: - - make [app_name] - make hello_world - -To build and upload an application using the Sensinode nano_programmer included -under /tools (default /dev/ttyUSB0): - - make [app_name].upload - make hello_world.upload - -To dump the serial port output (default /dev/ttyUSB0): - - make sensinode.serialdump - -To configure the hardware model, you can include a make option e.g. for the -N601 (N100 is assumed by default): - - make hello_world DEFINES=MODEL_N601 - -These make options are defined in /platform/sensinode/Makefile.sensinode - -Descriptions of applications: - -- udp-ipv6: UDP client-server example over uIPv6. Uses link-local and global - addresses. Button 1 on the client will send an echo request. - -- broadcast-rime: Just a broadcast rime example, slightly modified - -- sensors: Demonstrating button and ADC functionality - -- cc2431-location-engine: Example demonstrating the usage cc2431 location - engine (blind node) N.B. Not all sensinode devides have a cc2431 - -- event-post: Demonstrating the interaction between two processes with custom - events - -- blink-hello: Hello World with LED blinking. - -- timer-test: Same as clock_test above + testing the rtimer-arch code - -- border-router: 802.15.4 to SLIP bridge example. The node will forward packets - from the 15.4 network to its UART (and thus a connected PC over SLIP) diff --git a/examples/sensinode/blink-hello.c b/examples/sensinode/blink-hello.c deleted file mode 100644 index 80d2fb9ad..000000000 --- a/examples/sensinode/blink-hello.c +++ /dev/null @@ -1,62 +0,0 @@ -/* This is a very simple hello_world program. - * It aims to demonstrate the co-existence of two processes: - * One of them prints a hello world message and the other blinks the LEDs - * - * It is largely based on hello_world in $(CONTIKI)/examples/sensinode - * - * Author: George Oikonomou - */ - -#include "contiki.h" -#include "dev/leds.h" - -#include -/*---------------------------------------------------------------------------*/ -PROCESS(hello_world_process, "Hello world process"); -PROCESS(blink_process, "LED blink process"); - -AUTOSTART_PROCESSES(&hello_world_process, &blink_process); -/*---------------------------------------------------------------------------*/ -/* Implementation of the first process */ -PROCESS_THREAD(hello_world_process, ev, data) -{ - static struct etimer timer; - static int count; - - PROCESS_BEGIN(); - - etimer_set(&timer, CLOCK_CONF_SECOND * 4); - count = 0; - - while(1) { - - PROCESS_WAIT_EVENT(); - - if(ev == PROCESS_EVENT_TIMER) { - printf("Sensor says no... #%d\r\n", count); - count++; - - etimer_reset(&timer); - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ -/* Implementation of the second process */ -PROCESS_THREAD(blink_process, ev, data) -{ - static struct etimer timer; - PROCESS_BEGIN(); - - while(1) { - etimer_set(&timer, CLOCK_CONF_SECOND); - - PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); - - printf("Blink... (state %0.2X).\r\n", leds_get()); - leds_toggle(LEDS_GREEN); - } - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/border-router/Makefile b/examples/sensinode/border-router/Makefile deleted file mode 100644 index 18ae8b86c..000000000 --- a/examples/sensinode/border-router/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N601,PROJECT_CONF_H - -# We need uIPv6, therefore we also need banking -HAVE_BANKING=1 -UIP_CONF_IPV6=1 -UIP_CONF_RPL=1 - -PROJECT_SOURCEFILES += slip-bridge.c - -CONTIKI_PROJECT = border-router -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. - -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/border-router/README.md b/examples/sensinode/border-router/README.md deleted file mode 100644 index 92900008d..000000000 --- a/examples/sensinode/border-router/README.md +++ /dev/null @@ -1,20 +0,0 @@ -border-router example for sensinode devices -=========================================== - -This example is meant to be used with tunslip6 in tools/ - -- Build the code and load it onto your node -- Connect your node to your PC over USB -- run: - - sudo ./tunslip6
    / - -This will setup tun0 on your PC over device /dev/ttyUSBx. The address argument -should contain the v6 address that you want to assign to tun0 The node will use -this address to obtain the network prefix - -For example: - - sudo ./tunslip6 aaaa::1/64 - -This will use aaaa:: / 64 as the prefix for the 15.4 network. diff --git a/examples/sensinode/cc2431-location-engine/Makefile b/examples/sensinode/cc2431-location-engine/Makefile deleted file mode 100644 index 8fc75d484..000000000 --- a/examples/sensinode/cc2431-location-engine/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740 - -# This example doesn't need code banking so we turn it off -#HAVE_BANKING=1 - -CONTIKI_PROJECT = blind-node - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. - -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/cc2431-location-engine/blind-node.c b/examples/sensinode/cc2431-location-engine/blind-node.c deleted file mode 100644 index f4c4aeacd..000000000 --- a/examples/sensinode/cc2431-location-engine/blind-node.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Example demonstrating the cc2431 location engine. - * - * This file contains code for the blind node. The blind node must be - * equipped with a cc2431 SoC (as opposed to reference nodes which - * don't need to have a Loc. Eng.) - * - * The blind node receives co-ordinates of reference nodes over - * broadcast rime. Once it has enough data (3+ reference nodes), it - * will calculate its own position. - * - * We calculate with all potential values for parameter 'n' to - * demonstrate how 'n' influences the result of the calculation. - * - * Optionally, send the result of the calculation to a collection node - * - * More information on the cc2431 Location Engine can be found in: - * - cc2431 Datasheet - * - Texas Instruments Application Note 42 - * - * \author - * George Oikonomou - - */ - -#include "contiki.h" -#include "net/rime/rime.h" -#include "cc2431_loc_eng.h" -#include "cc2430_sfr.h" - -#include -#include - -#define MAX_REF_NODES 16 /* Do not change */ - -#define SAMPLE_RSSI 100 /* Used for testing */ -#define SAMPLE_ALPHA 101 - -static struct meas_params parameters; -static struct refcoords ref_coords[MAX_REF_NODES]; - -/* Store our current location here to be transmitted to a collector node */ -static uint8_t coords[2]; - -/*---------------------------------------------------------------------------*/ -PROCESS(blindnode_bcast_rec, "Blind Node"); -AUTOSTART_PROCESSES(&blindnode_bcast_rec); -/*---------------------------------------------------------------------------*/ -/* - * This handles the calculation cycle. Returns non-zero on error, 0 on success. - * - * When we move this outside the example, we will perhaps want to pass - * struct refcoords *, struct meas_params * - * instead of exposing our own data structures. If this happens, we will need - * to add checks to our code to detect non-sane values - */ -static uint8_t -calculate() -{ - static int j, x; - uint8_t valid_rssi = 0; - - /* Turn on the Engine */ - LOCENG = LOCENG_EN; - while(!(LOCENG & LOCENG_EN)); - - /* Reference Coordinate Load Stage */ - LOCENG |= LOCENG_REFLD; - while(!(LOCENG & LOCENG_REFLD)); - - for(j = 0; j < MAX_REF_NODES; j++) { - /* Write the Reference Node x,y into the engine */ - REFCOORD = ref_coords[j].x; - REFCOORD = ref_coords[j].y; - } - - /* Reference Coordinate Load Stage Done. Proceed with measured params */ - LOCENG &= ~LOCENG_REFLD; - LOCENG |= LOCENG_PARLD; - - /* Load Parameters */ - MEASPARM = parameters.alpha; - MEASPARM = parameters.n; - MEASPARM = parameters.x_min; - MEASPARM = parameters.x_delta; - MEASPARM = parameters.y_min; - MEASPARM = parameters.y_delta; - - /* Load Neighbor RSSIs */ - for(j = 0; j < MAX_REF_NODES; j++) { - if(parameters.rssi[j] != 0) { - /* Range-check for the RSSI here, can only be in [-95 dBm , -40 dBm] - * so we only accept 80 <= rssi <= 190*/ - if(parameters.rssi[j] >= 80 && parameters.rssi[j] <= 190) { - valid_rssi++; - } - } - /* Write the value, even if it's zero */ - MEASPARM = parameters.rssi[j]; - } - - /* Done with measured parameters too */ - LOCENG &= ~LOCENG_PARLD; - - /* Only Calculate if we have 3+ reference nodes (non-zero RSSIs) */ - if(valid_rssi >= 3) { - LOCENG |= LOCENG_RUN; - } else { - LOCENG = 0; - printf("some error\n"); - return 1; - } - - /* Block on the calculation, between 50us and 13ms */ - while(!(LOCENG & LOCENG_DONE)); - - /* - * LOCX contains an offset. Remove it to obtain our actual X value. - * cc2431 datasheet, section 2.1.3 - */ - x = (LOCX - parameters.x_min + 1) % (parameters.x_delta + 1) - + parameters.x_min; - coords[0] = x; - coords[1] = LOCY; /* No offset here */ - printf("n=%2u: X=%3u, Y=%3u\n", parameters.n, LOCX, LOCY); - - /* Turn it off */ - LOCENG = 0; - - return 0; -} - -/*---------------------------------------------------------------------------*/ -/* - * We receive X, Y from reference nodes. - * We store this in location J of the ref_coords array, where J is the LSB - * of the reference node's rime address. So we can only accept data from nodes - * with rime address ending in [0 , 15] - */ -static void -broadcast_recv(struct broadcast_conn *c, const linkaddr_t *from) -{ - packetbuf_attr_t rssi; /* Careful here, this is uint16_t */ - - if(from->u8[1] < MAX_REF_NODES) { - memset(&ref_coords[from->u8[1] - 1], 0, sizeof(struct refcoords)); - - /* Obtain incoming message's RSSI from contiki */ - rssi = packetbuf_attr(PACKETBUF_ATTR_RSSI); - /* Convert RSSI to the loc. eng. format */ - parameters.rssi[from->u8[1] - 1] = (-2 * rssi); - /* Raw dump the packetbuf into the ref_coords struct */ - memcpy(&ref_coords[from->u8[1] - 1], packetbuf_dataptr(), - 2 * sizeof(uint8_t)); - } - - return; -} -/* - * Imaginary nodes to test functionality - * All nodes at 1 meter distance, rssi = -40 (80) - * Since the rssi at 1 meter = -40 (A), the blind node should think it's at - * 5,5 - */ -/*---------------------------------------------------------------------------*/ -static void -set_imaginary_ref_nodes() -{ - ref_coords[0].x = 1; - ref_coords[0].y = 5; - parameters.rssi[0] = SAMPLE_RSSI; - - ref_coords[1].x = 5; - ref_coords[1].y = 1; - parameters.rssi[1] = SAMPLE_RSSI; - - ref_coords[2].x = 5; - ref_coords[2].y = 9; - parameters.rssi[2] = SAMPLE_RSSI; - - ref_coords[3].x = 9; - ref_coords[3].y = 5; - parameters.rssi[3] = SAMPLE_RSSI; -} -/*---------------------------------------------------------------------------*/ -static const struct broadcast_callbacks broadcast_call = { broadcast_recv }; -static struct broadcast_conn broadcast; -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(blindnode_bcast_rec, ev, data) -{ - static struct etimer et; - static uint8_t n; - int i; - - PROCESS_EXITHANDLER(broadcast_close(&broadcast)); - - PROCESS_BEGIN(); - - printf("Reading Chip ID: 0x%02x\n", CHIPID); - /* Read our chip ID. If we are not cc2431, bail out */ - if(CHIPID != CC2431_CHIP_ID) { - printf("Hardware does not have a location engine. Exiting.\n"); - PROCESS_EXIT(); - } - - /* OK, we are cc2431. Do stuff */ - n = 0; - - /* Initalise our structs and parameters */ - memset(ref_coords, 0, sizeof(struct refcoords) * MAX_REF_NODES); - memset(¶meters, 0, sizeof(struct meas_params)); - - /* - * Just hard-coding measurement parameters here. - * Ideally, this should be part of a calibration mechanism - */ - parameters.alpha = SAMPLE_ALPHA; - parameters.x_min = 0; - parameters.x_delta = 255; - parameters.y_min = 0; - parameters.y_delta = 255; - - set_imaginary_ref_nodes(); - - broadcast_open(&broadcast, 129, &broadcast_call); - - while(1) { - - etimer_set(&et, CLOCK_SECOND); - - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - - /* - * With the hard-coded parameters and locations, we will calculate - * for all possible values of n [0 , 31] - */ - parameters.n = n; - calculate(); - n++; - if(n == 32) { - n = 0; - } - - /* Send our calculated location to some monitoring node */ - packetbuf_copyfrom(&coords, 2 * sizeof(uint8_t)); - broadcast_send(&broadcast); - } - PROCESS_END(); -} diff --git a/examples/sensinode/cc2431-location-engine/cc2431_loc_eng.h b/examples/sensinode/cc2431-location-engine/cc2431_loc_eng.h deleted file mode 100644 index b5489797c..000000000 --- a/examples/sensinode/cc2431-location-engine/cc2431_loc_eng.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Header file used by the example demonstrating the cc2431 location - * engine. - * - * This file contains declarations of the location engine registers and - * the LOCENG register bits. It also contains some data structures used - * to store calculation parameters and reference node coordinates. - * - * This file only needs to be included bye the blind node code file. - * - * More information on the cc2431 Location Engine can be found in: - * - cc2431 Datasheet - * - K. Aamodt, "CC2431 Location Engine", Texas Instruments Application - * Note 42. - * - * \author - * George Oikonomou - - */ - -#include "8051def.h" -#include /* For syntax parsers */ - -/* Location Engine Registers on the cc2431 */ -__xdata __at (0xDF55) unsigned char REFCOORD; -__xdata __at (0xDF56) unsigned char MEASPARM; -__xdata __at (0xDF57) unsigned char LOCENG; -__xdata __at (0xDF58) unsigned char LOCX; -__xdata __at (0xDF59) unsigned char LOCY; - -/* LOCENG Register Bits */ -#define LOCENG_RUN 0x01 -#define LOCENG_REFLD 0x02 -#define LOCENG_PARLD 0x04 -#define LOCENG_DONE 0x08 -#define LOCENG_EN 0x10 - -/* cc2431 chips report 0x89 when the CHIPID register is read */ -#define CC2431_CHIP_ID 0x89 - -/* - * Struct for the Calculation Parameters. - * Values stored here feed the MEASPARM register. - * - * Values should be stored here in Location Engine format: - * RSSI: 0.5 Precision, without the minus sign. All 16 must be used. Use 0 - * to reduce the number of ref. nodes used in the calculation. - * Value range [-95 dBm , -40 dBm] - * A: 0.5 Precision. Value range [30.0 , 50.0] (Thus [60 , 100] decimal) - * n: Use the n Index value [0 , 31] - See cc2431 datasheet, Table 2. - * delta: Must be present. If we want the calculation to be unrestricted, - * use 0xFF - * - */ -struct meas_params { - uint8_t alpha; - uint8_t n; - uint8_t x_min; - uint8_t x_delta; - uint8_t y_min; - uint8_t y_delta; - uint8_t rssi[16]; -}; - -/* - * Store the reference node coordinates here. - * This will feed REFCOORD. - * - * Values should be stored here in Location Engine format: - * 2 LS bits for the fractional part, 0.25 precision - * 6 MS bits for the integral part. - * Value range [0 , 63.75] (thus [0 , 255]) - */ -struct refcoords { - uint8_t x; - uint8_t y; -}; diff --git a/examples/sensinode/disco/Makefile b/examples/sensinode/disco/Makefile deleted file mode 100644 index f95b14023..000000000 --- a/examples/sensinode/disco/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740 - -HAVE_BANKING=1 -UIP_CONF_IPV6=1 -UIP_CONF_RPL=1 -OFFSET_FIRMWARE=1 - -CONTIKI_PROJECT = disco-example - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. - -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/energy-scan/Makefile b/examples/sensinode/energy-scan/Makefile deleted file mode 100644 index 9020155e3..000000000 --- a/examples/sensinode/energy-scan/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740,PROJECT_CONF_H - -PROJECT_SOURCEFILES += stub-rdc.c - -CONTIKI_PROJECT = energy-scan - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. - -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/event-post/Makefile b/examples/sensinode/event-post/Makefile deleted file mode 100644 index 15113d249..000000000 --- a/examples/sensinode/event-post/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740 - -# This example doesn't need code banking so we turn it off -#HAVE_BANKING=1 - -CONTIKI_PROJECT = event-post - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. - -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/event-post/event-post.c b/examples/sensinode/event-post/event-post.c deleted file mode 100644 index 7a091cfa7..000000000 --- a/examples/sensinode/event-post/event-post.c +++ /dev/null @@ -1,98 +0,0 @@ -/* This file demonstrates the interaction between two processes via events. - * - * - "Sensor process": Throws an event periodically. This can be for example a - * sensor value. - * - "Print process" : Waits for events from "Sensor" and prints a message when - * an event occurs (e.g. prints the sensor value) - * - * This example is derived from the contiki code examples for the WSN430 - * (SensTools - Inria: http://senstools.gforge.inria.fr/) - * - * Author: George Oikonomou - */ - -#include "contiki.h" -//#include "dev/leds.h" -#include -#include -#include "event-post.h" - -/* This is our event type */ -static process_event_t event_data_ready; -/*---------------------------------------------------------------------------*/ -/* Declare the two processes here */ -PROCESS(sensor_process, "Sensor process"); -PROCESS(print_process, "Print process"); - -AUTOSTART_PROCESSES(&sensor_process, &print_process); -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(sensor_process, ev, data) -{ - static struct etimer timer; - static struct event_struct es; - - PROCESS_BEGIN(); - - es.s_val = SHRT_MAX - 2; - es.i_val = INT_MAX - 2; - es.l_val = LONG_MAX - 2; - es.ll_val = LONG_MAX - 2; - es.u8_val = UCHAR_MAX - 2; - es.u16_val = USHRT_MAX - 2; - es.u32_val = ULONG_MAX - 2; - - event_data_ready = process_alloc_event(); - - printf("Contiki allocated event ID %d.\r\n", event_data_ready); - - etimer_set(&timer, CLOCK_CONF_SECOND * 2); - - while(1) { - printf("Sensor process: Wait for timer event...\r\n"); - - PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); - - printf("Sensor Process: Incrementing values...\r\n"); - es.s_val++; - es.i_val++; - es.l_val++; - es.ll_val++; - es.u8_val++; - es.u16_val++; - es.u32_val++; - - printf("Sensor Process: Generating 'Data Ready' event.\r\n"); - process_post(&print_process, event_data_ready, &es); - - etimer_reset(&timer); - - } - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ -/* Implementation of "Print Process" */ -PROCESS_THREAD(print_process, ev, data) -{ - - struct event_struct *sd; - - PROCESS_BEGIN(); - - while(1) { - - PROCESS_WAIT_EVENT_UNTIL(ev == event_data_ready); - - sd = data; - printf("Print Process - Data Ready:\r\n"); - printf(" s: %d\r\n", sd->s_val); - printf(" i: %d\r\n", sd->i_val); - printf(" l: %ld\r\n", sd->l_val); - printf(" ll: %lld\r\n", sd->ll_val); - printf(" u8: %u\r\n", sd->u8_val); - printf(" u16: %u\r\n", sd->u16_val); - printf(" u32: %lu\r\n", sd->u32_val); - - } - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/event-post/event-post.h b/examples/sensinode/event-post/event-post.h deleted file mode 100644 index 650d38b4a..000000000 --- a/examples/sensinode/event-post/event-post.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * event-post.h - * Header file for the event_post example - * - * Created on: 30 Mar 2010 - * Author: George Oikonomou - */ - -#ifndef EVENT_POST_H_ -#define EVENT_POST_H_ - -struct event_struct { - short s_val; - int i_val; - long l_val; - long long ll_val; - uint8_t u8_val; - uint16_t u16_val; - uint32_t u32_val; -}; - -#endif /* EVENT_POST_H_ */ diff --git a/examples/sensinode/sensors-ipv6/Makefile b/examples/sensinode/sensors-ipv6/Makefile deleted file mode 100644 index 608de5c0d..000000000 --- a/examples/sensinode/sensors-ipv6/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740,PROJECT_CONF_H - -# This example won't fit in flash without banking so we turn it on -HAVE_BANKING=1 -UIP_CONF_IPV6=1 - -CONTIKI_SOURCEFILES += sensors-driver.c - -CONTIKI_PROJECT = sensors-ipv6 -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. - -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/sensors-ipv6/sensors-driver.c b/examples/sensinode/sensors-ipv6/sensors-driver.c deleted file mode 100644 index c3e90a13b..000000000 --- a/examples/sensinode/sensors-ipv6/sensors-driver.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * This file handles the sensor readings and float conversions - * for sensors-example. We keep this separate in order to place it - * to a higher BANK. - * - * Bankable - * - * \author - * George Oikonomou - - */ - -#include "contiki-conf.h" -#include "uip.h" /* for htons / htonl */ -#include "dev/leds.h" -#if CONTIKI_TARGET_SENSINODE -#include "dev/sensinode-sensors.h" -#include "debug.h" -#endif - -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif -#include -#include - -#define SENSOR_OK 0 -#define SENSOR_ADC_OFF -1 -#define SENSOR_UNKNOWN -2 - -/* Request Bits */ -#define REQUEST_BIT_P0_GET 0x0400 -#define REQUEST_BIT_L2_SET 0x0200 -#define REQUEST_BIT_L1_SET 0x0100 -#define REQUEST_BIT_LED_GET 0x0080 -#define REQUEST_BIT_ACC 0x0040 -#define REQUEST_BIT_BAT 0x0020 -#define REQUEST_BIT_VDD 0x0010 -#define REQUEST_BIT_TEMP 0x0008 -#define REQUEST_BIT_LIGHT 0x0004 -#define REQUEST_BIT_UPTIME 0x0002 -#define REQUEST_BIT_CHIPID 0x0001 - -/*---------------------------------------------------------------------------*/ -int8_t -read_sensor(char *rs) -{ - /* Sensor Values */ - static int rv; - static struct sensors_sensor *sensor; - - /* Those 3 variables are only used for debugging */ -#if DEBUG - static float sane = 0; - static int dec; - static float frac; -#endif - uint16_t r; - uint8_t len = 0; - - sensor = sensors_find(ADC_SENSOR); - if(!sensor) { - PRINTF("ADC not found\n"); - return (SENSOR_ADC_OFF); - } - - /* Fetch the request bytes */ - memcpy(&r, rs, 2); - r = uip_ntohs(r); - PRINTF("R=%u\n", r); - - if(r & REQUEST_BIT_CHIPID) { - uint8_t chipid = CHIPID; - memcpy(rs + len, &chipid, sizeof(chipid)); - len += sizeof(chipid); - PRINTF("ChipID=0x%02x\n", chipid); - } - if(r & REQUEST_BIT_UPTIME) { - /* Uptime */ - unsigned long l; - - l = uip_htonl(clock_seconds()); - memcpy(rs + len, &l, sizeof(l)); - len += sizeof(l); - PRINTF("Uptime=%lu secs\n", uip_ntohl(l)); - } - if(r & REQUEST_BIT_LIGHT) { - rv = sensor->value(ADC_SENSOR_TYPE_LIGHT); - if(rv != -1) { -#if DEBUG - sane = (float)(rv * 0.4071); - dec = sane; - frac = sane - dec; - PRINTF(" Light=%d.%02ulux (%d)\n", dec, (unsigned int)(frac * 100), rv); -#endif - memcpy(rs + len, &rv, sizeof(rv)); - len += sizeof(rv); - } - } - if(r & REQUEST_BIT_TEMP) { - rv = sensor->value(ADC_SENSOR_TYPE_TEMP); - if(rv != -1) { -#if DEBUG - sane = ((rv * 0.61065 - 773) / 2.45); - dec = sane; - frac = sane - dec; - PRINTF(" Temp=%d.%02u C (%d)\n", dec, (unsigned int)(frac * 100), rv); -#endif - memcpy(rs + len, &rv, sizeof(rv)); - len += sizeof(rv); - } - } - if(r & (REQUEST_BIT_VDD | REQUEST_BIT_BAT)) { - /* We want VDD for both cases */ - rv = sensor->value(ADC_SENSOR_TYPE_VDD); - if(rv != -1) { -#if DEBUG - sane = rv * 3.75 / 2047; - dec = sane; - frac = sane - dec; - PRINTF("Supply=%d.%02uV (%d)\n", dec, (unsigned int)(frac * 100), rv); - /* Store rv temporarily in dec so we can use it for the battery */ - dec = rv; -#endif - memcpy(rs + len, &rv, sizeof(rv)); - len += sizeof(rv); - } - /* And then carry on with battery if needed */ - if(r & REQUEST_BIT_BAT) { - rv = sensor->value(ADC_SENSOR_TYPE_BATTERY); - if(rv != -1) { -#if DEBUG - sane = (11.25 * rv * dec) / (0x7FE002); - dec = sane; - frac = sane - dec; - PRINTF(" Batt.=%d.%02uV (%d)\n", dec, (unsigned int)(frac * 100), rv); -#endif - memcpy(rs + len, &rv, sizeof(rv)); - len += sizeof(rv); - } - } - } - if(r & REQUEST_BIT_ACC) { - rv = sensor->value(ADC_SENSOR_TYPE_ACC_X); - if(rv != -1) { -#if DEBUG - sane = ((rv * 3.75 / 2047) - 1.65) / 0.44; - dec = sane; - frac = sane - dec; - frac = (frac < 0) ? -frac : frac; - - PRINTF(" AccX="); - if(sane < 0 && dec == 0) { - PRINTF('-'); - } - PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac * 100), rv); -#endif - memcpy(rs + len, &rv, sizeof(rv)); - len += sizeof(rv); - } - rv = sensor->value(ADC_SENSOR_TYPE_ACC_Y); - if(rv != -1) { -#if DEBUG - sane = ((rv * 3.75 / 2047) - 1.65) / 0.44; - dec = sane; - frac = sane - dec; - frac = (frac < 0) ? -frac : frac; - PRINTF(" AccY="); - if(sane < 0 && dec == 0) { - PRINTF('-'); - } - PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac * 100), rv); -#endif - memcpy(rs + len, &rv, sizeof(rv)); - len += sizeof(rv); - } - rv = sensor->value(ADC_SENSOR_TYPE_ACC_Z); - if(rv != -1) { -#if DEBUG - sane = ((rv * 3.75 / 2047) - 1.65) / 0.44; - dec = sane; - frac = sane - dec; - frac = (frac < 0) ? -frac : frac; - PRINTF(" AccZ="); - if(sane < 0 && dec == 0) { - PRINTF('-'); - } - PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac * 100), rv); -#endif - memcpy(rs + len, &rv, sizeof(rv)); - len += sizeof(rv); - } - } - if(r & REQUEST_BIT_L1_SET) { - leds_toggle(LEDS_GREEN); - } - if(r & REQUEST_BIT_L2_SET) { - leds_toggle(LEDS_RED); - } - if(r & REQUEST_BIT_LED_GET) { - uint8_t leds = leds_get(); - memcpy(rs + len, &leds, sizeof(leds)); - len += sizeof(leds); - PRINTF(" LED 2=%u\n", leds); - } - if(r & REQUEST_BIT_P0_GET) { - uint8_t p0 = P0_3; - memcpy(rs + len, &p0, sizeof(p0)); - len += sizeof(p0); - } - return len; -} diff --git a/examples/sensinode/sensors-ipv6/sensors-ipv6.c b/examples/sensinode/sensors-ipv6/sensors-ipv6.c deleted file mode 100644 index 1b563975b..000000000 --- a/examples/sensinode/sensors-ipv6/sensors-ipv6.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Example to demonstrate-test the sensors functionality on - * sensinode/cc2430 devices. - * - * A UDP/IPv6 process waits for requests from a monitoring station - * and responds with sensor values. - * - * The message exchange is based on a custom protocol. - * Check sensors-driver.c for protocol details. - * - * \author - * George Oikonomou - - */ - -#include "contiki.h" -#include "contiki-lib.h" -#include "contiki-net.h" - -#include - -#define DEBUG DEBUG_NONE -#include "net/ip/uip-debug.h" -#include "dev/watchdog.h" -#include "dev/leds.h" -#include "net/rpl/rpl.h" -#include - -#if CONTIKI_TARGET_SENSINODE -#include "debug.h" -#include "dev/sensinode-sensors.h" -#else -#define putstring(s) -#endif - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) - -#define MAX_PAYLOAD_LEN 120 - -static struct uip_udp_conn *server_conn; -static char buf[MAX_PAYLOAD_LEN]; -static uint16_t len; - -#define SERVER_PORT 60000 - -#define SENSOR_OK 0 -#define SENSOR_ADC_OFF 1 -#define SENSOR_UNKNOWN 2 - -int8_t read_sensor(char *rs); -/*---------------------------------------------------------------------------*/ -extern const struct sensors_sensor adc_sensor; -/*---------------------------------------------------------------------------*/ -PROCESS(udp_server_process, "UDP server process"); -AUTOSTART_PROCESSES(&udp_server_process); -/*---------------------------------------------------------------------------*/ -static void -tcpip_handler(void) -{ - memset(buf, 0, MAX_PAYLOAD_LEN); - - if(uip_newdata()) { - len = uip_datalen(); - memcpy(buf, uip_appdata, len); - PRINTF("%u bytes from [", len); - PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("]:%u\n", UIP_HTONS(UIP_UDP_BUF->srcport)); - len = read_sensor(buf); - if(len) { - server_conn->rport = UIP_UDP_BUF->srcport; - uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr); - uip_udp_packet_send(server_conn, buf, len); - PRINTF("Sent %u bytes\n", len); - } - - /* Restore server connection to allow data from any node */ - uip_create_unspecified(&server_conn->ripaddr); - server_conn->rport = 0; - } - return; -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(udp_server_process, ev, data) -{ -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - static struct sensors_sensor *b1; - static struct sensors_sensor *b2; -#endif - - PROCESS_BEGIN(); - putstring("Starting UDP server\n"); - -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - putstring("Button X: Toggle LED X\n"); -#endif - - server_conn = udp_new(NULL, UIP_HTONS(0), NULL); - udp_bind(server_conn, UIP_HTONS(SERVER_PORT)); - -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - b1 = sensors_find(BUTTON_1_SENSOR); - b2 = sensors_find(BUTTON_2_SENSOR); -#endif - - while(1) { - PROCESS_YIELD(); - if(ev == tcpip_event) { - tcpip_handler(); -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - } else if(ev == sensors_event && data != NULL) { - if(data == b1) { - leds_toggle(LEDS_GREEN); - } else if(data == b2) { - leds_toggle(LEDS_RED); - } -#endif /* (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) */ - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/sensors/Makefile b/examples/sensinode/sensors/Makefile deleted file mode 100644 index 90c05ae80..000000000 --- a/examples/sensinode/sensors/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740 - -# This example doesn't need code banking so we turn it off -#HAVE_BANKING=1 - -CONTIKI_PROJECT = sensors-example - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. - -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/sensors/sensors-example.c b/examples/sensinode/sensors/sensors-example.c deleted file mode 100644 index 4df6a7ac3..000000000 --- a/examples/sensinode/sensors/sensors-example.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Example to demonstrate-test the sensors functionality on - * sensinode/cc2430 devices. - * - * B1 turns L2 on and off. - * B2 reboots the node via the watchdog. - * - * The node takes readings from the various sensors every x seconds and - * prints out the results. - * - * We use floats here to translate the AD conversion results to - * meaningful values. However, our printf does not have %f support so - * we use an ugly hack to print out the value by extracting the integral - * part and then the fractional part. Don't try this at home. - * - * Temperature: - * Math is correct, the sensor needs calibration per device. - * I currently use default values for the math which may result in - * very incorrect values in degrees C. - * See TI Design Note DN102 about the offset calibration. - * - * Supply Voltage (VDD) and Battery Sensor: - * For VDD, math is correct, conversion is correct. See DN101 for details if - * interested. - * Battery reports different values when we run it many times - * in succession. The cause is unknown. - * I am fairly confident that I have captured the connections on the - * device correctly. I am however accepting input/feedback - * - * Light Sensor (Vishay Semiconductors TEPT4400): - * I am uncertain about the math. This needs testing. All I know is - * that 600lux = 0.9V and that the relation is linear. See inline for - * more details - * - * Accelerometer (Freescale Semiconductor MMA7340L): - * Math is correct but the sensor needs calibration. I've not - * attempted one cause the reported values differ per device. - * Place the N740 with the logo facing down to get 1g on the Z axis. - * Place the antenna side facing down to get 1g on the Y axis - * Place the N740 on its longer side while looking at the antenna and - * the D connector. Antenna on the bottom, D connector on the top. - * This should give you 1g on the X axis. - * - * Make sure you enable/disable things in contiki-conf.h - * - * \author - * George Oikonomou - - */ - -#include "contiki.h" -#include "contiki-conf.h" -#include "net/rime/rime.h" -#include "dev/leds.h" -#include "dev/watchdog.h" -#include "lib/random.h" - -#if CONTIKI_TARGET_SENSINODE -#include "dev/sensinode-sensors.h" -#else -#include "lib/sensors.h" -#endif - -#define DEBUG 1 -#if DEBUG -#include -#if CONTIKI_TARGET_SENSINODE -#include "debug.h" -#endif /* CONTIKI_TARGET_SENSINODE */ -#define PRINTF(...) printf(__VA_ARGS__) -#else /* DEBUG */ -/* We overwrite (read as annihilate) all output functions here */ -#define PRINTF(...) -#define putstring(...) -#define putchar(...) -#endif /* DEBUG */ - - -#define SEND_BATTERY_INFO 0 -#if SEND_BATTERY_INFO -#include "sensors-example.h" -static void -bc_rx(struct broadcast_conn *c, const linkaddr_t *from) -{ - return; -} - -static const struct broadcast_callbacks bc_cb = { bc_rx }; -static struct broadcast_conn bc_con; -#endif - -#if BUTTON_SENSOR_ON -extern const struct sensors_sensor button_1_sensor, button_2_sensor; -#endif - -/*---------------------------------------------------------------------------*/ -PROCESS(sensors_test_process, "Sensor Test Process"); -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) -PROCESS(buttons_test_process, "Button Test Process"); -AUTOSTART_PROCESSES(&sensors_test_process, &buttons_test_process); -#else -AUTOSTART_PROCESSES(&sensors_test_process); -#endif -/*---------------------------------------------------------------------------*/ -#if BUTTON_SENSOR_ON -PROCESS_THREAD(buttons_test_process, ev, data) -{ - struct sensors_sensor *sensor; - - PROCESS_BEGIN(); - - while(1) { - - PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event); - - /* If we woke up after a sensor event, inform what happened */ - sensor = (struct sensors_sensor *)data; - if(sensor == &button_1_sensor) { - leds_toggle(LEDS_GREEN); - } else if(sensor == &button_2_sensor) { - watchdog_reboot(); - } - } - - PROCESS_END(); -} -#endif -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(sensors_test_process, ev, data) -{ - static struct etimer et; -#if SEND_BATTERY_INFO - /* Node Time */ - static struct sensor_data sd; -#endif - - /* Sensor Values */ - static int rv; - static struct sensors_sensor *sensor; - static float sane = 0; - static int dec; - static float frac; - -#if SEND_BATTERY_INFO - PROCESS_EXITHANDLER(broadcast_close(&bc_con);) -#endif - - PROCESS_BEGIN(); - - putstring("========================\n"); - putstring("Starting Sensor Example.\n"); - putstring("========================\n"); - -#if SEND_BATTERY_INFO - broadcast_open(&bc_con, BATTERY_RIME_CHANNEL, &bc_cb); -#endif - - /* Set an etimer. We take sensor readings when it expires and reset it. */ - etimer_set(&et, CLOCK_SECOND * 2); - - while(1) { - - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - - /* - * Request some ADC conversions - * Return value -1 means sensor not available or turned off in conf - */ - sensor = sensors_find(ADC_SENSOR); - if(sensor) { - putstring("------------------\n"); - leds_on(LEDS_RED); - /* - * Temperature: - * Using 1.25V ref. voltage (1250mV). - * Typical Voltage at 0°C : 743 mV - * Typical Co-efficient : 2.45 mV/°C - * Offset at 25°C : 30 (this varies and needs calibration) - * - * Thus, at 12bit resolution: - * - * ADC x 1250 / 2047 - (743 + 30) 0.61065 x ADC - 773 - * T = ------------------------------ ~= ------------------- °C - * 2.45 2.45 - */ - rv = sensor->value(ADC_SENSOR_TYPE_TEMP); - if(rv != -1) { - sane = ((rv * 0.61065 - 773) / 2.45); - dec = sane; - frac = sane - dec; - PRINTF(" Temp=%d.%02u C (%d)\n", dec, (unsigned int)(frac * 100), - rv); - } - /* - * Accelerometer: Freescale Semiconductor MMA7340L - * Using 1.25V ref. voltage. - * Sensitivity: 0.44 mV/g in ±3g mode. - * 0.1175 mV/g in ±11g mode. - * Typical 0g Vout = 1.65V (both modes, Vdd=3.3V, T=25°C) - * ADC Input Voltage is 1/3 Accelerometer Output Voltage - * - * +3g -> 2.97V Acc Out -> 0.9900V ADC Input -> 1621 - * +1g -> 2.09V Acc Out -> 0.6967V ADC Input -> 1141 - * 0g -> 1.65V Acc Out -> 0.5500V ADC Input -> 901 - * -1g -> 1.21V Acc Out -> 0.4033V ADC Input -> 660 - * -3g -> 0.33V Acc Out -> 0.1100V ADC Input -> 180 - * - * Thus, at 12bit resolution, ±3g mode: - * ADC x 1.25 x 3 - * Vout = -------------- V - * 2047 - * - * Vout - 0g Vout - 1.65 - * Acc = ----------- = ----------- g - * Sensitivity 0.44 - * - * Similar calc. for ±11g with 0.1175V increments - * - * This is only valid if you set ACC_SENSOR_CONF_GSEL 0 in contiki-conf.h - */ - rv = sensor->value(ADC_SENSOR_TYPE_ACC_X); - if(rv != -1) { - sane = ((rv * 3.75 / 2047) - 1.65) / 0.44; - dec = sane; - frac = sane - dec; - frac = (frac < 0) ? -frac : frac; - - /* - * This will fail for numbers like -0.xyz (since there is no such thing - * as -0. We manually add a minus sign in the printout if sane is neg - * and dec is 0. - * This is the wrong way to do it... - */ - putstring(" AccX="); - if(sane < 0 && dec == 0) { - putchar('-'); - } - PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac * 100), rv); - } - rv = sensor->value(ADC_SENSOR_TYPE_ACC_Y); - if(rv != -1) { - sane = ((rv * 3.75 / 2047) - 1.65) / 0.44; - dec = sane; - frac = sane - dec; - frac = (frac < 0) ? -frac : frac; - putstring(" AccY="); - if(sane < 0 && dec == 0) { - putchar('-'); - } - PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac * 100), rv); - } - rv = sensor->value(ADC_SENSOR_TYPE_ACC_Z); - if(rv != -1) { - sane = ((rv * 3.75 / 2047) - 1.65) / 0.44; - dec = sane; - frac = sane - dec; - frac = (frac < 0) ? -frac : frac; - putstring(" AccZ="); - if(sane < 0 && dec == 0) { - putchar('-'); - } - PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac * 100), rv); - } - /* - * Light: Vishay Semiconductors TEPT4400 - * Using 1.25V ref. voltage. - * For 600 Lux illuminance, the sensor outputs 1mA current (0.9V ADC In) - * 600 lux = 1mA output => 1473 ADC value at 12 bit resolution) - * - * Thus, at 12bit resolution: - * 600 x 1.25 x ADC - * Lux = ---------------- ~= ADC * 0.4071 - * 2047 x 0.9 - */ - rv = sensor->value(ADC_SENSOR_TYPE_LIGHT); - if(rv != -1) { - sane = (float)(rv * 0.4071); - dec = sane; - frac = sane - dec; - PRINTF(" Light=%d.%02ulux (%d)\n", dec, (unsigned int)(frac * 100), - rv); - } - /* - * Power Supply Voltage. - * Using 1.25V ref. voltage. - * AD Conversion on VDD/3 - * - * Thus, at 12bit resolution: - * - * ADC x 1.25 x 3 - * Supply = -------------- V - * 2047 - */ - rv = sensor->value(ADC_SENSOR_TYPE_VDD); -#if SEND_BATTERY_INFO - sd.vdd = rv; -#endif - if(rv != -1) { - sane = rv * 3.75 / 2047; - dec = sane; - frac = sane - dec; - PRINTF("Supply=%d.%02uV (%d)\n", dec, (unsigned int)(frac * 100), rv); - /* Store rv temporarily in dec so we can use it for the battery */ - dec = rv; - } - /* - * Battery Voltage - Only 2/3 of the actual voltage reach the ADC input - * Using 1.25V ref. voltage would result in 2047 AD conversions all the - * time since ADC-in would be gt 1.25. We thus use AVDD_SOC as ref. - * - * Thus, at 12bit resolution (assuming VDD is 3.3V): - * - * ADC x 3.3 x 3 ADC x 4.95 - * Battery = ------------- = ---------- V - * 2047 x 2 2047 - * - * Replacing the 3.3V with an ADC reading of the actual VDD would yield - * better accuracy. See monitor-node.c for an example. - * - * 3 x ADC x VDD x 3.75 ADC x VDD x 11.25 - * Battery = -------------------- = ----------------- V - * 2 x 2047 x 2047 0x7FE002 - * - */ - rv = sensor->value(ADC_SENSOR_TYPE_BATTERY); - if(rv != -1) { - /* Instead of hard-coding 3.3 here, use the latest VDD (stored in dec) - * (slightly inaccurate still, but better than crude 3.3) */ - sane = (11.25 * rv * dec) / (0x7FE002); - dec = sane; - frac = sane - dec; - PRINTF(" Batt.=%d.%02uV (%d)\n", dec, (unsigned int)(frac * 100), rv); -#if SEND_BATTERY_INFO - sd.bat = rv; - packetbuf_copyfrom(&sd, sizeof(sd)); - broadcast_send(&bc_con); -#endif - } - leds_off(LEDS_RED); - } - etimer_reset(&et); - } - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/serial-flash/Makefile b/examples/sensinode/serial-flash/Makefile deleted file mode 100644 index b8c8d2fbe..000000000 --- a/examples/sensinode/serial-flash/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740 - -CONTIKI_PROJECT = flash - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/serial-flash/flash.c b/examples/sensinode/serial-flash/flash.c deleted file mode 100644 index 4ac6048c9..000000000 --- a/examples/sensinode/serial-flash/flash.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * - * Example demonstrating the flash memory functionality on - * sensinode N740s - * - * \author - * George Oikonomou - - */ - -#include "contiki.h" -#include "dev/leds.h" -#include "cc2430_sfr.h" -#include "8051def.h" -#include "dev/m25p16.h" -#include "dev/n740.h" - -#define DEBUG 1 -#if DEBUG -#include -#include "debug.h" -#define PRINTF(...) printf(__VA_ARGS__) -#define PUTBIN(b) putbin(b) -#else -#define PRINTF(...) -#define PUTBIN(b) -#endif - -static struct m25p16_rdid id; - -#define USE_SECTOR 0x10 -#define MAX_READ_CHUNK 10 -static uint8_t r_addr[3]; /* Read address: {USE_SECTOR, 0, 0} */ -static uint8_t d_buf[MAX_READ_CHUNK]; -static uint8_t rv; -static uint8_t counter; -/*---------------------------------------------------------------------------*/ -PROCESS(serial_flash_process, "Serial Flash example"); -AUTOSTART_PROCESSES(&serial_flash_process); -/*---------------------------------------------------------------------------*/ -static void -rdsr() -{ - rv = 0; - - n740_analog_deactivate(); - rv = m25p16_rdsr(); - n740_analog_activate(); - - PRINTF("RDSR: "); - putbin(rv); - PRINTF("\n"); -} -/*---------------------------------------------------------------------------*/ -static void -rdid() -{ - uint8_t i; - memset(&id, 0, sizeof(struct m25p16_rdid)); - - n740_analog_deactivate(); - m25p16_rdid(&id); - n740_analog_activate(); - - PRINTF("RDID: 0x%02x\n", id.man_id); - PRINTF("Type: 0x%02x\n", id.mem_type); - PRINTF("Size: 0x%02x\n", id.mem_size); - PRINTF("ULen: 0x%02x\n", id.uid_len); - PRINTF(" UID:"); - for(i = 0; i < id.uid_len; i++) { - PRINTF(" %02x", id.uid[i]); - } - PRINTF("\n"); -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(serial_flash_process, ev, data) -{ - static struct etimer et; - uint8_t i; - - PROCESS_BEGIN(); - - PRINTF("Start\n"); - - memset(r_addr, 0, 3); - r_addr[0] = USE_SECTOR; - counter = 1; - - while(1) { - - /* Delay */ - etimer_set(&et, CLOCK_SECOND * 2); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - - leds_on(LEDS_GREEN); - - if(counter == 0) { - n740_analog_deactivate(); - rv = m25p16_rdsr(); - n740_analog_activate(); - /* If counter==0, we started Bulk Erasing earlier. Check if we still are */ - if(rv & M25P16_SR_WIP) { - PRINTF("Yield [%02x]\n", rv); - } else { - counter = 1; - } - } - if(counter) { - /* - * Take us out of Deep Power Down - On first power-on, the device will - * go to stand by mode (which is not DP). However, we drop to DP at the - * end of every loop. RES must be 0x14. This is the old style signature - * and is only still there for backward compatibility. - */ - n740_analog_deactivate(); - rv = m25p16_res_res(); - n740_analog_activate(); - - PRINTF(" RES: 0x%02x\n", rv); - - n740_analog_deactivate(); - rv = M25P16_WIP(); - n740_analog_activate(); - - PRINTF("========\n"); - memset(d_buf, 0, MAX_READ_CHUNK); - - - /* - * Read Device ID: Return values must be: - * man_id: 0x20 (Numonyx) - * mem_type: 0x20 - * mem_size: 0x15 (2 ^ 0x15 bytes = 2MB) - * uid_len: number of bytes in UID - * uid: Either all zeroes or a customized factory data content - * */ - rdid(); - - /* Check the value of our Status Register (SR) */ - rdsr(); - - /* Enable Write: Set Bit 1 in the SR to 1 (bit WEL) */ - PRINTF("WREN\n"); - n740_analog_deactivate(); - m25p16_wren(); - n740_analog_activate(); - - /* Confirm: SR & 0x02 must be 1 */ - rdsr(); - - /* Disable the WEL bit */ - PRINTF("WRDI\n"); - n740_analog_deactivate(); - m25p16_wrdi(); - n740_analog_activate(); - - /* Confirm: SR & 0x02 must be 0 */ - rdsr(); - - /* Write something to the SR. We don't need to explicitly set WEL, wrsr() - * will do it for us. When the cycle ends, WEL will go low */ - PRINTF("WRSR\n"); - n740_analog_deactivate(); - - /* For instance, let's protect sector 31 (that's the highest one) */ - m25p16_wrsr(M25P16_SR_BP0); - - /* - * While this is running, WEL should remain high and WIP (bit 0) should - * also be high. When this ends, WIP and WEL will go low. - * - * While the write is in ongoing, we can still read the SR to check the - * cycle's progress - */ - while(M25P16_WIP()); - - n740_analog_activate(); - - /* Confirm: SR & 0x02 must be 0 */ - rdsr(); - - /* Read MAX_READ_CHUNK bytes from Page 0x000000 */ - memset(d_buf, 0, MAX_READ_CHUNK); - n740_analog_deactivate(); - m25p16_read(r_addr, d_buf, MAX_READ_CHUNK); - n740_analog_activate(); - - PRINTF("READ:"); - for(i = 0; i < MAX_READ_CHUNK; i++) { - PRINTF(" %02x", d_buf[i]); - } - PRINTF("\n"); - - /* Write MAX_READ_CHUNK bytes to the same Page */ - PRINTF("WRITE\n"); - for(i = 0; i < MAX_READ_CHUNK; i++) { - d_buf[i] = i; - } - n740_analog_deactivate(); - - /* We don't need to wren() explicitly, pp() will do that for us */ - m25p16_pp(r_addr, d_buf, MAX_READ_CHUNK); - - /* Wait for the cycle */ - while(M25P16_WIP()); - - /* Trash our data buffer */ - memset(d_buf, 0, MAX_READ_CHUNK); - - PRINTF("ERASE\n"); - n740_analog_deactivate(); - - /* Bulk erase every 4 loops, sector erase otherwise */ - - /* Bulk Erase: This takes a few seconds so we can't really block on it. - * It'd be a bad thing to do and the watchdog would bark anyway. - * Bulk Erase will only be accepted if all SR_BP[2:0] == 0 */ - if((counter % 4) == 0) { - m25p16_wrsr(0); - while(M25P16_WIP()); - m25p16_be(); - counter = 0; - } else { - m25p16_se(USE_SECTOR); - while(M25P16_WIP()); - /* Drop to Deep Power Down */ - m25p16_dp(); - counter++; - } - n740_analog_activate(); - } - leds_off(LEDS_GREEN); - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/sniffer/Makefile b/examples/sensinode/sniffer/Makefile deleted file mode 100644 index 07f074069..000000000 --- a/examples/sensinode/sniffer/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N601,PROJECT_CONF_H - -PROJECT_SOURCEFILES += stub-rdc.c - -CONTIKI_PROJECT = sniffer - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. - -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/sniffer/README.md b/examples/sensinode/sniffer/README.md deleted file mode 100644 index dd3926f0a..000000000 --- a/examples/sensinode/sniffer/README.md +++ /dev/null @@ -1,15 +0,0 @@ -A very simple sniffer for sensinode devices. -============================================ - -The cc2430 RF driver supports outputting all captured packets in hexdump -format. We turn this on, and turn everything else off. We use a stub RDC driver -to make sure no incoming packet ever goes up the stack and no packet is ever -sent out. - -We only initialise the radio driver instead of the entire stack by over-riding -the default netstack.c with the one in this directory. - -You can then pipe the sniffer's output to the n601-cap util, which will convert -the hexdumps to pcap format, which can in turn be piped to wireshark. This is -handy if we want live capture of the lowpan traffic from wireshark. See the -README in n601-cap for more details diff --git a/examples/sensinode/udp-ipv6/Makefile b/examples/sensinode/udp-ipv6/Makefile deleted file mode 100644 index 2f47d11b0..000000000 --- a/examples/sensinode/udp-ipv6/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740,PROJECT_CONF_H - -# This example won't fit in flash without banking so we turn it on -HAVE_BANKING=1 -UIP_CONF_IPV6=1 -UIP_CONF_RPL=1 - -CONTIKI_SOURCEFILES += ping6.c - -CONTIKI_PROJECT = client server -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. - -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/udp-ipv6/client.c b/examples/sensinode/udp-ipv6/client.c deleted file mode 100644 index 8308d13a8..000000000 --- a/examples/sensinode/udp-ipv6/client.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -#include "contiki.h" -#include "contiki-lib.h" -#include "contiki-net.h" - -#include -#include "dev/leds.h" - -#if CONTIKI_TARGET_SENSINODE -#include "dev/sensinode-sensors.h" -#include "debug.h" -#else -#define putstring(s) -#define puthex(s) -#define putchar(s) -#endif - -#define DEBUG DEBUG_NONE -#include "net/ip/uip-debug.h" - -#define SEND_INTERVAL 2 * CLOCK_SECOND -#define MAX_PAYLOAD_LEN 40 - -static char buf[MAX_PAYLOAD_LEN]; - -/* Our destinations and udp conns. One link-local and one global */ -#define LOCAL_CONN_PORT 3001 -static struct uip_udp_conn *l_conn; -#if UIP_CONF_ROUTER -#define GLOBAL_CONN_PORT 3002 -static struct uip_udp_conn *g_conn; -#endif - -/*---------------------------------------------------------------------------*/ -PROCESS(udp_client_process, "UDP client process"); -#if BUTTON_SENSOR_ON -PROCESS_NAME(ping6_process); -AUTOSTART_PROCESSES(&udp_client_process, &ping6_process); -#else -AUTOSTART_PROCESSES(&udp_client_process); -#endif -/*---------------------------------------------------------------------------*/ -static void -tcpip_handler(void) -{ - leds_on(LEDS_GREEN); - if(uip_newdata()) { - putstring("0x"); - puthex(uip_datalen()); - putstring(" bytes response=0x"); - puthex((*(uint16_t *) uip_appdata) >> 8); - puthex((*(uint16_t *) uip_appdata) & 0xFF); - putchar('\n'); - } - leds_off(LEDS_GREEN); - return; -} -/*---------------------------------------------------------------------------*/ -static void -timeout_handler(void) -{ - static int seq_id; - struct uip_udp_conn *this_conn; - - leds_on(LEDS_RED); - memset(buf, 0, MAX_PAYLOAD_LEN); - seq_id++; - -#if UIP_CONF_ROUTER - /* evens / odds */ - if(seq_id & 0x01) { - this_conn = l_conn; - } else { - this_conn = g_conn; - } -#else - this_conn = l_conn; -#endif - - PRINTF("Client to: "); - PRINT6ADDR(&this_conn->ripaddr); - - memcpy(buf, &seq_id, sizeof(seq_id)); - - PRINTF(" Remote Port %u,", UIP_HTONS(this_conn->rport)); - PRINTF(" (msg=0x%04x), %u bytes\n", *(uint16_t *) buf, sizeof(seq_id)); - -#if SEND_TOO_LARGE_PACKET_TO_TEST_FRAGMENTATION - uip_udp_packet_send(this_conn, buf, UIP_APPDATA_SIZE); -#else /* SEND_TOO_LARGE_PACKET_TO_TEST_FRAGMENTATION */ - uip_udp_packet_send(this_conn, buf, sizeof(seq_id)); -#endif /* SEND_TOO_LARGE_PACKET_TO_TEST_FRAGMENTATION */ - leds_off(LEDS_RED); -} -/*---------------------------------------------------------------------------*/ -static void -print_local_addresses(void) -{ - int i; - uint8_t state; - - PRINTF("Client IPv6 addresses:\n"); - for(i = 0; i < UIP_DS6_ADDR_NB; i++) { - state = uip_ds6_if.addr_list[i].state; - if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state - == ADDR_PREFERRED)) { - PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); - if(state == ADDR_TENTATIVE) { - uip_ds6_if.addr_list[i].state = ADDR_PREFERRED; - } - PRINTF(" state: %u.\n", uip_ds6_if.addr_list[i].state); - } - } - return; -} -/*---------------------------------------------------------------------------*/ -#if UIP_CONF_ROUTER -static void -set_global_address(void) -{ - uip_ipaddr_t ipaddr; - - uip_ip6addr(&ipaddr, 0x2001, 0x630, 0x301, 0x6453, 0, 0, 0, 0); - uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); - uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); -} -#endif /* UIP_CONF_ROUTER */ -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(udp_client_process, ev, data) -{ - static struct etimer et; - uip_ipaddr_t ipaddr; - - PROCESS_BEGIN(); - PRINTF("UDP client process started\n"); - -#if UIP_CONF_ROUTER - set_global_address(); -#endif - - print_local_addresses(); - - uip_ip6addr(&ipaddr, 0xfe80, 0, 0, 0, 0x0215, 0x2000, 0x0002, 0x0302); - /* new connection with remote host */ - l_conn = udp_new(&ipaddr, UIP_HTONS(3000), NULL); - if(!l_conn) { - PRINTF("udp_new l_conn error.\n"); - } - udp_bind(l_conn, UIP_HTONS(LOCAL_CONN_PORT)); - - PRINTF("Link-Local connection with "); - PRINT6ADDR(&l_conn->ripaddr); - PRINTF(" local/remote port %u/%u\n", - UIP_HTONS(l_conn->lport), UIP_HTONS(l_conn->rport)); - -#if UIP_CONF_ROUTER - uip_ip6addr(&ipaddr, 0x2001, 0x630, 0x301, 0x6453, 0x0215, 0x2000, 0x0002, - 0x0302); - g_conn = udp_new(&ipaddr, UIP_HTONS(3000), NULL); - if(!g_conn) { - PRINTF("udp_new g_conn error.\n"); - } - udp_bind(g_conn, UIP_HTONS(GLOBAL_CONN_PORT)); - - PRINTF("Global connection with "); - PRINT6ADDR(&g_conn->ripaddr); - PRINTF(" local/remote port %u/%u\n", - UIP_HTONS(g_conn->lport), UIP_HTONS(g_conn->rport)); -#endif - - etimer_set(&et, SEND_INTERVAL); - - while(1) { - PROCESS_YIELD(); - if(etimer_expired(&et)) { - timeout_handler(); - etimer_restart(&et); - } else if(ev == tcpip_event) { - tcpip_handler(); - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/udp-ipv6/ping6.c b/examples/sensinode/udp-ipv6/ping6.c deleted file mode 100644 index 1acccd371..000000000 --- a/examples/sensinode/udp-ipv6/ping6.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -#include "contiki.h" -#include "contiki-lib.h" -#include "contiki-net.h" -#include -#include - -#if CONTIKI_TARGET_SENSINODE -#include "dev/sensinode-sensors.h" -#include "debug.h" -#endif - -#define DEBUG DEBUG_NONE -#include "net/ip/uip-debug.h" - -#define PING6_NB 5 -#define PING6_DATALEN 16 - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) - -static struct etimer ping6_periodic_timer; -static uint8_t count = 0; -static uip_ipaddr_t dest_addr; - -PROCESS(ping6_process, "PING6 process"); -/*---------------------------------------------------------------------------*/ -static void -ping6handler() -{ - if(count < PING6_NB) { - UIP_IP_BUF->vtc = 0x60; - UIP_IP_BUF->tcflow = 1; - UIP_IP_BUF->flow = 0; - UIP_IP_BUF->proto = UIP_PROTO_ICMP6; - UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit; - uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &dest_addr); - uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); - - UIP_ICMP_BUF->type = ICMP6_ECHO_REQUEST; - UIP_ICMP_BUF->icode = 0; - /* set identifier and sequence number to 0 */ - memset((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN, 0, 4); - /* put one byte of data */ - memset((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN, - count, PING6_DATALEN); - - - uip_len = UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN + UIP_IPH_LEN + PING6_DATALEN; - UIP_IP_BUF->len[0] = (uint8_t)((uip_len - 40) >> 8); - UIP_IP_BUF->len[1] = (uint8_t)((uip_len - 40) & 0x00FF); - - UIP_ICMP_BUF->icmpchksum = 0; - UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); - - - PRINTF("Echo Request to "); - PRINT6ADDR(&UIP_IP_BUF->destipaddr); - PRINTF(" from "); - PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("\n"); - UIP_STAT(++uip_stat.icmp.sent); - - tcpip_ipv6_output(); - - count++; - etimer_set(&ping6_periodic_timer, 3 * CLOCK_SECOND); - } else { - count = 0; - } -} - -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(ping6_process, ev, data) -{ - -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - static struct sensors_sensor *btn; -#endif - - PROCESS_BEGIN(); - PRINTF("ping6 running.\n"); - PRINTF("Button 1: 5 pings 16 byte payload.\n"); - - uip_ip6addr(&dest_addr, 0x2001, 0x470, 0x55, 0, 0x0215, 0x2000, 0x0002, - 0x0302); - count = 0; - - /* Check if we have buttons */ -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - btn = sensors_find(BUTTON_1_SENSOR); -#endif - - while(1) { - PROCESS_YIELD(); - -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - if(ev == sensors_event) { - if(data == btn && count == 0) { - ping6handler(); - } - } -#endif - if(etimer_expired(&ping6_periodic_timer)) { - ping6handler(); - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/udp-ipv6/server.c b/examples/sensinode/udp-ipv6/server.c deleted file mode 100644 index fcdc0fec8..000000000 --- a/examples/sensinode/udp-ipv6/server.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -#include "contiki.h" -#include "contiki-lib.h" -#include "contiki-net.h" - -#include - -#define DEBUG DEBUG_NONE -#include "net/ip/uip-debug.h" -#include "dev/watchdog.h" -#include "dev/leds.h" -#include "net/rpl/rpl.h" - -#if CONTIKI_TARGET_SENSINODE -#include "dev/sensinode-sensors.h" -#include "debug.h" -#else -#define putstring(s) -#endif - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) - -#define MAX_PAYLOAD_LEN 120 - -static struct uip_udp_conn *server_conn; -static char buf[MAX_PAYLOAD_LEN]; -static uint16_t len; - -#define SERVER_REPLY 1 - -/* Should we act as RPL root? */ -#define SERVER_RPL_ROOT 0 - -#if SERVER_RPL_ROOT -static uip_ipaddr_t ipaddr; -#endif -/*---------------------------------------------------------------------------*/ -extern const struct sensors_sensor adc_sensor; -/*---------------------------------------------------------------------------*/ -PROCESS(udp_server_process, "UDP server process"); -AUTOSTART_PROCESSES(&udp_server_process); -/*---------------------------------------------------------------------------*/ -static void -tcpip_handler(void) -{ - memset(buf, 0, MAX_PAYLOAD_LEN); - if(uip_newdata()) { - leds_on(LEDS_RED); - len = uip_datalen(); - memcpy(buf, uip_appdata, len); - PRINTF("%u bytes from [", len); - PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("]:%u", UIP_HTONS(UIP_UDP_BUF->srcport)); - PRINTF(" V=%u", *buf); - PRINTF(" I=%u", *(buf + 1)); - PRINTF(" T=%u", *(buf + 2)); - PRINTF(" Val=%u\n", *(uint16_t *)(buf + 3)); -#if SERVER_REPLY - uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr); - server_conn->rport = UIP_UDP_BUF->srcport; - - uip_udp_packet_send(server_conn, buf, len); - /* Restore server connection to allow data from any node */ - uip_create_unspecified(&server_conn->ripaddr); - server_conn->rport = 0; -#endif - } - leds_off(LEDS_RED); - PRINTF("sent\n"); - return; -} -/*---------------------------------------------------------------------------*/ -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON && (DEBUG==DEBUG_PRINT)) -static void -print_stats() -{ - PRINTF("tl=%lu, ts=%lu, bs=%lu, bc=%lu\n", - RIMESTATS_GET(toolong), RIMESTATS_GET(tooshort), - RIMESTATS_GET(badsynch), RIMESTATS_GET(badcrc)); - PRINTF("llrx=%lu, lltx=%lu, rx=%lu, tx=%lu\n", RIMESTATS_GET(llrx), - RIMESTATS_GET(lltx), RIMESTATS_GET(rx), RIMESTATS_GET(tx)); -} -#else -#define print_stats() -#endif -/*---------------------------------------------------------------------------*/ -static void -print_local_addresses(void) -{ - int i; - uint8_t state; - - PRINTF("Server IPv6 addresses:\n"); - for(i = 0; i < UIP_DS6_ADDR_NB; i++) { - state = uip_ds6_if.addr_list[i].state; - if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state - == ADDR_PREFERRED)) { - PRINTF(" "); - PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); - PRINTF("\n"); - if(state == ADDR_TENTATIVE) { - uip_ds6_if.addr_list[i].state = ADDR_PREFERRED; - } - } - } -} -/*---------------------------------------------------------------------------*/ -#if SERVER_RPL_ROOT -void -create_dag() -{ - rpl_dag_t *dag; - - uip_ip6addr(&ipaddr, 0x2001, 0x630, 0x301, 0x6453, 0, 0, 0, 0); - uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); - uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); - - print_local_addresses(); - - dag = rpl_set_root(RPL_DEFAULT_INSTANCE, - &uip_ds6_get_global(ADDR_PREFERRED)->ipaddr); - if(dag != NULL) { - uip_ip6addr(&ipaddr, 0x2001, 0x630, 0x301, 0x6453, 0, 0, 0, 0); - rpl_set_prefix(dag, &ipaddr, 64); - PRINTF("Created a new RPL dag with ID: "); - PRINT6ADDR(&dag->dag_id); - PRINTF("\n"); - } -} -#endif /* SERVER_RPL_ROOT */ -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(udp_server_process, ev, data) -{ -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - static const struct sensors_sensor *b1; - static const struct sensors_sensor *b2; -#endif - - PROCESS_BEGIN(); - putstring("Starting UDP server\n"); - -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - putstring("Button 1: Print RIME stats\n"); - putstring("Button 2: Reboot\n"); -#endif - -#if SERVER_RPL_ROOT - create_dag(); -#endif - - server_conn = udp_new(NULL, UIP_HTONS(0), NULL); - udp_bind(server_conn, UIP_HTONS(3000)); - - PRINTF("Listen port: 3000, TTL=%u\n", server_conn->ttl); - -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - b1 = sensors_find(BUTTON_1_SENSOR); - b2 = sensors_find(BUTTON_2_SENSOR); -#endif - - while(1) { - PROCESS_YIELD(); - if(ev == tcpip_event) { - tcpip_handler(); -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - } else if(ev == sensors_event && data != NULL) { - if(data == b1) { - print_stats(); - } else if(data == b2) { - watchdog_reboot(); - } -#endif /* (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) */ - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/servreg-hack/Makefile b/examples/servreg-hack/Makefile index 84e057391..9c528ebba 100644 --- a/examples/servreg-hack/Makefile +++ b/examples/servreg-hack/Makefile @@ -1,10 +1,9 @@ CONTIKI_PROJECT = example-servreg-client all: $(CONTIKI_PROJECT) -UIP_CONF_IPV6=1 - APPS=servreg-hack CONTIKI = ../.. +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include -include /home/user/nes/testbed-scripts/Makefile.include diff --git a/examples/servreg-hack/example-servreg-client.c b/examples/servreg-hack/example-servreg-client.c index 108d40aeb..4557fab71 100644 --- a/examples/servreg-hack/example-servreg-client.c +++ b/examples/servreg-hack/example-servreg-client.c @@ -54,7 +54,7 @@ set_global_address(void) { uip_ipaddr_t ipaddr; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); } diff --git a/examples/servreg-hack/example-servreg-server.c b/examples/servreg-hack/example-servreg-server.c index 01dd7175a..4ff70060c 100644 --- a/examples/servreg-hack/example-servreg-server.c +++ b/examples/servreg-hack/example-servreg-server.c @@ -53,7 +53,7 @@ PROCESS_THREAD(example_servreg_server_process, ev, data) PROCESS_BEGIN(); /* Set a global address. */ - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); diff --git a/examples/settings-example/Makefile b/examples/settings-example/Makefile index 540adff63..ac53960ee 100644 --- a/examples/settings-example/Makefile +++ b/examples/settings-example/Makefile @@ -2,4 +2,5 @@ CONTIKI_PROJECT = settings-example all: $(CONTIKI_PROJECT) CFLAGS += -DCONTIKI_CONF_SETTINGS_MANAGER=1 CONTIKI = ../.. +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/sky-ip/Makefile b/examples/sky-ip/Makefile index 1602cd120..795e72da0 100644 --- a/examples/sky-ip/Makefile +++ b/examples/sky-ip/Makefile @@ -2,7 +2,7 @@ CONTIKI_PROJECT = sky-webserver all: sky-webserver sky-telnet-server telnet PLATFORM_BUILD=1 # This is needed to avoid the shell to include the httpd-cfs version of the webserver APPS = webserver telnetd -CFLAGS = -DWITH_UIP=1 -I. +CFLAGS = -I. SMALL=1 DEFINES=NETSTACK_CONF_RDC=cxmac_driver,NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE=8 @@ -19,6 +19,8 @@ DEFINES=NETSTACK_CONF_RDC=cxmac_driver,NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE=8 # endif CONTIKI = ../.. +CONTIKI_WITH_IPV4 = 1 +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include sky-webserver.$(TARGET): $(OBJECTDIR)/ajax-cgi.o diff --git a/examples/sky-shell-exec/Makefile b/examples/sky-shell-exec/Makefile index f2608f905..115d67a59 100644 --- a/examples/sky-shell-exec/Makefile +++ b/examples/sky-shell-exec/Makefile @@ -7,6 +7,7 @@ DEFINES=ELFLOADER_DATAMEMORY_SIZE=0x100,ELFLOADER_TEXTMEMORY_SIZE=0x100 APPS = serial-shell CONTIKI = ../.. +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include %.shell-upload: %.ce diff --git a/examples/sky-shell-exec/sky-shell-exec.c b/examples/sky-shell-exec/sky-shell-exec.c index bab3969c0..469d824c4 100644 --- a/examples/sky-shell-exec/sky-shell-exec.c +++ b/examples/sky-shell-exec/sky-shell-exec.c @@ -34,20 +34,6 @@ #include "shell.h" #include "serial-shell.h" -#include "dev/watchdog.h" - -#include "net/rime/rime.h" -#include "cc2420.h" -#include "dev/leds.h" -#include "dev/light.h" -#include "dev/sht11/sht11.h" -#include "dev/battery-sensor.h" - -#include "net/rime/timesynch.h" - -#include -#include - /*---------------------------------------------------------------------------*/ PROCESS(sky_shell_process, "Sky Contiki shell"); AUTOSTART_PROCESSES(&sky_shell_process); diff --git a/examples/sky-shell-webserver/Makefile b/examples/sky-shell-webserver/Makefile index 224409442..6bec0ff96 100644 --- a/examples/sky-shell-webserver/Makefile +++ b/examples/sky-shell-webserver/Makefile @@ -2,11 +2,13 @@ CONTIKI_PROJECT = sky-shell-webserver all: $(CONTIKI_PROJECT) PROJECT_SOURCEFILES = webserver-nogui.c HTTPD_CFS=1 -CFLAGS = -DWITH_UIP=1 -DRESOLV_CONF_SUPPORTS_MDNS=0 +CFLAGS = -DRESOLV_CONF_SUPPORTS_MDNS=0 DEFINES=NETSTACK_MAC=nullmac_driver,NETSTACK_RDC=nullrdc_driver SMALL=1 CONTIKI = ../.. APPS = webserver serial-shell +CONTIKI_WITH_IPV4 = 1 +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include - + diff --git a/examples/sky-shell-webserver/sky-shell-webserver.c b/examples/sky-shell-webserver/sky-shell-webserver.c index 708f53d5e..f89e19ac1 100644 --- a/examples/sky-shell-webserver/sky-shell-webserver.c +++ b/examples/sky-shell-webserver/sky-shell-webserver.c @@ -40,8 +40,6 @@ #include #include -#include -#include /*---------------------------------------------------------------------------*/ PROCESS(sky_shell_process, "Sky Contiki shell w. webserver"); @@ -51,7 +49,7 @@ PROCESS_THREAD(sky_shell_process, ev, data) { PROCESS_BEGIN(); - /* WITH_UIP=1 assumes incoming SLIP serial data. + /* NETSTACK_CONF_WITH_IPV4=1 assumes incoming SLIP serial data. * We override this assumption by restoring default serial input handler. */ uart1_set_input(serial_line_input_byte); serial_line_init(); diff --git a/examples/sky-shell/Makefile b/examples/sky-shell/Makefile index f7833e36d..6e1fc09bf 100644 --- a/examples/sky-shell/Makefile +++ b/examples/sky-shell/Makefile @@ -4,6 +4,7 @@ all: $(CONTIKI_PROJECT) APPS = serial-shell powertrace collect-view CONTIKI = ../.. +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include -include /home/user/nes/testbed-scripts/Makefile.include diff --git a/examples/sky-shell/sky-upload.c b/examples/sky-shell/sky-upload.c index 703b450bc..7d4b221ac 100644 --- a/examples/sky-shell/sky-upload.c +++ b/examples/sky-shell/sky-upload.c @@ -58,7 +58,6 @@ PROCESS_THREAD(test_shell_process, ev, data) shell_coffee_init(); shell_exec_init(); shell_file_init(); - shell_netfile_init(); shell_ps_init(); shell_rime_init(); shell_rime_netcmd_init(); diff --git a/examples/sky/Makefile b/examples/sky/Makefile index f66dff5a1..6d17fd421 100644 --- a/examples/sky/Makefile +++ b/examples/sky/Makefile @@ -3,7 +3,7 @@ ifndef TARGET TARGET=sky endif -all: blink sky-collect #rt-leds test-button test-cfs tcprudolph0 +all: blink sky-collect #rt-leds test-button tcprudolph0 %.tgz: %.ihex mkdir $(basename $<) ; \ @@ -11,10 +11,6 @@ all: blink sky-collect #rt-leds test-button test-cfs tcprudolph0 echo $(basename $<)/$(basename $<).ihex 600 > $(basename $<)/runfile ; \ tar czf $@ $(basename $<) -%.class: %.java - javac $(basename $<).java - -viewrssi: ViewRSSI.class - make login | java ViewRSSI - +CONTIKI_WITH_IPV4 = 1 +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/sky/ViewRSSI.java b/examples/sky/ViewRSSI.java deleted file mode 100644 index 1226921d9..000000000 --- a/examples/sky/ViewRSSI.java +++ /dev/null @@ -1,105 +0,0 @@ -/** - * RSSI Viewer - view RSSI values of 802.15.4 channels - * --------------------------------------------------- - * Note: run the rssi-scanner on a Sky or sentilla node connected to USB - * then start with - * make ViewRSSI.class - * make login | java ViewRSSI - * or - * make viewrssi - * - * Created: Fri Apr 24 00:40:01 2009, Joakim Eriksson - * - * @author Joakim Eriksson, SICS - * @version 1.0 - */ -import javax.swing.*; -import java.awt.*; -import java.io.*; - -public class ViewRSSI extends JPanel { - - private int[] rssi = new int[80]; - private int[] rssiMax = new int[80]; - /* 55 is added by the scanner. 45 is the offset of the CC2420 */ - private final int DELTA = -55 -45 - - /* this is the max value of the RSSI from the cc2420 */ - private static final int RSSI_MAX_VALUE = 200; - - public ViewRSSI() { - } - - public void paint(Graphics g) { - - int h = getHeight(); - int w = getWidth(); - double factor = (h - 20.0) / RSSI_MAX_VALUE; - double sSpacing = (w - 15) / 80.0; - int sWidth = (int) (sSpacing - 1); - if (sWidth == 0) - sWidth = 1; - - Graphics2D g2d=(Graphics2D)g; - Font myFont=new Font("Arial", Font.PLAIN, 8); - g2d.setFont( myFont ); - - g.setColor(Color.white); - g.fillRect(0, 0, w, h); - - g.setColor(Color.gray); - double xpos = 10; - for (int i = 0, n = rssi.length; i < n; i++) { - int rssi = (int) (rssiMax[i] * factor); - g.fillRect((int) xpos, h - 20 - rssi, sWidth, rssi + 1); - g2d.drawString(Integer.toString(rssiMax[i] + DELTA), (int)xpos,h - 20 - rssi - 5 ); - xpos += sSpacing; - } - - - xpos = 10; - for (int i = 0, n = rssi.length; i < n; i++) { - g.setColor(Color.black); - int rssiVal = (int) (rssi[i] * factor); - g.fillRect((int) xpos, h - 20 - rssiVal, sWidth, rssiVal + 1); - g2d.drawString(Integer.toString(rssi[i] + DELTA), (int)xpos,h - 20 - rssiVal - 8 ); - g.setColor(Color.white); - g2d.drawString(Float.toString((float)i / 5 + (float)56/5), (int)xpos,h - 20 - 5 ); - xpos += sSpacing; - } - } - - private void handleInput() throws IOException { - BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); - while (true) { - String line = reader.readLine(); - if (line.startsWith("RSSI:")) { - try { - String[] parts = line.substring(5).split(" "); - for (int i = 0, n = parts.length; i < n; i++) { - rssi[i] = 3 * Integer.parseInt(parts[i]); - if (rssi[i] >= rssiMax[i]) - rssiMax[i] = rssi[i]; - else if (rssiMax[i] > 0) - rssiMax[i]--; - } - } catch (Exception e) { - /* report but do not fail... */ - e.printStackTrace(); - } - repaint(); - } - } - } - - public static void main(String[] args) throws IOException { - JFrame win = new JFrame("RSSI Viewer"); - ViewRSSI panel; - win.setBounds(10, 10, 300, 300); - win.getContentPane().add(panel = new ViewRSSI()); - win.setVisible(true); - win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - - panel.handleInput(); - } -} diff --git a/examples/sky/sky-collect.c b/examples/sky/sky-collect.c index d49dc8184..04cedf696 100644 --- a/examples/sky/sky-collect.c +++ b/examples/sky/sky-collect.c @@ -38,6 +38,7 @@ */ #include "contiki.h" +#include "sys/cc.h" #include "net/netstack.h" #include "net/rime/rime.h" #include "net/rime/collect.h" @@ -120,8 +121,6 @@ PROCESS_THREAD(depth_blink_process, ev, data) PROCESS_END(); } /*---------------------------------------------------------------------------*/ -#define MAX(a, b) ((a) > (b)? (a): (b)) -#define MIN(a, b) ((a) < (b)? (a): (b)) struct spectrum { int channel[16]; }; diff --git a/examples/sky/tcprudolph0.c b/examples/sky/tcprudolph0.c deleted file mode 100644 index 1dfea085f..000000000 --- a/examples/sky/tcprudolph0.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -#include -#include - -#include "contiki.h" -#include "sys/etimer.h" -#include "loader/elfloader.h" - -#include "net/ip/uip.h" - -#include "dev/leds.h" - -#include "cfs/cfs.h" - -#include "codeprop.h" - -#include "net/rime/rudolph0.h" - -#include - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif - -PROCESS(tcp_loader_process, "TCP loader"); -AUTOSTART_PROCESSES(&tcp_loader_process); - -static -struct codeprop_state { - uint16_t addr; - uint16_t len; - struct pt tcpthread_pt; - int fd; -} s; - -static char msg[30 + 10]; - -static struct rudolph0_conn rudolph0; - -/*---------------------------------------------------------------------*/ -static int -start_program(void) -{ - /* Link, load, and start new program. */ - int ret; - s.fd = cfs_open("codeprop.out", CFS_READ); - ret = elfloader_load(s.fd); - - /* XXX: Interrupts seems to be turned off a little too long during the - ELF loading process, so we need to "manually" trigger a timer - interrupt here. */ - TACCR1 = TAR + 1000; - - if(ret == ELFLOADER_OK) { - sprintf(msg, "ok\n"); - PRINTF("Ok, starting new program.\n"); - /* Start processes. */ - autostart_start(elfloader_autostart_processes); - } else { - sprintf(msg, "err %d %s", ret, elfloader_unknown); - PRINTF("Error: '%s'.\n", msg); - } - cfs_close(s.fd); - return ret; -} -/*---------------------------------------------------------------------*/ -static -PT_THREAD(recv_tcpthread(struct pt *pt)) -{ - PT_BEGIN(pt); - - /* Read the header. */ - PT_WAIT_UNTIL(pt, uip_newdata() && uip_datalen() > 0); - - if(uip_datalen() < sizeof(struct codeprop_tcphdr)) { - PRINTF(("codeprop: header not found in first tcp segment\n")); - uip_abort(); - goto thread_done; - } - - /* Kill old program. */ - rudolph0_stop(&rudolph0); - /* elfloader_unload();*/ - - s.len = uip_htons(((struct codeprop_tcphdr *)uip_appdata)->len); - s.addr = 0; - uip_appdata += sizeof(struct codeprop_tcphdr); - uip_len -= sizeof(struct codeprop_tcphdr); - - s.fd = cfs_open("codeprop.out", CFS_WRITE); - cfs_close(s.fd); - /* xmem_erase(XMEM_ERASE_UNIT_SIZE, EEPROMFS_ADDR_CODEPROP);*/ - - /* Read the rest of the data. */ - do { - leds_toggle(LEDS_RED); - if(uip_len > 0) { - s.fd = cfs_open("codeprop.out", CFS_WRITE + CFS_APPEND); - cfs_seek(s.fd, s.addr, CFS_SEEK_SET); - /* xmem_pwrite(uip_appdata, uip_len, EEPROMFS_ADDR_CODEPROP + s.addr);*/ - cfs_write(s.fd, uip_appdata, uip_len); - cfs_close(s.fd); - - PRINTF("Wrote %d bytes to file\n", uip_len); - s.addr += uip_len; - } - if(s.addr < s.len) { - PT_YIELD_UNTIL(pt, uip_newdata()); - } - } while(s.addr < s.len); - leds_off(LEDS_RED); - -#if DEBUG - { - int i, fd, j; - printf("Contents of file:\n"); - fd = cfs_open("codeprop.out", CFS_READ); - j = 0; - printf("\n0x%04x: ", 0); - for(i = 0; i < s.len; ++i) { - unsigned char byte; - cfs_read(fd, &byte, 1); - printf("0x%02x, ", byte); - ++j; - if(j == 8) { - printf("\n0x%04x: ", i + 1); - j = 0; - } - clock_delay(400); - } - cfs_close(fd); - } -#endif - - int ret; - - ret = start_program(); - -#if CONTIKI_TARGET_NETSIM - rudolph0_send(&rudolph0, CLOCK_SECOND / 4); -#else /* CONTIKI_TARGET_NETSIM */ - if(ret == ELFLOADER_OK) { - /* Propagate program. */ - rudolph0_send(&rudolph0, CLOCK_SECOND / 4); - } -#endif /* CONTIKI_TARGET_NETSIM */ - - /* Return "ok" message. */ - do { - ret = strlen(msg); - uip_send(msg, ret); - PT_WAIT_UNTIL(pt, uip_acked() || uip_rexmit() || uip_closed()); - } while(uip_rexmit()); - - /* Close the connection. */ - uip_close(); - - - thread_done:; - PT_END(pt); -} -/*---------------------------------------------------------------------*/ -static void -write_chunk(struct rudolph0_conn *c, int offset, int flag, - uint8_t *data, int datalen) -{ - int fd; - - leds_toggle(LEDS_YELLOW); - - if(flag == RUDOLPH0_FLAG_NEWFILE) { - printf("+++ rudolph0 new file incoming at %u\n", clock_time()); - fd = cfs_open("codeprop.out", CFS_WRITE); - - if(elfloader_autostart_processes != NULL) { - PRINTF("Stopping old programs.\n"); - autostart_exit(elfloader_autostart_processes); - elfloader_autostart_processes = NULL; - } - - } else { - fd = cfs_open("codeprop.out", CFS_WRITE + CFS_APPEND); - } - - if(datalen > 0) { - int ret; - cfs_seek(fd, offset, CFS_SEEK_SET); - ret = cfs_write(fd, data, datalen); - /* printf("write_chunk wrote %d bytes at %d, %d\n", ret, offset, (unsigned char)data[0]);*/ - } - - cfs_close(fd); - - if(flag == RUDOLPH0_FLAG_LASTCHUNK) { - printf("+++ rudolph0 entire file received at %u\n", clock_time()); - start_program(); - leds_off(LEDS_YELLOW); - } -} -static int -read_chunk(struct rudolph0_conn *c, int offset, uint8_t *to, int maxsize) -{ - int fd; - int ret; - - leds_toggle(LEDS_GREEN); - - fd = cfs_open("codeprop.out", CFS_READ); - - cfs_seek(fd, offset, CFS_SEEK_SET); - ret = cfs_read(fd, to, maxsize); - /* printf("read_chunk %d bytes at %d, %d\n", ret, offset, (unsigned char)to[0]);*/ - if(ret < maxsize) { - leds_off(LEDS_GREEN); - } - cfs_close(fd); - return ret; -} -const static struct rudolph0_callbacks rudolph0_call = {write_chunk, - read_chunk}; -/*---------------------------------------------------------------------*/ -PROCESS_THREAD(tcp_loader_process, ev, data) -{ - PROCESS_BEGIN(); - - rudolph0_open(&rudolph0, 20, &rudolph0_call); - - tcp_listen(UIP_HTONS(CODEPROP_DATA_PORT)); - - while(1) { - PROCESS_YIELD(); - if(ev == tcpip_event && uip_conn->lport == UIP_HTONS(CODEPROP_DATA_PORT)) { - if(uip_connected()) { /* Really uip_connecting()!!! */ - if(data == NULL) { - PT_INIT(&s.tcpthread_pt); - process_poll(&tcp_loader_process); - tcp_markconn(uip_conn, &s); - - if(elfloader_autostart_processes != NULL) { - PRINTF("Stopping old programs.\n"); - autostart_exit(elfloader_autostart_processes); - elfloader_autostart_processes = NULL; - } - } else { - PRINTF(("codeprop: uip_connected() and data != NULL\n")); - uip_abort(); - } - } - recv_tcpthread(&s.tcpthread_pt); /* Run thread */ - - if(uip_closed() || uip_aborted() || uip_timedout()) { - PRINTF(("codeprop: connection down\n")); - tcp_markconn(uip_conn, NULL); - } - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------*/ -#include "net/rime/collect.h" -#include "net/rime/mesh.h" -#include "net/rime/rudolph0.h" -#include "net/rime/rudolph1.h" -void -dummy(void) -{ - /* Make sure that all Rime modules are present in the core */ - collect_close(NULL); - mesh_close(NULL); - ipolite_close(NULL); - polite_close(NULL); - ruc_close(NULL); - sibc_close(NULL); - rudolph0_close(NULL); - rudolph1_close(NULL); - - /* Make sure psock is included */ - psock_datalen(NULL); -} -/*---------------------------------------------------------------------*/ diff --git a/examples/sky/test-deluge.c b/examples/sky/test-deluge.c deleted file mode 100644 index 3bb9bb5e8..000000000 --- a/examples/sky/test-deluge.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * A test program for Deluge. - * \author - * Nicolas Tsiftes - */ - -#include "contiki.h" -#include "cfs/cfs.h" -#include "deluge.h" -#include "sys/node-id.h" - -#include -#include - -#ifndef SINK_ID -#define SINK_ID 1 -#endif - -#ifndef FILE_SIZE -#define FILE_SIZE 1000 -#endif - -PROCESS(deluge_test_process, "Deluge test process"); -AUTOSTART_PROCESSES(&deluge_test_process); -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(deluge_test_process, ev, data) -{ - int fd, r; - char buf[32]; - static struct etimer et; - - PROCESS_BEGIN(); - - memset(buf, 0, sizeof(buf)); - if(node_id == SINK_ID) { - strcpy(buf, "This is version 1 of the file"); - } else { - strcpy(buf, "This is version 0 of the file"); - } - - cfs_remove("test"); - fd = cfs_open("test", CFS_WRITE); - if(fd < 0) { - process_exit(NULL); - } - if(cfs_write(fd, buf, sizeof(buf)) != sizeof(buf)) { - cfs_close(fd); - process_exit(NULL); - } - - if(cfs_seek(fd, FILE_SIZE, CFS_SEEK_SET) != FILE_SIZE) { - printf("failed to seek to the end\n"); - } - - deluge_disseminate("test", node_id == SINK_ID); - cfs_close(fd); - - etimer_set(&et, CLOCK_SECOND * 5); - for(;;) { - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - if(node_id != SINK_ID) { - fd = cfs_open("test", CFS_READ); - if(fd < 0) { - printf("failed to open the test file\n"); - } else { - r = cfs_read(fd, buf, sizeof(buf)); - buf[sizeof(buf) - 1] = '\0'; - if(r <= 0) { - printf("failed to read data from the file\n"); - } else { - printf("File contents: %s\n", buf); - } - cfs_close(fd); - } - } - etimer_reset(&et); - } - - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/stm32nucleo-spirit1/sensor-demo/Makefile b/examples/stm32nucleo-spirit1/sensor-demo/Makefile new file mode 100644 index 000000000..0ec14cccd --- /dev/null +++ b/examples/stm32nucleo-spirit1/sensor-demo/Makefile @@ -0,0 +1,8 @@ +CONTIKI_PROJECT = sensor-demo +all: $(CONTIKI_PROJECT) + +TARGET=stm32nucleo-spirit1 +SENSORBOARD=iks01a1 + +CONTIKI = ../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/stm32nucleo-spirit1/sensor-demo/README.md b/examples/stm32nucleo-spirit1/sensor-demo/README.md new file mode 100644 index 000000000..b9cdc9caf --- /dev/null +++ b/examples/stm32nucleo-spirit1/sensor-demo/README.md @@ -0,0 +1,17 @@ +Sensor Demo +============ + +The sensor demo can be used to read the values of all sensors and print them every 5 seconds on the terminal. + +In order to use this example the X-NUCLEO-IKS01A1 expansion board featuring ST environmental and motion MEMS sensors +must be used. It needs to be connected on top of the NUCLEO-L152RE (MCU) and the X-NUCLEO-IDS01Ax +(sub-1GHz RF communication) boards. + +To build the example type: + + make TARGET=stm32nucleo-spirit1 BOARD=ids01a4 SENSORBOARD=iks01a1 +or + + make TARGET=stm32nucleo-spirit1 BOARD=ids01a5 SENSORBOARD=iks01a1 + +depending on the X-NUCLEO-IDS01Ax expansion board for sub GHz radio connectivity you have. diff --git a/examples/stm32nucleo-spirit1/sensor-demo/sensor-demo.c b/examples/stm32nucleo-spirit1/sensor-demo/sensor-demo.c new file mode 100644 index 000000000..18bea17bf --- /dev/null +++ b/examples/stm32nucleo-spirit1/sensor-demo/sensor-demo.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" + +#include /* For printf() */ + +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "net/ip/uip-udp-packet.h" + +#include "dev/button-sensor.h" +#include "dev/leds.h" +#include "dev/radio-sensor.h" +#include "dev/sensor-common.h" + +#include "st-lib.h" + +#ifdef X_NUCLEO_IKS01A1 +#include "dev/temperature-sensor.h" +#include "dev/humidity-sensor.h" +#include "dev/pressure-sensor.h" +#include "dev/magneto-sensor.h" +#include "dev/acceleration-sensor.h" +#include "dev/gyroscope-sensor.h" +#endif /*X_NUCLEO_IKS01A1*/ + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +#define PRINT_INTERVAL 5 * CLOCK_SECOND + +/*---------------------------------------------------------------------------*/ +PROCESS(sensor_demo_process, "Sensor demo process"); +AUTOSTART_PROCESSES(&sensor_demo_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(sensor_demo_process, ev, data) +{ + static struct etimer etimer; + static unsigned long _button_pressed; + static int sensor_value = 0; + + PROCESS_BEGIN(); + PROCESS_PAUSE(); + + SENSORS_ACTIVATE(button_sensor); + + SENSORS_ACTIVATE(radio_sensor); + +#ifdef X_NUCLEO_IKS01A1 + SENSORS_ACTIVATE(temperature_sensor); + SENSORS_ACTIVATE(humidity_sensor); + SENSORS_ACTIVATE(pressure_sensor); + SENSORS_ACTIVATE(magneto_sensor); + SENSORS_ACTIVATE(acceleration_sensor); + SENSORS_ACTIVATE(gyroscope_sensor); +#endif /*X_NUCLEO_IKS01A1*/ + + while(1) { + etimer_set(&etimer, PRINT_INTERVAL); + + PROCESS_WAIT_EVENT(); + if(ev == sensors_event && data == &button_sensor) { + printf("Sensor event detected: Button Pressed.\n\n"); + printf("Toggling Leds\n"); + _button_pressed++; + leds_toggle(LEDS_ALL); + } + + printf("Button state:\t%s (pressed %lu times)\n", button_sensor.value(0) ? "Released" : "Pressed", + _button_pressed); + +#ifdef X_NUCLEO_IKS01A1 + printf("LEDs status:\tRED:n/a GREEN:%s\n", leds_get() & LEDS_GREEN ? "on" : "off"); +#else + printf("LEDs status:\tRED:%s GREEN:%s\n", leds_get() & LEDS_RED ? "on" : "off", + leds_get() & LEDS_GREEN ? "on" : "off"); +#endif /*X_NUCLEO_IKS01A1*/ + sensor_value = radio_sensor.value(RADIO_SENSOR_LAST_PACKET); + printf("Radio (RSSI):\t%d.%d dBm\n", sensor_value / 10, ABS_VALUE(sensor_value) % 10); + printf("Radio (LQI):\t%d\n", radio_sensor.value(RADIO_SENSOR_LAST_VALUE)); + +#ifdef X_NUCLEO_IKS01A1 + sensor_value = temperature_sensor.value(0); + printf("Temperature:\t%d.%d C\n", sensor_value / 10, ABS_VALUE(sensor_value) % 10); + + sensor_value = humidity_sensor.value(0); + printf("Humidity:\t%d.%d rH\n", sensor_value / 10, ABS_VALUE(sensor_value) % 10); + + sensor_value = pressure_sensor.value(0); + printf("Pressure:\t%d.%d mbar\n", sensor_value / 10, ABS_VALUE(sensor_value) % 10); + + /* NOTE: this demo uses the mapping of ST Nucleo sensors on Contiki sensor API. + * For a real use case of sensors like acceleration, magneto and gyroscope, + * it is better to directly call the ST lib to get the three value (X/Y/Z) + * at once. + */ + printf("Magneto:\t%d/%d/%d (X/Y/Z) mgauss\n", magneto_sensor.value(X_AXIS), + magneto_sensor.value(Y_AXIS), + magneto_sensor.value(Z_AXIS)); + + printf("Acceleration:\t%d/%d/%d (X/Y/Z) mg\n", acceleration_sensor.value(X_AXIS), + acceleration_sensor.value(Y_AXIS), + acceleration_sensor.value(Z_AXIS)); + + printf("Gyroscope:\t%d/%d/%d (X/Y/Z) mdps\n", gyroscope_sensor.value(X_AXIS), + gyroscope_sensor.value(Y_AXIS), + gyroscope_sensor.value(Z_AXIS)); +#endif /*X_NUCLEO_IKS01A1*/ + + printf("\n"); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/tcp-socket/Makefile b/examples/tcp-socket/Makefile index 544963f05..9e04825df 100644 --- a/examples/tcp-socket/Makefile +++ b/examples/tcp-socket/Makefile @@ -1,5 +1,5 @@ all: tcp-server CONTIKI=../.. - +CONTIKI_WITH_IPV4 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/tcp-socket/tcp-server.c b/examples/tcp-socket/tcp-server.c index f2e776784..e25d65579 100644 --- a/examples/tcp-socket/tcp-server.c +++ b/examples/tcp-socket/tcp-server.c @@ -30,6 +30,7 @@ */ #include "contiki-net.h" +#include "sys/cc.h" #include #include @@ -104,7 +105,6 @@ PROCESS_THREAD(tcp_server_process, ev, data) while(bytes_to_send > 0) { PROCESS_PAUSE(); int len, tosend; -#define MIN(a,b) ((a)<(b)?(a):(b)) tosend = MIN(bytes_to_send, sizeof(outputbuf)); len = tcp_socket_send(&socket, (uint8_t *)"", tosend); bytes_to_send -= len; diff --git a/examples/telnet-server/Makefile b/examples/telnet-server/Makefile index 543dc8f49..b2f75b294 100644 --- a/examples/telnet-server/Makefile +++ b/examples/telnet-server/Makefile @@ -3,7 +3,6 @@ all: $(CONTIKI_PROJECT) APPS = telnetd program-handler -WITH_UIP=1 - CONTIKI = ../.. +CONTIKI_WITH_IPV4 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/telnet-server/Makefile.apple2enh.defines b/examples/telnet-server/Makefile.apple2enh.defines index 3dbfd3e2f..2ee328994 100644 --- a/examples/telnet-server/Makefile.apple2enh.defines +++ b/examples/telnet-server/Makefile.apple2enh.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_PFS +DEFINES = CONNECTIONS=3,WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_80COL,WITH_REBOOT diff --git a/examples/telnet-server/Makefile.atarixl.defines b/examples/telnet-server/Makefile.atarixl.defines index 405794c09..bcd39d550 100644 --- a/examples/telnet-server/Makefile.atarixl.defines +++ b/examples/telnet-server/Makefile.atarixl.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_CLIENT,WITH_DNS +DEFINES = CONNECTIONS=3,WITH_LOGGING,WITH_CLIENT,WITH_DNS diff --git a/examples/telnet-server/Makefile.c128.defines b/examples/telnet-server/Makefile.c128.defines index 84c86ef72..062a12cd7 100644 --- a/examples/telnet-server/Makefile.c128.defines +++ b/examples/telnet-server/Makefile.c128.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_PFS,CONNECTIONS=2,MTU_SIZE=500 +DEFINES = WITH_LOGGING,WITH_80COL diff --git a/examples/telnet-server/Makefile.c64.defines b/examples/telnet-server/Makefile.c64.defines index 3dbfd3e2f..caf0dfa69 100644 --- a/examples/telnet-server/Makefile.c64.defines +++ b/examples/telnet-server/Makefile.c64.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_PFS +DEFINES = CONNECTIONS=3,WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_PFS diff --git a/examples/telnet-server/telnet-server.c b/examples/telnet-server/telnet-server.c index a0862886e..0164d2744 100644 --- a/examples/telnet-server/telnet-server.c +++ b/examples/telnet-server/telnet-server.c @@ -48,21 +48,18 @@ PROCESS_THREAD(shell_init_process, ev, data) { PROCESS_BEGIN(); -#ifdef __CC65__ - shell_ps_init(); - shell_netstat_init(); - shell_wget_init(); - shell_memdebug_init(); -#else /* __CC65__ */ shell_file_init(); +#ifndef __CC65__ shell_httpd_init(); shell_irc_init(); shell_ps_init(); shell_run_init(); shell_text_init(); shell_time_init(); +#endif /* !__CC65__ */ +#ifndef __C128__ shell_wget_init(); -#endif /* __CC65__ */ +#endif /* !__C128__ */ PROCESS_END(); } diff --git a/examples/timers/Makefile b/examples/timers/Makefile new file mode 100644 index 000000000..d5b2a2846 --- /dev/null +++ b/examples/timers/Makefile @@ -0,0 +1,5 @@ +CONTIKI_PROJECT = all-timers +all: $(CONTIKI_PROJECT) + +CONTIKI = ../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/timers/all-timers.c b/examples/timers/all-timers.c new file mode 100644 index 000000000..60eb56651 --- /dev/null +++ b/examples/timers/all-timers.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include + +#include "contiki.h" +#include "sys/etimer.h" +#include "sys/stimer.h" +#include "sys/timer.h" +#include "sys/rtimer.h" + +PROCESS(process1, "ETimer x Timer x STimer Process"); +PROCESS(process2, "CTimer Process 2"); +PROCESS(process3, "RTimer Process 3"); +AUTOSTART_PROCESSES(&process1, &process2, &process3); + +static int counter_etimer; +static int counter_timer; +static int counter_stimer; +static int counter_ctimer; +static int counter_rtimer; +static struct timer timer_timer; +static struct stimer timer_stimer; +static struct ctimer timer_ctimer; +static struct rtimer timer_rtimer; +static rtimer_clock_t timeout_rtimer = RTIMER_SECOND / 2; + +void +do_timeout1() +{ + counter_etimer++; + if(timer_expired(&timer_timer)) { + counter_timer++; + } + + if(stimer_expired(&timer_stimer)) { + counter_stimer++; + } + + printf("\nProcess 1: %s", counter_timer == counter_etimer + && counter_timer == counter_stimer ? "SUCCESS" : "FAIL"); +} +/*---------------------------------------------------------------------------*/ +void +do_timeout2() +{ + ctimer_reset(&timer_ctimer); + printf("\nProcess 2: CTimer callback called"); + counter_ctimer++; +} +/*---------------------------------------------------------------------------*/ +void +do_timeout3(struct rtimer *timer, void *ptr) +{ + counter_rtimer++; + + printf("\nProcess 3: RTimer callback called"); + + /* Re-arm rtimer */ + rtimer_set(&timer_rtimer, RTIMER_NOW() + timeout_rtimer, 0, do_timeout3, + NULL); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(process1, ev, data) +{ + static struct etimer timer_etimer; + + PROCESS_BEGIN(); + + while(1) { + timer_set(&timer_timer, 3 * CLOCK_SECOND); + stimer_set(&timer_stimer, 3); + etimer_set(&timer_etimer, 3 * CLOCK_SECOND); + PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); + do_timeout1(); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(process2, ev, data) +{ + PROCESS_BEGIN(); + + while(1) { + ctimer_set(&timer_ctimer, 5 * CLOCK_SECOND, do_timeout2, NULL); + PROCESS_YIELD(); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(process3, ev, data) +{ + PROCESS_BEGIN(); + + while(1) { + rtimer_set(&timer_rtimer, RTIMER_NOW() + timeout_rtimer, 0, + do_timeout3, NULL); + PROCESS_YIELD(); + } + + PROCESS_END(); +} diff --git a/examples/trickle-library/Makefile b/examples/trickle-library/Makefile index 69a4e0402..6c08a2c46 100644 --- a/examples/trickle-library/Makefile +++ b/examples/trickle-library/Makefile @@ -1,9 +1,8 @@ -UIP_CONF_IPV6=1 - CONTIKI_PROJECT = trickle-library all: $(CONTIKI_PROJECT) CONTIKI = ../.. +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/trickle-library/trickle-library.csc b/examples/trickle-library/trickle-library.csc index 2df0dddab..7a6d74ca2 100644 --- a/examples/trickle-library/trickle-library.csc +++ b/examples/trickle-library/trickle-library.csc @@ -1,154 +1,154 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - [CONTIKI_DIR]/tools/cooja/apps/powertracker - - Example Demonstrating the Trickle Library's Functionality - 0 - generated - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - trickle-tester - [CONTIKI_DIR]/examples/trickle-library/trickle-library.c - make trickle-library.sky TARGET=sky - [CONTIKI_DIR]/examples/trickle-library/trickle-library.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 96.8286491032791 - 44.83363764767495 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 26.625418506201424 - 62.32118900834971 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 12.373988266345922 - 40.21870711164037 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 38.44294323221424 - 17.14724376428426 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 68.38248149463341 - 23.506083749222842 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky1 - - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.TrafficVisualizerSkin - org.contikios.cooja.plugins.skins.IDVisualizerSkin - 5.862188489126289 0.0 0.0 5.862188489126289 -4.083221885224075 -86.33855683341153 - - 642 - 0 - 369 - 447 - 10 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1235 - 2 - 285 - 4 - 389 - - - org.contikios.cooja.plugins.SimControl - 318 - 1 - 192 - 60 - 60 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + [CONTIKI_DIR]/tools/cooja/apps/powertracker + + Example Demonstrating the Trickle Library's Functionality + 0 + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + trickle-tester + [CONTIKI_DIR]/examples/trickle-library/trickle-library.c + make trickle-library.sky TARGET=sky + [CONTIKI_DIR]/examples/trickle-library/trickle-library.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 96.8286491032791 + 44.83363764767495 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 26.625418506201424 + 62.32118900834971 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 12.373988266345922 + 40.21870711164037 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 38.44294323221424 + 17.14724376428426 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 68.38248149463341 + 23.506083749222842 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky1 + + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + org.contikios.cooja.plugins.skins.IDVisualizerSkin + 5.862188489126289 0.0 0.0 5.862188489126289 -4.083221885224075 -86.33855683341153 + + 642 + 0 + 369 + 447 + 10 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1235 + 2 + 285 + 4 + 389 + + + org.contikios.cooja.plugins.SimControl + 318 + 1 + 192 + 60 + 60 + + + diff --git a/examples/udp-ipv6/Makefile b/examples/udp-ipv6/Makefile index 627e1c5f6..7a38bdbc5 100644 --- a/examples/udp-ipv6/Makefile +++ b/examples/udp-ipv6/Makefile @@ -1,6 +1,6 @@ all: udp-server udp-client -UIP_CONF_IPV6=1 - CONTIKI = ../.. +CONTIKI_WITH_IPV6 = 1 +CFLAGS += -DUIP_CONF_ND6_SEND_NA=1 include $(CONTIKI)/Makefile.include diff --git a/examples/udp-ipv6/udp-client.c b/examples/udp-ipv6/udp-client.c index 7f9b7659e..85854a48b 100644 --- a/examples/udp-ipv6/udp-client.c +++ b/examples/udp-ipv6/udp-client.c @@ -98,7 +98,7 @@ set_global_address(void) { uip_ipaddr_t ipaddr; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); } @@ -111,7 +111,7 @@ set_connection_address(uip_ipaddr_t *ipaddr) #if RESOLV_CONF_SUPPORTS_MDNS #define UDP_CONNECTION_ADDR contiki-udp-server.local #elif UIP_CONF_ROUTER -#define UDP_CONNECTION_ADDR aaaa:0:0:0:0212:7404:0004:0404 +#define UDP_CONNECTION_ADDR fd00:0:0:0:0212:7404:0004:0404 #else #define UDP_CONNECTION_ADDR fe80:0:0:0:6466:6666:6666:6666 #endif diff --git a/examples/udp-ipv6/udp-server.c b/examples/udp-ipv6/udp-server.c index c56720f9a..eeb7de700 100644 --- a/examples/udp-ipv6/udp-server.c +++ b/examples/udp-ipv6/udp-server.c @@ -99,7 +99,7 @@ PROCESS_THREAD(udp_server_process, ev, data) #endif #if UIP_CONF_ROUTER - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); #endif /* UIP_CONF_ROUTER */ diff --git a/examples/udp-stream/Makefile b/examples/udp-stream/Makefile index e1a1c9855..1a9b6e59b 100644 --- a/examples/udp-stream/Makefile +++ b/examples/udp-stream/Makefile @@ -6,8 +6,8 @@ ifndef TARGET TARGET = sky endif -UIP_CONF_IPV6 = 1 CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" SMALL = 1 +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/udp-stream/udp-stream.c b/examples/udp-stream/udp-stream.c index c10e8d6a5..875b594d8 100644 --- a/examples/udp-stream/udp-stream.c +++ b/examples/udp-stream/udp-stream.c @@ -74,7 +74,7 @@ set_global_address(void) int i; uint8_t state; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); @@ -102,7 +102,7 @@ create_rpl_dag(uip_ipaddr_t *ipaddr) rpl_set_root(RPL_DEFAULT_INSTANCE, ipaddr); dag = rpl_get_any_dag(); - uip_ip6addr(&prefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); rpl_set_prefix(dag, &prefix, 64); printf("created a new RPL dag\n"); } else { diff --git a/examples/udp-stream/udp-stream.csc b/examples/udp-stream/udp-stream.csc index 0908440f5..4639129d4 100644 --- a/examples/udp-stream/udp-stream.csc +++ b/examples/udp-stream/udp-stream.csc @@ -1,182 +1,182 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/mrm - - UDP Stream Example - 0 - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - mote - mote - [CONTIKI_DIR]/examples/udp-stream/udp-stream.c - make udp-stream.sky TARGET=sky - [CONTIKI_DIR]/examples/udp-stream/udp-stream.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - mote - - - - - org.contikios.cooja.interfaces.Position - 70.87477363740156 - 31.656474063135494 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - mote - - - - - org.contikios.cooja.interfaces.Position - 112.33402646502834 - 47.18506616257089 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - mote - - - - - org.contikios.cooja.interfaces.Position - 132.53950850661624 - 78.99637996219282 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - mote - - - - - org.contikios.cooja.interfaces.Position - 136.72844990548202 - 114.94735349716447 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - mote - - - - org.contikios.cooja.plugins.SimControl - 259 - 4 - 178 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - org.contikios.cooja.plugins.skins.AttributeVisualizerSkin - 1.2465387687077096 0.0 0.0 1.2465387687077096 22.99764760264848 12.704392736072247 - - 257 - 3 - 297 - 0 - 180 - - - org.contikios.cooja.plugins.LogListener - - - - - 568 - 2 - 663 - 257 - -2 - - - org.contikios.cooja.plugins.RadioLogger - - 449 - - - 605 - 1 - 661 - 824 - 0 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - 2 - 3 - 4 - - - 125 - 100000.0 - - 1429 - 0 - 141 - 1 - 661 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/mrm + + UDP Stream Example + 0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + mote + mote + [CONTIKI_DIR]/examples/udp-stream/udp-stream.c + make udp-stream.sky TARGET=sky + [CONTIKI_DIR]/examples/udp-stream/udp-stream.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + mote + + + + + org.contikios.cooja.interfaces.Position + 70.87477363740156 + 31.656474063135494 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + mote + + + + + org.contikios.cooja.interfaces.Position + 112.33402646502834 + 47.18506616257089 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + mote + + + + + org.contikios.cooja.interfaces.Position + 132.53950850661624 + 78.99637996219282 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + mote + + + + + org.contikios.cooja.interfaces.Position + 136.72844990548202 + 114.94735349716447 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + mote + + + + org.contikios.cooja.plugins.SimControl + 259 + 4 + 178 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + 1.2465387687077096 0.0 0.0 1.2465387687077096 22.99764760264848 12.704392736072247 + + 257 + 3 + 297 + 0 + 180 + + + org.contikios.cooja.plugins.LogListener + + + + + 568 + 2 + 663 + 257 + -2 + + + org.contikios.cooja.plugins.RadioLogger + + 449 + + + 605 + 1 + 661 + 824 + 0 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + + + 125 + 100000.0 + + 1429 + 0 + 141 + 1 + 661 + + + diff --git a/examples/webbrowser-80col/Makefile b/examples/webbrowser-80col/Makefile new file mode 100644 index 000000000..5067c2d9c --- /dev/null +++ b/examples/webbrowser-80col/Makefile @@ -0,0 +1,8 @@ +CONTIKI_PROJECT = webbrowser +all: $(CONTIKI_PROJECT) + +APPS = webbrowser + +CONTIKI = ../.. +CONTIKI_WITH_IPV4 = 1 +include $(CONTIKI)/Makefile.include diff --git a/examples/webbrowser-80col/Makefile.apple2enh.defines b/examples/webbrowser-80col/Makefile.apple2enh.defines new file mode 100644 index 000000000..71fb932e2 --- /dev/null +++ b/examples/webbrowser-80col/Makefile.apple2enh.defines @@ -0,0 +1 @@ +DEFINES = WITH_CLIENT,WITH_DNS,WITH_80COL,WITH_GUI,WITH_MOUSE,WITH_PFS diff --git a/examples/webbrowser-80col/Makefile.atarixl.defines b/examples/webbrowser-80col/Makefile.atarixl.defines new file mode 100644 index 000000000..962070b58 --- /dev/null +++ b/examples/webbrowser-80col/Makefile.atarixl.defines @@ -0,0 +1 @@ +DEFINES = WITH_CLIENT,WITH_DNS,WITH_80COL,WITH_GUI,WITH_MOUSE diff --git a/examples/webbrowser-80col/Makefile.c128.defines b/examples/webbrowser-80col/Makefile.c128.defines new file mode 100644 index 000000000..1b47d0cb1 --- /dev/null +++ b/examples/webbrowser-80col/Makefile.c128.defines @@ -0,0 +1 @@ +DEFINES = WITH_CLIENT,WITH_DNS,WITH_80COL,WITH_GUI,WITH_PFS,MTU_SIZE=500 diff --git a/examples/webbrowser-80col/Makefile.c64.defines b/examples/webbrowser-80col/Makefile.c64.defines new file mode 100644 index 000000000..71fb932e2 --- /dev/null +++ b/examples/webbrowser-80col/Makefile.c64.defines @@ -0,0 +1 @@ +DEFINES = WITH_CLIENT,WITH_DNS,WITH_80COL,WITH_GUI,WITH_MOUSE,WITH_PFS diff --git a/examples/webbrowser-80col/Makefile.native.defines b/examples/webbrowser-80col/Makefile.native.defines new file mode 100644 index 000000000..1b5caf200 --- /dev/null +++ b/examples/webbrowser-80col/Makefile.native.defines @@ -0,0 +1 @@ +DEFINES = WITH_GUI diff --git a/examples/webbrowser-80col/Makefile.win32.defines b/examples/webbrowser-80col/Makefile.win32.defines new file mode 100644 index 000000000..1b5caf200 --- /dev/null +++ b/examples/webbrowser-80col/Makefile.win32.defines @@ -0,0 +1 @@ +DEFINES = WITH_GUI diff --git a/examples/webbrowser-80col/webbrowser.c b/examples/webbrowser-80col/webbrowser.c new file mode 100644 index 000000000..0453fe0d2 --- /dev/null +++ b/examples/webbrowser-80col/webbrowser.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#include "contiki-net.h" +#include "www.h" + +/*---------------------------------------------------------------------------*/ +AUTOSTART_PROCESSES(&www_process); +/*---------------------------------------------------------------------------*/ diff --git a/examples/webbrowser/Makefile b/examples/webbrowser/Makefile index a7216d061..5067c2d9c 100644 --- a/examples/webbrowser/Makefile +++ b/examples/webbrowser/Makefile @@ -4,4 +4,5 @@ all: $(CONTIKI_PROJECT) APPS = webbrowser CONTIKI = ../.. +CONTIKI_WITH_IPV4 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/webserver-ipv6-raven/Makefile.webserver b/examples/webserver-ipv6-raven/Makefile.webserver index 2ec84da1a..2001d6c7b 100644 --- a/examples/webserver-ipv6-raven/Makefile.webserver +++ b/examples/webserver-ipv6-raven/Makefile.webserver @@ -3,9 +3,7 @@ all: webserver6 APPS=raven-webserver raven-lcd-interface TARGET=avr-raven -UIP_CONF_IPV6=1 -#UIP_CONF_RPL=0 //RPL is now the default. #RF230BB=1 //Use radio driver that communicates with the core MAC layer. Now the default. #COFFEE_FILES=1 //Static coffee file system in EEPROM #COFFEE_FILES=2 //Dynamic coffee file system in EEPROM @@ -14,5 +12,5 @@ UIP_CONF_IPV6=1 #COFFEE_ADDRESS=0xnnnn //Override default coffee file system starting address CONTIKI = ../.. - +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/webserver-ipv6/Makefile b/examples/webserver-ipv6/Makefile index 25a545c27..c764d9514 100644 --- a/examples/webserver-ipv6/Makefile +++ b/examples/webserver-ipv6/Makefile @@ -34,15 +34,15 @@ all : $(CONTIKI_PROJECT) @if (test -n "$(ELF_SIZE)");then $(ELF_SIZE) $(CONTIKI_PROJECT).$(TARGET);fi endif -UIP_CONF_IPV6=1 -DEFINES=WITH_UIP6 +DEFINES=UIP_CONF_TCP=1 # Make no RPL the default for minimal-net builds ifeq ($(TARGET),minimal-net) -ifndef UIP_CONF_RPL -UIP_CONF_RPL=0 +ifndef CONTIKI_WITH_RPL +CONTIKI_WITH_RPL = 0 endif endif CONTIKI = ../.. +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/webserver-ipv6/README.md b/examples/webserver-ipv6/README.md index ddeb5cb87..fae6057a1 100644 --- a/examples/webserver-ipv6/README.md +++ b/examples/webserver-ipv6/README.md @@ -41,7 +41,7 @@ On linux you can set up router advertisements as follows: - You might need to add a route: - ip -6 route add aaaa:0000:0000:0000:0206:98ff:fe00:0232/64 dev tap0 + ip -6 route add fd00:0000:0000:0000:0206:98ff:fe00:0232/64 dev tap0 - Then configure a global address by sending a router advertisement (RA) with a prefix option. You can use radvd for example to generate such a packet. diff --git a/examples/webserver/Makefile b/examples/webserver/Makefile index a5d599b93..0645e2b51 100644 --- a/examples/webserver/Makefile +++ b/examples/webserver/Makefile @@ -16,6 +16,7 @@ ifeq ($(HTTPD-CFS),1) endif CONTIKI = ../.. +CONTIKI_WITH_IPV4 = 1 include $(CONTIKI)/Makefile.include # Intentionally httpd.c and httpd-cfs.c implement the same interface. When diff --git a/examples/webserver/Makefile.apple2enh.defines b/examples/webserver/Makefile.apple2enh.defines index 70fa579ff..5d8fdd62e 100644 --- a/examples/webserver/Makefile.apple2enh.defines +++ b/examples/webserver/Makefile.apple2enh.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_BOOST,CONNECTIONS=5 +DEFINES = CONNECTIONS=4,WITH_LOGGING,WITH_BOOST,WITH_80COL diff --git a/examples/webserver/Makefile.atarixl.defines b/examples/webserver/Makefile.atarixl.defines index a17e2c1c1..461a038bb 100644 --- a/examples/webserver/Makefile.atarixl.defines +++ b/examples/webserver/Makefile.atarixl.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_BOOST +DEFINES = CONNECTIONS=4,WITH_LOGGING,WITH_BOOST diff --git a/examples/webserver/Makefile.c128.defines b/examples/webserver/Makefile.c128.defines index ac4b8c2d8..d4b3027dc 100644 --- a/examples/webserver/Makefile.c128.defines +++ b/examples/webserver/Makefile.c128.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_BOOST,WITH_PFS,CONNECTIONS=5 +DEFINES = CONNECTIONS=4,WITH_LOGGING,WITH_BOOST,WITH_80COL,WITH_PFS diff --git a/examples/webserver/Makefile.c64.defines b/examples/webserver/Makefile.c64.defines index 0c6ef3678..43f7fe613 100644 --- a/examples/webserver/Makefile.c64.defines +++ b/examples/webserver/Makefile.c64.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_BOOST,WITH_PFS +DEFINES = CONNECTIONS=4,WITH_LOGGING,WITH_BOOST,WITH_PFS diff --git a/examples/wget/Makefile b/examples/wget/Makefile index 1d55fde87..91e844062 100644 --- a/examples/wget/Makefile +++ b/examples/wget/Makefile @@ -4,4 +4,5 @@ all: $(CONTIKI_PROJECT) APPS = webbrowser CONTIKI = ../.. +CONTIKI_WITH_IPV4 = 1 include $(CONTIKI)/Makefile.include diff --git a/examples/wget/Makefile.apple2enh.defines b/examples/wget/Makefile.apple2enh.defines index a4bbe71fb..f596f97ce 100644 --- a/examples/wget/Makefile.apple2enh.defines +++ b/examples/wget/Makefile.apple2enh.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_ARGS +DEFINES = WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_80COL,WITH_ARGS diff --git a/examples/wget/Makefile.c128.defines b/examples/wget/Makefile.c128.defines index a4bbe71fb..adbaf5689 100644 --- a/examples/wget/Makefile.c128.defines +++ b/examples/wget/Makefile.c128.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_ARGS +DEFINES = WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_80COL,WITH_PFS,WITH_ARGS diff --git a/examples/wget/wget.c b/examples/wget/wget.c index 8a452771c..bdba5b25d 100644 --- a/examples/wget/wget.c +++ b/examples/wget/wget.c @@ -146,7 +146,7 @@ app_quit(void) if(file != -1) { cfs_close(file); } - puts("Press any key to continue..."); + puts("Press to continue..."); getchar(); process_exit(&wget_process); LOADER_UNLOAD(); @@ -169,14 +169,16 @@ PROCESS_THREAD(wget_process, ev, data) strcpy(url, contiki_argv[1]); puts(url); } else { - gets(url); + fgets(url, sizeof(url), stdin); + url[strlen(url) - 1] = 0; } fputs("Save as:", stdout); if(contiki_argc > 2) { strcpy(name, contiki_argv[2]); puts(name); } else { - gets(name); + fgets(name, sizeof(name), stdin); + name[strlen(name) - 1] = 0; } file = cfs_open(name, CFS_WRITE); if(file == -1) { diff --git a/examples/z1/Makefile b/examples/z1/Makefile deleted file mode 100644 index 99f08955a..000000000 --- a/examples/z1/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -ifndef TARGET -TARGET=z1 -endif - -CONTIKI_PROJECT = test-phidgets blink test-adxl345 test-tmp102 test-light-ziglet test-battery test-sht11 test-relay-phidget test-tlc59116 #test-potent -CONTIKI_SOURCEFILES += sht11.c# potentiometer-sensor.c -APPS=serial-shell - - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../.. -include $(CONTIKI)/Makefile.include diff --git a/examples/z1/rssi_scanner/Makefile b/examples/z1/rssi_scanner/Makefile deleted file mode 100644 index 2e66213f5..000000000 --- a/examples/z1/rssi_scanner/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -DEFINES=PROJECT_CONF_H=\"project-conf.h\" - -# Define the target platform -ifndef TARGET -TARGET=z1 -endif - -CONTIKI_SOURCEFILES += cc2420-arch.c sensors.c sht11.c -PROJECT_SOURCEFILES = i2cmaster.c tmp102.c adxl345.c battery-sensor.c sky-sensors.c #potentiometer-sensor.c - -# Give a name to your project -CONTIKI = ../../../../contiki-2.x/ -CONTIKI_PROJECT = rssi-scanner - -# Compile project typing "make" -all: $(CONTIKI_PROJECT) - -# Upload project typing "make upload" -upload: $(CONTIKI_PROJECT).upload - -%.class: %.java - javac $(basename $<).java - -viewrssi3d: ViewRSSI3D.class - make login | java ViewRSSI3D - -viewrssi: ViewRSSI.class - make login | java ViewRSSI - -# ContikiProjects: including the makefile -#include ../../../Makefile.projects -include $(CONTIKI)/Makefile.include - diff --git a/examples/z1/tutorials/Makefile b/examples/z1/tutorials/Makefile deleted file mode 100644 index 66023ece8..000000000 --- a/examples/z1/tutorials/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -CONTIKI = ../../.. - -ifndef TARGET -TARGET=z1 -endif - -CONTIKI_PROJECT = test-phidgets blink test-adxl345 tmp102-test test-battery test-sht11 #test-potent -CONTIKI_SOURCEFILES += cc2420-arch.c sensors.c sht11.c -PROJECT_SOURCEFILES = i2cmaster.c tmp102.c adxl345.c battery-sensor.c sky-sensors.c #potentiometer-sensor.c -all: example-unicast2 - -include $(CONTIKI)/Makefile.include - - diff --git a/examples/z1/tutorials/example-unicast-temp.c b/examples/z1/tutorials/example-unicast-temp.c deleted file mode 100644 index 4dcc45904..000000000 --- a/examples/z1/tutorials/example-unicast-temp.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Best-effort single-hop unicast example - * \author - * Adam Dunkels - */ - -#include "contiki.h" -#include "net/rime/rime.h" - -#include "dev/button-sensor.h" - -#include "dev/leds.h" - -#include -#include "dev/i2cmaster.h" -#include "dev/tmp102.h" - -#if 1 -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif - - -#define SENDER 205 -#define RECEIVER 200 - - -#define PRINTFDEBUG(...) - - -#define TMP102_READ_INTERVAL (CLOCK_SECOND/2) - - int16_t tempint; - uint16_t tempfrac; - int16_t raw; - uint16_t absraw; - int16_t sign; - char minus = ' '; - -/*---------------------------------------------------------------------------*/ -PROCESS(example_unicast_process, "Example unicast"); -AUTOSTART_PROCESSES(&example_unicast_process); -/*---------------------------------------------------------------------------*/ -static void -recv_uc(struct unicast_conn *c, const linkaddr_t *from) -{ - printf("unicast message received from %d.%d\n", - from->u8[0], from->u8[1]); -} -static const struct unicast_callbacks unicast_callbacks = {recv_uc}; -static struct unicast_conn uc; -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(example_unicast_process, ev, data) -{ - PROCESS_EXITHANDLER(unicast_close(&uc);) - - PROCESS_BEGIN(); - - - tmp102_init(); - linkaddr_t addr; - unicast_open(&uc, 133, &unicast_callbacks); - SENSORS_ACTIVATE(button_sensor); - while(1) { - -PROCESS_WAIT_EVENT_UNTIL(ev==sensors_event && data == &button_sensor); - sign = 1; - - //PRINTFDEBUG ("Reading Temp...\n"); - raw = tmp102_read_temp_raw(); - - absraw = raw; - if (raw < 0) { // Perform 2C's if sensor returned negative data - absraw = (raw ^ 0xFFFF) + 1; - sign = -1; - } - tempint = (absraw >> 8) * sign; - tempfrac = ((absraw>>4) % 16) * 625; // Info in 1/10000 of degree - minus = ((tempint == 0) & (sign == -1)) ? '-' : ' ' ; - PRINTF ("Current Temp = %c%d.%04d\n", minus, tempint, tempfrac); - - - - char s[30]; - sprintf(s,"Temp is %c%d.%04d\n", minus, tempint, tempfrac); - printf("sending %s\n",s); - packetbuf_copyfrom(s, 30); - addr.u8[0] = RECEIVER; - addr.u8[1] = 0; - - unicast_send(&uc, &addr); - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ - diff --git a/examples/z1sp/Makefile b/examples/z1sp/Makefile deleted file mode 100644 index 74dd6b812..000000000 --- a/examples/z1sp/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -ifndef TARGET -TARGET=z1sp -endif - -CONTIKI_PROJECT = test-potentiometer -CONTIKI_SOURCEFILES += cc2420-arch.c -PROJECT_SOURCEFILES = sky-sensors.c potentiometer-sensor.c -APPS=serial-shell - - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../.. -include $(CONTIKI)/Makefile.include diff --git a/examples/z1sp/Makefile.target b/examples/z1sp/Makefile.target deleted file mode 100644 index 503d8f4fa..000000000 --- a/examples/z1sp/Makefile.target +++ /dev/null @@ -1 +0,0 @@ -TARGET = z1sp diff --git a/examples/zolertia/z1/Makefile b/examples/zolertia/z1/Makefile new file mode 100644 index 000000000..78b18d9dc --- /dev/null +++ b/examples/zolertia/z1/Makefile @@ -0,0 +1,20 @@ +ifndef TARGET +TARGET=z1 +endif + +# Enable to pull-in Z1SP specific test/source files +ZOLERTIA_Z1SP=0 + +CONTIKI_PROJECT = test-phidgets blink test-adxl345 test-tmp102 test-light-ziglet +CONTIKI_PROJECT += test-battery test-relay-phidget test-tlc59116 test-sht25 +CONTIKI_SOURCEFILES += sht11.c reed-sensor.c +APPS=serial-shell + +ifeq ($(ZOLERTIA_Z1SP),1) +CONTIKI_PROJECT += test-potent +endif + +all: $(CONTIKI_PROJECT) +CONTIKI = ../../.. +CONTIKI_WITH_RIME = 1 +include $(CONTIKI)/Makefile.include diff --git a/examples/z1/ipv6/z1-websense/Makefile b/examples/zolertia/z1/ipv6/z1-websense/Makefile similarity index 74% rename from examples/z1/ipv6/z1-websense/Makefile rename to examples/zolertia/z1/ipv6/z1-websense/Makefile index 2f48df333..8db74458e 100644 --- a/examples/z1/ipv6/z1-websense/Makefile +++ b/examples/zolertia/z1/ipv6/z1-websense/Makefile @@ -1,28 +1,27 @@ all: z1-websense -CONTIKI=../../../.. +CONTIKI = ../../../../.. -UIP_CONF_IPV6=1 - -SMALL=1 +SMALL = 1 APPS += webserver webbrowser CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" CONTIKI_SOURCEFILES += wget.c -PROJECTDIRS += ../../../ipv6/rpl-border-router +PROJECTDIRS += ../../../../ipv6/rpl-border-router PROJECT_SOURCEFILES += httpd-simple.c +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include $(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c (cd $(CONTIKI)/tools && $(MAKE) tunslip6) connect-router: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + sudo $(CONTIKI)/tools/tunslip6 fd00::1/64 connect-router-cooja: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 aaaa::1/64 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 fd00::1/64 CUSTOM_RULE_LINK=1 %.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a $(LD) $(LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} ${filter %.a,$^} $(TARGET_LIBFILES) -o $@ -lm diff --git a/examples/z1/ipv6/z1-websense/Makefile.target b/examples/zolertia/z1/ipv6/z1-websense/Makefile.target similarity index 100% rename from examples/z1/ipv6/z1-websense/Makefile.target rename to examples/zolertia/z1/ipv6/z1-websense/Makefile.target diff --git a/examples/z1/ipv6/z1-websense/README.md b/examples/zolertia/z1/ipv6/z1-websense/README.md similarity index 87% rename from examples/z1/ipv6/z1-websense/README.md rename to examples/zolertia/z1/ipv6/z1-websense/README.md index c3883bb00..82e7f34ee 100644 --- a/examples/z1/ipv6/z1-websense/README.md +++ b/examples/zolertia/z1/ipv6/z1-websense/README.md @@ -18,8 +18,9 @@ To test the example in COOJA under Linux make connect-router-cooja 3. You should now be able to browse to the nodes using your web browser: - Router: http://[aaaa::0212:7401:0001:0101]/ - Node 2: http://[aaaa::0212:7402:0002:0202]/ + + Router: http://[fd00::0212:7401:0001:0101]/ + Node 2: http://[fd00::0212:7402:0002:0202]/ To run the example on real nodes under Linux @@ -31,7 +32,7 @@ To run the example on real nodes under Linux 2. Disconnect the nodes and program one node with the RPL border router - cd ../rpl-border-router && make TARGET=z1 border-router.upload + cd examples/ipv6/rpl-border-router && make TARGET=z1 border-router.upload 3. Connect to the border router using tunslip6: diff --git a/examples/z1/ipv6/z1-websense/example-sky-websense.csc b/examples/zolertia/z1/ipv6/z1-websense/example-z1-websense.csc similarity index 74% rename from examples/z1/ipv6/z1-websense/example-sky-websense.csc rename to examples/zolertia/z1/ipv6/z1-websense/example-z1-websense.csc index 53696c5f2..87a20f781 100644 --- a/examples/z1/ipv6/z1-websense/example-sky-websense.csc +++ b/examples/zolertia/z1/ipv6/z1-websense/example-z1-websense.csc @@ -1,207 +1,201 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - - Sky Websense with RPL router - 0 - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - skyweb - Sky Websense - [CONTIKI_DIR]/examples/ipv6/sky-websense/sky-websense.c - make sky-websense.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/sky-websense/sky-websense.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - org.contikios.cooja.interfaces.Position - 62.239287566073514 - 34.43810269527116 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - skyweb - - - - - org.contikios.cooja.interfaces.Position - 56.71945435107925 - 20.293530081848317 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - skyweb - - - - - org.contikios.cooja.interfaces.Position - 75.34889145168493 - 24.43340499309403 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - skyweb - - - - - org.contikios.cooja.interfaces.Position - 92.59837024854205 - 38.57797760651687 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - skyweb - - - - - org.contikios.cooja.interfaces.Position - 47.68359039801751 - 47.26544238238854 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - skyweb - - - - org.contikios.cooja.plugins.SimControl - 259 - 4 - 179 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 2.898638306051894 0.0 0.0 2.898638306051894 -68.40918308040007 -27.82360366026197 - - 258 - 2 - 209 - 0 - 178 - - - org.contikios.cooja.plugins.LogListener - - - - 1024 - 3 - 311 - 0 - 385 - - - org.contikios.cooja.plugins.RadioLogger - - 150 - - - 769 - 0 - 342 - 255 - -1 - - - SerialSocketServer - 0 - 422 - 1 - 74 - 601 - 310 - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + + Z1 Websense with RPL router + 0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Z1MoteType + rplroot + Z1 RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.z1 TARGET=z1 + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.z1 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.Z1MoteType + Z1web + Z1 Websense + [CONTIKI_DIR]/examples/zolertia/z1/ipv6/z1-websense/z1-websense.c + make z1-websense.z1 TARGET=z1 + [CONTIKI_DIR]/examples/zolertia/z1/ipv6/z1-websense/z1-websense.z1 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + org.contikios.cooja.interfaces.Position + 62.239287566073514 + 34.43810269527116 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + Z1web + + + + + org.contikios.cooja.interfaces.Position + 56.71945435107925 + 20.293530081848317 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + Z1web + + + + + org.contikios.cooja.interfaces.Position + 75.34889145168493 + 24.43340499309403 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + Z1web + + + + + org.contikios.cooja.interfaces.Position + 92.59837024854205 + 38.57797760651687 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + Z1web + + + + + org.contikios.cooja.interfaces.Position + 47.68359039801751 + 47.26544238238854 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + Z1web + + + + org.contikios.cooja.plugins.SimControl + 259 + 4 + 179 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.898638306051894 0.0 0.0 2.898638306051894 -68.40918308040007 -27.82360366026197 + + 258 + 2 + 209 + 0 + 178 + + + org.contikios.cooja.plugins.LogListener + + + + 1024 + 3 + 311 + 0 + 385 + + + org.contikios.cooja.plugins.RadioLogger + + 150 + + + 769 + 0 + 342 + 255 + -1 + + + org.contikios.cooja.serialsocket.SerialSocketServer + 0 + 422 + 1 + 74 + 601 + 310 + + diff --git a/examples/z1/ipv6/z1-websense/project-conf.h b/examples/zolertia/z1/ipv6/z1-websense/project-conf.h similarity index 100% rename from examples/z1/ipv6/z1-websense/project-conf.h rename to examples/zolertia/z1/ipv6/z1-websense/project-conf.h diff --git a/examples/z1/ipv6/z1-websense/websense-remote.c b/examples/zolertia/z1/ipv6/z1-websense/websense-remote.c similarity index 93% rename from examples/z1/ipv6/z1-websense/websense-remote.c rename to examples/zolertia/z1/ipv6/z1-websense/websense-remote.c index 7323293ca..a6336260d 100644 --- a/examples/z1/ipv6/z1-websense/websense-remote.c +++ b/examples/zolertia/z1/ipv6/z1-websense/websense-remote.c @@ -27,7 +27,7 @@ * SUCH DAMAGE. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * A simple example using HTTP to control and be controlled @@ -35,7 +35,7 @@ * Niclas Finne * Joakim Eriksson */ - +/*---------------------------------------------------------------------------*/ #include "contiki.h" #include "dev/button-sensor.h" #include "dev/leds.h" @@ -43,24 +43,22 @@ #include "webserver-nogui.h" #include "httpd-simple.h" #include - +/*---------------------------------------------------------------------------*/ /* The address of the server to register the services for this node */ -#define SERVER "aaaa::1" +#define SERVER "fd00::1" /* This command registers two services (/0 and /1) to turn the leds on or off */ #define REGISTER_COMMAND "/r?p=0&d=Turn%20off%20leds&p=1&d=Turn%20on%20leds" /* The address of the other node to control */ -#define OTHER_NODE "aaaa::212:7403:3:303" +#define OTHER_NODE "fd00::212:7403:3:303" /* The commands to send to the other node */ #define SET_LEDS_ON "/1" #define SET_LEDS_OFF "/0" - +/*---------------------------------------------------------------------------*/ PROCESS(websense_remote_process, "Websense Remote"); - AUTOSTART_PROCESSES(&websense_remote_process); - /*---------------------------------------------------------------------------*/ static const char *TOP = "Contiki Websense Remote\n"; static const char *BOTTOM = "\n"; @@ -161,7 +159,6 @@ PROCESS_THREAD(websense_remote_process, ev, data) } /* Alternate between the two commands */ mode = !mode; - } else if(ev == PROCESS_EVENT_TIMER && etimer_expired(&timer)) { printf("Registering services\n"); send_command(SERVER, REGISTER_COMMAND); diff --git a/examples/z1/ipv6/z1-websense/wget.c b/examples/zolertia/z1/ipv6/z1-websense/wget.c similarity index 87% rename from examples/z1/ipv6/z1-websense/wget.c rename to examples/zolertia/z1/ipv6/z1-websense/wget.c index 3d9b56974..d55040b11 100644 --- a/examples/z1/ipv6/z1-websense/wget.c +++ b/examples/zolertia/z1/ipv6/z1-websense/wget.c @@ -27,7 +27,7 @@ * SUCH DAMAGE. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * A simple wget implementation @@ -35,28 +35,29 @@ * Niclas Finne * Joakim Eriksson */ - +/*---------------------------------------------------------------------------*/ #include "webclient.h" #include "wget.h" #include "dev/leds.h" - +/*---------------------------------------------------------------------------*/ #define DEBUG DEBUG_NONE #include "net/ip/uip-debug.h" - +/*---------------------------------------------------------------------------*/ #define DEBUG_LEDS 0 #undef LEDS_ON #undef LEDS_OFF + #if DEBUG_LEDS #define LEDS_ON(led) leds_on(led) #define LEDS_OFF(led) leds_off(led) #else #define LEDS_ON(led) #define LEDS_OFF(led) -#endif /* DEBUG */ - +#endif /* DEBUG_LEDS */ +/*---------------------------------------------------------------------------*/ static int fetch_running; -#define STATS ((DEBUG) & DEBUG_PRINT) && 1 +#define STATS ((DEBUG)&DEBUG_PRINT) && 1 #if STATS static clock_time_t fetch_started; static unsigned long fetch_counter; @@ -66,9 +67,8 @@ static const char *server; static const char *file; static uint16_t port; static const struct wget_callbacks *callbacks; - +/*---------------------------------------------------------------------------*/ PROCESS(wget_process, "wget"); - /*---------------------------------------------------------------------------*/ static void call_done(int status) @@ -115,11 +115,11 @@ webclient_datahandler(char *data, uint16_t len) PRINTF("wget: recv %lu bytes during %lu sec (", fetch_counter, (elapsed / CLOCK_SECOND)); #if CLOCK_SECOND == 128 - PRINTF("%lu.%02lus, ", (unsigned long) elapsed >> 7, + PRINTF("%lu.%02lus, ", (unsigned long)elapsed >> 7, (unsigned long)((elapsed & 127) * 100) / 128); PRINTF("%lu byte/sec ", (fetch_counter * 128L) / elapsed); #endif - PRINTF("%lu tick): ", (unsigned long) elapsed); + PRINTF("%lu tick): ", (unsigned long)elapsed); if(elapsed > CLOCK_SECOND) { PRINTF("%lu", fetch_counter / (elapsed / CLOCK_SECOND)); } else { @@ -132,7 +132,7 @@ webclient_datahandler(char *data, uint16_t len) fetch_running = 0; call_done(WGET_OK); - LEDS_OFF(LEDS_RED|LEDS_YELLOW); + LEDS_OFF(LEDS_RED | LEDS_YELLOW); } else { #if STATS fetch_counter += len; @@ -156,7 +156,7 @@ void webclient_timedout(void) { PRINTF("wget: timedout\n"); - LEDS_OFF(LEDS_RED|LEDS_YELLOW); + LEDS_OFF(LEDS_RED | LEDS_YELLOW); fetch_running = 0; call_done(WGET_TIMEDOUT); } @@ -165,7 +165,7 @@ void webclient_aborted(void) { PRINTF("wget: aborted\n"); - LEDS_OFF(LEDS_RED|LEDS_YELLOW); + LEDS_OFF(LEDS_RED | LEDS_YELLOW); fetch_running = 0; call_done(WGET_ABORTED); } @@ -175,7 +175,7 @@ webclient_closed(void) { PRINTF("wget: closed\n"); fetch_running = 0; - LEDS_OFF(LEDS_RED|LEDS_YELLOW); + LEDS_OFF(LEDS_RED | LEDS_YELLOW); call_done(WGET_CLOSED); } /*---------------------------------------------------------------------------*/ diff --git a/examples/z1/ipv6/z1-websense/wget.h b/examples/zolertia/z1/ipv6/z1-websense/wget.h similarity index 96% rename from examples/z1/ipv6/z1-websense/wget.h rename to examples/zolertia/z1/ipv6/z1-websense/wget.h index b87f69692..28ab27aed 100644 --- a/examples/z1/ipv6/z1-websense/wget.h +++ b/examples/zolertia/z1/ipv6/z1-websense/wget.h @@ -42,8 +42,8 @@ #include "contiki.h" struct wget_callbacks { - void (* data)(const char *data, uint16_t len); - void (* done)(int status); + void (*data)(const char *data, uint16_t len); + void (*done)(int status); }; void wget_init(void); diff --git a/examples/z1/ipv6/z1-websense/z1-websense.c b/examples/zolertia/z1/ipv6/z1-websense/z1-websense.c similarity index 83% rename from examples/z1/ipv6/z1-websense/z1-websense.c rename to examples/zolertia/z1/ipv6/z1-websense/z1-websense.c index 5e8bedb1e..9dca126e9 100644 --- a/examples/z1/ipv6/z1-websense/z1-websense.c +++ b/examples/zolertia/z1/ipv6/z1-websense/z1-websense.c @@ -27,7 +27,7 @@ * SUCH DAMAGE. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * Battery and Temperature IPv6 Demo for Zolertia Z1 @@ -37,7 +37,7 @@ * Joel Hoglund * Enric M. Calvo */ - +/*---------------------------------------------------------------------------*/ #include "contiki.h" #include "httpd-simple.h" #include "webserver-nogui.h" @@ -46,22 +46,23 @@ #include "cc2420.h" #include "dev/leds.h" #include - - -float floor(float x){ - if(x>=0.0f) return (float) ((int)x); - else return (float) ((int)x-1); +/*---------------------------------------------------------------------------*/ +float +floor(float x) +{ + if(x >= 0.0f) { + return (float)((int)x); + } else { return (float)((int)x - 1); + } } - +/*---------------------------------------------------------------------------*/ PROCESS(web_sense_process, "Sense Web Demo"); - AUTOSTART_PROCESSES(&web_sense_process); - +/*---------------------------------------------------------------------------*/ #define HISTORY 16 static int temperature[HISTORY]; static int battery1[HISTORY]; static int sensors_pos; - /*---------------------------------------------------------------------------*/ static int get_battery(void) @@ -74,10 +75,16 @@ get_temp(void) { return temperature_sensor.value(0); } - -static float get_mybatt(void){ return (float) ((get_battery()*2.500*2)/4096);} -static float get_mytemp(void){ return (float) (((get_temp()*2.500)/4096)-0.986)*282;} - +static float +get_mybatt(void) +{ + return (float)((get_battery() * 2.500 * 2) / 4096); +} +static float +get_mytemp(void) +{ + return (float)(((get_temp() * 2.500) / 4096) - 0.986) * 282; +} /*---------------------------------------------------------------------------*/ static const char *TOP = "Contiki Web Sense\n"; static const char *BOTTOM = "\n"; @@ -85,11 +92,13 @@ static const char *BOTTOM = "\n"; /* Only one single request at time */ static char buf[256]; static int blen; -#define ADD(...) do { \ - blen += snprintf(&buf[blen], sizeof(buf) - blen, __VA_ARGS__); \ - } while(0) +#define ADD(...) do { \ + blen += snprintf(&buf[blen], sizeof(buf) - blen, __VA_ARGS__); \ +} while(0) +/*---------------------------------------------------------------------------*/ static void -generate_chart(const char *title, const char *unit, int min, int max, int *values) +generate_chart(const char *title, const char *unit, int min, int max, + int *values) { int i; blen = 0; @@ -103,6 +112,7 @@ generate_chart(const char *title, const char *unit, int min, int max, int *value } ADD("\">"); } +/*---------------------------------------------------------------------------*/ static PT_THREAD(send_values(struct httpd_state *s)) { @@ -120,20 +130,17 @@ PT_THREAD(send_values(struct httpd_state *s)) ADD("

    Current readings

    \n" "Battery: %ld.%03d V
    " "Temperature: %ld.%03d ° C", - (long) mybatt, (unsigned) ((mybatt-floor(mybatt))*1000), - (long) mytemp, (unsigned) ((mytemp-floor(mytemp))*1000)); + (long)mybatt, (unsigned)((mybatt - floor(mybatt)) * 1000), + (long)mytemp, (unsigned)((mytemp - floor(mytemp)) * 1000)); SEND_STRING(&s->sout, buf); - } else if(s->filename[1] == '0') { /* Turn off leds */ leds_off(LEDS_ALL); SEND_STRING(&s->sout, "Turned off leds!"); - } else if(s->filename[1] == '1') { /* Turn on leds */ leds_on(LEDS_ALL); SEND_STRING(&s->sout, "Turned on leds!"); - } else { if(s->filename[1] != 't') { generate_chart("Battery", "mV", 0, 4000, battery1); @@ -173,7 +180,7 @@ PROCESS_THREAD(web_sense_process, ev, data) PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer)); etimer_reset(&timer); - battery1[sensors_pos] = get_mybatt()*1000; + battery1[sensors_pos] = get_mybatt() * 1000; temperature[sensors_pos] = get_mytemp(); sensors_pos = (sensors_pos + 1) % HISTORY; } diff --git a/examples/z1/test-adxl345.c b/examples/zolertia/z1/test-adxl345.c similarity index 53% rename from examples/z1/test-adxl345.c rename to examples/zolertia/z1/test-adxl345.c index 48fa175dd..a5e199bef 100644 --- a/examples/z1/test-adxl345.c +++ b/examples/zolertia/z1/test-adxl345.c @@ -42,41 +42,29 @@ #include #include "contiki.h" -#include "serial-shell.h" -#include "shell-ps.h" -#include "shell-file.h" -#include "shell-text.h" +#include "dev/leds.h" #include "dev/adxl345.h" - -#define LED_INT_ONTIME CLOCK_SECOND/2 +/*---------------------------------------------------------------------------*/ +#define LED_INT_ONTIME (CLOCK_SECOND / 2) #define ACCM_READ_INTERVAL CLOCK_SECOND - -static process_event_t ledOff_event; +/*---------------------------------------------------------------------------*/ +static process_event_t led_off_event; +static struct etimer led_etimer; +static struct etimer et; /*---------------------------------------------------------------------------*/ PROCESS(accel_process, "Test Accel process"); PROCESS(led_process, "LED handling process"); AUTOSTART_PROCESSES(&accel_process, &led_process); /*---------------------------------------------------------------------------*/ -/* As several interrupts can be mapped to one interrupt pin, when interrupt - strikes, the adxl345 interrupt source register is read. This function prints - out which interrupts occurred. Note that this will include all interrupts, - even those mapped to 'the other' pin, and those that will always signal even if - not enabled (such as watermark). */ - +/* As several interrupts can be mapped to one interrupt pin, when interrupt + * strikes, the adxl345 interrupt source register is read. This function prints + * out which interrupts occurred. Note that this will include all interrupts, + * even those mapped to 'the other' pin, and those that will always signal even + * if not enabled (such as watermark). + */ void -print_int(uint16_t reg){ -#define ANNOYING_ALWAYS_THERE_ANYWAY_OUTPUT 0 -#if ANNOYING_ALWAYS_THERE_ANYWAY_OUTPUT - if(reg & ADXL345_INT_OVERRUN) { - printf("Overrun "); - } - if(reg & ADXL345_INT_WATERMARK) { - printf("Watermark "); - } - if(reg & ADXL345_INT_DATAREADY) { - printf("DataReady "); - } -#endif +print_int(uint16_t reg) +{ if(reg & ADXL345_INT_FREEFALL) { printf("Freefall "); } @@ -94,110 +82,84 @@ print_int(uint16_t reg){ } printf("\n"); } - /*---------------------------------------------------------------------------*/ /* accelerometer free fall detection callback */ void -accm_ff_cb(uint8_t reg){ - L_ON(LEDS_B); - process_post(&led_process, ledOff_event, NULL); - printf("~~[%u] Freefall detected! (0x%02X) -- ", ((uint16_t) clock_time())/128, reg); +accm_ff_cb(uint8_t reg) +{ + leds_on(LEDS_BLUE); + process_post(&led_process, led_off_event, NULL); + printf("~~[%u] Freefall detected! (0x%02X) -- ", + ((uint16_t)clock_time()) / 128, reg); print_int(reg); } /*---------------------------------------------------------------------------*/ /* accelerometer tap and double tap detection callback */ void -accm_tap_cb(uint8_t reg){ - process_post(&led_process, ledOff_event, NULL); - if(reg & ADXL345_INT_DOUBLETAP){ - L_ON(LEDS_G); - printf("~~[%u] DoubleTap detected! (0x%02X) -- ", ((uint16_t) clock_time())/128, reg); +accm_tap_cb(uint8_t reg) +{ + process_post(&led_process, led_off_event, NULL); + if(reg & ADXL345_INT_DOUBLETAP) { + leds_on(LEDS_GREEN); + printf("~~[%u] DoubleTap detected! (0x%02X) -- ", + ((uint16_t)clock_time()) / 128, reg); } else { - L_ON(LEDS_R); - printf("~~[%u] Tap detected! (0x%02X) -- ", ((uint16_t) clock_time())/128, reg); + leds_on(LEDS_RED); + printf("~~[%u] Tap detected! (0x%02X) -- ", + ((uint16_t)clock_time()) / 128, reg); } print_int(reg); } /*---------------------------------------------------------------------------*/ -/* When posted an ledOff event, the LEDs will switch off after LED_INT_ONTIME. - static process_event_t ledOff_event; - ledOff_event = process_alloc_event(); - process_post(&led_process, ledOff_event, NULL); -*/ - -static struct etimer ledETimer; PROCESS_THREAD(led_process, ev, data) { PROCESS_BEGIN(); - while(1){ - PROCESS_WAIT_EVENT_UNTIL(ev == ledOff_event); - etimer_set(&ledETimer, LED_INT_ONTIME); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&ledETimer)); - L_OFF(LEDS_R + LEDS_G + LEDS_B); + while(1) { + PROCESS_WAIT_EVENT_UNTIL(ev == led_off_event); + etimer_set(&led_etimer, LED_INT_ONTIME); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&led_etimer)); + leds_off(LEDS_RED + LEDS_GREEN + LEDS_BLUE); } PROCESS_END(); } - -/*---------------------------------------------------------------------------*/ -/* Returns a string with the argument byte written in binary. - Example usage: - printf("Port1: %s\n", char2bin(P1IN)); -*/ -/* -static uint8_t b[9]; - -static uint8_t -*char2bin(uint8_t x) { - uint8_t z; - b[8] = '\0'; - for (z = 0; z < 8; z++) { - b[7-z] = (x & (1 << z)) ? '1' : '0'; - } - return b; -} -*/ /*---------------------------------------------------------------------------*/ /* Main process, setups */ - -static struct etimer et; - -PROCESS_THREAD(accel_process, ev, data) { +PROCESS_THREAD(accel_process, ev, data) +{ PROCESS_BEGIN(); - { - int16_t x, y, z; - serial_shell_init(); - shell_ps_init(); - shell_file_init(); // for printing out files - shell_text_init(); // for binprint + int16_t x, y, z; - /* Register the event used for lighting up an LED when interrupt strikes. */ - ledOff_event = process_alloc_event(); + /* Register the event used for lighting up an LED when interrupt strikes. */ + led_off_event = process_alloc_event(); - /* Start and setup the accelerometer with default values, eg no interrupts enabled. */ - accm_init(); + /* Start and setup the accelerometer with default values, eg no interrupts + * enabled. + */ + SENSORS_ACTIVATE(adxl345); - /* Register the callback functions for each interrupt */ - ACCM_REGISTER_INT1_CB(accm_ff_cb); - ACCM_REGISTER_INT2_CB(accm_tap_cb); + /* Register the callback functions for each interrupt */ + ACCM_REGISTER_INT1_CB(accm_ff_cb); + ACCM_REGISTER_INT2_CB(accm_tap_cb); - /* Set what strikes the corresponding interrupts. Several interrupts per pin is - possible. For the eight possible interrupts, see adxl345.h and adxl345 datasheet. */ - accm_set_irq(ADXL345_INT_FREEFALL, ADXL345_INT_TAP + ADXL345_INT_DOUBLETAP); + /* Set what strikes the corresponding interrupts. Several interrupts per + * pin is possible. For the eight possible interrupts, see adxl345.h and + * adxl345 datasheet. + */ + accm_set_irq(ADXL345_INT_FREEFALL, ADXL345_INT_TAP + ADXL345_INT_DOUBLETAP); - while (1) { - x = accm_read_axis(X_AXIS); - y = accm_read_axis(Y_AXIS); - z = accm_read_axis(Z_AXIS); - printf("x: %d y: %d z: %d\n", x, y, z); + while(1) { + x = adxl345.value(X_AXIS); + y = adxl345.value(Y_AXIS); + z = adxl345.value(Z_AXIS); + printf("x: %d y: %d z: %d\n", x, y, z); - etimer_set(&et, ACCM_READ_INTERVAL); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - } + etimer_set(&et, ACCM_READ_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); } + PROCESS_END(); } - /*---------------------------------------------------------------------------*/ diff --git a/examples/z1/test-battery.c b/examples/zolertia/z1/test-battery.c similarity index 85% rename from examples/z1/test-battery.c rename to examples/zolertia/z1/test-battery.c index fb39e91d3..b10dbe6d5 100644 --- a/examples/z1/test-battery.c +++ b/examples/zolertia/z1/test-battery.c @@ -29,30 +29,27 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * Testing the internal MSP430 battery sensor on the Zolertia Z1 Platform. * \author * Enric M. Calvo */ - - +/*---------------------------------------------------------------------------*/ #include "contiki.h" #include "dev/battery-sensor.h" -#include /* For printf() */ - - +#include +/*---------------------------------------------------------------------------*/ float floor(float x) { if(x >= 0.0f) { - return (float) ((int) x); + return (float)((int)x); } else { - return (float) ((int) x - 1); + return (float)((int)x - 1); } } - /*---------------------------------------------------------------------------*/ PROCESS(test_battery_process, "Battery Sensor Test"); AUTOSTART_PROCESSES(&test_battery_process); @@ -67,13 +64,12 @@ PROCESS_THREAD(test_battery_process, ev, data) while(1) { uint16_t bateria = battery_sensor.value(0); float mv = (bateria * 2.500 * 2) / 4096; - printf("Battery: %i (%ld.%03d mV)\n", bateria, (long) mv, - (unsigned) ((mv - floor(mv)) * 1000)); + printf("Battery: %i (%ld.%03d mV)\n", bateria, (long)mv, + (unsigned)((mv - floor(mv)) * 1000)); } SENSORS_DEACTIVATE(battery_sensor); PROCESS_END(); } - /*---------------------------------------------------------------------------*/ diff --git a/examples/z1/test-light-ziglet.c b/examples/zolertia/z1/test-light-ziglet.c similarity index 77% rename from examples/z1/test-light-ziglet.c rename to examples/zolertia/z1/test-light-ziglet.c index 103163e19..ce292dff0 100644 --- a/examples/z1/test-light-ziglet.c +++ b/examples/zolertia/z1/test-light-ziglet.c @@ -29,55 +29,39 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * A quick program for testing the light ziglet driver in the Z1 platform * \author * Antonio Lignan */ - +/*---------------------------------------------------------------------------*/ #include #include "contiki.h" #include "dev/i2cmaster.h" #include "dev/light-ziglet.h" - - -#if 1 -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif - - -#if 0 -#define PRINTFDEBUG(...) printf(__VA_ARGS__) -#else -#define PRINTFDEBUG(...) -#endif - - -#define SENSOR_READ_INTERVAL (CLOCK_SECOND) - +/*---------------------------------------------------------------------------*/ +#define SENSOR_READ_INTERVAL (CLOCK_SECOND / 2) +/*---------------------------------------------------------------------------*/ PROCESS(test_process, "Test light ziglet process"); AUTOSTART_PROCESSES(&test_process); /*---------------------------------------------------------------------------*/ static struct etimer et; - +/*---------------------------------------------------------------------------*/ PROCESS_THREAD(test_process, ev, data) { PROCESS_BEGIN(); - uint16_t light; - + /* Initialize driver and set a slower data rate */ light_ziglet_init(); + i2c_setrate(I2C_PRESC_100KHZ_LSB, I2C_PRESC_100KHZ_MSB); while(1) { etimer_set(&et, SENSOR_READ_INTERVAL); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - - light = light_ziglet_read(); - PRINTF("Light = %u\n", light); + printf("Light = %u\n", light_ziglet_read()); } PROCESS_END(); } +/*---------------------------------------------------------------------------*/ diff --git a/examples/z1/test-phidgets.c b/examples/zolertia/z1/test-phidgets.c similarity index 88% rename from examples/z1/test-phidgets.c rename to examples/zolertia/z1/test-phidgets.c index 2ad9ee000..5dbdaf497 100644 --- a/examples/z1/test-phidgets.c +++ b/examples/zolertia/z1/test-phidgets.c @@ -29,52 +29,48 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file - * An example of how to use the button and light sensor on - * the Z1 platform. + * An example of how to use the button and read the ADC ports * \author * Joakim Eriksson */ - +/*---------------------------------------------------------------------------*/ #include #include "contiki.h" #include "dev/button-sensor.h" #include "dev/leds.h" #include "dev/z1-phidgets.h" - /*---------------------------------------------------------------------------*/ -PROCESS(test_button_process, "Test Button & Phidgets"); +PROCESS(test_button_process, "Test Button & ADC"); AUTOSTART_PROCESSES(&test_button_process); /*---------------------------------------------------------------------------*/ PROCESS_THREAD(test_button_process, ev, data) { - //static struct etimer et; + /* static struct etimer et; */ PROCESS_BEGIN(); SENSORS_ACTIVATE(phidgets); SENSORS_ACTIVATE(button_sensor); while(1) { - //etimer_set(&et, CLOCK_SECOND/2); printf("Please press the User Button\n"); + PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event && data == &button_sensor); - //PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); leds_toggle(LEDS_GREEN); - //printf("Button clicked\n"); + printf("Phidget 5V 1:%d\n", phidgets.value(PHIDGET5V_1)); printf("Phidget 5V 2:%d\n", phidgets.value(PHIDGET5V_2)); printf("Phidget 3V 1:%d\n", phidgets.value(PHIDGET3V_1)); printf("Phidget 3V 2:%d\n", phidgets.value(PHIDGET3V_2)); - if (phidgets.value(PHIDGET3V_1) < 100) { + if(phidgets.value(PHIDGET3V_1) < 100) { leds_on(LEDS_RED); } else { leds_off(LEDS_RED); } - } PROCESS_END(); } diff --git a/examples/z1/test-potent.c b/examples/zolertia/z1/test-potent.c similarity index 91% rename from examples/z1/test-potent.c rename to examples/zolertia/z1/test-potent.c index 7a2881d80..ecf92413f 100644 --- a/examples/z1/test-potent.c +++ b/examples/zolertia/z1/test-potent.c @@ -29,19 +29,17 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * Testing the Potentiometer in Zolertia Z1 Starter Platform. * \author * Enric M. Calvo */ - +/*---------------------------------------------------------------------------*/ #include "contiki.h" #include "dev/potentiometer-sensor.h" -#include - - +#include /*---------------------------------------------------------------------------*/ PROCESS(test_potent_process, "Testing Potentiometer in Z1SP"); AUTOSTART_PROCESSES(&test_potent_process); @@ -56,13 +54,11 @@ PROCESS_THREAD(test_potent_process, ev, data) while(1) { uint16_t value = potentiometer_sensor.value(0); - printf("Potentiometer Value: %i\n", v); + printf("Potentiometer Value: %u\n", value); } SENSORS_DEACTIVATE(potentiometer_sensor); PROCESS_END(); } - /*---------------------------------------------------------------------------*/ - diff --git a/examples/zolertia/z1/test-reed-sensor.c b/examples/zolertia/z1/test-reed-sensor.c new file mode 100644 index 000000000..799f913cf --- /dev/null +++ b/examples/zolertia/z1/test-reed-sensor.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/** + * \file + * A quick program for testing a reed sensor. + * \author + * Antonio Lignan + */ + +#include +#include "contiki.h" +#include "reed-sensor.h" +#define REED_READ_INTERVAL (CLOCK_SECOND / 4) +#define REED_EXAMPLE_EVENT 1 +/*---------------------------------------------------------------------------*/ +PROCESS(test_process, "Reed test process"); +AUTOSTART_PROCESSES(&test_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_process, ev, data) +{ + PROCESS_BEGIN(); + + SENSORS_ACTIVATE(reed_sensor); +#if REED_EXAMPLE_EVENT + reed_sensor.configure(REED_SENSOR_MODE, REED_SENSOR_EVENT_MODE); +#else + etimer_set(&et, REED_READ_INTERVAL); +#endif + + while(1) { + + PROCESS_YIELD(); + + if(ev == PROCESS_EVENT_TIMER) { + printf("Reed poll status [%d]\n", reed_sensor.value(REED_SENSOR_VAL)); + etimer_restart(&et); + } else if(ev == reed_sensor_event_changed) { + printf("Reed sensor event --> %d\n", (*((int *)data))); + } + } + PROCESS_END(); +} diff --git a/examples/z1/test-relay-phidget.c b/examples/zolertia/z1/test-relay-phidget.c similarity index 83% rename from examples/z1/test-relay-phidget.c rename to examples/zolertia/z1/test-relay-phidget.c index 9aad55f1b..2f1bef99a 100644 --- a/examples/z1/test-relay-phidget.c +++ b/examples/zolertia/z1/test-relay-phidget.c @@ -29,7 +29,7 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * A quick program for testing a generic relay device connected in the @@ -37,33 +37,24 @@ * \author * Antonio Lignan */ - +/*---------------------------------------------------------------------------*/ #include #include "contiki.h" #include "dev/relay-phidget.h" - - -#if 1 +/*---------------------------------------------------------------------------*/ +#if DEBUG #define PRINTF(...) printf(__VA_ARGS__) #else #define PRINTF(...) #endif - - -#if 0 -#define PRINTFDEBUG(...) printf(__VA_ARGS__) -#else -#define PRINTFDEBUG(...) -#endif - - +/*---------------------------------------------------------------------------*/ #define RELAY_INTERVAL (CLOCK_SECOND) - +/*---------------------------------------------------------------------------*/ PROCESS(test_process, "Relay test process"); AUTOSTART_PROCESSES(&test_process); /*---------------------------------------------------------------------------*/ static struct etimer et; -static uint8_t status; +static int8_t status; PROCESS_THREAD(test_process, ev, data) { @@ -75,9 +66,10 @@ PROCESS_THREAD(test_process, ev, data) while(1) { etimer_set(&et, RELAY_INTERVAL); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - + status = relay_toggle(); PRINTF("Relay [%d]\n", status); } PROCESS_END(); } +/*---------------------------------------------------------------------------*/ diff --git a/examples/z1/test-sht11.c b/examples/zolertia/z1/test-sht11.c similarity index 79% rename from examples/z1/test-sht11.c rename to examples/zolertia/z1/test-sht11.c index ff812eec3..b71d87711 100644 --- a/examples/z1/test-sht11.c +++ b/examples/zolertia/z1/test-sht11.c @@ -29,7 +29,7 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * Testing the SHT11 sensor on the Zolertia Z1 Platform. @@ -37,15 +37,15 @@ * Nicolas Tsiftes * Enric M. Calvo */ - +/*---------------------------------------------------------------------------*/ #include "contiki.h" #include "dev/sht11/sht11.h" #include - +/*---------------------------------------------------------------------------*/ PROCESS(test_sht11_process, "SHT11 test"); AUTOSTART_PROCESSES(&test_sht11_process); - +/*---------------------------------------------------------------------------*/ PROCESS_THREAD(test_sht11_process, ev, data) { static struct etimer et; @@ -54,14 +54,15 @@ PROCESS_THREAD(test_sht11_process, ev, data) PROCESS_BEGIN(); sht11_init(); - for (etimer_set(&et, CLOCK_SECOND);; etimer_reset(&et)) { + for(etimer_set(&et, CLOCK_SECOND);; etimer_reset(&et)) { PROCESS_YIELD(); printf("Temperature: %u degrees Celsius\n", - (unsigned) (-39.60 + 0.01 * sht11_temp())); + (unsigned)(-39.60 + 0.01 * sht11_temp())); rh = sht11_humidity(); printf("Rel. humidity: %u%%\n", - (unsigned) (-4 + 0.0405*rh - 2.8e-6*(rh*rh))); + (unsigned)(-4 + 0.0405 * rh - 2.8e-6 * (rh * rh))); } PROCESS_END(); } +/*---------------------------------------------------------------------------*/ diff --git a/examples/z1/tutorials/example-unicast2.c b/examples/zolertia/z1/test-sht25.c similarity index 68% rename from examples/z1/tutorials/example-unicast2.c rename to examples/zolertia/z1/test-sht25.c index a58650722..092935937 100644 --- a/examples/z1/tutorials/example-unicast2.c +++ b/examples/zolertia/z1/test-sht25.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Swedish Institute of Computer Science. + * Copyright (c) 2015, Zolertia * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,61 +29,38 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file - * Best-effort single-hop unicast example + * A quick program for testing the SHT25 temperature and humidity sensor * \author - * Adam Dunkels + * Antonio Lignan */ - -#include "contiki.h" -#include "net/rime/rime.h" - -#include "dev/button-sensor.h" - -#include "dev/leds.h" - +/*---------------------------------------------------------------------------*/ #include +#include "contiki.h" +#include "dev/sht25.h" +/*---------------------------------------------------------------------------*/ +PROCESS(test_sht25_process, "SHT25 test"); +AUTOSTART_PROCESSES(&test_sht25_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_sht25_process, ev, data) +{ + int16_t temperature, humidity; -/*---------------------------------------------------------------------------*/ -PROCESS(example_unicast_process, "Example unicast"); -AUTOSTART_PROCESSES(&example_unicast_process); -/*---------------------------------------------------------------------------*/ -static void -recv_uc(struct unicast_conn *c, const linkaddr_t *from) -{ - printf("unicast message received from %d.%d\n", - from->u8[0], from->u8[1]); -} -static const struct unicast_callbacks unicast_callbacks = {recv_uc}; -static struct unicast_conn uc; -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(example_unicast_process, ev, data) -{ - PROCESS_EXITHANDLER(unicast_close(&uc);) - PROCESS_BEGIN(); - - unicast_open(&uc, 199, &unicast_callbacks); + SENSORS_ACTIVATE(sht25); while(1) { - static struct etimer et; - linkaddr_t addr; - etimer_set(&et, CLOCK_SECOND); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - - //packetbuf_copyfrom("Enric Here!", 12); - //addr.u8[0] = 200; - //addr.u8[1] = 0; - //if(!linkaddr_cmp(&addr, &linkaddr_node_addr)) { - //unicast_send(&uc, &addr); - //} - + temperature = sht25.value(SHT25_VAL_TEMP); + printf("Temperature %d.%d ºC\n", temperature / 100, temperature % 100); + humidity = sht25.value(SHT25_VAL_HUM); + printf("Humidity %d.%d %%RH\n", humidity / 100, humidity % 100); } - PROCESS_END(); } /*---------------------------------------------------------------------------*/ diff --git a/examples/z1/test-tlc59116.c b/examples/zolertia/z1/test-tlc59116.c similarity index 87% rename from examples/z1/test-tlc59116.c rename to examples/zolertia/z1/test-tlc59116.c index 36dda845e..3d389a4ea 100644 --- a/examples/z1/test-tlc59116.c +++ b/examples/zolertia/z1/test-tlc59116.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2013, Jelmer Tiete. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -12,8 +12,8 @@ * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior - * written permission. - * + * written permission. + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -25,11 +25,11 @@ * 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. - * + * * This file is part of the Contiki operating system. - * + * */ - +/*---------------------------------------------------------------------------*/ /** * \file * A simple program for testing the TLC59116 I2C led driver. @@ -37,23 +37,21 @@ * \author * Jelmer Tiete, VUB */ - +/*---------------------------------------------------------------------------*/ #include #include "contiki.h" #include "dev/tlc59116.h" - -#define BLINK_INTERVAL CLOCK_SECOND/25 - +/*---------------------------------------------------------------------------*/ +#define BLINK_INTERVAL (CLOCK_SECOND / 25) /*---------------------------------------------------------------------------*/ PROCESS(tlc59116_process, "Test tlc59116 process"); AUTOSTART_PROCESSES(&tlc59116_process); - /*---------------------------------------------------------------------------*/ /* Main process, setups */ static struct etimer et; static uint8_t count = 0; - +/*---------------------------------------------------------------------------*/ PROCESS_THREAD(tlc59116_process, ev, data) { PROCESS_BEGIN(); @@ -80,5 +78,4 @@ PROCESS_THREAD(tlc59116_process, ev, data) } PROCESS_END(); } - /*---------------------------------------------------------------------------*/ diff --git a/examples/z1/test-tmp102.c b/examples/zolertia/z1/test-tmp102.c similarity index 67% rename from examples/z1/test-tmp102.c rename to examples/zolertia/z1/test-tmp102.c index 3f6f37ec4..ab5e7aca8 100644 --- a/examples/z1/test-tmp102.c +++ b/examples/zolertia/z1/test-tmp102.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Zolertia(TM) is a trademark of Advancare,SL + * Copyright (c) 2010-2016, Zolertia * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,71 +29,41 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file - * A quick program for testing the tmp102 driver in the Z1 platform + * A quick program for testing the tmp102 sensor in the Z1 platform * \author * Enric M. Calvo + * Antonio Lignan */ - +/*---------------------------------------------------------------------------*/ #include #include "contiki.h" #include "dev/i2cmaster.h" #include "dev/tmp102.h" - - -#if 1 -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif - - -#if 0 -#define PRINTFDEBUG(...) printf(__VA_ARGS__) -#else -#define PRINTFDEBUG(...) -#endif - - -#define TMP102_READ_INTERVAL (CLOCK_SECOND/2) - -PROCESS(temp_process, "Test Temperature process"); +/*---------------------------------------------------------------------------*/ +#define TMP102_READ_INTERVAL (CLOCK_SECOND / 2) +/*---------------------------------------------------------------------------*/ +PROCESS(temp_process, "TMP102 Temperature sensor process"); AUTOSTART_PROCESSES(&temp_process); /*---------------------------------------------------------------------------*/ static struct etimer et; - +/*---------------------------------------------------------------------------*/ PROCESS_THREAD(temp_process, ev, data) { PROCESS_BEGIN(); - int16_t tempint; - uint16_t tempfrac; - int16_t raw; - uint16_t absraw; - int16_t sign; - char minus = ' '; + int16_t temp; - tmp102_init(); + SENSORS_ACTIVATE(tmp102); while(1) { etimer_set(&et, TMP102_READ_INTERVAL); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - - sign = 1; - - PRINTFDEBUG("Reading Temp...\n"); - raw = tmp102_read_temp_raw(); - absraw = raw; - if(raw < 0) { // Perform 2C's if sensor returned negative data - absraw = (raw ^ 0xFFFF) + 1; - sign = -1; - } - tempint = (absraw >> 8) * sign; - tempfrac = ((absraw >> 4) % 16) * 625; // Info in 1/10000 of degree - minus = ((tempint == 0) & (sign == -1)) ? '-' : ' '; - PRINTF("Temp = %c%d.%04d\n", minus, tempint, tempfrac); + temp = tmp102.value(TMP102_READ); + printf("Temp = %d\n", temp); } PROCESS_END(); } +/*---------------------------------------------------------------------------*/ diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile new file mode 100644 index 000000000..ddd89f4ca --- /dev/null +++ b/examples/zolertia/zoul/Makefile @@ -0,0 +1,18 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" + +CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-power-mgmt +CONTIKI_PROJECT += test-bmp085-bmp180 test-motion test-rotation-sensor +CONTIKI_PROJECT += test-grove-light-sensor test-grove-loudness-sensor +CONTIKI_PROJECT += test-weather-meter test-grove-gyro test-lcd test-iaq +CONTIKI_PROJECT += test-pm10-sensor test-vac-sensor test-aac-sensor +CONTIKI_PROJECT += test-zonik + +CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c bmpx8x.c motion-sensor.c +CONTIKI_TARGET_SOURCEFILES += adc-sensors.c weather-meter.c grove-gyro.c +CONTIKI_TARGET_SOURCEFILES += rgb-bl-lcd.c pm10-sensor.c iaq.c zonik.c relay.c + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../.. +CONTIKI_WITH_RIME = 1 +include $(CONTIKI)/Makefile.include diff --git a/examples/zolertia/zoul/Makefile.target b/examples/zolertia/zoul/Makefile.target new file mode 100644 index 000000000..75430a6e4 --- /dev/null +++ b/examples/zolertia/zoul/Makefile.target @@ -0,0 +1 @@ +TARGET = zoul diff --git a/examples/zolertia/zoul/at-test/Makefile b/examples/zolertia/zoul/at-test/Makefile new file mode 100644 index 000000000..14ab8b54b --- /dev/null +++ b/examples/zolertia/zoul/at-test/Makefile @@ -0,0 +1,7 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" +CONTIKI_PROJECT = at-master-test +APPS = at-master +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/zolertia/zoul/at-test/at-master-test.c b/examples/zolertia/zoul/at-test/at-master-test.c new file mode 100644 index 000000000..520c28bdb --- /dev/null +++ b/examples/zolertia/zoul/at-test/at-master-test.c @@ -0,0 +1,487 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-AT-master-test + * @{ + * + * Test the Zoul hardware using AT commands + * @{ + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "cpu.h" +#include "at-master.h" +#include "sys/ctimer.h" +#include "sys/process.h" +#include "dev/adc.h" +#include "dev/leds.h" +#include "dev/watchdog.h" +#include "dev/sys-ctrl.h" +#include "dev/gpio.h" +#include "dev/ioc.h" +#include "net/rime/rime.h" +#include "lib/list.h" +#include "dev/sha256.h" +#include +#include +#include +/*---------------------------------------------------------------------------*/ +PROCESS(at_test_process, "AT test process"); +AUTOSTART_PROCESSES(&at_test_process); +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static struct at_cmd at_cmd_test; +static struct at_cmd at_cmd_board; +static struct at_cmd at_cmd_led; +static struct at_cmd at_cmd_addr; +static struct at_cmd at_cmd_gpio; +static struct at_cmd at_cmd_read; +static struct at_cmd at_cmd_flop; +static struct at_cmd at_cmd_reset; +static struct at_cmd at_cmd_sha256; +static struct at_cmd at_cmd_adc; +/*---------------------------------------------------------------------------*/ +#define HWTEST_GPIO_INPUT 0 +#define HWTEST_GPIO_OUTPUT 1 +#define HWTEST_GPIO_OUTPUT_ODD 3 +#define HWTEST_GPIO_OUTPUT_LIST 4 +#define HWTEST_GPIO_OUTPUT_MASK 0x55 +#define HWTEST_GPIO_OUTPUT_ODD_MASK 0xAA +/*---------------------------------------------------------------------------*/ +typedef struct { + char *name; + uint8_t port; + uint8_t pin; +} gpio_list_t; +/*---------------------------------------------------------------------------*/ +static struct ctimer ct; +/*---------------------------------------------------------------------------*/ +static void +floppin(uint8_t port, uint8_t pin) +{ + uint8_t i; + GPIO_CLR_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + clock_delay_usec(500); + for(i = 0; i < 50; i++) { + GPIO_SET_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + clock_delay_usec(500); + GPIO_CLR_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + clock_delay_usec(500); + } +} +/*---------------------------------------------------------------------------*/ +#if DEBUG +static char * +pname(uint8_t num) +{ + if(num == GPIO_A_NUM) { + return "PA"; + } + if(num == GPIO_B_NUM) { + return "PB"; + } + if(num == GPIO_C_NUM) { + return "PC"; + } + if(num == GPIO_D_NUM) { + return "PD"; + } + return "INVALID"; +} +#endif +/*---------------------------------------------------------------------------*/ +static void +config_gpio(uint8_t port, uint8_t pin, uint8_t type) +{ + GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + if(type == HWTEST_GPIO_OUTPUT) { + GPIO_SET_OUTPUT(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + } else if(type == HWTEST_GPIO_INPUT) { + GPIO_SET_INPUT(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + } +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_test_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + AT_RESPONSE("Hello!"); + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_board_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + AT_RESPONSE(BOARD_STRING); + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_flop_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + /* Format: AT&FLOP=PN where P(ort)N(number) */ + uint8_t port; + uint8_t pin = atoi(&data[9]); + + if((pin < 0) || (pin > 9)) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if(strncmp(&data[8], "A", 1) == 0) { + port = GPIO_A_NUM; + } else if(strncmp(&data[8], "B", 1) == 0) { + port = GPIO_B_NUM; + } else if(strncmp(&data[8], "C", 1) == 0) { + port = GPIO_C_NUM; + } else if(strncmp(&data[8], "D", 1) == 0) { + port = GPIO_D_NUM; + } else { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + config_gpio(port, pin, HWTEST_GPIO_OUTPUT); + floppin(port, pin); + + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_address_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + static char _lladdr[17]; + snprintf(_lladdr, 17, "%02x%02x%02x%02x%02x%02x%02x%02x", + linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1], + linkaddr_node_addr.u8[2], linkaddr_node_addr.u8[3], + linkaddr_node_addr.u8[4], linkaddr_node_addr.u8[5], + linkaddr_node_addr.u8[6], linkaddr_node_addr.u8[7]); + + AT_RESPONSE(_lladdr); + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_reset_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + uint8_t reset_val = atoi(&data[9]); + /* AT&RESET=n, where n: + * 0 : CC2538 soft reset + */ + if((reset_val != 0) && (reset_val != 1)) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + /* Send the response and wait a second until executing the command */ + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); + + if(reset_val == 0) { + ctimer_set(&ct, CLOCK_SECOND, sys_ctrl_reset, NULL); + } +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_leds_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + /* Format: AT&LED=L,s where L(ed)=R/G/B, s(tate)=1/0*/ + uint8_t led; + uint8_t state = strncmp(&data[9], "1", 1) ? 0 : 1; + + if(strncmp(&data[8], ",", 1) != 0) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if(strncmp(&data[7], "R", 1) == 0) { + led = LEDS_RED; + } else if(strncmp(&data[7], "G", 1) == 0) { + led = LEDS_GREEN; + } else if(strncmp(&data[7], "B", 1) == 0) { + led = LEDS_BLUE; + } else { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if(state) { + leds_on(led); + } else { + leds_off(led); + } + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_gpio_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + /* Format: AT&GPIO=PN,s where P(ort)N(number), s(tate)=1/0 */ + uint8_t port; + uint8_t state = strncmp(&data[11], "1", 1) ? 0 : 1; + uint8_t pin = atoi(&data[9]); + + if(strncmp(&data[10], ",", 1) != 0) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if((pin < 0) || (pin > 7)) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if((state < 0) || (state > 1)) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if(strncmp(&data[8], "A", 1) == 0) { + port = GPIO_A_NUM; + } else if(strncmp(&data[8], "B", 1) == 0) { + port = GPIO_B_NUM; + } else if(strncmp(&data[8], "C", 1) == 0) { + port = GPIO_C_NUM; + } else if(strncmp(&data[8], "D", 1) == 0) { + port = GPIO_D_NUM; + } else { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + config_gpio(port, pin, HWTEST_GPIO_OUTPUT); + + if(state) { + GPIO_SET_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + } else { + GPIO_CLR_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); + } + + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_adc_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + /* Format: AT&ADC=N where N is 4-7, it can be "*" to read all */ + uint8_t i, pin; + uint16_t res[4]; + char read_result[24]; + + if(strncmp(&data[7], "*", 1) == 0) { + pin = 8; + } else { + pin = atoi(&data[7]); + } + + if((pin < 4) || (pin > 8)) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if(pin < 8) { + config_gpio(GPIO_A_NUM, pin, HWTEST_GPIO_INPUT); + ioc_set_over(GPIO_A_NUM, pin, IOC_OVERRIDE_ANA); + res[pin - 4] = adc_get((SOC_ADC_ADCCON_CH_AIN0 + pin), + SOC_ADC_ADCCON_REF_AVDD5, + SOC_ADC_ADCCON_DIV_512); + res[pin - 4] = res[pin - 4] / 10; + PRINTF("ADC%u: %04d\n", pin, res[pin - 4]); + snprintf(read_result, 5, "%04d", res[pin - 4]); + } else { + for(i = 4; i < 8; i++) { + config_gpio(GPIO_A_NUM, i, HWTEST_GPIO_INPUT); + ioc_set_over(GPIO_A_NUM, i, IOC_OVERRIDE_ANA); + res[i - 4] = adc_get((SOC_ADC_ADCCON_CH_AIN0 + i), + SOC_ADC_ADCCON_REF_AVDD5, + SOC_ADC_ADCCON_DIV_512); + res[i - 4] = res[i - 4] / 10; + } + snprintf(read_result, 24, "%04d %04d %04d %04d", res[0], res[1], + res[2], res[3]); + } + + AT_RESPONSE(read_result); + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_read_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + /* Format: AT&READ=PN where P(ort)N(number), N can be "*" to read all */ + uint8_t port, pin; + char read_result[5]; + + if(strncmp(&data[9], "*", 1) == 0) { + pin = 0xFF; + } else { + pin = atoi(&data[9]); + } + + if((pin < 0) || (pin > 7)) { + if(pin != 0xFF) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + } + + if(pin < 8) { + pin = GPIO_PIN_MASK(pin); + } + + /* Exclude PA0-PA3 */ + if(strncmp(&data[8], "A", 1) == 0) { + port = GPIO_A_NUM; + if(pin < 0x1F) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } else { + if(pin == 0xFF) { + pin = 0xF0; + } + } + } else if(strncmp(&data[8], "B", 1) == 0) { + port = GPIO_B_NUM; + } else if(strncmp(&data[8], "C", 1) == 0) { + port = GPIO_C_NUM; + } else if(strncmp(&data[8], "D", 1) == 0) { + port = GPIO_D_NUM; + } else { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + config_gpio(port, pin, HWTEST_GPIO_INPUT); + snprintf(read_result, 5, "0x%02X", + (uint16_t)GPIO_READ_PIN(GPIO_PORT_TO_BASE(port), pin)); + AT_RESPONSE(read_result); + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +static void +at_cmd_sha256_callback(struct at_cmd *cmd, uint8_t len, char *data) +{ + /* Format: AT&SHA256=s, where s is a string up to 64 bytes */ + uint8_t i; + char tmp[4], sha256[32], sha256_res[64]; + static sha256_state_t state; + + crypto_init(); + if(sha256_init(&state) != CRYPTO_SUCCESS) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if(sha256_process(&state, &data[10], + len - (cmd->cmd_hdr_len)) != CRYPTO_SUCCESS) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + if(sha256_done(&state, sha256) != CRYPTO_SUCCESS) { + AT_RESPONSE(AT_DEFAULT_RESPONSE_ERROR); + return; + } + + crypto_disable(); + + PRINTF("Input: %s:\n", &data[10]); + snprintf(tmp, 3, "%02X", sha256[0]); + strncpy(sha256_res, tmp, 3); + for(i = 1; i < 32; i++) { + PRINTF("0x%02X ", sha256[i]); + snprintf(tmp, 3, "%02X", sha256[i]); + strcat(sha256_res, tmp); + } + PRINTF("\nSHA256: %s\n", sha256_res); + AT_RESPONSE(sha256_res); + AT_RESPONSE(AT_DEFAULT_RESPONSE_OK); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(at_test_process, ev, data) +{ + PROCESS_BEGIN(); + struct at_cmd *a; + + /* Initialize the driver, default is UART0 */ + at_init(0); + + /* Register a list of commands, is mandatory to start with "AT" */ + at_register(&at_cmd_test, &at_test_process, "AT", 2, 2, + at_cmd_test_callback); + at_register(&at_cmd_board, &at_test_process, "AT&V", 4, 4, + at_cmd_board_callback); + at_register(&at_cmd_led, &at_test_process, "AT&LED", 6, 10, + at_cmd_leds_callback); + at_register(&at_cmd_addr, &at_test_process, "AT&A", 4, 4, + at_cmd_address_callback); + at_register(&at_cmd_gpio, &at_test_process, "AT&GPIO=", 8, 12, + at_cmd_gpio_callback); + at_register(&at_cmd_read, &at_test_process, "AT&READ=", 8, 10, + at_cmd_read_callback); + at_register(&at_cmd_adc, &at_test_process, "AT&ADC=", 7, 8, + at_cmd_adc_callback); + at_register(&at_cmd_flop, &at_test_process, "AT&FLOP=", 8, 10, + at_cmd_flop_callback); + at_register(&at_cmd_reset, &at_test_process, "AT&RESET=", 9, 10, + at_cmd_reset_callback); + at_register(&at_cmd_sha256, &at_test_process, "AT&SHA256=", 10, 64, + at_cmd_sha256_callback); + + /* Print the command list */ + PRINTF("AT command list:\n"); + for(a = at_list(); a != NULL; a = list_item_next(a)) { + PRINTF("* HDR %s LEN %u MAX %u\n", a->cmd_header, a->cmd_hdr_len, + a->cmd_max_len); + } + + /* + * When an AT command is received over the serial line, the registered + * callbacks will be invoked, let the process spin until then + */ + while(1) { + PROCESS_YIELD(); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/examples/sensinode/energy-scan/netstack.c b/examples/zolertia/zoul/at-test/project-conf.h similarity index 70% rename from examples/sensinode/energy-scan/netstack.c rename to examples/zolertia/zoul/at-test/project-conf.h index d59acc3fe..4a29f1d59 100644 --- a/examples/sensinode/energy-scan/netstack.c +++ b/examples/zolertia/zoul/at-test/project-conf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Loughborough University - Computer Science + * Copyright (c) 2016, Zolertia - http://www.zolertia.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,24 +26,42 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * This file is part of the Contiki operating system. */ - +/*---------------------------------------------------------------------------*/ /** + * \addtogroup remote-examples + * @{ + * + * \defgroup zoul-AT-master-test + * + * Test the Zoul hardware over AT API + * @{ + * * \file - * Stub file overriding core/net/netstack.c. What we want to achieve - * here is call netstack_init from main without initialising the RDC, - * MAC and Network layers. It will just turn on the radio instead. + * Test the Zoul hardware over AT API * * \author - * George Oikonomou - + * Antonio Lignan */ +/*---------------------------------------------------------------------------*/ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ -#include "netstack.h" -/*---------------------------------------------------------------------------*/ -void -netstack_init(void) -{ - NETSTACK_RADIO.init(); -} -/*---------------------------------------------------------------------------*/ +/* Drop maximum to PM1 to have the UART on all the time */ +#define LPM_CONF_MAX_PM 1 + +/* the radio is not used */ +#define CONTIKI_NO_NET 1 + +/* Override serial-line defaults */ +#define SERIAL_LINE_CONF_BUFSIZE 128 +#undef IGNORE_CHAR +#undef END +#define IGNORE_CHAR(c) (c == 0x0d) +#define END 0x0a + +#define NETSTACK_CONF_RDC nullrdc_driver + +#endif /* PROJECT_CONF_H_ */ + +/** @} */ diff --git a/examples/zolertia/zoul/cc1200-demo/Makefile b/examples/zolertia/zoul/cc1200-demo/Makefile new file mode 100644 index 000000000..4a1a9e4ac --- /dev/null +++ b/examples/zolertia/zoul/cc1200-demo/Makefile @@ -0,0 +1,8 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" +CONTIKI_PROJECT = cc1200-demo + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../../.. +CONTIKI_WITH_RIME = 1 +include $(CONTIKI)/Makefile.include diff --git a/examples/zolertia/zoul/cc1200-demo/Makefile.target b/examples/zolertia/zoul/cc1200-demo/Makefile.target new file mode 100644 index 000000000..75430a6e4 --- /dev/null +++ b/examples/zolertia/zoul/cc1200-demo/Makefile.target @@ -0,0 +1 @@ +TARGET = zoul diff --git a/examples/sensinode/broadcast-rime.c b/examples/zolertia/zoul/cc1200-demo/cc1200-demo.c similarity index 52% rename from examples/sensinode/broadcast-rime.c rename to examples/zolertia/zoul/cc1200-demo/cc1200-demo.c index f69c2a1bc..1fe69f58c 100644 --- a/examples/sensinode/broadcast-rime.c +++ b/examples/zolertia/zoul/cc1200-demo/cc1200-demo.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Swedish Institute of Computer Science. + * Copyright (c) 2015, Zolertia - http://www.zolertia.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,94 +26,80 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * This file is part of the Contiki operating system. - * */ - +/*---------------------------------------------------------------------------*/ /** + * \addtogroup zoul-cc1200-demo Zoul on-board CC1200 RF transceiver test + * + * Demonstrates the use of the TI CC1200 RF transceiver on Sub-1GHz + * @{ + * * \file - * Testing the broadcast layer in Rime + * Test file for the CC1200 demo + * * \author - * Adam Dunkels + * Antonio Lignan */ #include "contiki.h" -#include "net/rime/rime.h" -#include "lib/random.h" -#include "net/rime/rimestats.h" +#include "cpu.h" +#include "sys/etimer.h" #include "dev/leds.h" -#include "dev/models.h" +#include "dev/watchdog.h" +#include "dev/serial-line.h" +#include "dev/sys-ctrl.h" +#include "net/rime/broadcast.h" -#define DEBUG 1 -#if DEBUG #include -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif - -#define BROADCAST_CHANNEL 129 - +#include /*---------------------------------------------------------------------------*/ -PROCESS(example_broadcast_process, "BROADCAST example"); -AUTOSTART_PROCESSES(&example_broadcast_process); +#define LOOP_PERIOD 2 +#define LOOP_INTERVAL (CLOCK_SECOND * LOOP_PERIOD) +#define BROADCAST_CHANNEL 129 +/*---------------------------------------------------------------------------*/ +static struct etimer et; +static uint16_t counter; /*---------------------------------------------------------------------------*/ static void broadcast_recv(struct broadcast_conn *c, const linkaddr_t *from) { - leds_toggle(LEDS_RED); - PRINTF("broadcast message received from %02x.%02x\n", from->u8[0], - from->u8[1]); - PRINTF("Size=0x%02x: '0x%04x'\n", packetbuf_datalen(), - *(uint16_t *)packetbuf_dataptr()); + printf("*** Received %u bytes from %u:%u: '0x%04u' ", packetbuf_datalen(), + from->u8[0], from->u8[1], *(uint16_t *)packetbuf_dataptr()); + printf("%d - %u\n", (int8_t)packetbuf_attr(PACKETBUF_ATTR_RSSI), + packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY)); + leds_toggle(LEDS_GREEN); } /*---------------------------------------------------------------------------*/ -static void -print_rime_stats() -{ - PRINTF("\nNetwork Stats\n"); - PRINTF(" TX=%lu , RX=%lu\n", RIMESTATS_GET(tx), RIMESTATS_GET(rx)); - PRINTF("LL-TX=%lu , LL-RX=%lu\n", RIMESTATS_GET(lltx), RIMESTATS_GET(llrx)); - PRINTF(" Long=%lu , Short=%lu\n", RIMESTATS_GET(toolong), - RIMESTATS_GET(tooshort)); - PRINTF("T/Out=%lu , CCA-Err=%lu\n", RIMESTATS_GET(timedout), - RIMESTATS_GET(contentiondrop)); -} - static const struct broadcast_callbacks bc_rx = { broadcast_recv }; -static struct broadcast_conn broadcast; +static struct broadcast_conn bc; /*---------------------------------------------------------------------------*/ -PROCESS_THREAD(example_broadcast_process, ev, data) +PROCESS(cc1200_demo_process, "cc1200 demo process"); +AUTOSTART_PROCESSES(&cc1200_demo_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(cc1200_demo_process, ev, data) { - static struct etimer et; - static uint16_t counter; - - PROCESS_EXITHANDLER(broadcast_close(&broadcast);) - + PROCESS_EXITHANDLER(broadcast_close(&bc)) PROCESS_BEGIN(); - PRINTF("Start\n"); - broadcast_open(&broadcast, BROADCAST_CHANNEL, &bc_rx); - PRINTF("Open Broadcast Connection, channel %u\n", BROADCAST_CHANNEL); + broadcast_open(&bc, BROADCAST_CHANNEL, &bc_rx); + + etimer_set(&et, LOOP_INTERVAL); while(1) { - - /* Delay 2-4 seconds */ - etimer_set(&et, CLOCK_SECOND * 2); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - leds_on(LEDS_GREEN); - packetbuf_copyfrom(&counter, sizeof(counter)); - PRINTF("Sending %u bytes: 0x%04x\n", packetbuf_datalen(), - *(uint16_t *)packetbuf_dataptr()); - if(broadcast_send(&broadcast) == 0) { - PRINTF("Error Sending\n"); + PROCESS_YIELD(); + if(ev == PROCESS_EVENT_TIMER) { + printf("Broadcast --> %u\n", counter); + leds_toggle(LEDS_RED); + packetbuf_copyfrom(&counter, sizeof(counter)); + broadcast_send(&bc); + counter++; + etimer_set(&et, LOOP_INTERVAL); } - - print_rime_stats(); - PRINTF("===================================\n"); - counter++; - leds_off(LEDS_GREEN); } PROCESS_END(); } /*---------------------------------------------------------------------------*/ +/** + * @} + */ + diff --git a/examples/sensinode/sniffer/project-conf.h b/examples/zolertia/zoul/cc1200-demo/project-conf.h similarity index 70% rename from examples/sensinode/sniffer/project-conf.h rename to examples/zolertia/zoul/cc1200-demo/project-conf.h index 3ed5ec99e..9367973ff 100644 --- a/examples/sensinode/sniffer/project-conf.h +++ b/examples/zolertia/zoul/cc1200-demo/project-conf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Loughborough University - Computer Science + * Copyright (c) 2015, Zolertia - http://www.zolertia.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,27 +26,36 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * This file is part of the Contiki operating system. */ - +/*---------------------------------------------------------------------------*/ /** - * \file - * Project specific configuration defines for the sniffer example. + * \addtogroup zoul-examples + * @{ * - * We make sure that the radio driver outputs all packets in hexdump - * format. + * \defgroup remote-cc1200-demo RE-Mote CC1200 RF transceiver test + * + * Demonstrates the use of the TI CC1200 RF transceiver on Sub-1GHz + * @{ + * + * \file + * Configuration file for the cc1200 demo * * \author - * George Oikonomou - + * Antonio Lignan */ - #ifndef PROJECT_CONF_H_ #define PROJECT_CONF_H_ -#define CC2430_RF_CONF_HEXDUMP 1 -#define CC2430_RF_CONF_AUTOACK 0 -#define NETSTACK_CONF_RDC stub_rdc_driver -#define ADC_SENSOR_CONF_ON 0 -#define LPM_CONF_MODE 0 +#undef NETSTACK_CONF_RADIO +#define NETSTACK_CONF_RADIO cc1200_driver +#define NETSTACK_CONF_RDC nullrdc_driver +#define CC1200_CONF_USE_GPIO2 0 +#define CC1200_CONF_USE_RX_WATCHDOG 0 +#define ANTENNA_SW_SELECT_DEF_CONF ANTENNA_SW_SELECT_SUBGHZ #endif /* PROJECT_CONF_H_ */ + +/** + * @} + * @} + */ diff --git a/examples/zolertia/zoul/cc1200-sniffer/Makefile b/examples/zolertia/zoul/cc1200-sniffer/Makefile new file mode 100644 index 000000000..5c2fa1675 --- /dev/null +++ b/examples/zolertia/zoul/cc1200-sniffer/Makefile @@ -0,0 +1,10 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" +PROJECT_SOURCEFILES += stub-rdc.c + +CONTIKI_PROJECT = sniffer + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../../.. +CONTIKI_WITH_RIME = 1 +include $(CONTIKI)/Makefile.include diff --git a/examples/zolertia/zoul/cc1200-sniffer/Makefile.target b/examples/zolertia/zoul/cc1200-sniffer/Makefile.target new file mode 100644 index 000000000..75430a6e4 --- /dev/null +++ b/examples/zolertia/zoul/cc1200-sniffer/Makefile.target @@ -0,0 +1 @@ +TARGET = zoul diff --git a/examples/zolertia/zoul/cc1200-sniffer/README.md b/examples/zolertia/zoul/cc1200-sniffer/README.md new file mode 100644 index 000000000..95ec65193 --- /dev/null +++ b/examples/zolertia/zoul/cc1200-sniffer/README.md @@ -0,0 +1,35 @@ +CC1200 README +======================== + +The CC1200 sniffer is heavily based on the CC2538 sniffer, used with the +IEEE 802.15.4 Sensniff application by George Oikonomou. + +Sensniff requires [Wireshark](http://www.wireshark.org/). + +Get Wireshark +----------------- +The best way is to go to the Wireshark site and follow the instructions for your +specific OS, in a bundle this will install for Ubuntu/LInux systems: + +`sudo apt-get install wireshark` + +To allow non-super users to capture packets: + +`sudo dpkg-reconfigure wireshark` + +Flash the sniffer application to the Zoul +----------------- +make sniffer.upload + +Run Sensniff +----------------- +``` +git clone https://github.com/g-oikonomou/sensniff +cd sensniff/host +python sensniff.py --non-interactive -d /dev/ttyUSB0 -b 460800 +``` + +On another terminal run: + +`sudo wireshark -i /tmp/sensnifff` + diff --git a/examples/sensinode/sniffer/netstack.c b/examples/zolertia/zoul/cc1200-sniffer/netstack.c similarity index 97% rename from examples/sensinode/sniffer/netstack.c rename to examples/zolertia/zoul/cc1200-sniffer/netstack.c index d59acc3fe..3aeb6968e 100644 --- a/examples/sensinode/sniffer/netstack.c +++ b/examples/zolertia/zoul/cc1200-sniffer/netstack.c @@ -25,10 +25,7 @@ * 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. - * - * This file is part of the Contiki operating system. */ - /** * \file * Stub file overriding core/net/netstack.c. What we want to achieve @@ -38,12 +35,12 @@ * \author * George Oikonomou - */ - #include "netstack.h" /*---------------------------------------------------------------------------*/ void netstack_init(void) { NETSTACK_RADIO.init(); + NETSTACK_RADIO.on(); } /*---------------------------------------------------------------------------*/ diff --git a/examples/zolertia/zoul/cc1200-sniffer/project-conf.h b/examples/zolertia/zoul/cc1200-sniffer/project-conf.h new file mode 100644 index 000000000..fca02e711 --- /dev/null +++ b/examples/zolertia/zoul/cc1200-sniffer/project-conf.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup zoul-cc1200-sniffer + * @{ + * + * \file + * Project specific configuration defines for the CC1200 sniffer + */ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#define CC1200_CONF_SNIFFER 1 +#define CC1200_RF_CONF_SNIFFER_UART 0 +#define CC1200_CONF_RF_CFG cc1200_802154g_863_870_fsk_50kbps + +#undef NETSTACK_CONF_RADIO +#define NETSTACK_CONF_RADIO cc1200_driver + +#define CC1200_CONF_USE_GPIO2 0 +#define CC1200_CONF_USE_RX_WATCHDOG 0 +#define ANTENNA_SW_SELECT_DEF_CONF ANTENNA_SW_SELECT_SUBGHZ + +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC stub_rdc_driver + +#define UART0_CONF_BAUD_RATE 460800 + +#endif /* PROJECT_CONF_H_ */ + +/** @} */ diff --git a/examples/zolertia/zoul/cc1200-sniffer/sniffer.c b/examples/zolertia/zoul/cc1200-sniffer/sniffer.c new file mode 100644 index 000000000..a0241f795 --- /dev/null +++ b/examples/zolertia/zoul/cc1200-sniffer/sniffer.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zoul-cc1200-sniffer CC1200 Sniffer + * + * Sniffer for the Zolertia's Zoul CC1200 on-board radio + * + * This example is to be used combined with the sensniff host-side tool, + * which can be downloaded from: https://github.com/g-oikonomou/sensniff + * + * @{ + * + * \file + * Implementation of a Sniffer Process Thread + */ +#include "contiki.h" + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" +/*---------------------------------------------------------------------------*/ +PROCESS(sniffer_process, "Sniffer process"); +AUTOSTART_PROCESSES(&sniffer_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(sniffer_process, ev, data) +{ + PROCESS_BEGIN(); + PRINTF("Sniffer started\n"); + PROCESS_EXIT(); + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ + +/** + * @} + * @} + */ diff --git a/examples/sensinode/energy-scan/stub-rdc.c b/examples/zolertia/zoul/cc1200-sniffer/stub-rdc.c similarity index 95% rename from examples/sensinode/energy-scan/stub-rdc.c rename to examples/zolertia/zoul/cc1200-sniffer/stub-rdc.c index ed335fc70..a8c54de6a 100644 --- a/examples/sensinode/energy-scan/stub-rdc.c +++ b/examples/zolertia/zoul/cc1200-sniffer/stub-rdc.c @@ -25,21 +25,17 @@ * 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. - * - * This file is part of the Contiki operating system. */ - /** * \file * Definition of a fake RDC driver to be used with passive - * examples. The code will never send packets and it will never + * examples. The sniffer will never send packets and it will never * push incoming packets up the stack. We do this by defining this * driver as our RDC. We then drop everything * * \author * George Oikonomou - */ - #include "net/mac/mac.h" #include "net/mac/rdc.h" /*---------------------------------------------------------------------------*/ @@ -73,7 +69,7 @@ on(void) static int off(int keep_radio_on) { - return 1; + return keep_radio_on; } /*---------------------------------------------------------------------------*/ static unsigned short diff --git a/examples/zolertia/zoul/node-red/README.md b/examples/zolertia/zoul/node-red/README.md new file mode 100644 index 000000000..f99458ac7 --- /dev/null +++ b/examples/zolertia/zoul/node-red/README.md @@ -0,0 +1,38 @@ +RE-Mote + Node Red README +======================== + +A very basic example of how to use MQTT-Demo + Mosquitto + Node Red + +Install Mosquitto +----------------- +* Install and run [mosquitto](http://mosquitto.org/). Default configuration + options should work. + +Fire up a Re-Mote +----------------- +* Compile the MQTT demo example from `../../../cc2538dk/mqtt-demo.c` following + the instructions of the README.md therein. +* Program your RE-Mote. +* If you are running mosquitto with `-v`, a few seconds later you should see + the Re-Mote connect, subscribe and start publishing. + +Deploy your Node Red +-------------------- +* Install and run [Node Red](https://github.com/node-red/node-red) as per the + instructions +* Open `mqtt-remote-demo.json` from this directory with your favourite text + editor, select all and copy. +* Once you have the opened the Node Red page, click the menu icon on the top + right and go to Import -> Clipboard. Paste the copied text. +* Double click the `MQTT input from Re-Mote` box on the top left. Set `Broker` + IP and port to those corresponding to your running mosquitto. +* Hit Deploy +* Optionally, export the flow to a file for future use + +Browse +------ +Fire up a browser and browse to `http:///remote` + +Do more cool stuff +------------------ +Come up with more cool flows and share! diff --git a/examples/zolertia/zoul/node-red/mqtt-remote-demo.json b/examples/zolertia/zoul/node-red/mqtt-remote-demo.json new file mode 100644 index 000000000..a121cc6c2 --- /dev/null +++ b/examples/zolertia/zoul/node-red/mqtt-remote-demo.json @@ -0,0 +1,2 @@ +[{"id":"d95a1e7f.43a","type":"mqtt-broker","broker":"localhost","port":"1883","clientid":""},{"id":"ddd5cc1c.723e18","type":"mqtt in","name":"MQTT input from Re-Mote","topic":"iot-2/evt/status/fmt/json","broker":"d95a1e7f.43a","x":131.11109924316406,"y":98.88890075683594,"z":"9b2868a4.2cef5","wires":[["12ea094e.3c2447"]]},{"id":"7728d120.25c64","type":"function","name":"Parse and Store Data","func":"var dat = msg.payload.d;\n\nif(dat) {\n var ret = [\n {\n name: \"Name\",\n value: dat.myName,\n unit: \"\",\n },\n {\n name: \"Seq #\",\n value: dat[\"Seq #\"],\n unit: \"\",\n },\n {\n name: \"Uptime\",\n value: dat[\"Uptime (sec)\"],\n unit: \"sec\",\n },\n {\n name: \"On-Chip Temp\",\n value: dat[\"On-Chip Temp (mC)\"],\n unit: \"C\",\n },\n {\n name: \"VDD/3\",\n value: dat[\"VDD3 (mV)\"],\n unit: \"V\",\n },\n {\n name: \"Parent RSSI\",\n value: dat[\"RSSI (dBm)\"],\n unit: \"dBm\",\n },\n ];\n \n context.ret = ret;\n} else {\n if(context.ret) {\n msg.has_data = true;\n msg.payload = context.ret;\n } else {\n msg.payload = \"No Data!\";\n }\n return [msg, msg];\n}\nreturn [msg, null];","outputs":"2","x":545.1110992431641,"y":346.38890075683594,"z":"9b2868a4.2cef5","wires":[["4249c5c.35b5c3c"],["dacab617.9133c8"]]},{"id":"12ea094e.3c2447","type":"json","name":"Convert to JS Object","x":305.61109924316406,"y":263.13890075683594,"z":"9b2868a4.2cef5","wires":[["7728d120.25c64"]]},{"id":"e5e8271c.99c2d","type":"http response","name":"Send HTTP Reponse","x":1252.2220611572266,"y":488.38890075683594,"z":"9b2868a4.2cef5","wires":[]},{"id":"4b2260f8.436808","type":"http in","name":"","url":"/remote","method":"get","x":327.11109924316406,"y":429.88890075683594,"z":"9b2868a4.2cef5","wires":[["8a3f88a9.ec77d8","7728d120.25c64"]]},{"id":"8a3f88a9.ec77d8","type":"debug","name":"","active":false,"console":"false","complete":"req","x":459.61109924316406,"y":522.3889007568359,"z":"9b2868a4.2cef5","wires":[]},{"id":"ac349e33.beb47","type":"template","name":"Render HTML from Data","field":"payload","template":"\n\n
      \n {{#payload}}\n
    • {{name}}: {{value}}{{#unit}} {{unit}}{{/unit}}
    • \n {{/payload}}\n
    \n\n","x":1046.361099243164,"y":347.13890075683594,"z":"9b2868a4.2cef5","wires":[["e5e8271c.99c2d","530bf522.d773dc"]]},{"id":"4249c5c.35b5c3c","type":"debug","name":"","active":false,"console":"false","complete":"false","x":620.1110992431641,"y":247.88890075683594,"z":"9b2868a4.2cef5","wires":[]},{"id":"dacab617.9133c8","type":"switch","name":"","property":"has_data","rules":[{"t":"true"},{"t":"else"}],"checkall":"false","outputs":2,"x":765.1110992431641,"y":352.88890075683594,"z":"9b2868a4.2cef5","wires":[["124554c4.5b82b3","ac349e33.beb47"],["e5e8271c.99c2d"]]},{"id":"530bf522.d773dc","type":"debug","name":"","active":false,"console":"false","complete":"payload","x":1228.361099243164,"y":217.88890075683594,"z":"9b2868a4.2cef5","wires":[]},{"id":"124554c4.5b82b3","type":"debug","name":"","active":false,"console":"false","complete":"payload","x":898.1110992431641,"y":220.88890075683594,"z":"9b2868a4.2cef5","wires":[]}] + diff --git a/examples/zolertia/zoul/project-conf.h b/examples/zolertia/zoul/project-conf.h new file mode 100644 index 000000000..230724b2d --- /dev/null +++ b/examples/zolertia/zoul/project-conf.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup remote-examples + * @{ + * + * \file + * Project specific configuration defines for the basic RE-Mote examples + */ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#define BROADCAST_CHANNEL 129 +#define NETSTACK_CONF_RDC nullrdc_driver + +/* Pin definition for the test-motion example, for the RE-Mote it uses the + * ADC1 pin + */ +#define MOTION_SENSOR_PORT GPIO_A_NUM +#define MOTION_SENSOR_PIN 5 +#define MOTION_SENSOR_VECTOR NVIC_INT_GPIO_PORT_A + +#endif /* PROJECT_CONF_H_ */ + +/** @} */ diff --git a/examples/zolertia/zoul/rtcc/Makefile b/examples/zolertia/zoul/rtcc/Makefile new file mode 100644 index 000000000..25dee77cb --- /dev/null +++ b/examples/zolertia/zoul/rtcc/Makefile @@ -0,0 +1,12 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" +CONTIKI_PROJECT = test-rtcc + +TARGET = zoul + +# Works in Linux and probably on OSX too (RTCC example) +CFLAGS = -DDATE="\"`date +"%02u %02d %02m %02y %02H %02M %02S"`\"" + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/zolertia/zoul/rtcc/project-conf.h b/examples/zolertia/zoul/rtcc/project-conf.h new file mode 100644 index 000000000..9ff57c953 --- /dev/null +++ b/examples/zolertia/zoul/rtcc/project-conf.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup remote-examples + * @{ + * + * \file + * Project specific configuration defines for the basic RE-Mote examples + */ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#define NETSTACK_CONF_RDC nullrdc_driver + +#endif /* PROJECT_CONF_H_ */ + +/** @} */ diff --git a/examples/zolertia/zoul/rtcc/test-rtcc.c b/examples/zolertia/zoul/rtcc/test-rtcc.c new file mode 100644 index 000000000..cb14d5fa5 --- /dev/null +++ b/examples/zolertia/zoul/rtcc/test-rtcc.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-examples + * @{ + + * \defgroup remote-rtcc-test RE-Mote on-board RTCC test application + * + * Example project to show the on-board RTCC configuration and operation + * Retrieves the current time and date from the system, then sets an alarm to + * trigger every TEST_ALARM_SECOND match, generating an interrupt event and + * printing the current time/date, toggling also the LEDs + * + * @{ + * + * \file + * RE-Mote on-board RTCC test application + * + * \author + * + * Antonio Lignan + * Aitor Mejias + * Toni Lozano + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "rtcc.h" +#include "dev/i2c.h" +#include "dev/leds.h" +#include +#include +/*---------------------------------------------------------------------------*/ +#ifndef DATE +#define DATE "Unknown" +#endif +/*---------------------------------------------------------------------------*/ +#define LOOP_PERIOD 60L +#define LOOP_INTERVAL (CLOCK_SECOND * LOOP_PERIOD) +#define TEST_ALARM_SECOND 30 +/*---------------------------------------------------------------------------*/ +PROCESS(test_remote_rtcc_process, "Test RTC driver process"); +AUTOSTART_PROCESSES(&test_remote_rtcc_process); +/*---------------------------------------------------------------------------*/ +static uint8_t rtc_buffer[sizeof(simple_td_map)]; +static simple_td_map *simple_td = (simple_td_map *)rtc_buffer; +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +void +rtcc_interrupt_callback(uint8_t value) +{ + printf("A RTCC interrupt just happened! time/date: "); + rtcc_print(RTCC_PRINT_DATE_DEC); + leds_toggle(LEDS_PURPLE); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_remote_rtcc_process, ev, data) +{ + static char *next; + + PROCESS_BEGIN(); + + /* Alternatively for test only, undefine DATE and define on your own as + * #define DATE "07 06 12 15 16 00 00" + * Also note that if you restart the node at a given time, it will use the + * already defined DATE, so if you want to update the device date/time you + * need to reflash the node + */ + + /* Get the system date in the following format: wd dd mm yy hh mm ss */ + printf("RE-Mote RTC test, system date: %s\n", DATE); + + /* Sanity check */ + if(strcmp("Unknown", DATE) == 0) { + printf("Fail: could not retrieve date from system\n"); + PROCESS_EXIT(); + } + + /* Configure RTC and return structure with all parameters */ + rtcc_init(); + + /* Map interrupt callback handler */ + RTCC_REGISTER_INT1(rtcc_interrupt_callback); + + /* Configure the RTC with the current values */ + simple_td->weekdays = (uint8_t)strtol(DATE, &next, 10); + simple_td->day = (uint8_t)strtol(next, &next, 10); + simple_td->months = (uint8_t)strtol(next, &next, 10); + simple_td->years = (uint8_t)strtol(next, &next, 10); + simple_td->hours = (uint8_t)strtol(next, &next, 10); + simple_td->minutes = (uint8_t)strtol(next, &next, 10); + simple_td->seconds = (uint8_t)strtol(next, NULL, 10); + + /* Don't care about the milliseconds... */ + simple_td->miliseconds = 0; + + /* This example relies on 24h mode */ + simple_td->mode = RTCC_24H_MODE; + + /* And to simplify the configuration, it relies it will be executed in the + * present century + */ + simple_td->century = RTCC_CENTURY_20XX; + + /* Set the time and date */ + if(rtcc_set_time_date(simple_td) == AB08_ERROR) { + printf("Fail: Time and date not configured\n"); + PROCESS_EXIT(); + } + + /* Wait a bit */ + etimer_set(&et, (CLOCK_SECOND * 2)); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* Retrieve the configured time and date, this doesn't overwrites the + * mode and century values + */ + if(rtcc_get_time_date(simple_td) == AB08_ERROR) { + printf("Fail: Couldn't read time and date\n"); + PROCESS_EXIT(); + } + + /* ...or for visualization only, just print the date directly from the RTCC */ + printf("Configured time: "); + rtcc_print(RTCC_PRINT_DATE_DEC); + + /* Configure the RTCC to trigger an alarm every TEST_ALARM_SECOND tick */ + printf("Setting an alarm to tick every minute matching %u seconds\n", + TEST_ALARM_SECOND); + simple_td->seconds = TEST_ALARM_SECOND; + + /* Notice the arguments, we want to trigger the alarm every time the clock + * matches the seconds values, so the alarm would have to be repeated every + * minute. In case we would want to trigger the alarm on a specific time, + * then we would want to set a daily repeat interval + */ + if(rtcc_set_alarm_time_date(simple_td, RTCC_ALARM_ON, + RTCC_REPEAT_MINUTE) == AB08_ERROR) { + printf("Fail: couldn't set the alarm\n"); + PROCESS_EXIT(); + } + + printf("Alarm set to match: "); + rtcc_print(RTCC_PRINT_ALARM_DEC); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/test-aac-sensor.c b/examples/zolertia/zoul/test-aac-sensor.c new file mode 100644 index 000000000..bbda23955 --- /dev/null +++ b/examples/zolertia/zoul/test-aac-sensor.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/* + * \addtogroup zoul-examples + * @{ + * \defgroup zoul-aac-sensor-test Test AAC sensor + * + * Demonstrates the operation of the current AAC analog sensor + * @{ + * + * \file + * Example demonstrating the Zoul module on the RE-Mote & AAC sensor 0-5V 50Amps AC + * + * \author + * Javier Sánchez + */ +#include "contiki.h" +#include "sys/etimer.h" +#include "sys/rtimer.h" +#include "dev/leds.h" +#include "dev/adc-sensors.h" +#include +#include +/*---------------------------------------------------------------------------*/ +#define ADC_PIN 2 +#define LOOP_PERIOD 2 +#define LOOP_INTERVAL (CLOCK_SECOND * LOOP_PERIOD) +#define LEDS_PERIODIC LEDS_GREEN +/*---------------------------------------------------------------------------*/ +static struct etimer et; + +static uint16_t counter; +/*---------------------------------------------------------------------------*/ +PROCESS(test_aac_sensor_process, "Test AAC sensor process"); +AUTOSTART_PROCESSES(&test_aac_sensor_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_aac_sensor_process, ev, data) +{ + + PROCESS_BEGIN(); + + counter = 0; + + /* Configure the ADC ports */ + /* Use pin number not mask, for example if using the PA5 pin then use 5 */ + adc_sensors.configure(ANALOG_AAC_SENSOR, ADC_PIN); + + printf("AAC test application\n"); + leds_on(LEDS_PERIODIC); + etimer_set(&et, LOOP_INTERVAL); + + while(1) { + + PROCESS_YIELD(); + + if(ev == PROCESS_EVENT_TIMER) { + leds_toggle(LEDS_PERIODIC); + + printf("-----------------------------------------\n" + "Counter = 0x%08x\n", counter); + + printf("AC Amps = %d mA\n", adc_sensors.value(ANALOG_AAC_SENSOR)); + + etimer_set(&et, LOOP_INTERVAL); + counter++; + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/examples/zolertia/zoul/test-bmp085-bmp180.c b/examples/zolertia/zoul/test-bmp085-bmp180.c new file mode 100644 index 000000000..73cf0168f --- /dev/null +++ b/examples/zolertia/zoul/test-bmp085-bmp180.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zoul-bmpx8x-test BMP085/BMP180 pressure and temperature sensor test + * + * Demonstrates the use of the BMP085/BMP180 pressure and temperature sensor + * @{ + * + * \file + * Test file for the BMP085/BMP180 digital pressure and temperature sensor + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/i2c.h" +#include "dev/leds.h" +#include "dev/bmpx8x.h" +/*---------------------------------------------------------------------------*/ +#define SENSOR_READ_INTERVAL (CLOCK_SECOND) +/*---------------------------------------------------------------------------*/ +PROCESS(remote_bmpx8x_process, "BMP085/BMP180 test process"); +AUTOSTART_PROCESSES(&remote_bmpx8x_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_bmpx8x_process, ev, data) +{ + PROCESS_BEGIN(); + static uint16_t pressure; + static int16_t temperature; + + /* Use Contiki's sensor macro to enable the sensor */ + SENSORS_ACTIVATE(bmpx8x); + + /* And periodically poll the sensor */ + + while(1) { + etimer_set(&et, SENSOR_READ_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + pressure = bmpx8x.value(BMPx8x_READ_PRESSURE); + temperature = bmpx8x.value(BMPx8x_READ_TEMP); + + if((pressure != BMPx8x_ERROR) && (temperature != BMPx8x_ERROR)) { + printf("Pressure = %u.%u(hPa), ", pressure / 10, pressure % 10); + printf("Temperature = %d.%u(ºC)\n", temperature / 10, temperature % 10); + } else { + printf("Error, enable the DEBUG flag in the BMPx8x driver for info, "); + printf("or check if the sensor is properly connected\n"); + PROCESS_EXIT(); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/test-grove-gyro.c b/examples/zolertia/zoul/test-grove-gyro.c new file mode 100644 index 000000000..24baa360f --- /dev/null +++ b/examples/zolertia/zoul/test-grove-gyro.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zoul-grove-gyro-test Grove's 3-axis gyroscope test application + * + * Demonstrates the use of the Grove's 3-axis gyroscope based on the ITG-3200 + * @{ + * + * \file + * Test file for the external Grove gyroscope + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/i2c.h" +#include "dev/leds.h" +#include "dev/grove-gyro.h" +/*---------------------------------------------------------------------------*/ +#define SENSOR_READ_INTERVAL (CLOCK_SECOND) +#define GROVE_GYRO_EXPECTED_ADDR GROVE_GYRO_ADDR +/*---------------------------------------------------------------------------*/ +PROCESS(remote_grove_gyro_process, "Grove gyro test process"); +AUTOSTART_PROCESSES(&remote_grove_gyro_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +static void +gyro_interrupt_callback(uint8_t status) +{ + /* The interrupt indicates that new data is available, the status value + * returns the outcome of the read operation, check to validate if the + * data is valid to read + */ + leds_toggle(LEDS_PURPLE); + + printf("Gyro: X_axis %u, Y_axis %u, Z_axis %u\n", gyro_values.x, + gyro_values.y, + gyro_values.z); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_grove_gyro_process, ev, data) +{ + PROCESS_BEGIN(); + + uint8_t aux; + + /* Use Contiki's sensor macro to enable the sensor */ + SENSORS_ACTIVATE(grove_gyro); + + /* The sensor itself is in low-power mode, to power on just the sensor and not + * the 3 gyroscope axis use GROVE_GYRO_SENSOR. Alternatively the value + * GROVE_GYRO_ALL could also be used to power everything at once + */ + grove_gyro.configure(GROVE_GYRO_POWER_ON, GROVE_GYRO_SENSOR); + + /* Read back the configured sensor I2C address to check if the sensor is + * working OK, this is the only case in which the value() returns a value + */ + aux = grove_gyro.value(GROVE_GYRO_ADDR); + if(aux == GROVE_GYRO_EXPECTED_ADDR) { + printf("Gyro sensor started with addr 0x%02X\n", GROVE_GYRO_EXPECTED_ADDR); + } else { + printf("Gyro sensor with unrecognized address 0x%02X\n", aux); + PROCESS_EXIT(); + } + + /* Register the interrupt handler */ + GROVE_GYRO_REGISTER_INT(gyro_interrupt_callback); + + /* The gyroscope sensor should be on now but the three gyroscope axis should + * be off, to enable a single axis or any combination of the 3 you can use as + * argument either GROVE_GYRO_X, GROVE_GYRO_Y, GROVE_GYRO_Z. To enable or + * disable the three axis alternatively use GROVE_GYRO_XYZ + */ + grove_gyro.configure(GROVE_GYRO_POWER_ON, GROVE_GYRO_XYZ); + + /* Calibrate the sensor taking 200 samples every 5ms for the zero-point offset + * value, this has to be done manually and is up to the user + */ + grove_gyro.configure(GROVE_GYRO_CALIBRATE_ZERO, 1); + + /* Enabling the data interrupt will feed data directly to the extern data + * structure and notify us about it, depending on the sampling rate and + * divisor this could generate many interrupts/second. A zero argument would + * disable the interrupts + */ + grove_gyro.configure(GROVE_GYRO_DATA_INTERRUPT, 1); + + /* And periodically poll the sensor, values are in º/s */ + + while(1) { + etimer_set(&et, SENSOR_READ_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* This sensor has a different operation from others using Contiki's sensor + * API, to make data acquisition we write the readings directly to the + * extern data structure, allowing to write more than 1 value at the same + * operation, and also allowing upon a data interrupt event to immediatly + * access the data. The return value of the value() call is then the status + * result of the read operation + */ + if(grove_gyro.value(GROVE_GYRO_XYZ) == GROVE_GYRO_SUCCESS) { + + /* Converted values with a 2-digit precision */ + printf("Gyro: X: %u.%u, Y: %u.%u, Z: %u.%u\n", gyro_values.x / 100, + gyro_values.x % 100, + gyro_values.y / 100, + gyro_values.y % 100, + gyro_values.z / 100, + gyro_values.z % 100); + } else { + printf("Error, enable the DEBUG flag in the grove-gyro driver for info,"); + printf(" or check if the sensor is properly connected\n"); + PROCESS_EXIT(); + } + + if(grove_gyro.value(GROVE_GYRO_TEMP) == GROVE_GYRO_SUCCESS) { + printf("Gyro: temperature %d.%02u C\n", gyro_values.temp / 100, + gyro_values.temp % 100); + } else { + printf("Error, enable the DEBUG flag in the grove-gyro driver for info,"); + printf(" or check if the sensor is properly connected\n"); + PROCESS_EXIT(); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/test-grove-light-sensor.c b/examples/zolertia/zoul/test-grove-light-sensor.c new file mode 100644 index 000000000..b4104f2b8 --- /dev/null +++ b/examples/zolertia/zoul/test-grove-light-sensor.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zoul-grove-light-sensor-test Grove's LDR sensor v.1.0 test + * + * Demonstrates the operation of the Grove's analog LDR + * @{ + * + * \file + * Grove's LDR sensor example using the ADC sensors wrapper + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/leds.h" +#include "dev/adc-sensors.h" +/*---------------------------------------------------------------------------*/ +#define ADC_PIN 5 +#define SENSOR_READ_INTERVAL (CLOCK_SECOND / 4) +/*---------------------------------------------------------------------------*/ +PROCESS(remote_grove_light_process, "Grove LDR test process"); +AUTOSTART_PROCESSES(&remote_grove_light_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_grove_light_process, ev, data) +{ + PROCESS_BEGIN(); + + uint16_t ldr; + + /* Use pin number not mask, for example if using the PA5 pin then use 5 */ + adc_sensors.configure(ANALOG_GROVE_LIGHT, 5); + + /* And periodically poll the sensor */ + + while(1) { + etimer_set(&et, SENSOR_READ_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + ldr = adc_sensors.value(ANALOG_GROVE_LIGHT); + + if(ldr != ADC_WRAPPER_ERROR) { + printf("LDR (resistor) = %u\n", ldr); + } else { + printf("Error, enable the DEBUG flag in adc-wrapper.c for info\n"); + PROCESS_EXIT(); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/test-grove-loudness-sensor.c b/examples/zolertia/zoul/test-grove-loudness-sensor.c new file mode 100644 index 000000000..b5042f814 --- /dev/null +++ b/examples/zolertia/zoul/test-grove-loudness-sensor.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zoul-grove-loudness-sensor-test Grove's loudness sensor + * + * Demonstrates the operation of the Grove's analog loudness sensor + * @{ + * + * \file + * Grove's loudness sensor example using the ADC sensors wrapper + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/leds.h" +#include "dev/adc-sensors.h" +/*---------------------------------------------------------------------------*/ +#define ADC_PIN 5 +#define SENSOR_READ_INTERVAL (CLOCK_SECOND / 8) +/*---------------------------------------------------------------------------*/ +PROCESS(remote_grove_loudness_process, "Grove loudness test process"); +AUTOSTART_PROCESSES(&remote_grove_loudness_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_grove_loudness_process, ev, data) +{ + PROCESS_BEGIN(); + + uint16_t loudness; + + /* Use pin number not mask, for example if using the PA5 pin then use 5 */ + adc_sensors.configure(ANALOG_GROVE_LOUDNESS, ADC_PIN); + + /* And periodically poll the sensor */ + + while(1) { + etimer_set(&et, SENSOR_READ_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + loudness = adc_sensors.value(ANALOG_GROVE_LOUDNESS); + + if(loudness != ADC_WRAPPER_ERROR) { + printf("%u\n", loudness); + } else { + printf("Error, enable the DEBUG flag in adc-wrapper.c for info\n"); + PROCESS_EXIT(); + } + + if(loudness < 100) { + leds_off(LEDS_ALL); + } + + if((loudness >= 100) && (loudness < 500)) { + leds_on(LEDS_BLUE); + leds_off(LEDS_GREEN | LEDS_RED); + } + + if((loudness >= 500) && (loudness < 1000)) { + leds_on(LEDS_GREEN); + leds_off(LEDS_BLUE | LEDS_RED); + } + + if(loudness >= 1000) { + leds_on(LEDS_RED); + leds_off(LEDS_BLUE | LEDS_GREEN); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/test-iaq.c b/examples/zolertia/zoul/test-iaq.c new file mode 100644 index 000000000..147ecd8a7 --- /dev/null +++ b/examples/zolertia/zoul/test-iaq.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-examples + * @{ + * \defgroup remote-iaq-test + * + * RE-Mote external IAQ test application + * Example of iAQ-Core implementation and simple operation reading the value + * of CO2, TVOC sensor and Status. The test checks for a each 5 minutes in + * order to get the first true measurement as datasheet recomendation + * (standard result of 0x82 is obtained in first time). + * Then, once initialized, periodically each 5 seconds reads + * the values of the IAQ sensor and shows in the screen, toggling the LED + * red if CO2 was not initialized and LED green if the reading was succeed. + * + * @{ + * \file + * RE-Mote implementation of external IAQ-CORE-C test application + * \author + * Aitor Mejias + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "iaq.h" +#include "dev/i2c.h" +#include "dev/leds.h" +#include +#include +/*---------------------------------------------------------------------------*/ +/* Standard warm up time iAQ Sensor */ +#define IAQ_INIT_WAIT 325L +#define LOOP_PERIOD 5L +#define LOOP_INTERVAL (CLOCK_SECOND * LOOP_PERIOD) +/*---------------------------------------------------------------------------*/ +PROCESS(test_remote_iaq_process, "Test IAQ driver process"); +AUTOSTART_PROCESSES(&test_remote_iaq_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_remote_iaq_process, ev, data) +{ + static uint16_t count_delay = 0; + static uint16_t status = 0; + + PROCESS_BEGIN(); + + /* Configure IAQ and return structure with all parameters */ + SENSORS_ACTIVATE(iaq); + + while(1) { + /* Wait a bit */ + etimer_set(&et, (LOOP_INTERVAL)); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + status = iaq.status(IAQ_DRIVER_STATUS); + + if(status == IAQ_INIT_STATE) { + count_delay += LOOP_PERIOD; + leds_toggle(LEDS_RED); + printf("Test-IAQ: Initializing Time-elapsed: %u seconds of aprox. %lu sec.\n", + count_delay, IAQ_INIT_WAIT); + } else if(status == IAQ_ACTIVE) { + leds_off(LEDS_RED); + leds_toggle(LEDS_GREEN); + + /* Get data from sensor: VOC, CO2 and internal status */ + printf("CO2 current value is: %d ppm\n", iaq.value(IAQ_VOC_VALUE)); + printf("TIAQ current value is: %d ppb\n", iaq.value(IAQ_CO2_VALUE)); + printf("Status is: 0x%0X\n", iaq.value(IAQ_STATUS)); + } + else { + printf("iAQ-Core Error: 0x%02X\n", status); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/test-lcd.c b/examples/zolertia/zoul/test-lcd.c new file mode 100644 index 000000000..6a17df99c --- /dev/null +++ b/examples/zolertia/zoul/test-lcd.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zoul-rgb-lcd-test Test the LCD with RGB backlight + * + * Demonstrates the use of the LCD with on-board RGB backlight + * @{ + * + * \file + * A quick program for testing the Grove's LCD with RGB backlight + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/rgb-bl-lcd.h" +#include "dev/button-sensor.h" +/*---------------------------------------------------------------------------*/ +#define SCROLL_PERIOD (CLOCK_SECOND / 6) +/*---------------------------------------------------------------------------*/ +PROCESS(remote_lcd_process, "Grove LCD backlight test"); +AUTOSTART_PROCESSES(&remote_lcd_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_lcd_process, ev, data) +{ + PROCESS_BEGIN(); + + static uint8_t i = 0; + static char buf[16]; + static uint16_t counter; + + /* Enable the LCD, default configuration is 2 rows and 16 columns, RGB + * backlight on with red color, no cursor/blink */ + SENSORS_ACTIVATE(rgb_bl_lcd); + + /* Set the cursor to column 17 and row 0 to not make it visible yet */ + lcd_set_cursor(17, LCD_RGB_1ST_ROW); + lcd_write("Hello Contiki!"); + + /* Now make the text appear from right to left and stay aligned left */ + while(i < 16) { + etimer_set(&et, SCROLL_PERIOD); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + lcd_scroll_display(LCD_RGB_CURSOR_MOVE_LEFT, 1); + i++; + etimer_restart(&et); + } + + /* wait 2 seconds */ + etimer_set(&et, (CLOCK_SECOND * 2)); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* Clear the welcome message */ + lcd_clear_display(); + + /* Spin the timer and print the counter value on the LCD */ + etimer_set(&et, CLOCK_SECOND); + + lcd_set_cursor(0, LCD_RGB_1ST_ROW); + lcd_write("Press the button!"); + + while(1) { + PROCESS_YIELD(); + + if(ev == PROCESS_EVENT_TIMER) { + snprintf(buf, 15, "Counter: %05u", counter); + lcd_set_cursor(0, LCD_RGB_2ND_ROW); + lcd_write(buf); + printf("Counter: %05u\n", counter); + counter++; + etimer_restart(&et); + } else if(ev == sensors_event) { + if(data == &button_sensor) { + if(button_sensor.value(BUTTON_SENSOR_VALUE_TYPE_LEVEL) == + BUTTON_SENSOR_PRESSED_LEVEL) { + printf("Button pressed!!\n"); + lcd_set_cursor(0, LCD_RGB_1ST_ROW); + lcd_write("Button pressed!!"); + } else { + lcd_set_cursor(0, LCD_RGB_1ST_ROW); + lcd_write("Press the button!"); + } + } + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/test-motion.c b/examples/zolertia/zoul/test-motion.c new file mode 100644 index 000000000..b5c9c3f59 --- /dev/null +++ b/examples/zolertia/zoul/test-motion.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zoul-motion-test Digital motion sensor test + * + * The example application shows how to use any digital motion sensor, basically + * driving a signal high when motion is detected. + * + * @{ + * + * \file + * Test application for the digital motion/presence sensor + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "cpu.h" +#include "sys/rtimer.h" +#include "dev/leds.h" +#include "dev/motion-sensor.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define LEDS_OFF_HYSTERISIS RTIMER_SECOND +/*---------------------------------------------------------------------------*/ +static struct rtimer rt; +/*---------------------------------------------------------------------------*/ +PROCESS(test_presence_sensor, "Test digital motion sensor"); +AUTOSTART_PROCESSES(&test_presence_sensor); +/*---------------------------------------------------------------------------*/ +void +rt_callback(struct rtimer *t, void *ptr) +{ + leds_off(LEDS_RED); +} +/*---------------------------------------------------------------------------*/ +static void +presence_callback(uint8_t value) +{ + printf("*** Presence detected!\n"); + leds_on(LEDS_RED); + rtimer_set(&rt, RTIMER_NOW() + LEDS_OFF_HYSTERISIS, 1, rt_callback, NULL); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_presence_sensor, ev, data) +{ + PROCESS_BEGIN(); + + /* Register the callback handler when presence is detected */ + MOTION_REGISTER_INT(presence_callback); + + /* Enable the sensor, as default it assumes the signal pin has a pull-down + * resistor and a rising interrupt (signal goes high when motion is detected), + * this is the case of the Grove's PIR sensor v.1.0. If the sensor has an + * inverse logic, change at the motion-sensor.c driver file + * GPIO_DETECT_FALLING instead of GPIO_DETECT_RISING if using an external + * pull-up resistor + */ + SENSORS_ACTIVATE(motion_sensor); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/examples/zolertia/zoul/test-pm10-sensor.c b/examples/zolertia/zoul/test-pm10-sensor.c new file mode 100644 index 000000000..d307f9050 --- /dev/null +++ b/examples/zolertia/zoul/test-pm10-sensor.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-examples + * @{ + * \defgroup zoul-pm10-sensor-test Test PM10 sensor + * + * Demonstrates the operation of the Sharp PM10 analog sensor + * @{ + * + * \file + * GP2Y1010AU0F PM10 sensor example using the ADC sensors wrapper + * + * \author + * Toni Lozano + */ +/*---------------------------------------------------------------------------*/ +#include +#include "cpu.h" +#include "contiki.h" +#include "dev/leds.h" +#include "dev/adc-sensors.h" +#include "dev/zoul-sensors.h" +#include "lib/sensors.h" +#include "dev/sys-ctrl.h" +#include "dev/pm10-sensor.h" +/*---------------------------------------------------------------------------*/ +#define ADC_PIN 2 +#define SENSOR_READ_INTERVAL (CLOCK_SECOND) +/*---------------------------------------------------------------------------*/ +PROCESS(test_pm10_sensor_process, "Test PM10 sensor process"); +AUTOSTART_PROCESSES(&test_pm10_sensor_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_pm10_sensor_process, ev, data) +{ + PROCESS_BEGIN(); + + static uint16_t pm10_value; + + /* Use pin number not mask, for example if using the PA5 pin then use 2 */ + pm10.configure(SENSORS_ACTIVE, ADC_PIN); + + /* And periodically poll the sensor */ + + while(1) { + etimer_set(&et, SENSOR_READ_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + leds_toggle(LEDS_GREEN); + pm10_value = pm10.value(1); + + if(pm10_value != ADC_WRAPPER_ERROR) { + printf("PM10 value = %u ppm\n", pm10_value); + } else { + printf("Error, enable the DEBUG flag in adc-wrapper.c for info\n"); + PROCESS_EXIT(); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/examples/zolertia/zoul/test-power-mgmt.c b/examples/zolertia/zoul/test-power-mgmt.c new file mode 100644 index 000000000..1b0690bdb --- /dev/null +++ b/examples/zolertia/zoul/test-power-mgmt.c @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-power-management-test + * @{ + * + * Test the RE-Mote's power management features, shutdown mode and battery + * management + * + * @{ + * + * \author + * Antonio Lignan + * Aitor Mejias + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "cpu.h" +#include "sys/etimer.h" +#include "sys/process.h" +#include "dev/leds.h" +#include "dev/sys-ctrl.h" +#include "dev/gpio.h" +#include "lib/list.h" +#include "power-mgmt.h" +#include "net/rime/broadcast.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/* RE-Mote revision A */ +#define PM_EXPECTED_VERSION 0x00 +#define ENTER_SHUTDOWN_COUNT 10 +/*---------------------------------------------------------------------------*/ +PROCESS(test_remote_pm, "RE-Mote Power Management Test"); +AUTOSTART_PROCESSES(&test_remote_pm); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +static void +broadcast_recv(struct broadcast_conn *c, const linkaddr_t *from) +{ + leds_toggle(LEDS_BLUE); + printf("*** Received %u bytes from %u:%u: '0x%04x'\n", packetbuf_datalen(), + from->u8[0], from->u8[1], *(uint16_t *)packetbuf_dataptr()); +} +/*---------------------------------------------------------------------------*/ +static const struct broadcast_callbacks bc_rx = { broadcast_recv }; +static struct broadcast_conn bc; +/*---------------------------------------------------------------------------*/ +static char * +print_pm(uint8_t state) +{ + switch(state) { + case PM_SYSOFF_ON: + return "Battery on"; + case PM_SYSOFF_OFF: + return "Battery off"; + case PM_TIMER_ENABLED: + return "Nano Timer enabled"; + case PM_TIMER_DISABLED: + return "Nano Timer disabled"; + case PM_AWAITING_RTC_EVENT: + return "Awaiting RTC event"; + default: + return "UNKNOWN"; + } +} +/*---------------------------------------------------------------------------*/ +static int8_t +get_status(uint8_t mask, uint8_t *val) +{ + uint8_t status, print_msg; + + /* Retrieve the status of the power management block */ + if(pm_get_state(&status) != PM_SUCCESS) { + printf("Failed to retrieve the power management status\n"); + return PM_ERROR; + } + + if(!mask) { + printf("STATUS %u\n", status); + *val = PM_IDLE; + return PM_SUCCESS; + } + + /* Read back ony the requested status bit */ + switch(mask) { + case PM_SYSOFF_ON_MASK: + print_msg = (status & mask) ? PM_SYSOFF_ON : PM_SYSOFF_OFF; + break; + case PM_TIMER_ENABLED_MASK: + print_msg = (status & mask) ? PM_TIMER_ENABLED : PM_TIMER_DISABLED; + break; + case PM_AWAITING_RTC_EVENT_MASK: + print_msg = (status & mask) ? PM_AWAITING_RTC_EVENT : PM_AWAITING_RTC_DIS; + break; + default: + return PM_ERROR; + } + + printf("Status -> %s\n", print_pm(print_msg)); + *val = print_msg; + return PM_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_remote_pm, ev, data) +{ + static uint8_t aux; + + PROCESS_BEGIN(); + + /* Configures the pins and initializes the driver */ + if(pm_init() != PM_SUCCESS) { + printf("Failed to initialize\n"); + PROCESS_EXIT(); + } + + /* Get the current firmware version to track the driver implementation on the + * low-power MCU + */ + if(pm_get_firmware_version(&aux) != PM_SUCCESS) { + printf("Failed to retrieve PIC's fw version\n"); + PROCESS_EXIT(); + } + printf("Firmware PIC-Power Manager Version: V0.%u\n", aux); + + if(aux != PM_EXPECTED_VERSION) { + printf("Unexpected firmware version\n"); + PROCESS_EXIT(); + } + + /* Enables the nano timer, the power management block will be driven by the + * nano timer now, putting the node in shutdown mode every minute (as + * default). For this test you need to disconnect the USB cable off to power + * the RE-Mote ONLY from the external battery, so after veryfing the above + * works, disconnect the USB cable and hit the reset button + * When the nano timer is enabled, the external battery is shutdown for a + * couple of usecs, so the CC2538 is restarted. After this as the nano timer + * is enabled, then it will run as intended + */ + + if(get_status(PM_TIMER_ENABLED_MASK, &aux) != PM_SUCCESS) { + PROCESS_EXIT(); + } + + if(aux == PM_TIMER_DISABLED) { + printf("Enabling the nano Timer...\n"); + if(pm_enable_timer() != PM_SUCCESS) { + printf("Failed to set the nano Timer\n"); + PROCESS_EXIT(); + } + } + + /* At this point as the RE-Mote is powered over USB you should see the prints, + * disconnect the USB cable and power only with the external battery. If + * something fails, then you should not see the red LED blinking + */ + aux = ENTER_SHUTDOWN_COUNT; + + /* Open the broadcast channel */ + broadcast_open(&bc, BROADCAST_CHANNEL, &bc_rx); + + /* Send a message */ + packetbuf_copyfrom(&aux, sizeof(aux)); + broadcast_send(&bc); + + /* And wait a few seconds before going to sleep */ + while(1){ + etimer_set(&et, CLOCK_SECOND); + PROCESS_WAIT_EVENT(); + + /* Enter shutdown mode before the shutdown period (1 min default) expires */ + if(!aux) { + /* Say goodnight */ + PM_SHUTDOWN_NOW; + printf("Goodnight!\n"); + PROCESS_EXIT(); + } + + aux--; + leds_toggle(LEDS_RED); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/test-relay.c b/examples/zolertia/zoul/test-relay.c new file mode 100644 index 000000000..cd743919d --- /dev/null +++ b/examples/zolertia/zoul/test-relay.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zoul-relay-test A simple program to test a generic relay + * + * Demonstrates the use of a generic relay, connected by default at the ADC1 + * connector of the RE-Mote + * + * @{ + * + * \file + * A quick program to test a generic relay + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/relay.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +PROCESS(remote_relay_process, "Generic relay test"); +AUTOSTART_PROCESSES(&remote_relay_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_relay_process, ev, data) +{ + PROCESS_BEGIN(); + SENSORS_ACTIVATE(relay); + + /* Activate the relay and wait for 5 seconds */ + relay.value(RELAY_ON); + etimer_set(&et, CLOCK_SECOND * 5); + printf("\nRelay: switch should be ON --> %u\n", relay.status(SENSORS_ACTIVE)); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* Now turn off and wait 5 seconds more */ + relay.value(RELAY_OFF); + etimer_set(&et, CLOCK_SECOND * 5); + printf("Relay: switch should be OFF --> %u\n\n", relay.status(SENSORS_ACTIVE)); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* Let it spin and toggle each second */ + while(1) { + etimer_set(&et, CLOCK_SECOND); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + relay.value(RELAY_TOGGLE); + printf("Relay: switch is now --> %u\n", relay.status(SENSORS_ACTIVE)); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/examples/zolertia/zoul/test-rotation-sensor.c b/examples/zolertia/zoul/test-rotation-sensor.c new file mode 100644 index 000000000..76fb029ec --- /dev/null +++ b/examples/zolertia/zoul/test-rotation-sensor.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zoul-rotation-sensor-test Phidget 1109 rotation sensor example + * + * Demonstrates the operation of the analog phidget 1109 rotation sensor + * @{ + * + * \file + * Phidget analog rotation sensor example using the ADC sensor wrapper + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/leds.h" +#include "dev/adc-sensors.h" +/*---------------------------------------------------------------------------*/ +#define ADC_PIN 5 +#define SENSOR_READ_INTERVAL (CLOCK_SECOND / 4) +/*---------------------------------------------------------------------------*/ +PROCESS(remote_rotation_process, "Phidget rotation test process"); +AUTOSTART_PROCESSES(&remote_rotation_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_rotation_process, ev, data) +{ + PROCESS_BEGIN(); + + uint16_t rotation; + + /* Use pin number not mask, for example if using the PA5 pin then use 5 */ + adc_sensors.configure(ANALOG_PHIDGET_ROTATION_1109, 5); + + /* And periodically poll the sensor */ + + while(1) { + etimer_set(&et, SENSOR_READ_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + rotation = adc_sensors.value(ANALOG_PHIDGET_ROTATION_1109); + + if(rotation != ADC_WRAPPER_ERROR) { + printf("Rotation = %u\n", rotation); + } else { + printf("Error, enable the DEBUG flag in adc-wrapper.c for info\n"); + PROCESS_EXIT(); + } + + if(rotation <= 45) { + leds_off(LEDS_ALL); + } + + if((rotation > 45) && (rotation < 150)) { + leds_on(LEDS_GREEN); + leds_off(LEDS_BLUE | LEDS_RED); + } + + if((rotation > 150) && (rotation < 250)) { + leds_on(LEDS_RED | LEDS_GREEN); + leds_off(LEDS_BLUE); + } + + if(rotation >= 250) { + leds_on(LEDS_RED); + leds_off(LEDS_BLUE | LEDS_GREEN); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/test-sht25.c b/examples/zolertia/zoul/test-sht25.c new file mode 100644 index 000000000..ea853c30b --- /dev/null +++ b/examples/zolertia/zoul/test-sht25.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zoul-sht25-test SHT25 temperature and humidity sensor test + * + * Demonstrates the use of the SHT25 digital temperature and humidity sensor + * @{ + * + * \file + * A quick program for testing the SHT25 temperature and humidity sensor + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/sht25.h" +/*---------------------------------------------------------------------------*/ +PROCESS(remote_sht25_process, "SHT25 test"); +AUTOSTART_PROCESSES(&remote_sht25_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_sht25_process, ev, data) +{ + int16_t temperature, humidity; + + PROCESS_BEGIN(); + SENSORS_ACTIVATE(sht25); + + /* Check if the sensor voltage operation is over 2.25V */ + if(sht25.value(SHT25_VOLTAGE_ALARM)) { + printf("Voltage is lower than recommended for the sensor operation\n"); + PROCESS_EXIT(); + } + + /* Configure the sensor for maximum resolution (14-bit temperature, 12-bit + * relative humidity), this will require up to 85ms for the temperature + * integration, and 29ms for the relative humidity (this is the default + * setting at power on). To achieve a faster integration time at the cost + * of a lower resolution, change the value below accordingly, see sht25.h. + */ + sht25.configure(SHT25_RESOLUTION, SHT2X_RES_14T_12RH); + + /* Let it spin and read sensor data */ + + while(1) { + etimer_set(&et, CLOCK_SECOND); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + temperature = sht25.value(SHT25_VAL_TEMP); + printf("Temperature %02d.%02d ºC, ", temperature / 100, temperature % 100); + humidity = sht25.value(SHT25_VAL_HUM); + printf("Humidity %02d.%02d RH\n", humidity / 100, humidity % 100); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/test-tsl2563.c b/examples/zolertia/zoul/test-tsl2563.c new file mode 100644 index 000000000..b6296b3e5 --- /dev/null +++ b/examples/zolertia/zoul/test-tsl2563.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zoul-tsl2563-test TSL2563 light sensor test + * + * Demonstrates the use of the TSL2563 digital ambient light sensor + * @{ + * + * \file + * Test file for the external TSL2563 light sensor + * + * \author + * Antonio Lignan + * Toni Lozano + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/i2c.h" +#include "dev/leds.h" +#include "dev/tsl2563.h" +/*---------------------------------------------------------------------------*/ +/* Default sensor's integration cycle is 402ms */ +#define SENSOR_READ_INTERVAL (CLOCK_SECOND) +/*---------------------------------------------------------------------------*/ +PROCESS(remote_tsl2563_process, "TSL2563 test process"); +AUTOSTART_PROCESSES(&remote_tsl2563_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +void +light_interrupt_callback(uint8_t value) +{ + printf("* Light sensor interrupt!\n"); + leds_toggle(LEDS_PURPLE); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_tsl2563_process, ev, data) +{ + PROCESS_BEGIN(); + static uint16_t light; + + /* Use Contiki's sensor macro to enable the sensor */ + SENSORS_ACTIVATE(tsl2563); + + /* Default integration time is 402ms with 1x gain, use the below call to + * change the gain and timming, see tsl2563.h for more options + */ + /* tsl2563.configure(TSL2563_TIMMING_CFG, TSL2563_G16X_402MS); */ + + /* Register the interrupt handler */ + TSL2563_REGISTER_INT(light_interrupt_callback); + + /* Enable the interrupt source for values over the threshold. The sensor + * compares against the value of CH0, one way to find out the required + * threshold for a given lux quantity is to enable the DEBUG flag and see + * the CH0 value for a given measurement. The other is to reverse the + * calculations done in the calculate_lux() function. The below value roughly + * represents a 2500 lux threshold, same as pointing a flashlight directly + */ + tsl2563.configure(TSL2563_INT_OVER, 0x15B8); + + /* And periodically poll the sensor */ + + while(1) { + etimer_set(&et, SENSOR_READ_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + light = tsl2563.value(TSL2563_VAL_READ); + if(light != TSL2563_ERROR) { + printf("Light = %u\n", (uint16_t)light); + } else { + printf("Error, enable the DEBUG flag in the tsl2563 driver for info, "); + printf("or check if the sensor is properly connected\n"); + PROCESS_EXIT(); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/test-vac-sensor.c b/examples/zolertia/zoul/test-vac-sensor.c new file mode 100644 index 000000000..37db59edf --- /dev/null +++ b/examples/zolertia/zoul/test-vac-sensor.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/* + * \addtogroup zoul-examples + * @{ + * \defgroup zoul-vac-sensor-test Test VAC sensor + * + * Demonstrates the operation of the voltage VAC analog sensor + * @{ + * + * \file + * Example demonstrating the Zoul module on the RE-Mote & VAC sensor 0-5V 250V AC + * + * \author + * Javier Sánchez + */ +#include "contiki.h" +#include "sys/etimer.h" +#include "sys/rtimer.h" +#include "dev/leds.h" +#include "dev/adc-sensors.h" +#include +#include +/*---------------------------------------------------------------------------*/ +#define ADC_PIN 2 +#define LOOP_PERIOD 2 +#define LOOP_INTERVAL (CLOCK_SECOND * LOOP_PERIOD) +#define LEDS_PERIODIC LEDS_GREEN +#define BUTTON_PRESS_EVENT_INTERVAL (CLOCK_SECOND) +/*---------------------------------------------------------------------------*/ +static struct etimer et; + +static uint16_t counter; +/*---------------------------------------------------------------------------*/ +PROCESS(test_vac_sensor_process, "test VAC sensor process"); +AUTOSTART_PROCESSES(&test_vac_sensor_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_vac_sensor_process, ev, data) +{ + + PROCESS_BEGIN(); + + counter = 0; + + /* Configure the ADC ports */ + /* Use pin number not mask, for example if using the PA5 pin then use 5 */ + adc_sensors.configure(ANALOG_VAC_SENSOR, ADC_PIN); + + printf("VAC test application\n"); + leds_on(LEDS_PERIODIC); + etimer_set(&et, LOOP_INTERVAL); + + while(1) { + + PROCESS_YIELD(); + + if(ev == PROCESS_EVENT_TIMER) { + leds_toggle(LEDS_PERIODIC); + + printf("-----------------------------------------\n" + "Counter = 0x%08x\n", counter); + + /*AC voltage value, with applied corresponding sensor algorithm*/ + printf("AC voltage = %d V\n", adc_sensors.value(ANALOG_VAC_SENSOR)); + + etimer_set(&et, LOOP_INTERVAL); + counter++; + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/examples/zolertia/zoul/test-weather-meter.c b/examples/zolertia/zoul/test-weather-meter.c new file mode 100644 index 000000000..2e2bcba2f --- /dev/null +++ b/examples/zolertia/zoul/test-weather-meter.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zoul-weather-meter-test Test the Sparkfun's weather meter + * + * The example application shows how to read data from the anemometer, wind vane + * and rain gauge, on board the Sparkfun's weater meter + * + * @{ + * + * \file + * Test application for the Sparkfun's weather meter + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "cpu.h" +#include "sys/etimer.h" +#include "dev/leds.h" +#include "dev/weather-meter.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define READ_SENSOR_PERIOD CLOCK_SECOND +#define ANEMOMETER_THRESHOLD_TICK 13 /**< 16 Km/h */ +#define RAIN_GAUGE_THRESHOLD_TICK 15 /**< each increment of 4.19 mm */ +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS(test_weather_meter_sensors, "Test Weather meter sensors"); +AUTOSTART_PROCESSES(&test_weather_meter_sensors); +/*---------------------------------------------------------------------------*/ +static void +rain_callback(uint16_t value) +{ + /* To calculate ticks from mm of rain, divide by 0.2794 mm */ + printf("*** Rain gauge over threshold (%u ticks)\n", value); + weather_meter.configure(WEATHER_METER_RAIN_GAUGE_INT_OVER, + (value + RAIN_GAUGE_THRESHOLD_TICK)); +} +/*---------------------------------------------------------------------------*/ +static void +wind_speed_callback(uint16_t value) +{ + /* This checks for instant wind speed values (over a second), the minimum + * value is 1.2 Km/h (one tick), as the reference is 2.4KM/h per rotation, and + * the anemometer makes 2 ticks per rotation. Instant speed is calculated as + * multiples of this, so if you want to check for 16Km/h, then it would be 13 + * ticks + */ + printf("*** Wind speed over threshold (%u ticks)\n", value); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_weather_meter_sensors, ev, data) +{ + PROCESS_BEGIN(); + + static uint32_t rain; + static uint16_t wind_speed; + static uint16_t wind_dir; + static uint16_t wind_dir_avg_2m; + static uint16_t wind_speed_avg; + static uint16_t wind_speed_avg_2m; + static uint16_t wind_speed_max; + + printf("Weather meter test example, integration period %u\n", + WEATHER_METER_AVG_PERIOD); + + /* Register the callback handler when thresholds are met */ + WEATHER_METER_REGISTER_ANEMOMETER_INT(wind_speed_callback); + WEATHER_METER_REGISTER_RAIN_GAUGE_INT(rain_callback); + + /* Enable the sensors, this has to be called before any of the interrupt calls + * like the ones below + */ + SENSORS_ACTIVATE(weather_meter); + + /* And the upper threshold value to compare and generate an interrupt */ + weather_meter.configure(WEATHER_METER_ANEMOMETER_INT_OVER, + ANEMOMETER_THRESHOLD_TICK); + weather_meter.configure(WEATHER_METER_RAIN_GAUGE_INT_OVER, + RAIN_GAUGE_THRESHOLD_TICK); + + etimer_set(&et, READ_SENSOR_PERIOD); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + rain = weather_meter.value(WEATHER_METER_RAIN_GAUGE); + wind_speed = weather_meter.value(WEATHER_METER_ANEMOMETER); + wind_dir = weather_meter.value(WEATHER_METER_WIND_VANE); + wind_dir_avg_2m = weather_meter.value(WEATHER_METER_WIND_VANE_AVG_X); + wind_speed_avg = weather_meter.value(WEATHER_METER_ANEMOMETER_AVG); + wind_speed_avg_2m = weather_meter.value(WEATHER_METER_ANEMOMETER_AVG_X); + wind_speed_max = weather_meter.value(WEATHER_METER_ANEMOMETER_MAX); + +#if WEATHER_METER_RAIN_RETURN_TICKS + rain *= WEATHER_METER_AUX_RAIN_MM; + if(rain > (WEATHER_METER_AUX_RAIN_MM * 3)) { + printf("Rain: %lu.%lu mm, ", (rain / 10000), (rain % 10000)); +#else + if(rain >= 10) { + printf("Rain: %u.%u mm, ", (rain / 10), (rain % 10)); +#endif + } else { + printf("Rain: 0.%lu mm, ", rain); + } + + printf("Wind dir: %u.%01u deg, ", (wind_dir / 10), (wind_dir % 10)); + printf("(%u.%01u deg avg)\n", (wind_dir_avg_2m / 10), (wind_dir_avg_2m % 10)); + printf("Wind speed: %u m/h ", wind_speed); + printf("(%u m/h avg, %u m/h 2m avg, %u m/h max)\n\n", wind_speed_avg, + wind_speed_avg_2m, + wind_speed_max); + etimer_reset(&et); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/examples/zolertia/zoul/test-zonik.c b/examples/zolertia/zoul/test-zonik.c new file mode 100644 index 000000000..622b73291 --- /dev/null +++ b/examples/zolertia/zoul/test-zonik.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-examples + * @{ + * \defgroup remote-zonik-test Zolertia Zonik sonometer test application + * + * Example of Zonik board implementation and simple operation: Infinite loop + * enablinkg the sensor and rading few times, acquiring the dBA of sensor + * The first value acquired is invalid, because it's in hw init state awaiting + * a valid internal reading.Once the driver is initialized, posterior readings + * are valid.Finally in the loop disables the board with standard call and + * shows the error, and loop again enabling it. + * + * @{ + * \file + * RE-Mote test application of Zolertia Zonik sound sensor + * \author + * Aitor Mejias + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "zonik.h" +#include "dev/i2c.h" +#include "dev/leds.h" +#include +#include +/*---------------------------------------------------------------------------*/ +#define MAX_VALID_READINGS 10L +#define MAX_INVALID_READINGS 3L +/*---------------------------------------------------------------------------*/ +PROCESS(test_remote_zonik_process, "Test Zonik driver process"); +AUTOSTART_PROCESSES(&test_remote_zonik_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_remote_zonik_process, ev, data) +{ + static int16_t zonik_val; + static uint8_t i; + + PROCESS_BEGIN(); + + printf("Initial status of sensor is: 0x%04X\n", + zonik.status(SENSORS_ACTIVE)); + + while(1) { + /* Configure Zonik and activate the internal process readings */ + SENSORS_ACTIVATE(zonik); + + printf("Initialized. Sensor status: 0x%04X\n", + zonik.status(SENSORS_ACTIVE)); + + /* Read sensor value dBA multiple times */ + for(i=0; i +#include +/*---------------------------------------------------------------------------*/ +#define LOOP_PERIOD 8 +#define LOOP_INTERVAL (CLOCK_SECOND * LOOP_PERIOD) +#define LEDS_OFF_HYSTERISIS ((RTIMER_SECOND * LOOP_PERIOD) >> 1) +#define LEDS_PERIODIC LEDS_BLUE +#define LEDS_BUTTON LEDS_RED +#define LEDS_SERIAL_IN LEDS_GREEN +#define LEDS_REBOOT LEDS_ALL +#define LEDS_RF_RX (LEDS_YELLOW | LEDS_RED) +#define BUTTON_PRESS_EVENT_INTERVAL (CLOCK_SECOND) +/*---------------------------------------------------------------------------*/ +static struct etimer et; +static struct rtimer rt; +static uint16_t counter; +/*---------------------------------------------------------------------------*/ +PROCESS(zoul_demo_process, "Zoul demo process"); +AUTOSTART_PROCESSES(&zoul_demo_process); +/*---------------------------------------------------------------------------*/ +static void +broadcast_recv(struct broadcast_conn *c, const linkaddr_t *from) +{ + leds_toggle(LEDS_RF_RX); + printf("*** Received %u bytes from %u:%u: '0x%04x'\n", packetbuf_datalen(), + from->u8[0], from->u8[1], *(uint16_t *)packetbuf_dataptr()); +} +/*---------------------------------------------------------------------------*/ +static const struct broadcast_callbacks bc_rx = { broadcast_recv }; +static struct broadcast_conn bc; +/*---------------------------------------------------------------------------*/ +static void +rt_callback(struct rtimer *t, void *ptr) +{ + leds_off(LEDS_PERIODIC); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(zoul_demo_process, ev, data) +{ + PROCESS_EXITHANDLER(broadcast_close(&bc)) + + PROCESS_BEGIN(); + + counter = 0; + + /* Disable the radio duty cycle and keep the radio on */ + NETSTACK_MAC.off(1); + + broadcast_open(&bc, BROADCAST_CHANNEL, &bc_rx); + + /* Configure the user button */ + button_sensor.configure(BUTTON_SENSOR_CONFIG_TYPE_INTERVAL, + BUTTON_PRESS_EVENT_INTERVAL); + + /* Configure the ADC ports */ + adc_zoul.configure(SENSORS_HW_INIT, ZOUL_SENSORS_ADC_ALL); + + printf("Zoul test application\n"); + + etimer_set(&et, LOOP_INTERVAL); + + while(1) { + + PROCESS_YIELD(); + + if(ev == PROCESS_EVENT_TIMER) { + leds_on(LEDS_PERIODIC); + + printf("-----------------------------------------\n" + "Counter = 0x%08x\n", counter); + + printf("VDD = %d mV\n", + vdd3_sensor.value(CC2538_SENSORS_VALUE_TYPE_CONVERTED)); + + printf("Temperature = %d mC\n", + cc2538_temp_sensor.value(CC2538_SENSORS_VALUE_TYPE_CONVERTED)); + + printf("ADC1 = %d raw\n", + adc_zoul.value(ZOUL_SENSORS_ADC1)); + + printf("ADC3 = %d raw\n", + adc_zoul.value(ZOUL_SENSORS_ADC3)); + + etimer_set(&et, LOOP_INTERVAL); + rtimer_set(&rt, RTIMER_NOW() + LEDS_OFF_HYSTERISIS, 1, + rt_callback, NULL); + counter++; + + } else if(ev == sensors_event) { + if(data == &button_sensor) { + if(button_sensor.value(BUTTON_SENSOR_VALUE_TYPE_LEVEL) == + BUTTON_SENSOR_PRESSED_LEVEL) { + printf("Button pressed\n"); + packetbuf_copyfrom(&counter, sizeof(counter)); + broadcast_send(&bc); + } else { + printf("...and released!\n"); + } + } + + } else if(ev == serial_line_event_message) { + leds_toggle(LEDS_SERIAL_IN); + } else if(ev == button_press_duration_exceeded) { + printf("Button pressed for %d ticks [%u events]\n", + (*((uint8_t *)data) * BUTTON_PRESS_EVENT_INTERVAL), + button_sensor.value(BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION)); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/lib/newlib/syscalls.c b/lib/newlib/syscalls.c new file mode 100644 index 000000000..72b7161de --- /dev/null +++ b/lib/newlib/syscalls.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014, Institute for Pervasive Computing, ETH Zurich. + * All rights reserved. + * + * Author: Andreas Dröscher + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ +/** + * \addtogroup lib + * @{ + * + * \defgroup newlib Generic Newlib customizations + * + * Library providing generic implementations of Newlib features for Contiki + * @{ + * + * \file + * System calls + */ +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +/** + * \brief Enlarges the allocated heap space + * \param incr Number of bytes by which to increase the heap space + * \return The previous end of heap on success (which is also a pointer to the + * start of the newly allocated memory if \p incr is positive), or + * (caddr_t)-1 with \c errno set to \c ENOMEM on error + */ +caddr_t +_sbrk(int incr) +{ + /* + * Newlib's _sbrk_r() assumes that this global errno variable is used here, + * which is different from the errno definition provided by . + */ +#undef errno + extern int errno; + + /* Heap boundaries from linker script. */ + extern uint8_t _heap; + extern uint8_t _eheap; + + static uint8_t *heap_end = &_heap; + uint8_t *prev_heap_end = heap_end; + + if(heap_end + incr > &_eheap) { + PRINTF("Out of heap space!\n"); + errno = ENOMEM; + return (caddr_t)-1; + } + + heap_end += incr; + return (caddr_t)prev_heap_end; +} + +/** + * @} + * @} + */ diff --git a/platform/osd-merkur/Makefile.osd-merkur b/platform/RaspBee/Makefile.RaspBee similarity index 61% rename from platform/osd-merkur/Makefile.osd-merkur rename to platform/RaspBee/Makefile.RaspBee index a083ba965..a4ba6342b 100644 --- a/platform/osd-merkur/Makefile.osd-merkur +++ b/platform/RaspBee/Makefile.RaspBee @@ -9,46 +9,45 @@ CONTIKI_TARGET_SOURCEFILES += temperature-sensor.c adc.c led.c sensors.c slip_ua CONTIKI_TARGET_SOURCEFILES += button-sensor.c # i2c Master CONTIKI_TARGET_SOURCEFILES += i2c.c -#Needed for DHT11 humidity sensor -CONTIKI_TARGET_SOURCEFILES += dht11.c -#Needed for DS18S20 temperature sensor -CONTIKI_TARGET_SOURCEFILES += ds1820.c + #Needed for Battery test CONTIKI_TARGET_SOURCEFILES += battery-sensor.c batmon.c -#Needed for PIR -CONTIKI_TARGET_SOURCEFILES += pir-sensor.c -#Needed for OPTRIAC -CONTIKI_TARGET_SOURCEFILES += optriac-sensor.c + CONTIKIAVR=$(CONTIKI)/cpu/avr -#Needed for SERVO -CONTIKI_TARGET_SOURCEFILES += servo.c servo-sensor.c -#Needed for Timer4 Servo -#CONTIKI_TARGET_SOURCEFILES += t4-servo.c t4-servo-sensor.c -#Needed for Relay 1 to 4 -CONTIKI_TARGET_SOURCEFILES += relay.c relay-sensor.c -# Arduino -CONTIKI_TARGET_SOURCEFILES += wiring_digital.c + + +#------------------------------------------------------------------------------- +# guh Source Files + + +# Smart Grid Ready Interface +CONTIKI_TARGET_SOURCEFILES += sg-ready.c + + + +#------------------------------------------------------------------------------- + CONTIKIBOARD=. BOOTLOADER_START = 0x1F000 CONTIKI_PLAT_DEFS = -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -DPLAT_TIMER=5 -MCU=atmega128rfa1 +MCU=atmega256rfr2 AVRDUDE_PROGRAMMER=jtag2 # For usb devices, you may either use PORT=usb, or (e.g. if you have more than one # programmer connected) you can use the following trick to find out the serial number: # -# The example is for an JTAGICE mkII used to program an ATmega128: -# avrdude -v -P usb:xxxx -c jtag2 -p atmega128 +# The example is for an JTAGICE mkII used to program an atmega256: +# avrdude -v -P usb:xxxx -c jtag2 -p atmega256 AVRDUDE_PORT=usb:00B000000D79 # Additional avrdude options # Verify off AVRDUDE_OPTIONS=-V -AVRDUDE_MCU=m128rfa1 +AVRDUDE_MCU=m256rfr2 #debug # CFLAGS += -save-temps @@ -67,4 +66,8 @@ LDFLAGS += -Wl,--defsym,bootloader_get_mac=$(BOOTLOADER_GET_MAC) include $(CONTIKIAVR)/Makefile.avr include $(CONTIKIAVR)/radio/Makefile.radio -MODULES += core/net/ipv6 core/net/ipv4 core/net/ip core/net/mac core/net core/net/rime core/net/rpl core/net/mac/sicslowmac core/net/mac/contikimac +MODULES += core/net/mac core/net core/net/mac/sicslowmac \ + core/net/mac/contikimac core/net/llsec \ +# core/net/ipv6 core/net/ipv4 core/net/ip \ +# core/net/rime \ +# core/net/rpl \ diff --git a/platform/osd-merkur/contiki-conf.h b/platform/RaspBee/contiki-conf.h similarity index 94% rename from platform/osd-merkur/contiki-conf.h rename to platform/RaspBee/contiki-conf.h index 4583498b2..b62ce80c9 100644 --- a/platform/osd-merkur/contiki-conf.h +++ b/platform/RaspBee/contiki-conf.h @@ -33,17 +33,18 @@ /** * \file - * Configuration for Atmel ATmega128rfa1 + * Configuration for Atmel ATMEGA256RFR2 * \author * David Kopf + Bernhard Trinnes */ #ifndef CONTIKI_CONF_H_ #define CONTIKI_CONF_H_ /* Platform name, type, and MCU clock rate */ -#define PLATFORM_NAME "RFA1" -#define PLATFORM_TYPE ATMEGA128RFA1 +#define PLATFORM_NAME "guhRF" +#define PLATFORM_TYPE ATMEGA256RFR2 #ifndef F_CPU #define F_CPU 16000000UL #endif @@ -74,12 +75,11 @@ typedef unsigned long clock_time_t; void clock_delay_msec(uint16_t howlong); void clock_adjust_ticks(clock_time_t howmany); -/* Michael Hartman's atmega128rfa1 board has an external 32768Hz crystal connected to TOSC1 and 2 pins similar to the Raven 1284p */ + /* and theoretically can use TIMER2 with it to keep time. Else TIMER0 is used. */ /* The sleep timer requires the crystal and adds a TIMER2 interrupt routine if not already define by clock.c */ #define AVR_CONF_USE32KCRYSTAL 0 -/* Michael Hartman's protobyte board has LED on PORTE1, used for radio on indication */ /* However this results in disabling UART0. */ #define RF230BB_CONF_LEDONPORTE1 0 @@ -129,10 +129,12 @@ typedef unsigned short uip_stats_t; * On the RF230 a reduced rx power threshold will not prevent autoack if enabled and requested. * These numbers applied to both Raven and Jackdaw give a maximum communication distance of about 15 cm * and a 10 meter range to a full-sensitivity RF230 sniffer. + #define RF230_MAX_TX_POWER 15 #define RF230_MIN_RX_POWER 30 + */ - /* The rf231 and atmega128rfa1 can use an rssi threshold for triggering rx_busy that saves 0.5ma in rx mode */ + /* The rf231 and ATMEGA256RFR2 can use an rssi threshold for triggering rx_busy that saves 0.5ma in rx mode */ /* 1 - 15 maps into -90 to -48 dBm; the register is written with RF230_MIN_RX_POWER/6 + 1. Undefine for -100dBm sensitivity */ //#define RF230_MIN_RX_POWER 0 @@ -142,13 +144,16 @@ typedef unsigned short uip_stats_t; /* TX routine does automatic cca and optional backoffs */ #define RDC_CONF_HARDWARE_CSMA 1 /* Allow MCU sleeping between channel checks */ -#define RDC_CONF_MCU_SLEEP 1 +#define RDC_CONF_MCU_SLEEP 1 -#if UIP_CONF_IPV6 +/* External Amplifier installed */ +#define _EXT_PA_ 1 + +#if NETSTACK_CONF_WITH_IPV6 #define LINKADDR_CONF_SIZE 8 #define UIP_CONF_ICMP6 1 #define UIP_CONF_UDP 1 -//#define UIP_CONF_TCP 1 +#define UIP_CONF_TCP 1 #define NETSTACK_CONF_NETWORK sicslowpan_driver #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #else @@ -239,15 +244,19 @@ typedef unsigned short uip_stats_t; #define NETSTACK_CONF_RDC contikimac_driver /* Default is two CCA separated by 500 usec */ #define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 -/* Wireshark won't decode with the header, but padded packets will fail ipv6 checksum */ -#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0 /* So without the header this needed for RPL mesh to form */ -#define CONTIKIMAC_CONF_SHORTEST_PACKET_SIZE 43-18 //multicast RPL DIS length +#define CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE 43-18 //multicast RPL DIS length /* Not tested much yet */ -#define CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION 0 +#define CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION 0 #define CONTIKIMAC_CONF_COMPOWER 1 -#define RIMESTATS_CONF_ENABLED 1 +#define RIMESTATS_CONF_ENABLED 0 + +#if NETSTACK_CONF_WITH_IPV6 #define NETSTACK_CONF_FRAMER framer_802154 +#else /* NETSTACK_CONF_WITH_IPV6 */ +#define NETSTACK_CONF_FRAMER contikimac_framer +#endif /* NETSTACK_CONF_WITH_IPV6 */ + #define NETSTACK_CONF_RADIO rf230_driver /* The radio needs to interrupt during an rtimer interrupt */ #define RTIMER_CONF_NESTED_INTERRUPTS 1 diff --git a/platform/osd-merkur/contiki-main.c b/platform/RaspBee/contiki-main.c similarity index 97% rename from platform/osd-merkur/contiki-main.c rename to platform/RaspBee/contiki-main.c index 1f0edb9fb..6c1f5c7e7 100644 --- a/platform/osd-merkur/contiki-main.c +++ b/platform/RaspBee/contiki-main.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -129,15 +130,15 @@ void rtimercycle(void) {rtimerflag=1;} typedef struct {const unsigned char B2;const unsigned char B1;const unsigned char B0;} __signature_t; #define SIGNATURE __signature_t __signature __attribute__((section (".signature"))) SIGNATURE = { - .B2 = 0x01,//SIGNATURE_2, //ATMEGA128rfa1 - .B1 = 0xA7,//SIGNATURE_1, //128KB flash + .B2 = 0x02,//SIGNATURE_2, //ATMEGA256rfr2 + .B1 = 0xA8,//SIGNATURE_1, //256KB flash .B0 = 0x1E,//SIGNATURE_0, //Atmel }; #endif #if 1 -/* JTAG+SPI enabled, External osc 1kck4ms1 , Boot 4096 words @ $1F000, TXC1K+4,1msec delay, Brownout 1.9 volts */ -FUSES ={.low = 0xF6, .high = 0x98, .extended = 0xfd,}; +/* JTAG+SPI enabled, External osc 1kck4ms1 , Boot 4096 words @ $1F000, TXC1K+4,1msec delay, Brownout 1.8 volts */ +FUSES ={.low = 0xF6, .high = 0x98, .extended = 0xfe,}; #define BOOTLOADER_START = 0x1F000 #else /* JTAG+SPI, Boot 4096 words @ $F000, Internal oscillator, startup 6 CK +0 ms, Brownout 1.8 volts */ @@ -145,10 +146,8 @@ FUSES ={.low = 0xC2, .high = 0x99, .extended = 0xfe,}; #endif #include "lib/sensors.h" -#include "dev/button-sensor.h" #include "dev/battery-sensor.h" -#include "dev/pir-sensor.h" -SENSORS(&button_sensor, &pir_sensor); + uint8_t rng_get_uint8(void) { @@ -277,7 +276,7 @@ uint8_t i; PRINTA("Random EUI64 address generated\n"); } -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(&uip_lladdr.addr, &addr.u8, sizeof(linkaddr_t)); #elif WITH_NODE_ID node_id=get_panaddr_from_eeprom(); @@ -293,7 +292,7 @@ uint8_t i; rf230_set_channel(params_get_channel()); rf230_set_txpower(params_get_txpower()); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 PRINTA("EUI-64 MAC: %x-%x-%x-%x-%x-%x-%x-%x\n",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]); #else PRINTA("MAC address "); @@ -323,7 +322,9 @@ uint8_t i; #endif /* ANNOUNCE_BOOT */ +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 process_start(&tcpip_process, NULL); +#endif #ifdef RAVEN_LCD_INTERFACE process_start(&raven_lcd_process, NULL); @@ -408,7 +409,7 @@ uint8_t i; #endif } -#if ROUTES && UIP_CONF_IPV6 +#if ROUTES && NETSTACK_CONF_WITH_IPV6 static void ipaddr_add(const uip_ipaddr_t *addr) { @@ -436,9 +437,9 @@ ipaddr_add(const uip_ipaddr_t *addr) int main(void) { -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 uip_ds6_nbr_t *nbr; -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ initialize(); while(1) { @@ -525,7 +526,7 @@ extern volatile unsigned long radioontime; clocktime+=1; #endif -#if PINGS && UIP_CONF_IPV6 +#if PINGS && NETSTACK_CONF_WITH_IPV6 extern void raven_ping6(void); if ((clocktime%PINGS)==1) { PRINTF("**Ping\n"); @@ -533,7 +534,7 @@ if ((clocktime%PINGS)==1) { } #endif -#if ROUTES && UIP_CONF_IPV6 +#if ROUTES && NETSTACK_CONF_WITH_IPV6 if ((clocktime%ROUTES)==2) { extern uip_ds6_netif_t uip_ds6_if; diff --git a/platform/RaspBee/dev/Arduino.h b/platform/RaspBee/dev/Arduino.h new file mode 100644 index 000000000..e0ea47b10 --- /dev/null +++ b/platform/RaspBee/dev/Arduino.h @@ -0,0 +1,172 @@ +#ifndef Arduino_h +#define Arduino_h + +#include +#include +#include +#include + +#include +#include +#include + +#include "binary.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#define HIGH 0x1 +#define LOW 0x0 + +#define INPUT 0x0 +#define OUTPUT 0x1 +#define INPUT_PULLUP 0x2 + +#define true 0x1 +#define false 0x0 + +#define PI 3.1415926535897932384626433832795 +#define HALF_PI 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 +#define DEG_TO_RAD 0.017453292519943295769236907684886 +#define RAD_TO_DEG 57.295779513082320876798154814105 + +#define SERIAL 0x0 +#define DISPLAY 0x1 + +#define LSBFIRST 0 +#define MSBFIRST 1 + +#define CHANGE 1 +#define FALLING 2 +#define RISING 3 + +#define DEFAULT ADC_DEFAULT +#define EXTERNAL ADC_EXTERNAL + +// undefine stdlib's abs if encountered +#ifdef abs +#undef abs +#endif + +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)>(b)?(a):(b)) +#define abs(x) ((x)>0?(x):-(x)) +#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) +#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) +#define radians(deg) ((deg)*DEG_TO_RAD) +#define degrees(rad) ((rad)*RAD_TO_DEG) +#define sq(x) ((x)*(x)) + +#define interrupts() sei() +#define noInterrupts() cli() + +#define lowByte(w) ((uint8_t) ((w) & 0xff)) +#define highByte(w) ((uint8_t) ((w) >> 8)) + +#define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#define bitSet(value, bit) ((value) |= (1UL << (bit))) +#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) + + +typedef unsigned int word; + +#define bit(b) (1UL << (b)) + +typedef uint8_t boolean; +typedef uint8_t byte; + +void pinMode(uint8_t, uint8_t); +void digitalWrite(uint8_t, uint8_t); +int digitalRead(uint8_t); + +unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout); + +void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); +uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder); + +void attachInterrupt(uint8_t, void (*)(void), int mode); +void detachInterrupt(uint8_t); + +void setup(void); +void loop(void); + +// Get the bit location within the hardware port of the given virtual pin. +// This comes from the pins_*.c file for the active board configuration. + +#define analogInPinToBit(P) (P) + +// On the ATmega1280, the addresses of some of the port registers are +// greater than 255, so we can't store them in uint8_t's. +extern const uint16_t PROGMEM port_to_mode_PGM[]; +extern const uint16_t PROGMEM port_to_input_PGM[]; +extern const uint16_t PROGMEM port_to_output_PGM[]; + +extern const uint8_t PROGMEM digital_pin_to_port_PGM[]; +// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[]; +extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[]; + +// Get the bit location within the hardware port of the given virtual pin. +// This comes from the pins_*.c file for the active board configuration. +// +// These perform slightly better as macros compared to inline functions +// +#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) ) +#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) ) +#define analogInPinToBit(P) (P) +#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) ) +#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) ) +#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) ) + +#define NOT_A_PIN 0 +#define NOT_A_PORT 0 + +#ifdef ARDUINO_MAIN +#define PA 1 +#define PB 2 +#define PC 3 +#define PD 4 +#define PE 5 +#define PF 6 +#define PG 7 +#define PH 8 +#define PJ 10 +#define PK 11 +#define PL 12 +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#ifdef __cplusplus +// look at this again when considering implementing serial +//#include "WCharacter.h" +//#include "WString.h" +//#include "HardwareSerial.h" + +uint16_t makeWord(uint16_t w); +uint16_t makeWord(byte h, byte l); + +#define word(...) makeWord(__VA_ARGS__) + +unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); + +void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0); +void noTone(uint8_t _pin); + +// WMath prototypes +long random(long); +long random(long, long); +void randomSeed(unsigned int); +long map(long, long, long, long, long); + +#endif + +#include "pins_arduino.h" + +#include "dev/arduino/arduino-compat.h" + +#endif diff --git a/platform/RaspBee/dev/adc.c b/platform/RaspBee/dev/adc.c new file mode 100644 index 000000000..7efde72e1 --- /dev/null +++ b/platform/RaspBee/dev/adc.c @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2012, BinaryLabs. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. 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. +* 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. +* +* @(#)$Id: adc.c,v 1.1 2010/08/25 19:34:06 nifi Exp $ +*/ + +/** +* \file +* ADC file for Atmega128rfa1. +* \author +* Paulo Louro +*/ + +#include "adc.h" + +static uint8_t analog_reference = ADC_DEFAULT; + +/* + * For arduino interface for setting external reference voltage + * Note that applying an external voltage *and* then setting the analog + * reference to something internal will short the internal and the + * external reference voltage and most likely destroy the processor. + */ +void analogReference(uint8_t mode) +{ + analog_reference = mode; +} + +int readADC(uint8_t pin) +{ + int result = 0; + + adc_setup (analog_reference, pin); + result = adc_read (); + adc_fin (); + return result; +} + +/** +* \return Internal temperature in 0.01C, e.g. 25C is 2500 +*/ +int readInternalTemp(void) +{ + int reading = 0; + + ADCSRB |= _BV(MUX5); + ADMUX = _BV(REFS1) | _BV(REFS0) | 0b1001 ; + ADCSRA = _BV(ADEN) | _BV(ADPS0) | _BV(ADPS2) ; + + ADCSRA |= 1 << ADSC; + loop_until_bit_is_clear(ADCSRA,ADSC); + reading = ADC; + + ADCSRB=0; //disable ADC, need to write B first for MUX5 bit + ADCSRA=0; //disable ADC + ADMUX=0; //turn off internal vref + + return reading * 113 - 27280; +} diff --git a/platform/RaspBee/dev/adc.h b/platform/RaspBee/dev/adc.h new file mode 100644 index 000000000..e3ff516b1 --- /dev/null +++ b/platform/RaspBee/dev/adc.h @@ -0,0 +1,65 @@ +#ifndef __ADC_ARCH_H__ +#define __ADC_ARCH_H__ + +#include + +/* + * Reference voltage + * The default is 1.6V reference voltage + * The selected reference voltage is the maximum voltage that can be + * measured. + * Directly provide shifted variants so we don't need to shift. + */ +#define ADC_1_5 (2<<6) +#define ADC_1_6 (3<<6) +#define ADC_1_8 (1<<6) +#define ADC_EXTERNAL (0<<6) +#define ADC_DEFAULT ADC_1_6 + +/* sometimes it's desirable to decouple setup / finish from sampling */ + +static inline void adc_setup (uint8_t ref_volt, uint8_t pin) +{ + ADMUX = ref_volt | (pin & 0x7); + ADCSRA = _BV(ADEN) | _BV(ADPS0) | _BV(ADPS2); +} + +static inline int adc_read (void) +{ + ADCSRA |= (1 << ADSC); + loop_until_bit_is_clear (ADCSRA, ADSC); + return ADC; +} + +static inline void adc_fin (void) +{ + ADCSRA = 0; + ADMUX = 0; +} + +static inline void adc_init (void) +{ + uint8_t temp; + ADCSRC = 0; + ADCSRB = 0; + adc_fin (); + /* + * Disable JTAG interface + * Hardware manual about JTD bit: + * "In order to avoid unintentional disabling or enabling of the + * JTAG interface, a timed sequence must be followed when changing + * this bit: The application software must write this bit to the + * desired value twice within four cycles to change its value." + * 15.4.1 "MCUCR - MCU Control Register", p. 219 + */ + temp = MCUCR | (1 << JTD); + MCUCR = temp; + MCUCR = temp; +} + +int readADC(uint8_t pin); +long readVcc(); +int readInternalTemp(void); +void analogReference(uint8_t mode); + +#endif /* __ADC_ARCH_H__ */ diff --git a/platform/RaspBee/dev/batmon.c b/platform/RaspBee/dev/batmon.c new file mode 100644 index 000000000..5c61d125f --- /dev/null +++ b/platform/RaspBee/dev/batmon.c @@ -0,0 +1,55 @@ +#include "contiki.h" +#include "batmon.h" +#include + + + + +int8_t batmon_init() +{ + return 0; +} + +int8_t batmon_get_voltage(uint16_t* voltage) +{ + uint16_t volt = 0; + uint16_t resolution = 75; + uint16_t offset = 2550; + int8_t ctr = 0; + + BATMON = 0 | _BV(BATMON_HR); + _delay_us(2); + + if(BATMON & _BV(BATMON_OK)) + { + // voltage above 2.550 V + resolution = 75; + offset = 2550; + for(ctr=15; ctr>=0; ctr--) + { + BATMON = (BATMON & 0xF0) | (ctr); + _delay_us(2); + if(BATMON & _BV(BATMON_OK)) break; + } + } + else + { + // voltage below 2.550 V + resolution = 50; + offset = 1700; + + BATMON &= ~_BV(BATMON_HR); + + for(ctr=15; ctr>=0; ctr--) + { + BATMON = (BATMON & 0xF0) | (ctr); + _delay_us(2); + if(BATMON & _BV(BATMON_OK)) break; + } + } + + volt = resolution*ctr+offset; + *voltage=volt; + + return 0; +} diff --git a/platform/RaspBee/dev/batmon.h b/platform/RaspBee/dev/batmon.h new file mode 100644 index 000000000..c05f48200 --- /dev/null +++ b/platform/RaspBee/dev/batmon.h @@ -0,0 +1,8 @@ +#ifndef BATMON_H_ +#define BATMON_H_ + +int8_t batmon_init(); +int8_t batmon_get_voltage(uint16_t* voltage); + + +#endif /* BATMON_H_ */ diff --git a/platform/RaspBee/dev/battery-sensor.c b/platform/RaspBee/dev/battery-sensor.c new file mode 100644 index 000000000..1eb7906b4 --- /dev/null +++ b/platform/RaspBee/dev/battery-sensor.c @@ -0,0 +1,90 @@ +/* +* Copyright (c) 2012, BinaryLabs. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. 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. +* 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. +* +* @(#)$Id: battery-sensor.h,v 1.1 2012/08/25 19:34:06 nifi Exp $ +*/ + +/** +* \file +* Battery sensor file for Atmega128rfa1. +* \author +* Paulo Louro +* Harald Pichler +*/ + +/** +*The atmel rf23x radios have a low voltage detector that can be configured in units of 75 millivolts. Here is example *code for the ATmega128rfa1, where the BATMON register is in extended io space [dak664] +*/ + +#include "dev/battery-sensor.h" +#include "dev/batmon.h" + +const struct sensors_sensor battery_sensor; +/*---------------------------------------------------------------------------*/ + +/** +* \return Voltage on battery measurement with BATMON register. +*/ +static int +value(int type) +{ + + uint16_t h; +/* + uint8_t p1; + BATMON = 16; //give BATMON time to stabilize at highest range and lowest voltage + +// Bandgap can't be measured against supply voltage in this chip. +// Use BATMON register instead + for ( p1=16; p1<31; p1++) { + BATMON = p1; + clock_delay_usec(100); // delay needed !! + if ((BATMON&(1< +*/ + +#ifndef __BATTERY_SENSOR_H__ +#define __BATTERY_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor battery_sensor; + +#define BATTERY_SENSOR "Battery" + +#endif /* __BATTERY_SENSOR_H__ */ \ No newline at end of file diff --git a/platform/RaspBee/dev/binary.h b/platform/RaspBee/dev/binary.h new file mode 100644 index 000000000..af1498033 --- /dev/null +++ b/platform/RaspBee/dev/binary.h @@ -0,0 +1,515 @@ +#ifndef Binary_h +#define Binary_h + +#define B0 0 +#define B00 0 +#define B000 0 +#define B0000 0 +#define B00000 0 +#define B000000 0 +#define B0000000 0 +#define B00000000 0 +#define B1 1 +#define B01 1 +#define B001 1 +#define B0001 1 +#define B00001 1 +#define B000001 1 +#define B0000001 1 +#define B00000001 1 +#define B10 2 +#define B010 2 +#define B0010 2 +#define B00010 2 +#define B000010 2 +#define B0000010 2 +#define B00000010 2 +#define B11 3 +#define B011 3 +#define B0011 3 +#define B00011 3 +#define B000011 3 +#define B0000011 3 +#define B00000011 3 +#define B100 4 +#define B0100 4 +#define B00100 4 +#define B000100 4 +#define B0000100 4 +#define B00000100 4 +#define B101 5 +#define B0101 5 +#define B00101 5 +#define B000101 5 +#define B0000101 5 +#define B00000101 5 +#define B110 6 +#define B0110 6 +#define B00110 6 +#define B000110 6 +#define B0000110 6 +#define B00000110 6 +#define B111 7 +#define B0111 7 +#define B00111 7 +#define B000111 7 +#define B0000111 7 +#define B00000111 7 +#define B1000 8 +#define B01000 8 +#define B001000 8 +#define B0001000 8 +#define B00001000 8 +#define B1001 9 +#define B01001 9 +#define B001001 9 +#define B0001001 9 +#define B00001001 9 +#define B1010 10 +#define B01010 10 +#define B001010 10 +#define B0001010 10 +#define B00001010 10 +#define B1011 11 +#define B01011 11 +#define B001011 11 +#define B0001011 11 +#define B00001011 11 +#define B1100 12 +#define B01100 12 +#define B001100 12 +#define B0001100 12 +#define B00001100 12 +#define B1101 13 +#define B01101 13 +#define B001101 13 +#define B0001101 13 +#define B00001101 13 +#define B1110 14 +#define B01110 14 +#define B001110 14 +#define B0001110 14 +#define B00001110 14 +#define B1111 15 +#define B01111 15 +#define B001111 15 +#define B0001111 15 +#define B00001111 15 +#define B10000 16 +#define B010000 16 +#define B0010000 16 +#define B00010000 16 +#define B10001 17 +#define B010001 17 +#define B0010001 17 +#define B00010001 17 +#define B10010 18 +#define B010010 18 +#define B0010010 18 +#define B00010010 18 +#define B10011 19 +#define B010011 19 +#define B0010011 19 +#define B00010011 19 +#define B10100 20 +#define B010100 20 +#define B0010100 20 +#define B00010100 20 +#define B10101 21 +#define B010101 21 +#define B0010101 21 +#define B00010101 21 +#define B10110 22 +#define B010110 22 +#define B0010110 22 +#define B00010110 22 +#define B10111 23 +#define B010111 23 +#define B0010111 23 +#define B00010111 23 +#define B11000 24 +#define B011000 24 +#define B0011000 24 +#define B00011000 24 +#define B11001 25 +#define B011001 25 +#define B0011001 25 +#define B00011001 25 +#define B11010 26 +#define B011010 26 +#define B0011010 26 +#define B00011010 26 +#define B11011 27 +#define B011011 27 +#define B0011011 27 +#define B00011011 27 +#define B11100 28 +#define B011100 28 +#define B0011100 28 +#define B00011100 28 +#define B11101 29 +#define B011101 29 +#define B0011101 29 +#define B00011101 29 +#define B11110 30 +#define B011110 30 +#define B0011110 30 +#define B00011110 30 +#define B11111 31 +#define B011111 31 +#define B0011111 31 +#define B00011111 31 +#define B100000 32 +#define B0100000 32 +#define B00100000 32 +#define B100001 33 +#define B0100001 33 +#define B00100001 33 +#define B100010 34 +#define B0100010 34 +#define B00100010 34 +#define B100011 35 +#define B0100011 35 +#define B00100011 35 +#define B100100 36 +#define B0100100 36 +#define B00100100 36 +#define B100101 37 +#define B0100101 37 +#define B00100101 37 +#define B100110 38 +#define B0100110 38 +#define B00100110 38 +#define B100111 39 +#define B0100111 39 +#define B00100111 39 +#define B101000 40 +#define B0101000 40 +#define B00101000 40 +#define B101001 41 +#define B0101001 41 +#define B00101001 41 +#define B101010 42 +#define B0101010 42 +#define B00101010 42 +#define B101011 43 +#define B0101011 43 +#define B00101011 43 +#define B101100 44 +#define B0101100 44 +#define B00101100 44 +#define B101101 45 +#define B0101101 45 +#define B00101101 45 +#define B101110 46 +#define B0101110 46 +#define B00101110 46 +#define B101111 47 +#define B0101111 47 +#define B00101111 47 +#define B110000 48 +#define B0110000 48 +#define B00110000 48 +#define B110001 49 +#define B0110001 49 +#define B00110001 49 +#define B110010 50 +#define B0110010 50 +#define B00110010 50 +#define B110011 51 +#define B0110011 51 +#define B00110011 51 +#define B110100 52 +#define B0110100 52 +#define B00110100 52 +#define B110101 53 +#define B0110101 53 +#define B00110101 53 +#define B110110 54 +#define B0110110 54 +#define B00110110 54 +#define B110111 55 +#define B0110111 55 +#define B00110111 55 +#define B111000 56 +#define B0111000 56 +#define B00111000 56 +#define B111001 57 +#define B0111001 57 +#define B00111001 57 +#define B111010 58 +#define B0111010 58 +#define B00111010 58 +#define B111011 59 +#define B0111011 59 +#define B00111011 59 +#define B111100 60 +#define B0111100 60 +#define B00111100 60 +#define B111101 61 +#define B0111101 61 +#define B00111101 61 +#define B111110 62 +#define B0111110 62 +#define B00111110 62 +#define B111111 63 +#define B0111111 63 +#define B00111111 63 +#define B1000000 64 +#define B01000000 64 +#define B1000001 65 +#define B01000001 65 +#define B1000010 66 +#define B01000010 66 +#define B1000011 67 +#define B01000011 67 +#define B1000100 68 +#define B01000100 68 +#define B1000101 69 +#define B01000101 69 +#define B1000110 70 +#define B01000110 70 +#define B1000111 71 +#define B01000111 71 +#define B1001000 72 +#define B01001000 72 +#define B1001001 73 +#define B01001001 73 +#define B1001010 74 +#define B01001010 74 +#define B1001011 75 +#define B01001011 75 +#define B1001100 76 +#define B01001100 76 +#define B1001101 77 +#define B01001101 77 +#define B1001110 78 +#define B01001110 78 +#define B1001111 79 +#define B01001111 79 +#define B1010000 80 +#define B01010000 80 +#define B1010001 81 +#define B01010001 81 +#define B1010010 82 +#define B01010010 82 +#define B1010011 83 +#define B01010011 83 +#define B1010100 84 +#define B01010100 84 +#define B1010101 85 +#define B01010101 85 +#define B1010110 86 +#define B01010110 86 +#define B1010111 87 +#define B01010111 87 +#define B1011000 88 +#define B01011000 88 +#define B1011001 89 +#define B01011001 89 +#define B1011010 90 +#define B01011010 90 +#define B1011011 91 +#define B01011011 91 +#define B1011100 92 +#define B01011100 92 +#define B1011101 93 +#define B01011101 93 +#define B1011110 94 +#define B01011110 94 +#define B1011111 95 +#define B01011111 95 +#define B1100000 96 +#define B01100000 96 +#define B1100001 97 +#define B01100001 97 +#define B1100010 98 +#define B01100010 98 +#define B1100011 99 +#define B01100011 99 +#define B1100100 100 +#define B01100100 100 +#define B1100101 101 +#define B01100101 101 +#define B1100110 102 +#define B01100110 102 +#define B1100111 103 +#define B01100111 103 +#define B1101000 104 +#define B01101000 104 +#define B1101001 105 +#define B01101001 105 +#define B1101010 106 +#define B01101010 106 +#define B1101011 107 +#define B01101011 107 +#define B1101100 108 +#define B01101100 108 +#define B1101101 109 +#define B01101101 109 +#define B1101110 110 +#define B01101110 110 +#define B1101111 111 +#define B01101111 111 +#define B1110000 112 +#define B01110000 112 +#define B1110001 113 +#define B01110001 113 +#define B1110010 114 +#define B01110010 114 +#define B1110011 115 +#define B01110011 115 +#define B1110100 116 +#define B01110100 116 +#define B1110101 117 +#define B01110101 117 +#define B1110110 118 +#define B01110110 118 +#define B1110111 119 +#define B01110111 119 +#define B1111000 120 +#define B01111000 120 +#define B1111001 121 +#define B01111001 121 +#define B1111010 122 +#define B01111010 122 +#define B1111011 123 +#define B01111011 123 +#define B1111100 124 +#define B01111100 124 +#define B1111101 125 +#define B01111101 125 +#define B1111110 126 +#define B01111110 126 +#define B1111111 127 +#define B01111111 127 +#define B10000000 128 +#define B10000001 129 +#define B10000010 130 +#define B10000011 131 +#define B10000100 132 +#define B10000101 133 +#define B10000110 134 +#define B10000111 135 +#define B10001000 136 +#define B10001001 137 +#define B10001010 138 +#define B10001011 139 +#define B10001100 140 +#define B10001101 141 +#define B10001110 142 +#define B10001111 143 +#define B10010000 144 +#define B10010001 145 +#define B10010010 146 +#define B10010011 147 +#define B10010100 148 +#define B10010101 149 +#define B10010110 150 +#define B10010111 151 +#define B10011000 152 +#define B10011001 153 +#define B10011010 154 +#define B10011011 155 +#define B10011100 156 +#define B10011101 157 +#define B10011110 158 +#define B10011111 159 +#define B10100000 160 +#define B10100001 161 +#define B10100010 162 +#define B10100011 163 +#define B10100100 164 +#define B10100101 165 +#define B10100110 166 +#define B10100111 167 +#define B10101000 168 +#define B10101001 169 +#define B10101010 170 +#define B10101011 171 +#define B10101100 172 +#define B10101101 173 +#define B10101110 174 +#define B10101111 175 +#define B10110000 176 +#define B10110001 177 +#define B10110010 178 +#define B10110011 179 +#define B10110100 180 +#define B10110101 181 +#define B10110110 182 +#define B10110111 183 +#define B10111000 184 +#define B10111001 185 +#define B10111010 186 +#define B10111011 187 +#define B10111100 188 +#define B10111101 189 +#define B10111110 190 +#define B10111111 191 +#define B11000000 192 +#define B11000001 193 +#define B11000010 194 +#define B11000011 195 +#define B11000100 196 +#define B11000101 197 +#define B11000110 198 +#define B11000111 199 +#define B11001000 200 +#define B11001001 201 +#define B11001010 202 +#define B11001011 203 +#define B11001100 204 +#define B11001101 205 +#define B11001110 206 +#define B11001111 207 +#define B11010000 208 +#define B11010001 209 +#define B11010010 210 +#define B11010011 211 +#define B11010100 212 +#define B11010101 213 +#define B11010110 214 +#define B11010111 215 +#define B11011000 216 +#define B11011001 217 +#define B11011010 218 +#define B11011011 219 +#define B11011100 220 +#define B11011101 221 +#define B11011110 222 +#define B11011111 223 +#define B11100000 224 +#define B11100001 225 +#define B11100010 226 +#define B11100011 227 +#define B11100100 228 +#define B11100101 229 +#define B11100110 230 +#define B11100111 231 +#define B11101000 232 +#define B11101001 233 +#define B11101010 234 +#define B11101011 235 +#define B11101100 236 +#define B11101101 237 +#define B11101110 238 +#define B11101111 239 +#define B11110000 240 +#define B11110001 241 +#define B11110010 242 +#define B11110011 243 +#define B11110100 244 +#define B11110101 245 +#define B11110110 246 +#define B11110111 247 +#define B11111000 248 +#define B11111001 249 +#define B11111010 250 +#define B11111011 251 +#define B11111100 252 +#define B11111101 253 +#define B11111110 254 +#define B11111111 255 + +#endif diff --git a/platform/RaspBee/dev/button-sensor.c b/platform/RaspBee/dev/button-sensor.c new file mode 100644 index 000000000..b402a3658 --- /dev/null +++ b/platform/RaspBee/dev/button-sensor.c @@ -0,0 +1,87 @@ +/* Sensor routine */ + +#include "lib/sensors.h" +#include "dev/button-sensor.h" + +#include +#include +#include "led.h" // debug + +const struct sensors_sensor button_sensor; + +static struct timer debouncetimer; +static int status(int type); +static int enabled = 0; +struct sensors_sensor *sensors[1]; +unsigned char sensors_flags[1]; + +#define BUTTON_BIT INTF4 +#define BUTTON_CHECK_IRQ() (EIFR & BUTTON_BIT) ? 0 : 1 + +#define PRINTF(...) printf(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +ISR(INT4_vect) +{ + +// leds_toggle(LEDS_RED); + + if(BUTTON_CHECK_IRQ()) { + if(timer_expired(&debouncetimer)) { + led1_on(); + timer_set(&debouncetimer, CLOCK_SECOND / 4); + sensors_changed(&button_sensor); + led1_off(); + } + } + +} +/*---------------------------------------------------------------------------*/ + +static int +value(int type) +{ + return (PINE & _BV(PE4) ? 0 : 1) || !timer_expired(&debouncetimer); + + //return 0; +} + +static int +configure(int type, int c) +{ + switch (type) { + case SENSORS_ACTIVE: + if (c) { + if(!status(SENSORS_ACTIVE)) { + led1_on(); + timer_set(&debouncetimer, 0); + DDRE |= (0< +#include "contiki.h" +#include "dht11.h" +#include "led.h" // debug + +#define udelay(u) clock_delay_usec(u) +#define mdelay(u) clock_delay_msec(u) + +// todo: set DHT22 or DHT11 in project file +// define for DHT11 else for DHT22, RHT03 +// #define DHT11 1 + +uint8_t DHT_Read_Data(uint16_t *temperature, uint16_t *humidity){ + + //data[5] is 8byte table where data come from DHT are stored + //laststate holds laststate value + //counter is used to count microSeconds + uint8_t data[5], laststate = 0, counter = 0, j = 0, i = 0; + + //Clear array + data[0] = data[1] = data[2] = data[3] = data[4] = 0; + + uint8_t volatile sreg; + sreg = SREG; /* Save status register before disabling interrupts. */ + cli(); /* Disable interrupts. */ + + //Set pin Output + //Pin High + DHT_DRIVE(); + mdelay(100); //Wait for 100mS + + //Send Request Signal + //Pin Low + OUTP_0(); //20ms Low + mdelay(20); + //Pin High + OUTP_1(); + udelay(40); //40us High + + //Set pin Input to read Bus + //Set pin Input + DHT_RELEASE(); + laststate=DHT_INP(); //Read Pin value + + //Repeat for each Transistions + for (i=0; i254) break; + } + + if (counter>254) break; + + //laststate==_BV(DHT_PIN) checks if laststate was High + //ignore the first 2 transitions which are the DHT Response + //if (laststate==_BV(DHT_PIN) && (i > 2)) { + if ((i&0x01) && (i > 2)) { + //Save bits in segments of bytes + //Shift data[] value 1 position left + //Example. 01010100 if we shift it left one time it will be + //10101000 + + data[j/8]<<=1; + if (counter >= 15) { //If it was high for more than 40uS + //led1_on(); + data[j/8]|=1; //it means it is bit '1' so make a logic + //led1_off(); + } //OR with the value (save it) + j++; //making an OR by 1 to this value 10101000 + } //we will have the resault 10101001 + //1 in 8-bit binary is 00000001 + //j/8 changes table record every 8 bits which means a byte has been saved + //so change to next record. 0/8=0 1/8=0 ... 7/8=0 8/8=1 ... 15/8=1 16/8=2 + laststate=DHT_INP(); //save current state + counter=0; //reset counter + + } + SREG = sreg; /* Enable interrupts. */ + //printf("HUM %d %d %d %d %d %d",data[0],data[1],data[2],data[3],data[4],(uint8_t)(data[0] + data[1] + data[2] + data[3]) ); + //Check if data received are correct by checking the CheckSum + if ((uint8_t)(data[0] + data[1] + data[2] + data[3]) == data[4]) { +#ifdef DHT11 + *humidity = data[0]*100; + *temperature = data[2]*100; +#else + *humidity = ((uint16_t)data[0]<<8 | data[1])*10; + *temperature = ((uint16_t)data[2]<<8 | data[3])*10; +#endif + return 0; + }else{ + *humidity = 2; + *temperature = 2; +// uart_puts("\r\nCheck Sum Error"); + } + + return 0xff; // Check Sum Error +} diff --git a/platform/RaspBee/dev/dht11.h b/platform/RaspBee/dev/dht11.h new file mode 100644 index 000000000..6cf757e5d --- /dev/null +++ b/platform/RaspBee/dev/dht11.h @@ -0,0 +1,67 @@ +/* + DHT-11 Library + (c) Created by Charalampos Andrianakis on 18/12/11. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + */ + +#include +#include +#include + +/* DHT 1-wire is at PortE.6 */ +#define DHT_PIN_READ PINE +#define DHT_PIN_MASK _BV(PE6) +#define DHT_PxOUT PORTE +#define DHT_PxDIR DDRE + +#define SET_PIN_INPUT() (DHT_PxDIR &= ~DHT_PIN_MASK) +#define SET_PIN_OUTPUT() (DHT_PxDIR |= DHT_PIN_MASK) + +#define OUTP_0() (DHT_PxOUT &= ~DHT_PIN_MASK) +#define OUTP_1() (DHT_PxOUT |= DHT_PIN_MASK) + +#define PIN_INIT() do{ \ + SET_PIN_INPUT(); \ + OUTP_0(); \ + } while(0) + + +/* Drive the one wire interface hight */ +#define DHT_DRIVE() do { \ + SET_PIN_OUTPUT(); \ + OUTP_1(); \ + } while (0) + +/* Release the one wire by turning on the internal pull-up. */ +#define DHT_RELEASE() do { \ + SET_PIN_INPUT(); \ + OUTP_1(); \ + } while (0) + +/* Read one bit. */ +#define DHT_INP() (DHT_PIN_READ & DHT_PIN_MASK) + +//The packet size is 40bit but each bit consists of low and high state +//so 40 x 2 = 80 transitions. Also we have 2 transistions DHT response +//and 2 transitions which indicates End Of Frame. In total 84 +#define MAXTIMINGS 84 + +//This is the main function which requests and reads the packet +uint8_t DHT_Read_Data(uint16_t *temperature, uint16_t *humidity); diff --git a/platform/iris/dev/ds2401.c b/platform/RaspBee/dev/ds1820.c similarity index 65% rename from platform/iris/dev/ds2401.c rename to platform/RaspBee/dev/ds1820.c index 578479891..9de3fc8a9 100644 --- a/platform/iris/dev/ds2401.c +++ b/platform/RaspBee/dev/ds1820.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, University of Colombo School of Computing + * Copyright (c) 2005, Swedish Institute of Computer Science * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,10 +28,10 @@ * * This file is part of the Contiki operating system. * + * @(#)$Id: ds1820.c,v 1.5 2010/08/25 18:35:52 nifi Exp $ */ - /* - * Device driver for the Dallas Semiconductor DS2401 chip. Heavily + * Device driver for the Dallas Semiconductor DS1820 chip. Heavily * based on the application note 126 "1-Wire Communications Through * Software". * @@ -39,8 +39,9 @@ */ /* - * For now we stuff in Crossbow Technology, Inc's unique OUI. - * 00:1A:4C Crossbow Technology, Inc + * For now we stuff in Moteiv Corporation's unique OUI. + * From http://www.ethereal.com/distribution/manuf.txt: + * 00:12:75 Moteiv # Moteiv Corporation * * The EUI-64 is a concatenation of the 24-bit OUI value assigned by * the IEEE Registration Authority and a 40-bit extension identifier @@ -50,16 +51,18 @@ #include #include #include "contiki.h" +#include "ds1820.h" -#include "ds2401.h" -unsigned char ds2401_id[8]; +unsigned char ds1820_id[8]; +unsigned char ds1820_ok[8]; -/* 1-wire is at PortA.4 */ -#define SERIAL_ID_PIN_READ PINA -#define SERIAL_ID_PIN_MASK _BV(4) -#define SERIAL_ID_PxOUT PORTA -#define SERIAL_ID_PxDIR DDRA +/* 1-wire is at PortE.3 */ +#define SERIAL_ID_PIN_READ PINE +//#define SERIAL_ID_PIN_MASK _BV(PE3) +#define SERIAL_ID_PIN_MASK _BV(PE4) +#define SERIAL_ID_PxOUT PORTE +#define SERIAL_ID_PxDIR DDRE #define SET_PIN_INPUT() (SERIAL_ID_PxDIR &= ~SERIAL_ID_PIN_MASK) #define SET_PIN_OUTPUT() (SERIAL_ID_PxDIR |= SERIAL_ID_PIN_MASK) @@ -88,6 +91,7 @@ unsigned char ds2401_id[8]; /* Read one bit. */ #define INP() (SERIAL_ID_PIN_READ & SERIAL_ID_PIN_MASK) + /* * Delay times in us. */ @@ -102,36 +106,16 @@ unsigned char ds2401_id[8]; #define tI 70 /* min-60.3, recommended-70, max-75.3 */ #define tJ 410 /* min-410, recommended-410, max-N/A */ /*---------------------------------------------------------------------------*/ -/* - * The delay caused by calling the delay_loop is given by the following - * formula. - * delay(us) = (4n + 1)/XTAL - * where n is the number of iterations and XTAL is the clock frequency(in MHz). - * TODO: Moving the delay_loop to dev/clock.c - */ -static void -delay_loop(uint16_t __count) -{ - asm volatile ("1: sbiw %0,1" "\n\t" - "brne 1b" - : "=w" (__count) - : "0" (__count) - ); -} +#define udelay(u) clock_delay_usec(u) /*---------------------------------------------------------------------------*/ -/* - * This macro relies on the compiler doing the arithmetic during compile time - * for the needed iterations.!! - * In MICAz, XTAL = 7.3728 MHz - */ -#define udelay(u) delay_loop(((7.3728F * u)-1)/4) -/*---------------------------------------------------------------------------*/ -static uint8_t -reset(void) + +static int +owreset(void) { - uint8_t result; + int result; + OW_DRIVE(); - udelay(500); /* 480 < tH < 640 */ + udelay(tH); /* 480 < tH < 640 */ OW_RELEASE(); /* Releases the bus */ udelay(tI); result = INP(); @@ -140,11 +124,12 @@ reset(void) } /*---------------------------------------------------------------------------*/ static void -write_byte(uint8_t byte) +owwriteb(unsigned byte) { - uint8_t i = 7; + int i = 7; + do { - if (byte & 0x01) { + if(byte & 0x01) { OW_DRIVE(); udelay(tA); OW_RELEASE(); /* Releases the bus */ @@ -155,31 +140,35 @@ write_byte(uint8_t byte) OW_RELEASE(); /* Releases the bus */ udelay(tD); } - if (i == 0) + if(i == 0) { return; + } i--; byte >>= 1; - } while (1); + } while(1); } /*---------------------------------------------------------------------------*/ static unsigned -read_byte(void) +owreadb(void) { unsigned result = 0; int i = 7; + do { OW_DRIVE(); udelay(tA); OW_RELEASE(); /* Releases the bus */ udelay(tE); - if (INP()) + if (INP()){ result |= 0x80; /* LSbit first */ + } udelay(tF); - if (i == 0) + if(i == 0) { return result; + } i--; result >>= 1; - } while (1); + } while(1); } /*---------------------------------------------------------------------------*/ /* Polynomial ^8 + ^5 + ^4 + 1 */ @@ -188,57 +177,115 @@ crc8_add(unsigned acc, unsigned byte) { int i; acc ^= byte; - for (i = 0; i < 8; i++) - if (acc & 1) + for(i = 0; i < 8; i++) { + if(acc & 1) { acc = (acc >> 1) ^ 0x8c; - else + } else { acc >>= 1; - + } + } return acc; } /*---------------------------------------------------------------------------*/ int -ds2401_init() +ds1820_init() { int i; - uint8_t volatile sreg; unsigned family, crc, acc; PIN_INIT(); - sreg = SREG; /* Save status register before disabling interrupts. */ - cli(); /* Disable interrupts. */ + if(owreset() == 0) { /* Something pulled down 1-wire. */ - if (reset() == 0) { - write_byte(0x33); /* Read ROM command. */ - family = read_byte(); - for (i = 7; i >= 2; i--) { - ds2401_id[i] = read_byte(); + owwriteb(0x33); /* Read ROM command. */ + family = owreadb(); + /* We receive 6 bytes in the reverse order, LSbyte first. */ + for(i = 7; i >= 2; i--) { + ds1820_id[i] = owreadb(); } - crc = read_byte(); + crc = owreadb(); - SREG = sreg; /* Enable interrupts. */ - - if(family != 0x01) { + /* Verify family DS1820 and that CRC match. */ + if(family != 0x10) { goto fail; } acc = crc8_add(0x0, family); - for (i = 7; i >= 2; i--) { - acc = crc8_add(acc, ds2401_id[i]); + for(i = 7; i >= 2; i--) { + acc = crc8_add(acc, ds1820_id[i]); } - if (acc == crc) { - /* 00:1A:4C OUI for Crossbow Technology, Inc. */ - ds2401_id[0] = 0x00; - ds2401_id[1] = 0x1A; - ds2401_id[2] = 0x4C; - return 1; /* Success! */ + if(acc == crc) { + ds1820_id[0] = 0x00; + ds1820_id[1] = 0x00; + ds1820_id[2] = 0x00; + return 1; /* Success! */ } } else { - SREG = sreg; /* Enable interrupts. */ } -fail: - memset(ds2401_id, 0x0, sizeof(ds2401_id)); - return 0; /* Fail! */ + + fail: + memset(ds1820_id, 0x0, sizeof(ds1820_id)); + return 0; /* Fail! */ } /*---------------------------------------------------------------------------*/ +int +ds1820_temp() +{ + ds1820_convert(); +// wait max 750ms pin lo + clock_wait(CLOCK_SECOND); + ds1820_read(); + return 1; +} + +int +ds1820_convert() +{ + unsigned i; + + PIN_INIT(); + for(i=0;i<3;i++){ + if(owreset() == 0) { /* Something pulled down 1-wire. */ + owwriteb(0xCC); /* Skip ROM command. */ + owwriteb(0x44); /* Convert T command. */ + OW_RELEASE(); /* Releases the bus */ + return 1; + } else { + } + } + return 0; /* Fail! */ +} +/*---------------------------------------------------------------------------*/ +int +ds1820_read() +{ + int i; + unsigned crc, acc; + + if(owreset() == 0) { /* Something pulled down 1-wire. */ + owwriteb(0xCC); /* Skip ROM command. */ + owwriteb(0xBE); /* Read Scratchpad command. */ + /* We receive 8 bytes in the reverse order, LSbyte first. */ + for(i = 0; i < 8; i++) { + ds1820_id[i] = owreadb(); + } + crc = owreadb(); + + acc=0; + for(i = 0; i < 8; i++) { + acc = crc8_add(acc, ds1820_id[i]); + } + if(acc == crc) { + // store temp + for(i = 0; i < 8; i++) { + ds1820_ok[i]=ds1820_id[i]; + } + return 1; /* Success! */ + } else { + return 0; /* Fail! */ + } + } else { + return 0; /* Fail! */ + } + return 1; /* Fail! */ +} diff --git a/platform/sensinode/dev/button-sensor.h b/platform/RaspBee/dev/ds1820.h similarity index 80% rename from platform/sensinode/dev/button-sensor.h rename to platform/RaspBee/dev/ds1820.h index 97a185223..e4178d63e 100644 --- a/platform/sensinode/dev/button-sensor.h +++ b/platform/RaspBee/dev/ds1820.h @@ -27,22 +27,19 @@ * SUCH DAMAGE. * * This file is part of the Contiki operating system. - */ - -/** - * \file - * Override core/dev/button-sensor.h * - * We simply include "dev/sensinode-sensors.h". We do this so that apps - * and examples including button-sensor.h will compile for sensinodes - * - * \author - * George Oikonomou - + * @(#)$Id: ds1820.h,v 1.1 2006/06/17 22:41:16 adamdunkels Exp $ */ +/* -*- C -*- */ +/* @(#)$Id: ds1820.h,v 1.1 2006/06/17 22:41:16 adamdunkels Exp $ */ -#ifndef BUTTON_SENSOR_H_ -#define BUTTON_SENSOR_H_ +#ifndef DS1820_H +#define DS1820_H -#include "dev/sensinode-sensors.h" - -#endif /* BUTTON_SENSOR_H_ */ +extern unsigned char ds1820_id[8]; +extern unsigned char ds1820_ok[8]; +extern int ds1820_init(); +extern int ds1820_convert(); +extern int ds1820_read(); +extern int ds1820_temp(); +#endif /* DS1820_H */ diff --git a/platform/RaspBee/dev/hw-arduino.h b/platform/RaspBee/dev/hw-arduino.h new file mode 100644 index 000000000..bcd626ec6 --- /dev/null +++ b/platform/RaspBee/dev/hw-arduino.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014, Ralf Schlatterbeck Open Source Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + */ + +/** + * \defgroup compatibility Arduino - Contiki + * + * This defines contiki-compatible hardware definitions for running + * arduino sketches (or just to call arduino-compatible function). + * For now only for osd hardware, a similar file should exist for each + * arduino-compatible hardware. + * + * @{ + */ + +/** + * \file + * Header file for arduino compatibility + * \author + * Ralf Schlatterbeck + * + */ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include "contiki.h" + +/* + * The OSD hardware only supports timer 3 for PWM, timer 2 is used by + * contiki for sleep/wakeup timing and is not usable for PWM. + */ +#define digitalPinToTimer(pin) \ + ( (pin) == 2 \ + ? TIMER3A \ + : ( (pin) == 3 \ + ? TIMER3B \ + : ((pin == 4) ? TIMER3C : NOT_ON_TIMER) \ + ) \ + ) + +/* Only init timer 3 with phase correct pwm 8-bit and prescaler 64 */ +#define arduino_pwm_timer_init() \ + (hwtimer_ini (3, HWT_WGM_PWM_PHASE_8_BIT, HWT_CLOCK_PRESCALER_64, 0)) + +/* + * VI settings, see coding style + * ex:ts=8:et:sw=2 + */ + +#ifdef __cplusplus +} // extern "C" +#endif + +/** @} */ diff --git a/platform/RaspBee/dev/i2c.c b/platform/RaspBee/dev/i2c.c new file mode 100644 index 000000000..0fa295849 --- /dev/null +++ b/platform/RaspBee/dev/i2c.c @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2014, Ingo Gulyas Intembsys + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + + /** + * \file + * I2C driver for ATMEGA128rfa1 + * + * \author + * Ingo Gulyas Intembsys + * office@intembsys.at + * www.intembsys.at + */ + + +#include "i2c.h" +#include "contiki-conf.h" +#include +#include +#include +#include + +#if I2C_TD != 0 +#include +#include +#include "system_mgmt.h" +#define PRINTD(FORMAT,args...) {sleep_acquire_lock(); printf_P(PSTR(FORMAT),##args); sleep_release_lock();} +#else +#define PRINTD(...) +#endif + +#if WITH_RTDEBUG == 1 +#include "rtdebug.h" +#define RTDEBUG_PUSH(x) rtdebug_push(x) +#else +#warning "I2C Driver compiling without RTDEBUG!" +#define RTDEBUG_PUSH(x) +#endif + +#ifndef TIMEOUT_TIMER +#warning "I2C Driver compiling without TIMEOUT!" +#endif + + +static int8_t wait_job(); +static int8_t wait_stop(); + +static int8_t i2c_ioctl(const i2c_driver* const me, uint8_t cmd, uint8_t arg); +static int8_t i2c_read(const i2c_driver* const me, uint8_t cmd_flags, uint8_t* buffer, uint8_t len); +static int8_t i2c_write(const i2c_driver* const me, uint8_t cmd_flags, const uint8_t* data, uint8_t len); + + +// static linkage of member functions +i2c_driver i2c_drv = {i2c_ioctl, i2c_read, i2c_write}; +// lock spi if driver opened to prevent further opening access +static volatile bool i2c_lock = false; + + +/////////////////////////////////////////////////////////////// +// global functions +/////////////////////////////////////////////////////////////// + +i2c_driver* i2c_open(void) +{ + if(i2c_lock == true) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_OPEN__DEVICE_BUSY); + return NULL; + } + + i2c_lock = true; + power_twi_enable(); + I2C_INIT(); + + TWBR = I2C_FREQ_STANDARD; + TWSR &= ~((1< 0) && (buffer == NULL)) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__ERROR_NULLPOINTER); + return I2C_ERROR_DRIVER; + } + + do + { + if(cmd_flags & I2C_CMD_FLAG_START) + { + I2C_START(); + if(wait_job() != I2C_OK) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__START_TIMEOUT); + status = I2C_ERROR_TIMEOUT; + break; + } + if((I2C_STATUS() != I2C_STATUS_START) && (I2C_STATUS() != I2C_STATUS_START_REP)) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__START_ERROR); + status = I2C_ERROR_START; + break; + } + PRINTD("I2C-RD-START\n"); + } + + if(len == 0) break; + + for(i=0; i<(len-1); i++) + { + I2C_READ_BYTE_ACK(); + if(wait_job() != I2C_OK) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__READ_BYTE_ACK_TIMEOUT); + status = I2C_ERROR_TIMEOUT; + break; + } + if(I2C_STATUS() != I2C_STATUS_DATAR_ACK) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__READ_BYTE_ACK_ERROR); + status = I2C_ERROR_READ; + break; + } + buffer[i] = I2C_RX_REG; + PRINTD("I2C-RD-RACK: 0x%02X\n", buffer[i]); + } + + I2C_READ_BYTE_NACK(); + if(wait_job() != I2C_OK) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__READ_BYTE_NACK_TIMEOUT); + status = I2C_ERROR_TIMEOUT; + break; + } + if(I2C_STATUS() != I2C_STATUS_DATAR_NACK) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__READ_BYTE_NACK_ERROR); + status = I2C_ERROR_READ; + break; + } + buffer[i] = I2C_RX_REG; + PRINTD("I2C-RD-RNACK: 0x%02X\n", buffer[i]); + + } while (0); + + if(cmd_flags & I2C_CMD_FLAG_STOP) + { + I2C_STOP(); + if(wait_stop() != I2C_OK) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_READ__STOP_TIMEOUT); + status = I2C_ERROR_TIMEOUT; + } + PRINTD("I2C-RD_STOP\n"); + } + + return status; +} + +static int8_t i2c_write(const i2c_driver* const me, uint8_t cmd_flags, const uint8_t* data, uint8_t len) +{ + uint8_t i = 0; + int8_t status = I2C_OK; + + + if(me == NULL || i2c_lock == false) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__DEVICE_CLOSED); + return I2C_ERROR_DRIVER; + } + + if((len > 0) && (data == NULL)) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__ERROR_NULLPOINTER); + return I2C_ERROR_DRIVER; + } + + do + { + if(cmd_flags & I2C_CMD_FLAG_START) + { + I2C_START(); + if(wait_job() != I2C_OK) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__START_TIMEOUT); + status = I2C_ERROR_TIMEOUT; + break; + } + if((I2C_STATUS() != I2C_STATUS_START) && (I2C_STATUS() != I2C_STATUS_START_REP)) + { + RTDEBUG_PUSH(RTDEBUG_CODE__I2C_WRITE__START_ERROR); + status = I2C_ERROR_START; + break; + } + PRINTD("I2C-WR-START\n"); + } + + + + for(i=0; i + +//////////////////////////////////////////////////////////////////////////////////////////// +// CONFIGURATION SECTION: + +#define I2C_TD 0 // compiler switch: i2c testdriver code + +#define I2C_PORT PORTD +#define I2C_DDR DDRD +#define I2C_SCL_PIN 0 +#define I2C_SDA_PIN 1 + +// END OF CONFIGURATION SECTION +//////////////////////////////////////////////////////////////////////////////////////////// + +#define I2C_INIT() ({I2C_DDR &= ~((1< CHECK F_CPU SETTINGS!" +#endif + + +#define I2C_STATUS_REG TWSR +#define I2C_TX_REG TWDR +#define I2C_RX_REG TWDR + +#define I2C_START() (TWCR = (1< -#include "dev/led.h" -#include "intkey.h" +#include "key.h" /*---------------------------------------------------------------------------*/ @@ -48,20 +46,10 @@ * \brief This will intialize the KEY for button readings. */ void -intkey_init(void) +key_init(void) { - // Reed1 - PORTB |= (1< #include -void intkey_init(void); -uint8_t is_reed1(void); -uint8_t is_reed2(void); -uint8_t is_sabotage(void); +void key_init(void); +uint8_t is_button(void); #endif /* __KEY_H__ */ diff --git a/platform/RaspBee/dev/led.c b/platform/RaspBee/dev/led.c new file mode 100644 index 000000000..f9a7163d0 --- /dev/null +++ b/platform/RaspBee/dev/led.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2012 Bernhard Trinnes + * All rights reserved. + * + * 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 + * 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 OWNER 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. + */ +/** + * \file + * + * \brief + * This file provides RaspBee LED support. + * + * \author + * Bernhard Trinnes bernhard.trinnes@guh.guru + * + */ + +#include "led.h" + +/** + * \addtogroup relay + * \{ +*/ +/*---------------------------------------------------------------------------*/ + +/** + * \brief Turns LED1 on. +*/ +void +led1_on(void) +{ + PORTD &= ~(1< +*/ + +#include "contiki.h" +#include "Arduino.h" +#include "dev/optriac-sensor.h" + +#define PRINTF(...) printf(__VA_ARGS__) + +const struct sensors_sensor optriac_sensor; +static int status(int type); +static int enabled = 0; +static int optriac[2]={0,0}; +static int optriacpin[8]={OPTRIAC_PIN_1,OPTRIAC_PIN_2}; + +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return optriac[type]; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + switch(type) { + case SENSORS_ACTIVE: + if(c) { + if(!status(SENSORS_ACTIVE)) { + pinMode(optriacpin[OPTRIAC_SENSOR_1], OUTPUT); + digitalWrite(optriacpin[OPTRIAC_SENSOR_1], LOW); + pinMode(optriacpin[OPTRIAC_SENSOR_2], OUTPUT); + digitalWrite(optriacpin[OPTRIAC_SENSOR_2], LOW); + + enabled = 1; + } + } else { + enabled = 1; + } + break; + case OPTRIAC_SENSOR_1: + case OPTRIAC_SENSOR_2: + + if(c==0){ + digitalWrite(optriacpin[type], LOW); + optriac[type]=0; + }else{ + digitalWrite(optriacpin[type], HIGH); + optriac[type]=1; + }; + break; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(optriac_sensor, OPTRIAC_SENSOR, value, configure, status); diff --git a/platform/RaspBee/dev/optriac-sensor.h b/platform/RaspBee/dev/optriac-sensor.h new file mode 100644 index 000000000..8cec46c14 --- /dev/null +++ b/platform/RaspBee/dev/optriac-sensor.h @@ -0,0 +1,54 @@ +/* +* Copyright (c), Harald Pichler. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. 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. +* 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. +* +* @(#)$Id: servo-sensor.h,v 1.0 2013/02/20 19:34:06 nifi Exp $ +*/ + +/** +* \file +* Servo sensor header file for Atmega128rfa1. +* \author +* Harald Pichler +*/ + +#ifndef __OPTRIAC_SENSOR_H__ +#define __OPTRIAC_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor optriac_sensor; + +#define OPTRIAC_SENSOR "TRIAC" +#define OPTRIAC_SENSOR_1 0 +#define OPTRIAC_SENSOR_2 1 + +/* default pins Arduino-Merkurboard */ +#define OPTRIAC_PIN_1 2 +#define OPTRIAC_PIN_2 3 + +#endif /* __OPTRIAC_SENSOR_H__ */ diff --git a/platform/osd-merkur/dev/pins_arduino.h b/platform/RaspBee/dev/pins_arduino.h similarity index 96% rename from platform/osd-merkur/dev/pins_arduino.h rename to platform/RaspBee/dev/pins_arduino.h index 738444bd1..d3b439299 100644 --- a/platform/osd-merkur/dev/pins_arduino.h +++ b/platform/RaspBee/dev/pins_arduino.h @@ -1,218 +1,218 @@ -/* - pins_arduino.h - Pin definition functions for Arduino - Part of Arduino - http://www.arduino.cc/ - - Copyright (c) 2014 Harald Pichler - - 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., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA - - $Id: wiring.h 249 2014-04-18 17:35:12Z pichler $ -*/ - -/* - This version of pins_arduino.h is for the Merkur Dev Board r1 - Harald Pichler 2014 Apr 18 -*/ - -#ifndef Pins_Arduino_h -#define Pins_Arduino_h - -#include - -#define NUM_DIGITAL_PINS 15 -#define NUM_ANALOG_INPUTS 6 -#define analogInputToDigitalPin(p) ((p < NUM_ANALOG_INPUTS) ? (p) + NUM_DIGITAL_PINS : -1) -#define digitalPinHasPWM(p) ((p) == 2 ||(p) == 3 ||(p) == 4 ||(p) == 14 ) - -// Dev board specific defines: RF RX and TX LEDs: -#define RXLED_DDR DDRB -#define RXLED_PORT PORTB -#define RXLED_POS PB6 - -#define TXLED_DDR DDRB -#define TXLED_PORT PORTB -#define TXLED_POS PB7 - -const static uint8_t SS = 10; -const static uint8_t MOSI = 11; -const static uint8_t MISO = 13; -const static uint8_t SCK = 12; - -const static uint8_t SDA = 9; -const static uint8_t SCL = 8; -const static uint8_t LED = 4; -const static uint8_t LED1 = 4; -const static uint8_t LED2 = 5; - -const static uint8_t A0 = 7; -const static uint8_t A1 = 6; -const static uint8_t A2 = 5; -const static uint8_t A3 = 4; -const static uint8_t A4 = 0; -const static uint8_t A5 = 1; - -// A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins) -// Only pins available for RECEIVE (TRANSMIT can be on any pin): -// Pins: 10, 11, 12, 13, 14 - -#define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 14)) || ? (&PCICR) : ((uint8_t *)0) ) - -#define digitalPinToPCICRbit(p) ( 0 ) - -#define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 14)) ? (&PCMSK0) : ((uint8_t *)0) ) - -#define digitalPinToPCMSKbit(p) ( ((p) == 10) ? 6 : \ - ( ((p) == 11) ? 5 : \ - ( ((p) == 12) ? 1 : \ - ( ((p) == 13) ? 3 : \ - ( ((p) == 14) ? 7 : \ - 0 ) ) ) ) ) - -#ifdef ARDUINO_MAIN - -const uint16_t PROGMEM port_to_mode_PGM[] = { - NOT_A_PORT, - NOT_A_PORT, - (uint16_t)&DDRB, - NOT_A_PORT, - (uint16_t)&DDRD, - (uint16_t)&DDRE, - (uint16_t)&DDRF, - (uint16_t)&DDRG, - NOT_A_PORT, - NOT_A_PORT, - NOT_A_PORT, - NOT_A_PORT, - NOT_A_PORT, -}; - -const uint16_t PROGMEM port_to_output_PGM[] = { - NOT_A_PORT, - NOT_A_PORT, - (uint16_t)&PORTB, - NOT_A_PORT, - (uint16_t)&PORTD, - (uint16_t)&PORTE, - (uint16_t)&PORTF, - (uint16_t)&PORTG, - NOT_A_PORT, - NOT_A_PORT, - NOT_A_PORT, - NOT_A_PORT, - NOT_A_PORT, -}; - -const uint16_t PROGMEM port_to_input_PGM[] = { - NOT_A_PIN, - NOT_A_PIN, - NOT_A_PIN, - (uint16_t)&PINC, - (uint16_t)&PIND, - (uint16_t)&PINE, - (uint16_t)&PINF, - (uint16_t)&PING, - NOT_A_PIN, - NOT_A_PIN, - NOT_A_PIN, - NOT_A_PIN, - NOT_A_PIN, -}; - -const uint8_t PROGMEM digital_pin_to_port_PGM[] = { - // PORTLIST - // ------------------------------------------- - PE , // PE 1 ** 0 ** D0 / USART0_TX - PE , // PE 0 ** 1 ** D1 / USART0_RX - PE , // PE 3 ** 2 ** D2 / PWM - PE , // PE 4 ** 3 ** D3 / PWM - PE , // PE 5 ** 4 ** D4 / PWM / LED1 / LED - PE , // PE 6 ** 5 ** D5 / LED2 - PD , // PD 3 ** 6 ** D6 / USART1_TX - PD , // PD 2 ** 7 ** D7 / USART1_RX - PD , // PD 0 ** 8 ** D8 / I2C_SCL - PD , // PD 1 ** 9 ** D9 / I2C_SDA - PB , // PB 0 ** 10 ** D10 / SPI_SSN - PB , // PB 2 ** 11 ** D11 / SPI_MOSI - PB , // PB 1 ** 12 ** D12 / SPI_SCK - PB , // PB 3 ** 13 ** D13 / SPI_MISO - PB , // PB 4 ** 14 ** D14 / PWM - PF , // PF 7 ** 15 ** A0 / D15 - PF , // PF 6 ** 16 ** A1 / D16 - PF , // PF 5 ** 17 ** A2 / D17 - PF , // PF 4 ** 18 ** A3 / D18 - PF , // PF 0 ** 19 ** A4 / D19 - PF , // PF 1 ** 20 ** A5 / D20 -// PB , // PB 6 ** 34 ** D34 / LED1 / LED / PWM -// PB , // PB 7 ** 35 ** D35 / LED2 / PWM -// PE , // PE 2 ** 2 ** D2 -// PE , // PE 7 ** 7 ** D7 -// PB , // PB 5 ** 8 ** D8 / PWM -// PG , // PG 0 ** 16 ** D16 -// PG , // PG 1 ** 17 ** D17 -// PG , // PG 2 ** 18 ** D18 -// PG , // PG 5 ** 19 ** D19 / PWM -// PD , // PD 4 ** 22 ** D22 -// PD , // PD 5 ** 23 ** D23 -// PD , // PD 6 ** 24 ** D24 -// PD , // PD 7 ** 25 ** D25 -// PF , // PF 2 ** 28 ** A2 / D28 -// PF , // PF 3 ** 29 ** A3 / D29 -}; - -const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { - // PIN IN PORT - // ------------------------------------------- - _BV( 1 ) , // PE 1 ** 0 ** USART0_TX - _BV( 0 ) , // PE 0 ** 1 ** USART0_RX - _BV( 3 ) , // PE 3 ** 2 ** D3 / PWM - _BV( 4 ) , // PE 4 ** 3 ** D4 / PWM - _BV( 5 ) , // PE 5 ** 4 ** D5 / PWM - _BV( 6 ) , // PE 6 ** 5 ** D6 - _BV( 3 ) , // PD 3 ** 6 ** D21 / USART1_TX - _BV( 2 ) , // PD 2 ** 7 ** D20 / USART1_RX - _BV( 0 ) , // PD 0 ** 8 ** D15 / I2C_SCL - _BV( 1 ) , // PD 1 ** 9 ** D14 / I2C_SDA - _BV( 0 ) , // PB 0 ** 10 ** D10 / SPI_SSN - _BV( 2 ) , // PB 2 ** 11 ** D11 / SPI_MOSI - _BV( 1 ) , // PB 1 ** 12 ** D13 / SPI_SCK - _BV( 3 ) , // PB 3 ** 13 ** D12 / SPI_MISO - _BV( 4 ) , // PB 4 ** 14 ** D9 / PWM - _BV( 7 ) , // PF 7 ** 15 ** A0 / D33 - _BV( 6 ) , // PF 6 ** 16 ** A1 / D32 - _BV( 5 ) , // PF 5 ** 17 ** A2 / D31 - _BV( 4 ) , // PF 4 ** 18 ** A3 / D30 - _BV( 0 ) , // PF 0 ** 19 ** A4 / D26 - _BV( 1 ) , // PF 1 ** 20 ** A5 / D27 -// _BV( 2 ) , // PE 2 ** 2 ** D2 -// _BV( 7 ) , // PE 7 ** 7 ** D7 -// _BV( 5 ) , // PB 5 ** 8 ** D8 / PWM -// _BV( 0 ) , // PG 0 ** 16 ** D16 -// _BV( 1 ) , // PG 1 ** 17 ** D17 -// _BV( 2 ) , // PG 2 ** 18 ** D18 -// _BV( 5 ) , // PG 5 ** 19 ** D19 / PWM -// _BV( 4 ) , // PD 4 ** 22 ** D22 -// _BV( 5 ) , // PD 5 ** 23 ** D23 -// _BV( 6 ) , // PD 6 ** 24 ** D24 -// _BV( 7 ) , // PD 7 ** 25 ** D25 -// _BV( 2 ) , // PF 2 ** 28 ** A2 / D28 -// _BV( 3 ) , // PF 3 ** 29 ** A3 / D29 -// _BV( 6 ) , // PB 6 ** 34 ** D34 / LED1 / LED / PWM -// _BV( 7 ) , // PB 7 ** 35 ** D35 / LED2 / PWM -}; - -#endif - -#endif +/* + pins_arduino.h - Pin definition functions for Arduino + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2014 Harald Pichler + + 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., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.h 249 2014-04-18 17:35:12Z pichler $ +*/ + +/* + This version of pins_arduino.h is for the Merkur Dev Board r1 + Harald Pichler 2014 Apr 18 +*/ + +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define NUM_DIGITAL_PINS 15 +#define NUM_ANALOG_INPUTS 6 +#define analogInputToDigitalPin(p) ((p < NUM_ANALOG_INPUTS) ? (p) + NUM_DIGITAL_PINS : -1) +#define digitalPinHasPWM(p) ((p) == 2 ||(p) == 3 ||(p) == 4 ||(p) == 14 ) + +// Dev board specific defines: RF RX and TX LEDs: +#define RXLED_DDR DDRB +#define RXLED_PORT PORTB +#define RXLED_POS PB6 + +#define TXLED_DDR DDRB +#define TXLED_PORT PORTB +#define TXLED_POS PB7 + +const static uint8_t SS = 10; +const static uint8_t MOSI = 11; +const static uint8_t MISO = 13; +const static uint8_t SCK = 12; + +const static uint8_t SDA = 9; +const static uint8_t SCL = 8; +const static uint8_t LED = 4; +const static uint8_t LED1 = 4; +const static uint8_t LED2 = 5; + +const static uint8_t A0 = 7; +const static uint8_t A1 = 6; +const static uint8_t A2 = 5; +const static uint8_t A3 = 4; +const static uint8_t A4 = 0; +const static uint8_t A5 = 1; + +// A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins) +// Only pins available for RECEIVE (TRANSMIT can be on any pin): +// Pins: 10, 11, 12, 13, 14 + +#define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 14)) || ? (&PCICR) : ((uint8_t *)0) ) + +#define digitalPinToPCICRbit(p) ( 0 ) + +#define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 14)) ? (&PCMSK0) : ((uint8_t *)0) ) + +#define digitalPinToPCMSKbit(p) ( ((p) == 10) ? 6 : \ + ( ((p) == 11) ? 5 : \ + ( ((p) == 12) ? 1 : \ + ( ((p) == 13) ? 3 : \ + ( ((p) == 14) ? 7 : \ + 0 ) ) ) ) ) + +#ifdef ARDUINO_MAIN + +const uint16_t PROGMEM port_to_mode_PGM[] = { + NOT_A_PORT, + NOT_A_PORT, + (uint16_t)&DDRB, + NOT_A_PORT, + (uint16_t)&DDRD, + (uint16_t)&DDRE, + (uint16_t)&DDRF, + (uint16_t)&DDRG, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, +}; + +const uint16_t PROGMEM port_to_output_PGM[] = { + NOT_A_PORT, + NOT_A_PORT, + (uint16_t)&PORTB, + NOT_A_PORT, + (uint16_t)&PORTD, + (uint16_t)&PORTE, + (uint16_t)&PORTF, + (uint16_t)&PORTG, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, +}; + +const uint16_t PROGMEM port_to_input_PGM[] = { + NOT_A_PIN, + NOT_A_PIN, + NOT_A_PIN, + (uint16_t)&PINC, + (uint16_t)&PIND, + (uint16_t)&PINE, + (uint16_t)&PINF, + (uint16_t)&PING, + NOT_A_PIN, + NOT_A_PIN, + NOT_A_PIN, + NOT_A_PIN, + NOT_A_PIN, +}; + +const uint8_t PROGMEM digital_pin_to_port_PGM[] = { + // PORTLIST + // ------------------------------------------- + PE , // PE 1 ** 0 ** D0 / USART0_TX + PE , // PE 0 ** 1 ** D1 / USART0_RX + PE , // PE 3 ** 2 ** D2 / PWM + PE , // PE 4 ** 3 ** D3 / PWM + PE , // PE 5 ** 4 ** D4 / PWM / LED1 / LED + PE , // PE 6 ** 5 ** D5 / LED2 + PD , // PD 3 ** 6 ** D6 / USART1_TX + PD , // PD 2 ** 7 ** D7 / USART1_RX + PD , // PD 0 ** 8 ** D8 / I2C_SCL + PD , // PD 1 ** 9 ** D9 / I2C_SDA + PB , // PB 0 ** 10 ** D10 / SPI_SSN + PB , // PB 2 ** 11 ** D11 / SPI_MOSI + PB , // PB 1 ** 12 ** D12 / SPI_SCK + PB , // PB 3 ** 13 ** D13 / SPI_MISO + PB , // PB 4 ** 14 ** D14 / PWM + PF , // PF 7 ** 15 ** A0 / D15 + PF , // PF 6 ** 16 ** A1 / D16 + PF , // PF 5 ** 17 ** A2 / D17 + PF , // PF 4 ** 18 ** A3 / D18 + PF , // PF 0 ** 19 ** A4 / D19 + PF , // PF 1 ** 20 ** A5 / D20 +// PB , // PB 6 ** 34 ** D34 / LED1 / LED / PWM +// PB , // PB 7 ** 35 ** D35 / LED2 / PWM +// PE , // PE 2 ** 2 ** D2 +// PE , // PE 7 ** 7 ** D7 +// PB , // PB 5 ** 8 ** D8 / PWM +// PG , // PG 0 ** 16 ** D16 +// PG , // PG 1 ** 17 ** D17 +// PG , // PG 2 ** 18 ** D18 +// PG , // PG 5 ** 19 ** D19 / PWM +// PD , // PD 4 ** 22 ** D22 +// PD , // PD 5 ** 23 ** D23 +// PD , // PD 6 ** 24 ** D24 +// PD , // PD 7 ** 25 ** D25 +// PF , // PF 2 ** 28 ** A2 / D28 +// PF , // PF 3 ** 29 ** A3 / D29 +}; + +const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { + // PIN IN PORT + // ------------------------------------------- + _BV( 1 ) , // PE 1 ** 0 ** USART0_TX + _BV( 0 ) , // PE 0 ** 1 ** USART0_RX + _BV( 3 ) , // PE 3 ** 2 ** D3 / PWM + _BV( 4 ) , // PE 4 ** 3 ** D4 / PWM + _BV( 5 ) , // PE 5 ** 4 ** D5 / PWM + _BV( 6 ) , // PE 6 ** 5 ** D6 + _BV( 3 ) , // PD 3 ** 6 ** D21 / USART1_TX + _BV( 2 ) , // PD 2 ** 7 ** D20 / USART1_RX + _BV( 0 ) , // PD 0 ** 8 ** D15 / I2C_SCL + _BV( 1 ) , // PD 1 ** 9 ** D14 / I2C_SDA + _BV( 0 ) , // PB 0 ** 10 ** D10 / SPI_SSN + _BV( 2 ) , // PB 2 ** 11 ** D11 / SPI_MOSI + _BV( 1 ) , // PB 1 ** 12 ** D13 / SPI_SCK + _BV( 3 ) , // PB 3 ** 13 ** D12 / SPI_MISO + _BV( 4 ) , // PB 4 ** 14 ** D9 / PWM + _BV( 7 ) , // PF 7 ** 15 ** A0 / D33 + _BV( 6 ) , // PF 6 ** 16 ** A1 / D32 + _BV( 5 ) , // PF 5 ** 17 ** A2 / D31 + _BV( 4 ) , // PF 4 ** 18 ** A3 / D30 + _BV( 0 ) , // PF 0 ** 19 ** A4 / D26 + _BV( 1 ) , // PF 1 ** 20 ** A5 / D27 +// _BV( 2 ) , // PE 2 ** 2 ** D2 +// _BV( 7 ) , // PE 7 ** 7 ** D7 +// _BV( 5 ) , // PB 5 ** 8 ** D8 / PWM +// _BV( 0 ) , // PG 0 ** 16 ** D16 +// _BV( 1 ) , // PG 1 ** 17 ** D17 +// _BV( 2 ) , // PG 2 ** 18 ** D18 +// _BV( 5 ) , // PG 5 ** 19 ** D19 / PWM +// _BV( 4 ) , // PD 4 ** 22 ** D22 +// _BV( 5 ) , // PD 5 ** 23 ** D23 +// _BV( 6 ) , // PD 6 ** 24 ** D24 +// _BV( 7 ) , // PD 7 ** 25 ** D25 +// _BV( 2 ) , // PF 2 ** 28 ** A2 / D28 +// _BV( 3 ) , // PF 3 ** 29 ** A3 / D29 +// _BV( 6 ) , // PB 6 ** 34 ** D34 / LED1 / LED / PWM +// _BV( 7 ) , // PB 7 ** 35 ** D35 / LED2 / PWM +}; + +#endif + +#endif diff --git a/platform/RaspBee/dev/pir-sensor.c b/platform/RaspBee/dev/pir-sensor.c new file mode 100644 index 000000000..37a97c025 --- /dev/null +++ b/platform/RaspBee/dev/pir-sensor.c @@ -0,0 +1,85 @@ +/* Sensor routine */ +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/pir-sensor.h" + +#include +#include "led.h" // debug + +const struct sensors_sensor pir_sensor; + +static struct timer debouncetimer; +static int status(int type); +static int enabled = 0; +struct sensors_sensor *sensors[1]; +unsigned char sensors_flags[1]; + +#define PIR_BIT INTF6 +#define PIR_CHECK_IRQ() (EIFR & PIR_BIT) ? 0 : 1 + +#define PRINTF(...) printf(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +ISR(INT6_vect) +{ + +// leds_toggle(LEDS_YELLOW); + + if(PIR_CHECK_IRQ()) { + if(timer_expired(&debouncetimer)) { + // led1_on(); + timer_set(&debouncetimer, CLOCK_SECOND / 4); + sensors_changed(&pir_sensor); + // led1_off(); + } + } + +} +/*---------------------------------------------------------------------------*/ + +static int +value(int type) +{ + return (PORTE & _BV(PE6) ? 0 : 1) || !timer_expired(&debouncetimer); + //return 0; +} + +static int +configure(int type, int c) +{ + switch (type) { + case SENSORS_ACTIVE: + if (c) { + if(!status(SENSORS_ACTIVE)) { + // led1_on(); + timer_set(&debouncetimer, 0); + DDRE |= (0< +*/ + +#ifndef __PIR_SENSOR_H__ +#define __PIR_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor pir_sensor; + +#define PIR_SENSOR "PIR" + +#endif /* __PIR_SENSOR_H__ */ \ No newline at end of file diff --git a/platform/RaspBee/dev/relay-sensor.c b/platform/RaspBee/dev/relay-sensor.c new file mode 100644 index 000000000..6415926c9 --- /dev/null +++ b/platform/RaspBee/dev/relay-sensor.c @@ -0,0 +1,109 @@ +/* +* Copyright (c) , Harald Pichler. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. 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. +* 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. +* +* @(#)$Id: relay-sensor.c,v 1.0 2013/11/22 19:34:06 nifi Exp $ +*/ + +/** +* \file +* relay sensor header file for Atmega128rfa1. +* \author +* Harald Pichler +*/ + +#include "contiki.h" +#include "dev/relay.h" +#include "dev/relay-sensor.h" + +#define PRINTF(...) printf(__VA_ARGS__) + +const struct sensors_sensor relay_sensor; +static int status(int type); +static int enabled = 0; +static int relay[8]={0,0,0,0,0,0,0,0}; +static int relaypin[8]={RELAY_PIN_1,RELAY_PIN_2,RELAY_PIN_3,RELAY_PIN_4,RELAY_PIN_5,RELAY_PIN_6,RELAY_PIN_7,RELAY_PIN_8}; +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return relay[type]; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + switch(type) { + case SENSORS_ACTIVE: + if(c) { + if(!status(SENSORS_ACTIVE)) { + relay_init(relaypin[RELAY_SENSOR_1]); + relay_init(relaypin[RELAY_SENSOR_2]); + relay_init(relaypin[RELAY_SENSOR_3]); + relay_init(relaypin[RELAY_SENSOR_4]); + relay_init(relaypin[RELAY_SENSOR_5]); + relay_init(relaypin[RELAY_SENSOR_6]); + relay_init(relaypin[RELAY_SENSOR_7]); + relay_init(relaypin[RELAY_SENSOR_8]); + enabled = 1; + } + } else { + enabled = 1; + } + break; + case RELAY_SENSOR_1: + case RELAY_SENSOR_2: + case RELAY_SENSOR_3: + case RELAY_SENSOR_4: + case RELAY_SENSOR_5: + case RELAY_SENSOR_6: + case RELAY_SENSOR_7: + case RELAY_SENSOR_8: + if(c==0){ + relay_off(relaypin[type]); + relay[type]=0; + }else{ + relay_on(relaypin[type]); + relay[type]=1; + }; + break; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(relay_sensor, RELAY_SENSOR, value, configure, status); diff --git a/platform/RaspBee/dev/relay-sensor.h b/platform/RaspBee/dev/relay-sensor.h new file mode 100644 index 000000000..88b9dd0f5 --- /dev/null +++ b/platform/RaspBee/dev/relay-sensor.h @@ -0,0 +1,66 @@ +/* +* Copyright (c), Harald Pichler. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. 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. +* 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. +* +* @(#)$Id: relay-sensor.h,v 1.0 2013/11/22 19:34:06 nifi Exp $ +*/ + +/** +* \file +* Relay sensor header file for Atmega128rfa1. +* \author +* Harald Pichler +*/ + +#ifndef __RELAY_SENSOR_H__ +#define __RELAY_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor relay_sensor; + +#define RELAY_SENSOR "RELAY" +#define RELAY_SENSOR_1 0 +#define RELAY_SENSOR_2 1 +#define RELAY_SENSOR_3 2 +#define RELAY_SENSOR_4 3 +#define RELAY_SENSOR_5 4 +#define RELAY_SENSOR_6 5 +#define RELAY_SENSOR_7 6 +#define RELAY_SENSOR_8 7 + +/* default pins Arduino-Merkurboard */ +#define RELAY_PIN_1 10 +#define RELAY_PIN_2 11 +#define RELAY_PIN_3 12 +#define RELAY_PIN_4 13 +#define RELAY_PIN_5 15 +#define RELAY_PIN_6 16 +#define RELAY_PIN_7 17 +#define RELAY_PIN_8 18 + +#endif /* __RELAY_SENSOR_H__ */ diff --git a/platform/RaspBee/dev/relay.c b/platform/RaspBee/dev/relay.c new file mode 100644 index 000000000..67d9c7f5b --- /dev/null +++ b/platform/RaspBee/dev/relay.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2012 harald pichler + * All rights reserved. + * + * 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 + * 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 OWNER 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. + */ +/** + * \file + * + * \brief + * This file provides Raven LED support. + * + * \author + * Harald Pichler harald@the-develop.net + * + */ +#include "Arduino.h" +#include "relay.h" + +/** + * \addtogroup relay + * \{ +*/ +/*---------------------------------------------------------------------------*/ +/** + * \brief init RELAY PINS. +*/ +void +relay_init(uint8_t pin) +{ + pinMode(pin, OUTPUT); + digitalWrite(pin, LOW); +} +/** + * \brief Turns the RELAY on. +*/ + +void +relay_on(uint8_t pin) +{ + digitalWrite(pin, HIGH); +} + +/*---------------------------------------------------------------------------*/ + +/** + * \brief Turns the RELAY off +*/ +void +relay_off(uint8_t pin) +{ + digitalWrite(pin, LOW); +} diff --git a/platform/RaspBee/dev/relay.h b/platform/RaspBee/dev/relay.h new file mode 100644 index 000000000..3b9b48759 --- /dev/null +++ b/platform/RaspBee/dev/relay.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2012 Harald Pichler + * All rights reserved. + * + * 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 + * 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 OWNER 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. + */ +/** + * \file + * + * \brief + * This file provides Raven LED support. + * + * \author + * Harald Pichler harald@the-develop.net + * + */ + +#ifndef __RELAY_H__ +#define __RELAY_H__ + +#include + +/** @name RELAY Functions */ +/** @{ */ +void relay_init(uint8_t pin); +void relay_on(uint8_t pin); +void relay_off(uint8_t pin); + +/** @} */ + +#endif /* __RELAY_H__ */ diff --git a/platform/RaspBee/dev/servo-sensor.c b/platform/RaspBee/dev/servo-sensor.c new file mode 100644 index 000000000..9da3caf80 --- /dev/null +++ b/platform/RaspBee/dev/servo-sensor.c @@ -0,0 +1,100 @@ +/* +* Copyright (c) , Harald Pichler. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. 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. +* 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. +* +* @(#)$Id: servo-sensor.c,v 1.0 2013/02/20 19:34:06 nifi Exp $ +*/ + +/** +* \file +* Servo sensor header file for Atmega128rfa1. +* \author +* Harald Pichler +*/ + +#include "contiki.h" +#include "dev/servo.h" +#include "dev/servo-sensor.h" + +#define PRINTF(...) printf(__VA_ARGS__) + +const struct sensors_sensor servo_sensor; +static int status(int type); +static int enabled = 0; + +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + switch(type) { + case SERVO_SENSOR_A: + return servo_get(0);; + + /* Total Solar Radiation. */ + case SERVO_SENSOR_B: + return servo_get(1); + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + switch(type) { + case SENSORS_ACTIVE: + if(c) { + if(!status(SENSORS_ACTIVE)) { + servo_init(); + enabled = 1; + } + } else { + servo_off(); + enabled = 1; + } + break; + case SERVO_SENSOR_A: + servo_set(0,c); + break; + case SERVO_SENSOR_B: + servo_set(1,c); + break; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(servo_sensor, SERVO_SENSOR, value, configure, status); diff --git a/platform/RaspBee/dev/servo-sensor.h b/platform/RaspBee/dev/servo-sensor.h new file mode 100644 index 000000000..44e50c0f8 --- /dev/null +++ b/platform/RaspBee/dev/servo-sensor.h @@ -0,0 +1,50 @@ +/* +* Copyright (c), Harald Pichler. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. 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. +* 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. +* +* @(#)$Id: servo-sensor.h,v 1.0 2013/02/20 19:34:06 nifi Exp $ +*/ + +/** +* \file +* Servo sensor header file for Atmega128rfa1. +* \author +* Harald Pichler +*/ + +#ifndef __SERVO_SENSOR_H__ +#define __SERVO_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor servo_sensor; + +#define SERVO_SENSOR "Servo" +#define SERVO_SENSOR_A 0 +#define SERVO_SENSOR_B 1 + +#endif /* __SERVO_SENSOR_H__ */ diff --git a/platform/RaspBee/dev/servo.c b/platform/RaspBee/dev/servo.c new file mode 100644 index 000000000..874e98b89 --- /dev/null +++ b/platform/RaspBee/dev/servo.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/* + * Device driver for the Sensirion SHT1x/SHT7x family of humidity and + * temperature sensors. + */ + +#include "contiki.h" +#include +#include + +#define DEBUG 0 + +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/* + * servo device + */ + +unsigned int servoa=SERVO_INIT; +unsigned int servob=SERVO_INIT; + +void +servo_init(void) +{ + // Port E initialization + // Set Pin 3 and 4 to output mode for OCR1A and OCR2A + DDRE |= 1<<3 | 1<<4; + + // Timer/Counter 3 initialization + // Clock source: System Clock + // Clock value: 2000.000 kHz + // Mode: Ph. & fr. cor. PWM top=ICR1 + // OC3A output: Connected + // OC3B output: Connected + // OC3C output: Connected + // Noise Canceler: Off + // Input Capture on Falling Edge + // Timer3 Overflow Interrupt: Off + // Input Capture Interrupt: Off + // Compare A Match Interrupt: Off + // Compare B Match Interrupt: Off + // Compare C Match Interrupt: Off + + /* TCCR3A = [COM3A1|COM3A0|COM3B1|COM3B0||FOC3A|FOC3B|WGM31|WGM30] */ + /* 1 0 1 0 1 0 0 0 */ + TCCR3A=0xA8; + /* TCCR3B = [ ICNC3| ICES3| -| WGM33||WGM32| CS32| CS31| CS30] */ + /* 0 0 0 1 0 0 1 0 */ + TCCR3B=0x12; + TCNT3H=0x00; + TCNT3L=0x00; + // ICR3 has a computed value of 20,000 - see the chip manual for how this + // value was derived. + // 20000 == 0x4e20 so that's what goes into the high and low byte of the ICR3 register + // alternatively, Codevision would let you just do ICR3 = 20000; + ICR3H=0x4E; + ICR3L=0x20; + + // OCR3A will govern the steering servo, OCR3B will govern throttle + OCR3A = servoa; // set it to an initial position somewhere in the middle of the 1 to 2ms range + + // OCR3A will govern the steering servo, OCR3B will govern throttle + OCR3B = servob; // set it to an initial position somewhere in the middle of the 1 to 2ms range + // start with motor off - no duty cycle at all + OCR3CH=0x00; + OCR3CL=0x00; +} +/*---------------------------------------------------------------------------*/ +/* + * Power of device. + */ +void +servo_off(void) +{ + +} +/*---------------------------------------------------------------------------*/ +/* + * get servo position + */ +unsigned int +servo_get(unsigned int i) +{ + if(i==0) + return servoa; + if(i==1) + return servob; + return 0; +} +/*---------------------------------------------------------------------------*/ +/* + * Set servo position + */ +unsigned int +servo_set(unsigned i,unsigned int j) +{ + if(j > SERVO_MAX) + j=SERVO_MAX; + if(j < SERVO_MIN) + j=SERVO_MIN; + + if(i==0) + { + servoa=j; + OCR3A = servoa; + return 1; + } + if(i==1) + { + servob=j; + OCR3B = servob; + return 1; + } + + return 0; +} diff --git a/platform/RaspBee/dev/servo.h b/platform/RaspBee/dev/servo.h new file mode 100644 index 000000000..c6ae4ab57 --- /dev/null +++ b/platform/RaspBee/dev/servo.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +#ifndef SERVO_H +#define SERVO_H + +#define SERVO_MIN 575 +#define SERVO_MAX 2425 +#define SERVO_INIT 1500 + +void servo_init(void); +void servo_off(void); + +unsigned int servo_get(unsigned int i); +unsigned int servo_set(unsigned i,unsigned int j); + +#endif /* SHT11_H */ diff --git a/platform/RaspBee/dev/sg-ready.c b/platform/RaspBee/dev/sg-ready.c new file mode 100644 index 000000000..0f34d94b7 --- /dev/null +++ b/platform/RaspBee/dev/sg-ready.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2015 Bernhard Trinnes + * All rights reserved. + * + * 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 + * 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 OWNER 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. + */ +/** + * \file + * + * \brief + * Smart Grid Ready Module - guhRF + * + * \author + * Bernhard Trinnes bernhard.trinnes@guh.guru + * + */ + +#include "sg-ready.h" +#define LATCH_TIME 3000 // time in micro seconds + +#define RELAY1_ON (1< Pin high = Relay Open */ + if ((~PIND & RELAY1_FB) && (~PIND & RELAY2_FB)){ + state = 4; + }else if (~PIND & RELAY1_FB){ + state = 1; + } else if (~PIND & RELAY2_FB){ + state = 3; + } else { + state = 2; + } + return state; +} +/** + * \brief +*/ + +void +switch_difference(uint8_t old, uint8_t new) +{ + switch(old) { + case 1: + switch(new) { + case 2: + PORTB |= RELAY1_OFF; + PORTB &= ~(RELAY1_ON | RELAY2_ON | RELAY2_OFF); + clock_delay_usec (LATCH_TIME); + PORTB &= ~(RELAY1_OFF); + break; + case 3: + PORTB |= (RELAY1_OFF | RELAY2_ON ); + PORTB &= ~(RELAY1_ON | RELAY2_OFF); + clock_delay_usec (LATCH_TIME); + PORTB &= ~(RELAY1_OFF | RELAY2_ON); + break; + case 4: + PORTB |= RELAY2_ON; + PORTB &= ~(RELAY1_ON | RELAY1_OFF | RELAY2_OFF); + clock_delay_usec (LATCH_TIME); + PORTB &= ~(RELAY2_ON); + break; + } + break; + case 2: + switch(new) { + case 1: + PORTB |= RELAY1_ON; + PORTB &= ~(RELAY1_OFF | RELAY2_ON | RELAY2_OFF); + clock_delay_usec (LATCH_TIME); + PORTB &= ~(RELAY1_ON); + break; + case 3: + PORTB |= (RELAY2_ON); + PORTB &= ~(RELAY1_ON | RELAY1_OFF | RELAY2_OFF); + clock_delay_usec (LATCH_TIME); + PORTB &= ~(RELAY2_ON); + break; + case 4: + PORTB |= (RELAY1_ON | RELAY2_ON); + PORTB &= ~(RELAY1_OFF | RELAY2_OFF); + clock_delay_usec (LATCH_TIME); + PORTB &= ~(RELAY1_ON | RELAY2_ON); + break; + } + + break; + case 3: + switch(new) { + case 1: + PORTB |= (RELAY1_ON | RELAY2_OFF); + PORTB &= ~(RELAY1_OFF | RELAY2_ON); + clock_delay_usec (LATCH_TIME); + PORTB &= ~(RELAY1_ON | RELAY2_OFF); + break; + case 2: + PORTB |= RELAY2_OFF; + PORTB &= ~(RELAY1_ON | RELAY1_OFF | RELAY2_ON); + clock_delay_usec (LATCH_TIME); + PORTB &= ~(RELAY2_OFF); + break; + case 4: + PORTB |= RELAY1_ON; + PORTB &= ~(RELAY1_OFF | RELAY2_ON | RELAY2_OFF); + clock_delay_usec (LATCH_TIME); + PORTB &= ~(RELAY1_ON); + break; + } + break; + case 4: + switch(new) { + case 1: + PORTB |= RELAY2_OFF; + PORTB &= ~(RELAY1_ON | RELAY1_OFF | RELAY2_ON); + clock_delay_usec (LATCH_TIME); + PORTB &= ~(RELAY2_OFF); + break; + case 2: + PORTB |= (RELAY1_OFF | RELAY2_OFF); + PORTB &= ~(RELAY1_ON | RELAY2_ON ); + clock_delay_usec (LATCH_TIME); + PORTB &= ~(RELAY1_OFF | RELAY2_OFF); + break; + case 3: + PORTB |= RELAY1_OFF; + PORTB &= ~(RELAY1_ON | RELAY2_ON | RELAY2_OFF); + clock_delay_usec (LATCH_TIME); + PORTB &= ~(RELAY1_OFF); + break; + } + break; + } +} + diff --git a/platform/RaspBee/dev/sg-ready.h b/platform/RaspBee/dev/sg-ready.h new file mode 100644 index 000000000..81ba3f0c9 --- /dev/null +++ b/platform/RaspBee/dev/sg-ready.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2015 Bernhard Trinnes + * All rights reserved. + * + * 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 + * 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 OWNER 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. + */ +/** + * \file + * + * \brief + * + * + * \author + * Bernhard Trinnes bernhard.trinnes@guh.guru + * + */ + +#ifndef __SGREADY_H__ +#define __SGREADY_H__ + +#include + +/** @name Smart Grid Ready Functions */ +/** @{ */ +void relay_init(uint8_t pin); +void set_state(uint8_t pin); +uint8_t get_state(); +void switch_difference(uint8_t old, uint8_t new); + +/** @} */ + +#endif /* __SGREADY_H__ */ diff --git a/platform/RaspBee/dev/t4-servo-sensor.c b/platform/RaspBee/dev/t4-servo-sensor.c new file mode 100644 index 000000000..a35b2de02 --- /dev/null +++ b/platform/RaspBee/dev/t4-servo-sensor.c @@ -0,0 +1,101 @@ +/* +** Copyright (C) 2013-2014 Marcus Priesch, All rights reserved +** In Prandnern 31, A--2122 Riedenthal, Austria. office@priesch.co.at +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. 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. +** 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. +** +**++ +** Name +** t4-servo-sensor +** +** Purpose +** Implements a sensor around t4servo.c +** +** +** Revision Dates +** 31-Mar-2013 (MPR) Creation +** 12-Mar-2014 (MPR) Factored to support configurable amount of pwm's +** revision-date +**-- +*/ + +#include "contiki.h" +#include "dev/t4-servo.h" +#include "dev/t4-servo-sensor.h" + +const struct sensors_sensor t4_servo_sensor; + +static int status(int type); +static int enabled = 0; + +static int value (int channel) + { + if (channel >= SERVO_COUNT) + return -1; + else if (channel < 0) + return -2; + else + return t4_servo_get (channel); + } + +static int configure (int type, int c) // type, c: SENSORS_ACTIVE, 1 -> act. + // type, c: SENSORS_ACTIVE, 0 -> deact. + { + switch (type) + { + case SENSORS_ACTIVE : + if (c == 0) + { + t4_servo_off (); + } + else if (c == 1) + { + t4_servo_init (); + } + break; + + default : + if (type >= SERVO_COUNT) + return -1; + else + t4_servo_set (type, c); + break; + + } + return 0; + } + +static int status(int type) + { + switch (type) + { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; + } + +SENSORS_SENSOR(t4_servo_sensor, T4_SENSOR_NAME, value, configure, status); diff --git a/platform/RaspBee/dev/t4-servo-sensor.h b/platform/RaspBee/dev/t4-servo-sensor.h new file mode 100644 index 000000000..099bb4c66 --- /dev/null +++ b/platform/RaspBee/dev/t4-servo-sensor.h @@ -0,0 +1,52 @@ +/* +** Copyright (C) 2013-2014 Marcus Priesch, All rights reserved +** In Prandnern 31, A--2122 Riedenthal, Austria. office@priesch.co.at +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. 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. +** 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. +** +**++ +** Name +** t4-servo-sensor +** +** Purpose +** Implements a sensor around t4servo.c +** +** +** Revision Dates +** 31-Mar-2013 (MPR) Creation +** 12-Mar-2014 (MPR) Factored to support configurable amount of pwm's + revision-date +**-- +*/ + +#ifndef __T4_SERVO_SENSOR_H__ +#define __T4_SERVO_SENSOR_H__ + +#include "lib/sensors.h" +#include "t4-servo-config.h" + +extern const struct sensors_sensor t4_servo_sensor; + +#endif /* __T4_SERVO_SENSOR_H__ */ diff --git a/platform/RaspBee/dev/t4-servo.c b/platform/RaspBee/dev/t4-servo.c new file mode 100644 index 000000000..45f74ad9b --- /dev/null +++ b/platform/RaspBee/dev/t4-servo.c @@ -0,0 +1,139 @@ +/* +** Copyright (C) 2013-2014 Marcus Priesch, All rights reserved +** In Prandnern 31, A--2122 Riedenthal, Austria. office@priesch.co.at +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. 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. +** 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. +** +**++ +** Name +** t4-servo +** +** Purpose +** Implements software pwm on any portpins via timer 4 +** +** +** Revision Dates +** 31-Mar-2013 (MPR) Creation +** 12-Mar-2014 (MPR) Factored to support configurable amount of pwm's +** ««revision-date»»··· +**-- +*/ + +#include "t4-servo.h" +#include "t4-servo-config.h" +#include "t4-servo-hardware.h" +#include +#include + +// static servo_channel_type servo_channels [SERVO_COUNT]; + +// timer 4: CTC OCR4A +#define WGM4 0x4 + +void t4_servo_init (void) +{ + unsigned char channel; + + for (channel = 0; channel < SERVO_COUNT; channel ++) + { + _SFR_IO8 (servo_channels [channel].ddr ) |= servo_channels [channel].pin; + _SFR_IO8 (servo_channels [channel].port) &= ~(servo_channels [channel].pin); + } + + cli (); + TCCR4A = 0x00; + TCCR4A_struct.wgm4 = WGM4 & 0x3; + TCCR4B_struct.wgm4 = (WGM4 & 0xc) >> 2; + TCCR4B_struct.cs4 = 0x1; // No prescaler + TCCR4C = 0x00; + OCR4A = (T4_VALUE); + TIMSK4_struct.ocie4a = 1; + TIMSK4_struct.toie4 = 1; + sei(); +} + +void t4_servo_off (void) + { + TIMSK4_struct.toie4 = 0; + TIMSK4_struct.ocie4a = 0; + } + +int t4_servo_get (unsigned int channel) + { + if (channel >= SERVO_COUNT) + return -1; + //printf ("t4_servo_get: %d, %d\n", channel, servo_channels [channel].duty); + return servo_channels [channel].duty; + } + +int t4_servo_set (unsigned int channel, unsigned char duty) + { + //printf ("t4_servo_set: %d, %d\n", channel, duty); + + if (channel >= SERVO_COUNT) + return -1; + + if (duty > SERVO_MAX) + return -2; + + if (duty < SERVO_MIN) + return -3; + + servo_channels [channel].duty = duty; + return 0; + } + +ISR (TIMER4_COMPA_vect, ISR_NOBLOCK) + { + unsigned char channel; + static unsigned int tick_count = 0; + + cli (); + for (channel = 0; channel < SERVO_COUNT; channel ++) + { + if (tick_count < servo_channels [channel].duty) + { + // turn on +// _SFR_IO8 (servo_channels [channel].ddr ) |= servo_channels [channel].pin; + _SFR_IO8 (servo_channels [channel].port) |= servo_channels [channel].pin; + } + else + { + // turn off + _SFR_IO8 (servo_channels [channel].port) &= ~(servo_channels [channel].pin); +// _SFR_IO8 (servo_channels [channel].ddr ) |= servo_channels [channel].pin; + } + } + + tick_count ++; + + if (tick_count >= (SERVO_MAX + SERVO_OFFSET)) + { + tick_count = 0; + } + sei(); + + } + diff --git a/platform/RaspBee/dev/t4-servo.h b/platform/RaspBee/dev/t4-servo.h new file mode 100644 index 000000000..5acdc4013 --- /dev/null +++ b/platform/RaspBee/dev/t4-servo.h @@ -0,0 +1,61 @@ +/* +** Copyright (C) 2013-2014 Marcus Priesch, All rights reserved +** In Prandnern 31, A--2122 Riedenthal, Austria. office@priesch.co.at +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. 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. +** 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. +** +**++ +** Name +** t4-servo +** +** Purpose +** Implements software pwm on any portpins via timer 4 +** +** +** Revision Dates +** 31-Mar-2013 (MPR) Creation +** 12-Mar-2014 (MPR) Factored to support configurable amount of pwm's + ««revision-date»»··· +**-- +*/ + +#ifndef __T4_SERVO_H__ +#define __T4_SERVO_H__ + +typedef struct struct_servo_channel +{ + unsigned char port; + unsigned char ddr; + unsigned char pin; + unsigned char duty; +} servo_channel_type; + +void t4_servo_init(void); +void t4_servo_off(void); + +int t4_servo_get(unsigned int channel); +int t4_servo_set(unsigned int channel, unsigned char duty); + +#endif /* __T4_SERVO_H__ */ diff --git a/platform/RaspBee/dev/temperature-sensor.c b/platform/RaspBee/dev/temperature-sensor.c new file mode 100644 index 000000000..c85896178 --- /dev/null +++ b/platform/RaspBee/dev/temperature-sensor.c @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2012, BinaryLabs. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. 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. +* 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. +* +* @(#)$Id: temperature-sensor.c,v 1.1 2010/08/25 19:34:06 nifi Exp $ +*/ + +/** +* \file +* Temperature sensor header file for Atmega128rfa1. +* \author +* Paulo Louro +*/ + +#include "contiki.h" +#include "dev/temperature-sensor.h" + +#define PRINTF(...) printf(__VA_ARGS__) + + +const struct sensors_sensor temperature_sensor; + +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return readInternalTemp(); +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(temperature_sensor, TEMPERATURE_SENSOR, value, configure, status); \ No newline at end of file diff --git a/platform/RaspBee/dev/temperature-sensor.h b/platform/RaspBee/dev/temperature-sensor.h new file mode 100644 index 000000000..6cf5dbf26 --- /dev/null +++ b/platform/RaspBee/dev/temperature-sensor.h @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2012, BinaryLabs. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. 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. +* 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. +* +* @(#)$Id: temperature-sensor.h,v 1.1 2012/08/25 19:34:06 nifi Exp $ +*/ + +/** +* \file +* Temperature sensor header file for Atmega128rfa1. +* \author +* Paulo Louro +*/ + +#ifndef __TEMPERATURE_SENSOR_H__ +#define __TEMPERATURE_SENSOR_H__ + +#include "lib/sensors.h" +#include "dev/adc.h" + +extern const struct sensors_sensor temperature_sensor; + +#define TEMPERATURE_SENSOR "Temperature" + +#endif /* __TEMPERATURE_SENSOR_H__ */ \ No newline at end of file diff --git a/platform/RaspBee/dev/wiring_digital.c b/platform/RaspBee/dev/wiring_digital.c new file mode 100644 index 000000000..75b6745d6 --- /dev/null +++ b/platform/RaspBee/dev/wiring_digital.c @@ -0,0 +1,104 @@ +/* + wiring_digital.c - digital input and output functions + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + 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., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + Modified 28 September 2010 by Mark Sproul + + $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ +*/ + +#define ARDUINO_MAIN +#include "wiring_private.h" +#include "pins_arduino.h" + +void pinMode(uint8_t pin, uint8_t mode) +{ + uint8_t bit = digitalPinToBitMask(pin); + uint8_t port = digitalPinToPort(pin); + volatile uint8_t *reg, *out; + + if (port == NOT_A_PIN) return; + + // JWS: can I let the optimizer do this? + reg = portModeRegister(port); + out = portOutputRegister(port); + + if (mode == INPUT) { + uint8_t oldSREG = SREG; + cli(); + *reg &= ~bit; + *out &= ~bit; + SREG = oldSREG; + } else if (mode == INPUT_PULLUP) { + uint8_t oldSREG = SREG; + cli(); + *reg &= ~bit; + *out |= bit; + SREG = oldSREG; + } else { + uint8_t oldSREG = SREG; + cli(); + *reg |= bit; + SREG = oldSREG; + } +} + +void digitalWrite(uint8_t pin, uint8_t val) +{ + uint8_t timer = digitalPinToTimer(pin); + uint8_t bit = digitalPinToBitMask(pin); + uint8_t port = digitalPinToPort(pin); + volatile uint8_t *out; + + if (port == NOT_A_PIN) return; + + // If the pin that support PWM output, we need to turn it off + // before doing a digital write. + if (timer != NOT_ON_TIMER) turnOffPWM(timer); + + out = portOutputRegister(port); + + uint8_t oldSREG = SREG; + cli(); + + if (val == LOW) { + *out &= ~bit; + } else { + *out |= bit; + } + + SREG = oldSREG; +} + +int digitalRead(uint8_t pin) +{ + uint8_t timer = digitalPinToTimer(pin); + uint8_t bit = digitalPinToBitMask(pin); + uint8_t port = digitalPinToPort(pin); + + if (port == NOT_A_PIN) return LOW; + + // If the pin that support PWM output, we need to turn it off + // before getting a digital reading. + if (timer != NOT_ON_TIMER) turnOffPWM(timer); + + if (*portInputRegister(port) & bit) return HIGH; + return LOW; +} diff --git a/platform/RaspBee/dev/wiring_private.h b/platform/RaspBee/dev/wiring_private.h new file mode 100644 index 000000000..37c263352 --- /dev/null +++ b/platform/RaspBee/dev/wiring_private.h @@ -0,0 +1,69 @@ +/* + wiring_private.h - Internal header file. + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + 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., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.h 239 2007-01-12 17:58:39Z mellis $ +*/ + +#ifndef WiringPrivate_h +#define WiringPrivate_h + +#include +#include +#include +#include + +#include "Arduino.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#ifndef cbi +#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +#endif +#ifndef sbi +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#endif + +#define EXTERNAL_INT_0 0 +#define EXTERNAL_INT_1 1 +#define EXTERNAL_INT_2 2 +#define EXTERNAL_INT_3 3 +#define EXTERNAL_INT_4 4 +#define EXTERNAL_INT_5 5 +#define EXTERNAL_INT_6 6 +#define EXTERNAL_INT_7 7 + +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#define EXTERNAL_NUM_INTERRUPTS 8 +#elif defined(__AVR_ATmega128RFA1__) || (__AVR_ATmega256RFR2__) +#define EXTERNAL_NUM_INTERRUPTS 8 +#else +#define EXTERNAL_NUM_INTERRUPTS 2 +#endif + +typedef void (*voidFuncPtr)(void); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/platform/osd-merkur/node-id.c b/platform/RaspBee/node-id.c similarity index 100% rename from platform/osd-merkur/node-id.c rename to platform/RaspBee/node-id.c diff --git a/platform/osd-merkur/node-id.h b/platform/RaspBee/node-id.h similarity index 100% rename from platform/osd-merkur/node-id.h rename to platform/RaspBee/node-id.h diff --git a/platform/osd-merkur/params.c b/platform/RaspBee/params.c similarity index 100% rename from platform/osd-merkur/params.c rename to platform/RaspBee/params.c diff --git a/platform/osd-merkur/params.h b/platform/RaspBee/params.h similarity index 93% rename from platform/osd-merkur/params.h rename to platform/RaspBee/params.h index a8fa7637e..68c717dec 100644 --- a/platform/osd-merkur/params.h +++ b/platform/RaspBee/params.h @@ -17,16 +17,16 @@ // end default settings -#define CONTIKI_CONF_RANDOM_MAC 0 //adds 78 bytes +#define CONTIKI_CONF_RANDOM_MAC 1 //adds 78 bytes #define CONTIKI_CONF_SETTINGS_MANAGER 0 //adds 1696 bytes -#define BOOTLOADER_GET_MAC 1 // get mac form boolaoder, need bootlaoder bonsai, PARAMETER_STORAGE 0 +#define BOOTLOADER_GET_MAC 0 // get mac form boolaoder, need bootlaoder bonsai, PARAMETER_STORAGE 0 #if CONTIKI_CONF_SETTINGS_MANAGER //#define PARAMETER_STORAGE 2 #define PARAMETER_STORAGE 2 #else //#define PARAMETER_STORAGE 1 -#define PARAMETER_STORAGE 0 // get mac form boolaoder, need bootlaoder bonsai, PARAMETER_STORAGE 0 +#define PARAMETER_STORAGE 1 // get mac form boolaoder, need bootlaoder bonsai, PARAMETER_STORAGE 0 #endif /* Include settings.h, then dummy out the write routines */ @@ -46,7 +46,7 @@ extern uint8_t eemem_domain_name[30]; #ifdef SERVER_NAME #define PARAMS_SERVERNAME SERVER_NAME #else -#define PARAMS_SERVERNAME "ATMEGA128rfa1" +#define PARAMS_SERVERNAME "ATMEGA256rfr2" #endif #ifdef DOMAIN_NAME #define PARAMS_DOMAINNAME DOMAIN_NAME diff --git a/platform/osd-merkur/slip_uart0.c b/platform/RaspBee/slip_uart0.c similarity index 100% rename from platform/osd-merkur/slip_uart0.c rename to platform/RaspBee/slip_uart0.c diff --git a/platform/apple2enh/Makefile.apple2enh b/platform/apple2enh/Makefile.apple2enh index ca1d45970..01734c6ea 100644 --- a/platform/apple2enh/Makefile.apple2enh +++ b/platform/apple2enh/Makefile.apple2enh @@ -41,7 +41,7 @@ LC_SOURCEFILES = process.c tcpip.c ifeq ($(findstring WITH_REBOOT,$(DEFINES)),WITH_REBOOT) LDFLAGS += -D __LCADDR__=0xD000 -D __LCSIZE__=0x1000 - LC_SOURCEFILES += etimer.c + LC_SOURCEFILES += autostart.c timer.c uip_arch.c uiplib.c endif # Set a target-specific variable value @@ -55,14 +55,14 @@ endif disk: all cp $(CONTIKI)/tools/$(TARGET)/prodos.dsk contiki.dsk - java -jar $(AC) -p contiki.dsk contiki.system sys 0 < $(CC65_HOME)/targetutil/loader.system + java -jar $(AC) -p contiki.dsk contiki.system sys < $(CC65_TARGET_DIR)/util/loader.system java -jar $(AC) -cc65 contiki.dsk contiki bin < $(CONTIKI_PROJECT).$(TARGET) java -jar $(AC) -p contiki.dsk contiki.cfg bin 0 < $(CONTIKI)/tools/$(TARGET)/sample.cfg java -jar $(AC) -p contiki.dsk cs8900a.eth rel 0 < cs8900a.eth java -jar $(AC) -p contiki.dsk lan91c96.eth rel 0 < lan91c96.eth java -jar $(AC) -p contiki.dsk w5100.eth rel 0 < w5100.eth ifeq ($(findstring WITH_MOUSE,$(DEFINES)),WITH_MOUSE) - java -jar $(AC) -p contiki.dsk contiki.mou rel 0 < $(CC65_HOME)/mou/a2e.stdmou.mou + java -jar $(AC) -p contiki.dsk contiki.mou rel 0 < $(CC65_TARGET_DIR)/drv/mou/a2e.stdmou.mou endif ifeq ($(HTTPD-CFS),1) java -jar $(AC) -p contiki.dsk index.htm bin 0 < httpd-cfs/index.htm diff --git a/platform/apple2enh/contiki-conf.h b/platform/apple2enh/contiki-conf.h index 3f96da1aa..d3a684d3c 100644 --- a/platform/apple2enh/contiki-conf.h +++ b/platform/apple2enh/contiki-conf.h @@ -42,27 +42,31 @@ #define CTK_CONF_WIDGETUP_KEY 0x01 /* Ctrl-A */ #define CTK_CONF_WIDGETDOWN_KEY '\t' /* Tab or Ctrl-I */ +#if WITH_80COL #define MOUSE_CONF_XTOC(x) ((x) * 2 / 7) +#else +#define MOUSE_CONF_XTOC(x) ((x) / 7) +#endif #define MOUSE_CONF_YTOC(y) ((y) / 8) -#define EMAIL_CONF_WIDTH 79 -#define EMAIL_CONF_HEIGHT 19 -#define EMAIL_CONF_ERASE 0 - -#define FTP_CONF_WIDTH 38 -#define FTP_CONF_HEIGHT 21 - +#if WITH_80COL #define IRC_CONF_WIDTH 80 +#else +#define IRC_CONF_WIDTH 40 +#endif #define IRC_CONF_HEIGHT 23 -#define WWW_CONF_WEBPAGE_WIDTH 80 -#define WWW_CONF_WEBPAGE_HEIGHT 19 -#define WWW_CONF_HISTORY_SIZE 4 -#define WWW_CONF_MAX_URLLEN 78 -#define WWW_CONF_MAX_NUMPAGEWIDGETS 20 -#define WWW_CONF_FORMS 1 -#define WWW_CONF_MAX_FORMACTIONLEN 20 -#define WWW_CONF_MAX_INPUTNAMELEN 20 -#define WWW_CONF_MAX_INPUTVALUELEN 20 +#ifndef TELNETD_CONF_MAX_IDLE_TIME +#define TELNETD_CONF_MAX_IDLE_TIME 300 +#endif + +#if WITH_80COL +#define WWW_CONF_WEBPAGE_WIDTH 80 +#else +#define WWW_CONF_WEBPAGE_WIDTH 40 +#endif +#define WWW_CONF_WEBPAGE_HEIGHT 19 +#define WWW_CONF_HISTORY_SIZE 4 +#define WWW_CONF_WGET_EXEC(url) exec("wget", url) #endif /* CONTIKI_CONF_H_ */ diff --git a/platform/apple2enh/contiki-main.c b/platform/apple2enh/contiki-main.c index 2637da92e..f65a4fe94 100644 --- a/platform/apple2enh/contiki-main.c +++ b/platform/apple2enh/contiki-main.c @@ -83,7 +83,9 @@ main(void) rebootafterexit(); #endif /* WITH_REBOOT */ +#if WITH_80COL videomode(VIDEOMODE_80COL); +#endif /* WITH_80COL */ process_init(); @@ -104,7 +106,7 @@ main(void) uip_setdraddr(&addr); uip_ipaddr(&addr, 192,168,0,1); - resolv_conf(&addr); + uip_nameserver_update(&addr, UIP_NAMESERVER_INFINITE_LIFETIME); ethernet_config = &config; } @@ -112,7 +114,7 @@ main(void) procinit_init(); - process_start((struct process *)ðernet_process, (char *)ethernet_config); + process_start((struct process *)ðernet_process, (void *)ethernet_config); autostart_start(autostart_processes); diff --git a/platform/apple2enh/lib/error.c b/platform/apple2enh/lib/error.c index 2c5d5572e..b030d5877 100644 --- a/platform/apple2enh/lib/error.c +++ b/platform/apple2enh/lib/error.c @@ -42,8 +42,10 @@ void error_exit(void) { +#if LOG_CONF_ENABLED log_message("Press any key to continue ...", ""); ctk_arch_getkey(); +#endif /* LOG_CONF_ENABLED */ exit(EXIT_FAILURE); } /*-----------------------------------------------------------------------------------*/ diff --git a/platform/apple2enh/lib/pfs.S b/platform/apple2enh/lib/pfs.S index 00101d329..5c2ac488c 100644 --- a/platform/apple2enh/lib/pfs.S +++ b/platform/apple2enh/lib/pfs.S @@ -32,13 +32,14 @@ ; ;--------------------------------------------------------------------- .constructor init_pfs - .destructor done_pfs + .destructor done_pfs .importzp ptr1 - .import popax, _uip_aligned_buf - .export _pfs_open, _pfs_read, _pfs_close + .import popax, _uip_aligned_buf + .export _pfs_open, _pfs_read, _pfs_close ;--------------------------------------------------------------------- pathname := $0280 mli := $BF00 +level := $BF94 OPEN_CALL = $C8 READ_CALL = $CA @@ -65,11 +66,14 @@ read_count_out: .word $0000 ;TRANS_COUNT close_param: .byte $01 ;PARAM_COUNT close_fd: .byte $00 ;REF_NUM ;--------------------------------------------------------------------- - .segment "INIT" + .segment "ONCE" init_pfs: - ; Get prefix len of path used to load binary - ldx pathname + ; Allow exec() to keep file open + inc level + + ; Get prefix len of path used to load binary + ldx pathname : lda pathname,x cmp #'/' beq :+ @@ -80,6 +84,15 @@ init_pfs: ;--------------------------------------------------------------------- .code +done_pfs: + ; Close all file + lda #$00 + jsr _pfs_close + + ; Allow exec() to keep file open + dec level + rts + _pfs_open: ; Pop and store name jsr popax @@ -131,11 +144,8 @@ _pfs_read: ldx read_count_out+1 rts -done_pfs: - lda #$00 - _pfs_close: - ; Store fd + ; Store fd sta close_fd jsr mli @@ -147,6 +157,6 @@ _pfs_close: error: ; Return -1 lda #$FF - tax - rts + tax + rts ;--------------------------------------------------------------------- diff --git a/platform/apple2enh/sys/clock.c b/platform/apple2enh/sys/clock.c index e17cc922f..f8b33e9c1 100644 --- a/platform/apple2enh/sys/clock.c +++ b/platform/apple2enh/sys/clock.c @@ -63,7 +63,7 @@ clock_update(void) static unsigned int count; count += tick; - if(count > 2000) { + if(count > 1000) { count = 0; ++time; } diff --git a/platform/atarixl/Makefile.atarixl b/platform/atarixl/Makefile.atarixl index 8b0615c85..64ade5a13 100644 --- a/platform/atarixl/Makefile.atarixl +++ b/platform/atarixl/Makefile.atarixl @@ -34,8 +34,8 @@ CONTIKI_CPU = $(CONTIKI)/cpu/6502 include $(CONTIKI_CPU)/Makefile.6502 -SHADOW_RAM_SOURCEFILES = etimer.c uip.c -SHADOW_RAM2_SOURCEFILES = clock.c error.c uip_arch.c uip_arp.c +SHADOW_RAM_SOURCEFILES = ethernet.c ethernet-drv.c timer.c uip.c uiplib.c +SHADOW_RAM2_SOURCEFILES = clock.c uip_arch.c uip_arp.c # Set target-specific variable values ${addprefix $(OBJECTDIR)/,${call oname, $(SHADOW_RAM_SOURCEFILES)}}: CFLAGS += --code-name SHADOW_RAM @@ -55,7 +55,7 @@ disk: all cp $(CONTIKI)/tools/$(TARGET)/sample.cfg atr/contiki.cfg cp cs8900a.eth atr/cs8900a.eth ifeq ($(findstring WITH_MOUSE,$(DEFINES)),WITH_MOUSE) - cp $(CC65_HOME)/mou/atrxst.mou atr/contiki.mou + cp $(CC65_TARGET_DIR)/drv/mou/atrxst.mou atr/contiki.mou endif ifeq ($(HTTPD-CFS),1) cp httpd-cfs/index.htm atr/index.htm diff --git a/platform/atarixl/contiki-conf.h b/platform/atarixl/contiki-conf.h index 047e473ed..9adcdd93f 100644 --- a/platform/atarixl/contiki-conf.h +++ b/platform/atarixl/contiki-conf.h @@ -50,24 +50,15 @@ #define BORDERCOLOR COLOR_BLACK #define SCREENCOLOR COLOR_BLACK -#define EMAIL_CONF_WIDTH 39 -#define EMAIL_CONF_HEIGHT 19 -#define EMAIL_CONF_ERASE 0 - -#define FTP_CONF_WIDTH 18 -#define FTP_CONF_HEIGHT 21 - #define IRC_CONF_WIDTH 40 #define IRC_CONF_HEIGHT 23 -#define WWW_CONF_WEBPAGE_WIDTH 40 -#define WWW_CONF_WEBPAGE_HEIGHT 19 -#define WWW_CONF_HISTORY_SIZE 4 -#define WWW_CONF_MAX_URLLEN 80 -#define WWW_CONF_MAX_NUMPAGEWIDGETS 20 -#define WWW_CONF_FORMS 1 -#define WWW_CONF_MAX_FORMACTIONLEN 20 -#define WWW_CONF_MAX_INPUTNAMELEN 20 -#define WWW_CONF_MAX_INPUTVALUELEN 20 +#ifndef TELNETD_CONF_MAX_IDLE_TIME +#define TELNETD_CONF_MAX_IDLE_TIME 300 +#endif + +#define WWW_CONF_WEBPAGE_WIDTH 40 +#define WWW_CONF_WEBPAGE_HEIGHT 19 +#define WWW_CONF_HISTORY_SIZE 4 #endif /* CONTIKI_CONF_H_ */ diff --git a/platform/atarixl/contiki-main.c b/platform/atarixl/contiki-main.c index 268cd10ba..91cb35367 100644 --- a/platform/atarixl/contiki-main.c +++ b/platform/atarixl/contiki-main.c @@ -100,7 +100,7 @@ main(void) uip_setdraddr(&addr); uip_ipaddr(&addr, 192,168,0,1); - resolv_conf(&addr); + uip_nameserver_update(&addr, UIP_NAMESERVER_INFINITE_LIFETIME); ethernet_config = &config; } @@ -108,7 +108,7 @@ main(void) procinit_init(); - process_start((struct process *)ðernet_process, (char *)ethernet_config); + process_start((struct process *)ðernet_process, (void *)ethernet_config); autostart_start(autostart_processes); diff --git a/platform/atarixl/lib/error.c b/platform/atarixl/lib/error.c index 2c5d5572e..b030d5877 100644 --- a/platform/atarixl/lib/error.c +++ b/platform/atarixl/lib/error.c @@ -42,8 +42,10 @@ void error_exit(void) { +#if LOG_CONF_ENABLED log_message("Press any key to continue ...", ""); ctk_arch_getkey(); +#endif /* LOG_CONF_ENABLED */ exit(EXIT_FAILURE); } /*-----------------------------------------------------------------------------------*/ diff --git a/platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 b/platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 index b9a792c85..2fd8a9ac2 100644 --- a/platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 +++ b/platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 @@ -9,7 +9,7 @@ CONTIKI_TARGET_SOURCEFILES += button-sensor.c sensors.c slip_uart0.c slip.c CONTIKIAVR=$(CONTIKI)/cpu/avr CONTIKIBOARD=. -CONTIKI_PLAT_DEFS = -DF_CPU=8000000UL -DAUTO_CRC_PADDING=2 +CONTIKI_PLAT_DEFS = -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 MCU=atmega128rfa1 @@ -31,3 +31,4 @@ AVRDUDE_MCU=m128rfa1 include $(CONTIKIAVR)/Makefile.avr include $(CONTIKIAVR)/radio/Makefile.radio +MODULES += core/net/mac core/net core/net/mac/sicslowmac core/net/mac/contikimac core/net/llsec diff --git a/platform/avr-atmega128rfa1/apps/raven-ipso/raven-ipso.c b/platform/avr-atmega128rfa1/apps/raven-ipso/raven-ipso.c index 4e82eb959..04802951a 100644 --- a/platform/avr-atmega128rfa1/apps/raven-ipso/raven-ipso.c +++ b/platform/avr-atmega128rfa1/apps/raven-ipso/raven-ipso.c @@ -30,21 +30,19 @@ * */ +/** \addtogroup avr-atmega128rfa1 + * @{ + */ + /** + * \defgroup ravenserial Serial interface between Raven processors + * * \brief This module contains code to interface a Contiki-based * project on the AVR Raven platform's ATMega1284P chip to the LCD * driver chip (ATMega3290P) on the Raven. * * \author Durvy Mathilde * - */ - -/** \addtogroup raven - * @{ - */ - -/** - * \defgroup ravenserial Serial interface between Raven processors * @{ */ @@ -97,7 +95,7 @@ raven_ping6(void) /* ping ipv6.google.com*/ uip_ip6addr(&ping_addr,0x2001,0x420,0x5FFF,0x7D,0x2D0,0xB7FF,0xFE23,0xE6DB); //uip_ip6addr(&ping_addr, 0x2001, 0x4860, 0, 0x2001, 0, 0, 0, 0x68); - //uip_ip6addr(&ping_addr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1); + //uip_ip6addr(&ping_addr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 1); UIP_IP_BUF->vtc = 0x60; UIP_IP_BUF->tcflow = 1; diff --git a/platform/avr-atmega128rfa1/apps/raven-lcd-interface/raven-lcd.c b/platform/avr-atmega128rfa1/apps/raven-lcd-interface/raven-lcd.c index 26743f86b..7fb54d187 100644 --- a/platform/avr-atmega128rfa1/apps/raven-lcd-interface/raven-lcd.c +++ b/platform/avr-atmega128rfa1/apps/raven-lcd-interface/raven-lcd.c @@ -30,21 +30,19 @@ * */ -/** - * \brief This module contains code to interface a Contiki-based - * project on the AVR Raven platform's ATMega1284P chip to the LCD - * driver chip (ATMega3290P) on the Raven. - * - * \author Blake Leverett - * -*/ - /** \addtogroup raven * @{ */ /** * \defgroup ravenserial Serial interface between Raven processors + * + * \brief This module contains code to interface a Contiki-based + * project on the AVR Raven platform's ATMega1284P chip to the LCD + * driver chip (ATMega3290P) on the Raven. + * + * \author Blake Leverett + * * @{ */ /** diff --git a/platform/avr-atmega128rfa1/apps/raven-webserver/webserver-nogui.c b/platform/avr-atmega128rfa1/apps/raven-webserver/webserver-nogui.c index 557e08560..a92cd8449 100644 --- a/platform/avr-atmega128rfa1/apps/raven-webserver/webserver-nogui.c +++ b/platform/avr-atmega128rfa1/apps/raven-webserver/webserver-nogui.c @@ -68,7 +68,7 @@ webserver_log_file(uip_ipaddr_t *requester, char *file) { /* Print out IP address of requesting host. */ #if LOG_CONF_ENABLED -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 char buf[48]; uint8_t j; j=httpd_cgi_sprint_ip6((uip_ip6addr_t)*requester, buf); @@ -77,7 +77,7 @@ webserver_log_file(uip_ipaddr_t *requester, char *file) char buf[20]; sprintf(buf, "%d.%d.%d.%d: ", requester->u8[0], requester->u8[1], requester->u8[2], requester->u8[3]); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ log_message(buf, file); #endif /* LOG_CONF_ENABLED */ diff --git a/platform/avr-atmega128rfa1/contiki-conf.h b/platform/avr-atmega128rfa1/contiki-conf.h index e8324b1a4..dddc6c81d 100644 --- a/platform/avr-atmega128rfa1/contiki-conf.h +++ b/platform/avr-atmega128rfa1/contiki-conf.h @@ -45,7 +45,7 @@ #define PLATFORM_NAME "RFA1" #define PLATFORM_TYPE ATMEGA128RFA1 #ifndef F_CPU -#define F_CPU 8000000UL +#define F_CPU 16000000UL #endif #include @@ -56,18 +56,10 @@ */ /* Clock ticks per second */ #define CLOCK_CONF_SECOND 128 -#if 1 -/* 16 bit counter overflows every ~10 minutes */ -typedef unsigned short clock_time_t; -#define CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) -#define INFINITE_TIME 0xffff -#define RIME_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME INFINITE_TIME/CLOCK_CONF_SECOND /* Default uses 600 */ -#define COLLECT_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME INFINITE_TIME/CLOCK_CONF_SECOND /* Default uses 600 */ -#else -typedef unsigned long clock_time_t; -#define CLOCK_LT(a,b) ((signed long)((a)-(b)) < 0) -#define INFINITE_TIME 0xffffffff -#endif + +typedef uint32_t clock_time_t; +#define CLOCK_LT(a,b) ((int32_t)((a)-(b)) < 0) + /* These routines are not part of the contiki core but can be enabled in cpu/avr/clock.c */ void clock_delay_msec(uint16_t howlong); void clock_adjust_ticks(clock_time_t howmany); @@ -142,7 +134,7 @@ typedef unsigned short uip_stats_t; /* Allow MCU sleeping between channel checks */ #define RDC_CONF_MCU_SLEEP 1 -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #define LINKADDR_CONF_SIZE 8 #define UIP_CONF_ICMP6 1 #define UIP_CONF_UDP 1 @@ -159,10 +151,10 @@ typedef unsigned short uip_stats_t; #define UIP_CONF_LLH_LEN 0 /* 10 bytes per stateful address context - see sicslowpan.c */ -/* Default is 1 context with prefix aaaa::/64 */ +/* Default is 1 context with prefix fd00::/64 */ /* These must agree with all the other nodes or there will be a failure to communicate! */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 -#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 {addr_contexts[0].prefix[0]=0xaa;addr_contexts[0].prefix[1]=0xaa;} +#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 {addr_contexts[0].prefix[0]=UIP_DS6_DEFAULT_PREFIX_0;addr_contexts[0].prefix[1]=UIP_DS6_DEFAULT_PREFIX_1;} #define SICSLOWPAN_CONF_ADDR_CONTEXT_1 {addr_contexts[1].prefix[0]=0xbb;addr_contexts[1].prefix[1]=0xbb;} #define SICSLOWPAN_CONF_ADDR_CONTEXT_2 {addr_contexts[2].prefix[0]=0x20;addr_contexts[2].prefix[1]=0x01;addr_contexts[2].prefix[2]=0x49;addr_contexts[2].prefix[3]=0x78,addr_contexts[2].prefix[4]=0x1d;addr_contexts[2].prefix[5]=0xb1;} @@ -191,8 +183,6 @@ typedef unsigned short uip_stats_t; #define CHANNEL_802_15_4 26 /* AUTOACK receive mode gives better rssi measurements, even if ACK is never requested */ #define RF230_CONF_AUTOACK 1 -/* Request 802.15.4 ACK on all packets sent (else autoretry). This is primarily for testing. */ -#define SICSLOWPAN_CONF_ACK_ALL 0 /* 1 + Number of auto retry attempts 0-15 (0 implies don't use extended TX_ARET_ON mode) */ #define RF230_CONF_FRAME_RETRIES 2 /* Number of csma retry attempts 0-5 in extended tx mode (7 does immediate tx with no csma) */ @@ -237,15 +227,19 @@ typedef unsigned short uip_stats_t; #define NETSTACK_CONF_RDC contikimac_driver /* Default is two CCA separated by 500 usec */ #define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 -/* Wireshark won't decode with the header, but padded packets will fail ipv6 checksum */ -#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0 /* So without the header this needed for RPL mesh to form */ -#define CONTIKIMAC_CONF_SHORTEST_PACKET_SIZE 43-18 //multicast RPL DIS length +#define CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE 43-18 //multicast RPL DIS length /* Not tested much yet */ #define WITH_PHASE_OPTIMIZATION 0 #define CONTIKIMAC_CONF_COMPOWER 1 #define RIMESTATS_CONF_ENABLED 1 -#define NETSTACK_CONF_FRAMER framer_802154 + +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_FRAMER framer802154 +#else /* NETSTACK_CONF_WITH_IPV6 */ +#define NETSTACK_CONF_FRAMER contikimac_framer +#endif /* NETSTACK_CONF_WITH_IPV6 */ + #define NETSTACK_CONF_RADIO rf230_driver #define CHANNEL_802_15_4 26 /* The radio needs to interrupt during an rtimer interrupt */ diff --git a/platform/avr-atmega128rfa1/contiki-main.c b/platform/avr-atmega128rfa1/contiki-main.c index 5724dc7ca..ec22d58f6 100644 --- a/platform/avr-atmega128rfa1/contiki-main.c +++ b/platform/avr-atmega128rfa1/contiki-main.c @@ -264,7 +264,7 @@ uint8_t i; PRINTA("Random EUI64 address generated\n"); } -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(&uip_lladdr.addr, &addr.u8, sizeof(linkaddr_t)); #elif WITH_NODE_ID node_id=get_panaddr_from_eeprom(); @@ -278,7 +278,7 @@ uint8_t i; rf230_set_channel(params_get_channel()); rf230_set_txpower(params_get_txpower()); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 PRINTA("EUI-64 MAC: %x-%x-%x-%x-%x-%x-%x-%x\n",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]); #else PRINTA("MAC address "); @@ -308,7 +308,9 @@ uint8_t i; #endif /* ANNOUNCE_BOOT */ +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 process_start(&tcpip_process, NULL); +#endif #ifdef RAVEN_LCD_INTERFACE process_start(&raven_lcd_process, NULL); @@ -338,7 +340,7 @@ uint8_t i; #if 0 { uip_ip6addr_t ipaddr; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); // uip_ds6_prefix_add(&ipaddr,64,0); } @@ -391,7 +393,7 @@ uint8_t i; #endif } -#if ROUTES && UIP_CONF_IPV6 +#if ROUTES && NETSTACK_CONF_WITH_IPV6 static void ipaddr_add(const uip_ipaddr_t *addr) { @@ -419,9 +421,9 @@ ipaddr_add(const uip_ipaddr_t *addr) int main(void) { -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 uip_ds6_nbr_t *nbr; -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ initialize(); while(1) { @@ -506,7 +508,7 @@ extern volatile unsigned long radioontime; clocktime+=1; #endif -#if PINGS && UIP_CONF_IPV6 +#if PINGS && NETSTACK_CONF_WITH_IPV6 extern void raven_ping6(void); if ((clocktime%PINGS)==1) { PRINTF("**Ping\n"); @@ -514,7 +516,7 @@ if ((clocktime%PINGS)==1) { } #endif -#if ROUTES && UIP_CONF_IPV6 +#if ROUTES && NETSTACK_CONF_WITH_IPV6 if ((clocktime%ROUTES)==2) { extern uip_ds6_netif_t uip_ds6_if; diff --git a/platform/avr-raven/Makefile.avr-raven b/platform/avr-raven/Makefile.avr-raven index d13307c0b..cf3c276c3 100644 --- a/platform/avr-raven/Makefile.avr-raven +++ b/platform/avr-raven/Makefile.avr-raven @@ -35,4 +35,5 @@ AVRDUDE_MCU=m1284p include $(CONTIKIAVR)/Makefile.avr include $(CONTIKIAVR)/radio/Makefile.radio -MODULES += core/net/ipv6 core/net/ipv4 core/net/ip core/net/mac core/net core/net/rime core/net/mac/sicslowmac +MODULES += core/net/mac core/net core/net/mac/sicslowmac \ + core/net/llsec diff --git a/platform/avr-raven/apps/raven-ipso/raven-ipso.c b/platform/avr-raven/apps/raven-ipso/raven-ipso.c index 4e82eb959..5779e814b 100644 --- a/platform/avr-raven/apps/raven-ipso/raven-ipso.c +++ b/platform/avr-raven/apps/raven-ipso/raven-ipso.c @@ -30,21 +30,19 @@ * */ -/** - * \brief This module contains code to interface a Contiki-based - * project on the AVR Raven platform's ATMega1284P chip to the LCD - * driver chip (ATMega3290P) on the Raven. - * - * \author Durvy Mathilde - * - */ - /** \addtogroup raven * @{ */ /** * \defgroup ravenserial Serial interface between Raven processors + * + * \brief This module contains code to interface a Contiki-based + * project on the AVR Raven platform's ATMega1284P chip to the LCD + * driver chip (ATMega3290P) on the Raven. + * + * \author Durvy Mathilde + * * @{ */ @@ -97,7 +95,7 @@ raven_ping6(void) /* ping ipv6.google.com*/ uip_ip6addr(&ping_addr,0x2001,0x420,0x5FFF,0x7D,0x2D0,0xB7FF,0xFE23,0xE6DB); //uip_ip6addr(&ping_addr, 0x2001, 0x4860, 0, 0x2001, 0, 0, 0, 0x68); - //uip_ip6addr(&ping_addr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1); + //uip_ip6addr(&ping_addr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 1); UIP_IP_BUF->vtc = 0x60; UIP_IP_BUF->tcflow = 1; diff --git a/platform/avr-raven/apps/raven-lcd-interface/Makefile.raven-lcd-interface b/platform/avr-raven/apps/raven-lcd-interface/Makefile.raven-lcd-interface index 0b1196c5f..707f0a3fe 100644 --- a/platform/avr-raven/apps/raven-lcd-interface/Makefile.raven-lcd-interface +++ b/platform/avr-raven/apps/raven-lcd-interface/Makefile.raven-lcd-interface @@ -1,4 +1,4 @@ raven-lcd-interface_src = raven-lcd.c -CFLAGS+=-DRAVEN_LCD_INTERFACE=1 +CFLAGS+=-DRAVEN_LCD_INTERFACE=1 -DPLATFORM_HAS_BATTERY -DPLATFORM_HAS_TEMPERATURE diff --git a/platform/avr-raven/apps/raven-lcd-interface/raven-lcd.c b/platform/avr-raven/apps/raven-lcd-interface/raven-lcd.c index 8a165d5ee..acf6eef46 100644 --- a/platform/avr-raven/apps/raven-lcd-interface/raven-lcd.c +++ b/platform/avr-raven/apps/raven-lcd-interface/raven-lcd.c @@ -30,21 +30,20 @@ * */ -/** - * \brief This module contains code to interface a Contiki-based - * project on the AVR Raven platform's ATMega1284P chip to the LCD - * driver chip (ATMega3290P) on the Raven. - * - * \author Blake Leverett - * -*/ - /** \addtogroup raven * @{ */ /** * \defgroup ravenserial Serial interface between Raven processors + * + * \brief This module contains code to interface a Contiki-based + * project on the AVR Raven platform's ATMega1284P chip to the LCD + * driver chip (ATMega3290P) on the Raven. + * + * \author Blake Leverett + * \author Cristiano De Alti + * * @{ */ /** @@ -71,6 +70,7 @@ #endif #include "raven-lcd.h" +#include "lib/sensors.h" #include #include @@ -96,6 +96,9 @@ static struct{ #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) #define PING6_DATALEN 16 +static int battery_value; +static int temperature_value; + void rs232_send(uint8_t port, unsigned char c); /*---------------------------------------------------------------------------*/ @@ -308,12 +311,14 @@ raven_gui_loop(process_event_t ev, process_data_t data) /* Set temperature string in web server */ web_set_temp((char *)cmd.frame); #endif + temperature_value = atoi((char *)cmd.frame); break; case SEND_ADC2: #if AVR_WEBSERVER /* Set ext voltage string in web server */ web_set_voltage((char *)cmd.frame); #endif + battery_value = atoi((char *)cmd.frame); break; case SEND_SLEEP: /* Sleep radio and 1284p. */ @@ -460,6 +465,42 @@ char buf[sizeof(eemem_server_name)+1]; raven_lcd_show_text(buf); //must fit in all the buffers or it will be truncated! } #endif + +/*---------------------------------------------------------------------------*/ +int +value_temperature(int type) { + return temperature_value; +} + +int +value_battery(int type) { + return battery_value; +} + +/*---------------------------------------------------------------------------*/ +int +configure(int type, int value) { + /* prevent compiler warnings */ + return type = value = 1; +} + +/*---------------------------------------------------------------------------*/ +int +status(int type) { + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return 1; + } + return 0; +} + +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(temperature_sensor, "Temperature", + value_temperature, configure, status); +SENSORS_SENSOR(battery_sensor, "Battery", + value_battery, configure, status); + /*---------------------------------------------------------------------------*/ PROCESS(raven_lcd_process, "Raven LCD interface process"); PROCESS_THREAD(raven_lcd_process, ev, data) diff --git a/platform/avr-raven/apps/raven-webserver/httpd-cgi.c b/platform/avr-raven/apps/raven-webserver/httpd-cgi.c index f085991bf..874ad4246 100644 --- a/platform/avr-raven/apps/raven-webserver/httpd-cgi.c +++ b/platform/avr-raven/apps/raven-webserver/httpd-cgi.c @@ -368,7 +368,7 @@ make_routes(void *p) j++; numprinted += httpd_cgi_sprint_ip6(r->ipaddr, uip_appdata + numprinted); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, r->length); - numprinted += httpd_cgi_sprint_ip6(uip_ds6_route_nexthop(r), uip_appdata + numprinted); + numprinted += httpd_cgi_sprint_ip6(*uip_ds6_route_nexthop(r), uip_appdata + numprinted); if(r->state.lifetime < 3600) { numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, r->state.lifetime); } else { diff --git a/platform/avr-raven/apps/raven-webserver/webserver-nogui.c b/platform/avr-raven/apps/raven-webserver/webserver-nogui.c index 557e08560..a92cd8449 100644 --- a/platform/avr-raven/apps/raven-webserver/webserver-nogui.c +++ b/platform/avr-raven/apps/raven-webserver/webserver-nogui.c @@ -68,7 +68,7 @@ webserver_log_file(uip_ipaddr_t *requester, char *file) { /* Print out IP address of requesting host. */ #if LOG_CONF_ENABLED -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 char buf[48]; uint8_t j; j=httpd_cgi_sprint_ip6((uip_ip6addr_t)*requester, buf); @@ -77,7 +77,7 @@ webserver_log_file(uip_ipaddr_t *requester, char *file) char buf[20]; sprintf(buf, "%d.%d.%d.%d: ", requester->u8[0], requester->u8[1], requester->u8[2], requester->u8[3]); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ log_message(buf, file); #endif /* LOG_CONF_ENABLED */ diff --git a/platform/avr-raven/contiki-conf.h b/platform/avr-raven/contiki-conf.h index cff7988d7..45ea5fb22 100644 --- a/platform/avr-raven/contiki-conf.h +++ b/platform/avr-raven/contiki-conf.h @@ -68,18 +68,10 @@ */ /* Clock ticks per second */ #define CLOCK_CONF_SECOND 128 -#if 1 -/* 16 bit counter overflows every ~10 minutes */ -typedef unsigned short clock_time_t; -#define CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) -#define INFINITE_TIME 0xffff -#define RIME_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME INFINITE_TIME/CLOCK_CONF_SECOND /* Default uses 600 */ -#define COLLECT_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME INFINITE_TIME/CLOCK_CONF_SECOND /* Default uses 600 */ -#else -typedef unsigned long clock_time_t; -#define CLOCK_LT(a,b) ((signed long)((a)-(b)) < 0) -#define INFINITE_TIME 0xffffffff -#endif + +typedef uint32_t clock_time_t; +#define CLOCK_LT(a,b) ((int32_t)((a)-(b)) < 0) + /* These routines are not part of the contiki core but can be enabled in cpu/avr/clock.c */ void clock_delay_msec(uint16_t howlong); void clock_adjust_ticks(clock_time_t howmany); @@ -146,39 +138,36 @@ typedef unsigned short uip_stats_t; /* Network setup. The new NETSTACK interface requires RF230BB (as does ip4) */ #if RF230BB -#undef PACKETBUF_CONF_HDR_SIZE //Use the packetbuf default for header size /* TX routine passes the cca/ack result in the return parameter */ #define RDC_CONF_HARDWARE_ACK 1 /* TX routine does automatic cca and optional backoff */ #define RDC_CONF_HARDWARE_CSMA 1 /* Allow MCU sleeping between channel checks */ #define RDC_CONF_MCU_SLEEP 0 -#else -#define PACKETBUF_CONF_HDR_SIZE 0 //RF230 combined driver/mac handles headers internally #endif /*RF230BB */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #define LINKADDR_CONF_SIZE 8 #define UIP_CONF_ICMP6 1 #define UIP_CONF_UDP 1 #define UIP_CONF_TCP 1 -//#define UIP_CONF_IPV6_RPL 0 +#define UIP_CONF_BUFFER_SIZE 1300 #define NETSTACK_CONF_NETWORK sicslowpan_driver #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #else /* ip4 should build but is largely untested */ #define LINKADDR_CONF_SIZE 2 #define NETSTACK_CONF_NETWORK rime_driver -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_LL_802154 1 #define UIP_CONF_LLH_LEN 0 /* 10 bytes per stateful address context - see sicslowpan.c */ -/* Default is 1 context with prefix aaaa::/64 */ +/* Default is 1 context with prefix fd00::/64 */ /* These must agree with all the other nodes or there will be a failure to communicate! */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 -#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 {addr_contexts[0].prefix[0]=0xaa;addr_contexts[0].prefix[1]=0xaa;} +#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 {addr_contexts[0].prefix[0]=UIP_DS6_DEFAULT_PREFIX_0;addr_contexts[0].prefix[1]=UIP_DS6_DEFAULT_PREFIX_1;} #define SICSLOWPAN_CONF_ADDR_CONTEXT_1 {addr_contexts[1].prefix[0]=0xbb;addr_contexts[1].prefix[1]=0xbb;} #define SICSLOWPAN_CONF_ADDR_CONTEXT_2 {addr_contexts[2].prefix[0]=0x20;addr_contexts[2].prefix[1]=0x01;addr_contexts[2].prefix[2]=0x49;addr_contexts[2].prefix[3]=0x78,addr_contexts[2].prefix[4]=0x1d;addr_contexts[2].prefix[5]=0xb1;} @@ -207,8 +196,6 @@ typedef unsigned short uip_stats_t; #define RADIO_CONF_CALIBRATE_INTERVAL 256 /* AUTOACK receive mode gives better rssi measurements, even if ACK is never requested */ #define RF230_CONF_AUTOACK 1 -/* Request 802.15.4 ACK on all packets sent (else autoretry). This is primarily for testing. */ -#define SICSLOWPAN_CONF_ACK_ALL 0 /* Number of auto retry attempts+1, 1-16. Set zero to disable extended TX_ARET_ON mode with CCA) */ #define RF230_CONF_FRAME_RETRIES 3 /* Number of CSMA attempts 0-7. 802.15.4 2003 standard max is 5. */ @@ -253,15 +240,19 @@ typedef unsigned short uip_stats_t; #define NETSTACK_CONF_RDC contikimac_driver /* Default is two CCA separated by 500 usec */ #define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 -/* Wireshark won't decode with the header, but padded packets will fail ipv6 checksum */ -#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0 /* So without the header this needed for RPL mesh to form */ -#define CONTIKIMAC_CONF_SHORTEST_PACKET_SIZE 43-18 //multicast RPL DIS length +#define CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE 43-18 //multicast RPL DIS length /* Not tested much yet */ #define WITH_PHASE_OPTIMIZATION 0 #define CONTIKIMAC_CONF_COMPOWER 1 #define RIMESTATS_CONF_ENABLED 1 -#define NETSTACK_CONF_FRAMER framer_802154 + +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_FRAMER framer802154 +#else /* NETSTACK_CONF_WITH_IPV6 */ +#define NETSTACK_CONF_FRAMER contikimac_framer +#endif /* NETSTACK_CONF_WITH_IPV6 */ + #define NETSTACK_CONF_RADIO rf230_driver #define CHANNEL_802_15_4 26 /* The radio needs to interrupt during an rtimer interrupt */ diff --git a/platform/avr-raven/contiki-raven-default-init-net.c b/platform/avr-raven/contiki-raven-default-init-net.c index 61fc23213..ca29e34fb 100644 --- a/platform/avr-raven/contiki-raven-default-init-net.c +++ b/platform/avr-raven/contiki-raven-default-init-net.c @@ -44,7 +44,7 @@ init_net(void) /* uip_ipaddr_t ipprefix; - uip_ip6addr(&ipprefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipprefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_netif_addr_add(&ipprefix, UIP_DEFAULT_PREFIX_LEN, 0, AUTOCONF); uip_nd6_prefix_add(&ipprefix, UIP_DEFAULT_PREFIX_LEN, 0); diff --git a/platform/avr-raven/contiki-raven-main.c b/platform/avr-raven/contiki-raven-main.c index 37f37dd48..274bdf2ff 100644 --- a/platform/avr-raven/contiki-raven-main.c +++ b/platform/avr-raven/contiki-raven-main.c @@ -265,7 +265,7 @@ uint8_t i; PRINTA("Random EUI64 address generated\n"); } -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(&uip_lladdr.addr, &addr.u8, sizeof(linkaddr_t)); linkaddr_set_node_addr(&addr); rf230_set_pan_addr(params_get_panid(),params_get_panaddr(),(uint8_t *)&addr.u8); @@ -284,7 +284,7 @@ uint8_t i; rf230_set_channel(params_get_channel()); rf230_set_txpower(params_get_txpower()); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 PRINTA("EUI-64 MAC: %x-%x-%x-%x-%x-%x-%x-%x\n",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]); #else PRINTA("MAC address "); @@ -316,13 +316,17 @@ uint8_t i; // rime_init(rime_udp_init(NULL)); // uip_router_register(&rimeroute); +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 process_start(&tcpip_process, NULL); +#endif #else /* !RF230BB */ /* Original RF230 combined mac/radio driver */ /* mac process must be started before tcpip process! */ process_start(&mac_process, NULL); +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 process_start(&tcpip_process, NULL); +#endif #endif /* RF230BB */ #ifdef RAVEN_LCD_INTERFACE @@ -353,7 +357,7 @@ uint8_t i; #if 0 { uip_ip6addr_t ipaddr; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); // uip_ds6_prefix_add(&ipaddr,64,0); } @@ -401,7 +405,7 @@ uint8_t i; } } -#if ROUTES && UIP_CONF_IPV6 +#if ROUTES && NETSTACK_CONF_WITH_IPV6 static void ipaddr_add(const uip_ipaddr_t *addr) { @@ -429,9 +433,9 @@ ipaddr_add(const uip_ipaddr_t *addr) int main(void) { -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 uip_ds6_nbr_t *nbr; -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ initialize(); while(1) { @@ -502,7 +506,7 @@ extern volatile unsigned long radioontime; clocktime+=1; #endif -#if PINGS && UIP_CONF_IPV6 +#if PINGS && NETSTACK_CONF_WITH_IPV6 extern void raven_ping6(void); if ((clocktime%PINGS)==1) { PRINTF("**Ping\n"); @@ -510,7 +514,7 @@ if ((clocktime%PINGS)==1) { } #endif -#if ROUTES && UIP_CONF_IPV6 +#if ROUTES && NETSTACK_CONF_WITH_IPV6 if ((clocktime%ROUTES)==2) { extern uip_ds6_netif_t uip_ds6_if; @@ -523,6 +527,7 @@ extern uip_ds6_netif_t uip_ds6_if; PRINTF("\n"); } } + j = 1; PRINTF("\nNeighbors [%u max]\n",NBR_TABLE_MAX_NEIGHBORS); for(nbr = nbr_table_head(ds6_neighbors); nbr != NULL; diff --git a/platform/avr-raven/dev/temperature-sensor.h b/platform/avr-raven/dev/temperature-sensor.h new file mode 100644 index 000000000..05eafe852 --- /dev/null +++ b/platform/avr-raven/dev/temperature-sensor.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file + * Temperature sensor header file. + * \author + * Adam Dunkels + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef TEMPERATURE_SENSOR_H_ +#define TEMPERATURE_SENSOR_H_ + +#include "lib/sensors.h" + +extern const struct sensors_sensor temperature_sensor; + +#define TEMPERATURE_SENSOR "Temperature" + +#endif /* TEMPERATURE_SENSOR_H_ */ diff --git a/platform/avr-ravenlcd/Makefile b/platform/avr-ravenlcd/Makefile index e16132765..fef0167d9 100644 --- a/platform/avr-ravenlcd/Makefile +++ b/platform/avr-ravenlcd/Makefile @@ -28,7 +28,7 @@ LDFLAGS = $(COMMON) LDFLAGS += -Wl,-Map=$(PROJECT).map,--cref ## Intel Hex file production flags -HEX_FLASH_FLAGS = -R .eeprom +HEX_FLASH_FLAGS = -j .text -j .data HEX_EEPROM_FLAGS = -j .eeprom HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" diff --git a/platform/avr-ravenlcd/beep.c b/platform/avr-ravenlcd/beep.c index 34f2ee23f..cb2a0510b 100644 --- a/platform/avr-ravenlcd/beep.c +++ b/platform/avr-ravenlcd/beep.c @@ -132,11 +132,11 @@ beep(void) static uint8_t tuneindex=0; -static uint8_t pictures[] PROGMEM = {G4,4, F4,4, AS4,4, C5,2, F5,2, D5,4, C5,2, F5,2, D5,4, AS4,4, C5,4, G4,4, F4,4, 0xff}; -static uint8_t axel[] PROGMEM = {FS4,2, NONE,2, A4,3, FS4,2, FS4,1, B4,2, FS4,2, E4,2, FS4,2, NONE,2, CS5,3, FS4,2, FS4,1, D5,2, CS5,2, A4,2, FS4,2, CS5,2, FS5,2, FS4,1, E4,2, E4,1, CS4,2, GS4,2, FS4,6, 0xff}; -static uint8_t sandman1[] PROGMEM = {F4,2, G4,2, B4,4, A4,10, B4,2, B4,2, A4,2, B4,12, 0xff}; -static uint8_t sandman2[] PROGMEM = {C4,2, E4,2, G4,2, B4,2, A4,2, G4,2, E4,2, C4,2, D4,2, F4,2, A4,2, C5,2, B4,8, 0xff}; -static uint8_t furelise[] PROGMEM = {E5,1, DS5,1, E5,1, DS5,1, E5,1, B4,1, D5,1, E5,1, A4,2, NONE,1, C4,1, E4,1, A4,1, B4,2, NONE,1, E4,1, GS4,1, B4,1, C5,2, 0xff}; +static const uint8_t pictures[] PROGMEM = {G4,4, F4,4, AS4,4, C5,2, F5,2, D5,4, C5,2, F5,2, D5,4, AS4,4, C5,4, G4,4, F4,4, 0xff}; +static const uint8_t axel[] PROGMEM = {FS4,2, NONE,2, A4,3, FS4,2, FS4,1, B4,2, FS4,2, E4,2, FS4,2, NONE,2, CS5,3, FS4,2, FS4,1, D5,2, CS5,2, A4,2, FS4,2, CS5,2, FS5,2, FS4,1, E4,2, E4,1, CS4,2, GS4,2, FS4,6, 0xff}; +static const uint8_t sandman1[] PROGMEM = {F4,2, G4,2, B4,4, A4,10, B4,2, B4,2, A4,2, B4,12, 0xff}; +static const uint8_t sandman2[] PROGMEM = {C4,2, E4,2, G4,2, B4,2, A4,2, G4,2, E4,2, C4,2, D4,2, F4,2, A4,2, C5,2, B4,8, 0xff}; +static const uint8_t furelise[] PROGMEM = {E5,1, DS5,1, E5,1, DS5,1, E5,1, B4,1, D5,1, E5,1, A4,2, NONE,1, C4,1, E4,1, A4,1, B4,2, NONE,1, E4,1, GS4,1, B4,1, C5,2, 0xff}; static volatile uint8_t icnt,tone; @@ -153,7 +153,8 @@ ISR(TIMER0_OVF_vect) void play_ringtone(void) { -uint8_t i,*noteptr; +uint8_t i; +const uint8_t *noteptr; /* What's next on the playlist? */ switch (tuneindex++) { diff --git a/platform/avr-ravenlcd/doc/Doxyfile b/platform/avr-ravenlcd/doc/Doxyfile index e87bf474f..e8c4027d1 100644 --- a/platform/avr-ravenlcd/doc/Doxyfile +++ b/platform/avr-ravenlcd/doc/Doxyfile @@ -1,240 +1,240 @@ -# Doxyfile 1.4.1 - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- -PROJECT_NAME = "Contiki 6LoWPAN Menu" -PROJECT_NUMBER = -OUTPUT_DIRECTORY = . -CREATE_SUBDIRS = NO -OUTPUT_LANGUAGE = English -USE_WINDOWS_ENCODING = NO -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = YES -STRIP_FROM_PATH = ../ -STRIP_FROM_INC_PATH = -SHORT_NAMES = YES -JAVADOC_AUTOBRIEF = YES -MULTILINE_CPP_IS_BRIEF = NO -DETAILS_AT_TOP = YES -INHERIT_DOCS = YES -DISTRIBUTE_GROUP_DOC = NO -TAB_SIZE = 8 -ALIASES = -OPTIMIZE_OUTPUT_FOR_C = YES -OPTIMIZE_OUTPUT_JAVA = NO -SUBGROUPING = YES -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- -EXTRACT_ALL = NO -EXTRACT_PRIVATE = NO -EXTRACT_STATIC = YES -EXTRACT_LOCAL_CLASSES = NO -EXTRACT_LOCAL_METHODS = NO -HIDE_UNDOC_MEMBERS = YES -HIDE_UNDOC_CLASSES = YES -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = NO -CASE_SENSE_NAMES = YES -HIDE_SCOPE_NAMES = NO -SHOW_INCLUDE_FILES = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO -SORT_BY_SCOPE_NAME = NO -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = NO -GENERATE_DEPRECATEDLIST= NO -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = NO -SHOW_DIRECTORIES = YES -FILE_VERSION_FILTER = -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = NO -WARN_IF_DOC_ERROR = YES -WARN_NO_PARAMDOC = NO -WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = ../adc.c \ - ../beep.c \ - ../key.c \ - ../lcd.c \ - ../menu.c \ - ../raven3290.c \ - ../sleep.c \ - ../temp.c \ - ../timer.c \ - ../uart.c \ - ../adc.h \ - ../beep.h \ - ../key.h \ - ../lcd.h \ - ../menu.h \ - ../main.h \ - ../sleep.h \ - ../temp.h \ - ../timer.h \ - ../uart.h - -FILE_PATTERNS = -RECURSIVE = NO -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXAMPLE_PATH = -EXAMPLE_PATTERNS = -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = ./pics -INPUT_FILTER = -FILTER_PATTERNS = -FILTER_SOURCE_FILES = NO -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = YES -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = NO -REFERENCED_BY_RELATION = YES -REFERENCES_RELATION = YES -VERBATIM_HEADERS = YES -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = YES -COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = html -HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = -HTML_STYLESHEET = -HTML_ALIGN_MEMBERS = YES -GENERATE_HTMLHELP = YES -CHM_FILE = -HHC_LOCATION = -GENERATE_CHI = YES -BINARY_TOC = YES -TOC_EXPAND = YES -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = YES -TREEVIEW_WIDTH = 250 -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = YES -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = YES -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = YES -USE_PDFLATEX = YES -LATEX_BATCHMODE = NO -LATEX_HIDE_INDICES = NO -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -XML_OUTPUT = xml -XML_SCHEMA = -XML_DTD = -XML_PROGRAMLISTING = YES -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = DOXYGEN -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- -CLASS_DIAGRAMS = NO -HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = YES -CLASS_GRAPH = NO -COLLABORATION_GRAPH = NO -GROUP_GRAPHS = NO -UML_LOOK = NO -TEMPLATE_RELATIONS = NO -INCLUDE_GRAPH = NO -INCLUDED_BY_GRAPH = NO -CALL_GRAPH = NO -GRAPHICAL_HIERARCHY = NO -DIRECTORY_GRAPH = NO -DOT_IMAGE_FORMAT = png -DOT_PATH = -DOTFILE_DIRS = -MAX_DOT_GRAPH_WIDTH = 1024 -MAX_DOT_GRAPH_HEIGHT = 1024 -MAX_DOT_GRAPH_DEPTH = 0 -DOT_TRANSPARENT = NO -DOT_MULTI_TARGETS = NO -GENERATE_LEGEND = YES -DOT_CLEANUP = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = NO +# Doxyfile 1.4.1 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = "Contiki 6LoWPAN Menu" +PROJECT_NUMBER = +OUTPUT_DIRECTORY = . +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = ../ +STRIP_FROM_INC_PATH = +SHORT_NAMES = YES +JAVADOC_AUTOBRIEF = YES +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = YES +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = NO +GENERATE_DEPRECATEDLIST= NO +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = NO +SHOW_DIRECTORIES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = NO +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = ../adc.c \ + ../beep.c \ + ../key.c \ + ../lcd.c \ + ../menu.c \ + ../raven3290.c \ + ../sleep.c \ + ../temp.c \ + ../timer.c \ + ../uart.c \ + ../adc.h \ + ../beep.h \ + ../key.h \ + ../lcd.h \ + ../menu.h \ + ../main.h \ + ../sleep.h \ + ../temp.h \ + ../timer.h \ + ../uart.h + +FILE_PATTERNS = +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = ./pics +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = NO +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = YES +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = YES +BINARY_TOC = YES +TOC_EXPAND = YES +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = YES +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = YES +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = DOXYGEN +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +CLASS_GRAPH = NO +COLLABORATION_GRAPH = NO +GROUP_GRAPHS = NO +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = NO +INCLUDED_BY_GRAPH = NO +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = NO +DIRECTORY_GRAPH = NO +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/platform/avr-ravenlcd/menu.c b/platform/avr-ravenlcd/menu.c index a5cda40a9..3069d7825 100644 --- a/platform/avr-ravenlcd/menu.c +++ b/platform/avr-ravenlcd/menu.c @@ -66,6 +66,27 @@ bool auto_temp=true; /*---------------------------------------------------------------------------*/ +/** + * \brief This will reliably set or clear the JTD bit of the MCUCR register. + * + * \param x True to set the JTD bit disabling JTAG. +*/ +#define jtd_set(x)\ +{\ + __asm__ __volatile__ (\ + "in __tmp_reg__,__SREG__" "\n\t"\ + "cli" "\n\t"\ + "out %1, %0" "\n\t"\ + "out __SREG__, __tmp_reg__" "\n\t"\ + "out %1, %0" "\n\t"\ + : /* no outputs */\ + : "r" ((uint8_t)(x ? (1<ravenlcd_329025-Apr-2008 11:07:1628-Aug-2008 17:12:52241025-Apr-2008 11:07:1644, 13, 0, 569AVR GCCdefault\ravenlcd_3290.elfC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\JTAGICE mkIIATmega3290PfalseR00R01R02R03R04R05R06R07R08R09R10R11R12R13R14R15R16R17R18R19R20R21R22R23R24R25R26R27R28R29R30R31Auto00menuresultstrpnpayloadnumb0uart.cadc.ckey.clcd.cmenu.craven3290.csleep.cbeep.ctimer.ctemp.cdefault\ravenlcd_3290.lssdefault\ravenlcd_3290.mapdefaultNOatmega3290p111ravenlcd_3290.elfdefault\0.\-Wall -gdwarf-2 -std=gnu99 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enumsdefault1C:\Programme\WinAVR-20080610\bin\avr-gcc.exeC:\Programme\WinAVR-20080610\utils\bin\make.exeC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\uart.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\adc.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\key.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\lcd.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\menu.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\raven3290.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\sleep.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\beep.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\timer.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\temp.c00000raven3290.c25900001sleep.c25700002lcd.c25900003timer.c25900004adc.c25900005menu.c25900006temp.c25900007key.c25900008uart.c259 +ravenlcd_329025-Apr-2008 11:07:1628-Aug-2008 17:12:52241025-Apr-2008 11:07:1644, 13, 0, 569AVR GCCdefault\ravenlcd_3290.elfC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\JTAGICE mkIIATmega3290PfalseR00R01R02R03R04R05R06R07R08R09R10R11R12R13R14R15R16R17R18R19R20R21R22R23R24R25R26R27R28R29R30R31Auto00menuresultstrpnpayloadnumb0uart.cadc.ckey.clcd.cmenu.craven3290.csleep.cbeep.ctimer.ctemp.cdefault\ravenlcd_3290.lssdefault\ravenlcd_3290.mapdefaultNOatmega3290p111ravenlcd_3290.elfdefault\0.\-Wall -gdwarf-2 -std=gnu99 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enumsdefault1C:\Programme\WinAVR-20080610\bin\avr-gcc.exeC:\Programme\WinAVR-20080610\utils\bin\make.exeC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\uart.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\adc.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\key.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\lcd.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\menu.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\raven3290.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\sleep.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\beep.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\timer.cC:\Atmel\cisco\branches\macipv6\apps\ravenlcd_3290\temp.c00000raven3290.c25900001sleep.c25700002lcd.c25900003timer.c25900004adc.c25900005menu.c25900006temp.c25900007key.c25900008uart.c259 diff --git a/platform/avr-ravenlcd/temp.c b/platform/avr-ravenlcd/temp.c index cf7c20c31..e7e8243b6 100644 --- a/platform/avr-ravenlcd/temp.c +++ b/platform/avr-ravenlcd/temp.c @@ -58,7 +58,7 @@ static uint16_t temp_table_celcius[]; static uint16_t temp_table_fahrenheit[]; #else /* !DOXYGEN */ /** Celcius temperatures (ADC-value) from -15 to 60 degrees */ -static uint16_t temp_table_celcius[] PROGMEM = { +static const uint16_t temp_table_celcius[] PROGMEM = { 923,917,911,904,898,891,883,876,868,860,851,843,834,825,815, 806,796,786,775,765,754,743,732,720,709,697,685,673,661,649, 636,624,611,599,586,574,562,549,537,524,512,500,488,476,464, @@ -68,7 +68,7 @@ static uint16_t temp_table_celcius[] PROGMEM = { }; /** Fahrenheit temperatures (ADC-value) from 0 to 140 degrees */ -static uint16_t temp_table_fahrenheit[] PROGMEM = { +static const uint16_t temp_table_fahrenheit[] PROGMEM = { 938, 935, 932, 929, 926, 923, 920, 916, 913, 909, 906, 902, 898, 894, 891, 887, 882, 878, 874, 870, 865, 861, 856, 851, 847, 842, 837, 832, 827, 822, 816, 811, 806, 800, 795, 789, 783, 778, 772, @@ -99,7 +99,7 @@ bool temp_initialized = false; * * \return EOF on error */ -static int find_temp(int16_t value, uint16_t* array, int count); +static int find_temp(int16_t value, const uint16_t* array, int count); /*---------------------------------------------------------------------------*/ @@ -232,7 +232,7 @@ temp_get(temp_unit_t unit) * \return EOF on error */ static int -find_temp(int16_t value, uint16_t* array, int count) +find_temp(int16_t value, const uint16_t* array, int count) { int i = 0; int table_val = 0; diff --git a/platform/avr-ravenusb/Makefile.avr-ravenusb b/platform/avr-ravenusb/Makefile.avr-ravenusb index 977b8e26d..6c702a261 100644 --- a/platform/avr-ravenusb/Makefile.avr-ravenusb +++ b/platform/avr-ravenusb/Makefile.avr-ravenusb @@ -42,7 +42,7 @@ CONTIKI_PLAT_DEFS = -DF_CPU=8000000UL -DAVRGCC -DAUTO_CRC_PADDING=2 -DJACKDAW=1 #The no-net build using fakeuip.c is always ipv6 CFLAGS += -I$(CONTIKI)/core/net/ipv6 -I$(CONTIKI)/core/net/ip -I$(CONTIKI)/core/net/ipv4 ifdef CONTIKI_NO_NET -CONTIKI_PLAT_DEFS+= -DUIP_CONF_IPV6=1 +CONTIKI_PLAT_DEFS+= -DNETSTACK_CONF_WITH_IPV6=1 endif @@ -67,9 +67,9 @@ include $(CONTIKIAVR)/Makefile.avr include $(CONTIKIAVR)/radio/Makefile.radio ifndef CONTIKI_NO_NET -MODULES+=core/net/ip core/net/ipv4 core/net core/net/ipv6 \ - core/net/rime core/net/mac core/net/mac/sicslowmac +MODULES+=core/net/mac core/net/mac/sicslowmac \ + core/net/llsec else vpath %.c $(CONTIKI)/core/net/ipv6 -CONTIKI_SOURCEFILES += sicslowpan.c linkaddr.c +CONTIKI_SOURCEFILES += sicslowpan.c linkaddr.c link-stats.c nbr-table.c endif diff --git a/platform/avr-ravenusb/cdc_task.c b/platform/avr-ravenusb/cdc_task.c index 8456e9cf1..de30d8d65 100644 --- a/platform/avr-ravenusb/cdc_task.c +++ b/platform/avr-ravenusb/cdc_task.c @@ -1,12 +1,12 @@ /* This file has been prepared for Doxygen automatic documentation generation.*/ -/*! \file cdc_task.c ********************************************************** +/*! \file platform/avr-ravenusb/cdc_task.c ********************************************************** * * \brief * Manages the CDC-ACM Virtual Serial Port Dataclass for the USB Device * * \addtogroup usbstick * - * \author + * \author * Colin O'Flynn * ******************************************************************************/ @@ -48,6 +48,7 @@ #include "contiki.h" +#include "sys/cc.h" #include "usb_drv.h" #include "usb_descriptors.h" #include "usb_specific_request.h" @@ -74,6 +75,13 @@ #include #include +#if UIP_CONF_IPV6_RPL +// Include needs to be up here instead of embedded in the other +// UIP_CONF_IPV6_RPL block, as doxygen seems not to be compatible with +// #includes embedded in other functions and spits out a warning. +#include "rpl.h" +#endif + #if JACKDAW_CONF_USE_SETTINGS #include "settings.h" #endif @@ -102,7 +110,7 @@ void menu_process(char c); extern char usb_busy; //! Counter for USB Serial port -extern U8 tx_counter; +extern U8 tx_counter; //! Timers for LEDs uint8_t led3_timer; @@ -151,13 +159,13 @@ PROCESS_THREAD(cdc_process, ev, data_proc) // turn off LED's if necessary if (led3_timer) led3_timer--; else Led3_off(); - + if(Is_device_enumerated()) { // If the configuration is different than the last time we checked... if((uart_usb_get_control_line_state()&1)!=previous_uart_usb_control_line_state) { previous_uart_usb_control_line_state = uart_usb_get_control_line_state()&1; static FILE* previous_stdout; - + if(previous_uart_usb_control_line_state&1) { previous_stdout = stdout; uart_usb_init(); @@ -202,8 +210,8 @@ PROCESS_THREAD(cdc_process, ev, data_proc) etimer_set(&et, CLOCK_SECOND); } - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + } // while(1) PROCESS_END(); @@ -282,18 +290,18 @@ void menu_process(char c) channel, txpower } menustate = normal; - + static char channel_string[3]; static uint8_t channel_string_i;// = 0; - + int tempchannel; if (menustate == channel) { switch(c) { case '\r': - case '\n': - + case '\n': + if (channel_string_i) { channel_string[channel_string_i] = 0; tempchannel = atoi(channel_string); @@ -309,7 +317,7 @@ void menu_process(char c) } else { #endif #if JACKDAW_CONF_USE_SETTINGS - if(settings_set_uint8(SETTINGS_KEY_CHANNEL, tempchannel)==SETTINGS_STATUS_OK) { + if(settings_set_uint8(SETTINGS_KEY_CHANNEL, tempchannel)==SETTINGS_STATUS_OK) { PRINTF_P(PSTR("\n\rChannel changed to %d and stored in EEPROM.\n\r"),tempchannel); } else { PRINTF_P(PSTR("\n\rChannel changed to %d, but unable to store in EEPROM!\n\r"),tempchannel); @@ -324,15 +332,15 @@ void menu_process(char c) menustate = normal; break; - + case '\b': - + if (channel_string_i) { channel_string_i--; PRINTF_P(PSTR("\b \b")); } break; - + case '0': case '1': case '2': @@ -352,7 +360,7 @@ void menu_process(char c) } putc(c, stdout); //uart_usb_putchar(c); - + channel_string[channel_string_i] = c; channel_string_i++; break; @@ -364,8 +372,8 @@ void menu_process(char c) switch(c) { case '\r': - case '\n': - + case '\n': + if (channel_string_i) { channel_string[channel_string_i] = 0; tempchannel = atoi(channel_string); @@ -396,15 +404,15 @@ void menu_process(char c) menustate = normal; break; - + case '\b': - + if (channel_string_i) { channel_string_i--; PRINTF_P(PSTR("\b \b")); } break; - + case '0': case '1': case '2': @@ -424,7 +432,7 @@ void menu_process(char c) } putc(c, stdout); //uart_usb_putchar(c); - + channel_string[channel_string_i] = c; channel_string_i++; break; @@ -432,7 +440,7 @@ void menu_process(char c) default: break; } - + } else { uint8_t i; @@ -482,7 +490,7 @@ void menu_process(char c) usbstick_mode.translate = 0; #if RF230BB rf230_listen_channel(rf230_get_channel()); -#else +#else radio_set_trx_state(RX_ON); #endif break; @@ -518,7 +526,7 @@ void menu_process(char c) usbstick_mode.translate = 1; #if RF230BB rf230_set_channel(rf230_get_channel()); -#else +#else radio_set_trx_state(RX_AACK_ON); //TODO: Use startup state which may be RX_ON #endif break; @@ -530,8 +538,8 @@ void menu_process(char c) } else { PRINTF_P(PSTR("Jackdaw now performs 6lowpan translations\n\r")); usbstick_mode.sicslowpan = 1; - } - + } + break; case 'r': @@ -541,7 +549,7 @@ void menu_process(char c) } else { PRINTF_P(PSTR("Jackdaw now captures raw frames\n\r")); usbstick_mode.raw = 1; - } + } break; #if USB_CONF_RS232 case 'd': @@ -551,7 +559,7 @@ void menu_process(char c) } else { PRINTF_P(PSTR("Jackdaw now outputs debug strings\n\r")); usbstick_mode.debugOn = 1; - } + } break; #endif @@ -578,14 +586,13 @@ void menu_process(char c) #if UIP_CONF_IPV6_RPL -#include "rpl.h" extern uip_ds6_netif_t uip_ds6_if; case 'N': { uint8_t i,j; uip_ds6_nbr_t *nbr; PRINTF_P(PSTR("\n\rAddresses [%u max]\n\r"),UIP_DS6_ADDR_NB); for (i=0;iipaddr); PRINTF_P(PSTR("/%u (via "), route->length); ipaddr_add(uip_ds6_route_nexthop(route)); @@ -619,21 +626,21 @@ extern uip_ds6_netif_t uip_ds6_if; PRINTF_P(PSTR("\n\r---------\n\r")); break; } - + case 'G': PRINTF_P(PSTR("Global repair returns %d\n\r"),rpl_repair_root(RPL_DEFAULT_INSTANCE)); break; - + case 'L': rpl_local_repair(rpl_get_any_dag()); - PRINTF_P(PSTR("Local repair initiated\n\r")); + PRINTF_P(PSTR("Local repair initiated\n\r")); break; - - case 'Z': //zap the routing table + + case 'Z': //zap the routing table PRINTF_P(PSTR("Not implemented.\n\r")); break; -#endif - +#endif + case 'm': PRINTF_P(PSTR("Currently Jackdaw:\n\r * Will ")); if (usbstick_mode.sendToRf == 0) { PRINTF_P(PSTR("not "));} @@ -676,7 +683,7 @@ extern uip_ds6_netif_t uip_ds6_if; PRINTF_P(PSTR(" * Operates on channel %d with TX power "),rf230_get_channel()); printtxpower(); PRINTF_P(PSTR("\n\r")); -#else //just show the raw value +#else //just show the raw value PRINTF_P(PSTR(" * Operates on channel %d\n\r"), rf230_get_channel()); PRINTF_P(PSTR(" * TX Power(0=+3dBm, 15=-17.2dBm): %d\n\r"), rf230_get_txpower()); #endif @@ -698,7 +705,7 @@ extern uip_ds6_netif_t uip_ds6_if; else PRINTF_P(PSTR("Unknown\n\r")); } - + #endif /* RF230BB */ PRINTF_P(PSTR(" * Configuration: %d, USB<->ETH is "), usb_configuration_nb); @@ -735,10 +742,10 @@ uint16_t p=(uint16_t)&__bss_end; #endif int8_t RSSI, maxRSSI[17]; uint16_t accRSSI[17]; - + bzero((void*)accRSSI,sizeof(accRSSI)); bzero((void*)maxRSSI,sizeof(maxRSSI)); - + for(j=0;j<(1<<12);j++) { for(i=11;i<=26;i++) { #if RF230BB @@ -753,7 +760,7 @@ uint16_t p=(uint16_t)&__bss_end; radio_get_rssi_value(&RSSI); RSSI*=3; #endif - maxRSSI[i-11]=Max(maxRSSI[i-11],RSSI); + maxRSSI[i-11]=MAX(maxRSSI[i-11],RSSI); accRSSI[i-11]+=RSSI; } if(j&(1<<7)) { @@ -774,7 +781,7 @@ uint16_t p=(uint16_t)&__bss_end; #endif PRINTF_P(PSTR("\n")); for(i=11;i<=26;i++) { - uint8_t activity=Min(maxRSSI[i-11],accRSSI[i-11]/(1<<7)); + uint8_t activity=MIN(maxRSSI[i-11],accRSSI[i-11]/(1<<7)); PRINTF_P(PSTR(" %d: %02ddB "),i, -91+(maxRSSI[i-11]-1)); for(;activity--;maxRSSI[i-11]--) { PRINTF_P(PSTR("#")); @@ -789,7 +796,7 @@ uint16_t p=(uint16_t)&__bss_end; } PRINTF_P(PSTR("Done.\n")); uart_usb_flush(); - + break; @@ -814,7 +821,7 @@ uint16_t p=(uint16_t)&__bss_end; watchdog_reboot(); } break; - + #if USB_CONF_STORAGE case 'u': diff --git a/platform/avr-ravenusb/contiki-conf.h b/platform/avr-ravenusb/contiki-conf.h index 9669becc9..8eab7cce9 100644 --- a/platform/avr-ravenusb/contiki-conf.h +++ b/platform/avr-ravenusb/contiki-conf.h @@ -70,18 +70,10 @@ */ /* Clock ticks per second */ #define CLOCK_CONF_SECOND 125 -#if 1 -/* 16 bit counter overflows every ~10 minutes */ -typedef unsigned short clock_time_t; -#define CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) -#define INFINITE_TIME 0xffff -#define RIME_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME INFINITE_TIME/CLOCK_CONF_SECOND /* Default uses 600 */ -#define COLLECT_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME INFINITE_TIME/CLOCK_CONF_SECOND /* Default uses 600 */ -#else -typedef unsigned long clock_time_t; -#define CLOCK_LT(a,b) ((signed long)((a)-(b)) < 0) -#define INFINITE_TIME 0xffffffff -#endif + +typedef uint32_t clock_time_t; +#define CLOCK_LT(a,b) ((int32_t)((a)-(b)) < 0) + /* These routines are not part of the contiki core but can be enabled in cpu/avr/clock.c */ void clock_delay_msec(uint16_t howlong); void clock_adjust_ticks(clock_time_t howmany); @@ -212,24 +204,18 @@ extern void mac_log_802_15_4_rx(const uint8_t* buffer, size_t total_len); /* Network setup. The new NETSTACK interface requires RF230BB (as does ip4) */ /* These mostly have no effect when the Jackdaw is a repeater (CONTIKI_NO_NET=1 using fakeuip.c) */ -#if RF230BB -#else -#define PACKETBUF_CONF_HDR_SIZE 0 //RF230 combined driver/mac handles headers internally -#endif /*RF230BB */ - -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #define LINKADDR_CONF_SIZE 8 #define UIP_CONF_ICMP6 1 #define UIP_CONF_UDP 1 #define UIP_CONF_TCP 0 -//#define UIP_CONF_IPV6_RPL 0 #define NETSTACK_CONF_NETWORK sicslowpan_driver #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #else /* ip4 should build but is thoroughly untested */ #define LINKADDR_CONF_SIZE 2 #define NETSTACK_CONF_NETWORK rime_driver -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /* See uip-ds6.h */ #define NBR_TABLE_CONF_MAX_NEIGHBORS 2 @@ -245,10 +231,10 @@ extern void mac_log_802_15_4_rx(const uint8_t* buffer, size_t total_len); #define UIP_CONF_BUFSIZE UIP_LINK_MTU + UIP_LLH_LEN + 4 /* +4 for vlan on macosx */ /* 10 bytes per stateful address context - see sicslowpan.c */ -/* Default is 1 context with prefix aaaa::/64 */ +/* Default is 1 context with prefix fd00::/64 */ /* These must agree with all the other nodes or there will be a failure to communicate! */ #//define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 -#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 {addr_contexts[0].prefix[0]=0xaa;addr_contexts[0].prefix[1]=0xaa;} +#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 {addr_contexts[0].prefix[0]=UIP_DS6_DEFAULT_PREFIX_0;addr_contexts[0].prefix[1]=UIP_DS6_DEFAULT_PREFIX_1;} #define SICSLOWPAN_CONF_ADDR_CONTEXT_1 {addr_contexts[1].prefix[0]=0xbb;addr_contexts[1].prefix[1]=0xbb;} #define SICSLOWPAN_CONF_ADDR_CONTEXT_2 {addr_contexts[2].prefix[0]=0x20;addr_contexts[2].prefix[1]=0x01;addr_contexts[2].prefix[2]=0x49;addr_contexts[2].prefix[3]=0x78,addr_contexts[2].prefix[4]=0x1d;addr_contexts[2].prefix[5]=0xb1;} @@ -285,9 +271,6 @@ typedef unsigned short uip_stats_t; #define RADIO_CONF_CALIBRATE_INTERVAL 256 /* AUTOACK receive mode gives better rssi measurements, even if ACK is never requested */ #define RF230_CONF_AUTOACK 1 -/* Request 802.15.4 ACK on all packets sent by sicslowpan.c (else autoretry) */ -/* Broadcasts will be duplicated by the retry count, since no one will ACK them! */ -#define SICSLOWPAN_CONF_ACK_ALL 0 /* 1 + Number of auto retry attempts 0-15 (0 implies don't use extended TX_ARET_ON mode with CCA) */ #define RF230_CONF_FRAME_RETRIES 2 /* CCA theshold energy -91 to -61 dBm (default -77). Set this smaller than the expected minimum rssi to avoid packet collisions */ @@ -312,7 +295,13 @@ typedef unsigned short uip_stats_t; #define NETSTACK_CONF_MAC nullmac_driver //#define NETSTACK_CONF_MAC csma_driver #define NETSTACK_CONF_RDC contikimac_driver -#define NETSTACK_CONF_FRAMER framer_802154 + +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_FRAMER framer802154 +#else /* NETSTACK_CONF_WITH_IPV6 */ +#define NETSTACK_CONF_FRAMER contikimac_framer +#endif /* NETSTACK_CONF_WITH_IPV6 */ + #define NETSTACK_CONF_RADIO rf230_driver #define CHANNEL_802_15_4 26 /* Enable extended mode with autoack, but no csma/autoretry */ @@ -374,13 +363,12 @@ typedef unsigned short uip_stats_t; //#pragma mark RPL Settings /* ************************************************************************** */ -#define UIP_CONF_IPV6_RPL 0 #if UIP_CONF_IPV6_RPL /* Not completely working yet. Works on Ubuntu after $ifconfig usb0 -arp to drop the neighbor solitications */ /* Dropping the NS on other OSs is more complicated, see http://www.sics.se/~adam/wiki/index.php/Jackdaw_RNDIS_RPL_border_router */ -/* RPL requires the uip stack. Change #CONTIKI_NO_NET=1 to UIP_CONF_IPV6=1 in the examples makefile, +/* RPL requires the uip stack. Change #CONTIKI_NO_NET=1 to NETSTACK_CONF_WITH_IPV6=1 in the examples makefile, or include the needed source files in /plaftorm/avr-ravenusb/Makefile.avr-ravenusb */ /* For the present the buffer_length calcs in rpl-icmp6.c will need adjustment by the length difference between 6lowpan (0) and ethernet (14) link-layer headers: diff --git a/platform/avr-ravenusb/contiki-raven-main.c b/platform/avr-ravenusb/contiki-raven-main.c index c55448e3d..e2ca7711e 100644 --- a/platform/avr-ravenusb/contiki-raven-main.c +++ b/platform/avr-ravenusb/contiki-raven-main.c @@ -132,7 +132,7 @@ init(void) { } void mac_LowpanToEthernet(void); -static void +static int output(void) { // if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) { @@ -142,6 +142,7 @@ output(void) PRINTD("SUT: %u\n", uip_len); mac_LowpanToEthernet(); //bounceback trap is done in lowpanToEthernet // } + return 0; } const struct uip_fallback_interface rpl_interface = { init, output @@ -500,7 +501,7 @@ uint16_t p=(uint16_t)&__bss_end; //Fix MAC address init_net(); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(&uip_lladdr.addr, &tmp_addr.u8, 8); #endif @@ -552,7 +553,9 @@ uint16_t p=(uint16_t)&__bss_end; #else /* RF230BB */ /* The order of starting these is important! */ process_start(&mac_process, NULL); +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 process_start(&tcpip_process, NULL); +#endif #endif /* RF230BB */ /* Start ethernet network and storage process */ diff --git a/platform/avr-ravenusb/httpd-simple-avr.c b/platform/avr-ravenusb/httpd-simple-avr.c index 3d36076eb..3d225a4f4 100644 --- a/platform/avr-ravenusb/httpd-simple-avr.c +++ b/platform/avr-ravenusb/httpd-simple-avr.c @@ -253,7 +253,7 @@ PT_THREAD(generate_routes(struct httpd_state *s)) PSOCK_GENERATOR_SEND(&s->sout, generate_string_P, (char *) TOP1); PSOCK_GENERATOR_SEND(&s->sout, generate_string_P, (char *) TOP2); -#if UIP_CONF_IPV6 //allow ip4 builds +#if NETSTACK_CONF_WITH_IPV6 //allow ip4 builds blen = 0; ADD("

    Neighbors [%u max]

    ",NBR_TABLE_CONF_MAX_NEIGHBORS); PSOCK_GENERATOR_SEND(&s->sout, generate_string, buf); @@ -296,11 +296,11 @@ PT_THREAD(generate_routes(struct httpd_state *s)) PSOCK_GENERATOR_SEND(&s->sout, generate_string, buf); blen = 0; } -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ blen = 0;i++; ADD("

    Hey, you got ip4 working!

    "); PSOCK_GENERATOR_SEND(&s->sout, generate_string, buf); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ PSOCK_GENERATOR_SEND(&s->sout, generate_string_P, (char *) BOTTOM); diff --git a/platform/avr-ravenusb/rng.c b/platform/avr-ravenusb/rng.c index 83ce3e5b8..ed385d960 100644 --- a/platform/avr-ravenusb/rng.c +++ b/platform/avr-ravenusb/rng.c @@ -66,7 +66,7 @@ extract_random_bit_() { cli(); #ifdef PRR - // Enable ADC module + // Enable ADC module PRR &= ~(1 << PRADC); #endif @@ -100,7 +100,7 @@ extract_random_bit_() { // Toggling the reference voltage // seems to help introduce noise. ADMUX^=(1<dest.addr[0]), 6) == 0) { -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 //Addressed to us: make 802.15.4 address from IPv6 Address destAddr.addr[0] = UIP_IP_BUF->destipaddr.u8[8] ^ 0x02; destAddr.addr[1] = UIP_IP_BUF->destipaddr.u8[9]; @@ -409,7 +409,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) #if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS else { //Not addressed to us - uip_len = 0; + uip_clear_buf(); return; } #else @@ -422,7 +422,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) #if !RF230BB usb_eth_stat.txbad++; #endif - uip_len = 0; + uip_clear_buf(); return; } PRINTF(" translated OK\n\r"); @@ -445,7 +445,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) #endif } -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /* Send the packet to the uip6 stack if it exists, else send to 6lowpan */ #if UIP_CONF_IPV6_RPL /* Save the destination address, to trap ponging it back to the interface */ @@ -456,14 +456,14 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) // PRINTF("Output to %x %x %x %x %x %x %x %x\n",destAddr.addr[0],destAddr.addr[1],destAddr.addr[2],destAddr.addr[3],destAddr.addr[4],destAddr.addr[5],destAddr.addr[6],destAddr.addr[7]); tcpip_output(destAddrPtr); #endif -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ tcpip_output(); //Allow non-ipv6 builds (Hello World) -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #if !RF230BB usb_eth_stat.txok++; #endif - uip_len = 0; + uip_clear_buf(); } @@ -481,11 +481,8 @@ void mac_LowpanToEthernet(void) //Setup generic ethernet stuff ETHBUF(uip_buf)->type = uip_htons(UIP_ETHTYPE_IPV6); - //Check for broadcast message - #if RF230BB - if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) { -// if(linkaddr_cmp((const linkaddr_t *)destAddr, &linkaddr_null)) { + if(packetbuf_holds_broadcast()) { #else if( ( parsed_frame->fcf->destAddrMode == SHORTADDRMODE) && ( parsed_frame->dest_addr->addr16 == 0xffff) ) { @@ -493,7 +490,7 @@ void mac_LowpanToEthernet(void) ETHBUF(uip_buf)->dest.addr[0] = 0x33; ETHBUF(uip_buf)->dest.addr[1] = 0x33; -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 ETHBUF(uip_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12]; ETHBUF(uip_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13]; ETHBUF(uip_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14]; @@ -546,7 +543,7 @@ void mac_LowpanToEthernet(void) #if !RF230BB usb_eth_stat.rxok++; #endif - uip_len = 0; + uip_clear_buf(); } /** @@ -712,7 +709,7 @@ int8_t mac_translateIcmpLinkLayer(lltype_t target) //We broke ICMP checksum, be sure to fix that UIP_ICMP_BUF->icmpchksum = 0; -#if UIP_CONF_IPV6 //allow non ipv6 builds +#if NETSTACK_CONF_WITH_IPV6 //allow non ipv6 builds UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); #endif @@ -977,7 +974,7 @@ mac_log_802_15_4_tx(const uint8_t* buffer, size_t total_len) { ETHBUF(raw_buf)->type = uip_htons(0x809A); //UIP_ETHTYPE_802154 0x809A /* Check for broadcast message */ - if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) { + if(packetbuf_holds_broadcast()) { ETHBUF(raw_buf)->dest.addr[0] = 0x33; ETHBUF(raw_buf)->dest.addr[1] = 0x33; ETHBUF(raw_buf)->dest.addr[2] = 0x00; @@ -1018,7 +1015,7 @@ mac_log_802_15_4_rx(const uint8_t* buf, size_t len) { ETHBUF(raw_buf)->type = uip_htons(0x809A); //UIP_ETHTYPE_802154 0x809A /* Check for broadcast message */ - if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) { + if(packetbuf_holds_broadcast()) { ETHBUF(raw_buf)->dest.addr[0] = 0x33; ETHBUF(raw_buf)->dest.addr[1] = 0x33; ETHBUF(raw_buf)->dest.addr[2] = 0x00; diff --git a/platform/avr-rcb/Makefile.avr-rcb b/platform/avr-rcb/Makefile.avr-rcb index 96dcd0cd3..5c14240b0 100644 --- a/platform/avr-rcb/Makefile.avr-rcb +++ b/platform/avr-rcb/Makefile.avr-rcb @@ -5,10 +5,14 @@ CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o CONTIKI_TARGET_SOURCEFILES += rs232.c cfs-eeprom.c eeprom.c random.c \ mmem.c contiki-rcb-main.c +MODULES += core/net core/net/mac core/net/mac/sicslowmac core/net/mac/contikimac \ + core/net/mac/cxmac core/net/rime core/net/ipv4 core/net/ip \ + core/net/ipv6 core/net/rpl core/net/llsec + CONTIKIAVR=$(CONTIKI)/cpu/avr CONTIKIBOARD=. -CONTIKI_PLAT_DEFS = -DF_CPU=8000000UL -DAUTO_CRC_PADDING=2 +CONTIKI_PLAT_DEFS = -DF_CPU=8000000UL -DAUTO_CRC_PADDING=2 -DNETSTACK_CONF_WITH_RIME=1 -DNETSTACK_CONF_WITH_IPV6=1 MCU=atmega1281 AVRDUDE_PROGRAMMER=jtag2 diff --git a/platform/avr-rcb/contiki-conf.h b/platform/avr-rcb/contiki-conf.h index d10edf4f1..68ce8f3b6 100644 --- a/platform/avr-rcb/contiki-conf.h +++ b/platform/avr-rcb/contiki-conf.h @@ -62,18 +62,10 @@ */ /* Clock ticks per second */ #define CLOCK_CONF_SECOND 125 -#if 1 -/* 16 bit counter overflows every ~10 minutes */ -typedef unsigned short clock_time_t; -#define CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) -#define INFINITE_TIME 0xffff -#define RIME_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME INFINITE_TIME/CLOCK_CONF_SECOND /* Default uses 600 */ -#define COLLECT_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME INFINITE_TIME/CLOCK_CONF_SECOND /* Default uses 600 */ -#else -typedef unsigned long clock_time_t; -#define CLOCK_LT(a,b) ((signed long)((a)-(b)) < 0) -#define INFINITE_TIME 0xffffffff -#endif + +typedef uint32_t clock_time_t; +#define CLOCK_LT(a,b) ((int32_t)((a)-(b)) < 0) + /* These routines are not part of the contiki core but can be enabled in cpu/avr/clock.c */ void clock_delay_msec(uint16_t howlong); void clock_adjust_ticks(clock_time_t howmany); @@ -92,17 +84,25 @@ void clock_adjust_ticks(clock_time_t howmany); #define CCIF #define CLIF -//#define UIP_CONF_IPV6 1 //Let makefile determine this so ipv4 hello-world will compile - #define LINKADDR_CONF_SIZE 8 -#define PACKETBUF_CONF_HDR_SIZE 0 -/* 0 for IPv6, or 1 for HC1, 2 for HC01 */ -#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 -#define SICSLOWPAN_CONF_COMPRESSION_HC1 1 -#define SICSLOWPAN_CONF_COMPRESSION_HC01 2 +/* Uncomment this lines to activate the specific drivers */ +//#define NETSTACK_CONF_NETWORK rime_driver +//#define NETSTACK_CONF_MAC nullmac_driver +//#define NETSTACK_CONF_RDC sicslowmac_driver +//#define NETSTACK_CONF_FRAMER framer_802154 /* Framer for 802.15.4 Medium Access Control */ +#define NETSTACK_CONF_RADIO rf230_driver /* Select the wireless driver, otherwise contiki would operate with the "nulldriver" which does nothing */ -#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_CONF_COMPRESSION_HC01 +#define RF230_CONF_AUTOACK 1 +#define CXMAC_CONF_ANNOUNCEMENTS 10 +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 + +/* 211 bytes per queue buffer. Burst mode will need 15 for a 1280 byte MTU */ +#define QUEUEBUF_CONF_NUM 15 +/* 54 bytes per queue ref buffer */ +#define QUEUEBUF_CONF_REF_NUM 2 + +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 #define SICSLOWPAN_CONF_FRAG 1 @@ -122,20 +122,16 @@ void clock_adjust_ticks(clock_time_t howmany); #define UIP_CONF_IPV6_QUEUE_PKT 0 #define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_NETIF_MAX_ADDRESSES 3 -#define UIP_CONF_ND6_MAX_PREFIXES 3 -#define UIP_CONF_ND6_MAX_DEFROUTERS 2 -#if UIP_CONF_IPV6 //tcpip.c error on ipv4 build if UIP_CONF_ICMP6 defined -#define UIP_CONF_ICMP6 1 +#if NETSTACK_CONF_WITH_IPV6 //tcpip.c error on ipv4 build if UIP_CONF_ICMP6 defined +#define UIP_CONF_ICMP6 1 #endif #define UIP_CONF_UDP 1 #define UIP_CONF_UDP_CHECKSUMS 1 -#define UIP_CONF_TCP 0 +#define UIP_CONF_TCP 1 #define UIP_CONF_TCP_SPLIT 0 - - /* These names are deprecated, use C99 names. */ /*typedef unsigned char u8_t; typedef unsigned short u16_t; diff --git a/platform/avr-rcb/contiki-rcb-main.c b/platform/avr-rcb/contiki-rcb-main.c index 4a6a98e22..bc7a08602 100644 --- a/platform/avr-rcb/contiki-rcb-main.c +++ b/platform/avr-rcb/contiki-rcb-main.c @@ -74,9 +74,17 @@ FUSES = PROCESS(rcb_leds, "RCB leds process"); #if RF230BB +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 PROCINIT(&etimer_process, &tcpip_process, &rcb_leds); #else +PROCINIT(&etimer_process, &rcb_leds); +#endif +#else +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 PROCINIT(&etimer_process, &mac_process, &tcpip_process, &rcb_leds); +#else +PROCINIT(&etimer_process, &mac_process, &rcb_leds); +#endif #endif /* Put default MAC address in EEPROM */ @@ -101,21 +109,22 @@ init_lowlevel(void) rs232_redirect_stdout(RS232_PORT_1); DDRE |= LED1 | LED2 | LED3; + + ctimer_init(); + } static struct etimer et; PROCESS_THREAD(rcb_leds, ev, data) { - uint8_t error; PROCESS_BEGIN(); - if((error = icmp6_new(NULL)) == 0) { while(1) { PROCESS_YIELD(); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 if (ev == ICMP6_ECHO_REQUEST) { #else if (1) { @@ -126,7 +135,6 @@ PROCESS_THREAD(rcb_leds, ev, data) LEDOff(LED2); } } - } PROCESS_END(); } @@ -134,14 +142,10 @@ PROCESS_THREAD(rcb_leds, ev, data) int main(void) { - //calibrate_rc_osc_32k(); //CO: Had to comment this out - /* Initialize hardware */ - init_lowlevel(); - + init_lowlevel(); /* Clock */ clock_init(); - LEDOff(LED1 | LED2); /* Process subsystem */ @@ -149,17 +153,29 @@ main(void) /* Register initial processes */ procinit_init(); + + /* It is very important to do the NETSTACK_* initializations right here + * to enable the PROCESS_YIELD** functionality. + * The receive process is an single protothread which handles the + * received packets. This process needs PROCESS_YIELD_UNTIL(). + **/ + /* Start radio and radio receive process */ + NETSTACK_RADIO.init(); + /* Initialize stack protocols */ + queuebuf_init(); + NETSTACK_RDC.init(); + NETSTACK_MAC.init(); + NETSTACK_NETWORK.init(); /* Autostart processes */ autostart_start(autostart_processes); printf_P(PSTR("\n********BOOTING CONTIKI*********\n")); - printf_P(PSTR("System online.\n")); /* Main scheduler loop */ while(1) { - process_run(); + process_run(); } return 0; diff --git a/platform/avr-rss2/Makefile.avr-rss2 b/platform/avr-rss2/Makefile.avr-rss2 new file mode 100644 index 000000000..2655b8b4a --- /dev/null +++ b/platform/avr-rss2/Makefile.avr-rss2 @@ -0,0 +1,61 @@ +CONTIKI_TARGET_DIRS = . apps net loader dev + +CONTIKI_CORE=contiki-main +CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o +CONTIKI_TARGET_SOURCEFILES += contiki-main.c params.c battery-sensor.c i2c.c + +CONTIKI_TARGET_SOURCEFILES += sensors.c button-sensor.c slip_uart0.c slip.c leds.c temp_mcu-sensor.c light-sensor.c adc.c cfs-eeprom.c eeprom.c pulse-sensor.c + +CONTIKI_TARGET_SOURCEFILES += temp-sensor.c + +CONTIKI_TARGET_SOURCEFILES += enc28j60_avr.c +CONTIKI_TARGET_SOURCEFILES += co2_sa_kxx-sensor.c + +CONTIKIAVR=$(CONTIKI)/cpu/avr +CONTIKIBOARD=. + + +ifdef $(MCU) +MCU=$(MCU) +else +MCU=atmega256rfr2 +endif + +ifeq ($(MCU),atmega128rfa1) +CONTIKI_PLAT_DEFS = -DF_CPU=8000000UL -DAUTO_CRC_PADDING=2 +BOOTLOADER_START = 0x1E000 +endif + +ifeq ($(MCU),atmega128rfr2) +CONTIKI_PLAT_DEFS = -DF_CPU=8000000UL -DAUTO_CRC_PADDING=2 +BOOTLOADER_START = 0x1E000 +endif + +ifeq ($(MCU),atmega256rfr2) +CONTIKI_PLAT_DEFS = -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 +BOOTLOADER_START = 0x3E000 +endif + +AVRDUDE_PROGRAMMER=jtag2 + +# For usb devices, you may either use PORT=usb, or (e.g. if you have more than one +# programmer connected) you can use the following trick to find out the serial number: +# +# The example is for an JTAGICE mkII used to program an ATmega128: +# avrdude -v -P usb:xxxx -c jtag2 -p atmega128 +AVRDUDE_PORT=usb:00B000000D79 + +# Additional avrdude options +# Verify off +AVRDUDE_OPTIONS=-V +AVRDUDE_MCU=m256rfr2 + +include $(CONTIKIAVR)/Makefile.avr +include $(CONTIKIAVR)/radio/Makefile.radio + +#MODULES += core/net/mac core/net core/net/mac/sicslowmac core/net/mac/contikimac core/net/llsec core/net/rime + +MODULES += core/net/mac core/net core/net/mac/sicslowmac core/net/mac/contikimac core/net/llsec + + + diff --git a/platform/avr-rss2/README.md b/platform/avr-rss2/README.md new file mode 100644 index 000000000..05d448fc6 --- /dev/null +++ b/platform/avr-rss2/README.md @@ -0,0 +1,175 @@ +Getting Started with Contiki using avr-rss2 +=========================================== +This guide's aim is to help you start using Contiki for RSS2 boards +The platform supports different AtMega-RF boards: + +* Based on MCU AtMega128RFR2 +* Based on MCU AtMega256RFR2 +* Based on MCU AtMega128RFA1 + +Boards all looks the same. AtMega256RFR2 boards are labeled with "Made in EU". +The platform and CPU code, are common for both boards, can be found under +`$(CONTIKI)/platfrom/avr-rssa`. The port was developed and tested with RSS2. +This guide assumes that you have basic understanding of how to use the +command line and perform basic admin tasks on UNIX family OSs. You should +also have understanding about the Contiki OS design as well have C +programming skills. + +Board Features +---------------- +* Chip Antenna. Supercardiod. +* Robust radio performance. Up to 300 meter line-of-sight. +* Unique EUI64 address via chip combined with EEPROM +* Onboard temp sensor DS18B20, +* Light Sensor. +* 32kHz RTC xtal +* Comparator chip and input. +* SW FET, (relay) for power on/off of sensors. +* DC input via LDO up to 25V. +* Standard. 6-pin TTL-USB header for FTDI cable for UART. +* PCB formfactor for cheap project box G.40X IP54 +* Power/current: + * RX ~10mA (Full RPC AtMegaXXRFR2). + * Sleep ~45uA @ 16MHz XTAL + * Sleep ~15uA @ 8MHz using internal oscillator +* Preprogammed bootloader. +* CE certified by test institute. + +UART +---- +The board has one UART via the 6-pin TTL-USB adapter, The recommended +baudrate is 38400 bps. This speed gives the lowest error with respect +of the used clock frequency used internally. A possible hi-speed is +250000 bps wich gives 0% Error with 16MHz clock. + +Port Features +-------------- +The platform has the following key features: +* Standard, E64 address from built-in chip. +* First hooks for RPC (Reduced Power Consumption) for AtMegaXXXRFR2. + +Toolchain needs +--------------- +The Atmel toolcahin is available in most operating system. +Note. The native OS packages does not yet support the new +AtMega256RfR2 MCU. + +We'll use toolchain from Atmels web-site. You might also consider +Instant Contiki. + + +###### For Linux + +1. See http://www.atmel.com/tools/ATMELAVRTOOLCHAINFORLINUX.aspx +2. Download the proper 8-bit platform 32 or 64 bit. +3. Unpack under `/usr/local` +4. Add to your search PATH. For example add to `.bashrc`: `export PATH=$PATH:/usr/local/avr8-gnu-toolchain-linux_x86_64/bin` (for 64 bit systems) or `export PATH=$PATH:/usr/local/avr8-gnu-toolchain-linux_x86/bin` (for 32 birt systems). +5. For flash programming you'll need `avrdude`. It can be installed with the command +`apt-get install avrdude` + +###### For Windows + +Goes here + +Contiki build TARGET +-------------------- + make TARGET=avr-rss2 + +For AtMega128RFR2 boards: + + make TARGET=avr-rss2 MCU=atmega128rfr2 + +For AtMega128RFA1 boards: + + make TARGET=avr-rss2 MCU=atmega128rfa1 + +Flashing +-------- +Programming using avrdude using serial bootloader. (TTL-USB cable) +Press the RESET button. The bootloader with wait for boot commands +for 3 seconds. + +Flashing commnad line example 256k MCU: + + avrdude -p m256rfr2 -c stk500v2 -P /dev/ttyUSB0 -b 38400 -e -U flash:w:hello-world.avr-rss2 + +Flashing commnad line example 128k MCU: + + avrdude -p m128rfa1 -c avr109 -P /dev/ttyUSB0 -b 38400 -e -U flash:w:hello-world.avr-rss2 + +Older boards may use the avr109 boot loader. The `stk500v2` uses the yellow +lED while the avr109 uses the red LED. + +Tested applications and examples +--------------------------------- +* `hello-world` +* `ipv6/rpl-udp` +* `ipv6/simple-udp-rpl` +* `rime` +* `ipv6/multicast` +* `examples/powertrace` +* `example-shell` + +Note that the shell example needs file `symbols.c` to be added to project also seems like +in `core/dev/serial-line.c` the function `process_poll` must be replaced with `process_post`: + + /* Wake up consumer process */ + - process_poll(&serial_line_process); + + process_post(&serial_line_process, 0, 0); + + +Platform tutorial applications +----------------------------- +Example to read out various sensors, leds, serial numbers, and so on: +[platform/avr-rss2/examples/hello-sensors/](examples/hello-sensors/). + +The previous example uses the `sensd` data encoding. An example that uses UDP through 6lowpan is here: +[platform/avr-rss2/examples/ipv6/rpl-udp-report](examples/ipv6/rpl-udp-report). + +An Ethernet gateway with ip64 NAT, based on Contiki `core/net/ip64` code: +[platform/avr-rss2/examples/ipv6/rpl-border-router/](examples/ipv6/rpl-border-router/). + +Regressions tests +----------------- +Travis compile regression test for the platform: +[regression-tests/23-compile-avr](../../regression-tests/23-compile-avr). + +This port adds newer version of `avr-gcc` compiler (4.9.2), to support +testing of newer Atmel MCU as Atmega256RFR2. + + +Board approvals +--------------- +Summary: +* R&TTE 73/23/EEC, 89/336/EEC and 99/5/EC +* Safety: EN 60950-1:2006 + A12: 2011 +* RF: ETSI EN 300 328 V1.7.1 (2006-10) +* EMC: ETSI EN 301 489-1 V1.9.2 (2011-09), ETSI EN 301 489-17 V2.2.1 (2012-09) +* EMF: EN 62479:2010 +* Human exposure to electromagnetic fields: EN 62479:2010 + +Commercial availability +------------------------ +Through vendor and though resellers. Note board is will only available +were CE approval is covered. This may be further restricted by WEEE. +Contact vendor. For research legislation is more relaxed in most +countries. + +References +---------- +AtMega64/128/256/RFR2 chip documentation available via Atmel. +Schematics and boards description. Available via Radio-Senors +Smart Reduced Power Consumption Techniques. AT02594 available via Atmel. + +ToDo +----- +API for radio power saving settings introduced Atmels app note AT02594. +Also function for the desensitizing RPC resister. + +Vendor info +----------- +http://radio-sensors.com/ + +Maintainer +---------- +Robert Olsson diff --git a/platform/avr-rss2/apps/sniffer/Makefile b/platform/avr-rss2/apps/sniffer/Makefile new file mode 100644 index 000000000..63412a817 --- /dev/null +++ b/platform/avr-rss2/apps/sniffer/Makefile @@ -0,0 +1,11 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" +PROJECT_SOURCEFILES += stub-rdc.c + +CONTIKI_PROJECT = sniffer + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../../.. + +CONTIKI_WITH_RIME = 1 +include $(CONTIKI)/Makefile.include diff --git a/platform/avr-rss2/apps/sniffer/README.md b/platform/avr-rss2/apps/sniffer/README.md new file mode 100644 index 000000000..b9332893b --- /dev/null +++ b/platform/avr-rss2/apps/sniffer/README.md @@ -0,0 +1,29 @@ +Sniffer application mote side +============================= +This put the radio in sniff mode and should capure all traffic used +on the set channel. + +Default channel +--------------- +26 + +Bulld +----- +make TARGET=avr-rss2 + +Default serial port speed +------------------------- +38400 bps + +More info & uasage +------------------ +Look in the host directory + +Contiki support +--------------- +The code promisc for support is needed. This also adds the sensniff +format. + +References +---------- +https://github.com/g-oikonomou/sensniff diff --git a/examples/sensinode/energy-scan/project-conf.h b/platform/avr-rss2/apps/sniffer/project-conf.h similarity index 90% rename from examples/sensinode/energy-scan/project-conf.h rename to platform/avr-rss2/apps/sniffer/project-conf.h index 91c1917e4..d56b19e7d 100644 --- a/examples/sensinode/energy-scan/project-conf.h +++ b/platform/avr-rss2/apps/sniffer/project-conf.h @@ -33,18 +33,19 @@ * \file * Project specific configuration defines for the sniffer example. * - * We make sure that the radio driver outputs all packets in hexdump - * format. - * * \author * George Oikonomou - + * Robert Olsson - */ #ifndef PROJECT_CONF_H_ #define PROJECT_CONF_H_ + +#define NETSTACK_CONF_MAC nullmac_driver +/* Can see other channels. Interesting. */ +/* #define NETSTACK_CONF_MAC csma_driver */ #define NETSTACK_CONF_RDC stub_rdc_driver -#define ADC_SENSOR_CONF_ON 0 -#define LPM_CONF_MODE 0 + #endif /* PROJECT_CONF_H_ */ diff --git a/platform/avr-rss2/apps/sniffer/sniffer-example-coap.pcapng b/platform/avr-rss2/apps/sniffer/sniffer-example-coap.pcapng new file mode 100644 index 000000000..e69de29bb diff --git a/platform/avr-rss2/apps/sniffer/sniffer.c b/platform/avr-rss2/apps/sniffer/sniffer.c new file mode 100644 index 000000000..be572bce1 --- /dev/null +++ b/platform/avr-rss2/apps/sniffer/sniffer.c @@ -0,0 +1,67 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/* + Author: Robert Olsson +*/ + +#include "contiki.h" +#include "net/rime/rime.h" +#include "random.h" +#include "dev/button-sensor.h" +#include "dev/leds.h" +#include +/*---------------------------------------------------------------------------*/ + +PROCESS(sniffer_process, "Sniffer process"); +AUTOSTART_PROCESSES(&sniffer_process); + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(sniffer_process, ev, data) +{ + PROCESS_BEGIN(); + + /* + To get rf230bb radio in sniff mode we need to have radio in RX_ON. + The promisc commands fixes this for us. No need to set PAN and + address or MAC to zero is this case. Se Atmel datasheet. There is + a chance other radios works the same way. + */ + + rf230_set_promiscuous_mode(1); + + printf("Sniffer started\n"); + + while(1) { + PROCESS_YIELD(); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/sniffer/stub-rdc.c b/platform/avr-rss2/apps/sniffer/stub-rdc.c similarity index 100% rename from examples/sensinode/sniffer/stub-rdc.c rename to platform/avr-rss2/apps/sniffer/stub-rdc.c diff --git a/platform/avr-rss2/contiki-conf.h b/platform/avr-rss2/contiki-conf.h new file mode 100644 index 000000000..3e1f5dfc2 --- /dev/null +++ b/platform/avr-rss2/contiki-conf.h @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2006, Technical University of Munich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * @(#)$$ + */ + +/** + * \file + * Configuration for RSS2 (radio-sensors.com) platform + */ + +#ifndef CONTIKI_CONF_H_ +#define CONTIKI_CONF_H_ + +/* include the project config */ +/* PROJECT_CONF_H might be defined in the project Makefile */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif + +/* Platform name, type, and MCU clock rate */ +#define PLATFORM_NAME "rss2" +#define PLATFORM_TYPE ATMEGA256RFR2 +#ifndef F_CPU +#define F_CPU 8000000UL +#endif + +#include + +#ifndef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC csma_driver +#endif + +#ifndef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC contikimac_driver +#endif + +#ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 +#endif + +#ifndef NETSTACK_CONF_FRAMER +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_FRAMER contikimac_framer +#else +#define NETSTACK_CONF_FRAMER framer_802154 +#endif +#endif + +#ifndef NETSTACK_CONF_RADIO +#define NETSTACK_CONF_RADIO rf230_driver +#endif + +#ifndef CHANNEL_802_15_4 +#define CHANNEL_802_15_4 26 +#endif + +/* AUTOACK receive mode gives better rssi measurements, even if ACK is never requested */ +#ifndef RF230_CONF_AUTOACK +#define RF230_CONF_AUTOACK 1 +#endif + +#define MCUCSR MCUSR + +/* The AVR tick interrupt usually is done with an 8 bit counter around 128 Hz. + * 125 Hz needs slightly more overhead during the interrupt, as does a 32 bit + * clock_time_t. + */ +/* Clock ticks per second */ + +#define CLOCK_CONF_SECOND 128 +typedef unsigned long clock_time_t; +#define CLOCK_LT(a, b) ((signed long)((a) - (b)) < 0) +#define INFINITE_TIME 0xffffffff +/* These routines are not part of the contiki core but can be enabled in cpu/avr/clock.c */ +void clock_delay_msec(uint16_t howlong); +void clock_adjust_ticks(clock_time_t howmany); + +/* The radio needs to interrupt during an rtimer interrupt */ +#define RTIMER_CONF_NESTED_INTERRUPTS 1 + +/* RSS2 boards has a 32768Hz on TIMER2 */ +#define AVR_CONF_USE32KCRYSTAL 1 +#define SLIP_PORT RS232_PORT_0 + +/* Pre-allocated memory for loadable modules heap space (in bytes)*/ +/* Default is 4096. Currently used only when elfloader is present. Not tested on Raven */ +/* #define MMEM_CONF_SIZE 256 */ + +/* Starting address for code received via the codeprop facility. Not tested. */ +typedef unsigned long off_t; +/* #define EEPROMFS_ADDR_CODEPROP 0x8000 */ + +/* Logging adds 200 bytes to program size. RS232 output slows down webserver. */ +/* #define LOG_CONF_ENABLED 1 */ + +/* RADIOSTATS is used in rf230bb, clock.c and the webserver cgi to report radio usage */ +/* It has less overhead than ENERGEST */ +#define RADIOSTATS 1 + +/* More extensive stats, via main loop printfs or webserver status pages */ +#define ENERGEST_CONF_ON 1 + +/* Packet statistics */ +typedef unsigned short uip_stats_t; +#define UIP_STATISTICS 0 + +/* Available watchdog timeouts depend on mcu. Default is WDTO_2S. -1 Disables the watchdog. */ +/* AVR Studio simulator tends to reboot due to clocking the WD 8 times too fast */ +/* #define WATCHDOG_CONF_TIMEOUT -1 */ + +/* Debugflow macro, useful for tracing path through mac and radio interrupts */ +/* #define DEBUGFLOWSIZE 128 */ + +/* Define MAX_*X_POWER to reduce tx power and ignore weak rx packets for testing a miniature multihop network. + * Leave undefined for full power and sensitivity. + * tx=0 (3dbm, default) to 15 (-17.2dbm) + * RF230_CONF_AUTOACK sets the extended mode using the energy-detect register with rx=0 (-91dBm) to 84 (-7dBm) + * else the rssi register is used having range 0 (91dBm) to 28 (-10dBm) + * For simplicity RF230_MIN_RX_POWER is based on the energy-detect value and divided by 3 when autoack is not set. + * On the RF230 a reduced rx power threshold will not prevent autoack if enabled and requested. + * These numbers applied to both Raven and Jackdaw give a maximum communication distance of about 15 cm + * and a 10 meter range to a full-sensitivity RF230 sniffer. + *#define RF230_MAX_TX_POWER 15 + *#define RF230_MIN_RX_POWER 30 + */ +/* The rf231 and atmega128rfa1 can use an rssi threshold for triggering rx_busy that saves 0.5ma in rx mode */ +/* 1 - 15 maps into -90 to -48 dBm; the register is written with RF230_MIN_RX_POWER/6 + 1. Undefine for -100dBm sensitivity */ +/* #define RF230_MIN_RX_POWER 0 */ + +/* Network setup */ +/* TX routine passes the cca/ack result in the return parameter */ +#define RDC_CONF_HARDWARE_ACK 1 +/* TX routine does automatic cca and optional backoffs */ +#define RDC_CONF_HARDWARE_CSMA 1 +/* Allow MCU sleeping between channel checks */ +#define RDC_CONF_MCU_SLEEP 1 + +#if NETSTACK_CONF_WITH_IPV6 +#define LINKADDR_CONF_SIZE 8 +#define UIP_CONF_ICMP6 1 +#define UIP_CONF_UDP 1 +#ifndef UIP_CONF_TCP +#define UIP_CONF_TCP 1 +#endif +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#else +/* ip4 should build but is largely untested */ +#define LINKADDR_CONF_SIZE 2 +#define NETSTACK_CONF_NETWORK rime_driver +#endif + +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 + +/* 10 bytes per stateful address context - see sicslowpan.c */ +/* Default is 1 context with prefix aaaa::/64 */ +/* These must agree with all the other nodes or there will be a failure to communicate! */ +#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 +#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 { addr_contexts[0].prefix[0] = 0xaa; addr_contexts[0].prefix[1] = 0xaa; } +#define SICSLOWPAN_CONF_ADDR_CONTEXT_1 { addr_contexts[1].prefix[0] = 0xbb; addr_contexts[1].prefix[1] = 0xbb; } +#define SICSLOWPAN_CONF_ADDR_CONTEXT_2 { addr_contexts[2].prefix[0] = 0x20; addr_contexts[2].prefix[1] = 0x01; addr_contexts[2].prefix[2] = 0x49; addr_contexts[2].prefix[3] = 0x78, addr_contexts[2].prefix[4] = 0x1d; addr_contexts[2].prefix[5] = 0xb1; } + +/* Take the default TCP maximum segment size for efficiency and simpler wireshark captures */ +/* Use this to prevent 6LowPAN fragmentation (whether or not fragmentation is enabled) */ +/* #define UIP_CONF_TCP_MSS 48 */ + +#define UIP_CONF_IP_FORWARD 0 +#define UIP_CONF_FWCACHE_SIZE 0 + +#define UIP_CONF_IPV6_CHECKS 1 +#define UIP_CONF_IPV6_QUEUE_PKT 1 +#define UIP_CONF_IPV6_REASSEMBLY 0 + +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_TCP_SPLIT 1 +#define UIP_CONF_DHCP_LIGHT 1 + +#if 0 /* No radio cycling */ + +#define NETSTACK_CONF_MAC nullmac_driver +#define NETSTACK_CONF_RDC sicslowmac_driver +#define NETSTACK_CONF_FRAMER framer_802154 +/* 1 + Number of auto retry attempts 0-15 (0 implies don't use extended TX_ARET_ON mode) */ +#define RF230_CONF_FRAME_RETRIES 2 +/* Number of csma retry attempts 0-5 in extended tx mode (7 does immediate tx with no csma) */ +#define RF230_CONF_CSMA_RETRIES 5 +/* Default is one RAM buffer for received packets. More than one may benefit multiple TCP connections or ports */ +#define RF230_CONF_RX_BUFFERS 3 +#define SICSLOWPAN_CONF_FRAG 1 +/* Most browsers reissue GETs after 3 seconds which stops fragment reassembly so a longer MAXAGE does no good */ +#define SICSLOWPAN_CONF_MAXAGE 3 +/* How long to wait before terminating an idle TCP connection. Smaller to allow faster sleep. Default is 120 seconds */ +/* If wait is too short the connection can be reset as a result of multiple fragment reassembly timeouts */ +#define UIP_CONF_WAIT_TIMEOUT 20 +/* 54 bytes per queue ref buffer */ +#define QUEUEBUF_CONF_REF_NUM 2 +/* Allocate remaining RAM as desired */ +/* 30 bytes per TCP connection */ +/* 6LoWPAN does not do well with concurrent TCP streams, as new browser GETs collide with packets coming */ +/* from previous GETs, causing decreased throughput, retransmissions, and timeouts. Increase to study this. */ +/* ACKs to other ports become interleaved with computation-intensive GETs, so ACKs are particularly missed. */ +/* Increasing the number of packet receive buffers in RAM helps to keep ACKs from being lost */ +#define UIP_CONF_MAX_CONNECTIONS 4 +/* 2 bytes per TCP listening port */ +#define UIP_CONF_MAX_LISTENPORTS 4 +/* 25 bytes per UDP connection */ +#define UIP_CONF_UDP_CONNS 10 +/* See uip-ds6.h */ +#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#define UIP_CONF_DS6_DEFRT_NBU 2 +#define UIP_CONF_DS6_PREFIX_NBU 3 +#define UIP_CONF_MAX_ROUTES 20 +#define UIP_CONF_DS6_ADDR_NBU 3 +#define UIP_CONF_DS6_MADDR_NBU 0 +#define UIP_CONF_DS6_AADDR_NBU 0 + +#elif 1 /* Contiki-mac radio cycling */ +/* #define NETSTACK_CONF_MAC nullmac_driver */ +/* csma needed for burst mode at present. Webserver won't work without it */ +/* #define NETSTACK_CONF_MAC csma_driver */ +/* #define NETSTACK_CONF_RDC contikimac_driver */ +/* Default is two CCA separated by 500 usec */ + +/* So without the header this needed for RPL mesh to form */ +#define CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE (43 - 18) /* multicast RPL DIS length */ +/* Not tested much yet */ +#define CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION 0 +#define CONTIKIMAC_CONF_COMPOWER 1 +#define RIMESTATS_CONF_ENABLED 0 + +/* A 0 here means non-extended mode; 1 means extended mode with no retry, >1 for retrys */ +/* Contikimac strobes on its own, but hardware retries are faster */ +#define RF230_CONF_FRAME_RETRIES 1 +/* Long csma backoffs will compromise radio cycling; set to 0 for 1 csma */ +#define RF230_CONF_CSMA_RETRIES 0 +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 3 +/* 54 bytes per queue ref buffer */ +#define QUEUEBUF_CONF_REF_NUM 2 +/* Allocate remaining RAM. Not much left due to queuebuf increase */ +#define UIP_CONF_MAX_CONNECTIONS 2 +#define UIP_CONF_MAX_LISTENPORTS 4 +#define UIP_CONF_UDP_CONNS 5 +#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#define UIP_CONF_DS6_DEFRT_NBU 2 +#define UIP_CONF_DS6_PREFIX_NBU 3 +#define UIP_CONF_MAX_ROUTES 4 +#define UIP_CONF_DS6_ADDR_NBU 3 +#define UIP_CONF_DS6_MADDR_NBU 0 +#define UIP_CONF_DS6_AADDR_NBU 0 + +#elif 0 /* cx-mac radio cycling */ +/* RF230 does clear-channel assessment in extended mode (autoretries>0) */ +/* These values are guesses */ +#define RF230_CONF_FRAME_RETRIES 10 +#define RF230_CONF_CSMA_RETRIES 2 +#if RF230_CONF_CSMA_RETRIES +#define NETSTACK_CONF_MAC nullmac_driver +#else +#define NETSTACK_CONF_MAC csma_driver +#endif +#define NETSTACK_CONF_RDC cxmac_driver +#define NETSTACK_CONF_FRAMER framer_802154 +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 3 +#define CXMAC_CONF_ANNOUNCEMENTS 0 +/* 54 bytes per queue ref buffer */ +#define QUEUEBUF_CONF_REF_NUM 2 +/* Allocate remaining RAM. Not much left due to queuebuf increase */ +#define UIP_CONF_MAX_CONNECTIONS 2 +#define UIP_CONF_MAX_LISTENPORTS 4 +#define UIP_CONF_UDP_CONNS 5 +#define NBR_TABLE_CONF_MAX_NEIGHBORS 4 +#define UIP_CONF_DS6_DEFRT_NBU 2 +#define UIP_CONF_DS6_PREFIX_NBU 3 +#define UIP_CONF_MAX_ROUTES 4 +#define UIP_CONF_DS6_ADDR_NBU 3 +#define UIP_CONF_DS6_MADDR_NBU 0 +#define UIP_CONF_DS6_AADDR_NBU 0 +/* Below gives 10% duty cycle, undef for default 5% */ +/* #define CXMAC_CONF_ON_TIME (RTIMER_ARCH_SECOND / 80) */ +/* Below gives 50% duty cycle */ +/* #define CXMAC_CONF_ON_TIME (RTIMER_ARCH_SECOND / 16) */ + +#else +/* #error Network configuration not specified! */ +#endif /* Network setup */ + +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 15 +#endif + +/* ************************************************************************** */ +/* #pragma mark RPL Settings */ +/* ************************************************************************** */ +#if UIP_CONF_IPV6_RPL + +#define UIP_CONF_ROUTER 1 +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +/* For slow slip connections, to prevent buffer overruns */ +/* #define UIP_CONF_RECEIVE_WINDOW 300 */ +#undef UIP_CONF_FWCACHE_SIZE +#define UIP_CONF_BUFFER_SIZE 600 /* DHCPv4 packets by ip64 module */ +#define UIP_CONF_FWCACHE_SIZE 30 +#define UIP_CONF_BROADCAST 1 +#define UIP_ARCH_IPCHKSUM 1 +#define UIP_CONF_PINGADDRCONF 0 +#define UIP_CONF_LOGGING 0 + +#endif /* RPL */ + +#define CCIF +#define CLIF +#ifndef CC_CONF_INLINE +#define CC_CONF_INLINE inline +#endif + +#endif /* CONTIKI_CONF_H_ */ diff --git a/platform/avr-rss2/contiki-main.c b/platform/avr-rss2/contiki-main.c new file mode 100644 index 000000000..8abac4d04 --- /dev/null +++ b/platform/avr-rss2/contiki-main.c @@ -0,0 +1,640 @@ +/* + * Copyright (c) 2006, Technical University of Munich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * Reworked for avr-rss2 platform. Robert Olsson + */ + +#define PRINTF(FORMAT, args ...) printf_P(PSTR(FORMAT),##args) + +#define ANNOUNCE_BOOT 1 /* adds about 600 bytes to program size */ +#if ANNOUNCE_BOOT +#define PRINTA(FORMAT, args ...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTA(...) +#endif + +#define DEBUG 0 +#if DEBUG +#define PRINTD(FORMAT, args ...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTD(...) +#endif + +#include +#include +#include +#include +#include +#include + +#include "loader/symbols-def.h" +#include "loader/symtab.h" + +#include "params.h" +#include "rss2.h" +#include "leds.h" +#include "i2c.h" +#include "radio/rf230bb/rf230bb.h" +#include "net/mac/frame802154.h" +#include "net/mac/framer-802154.h" +#include "net/ipv6/sicslowpan.h" + +#include "contiki.h" +#include "contiki-net.h" +#include "contiki-lib.h" + +#include "dev/rs232.h" +#include "dev/serial-line.h" +#include "dev/slip.h" + +#if AVR_WEBSERVER +#include "httpd-fs.h" +#include "httpd-cgi.h" +#endif + +#ifdef COFFEE_FILES +#include "cfs/cfs.h" +#include "cfs/cfs-coffee.h" +#endif + +#if UIP_CONF_ROUTER && 0 +#include "net/routing/rimeroute.h" +#include "net/rime/rime-udp.h" +#endif + +#include "net/rime/rime.h" + +/* Track interrupt flow through mac, rdc and radio driver */ +/* #define DEBUGFLOWSIZE 32 */ +#if DEBUGFLOWSIZE +uint8_t debugflowsize, debugflow[DEBUGFLOWSIZE]; +#define DEBUGFLOW(c) if(debugflowsize < (DEBUGFLOWSIZE - 1)) debugflow[debugflowsize++] = c +#else +#define DEBUGFLOW(c) +#endif + +/* Get periodic prints from idle loop, from clock seconds or rtimer interrupts */ +/* Use of rtimer will conflict with other rtimer interrupts such as contikimac radio cycling */ +/* STAMPS will print ENERGEST outputs if that is enabled. */ +#define PERIODICPRINTS 1 +#if PERIODICPRINTS +/* #define PINGS 64 */ +#define ROUTES 600 +#define STAMPS 60 +#define STACKMONITOR 1024 +uint32_t clocktime; +#define TESTRTIMER 0 +#if TESTRTIMER +uint8_t rtimerflag = 1; +struct rtimer rt; +void +rtimercycle(void) +{ + rtimerflag = 1; +} +#endif +#endif + +uint16_t node_id; /* Can be set by cooja */ + +uint16_t ledtimer_red, ledtimer_yellow; +uint16_t i2c_probed; /* i2c devices we have probed */ + + +/*-------------------------------------------------------------------------*/ +/*----------------------Configuration of the .elf file---------------------*/ +#if 1 +/* The proper way to set the signature is */ +#include +#else +/* Older avr-gcc's may not define the needed SIGNATURE bytes. Do it manually if you get an error */ +typedef struct {const unsigned char B2; + const unsigned char B1; + const unsigned char B0; +} __signature_t; +#define SIGNATURE __signature_t __signature __attribute__((section(".signature"))) +SIGNATURE = { + .B2 = 0x01, /* SIGNATURE_2, //ATMEGA128rfa1 */ + .B1 = 0xA7, /* SIGNATURE_1, //128KB flash */ + .B0 = 0x1E, /* SIGNATURE_0, //Atmel */ +}; +#endif + +#if 1 +/* JTAG, SPI enabled, Internal RC osc, Boot flash size 4K, 6CK+65msec delay, brownout disabled */ +FUSES = { .low = 0xe2, .high = 0x99, .extended = 0xff, }; +#else +/* JTAG+SPI, Boot 4096 words @ $F000, Internal oscillator, startup 6 CK +0 ms, Brownout 1.8 volts */ +FUSES = { .low = 0xC2, .high = 0x99, .extended = 0xfe, }; +#endif + +uint8_t +rng_get_uint8(void) +{ +#if 1 + /* Upper two RSSI reg bits (RND_VALUE) are random in rf231 */ + uint8_t j; + j = (PHY_RSSI & 0xc0) + ((PHY_RSSI >> 2) & 0x30) + ((PHY_RSSI >> 4) & 0x0c) + ((PHY_RSSI >> 6) & 0x03); +#else +/* Get a pseudo random number using the ADC */ + uint8_t i, j; + ADCSRA = 1 << ADEN; /* Enable ADC, not free running, interrupt disabled, fastest clock */ + for(i = 0; i < 4; i++) { + ADMUX = 0; /* toggle reference to increase noise */ + ADMUX = 0x1E; /* Select AREF as reference, measure 1.1 volt bandgap reference. */ + ADCSRA |= 1 << ADSC; /* Start conversion */ + while(ADCSRA & (1 << ADSC)) ; /* Wait till done */ + j = (j << 2) + ADC; + } + ADCSRA = 0; /* Disable ADC */ +#endif + PRINTD("rng issues %d\n", j); + return j; +} +/*-------------------------Low level initialization------------------------*/ +/*------Done in a subroutine to keep main routine stack usage small--------*/ +void +initialize(void) +{ + watchdog_init(); + watchdog_start(); + leds_init(); + serial_line_init(); + + rs232_init(RS232_PORT_0, USART_BAUD_38400, USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); + rs232_redirect_stdout(RS232_PORT_0); + +#if 0 + /* Do it my way... */ + //UBRR0L = 8; UBRR0H = 0; UCSR0A = (0 << U2X0); // 115.2k err=-3.5% + //UBRR0L = 16; UBRR0H = 0; UCSR0A = (1 << U2X0); // 115.2k 2.1% + //UBRR0L = 3; UBRR0H = 0; UCSR0A = (1 << U2X0); // 500k 0% +#endif + + rs232_set_input(RS232_PORT_0, serial_line_input_byte); + + clock_init(); + + if(MCUSR & (1 << PORF)) { + PRINTD("Power-on reset.\n"); + } + if(MCUSR & (1 << EXTRF)) { + PRINTD("External reset!\n"); + } + if(MCUSR & (1 << BORF)) { + PRINTD("Brownout reset!\n"); + } + if(MCUSR & (1 << WDRF)) { + PRINTD("Watchdog reset!\n"); + } + if(MCUSR & (1 << JTRF)) { + PRINTD("JTAG reset!\n"); + } + + i2c_init(100000); /* 100 bit/s */ + +#if STACKMONITOR + /* Simple stack pointer highwater monitor. Checks for magic numbers in the main + * loop. In conjuction with PERIODICPRINTS, never-used stack will be printed + * every STACKMONITOR seconds. + */ + { + extern uint16_t __bss_end; + uint16_t p = (uint16_t)&__bss_end; + do { + *(uint16_t *)p = 0x4242; + p += 10; + } while(p < SP - 10); /* don't overwrite our own stack */ + } +#endif + +#define CONF_CALIBRATE_OSCCAL 0 +#if CONF_CALIBRATE_OSCCAL + void calibrate_rc_osc_32k(); + { + extern uint8_t osccal_calibrated; + uint8_t i; + PRINTD("\nBefore calibration OSCCAL=%x\n", OSCCAL); + for(i = 0; i < 10; i++) { + calibrate_rc_osc_32k(); + PRINTD("Calibrated=%x\n", osccal_calibrated); +/* #include */ +/* #define delay_us( us ) ( _delay_loop_2(1+(us*F_CPU)/4000000UL) ) */ +/* delay_us(50000); */ + } + clock_init(); + } +#endif + + PRINTA("\n*******Booting %s*******\n", CONTIKI_VERSION_STRING); + +/* rtimers needed for radio cycling */ + rtimer_init(); + + /* Initialize process subsystem */ + process_init(); + + /* etimers must be started before ctimer_init */ + process_start(&etimer_process, NULL); + ctimer_init(); + + /* Start radio and radio receive process */ + NETSTACK_RADIO.init(); + +/* Get a random seed for the 802.15.4 packet sequence number. + * Some layers will ignore duplicates found in a history (e.g. Contikimac) + * causing the initial packets to be ignored after a short-cycle restart. + */ + random_init(rng_get_uint8()); + + /* Set addresses BEFORE starting tcpip process */ + + linkaddr_t addr; + char eui64[8]; + + printf("I2C: "); + i2c_probed = i2c_probe(); + printf("\n"); + + if( i2c_probed & I2C_AT24MAC ) { + i2c_at24mac_read((char *)&eui64, 1); + linkaddr_set_node_addr((linkaddr_t *) &eui64); + node_id = (eui64[1] << 8) + eui64[7]; + } + else { + printf("Random EUI64 address generated\n"); + eui64[0] = 0xfc; /* Atmels OUI */ + eui64[1] = 0xc2; + eui64[2] = 0x3d; + eui64[3] = 0; + eui64[4] = 0; + eui64[5] = 0; + eui64[6] = node_id >> 8; + eui64[7] = node_id & 0xff; + linkaddr_set_node_addr((linkaddr_t *)&eui64); + } + + /* memcpy(&uip_lladdr.addr, &addr.u8, sizeof(linkaddr_t)); */ + +#if NETSTACK_CONF_WITH_IPV6 + memcpy(&addr.u8, &eui64, sizeof(linkaddr_t)); + memcpy(&uip_lladdr.addr, &addr.u8, sizeof(linkaddr_t)); +#endif + + rf230_set_pan_addr(params_get_panid(), params_get_panaddr(), (uint8_t *)&addr.u8); + rf230_set_channel(params_get_channel()); + rf230_set_txpower(params_get_txpower()); + +#if NETSTACK_CONF_WITH_IPV6 + PRINTA("EUI-64 MAC: %x-%x-%x-%x-%x-%x-%x-%x\n", addr.u8[0], addr.u8[1], addr.u8[2], addr.u8[3], addr.u8[4], addr.u8[5], addr.u8[6], addr.u8[7]); +#else + PRINTA("MAC address "); + uint8_t i; + addr.u8[0] = eui64[1] ; + addr.u8[1] = eui64[7]; + + for(i = sizeof(linkaddr_t); i > 0; i--) { + PRINTA("%x:", addr.u8[i - 1]); + } + PRINTA("\n"); +#endif + + /* Initialize stack protocols */ + queuebuf_init(); + NETSTACK_RDC.init(); + NETSTACK_MAC.init(); + NETSTACK_NETWORK.init(); + +#if ANNOUNCE_BOOT + PRINTA("MAC=%s, RDC=%s, NETWORK=%s, channel=%-u, check-rate-Hz=%-u, tx-power=%-u\n", NETSTACK_MAC.name, + NETSTACK_RDC.name, NETSTACK_NETWORK.name, rf230_get_channel(), + CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1 : NETSTACK_RDC.channel_check_interval()), + rf230_get_txpower()); +#if UIP_CONF_IPV6_RPL + PRINTA("RPL Enabled\n"); +#endif +#if UIP_CONF_ROUTER + PRINTA("Routing Enabled\n"); +#endif + +#endif /* ANNOUNCE_BOOT */ + +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 + process_start(&tcpip_process, NULL); +#endif + + /* Autostart other processes */ + autostart_start(autostart_processes); + + /*---If using coffee file system create initial web content if necessary---*/ +#if COFFEE_FILES + int fa = cfs_open("/index.html", CFS_READ); + if(fa < 0) { /* Make some default web content */ + PRINTA("No index.html file found, creating upload.html!\n"); + PRINTA("Formatting FLASH file system for coffee..."); + cfs_coffee_format(); + PRINTA("Done!\n"); + fa = cfs_open("/index.html", CFS_WRITE); + int r = cfs_write(fa, &"It works!", 9); + if(r < 0) { + PRINTA("Can''t create /index.html!\n"); + } + cfs_close(fa); +/* fa = cfs_open("upload.html"), CFW_WRITE); */ +/*
    */ + } +#endif /* COFFEE_FILES */ + +/* Add addresses for testing */ +#if 0 + { + uip_ip6addr_t ipaddr; + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); +/* uip_ds6_prefix_add(&ipaddr,64,0); */ + } +#endif +/*--------------------------Announce the configuration---------------------*/ +#if ANNOUNCE_BOOT +#if AVR_WEBSERVER + { uint8_t i; + char buf[80]; + unsigned int size; + + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + if(uip_ds6_if.addr_list[i].isused) { + httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr, buf); + PRINTA("IPv6 Address: %s\n", buf); + } + } + cli(); + eeprom_read_block(buf, eemem_server_name, sizeof(eemem_server_name)); + sei(); + buf[sizeof(eemem_server_name)] = 0; + PRINTA("%s", buf); + cli(); + eeprom_read_block(buf, eemem_domain_name, sizeof(eemem_domain_name)); + sei(); + buf[sizeof(eemem_domain_name)] = 0; + size = httpd_fs_get_size(); +#ifndef COFFEE_FILES + PRINTA(".%s online with fixed %u byte web content\n", buf, size); +#elif COFFEE_FILES == 1 + PRINTA(".%s online with static %u byte EEPROM file system\n", buf, size); +#elif COFFEE_FILES == 2 + PRINTA(".%s online with dynamic %u KB EEPROM file system\n", buf, size >> 10); +#elif COFFEE_FILES == 3 + PRINTA(".%s online with static %u byte program memory file system\n", buf, size); +#elif COFFEE_FILES == 4 + PRINTA(".%s online with dynamic %u KB program memory file system\n", buf, size >> 10); +#endif /* COFFEE_FILES */ + } +#else + PRINTA("Online\n"); +#endif +#endif /* ANNOUNCE_BOOT */ + + ledtimer_red = 1000; + leds_on(LEDS_RED); +} + + +#if ROUTES && NETSTACK_CONF_WITH_IPV6 +static void +ipaddr_add(const uip_ipaddr_t *addr) +{ + uint16_t a; + int8_t i, f; + for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { + a = (addr->u8[i] << 8) + addr->u8[i + 1]; + if(a == 0 && f >= 0) { + if(f++ == 0) { + PRINTF("::"); + } + } else { + if(f > 0) { + f = -1; + } else if(i > 0) { + PRINTF(":"); + } + PRINTF("%x", a); + } + } +} +#endif +/*-------------------------------------------------------------------------*/ +/*------------------------- Main Scheduler loop----------------------------*/ +/*-------------------------------------------------------------------------*/ +int +main(void) +{ +#if NETSTACK_CONF_WITH_IPV6 + uip_ds6_nbr_t *nbr; +#endif /* NETSTACK_CONF_WITH_IPV6 */ + initialize(); + + while(1) { + process_run(); + watchdog_periodic(); + + /* Turn off LED's */ + if(ledtimer_red) { + if(--ledtimer_red == 0) { + leds_off(LEDS_RED); + } + } + if(ledtimer_yellow) { + if(--ledtimer_yellow == 0) { + leds_off(LEDS_YELLOW); + } + } + leds_off(LEDS_RED); + leds_off(LEDS_YELLOW); + +#if 0 +/* Various entry points for debugging in the AVR Studio simulator. + * Set as next statement and step into the routine. + */ + NETSTACK_RADIO.send(packetbuf_hdrptr(), 42); + process_poll(&rf230_process); + packetbuf_clear(); + len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE); + packetbuf_set_datalen(42); + NETSTACK_RDC.input(); +#endif + +#if 0 +/* Clock.c can trigger a periodic PLL calibration in the RF230BB driver. + * This can show when that happens. + */ + extern uint8_t rf230_calibrated; + if(rf230_calibrated) { + PRINTD("\nRF230 calibrated!\n"); + rf230_calibrated = 0; + } +#endif + +/* Set DEBUGFLOWSIZE in contiki-conf.h to track path through MAC, RDC, and RADIO */ +#if DEBUGFLOWSIZE + if(debugflowsize) { + debugflow[debugflowsize] = 0; + PRINTF("%s", debugflow); + debugflowsize = 0; + } +#endif + +#if PERIODICPRINTS +#if TESTRTIMER +/* Timeout can be increased up to 8 seconds maximum. + * A one second cycle is convenient for triggering the various debug printouts. + * The triggers are staggered to avoid printing everything at once. + */ + if(rtimerflag) { + rtimer_set(&rt, RTIMER_NOW() + RTIMER_ARCH_SECOND * 1UL, 1, (void *)rtimercycle, NULL); + rtimerflag = 0; +#else + if(clocktime != clock_seconds()) { + clocktime = clock_seconds(); +#endif + +#if STAMPS + if((clocktime % STAMPS) == 0) { +#if ENERGEST_CONF_ON +#include "lib/print-stats.h" + print_stats(); +#elif RADIOSTATS + extern volatile unsigned long radioontime; + PRINTF("%u(%u)s\n", clocktime, radioontime); +#else + PRINTF("%us\n", clocktime); +#endif + } +#endif +#if TESTRTIMER + clocktime += 1; +#endif + +#if PINGS && NETSTACK_CONF_WITH_IPV6 + extern void raven_ping6(void); + if((clocktime % PINGS) == 1) { + PRINTF("**Ping\n"); + raven_ping6(); + } +#endif + +#if ROUTES && NETSTACK_CONF_WITH_IPV6 + if((clocktime % ROUTES) == 2) { + + extern uip_ds6_netif_t uip_ds6_if; + + uint8_t i, j; + PRINTF("\nAddresses [%u max]\n", UIP_DS6_ADDR_NB); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + if(uip_ds6_if.addr_list[i].isused) { + ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr); + PRINTF("\n"); + } + } + PRINTF("\nNeighbors [%u max]\n", NBR_TABLE_MAX_NEIGHBORS); + j = 0; + for(nbr = nbr_table_head(ds6_neighbors); + nbr != NULL; + nbr = nbr_table_next(ds6_neighbors, nbr)) { + ipaddr_add(&nbr->ipaddr); + PRINTF("\n"); + j++; + } + if(!j) { + PRINTF(" "); + } + PRINTF("\nRoutes [%u max]\n", UIP_DS6_ROUTE_NB); + { + uip_ds6_route_t *r; + j = 0; + for(r = uip_ds6_route_head(); + r != NULL; + r = uip_ds6_route_next(r)) { + ipaddr_add(&r->ipaddr); + PRINTF("/%u (via ", r->length); + ipaddr_add(uip_ds6_route_nexthop(r)); + PRINTF(") %lus\n", r->state.lifetime); + j++; + } + } + if(!j) { + PRINTF(" "); + } + PRINTF("\n---------\n"); + } +#endif + +#if STACKMONITOR + if((clocktime % STACKMONITOR) == 3) { + extern uint16_t __bss_end; + uint16_t p = (uint16_t)&__bss_end; + do { + if(*(uint16_t *)p != 0x4242) { + PRINTF("Never-used stack > %d bytes\n", p - (uint16_t)&__bss_end); + break; + } + p += 10; + } while(p < RAMEND - 10); + } +#endif + } +#endif /* PERIODICPRINTS */ + +#if RF230BB && 0 + extern uint8_t rf230processflag; + if(rf230processflag) { + PRINTF("rf230p%d", rf230processflag); + rf230processflag = 0; + } +#endif + +#if RF230BB && 0 + extern uint8_t rf230_interrupt_flag; + if(rf230_interrupt_flag) { + /* if (rf230_interrupt_flag!=11) { */ + PRINTF("**RI%u", rf230_interrupt_flag); + /* } */ + rf230_interrupt_flag = 0; + } +#endif + } + return 0; +} +/*---------------------------------------------------------------------------*/ + +void +log_message(char *m1, char *m2) +{ + PRINTF("%s%s\n", m1, m2); +} diff --git a/platform/avr-rss2/dev/adc.c b/platform/avr-rss2/dev/adc.c new file mode 100644 index 000000000..cb82d16b7 --- /dev/null +++ b/platform/avr-rss2/dev/adc.c @@ -0,0 +1,76 @@ +/* Copyright Robert Olsson */ + +#include +#include +#include +#include +#include +#include +#include "params.h" +#include "rss2.h" +#include "contiki.h" +#include "adc.h" +#include "rss2.h" + +uint16_t +adc_read(uint8_t pin) +{ + uint16_t volt = 0; + int i; + + ADMUX = pin; /* ADC pin PA0-PA7 -> 0-7 */ + ADCSRB &= ~(1 << MUX5); /* Needs to write before ADMUX pp 418 */ + ADMUX |= (1 << REFS1) | (1 << REFS0); /* 1.6 */ + + /* Maximal Track and Hold time */ + + ADCSRA = (1 << ADPS2) | (0 << ADPS1) | (1 << ADPS0); /* Prescaler /32 */ + ADCSRA |= (1 << ADEN); /* Enable the ADC */ + + while(!(ADCSRB & (1 << AVDDOK))) ; /* Wait for AVDD ok */ + while(!(ADCSRB & (1 << REFOK))) ; /* Wait for ref ok */ + + /* Ignore first result */ + + ADCSRA |= (1 << ADSC); + while(ADCSRA & _BV(ADSC)) { + } + + ADCW = 0; +#define RES 4 + + for(i = 0; i < RES; i++) { + + /* Start the conversion */ + ADCSRA |= (1 << ADSC); + + /* Wait for conversion */ + while(ADCSRA & (1 << ADSC)) { + } + + volt += ADCW; + } + ADMUX = 0; /* turn off internal vref */ + volt = volt / RES; + + /* Disable the ADC to save power */ + ADCSRA &= ~_BV(ADEN); + + return volt; +} +double +adc_read_v_in(void) +{ + /* Special treatment for v_in. Schottky voltage drop add */ + return ((double)adc_read(AV_IN)) * V_IN_FACTOR_SCHOTTKY + SCHOTTKY_DROP; +} +double +adc_read_a1(void) +{ + return ((double)adc_read(A1)) * V_IN_FACTOR; +} +double +adc_read_a2(void) +{ + return ((double)adc_read(A2)) * V_IN_FACTOR; +} diff --git a/platform/avr-rss2/dev/adc.h b/platform/avr-rss2/dev/adc.h new file mode 100644 index 000000000..9e9473e31 --- /dev/null +++ b/platform/avr-rss2/dev/adc.h @@ -0,0 +1,16 @@ +/* Copyright Robert Olsson */ + +#define V_IN_FACTOR 0.006256 /* 6.4/1023 */ +#define V_IN_FACTOR_NONE 0.001564 /* 1.6/1023 */ +#define SCHOTTKY_DROP 0.29 +#define V_IN_FACTOR_SCHOTTKY 0.0292 /* 30.19-SCHOTTKY_DROP/1023 schottky corr */ + +uint16_t +adc_read(uint8_t pin); +double +adc_read_v_in(void); +double +adc_read_a1(void); +double +adc_read_a2(void); + diff --git a/platform/avr-rss2/dev/battery-sensor.c b/platform/avr-rss2/dev/battery-sensor.c new file mode 100644 index 000000000..b81db95f6 --- /dev/null +++ b/platform/avr-rss2/dev/battery-sensor.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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 ADVISE OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * ----------------------------------------------------------------- + * + * Author : Dag Björklund, Robert Olsson + * Created : 2005-11-01 + * Updated : $Date: 2010/08/25 19:30:52 $ + * $Revision: 1.11 $ + */ + +#include "contiki.h" +#include "dev/battery-sensor.h" +#include +#define delay_us(us) (_delay_loop_2(1 + (us * F_CPU) / 4000000UL)) + +const struct sensors_sensor battery_sensor; + +/* Returns the MCU voltage in mV read from the BATMON MCU register + * See AtMega chip docs for BATMON details. + */ + +static int +value(int type) +{ + uint16_t mv; + int i; + /* Resolution is 75mV if V>=2.55V; and 50mV if V<=2.45V */ + mv = 3675; + + for(i = 0x1f; 1; i--) { + + BATMON = i; + delay_us(100); + if(BATMON & 0x20) { + break; + } + + if(i == 0x10) { /* Range hi or lo */ + mv = 2500; + } + if(i > 0x10) { + mv -= 75; + } else { + mv -= 50; + } + } + return (int)((float)mv); +} +static int +configure(int type, int c) +{ + return 0; +} +static int +status(int type) +{ + return 1; +} +SENSORS_SENSOR(battery_sensor, BATTERY_SENSOR, value, configure, status); + diff --git a/platform/avr-rss2/dev/button-sensor.c b/platform/avr-rss2/dev/button-sensor.c new file mode 100644 index 000000000..664278993 --- /dev/null +++ b/platform/avr-rss2/dev/button-sensor.c @@ -0,0 +1,41 @@ +/* Dummy sensor routine */ + +#include "lib/sensors.h" +#include "dev/button-sensor.h" +const struct sensors_sensor button_sensor; +static int status(int type); +struct sensors_sensor *sensors[1]; +unsigned char sensors_flags[1]; + +static int +value(int type) +{ + return 0; +} +static int +configure(int type, int c) +{ + switch(type) { + case SENSORS_ACTIVE: + if(c) { + if(!status(SENSORS_ACTIVE)) { + } + } else { + } + return 1; + } + return 0; +} +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return 1; + } + return 0; +} +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, + value, configure, status); + diff --git a/platform/avr-rss2/dev/co2_sa_kxx-sensor.c b/platform/avr-rss2/dev/co2_sa_kxx-sensor.c new file mode 100644 index 000000000..564f8c011 --- /dev/null +++ b/platform/avr-rss2/dev/co2_sa_kxx-sensor.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2015, Copyright Markus Hidell, Robert Olsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * + * Authors : Markus Hidell, Robert Olsson {mahidell, roolss} @kth.se + * Created : 2015-10-27 + * Updated : $Date: 2010/01/14 20:23:02 $ + * $Revision: 1.2 $ + */ + +#include "contiki.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dev/watchdog.h" +#include "lib/list.h" +#include "lib/memb.h" +#include "co2_sa_kxx-sensor.h" + +static int +status(int type) +{ + return 0; +} +static int +configure(int type, int c) +{ + return 0; +} +static int +value(int var) +{ + int val, status; + uint8_t buf[2], csum; + int16_t res; + (void) status; + (void) csum; + + res = 0; + i2c_start_wait(I2C_CO2SA_ADDR | I2C_WRITE); + if(res) { + goto err; + } + + i2c_write(0x22); + i2c_write(0x00); + + if(var == CO2_SA_KXX_CO2) { + i2c_write(0x08); + i2c_write(0x2A); + } + + if(var == CO2_SA_KXX_TEMP) { + i2c_write(0x12); + i2c_write(0x34); + } + + if(var == CO2_SA_KXX_RH) { + i2c_write(0x14); + i2c_write(0x36); + } + + i2c_stop(); + + if(res) { + goto err; + } + + clock_delay_msec(20); + + res = 0; + i2c_start(I2C_CO2SA_ADDR | I2C_READ); + + if(res) { + goto err; + } + + + status = i2c_readAck(); + + if((status & 0x01) == 0) + goto err; + + buf[0] = i2c_readAck(); + buf[1] = i2c_readAck(); + csum = i2c_readNak(); + i2c_stop(); + + val = ((int16_t)(buf[0] << 8)) | buf[1]; + + return val; + +err: + i2c_stop(); + return 0; +} +SENSORS_SENSOR(co2_sa_kxx_sensor, "CO2", value, configure, status); diff --git a/platform/sensinode/debug.h b/platform/avr-rss2/dev/co2_sa_kxx-sensor.h similarity index 75% rename from platform/sensinode/debug.h rename to platform/avr-rss2/dev/co2_sa_kxx-sensor.h index 94eaa4f51..bdb366fea 100644 --- a/platform/sensinode/debug.h +++ b/platform/avr-rss2/dev/co2_sa_kxx-sensor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Swedish Institute of Computer Science + * Copyright (c) 2015, Copyright Markus Hidell, Robert Olsson * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,28 +28,24 @@ * * This file is part of the Contiki operating system. * + * + * Authors : Markus Hidell, Robert Olsson {mahidell, roolss} @kth.se + * Created : 2015-10-27 + * Updated : $Date: 2010/01/14 20:23:02 $ + * $Revision: 1.2 $ */ -/** - * \file - * Header file for debugging functions used by the sensinode port. - * - * putstring() and puthex() are from msp430/watchdog.c - * - * \author - * George Oikonomou - - */ +#ifndef CO2_SA_KXX_SENSOR_H_ +#define CO2_SA_KXX_SENSOR_H_ -#ifndef DEBUG_H_ -#define DEBUG_H_ +#define CO2_SA_KXX_CO2 0 +#define CO2_SA_KXX_TEMP 1 +#define CO2_SA_KXX_RH 3 -#include "8051def.h" -#include "dev/uart1.h" +#include "lib/sensors.h" -void putchar(char c); -void putstring(char *s); -void puthex(uint8_t c); -void putbin(uint8_t c); -void putdec(uint8_t c); +extern const struct sensors_sensor co2_sa_kxx_sensor; -#endif /* DEBUG_H_ */ +#define I2C_CO2SA_ADDR (0x68 << 1) + +#endif /* CO2_SA_KXX-SENSOR_H_ */ diff --git a/platform/avr-rss2/dev/ds18b20.c b/platform/avr-rss2/dev/ds18b20.c new file mode 100644 index 000000000..6044ad91e --- /dev/null +++ b/platform/avr-rss2/dev/ds18b20.c @@ -0,0 +1,247 @@ +/* + + Contiki library for DS18B20 temperature sensor - + For more details see http://xxx + + Author - + Author - + + License - GPLv3 + + */ + +#include "ds18b20.h" + +/* probe_for_ds18b20 probes for the sensor. Returns 0 on failure, 1 on success */ +/* Assumptions: only one sensor on the "1-wire bus", on port WSN_DS18B20_PORT */ +/* BUG: THIS CODE DOES NOT WORK AS INTENDED! IT RETURNS "1" EVEN WHEN THERE IS NO */ +/* SENSOR CONNECTED. */ + +uint8_t +ds18b20_probe(void) +{ + uint8_t result = 0; + + /* Reset 1W-bus */ + + /* Pull PIN low for 480 microseconds (us) */ + /* Start with setting bit DS18B20_1_PIN to 0 */ + OW_SET_PIN_LOW(); + /* then set direction to OUT by setting DS18B20_1_DDR bit to 1 */ + OW_SET_OUTPUT(); + /* Delay 480 us */ + clock_delay_usec(480); + /* See if sensor responds. First release the bus and switch to INput mode */ + /* by setting DS18B20_1_DDR bit to 0 */ + OW_SET_INPUT(); + /* Activate internal pull-up by setting pin to HIGH (when in INput mode) */ + /* OW_SET_PIN_HIGH(); */ + /* Wait for the pin to go HIGH for 64 us */ + clock_delay_usec(64); + /* Now the sensor, if present, pulls the pin LOW for 60-240 us */ + /* Detect 0 on PIND bit DS18B20_1_PIN. Invert the result so a presence (aka a 0) */ + /* sets "result" to 1 (for success) */ + result = !OW_GET_PIN_STATE(); + + /* The sensor releases the pin so it goes HIGH after 240 us, add some */ + /* for the signal to stabilize, say 300 usecs to be on the safe side? */ + if(result) { + clock_delay_usec(300); + /* Now the bus should be HIGH again */ + result = OW_GET_PIN_STATE(); + } + + return result; +} +/* Write 1 or 0 on the bus */ + +void +write_bit(uint8_t bit) +{ + /* Set pin to 0 */ + OW_SET_OUTPUT(); + OW_SET_PIN_LOW(); + + /* Pin should be 0 for at least 1 us */ + clock_delay_usec(2); + + /* If we're writing a 1, let interna pull-up pull the bus high */ + /* within 15 us of setting the bus to low */ + if(bit) { + /* Internal pull-up is activated by setting direction to IN and the */ + /* setting the pin to HIGH */ + OW_SET_INPUT(); + OW_SET_PIN_HIGH(); + } + /* OK, now the bus is either LOW, or pulled HIGH by the internal pull-up */ + /* Let this state remain for 60 us, then release the bus */ + clock_delay_usec(60); + + /* Release the bus */ + OW_SET_PIN_HIGH(); + OW_SET_INPUT(); + + /* Allow > 1 us between read/write operations */ + clock_delay_usec(2); +} +/* */ +/* Read one bit of information from the bus, and return it as 1 or 0 */ +/* */ + +uint8_t +read_bit(void) +{ + uint8_t bit = 0; + + /* Set pin to 0 */ + OW_SET_OUTPUT(); + OW_SET_PIN_LOW(); + + /* Pin should be 0 for at least 1 us */ + clock_delay_usec(2); + + /* Now read the bus, start by setting in/out direction and activating internal */ + /* pull-up resistor */ + OW_SET_INPUT(); + OW_SET_PIN_HIGH(); + + /* ds18b20 either keeps the pin down or releases the bus and the */ + /* bus then goes high because of the interna pull-up resistor */ + /* Check whichever happens before 15 us has passed */ + clock_delay_usec(15 - 2 - 1); + bit = OW_GET_PIN_STATE(); + + /* The complete read cycle must last at least 60 us. We have now spent */ + /* about 14-15 us in delays, so add another delay to reach >= 60 us */ + clock_delay_usec(50); + + /* Release bus */ + OW_SET_PIN_HIGH(); + OW_SET_INPUT(); + + /* Allow > 1 us between read/write operations */ + clock_delay_usec(2); + + return bit ? 1 : 0; +} +/* */ +/* Read one byte of information. A byte is read least significant bit first */ +/* */ + +uint8_t +read_byte(void) +{ + uint8_t result = 0; + uint8_t bit; + int i; + + for(i = 0; i < 8; i++) { + bit = read_bit(); + result += (bit << i); + } + return result; +} +/* */ +/* Write one byte of information. A byte is written least significant bit first */ +/* */ + +void +write_byte(uint8_t byte) +{ + int i; + + for(i = 0; i < 8; i++) { + write_bit((byte >> i) & 1); + } +} +/* */ +/* ds18b20_get_temp returns the temperature in "temp" (in degrees celsius) */ +/* Returns 0 on failure (and then "temp" is left unchanged */ +/* Returns 1 on success, and sets temp */ +/* */ + +uint8_t +ds18b20_get_temp(float *temp) +{ + uint8_t result = 0; + + /* Reset bus by probing. Probe returns 1 on success/presence of sensor */ + if(ds18b20_probe()) { + /* write command "skip rom" since we only have one sensor on the wire! */ + write_byte(DS18B20_COMMAND_SKIP_ROM); + + /* write command to start measurement */ + write_byte(DS18B20_COMMAND_START_CONVERSION); + + /* Wait for conversion to complete */ + /* Conversion is 12-bit by default. */ + /* Since we have external power to the sensor (ie not in "parasitic power" mode) */ + /* the bus is held LOW by the sensor while the conversion is going on, and then HIGH */ + /* when conversion is finished. */ + OW_SET_INPUT(); + int count = 0; + while(!OW_GET_PIN_STATE()) { + clock_delay_msec(10); + count++; + /* Longest conversion time is 750 ms (12-bit resolution) */ + /* So if count > 80 (for a little margin!), we return -274.0 */ + /* which indicates failure to read the temperature. */ + if(count > 80) { + return 0; + } + } + + /* The result is stored in the "scratch pad", a 9 byte memory block. */ + /* The first two bytes are the conversion result. Reading the scratch pad */ + /* can be terminated by sending a reset signal (but we read all 9 bytes) */ + (void)ds18b20_probe(); + write_byte(DS18B20_COMMAND_SKIP_ROM); + write_byte(DS18B20_COMMAND_READ_SCRATCH_PAD); + uint8_t i, sp_arr[9]; + for(i = 0; i < 9; i++) { + sp_arr[i] = read_byte(); + } + + /* Check CRC, if mismatch, return 0 (failure to read temperature) */ + uint8_t crc_cal = crc8_ds18b20(sp_arr, 8); + + if(crc_cal != sp_arr[8]) { + return 0; + } + + /* OK, now decode what the temperature reading is. This code assumes 12-bit resolution, */ + /* so this must be modified if the code is modified to use any other resolution! */ + int16_t temp_res; + uint8_t temp_lsb = sp_arr[0]; + uint8_t temp_msb = sp_arr[1]; + + temp_res = (int16_t)temp_msb << 8 | temp_lsb; + *temp = (float)temp_res * 0.0625; + + result = 1; + } + return result; +} +/* */ +/* crc8 algorithm for ds18b20 */ +/* http://www.miscel.dk/MiscEl/CRCcalculations.html */ +/* */ + +uint8_t +crc8_ds18b20(uint8_t *buf, uint8_t buf_len) +{ + uint8_t result = 0; + uint8_t i, b; + + for(i = 0; i < buf_len; i++) { + result = result ^ buf[i]; + for(b = 1; b < 9; b++) { + if(result & 0x1) { + result = (result >> 1) ^ 0x8C; + } else { + result = result >> 1; + } + } + } + return result; +} diff --git a/platform/avr-rss2/dev/enc28j60_avr.c b/platform/avr-rss2/dev/enc28j60_avr.c new file mode 100644 index 000000000..2bfb49562 --- /dev/null +++ b/platform/avr-rss2/dev/enc28j60_avr.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2012-2013, Robert Olsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + */ + +#include +#include +#include +#include "dev/watchdog.h" +#include "contiki.h" +#include "i2c.h" +#include +#include +#include +#include "enc28j60_avr.h" + +#include +#define delay_us(us) (_delay_loop_2(1 + (us * F_CPU) / 4000000UL)) + +void +enc28j60_arch_spi_init(void) +{ + CS_SPI_DDR |= (1 << SPI_CS); + CS_SPI_PORT |= (1 << SPI_CS); + + SPI_DDR |= (1 << SPI_MOSI) | (1 << SPI_SCK); + SPI_DDR &= ~(1 << SPI_MISO); + SPI_PORT &= ~(1 << SPI_MOSI); + SPI_PORT &= ~(1 << SPI_SCK); + SPCR = (1 << SPE) | (1 << MSTR); + /* SPSR |= (1< + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + */ + +#ifndef ENC28J60_AVR_H +#define ENC28J60_AVR_H + +#define SPI_DDR DDRB /* Data Direction Register: Port B */ +#define SPI_PORT PORTB /* Serial Peripheral Interface */ +#define SPI_MOSI 2 /* PB2: Master Out Slave In */ +#define SPI_MISO 3 /* PB3: Master In Slave out */ +#define SPI_SCK 1 /* PB1: Serial Clock */ + +#define CS_SPI_DDR DDRD /* Data Direction Register: Port B */ +#define CS_SPI_PORT PORTD /* Serial Peripheral Interface */ +#define SPI_CS 6 /* PD6: OW2_PIN, Chip Select */ + +/* AVR specific's for enc28j60 */ + +void enc28j60_arch_spi_init(void); +uint8_t enc28j60_arch_spi_write(uint8_t data); +uint8_t enc28j60_arch_spi_read(void); +void enc28j60_arch_spi_select(void); +void enc28j60_arch_spi_deselect(void); + +#endif /* ENC28J60_AVR_H */ diff --git a/platform/avr-rss2/dev/i2c.c b/platform/avr-rss2/dev/i2c.c new file mode 100644 index 000000000..2668aad58 --- /dev/null +++ b/platform/avr-rss2/dev/i2c.c @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file + * i2c core functions + * \author + * Robert Olsson + */ + +#include +#include +#include +#include +#include "dev/watchdog.h" +#include "contiki.h" +#include "i2c.h" +#include +#include +#include +#include "dev/co2_sa_kxx-sensor.h" + +void +i2c_init(uint32_t speed) +{ + /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */ + + TWSR = 0; /* no prescaler */ + TWBR = ((F_CPU / speed) - 16) / 2; /* must be > 10 for stable operation */ +} +uint8_t +i2c_start(uint8_t addr) +{ + uint8_t twst; + uint32_t n; + + /* Send START condition */ + TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); + + /* Wait until transmission completed */ + for(n = 0; n < 100000 && !(TWCR & (1 << TWINT)); n++) { + } + if(n >= 100000) { + return 1; + } + + /* check value of TWI Status Register. Mask prescaler bits. */ + twst = TW_STATUS & 0xF8; + if((twst != TW_START) && (twst != TW_REP_START)) { + return 1; + } + + /* send device address */ + TWDR = addr; + TWCR = (1 << TWINT) | (1 << TWEN); + + /* wail until transmission completed and ACK/NACK has been received */ + for(n = 0; n < 100000 && !(TWCR & (1 << TWINT)); n++) { + } + if(n >= 100000) { + return 1; + } + + /* check value of TWI Status Register. Mask prescaler bits. */ + twst = TW_STATUS & 0xF8; + if((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) { + return 1; + } + + return 0; +} +void +i2c_start_wait(uint8_t addr) +{ + uint8_t twst; + while ( 1 ) + { + // send START condition + TWCR = (1< + */ + +#include "contiki.h" + +/* Here we define the i2c address for dev we support */ +#define I2C_AT24MAC_ADDR 0xB0 /* EUI64 ADDR */ +#define I2C_SHT2X_ADDR (0x40 << 1) /* SHT2X ADDR */ + + +/* Here we define a enumration for devices */ +#define I2C_AT24MAC (1<<0) +#define I2C_SHT2X (1<<1) +#define I2C_CO2SA (1<<2) /* Sense-Air CO2 */ + +#define I2C_READ 1 +#define I2C_WRITE 0 + +void i2c_init(uint32_t speed); +uint8_t i2c_start(uint8_t addr); +void i2c_start_wait(uint8_t addr); +void i2c_stop(void); +void i2c_write(uint8_t u8data); +uint8_t i2c_readAck(void); +uint8_t i2c_readNak(void); +uint8_t i2c_getstatus(void); +uint16_t i2c_probe(void); +void i2c_read_mem(uint8_t addr, uint8_t reg, uint8_t buf[], uint8_t bytes); +void i2c_write_mem(uint8_t addr, uint8_t reg, uint8_t value); +void i2c_at24mac_read(char *buf, uint8_t eui64); +extern uint16_t i2c_probed; /* i2c devices we have probed */ diff --git a/platform/avr-rss2/dev/leds.c b/platform/avr-rss2/dev/leds.c new file mode 100644 index 000000000..c59f9d09f --- /dev/null +++ b/platform/avr-rss2/dev/leds.c @@ -0,0 +1,45 @@ +#include +#include "rss2.h" +#include "leds.h" + +void +leds_init(void) +{ + DDRE |= (1 << LED_RED); + DDRE |= (1 << LED_YELLOW); + /* Off */ + leds_off(LEDS_ALL); +} +void +leds_on(unsigned char ledv) +{ + if(ledv & LEDS_YELLOW) { + PORTE &= ~(1 << LED_YELLOW); + } + if(ledv & LEDS_RED) { + PORTE &= ~(1 << LED_RED); + } +} +void +leds_off(unsigned char ledv) +{ + if(ledv & LEDS_YELLOW) { + PORTE |= (1 << LED_YELLOW); + } + if(ledv & LEDS_RED) { + PORTE |= (1 << LED_RED); + } +} +void +leds_toggle(unsigned char ledv) +{ +} +void +leds_invert(unsigned char ledv) +{ +} +unsigned char +leds_get(void) +{ + return 0; +} diff --git a/platform/avr-rss2/dev/leds.h b/platform/avr-rss2/dev/leds.h new file mode 100644 index 000000000..6dee358c8 --- /dev/null +++ b/platform/avr-rss2/dev/leds.h @@ -0,0 +1,17 @@ + +#ifndef CONTIKI_LED_H_ +#define CONTIKI_LED_H_ + +#define LEDS_GREEN 1 +#define LEDS_YELLOW 2 +#define LEDS_RED 4 +#define LEDS_ALL 7 + +void leds_init(void); /* Initialize the LEDs driver. */ +unsigned char leds_get(void); /* Get the status of a LED. */ +void leds_on(unsigned char ledv); /* Turn on a set of LEDs. */ +void leds_off(unsigned char ledv); /* Turn off a set of LEDs. */ +void leds_toggle(unsigned char ledv); /* Toggle a set of LEDs. */ +void leds_invert(unsigned char ledv); /* Toggle a set of LEDs. */ + +#endif /* CONTIKI_LED_H_ */ diff --git a/platform/iris/apps/mts310/magnet-test.c b/platform/avr-rss2/dev/light-sensor.c similarity index 76% rename from platform/iris/apps/mts310/magnet-test.c rename to platform/avr-rss2/dev/light-sensor.c index 2b22436b5..cbb0a93f7 100644 --- a/platform/iris/apps/mts310/magnet-test.c +++ b/platform/avr-rss2/dev/light-sensor.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, University of Colombo School of Computing + * Copyright (c) 2015, Copyright Robert Olsson * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,34 +28,37 @@ * * This file is part of the Contiki operating system. * - * @(#)$$ */ #include "contiki.h" -#include "dev/sensors/mts300.h" -#include +#include "lib/sensors.h" +#include "dev/light-sensor.h" +#include "rss2.h" +#include "adc.h" + +const struct sensors_sensor light_sensor; /*---------------------------------------------------------------------------*/ -PROCESS(test_sounder_process, "Sounder test"); -AUTOSTART_PROCESSES(&test_sounder_process); -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(test_sounder_process, ev, data) +static int +value(int type) { - static struct etimer et; - - PROCESS_BEGIN(); - - while(1) { - - sounder_on(); - etimer_set(&et, 1); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - - sounder_off(); - etimer_set(&et, 1); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - } - - PROCESS_END(); + return adc_read(A3); } /*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + DDRF &= ~(1 << A3); /* Light sensor */ + DDRF &= ~(1 << A3_PWR); + + PORTF |= (1 << A3_PWR); /* Light sensor */ + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(light_sensor, "Light", value, configure, status); diff --git a/platform/avr-rss2/dev/light-sensor.h b/platform/avr-rss2/dev/light-sensor.h new file mode 100644 index 000000000..da26c724e --- /dev/null +++ b/platform/avr-rss2/dev/light-sensor.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015, Copyright Robert Olsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * + * Author : Robert Olsson + * Created : 2015-10-27 + * Updated : $Date: 2010/01/14 20:23:02 $ + * $Revision: 1.2 $ + */ + +#ifndef LIGHT_SENSOR_H_ +#define LIGHT_SENSOR_H_ + +#include "lib/sensors.h" + +extern const struct sensors_sensor light_sensor; + +#endif /* LIGHT-SENSOR_H_ */ diff --git a/platform/avr-rss2/dev/pulse-sensor.c b/platform/avr-rss2/dev/pulse-sensor.c new file mode 100644 index 000000000..eb0f3a842 --- /dev/null +++ b/platform/avr-rss2/dev/pulse-sensor.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2015, Copyright Robert Olsson / Radio Sensors AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * + * Author : Robert Olsson robert@radio-sensors.com + * Created : 2015-11-22 + */ + +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/pulse-sensor.h" +#include "rss2.h" + +const struct sensors_sensor pulse_sensor; + +#define NP 2 + +uint32_t volatile pc[NP]; + +/* + * Note interrupt sources can be woken up from sleep mode PWR_SAVE + * Two interrupt ports, #0 green terminal block. #1 pin header via + * a comparator. + */ + +static void +port_irq_ctrl(uint8_t on) +{ + if(on) { + + DDRD &= ~(1 << PD2); + PORTD &= ~(1 << PD2); + EIMSK = 0; + EICRA |= 0x20; /* Falling edge INT2 */ + EIMSK |= (1 << PD2); /* Enable interrupt for pin */ + + /* p1 port */ + DDRD &= ~(1 << PD3); + PORTD &= ~(1 << PD3); + EIMSK |= (1 << PD3); /* Enable interrupt for pin */ + EICRA |= 0x80; /* Falling edge */ + PCICR |= (1 << PCIE0); /* And enable irq PCINT 7:0 */ + } else { + EICRA = 0; + PORTD |= (1 << PD2); + EIMSK &= ~(1 << PD2); /* Disable interrupt for pin */ + + PORTD |= (1 << PD3); + EIMSK &= ~(1 << PD3); /* Disable interrupt for pin */ + } +} +ISR(INT2_vect) +{ + if(!(PCICR & (1 << PCIE0))) { + return; + } + pc[0]++; +} + +ISR(INT3_vect) +{ + if(!(PCICR & (1 << PCIE0))) { + return; + } + pc[1]++; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if(type == 0) { + return (int)pc[0]; + } + if(type == 1) { + return (int)pc[1]; + } + return -1; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + port_irq_ctrl(1); /* Enable pulse counts */ + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(pulse_sensor, "Pulse", value, configure, status); diff --git a/platform/avr-rss2/dev/pulse-sensor.h b/platform/avr-rss2/dev/pulse-sensor.h new file mode 100644 index 000000000..03a09cd1b --- /dev/null +++ b/platform/avr-rss2/dev/pulse-sensor.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015, Copyright Robert Olsson / Radio Sensors AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * + * Author : Robert Olsson robert@radio-sensors.com + * Created : 2015-11-22 + */ + +#ifndef PULSE_SENSOR_H_ +#define PULSE_SENSOR_H_ + +#include "lib/sensors.h" + +extern const struct sensors_sensor pulse_sensor; + +#endif /* PULSE-SENSOR_H_ */ diff --git a/platform/avr-rss2/dev/temp-sensor.c b/platform/avr-rss2/dev/temp-sensor.c new file mode 100644 index 000000000..5bc108c7e --- /dev/null +++ b/platform/avr-rss2/dev/temp-sensor.c @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2015, Copyright Per Lindgren + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * + * Author : Per Lindgren + * Hacked by: Robert Olsson robert@radio-sensors.com + * Created : 2015-11-22 + */ + +#include "contiki.h" +#include "dev/temp-sensor.h" +#include +#define delay_us(us) (_delay_loop_2(1 + (us * F_CPU) / 4000000UL)) + +const struct sensors_sensor temp_mcu_sensor; + +/* probe_for_ds18b20 probes for the sensor. Returns 0 on failure, 1 on success + * Assumptions: only one sensor on the "1-wire bus", on port WSN_DS18B20_PORT + * BUG: THIS CODE DOES NOT WORK AS INTENDED! IT RETURNS "1" EVEN WHEN THERE + * IS NO SENSOR CONNECTED. + */ + +uint8_t +ds18b20_probe(void) +{ + uint8_t result = 0; + + /* Reset 1W-bus */ + + /* Pull PIN low for 480 microseconds (us) + * Start with setting bit DS18B20_1_PIN to 0 */ + OW_SET_PIN_LOW(); + /* then set direction to OUT by setting DS18B20_1_DDR bit to 1 */ + OW_SET_OUTPUT(); + /* Delay 480 us */ + clock_delay_usec(480); + /* See if sensor responds. First release the bus and switch to INput mode + * by setting DS18B20_1_DDR bit to 0 */ + OW_SET_INPUT(); + /* Activate internal pull-up by setting pin to HIGH (when in INput mode) + * OW_SET_PIN_HIGH(); + * Wait for the pin to go HIGH for 64 us */ + clock_delay_usec(64); + /* Now the sensor, if present, pulls the pin LOW for 60-240 us + * Detect 0 on PIND bit DS18B20_1_PIN. Invert the result so a presence + * (aka * a 0) sets "result" to 1 (for success) */ + result = !OW_GET_PIN_STATE(); + + /* The sensor releases the pin so it goes HIGH after 240 us, add some + for the signal to stabilize, say 300 usecs to be on the safe side? */ + if(result) { + clock_delay_usec(300); + /* Now the bus should be HIGH again */ + result = OW_GET_PIN_STATE(); + } + return result; +} +/* Write 1 or 0 on the bus */ + +void +write_bit(uint8_t bit) +{ + /* Set pin to 0 */ + OW_SET_OUTPUT(); + OW_SET_PIN_LOW(); + + /* Pin should be 0 for at least 1 us */ + clock_delay_usec(2); + + /* If we're writing a 1, let interna pull-up pull the bus high + * within 15 us of setting the bus to low */ + if(bit) { + /* Internal pull-up is activated by setting direction to IN and the + * setting the pin to HIGH */ + OW_SET_INPUT(); + OW_SET_PIN_HIGH(); + } + /* OK, now the bus is either LOW, or pulled HIGH by the internal pull-up + * Let this state remain for 60 us, then release the bus */ + clock_delay_usec(60); + + /* Release the bus */ + OW_SET_PIN_HIGH(); + OW_SET_INPUT(); + + /* Allow > 1 us between read/write operations */ + clock_delay_usec(2); +} +/* Read one bit of information from the bus, and return it as 1 or 0 */ + +uint8_t +read_bit(void) +{ + uint8_t bit = 0; + + /* Set pin to 0 */ + OW_SET_OUTPUT(); + OW_SET_PIN_LOW(); + + /* Pin should be 0 for at least 1 us */ + clock_delay_usec(2); + + /* Now read the bus, start by setting in/out direction and activating + * internal pull-up resistor */ + OW_SET_INPUT(); + OW_SET_PIN_HIGH(); + + /* ds18b20 either keeps the pin down or releases the bus and the + * bus then goes high because of the interna pull-up resistor + * Check whichever happens before 15 us has passed */ + clock_delay_usec(15 - 2 - 1); + bit = OW_GET_PIN_STATE(); + + /* The complete read cycle must last at least 60 us. We have now spent + * about 14-15 us in delays, so add another delay to reach >= 60 us */ + clock_delay_usec(50); + + /* Release bus */ + OW_SET_PIN_HIGH(); + OW_SET_INPUT(); + + /* Allow > 1 us between read/write operations */ + clock_delay_usec(2); + + return bit ? 1 : 0; +} +/* Read one byte of information. A byte is read least significant bit first */ + +uint8_t +read_byte(void) +{ + uint8_t result = 0; + uint8_t bit; + int i; + + for(i = 0; i < 8; i++) { + bit = read_bit(); + result += (bit << i); + } + return result; +} +/* Write one byte of information. A byte is written least significant bit first */ + +void +write_byte(uint8_t byte) +{ + int i; + + for(i = 0; i < 8; i++) { + write_bit((byte >> i) & 1); + } +} +/* ds18b20_get_temp returns the temperature in "temp" (in degrees celsius) + * Returns 0 on failure (and then "temp" is left unchanged + * Returns 1 on success, and sets temp */ + +uint8_t +ds18b20_get_temp(double *temp) +{ + uint8_t result = 0; + + /* Reset bus by probing. Probe returns 1 on success/presence of sensor */ + if(ds18b20_probe()) { + /* write command "skip rom" since we only have one sensor on the wire! */ + write_byte(DS18B20_COMMAND_SKIP_ROM); + + /* write command to start measurement */ + write_byte(DS18B20_COMMAND_START_CONVERSION); + + /* Wait for conversion to complete. Conversion is 12-bit by default. + * Since we have external power to the sensor (ie not in "parasitic power" + * mode) the bus is held LOW by the sensor while the conversion is going + * on, and then HIGH when conversion is finished. */ + OW_SET_INPUT(); + int count = 0; + while(!OW_GET_PIN_STATE()) { + clock_delay_msec(10); + count++; + /* Longest conversion time is 750 ms (12-bit resolution) + * So if count > 80 (for a little margin!), we return -274.0 + * which indicates failure to read the temperature. */ + if(count > 80) { + return 0; + } + } + + /* The result is stored in the "scratch pad", a 9 byte memory block. + * The first two bytes are the conversion result. Reading the scratch pad + * can be terminated by sending a reset signal (but we read all 9 bytes) */ + (void)ds18b20_probe(); + write_byte(DS18B20_COMMAND_SKIP_ROM); + write_byte(DS18B20_COMMAND_READ_SCRATCH_PAD); + uint8_t i, sp_arr[9]; + for(i = 0; i < 9; i++) { + sp_arr[i] = read_byte(); + } + + /* Check CRC, if mismatch, return 0 (failure to read temperature) */ + uint8_t crc_cal = crc8_ds18b20(sp_arr, 8); + + if(crc_cal != sp_arr[8]) { + return 0; + } + + /* OK, now decode what the temperature reading is. This code assumes + * 12-bit resolution, so this must be modified if the code is modified + * to use any other resolution! */ + int16_t temp_res; + uint8_t temp_lsb = sp_arr[0]; + uint8_t temp_msb = sp_arr[1]; + + temp_res = (int16_t)temp_msb << 8 | temp_lsb; + *temp = (double)temp_res * 0.0625; + + result = 1; + } + return result; +} +/* crc8 algorithm for ds18b20 */ +/* http://www.miscel.dk/MiscEl/CRCcalculations.html */ + +uint8_t +crc8_ds18b20(uint8_t *buf, uint8_t buf_len) +{ + uint8_t result = 0; + uint8_t i, b; + + for(i = 0; i < buf_len; i++) { + result = result ^ buf[i]; + for(b = 1; b < 9; b++) { + if(result & 0x1) { + result = (result >> 1) ^ 0x8C; + } else { + result = result >> 1; + } + } + } + return result; +} +static int +value(int type) +{ + double t; + int ret; + ret = ds18b20_get_temp(&t); + + /* Return temp multiplied by 100 for two decimals */ + if(ret) + return (int) (t * 100); + + /* Error return largest negative value */ + return 0x8000; +} +static int +configure(int type, int c) +{ + ds18b20_probe(); + return 0; +} +static int +status(int type) +{ + return 1; +} +SENSORS_SENSOR(temp_sensor, TEMP_SENSOR, value, configure, status); diff --git a/platform/avr-rss2/dev/temp-sensor.h b/platform/avr-rss2/dev/temp-sensor.h new file mode 100644 index 000000000..b5ab53659 --- /dev/null +++ b/platform/avr-rss2/dev/temp-sensor.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015, Copyright Per Lindgren + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * + * Author : Per Lindgren + * Hacked by: Robert Olsson robert@radio-sensors.com + * Created : 2015-11-22 + */ + +#ifndef TEMP_SENSOR_H_ +#define TEMP_SENSOR_H_ + +#include "lib/sensors.h" +#include +#include "contiki.h" +#include "rss2.h" + +#define DS18B20_1_PIN OW_BUS_0 +#define DS18B20_1_IN PIND +#define DS18B20_1_OUT PORTD +#define DS18B20_1_DDR DDRD + +#define OW_SET_PIN_LOW() (DS18B20_1_OUT &= ~(1 << DS18B20_1_PIN)) +#define OW_SET_PIN_HIGH() (DS18B20_1_OUT |= (1 << DS18B20_1_PIN)) +#define OW_SET_OUTPUT() (DS18B20_1_DDR |= (1 << DS18B20_1_PIN)) +#define OW_SET_INPUT() (DS18B20_1_DDR &= ~(1 << DS18B20_1_PIN)) +#define OW_GET_PIN_STATE() ((DS18B20_1_IN & (1 << DS18B20_1_PIN)) ? 1 : 0) + +#define DS18B20_COMMAND_READ_SCRATCH_PAD 0xBE +#define DS18B20_COMMAND_START_CONVERSION 0x44 +#define DS18B20_COMMAND_SKIP_ROM 0xCC + +/* probe_for_ds18b20 probes for the sensor. Returns 0 on failure, 1 on success + * Assumption: only one sensor on the "1-wire bus", on port DS18B20_1_PIN */ + +extern uint8_t ds18b20_probe(void); +extern uint8_t ds18b20_get_temp(double *temp); +extern uint8_t crc8_ds18b20(uint8_t *buf, uint8_t buf_len); + +extern const struct sensors_sensor temp_sensor; + +#define TEMP_SENSOR "temp" + +#endif /* TEMP_SENSOR_H_ */ diff --git a/platform/avr-rss2/dev/temp_mcu-sensor.c b/platform/avr-rss2/dev/temp_mcu-sensor.c new file mode 100644 index 000000000..cfa21707d --- /dev/null +++ b/platform/avr-rss2/dev/temp_mcu-sensor.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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 ADVISE OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * ----------------------------------------------------------------- + * + * Author : Robert Olsson + * Created : 2015-10-27 + * Updated : $Date: 2010/08/25 19:30:52 $ + * $Revision: 1.11 $ + */ + +#include "contiki.h" +#include "dev/temp_mcu-sensor.h" +#include +#define delay_us(us) (_delay_loop_2(1 + (us * F_CPU) / 4000000UL)) + +const struct sensors_sensor temp_mcu_sensor; + +/* Returns the MCU temp in C*10 read from the BATMON MCU register + * See AtMega chip docs for BATMON details. + */ + +static int +value(int type) +{ + uint16_t v; + + ADCSRB |= (1 << MUX5); /* this bit buffered till ADMUX written to! */ + ADMUX = 0xc9; + + /* ADC on /32 ADC start */ + ADCSRA = (1 << ADPS2) | (0 << ADPS1) | (1 << ADPS0); + ADCSRA |= (1 << ADEN); /* Enable the ADC */ + + while(!(ADCSRB & (1 << AVDDOK))) ; /* Wait for AVDD ok */ + while(!(ADCSRB & (1 << REFOK))) ; /* Wait for ref ok */ + + ADCSRA |= (1 << ADSC); /* Throwaway conversion */ + while + (ADCSRA & (1 << ADSC)) ; + + ADCSRA |= (1 << ADSC); /* Start conversion */ + while + (ADCSRA & (1 << ADSC)) ; + + v = ADC; + + /* Disable the ADC to save power */ + ADCSRA &= ~_BV(ADEN); + /* ADMUX = 0; //turn off internal vref */ + return (int)((double)(v * 1.13 - 272.8) * 10); +} +static int +configure(int type, int c) +{ + return 0; +} +static int +status(int type) +{ + return 1; +} +SENSORS_SENSOR(temp_mcu_sensor, TEMP_MCU_SENSOR, value, configure, status); + diff --git a/platform/z1sp/dev/potentiometer-sensor.h b/platform/avr-rss2/dev/temp_mcu-sensor.h similarity index 80% rename from platform/z1sp/dev/potentiometer-sensor.h rename to platform/avr-rss2/dev/temp_mcu-sensor.h index d9d8b983d..c311fdb16 100644 --- a/platform/z1sp/dev/potentiometer-sensor.h +++ b/platform/avr-rss2/dev/temp_mcu-sensor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Zolertia(TM) is a trademark by Advancare,SL + * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,18 +29,19 @@ * * ----------------------------------------------------------------- * - * Author : Enric M. Calvo (based on work by A. Dunkels, J. Eriksson, N. Finne) - * Created : 2011-02-22 - * $Revision: 1.0 $ + * Author : Robert Olsson + * Created : 2015-10-27 + * Updated : $Date: 2007/11/13 20:36:40 $ + * $Revision: 1.1 $ */ -#ifndef POTENTIOMETER_SENSOR_H_ -#define POTENTIOMETER_SENSOR_H_ +#ifndef TEMP_MCU_SENSOR_H_ +#define TEMP_MCU_SENSOR_H_ #include "lib/sensors.h" -extern const struct sensors_sensor potentiometer_sensor; +extern const struct sensors_sensor temp_mcu_sensor; -#define POTENTIOMETER_SENSOR "Potentiometer" +#define TEMP_MCU_SENSOR "temp_mcu" -#endif /* POTENTIOMETER_SENSOR_H_ */ +#endif /* TEMP_MCU_SENSOR_H_ */ diff --git a/platform/avr-rss2/ip64-conf.h b/platform/avr-rss2/ip64-conf.h new file mode 100644 index 000000000..26c51a55f --- /dev/null +++ b/platform/avr-rss2/ip64-conf.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ +#ifndef IP64_CONF_H +#define IP64_CONF_H + +#include "net/ip64/ip64-eth-interface.h" +#include "dev/enc28j60/enc28j60-ip64-driver.h" +#define IP64_CONF_UIP_FALLBACK_INTERFACE ip64_eth_interface +#define IP64_CONF_INPUT ip64_eth_interface_input +#define IP64_CONF_DHCP 1 +#define IP64_CONF_ETH_DRIVER enc28j60_ip64_driver + +#endif /* IP64_CONF_H */ diff --git a/platform/avr-rss2/params.c b/platform/avr-rss2/params.c new file mode 100644 index 000000000..f2ae2abfc --- /dev/null +++ b/platform/avr-rss2/params.c @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +#define PRINTF(FORMAT, args ...) printf_P(PSTR(FORMAT),##args) + +#define DEBUG 1 +#if DEBUG +#define PRINTD(FORMAT, args ...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTD(...) +#endif + +#include "contiki.h" +#include +#include +#include +#include + +#if AVR_WEBSERVER +/* #include "httpd-fs.h" */ +/* #include "httpd-cgi.h" */ +#endif + +#include "contiki-net.h" +#include "params.h" + +#if CONTIKI_CONF_RANDOM_MAC +extern uint8_t rng_get_uint8(void); +static void +generate_new_eui64(uint8_t eui64[8]) +{ + eui64[0] = 0x02; + eui64[1] = rng_get_uint8(); + eui64[2] = rng_get_uint8(); + eui64[3] = 0xFF; + eui64[4] = 0xFE; + eui64[5] = rng_get_uint8(); + eui64[6] = rng_get_uint8(); + eui64[7] = rng_get_uint8(); +} +#endif + +#if AVR_WEBSERVER +/* Webserver builds can set these in httpd-fsdata.c via makefsdata.h */ +extern uint8_t default_mac_address[8]; +extern uint8_t default_server_name[16]; +extern uint8_t default_domain_name[30]; +#else +const uint8_t default_mac_address[8] PROGMEM = PARAMS_EUI64ADDR; +const uint8_t default_server_name[] PROGMEM = PARAMS_SERVERNAME; +const uint8_t default_domain_name[] PROGMEM = PARAMS_DOMAINNAME; +#endif + +#if PARAMETER_STORAGE == 0 +/* 0 Hard coded, minmal program and eeprom usage. */ +uint8_t +params_get_eui64(uint8_t *eui64) +{ +#if CONTIKI_CONF_RANDOM_MAC + PRINTD("Generating random EUI64 MAC\n"); + generate_new_eui64(eui64); + return 1; +#else + uint8_t i; + for(i = 0; i < sizeof(default_mac_address); i++) { + eui64[i] = pgm_read_byte_near(default_mac_address + i); + } + return 0; +#endif +} +#elif PARAMETER_STORAGE == 1 +/* 1 Stored in fixed eeprom locations, rewritten from flash if corrupt. + * They can be manually changed and kept over program reflash. + * The channel and bit complement are used to check EEMEM integrity, + * If corrupt all values will be rewritten with the default flash values. + * To make this work, get the channel before anything else. + */ +#if !AVR_WEBSERVER +uint8_t eemem_mac_address[] EEMEM = PARAMS_EUI64ADDR; +uint8_t eemem_server_name[] EEMEM = PARAMS_SERVERNAME; +uint8_t eemem_domain_name[] EEMEM = PARAMS_DOMAINNAME; +#endif /*AVR_WEBSERVER */ + +uint16_t eemem_nodeid EEMEM = PARAMS_NODEID; +uint8_t eemem_channel[2] EEMEM = { PARAMS_CHANNEL, ~PARAMS_CHANNEL }; +uint16_t eemem_panid EEMEM = PARAMS_PANID; +uint16_t eemem_panaddr EEMEM = PARAMS_PANADDR; +uint8_t eemem_txpower EEMEM = PARAMS_TXPOWER; + +#if CONTIKI_CONF_RANDOM_MAC +static uint8_t randomeui64; +#endif + +uint8_t +params_get_channel(void) +{ + uint8_t x[2]; + *(uint16_t *)x = eeprom_read_word((uint16_t *)&eemem_channel); +/* Don't return an invalid channel number */ + if((x[0] < 11) || (x[0] > 26)) { + x[1] = x[0]; + } +/* Do exclusive or test on the two values read */ + if((uint8_t)x[0] != (uint8_t) ~x[1]) { /* ~x[1] can promote comparison to 16 bit */ +/* Verification fails, rewrite everything */ + uint8_t i, buffer[32]; + PRINTD("EEPROM is corrupt, rewriting with defaults.\n"); +#if CONTIKI_CONF_RANDOM_MAC + PRINTD("Generating random EUI64 MAC\n"); + generate_new_eui64(&buffer); + randomeui64 = 1; +#else + for(i = 0; i < sizeof(default_mac_address); i++) { + buffer[i] = pgm_read_byte_near(default_mac_address + i); + } +#endif +/* eeprom_write_block should not be interrupted */ + cli(); + eeprom_write_block(&buffer, &eemem_mac_address, sizeof(eemem_mac_address)); + for(i = 0; i < sizeof(default_server_name); i++) { + buffer[i] = pgm_read_byte_near(default_server_name + i); + } + eeprom_write_block(&buffer, &eemem_server_name, sizeof(eemem_server_name)); + for(i = 0; i < sizeof(default_domain_name); i++) { + buffer[i] = pgm_read_byte_near(default_domain_name + i); + } + eeprom_write_block(&buffer, &eemem_domain_name, sizeof(eemem_domain_name)); + eeprom_write_word(&eemem_panid, PARAMS_PANID); + eeprom_write_word(&eemem_panaddr, PARAMS_PANADDR); + eeprom_write_byte(&eemem_txpower, PARAMS_TXPOWER); + eeprom_write_word(&eemem_nodeid, PARAMS_NODEID); + x[0] = PARAMS_CHANNEL; + x[1] = ~x[0]; + eeprom_write_word((uint16_t *)&eemem_channel, *(uint16_t *)x); + sei(); + } +/* Always returns a valid channel */ + return x[0]; +} +uint8_t +params_get_eui64(uint8_t *eui64) +{ + cli(); + eeprom_read_block((void *)eui64, &eemem_mac_address, sizeof(linkaddr_t)); + sei(); +#if CONTIKI_CONF_RANDOM_MAC + return randomeui64; +#else + return 0; +#endif +} +uint16_t +params_get_panid(void) +{ + return eeprom_read_word(&eemem_panid); +} +uint16_t +params_get_panaddr(void) +{ + return eeprom_read_word(&eemem_panaddr); +} +uint8_t +params_get_txpower(void) +{ + return eeprom_read_byte(&eemem_txpower); +} +#else /* CONTIKI_CONF_SETTINGS_MANAGER */ + +uint8_t +params_get_channel() +{ + uint8_t x; + size_t size = 1; + if(settings_get(SETTINGS_KEY_CHANNEL, 0, (unsigned char *)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get RF channel %u\n", x); + } else { + x = PARAMS_CHANNEL; + if(settings_add_uint8(SETTINGS_KEY_CHANNEL, x) == SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM RF channel to %d\n", x); + } + } + return x; +} +uint8_t +params_get_eui64(uint8_t *eui64) +{ + size_t size = sizeof(linkaddr_t); + if(settings_get(SETTINGS_KEY_EUI64, 0, (unsigned char *)eui64, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get EUI64 MAC\n"); + return 0; + } +#if CONTIKI_CONF_RANDOM_MAC + PRINTD("Generating random EUI64 MAC\n"); + generate_new_eui64(eui64); +#else + { uint8_t i; + for(i = 0; i < 8; i++) { + eui64[i] = pgm_read_byte_near(default_mac_address + i); + } + } /* test this */ +#endif + if(settings_add(SETTINGS_KEY_EUI64, (unsigned char *)eui64, 8) == SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM MAC address\n"); + } +#if CONTIKI_CONF_RANDOM_MAC + return 1; +#else + return 0; +#endif +} +uint16_t +params_get_panid(void) +{ + uint16_t x; + size_t size = 2; + if(settings_get(SETTINGS_KEY_PAN_ID, 0, (unsigned char *)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get PAN ID of %04x\n", x); + } else { + x = PARAMS_PANID; + if(settings_add_uint16(SETTINGS_KEY_PAN_ID, x) == SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM PAN ID to %04x\n", x); + } + } + return x; +} +uint16_t +params_get_panaddr(void) +{ + uint16_t x; + size_t size = 2; + if(settings_get(SETTINGS_KEY_PAN_ADDR, 0, (unsigned char *)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get PAN address of %04x\n", x); + } else { + x = PARAMS_PANADDR; + if(settings_add_uint16(SETTINGS_KEY_PAN_ADDR, x) == SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM PAN address to %04x\n", x); + } + } + return x; +} +uint8_t +params_get_txpower(void) +{ + uint8_t x; + size_t size = 1; + if(settings_get(SETTINGS_KEY_TXPOWER, 0, (unsigned char *)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get tx power of %d (0=max)\n", x); + } else { + x = PARAMS_TXPOWER; + if(settings_add_uint8(SETTINGS_KEY_TXPOWER, x) == SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM tx power of %d (0=max)\n", x); + } + } + return x; +} +#endif /* CONTIKI_CONF_SETTINGS_MANAGER */ diff --git a/platform/avr-rss2/params.h b/platform/avr-rss2/params.h new file mode 100644 index 000000000..95150333b --- /dev/null +++ b/platform/avr-rss2/params.h @@ -0,0 +1,108 @@ +#ifndef __PARAMS_H__ +#define __PARAMS_H__ +/* PARAMETER_STORAGE = + * 0 Hard coded, minmal program and eeprom usage. + * 1 Stored in fixed eeprom locations, rewritten from flash if corrupt. + * This allows parameter changes using a hardware programmer or custom application code. + * Corruption test is based on channel verify so get the channel before anything else! + * 2 Obtained from eeprom using the general settings manager and read from program flash if not present. + * Useful for for testing builds without wearing out flash memory. + * 3 Obtained from eeprom using the settings manager and rewritten from flash if not present. + * This ensures all parameters are present in upper eeprom flash. + * + * Note the parameters in this file can be changed without forcing a complete rebuild. + */ +#define CONTIKI_CONF_RANDOM_MAC 0 /* adds 78 bytes */ +#define CONTIKI_CONF_SETTINGS_MANAGER 0 /* adds 1696 bytes */ + +#if CONTIKI_CONF_SETTINGS_MANAGER +/* #define PARAMETER_STORAGE 2 */ +#define PARAMETER_STORAGE 2 +#else +#define PARAMETER_STORAGE 1 +#endif + +/* Include settings.h, then dummy out the write routines */ +#include "settings.h" +#if PARAMETER_STORAGE == 2 +#define settings_add(...) 0 +#define settings_add_uint8(...) 0 +#define settings_add_uint16(...) 0 +#endif + +#if AVR_WEBSERVER +/* Webserver builds can set some defaults in httpd-fsdata.c via makefsdata.h */ +extern uint8_t eemem_mac_address[8]; +extern uint8_t eemem_server_name[16]; +extern uint8_t eemem_domain_name[30]; +#endif + +#ifdef SERVER_NAME +#define PARAMS_SERVERNAME SERVER_NAME +#else +#define PARAMS_SERVERNAME "ATMEGA256rfr2" +#endif +#ifdef DOMAIN_NAME +#define PARAMS_DOMAINNAME DOMAIN_NAME +#else +#define PARAMS_DOMAINNAME "localhost" +#endif +#ifdef NODE_ID +#define PARAMS_NODEID NODE_ID +#else +#define PARAMS_NODEID 0 +#endif +#ifdef CHANNEL_802_15_4 +#define PARAMS_CHANNEL CHANNEL_802_15_4 +#else +#define PARAMS_CHANNEL 26 +#endif +#ifdef IEEE802154_PANID +#define PARAMS_PANID IEEE802154_PANID +#else +#define PARAMS_PANID 0xABCD +#endif +#ifdef IEEE802154_PANADDR +#define PARAMS_PANADDR IEEE802154_PANADDR +#else +#define PARAMS_PANADDR 0 +#endif +#ifdef RF230_MAX_TX_POWER +#define PARAMS_TXPOWER RF230_MAX_TX_POWER +#else +#define PARAMS_TXPOWER 0 +#endif +#ifdef EUI64_ADDRESS +#define PARAMS_EUI64ADDR EUI64_ADDRESS +#else +/* This form of of EUI64 mac allows full 6LoWPAN header compression from mac address */ +#if UIP_CONF_LL_802154 +/* #define PARAMS_EUI64ADDR {0x02, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN} */ +#define PARAMS_EUI64ADDR { 0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01 } +#else +/* #define PARAMS_EUI64ADDR {0x02, 0xNN, 0xNN, 0xff, 0xfe, 0xNN, 0xNN, 0xNN} */ +#define PARAMS_EUI64ADDR { 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01 } +#endif +/* This form of of EUI64 mac allows 16 bit 6LoWPAN header compression on multihops */ +/* #define PARAMS_EUI64ADDR {0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0xNN, 0xNN} */ +#endif + +uint8_t params_get_eui64(uint8_t *eui64); +#if PARAMETER_STORAGE == 0 +/* Hard coded program flash parameters */ +#define params_get_servername(...) +#define params_get_nodeid(...) PARAMS_NODEID +#define params_get_channel(...) PARAMS_CHANNEL +#define params_get_panid(...) PARAMS_PANID +#define params_get_panaddr(...) PARAMS_PANADDR +#define params_get_txpower(...) PARAMS_TXPOWER +#else +/* Parameters stored in eeprom */ +uint16_t params_get_nodeid(void); +uint8_t params_get_channel(void); +uint16_t params_get_panid(void); +uint16_t params_get_panaddr(void); +uint8_t params_get_txpower(void); +#endif + +#endif /* __PARAMS_H__ */ diff --git a/platform/avr-rss2/rss2.h b/platform/avr-rss2/rss2.h new file mode 100644 index 000000000..46ade3822 --- /dev/null +++ b/platform/avr-rss2/rss2.h @@ -0,0 +1,36 @@ + +/* + Pin assigments for Radio Sensors board revision 2.3 + using MCU AtMega128rfa1 + */ + +#define ISP_1 PB1 /* SCK */ +#define ISP_2 PB2 /* MOSI */ +#define ISP_3 PB3 /* MISO */ + +#define LED_YELLOW PE3 /* 1k pullup to Vcc */ +#define LED_RED PE4 /* 1k pullup to Vcc */ +#define USB_PWR PB5 /* High if FTDI TTL-USB cable sources */ +#define P0 PD2 /* Pulse count input. Pullup via jumper */ +#define P1 PD3 /* Pulse count input via optional Comparator */ +#define PWR_1 PE7 /* Programmable power pin Vcc via P-FET */ + +#define AV_IN PF0 /* V_IN ADC input. 100k/1M volt. divider */ +#define A1 PF1 /* A1 ADC input. 100k/300k volt. divider */ +#define A2 PF2 /* A2 ADC input 100k/300k volt. divider */ +#define A3 PF3 /* Light sensor A3 ADC input 100k/100k volt. divider */ +#define A3_PWR PF4 /* Light sensor power A3_PWR */ + +#define RX0 PE0 /* RX UART0 -- FTDI TTL-USB cable */ +#define TX0 PE1 /* TX UART0 -- FTDI TTL-USB cable */ + +#define OW_BUS_0 PD7 /* One-Wire bus w temp/ID Pulled Up. Separate Vcc */ +#define OW_BUS_1 PD6 /* One-Wire bus extra Pulled Up. Separate Vcc */ + +/* AVR ISP standard connected */ +/* 16 MHz xtal */ +/* RTC 32.768 Hz xtal */ + +/*Optional HIH610 connected on SPI */ +#define HUM_PWR PE2 /* Power pin for HIH6130 also to ena. HIH 6130 Alarm mode */ + diff --git a/platform/avr-rss2/slip_uart0.c b/platform/avr-rss2/slip_uart0.c new file mode 100644 index 000000000..8f064f980 --- /dev/null +++ b/platform/avr-rss2/slip_uart0.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2010, University of Colombo School of Computing + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * @(#)$$ + */ + +/** + * \file + * Machine dependent AVR SLIP routines for UART0. + * \author + * Kasun Hewage + */ + +#include +#include "contiki.h" +#include "dev/rs232.h" +#include "slip.h" + +/*---------------------------------------------------------------------------*/ +static int +slip_putchar(char c, FILE *stream) +{ +#define SLIP_END 0300 + static char debug_frame = 0; + + if(!debug_frame) { /* Start of debug output */ + slip_arch_writeb(SLIP_END); + slip_arch_writeb('\r'); /* Type debug line == '\r' */ + debug_frame = 1; + } + + slip_arch_writeb((unsigned char)c); + + /* + * Line buffered output, a newline marks the end of debug output and + * implicitly flushes debug output. + */ + if(c == '\n') { + slip_arch_writeb(SLIP_END); + debug_frame = 0; + } + + return c; +} +/*---------------------------------------------------------------------------*/ +static FILE slip_stdout = FDEV_SETUP_STREAM(slip_putchar, NULL, + _FDEV_SETUP_WRITE); +/*---------------------------------------------------------------------------*/ +void +slip_arch_init(unsigned long ubr) +{ + rs232_set_input(SLIP_PORT, slip_input_byte); + stdout = &slip_stdout; +} +/*---------------------------------------------------------------------------*/ +/* + XXX: + Currently, the following function is in cpu/avr/dev/rs232.c file. this + should be moved to here from there hence this is a platform specific slip + related function. + void + slip_arch_writeb(unsigned char c) + { + rs232_send(RS232_PORT_0, c); + } + */ diff --git a/platform/avr-zigbit/Makefile.avr-zigbit b/platform/avr-zigbit/Makefile.avr-zigbit index 348c06f65..d2599da9a 100644 --- a/platform/avr-zigbit/Makefile.avr-zigbit +++ b/platform/avr-zigbit/Makefile.avr-zigbit @@ -1,30 +1,20 @@ -CONTIKI_TARGET_DIRS = . apps net loader -CONTIKI_CORE=contiki-avr-zigbit +CONTIKIDIRS += ${addprefix $(CONTIKI)/core/, net/mac net/mac/sicslowmac . } + +CONTIKI_TARGET_DIRS = . apps /core/net/mac/ /core/net/mac/sicslowmac/ +CONTIKI_CORE = contiki-avr-zigbit CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o -CONTIKI_TARGET_SOURCEFILES += rs232.c cfs-eeprom.c eeprom.c random.c \ - mmem.c contiki-avr-zigbit-main.c +CONTIKI_TARGET_SOURCEFILES += rs232.c cfs-eeprom.c eeprom.c random.c mmem.c \ + contiki-avr-zigbit-main.c \ + sicslowmac.c linkaddr.c queuebuf.c nullmac.c packetbuf.c \ + frame802154.c framer-802154.c framer.c nullsec.c nbr-table.c -CONTIKIAVR=$(CONTIKI)/cpu/avr -CONTIKIBOARD=. +CONTIKIAVR = $(CONTIKI)/cpu/avr +CONTIKIBOARD = . CONTIKI_PLAT_DEFS = -DF_CPU=8000000UL -DAUTO_CRC_PADDING=2 -MCU=atmega1281 -AVRDUDE_PROGRAMMER=jtag2 - -# For usb devices, you may either use PORT=usb, or (e.g. if you have more than one -# programmer connected) you can use the following trick to find out the serial number: -# -# The example is for an JTAGICE mkII used to program an ATmega128: -# avrdude -v -P usb:xxxx -c jtag2 -p atmega128 -AVRDUDE_PORT=usb:00B000000D79 - - -# Additional avrdude options -# Verify off -AVRDUDE_OPTIONS=-V - +MCU = atmega1281 include $(CONTIKIAVR)/Makefile.avr -include $(CONTIKIAVR)/radio/Makefile.radio +include $(CONTIKIAVR)/radio/Makefile.radio \ No newline at end of file diff --git a/platform/avr-zigbit/contiki-avr-zigbit-main.c b/platform/avr-zigbit/contiki-avr-zigbit-main.c index 9b8f3e9e4..52564b0d4 100644 --- a/platform/avr-zigbit/contiki-avr-zigbit-main.c +++ b/platform/avr-zigbit/contiki-avr-zigbit-main.c @@ -82,20 +82,32 @@ FUSES = }; #if RF230BB +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 //PROCINIT(&etimer_process, &tcpip_process ); #else +//PROCINIT(&etimer_process ); +#endif +#else +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 PROCINIT(&etimer_process, &mac_process, &tcpip_process ); +#else +PROCINIT(&etimer_process, &mac_process ); +#endif #endif /* Put default MAC address in EEPROM */ +#if MY_NODE_ID +uint8_t mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, + MY_NODE_ID}; +#else uint8_t mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55}; - +#endif void init_lowlevel(void) { /* Second rs232 port for debugging */ - rs232_init(RS232_PORT_1, USART_BAUD_115200, + rs232_init(RS232_PORT_1, USART_BAUD_38400, USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); /* Redirect stdout to second port */ @@ -124,7 +136,7 @@ init_lowlevel(void) memset(&addr, 0, sizeof(linkaddr_t)); eeprom_read_block ((void *)&addr.u8, &mac_address, 8); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(&uip_lladdr.addr, &addr.u8, 8); #endif rf230_set_pan_addr(IEEE802154_PANID, 0, (uint8_t *)&addr.u8); @@ -159,16 +171,18 @@ init_lowlevel(void) #if ANNOUNCE_BOOT printf_P(PSTR("Routing Enabled\n")); #endif - rime_init(rime_udp_init(NULL)); - uip_router_register(&rimeroute); + //rime_init(rime_udp_init(NULL)); + //uip_router_register(&rimeroute); #endif - +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 process_start(&tcpip_process, NULL); - +#endif #else /* mac process must be started before tcpip process! */ process_start(&mac_process, NULL); +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 process_start(&tcpip_process, NULL); +#endif #endif /*RF230BB*/ } @@ -185,13 +199,13 @@ main(void) /* Register initial processes */ // procinit_init(); - /* Autostart processes */ - autostart_start(autostart_processes); - printf_P(PSTR("\n********BOOTING CONTIKI*********\n")); printf_P(PSTR("System online.\n")); + /* Autostart processes */ + autostart_start(autostart_processes); + /* Main scheduler loop */ while(1) { process_run(); diff --git a/platform/avr-zigbit/contiki-conf.h b/platform/avr-zigbit/contiki-conf.h index af5be6f7b..c01c6555c 100644 --- a/platform/avr-zigbit/contiki-conf.h +++ b/platform/avr-zigbit/contiki-conf.h @@ -62,18 +62,10 @@ */ /* Clock ticks per second */ #define CLOCK_CONF_SECOND 125 -#if 1 -/* 16 bit counter overflows every ~10 minutes */ -typedef unsigned short clock_time_t; -#define CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) -#define INFINITE_TIME 0xffff -#define RIME_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME INFINITE_TIME/CLOCK_CONF_SECOND /* Default uses 600 */ -#define COLLECT_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME INFINITE_TIME/CLOCK_CONF_SECOND /* Default uses 600 */ -#else -typedef unsigned long clock_time_t; -#define CLOCK_LT(a,b) ((signed long)((a)-(b)) < 0) -#define INFINITE_TIME 0xffffffff -#endif + +typedef uint32_t clock_time_t; +#define CLOCK_LT(a,b) ((int32_t)((a)-(b)) < 0) + /* These routines are not part of the contiki core but can be enabled in cpu/avr/clock.c */ void clock_delay_msec(uint16_t howlong); void clock_adjust_ticks(clock_time_t howmany); @@ -96,10 +88,9 @@ void clock_adjust_ticks(clock_time_t howmany); #endif #define LINKADDR_CONF_SIZE 8 -#define PACKETBUF_CONF_HDR_SIZE 0 -//define UIP_CONF_IPV6 1 //Let the makefile do this, allows hello-world to compile -#if UIP_CONF_IPV6 +//define NETSTACK_CONF_WITH_IPV6 1 //Let the makefile do this, allows hello-world to compile +#if NETSTACK_CONF_WITH_IPV6 #define UIP_CONF_ICMP6 1 #define UIP_CONF_UDP 1 #define UIP_CONF_TCP 1 @@ -108,12 +99,10 @@ void clock_adjust_ticks(clock_time_t howmany); /* The new NETSTACK interface requires RF230BB */ #if RF230BB #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 -#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 //for barebones driver, sicslowpan calls radio->read function -#undef PACKETBUF_CONF_HDR_SIZE //RF230BB takes the packetbuf default for header size #define UIP_CONF_LLH_LEN 0 /* No radio cycling */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #define NETSTACK_CONF_NETWORK sicslowpan_driver #else #define NETSTACK_CONF_NETWORK rime_driver @@ -135,21 +124,16 @@ void clock_adjust_ticks(clock_time_t howmany); #else /* Original combined RF230/mac code will not compile with current contiki stack */ -//#define PACKETBUF_CONF_HDR_SIZE 0 //RF230 handles headers internally -/* 0 for IPv6, or 1 for HC1, 2 for HC01 */ -#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 -#define SICSLOWPAN_CONF_COMPRESSION_HC1 1 -#define SICSLOWPAN_CONF_COMPRESSION_HC01 2 //NB '2' is now HC06 in the core mac! //FTH081105 -#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_CONF_COMPRESSION_HC01 +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #define SICSLOWPAN_CONF_MAXAGE 5 #define UIP_CONF_LLH_LEN 14 #endif /*RF230BB */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_FRAG 1 -#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LL_802154 1 #define UIP_CONF_MAX_CONNECTIONS 2 #define UIP_CONF_MAX_LISTENPORTS 2 @@ -159,11 +143,9 @@ void clock_adjust_ticks(clock_time_t howmany); #define UIP_CONF_FWCACHE_SIZE 0 #define UIP_CONF_IPV6_CHECKS 1 -#define UIP_CONF_IPV6_QUEUE_PKT 0 +#define UIP_CONF_IPV6_QUEUE_PKT 0 #define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_NETIF_MAX_ADDRESSES 3 -#define UIP_CONF_ND6_MAX_PREFIXES 3 -#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_UDP_CHECKSUMS 1 #define UIP_CONF_TCP_SPLIT 1 diff --git a/platform/c128/Makefile.c128 b/platform/c128/Makefile.c128 index 6b73ff04c..0c674ee38 100644 --- a/platform/c128/Makefile.c128 +++ b/platform/c128/Makefile.c128 @@ -31,7 +31,7 @@ # Author: Oliver Schmidt # -CONTIKI_TARGET_SOURCEFILES += pfs.S pfs_write.S +CONTIKI_TARGET_SOURCEFILES += exec.c lseek.c pfs.S pfs_remove.S pfs_seek.S pfs_write.S CONTIKI_CPU = $(CONTIKI)/cpu/6502 include $(CONTIKI_CPU)/Makefile.6502 @@ -46,16 +46,16 @@ endif disk: all $(C1541) -format contiki,00 d71 contiki.d71 - $(C1541) -attach contiki.d71 -write $(CONTIKI_PROJECT).$(TARGET) contiki,p - $(C1541) -attach contiki.d71 -write $(CONTIKI)/tools/$(TARGET)/sample.cfg contiki.cfg,s - $(C1541) -attach contiki.d71 -write cs8900a.eth cs8900a.eth,s - $(C1541) -attach contiki.d71 -write lan91c96.eth lan91c96.eth,s + $(C1541) -attach contiki.d71 -write $(CONTIKI_PROJECT).$(TARGET) contiki,p + $(C1541) -attach contiki.d71 -write $(CONTIKI)/tools/$(TARGET)/sample.cfg contiki.cfg,s + $(C1541) -attach contiki.d71 -write cs8900a.eth cs8900a.eth,s + $(C1541) -attach contiki.d71 -write lan91c96.eth lan91c96.eth,s ifeq ($(findstring WITH_MOUSE,$(DEFINES)),WITH_MOUSE) - $(C1541) -attach contiki.d71 -write $(CC65_HOME)/mou/c128-1351.mou contiki.mou,s + $(C1541) -attach contiki.d71 -write $(CC65_TARGET_DIR)/drv/mou/c128-1351.mou contiki.mou,s endif ifeq ($(HTTPD-CFS),1) - $(C1541) -attach contiki.d71 -write httpd-cfs/index.htm index.htm,s - $(C1541) -attach contiki.d71 -write httpd-cfs/backgrnd.gif backgrnd.gif,s - $(C1541) -attach contiki.d71 -write httpd-cfs/contiki.gif contiki.gif,s - $(C1541) -attach contiki.d71 -write httpd-cfs/notfound.htm notfound.htm,s + $(C1541) -attach contiki.d71 -write httpd-cfs/index.htm index.htm,s + $(C1541) -attach contiki.d71 -write httpd-cfs/backgrnd.gif backgrnd.gif,s + $(C1541) -attach contiki.d71 -write httpd-cfs/contiki.gif contiki.gif,s + $(C1541) -attach contiki.d71 -write httpd-cfs/notfound.htm notfound.htm,s endif diff --git a/platform/c128/contiki-conf.h b/platform/c128/contiki-conf.h index 8aabcca03..057d6473d 100644 --- a/platform/c128/contiki-conf.h +++ b/platform/c128/contiki-conf.h @@ -42,7 +42,11 @@ #define CTK_CONF_WIDGETUP_KEY CH_F5 #define CTK_CONF_WIDGETDOWN_KEY CH_F7 +#if WITH_80COL #define MOUSE_CONF_XTOC(x) ((x) / 4) +#else +#define MOUSE_CONF_XTOC(x) ((x) / 8) +#endif #define MOUSE_CONF_YTOC(y) ((y) / 8) #define BORDERCOLOR COLOR_BLACK @@ -55,21 +59,25 @@ #define WIDGETCOLOR_FWIN COLOR_WHITE #define WIDGETCOLOR_HLINK COLOR_CYAN -#define EMAIL_CONF_WIDTH 79 -#define EMAIL_CONF_HEIGHT 20 -#define EMAIL_CONF_ERASE 0 - -#define FTP_CONF_WIDTH 38 -#define FTP_CONF_HEIGHT 22 - +#if WITH_80COL #define IRC_CONF_WIDTH 80 +#else +#define IRC_CONF_WIDTH 40 +#endif #define IRC_CONF_HEIGHT 24 -#define WWW_CONF_WEBPAGE_WIDTH 80 -#define WWW_CONF_WEBPAGE_HEIGHT 20 -#define WWW_CONF_HISTORY_SIZE 0 -#define WWW_CONF_MAX_URLLEN 78 -#define WWW_CONF_MAX_NUMPAGEWIDGETS 20 -#define WWW_CONF_FORMS 0 +#ifndef TELNETD_CONF_MAX_IDLE_TIME +#define TELNETD_CONF_MAX_IDLE_TIME 300 +#endif + +#if WITH_80COL +#define WWW_CONF_WEBPAGE_WIDTH 80 +#else +#define WWW_CONF_WEBPAGE_WIDTH 40 +#endif +#define WWW_CONF_WEBPAGE_HEIGHT 20 +#define WWW_CONF_HISTORY_SIZE 0 +#define WWW_CONF_FORMS 0 +#define WWW_CONF_PAGEATTRIB_SIZE 1500 #endif /* CONTIKI_CONF_H_ */ diff --git a/platform/c128/contiki-main.c b/platform/c128/contiki-main.c index 128ccb9f1..a1856d405 100644 --- a/platform/c128/contiki-main.c +++ b/platform/c128/contiki-main.c @@ -32,8 +32,6 @@ * */ -#include - #include "contiki-net.h" #include "ctk/ctk.h" #include "sys/log.h" @@ -79,7 +77,9 @@ main(void) #endif /* WITH_ARGS */ +#if WITH_80COL videomode(VIDEOMODE_80COL); +#endif /* WITH_80COL */ process_init(); @@ -100,33 +100,15 @@ main(void) uip_setdraddr(&addr); uip_ipaddr(&addr, 192,168,0,1); - resolv_conf(&addr); + uip_nameserver_update(&addr, UIP_NAMESERVER_INFINITE_LIFETIME); ethernet_config = &config; } #endif -#if (WITH_GUI && WITH_MOUSE) - { - static const uint8_t mouse_sprite[64] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0F, 0xE0, 0x00, 0x0F, 0xC0, 0x00, 0x0F, - 0x80, 0x00, 0x0F, 0xC0, 0x00, 0x0D, 0xE0, 0x00, - 0x08, 0xF0, 0x00, 0x00, 0x78, 0x00, 0x00, 0x3C, - 0x00, 0x00, 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, - 0x07, 0x80, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - memcpy((void*)0x0E00, mouse_sprite, sizeof(mouse_sprite)); - *(uint8_t*)0x07F8 = 0x0E00 / 64; - VIC.spr0_color = COLOR_WHITE; - } -#endif /* WITH_GUI && WITH_MOUSE */ - procinit_init(); - process_start((struct process *)ðernet_process, (char *)ethernet_config); + process_start((struct process *)ðernet_process, (void *)ethernet_config); autostart_start(autostart_processes); diff --git a/platform/c128/lib/exec.c b/platform/c128/lib/exec.c new file mode 100644 index 000000000..5a633d45d --- /dev/null +++ b/platform/c128/lib/exec.c @@ -0,0 +1,139 @@ +/* +** Program-chaining function for Commodore platforms. +** +** This copy of the cc65 system library function makes smaller code by using +** Contiki's Personal File System (instead of POSIX) functions. +** +** 2016-03-16, Greg King +** +** This function exploits the program-chaining feature in CBM BASIC's ROM. +** +** CC65's CBM programs have a BASIC program stub. We start those programs by +** RUNning that stub; it SYSes to the Machine Language code. Normally, after +** the ML code exits, the BASIC ROM continues running the stub. But, it has +** no more statements; so, the program stops. +** +** This function puts the desired program's name and device number into a LOAD +** statement. Then, it points BASIC to that statement, so that the ROM will run +** that statement after this program quits. The ROM will load the next program, +** and will execute it (because the LOAD will be seen in a running program). +*/ + +#include +#include +#include +#include +#include + +#include "cfs.h" + + +/* The struct below is a line of BASIC code. It sits in the LOWCODE segment +** to make sure that it won't be hidden by a ROM when BASIC is re-enabled. +** The line is: +** 0 CLR:LOAD""+"" ,01 +** After this function has written into the line, it might look like this: +** 0 CLR:LOAD""+"program name" ,08 +** +** When BASIC's LOAD command asks the Kernal to load a file, it gives the +** Kernal a pointer to a file-name string. CC65's CBM programs use that +** pointer to give a copy of the program's name to main()'s argv[0] parameter. +** But, when BASIC uses a string literal that is in a program, it points +** directly to that literal -- in the models that don't use banked RAM +** (Pet/CBM, VIC-20, and 64). The literal is overwritten by the next program +** that is loaded. So, argv[0] would point to machine code. String operations +** create a new result string -- even when that operation changes nothing. The +** result is put in the string space at the top of BASIC's memory. So, the ""+ +** in this BASIC line guarantees that argv[0] will get a name from a safe place. +*/ +#pragma data-name(push, "LOWCODE") +static struct line { + const char end_of_line; /* fake previous line */ + const struct line* const next; + const unsigned line_num; + const char CLR_token, colon, LOAD_token, quotes[2], add_token, quote; + char name[21]; + const char comma; + char unit[3]; +} basic = { + '\0', &basic + 1, /* high byte of link must be non-zero */ + 0, 0x9C, ':', 0x93, "\"\"", 0xAA, '\"', + "\" ", /* format: "123:1234567890123456\"" */ + ',', "01" +}; +#pragma data-name(pop) + +/* These values are platform-specific. */ +extern const void* vartab; /* points to BASIC program variables */ +#pragma zpsym("vartab") +extern const void* memsize; /* points to top of BASIC RAM */ +#pragma zpsym("memsize") +extern const struct line* txtptr; /* points to BASIC code */ +#pragma zpsym("txtptr") +extern char basbuf[]; /* BASIC's input buffer */ +extern void basbuf_len[]; +#pragma zpsym("basbuf_len") + + +int __fastcall__ +exec(const char *progname, const char *cmdline) +{ + static int fd; + static unsigned char dv, n; + + /* Exclude devices that can't load files. */ + /* (Use hand optimization, to make smaller code.) */ + dv = getcurrentdevice(); + if(dv < 8 && __AX__ != 1 || __AX__ > 30) { + return _mappederrno(9); /* illegal device number */ + } + utoa(dv, basic.unit, 10); + + /* Tape files can be openned only once; skip this test for the Datasette. */ + if(dv != 1) { + /* Don't try to run a program that can't be found. */ + fd = cfs_open(progname, CFS_READ); + if(fd < 0) { + return -1; + } + cfs_close(fd); + } + + n = 0; + do { + if((basic.name[n] = progname[n]) == '\0') { + break; + } + } while(++n < 20); /* truncate long names */ + basic.name[n] = '\"'; + +/* This next part isn't needed by machines that put +** BASIC source and variables in different RAM banks. +*/ +#if !defined(__C128__) + /* cc65 program loads might extend beyond the end of the RAM that is allowed + ** for BASIC. Then, the LOAD statement would complain that it is "out of + ** memory". Some pointers that say where to put BASIC program variables + ** must be changed, so that we do not get that error. One pointer is + ** changed here; a BASIC CLR statement changes the others. Some space is + ** needed for the file-name string. Subtracting an entire RAM page allows + ** better optimization of this expression. + */ + vartab = (char*)memsize - 0x0100; +#endif + + /* Build the next program's argument list. */ + basbuf[0] = 0x8F; /* REM token */ + basbuf[1] = '\0'; + if(cmdline != NULL) { + strncat(basbuf, cmdline, (size_t)basbuf_len - 2); + } + + /* Tell the ROM where to find that BASIC program. */ + txtptr = &basic; + + /* (The return code, in ST [status], will be destroyed by LOAD. + ** So, don't bother to set it here.) + */ + exit(__AX__); +} diff --git a/platform/sky/dev/light.h b/platform/c128/lib/lseek.c similarity index 80% rename from platform/sky/dev/light.h rename to platform/c128/lib/lseek.c index 52962b162..d79f9e529 100644 --- a/platform/sky/dev/light.h +++ b/platform/c128/lib/lseek.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Swedish Institute of Computer Science + * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,14 +27,17 @@ * SUCH DAMAGE. * * This file is part of the Contiki operating system. + * + * Author: Oliver Schmidt * */ -#ifndef LIGHT_H_ -#define LIGHT_H_ -void sensors_light_init(void); +#include -unsigned sensors_light1(void); -unsigned sensors_light2(void); - -#endif /* LIGHT_H_ */ +/*-----------------------------------------------------------------------------------*/ +off_t +__fastcall__ lseek(int fd, off_t offset, int whence) +{ + return (off_t)-1; +} +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c128/lib/pfs.S b/platform/c128/lib/pfs.S index e82a1cb7c..7947b67d8 100644 --- a/platform/c128/lib/pfs.S +++ b/platform/c128/lib/pfs.S @@ -29,103 +29,212 @@ ; This file is part of the Contiki operating system. ; ; Author: Kajtar Zsolt +; Author: Greg King ; ;--------------------------------------------------------------------- - .define F_IDE64 0 ; support IDE64, not on C128 +.define F_IDE64 0 ; C128 doesn't have IDE64 - .constructor init_pfs - .destructor done_pfs - .importzp ptr1, ptr2, ptr3, sp - .import curunit, __filetype, popax, addysp, subysp - .export pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend - .if F_IDE64 - .export ide64_rwprepare, ide64_rwfinish - .endif - .export _pfs_open, _pfs_read, _pfs_close -;--------------------------------------------------------------------- -F_EOF = $80 -F_NBLK = $40 -F_OPEN = $20 -F_MAXLEN = 80 ;max filename length -ST = $90 ;status -FN = $BB ;filename -FNL = $B7 ;filenamelength -LF = $B8 ;logical file number -SA = $B9 ;secondary address -OPEN = $FFC0 -CLOSE = $FFC3 -CHKIN = $FFC6 -CHKOUT = $FFC9 -CLRCHN = $FFCC -CHRIN = $FFCF -CHROUT = $FFD2 -SETLFS = $FFBA -SETNAM = $FFBD -CLALL = $FFE7 -WRITE = $DEF1 -READ = $DEF4 -;--------------------------------------------------------------------- - .bss + .constructor init_pfs + .destructor done_pfs + .importzp sp, ptr1, ptr2, ptr3 + .import curunit, __filetype, popax, addysp, subysp + .export pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend +.if F_IDE64 + .export ide64_rwprepare, ide64_rwfinish +.endif + .export cmdc, flags + .export pfs_makename, pfs_scratch -cmdc: .res 1 -flags: .res 10 + .export _pfs_open, _pfs_read, _pfs_close +;--------------------------------------------------------------------- +MAXLEN = 80 ;maximum filename length + +; Flag bits +F_EOF = %10000000 ;end of file +F_NBLK = %01000000 ;block read/write not available +F_OPEN = %00100000 + +; Kernal variables +ST := $90 ;status +FN := $BB ;filename +FNL := $B7 ;filename length +LF := $B8 ;logical file number + +OPNVec := $031A ;address vector to OPEN function's code + +; IDEDOS function +READ := $DEF4 + +; Kernal functions +SETLFS := $FFBA +SETNAM := $FFBD +OPEN := $FFC0 +CLOSE := $FFC3 +CHKIN := $FFC6 +CHKOUT := $FFC9 +CLRCHN := $FFCC +CHRIN := $FFCF +CHROUT := $FFD2 ;--------------------------------------------------------------------- .data -illchr: .byte $3A, $2A, $3F, $3D ;illegal chars -pw: .byte $2C -filet: .byte $50, $2C, $57 ;,p,w +; illchr and sw must stay together because the comma, also, is illegal in names. +illchr: .byte "*?:=" ;illegal chars +sw: .byte ",s,w" +cmdc: .byte 0 +flags: .res 10 ;(Kernal allows only ten open files) ;--------------------------------------------------------------------- - .segment "INIT" + .segment "ONCE" init_pfs: - ldy #F_MAXLEN+8 - jsr subysp ;allocate - lda #0 - sta FNL ;no name - ldy #15-1 - jsr open2 ;open command channel + ldy #MAXLEN + 8 + jsr subysp ;allocate because open2 will free it + lda #0 ;no name, file number 1 + sta FNL + ldy #15 - 1 ;secondary address 15 + jsr open2 ;open command channel sta cmdc rts ;--------------------------------------------------------------------- .code -error3: jmp error - _pfs_open: - sta ptr2 - ; Pop and store name + sta ptr2 ;save open-mode flags + + ; Get and store name jsr popax + jsr pfs_makename + lda FNL + beq error ;must have a filename + + lda #2 - 1 ;file number + tay ;secondary address +open2: sta ptr2 + sty ptr2 + 1 + +next: inc ptr2 ;next file number + ldx ptr2 ;file number + cpx #.sizeof(flags) + 1 + bcs error ;no more files + lda flags - 1,x + bne next ;already used + lda ptr2 + 1 + bne nextsa + inx + stx ptr2 + 1 +nextsa: inc ptr2 + 1 ;next channel +retr: lda ptr2 ;file number + ldx curunit + ldy ptr2 + 1 ;secondary address (channel number) + jsr SETLFS + jsr OPEN ;open a pair of files (in computer and drive) + bcs oerr ;branch if could not open computer file + ldx cmdc + beq opok ;branch if error channel just was openned + jsr CHKIN + bcs error + jsr CHRIN + pha ;first digit of error code + jsr CHRIN + sta ptr1 ;second digit +@L4: jsr CHRIN ;flush status message + lda ST + beq @L4 + jsr CLRCHN + pla + cmp #'2' + bcc opok ;no serious error + pha + lda ptr2 + jsr CLOSE ;close computer file + pla + ldx ptr1 + cmp #'7' ;no channel? + bne nnoc + cpx #'0' + bne error ;not "no channel" + lda ptr2 + 1 + cmp #14 + bcc nextsa ;try next channel + bcs error ;give up + +opok: ldx ptr2 + lda #F_OPEN + sta flags - 1,x + txa ;OK, return file number +ret0: ldx #>$0000 +ret: ldy #MAXLEN + 8 ;free filename space + jmp addysp + +oerr: dec ptr2 + 1 + cmp #2 ;already open, + beq next ;retry with next + +error: lda #<-1 + tax ;failed + bne ret + +nnoc: inc ptr3 + bne error ;no retry + cmp #'6' + bne error ;not "file exists" + cpx #'3' + bne error + jsr pfs_scratch + bcc retr + bcs error ;branch always + +pfs_scratch: + ldx cmdc + jsr CHKOUT + bcs @L5 + ldy #1 + lda #'s' ;scratch +@L4: jsr CHROUT + lda (FN),y + iny + cmp #',' + bne @L4 + lda #$0D ;carriage return + jsr CHROUT + jsr CLRCHN + clc ;carry = 0: OK +@L5: rts ;carry = 1: error + +pfs_makename: sta FN - stx FN+1 ;filename (kernal) - ldy #F_MAXLEN+8 - jsr subysp ;allocate name - ldy #255 + stx FN+1 ;Kernal filename pointer + ldy #MAXLEN + 8 + jsr subysp ;allocate name space + + ; Validate the name; and, find its length + ldy #<-1 sty ptr3 sty ptr1 @L10: iny - cpy #F_MAXLEN - bcs error3 ;too long... - ldx #4 ;4+1 (comma) + cpy #MAXLEN + bcs badchr ;too long + lda (FN),y + ldx #.sizeof(illchr); 4 + 1 (includes comma) @L12: cmp illchr,x - beq error3 ;illegal char? + beq badchr ;illegal char dex bpl @L12 - cmp #$2F + cmp #'/' bne @L11 - sty ptr1 ;last slash -@L11: lda (FN),y + sty ptr1 ;last slash +@L11: tax ;test for '\0' bne @L10 - sty FNL + cpy #0 + beq badchr ;no name - tay - tax - lda #$30 ;this partition + tay ;zero index reg. + lda #'0' ;drive 0 or current partition sta (sp),y iny inc ptr1 beq nopath - lda #$2F + lda #'/' @L13: sta (sp),y iny lda (FN,x) @@ -134,158 +243,67 @@ _pfs_open: inc FN+1 @L14: cpy ptr1 bcc @L13 - lda #$2F + ;lda #'/' ; (.A already has a slash) sta (sp),y iny -nopath: lda #$3A +nopath: lda #':' @L16: sta (sp),y iny lda (FN,x) inc FN bne @L15 inc FN+1 -@L15: ora #0 +@L15: ora #$00 ;test for '\0' bne @L16 lsr ptr2 - bcs ro ;read only + bcs ro ;read-only (read-write not supported) lda __filetype - sta filet ;set filetype - ldx #252 -@L20: lda pw-252,x - sta (sp),y ;write + sta sw + 1 ;set filetype + lsr ptr2 + lda #'w' ;write-only + lsr ptr2 + bcc write + lda #'a' ;append +write: sta sw + 3 ;set mode + ldx #$0100 - .sizeof(sw) +@L20: lda sw - ($0100 - .sizeof(sw)),x + sta (sp),y iny inx bne @L20 -ro: tya ;name length (kernal) +ro: tya ;pathname length ldx sp ldy sp+1 - jsr SETNAM +namset: jmp SETNAM - lda #0 ;file number - tay ;secondary address -open2: sta ptr2 - sty ptr2+1 - -next: inc ptr2 ;next file number - ldx ptr2 ;file number - cpx #11 - bcs error ;no more files - lda flags-1,x - bne next ;already used - lda ptr2+1 - bne nextsa - inx - stx ptr2+1 -nextsa: inc ptr2+1 ;next channel -retr: lda ptr2 ;file number - ldx curunit - ldy ptr2+1 ;secondary address - jsr SETLFS - jsr OPEN ;open - bcs oerr - ldx cmdc - beq opok ;error channel open - jsr CHKIN - bcs error - jsr CHRIN - pha - jsr CHRIN - sta ptr1 -@L4: jsr CHRIN - lda ST - beq @L4 - jsr CLRCHN - pla - tax - lsr - cmp #$18 ;no serious error - beq opok - txa - pha - lda ptr2 - jsr CLOSE ;close - pla - ldx ptr1 - cmp #$37 ;no channel? - bne nnoc - cpx #$30 - bne error ;not no channel - lda ptr2+1 - cmp #14 - bcc nextsa ;try next channel - bcs error ;give up - -opok: ldx ptr2 - lda #F_OPEN - sta flags-1,x - txa ;ok, return file number - ldx #0 -ret: ldy #F_MAXLEN+8 ; free filename - jmp addysp - -oerr: dec ptr2+1 - cmp #2 ;already open, - beq next ;retry with next - -error: lda #$FF - tax ;failed - bne ret - -nnoc: inc ptr3 - bne error ;no retry - cmp #$36 - bne error ;no exists - cpx #$33 - bne error - ldx cmdc - jsr CHKOUT - bcs error - lda FNL - sec - sbc #5 - tax - lda #$53 ;scratch - jsr CHROUT - ldy #1 -@L4: lda (FN),y - iny - jsr CHROUT - dex - bne @L4 - lda #$3D - jsr CHROUT - iny - lda (FN),y - jsr CHROUT - lda #$0d - jsr CHROUT - jsr CLRCHN - jmp retr +badchr: lda #0 + beq namset .proc _pfs_read jsr pfs_rwcommon ; pop params, check handle beq error2 ; not open bmi eof - .if F_IDE64 - asl + +.if F_IDE64 + asl a bmi nblk ; no block operation jsr CHKIN bcs error2 - + ; check support jsr ide64_rwprepare bcs norm - - ; read + + ; do a block read jsr READ bcs nosup jmp ide64_rwfinish nosup: lda #F_NBLK jsr pfs_rwsetflags - .endif +.endif ; Valid lfn. Make it the input file nblk: jsr CHKIN @@ -296,15 +314,15 @@ norm: ldy #0 @L3: inc ptr1 bne @L0 inc ptr1+1 - beq done ; branch always + beq done ; Read the next byte @L0: jsr CHRIN tax ; save the input byte - lda ST ; read the IEEE status - cmp #1 ; save it - and #%10111111 ; check anything but the EOI bit + lda ST ; read the file status + cmp #$01 ; save it + and #%10111111 ; check anything but the EOF bit bne error5 ; assume device not present ; Store the byte just read @@ -314,45 +332,60 @@ norm: ldy #0 bne @L1 inc ptr2+1 ; *buf++ = A; - ; Get the status again and check the EOI bit -@L1: bcc @L3 ; loop if no end of file + ; Get the status again; and, check the EOF bit +@L1: bcc @L3 ; loop if not end of file - ; Set the EOI flag and bail out + ; Set the EOF flag; and, bail out lda #F_EOF jsr pfs_rwsetflags - ; Read done, close the input channel -done: jsr CLRCHN ; clrchn + ; Read done; cancel the input channel +done: jsr CLRCHN ; Return the number of chars read -eof: jmp pfs_rwcommonend +eof: +; jmp pfs_rwcommonend ; (fall through) +.endproc + +.proc pfs_rwcommonend + lda ptr2 + sec + sbc ptr3 + pha + lda ptr2+1 + sbc ptr3+1 + tax + pla + rts .endproc - ; Error entry, file is not open done_pfs: - ldx #10 -@L2: ldy flags-1,x ; file open? + ldx #.sizeof(flags) +@L2: ldy flags - 1,x ; file open? beq @L1 txa - jsr _pfs_close + jsr close1 @L1: dex - bne @L2 + bne @L2 rts -error5: jsr CLRCHN ; clrchn +error5: jsr CLRCHN -error2: ldx #255 + ; Error entry, file is not open +error2: ldx #>-1 txa rts _pfs_close: - pha - jsr CLOSE ;close + cmp #.sizeof(flags) + 1 + bcs close0 ; don't close if not valid file number +close1: pha + jsr CLOSE pla tax - lda #0 - sta flags-1,x - rts + lda #$00 + sta flags - 1,x +close0: rts ; .X = file number .proc pfs_rwcommon eor #$FF @@ -370,70 +403,56 @@ _pfs_close: jsr popax ; get the handle sta LF - lda #0 - beq pfs_rwsetflags + lda #$00 +; beq pfs_rwsetflags ; (fall through) .endproc - .if F_IDE64 -.proc ide64_rwprepare - sec - lda ptr1+1 - eor #255 - beq small ; too small, not worth it - tay - lda ptr1 ; setup registers - eor #255 - tax - lda $031B - eor #$DE - bne noide ; open vector set? - lda $DE60 - eor #$49 - bne noide ; check identification - lda $DE61 - eor #$44 - bne noide - lda $DE62 - eor #$45 - bne noide - clc - lda #ptr2 -small: rts - -noide: lda #F_NBLK - bne pfs_rwsetflags -.endproc - .endif - .proc pfs_rwsetflags ldx LF - ora flags-1,x - sta flags-1,x + ora flags - 1,x + sta flags - 1,x rts .endproc - .if F_IDE64 +.if F_IDE64 +.proc ide64_rwprepare + sec ; assume it won't use IDEDOS + lda ptr1+1 + eor #$FF ; convert -count-1 back to count + beq small ; too small, not worth it + tay + lda ptr1 ; set up registers + eor #$FF + tax + lda OPNVec+1 + eor #>$DE00 + bne noide ; is OPEN vector set to IDEDOS? + lda $DE60 + eor #'i' + bne noide ; check identification + lda $DE61 + eor #'d' + bne noide + lda $DE62 + eor #'e' + bne noide + clc ; it will use IDEDOS + lda #ptr2 +small: rts + +noide: lda #F_NBLK + bne pfs_rwsetflags +.endproc + .proc ide64_rwfinish - txa + txa ; push .YX pha tya pha jsr CLRCHN - pla - tax - pla - rts -.endproc - .endif - -.proc pfs_rwcommonend - lda ptr2 - sec - sbc ptr3 - pha - lda ptr2+1 - sbc ptr3+1 + pla ; pull .XA tax pla rts .endproc +.endif diff --git a/platform/c128/lib/pfs_remove.S b/platform/c128/lib/pfs_remove.S new file mode 100644 index 000000000..7477e4314 --- /dev/null +++ b/platform/c128/lib/pfs_remove.S @@ -0,0 +1,59 @@ +; +; Copyright (c) 2016, Greg King +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions, and the following disclaimer. +; 2. 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. +; 3. Neither the name of the author nor the names of contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +; +; This file is part of the Contiki operating system. +; +; Author: Greg King +; +;--------------------------------------------------------------------- + .importzp ptr2 + .import addysp + .import pfs_makename, pfs_scratch + + .export _pfs_remove +;--------------------------------------------------------------------- +MAXLEN = 80 ; max. filename length + +FNL := $B7 ; filename length +;--------------------------------------------------------------------- +.proc _pfs_remove + asl ptr2 ; force pfs_makename to format for pfs_scratch + jsr pfs_makename + ldx FNL + beq error ; no name + + jsr pfs_scratch + ldx #>$0000 + bcs error +ret: txa + ldy #MAXLEN + 8 ; free filename space + jmp addysp + +error: dex ;(ldx #>-1) + bne ret +.endproc diff --git a/platform/c128/lib/pfs_seek.S b/platform/c128/lib/pfs_seek.S new file mode 100644 index 000000000..4ef0014d1 --- /dev/null +++ b/platform/c128/lib/pfs_seek.S @@ -0,0 +1,46 @@ +; +; Copyright (c) 2016, Greg King +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions, and the following disclaimer. +; 2. 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. +; 3. Neither the name of the author nor the names of contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +; +; This file is part of the Contiki operating system. +; +; Author: Greg King +; +;--------------------------------------------------------------------- + .importzp sp, sreg, ptr1, ptr2, ptr3 + .import popax, incsp6 + .import cmdc, flags + + .export _pfs_seek +;--------------------------------------------------------------------- +.proc _pfs_seek + lda #<-1 ; seek not implemented + tax + stx sreg ; return long data type + stx sreg+1 + jmp incsp6 ; drop int and long arguments from stack +.endproc diff --git a/platform/c128/lib/pfs_write.S b/platform/c128/lib/pfs_write.S index 0fc8e3160..e17ff91b7 100644 --- a/platform/c128/lib/pfs_write.S +++ b/platform/c128/lib/pfs_write.S @@ -31,27 +31,33 @@ ; Author: Kajtar Zsolt ; ;--------------------------------------------------------------------- - .define F_IDE64 0 ; support IDE64, 100 byte only +.define F_IDE64 0 ; c128 doesn't have IDE64 - .importzp ptr1, ptr2 - .import pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend - .if F_IDE64 - .import ide64_rwprepare, ide64_rwfinish - .endif - .export _pfs_write + .importzp ptr1, ptr2 + .import pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend +.if F_IDE64 + .import ide64_rwprepare, ide64_rwfinish +.endif + + .export _pfs_write ;--------------------------------------------------------------------- -F_NBLK = $40 -ST = $90 ;status -CHKOUT = $FFC9 -CLRCHN = $FFCC -CHROUT = $FFD2 -WRITE = $DEF1 +F_NBLK = %01000000 ;block read/write not available + +ST := $90 ;status + +; IDEDOS function +WRITE := $DEF1 + +; Kernal functions +CHKOUT := $FFC9 +CLRCHN := $FFCC +CHROUT := $FFD2 ;--------------------------------------------------------------------- .code -error5: jsr CLRCHN ; clrchn +error5: jsr CLRCHN -error2: ldx #255 +error2: ldx #>-1 txa rts @@ -59,8 +65,8 @@ error2: ldx #255 jsr pfs_rwcommon ; pop params, check handle beq error2 ; not open - .if F_IDE64 - asl +.if F_IDE64 + asl a bmi nblk ; no block operation jsr CHKOUT @@ -70,7 +76,7 @@ error2: ldx #255 jsr ide64_rwprepare bcs norm - ; write + ; do a block write jsr WRITE bcs nosup jmp ide64_rwfinish @@ -98,10 +104,9 @@ norm: ldy #0 lda ST beq @L3 bne error5 ; bail out on errors -@L2: - ; Wrote all chars, close the output channel - jsr CLRCHN + ; Wrote all chars.; cancel the output channel +@L2: jsr CLRCHN ; Return the number of chars written jmp pfs_rwcommonend diff --git a/platform/c64/Makefile.c64 b/platform/c64/Makefile.c64 index ddc94d586..f78dcf717 100644 --- a/platform/c64/Makefile.c64 +++ b/platform/c64/Makefile.c64 @@ -31,13 +31,17 @@ # Author: Oliver Schmidt # -CONTIKI_TARGET_SOURCEFILES += pfs.S pfs_write.S +CONTIKI_TARGET_SOURCEFILES += exec.c lseek.c pfs.S pfs_remove.S pfs_seek.S pfs_write.S CONTIKI_CPU = $(CONTIKI)/cpu/6502 include $(CONTIKI_CPU)/Makefile.6502 CFLAGS += -DWITH_PETSCII +ifeq ($(findstring WITH_80COL,$(DEFINES)),WITH_80COL) + LDFLAGS += c64-soft80.o +endif + ifeq ($(MAKECMDGOALS),disk) ifndef C1541 ${error C1541 not defined! You must specify where VICE c1541 resides} @@ -46,16 +50,16 @@ endif disk: all $(C1541) -format contiki,00 d64 contiki.d64 - $(C1541) -attach contiki.d64 -write $(CONTIKI_PROJECT).$(TARGET) contiki,p - $(C1541) -attach contiki.d64 -write $(CONTIKI)/tools/$(TARGET)/sample.cfg contiki.cfg,s - $(C1541) -attach contiki.d64 -write cs8900a.eth cs8900a.eth,s - $(C1541) -attach contiki.d64 -write lan91c96.eth lan91c96.eth,s + $(C1541) -attach contiki.d64 -write $(CONTIKI_PROJECT).$(TARGET) contiki,p + $(C1541) -attach contiki.d64 -write $(CONTIKI)/tools/$(TARGET)/sample.cfg contiki.cfg,s + $(C1541) -attach contiki.d64 -write cs8900a.eth cs8900a.eth,s + $(C1541) -attach contiki.d64 -write lan91c96.eth lan91c96.eth,s ifeq ($(findstring WITH_MOUSE,$(DEFINES)),WITH_MOUSE) - $(C1541) -attach contiki.d64 -write $(CC65_HOME)/mou/c64-1351.mou contiki.mou,s + $(C1541) -attach contiki.d64 -write $(CC65_TARGET_DIR)/drv/mou/c64-1351.mou contiki.mou,s endif ifeq ($(HTTPD-CFS),1) - $(C1541) -attach contiki.d64 -write httpd-cfs/index.htm index.htm,s - $(C1541) -attach contiki.d64 -write httpd-cfs/backgrnd.gif backgrnd.gif,s - $(C1541) -attach contiki.d64 -write httpd-cfs/contiki.gif contiki.gif,s - $(C1541) -attach contiki.d64 -write httpd-cfs/notfound.htm notfound.htm,s + $(C1541) -attach contiki.d64 -write httpd-cfs/index.htm index.htm,s + $(C1541) -attach contiki.d64 -write httpd-cfs/backgrnd.gif backgrnd.gif,s + $(C1541) -attach contiki.d64 -write httpd-cfs/contiki.gif contiki.gif,s + $(C1541) -attach contiki.d64 -write httpd-cfs/notfound.htm notfound.htm,s endif diff --git a/platform/c64/contiki-conf.h b/platform/c64/contiki-conf.h index 0e5581aae..7d5a8d070 100644 --- a/platform/c64/contiki-conf.h +++ b/platform/c64/contiki-conf.h @@ -42,7 +42,11 @@ #define CTK_CONF_WIDGETUP_KEY CH_F5 #define CTK_CONF_WIDGETDOWN_KEY CH_F7 +#if WITH_80COL +#define MOUSE_CONF_XTOC(x) ((x) / 4) +#else #define MOUSE_CONF_XTOC(x) ((x) / 8) +#endif #define MOUSE_CONF_YTOC(y) ((y) / 8) #define BORDERCOLOR COLOR_BLACK @@ -55,25 +59,24 @@ #define WIDGETCOLOR_FWIN COLOR_GRAY3 #define WIDGETCOLOR_HLINK COLOR_CYAN -#define EMAIL_CONF_WIDTH 39 -#define EMAIL_CONF_HEIGHT 20 -#define EMAIL_CONF_ERASE 0 - -#define FTP_CONF_WIDTH 18 -#define FTP_CONF_HEIGHT 22 - +#if WITH_80COL +#define IRC_CONF_WIDTH 80 +#else #define IRC_CONF_WIDTH 40 +#endif #define IRC_CONF_HEIGHT 24 -#define WWW_CONF_WEBPAGE_WIDTH 40 -#define WWW_CONF_WEBPAGE_HEIGHT 20 -#define WWW_CONF_HISTORY_SIZE 4 -#define WWW_CONF_MAX_URLLEN 80 -#define WWW_CONF_MAX_NUMPAGEWIDGETS 20 -#define WWW_CONF_FORMS 1 -#define WWW_CONF_MAX_FORMACTIONLEN 20 -#define WWW_CONF_MAX_INPUTNAMELEN 20 -#define WWW_CONF_MAX_INPUTVALUELEN 20 -#define WWW_CONF_WGET_EXEC(url) exec("wget", url) +#ifndef TELNETD_CONF_MAX_IDLE_TIME +#define TELNETD_CONF_MAX_IDLE_TIME 300 +#endif + +#if WITH_80COL +#define WWW_CONF_WEBPAGE_WIDTH 80 +#else +#define WWW_CONF_WEBPAGE_WIDTH 40 +#endif +#define WWW_CONF_WEBPAGE_HEIGHT 20 +#define WWW_CONF_HISTORY_SIZE 4 +#define WWW_CONF_WGET_EXEC(url) exec("wget", url) #endif /* CONTIKI_CONF_H_ */ diff --git a/platform/c64/contiki-main.c b/platform/c64/contiki-main.c index e6ebfdb3a..f2b4aae18 100644 --- a/platform/c64/contiki-main.c +++ b/platform/c64/contiki-main.c @@ -32,7 +32,7 @@ * */ -#include +#include #include "contiki-net.h" #include "ctk/ctk.h" @@ -79,6 +79,10 @@ main(void) #endif /* WITH_ARGS */ +#if WITH_80COL + _heapadd((void *)0x0400, 0x0400); +#endif /* WITH_80COL */ + process_init(); #if 1 @@ -98,33 +102,15 @@ main(void) uip_setdraddr(&addr); uip_ipaddr(&addr, 192,168,0,1); - resolv_conf(&addr); + uip_nameserver_update(&addr, UIP_NAMESERVER_INFINITE_LIFETIME); ethernet_config = &config; } #endif -#if (WITH_GUI && WITH_MOUSE) - { - static const uint8_t mouse_sprite[64] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0F, 0xE0, 0x00, 0x0F, 0xC0, 0x00, 0x0F, - 0x80, 0x00, 0x0F, 0xC0, 0x00, 0x0D, 0xE0, 0x00, - 0x08, 0xF0, 0x00, 0x00, 0x78, 0x00, 0x00, 0x3C, - 0x00, 0x00, 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, - 0x07, 0x80, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - memcpy((void*)0x0340, mouse_sprite, sizeof(mouse_sprite)); - *(uint8_t*)0x07F8 = 0x0340 / 64; - VIC.spr0_color = COLOR_WHITE; - } -#endif /* WITH_GUI && WITH_MOUSE */ - procinit_init(); - process_start((struct process *)ðernet_process, (char *)ethernet_config); + process_start((struct process *)ðernet_process, (void *)ethernet_config); autostart_start(autostart_processes); diff --git a/platform/c64/lib/exec.c b/platform/c64/lib/exec.c new file mode 100644 index 000000000..5a633d45d --- /dev/null +++ b/platform/c64/lib/exec.c @@ -0,0 +1,139 @@ +/* +** Program-chaining function for Commodore platforms. +** +** This copy of the cc65 system library function makes smaller code by using +** Contiki's Personal File System (instead of POSIX) functions. +** +** 2016-03-16, Greg King +** +** This function exploits the program-chaining feature in CBM BASIC's ROM. +** +** CC65's CBM programs have a BASIC program stub. We start those programs by +** RUNning that stub; it SYSes to the Machine Language code. Normally, after +** the ML code exits, the BASIC ROM continues running the stub. But, it has +** no more statements; so, the program stops. +** +** This function puts the desired program's name and device number into a LOAD +** statement. Then, it points BASIC to that statement, so that the ROM will run +** that statement after this program quits. The ROM will load the next program, +** and will execute it (because the LOAD will be seen in a running program). +*/ + +#include +#include +#include +#include +#include + +#include "cfs.h" + + +/* The struct below is a line of BASIC code. It sits in the LOWCODE segment +** to make sure that it won't be hidden by a ROM when BASIC is re-enabled. +** The line is: +** 0 CLR:LOAD""+"" ,01 +** After this function has written into the line, it might look like this: +** 0 CLR:LOAD""+"program name" ,08 +** +** When BASIC's LOAD command asks the Kernal to load a file, it gives the +** Kernal a pointer to a file-name string. CC65's CBM programs use that +** pointer to give a copy of the program's name to main()'s argv[0] parameter. +** But, when BASIC uses a string literal that is in a program, it points +** directly to that literal -- in the models that don't use banked RAM +** (Pet/CBM, VIC-20, and 64). The literal is overwritten by the next program +** that is loaded. So, argv[0] would point to machine code. String operations +** create a new result string -- even when that operation changes nothing. The +** result is put in the string space at the top of BASIC's memory. So, the ""+ +** in this BASIC line guarantees that argv[0] will get a name from a safe place. +*/ +#pragma data-name(push, "LOWCODE") +static struct line { + const char end_of_line; /* fake previous line */ + const struct line* const next; + const unsigned line_num; + const char CLR_token, colon, LOAD_token, quotes[2], add_token, quote; + char name[21]; + const char comma; + char unit[3]; +} basic = { + '\0', &basic + 1, /* high byte of link must be non-zero */ + 0, 0x9C, ':', 0x93, "\"\"", 0xAA, '\"', + "\" ", /* format: "123:1234567890123456\"" */ + ',', "01" +}; +#pragma data-name(pop) + +/* These values are platform-specific. */ +extern const void* vartab; /* points to BASIC program variables */ +#pragma zpsym("vartab") +extern const void* memsize; /* points to top of BASIC RAM */ +#pragma zpsym("memsize") +extern const struct line* txtptr; /* points to BASIC code */ +#pragma zpsym("txtptr") +extern char basbuf[]; /* BASIC's input buffer */ +extern void basbuf_len[]; +#pragma zpsym("basbuf_len") + + +int __fastcall__ +exec(const char *progname, const char *cmdline) +{ + static int fd; + static unsigned char dv, n; + + /* Exclude devices that can't load files. */ + /* (Use hand optimization, to make smaller code.) */ + dv = getcurrentdevice(); + if(dv < 8 && __AX__ != 1 || __AX__ > 30) { + return _mappederrno(9); /* illegal device number */ + } + utoa(dv, basic.unit, 10); + + /* Tape files can be openned only once; skip this test for the Datasette. */ + if(dv != 1) { + /* Don't try to run a program that can't be found. */ + fd = cfs_open(progname, CFS_READ); + if(fd < 0) { + return -1; + } + cfs_close(fd); + } + + n = 0; + do { + if((basic.name[n] = progname[n]) == '\0') { + break; + } + } while(++n < 20); /* truncate long names */ + basic.name[n] = '\"'; + +/* This next part isn't needed by machines that put +** BASIC source and variables in different RAM banks. +*/ +#if !defined(__C128__) + /* cc65 program loads might extend beyond the end of the RAM that is allowed + ** for BASIC. Then, the LOAD statement would complain that it is "out of + ** memory". Some pointers that say where to put BASIC program variables + ** must be changed, so that we do not get that error. One pointer is + ** changed here; a BASIC CLR statement changes the others. Some space is + ** needed for the file-name string. Subtracting an entire RAM page allows + ** better optimization of this expression. + */ + vartab = (char*)memsize - 0x0100; +#endif + + /* Build the next program's argument list. */ + basbuf[0] = 0x8F; /* REM token */ + basbuf[1] = '\0'; + if(cmdline != NULL) { + strncat(basbuf, cmdline, (size_t)basbuf_len - 2); + } + + /* Tell the ROM where to find that BASIC program. */ + txtptr = &basic; + + /* (The return code, in ST [status], will be destroyed by LOAD. + ** So, don't bother to set it here.) + */ + exit(__AX__); +} diff --git a/platform/wismote/dev/light.h b/platform/c64/lib/lseek.c similarity index 80% rename from platform/wismote/dev/light.h rename to platform/c64/lib/lseek.c index 52962b162..d79f9e529 100644 --- a/platform/wismote/dev/light.h +++ b/platform/c64/lib/lseek.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Swedish Institute of Computer Science + * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,14 +27,17 @@ * SUCH DAMAGE. * * This file is part of the Contiki operating system. + * + * Author: Oliver Schmidt * */ -#ifndef LIGHT_H_ -#define LIGHT_H_ -void sensors_light_init(void); +#include -unsigned sensors_light1(void); -unsigned sensors_light2(void); - -#endif /* LIGHT_H_ */ +/*-----------------------------------------------------------------------------------*/ +off_t +__fastcall__ lseek(int fd, off_t offset, int whence) +{ + return (off_t)-1; +} +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/lib/pfs.S b/platform/c64/lib/pfs.S index 89eb03ae0..49ef496ec 100644 --- a/platform/c64/lib/pfs.S +++ b/platform/c64/lib/pfs.S @@ -29,103 +29,212 @@ ; This file is part of the Contiki operating system. ; ; Author: Kajtar Zsolt +; Author: Greg King ; ;--------------------------------------------------------------------- - .define F_IDE64 1 ; support IDE64, 100 byte only +.define F_IDE64 1 ; support IDE64, >= $0100 bytes only - .constructor init_pfs - .destructor done_pfs - .importzp ptr1, ptr2, ptr3, sp - .import curunit, __filetype, popax, addysp, subysp - .export pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend - .if F_IDE64 - .export ide64_rwprepare, ide64_rwfinish - .endif - .export _pfs_open, _pfs_read, _pfs_close -;--------------------------------------------------------------------- -F_EOF = $80 -F_NBLK = $40 -F_OPEN = $20 -F_MAXLEN = 80 ;max filename length -ST = $90 ;status -FN = $BB ;filename -FNL = $B7 ;filenamelength -LF = $B8 ;logical file number -SA = $B9 ;secondary address -OPEN = $FFC0 -CLOSE = $FFC3 -CHKIN = $FFC6 -CHKOUT = $FFC9 -CLRCHN = $FFCC -CHRIN = $FFCF -CHROUT = $FFD2 -SETLFS = $FFBA -SETNAM = $FFBD -CLALL = $FFE7 -WRITE = $DEF1 -READ = $DEF4 -;--------------------------------------------------------------------- - .bss + .constructor init_pfs + .destructor done_pfs + .importzp sp, ptr1, ptr2, ptr3 + .import curunit, __filetype, popax, addysp, subysp + .export pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend +.if F_IDE64 + .export ide64_rwprepare, ide64_rwfinish +.endif + .export cmdc, flags + .export pfs_makename, pfs_scratch -cmdc: .res 1 -flags: .res 10 + .export _pfs_open, _pfs_read, _pfs_close +;--------------------------------------------------------------------- +MAXLEN = 80 ;maximum filename length + +; Flag bits +F_EOF = %10000000 ;end of file +F_NBLK = %01000000 ;block read/write not available +F_OPEN = %00100000 + +; Kernal variables +ST := $90 ;status +FN := $BB ;filename +FNL := $B7 ;filename length +LF := $B8 ;logical file number + +OPNVec := $031A ;address vector to OPEN function's code + +; IDEDOS function +READ := $DEF4 + +; Kernal functions +SETLFS := $FFBA +SETNAM := $FFBD +OPEN := $FFC0 +CLOSE := $FFC3 +CHKIN := $FFC6 +CHKOUT := $FFC9 +CLRCHN := $FFCC +CHRIN := $FFCF +CHROUT := $FFD2 ;--------------------------------------------------------------------- .data -illchr: .byte $3A, $2A, $3F, $3D ;illegal chars -pw: .byte $2C -filet: .byte $50, $2C, $57 ;,p,w +; illchr and sw must stay together because the comma, also, is illegal in names. +illchr: .byte "*?:=" ;illegal chars +sw: .byte ",s,w" +cmdc: .byte 0 +flags: .res 10 ;(Kernal allows only ten open files) ;--------------------------------------------------------------------- - .segment "INIT" + .segment "ONCE" init_pfs: - ldy #F_MAXLEN+8 - jsr subysp ;allocate - lda #0 - sta FNL ;no name - ldy #15-1 - jsr open2 ;open command channel + ldy #MAXLEN + 8 + jsr subysp ;allocate because open2 will free it + lda #0 ;no name, file number 1 + sta FNL + ldy #15 - 1 ;secondary address 15 + jsr open2 ;open command channel sta cmdc rts ;--------------------------------------------------------------------- .code -error3: jmp error - _pfs_open: - sta ptr2 - ; Pop and store name + sta ptr2 ;save open-mode flags + + ; Get and store name jsr popax + jsr pfs_makename + lda FNL + beq error ;must have a filename + + lda #2 - 1 ;file number + tay ;secondary address +open2: sta ptr2 + sty ptr2 + 1 + +next: inc ptr2 ;next file number + ldx ptr2 ;file number + cpx #.sizeof(flags) + 1 + bcs error ;no more files + lda flags - 1,x + bne next ;already used + lda ptr2 + 1 + bne nextsa + inx + stx ptr2 + 1 +nextsa: inc ptr2 + 1 ;next channel +retr: lda ptr2 ;file number + ldx curunit + ldy ptr2 + 1 ;secondary address (channel number) + jsr SETLFS + jsr OPEN ;open a pair of files (in computer and drive) + bcs oerr ;branch if could not open computer file + ldx cmdc + beq opok ;branch if error channel just was openned + jsr CHKIN + bcs error + jsr CHRIN + pha ;first digit of error code + jsr CHRIN + sta ptr1 ;second digit +@L4: jsr CHRIN ;flush status message + lda ST + beq @L4 + jsr CLRCHN + pla + cmp #'2' + bcc opok ;no serious error + pha + lda ptr2 + jsr CLOSE ;close computer file + pla + ldx ptr1 + cmp #'7' ;no channel? + bne nnoc + cpx #'0' + bne error ;not "no channel" + lda ptr2 + 1 + cmp #14 + bcc nextsa ;try next channel + bcs error ;give up + +opok: ldx ptr2 + lda #F_OPEN + sta flags - 1,x + txa ;OK, return file number +ret0: ldx #>$0000 +ret: ldy #MAXLEN + 8 ;free filename space + jmp addysp + +oerr: dec ptr2 + 1 + cmp #2 ;already open, + beq next ;retry with next + +error: lda #<-1 + tax ;failed + bne ret + +nnoc: inc ptr3 + bne error ;no retry + cmp #'6' + bne error ;not "file exists" + cpx #'3' + bne error + jsr pfs_scratch + bcc retr + bcs error ;branch always + +pfs_scratch: + ldx cmdc + jsr CHKOUT + bcs @L5 + ldy #1 + lda #'s' ;scratch +@L4: jsr CHROUT + lda (FN),y + iny + cmp #',' + bne @L4 + lda #$0D ;carriage return + jsr CHROUT + jsr CLRCHN + clc ;carry = 0: OK +@L5: rts ;carry = 1: error + +pfs_makename: sta FN - stx FN+1 ;filename (kernal) - ldy #F_MAXLEN+8 - jsr subysp ;allocate name - ldy #255 + stx FN+1 ;Kernal filename pointer + ldy #MAXLEN + 8 + jsr subysp ;allocate name space + + ; Validate the name; and, find its length + ldy #<-1 sty ptr3 sty ptr1 @L10: iny - cpy #F_MAXLEN - bcs error3 ;too long... - ldx #4 ;4+1 (comma) + cpy #MAXLEN + bcs badchr ;too long + lda (FN),y + ldx #.sizeof(illchr); 4 + 1 (includes comma) @L12: cmp illchr,x - beq error3 ;illegal char? + beq badchr ;illegal char dex bpl @L12 - cmp #$2F + cmp #'/' bne @L11 - sty ptr1 ;last slash -@L11: lda (FN),y + sty ptr1 ;last slash +@L11: tax ;test for '\0' bne @L10 - sty FNL + cpy #0 + beq badchr ;no name - tay - tax - lda #$30 ;this partition + tay ;zero index reg. + lda #'0' ;drive 0 or current partition sta (sp),y iny inc ptr1 beq nopath - lda #$2F + lda #'/' @L13: sta (sp),y iny lda (FN,x) @@ -134,158 +243,67 @@ _pfs_open: inc FN+1 @L14: cpy ptr1 bcc @L13 - lda #$2F + ;lda #'/' ; (.A already has a slash) sta (sp),y iny -nopath: lda #$3A +nopath: lda #':' @L16: sta (sp),y iny lda (FN,x) inc FN bne @L15 inc FN+1 -@L15: ora #0 +@L15: ora #$00 ;test for '\0' bne @L16 lsr ptr2 - bcs ro ;read only + bcs ro ;read-only (read-write not supported) lda __filetype - sta filet ;set filetype - ldx #252 -@L20: lda pw-252,x - sta (sp),y ;write + sta sw + 1 ;set filetype + lsr ptr2 + lda #'w' ;write-only + lsr ptr2 + bcc write + lda #'a' ;append +write: sta sw + 3 ;set mode + ldx #$0100 - .sizeof(sw) +@L20: lda sw - ($0100 - .sizeof(sw)),x + sta (sp),y iny inx bne @L20 -ro: tya ;name length (kernal) +ro: tya ;pathname length ldx sp ldy sp+1 - jsr SETNAM +namset: jmp SETNAM - lda #0 ;file number - tay ;secondary address -open2: sta ptr2 - sty ptr2+1 - -next: inc ptr2 ;next file number - ldx ptr2 ;file number - cpx #11 - bcs error ;no more files - lda flags-1,x - bne next ;already used - lda ptr2+1 - bne nextsa - inx - stx ptr2+1 -nextsa: inc ptr2+1 ;next channel -retr: lda ptr2 ;file number - ldx curunit - ldy ptr2+1 ;secondary address - jsr SETLFS - jsr OPEN ;open - bcs oerr - ldx cmdc - beq opok ;error channel open - jsr CHKIN - bcs error - jsr CHRIN - pha - jsr CHRIN - sta ptr1 -@L4: jsr CHRIN - lda ST - beq @L4 - jsr CLRCHN - pla - tax - lsr - cmp #$18 ;no serious error - beq opok - txa - pha - lda ptr2 - jsr CLOSE ;close - pla - ldx ptr1 - cmp #$37 ;no channel? - bne nnoc - cpx #$30 - bne error ;not no channel - lda ptr2+1 - cmp #14 - bcc nextsa ;try next channel - bcs error ;give up - -opok: ldx ptr2 - lda #F_OPEN - sta flags-1,x - txa ;ok, return file number - ldx #0 -ret: ldy #F_MAXLEN+8 ; free filename - jmp addysp - -oerr: dec ptr2+1 - cmp #2 ;already open, - beq next ;retry with next - -error: lda #$FF - tax ;failed - bne ret - -nnoc: inc ptr3 - bne error ;no retry - cmp #$36 - bne error ;no exists - cpx #$33 - bne error - ldx cmdc - jsr CHKOUT - bcs error - lda FNL - sec - sbc #5 - tax - lda #$53 ;scratch - jsr CHROUT - ldy #1 -@L4: lda (FN),y - iny - jsr CHROUT - dex - bne @L4 - lda #$3D - jsr CHROUT - iny - lda (FN),y - jsr CHROUT - lda #$0d - jsr CHROUT - jsr CLRCHN - jmp retr +badchr: lda #0 + beq namset .proc _pfs_read jsr pfs_rwcommon ; pop params, check handle beq error2 ; not open bmi eof - .if F_IDE64 - asl + +.if F_IDE64 + asl a bmi nblk ; no block operation jsr CHKIN bcs error2 - + ; check support jsr ide64_rwprepare bcs norm - - ; read + + ; do a block read jsr READ bcs nosup jmp ide64_rwfinish nosup: lda #F_NBLK jsr pfs_rwsetflags - .endif +.endif ; Valid lfn. Make it the input file nblk: jsr CHKIN @@ -296,15 +314,15 @@ norm: ldy #0 @L3: inc ptr1 bne @L0 inc ptr1+1 - beq done ; branch always + beq done ; Read the next byte @L0: jsr CHRIN tax ; save the input byte - lda ST ; read the IEEE status - cmp #1 ; save it - and #%10111111 ; check anything but the EOI bit + lda ST ; read the file status + cmp #$01 ; save it + and #%10111111 ; check anything but the EOF bit bne error5 ; assume device not present ; Store the byte just read @@ -314,45 +332,60 @@ norm: ldy #0 bne @L1 inc ptr2+1 ; *buf++ = A; - ; Get the status again and check the EOI bit -@L1: bcc @L3 ; loop if no end of file + ; Get the status again; and, check the EOF bit +@L1: bcc @L3 ; loop if not end of file - ; Set the EOI flag and bail out + ; Set the EOF flag; and, bail out lda #F_EOF jsr pfs_rwsetflags - ; Read done, close the input channel -done: jsr CLRCHN ; clrchn + ; Read done; cancel the input channel +done: jsr CLRCHN ; Return the number of chars read -eof: jmp pfs_rwcommonend +eof: +; jmp pfs_rwcommonend ; (fall through) +.endproc + +.proc pfs_rwcommonend + lda ptr2 + sec + sbc ptr3 + pha + lda ptr2+1 + sbc ptr3+1 + tax + pla + rts .endproc - ; Error entry, file is not open done_pfs: - ldx #10 -@L2: ldy flags-1,x ; file open? + ldx #.sizeof(flags) +@L2: ldy flags - 1,x ; file open? beq @L1 txa - jsr _pfs_close + jsr close1 @L1: dex - bne @L2 + bne @L2 rts -error5: jsr CLRCHN ; clrchn +error5: jsr CLRCHN -error2: ldx #255 + ; Error entry, file is not open +error2: ldx #>-1 txa rts _pfs_close: - pha - jsr CLOSE ;close + cmp #.sizeof(flags) + 1 + bcs close0 ; don't close if not valid file number +close1: pha + jsr CLOSE pla tax - lda #0 - sta flags-1,x - rts + lda #$00 + sta flags - 1,x +close0: rts ; .X = file number .proc pfs_rwcommon eor #$FF @@ -370,70 +403,56 @@ _pfs_close: jsr popax ; get the handle sta LF - lda #0 - beq pfs_rwsetflags + lda #$00 +; beq pfs_rwsetflags ; (fall through) .endproc - .if F_IDE64 -.proc ide64_rwprepare - sec - lda ptr1+1 - eor #255 - beq small ; too small, not worth it - tay - lda ptr1 ; setup registers - eor #255 - tax - lda $031B - eor #$DE - bne noide ; open vector set? - lda $DE60 - eor #$49 - bne noide ; check identification - lda $DE61 - eor #$44 - bne noide - lda $DE62 - eor #$45 - bne noide - clc - lda #ptr2 -small: rts - -noide: lda #F_NBLK - bne pfs_rwsetflags -.endproc - .endif - .proc pfs_rwsetflags ldx LF - ora flags-1,x - sta flags-1,x + ora flags - 1,x + sta flags - 1,x rts .endproc - .if F_IDE64 +.if F_IDE64 +.proc ide64_rwprepare + sec ; assume it won't use IDEDOS + lda ptr1+1 + eor #$FF ; convert -count-1 back to count + beq small ; too small, not worth it + tay + lda ptr1 ; set up registers + eor #$FF + tax + lda OPNVec+1 + eor #>$DE00 + bne noide ; is OPEN vector set to IDEDOS? + lda $DE60 + eor #'i' + bne noide ; check identification + lda $DE61 + eor #'d' + bne noide + lda $DE62 + eor #'e' + bne noide + clc ; it will use IDEDOS + lda #ptr2 +small: rts + +noide: lda #F_NBLK + bne pfs_rwsetflags +.endproc + .proc ide64_rwfinish - txa + txa ; push .YX pha tya pha jsr CLRCHN - pla - tax - pla - rts -.endproc - .endif - -.proc pfs_rwcommonend - lda ptr2 - sec - sbc ptr3 - pha - lda ptr2+1 - sbc ptr3+1 + pla ; pull .XA tax pla rts .endproc +.endif diff --git a/platform/c64/lib/pfs_remove.S b/platform/c64/lib/pfs_remove.S new file mode 100644 index 000000000..7477e4314 --- /dev/null +++ b/platform/c64/lib/pfs_remove.S @@ -0,0 +1,59 @@ +; +; Copyright (c) 2016, Greg King +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions, and the following disclaimer. +; 2. 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. +; 3. Neither the name of the author nor the names of contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +; +; This file is part of the Contiki operating system. +; +; Author: Greg King +; +;--------------------------------------------------------------------- + .importzp ptr2 + .import addysp + .import pfs_makename, pfs_scratch + + .export _pfs_remove +;--------------------------------------------------------------------- +MAXLEN = 80 ; max. filename length + +FNL := $B7 ; filename length +;--------------------------------------------------------------------- +.proc _pfs_remove + asl ptr2 ; force pfs_makename to format for pfs_scratch + jsr pfs_makename + ldx FNL + beq error ; no name + + jsr pfs_scratch + ldx #>$0000 + bcs error +ret: txa + ldy #MAXLEN + 8 ; free filename space + jmp addysp + +error: dex ;(ldx #>-1) + bne ret +.endproc diff --git a/platform/c64/lib/pfs_seek.S b/platform/c64/lib/pfs_seek.S new file mode 100644 index 000000000..4ef0014d1 --- /dev/null +++ b/platform/c64/lib/pfs_seek.S @@ -0,0 +1,46 @@ +; +; Copyright (c) 2016, Greg King +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions, and the following disclaimer. +; 2. 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. +; 3. Neither the name of the author nor the names of contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +; +; This file is part of the Contiki operating system. +; +; Author: Greg King +; +;--------------------------------------------------------------------- + .importzp sp, sreg, ptr1, ptr2, ptr3 + .import popax, incsp6 + .import cmdc, flags + + .export _pfs_seek +;--------------------------------------------------------------------- +.proc _pfs_seek + lda #<-1 ; seek not implemented + tax + stx sreg ; return long data type + stx sreg+1 + jmp incsp6 ; drop int and long arguments from stack +.endproc diff --git a/platform/c64/lib/pfs_write.S b/platform/c64/lib/pfs_write.S index 7e511e513..82632df8f 100644 --- a/platform/c64/lib/pfs_write.S +++ b/platform/c64/lib/pfs_write.S @@ -31,27 +31,33 @@ ; Author: Kajtar Zsolt ; ;--------------------------------------------------------------------- - .define F_IDE64 1 ; support IDE64, 100 byte only +.define F_IDE64 1 ; support IDE64, >= $0100 bytes only - .importzp ptr1, ptr2 - .import pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend - .if F_IDE64 - .import ide64_rwprepare, ide64_rwfinish - .endif - .export _pfs_write + .importzp ptr1, ptr2 + .import pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend +.if F_IDE64 + .import ide64_rwprepare, ide64_rwfinish +.endif + + .export _pfs_write ;--------------------------------------------------------------------- -F_NBLK = $40 -ST = $90 ;status -CHKOUT = $FFC9 -CLRCHN = $FFCC -CHROUT = $FFD2 -WRITE = $DEF1 +F_NBLK = %01000000 ;block read/write not available + +ST := $90 ;status + +; IDEDOS function +WRITE := $DEF1 + +; Kernal functions +CHKOUT := $FFC9 +CLRCHN := $FFCC +CHROUT := $FFD2 ;--------------------------------------------------------------------- .code -error5: jsr CLRCHN ; clrchn +error5: jsr CLRCHN -error2: ldx #255 +error2: ldx #>-1 txa rts @@ -59,8 +65,8 @@ error2: ldx #255 jsr pfs_rwcommon ; pop params, check handle beq error2 ; not open - .if F_IDE64 - asl +.if F_IDE64 + asl a bmi nblk ; no block operation jsr CHKOUT @@ -70,7 +76,7 @@ error2: ldx #255 jsr ide64_rwprepare bcs norm - ; write + ; do a block write jsr WRITE bcs nosup jmp ide64_rwfinish @@ -98,10 +104,9 @@ norm: ldy #0 lda ST beq @L3 bne error5 ; bail out on errors -@L2: - ; Wrote all chars, close the output channel - jsr CLRCHN + ; Wrote all chars.; cancel the output channel +@L2: jsr CLRCHN ; Return the number of chars written jmp pfs_rwcommonend diff --git a/platform/cc2530dk/Makefile.cc2530dk b/platform/cc2530dk/Makefile.cc2530dk index a163a2aef..77c7d6e14 100644 --- a/platform/cc2530dk/Makefile.cc2530dk +++ b/platform/cc2530dk/Makefile.cc2530dk @@ -19,7 +19,7 @@ CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) CLEAN += *.cc2530dk -ifeq ($(UIP_CONF_IPV6),1) +ifeq ($(CONTIKI_WITH_IPV6),1) CONTIKI_TARGET_SOURCEFILES += viztool.c endif @@ -47,4 +47,5 @@ CONTIKI_CPU=$(CONTIKI)/cpu/cc253x include $(CONTIKI_CPU)/Makefile.cc253x # Default modules -MODULES += core/net/ip core/net/ipv6 core/net/rime core/net core/net/mac core/net/rpl +MODULES += core/net core/net/mac \ + core/net/llsec diff --git a/platform/cc2530dk/contiki-conf.h b/platform/cc2530dk/contiki-conf.h index d176a6756..9c79aa828 100644 --- a/platform/cc2530dk/contiki-conf.h +++ b/platform/cc2530dk/contiki-conf.h @@ -157,19 +157,19 @@ #endif /* Viztool on by default for IPv6 builds */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #ifndef VIZTOOL_CONF_ON #define VIZTOOL_CONF_ON 1 #endif /* VIZTOOL_CONF_ON */ -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /* Network Stack */ #ifndef NETSTACK_CONF_NETWORK -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #define NETSTACK_CONF_NETWORK sicslowpan_driver #else #define NETSTACK_CONF_NETWORK rime_driver -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #endif /* NETSTACK_CONF_NETWORK */ #ifndef NETSTACK_CONF_MAC @@ -193,7 +193,9 @@ #define NETSTACK_CONF_RADIO cc2530_rf_driver /* RF Config */ -#define IEEE802154_CONF_PANID 0x5449 /* TI */ +#ifndef IEEE802154_CONF_PANID +#define IEEE802154_CONF_PANID 0xABCD +#endif #ifndef CC2530_RF_CONF_CHANNEL #define CC2530_RF_CONF_CHANNEL 25 @@ -203,7 +205,7 @@ #define CC2530_RF_CONF_AUTOACK 1 #endif /* CC2530_CONF_AUTOACK */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /* Addresses, Sizes and Interfaces */ /* 8-byte addresses here, 2 otherwise */ #define LINKADDR_CONF_SIZE 8 @@ -224,7 +226,7 @@ #define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_IP_FORWARD 0 #define RPL_CONF_STATS 0 -#define RPL_CONF_MAX_DAG_ENTRIES 1 + #ifndef RPL_CONF_OF #define RPL_CONF_OF rpl_mrhof #endif @@ -257,8 +259,8 @@ /* Define our IPv6 prefixes/contexts here */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 #define SICSLOWPAN_CONF_ADDR_CONTEXT_0 { \ - addr_contexts[0].prefix[0] = 0xaa; \ - addr_contexts[0].prefix[1] = 0xaa; \ + addr_contexts[0].prefix[0] = UIP_DS6_DEFAULT_PREFIX_0; \ + addr_contexts[0].prefix[1] = UIP_DS6_DEFAULT_PREFIX_1; \ } #define MAC_CONF_CHANNEL_CHECK_RATE 8 @@ -267,13 +269,13 @@ #define QUEUEBUF_CONF_NUM 6 #endif -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ /* Network setup for non-IPv6 (rime). */ #define UIP_CONF_IP_FORWARD 1 #define UIP_CONF_BUFFER_SIZE 108 #define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 #define QUEUEBUF_CONF_NUM 8 -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /* Prevent SDCC compile error when UIP_CONF_ROUTER == 0 */ #if !UIP_CONF_ROUTER diff --git a/platform/cc2530dk/contiki-main.c b/platform/cc2530dk/contiki-main.c index 7e63650f9..164481512 100644 --- a/platform/cc2530dk/contiki-main.c +++ b/platform/cc2530dk/contiki-main.c @@ -9,6 +9,7 @@ #include "dev/io-arch.h" #include "dev/dma.h" #include "dev/cc2530-rf.h" +#include "dev/radio.h" #include "dev/watchdog.h" #include "dev/clock-isr.h" #include "dev/port2.h" @@ -79,9 +80,11 @@ fade(int l) CC_NON_BANKED } /*---------------------------------------------------------------------------*/ static void -set_rime_addr(void) CC_NON_BANKED +set_rf_params(void) CC_NON_BANKED { char i; + uint16_t short_addr; + uint8_t ext_addr[8]; #if CC2530_CONF_MAC_FROM_PRIMARY __xdata unsigned char *macp = &X_IEEE_ADDR; @@ -114,8 +117,12 @@ set_rime_addr(void) CC_NON_BANKED FMAP = CC2530_LAST_FLASH_BANK; #endif - for(i = (LINKADDR_SIZE - 1); i >= 0; --i) { - linkaddr_node_addr.u8[i] = *macp; + /* + * Read IEEE address from flash, store in ext_addr. + * Invert endianness (from little to big endian) + */ + for(i = 7; i >= 0; --i) { + ext_addr[i] = *macp; macp++; } @@ -125,6 +132,12 @@ set_rime_addr(void) CC_NON_BANKED ENABLE_INTERRUPTS(); #endif + short_addr = ext_addr[7]; + short_addr |= ext_addr[6] << 8; + + /* Populate linkaddr_node_addr. Maintain endianness */ + memcpy(&linkaddr_node_addr, &ext_addr[8 - LINKADDR_SIZE], LINKADDR_SIZE); + /* Now the address is stored MSB first */ #if STARTUP_CONF_VERBOSE PUTSTRING("Rime configured with address "); @@ -136,7 +149,11 @@ set_rime_addr(void) CC_NON_BANKED PUTCHAR('\n'); #endif - cc2530_rf_set_addr(IEEE802154_PANID); + /* Write params to RF registers */ + NETSTACK_RADIO.set_value(RADIO_PARAM_PAN_ID, IEEE802154_PANID); + NETSTACK_RADIO.set_value(RADIO_PARAM_16BIT_ADDR, short_addr); + NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, CC2530_RF_CHANNEL); + NETSTACK_RADIO.set_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8); return; } /*---------------------------------------------------------------------------*/ @@ -235,7 +252,7 @@ main(void) CC_NON_BANKED /* initialize the netstack */ netstack_init(); - set_rime_addr(); + set_rf_params(); #if BUTTON_SENSOR_ON || ADC_SENSOR_ON process_start(&sensors_process, NULL); @@ -243,11 +260,11 @@ main(void) CC_NON_BANKED ADC_SENSOR_ACTIVATE(); #endif -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(&uip_lladdr.addr, &linkaddr_node_addr, sizeof(uip_lladdr.addr)); queuebuf_init(); process_start(&tcpip_process, NULL); -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #if VIZTOOL_CONF_ON process_start(&viztool_process, NULL); @@ -318,8 +335,7 @@ main(void) CC_NON_BANKED if(SLEEPCMD & SLEEP_MODE0) { #endif /* LPM_MODE==LPM_MODE_PM2 */ - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* We are only interested in IRQ energest while idle or in LPM */ ENERGEST_IRQ_RESTORE(irq_energest); @@ -335,8 +351,7 @@ main(void) CC_NON_BANKED /* Remember energest IRQ for next pass */ ENERGEST_IRQ_SAVE(irq_energest); - ENERGEST_ON(ENERGEST_TYPE_CPU); - ENERGEST_OFF(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); #if (LPM_MODE==LPM_MODE_PM2) SLEEPCMD &= ~SLEEP_OSC_PD; /* Make sure both HS OSCs are on */ diff --git a/platform/cc2530dk/debug.h b/platform/cc2530dk/debug.h index 94eaa4f51..592965843 100644 --- a/platform/cc2530dk/debug.h +++ b/platform/cc2530dk/debug.h @@ -32,7 +32,7 @@ /** * \file - * Header file for debugging functions used by the sensinode port. + * Header file for debugging functions used by the CC2530DK port. * * putstring() and puthex() are from msp430/watchdog.c * diff --git a/platform/cc2530dk/uip-debug.c b/platform/cc2530dk/uip-debug.c index ee7942664..1a1660e65 100644 --- a/platform/cc2530dk/uip-debug.c +++ b/platform/cc2530dk/uip-debug.c @@ -43,7 +43,7 @@ void uip_debug_ipaddr_print(const uip_ipaddr_t *addr) { -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 uint16_t a; unsigned int i; int f; @@ -63,20 +63,8 @@ uip_debug_ipaddr_print(const uip_ipaddr_t *addr) puthex(a & 0xFF); } } -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ PRINTA("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]); -#endif /* UIP_CONF_IPV6 */ -} -/*---------------------------------------------------------------------------*/ -void -uip_debug_lladdr_print(const uip_lladdr_t *addr) -{ - unsigned int i; - for(i = 0; i < sizeof(uip_lladdr_t); i++) { - if(i > 0) { - putstring(":"); - } - puthex(addr->addr[i]); - } +#endif /* NETSTACK_CONF_WITH_IPV6 */ } /*---------------------------------------------------------------------------*/ diff --git a/platform/cc2530dk/viztool.c b/platform/cc2530dk/viztool.c index e6b2fbed3..1901e9f74 100644 --- a/platform/cc2530dk/viztool.c +++ b/platform/cc2530dk/viztool.c @@ -127,8 +127,8 @@ process_request() CC_NON_BANKED if(rt != NULL) { entry_size = sizeof(i) + sizeof(rt->ipaddr) + sizeof(rt->length) - + sizeof(rt->state.lifetime) - + sizeof(rt->state.learned_from); + + sizeof(rt->state.lifetime); + /* + sizeof(rt->state.learned_from); */ memcpy(buf + len, &i, sizeof(i)); len += sizeof(i); @@ -147,11 +147,11 @@ process_request() CC_NON_BANKED len += sizeof(flip); PRINTF(" - %08lx", rt->state.lifetime); - memcpy(buf + len, &rt->state.learned_from, - sizeof(rt->state.learned_from)); - len += sizeof(rt->state.learned_from); + /* memcpy(buf + len, &rt->state.learned_from, */ + /* sizeof(rt->state.learned_from)); */ + /* len += sizeof(rt->state.learned_from); */ - PRINTF(" - %02x [%u]\n", rt->state.learned_from, entry_size); + PRINTF(" - [%u]\n", entry_size); count++; left -= entry_size; diff --git a/platform/cc2538dk/Makefile.cc2538dk b/platform/cc2538dk/Makefile.cc2538dk index 41ccbf507..c1b7890b8 100644 --- a/platform/cc2538dk/Makefile.cc2538dk +++ b/platform/cc2538dk/Makefile.cc2538dk @@ -9,10 +9,7 @@ CONTIKI_TARGET_DIRS = . dev CONTIKI_TARGET_SOURCEFILES += leds.c leds-arch.c CONTIKI_TARGET_SOURCEFILES += contiki-main.c CONTIKI_TARGET_SOURCEFILES += sensors.c smartrf-sensors.c -CONTIKI_TARGET_SOURCEFILES += button-sensor.c adc-sensor.c - -TARGET_START_SOURCEFILES += startup-gcc.c -TARGET_STARTFILES = ${addprefix $(OBJECTDIR)/,${call oname, $(TARGET_START_SOURCEFILES)}} +CONTIKI_TARGET_SOURCEFILES += button-sensor.c als-sensor.c CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) @@ -27,14 +24,25 @@ endif CONTIKI_CPU=$(CONTIKI)/cpu/cc2538 include $(CONTIKI_CPU)/Makefile.cc2538 -MODULES += core/net core/net/ipv6 core/net/mac core/net/ip \ - core/net/rpl core/net/rime core/net/mac/contikimac +MODULES += core/net core/net/mac \ + core/net/mac/contikimac \ + core/net/llsec core/net/llsec/noncoresec + +PYTHON = python +BSL_FLAGS += -e -w -v + +ifdef PORT + BSL_FLAGS += -p $(PORT) +endif BSL = $(CONTIKI)/tools/cc2538-bsl/cc2538-bsl.py -%.upload: %.bin +%.upload: %.bin %.elf ifeq ($(wildcard $(BSL)), ) @echo "ERROR: Could not find the cc2538-bsl script. Did you run 'git submodule update --init' ?" else - python $(BSL) -e -w -v $< + $(eval BSL_ADDRESS_ARG := -a $(shell $(OBJDUMP) -h $*.elf | grep -B1 LOAD | \ + grep -Ev 'LOAD|\-\-' | awk '{print "0x" $$5}' | \ + sort -g | head -1)) + $(PYTHON) $(BSL) $(BSL_FLAGS) $(BSL_ADDRESS_ARG) $< endif diff --git a/platform/cc2538dk/README.md b/platform/cc2538dk/README.md index 966d41333..4bcb2c6f4 100644 --- a/platform/cc2538dk/README.md +++ b/platform/cc2538dk/README.md @@ -29,6 +29,10 @@ In terms of hardware support, the following drivers have been implemented: * Low Power Modes * General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development. * ADC + * PWM + * Cryptoprocessor (AES-ECB/CBC/CTR/CBC-MAC/GCM/CCM-128/192/256, SHA-256) + * Public Key Accelerator (ECDH, ECDSA) + * Flash-based port of Coffee * SmartRF06 EB and BB peripherals * LEDs * Buttons @@ -62,22 +66,15 @@ The platform has been developed and tested under Windows XP, Mac OS X 10.9.1 and Install a Toolchain ------------------- -The toolchain used to build contiki is arm-gcc, also used by other arm-based Contiki ports. If you are using Instant Contiki, you will have a version pre-installed in your system. To find out if this is the case, try this: +The toolchain used to build contiki is arm-gcc, also used by other arm-based Contiki ports. If you are using Instant Contiki, you may have a version pre-installed in your system. - $ arm-none-eabi-gcc -v - Using built-in specs. - Target: arm-none-eabi - Configured with: /scratch/julian/lite-respin/eabi/src/gcc-4.3/configure - ... - (skip) - ... - Thread model: single - gcc version 4.3.2 (Sourcery G++ Lite 2008q3-66) +The platform is currently being used/tested with "GNU Tools for ARM Embedded Processors" (). The current recommended version and the one being used by Contiki's regression tests on Travis is shown below. -The platform is currently being used/tested with the following toolchains: - -* GNU Tools for ARM Embedded Processors. This is the recommended version. Works nicely on OS X. -* Alternatively, you can use this older version for Linux. At the time of writing, this is the version used by Contiki's regression tests. + $ arm-none-eabi-gcc --version + arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 5.2.1 20151202 (release) [ARM/embedded-5-branch revision 231848] + Copyright (C) 2015 Free Software Foundation, Inc. + This is free software; see the source for copying conditions. There is NO + warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Drivers ------- @@ -101,6 +98,11 @@ You will need to install XDS drivers if you want to do anything useful with the * As root or with `sudo`, run the command below (if necessary, replace the `vendor` and `product` arguments with the values you got from `lsusb`): modprobe ftdi_sio vendor=0x403 product=0xa6d1 + + * From Kernel 3.12 run the command below: + + modprobe ftdi_sio + echo 0403 a6d1 > /sys/bus/usb-serial/drivers/ftdi_sio/new_id * You may have have to remove package `brltty`, if it's installed. * The board should have enumerated as `/dev/ttyUSB{0,1}`. `ttyUSB1` will be the UART backchannel. @@ -142,10 +144,14 @@ The CC2538 EM's USB Vendor and Product IDs are the following: The implementation in Contiki is pure CDC-ACM: The Linux and OS X kernels know exactly what to do and drivers are not required. -On windows, you will need to provide a driver: +On windows, you will need to provide a driver. You have two options: - * Download this LUFA CDC-ACM driver: - + * Use the signed or unsigned driver provided by TI in [CC2538 Foundation Firmware](http://www.ti.com/tool/cc2538-sw). You will find them both under the `drivers` directory. + * Download a generic Virtual Serial Port driver and modify it so it works for the CC2538. + +For the latter option: + + * Download this [LUFA CDC-ACM driver](https://raw.githubusercontent.com/abcminiuser/lufa/master/Demos/Device/LowLevel/VirtualSerial/LUFA%20VirtualSerial.inf). * Adjust the VID and PID near the end with the values at the start of this section. * Next time you get prompted for the driver, include the directory containing the .inf file in the search path and the driver will be installed. @@ -246,6 +252,8 @@ If you want to upload the compiled firmware to a node via the serial boot loader For the `cc2538-demo`, the comments at the top of `cc2538-demo.c` describe in detail what the example does. +To generate an assembly listing of the compiled firmware, run `make cc2538-demo.lst`. This may be useful for debugging or optimizing your application code. To intersperse the C source code within the assembly listing, you must instruct the compiler to include debugging information by adding `CFLAGS += -g` to the project Makefile and rebuild by running `make clean cc2538-demo.lst`. + Node IEEE/RIME/IPv6 Addresses ----------------------------- @@ -300,14 +308,14 @@ Start by building a border router from `examples/ipv6/rpl-border-router` * Connect device to Linux or OS X over its XDS port. * `cd $(CONTIKI)/tools` * `make tunslip6` - * `sudo $(CONTIKI)/tools/tunslip6 -s /dev/ aaaa::1/64` + * `sudo $(CONTIKI)/tools/tunslip6 -s /dev/ fd00::1/64` * The router will print its own IPv6 address. Use it below. Got configuration message of type P - Setting prefix aaaa:: + Setting prefix fd00:: created a new RPL dag Server IPv6 addresses: - aaaa::212:4b00:89ab:cdef + fd00::212:4b00:89ab:cdef fe80::212:4b00:89ab:cdef * `ping6
    ` @@ -363,11 +371,33 @@ By default, everything is configured to use the UART (stdio, border router's SLI You can multiplex things (for instance, SLIP as well as debugging over USB or SLIP over USB but debugging over UART and other combinations). +Selecting UART0 and/or UART1 +---------------------------- +By default, everything is configured to use the UART0 (stdio, border router's SLIP, sniffer's output stream). If you want to change this, these are the relevant lines in contiki-conf.h (0: UART0, 1: UART1): + + #define SERIAL_LINE_CONF_UART 0 + #define SLIP_ARCH_CONF_UART 0 + #define CC2538_RF_CONF_SNIFFER_UART 0 + #define DBG_CONF_UART 0 + #define UART1_CONF_UART 0 + +A single UART is available on CC2538DK, so all the configuration values above should be the same (i.e. either all 0 or all 1), but 0 and 1 could be mixed for other CC2538-based platforms supporting 2 UARTs. + +The chosen UARTs must have their ports and pins defined in board.h: + + #define UART0_RX_PORT GPIO_A_NUM + #define UART0_RX_PIN 0 + #define UART0_TX_PORT GPIO_A_NUM + #define UART0_TX_PIN 1 + +Only the UART ports and pins implemented on the board can be defined. + UART Baud Rate -------------- -By default, the CC2538 UART is configured with a baud rate of 115200. It is easy to increase this to 230400 by changing the value of `UART_CONF_BAUD_RATE` in `contiki-conf.h` or `project-conf.h`. +By default, the CC2538 UART is configured with a baud rate of 115200. It is easy to increase this to 230400 by changing the value of `UART0_CONF_BAUD_RATE` or `UART1_CONF_BAUD_RATE` in `contiki-conf.h` or `project-conf.h`, according to the UART instance used. - #define UART_CONF_BAUD_RATE 230400 + #define UART0_CONF_BAUD_RATE 230400 + #define UART1_CONF_BAUD_RATE 230400 RF and USB DMA -------------- diff --git a/platform/cc2538dk/contiki-conf.h b/platform/cc2538dk/contiki-conf.h index 964d01074..c6f0e2b6a 100644 --- a/platform/cc2538dk/contiki-conf.h +++ b/platform/cc2538dk/contiki-conf.h @@ -1,5 +1,5 @@ /** - * \addtogroup cc2538 + * \addtogroup cc2538dk * @{ * * \file @@ -34,12 +34,20 @@ typedef uint32_t uip_stats_t; /* * rtimer.h typedefs rtimer_clock_t as unsigned short. We need to define - * RTIMER_CLOCK_LT to override this + * RTIMER_CLOCK_DIFF to override this */ typedef uint32_t rtimer_clock_t; -#define RTIMER_CLOCK_LT(a,b) ((int32_t)((a)-(b)) < 0) +#define RTIMER_CLOCK_DIFF(a,b) ((int32_t)((a)-(b))) /** @} */ /*---------------------------------------------------------------------------*/ +#define TSCH_CONF_HW_FRAME_FILTERING 0 + +/* 352us from calling transmit() until the SFD byte has been sent */ +#define RADIO_DELAY_BEFORE_TX ((unsigned)US_TO_RTIMERTICKS(352)) +/* 192us as in datasheet but ACKs are not always received, so adjusted to 250us */ +#define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(250)) +#define RADIO_DELAY_BEFORE_DETECT 0 +/*---------------------------------------------------------------------------*/ /** * \name Serial Boot Loader Backdoor configuration * @@ -48,6 +56,24 @@ typedef uint32_t rtimer_clock_t; #ifndef FLASH_CCA_CONF_BOOTLDR_BACKDOOR #define FLASH_CCA_CONF_BOOTLDR_BACKDOOR 1 /** @@ -52,30 +52,15 @@ static int value(int type) { - uint8_t channel; + uint8_t channel = SOC_ADC_ADCCON_CH_AIN0 + ADC_ALS_OUT_PIN; int16_t res; - switch(type) { - case ADC_SENSOR_VDD_3: - channel = SOC_ADC_ADCCON_CH_VDD_3; - break; - case ADC_SENSOR_TEMP: - channel = SOC_ADC_ADCCON_CH_TEMP; - break; - case ADC_SENSOR_ALS: - channel = SOC_ADC_ADCCON_CH_AIN0 + ADC_ALS_OUT_PIN; - GPIO_SET_PIN(ADC_ALS_PWR_PORT_BASE, ADC_ALS_PWR_PIN_MASK); - clock_delay_usec(2000); - break; - default: - return 0; - } + GPIO_SET_PIN(ADC_ALS_PWR_PORT_BASE, ADC_ALS_PWR_PIN_MASK); + clock_delay_usec(2000); res = adc_get(channel, SOC_ADC_ADCCON_REF_INT, SOC_ADC_ADCCON_DIV_512); - if(type == ADC_SENSOR_ALS) { - GPIO_CLR_PIN(ADC_ALS_PWR_PORT_BASE, ADC_ALS_PWR_PIN_MASK); - } + GPIO_CLR_PIN(ADC_ALS_PWR_PORT_BASE, ADC_ALS_PWR_PIN_MASK); return res; } @@ -94,7 +79,6 @@ configure(int type, int value) GPIO_SET_INPUT(GPIO_A_BASE, ADC_ALS_OUT_PIN_MASK); ioc_set_over(GPIO_A_NUM, ADC_ALS_OUT_PIN, IOC_OVERRIDE_ANA); - adc_init(); break; } return 0; @@ -106,6 +90,6 @@ status(int type) return 1; } /*---------------------------------------------------------------------------*/ -SENSORS_SENSOR(adc_sensor, ADC_SENSOR, value, configure, status); +SENSORS_SENSOR(als_sensor, ALS_SENSOR, value, configure, status); /** @} */ diff --git a/platform/cc2538dk/dev/adc-sensor.h b/platform/cc2538dk/dev/als-sensor.h similarity index 79% rename from platform/cc2538dk/dev/adc-sensor.h rename to platform/cc2538dk/dev/als-sensor.h index b6d0efbdf..abed92e13 100644 --- a/platform/cc2538dk/dev/adc-sensor.h +++ b/platform/cc2538dk/dev/als-sensor.h @@ -33,33 +33,29 @@ * \addtogroup cc2538-smartrf-sensors * @{ * - * \defgroup cc2538dk-adc-sensor cc2538dk ADC Driver + * \defgroup cc2538dk-als-sensor cc2538dk ALS Driver * - * Driver for the SmartRF06EB ADC sensors + * Driver for the SmartRF06EB ALS sensor * @{ * * \file - * Header file for the cc2538dk ADC Driver + * Header file for the cc2538dk ALS Driver */ -#ifndef ADC_SENSOR_H_ -#define ADC_SENSOR_H_ +#ifndef ALS_SENSOR_H_ +#define ALS_SENSOR_H_ #include "lib/sensors.h" /*---------------------------------------------------------------------------*/ -/** \name ADC sensors +/** \name ALS sensor * @{ */ -#define ADC_SENSOR "ADC" - -#define ADC_SENSOR_VDD_3 0 /**< On-chip VDD / 3 */ -#define ADC_SENSOR_TEMP 1 /**< On-chip temperature */ -#define ADC_SENSOR_ALS 2 /**< Ambient light sensor */ +#define ALS_SENSOR "ALS" /** @} */ -extern const struct sensors_sensor adc_sensor; +extern const struct sensors_sensor als_sensor; -#endif /* ADC_SENSOR_H_ */ +#endif /* ALS_SENSOR_H_ */ /** * @} diff --git a/platform/cc2538dk/dev/board.h b/platform/cc2538dk/dev/board.h index 98a297855..2d9c5ac48 100644 --- a/platform/cc2538dk/dev/board.h +++ b/platform/cc2538dk/dev/board.h @@ -28,7 +28,8 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** \addtogroup cc2538 +/** + * \addtogroup cc2538dk * @{ * * \defgroup cc2538-smartrf SmartRF06EB Peripherals @@ -77,28 +78,28 @@ #undef LEDS_RED #undef LEDS_CONF_ALL -#define LEDS_YELLOW 2 /**< LED2 (Yellow) -> PC1 */ -#define LEDS_GREEN 4 /**< LED3 (Green) -> PC2 */ -#define LEDS_ORANGE 8 /**< LED4 (Orange) -> PC3 */ +#define LEDS_YELLOW 2 /**< LED2 (Yellow) -> PC1 */ +#define LEDS_GREEN 4 /**< LED3 (Green) -> PC2 */ +#define LEDS_ORANGE 8 /**< LED4 (Orange) -> PC3 */ #if USB_SERIAL_CONF_ENABLE -#define LEDS_CONF_ALL 14 -#define LEDS_RED LEDS_ORANGE +#define LEDS_CONF_ALL 14 +#define LEDS_RED LEDS_ORANGE #else -#define LEDS_CONF_ALL 15 -#define LEDS_RED 1 /**< LED1 (Red) -> PC0 */ +#define LEDS_CONF_ALL 15 +#define LEDS_RED 1 /**< LED1 (Red) -> PC0 */ #endif /* Notify various examples that we have LEDs */ -#define PLATFORM_HAS_LEDS 1 +#define PLATFORM_HAS_LEDS 1 /** @} */ /*---------------------------------------------------------------------------*/ /** \name USB configuration * * The USB pullup is driven by PC0 and is shared with LED1 */ -#define USB_PULLUP_PORT GPIO_C_NUM -#define USB_PULLUP_PIN 0 +#define USB_PULLUP_PORT GPIO_C_NUM +#define USB_PULLUP_PIN 0 /** @} */ /*---------------------------------------------------------------------------*/ /** \name UART configuration @@ -110,22 +111,21 @@ * - CTS: PB0 (Can only be used with UART1) * - RTS: PD3 (Can only be used with UART1) * - * We configure the port to use UART0. To use UART1, change UART_CONF_BASE + * We configure the port to use UART0. To use UART1, replace UART0_* with + * UART1_* below. * @{ */ -#define UART_CONF_BASE UART_0_BASE +#define UART0_RX_PORT GPIO_A_NUM +#define UART0_RX_PIN 0 -#define UART_RX_PORT GPIO_A_NUM -#define UART_RX_PIN 0 +#define UART0_TX_PORT GPIO_A_NUM +#define UART0_TX_PIN 1 -#define UART_TX_PORT GPIO_A_NUM -#define UART_TX_PIN 1 +#define UART1_CTS_PORT GPIO_B_NUM +#define UART1_CTS_PIN 0 -#define UART_CTS_PORT GPIO_B_NUM -#define UART_CTS_PIN 0 - -#define UART_RTS_PORT GPIO_D_NUM -#define UART_RTS_PIN 3 +#define UART1_RTS_PORT GPIO_D_NUM +#define UART1_RTS_PIN 3 /** @} */ /*---------------------------------------------------------------------------*/ /** \name SmartRF Button configuration @@ -139,32 +139,32 @@ * @{ */ /** BUTTON_SELECT -> PA3 */ -#define BUTTON_SELECT_PORT GPIO_A_NUM -#define BUTTON_SELECT_PIN 3 -#define BUTTON_SELECT_VECTOR NVIC_INT_GPIO_PORT_A +#define BUTTON_SELECT_PORT GPIO_A_NUM +#define BUTTON_SELECT_PIN 3 +#define BUTTON_SELECT_VECTOR NVIC_INT_GPIO_PORT_A /** BUTTON_LEFT -> PC4 */ -#define BUTTON_LEFT_PORT GPIO_C_NUM -#define BUTTON_LEFT_PIN 4 -#define BUTTON_LEFT_VECTOR NVIC_INT_GPIO_PORT_C +#define BUTTON_LEFT_PORT GPIO_C_NUM +#define BUTTON_LEFT_PIN 4 +#define BUTTON_LEFT_VECTOR NVIC_INT_GPIO_PORT_C /** BUTTON_RIGHT -> PC5 */ -#define BUTTON_RIGHT_PORT GPIO_C_NUM -#define BUTTON_RIGHT_PIN 5 -#define BUTTON_RIGHT_VECTOR NVIC_INT_GPIO_PORT_C +#define BUTTON_RIGHT_PORT GPIO_C_NUM +#define BUTTON_RIGHT_PIN 5 +#define BUTTON_RIGHT_VECTOR NVIC_INT_GPIO_PORT_C /** BUTTON_UP -> PC6 */ -#define BUTTON_UP_PORT GPIO_C_NUM -#define BUTTON_UP_PIN 6 -#define BUTTON_UP_VECTOR NVIC_INT_GPIO_PORT_C +#define BUTTON_UP_PORT GPIO_C_NUM +#define BUTTON_UP_PIN 6 +#define BUTTON_UP_VECTOR NVIC_INT_GPIO_PORT_C /** BUTTON_DOWN -> PC7 */ #define BUTTON_DOWN_PORT GPIO_C_NUM -#define BUTTON_DOWN_PIN 7 -#define BUTTON_DOWN_VECTOR NVIC_INT_GPIO_PORT_C +#define BUTTON_DOWN_PIN 7 +#define BUTTON_DOWN_VECTOR NVIC_INT_GPIO_PORT_C /* Notify various examples that we have Buttons */ -#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_BUTTON 1 /** @} */ /*---------------------------------------------------------------------------*/ /** @@ -176,25 +176,49 @@ * ADC inputs can only be on port A. * @{ */ -#define ADC_ALS_PWR_PORT GPIO_A_NUM /**< ALS power GPIO control port */ -#define ADC_ALS_PWR_PIN 7 /**< ALS power GPIO control pin */ -#define ADC_ALS_OUT_PIN 6 /**< ALS output ADC input pin on port A */ +#define ADC_ALS_PWR_PORT GPIO_A_NUM /**< ALS power GPIO control port */ +#define ADC_ALS_PWR_PIN 7 /**< ALS power GPIO control pin */ +#define ADC_ALS_OUT_PIN 6 /**< ALS output ADC input pin on port A */ /** @} */ /*---------------------------------------------------------------------------*/ /** * \name SPI configuration * - * These values configure which CC2538 pins to use for the SPI lines. + * These values configure which CC2538 pins to use for the SPI lines. Both + * SPI instances can be used independently by providing the corresponding + * port / pin macros. * @{ */ -#define SPI_CLK_PORT GPIO_A_NUM -#define SPI_CLK_PIN 2 -#define SPI_MOSI_PORT GPIO_A_NUM -#define SPI_MOSI_PIN 4 -#define SPI_MISO_PORT GPIO_A_NUM -#define SPI_MISO_PIN 5 -#define SPI_SEL_PORT GPIO_B_NUM -#define SPI_SEL_PIN 5 +#define SPI0_IN_USE 0 +#define SPI1_IN_USE 0 +#if SPI0_IN_USE +/** Clock port SPI0 */ +#define SPI0_CLK_PORT GPIO_A_NUM +/** Clock pin SPI0 */ +#define SPI0_CLK_PIN 2 +/** TX port SPI0 (master mode: MOSI) */ +#define SPI0_TX_PORT GPIO_A_NUM +/** TX pin SPI0 */ +#define SPI0_TX_PIN 4 +/** RX port SPI0 (master mode: MISO */ +#define SPI0_RX_PORT GPIO_A_NUM +/** RX pin SPI0 */ +#define SPI0_RX_PIN 5 +#endif /* #if SPI0_IN_USE */ +#if SPI1_IN_USE +/** Clock port SPI1 */ +#define SPI1_CLK_PORT GPIO_A_NUM +/** Clock pin SPI1 */ +#define SPI1_CLK_PIN 2 +/** TX port SPI1 (master mode: MOSI) */ +#define SPI1_TX_PORT GPIO_A_NUM +/** TX pin SPI1 */ +#define SPI1_TX_PIN 4 +/** RX port SPI1 (master mode: MISO) */ +#define SPI1_RX_PORT GPIO_A_NUM +/** RX pin SPI1 */ +#define SPI1_RX_PIN 5 +#endif /* #if SPI1_IN_USE */ /** @} */ /*---------------------------------------------------------------------------*/ /** diff --git a/platform/cc2538dk/dev/button-sensor.c b/platform/cc2538dk/dev/button-sensor.c index ba45e20c3..ca6b88280 100644 --- a/platform/cc2538dk/dev/button-sensor.c +++ b/platform/cc2538dk/dev/button-sensor.c @@ -103,25 +103,17 @@ btn_callback(uint8_t port, uint8_t pin) } timer_set(&debouncetimer, CLOCK_SECOND / 8); - if(port == GPIO_A_NUM) { + + if((port == BUTTON_SELECT_PORT) && (pin == BUTTON_SELECT_PIN)) { sensors_changed(&button_select_sensor); - } else if(port == GPIO_C_NUM) { - switch(pin) { - case BUTTON_LEFT_PIN: - sensors_changed(&button_left_sensor); - break; - case BUTTON_RIGHT_PIN: - sensors_changed(&button_right_sensor); - break; - case BUTTON_UP_PIN: - sensors_changed(&button_up_sensor); - break; - case BUTTON_DOWN_PIN: - sensors_changed(&button_down_sensor); - break; - default: - return; - } + } else if((port == BUTTON_LEFT_PORT) && (pin == BUTTON_LEFT_PIN)) { + sensors_changed(&button_left_sensor); + } else if((port == BUTTON_RIGHT_PORT) && (pin == BUTTON_RIGHT_PIN)) { + sensors_changed(&button_right_sensor); + } else if((port == BUTTON_UP_PORT) && (pin == BUTTON_UP_PIN)) { + sensors_changed(&button_up_sensor); + } else if((port == BUTTON_DOWN_PORT) && (pin == BUTTON_DOWN_PIN)) { + sensors_changed(&button_down_sensor); } } /*---------------------------------------------------------------------------*/ diff --git a/platform/cc2538dk/dev/smartrf-sensors.c b/platform/cc2538dk/dev/smartrf-sensors.c index 41d977783..76841af3b 100644 --- a/platform/cc2538dk/dev/smartrf-sensors.c +++ b/platform/cc2538dk/dev/smartrf-sensors.c @@ -42,13 +42,15 @@ */ #include "contiki.h" #include "dev/button-sensor.h" -#include "dev/adc-sensor.h" +#include "dev/als-sensor.h" +#include "dev/cc2538-sensors.h" #include /** \brief Exports a global symbol to be used by the sensor API */ SENSORS(&button_select_sensor, &button_left_sensor, &button_right_sensor, - &button_up_sensor, &button_down_sensor, &adc_sensor); + &button_up_sensor, &button_down_sensor, &als_sensor, + &cc2538_temp_sensor, &vdd3_sensor); /** * @} diff --git a/platform/cooja-ip64/Makefile.cooja-ip64 b/platform/cooja-ip64/Makefile.cooja-ip64 new file mode 100644 index 000000000..d86077c57 --- /dev/null +++ b/platform/cooja-ip64/Makefile.cooja-ip64 @@ -0,0 +1,15 @@ +COOJAPLATFORMDIR=$(CONTIKI)/platform/cooja + +MODULES += core/net/ip64 +include $(COOJAPLATFORMDIR)/Makefile.cooja + +vpath %.c $(COOJAPLATFORMDIR) $(COOJAPLATFORMDIR)/dev \ + $(COOJAPLATFORMDIR)/net $(COOJAPLATFORMDIR)/lib \ + $(COOJAPLATFORMDIR)/sys $(COOJAPLATFORMDIR)/cfs +CFLAGS += -I $(COOJAPLATFORMDIR) + +CFLAGS += -DWITH_IP64=1 -DWITH_LARGE_BUFFER_SIZE=1 +CFLAGS += -DINCLUDE_SUBPLATFORM_CONF=1 + +%.cooja: %.cooja-ip64 + cp $< $@ diff --git a/platform/cooja-ip64/Makefile.customrules-cooja-ip64 b/platform/cooja-ip64/Makefile.customrules-cooja-ip64 new file mode 100644 index 000000000..3de3bc7c5 --- /dev/null +++ b/platform/cooja-ip64/Makefile.customrules-cooja-ip64 @@ -0,0 +1,50 @@ +### Define custom targets + +REDEF_PRINTF=1 # Redefine functions to enable printf()s inside Cooja + +# NB: Assumes ARCHIVE was not overridden and is in $(OBJECTDIR) +$(ARCHIVE): $(CONTIKI_OBJECTFILES) | $(OBJECTDIR) + ${subst obj_cooja/,$(OBJECTDIR)/,$(AR_COMMAND_1)} $^ $(AR_COMMAND_2) + +# NB: Assumes JNILIB was not overridden and is in $(OBJECTDIR) +$(JNILIB): $(CONTIKI_APP_OBJ) $(MAIN_OBJ) $(PROJECT_OBJECTFILES) $(ARCHIVE) | $(OBJECTDIR) +ifdef SYMBOLS + @echo Generating symbols + # Recreate symbols file and relink with final memory layout (twice) + ${CONTIKI}/tools/make-symbols-nm $(JNILIB) + $(CC) $(CFLAGS) -c symbols.c -o $(OBJECTDIR)/symbols.o + $(LINK_COMMAND_1) $^ $(LINK_COMMAND_2) + ${CONTIKI}/tools/make-symbols-nm $(JNILIB) + $(CC) $(CFLAGS) -c symbols.c -o $(OBJECTDIR)/symbols.o +endif ## SYMBOLS +ifdef REDEF_PRINTF + @echo Redefining printf + -$(foreach OBJ,$^, $(OBJCOPY) --redefine-sym printf=log_printf $(OBJ); ) + -$(foreach OBJ,$^, $(OBJCOPY) --redefine-sym puts=log_puts $(OBJ); ) + -$(foreach OBJ,$^, $(OBJCOPY) --redefine-sym putchar=log_putchar $(OBJ); ) +endif ## REDEF_PRINTF + ${subst .cooja,.$(TARGET),${subst obj_cooja/,$(OBJECTDIR)/,$(LINK_COMMAND_1)}} $^ $(LINK_COMMAND_2) + +.PHONY: $(CONTIKI_APP).$(TARGET) +$(CONTIKI_APP).$(TARGET): $(JNILIB) + cp $(JNILIB) $@ + rm $(CONTIKI_APP_OBJ) + + mkdir -p obj_cooja + @-cp obj_cooja-ip64/$(LIBNAME).map obj_cooja/$(LIBNAME).map && echo Placed a copy of the map file at obj_cooja/$(LIBNAME).map + + cp obj_cooja-ip64/$(LIBNAME).cooja-ip64 obj_cooja/$(LIBNAME).cooja + @echo Placed a copy of the shared library at obj_cooja/$(LIBNAME).cooja + + cp $@ $(CONTIKI_APP).cooja + @echo Placed a copy of the shared library at $(CONTIKI_APP).cooja + +# Trickiness: GNU make matches this against the file base name. +# Assume that the directory part is the standard location. +mtype%.o: contiki-cooja-ip64-main.o | $(OBJECTDIR) + mv contiki-cooja-ip64-main.o $@ + +symbols.c: + # Create initial symbol files if not existing + cp ${CONTIKI}/tools/empty-symbols.c symbols.c + cp ${CONTIKI}/tools/empty-symbols.h symbols.h diff --git a/platform/cooja-ip64/contiki-cooja-ip64-main.c b/platform/cooja-ip64/contiki-cooja-ip64-main.c new file mode 100644 index 000000000..02576a3be --- /dev/null +++ b/platform/cooja-ip64/contiki-cooja-ip64-main.c @@ -0,0 +1,436 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file + * COOJA Contiki mote main file. + * \author + * Fredrik Osterlind + */ + +#include +#include +#include + +#include "contiki.h" + +#include "sys/clock.h" +#include "sys/etimer.h" +#include "sys/cooja_mt.h" +#include "sys/autostart.h" + +#include "lib/random.h" +#include "lib/simEnvChange.h" + +#include "net/rime/rime.h" +#include "net/netstack.h" +#include "net/ip/uip-nameserver.h" + +#include "dev/serial-line.h" +#include "dev/cooja-radio.h" +#include "dev/button-sensor.h" +#include "dev/pir-sensor.h" +#include "dev/vib-sensor.h" + +#include "sys/node-id.h" + +#include "ip64.h" +#include "dev/slip.h" + +/* JNI-defined functions, depends on the environment variable CLASSNAME */ +#ifndef CLASSNAME +#error CLASSNAME is undefined, required by contiki-cooja-main.c +#endif /* CLASSNAME */ +#define COOJA__QUOTEME(a,b,c) COOJA_QUOTEME(a,b,c) +#define COOJA_QUOTEME(a,b,c) a##b##c +#define COOJA_JNI_PATH Java_org_contikios_cooja_corecomm_ +#define Java_org_contikios_cooja_corecomm_CLASSNAME_init COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_init) +#define Java_org_contikios_cooja_corecomm_CLASSNAME_getMemory COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_getMemory) +#define Java_org_contikios_cooja_corecomm_CLASSNAME_setMemory COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_setMemory) +#define Java_org_contikios_cooja_corecomm_CLASSNAME_tick COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_tick) +#define Java_org_contikios_cooja_corecomm_CLASSNAME_setReferenceAddress COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_setReferenceAddress) + +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#define PRINT6ADDR(addr) printf("%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) + +/* Simulation mote interfaces */ +SIM_INTERFACE_NAME(moteid_interface); +SIM_INTERFACE_NAME(vib_interface); +SIM_INTERFACE_NAME(rs232_interface); +SIM_INTERFACE_NAME(simlog_interface); +SIM_INTERFACE_NAME(beep_interface); +SIM_INTERFACE_NAME(radio_interface); +SIM_INTERFACE_NAME(button_interface); +SIM_INTERFACE_NAME(pir_interface); +SIM_INTERFACE_NAME(clock_interface); +SIM_INTERFACE_NAME(leds_interface); +SIM_INTERFACE_NAME(cfs_interface); +SIM_INTERFACES(&vib_interface, &moteid_interface, &rs232_interface, &simlog_interface, &beep_interface, &radio_interface, &button_interface, &pir_interface, &clock_interface, &leds_interface, &cfs_interface); +/* Example: manually add mote interfaces */ +//SIM_INTERFACE_NAME(dummy_interface); +//SIM_INTERFACES(..., &dummy_interface); + +/* Sensors */ +SENSORS(&button_sensor, &pir_sensor, &vib_sensor); + +/* + * referenceVar is used for comparing absolute and process relative memory. + * (this must not be static due to memory locations) + */ +long referenceVar; + +/* + * Contiki and rtimer threads. + */ +static struct cooja_mt_thread rtimer_thread; +static struct cooja_mt_thread process_run_thread; + +#define MIN(a, b) ( (a)<(b) ? (a) : (b) ) + +/*---------------------------------------------------------------------------*/ +static void +print_processes(struct process * const processes[]) +{ + /* const struct process * const * p = processes;*/ + printf("Starting"); + while(*processes != NULL) { + printf(" '%s'", (*processes)->name); + processes++; + } + putchar('\n'); +} +/*---------------------------------------------------------------------------*/ +static void +rtimer_thread_loop(void *data) +{ + while(1) + { + rtimer_arch_check(); + + /* Return to COOJA */ + cooja_mt_yield(); + } +} +/*---------------------------------------------------------------------------*/ +static void +set_mac_addr(void) +{ + linkaddr_t addr; + int i; + + memset(&addr, 0, sizeof(linkaddr_t)); + for(i = 0; i < sizeof(uip_lladdr.addr); i += 2) { + addr.u8[i + 1] = node_id & 0xff; + addr.u8[i + 0] = node_id >> 8; + } + linkaddr_set_node_addr(&addr); + printf("MAC address "); + for(i = 0; i < sizeof(addr.u8) - 1; i++) { + printf("%d.", addr.u8[i]); + } + printf("%d\n", addr.u8[i]); +} +/*---------------------------------------------------------------------------*/ +void +contiki_init(void) +{ + int i; + uint8_t addr[sizeof(uip_lladdr.addr)]; + uip_ipaddr_t ipaddr; + uip_ds6_addr_t *lladdr; + uip_ip4addr_t ipv4addr, netmask; + + /* Start process handler */ + process_init(); + + /* Start Contiki processes */ + process_start(&etimer_process, NULL); + process_start(&sensors_process, NULL); + ctimer_init(); + + /* Print startup information */ + printf(CONTIKI_VERSION_STRING " started. "); + if(node_id > 0) { + printf("Node id is set to %u.\n", node_id); + } else { + printf("Node id is not set.\n"); + } + + set_mac_addr(); + + queuebuf_init(); + + /* Initialize communication stack */ + netstack_init(); + printf("%s/%s/%s, channel check rate %lu Hz\n", + NETSTACK_NETWORK.name, NETSTACK_MAC.name, NETSTACK_RDC.name, + CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1: + NETSTACK_RDC.channel_check_interval())); + + /* IPv6 CONFIGURATION */ + + + for(i = 0; i < sizeof(uip_lladdr.addr); i += 2) { + addr[i + 1] = node_id & 0xff; + addr[i + 0] = node_id >> 8; + } + linkaddr_copy(addr, &linkaddr_node_addr); + memcpy(&uip_lladdr.addr, addr, sizeof(uip_lladdr.addr)); + + process_start(&tcpip_process, NULL); + + printf("Tentative link-local IPv6 address "); + + lladdr = uip_ds6_get_link_local(-1); + for(i = 0; i < 7; ++i) { + printf("%02x%02x:", lladdr->ipaddr.u8[i * 2], + lladdr->ipaddr.u8[i * 2 + 1]); + } + printf("%02x%02x\n", lladdr->ipaddr.u8[14], + lladdr->ipaddr.u8[15]); + + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); + uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE); + printf("Tentative global IPv6 address "); + for(i = 0; i < 7; ++i) { + printf("%02x%02x:", + ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]); + } + printf("%02x%02x\n", + ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]); + + /* Start serial process */ + serial_line_init(); + + /* Start autostart processes (defined in Contiki application) */ + print_processes(autostart_processes); + autostart_start(autostart_processes); + + /* Start the SLIP */ + printf("Initiating SLIP with IP address is 172.16.0.2.\n"); + + uip_ipaddr(&ipv4addr, 172, 16, 0, 2); + uip_ipaddr(&netmask, 255, 255, 255, 0); + ip64_set_ipv4_address(&ipv4addr, &netmask); + + rs232_set_input(slip_input_byte); + log_set_putchar_with_slip(1); + + uip_ip4addr_t ip4addr; + uip_ip6addr_t ip6addr; + + uip_ipaddr(&ip4addr, 8,8,8,8); + ip64_addr_4to6(&ip4addr, &ip6addr); + + uip_nameserver_update((uip_ipaddr_t *)&ip6addr, UIP_NAMESERVER_INFINITE_LIFETIME); +} +/*---------------------------------------------------------------------------*/ +static void +process_run_thread_loop(void *data) +{ + /* Yield once during bootup */ + simProcessRunValue = 1; + cooja_mt_yield(); + + contiki_init(); + + while(1) { + simProcessRunValue = process_run(); + while(simProcessRunValue-- > 0) { + process_run(); + } + simProcessRunValue = process_nevents(); + + /* Check if we must stay awake */ + if(simDontFallAsleep) { + simDontFallAsleep = 0; + simProcessRunValue = 1; + } + + /* Return to COOJA */ + cooja_mt_yield(); + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize a mote by starting processes etc. + * \param env JNI Environment interface pointer + * \param obj unused + * + * This function initializes a mote by starting certain + * processes and setting up the environment. + * + * This is a JNI function and should only be called via the + * responsible Java part (MoteType.java). + */ +JNIEXPORT void JNICALL +Java_org_contikios_cooja_corecomm_CLASSNAME_init(JNIEnv *env, jobject obj) +{ + /* Create rtimers and Contiki threads */ + cooja_mt_start(&rtimer_thread, &rtimer_thread_loop, NULL); + cooja_mt_start(&process_run_thread, &process_run_thread_loop, NULL); + } +/*---------------------------------------------------------------------------*/ +/** + * \brief Get a segment from the process memory. + * \param env JNI Environment interface pointer + * \param obj unused + * \param rel_addr Start address of segment + * \param length Size of memory segment + * \param mem_arr Byte array destination for the fetched memory segment + * \return Java byte array containing a copy of memory segment. + * + * Fetches a memory segment from the process memory starting at + * (rel_addr), with size (length). This function does not perform + * ANY error checking, and the process may crash if addresses are + * not available/readable. + * + * This is a JNI function and should only be called via the + * responsible Java part (MoteType.java). + */ +JNIEXPORT void JNICALL +Java_org_contikios_cooja_corecomm_CLASSNAME_getMemory(JNIEnv *env, jobject obj, jint rel_addr, jint length, jbyteArray mem_arr) +{ + (*env)->SetByteArrayRegion( + env, + mem_arr, + 0, + (size_t) length, + (jbyte *) (((long)rel_addr) + referenceVar) + ); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Replace a segment of the process memory with given byte array. + * \param env JNI Environment interface pointer + * \param obj unused + * \param rel_addr Start address of segment + * \param length Size of memory segment + * \param mem_arr Byte array contaning new memory + * + * Replaces a process memory segment with given byte array. + * This function does not perform ANY error checking, and the + * process may crash if addresses are not available/writable. + * + * This is a JNI function and should only be called via the + * responsible Java part (MoteType.java). + */ +JNIEXPORT void JNICALL +Java_org_contikios_cooja_corecomm_CLASSNAME_setMemory(JNIEnv *env, jobject obj, jint rel_addr, jint length, jbyteArray mem_arr) +{ + jbyte *mem = (*env)->GetByteArrayElements(env, mem_arr, 0); + memcpy((char *)(((long)rel_addr) + referenceVar), + mem, + length); + (*env)->ReleaseByteArrayElements(env, mem_arr, mem, 0); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Let mote execute one "block" of code (tick mote). + * \param env JNI Environment interface pointer + * \param obj unused + * + * Let mote defined by the active contiki processes and current + * process memory execute some program code. This code must not block + * or else this function will never return. A typical contiki + * process will return when it executes PROCESS_WAIT..() statements. + * + * Before the control is left to contiki processes, any messages + * from the Java part are handled. These may for example be + * incoming network data. After the contiki processes return control, + * messages to the Java part are also handled (those which may need + * special attention). + * + * This is a JNI function and should only be called via the + * responsible Java part (MoteType.java). + */ +JNIEXPORT void JNICALL +Java_org_contikios_cooja_corecomm_CLASSNAME_tick(JNIEnv *env, jobject obj) +{ + clock_time_t nextEtimer; + rtimer_clock_t nextRtimer; + + simProcessRunValue = 0; + + /* Let all simulation interfaces act first */ + doActionsBeforeTick(); + + /* Poll etimer process */ + if(etimer_pending()) { + etimer_request_poll(); + } + + /* Let rtimers run. + * Sets simProcessRunValue */ + cooja_mt_exec(&rtimer_thread); + + if(simProcessRunValue == 0) { + /* Rtimers done: Let Contiki handle a few events. + * Sets simProcessRunValue */ + cooja_mt_exec(&process_run_thread); + } + + /* Let all simulation interfaces act before returning to java */ + doActionsAfterTick(); + + /* Do we have any pending timers */ + simEtimerPending = etimer_pending() || rtimer_arch_pending(); + if(!simEtimerPending) { + return; + } + + /* Save nearest expiration time */ + nextEtimer = etimer_next_expiration_time() - (clock_time_t) simCurrentTime; + nextRtimer = rtimer_arch_next() - (rtimer_clock_t) simCurrentTime; + if(etimer_pending() && rtimer_arch_pending()) { + simNextExpirationTime = MIN(nextEtimer, nextRtimer); + } else if(etimer_pending()) { + simNextExpirationTime = nextEtimer; + } else if(rtimer_arch_pending()) { + simNextExpirationTime = nextRtimer; + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Set the relative memory address of the reference variable. + * \param env JNI Environment interface pointer + * \param obj unused + * \param addr Relative memory address + * + * This is a JNI function and should only be called via the + * responsible Java part (MoteType.java). + */ +JNIEXPORT void JNICALL +Java_org_contikios_cooja_corecomm_CLASSNAME_setReferenceAddress(JNIEnv *env, jobject obj, jint addr) +{ + referenceVar = (((long)&referenceVar) - ((long)addr)); +} diff --git a/platform/cooja-ip64/ip64-conf.h b/platform/cooja-ip64/ip64-conf.h new file mode 100644 index 000000000..376614abe --- /dev/null +++ b/platform/cooja-ip64/ip64-conf.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012-2013, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + */ +#ifndef IP64_CONF_H +#define IP64_CONF_H + +#undef UIP_FALLBACK_INTERFACE +#define UIP_FALLBACK_INTERFACE ip64_uip_fallback_interface + +#include "ip64-slip-interface.h" +#include "ip64-null-driver.h" + +#define IP64_CONF_UIP_FALLBACK_INTERFACE_SLIP 1 +#define IP64_CONF_UIP_FALLBACK_INTERFACE ip64_slip_interface +#define IP64_CONF_INPUT ip64_slip_interface_input +#define IP64_CONF_ETH_DRIVER ip64_null_driver + +#endif /* IP64_CONF_H */ diff --git a/platform/cooja-ip64/subplatform-conf.h b/platform/cooja-ip64/subplatform-conf.h new file mode 100644 index 000000000..773100051 --- /dev/null +++ b/platform/cooja-ip64/subplatform-conf.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + */ + +#ifndef __PLATFORM_CONF_H__ +#define __PLATFORM_CONF_H__ + +#if WITH_IP64 +#define WITH_SLIP 1 +#ifndef UIP_FALLBACK_INTERFACE +#define UIP_FALLBACK_INTERFACE ip64_uip_fallback_interface +#endif +#endif /* WITH_IP64 */ + +#ifndef UIP_CONF_ND6_RA_RDNSS +#define UIP_CONF_ND6_RA_RDNSS 1 +#endif + +#ifndef UIP_CONF_ND6_SEND_RA +#define UIP_CONF_ND6_SEND_RA 1 +#endif + +#ifndef UIP_CONF_ROUTER +#define UIP_CONF_ROUTER 1 +#endif + +#endif /* __PLATFORM_CONF_H__ */ diff --git a/platform/cooja/Makefile.cooja b/platform/cooja/Makefile.cooja index 1426bf7cc..d10979cd9 100644 --- a/platform/cooja/Makefile.cooja +++ b/platform/cooja/Makefile.cooja @@ -37,7 +37,7 @@ endif ## QUICKSTART #MAIN_SRC = $(OBJECTDIR)/$(LIBNAME).c MAIN_OBJ = $(OBJECTDIR)/$(LIBNAME).o ARCHIVE = $(OBJECTDIR)/$(LIBNAME).a -JNILIB = $(OBJECTDIR)/$(LIBNAME).cooja +JNILIB = $(OBJECTDIR)/$(LIBNAME).$(TARGET) CONTIKI_APP_OBJ = $(CONTIKI_APP).co ### COOJA platform sources @@ -47,11 +47,12 @@ CONTIKI_TARGET_DIRS = . dev lib sys cfs net # (COOJA_SOURCEDIRS contains additional sources dirs set from simulator) vpath %.c $(COOJA_SOURCEDIRS) -COOJA_BASE = simEnvChange.c cooja_mt.c cooja_mtarch.c rtimer-arch.c slip.c watchdog.c rimestats.c +COOJA_BASE = simEnvChange.c cooja_mt.c cooja_mtarch.c rtimer-arch.c slip.c watchdog.c rimestats.c elfloader-x86.c COOJA_INTFS = beep.c button-sensor.c ip.c leds-arch.c moteid.c \ pir-sensor.c rs232.c vib-sensor.c \ - clock.c log.c cfs-cooja.c cooja-radio.c + clock.c log.c cfs-cooja.c cooja-radio.c \ + eeprom.c slip-arch.c COOJA_CORE = random.c sensors.c leds.c symbols.c @@ -73,20 +74,29 @@ CONTIKI_CPU=$(CONTIKI)/cpu/x86 CFLAGSNO = $(EXTRA_CC_ARGS) -Wall -g -I/usr/local/include -DCLASSNAME=$(CLASSNAME) CFLAGS += $(CFLAGSNO) -ifeq ($(UIP_CONF_IPV6),1) - CFLAGS += -DWITH_UIP6=1 -endif -ifdef WITH_UIP - CFLAGS += -DWITH_UIP=1 -endif +MODULES += core/net core/net/mac \ + core/net/llsec core/net/ip64-addr ## Copied from Makefile.include, since Cooja overrides CFLAGS et al -ifeq ($(UIP_CONF_IPV6),1) - CFLAGS += -DUIP_CONF_IPV6=1 - ifneq ($(UIP_CONF_RPL),0) - CFLAGS += -DUIP_CONF_IPV6_RPL=1 - endif # UIP_CONF_RPL -endif # UIP_CONF_IPV6 +HAS_STACK = 0 +ifeq ($(CONTIKI_WITH_IPV4),1) + HAS_STACK = 1 + CFLAGS += -DNETSTACK_CONF_WITH_IPV4=1 +endif -MODULES += core/net core/net/ip core/net/ipv4 \ - core/net/ipv6 core/net/mac core/net/rime core/net/rpl +ifeq ($(CONTIKI_WITH_RIME),1) + HAS_STACK = 1 + CFLAGS += -DNETSTACK_CONF_WITH_RIME=1 +endif + +# Make IPv6 the default stack +ifeq ($(HAS_STACK),0) +CONTIKI_WITH_IPV6 = 1 +endif + +ifeq ($(CONTIKI_WITH_IPV6),1) + CFLAGS += -DNETSTACK_CONF_WITH_IPV6=1 + ifneq ($(CONTIKI_WITH_RPL),0) + CFLAGS += -DUIP_CONF_IPV6_RPL=1 + endif +endif diff --git a/platform/cooja/cfs/cfs-cooja.c b/platform/cooja/cfs/cfs-cooja.c index 0119ea5a0..3150517b2 100644 --- a/platform/cooja/cfs/cfs-cooja.c +++ b/platform/cooja/cfs/cfs-cooja.c @@ -29,6 +29,7 @@ * This file is part of the Contiki operating system. * */ +#include #include #include "lib/simEnvChange.h" #include "cfs/cfs.h" @@ -50,6 +51,7 @@ const struct simInterface cfs_interface; // COOJA variables #define CFS_BUF_SIZE 4000 /* Configure CFS size here and in ContikiCFS.java */ char simCFSData[CFS_BUF_SIZE] = { 0 }; +int simCFSSize = 0; char simCFSChanged = 0; int simCFSRead = 0; int simCFSWritten = 0; @@ -61,11 +63,15 @@ cfs_open(const char *n, int f) if(file.flag == FLAG_FILE_CLOSED) { file.flag = FLAG_FILE_OPEN; file.access = f; - if(f & CFS_APPEND) { - file.fileptr = file.endptr; - } else { - file.fileptr = 0; - } + file.fileptr = 0; + file.endptr = simCFSSize; + if(f & CFS_WRITE) { + if(f & CFS_APPEND) { + file.fileptr = file.endptr; + } else { + file.endptr = 0; + } + } return 0; } else { return -1; @@ -110,6 +116,9 @@ cfs_write(int f, const void *buf, unsigned int len) if(file.fileptr > file.endptr) { file.endptr = file.fileptr; } + if(file.fileptr > simCFSSize) { + simCFSSize = file.fileptr; + } return len; } else { return -1; diff --git a/platform/cooja/contiki-conf.h b/platform/cooja/contiki-conf.h index 98d61151c..91c93a3b4 100644 --- a/platform/cooja/contiki-conf.h +++ b/platform/cooja/contiki-conf.h @@ -33,6 +33,10 @@ #ifndef CONTIKI_CONF_H_ #define CONTIKI_CONF_H_ +#ifdef INCLUDE_SUBPLATFORM_CONF +#include "subplatform-conf.h" +#endif /* INCLUDE_SUBPLATFORM_CONF */ + #define PROFILE_CONF_ON 0 #define ENERGEST_CONF_ON 0 #define LOG_CONF_ENABLED 1 @@ -47,11 +51,11 @@ #define w_memcpy memcpy -#if WITH_UIP -#if WITH_UIP6 -#error WITH_UIP && WITH_IP6: Bad configuration -#endif /* WITH_UIP6 */ -#endif /* WITH_UIP */ +#if NETSTACK_CONF_WITH_IPV4 +#if NETSTACK_CONF_WITH_IPV6 +#error NETSTACK_CONF_WITH_IPV4 && NETSTACK_CONF_WITH_IPV6: Bad configuration +#endif /* NETSTACK_CONF_WITH_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ #ifdef NETSTACK_CONF_H @@ -63,7 +67,7 @@ #else /* NETSTACK_CONF_H */ /* Default network config */ -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 #define NULLRDC_CONF_802154_AUTOACK 1 #define NULLRDC_CONF_SEND_802154_ACK 1 @@ -78,9 +82,9 @@ #define NETSTACK_CONF_RADIO cooja_radio_driver #define NETSTACK_CONF_FRAMER framer_802154 -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 /* Network setup for IPv4 */ #define NETSTACK_CONF_NETWORK rime_driver /* NOTE: uip_over_mesh. else: uip_driver */ @@ -89,7 +93,7 @@ #define NETSTACK_CONF_RADIO cooja_radio_driver #define UIP_CONF_IP_FORWARD 1 -#else /* WITH_UIP */ +#else /* NETSTACK_CONF_WITH_IPV4 */ /* Network setup for Rime */ #define NETSTACK_CONF_NETWORK rime_driver @@ -98,15 +102,15 @@ #define NETSTACK_CONF_RADIO cooja_radio_driver /*#define NETSTACK_CONF_FRAMER framer_nullmac*/ -#endif /* WITH_UIP */ -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #endif /* NETSTACK_CONF_H */ #define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 /* Default network config */ -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 @@ -116,7 +120,7 @@ #define NETSTACK_CONF_RDC nullrdc_driver #define NETSTACK_CONF_RADIO cooja_radio_driver #define NETSTACK_CONF_FRAMER framer_802154 -#define UIP_CONF_IPV6 1 +#define NETSTACK_CONF_WITH_IPV6 1 #define LINKADDR_CONF_SIZE 8 @@ -124,9 +128,6 @@ #define UIP_CONF_LLH_LEN 0 #define UIP_CONF_ROUTER 1 -#ifndef UIP_CONF_IPV6_RPL -#define UIP_CONF_IPV6_RPL 1 -#endif /* UIP_CONF_IPV6_RPL */ /* configure number of neighbors and routes */ #ifndef NBR_TABLE_CONF_MAX_NEIGHBORS @@ -135,17 +136,26 @@ #ifndef UIP_CONF_MAX_ROUTES #define UIP_CONF_MAX_ROUTES 300 #endif /* UIP_CONF_MAX_ROUTES */ +#ifndef RPL_NS_CONF_LINK_NUM +#define RPL_NS_CONF_LINK_NUM 300 +#endif /* RPL_NS_CONF_LINK_NUM */ #define TCPIP_CONF_ANNOTATE_TRANSMISSIONS 1 +#ifndef UIP_CONF_ND6_SEND_RA #define UIP_CONF_ND6_SEND_RA 0 +#endif + +#ifndef UIP_CONF_ND6_REACHABLE_TIME #define UIP_CONF_ND6_REACHABLE_TIME 600000 +#endif + +#ifndef UIP_CONF_ND6_RETRANS_TIMER #define UIP_CONF_ND6_RETRANS_TIMER 10000 +#endif #define LINKADDR_CONF_SIZE 8 #define UIP_CONF_NETIF_MAX_ADDRESSES 3 -#define UIP_CONF_ND6_MAX_PREFIXES 3 -#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #ifndef UIP_CONF_IPV6_QUEUE_PKT #define UIP_CONF_IPV6_QUEUE_PKT 1 @@ -153,37 +163,26 @@ #define UIP_CONF_IPV6_CHECKS 1 #define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_NETIF_MAX_ADDRESSES 3 -#define UIP_CONF_ND6_MAX_PREFIXES 3 -#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_IP_FORWARD 0 -#ifndef UIP_CONF_BUFFER_SIZE -#define UIP_CONF_BUFFER_SIZE 240 -#endif -#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 -#define SICSLOWPAN_CONF_COMPRESSION_HC1 1 -#define SICSLOWPAN_CONF_COMPRESSION_HC01 2 #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #ifndef SICSLOWPAN_CONF_FRAG #define SICSLOWPAN_CONF_FRAG 1 #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ -#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 8 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define PACKETBUF_CONF_ATTRS_INLINE 1 +#ifndef QUEUEBUF_CONF_NUM #define QUEUEBUF_CONF_NUM 16 +#endif #define CC_CONF_REGISTER_ARGS 1 #define CC_CONF_FUNCTION_POINTER_ARGS 1 -#define CC_CONF_FASTCALL #define CC_CONF_VA_ARGS 1 #define CC_CONF_INLINE inline @@ -202,7 +201,7 @@ typedef unsigned short uip_stats_t; #define CLOCK_CONF_SECOND 1000L typedef unsigned long clock_time_t; typedef unsigned long rtimer_clock_t; -#define RTIMER_CLOCK_LT(a,b) ((signed long)((a)-(b)) < 0) +#define RTIMER_CLOCK_DIFF(a,b) ((signed long)((a)-(b))) #define AODV_COMPLIANCE #define AODV_NUM_RT_ENTRIES 32 @@ -213,12 +212,6 @@ typedef unsigned long rtimer_clock_t; #define UIP_CONF_DHCP_LIGHT #define UIP_CONF_LLH_LEN 0 -#ifndef UIP_CONF_RECEIVE_WINDOW -#define UIP_CONF_RECEIVE_WINDOW 48 -#endif -#ifndef UIP_CONF_TCP_MSS -#define UIP_CONF_TCP_MSS 48 -#endif #define UIP_CONF_MAX_CONNECTIONS 4 #define UIP_CONF_MAX_LISTENPORTS 8 #define UIP_CONF_UDP_CONNS 12 @@ -232,15 +225,36 @@ typedef unsigned long rtimer_clock_t; #define UIP_CONF_TCP_SPLIT 0 -#if UIP_CONF_IPV6 -#endif /* UIP_CONF_IPV6 */ +#if NETSTACK_CONF_WITH_IPV6 +#endif /* NETSTACK_CONF_WITH_IPV6 */ + +/* Turn off example-provided putchars */ +#define SLIP_BRIDGE_CONF_NO_PUTCHAR 1 + #define CFS_CONF_OFFSET_TYPE long +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 1600 +#endif + +#ifndef UIP_CONF_TCP_MSS +#define UIP_CONF_TCP_MSS (UIP_CONF_BUFFER_SIZE - 70) +#endif + +#ifndef UIP_CONF_RECEIVE_WINDOW +#define UIP_CONF_RECEIVE_WINDOW (UIP_CONF_BUFFER_SIZE - 70) +#endif + +#define RF_CHANNEL 26 +#define IEEE802154_CONF_PANID 0xABCD +#define NETSTACK_RADIO_MAX_PAYLOAD_LEN 125 + /* include the project config */ /* PROJECT_CONF_H might be defined in the project Makefile */ #ifdef PROJECT_CONF_H #include PROJECT_CONF_H #endif /* PROJECT_CONF_H */ + #endif /* CONTIKI_CONF_H_ */ diff --git a/platform/cooja/contiki-cooja-main.c b/platform/cooja/contiki-cooja-main.c index 035f9ee6b..40dd49d1c 100644 --- a/platform/cooja/contiki-cooja-main.c +++ b/platform/cooja/contiki-cooja-main.c @@ -40,6 +40,7 @@ #include #include "contiki.h" +#include "sys/cc.h" #include "sys/clock.h" #include "sys/etimer.h" @@ -52,6 +53,7 @@ #include "net/rime/rime.h" #include "net/netstack.h" +#include "dev/eeprom.h" #include "dev/serial-line.h" #include "dev/cooja-radio.h" #include "dev/button-sensor.h" @@ -74,10 +76,10 @@ #define Java_org_contikios_cooja_corecomm_CLASSNAME_tick COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_tick) #define Java_org_contikios_cooja_corecomm_CLASSNAME_setReferenceAddress COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_setReferenceAddress) -#ifndef WITH_UIP -#define WITH_UIP 0 +#ifndef NETSTACK_CONF_WITH_IPV4 +#define NETSTACK_CONF_WITH_IPV4 0 #endif -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 #include "dev/rs232.h" #include "dev/slip.h" #include "net/ip/uip.h" @@ -91,16 +93,16 @@ static struct uip_fw_netif meshif = #define UIP_OVER_MESH_CHANNEL 8 static uint8_t is_gateway; -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ -#ifndef WITH_UIP6 -#define WITH_UIP6 0 +#ifndef NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_WITH_IPV6 0 #endif -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 #include "net/ip/uip.h" #include "net/ipv6/uip-ds6.h" #define PRINT6ADDR(addr) printf("%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /* Simulation mote interfaces */ SIM_INTERFACE_NAME(moteid_interface); @@ -114,7 +116,8 @@ SIM_INTERFACE_NAME(pir_interface); SIM_INTERFACE_NAME(clock_interface); SIM_INTERFACE_NAME(leds_interface); SIM_INTERFACE_NAME(cfs_interface); -SIM_INTERFACES(&vib_interface, &moteid_interface, &rs232_interface, &simlog_interface, &beep_interface, &radio_interface, &button_interface, &pir_interface, &clock_interface, &leds_interface, &cfs_interface); +SIM_INTERFACE_NAME(eeprom_interface); +SIM_INTERFACES(&vib_interface, &moteid_interface, &rs232_interface, &simlog_interface, &beep_interface, &radio_interface, &button_interface, &pir_interface, &clock_interface, &leds_interface, &cfs_interface, &eeprom_interface); /* Example: manually add mote interfaces */ //SIM_INTERFACE_NAME(dummy_interface); //SIM_INTERFACES(..., &dummy_interface); @@ -134,10 +137,8 @@ long referenceVar; static struct cooja_mt_thread rtimer_thread; static struct cooja_mt_thread process_run_thread; -#define MIN(a, b) ( (a)<(b) ? (a) : (b) ) - /*---------------------------------------------------------------------------*/ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 static void set_gateway(void) { @@ -151,7 +152,7 @@ set_gateway(void) is_gateway = 1; } } -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ /*---------------------------------------------------------------------------*/ static void print_processes(struct process * const processes[]) @@ -184,15 +185,15 @@ set_rime_addr(void) int i; memset(&addr, 0, sizeof(linkaddr_t)); -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 for(i = 0; i < sizeof(uip_lladdr.addr); i += 2) { addr.u8[i + 1] = node_id & 0xff; addr.u8[i + 0] = node_id >> 8; } -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ addr.u8[0] = node_id & 0xff; addr.u8[1] = node_id >> 8; -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ linkaddr_set_node_addr(&addr); printf("Rime started with address "); for(i = 0; i < sizeof(addr.u8) - 1; i++) { @@ -227,10 +228,7 @@ contiki_init() set_rime_addr(); { uint8_t longaddr[8]; - uint16_t shortaddr; - - shortaddr = (linkaddr_node_addr.u8[0] << 8) + - linkaddr_node_addr.u8[1]; + memset(longaddr, 0, sizeof(longaddr)); linkaddr_copy((linkaddr_t *)&longaddr, &linkaddr_node_addr); printf("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ", @@ -243,11 +241,11 @@ contiki_init() /* Initialize communication stack */ netstack_init(); printf("%s/%s/%s, channel check rate %lu Hz\n", - NETSTACK_NETWORK.name, NETSTACK_MAC.name, NETSTACK_RDC.name, + NETSTACK_NETWORK.name, NETSTACK_MAC.name, NETSTACK_RDC.name, CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1: NETSTACK_RDC.channel_check_interval())); -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 /* IPv4 CONFIGURATION */ { uip_ipaddr_t hostaddr, netmask; @@ -274,9 +272,9 @@ contiki_init() rs232_set_input(slip_input_byte); printf("IPv4 address: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&hostaddr)); } -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 /* IPv6 CONFIGURATION */ { int i; @@ -285,7 +283,7 @@ contiki_init() addr[i + 1] = node_id & 0xff; addr[i + 0] = node_id >> 8; } - linkaddr_copy(addr, &linkaddr_node_addr); + linkaddr_copy((linkaddr_t *)addr, &linkaddr_node_addr); memcpy(&uip_lladdr.addr, addr, sizeof(uip_lladdr.addr)); process_start(&tcpip_process, NULL); @@ -296,17 +294,17 @@ contiki_init() int i; lladdr = uip_ds6_get_link_local(-1); for(i = 0; i < 7; ++i) { - printf("%02x%02x:", lladdr->ipaddr.u8[i * 2], - lladdr->ipaddr.u8[i * 2 + 1]); + printf("%02x%02x:", lladdr->ipaddr.u8[i * 2], + lladdr->ipaddr.u8[i * 2 + 1]); } printf("%02x%02x\n", lladdr->ipaddr.u8[14], - lladdr->ipaddr.u8[15]); + lladdr->ipaddr.u8[15]); } if(1) { uip_ipaddr_t ipaddr; int i; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE); printf("Tentative global IPv6 address "); @@ -318,7 +316,10 @@ contiki_init() ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]); } } -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ + + /* Initialize eeprom */ + eeprom_init(); /* Start serial process */ serial_line_init(); @@ -358,6 +359,8 @@ process_run_thread_loop(void *data) /*---------------------------------------------------------------------------*/ /** * \brief Initialize a mote by starting processes etc. + * \param env JNI Environment interface pointer + * \param obj unused * * This function initializes a mote by starting certain * processes and setting up the environment. @@ -375,12 +378,15 @@ Java_org_contikios_cooja_corecomm_CLASSNAME_init(JNIEnv *env, jobject obj) /*---------------------------------------------------------------------------*/ /** * \brief Get a segment from the process memory. - * \param start Start address of segment - * \param length Size of memory segment + * \param env JNI Environment interface pointer + * \param obj unused + * \param rel_addr Start address of segment + * \param length Size of memory segment + * \param mem_arr Byte array destination for the fetched memory segment * \return Java byte array containing a copy of memory segment. * * Fetches a memory segment from the process memory starting at - * (start), with size (length). This function does not perform + * (rel_addr), with size (length). This function does not perform * ANY error checking, and the process may crash if addresses are * not available/readable. * @@ -401,9 +407,11 @@ Java_org_contikios_cooja_corecomm_CLASSNAME_getMemory(JNIEnv *env, jobject obj, /*---------------------------------------------------------------------------*/ /** * \brief Replace a segment of the process memory with given byte array. - * \param start Start address of segment - * \param length Size of memory segment - * \param mem_arr Byte array contaning new memory + * \param env JNI Environment interface pointer + * \param obj unused + * \param rel_addr Start address of segment + * \param length Size of memory segment + * \param mem_arr Byte array contaning new memory * * Replaces a process memory segment with given byte array. * This function does not perform ANY error checking, and the @@ -416,15 +424,16 @@ JNIEXPORT void JNICALL Java_org_contikios_cooja_corecomm_CLASSNAME_setMemory(JNIEnv *env, jobject obj, jint rel_addr, jint length, jbyteArray mem_arr) { jbyte *mem = (*env)->GetByteArrayElements(env, mem_arr, 0); - memcpy( - (char*) (((long)rel_addr) + referenceVar), - mem, - length); + memcpy((char*) (((long)rel_addr) + referenceVar), + mem, + length); (*env)->ReleaseByteArrayElements(env, mem_arr, mem, 0); } /*---------------------------------------------------------------------------*/ /** * \brief Let mote execute one "block" of code (tick mote). + * \param env JNI Environment interface pointer + * \param obj unused * * Let mote defined by the active contiki processes and current * process memory execute some program code. This code must not block @@ -452,7 +461,7 @@ Java_org_contikios_cooja_corecomm_CLASSNAME_tick(JNIEnv *env, jobject obj) doActionsBeforeTick(); /* Poll etimer process */ - if (etimer_pending()) { + if(etimer_pending()) { etimer_request_poll(); } @@ -480,16 +489,18 @@ Java_org_contikios_cooja_corecomm_CLASSNAME_tick(JNIEnv *env, jobject obj) nextRtimer = rtimer_arch_next() - (rtimer_clock_t) simCurrentTime; if(etimer_pending() && rtimer_arch_pending()) { simNextExpirationTime = MIN(nextEtimer, nextRtimer); - } else if (etimer_pending()) { + } else if(etimer_pending()) { simNextExpirationTime = nextEtimer; - } else if (rtimer_arch_pending()) { + } else if(rtimer_arch_pending()) { simNextExpirationTime = nextRtimer; } } /*---------------------------------------------------------------------------*/ /** * \brief Set the relative memory address of the reference variable. - * \return Relative memory address. + * \param env JNI Environment interface pointer + * \param obj unused + * \param addr Relative memory address * * This is a JNI function and should only be called via the * responsible Java part (MoteType.java). diff --git a/platform/cooja/dev/cooja-radio.c b/platform/cooja/dev/cooja-radio.c index 4c5c53593..9a969016d 100644 --- a/platform/cooja/dev/cooja-radio.c +++ b/platform/cooja/dev/cooja-radio.c @@ -272,6 +272,30 @@ init(void) return 1; } /*---------------------------------------------------------------------------*/ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ const struct radio_driver cooja_radio_driver = { init, @@ -284,6 +308,10 @@ const struct radio_driver cooja_radio_driver = pending_packet, radio_on, radio_off, + get_value, + set_value, + get_object, + set_object }; /*---------------------------------------------------------------------------*/ SIM_INTERFACE(radio_interface, diff --git a/platform/cooja/dev/eeprom.c b/platform/cooja/dev/eeprom.c new file mode 100644 index 000000000..026c10f26 --- /dev/null +++ b/platform/cooja/dev/eeprom.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2014, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +#include +#include "dev/eeprom.h" + +#include "lib/simEnvChange.h" + +const struct simInterface eeprom_interface; + +#define EEPROM_BUF_SIZE 1024 /* Configure EEPROM size here and in ContikiEeprom.java */ + +unsigned char simEEPROMData[EEPROM_BUF_SIZE]; +char simEEPROMChanged = 0; +int simEEPROMRead = 0; +int simEEPROMWritten = 0; + +void +eeprom_init(void) +{ +} + +void +eeprom_read(eeprom_addr_t addr, unsigned char *buf, int len) +{ + if (addr >= EEPROM_BUF_SIZE) { + return; + } + + if(addr + len >= EEPROM_BUF_SIZE) { + len = EEPROM_BUF_SIZE - addr; + } + + memcpy(buf, &simEEPROMData[addr], len); + + simEEPROMChanged = 1; + simEEPROMRead += len; +} + +void +eeprom_write(eeprom_addr_t addr, unsigned char *buf, int len) +{ + if (addr >= EEPROM_BUF_SIZE) { + return; + } + + if(addr + len >= EEPROM_BUF_SIZE) { + len = EEPROM_BUF_SIZE - addr; + } + + + memcpy(&simEEPROMData[addr], buf, len); + + simEEPROMChanged = 1; + simEEPROMWritten += len; + +} + +/*-----------------------------------------------------------------------------------*/ +static void +doInterfaceActionsBeforeTick(void) +{ +} +/*-----------------------------------------------------------------------------------*/ +static void +doInterfaceActionsAfterTick(void) +{ +} +/*-----------------------------------------------------------------------------------*/ + +SIM_INTERFACE(eeprom_interface, + doInterfaceActionsBeforeTick, + doInterfaceActionsAfterTick); diff --git a/platform/cooja/dev/ip.c b/platform/cooja/dev/ip.c index de513d074..7a637c8ac 100644 --- a/platform/cooja/dev/ip.c +++ b/platform/cooja/dev/ip.c @@ -37,31 +37,31 @@ const struct simInterface ip_interface; // COOJA variables -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 char simIPChanged; char simIP[16]; -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 char simIPChanged; char simIP[4]; -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ /*-----------------------------------------------------------------------------------*/ static void doInterfaceActionsBeforeTick(void) { -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /* check if IPv6 address should change */ -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 /* check if IPv4 address should change */ /* @@ -73,7 +73,7 @@ doInterfaceActionsBeforeTick(void) } */ -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ } /*-----------------------------------------------------------------------------------*/ static void diff --git a/platform/cooja/dev/rs232.c b/platform/cooja/dev/rs232.c index a52b9a130..08257b555 100644 --- a/platform/cooja/dev/rs232.c +++ b/platform/cooja/dev/rs232.c @@ -37,7 +37,7 @@ const struct simInterface rs232_interface; -#define SERIAL_BUF_SIZE 1024 +#define SERIAL_BUF_SIZE 2048 // COOJA variables char simSerialReceivingData[SERIAL_BUF_SIZE]; @@ -46,6 +46,7 @@ char simSerialReceivingFlag; static int (* input_handler)(unsigned char) = NULL; +void simlog_char(char c); /*-----------------------------------------------------------------------------------*/ void rs232_init(void) { } /*-----------------------------------------------------------------------------------*/ diff --git a/platform/cooja/dev/rs232.h b/platform/cooja/dev/rs232.h index aefb5c823..d21c549b0 100644 --- a/platform/cooja/dev/rs232.h +++ b/platform/cooja/dev/rs232.h @@ -30,18 +30,10 @@ * */ -/** \addtogroup esb - * @{ */ - -/** - * \defgroup esbrs232 ESB RS232 - * - * @{ - */ /** * \file - * Header file for MSP430 RS232 driver. + * Header file for COOJA RS232 driver. * \author Adam Dunkels * */ @@ -93,7 +85,7 @@ void rs232_set_speed(unsigned char speed); /** * \brief Print a text string on RS232 - * \param str A pointer to the string that is to be printed + * \param text A pointer to the string that is to be printed * * This function prints a string to RS232. The string must * be terminated by a null byte. The RS232 module must be @@ -114,4 +106,3 @@ void rs232_send(char c); #endif /* RS232_H_ */ -/** @} */ /** @} */ diff --git a/platform/cooja/dev/uart1.h b/platform/cooja/dev/uart1.h new file mode 100644 index 000000000..69b96e574 --- /dev/null +++ b/platform/cooja/dev/uart1.h @@ -0,0 +1,31 @@ +/* + Copied from mc1322x/dev/cpu. + + This file exists as a work-around for the hardware dependant calls + to slip_arch_init. + + Current the prototype for slip_arch_init is slip_arch_init(urb) + + and a typical call is something like + slip_arch_init(BAUD2URB(115200)) + + BAUD2UBR is hardware specific, however. Furthermore, for the sky + platform it's typically defined with #include "dev/uart1.h" (see + rpl-boarder-router/slip-bridge.c), a sky specific file. dev/uart1.h + includes msp430.h which includes the sky contiki-conf.h which + defines BAUD2UBR. + + To me, the correct think to pass is simply the baudrate and have the + hardware specific conversion happen inside slip_arch_init. + + Notably, most implementations just ignore the passed parameter + anyway. (except AVR) + + */ + +#ifndef DEV_UART1_H +#define DEV_UART1_H + +#define BAUD2UBR(x) x + +#endif diff --git a/platform/cooja/net/uip-driver.c b/platform/cooja/net/uip-driver.c index 39dbd6e01..896550f93 100644 --- a/platform/cooja/net/uip-driver.c +++ b/platform/cooja/net/uip-driver.c @@ -45,13 +45,17 @@ /*--------------------------------------------------------------------*/ uint8_t +#if NETSTACK_CONF_WITH_IPV6 +uip_driver_send(const uip_lladdr_t *addr) +#else uip_driver_send(void) +#endif { packetbuf_copyfrom(&uip_buf[UIP_LLH_LEN], uip_len); /* XXX we should provide a callback function that is called when the packet is sent. For now, we just supply a NULL pointer. */ - NETSTACK_MAC.send(NULL, NULL); + NETSTACK_LLSEC.send(NULL, NULL); return 1; } /*--------------------------------------------------------------------*/ diff --git a/platform/cooja/net/uip-driver.h b/platform/cooja/net/uip-driver.h index 2a9c4b191..a711313b8 100644 --- a/platform/cooja/net/uip-driver.h +++ b/platform/cooja/net/uip-driver.h @@ -41,7 +41,11 @@ #include "net/netstack.h" +#if NETSTACK_CONF_WITH_IPV6 +uint8_t uip_driver_send(const uip_lladdr_t *); +#else uint8_t uip_driver_send(void); +#endif extern const struct network_driver uip_driver; diff --git a/platform/z1sp/contiki-z1sp-platform.c b/platform/cooja/slip-arch.c similarity index 83% rename from platform/z1sp/contiki-z1sp-platform.c rename to platform/cooja/slip-arch.c index 60272bb00..959eeda47 100644 --- a/platform/z1sp/contiki-z1sp-platform.c +++ b/platform/cooja/slip-arch.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Zolertia(TM) is a trademark of Advancare,SL + * Copyright (c) 2014, TU Braunschweig * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,16 +26,14 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * - * Author: Enric M. Calvo based on previous work by - * Niclas Finne , Joakim Eriksson - * */ -#include "dev/button-sensor.h" +#include "dev/slip.h" +#include "dev/rs232.h" void -init_platform(void) +slip_arch_init(unsigned long ubr) { - process_start(&sensors_process, NULL); + rs232_set_input(slip_input_byte); } + diff --git a/platform/cooja/sys/log.c b/platform/cooja/sys/log.c index a5f11958d..7d03ae2ce 100644 --- a/platform/cooja/sys/log.c +++ b/platform/cooja/sys/log.c @@ -36,13 +36,13 @@ #define IMPLEMENT_PRINTF 1 -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 /* uIP packets via SLIP */ #include "uip.h" #define MAX_LOG_LENGTH (2*UIP_BUFSIZE) -#else /* WITH_UIP */ +#else /* NETSTACK_CONF_WITH_IPV4 */ #define MAX_LOG_LENGTH 1024 -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ #if MAX_LOG_LENGTH < 1024 #undef MAX_LOG_LENGTH diff --git a/platform/econotag/Makefile.econotag b/platform/econotag/Makefile.econotag index 8e6939f9c..1567de910 100644 --- a/platform/econotag/Makefile.econotag +++ b/platform/econotag/Makefile.econotag @@ -4,7 +4,7 @@ CONTIKI_TARGET_DIRS = . dev apps net CONTIKI_CORE = main CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o -CONTIKI_TARGET_SOURCEFILES += main.c clock.c button-sensor.c sensors.c slip.c platform_prints.c +CONTIKI_TARGET_SOURCEFILES += main.c clock.c button-sensor.c button-sensor2.c sensors.c slip.c platform_prints.c ${warning $(CONTIKI)} CONTIKIMC1322X=$(CONTIKI)/cpu/mc1322x @@ -14,11 +14,8 @@ CONTIKI_PLAT_DEFS = MCU=arm7tdmi-s -ifeq ($(UIP_CONF_IPV6),1) -CFLAGS += -DWITH_UIP6=1 -endif - include $(CONTIKIMC1322X)/Makefile.mc1322x -MODULES+=core/net/ip core/net/ipv4 core/net core/net/rpl \ - core/net/ipv6 core/net/rime core/net/mac +MODULES+=core/net \ + core/net/mac \ + core/net/llsec diff --git a/platform/econotag/apps/ecc/Makefile.ecc b/platform/econotag/apps/ecc/Makefile.ecc new file mode 100644 index 000000000..44dd816c2 --- /dev/null +++ b/platform/econotag/apps/ecc/Makefile.ecc @@ -0,0 +1 @@ +ecc_src = ecc.c diff --git a/platform/econotag/apps/ecc/ecc.c b/platform/econotag/apps/ecc/ecc.c new file mode 100644 index 000000000..8d8598d8b --- /dev/null +++ b/platform/econotag/apps/ecc/ecc.c @@ -0,0 +1,1016 @@ +/* + * Copyright (c) 2015, Lars Schmertmann , + * Jens Trillmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ + +#include "ecc.h" + +#include + +#define X 0 +#define Y 8 +#define Z 16 + +const uint32_t ecc_prime_m[8] = { 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0xffffffff }; +const uint32_t ecc_prime_r[8] = { 0x00000001, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, 0x00000000 }; + +/*---------------------------------------------------------------------------*/ + +#define DEBUG 0 +#define SELF_TEST 0 + +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINTHEX(...) print_hex(__VA_ARGS__) +static void +print_hex(const char *name, const uint32_t *d, uint32_t l) +{ + printf("%s:", name); + int i; + for(i = l - 1; i >= 0; --i) { + printf(" %08X", d[i]); + } + printf("\n"); +} +#else +#define PRINTF(...) +#define PRINTHEX(...) +#endif + +#if SELF_TEST +#include +static void selfTest(); +#endif + +/* private prototypes ----------------------------------------------------- */ + +/* simple functions to work with 256 bit numbers */ +static void ecc_setZero(uint32_t *a); +static void ecc_copy(uint32_t *dst, const uint32_t *src); +static uint32_t ecc_isX(const uint32_t *a, const uint32_t x); +static void ecc_rshift(uint32_t *a); +static void ecc_replace(uint32_t bit, uint32_t *dst, uint32_t *src); +static uint32_t ecc_add(uint32_t *result, const uint32_t *a, const uint32_t *b); +static uint32_t ecc_sub(uint32_t *result, const uint32_t *a, const uint32_t *b); +static void ecc_mult(uint32_t *result, const uint32_t *x, const uint32_t *y, const uint32_t length); + +/* ecc_field_ModP-Helper */ +__attribute__((always_inline)) static void ecc_form_s1(uint32_t *dst, const uint32_t *src); +__attribute__((always_inline)) static void ecc_form_s2(uint32_t *dst, const uint32_t *src); +__attribute__((always_inline)) static void ecc_form_s3(uint32_t *dst, const uint32_t *src); +__attribute__((always_inline)) static void ecc_form_s4(uint32_t *dst, const uint32_t *src); +__attribute__((always_inline)) static void ecc_form_d1(uint32_t *dst, const uint32_t *src); +__attribute__((always_inline)) static void ecc_form_d2(uint32_t *dst, const uint32_t *src); +__attribute__((always_inline)) static void ecc_form_d3(uint32_t *dst, const uint32_t *src); +__attribute__((always_inline)) static void ecc_form_d4(uint32_t *dst, const uint32_t *src); + +/* field functions for 256 bit numbers */ +static void ecc_field_Add(uint32_t *result, const uint32_t *x, const uint32_t *y); +static void ecc_field_Sub(uint32_t *result, const uint32_t *x, const uint32_t *y); +static void ecc_field_ModP(uint32_t *result, const uint32_t *T); +static void ecc_field_Mult(uint32_t *result, const uint32_t *A, const uint32_t *B); +static void ecc_field_Inv(uint32_t *result, const uint32_t *A); + +/* new projective stuff */ +static void ecc_projective_double(uint32_t *val); +static void ecc_projective_add(uint32_t *result, const uint32_t *val_1, const uint32_t *x_2, const uint32_t *y_2, const uint32_t *z_2); + +/* public functions -------------------------------------------------------- */ + +int32_t +ecc_compare(const uint32_t *a, const uint32_t *b) +{ + int32_t r = 0; + uint32_t i = 8; + while(i--) { + uint32_t neq = (a[i] != b[i]); + int32_t greater = (a[i] > b[i] ? 1 : -1); + r ^= ((-(!r && neq)) & (r ^ greater)); + } + return r; +} +void +ecc_ec_mult(uint32_t *resultx, uint32_t *resulty, const uint32_t *px, const uint32_t *py, const uint32_t *secret) +{ +#if SELF_TEST + selfTest(); +#endif + + PRINTHEX("PX", px, 8); + PRINTHEX("PY", py, 8); + PRINTHEX("SC", secret, 8); + + uint32_t Q[24]; + ecc_setZero(Q + X); + ecc_setZero(Q + Y); + ecc_setZero(Q + Z); + Q[Z] = 0x00000001; + + uint32_t pz[8]; + ecc_setZero(pz); + pz[0] = 0x00000001; + + uint32_t temp[24]; + + int i; + for(i = 255; i >= 0; --i) { + ecc_projective_double(Q); +/* PRINTHEX("QX", Q+X, 8); */ +/* PRINTHEX("QY", Q+Y, 8); */ +/* PRINTHEX("QZ", Q+Z, 8); */ + ecc_projective_add(temp, Q, px, py, pz); +/* PRINTHEX("QX", temp+X, 8); */ +/* PRINTHEX("QY", temp+Y, 8); */ +/* PRINTHEX("QZ", temp+Z, 8); */ + int current_bit = (secret[i / 32] >> (i % 32)) & 0x1; /* ((secret[i / 32]) & ((uint32_t)1 << (i % 32))); */ + ecc_replace(current_bit, Q, temp); +/* PRINTHEX("QX", Q+X, 8); */ +/* PRINTHEX("QY", Q+Y, 8); */ +/* PRINTHEX("QZ", Q+Z, 8); */ + } +/* PRINTHEX("QX", Q+X, 8); */ +/* PRINTHEX("QY", Q+Y, 8); */ +/* PRINTHEX("QZ", Q+Z, 8); */ + ecc_field_Inv(temp, Q + Z); + ecc_field_Mult(resultx, Q + X, temp); + ecc_field_Mult(resulty, Q + Y, temp); + PRINTHEX("RX", resultx, 8); + PRINTHEX("RY", resulty, 8); +} +/* private functions ------------------------------------------------------- */ + +static void +ecc_setZero(uint32_t *a) +{ + asm volatile ( + "mov r1, $0 \n\t" + "mov r2, r1 \n\t" + "mov r3, r2 \n\t" + "mov r4, r3 \n\t" + "stm %[a]!, {r1-r4} \n\t" + "stm %[a]!, {r1-r4} \n\t" + : /* out */ + : /* in */ + [a] "l" (a) + : /* clobber list */ + "r1", "r2", "r3", "r4", "memory" + ); +} +/* + * copy one array to another + */ +static void +ecc_copy(uint32_t *dst, const uint32_t *src) +{ + asm volatile ( + "ldm %[s]!, {r2-r5} \n\t" + "stm %[d]!, {r2-r5} \n\t" + "ldm %[s]!, {r2-r5} \n\t" + "stm %[d]!, {r2-r5} \n\t" + : /* out */ + : /* in */ + [d] "l" (dst), + [s] "l" (src) + : /* clobber list */ + "r2", "r3", "r4", "r5", "memory" + ); +} +static uint32_t +ecc_isX(const uint32_t *a, const uint32_t x) +{ + uint32_t r = (a[0] == x); + uint32_t n = 8; + while(--n) { + r &= (a[n] == 0); + } + return r; +} +static void +ecc_rshift(uint32_t *a) +{ + uint32_t index = 32; + uint32_t carry = 0; + + asm volatile ( + "0: \n\t" + "sub %[i], %[i], #4 \n\t" /* index -= 4 */ + "mov r4, %[c] \n\t" /* result = carry */ + "ldr r3, [%[a],%[i]] \n\t" /* value = a[index] */ + "lsl %[c], r3, #31 \n\t" /* carry = value << 31 */ + "lsr r3, r3, #1 \n\t" /* value >>= 1 */ + "orr r4, r4, r3 \n\t" /* result |= value */ + "str r4, [%[a],%[i]] \n\t" /* a[index] = result */ + "cmp %[i], $0 \n\t" /* index == 0 */ + "bne 0b \n\t" /* != ? next loop */ + : /* out */ + : /* in */ + [a] "r" (a), + [i] "r" (index), + [c] "r" (carry) + : /* clobber list */ + "r3", "r4", "memory" + ); +} +static void +ecc_replace(uint32_t bit, uint32_t *dst, uint32_t *src) +{ + bit = -bit; + int i; + for(i = 0; i < 24; i++) { + dst[i] ^= (bit & (dst[i] ^ src[i])); + } +} +static uint32_t +ecc_add(uint32_t *result, const uint32_t *a, const uint32_t *b) +{ + uint32_t carry; + + asm volatile ( + "ldm %[x]!, {r4,r5} \n\t" + "ldm %[y]!, {r6,r7} \n\t" + "add r4, r4, r6 \n\t" + "adc r5, r5, r7 \n\t" + "stm %[r]!, {r4,r5} \n\t" + "ldm %[x]!, {r4,r5} \n\t" + "ldm %[y]!, {r6,r7} \n\t" + "adc r4, r4, r6 \n\t" + "adc r5, r5, r7 \n\t" + "stm %[r]!, {r4,r5} \n\t" + "ldm %[x]!, {r4,r5} \n\t" + "ldm %[y]!, {r6,r7} \n\t" + "adc r4, r4, r6 \n\t" + "adc r5, r5, r7 \n\t" + "stm %[r]!, {r4,r5} \n\t" + "ldm %[x]!, {r4,r5} \n\t" + "ldm %[y]!, {r6,r7} \n\t" + "adc r4, r4, r6 \n\t" + "adc r5, r5, r7 \n\t" + "stm %[r]!, {r4,r5} \n\t" + "bcc 0f \n\t" + "mov %[c], #1 \n\t" + "b 1f \n\t" + "0: \n\t" + "mov %[c], $0 \n\t" + "1: \n\t" + : /* out */ + [c] "=l" (carry) + : /* in */ + [x] "l" (a), + [y] "l" (b), + [r] "l" (result) + : /* clobber list */ + "r4", "r5", "r6", "r7", "memory" + ); + + return carry; +} +static uint32_t +ecc_sub(uint32_t *result, const uint32_t *a, const uint32_t *b) +{ + uint32_t carry; + + asm volatile ( + "ldm %[x]!, {r4,r5} \n\t" + "ldm %[y]!, {r6,r7} \n\t" + "sub r4, r4, r6 \n\t" + "sbc r5, r5, r7 \n\t" + "stm %[r]!, {r4,r5} \n\t" + "ldm %[x]!, {r4,r5} \n\t" + "ldm %[y]!, {r6,r7} \n\t" + "sbc r4, r4, r6 \n\t" + "sbc r5, r5, r7 \n\t" + "stm %[r]!, {r4,r5} \n\t" + "ldm %[x]!, {r4,r5} \n\t" + "ldm %[y]!, {r6,r7} \n\t" + "sbc r4, r4, r6 \n\t" + "sbc r5, r5, r7 \n\t" + "stm %[r]!, {r4,r5} \n\t" + "ldm %[x]!, {r4,r5} \n\t" + "ldm %[y]!, {r6,r7} \n\t" + "sbc r4, r4, r6 \n\t" + "sbc r5, r5, r7 \n\t" + "stm %[r]!, {r4,r5} \n\t" + "bcs 0f \n\t" + "mov %[c], #1 \n\t" + "b 1f \n\t" + "0: \n\t" + "mov %[c], $0 \n\t" + "1: \n\t" + : /* out */ + [c] "=l" (carry) + : /* in */ + [x] "l" (a), + [y] "l" (b), + [r] "l" (result) + : /* clobber list */ + "r4", "r5", "r6", "r7", "memory" + ); + + return carry; +} +static void +ecc_mult(uint32_t *result, const uint32_t *x, const uint32_t *y, const uint32_t length) +{ + if(length == 1) { + /* Version 1: 56 Byte bigger as ASM-Version */ + /* uint64_t *r = (uint64_t *) result; */ + /* *r = (uint64_t) x[0] * (uint64_t) y[0]; */ + + /* Version 2: 56 Byte lesser as Version 1 but same speed */ + asm volatile ( + "ldrh r5, [%[x], $0] \n\t" /* r5 = (x[0] & 0x0000FFFF) */ + "ldrh r3, [%[y], $0] \n\t" /* r3 = (y[0] & 0x0000FFFF) */ + "mul r5, r3 \n\t" /* r5 *= r3 r5 = AB[0] */ + "ldrh r6, [%[x], #2] \n\t" /* r6 = (x[0] >> 16) */ + "mul r3, r6 \n\t" /* r3 *= r6 r3 = C[0] */ + "ldrh r4, [%[y], #2] \n\t" /* r4 = (y[0] >> 16) */ + "mul r6, r4 \n\t" /* r6 *= r4 r6 = AB[1] */ + /* %[y] is not longer needed - its called ry now */ + "ldrh %[y], [%[x], $0] \n\t" /* ry = (x[0] & 0x0000FFFF) */ + "mul r4, %[y] \n\t" /* r4 *= ry r4 = C[1] */ + "add %[y], r3, r4 \n\t" /* ry = r3 + r4 ry = C[0] + C[1] */ + /* C[1] (r4) is not longer needed */ + "mov r4, $0 \n\t" /* r4 = 0 */ + "bcc 0f \n\t" /* jump if carry clear */ + "mov r4, #1 \n\t" /* r4 = 1 */ + "lsl r4, r4, #16 \n\t" /* r4 <<= 16 */ + "0: \n\t" /* r4 = 0x000c0000 = (carry << 16) */ + "lsr r3, %[y], #16 \n\t" /* r3 = (ry >> 16) */ + "orr r4, r4, r3 \n\t" /* r4 |= r3 r4 = 0x000c'ryh' = (r4 | ry >> 16) */ + "lsl r3, %[y], #16 \n\t" /* r3 = (ry << 16) r3 = 0x'ryl'0000 = (ry << 16) */ + "add r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[r]!, {r3, r4} \n\t" + : /* out */ + : /* in */ + [x] "l" (x), + [y] "l" (y), + [r] "l" (result) + : /* clobber list */ + "r3", "r4", "r5", "r6", "memory" + ); + } else { + uint32_t carry; + uint32_t C[length * 2]; + ecc_mult(result, x, y, length / 2); + ecc_mult(result + length, x + (length / 2), y + (length / 2), length / 2); + ecc_mult(C, x, y + (length / 2), length / 2); + ecc_mult(C + length, x + (length / 2), y, length / 2); + if(length == 8) { + carry = ecc_add(C, C, C + length); + } else { + asm volatile ( + "cmp %[l], #2 \n\t" + "beq .add2 \n\t" + /* ASM for: ecc_add(C, C, C + 4, 4); */ + "mov %[l], %[a] \n\t" + "ldm %[a]!, {r3-r6} \n\t" + "ldm %[a]!, {r5,r6} \n\t" + "sub %[a], %[a], #16 \n\t" + "add r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "ldm %[a]!, {r3-r6} \n\t" + "ldm %[a]!, {r5,r6} \n\t" + "adc r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "b 0f \n\t" + ".add2: \n\t" + /* ASM for: ecc_add(C, C, C + 2, 2); */ + "ldm %[a]!, {r3-r6} \n\t" + "sub %[a], %[a], #16 \n\t" + "add r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[a]!, {r3,r4} \n\t" + "0: \n\t" + "bcc 1f \n\t" + "mov %[c], #1 \n\t" + "b 2f \n\t" + "1: \n\t" + "mov %[c], $0 \n\t" + "2: \n\t" + : /* out */ + [c] "=l" (carry) + : /* in */ + [a] "l" (C), + [l] "l" (length) + : /* clobber list */ + "r3", "r4", "r5", "r6", "memory" + ); + } C[length] = carry; + asm volatile ( + "cmp %[l], #2 \n\t" + "beq .add3 \n\t" + "cmp %[l], #4 \n\t" + "beq .add6 \n\t" + ".add12: \n\t" + /* ASM for: ecc_add(result + 4, result + 4, C, 12); */ + /* RRRRRRRRRRRRRRRR */ + /* + CCCCCCCCC000 */ + /* = RRRRRRRRRRRRRRRR */ + "add %[r], %[r], #16 \n\t" + "mov %[l], %[r] \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5,r6} \n\t" + "add r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5,r6} \n\t" + "adc r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5,r6} \n\t" + "adc r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5,r6} \n\t" + "adc r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5} \n\t" + "mov r6, $0 \n\t" + "adc r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "adc r3, r3, r6 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "b 0f \n\t" + ".add6: \n\t" + /* ASM for: ecc_add(result + 2, result + 2, C, 6); */ + /* RRRRRRRR */ + /* + CCCCC0 */ + /* = RRRRRRRR */ + "add %[r], %[r], #8 \n\t" + "mov %[l], %[r] \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5,r6} \n\t" + "add r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5,r6} \n\t" + "adc r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5} \n\t" + "mov r6, $0 \n\t" + "adc r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "stm %[l]!, {r3,r4} \n\t" + "b 0f \n\t" + ".add3: \n\t" + /* ASM for: ecc_add(result + 1, result + 1, C, 3); */ + /* RRRR */ + /* + CCC */ + /* = RRRR */ + "add %[r], %[r], #4 \n\t" + "mov %[l], %[r] \n\t" + "ldm %[r]!, {r3,r4} \n\t" + "ldm %[c]!, {r5,r6} \n\t" + "add r3, r3, r5 \n\t" + "adc r4, r4, r6 \n\t" + "ldr r5, [%[r], $0] \n\t" + "ldr r6, [%[c], $0] \n\t" + "adc r5, r5, r6 \n\t" + "stm %[l]!, {r3-r5} \n\t" + "0: \n\t" + : /* out */ + : /* in */ + [r] "l" (result), + [c] "l" (C), + [l] "l" (length) + : /* clobber list */ + "r3", "r4", "r5", "r6", "memory" + ); + } +} +/*---------------------------------------------------------------------------*/ + +__attribute__((always_inline)) static void +ecc_form_s1(uint32_t *dst, const uint32_t *src) +{ + /* 0, 0, 0, src[11], src[12], src[13], src[14], src[15] */ + asm volatile ( + "mov r2, $0 \n\t" + "mov r3, r2 \n\t" + "mov r4, r3 \n\t" + "stm %[d]!, {r2-r4} \n\t" + "add %[s], #44 \n\t" + "ldm %[s]!, {r2-r6} \n\t" + "stm %[d]!, {r2-r6} \n\t" + : /* out */ + [d] "+l" (dst), + [s] "+l" (src) + : /* in */ + : /* clobber list */ + "r2", "r3", "r4", "r5", "r6", "memory" + ); +} +__attribute__((always_inline)) static void +ecc_form_s2(uint32_t *dst, const uint32_t *src) +{ + /* 0, 0, 0, src[12], src[13], src[14], src[15], 0 */ + asm volatile ( + "mov r2, $0 \n\t" + "mov r3, r2 \n\t" + "mov r4, r3 \n\t" + "stm %[d]!, {r2-r4} \n\t" + "add %[s], #48 \n\t" + "ldm %[s]!, {r2-r5} \n\t" + "stm %[d]!, {r2-r5} \n\t" + "mov r2, $0 \n\t" + "stm %[d]!, {r2} \n\t" + : /* out */ + [d] "+l" (dst), + [s] "+l" (src) + : /* in */ + : /* clobber list */ + "r2", "r3", "r4", "r5", "memory" + ); +} +__attribute__((always_inline)) static void +ecc_form_s3(uint32_t *dst, const uint32_t *src) +{ + /* src[8], src[9], src[10], 0, 0, 0, src[14], src[15] */ + asm volatile ( + "add %[s], #32 \n\t" + "ldm %[s]!, {r2-r4} \n\t" + "mov r5, $0 \n\t" + "stm %[d]!, {r2-r5} \n\t" + "mov r2, r5 \n\t" + "mov r3, r2 \n\t" + "add %[s], #12 \n\t" + "ldm %[s]!, {r4,r5} \n\t" + "stm %[d]!, {r2-r5} \n\t" + : /* out */ + [d] "+l" (dst), + [s] "+l" (src) + : /* in */ + : /* clobber list */ + "r2", "r3", "r4", "r5", "memory" + ); +} +__attribute__((always_inline)) static void +ecc_form_s4(uint32_t *dst, const uint32_t *src) +{ + /* src[9], src[10], src[11], src[13], src[14], src[15], src[13], src[8] */ + asm volatile ( + "add %[s], #32 \n\t" + "ldm %[s]!, {r2-r5} \n\t" + "stm %[d]!, {r3-r5} \n\t" + "add %[s], #4 \n\t" + "ldm %[s]!, {r3-r5} \n\t" + "stm %[d]!, {r3-r5} \n\t" + "mov r4, r2 \n\t" + "stm %[d]!, {r3,r4} \n\t" + : /* out */ + [d] "+l" (dst), + [s] "+l" (src) + : /* in */ + : /* clobber list */ + "r2", "r3", "r4", "r5", "memory" + ); +} +__attribute__((always_inline)) static void +ecc_form_d1(uint32_t *dst, const uint32_t *src) +{ + /* src[11], src[12], src[13], 0, 0, 0, src[8], src[10] */ + asm volatile ( + "add %[s], #32 \n\t" + "ldm %[s]!, {r2-r7} \n\t" + "stm %[d]!, {r5-r7} \n\t" + "mov r3, $0 \n\t" + "mov r5, r3 \n\t" + "mov r6, r5 \n\t" + "stm %[d]!, {r3,r5,r6} \n\t" + "stm %[d]!, {r2,r4} \n\t" + : /* out */ + [d] "+l" (dst), + [s] "+l" (src) + : /* in */ + : /* clobber list */ + "r2", "r3", "r4", "r5", "r6", "r7", "memory" + ); +} +__attribute__((always_inline)) static void +ecc_form_d2(uint32_t *dst, const uint32_t *src) +{ + /* src[12], src[13], src[14], src[15], 0, 0, src[9], src[11] */ + asm volatile ( + "add %[s], #48 \n\t" + "ldm %[s]!, {r2-r5} \n\t" + "stm %[d]!, {r2-r5} \n\t" + "sub %[s], #28 \n\t" + "ldm %[s]!, {r4-r6} \n\t" + "mov r2, $0 \n\t" + "mov r3, r2 \n\t" + "stm %[d]!, {r2-r4,r6} \n\t" + : /* out */ + [d] "+l" (dst), + [s] "+l" (src) + : /* in */ + : /* clobber list */ + "r2", "r3", "r4", "r5", "r6", "memory" + ); +} +__attribute__((always_inline)) static void +ecc_form_d3(uint32_t *dst, const uint32_t *src) +{ + /* src[13], src[14], src[15], src[8], src[9], src[10], 0, src[12] */ + asm volatile ( + "add %[s], #52 \n\t" + "ldm %[s]!, {r2-r4} \n\t" + "stm %[d]!, {r2-r4} \n\t" + "sub %[s], #32 \n\t" + "ldm %[s]!, {r2-r6} \n\t" + "mov r5, $0 \n\t" + "stm %[d]!, {r2-r6} \n\t" + : /* out */ + [d] "+l" (dst), + [s] "+l" (src) + : /* in */ + : /* clobber list */ + "r2", "r3", "r4", "r5", "r6", "memory" + ); +} +__attribute__((always_inline)) static void +ecc_form_d4(uint32_t *dst, const uint32_t *src) +{ + /* src[14], src[15], 0, src[9], src[10], src[11], 0, src[13] */ + asm volatile ( + "add %[s], #56 \n\t" + "ldm %[s]!, {r2,r3} \n\t" + "mov r4, $0 \n\t" + "stm %[d]!, {r2-r4} \n\t" + "sub %[s], #28 \n\t" + "ldm %[s]!, {r2-r6} \n\t" + "mov r5, $0 \n\t" + "stm %[d]!, {r2-r6} \n\t" + : /* out */ + [d] "+l" (dst), + [s] "+l" (src) + : /* in */ + : /* clobber list */ + "r2", "r3", "r4", "r5", "r6", "memory" + ); +} +/*---------------------------------------------------------------------------*/ + +static void +ecc_field_Add(uint32_t *result, const uint32_t *x, const uint32_t *y) +{ + uint32_t temp[8]; + uint32_t carry = -ecc_add(result, x, y); + ecc_add(temp, result, ecc_prime_r); + + int i; + for(i = 0; i < 8; i++) { + result[i] ^= (carry & (result[i] ^ temp[i])); + } +} +static void +ecc_field_Sub(uint32_t *result, const uint32_t *x, const uint32_t *y) +{ + uint32_t temp[8]; + uint32_t carry = -ecc_sub(result, x, y); + ecc_add(temp, result, ecc_prime_m); + + int i; + for(i = 0; i < 8; i++) { + result[i] ^= (carry & (result[i] ^ temp[i])); + } +} +static void +ecc_field_ModP(uint32_t *result, const uint32_t *T) +{ + uint32_t SX_o_DX[8]; + ecc_copy(result, T); /* result = T */ + + ecc_form_s1(SX_o_DX, T); /* Form S1 */ + ecc_field_Add(result, result, SX_o_DX); /* result = T + S1 */ + ecc_field_Add(result, result, SX_o_DX); /* result = T + S1 + S1 */ + + ecc_form_s2(SX_o_DX, T); /* Form S2 */ + ecc_field_Add(result, result, SX_o_DX); /* result = T + S1 + S1 + S2 */ + ecc_field_Add(result, result, SX_o_DX); /* result = T + S1 + S1 + S2 + S2 */ + + ecc_form_s3(SX_o_DX, T); /* Form S3 */ + ecc_field_Add(result, result, SX_o_DX); /* result = T + S1 + S1 + S2 + S2 + S3 */ + + ecc_form_s4(SX_o_DX, T); /* Form S4 */ + ecc_field_Add(result, result, SX_o_DX); /* result = T + S1 + S1 + S2 + S2 + S3 + S4 */ + + ecc_form_d1(SX_o_DX, T); /* Form D1 */ + ecc_field_Sub(result, result, SX_o_DX); /* result = T + S1 + S1 + S2 + S2 + S3 + S4 - D1 */ + + ecc_form_d2(SX_o_DX, T); /* Form D2 */ + ecc_field_Sub(result, result, SX_o_DX); /* result = T + S1 + S1 + S2 + S2 + S3 + S4 - D1 - D2 */ + + ecc_form_d3(SX_o_DX, T); /* Form D3 */ + ecc_field_Sub(result, result, SX_o_DX); /* result = T + S1 + S1 + S2 + S2 + S3 + S4 - D1 - D2 - D3 */ + + ecc_form_d4(SX_o_DX, T); /* Form D4 */ + ecc_field_Sub(result, result, SX_o_DX); /* result = T + S1 + S1 + S2 + S2 + S3 + S4 - D1 - D2 - D3 - D4 */ + + if(ecc_compare(result, ecc_prime_m) >= 0) { + ecc_field_Sub(result, result, ecc_prime_m); + } +} +static void +ecc_field_Mult(uint32_t *result, const uint32_t *A, const uint32_t *B) +{ + uint32_t product[16]; + ecc_mult(product, A, B, 8); + ecc_field_ModP(result, product); +} +static void +ecc_field_Inv(uint32_t *result, const uint32_t *A) +{ + PRINTHEX("Input", A, 8); + + ecc_setZero(result); + result[0] = 0x00000001; + int i; + for(i = 255; i >= 0; --i) { + ecc_field_Mult(result, result, result); + if(((ecc_prime_m[i / 32] >> (i % 32)) & 0x1) == 1 && i != 1) { + ecc_field_Mult(result, result, A); + } + } + + PRINTHEX("Result", result, 8); +} +/*---------------------------------------------------------------------------*/ + +static void +ecc_projective_double(uint32_t *val) +{ + /* Algorithm taken from https://hyperelliptic.org/EFD/g1p/auto-shortw-projective-3.html#doubling-dbl-2007-bl-2 */ + /* w = 3*(X1-Z1)*(X1+Z1) */ + /* s = 2*Y1*Z1 */ + /* ss = s^2 */ + /* sss = s*ss */ + /* R = Y1*s */ + /* RR = R^2 */ + /* B = 2*X1*R */ + /* h = w^2-2*B */ + /* X3 = h*s */ + /* Y3 = w*(B-h)-2*RR */ + /* Z3 = sss */ + + uint32_t temp[24]; + uint32_t w[8]; + uint32_t s[8]; + uint32_t B[8]; + uint32_t h[8]; + + uint8_t is_zero = ecc_isX(val + X, 0) & ecc_isX(val + Y, 0) & ecc_isX(val + Z, 1); + + ecc_field_Sub(temp + X, val + X, val + Z); + ecc_field_Add(temp + Y, val + X, val + Z); + ecc_field_Mult(temp + Z, temp + X, temp + Y); + ecc_field_Add(temp + X, temp + Z, temp + Z); + ecc_field_Add(w, temp + Z, temp + X); + ecc_field_Mult(temp + X, val + Y, val + Z); + ecc_field_Add(s, temp + X, temp + X); + ecc_field_Mult(temp + X, s, s); + ecc_field_Mult(val + Z, s, temp + X); + ecc_field_Mult(temp + X, val + Y, s); /* temp = R */ + ecc_field_Mult(temp + Z, temp + X, temp + X); /* temp3 = RR */ + ecc_field_Mult(temp + Y, val + X, temp + X); /* temp2 = R*x */ + ecc_field_Add(B, temp + Y, temp + Y); /* B = 2*R*x */ + ecc_field_Mult(temp + X, w, w); + ecc_field_Add(temp + Y, B, B); + ecc_field_Sub(h, temp + X, temp + Y); + ecc_field_Mult(val + X, h, s); + ecc_field_Sub(temp + X, B, h); + ecc_field_Mult(temp + Y, w, temp + X); + ecc_field_Add(temp + Z, temp + Z, temp + Z); /* temp3 = 2*RR */ + ecc_field_Sub(val + Y, temp + Y, temp + Z); + /* finished, now swap the result if necessary */ + + ecc_setZero(temp + X); + ecc_setZero(temp + Y); + ecc_setZero(temp + Z); + (temp + Z)[0] = 0x00000001; + + ecc_replace(is_zero, val, temp); +} +static void +ecc_projective_add(uint32_t *result, const uint32_t *val_1, const uint32_t *x_2, const uint32_t *y_2, const uint32_t *z_2) +{ +/* algorithm taken from https://hyperelliptic.org/EFD/g1p/auto-shortw-projective-3.html#addition-add-1998-cmo-2 */ +/* X Z X Y U Y */ +/* 1 1 2 2 U UU V 1V */ +/* Z R Z ZVZ R UZZ VR ZY */ +/* VX 2RAY 2Z 1V1UA UZV V2A 2Z */ +/* Y1Z2 = Y1*Z2 | */ +/* X2Z1 = X2*Z1 | | */ +/* X1Z2 = X1*Z2 | | | */ +/* V = X2Z1-X1Z2 | x x | */ +/* VV = V^2 x | | | */ +/* R = VV*X1Z2 | x| x | */ +/* VVV = V*VV x | x | | */ +/* Y2Z1 = Y2*Z1 | | | | | */ +/* U = Y2Z1-Y1Z2 | | x| | x */ +/* UU = U^2 | | x | | | */ +/* Z1Z2 = Z1*Z2 | | | | | | | */ +/* UUZZ = UU*Z1Z2 | | x | x| | | */ +/* UZV = UUZZ-VVV | | | | x| x | */ +/* Z = VVV*Z1Z2 | | x| | | x | */ +/* VYZ = VVV*Y1Z2 | | | | | x x| */ +/* R2 = 2*R | x | | | | | */ +/* A = UZV-2R | | | | x x| | */ +/* X = V*A x| | | | x | */ +/* RA = R-A | x| | | x | */ +/* URA = U*RA | x | x| | */ +/* Y = URA-VYZ | | | x x */ + + uint32_t temp[32]; + #define X1 val_1 + X + #define Y1 val_1 + Y + #define Z1 val_1 + Z + #define X2 x_2 + #define Y2 y_2 + #define Z2 z_2 + #define V result + X + #define X1Z2 result + Y + #define R result + Y + #define RA result + Y + #define Z1Z2 result + Z + #define X2Z1 temp + X + #define VV temp + X + #define Y2Z1 temp + X + #define U temp + X + #define URA temp + X + #define UU temp + Y + #define UUZZ temp + Y + #define UZV temp + Y + #define VVV temp + Z + #define R2 temp + Z + #define A temp + Z + #define Y1Z2 temp + 24 + #define VYZ temp + 24 + + uint8_t is_input1_zero = ecc_isX(val_1 + X, 0) & ecc_isX(val_1 + Y, 0) & ecc_isX(val_1 + Z, 1); + uint8_t is_input2_zero = ecc_isX(x_2, 0) & ecc_isX(y_2, 0) & ecc_isX(z_2, 1); + + ecc_copy(temp + X, x_2); + ecc_copy(temp + Y, y_2); + ecc_copy(temp + Z, z_2); + ecc_replace(is_input1_zero, result, temp); + + ecc_copy(temp + X, val_1 + X); + ecc_copy(temp + Y, val_1 + Y); + ecc_copy(temp + Z, val_1 + Z); + ecc_replace(is_input2_zero, result, temp); + + /* invalidate the result pointer */ + result = (uint32_t *)((uintptr_t)result ^ (-(is_input2_zero | is_input1_zero) & ((uintptr_t)result ^ (uintptr_t)temp))); + + ecc_field_Mult(Y1Z2, Y1, Z2); + ecc_field_Mult(X2Z1, X2, Z1); + ecc_field_Mult(X1Z2, X1, Z2); + ecc_field_Sub(V, X2Z1, X1Z2); + ecc_field_Mult(VV, V, V); + ecc_field_Mult(R, VV, X1Z2); + ecc_field_Mult(VVV, V, VV); + ecc_field_Mult(Y2Z1, Y2, Z1); + ecc_field_Sub(U, Y2Z1, Y1Z2); + ecc_field_Mult(UU, U, U); + ecc_field_Mult(Z1Z2, Z1, Z2); + ecc_field_Mult(UUZZ, UU, Z1Z2); + ecc_field_Sub(UZV, UUZZ, VVV); + ecc_field_Mult(result + Z, VVV, Z1Z2); + ecc_field_Mult(VYZ, VVV, Y1Z2); + ecc_field_Add(R2, R, R); + ecc_field_Sub(A, UZV, R2); + ecc_field_Mult(result + X, V, A); + ecc_field_Sub(RA, R, A); + ecc_field_Mult(URA, U, RA); + ecc_field_Sub(result + Y, URA, VYZ); +} +/*---------------------------------------------------------------------------*/ + +#if SELF_TEST +static void +assertTrue(uint32_t value, const char *msg) +{ + if(!value) { + printf("%s\n", msg); + } +} +static void +assertFalse(uint32_t value, const char *msg) +{ + if(value) { + printf("%s\n", msg); + } +} +static void +assertSame(uint32_t *val_1, uint32_t *val_2, const char *msg) +{ + if(ecc_compare(val_1, val_2)) { + printf("%s\n", msg); + } +} +static void +selfTest() +{ + uint32_t num_000[8] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; + uint32_t num_001[8] = { 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; + uint32_t num_002[8] = { 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; + uint32_t num_004[8] = { 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; + uint32_t num_max[8] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; + uint32_t primeMinusOne[8] = { 0xfffffffe, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0xffffffff }; + + uint32_t result[8]; + + /* ecc_compare */ + assertFalse(ecc_compare(num_001, num_001), "ecc_compare 1: Wrong result!"); + assertTrue(ecc_compare(num_000, num_001) == -1, "ecc_compare 2: Wrong result!"); + assertTrue(ecc_compare(num_001, num_000) == 1, "ecc_compare 3: Wrong result!"); + + /* ecc_isX */ + assertTrue(ecc_isX(num_000, 0), "ecc_isX 1: Wrong result!"); + assertTrue(ecc_isX(num_001, 1), "ecc_isX 2: Wrong result!"); + assertTrue(ecc_isX(num_002, 2), "ecc_isX 3: Wrong result!"); + assertTrue(ecc_isX(num_004, 4), "ecc_isX 4: Wrong result!"); + assertFalse(ecc_isX(num_000, 1), "ecc_isX 5: Wrong result!"); + assertFalse(ecc_isX(num_000, 2), "ecc_isX 6: Wrong result!"); + assertFalse(ecc_isX(num_000, 4), "ecc_isX 7: Wrong result!"); + assertFalse(ecc_isX(num_001, 0), "ecc_isX 8: Wrong result!"); + assertFalse(ecc_isX(num_001, 2), "ecc_isX 9: Wrong result!"); + assertFalse(ecc_isX(num_001, 4), "ecc_isX 10: Wrong result!"); + assertFalse(ecc_isX(num_002, 0), "ecc_isX 11: Wrong result!"); + assertFalse(ecc_isX(num_002, 1), "ecc_isX 12: Wrong result!"); + assertFalse(ecc_isX(num_002, 4), "ecc_isX 13: Wrong result!"); + assertFalse(ecc_isX(num_004, 0), "ecc_isX 14: Wrong result!"); + assertFalse(ecc_isX(num_004, 1), "ecc_isX 15: Wrong result!"); + assertFalse(ecc_isX(num_004, 2), "ecc_isX 16: Wrong result!"); + + /* ecc_add */ + assertFalse(ecc_add(result, num_001, num_002), "ecc_add 1: Unexpected carrybit!"); + assertFalse(ecc_add(result, result, num_001), "ecc_add 2: Unexpected carrybit!"); + assertSame(result, num_004, "ecc_add 3: Wrong result!"); + assertTrue(ecc_add(result, num_max, num_002), "ecc_add 4: Carrybit missing!"); + assertSame(result, num_001, "ecc_add 5: Wrong result!"); + + /* ecc_sub */ + assertFalse(ecc_sub(result, num_004, num_002), "ecc_sub 1: Unexpected carrybit!"); + assertFalse(ecc_sub(result, result, num_001), "ecc_sub 2: Unexpected carrybit!"); + assertFalse(ecc_sub(result, result, num_001), "ecc_sub 3: Unexpected carrybit!"); + assertSame(result, num_000, "ecc_sub 4: Wrong result!"); + assertTrue(ecc_sub(result, num_000, num_001), "ecc_sub 5: Carrybit missing!"); + assertSame(result, num_max, "ecc_sub 6: Wrong result!"); + + /* ecc_field_Sub */ + ecc_field_Sub(result, num_001, num_000); + assertSame(num_001, result, "ecc_field_Sub 1: Wrong result!"); + ecc_field_Sub(result, num_001, num_001); + assertSame(num_000, result, "ecc_field_Sub 2: Wrong result!"); + ecc_field_Sub(result, num_000, num_001); + assertSame(primeMinusOne, result, "ecc_field_Sub 3: Wrong result!"); + + printf("Tests completed!\n"); +} +#endif diff --git a/platform/econotag/apps/ecc/ecc.h b/platform/econotag/apps/ecc/ecc.h new file mode 100644 index 000000000..b90b55260 --- /dev/null +++ b/platform/econotag/apps/ecc/ecc.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015, Lars Schmertmann , + * Jens Trillmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Calculations on elliptic curve secp256r1 + * + * This is a efficient ECC implementation on the secp256r1 curve for + * 32 Bit CPU architectures. It provides basic operations on the + * secp256r1 curve and support for ECDH and ECDSA. + * + * \author + * Lars Schmertmann + * Jens Trillmann + */ + +#ifndef ECC_H_ +#define ECC_H_ + +#include + +/** + * \brief Checks if a (random) number is valid as scalar on elliptic curve secp256r1 + * + * A (random) number is only usable as scalar on elliptic curve secp256r1 if + * it is lower than the order of the curve. For the check, you need to provide + * the order of elliptic curve secp256r1. + * + * uint32_t order[8] = {0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF}; + * + * \param key The (random) number to check for usability + * \param order The order of elliptic curve secp256r1 + * + * \return 1 if key is valid + */ +#define ecc_is_valid_key(key, order) (ecc_compare(order, key) == 1) + +/** + * \brief Compares the value of a with the value of b + * + * This function is only public because its needed for the macro ecc_is_valid_key. + * It does a comparison of two 256 bit numbers. The return values are 1, 0 or -1. + * + * \param a First number + * \param b Second number + * + * \return 1 if a is greater than b + 0 if a is equal to b + -1 if a is less than b + */ +int32_t ecc_compare(const uint32_t *a, const uint32_t *b); + +/** + * \brief ECC scalar multiplication on elliptic curve secp256r1 + * + * This function does a scalar multiplication on elliptic curve secp256r1. + * For an Elliptic curve Diffie–Hellman you need two multiplications. First one + * with the base point of elliptic curve secp256r1 you need to provide. + * + * uint32_t base_x[8] = {0xd898c296, 0xf4a13945, 0x2deb33a0, 0x77037d81, 0x63a440f2, 0xf8bce6e5, 0xe12c4247, 0x6b17d1f2}; + * uint32_t base_y[8] = {0x37bf51f5, 0xcbb64068, 0x6b315ece, 0x2bce3357, 0x7c0f9e16, 0x8ee7eb4a, 0xfe1a7f9b, 0x4fe342e2}; + * + * \param resultx Pointer to memory to store the x-coordinate of the result + * \param resulty Pointer to memory to store the y-coordinate of the result + * \param px x-coordinate of the point to multiply with scalar + * \param py y-coordinate of the point to multiply with scalar + * \param secret Scalar for multiplication with elliptic curve point + */ +void ecc_ec_mult(uint32_t *resultx, uint32_t *resulty, const uint32_t *px, const uint32_t *py, const uint32_t *secret); + +#endif /* ECC_H_ */ diff --git a/platform/econotag/apps/flash/Makefile.flash b/platform/econotag/apps/flash/Makefile.flash new file mode 100644 index 000000000..d78891b5c --- /dev/null +++ b/platform/econotag/apps/flash/Makefile.flash @@ -0,0 +1 @@ +flash_src = flash.c diff --git a/platform/econotag/apps/flash/flash.c b/platform/econotag/apps/flash/flash.c new file mode 100644 index 000000000..959724697 --- /dev/null +++ b/platform/econotag/apps/flash/flash.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ + +#include "flash.h" + +#define FLASH_BLOCK_SIZE 0x01000 + +#define FLASH_BLOCK_11 0x18000 +#define FLASH_BLOCK_21 0x1A000 + +#ifndef FLASH_CONF_B1 +#define FLASH_CONF_B1 FLASH_BLOCK_SIZE +#endif + +#ifndef FLASH_CONF_B2 +#define FLASH_CONF_B2 FLASH_BLOCK_SIZE +#endif + +#define DEBUG 0 + +#if DEBUG +#include +#include "mc1322x.h" +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +uint16_t stackPointer; + +/* private prototypes ----------------------------------------------------- */ + +flash_addr_t getAddr(flash_addr_t address); + +/* public functions -------------------------------------------------------- */ + +void +flash_init() +{ + PRINTF("Initializing flash ... "); + + nvm_erase(gNvmInternalInterface_c, gNvmType_SST_c, 0x0F000000); + + nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, "\001", FLASH_BLOCK_11, 1); + nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, "\001", FLASH_BLOCK_21, 1); + + uint32_t i; + for(i = 1; i < 0x2000; i++) { +#if DEBUG + if(i % 0x400 == 0) { + PRINTF(" ."); + } +#endif + nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, "\0", FLASH_BLOCK_11 + i, 1); + nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, "\0", FLASH_BLOCK_21 + i, 1); + } + + PRINTF("DONE\n"); +} +nvmErr_t +flash_getVar(void *dest, flash_addr_t address, uint32_t numBytes) +{ + address = getAddr(address); + + if(address >= 0x18000 && address <= 0x1EFFF) { + PRINTF("Read from Adress: %p\n", address); + nvmErr_t err = nvm_read(gNvmInternalInterface_c, gNvmType_SST_c, dest, address, numBytes); + if(err) { + PRINTF("Read error, nmv_error: %u\n", err); + return err; + } + return gNvmErrNoError_c; + } + + PRINTF("Read error - Invalid pointer.\n"); + return gNvmErrInvalidPointer_c; +} +nvmErr_t +flash_setVar(void *src, flash_addr_t address, uint32_t numBytes) +{ +#if DEBUG + printf("SetVar - START . "); + uint32_t time = *MACA_CLK; +#endif + + if(address >= 8192) { + PRINTF("Write error - Invalid pointer.\n"); + return gNvmErrInvalidPointer_c; + } + uint32_t block_len = (address < 4096 ? FLASH_CONF_B1 : FLASH_CONF_B2); + + address = getAddr(address); + + flash_addr_t src_block = address & 0xFF000; + flash_addr_t dst_block = src_block ^ 0x01000; + address = address & 0x00FFF; + + if(address < 1 || address >= block_len) { + PRINTF("Write error - Invalid pointer.\n"); + return gNvmErrInvalidPointer_c; + } + if(address + numBytes > block_len) { + PRINTF("Write error - Var is to long.\n"); + return gNvmErrAddressSpaceOverflow_c; + } + + nvm_erase(gNvmInternalInterface_c, gNvmType_SST_c, 1 << (dst_block / FLASH_BLOCK_SIZE)); + + uint32_t i; + uint8_t buf; + for(i = 0; i < address; i++) { + nvm_read(gNvmInternalInterface_c, gNvmType_SST_c, &buf, src_block + i, 1); + nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, &buf, dst_block + i, 1); + } + PRINTF("Write to adress: %p\n", dst_block + i); + nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, src, dst_block + i, numBytes); + for(i += numBytes; i < block_len; i++) { + nvm_read(gNvmInternalInterface_c, gNvmType_SST_c, &buf, src_block + i, 1); + nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, &buf, dst_block + i, 1); + } + + nvm_erase(gNvmInternalInterface_c, gNvmType_SST_c, 1 << (src_block / FLASH_BLOCK_SIZE)); + +#if DEBUG + time = *MACA_CLK - time; + printf("FINISHED AFTER %u MS\n", time / 250); +#endif + + return gNvmErrNoError_c; +} +nvmErr_t +flash_cmp(void *src, flash_addr_t address, uint32_t numBytes) +{ + address = getAddr(address); + + if(address >= 0x18000 && address <= 0x1EFFF) { + return nvm_verify(gNvmInternalInterface_c, gNvmType_SST_c, src, address, numBytes); + } + PRINTF("Read error - Invalid pointer.\n"); + return gNvmErrInvalidPointer_c; +} +void +flash_stack_init() +{ + stackPointer = 0; + nvm_erase(gNvmInternalInterface_c, gNvmType_SST_c, 1 << (FLASH_STACK / FLASH_BLOCK_SIZE)); +} +nvmErr_t +flash_stack_push(uint8_t *src, uint32_t numBytes) +{ + if(stackPointer + numBytes > FLASH_BLOCK_SIZE) { + return gNvmErrAddressSpaceOverflow_c; + } + + nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, src, FLASH_STACK + stackPointer, numBytes); + stackPointer += numBytes; + return gNvmErrNoError_c; +} +uint32_t +flash_stack_size() +{ + return stackPointer; +} +/* private functions ------------------------------------------------------- */ + +flash_addr_t +getAddr(flash_addr_t address) +{ + if(address >= 0x02000) { + return address; + } + + flash_addr_t block = (address & 0x01000 ? FLASH_BLOCK_21 : FLASH_BLOCK_11); + uint8_t blockcheck = (flash_cmp("\001", block, 1) == 0 ? 0 : 1); + return block + (blockcheck << 12) + (address & 0x00FFF); +} diff --git a/platform/econotag/apps/flash/flash.h b/platform/econotag/apps/flash/flash.h new file mode 100644 index 000000000..a50bddc80 --- /dev/null +++ b/platform/econotag/apps/flash/flash.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * App for easy usage of additional flash memory + * + * Purposes of the different flash blocks + * 1 : 0x18000 - 0x18FFF : Random access block 1.1 + * 2 : 0x19000 - 0x19FFF : Random access block 1.2 + * 3 : 0x1A000 - 0x1AFFF : Random access block 2.1 + * 4 : 0x1B000 - 0x1BFFF : Random access block 2.2 + * 5 : 0x1C000 - 0x1CFFF : Stack without pop function + * 6 : 0x1D000 - 0x1DFFF : Read only + * 7 : 0x1E000 - 0x1EFFF : Read only + * 8 : 0x1F000 - 0x1FFFF : System reserved + * + * This app only allows write access to blocks 1 - 5 + * and read access to blocks 1 - 7. + * + * To use the stack in block 5 you need: flash_stack_init, + * flash_stack_push, flash_stack_size, flash_stack_read. + * + * To use the random access blocks 1.x and 2.x you need: flash_init, + * flash_getVar, flash_setVar, flash_cmp. + * + * Blocks 1.x and 2.x are accessible with adresses + * 0x0001 - 0x0FFF and 0x1001 - 0x1FFF. + * + * To be able to write to flash memory, its required to delete + * it first, but its only possible to delete a full block. So this + * app copies the data of a block, changing the requested data. + * Copying a block needs time. So when you only use the first N bytes, + * you can set FLASH_CONF_B1=N and FLASH_CONF_B2=N in your makefile + * to optimize speed. + * + * You can find an example in examples/econotag-flash-test. + * + * \author + * Lars Schmertmann + */ + +#ifndef FLASH_H_ +#define FLASH_H_ + +#include + +#define FLASH_STACK 0x1C000 + +typedef uint32_t flash_addr_t; + +/** + * \brief Initialize or clear random access blocks + * + * To use the random access blocks, you need to call this + * function first. You can also use it to delete all data + * in this blocks. + */ +void flash_init(); + +/** + * \brief Read data from flash memory + * + * Reads data from flash memory and stores it into RAM. + * You can read the flash area 0x18000 - 0x1EFFF. Addresses + * 0x0000 - 0x1FFF will be mapped to 0x18000 - 0x1BFFF. + * + * \param dest Memory area to store the data + * \param address Area in flash memory to read from + * \param numBytes Number of bytes to read + * + * \return gNvmErrNoError_c (0) if read was successfull + */ +nvmErr_t flash_getVar(void *dest, flash_addr_t address, uint32_t numBytes); + +/** + * \brief Write data to flash memory + * + * Writes data to flash memory. Valid addresses are + * 0x0001 - 0x0FFF and 0x1001 - 0x1FFF -> Mapped to + * 0x18000 - 0x1BFFF. + * + * \param src Memory area with data to store in flash memory + * \param address Area in flash memory to write + * \param numBytes Number of bytes to write + * + * \return gNvmErrNoError_c (0) if write was successfull + */ +nvmErr_t flash_setVar(void *src, flash_addr_t address, uint32_t numBytes); + +/** + * \brief Compares data from RAM with flash memory + * + * Compares data from RAM with flash memory. + * Valid addresses are 0x18000 - 0x1EFFF. Addresses + * 0x0 - 0x1FFF will be mapped to 0x18000 - 0x1BFFF. + * + * \param src Memory area with data to compare + * \param address Area in flash memory + * \param numBytes Number of bytes to compare + * + * \return 0 if data is matching + */ +nvmErr_t flash_cmp(void *src, flash_addr_t address, uint32_t numBytes); + +/** + * \brief Stack initialisation + * + * Clears and initializes the stack. + */ +void flash_stack_init(); + +/** + * \brief Push data to stack + * + * Pushes numBytes from src to stack into flash memory. + * + * \param src Memory area with data to store in flash memory + * \param numBytes Number of bytes to write + * + * \return gNvmErrNoError_c (0) if push was successfull + */ +nvmErr_t flash_stack_push(uint8_t *src, uint32_t numBytes); + +/** + * \brief Stacksize + * + * Returns the size of data in stack + * + * \return Number of bytes in stack + */ +uint32_t flash_stack_size(); + +/** + * \brief Read data from stack + * + * Reads data from stack (without removing it) and stores it into RAM. + * + * \param dest Memory area to store the data + * \param offset Position in stack to read from + * \param numBytes Number of bytes to read + * + * \return gNvmErrNoError_c (0) if read was successfull + */ +#define flash_stack_read(dest, offset, numBytes) flash_getVar(dest, FLASH_STACK + (offset), numBytes) + +#endif /* FLASH_H_ */ diff --git a/platform/econotag/button-sensor.c b/platform/econotag/button-sensor.c index f89cd6544..cbd1e0fd8 100644 --- a/platform/econotag/button-sensor.c +++ b/platform/econotag/button-sensor.c @@ -68,6 +68,8 @@ configure(int type, int c) if(!status(SENSORS_ACTIVE)) { timer_set(&debouncetimer, 0); enable_irq_kbi(4); + kbi_edge(4); + enable_ext_wu(4); } } else { disable_irq_kbi(4); diff --git a/platform/econotag/button-sensor2.c b/platform/econotag/button-sensor2.c new file mode 100644 index 000000000..6552a94cb --- /dev/null +++ b/platform/econotag/button-sensor2.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2010, Mariano Alvira and other contributors + * to the MC1322x project (http://mc1322x.devl.org) and Contiki. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki OS. + * + * $Id: button-sensor.c,v 1.1 2010/06/09 14:46:30 maralvira Exp $ + */ + +#include "lib/sensors.h" +#include "dev/button-sensor.h" + +#include "mc1322x.h" + +#include + +const struct sensors_sensor button_sensor2; + +static struct timer debouncetimer; +static int status(int type); + +void kbi5_isr(void) { + if(timer_expired(&debouncetimer)) { + timer_set(&debouncetimer, CLOCK_SECOND / 4); + sensors_changed(&button_sensor2); + } + clear_kbi_evnt(5); +} + +static int +value(int type) +{ + return GPIO->DATA.GPIO_27 || !timer_expired(&debouncetimer); +} + +static int +configure(int type, int c) +{ + switch (type) { + case SENSORS_ACTIVE: + if (c) { + if(!status(SENSORS_ACTIVE)) { + timer_set(&debouncetimer, 0); + enable_irq_kbi(5); + kbi_edge(5); + enable_ext_wu(5); + } + } else { + disable_irq_kbi(5); + } + return 1; + } + return 0; +} + +static int +status(int type) +{ + switch (type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return bit_is_set(*CRM_WU_CNTL, 21); /* check if kbi5 irq is enabled */ + } + return 0; +} + +SENSORS_SENSOR(button_sensor2, BUTTON_SENSOR, + value, configure, status); diff --git a/platform/econotag/contiki-conf.h b/platform/econotag/contiki-conf.h index 45968d401..2b29867ef 100644 --- a/platform/econotag/contiki-conf.h +++ b/platform/econotag/contiki-conf.h @@ -108,7 +108,7 @@ #define LINKADDR_CONF_SIZE 8 -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 /* Network setup for IPv6 */ #define NETSTACK_CONF_NETWORK sicslowpan_driver #define NETSTACK_CONF_MAC nullmac_driver @@ -121,7 +121,7 @@ #define CXMAC_CONF_ANNOUNCEMENTS 0 #define XMAC_CONF_ANNOUNCEMENTS 0 -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ /* Network setup for non-IPv6 (rime). */ #define NETSTACK_CONF_NETWORK rime_driver @@ -144,7 +144,7 @@ #define COLLECT_NBR_TABLE_CONF_MAX_NEIGHBORS 32 -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define QUEUEBUF_CONF_NUM 16 @@ -169,7 +169,7 @@ #define PROCESS_CONF_NUMEVENTS 8 #define PROCESS_CONF_STATS 1 -#ifdef WITH_UIP6 +#ifdef NETSTACK_CONF_WITH_IPV6 #define LINKADDR_CONF_SIZE 8 @@ -180,10 +180,6 @@ #define UIP_CONF_ROUTER 1 #endif -#ifndef UIP_CONF_IPV6_RPL -#define UIP_CONF_IPV6_RPL 1 -#endif - #define NBR_TABLE_CONF_MAX_NEIGHBORS 30 #define UIP_CONF_MAX_ROUTES 30 @@ -191,32 +187,26 @@ #define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_RETRANS_TIMER 10000 -#define UIP_CONF_IPV6 1 +#define NETSTACK_CONF_WITH_IPV6 1 #define UIP_CONF_IPV6_QUEUE_PKT 0 #define UIP_CONF_IPV6_CHECKS 1 #define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_NETIF_MAX_ADDRESSES 3 -#define UIP_CONF_ND6_MAX_PREFIXES 3 -#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_IP_FORWARD 0 #define UIP_CONF_BUFFER_SIZE 1300 #define SICSLOWPAN_CONF_FRAG 1 #define SICSLOWPAN_CONF_MAXAGE 8 -#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 -#define SICSLOWPAN_CONF_COMPRESSION_HC1 1 -#define SICSLOWPAN_CONF_COMPRESSION_HC01 2 #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #ifndef SICSLOWPAN_CONF_FRAG #define SICSLOWPAN_CONF_FRAG 1 #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ -#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_IP_FORWARD 1 #define UIP_CONF_BUFFER_SIZE 1300 -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_ICMP_DEST_UNREACH 1 diff --git a/platform/econotag/main.c b/platform/econotag/main.c index 2f8cc27b1..55b9737c8 100644 --- a/platform/econotag/main.c +++ b/platform/econotag/main.c @@ -50,7 +50,9 @@ /* econotag */ #include "platform_prints.h" -SENSORS(&button_sensor); +#ifndef OWN_SENSORS_DEFINITION +SENSORS(&button_sensor, &button_sensor2); +#endif #ifndef M12_CONF_SERIAL #define M12_SERIAL 0x000000 @@ -122,7 +124,7 @@ int main(void) { /* configure address on maca hardware and RIME */ contiki_maca_set_mac_address(mc1322x_config.eui); -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(&uip_lladdr.addr, &linkaddr_node_addr.u8, sizeof(uip_lladdr.addr)); queuebuf_init(); NETSTACK_RDC.init(); @@ -135,7 +137,7 @@ int main(void) { #if DEBUG_ANNOTATE print_lladdrs(); #endif -#endif /* endif WITH_UIP6 */ +#endif /* endif NETSTACK_CONF_WITH_IPV6 */ process_start(&sensors_process, NULL); diff --git a/platform/ev-aducrf101mkxz/Makefile.ev-aducrf101mkxz b/platform/ev-aducrf101mkxz/Makefile.ev-aducrf101mkxz new file mode 100644 index 000000000..6e5246e85 --- /dev/null +++ b/platform/ev-aducrf101mkxz/Makefile.ev-aducrf101mkxz @@ -0,0 +1,57 @@ +# -*- makefile -*- + +# Copyright (c) 2014, Analog Devices, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted (subject to the limitations in the +# disclaimer below) 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 Analog Devices, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE +# GRANTED BY THIS LICENSE. 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 OWNER 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. + +# Author: Jim Paris + +CONTIKI_TARGET_DIRS = . +CONTIKI_CORE = contiki-main +CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o + +CONTIKI_TARGET_SOURCEFILES += $(ARCH) +CONTIKI_TARGET_SOURCEFILES += contiki-main.c +CONTIKI_TARGET_SOURCEFILES += slip.c +CONTIKI_TARGET_SOURCEFILES += button-sensor.c +CONTIKI_TARGET_SOURCEFILES += leds-arch.c + +CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) + +CONTIKI_PLAT_DEFS = + +include $(CONTIKI)/cpu/arm/aducrf101/Makefile.aducrf101 + +MODULES += \ + core/net \ + core/net/mac \ + core/net/mac/sicslowmac \ + core/net/llsec diff --git a/platform/ev-aducrf101mkxz/README.md b/platform/ev-aducrf101mkxz/README.md new file mode 100644 index 000000000..5dd7c5b06 --- /dev/null +++ b/platform/ev-aducrf101mkxz/README.md @@ -0,0 +1,159 @@ +Building Contiki for the EV-ADuCRF101MKxZ Board +=============================================== + +On Debian/Ubuntu Linux: +----------------------- + +For older versions of Ubuntu (prior to 14.04), add the external +package repository that provides recent versions of GCC for ARM: + + sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded + sudo apt-get update + +For all systems, install the required development packages: + + sudo apt-get install git make gcc-arm-none-eabi python-serial + +Obtain the Contiki source code: + + git clone https://github.com/contiki-os/contiki.git + +Build Contiki's `example-abc`: + + make -C contiki/examples/rime \ + TARGET=ev-aducrf101mkxz \ + example-abc.ev-aducrf101mkxz.hex + +The default radio frequency can optionally be specified on the +command-line as follows. A clean rebuild may be needed when changing +it: + + make -C contiki/examples/rime \ + TARGET=ev-aducrf101mkxz \ + RF_CHANNEL=915000000 \ + clean \ + example-abc.ev-aducrf101mkxz.hex + +The code can be flashed to the eval board and tested using +[adi-cm3sd](https://github.com/jimparis/adi-cm3sd.git). Obtain +`adi-cm3sd`: + + git clone https://github.com/jimparis/adi-cm3sd.git + +Connect the evaluation board using its J-Link board, or any other +serial adapter. Flash `example-adc` and open a terminal by running: + + adi-cm3sd/cm3sd.py -a contiki/examples/rime/example-abc.ev-aducrf101mkxz.hex \ + /dev/serial/by-id/usb-SEGGER_J-Link_000541011111-if00 + +replacing `/dev/serial/by-id/usb-SEGGER_J-Link_000541011111-if00` with +the path to the correct serial device. Flash the same code on a +second evaluation board to see them communicate. + +### IPv6 Example ### + +#### Border Router #### + +First, build and run the IPv6 `border-router` example: + + make -C contiki/examples/ipv6/rpl-border-router \ + TARGET=ev-aducrf101mkxz \ + SERIAL_ID='"00001234"' \ + border-router.ev-aducrf101mkxz.hex + + adi-cm3sd/cm3sd.py -a contiki/examples/ipv6/rpl-border-router/border-router.ev-aducrf101mkxz.hex \ + /dev/serial/by-id/usb-SEGGER_J-Link_000541011111-if00 + +After flashing, close the terminal with `CTRL-C`, then build and run +the SLIP tunnel on the host machine: + + make -C contiki/tools tunslip6 + + sudo contiki/tools/tunslip6 \ + -s /dev/serial/by-id/usb-SEGGER_J-Link_000541011111-if00 \ + -B 115200 -v3 fd00::1/64 + +Open the border router's home page at: http://[fd00::3230:3030:3132:3334]/ + +#### Web Server #### + +Then, build and flash the IPv6 `webserver6` example on another eval +board. The different `SERIAL_ID` ensures that the webserver uses a +link-local IP address that is different from that of the border +router: + + make -C contiki/examples/webserver-ipv6 \ + TARGET=ev-aducrf101mkxz \ + SERIAL_ID='"00005678"' \ + webserver6.ev-aducrf101mkxz.hex + + adi-cm3sd/cm3sd.py -a contiki/examples/webserver-ipv6/webserver6.ev-aducrf101mkxz.hex \ + /dev/serial/by-id/usb-SEGGER_J-Link_000541022222-if00 + +Open the web server's home page at: http://[fd00::3230:3030:3536:3738]/ + +On Windows: +----------- + +### Install prerequisites ### + +Install [git](http://git-scm.com/download/win/) with default options. + +Install MinGW as follows: + +* Download and run [mingw-get-setup.exe](https://sourceforge.net/projects/mingw/files/latest/download). +* Select `Install`, `Continue`, and `Continue` again. +* Click `Basic Setup` on the left panel. +* Click the checkbox next to `mingw32-base`, then click `Mark for Installation`. +* Select 'Installation -> Apply Changes' from the menu bar. +* Click 'Apply', then close and quit the MinGW installer. + +### Install toolchain ### + +Contiki can be built with either GCC or IAR: + +* **GCC**: Install + [GNU Tools for ARM Embedded Processors](https://launchpad.net/gcc-arm-embedded/+download). + Use the "Windows installer" version. Ensure that "Add path to + environment variable" is selected in the installer. + +* **IAR**: Install + [IAR Embedded Workbench](http://www.iar.com/ewarm/). + +### Building `example-abc` ### + +Open a shell by right-clicking the desktop or any folder and +selecting `Git Bash`. + +Obtain the Contiki source code: + + git clone https://github.com/contiki-os/contiki.git + +Build Contiki's `example-abc`: + +* **GCC** + + /c/mingw/bin/mingw32-make -C contiki/examples/rime \ + TARGET=ev-aducrf101mkxz \ + example-abc.ev-aducrf101mkxz.hex + +* **IAR** + + /c/mingw/bin/mingw32-make -C contiki/examples/rime \ + IAR=1 \ + TARGET=ev-aducrf101mkxz \ + example-abc.ev-aducrf101mkxz.hex + +Other build options like `RF_CHANNEL` and `SERIAL_ID` can be specified +as in the Linux instructions above. + +### Flashing and running ### + +The resulting file +`contiki/examples/rime/example-abc.ev-aducrf101mkxz.hex` can be +flashed to the evaluation board using ADI's +[CM3WSD](http://www.analog.com/static/imported-files/eval_boards/CM3WSD.zip) +utility. + +Use a terminal emulator (e.g. HyperTerminal) at 115200 baud to see the +program output. diff --git a/platform/ev-aducrf101mkxz/button-sensor.c b/platform/ev-aducrf101mkxz/button-sensor.c new file mode 100644 index 000000000..1e43e6fdf --- /dev/null +++ b/platform/ev-aducrf101mkxz/button-sensor.c @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + * \author Jim Paris + */ + +#include "lib/sensors.h" +#include "dev/button-sensor.h" +#include "platform-conf.h" + +#include + +const struct sensors_sensor button_sensor; +static struct timer debouncetimer; + +/* e.g. pADI_GP0 */ +#define GPIO CC_CONCAT(pADI_GP, BUTTON_GPIO) + +/* e.g. Ext_Int2_Handler */ +#define HANDLER CC_CONCAT(CC_CONCAT(Ext_Int, BUTTON_INT), _Handler) + +/* e.g. EINT2_IRQn */ +#define IRQN CC_CONCAT(CC_CONCAT(EINT, BUTTON_INT), _IRQn) + +void +HANDLER(void) +{ + pADI_INTERRUPT->EICLR = (1 << BUTTON_INT); + if(!timer_expired(&debouncetimer)) { + return; + } + timer_set(&debouncetimer, CLOCK_SECOND / 8); + sensors_changed(&button_sensor); +} +static int +config(int type, int c) +{ + switch(type) { + case SENSORS_HW_INIT: + timer_set(&debouncetimer, 0); + return 1; + case SENSORS_ACTIVE: + /* Set button as a GPIO input with pullup */ + GPIO->GPCON &= ~(3UL << (BUTTON_PIN * 2)); + GPIO->GPOEN &= ~(1UL << BUTTON_PIN); + GPIO->GPPUL |= (1UL << BUTTON_PIN); + + /* Enable interrupt for the button (rise and fall) */ +#if BUTTON_INT <= 3 + pADI_INTERRUPT->EI0CFG |= (0xaUL << (4 * (BUTTON_INT - 0))); +#elif BUTTON_INT <= 7 + pADI_INTERRUPT->EI1CFG |= (0xaUL << (4 * (BUTTON_INT - 4))); +#endif + pADI_INTERRUPT->EICLR = (1 << BUTTON_INT); + NVIC_EnableIRQ(IRQN); + return 1; + } + return 0; +} +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + if(GPIO->GPIN & (1UL << BUTTON_PIN)) { + return 1; + } + return 0; + } + return 0; +} +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, NULL, config, status); diff --git a/platform/ev-aducrf101mkxz/contiki-conf.h b/platform/ev-aducrf101mkxz/contiki-conf.h new file mode 100644 index 000000000..673a358ab --- /dev/null +++ b/platform/ev-aducrf101mkxz/contiki-conf.h @@ -0,0 +1,182 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + * \author Jim Paris + */ + +#ifndef __CONTIKI_CONF_H__ +#define __CONTIKI_CONF_H__ + +#include + +#include "aducrf101-contiki.h" +#include "platform-conf.h" + +/* Clock ticks per second */ +#define CLOCK_CONF_SECOND 1000 + +#define CCIF +#define CLIF + +/* start of conitki config. */ +#define PLATFORM_HAS_LEDS 1 +#define PLATFORM_HAS_BUTTON 1 + +#define LINKADDR_CONF_SIZE 8 + +#if NETSTACK_CONF_WITH_IPV6 +/* Network setup for IPv6 */ +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#define NETSTACK_CONF_MAC nullmac_driver +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_RADIO aducrf101_radio_driver +#define NETSTACK_CONF_FRAMER framer_802154 + +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 +#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 +#define CXMAC_CONF_ANNOUNCEMENTS 0 +#define XMAC_CONF_ANNOUNCEMENTS 0 + +#else /* NETSTACK_CONF_WITH_IPV6 */ + +/* Network setup for non-IPv6 (rime). */ +#define NETSTACK_CONF_NETWORK rime_driver +#define NETSTACK_CONF_MAC csma_driver +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_RADIO aducrf101_radio_driver +#define NETSTACK_CONF_FRAMER framer_802154 + +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 + +#define COLLECT_CONF_ANNOUNCEMENTS 1 +#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 +#define CXMAC_CONF_ANNOUNCEMENTS 0 +#define XMAC_CONF_ANNOUNCEMENTS 0 +#define CONTIKIMAC_CONF_ANNOUNCEMENTS 0 + +#define CONTIKIMAC_CONF_COMPOWER 0 +#define XMAC_CONF_COMPOWER 0 +#define CXMAC_CONF_COMPOWER 0 + +#define COLLECT_NBR_TABLE_CONF_MAX_NEIGHBORS 16 + +#endif /* NETSTACK_CONF_WITH_IPV6 */ + +#define QUEUEBUF_CONF_NUM 4 + +#define PACKETBUF_CONF_ATTRS_INLINE 1 + +#ifndef RF_CHANNEL +#define RF_CHANNEL 868000000 +#endif /* RF_CHANNEL */ + +#define CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT 0 + +#define IEEE802154_CONF_PANID 0xABCD + +#define PROFILE_CONF_ON 0 +#define ENERGEST_CONF_ON 0 + +#define AODV_COMPLIANCE +#define AODV_NUM_RT_ENTRIES 16 + +#define WITH_ASCII 1 + +#define PROCESS_CONF_NUMEVENTS 8 +#define PROCESS_CONF_STATS 1 + +#ifdef NETSTACK_CONF_WITH_IPV6 + +#define LINKADDR_CONF_SIZE 8 + +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 + +#ifndef UIP_CONF_ROUTER +#define UIP_CONF_ROUTER 1 +#endif + +#define NBR_TABLE_CONF_MAX_NEIGHBORS 16 +#define UIP_CONF_MAX_ROUTES 16 + +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +#define NETSTACK_CONF_WITH_IPV6 1 +#define UIP_CONF_IPV6_QUEUE_PKT 0 +#define UIP_CONF_IPV6_CHECKS 1 +#define UIP_CONF_IPV6_REASSEMBLY 0 +#define UIP_CONF_NETIF_MAX_ADDRESSES 3 +#define UIP_CONF_IP_FORWARD 0 +#define UIP_CONF_BUFFER_SIZE 240 +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 8 + +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#ifndef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 8 +#endif /* SICSLOWPAN_CONF_FRAG */ +#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 +#else /* NETSTACK_CONF_WITH_IPV6 */ +#define UIP_CONF_IP_FORWARD 1 +#define UIP_CONF_BUFFER_SIZE 140 +#endif /* NETSTACK_CONF_WITH_IPV6 */ + +#define UIP_CONF_ICMP_DEST_UNREACH 1 + +#define UIP_CONF_DHCP_LIGHT +#define UIP_CONF_LLH_LEN 0 +#define UIP_CONF_RECEIVE_WINDOW 48 +#define UIP_CONF_TCP_MSS 48 +#define UIP_CONF_MAX_CONNECTIONS 4 +#define UIP_CONF_MAX_LISTENPORTS 4 +#define UIP_CONF_UDP_CONNS 8 +#define UIP_CONF_FWCACHE_SIZE 16 +#define UIP_CONF_BROADCAST 1 +#define UIP_CONF_UDP 1 +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_PINGADDRCONF 0 +#define UIP_CONF_LOGGING 0 + +#define UIP_CONF_TCP_SPLIT 0 + +/* include the project config */ +/* PROJECT_CONF_H might be defined in the project Makefile */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif /* PROJECT_CONF_H */ + +#endif /* __CONTIKI_CONF_H__ */ diff --git a/platform/ev-aducrf101mkxz/contiki-main.c b/platform/ev-aducrf101mkxz/contiki-main.c new file mode 100644 index 000000000..c1db305e6 --- /dev/null +++ b/platform/ev-aducrf101mkxz/contiki-main.c @@ -0,0 +1,199 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + * \author Jim Paris + */ + +#include +#include +#include + +#include "contiki.h" +#include "net/netstack.h" + +#include "dev/serial-line.h" + +#include "net/ip/uip.h" + +#include "dev/button-sensor.h" +#include "dev/leds.h" + +#if NETSTACK_CONF_WITH_IPV6 +#include "net/ipv6/uip-ds6.h" +#endif /* NETSTACK_CONF_WITH_IPV6 */ + +#include "net/rime/rime.h" + +#include "uart.h" +#include "watchdog.h" + +SENSORS(&button_sensor); + +#ifndef SERIAL_ID +#define SERIAL_ID { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 } +#endif + +uint8_t serial_id[] = SERIAL_ID; +uint16_t node_id = 0x0102; + +/*---------------------------------------------------------------------------*/ +static void +set_rime_addr(void) +{ + linkaddr_t addr; + int i; + + memset(&addr, 0, sizeof(linkaddr_t)); +#if NETSTACK_CONF_WITH_IPV6 + memcpy(addr.u8, serial_id, sizeof(addr.u8)); +#else + if(node_id == 0) { + for(i = 0; i < sizeof(linkaddr_t); ++i) { + addr.u8[i] = serial_id[7 - i]; + } + } else { + addr.u8[0] = node_id & 0xff; + addr.u8[1] = node_id >> 8; + } +#endif + linkaddr_set_node_addr(&addr); + printf("Rime started with address "); + for(i = 0; i < sizeof(addr.u8) - 1; i++) { + printf("%d.", addr.u8[i]); + } + printf("%d\n", addr.u8[i]); +} +/*---------------------------------------------------------------------------*/ +static void +set_rf_params(void) +{ + int chan; + NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, RF_CHANNEL); + NETSTACK_RADIO.get_value(RADIO_PARAM_CHANNEL, &chan); + printf("RF channel set to %d Hz\n", chan); +} +/*---------------------------------------------------------------------------*/ +int contiki_argc = 0; +char **contiki_argv; + +int +main(int argc, char **argv) +{ + watchdog_init(); + leds_init(); + uart_init(115200); + clock_init(); + +#if NETSTACK_CONF_WITH_IPV6 +#if UIP_CONF_IPV6_RPL + printf(CONTIKI_VERSION_STRING " started with IPV6, RPL\n"); +#else + printf(CONTIKI_VERSION_STRING " started with IPV6\n"); +#endif +#else + printf(CONTIKI_VERSION_STRING " started\n"); +#endif + + contiki_argc = argc; + contiki_argv = argv; + + process_init(); + process_start(&etimer_process, NULL); + ctimer_init(); + rtimer_init(); + + set_rime_addr(); + + queuebuf_init(); + + set_rf_params(); + netstack_init(); + printf("MAC %s RDC %s NETWORK %s\n", + NETSTACK_MAC.name, NETSTACK_RDC.name, NETSTACK_NETWORK.name); + +#if NETSTACK_CONF_WITH_IPV6 + memcpy(&uip_lladdr.addr, serial_id, sizeof(uip_lladdr.addr)); + + process_start(&tcpip_process, NULL); + printf("Tentative link-local IPv6 address "); + { + uip_ds6_addr_t *lladdr; + int i; + lladdr = uip_ds6_get_link_local(-1); + for(i = 0; i < 8; i++) { + printf("%02x%02x%c", lladdr->ipaddr.u8[i * 2], + lladdr->ipaddr.u8[i * 2 + 1], + i == 7 ? '\n' : ':'); + } + /* make it hardcoded... */ + lladdr->state = ADDR_AUTOCONF; + } +#elif NETSTACK_CONF_WITH_IPV4 + process_start(&tcpip_process, NULL); +#endif + + serial_line_init(); + process_start(&sensors_process, NULL); + + autostart_start(autostart_processes); + + while(1) { + watchdog_periodic(); + + process_run(); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +void +log_message(char *m1, char *m2) +{ + printf("%s%s\n", m1, m2); +} +/*---------------------------------------------------------------------------*/ +void +uip_log(char *m) +{ + printf("%s\n", m); +} +/*---------------------------------------------------------------------------*/ +void +_xassert(const char *file, int line) +{ + printf("%s:%u: failed assertion\n", file, line); + for(;;) { + continue; + } +} diff --git a/platform/ev-aducrf101mkxz/leds-arch.c b/platform/ev-aducrf101mkxz/leds-arch.c new file mode 100644 index 000000000..2a3f5a9c4 --- /dev/null +++ b/platform/ev-aducrf101mkxz/leds-arch.c @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + * \author Jim Paris + */ + +#include "contiki.h" +#include "dev/leds.h" +#include "platform-conf.h" +#include "aducrf101-contiki.h" + +/* e.g. pADI_GP4 */ +#define GPIO CC_CONCAT(pADI_GP, LED_GPIO) + +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + /* Set LED pin as a GPIO output */ + GPIO->GPOEN |= (1UL << LED_PIN); + leds_arch_set(0); +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + if(GPIO->GPOUT & (1UL << LED_PIN)) { + return 0; + } else { + return 1; + } +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char leds) +{ + if(leds & 1) { + GPIO->GPCLR = (1UL << LED_PIN); + } else { + GPIO->GPSET = (1UL << LED_PIN); + } +} +/*---------------------------------------------------------------------------*/ + +/** + * @} + * @} + */ diff --git a/platform/ev-aducrf101mkxz/platform-conf.h b/platform/ev-aducrf101mkxz/platform-conf.h new file mode 100644 index 000000000..6842aaa5a --- /dev/null +++ b/platform/ev-aducrf101mkxz/platform-conf.h @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2014, Analog Devices, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 OWNER 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. + */ +/** + * \author Jim Paris + */ + +#ifndef __ADUCRF101_PLATFORM_CONF_H__ +#define __ADUCRF101_PLATFORM_CONF_H__ + +#define LED_GPIO 4 +#define LED_PIN 2 + +#define BUTTON_GPIO 0 +#define BUTTON_PIN 6 +#define BUTTON_INT 2 + +#endif diff --git a/platform/eval-adf7xxxmb4z/Makefile.eval-adf7xxxmb4z b/platform/eval-adf7xxxmb4z/Makefile.eval-adf7xxxmb4z index ff62e000f..42478c940 100644 --- a/platform/eval-adf7xxxmb4z/Makefile.eval-adf7xxxmb4z +++ b/platform/eval-adf7xxxmb4z/Makefile.eval-adf7xxxmb4z @@ -51,10 +51,6 @@ CONTIKIBOARD = . CONTIKI_PLAT_DEFS = -ifeq ($(UIP_CONF_IPV6),1) -CFLAGS += -DWITH_UIP6=1 -endif - include $(CONTIKIRL78)/Makefile.rl78 PROG_UART ?= /dev/ttyUSB1 @@ -62,5 +58,6 @@ PROG_UART ?= /dev/ttyUSB1 run: $(CONTIKI_PROJECT).$(TARGET).srec ~/adi-contiki/github/rl78flash/rl78flash -vv -i -m3 $(PROG_UART) -b500000 -a $< -MODULES+=core/net/ip core/net/ipv4 core/net core/net/rpl \ - core/net/ipv6 core/net/rime core/net/mac core/net/mac/sicslowmac +MODULES+=core/net \ + core/net/mac core/net/mac/sicslowmac \ + core/net/llsec diff --git a/platform/eval-adf7xxxmb4z/README.md b/platform/eval-adf7xxxmb4z/README.md index 1faa1a625..dc023e766 100644 --- a/platform/eval-adf7xxxmb4z/README.md +++ b/platform/eval-adf7xxxmb4z/README.md @@ -51,9 +51,9 @@ Build and run the SLIP tunnel on the host machine. Here it is assumed that the Secondary UART USB port (J3) is attached to /dev/ttyUSB1: make -C contiki/tools tunslip6 - sudo contiki/tools/tunslip6 -B 38400 -s /dev/ttyUSB1 -v3 aaaa::1/64 + sudo contiki/tools/tunslip6 -B 38400 -s /dev/ttyUSB1 -v3 fd00::1/64 -Open the border router home page at http://[aaaa::302:304:506:708]/ +Open the border router home page at http://[fd00::302:304:506:708]/ Build and run the IPv6 web server example on another eval board. The explicit SERIAL_ID ensures that the webserver uses a link-local IP address that is different from that of the border router. @@ -61,7 +61,7 @@ The explicit SERIAL_ID ensures that the webserver uses a link-local IP address t make -C contiki/examples/webserver-ipv6 TARGET=eval-adf7xxxmb4z SERIAL_ID='"\x01\x02\x03\x04\x05\x06\x07\x09"' webserver6.eval-adf7xxxmb4z.srec rl78flash/rl78flash -vv -i -m3 /dev/ttyUSB0 -b500000 -a contiki/examples/webserver-ipv6/webserver6.eval-adf7xxxmb4z.srec -Open the web server's home page at http://[aaaa::7a30:3178:3032:7830] +Open the web server's home page at http://[fd00::7a30:3178:3032:7830] On Windows: diff --git a/platform/eval-adf7xxxmb4z/contiki-conf.h b/platform/eval-adf7xxxmb4z/contiki-conf.h index 407251e6e..965bb16cd 100644 --- a/platform/eval-adf7xxxmb4z/contiki-conf.h +++ b/platform/eval-adf7xxxmb4z/contiki-conf.h @@ -56,9 +56,9 @@ #define PLATFORM_HAS_LEDS 0 /* TODO */ #define PLATFORM_HAS_BUTTON 1 -#define RIMEADDR_CONF_SIZE 8 +#define LINKADDR_CONF_SIZE 8 -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 /* Network setup for IPv6 */ #define NETSTACK_CONF_NETWORK sicslowpan_driver #define NETSTACK_CONF_MAC nullmac_driver @@ -71,7 +71,7 @@ #define CXMAC_CONF_ANNOUNCEMENTS 0 #define XMAC_CONF_ANNOUNCEMENTS 0 -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ /* Network setup for non-IPv6 (rime). */ #define NETSTACK_CONF_NETWORK rime_driver @@ -94,7 +94,7 @@ #define COLLECT_NBR_TABLE_CONF_MAX_NEIGHBORS 32 -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define QUEUEBUF_CONF_NUM 16 @@ -119,9 +119,9 @@ #define PROCESS_CONF_NUMEVENTS 8 #define PROCESS_CONF_STATS 1 -#ifdef WITH_UIP6 +#ifdef NETSTACK_CONF_WITH_IPV6 -#define RIMEADDR_CONF_SIZE 8 +#define LINKADDR_CONF_SIZE 8 #define UIP_CONF_LL_802154 1 #define UIP_CONF_LLH_LEN 0 @@ -130,10 +130,6 @@ #define UIP_CONF_ROUTER 1 #endif -#ifndef UIP_CONF_IPV6_RPL -#define UIP_CONF_IPV6_RPL 1 -#endif - #define NBR_TABLE_CONF_MAX_NEIGHBORS 30 #define UIP_CONF_MAX_ROUTES 30 @@ -141,32 +137,26 @@ #define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_RETRANS_TIMER 10000 -#define UIP_CONF_IPV6 1 +#define NETSTACK_CONF_WITH_IPV6 1 #define UIP_CONF_IPV6_QUEUE_PKT 0 #define UIP_CONF_IPV6_CHECKS 1 #define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_NETIF_MAX_ADDRESSES 3 -#define UIP_CONF_ND6_MAX_PREFIXES 3 -#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_IP_FORWARD 0 #define UIP_CONF_BUFFER_SIZE 1300 #define SICSLOWPAN_CONF_FRAG 1 #define SICSLOWPAN_CONF_MAXAGE 8 -#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 -#define SICSLOWPAN_CONF_COMPRESSION_HC1 1 -#define SICSLOWPAN_CONF_COMPRESSION_HC01 2 #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #ifndef SICSLOWPAN_CONF_FRAG #define SICSLOWPAN_CONF_FRAG 1 #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ -#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_IP_FORWARD 1 #define UIP_CONF_BUFFER_SIZE 1300 -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_ICMP_DEST_UNREACH 1 diff --git a/platform/eval-adf7xxxmb4z/contiki-main.c b/platform/eval-adf7xxxmb4z/contiki-main.c index e82d78aa9..d34b7e63f 100644 --- a/platform/eval-adf7xxxmb4z/contiki-main.c +++ b/platform/eval-adf7xxxmb4z/contiki-main.c @@ -45,9 +45,9 @@ #include "dev/button-sensor.h" -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 #include "net/ipv6/uip-ds6.h" -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #include "net/rime/rime.h" #include "uart0.h" @@ -66,7 +66,9 @@ SENSORS(&button_sensor); #endif static uint8_t serial_id[] = SERIAL_ID; +#if !NETSTACK_CONF_WITH_IPV6 static uint16_t node_id = 0x0102; +#endif /* !NETSTACK_CONF_WITH_IPV6 */ /*---------------------------------------------------------------------------*/ static void @@ -76,7 +78,7 @@ set_rime_addr(void) int i; memset(&addr, 0, sizeof(linkaddr_t)); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(addr.u8, serial_id, sizeof(addr.u8)); #else if(node_id == 0) { @@ -158,7 +160,7 @@ main(int argc, char **argv) PM3 &= ~BIT(0); /* LED7 */ PM5 &= ~BIT(0); /* LED8 */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #if UIP_CONF_IPV6_RPL printf(CONTIKI_VERSION_STRING " started with IPV6, RPL" NEWLINE); #else @@ -183,7 +185,7 @@ main(int argc, char **argv) netstack_init(); printf("MAC %s RDC %s NETWORK %s" NEWLINE, NETSTACK_MAC.name, NETSTACK_RDC.name, NETSTACK_NETWORK.name); -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(&uip_lladdr.addr, serial_id, sizeof(uip_lladdr.addr)); process_start(&tcpip_process, NULL); @@ -201,7 +203,7 @@ main(int argc, char **argv) printf("%02x%02x" NEWLINE, lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]); } -#else +#elif NETSTACK_CONF_WITH_IPV4 process_start(&tcpip_process, NULL); #endif diff --git a/platform/exp5438/Makefile.exp5438 b/platform/exp5438/Makefile.exp5438 index 380012c36..04296f41f 100644 --- a/platform/exp5438/Makefile.exp5438 +++ b/platform/exp5438/Makefile.exp5438 @@ -1,9 +1,9 @@ # $Id: Makefile.z1,v 1.4 2010/11/07 08:40:24 enricmcalvo Exp $ # msp430flasher -n msp430x5437 -w "Firmware.txt" -v -z [VCC] -MODULES += core/net core/net/ip core/net/ipv6 core/net/ipv4 \ - core/net/mac core/net/rpl core/net/rime core/net/mac/contikimac \ - dev/cc2420 +MODULES += core/net \ + core/net/mac core/net/mac/contikimac \ + core/net/llsec dev/cc2420 ifdef IAR CFLAGS+=-e --vla -Ohz --multiplier=32 --multiplier_location=4C0 --hw_workaround=CPU40 --core=430X --data_model small --double=32 -D__MSP430F5438A__=1 @@ -44,19 +44,6 @@ ifndef CONTIKI_TARGET_MAIN CONTIKI_TARGET_MAIN = contiki-exp5438-main.c endif -ifeq ($(UIP_CONF_IPV6),1) -CFLAGS += -DWITH_UIP6=1 -endif - -ifndef IAR -ifneq (,$(findstring 4.7.,$(shell msp430-gcc -dumpversion))) -TARGET_MEMORY_MODEL ?= medium -CFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) -CFLAGS += -ffunction-sections -fdata-sections -mcode-region=far -LDFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) -Wl,-gc-sections -endif -endif - CONTIKI_TARGET_SOURCEFILES += $(ARCH) $(UIPDRIVERS) ifdef IAR @@ -64,6 +51,10 @@ MCU=msp430f5438a else MCU=msp430f5438 endif + +# Platform has a MSP430X MCU with 20-bit support +CPU_HAS_MSP430X=1 + include $(CONTIKI)/cpu/msp430/Makefile.msp430 contiki-$(TARGET).a: ${addprefix $(OBJECTDIR)/,symbols.o} diff --git a/platform/exp5438/clock.c b/platform/exp5438/clock.c index 7a0dcaf72..d6118e12e 100644 --- a/platform/exp5438/clock.c +++ b/platform/exp5438/clock.c @@ -43,12 +43,26 @@ #define MAX_TICKS (~((clock_time_t)0) / 2) +#define CLOCK_LT(a, b) ((int16_t)((a)-(b)) < 0) + static volatile unsigned long seconds; static volatile clock_time_t count = 0; /* last_tar is used for calculating clock_fine, last_ccr might be better? */ static unsigned short last_tar = 0; /*---------------------------------------------------------------------------*/ +static inline uint16_t +read_tar(void) +{ + /* Same as clock_counter(), but can be inlined */ + uint16_t t1, t2; + do { + t1 = TA1R; + t2 = TA1R; + } while(t1 != t2); + return t1; +} +/*---------------------------------------------------------------------------*/ ISR(TIMER1_A1, timera1) { ENERGEST_ON(ENERGEST_TYPE_IRQ); @@ -59,8 +73,9 @@ ISR(TIMER1_A1, timera1) * Occurrs when timer state is toggled between STOP and CONT. */ while(TA1CTL & MC1 && TA1CCR1 - TA1R == 1); + last_tar = read_tar(); /* Make sure interrupt time is future */ - do { + while(!CLOCK_LT(last_tar, TA1CCR1)) { /* TACTL &= ~MC1;*/ TA1CCR1 += INTERVAL; /* TACTL |= MC1;*/ @@ -78,9 +93,8 @@ ISR(TIMER1_A1, timera1) ++seconds; energest_flush(); } - } while((TA1CCR1 - TA1R) > INTERVAL); - - last_tar = TA1R; + last_tar = read_tar(); + } if(etimer_pending() && (etimer_next_expiration_time() - count - 1) > MAX_TICKS) { @@ -208,7 +222,7 @@ __delay_cycles(unsigned long c) } #endif /* __GNUC__ */ /*---------------------------------------------------------------------------*/ -/** +/* * Wait for a multiple of 10 ms. * */ diff --git a/platform/exp5438/contiki-conf.h b/platform/exp5438/contiki-conf.h index c03fccfdb..9220ba890 100644 --- a/platform/exp5438/contiki-conf.h +++ b/platform/exp5438/contiki-conf.h @@ -26,7 +26,11 @@ #endif /* NETSTACK_CONF_RADIO */ #ifndef NETSTACK_CONF_FRAMER +#if NETSTACK_CONF_WITH_IPV6 #define NETSTACK_CONF_FRAMER framer_802154 +#else /* NETSTACK_CONF_WITH_IPV6 */ +#define NETSTACK_CONF_FRAMER contikimac_framer +#endif /* NETSTACK_CONF_WITH_IPV6 */ #endif /* NETSTACK_CONF_FRAMER */ #ifndef CC2420_CONF_AUTOACK @@ -35,7 +39,7 @@ #define NULLRDC_CONF_802154_AUTOACK 1 -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 /* Network setup for IPv6 */ #define NETSTACK_CONF_NETWORK sicslowpan_driver @@ -44,7 +48,6 @@ larger than a specified size, if no ContikiMAC header should be used. */ #define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63 -#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0 #define CXMAC_CONF_ANNOUNCEMENTS 0 #define XMAC_CONF_ANNOUNCEMENTS 0 @@ -53,7 +56,7 @@ #define QUEUEBUF_CONF_NUM 8 #endif -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ /* Network setup for non-IPv6 (rime). */ @@ -86,7 +89,7 @@ #define CC2420_CONF_SFD_TIMESTAMPS 1 #endif /* TIMESYNCH_CONF_ENABLED */ -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define PACKETBUF_CONF_ATTRS_INLINE 1 @@ -132,7 +135,7 @@ #define PROCESS_CONF_STATS 1 /*#define PROCESS_CONF_FASTPOLL 4*/ -#ifdef WITH_UIP6 +#ifdef NETSTACK_CONF_WITH_IPV6 #define LINKADDR_CONF_SIZE 8 @@ -140,9 +143,6 @@ #define UIP_CONF_LLH_LEN 0 #define UIP_CONF_ROUTER 1 -#ifndef UIP_CONF_IPV6_RPL -#define UIP_CONF_IPV6_RPL 1 -#endif /* UIP_CONF_IPV6_RPL */ /* configure number of neighbors and routes */ #ifndef NBR_TABLE_CONF_MAX_NEIGHBORS @@ -156,37 +156,28 @@ #define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_RETRANS_TIMER 10000 -#define UIP_CONF_IPV6 1 +#define NETSTACK_CONF_WITH_IPV6 1 #ifndef UIP_CONF_IPV6_QUEUE_PKT #define UIP_CONF_IPV6_QUEUE_PKT 0 #endif /* UIP_CONF_IPV6_QUEUE_PKT */ #define UIP_CONF_IPV6_CHECKS 1 #define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_NETIF_MAX_ADDRESSES 3 -#define UIP_CONF_ND6_MAX_PREFIXES 3 -#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_IP_FORWARD 0 #ifndef UIP_CONF_BUFFER_SIZE #define UIP_CONF_BUFFER_SIZE 240 #endif -#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 -#define SICSLOWPAN_CONF_COMPRESSION_HC1 1 -#define SICSLOWPAN_CONF_COMPRESSION_HC01 2 #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #ifndef SICSLOWPAN_CONF_FRAG #define SICSLOWPAN_CONF_FRAG 1 #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ -#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_IP_FORWARD 1 #define UIP_CONF_BUFFER_SIZE 108 -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_ICMP_DEST_UNREACH 1 diff --git a/platform/exp5438/contiki-exp5438-main.c b/platform/exp5438/contiki-exp5438-main.c index 3dafe68aa..321bb9171 100644 --- a/platform/exp5438/contiki-exp5438-main.c +++ b/platform/exp5438/contiki-exp5438-main.c @@ -53,9 +53,9 @@ #include "lcd.h" #include "duty-cycle-scroller.h" -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 #include "net/ipv6/uip-ds6.h" -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define DEBUG 1 @@ -77,7 +77,7 @@ set_rime_addr(void) int i; memset(&addr, 0, sizeof(linkaddr_t)); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(addr.u8, node_mac, sizeof(addr.u8)); #else if(node_id == 0) { @@ -122,9 +122,9 @@ main(int argc, char **argv) leds_on(LEDS_RED); uart1_init(BAUD2UBR(115200)); /* Must come before first printf */ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 slip_arch_init(BAUD2UBR(115200)); -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ leds_on(LEDS_GREEN); /* xmem_init(); */ @@ -203,7 +203,7 @@ main(int argc, char **argv) PRINTF("Node id not set.\n"); } -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(&uip_lladdr.addr, node_mac, sizeof(uip_lladdr.addr)); /* Setup nullmac-like MAC for 802.15.4 */ @@ -236,7 +236,7 @@ main(int argc, char **argv) if(!UIP_CONF_IPV6_RPL) { uip_ipaddr_t ipaddr; int i; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE); printf("Tentative global IPv6 address "); @@ -248,7 +248,7 @@ main(int argc, char **argv) ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]); } -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ NETSTACK_RDC.init(); NETSTACK_MAC.init(); @@ -259,9 +259,9 @@ main(int argc, char **argv) CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0? 1: NETSTACK_RDC.channel_check_interval()), CC2420_CONF_CHANNEL); -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ -#if !WITH_UIP6 +#if !NETSTACK_CONF_WITH_IPV6 uart1_set_input(serial_line_input_byte); serial_line_init(); #endif @@ -307,8 +307,7 @@ main(int argc, char **argv) static unsigned long irq_energest = 0; /* Re-enable interrupts and go to sleep atomically. */ - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* We only want to measure the processing done in IRQs when we are asleep, so we discard the processing time done when we were awake. */ @@ -327,8 +326,7 @@ main(int argc, char **argv) irq_energest = energest_type_time(ENERGEST_TYPE_IRQ); eint(); watchdog_start(); - ENERGEST_OFF(ENERGEST_TYPE_LPM); - ENERGEST_ON(ENERGEST_TYPE_CPU); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } } } diff --git a/platform/exp5438/hal_MSP-EXP430F5438.h b/platform/exp5438/hal_MSP-EXP430F5438.h index 8b64313bb..d03162066 100644 --- a/platform/exp5438/hal_MSP-EXP430F5438.h +++ b/platform/exp5438/hal_MSP-EXP430F5438.h @@ -1,15 +1,15 @@ -/******************************************************************************* - Filename: hal_MSP-EXP430F5438.h - - Copyright 2008 Texas Instruments, Inc. - -This is the master header file and also the only necessary file to be included -in order to use MSP-EXP430F548 HAL. -***************************************************************************/ - -#ifndef HAL_MSP_EXP430F5438_H -#define HAL_MSP_EXP430F5438_H - -#include "hal_lcd.h" - -#endif +/******************************************************************************* + Filename: hal_MSP-EXP430F5438.h + + Copyright 2008 Texas Instruments, Inc. + +This is the master header file and also the only necessary file to be included +in order to use MSP-EXP430F548 HAL. +***************************************************************************/ + +#ifndef HAL_MSP_EXP430F5438_H +#define HAL_MSP_EXP430F5438_H + +#include "hal_lcd.h" + +#endif diff --git a/platform/exp5438/hal_lcd.c b/platform/exp5438/hal_lcd.c index fdaf32203..66be62de9 100644 --- a/platform/exp5438/hal_lcd.c +++ b/platform/exp5438/hal_lcd.c @@ -1,1198 +1,1196 @@ -/******************************************************************************* - * - * hal_lcd.c - * - * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ - * - * 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 Texas Instruments Incorporated 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 - * OWNER 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. - * - ******************************************************************************/ - -#include "contiki-conf.h" - -#include "hal_MSP-EXP430F5438.h" -#include "hal_lcd_fonts.h" - -unsigned char LcdInitMacro[] = { - 0x74, 0x00, 0x00, 0x76, 0x00, 0x01, // R00 start oscillation - 0x74, 0x00, 0x01, 0x76, 0x00, 0x0D, // R01 driver output control - 0x74, 0x00, 0x02, 0x76, 0x00, 0x4C, // R02 LCD - driving waveform control - 0x74, 0x00, 0x03, 0x76, 0x12, 0x14, // R03 Power control - 0x74, 0x00, 0x04, 0x76, 0x04, 0x66, // R04 Contrast control - 0x74, 0x00, 0x05, 0x76, 0x00, 0x10, // R05 Entry mode - 0x74, 0x00, 0x06, 0x76, 0x00, 0x00, // R06 RAM data write mask - 0x74, 0x00, 0x07, 0x76, 0x00, 0x15, // R07 Display control - 0x74, 0x00, 0x08, 0x76, 0x00, 0x03, // R08 Cursor Control - 0x74, 0x00, 0x09, 0x76, 0x00, 0x00, // R09 RAM data write mask - 0x74, 0x00, 0x0A, 0x76, 0x00, 0x15, // R0A - 0x74, 0x00, 0x0B, 0x76, 0x00, 0x03, // R0B Horizontal Cursor Position - 0x74, 0x00, 0x0C, 0x76, 0x00, 0x03, // R0C Vertical Cursor Position - 0x74, 0x00, 0x0D, 0x76, 0x00, 0x00, // R0D - 0x74, 0x00, 0x0E, 0x76, 0x00, 0x15, // R0E - 0x74, 0x00, 0x0F, 0x76, 0x00, 0x03, // R0F - 0x74, 0x00, 0x10, 0x76, 0x00, 0x15, // R0E - 0x74, 0x00, 0x11, 0x76, 0x00, 0x03, // R0F -}; - -unsigned char Read_Block_Address_Macro[] = {0x74, 0x00, 0x12, 0x77, 0x00, 0x00}; -unsigned char Draw_Block_Value_Macro[] = {0x74, 0x00, 0x12, 0x76, 0xFF, 0xFF}; -unsigned char Draw_Block_Address_Macro[] = {0x74, 0x00, 0x11, 0x76, 0x00, 0x00}; - -unsigned int LcdAddress = 0, LcdTableAddress = 0; -unsigned char contrast = 0x66; -unsigned char backlight = 8; -int LCD_MEM[110 * 17]; //This array stores a copy of all data on the LCD -//screen. If memory is an issue though, this array -//can be eliminated and the halLcdReadBlock() -//command can be used instead whenever you are -//manipulating the currently displayed data. - -/**********************************************************************//** - * @brief Sends 3+3 bytes of data to the LCD using the format specified - * by the LCD Guide. - * - * @param Data[] Data array for transmission - * - * @return none - *************************************************************************/ - -void halLcdSendCommand(unsigned char Data[]) -{ - unsigned char i; - - LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer - for (i = 0; i < 6; i++) - { - while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG - UCB2TXBUF = Data[i]; // Load data - - if (i == 2) //Pull CS up after 3 bytes - { - while (UCB2STAT & UCBUSY) ; - LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer - LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer - } - } - while (UCB2STAT & UCBUSY) ; - LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer -} - -/**********************************************************************//** - * @brief Initializes the USCI module, LCD device for communication. - * - * - Sets up the SPI2C Communication Module - * - Performs Hitachi LCD Initialization Procedure - * - * @param none - * - * @return none - *************************************************************************/ - -void halLcdInit(void) -{ - volatile unsigned int i = 0; - - LCD_CS_RST_OUT |= LCD_CS_PIN | LCD_RESET_PIN; - LCD_CS_RST_DIR |= LCD_CS_PIN | LCD_RESET_PIN; - - LCD_BACKLT_SEL |= LCD_BACKLIGHT_PIN; - - LCD_CS_RST_OUT &= ~LCD_RESET_PIN; // Reset LCD - __delay_cycles(0x47FF); //Reset Pulse - LCD_CS_RST_OUT |= LCD_RESET_PIN; - - // UCLK,MOSI setup, SOMI cleared - LCD_SPI_SEL |= LCD_MOSI_PIN + LCD_CLK_PIN; - LCD_SPI_SEL &= ~LCD_MISO_PIN; - LCD_SPI_DIR &= ~(LCD_MISO_PIN + LCD_MOSI_PIN); // Pin direction controlled by module, - // Set both pins to input as default - - // Initialize the USCI_B2 module for SPI operation - UCB2CTL1 = UCSWRST; // Hold USCI in SW reset mode while configuring - // it - UCB2CTL0 = UCMST + UCSYNC + UCCKPL + UCMSB; // 3-pin, 8-bit SPI master - UCB2CTL1 |= UCSSEL_2; // SMCLK - UCB2BR0 = 4; // Note: Do not exceed D/S spec for UCLK! - UCB2BR1 = 0; - UCB2CTL1 &= ~UCSWRST; // Release USCI state machine - UCB2IFG &= ~UCRXIFG; - - // Wake-up the LCD as per datasheet specifications - halLcdActive(); - - // LCD Initialization Routine Using Predefined Macros - halLcdSendCommand(&LcdInitMacro[1 * 6]); - halLcdSendCommand(&LcdInitMacro[2 * 6]); - halLcdSendCommand(&LcdInitMacro[4 * 6]); - halLcdSendCommand(&LcdInitMacro[5 * 6]); - halLcdSendCommand(&LcdInitMacro[6 * 6]); - halLcdSendCommand(&LcdInitMacro[7 * 6]); - -} - -/**********************************************************************//** - * @brief Shuts down the LCD display and hdisables the USCI communication. - * - * @param none - * - * @return none - *************************************************************************/ - -void halLcdShutDown(void) -{ - halLcdStandby(); - - LCD_CS_RST_DIR |= LCD_CS_PIN | LCD_RESET_PIN; - LCD_CS_RST_OUT &= ~(LCD_CS_PIN | LCD_RESET_PIN); - LCD_CS_RST_OUT &= ~LCD_RESET_PIN; - - LCD_SPI_SEL &= ~(LCD_MOSI_PIN + LCD_CLK_PIN + LCD_MISO_PIN); - LCD_CS_RST_DIR |= LCD_MOSI_PIN + LCD_CLK_PIN + LCD_MISO_PIN; - LCD_CS_RST_OUT &= ~(LCD_MOSI_PIN + LCD_CLK_PIN + LCD_MISO_PIN); - - UCB2CTL0 = UCSWRST; -} - -/**********************************************************************//** - * @brief Initializes the LCD backlight PWM signal. - * - * @param none - * - * @return none - * - *************************************************************************/ - -void halLcdBackLightInit(void) -{ - LCD_BACKLT_DIR |= LCD_BACKLIGHT_PIN; - LCD_BACKLT_OUT |= LCD_BACKLIGHT_PIN; - LCD_BACKLT_SEL |= LCD_BACKLIGHT_PIN; - - TA0CCTL3 = OUTMOD_7; - TA0CCR3 = TA0CCR0 >> 1; - backlight = 8; - - TA0CCR0 = 400; - TA0CTL = TASSEL_2 + MC_1; -} - -/**********************************************************************//** - * @brief Get function for the backlight PWM's duty cycle. - * - * @param none - * - * @return backlight One of the the 17 possible settings - valued 0 to 16. - * - *************************************************************************/ - -unsigned int halLcdGetBackLight(void) -{ - return backlight; -} - -/**********************************************************************//** - * @brief Set function for the backlight PWM's duty cycle - * - * @param BackLightLevel The target backlight duty cycle - valued 0 to 16. - * - * @return none - *************************************************************************/ - -void halLcdSetBackLight(unsigned char BackLightLevel) -{ - unsigned int dutyCycle = 0, i, dummy; - - if (BackLightLevel > 0) - { - TA0CCTL3 = OUTMOD_7; - dummy = (TA0CCR0 >> 4); - - for (i = 0; i < BackLightLevel; i++) - dutyCycle += dummy; - - TA0CCR3 = dutyCycle; - - // If the backlight was previously turned off, turn it on. - if (!backlight) - TA0CTL |= MC0; - } - else - { - TA0CCTL3 = 0; - TA0CTL &= ~MC0; - } - backlight = BackLightLevel; -} - -/**********************************************************************//** - * @brief Turns off the backlight. - * - * Clears the respective GPIO and timer settings. - * - * @param none - * - * @return none - *************************************************************************/ - -void halLcdShutDownBackLight(void) -{ - LCD_BACKLT_DIR |= LCD_BACKLIGHT_PIN; - LCD_BACKLT_OUT &= ~(LCD_BACKLIGHT_PIN); - LCD_BACKLT_SEL &= ~LCD_BACKLIGHT_PIN; - - TA0CCTL3 = 0; - TA0CTL = 0; - - backlight = 0; -} - -/**********************************************************************//** - * @brief Set function for the contrast level of the LCD. - * - * @param ContrastLevel The target contrast level - * - * @return none - *************************************************************************/ - -void halLcdSetContrast(unsigned char ContrastLevel) -{ - if (ContrastLevel > 127) ContrastLevel = 127; - if (ContrastLevel < 70) ContrastLevel = 70; - LcdInitMacro[0x04 * 6 + 5] = ContrastLevel; - halLcdSendCommand(&LcdInitMacro[0x04 * 6]); -} - -/**********************************************************************//** - * @brief Get function for the contrast level of the LCD. - * - * @param none - * - * @return ContrastLevel The LCD constrast level - *************************************************************************/ - -unsigned char halLcdGetContrast(void) -{ - return LcdInitMacro[0x04 * 6 + 5]; -} - -/**********************************************************************//** - * @brief Turns the LCD cursor on at the current text position. - * - * @param none - * - * @return none - *************************************************************************/ - -void halLcdCursor(void) -{ - LcdInitMacro[8 * 6 + 5] ^= BIT2; - halLcdSendCommand(&LcdInitMacro[8 * 6]); - - LcdInitMacro[0x0B * 6 + 5] = ((LcdAddress & 0x1F) << 3); - LcdInitMacro[0x0B * 6 + 4] = ((LcdAddress & 0x1F) << 3) + 3; - LcdInitMacro[0x0C * 6 + 5] = (LcdAddress >> 5); - LcdInitMacro[0x0C * 6 + 4] = (LcdAddress >> 5) + 7; - halLcdSendCommand(&LcdInitMacro[0x0B * 6]); - halLcdSendCommand(&LcdInitMacro[0x0C * 6]); - - halLcdSetAddress(LcdAddress); -} - -/**********************************************************************//** - * @brief Turns off the LCD cursor. - * - * @param none - * - * @return none - *************************************************************************/ - -void halLcdCursorOff(void) -{ - LcdInitMacro[8 * 6 + 5] &= ~BIT2; - halLcdSendCommand(&LcdInitMacro[8 * 6]); -} - -/**********************************************************************//** - * @brief Inverts the grayscale values of the LCD display (Black <> white). - * - * @param none - * - * @return none - *************************************************************************/ - -void halLcdReverse(void) -{ - LcdInitMacro[7 * 6 + 5] ^= BIT1; - halLcdSendCommand(&LcdInitMacro[7 * 6]); -} - -/**********************************************************************//** - * @brief Sets the LCD in standby mode to reduce power consumption. - * - * @param none - * - * @return none - *************************************************************************/ - -void halLcdStandby(void) -{ - LcdInitMacro[3 * 6 + 5] &= (~BIT3) & (~BIT2); - LcdInitMacro[3 * 6 + 5] |= BIT0; - halLcdSendCommand(&LcdInitMacro[3 * 6]); -} - -/**********************************************************************//** - * @brief Puts the LCD into active mode. - * - * @param none - * - * @return none - *************************************************************************/ - -void halLcdActive(void) -{ - halLcdSendCommand(LcdInitMacro); // R00 start oscillation - - // Wait a minimum of 25ms after issuing "start oscillation" - // command (to accomodate for MCLK up to 25MHz) - { - int i; - for(i = 0; i < 5; ++i) { - __delay_cycles(50000); - } - } - - LcdInitMacro[3 * 6 + 5] |= BIT3; - LcdInitMacro[3 * 6 + 5] &= ~BIT0; - halLcdSendCommand(&LcdInitMacro[3 * 6]); // R03 Power control -} - -/**********************************************************************//** - * @brief Sets the pointer location in the LCD. - * - * - LcdAddress = Address - * - LcdTableAddress = Correct Address Row + Column - * = (Address / 0x20)* 17 + Column - * - * @param Address The target pointer location in the LCD. - * - * @return none - *************************************************************************/ - -void halLcdSetAddress(int Address) -{ - int temp; - - Draw_Block_Address_Macro[4] = Address >> 8; - Draw_Block_Address_Macro[5] = Address & 0xFF; - halLcdSendCommand(Draw_Block_Address_Macro); - LcdAddress = Address; - temp = Address >> 5; // Divided by 0x20 - temp = temp + (temp << 4); - //Multiplied by (1+16) and added by the offset - LcdTableAddress = temp + (Address & 0x1F); -} - -/**********************************************************************//** - * @brief Draws a block at the specified LCD address. - * - * A block is the smallest addressable memory on the LCD and is - * equivalent to 8 pixels, each of which is represented by 2 bits - * that represent a grayscale value between 00b and 11b. - * - * @param Address The address at which to draw the block. - * - * @param Value The value of the block - * - * @return none - *************************************************************************/ - -void halLcdDrawBlock(unsigned int Address, unsigned int Value) -{ - halLcdSetAddress(Address); - halLcdDrawCurrentBlock(Value); -} - -/**********************************************************************//** - * @brief Writes Value to LCD CGram and MSP430 internal LCD table. - * - * Also updates the LcdAddress and LcdTableAddress to the correct values. - * - * @param Value The value of the block to be written to the LCD. - * - * @return none - *************************************************************************/ - -void halLcdDrawCurrentBlock(unsigned int Value) -{ - int temp; - - Draw_Block_Value_Macro[4] = Value >> 8; - Draw_Block_Value_Macro[5] = Value & 0xFF; - LCD_MEM[LcdTableAddress] = Value; - - halLcdSendCommand(Draw_Block_Value_Macro); - - LcdAddress++; - temp = LcdAddress >> 5; // Divided by 0x20 - temp = temp + (temp << 4); - // Multiplied by (1+16) and added by the offset - LcdTableAddress = temp + (LcdAddress & 0x1F); - - // If LcdAddress gets off the right edge, move to next line - if ((LcdAddress & 0x1F) > 0x11) - halLcdSetAddress((LcdAddress & 0xFFE0) + 0x20); - if (LcdAddress == LCD_Size) - halLcdSetAddress(0); -} - -/**********************************************************************//** - * @brief Returns the LCD CGRAM value at location Address. - * - * @param Address The address of the block to be read from the LCD. - * - * @return Value The value held at the specified address. - *************************************************************************/ - -int halLcdReadBlock(unsigned int Address) -{ - int i = 0, Value = 0, ReadData[7]; - - halLcdSetAddress(Address); - halLcdSendCommand(Read_Block_Address_Macro); - - LCD_CS_RST_OUT &= ~LCD_CS_PIN; // start transfer CS=0 - UCB2TXBUF = 0x77; // Transmit first character 0x77 - - while (!(UCB2IFG & UCTXIFG)) ; - while (UCB2STAT & UCBUSY) ; - - //Read 5 dummies values and 2 valid address data - LCD_SPI_SEL &= ~LCD_MOSI_PIN; //Change SPI2C Dir - LCD_SPI_SEL |= LCD_MISO_PIN; - - for (i = 0; i < 7; i++) - { - UCB2IFG &= ~UCRXIFG; - UCB2TXBUF = 1; // load dummy byte 1 for clk - while (!(UCB2IFG & UCRXIFG)) ; - ReadData[i] = UCB2RXBUF; - } - LCD_CS_RST_OUT |= LCD_CS_PIN; // Stop Transfer CS = 1 - - LCD_SPI_SEL |= LCD_MOSI_PIN; //Change SPI2C Dir - LCD_SPI_SEL &= ~LCD_MISO_PIN; - LCD_CS_RST_DIR |= LCD_MOSI_PIN + LCD_CLK_PIN; - LCD_CS_RST_DIR &= ~LCD_MISO_PIN; - - Value = (ReadData[5] << 8) + ReadData[6]; - return Value; -} - -/**********************************************************************//** - * @brief Draw a Pixel of grayscale at coordinate (x,y) to LCD - * - * @param x x-coordinate for grayscale value - * - * @param y y-coordinate for grayscale value - * - * @param GrayScale The intended grayscale value of the pixel - one of - * four possible settings. - * - * @return none - *************************************************************************/ - -void halLcdPixel(int x, int y, unsigned char GrayScale) -{ - int Address, Value; - unsigned char offset; - - //Each line increments by 0x20 - if ((x >= 0) && (x < LCD_COL) && (y >= 0) && (y < LCD_ROW)) - { - Address = (y << 5) + (x >> 3); //Narrow down to 8 possible pixels - - Value = LCD_MEM[(y << 4) + y + (x >> 3)]; //y * 17 --> row. x>>3 --> column - - offset = (x & 0x07) << 1; //3 LSBs = pos. within the 8 columns - Value &= ~(3 << offset); //clear out the corresponding bits - Value |= GrayScale << offset; //set pixel to GrayScale level - - halLcdDrawBlock(Address, Value); - } -} - -/**********************************************************************//** - * @brief Clears entire LCD CGRAM as well as LCD_MEM. - * - * @param none - * - * @return none - *************************************************************************/ - -void halLcdClearScreen(void) -{ - int i, j, k, Current_Location = 0; - - halLcdSetAddress(0); - - for (i = 0; i < 110; i++) - { - //prepare to send image - LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer - for (k = 0; k < 3; k++) - { - while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG - UCB2TXBUF = Draw_Block_Value_Macro[k]; // Load data - } - while (UCB2STAT & UCBUSY) ; - LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer - LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer - while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG - UCB2TXBUF = Draw_Block_Value_Macro[3]; // Load data - - //send blank line - for (j = 0; j < 17; j++) - { - LCD_MEM[LcdTableAddress++] = 0x00; - while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG - UCB2TXBUF = 0x00; // Load data - while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG - UCB2TXBUF = 0x00; // Load data - } - //Clear the partially visible block at the edge of the screen - while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG - UCB2TXBUF = 0x00; // Load data - while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG - UCB2TXBUF = 0x00; // Load data - while (UCB2STAT & UCBUSY) ; - LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer - - Current_Location += 0x20; - halLcdSetAddress(Current_Location); - } - - halLcdSetAddress(0); -} - -/**********************************************************************//** - * @brief Loads an image of size = rows * columns, starting at the - * coordinate (x,y). - * - * @param Image[] The image to be loaded - * - * @param Rows The number of rows in the image. Size = Rows * Columns. - * - * @param Columns The number of columns in the image. Size = Rows * Columns. - * - * @param x x-coordinate of the image's starting location - * - * @param y y-coordinate of the image's starting location - * - * @return none - *************************************************************************/ - -void halLcdImage(const unsigned int Image[], int Columns, int Rows, int x, int y) -{ - int i, CurrentLocation; - - CurrentLocation = (y << 5) + (x >> 3); - halLcdSetAddress(CurrentLocation); - for (i = 0; i < Rows; i++) - { - halLcdDrawCurrentLine(Image, Columns); - Image += Columns; - CurrentLocation += 0x20; - halLcdSetAddress(CurrentLocation); - } -} - -/**********************************************************************//** - * @brief Writes Value to LCD CGram and MSP430 internal LCD table. - * - * Also updates the LcdAddress and LcdTableAddress to the correct values. - * - * @param *value Pointer to the line to be written to the LCD. - * - * @return none - *************************************************************************/ - -void halLcdDrawCurrentLine(const unsigned int *value, int Columns) -{ - unsigned char i; - - //prepare to send image - LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer - for (i = 0; i < 3; i++) - { - while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG - UCB2TXBUF = Draw_Block_Value_Macro[i]; // Load data - } - while (UCB2STAT & UCBUSY) ; - LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer - LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer - while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG - UCB2TXBUF = Draw_Block_Value_Macro[3]; // Load data - - //send the image - for (i = 0; i < Columns; i++) - { - // Make sure we are not writing outside LCD_MEM[] - if (LcdTableAddress >= sizeof(LCD_MEM)){ - break; - } - LCD_MEM[LcdTableAddress++] = *value; - while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG - UCB2TXBUF = (*value) >> 8; // Load data - while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG - UCB2TXBUF = (*value++) & 0xFF; // Load data - } - - while (UCB2STAT & UCBUSY) ; - LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer -} - -/**********************************************************************//** - * @brief Clears an image of size rows x columns starting at (x, y). - * - * @param Columns The size, in columns, of the image to be cleared. - * - * @param Rows The size, in rows, of the image to be cleared. - * - * @param x x-coordinate of the image to be cleared - * - * @param y y-coordinate of the image to be cleared - * - * @return none - *************************************************************************/ - -void halLcdClearImage(int Columns, int Rows, int x, int y) -{ - int i, j, k, Current_Location; - - Current_Location = (y << 5) + (x >> 3); - halLcdSetAddress(Current_Location); - - for (i = 0; i < Rows; i++) - { - //prepare to send image - LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer - for (k = 0; k < 3; k++) - { - while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG - UCB2TXBUF = Draw_Block_Value_Macro[k]; // Load data - } - while (UCB2STAT & UCBUSY) ; - LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer - LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer - while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG - UCB2TXBUF = Draw_Block_Value_Macro[3]; // Load data - - //send blank line - for (j = 0; j < Columns; j++) - { - LCD_MEM[LcdTableAddress++] = 0x00; - while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG - UCB2TXBUF = 0x00; // Load data - while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG - UCB2TXBUF = 0x00; // Load data - } - while (UCB2STAT & UCBUSY) ; - LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer - - Current_Location += 0x20; - halLcdSetAddress(Current_Location); - } -} - -/**********************************************************************//** - * @brief Writes Value to LCD CGRAM. Pointers internal to the LCD - * are also updated. - * - * @param Value The value to be written to the current LCD pointer - * - * @return none - *************************************************************************/ - -void halLcdDrawTextBlock(unsigned int Value) -{ - int temp; - - Draw_Block_Value_Macro[4] = Value >> 8; - Draw_Block_Value_Macro[5] = Value & 0xFF; - LCD_MEM[LcdTableAddress] = Value; - - halLcdSendCommand(Draw_Block_Value_Macro); - - LcdAddress++; - temp = LcdAddress >> 5; // Divided by 0x20 - temp = temp + (temp << 4); - //Multiplied by (1+16) and added by the offset - LcdTableAddress = temp + (LcdAddress & 0x1F); - - // If LcdAddress gets off the right edge, move to next line - if ((LcdAddress & 0x1F) > 0x10) - halLcdSetAddress((LcdAddress & 0xFFE0) + 0x20); - - if (LcdAddress >= LCD_Size) - halLcdSetAddress(0); -} - -/**********************************************************************//** - * @brief Displays the string to the LCD starting at current location. - * - * Writes all the data to LCD_MEM first, then updates all corresponding - * LCD CGRAM locations at once, in a continuous fashion. - * - * @param String[] The string to be displayed on LCD. - * - * @param TextStyle Value that specifies whether the string is to be - * inverted or overwritten. - * - Invert = 0x01 - * - Overwrite = 0x04 - * - * @return none - *************************************************************************/ - -void halLcdPrint(char String[], unsigned char TextStyle) -{ - int i, j, Counter = 0, BlockValue; - int Address, LCD_MEM_Add, ActualAddress; - int temp; - char LookUpChar; - - ActualAddress = LcdAddress; - Counter = LcdAddress & 0x1F; - i = 0; - - while (String[i] != 0) // Stop on null character - { - LookUpChar = fonts_lookup[String[i]]; - - for (j = 0; j < FONT_HEIGHT; j++) - { - Address = ActualAddress + j * 0x20; - temp = Address >> 5; - temp += (temp << 4); - - LCD_MEM_Add = temp + (Address & 0x1F); - - BlockValue = LCD_MEM[LCD_MEM_Add]; - - if (TextStyle & GRAYSCALE_TEXT) - { - if (TextStyle & INVERT_TEXT) - if (TextStyle & OVERWRITE_TEXT) - BlockValue = 0xAAAA - GrayScale_fonts[LookUpChar * (FONT_HEIGHT + 1) + j]; - else - BlockValue |= 0xAAAA - GrayScale_fonts[LookUpChar * (FONT_HEIGHT + 1) + j]; - else - if (TextStyle & OVERWRITE_TEXT) - BlockValue = GrayScale_fonts[LookUpChar * (FONT_HEIGHT + 1) + j]; - else - BlockValue |= GrayScale_fonts[LookUpChar * (FONT_HEIGHT + 1) + j]; - } - else - { - if (TextStyle & INVERT_TEXT) - if (TextStyle & OVERWRITE_TEXT) - BlockValue = 0xFFFF - fonts[LookUpChar * 13 + j]; - else - BlockValue |= 0xFFFF - fonts[LookUpChar * 13 + j]; - - else - if (TextStyle & OVERWRITE_TEXT) - BlockValue = fonts[LookUpChar * (FONT_HEIGHT + 1) + j]; - else - BlockValue |= fonts[LookUpChar * (FONT_HEIGHT + 1) + j]; - } - halLcdDrawBlock(Address, BlockValue); - } - - Counter++; - if (Counter == 17) - { - Counter = 0; - ActualAddress += 0x20 * FONT_HEIGHT - 16; - if (ActualAddress > LCD_Last_Pixel - 0x20 * FONT_HEIGHT) - ActualAddress = 0; - } - else - ActualAddress++; - i++; - } - halLcdSetAddress(ActualAddress); - -} - -/**********************************************************************//** - * @brief Displays the string to the LCD starting at (x,y) location. - * - * Writes all the data to LCD_MEM first, then updates all corresponding - * LCD CGRAM locations at once, in a continuous fashion. - * - * @param String[] String to be displayed on LCD - * - * @param x x-coordinate of the write location on the LCD - * - * @param y y-coordinate of the write location on the LCD - * - * @param TextStyle Value that specifies whether the string is to be - * inverted or overwritten. - * - Invert = 0x01 - * - Overwrite = 0x04 - *************************************************************************/ - -void halLcdPrintXY(char String[], int x, int y, unsigned char TextStyle) -{ - //Each line increments by 0x20 - halLcdSetAddress((y << 5) + (x >> 3)); //Narrow down to 8 possible pixels - halLcdPrint(String, TextStyle); -} - -/**********************************************************************//** - * @brief Displays a string on the LCD on the specified line. - * - * @param String[] The string to be displayed on LCD. - * - * @param Line The line on the LCD on which to print the string. - * - * @param TextStyle Value that specifies whether the string is to be - * inverted or overwritten. - * - Invert = 0x01 - * - Overwrite = 0x04 - * - * @return none - *************************************************************************/ - -void halLcdPrintLine(char String[], unsigned char Line, unsigned char TextStyle) -{ - int temp; - - temp = Line * FONT_HEIGHT; - halLcdSetAddress(temp << 5); // 0x20 = 2^5 - halLcdPrint(String, TextStyle); -} - -/**********************************************************************//** - * @brief Prints a string beginning on a given line and column. - * - * @param String[] The string to be displayed on LCD. - * - * @param Line The line on which to print the string of text - * - * @param Col The column on which to print the string of text - * - * @param TextStyle Value that specifies whether the string is to be - * inverted or overwritten. - * - Invert = 0x01 - * - Overwrite = 0x04 - * - * @return none - *************************************************************************/ - -void halLcdPrintLineCol(char String[], unsigned char Line, unsigned char Col, - unsigned char TextStyle) -{ - int temp; - - temp = Line * FONT_HEIGHT; - temp <<= 5; - temp += Col; - - halLcdSetAddress(temp); // 0x20 = 2^5 - halLcdPrint(String, TextStyle); -} - -/**********************************************************************//** - * @brief Draws a horizontral line from (x1,y) to (x2,y) of GrayScale level - * - * @param x1 x-coordinate of the first point - * - * @param x2 x-coordinate of the second point - * - * @param y y-coordinate of both points - * - * @param GrayScale Grayscale level of the horizontal line - * - * @return none - *************************************************************************/ - -void halLcdHLine(int x1, int x2, int y, unsigned char GrayScale) -{ - int x_dir, x; - - if (x1 < x2) - x_dir = 1; - else - x_dir = -1; - x = x1; - while (x != x2) - { - halLcdPixel(x, y, GrayScale); - x += x_dir; - } -} - -/**********************************************************************//** - * @brief Draws a vertical line from (x,y1) to (x,y2) of GrayScale level - * - * @param x x-coordinate of both points - * - * @param y1 y-coordinate of the first point - * - * @param y2 y-coordinate of the second point - * - * @param GrayScale GrayScale level of the vertical line - * - * @return none - *************************************************************************/ - -void halLcdVLine(int x, int y1, int y2, unsigned char GrayScale) -{ - int y_dir, y; - - if (y1 < y2) - y_dir = 1; - else - y_dir = -1; - y = y1; - while (y != y2) - { - halLcdPixel(x, y, GrayScale); - y += y_dir; - } -} - -/**********************************************************************//** - * @brief Draws a line from (x1,y1) to (x2,y2) of GrayScale level. - * - * Uses Bresenham's line algorithm. - * - * @param x1 x-coordinate of the first point - * - * @param y1 y-coordinate of the first point - * - * @param x2 x-coordinate of the second point - * - * @param y2 y-coordinate of the second point - * - * @param GrayScale Grayscale level of the line - * - * @return none - *************************************************************************/ - -void halLcdLine(int x1, int y1, int x2, int y2, unsigned char GrayScale) -{ - int x, y, deltay, deltax, d; - int x_dir, y_dir; - - if (x1 == x2) - halLcdVLine(x1, y1, y2, GrayScale); - else - { - if (y1 == y2) - halLcdHLine(x1, x2, y1, GrayScale); - else // a diagonal line - { - if (x1 > x2) - x_dir = -1; - else x_dir = 1; - if (y1 > y2) - y_dir = -1; - else y_dir = 1; - - x = x1; - y = y1; - deltay = ABS(y2 - y1); - deltax = ABS(x2 - x1); - - if (deltax >= deltay) - { - d = (deltay << 1) - deltax; - while (x != x2) - { - halLcdPixel(x, y, GrayScale); - if (d < 0) - d += (deltay << 1); - else - { - d += ((deltay - deltax) << 1); - y += y_dir; - } - x += x_dir; - } - } - else - { - d = (deltax << 1) - deltay; - while (y != y2) - { - halLcdPixel(x, y, GrayScale); - if (d < 0) - d += (deltax << 1); - else - { - d += ((deltax - deltay) << 1); - x += x_dir; - } - y += y_dir; - } - } - } - } -} - -/**********************************************************************//** - * @brief Draw a circle of Radius with center at (x,y) of GrayScale level. - * - * Uses Bresenham's circle algorithm - * - * @param x x-coordinate of the circle's center point - * - * @param y y-coordinate of the circle's center point - * - * @param Radius Radius of the circle - * - * @param GrayScale Grayscale level of the circle - *************************************************************************/ - -void halLcdCircle(int x, int y, int Radius, int GrayScale) -{ - int xx, yy, ddF_x, ddF_y, f; - - ddF_x = 0; - ddF_y = -(2 * Radius); - f = 1 - Radius; - - xx = 0; - yy = Radius; - halLcdPixel(x + xx, y + yy, GrayScale); - halLcdPixel(x + xx, y - yy, GrayScale); - halLcdPixel(x - xx, y + yy, GrayScale); - halLcdPixel(x - xx, y - yy, GrayScale); - halLcdPixel(x + yy, y + xx, GrayScale); - halLcdPixel(x + yy, y - xx, GrayScale); - halLcdPixel(x - yy, y + xx, GrayScale); - halLcdPixel(x - yy, y - xx, GrayScale); - while (xx < yy) - { - if (f >= 0) - { - yy--; - ddF_y += 2; - f += ddF_y; - } - xx++; - ddF_x += 2; - f += ddF_x + 1; - halLcdPixel(x + xx, y + yy, GrayScale); - halLcdPixel(x + xx, y - yy, GrayScale); - halLcdPixel(x - xx, y + yy, GrayScale); - halLcdPixel(x - xx, y - yy, GrayScale); - halLcdPixel(x + yy, y + xx, GrayScale); - halLcdPixel(x + yy, y - xx, GrayScale); - halLcdPixel(x - yy, y + xx, GrayScale); - halLcdPixel(x - yy, y - xx, GrayScale); - } -} - -/**********************************************************************//** - * @brief Scrolls a single row of pixels one column to the left. - * - * The column that is scrolled out of the left side of the LCD will be - * displayed the right side of the LCD. - * - * @param y The row of pixels to scroll. y = 0 is at the top-left - * corner of the LCD. - * - * @return none - *************************************************************************/ - -void halLcdScrollRow(int y) -{ - int i, Address, LcdTableAddressTemp; - unsigned int temp; - - Address = y << 5; - - halLcdSetAddress(Address); - - //Multiplied by (1+16) and added by the offset - LcdTableAddressTemp = y + (y << 4); - temp = ((LCD_MEM[LcdTableAddressTemp] & 0x0003) << 14); - - for (i = 0; i < 0x10; i++) - halLcdDrawCurrentBlock(((LCD_MEM[LcdTableAddressTemp + i] & 0xFFFC) >> 2) \ - + ((LCD_MEM[LcdTableAddressTemp + i + 1] & 0x0003) << 14)); - - halLcdDrawCurrentBlock(((LCD_MEM[LcdTableAddressTemp + 0x10] & 0xFFFC) >> 2) + temp); -} - -/**********************************************************************//** - * @brief Scrolls multiple rows of pixels, yStart to yEnd, - * one column to the left. - * - * The column that is scrolled out of the left side of the LCD will be - * displayed the right side of the LCD. y = 0 is at the top-left of the - * LCD screen. - * - * @param yStart The beginning row to be scrolled - * - * @param yEnd The last row to be scrolled - * - * @return none - *************************************************************************/ - -void halLcdHScroll(int yStart, int yEnd) -{ - int i; - - for (i = yStart; i < yEnd + 1; i++) - halLcdScrollRow(i); -} - -/**********************************************************************//** - * @brief Scrolls a line of text one column to the left. - * - * @param Line The line of text to be scrolled. - * - * @return none - *************************************************************************/ - -void halLcdScrollLine(int Line) -{ - int i, Row; - - Row = Line * FONT_HEIGHT; - - for (i = Row; i < Row + FONT_HEIGHT; i++) - halLcdScrollRow(i); -} - +/******************************************************************************* + * + * hal_lcd.c + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * 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 Texas Instruments Incorporated 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 + * OWNER 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. + * + ******************************************************************************/ + +#include "contiki-conf.h" +#include "core/sys/cc.h" + +#include "hal_MSP-EXP430F5438.h" +#include "hal_lcd_fonts.h" + +unsigned char LcdInitMacro[] = { + 0x74, 0x00, 0x00, 0x76, 0x00, 0x01, // R00 start oscillation + 0x74, 0x00, 0x01, 0x76, 0x00, 0x0D, // R01 driver output control + 0x74, 0x00, 0x02, 0x76, 0x00, 0x4C, // R02 LCD - driving waveform control + 0x74, 0x00, 0x03, 0x76, 0x12, 0x14, // R03 Power control + 0x74, 0x00, 0x04, 0x76, 0x04, 0x66, // R04 Contrast control + 0x74, 0x00, 0x05, 0x76, 0x00, 0x10, // R05 Entry mode + 0x74, 0x00, 0x06, 0x76, 0x00, 0x00, // R06 RAM data write mask + 0x74, 0x00, 0x07, 0x76, 0x00, 0x15, // R07 Display control + 0x74, 0x00, 0x08, 0x76, 0x00, 0x03, // R08 Cursor Control + 0x74, 0x00, 0x09, 0x76, 0x00, 0x00, // R09 RAM data write mask + 0x74, 0x00, 0x0A, 0x76, 0x00, 0x15, // R0A + 0x74, 0x00, 0x0B, 0x76, 0x00, 0x03, // R0B Horizontal Cursor Position + 0x74, 0x00, 0x0C, 0x76, 0x00, 0x03, // R0C Vertical Cursor Position + 0x74, 0x00, 0x0D, 0x76, 0x00, 0x00, // R0D + 0x74, 0x00, 0x0E, 0x76, 0x00, 0x15, // R0E + 0x74, 0x00, 0x0F, 0x76, 0x00, 0x03, // R0F + 0x74, 0x00, 0x10, 0x76, 0x00, 0x15, // R0E + 0x74, 0x00, 0x11, 0x76, 0x00, 0x03, // R0F +}; + +unsigned char Read_Block_Address_Macro[] = {0x74, 0x00, 0x12, 0x77, 0x00, 0x00}; +unsigned char Draw_Block_Value_Macro[] = {0x74, 0x00, 0x12, 0x76, 0xFF, 0xFF}; +unsigned char Draw_Block_Address_Macro[] = {0x74, 0x00, 0x11, 0x76, 0x00, 0x00}; + +unsigned int LcdAddress = 0, LcdTableAddress = 0; +unsigned char contrast = 0x66; +unsigned char backlight = 8; +int LCD_MEM[110 * 17]; //This array stores a copy of all data on the LCD +//screen. If memory is an issue though, this array +//can be eliminated and the halLcdReadBlock() +//command can be used instead whenever you are +//manipulating the currently displayed data. + +/**********************************************************************//** + * @brief Sends 3+3 bytes of data to the LCD using the format specified + * by the LCD Guide. + * + * @param Data[] Data array for transmission + * + * @return none + *************************************************************************/ + +void halLcdSendCommand(unsigned char Data[]) +{ + unsigned char i; + + LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer + for (i = 0; i < 6; i++) + { + while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG + UCB2TXBUF = Data[i]; // Load data + + if (i == 2) //Pull CS up after 3 bytes + { + while (UCB2STAT & UCBUSY) ; + LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer + LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer + } + } + while (UCB2STAT & UCBUSY) ; + LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer +} + +/**********************************************************************//** + * @brief Initializes the USCI module, LCD device for communication. + * + * - Sets up the SPI2C Communication Module + * - Performs Hitachi LCD Initialization Procedure + * + * @param none + * + * @return none + *************************************************************************/ + +void halLcdInit(void) +{ + LCD_CS_RST_OUT |= LCD_CS_PIN | LCD_RESET_PIN; + LCD_CS_RST_DIR |= LCD_CS_PIN | LCD_RESET_PIN; + + LCD_BACKLT_SEL |= LCD_BACKLIGHT_PIN; + + LCD_CS_RST_OUT &= ~LCD_RESET_PIN; // Reset LCD + __delay_cycles(0x47FF); //Reset Pulse + LCD_CS_RST_OUT |= LCD_RESET_PIN; + + // UCLK,MOSI setup, SOMI cleared + LCD_SPI_SEL |= LCD_MOSI_PIN + LCD_CLK_PIN; + LCD_SPI_SEL &= ~LCD_MISO_PIN; + LCD_SPI_DIR &= ~(LCD_MISO_PIN + LCD_MOSI_PIN); // Pin direction controlled by module, + // Set both pins to input as default + + // Initialize the USCI_B2 module for SPI operation + UCB2CTL1 = UCSWRST; // Hold USCI in SW reset mode while configuring + // it + UCB2CTL0 = UCMST + UCSYNC + UCCKPL + UCMSB; // 3-pin, 8-bit SPI master + UCB2CTL1 |= UCSSEL_2; // SMCLK + UCB2BR0 = 4; // Note: Do not exceed D/S spec for UCLK! + UCB2BR1 = 0; + UCB2CTL1 &= ~UCSWRST; // Release USCI state machine + UCB2IFG &= ~UCRXIFG; + + // Wake-up the LCD as per datasheet specifications + halLcdActive(); + + // LCD Initialization Routine Using Predefined Macros + halLcdSendCommand(&LcdInitMacro[1 * 6]); + halLcdSendCommand(&LcdInitMacro[2 * 6]); + halLcdSendCommand(&LcdInitMacro[4 * 6]); + halLcdSendCommand(&LcdInitMacro[5 * 6]); + halLcdSendCommand(&LcdInitMacro[6 * 6]); + halLcdSendCommand(&LcdInitMacro[7 * 6]); + +} + +/**********************************************************************//** + * @brief Shuts down the LCD display and hdisables the USCI communication. + * + * @param none + * + * @return none + *************************************************************************/ + +void halLcdShutDown(void) +{ + halLcdStandby(); + + LCD_CS_RST_DIR |= LCD_CS_PIN | LCD_RESET_PIN; + LCD_CS_RST_OUT &= ~(LCD_CS_PIN | LCD_RESET_PIN); + LCD_CS_RST_OUT &= ~LCD_RESET_PIN; + + LCD_SPI_SEL &= ~(LCD_MOSI_PIN + LCD_CLK_PIN + LCD_MISO_PIN); + LCD_CS_RST_DIR |= LCD_MOSI_PIN + LCD_CLK_PIN + LCD_MISO_PIN; + LCD_CS_RST_OUT &= ~(LCD_MOSI_PIN + LCD_CLK_PIN + LCD_MISO_PIN); + + UCB2CTL0 = UCSWRST; +} + +/**********************************************************************//** + * @brief Initializes the LCD backlight PWM signal. + * + * @param none + * + * @return none + * + *************************************************************************/ + +void halLcdBackLightInit(void) +{ + LCD_BACKLT_DIR |= LCD_BACKLIGHT_PIN; + LCD_BACKLT_OUT |= LCD_BACKLIGHT_PIN; + LCD_BACKLT_SEL |= LCD_BACKLIGHT_PIN; + + TA0CCTL3 = OUTMOD_7; + TA0CCR3 = TA0CCR0 >> 1; + backlight = 8; + + TA0CCR0 = 400; + TA0CTL = TASSEL_2 + MC_1; +} + +/**********************************************************************//** + * @brief Get function for the backlight PWM's duty cycle. + * + * @param none + * + * @return backlight One of the the 17 possible settings - valued 0 to 16. + * + *************************************************************************/ + +unsigned int halLcdGetBackLight(void) +{ + return backlight; +} + +/**********************************************************************//** + * @brief Set function for the backlight PWM's duty cycle + * + * @param BackLightLevel The target backlight duty cycle - valued 0 to 16. + * + * @return none + *************************************************************************/ + +void halLcdSetBackLight(unsigned char BackLightLevel) +{ + unsigned int dutyCycle = 0, i, dummy; + + if (BackLightLevel > 0) + { + TA0CCTL3 = OUTMOD_7; + dummy = (TA0CCR0 >> 4); + + for (i = 0; i < BackLightLevel; i++) + dutyCycle += dummy; + + TA0CCR3 = dutyCycle; + + // If the backlight was previously turned off, turn it on. + if (!backlight) + TA0CTL |= MC0; + } + else + { + TA0CCTL3 = 0; + TA0CTL &= ~MC0; + } + backlight = BackLightLevel; +} + +/**********************************************************************//** + * @brief Turns off the backlight. + * + * Clears the respective GPIO and timer settings. + * + * @param none + * + * @return none + *************************************************************************/ + +void halLcdShutDownBackLight(void) +{ + LCD_BACKLT_DIR |= LCD_BACKLIGHT_PIN; + LCD_BACKLT_OUT &= ~(LCD_BACKLIGHT_PIN); + LCD_BACKLT_SEL &= ~LCD_BACKLIGHT_PIN; + + TA0CCTL3 = 0; + TA0CTL = 0; + + backlight = 0; +} + +/**********************************************************************//** + * @brief Set function for the contrast level of the LCD. + * + * @param ContrastLevel The target contrast level + * + * @return none + *************************************************************************/ + +void halLcdSetContrast(unsigned char ContrastLevel) +{ + if (ContrastLevel > 127) ContrastLevel = 127; + if (ContrastLevel < 70) ContrastLevel = 70; + LcdInitMacro[0x04 * 6 + 5] = ContrastLevel; + halLcdSendCommand(&LcdInitMacro[0x04 * 6]); +} + +/**********************************************************************//** + * @brief Get function for the contrast level of the LCD. + * + * @param none + * + * @return ContrastLevel The LCD constrast level + *************************************************************************/ + +unsigned char halLcdGetContrast(void) +{ + return LcdInitMacro[0x04 * 6 + 5]; +} + +/**********************************************************************//** + * @brief Turns the LCD cursor on at the current text position. + * + * @param none + * + * @return none + *************************************************************************/ + +void halLcdCursor(void) +{ + LcdInitMacro[8 * 6 + 5] ^= BIT2; + halLcdSendCommand(&LcdInitMacro[8 * 6]); + + LcdInitMacro[0x0B * 6 + 5] = ((LcdAddress & 0x1F) << 3); + LcdInitMacro[0x0B * 6 + 4] = ((LcdAddress & 0x1F) << 3) + 3; + LcdInitMacro[0x0C * 6 + 5] = (LcdAddress >> 5); + LcdInitMacro[0x0C * 6 + 4] = (LcdAddress >> 5) + 7; + halLcdSendCommand(&LcdInitMacro[0x0B * 6]); + halLcdSendCommand(&LcdInitMacro[0x0C * 6]); + + halLcdSetAddress(LcdAddress); +} + +/**********************************************************************//** + * @brief Turns off the LCD cursor. + * + * @param none + * + * @return none + *************************************************************************/ + +void halLcdCursorOff(void) +{ + LcdInitMacro[8 * 6 + 5] &= ~BIT2; + halLcdSendCommand(&LcdInitMacro[8 * 6]); +} + +/**********************************************************************//** + * @brief Inverts the grayscale values of the LCD display (Black <> white). + * + * @param none + * + * @return none + *************************************************************************/ + +void halLcdReverse(void) +{ + LcdInitMacro[7 * 6 + 5] ^= BIT1; + halLcdSendCommand(&LcdInitMacro[7 * 6]); +} + +/**********************************************************************//** + * @brief Sets the LCD in standby mode to reduce power consumption. + * + * @param none + * + * @return none + *************************************************************************/ + +void halLcdStandby(void) +{ + LcdInitMacro[3 * 6 + 5] &= (~BIT3) & (~BIT2); + LcdInitMacro[3 * 6 + 5] |= BIT0; + halLcdSendCommand(&LcdInitMacro[3 * 6]); +} + +/**********************************************************************//** + * @brief Puts the LCD into active mode. + * + * @param none + * + * @return none + *************************************************************************/ + +void halLcdActive(void) +{ + halLcdSendCommand(LcdInitMacro); // R00 start oscillation + + // Wait a minimum of 25ms after issuing "start oscillation" + // command (to accomodate for MCLK up to 25MHz) + { + int i; + for(i = 0; i < 5; ++i) { + __delay_cycles(50000); + } + } + + LcdInitMacro[3 * 6 + 5] |= BIT3; + LcdInitMacro[3 * 6 + 5] &= ~BIT0; + halLcdSendCommand(&LcdInitMacro[3 * 6]); // R03 Power control +} + +/**********************************************************************//** + * @brief Sets the pointer location in the LCD. + * + * - LcdAddress = Address + * - LcdTableAddress = Correct Address Row + Column + * = (Address / 0x20)* 17 + Column + * + * @param Address The target pointer location in the LCD. + * + * @return none + *************************************************************************/ + +void halLcdSetAddress(int Address) +{ + int temp; + + Draw_Block_Address_Macro[4] = Address >> 8; + Draw_Block_Address_Macro[5] = Address & 0xFF; + halLcdSendCommand(Draw_Block_Address_Macro); + LcdAddress = Address; + temp = Address >> 5; // Divided by 0x20 + temp = temp + (temp << 4); + //Multiplied by (1+16) and added by the offset + LcdTableAddress = temp + (Address & 0x1F); +} + +/**********************************************************************//** + * @brief Draws a block at the specified LCD address. + * + * A block is the smallest addressable memory on the LCD and is + * equivalent to 8 pixels, each of which is represented by 2 bits + * that represent a grayscale value between 00b and 11b. + * + * @param Address The address at which to draw the block. + * + * @param Value The value of the block + * + * @return none + *************************************************************************/ + +void halLcdDrawBlock(unsigned int Address, unsigned int Value) +{ + halLcdSetAddress(Address); + halLcdDrawCurrentBlock(Value); +} + +/**********************************************************************//** + * @brief Writes Value to LCD CGram and MSP430 internal LCD table. + * + * Also updates the LcdAddress and LcdTableAddress to the correct values. + * + * @param Value The value of the block to be written to the LCD. + * + * @return none + *************************************************************************/ + +void halLcdDrawCurrentBlock(unsigned int Value) +{ + int temp; + + Draw_Block_Value_Macro[4] = Value >> 8; + Draw_Block_Value_Macro[5] = Value & 0xFF; + LCD_MEM[LcdTableAddress] = Value; + + halLcdSendCommand(Draw_Block_Value_Macro); + + LcdAddress++; + temp = LcdAddress >> 5; // Divided by 0x20 + temp = temp + (temp << 4); + // Multiplied by (1+16) and added by the offset + LcdTableAddress = temp + (LcdAddress & 0x1F); + + // If LcdAddress gets off the right edge, move to next line + if ((LcdAddress & 0x1F) > 0x11) + halLcdSetAddress((LcdAddress & 0xFFE0) + 0x20); + if (LcdAddress == LCD_Size) + halLcdSetAddress(0); +} + +/**********************************************************************//** + * @brief Returns the LCD CGRAM value at location Address. + * + * @param Address The address of the block to be read from the LCD. + * + * @return Value The value held at the specified address. + *************************************************************************/ + +int halLcdReadBlock(unsigned int Address) +{ + int i = 0, Value = 0, ReadData[7]; + + halLcdSetAddress(Address); + halLcdSendCommand(Read_Block_Address_Macro); + + LCD_CS_RST_OUT &= ~LCD_CS_PIN; // start transfer CS=0 + UCB2TXBUF = 0x77; // Transmit first character 0x77 + + while (!(UCB2IFG & UCTXIFG)) ; + while (UCB2STAT & UCBUSY) ; + + //Read 5 dummies values and 2 valid address data + LCD_SPI_SEL &= ~LCD_MOSI_PIN; //Change SPI2C Dir + LCD_SPI_SEL |= LCD_MISO_PIN; + + for (i = 0; i < 7; i++) + { + UCB2IFG &= ~UCRXIFG; + UCB2TXBUF = 1; // load dummy byte 1 for clk + while (!(UCB2IFG & UCRXIFG)) ; + ReadData[i] = UCB2RXBUF; + } + LCD_CS_RST_OUT |= LCD_CS_PIN; // Stop Transfer CS = 1 + + LCD_SPI_SEL |= LCD_MOSI_PIN; //Change SPI2C Dir + LCD_SPI_SEL &= ~LCD_MISO_PIN; + LCD_CS_RST_DIR |= LCD_MOSI_PIN + LCD_CLK_PIN; + LCD_CS_RST_DIR &= ~LCD_MISO_PIN; + + Value = (ReadData[5] << 8) + ReadData[6]; + return Value; +} + +/**********************************************************************//** + * @brief Draw a Pixel of grayscale at coordinate (x,y) to LCD + * + * @param x x-coordinate for grayscale value + * + * @param y y-coordinate for grayscale value + * + * @param GrayScale The intended grayscale value of the pixel - one of + * four possible settings. + * + * @return none + *************************************************************************/ + +void halLcdPixel(int x, int y, unsigned char GrayScale) +{ + int Address, Value; + unsigned char offset; + + //Each line increments by 0x20 + if ((x >= 0) && (x < LCD_COL) && (y >= 0) && (y < LCD_ROW)) + { + Address = (y << 5) + (x >> 3); //Narrow down to 8 possible pixels + + Value = LCD_MEM[(y << 4) + y + (x >> 3)]; //y * 17 --> row. x>>3 --> column + + offset = (x & 0x07) << 1; //3 LSBs = pos. within the 8 columns + Value &= ~(3 << offset); //clear out the corresponding bits + Value |= GrayScale << offset; //set pixel to GrayScale level + + halLcdDrawBlock(Address, Value); + } +} + +/**********************************************************************//** + * @brief Clears entire LCD CGRAM as well as LCD_MEM. + * + * @param none + * + * @return none + *************************************************************************/ + +void halLcdClearScreen(void) +{ + int i, j, k, Current_Location = 0; + + halLcdSetAddress(0); + + for (i = 0; i < 110; i++) + { + //prepare to send image + LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer + for (k = 0; k < 3; k++) + { + while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG + UCB2TXBUF = Draw_Block_Value_Macro[k]; // Load data + } + while (UCB2STAT & UCBUSY) ; + LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer + LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer + while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG + UCB2TXBUF = Draw_Block_Value_Macro[3]; // Load data + + //send blank line + for (j = 0; j < 17; j++) + { + LCD_MEM[LcdTableAddress++] = 0x00; + while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG + UCB2TXBUF = 0x00; // Load data + while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG + UCB2TXBUF = 0x00; // Load data + } + //Clear the partially visible block at the edge of the screen + while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG + UCB2TXBUF = 0x00; // Load data + while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG + UCB2TXBUF = 0x00; // Load data + while (UCB2STAT & UCBUSY) ; + LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer + + Current_Location += 0x20; + halLcdSetAddress(Current_Location); + } + + halLcdSetAddress(0); +} + +/**********************************************************************//** + * @brief Loads an image of size = rows * columns, starting at the + * coordinate (x,y). + * + * @param Image[] The image to be loaded + * + * @param Rows The number of rows in the image. Size = Rows * Columns. + * + * @param Columns The number of columns in the image. Size = Rows * Columns. + * + * @param x x-coordinate of the image's starting location + * + * @param y y-coordinate of the image's starting location + * + * @return none + *************************************************************************/ + +void halLcdImage(const unsigned int Image[], int Columns, int Rows, int x, int y) +{ + int i, CurrentLocation; + + CurrentLocation = (y << 5) + (x >> 3); + halLcdSetAddress(CurrentLocation); + for (i = 0; i < Rows; i++) + { + halLcdDrawCurrentLine(Image, Columns); + Image += Columns; + CurrentLocation += 0x20; + halLcdSetAddress(CurrentLocation); + } +} + +/**********************************************************************//** + * @brief Writes Value to LCD CGram and MSP430 internal LCD table. + * + * Also updates the LcdAddress and LcdTableAddress to the correct values. + * + * @param *value Pointer to the line to be written to the LCD. + * + * @return none + *************************************************************************/ + +void halLcdDrawCurrentLine(const unsigned int *value, int Columns) +{ + unsigned char i; + + //prepare to send image + LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer + for (i = 0; i < 3; i++) + { + while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG + UCB2TXBUF = Draw_Block_Value_Macro[i]; // Load data + } + while (UCB2STAT & UCBUSY) ; + LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer + LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer + while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG + UCB2TXBUF = Draw_Block_Value_Macro[3]; // Load data + + //send the image + for (i = 0; i < Columns; i++) + { + // Make sure we are not writing outside LCD_MEM[] + if (LcdTableAddress >= sizeof(LCD_MEM)){ + break; + } + LCD_MEM[LcdTableAddress++] = *value; + while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG + UCB2TXBUF = (*value) >> 8; // Load data + while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG + UCB2TXBUF = (*value++) & 0xFF; // Load data + } + + while (UCB2STAT & UCBUSY) ; + LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer +} + +/**********************************************************************//** + * @brief Clears an image of size rows x columns starting at (x, y). + * + * @param Columns The size, in columns, of the image to be cleared. + * + * @param Rows The size, in rows, of the image to be cleared. + * + * @param x x-coordinate of the image to be cleared + * + * @param y y-coordinate of the image to be cleared + * + * @return none + *************************************************************************/ + +void halLcdClearImage(int Columns, int Rows, int x, int y) +{ + int i, j, k, Current_Location; + + Current_Location = (y << 5) + (x >> 3); + halLcdSetAddress(Current_Location); + + for (i = 0; i < Rows; i++) + { + //prepare to send image + LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer + for (k = 0; k < 3; k++) + { + while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG + UCB2TXBUF = Draw_Block_Value_Macro[k]; // Load data + } + while (UCB2STAT & UCBUSY) ; + LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer + LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer + while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG + UCB2TXBUF = Draw_Block_Value_Macro[3]; // Load data + + //send blank line + for (j = 0; j < Columns; j++) + { + LCD_MEM[LcdTableAddress++] = 0x00; + while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG + UCB2TXBUF = 0x00; // Load data + while (!(UCB2IFG & UCTXIFG)) ; // Wait for TXIFG + UCB2TXBUF = 0x00; // Load data + } + while (UCB2STAT & UCBUSY) ; + LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer + + Current_Location += 0x20; + halLcdSetAddress(Current_Location); + } +} + +/**********************************************************************//** + * @brief Writes Value to LCD CGRAM. Pointers internal to the LCD + * are also updated. + * + * @param Value The value to be written to the current LCD pointer + * + * @return none + *************************************************************************/ + +void halLcdDrawTextBlock(unsigned int Value) +{ + int temp; + + Draw_Block_Value_Macro[4] = Value >> 8; + Draw_Block_Value_Macro[5] = Value & 0xFF; + LCD_MEM[LcdTableAddress] = Value; + + halLcdSendCommand(Draw_Block_Value_Macro); + + LcdAddress++; + temp = LcdAddress >> 5; // Divided by 0x20 + temp = temp + (temp << 4); + //Multiplied by (1+16) and added by the offset + LcdTableAddress = temp + (LcdAddress & 0x1F); + + // If LcdAddress gets off the right edge, move to next line + if ((LcdAddress & 0x1F) > 0x10) + halLcdSetAddress((LcdAddress & 0xFFE0) + 0x20); + + if (LcdAddress >= LCD_Size) + halLcdSetAddress(0); +} + +/**********************************************************************//** + * @brief Displays the string to the LCD starting at current location. + * + * Writes all the data to LCD_MEM first, then updates all corresponding + * LCD CGRAM locations at once, in a continuous fashion. + * + * @param String[] The string to be displayed on LCD. + * + * @param TextStyle Value that specifies whether the string is to be + * inverted or overwritten. + * - Invert = 0x01 + * - Overwrite = 0x04 + * + * @return none + *************************************************************************/ + +void halLcdPrint(char String[], unsigned char TextStyle) +{ + int i, j, Counter = 0, BlockValue; + int Address, LCD_MEM_Add, ActualAddress; + int temp; + char LookUpChar; + + ActualAddress = LcdAddress; + Counter = LcdAddress & 0x1F; + i = 0; + + while (String[i] != 0) // Stop on null character + { + LookUpChar = fonts_lookup[(unsigned char)String[i]]; + + for (j = 0; j < FONT_HEIGHT; j++) + { + Address = ActualAddress + j * 0x20; + temp = Address >> 5; + temp += (temp << 4); + + LCD_MEM_Add = temp + (Address & 0x1F); + + BlockValue = LCD_MEM[LCD_MEM_Add]; + + if (TextStyle & GRAYSCALE_TEXT) + { + if (TextStyle & INVERT_TEXT) + if (TextStyle & OVERWRITE_TEXT) + BlockValue = 0xAAAA - GrayScale_fonts[LookUpChar * (FONT_HEIGHT + 1) + j]; + else + BlockValue |= 0xAAAA - GrayScale_fonts[LookUpChar * (FONT_HEIGHT + 1) + j]; + else + if (TextStyle & OVERWRITE_TEXT) + BlockValue = GrayScale_fonts[LookUpChar * (FONT_HEIGHT + 1) + j]; + else + BlockValue |= GrayScale_fonts[LookUpChar * (FONT_HEIGHT + 1) + j]; + } + else + { + if (TextStyle & INVERT_TEXT) + if (TextStyle & OVERWRITE_TEXT) + BlockValue = 0xFFFF - fonts[LookUpChar * 13 + j]; + else + BlockValue |= 0xFFFF - fonts[LookUpChar * 13 + j]; + + else + if (TextStyle & OVERWRITE_TEXT) + BlockValue = fonts[LookUpChar * (FONT_HEIGHT + 1) + j]; + else + BlockValue |= fonts[LookUpChar * (FONT_HEIGHT + 1) + j]; + } + halLcdDrawBlock(Address, BlockValue); + } + + Counter++; + if (Counter == 17) + { + Counter = 0; + ActualAddress += 0x20 * FONT_HEIGHT - 16; + if (ActualAddress > LCD_Last_Pixel - 0x20 * FONT_HEIGHT) + ActualAddress = 0; + } + else + ActualAddress++; + i++; + } + halLcdSetAddress(ActualAddress); + +} + +/**********************************************************************//** + * @brief Displays the string to the LCD starting at (x,y) location. + * + * Writes all the data to LCD_MEM first, then updates all corresponding + * LCD CGRAM locations at once, in a continuous fashion. + * + * @param String[] String to be displayed on LCD + * + * @param x x-coordinate of the write location on the LCD + * + * @param y y-coordinate of the write location on the LCD + * + * @param TextStyle Value that specifies whether the string is to be + * inverted or overwritten. + * - Invert = 0x01 + * - Overwrite = 0x04 + *************************************************************************/ + +void halLcdPrintXY(char String[], int x, int y, unsigned char TextStyle) +{ + //Each line increments by 0x20 + halLcdSetAddress((y << 5) + (x >> 3)); //Narrow down to 8 possible pixels + halLcdPrint(String, TextStyle); +} + +/**********************************************************************//** + * @brief Displays a string on the LCD on the specified line. + * + * @param String[] The string to be displayed on LCD. + * + * @param Line The line on the LCD on which to print the string. + * + * @param TextStyle Value that specifies whether the string is to be + * inverted or overwritten. + * - Invert = 0x01 + * - Overwrite = 0x04 + * + * @return none + *************************************************************************/ + +void halLcdPrintLine(char String[], unsigned char Line, unsigned char TextStyle) +{ + int temp; + + temp = Line * FONT_HEIGHT; + halLcdSetAddress(temp << 5); // 0x20 = 2^5 + halLcdPrint(String, TextStyle); +} + +/**********************************************************************//** + * @brief Prints a string beginning on a given line and column. + * + * @param String[] The string to be displayed on LCD. + * + * @param Line The line on which to print the string of text + * + * @param Col The column on which to print the string of text + * + * @param TextStyle Value that specifies whether the string is to be + * inverted or overwritten. + * - Invert = 0x01 + * - Overwrite = 0x04 + * + * @return none + *************************************************************************/ + +void halLcdPrintLineCol(char String[], unsigned char Line, unsigned char Col, + unsigned char TextStyle) +{ + int temp; + + temp = Line * FONT_HEIGHT; + temp <<= 5; + temp += Col; + + halLcdSetAddress(temp); // 0x20 = 2^5 + halLcdPrint(String, TextStyle); +} + +/**********************************************************************//** + * @brief Draws a horizontral line from (x1,y) to (x2,y) of GrayScale level + * + * @param x1 x-coordinate of the first point + * + * @param x2 x-coordinate of the second point + * + * @param y y-coordinate of both points + * + * @param GrayScale Grayscale level of the horizontal line + * + * @return none + *************************************************************************/ + +void halLcdHLine(int x1, int x2, int y, unsigned char GrayScale) +{ + int x_dir, x; + + if (x1 < x2) + x_dir = 1; + else + x_dir = -1; + x = x1; + while (x != x2) + { + halLcdPixel(x, y, GrayScale); + x += x_dir; + } +} + +/**********************************************************************//** + * @brief Draws a vertical line from (x,y1) to (x,y2) of GrayScale level + * + * @param x x-coordinate of both points + * + * @param y1 y-coordinate of the first point + * + * @param y2 y-coordinate of the second point + * + * @param GrayScale GrayScale level of the vertical line + * + * @return none + *************************************************************************/ + +void halLcdVLine(int x, int y1, int y2, unsigned char GrayScale) +{ + int y_dir, y; + + if (y1 < y2) + y_dir = 1; + else + y_dir = -1; + y = y1; + while (y != y2) + { + halLcdPixel(x, y, GrayScale); + y += y_dir; + } +} + +/**********************************************************************//** + * @brief Draws a line from (x1,y1) to (x2,y2) of GrayScale level. + * + * Uses Bresenham's line algorithm. + * + * @param x1 x-coordinate of the first point + * + * @param y1 y-coordinate of the first point + * + * @param x2 x-coordinate of the second point + * + * @param y2 y-coordinate of the second point + * + * @param GrayScale Grayscale level of the line + * + * @return none + *************************************************************************/ + +void halLcdLine(int x1, int y1, int x2, int y2, unsigned char GrayScale) +{ + int x, y, deltay, deltax, d; + int x_dir, y_dir; + + if (x1 == x2) + halLcdVLine(x1, y1, y2, GrayScale); + else + { + if (y1 == y2) + halLcdHLine(x1, x2, y1, GrayScale); + else // a diagonal line + { + if (x1 > x2) + x_dir = -1; + else x_dir = 1; + if (y1 > y2) + y_dir = -1; + else y_dir = 1; + + x = x1; + y = y1; + deltay = ABS(y2 - y1); + deltax = ABS(x2 - x1); + + if (deltax >= deltay) + { + d = (deltay << 1) - deltax; + while (x != x2) + { + halLcdPixel(x, y, GrayScale); + if (d < 0) + d += (deltay << 1); + else + { + d += ((deltay - deltax) << 1); + y += y_dir; + } + x += x_dir; + } + } + else + { + d = (deltax << 1) - deltay; + while (y != y2) + { + halLcdPixel(x, y, GrayScale); + if (d < 0) + d += (deltax << 1); + else + { + d += ((deltax - deltay) << 1); + x += x_dir; + } + y += y_dir; + } + } + } + } +} + +/**********************************************************************//** + * @brief Draw a circle of Radius with center at (x,y) of GrayScale level. + * + * Uses Bresenham's circle algorithm + * + * @param x x-coordinate of the circle's center point + * + * @param y y-coordinate of the circle's center point + * + * @param Radius Radius of the circle + * + * @param GrayScale Grayscale level of the circle + *************************************************************************/ + +void halLcdCircle(int x, int y, int Radius, int GrayScale) +{ + int xx, yy, ddF_x, ddF_y, f; + + ddF_x = 0; + ddF_y = -(2 * Radius); + f = 1 - Radius; + + xx = 0; + yy = Radius; + halLcdPixel(x + xx, y + yy, GrayScale); + halLcdPixel(x + xx, y - yy, GrayScale); + halLcdPixel(x - xx, y + yy, GrayScale); + halLcdPixel(x - xx, y - yy, GrayScale); + halLcdPixel(x + yy, y + xx, GrayScale); + halLcdPixel(x + yy, y - xx, GrayScale); + halLcdPixel(x - yy, y + xx, GrayScale); + halLcdPixel(x - yy, y - xx, GrayScale); + while (xx < yy) + { + if (f >= 0) + { + yy--; + ddF_y += 2; + f += ddF_y; + } + xx++; + ddF_x += 2; + f += ddF_x + 1; + halLcdPixel(x + xx, y + yy, GrayScale); + halLcdPixel(x + xx, y - yy, GrayScale); + halLcdPixel(x - xx, y + yy, GrayScale); + halLcdPixel(x - xx, y - yy, GrayScale); + halLcdPixel(x + yy, y + xx, GrayScale); + halLcdPixel(x + yy, y - xx, GrayScale); + halLcdPixel(x - yy, y + xx, GrayScale); + halLcdPixel(x - yy, y - xx, GrayScale); + } +} + +/**********************************************************************//** + * @brief Scrolls a single row of pixels one column to the left. + * + * The column that is scrolled out of the left side of the LCD will be + * displayed the right side of the LCD. + * + * @param y The row of pixels to scroll. y = 0 is at the top-left + * corner of the LCD. + * + * @return none + *************************************************************************/ + +void halLcdScrollRow(int y) +{ + int i, Address, LcdTableAddressTemp; + unsigned int temp; + + Address = y << 5; + + halLcdSetAddress(Address); + + //Multiplied by (1+16) and added by the offset + LcdTableAddressTemp = y + (y << 4); + temp = ((LCD_MEM[LcdTableAddressTemp] & 0x0003) << 14); + + for (i = 0; i < 0x10; i++) + halLcdDrawCurrentBlock(((LCD_MEM[LcdTableAddressTemp + i] & 0xFFFC) >> 2) \ + + ((LCD_MEM[LcdTableAddressTemp + i + 1] & 0x0003) << 14)); + + halLcdDrawCurrentBlock(((LCD_MEM[LcdTableAddressTemp + 0x10] & 0xFFFC) >> 2) + temp); +} + +/**********************************************************************//** + * @brief Scrolls multiple rows of pixels, yStart to yEnd, + * one column to the left. + * + * The column that is scrolled out of the left side of the LCD will be + * displayed the right side of the LCD. y = 0 is at the top-left of the + * LCD screen. + * + * @param yStart The beginning row to be scrolled + * + * @param yEnd The last row to be scrolled + * + * @return none + *************************************************************************/ + +void halLcdHScroll(int yStart, int yEnd) +{ + int i; + + for (i = yStart; i < yEnd + 1; i++) + halLcdScrollRow(i); +} + +/**********************************************************************//** + * @brief Scrolls a line of text one column to the left. + * + * @param Line The line of text to be scrolled. + * + * @return none + *************************************************************************/ + +void halLcdScrollLine(int Line) +{ + int i, Row; + + Row = Line * FONT_HEIGHT; + + for (i = Row; i < Row + FONT_HEIGHT; i++) + halLcdScrollRow(i); +} diff --git a/platform/exp5438/hal_lcd.h b/platform/exp5438/hal_lcd.h index 5d76c6c6a..6f2508b29 100644 --- a/platform/exp5438/hal_lcd.h +++ b/platform/exp5438/hal_lcd.h @@ -1,159 +1,147 @@ -/******************************************************************************* - * - * hal_lcd.h - * - * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ - * - * 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 Texas Instruments Incorporated 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 - * OWNER 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. - * - ******************************************************************************/ - -#ifndef HAL_LCD_H -#define HAL_LCD_H - -#ifndef MIN -# define MIN(n, m) (((n) < (m)) ? (n) : (m)) -#endif - -#ifndef MAX -# define MAX(n, m) (((n) < (m)) ? (m) : (n)) -#endif - -#ifndef ABS -# define ABS(n) (((n) < 0) ? -(n) : (n)) -#endif - -#define LCD_BACKLT_OUT P8OUT -#define LCD_BACKLT_DIR P8DIR -#define LCD_BACKLT_SEL P8SEL -#define LCD_BACKLIGHT_PIN BIT3 -#define LCD_CS_RST_DIR P9DIR -#define LCD_CS_RST_OUT P9OUT -#define LCD_CS_PIN BIT6 -#define LCD_RESET_PIN BIT7 -#define LCD_SPI_SEL P9SEL -#define LCD_SPI_DIR P9DIR -#define LCD_MOSI_PIN BIT1 -#define LCD_MISO_PIN BIT2 -#define LCD_CLK_PIN BIT3 - -#define LCD_ROW 110 -#define LCD_COL 138 -#define LCD_Size 3505 -#define LCD_MEM_Size 110 * 17 -#define LCD_Max_Column_Offset 0x10 - -#define LCD_Last_Pixel 3505 - -#define LCD_MEM_Row 0x11 -#define LCD_Row 0x20 - -// Grayscale level definitions -#define PIXEL_OFF 0 -#define PIXEL_LIGHT 1 -#define PIXEL_DARK 2 -#define PIXEL_ON 3 - -#define INVERT_TEXT BIT0 -#define OVERWRITE_TEXT BIT2 -#define GRAYSCALE_TEXT BIT1 - -/*------------------------------------------------------------- - * Function Prototypes - * ------------------------------------------------------------*/ -extern void halLcdInit(void); -extern void halLcdShutDown(void); -extern void halLcdBackLightInit(void); -extern void halLcdSetBackLight(unsigned char BackLightLevel); -extern unsigned int halLcdGetBackLight(void); -extern void halLcdShutDownBackLight(void); - -extern void halLcdSendCommand(unsigned char Data[]); -extern void halLcdSetContrast(unsigned char ContrastLevel); -extern unsigned char halLcdGetContrast(void); -extern void halLcdStandby(void); -extern void halLcdActive(void); - -//Move to specified LCD address -extern void halLcdSetAddress(int Address); - -//Draw at current segment location -extern void halLcdDrawCurrentBlock(unsigned int Value); -extern void halLcdDrawCurrentLine(const unsigned int *value, int length); - -//Draw at specified location by calling -//LCD_Set_Address(Address) & LCD_Draw_Current_Block( value ) -extern void halLcdDrawBlock(unsigned int Address, unsigned int Value); - -//Read value from LCD CGRAM -extern int halLcdReadBlock(unsigned int Address); - -//Clear LCD Screen -extern void halLcdClearScreen(void); - -//Invert black to white and vice versa -extern void halLcdReverse(void); - -// Draw a Pixel @ (x,y) with GrayScale level -extern void halLcdPixel(int x, int y, unsigned char GrayScale); - -//Draw Line from (x1,y1) to (x2,y2) with GrayScale level -extern void halLcdLine(int x1, int y1, int x2, int y2, unsigned char GrayScale); -extern void halLcdHLine(int x1, int x2, int y, unsigned char GrayScale); -extern void halLcdVLine(int x1, int x2, int y, unsigned char GrayScale); - -extern void halLcdCircle(int x, int y, int Radius, int GrayScale); - -extern void halLcdImage(const unsigned int Image[], int Columns, int Rows, int x, int y); -extern void halLcdClearImage(int Columns, int Rows, int x, int y); - -//Print String of Length starting at current LCD location -extern void halLcdPrint(char String[], unsigned char TextStyle); - -//Print String of Length starting at (x,y) -extern void halLcdPrintXY(char String[], int x, int y, unsigned char TextStyle); - -//Print String of Length starting at (x,y) -extern void halLcdPrintLine(char String[], unsigned char Line, unsigned char TextStyle); -extern void halLcdPrintLineCol(char String[], unsigned char Line, unsigned char Col, - unsigned char TextStyle); - -extern void halLcdCursor(void); -extern void halLcdCursorOff(void); - -//Scroll a single row of pixels -extern void halLcdScrollRow(int y); - -//Scroll a number of consecutive rows from yStart to yEnd -extern void halLcdHScroll(int yStart, int yEnd); - -//Scroll a line of text -extern void halLcdScrollLine(int Line); - -#endif /* HAL_LCD_H */ +/******************************************************************************* + * + * hal_lcd.h + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * 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 Texas Instruments Incorporated 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 + * OWNER 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. + * + ******************************************************************************/ + +#ifndef HAL_LCD_H +#define HAL_LCD_H + +#define LCD_BACKLT_OUT P8OUT +#define LCD_BACKLT_DIR P8DIR +#define LCD_BACKLT_SEL P8SEL +#define LCD_BACKLIGHT_PIN BIT3 +#define LCD_CS_RST_DIR P9DIR +#define LCD_CS_RST_OUT P9OUT +#define LCD_CS_PIN BIT6 +#define LCD_RESET_PIN BIT7 +#define LCD_SPI_SEL P9SEL +#define LCD_SPI_DIR P9DIR +#define LCD_MOSI_PIN BIT1 +#define LCD_MISO_PIN BIT2 +#define LCD_CLK_PIN BIT3 + +#define LCD_ROW 110 +#define LCD_COL 138 +#define LCD_Size 3505 +#define LCD_MEM_Size 110 * 17 +#define LCD_Max_Column_Offset 0x10 + +#define LCD_Last_Pixel 3505 + +#define LCD_MEM_Row 0x11 +#define LCD_Row 0x20 + +// Grayscale level definitions +#define PIXEL_OFF 0 +#define PIXEL_LIGHT 1 +#define PIXEL_DARK 2 +#define PIXEL_ON 3 + +#define INVERT_TEXT BIT0 +#define OVERWRITE_TEXT BIT2 +#define GRAYSCALE_TEXT BIT1 + +/*------------------------------------------------------------- + * Function Prototypes + * ------------------------------------------------------------*/ +extern void halLcdInit(void); +extern void halLcdShutDown(void); +extern void halLcdBackLightInit(void); +extern void halLcdSetBackLight(unsigned char BackLightLevel); +extern unsigned int halLcdGetBackLight(void); +extern void halLcdShutDownBackLight(void); + +extern void halLcdSendCommand(unsigned char Data[]); +extern void halLcdSetContrast(unsigned char ContrastLevel); +extern unsigned char halLcdGetContrast(void); +extern void halLcdStandby(void); +extern void halLcdActive(void); + +//Move to specified LCD address +extern void halLcdSetAddress(int Address); + +//Draw at current segment location +extern void halLcdDrawCurrentBlock(unsigned int Value); +extern void halLcdDrawCurrentLine(const unsigned int *value, int length); + +//Draw at specified location by calling +//LCD_Set_Address(Address) & LCD_Draw_Current_Block( value ) +extern void halLcdDrawBlock(unsigned int Address, unsigned int Value); + +//Read value from LCD CGRAM +extern int halLcdReadBlock(unsigned int Address); + +//Clear LCD Screen +extern void halLcdClearScreen(void); + +//Invert black to white and vice versa +extern void halLcdReverse(void); + +// Draw a Pixel @ (x,y) with GrayScale level +extern void halLcdPixel(int x, int y, unsigned char GrayScale); + +//Draw Line from (x1,y1) to (x2,y2) with GrayScale level +extern void halLcdLine(int x1, int y1, int x2, int y2, unsigned char GrayScale); +extern void halLcdHLine(int x1, int x2, int y, unsigned char GrayScale); +extern void halLcdVLine(int x1, int x2, int y, unsigned char GrayScale); + +extern void halLcdCircle(int x, int y, int Radius, int GrayScale); + +extern void halLcdImage(const unsigned int Image[], int Columns, int Rows, int x, int y); +extern void halLcdClearImage(int Columns, int Rows, int x, int y); + +//Print String of Length starting at current LCD location +extern void halLcdPrint(char String[], unsigned char TextStyle); + +//Print String of Length starting at (x,y) +extern void halLcdPrintXY(char String[], int x, int y, unsigned char TextStyle); + +//Print String of Length starting at (x,y) +extern void halLcdPrintLine(char String[], unsigned char Line, unsigned char TextStyle); +extern void halLcdPrintLineCol(char String[], unsigned char Line, unsigned char Col, + unsigned char TextStyle); + +extern void halLcdCursor(void); +extern void halLcdCursorOff(void); + +//Scroll a single row of pixels +extern void halLcdScrollRow(int y); + +//Scroll a number of consecutive rows from yStart to yEnd +extern void halLcdHScroll(int yStart, int yEnd); + +//Scroll a line of text +extern void halLcdScrollLine(int Line); + +#endif /* HAL_LCD_H */ diff --git a/platform/exp5438/hal_lcd_fonts.c b/platform/exp5438/hal_lcd_fonts.c index 0bdb419de..4780af9d2 100644 --- a/platform/exp5438/hal_lcd_fonts.c +++ b/platform/exp5438/hal_lcd_fonts.c @@ -1,353 +1,353 @@ -/******************************************************************************* - * - * hal_lcd_fonts.c - * - * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ - * - * 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 Texas Instruments Incorporated 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 - * OWNER 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. - * - ******************************************************************************/ - -const unsigned char fonts_lookup[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 64, 65, 0, 69, 0, 68, 67, 0, 0, 1, //'0' = 48 = 0x30 - 2, 3, 4, 5, 6, 7, 8, 9, 66, 0, //'9' = 57 = 0x39 - 0, 70, 0, 62, 0, 10, 11, 12, 13, 14, //'A' --> 'Z' - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 0, 0, 0, 71, 0, 0, 36, 37, 38, //'a' = 97 - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 0, 0, 0, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81 //'z' = 122 -}; - -const unsigned int fonts[] = { - 0x0000, 0x0ffc, 0x3c0f, 0x3f0f, 0x3fcf, 0x3ccf, 0x3cff, 0x3c3f, - 0x3c0f, 0x0ffc, 0x0000, 0x0000, 0x0000, 0x0000, 0x00c0, 0x00f0, - 0x00ff, 0x00f0, 0x00f0, 0x00f0, 0x00f0, 0x00f0, 0x0fff, 0x0000, - 0x0000, 0x0000, 0x0000, 0x03fc, 0x0f0f, 0x0f0f, 0x0f00, 0x03c0, - 0x00f0, 0x003c, 0x0f0f, 0x0fff, 0x0000, 0x0000, 0x0000, 0x0000, - 0x03fc, 0x0f0f, 0x0f00, 0x0f00, 0x03f0, 0x0f00, 0x0f00, 0x0f0f, - 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f00, 0x0fc0, 0x0ff0, - 0x0f3c, 0x0f0f, 0x3fff, 0x0f00, 0x0f00, 0x3fc0, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0fff, 0x000f, 0x000f, 0x000f, 0x03ff, 0x0f00, - 0x0f00, 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, 0x03f0, - 0x003c, 0x000f, 0x000f, 0x03ff, 0x0f0f, 0x0f0f, 0x0f0f, 0x03fc, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3fff, 0x3c0f, 0x3c0f, 0x3c00, - 0x0f00, 0x03c0, 0x00f0, 0x00f0, 0x00f0, 0x0000, 0x0000, 0x0000, - 0x0000, 0x03fc, 0x0f0f, 0x0f0f, 0x0f3f, 0x03fc, 0x0fcf, 0x0f0f, - 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, 0x03fc, 0x0f0f, - 0x0f0f, 0x0f0f, 0x0ffc, 0x03c0, 0x03c0, 0x00f0, 0x00fc, 0x0000, - 0x0000, 0x0000, 0x0000, 0x00f0, 0x03fc, 0x0f0f, 0x0f0f, 0x0f0f, - 0x0fff, 0x0f0f, 0x0f0f, 0x0f0f, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0fff, 0x3c3c, 0x3c3c, 0x3c3c, 0x0ffc, 0x3c3c, 0x3c3c, 0x3c3c, - 0x0fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0ff0, 0x3c3c, 0x3c0f, - 0x000f, 0x000f, 0x000f, 0x3c0f, 0x3c3c, 0x0ff0, 0x0000, 0x0000, - 0x0000, 0x0000, 0x03ff, 0x0f3c, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, - 0x3c3c, 0x0f3c, 0x03ff, 0x0000, 0x0000, 0x0000, 0x0000, 0x3fff, - 0x303c, 0x003c, 0x0c3c, 0x0ffc, 0x0c3c, 0x003c, 0x303c, 0x3fff, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3fff, 0x3c3c, 0x303c, 0x0c3c, - 0x0ffc, 0x0c3c, 0x003c, 0x003c, 0x00ff, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0ff0, 0x3c3c, 0x3c0f, 0x000f, 0x000f, 0x3f0f, 0x3c0f, - 0x3c3c, 0x3ff0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f0f, 0x0f0f, - 0x0f0f, 0x0f0f, 0x0fff, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0000, - 0x0000, 0x0000, 0x0000, 0x03fc, 0x00f0, 0x00f0, 0x00f0, 0x00f0, - 0x00f0, 0x00f0, 0x00f0, 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3fc0, 0x0f00, 0x0f00, 0x0f00, 0x0f00, 0x0f0f, 0x0f0f, 0x0f0f, - 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c3f, 0x3c3c, 0x0f3c, - 0x0f3c, 0x03fc, 0x0f3c, 0x0f3c, 0x3c3c, 0x3c3f, 0x0000, 0x0000, - 0x0000, 0x0000, 0x00ff, 0x003c, 0x003c, 0x003c, 0x003c, 0x303c, - 0x3c3c, 0x3c3c, 0x3fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c0f, - 0x3f3f, 0x3fff, 0x3fff, 0x3ccf, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, - 0x0000, 0x0000, 0x0000, 0x0000, 0x3c0f, 0x3c0f, 0x3c3f, 0x3cff, - 0x3fff, 0x3fcf, 0x3f0f, 0x3c0f, 0x3c0f, 0x0000, 0x0000, 0x0000, - 0x0000, 0x03f0, 0x0f3c, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, - 0x0f3c, 0x03f0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0fff, 0x3c3c, - 0x3c3c, 0x3c3c, 0x0ffc, 0x003c, 0x003c, 0x003c, 0x00ff, 0x0000, - 0x0000, 0x0000, 0x0000, 0x03f0, 0x0f3c, 0x3c0f, 0x3c0f, 0x3c0f, - 0x3f0f, 0x3fcf, 0x0ffc, 0x0f00, 0x3fc0, 0x0000, 0x0000, 0x0000, - 0x0fff, 0x3c3c, 0x3c3c, 0x3c3c, 0x0ffc, 0x0f3c, 0x3c3c, 0x3c3c, - 0x3c3f, 0x0000, 0x0000, 0x0000, 0x0000, 0x03fc, 0x0f0f, 0x0f0f, - 0x000f, 0x00fc, 0x03c0, 0x0f0f, 0x0f0f, 0x03fc, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0fff, 0x0cf3, 0x00f0, 0x00f0, 0x00f0, 0x00f0, - 0x00f0, 0x00f0, 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f0f, - 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x03fc, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, - 0x0f0f, 0x0f0f, 0x0f0f, 0x03fc, 0x00f0, 0x0000, 0x0000, 0x0000, - 0x0000, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3ccf, 0x3ccf, 0x0f3c, - 0x0f3c, 0x0f3c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f0f, 0x0f0f, - 0x0f0f, 0x03fc, 0x00f0, 0x03fc, 0x0f0f, 0x0f0f, 0x0f0f, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x03fc, - 0x00f0, 0x00f0, 0x00f0, 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3fff, 0x3f0f, 0x03c3, 0x03c0, 0x00f0, 0x003c, 0x303c, 0x3c0f, - 0x3fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x03fc, 0x0f00, 0x0ffc, 0x0f0f, 0x0f0f, 0x3cfc, 0x0000, 0x0000, - 0x0000, 0x0000, 0x003f, 0x003c, 0x003c, 0x0ffc, 0x3c3c, 0x3c3c, - 0x3c3c, 0x3c3c, 0x0fcf, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x03fc, 0x0f0f, 0x000f, 0x000f, 0x0f0f, 0x03fc, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0fc0, 0x0f00, 0x0f00, 0x0ffc, - 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x3cfc, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x03fc, 0x0f0f, 0x0fff, 0x000f, - 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, 0x03f0, 0x0f3c, - 0x003c, 0x003c, 0x03ff, 0x003c, 0x003c, 0x003c, 0x00ff, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3cfc, 0x0f0f, - 0x0f0f, 0x0f0f, 0x0ffc, 0x0f00, 0x0f0f, 0x03fc, 0x0000, 0x0000, - 0x003f, 0x003c, 0x003c, 0x0f3c, 0x3cfc, 0x3c3c, 0x3c3c, 0x3c3c, - 0x3c3f, 0x0000, 0x0000, 0x0000, 0x0000, 0x03c0, 0x03c0, 0x0000, - 0x03fc, 0x03c0, 0x03c0, 0x03c0, 0x03c0, 0x3ffc, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0f00, 0x0f00, 0x0000, 0x0ff0, 0x0f00, 0x0f00, - 0x0f00, 0x0f00, 0x0f0f, 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x003f, - 0x003c, 0x003c, 0x3c3c, 0x0f3c, 0x03fc, 0x0f3c, 0x3c3c, 0x3c3f, - 0x0000, 0x0000, 0x0000, 0x0000, 0x03fc, 0x03c0, 0x03c0, 0x03c0, - 0x03c0, 0x03c0, 0x03c0, 0x03c0, 0x3ffc, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0fff, 0x3ccf, 0x3ccf, 0x3ccf, - 0x3ccf, 0x3c0f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x03ff, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03fc, 0x0f0f, - 0x0f0f, 0x0f0f, 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0fcf, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, - 0x0ffc, 0x003c, 0x00ff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3cfc, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0ffc, 0x0f00, 0x3fc0, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f3f, 0x3f3c, 0x3cfc, - 0x003c, 0x003c, 0x00ff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x03fc, 0x0f0f, 0x003c, 0x03c0, 0x0f0f, 0x03fc, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0030, 0x003c, 0x0fff, - 0x003c, 0x003c, 0x003c, 0x0f3c, 0x03f0, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, - 0x0f0f, 0x3cfc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x03fc, 0x00f0, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c0f, 0x3c0f, - 0x3ccf, 0x3ccf, 0x0f3c, 0x0f3c, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x3c0f, 0x0f3c, 0x03f0, 0x03f0, 0x0f3c, - 0x3c0f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, 0x0ff0, 0x0f00, 0x03c0, 0x00ff, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0fff, 0x0f03, 0x03c0, - 0x003c, 0x0c0f, 0x0fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x03fc, - 0x0f0f, 0x0f00, 0x03c0, 0x00f0, 0x00f0, 0x0000, 0x00f0, 0x00f0, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0f00, 0x03c0, 0x00f0, 0x003c, 0x003c, 0x003c, 0x00f0, - 0x03c0, 0x0f00, 0x0000, 0x0000, 0x0000, 0x0000, 0x003c, 0x00f0, - 0x03c0, 0x0f00, 0x0f00, 0x0f00, 0x03c0, 0x00f0, 0x003c, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03f0, 0x03f0, 0x0000, - 0x0000, 0x03f0, 0x03f0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03f0, - 0x03f0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x3ffc, 0x3ffc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x03c0, 0x03c0, 0x3ffc, 0x3ffc, - 0x03c0, 0x03c0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x3ffc, 0x0000, 0x0000, 0x3ffc, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x03fc, 0x0f0f, 0x0f0f, 0x0f0f, - 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - //0--------------------------- - 0x0000, 0x0ffc, 0x3c0f, 0x3f0f, 0x3fcf, 0x3ccf, 0x3cff, 0x3c3f, - 0x3c0f, 0x0ffc, 0x0000, 0x0000, 0x0000, - //1--------------------------- - 0x0000, 0x00c0, 0x00f0, 0x00ff, 0x00f0, 0x00f0, 0x00f0, 0x00f0, - 0x00f0, 0x0fff, 0x0000, 0x0000, 0x0000, - //2--------------------------- - 0x0000, 0x03fc, 0x0f0f, 0x0f0f, 0x0f00, 0x03c0, 0x00f0, 0x003c, - 0x0f0f, 0x0fff, 0x0000, 0x0000, 0x0000, - //3--------------------------- - 0x0000, 0x03fc, 0x0f0f, 0x0f00, 0x0f00, 0x03f0, 0x0f00, 0x0f00, - 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x0000, - //4--------------------------- - 0x0000, 0x0f00, 0x0fc0, 0x0ff0, 0x0f3c, 0x0f0f, 0x3fff, 0x0f00, - 0x0f00, 0x3fc0, 0x0000, 0x0000, 0x0000, - //5--------------------------- - 0x0000, 0x0fff, 0x000f, 0x000f, 0x000f, 0x03ff, 0x0f00, 0x0f00, - 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x0000, - //6--------------------------- - 0x0000, 0x03f0, 0x003c, 0x000f, 0x000f, 0x03ff, 0x0f0f, 0x0f0f, - 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x0000, - //7--------------------------- - 0x0000, 0x3fff, 0x3c0f, 0x3c0f, 0x3c00, 0x0f00, 0x03c0, 0x00f0, - 0x00f0, 0x00f0, 0x0000, 0x0000, 0x0000, - //8--------------------------- - 0x0000, 0x03fc, 0x0f0f, 0x0f0f, 0x0f3f, 0x03fc, 0x0fcf, 0x0f0f, - 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x0000, - //9--------------------------- - 0x0000, 0x03fc, 0x0f0f, 0x0f0f, 0x0f0f, 0x0ffc, 0x03c0, 0x03c0, - 0x00f0, 0x00fc, 0x0000, 0x0000, 0x0000, -}; - - -const unsigned int GrayScale_fonts[] = { - 0x0000, 0x0aa8, 0x280a, 0x2a0a, 0x2a8a, 0x288a, 0x28aa, 0x282a, - 0x280a, 0x0aa8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0080, 0x00a0, - 0x00aa, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x0aaa, 0x0000, - 0x0000, 0x0000, 0x0000, 0x02a8, 0x0a0a, 0x0a0a, 0x0a00, 0x0280, - 0x00a0, 0x0028, 0x0a0a, 0x0aaa, 0x0000, 0x0000, 0x0000, 0x0000, - 0x02a8, 0x0a0a, 0x0a00, 0x0a00, 0x02a0, 0x0a00, 0x0a00, 0x0a0a, - 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a00, 0x0a80, 0x0aa0, - 0x0a28, 0x0a0a, 0x2aaa, 0x0a00, 0x0a00, 0x2a80, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0aaa, 0x000a, 0x000a, 0x000a, 0x02aa, 0x0a00, - 0x0a00, 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x02a0, - 0x0028, 0x000a, 0x000a, 0x02aa, 0x0a0a, 0x0a0a, 0x0a0a, 0x02a8, - 0x0000, 0x0000, 0x0000, 0x0000, 0x2aaa, 0x280a, 0x280a, 0x2800, - 0x0a00, 0x0280, 0x00a0, 0x00a0, 0x00a0, 0x0000, 0x0000, 0x0000, - 0x0000, 0x02a8, 0x0a0a, 0x0a0a, 0x0a2a, 0x02a8, 0x0a8a, 0x0a0a, - 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x02a8, 0x0a0a, - 0x0a0a, 0x0a0a, 0x0aa8, 0x0280, 0x0280, 0x00a0, 0x00a8, 0x0000, - 0x0000, 0x0000, 0x0000, 0x00a0, 0x02a8, 0x0a0a, 0x0a0a, 0x0a0a, - 0x0aaa, 0x0a0a, 0x0a0a, 0x0a0a, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0aaa, 0x2828, 0x2828, 0x2828, 0x0aa8, 0x2828, 0x2828, 0x2828, - 0x0aaa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0aa0, 0x2828, 0x280a, - 0x000a, 0x000a, 0x000a, 0x280a, 0x2828, 0x0aa0, 0x0000, 0x0000, - 0x0000, 0x0000, 0x02aa, 0x0a28, 0x2828, 0x2828, 0x2828, 0x2828, - 0x2828, 0x0a28, 0x02aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x2aaa, - 0x2028, 0x0028, 0x0828, 0x0aa8, 0x0828, 0x0028, 0x2028, 0x2aaa, - 0x0000, 0x0000, 0x0000, 0x0000, 0x2aaa, 0x2828, 0x2028, 0x0828, - 0x0aa8, 0x0828, 0x0028, 0x0028, 0x00aa, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0aa0, 0x2828, 0x280a, 0x000a, 0x000a, 0x2a0a, 0x280a, - 0x2828, 0x2aa0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a0a, 0x0a0a, - 0x0a0a, 0x0a0a, 0x0aaa, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0000, - 0x0000, 0x0000, 0x0000, 0x02a8, 0x00a0, 0x00a0, 0x00a0, 0x00a0, - 0x00a0, 0x00a0, 0x00a0, 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, - 0x2a80, 0x0a00, 0x0a00, 0x0a00, 0x0a00, 0x0a0a, 0x0a0a, 0x0a0a, - 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x282a, 0x2828, 0x0a28, - 0x0a28, 0x02a8, 0x0a28, 0x0a28, 0x2828, 0x282a, 0x0000, 0x0000, - 0x0000, 0x0000, 0x00aa, 0x0028, 0x0028, 0x0028, 0x0028, 0x2028, - 0x2828, 0x2828, 0x2aaa, 0x0000, 0x0000, 0x0000, 0x0000, 0x280a, - 0x2a2a, 0x2aaa, 0x2aaa, 0x288a, 0x280a, 0x280a, 0x280a, 0x280a, - 0x0000, 0x0000, 0x0000, 0x0000, 0x280a, 0x280a, 0x282a, 0x28aa, - 0x2aaa, 0x2a8a, 0x2a0a, 0x280a, 0x280a, 0x0000, 0x0000, 0x0000, - 0x0000, 0x02a0, 0x0a28, 0x280a, 0x280a, 0x280a, 0x280a, 0x280a, - 0x0a28, 0x02a0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0aaa, 0x2828, - 0x2828, 0x2828, 0x0aa8, 0x0028, 0x0028, 0x0028, 0x00aa, 0x0000, - 0x0000, 0x0000, 0x0000, 0x02a0, 0x0a28, 0x280a, 0x280a, 0x280a, - 0x2a0a, 0x2a8a, 0x0aa8, 0x0a00, 0x2a80, 0x0000, 0x0000, 0x0000, - 0x0aaa, 0x2828, 0x2828, 0x2828, 0x0aa8, 0x0a28, 0x2828, 0x2828, - 0x282a, 0x0000, 0x0000, 0x0000, 0x0000, 0x02a8, 0x0a0a, 0x0a0a, - 0x000a, 0x00a8, 0x0280, 0x0a0a, 0x0a0a, 0x02a8, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0aaa, 0x08a2, 0x00a0, 0x00a0, 0x00a0, 0x00a0, - 0x00a0, 0x00a0, 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a0a, - 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x02a8, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, - 0x0a0a, 0x0a0a, 0x0a0a, 0x02a8, 0x00a0, 0x0000, 0x0000, 0x0000, - 0x0000, 0x280a, 0x280a, 0x280a, 0x280a, 0x288a, 0x288a, 0x0a28, - 0x0a28, 0x0a28, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a0a, 0x0a0a, - 0x0a0a, 0x02a8, 0x00a0, 0x02a8, 0x0a0a, 0x0a0a, 0x0a0a, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x02a8, - 0x00a0, 0x00a0, 0x00a0, 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, - 0x2aaa, 0x2a0a, 0x0282, 0x0280, 0x00a0, 0x0028, 0x2028, 0x280a, - 0x2aaa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x02a8, 0x0a00, 0x0aa8, 0x0a0a, 0x0a0a, 0x28a8, 0x0000, 0x0000, - 0x0000, 0x0000, 0x002a, 0x0028, 0x0028, 0x0aa8, 0x2828, 0x2828, - 0x2828, 0x2828, 0x0a8a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x02a8, 0x0a0a, 0x000a, 0x000a, 0x0a0a, 0x02a8, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0a80, 0x0a00, 0x0a00, 0x0aa8, - 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x28a8, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x02a8, 0x0a0a, 0x0aaa, 0x000a, - 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x02a0, 0x0a28, - 0x0028, 0x0028, 0x02aa, 0x0028, 0x0028, 0x0028, 0x00aa, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x28a8, 0x0a0a, - 0x0a0a, 0x0a0a, 0x0aa8, 0x0a00, 0x0a0a, 0x02a8, 0x0000, 0x0000, - 0x002a, 0x0028, 0x0028, 0x0a28, 0x28a8, 0x2828, 0x2828, 0x2828, - 0x282a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0280, 0x0280, 0x0000, - 0x02a8, 0x0280, 0x0280, 0x0280, 0x0280, 0x2aa8, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0a00, 0x0a00, 0x0000, 0x0aa0, 0x0a00, 0x0a00, - 0x0a00, 0x0a00, 0x0a0a, 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x002a, - 0x0028, 0x0028, 0x2828, 0x0a28, 0x02a8, 0x0a28, 0x2828, 0x282a, - 0x0000, 0x0000, 0x0000, 0x0000, 0x02a8, 0x0280, 0x0280, 0x0280, - 0x0280, 0x0280, 0x0280, 0x0280, 0x2aa8, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0aaa, 0x288a, 0x288a, 0x288a, - 0x288a, 0x280a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x02aa, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x02a8, 0x0a0a, - 0x0a0a, 0x0a0a, 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0a8a, 0x2828, 0x2828, 0x2828, 0x2828, - 0x0aa8, 0x0028, 0x00aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x28a8, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0aa8, 0x0a00, 0x2a80, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a2a, 0x2a28, 0x28a8, - 0x0028, 0x0028, 0x00aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x02a8, 0x0a0a, 0x0028, 0x0280, 0x0a0a, 0x02a8, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0028, 0x0aaa, - 0x0028, 0x0028, 0x0028, 0x0a28, 0x02a0, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, - 0x0a0a, 0x28a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x02a8, 0x00a0, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x280a, 0x280a, - 0x288a, 0x288a, 0x0a28, 0x0a28, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x280a, 0x0a28, 0x02a0, 0x02a0, 0x0a28, - 0x280a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x2828, 0x2828, 0x2828, 0x2828, 0x0aa0, 0x0a00, 0x0280, 0x00aa, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0aaa, 0x0a02, 0x0280, - 0x0028, 0x080a, 0x0aaa, 0x0000, 0x0000, 0x0000, 0x0000, 0x02a8, - 0x0a0a, 0x0a00, 0x0280, 0x00a0, 0x00a0, 0x0000, 0x00a0, 0x00a0, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0a00, 0x0280, 0x00a0, 0x0028, 0x0028, 0x0028, 0x00a0, - 0x0280, 0x0a00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0028, 0x00a0, - 0x0280, 0x0a00, 0x0a00, 0x0a00, 0x0280, 0x00a0, 0x0028, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x02a0, 0x02a0, 0x0000, - 0x0000, 0x02a0, 0x02a0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x02a0, - 0x02a0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x2aa8, 0x2aa8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0280, 0x0280, 0x2aa8, 0x2aa8, - 0x0280, 0x0280, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x2aa8, 0x0000, 0x0000, 0x2aa8, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x02a8, 0x0a0a, 0x0a0a, 0x0a0a, - 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - //0--------------------------- - 0x0000, 0x0aa8, 0x280a, 0x2a0a, 0x2a8a, 0x288a, 0x28aa, 0x282a, - 0x280a, 0x0aa8, 0x0000, 0x0000, 0x0000, - //1--------------------------- - 0x0000, 0x0080, 0x00a0, 0x00aa, 0x00a0, 0x00a0, 0x00a0, 0x00a0, - 0x00a0, 0x0aaa, 0x0000, 0x0000, 0x0000, - //2--------------------------- - 0x0000, 0x02a8, 0x0a0a, 0x0a0a, 0x0a00, 0x0280, 0x00a0, 0x0028, - 0x0a0a, 0x0aaa, 0x0000, 0x0000, 0x0000, - //2--------------------------- - 0x0000, 0x02a8, 0x0a0a, 0x0a00, 0x0a00, 0x02a0, 0x0a00, 0x0a00, - 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x0000, - //4--------------------------- - 0x0000, 0x0a00, 0x0a80, 0x0aa0, 0x0a28, 0x0a0a, 0x2aaa, 0x0a00, - 0x0a00, 0x2a80, 0x0000, 0x0000, 0x0000, - //5--------------------------- - 0x0000, 0x0aaa, 0x000a, 0x000a, 0x000a, 0x02aa, 0x0a00, 0x0a00, - 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x0000, - //6--------------------------- - 0x0000, 0x02a0, 0x0028, 0x000a, 0x000a, 0x02aa, 0x0a0a, 0x0a0a, - 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x0000, - //7--------------------------- - 0x0000, 0x2aaa, 0x280a, 0x280a, 0x2800, 0x0a00, 0x0280, 0x00a0, - 0x00a0, 0x00a0, 0x0000, 0x0000, 0x0000, - //8--------------------------- - 0x0000, 0x02a8, 0x0a0a, 0x0a0a, 0x0a2a, 0x02a8, 0x0a8a, 0x0a0a, - 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x0000, - //9--------------------------- - 0x0000, 0x02a8, 0x0a0a, 0x0a0a, 0x0a0a, 0x0aa8, 0x0280, 0x0280, - 0x00a0, 0x00a8, 0x0000, 0x0000, 0x0000, -}; +/******************************************************************************* + * + * hal_lcd_fonts.c + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * 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 Texas Instruments Incorporated 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 + * OWNER 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. + * + ******************************************************************************/ + +const unsigned char fonts_lookup[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 64, 65, 0, 69, 0, 68, 67, 0, 0, 1, //'0' = 48 = 0x30 + 2, 3, 4, 5, 6, 7, 8, 9, 66, 0, //'9' = 57 = 0x39 + 0, 70, 0, 62, 0, 10, 11, 12, 13, 14, //'A' --> 'Z' + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 0, 0, 0, 71, 0, 0, 36, 37, 38, //'a' = 97 + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 0, 0, 0, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81 //'z' = 122 +}; + +const unsigned int fonts[] = { + 0x0000, 0x0ffc, 0x3c0f, 0x3f0f, 0x3fcf, 0x3ccf, 0x3cff, 0x3c3f, + 0x3c0f, 0x0ffc, 0x0000, 0x0000, 0x0000, 0x0000, 0x00c0, 0x00f0, + 0x00ff, 0x00f0, 0x00f0, 0x00f0, 0x00f0, 0x00f0, 0x0fff, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03fc, 0x0f0f, 0x0f0f, 0x0f00, 0x03c0, + 0x00f0, 0x003c, 0x0f0f, 0x0fff, 0x0000, 0x0000, 0x0000, 0x0000, + 0x03fc, 0x0f0f, 0x0f00, 0x0f00, 0x03f0, 0x0f00, 0x0f00, 0x0f0f, + 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f00, 0x0fc0, 0x0ff0, + 0x0f3c, 0x0f0f, 0x3fff, 0x0f00, 0x0f00, 0x3fc0, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0fff, 0x000f, 0x000f, 0x000f, 0x03ff, 0x0f00, + 0x0f00, 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, 0x03f0, + 0x003c, 0x000f, 0x000f, 0x03ff, 0x0f0f, 0x0f0f, 0x0f0f, 0x03fc, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3fff, 0x3c0f, 0x3c0f, 0x3c00, + 0x0f00, 0x03c0, 0x00f0, 0x00f0, 0x00f0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x03fc, 0x0f0f, 0x0f0f, 0x0f3f, 0x03fc, 0x0fcf, 0x0f0f, + 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, 0x03fc, 0x0f0f, + 0x0f0f, 0x0f0f, 0x0ffc, 0x03c0, 0x03c0, 0x00f0, 0x00fc, 0x0000, + 0x0000, 0x0000, 0x0000, 0x00f0, 0x03fc, 0x0f0f, 0x0f0f, 0x0f0f, + 0x0fff, 0x0f0f, 0x0f0f, 0x0f0f, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0fff, 0x3c3c, 0x3c3c, 0x3c3c, 0x0ffc, 0x3c3c, 0x3c3c, 0x3c3c, + 0x0fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0ff0, 0x3c3c, 0x3c0f, + 0x000f, 0x000f, 0x000f, 0x3c0f, 0x3c3c, 0x0ff0, 0x0000, 0x0000, + 0x0000, 0x0000, 0x03ff, 0x0f3c, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, + 0x3c3c, 0x0f3c, 0x03ff, 0x0000, 0x0000, 0x0000, 0x0000, 0x3fff, + 0x303c, 0x003c, 0x0c3c, 0x0ffc, 0x0c3c, 0x003c, 0x303c, 0x3fff, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3fff, 0x3c3c, 0x303c, 0x0c3c, + 0x0ffc, 0x0c3c, 0x003c, 0x003c, 0x00ff, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0ff0, 0x3c3c, 0x3c0f, 0x000f, 0x000f, 0x3f0f, 0x3c0f, + 0x3c3c, 0x3ff0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f0f, 0x0f0f, + 0x0f0f, 0x0f0f, 0x0fff, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03fc, 0x00f0, 0x00f0, 0x00f0, 0x00f0, + 0x00f0, 0x00f0, 0x00f0, 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3fc0, 0x0f00, 0x0f00, 0x0f00, 0x0f00, 0x0f0f, 0x0f0f, 0x0f0f, + 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c3f, 0x3c3c, 0x0f3c, + 0x0f3c, 0x03fc, 0x0f3c, 0x0f3c, 0x3c3c, 0x3c3f, 0x0000, 0x0000, + 0x0000, 0x0000, 0x00ff, 0x003c, 0x003c, 0x003c, 0x003c, 0x303c, + 0x3c3c, 0x3c3c, 0x3fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c0f, + 0x3f3f, 0x3fff, 0x3fff, 0x3ccf, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3c0f, 0x3c0f, 0x3c3f, 0x3cff, + 0x3fff, 0x3fcf, 0x3f0f, 0x3c0f, 0x3c0f, 0x0000, 0x0000, 0x0000, + 0x0000, 0x03f0, 0x0f3c, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, + 0x0f3c, 0x03f0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0fff, 0x3c3c, + 0x3c3c, 0x3c3c, 0x0ffc, 0x003c, 0x003c, 0x003c, 0x00ff, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03f0, 0x0f3c, 0x3c0f, 0x3c0f, 0x3c0f, + 0x3f0f, 0x3fcf, 0x0ffc, 0x0f00, 0x3fc0, 0x0000, 0x0000, 0x0000, + 0x0fff, 0x3c3c, 0x3c3c, 0x3c3c, 0x0ffc, 0x0f3c, 0x3c3c, 0x3c3c, + 0x3c3f, 0x0000, 0x0000, 0x0000, 0x0000, 0x03fc, 0x0f0f, 0x0f0f, + 0x000f, 0x00fc, 0x03c0, 0x0f0f, 0x0f0f, 0x03fc, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0fff, 0x0cf3, 0x00f0, 0x00f0, 0x00f0, 0x00f0, + 0x00f0, 0x00f0, 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f0f, + 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x03fc, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, + 0x0f0f, 0x0f0f, 0x0f0f, 0x03fc, 0x00f0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3ccf, 0x3ccf, 0x0f3c, + 0x0f3c, 0x0f3c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f0f, 0x0f0f, + 0x0f0f, 0x03fc, 0x00f0, 0x03fc, 0x0f0f, 0x0f0f, 0x0f0f, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x03fc, + 0x00f0, 0x00f0, 0x00f0, 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3fff, 0x3f0f, 0x03c3, 0x03c0, 0x00f0, 0x003c, 0x303c, 0x3c0f, + 0x3fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x03fc, 0x0f00, 0x0ffc, 0x0f0f, 0x0f0f, 0x3cfc, 0x0000, 0x0000, + 0x0000, 0x0000, 0x003f, 0x003c, 0x003c, 0x0ffc, 0x3c3c, 0x3c3c, + 0x3c3c, 0x3c3c, 0x0fcf, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x03fc, 0x0f0f, 0x000f, 0x000f, 0x0f0f, 0x03fc, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0fc0, 0x0f00, 0x0f00, 0x0ffc, + 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x3cfc, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x03fc, 0x0f0f, 0x0fff, 0x000f, + 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, 0x03f0, 0x0f3c, + 0x003c, 0x003c, 0x03ff, 0x003c, 0x003c, 0x003c, 0x00ff, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3cfc, 0x0f0f, + 0x0f0f, 0x0f0f, 0x0ffc, 0x0f00, 0x0f0f, 0x03fc, 0x0000, 0x0000, + 0x003f, 0x003c, 0x003c, 0x0f3c, 0x3cfc, 0x3c3c, 0x3c3c, 0x3c3c, + 0x3c3f, 0x0000, 0x0000, 0x0000, 0x0000, 0x03c0, 0x03c0, 0x0000, + 0x03fc, 0x03c0, 0x03c0, 0x03c0, 0x03c0, 0x3ffc, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0f00, 0x0f00, 0x0000, 0x0ff0, 0x0f00, 0x0f00, + 0x0f00, 0x0f00, 0x0f0f, 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x003f, + 0x003c, 0x003c, 0x3c3c, 0x0f3c, 0x03fc, 0x0f3c, 0x3c3c, 0x3c3f, + 0x0000, 0x0000, 0x0000, 0x0000, 0x03fc, 0x03c0, 0x03c0, 0x03c0, + 0x03c0, 0x03c0, 0x03c0, 0x03c0, 0x3ffc, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0fff, 0x3ccf, 0x3ccf, 0x3ccf, + 0x3ccf, 0x3c0f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x03ff, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03fc, 0x0f0f, + 0x0f0f, 0x0f0f, 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0fcf, 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, + 0x0ffc, 0x003c, 0x00ff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3cfc, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0ffc, 0x0f00, 0x3fc0, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0f3f, 0x3f3c, 0x3cfc, + 0x003c, 0x003c, 0x00ff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x03fc, 0x0f0f, 0x003c, 0x03c0, 0x0f0f, 0x03fc, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0030, 0x003c, 0x0fff, + 0x003c, 0x003c, 0x003c, 0x0f3c, 0x03f0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, + 0x0f0f, 0x3cfc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x03fc, 0x00f0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c0f, 0x3c0f, + 0x3ccf, 0x3ccf, 0x0f3c, 0x0f3c, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3c0f, 0x0f3c, 0x03f0, 0x03f0, 0x0f3c, + 0x3c0f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3c3c, 0x3c3c, 0x3c3c, 0x3c3c, 0x0ff0, 0x0f00, 0x03c0, 0x00ff, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0fff, 0x0f03, 0x03c0, + 0x003c, 0x0c0f, 0x0fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x03fc, + 0x0f0f, 0x0f00, 0x03c0, 0x00f0, 0x00f0, 0x0000, 0x00f0, 0x00f0, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0f00, 0x03c0, 0x00f0, 0x003c, 0x003c, 0x003c, 0x00f0, + 0x03c0, 0x0f00, 0x0000, 0x0000, 0x0000, 0x0000, 0x003c, 0x00f0, + 0x03c0, 0x0f00, 0x0f00, 0x0f00, 0x03c0, 0x00f0, 0x003c, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03f0, 0x03f0, 0x0000, + 0x0000, 0x03f0, 0x03f0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03f0, + 0x03f0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3ffc, 0x3ffc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x03c0, 0x03c0, 0x3ffc, 0x3ffc, + 0x03c0, 0x03c0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x3ffc, 0x0000, 0x0000, 0x3ffc, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x03fc, 0x0f0f, 0x0f0f, 0x0f0f, + 0x03fc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + //0--------------------------- + 0x0000, 0x0ffc, 0x3c0f, 0x3f0f, 0x3fcf, 0x3ccf, 0x3cff, 0x3c3f, + 0x3c0f, 0x0ffc, 0x0000, 0x0000, 0x0000, + //1--------------------------- + 0x0000, 0x00c0, 0x00f0, 0x00ff, 0x00f0, 0x00f0, 0x00f0, 0x00f0, + 0x00f0, 0x0fff, 0x0000, 0x0000, 0x0000, + //2--------------------------- + 0x0000, 0x03fc, 0x0f0f, 0x0f0f, 0x0f00, 0x03c0, 0x00f0, 0x003c, + 0x0f0f, 0x0fff, 0x0000, 0x0000, 0x0000, + //3--------------------------- + 0x0000, 0x03fc, 0x0f0f, 0x0f00, 0x0f00, 0x03f0, 0x0f00, 0x0f00, + 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x0000, + //4--------------------------- + 0x0000, 0x0f00, 0x0fc0, 0x0ff0, 0x0f3c, 0x0f0f, 0x3fff, 0x0f00, + 0x0f00, 0x3fc0, 0x0000, 0x0000, 0x0000, + //5--------------------------- + 0x0000, 0x0fff, 0x000f, 0x000f, 0x000f, 0x03ff, 0x0f00, 0x0f00, + 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x0000, + //6--------------------------- + 0x0000, 0x03f0, 0x003c, 0x000f, 0x000f, 0x03ff, 0x0f0f, 0x0f0f, + 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x0000, + //7--------------------------- + 0x0000, 0x3fff, 0x3c0f, 0x3c0f, 0x3c00, 0x0f00, 0x03c0, 0x00f0, + 0x00f0, 0x00f0, 0x0000, 0x0000, 0x0000, + //8--------------------------- + 0x0000, 0x03fc, 0x0f0f, 0x0f0f, 0x0f3f, 0x03fc, 0x0fcf, 0x0f0f, + 0x0f0f, 0x03fc, 0x0000, 0x0000, 0x0000, + //9--------------------------- + 0x0000, 0x03fc, 0x0f0f, 0x0f0f, 0x0f0f, 0x0ffc, 0x03c0, 0x03c0, + 0x00f0, 0x00fc, 0x0000, 0x0000, 0x0000, +}; + + +const unsigned int GrayScale_fonts[] = { + 0x0000, 0x0aa8, 0x280a, 0x2a0a, 0x2a8a, 0x288a, 0x28aa, 0x282a, + 0x280a, 0x0aa8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0080, 0x00a0, + 0x00aa, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x0aaa, 0x0000, + 0x0000, 0x0000, 0x0000, 0x02a8, 0x0a0a, 0x0a0a, 0x0a00, 0x0280, + 0x00a0, 0x0028, 0x0a0a, 0x0aaa, 0x0000, 0x0000, 0x0000, 0x0000, + 0x02a8, 0x0a0a, 0x0a00, 0x0a00, 0x02a0, 0x0a00, 0x0a00, 0x0a0a, + 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a00, 0x0a80, 0x0aa0, + 0x0a28, 0x0a0a, 0x2aaa, 0x0a00, 0x0a00, 0x2a80, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0aaa, 0x000a, 0x000a, 0x000a, 0x02aa, 0x0a00, + 0x0a00, 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x02a0, + 0x0028, 0x000a, 0x000a, 0x02aa, 0x0a0a, 0x0a0a, 0x0a0a, 0x02a8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2aaa, 0x280a, 0x280a, 0x2800, + 0x0a00, 0x0280, 0x00a0, 0x00a0, 0x00a0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x02a8, 0x0a0a, 0x0a0a, 0x0a2a, 0x02a8, 0x0a8a, 0x0a0a, + 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x02a8, 0x0a0a, + 0x0a0a, 0x0a0a, 0x0aa8, 0x0280, 0x0280, 0x00a0, 0x00a8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x00a0, 0x02a8, 0x0a0a, 0x0a0a, 0x0a0a, + 0x0aaa, 0x0a0a, 0x0a0a, 0x0a0a, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0aaa, 0x2828, 0x2828, 0x2828, 0x0aa8, 0x2828, 0x2828, 0x2828, + 0x0aaa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0aa0, 0x2828, 0x280a, + 0x000a, 0x000a, 0x000a, 0x280a, 0x2828, 0x0aa0, 0x0000, 0x0000, + 0x0000, 0x0000, 0x02aa, 0x0a28, 0x2828, 0x2828, 0x2828, 0x2828, + 0x2828, 0x0a28, 0x02aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x2aaa, + 0x2028, 0x0028, 0x0828, 0x0aa8, 0x0828, 0x0028, 0x2028, 0x2aaa, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2aaa, 0x2828, 0x2028, 0x0828, + 0x0aa8, 0x0828, 0x0028, 0x0028, 0x00aa, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0aa0, 0x2828, 0x280a, 0x000a, 0x000a, 0x2a0a, 0x280a, + 0x2828, 0x2aa0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a0a, 0x0a0a, + 0x0a0a, 0x0a0a, 0x0aaa, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0000, + 0x0000, 0x0000, 0x0000, 0x02a8, 0x00a0, 0x00a0, 0x00a0, 0x00a0, + 0x00a0, 0x00a0, 0x00a0, 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2a80, 0x0a00, 0x0a00, 0x0a00, 0x0a00, 0x0a0a, 0x0a0a, 0x0a0a, + 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x282a, 0x2828, 0x0a28, + 0x0a28, 0x02a8, 0x0a28, 0x0a28, 0x2828, 0x282a, 0x0000, 0x0000, + 0x0000, 0x0000, 0x00aa, 0x0028, 0x0028, 0x0028, 0x0028, 0x2028, + 0x2828, 0x2828, 0x2aaa, 0x0000, 0x0000, 0x0000, 0x0000, 0x280a, + 0x2a2a, 0x2aaa, 0x2aaa, 0x288a, 0x280a, 0x280a, 0x280a, 0x280a, + 0x0000, 0x0000, 0x0000, 0x0000, 0x280a, 0x280a, 0x282a, 0x28aa, + 0x2aaa, 0x2a8a, 0x2a0a, 0x280a, 0x280a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x02a0, 0x0a28, 0x280a, 0x280a, 0x280a, 0x280a, 0x280a, + 0x0a28, 0x02a0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0aaa, 0x2828, + 0x2828, 0x2828, 0x0aa8, 0x0028, 0x0028, 0x0028, 0x00aa, 0x0000, + 0x0000, 0x0000, 0x0000, 0x02a0, 0x0a28, 0x280a, 0x280a, 0x280a, + 0x2a0a, 0x2a8a, 0x0aa8, 0x0a00, 0x2a80, 0x0000, 0x0000, 0x0000, + 0x0aaa, 0x2828, 0x2828, 0x2828, 0x0aa8, 0x0a28, 0x2828, 0x2828, + 0x282a, 0x0000, 0x0000, 0x0000, 0x0000, 0x02a8, 0x0a0a, 0x0a0a, + 0x000a, 0x00a8, 0x0280, 0x0a0a, 0x0a0a, 0x02a8, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0aaa, 0x08a2, 0x00a0, 0x00a0, 0x00a0, 0x00a0, + 0x00a0, 0x00a0, 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a0a, + 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x02a8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, + 0x0a0a, 0x0a0a, 0x0a0a, 0x02a8, 0x00a0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x280a, 0x280a, 0x280a, 0x280a, 0x288a, 0x288a, 0x0a28, + 0x0a28, 0x0a28, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a0a, 0x0a0a, + 0x0a0a, 0x02a8, 0x00a0, 0x02a8, 0x0a0a, 0x0a0a, 0x0a0a, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x02a8, + 0x00a0, 0x00a0, 0x00a0, 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2aaa, 0x2a0a, 0x0282, 0x0280, 0x00a0, 0x0028, 0x2028, 0x280a, + 0x2aaa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x02a8, 0x0a00, 0x0aa8, 0x0a0a, 0x0a0a, 0x28a8, 0x0000, 0x0000, + 0x0000, 0x0000, 0x002a, 0x0028, 0x0028, 0x0aa8, 0x2828, 0x2828, + 0x2828, 0x2828, 0x0a8a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x02a8, 0x0a0a, 0x000a, 0x000a, 0x0a0a, 0x02a8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0a80, 0x0a00, 0x0a00, 0x0aa8, + 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x28a8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x02a8, 0x0a0a, 0x0aaa, 0x000a, + 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x02a0, 0x0a28, + 0x0028, 0x0028, 0x02aa, 0x0028, 0x0028, 0x0028, 0x00aa, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x28a8, 0x0a0a, + 0x0a0a, 0x0a0a, 0x0aa8, 0x0a00, 0x0a0a, 0x02a8, 0x0000, 0x0000, + 0x002a, 0x0028, 0x0028, 0x0a28, 0x28a8, 0x2828, 0x2828, 0x2828, + 0x282a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0280, 0x0280, 0x0000, + 0x02a8, 0x0280, 0x0280, 0x0280, 0x0280, 0x2aa8, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0a00, 0x0a00, 0x0000, 0x0aa0, 0x0a00, 0x0a00, + 0x0a00, 0x0a00, 0x0a0a, 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x002a, + 0x0028, 0x0028, 0x2828, 0x0a28, 0x02a8, 0x0a28, 0x2828, 0x282a, + 0x0000, 0x0000, 0x0000, 0x0000, 0x02a8, 0x0280, 0x0280, 0x0280, + 0x0280, 0x0280, 0x0280, 0x0280, 0x2aa8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0aaa, 0x288a, 0x288a, 0x288a, + 0x288a, 0x280a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x02aa, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x02a8, 0x0a0a, + 0x0a0a, 0x0a0a, 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0a8a, 0x2828, 0x2828, 0x2828, 0x2828, + 0x0aa8, 0x0028, 0x00aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x28a8, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0aa8, 0x0a00, 0x2a80, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a2a, 0x2a28, 0x28a8, + 0x0028, 0x0028, 0x00aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x02a8, 0x0a0a, 0x0028, 0x0280, 0x0a0a, 0x02a8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0028, 0x0aaa, + 0x0028, 0x0028, 0x0028, 0x0a28, 0x02a0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, + 0x0a0a, 0x28a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x02a8, 0x00a0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x280a, 0x280a, + 0x288a, 0x288a, 0x0a28, 0x0a28, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x280a, 0x0a28, 0x02a0, 0x02a0, 0x0a28, + 0x280a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x2828, 0x2828, 0x2828, 0x2828, 0x0aa0, 0x0a00, 0x0280, 0x00aa, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0aaa, 0x0a02, 0x0280, + 0x0028, 0x080a, 0x0aaa, 0x0000, 0x0000, 0x0000, 0x0000, 0x02a8, + 0x0a0a, 0x0a00, 0x0280, 0x00a0, 0x00a0, 0x0000, 0x00a0, 0x00a0, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0a00, 0x0280, 0x00a0, 0x0028, 0x0028, 0x0028, 0x00a0, + 0x0280, 0x0a00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0028, 0x00a0, + 0x0280, 0x0a00, 0x0a00, 0x0a00, 0x0280, 0x00a0, 0x0028, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x02a0, 0x02a0, 0x0000, + 0x0000, 0x02a0, 0x02a0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x02a0, + 0x02a0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2aa8, 0x2aa8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0280, 0x0280, 0x2aa8, 0x2aa8, + 0x0280, 0x0280, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2aa8, 0x0000, 0x0000, 0x2aa8, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x02a8, 0x0a0a, 0x0a0a, 0x0a0a, + 0x02a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + //0--------------------------- + 0x0000, 0x0aa8, 0x280a, 0x2a0a, 0x2a8a, 0x288a, 0x28aa, 0x282a, + 0x280a, 0x0aa8, 0x0000, 0x0000, 0x0000, + //1--------------------------- + 0x0000, 0x0080, 0x00a0, 0x00aa, 0x00a0, 0x00a0, 0x00a0, 0x00a0, + 0x00a0, 0x0aaa, 0x0000, 0x0000, 0x0000, + //2--------------------------- + 0x0000, 0x02a8, 0x0a0a, 0x0a0a, 0x0a00, 0x0280, 0x00a0, 0x0028, + 0x0a0a, 0x0aaa, 0x0000, 0x0000, 0x0000, + //2--------------------------- + 0x0000, 0x02a8, 0x0a0a, 0x0a00, 0x0a00, 0x02a0, 0x0a00, 0x0a00, + 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x0000, + //4--------------------------- + 0x0000, 0x0a00, 0x0a80, 0x0aa0, 0x0a28, 0x0a0a, 0x2aaa, 0x0a00, + 0x0a00, 0x2a80, 0x0000, 0x0000, 0x0000, + //5--------------------------- + 0x0000, 0x0aaa, 0x000a, 0x000a, 0x000a, 0x02aa, 0x0a00, 0x0a00, + 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x0000, + //6--------------------------- + 0x0000, 0x02a0, 0x0028, 0x000a, 0x000a, 0x02aa, 0x0a0a, 0x0a0a, + 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x0000, + //7--------------------------- + 0x0000, 0x2aaa, 0x280a, 0x280a, 0x2800, 0x0a00, 0x0280, 0x00a0, + 0x00a0, 0x00a0, 0x0000, 0x0000, 0x0000, + //8--------------------------- + 0x0000, 0x02a8, 0x0a0a, 0x0a0a, 0x0a2a, 0x02a8, 0x0a8a, 0x0a0a, + 0x0a0a, 0x02a8, 0x0000, 0x0000, 0x0000, + //9--------------------------- + 0x0000, 0x02a8, 0x0a0a, 0x0a0a, 0x0a0a, 0x0aa8, 0x0280, 0x0280, + 0x00a0, 0x00a8, 0x0000, 0x0000, 0x0000, +}; diff --git a/platform/exp5438/hal_lcd_fonts.h b/platform/exp5438/hal_lcd_fonts.h index bb0a7e1f4..a15ac38ba 100644 --- a/platform/exp5438/hal_lcd_fonts.h +++ b/platform/exp5438/hal_lcd_fonts.h @@ -1,46 +1,46 @@ -/******************************************************************************* - * - * hal_lcd_fonts.h - * - * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ - * - * 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 Texas Instruments Incorporated 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 - * OWNER 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. - * - ******************************************************************************/ - -#ifndef FONTS_H -#define FONTS_H - -#define FONT_HEIGHT 12 // Each character has 13 lines - -extern const unsigned char fonts_lookup[]; -extern const unsigned int fonts[]; -extern const unsigned int GrayScale_fonts[]; - -#endif /* FONTS_H */ +/******************************************************************************* + * + * hal_lcd_fonts.h + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * 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 Texas Instruments Incorporated 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 + * OWNER 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. + * + ******************************************************************************/ + +#ifndef FONTS_H +#define FONTS_H + +#define FONT_HEIGHT 12 // Each character has 13 lines + +extern const unsigned char fonts_lookup[]; +extern const unsigned int fonts[]; +extern const unsigned int GrayScale_fonts[]; + +#endif /* FONTS_H */ diff --git a/platform/exp5438/uart1x.c b/platform/exp5438/uart1x.c index bd212f27d..fe3f17f4f 100644 --- a/platform/exp5438/uart1x.c +++ b/platform/exp5438/uart1x.c @@ -72,8 +72,8 @@ uart1_writeb(unsigned char c) UCA1TXBUF = c; } /*---------------------------------------------------------------------------*/ -#if ! WITH_UIP /* If WITH_UIP is defined, putchar() is defined by the SLIP driver */ -#endif /* ! WITH_UIP */ +#if ! NETSTACK_CONF_WITH_IPV4 /* If NETSTACK_CONF_WITH_IPV4 is defined, putchar() is defined by the SLIP driver */ +#endif /* ! NETSTACK_CONF_WITH_IPV4 */ /*---------------------------------------------------------------------------*/ /** * Initalize the RS232 port. diff --git a/platform/galileo/Makefile.customrules-galileo b/platform/galileo/Makefile.customrules-galileo new file mode 100644 index 000000000..b141ee211 --- /dev/null +++ b/platform/galileo/Makefile.customrules-galileo @@ -0,0 +1,59 @@ +GDB ?= gdb +OPENOCD_SCRIPTS = $(CONTIKI)/platform/galileo/bsp/openocd-scripts + +.PHONY: debug $(CONTIKI_PROJECT) + +# Multiboot ELF binary +MULTIBOOT_SFX = $(TARGET) +MULTIBOOT = $(CONTIKI_PROJECT).$(MULTIBOOT_SFX) +# UEFI binary +UEFI_DLL_SFX = $(TARGET).dll +UEFI_DLL = $(CONTIKI_PROJECT).$(UEFI_SFX) +# The GenFw program is unable to process absolute symbols like _stext_addr, +# etc., that are defined in quarkX1000_dma.ld and quarkX1000_multi_seg.ld +# and used to configure segments in multi-segment.c, etc. Furthermore, +# relocating the UEFI image during load would result in those symbols not +# pointing to the expected image locations. So, relocation data is omitted +# from the intermediate UEFI DLL. This will only result in a +# correctly-functioning build if the UEFI firmware does not attempt to +# relocate the UEFI image, so it may be desirable in the future to revisit +# this design. To emit relocation data, '-Xlinker --emit-relocs' should be +# appended to the following line. +UEFI_LDFLAGS = -Xlinker --entry=uefi_start +UEFI_SFX = $(TARGET).efi +UEFI = $(CONTIKI_PROJECT).$(UEFI_SFX) + +# Suffixes for final (non-intermediate) files to be built +FINAL_SFXS = $(MULTIBOOT_SFX) +ifeq ($(EN_UEFI),1) +FINAL_SFXS += $(UEFI_SFX) +endif + +debug: $(MULTIBOOT) + @openocd -s $(OPENOCD_SCRIPTS) -f debug.cfg &> $(shell pwd)/LOG_OPENOCD & + @$(GDB) $< -ex "target remote :3333" + +CUSTOM_RULE_LINK=1 + +%.$(MULTIBOOT_SFX): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a + $(TRACE_LD) + $(Q)$(LD) $(LDFLAGS) $(MULTIBOOT_LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} \ + ${filter %.a,$^} $(TARGET_LIBFILES) -o $@ + +%.$(UEFI_DLL_SFX): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a + $(TRACE_LD) + $(Q)$(LD) $(LDFLAGS) $(UEFI_LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} \ + ${filter %.a,$^} $(TARGET_LIBFILES) -o $@ + +%.$(UEFI_SFX): %.$(UEFI_DLL_SFX) + $(Q)$(GEN_FW) -o $@ -e UEFI_APPLICATION $^ + # The Intel Galileo firmware has been observed to not relocate the image + # if its base is set to the 1M boundary. This makes debugging easier, + # since the symbols in the intermediate DLL then correspond to the load + # addresses. + $(Q)$(GEN_FW) -o $@ --rebase 0x100000 $@ + +$(CONTIKI_PROJECT): $(addprefix $(CONTIKI_PROJECT).,$(FINAL_SFXS)) + @$(SIZE) $^ + +CLEAN += $(addprefix $(CONTIKI_PROJECT).,$(FINAL_SFXS)) diff --git a/platform/galileo/Makefile.galileo b/platform/galileo/Makefile.galileo new file mode 100644 index 000000000..8be977bc8 --- /dev/null +++ b/platform/galileo/Makefile.galileo @@ -0,0 +1,33 @@ +BSP_PATH=$(CONTIKI)/platform/galileo/bsp +LIBC_PATH=$(BSP_PATH)/libc +LIBC=$(LIBC_PATH)/i586-elf +LIBGCC_PATH = /usr/lib/gcc/$(shell gcc -dumpmachine)/$(shell gcc -dumpversion) + +CONTIKI_TARGET_DIRS = . core/sys/ drivers/ net/ +CONTIKI_TARGET_MAIN = ${addprefix $(OBJECTDIR)/,contiki-main.o} +CONTIKI_SOURCEFILES += contiki-main.c clock.c rtimer-arch.c gpio-pcal9535a.c pwm-pca9685.c galileo-pinmux.c eth-proc.c eth-conf.c + +ifeq ($(CONTIKI_WITH_IPV6),1) + CONTIKI_SOURCEFILES += nbr-table.c packetbuf.c linkaddr.c +endif + +PROJECT_SOURCEFILES += newlib-syscalls.c + +CONTIKI_CPU=$(CONTIKI)/cpu/x86 +include $(CONTIKI)/cpu/x86/Makefile.x86_quarkX1000 + +CFLAGS += -fno-stack-protector -I$(LIBC)/include +ifeq (clang,$(findstring clang,$(CC))) + CFLAGS += -nostdlibinc +else + CFLAGS += -nostdinc -isystem $(LIBGCC_PATH)/include -isystem $(LIBGCC_PATH)/include-fixed +endif +LDFLAGS += -nostdlib -L$(LIBC)/lib -L$(LIBGCC_PATH)/32 + +TARGET_LIBFILES += -lm -lc -lgcc + +-include $(LIBC_PATH)/Makefile.libc + +ifndef BUILT_LIBC + $(error Build the C library by executing $(LIBC_PATH)/build_newlib.sh) +endif diff --git a/platform/galileo/README.md b/platform/galileo/README.md new file mode 100644 index 000000000..e441876db --- /dev/null +++ b/platform/galileo/README.md @@ -0,0 +1,226 @@ +Intel Galileo Board +=================== + +This README file contains general information about the Intel Galileo board +support. In the following lines you will find information about supported +features as well as instructions on how to build, run and debug applications +for this platform. The instructions were only test in Linux environment. + +Requirements +------------ + +In order to build and debug the following packages must be installed in your +system: + * gcc + * gdb + * openocd + +Moreover, in order to debug via JTAG or serial console, you will some extra +devices as described in [1] and [2]. + +Features +-------- + +This section presents the features currently supported (e.g. device drivers +and Contiki APIs) by the Galileo port. + +Device drivers: + * Programmable Interrupt Controller (PIC) + * Programmable Intergal Timer (PIT) + * Real-Time Clock (RTC) + * UART + * Ethernet + * I2C + * GPIO (default pinmux configuration is listed in + platform/galileo/drivers/galileo-pinmux.c) + * Intel Quark X1000 SoC message bus + * Isolated Memory Regions (IMRs) + +Contiki APIs: + * Clock module + * Timer, Stimer, Etimer, Ctimer, and Rtimer libraries + +Standard APIs: + * Stdio library (stdout and stderr only). Console output through UART 1 + device (connected to Galileo Gen2 FTDI header) + +Optional support for protection domains is also implemented and is +described in cpu/x86/mm/README.md. + +Building +-------- + +Prerequisites on all Ubuntu Linux systems include texinfo and uuid-dev. +Additional prerequisites on 64-bit Ubuntu Linux systems include +gcc-multilib and g++-multilib. + +To build applications for this platform you should first build newlib (in +case it wasn't already built). To build newlib you can run the following +command: +``` +$ ./platform/galileo/bsp/libc/build_newlib.sh +``` + +Once newlib is built, you are ready to build applications. By default, the +following steps will use gcc as the C compiler and to invoke the linker. To +use LLVM clang instead, change the values for both the CC and LD variables in +cpu/x86/Makefile.x86_common to 'clang'. + +To build applications for the Galileo platform you should set the TARGET +variable to 'galileo'. For instance, building the hello-world application +should look like this: +``` +$ cd examples/hello-world/ && make TARGET=galileo +``` + +This will generate the 'hello-world.galileo' file which is a multiboot- +compliant [3] ELF image. This image contains debugging information and it +should be used in your daily development. + +You can also build a "Release" image by setting the BUILD_RELEASE variable to +1. This will generate a Contiki stripped-image optimized for size. +``` +$ cd examples/hello-world/ && make TARGET=galileo BUILD_RELEASE=1 +``` + +To also generate an '.galileo.efi' file which is a UEFI [4] image, +you can run the following command prior to building applications: +``` +$ cpu/x86/uefi/build_uefi.sh +``` + +To restrict DMA so that peripherals are blocked from accessing memory +regions that do not contain any data that needs to be DMA-accessible, +specify X86_CONF_RESTRICT_DMA=1 as a command-line argument to the make +command that is used to build the image. This will configure and lock +the IMRs. + +Running +------- + +In order to boot the Contiki image, you will need a multiboot-compliant +bootloader. In the bsp directory, we provide a helper script which builds the +Grub bootloader with multiboot support. To build the bootloader, just run the +following command: +``` +$ platform/galileo/bsp/grub/build_grub.sh +``` + +Once Grub is built, we have three main steps to run Contiki applications: +prepare SDcard, connect to console, and boot image. Below follows +detailed instructions. + +### Prepare SDcard + +Mount the sdcard in directory /mnt/sdcard. + +#### Approach for Multiboot-compliant ELF Image + +Copy Contiki binary image to sdcard +``` +$ cp examples/hello-world/hello-world.galileo /mnt/sdcard +``` + +Copy grub binary to sdcard +``` +$ cp platform/galileo/bsp/grub/bin/grub.efi /mnt/sdcard +``` + +#### Approach for UEFI Image + +Copy Contiki binary image to sdcard +``` +$ cp examples/hello-world/hello-world.galileo.efi /mnt/sdcard +``` + +### Connect to the console output + +Connect the serial cable to your computer as shown in [2]. + +Choose a terminal emulator such as PuTTY. Make sure you use the SCO keyboard +mode (on PuTTY that option is at Terminal -> Keyboard, on the left menu). +Connect to the appropriate serial port using a baud rate of 115200. + +### Boot Contiki Image + +Turn on your board. After a few seconds you should see the following text +in the screen: +``` +Press [Enter] to directly boot. +Press [F7] to show boot menu options. +``` + +Press and select the option "UEFI Internal Shell" within the menu. + +#### Boot Multiboot-compliant ELF Image + +Once you have a shell, run the following commands to run grub application: +``` +$ fs0: +$ grub.efi +``` + +You'll reach the grub shell. Now run the following commands to boot Contiki +image: +``` +$ multiboot /hello-world.galileo +$ boot +``` + +#### Boot UEFI Image + +Once you have a shell, run the following commands to boot Contiki image: +``` +$ fs0: +$ hello-world.galileo.efi +``` + +### Verify that Contiki is Running + +This should boot the Contiki image, resulting in the following messages being +sent to the serial console: +``` +Starting Contiki +Hello World +``` + +Debugging +--------- + +This section describes how to debug Contiki via JTAG. The following +instructions consider you have the devices: Flyswatter2 and ARM-JTAG-20-10 +adapter (see [1]). + +Attach the Flyswatter2 to your host computer with an USB cable. Connect the +Flyswatter2 and ARM-JTAG-20-10 adapter using the 20-pins head. Connect the +ARM-JTAG-20-10 adapter to Galileo Gen2 JTAG port using the 10-pins head. + +Once everything is connected, run Contiki as described in "Running" section, +but right after loading Contiki image (multiboot command), run the following +command: +``` +$ make TARGET=galileo debug +``` + +The 'debug' rule will run OpenOCD and gdb with the right parameters. OpenOCD +will run in background and its output will be redirected to a log file in the +application's path called LOG_OPENOCD. Once gdb client is detached, OpenOCD +is terminated. + +If you use a gdb front-end, you can define the "GDB" environment +variable and your gdb front-end will be used instead of default gdb. +For instance, if you want to use cgdb front-end, just run the command: +``` +$ make BOARD=galileo debug GDB=cgdb +``` + +References +---------- + +[1] https://communities.intel.com/message/211778 + +[2] https://software.intel.com/en-us/articles/intel-galileo-gen-2-board-assembly-using-eclipse-and-intel-xdk-iot-edition + +[3] https://www.gnu.org/software/grub/manual/multiboot/multiboot.html + +[4] http://www.uefi.org/ diff --git a/platform/galileo/bsp/grub/build_grub.sh b/platform/galileo/bsp/grub/build_grub.sh new file mode 100755 index 000000000..6d33799e3 --- /dev/null +++ b/platform/galileo/bsp/grub/build_grub.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +set -e + +JOBS=5 +HEAD="bac5d1a64ab4191058a8fd4c05f6b3b339e249e7" +SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) + +prepare() { + if [[ ! -d ./src ]]; then + git clone git://git.savannah.gnu.org/grub.git src + fi + + pushd src + git checkout $HEAD + git clean -fdx + popd +} + +build() { + pushd src + + ./autogen.sh + ./configure --with-platform=efi --target=i386 + + make -j${JOBS} + + ./grub-mkimage -p /EFI/BOOT -d ./grub-core/ -O i386-efi -o grub.efi \ + boot efifwsetup efi_gop efinet efi_uga lsefimmap lsefi lsefisystab \ + exfat fat multiboot2 multiboot terminal part_msdos part_gpt normal \ + all_video aout configfile echo file fixvideo fshelp gfxterm gfxmenu \ + gfxterm_background gfxterm_menu legacycfg video_bochs video_cirrus \ + video_colors video_fb videoinfo video + + popd +} + +setup() { + mkdir -p bin + cp src/grub.efi bin/ +} + +cleanup() { + rm -rf ./src + rm -rf ./bin +} + +# This script will always run on its own basepath, no matter where you call it from. +pushd ${SCRIPT_DIR} + +case $1 in + -c | --cleanup) + cleanup + ;; + *) + prepare && build && setup + ;; +esac + +popd diff --git a/platform/galileo/bsp/libc/build_newlib.sh b/platform/galileo/bsp/libc/build_newlib.sh new file mode 100755 index 000000000..0e104802e --- /dev/null +++ b/platform/galileo/bsp/libc/build_newlib.sh @@ -0,0 +1,119 @@ +#!/bin/bash + +set -e + +JOBS=5 +TARGET=i586-elf +VERSION=2.2.0-1 +MD5=94114fdc1d8391cdbc2653d89249cccf +PKG_NAME=newlib +SRC_DIR=${PKG_NAME}-${VERSION} +PATCH_DIR=../patches +TARBALL=${SRC_DIR}.tar.gz +DIST_SITE=ftp://sources.redhat.com/pub/newlib + +SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) + +# This script will always run on its own basepath, no matter where you call it from. +pushd ${SCRIPT_DIR} + +prepare() { + # If the source tarball doesn't exist of its md5 checksum doesn't match, download it. + if [ ! -e ./${TARBALL} ] || [ "$(md5sum ./${TARBALL} | cut -d' ' -f1)" != $MD5 ]; then + wget -c ${DIST_SITE}/${TARBALL} + fi + if [ ! -e ./${TARBALL} ] || [ "$(md5sum ./${TARBALL} | cut -d' ' -f1)" != $MD5 ]; then + echo "Error obtaining tarball." + exit 1 + fi + + # Clean up the previous source dir, if any. + if [[ -d ./${SRC_DIR} ]]; then + rm -rf ./${SRC_DIR} + fi + + # Clean up the previous install dir, if any. + if [[ -d ./${TARGET} ]]; then + rm -rf ./${TARGET} + fi + + tar xf ${TARBALL} + cd ${SRC_DIR} + + for i in `ls ${PATCH_DIR}/*.patch`; do patch -p0 < ${i}; done +} + + +build() { + export AR_FOR_TARGET=ar + export AS_FOR_TARGET=as + export CC_FOR_TARGET=cc + export GCC_FOR_TARGET=gcc + export CXX_FOR_TARGET=c++ + export RAW_CXX_FOR_TARGET=c++ + export GCJ_FOR_TARGET=gcj + export GFORTRAN_FOR_TARGET=gfortran + export GOC_FOR_TARGET=gccgo + export DLLTOOL_FOR_TARGET=dlltool + export LD_FOR_TARGET=ld + export LIPO_FOR_TARGET=lipo + export NM_FOR_TARGET=nm + export OBJDUMP_FOR_TARGET=objdump + export RANLIB_FOR_TARGET=ranlib + export READELF_FOR_TARGET=readelf + export STRIP_FOR_TARGET=strip + export WINDRES_FOR_TARGET=windres + export WINDMC_FOR_TARGET=windmc + export COMPILER_AS_FOR_TARGET=as + export COMPILER_LD_FOR_TARGET=ld + export COMPILER_NM_FOR_TARGET=nm + export CFLAGS_FOR_TARGET="-Os -m32 -march=i586 -mtune=i586 -fno-stack-protector -DPREFER_SIZE_OVER_SPEED -ffunction-sections -fdata-sections -fno-asynchronous-unwind-tables -fno-unwind-tables" + export CXXFLAGS_FOR_TARGET="-Os -m32 -march=i586 -mtune=i586 -fno-stack-protector -DPREFER_SIZE_OVER_SPEED -ffunction-sections -fdata-sections -fno-asynchronous-unwind-tables -fno-unwind-tables" + + mkdir -p install + ./configure --target=${TARGET} \ + --prefix=`pwd`/install \ + --enable-newlib-nano-formatted-io \ + --enable-newlib-nano-malloc \ + --enable-multithread \ + --disable-newlib-fvwrite-in-streamio \ + --disable-newlib-fseek-optimization \ + --disable-newlib-wide-orient \ + --disable-newlib-unbuf-stream-opt \ + --disable-libstdcxx \ + --disable-multilib \ + --disable-newlib-mb \ + --disable-newlib-supplied-syscalls + + make -j${JOBS} all && make install + cd .. + + echo "BUILT_LIBC = newlib" > Makefile.libc +} + +setup() { + cp -r ./${SRC_DIR}/install/${TARGET} . +} + +cleanup() { + rm -rf ./${SRC_DIR}* +} + + +# By default we always call prepare, build and setup. +prepare +build +setup + +# But we only cleanup if -c is used. +case $1 in + -c | --cleanup) + cleanup + shift + ;; + *) + # unknown option + ;; +esac + +popd diff --git a/platform/galileo/bsp/libc/patches/large64_files.patch b/platform/galileo/bsp/libc/patches/large64_files.patch new file mode 100644 index 000000000..07d5aeeea --- /dev/null +++ b/platform/galileo/bsp/libc/patches/large64_files.patch @@ -0,0 +1,11 @@ +--- newlib/libc/include/sys/config.h 2015-01-14 07:25:15.000000000 -0200 ++++ newlib/libc/include/sys/config.h 2015-03-13 14:21:33.247980336 -0300 +@@ -94,9 +94,6 @@ + #define HAVE_GETDATE + #define _HAVE_SYSTYPES + #define _READ_WRITE_RETURN_TYPE _ssize_t +-#define __LARGE64_FILES 1 +-/* we use some glibc header files so turn on glibc large file feature */ +-#define _LARGEFILE64_SOURCE 1 + #endif + #endif diff --git a/platform/galileo/bsp/libc/patches/newlib_add_i586_elf.patch b/platform/galileo/bsp/libc/patches/newlib_add_i586_elf.patch new file mode 100644 index 000000000..20c444ba3 --- /dev/null +++ b/platform/galileo/bsp/libc/patches/newlib_add_i586_elf.patch @@ -0,0 +1,13 @@ +--- newlib/configure.host 2015-03-12 17:59:39.380318464 -0300 ++++ newlib/configure.host 2015-03-12 17:55:05.933645678 -0300 +@@ -810,6 +810,10 @@ + z8k-*-*) + syscall_dir=syscalls + ;; ++ i586-*-elf) ++ newlib_cflags="${newlib_cflags} -DREENTRANT_SYSCALLS_PROVIDED" ++ syscall_dir=syscalls ++ ;; + *) + newlib_cflags="${newlib_cflags} -DMISSING_SYSCALL_NAMES" + syscall_dir= diff --git a/platform/galileo/bsp/libc/patches/stdio_strengthen_syms.patch b/platform/galileo/bsp/libc/patches/stdio_strengthen_syms.patch new file mode 100644 index 000000000..97c7f4f3a --- /dev/null +++ b/platform/galileo/bsp/libc/patches/stdio_strengthen_syms.patch @@ -0,0 +1,19 @@ +--- newlib/libc/stdio/nano-vfprintf_local.h 2014-07-04 10:21:43.000000000 -0700 ++++ newlib/libc/stdio/nano-vfprintf_local.h 2015-07-17 12:51:12.974269921 -0700 +@@ -230,5 +230,5 @@ _printf_float (struct _reent *data, + FILE *fp, + int (*pfunc)(struct _reent *, FILE *, + _CONST char *, size_t len), +- va_list *ap) _ATTRIBUTE((__weak__)); ++ va_list *ap); + #endif +--- newlib/libc/stdio/nano-vfscanf_local.h 2014-07-04 10:21:44.000000000 -0700 ++++ newlib/libc/stdio/nano-vfscanf_local.h 2015-07-17 12:51:33.967362409 -0700 +@@ -173,6 +173,6 @@ _scanf_i (struct _reent *rptr, + extern int + _scanf_float (struct _reent *rptr, + struct _scan_data_t *pdata, +- FILE *fp, va_list *ap) _ATTRIBUTE((__weak__)); ++ FILE *fp, va_list *ap); + + #endif diff --git a/platform/galileo/bsp/openocd-scripts/debug.cfg b/platform/galileo/bsp/openocd-scripts/debug.cfg new file mode 100644 index 000000000..bbe8a5919 --- /dev/null +++ b/platform/galileo/bsp/openocd-scripts/debug.cfg @@ -0,0 +1,11 @@ +source [find interface/ftdi/flyswatter2.cfg]; +source [find board/quark_x10xx_board.cfg]; + +quark_x10xx.cpu configure -event gdb-attach { + halt +} + +quark_x10xx.cpu configure -event gdb-detach { + resume + shutdown +} diff --git a/platform/galileo/contiki-conf.h b/platform/galileo/contiki-conf.h new file mode 100644 index 000000000..2d64c440f --- /dev/null +++ b/platform/galileo/contiki-conf.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CONTIKI_CONF_H +#define CONTIKI_CONF_H + +/* Include the default configuration file early here so that this file can + * unconfigure the IP buffer size. That will allow uipopt.h to define a + * default IP buffer size that is larger and more useful. + */ +#include "contiki-default-conf.h" + +#undef UIP_CONF_BUFFER_SIZE + +#include + +#define CLOCK_CONF_SECOND 128 +typedef unsigned long clock_time_t; + +typedef uint64_t rtimer_clock_t; +#define RTIMER_ARCH_SECOND 1024 +#define RTIMER_CLOCK_DIFF(a, b) ((int64_t)((a) - (b))) + +/* We define the following macros and types otherwise Contiki does not + * compile. + */ +#define CCIF +#define CLIF + +#define UIP_CONF_LLH_LEN 14 + +#define LINKADDR_CONF_SIZE 6 + +typedef unsigned short uip_stats_t; + +#endif /* CONTIKI_CONF_H */ diff --git a/platform/galileo/contiki-main.c b/platform/galileo/contiki-main.c new file mode 100644 index 000000000..ccc1f519f --- /dev/null +++ b/platform/galileo/contiki-main.c @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include + +#include "contiki.h" +#include "contiki-net.h" +#include "cpu.h" +#include "eth.h" +#include "eth-conf.h" +#include "galileo-pinmux.h" +#include "gpio.h" +#include "helpers.h" +#include "i2c.h" +#include "imr-conf.h" +#include "interrupt.h" +#include "irq.h" +#include "pci.h" +#include "prot-domains.h" +#include "shared-isr.h" +#include "uart.h" + +PROCINIT( &etimer_process + , &tcpip_process +#if WITH_DNS + , &resolv_process +#endif + ); + +extern int _sdata_kern_startup_func, _edata_kern_startup_func; + +/*---------------------------------------------------------------------------*/ +void +app_main(void) +{ + printf("Starting Contiki\n"); + + process_init(); + procinit_init(); + ctimer_init(); + autostart_start(autostart_processes); + + eth_init(); + + while(1) { + process_run(); + } + + halt(); +} +/*---------------------------------------------------------------------------*/ +/* Kernel entrypoint */ +int +main(void) +{ + uintptr_t *func_ptr; + +#ifdef X86_CONF_RESTRICT_DMA + quarkX1000_imr_conf(); +#endif + irq_init(); + /* Initialize UART connected to Galileo Gen2 FTDI header */ + quarkX1000_uart_init(QUARK_X1000_UART_1); + clock_init(); + rtimer_init(); + + pci_root_complex_init(); + quarkX1000_eth_init(); + quarkX1000_i2c_init(); + quarkX1000_i2c_configure(QUARKX1000_I2C_SPEED_STANDARD, + QUARKX1000_I2C_ADDR_MODE_7BIT); + /* use default pinmux configuration */ + if(galileo_pinmux_initialize() < 0) { + fprintf(stderr, "Failed to initialize pinmux\n"); + } + quarkX1000_gpio_init(); + shared_isr_init(); + + /* The ability to remap interrupts is not needed after this point and should + * thus be disabled according to the principle of least privilege. + */ + pci_root_complex_lock(); + + func_ptr = (uintptr_t *)&_sdata_kern_startup_func; + while(func_ptr != (uintptr_t *)&_edata_kern_startup_func) { + ((void (*)(void))*func_ptr)(); + + func_ptr++; + } + + prot_domains_leave_main(); + + return 0; +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/galileo/core/sys/clock.c b/platform/galileo/core/sys/clock.c new file mode 100644 index 000000000..e84ef20eb --- /dev/null +++ b/platform/galileo/core/sys/clock.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "sys/clock.h" +#include "sys/etimer.h" + +#include "contiki-conf.h" +#include "drivers/legacy_pc/rtc.h" + +#if CLOCK_CONF_SECOND == 2 +#define FREQ RTC_2_HZ +#elif CLOCK_CONF_SECOND == 4 +#define FREQ RTC_4_HZ +#elif CLOCK_CONF_SECOND == 8 +#define FREQ RTC_8_HZ +#elif CLOCK_CONF_SECOND == 16 +#define FREQ RTC_16_HZ +#elif CLOCK_CONF_SECOND == 32 +#define FREQ RTC_32_HZ +#elif CLOCK_CONF_SECOND == 64 +#define FREQ RTC_64_HZ +#elif CLOCK_CONF_SECOND == 128 +#define FREQ RTC_128_HZ +#elif CLOCK_CONF_SECOND == 256 +#define FREQ RTC_256_HZ +#elif CLOCK_CONF_SECOND == 512 +#define FREQ RTC_512_HZ +#elif CLOCK_CONF_SECOND == 1024 +#define FREQ RTC_1024_HZ +#elif CLOCK_CONF_SECOND == 2048 +#define FREQ RTC_2048_HZ +#elif CLOCK_CONF_SECOND == 4096 +#define FREQ RTC_4096_HZ +#elif CLOCK_CONF_SECOND == 8192 +#define FREQ RTC_8192_HZ +#else +#define FREQ -1 +#error "RTC is being used thus CLOCK_CONF_SECOND has to be a value defined by rtc_frequency_t." +#endif + +static volatile clock_time_t tick_count = 0; + +static void +update_ticks(void) +{ + clock_time_t expire = etimer_next_expiration_time(); + + tick_count++; + + /* Notify etimer library if the next event timer has expired */ + if(expire != 0 && tick_count >= expire) { + etimer_request_poll(); + } +} +/*---------------------------------------------------------------------------*/ +void +clock_init(void) +{ + rtc_init(FREQ, update_ticks); +} +/*---------------------------------------------------------------------------*/ +clock_time_t +clock_time(void) +{ + return tick_count; +} +/*---------------------------------------------------------------------------*/ +unsigned long +clock_seconds(void) +{ + return tick_count / CLOCK_CONF_SECOND; +} +/*---------------------------------------------------------------------------*/ +void +clock_wait(clock_time_t t) +{ + clock_time_t initial = tick_count; + + while(tick_count < t + initial); +} +/*---------------------------------------------------------------------------*/ +void +clock_set_seconds(unsigned long sec) +{ + /* Stubbed function */ +} +/*---------------------------------------------------------------------------*/ +void +clock_delay_usec(uint16_t t) +{ + /* Stubbed function */ +} diff --git a/platform/galileo/core/sys/mtarch.h b/platform/galileo/core/sys/mtarch.h new file mode 100644 index 000000000..c8c3440df --- /dev/null +++ b/platform/galileo/core/sys/mtarch.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef MTARCH_H_ +#define MTARCH_H_ + +struct mtarch_thread { +}; + +#endif /* MTARCH_H_ */ diff --git a/platform/galileo/core/sys/rtimer-arch.c b/platform/galileo/core/sys/rtimer-arch.c new file mode 100644 index 000000000..71c4f13f5 --- /dev/null +++ b/platform/galileo/core/sys/rtimer-arch.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "sys/rtimer.h" + +#include "contiki-conf.h" +#include "drivers/legacy_pc/pit.h" + +static volatile rtimer_clock_t tick_count = 0; +static rtimer_clock_t trigger = UINT64_MAX; + +static void +update_ticks(void) +{ + if(++tick_count >= trigger) { + /* Disable trigger by assigning it to the maximum value */ + trigger = UINT64_MAX; + rtimer_run_next(); + } +} +/*---------------------------------------------------------------------------*/ +void +rtimer_arch_init(void) +{ + pit_init(RTIMER_ARCH_SECOND, update_ticks); +} +/*---------------------------------------------------------------------------*/ +rtimer_clock_t +rtimer_arch_now() +{ + return tick_count; +} +/*---------------------------------------------------------------------------*/ +void +rtimer_arch_schedule(rtimer_clock_t t) +{ + trigger = t; +} diff --git a/platform/galileo/core/sys/rtimer-arch.h b/platform/galileo/core/sys/rtimer-arch.h new file mode 100644 index 000000000..3f12056e1 --- /dev/null +++ b/platform/galileo/core/sys/rtimer-arch.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef RTIMER_ARCH_H +#define RTIMER_ARCH_H + +rtimer_clock_t rtimer_arch_now(); + +#endif /* RTIMER_ARCH_H */ diff --git a/platform/galileo/drivers/galileo-pinmux.c b/platform/galileo/drivers/galileo-pinmux.c new file mode 100644 index 000000000..3059bdb36 --- /dev/null +++ b/platform/galileo/drivers/galileo-pinmux.c @@ -0,0 +1,618 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "galileo-pinmux.h" +#include "gpio.h" +#include "gpio-pcal9535a.h" +#include "i2c.h" +#include "pwm-pca9685.h" + +#define GPIO_PCAL9535A_0_I2C_ADDR 0x25 +#define GPIO_PCAL9535A_1_I2C_ADDR 0x26 +#define GPIO_PCAL9535A_2_I2C_ADDR 0x27 +#define PWM_PCA9685_0_I2C_ADDR 0x47 + +#define PINMUX_NUM_FUNCS 4 +#define PINMUX_NUM_PATHS 4 +#define PINMUX_NUM_PINS 20 + +typedef enum { + NONE, + EXP0, + EXP1, + EXP2, + PWM0 +} MUX_CHIP; + +typedef enum { + PIN_LOW = 0x00, + PIN_HIGH = 0x01, + DISABLED = 0xFF +} PIN_LEVEL; + +struct pin_config { + uint8_t pin_num; + GALILEO_PINMUX_FUNC func; +}; + +static struct pin_config default_pinmux_config[PINMUX_NUM_PINS] = { + { 0, GALILEO_PINMUX_FUNC_C }, /* UART0_RXD */ + { 1, GALILEO_PINMUX_FUNC_C }, /* UART0_TXD */ + { 2, GALILEO_PINMUX_FUNC_A }, /* GPIO5(out) */ + { 3, GALILEO_PINMUX_FUNC_B }, /* GPIO6(in) */ + { 4, GALILEO_PINMUX_FUNC_B }, /* GPIO_SUS4 (in) */ + { 5, GALILEO_PINMUX_FUNC_B }, /* GPIO8 (in) */ + { 6, GALILEO_PINMUX_FUNC_B }, /* GPIO9 (in) */ + { 7, GALILEO_PINMUX_FUNC_B }, /* EXP1.P0_6 (in) */ + { 8, GALILEO_PINMUX_FUNC_B }, /* EXP1.P1_0 (in) */ + { 9, GALILEO_PINMUX_FUNC_B }, /* GPIO_SUS2 (in) */ + { 10, GALILEO_PINMUX_FUNC_A }, /* GPIO2 (out) */ + { 11, GALILEO_PINMUX_FUNC_B }, /* GPIO_SUS3 (in) */ + { 12, GALILEO_PINMUX_FUNC_B }, /* GPIO7 (in) */ + { 13, GALILEO_PINMUX_FUNC_B }, /* GPIO_SUS5(in) */ + { 14, GALILEO_PINMUX_FUNC_B }, /* EXP2.P0_0 (in)/ADC.IN0 */ + { 15, GALILEO_PINMUX_FUNC_B }, /* EXP2.P0_2 (in)/ADC.IN1 */ + { 16, GALILEO_PINMUX_FUNC_B }, /* EXP2.P0_4 (in)/ADC.IN2 */ + { 17, GALILEO_PINMUX_FUNC_B }, /* EXP2.P0_6 (in)/ADC.IN3 */ + { 18, GALILEO_PINMUX_FUNC_C }, /* I2C_SDA */ + { 19, GALILEO_PINMUX_FUNC_C }, /* I2C_SCL */ +}; + +struct mux_pin { + MUX_CHIP chip; + uint8_t pin; + PIN_LEVEL level; + uint32_t cfg; +}; + +struct mux_path { + uint8_t io_pin; + GALILEO_PINMUX_FUNC func; + struct mux_pin path[PINMUX_NUM_PATHS]; +}; + +struct pinmux_internal_data { + struct gpio_pcal9535a_data exp0; + struct gpio_pcal9535a_data exp1; + struct gpio_pcal9535a_data exp2; + struct pwm_pca9685_data pwm0; +}; + +static struct pinmux_internal_data data; + +static struct mux_path galileo_pinmux_paths[PINMUX_NUM_PINS * PINMUX_NUM_FUNCS] = { + {0, GALILEO_PINMUX_FUNC_A, { + { EXP1, 0, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, /* GPIO3 out */ + { EXP1, 1, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {0, GALILEO_PINMUX_FUNC_B, { + { EXP1, 0, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO3 in */ + { EXP1, 1, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {0, GALILEO_PINMUX_FUNC_C, { + { EXP1, 0, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* UART0_RXD */ + { EXP1, 1, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {0, GALILEO_PINMUX_FUNC_D, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + + {1, GALILEO_PINMUX_FUNC_A, { + { EXP1, 13, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO4 out */ + { EXP0, 12, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 13, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {1, GALILEO_PINMUX_FUNC_B, { + { EXP1, 13, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO4 in */ + { EXP0, 12, PIN_HIGH, (QUARKX1000_GPIO_OUT)}, + { EXP0, 13, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {1, GALILEO_PINMUX_FUNC_C, { + { EXP1, 13, PIN_HIGH, (QUARKX1000_GPIO_OUT)}, /* UART0_TXD */ + { EXP0, 12, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 13, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {1, GALILEO_PINMUX_FUNC_D, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + + {2, GALILEO_PINMUX_FUNC_A, { + { PWM0, 13, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, /* GPIO5 out */ + { EXP1, 2, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP1, 3, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {2, GALILEO_PINMUX_FUNC_B, { + { PWM0, 13, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, /* GPIO5 in */ + { EXP1, 2, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, + { EXP1, 3, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {2, GALILEO_PINMUX_FUNC_C, { + { PWM0, 13, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* UART1_RXD */ + { EXP1, 2, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, + { EXP1, 3, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {2, GALILEO_PINMUX_FUNC_D, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + + {3, GALILEO_PINMUX_FUNC_A, { + { PWM0, 0, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO6 out */ + { PWM0, 12, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 0, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 1, PIN_LOW, (QUARKX1000_GPIO_OUT) }}}, + {3, GALILEO_PINMUX_FUNC_B, { + { PWM0, 0, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO6 in */ + { PWM0, 12, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 0, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, + { EXP0, 1, PIN_LOW, (QUARKX1000_GPIO_OUT) }}}, + {3, GALILEO_PINMUX_FUNC_C, { + { PWM0, 0, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* UART1_TXD */ + { PWM0, 12, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, + { EXP0, 0, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 1, PIN_LOW, (QUARKX1000_GPIO_OUT) }}}, + {3, GALILEO_PINMUX_FUNC_D, { + { PWM0, 0, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, /* PWM.LED1 */ + { PWM0, 12, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 0, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 1, PIN_LOW, (QUARKX1000_GPIO_OUT) }}}, + + {4, GALILEO_PINMUX_FUNC_A, { + { EXP1, 4, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO_SUS4 out */ + { EXP1, 5, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {4, GALILEO_PINMUX_FUNC_B, { + { EXP1, 4, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, /* GPIO_SUS4 in */ + { EXP1, 5, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {4, GALILEO_PINMUX_FUNC_C, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {4, GALILEO_PINMUX_FUNC_D, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + + {5, GALILEO_PINMUX_FUNC_A, { + { PWM0, 2, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO8 (out) */ + { EXP0, 2, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 3, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {5, GALILEO_PINMUX_FUNC_B, { + { PWM0, 2, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO8 (in) */ + { EXP0, 2, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, + { EXP0, 3, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {5, GALILEO_PINMUX_FUNC_C, { + { PWM0, 2, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, /* PWM.LED3 */ + { EXP0, 2, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 3, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {5, GALILEO_PINMUX_FUNC_D, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + + {6, GALILEO_PINMUX_FUNC_A, { + { PWM0, 4, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO9 (out) */ + { EXP0, 4, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 5, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {6, GALILEO_PINMUX_FUNC_B, { + { PWM0, 4, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO9 (in) */ + { EXP0, 4, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, + { EXP0, 5, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {6, GALILEO_PINMUX_FUNC_C, { + { PWM0, 4, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, /* PWM.LED5 */ + { EXP0, 4, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 5, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {6, GALILEO_PINMUX_FUNC_D, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + + {7, GALILEO_PINMUX_FUNC_A, { + { EXP1, 6, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO_SUS0 (out) */ + { EXP1, 7, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {7, GALILEO_PINMUX_FUNC_B, { + { EXP1, 6, PIN_LOW, (QUARKX1000_GPIO_IN ) }, /* GPIO_SUS0 (in) */ + { EXP1, 7, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {7, GALILEO_PINMUX_FUNC_C, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {7, GALILEO_PINMUX_FUNC_D, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + + {8, GALILEO_PINMUX_FUNC_A, { + { EXP1, 8, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO_SUS1 (out) */ + { EXP1, 9, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {8, GALILEO_PINMUX_FUNC_B, { + { EXP1, 8, PIN_LOW, (QUARKX1000_GPIO_IN ) }, /* GPIO_SUS1 (in) */ + { EXP1, 9, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {8, GALILEO_PINMUX_FUNC_C, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {8, GALILEO_PINMUX_FUNC_D, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + + {9, GALILEO_PINMUX_FUNC_A, { + { PWM0, 6, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO_SUS2 (out) */ + { EXP0, 6, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 7, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {9, GALILEO_PINMUX_FUNC_B, { + { PWM0, 6, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO_SUS2 (in) */ + { EXP0, 6, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, + { EXP0, 7, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {9, GALILEO_PINMUX_FUNC_C, { + { PWM0, 6, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, /* PWM.LED7 */ + { EXP0, 6, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 7, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {9, GALILEO_PINMUX_FUNC_C, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + + {10, GALILEO_PINMUX_FUNC_A, { + { PWM0, 10, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO2 (out) */ + { EXP0, 10, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 11, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {10, GALILEO_PINMUX_FUNC_B, { + { PWM0, 10, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO2 (in) */ + { EXP0, 10, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, + { EXP0, 11, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {10, GALILEO_PINMUX_FUNC_C, { + { PWM0, 10, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, /* PWM.LED11 */ + { EXP0, 10, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 11, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {10, GALILEO_PINMUX_FUNC_D, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + + {11, GALILEO_PINMUX_FUNC_A, { + { EXP1, 12, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO_SUS3 (out) */ + { PWM0, 8, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 8, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 9, PIN_LOW, (QUARKX1000_GPIO_OUT) }}}, + {11, GALILEO_PINMUX_FUNC_B, { + { EXP1, 12, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO_SUS3 (in) */ + { PWM0, 8, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 8, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, + { EXP0, 9, PIN_LOW, (QUARKX1000_GPIO_OUT) }}}, + {11, GALILEO_PINMUX_FUNC_C, { + { EXP1, 12, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* PWM.LED9 */ + { PWM0, 8, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, + { EXP0, 8, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 9, PIN_LOW, (QUARKX1000_GPIO_OUT) }}}, + {11, GALILEO_PINMUX_FUNC_D, { + { EXP1, 12, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, /* SPI1_MOSI */ + { PWM0, 8, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 8, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 9, PIN_LOW, (QUARKX1000_GPIO_OUT) }}}, + + {12, GALILEO_PINMUX_FUNC_A, { + { EXP1, 10, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO7 (out) */ + { EXP1, 11, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {12, GALILEO_PINMUX_FUNC_B, { + { EXP1, 10, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, /* GPIO7 (in) */ + { EXP1, 11, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {12, GALILEO_PINMUX_FUNC_C, { + { EXP1, 10, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* SPI1_MISO */ + { EXP1, 11, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {12, GALILEO_PINMUX_FUNC_D, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + + {13, GALILEO_PINMUX_FUNC_A, { + { EXP1, 14, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO_SUS5 (out) */ + { EXP0, 14, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 15, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {13, GALILEO_PINMUX_FUNC_B, { + { EXP1, 14, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* GPIO_SUS5 (in) */ + { EXP0, 14, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, + { EXP0, 15, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {13, GALILEO_PINMUX_FUNC_C, { + { EXP1, 14, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, /* SPI1_CLK */ + { EXP0, 14, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP0, 15, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {13, GALILEO_PINMUX_FUNC_D, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + + {14, GALILEO_PINMUX_FUNC_A, { + { EXP2, 0, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* EXP2.P0_0 (out)/ADC.IN0 */ + { EXP2, 1, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {14, GALILEO_PINMUX_FUNC_B, { + { EXP2, 0, PIN_LOW, (QUARKX1000_GPIO_IN ) }, /* EXP2.P0_0 (in)/ADC.IN0 */ + { EXP2, 1, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {14, GALILEO_PINMUX_FUNC_C, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {14, GALILEO_PINMUX_FUNC_D, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + + {15, GALILEO_PINMUX_FUNC_A, { + { EXP2, 2, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* EXP2.P0_2 (out)/ADC.IN1 */ + { EXP2, 3, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {15, GALILEO_PINMUX_FUNC_B, { + { EXP2, 2, PIN_LOW, (QUARKX1000_GPIO_IN ) }, /* EXP2.P0_2 (in)/ADC.IN1 */ + { EXP2, 3, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {15, GALILEO_PINMUX_FUNC_C, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {15, GALILEO_PINMUX_FUNC_D, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + + {16, GALILEO_PINMUX_FUNC_A, { + { EXP2, 4, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* EXP2.P0_4 (out)/ADC.IN2 */ + { EXP2, 5, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {16, GALILEO_PINMUX_FUNC_B, { + { EXP2, 4, PIN_LOW, (QUARKX1000_GPIO_IN ) }, /* EXP2.P0_4 (in)/ADC.IN2 */ + { EXP2, 5, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {16, GALILEO_PINMUX_FUNC_C, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {16, GALILEO_PINMUX_FUNC_D, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + + {17, GALILEO_PINMUX_FUNC_A, { + { EXP2, 6, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* EXP2.P0_6 (out)/ADC.IN3 */ + { EXP2, 7, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {17, GALILEO_PINMUX_FUNC_B, { + { EXP2, 6, PIN_LOW, (QUARKX1000_GPIO_IN ) }, /* EXP2.P0_6 (in)/ADC.IN3 */ + { EXP2, 7, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {17, GALILEO_PINMUX_FUNC_C, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {17, GALILEO_PINMUX_FUNC_D, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + + {18, GALILEO_PINMUX_FUNC_A, { + { PWM0, 14, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, /* EXP2.P1_0 (out)/ADC.IN4 */ + { EXP2, 12, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, + { EXP2, 8, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP2, 9, PIN_LOW, (QUARKX1000_GPIO_OUT) }}}, + {18, GALILEO_PINMUX_FUNC_B, { + { PWM0, 14, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* EXP2.P1_0 (in)/ADC.IN4 */ + { EXP2, 12, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, + { EXP2, 8, PIN_LOW, (QUARKX1000_GPIO_IN ) }, + { EXP2, 9, PIN_LOW, (QUARKX1000_GPIO_OUT) }}}, + {18, GALILEO_PINMUX_FUNC_C, { + { PWM0, 14, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, /* I2C SDA */ + { EXP2, 9, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP2, 12, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {18, GALILEO_PINMUX_FUNC_D, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + + {19, GALILEO_PINMUX_FUNC_A, { + { PWM0, 15, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, /* EXP2.P1_2 (out)/ADC.IN5 */ + { EXP2, 12, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, + { EXP2, 10, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP2, 11, PIN_LOW, (QUARKX1000_GPIO_OUT) }}}, + {19, GALILEO_PINMUX_FUNC_B, { + { PWM0, 15, PIN_LOW, (QUARKX1000_GPIO_OUT) }, /* EXP2.P1_2 (in)/ADC.IN5 */ + { EXP2, 12, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, + { EXP2, 10, PIN_LOW, (QUARKX1000_GPIO_IN ) }, + { EXP2, 11, PIN_LOW, (QUARKX1000_GPIO_OUT) }}}, + {19, GALILEO_PINMUX_FUNC_C, { + { PWM0, 15, PIN_HIGH, (QUARKX1000_GPIO_OUT) }, /* I2C SCL */ + { EXP2, 11, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { EXP2, 12, PIN_LOW, (QUARKX1000_GPIO_OUT) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, + {19, GALILEO_PINMUX_FUNC_D, { + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, /* NONE */ + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }, + { NONE, 0, DISABLED, (QUARKX1000_GPIO_IN ) }}}, +}; + +int +galileo_pinmux_set_pin(uint8_t pin, GALILEO_PINMUX_FUNC func) +{ + struct mux_path *mux_path; + uint8_t index, i; + + if(pin > PINMUX_NUM_PINS) { + return -1; + } + + index = PINMUX_NUM_FUNCS * pin; + index += func; + + mux_path = &galileo_pinmux_paths[index]; + + for(i = 0; i < PINMUX_NUM_PATHS; i++) { + switch(mux_path->path[i].chip) { + case EXP0: + if(gpio_pcal9535a_write(&data.exp0, mux_path->path[i].pin, mux_path->path[i].level) < 0) { + return -1; + } + if(gpio_pcal9535a_config(&data.exp0, mux_path->path[i].pin, mux_path->path[i].cfg) < 0) { + return -1; + } + break; + case EXP1: + if(gpio_pcal9535a_write(&data.exp1, mux_path->path[i].pin, mux_path->path[i].level) < 0) { + return -1; + } + if(gpio_pcal9535a_config(&data.exp1, mux_path->path[i].pin, mux_path->path[i].cfg) < 0) { + return -1; + } + break; + case EXP2: + if(gpio_pcal9535a_write(&data.exp2, mux_path->path[i].pin, mux_path->path[i].level) < 0) { + return -1; + } + if(gpio_pcal9535a_config(&data.exp2, mux_path->path[i].pin, mux_path->path[i].cfg) < 0) { + return -1; + } + break; + case PWM0: + if(pwm_pca9685_set_duty_cycle(&data.pwm0, mux_path->path[i].pin, mux_path->path[i].level ? 100 : 0) < 0) { + return -1; + } + break; + case NONE: + break; + } + } + + return 0; +} +int +galileo_pinmux_initialize(void) +{ + uint8_t i; + + /* has to init after I2C master */ + if(!quarkX1000_i2c_is_available()) { + return -1; + } + + if(gpio_pcal9535a_init(&data.exp0, GPIO_PCAL9535A_0_I2C_ADDR) < 0) { + return -1; + } + + if(gpio_pcal9535a_init(&data.exp1, GPIO_PCAL9535A_1_I2C_ADDR) < 0) { + return -1; + } + + if(gpio_pcal9535a_init(&data.exp2, GPIO_PCAL9535A_2_I2C_ADDR) < 0) { + return -1; + } + + if(pwm_pca9685_init(&data.pwm0, PWM_PCA9685_0_I2C_ADDR) < 0) { + return -1; + } + + for(i = 0; i < PINMUX_NUM_PINS; i++) { + if(galileo_pinmux_set_pin(default_pinmux_config[i].pin_num, default_pinmux_config[i].func) < 0) { + return -1; + } + } + + return 0; +} diff --git a/platform/galileo/drivers/galileo-pinmux.h b/platform/galileo/drivers/galileo-pinmux.h new file mode 100644 index 000000000..f7d4fa39e --- /dev/null +++ b/platform/galileo/drivers/galileo-pinmux.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_DRIVERS_GALILEO_PINMUX_H_ +#define CPU_X86_DRIVERS_GALILEO_PINMUX_H_ + +#include + +typedef enum { + GALILEO_PINMUX_FUNC_A, + GALILEO_PINMUX_FUNC_B, + GALILEO_PINMUX_FUNC_C, + GALILEO_PINMUX_FUNC_D +} GALILEO_PINMUX_FUNC; + +int galileo_pinmux_initialize(void); +int galileo_pinmux_set_pin(uint8_t pin, GALILEO_PINMUX_FUNC func); + +#endif /* CPU_X86_DRIVERS_GALILEO_PINMUX_H_ */ diff --git a/platform/galileo/drivers/gpio-pcal9535a.c b/platform/galileo/drivers/gpio-pcal9535a.c new file mode 100644 index 000000000..1fac7f74b --- /dev/null +++ b/platform/galileo/drivers/gpio-pcal9535a.c @@ -0,0 +1,357 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "contiki.h" +#include "gpio.h" +#include "gpio-pcal9535a.h" +#include "i2c.h" +#include "stdio.h" + +#define REG_INPUT_PORT0 0x00 +#define REG_INPUT_PORT1 0x01 +#define REG_OUTPUT_PORT0 0x02 +#define REG_OUTPUT_PORT1 0x03 +#define REG_POL_INV_PORT0 0x04 +#define REG_POL_INV_PORT1 0x05 +#define REG_CONF_PORT0 0x06 +#define REG_CONG_PORT1 0x07 +#define REG_OUT_DRV_STRENGTH_PORT0_L 0x40 +#define REG_OUT_DRV_STRENGTH_PORT0_H 0x41 +#define REG_OUT_DRV_STRENGTH_PORT1_L 0x42 +#define REG_OUT_DRV_STRENGTH_PORT1_H 0x43 +#define REG_INPUT_LATCH_PORT0 0x44 +#define REG_INPUT_LATCH_PORT1 0x45 +#define REG_PUD_EN_PORT0 0x46 +#define REG_PUD_EN_PORT1 0x47 +#define REG_PUD_SEL_PORT0 0x48 +#define REG_PUD_SEL_PORT1 0x49 +#define REG_INT_MASK_PORT0 0x4A +#define REG_INT_MASK_PORT1 0x4B +#define REG_INT_STATUS_PORT0 0x4C +#define REG_INT_STATUS_PORT1 0x4D +#define REG_OUTPUT_PORT_CONF 0x4F + +#define READ_PORT_TIMEOUT (CLOCK_SECOND / 100) +#define READ_PORT_TRIES 5 + +static int +read_port_regs(struct gpio_pcal9535a_data *data, uint8_t reg, union gpio_pcal9535a_port_data *buf) +{ + int r; + uint8_t tries = READ_PORT_TRIES; + + buf->byte[0] = reg; + buf->byte[1] = 0; + + if(quarkX1000_i2c_write(buf->byte, 1, data->i2c_slave_addr) < 0) { + return -1; + } + + do { + clock_wait(READ_PORT_TIMEOUT); + + r = quarkX1000_i2c_read(buf->byte, 2, data->i2c_slave_addr); + if(r == 0) { + break; + } + } while(tries--); + + if(r < 0) { + return -1; + } + + return 0; +} +static int +write_port_regs(struct gpio_pcal9535a_data *data, uint8_t reg, union gpio_pcal9535a_port_data *buf) +{ + uint8_t cmd[] = { reg, buf->byte[0], buf->byte[1] }; + + if(quarkX1000_i2c_polling_write(cmd, sizeof(cmd), data->i2c_slave_addr) < 0) { + return -1; + } + + return 0; +} +static int +setup_pin_dir(struct gpio_pcal9535a_data *data, uint32_t pin, int flags) +{ + union gpio_pcal9535a_port_data *port = &data->reg_cache.dir; + uint16_t bit_mask, new_value = 0; + + bit_mask = 1 << pin; + + if((flags & QUARKX1000_GPIO_DIR_MASK) == QUARKX1000_GPIO_IN) { + new_value = 1 << pin; + } + + port->all &= ~bit_mask; + port->all |= new_value; + + return write_port_regs(data, REG_CONF_PORT0, port); +} +static int +setup_pin_pullupdown(struct gpio_pcal9535a_data *data, uint32_t pin, int flags) +{ + union gpio_pcal9535a_port_data *port; + uint16_t bit_mask, new_value = 0; + + if((flags & QUARKX1000_GPIO_PUD_MASK) != QUARKX1000_GPIO_PUD_NORMAL) { + port = &data->reg_cache.pud_sel; + bit_mask = 1 << pin; + + if((flags & QUARKX1000_GPIO_PUD_MASK) == QUARKX1000_GPIO_PUD_PULL_UP) { + new_value = 1 << pin; + } + + port->all &= ~bit_mask; + port->all |= new_value; + + if(write_port_regs(data, REG_PUD_SEL_PORT0, port) < 0) { + return -1; + } + } + + port = &data->reg_cache.pud_en; + bit_mask = 1 << pin; + + if((flags & QUARKX1000_GPIO_PUD_MASK) != QUARKX1000_GPIO_PUD_NORMAL) { + new_value = 1 << pin; + } + + port->all &= ~bit_mask; + port->all |= new_value; + + return write_port_regs(data, REG_PUD_EN_PORT0, port); +} +static int +setup_pin_polarity(struct gpio_pcal9535a_data *data, uint32_t pin, int flags) +{ + union gpio_pcal9535a_port_data *port = &data->reg_cache.pol_inv; + uint16_t bit_mask, new_value = 0; + + bit_mask = 1 << pin; + + if((flags & QUARKX1000_GPIO_POL_MASK) == QUARKX1000_GPIO_POL_INV) { + new_value = 1 << pin; + } + + port->all &= ~bit_mask; + port->all |= new_value; + + if(write_port_regs(data, REG_POL_INV_PORT0, port) < 0) { + return -1; + } + + data->out_pol_inv = port->all; + + return 0; +} +int +gpio_pcal9535a_write(struct gpio_pcal9535a_data *data, uint32_t pin, uint32_t value) +{ + union gpio_pcal9535a_port_data *port = &data->reg_cache.output; + uint16_t bit_mask, new_value; + + if(!quarkX1000_i2c_is_available()) { + return -1; + } + + bit_mask = 1 << pin; + + new_value = (value << pin) & bit_mask; + new_value ^= (data->out_pol_inv & bit_mask); + new_value &= bit_mask; + + port->all &= ~bit_mask; + port->all |= new_value; + + return write_port_regs(data, REG_OUTPUT_PORT0, port); +} +int +gpio_pcal9535a_read(struct gpio_pcal9535a_data *data, uint32_t pin, uint32_t *value) +{ + union gpio_pcal9535a_port_data buf; + + if(!quarkX1000_i2c_is_available()) { + return -1; + } + + if(read_port_regs(data, REG_INPUT_PORT0, &buf) < 0) { + return -1; + } + + *value = (buf.all >> pin) & 0x01; + + return 0; +} +int +gpio_pcal9535a_config(struct gpio_pcal9535a_data *data, uint32_t pin, int flags) +{ + if(!quarkX1000_i2c_is_available()) { + return -1; + } + + if(setup_pin_dir(data, pin, flags) < 0) { + return -1; + } + + if(setup_pin_polarity(data, pin, flags) < 0) { + return -1; + } + + if(setup_pin_pullupdown(data, pin, flags) < 0) { + return -1; + } + + return 0; +} +static int +setup_port_dir(struct gpio_pcal9535a_data *data, uint32_t pin, int flags) +{ + union gpio_pcal9535a_port_data *port = &data->reg_cache.dir; + + port->all = ((flags & QUARKX1000_GPIO_DIR_MASK) == QUARKX1000_GPIO_IN) ? 0xFFFF : 0x0; + + return write_port_regs(data, REG_CONF_PORT0, port); +} +static int +setup_port_pullupdown(struct gpio_pcal9535a_data *data, uint32_t pin, int flags) +{ + union gpio_pcal9535a_port_data *port; + + if((flags & QUARKX1000_GPIO_PUD_MASK) != QUARKX1000_GPIO_PUD_NORMAL) { + port = &data->reg_cache.pud_sel; + port->all = ((flags & QUARKX1000_GPIO_PUD_MASK) == QUARKX1000_GPIO_PUD_PULL_UP) ? 0xFFFF : 0x0; + + if(write_port_regs(data, REG_PUD_SEL_PORT0, port) < 0) { + return -1; + } + } + + port = &data->reg_cache.pud_en; + port->all = ((flags & QUARKX1000_GPIO_PUD_MASK) != QUARKX1000_GPIO_PUD_NORMAL) ? 0xFFFF : 0x0; + + return write_port_regs(data, REG_PUD_EN_PORT0, port); +} +static int +setup_port_polarity(struct gpio_pcal9535a_data *data, uint32_t pin, int flags) +{ + union gpio_pcal9535a_port_data *port = &data->reg_cache.pol_inv; + + port->all = ((flags & QUARKX1000_GPIO_POL_MASK) == QUARKX1000_GPIO_POL_INV) ? 0xFFFF : 0x0; + + if(write_port_regs(data, REG_POL_INV_PORT0, port) < 0) { + return -1; + } + + data->out_pol_inv = port->all; + + return 0; +} +int +gpio_pcal9535a_write_port(struct gpio_pcal9535a_data *data, uint32_t pin, uint32_t value) +{ + union gpio_pcal9535a_port_data *port = &data->reg_cache.output; + uint16_t bit_mask, new_value; + + if(!quarkX1000_i2c_is_available()) { + return -1; + } + + port->all = value; + bit_mask = data->out_pol_inv; + + new_value = value & bit_mask; + new_value ^= data->out_pol_inv; + new_value &= bit_mask; + + port->all &= ~bit_mask; + port->all |= new_value; + + return write_port_regs(data, REG_OUTPUT_PORT0, port); +} +int +gpio_pcal9535a_read_port(struct gpio_pcal9535a_data *data, uint32_t pin, uint32_t *value) +{ + union gpio_pcal9535a_port_data buf; + + if(!quarkX1000_i2c_is_available()) { + return -1; + } + + if(read_port_regs(data, REG_INPUT_PORT0, &buf) < 0) { + return -1; + } + + *value = buf.all; + + return 0; +} +int +gpio_pcal9535a_config_port(struct gpio_pcal9535a_data *data, uint32_t pin, int flags) +{ + if(!quarkX1000_i2c_is_available()) { + return -1; + } + + if(setup_port_dir(data, pin, flags) < 0) { + return -1; + } + + if(setup_port_polarity(data, pin, flags) < 0) { + return -1; + } + + if(setup_port_pullupdown(data, pin, flags) < 0) { + return -1; + } + + return 0; +} +int +gpio_pcal9535a_init(struct gpio_pcal9535a_data *data, uint16_t i2c_slave_addr) +{ + /* has to init after I2C master */ + if(!quarkX1000_i2c_is_available()) { + return -1; + } + + data->i2c_slave_addr = i2c_slave_addr; + + /* default for registers according to datasheet */ + data->reg_cache.output.all = 0xFFFF; + data->reg_cache.pol_inv.all = 0x0; + data->reg_cache.dir.all = 0xFFFF; + data->reg_cache.pud_en.all = 0x0; + data->reg_cache.pud_sel.all = 0xFFFF; + + return 0; +} diff --git a/platform/galileo/drivers/gpio-pcal9535a.h b/platform/galileo/drivers/gpio-pcal9535a.h new file mode 100644 index 000000000..f7f8ce699 --- /dev/null +++ b/platform/galileo/drivers/gpio-pcal9535a.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_DRIVERS_GPIO_PCAL9535A_H_ +#define CPU_X86_DRIVERS_GPIO_PCAL9535A_H_ + +#include + +union gpio_pcal9535a_port_data { + uint16_t all; + uint8_t port[2]; + uint8_t byte[2]; +}; + +struct gpio_pcal9535a_data { + uint16_t i2c_slave_addr; + uint32_t out_pol_inv; + + struct { + union gpio_pcal9535a_port_data output; + union gpio_pcal9535a_port_data pol_inv; + union gpio_pcal9535a_port_data dir; + union gpio_pcal9535a_port_data pud_en; + union gpio_pcal9535a_port_data pud_sel; + } reg_cache; +}; + +int gpio_pcal9535a_init(struct gpio_pcal9535a_data *data, uint16_t i2c_slave_addr); + +int gpio_pcal9535a_config(struct gpio_pcal9535a_data *data, uint32_t pin, int flags); +int gpio_pcal9535a_read(struct gpio_pcal9535a_data *data, uint32_t pin, uint32_t *value); +int gpio_pcal9535a_write(struct gpio_pcal9535a_data *data, uint32_t pin, uint32_t value); + +int gpio_pcal9535a_config_port(struct gpio_pcal9535a_data *data, uint32_t pin, int flags); +int gpio_pcal9535a_read_port(struct gpio_pcal9535a_data *data, uint32_t pin, uint32_t *value); +int gpio_pcal9535a_write_port(struct gpio_pcal9535a_data *data, uint32_t pin, uint32_t value); + +#endif /* CPU_X86_DRIVERS_GPIO_PCAL9535A_H_ */ diff --git a/platform/galileo/drivers/pwm-pca9685.c b/platform/galileo/drivers/pwm-pca9685.c new file mode 100644 index 000000000..6a3d7ce2d --- /dev/null +++ b/platform/galileo/drivers/pwm-pca9685.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "i2c.h" +#include "pwm-pca9685.h" + +#define REG_MODE1 0x00 +#define REG_MODE2 0x01 + +#define REG_LED_ON_L(n) ((4 * n) + 0x06) +#define REG_LED_ON_H(n) ((4 * n) + 0x07) +#define REG_LED_OFF_L(n) ((4 * n) + 0x08) +#define REG_LED_OFF_H(n) ((4 * n) + 0x09) + +#define MAX_PWM_OUT 16 +#define PWM_ONE_PERIOD_TICKS 4096 + +int +pwm_pca9685_set_values(struct pwm_pca9685_data *data, uint32_t pwm, uint32_t on, uint32_t off) +{ + uint8_t buf[5] = { 0 }; + + if(!quarkX1000_i2c_is_available()) { + return -1; + } + + if(pwm > MAX_PWM_OUT) { + return -1; + } + + buf[0] = REG_LED_ON_L(pwm); + + if((on >= PWM_ONE_PERIOD_TICKS) || (off >= PWM_ONE_PERIOD_TICKS)) { + /* Treat as 100% */ + buf[1] = 0x0; + buf[2] = (1 << 4); + buf[3] = 0x0; + buf[4] = 0x0; + } else if(off == 0) { + /* Treat it as 0% */ + buf[1] = 0x0; + buf[2] = 0x0; + buf[3] = 0x0; + buf[4] = (1 << 4); + } else { + /* Populate registers accordingly */ + buf[0] = (on & 0xFF); + buf[1] = ((on >> 8) & 0x0F); + buf[2] = (off & 0xFF); + buf[3] = ((off >> 8) & 0x0F); + } + + return quarkX1000_i2c_polling_write(buf, sizeof(buf), data->i2c_slave_addr); +} +int +pwm_pca9685_set_duty_cycle(struct pwm_pca9685_data *data, uint32_t pwm, uint8_t duty) +{ + uint32_t on, off; + + if(duty == 0) { + on = 0; + off = 0; + } else if(duty >= 100) { + on = PWM_ONE_PERIOD_TICKS + 1; + off = PWM_ONE_PERIOD_TICKS + 1; + } else { + on = PWM_ONE_PERIOD_TICKS * duty / 100; + off = PWM_ONE_PERIOD_TICKS - 1; + } + + return pwm_pca9685_set_values(data, pwm, on, off); +} +int +pwm_pca9685_init(struct pwm_pca9685_data *data, uint16_t i2c_slave_addr) +{ + uint8_t buf[2] = { 0 }; + + /* has to init after I2C master */ + if(!quarkX1000_i2c_is_available()) { + return -1; + } + + data->i2c_slave_addr = i2c_slave_addr; + + buf[0] = REG_MODE1; + buf[1] = (1 << 5); + + if(quarkX1000_i2c_polling_write(buf, 2, i2c_slave_addr) < 0) { + return -1; + } + + return 0; +} diff --git a/platform/galileo/drivers/pwm-pca9685.h b/platform/galileo/drivers/pwm-pca9685.h new file mode 100644 index 000000000..394e9357d --- /dev/null +++ b/platform/galileo/drivers/pwm-pca9685.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef CPU_X86_DRIVERS_PWM_PCA9685_H_ +#define CPU_X86_DRIVERS_PWM_PCA9685_H_ + +#include + +struct pwm_pca9685_data { + uint16_t i2c_slave_addr; +}; + +int pwm_pca9685_init(struct pwm_pca9685_data *data, uint16_t i2c_slave_addr); +int pwm_pca9685_set_duty_cycle(struct pwm_pca9685_data *data, uint32_t pwm, uint8_t duty); +int pwm_pca9685_set_values(struct pwm_pca9685_data *data, uint32_t pwm, uint32_t on, uint32_t off); + +#endif /* CPU_X86_DRIVERS_PWM_PCA9685_H_ */ diff --git a/platform/galileo/net/eth-conf.c b/platform/galileo/net/eth-conf.c new file mode 100644 index 000000000..061e0aae7 --- /dev/null +++ b/platform/galileo/net/eth-conf.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2015-2016, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include "eth-conf.h" +#include "net/eth-proc.h" +#include "contiki-net.h" +#include "net/linkaddr.h" + +#if NETSTACK_CONF_WITH_IPV6 +const linkaddr_t linkaddr_null = { { 0, 0, 0, 0, 0, 0 } }; +#else +/* 192.0.2.0/24 is a block reserved for documentation by RFC 5737. */ +#define SUBNET_IP 192, 0, 2 +#define NETMASK_IP 255, 255, 255, 0 +#define HOST_IP SUBNET_IP, 2 +#define GATEWAY_IP SUBNET_IP, 1 +#define NAMESERVER_IP GATEWAY_IP +#endif + +/*---------------------------------------------------------------------------*/ +void +eth_init(void) +{ +#if !NETSTACK_CONF_WITH_IPV6 + uip_ipaddr_t ip_addr; + +#define SET_IP_ADDR(x) \ + uip_ipaddr(&ip_addr, x) + + SET_IP_ADDR(HOST_IP); + uip_sethostaddr(&ip_addr); + + SET_IP_ADDR(NETMASK_IP); + uip_setnetmask(&ip_addr); + + SET_IP_ADDR(GATEWAY_IP); + uip_setdraddr(&ip_addr); + +#if WITH_DNS + SET_IP_ADDR(NAMESERVER_IP); + uip_nameserver_update(&ip_addr, UIP_NAMESERVER_INFINITE_LIFETIME); +#endif +#endif + + process_start(ð_process, NULL); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/galileo/net/eth-conf.h b/platform/galileo/net/eth-conf.h new file mode 100644 index 000000000..e84091809 --- /dev/null +++ b/platform/galileo/net/eth-conf.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef PLATFORM_GALILEO_ETH_CONF_H_ +#define PLATFORM_GALILEO_ETH_CONF_H_ + +void eth_init(void); + +#endif /* PLATFORM_GALILEO_ETH_CONF_H_ */ diff --git a/platform/galileo/net/eth-proc.c b/platform/galileo/net/eth-proc.c new file mode 100644 index 000000000..412d0c8cf --- /dev/null +++ b/platform/galileo/net/eth-proc.c @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include + +#include "contiki-net.h" +#include "net/ipv4/uip-neighbor.h" +#include "net/eth-proc.h" +#include "eth.h" + +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) +#define IPBUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) + +PROCESS(eth_process, "Ethernet"); + +/*---------------------------------------------------------------------------*/ +#if NETSTACK_CONF_WITH_IPV6 +static uint8_t +output(const uip_lladdr_t *dest_mac) +{ + if (dest_mac == NULL) { + /* broadcast packet */ + memset(&BUF->dest, 0xFF, UIP_LLH_LEN); + } else { + memcpy(&BUF->dest, dest_mac, UIP_LLH_LEN); + } + memcpy(&BUF->src, uip_lladdr.addr, UIP_LLH_LEN); + quarkX1000_eth_send(); + + return 0; +} +#else +static uint8_t +output(void) +{ + uip_arp_out(); + quarkX1000_eth_send(); + + return 0; +} +#endif /* NETSTACK_CONF_WITH_IPV6 */ +/*---------------------------------------------------------------------------*/ +static void +pollhandler(void) +{ + process_poll(ð_process); + quarkX1000_eth_poll(&uip_len); + + if(uip_len > 0) { +#if NETSTACK_CONF_WITH_IPV6 + if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) { + tcpip_input(); + } +#else + if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) { + uip_len -= sizeof(struct uip_eth_hdr); + tcpip_input(); + } else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + quarkX1000_eth_send(); + } + } +#endif /* NETSTACK_CONF_WITH_IPV6 */ + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(eth_process, ev, data) +{ + PROCESS_POLLHANDLER(pollhandler()); + + PROCESS_BEGIN(); + + tcpip_set_outputfunc(output); + + process_poll(ð_process); + + PROCESS_WAIT_UNTIL(ev == PROCESS_EVENT_EXIT); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/galileo/net/eth-proc.h b/platform/galileo/net/eth-proc.h new file mode 100644 index 000000000..88dbf4c7b --- /dev/null +++ b/platform/galileo/net/eth-proc.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#ifndef PLATFORM_GALILEO_NET_ETH_PROC_H_ +#define PLATFORM_GALILEO_NET_ETH_PROC_H_ + +#include "contiki.h" + +PROCESS_NAME(eth_process); + +#endif /* PLATFORM_GALILEO_NET_ETH_PROC_H_ */ diff --git a/platform/galileo/newlib-syscalls.c b/platform/galileo/newlib-syscalls.c new file mode 100644 index 000000000..fa098c6eb --- /dev/null +++ b/platform/galileo/newlib-syscalls.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2015, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +#include +#include + +#include "uart.h" +#include "helpers.h" + +#define CONSOLE_OUTPUT_DEV QUARK_X1000_UART_1 + +#define HEAP_MAX_SIZE 2048 + +static char _heap[HEAP_MAX_SIZE]; +static char *prog_break = _heap; + +int +_close_r(struct _reent *ptr, int file) +{ + /* Stubbed function */ + ptr->_errno = ENOTSUP; + return -1; +} +/*---------------------------------------------------------------------------*/ +void +_exit(int status) +{ + halt(); +} +/*---------------------------------------------------------------------------*/ +int +_getpid_r(struct _reent *ptr) +{ + /* Stubbed function */ + ptr->_errno = ENOTSUP; + return -1; +} +/*---------------------------------------------------------------------------*/ +int +_isatty_r(struct _reent *ptr, int file) +{ + /* Stubbed function */ + ptr->_errno = ENOTSUP; + return 0; +} +/*---------------------------------------------------------------------------*/ +int +_kill_r(struct _reent *ptr, int pid, int signal) +{ + /* Stubbed function */ + ptr->_errno = ENOTSUP; + return -1; +} +/*---------------------------------------------------------------------------*/ +int +_read_r(struct _reent *ptr, int file, char *buf, int len) +{ + /* Stubbed function */ + ptr->_errno = ENOTSUP; + return -1; +} +/*---------------------------------------------------------------------------*/ +int +_write_r(struct _reent *ptr, int file, const char *buf, int len) +{ + int ret; + int i; + + switch(file) { + case 0: + ptr->_errno = EBADF; + ret = -1; + break; + + case 1: + case 2: + for(i = 0; i < len; i++) { + /* Since file descriptors 1 and 2 (stdout and stderr) are mapped to a + * serial console, we should translate the 'newline' escape sequence + * to 'carriage return' (CR) followed by 'line feed' (LF) ASCII + * characters. + */ + if(buf[i] == '\n') { + quarkX1000_uart_tx(CONSOLE_OUTPUT_DEV, '\r'); + } + quarkX1000_uart_tx(CONSOLE_OUTPUT_DEV, buf[i]); + } + + ret = len; + break; + + default: + /* We don't support any filesystem yet. */ + ptr->_errno = ENOTSUP; + ret = -1; + break; + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +int +_lseek_r(struct _reent *ptr, int file, int p, int dir) +{ + /* Stubbed function */ + ptr->_errno = ENOTSUP; + return -1; +} +/*---------------------------------------------------------------------------*/ +int +_fstat_r(struct _reent *ptr, int file, struct stat *st) +{ + /* We don't support the standard input yet so file descriptor 0 is not + * supported by this function. Additionally, we don't have support for + * any filesystem thus file descriptors greater than 2 are not supported + * as well. + * + * We support standard ouput and error (file descriptors 1 and 2) only. + */ + if(file == 0 || file > 2) { + ptr->_errno = ENOTSUP; + return -1; + } + + st->st_mode = S_IFCHR; + return 0; +} +/*---------------------------------------------------------------------------*/ +caddr_t +_sbrk_r(struct _reent *ptr, int incr) +{ + char *prev_prog_break; + + /* If the new program break overruns the maximum heap address, we return + * "Out of Memory" error to the user. + */ + if(prog_break + incr > _heap + HEAP_MAX_SIZE) { + ptr->_errno = ENOMEM; + return NULL; + } + + prev_prog_break = prog_break; + + prog_break += incr; + + return prev_prog_break; +} diff --git a/platform/iris/Makefile.iris b/platform/iris/Makefile.iris deleted file mode 100644 index 1558857f5..000000000 --- a/platform/iris/Makefile.iris +++ /dev/null @@ -1,57 +0,0 @@ -CONTIKI_TARGET_DIRS = . dev dev/sensors -CONTIKI_CORE=contiki-iris -CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o - -SENSOR_BOARD_SOURCEFILES = mts300.c - -CONTIKI_TARGET_SOURCEFILES += adc.c rs232.c cfs-eeprom.c contiki-iris-main.c \ - leds-arch.c init-net.c node-id.c \ - clock.c spi.c rtimer-arch.c ds2401.c \ - battery-sensor.c slip.c slip_uart0.c - -CONTIKI_TARGET_SOURCEFILES += $(SENSOR_BOARD_SOURCEFILES) - -CONTIKIAVR=$(CONTIKI)/cpu/avr -CONTIKIBOARD=. - -# IRIS runs on Clock rate 8 MHz -CONTIKI_PLAT_DEFS = -DF_CPU=8000000UL -DAUTO_CRC_PADDING=2 #-DUSART_BAUD_115200 - -MCU=atmega1281 -AVRDUDE_OPTIONS=-V -AVRDUDE_PROGRAMMER=mib510 -#AVRDUDE_PROGRAMMER=jtag2 -#AVRDUDE_PORT=usb -AVRDUDE_PORT=$(PORT) - -include $(CONTIKIAVR)/Makefile.avr - - -%.od: %.$(TARGET) - avr-objdump -zhD $< > $@ - - -ifeq ($(PRGBOARD), ) - PRGBOARD = mib510 -endif - -ifeq ($(PORT), ) - ifeq ($(HOST_OS), Windows) - PORT = COM1 - else - PORT = /dev/ttyUSB0 - endif -endif - -PRGBOARD_FILE = $(CONTIKI)/platform/$(TARGET)/buildscripts/Makefile.$(PRGBOARD) -HAVE_PRGBOARD_FILE = $(wildcard $(PRGBOARD_FILE)) - -ifneq ($(strip $(HAVE_PRGBOARD_FILE)), ) - include $(PRGBOARD_FILE) -endif - -include $(CONTIKIAVR)/radio/Makefile.radio -ifeq ($(UIP_CONF_IPV6),1) -CFLAGS += -DWITH_UIP6=1 -endif - diff --git a/platform/iris/apps/Makefile b/platform/iris/apps/Makefile deleted file mode 100644 index 082acb6c9..000000000 --- a/platform/iris/apps/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -CONTIKI = ../../.. - -all: battery-monitor - -include $(CONTIKI)/Makefile.include diff --git a/platform/iris/apps/battery-monitor.c b/platform/iris/apps/battery-monitor.c deleted file mode 100644 index be4599458..000000000 --- a/platform/iris/apps/battery-monitor.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "contiki.h" -#include "dev/battery-sensor.h" -#include "lib/sensors.h" -#include /* For printf() */ -/*---------------------------------------------------------------------------*/ -PROCESS(battery_monitor_process, "Battery Voltage Monitor"); -AUTOSTART_PROCESSES(&battery_monitor_process); -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(battery_monitor_process, ev, data) -{ - static struct etimer et; - - PROCESS_BEGIN(); - - SENSORS_ACTIVATE(battery_sensor); - - while(1) { - - etimer_set(&et, CLOCK_SECOND * 2); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - /* - * Battery voltage calculation formula - * - * V(Battery Voltage) = v(Voltage Reference) * 1024 / ADC - * - * Where: - * v = 1.223 - * - */ - printf("ADC value : %d\n", battery_sensor.value(0)); - } - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/iris/apps/mts310/Makefile b/platform/iris/apps/mts310/Makefile deleted file mode 100644 index 744dd1613..000000000 --- a/platform/iris/apps/mts310/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -CONTIKI = ../../../.. - -all: accel-test light-test magnet-test mic-test - -include $(CONTIKI)/Makefile.include diff --git a/platform/iris/dev/adc.c b/platform/iris/dev/adc.c deleted file mode 100644 index 1748c053b..000000000 --- a/platform/iris/dev/adc.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2010, University of Colombo School of Computing - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -#include -#include "dev/adc.h" - -/*---------------------------------------------------------------------------*/ -void -adc_init() -{ - ADMUX = 0; - /* AVCC with external capacitor at AREF pin. */ - ADMUX |= _BV(REFS0); - /* Disable ADC interrupts. */ - ADCSRA &= ~( _BV(ADIE) | _BV(ADIF) ); - /* Set ADC prescaler to 64 and clear interrupt flag. */ - ADCSRA |= _BV(ADPS2) | _BV(ADPS1) | _BV(ADIE); - -} -/*---------------------------------------------------------------------------*/ -/* Poll based approach. The interrupt based adc is currently not used. - The ADC result is right adjusted. First 8 bits(from left) are in ADCL and - other two bits are in ADCH. See Atmega128 datasheet page 228. */ -uint16_t -get_adc(int channel) -{ - uint16_t reading; - - ADMUX |= (channel & 0x1F); - - /* Disable ADC interrupts. */ - ADCSRA &= ~_BV(ADIE); - /* Clear previous interrupts. */ - ADCSRA |= _BV(ADIF); - /* Enable ADC and start conversion. */ - ADCSRA |= _BV(ADEN) | _BV(ADSC); - /* Wait until conversion is completed. */ - while ( ADCSRA & _BV(ADSC) ); - /* Get first 8 bits. */ - reading = ADCL; - /* Get last two bits. */ - reading |= (ADCH & 3) << 8; - /* Disable ADC. */ - ADCSRA &= ~_BV(ADEN); - return reading; -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/iris/dev/sensors/mts300.c b/platform/iris/dev/sensors/mts300.c deleted file mode 100644 index cef039b60..000000000 --- a/platform/iris/dev/sensors/mts300.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) 2009, University of Colombo School of Computing - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - * @(#)$$ - */ - -/** - * \file - * Device drivers implementation for MTS300 sensor board. - * \author - * Kasun Hewage - */ - -#include "mts300.h" -/*---------------------------------------------------------------------------*/ -void -sounder_on() -{ SOUNDER_DDR |= SOUNDER_MASK; - SOUNDER_PORT &= ~SOUNDER_MASK; - SOUNDER_PORT |= SOUNDER_MASK; -} -/*---------------------------------------------------------------------------*/ -void -sounder_off() -{ - SOUNDER_PORT &= ~(SOUNDER_MASK); - SOUNDER_DDR &= ~(SOUNDER_MASK); -} -/*---------------------------------------------------------------------------*/ -void -adc_init() -{ - ADMUX = 0; - /* AVCC with external capacitor at AREF pin. */ - //ADMUX |= _BV(REFS0) - /* Disable ADC interrupts. */ - ADCSRA &= ~( _BV(ADIE) | _BV(ADIF) ); - /* Set ADC prescaler to 64 and clear interrupt flag. */ - ADCSRA |= _BV(ADPS2) | _BV(ADPS1) | _BV(ADIE); - -} -/*---------------------------------------------------------------------------*/ -/* Poll based approach. The interrupt based adc is currently not used. - The ADC result is right adjusted. First 8 bits(from left) are in ADCL and - other two bits are in ADCH. See Atmega128 datasheet page 228. */ -uint16_t -get_adc(int channel) -{ - uint16_t reading; - - ADMUX |= (channel & 0x1F); - - /* Disable ADC interrupts. */ - ADCSRA &= ~_BV(ADIE); - /* Clear previous interrupts. */ - ADCSRA |= _BV(ADIF); - /* Enable ADC and start conversion. */ - ADCSRA |= _BV(ADEN) | _BV(ADSC); - /* Wait until conversion is completed. */ - while ( ADCSRA & _BV(ADSC) ); - /* Get first 8 bits. */ - reading = ADCL; - /* Get last two bits. */ - reading |= (ADCH & 3) << 8; - /* Disable ADC. */ - ADCSRA &= ~_BV(ADEN); - return reading; -} -/*---------------------------------------------------------------------------*/ -uint16_t -get_light() -{ - uint16_t reading; - - /* Enable light sensor. */ - LIGHT_PORT |= LIGHT_PIN_MASK; - LIGHT_PORT_DDR |= LIGHT_PIN_MASK; - /* Disable temperature sensor. */ - TEMP_PORT_DDR &= ~TEMP_PIN_MASK; - TEMP_PORT &= ~TEMP_PIN_MASK; - /* Read ADC. */ - reading = get_adc(LIGHT_ADC_CHANNEL); - /* Disable light sensor. */ - LIGHT_PORT &= ~LIGHT_PIN_MASK; - LIGHT_PORT_DDR &= ~LIGHT_PIN_MASK; - return reading; -} -/*---------------------------------------------------------------------------*/ -uint16_t -get_temp() -{ - uint16_t reading; - - /* Disable light sensor. */ - LIGHT_PORT &= ~LIGHT_PIN_MASK; - LIGHT_PORT_DDR &= ~LIGHT_PIN_MASK; - /* Enable temperature sensor. */ - TEMP_PORT_DDR |= TEMP_PIN_MASK; - TEMP_PORT |= TEMP_PIN_MASK; - /* Read ADC. */ - reading = get_adc(TEMP_ADC_CHANNEL); - /* Disable temperature sensor. */ - TEMP_PORT_DDR &= ~TEMP_PIN_MASK; - TEMP_PORT &= ~TEMP_PIN_MASK; - - return reading; -} -/*---------------------------------------------------------------------------*/ -uint16_t -get_accx() -{ - uint16_t reading; - - /* Enable accelerometer. */ - ACCEL_PORT_DDR |= ACCEL_PIN_MASK; - ACCEL_PORT |= ACCEL_PIN_MASK; - /* Read ADC. */ - reading = get_adc(ACCELX_ADC_CHANNEL); - /* Enable accelerometer. */ - ACCEL_PORT_DDR &= ~ACCEL_PIN_MASK; - ACCEL_PORT &= ~ACCEL_PIN_MASK; - - return reading; -} -/*---------------------------------------------------------------------------*/ -uint16_t -get_accy() -{ - uint16_t reading; - - /* Enable accelerometer. */ - ACCEL_PORT_DDR |= ACCEL_PIN_MASK; - ACCEL_PORT |= ACCEL_PIN_MASK; - /* Read ADC. */ - reading = get_adc(ACCELY_ADC_CHANNEL); - /* Enable accelerometer. */ - ACCEL_PORT_DDR &= ~ACCEL_PIN_MASK; - ACCEL_PORT &= ~ACCEL_PIN_MASK; - - return reading; -} -/*---------------------------------------------------------------------------*/ -uint16_t -get_magx() -{ - uint16_t reading; - - /* Enable magnetometer. */ - MAGNET_PORT_DDR |= MAGNET_PIN_MASK; - MAGNET_PORT |= MAGNET_PIN_MASK; - /* Read ADC. */ - reading = get_adc(MAGNETX_ADC_CHANNEL); - /* Enable magnetometer. */ - MAGNET_PORT_DDR &= ~MAGNET_PIN_MASK; - MAGNET_PORT &= ~MAGNET_PIN_MASK; - - return reading; -} -/*---------------------------------------------------------------------------*/ -uint16_t -get_magy() -{ - uint16_t reading; - - /* Enable magnetometer. */ - MAGNET_PORT_DDR |= MAGNET_PIN_MASK; - MAGNET_PORT |= MAGNET_PIN_MASK; - /* Read ADC. */ - reading = get_adc(MAGNETY_ADC_CHANNEL); - /* Enable magnetometer. */ - MAGNET_PORT_DDR &= ~MAGNET_PIN_MASK; - MAGNET_PORT &= ~MAGNET_PIN_MASK; - - return reading; -} -/*---------------------------------------------------------------------------*/ -uint16_t -get_mic() -{ - uint16_t reading; - - /* Enable mic. */ - MIC_PORT_DDR |= MIC_PIN_MASK; - MIC_PORT |= MIC_PIN_MASK; - /* Read ADC. */ - reading = get_adc(MIC_ADC_CHANNEL); - /* Enable mic. */ - MIC_PORT_DDR &= ~MIC_PIN_MASK; - MIC_PORT &= ~MIC_PIN_MASK; - - return reading; -} -/*---------------------------------------------------------------------------*/ - diff --git a/platform/iris/dev/sensors/mts300.h b/platform/iris/dev/sensors/mts300.h deleted file mode 100644 index 0e07af034..000000000 --- a/platform/iris/dev/sensors/mts300.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2009, University of Colombo School of Computing - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - * @(#)$$ - */ - -/** - * \file - * Device drivers header file for MTS300 sensor board. - * \author - * Kasun Hewage - */ - -#ifndef MTS300_H_ -#define MTS300_H_ - -#include -#include "contiki-conf.h" - -#define SOUNDER_PORT PORTC -#define SOUNDER_MASK _BV(2) -#define SOUNDER_DDR DDRC - -/* MTS300CA and MTS310CA, the light sensor power is controlled - * by setting signal INT1(PORTE pin 5). - * Both light and thermistor use the same ADC channel. - */ -#define LIGHT_PORT_DDR DDRE -#define LIGHT_PORT PORTE -#define LIGHT_PIN_MASK _BV(5) -#define LIGHT_ADC_CHANNEL 1 - -/* MTS300CA and MTS310CA, the thermistor power is controlled - * by setting signal INT2(PORTE pin 6). - * Both light and thermistor use the same ADC channel. - */ -#define TEMP_PORT_DDR DDRE -#define TEMP_PORT PORTE -#define TEMP_PIN_MASK _BV(6) -#define TEMP_ADC_CHANNEL 1 - -/* Power is controlled to the accelerometer by setting signal - * PW4(PORTC pin 4), and the analog data is sampled on ADC3 and ADC4. - */ -#define ACCEL_PORT_DDR DDRC -#define ACCEL_PORT PORTC -#define ACCEL_PIN_MASK _BV(4) -#define ACCELX_ADC_CHANNEL 3 -#define ACCELY_ADC_CHANNEL 4 - -/* Power is controlled to the magnetometer by setting signal - * PW5(PORTC pin 5), and the analog data is sampled on ADC5 and ADC6. - */ -#define MAGNET_PORT_DDR DDRC -#define MAGNET_PORT PORTC -#define MAGNET_PIN_MASK _BV(5) -#define MAGNETX_ADC_CHANNEL 5 -#define MAGNETY_ADC_CHANNEL 6 - - -#define MIC_PORT_DDR DDRC -#define MIC_PORT PORTC -#define MIC_PIN_MASK _BV(3) -#define MIC_ADC_CHANNEL 2 - -void sounder_on(); -void sounder_off(); - -uint16_t get_light(); -uint16_t get_temp(); - -uint16_t get_accx(); -uint16_t get_accy(); - -uint16_t get_magx(); -uint16_t get_magy(); - -uint16_t get_mic(); - -void mts300_init(); - -#endif /* MTS300_H_ */ - - - diff --git a/platform/iris/init-net.c b/platform/iris/init-net.c deleted file mode 100644 index 06bf4eb03..000000000 --- a/platform/iris/init-net.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (c) 2010, University of Colombo School of Computing - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - * @(#)$$ - */ - -/** - * \file - * Network initialization for the MICAz port. - * \author - * Kasun Hewage - */ - -#include -#include -#include - -#include "contiki.h" -#include "rf230bb.h" -#include "dev/rs232.h" -#include "dev/slip.h" -#include "dev/leds.h" -#include "net/netstack.h" -#include "net/mac/frame802154.h" - -#include "dev/ds2401.h" -#include "sys/node-id.h" - -#if WITH_UIP6 -#include "net/ipv6/uip-ds6.h" -#endif /* WITH_UIP6 */ - -#if WITH_UIP -#include "net/ip/uip.h" -#include "net/ipv4/uip-fw.h" -#include "net/uip-fw-drv.h" -#include "net/ipv4/uip-over-mesh.h" -static struct uip_fw_netif slipif = - {UIP_FW_NETIF(192,168,1,2, 255,255,255,255, slip_send)}; -static struct uip_fw_netif meshif = - {UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)}; - -static uint8_t is_gateway; - -#endif /* WITH_UIP */ - -#define UIP_OVER_MESH_CHANNEL 8 - -/*---------------------------------------------------------------------------*/ -static void -set_rime_addr(void) -{ - linkaddr_t addr; - int i; - - memset(&addr, 0, sizeof(linkaddr_t)); -#if UIP_CONF_IPV6 - memcpy(addr.u8, ds2401_id, sizeof(addr.u8)); -#else - if(node_id == 0) { - for(i = 0; i < sizeof(linkaddr_t); ++i) { - addr.u8[i] = ds2401_id[7 - i]; - } - } else { - addr.u8[0] = node_id & 0xff; - addr.u8[1] = node_id >> 8; - } -#endif - linkaddr_set_node_addr(&addr); - printf_P(PSTR("Rime started with address ")); - for(i = 0; i < sizeof(addr.u8) - 1; i++) { - printf_P(PSTR("%d."), addr.u8[i]); - } - printf_P(PSTR("%d\n"), addr.u8[i]); -} - -/*--------------------------------------------------------------------------*/ -#if WITH_UIP -static void -set_gateway(void) -{ - if(!is_gateway) { - leds_on(LEDS_RED); - printf_P(PSTR("%d.%d: making myself the IP network gateway.\n\n"), - linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]); - printf_P(PSTR("IPv4 address of the gateway: %d.%d.%d.%d\n\n"), - uip_ipaddr_to_quad(&uip_hostaddr)); - uip_over_mesh_set_gateway(&linkaddr_node_addr); - uip_over_mesh_make_announced_gateway(); - is_gateway = 1; - } -} -#endif /* WITH_UIP */ -/*---------------------------------------------------------------------------*/ -void -init_net(void) -{ - - set_rime_addr(); - NETSTACK_RADIO.init(); - { - uint8_t longaddr[8]; - uint16_t shortaddr; - - shortaddr = (linkaddr_node_addr.u8[0] << 8) + - linkaddr_node_addr.u8[1]; - memset(longaddr, 0, sizeof(longaddr)); - linkaddr_copy((linkaddr_t *)&longaddr, &linkaddr_node_addr); - printf_P(PSTR("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n"), - longaddr[0], longaddr[1], longaddr[2], longaddr[3], - longaddr[4], longaddr[5], longaddr[6], longaddr[7]); - - rf230_set_pan_addr(IEEE802154_PANID, shortaddr, longaddr); - } - rf230_set_channel(RF_CHANNEL); - - -#if WITH_UIP6 - memcpy(&uip_lladdr.addr, ds2401_id, sizeof(uip_lladdr.addr)); - /* Setup nullmac-like MAC for 802.15.4 */ - /* sicslowpan_init(sicslowmac_init(&cc2420_driver)); */ - /* printf(" %s channel %u\n", sicslowmac_driver.name, RF_CHANNEL); */ - - /* Setup X-MAC for 802.15.4 */ - queuebuf_init(); - NETSTACK_RDC.init(); - NETSTACK_MAC.init(); - NETSTACK_NETWORK.init(); - - printf_P(PSTR("%s %s, channel check rate %d Hz, radio channel %d\n"), - NETSTACK_MAC.name, NETSTACK_RDC.name, - CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1: - NETSTACK_RDC.channel_check_interval()), - RF_CHANNEL); - - process_start(&tcpip_process, NULL); - - printf_P(PSTR("Tentative link-local IPv6 address ")); - { - uip_ds6_addr_t *lladdr; - int i; - lladdr = uip_ds6_get_link_local(-1); - for(i = 0; i < 7; ++i) { - printf_P(PSTR("%02x%02x:"), lladdr->ipaddr.u8[i * 2], - lladdr->ipaddr.u8[i * 2 + 1]); - } - printf_P(PSTR("%02x%02x\n"), lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]); - } - - if(!UIP_CONF_IPV6_RPL) { - uip_ipaddr_t ipaddr; - int i; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); - uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); - uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE); - printf_P(PSTR("Tentative global IPv6 address ")); - for(i = 0; i < 7; ++i) { - printf_P(PSTR("%02x%02x:"), - ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]); - } - printf_P(PSTR("%02x%02x\n"), - ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]); - } - -#else /* WITH_UIP6 */ - - NETSTACK_RDC.init(); - NETSTACK_MAC.init(); - NETSTACK_NETWORK.init(); - - printf_P(PSTR("%s %s, channel check rate %d Hz, radio channel %d\n"), - NETSTACK_MAC.name, NETSTACK_RDC.name, - CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0? 1: - NETSTACK_RDC.channel_check_interval()), - RF_CHANNEL); -#endif /* WITH_UIP6 */ - - -#if WITH_UIP - uip_ipaddr_t hostaddr, netmask; - - uip_init(); - uip_fw_init(); - - process_start(&tcpip_process, NULL); - process_start(&slip_process, NULL); - process_start(&uip_fw_process, NULL); - - slip_set_input_callback(set_gateway); - - /* Construct ip address from four bytes. */ - uip_ipaddr(&hostaddr, 172, 16, linkaddr_node_addr.u8[0], - linkaddr_node_addr.u8[1]); - /* Construct netmask from four bytes. */ - uip_ipaddr(&netmask, 255,255,0,0); - - uip_ipaddr_copy(&meshif.ipaddr, &hostaddr); - /* Set the IP address for this host. */ - uip_sethostaddr(&hostaddr); - /* Set the netmask for this host. */ - uip_setnetmask(&netmask); - - uip_over_mesh_set_net(&hostaddr, &netmask); - - /* Register slip interface with forwarding module. */ - //uip_fw_register(&slipif); - uip_over_mesh_set_gateway_netif(&slipif); - /* Set slip interface to be a default forwarding interface . */ - uip_fw_default(&meshif); - uip_over_mesh_init(UIP_OVER_MESH_CHANNEL); - printf_P(PSTR("uIP started with IP address %d.%d.%d.%d\n"), - uip_ipaddr_to_quad(&hostaddr)); -#endif /* WITH_UIP */ - - - -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/iris/platform-conf.h b/platform/iris/platform-conf.h deleted file mode 100644 index 48659ddae..000000000 --- a/platform/iris/platform-conf.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - */ - -/** - * \file - * A brief description of what this file is - * \author - * Niclas Finne - * Joakim Eriksson - */ - -#ifndef PLATFORM_CONF_H_ -#define PLATFORM_CONF_H_ - -/* - * Definitions below are dictated by the hardware and not really - * changeable! - */ -/* Platform name, type, and MCU clock rate */ -#define PLATFORM_NAME "Iris" -#define PLATFORM_TYPE IRIS -#ifndef F_CPU -#define F_CPU 8000000UL -#endif - -/* The AVR tick interrupt usually is done with an 8 bit counter around 128 Hz. - * 125 Hz needs slightly more overhead during the interrupt, as does a 32 bit - * clock_time_t. - */ -/* Clock ticks per second */ -#define CLOCK_CONF_SECOND 128 -#if 1 -/* 16 bit counter overflows every ~10 minutes */ -typedef unsigned short clock_time_t; -#define CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) -#define INFINITE_TIME 0xffff -#define RIME_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME INFINITE_TIME/CLOCK_CONF_SECOND /* Default uses 600 */ -#define COLLECT_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME INFINITE_TIME/CLOCK_CONF_SECOND /* Default uses 600 */ -#else -typedef unsigned long clock_time_t; -#define CLOCK_LT(a,b) ((signed long)((a)-(b)) < 0) -#define INFINITE_TIME 0xffffffff -#endif -/* These routines are not part of the contiki core but can be enabled in cpu/avr/clock.c */ -void clock_delay_msec(uint16_t howlong); -void clock_adjust_ticks(clock_time_t howmany); - -/* LED ports */ -#define LEDS_PxDIR DDRA // port direction register -#define LEDS_PxOUT PORTA // port register -#define LEDS_CONF_RED 0x04 //red led -#define LEDS_CONF_GREEN 0x02 // green led -#define LEDS_CONF_YELLOW 0x01 // yellow led - -/* COM port to be used for SLIP connection */ -#define SLIP_PORT RS232_PORT_0 - -/* Pre-allocated memory for loadable modules heap space (in bytes)*/ -#define MMEM_CONF_SIZE 256 - -/* Use the following address for code received via the codeprop - * facility - */ -#define EEPROMFS_ADDR_CODEPROP 0x8000 - -#define EEPROM_NODE_ID_START 0x00 - - -#define NETSTACK_CONF_RADIO rf230_driver - - -/* - * SPI bus configuration for the TMote Sky. - */ - -/* SPI input/output registers. */ -#define SPI_TXBUF SPDR -#define SPI_RXBUF SPDR - -#define BV(bitno) _BV(bitno) - -#define SPI_WAITFOREOTx() do { while (!(SPSR & BV(SPIF))); } while (0) -#define SPI_WAITFOREORx() do { while (!(SPSR & BV(SPIF))); } while (0) - -#define SCK 1 /* - Output: SPI Serial Clock (SCLK) - ATMEGA128 PORTB, PIN1 */ -#define MOSI 2 /* - Output: SPI Master out - slave in (MOSI) - ATMEGA128 PORTB, PIN2 */ -#define MISO 3 /* - Input: SPI Master in - slave out (MISO) - ATMEGA128 PORTB, PIN3 */ - -/* - * SPI bus - M25P80 external flash configuration. - */ - -#define FLASH_PWR 3 /* P4.3 Output */ -#define FLASH_CS 4 /* P4.4 Output */ -#define FLASH_HOLD 7 /* P4.7 Output */ - -/* Enable/disable flash access to the SPI bus (active low). */ - -#define SPI_FLASH_ENABLE() ( P4OUT &= ~BV(FLASH_CS) ) -#define SPI_FLASH_DISABLE() ( P4OUT |= BV(FLASH_CS) ) - -#define SPI_FLASH_HOLD() ( P4OUT &= ~BV(FLASH_HOLD) ) -#define SPI_FLASH_UNHOLD() ( P4OUT |= BV(FLASH_HOLD) ) - -#define CSN 0 - -#endif /* PLATFORM_CONF_H_ */ diff --git a/platform/jn516x/App_Stack_Size.ld b/platform/jn516x/App_Stack_Size.ld new file mode 100644 index 000000000..3eaaf34c0 --- /dev/null +++ b/platform/jn516x/App_Stack_Size.ld @@ -0,0 +1,46 @@ +/***************************************************************************** + * + * MODULE: App_Stack_Size.ld + * + * DESCRIPTION: Linker command file defining the default app stack size + * + **************************************************************************** + /* +* Copyright (c) 2015 NXP B.V. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. 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. +* 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. +* +* This file is part of the Contiki operating system. +* +* +*/ + +/* Default stack size for MAC applications. + * To override the default setting, copy this + * file to your apoplication build folder and + * alter the stack size as required. */ + +_stack_size = 2048; diff --git a/platform/jn516x/Makefile.jn516x b/platform/jn516x/Makefile.jn516x new file mode 100644 index 000000000..ca41ce3ae --- /dev/null +++ b/platform/jn516x/Makefile.jn516x @@ -0,0 +1,318 @@ +ifndef CONTIKI + $(error CONTIKI not defined! You must specify where CONTIKI resides!) +endif + +############################################################################## +# User definable make parameters that may be overwritten from the command line +ifdef CHIP + JENNIC_CHIP = $(CHIP) +else +JENNIC_CHIP ?= JN5168 +endif +ifdef MODULE + JN5168_MODULE = $(MODULE) +else + JN5168_MODULE ?= M00 +endif +JENNIC_PCB ?= DEVKIT4 +JENNIC_STACK ?= MAC +JENNIC_MAC ?= MiniMac +DISABLE_LTO ?= 1 +# can be set to SW or HW +DEBUG ?= None + +ifeq ($(HOST_OS),Windows) + SDK_BASE_DIR ?= C:/NXP/bstudio_nxp/sdk/JN-SW-4163 + FLASH_PROGRAMMER ?= ${SDK_BASE_DIR}/Tools/flashprogrammer/FlashCLI.exe +else + # Assume Linux + SDK_BASE_DIR ?= /usr/jn516x-sdk/JN-SW-4163 + FLASH_PROGRAMMER ?= $(CONTIKI)/tools/jn516x/JennicModuleProgrammer +endif + +############################################################################### +# Include NXP makefiles +include $(SDK_BASE_DIR)/Chip/Common/Build/config.mk +include $(SDK_BASE_DIR)/Platform/Common/Build/config.mk +include $(SDK_BASE_DIR)/Stack/Common/Build/config.mk + +# Add missing includes +INCFLAGS += -I$(COMPONENTS_BASE_DIR)/MicroSpecific/Include +INCFLAGS += -I$(COMPONENTS_BASE_DIR)/Recal/Include +INCFLAGS += -I$(COMPONENTS_BASE_DIR)/ProductionTestApi/Include +INCFLAGS += -I$(COMPONENTS_BASE_DIR)/Xcv/Include + +# Add missing libs and +# do not link with MiniMac nor MiniMacShim (we use MMAC) +LDLIBS += Recal_$(JENNIC_CHIP_FAMILY) +LDLIBS := $(subst MiniMacShim_JN516x, ,$(LDLIBS)) +ifeq ($(JENNIC_CHIP),JN5169) + LDLIBS := $(subst MiniMac_JN5169, ,$(LDLIBS)) +else +LDLIBS := $(subst MiniMac_JN516x, ,$(LDLIBS)) + LDLIBS += JPT_$(JENNIC_CHIP) +endif + +# Enable all warnings +CFLAGS += -Wall +# Disable warnings that result many false positives with the Contiki core +CFLAGS += -Wno-strict-aliasing +CFLAGS += -Wno-cast-align + +# Warings as error +ifdef WERROR +CFLAGS += -Werror +endif + +# Pass DEBUG as CFLAG +ifeq ($(DEBUG),SW) +CFLAGS += -DDEBUG=1 +endif + +# Path-independent cross-compiler +CC:=$(CROSS_COMPILE)-gcc +AS:=$(CROSS_COMPILE)-as +LD:=$(CROSS_COMPILE)-ls +AR:=$(CROSS_COMPILE)-ar +NM:=$(CROSS_COMPILE)-nm +STRIP:=$(CROSS_COMPILE)-strip +SIZE:=$(CROSS_COMPILE)-size +OBJCOPY:=$(CROSS_COMPILE)-objcopy +OBJDUMP:=$(CROSS_COMPILE)-objdump + +ARCH = jn516x-ccm-star.c exceptions.c rtimer-arch.c rtimer-arch-slow.c \ + slip_uart0.c clock.c micromac-radio.c \ + mtarch.c node-id.c watchdog.c log.c slip.c sprintf.c +# Default uart0 for printf and slip +TARGET_WITH_UART0 ?= 1 +TARGET_WITH_UART1 ?= 0 + +# Get required uart files +ifeq ($(TARGET_WITH_UART0),1) +WITH_UART = 1 +ARCH += uart0.c +endif +ifeq ($(TARGET_WITH_UART1),1) +WITH_UART = 1 +ARCH += uart1.c +endif +ifeq ($(WITH_UART),1) +ARCH += uart-driver.c +endif + +CONTIKI_TARGET_DIRS = . dev lib +CONTIKI_TARGET_MAIN = contiki-jn516x-main.c + +ifeq ($(JN516x_WITH_DR1175),1) +JN516x_WITH_DR1174 = 1 +CFLAGS += -DSENSOR_BOARD_DR1175 +CONTIKI_TARGET_DIRS += dev/dr1175 +ARCH += ht-sensor.c light-sensor.c leds-extension.c leds-arch-1175.c +endif + +ifeq ($(JN516x_WITH_DR1199),1) +JN516x_WITH_DR1174 = 1 +CFLAGS += -DSENSOR_BOARD_DR1199 +CONTIKI_TARGET_DIRS += dev/dr1199 +ARCH += pot-sensor.c leds-arch-1199.c +endif + +ifeq ($(JN516x_WITH_DR1174),1) +CFLAGS += -DSENSOR_BOARD_DR1174 +CONTIKI_TARGET_DIRS += dev/dr1174 +ARCH += button-sensor.c leds-arch.c +else +# Dongle is the default platform +JN516x_WITH_DONGLE = 1 +endif + +ifeq ($(JN516x_WITH_DONGLE),1) +CFLAGS += -DDONGLE_NODE +CONTIKI_TARGET_DIRS += dev/dongle +ARCH += leds-arch.c +endif + +ifeq ($(JENNIC_CHIP),JN5168) +CFLAGS += -DJN5168_$(JN5168_MODULE) +endif + +ifdef nodemac +CFLAGS += -DMACID=$(nodemac) +endif + +CLEAN += *.jn516x +CLEAN += *.jn516x.bin + +MODULES += core/net \ + core/net/mac \ + core/net/mac/contikimac \ + core/net/llsec core/net/llsec/noncoresec + +CONTIKI_TARGET_SOURCEFILES += $(ARCH) +CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) + +PROJECT_OBJECTFILES += ${addprefix $(OBJECTDIR)/,$(CONTIKI_TARGET_MAIN:.c=.o)} + +CFLAGS += $(INCFLAGS) + +# Library search paths +LDFLAGS += -L$(CHIP_BASE_DIR)/Build +LDFLAGS += -L$(CHIP_BASE_DIR)/Library + +LDLIBS := $(addsuffix _$(JENNIC_CHIP_FAMILY),$(APPLIBS)) $(LDLIBS) + +ifeq ($(HOST_OS),Windows) +# Windows assumes Cygwin. Substitute all paths in CFLAGS and LDFLAGS with Windows paths. +CFLAGS := $(patsubst -I/cygdrive/c/%,-Ic:/%,$(CFLAGS)) +LDFLAGS := $(patsubst -L/cygdrive/c/%,-Lc:/%,$(LDFLAGS)) +endif + +######################################################################## + +MOTELIST = python $(CONTIKI)/tools/jn516x/mote-list.py + +# Check if we are running under Windows +ifeq ($(HOST_OS),Windows) + USBDEVPREFIX=/dev/com + USBDEVBASENAME=COM + SERIALDUMP ?= $(CONTIKI)/tools/jn516x/serialdump-windows +else +ifeq ($(HOST_OS),Darwin) + USBDEVPREFIX= + USBDEVBASENAME=/dev/tty.usbserial- + SERIALDUMP ?= $(CONTIKI)/tools/jn516x/serialdump-macos +else + # Else we assume Linux + USBDEVPREFIX= + USBDEVBASENAME=/dev/ttyUSB + SERIALDUMP ?= $(CONTIKI)/tools/jn516x/serialdump-linux +endif +endif + +# Note: this logic is different from Sky +ifneq ("", "$(filter-out %all,$(filter %.upload serial% login, $(MAKECMDGOALS)))") +ifndef MOTE + $(error MOTE not defined! You must specify which MOTE (serial port) to use) +endif +endif +PORT = $(USBDEVBASENAME)$(MOTE) + +#### make targets + +######################################################################## +# Dependency, compilation and flash-programming rules + +.PHONY: all clean + +.PRECIOUS: %.elf + +%.d: clean + +%.nm: %.$(TARGET) + $(Q)$(NM) -nS $< > $@ + +%.dmp: %.$(TARGET) + $(Q)$(OBJDUMP) -d $< > $@ + +define FINALIZE_DEPENDENCY_ +# hack: subsitute windows path back to cygwin path +sed -e 's/c:\//\/cygdrive\/c\//' $(@:.o=.d) > $(@:.o=.$$$$); \ +cp $(@:.o=.$$$$) $(@:.o=.d); \ +sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:.o=.$$$$) >> $(@:.o=.d); \ +rm -f $(@:.o=.$$$$) +endef + +CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 +$(OBJECTDIR)/%.o: %.c | $(OBJECTDIR) + $(TRACE_CC) + $(Q)$(CC) $(CFLAGS) -MMD -c $< -o $@ + @$(FINALIZE_DEPENDENCY_) + +CUSTOM_RULE_LINK = 1 +ALLLIBS = $(addprefix -l,$(LDLIBS)) $(addprefix -l,$(LDSTACKLIBS)) $(addprefix -l,$(LDMYLIBS)) +ABS_APPLIBS = $(addsuffix _$(JENNIC_CHIP_FAMILY).a,$(addprefix $(COMPONENTS_BASE_DIR)/Library/lib,$(APPLIBS))) + +ifneq ($(wildcard $(SDK_BASE_DIR)/Components/Library/*),) +# The SDK is fully installed, proceed to linking and objcopy to ready-to-upload .jn516x.bin file +%.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a $(ABS_APPLIBS) + echo ${filter %.a,$^} + $(Q)$(CC) -Wl,--gc-sections $(LDFLAGS) -T$(LINKCMD) -o $@ -Wl,--start-group \ + $(patsubst /cygdrive/c/%,c:/%,${filter-out %.a,$^}) \ + $(patsubst /cygdrive/c/%,c:/%,${filter %.a,$^}) \ + $(ALLLIBS) -Wl,--end-group -Wl,-Map,contiki-$(TARGET).map + $(OBJCOPY) -S -O binary $@ $@.bin +else +# The SDK does not include libraries, only build objects and libraries, skip linking +%.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a + echo Creating empty $@ + touch $@ +endif + +%.$(TARGET).bin: %.$(TARGET) + $(Q)$(OBJCOPY) -S -O binary $< $@ + +symbols.c symbols.h: + @${CONTIKI}/tools/make-empty-symbols + +### Upload target to one jn516x mote specified by MOTE=portNumber +ifeq ($(HOST_OS),Windows) +%.upload: %.$(TARGET).bin + ${FLASH_PROGRAMMER} -a -c $(PORT) -B 1000000 -s -w -f $< +else +%.upload: %.$(TARGET).bin + ${FLASH_PROGRAMMER} -V 10 -v -s $(PORT) -I 38400 -P 1000000 -f $< +endif + +### Flash the given file +ifeq ($(HOST_OS),Windows) +%.flash: ${FLASH_PROGRAMMER} + ${FLASH_PROGRAMMER} -a -c $(PORT) -B 1000000 -s -w -f $*.$(TARGET).bin +else +%.flash: ${FLASH_PROGRAMMER} + ${FLASH_PROGRAMMER} -V 10 -v -s $(PORT) -I 38400 -P 1000000 -s -f $*.$(TARGET).bin +endif + +### List the ports with connected jn516x motes +motelist: + $(Q)$(MOTELIST) ${FLASH_PROGRAMMER} \# + +motelistmac: + $(Q)$(MOTELIST) ${FLASH_PROGRAMMER} \! + +motelistinfo: + $(Q)$(MOTELIST) ${FLASH_PROGRAMMER} \? + +### Upload target to all connected jn516x motes +%.uploadall: %.$(TARGET).bin + $(Q)$(MOTELIST) ${FLASH_PROGRAMMER} $< + +### Flash the given file to all connected jn516x motes +%.flashall: + $(Q)$(MOTELIST) ${FLASH_PROGRAMMER} $* + +### Dump output from all connected jn516x motes +serialdumpall: + $(Q)$(MOTELIST) ${FLASH_PROGRAMMER} \% $(SERIALDUMP) + +########### login: read serial line ############## +### USAGE: make TARGET=jn516x login UART_BAUDRATE={baudrate} {serial device} +### UART_BAUDRATE: i.e., 115200. default is 1000000 +### example: make TARGET=jn516x UART_BAUDRATE=115200 login MOTE=1 + +UART_BAUDRATE ?= 1000000 + +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + ($(MAKE) -C $(CONTIKI)/tools tunslip6 CFLAGS= LDFLAGS= LDLIBS= INCFLAGS=) + +$(SERIALDUMP): $(CONTIKI)/tools/jn516x/serialdump.c + (cd $(CONTIKI)/tools/jn516x; ${MAKE} $(notdir $(SERIALDUMP))) + +login: $(SERIALDUMP) + $(SERIALDUMP) -b${UART_BAUDRATE} $(USBDEVPREFIX)$(PORT) + +serialview: $(SERIALDUMP) + $(SERIALDUMP) -b${UART_BAUDRATE} $(USBDEVPREFIX)$(PORT) | $(CONTIKI)/tools/timestamp + +serialdump: $(SERIALDUMP) + $(SERIALDUMP) -b${UART_BAUDRATE} $(USBDEVPREFIX)$(PORT) | $(CONTIKI)/tools/timestamp | tee serialdump-$(notdir $(PORT))-`date +%Y%m%d-%H%M` diff --git a/platform/jn516x/README.md b/platform/jn516x/README.md new file mode 100644 index 000000000..1d45ca7a4 --- /dev/null +++ b/platform/jn516x/README.md @@ -0,0 +1,202 @@ +# NXP JN516x platform + +## Overview + +The JN516x series is a range of ultra low power, high performance wireless microcontrollers from NXP. They feature an enhanced 32-bit RISC processor (256kB/32kB/4kB Flash/RAM/EEPROM for JN5168), and also include a 2.4GHz IEEE802.15.4-compliant transceiver. +These system on chip (SoC) devices have the following main [features][jn516x-datasheet]: +* 32-bit RISC CPU (Beyond Architecture -- BA), 1 to 32MHz clock speed +* 2.4GHz IEEE802.15.4-compliant transceiver +* 128-bit AES security processor +* MAC accelerator with packet formatting, CRCs, address check, auto-acks, timers +* Transmit power 2.5dBm +* Receiver sensitivity -95dBm +* RX current 17mA, TX 15mA +* Integrated ultra low power sleep oscillator – 0.6μA +* Deep sleep current 0.12μA (Wake-up from IO) +* Time of Flight engine for ranging +* Antenna Diversity (Auto RX) +* 2.0V to 3.6V battery operation +* Supply voltage monitor with 8 programmable thresholds +* Built-in battery and temperature sensors +* Infra-red remote control transmitter +* Peripherals: I2C, SPI, 2x UART, 4-input 10-bit ADC, comparator, 5x PWM + +## Maintainers and Contact + +Long-term maintainers: +* Chris Gray, NXP, christopher.gray@nxp.com, github user: [NxpChrisGray](https://github.com/NxpChrisGray) +* Simon Duquennoy, SICS, simonduq@sics.se, github user: [simonduq](https://github.com/simonduq) + +Other contributors: +* Beshr Al Nahas, SICS (now Chalmers University), beshr@chalmers.se, github user: [beshrns](https://github.com/beshrns) +* Atis Elsts, SICS, atis.elsts@sics.se, github user: [atiselsts](https://github.com/atiselsts) + +## License + +All files are under BSD license, as described by the copyright statement in every source file. + +## Port Features + +The following features have been implemented: + * A radio driver with two modes (polling and interrupt based) + * CCM* driver with HW accelerated AES + * UART driver (with HW and SW flow control, 1'000'000 baudrate by default) + * Contiki tickless clock + * Contiki rtimers based on either + * the 32 kHz external oscillator + * or the internal 32 MHz oscillator (which gives a 16 MHz rtimer) + * CPU low-power mdoes + * doze mode: shallow sleep, 32 MHz oscillator (source of rtimer and radio clock) keeps running + * sleep mode: deeper sleep, 32 MHz oscillator turned off, next wakeup set on 32 kHz oscillator + * Periodic DCO recalibration + * HW random number generator used as a random seed for pseudo-random generator + * Watchdog, JN516x HW exception handlers + +The following hardware platforms have been tested: + * DR1174 evaluation board (with a button sensor) + * DR1175 sensor board (with humidity/temperature and light sensors) + * DR1199 sensor board (with potentiometer and button sensors) + * USB dongle + +## TODO list + +The following features are planned: + * Time-accurate radio primitives ("send at", "listen until") + * External storage + +## Requirements + +To start using JN516x with Contiki, the following are required: + * The toolchain and Software Development Kit to compile Contiki for JN516x + * Drivers so that your OS can communicate with your hardware + * Software to upload images to the JN516x + +### Install a Toolchain + +The toolchain used to build Contiki for JN516x is `ba-elf-gcc`. +The compiler as well as the binary libraries required to link the executables can be downloaded from NXP. To express your interest in obtaining them, go to [NXP 802.15.4 software page][NXP-802.15.4-software], select "JN-SW-4163", and contact the NXP support through the web form. The download link is then obtained via e-mail (allow 1+ working day for a reply). +The example applications in this port have been tested with compiler version `gcc-4.7.4-ba-r36379`. + +Linux and Windows instructions: +* On Linux: A compiled version for linux 64-bit is available: download [this](http://simonduq.github.io/resources/ba-elf-gcc-4.7.4-part1.tar.bz2) and [this](http://simonduq.github.io/resources/ba-elf-gcc-4.7.4-part2.tar.bz2) file, extract both in `/usr/ba-elf-gcc` such and add `/usr/ba-elf-gcc/bin` to your `$PATH` environment variable. Place the JN516x SDK under `/usr/jn516x-sdk`. +* On Windows: Run the setup program and select `C:/NXP/bstudio_nxp/` as install directory. Also make sure your PATH environment variable points to the compiler binaries (by default in `C:/NXP/bstudio_nxp/sdk/Tools/ba-elf-ba2-r36379/bin`). + +### Drivers + +The JN516x platforms feature FTDI serial-to-USB modules. The driver is commonly found in most OS, but if required it can be downloaded from + +### Device Enumerations +For the UART, serial line settings are 1000000 8N1, no flow control. + +Once all drivers have been installed correctly: +* On Windows, devices will appear as a virtual COM port. +* On Linux and OS X, devices will appear as `/dev/tty*`. + +### Software to Program the Nodes + +The JN516x can be programmed via the serial boot loader on the chip. +* On Linux, nodes can be programmed via the serial boot loader using the [JennicModuleProgrammer] tool. It is pre-installed under `tools/jn516x/JennicModuleProgrammer`. +* On Windows, nodes are programmed using NXP's Flash Programmer. There are two versions of it: GUI and command line. The Contiki make system is configured to use the command line version. By default it looks for the programmer in the SDK base directory under `Tools/flashprogrammer/FlashCLI.exe`. With the default SDK installation path the file should be located under `C:/NXP/bstudio_nxp/sdk/JN-SW-4163/Tools/flashprogrammer/FlashCLI.exe`. Modify `platforms/jn516x/Makefile.common` to change this default location. + +## Using the Port + +The following examples are intended to work off-the-shelf: +* Platform-specific examples under `examples/jn516x` +* All platform-independent Contiki application examples + +### Building an example + +To build the classic "hello world" example, navigate to `examples/hello-world`. It is recommended to either set the `TARGET` environmental variable or to save the `jn516x` platform as the default make target. To do that, run: + +`make TARGET=jn516x savetarget` + +Then run `make hello-world` to compile the application for JN516x platform. + +### Uploading an example + +Run the `upload` command to program the binary image on it: +`make hello-world.upload MOTE=0` + +The `MOTE` argument is used to specify to which of the ports the device is connected. For example, if there is a single mote connected to `/dev/ttyUSB3` in Linux (or, alternatively, `COM3` in Windows), the right command would be: +`make hello-world.upload MOTE=3` + +Note that on Windows, the FTDI drivers are able to switch the board to programming mode before uploading the image. + +On Linux, the drivers are not able to do so yet. We use a modified bootloader for JN516x, where nodes wait 5s in programming mode after a reset. You simply need to reset them before using `make upload`. The modified bootloader can be downloaded [here](http://simonduq.github.io/resources/BootLoader_JN5168.ba2.bin) and installed using a JTAG programmer, or alternatively, [this image](http://simonduq.github.io/resources/BootLoaderUpdater_JN5168.bin) can be installed as a normal application using the normal Windows tools. Once the device resets, this application will run and will then install the new boot loader. It generates some status output over UART0 at 115200 baud during this process. **Warning**: use the images above at your risk; NXP does not accept responsibility for any devices that are rendered unusable as a result of using it. + +### Listening to output + +Run the `login` command to start the `serialdump` application. +`make login MOTE=3` + +On Linux: after the application has started, press the reset button on the node. + +### Platform-specific make targets + +* `.flash` - flash the (pre-compiled) application to a JN516x mote (specified via the `MOTE` variable) +* `.flashall` - flash the (pre-compiled) application to all all connected JN516x motes +* `.upload` - compile and flash the application to a JN516x mote (specified via the `MOTE` variable) +* `.uploadall` - compile and flash the application to all all connected JN516x motes +* `login`, `serialview`, `serialdump` - dump serial port output from a JN516x mote (specified via the `MOTE` variable) +* `serialdumpall` - dump serial port output from all connected JN516x motes +* `motelist` - list all connected JN516x motes. +* `motelistmac` - list MAC addresses of all connected JN516x motes (Note: not implemented on Linux!) +* `motelistinfo` - list info about all connected JN516x motes (Note: very limited functionality on Linux!) + +*Troubleshooting:* you need a working Python installation for these commands to work. On Windows, make sure Python executable is in your `PATH`. + +### Compiling for different MCUs and boards + +The platforms can selected by using `Makefile` variables. + +The following MCU models are supported: +* `JN5164` - 160kB/32kB/4kB Flash/RAM/EEPROM +* `JN5168` - 256kB/32kB/4kB Flash/RAM/EEPROM (default MCU) +* `JN5169` - 512kB/32kB/4kB Flash/RAM/EEPROM + +Set `CHIP` variable to change this; for example, to select JN5164 use: +`make CHIP=JN5164` + +The JN5168 has four module variants available: +* `M00` - Standard power, integrated antenna (default module) +* `M03` - Standard power, uFL connector +* `M05` - Medium power, uFL connector +* `M06` - High power, uFL connector + +The `M05` and `M06` need to control the internal power amplifier. Set the `MODULE` variable to select the module, for example: +`make CHIP=JN5168 MODULE=M05` + +The following platform-specific configurations are supported: +* DR1174 evaluation kit; enable this with `JN516x_WITH_DR1174 = 1` in your makefile +* DR1174 with DR1175 sensor board; enable this with `JN516x_WITH_DR1175 = 1` (will set `JN516x_WITH_DR1174` automatically) +* DR1174 with DR1199 sensor board; enable this with `JN516x_WITH_DR1199 = 1` (will set `JN516x_WITH_DR1174` automatically) +* USB dongle; enable this with `JN516x_WITH_DONGLE = 1` + +### Enabling specific hardware features + +The JN516X Contiki platform supports sleep mode (with RAM retention and keeping the external oscillator on). To enable sleeping, configure `JN516X_SLEEP_CONF_ENABLED=1`. + +Sleeping will only happen if there at least 50 ms until the next rtimer or etimer. Also, the system will wake up ~10 ms before the next timer should fire in order to reinitialize all hardware peripherals. + +The JN516X Contiki platform also supports rtimers at two different speeds: 16 MHz and 32 kHz. By default, the high-speed timer is used. The two timers have similar expected accuracy (drift ppm), but the 16 MHz one has higher precision. However, the low-speed timers are also kept running during sleeping. + +To enable the low-frequency timer option, set `RTIMER_USE_32KHZ=1`. An external crystal oscillator is required to achieve reasonable accuracy in this case. This oscilator is present on most platforms, and is enabled automatically if either 32kHz timers or sleeping are enabled. + +### Node IEEE/RIME/IPv6 Addresses + +Nodes will autoconfigure their IPv6 address based on their 64-bit IEEE/MAC address. The 64-bit MAC address is read directly from JN516x System on Chip. +The 16-bit RIME address and the Node ID are set from the last 16-bits of the 64-bit MAC address. + +## Additional documentation + +1. [Data Sheet: JN516x IEEE802.15.4 Wireless Microcontroller][jn516x-datasheet] +2. [JN516x web page][jn516x-web] +3. [JN5168 web page][jn5168-web] +4. [JN516x user manuals][user-manuals] + +[jn516x-datasheet]: http://www.nxp.com/documents/data_sheet/JN516X.pdf +[jn516x-web]: http://www.nxp.com/products/microcontrollers/product_series/jn516x +[jn5168-web]: http://www.nxp.com/products/microcontrollers/product_series/jn516x/JN5168.html +[user-manuals]: http://www.nxp.com/technical-support-portal/#/tid=1,sid=,bt=,tab=usermanuals,p=1,rpp=,sc=,so=,jump= +[NXP-802.15.4-software]: http://www.nxp.com/techzones/wireless-connectivity/ieee802-15-4.html +[JennicModuleProgrammer]: https://github.com/WRTIOT/JennicModuleProgrammer diff --git a/platform/iris/contiki-conf.h b/platform/jn516x/contiki-conf.h similarity index 60% rename from platform/iris/contiki-conf.h rename to platform/jn516x/contiki-conf.h index adda6ae16..1a326f62b 100644 --- a/platform/iris/contiki-conf.h +++ b/platform/jn516x/contiki-conf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, University of Colombo School of Computing + * Copyright (c) 2015, SICS Swedish ICT. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,110 +28,122 @@ * * This file is part of the Contiki operating system. * - * @(#)$$ - */ - -/** - * \file - * Configuration for MICAz platform. - * - * \author - * Kasun Hewage */ #ifndef CONTIKI_CONF_H_ #define CONTIKI_CONF_H_ -#define HAVE_STDINT_H -#include "avrdef.h" - +#ifdef PLATFORM_CONF_H +#include PLATFORM_CONF_H +#else #include "platform-conf.h" +#endif /* PLATFORM_CONF_H */ -#if WITH_UIP6 +#ifndef CCM_STAR_CONF +#define CCM_STAR_CONF ccm_star_driver_jn516x +#endif /* CCM_STAR_CONF */ -/* Network setup for IPv6 */ -#define NETSTACK_CONF_NETWORK sicslowpan_driver +#ifndef NETSTACK_CONF_MAC #define NETSTACK_CONF_MAC csma_driver +#endif /* NETSTACK_CONF_MAC */ + +#ifndef NETSTACK_CONF_RDC #define NETSTACK_CONF_RDC nullrdc_driver +#endif /* NETSTACK_CONF_RDC */ + +#ifndef NETSTACK_CONF_RADIO +#define NETSTACK_CONF_RADIO micromac_radio_driver +#endif /* NETSTACK_CONF_RADIO */ + +#ifndef NETSTACK_CONF_FRAMER #define NETSTACK_CONF_FRAMER framer_802154 - -#define RF230_CONF_AUTOACK 1 -#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 -#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 -#define CXMAC_CONF_ANNOUNCEMENTS 0 - -#else /* WITH_UIP6 */ - -/* Network setup for non-IPv6 (rime). */ - -#define NETSTACK_CONF_NETWORK rime_driver -#define NETSTACK_CONF_MAC csma_driver -#define NETSTACK_CONF_RDC cxmac_driver -#define NETSTACK_CONF_FRAMER framer_802154 - -#define RF230_CONF_AUTOACK 1 -#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 - -#define COLLECT_CONF_ANNOUNCEMENTS 1 -#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 1 -#define CXMAC_CONF_ANNOUNCEMENTS 0 -#define CXMAC_CONF_COMPOWER 1 -#define CONTIKIMAC_CONF_ANNOUNCEMENTS 0 -#define CONTIKIMAC_CONF_COMPOWER 1 - -#define COLLECT_NBR_TABLE_CONF_MAX_NEIGHBORS 32 - -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_FRAMER */ #define PACKETBUF_CONF_ATTRS_INLINE 1 -#ifndef RF_CHANNEL -#define RF_CHANNEL 26 -#endif /* RF_CHANNEL */ - -#define CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT 0 - +#ifndef IEEE802154_CONF_PANID #define IEEE802154_CONF_PANID 0xABCD +#endif /* IEEE802154_CONF_PANID */ - -#define AODV_COMPLIANCE -#define AODV_NUM_RT_ENTRIES 32 +#ifndef ENERGEST_CONF_ON +#define ENERGEST_CONF_ON 1 +#endif /* ENERGEST_CONF_ON */ #define WITH_ASCII 1 #define PROCESS_CONF_NUMEVENTS 8 #define PROCESS_CONF_STATS 1 -#ifdef WITH_UIP6 +#if !defined NETSTACK_CONF_WITH_IPV6 && !defined NETSTACK_CONF_WITH_IPV4 && !defined NETSTACK_CONF_WITH_RIME +#define NETSTACK_CONF_WITH_IPV6 1 +#endif /* NETSTACK_CONF_ not defined */ + +/* Network setup for IP */ +#if NETSTACK_CONF_WITH_IPV4 || NETSTACK_CONF_WITH_IPV6 #define LINKADDR_CONF_SIZE 8 +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 16 +#endif + +/* Network setup for non-IP (rime). */ +#else + +#define LINKADDR_CONF_SIZE 2 + +#ifndef COLLECT_NEIGHBOR_CONF_MAX_COLLECT_NEIGHBORS +#define COLLECT_NEIGHBOR_CONF_MAX_COLLECT_NEIGHBORS 32 +#endif /* COLLECT_NEIGHBOR_CONF_MAX_COLLECT_NEIGHBORS */ + +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 16 +#endif /* QUEUEBUF_CONF_NUM */ + +#endif /* NETSTACK_CONF_WITH_IPV4 || NETSTACK_CONF_WITH_IPV6 */ + +/* Network setup for IPv6 */ +#if NETSTACK_CONF_WITH_IPV6 + +/* Network setup for IPv6 */ +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#define UIP_CONF_BROADCAST 1 + +/* Configure NullRDC for when it is selected */ +#define NULLRDC_CONF_802154_AUTOACK_HW 1 + #define UIP_CONF_LL_802154 1 #define UIP_CONF_LLH_LEN 0 #define UIP_CONF_ROUTER 1 +#ifndef UIP_CONF_IPV6_RPL #define UIP_CONF_IPV6_RPL 1 +#endif /* UIP_CONF_IPV6_RPL */ /* configure number of neighbors and routes */ -#define NBR_TABLE_CONF_MAX_NEIGHBORS 5 -#define UIP_CONF_MAX_ROUTES 5 +#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */ +#ifndef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 20 +#endif /* UIP_CONF_MAX_ROUTES */ -#define RPL_CONF_MAX_PARENTS 4 -#define NBR_TABLE_CONF_MAX_NEIGHBORS 8 - -#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_RETRANS_TIMER 10000 -#define UIP_CONF_IPV6 1 +#ifndef UIP_CONF_IPV6_QUEUE_PKT #define UIP_CONF_IPV6_QUEUE_PKT 0 +#endif /* UIP_CONF_IPV6_QUEUE_PKT */ #define UIP_CONF_IPV6_CHECKS 1 #define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_ND6_MAX_PREFIXES 3 #define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_IP_FORWARD 0 -#define UIP_CONF_BUFFER_SIZE 240 +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 1280 +#endif #define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 #define SICSLOWPAN_CONF_COMPRESSION_HC1 1 @@ -141,55 +153,38 @@ #define SICSLOWPAN_CONF_FRAG 1 #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ -#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#else /* WITH_UIP6 */ -#define UIP_CONF_IP_FORWARD 1 -#define UIP_CONF_BUFFER_SIZE 128 -#endif /* WITH_UIP6 */ - -#define UIP_CONF_ICMP_DEST_UNREACH 1 - -#if !WITH_UIP && !WITH_UIP6 -#define QUEUEBUF_CONF_NUM 8 -#else -#define QUEUEBUF_CONF_NUM 4 -#endif - -#define TIMESYNCH_CONF_ENABLED 1 -#define RF230_CONF_TIMESTAMPS 0 -#define RF230_CONF_SYMBOL_LOOP_COUNT 500 - -#define WITH_NULLMAC 0 - -#define CCIF -#define CLIF - -/* The process names are not used to save RAM */ -#define PROCESS_CONF_NO_PROCESS_NAMES 0 - #define UIP_CONF_ICMP_DEST_UNREACH 1 #define UIP_CONF_DHCP_LIGHT -#define UIP_CONF_LLH_LEN 0 +#ifndef UIP_CONF_RECEIVE_WINDOW #define UIP_CONF_RECEIVE_WINDOW 48 +#endif +#ifndef UIP_CONF_TCP_MSS #define UIP_CONF_TCP_MSS 48 +#endif #define UIP_CONF_MAX_CONNECTIONS 4 #define UIP_CONF_MAX_LISTENPORTS 8 #define UIP_CONF_UDP_CONNS 12 -#define UIP_CONF_FWCACHE_SIZE 15 +#define UIP_CONF_FWCACHE_SIZE 30 #define UIP_CONF_BROADCAST 1 -//#define UIP_ARCH_IPCHKSUM 1 +#define UIP_ARCH_CHKSUM 0 +#define UIP_ARCH_ADD32 0 #define UIP_CONF_UDP 1 #define UIP_CONF_UDP_CHECKSUMS 1 #define UIP_CONF_PINGADDRCONF 0 #define UIP_CONF_LOGGING 0 +#define LOG_CONF_ENABLED 0 #define UIP_CONF_TCP_SPLIT 0 -typedef unsigned short uip_stats_t; -typedef unsigned long off_t; +#define UIP_CONF_BYTE_ORDER UIP_BIG_ENDIAN +#define UIP_CONF_LOGGING 0 +#endif /* NETSTACK_CONF_WITH_IPV6 */ + +/* include the project config */ +/* PROJECT_CONF_H might be defined in the project Makefile */ #ifdef PROJECT_CONF_H #include PROJECT_CONF_H #endif /* PROJECT_CONF_H */ diff --git a/platform/jn516x/contiki-jn516x-main.c b/platform/jn516x/contiki-jn516x-main.c new file mode 100644 index 000000000..9a64365e6 --- /dev/null +++ b/platform/jn516x/contiki-jn516x-main.c @@ -0,0 +1,569 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the Contiki OS + * + */ + +/** + * \file + * Contiki main for NXP JN516X platform + * + * \author + * Beshr Al Nahas + * Atis Elsts + */ + +#include +#include +#include + +#include "dev/watchdog.h" +#include +#include +#include +#include "dev/uart0.h" +#include "dev/uart-driver.h" + +#include "contiki.h" +#include "net/netstack.h" + +#include "dev/serial-line.h" + +#include "net/ip/uip.h" +#include "dev/leds.h" + +#include "lib/random.h" +#include "sys/node-id.h" +#include "rtimer-arch.h" + +#if NETSTACK_CONF_WITH_IPV6 +#include "net/ipv6/uip-ds6.h" +#endif /* NETSTACK_CONF_WITH_IPV6 */ + +#include "net/rime/rime.h" + +#include "dev/micromac-radio.h" +#include "MMAC.h" +/* Includes depending on connected sensor boards */ +#if SENSOR_BOARD_DR1175 +#include "light-sensor.h" +#include "ht-sensor.h" +SENSORS(&light_sensor, &ht_sensor); +#elif SENSOR_BOARD_DR1199 +#include "button-sensor.h" +#include "pot-sensor.h" +SENSORS(&pot_sensor, &button_sensor); +#else +#include "dev/button-sensor.h" +/* #include "dev/pir-sensor.h" */ +/* #include "dev/vib-sensor.h" */ +/* &pir_sensor, &vib_sensor */ +SENSORS(&button_sensor); +#endif +unsigned char node_mac[8]; + +/* Symbol defined by the linker script + * marks the end of the stack taking into account the used heap */ +extern uint32_t heap_location; + +#ifndef NETSTACK_CONF_WITH_IPV4 +#define NETSTACK_CONF_WITH_IPV4 0 +#endif + +#if NETSTACK_CONF_WITH_IPV4 +#include "net/ip/uip.h" +#include "net/ipv4/uip-fw.h" +#include "net/ipv4/uip-fw-drv.h" +#include "net/ipv4/uip-over-mesh.h" +static struct uip_fw_netif slipif = +{ UIP_FW_NETIF(192, 168, 1, 2, 255, 255, 255, 255, slip_send) }; +static struct uip_fw_netif meshif = +{ UIP_FW_NETIF(172, 16, 0, 0, 255, 255, 0, 0, uip_over_mesh_send) }; + +#define UIP_OVER_MESH_CHANNEL 8 +static uint8_t is_gateway; +#endif /* NETSTACK_CONF_WITH_IPV4 */ + +#ifdef EXPERIMENT_SETUP +#include "experiment-setup.h" +#endif + +/* _EXTRA_LPM is the sleep mode, _LPM is the doze mode */ +#define ENERGEST_TYPE_EXTRA_LPM ENERGEST_TYPE_LPM + +static void main_loop(void); + +#if DCOSYNCH_CONF_ENABLED +static unsigned long last_dco_calibration_time; +#endif +static uint64_t sleep_start; +static uint32_t sleep_start_ticks; + +/*---------------------------------------------------------------------------*/ +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) do { printf(__VA_ARGS__); } while(0) +#else +#define PRINTF(...) do {} while(0) +#endif +/*---------------------------------------------------------------------------*/ +/* Reads MAC from SoC + * Must be called before node_id_restore() + * and network addresses initialization */ +static void +init_node_mac(void) +{ + tuAddr psExtAddress; + vMMAC_GetMacAddress(&psExtAddress.sExt); + node_mac[7] = psExtAddress.sExt.u32L; + node_mac[6] = psExtAddress.sExt.u32L >> (uint32_t)8; + node_mac[5] = psExtAddress.sExt.u32L >> (uint32_t)16; + node_mac[4] = psExtAddress.sExt.u32L >> (uint32_t)24; + node_mac[3] = psExtAddress.sExt.u32H; + node_mac[2] = psExtAddress.sExt.u32H >> (uint32_t)8; + node_mac[1] = psExtAddress.sExt.u32H >> (uint32_t)16; + node_mac[0] = psExtAddress.sExt.u32H >> (uint32_t)24; +} +/*---------------------------------------------------------------------------*/ +#if !PROCESS_CONF_NO_PROCESS_NAMES +static void +print_processes(struct process *const processes[]) +{ + /* const struct process * const * p = processes;*/ + PRINTF("Starting"); + while(*processes != NULL) { + PRINTF(" '%s'", (*processes)->name); + processes++; + } + putchar('\n'); +} +#endif /* !PROCESS_CONF_NO_PROCESS_NAMES */ +/*---------------------------------------------------------------------------*/ +#if NETSTACK_CONF_WITH_IPV4 +static void +set_gateway(void) +{ + if(!is_gateway) { + leds_on(LEDS_RED); + printf("%d.%d: making myself the IP network gateway.\n\n", + linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]); + printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n", + uip_ipaddr_to_quad(&uip_hostaddr)); + uip_over_mesh_set_gateway(&linkaddr_node_addr); + uip_over_mesh_make_announced_gateway(); + is_gateway = 1; + } +} +#endif /* NETSTACK_CONF_WITH_IPV4 */ +/*---------------------------------------------------------------------------*/ +static void +start_autostart_processes() +{ +#if !PROCESS_CONF_NO_PROCESS_NAMES + print_processes(autostart_processes); +#endif /* !PROCESS_CONF_NO_PROCESS_NAMES */ + autostart_start(autostart_processes); +} +/*---------------------------------------------------------------------------*/ +#if NETSTACK_CONF_WITH_IPV6 +static void +start_uip6(void) +{ + NETSTACK_NETWORK.init(); + +#ifndef WITH_SLIP_RADIO + process_start(&tcpip_process, NULL); +#else +#if WITH_SLIP_RADIO == 0 + process_start(&tcpip_process, NULL); +#endif +#endif /* WITH_SLIP_RADIO */ + +#if DEBUG + PRINTF("Tentative link-local IPv6 address "); + { + uip_ds6_addr_t *lladdr; + int i; + lladdr = uip_ds6_get_link_local(-1); + for(i = 0; i < 7; ++i) { + PRINTF("%02x%02x:", lladdr->ipaddr.u8[i * 2], + lladdr->ipaddr.u8[i * 2 + 1]); + /* make it hardcoded... */ + } + lladdr->state = ADDR_AUTOCONF; + + PRINTF("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]); + } +#endif /* DEBUG */ + + if(!UIP_CONF_IPV6_RPL) { + uip_ipaddr_t ipaddr; + int i; + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); + uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE); + PRINTF("Tentative global IPv6 address "); + for(i = 0; i < 7; ++i) { + PRINTF("%02x%02x:", + ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]); + } + PRINTF("%02x%02x\n", + ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]); + } +} +#endif /* NETSTACK_CONF_WITH_IPV6 */ +/*---------------------------------------------------------------------------*/ +static void +set_linkaddr(void) +{ + int i; + linkaddr_t addr; + memset(&addr, 0, LINKADDR_SIZE); +#if NETSTACK_CONF_WITH_IPV6 + memcpy(addr.u8, node_mac, sizeof(addr.u8)); +#else + if(node_id == 0) { + for(i = 0; i < LINKADDR_SIZE; ++i) { + addr.u8[i] = node_mac[LINKADDR_SIZE - 1 - i]; + } + } else { + addr.u8[0] = node_id & 0xff; + addr.u8[1] = node_id >> 8; + } +#endif + linkaddr_set_node_addr(&addr); +#if DEBUG + PRINTF("Link-layer address: "); + for(i = 0; i < sizeof(addr.u8) - 1; i++) { + PRINTF("%d.", addr.u8[i]); + } + PRINTF("%d\n", addr.u8[i]); +#endif +} +/*---------------------------------------------------------------------------*/ +bool_t +xosc_init(void) +{ + /* The internal 32kHz RC oscillator is used by default; + * Initialize and enable the external 32.768kHz crystal. + */ + vAHI_Init32KhzXtal(); + /* Switch to the 32.768kHz crystal. + * This will block and wait up to 1 sec for it to stabilize. */ + return bAHI_Set32KhzClockMode(E_AHI_XTAL); +} +/*---------------------------------------------------------------------------*/ +#if WITH_TINYOS_AUTO_IDS +uint16_t TOS_NODE_ID = 0x1234; /* non-zero */ +uint16_t TOS_LOCAL_ADDRESS = 0x1234; /* non-zero */ +#endif /* WITH_TINYOS_AUTO_IDS */ +int +main(void) +{ + /* Set stack overflow address for detecting overflow in runtime */ + vAHI_SetStackOverflow(TRUE, ((uint32_t *)&heap_location)[0]); + + /* Initialize random with a seed from the SoC random generator. + * This must be done before selecting the high-precision external oscillator. + */ + vAHI_StartRandomNumberGenerator(E_AHI_RND_SINGLE_SHOT, E_AHI_INTS_DISABLED); + random_init(u16AHI_ReadRandomNumber()); + + clock_init(); + rtimer_init(); + +#if JN516X_EXTERNAL_CRYSTAL_OSCILLATOR + /* initialize the 32kHz crystal and wait for ready */ + xosc_init(); + /* need to reinitialize because the wait-for-ready process uses system timers */ + clock_init(); + rtimer_init(); +#endif + + watchdog_init(); + leds_init(); + leds_on(LEDS_ALL); + init_node_mac(); + + energest_init(); + ENERGEST_ON(ENERGEST_TYPE_CPU); + + node_id_restore(); + +#if WITH_TINYOS_AUTO_IDS + node_id = TOS_NODE_ID; +#endif /* WITH_TINYOS_AUTO_IDS */ + /* for setting "hardcoded" IEEE 802.15.4 MAC addresses */ +#ifdef IEEE_802154_MAC_ADDRESS + { + uint8_t ieee[] = IEEE_802154_MAC_ADDRESS; + memcpy(node_mac, ieee, sizeof(uip_lladdr.addr)); + node_mac[7] = node_id & 0xff; + } +#endif + + process_init(); + ctimer_init(); + uart0_init(UART_BAUD_RATE); /* Must come before first PRINTF */ + +#if NETSTACK_CONF_WITH_IPV4 + slip_arch_init(UART_BAUD_RATE); +#endif /* NETSTACK_CONF_WITH_IPV4 */ + + /* check for reset source */ + if(bAHI_WatchdogResetEvent()) { + PRINTF("Init: Watchdog timer has reset device!\r\n"); + } + process_start(&etimer_process, NULL); + set_linkaddr(); + netstack_init(); + +#if NETSTACK_CONF_WITH_IPV6 +#if UIP_CONF_IPV6_RPL + PRINTF(CONTIKI_VERSION_STRING " started with IPV6, RPL\n"); +#else + PRINTF(CONTIKI_VERSION_STRING " started with IPV6\n"); +#endif +#elif NETSTACK_CONF_WITH_IPV4 + PRINTF(CONTIKI_VERSION_STRING " started with IPV4\n"); +#else + PRINTF(CONTIKI_VERSION_STRING " started\n"); +#endif + + if(node_id > 0) { + PRINTF("Node id is set to %u.\n", node_id); + } else { + PRINTF("Node id is not set.\n"); + } +#if NETSTACK_CONF_WITH_IPV6 + memcpy(&uip_lladdr.addr, node_mac, sizeof(uip_lladdr.addr)); + queuebuf_init(); +#endif /* NETSTACK_CONF_WITH_IPV6 */ + + PRINTF("%s %s %s\n", NETSTACK_LLSEC.name, NETSTACK_MAC.name, NETSTACK_RDC.name); + +#ifndef UIP_FALLBACK_INTERFACE + uart0_set_input(serial_line_input_byte); + serial_line_init(); +#endif /* UIP_FALLBACK_INTERFACE */ + +#if TIMESYNCH_CONF_ENABLED + timesynch_init(); + timesynch_set_authority_level((linkaddr_node_addr.u8[0] << 4) + 16); +#endif /* TIMESYNCH_CONF_ENABLED */ + +#if NETSTACK_CONF_WITH_IPV4 + process_start(&tcpip_process, NULL); + process_start(&uip_fw_process, NULL); /* Start IP output */ + process_start(&slip_process, NULL); + + slip_set_input_callback(set_gateway); + + { + uip_ipaddr_t hostaddr, netmask; + + uip_init(); + + uip_ipaddr(&hostaddr, 172, 16, + linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]); + uip_ipaddr(&netmask, 255, 255, 0, 0); + uip_ipaddr_copy(&meshif.ipaddr, &hostaddr); + + uip_sethostaddr(&hostaddr); + uip_setnetmask(&netmask); + uip_over_mesh_set_net(&hostaddr, &netmask); + /* uip_fw_register(&slipif);*/ + uip_over_mesh_set_gateway_netif(&slipif); + uip_fw_default(&meshif); + uip_over_mesh_init(UIP_OVER_MESH_CHANNEL); + PRINTF("uIP started with IP address %d.%d.%d.%d\n", + uip_ipaddr_to_quad(&hostaddr)); + } +#endif /* NETSTACK_CONF_WITH_IPV4 */ + + watchdog_start(); + +#if NETSTACK_CONF_WITH_IPV6 + start_uip6(); +#endif /* NETSTACK_CONF_WITH_IPV6 */ + + /* need this to reliably generate the first rtimer callback and callbacks in other + auto-start processes */ + (void)u32AHI_Init(); + + start_autostart_processes(); + + leds_off(LEDS_ALL); + + main_loop(); + + return -1; +} + +static void +main_loop(void) +{ + int r; + clock_time_t time_to_etimer; + rtimer_clock_t ticks_to_rtimer; + + while(1) { + do { + /* Reset watchdog. */ + watchdog_periodic(); + r = process_run(); + } while(r > 0); + /* + * Idle processing. + */ + watchdog_stop(); + +#if DCOSYNCH_CONF_ENABLED + /* Calibrate the DCO every DCOSYNCH_PERIOD + * if we have more than 500uSec until next rtimer + * PS: Calibration disables interrupts and blocks for 200uSec. + * */ + if(clock_seconds() - last_dco_calibration_time > DCOSYNCH_PERIOD) { + if(rtimer_arch_time_to_rtimer() > RTIMER_SECOND / 2000) { + /* PRINTF("ContikiMain: Calibrating the DCO\n"); */ + eAHI_AttemptCalibration(); + /* Patch to allow CpuDoze after calibration */ + vREG_PhyWrite(REG_PHY_IS, REG_PHY_INT_VCO_CAL_MASK); + last_dco_calibration_time = clock_seconds(); + } + } +#endif /* DCOSYNCH_CONF_ENABLED */ + + /* flush standard output before sleeping */ + uart_driver_flush(E_AHI_UART_0, TRUE, FALSE); + + /* calculate the time to the next etimer and rtimer */ + time_to_etimer = clock_arch_time_to_etimer(); + ticks_to_rtimer = rtimer_arch_time_to_rtimer(); + +#if JN516X_SLEEP_ENABLED + /* we can sleep only up to the next rtimer/etimer */ + rtimer_clock_t max_sleep_time = ticks_to_rtimer; + if(max_sleep_time >= JN516X_MIN_SLEEP_TIME) { + /* also take into account etimers */ + uint64_t ticks_to_etimer = ((uint64_t)time_to_etimer * RTIMER_SECOND) / CLOCK_SECOND; + max_sleep_time = MIN(ticks_to_etimer, ticks_to_rtimer); + } + + if(max_sleep_time >= JN516X_MIN_SLEEP_TIME) { + max_sleep_time -= JN516X_SLEEP_GUARD_TIME; + /* bound the sleep time to 1 second */ + max_sleep_time = MIN(max_sleep_time, JN516X_MAX_SLEEP_TIME); + +#if !RTIMER_USE_32KHZ + /* convert to 32.768 kHz oscillator ticks */ + max_sleep_time = (uint64_t)max_sleep_time * JN516X_XOSC_SECOND / RTIMER_SECOND; +#endif + vAHI_WakeTimerEnable(WAKEUP_TIMER, TRUE); + /* sync with the tick timer */ + WAIT_FOR_EDGE(sleep_start); + sleep_start_ticks = u32AHI_TickTimerRead(); + + vAHI_WakeTimerStartLarge(WAKEUP_TIMER, max_sleep_time); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_EXTRA_LPM); + vAHI_Sleep(E_AHI_SLEEP_OSCON_RAMON); + } else { +#else + { +#endif /* JN516X_SLEEP_ENABLED */ + clock_arch_schedule_interrupt(time_to_etimer, ticks_to_rtimer); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); + vAHI_CpuDoze(); + watchdog_start(); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); + } + } +} +/*---------------------------------------------------------------------------*/ +void +AppColdStart(void) +{ + /* After reset or sleep with memory off */ + main(); +} +/*---------------------------------------------------------------------------*/ +void +AppWarmStart(void) +{ + /* Wakeup after sleep with memory on. + * Need to initialize devices but not the application state. + * Note: the actual time this function is called is + * ~8 ticks (32kHz timer) later than the scheduled sleep end time. + */ + uint32_t sleep_ticks; + uint64_t sleep_end; + rtimer_clock_t sleep_ticks_rtimer; + + clock_arch_calibrate(); + leds_init(); + uart0_init(UART_BAUD_RATE); /* Must come before first PRINTF */ + NETSTACK_RADIO.init(); + watchdog_init(); + watchdog_stop(); + + WAIT_FOR_EDGE(sleep_end); + sleep_ticks = (uint32_t)(sleep_start - sleep_end) + 1; + +#if RTIMER_USE_32KHZ + sleep_ticks_rtimer = sleep_ticks; +#else + { + static uint32_t remainder; + uint64_t t = (uint64_t)sleep_ticks * RTIMER_SECOND + remainder; + sleep_ticks_rtimer = (uint32_t)(t / JN516X_XOSC_SECOND); + remainder = t - sleep_ticks_rtimer * JN516X_XOSC_SECOND; + } +#endif + + /* reinitialize rtimers */ + rtimer_arch_reinit(sleep_start_ticks, sleep_ticks_rtimer); + + ENERGEST_SWITCH(ENERGEST_TYPE_EXTRA_LPM, ENERGEST_TYPE_CPU); + + watchdog_start(); + + /* reinitialize clock */ + clock_arch_init(1); + /* schedule etimer interrupt */ + clock_arch_schedule_interrupt(clock_arch_time_to_etimer(), rtimer_arch_time_to_rtimer()); + +#if DCOSYNCH_CONF_ENABLED + /* The radio is recalibrated on wakeup */ + last_dco_calibration_time = clock_seconds(); +#endif + + main_loop(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/jn516x/dev/clock.c b/platform/jn516x/dev/clock.c new file mode 100644 index 000000000..8b2c316c0 --- /dev/null +++ b/platform/jn516x/dev/clock.c @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Tickless clock implementation for NXP jn516x. + * \author + * Beshr Al Nahas + * Atis Elsts + * + */ + +#include +#include +#include "contiki.h" +#include "sys/energest.h" +#include "sys/clock.h" +#include "sys/etimer.h" +#include "rtimer-arch.h" +#include "dev/watchdog.h" + + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#define CLOCK_TIMER E_AHI_TIMER_1 +#define CLOCK_TIMER_ISR_DEV E_AHI_DEVICE_TIMER1 + +#define OVERFLOW_TIMER E_AHI_TIMER_0 +#define OVERFLOW_TIMER_ISR_DEV E_AHI_DEVICE_TIMER0 + +/* 16Mhz / 2^10 = 15.625 kHz */ +#define CLOCK_PRESCALE 10 +#define PRESCALED_TICKS_PER_SECOND 15625 +/* 8ms tick --> overflow after ~397.7 days */ +#define CLOCK_INTERVAL 125 +/* Max schedulable number of ticks. + * Must not be more than: + * 0xffff / (16'000'000 / (1 << CLOCK_PRESCALE) / CLOCK_SECOND) + */ +#define CLOCK_MAX_SCHEDULABLE_TICKS 520 +/* Min guard time an etimer can be scheduled before an rtimer */ +#define CLOCK_RTIMER_GUARD_TIME US_TO_RTIMERTICKS(16) +/* Clock tick expressed as rtimer ticks */ +#define CLOCK_TICK ((1 << CLOCK_PRESCALE) * CLOCK_INTERVAL) + +#define RTIMER_OVERFLOW_PRESCALED 4194304 /* = 0x100000000 / (2^CLOCK_PRESCALE) */ +#define RTIMER_OVERFLOW_REMAINDER 54 /* in prescaled ticks, per one overflow */ + + +#define CLOCK_LT(a, b) ((int32_t)((a)-(b)) < 0) + +/*---------------------------------------------------------------------------*/ +static uint32_t +clock(void) +{ + /* same as rtimer_arch_now() */ + return u32AHI_TickTimerRead(); +} +/*---------------------------------------------------------------------------*/ +static uint32_t +check_rtimer_overflow(rtimer_clock_t now) +{ + static rtimer_clock_t last_rtimer_ticks; + static uint32_t clock_ticks_remainder; + static uint32_t clock_ticks_base; + + if(last_rtimer_ticks > now) { + clock_ticks_base += RTIMER_OVERFLOW_PRESCALED / CLOCK_INTERVAL; + clock_ticks_remainder += RTIMER_OVERFLOW_REMAINDER; + if(clock_ticks_remainder > CLOCK_INTERVAL) { + clock_ticks_remainder -= CLOCK_INTERVAL; + clock_ticks_base += 1; + } + } + last_rtimer_ticks = now; + return clock_ticks_base; +} +/*---------------------------------------------------------------------------*/ +static void +check_etimers(void) +{ + if(etimer_pending()) { + clock_time_t now = clock_time(); + if(!CLOCK_LT(now, etimer_next_expiration_time())) { + etimer_request_poll(); + } + } + process_nevents(); +} +/*---------------------------------------------------------------------------*/ +void +clockTimerISR(uint32 u32Device, uint32 u32ItemBitmap) +{ + if(u32Device != CLOCK_TIMER_ISR_DEV && u32Device != OVERFLOW_TIMER_ISR_DEV) { + return; + } + + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + if(u32Device == CLOCK_TIMER_ISR_DEV) { + check_etimers(); + } + + if(u32Device == OVERFLOW_TIMER_ISR_DEV) { + check_rtimer_overflow(clock()); + } + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +void +clock_arch_calibrate(void) +{ + bAHI_SetClockRate(E_AHI_XTAL_32MHZ); + + /* Wait for oscillator to stabilise */ + while(bAHI_GetClkSource() == 1) ; + while(bAHI_Clock32MHzStable() == 0) ; + + vAHI_OptimiseWaitStates(); + + /* Turn on SPI master */ + vREG_SysWrite(REG_SYS_PWR_CTRL, u32REG_SysRead(REG_SYS_PWR_CTRL) + | REG_SYSCTRL_PWRCTRL_SPIMEN_MASK); +} +/*---------------------------------------------------------------------------*/ +void +clock_arch_init(int is_reinitialization) +{ + /* initialize etimer interrupt timer */ + vAHI_TimerEnable(CLOCK_TIMER, CLOCK_PRESCALE, 0, 1, 0); + vAHI_TimerClockSelect(CLOCK_TIMER, 0, 0); + + vAHI_TimerConfigureOutputs(CLOCK_TIMER, 0, 1); + vAHI_TimerDIOControl(CLOCK_TIMER, 0); + + vAHI_Timer1RegisterCallback(clockTimerISR); + + /* initialize and start rtimer overflow timer */ + vAHI_TimerEnable(OVERFLOW_TIMER, CLOCK_PRESCALE, 0, 1, 0); + vAHI_TimerClockSelect(OVERFLOW_TIMER, 0, 0); + + vAHI_TimerConfigureOutputs(OVERFLOW_TIMER, 0, 1); + vAHI_TimerDIOControl(OVERFLOW_TIMER, 0); + + vAHI_Timer0RegisterCallback(clockTimerISR); + vAHI_TimerStartRepeat(OVERFLOW_TIMER, 0, PRESCALED_TICKS_PER_SECOND * 4); + + if(is_reinitialization) { + /* check if the etimer has overflowed (useful when this is executed after sleep */ + check_rtimer_overflow(clock()); + } +} +/*---------------------------------------------------------------------------*/ +void +clock_init(void) +{ + /* gMAC_u8MaxBuffers = 2; */ +#ifdef JENNIC_CHIP_FAMILY_JN516x + /* Turn off debugger */ + *(volatile uint32 *)0x020000a0 = 0; +#endif + + clock_arch_calibrate(); + + /* setup clock mode and interrupt handler */ + clock_arch_init(0); +} +/*---------------------------------------------------------------------------*/ +clock_time_t +clock_time(void) +{ + uint32_t now = clock(); + clock_time_t base = check_rtimer_overflow(now); + return base + now / CLOCK_TICK; +} +/*---------------------------------------------------------------------------*/ +/** + * Delay the CPU for a multiple of 0.0625 us. + */ +void +clock_delay_usec(uint16_t dt) +{ + uint32_t end = clock() + dt; + /* Note: this does not call watchdog periodic() */ + while(CLOCK_LT(clock(), end)); +} +/*---------------------------------------------------------------------------*/ +/** + * Delay the CPU for a multiple of 8 us. + */ +void +clock_delay(unsigned int dt) +{ + uint32_t end = clock() + dt * 128; + while(CLOCK_LT(clock(), end)) { + watchdog_periodic(); + } +} +/*---------------------------------------------------------------------------*/ +/** + * Wait for a multiple of 10 ms. + * + */ +void +clock_wait(clock_time_t t) +{ + clock_time_t end = clock_time() + t; + while(CLOCK_LT(clock_time(), end)) { + watchdog_periodic(); + } +} +/*---------------------------------------------------------------------------*/ +unsigned long +clock_seconds(void) +{ + return clock_time() / CLOCK_SECOND; +} +/*---------------------------------------------------------------------------*/ +clock_time_t +clock_arch_time_to_etimer(void) +{ + clock_time_t time_to_etimer; + if(etimer_pending()) { + time_to_etimer = etimer_next_expiration_time() - clock_time(); + if((int32_t)time_to_etimer < 0) { + time_to_etimer = 0; + } + } else { + /* no active etimers */ + time_to_etimer = (clock_time_t)-1; + } + return time_to_etimer; +} +/*---------------------------------------------------------------------------*/ +void +clock_arch_schedule_interrupt(clock_time_t time_to_etimer, rtimer_clock_t ticks_to_rtimer) +{ + if(time_to_etimer > CLOCK_MAX_SCHEDULABLE_TICKS) { + time_to_etimer = CLOCK_MAX_SCHEDULABLE_TICKS; + } + + time_to_etimer *= CLOCK_INTERVAL; + + if(ticks_to_rtimer != (rtimer_clock_t)-1) { + /* if the next rtimer is close enough to the etimer... */ + rtimer_clock_t ticks_to_etimer = time_to_etimer * (1 << CLOCK_PRESCALE); + +#if RTIMER_USE_32KHZ + ticks_to_rtimer = (uint64_t)ticks_to_rtimer * (F_CPU / 2) / RTIMER_SECOND; +#endif + + if(!CLOCK_LT(ticks_to_rtimer, ticks_to_etimer) + && CLOCK_LT(ticks_to_rtimer, ticks_to_etimer + CLOCK_RTIMER_GUARD_TIME)) { + /* ..then schedule the etimer after the rtimer */ + time_to_etimer += 2; + } + } + + /* interrupt will not be generated if 0 is passed as the parameter */ + if(time_to_etimer == 0) { + time_to_etimer = 1; + } + + vAHI_TimerStartSingleShot(CLOCK_TIMER, 0, time_to_etimer); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/jn516x/dev/dongle/README.md b/platform/jn516x/dev/dongle/README.md new file mode 100644 index 000000000..a9b6e9cb2 --- /dev/null +++ b/platform/jn516x/dev/dongle/README.md @@ -0,0 +1,9 @@ +This directory contains the contiki driver for the LED driver for the dongle. + +Mapping of LEDs on JN516x Dongle: + leds.h led on dongle: + LEDS_RED Red LED + LEDS_GREEN Green LED +Note: Only one LED can be switch on at the same time + + diff --git a/platform/jn516x/dev/dongle/leds-arch.c b/platform/jn516x/dev/dongle/leds-arch.c new file mode 100644 index 000000000..5eff3c63e --- /dev/null +++ b/platform/jn516x/dev/dongle/leds-arch.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "leds.h" +#include + +#define LED_G (1 << 16) +#define LED_R (1 << 17) + +static volatile uint8_t leds; + +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + vAHI_DioSetDirection(0, LED_R | LED_G); + vAHI_DioSetOutput(0, LED_R | LED_G); /* Default off */ + leds = 0; +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + return leds; +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char c) +{ + uint32 on_mask = 0; + uint32 off_mask = 0; + + if(c & LEDS_GREEN) { + on_mask |= LED_G; + } else { + off_mask |= LED_G; + } if(c & LEDS_RED) { + on_mask |= LED_R; + } else { + off_mask |= LED_R; + } vAHI_DioSetOutput(on_mask, off_mask); + /* Both LEDs can not be switched on at the same time. + Will result in both leds being OFF */ + if(on_mask == (LED_R | LED_G)) { + leds = 0; + } else { + leds = c; + } +} diff --git a/platform/jn516x/dev/dr1174/README.md b/platform/jn516x/dev/dr1174/README.md new file mode 100644 index 000000000..d3a21cbe0 --- /dev/null +++ b/platform/jn516x/dev/dr1174/README.md @@ -0,0 +1,8 @@ +This directory contains the contiki driver for the button sensor on the DR1174 baseboard. +When used with an extention board, sensors from the dr1175 anf dr1179 directories are used in addition to this. +leds-arch.c implements the led driver for leds D3 and D6 on the board. +Mapping of LEDs on JN516x DR1174: + leds.h: led on DR1174: + LEDS_GP0 LED D3 + LEDS_GP1 LED D6 +Note: LEDS_GPx definitions included in leds.h via platform-conf.h diff --git a/platform/jn516x/dev/dr1174/button-sensor.c b/platform/jn516x/dev/dr1174/button-sensor.c new file mode 100644 index 000000000..9262a6ef8 --- /dev/null +++ b/platform/jn516x/dev/dr1174/button-sensor.c @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "sys/etimer.h" +#include "lib/sensors.h" +#include "button-sensor.h" +#include + +/*---------------------------------------------------------------------------*/ +/* LOCAL DEFINITIONS */ +/*---------------------------------------------------------------------------*/ +/* #define DEBUG */ +#ifdef DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +typedef enum { + APP_E_BUTTON_SW0 = 0, +#if SENSOR_BOARD_DR1199 + APP_E_BUTTON_SW1, + APP_E_BUTTON_SW2, + APP_E_BUTTON_SW3, + APP_E_BUTTON_SW4, +#endif /* SENSOR_BOARD_DR1199 */ + APP_E_BUTTON_NUM /* Number of buttons */ +} app_e_button_t; + +/* Mapping of DIO port connections to buttons. Use as mask to get button value */ +#define APP_PORT_BUTTON_SW0 (8) +#if SENSOR_BOARD_DR1199 +#define APP_PORT_BUTTON_SW1 (11) +#define APP_PORT_BUTTON_SW2 (12) +#define APP_PORT_BUTTON_SW3 (17) +#define APP_PORT_BUTTON_SW4 (1) +#endif /* SENSOR_BOARD_DR1199 */ + +/* Definition of port masks based on button mapping */ +#if SENSOR_BOARD_DR1199 +#define APP_BUTTONS_DIO_MASK ((1 << APP_PORT_BUTTON_SW0) | \ + (1 << APP_PORT_BUTTON_SW1) | \ + (1 << APP_PORT_BUTTON_SW2) | \ + (1 << APP_PORT_BUTTON_SW3) | \ + (1 << APP_PORT_BUTTON_SW4)) +#else /* SENSOR_BOARD_DR1199 */ +#define APP_BUTTONS_DIO_MASK (1 << APP_PORT_BUTTON_SW0) +#endif /* SENSOR_BOARD_DR1199 */ + +#define KEY_SAMPLE_TIME (CLOCK_SECOND / 20) + +typedef enum { + BUTTONS_STATUS_NOT_INIT = 0, + BUTTONS_STATUS_INIT, + BUTTONS_STATUS_NOT_ACTIVE = BUTTONS_STATUS_INIT, + BUTTONS_STATUS_ACTIVE +} buttons_status_t; + +/*---------------------------------------------------------------------------*/ +/* LOCAL DATA DEFINITIONS */ +/*---------------------------------------------------------------------------*/ +const struct sensors_sensor button_sensor; +volatile static buttons_status_t buttons_status = BUTTONS_STATUS_NOT_INIT; +static int key_value = 0; +static uint8 key_map[] = { APP_PORT_BUTTON_SW0, /* APP_E_BUTTON_SW0 */ +#if SENSOR_BOARD_DR1199 + APP_PORT_BUTTON_SW1, /* APP_E_BUTTON_SW1 */ + APP_PORT_BUTTON_SW2, /* APP_E_BUTTON_SW2 */ + APP_PORT_BUTTON_SW3, /* APP_E_BUTTON_SW3 */ + APP_PORT_BUTTON_SW4 /* APP_E_BUTTON_SW4 */ +#endif /* SENSOR_BOARD_DR1199 */ +}; + +/*---------------------------------------------------------------------------*/ +/* LOCAL FUNCTION PROTOTYPES */ +/*---------------------------------------------------------------------------*/ +PROCESS(key_sampling, "Key sample"); +static int get_key_value(void); + +/*---------------------------------------------------------------------------*/ +/* PUBLIC FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type == SENSORS_HW_INIT) { + /* Called from sensor thread when started. + Configure DIO lines with buttons connected as input */ + vAHI_DioSetDirection(APP_BUTTONS_DIO_MASK, 0); + /* Turn on pull-ups for DIO lines with buttons connected */ + vAHI_DioSetPullup(APP_BUTTONS_DIO_MASK, 0); + PRINTF("HW_INIT BUTTONS (0x%x)\n", APP_BUTTONS_DIO_MASK); + /* Configure debounce timer. Do not run it yet. */ + buttons_status = BUTTONS_STATUS_INIT; + process_start(&key_sampling, NULL); + return 1; + } else if(type == SENSORS_ACTIVE) { + if(buttons_status != BUTTONS_STATUS_NOT_INIT) { + if(value) { + /* Button sensor activated */ + PRINTF("BUTTONS ACTIVATED\n"); + buttons_status = BUTTONS_STATUS_ACTIVE; + } else { + /* Button sensor de-activated */ + PRINTF("BUTTONS DE-ACTIVATED\n"); + buttons_status = BUTTONS_STATUS_NOT_ACTIVE; + } + process_post(&key_sampling, PROCESS_EVENT_MSG, (void *)&buttons_status); + return 1; + } else { + /* Buttons must be intialised before being (de)-activated */ + PRINTF("ERROR: NO HW_INIT BUTTONS\n"); + return 0; + } + } else { + /* Non valid type */ + return 0; + } +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + if(type == SENSORS_ACTIVE) { + return buttons_status == BUTTONS_STATUS_ACTIVE; + } else if(type == SENSORS_READY) { + return buttons_status != BUTTONS_STATUS_NOT_INIT; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + /* type: Not defined for the buttons interface + */ + return key_value; +} +/*---------------------------------------------------------------------------*/ +/* LOCAL FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +static int +get_key_value(void) +{ + /* Function returns the actual key value. Pressed key will return '1' */ + int io_value = ~u32AHI_DioReadInput() & APP_BUTTONS_DIO_MASK; + int k = 0; + int key = 0; + + while(k < APP_E_BUTTON_NUM) { + if(io_value & (1 << key_map[k])) { + key |= (1 << k); + } + k++; + } + return key; +} +/* Process takes care of detecting key changes */ +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(key_sampling, ev, data) +{ + PROCESS_BEGIN(); + static struct etimer et; + static int previous_key_value = 0; + static char debounce_check = 0; + int current_key_value; + + etimer_set(&et, CLOCK_SECOND / 50); + while(1) { + PROCESS_WAIT_EVENT_UNTIL((ev == PROCESS_EVENT_TIMER) || (ev == PROCESS_EVENT_MSG)); + if(ev == PROCESS_EVENT_TIMER) { + /* Handle sensor reading. */ + PRINTF("Key sample\n"); + current_key_value = get_key_value(); + if(debounce_check != 0) { + /* Check if key remained constant */ + if(previous_key_value == current_key_value) { + sensors_changed(&button_sensor); + key_value = current_key_value; + debounce_check = 0; + } else { + /* Bouncing */ + previous_key_value = current_key_value; + } + } else + /* Check for new key change */ + if(current_key_value != previous_key_value) { + previous_key_value = current_key_value; + debounce_check = 1; + } + etimer_reset(&et); + } else { + /* ev == PROCESS_EVENT_MSG */ + if(*(buttons_status_t *)data == BUTTONS_STATUS_NOT_ACTIVE) { + /* Stop sampling */ + etimer_stop(&et); + } else if((*(buttons_status_t *)data == BUTTONS_STATUS_ACTIVE)) { + /* restart sampling */ + etimer_restart(&et); + } + } + } + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +/* Sensor defintion for sensor module */ +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ diff --git a/platform/iris/init-net.h b/platform/jn516x/dev/dr1174/button-sensor.h similarity index 84% rename from platform/iris/init-net.h rename to platform/jn516x/dev/dr1174/button-sensor.h index 066a6d4fd..eaa87a751 100644 --- a/platform/iris/init-net.h +++ b/platform/jn516x/dev/dr1174/button-sensor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, University of Colombo School of Computing + * Copyright (c) 2015, SICS Swedish ICT. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,19 +28,14 @@ * * This file is part of the Contiki operating system. * - * @(#)$$ */ +#ifndef __BUTTON_SENSOR_H__ +#define __BUTTON_SENSOR_H__ -/** - * \file - * Network initialization for the MICAz port. - * \author - * Kasun Hewage - */ +#include "lib/sensors.h" -#ifndef INIT_NET_H_ -#define INIT_NET_H_ +extern const struct sensors_sensor button_sensor; -void init_net(void); +#define BUTTON_SENSOR "Button" -#endif /* INIT_NET_H_ */ +#endif /* __BUTTON_SENSOR_H__ */ diff --git a/platform/jn516x/dev/dr1174/leds-arch.c b/platform/jn516x/dev/dr1174/leds-arch.c new file mode 100644 index 000000000..4e49e9c53 --- /dev/null +++ b/platform/jn516x/dev/dr1174/leds-arch.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "dev/leds.h" +#include +#ifdef SENSOR_BOARD_DR1199 +#include "dr1199/leds-arch-1199.h" +#endif +#ifdef SENSOR_BOARD_DR1175 +#include "leds-extension.h" +#include "dr1175/leds-arch-1175.h" +#endif + +#define LED_D3 (1 << 3) +#define LED_D6 (1 << 2) + +static volatile unsigned char leds; + +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + vAHI_DioSetDirection(0, LED_D3 | LED_D6); + vAHI_DioSetOutput(LED_D3 | LED_D6, 0); /* Default off */ +#ifdef SENSOR_BOARD_DR1199 + leds_arch_init_1199(); +#endif +#ifdef SENSOR_BOARD_DR1175 + leds_arch_init_1175(); +#endif + leds = 0; +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + return leds; +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char c) +{ + uint32 on_mask = 0; + uint32 off_mask = 0; + + /* LOW level on pins switches ON LED for DR1174 */ + if(c & LEDS_GP0) { + on_mask |= LED_D3; + } else { + off_mask |= LED_D3; + } if(c & LEDS_GP1) { + on_mask |= LED_D6; + } else { + off_mask |= LED_D6; + } vAHI_DioSetOutput(off_mask, on_mask); +#ifdef SENSOR_BOARD_DR1199 + /* DR1174 with DR1199 */ + leds_arch_set_1199(c); + if(c == LEDS_ALL) { + leds = LEDS_GP0 | LEDS_GP1 | LEDS_RED | LEDS_BLUE | LEDS_GREEN; + } else { + leds = (c & (LEDS_GP0 | LEDS_GP1 | LEDS_RED | LEDS_BLUE | LEDS_GREEN)); + } +#elif SENSOR_BOARD_DR1175 + /* DR1174 with DR1175 */ + leds_arch_set_1175(c); + if(c == LEDS_ALL) { + leds = LEDS_GP0 | LEDS_GP1 | LEDS_RED | LEDS_BLUE | LEDS_GREEN | LEDS_WHITE; + } else { + leds = (c & (LEDS_GP0 | LEDS_GP1 | LEDS_RED | LEDS_BLUE | LEDS_GREEN | LEDS_WHITE)); +/* printf("++++++++++++++++++++ leds_arch_set: leds: 0x%x\n", leds); */ + } +#else + /* DR1174-only */ + if(c == LEDS_ALL) { + leds = LEDS_GP0 | LEDS_GP1; + } else { + leds = c; + } +#endif +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set_level(unsigned char level, unsigned char c) +{ +#ifdef SENSOR_BOARD_DR1175 + leds_arch_set_level_1175(level, c, leds); +/* printf("++++++++++++++++++++ leds_arch_set_level: leds: 0x%x\n", leds); */ +#endif +} diff --git a/platform/jn516x/dev/dr1175/README.md b/platform/jn516x/dev/dr1175/README.md new file mode 100644 index 000000000..232e34768 --- /dev/null +++ b/platform/jn516x/dev/dr1175/README.md @@ -0,0 +1,18 @@ +This directory contains the contiki driver for the sensors (light, humidity and temperature sensor) available on the +NXP DR1175 board. This board is part of the NXP JN516X Evaluation Kit (see http://www.nxp.com/documents/leaflet/75017368.pdf). + +The dr1175 sensor code interfaces to the contiki `core/lib/sensors.c` framework. +The code is specificaly for the JN516X platform, because it makes use of the platform\DK4 libraries +of this JN516X SDK. +`examples/jn516x/rpl/coap-dr1175-node.c` shows an example on using this contiki driver. + +Mapping of LEDs on JN516x DR1175/DR1174: + leds.h: led on DR1175/DR1174: +DR1174+DR1175: + LEDS_RED Red led in RGB-led with level control on DR1175 + LEDS_GREEN Green led in RGB-led with level control on DR1175 + LEDS_BLUE Blue led in RGB-led with level control on DR1175 + LEDS_WHITE White power led with level control on DR1175 + LEDS_GP0 LEDS D3 on DR1174 + LEDS_GP1 LEDS D6 on DR1174 +Note: LEDS_GPx and LEDS_WHITE definitions included in leds.h via platform-conf.h diff --git a/platform/jn516x/dev/dr1175/ht-sensor.c b/platform/jn516x/dev/dr1175/ht-sensor.c new file mode 100644 index 000000000..76f889d84 --- /dev/null +++ b/platform/jn516x/dev/dr1175/ht-sensor.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "sys/etimer.h" +#include "lib/sensors.h" +#include "ht-sensor.h" +#include +#include + +/*---------------------------------------------------------------------------*/ +/* LOCAL DEFINITIONS */ +/*---------------------------------------------------------------------------*/ +/* #define DEBUG */ +#ifdef DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +typedef enum { + HT_SENSOR_STATUS_NOT_INIT = 0, + HT_SENSOR_STATUS_INIT, + HT_SENSOR_STATUS_NOT_ACTIVE = HT_SENSOR_STATUS_INIT, + HT_SENSOR_STATUS_ACTIVE +} ht_sensor_status_t; + +/* Absolute delta in light or humidity level needed to generate event */ +#define DELTA_TEMP_SENSOR_VALUE 1 +#define DELTA_HUM_SENSOR_VALUE 1 + +/*---------------------------------------------------------------------------*/ +/* LOCAL DATA DEFINITIONS */ +/*---------------------------------------------------------------------------*/ +const struct sensors_sensor ht_sensor; +volatile static ht_sensor_status_t ht_sensor_status = HT_SENSOR_STATUS_NOT_INIT; +static int prev_temp_event_val = 0; +static int prev_hum_event_val = 0; +static int temp_sensor_value = 0; +static int hum_sensor_value = 0; + +/*---------------------------------------------------------------------------*/ +/* LOCAL FUNCTION PROTOTYPES */ +/*---------------------------------------------------------------------------*/ +PROCESS(HTSensorSampling, "Humidity/Temperature sensor"); + +/*---------------------------------------------------------------------------*/ +/* PUBLIC FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type == SENSORS_HW_INIT) { + PRINTF("SENSORS_HW_INIT\n"); + ht_sensor_status = HT_SENSOR_STATUS_INIT; + process_start(&HTSensorSampling, NULL); + return 1; + } else if(type == SENSORS_ACTIVE) { + if(ht_sensor_status != HT_SENSOR_STATUS_NOT_INIT) { + if(value) { + /* ACTIVATE SENSOR */ + vHTSreset(); + prev_temp_event_val = 0; + prev_hum_event_val = 0; + /* Activate ht sensor. Start sampling */ + PRINTF("HT SENSOR ACTIVATED\n"); + ht_sensor_status = HT_SENSOR_STATUS_ACTIVE; + process_post(&HTSensorSampling, PROCESS_EVENT_MSG, (void *)&ht_sensor_status); + } else { + /* DE-ACTIVATE SENSOR */ + PRINTF("HT SENSOR DE-ACTIVATED\n"); + ht_sensor_status = HT_SENSOR_STATUS_NOT_ACTIVE; + process_post(&HTSensorSampling, PROCESS_EVENT_MSG, (void *)&ht_sensor_status); + } + return 1; + } else { + /* HT sensor must be intialised before being (de)-activated */ + PRINTF("ERROR: NO HW_INIT HT SENSOR\n"); + return 0; + } + } else { + /* Non valid type */ + return 0; + } +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + if(type == SENSORS_ACTIVE) { + return ht_sensor_status == HT_SENSOR_STATUS_ACTIVE; + } else if(type == SENSORS_READY) { + return ht_sensor_status != HT_SENSOR_STATUS_NOT_INIT; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + /* type: HT_SENSOR_TEMP is to return temperature + !=HT_SENSOR_TEMP is to return humidity */ + if(type == HT_SENSOR_TEMP) { + return temp_sensor_value; + } else { + return hum_sensor_value; + } +} +/*---------------------------------------------------------------------------*/ +/* LOCAL FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +/* Process to get ht sensor value. + ht sensor is sampled. Sampling stopped when sensor is de-activated. + Event is generated if temp and/or hum value changed at least the value DELTA_TEMP_SENSOR_VALUE + or DELTA_HUM_SENSOR_VALUE since last event. */ +PROCESS_THREAD(HTSensorSampling, ev, data) +{ + PROCESS_BEGIN(); + static struct etimer et; + + etimer_set(&et, CLOCK_SECOND); + while(1) { + PROCESS_WAIT_EVENT_UNTIL((ev == PROCESS_EVENT_TIMER) || (ev == PROCESS_EVENT_MSG)); + if(ev == PROCESS_EVENT_TIMER) { + /* Handle sensor reading. */ + vHTSstartReadTemp(); + temp_sensor_value = u16HTSreadTempResult(); + PRINTF("Temperature sample: %d\n", temp_sensor_value); + vHTSstartReadHumidity(); + hum_sensor_value = u16HTSreadHumidityResult(); + PRINTF("Humidity sample: %d\n", hum_sensor_value); + if((abs(temp_sensor_value - prev_temp_event_val) > DELTA_TEMP_SENSOR_VALUE) || + (abs(hum_sensor_value - prev_hum_event_val) > DELTA_HUM_SENSOR_VALUE)) { + prev_temp_event_val = temp_sensor_value; + prev_hum_event_val = hum_sensor_value; + sensors_changed(&ht_sensor); + } + etimer_reset(&et); + } else { + /* ev == PROCESS_EVENT_MSG */ + if(*(int *)data == HT_SENSOR_STATUS_NOT_ACTIVE) { + /* Stop sampling */ + etimer_stop(&et); + } else if((*(int *)data == HT_SENSOR_STATUS_ACTIVE)) { + /* restart sampling */ + etimer_restart(&et); + } + } + } + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +/* Sensor defintion for sensor module */ +SENSORS_SENSOR(ht_sensor, HT_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ diff --git a/platform/jn516x/dev/dr1175/ht-sensor.h b/platform/jn516x/dev/dr1175/ht-sensor.h new file mode 100644 index 000000000..43fb8b63a --- /dev/null +++ b/platform/jn516x/dev/dr1175/ht-sensor.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#ifndef __HT_SENSOR_H__ +#define __HT_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor ht_sensor; + +#define HT_SENSOR "TH" + +#define HT_SENSOR_TEMP 0 +#define HT_SENSOR_HUM 1 + +#endif /* __HT_SENSOR_H__ */ diff --git a/platform/jn516x/dev/dr1175/leds-arch-1175.c b/platform/jn516x/dev/dr1175/leds-arch-1175.c new file mode 100644 index 000000000..c1adeb2fb --- /dev/null +++ b/platform/jn516x/dev/dr1175/leds-arch-1175.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "dev/leds.h" +#include + +static uint8_t white_level; +static uint8_t red_level; +static uint8_t green_level; +static uint8_t blue_level; + +/*---------------------------------------------------------------------------*/ +void +leds_arch_init_1175(void) +{ + /* White LED initialisation */ + white_level = 0; + bWhite_LED_Enable(); + bWhite_LED_SetLevel(0); + bWhite_LED_On(); + /* Coloured LED initialisation */ + red_level = 0; + green_level = 0; + blue_level = 0; + bRGB_LED_Enable(); + bRGB_LED_SetGroupLevel(255); + bRGB_LED_SetLevel(0, 0, 0); + bRGB_LED_On(); +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set_1175(unsigned char c) +{ + bWhite_LED_SetLevel(c & LEDS_WHITE ? white_level : 0); + bRGB_LED_SetLevel(c & LEDS_RED ? red_level : 0, + c & LEDS_GREEN ? green_level : 0, + c & LEDS_BLUE ? blue_level : 0); +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set_level_1175(unsigned char level, unsigned char c, unsigned char leds) +{ + if(c & LEDS_WHITE) { + white_level = level; + } + if(c & LEDS_RED) { + red_level = level; + } + if(c & LEDS_GREEN) { + green_level = level; + } + if(c & LEDS_BLUE) { + blue_level = level; + /* Activate level if LED is on */ + } + bRGB_LED_SetLevel(leds & LEDS_RED ? red_level : 0, + leds & LEDS_GREEN ? green_level : 0, + leds & LEDS_BLUE ? blue_level : 0); + bWhite_LED_SetLevel(leds & LEDS_WHITE ? white_level : 0); +} \ No newline at end of file diff --git a/platform/jn516x/dev/dr1175/leds-arch-1175.h b/platform/jn516x/dev/dr1175/leds-arch-1175.h new file mode 100644 index 000000000..7611bc51d --- /dev/null +++ b/platform/jn516x/dev/dr1175/leds-arch-1175.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +void leds_arch_init_1175(void); +void leds_arch_set_1175(unsigned char c); +void leds_arch_set_level_1175(unsigned char level, unsigned char c, unsigned char leds); diff --git a/platform/jn516x/dev/dr1175/light-sensor.c b/platform/jn516x/dev/dr1175/light-sensor.c new file mode 100644 index 000000000..6a25b2af4 --- /dev/null +++ b/platform/jn516x/dev/dr1175/light-sensor.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "sys/etimer.h" +#include "lib/sensors.h" +#include "light-sensor.h" +#include +#include +#include + +/*---------------------------------------------------------------------------*/ +/* LOCAL DEFINITIONS */ +/*---------------------------------------------------------------------------*/ +/* #define DEBUG */ +#ifdef DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +typedef enum { + LIGHT_SENSOR_STATUS_NOT_INIT = 0, + LIGHT_SENSOR_STATUS_INIT, + LIGHT_SENSOR_STATUS_NOT_ACTIVE = LIGHT_SENSOR_STATUS_INIT, + LIGHT_SENSOR_STATUS_ACTIVE +} light_sensor_status_t; + +/* Absolute delta in light level needed to generate event */ +#define DELTA_LIGHT_SENSOR_VALUE 1 + +/*---------------------------------------------------------------------------*/ +/* LOCAL DATA DEFINITIONS */ +/*---------------------------------------------------------------------------*/ +const struct sensors_sensor light_sensor; +volatile static light_sensor_status_t light_sensor_status = LIGHT_SENSOR_STATUS_NOT_INIT; +static int prev_light_event_val = 0; +static int light_sensor_value = 0; + +/*---------------------------------------------------------------------------*/ +/* LOCAL FUNCTION PROTOTYPES */ +/*---------------------------------------------------------------------------*/ +static int adjust(int input1, int input2); +PROCESS(LightSensorSampling, "Light sensor"); + +/*---------------------------------------------------------------------------*/ +/* PUBLIC FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type == SENSORS_HW_INIT) { + PRINTF("SENSORS_HW_INIT\n"); + light_sensor_status = LIGHT_SENSOR_STATUS_INIT; + process_start(&LightSensorSampling, NULL); + return 1; + } else if(type == SENSORS_ACTIVE) { + if(light_sensor_status != LIGHT_SENSOR_STATUS_NOT_INIT) { + if(value) { + /* ACTIVATE SENSOR */ + vALSreset(); + prev_light_event_val = 0; + /* Activate light sensor. Use channel 0. (Channel 1 = IR). Start sampling */ + PRINTF("LIGHT SENSOR ACTIVATED\n"); + light_sensor_status = LIGHT_SENSOR_STATUS_ACTIVE; + process_post(&LightSensorSampling, PROCESS_EVENT_MSG, (void *)&light_sensor_status); + } else { + /* DE-ACTIVATE SENSOR */ + vALSpowerDown(); + PRINTF("LIGHT SENSOR DE-ACTIVATED\n"); + light_sensor_status = LIGHT_SENSOR_STATUS_NOT_ACTIVE; + process_post(&LightSensorSampling, PROCESS_EVENT_MSG, (void *)&light_sensor_status); + } + return 1; + } else { + /* Light sensor must be intialised before being (de)-activated */ + PRINTF("ERROR: NO HW_INIT LIGHT SENSOR\n"); + return 0; + } + } else { + /* Non valid type */ + return 0; + } +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + if(type == SENSORS_ACTIVE) { + return light_sensor_status == LIGHT_SENSOR_STATUS_ACTIVE; + } else if(type == SENSORS_READY) { + return light_sensor_status != LIGHT_SENSOR_STATUS_NOT_INIT; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + /* type: Not defined for the light sensor interface */ + return light_sensor_value; +} +/*---------------------------------------------------------------------------*/ +/* LOCAL FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +/* Process to get light sensor value. + Light sensor is sampled. Sampling stopped when sensor is de-activated. + Event is generated if light value changed at least the value DELTA_LIGHT_SENSOR_VALUE + since last event. */ +PROCESS_THREAD(LightSensorSampling, ev, data) +{ + PROCESS_BEGIN(); + static struct etimer et; + int channel0_value, channel1_value; + + etimer_set(&et, CLOCK_SECOND / 10); + while(1) { + PROCESS_WAIT_EVENT_UNTIL((ev == PROCESS_EVENT_TIMER) || (ev == PROCESS_EVENT_MSG)); + if(ev == PROCESS_EVENT_TIMER) { + /* Handle sensor reading. */ + PRINTF("Light sensor sample\n"); + vALSstartReadChannel(0); + channel0_value = u16ALSreadChannelResult(); + PRINTF("Channel 0 = %d\n", channel0_value); + vALSstartReadChannel(1); + channel1_value = u16ALSreadChannelResult(); + PRINTF("Channel 1 = %d\n", channel1_value); + light_sensor_value = adjust(channel0_value, channel1_value); + PRINTF("Light output = %d\n", light_sensor_value); + if(abs(light_sensor_value - prev_light_event_val) > DELTA_LIGHT_SENSOR_VALUE) { + prev_light_event_val = light_sensor_value; + sensors_changed(&light_sensor); + } + etimer_reset(&et); + } else { + /* ev == PROCESS_EVENT_MSG */ + if(*(int *)data == LIGHT_SENSOR_STATUS_NOT_ACTIVE) { + /* Stop sampling */ + etimer_stop(&et); + } else if((*(int *)data == LIGHT_SENSOR_STATUS_ACTIVE)) { + /* restart sampling */ + etimer_restart(&et); + } + } + } + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +/* Sensor defintion for sensor module */ +SENSORS_SENSOR(light_sensor, LIGHT_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* adjust() converts the 2 measured light level into 1 ambient light level. */ +/* See manual JN-RM-2003.pdf */ +/* Approximation is used: output[Lux] = 0.39*(ch0-ch1) */ +/*---------------------------------------------------------------------------*/ +static int +adjust(int ch0, int ch1) +{ + if(ch0 > ch1) { + return (39 * (ch0 - ch1)) / 100; + } else { + return 0; + } +} diff --git a/platform/jn516x/dev/dr1175/light-sensor.h b/platform/jn516x/dev/dr1175/light-sensor.h new file mode 100644 index 000000000..49f9d9bbd --- /dev/null +++ b/platform/jn516x/dev/dr1175/light-sensor.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#ifndef __LIGHT_SENSOR_H__ +#define __LIGHT_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor light_sensor; + +#define LIGHT_SENSOR "Light" + +#endif /* __LIGHT_SENSOR_H__ */ diff --git a/platform/jn516x/dev/dr1199/README.md b/platform/jn516x/dev/dr1199/README.md new file mode 100644 index 000000000..f70d7558c --- /dev/null +++ b/platform/jn516x/dev/dr1199/README.md @@ -0,0 +1,19 @@ +This directory contains the contiki driver for the sensor (potentiometer) available on the +NXP DR1199 board. This board is part of the NXP JN516x Evaluation Kit (see http://www.nxp.com/documents/leaflet/75017368.pdf). +The driver for the switches on the DR1199 are supported by `dev/dr1174` when compiled with the flag `SENSOR_BOARD_DR1199` set. + +The dr1199 sensor code interfaces to contiki `core/lib/sensors.c` framework. +The code is specificaly for the JN516X platform, because it makes use of the platform\DK4 libraries +of this JN516X SDK. +`examples/jn516x/rpl/coap-dr1199-node.c` shows an example on using this contiki driver. +leds-arch.c implements the led driver for leds D3 and D6 on the DR1174 base-board and the DR1199 board. +Mapping of LEDs on JN516x DR1199/DR1174: + leds.h: led on DR1174: +DR1174+DR1199: + leds.h physical leds + LEDS_GREEN LED D1 on DR1199 + LEDS_BLUE LED D2 on DR1199 + LEDS_RED LED D3 on DR1199 + LEDS_GP0 LED D3 on DR1174 + LEDS_GP1 LED D6 on DR1174 +Note: LEDS_GPx definitions included in leds.h via platform-conf.h diff --git a/platform/jn516x/dev/dr1199/leds-arch-1199.c b/platform/jn516x/dev/dr1199/leds-arch-1199.c new file mode 100644 index 000000000..c6dc1c3ba --- /dev/null +++ b/platform/jn516x/dev/dr1199/leds-arch-1199.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "dev/leds.h" +#include + +/*---------------------------------------------------------------------------*/ +void +leds_arch_init_1199(void) +{ + vGenericLEDInit(); +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set_1199(unsigned char c) +{ + vGenericLEDSetOutput(GEN_BOARD_LED_D1_VAL, c & LEDS_GREEN); + vGenericLEDSetOutput(GEN_BOARD_LED_D2_VAL, c & LEDS_BLUE); + vGenericLEDSetOutput(GEN_BOARD_LED_D3_VAL, c & LEDS_RED); +} diff --git a/platform/jn516x/dev/dr1199/leds-arch-1199.h b/platform/jn516x/dev/dr1199/leds-arch-1199.h new file mode 100644 index 000000000..477d2402b --- /dev/null +++ b/platform/jn516x/dev/dr1199/leds-arch-1199.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +void leds_arch_init_1199(void); +void leds_arch_set_1199(unsigned char c); diff --git a/platform/jn516x/dev/dr1199/pot-sensor.c b/platform/jn516x/dev/dr1199/pot-sensor.c new file mode 100644 index 000000000..e6254337a --- /dev/null +++ b/platform/jn516x/dev/dr1199/pot-sensor.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "contiki.h" +#include "sys/etimer.h" +#include "lib/sensors.h" +#include "pot-sensor.h" +#include +#include + +/*---------------------------------------------------------------------------*/ +/* LOCAL DEFINITIONS */ +/*---------------------------------------------------------------------------*/ +/* #define DEBUG */ +#ifdef DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +typedef enum { + POT_STATUS_NOT_INIT = 0, + POT_STATUS_INIT, + POT_STATUS_NOT_ACTIVE = POT_STATUS_INIT, + POT_STATUS_ACTIVE +} pot_status_t; + +/* Absolute delta in pot level needed to generate event */ +#define DELTA_POT_VALUE 1 + +/*---------------------------------------------------------------------------*/ +/* LOCAL DATA DEFINITIONS */ +/*---------------------------------------------------------------------------*/ +const struct sensors_sensor pot_sensor; +volatile static pot_status_t pot_status = POT_STATUS_NOT_INIT; +static int prev_pot_event_val = 0; +static int pot_value = 0; + +/*---------------------------------------------------------------------------*/ +/* LOCAL FUNCTION PROTOTYPES */ +/*---------------------------------------------------------------------------*/ +PROCESS(POTSampling, "POT"); + +/*---------------------------------------------------------------------------*/ +/* PUBLIC FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type == SENSORS_HW_INIT) { + pot_status = POT_STATUS_INIT; + bPotEnable(); + process_start(&POTSampling, NULL); + return 1; + } else if(type == SENSORS_ACTIVE) { + if(pot_status != POT_STATUS_NOT_INIT) { + if(value) { + /* ACTIVATE SENSOR */ + bPotEnable(); + prev_pot_event_val = 0; + /* Activate POT. */ + PRINTF("POT ACTIVATED\n"); + pot_status = POT_STATUS_ACTIVE; + process_post(&POTSampling, PROCESS_EVENT_MSG, (void *)&pot_status); + } else { + /* DE-ACTIVATE SENSOR */ + bPotDisable(); + PRINTF("POT DE-ACTIVATED\n"); + pot_status = POT_STATUS_NOT_ACTIVE; + process_post(&POTSampling, PROCESS_EVENT_MSG, (void *)&pot_status); + } + return 1; + } else { + /* + POT must be intialised before being (de)-activated */ + PRINTF("ERROR: NO HW_INIT POT\n"); + return 0; + } + } else { + /* Non valid type */ + return 0; + } +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + if(type == SENSORS_ACTIVE) { + return pot_status == POT_STATUS_ACTIVE; + } else if(type == SENSORS_READY) { + return pot_status != POT_STATUS_NOT_INIT; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + /* type: Not defined for the pot interface */ + return pot_value; +} +/*---------------------------------------------------------------------------*/ +/* LOCAL FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +/* Process to get POT_SENSOR value. + POT is sampled. Sampling stopped when POT is de-activated. + Event is generated if pot value changed at least the value DELTA_POT_VALUE + since last event. */ +PROCESS_THREAD(POTSampling, ev, data) +{ + PROCESS_BEGIN(); + static struct etimer et; + + etimer_set(&et, CLOCK_SECOND / 10); + while(1) { + PROCESS_WAIT_EVENT_UNTIL((ev == PROCESS_EVENT_TIMER) || (ev == PROCESS_EVENT_MSG)); + if(ev == PROCESS_EVENT_TIMER) { + /* Handle sensor reading. */ + PRINTF("POT sample\n"); + pot_value = u16ReadPotValue(); + PRINTF("POT = %d\n", pot_value); + if(abs(pot_value - prev_pot_event_val) > DELTA_POT_VALUE) { + prev_pot_event_val = pot_value; + sensors_changed(&pot_sensor); + } + etimer_reset(&et); + } else { + /* ev == PROCESS_EVENT_MSG */ + if(*(int *)data == POT_STATUS_NOT_ACTIVE) { + /* Stop sampling */ + etimer_stop(&et); + } else if((*(int *)data == POT_STATUS_ACTIVE)) { + /* restart sampling */ + etimer_restart(&et); + } + } + } + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +/* Sensor defintion for sensor module */ +SENSORS_SENSOR(pot_sensor, POT_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ + diff --git a/platform/jn516x/dev/dr1199/pot-sensor.h b/platform/jn516x/dev/dr1199/pot-sensor.h new file mode 100644 index 000000000..d2297f822 --- /dev/null +++ b/platform/jn516x/dev/dr1199/pot-sensor.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#ifndef __POT_SENSOR_H__ +#define __POT_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor pot_sensor; + +#define POT_SENSOR "pot" + +#endif /* __POT_SENSOR_H__ */ + diff --git a/platform/jn516x/dev/exceptions.c b/platform/jn516x/dev/exceptions.c new file mode 100644 index 000000000..10a3bf11b --- /dev/null +++ b/platform/jn516x/dev/exceptions.c @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Thomas Haydon + * Integrated into Contiki by Beshr Al Nahas + * + */ + +#include +#include +#include +#include "exceptions.h" + +#ifndef EXCEPTION_STALLS_SYSTEM +#define EXCEPTION_STALLS_SYSTEM 0 +#endif /* EXCEPTION_STALLS_SYSTEM */ + +#ifndef PRINT_STACK_ON_REBOOT +#define PRINT_STACK_ON_REBOOT 1 +#endif /* PRINT_STACK_ON_REBOOT */ + +/** Define to dump the stack on exception */ +#ifndef EXC_DUMP_STACK +#define EXC_DUMP_STACK +#endif /* EXC_DUMP_STACK */ + +/** Define to dump registers on exception */ +#ifndef EXC_DUMP_REGS +/* #define EXC_DUMP_REGS */ +#endif /* EXC_DUMP_REGS */ + +/* Select whether exception vectors should be in RAM or Flash based on chip family */ +#if (defined JENNIC_CHIP_FAMILY_JN514x) +#define EXCEPTION_VECTORS_LOCATION_RAM +#elif (defined JENNIC_CHIP_FAMILY_JN516x) +#define EXCEPTION_VECTORS_LOCATION_FLASH +#else +#error Unsupported chip family selected +#endif /* JENNIC_CHIP_FAMILY */ + +#if (defined EXCEPTION_VECTORS_LOCATION_RAM) +/* RAM exception vectors are set up at run time */ +/* Addresses of exception vectors in RAM */ +#define BUS_ERROR *((volatile uint32 *)(0x4000000)) +#define TICK_TIMER *((volatile uint32 *)(0x4000004)) +#define UNALIGNED_ACCESS *((volatile uint32 *)(0x4000008)) +#define ILLEGAL_INSTRUCTION *((volatile uint32 *)(0x400000c)) +#define EXTERNAL_INTERRUPT *((volatile uint32 *)(0x4000010)) +#define SYSCALL *((volatile uint32 *)(0x4000014)) +#define TRAP *((volatile uint32 *)(0x4000018)) +#define GENERIC *((volatile uint32 *)(0x400001c)) +#define STACK_OVERFLOW *((volatile uint32 *)(0x4000020)) +#elif (defined EXCEPTION_VECTORS_LOCATION_FLASH) +/* Flash exception vectors are set up at compile time */ +#else +#error Unknown exception vector location +#endif /* EXCEPTION_VECTORS_LOCATION */ + +/* Locations in stack trace of important information */ +#define STACK_REG 1 +#define PROGRAM_COUNTER 18 +#define EFFECTIVE_ADDR 19 + +/* Number of registers */ +#define REG_COUNT 16 + +/* Chip dependant RAM size */ +#if defined(JENNIC_CHIP_JN5148) || defined(JENNIC_CHIP_JN5148J01) +#define EXCEPTION_RAM_TOP 0x04020000 +#else +#define EXCEPTION_RAM_TOP 0x04008000 +#endif + +static void exception_handler(uint32 *pu32Stack, eExceptionType eType); +static void *heap_alloc_overflow_protect(void *pvPointer, uint32 u32Size, bool_t bClear); +/*---------------------------------------------------------------------------*/ +#if PRINT_STACK_ON_REBOOT +static void hexprint(uint8 v); +static void hexprint32(uint32 v); +static void printstring(const char *s); +#endif /* PRINT_STACK_ON_REBOOT */ + +/* For debugging */ +static const char *debug_filename = "nothing"; +static int debug_line = -1; + +void +debug_file_line(const char *file, int line) +{ + debug_filename = file; + debug_line = line; +} +extern uint32 heap_location; +extern void *(*prHeap_AllocFunc)(void *, uint32, bool_t); +PRIVATE void *(*prHeap_AllocOrig)(void *, uint32, bool_t); + +/* Symbol defined by the linker script */ +/* marks the end of the stack */ +extern void *stack_low_water_mark; + +/****************************************************************************/ +/*** Local Functions ***/ +/****************************************************************************/ +/*---------------------------------------------------------------------------*/ +#if PRINT_STACK_ON_REBOOT +#include "dev/uart0.h" +#define printchar(X) uart0_write_direct(X) +/*---------------------------------------------------------------------------*/ +static void +hexprint(uint8 v) +{ + const char hexconv[] = "0123456789abcdef"; + printchar(hexconv[v >> 4]); + printchar(hexconv[v & 0x0f]); +} +/*---------------------------------------------------------------------------*/ +static void +hexprint32(uint32 v) +{ + hexprint(((uint32)v) >> (uint32)24); + hexprint(((uint32)v) >> (uint32)16); + hexprint(((uint32)v) >> (uint32)8); + hexprint((v) & 0xff); +} +/*---------------------------------------------------------------------------*/ +static void +printstring(const char *s) +{ + while(*s) { + printchar(*s++); + } +} +#endif /* PRINT_STACK_ON_REBOOT */ + +/**************************************************************************** + * + * NAME: vEXC_Register + * + * DESCRIPTION: + * Set up exceptions. When in RAM, overwrite the default vectors with ours. + * We also patch the heap allocation function so that we can keep tabs on + * the amount of free heap. + * + * PARAMETERS: None + * + * RETURNS: + * None + * + ****************************************************************************/ +PUBLIC void +vEXC_Register(void) +{ +#ifdef EXCEPTION_VECTORS_LOCATION_RAM + /* Overwrite exception vectors, pointing them all at the generic handler */ + BUS_ERROR = (uint32)exception_handler; + UNALIGNED_ACCESS = (uint32)exception_handler; + ILLEGAL_INSTRUCTION = (uint32)exception_handler; + SYSCALL = (uint32)exception_handler; + TRAP = (uint32)exception_handler; + GENERIC = (uint32)exception_handler; + STACK_OVERFLOW = (uint32)exception_handler; +#endif /* EXCEPTION_VECTORS_LOCATION */ + + prHeap_AllocOrig = prHeap_AllocFunc; + prHeap_AllocFunc = heap_alloc_overflow_protect; +} +#ifdef EXCEPTION_VECTORS_LOCATION_FLASH +/* If exception vectors are in flash, define the handler functions here to be linked in */ +/* These function names are defined in the 6x linker script for the various exceptions */ +/* Point them all at the generic handler */ +PUBLIC void +vException_BusError(uint32 *pu32Stack, eExceptionType eType) +{ + exception_handler(pu32Stack, eType); +} +PUBLIC void +vException_UnalignedAccess(uint32 *pu32Stack, eExceptionType eType) +{ + exception_handler(pu32Stack, eType); +} +PUBLIC void +vException_IllegalInstruction(uint32 *pu32Stack, eExceptionType eType) +{ + exception_handler(pu32Stack, eType); +} +PUBLIC void +vException_SysCall(uint32 *pu32Stack, eExceptionType eType) +{ + exception_handler(pu32Stack, eType); +} +PUBLIC void +vException_Trap(uint32 *pu32Stack, eExceptionType eType) +{ + exception_handler(pu32Stack, eType); +} +PUBLIC void +vException_StackOverflow(uint32 *pu32Stack, eExceptionType eType) +{ + exception_handler(pu32Stack, eType); +} +#endif /* EXCEPTION_VECTORS_LOCATION_FLASH */ + +/**************************************************************************** + * + * NAME: exception_handler + * + * DESCRIPTION: + * Generic exception handler which is called whether the vectors are in RAM or flash + * + * PARAMETERS: None + * + * RETURNS: + * None + * + ****************************************************************************/ +static void +exception_handler(uint32 *pu32Stack, eExceptionType eType) +{ +#if (defined EXC_DUMP_STACK) || (defined EXC_DUMP_REGS) + int i; +#endif + uint32 u32EPCR, u32EEAR, u32Stack; + char *pcString; + + MICRO_DISABLE_INTERRUPTS(); + + switch(eType) { + case E_EXC_BUS_ERROR: + pcString = "BUS"; + break; + + case E_EXC_UNALIGNED_ACCESS: + pcString = "ALIGN"; + break; + + case E_EXC_ILLEGAL_INSTRUCTION: + pcString = "ILLEGAL"; + break; + + case E_EXC_SYSCALL: + pcString = "SYSCALL"; + break; + + case E_EXC_TRAP: + pcString = "TRAP"; + break; + + case E_EXC_GENERIC: + pcString = "GENERIC"; + break; + + case E_EXC_STACK_OVERFLOW: + pcString = "STACK"; + break; + + default: + pcString = "UNKNOWN"; + break; + } + + if(bAHI_WatchdogResetEvent()) { + pcString = "WATCHDOG"; + } + vAHI_WatchdogStop(); + + /* Pull the EPCR and EEAR values from where they've been saved by the ROM exception handler */ + u32EPCR = pu32Stack[PROGRAM_COUNTER]; + u32EEAR = pu32Stack[EFFECTIVE_ADDR]; + u32Stack = pu32Stack[STACK_REG]; + + /* Log the exception */ + printstring("\n\n\n"); + printstring(pcString); + printstring(" EXCEPTION @ $"); + hexprint32(u32EPCR); + printstring(" EA: "); + hexprint32(u32EEAR); + printstring(" SK: "); + hexprint32(u32Stack); + printstring(" HP: "); + hexprint32(((uint32 *)&heap_location)[0]); + printstring("\n"); + printstring(" File: "); + printstring(debug_filename); + printstring(" Line: "); + hexprint32(debug_line); + printstring("\n"); + +#ifdef EXC_DUMP_REGS + printstring("\nREGS: "); + /* Pull and print the registers from saved locations */ + for(i = 0; i < REG_COUNT; i += 4) { + printstring("R"); + hexprint(i); + printstring("-"); + hexprint(i + 3); + printstring(": "); + hexprint(pu32Stack[i]); + printstring(" "); + hexprint32(pu32Stack[i + 1]); + printstring(" "); + hexprint32(pu32Stack[i + 2]); + printstring(" "); + hexprint32(pu32Stack[i + 3]); + printstring("\n"); + } +#endif + +#ifdef EXC_DUMP_STACK + /* Print the stack */ + printstring("\nRAM top: "); + hexprint32(EXCEPTION_RAM_TOP); + printstring("\nSTACK: \n"); + pu32Stack = (uint32 *)(u32Stack & 0xFFFFFFF0); + for(i = 0; (pu32Stack + i) < (uint32 *)(EXCEPTION_RAM_TOP); i += 4) { + printstring("@"); + hexprint32((uint32)(pu32Stack + i)); + printstring(": "); + hexprint32(pu32Stack[i]); + printstring(" "); + hexprint32(pu32Stack[i + 1]); + printstring(" "); + hexprint32(pu32Stack[i + 2]); + printstring(" "); + hexprint32(pu32Stack[i + 3]); + printstring("\n"); + } +#endif + +#if EXCEPTION_STALLS_SYSTEM + while(1) { + } +#else /* EXCEPTION_STALLS_SYSTEM */ + /* Software reset */ + vAHI_WatchdogException(0); + vAHI_SwReset(); +#endif /* EXCEPTION_STALLS_SYSTEM */ +} +/**************************************************************************** + * + * NAME: heap_alloc_overflow_protect + * + * DESCRIPTION: + * New heap allocation function that sets the stack overflow location to the new + * top address of the heap. + * + * PARAMETERS: Name RW Usage + * pvPointer W Location of allocated heap memory + * u32Size R Number of bytes to allocate + * bClear R Flag to set new memory to 0 + * + * RETURNS: + * Pointer to new memory + * + ****************************************************************************/ +static void * +heap_alloc_overflow_protect(void *pvPointer, uint32 u32Size, bool_t bClear) +{ + void *pvAlloc; + /* Call original heap allocation function */ + pvAlloc = prHeap_AllocOrig(pvPointer, u32Size, bClear); + /* + * Initialise the stack overflow exception to trigger if the end of the + * stack is reached. See the linker command file to adjust the allocated + * stack size. + */ + /* Set stack overflow address */ + vAHI_SetStackOverflow(TRUE, ((uint32 *)&heap_location)[0]); + return pvAlloc; +} diff --git a/platform/jn516x/dev/exceptions.h b/platform/jn516x/dev/exceptions.h new file mode 100644 index 000000000..6acfd8d16 --- /dev/null +++ b/platform/jn516x/dev/exceptions.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Thomas Haydon + * Integrated into Contiki by Beshr Al Nahas + * + */ + +#ifndef EXCEPTIONS_H +#define EXCEPTIONS_H + +#include + +/** Enumerated type of CPU exception numbers */ +typedef enum { + E_EXC_BUS_ERROR = 0x02, + E_EXC_TICK_TIMER = 0x05, + E_EXC_UNALIGNED_ACCESS = 0x06, + E_EXC_ILLEGAL_INSTRUCTION = 0x07, + E_EXC_EXTERNAL_INTERRUPT = 0x08, + E_EXC_SYSCALL = 0x0C, + E_EXC_TRAP = 0x0E, + E_EXC_GENERIC = 0x0F, + E_EXC_STACK_OVERFLOW = 0x10 +} eExceptionType; + +/* Exceptions set up function */ +PUBLIC void vEXC_Register(void); +/* For debugging */ +void debug_file_line(const char *file, int line); + +#endif /* EXCEPTIONS_H */ diff --git a/platform/jn516x/dev/jn516x-ccm-star.c b/platform/jn516x/dev/jn516x-ccm-star.c new file mode 100644 index 000000000..b846985be --- /dev/null +++ b/platform/jn516x/dev/jn516x-ccm-star.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * CCM* header implementation exploiting the JN516x + * cryptographic co-processor + * \author + * Simon Duquennoy + */ + +#include "ccm-star.h" +#include +#include + +static tsReg128 current_key; +static int current_key_is_new = 1; + +/*---------------------------------------------------------------------------*/ +static void +aead(const uint8_t *nonce, + uint8_t *m, uint8_t m_len, + const uint8_t *a, uint8_t a_len, + uint8_t *result, uint8_t mic_len, + int forward) +{ + tsReg128 nonce_aligned; + memcpy(&nonce_aligned, nonce, sizeof(nonce_aligned)); + if(forward) { + bACI_CCMstar( + ¤t_key, + current_key_is_new, + XCV_REG_AES_SET_MODE_CCM, + mic_len, + a_len, + m_len, + &nonce_aligned, + (uint8_t *)a, + (uint8_t *)m, + (uint8_t *)m, + result, + NULL + ); + } else { + bool_t auth; + bACI_CCMstar( + ¤t_key, + current_key_is_new, + XCV_REG_AES_SET_MODE_CCM_D, + mic_len, + a_len, + m_len, + &nonce_aligned, + (uint8_t *)a, + (uint8_t *)m, + (uint8_t *)m, + (uint8_t *)a + a_len + m_len, + &auth + ); + /* To comply with the CCM_STAR interface, copy MIC to result in case of success */ + if(result != NULL) { + if(auth) { + memcpy(result, a + a_len + m_len, mic_len); + } else { + /* Otherwise, corrupt the result */ + memcpy(result, a + a_len + m_len, mic_len); + result[0]++; + } + } + } + + current_key_is_new = 0; +} +/*---------------------------------------------------------------------------*/ +static void +set_key(const uint8_t *key) +{ + if(memcmp(¤t_key, key, sizeof(current_key)) == 0) { + current_key_is_new = 0; + } else { + memcpy(¤t_key, key, sizeof(current_key)); + current_key_is_new = 1; + } +} +/*---------------------------------------------------------------------------*/ +const struct ccm_star_driver ccm_star_driver_jn516x = { + set_key, + aead +}; +/*---------------------------------------------------------------------------*/ diff --git a/platform/jn516x/dev/leds-extension.c b/platform/jn516x/dev/leds-extension.c new file mode 100644 index 000000000..05e9a8223 --- /dev/null +++ b/platform/jn516x/dev/leds-extension.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#include "leds-extension.h" +#include "dev/leds.h" + +void +leds_set_level(unsigned char level, unsigned char c) +{ + leds_arch_set_level(level, c); +} diff --git a/platform/jn516x/dev/leds-extension.h b/platform/jn516x/dev/leds-extension.h new file mode 100644 index 000000000..2e33b59ff --- /dev/null +++ b/platform/jn516x/dev/leds-extension.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Theo van Daele + * + */ +#ifndef LEDS_EXTENSION_H_ +#define LEDS_EXTENSION_H_ + +void leds_set_level(unsigned char level, unsigned char c); + +/** + * Leds implementation + */ +void leds_arch_set_level(unsigned char level, unsigned char c); + +#endif /* LEDS_EXTENSION_H_ */ \ No newline at end of file diff --git a/platform/jn516x/dev/micromac-radio.c b/platform/jn516x/dev/micromac-radio.c new file mode 100644 index 000000000..e2d087aa2 --- /dev/null +++ b/platform/jn516x/dev/micromac-radio.c @@ -0,0 +1,967 @@ +/* + * Copyright (c) 2014, NXP and SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Contiki driver for NXP JN516X using MMAC interface + * \authors + * Beshr Al Nahas + * Simon Duquennot + * Atis Elsts + * + */ + +#include +#include "contiki.h" +#include "dev/leds.h" +#include "sys/rtimer.h" +#include "net/packetbuf.h" +#include "net/rime/rimestats.h" +#include "net/netstack.h" +#include "net/mac/frame802154.h" +#include "lib/crc16.h" +#include "lib/ringbufindex.h" + +#include "AppHardwareApi.h" +#include "MMAC.h" +#include "micromac-radio.h" +#include "JPT.h" +#include "PeripheralRegs.h" + +void vMMAC_SetChannelAndPower(uint8 u8Channel, int8 i8power); + +/* This driver configures the radio in PHY mode and does address decoding + * and acknowledging in software. */ + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +/* Perform CRC check for received packets in SW, + * since we use PHY mode which does not calculate CRC in HW */ +#define CRC_SW 1 + +#define CHECKSUM_LEN 2 + +/* Max packet duration: 5 + 127 + 2 bytes, 32us per byte */ +#define MAX_PACKET_DURATION US_TO_RTIMERTICKS((127 + 2) * 32 + RADIO_DELAY_BEFORE_TX) +/* Max ACK duration: 5 + 3 + 2 bytes */ +#define MAX_ACK_DURATION US_TO_RTIMERTICKS((3 + 2) * 32 + RADIO_DELAY_BEFORE_TX) + +/* Test-mode pins output on dev-kit */ +#define RADIO_TEST_MODE_HIGH_PWR 1 +#define RADIO_TEST_MODE_ADVANCED 2 +#define RADIO_TEST_MODE_DISABLED 0 + +#ifndef RADIO_TEST_MODE +#define RADIO_TEST_MODE RADIO_TEST_MODE_DISABLED +#endif /* RADIO_TEST_MODE */ + +/* The number of input buffers */ +#ifndef MIRCOMAC_CONF_BUF_NUM +#define MIRCOMAC_CONF_BUF_NUM 2 +#endif /* MIRCOMAC_CONF_BUF_NUM */ + +/* Init radio channel */ +#ifndef MICROMAC_CONF_CHANNEL +#define MICROMAC_CONF_CHANNEL 26 +#endif + +/* Default energy level threshold for clear channel detection */ +#ifndef MICROMAC_CONF_CCA_THR +#define MICROMAC_CONF_CCA_THR 39 /* approximately -85 dBm */ +#endif /* MICROMAC_CONF_CCA_THR */ + +#if (JENNIC_CHIP == JN5169) +#define OUTPUT_POWER_MAX 10 +#define OUTPUT_POWER_MIN (-32) +#define ABS_OUTPUT_POWER_MIN (32) +#else +#define OUTPUT_POWER_MAX 0 +#define OUTPUT_POWER_MIN (-32) +#endif + +/* Default Tx power [dBm] (between OUTPUT_POWER_MIN and OUTPUT_POWER_MAX) */ +#ifndef MICROMAC_CONF_TX_POWER +#define MICROMAC_CONF_TX_POWER 0 +#endif + +/* Autoack */ +#ifndef MICROMAC_CONF_AUTOACK +#define MICROMAC_CONF_AUTOACK 1 +#endif /* MICROMAC_CONF_AUTOACK */ + +/* Set radio always on for now because this is what Contiki MAC layers + * expect. */ +#ifndef MICROMAC_CONF_ALWAYS_ON +#define MICROMAC_CONF_ALWAYS_ON 1 +#endif /* MICROMAC_CONF_ALWAYS_ON */ + +#define BUSYWAIT_UNTIL(cond, max_time) \ + do { \ + rtimer_clock_t t0; \ + t0 = RTIMER_NOW(); \ + while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))) ; \ + } while(0) + +/* Local variables */ +static volatile signed char radio_last_rssi; +static volatile uint8_t radio_last_correlation; /* LQI */ + +/* Did we miss a request to turn the radio on due to overflow? */ +static volatile uint8_t missed_radio_on_request = 0; + +/* Poll mode disabled by default */ +static uint8_t poll_mode = 0; +/* (Software) frame filtering enabled by default */ +static uint8_t frame_filtering = 1; +/* (Software) autoack */ +static uint8_t autoack_enabled = MICROMAC_CONF_AUTOACK; +/* CCA before sending? Disabled by default. */ +static uint8_t send_on_cca = 0; + +/* Current radio channel */ +static int current_channel = MICROMAC_CONF_CHANNEL; + +/* Current set point tx power + Actual tx power may be different. Use get_txpower() for actual power */ +static int current_tx_power = MICROMAC_CONF_TX_POWER; + +/* an integer between 0 and 255, used only with cca() */ +static uint8_t cca_thershold = MICROMAC_CONF_CCA_THR; + +/* Tx in progress? */ +static volatile uint8_t tx_in_progress = 0; +/* Are we currently listening? */ +static volatile uint8_t listen_on = 0; + +/* Is the driver currently transmitting a software ACK? */ +static uint8_t in_ack_transmission = 0; + +/* TX frame buffer */ +static tsPhyFrame tx_frame_buffer; + +/* RX frame buffer */ +static tsPhyFrame *rx_frame_buffer; + +/* Frame buffer pointer to read from */ +static tsPhyFrame *input_frame_buffer = NULL; + +/* Ringbuffer for received packets in interrupt enabled mode */ +static struct ringbufindex input_ringbuf; +static tsPhyFrame input_array[MIRCOMAC_CONF_BUF_NUM]; + +/* SFD timestamp in RTIMER ticks */ +static volatile uint32_t last_packet_timestamp = 0; + +/* Local functions prototypes */ +static int on(void); +static int off(void); +static int is_packet_for_us(uint8_t *buf, int len, int do_send_ack); +static void set_frame_filtering(uint8_t enable); +static rtimer_clock_t get_packet_timestamp(void); +static void set_txpower(int8_t power); +void set_channel(int c); +static void radio_interrupt_handler(uint32 mac_event); +static int get_detected_energy(void); +static int get_rssi(void); +static void read_last_rssi(void); + +/*---------------------------------------------------------------------------*/ +PROCESS(micromac_radio_process, "micromac_radio_driver"); +/*---------------------------------------------------------------------------*/ + +/* Custom Radio parameters */ +#ifndef RADIO_RX_MODE_POLL_MODE +#define RADIO_PARAM_LAST_RSSI 0x80 +#define RADIO_PARAM_LAST_PACKET_TIMESTAMP 0x81 +#define RADIO_RX_MODE_POLL_MODE (1 << 2) +#endif /* RADIO_RX_MODE_POLL_MODE */ + +/*---------------------------------------------------------------------------*/ +static rtimer_clock_t +get_packet_timestamp(void) +{ + /* Wait for an edge */ + uint32_t t = u32MMAC_GetTime(); + while(u32MMAC_GetTime() == t); + /* Save SFD timestamp, converted from radio timer to RTIMER */ + last_packet_timestamp = RTIMER_NOW() - + RADIO_TO_RTIMER((uint32_t)(u32MMAC_GetTime() - (u32MMAC_GetRxTime() - 1))); + /* The remaining measured error is typically in range 0..16 usec. + * Center it around zero, in the -8..+8 usec range. */ + last_packet_timestamp -= US_TO_RTIMERTICKS(8); + return last_packet_timestamp; +} +/*---------------------------------------------------------------------------*/ +static int +init_software(void) +{ + int put_index; + /* Initialize ring buffer and first input packet pointer */ + ringbufindex_init(&input_ringbuf, MIRCOMAC_CONF_BUF_NUM); + /* get pointer to next input slot */ + put_index = ringbufindex_peek_put(&input_ringbuf); + if(put_index == -1) { + rx_frame_buffer = NULL; + printf("micromac_radio init:! no buffer available. Abort init.\n"); + off(); + return 0; + } else { + rx_frame_buffer = &input_array[put_index]; + } + input_frame_buffer = rx_frame_buffer; + + process_start(µmac_radio_process, NULL); + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +init(void) +{ + int ret = 1; + tsExtAddr node_long_address; + uint16_t node_short_address; + static uint8_t is_initialized; + + tx_in_progress = 0; + + u32JPT_Init(); + vMMAC_Enable(); + + /* Enable/disable interrupts */ + if(poll_mode) { + vMMAC_EnableInterrupts(NULL); + vMMAC_ConfigureInterruptSources(0); + } else { + vMMAC_EnableInterrupts(&radio_interrupt_handler); + } + vMMAC_ConfigureRadio(); + set_channel(current_channel); + set_txpower(current_tx_power); + + vMMAC_GetMacAddress(&node_long_address); + /* Short addresses are disabled by default */ + node_short_address = (uint16_t)node_long_address.u32L; + vMMAC_SetRxAddress(frame802154_get_pan_id(), node_short_address, &node_long_address); + + /* Disable hardware backoff */ + vMMAC_SetTxParameters(1, 0, 0, 0); + vMMAC_SetCutOffTimer(0, FALSE); + +#if RADIO_TEST_MODE == RADIO_TEST_MODE_HIGH_PWR + /* Enable high power mode. + * In this mode DIO2 goes high during RX + * and DIO3 goes high during TX + **/ + vREG_SysWrite(REG_SYS_PWR_CTRL, + u32REG_SysRead(REG_SYS_PWR_CTRL) + | REG_SYSCTRL_PWRCTRL_RFRXEN_MASK + | REG_SYSCTRL_PWRCTRL_RFTXEN_MASK); +#elif RADIO_TEST_MODE == RADIO_TEST_MODE_ADVANCED + /* output internal radio status on IO pins. + * See Chris@NXP email */ + vREG_SysWrite(REG_SYS_PWR_CTRL, + u32REG_SysRead(REG_SYS_PWR_CTRL) | (1UL << 26UL)); +#endif /* TEST_MODE */ + + if(!is_initialized) { + is_initialized = 1; + ret = init_software(); + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +on(void) +{ + /* No address matching or frame decoding */ + if(rx_frame_buffer != NULL) { + vMMAC_StartPhyReceive(rx_frame_buffer, + (uint16_t)(E_MMAC_RX_START_NOW + | E_MMAC_RX_NO_FCS_ERROR) /* means: reject FCS errors */ + ); + } else { + missed_radio_on_request = 1; + } + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + listen_on = 1; + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +off(void) +{ + listen_on = 0; + tx_in_progress = 0; + + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + + /* The following would be needed with delayed Tx/Rx functions + * vMMAC_SetCutOffTimer(0, FALSE);*/ + vMMAC_RadioOff(); + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +transmit(unsigned short payload_len) +{ + if(tx_in_progress) { + return RADIO_TX_COLLISION; + } + tx_in_progress = 1; + + /* Energest */ + if(listen_on) { + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + } + ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); + + /* Transmit and wait */ + vMMAC_StartPhyTransmit(&tx_frame_buffer, + E_MMAC_TX_START_NOW | + (send_on_cca ? E_MMAC_TX_USE_CCA : E_MMAC_TX_NO_CCA)); + + if(poll_mode) { + BUSYWAIT_UNTIL(u32MMAC_PollInterruptSource(E_MMAC_INT_TX_COMPLETE), MAX_PACKET_DURATION); + } else { + if(in_ack_transmission) { + /* as nested interupts are not possible, the tx flag will never be cleared */ + BUSYWAIT_UNTIL(FALSE, MAX_ACK_DURATION); + } else { + /* wait until the tx flag is cleared */ + BUSYWAIT_UNTIL(!tx_in_progress, MAX_PACKET_DURATION); + } + } + + /* Energest */ + ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); + if(listen_on) { + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + } + tx_in_progress = 0; + + /* Check error code */ + int ret; + uint32_t tx_error = u32MMAC_GetTxErrors(); + if(tx_error == 0) { + ret = RADIO_TX_OK; + RIMESTATS_ADD(acktx); + } else if(tx_error & E_MMAC_TXSTAT_ABORTED) { + ret = RADIO_TX_ERR; + RIMESTATS_ADD(sendingdrop); + } else if(tx_error & E_MMAC_TXSTAT_CCA_BUSY) { + ret = RADIO_TX_COLLISION; + RIMESTATS_ADD(contentiondrop); + } else if(tx_error & E_MMAC_TXSTAT_NO_ACK) { + ret = RADIO_TX_NOACK; + RIMESTATS_ADD(noacktx); + } else { + ret = RADIO_TX_ERR; + } + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +prepare(const void *payload, unsigned short payload_len) +{ + uint8_t i; + uint16_t checksum; + + RIMESTATS_ADD(lltx); + + if(tx_in_progress) { + return 1; + } + if(payload_len > 127 || payload == NULL) { + return 1; + } + /* Copy payload to (soft) Ttx buffer */ + memcpy(tx_frame_buffer.uPayload.au8Byte, payload, payload_len); + i = payload_len; +#if CRC_SW + /* Compute CRC */ + checksum = crc16_data(payload, payload_len, 0); + tx_frame_buffer.uPayload.au8Byte[i++] = checksum; + tx_frame_buffer.uPayload.au8Byte[i++] = (checksum >> 8) & 0xff; + tx_frame_buffer.u8PayloadLength = payload_len + CHECKSUM_LEN; +#else + tx_frame_buffer.u8PayloadLength = payload_len; +#endif + + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +send(const void *payload, unsigned short payload_len) +{ + if(prepare(payload, payload_len) == 0) { + return transmit(payload_len); + } else { + return RADIO_TX_ERR; + } +} +/*---------------------------------------------------------------------------*/ +int +get_channel(void) +{ + return current_channel; +} +/*---------------------------------------------------------------------------*/ +void +set_channel(int c) +{ + current_channel = c; + /* will fine tune TX power as well */ + vMMAC_SetChannel(current_channel); +} +/*---------------------------------------------------------------------------*/ +static int +is_broadcast_addr(uint8_t mode, uint8_t *addr) +{ + int i = ((mode == FRAME802154_SHORTADDRMODE) ? 2 : 8); + while(i-- > 0) { + if(addr[i] != 0xff) { + return 0; + } + } + return 1; +} +/*---------------------------------------------------------------------------*/ +/* Send an ACK */ +static void +send_ack(const frame802154_t *frame) +{ + uint8_t buffer[3]; + /* FCF: 2 octets */ + buffer[0] = FRAME802154_ACKFRAME; + buffer[1] = 0; + /* Seqnum: 1 octets */ + buffer[2] = frame->seq; + in_ack_transmission = 1; + send(&buffer, sizeof(buffer)); + in_ack_transmission = 0; +} +/*---------------------------------------------------------------------------*/ +/* Check if a packet is for us */ +static int +is_packet_for_us(uint8_t *buf, int len, int do_send_ack) +{ + frame802154_t frame; + int result; + uint8_t parsed = frame802154_parse(buf, len, &frame); + if(parsed) { + if(frame.fcf.dest_addr_mode) { + int has_dest_panid; + frame802154_has_panid(&frame.fcf, NULL, &has_dest_panid); + if(has_dest_panid + && frame802154_get_pan_id() != FRAME802154_BROADCASTPANDID + && frame.dest_pid != frame802154_get_pan_id() + && frame.dest_pid != FRAME802154_BROADCASTPANDID) { + /* Packet to another PAN */ + return 0; + } + if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { + result = linkaddr_cmp((linkaddr_t *)frame.dest_addr, &linkaddr_node_addr); + if(autoack_enabled && result && do_send_ack) { + /* this is a unicast frame and sending ACKs is enabled */ + send_ack(&frame); + } + return result; + } + } + return 1; + } else { + return 0; + } +} +/*---------------------------------------------------------------------------*/ +static int +read(void *buf, unsigned short bufsize) +{ + int len = 0; + uint16_t radio_last_rx_crc; + uint8_t radio_last_rx_crc_ok = 1; + + len = input_frame_buffer->u8PayloadLength; + + if(len <= CHECKSUM_LEN) { + input_frame_buffer->u8PayloadLength = 0; + return 0; + } else { + len -= CHECKSUM_LEN; + /* Check CRC */ +#if CRC_SW + uint16_t checksum = crc16_data(input_frame_buffer->uPayload.au8Byte, len, 0); + radio_last_rx_crc = + (uint16_t)(input_frame_buffer->uPayload.au8Byte[len + 1] << (uint16_t)8) + | input_frame_buffer->uPayload.au8Byte[len]; + radio_last_rx_crc_ok = (checksum == radio_last_rx_crc); + if(!radio_last_rx_crc_ok) { + RIMESTATS_ADD(badcrc); + } +#endif /* CRC_SW */ + if(radio_last_rx_crc_ok) { + /* If we are in poll mode we need to check the frame here */ + if(poll_mode) { + if(frame_filtering && + !is_packet_for_us(input_frame_buffer->uPayload.au8Byte, len, 0)) { + len = 0; + } else { + read_last_rssi(); + } + } + if(len != 0) { + bufsize = MIN(len, bufsize); + memcpy(buf, input_frame_buffer->uPayload.au8Byte, bufsize); + RIMESTATS_ADD(llrx); + if(!poll_mode) { + /* Not in poll mode: packetbuf should not be accessed in interrupt context */ + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, radio_last_rssi); + packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, radio_last_correlation); + } + } + } else { + len = 0; + } + /* Disable further read attempts */ + input_frame_buffer->u8PayloadLength = 0; + } + + return len; +} +/*---------------------------------------------------------------------------*/ +static void +set_txpower(int8_t power) +{ + if(power > OUTPUT_POWER_MAX) { + current_tx_power = OUTPUT_POWER_MAX; + } else { + if(power < OUTPUT_POWER_MIN) { + current_tx_power = OUTPUT_POWER_MIN; + } else { + current_tx_power = power; + } + } + vMMAC_SetChannelAndPower(current_channel, current_tx_power); +} +/*--------------------------------------------------------------------------*/ +static int +get_txpower(void) +{ + int actual_tx_power; +#if (JENNIC_CHIP == JN5169) + /* Actual tx power value rounded to nearest integer number */ + const static int8 power_table [] = { + -32, -30, -29, -29, /* -32 .. -29 */ + -28, -28, -28, -28, /* -28 .. -25 */ + -21, -21, -21, -2, /* -24 .. -21 */ + -20, -19, -18, -17, /* -20 .. -17 */ + -17, -17, -17, -10, /* -16 .. -13 */ + -10, -10, -10, -9, /* -12 .. -09 */ + -8, -7, -6, -6, /* -08 .. -05 */ + -6, -6, 1, 1, /* -04 .. -01 */ + 1, 1, 2, 3, /* 00 .. 03 */ + 4, 5, 6, 7, /* 04 .. 07 */ + 9, 9, 10 }; /* 08 .. 10 */ + if(current_tx_power > OUTPUT_POWER_MAX) { + actual_tx_power = OUTPUT_POWER_MAX; + } else if(current_tx_power < OUTPUT_POWER_MIN) { + actual_tx_power = OUTPUT_POWER_MIN; + } else { + actual_tx_power = power_table[current_tx_power + ABS_OUTPUT_POWER_MIN]; + } +#else + /* Other JN516x chips */ + if(current_tx_power < (-24)) { + actual_tx_power = OUTPUT_POWER_MIN; + } else if(current_tx_power < (-12)) { + actual_tx_power = (-20); + } else if(current_tx_power < 0) { + actual_tx_power = (-9); + } else { + actual_tx_power = OUTPUT_POWER_MAX; + } +#endif + return (int)actual_tx_power; +} +/*---------------------------------------------------------------------------*/ +static int +get_detected_energy(void) +{ + const uint32 u32Samples = 8; + return u8JPT_EnergyDetect(current_channel, u32Samples); +} +/*---------------------------------------------------------------------------*/ +static int +get_rssi(void) +{ + /* this approximate formula for RSSI is taken from NXP internal docs */ + return (7 * get_detected_energy() - 1970) / 20; +} +/*---------------------------------------------------------------------------*/ +static void +read_last_rssi(void) +{ + uint8_t radio_last_rx_energy; + radio_last_rx_energy = u8MMAC_GetRxLqi((uint8_t *)&radio_last_correlation); + radio_last_rssi = i16JPT_ConvertEnergyTodBm(radio_last_rx_energy); +} +/*---------------------------------------------------------------------------*/ +int +receiving_packet(void) +{ + return bMMAC_RxDetected(); +} +/*---------------------------------------------------------------------------*/ +static int +pending_packet(void) +{ + if(!poll_mode) { + return ringbufindex_peek_get(&input_ringbuf) != -1; + } else { + return u32MMAC_PollInterruptSource( + E_MMAC_INT_RX_COMPLETE | E_MMAC_INT_RX_HEADER); + } +} +/*---------------------------------------------------------------------------*/ +static int +cca(void) +{ + bool_t is_channel_busy = bJPT_CCA(current_channel, + E_JPT_CCA_MODE_CARRIER_OR_ENERGY, + cca_thershold); + return is_channel_busy == FALSE; +} +/*---------------------------------------------------------------------------*/ +static void +radio_interrupt_handler(uint32 mac_event) +{ + uint32_t rx_status; + uint8_t overflow = 0; + int get_index; + int put_index; + int packet_for_me = 0; + + if(mac_event & E_MMAC_INT_TX_COMPLETE) { + /* Transmission attempt has finished */ + tx_in_progress = 0; + } else if(mac_event & E_MMAC_INT_RX_COMPLETE) { + rx_status = u32MMAC_GetRxErrors(); + /* If rx is successful */ + if(rx_status == 0) { + /* Save SFD timestamp */ + last_packet_timestamp = get_packet_timestamp(); + + if(!poll_mode && (mac_event & E_MMAC_INT_RX_COMPLETE)) { + if(rx_frame_buffer->u8PayloadLength > CHECKSUM_LEN) { + if(frame_filtering) { + /* Check RX address */ + packet_for_me = is_packet_for_us(rx_frame_buffer->uPayload.au8Byte, rx_frame_buffer->u8PayloadLength - CHECKSUM_LEN, 1); + } else if(!frame_filtering) { + packet_for_me = 1; + } + } + if(!packet_for_me) { + /* Prevent reading */ + rx_frame_buffer->u8PayloadLength = 0; + } else { + /* read and cache RSSI and LQI values */ + read_last_rssi(); + /* Put received frame in queue */ + ringbufindex_put(&input_ringbuf); + + if((get_index = ringbufindex_peek_get(&input_ringbuf)) != -1) { + input_frame_buffer = &input_array[get_index]; + } + process_poll(µmac_radio_process); + + /* get pointer to next input slot */ + put_index = ringbufindex_peek_put(&input_ringbuf); + /* is there space? */ + if(put_index != -1) { + /* move rx_frame_buffer to next empty slot */ + rx_frame_buffer = &input_array[put_index]; + } else { + overflow = 1; + rx_frame_buffer = NULL; + } + } + } + } else { /* if rx is not successful */ + if(rx_status & E_MMAC_RXSTAT_ABORTED) { + RIMESTATS_ADD(badsynch); + } else if(rx_status & E_MMAC_RXSTAT_ERROR) { + RIMESTATS_ADD(badcrc); + } else if(rx_status & E_MMAC_RXSTAT_MALFORMED) { + RIMESTATS_ADD(toolong); + } + } + } + if(overflow) { + off(); + } else if(MICROMAC_CONF_ALWAYS_ON + && (mac_event & (E_MMAC_INT_TX_COMPLETE | E_MMAC_INT_RX_COMPLETE))) { + on(); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(micromac_radio_process, ev, data) +{ + PROCESS_BEGIN(); + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + + /* Pass received packets to upper layer */ + int16_t read_index; + /* Loop on accessing (without removing) a pending input packet */ + while((read_index = ringbufindex_peek_get(&input_ringbuf)) != -1) { + input_frame_buffer = &input_array[read_index]; + /* Put packet into packetbuf for input callback */ + packetbuf_clear(); + int len = read(packetbuf_dataptr(), PACKETBUF_SIZE); + /* is packet valid? */ + if(len > 0) { + packetbuf_set_datalen(len); + NETSTACK_RDC.input(); + } + /* Remove packet from ringbuf */ + ringbufindex_get(&input_ringbuf); + /* Disable further read attempts */ + input_frame_buffer->u8PayloadLength = 0; + } + + /* Are we recovering from overflow? */ + if(rx_frame_buffer == NULL) { + /* get pointer to next input slot */ + int put_index = ringbufindex_peek_put(&input_ringbuf); + /* is there space? */ + if(put_index != -1) { + /* move rx_frame_buffer to next empty slot */ + rx_frame_buffer = &input_array[put_index]; + /* do we need to turn radio on? */ + if(MICROMAC_CONF_ALWAYS_ON || missed_radio_on_request) { + missed_radio_on_request = 0; + on(); + } + } else { + rx_frame_buffer = NULL; + } + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +static void +set_frame_filtering(uint8_t enable) +{ + frame_filtering = enable; +} +/*---------------------------------------------------------------------------*/ +static void +set_autoack(uint8_t enable) +{ + autoack_enabled = enable; +} +/*---------------------------------------------------------------------------*/ +static void +set_poll_mode(uint8_t enable) +{ + poll_mode = enable; + if(poll_mode) { + /* Disable interrupts */ + vMMAC_EnableInterrupts(NULL); + vMMAC_ConfigureInterruptSources(0); + } else { + /* Initialize and enable interrupts */ + /* TODO: enable E_MMAC_INT_RX_HEADER & filter out frames after header rx */ + vMMAC_ConfigureInterruptSources( + E_MMAC_INT_RX_COMPLETE | E_MMAC_INT_TX_COMPLETE); + vMMAC_EnableInterrupts(&radio_interrupt_handler); + } +} +/* Enable or disable CCA before sending */ +static void +set_send_on_cca(uint8_t enable) +{ + send_on_cca = enable; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + if(!value) { + return RADIO_RESULT_INVALID_VALUE; + } + switch(param) { + case RADIO_PARAM_POWER_MODE: + *value = listen_on || tx_in_progress ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF; + return RADIO_RESULT_OK; + case RADIO_PARAM_CHANNEL: + *value = get_channel(); + return RADIO_RESULT_OK; + case RADIO_PARAM_RX_MODE: + *value = 0; + if(frame_filtering) { + *value |= RADIO_RX_MODE_ADDRESS_FILTER; + } + if(autoack_enabled) { + *value |= RADIO_RX_MODE_AUTOACK; + } + if(poll_mode) { + *value |= RADIO_RX_MODE_POLL_MODE; + } + return RADIO_RESULT_OK; + case RADIO_PARAM_TX_MODE: + *value = 0; + if(send_on_cca) { + *value |= RADIO_TX_MODE_SEND_ON_CCA; + } + return RADIO_RESULT_OK; + case RADIO_PARAM_TXPOWER: + *value = get_txpower(); + return RADIO_RESULT_OK; + case RADIO_PARAM_RSSI: + *value = get_rssi(); + return RADIO_RESULT_OK; + case RADIO_PARAM_LAST_RSSI: + *value = radio_last_rssi; + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + *value = cca_thershold; + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MIN: + *value = 11; + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MAX: + *value = 26; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MIN: + *value = OUTPUT_POWER_MIN; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MAX: + *value = OUTPUT_POWER_MAX; + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + switch(param) { + case RADIO_PARAM_POWER_MODE: + if(value == RADIO_POWER_MODE_ON) { + on(); + return RADIO_RESULT_OK; + } + if(value == RADIO_POWER_MODE_OFF) { + off(); + return RADIO_RESULT_OK; + } + return RADIO_RESULT_INVALID_VALUE; + case RADIO_PARAM_CHANNEL: + if(value < 11 || value > 26) { + return RADIO_RESULT_INVALID_VALUE; + } + set_channel(value); + return RADIO_RESULT_OK; + case RADIO_PARAM_RX_MODE: + if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER | + RADIO_RX_MODE_AUTOACK | RADIO_RX_MODE_POLL_MODE)) { + return RADIO_RESULT_INVALID_VALUE; + } + set_frame_filtering((value & RADIO_RX_MODE_ADDRESS_FILTER) != 0); + set_autoack((value & RADIO_RX_MODE_AUTOACK) != 0); + set_poll_mode((value & RADIO_RX_MODE_POLL_MODE) != 0); + return RADIO_RESULT_OK; + case RADIO_PARAM_TX_MODE: + if(value & ~(RADIO_TX_MODE_SEND_ON_CCA)) { + return RADIO_RESULT_INVALID_VALUE; + } + set_send_on_cca((value & RADIO_TX_MODE_SEND_ON_CCA) != 0); + return RADIO_RESULT_OK; + case RADIO_PARAM_TXPOWER: + if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) { + return RADIO_RESULT_INVALID_VALUE; + /* Find the closest higher PA_LEVEL for the desired output power */ + } + set_txpower(value); + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + cca_thershold = value; + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + if(param == RADIO_PARAM_LAST_PACKET_TIMESTAMP) { + if(size != sizeof(rtimer_clock_t) || !dest) { + return RADIO_RESULT_INVALID_VALUE; + } + *(rtimer_clock_t *)dest = get_packet_timestamp(); + + return RADIO_RESULT_OK; + } + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +const struct radio_driver micromac_radio_driver = { + init, + prepare, + transmit, + send, + read, + cca, + receiving_packet, + pending_packet, + on, + off, + get_value, + set_value, + get_object, + set_object +}; diff --git a/platform/jn516x/dev/micromac-radio.h b/platform/jn516x/dev/micromac-radio.h new file mode 100644 index 000000000..a283af23d --- /dev/null +++ b/platform/jn516x/dev/micromac-radio.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014, NXP and SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * MICROMAC_RADIO driver header file + * \authors + * Beshr Al Nahas + * Simon Duquennot + */ + +#ifndef MICROMAC_RADIO_H_ +#define MICROMAC_RADIO_H_ + +#include "dev/radio.h" + +extern const struct radio_driver micromac_radio_driver; + +#endif /* MICROMAC_RADIO_H_ */ diff --git a/platform/jn516x/dev/mtarch.c b/platform/jn516x/dev/mtarch.c new file mode 100644 index 000000000..c3c81457e --- /dev/null +++ b/platform/jn516x/dev/mtarch.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2008 + * Telecooperation Office (TecO), Universitaet Karlsruhe (TH), Germany. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Universitaet Karlsruhe (TH) 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 + * OWNER 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. + * + * Author(s): Philipp Scholl + */ + +/* Copied from Philipp Scholl's (BSD) Contiki port to Jennic */ + +#include "mtarch.h" + +void +mtarch_init(void) +{ +} +void +mtarch_remove(void) +{ +} +void +mtarch_start(struct mtarch_thread *thread, + void (*function)(void *data), + void *data) +{ +} +void +mtarch_yield(void) +{ +} +void +mtarch_exec(struct mtarch_thread *thread) +{ +} +void +mtarch_stop(struct mtarch_thread *thread) +{ +} +void +mtarch_pstart(void) +{ +} +void +mtarch_pstop(void) +{ +} diff --git a/platform/jn516x/dev/mtarch.h b/platform/jn516x/dev/mtarch.h new file mode 100644 index 000000000..3c6292f1d --- /dev/null +++ b/platform/jn516x/dev/mtarch.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2008 + * Telecooperation Office (TecO), Universitaet Karlsruhe (TH), Germany. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Universitaet Karlsruhe (TH) 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 + * OWNER 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. + * + * Author(s): Philipp Scholl + */ + +/* Copied from Philipp Scholl's (BSD) Contiki port to Jennic */ + +#ifndef __MTARCH_H__ +#define __MTARCH_H__ + +struct mtarch_thread { + void *mt_thread; +}; + +#endif /* __MTARCH_H__ */ diff --git a/examples/sensinode/disco/disco-example.c b/platform/jn516x/dev/node-id.c similarity index 80% rename from examples/sensinode/disco/disco-example.c rename to platform/jn516x/dev/node-id.c index 8f97a13fc..d0e95d521 100644 --- a/examples/sensinode/disco/disco-example.c +++ b/platform/jn516x/dev/node-id.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Loughborough University - Computer Science + * Copyright (c) 2014, SICS Swedish ICT. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,27 +27,35 @@ * SUCH DAMAGE. * * This file is part of the Contiki operating system. + * */ /** * \file - * Stub project source file. We just need to build contiki with - * OFFSET_FIRMWARE, Makefile does so. + * For compatibility with Contiki node-id interface * * \author - * George Oikonomou - + * Beshr Al Nahas */ #include "contiki.h" +#include "sys/node-id.h" +#include "contiki-conf.h" /*---------------------------------------------------------------------------*/ -PROCESS(stub_process, "Stub process"); -AUTOSTART_PROCESSES(&stub_process); +extern unsigned char node_mac[8]; +unsigned short node_id = 0; /*---------------------------------------------------------------------------*/ -PROCESS_THREAD(stub_process, ev, data) +void +node_id_restore(void) { - PROCESS_BEGIN(); - - PROCESS_END(); + /* base node-id on MAC address */ + node_id = (node_mac[6] << 8) | node_mac[7]; } /*---------------------------------------------------------------------------*/ +void +node_id_burn(unsigned short id) +{ + /* does not burn anything */ + node_id = id; +} diff --git a/platform/jn516x/dev/rtimer-arch-slow.c b/platform/jn516x/dev/rtimer-arch-slow.c new file mode 100644 index 000000000..588edc341 --- /dev/null +++ b/platform/jn516x/dev/rtimer-arch-slow.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * RTIMER for NXP jn516x: 32 kHz mode + * \author + * Atis Elsts + */ + +#include "sys/rtimer.h" +#include "sys/clock.h" +#include +#include +#include +#include "dev/watchdog.h" +#include "sys/energest.h" +#include "sys/process.h" + +#if RTIMER_USE_32KHZ + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#define RTIMER_TIMER_ISR_DEV E_AHI_DEVICE_SYSCTRL +/* 1.5 days wraparound time */ +#define MAX_VALUE 0xFFFFFFFF +/* make this small to more easily detect wraparound bugs */ +#define START_VALUE (60 * RTIMER_ARCH_SECOND) +#define WRAPAROUND_VALUE ((uint64_t)0x1FFFFFFFFFF) + +static volatile rtimer_clock_t scheduled_time; +static volatile uint8_t has_next; + +/*---------------------------------------------------------------------------*/ +static void +timerISR(uint32 u32Device, uint32 u32ItemBitmap) +{ + PRINTF("\ntimer isr %u %u\n", u32Device, u32ItemBitmap); + if(u32Device != RTIMER_TIMER_ISR_DEV) { + return; + } + + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + if(u32ItemBitmap & TICK_TIMER_MASK) { + /* 32-bit overflow happened; restart the timer */ + uint32_t ticks_late = WRAPAROUND_VALUE - u64AHI_WakeTimerReadLarge(TICK_TIMER); + + PRINTF("\nrtimer oflw, missed ticks %u\n", ticks_late); + + vAHI_WakeTimerStartLarge(TICK_TIMER, MAX_VALUE - ticks_late); + } + + if(u32ItemBitmap & WAKEUP_TIMER_MASK) { + PRINTF("\nrtimer fire @ %u\n", rtimer_arch_now()); + + /* Compare with the current time, as after sleep there is + * a fake interrupt generated 10ms earlier to wake up & reinitialize + * the system before the actual rtimer fires. + */ + rtimer_clock_t now = rtimer_arch_now(); + if(RTIMER_CLOCK_LT(now + 1, scheduled_time)) { + vAHI_WakeTimerEnable(WAKEUP_TIMER, TRUE); + vAHI_WakeTimerStartLarge(WAKEUP_TIMER, scheduled_time - now); + } else { + has_next = 0; + watchdog_start(); + rtimer_run_next(); + process_nevents(); + } + } + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +void +rtimer_arch_init(void) +{ + /* Initialise tick timer to run continuously */ + vAHI_TickTimerIntEnable(0); + vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_DISABLE); + vAHI_TickTimerWrite(0); + vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_CONT); + + vAHI_SysCtrlRegisterCallback(timerISR); + /* set the highest priority for the rtimer interrupt */ + vAHI_InterruptSetPriority(MICRO_ISR_MASK_SYSCTRL, 15); + /* enable interrupt on a rtimer */ + vAHI_WakeTimerEnable(WAKEUP_TIMER, TRUE); + /* enable interrupt on 32-bit overflow */ + vAHI_WakeTimerEnable(TICK_TIMER, TRUE); + /* count down from START_VALUE */ + vAHI_WakeTimerStartLarge(TICK_TIMER, START_VALUE); + + (void)u32AHI_Init(); +} +/*---------------------------------------------------------------------------*/ +void +rtimer_arch_reinit(rtimer_clock_t sleep_start, rtimer_clock_t sleep_ticks) +{ + uint64_t t; + + uint32_t wakeup_time = sleep_start + (uint64_t)sleep_ticks * (F_CPU / 2) / RTIMER_SECOND; + + /* Initialise tick timer to run continuously */ + vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_DISABLE); + vAHI_TickTimerIntEnable(0); + WAIT_FOR_EDGE(t); + vAHI_TickTimerWrite(wakeup_time); + vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_CONT); + + /* call pending interrupts */ + (void)u32AHI_Init(); + + if(has_next) { + /* reschedule the timer */ + rtimer_arch_schedule(scheduled_time); + } +} +/*---------------------------------------------------------------------------*/ +rtimer_clock_t +rtimer_arch_now(void) +{ + return START_VALUE - (rtimer_clock_t)u64AHI_WakeTimerReadLarge(TICK_TIMER); +} +/*---------------------------------------------------------------------------*/ +void +rtimer_arch_schedule(rtimer_clock_t t) +{ + PRINTF("rtimer_arch_schedule time %lu\n", t); + vAHI_WakeTimerEnable(WAKEUP_TIMER, TRUE); + vAHI_WakeTimerStartLarge(WAKEUP_TIMER, t - rtimer_arch_now()); + scheduled_time = t; + has_next = 1; +} +/*---------------------------------------------------------------------------*/ +rtimer_clock_t +rtimer_arch_time_to_rtimer(void) +{ + rtimer_clock_t now = RTIMER_NOW(); + if(has_next) { + return scheduled_time >= now ? scheduled_time - now : 0; + } + /* if no wakeup is scheduled yet return maximum time */ + return (rtimer_clock_t)-1; +} +/*---------------------------------------------------------------------------*/ +#endif /* RTIMER_USE_32KHZ */ diff --git a/platform/jn516x/dev/rtimer-arch.c b/platform/jn516x/dev/rtimer-arch.c new file mode 100644 index 000000000..f74fa3fd7 --- /dev/null +++ b/platform/jn516x/dev/rtimer-arch.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * RTIMER for NXP jn516x + * \author + * Beshr Al Nahas + * Atis Elsts + */ + +#include "sys/rtimer.h" +#include "sys/clock.h" +#include +#include +#include +#include "dev/watchdog.h" +#include "sys/energest.h" +#include "sys/process.h" + +#if !RTIMER_USE_32KHZ + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#define RTIMER_TIMER_ISR_DEV E_AHI_DEVICE_TICK_TIMER + +static volatile rtimer_clock_t scheduled_time; +static volatile uint8_t has_next; + +void +rtimer_arch_run_next(uint32 u32DeviceId, uint32 u32ItemBitmap) +{ + uint32_t delta; + + if(u32DeviceId != RTIMER_TIMER_ISR_DEV) { + return; + } + + ENERGEST_ON(ENERGEST_TYPE_IRQ); + vAHI_TickTimerIntPendClr(); + vAHI_TickTimerIntEnable(0); + /* + * compare register is only 28bits wide so make sure the upper 4bits match + * the set compare point + */ + delta = u32AHI_TickTimerRead() - scheduled_time; + if(delta >> 28 == 0) { + /* run scheduled */ + has_next = 0; + watchdog_start(); + rtimer_run_next(); + process_nevents(); + } else { + /* No match. Schedule again. */ + vAHI_TickTimerIntEnable(1); + vAHI_TickTimerInterval(scheduled_time); + } + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +void +rtimer_arch_init(void) +{ + /* Initialise tick timer to run continuously */ + vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_DISABLE); + vAHI_TickTimerIntEnable(0); + vAHI_TickTimerRegisterCallback(rtimer_arch_run_next); + vAHI_TickTimerWrite(0); + vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_CONT); + + /* enable wakeup timers, but keep interrupts disabled */ + vAHI_WakeTimerEnable(WAKEUP_TIMER, FALSE); + vAHI_WakeTimerEnable(TICK_TIMER, FALSE); + /* count down from zero (2, as values 0 and 1 must not be used) */ + vAHI_WakeTimerStartLarge(TICK_TIMER, 2); + + (void)u32AHI_Init(); +} +/*---------------------------------------------------------------------------*/ +void +rtimer_arch_reinit(rtimer_clock_t sleep_start, rtimer_clock_t sleep_ticks) +{ + uint64_t t; + /* Initialise tick timer to run continuously */ + vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_DISABLE); + vAHI_TickTimerIntEnable(0); + /* set the highest priority for the rtimer interrupt */ + vAHI_InterruptSetPriority(MICRO_ISR_MASK_TICK_TMR, 15); + vAHI_TickTimerRegisterCallback(rtimer_arch_run_next); + WAIT_FOR_EDGE(t); + vAHI_TickTimerWrite(sleep_start + sleep_ticks); + vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_CONT); + + /* call pending interrupts */ + u32AHI_Init(); + + if(has_next) { + vAHI_TickTimerIntPendClr(); + vAHI_TickTimerIntEnable(1); + vAHI_TickTimerInterval(scheduled_time); + } +} +/*---------------------------------------------------------------------------*/ +rtimer_clock_t +rtimer_arch_now(void) +{ + return u32AHI_TickTimerRead(); +} +/*---------------------------------------------------------------------------*/ +void +rtimer_arch_schedule(rtimer_clock_t t) +{ + PRINTF("rtimer_arch_schedule time %lu\n", t); + vAHI_TickTimerIntPendClr(); + vAHI_TickTimerIntEnable(1); + vAHI_TickTimerInterval(t); + has_next = 1; + scheduled_time = t; +} +/*---------------------------------------------------------------------------*/ +rtimer_clock_t +rtimer_arch_time_to_rtimer(void) +{ + rtimer_clock_t now = RTIMER_NOW(); + if(has_next) { + return scheduled_time >= now ? scheduled_time - now : 0; + } + /* if no wakeup is scheduled yet return maximum time */ + return (rtimer_clock_t)-1; +} +/*---------------------------------------------------------------------------*/ +#endif /* !RTIMER_USE_32KHZ */ diff --git a/platform/jn516x/dev/rtimer-arch.h b/platform/jn516x/dev/rtimer-arch.h new file mode 100644 index 000000000..3ffafeeac --- /dev/null +++ b/platform/jn516x/dev/rtimer-arch.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Header file for NXP jn516x-specific rtimer code + * \author + * Beshr Al Nahas + * Atis Elsts + */ + +#ifndef RTIMER_ARCH_H_ +#define RTIMER_ARCH_H_ + +#include "sys/rtimer.h" + +#ifdef RTIMER_CONF_SECOND +# define RTIMER_ARCH_SECOND RTIMER_CONF_SECOND +#else +#if RTIMER_USE_32KHZ +# if JN516X_EXTERNAL_CRYSTAL_OSCILLATOR +# define RTIMER_ARCH_SECOND 32768 +# else +# define RTIMER_ARCH_SECOND 32000 +#endif +#else +/* 32MHz CPU clock => 16MHz timer */ +# define RTIMER_ARCH_SECOND (F_CPU / 2) +#endif +#endif + +#if RTIMER_USE_32KHZ +#define US_TO_RTIMERTICKS(US) ((US) >= 0 ? \ + (((int32_t)(US) * (RTIMER_ARCH_SECOND) + 500000) / 1000000L) : \ + ((int32_t)(US) * (RTIMER_ARCH_SECOND) - 500000) / 1000000L) + +#define RTIMERTICKS_TO_US(T) ((T) >= 0 ? \ + (((int32_t)(T) * 1000000L + ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND)) : \ + ((int32_t)(T) * 1000000L - ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND)) + +/* A 64-bit version because the 32-bit one cannot handle T >= 4295 ticks. + Intended only for positive values of T. */ +#define RTIMERTICKS_TO_US_64(T) ((uint32_t)(((uint64_t)(T) * 1000000 + ((RTIMER_ARCH_SECOND) / 2)) / (RTIMER_ARCH_SECOND))) + +#else + +#define US_TO_RTIMERTICKS(D) ((int64_t)(D) << 4) +#define RTIMERTICKS_TO_US(T) ((int64_t)(T) >> 4) +#define RTIMERTICKS_TO_US_64(T) RTIMERTICKS_TO_US(T) + +#endif + +rtimer_clock_t rtimer_arch_now(void); + +rtimer_clock_t rtimer_arch_time_to_rtimer(void); + +void rtimer_arch_reinit(rtimer_clock_t sleep_start, rtimer_clock_t wakeup_time); + +void clock_arch_init(int is_reinitialization); + +void clock_arch_calibrate(void); + +void clock_arch_reinit(void); + +void clock_arch_schedule_interrupt(clock_time_t time_to_etimer, rtimer_clock_t ticks_to_rtimer); + +clock_t clock_arch_time_to_etimer(void); + +/* Use 20 ms: enough for TSCH with the default schedule to sleep */ +#define JN516X_MIN_SLEEP_TIME (RTIMER_SECOND / 50) +/* 1 second by default: arbitrary picked value which could be increased */ +#define JN516X_MAX_SLEEP_TIME RTIMER_SECOND +/* Assume conservative 10 ms maximal system wakeup time */ +#define JN516X_SLEEP_GUARD_TIME (RTIMER_ARCH_SECOND / 100) + +#define WAKEUP_TIMER E_AHI_WAKE_TIMER_0 +#define WAKEUP_TIMER_MASK E_AHI_SYSCTRL_WK0_MASK + +#define TICK_TIMER E_AHI_WAKE_TIMER_1 +#define TICK_TIMER_MASK E_AHI_SYSCTRL_WK1_MASK + +#define WAIT_FOR_EDGE(edge_t) do { \ + uint64_t start_t = u64AHI_WakeTimerReadLarge(TICK_TIMER); \ + do { \ + edge_t = u64AHI_WakeTimerReadLarge(TICK_TIMER); \ + } while(edge_t == start_t); \ + } while(0) + +#endif /* RTIMER_ARCH_H_ */ diff --git a/platform/sensinode/dev/slip-arch.c b/platform/jn516x/dev/slip_uart0.c similarity index 87% rename from platform/sensinode/dev/slip-arch.c rename to platform/jn516x/dev/slip_uart0.c index 422847cf9..a02791de2 100644 --- a/platform/sensinode/dev/slip-arch.c +++ b/platform/jn516x/dev/slip_uart0.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Swedish Institute of Computer Science + * Copyright (c) 2014, SICS Swedish ICT. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,21 +29,26 @@ */ /* - * Sensinode/cc2430 SLIP routines (over UART1). + * Machine dependent jn516x SLIP routines for UART0. */ +#include "contiki-conf.h" #include "dev/slip.h" -#include "dev/uart1.h" +#include "dev/uart0.h" /*---------------------------------------------------------------------------*/ void slip_arch_writeb(unsigned char c) { - uart1_writeb(c); + uart0_writeb(c); } /*---------------------------------------------------------------------------*/ +/** + * Initalize the RS232 port and the SLIP driver. + * + */ void slip_arch_init(unsigned long ubr) { - uart1_set_input(slip_input_byte); + uart0_set_input(slip_input_byte); } /*---------------------------------------------------------------------------*/ diff --git a/platform/jn516x/dev/uart-driver.c b/platform/jn516x/dev/uart-driver.c new file mode 100644 index 000000000..8719004a7 --- /dev/null +++ b/platform/jn516x/dev/uart-driver.c @@ -0,0 +1,612 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Lee Mitchell + * Integrated into Contiki by Beshr Al Nahas + * + */ + +#include + +#ifdef DEBUG +#include +#else +#define DBG_vPrintf(...) +#endif + +#include "contiki-conf.h" +#include "uart-driver.h" +#include "sys/rtimer.h" +#include "watchdog.h" +#include +#include + +#if UART_XONXOFF_FLOW_CTRL + +#include "sys/process.h" + +#define TX_FIFO_SW_FLOW_LIMIT 8 /* Maximum allowed fill level for tx fifo */ +#if TX_FIFO_SW_FLOW_LIMIT > 16 +#undef TX_FIFO_SW_FLOW_LIMIT +#define TX_FIFO_SW_FLOW_LIMIT 16 +#warning "TX_FIFO_SW_FLOW_LIMIT too big. Forced to 16." +#endif /* TX_FIFO_SW_FLOW_LIMIT > 16 */ + +#define XON 17 +#define XOFF 19 + +extern volatile unsigned char xonxoff_state; + +#endif /* UART_XONXOFF_FLOW_CTRL */ + +/*** Macro Definitions ***/ +#define BUSYWAIT_UNTIL(cond, max_time) \ + do { \ + rtimer_clock_t t0; \ + t0 = RTIMER_NOW(); \ + while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))) ; \ + } while(0) + +#define DEBUG_UART_BUFFERED FALSE + +#define CHAR_DEADLINE (uart_char_delay * 100) + +/*** Local Function Prototypes ***/ +static void uart_driver_isr(uint32_t device_id, uint32_t item_bitmap); +#if !UART_XONXOFF_FLOW_CTRL +static int16_t uart_driver_get_tx_fifo_available_space(uint8_t uart_dev); +#endif /* !UART_XONXOFF_FLOW_CTRL */ +static void uart_driver_set_baudrate(uint8_t uart_dev, uint8_t br); +static void uart_driver_set_high_baudrate(uint8_t uart_dev, uint32_t baud_rate); + +/*** Local Variables ***/ +#define UART_NUM_UARTS 2 +static uint16_t tx_fifo_size[UART_NUM_UARTS] = { 0 }; +static uint8_t active_uarts[UART_NUM_UARTS] = { 0 }; +/** slip input function pointer */ +static int(*uart_input[UART_NUM_UARTS]) (unsigned char) = { 0 }; +/* time in uSec for transmitting 1 char */ +static uint16_t uart_char_delay = 0; +static volatile int8_t interrupt_enabled[UART_NUM_UARTS] = { 0 }; +static volatile int8_t interrupt_enabled_saved[UART_NUM_UARTS] = { 0 }; + +/**************************************************************************** + * + * NAME: uart_driver_init + * + * DESCRIPTION: + * Initializes the specified UART device. + * + * PARAMETERS: Name RW Usage + * uart_dev R UART to initialise, eg, E_AHI_UART_0 + * br R Baudrate to use (e.g. UART_RATE_115200) + * if br > UART_RATE_115200 + * then uart_driver_set_baud_rate is called + * else vAHI_UartSetClockDivisor + * txbuf_data R Pointer to a memory block to use + * and rxbuf_data as uart tx/rx fifo + * txbuf_size R size of tx fifo (valid range: 16-2047) + * txbuf_size R size of rx fifo (valid range: 16-2047) + * uart_input_function a function pointer to input uart rx bytes + * RETURNS: + * void + * + ****************************************************************************/ +void +uart_driver_init(uint8_t uart_dev, uint8_t br, uint8_t *txbuf_data, + uint16_t txbuf_size, uint8_t *rxbuf_data, uint16_t rxbuf_size, + int (*uart_input_function)(unsigned char c)) +{ +#if !UART_HW_FLOW_CTRL + /* Disable RTS/CTS */ + vAHI_UartSetRTSCTS(uart_dev, FALSE); +#endif + + tx_fifo_size[uart_dev] = txbuf_size; + + /* Configure the selected Uart */ + uint8_t uart_enabled = bAHI_UartEnable(uart_dev, txbuf_data, txbuf_size, + rxbuf_data, rxbuf_size); + /* fallback to internal buffers */ + if(!uart_enabled) { + vAHI_UartEnable(uart_dev); + tx_fifo_size[uart_dev] = 16; /* Fixed size */ + } + /* Reset tx/rx fifos */ + vAHI_UartReset(uart_dev, TRUE, TRUE); + vAHI_UartReset(uart_dev, FALSE, FALSE); + + uart_driver_set_baudrate(uart_dev, br); + + /* install interrupt service callback */ + if(uart_dev == E_AHI_UART_0) { + vAHI_Uart0RegisterCallback((void *)uart_driver_isr); + } else { + vAHI_Uart1RegisterCallback((void *)uart_driver_isr); + /* Enable RX interrupt */ + } + uart_driver_enable_interrupts(uart_dev); + uart_input[uart_dev] = uart_input_function; + active_uarts[uart_dev] = 1; + +#if UART_HW_FLOW_CTRL + /* Configure HW flow control */ + vAHI_UartSetAutoFlowCtrl(uart_dev, E_AHI_UART_FIFO_ARTS_LEVEL_13, /* uint8 const u8RxFifoLevel,*/ + FALSE, /* bool_t const bFlowCtrlPolarity,*/ + TRUE, /* bool_t const bAutoRts, */ + TRUE /* bool_t const bAutoCts */); +#endif + + DBG_vPrintf("UART %d init: using %s buffers %d\n", uart_dev, + uart_enabled ? "external" : "internal", tx_fifo_size[uart_dev]); +} +void +uart_driver_enable_interrupts(uint8_t uart_dev) +{ + /* wait while char being tx is done */ + while((u8AHI_UartReadLineStatus(uart_dev) & E_AHI_UART_LS_THRE) == 0) ; + + vAHI_UartSetInterrupt(uart_dev, FALSE /*bEnableModemStatus*/, + FALSE /*bEnableRxLineStatus == Break condition */, + FALSE /*bEnableTxFifoEmpty*/, + TRUE /* bEnableRxData */, E_AHI_UART_FIFO_LEVEL_14); + interrupt_enabled[uart_dev] = 1; +} +void +uart_driver_disable_interrupts(uint8_t uart_dev) +{ + /* wait while char being tx is done */ + while((u8AHI_UartReadLineStatus(uart_dev) & E_AHI_UART_LS_THRE) == 0) ; + + vAHI_UartSetInterrupt(uart_dev, FALSE /*bEnableModemStatus*/, + FALSE /*bEnableRxLineStatus == Break condition */, + FALSE /*bEnableTxFifoEmpty*/, + FALSE /* bEnableRxData */, E_AHI_UART_FIFO_LEVEL_14); + interrupt_enabled[uart_dev] = 0; +} +void +uart_driver_store_interrupts(uint8_t uart_dev) +{ + interrupt_enabled_saved[uart_dev] = interrupt_enabled[uart_dev]; +} +void +uart_driver_restore_interrupts(uint8_t uart_dev) +{ + if(interrupt_enabled_saved[uart_dev]) { + uart_driver_enable_interrupts(uart_dev); + } else { + uart_driver_disable_interrupts(uart_dev); + } +} +int8_t +uart_driver_interrupt_is_enabled(uint8_t uart_dev) +{ + return interrupt_enabled[uart_dev]; +} +void +uart_driver_set_input(uint8_t uart_dev, int + (*uart_input_function)(unsigned char c)) +{ + uart_input[uart_dev] = uart_input_function; +} +/**************************************************************************** + * + * NAME: uart_driver_read + * + * DESCRIPTION: + * Reads 1 byte from the RX buffer. If there is no data in the + * buffer, then return FALSE + * + * PARAMETERS: Name RW Usage + * uart_dev R UART to use, eg, E_AHI_UART_0 + * + * RETURNS: + * TRUE if a byte has been read from the queue + * + ****************************************************************************/ +uint8_t +uart_driver_read(uint8_t uart_dev, uint8_t *data) +{ + if(data && u16AHI_UartReadRxFifoLevel(uart_dev) > 0) { + *data = u8AHI_UartReadData(uart_dev); + return TRUE; + } + return FALSE; +} +void +uart_driver_write_buffered(uint8_t uart_dev, uint8_t ch) +{ + uart_driver_write_with_deadline(uart_dev, ch); +} +/**************************************************************************** + * + * NAME: uart_driver_write_with_deadline + * + * DESCRIPTION: + * Writes one byte to the specified uart for transmission + * + * PARAMETERS: Name RW Usage + * uart_dev R UART to use, eg, E_AHI_UART_0 + * ch R data to transmit + * + * RETURNS: + * void + * + ****************************************************************************/ +void +uart_driver_write_with_deadline(uint8_t uart_dev, uint8_t ch) +{ +#if UART_XONXOFF_FLOW_CTRL + /* Block until host can receive data */ + /* Wait until there are less than N characters in TX FIFO */ + while(xonxoff_state != XON + || u16AHI_UartReadTxFifoLevel(uart_dev) > TX_FIFO_SW_FLOW_LIMIT) { + watchdog_periodic(); + } + /* write to TX FIFO and return immediately */ + vAHI_UartWriteData(uart_dev, ch); +#else /* UART_XONXOFF_FLOW_CTRL */ + volatile int16_t write = 0; + watchdog_periodic(); + /* wait until there is space in tx fifo */ + BUSYWAIT_UNTIL(write = (uart_driver_get_tx_fifo_available_space(uart_dev) > 0), + CHAR_DEADLINE); + /* write only if there is space so we do not get stuck */ + if(write) { + /* write to TX FIFO and return immediately */ + vAHI_UartWriteData(uart_dev, ch); + } +#endif /* UART_XONXOFF_FLOW_CTRL */ +} +void +uart_driver_write_direct(uint8_t uart_dev, uint8_t ch) +{ + /* Write character */ + vAHI_UartWriteData(uart_dev, ch); + /* Wait for buffers to empty */ + while((u8AHI_UartReadLineStatus(uart_dev) & E_AHI_UART_LS_THRE) == 0) ; + while((u8AHI_UartReadLineStatus(uart_dev) & E_AHI_UART_LS_TEMT) == 0) ; +} +/**************************************************************************** + * + * NAME: uart_driver_rx_handler + * + * DESCRIPTION: + * Interrupt service callback for UART data reception. Reads a received + * byte from the UART and writes it to the reception buffer if it is not + * full. + * + * PARAMETERS: Name RW Usage + * uart_dev R Uart to read from + * + * RETURNS: + * void + * + ****************************************************************************/ +void +uart_driver_rx_handler(uint8_t uart_dev) +{ + /* optimization for high throughput: Read upto 32 bytes from RX fifo. + * Disabled because it does not work with current slip_input_byte */ + + /* Status from uart_input: + * 0 means do not exit power saving mode + * -1 means RX buffer overflow ==> stop reading + * 1 means end of slip packet + */ +#if UART_XONXOFF_FLOW_CTRL + /* save old status */ + int xonxoff_state_old = xonxoff_state; +#endif /* UART_XONXOFF_FLOW_CTRL */ + int status = 0; + int c = 0; + while(u16AHI_UartReadRxFifoLevel(uart_dev) > 0 && c++ < 32 && status == 0) { + if(uart_input[uart_dev] != NULL) { /* read one char at a time */ + + /* process received character */ + status = (uart_input[uart_dev])(u8AHI_UartReadData(uart_dev)); + +#if UART_XONXOFF_FLOW_CTRL + /* Process XON-XOFF*/ + if(xonxoff_state == XOFF) { + /* XXX do not set break condition as it corrupts one character, instead we block on TX */ + /* Instruct uart to stop TX */ + /* vAHI_UartSetBreak(uart_dev, TRUE); */ + break; + } else if(xonxoff_state_old == XOFF && xonxoff_state == XON) { + /* Instruct uart to resume TX if it was stopped */ + /* vAHI_UartSetBreak(uart_dev, FALSE); */ + } +#endif /* UART_XONXOFF_FLOW_CTRL */ + } else { + /* no input handler, or no bytes to read: Discard byte. */ + u8AHI_UartReadData(uart_dev); + } + } +} +/****************************************************************************/ +/*** Local Functions ***/ +/****************************************************************************/ + +#if !UART_XONXOFF_FLOW_CTRL +/* Returns the free space in tx fifo, i.e., how many characters we can put */ +static int16_t +uart_driver_get_tx_fifo_available_space(uint8_t uart_dev) +{ + return tx_fifo_size[uart_dev] - u16AHI_UartReadTxFifoLevel(uart_dev); +} +#endif /* !UART_XONXOFF_FLOW_CTRL */ +/* Initializes the specified UART with auto-selection of + baudrate tuning method */ +static void +uart_driver_set_baudrate(uint8_t uart_dev, uint8_t br) +{ + uint32_t high_br = 0; + uint8_t low_br = 0; + + switch(br) { + case UART_RATE_4800: + low_br = E_AHI_UART_RATE_4800; + uart_char_delay = 1667; + break; + case UART_RATE_9600: + low_br = E_AHI_UART_RATE_9600; + uart_char_delay = 834; + break; + case UART_RATE_19200: + low_br = E_AHI_UART_RATE_19200; + uart_char_delay = 417; + break; + case UART_RATE_38400: + low_br = E_AHI_UART_RATE_38400; + uart_char_delay = 209; + break; + case UART_RATE_76800: + low_br = E_AHI_UART_RATE_76800; + uart_char_delay = 105; + break; + case UART_RATE_115200: + low_br = E_AHI_UART_RATE_115200; + uart_char_delay = 69; + break; + case UART_RATE_230400: + high_br = 230400UL; + uart_char_delay = 35; + break; + case UART_RATE_460800: + high_br = 460800UL; + uart_char_delay = 18; + break; + case UART_RATE_500000: + high_br = 500000UL; + uart_char_delay = 16; + break; + case UART_RATE_576000: + high_br = 576000UL; + uart_char_delay = 14; + break; + case UART_RATE_921600: + high_br = 921600UL; + uart_char_delay = 9; + break; + case UART_RATE_1000000: + high_br = 1000000UL; + uart_char_delay = 8; + break; + default: + high_br = 1000000UL; + uart_char_delay = 8; + break; + } + if(high_br == 0) { + vAHI_UartSetClockDivisor(uart_dev, low_br); + } else { + uart_driver_set_high_baudrate(uart_dev, high_br); + } +} +/**************************************************************************** + * + * NAME: uart_driver_set_high_baudrate + * + * DESCRIPTION: + * Sets the baud rate for the specified uart + * + * PARAMETERS: Name RW Usage + * uart_dev R UART to initialise, eg, E_AHI_UART_0 + * baud_rate R Baudrate to use (bps eg 921600) + * + * RETURNS: + * void + * + ****************************************************************************/ +static void +uart_driver_set_high_baudrate(uint8_t uart_dev, uint32_t baud_rate) +{ + uint16 u16Divisor = 1; + uint32_t u32Remainder; + uint8_t u8ClocksPerBit = 16; + +#if (ENABLE_ADVANCED_BAUD_SELECTION) + /* Defining ENABLE_ADVANCED_BAUD_SELECTION in the Makefile + * enables this code which searches for a clocks per bit setting + * that gets closest to the configured rate. + */ + uint32_t u32CalcBaudRate = 0; + int32 i32BaudError = 0x7FFFFFFF; + + DBG_vPrintf(DEBUG_UART_BUFFERED, "Config uart=%d, baud=%d\n", uart_dev, + baud_rate); + + while(ABS(i32BaudError) > (int32)(baud_rate >> 4)) { /* 6.25% (100/16) error */ + if(--u8ClocksPerBit < 3) { + DBG_vPrintf(DEBUG_UART_BUFFERED, + "Could not calculate UART settings for target baud!"); + return; + } +#endif /* ENABLE_ADVANCED_BAUD_SELECTION */ + + /* Calculate Divisor register = 16MHz / (16 x baud rate) */ + u16Divisor = (uint16)(16000000UL / ((u8ClocksPerBit + 1) * baud_rate)); + + /* Correct for rounding errors */ + u32Remainder = + (uint32_t)(16000000UL % ((u8ClocksPerBit + 1) * baud_rate)); + + if(u32Remainder >= (((u8ClocksPerBit + 1) * baud_rate) / 2)) { + u16Divisor += 1; + } +#if (ENABLE_ADVANCED_BAUD_SELECTION) + DBG_vPrintf(DEBUG_UART_BUFFERED, "Divisor=%d, cpb=%d\n", u16Divisor, + u8ClocksPerBit); + + u32CalcBaudRate = (16000000UL / ((u8ClocksPerBit + 1) * u16Divisor)); + + DBG_vPrintf(DEBUG_UART_BUFFERED, "Calculated baud=%d\n", u32CalcBaudRate); + + i32BaudError = (int32)u32CalcBaudRate - (int32)baud_rate; + + DBG_vPrintf(DEBUG_UART_BUFFERED, "Error baud=%d\n", i32BaudError); +} +DBG_vPrintf(DEBUG_UART_BUFFERED, "Config uart=%d: Divisor=%d, cpb=%d\n", + uart_dev, u16Divisor, u8ClocksPerBit); + +/* Set the calculated clocks per bit */ +vAHI_UartSetClocksPerBit(uart_dev, u8ClocksPerBit); +#endif /* ENABLE_ADVANCED_BAUD_SELECTION */ + + /* Set the calculated divisor */ + vAHI_UartSetBaudDivisor(uart_dev, u16Divisor); +} + +/**************************************************************************** + * + * NAME: uart_driver_isr + * + * DESCRIPTION: + * Interrupt service callback for UART's + * + * PARAMETERS: Name RW Usage + * device_id R Device ID of whatever generated the + * interrupt + * item_bitmap R Which part of the device generated + * the interrupt + * + * RETURNS: + * void + * + ****************************************************************************/ +static void +uart_driver_isr(uint32_t device_id, uint32_t item_bitmap) +{ + uint8_t uart_dev; + switch(device_id) { + case E_AHI_DEVICE_UART0: + uart_dev = E_AHI_UART_0; + break; + case E_AHI_DEVICE_UART1: + uart_dev = E_AHI_UART_1; + break; + default: + return; + } + switch(item_bitmap) { + /* byte available since a long time but RX-fifo not full: */ + case E_AHI_UART_INT_TIMEOUT: + /* RX-fifo full: */ + case E_AHI_UART_INT_RXDATA: + uart_driver_rx_handler(uart_dev); + break; + case E_AHI_UART_INT_TX: + break; + case E_AHI_UART_INT_RXLINE: + /* rx-line interrupt is disabled. Should not get here */ + /* An error condition has occurred on the RxD line, such as + a break indication, framing error, parity error or over-run. */ + break; + } +} +/**************************************************************************** + * + * NAME: uart_driver_tx_in_progress + * + * DESCRIPTION: + * Returns the state of data transmission + * + * PARAMETERS: Name RW Usage + * uart_dev R UART to use, eg, E_AHI_UART_0 + * + * RETURNS: + * uint8_t: TRUE if data in buffer is being transmitted + * FALSE if all data in buffer has been transmitted by the UART + * + ****************************************************************************/ +uint8_t +uart_driver_tx_in_progress(uint8_t uart_dev) +{ + + if(u16AHI_UartReadTxFifoLevel(uart_dev) == 0) { + if((u8AHI_UartReadLineStatus(uart_dev) & E_AHI_UART_LS_TEMT) != 0) { + return FALSE; + } + } + return TRUE; +} +#ifdef UART_EXTRAS + +/**************************************************************************** + * + * NAME: uart_driver_flush + * + * DESCRIPTION: + * Flushes the buffers of the specified UART + * + * PARAMETERS: Name RW Usage + * uart_dev R UART to disable, eg, E_AHI_UART_0 + * reset_tx R to reset the transmit FIFO + * reset_rx R to reset the receive FIFO + * + * RETURNS: + * void + * + ****************************************************************************/ +void +uart_driver_flush(uint8_t uart_dev, bool_t reset_tx, bool_t reset_rx) +{ + /* Disable TX Fifo empty and Rx data interrupts */ + uart_driver_disable_interrupts(uart_dev); + + /* flush hardware buffer */ + vAHI_UartReset(uart_dev, reset_tx, reset_rx); + vAHI_UartReset(uart_dev, FALSE, FALSE); + + /* Re-enable TX Fifo empty and Rx data interrupts */ + uart_driver_enable_interrupts(uart_dev); +} +#endif /* UART_EXTRAS */ diff --git a/platform/jn516x/dev/uart-driver.h b/platform/jn516x/dev/uart-driver.h new file mode 100644 index 000000000..6ac0c2614 --- /dev/null +++ b/platform/jn516x/dev/uart-driver.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2015 NXP B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. + * + * This file is part of the Contiki operating system. + * + * Author: Lee Mitchell + * Integrated into Contiki by Beshr Al Nahas + * + */ + +#ifndef UARTDRIVER_H +#define UARTDRIVER_H + +#include +#include "contiki-conf.h" + +#define UART_EXTRAS 1 + +void uart_driver_init(uint8_t uart_dev, uint8_t br, uint8_t * txbuf_data, uint16_t txbuf_size, uint8_t * rxbuf_data, uint16_t rxbuf_size, int (*uart_input_function)(unsigned char c)); +void uart_driver_write_buffered(uint8_t uart_dev, uint8_t ch); +void uart_driver_write_with_deadline(uint8_t uart_dev, uint8_t c); +uint8_t uart_driver_read(uint8_t uart_dev, uint8_t *data); +void uart_driver_write_direct(uint8_t uart_dev, uint8_t ch); +void uart_driver_set_input(uint8_t u8Uart, int (*uart_input_function)(unsigned char c)); + +void uart_driver_rx_handler(uint8_t uart_dev); +void uart_driver_enable_interrupts(uint8_t uart_dev); +void uart_driver_disable_interrupts(uint8_t uart_dev); +int8_t uart_driver_interrupt_is_enabled(uint8_t uart_dev); +void uart_driver_store_interrupts(uint8_t uart_dev); +void uart_driver_restore_interrupts(uint8_t uart_dev); + +uint8_t uart_driver_tx_in_progress(uint8_t uart_dev); + +#ifdef UART_EXTRAS +void uart_driver_flush(uint8_t uart_dev, bool_t reset_tx, bool_t reset_rx); +#endif + +#endif /* UARTDRIVER_H */ diff --git a/platform/jn516x/dev/uart0.c b/platform/jn516x/dev/uart0.c new file mode 100644 index 000000000..58432abcc --- /dev/null +++ b/platform/jn516x/dev/uart0.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * UART0 drivers + * \author + * Beshr Al Nahas + * + */ + +#include +#include +#include +#include "contiki-conf.h" +#include "dev/uart0.h" +#include "uart-driver.h" + +/* Valid range for TXBUFSIZE and RXBUFSIZE: 16-2047 */ + +static unsigned char txbuf_data[UART_TX_BUFFER_SIZE]; +static unsigned char rxbuf_data[UART_RX_BUFFER_SIZE]; +static int (*uart0_input)(unsigned char c); + +uint8_t +uart0_active(void) +{ + return uart_driver_tx_in_progress(E_AHI_UART_0); +} +void +uart0_set_input(int + (*input)(unsigned char c)) +{ + uart0_input = input; + uart_driver_set_input(E_AHI_UART_0, uart0_input); +} +void +uart0_writeb(unsigned char c) +{ + uart_driver_write_buffered(E_AHI_UART_0, c); +} +void +uart0_init(uint8_t br) +{ + uart_driver_init(E_AHI_UART_0, br, txbuf_data, UART_TX_BUFFER_SIZE, rxbuf_data, UART_RX_BUFFER_SIZE, uart0_input); +} diff --git a/cpu/cc2430/dev/watchdog-cc2430.h b/platform/jn516x/dev/uart0.h similarity index 58% rename from cpu/cc2430/dev/watchdog-cc2430.h rename to platform/jn516x/dev/uart0.h index 8ea81fa2c..6f93f7147 100644 --- a/cpu/cc2430/dev/watchdog-cc2430.h +++ b/platform/jn516x/dev/uart0.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Loughborough University - Computer Science + * Copyright (c) 2014, SICS Swedish ICT. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,46 +27,50 @@ * SUCH DAMAGE. * * This file is part of the Contiki operating system. + * */ /** * \file - * Hardware-dependent header file for the cc2430 watchdog timer. - * - * The interrupt service routine's prototype must be included by the - * file containing main(). - * + * UART0 drivers * \author - * George Oikonomou - + * Beshr Al Nahas + * */ -#ifndef WATCHDOG_CC2430_H_ -#define WATCHDOG_CC2430_H_ +#ifndef __UART0_H__ +#define __UART0_H__ -#include "dev/watchdog.h" -#include "cc2430_sfr.h" +#include #include "contiki-conf.h" +#include "uart-driver.h" -#define WDT_TIMEOUT_1_SEC 0x00 -#define WDT_TIMEOUT_250_MSEC WDT_INT0 -#define WDT_TIMEOUT_15_MSEC WDT_INT1 -#define WDT_TIMEOUT_2_MSEC WDT_INT1 | WDT_INT0 - -#if WDT_CONF_TIMER_MODE -#define WDT_TIMER_MODE WDT_MODE /* Timer */ +#define UART_DEFAULT_RX_BUFFER_SIZE 2047 +#if UART_XONXOFF_FLOW_CTRL +#define UART_DEFAULT_TX_BUFFER_SIZE 64 #else -#define WDT_TIMER_MODE 0x00 /* Watchdog */ +#define UART_DEFAULT_TX_BUFFER_SIZE 1281 #endif - -#ifdef WDT_CONF_INTERVAL -#define WDT_INTERVAL WDT_CONF_INTERVAL +#ifdef UART_CONF_TX_BUFFER_SIZE +#define UART_TX_BUFFER_SIZE UART_CONF_TX_BUFFER_SIZE #else -#define WDT_INTERVAL WDT_TIMEOUT_1_SEC /* 2 secs */ +#define UART_TX_BUFFER_SIZE UART_DEFAULT_TX_BUFFER_SIZE #endif - -/* The watchdog only throws interrupts in timer mode */ -#if WDT_TIMER_MODE -void cc4230_watchdog_ISR(void) __interrupt (WDT_VECTOR); +#ifdef UART_CONF_RX_BUFFER_SIZE +#define UART_RX_BUFFER_SIZE UART_CONF_RX_BUFFER_SIZE +#else +#define UART_RX_BUFFER_SIZE UART_DEFAULT_RX_BUFFER_SIZE #endif +void uart0_set_input(int (*input)(unsigned char c)); +void uart0_writeb(unsigned char c); +void uart0_init(unsigned char br); -#endif /* WATCHDOG_CC2430_H_ */ +#define uart0_write_direct(c) uart_driver_write_direct(E_AHI_UART_0, (c)) +#define uart0_disable_interrupts() uart_driver_disable_interrupts(E_AHI_UART_0) +#define uart0_enable_interrupts() uart_driver_enable_interrupts(E_AHI_UART_0) +#define uart0_restore_interrupts() uart_driver_restore_interrupts(E_AHI_UART_0) +#define uart0_store_interrupts() uart_driver_store_interrupts(E_AHI_UART_0) + +uint8_t uart0_active(void); + +#endif diff --git a/platform/jn516x/dev/uart1.c b/platform/jn516x/dev/uart1.c new file mode 100644 index 000000000..7f4c1fa8f --- /dev/null +++ b/platform/jn516x/dev/uart1.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * UART1 drivers + * \author + * Beshr Al Nahas + * + */ + +#include +#include +#include +#include "contiki-conf.h" +#include "dev/uart1.h" +#include "uart-driver.h" + +static unsigned char txbuf_data[UART1_TX_BUFFER_SIZE]; +static unsigned char rxbuf_data[UART1_RX_BUFFER_SIZE]; +static int (*uart1_input)(unsigned char c); + +uint8_t +uart1_active(void) +{ + return uart_driver_tx_in_progress(E_AHI_UART_1); +} +void +uart1_set_input(int + (*input)(unsigned char c)) +{ + uart1_input = input; + uart_driver_set_input(E_AHI_UART_1, uart1_input); +} +void +uart1_writeb(unsigned char c) +{ + uart_driver_write_buffered(E_AHI_UART_1, c); +} +void +uart1_init(uint8_t br) +{ + uart_driver_init(E_AHI_UART_1, br, txbuf_data, UART1_TX_BUFFER_SIZE, rxbuf_data, UART1_RX_BUFFER_SIZE, uart1_input); +} diff --git a/platform/jn516x/dev/uart1.h b/platform/jn516x/dev/uart1.h new file mode 100644 index 000000000..2fdc207ca --- /dev/null +++ b/platform/jn516x/dev/uart1.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * UART1 drivers + * \author + * Beshr Al Nahas + * + */ + +#ifndef __UART1_H__ +#define __UART1_H__ + +#include +#include "contiki-conf.h" + +/* Default buffer size + Valid range for TX_BUFFER_SIZE and RX_BUFFER_SIZE: 16-2047 */ +#define UART1_DEFAULT_RX_BUFFER_SIZE 16 +#define UART1_DEFAULT_TX_BUFFER_SIZE 16 + +/* Buffer size selection */ +#ifdef UART1_CONF_TX_BUFFER_SIZE +#define UART1_TX_BUFFER_SIZE UART1_CONF_TX_BUFFER_SIZE +#else +#define UART1_TX_BUFFER_SIZE UART1_DEFAULT_TX_BUFFER_SIZE +#endif + +#ifdef UART1_CONF_RX_BUFFER_SIZE +#define UART1_RX_BUFFER_SIZE UART1_CONF_RX_BUFFER_SIZE +#else +#define UART1_RX_BUFFER_SIZE UART1_DEFAULT_RX_BUFFER_SIZE +#endif + +void uart1_set_input(int (*input)(unsigned char c)); +void uart1_writeb(unsigned char c); +void uart1_init(unsigned char br); + +#define uart1_write_direct(c) uart_driver_write_direct(E_AHI_UART_1, (c)) +#define uart1_disable_interrupts() uart_driver_disable_interrupts(E_AHI_UART_1) +#define uart1_enable_interrupts() uart_driver_enable_interrupts(E_AHI_UART_1) +#define uart1_restore_interrupts() uart_driver_restore_interrupts(E_AHI_UART_1) +#define uart1_store_interrupts() uart_driver_store_interrupts(E_AHI_UART_1) + +uint8_t uart1_active(void); + +#endif diff --git a/examples/sky/rssi-scanner.c b/platform/jn516x/dev/watchdog.c similarity index 63% rename from examples/sky/rssi-scanner.c rename to platform/jn516x/dev/watchdog.c index 92da5aa3e..395106fd3 100644 --- a/examples/sky/rssi-scanner.c +++ b/platform/jn516x/dev/watchdog.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Swedish Institute of Computer Science. + * Copyright (c) 2014, SICS Swedish ICT. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,63 +32,59 @@ /** * \file - * Scanning 2.4 GHz radio frequencies using CC2420 and prints - * the values + * JN516X watchdog support. * \author - * Joakim Eriksson, joakime@sics.se + * Beshr Al Nahas + * */ -#include "contiki.h" -#include "net/rime/rime.h" -#include "net/netstack.h" - -#include "dev/leds.h" -#include "cc2420.h" -#include "cc2420_const.h" -#include "dev/spi.h" -#include +#include "dev/watchdog.h" +#include "AppHardwareApi.h" /*---------------------------------------------------------------------------*/ -/* This assumes that the CC2420 is always on and "stable" */ -static void -set_frq(int c) -{ - int f; - /* fine graied channel - can we even read other channels with CC2420 ? */ - f = c + 302 + 0x4000; +static int counter = 0; - CC2420_WRITE_REG(CC2420_FSCTRL, f); - CC2420_STROBE(CC2420_SRXON); +/*---------------------------------------------------------------------------*/ +void +watchdog_init(void) +{ + counter = 0; + watchdog_stop(); + /* enable WDT interrupt */ + vAHI_WatchdogException(1); } - -static void -do_rssi(void) +/*---------------------------------------------------------------------------*/ +void +watchdog_start(void) { - int channel; - printf("RSSI:"); - for(channel = 0; channel <= 79; ++channel) { - set_frq(channel + 55); - printf("%d ", cc2420_rssi() + 55); + /* We setup the watchdog to reset the device after two seconds, + unless watchdog_periodic() is called. */ + counter--; + if(counter == 0) { + vAHI_WatchdogStart(9); /* about 8*2^(9-1)ms=2.048s timeout */ } - printf("\n"); } - /*---------------------------------------------------------------------------*/ -PROCESS(scanner_process, "RSSI Scanner"); -AUTOSTART_PROCESSES(&scanner_process); -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(scanner_process, ev, data) +void +watchdog_periodic(void) { - PROCESS_BEGIN(); - /* switch mac layer off, and turn radio on */ - NETSTACK_MAC.off(0); - cc2420_on(); - - while(1) { - do_rssi(); - PROCESS_PAUSE(); - } - - PROCESS_END(); + /* This function is called periodically to restart the watchdog + timer. */ + vAHI_WatchdogRestart(); +} +/*---------------------------------------------------------------------------*/ +void +watchdog_stop(void) +{ + counter++; + if(counter == 1) { + vAHI_WatchdogStop(); + } +} +/*---------------------------------------------------------------------------*/ +void +watchdog_reboot(void) +{ + vAHI_SwReset(); } /*---------------------------------------------------------------------------*/ diff --git a/platform/jn516x/lib/log.c b/platform/jn516x/lib/log.c new file mode 100644 index 000000000..adf85ec1a --- /dev/null +++ b/platform/jn516x/lib/log.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the Contiki OS + * + */ + +#include +#include + +#include "net/ip/uip.h" +#include "sys/log.h" + +/*---------------------------------------------------------------------------*/ +#if LOG_CONF_ENABLED +void +log_message(char *m1, char *m2) +{ + printf("%s%s\n", m1, m2); +} +#endif /* LOG_CONF_ENABLED */ +/*---------------------------------------------------------------------------*/ +#if UIP_LOGGING +void +uip_log(char *m) +{ + printf("uip_log: %s\n", m); +} +#endif /* UIP_LOGGING */ +/*---------------------------------------------------------------------------*/ diff --git a/platform/jn516x/lib/slip.c b/platform/jn516x/lib/slip.c new file mode 100644 index 000000000..31828e7e3 --- /dev/null +++ b/platform/jn516x/lib/slip.c @@ -0,0 +1,447 @@ +/* + * Copyright (c) 2014, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Alternative implementation for SLIP: + * 1. Accepts more than two packet + * 2. Disables UART rx interrupt when buffer is full + * (thus invoking flow control if configured) + * \author + * Niklas Finne + * Beshr Al Nahas + * + */ + +#include "contiki.h" + +#include +#include "net/ip/uip.h" +#include "net/ipv4/uip-fw.h" +#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#include "dev/slip.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PUTCHAR(X) do { putchar(X); putchar('\n'); } while(0) +#else +#define PRINTF(...) do {} while(0) +#define PUTCHAR(X) do {} while(0) +#endif + +#define SLIP_END 0300 +#define SLIP_ESC 0333 +#define SLIP_ESC_END 0334 +#define SLIP_ESC_ESC 0335 +#define SLIP_NEUTRAL 0 /* means: none of the above */ +#define SLIP_ESC_XON 0336 +#define SLIP_ESC_XOFF 0337 +#define XON ((unsigned char)17) +#define XOFF ((unsigned char)19) +#if UART_XONXOFF_FLOW_CTRL +volatile unsigned char xonxoff_state = XON; +#endif /* UART_XONXOFF_FLOW_CTRL */ + +PROCESS(slip_process, "SLIP driver"); + +#include "dev/uart0.h" +#define STORE_UART_INTERRUPTS uart0_store_interrupts +#define RESTORE_UART_INTERRUPTS uart0_restore_interrupts +#define DISABLE_UART_INTERRUPTS uart0_disable_interrupts +#define ENABLE_UART_INTERRUPTS uart0_enable_interrupts + +/** + * @brief A block of code may be made atomic by wrapping it with this + * macro. Something which is atomic cannot be interrupted by interrupts. + */ +/* A specific ATMOIC that disables UART interrupts only */ +#define ATOMIC(blah) \ + { \ + /* STORE_UART_INTERRUPTS(); */ \ + DISABLE_UART_INTERRUPTS(); \ + { blah } \ + /* RESTORE_UART_INTERRUPTS(); */ \ + ENABLE_UART_INTERRUPTS(); \ + } + +/* A generic ATMOIC that disables all interrupts */ +#define GLOBAL_ATOMIC(blah) \ + { \ + MICRO_DISABLE_INTERRUPTS(); \ + { blah } \ + MICRO_ENABLE_INTERRUPTS(); \ + } + +#if 1 +#define SLIP_STATISTICS(statement) +#else +uint16_t slip_drop_bytes, slip_overflow, slip_error_drop; +/* No used in this file */ +uint16_t slip_rubbish, slip_twopackets, slip_ip_drop; +unsigned long slip_received, slip_frames; +#define SLIP_STATISTICS(statement) statement +#endif + +/* Must be at least one byte larger than UIP_BUFSIZE (for SLIP_END)! */ +#ifdef SLIP_CONF_RX_BUFSIZE +#define RX_BUFSIZE SLIP_CONF_RX_BUFSIZE + +#if RX_BUFSIZE < (UIP_BUFSIZE - UIP_LLH_LEN + 16) +#error "SLIP_CONF_RX_BUFSIZE too small for UIP_BUFSIZE" +#endif + +#else +#define RX_BUFSIZE (UIP_CONF_BUFFER_SIZE * 2) +#endif + +/* + * Variables begin and end manage the buffer space in a cyclic + * fashion. The first used byte is at begin and end is one byte past + * the last. I.e. [begin, end) is the actively used space. + */ + +static volatile uint16_t begin, end, end_counter; +static uint8_t rxbuf[RX_BUFSIZE]; +static volatile uint8_t is_dropping = 0; +static volatile uint8_t is_full = 0; + +static void (*input_callback)(void) = NULL; +/*---------------------------------------------------------------------------*/ +void +slip_set_input_callback(void (*c)(void)) +{ + input_callback = c; +} +static void +slip_write_char(uint8_t c) +{ + /* Escape SLIP control characters */ + if(c == SLIP_END) { + slip_arch_writeb(SLIP_ESC); + c = SLIP_ESC_END; + } else if(c == SLIP_ESC) { + slip_arch_writeb(SLIP_ESC); + c = SLIP_ESC_ESC; + } +#if UART_XONXOFF_FLOW_CTRL + /* Escape XON/XOFF characters */ + else if(c == XON) { + slip_arch_writeb(SLIP_ESC); + c = SLIP_ESC_XON; + } else if(c == XOFF) { + slip_arch_writeb(SLIP_ESC); + c = SLIP_ESC_XOFF; + } +#endif /* UART_XONXOFF_FLOW_CTRL */ + slip_arch_writeb(c); +} +/*---------------------------------------------------------------------------*/ +uint8_t +slip_write(const void *_ptr, int len) +{ + const uint8_t *ptr = _ptr; + uint16_t i; + uint8_t c; + + slip_arch_writeb(SLIP_END); + + for(i = 0; i < len; ++i) { + c = *ptr++; + slip_write_char(c); + } + slip_arch_writeb(SLIP_END); + + return len; +} +/*---------------------------------------------------------------------------*/ +/* slip_send: forward (IPv4) packets with {UIP_FW_NETIF(..., slip_send)} + * was used in slip-bridge.c + */ +uint8_t +slip_send(void) +{ + uint16_t i; + uint8_t *ptr; + uint8_t c; + + slip_arch_writeb(SLIP_END); + + ptr = &uip_buf[UIP_LLH_LEN]; + for(i = 0; i < uip_len; ++i) { + if(i == UIP_TCPIP_HLEN) { + ptr = (uint8_t *)uip_appdata; + } + c = *ptr++; + slip_write_char(c); + } + slip_arch_writeb(SLIP_END); + + return UIP_FW_OK; +} +/*---------------------------------------------------------------------------*/ +static void +rxbuf_init(void) +{ + begin = end = end_counter = 0; + is_dropping = 0; +} +/*---------------------------------------------------------------------------*/ +/* Upper half does the polling. */ +static uint16_t +slip_poll_handler(uint8_t *outbuf, uint16_t blen) +{ + uint16_t len; + uint16_t pos; + uint8_t c; + uint8_t state; + + if(end_counter == 0 && is_full == 0) { + return 0; + } + for(len = 0, pos = begin, state = c = SLIP_NEUTRAL; + len < blen + 1; /* +1 for SLIP_END! */ + ) { + + c = rxbuf[pos++]; + + if(pos == RX_BUFSIZE) { + /* Circular buffer: warp around */ + pos = 0; + } + if(c == SLIP_END) { + /* End of packet */ + break; + } + if(len >= blen) { + /* End of buffer with no SLIP_END + * ==> something wrong happened */ + break; + } + switch(c) { + case SLIP_ESC: + state = SLIP_ESC; + break; + case SLIP_ESC_END: + if(state == SLIP_ESC) { + outbuf[len++] = SLIP_END; + state = SLIP_NEUTRAL; + } else { + outbuf[len++] = c; + } break; + case SLIP_ESC_ESC: + if(state == SLIP_ESC) { + outbuf[len++] = SLIP_ESC; + state = SLIP_NEUTRAL; + } else { + outbuf[len++] = c; + } break; +#if UART_XONXOFF_FLOW_CTRL + case SLIP_ESC_XON: + if(state == SLIP_ESC) { + outbuf[len++] = XON; + state = SLIP_NEUTRAL; + } else { + outbuf[len++] = c; + } break; + case SLIP_ESC_XOFF: + if(state == SLIP_ESC) { + outbuf[len++] = XOFF; + state = SLIP_NEUTRAL; + } else { + outbuf[len++] = c; + } break; +#endif /* UART_XONXOFF_FLOW_CTRL */ + default: + outbuf[len++] = c; + state = SLIP_NEUTRAL; + break; + } + } + + /* Update counters */ + if(c == SLIP_END) { + ATOMIC(begin = pos; + if(end_counter) { + end_counter--; + } + ) + PUTCHAR('P'); + } else { + /* Something went wrong, no SLIP_END found, drop everything */ + ATOMIC(rxbuf_init(); + is_dropping = 1; + ) + SLIP_STATISTICS(slip_error_drop++); + len = 0; + PRINTF("SLIP: *** out of sync!\n"); + } + + if(end_counter > 0) { + /* One more packet is buffered, need to be polled again! */ + process_poll(&slip_process); + } + return len; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(slip_process, ev, data) +{ + PROCESS_BEGIN(); + + rxbuf_init(); + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + + /* Move packet from rxbuf to buffer provided by uIP. */ + uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN], + UIP_BUFSIZE - UIP_LLH_LEN); + + PRINTF("SLIP: recv bytes %u frames RECV: %u. is_full %u, is_dropping %u.\n", + end_counter, uip_len, is_full, is_dropping); + + /* We have free space now, resume slip RX */ + if(is_full) { + is_full = 0; + ENABLE_UART_INTERRUPTS(); + } + + if(uip_len > 0) { + if(input_callback) { + input_callback(); + } +#ifdef SLIP_CONF_TCPIP_INPUT + SLIP_CONF_TCPIP_INPUT(); +#else + tcpip_input(); +#endif + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/* Return status from slip_input_byte: + * -1 means RX buffer overflow ==> stop reading + * 0 means do not exit power saving mode + * 1 means exit power saving mode + **/ +int +slip_input_byte(unsigned char c) +{ + static int in_frame = 0; + uint16_t next, next_next; + int error_return_code = is_full ? -1 : 0; + int success_return_code = is_full ? -1 : 1; + + SLIP_STATISTICS(slip_received++); + +#if UART_XONXOFF_FLOW_CTRL + if(c == XOFF || c == XON) { + xonxoff_state = c; + return 1; + } else { + /* ANY char would be XON */ + xonxoff_state = XON; + } +#endif /* UART_XONXOFF_FLOW_CTRL */ + + if(is_dropping) { + /* Make sure to drop full frames when overflow or + * out of sync happens */ + if(c != SLIP_END) { + SLIP_STATISTICS(slip_drop_bytes++); + } else { + is_dropping = 0; + in_frame = 0; + } + return error_return_code; + } + + if(!in_frame && c == SLIP_END) { + /* Ignore slip end when not receiving frame */ + return error_return_code; + /* increment and wrap */ + } + next = end + 1; + if(next >= RX_BUFSIZE) { + next = 0; + } + next_next = next + 1; + if(next_next >= RX_BUFSIZE) { + next_next = 0; + /* Next byte will overflow. Stop accepting. */ + } + if(next_next == begin) { + is_full = 1; + /* disable UART interrupts */ + DISABLE_UART_INTERRUPTS(); + process_poll(&slip_process); + } + + /* Buffer is full. We can't store anymore. + * Shall not happen normally, + * because of overflow protection above. */ + if(next == begin) { + is_dropping = 1; + SLIP_STATISTICS(slip_overflow++); + is_full = 1; + /* disable UART interrupts */ + DISABLE_UART_INTERRUPTS(); + process_poll(&slip_process); + return -1; + } + + rxbuf[end] = c; + end = next; + in_frame = 1; + + if(c == SLIP_END) { + in_frame = 0; + end_counter++; + SLIP_STATISTICS(slip_frames++); + process_poll(&slip_process); + return success_return_code; + } + return error_return_code; +} +/*---------------------------------------------------------------------------*/ +#if SLIP_BRIDGE_CONF_NO_PUTCHAR +int +putchar(int c) +{ + uart0_writeb(c); + return 1; +} +#endif diff --git a/platform/jn516x/lib/sprintf.c b/platform/jn516x/lib/sprintf.c new file mode 100644 index 000000000..500951e92 --- /dev/null +++ b/platform/jn516x/lib/sprintf.c @@ -0,0 +1,235 @@ +/* + File: printf.c + + Copyright (c) 2004,2008 Kustaa Nyholm / SpareTimeLabs + + All rights reserved. + + 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 Kustaa Nyholm or SpareTimeLabs 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. + + */ + +/* + * This is BSD code obtained from http://www.sparetimelabs.com/printfrevisited/index.html + * From the web page: + * "The code is GPL and BSD lincensed, download the BSD licensed version from the link + * above or use the GPL licensed code from this page below." + * + * modified by Beshr Al Nahas and Simon Duquennoy + */ + +#include "contiki-conf.h" +#include +#include +#include +#include +#include +#include "dev/uart0.h" + +static char *bf, buf[14], uc, zs; +static unsigned int num; + +static void +out(char c) +{ + *bf++ = c; +} +static void +outDgt(char dgt) +{ + out(dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10)); + zs = 1; +} +static void +divOut(unsigned int div) +{ + unsigned char dgt = 0; + while(num >= div) { + num -= div; + dgt++; + } + if(zs || dgt > 0) { + outDgt(dgt); + } +} +int +vsnprintf(char *str, size_t n, const char *fmt, __VALIST va) +{ + char ch, *p, *str_orig = str; + char next_ch; + + while((ch = *fmt++) && str - str_orig < n) { + if(ch != '%') { + *str++ = ch; + } else { + char lz = 0; + char w = 0; + ch = *(fmt++); + if(ch == '0') { + ch = *(fmt++); + lz = 1; + } + if(ch >= '0' && ch <= '9') { + w = 0; + while(ch >= '0' && ch <= '9') { + w = (((w << 2) + w) << 1) + ch - '0'; + ch = *fmt++; + } + } + bf = buf; + p = bf; + zs = 0; +start_format: + next_ch = *fmt; + switch(ch) { + case 0: + goto abort; + case 'l': + if(next_ch == 'x' + || next_ch == 'X' + || next_ch == 'u' + || next_ch == 'd') { + ch = *(fmt++); + goto start_format; + } + case 'u': + case 'd': + num = va_arg(va, unsigned int); + if(ch == 'd' && (int)num < 0) { + num = -(int)num; + out('-'); + } + divOut(1000000000); + divOut(100000000); + divOut(10000000); + divOut(1000000); + divOut(100000); + divOut(10000); + divOut(1000); + divOut(100); + divOut(10); + outDgt(num); + break; + case 'p': + case 'x': + case 'X': + uc = ch == 'X'; + num = va_arg(va, unsigned int); + /* divOut(0x100000000UL); */ + divOut(0x10000000); + divOut(0x1000000); + divOut(0x100000); + divOut(0x10000); + divOut(0x1000); + divOut(0x100); + divOut(0x10); + outDgt(num); + break; + case 'c': + out((char)(va_arg(va, int))); + break; + case 's': + p = va_arg(va, char *); + break; + case '%': + out('%'); + default: + break; + } + *bf = 0; + bf = p; + + while(*bf++ && w > 0) { + w--; + } + while(w-- > 0) { + if(str - str_orig < n) { + *str++ = lz ? '0' : ' '; + } else { + goto abort; + } + } + while((ch = *p++)) { + if(str - str_orig < n) { + *str++ = ch; + } else { + goto abort; + } + } + } + } + +abort: + if(str - str_orig < n) { + *str = '\0'; + } else { + *(--str) = '\0'; + } return str - str_orig; +} +int +sprintf(char *str, const char *fmt, ...) +{ + int m; + __VALIST va; + va_start(va, fmt); + m = vsnprintf(str, 0xffffffff, fmt, va); + va_end(va); + return m; +} +int +snprintf(char *str, size_t n, const char *fmt, ...) +{ + int m; + __VALIST va; + va_start(va, fmt); + m = vsnprintf(str, n, fmt, va); + va_end(va); + return m; +} +int +printf(const char *fmt, ...) +{ + int m, i; + char str[256]; + __VALIST va; + va_start(va, fmt); + m = vsnprintf(str, sizeof(str), fmt, va); + va_end(va); + for(i = 0; i < m; i++) { + putchar(str[i]); + } + return m; +} +int +puts(const char *s) +{ + char c; + while((c = *s++) != '\0') { + putchar(c); + } + putchar('\n'); + return strlen(s); +} diff --git a/platform/jn516x/platform-conf.h b/platform/jn516x/platform-conf.h new file mode 100644 index 000000000..408b4957e --- /dev/null +++ b/platform/jn516x/platform-conf.h @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#ifndef PLATFORM_CONF_H +#define PLATFORM_CONF_H + +#include +#include + +#undef putchar + +/* Delay between GO signal and SFD + * Measured 153us between GO and preamble. Add 5 bytes (preamble + SFD) air time: 153+5*32 = 313 */ +#define RADIO_DELAY_BEFORE_TX ((unsigned)US_TO_RTIMERTICKS(313)) +/* Delay between GO signal and start listening + * Measured 104us: between GO signal and start listening */ +#define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(104)) +/* Delay between the SFD finishes arriving and it is detected in software */ +#define RADIO_DELAY_BEFORE_DETECT ((unsigned)US_TO_RTIMERTICKS(14)) + +/* Micromac configuration */ + +#ifndef MIRCOMAC_CONF_BUF_NUM +#define MIRCOMAC_CONF_BUF_NUM 2 +#endif + +#ifndef MICROMAC_CONF_CHANNEL +#define MICROMAC_CONF_CHANNEL 26 +#endif + +/* 32kHz or 16MHz rtimers? */ +#ifdef RTIMER_CONF_USE_32KHZ +#define RTIMER_USE_32KHZ RTIMER_CONF_USE_32KHZ +#else +#define RTIMER_USE_32KHZ 0 +#endif + +/* Put the device in a sleep mode in idle periods? + * If RTIMER_USE_32KHZ is set, the device runs all the time on the 32 kHz oscillator. + * If RTIMER_USE_32KHZ is not set, the device runs on the 32 kHz oscillator during sleep, + * and switches back to the 32 MHz oscillator (16 MHz rtimer) at wakeup. + * */ +#ifdef JN516X_SLEEP_CONF_ENABLED +#define JN516X_SLEEP_ENABLED JN516X_SLEEP_CONF_ENABLED +#else +#define JN516X_SLEEP_ENABLED 0 +#endif + +/* Enable this to get the 32.768kHz oscillator */ +#ifndef JN516X_EXTERNAL_CRYSTAL_OSCILLATOR +#define JN516X_EXTERNAL_CRYSTAL_OSCILLATOR (RTIMER_USE_32KHZ || JN516X_SLEEP_ENABLED) +#endif /* JN516X_EXTERNAL_CRYSTAL_OSCILLATOR */ + +/* Core rtimer.h defaults to 16 bit timer unless RTIMER_CLOCK_DIFF is defined */ +typedef uint32_t rtimer_clock_t; +#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b))) + +/* 8ms timer tick */ +#define CLOCK_CONF_SECOND 125 + +#if JN516X_EXTERNAL_CRYSTAL_OSCILLATOR +#define JN516X_XOSC_SECOND 32768 +#else +#define JN516X_XOSC_SECOND 32000 +#endif + +/* Timer conversion*/ +#if RTIMER_USE_32KHZ +#define RADIO_TO_RTIMER(X) ((X) * (JN516X_XOSC_SECOND) / 62500) +#else + /* RTIMER 16M = 256 * 62500(RADIO) == 2^8 * 62500 */ +#define RADIO_TO_RTIMER(X) ((rtimer_clock_t)((X) << (int32_t)8L)) +#endif + +/* If the timer base a binary 32kHz clock, compensate for this base drift */ +#if RTIMER_USE_32KHZ && JN516X_EXTERNAL_CRYSTAL_OSCILLATOR +/* Drift calculated using this formula: +* ((US_TO_TICKS(10000) * 100) - RTIMER_SECOND) * 1e6 = 976.5625 ppm +*/ +#define TSCH_CONF_BASE_DRIFT_PPM -977 +#endif + +#define DR_11744_DIO2 12 +#define DR_11744_DIO3 13 +#define DR_11744_DIO4 14 +#define DR_11744_DIO5 15 +#define DR_11744_DIO6 16 +#define DR_11744_DIO7 17 + +/* Enable power amplifier of JN5168 M05 and M06 modules */ +#if defined(JN5168_M05) || defined(JN5168_M06) +#define RADIO_TEST_MODE RADIO_TEST_MODE_HIGH_PWR +#else +#define RADIO_TEST_MODE RADIO_TEST_MODE_DISABLED +#endif + +#define TSCH_DEBUG 0 + +#if TSCH_DEBUG +#define TSCH_DEBUG_INIT() do { \ + vAHI_DioSetDirection(0, (1 << DR_11744_DIO2) | (1 << DR_11744_DIO3) | (1 << DR_11744_DIO4) | (1 << DR_11744_DIO5) | (1 << DR_11744_DIO6) | (1 << DR_11744_DIO7)); \ + vAHI_DioSetOutput(0, (1 << DR_11744_DIO2) | (1 << DR_11744_DIO3) | (1 << DR_11744_DIO4) | (1 << DR_11744_DIO5) | (1 << DR_11744_DIO6) | (1 << DR_11744_DIO7)); } while(0); +#define TSCH_DEBUG_INTERRUPT() do { \ + static dio_state = 0; \ + dio_state = !dio_state; \ + if(dio_state) { \ + vAHI_DioSetOutput((1 << DR_11744_DIO2), 0); \ + } else { \ + vAHI_DioSetOutput(0, (1 << DR_11744_DIO2)); \ + } \ +} while(0); +#define TSCH_DEBUG_RX_EVENT() do { \ + static dio_state = 0; \ + dio_state = !dio_state; \ + if(dio_state) { \ + vAHI_DioSetOutput((1 << DR_11744_DIO4), 0); \ + } else { \ + vAHI_DioSetOutput(0, (1 << DR_11744_DIO4)); \ + } \ +} while(0); +#define TSCH_DEBUG_TX_EVENT() do { \ + static dio_state = 0; \ + dio_state = !dio_state; \ + if(dio_state) { \ + vAHI_DioSetOutput((1 << DR_11744_DIO5), 0); \ + } else { \ + vAHI_DioSetOutput(0, (1 << DR_11744_DIO5)); \ + } \ +} while(0); +#define TSCH_DEBUG_SLOT_START() do { \ + static dio_state = 0; \ + dio_state = !dio_state; \ + if(dio_state) { \ + vAHI_DioSetOutput((1 << DR_11744_DIO3), 0); \ + } else { \ + vAHI_DioSetOutput(0, (1 << DR_11744_DIO3)); \ + } \ +} while(0); +#define TSCH_DEBUG_SLOT_END() +#endif /* TSCH_DEBUG */ + +#ifndef BAUD2UBR +#define BAUD2UBR(X) (X) +#endif /* BAUD2UBR */ + +/* UART baud rates */ +#define UART_RATE_4800 0 +#define UART_RATE_9600 1 +#define UART_RATE_19200 2 +#define UART_RATE_38400 3 +#define UART_RATE_76800 4 +#define UART_RATE_115200 5 +#define UART_RATE_230400 6 +#define UART_RATE_460800 7 +#define UART_RATE_500000 8 +#define UART_RATE_576000 9 +#define UART_RATE_921600 10 +#define UART_RATE_1000000 11 + +#define PLATFORM_HAS_LEDS 1 +#define PLATFORM_HAS_BUTTON (SENSOR_BOARD_DR1174 == 1) +#define PLATFORM_HAS_LIGHT (SENSOR_BOARD_DR1175 == 1) +#define PLATFORM_HAS_HT (SENSOR_BOARD_DR1175 == 1) +#define PLATFORM_HAS_POT (SENSOR_BOARD_DR1199 == 1) +#define PLATFORM_HAS_BATTERY 0 /* sensor driver not implemented */ +#define PLATFORM_HAS_SHT11 0 +#define PLATFORM_HAS_RADIO 1 + +/* CPU target speed in Hz + * RTIMER and peripherals clock is F_CPU/2 */ +#define F_CPU 32000000UL + +/* LED ports */ +/* + #define LEDS_PxDIR P5DIR + #define LEDS_PxOUT P5OUT + #define LEDS_CONF_RED 0x10 + #define LEDS_CONF_GREEN 0x20 + #define LEDS_CONF_YELLOW 0x40 + #define JENNIC_CONF_BUTTON_PIN (IRQ_DIO9|IRQ_DIO10) + */ + +#define CC_CONF_REGISTER_ARGS 1 +#define CC_CONF_FUNCTION_POINTER_ARGS 1 +#define CC_CONF_VA_ARGS 1 +#define CC_CONF_INLINE inline + +#define CCIF +#define CLIF + +#ifdef HAVE_STDINT_H +#include +#else +#ifndef uint8_t +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +typedef signed char int8_t; +typedef short int16_t; +typedef long int32_t; +typedef unsigned long long uint64_t; +typedef long long int64_t; +#endif +#endif /* !HAVE_STDINT_H */ + +/* Types for clocks and uip_stats */ +typedef uint16_t uip_stats_t; +typedef uint32_t clock_time_t; + +/* Shall we calibrate the DCO periodically? */ +#ifndef DCOSYNCH_CONF_ENABLED +#define DCOSYNCH_CONF_ENABLED 1 +#endif + +/* How often shall we attempt to calibrate DCO? + * PS: It should be calibrated upon temperature changes, + * but the naive approach of periodic calibration is fine too */ +#ifndef DCOSYNCH_PERIOD +#define DCOSYNCH_PERIOD (5 * 60) +#endif /* VCO_CALIBRATION_INTERVAL */ + +/* Disable UART HW flow control */ +#ifndef UART_HW_FLOW_CTRL +#define UART_HW_FLOW_CTRL 0 +#endif /* UART_HW_FLOW_CTRL */ + +/* Disable UART SW flow control */ +#ifndef UART_XONXOFF_FLOW_CTRL +#define UART_XONXOFF_FLOW_CTRL 1 +#endif /* UART_XONXOFF_FLOW_CTRL */ + +#ifndef UART_BAUD_RATE +#define UART_BAUD_RATE UART_RATE_1000000 +#endif /* UART_BAUD_RATE */ + +#ifndef UART1_BAUD_RATE +#define UART1_BAUD_RATE UART_RATE_1000000 +#endif +#define ENABLE_ADVANCED_BAUD_SELECTION (UART_BAUD_RATE > UART_RATE_115200) + +/* Set this to zero only if we are using SLIP */ +#ifndef SLIP_BRIDGE_CONF_NO_PUTCHAR +#define SLIP_BRIDGE_CONF_NO_PUTCHAR 1 +#endif /* SLIP_BRIDGE_CONF_NO_PUTCHAR */ + +/* Extension of LED definitions from leds.h for various JN516x dev boards +JN516x Dongle: + LEDS_RED Red LED on dongle + LEDS_GREEN Green LED on dongle + Note: Only one LED can be switch on at the same time + +DR1174-only: + LEDS_GP0 LED D3 on DR1174 + LEDS_GP1 LED D6 on DR1174 + +DR1174+DR1199: + LEDS_RED LED D1 on DR1199 + LEDS_GREEN LED D2 on DR1199 + LEDS_BLUE LED D3 on DR1199 + LEDS_GP0 LED D3 on DR1174 + LEDS_GP1 LED D6 on DR1174 + +DR1174+DR1175: + LEDS_RED Red led in RGB-led with level control on DR1175 + LEDS_GREEN Green led in RGB-led with level control on DR1175 + LEDS_BLUE Blue led in RGB-led with level control on DR1175 + LEDS_WHITE White power led with level control on DR1175 + LEDS_GP0 LEDS D3 on DR1174 + LEDS_GP1 LEDS D6 on DR1174 +*/ +#define LEDS_WHITE 8 +#define LEDS_GP0 16 +#define LEDS_GP1 32 +#define LEDS_GP2 64 +#define LEDS_GP3 128 +#define LEDS_CONF_ALL 255 +#endif /* PLATFORM_CONF_H */ diff --git a/platform/mbxxx/Makefile.mbxxx b/platform/mbxxx/Makefile.mbxxx index 68905e295..8ce2415dd 100644 --- a/platform/mbxxx/Makefile.mbxxx +++ b/platform/mbxxx/Makefile.mbxxx @@ -6,10 +6,6 @@ ifndef CONTIKI_TARGET_MAIN CONTIKI_TARGET_MAIN = contiki-main.c board.c endif -ifdef UIP_CONF_IPV6 -CFLAGS += -DWITH_UIP6=1 -endif - CONTIKI_TARGET_SOURCEFILES += $(ARCH) $(CONTIKI_TARGET_MAIN) MCU=STM32W108 @@ -21,5 +17,6 @@ ifeq ($(HOST_OS),Windows) SERIALDUMP = $(CONTIKI)/tools/stm32w/serialdump-windows endif -MODULES+=core/net/ip core/net/ipv4 core/net core/net/ipv6 \ - core/net/rpl core/net/rime core/net/mac core/net/mac/contikimac +MODULES+=core/net \ + core/net/mac core/net/mac/contikimac \ + core/net/llsec diff --git a/platform/mbxxx/clock.c b/platform/mbxxx/clock.c index cc9a1406b..896c2a9bb 100644 --- a/platform/mbxxx/clock.c +++ b/platform/mbxxx/clock.c @@ -126,7 +126,7 @@ void clock_delay(unsigned int i) } /*---------------------------------------------------------------------------*/ -/** +/* * Wait for a multiple of 1 ms. * */ diff --git a/platform/mbxxx/contiki-conf.h b/platform/mbxxx/contiki-conf.h index c732fe8ac..1d2b17322 100644 --- a/platform/mbxxx/contiki-conf.h +++ b/platform/mbxxx/contiki-conf.h @@ -115,7 +115,7 @@ #define RPL_CONF_MAX_DAG_PER_INSTANCE 1 #define PROCESS_CONF_NUMEVENTS 16 -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 /* Network setup for IPv6 */ #define NETSTACK_CONF_NETWORK sicslowpan_driver @@ -125,26 +125,16 @@ larger than a specified size, if no ContikiMAC header should be used. */ #define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63 -#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0 #define UIP_CONF_UDP 1 -#if (WITH_COAP==7) || (WITH_COAP==6) || (WITH_COAP==3) -#define UIP_CONF_TCP 0 -#else -#define UIP_CONF_TCP 1 -#endif /* WITH_COAP */ - #define UIP_CONF_ROUTER 1 -#define UIP_CONF_IPV6_RPL 1 #define UIP_CONF_ND6_SEND_RA 0 -#define UIP_CONF_IPV6 1 +#define NETSTACK_CONF_WITH_IPV6 1 #define UIP_CONF_IPV6_QUEUE_PKT 0 #define UIP_CONF_IPV6_CHECKS 1 #define UIP_CONF_IPV6_REASSEMBLY 0 -#define UIP_CONF_ND6_MAX_PREFIXES 2 -#define UIP_CONF_ND6_MAX_DEFROUTERS 1 #define UIP_CONF_IP_FORWARD 0 #define UIP_CONF_BUFFER_SIZE 140 #define UIP_CONF_MAX_CONNECTIONS 4 @@ -162,12 +152,12 @@ #define SICSLOWPAN_CONF_MAXAGE 2 #endif /* SICSLOWPAN_CONF_MAXAGE */ -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ /* Network setup for non-IPv6 (rime). */ #define NETSTACK_CONF_NETWORK rime_driver -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #ifdef PROJECT_CONF_H #include PROJECT_CONF_H diff --git a/platform/mbxxx/contiki-init-net.c b/platform/mbxxx/contiki-init-net.c index 0f6eb0a64..381c4f3cf 100644 --- a/platform/mbxxx/contiki-init-net.c +++ b/platform/mbxxx/contiki-init-net.c @@ -46,7 +46,7 @@ #include "contiki-net.h" -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #define DEBUG 1 #if DEBUG @@ -136,5 +136,5 @@ void set_net_address(void) #endif /* FIXED_GLOBAL_ADDRESS */ -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /** @} */ diff --git a/platform/mbxxx/contiki-main.c b/platform/mbxxx/contiki-main.c index ae16cbf55..f1ad1d8d4 100644 --- a/platform/mbxxx/contiki-main.c +++ b/platform/mbxxx/contiki-main.c @@ -72,24 +72,14 @@ #include "net/rime/rime.h" #include "net/ip/uip.h" -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 #include "net/ipv6/uip-ds6.h" -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ -#define DEBUG 1 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",lladdr.u8[0], lladdr.u8[1], lladdr.u8[2], lladdr.u8[3],lladdr.u8[4], lladdr.u8[5], lladdr.u8[6], lladdr.u8[7]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(addr) -#endif +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" - -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 PROCINIT(&tcpip_process, &sensors_process); #else PROCINIT(&sensors_process); @@ -121,11 +111,11 @@ set_rime_addr(void) } } -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(&uip_lladdr.addr, &eui64, sizeof(uip_lladdr.addr)); #endif -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 linkaddr_set_node_addr((linkaddr_t *)&eui64); #else linkaddr_set_node_addr((linkaddr_t *)&eui64.u8[8 - LINKADDR_SIZE]); @@ -183,13 +173,13 @@ main(void) set_rime_addr(); - printf("%s %s, channel check rate %lu Hz\n", + printf("%s %s, channel check rate %d Hz\n", NETSTACK_MAC.name, NETSTACK_RDC.name, CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1: NETSTACK_RDC.channel_check_interval())); printf("802.15.4 PAN ID 0x%x, EUI-%d:", IEEE802154_CONF_PANID, UIP_CONF_LL_802154?64:16); - uip_debug_lladdr_print(&linkaddr_node_addr); + net_debug_lladdr_print((const uip_lladdr_t *)&linkaddr_node_addr); printf(", radio channel %u\n", RF_CHANNEL); procinit_init(); @@ -207,7 +197,7 @@ main(void) ST_RadioSetEdCcaThreshold(DEFAULT_RADIO_CCA_THRESHOLD); autostart_start(autostart_processes); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 printf("Tentative link-local IPv6 address "); { uip_ds6_addr_t *lladdr; @@ -224,7 +214,7 @@ main(void) if(!UIP_CONF_IPV6_RPL) { uip_ipaddr_t ipaddr; int i; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE); printf("Tentative global IPv6 address "); @@ -235,7 +225,7 @@ main(void) printf("%02x%02x\n", ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]); } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ watchdog_start(); @@ -251,15 +241,13 @@ main(void) - ENERGEST_OFF(ENERGEST_TYPE_CPU); - /* watchdog_stop(); */ - ENERGEST_ON(ENERGEST_TYPE_LPM); + /* watchdog_stop(); */ + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* Go to idle mode. */ halSleepWithOptions(SLEEPMODE_IDLE,0); /* We are awake. */ /* watchdog_start(); */ - ENERGEST_OFF(ENERGEST_TYPE_LPM); - ENERGEST_ON(ENERGEST_TYPE_CPU); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } diff --git a/platform/mbxxx/dev/eeprom.c b/platform/mbxxx/dev/eeprom.c index 4932787da..62ef92932 100644 --- a/platform/mbxxx/dev/eeprom.c +++ b/platform/mbxxx/dev/eeprom.c @@ -4,7 +4,7 @@ * Department of Innovation Engineering - University of Salento * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -32,7 +32,7 @@ */ /** - * \file eeprom.c + * \file platform/mbxxx/dev/eeprom.c * \brief ST M24C64W EEPROM driver. * \author Maria Laura Stefanizzi * \date 2013-11-20 @@ -49,7 +49,7 @@ #define EE_MAX_TRIALS 300 /* Write Cycle polling - * + * * During the internal Write cycle, the device disconnects itself from the bus, * and writes a copy of the data from its internal latches to the memory cells. */ diff --git a/platform/mbxxx/dev/i2c.c b/platform/mbxxx/dev/i2c.c index 96fb46a84..2c04296bb 100644 --- a/platform/mbxxx/dev/i2c.c +++ b/platform/mbxxx/dev/i2c.c @@ -4,7 +4,7 @@ * Department of Innovation Engineering - University of Salento * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -32,7 +32,7 @@ */ /** - * \file i2c.c + * \file platform/mbxxx/dev/i2c.c * \brief I2C bus master driver for mbxxx platform. * \author Maria Laura Stefanizzi * \date 2013-11-20 @@ -54,11 +54,11 @@ i2c_enable(void) /* Configure serial controller to I2C mode */ SC2_MODE = SC2_MODE_I2C; - /* - * The SCL is produced by dividing down 12MHz according to + /* + * The SCL is produced by dividing down 12MHz according to * this equation: * Rate = 12 MHz / ( (LIN + 1) * (2^EXP) ) - * + * * Configure rate registers for Fast Mode operation (400 kbps) */ SC2_RATELIN = 14; diff --git a/platform/mbxxx/dev/i2c.h b/platform/mbxxx/dev/i2c.h index c85bc6d8b..be2e62876 100644 --- a/platform/mbxxx/dev/i2c.h +++ b/platform/mbxxx/dev/i2c.h @@ -4,7 +4,7 @@ * Department of Innovation Engineering - University of Salento * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -32,7 +32,7 @@ */ /** - * \file i2c.h + * \file platform/mbxxx/dev/i2c.h * \brief I2C bus master driver for mbxxx platform. * \author Maria Laura Stefanizzi * \date 2013-11-20 diff --git a/platform/mbxxx/dev/temperature-sensor.c b/platform/mbxxx/dev/temperature-sensor.c index c4418c55a..520032cb4 100644 --- a/platform/mbxxx/dev/temperature-sensor.c +++ b/platform/mbxxx/dev/temperature-sensor.c @@ -76,7 +76,6 @@ value(int type) { static uint16_t ADCvalue; static int16_t volts; - uint16_t scale=1; halStartAdcConversion(ADC_USER_APP, ADC_REF_INT, ADC_SOURCE(halGetADCChannelFromGPIO(TEMPERATURE_SENSOR_GPIO),ADC_MUX_VREF2), ADC_CONVERSION_TIME_US_4096); diff --git a/platform/mbxxx/platform-conf.h b/platform/mbxxx/platform-conf.h index 5ed278687..98870980d 100644 --- a/platform/mbxxx/platform-conf.h +++ b/platform/mbxxx/platform-conf.h @@ -1,5 +1,8 @@ /** - * \defgroup mbxxx-platform The STM32W MBXXX platform. + * \addtogroup platform + * @{ */ +/** + * \defgroup mbxxx-platform The STM32W MBXXX platform * * The STM32W MBXXX platform. * @@ -59,7 +62,6 @@ /* Platform-dependent definitions */ #define CC_CONF_REGISTER_ARGS 0 #define CC_CONF_FUNCTION_POINTER_ARGS 1 -#define CC_CONF_FASTCALL #define CC_CONF_VA_ARGS 1 #define CC_CONF_INLINE inline @@ -85,7 +87,7 @@ typedef unsigned long clock_time_t; typedef unsigned long rtimer_clock_t; -#define RTIMER_CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) +#define RTIMER_CLOCK_DIFF(a,b) ((signed long)((a)-(b))) #define LEDS_CONF_RED_PIN boardDescription->io->leds[1].gpioPin #define LEDS_CONF_GREEN_PIN boardDescription->io->leds[0].gpioPin @@ -102,3 +104,4 @@ typedef unsigned long rtimer_clock_t; #endif /* PLATFORM_CONF_H_ */ /** @} */ +/** @} */ diff --git a/platform/micaz/Makefile.micaz b/platform/micaz/Makefile.micaz index cdfea9e74..f048518b8 100644 --- a/platform/micaz/Makefile.micaz +++ b/platform/micaz/Makefile.micaz @@ -45,5 +45,6 @@ ifneq ($(strip $(HAVE_PRGBOARD_FILE)), ) include $(PRGBOARD_FILE) endif -MODULES += core/net core/net/ip core/net/ipv6 core/net/ipv4 core/net/rime \ - core/net/mac core/net/rpl core/net/mac/cxmac dev/cc2420 +MODULES += core/net \ + core/net/mac core/net/mac/cxmac core/net/mac/sicslowmac \ + core/net/llsec dev/cc2420 diff --git a/platform/micaz/contiki-conf.h b/platform/micaz/contiki-conf.h index a94afac86..50e2ace1e 100644 --- a/platform/micaz/contiki-conf.h +++ b/platform/micaz/contiki-conf.h @@ -48,10 +48,10 @@ #include "platform-conf.h" -#if UIP_CONF_IPV6 -#define WITH_UIP6 1 +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_WITH_IPV6 1 #endif -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 /* Network setup for IPv6 */ #define NETSTACK_CONF_NETWORK sicslowpan_driver //#define NETSTACK_CONF_MAC csma_driver @@ -65,7 +65,7 @@ #define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 #define CXMAC_CONF_ANNOUNCEMENTS 0 -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ /* Network setup for non-IPv6 (rime). */ @@ -86,7 +86,7 @@ #define COLLECT_NBR_TABLE_CONF_MAX_NEIGHBORS 32 -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define PACKETBUF_CONF_ATTRS_INLINE 1 @@ -115,7 +115,7 @@ #define PROCESS_CONF_NUMEVENTS 8 #define PROCESS_CONF_STATS 1 -#ifdef WITH_UIP6 +#ifdef NETSTACK_CONF_WITH_IPV6 #define LINKADDR_CONF_SIZE 8 @@ -123,50 +123,44 @@ #define UIP_CONF_LLH_LEN 0 #define UIP_CONF_ROUTER 0 -#define UIP_CONF_IPV6_RPL 1 /* configure number of neighbors and routes */ -#define NBR_TABLE_CONF_MAX_NEIGHBORS 5 -#define UIP_CONF_MAX_ROUTES 5 +#define NBR_TABLE_CONF_MAX_NEIGHBORS 4 +#define UIP_CONF_MAX_ROUTES 4 -#define RPL_CONF_MAX_PARENTS 4 -#define NBR_TABLE_CONF_MAX_NEIGHBORS 8 +#define RPL_CONF_MAX_PARENTS 4 +#define RPL_CONF_MAX_DAG_PER_INSTANCE 1 #define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_RETRANS_TIMER 10000 -#define UIP_CONF_IPV6 1 +#define NETSTACK_CONF_WITH_IPV6 1 #define UIP_CONF_IPV6_QUEUE_PKT 0 #define UIP_CONF_IPV6_CHECKS 1 #define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_NETIF_MAX_ADDRESSES 3 -#define UIP_CONF_ND6_MAX_PREFIXES 3 -#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_IP_FORWARD 0 -#define UIP_CONF_BUFFER_SIZE 240 +#define UIP_CONF_BUFFER_SIZE 200 -#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 -#define SICSLOWPAN_CONF_COMPRESSION_HC1 1 -#define SICSLOWPAN_CONF_COMPRESSION_HC01 2 #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #ifndef SICSLOWPAN_CONF_FRAG #define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_FRAGMENT_BUFFERS 3 #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ -#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_IP_FORWARD 1 #define UIP_CONF_BUFFER_SIZE 128 -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_ICMP_DEST_UNREACH 1 -#if !WITH_UIP && !WITH_UIP6 +#if !NETSTACK_CONF_WITH_IPV4 && !NETSTACK_CONF_WITH_IPV6 #define QUEUEBUF_CONF_NUM 8 #else -#define QUEUEBUF_CONF_NUM 4 +#define QUEUEBUF_CONF_NUM 2 #endif #define TIMESYNCH_CONF_ENABLED 1 diff --git a/platform/micaz/contiki-micaz-main.c b/platform/micaz/contiki-micaz-main.c index 488503df4..318cdb8da 100644 --- a/platform/micaz/contiki-micaz-main.c +++ b/platform/micaz/contiki-micaz-main.c @@ -63,12 +63,12 @@ init_usart(void) rs232_init(RS232_PORT_0, USART_BAUD_115200, USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); -#if WITH_UIP || WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV4 || NETSTACK_CONF_WITH_IPV6 // slip_arch_init(USART_BAUD_115200); rs232_redirect_stdout(RS232_PORT_0); #else rs232_redirect_stdout(RS232_PORT_0); -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 || NETSTACK_CONF_WITH_IPV6*/ } /*---------------------------------------------------------------------------*/ diff --git a/platform/micaz/dev/clock.c b/platform/micaz/dev/clock.c index 2ed808637..e8e387b08 100644 --- a/platform/micaz/dev/clock.c +++ b/platform/micaz/dev/clock.c @@ -129,7 +129,7 @@ clock_delay(unsigned int i) } /*---------------------------------------------------------------------------*/ -/** +/* * Wait for a multiple of 1 / 128 sec = 7.8125 ms. * */ diff --git a/platform/micaz/init-net.c b/platform/micaz/init-net.c index c0366c833..9c09fe4ae 100644 --- a/platform/micaz/init-net.c +++ b/platform/micaz/init-net.c @@ -49,15 +49,17 @@ #include "dev/leds.h" #include "net/netstack.h" #include "net/mac/frame802154.h" +#include "net/linkaddr.h" +#include "net/queuebuf.h" #include "dev/ds2401.h" #include "sys/node-id.h" -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 #include "net/ipv6/uip-ds6.h" -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 #include "net/ip/uip.h" #include "net/ipv4/uip-fw.h" #include "net/uip-fw-drv.h" @@ -69,7 +71,7 @@ static struct uip_fw_netif meshif = static uint8_t is_gateway; -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ #define UIP_OVER_MESH_CHANNEL 8 @@ -81,7 +83,7 @@ set_rime_addr(void) int i; memset(&addr, 0, sizeof(linkaddr_t)); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(addr.u8, ds2401_id, sizeof(addr.u8)); #else if(node_id == 0) { @@ -102,7 +104,7 @@ set_rime_addr(void) } /*--------------------------------------------------------------------------*/ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 static void set_gateway(void) { @@ -117,7 +119,7 @@ set_gateway(void) is_gateway = 1; } } -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ /*---------------------------------------------------------------------------*/ void init_net(void) @@ -140,7 +142,7 @@ init_net(void) cc2420_set_pan_addr(IEEE802154_PANID, shortaddr, longaddr); } -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(&uip_lladdr.addr, ds2401_id, sizeof(uip_lladdr.addr)); /* Setup nullmac-like MAC for 802.15.4 */ /* sicslowpan_init(sicslowmac_init(&cc2420_driver)); */ @@ -175,7 +177,7 @@ init_net(void) if(!UIP_CONF_IPV6_RPL) { uip_ipaddr_t ipaddr; int i; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE); printf_P(PSTR("Tentative global IPv6 address ")); @@ -187,7 +189,7 @@ init_net(void) ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]); } -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ NETSTACK_RDC.init(); NETSTACK_MAC.init(); @@ -198,10 +200,10 @@ init_net(void) CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0? 1: NETSTACK_RDC.channel_check_interval()), CC2420_CONF_CHANNEL); -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 uip_ipaddr_t hostaddr, netmask; uip_init(); @@ -235,7 +237,7 @@ init_net(void) uip_over_mesh_init(UIP_OVER_MESH_CHANNEL); printf_P(PSTR("uIP started with IP address %d.%d.%d.%d\n"), uip_ipaddr_to_quad(&hostaddr)); -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ diff --git a/platform/micaz/node-id.c b/platform/micaz/node-id.c index 00f1ed13a..998dd1b0d 100644 --- a/platform/micaz/node-id.c +++ b/platform/micaz/node-id.c @@ -33,6 +33,7 @@ #include "contiki-conf.h" #include "sys/node-id.h" +#include "dev/eeprom.h" unsigned short node_id = 0; diff --git a/platform/micaz/platform-conf.h b/platform/micaz/platform-conf.h index 9a5a41f8c..a54f90a1b 100644 --- a/platform/micaz/platform-conf.h +++ b/platform/micaz/platform-conf.h @@ -56,18 +56,10 @@ */ /* Clock ticks per second */ #define CLOCK_CONF_SECOND 128 -#if 1 -/* 16 bit counter overflows every ~10 minutes */ -typedef unsigned short clock_time_t; -#define CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) -#define INFINITE_TIME 0xffff -#define RIME_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME INFINITE_TIME/CLOCK_CONF_SECOND /* Default uses 600 */ -#define COLLECT_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME INFINITE_TIME/CLOCK_CONF_SECOND /* Default uses 600 */ -#else -typedef unsigned long clock_time_t; -#define CLOCK_LT(a,b) ((signed long)((a)-(b)) < 0) -#define INFINITE_TIME 0xffffffff -#endif + +typedef uint32_t clock_time_t; +#define CLOCK_LT(a,b) ((int32_t)((a)-(b)) < 0) + /* These routines are not part of the contiki core but can be enabled in cpu/avr/clock.c */ void clock_delay_msec(uint16_t howlong); void clock_adjust_ticks(clock_time_t howmany); diff --git a/platform/minimal-net/Makefile.minimal-net b/platform/minimal-net/Makefile.minimal-net index 9a37adf52..2c2399617 100644 --- a/platform/minimal-net/Makefile.minimal-net +++ b/platform/minimal-net/Makefile.minimal-net @@ -14,7 +14,7 @@ CONTIKI_TARGET_SOURCEFILES = contiki-main.c clock.c leds.c leds-arch.c cfs-posix ifeq ($(HOST_OS),Windows) CONTIKI_TARGET_SOURCEFILES += wpcap-drv.c wpcap.c else -CONTIKI_TARGET_SOURCEFILES += tapdev-drv.c tapdev.c tapdev6.c +CONTIKI_TARGET_SOURCEFILES += tapdev-drv.c tapdev.c tapdev6.c linuxradio-drv.c endif CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) @@ -29,4 +29,4 @@ endif CONTIKI_CPU=$(CONTIKI)/cpu/native include $(CONTIKI)/cpu/native/Makefile.native -MODULES+=core/net/ip core/net/ipv4 core/net core/net/ipv6 core/net/rime +MODULES+=core/net diff --git a/platform/minimal-net/contiki-conf.h b/platform/minimal-net/contiki-conf.h index be000340e..9fa2e225f 100644 --- a/platform/minimal-net/contiki-conf.h +++ b/platform/minimal-net/contiki-conf.h @@ -35,10 +35,18 @@ #include #include +#ifndef _WIN32 +#include +#endif + +struct select_callback { + int (* set_fd)(fd_set *fdr, fd_set *fdw); + void (* handle_fd)(fd_set *fdr, fd_set *fdw); +}; +int select_set_callback(int fd, const struct select_callback *callback); #define CC_CONF_REGISTER_ARGS 1 #define CC_CONF_FUNCTION_POINTER_ARGS 1 -#define CC_CONF_FASTCALL #define CC_CONF_VA_ARGS 1 #define CCIF @@ -57,7 +65,7 @@ typedef int32_t s32_t; typedef unsigned short uip_stats_t; -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /* The Windows build uses wpcap to connect to a host interface. It finds the interface by scanning for * an address, which can be specified here and overridden with the command line. * An ip4 or ip6 address can be used; this allows turning off the ip4 protocol on the interface. @@ -88,10 +96,9 @@ typedef unsigned short uip_stats_t; */ #define WEBSERVER_CONF_STATUSPAGE 1 -/* RPL currently works only on Windows. *nix would require converting the tun interface to two pcap tees. */ -//#define UIP_CONF_IPV6_RPL 0 +/* RPL currently works only on Windows. *nix would require converting the tun interface to two pcap tees. */ //#define RPL_BORDER_ROUTER 0 -#endif +#endif #if UIP_CONF_IPV6_RPL /* RPL motes use the uip.c link layer address or optionally the harded coded address (but without the prefix!) @@ -122,7 +129,7 @@ typedef unsigned short uip_stats_t; * e.g. the jackdaw RNDIS <-> repeater. Then RPL will configure on the radio network and the RF motes will * be reached through bbbb::. * Possibly minimal-net RPL motes could also be added to this interface? - * + * */ #undef UIP_CONF_ROUTER #define UIP_CONF_ROUTER 1 @@ -152,16 +159,16 @@ typedef unsigned short uip_stats_t; /* Not used but avoids compile errors while sicslowpan.c is being developed */ #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#define NETSTACK_CONF_LINUXRADIO_DEV "wpan0" + #define UIP_CONF_UDP 1 #define UIP_CONF_TCP 1 -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #define UIP_CONF_IPV6_QUEUE_PKT 1 #define UIP_CONF_IPV6_CHECKS 1 #define UIP_CONF_IPV6_REASSEMBLY 1 //#define UIP_CONF_NETIF_MAX_ADDRESSES 5 -//#define UIP_CONF_ND6_MAX_PREFIXES 3 -//#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define NBR_TABLE_CONF_MAX_NEIGHBORS 100 #define UIP_CONF_DS6_DEFRT_NBU 2 #define UIP_CONF_DS6_PREFIX_NBU 5 @@ -169,7 +176,7 @@ typedef unsigned short uip_stats_t; #define UIP_CONF_DS6_ADDR_NBU 10 #define UIP_CONF_DS6_MADDR_NBU 0 #define UIP_CONF_DS6_AADDR_NBU 0 -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ typedef unsigned long clock_time_t; #define CLOCK_CONF_SECOND 1000 diff --git a/platform/minimal-net/contiki-main.c b/platform/minimal-net/contiki-main.c index d8158605e..90d700876 100644 --- a/platform/minimal-net/contiki-main.c +++ b/platform/minimal-net/contiki-main.c @@ -54,9 +54,17 @@ #endif /* __CYGWIN__ */ #ifdef __CYGWIN__ +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 PROCINIT(&etimer_process, &tcpip_process, &wpcap_process, &serial_line_process); +#else +PROCINIT(&etimer_process, &wpcap_process, &serial_line_process); +#endif #else /* __CYGWIN__ */ +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 PROCINIT(&etimer_process, &tapdev_process, &tcpip_process, &serial_line_process); +#else +PROCINIT(&etimer_process, &tapdev_process, &serial_line_process); +#endif #endif /* __CYGWIN__ */ #if RPL_BORDER_ROUTER @@ -135,7 +143,7 @@ PROCESS_THREAD(border_router_process, ev, data) } #endif /* RPL_BORDER_ROUTER */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /*---------------------------------------------------------------------------*/ static void sprint_ip6(uip_ip6addr_t addr) @@ -174,7 +182,7 @@ sprint_ip6(uip_ip6addr_t addr) *result=0; printf("%s", thestring); } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ /*---------------------------------------------------------------------------*/ int contiki_argc = 0; char **contiki_argv; @@ -198,7 +206,7 @@ main(int argc, char **argv) #endif clock_init(); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 /* A hard coded address overrides the stack default MAC address to allow multiple instances. uip6.c defines it as {0x00,0x06,0x98,0x00,0x02,0x32} giving an ipv6 address of @@ -229,7 +237,7 @@ main(int argc, char **argv) } } #endif /* HARD_CODED_ADDRESS */ -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ process_init(); /* procinit_init initializes RPL which sets a ctimer for the first DIS */ @@ -248,7 +256,7 @@ main(int argc, char **argv) autostart_start(autostart_processes); /* Set default IP addresses if not specified */ -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 { uip_ipaddr_t addr; @@ -273,7 +281,7 @@ main(int argc, char **argv) } printf("Def. Router: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr)); } -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ #if !UIP_CONF_IPV6_RPL { @@ -281,7 +289,7 @@ main(int argc, char **argv) #ifdef HARD_CODED_ADDRESS uiplib_ipaddrconv(HARD_CODED_ADDRESS, &ipaddr); #else - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); #endif if((ipaddr.u16[0] != 0) || (ipaddr.u16[1] != 0) || @@ -305,7 +313,7 @@ main(int argc, char **argv) } #endif /* !UIP_CONF_IPV6_RPL */ -#endif /* !UIP_CONF_IPV6 */ +#endif /* !NETSTACK_CONF_WITH_IPV6 */ // procinit_init(); // autostart_start(autostart_processes); @@ -315,7 +323,7 @@ main(int argc, char **argv) printf("\n*******%s online*******\n",CONTIKI_VERSION_STRING); -#if UIP_CONF_IPV6 && !RPL_BORDER_ROUTER /* Border router process prints addresses later */ +#if NETSTACK_CONF_WITH_IPV6 && !RPL_BORDER_ROUTER /* Border router process prints addresses later */ { int i = 0; int interface_count = 0; diff --git a/platform/native/Makefile.native b/platform/native/Makefile.native index cda1488c1..504c91a3a 100644 --- a/platform/native/Makefile.native +++ b/platform/native/Makefile.native @@ -6,10 +6,6 @@ ifeq ($(HOST_OS),Darwin) AROPTS = rc endif -ifeq ($(UIP_CONF_IPV6),1) -CFLAGS += -DWITH_UIP6=1 -endif - CONTIKI_TARGET_DIRS = . dev ctk CONTIKI_TARGET_MAIN = ${addprefix $(OBJECTDIR)/,contiki-main.o} @@ -21,9 +17,9 @@ ifeq ($(HOST_OS),Windows) CONTIKI_TARGET_SOURCEFILES += wpcap-drv.c wpcap.c TARGET_LIBFILES = /lib/w32api/libws2_32.a /lib/w32api/libiphlpapi.a else -CONTIKI_TARGET_SOURCEFILES += tapdev-drv.c +CONTIKI_TARGET_SOURCEFILES += tapdev-drv.c linuxradio-drv.c #math -ifneq ($(UIP_CONF_IPV6),1) +ifneq ($(CONTIKI_WITH_IPV6),1) CONTIKI_TARGET_SOURCEFILES += tapdev.c else CONTIKI_TARGET_SOURCEFILES += tapdev6.c @@ -46,5 +42,4 @@ CURSES_LIBS ?= -lncurses TARGET_LIBFILES += $(CURSES_LIBS) -MODULES+=core/net/ip core/net/ipv4 core/net core/net/ipv6 core/net/rime \ - core/net/mac core/net/rpl core/ctk +MODULES+=core/net core/net/mac core/ctk core/net/llsec core/net/ip64-addr/ diff --git a/platform/native/cfs-coffee-arch.h b/platform/native/cfs-coffee-arch.h index d7622cd46..763e1ebae 100644 --- a/platform/native/cfs-coffee-arch.h +++ b/platform/native/cfs-coffee-arch.h @@ -55,7 +55,6 @@ #define COFFEE_LOG_SIZE 8192 #define COFFEE_LOG_TABLE_LIMIT 256 #define COFFEE_MICRO_LOGS 0 -#define COFFEE_IO_SEMANTICS 1 #define COFFEE_WRITE(buf, size, offset) \ xmem_pwrite((char *)(buf), (size), COFFEE_START + (offset)) diff --git a/platform/native/contiki-conf.h b/platform/native/contiki-conf.h index 54fc8e9e2..03eacbbde 100644 --- a/platform/native/contiki-conf.h +++ b/platform/native/contiki-conf.h @@ -46,7 +46,6 @@ int select_set_callback(int fd, const struct select_callback *callback); #define CC_CONF_REGISTER_ARGS 1 #define CC_CONF_FUNCTION_POINTER_ARGS 1 -#define CC_CONF_FASTCALL #define CC_CONF_VA_ARGS 1 /*#define CC_CONF_INLINE inline*/ @@ -79,7 +78,7 @@ typedef unsigned short uip_stats_t; #define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 #endif /* NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE */ -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #define LINKADDR_CONF_SIZE 8 @@ -101,31 +100,21 @@ typedef unsigned short uip_stats_t; #define NETSTACK_CONF_NETWORK sicslowpan_driver -#define UIP_CONF_ROUTER 1 -#ifndef UIP_CONF_IPV6_RPL -#define UIP_CONF_IPV6_RPL 1 -#endif /* UIP_CONF_IPV6_RPL */ +#define NETSTACK_CONF_LINUXRADIO_DEV "wpan0" + +#define UIP_CONF_ROUTER 1 -#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 -#define SICSLOWPAN_CONF_COMPRESSION_HC1 1 -#define SICSLOWPAN_CONF_COMPRESSION_HC01 2 #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #ifndef SICSLOWPAN_CONF_FRAG #define SICSLOWPAN_CONF_FRAG 1 #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ -#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ #define UIP_CONF_IPV6_CHECKS 1 #define UIP_CONF_IPV6_QUEUE_PKT 1 #define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_NETIF_MAX_ADDRESSES 3 -#define UIP_CONF_ND6_MAX_PREFIXES 3 -#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ICMP6 1 /* configure number of neighbors and routes */ @@ -165,7 +154,7 @@ typedef unsigned short uip_stats_t; -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #include #define ctk_arch_isprint isprint diff --git a/platform/native/contiki-main.c b/platform/native/contiki-main.c index e0e2f2012..9c4639b16 100644 --- a/platform/native/contiki-main.c +++ b/platform/native/contiki-main.c @@ -31,10 +31,22 @@ * */ +/** + * \ingroup platform + * + * \defgroup native_platform Native platform + * + * Platform running in the host (Windows or Linux) environment. + * + * Used mainly for development and debugging. + * @{ + */ + #include #include #include #include +#include #ifdef __CYGWIN__ #include "net/wpcap-drv.h" @@ -54,9 +66,9 @@ #include "dev/pir-sensor.h" #include "dev/vib-sensor.h" -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 #include "net/ipv6/uip-ds6.h" -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #include "net/rime/rime.h" @@ -72,7 +84,9 @@ static int select_max = 0; SENSORS(&pir_sensor, &vib_sensor, &button_sensor); static uint8_t serial_id[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}; +#if !NETSTACK_CONF_WITH_IPV6 static uint16_t node_id = 0x0102; +#endif /* !NETSTACK_CONF_WITH_IPV6 */ /*---------------------------------------------------------------------------*/ int select_set_callback(int fd, const struct select_callback *callback) @@ -133,7 +147,7 @@ set_rime_addr(void) int i; memset(&addr, 0, sizeof(linkaddr_t)); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(addr.u8, serial_id, sizeof(addr.u8)); #else if(node_id == 0) { @@ -161,7 +175,7 @@ char **contiki_argv; int main(int argc, char **argv) { -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 #if UIP_CONF_IPV6_RPL printf(CONTIKI_VERSION_STRING " started with IPV6, RPL\n"); #else @@ -190,6 +204,7 @@ main(int argc, char **argv) process_init(); process_start(&etimer_process, NULL); ctimer_init(); + rtimer_init(); #if WITH_GUI process_start(&ctk_process, NULL); @@ -197,12 +212,12 @@ main(int argc, char **argv) set_rime_addr(); - queuebuf_init(); - netstack_init(); printf("MAC %s RDC %s NETWORK %s\n", NETSTACK_MAC.name, NETSTACK_RDC.name, NETSTACK_NETWORK.name); -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 + queuebuf_init(); + memcpy(&uip_lladdr.addr, serial_id, sizeof(uip_lladdr.addr)); process_start(&tcpip_process, NULL); @@ -223,7 +238,7 @@ main(int argc, char **argv) printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]); } -#else +#elif NETSTACK_CONF_WITH_IPV4 process_start(&tcpip_process, NULL); #endif @@ -259,7 +274,9 @@ main(int argc, char **argv) retval = select(maxfd + 1, &fdr, &fdw, NULL, &tv); if(retval < 0) { - perror("select"); + if(errno != EINTR) { + perror("select"); + } } else if(retval > 0) { /* timeout => retval == 0 */ for(i = 0; i <= maxfd; i++) { @@ -293,3 +310,5 @@ uip_log(char *m) fprintf(stderr, "%s\n", m); } /*---------------------------------------------------------------------------*/ +/** @} */ + diff --git a/platform/native/dev/beep.h b/platform/native/dev/beep.h index c2ab7d3f7..f02db7481 100644 --- a/platform/native/dev/beep.h +++ b/platform/native/dev/beep.h @@ -29,8 +29,9 @@ * This file is part of the Contiki operating system. * */ + /** - * \addtogroup esb + * \addtogroup native_platform * @{ */ diff --git a/platform/nrf52dk/Makefile.nrf52dk b/platform/nrf52dk/Makefile.nrf52dk new file mode 100644 index 000000000..8fa911cc4 --- /dev/null +++ b/platform/nrf52dk/Makefile.nrf52dk @@ -0,0 +1,34 @@ +ifndef CONTIKI + $(error CONTIKI not defined! You must specify where CONTIKI resides!) +endif + +### Include the board-specific makefile +PLATFORM_ROOT_DIR = $(CONTIKI)/platform/$(TARGET) + +CONTIKI_TARGET_DIRS += . dev config +CONTIKI_SOURCEFILES += contiki-main.c leds-arch.c nrf52dk-sensors.c button-sensor.c temperature-sensor.c + +ifeq ($(NRF52_USE_RTT),1) +### Use the existing debug I/O in cpu/arm/common +CONTIKI_TARGET_DIRS += rtt +CONTIKI_SOURCEFILES += rtt-printf.c segger-rtt.c segger-rtt-printf.c +else +CONTIKI_TARGET_DIRS += dbg-io +CONTIKI_SOURCEFILES += dbg.c +CONTIKI_CPU_DIRS += ../arm/common/dbg-io +CONTIKI_CPU_SOURCEFILES += dbg-printf.c dbg-putchar.c dbg-snprintf.c dbg-sprintf.c strformat.c +endif + +CLEAN += *.nrf52dk + +### Unless the example dictates otherwise, build with code size optimisations switched +### off +ifndef SMALL + SMALL = 0 +endif + +### Define the CPU directory and pull in the correct CPU makefile. +CONTIKI_CPU=$(CONTIKI)/cpu/nrf52832 +include $(CONTIKI_CPU)/Makefile.nrf52832 + +MODULES += core/net core/net/mac core/net/llsec diff --git a/platform/nrf52dk/README-BLE-6LoWPAN.md b/platform/nrf52dk/README-BLE-6LoWPAN.md new file mode 100644 index 000000000..e4c9ef5f6 --- /dev/null +++ b/platform/nrf52dk/README-BLE-6LoWPAN.md @@ -0,0 +1,100 @@ +This README contains information how to establish an IPv6 connecton between +Linux BLE router and an IPSP enabled BLE device. + +Prerequisites +============= +In general, any device capable of running Linux operating system, can be used +as a BLE router provided the following conditions are met: + +* Linux Kernel >3.18 is used +* bluez, libcap-ng0, radvd tools are present. + +If a built-in Bluetooth device is not available then Bluetooth 4.0 compatible +USB dongle can be used. + +The following procedures have been tested on Ubuntu 15.10. + +Establishing an IPv6 connection +=============================== +Use the following procedure to establish a connection between an nRF52 device +and Linux router: + +First enable 6LoWPAN module. This is neccessary only once per session: + + # Log in as a root user. + sudo su + + # Mount debugfs file system. + mount -t debugfs none /sys/kernel/debug + + # Load 6LoWPAN module. + modprobe bluetooth_6lowpan + + # Enable the bluetooth 6lowpan module. + echo 1 > /sys/kernel/debug/bluetooth/6lowpan_enable + + # Look for available HCI devices. + hciconfig + + # Reset HCI device - for example hci0 device. + hciconfig hci0 reset + + # Read 00:AA:BB:XX:YY:ZZ address of the nRF5x device. + hcitool lescan + +If you see device name and address in lescan output then you can connect to the +device: + + echo "connect 00:AA:BB:XX:YY:ZZ 1" > /sys/kernel/debug/bluetooth/6lowpan_control + +If above is successful then LED1 will stop blinking and LED2 will switch on. +You can then check the connection using the following commands: + + # Check if bt0 interface is present and up + ifconfig + + # Try to ping the device using its link-local address, for example, on bt0 interface. + ping6 -I bt0 fe80::2aa:bbff:fexx:yyzz + +If you'd like to learn more about the procedure please refer to +[Connecting devices to the router]. + +Distributing routable IPv6 prefix +================================= +In Linux, Router Advertisement Daemon (RADVD) can be used to distribute prefixes +in the network, hance configure routable IPv6 address. + +To configure RADVD create `/etc/radvd.conf` file and paste the following contents: + + interface bt0 + { + AdvSendAdvert on; + prefix 2001:db8::/64 + { + AdvOnLink off; + AdvAutonomous on; + AdvRouterAddr on; + }; + }; + +Next, start RADVD daemon: + + # Set IPv6 forwarding (must be present). + sudo echo 1 > /proc/sys/net/ipv6/conf/all/forwarding + # Run radvd daemon. + sudo service radvd restart + +If successfull then all devices connected to the host will receive +a routable `2001:db8` prefix. + +This can be verified by sending echo request to the full address: + + ping6 -I bt0 2001:db8::2aa:bbff:fexx:yyzz + +where `aa:bbff:fexx:yyzz` is device Bluetooth address. + +If you'd like to learn more about the procedure please refer to +[Distributing a global IPv6 prefix]. + +* [Connecting devices to the router]: http://developer.nordicsemi.com/nRF5_IoT_SDK/doc/0.9.0/html/a00089.html +* [Distributing a global IPv6 prefix]: http://developer.nordicsemi.com/nRF5_IoT_SDK/doc/0.9.0/html/a00090.html \ No newline at end of file diff --git a/platform/nrf52dk/README.md b/platform/nrf52dk/README.md new file mode 100644 index 000000000..236892858 --- /dev/null +++ b/platform/nrf52dk/README.md @@ -0,0 +1,254 @@ +Contiki for nRF52 Development Kit +================================= +This guide's aim is to help you with using Contiki for +Nordic Semiconductor's nRF52 DK. + +The port depends on Nordic Semiconductor IoT SDK for nRF52. +The IoT SDK contains source code and libraries which are +required for successfull port compilation. It also contains +SoftDevice binary driver which is required for BLE operation. +See prerequisites section for details on how to set up the SDK. + +For more information about SoftDevice please refer to the SDK +docummentation [nRF52 Datasheet and SDK documentation]. + +This port supports DK versions PCA10040 and PCA10036. + +Port Features +============= +The following features have been implemented: +* Support for IPv6 over BLE using Contiki 6LoWPAN implementation +* Contiki system clock and rtimers (using 32kHz and 1MHz timers) +* UART driver +* Watchdog driver +* Hardware RNG +* Temperature sensor driver +* DK LED driver +* DK Buttons driver +* Real Time Transfer (RTT) I/O support + +Note that this port supports only IPv6 network stack. + +The port is organized as follows: +* nRF52832 CPU and BLE drivers are located in `cpu/nrf52832` folder +* nRF52 Development Kit drivers are located in `platform/nrf52dk` folder +* Platform examples are located in `examples/nrf52dk` folder + +Prerequisites and Setup +======================= +In order to compile for the nRF52 DK platform you'll need: + +* nRF5 IOT SDK + https://developer.nordicsemi.com + + Download nRF5 IOT SDK, extract it to a folder of your choice, + and point `NRF52_SDK_ROOT` environmental variable to it, e.g.,: + + ``` + wget https://developer.nordicsemi.com/nRF5_IoT_SDK/nRF5_IoT_SDK_v0.9.x/nrf5_iot_sdk_3288530.zip + unzip nrf5_iot_sdk_3288530.zip -d /path/to/sdk + export NRF52_SDK_ROOT=/path/to/sdk + ``` + +* An ARM compatible toolchain + The port has been tested with GNU Tools for ARM Embedded Processors + version 5.2.1. + + For Ubuntu you can use package version provided by your distribution: + ``` + sudo apt-get install gcc-arm-none-eabi + ``` + + Alternatively, install the toolchain from PPA to get the latest version + of the compiler: https://launchpad.net/~team-gcc-arm-embedded/+archive/ubuntu/ppa + + For other systems please download and install toolchain available at + https://launchpad.net/gcc-arm-embedded + +* GNU make + +* Segger JLink Software for Linux + https://www.segger.com/jlink-software.html + + This package contains tools necessary for programming and debugging nRF52 DK. + + For Ubuntu you can download and install a .deb package. Alternatively download + tar.gz archive and extract it to a folder of your choice. In this case you + need to set `NRF52_JLINK_PATH` environmental variable to point to the + JLink tools location: + + ``` + export NRF52_JLINK_PATH=/path/to/jlink/tools + ``` + + To keep this variable set between sessions please add the above line to your + `rc.local` file. + + In order to access the DK as a regular Linux user create a `99-jlink.rules` + file in your udev rules folder (e.g., `/etc/udev/rules.d/`) and add the + following line to it: + + ``` + ATTRS{idProduct}=="1015", ATTRS{idVendor}=="1366", MODE="0666" + ``` + When installing from a deb package, the `99-jlink.rules` file is added + automatically to /etc/udev/rules.d folder. However, the syntax of the file + doesn't work on newer udev versions. To fix this problem edit this file and + replace ATTR keyword with ATTRS. + +To fully use the platform a BLE enabled router device is needed. Please refer +to `Preqrequisites` section in `README-BLE-6LoWPAN.md` for details. + +Getting Started +=============== +Once all tools are installed it is recommended to start by compiling +and flashing `examples/hello-word` application. This allows to verify +that toolchain setup is correct. + +To compile the example, go to `examples/hello-world` and execute: + + make TARGET=nrf52dk + +If you haven't used the device with Contiki before we advise to +erase the device and flash new SoftDevice: + + make TARGET=nrf52dk erase + make TARGET=nrf52dk softdevice.flash + +If the compilation is completed without errors flash the board: + + make TARGET=nrf52dk hello-world.flash + +The device will start BLE advertising as soon as initialized. By +default the device name is set to 'Contiki nRF52 DK'. To verify +that the device is advertising properly run: + + sudo hcitool lescan + +And observe if the device name appears in the output. Also, observe +if LED1 is blinking what indicates that device is waiting for a connection +from BLE master. + +If device is functioning as expected you can test IPv6 connection +to the device. Please refer to `README-BLE-6LoWPAN.md` on details how to do +this. + +Examples +======== +Examples specific for nRF52 DK can be found in `examples/nrf52dk` folder. Please +refer to README.md in respective examples for detailed description. + +The DK has also been tested with the `examples/hello-world` and `examples/webserver-ipv6` +generic examples. + +Compilation Options +=================== +The Contiki TARGET name for this port is `nrf52dk`, so in order to compile +an application you need to invoke GNU make as follows: + + make TARGET=nrf52dk + +In addition to this port supports the following variables which can be +set on the compilation command line: + +* `NRF52_SDK_ROOT=` + This variable allows to specify a path to the nRF52 SDK which should + be used for the build. + +* `NRF52_WITHOUT_SOFTDEVICE={0|1}` + Disables SoftDevice support if set to 1. By default, SoftDevice support + is used. Note that SoftDevice must be present (flashed) in the device + before you run an application that requires it's presence. + +* `NRF52_USE_RTT={0|1}` + Enables RealTime Terminal I/O. See VCOM and RTT for details. By default, + RTT is disabled and IO is done using Virtual COM port. + +* `NRF52_JLINK_SN=` + Allows to choose a particular DK by its serial number (printed on the + label). This is useful if you have more than one DK connected to your + PC and whish to flash a particular device. + +* `NRF52_DK_REVISION={pca10040|pca10036}` + Allows to specify DK revision. By default, pca10040 is used. + +Compilation Targets +=================== +Invoking make solely with the `TARGET` variable set will build all +applications in a given folder. A particular application can be built +by invoking make with its name as a compilation target: + + make TARGET=nrf52dk hello-world + +In order to flash the application binary to the device use `.flash` +as make target, e.g.: + + make TARGET=nrf52dk hello-world.flash + +In addition, the SoftDevice binary can be flashed to the DK by invoking: + + make TARGET=nrf52dk softdevice.flash + +To remove all build results invoke: + + make TARGET=nrf52dk clean + +The device memory can be erased using: + + make TARGET=nrf52dk erase + +Note, that once the device is erased, the SoftDevice must be programmed again. + +Virtual COM and Real Time Transfer +================================== +By default, the nRF52 DK uses a Virtual COM port to output logs. Once +the DK is plugged in a `/tty/ACM` or `/ttyUSB` device should appear in +your filesystem. A terminal emulator, such as picocom or minicom, can be +used to connect to the device. Default serial port speed is 38400 bps. + +To connect to serial port using picocom invoke: + + picocom -fh -b 38400 --imap lfcrlf /dev/ttyACM0 + +Note, that if you have not fixed file permissions for `/dev/ttyACM0` +according to section `Segger JLink Software for Linux` you'll need to use +root or sudo to open the port with `picocom`. + +In addition to Virtual COM the port supports SEGGER's Real Time Transfer +for low overhead I/O support. This allows for outputting debugging information +at much higher rate with significantly lower overhead than regular I/O. + +To compile an application with RTT rather that VCOM set `NRF52_USE_RTT` to 1 on +the compilation command line: + + make TARGET=nrf52dk NRF52_USE_RTT=1 hello-world + +You can then connect to the device terminal using `JLinkRTTClient`. Note that +a JLlink gdb or commander must be connected to the target for the RTT to work. + +More details regarding RTT can be found at https://www.segger.com/jlink-rtt.html + +Docummentation +============== +This port provides doxygen source code docummentation. To build the +docummentation please run: + + sudo apt-get install doxygen + cd \doc + make + +Support +======= +This port is officially supported by Nordic Semiconductor. Please send bug +reports or/and suggestions to . + +License +======= +All files in the port are under BSD license. nRF52 SDK and SoftDevice are +licensed on a separate terms. + +Resources +========= +* nRF52 Datasheet and SDK documentation (http://infocenter.nordicsemi.com) +* nRF52 SDK Downloads (https://developer.nordicsemi.com/) +* JLink Tools (https://www.segger.com/) \ No newline at end of file diff --git a/platform/nrf52dk/config/nrf_drv_config.h b/platform/nrf52dk/config/nrf_drv_config.h new file mode 100644 index 000000000..cfc3595b2 --- /dev/null +++ b/platform/nrf52dk/config/nrf_drv_config.h @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \addtogroup nrf52dk + * @{ + * + * \defgroup nrf52dk-config nRF52 SDK configuration + * @{ + */ + +#ifndef NRF_DRV_CONFIG_H +#define NRF_DRV_CONFIG_H + +/* CLOCK */ +#define CLOCK_CONFIG_XTAL_FREQ NRF_CLOCK_XTALFREQ_Default +#define CLOCK_CONFIG_LF_SRC NRF_CLOCK_LF_SRC_Xtal +#define CLOCK_CONFIG_LF_RC_CAL_INTERVAL RC_2000MS_CALIBRATION_INTERVAL +#define CLOCK_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +/* GPIOTE */ +#define GPIOTE_ENABLED 1 + +#if (GPIOTE_ENABLED == 1) +#define GPIOTE_CONFIG_USE_SWI_EGU false +#define GPIOTE_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH +#define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 4 +#endif + +/* TIMER */ +#define TIMER0_ENABLED 0 + +#if (TIMER0_ENABLED == 1) +#define TIMER0_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz +#define TIMER0_CONFIG_MODE TIMER_MODE_MODE_Timer +#define TIMER0_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_32Bit +#define TIMER0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define TIMER0_INSTANCE_INDEX 0 +#endif + +#define TIMER1_ENABLED 1 + +#if (TIMER1_ENABLED == 1) +#define TIMER1_CONFIG_FREQUENCY NRF_TIMER_FREQ_62500Hz +#define TIMER1_CONFIG_MODE TIMER_MODE_MODE_Timer +#define TIMER1_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_32Bit +#define TIMER1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define TIMER1_INSTANCE_INDEX (TIMER0_ENABLED) +#endif + +#define TIMER2_ENABLED 0 + +#if (TIMER2_ENABLED == 1) +#define TIMER2_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz +#define TIMER2_CONFIG_MODE TIMER_MODE_MODE_Timer +#define TIMER2_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit +#define TIMER2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define TIMER2_INSTANCE_INDEX (TIMER1_ENABLED+TIMER0_ENABLED) +#endif + +#define TIMER3_ENABLED 0 + +#if (TIMER3_ENABLED == 1) +#define TIMER3_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz +#define TIMER3_CONFIG_MODE TIMER_MODE_MODE_Timer +#define TIMER3_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit +#define TIMER3_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define TIMER3_INSTANCE_INDEX (TIMER2_ENABLED+TIMER2_INSTANCE_INDEX) +#endif + +#define TIMER4_ENABLED 0 + +#if (TIMER4_ENABLED == 1) +#define TIMER4_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz +#define TIMER4_CONFIG_MODE TIMER_MODE_MODE_Timer +#define TIMER4_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit +#define TIMER4_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define TIMER4_INSTANCE_INDEX (TIMER3_ENABLED+TIMER3_INSTANCE_INDEX) +#endif + + +#define TIMER_COUNT (TIMER0_ENABLED + TIMER1_ENABLED + TIMER2_ENABLED + TIMER3_ENABLED + TIMER4_ENABLED) + +/* RTC */ +#define RTC0_ENABLED 0 + +#if (RTC0_ENABLED == 1) +#define RTC0_CONFIG_FREQUENCY 32678 +#define RTC0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define RTC0_CONFIG_RELIABLE false + +#define RTC0_INSTANCE_INDEX 0 +#endif + +#define RTC1_ENABLED 1 + +#if (RTC1_ENABLED == 1) +#define RTC1_CONFIG_FREQUENCY 128 +#define RTC1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define RTC1_CONFIG_RELIABLE false + +#define RTC1_INSTANCE_INDEX (RTC0_ENABLED) +#endif + +#define RTC_COUNT (RTC0_ENABLED+RTC1_ENABLED) + +#define NRF_MAXIMUM_LATENCY_US 2000 + +/* RNG */ +#define RNG_ENABLED 1 + +#if (RNG_ENABLED == 1) +#define RNG_CONFIG_ERROR_CORRECTION true +#define RNG_CONFIG_POOL_SIZE 8 +#define RNG_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#endif + +/* SPI */ +#define SPI0_ENABLED 0 + +#if (SPI0_ENABLED == 1) +#define SPI0_USE_EASY_DMA 0 + +#define SPI0_CONFIG_SCK_PIN 2 +#define SPI0_CONFIG_MOSI_PIN 3 +#define SPI0_CONFIG_MISO_PIN 4 +#define SPI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define SPI0_INSTANCE_INDEX 0 +#endif + +#define SPI1_ENABLED 0 + +#if (SPI1_ENABLED == 1) +#define SPI1_USE_EASY_DMA 0 + +#define SPI1_CONFIG_SCK_PIN 2 +#define SPI1_CONFIG_MOSI_PIN 3 +#define SPI1_CONFIG_MISO_PIN 4 +#define SPI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define SPI1_INSTANCE_INDEX (SPI0_ENABLED) +#endif + +#define SPI2_ENABLED 0 + +#if (SPI2_ENABLED == 1) +#define SPI2_USE_EASY_DMA 0 + +#define SPI2_CONFIG_SCK_PIN 2 +#define SPI2_CONFIG_MOSI_PIN 3 +#define SPI2_CONFIG_MISO_PIN 4 +#define SPI2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define SPI2_INSTANCE_INDEX (SPI0_ENABLED + SPI1_ENABLED) +#endif + +#define SPI_COUNT (SPI0_ENABLED + SPI1_ENABLED + SPI2_ENABLED) + +/* UART */ +#define UART0_ENABLED 1 + +#if (UART0_ENABLED == 1) +#define UART0_CONFIG_HWFC NRF_UART_HWFC_DISABLED +#define UART0_CONFIG_PARITY NRF_UART_PARITY_EXCLUDED +#define UART0_CONFIG_BAUDRATE NRF_UART_BAUDRATE_38400 +#define UART0_CONFIG_PSEL_TXD 6 +#define UART0_CONFIG_PSEL_RXD 8 +#define UART0_CONFIG_PSEL_CTS 7 +#define UART0_CONFIG_PSEL_RTS 5 +#define UART0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#ifdef NRF52 +#define UART0_CONFIG_USE_EASY_DMA false +//Compile time flag +#define UART_EASY_DMA_SUPPORT 1 +#define UART_LEGACY_SUPPORT 1 +#endif //NRF52 +#endif + +#define TWI0_ENABLED 0 + +#if (TWI0_ENABLED == 1) +#define TWI0_CONFIG_FREQUENCY NRF_TWI_FREQ_100K +#define TWI0_CONFIG_SCL 0 +#define TWI0_CONFIG_SDA 1 +#define TWI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH + +#define TWI0_INSTANCE_INDEX 0 +#endif + +#define TWI1_ENABLED 0 + +#if (TWI1_ENABLED == 1) +#define TWI1_CONFIG_FREQUENCY NRF_TWI_FREQ_100K +#define TWI1_CONFIG_SCL 0 +#define TWI1_CONFIG_SDA 1 +#define TWI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH + +#define TWI1_INSTANCE_INDEX (TWI0_ENABLED) +#endif + +#define TWI_COUNT (TWI0_ENABLED+TWI1_ENABLED) + +/* TWIS */ +#define TWIS0_ENABLED 0 + +#if (TWIS0_ENABLED == 1) + #define TWIS0_CONFIG_ADDR0 0 + #define TWIS0_CONFIG_ADDR1 0 /* 0: Disabled */ + #define TWIS0_CONFIG_SCL 0 + #define TWIS0_CONFIG_SDA 1 + #define TWIS0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH + + #define TWIS0_INSTANCE_INDEX 0 +#endif + +#define TWIS1_ENABLED 0 + +#if (TWIS1_ENABLED == 1) + #define TWIS1_CONFIG_ADDR0 0 + #define TWIS1_CONFIG_ADDR1 0 /* 0: Disabled */ + #define TWIS1_CONFIG_SCL 0 + #define TWIS1_CONFIG_SDA 1 + #define TWIS1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH + + #define TWIS1_INSTANCE_INDEX (TWIS0_ENABLED) +#endif + +#define TWIS_COUNT (TWIS0_ENABLED + TWIS1_ENABLED) +/* For more documentation see nrf_drv_twis.h file */ +#define TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 +/* For more documentation see nrf_drv_twis.h file */ +#define TWIS_NO_SYNC_MODE 0 +/** + * \brief Definition for patching PAN problems + * + * Set this definition to nonzero value to patch anomalies + * from MPW3 - first lunch microcontroller. + * + * Concerns: + * - PAN-29: TWIS: incorrect bits in ERRORSRC + * - PAN-30: TWIS: STOP task does not work as expected + */ +#define NRF_TWIS_PATCH_FOR_MPW3 1 + + +/* QDEC */ +#define QDEC_ENABLED 0 + +#if (QDEC_ENABLED == 1) +#define QDEC_CONFIG_REPORTPER NRF_QDEC_REPORTPER_10 +#define QDEC_CONFIG_SAMPLEPER NRF_QDEC_SAMPLEPER_16384us +#define QDEC_CONFIG_PIO_A 1 +#define QDEC_CONFIG_PIO_B 2 +#define QDEC_CONFIG_PIO_LED 3 +#define QDEC_CONFIG_LEDPRE 511 +#define QDEC_CONFIG_LEDPOL NRF_QDEC_LEPOL_ACTIVE_HIGH +#define QDEC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define QDEC_CONFIG_DBFEN false +#define QDEC_CONFIG_SAMPLE_INTEN false +#endif + +/* SAADC */ +#define SAADC_ENABLED 0 + +#if (SAADC_ENABLED == 1) +#define SAADC_CONFIG_RESOLUTION NRF_SAADC_RESOLUTION_10BIT +#define SAADC_CONFIG_OVERSAMPLE NRF_SAADC_OVERSAMPLE_DISABLED +#define SAADC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#endif + +/* LPCOMP */ +#define LPCOMP_ENABLED 0 + +#if (LPCOMP_ENABLED == 1) +#define LPCOMP_CONFIG_REFERENCE NRF_LPCOMP_REF_SUPPLY_4_8 +#define LPCOMP_CONFIG_DETECTION NRF_LPCOMP_DETECT_DOWN +#define LPCOMP_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define LPCOMP_CONFIG_INPUT NRF_LPCOMP_INPUT_0 +#endif + +/* WDT */ +#define WDT_ENABLED 1 + +#if (WDT_ENABLED == 1) +#define WDT_CONFIG_BEHAVIOUR NRF_WDT_BEHAVIOUR_RUN_SLEEP +#define WDT_CONFIG_RELOAD_VALUE 2000 +#define WDT_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH +#endif + +#include "nrf_drv_config_validation.h" +#endif // NRF_DRV_CONFIG_H + +/** + * @} + * @} + */ diff --git a/platform/nrf52dk/config/pstorage_platform.h b/platform/nrf52dk/config/pstorage_platform.h new file mode 100644 index 000000000..3102b2097 --- /dev/null +++ b/platform/nrf52dk/config/pstorage_platform.h @@ -0,0 +1,74 @@ +/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. + * + * The information contained herein is property of Nordic Semiconductor ASA. + * Terms and conditions of usage are described in detail in NORDIC + * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. + * + * Licensees are granted free, non-transferable use of the information. NO + * WARRANTY of ANY KIND is provided. This heading must NOT be removed from + * the file. + * + */ + + /** @cond To make doxygen skip this file */ + +/** @file + * This header contains defines with respect persistent storage that are specific to + * persistent storage implementation and application use case. + */ +#ifndef PSTORAGE_PL_H__ +#define PSTORAGE_PL_H__ + +#include +#include "nrf.h" + +static __INLINE uint16_t pstorage_flash_page_size() +{ + return (uint16_t)NRF_FICR->CODEPAGESIZE; +} + +#define PSTORAGE_FLASH_PAGE_SIZE pstorage_flash_page_size() /**< Size of one flash page. */ +#define PSTORAGE_FLASH_EMPTY_MASK 0xFFFFFFFF /**< Bit mask that defines an empty address in flash. */ + +#ifdef NRF51 +#define BOOTLOADER_ADDRESS (NRF_UICR->BOOTLOADERADDR) +#elif defined NRF52 +#define BOOTLOADER_ADDRESS (PSTORAGE_FLASH_EMPTY_MASK) +#endif + +#define PSTORAGE_FLASH_PAGE_END \ + ((BOOTLOADER_ADDRESS != PSTORAGE_FLASH_EMPTY_MASK) \ + ? (BOOTLOADER_ADDRESS / PSTORAGE_FLASH_PAGE_SIZE) \ + : NRF_FICR->CODESIZE) + + +#define PSTORAGE_NUM_OF_PAGES 2 /**< Number of flash pages allocated for the pstorage module excluding the swap page, configurable based on system requirements. */ +#define PSTORAGE_MIN_BLOCK_SIZE 0x0010 /**< Minimum size of block that can be registered with the module. Should be configured based on system requirements, recommendation is not have this value to be at least size of word. */ + +#define PSTORAGE_DATA_START_ADDR ((PSTORAGE_FLASH_PAGE_END - PSTORAGE_NUM_OF_PAGES - 1) \ + * PSTORAGE_FLASH_PAGE_SIZE) /**< Start address for persistent data, configurable according to system requirements. */ +#define PSTORAGE_DATA_END_ADDR ((PSTORAGE_FLASH_PAGE_END - 1) * PSTORAGE_FLASH_PAGE_SIZE) /**< End address for persistent data, configurable according to system requirements. */ +#define PSTORAGE_SWAP_ADDR PSTORAGE_DATA_END_ADDR /**< Top-most page is used as swap area for clear and update. */ + +#define PSTORAGE_MAX_BLOCK_SIZE PSTORAGE_FLASH_PAGE_SIZE /**< Maximum size of block that can be registered with the module. Should be configured based on system requirements. And should be greater than or equal to the minimum size. */ +#define PSTORAGE_CMD_QUEUE_SIZE 30 /**< Maximum number of flash access commands that can be maintained by the module for all applications. Configurable. */ + + +/** Abstracts persistently memory block identifier. */ +typedef uint32_t pstorage_block_t; + +typedef struct +{ + uint32_t module_id; /**< Module ID.*/ + pstorage_block_t block_id; /**< Block ID.*/ +} pstorage_handle_t; + +typedef uint16_t pstorage_size_t; /** Size of length and offset fields. */ + +/**\brief Handles Flash Access Result Events. To be called in the system event dispatcher of the application. */ +void pstorage_sys_event_handler (uint32_t sys_evt); + +#endif // PSTORAGE_PL_H__ + +/** @} */ +/** @endcond */ diff --git a/platform/nrf52dk/contiki-conf.h b/platform/nrf52dk/contiki-conf.h new file mode 100644 index 000000000..6303c90db --- /dev/null +++ b/platform/nrf52dk/contiki-conf.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \addtogroup nrf52dk + * @{ + * + * \addtogroup nrf52dk-contikic-conf Contiki configuration + * @{ + * + * \file + * Contiki configuration for the nRF52 DK + */ +#ifndef CONTIKI_CONF_H +#define CONTIKI_CONF_H + +#include +/*---------------------------------------------------------------------------*/ +/* Include Project Specific conf */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif /* PROJECT_CONF_H */ +/*---------------------------------------------------------------------------*/ +/* Include platform peripherals configuration */ +#include "platform-conf.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Network Stack Configuration + * + * @{ + */ +#ifndef NETSTACK_CONF_NETWORK +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#endif /* NETSTACK_CONF_NETWORK */ + +#ifndef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC ble_ipsp_mac_driver +#endif /* NETSTACK_CONF_MAC */ + +/* 6LoWPAN */ +#define SICSLOWPAN_CONF_MAC_MAX_PAYLOAD 1280 +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 0 /**< Always compress IPv6 packets. */ +#define SICSLOWPAN_CONF_FRAG 0 /**< We don't use 6LoWPAN fragmentation as IPSP takes care of that for us.*/ +#define SICSLOWPAN_FRAMER_HDRLEN 0 /**< Use fixed header len rather than framer.length() function */ + +/* Packet buffer */ +#define PACKETBUF_CONF_SIZE 1280 /**< Required IPv6 MTU size */ +/** @} */ + +/** + * \name BLE configuration + * @{ + */ +#ifndef DEVICE_NAME +#define DEVICE_NAME "Contiki nRF52dk" /**< Device name used in BLE undirected advertisement. */ +#endif +/** + * @} + */ + +/** + * \name IPv6 network buffer configuration + * + * @{ + */ +/* Don't let contiki-default-conf.h decide if we are an IPv6 build */ +#ifndef NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_WITH_IPV6 0 +#endif + +#if NETSTACK_CONF_WITH_IPV6 +/*---------------------------------------------------------------------------*/ +/* Addresses, Sizes and Interfaces */ +#define LINKADDR_CONF_SIZE 8 +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 + +/* The size of the uIP main buffer */ +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 1280 +#endif + +/* ND and Routing */ +#define UIP_CONF_ROUTER 0 /**< BLE master role, which allows for routing, isn't supported. */ +#define UIP_CONF_ND6_SEND_NA 1 +#define UIP_CONF_IP_FORWARD 0 /**< No packet forwarding. */ + +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#endif + +#ifndef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 20 +#endif + +#ifndef UIP_CONF_TCP +#define UIP_CONF_TCP 1 +#endif + +#ifndef UIP_CONF_TCP_MSS +#define UIP_CONF_TCP_MSS 64 +#endif + +#define UIP_CONF_UDP 1 +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_ICMP6 1 +#endif /* NETSTACK_CONF_WITH_IPV6 */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Generic Configuration directives + * + * @{ + */ +#ifndef ENERGEST_CONF_ON +#define ENERGEST_CONF_ON 1 /**< Energest Module */ +#endif +/** @} */ +#endif /* CONTIKI_CONF_H */ +/** + * @} + * @} + */ diff --git a/platform/nrf52dk/contiki-main.c b/platform/nrf52dk/contiki-main.c new file mode 100644 index 000000000..9181d7faf --- /dev/null +++ b/platform/nrf52dk/contiki-main.c @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup nrf52dk nRF52 Development Kit + * @{ + */ +#include +#include + +#include "nordic_common.h" +#include "nrf_drv_config.h" +#include "nrf_drv_gpiote.h" +#ifdef SOFTDEVICE_PRESENT +#include "softdevice_handler.h" +#include "ble/ble-core.h" +#include "ble/ble-mac.h" +#endif + +#include "contiki.h" +#include "contiki-net.h" +#include "leds.h" +#include "lib/sensors.h" + +#include "dev/watchdog.h" +#include "dev/serial-line.h" +#include "dev/uart0.h" +#include "dev/lpm.h" + +#define DEBUG 0 + +#if NETSTACK_CONF_WITH_IPV6 +#include "uip-debug.h" +#include "net/ipv6/uip-ds6.h" +#else +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +#endif + +#if defined(SOFTDEVICE_PRESENT) && PLATFORM_INDICATE_BLE_STATE +PROCESS(ble_iface_observer, "BLE interface observer"); + +/** + * \brief A process that handles adding/removing + * BLE IPSP interfaces. + */ +PROCESS_THREAD(ble_iface_observer, ev, data) +{ + static struct etimer led_timer; + + PROCESS_BEGIN(); + + etimer_set(&led_timer, CLOCK_SECOND/2); + + while(1) { + PROCESS_WAIT_EVENT(); + if(ev == ble_event_interface_added) { + etimer_stop(&led_timer); + leds_off(LEDS_1); + leds_on(LEDS_2); + } else if(ev == ble_event_interface_deleted) { + etimer_set(&led_timer, CLOCK_SECOND/2); + leds_off(LEDS_2); + } else if(ev == PROCESS_EVENT_TIMER && etimer_expired(&led_timer)) { + etimer_reset(&led_timer); + leds_toggle(LEDS_1); + } + } + PROCESS_END(); +} +#endif +/*---------------------------------------------------------------------------*/ +/** + * \brief Board specific initialization + * + * This function will enable SoftDevice is present. + */ +static void +board_init(void) +{ +#ifdef SOFTDEVICE_PRESENT + /* Initialize the SoftDevice handler module */ + SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, NULL); +#endif +#ifdef PLATFORM_HAS_BUTTON + if (!nrf_drv_gpiote_is_init()) { + nrf_drv_gpiote_init(); + } +#endif +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Main function for nRF52dk platform. + * \note This function doesn't return. + */ +int +main(void) +{ + board_init(); + leds_init(); + + clock_init(); + rtimer_init(); + + watchdog_init(); + process_init(); + + // Seed value is ignored since hardware RNG is used. + random_init(0); + +#ifdef UART0_ENABLED + uart0_init(); +#if SLIP_ARCH_CONF_ENABLE + slip_arch_init(0); +#else + uart0_set_input(serial_line_input_byte); + serial_line_init(); +#endif +#endif + + PRINTF("Starting " CONTIKI_VERSION_STRING "\n"); + + process_start(&etimer_process, NULL); + ctimer_init(); + +#if ENERGEST_CONF_ON + energest_init(); + ENERGEST_ON(ENERGEST_TYPE_CPU); +#endif + +#ifdef SOFTDEVICE_PRESENT + ble_stack_init(); + ble_advertising_init(DEVICE_NAME); + +#if NETSTACK_CONF_WITH_IPV6 + netstack_init(); + linkaddr_t linkaddr; + ble_get_mac(linkaddr.u8); + /* Set link layer address */ + linkaddr_set_node_addr(&linkaddr); + /* Set device link layer address in uip stack */ + memcpy(&uip_lladdr.addr, &linkaddr, sizeof(uip_lladdr.addr)); + process_start(&ble_iface_observer, NULL); + process_start(&tcpip_process, NULL); +#endif /* NETSTACK_CONF_WITH_IPV6 */ +#endif /* SOFTDEVICE_PRESENT */ + + process_start(&sensors_process, NULL); + autostart_start(autostart_processes); + + watchdog_start(); + +#ifdef SOFTDEVICE_PRESENT + ble_advertising_start(); + PRINTF("Advertising name [%s]\n", DEVICE_NAME); +#endif + + while(1) { + uint8_t r; + do { + r = process_run(); + watchdog_periodic(); + } while(r > 0); + + lpm_drop(); + } +} +/** + * @} + */ diff --git a/platform/nrf52dk/dbg-io/dbg.c b/platform/nrf52dk/dbg-io/dbg.c new file mode 100644 index 000000000..db9bb63c0 --- /dev/null +++ b/platform/nrf52dk/dbg-io/dbg.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \addtogroup nrf52dk + * @{ + * + * \addtogroup nrf52dk-dbg-io Debug IO over UART + * @{ + * + * \file + * Function implementations for debug io module. + * \author + * Wojciech Bober + * + */ +#include "dev/uart0.h" +/*---------------------------------------------------------------------------*/ +unsigned int +dbg_send_bytes(const unsigned char *s, unsigned int len) +{ + unsigned int i = 0; + + while (s && *s != 0) { + if (i >= len) { + break; + } + uart0_writeb(*s++); + i++; + } + + return i; +} +/*---------------------------------------------------------------------------*/ +int +dbg_putchar(int c) +{ + uart0_writeb(c); + return c; +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/nrf52dk/dbg-io/dbg.h b/platform/nrf52dk/dbg-io/dbg.h new file mode 100644 index 000000000..7c623336b --- /dev/null +++ b/platform/nrf52dk/dbg-io/dbg.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * +3 * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \addtogroup nrf52dk + * @{ + * + * \addtogroup nrf52dk-dbg-io Debug IO over UART + * @{ + * + * \file + * Header file for the debug module. + * \author + * Wojciech Bober + * + */ +#ifndef DBG_H_ +#define DBG_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +/*---------------------------------------------------------------------------*/ +/** + * \brief Print a stream of bytes + * \param seq A pointer to the stream + * \param len The number of bytes to print + * \return The number of printed bytes + */ +unsigned int dbg_send_bytes(const unsigned char *seq, unsigned int len); +/** + * \brief Print a character to debug output + * \param c Character to print + * \return Printed character + */ +int dbg_putchar(int c); +/*---------------------------------------------------------------------------*/ +#endif /* DBG_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/nrf52dk/dbg-io/debug-uart.h b/platform/nrf52dk/dbg-io/debug-uart.h new file mode 100644 index 000000000..b52d2fb50 --- /dev/null +++ b/platform/nrf52dk/dbg-io/debug-uart.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/** + * \addtogroup nrf52dk + * @{ + * + * \addtogroup nrf52dk-dbg-io Debug IO over UART + * @{ + * + * \file + * A header file to maintain compatibility with DBG I/O. + * \author + * Wojciech Bober + * + */ +/*---------------------------------------------------------------------------*/ +#ifndef DEBUG_UART_H_ +#define DEBUG_UART_H_ +/*---------------------------------------------------------------------------*/ +#include "dbg.h" +/*---------------------------------------------------------------------------*/ +#endif /* DEBUG_UART_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/nrf52dk/dev/button-sensor.c b/platform/nrf52dk/dev/button-sensor.c new file mode 100644 index 000000000..3c218a439 --- /dev/null +++ b/platform/nrf52dk/dev/button-sensor.c @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup nrf52dk-devices Device drivers + * @{ + * + * \addtogroup nrf52dk-devices-button Buttons driver + * @{ + * + * \file + * Driver for nRF52 DK buttons. + * \author + * Wojciech Bober + */ +/*---------------------------------------------------------------------------*/ +#include +#include "nordic_common.h" +#include "nrf_drv_gpiote.h" +#include "nrf_assert.h" +#include "boards.h" +#include "contiki.h" +#include "lib/sensors.h" +#include "button-sensor.h" + +/*---------------------------------------------------------------------------*/ +#define DEBOUNCE_DURATION (CLOCK_SECOND >> 5) /**< Delay before button state is assumed to be stable */ + +/*---------------------------------------------------------------------------*/ +struct btn_timer +{ + struct timer debounce; + clock_time_t start; + clock_time_t duration; +}; + +static struct btn_timer btn_timer[BUTTONS_NUMBER]; +static int btn_state = 0; + +/*---------------------------------------------------------------------------*/ +/** + * \brief Button toggle handler + * \param pin GPIO pin which has been triggered + * \param action toggle direction + * + */ +static void +gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) +{ + int id = pin - BUTTON_START; + + if(!timer_expired(&(btn_timer[id].debounce))) { + return; + } + + /* Set timer to ignore consecutive changes for + * DEBOUNCE_DURATION. + */ + timer_set(&(btn_timer[id].debounce), DEBOUNCE_DURATION); + + /* + * Start measuring duration on falling edge, stop on rising edge. + */ + if(nrf_drv_gpiote_in_is_set(pin) == 0) { + btn_timer[id].start = clock_time(); + btn_timer[id].duration = 0; + } else { + btn_timer[id].duration = clock_time() - btn_timer[id].start; + } + sensors_changed(&buttons[id]); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the button sensor for all buttons. + * + * \param type if \a SENSORS_HW_INIT is passed the function will initialize + * given button + * if \a SENSORS_ACTIVE is passed then \p c parameter defines + * whether button should be set active or inactive + * \param c 0 to disable the button, non-zero: enable + * \param pin GPIOE pin number + */ +static int +config(int type, int c, nrf_drv_gpiote_pin_t pin) +{ + int id = pin - BUTTON_START; + + switch(type) { + case SENSORS_HW_INIT: { + nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false); + config.pull = NRF_GPIO_PIN_PULLUP; + nrf_drv_gpiote_in_init(pin, &config, gpiote_event_handler); + timer_set(&(btn_timer[id].debounce), DEBOUNCE_DURATION); + return 1; + } + case SENSORS_ACTIVE: { + if(c) { + nrf_drv_gpiote_in_event_enable(pin, true); + btn_state |= (1 << id); + } else { + nrf_drv_gpiote_in_event_disable(pin); + btn_state &= ~(1 << id); + } + return 1; + } + default: + return 0; + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for button 1 + * + * \param type passed to config() as-is + * \param value passed to config() as-is + * \return same as config() return value + */ +static int +config_button_1(int type, int value) +{ + return config(type, value, BSP_BUTTON_0); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for button 2 + * + * \param type passed to config() as-is + * \param value passed to config() as-is + * \return same as config() return value + */ +static int +config_button_2(int type, int value) +{ + return config(type, value, BSP_BUTTON_1); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for button 3 + * + * \param type passed to config() as-is + * \param value passed to config() as-is + * \return same as config() return value + */ +static int +config_button_3(int type, int value) +{ + return config(type, value, BSP_BUTTON_2); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for button 4 + * + * \param type passed to config() as-is + * \param value passed to config() as-is + * \return same as config() return value + */ +static int +config_button_4(int type, int value) +{ + return config(type, value, BSP_BUTTON_3); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Return current state of a button + * \param type pass \ref BUTTON_SENSOR_VALUE_STATE to get current button state + * or \ref BUTTON_SENSOR_VALUE_DURATION to get active state duration + * \param pin GPIOE pin number + * + * \retval BUTTON_SENSOR_VALUE_PRESSED + * \retval BUTTON_SENSOR_VALUE_RELEASED when \a type is \ref BUTTON_SENSOR_VALUE_STATE + * \retval duration Active state duration in clock ticks + */ +static int +value(int type, nrf_drv_gpiote_pin_t pin) +{ + + if(type == BUTTON_SENSOR_VALUE_STATE) { + return nrf_drv_gpiote_in_is_set(pin) == 0 ? + BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; + } else if(type == BUTTON_SENSOR_VALUE_DURATION) { + return btn_timer[pin - BUTTON_START].duration; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Return current state of a button 1 + * \param type passed to value() as-is + * \return same as value returned by value() + */ +static int +value_button_1(int type) +{ + return value(type, BSP_BUTTON_0); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Return current state of a button 2 + * \param type passed to value() as-is + * \return same as value returned by value() + */ +static int +value_button_2(int type) +{ + return value(type, BSP_BUTTON_1); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Return current state of a button 3 + * \param type passed to value() as-is + * \return same as value returned by value() + */ +static int +value_button_3(int type) +{ + return value(type, BSP_BUTTON_2); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Return current state of a button 4 + * \param type passed to value() as-is + * \return same as value returned by value() + */ +static int +value_button_4(int type) +{ + return value(type, BSP_BUTTON_3); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Get status of a given button + * \param type \a SENSORS_ACTIVE or \a SENSORS_READY + * \param pin GPIOE pin number + * \return 1 if the button's port interrupt is enabled + */ +static int +status(int type, nrf_drv_gpiote_pin_t pin) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return (btn_state & (1 << (pin - BUTTON_START))); + default: + break; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for button 1 + * \param type passed to state() as-is + * \return value returned by state() + */ +static int +status_button_1(int type) +{ + return status(type, BSP_BUTTON_0); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for button 2 + * \param type passed to state() as-is + * \return value returned by state() + */ +static int +status_button_2(int type) +{ + return status(type, BSP_BUTTON_1); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for button 3 + * \param type passed to state() as-is + * \return value returned by state() + */ +static int +status_button_3(int type) +{ + return status(type, BSP_BUTTON_2); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for button 3 + * \param type passed to state() as-is + * \return value returned by state() + */ +static int +status_button_4(int type) +{ + return status(type, BSP_BUTTON_3); +} +/*---------------------------------------------------------------------------*/ +const struct sensors_sensor buttons[BUTTONS_NUMBER] = { + {BUTTON_SENSOR, value_button_1, config_button_1, status_button_1}, + {BUTTON_SENSOR, value_button_2, config_button_2, status_button_2}, + {BUTTON_SENSOR, value_button_3, config_button_3, status_button_3}, + {BUTTON_SENSOR, value_button_4, config_button_4, status_button_4}, }; +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/nrf52dk/dev/button-sensor.h b/platform/nrf52dk/dev/button-sensor.h new file mode 100644 index 000000000..ababb1c1c --- /dev/null +++ b/platform/nrf52dk/dev/button-sensor.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup nrf52dk-devices Device drivers + * @{ + * + * \addtogroup nrf52dk-devices-button Buttons driver + * @{ + * + * \file + * Header file for the nRF52dk button driver. + * \author + * Wojciech Bober + * + */ +/*---------------------------------------------------------------------------*/ +#ifndef BUTTON_SENSOR_H_ +#define BUTTON_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR "Button" +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR_VALUE_STATE 0 /**< Can be passed to value() function + to get current button state */ +#define BUTTON_SENSOR_VALUE_DURATION 1 /**< Can be passed to value() function + to get low state duration */ + +#define BUTTON_SENSOR_VALUE_RELEASED 0 +#define BUTTON_SENSOR_VALUE_PRESSED 1 +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor buttons[]; +/*---------------------------------------------------------------------------*/ +#define button_1 buttons[0] +#define button_2 buttons[1] +#define button_3 buttons[2] +#define button_4 buttons[3] +/*---------------------------------------------------------------------------*/ +#endif /* BUTTON_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/examples/z1sp/test-potentiometer.c b/platform/nrf52dk/dev/leds-arch.c similarity index 70% rename from examples/z1sp/test-potentiometer.c rename to platform/nrf52dk/dev/leds-arch.c index 7a2881d80..019589493 100644 --- a/examples/z1sp/test-potentiometer.c +++ b/platform/nrf52dk/dev/leds-arch.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Zolertia(TM) is a trademark of Advancare,SL + * Copyright (c) 2015, Nordic Semiconductor * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,43 +26,52 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * This file is part of the Contiki operating system. - * */ /** + * \addtogroup nrf52dk + * @{ + * + * \addtogroup nrf52dk-devices Device drivers + * @{ + * + * \addtogroup nrf52dk-devices-led LED driver + * @{ + * * \file - * Testing the Potentiometer in Zolertia Z1 Starter Platform. + * Architecture specific LED driver implementation for nRF52 DK. * \author - * Enric M. Calvo + * Wojciech Bober */ - +#include "boards.h" #include "contiki.h" -#include "dev/potentiometer-sensor.h" -#include - +#include "dev/leds.h" /*---------------------------------------------------------------------------*/ -PROCESS(test_potent_process, "Testing Potentiometer in Z1SP"); -AUTOSTART_PROCESSES(&test_potent_process); -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(test_potent_process, ev, data) +void +leds_arch_init(void) { - - PROCESS_BEGIN(); - - SENSORS_ACTIVATE(potentiometer_sensor); - - while(1) { - uint16_t value = potentiometer_sensor.value(0); - - printf("Potentiometer Value: %i\n", v); - } - - SENSORS_DEACTIVATE(potentiometer_sensor); - - PROCESS_END(); + LEDS_CONFIGURE(LEDS_MASK); + LEDS_OFF(LEDS_MASK); +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + return (unsigned char)(LED_IS_ON(LEDS_MASK) >> LED_START); +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char leds) +{ + unsigned int mask = (unsigned int)leds << LED_START; + LEDS_OFF(LEDS_MASK); + LEDS_ON(mask); } - /*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/platform/nrf52dk/dev/nrf52dk-sensors.c b/platform/nrf52dk/dev/nrf52dk-sensors.c new file mode 100644 index 000000000..3d56e91d1 --- /dev/null +++ b/platform/nrf52dk/dev/nrf52dk-sensors.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \addtogroup nrf52dk + * @{ + * + * \addtogroup nrf52dk-devices Device drivers + * @{ + * + * \addtogroup nrf52dk-sensors Sensors + * The nRF52 DK exports 4 button sensors and an internal temperature sensor. + * @{ + * + * \file + * This file exports a global sensors table. + * \author + * Wojciech Bober + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/button-sensor.h" +#include "dev/temperature-sensor.h" +/*---------------------------------------------------------------------------*/ +SENSORS( + &button_1, + &button_2, + &button_3, + &button_4, + &temperature_sensor +); +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/platform/nrf52dk/dev/temperature-sensor.c b/platform/nrf52dk/dev/temperature-sensor.c new file mode 100644 index 000000000..5aac8b3ef --- /dev/null +++ b/platform/nrf52dk/dev/temperature-sensor.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \addtogroup nrf52dk-devices Device drivers + * @{ + * + * \addtogroup nrf52dk-devices-temp Temperature sensor driver + * This is a driver for nRF52832 hardware sensor. + * + * @{ + * + * \file + * Temperature sensor implementation. + * \author + * Wojciech Bober + * + */ +#ifndef SOFTDEVICE_PRESENT +#include "nrf_temp.h" +#else +#include "nrf_soc.h" +#endif +#include "contiki.h" +#include "dev/temperature-sensor.h" + + +const struct sensors_sensor temperature_sensor; + +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns device temperature + * \param type ignored + * \return Device temperature in degrees Celsius + */ +static int +value(int type) +{ +#ifndef SOFTDEVICE_PRESENT + return nrf_temp_read(); +#else + int32_t temp; + sd_temp_get(&temp); + return temp >> 2; +#endif +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configures temperature sensor + * \param type initializes the hardware sensor when \a type is set to + * \a SENSORS_HW_INIT + * \param c ignored + * \return 1 + * \note This function does nothing when SoftDevice is present + */ +static int +configure(int type, int c) +{ +#ifndef SOFTDEVICE_PRESENT + if (type == SENSORS_HW_INIT) { + nrf_temp_init(); + } +#endif + return 1; +} +/** + * \brief Return temperature sensor status + * \param type ignored + * \return 1 + */ +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(temperature_sensor, TEMPERATURE_SENSOR, value, configure, status); +/** + * @} + * @} + */ diff --git a/platform/nrf52dk/dev/temperature-sensor.h b/platform/nrf52dk/dev/temperature-sensor.h new file mode 100644 index 000000000..27b246b2d --- /dev/null +++ b/platform/nrf52dk/dev/temperature-sensor.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \addtogroup nrf52dk-devices Device drivers + * @{ + * + * \addtogroup nrf52dk-devices-temp Temperature sensor driver + * @{ + * + * \file + * Temperature sensor header file. + * \author + * Wojciech Bober + * + */ + +#ifndef TEMPERATURE_SENSOR_H_ +#define TEMPERATURE_SENSOR_H_ + +#include "lib/sensors.h" + +extern const struct sensors_sensor temperature_sensor; + +#define TEMPERATURE_SENSOR "Temperature" + +#endif /* TEMPERATURE_SENSOR_H_ */ + +/** + * @} + * @} + */ diff --git a/platform/nrf52dk/platform-conf.h b/platform/nrf52dk/platform-conf.h new file mode 100644 index 000000000..d40fd2b3e --- /dev/null +++ b/platform/nrf52dk/platform-conf.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \addtogroup platform + * @{ + * + * \addtogroup nrf52dk nRF52 Development Kit + * @{ + * + * \addtogroup nrf52dk-platform-conf Platform configuration + * @{ + * \file + * Platform features configuration. + * \author + * Wojciech Bober + * + */ +#ifndef PLATFORM_CONF_H_ +#define PLATFORM_CONF_H_ + +#include "boards.h" + +#define PLATFORM_HAS_BATTERY 0 +#define PLATFORM_HAS_RADIO 0 +#define PLATFORM_HAS_TEMPERATURE 1 + +/** + * \name Leds configurations + * + * On nRF52dk all leds are green. + * + * @{ + */ +#define PLATFORM_HAS_LEDS 1 + +#define LEDS_1 (1 << (LED_1 - LED_START)) // 1 +#define LEDS_2 (1 << (LED_2 - LED_START)) // 2 +#define LEDS_3 (1 << (LED_3 - LED_START)) // 4 +#define LEDS_4 (1 << (LED_4 - LED_START)) // 8 + +#define LEDS_GREEN LEDS_1 +#define LEDS_YELLOW LEDS_2 +#define LEDS_RED LEDS_3 +#define LEDS_BLUE LEDS_4 + +#define LEDS_CONF_ALL (LEDS_1 | LEDS_2 | LEDS_3 | LEDS_4) + +/** + * \brief If set to 1 then LED1 and LED2 are used by the + * platform to indicate BLE connection state. + */ +#define PLATFORM_INDICATE_BLE_STATE 1 +/** @} */ + +/** + * \name Button configurations + * + * @{ + */ +/* Notify various examples that we have Buttons */ +#define PLATFORM_HAS_BUTTON 1 + +/* + * Override button symbols from dev/button-sensor.h, for the examples that + * include it + */ +#define button_sensor button_1 +#define button_sensor2 button_2 + +/** + * \brief nRF52 RTC instance to be used for Contiki clock driver. + * \note RTC 0 is used by the SoftDevice. + */ +#define PLATFORM_RTC_INSTANCE_ID 1 + +/** + * \brief nRF52 timer instance to be used for Contiki rtimer driver. + * \note Timer 0 is used by the SoftDevice. + */ +#define PLATFORM_TIMER_INSTANCE_ID 1 + +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Compiler configuration and platform-specific type definitions + * + * Those values are not meant to be modified by the user + * @{ + */ +#define CLOCK_CONF_SECOND 128 + +/* Compiler configurations */ +#define CCIF +#define CLIF + +/* Platform typedefs */ +typedef uint32_t clock_time_t; +typedef uint32_t uip_stats_t; + +/* Clock (time) comparison macro */ +#define CLOCK_LT(a, b) ((signed long)((a) - (b)) < 0) + +#define RTIMER_ARCH_SECOND 62500 +/* + * rtimer.h typedefs rtimer_clock_t as unsigned short. We need to define + * RTIMER_CLOCK_DIFF to override this + */ +typedef uint32_t rtimer_clock_t; +#define RTIMER_CLOCK_DIFF(a,b) ((int32_t)((a)-(b))) + +/** @} */ +/*---------------------------------------------------------------------------*/ +/** @} + * @} + * @} + */ +#endif /* PLATFORM_CONF_H_ */ diff --git a/platform/nrf52dk/rtt/rtt-printf.c b/platform/nrf52dk/rtt/rtt-printf.c new file mode 100644 index 000000000..416fff0ab --- /dev/null +++ b/platform/nrf52dk/rtt/rtt-printf.c @@ -0,0 +1,24 @@ +#include +#include "segger-rtt.h" + +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList); + +int +putchar(int c) +{ + SEGGER_RTT_Write(0, &c, 1); + return c; +} + +int +printf(const char *fmt, ...) +{ + int res; + va_list ap; + va_start(ap, fmt); + res = SEGGER_RTT_vprintf(0, fmt, &ap); + va_end(ap); + return res; +} + + diff --git a/platform/nrf52dk/rtt/segger-rtt-conf.h b/platform/nrf52dk/rtt/segger-rtt-conf.h new file mode 100644 index 000000000..ac996644f --- /dev/null +++ b/platform/nrf52dk/rtt/segger-rtt-conf.h @@ -0,0 +1,135 @@ +/********************************************************************* +* SEGGER MICROCONTROLLER GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 2014 - 2015 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +---------------------------------------------------------------------- +File : SEGGER_RTT_Conf.h +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. +---------------------------END-OF-HEADER------------------------------ +*/ + +#ifndef SEGGER_RTT_CONF_H +#define SEGGER_RTT_CONF_H + +#ifdef __ICCARM__ + #include +#endif + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ + +#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (2) // Max. number of up-buffers (T->H) available on this target (Default: 2) +#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (2) // Max. number of down-buffers (H->T) available on this target (Default: 2) + +#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k) +#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) + +#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) + +#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) + +// +// Target is not allowed to perform other RTT operations while string still has not been stored completely. +// Otherwise we would probably end up with a mixed string in the buffer. +// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. +// +/********************************************************************* +* +* RTT lock configuration for SEGGER Embedded Studio, +* Rowley CrossStudio and GCC +*/ +#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__) + #ifdef __ARM_ARCH_6M__ + #define SEGGER_RTT_LOCK(SavedState) { \ + asm volatile ("mrs %0, primask \n\t" \ + "mov r1, $1 \n\t" \ + "msr primask, r1 \n\t" \ + : "=r" (SavedState) \ + : \ + : "r1" \ + ); \ + } + + #define SEGGER_RTT_UNLOCK(SavedState) { \ + asm volatile ("msr primask, %0 \n\t" \ + : \ + : "r" (SavedState) \ + : \ + ); \ + } + + #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)) + #define SEGGER_RTT_LOCK(SavedState) { \ + asm volatile ("mrs %0, basepri \n\t" \ + "mov r1, $128 \n\t" \ + "msr basepri, r1 \n\t" \ + : "=r" (SavedState) \ + : \ + : "r1" \ + ); \ + } + #define SEGGER_RTT_UNLOCK(SavedState) { \ + asm volatile ("msr basepri, %0 \n\t" \ + : \ + : "r" (SavedState) \ + : \ + ); \ + } + #else + #define SEGGER_RTT_LOCK(SavedState) (void)(SavedState) + #define SEGGER_RTT_UNLOCK(SavedState) (void)(SavedState) + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR EWARM +*/ +#ifdef __ICCARM__ + #if (defined (__ARM7M__) && (__CORE__ == __ARM7M__)) + #define SEGGER_RTT_LOCK(SavedState) { \ + SavedState = __get_PRIMASK(); \ + __set_PRIMASK(1); \ + } + + #define SEGGER_RTT_UNLOCK(SavedState) { \ + __set_PRIMASK(SavedState); \ + } + #elif (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) + #define SEGGER_RTT_LOCK(SavedState) { \ + SavedState = __get_BASEPRI(); \ + __set_BASEPRI(128); \ + } + + #define SEGGER_RTT_UNLOCK(SavedState) { \ + __set_BASEPRI(SavedState); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration fallback +*/ +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK(SavedState) (void)(SavedState) +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK(SavedState) (void)(SavedState) +#endif + +#endif +/*************************** End of file ****************************/ diff --git a/platform/nrf52dk/rtt/segger-rtt-printf.c b/platform/nrf52dk/rtt/segger-rtt-printf.c new file mode 100644 index 000000000..e992e7a36 --- /dev/null +++ b/platform/nrf52dk/rtt/segger-rtt-printf.c @@ -0,0 +1,510 @@ +/********************************************************************* +* SEGGER MICROCONTROLLER GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 2014 - 2015 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* * This software may in its unmodified form be freely redistributed * +* in source form. * +* * The source code may be modified, provided the source code * +* retains the above copyright notice, this list of conditions and * +* the following disclaimer. * +* * Modified versions of this software in source or linkable form * +* may not be distributed without prior consent of SEGGER. * +* * This software may only be used for communication with SEGGER * +* J-Link debug probes. * +* * +* 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 SEGGER Microcontroller 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. * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_printf.c +Purpose : Replacement for printf to write formatted data via RTT +---------------------------------------------------------------------- +*/ +#include "segger-rtt.h" +#include "segger-rtt-conf.h" + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ + +#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE + #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64) +#endif + +#include +#include + + +#define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0) +#define FORMAT_FLAG_PAD_ZERO (1u << 1) +#define FORMAT_FLAG_PRINT_SIGN (1u << 2) +#define FORMAT_FLAG_ALTERNATE (1u << 3) + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +typedef struct { + char* pBuffer; + unsigned BufferSize; + unsigned Cnt; + + int ReturnValue; + + unsigned RTTBufferIndex; +} SEGGER_RTT_PRINTF_DESC; + +/********************************************************************* +* +* Function prototypes +* +********************************************************************** +*/ +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList); + +/********************************************************************* +* +* Static code +* +********************************************************************** +*/ +/********************************************************************* +* +* _StoreChar +*/ +static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) { + unsigned Cnt; + + Cnt = p->Cnt; + if ((Cnt + 1u) <= p->BufferSize) { + *(p->pBuffer + Cnt) = c; + p->Cnt = Cnt + 1u; + p->ReturnValue++; + } + // + // Write part of string, when the buffer is full + // + if (p->Cnt == p->BufferSize) { + if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) { + p->ReturnValue = -1; + } else { + p->Cnt = 0u; + } + } +} + +/********************************************************************* +* +* _PrintUnsigned +*/ +static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { + static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + unsigned Div; + unsigned Digit; + unsigned Number; + unsigned Width; + char c; + + Number = v; + Digit = 1u; + // + // Get actual field width + // + Width = 1u; + while (Number >= Base) { + Number = (Number / Base); + Width++; + } + if (NumDigits > Width) { + Width = NumDigits; + } + // + // Print leading chars if necessary + // + if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) { + if (FieldWidth != 0u) { + if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) { + c = '0'; + } else { + c = ' '; + } + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, c); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Compute Digit. + // Loop until Digit has the value of the highest digit required. + // Example: If the output is 345 (Base 10), loop 2 times until Digit is 100. + // + while (1) { + if (NumDigits > 1u) { // User specified a min number of digits to print? => Make sure we loop at least that often, before checking anything else (> 1 check avoids problems with NumDigits being signed / unsigned) + NumDigits--; + } else { + Div = v / Digit; + if (Div < Base) { // Is our divider big enough to extract the highest digit from value? => Done + break; + } + } + Digit *= Base; + } + // + // Output digits + // + do { + Div = v / Digit; + v -= Div * Digit; + _StoreChar(pBufferDesc, _aV2C[Div]); + if (pBufferDesc->ReturnValue < 0) { + break; + } + Digit /= Base; + } while (Digit); + // + // Print trailing spaces if necessary + // + if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, ' '); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + } +} + +/********************************************************************* +* +* _PrintInt +*/ +static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { + unsigned Width; + int Number; + + Number = (v < 0) ? -v : v; + + // + // Get actual field width + // + Width = 1u; + while (Number >= (int)Base) { + Number = (Number / (int)Base); + Width++; + } + if (NumDigits > Width) { + Width = NumDigits; + } + if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) { + FieldWidth--; + } + + // + // Print leading spaces if necessary + // + if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, ' '); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + // + // Print sign if necessary + // + if (pBufferDesc->ReturnValue >= 0) { + if (v < 0) { + v = -v; + _StoreChar(pBufferDesc, '-'); + } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) { + _StoreChar(pBufferDesc, '+'); + } else { + + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Print leading zeros if necessary + // + if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, '0'); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Print number without sign + // + _PrintUnsigned(pBufferDesc, (unsigned)v, Base, NumDigits, FieldWidth, FormatFlags); + } + } + } +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* SEGGER_RTT_vprintf +* +* Function description +* Stores a formatted string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") +* sFormat Pointer to format string +* pParamList Pointer to the list of arguments for the format string +* +* Return values +* >= 0: Number of bytes which have been stored in the "Up"-buffer. +* < 0: Error +*/ +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) { + char c; + SEGGER_RTT_PRINTF_DESC BufferDesc; + int v; + unsigned NumDigits; + unsigned FormatFlags; + unsigned FieldWidth; + char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE]; + + BufferDesc.pBuffer = acBuffer; + BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE; + BufferDesc.Cnt = 0u; + BufferDesc.RTTBufferIndex = BufferIndex; + BufferDesc.ReturnValue = 0; + + do { + c = *sFormat; + sFormat++; + if (c == 0u) { + break; + } + if (c == '%') { + // + // Filter out flags + // + FormatFlags = 0u; + v = 1; + do { + c = *sFormat; + switch (c) { + case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break; + case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break; + case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break; + case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break; + default: v = 0; break; + } + } while (v); + // + // filter out field with + // + FieldWidth = 0u; + do { + c = *sFormat; + if ((c < '0') || (c > '9')) { + break; + } + sFormat++; + FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0'); + } while (1); + + // + // Filter out precision (number of digits to display) + // + NumDigits = 0u; + c = *sFormat; + if (c == '.') { + sFormat++; + do { + c = *sFormat; + if (c == '*') { + sFormat++; + v = va_arg(*pParamList, int); + NumDigits = (unsigned)v; + break; + } + if ((c < '0') || (c > '9')) { + break; + } + sFormat++; + NumDigits = NumDigits * 10u + ((unsigned)c - '0'); + } while (1); + } + // + // Filter out length modifier + // + c = *sFormat; + do { + if ((c == 'l') || (c == 'h')) { + c = *sFormat; + sFormat++; + } else { + break; + } + } while (1); + // + // Handle specifiers + // + switch (c) { + case 'c': { + char c0; + v = va_arg(*pParamList, int); + c0 = (char)v; + _StoreChar(&BufferDesc, c0); + break; + } + case 'd': + v = va_arg(*pParamList, int); + _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags); + break; + case 'u': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags); + break; + case 'x': + case 'X': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags); + break; + case 's': + { + const char * s = va_arg(*pParamList, const char *); + if (NumDigits > 0) { + do { + c = *s; + s++; + if (NumDigits == 0) { + break; + } + NumDigits--; + _StoreChar(&BufferDesc, c); + } while (BufferDesc.ReturnValue >= 0); + } else { + do { + c = *s; + s++; + if (c == '\0' || NumDigits == 0) { + break; + } + _StoreChar(&BufferDesc, c); + } while (BufferDesc.ReturnValue >= 0); + } + } + break; + case 'p': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u); + break; + case '%': + _StoreChar(&BufferDesc, '%'); + break; + default: + break; + } + sFormat++; + } else { + _StoreChar(&BufferDesc, c); + } + } while (BufferDesc.ReturnValue >= 0); + + if (BufferDesc.ReturnValue > 0) { + // + // Write remaining data, if any + // + if (BufferDesc.Cnt != 0u) { + SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt); + } + BufferDesc.ReturnValue += (int)BufferDesc.Cnt; + } + return BufferDesc.ReturnValue; +} + +/********************************************************************* +* +* SEGGER_RTT_printf +* +* Function description +* Stores a formatted string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") +* sFormat Pointer to format string, followed by the arguments for conversion +* +* Return values +* >= 0: Number of bytes which have been stored in the "Up"-buffer. +* < 0: Error +* +* Notes +* (1) Conversion specifications have following syntax: +* %[flags][FieldWidth][.Precision]ConversionSpecifier +* (2) Supported flags: +* -: Left justify within the field width +* +: Always print sign extension for signed conversions +* 0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision +* Supported conversion specifiers: +* c: Print the argument as one char +* d: Print the argument as a signed integer +* u: Print the argument as an unsigned integer +* x: Print the argument as an hexadecimal integer +* s: Print the string pointed to by the argument +* p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.) +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) { + va_list ParamList; + + va_start(ParamList, sFormat); + return SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList); +} +/*************************** End of file ****************************/ diff --git a/platform/nrf52dk/rtt/segger-rtt.c b/platform/nrf52dk/rtt/segger-rtt.c new file mode 100644 index 000000000..453a6a0e4 --- /dev/null +++ b/platform/nrf52dk/rtt/segger-rtt.c @@ -0,0 +1,1102 @@ +/********************************************************************* +* SEGGER MICROCONTROLLER GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 2014 - 2015 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* * This software may in its unmodified form be freely redistributed * +* in source form. * +* * The source code may be modified, provided the source code * +* retains the above copyright notice, this list of conditions and * +* the following disclaimer. * +* * Modified versions of this software in source or linkable form * +* may not be distributed without prior consent of SEGGER. * +* * This software may only be used for communication with SEGGER * +* J-Link debug probes. * +* * +* 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 SEGGER Microcontroller 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. * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.c +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. + +Additional information: + Type "int" is assumed to be 32-bits in size + H->T Host to target communication + T->H Target to host communication + + RTT channel 0 is always present and reserved for Terminal usage. + Name is fixed to "Terminal" + +---------------------------------------------------------------------- +*/ + +#include "segger-rtt.h" + +#include // for memcpy + +/********************************************************************* +* +* Configuration, default values +* +********************************************************************** +*/ + +#ifndef BUFFER_SIZE_UP + #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host +#endif + +#ifndef BUFFER_SIZE_DOWN + #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input) +#endif + +#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS + #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target +#endif + +#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS + #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target +#endif + +#ifndef SEGGER_RTT_MODE_DEFAULT + #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP +#endif + +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK(SavedState) +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK(SavedState) +#endif + +#ifndef STRLEN + #define STRLEN(a) strlen((a)) +#endif + +#ifndef MEMCPY + #define MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes)) +#endif + +#ifndef MIN + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX + #define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif +// +// For some environments, NULL may not be defined until certain headers are included +// +#ifndef NULL + #define NULL 0 +#endif + +/********************************************************************* +* +* Static const data +* +********************************************************************** +*/ + +static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + +/********************************************************************* +* +* Static data +* +********************************************************************** +*/ +// +// Allocate buffers for channel 0 +// +static char _acUpBuffer [BUFFER_SIZE_UP]; +static char _acDownBuffer[BUFFER_SIZE_DOWN]; +// +// Initialize SEGGER Real-time-Terminal control block (CB) +// +SEGGER_RTT_CB _SEGGER_RTT; + +static char _ActiveTerminal; + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ + +/********************************************************************* +* +* _DoInit() +* +* Function description +* Initializes the control block an buffers. +* May only be called via INIT() to avoid overriding settings. +* +*/ +#define INIT() do { \ + if (_SEGGER_RTT.acID[0] == '\0') { _DoInit(); } \ + } while (0) +static void _DoInit(void) { + SEGGER_RTT_CB* p; + // + // Initialize control block + // + p = &_SEGGER_RTT; + p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; + p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; + // + // Initialize up buffer 0 + // + p->aUp[0].sName = "Terminal"; + p->aUp[0].pBuffer = _acUpBuffer; + p->aUp[0].SizeOfBuffer = sizeof(_acUpBuffer); + p->aUp[0].RdOff = 0u; + p->aUp[0].WrOff = 0u; + p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT; + // + // Initialize down buffer 0 + // + p->aDown[0].sName = "Terminal"; + p->aDown[0].pBuffer = _acDownBuffer; + p->aDown[0].SizeOfBuffer = sizeof(_acDownBuffer); + p->aDown[0].RdOff = 0u; + p->aDown[0].WrOff = 0u; + p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT; + // + // Finish initialization of the control block. + // Copy Id string in three steps to make sure "SEGGER RTT" is not found + // in initializer memory (usually flash) by J-Link + // + strcpy(&p->acID[7], "RTT"); + strcpy(&p->acID[0], "SEGGER"); + p->acID[6] = ' '; +} + +/********************************************************************* +* +* _WriteBlocking() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* The caller is responsible for managing the write chunk sizes as +* _WriteBlocking() will block until all data has been posted successfully. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* >= 0 - Number of bytes written into buffer. +*/ +static unsigned _WriteBlocking(SEGGER_RTT_RING_BUFFER *pRing, const char* pBuffer, unsigned NumBytes) { + unsigned NumBytesToWrite; + unsigned NumBytesWritten; + unsigned RdOff; + unsigned WrOff; + // + // Write data to buffer and handle wrap-around if necessary + // + NumBytesWritten = 0u; + WrOff = pRing->WrOff; + do { + RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime + if (RdOff > WrOff) { + NumBytesToWrite = RdOff - WrOff - 1u; + } else { + NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u); + } + NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around + NumBytesToWrite = MIN(NumBytesToWrite, NumBytes); + memcpy(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite); + NumBytesWritten += NumBytesToWrite; + pBuffer += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0u; + } + pRing->WrOff = WrOff; + } while (NumBytes); + // + return NumBytesWritten; +} + +/********************************************************************* +* +* _WriteNoCheck() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* It is callers responsibility to make sure data actually fits in buffer. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking +*/ +static void _WriteNoCheck(SEGGER_RTT_RING_BUFFER *pRing, const char* pData, unsigned NumBytes) { + unsigned NumBytesAtOnce; + unsigned WrOff; + unsigned Rem; + + WrOff = pRing->WrOff; + Rem = pRing->SizeOfBuffer - WrOff; + if (Rem > NumBytes) { + // + // All data fits before wrap around + // + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + } else { + // + // We reach the end of the buffer, so need to wrap around + // + NumBytesAtOnce = Rem; + memcpy(pRing->pBuffer + WrOff, pData, NumBytesAtOnce); + NumBytesAtOnce = NumBytes - Rem; + memcpy(pRing->pBuffer, pData + Rem, NumBytesAtOnce); + pRing->WrOff = NumBytesAtOnce; + } +} + +/********************************************************************* +* +* _PostTerminalSwitch() +* +* Function description +* Switch terminal to the given terminal ID. It is the caller's +* responsibility to ensure the terminal ID is correct and there is +* enough space in the buffer for this to complete successfully. +* +* Parameters +* pRing Ring buffer to post to. +* TerminalId Terminal ID to switch to. +*/ +static void _PostTerminalSwitch(SEGGER_RTT_RING_BUFFER *pRing, char TerminalId) { + char ac[2]; + + ac[0] = 0xFFu; + ac[1] = _aTerminalId[(int)TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit + _WriteBlocking(pRing, ac, 2u); +} + +/********************************************************************* +* +* _GetAvailWriteSpace() +* +* Function description +* Returns the number of bytes that can be written to the ring +* buffer without blocking. +* +* Parameters +* pRing Ring buffer to check. +* +* Return value +* Number of bytes that are free in the buffer. +*/ +static unsigned _GetAvailWriteSpace(SEGGER_RTT_RING_BUFFER *pRing) { + unsigned RdOff; + unsigned WrOff; + unsigned r; + // + // Avoid warnings regarding volatile access order. It's not a problem + // in this case, but dampen compiler enthusiasm. + // + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + if (RdOff <= WrOff) { + r = pRing->SizeOfBuffer - 1u - WrOff + RdOff; + } else { + r = RdOff - WrOff - 1u; + } + return r; +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* SEGGER_RTT_ReadNoLock() +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* Do not lock against interrupts and multiple access. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { + unsigned NumBytesRem; + unsigned NumBytesRead; + unsigned RdOff; + unsigned WrOff; + unsigned char* pBuffer; + SEGGER_RTT_RING_BUFFER* pRing; + // + INIT(); + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + pBuffer = (unsigned char*)pData; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + NumBytesRead = 0u; + // + // Read from current read position to wrap-around of buffer, first + // + if (RdOff > WrOff) { + NumBytesRem = pRing->SizeOfBuffer - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + // + // Handle wrap-around of buffer + // + if (RdOff == pRing->SizeOfBuffer) { + RdOff = 0u; + } + } + // + // Read remaining items of buffer + // + NumBytesRem = WrOff - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + if (NumBytesRem > 0u) { + memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + } + if (NumBytesRead) { + pRing->RdOff = RdOff; + } + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_Read +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { + unsigned NumBytesRead; + volatile unsigned SavedState; + // + SEGGER_RTT_LOCK(SavedState); + // + // Call the non-locking read function + // + NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(SavedState); + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteSkipNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteSkipNoLock does not lock the application and +* skips all data, if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, all data is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_RING_BUFFER* pRing; + unsigned Avail; + unsigned RdOff; + unsigned WrOff; + unsigned Rem; + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer and copy some elements into local variables. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + // + // Handle the most common cases fastest. + // Which is: + // RdOff <= WrOff -> Space until wrap around is free. + // AND + // WrOff + NumBytes < SizeOfBuffer -> No Wrap around necessary. + // + // OR + // + // RdOff > WrOff -> Space until RdOff - 1 is free. + // AND + // WrOff + NumBytes < RdOff -> Data fits into buffer + // + if (RdOff <= WrOff) { + // + // Get space until WrOff will be at wrap around. + // + Avail = pRing->SizeOfBuffer - 1u - WrOff ; + if (Avail >= NumBytes) { + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + return 1; + } + // + // If data did not fit into space until wrap around calculate complete space in buffer. + // + Avail += RdOff; + // + // If there is still no space for the whole of this output, don't bother. + // + if (Avail >= NumBytes) { + // + // OK, we have enough space in buffer. Copy in one or 2 chunks + // + Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer + if (Rem > NumBytes) { + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + } else { + // + // We reach the end of the buffer, so need to wrap around + // + memcpy(pRing->pBuffer + WrOff, pData, Rem); + memcpy(pRing->pBuffer, pData + Rem, NumBytes - Rem); + pRing->WrOff = NumBytes - Rem; + } + return 1; + } + } else { + Avail = RdOff - WrOff - 1u; + if (Avail >= NumBytes) { + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + return 1; + } + } + // + // If we reach this point no data has been written + // + return 0; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteNoLock does not lock the application. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + unsigned Avail; + const char* pData; + SEGGER_RTT_RING_BUFFER *pRing; + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // How we output depends upon the mode... + // + switch (pRing->Flags) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother. + // + Avail = _GetAvailWriteSpace(pRing); + if (Avail < NumBytes) { + Status = 0u; + } else { + Status = NumBytes; + _WriteNoCheck(pRing, pData, NumBytes); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode, trim to what we can output without blocking. + // + Avail = _GetAvailWriteSpace(pRing); + Status = Avail < NumBytes ? Avail : NumBytes; + _WriteNoCheck(pRing, pData, Status); + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + Status = _WriteBlocking(pRing, pData, NumBytes); + break; + default: + Status = 0u; + break; + } + // + // Finish up. + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_Write +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. +*/ +unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + volatile unsigned SavedState; + // + INIT(); + SEGGER_RTT_LOCK(SavedState); + // + // Call the non-locking write function + // + Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(SavedState); + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteString +* +* Function description +* Stores string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* s Pointer to string. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, depending on configuration, +* remaining characters may be dropped or RTT module waits until there is more space in the buffer. +* (2) String passed to this function has to be \0 terminated +* (3) \0 termination character is *not* stored in RTT buffer +*/ +unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) { + unsigned Len; + + Len = STRLEN(s); + return SEGGER_RTT_Write(BufferIndex, s, Len); +} + +/********************************************************************* +* +* SEGGER_RTT_GetKey +* +* Function description +* Reads one character from the SEGGER RTT buffer. +* Host has previously stored data there. +* +* Return value +* < 0 - No character available (buffer empty). +* >= 0 - Character which has been read. (Possible values: 0 - 255) +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0. +*/ +int SEGGER_RTT_GetKey(void) { + char c; + int r; + + r = (int)SEGGER_RTT_Read(0u, &c, 1u); + if (r == 1) { + r = (int)(unsigned char)c; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_WaitKey +* +* Function description +* Waits until at least one character is avaible in the SEGGER RTT buffer. +* Once a character is available, it is read and this function returns. +* +* Return value +* >=0 - Character which has been read. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +* (2) This function is blocking if no character is present in RTT buffer +*/ +int SEGGER_RTT_WaitKey(void) { + int r; + + do { + r = SEGGER_RTT_GetKey(); + } while (r < 0); + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasKey +* +* Function description +* Checks if at least one character for reading is available in the SEGGER RTT buffer. +* +* Return value +* == 0 - No characters are available to read. +* == 1 - At least one character is available. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +*/ +int SEGGER_RTT_HasKey(void) { + unsigned RdOff; + int r; + + INIT(); + RdOff = _SEGGER_RTT.aDown[0].RdOff; + if (RdOff != _SEGGER_RTT.aDown[0].WrOff) { + r = 1; + } else { + r = 0; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasData +* +* Function description +* Check if there is data from the host in the given buffer. +* +* Return value: +* ==0: No data +* !=0: Data in buffer +* +*/ +unsigned SEGGER_RTT_HasData(unsigned BufferIndex) { + SEGGER_RTT_RING_BUFFER *pRing; + unsigned v; + + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + v = pRing->WrOff; + return v - pRing->RdOff; +} + + +/********************************************************************* +* +* SEGGER_RTT_ConfigUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer (T->H). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. +* < 0 - Error +*/ +int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + volatile unsigned SavedState; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(SavedState); + if (BufferIndex > 0u) { + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + _SEGGER_RTT.aUp[BufferIndex].pBuffer = pBuffer; + _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(SavedState); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigDownBuffer +* +* Function description +* Run-time configuration of a specific down-buffer (H->T). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + volatile unsigned SavedState; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(SavedState); + if (BufferIndex > 0u) { + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + _SEGGER_RTT.aDown[BufferIndex].pBuffer = pBuffer; + _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(SavedState); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { + int r; + volatile unsigned SavedState; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(SavedState); + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(SavedState); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameDownBuffer +* +* Function description +* Run-time configuration of a specific Down-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { + int r; + volatile unsigned SavedState; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(SavedState); + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(SavedState); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_Init +* +* Function description +* Initializes the RTT Control Block. +* Should be used in RAM targets, at start of the application. +* +*/ +void SEGGER_RTT_Init (void) { + INIT(); +} + +/********************************************************************* +* +* SEGGER_RTT_SetTerminal +* +* Function description +* Sets the terminal to be used for output on channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* +* Return value +* >= 0 O.K. +* < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id) +*/ +int SEGGER_RTT_SetTerminal (char TerminalId) { + char ac[2]; + SEGGER_RTT_RING_BUFFER *pRing; + volatile unsigned SavedState; + unsigned Avail; + int r; + // + INIT(); + // + r = 0; + ac[0] = 0xFFU; + if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels + ac[1] = _aTerminalId[(int)TerminalId]; + pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed + SEGGER_RTT_LOCK(SavedState); // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing + if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { + _ActiveTerminal = TerminalId; + _WriteBlocking(pRing, ac, 2u); + } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes + Avail = _GetAvailWriteSpace(pRing); + if (Avail >= 2) { + _ActiveTerminal = TerminalId; // Only change active terminal in case of success + _WriteNoCheck(pRing, ac, 2u); + } else { + r = -1; + } + } + SEGGER_RTT_UNLOCK(SavedState); + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_TerminalOut +* +* Function description +* Writes a string to the given terminal +* without changing the terminal for channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* s String to be printed on the terminal. +* +* Return value +* >= 0 - Number of bytes written. +* < 0 - Error. +* +*/ +int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) { + int Status; + unsigned FragLen; + unsigned Avail; + SEGGER_RTT_RING_BUFFER *pRing; + volatile unsigned SavedState; + // + INIT(); + // + // Validate terminal ID. + // + if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[0]; + // + // Need to be able to change terminal, write data, change back. + // Compute the fixed and variable sizes. + // + FragLen = strlen(s); + // + // How we output depends upon the mode... + // + SEGGER_RTT_LOCK(SavedState); + Avail = _GetAvailWriteSpace(pRing); + switch (pRing->Flags & SEGGER_RTT_MODE_MASK) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother switching terminals at all. + // + if (Avail < (FragLen + 4u)) { + Status = 0; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode and there is not enough space for everything, + // trim the output but always include the terminal switch. If no room + // for terminal switch, skip that totally. + // + if (Avail < 4u) { + Status = -1; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u)); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + break; + default: + Status = -1; + break; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(SavedState); + } else { + Status = -1; + } + return Status; +} + + +/*************************** End of file ****************************/ diff --git a/platform/nrf52dk/rtt/segger-rtt.h b/platform/nrf52dk/rtt/segger-rtt.h new file mode 100644 index 000000000..e3436c462 --- /dev/null +++ b/platform/nrf52dk/rtt/segger-rtt.h @@ -0,0 +1,204 @@ +/********************************************************************* +* SEGGER MICROCONTROLLER GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 2014 - 2015 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* * This software may in its unmodified form be freely redistributed * +* in source form. * +* * The source code may be modified, provided the source code * +* retains the above copyright notice, this list of conditions and * +* the following disclaimer. * +* * Modified versions of this software in source or linkable form * +* may not be distributed without prior consent of SEGGER. * +* * This software may only be used for communication with SEGGER * +* J-Link debug probes. * +* * +* 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 SEGGER Microcontroller 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. * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.h +Purpose : Implementation of SEGGER real-time transfer which allows + real-time communication on targets which support debugger + memory accesses while the CPU is running. +---------------------------------------------------------------------- +*/ + +#ifndef SEGGER_RTT_H +#define SEGGER_RTT_H + +#include "segger-rtt-conf.h" + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as up- (T->H) or down-buffer (H->T) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + volatile unsigned WrOff; // Position of next item to be written by either host (down-buffer) or target (up-buffer). Must be volatile since it may be modified by host (down-buffer) + volatile unsigned RdOff; // Position of next item to be read by target (down-buffer) or host (up-buffer). Must be volatile since it may be modified by host (up-buffer) + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_RING_BUFFER; + +// +// RTT control block which describes the number of buffers available +// as well as the configuration for each buffer +// +// +typedef struct { + char acID[16]; // Initialized to "SEGGER RTT" + int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2) + int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2) + SEGGER_RTT_RING_BUFFER aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host + SEGGER_RTT_RING_BUFFER aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target +} SEGGER_RTT_CB; + +/********************************************************************* +* +* Global data +* +********************************************************************** +*/ +extern SEGGER_RTT_CB _SEGGER_RTT; + +/********************************************************************* +* +* RTT API functions +* +********************************************************************** +*/ +int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_GetKey (void); +unsigned SEGGER_RTT_HasData (unsigned BufferIndex); +int SEGGER_RTT_HasKey (void); +void SEGGER_RTT_Init (void); +unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); +unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); +int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_WaitKey (void); +unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s); +// +// Function macro for performance optimization +// +#define SEGGER_RTT_HASDATA(n) (_SEGGER_RTT.aDown[n].WrOff - _SEGGER_RTT.aDown[n].RdOff) + +/********************************************************************* +* +* RTT "Terminal" API functions +* +********************************************************************** +*/ +int SEGGER_RTT_SetTerminal (char TerminalId); +int SEGGER_RTT_TerminalOut (char TerminalId, const char* s); + +/********************************************************************* +* +* RTT printf functions (require SEGGER_RTT_printf.c) +* +********************************************************************** +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...); + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ + +// +// Operating modes. Define behavior if buffer is full (not enough space for entire message) +// +#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0U) // Skip. Do not block, output nothing. (Default) +#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1U) // Trim: Do not block, output as much as fits. +#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2U) // Block: Wait until there is space in the buffer. +#define SEGGER_RTT_MODE_MASK (3U) + +// +// Control sequences, based on ANSI. +// Can be used to control color, and clear the screen +// +#define RTT_CTRL_RESET "\e[0m" // Reset to default colors +#define RTT_CTRL_CLEAR "\e[2J" // Clear screen, reposition cursor to top left + +#define RTT_CTRL_TEXT_BLACK "\e[2;30m" +#define RTT_CTRL_TEXT_RED "\e[2;31m" +#define RTT_CTRL_TEXT_GREEN "\e[2;32m" +#define RTT_CTRL_TEXT_YELLOW "\e[2;33m" +#define RTT_CTRL_TEXT_BLUE "\e[2;34m" +#define RTT_CTRL_TEXT_MAGENTA "\e[2;35m" +#define RTT_CTRL_TEXT_CYAN "\e[2;36m" +#define RTT_CTRL_TEXT_WHITE "\e[2;37m" + +#define RTT_CTRL_TEXT_BRIGHT_BLACK "\e[1;30m" +#define RTT_CTRL_TEXT_BRIGHT_RED "\e[1;31m" +#define RTT_CTRL_TEXT_BRIGHT_GREEN "\e[1;32m" +#define RTT_CTRL_TEXT_BRIGHT_YELLOW "\e[1;33m" +#define RTT_CTRL_TEXT_BRIGHT_BLUE "\e[1;34m" +#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "\e[1;35m" +#define RTT_CTRL_TEXT_BRIGHT_CYAN "\e[1;36m" +#define RTT_CTRL_TEXT_BRIGHT_WHITE "\e[1;37m" + +#define RTT_CTRL_BG_BLACK "\e[24;40m" +#define RTT_CTRL_BG_RED "\e[24;41m" +#define RTT_CTRL_BG_GREEN "\e[24;42m" +#define RTT_CTRL_BG_YELLOW "\e[24;43m" +#define RTT_CTRL_BG_BLUE "\e[24;44m" +#define RTT_CTRL_BG_MAGENTA "\e[24;45m" +#define RTT_CTRL_BG_CYAN "\e[24;46m" +#define RTT_CTRL_BG_WHITE "\e[24;47m" + +#define RTT_CTRL_BG_BRIGHT_BLACK "\e[4;40m" +#define RTT_CTRL_BG_BRIGHT_RED "\e[4;41m" +#define RTT_CTRL_BG_BRIGHT_GREEN "\e[4;42m" +#define RTT_CTRL_BG_BRIGHT_YELLOW "\e[4;43m" +#define RTT_CTRL_BG_BRIGHT_BLUE "\e[4;44m" +#define RTT_CTRL_BG_BRIGHT_MAGENTA "\e[4;45m" +#define RTT_CTRL_BG_BRIGHT_CYAN "\e[4;46m" +#define RTT_CTRL_BG_BRIGHT_WHITE "\e[4;47m" + + +#endif + +/*************************** End of file ****************************/ diff --git a/platform/openmote-cc2538/Makefile.openmote-cc2538 b/platform/openmote-cc2538/Makefile.openmote-cc2538 new file mode 100644 index 000000000..3439a3211 --- /dev/null +++ b/platform/openmote-cc2538/Makefile.openmote-cc2538 @@ -0,0 +1,50 @@ +# openmote-cc2538 platform makefile + +ifndef CONTIKI + $(error CONTIKI not defined! You must specify where CONTIKI resides!) +endif + +### Configure the build for the board and pull in board-specific sources +CONTIKI_TARGET_DIRS += . dev +PLATFORM_ROOT_DIR = $(CONTIKI)/platform/$(TARGET) + +### Include +CONTIKI_TARGET_SOURCEFILES += contiki-main.c board.c +CONTIKI_TARGET_SOURCEFILES += leds-arch.c button-sensor.c openmote-sensors.c +CONTIKI_TARGET_SOURCEFILES += antenna.c adxl346.c max44009.c sht21.c tps62730.c + +CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) + +CLEAN += *.openmote-cc2538 + +### Unless the example dictates otherwise, build with code size optimisations +ifndef SMALL + SMALL = 1 +endif + +### Define the CPU directory +CONTIKI_CPU=$(CONTIKI)/cpu/cc2538 +include $(CONTIKI_CPU)/Makefile.cc2538 + +MODULES += core/net core/net/mac \ + core/net/mac/contikimac \ + core/net/llsec core/net/llsec/noncoresec + +PYTHON = python +BSL_FLAGS += -e -w -v -b 450000 + +ifdef PORT + BSL_FLAGS += -p $(PORT) +endif + +BSL = $(CONTIKI)/tools/cc2538-bsl/cc2538-bsl.py + +%.upload: %.bin %.elf +ifeq ($(wildcard $(BSL)), ) + @echo "ERROR: Could not find the cc2538-bsl script. Did you run 'git submodule update --init' ?" +else + $(eval BSL_ADDRESS_ARG := -a $(shell $(OBJDUMP) -h $*.elf | grep -B1 LOAD | \ + grep -Ev 'LOAD|\-\-' | awk '{print "0x" $$5}' | \ + sort -g | head -1)) + $(PYTHON) $(BSL) $(BSL_FLAGS) $(BSL_ADDRESS_ARG) $< +endif diff --git a/platform/openmote-cc2538/README.md b/platform/openmote-cc2538/README.md new file mode 100644 index 000000000..2f3ee7d07 --- /dev/null +++ b/platform/openmote-cc2538/README.md @@ -0,0 +1,189 @@ +OpenMote-CC2538 platform +======================== +The OpenMote-CC2538 is based on TI's CC2538 SoC (System on Chip), featuring an ARM Cortex-M3 running at 16/32 MHz and with 32 kbytes of RAM and 512 kbytes of FLASH. It has the following key features: + + * Standard Cortex M3 peripherals (NVIC, SCB, SysTick) + * Sleep Timer (underpins rtimers) + * SysTick (underpins the platform clock and Contiki's timers infrastructure) + * RF (2.4 GHz) + * UART + * Watchdog (in watchdog mode) + * USB (in CDC-ACM) + * uDMA Controller (RAM to/from USB and RAM to/from RF) + * Random number generator + * Low Power Modes + * General-Purpose Timers + * ADC + * Cryptoprocessor (AES-ECB/CBC/CTR/CBC-MAC/GCM/CCM-128/192/256, SHA-256) + * Public Key Accelerator (ECDH, ECDSA) + * Flash-based port of Coffee + * PWM + * Built-in core temperature and battery sensor + +Requirements +============ +To start using Contiki with the OpenMote-CC2538, the following is required: + + * An OpenMote-CC2538 board. + * A toolchain to compile Contiki for the CC2538. + * Drivers so that your OS can communicate with your hardware. + * Software to upload images to the CC2538. + +Install a Toolchain +------------------- +The toolchain used to build contiki is arm-gcc, also used by other arm-based Contiki ports. If you are using Instant Contiki, you may have a version pre-installed in your system. + +The platform is currently being used/tested with "GNU Tools for ARM Embedded Processors" (). The current recommended version and the one being used by Contiki's regression tests on Travis is shown below. + + $ arm-none-eabi-gcc --version + arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 5.2.1 20151202 (release) [ARM/embedded-5-branch revision 231848] + Copyright (C) 2015 Free Software Foundation, Inc. + This is free software; see the source for copying conditions. There is NO + warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Software to Program the Nodes +----------------------------- +The OpenMote-CC2538 can be programmed via the jtag interface or via the serial boot loader on the chip. + +The OpenMote-CC2538 has a mini JTAG 10-pin male header, compatible with the `SmartRF06` development board, which can be used to flash and debug the platforms. Alternatively one could use the `JLink` programmer with a 20-to-10 pin converter like the following: . + +The serial boot loader on the chip is exposed to the user via the USB interface. To activate the bootloader short the ON/SLEEP pin to GND and then press the reset button. + +Instructions to flash for different OS are given below. + +* On Windows: + * Nodes can be programmed with TI's ArmProgConsole or the SmartRF Flash Programmer 2. The README should be self-explanatory. With ArmProgConsole, upload the file with a `.bin` extension. + * Nodes can also be programmed via the serial boot loader in the cc2538. In `tools/cc2538-bsl/` you can find `cc2538-bsl.py` python script, which can download firmware to your node via a serial connection. If you use this option you just need to make sure you have a working version of python installed. You can read the README in the same directory for more info. + +* On Linux: + * Nodes can be programmed with TI's [UniFlash] tool. With UniFlash, use the file with `.elf` extension. + * Nodes can also be programmed via the serial boot loader in the cc2538. No extra software needs to be installed. + +* On OSX: + * The `cc2538-bsl.py` script in `tools/cc2538-bsl/` is the only option. No extra software needs to be installed. + +Use the Port +============ +The following examples are intended to work off-the-shelf: + +* Examples under `examples/openmote-cc2538` +* MQTT example `examples/cc2538dk/mqtt-demo` +* Border router: `examples/ipv6/rpl-border-router` +* Webserver: `examples/webserver-ipv6` +* CoAP example: `examples/er-rest-example` + +Build your First Examples +------------------------- +It is recommended to start with the `openmote-demo`, it is a simple example that demonstrates the OpenMote-CC2538 features, such as the built-in sensors, LEDs, user button and radio (using RIME broadcast). + +The `Makefile.target` includes the `TARGET=` argument, predefining which is the target platform to compile for, it is automatically included at compilation. + +To generate or override an existing one, you can run: + +`make TARGET=openmote-cc2538 savetarget` + +Then you can just run `make` to compile an application, otherwise you will need to do `make TARGET=openmote-cc2538`. + +If you want to upload the compiled firmware to a node via the serial boot loader you need first to either manually enable the boot loader. + +Then use `make openmote-demo.upload`. + +The `PORT` argument could be used to specify in which port the device is connected, in case we have multiple devices connected at the same time. + +To generate an assembly listing of the compiled firmware, run `make openmote-demo.lst`. This may be useful for debugging or optimizing your application code. To intersperse the C source code within the assembly listing, you must instruct the compiler to include debugging information by adding `CFLAGS += -g` to the project Makefile and rebuild by running `make clean openmote-demo.lst`. + +To enable printing debug output to your console, use the `make login` to get the information over the USB programming/debugging port, or alternatively use `make serialview` to also add a timestamp in each print. + +Node IEEE/RIME/IPv6 Addresses +----------------------------- + +Nodes will generally autoconfigure their IPv6 address based on their IEEE address. The IEEE address can be read directly from the CC2538 Info Page, or it can be hard-coded. Additionally, the user may specify a 2-byte value at build time, which will be used as the IEEE address' 2 LSBs. + +To configure the IEEE address source location (Info Page or hard-coded), use the `IEEE_ADDR_CONF_HARDCODED` define in contiki-conf.h: + +* 0: Info Page +* 1: Hard-coded + +If `IEEE_ADDR_CONF_HARDCODED` is defined as 1, the IEEE address will take its value from the `IEEE_ADDR_CONF_ADDRESS` define. If `IEEE_ADDR_CONF_HARDCODED` is defined as 0, the IEEE address can come from either the primary or secondary location in the Info Page. To use the secondary address, define `IEEE_ADDR_CONF_USE_SECONDARY_LOCATION` as 1. + +Additionally, you can override the IEEE's 2 LSBs, by using the `NODEID` make variable. The value of `NODEID` will become the value of the `IEEE_ADDR_NODE_ID` pre-processor define. If `NODEID` is not defined, `IEEE_ADDR_NODE_ID` will not get defined either. For example: + + make NODEID=0x79ab + +This will result in the 2 last bytes of the IEEE address getting set to 0x79 0xAB + +Note: Some early production devices do not have am IEEE address written on the Info Page. For those devices, using value 0 above will result in a Rime address of all 0xFFs. If your device is in this category, define `IEEE_ADDR_CONF_HARDCODED` to 1 and specify `NODEID` to differentiate between devices. + +Low-Power Modes +--------------- +The CC2538 port supports power modes for low energy consumption. The SoC will enter a low power mode as part of the main loop when there are no more events to service. + +LPM support can be disabled in its entirety by setting `LPM_CONF_ENABLE` to 0 in `contiki-conf.h` or `project-conf.h`. + +The Low-Power module uses a simple heuristic to determine the best power mode, depending on anticipated Deep Sleep duration and the state of various peripherals. + +In a nutshell, the algorithm first answers the following questions: + +* Is the RF off? +* Are all registered peripherals permitting PM1+? +* Is the Sleep Timer scheduled to fire an interrupt? + +If the answer to any of the above question is "No", the SoC will enter PM0. If the answer to all questions is "Yes", the SoC will enter one of PMs 0/1/2 depending on the expected Deep Sleep duration and subject to user configuration and application requirements. + +At runtime, the application may enable/disable some Power Modes by making calls to `lpm_set_max_pm()`. For example, to avoid PM2 an application could call `lpm_set_max_pm(1)`. Subsequently, to re-enable PM2 the application would call `lpm_set_max_pm(2)`. + +The LPM module can be configured with a hard maximum permitted power mode. + + #define LPM_CONF_MAX_PM N + +Where N corresponds to the PM number. Supported values are 0, 1, 2. PM3 is not supported. Thus, if the value of the define is 1, the SoC will only ever enter PMs 0 or 1 but never 2 and so on. + +The configuration directive `LPM_CONF_MAX_PM` sets a hard upper boundary. For instance, if `LPM_CONF_MAX_PM` is defined as 1, calls to `lpm_set_max_pm()` can only enable/disable PM1. In this scenario, PM2 can not be enabled at runtime. + +When setting `LPM_CONF_MAX_PM` to 0 or 1, the entire SRAM will be available. Crucially, when value 2 is used the linker will automatically stop using the SoC's SRAM non-retention area, resulting in a total available RAM of 16 kbytes instead of 32 kbytes. + +### LPM and Duty Cycling Driver +LPM is highly related to the operations of the Radio Duty Cycling (RDC) driver of the Contiki network stack and will work correctly with ContikiMAC and NullRDC. + +* With ContikiMAC, PMs 0/1/2 are supported subject to user configuration. +* When NullRDC is in use, the radio will be always on. As a result, the algorithm discussed above will always choose PM0 and will never attempt to drop to PM1/2. + +Build headless nodes +-------------------- +It is possible to turn off all character I/O for nodes not connected to a PC. Doing this will entirely disable the UART as well as the USB controller, preserving energy in the long term. The define used to achieve this is (1: Quiet, 0: Normal output): + + #define CC2538_CONF_QUIET 0 + +Setting this define to 1 will automatically set the following to 0: + +* `USB_SERIAL_CONF_ENABLE` +* `UART_CONF_ENABLE` +* `STARTUP_CONF_VERBOSE` + +Code Size Optimisations +----------------------- +The build system currently uses optimization level `-Os`, which is controlled indirectly through the value of the `SMALL` make variable. This value can be overridden by example makefiles, or it can be changed directly in `platform/openmote-cc2538/Makefile.openmote-cc2538`. + +Historically, the `-Os` flag has caused problems with some toolchains. If you are using one of the toolchains documented in this README, you should be able to use it without issues. If for whatever reason you do come across problems, try setting `SMALL=0` or replacing `-Os` with `-O2` in `cpu/cc2538/Makefile.cc2538`. + +Doxygen Documentation +===================== +This port's code has been documented with doxygen. To build the documentation, navigate to `$(CONTIKI)/doc` and run `make`. This will build the entire contiki documentation and may take a while. + +If you want to build this platform's documentation only and skip the remaining platforms, run this: + + make basedirs="platform/openmote-cc2538 core cpu/cc2538 examples/openmote-cc2538 examples/openmote-cc2538" + +Once you've built the docs, open `$(CONTIKI)/doc/html/index.html` and enjoy. + +Other Versions of this Guide +============================ +If you prefer this guide in other formats, use the excellent [pandoc] to convert it. + +* **pdf**: `pandoc -s --toc README.md -o README.pdf` +* **html**: `pandoc -s --toc README.md -o README.html` + +Maintainers +=========== +The OpenMote-CC2538 is maintained by OpenMote Technologies. +Main contributor: Pere Tuset diff --git a/platform/openmote-cc2538/board.c b/platform/openmote-cc2538/board.c new file mode 100644 index 000000000..c27812a9a --- /dev/null +++ b/platform/openmote-cc2538/board.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-cc2538 + * @{ + * + * \file + * Board-initialisation for the OpenMote-CC2538 platform + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "dev/antenna.h" +#include +#include +/*---------------------------------------------------------------------------*/ +static void +configure_unused_pins(void) +{ + /* FIXME */ +} +/*---------------------------------------------------------------------------*/ +void +board_init() +{ + antenna_init(); + configure_unused_pins(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/platform/openmote-cc2538/board.h b/platform/openmote-cc2538/board.h new file mode 100644 index 000000000..9c9a62bc1 --- /dev/null +++ b/platform/openmote-cc2538/board.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ +/* -------------------------------------------------------------------------- */ +/** + * \addtogroup openmote-cc2538 + * @{ + * + * \file + * This file provides connectivity information on LEDs, Buttons, UART and + * other OpenMote-CC2538 peripherals. + * + * This file can be used as the basis to configure other platforms using the + * cc2538 SoC. + * + * \note Do not include this file directly. It gets included by contiki-conf + * after all relevant directives have been set. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ +/*---------------------------------------------------------------------------*/ +#include "dev/gpio.h" +#include "dev/nvic.h" +/*---------------------------------------------------------------------------*/ +/** \name OpenMote-CC2538 LED configuration + * + * LEDs on the OpenMote-CC2538 are connected as follows: + * - LED1 (Red) -> PC4 + * - LED2 (Yellow) -> PC6 + * - LED3 (Green) -> PC7 + * - LED4 (Orange) -> PC5 + * + * @{ + */ +/*---------------------------------------------------------------------------*/ +/* Some files include leds.h before us, so we need to get rid of defaults in + * leds.h before we provide correct definitions */ +#undef LEDS_GREEN +#undef LEDS_YELLOW +#undef LEDS_RED +#undef LEDS_CONF_ALL + +#define LEDS_RED 16 /**< LED1 (Red) -> PC4 */ +#define LEDS_YELLOW 64 /**< LED2 (Yellow) -> PC6 */ +#define LEDS_GREEN 128 /**< LED3 (Green) -> PC7 */ +#define LEDS_ORANGE 32 /**< LED4 (Orange) -> PC5 */ +#define LEDS_CONF_ALL 240 + +/* Notify various examples that we have LEDs */ +#define PLATFORM_HAS_LEDS 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name USB configuration + * + * The USB pullup is driven by PC0 + */ +#define USB_PULLUP_PORT GPIO_C_NUM +#define USB_PULLUP_PIN 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name UART configuration + * + * On the OpenMote, the UART is connected to the + * following ports/pins + * - RX: PA0 + * - TX: PA1 + * - CTS: PB0 (Can only be used with UART1) + * - RTS: PD3 (Can only be used with UART1) + * + * We configure the port to use UART0. To use UART1, replace UART0_* with + * UART1_* below. + * @{ + */ +#define UART0_RX_PORT GPIO_A_NUM +#define UART0_RX_PIN 0 +#define UART0_TX_PORT GPIO_A_NUM +#define UART0_TX_PIN 1 + +#define UART1_RX_PORT GPIO_B_NUM +#define UART1_RX_PIN 0 +#define UART1_TX_PORT GPIO_D_NUM +#define UART1_TX_PIN 3 +#define UART1_CTS_PORT (-1) +#define UART1_CTS_PIN (-1) +#define UART1_RTS_PORT (-1) +#define UART1_RTS_PIN (-1) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name OpenMote-CC2538 Button configuration + * + * Buttons on the OpenMote-CC2538 are connected as follows: + * - BUTTON_USER -> PC3 + * @{ + */ +/** BUTTON_USER -> PC3 */ +#define BUTTON_USER_PORT GPIO_C_NUM +#define BUTTON_USER_PIN 3 +#define BUTTON_USER_VECTOR NVIC_INT_GPIO_PORT_C +/* Notify various examples that we have Buttons */ +#define PLATFORM_HAS_BUTTON 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI (SSI0) configuration + * + * These values configure which CC2538 pins to use for the SPI (SSI0) lines. + * The SSI0 is currently used to interface with the Ethernet driver (ENC28J60) + * on the OpenBase board. + * @{ + */ +#define SPI_CLK_PORT GPIO_A_NUM +#define SPI_CLK_PIN 2 +#define SPI_MOSI_PORT GPIO_A_NUM +#define SPI_MOSI_PIN 5 +#define SPI_MISO_PORT GPIO_A_NUM +#define SPI_MISO_PIN 4 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI (SSI1) configuration + * + * These values configure which CC2538 pins to use for the SPI (SSI1) lines. + * The SSI1 is currently not used. + * @{ + */ +#define SPI1_CLK_PORT GPIO_C_NUM +#define SPI1_CLK_PIN 4 +#define SPI1_TX_PORT GPIO_C_NUM +#define SPI1_TX_PIN 5 +#define SPI1_RX_PORT GPIO_C_NUM +#define SPI1_RX_PIN 6 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name I2C configuration + * + * These values configure which CC2538 pins to use for the I2C lines. + * @{ + */ +#define I2C_SCL_PORT GPIO_B_NUM +#define I2C_SCL_PIN 3 +#define I2C_SDA_PORT GPIO_B_NUM +#define I2C_SDA_PIN 4 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Device string used on startup + * @{ + */ +#define BOARD_STRING "OpenMote-CC2538" +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* BOARD_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/platform/openmote-cc2538/contiki-conf.h b/platform/openmote-cc2538/contiki-conf.h new file mode 100644 index 000000000..87b58f299 --- /dev/null +++ b/platform/openmote-cc2538/contiki-conf.h @@ -0,0 +1,579 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-cc2538 + * @{ + * + * \defgroup openmote-cc2538-platforms OpenMote-CC2538 platform + * + * The OpenMote-CC2538 platform was designed at UC Berkeley in 2013 and + * is comercialized by OpenMote Technologies since 2014. It is the first + * commercial platform based on the powerful TI CC2538 SoC. It uses a + * XBee form-factor to ease prototyping. + * + * \file + * Configuration for the OpenMote-CC2538 platform + */ +#ifndef CONTIKI_CONF_H_ +#define CONTIKI_CONF_H_ + +#include +#include +/*---------------------------------------------------------------------------*/ +/* Include Project Specific conf */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif /* PROJECT_CONF_H */ +/*---------------------------------------------------------------------------*/ +/** + * \name Compiler configuration and platform-specific type definitions + * + * Those values are not meant to be modified by the user + * @{ + */ +#define CLOCK_CONF_SECOND 128 + +/* Compiler configurations */ +#define CCIF +#define CLIF + +/* Platform typedefs */ +typedef uint32_t clock_time_t; +typedef uint32_t uip_stats_t; + +/* + * rtimer.h typedefs rtimer_clock_t as unsigned short. We need to define + * RTIMER_CLOCK_DIFF to override this + */ +typedef uint32_t rtimer_clock_t; +#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b))) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Serial Boot Loader Backdoor configuration + * + * @{ + */ +#ifndef FLASH_CCA_CONF_BOOTLDR_BACKDOOR +#define FLASH_CCA_CONF_BOOTLDR_BACKDOOR 1 /** RAM DMA channel */ +#define USB_ARCH_CONF_TX_DMA_CHAN 1 /**< RAM -> USB DMA channel */ +#define CC2538_RF_CONF_TX_DMA_CHAN 2 /**< RF -> RAM DMA channel */ +#define CC2538_RF_CONF_RX_DMA_CHAN 3 /**< RAM -> RF DMA channel */ +#define UDMA_CONF_MAX_CHANNEL CC2538_RF_CONF_RX_DMA_CHAN +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Character I/O Configuration + * + * @{ + */ +#ifndef UART_CONF_ENABLE +#define UART_CONF_ENABLE 1 /**< Enable/Disable UART I/O */ +#endif + +#ifndef UART0_CONF_BAUD_RATE +#define UART0_CONF_BAUD_RATE 115200 /**< Default UART0 baud rate */ +#endif + +#ifndef UART1_CONF_BAUD_RATE +#define UART1_CONF_BAUD_RATE 115200 /**< Default UART1 baud rate */ +#endif + +#ifndef SLIP_ARCH_CONF_USB +#define SLIP_ARCH_CONF_USB 0 /**< SLIP over UART by default */ +#endif + +#ifndef CC2538_RF_CONF_SNIFFER_USB +#define CC2538_RF_CONF_SNIFFER_USB 0 /**< Sniffer out over UART by default */ +#endif + +#ifndef DBG_CONF_USB +#define DBG_CONF_USB 0 /**< All debugging over UART by default */ +#endif + +#ifndef SERIAL_LINE_CONF_UART +#define SERIAL_LINE_CONF_UART 0 /**< UART to use with serial line */ +#endif + +#if !SLIP_ARCH_CONF_USB +#ifndef SLIP_ARCH_CONF_UART +#define SLIP_ARCH_CONF_UART 0 /**< UART to use with SLIP */ +#endif +#endif + +#if !CC2538_RF_CONF_SNIFFER_USB +#ifndef CC2538_RF_CONF_SNIFFER_UART +#define CC2538_RF_CONF_SNIFFER_UART 0 /**< UART to use with sniffer */ +#endif +#endif + +#if !DBG_CONF_USB +#ifndef DBG_CONF_UART +#define DBG_CONF_UART 0 /**< UART to use for debugging */ +#endif +#endif + +#ifndef UART1_CONF_UART +#define UART1_CONF_UART 0 /**< UART to use for examples relying on + the uart1_* API */ +#endif + +/* Turn off example-provided putchars */ +#define SLIP_BRIDGE_CONF_NO_PUTCHAR 1 +#define SLIP_RADIO_CONF_NO_PUTCHAR 1 + +#ifndef SLIP_ARCH_CONF_ENABLED +/* + * Determine whether we need SLIP + * This will keep working while UIP_FALLBACK_INTERFACE and CMD_CONF_OUTPUT + * keep using SLIP + */ +#if defined(UIP_FALLBACK_INTERFACE) || defined(CMD_CONF_OUTPUT) +#define SLIP_ARCH_CONF_ENABLED 1 +#endif +#endif + +/* + * When set, the radio turns off address filtering and sends all captured + * frames down a peripheral (UART or USB, depending on the value of + * CC2538_RF_CONF_SNIFFER_USB) + */ +#ifndef CC2538_RF_CONF_SNIFFER +#define CC2538_RF_CONF_SNIFFER 0 +#endif + +/** + * \brief Define this as 1 to build a headless node. + * + * The UART will not be initialised its clock will be gated, offering some + * energy savings. The USB will not be initialised either + */ +#ifndef CC2538_CONF_QUIET +#define CC2538_CONF_QUIET 0 +#endif + +/* CC2538_CONF_QUIET is hard and overrides all other related defines */ +#if CC2538_CONF_QUIET +#undef USB_SERIAL_CONF_ENABLE +#define USB_SERIAL_CONF_ENABLE 0 + +#undef UART_CONF_ENABLE +#define UART_CONF_ENABLE 0 + +#undef STARTUP_CONF_VERBOSE +#define STARTUP_CONF_VERBOSE 0 + +/* Little sanity check: We can't have quiet sniffers */ +#if CC2538_RF_CONF_SNIFFER +#error "CC2538_RF_CONF_SNIFFER == 1 and CC2538_CONF_QUIET == 1" +#error "These values are conflicting. Please set either to 0" +#endif +#endif /* CC2538_CONF_QUIET */ + +/** + * \brief Enable the USB core only if we need it + */ +#ifndef USB_SERIAL_CONF_ENABLE +#define USB_SERIAL_CONF_ENABLE \ + ((SLIP_ARCH_CONF_USB & SLIP_ARCH_CONF_ENABLED) | \ + DBG_CONF_USB | \ + (CC2538_RF_CONF_SNIFFER & CC2538_RF_CONF_SNIFFER_USB)) +#endif + +/* + * If debugging and SLIP use the same peripheral, this will be 1. Don't modify + * this + */ +#if SLIP_ARCH_CONF_ENABLED +#define DBG_CONF_SLIP_MUX (SLIP_ARCH_CONF_USB == DBG_CONF_USB && \ + (SLIP_ARCH_CONF_USB || \ + SLIP_ARCH_CONF_UART == DBG_CONF_UART)) +#endif + +/* + * Automatic detection of whether a specific UART is in use + */ +#define UART_IN_USE_BY_SERIAL_LINE(u) (SERIAL_LINE_CONF_UART == (u)) +#define UART_IN_USE_BY_SLIP(u) (SLIP_ARCH_CONF_ENABLED && \ + !SLIP_ARCH_CONF_USB && \ + SLIP_ARCH_CONF_UART == (u)) +#define UART_IN_USE_BY_RF_SNIFFER(u) (CC2538_RF_CONF_SNIFFER && \ + !CC2538_RF_CONF_SNIFFER_USB && \ + CC2538_RF_CONF_SNIFFER_UART == (u)) +#define UART_IN_USE_BY_DBG(u) (!DBG_CONF_USB && DBG_CONF_UART == (u)) +#define UART_IN_USE_BY_UART1(u) (UART1_CONF_UART == (u)) + +#define UART_IN_USE(u) ( \ + UART_CONF_ENABLE && \ + (UART_IN_USE_BY_SERIAL_LINE(u) || \ + UART_IN_USE_BY_SLIP(u) || \ + UART_IN_USE_BY_RF_SNIFFER(u) || \ + UART_IN_USE_BY_DBG(u) || \ + UART_IN_USE_BY_UART1(u)) \ + ) +/** @} */ +/*---------------------------------------------------------------------------*/ +/* board.h assumes that basic configuration is done */ +#include "board.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Network Stack Configuration + * + * @{ + */ +#ifndef NETSTACK_CONF_NETWORK +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#else +#define NETSTACK_CONF_NETWORK rime_driver +#endif /* NETSTACK_CONF_WITH_IPV6 */ +#endif /* NETSTACK_CONF_NETWORK */ + +#ifndef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC csma_driver +#endif + +#ifndef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC contikimac_driver +#endif + +/* Configure NullRDC for when it's selected */ +#define NULLRDC_802154_AUTOACK 1 +#define NULLRDC_802154_AUTOACK_HW 1 + +/* Configure ContikiMAC for when it's selected */ +#define CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION 0 +#define WITH_FAST_SLEEP 1 + +#ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 +#endif + +#ifndef NETSTACK_CONF_FRAMER +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_FRAMER framer_802154 +#else /* NETSTACK_CONF_WITH_IPV6 */ +#define NETSTACK_CONF_FRAMER contikimac_framer +#endif /* NETSTACK_CONF_WITH_IPV6 */ +#endif /* NETSTACK_CONF_FRAMER */ + +#ifndef NETSTACK_CONF_RADIO +#define NETSTACK_CONF_RADIO cc2538_rf_driver +#endif + +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name LPM configuration + * @{ + */ +#ifndef LPM_CONF_ENABLE +#define LPM_CONF_ENABLE 1 /**< Set to 0 to disable LPM entirely */ +#endif + +/** + * \brief Maximum PM + * + * The SoC will never drop to a Power Mode deeper than the one specified here. + * 0 for PM0, 1 for PM1 and 2 for PM2 + */ +#ifndef LPM_CONF_MAX_PM +#define LPM_CONF_MAX_PM 1 +#endif + +#ifndef LPM_CONF_STATS +#define LPM_CONF_STATS 0 /**< Set to 1 to enable LPM-related stats */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name IEEE address configuration + * + * Used to generate our RIME & IPv6 address + * @{ + */ +/** + * \brief Location of the IEEE address + * 0 => Read from InfoPage, + * 1 => Use a hardcoded address, configured by IEEE_ADDR_CONF_ADDRESS + */ +#ifndef IEEE_ADDR_CONF_HARDCODED +#define IEEE_ADDR_CONF_HARDCODED 0 +#endif + +/** + * \brief The hardcoded IEEE address to be used when IEEE_ADDR_CONF_HARDCODED + * is defined as 1 + */ +#ifndef IEEE_ADDR_CONF_ADDRESS +#define IEEE_ADDR_CONF_ADDRESS { 0x00, 0x12, 0x4B, 0x00, 0x89, 0xAB, 0xCD, 0xEF } +#endif + +/** + * \brief Location of the IEEE address in the InfoPage when + * IEEE_ADDR_CONF_HARDCODED is defined as 0 + * 0 => Use the primary address location + * 1 => Use the secondary address location + */ +#ifndef IEEE_ADDR_CONF_USE_SECONDARY_LOCATION +#define IEEE_ADDR_CONF_USE_SECONDARY_LOCATION 0 +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name RF configuration + * + * @{ + */ +/* RF Config */ +#ifndef IEEE802154_CONF_PANID +#define IEEE802154_CONF_PANID 0xABCD +#endif + +#ifndef CC2538_RF_CONF_CHANNEL +#define CC2538_RF_CONF_CHANNEL 26 +#endif /* CC2538_RF_CONF_CHANNEL */ + +#ifndef CC2538_RF_CONF_AUTOACK +#define CC2538_RF_CONF_AUTOACK 1 /**< RF H/W generates ACKs */ +#endif /* CC2538_CONF_AUTOACK */ + +#ifndef CC2538_RF_CONF_TX_USE_DMA +#define CC2538_RF_CONF_TX_USE_DMA 1 /**< RF TX over DMA */ +#endif + +#ifndef CC2538_RF_CONF_RX_USE_DMA +#define CC2538_RF_CONF_RX_USE_DMA 1 /**< RF RX over DMA */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name IPv6, RIME and network buffer configuration + * + * @{ + */ + +/* Don't let contiki-default-conf.h decide if we are an IPv6 build */ +#ifndef NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_WITH_IPV6 0 +#endif + +#if NETSTACK_CONF_WITH_IPV6 +/* Addresses, Sizes and Interfaces */ +/* 8-byte addresses here, 2 otherwise */ +#define LINKADDR_CONF_SIZE 8 +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 +#define UIP_CONF_NETIF_MAX_ADDRESSES 3 + +/* TCP, UDP, ICMP */ +#ifndef UIP_CONF_TCP +#define UIP_CONF_TCP 1 +#endif +#ifndef UIP_CONF_TCP_MSS +#define UIP_CONF_TCP_MSS 64 +#endif +#define UIP_CONF_UDP 1 +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_ICMP6 1 + +/* ND and Routing */ +#ifndef UIP_CONF_ROUTER +#define UIP_CONF_ROUTER 1 +#endif + +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_IP_FORWARD 0 +#define RPL_CONF_STATS 0 + +#ifndef RPL_CONF_OF +#define RPL_CONF_OF rpl_mrhof +#endif + +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#endif +#ifndef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 20 +#endif + +/* uIP */ +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 1300 +#endif + +#define UIP_CONF_IPV6_QUEUE_PKT 0 +#define UIP_CONF_IPV6_CHECKS 1 +#define UIP_CONF_IPV6_REASSEMBLY 0 +#define UIP_CONF_MAX_LISTENPORTS 8 + +/* 6lowpan */ +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#ifndef SICSLOWPAN_CONF_COMPRESSION_THRESHOLD +#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63 +#endif +#ifndef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +#endif +#define SICSLOWPAN_CONF_MAXAGE 8 + +/* Define our IPv6 prefixes/contexts here */ +#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 +#ifndef SICSLOWPAN_CONF_ADDR_CONTEXT_0 +#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 { \ + addr_contexts[0].prefix[0] = UIP_DS6_DEFAULT_PREFIX_0; \ + addr_contexts[0].prefix[1] = UIP_DS6_DEFAULT_PREFIX_1; \ +} +#endif + +#define MAC_CONF_CHANNEL_CHECK_RATE 8 + +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 8 +#endif +/*---------------------------------------------------------------------------*/ +#else /* NETSTACK_CONF_WITH_IPV6 */ +/* Network setup for non-IPv6 (rime). */ +#define UIP_CONF_IP_FORWARD 1 + +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 108 +#endif + +#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 + +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 8 +#endif + +#endif /* NETSTACK_CONF_WITH_IPV6 */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Security + * + * @{ + */ +#ifndef CRYPTO_CONF_INIT +#define CRYPTO_CONF_INIT 1 /**< Whether to init cryptoprocessor */ +#endif + +#ifndef AES_128_CONF +#define AES_128_CONF cc2538_aes_128_driver /**< AES-128 driver */ +#endif + +#ifndef CCM_STAR_CONF +#define CCM_STAR_CONF cc2538_ccm_star_driver /**< AES-CCM* driver */ +#endif + +/*---------------------------------------------------------------------------*/ +#endif /* CONTIKI_CONF_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/contiki-main.c b/platform/openmote-cc2538/contiki-main.c new file mode 100644 index 000000000..580f84f56 --- /dev/null +++ b/platform/openmote-cc2538/contiki-main.c @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup platform + * @{ + * + * \defgroup openmote-cc2538 OpenMote-CC2538 platform + * + * The OpenMote-CC2538 is based on the CC2538, the new platform by Texas Instruments + * based on an ARM Cortex-M3 core and a IEEE 802.15.4 radio. + * @{ + * + * \file + * Main module for the OpenMote-CC2538 platform + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/leds.h" +#include "dev/sys-ctrl.h" +#include "dev/scb.h" +#include "dev/nvic.h" +#include "dev/uart.h" +#include "dev/i2c.h" +#include "dev/watchdog.h" +#include "dev/ioc.h" +#include "dev/button-sensor.h" +#include "dev/serial-line.h" +#include "dev/slip.h" +#include "dev/cc2538-rf.h" +#include "dev/udma.h" +#include "dev/crypto.h" +#include "usb/usb-serial.h" +#include "lib/random.h" +#include "net/netstack.h" +#include "net/queuebuf.h" +#include "net/ip/tcpip.h" +#include "net/ip/uip.h" +#include "net/mac/frame802154.h" +#include "soc.h" +#include "cpu.h" +#include "reg.h" +#include "ieee-addr.h" +#include "lpm.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#if STARTUP_CONF_VERBOSE +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#if UART_CONF_ENABLE +#define PUTS(s) puts(s) +#else +#define PUTS(s) +#endif +/*---------------------------------------------------------------------------*/ +/** + * \brief Board specific iniatialisation + */ +void board_init(void); +/*---------------------------------------------------------------------------*/ +static void +fade(unsigned char l) +{ + volatile int i; + int k, j; + for(k = 0; k < 800; ++k) { + j = k > 400 ? 800 - k : k; + + leds_on(l); + for(i = 0; i < j; ++i) { + asm("nop"); + } + leds_off(l); + for(i = 0; i < 400 - j; ++i) { + asm("nop"); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +set_rf_params(void) +{ + uint16_t short_addr; + uint8_t ext_addr[8]; + + ieee_addr_cpy_to(ext_addr, 8); + + short_addr = ext_addr[7]; + short_addr |= ext_addr[6] << 8; + + /* Populate linkaddr_node_addr. Maintain endianness */ + memcpy(&linkaddr_node_addr, &ext_addr[8 - LINKADDR_SIZE], LINKADDR_SIZE); + +#if STARTUP_CONF_VERBOSE + { + int i; + printf("Rime configured with address "); + for(i = 0; i < LINKADDR_SIZE - 1; i++) { + printf("%02x:", linkaddr_node_addr.u8[i]); + } + printf("%02x\n", linkaddr_node_addr.u8[i]); + } +#endif + + NETSTACK_RADIO.set_value(RADIO_PARAM_PAN_ID, IEEE802154_PANID); + NETSTACK_RADIO.set_value(RADIO_PARAM_16BIT_ADDR, short_addr); + NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, CC2538_RF_CHANNEL); + NETSTACK_RADIO.set_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Main routine for the OpenMote-CC2538 platforms + */ +int +main(void) +{ + nvic_init(); + ioc_init(); + sys_ctrl_init(); + clock_init(); + lpm_init(); + rtimer_init(); + gpio_init(); + leds_init(); + fade(LEDS_RED); + process_init(); + watchdog_init(); + +#if UART_CONF_ENABLE + uart_init(0); + uart_init(1); + uart_set_input(SERIAL_LINE_CONF_UART, serial_line_input_byte); +#endif + +#if USB_SERIAL_CONF_ENABLE + usb_serial_init(); + usb_serial_set_input(serial_line_input_byte); +#endif + + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, I2C_SCL_NORMAL_BUS_SPEED); + + serial_line_init(); + + INTERRUPTS_ENABLE(); + fade(LEDS_BLUE); + + PUTS(CONTIKI_VERSION_STRING); + PUTS(BOARD_STRING); +#if STARTUP_CONF_VERBOSE + soc_print_info(); +#endif + + random_init(0); + + udma_init(); + + process_start(&etimer_process, NULL); + ctimer_init(); + + board_init(); + +#if CRYPTO_CONF_INIT + crypto_init(); + crypto_disable(); +#endif + + netstack_init(); + set_rf_params(); + + PRINTF("Net: "); + PRINTF("%s\n", NETSTACK_NETWORK.name); + PRINTF("MAC: "); + PRINTF("%s\n", NETSTACK_MAC.name); + PRINTF("RDC: "); + PRINTF("%s\n", NETSTACK_RDC.name); + +#if NETSTACK_CONF_WITH_IPV6 + memcpy(&uip_lladdr.addr, &linkaddr_node_addr, sizeof(uip_lladdr.addr)); + queuebuf_init(); + process_start(&tcpip_process, NULL); +#endif /* NETSTACK_CONF_WITH_IPV6 */ + + process_start(&sensors_process, NULL); + + SENSORS_ACTIVATE(button_sensor); + + energest_init(); + ENERGEST_ON(ENERGEST_TYPE_CPU); + + autostart_start(autostart_processes); + + watchdog_start(); + fade(LEDS_GREEN); + + while(1) { + uint8_t r; + do { + watchdog_periodic(); + + r = process_run(); + } while(r > 0); + + lpm_enter(); + } +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/adxl346.c b/platform/openmote-cc2538/dev/adxl346.c new file mode 100644 index 000000000..400e3fdf6 --- /dev/null +++ b/platform/openmote-cc2538/dev/adxl346.c @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-adxl346-sensor + * @{ + * + * \file + * Driver for the ADXL346 acceleration sensor + * + * \author + * Pere Tuset + */ +/*---------------------------------------------------------------------------*/ +#include "dev/i2c.h" +#include "dev/adxl346.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +/** + * \name ADXL346 address and device identifier + * @{ + */ +#define ADXL346_ADDRESS (0x53) +#define ADXL346_DEVID_VALUE (0xE6) +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name ADXL346 register addresses + * @{ + */ +#define ADXL346_DEVID_ADDR (0x00) +#define ADXL346_THRES_TAP_ADDR (0x1D) +#define ADXL346_OFSX_ADDR (0x1E) +#define ADXL346_OFSY_ADDR (0x1F) +#define ADXL346_OFSZ_ADDR (0x20) +#define ADXL346_DUR_ADDR (0x21) +#define ADXL346_LATENT_ADDR (0x22) +#define ADXL346_WINDOW_ADDR (0x23) +#define ADXL346_THRESH_ACT_ADDR (0x24) +#define ADXL346_THRESH_INACT_ADDR (0x25) +#define ADXL346_TIME_INACT_ADDR (0x26) +#define ADXL346_ACT_INACT_CTL_ADDR (0x27) +#define ADXL346_THRESH_FF_ADDR (0x28) +#define ADXL346_TIME_FF_ADDR (0x29) +#define ADXL346_TAP_AXES_ADDR (0x2A) +#define ADXL346_ACT_TAP_STATUS_ADDR (0x2B) +#define ADXL346_BW_RATE_ADDR (0x2C) +#define ADXL346_POWER_CTL_ADDR (0x2D) +#define ADXL346_INT_ENABLE_ADDR (0x2E) +#define ADXL346_INT_MAP_ADDR (0x2F) +#define ADXL346_INT_SOURCE_ADDR (0x30) +#define ADXL346_DATA_FORMAT_ADDR (0x31) +#define ADXL346_DATAX0_ADDR (0x32) +#define ADXL346_DATAX1_ADDR (0x33) +#define ADXL346_DATAY0_ADDR (0x34) +#define ADXL346_DATAY1_ADDR (0x35) +#define ADXL346_DATAZ0_ADDR (0x36) +#define ADXL346_DATAZ1_ADDR (0x37) +#define ADXL346_FIFO_CTL_ADDR (0x38) +#define ADXL346_FIFO_STATUS_ADDR (0x39) +#define ADXL346_TAP_SIGN_ADDR (0x3A) +#define ADXL346_ORIENT_CONF_ADDR (0x3B) +#define ADXL346_ORIENT_ADDR (0x3C) +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name ADXL346 register values + * @{ + */ +#define ADXL346_INT_ENABLE_DATA_READY (1 << 7) +#define ADXL346_INT_ENABLE_SINGLE_TAP (1 << 6) +#define ADXL346_INT_ENABLE_DOUBLE_TAP (1 << 5) +#define ADXL346_INT_ENABLE_ACTIVITY (1 << 4) +#define ADXL346_INT_ENABLE_INACTIVITY (1 << 3) +#define ADXL346_INT_ENABLE_FREE_FALL (1 << 2) +#define ADXL346_INT_ENABLE_WATERMARK (1 << 1) +#define ADXL346_INT_ENABLE_OVERRUN (1 << 0) + +#define ADXL346_ACT_INACT_CTL_ACT_ACDC (1 << 7) +#define ADXL346_ACT_INACT_CTL_ACT_X_EN (1 << 6) +#define ADXL346_ACT_INACT_CTL_ACT_Y_EN (1 << 5) +#define ADXL346_ACT_INACT_CTL_ACT_Z_EN (1 << 4) +#define ADXL346_ACT_INACT_CTL_INACT_ACDC (1 << 3) +#define ADXL346_ACT_INACT_CTL_INACT_X_EN (1 << 2) +#define ADXL346_ACT_INACT_CTL_INACT_Y_EN (1 << 1) +#define ADXL346_ACT_INACT_CTL_INACT_Z_EN (1 << 0) + +#define ADXL346_TAP_AXES_SUPPRESS (1 << 3) +#define ADXL346_TAP_AXES_TAP_X_EN (1 << 2) +#define ADXL346_TAP_AXES_TAP_Y_EN (1 << 1) +#define ADXL346_TAP_AXES_TAP_Z_EN (1 << 0) + +#define ADXL346_ACT_TAP_STATUS_ACT_X_SRC (1 << 6) +#define ADXL346_ACT_TAP_STATUS_ACT_Y_SRC (1 << 5) +#define ADXL346_ACT_TAP_STATUS_ACT_Z_SRC (1 << 4) +#define ADXL346_ACT_TAP_STATUS_ASLEEP (1 << 3) +#define ADXL346_ACT_TAP_STATUS_TAP_X_SRC (1 << 2) +#define ADXL346_ACT_TAP_STATUS_TAP_Y_SRC (1 << 1) +#define ADXL346_ACT_TAP_STATUS_TAP_Z_SRC (1 << 0) + +#define ADXL346_BW_RATE_POWER (1 << 4) +#define ADXL346_BW_RATE_RATE(x) ((x) & 0x0F) + +#define ADXL346_POWER_CTL_LINK (1 << 5) +#define ADXL346_POWER_CTL_AUTO_SLEEP (1 << 4) +#define ADXL346_POWER_CTL_MEASURE (1 << 3) +#define ADXL346_POWER_CTL_SLEEP (1 << 2) +#define ADXL346_POWER_CTL_WAKEUP(x) ((x) & 0x03) + +#define ADXL346_DATA_FORMAT_SELF_TEST (1 << 7) +#define ADXL346_DATA_FORMAT_SPI (1 << 6) +#define ADXL346_DATA_FORMAT_INT_INVERT (1 << 5) +#define ADXL346_DATA_FORMAT_FULL_RES (1 << 3) +#define ADXL346_DATA_FORMAT_JUSTIFY (1 << 2) +#define ADXL346_DATA_FORMAT_RANGE(x) ((x) & 0x03) +#define ADXL346_DATA_FORMAT_RANGE_PM_2g (0) +#define ADXL346_DATA_FORMAT_RANGE_PM_4g (1) +#define ADXL346_DATA_FORMAT_RANGE_PM_8g (2) +#define ADXL346_DATA_FORMAT_RANGE_PM_16g (3) + +#define ADXL346_USER_CONFIGURATION (ADXL346_DATA_FORMAT_RANGE_PM_2g) + +/** @} */ +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +static void +adxl346_init(void) +{ + uint8_t config[2]; + + config[0] = ADXL346_BW_RATE_ADDR; + config[1] = (ADXL346_BW_RATE_RATE(6)); + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); + + config[0] = ADXL346_DATA_FORMAT_ADDR; + config[1] = (ADXL346_USER_CONFIGURATION); + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); + + config[0] = ADXL346_POWER_CTL_ADDR; + config[1] = (ADXL346_POWER_CTL_MEASURE); + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); +} +/*---------------------------------------------------------------------------*/ +static uint8_t +adxl346_is_present(void) +{ + uint8_t is_present; + + i2c_single_send(ADXL346_ADDRESS, ADXL346_DEVID_ADDR); + i2c_single_receive(ADXL346_ADDRESS, &is_present); + + return is_present == ADXL346_DEVID_VALUE; +} +/*---------------------------------------------------------------------------*/ +static int16_t +adxl346_read_accel(uint8_t addr1, uint8_t addr2) +{ + uint8_t acceleration[2]; + int16_t result; + + i2c_single_send(ADXL346_ADDRESS, addr1); + i2c_single_receive(ADXL346_ADDRESS, &acceleration[0]); + i2c_single_send(ADXL346_ADDRESS, addr2); + i2c_single_receive(ADXL346_ADDRESS, &acceleration[1]); + + result = (acceleration[1] << 8) | acceleration[0]; + + return result; +} +/*---------------------------------------------------------------------------*/ +static int16_t +adxl346_convert_accel(int16_t accel) +{ + int32_t result; + + result = (1000 * accel) / 256; + + return (int16_t)result; +} +/*---------------------------------------------------------------------------*/ +static void +adxl346_calibrate_offset(void) +{ + int32_t accum_x = 0; + int32_t accum_y = 0; + int32_t accum_z = 0; + uint8_t config[2]; + int8_t offset; + + config[0] = ADXL346_OFSX_ADDR; + config[1] = 0; + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); + config[0] = ADXL346_OFSY_ADDR; + config[1] = 0; + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); + config[0] = ADXL346_OFSZ_ADDR; + config[1] = 0; + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); + + uint16_t i; + for(i = 0; i < 100; i++) { + uint16_t x, y, z; + + x = adxl346_read_accel(ADXL346_DATAX0_ADDR, ADXL346_DATAX1_ADDR); + accum_x += x; + + y = adxl346_read_accel(ADXL346_DATAY0_ADDR, ADXL346_DATAY1_ADDR); + accum_y += y; + + z = adxl346_read_accel(ADXL346_DATAZ0_ADDR, ADXL346_DATAZ1_ADDR); + accum_z += z; + } + + offset = (64 * accum_x) / 25600; + config[0] = ADXL346_OFSX_ADDR; + config[1] = -offset; + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); + PRINTF("ADXL346: X calibration offset is %d\n", offset); + + offset = (64 * accum_y) / 25600; + config[0] = ADXL346_OFSY_ADDR; + config[1] = -offset; + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); + PRINTF("ADXL346: Y calibration offset is %d\n", offset); + + offset = (64 * accum_z) / 25600; + config[0] = ADXL346_OFSZ_ADDR; + config[1] = -offset; + i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); + PRINTF("ADXL346: Z calibration offset is %d\n", offset); +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + int16_t accel; + if(!enabled) { + PRINTF("ADXL346: sensor not started\n"); + return ADXL346_ERROR; + } + + if(type == ADXL346_READ_X) { + return adxl346_read_accel(ADXL346_DATAX0_ADDR, ADXL346_DATAX1_ADDR); + } else if(type == ADXL346_READ_Y) { + return adxl346_read_accel(ADXL346_DATAY0_ADDR, ADXL346_DATAY1_ADDR); + } else if(type == ADXL346_READ_Z) { + return adxl346_read_accel(ADXL346_DATAZ0_ADDR, ADXL346_DATAZ1_ADDR); + } else if(type == ADXL346_READ_X_mG) { + accel = adxl346_read_accel(ADXL346_DATAX0_ADDR, ADXL346_DATAX1_ADDR); + return adxl346_convert_accel(accel); + } else if(type == ADXL346_READ_Y_mG) { + accel = adxl346_read_accel(ADXL346_DATAY0_ADDR, ADXL346_DATAY1_ADDR); + return adxl346_convert_accel(accel); + } else if(type == ADXL346_READ_Z_mG) { + accel = adxl346_read_accel(ADXL346_DATAZ0_ADDR, ADXL346_DATAZ1_ADDR); + return adxl346_convert_accel(accel); + } else { + PRINTF("ADXL346: invalid value requested\n"); + return ADXL346_ERROR; + } + + return ADXL346_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type == ADXL346_ACTIVATE) { + if(!adxl346_is_present()) { + PRINTF("ADXL346: is not present\n"); + enabled = 0; + return ADXL346_ERROR; + } else { + adxl346_init(); + enabled = 1; + return ADXL346_SUCCESS; + } + } + + if(type == ADXL346_CALIB_OFFSET && enabled) { + adxl346_calibrate_offset(); + return ADXL346_SUCCESS; + } + + return ADXL346_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(adxl346, ADXL346_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/openmote-cc2538/dev/adxl346.h b/platform/openmote-cc2538/dev/adxl346.h new file mode 100644 index 000000000..401e601d1 --- /dev/null +++ b/platform/openmote-cc2538/dev/adxl346.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-sensors + * @{ + * + * \defgroup openmote-adxl346-sensor ADXL346 acceleration sensor + * @{ + * + * \file + * ADXL346 acceleration sensor driver header file + * + * \author + * Pere Tuset + */ +/*---------------------------------------------------------------------------*/ +#ifndef ADXL346_H_ +#define ADXL346_H_ +/*---------------------------------------------------------------------------*/ +#define ADXL346_ERROR (-1) +#define ADXL346_SUCCESS (0) +#define ADXL346_ACTIVATE (SENSORS_ACTIVE) +#define ADXL346_READ_X (2) +#define ADXL346_READ_X_mG (3) +#define ADXL346_READ_Y (4) +#define ADXL346_READ_Y_mG (5) +#define ADXL346_READ_Z (6) +#define ADXL346_READ_Z_mG (7) +#define ADXL346_CALIB_OFFSET (8) +#define ADXL346_NONE (9) +/*---------------------------------------------------------------------------*/ +#define ADXL346_SENSOR "ADXL346 Sensor" +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor adxl346; +/*---------------------------------------------------------------------------*/ +#endif /* ADXL346_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/antenna.c b/platform/openmote-cc2538/dev/antenna.c new file mode 100644 index 000000000..3672258f9 --- /dev/null +++ b/platform/openmote-cc2538/dev/antenna.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-antenna + * @{ + * + * Driver for the OpenMote-CC2538 RF switch. + * INT is the internal antenna (chip) configured through ANT1_SEL (V1) + * EXT is the external antenna (connector) configured through ANT2_SEL (V2) + * @{ + * + * \file + * Driver implementation for the OpenMote-CC2538 antenna switch + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "dev/gpio.h" +#include "dev/antenna.h" +/*---------------------------------------------------------------------------*/ +#define BSP_RADIO_BASE GPIO_PORT_TO_BASE(GPIO_D_NUM) +#define BSP_RADIO_INT GPIO_PIN_MASK(5) +#define BSP_RADIO_EXT GPIO_PIN_MASK(4) +/*---------------------------------------------------------------------------*/ +void +antenna_init(void) +{ + /* Configure the ANT1 and ANT2 GPIO as output */ + GPIO_SET_OUTPUT(BSP_RADIO_BASE, BSP_RADIO_INT); + GPIO_SET_OUTPUT(BSP_RADIO_BASE, BSP_RADIO_EXT); + + /* Select external antenna by default. */ + antenna_external(); +} +/*---------------------------------------------------------------------------*/ +void +antenna_external(void) +{ + GPIO_WRITE_PIN(BSP_RADIO_BASE, BSP_RADIO_INT, 0); + GPIO_WRITE_PIN(BSP_RADIO_BASE, BSP_RADIO_EXT, 1); +} +/*---------------------------------------------------------------------------*/ +void +antenna_internal(void) +{ + GPIO_WRITE_PIN(BSP_RADIO_BASE, BSP_RADIO_EXT, 0); + GPIO_WRITE_PIN(BSP_RADIO_BASE, BSP_RADIO_INT, 1); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/antenna.h b/platform/openmote-cc2538/dev/antenna.h new file mode 100644 index 000000000..9c42bf885 --- /dev/null +++ b/platform/openmote-cc2538/dev/antenna.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2014, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ +/*--------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-cc2538 + * @{ + * + * \defgroup openmote-antenna OpenMote-CC2538 antenna switch + * + * Driver for the OpenMote-CC2538 antenna switch + * @{ + * + * \file + * Header for the OpenMote-CC2538 antenna switch + */ +/*---------------------------------------------------------------------------*/ +#ifndef ANTENNA_H_ +#define ANTENNA_H_ +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize the antenna switch, by default it uses the external + */ +void antenna_init(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Select the external (connector) antenna + */ +void antenna_internal(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Select the internal (chip) antenna + */ +void antenna_external(void); +/*---------------------------------------------------------------------------*/ +#endif /* ANTENNA_H_ */ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/button-sensor.c b/platform/openmote-cc2538/dev/button-sensor.c new file mode 100644 index 000000000..6477045c5 --- /dev/null +++ b/platform/openmote-cc2538/dev/button-sensor.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-button-sensor + * @{ + * + * \file + * Driver for for the OpenMote-CC2538 user button + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/nvic.h" +#include "dev/ioc.h" +#include "dev/gpio.h" +#include "dev/button-sensor.h" +#include "sys/timer.h" +#include "sys/ctimer.h" +#include "sys/process.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define BUTTON_USER_PORT_BASE GPIO_PORT_TO_BASE(BUTTON_USER_PORT) +#define BUTTON_USER_PIN_MASK GPIO_PIN_MASK(BUTTON_USER_PIN) +/*---------------------------------------------------------------------------*/ +#define DEBOUNCE_DURATION (CLOCK_SECOND >> 4) + +static struct timer debouncetimer; +/*---------------------------------------------------------------------------*/ +static clock_time_t press_duration = 0; +static struct ctimer press_counter; +static uint8_t press_event_counter; + +process_event_t button_press_duration_exceeded; +/*---------------------------------------------------------------------------*/ +static void +duration_exceeded_callback(void *data) +{ + press_event_counter++; + process_post(PROCESS_BROADCAST, button_press_duration_exceeded, + &press_event_counter); + ctimer_set(&press_counter, press_duration, duration_exceeded_callback, + NULL); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Retrieves the value of the button pin + * \param type Returns the pin level or the counter of press duration events. + * type == BUTTON_SENSOR_VALUE_TYPE_LEVEL or + * type == BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION + * respectively + */ +static int +value(int type) +{ + switch(type) { + case BUTTON_SENSOR_VALUE_TYPE_LEVEL: + return GPIO_READ_PIN(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + case BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION: + return press_event_counter; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Callback registered with the GPIO module. Gets fired with a button + * port/pin generates an interrupt + * \param port The port number that generated the interrupt + * \param pin The pin number that generated the interrupt. This is the pin + * absolute number (i.e. 0, 1, ..., 7), not a mask + */ +static void +btn_callback(uint8_t port, uint8_t pin) +{ + if(!timer_expired(&debouncetimer)) { + return; + } + + timer_set(&debouncetimer, DEBOUNCE_DURATION); + + if(press_duration) { + press_event_counter = 0; + if(value(BUTTON_SENSOR_VALUE_TYPE_LEVEL) == BUTTON_SENSOR_PRESSED_LEVEL) { + ctimer_set(&press_counter, press_duration, duration_exceeded_callback, + NULL); + } else { + ctimer_stop(&press_counter); + } + } + + sensors_changed(&button_sensor); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Init function for the User button. + * \param type SENSORS_ACTIVE: Activate / Deactivate the sensor (value == 1 + * or 0 respectively) + * + * \param value Depends on the value of the type argument + * \return Depends on the value of the type argument + */ +static int +config_user(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: + button_press_duration_exceeded = process_alloc_event(); + + /* Software controlled */ + GPIO_SOFTWARE_CONTROL(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + + /* Set pin to input */ + GPIO_SET_INPUT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + + /* Enable edge detection */ + GPIO_DETECT_EDGE(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + + /* Both Edges */ + GPIO_TRIGGER_BOTH_EDGES(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + + ioc_set_over(BUTTON_USER_PORT, BUTTON_USER_PIN, IOC_OVERRIDE_PUE); + + gpio_register_callback(btn_callback, BUTTON_USER_PORT, BUTTON_USER_PIN); + break; + case SENSORS_ACTIVE: + if(value) { + GPIO_ENABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + nvic_interrupt_enable(BUTTON_USER_VECTOR); + } else { + GPIO_DISABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + nvic_interrupt_disable(BUTTON_USER_VECTOR); + } + return value; + case BUTTON_SENSOR_CONFIG_TYPE_INTERVAL: + press_duration = (clock_time_t)value; + break; + default: + break; + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, value, config_user, NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/openmote-cc2538/dev/button-sensor.h b/platform/openmote-cc2538/dev/button-sensor.h new file mode 100644 index 000000000..9a08634ae --- /dev/null +++ b/platform/openmote-cc2538/dev/button-sensor.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-cc2538 + * @{ + * + * \defgroup openmote-button-sensor OpenMote-CC2538 user button driver + * + * The user button will generate a sensors_changed event on press as + * well as on release. + * + * @{ + * + * \file + * Header for the OpenMote-CC2538 button driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef BUTTON_SENSOR_H_ +#define BUTTON_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR "Button" + +extern const struct sensors_sensor button_sensor; +/*---------------------------------------------------------------------------*/ +extern process_event_t button_press_duration_exceeded; +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR_CONFIG_TYPE_INTERVAL 0x0100 + +#define BUTTON_SENSOR_VALUE_TYPE_LEVEL 0 +#define BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION 1 + +#define BUTTON_SENSOR_PRESSED_LEVEL 0 +#define BUTTON_SENSOR_RELEASED_LEVEL 8 +/*---------------------------------------------------------------------------*/ +#endif /* BUTTON_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/leds-arch.c b/platform/openmote-cc2538/dev/leds-arch.c new file mode 100644 index 000000000..28454dacf --- /dev/null +++ b/platform/openmote-cc2538/dev/leds-arch.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-cc2538 + * @{ + * + * \defgroup openmote-leds OpenMote-CC2538 LED driver + * @{ + * + * \file + * LED driver implementation for the OpenMote-CC2538 platform + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "reg.h" +#include "dev/leds.h" +#include "dev/gpio.h" +/*---------------------------------------------------------------------------*/ +#define LEDS_GPIO_PIN_MASK LEDS_ALL +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + GPIO_SET_OUTPUT(GPIO_C_BASE, LEDS_GPIO_PIN_MASK); +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + return GPIO_READ_PIN(GPIO_C_BASE, LEDS_GPIO_PIN_MASK); +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char leds) +{ + GPIO_WRITE_PIN(GPIO_C_BASE, LEDS_GPIO_PIN_MASK, leds); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/max44009.c b/platform/openmote-cc2538/dev/max44009.c new file mode 100644 index 000000000..d7f4e90d9 --- /dev/null +++ b/platform/openmote-cc2538/dev/max44009.c @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-max44009-sensor + * @{ + * + * \file + * Driver for the MAX44009 light sensor + * + * \author + * Pere Tuset + */ +/*---------------------------------------------------------------------------*/ +#include "dev/i2c.h" +#include "dev/max44009.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +/** + * \name MAX44009 address and device identifier + * @{ + */ +#define MAX44009_ADDRESS (0x4A) +#define MAX44009_NOT_FOUND (0x00) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name MAX44009 register addresses + * @{ + */ +#define MAX44009_INT_STATUS_ADDR (0x00) /* R */ +#define MAX44009_INT_ENABLE_ADDR (0x01) /* R/W */ +#define MAX44009_CONFIG_ADDR (0x02) /* R/W */ +#define MAX44009_LUX_HIGH_ADDR (0x03) /* R */ +#define MAX44009_LUX_LOW_ADDR (0x04) /* R */ +#define MAX44009_THR_HIGH_ADDR (0x05) /* R/W */ +#define MAX44009_THR_LOW_ADDR (0x06) /* R/W */ +#define MAX44009_THR_TIMER_ADDR (0x07) /* R/W */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name MAX44009 register values + * @{ + */ +#define MAX44009_INT_STATUS_OFF (0x00) +#define MAX44009_INT_STATUS_ON (0x01) +#define MAX44009_INT_DISABLED (0x00) +#define MAX44009_INT_ENABLED (0x01) + +#define MAX44009_CONFIG_DEFAULT (0 << 7) +#define MAX44009_CONFIG_CONTINUOUS (1 << 7) +#define MAX44009_CONFIG_AUTO (0 << 6) +#define MAX44009_CONFIG_MANUAL (1 << 6) +#define MAX44009_CONFIG_CDR_NORMAL (0 << 5) +#define MAX44009_CONFIG_CDR_DIVIDED (1 << 5) +#define MAX44009_CONFIG_INTEGRATION_800ms (0 << 0) +#define MAX44009_CONFIG_INTEGRATION_400ms (1 << 0) +#define MAX44009_CONFIG_INTEGRATION_200ms (2 << 0) +#define MAX44009_CONFIG_INTEGRATION_100ms (3 << 0) +#define MAX44009_CONFIG_INTEGRATION_50ms (4 << 0) +#define MAX44009_CONFIG_INTEGRATION_25ms (5 << 0) +#define MAX44009_CONFIG_INTEGRATION_12ms (6 << 0) +#define MAX44009_CONFIG_INTEGRATION_6ms (7 << 0) + +#define MAX44009_DEFAULT_CONFIGURATION (MAX44009_CONFIG_DEFAULT | \ + MAX44009_CONFIG_AUTO | \ + MAX44009_CONFIG_CDR_NORMAL | \ + MAX44009_CONFIG_INTEGRATION_100ms) + +#define MAX44009_USER_CONFIGURATION (MAX44009_CONFIG_DEFAULT | \ + MAX44009_CONFIG_AUTO | \ + MAX44009_CONFIG_CDR_NORMAL | \ + MAX44009_CONFIG_INTEGRATION_800ms) + +/** @} */ +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +static void +max44009_init(void) +{ + uint8_t max44009_address[5] = { MAX44009_INT_ENABLE_ADDR, MAX44009_CONFIG_ADDR, \ + MAX44009_THR_HIGH_ADDR, MAX44009_THR_LOW_ADDR, \ + MAX44009_THR_TIMER_ADDR }; + uint8_t max44009_value[5]; + uint8_t max44009_data[2]; + uint8_t i; + + max44009_value[0] = (MAX44009_INT_STATUS_OFF); + max44009_value[1] = (MAX44009_USER_CONFIGURATION); + max44009_value[2] = (0xFF); + max44009_value[3] = (0x00); + max44009_value[4] = (0xFF); + + for(i = 0; i < sizeof(max44009_address) / sizeof(max44009_address[0]); i++) { + max44009_data[0] = max44009_address[i]; + max44009_data[1] = max44009_value[i]; + i2c_burst_send(MAX44009_ADDRESS, max44009_data, 2); + } +} +/*---------------------------------------------------------------------------*/ +static void +max44009_reset(void) +{ + uint8_t max44009_address[5] = { MAX44009_INT_ENABLE_ADDR, MAX44009_CONFIG_ADDR, \ + MAX44009_THR_HIGH_ADDR, MAX44009_THR_LOW_ADDR, \ + MAX44009_THR_TIMER_ADDR }; + uint8_t max44009_value[5] = { 0x00, 0x03, 0xFF, 0x00, 0xFF }; + uint8_t max44009_data[2]; + uint8_t i; + + for(i = 0; i < sizeof(max44009_address) / sizeof(max44009_address[0]); i++) { + max44009_data[0] = max44009_address[i]; + max44009_data[1] = max44009_value[i]; + i2c_burst_send(MAX44009_ADDRESS, max44009_data, 2); + } +} +/*---------------------------------------------------------------------------*/ +static uint8_t +max44009_is_present(void) +{ + uint8_t status; + uint8_t is_present; + + i2c_single_send(MAX44009_ADDRESS, MAX44009_CONFIG_ADDR); + status = i2c_single_receive(MAX44009_ADDRESS, &is_present); + if(status != I2C_MASTER_ERR_NONE) { + return 0; + } + + return is_present != MAX44009_NOT_FOUND; +} +/*---------------------------------------------------------------------------*/ +static uint16_t +max44009_read_light(void) +{ + uint8_t exponent, mantissa; + uint8_t max44009_data[2]; + uint32_t result; + + i2c_single_send(MAX44009_ADDRESS, MAX44009_LUX_HIGH_ADDR); + i2c_single_receive(MAX44009_ADDRESS, &max44009_data[0]); + i2c_single_send(MAX44009_ADDRESS, MAX44009_LUX_LOW_ADDR); + i2c_single_receive(MAX44009_ADDRESS, &max44009_data[1]); + + exponent = ((max44009_data[0] >> 4) & 0x0E); + mantissa = ((max44009_data[0] & 0x0F) << 4) | (max44009_data[1] & 0x0F); + + result = ((uint16_t)exponent << 8) | ((uint16_t)mantissa << 0); + + return result; +} +/*---------------------------------------------------------------------------*/ +static uint16_t +max44009_convert_light(uint16_t lux) +{ + uint8_t exponent, mantissa; + uint32_t result; + + exponent = (lux >> 8) & 0xFF; + exponent = (exponent == 0x0F ? exponent & 0x0E : exponent); + mantissa = (lux >> 0) & 0xFF; + + result = 45 * (2 ^ exponent * mantissa) / 10; + + return (uint16_t)result; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + uint16_t value; + + if(!enabled) { + PRINTF("MAX44009: sensor not started\n"); + return MAX44009_ERROR; + } + + if(type == MAX44009_READ_RAW_LIGHT) { + return max44009_read_light(); + } else if(type == MAX44009_READ_LIGHT) { + value = max44009_read_light(); + return max44009_convert_light(value); + } else { + PRINTF("MAX44009: invalid value requested\n"); + return MAX44009_ERROR; + } +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type == MAX44009_ACTIVATE) { + if(!max44009_is_present()) { + return MAX44009_ERROR; + } else { + max44009_init(); + enabled = 1; + return MAX44009_SUCCESS; + } + } + + if((type == MAX44009_RESET) && enabled) { + max44009_reset(); + return MAX44009_SUCCESS; + } else { + PRINTF("MAX44009: is not enabled\n"); + return MAX44009_ERROR; + } + + return MAX44009_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(max44009, MAX44009_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/iris/dev/leds-arch.c b/platform/openmote-cc2538/dev/max44009.h similarity index 67% rename from platform/iris/dev/leds-arch.c rename to platform/openmote-cc2538/dev/max44009.h index b1397b8a1..32ba101e8 100644 --- a/platform/iris/dev/leds-arch.c +++ b/platform/openmote-cc2538/dev/max44009.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, University of Colombo School of Computing + * Copyright (c) 2014, OpenMote Technologies, S.L. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,40 +28,40 @@ * * This file is part of the Contiki operating system. * - * @(#)$$ */ - +/*---------------------------------------------------------------------------*/ /** + * \addtogroup openmote-sensors + * @{ + * + * \defgroup openmote-max44009-sensor MAX4009 light sensor + * @{ + * * \file - * LED architecture of the MICAz port. + * Header file for the MAX44009 light sensor driver + * * \author - * Kasun Hewage + * Pere Tuset */ - -#include "contiki-conf.h" -#include "dev/leds.h" -#include - - /*---------------------------------------------------------------------------*/ -void leds_arch_init(void) -{ - LEDS_PxDIR |= (LEDS_CONF_RED | LEDS_CONF_GREEN | LEDS_CONF_YELLOW); - LEDS_PxOUT |= (LEDS_CONF_RED | LEDS_CONF_GREEN | LEDS_CONF_YELLOW); -} +#ifndef MAX44009_H_ +#define MAX44009_H_ /*---------------------------------------------------------------------------*/ -unsigned char leds_arch_get(void) -{ - return ((LEDS_PxOUT & LEDS_CONF_RED) ? 0 : LEDS_RED) - | ((LEDS_PxOUT & LEDS_CONF_GREEN) ? 0 : LEDS_GREEN) - | ((LEDS_PxOUT & LEDS_CONF_YELLOW) ? 0 : LEDS_YELLOW); -} +#define MAX44009_ERROR (-1) +#define MAX44009_SUCCESS (0) +#define MAX44009_ACTIVATE (SENSORS_ACTIVE) +#define MAX44009_READ_RAW_LIGHT (2) +#define MAX44009_READ_LIGHT (3) +#define MAX44009_RESET (4) +#define MAX44009_NONE (5) /*---------------------------------------------------------------------------*/ -void leds_arch_set(unsigned char leds) -{ - LEDS_PxOUT = (LEDS_PxOUT & ~(LEDS_CONF_RED|LEDS_CONF_GREEN|LEDS_CONF_YELLOW)) - | ((leds & LEDS_RED) ? 0 : LEDS_CONF_RED) - | ((leds & LEDS_GREEN) ? 0 : LEDS_CONF_GREEN) - | ((leds & LEDS_YELLOW) ? 0 : LEDS_CONF_YELLOW); -} +#define MAX44009_SENSOR "MAX44009 Sensor" /*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor max44009; +/*---------------------------------------------------------------------------*/ +#endif /* MAX44009_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/openmote-sensors.c b/platform/openmote-cc2538/dev/openmote-sensors.c new file mode 100644 index 000000000..3b55e4cbb --- /dev/null +++ b/platform/openmote-cc2538/dev/openmote-sensors.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-sensors + * @{ + * + * Generic module controlling sensors on the OpenMote-CC2538 platform + * @{ + * + * \file + * Implementation of a generic module controlling OpenMote-CC2538 sensors + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/cc2538-sensors.h" +#include "dev/button-sensor.h" + +#include +/*---------------------------------------------------------------------------*/ +/** + * \brief Exports a global symbol to be used by the sensor API + */ +SENSORS(&button_sensor, &cc2538_temp_sensor); +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/openmote-sensors.h b/platform/openmote-cc2538/dev/openmote-sensors.h new file mode 100644 index 000000000..a765dbd3d --- /dev/null +++ b/platform/openmote-cc2538/dev/openmote-sensors.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-cc2538 + * @{ + * + * \defgroup openmote-sensors OpenMote-CC2538 sensors + * + * Generic module controlling sensors on the OpenMote-CC2538 platform + * @{ + * + * \file + * Implementation of a generic module controlling OpenMote-CC2538 sensors + */ +/*---------------------------------------------------------------------------*/ +#ifndef OPENMOTE_SENSORS_H_ +#define OPENMOTE_SENSORS_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "dev/cc2538-sensors.h" +#include "dev/button-sensor.h" +/*---------------------------------------------------------------------------*/ +#endif /* OPENMOTE_SENSORS_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/sht21.c b/platform/openmote-cc2538/dev/sht21.c new file mode 100644 index 000000000..4fd577e01 --- /dev/null +++ b/platform/openmote-cc2538/dev/sht21.c @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-sht21-sensor + * @{ + * + * \file + * Driver for the SHT21 temperature and relative humidity sensor + * + * \author + * Pere Tuset + */ +/*---------------------------------------------------------------------------*/ +#include "dev/i2c.h" +#include "dev/sht21.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +/** + * \name SHT21 address + */ +#define SHT21_ADDRESS (0x40) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SHT21 register addresses and values + * @{ + */ +#define SHT21_USER_REG_READ (0xE7) +#define SHT21_USER_REG_WRITE (0xE6) +#define SHT21_USER_REG_RESERVED_BITS (0x38) + +#define SHT21_TEMPERATURE_HM_CMD (0xE3) +#define SHT21_HUMIDITY_HM_CMD (0xE5) +#define SHT21_TEMPERATURE_NHM_CMD (0xF3) +#define SHT21_HUMIDITY_NHM_CMD (0xF5) +#define SHT21_RESET_CMD (0xFE) + +#define SHT21_STATUS_MASK (0xFC) + +#define SHT21_RESOLUTION_12b_14b ((0 << 7) | (0 << 0)) +#define SHT21_RESOLUTION_8b_12b ((0 << 7) | (1 << 0)) +#define SHT21_RESOLUTION_10b_13b ((1 << 7) | (0 << 0)) +#define SHT21_RESOLUTION_11b_11b ((1 << 7) | (1 << 0)) +#define SHT21_BATTERY_ABOVE_2V25 (0 << 6) +#define SHT21_BATTERY_BELOW_2V25 (1 << 6) +#define SHT21_ONCHIP_HEATER_ENABLE (1 << 2) +#define SHT21_ONCHIP_HEATER_DISABLE (0 << 2) +#define SHT21_OTP_RELOAD_ENABLE (0 << 1) +#define SHT21_OTP_RELOAD_DISABLE (1 << 1) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SHT21 configuration values + * @{ + */ +#define SHT21_DEFAULT_CONFIG (SHT21_RESOLUTION_12b_14b | \ + SHT21_ONCHIP_HEATER_DISABLE | \ + SHT21_BATTERY_ABOVE_2V25 | \ + SHT21_OTP_RELOAD_DISABLE) + +#define SHT21_USER_CONFIG (SHT21_RESOLUTION_12b_14b | \ + SHT21_ONCHIP_HEATER_DISABLE | \ + SHT21_BATTERY_ABOVE_2V25 | \ + SHT21_OTP_RELOAD_DISABLE) +/** @} */ +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +static void +sht21_init(void) +{ + uint8_t config[2]; + + /* Setup the configuration vector, the first position holds address */ + /* and the second position holds the actual configuration */ + config[0] = SHT21_USER_REG_WRITE; + config[1] = 0; + + /* Read the current configuration according to the datasheet (pag. 9, fig. 18) */ + i2c_single_send(SHT21_ADDRESS, SHT21_USER_REG_READ); + i2c_single_receive(SHT21_ADDRESS, &config[1]); + + /* Clean all the configuration bits except those reserved */ + config[1] &= SHT21_USER_REG_RESERVED_BITS; + + /* Set the configuration bits without changing those reserved */ + config[1] |= SHT21_USER_CONFIG; + + i2c_burst_send(SHT21_ADDRESS, config, sizeof(config)); +} +/*---------------------------------------------------------------------------*/ +static void +sht21_reset(void) +{ + /* Send a soft-reset command according to the datasheet (pag. 9, fig. 17) */ + i2c_single_send(SHT21_ADDRESS, SHT21_RESET_CMD); +} +/*---------------------------------------------------------------------------*/ +static uint8_t +sht21_is_present(void) +{ + uint8_t status; + uint8_t is_present; + + /* Read the current configuration according to the datasheet (pag. 9, fig. 18) */ + i2c_single_send(SHT21_ADDRESS, SHT21_USER_REG_READ); + status = i2c_single_receive(SHT21_ADDRESS, &is_present); + if(status != I2C_MASTER_ERR_NONE) { + return 0; + } + + /* Clear the reserved bits according to the datasheet (pag. 9, tab. 8) */ + is_present &= ~SHT21_USER_REG_RESERVED_BITS; + + return (is_present == SHT21_USER_CONFIG) || (is_present == SHT21_DEFAULT_CONFIG); +} +/*---------------------------------------------------------------------------*/ +static uint32_t +sht21_read_temperature(void) +{ + uint8_t sht21_temperature[2]; + uint16_t temperature; + + /* Read the current temperature according to the datasheet (pag. 8, fig. 15) */ + i2c_single_send(SHT21_ADDRESS, SHT21_TEMPERATURE_HM_CMD); + i2c_burst_receive(SHT21_ADDRESS, sht21_temperature, sizeof(sht21_temperature)); + + temperature = (sht21_temperature[0] << 8) | ((sht21_temperature[1] & SHT21_STATUS_MASK)); + + return temperature; +} +/*---------------------------------------------------------------------------*/ +static int16_t +sht21_convert_temperature(uint32_t temperature) +{ + int16_t result; + + temperature *= 17572; + temperature = temperature >> 16; + result = (int16_t)temperature - 4685; + + return result; +} +/*---------------------------------------------------------------------------*/ +static uint32_t +sht21_read_humidity(void) +{ + uint8_t sht21_humidity[2]; + uint16_t humidity; + + /* Read the current humidity according to the datasheet (pag. 8, fig. 15) */ + i2c_single_send(SHT21_ADDRESS, SHT21_HUMIDITY_HM_CMD); + i2c_burst_receive(SHT21_ADDRESS, sht21_humidity, sizeof(sht21_humidity)); + + humidity = (sht21_humidity[0] << 8) | ((sht21_humidity[1] & SHT21_STATUS_MASK)); + + return humidity; +} +/*---------------------------------------------------------------------------*/ +static int16_t +sht21_convert_humidity(uint32_t humidity) +{ + int16_t result; + + humidity *= 12500; + humidity = humidity >> 16; + result = (int16_t)humidity - 600; + result = (result > 10000) ? 10000 : result; + + return result; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + uint32_t value; + + if(!enabled) { + PRINTF("SHT21: sensor not started\n"); + return SHT21_ERROR; + } + + if(type == SHT21_READ_RAW_TEMP) { + return sht21_read_temperature(); + } else if(type == SHT21_READ_RAW_RHUM) { + return sht21_read_humidity(); + } else if(type == SHT21_READ_TEMP) { + value = sht21_read_temperature(); + return sht21_convert_temperature(value); + } else if(type == SHT21_READ_RHUM) { + value = sht21_read_humidity(); + return sht21_convert_humidity(value); + } else { + PRINTF("SHT21: invalid value requested\n"); + return SHT21_ERROR; + } +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type == SHT21_ACTIVATE) { + if(!sht21_is_present()) { + PRINTF("SHT21: is not present\n"); + return SHT21_ERROR; + } else { + sht21_init(); + enabled = 1; + return SHT21_SUCCESS; + } + } + + if(type == SHT21_RESET && enabled) { + sht21_reset(); + return SHT21_SUCCESS; + } else { + PRINTF("SHT21: is not enabled\n"); + return SHT21_ERROR; + } + + return SHT21_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(sht21, SHT21_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/openmote-cc2538/dev/sht21.h b/platform/openmote-cc2538/dev/sht21.h new file mode 100644 index 000000000..3304d915e --- /dev/null +++ b/platform/openmote-cc2538/dev/sht21.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-sensors + * @{ + * + * \defgroup openmote-sht21-sensor SHT21 sensor + * @{ + * + * \file + * Header file for the SHT21 temperature and humidity sensor driver + * + * \author + * Pere Tuset + */ +/*---------------------------------------------------------------------------*/ +#ifndef SHT21_H_ +#define SHT21_H_ +/*---------------------------------------------------------------------------*/ +#define SHT21_ERROR (-1) +#define SHT21_SUCCESS (0) +#define SHT21_ACTIVATE (SENSORS_ACTIVE) +#define SHT21_READ_RAW_TEMP (2) +#define SHT21_READ_RAW_RHUM (3) +#define SHT21_READ_TEMP (4) +#define SHT21_READ_RHUM (5) +#define SHT21_RESET (6) +#define SHT21_NONE (7) +/*---------------------------------------------------------------------------*/ +#define SHT21_SENSOR "SHT21 Sensor" +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor sht21; +/*---------------------------------------------------------------------------*/ +#endif /* SHT21_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/tps62730.c b/platform/openmote-cc2538/dev/tps62730.c new file mode 100644 index 000000000..f90c0e097 --- /dev/null +++ b/platform/openmote-cc2538/dev/tps62730.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-tps62730 + * @{ + * + * Driver for the TPS62730 voltage regulator, to enable power from + * the battery voltage (bypass, Vout=Vin, Iq < 1uA) or through the + * buck regulator (on, Vout=2.1V, Iq = 30uA) + * @{ + * + * \file + * Driver for the TPS62730 voltage regulator + * + * \author + * Pere Tuset + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "dev/gpio.h" +#include "dev/tps62730.h" +/*---------------------------------------------------------------------------*/ +#define BSP_TPS62730_BASE (GPIO_B_BASE) +#define BSP_TPS62730_ON (1 << 1) +#define BSP_TPS62730_STATUS (1 << 0) +/*---------------------------------------------------------------------------*/ +static void +gpio_set(int port, int bit) +{ + REG((port | GPIO_DATA) + (bit << 2)) = bit; +} +/*---------------------------------------------------------------------------*/ +static void +gpio_reset(int port, int bit) +{ + REG((port | GPIO_DATA) + (bit << 2)) = 0; +} +/*---------------------------------------------------------------------------*/ +void +tps62730_init(void) +{ + GPIO_SET_OUTPUT(BSP_TPS62730_BASE, BSP_TPS62730_ON); + GPIO_SET_INPUT(BSP_TPS62730_BASE, BSP_TPS62730_STATUS); + + tps62730_bypass(); +} +/*---------------------------------------------------------------------------*/ +void +tps62730_on(void) +{ + gpio_set(BSP_TPS62730_BASE, BSP_TPS62730_ON); +} +/*---------------------------------------------------------------------------*/ +void +tps62730_bypass(void) +{ + gpio_reset(BSP_TPS62730_BASE, BSP_TPS62730_ON); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/openmote-cc2538/dev/tps62730.h b/platform/openmote-cc2538/dev/tps62730.h new file mode 100644 index 000000000..00518c9c7 --- /dev/null +++ b/platform/openmote-cc2538/dev/tps62730.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014, OpenMote Technologies, S.L. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup openmote-cc2538 + * @{ + * + * \defgroup openmote-tps62730 TPS62730 voltage regulator + * + * Driver for the TPS62730 voltage regulator, to enable power from + * the battery voltage (bypass, Vout=Vin, Iq < 1uA) or through the + * buck regulator (on, Vout=2.1V, Iq = 30uA) + * @{ + * + * \file + * Driver for the TPS62730 voltage regulator + * + * \author + * Pere Tuset + */ +/*---------------------------------------------------------------------------*/ +#ifndef TPS62730_H_ +#define TPS62730_H_ +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize the TPS62730 voltage regulator in bypass mode + */ +void tps62730_init(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Set TPS62730 to on, Vout = 2.2V, Iq = 30 uA + */ +void tps62730_on(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Set TPS62730 to bypass, Vout = Vin, Iq < 1 uA + */ +void tps62730_bypass(void); +/*---------------------------------------------------------------------------*/ +#endif /* TPS62730_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/osd-merkur-128/Makefile.osd-merkur-128 b/platform/osd-merkur-128/Makefile.osd-merkur-128 new file mode 100644 index 000000000..8817f3855 --- /dev/null +++ b/platform/osd-merkur-128/Makefile.osd-merkur-128 @@ -0,0 +1,91 @@ +CONTIKI_TARGET_DIRS = . dev apps net loader dev/arduino + +CONTIKI_CORE=contiki-main +CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o +CONTIKI_TARGET_SOURCEFILES += contiki-main.c params.c node-id.c +#Needed for slip +CONTIKI_TARGET_SOURCEFILES += led.c sensors.c slip_uart0.c slip.c leds-arch.c +CONTIKI_TARGET_SOURCEFILES += temperature-sensor.c adc.c +#Needed for Button +CONTIKI_TARGET_SOURCEFILES += button-sensor.c +# i2c Master +#CONTIKI_TARGET_SOURCEFILES += i2c.c +#Needed for DHT11 humidity sensor +CONTIKI_TARGET_SOURCEFILES += dht11.c +#Needed for DS18S20 temperature sensor +CONTIKI_TARGET_SOURCEFILES += ds1820.c +#Needed for Battery test +CONTIKI_TARGET_SOURCEFILES += battery-sensor.c batmon.c +#Needed for PIR +CONTIKI_TARGET_SOURCEFILES += pir-sensor.c +#Needed for OPTRIAC +CONTIKI_TARGET_SOURCEFILES += optriac-sensor.c +#Needed for SERVO +CONTIKI_TARGET_SOURCEFILES += servo.c servo-sensor.c +#Needed for Timer4 Servo +#CONTIKI_TARGET_SOURCEFILES += t4-servo.c t4-servo-sensor.c +#Needed for Relay 1 to 4 +CONTIKI_TARGET_SOURCEFILES += relay.c relay-sensor.c +# Arduino +CONTIKI_TARGET_SOURCEFILES += wiring_digital.c +CONTIKI_TARGET_SOURCEFILES += new.cpp twi.c Wire.cpp WMath.cpp +CONTIKI_TARGET_SOURCEFILES += Print.cpp Stream.cpp WString.cpp +# guh Source Files +# Smart Grid Ready Interface +CONTIKI_TARGET_SOURCEFILES += sg-ready.c + +CONTIKIAVR=$(CONTIKI)/cpu/avr + +CONTIKIBOARD=. +BOOTLOADER_START = 0x1F000 +CONTIKI_PLAT_DEFS = -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -DPLAT_TIMER=5 + +MCU=atmega128rfa1 + +#AVRDUDE_PROGRAMMER=jtag2 +AVRDUDE_PROGRAMMER=arduino + +# For usb devices, you may either use PORT=usb, or (e.g. if you have +# more than one programmer connected) you can use the following trick to +# find out the serial number: +# +# The example is for an JTAGICE mkII used to program an ATmega128: +# avrdude -v -P usb:xxxx -c jtag2 -p atmega128 +# AVRDUDE_PORT=usb:00B000000D79 +# For serial devices with bootloader we also use the AVRDUDE_PORT setting: +AVRDUDE_PORT=/dev/ttyUSB0 +# Only needed for serial devices, use empty setting for other +# programmers +AVRDUDE_BAUD_OPTION=-b 57600 + +# Additional avrdude options +# First some flash options: +# Verify off is -V +# Erase is -e +# No-Erase (needed by some stk500 variants) is -D +AVRDUDE_FLASH_OPTIONS=-e +AVRDUDE_OPTIONS=$(AVRDUDE_BAUD_OPTION) $(AVRDUDE_FLASH_OPTIONS) +AVRDUDE_MCU=m128rfa1 + +#debug +# CFLAGS += -save-temps +# Bootloader bonsai +# LDFLAGS += -save-temps +# For the old bonsai bootloader compiled with squeeze gcc-avr we +# directly used the address of the bootloader: +#BOOTLOADER_GET_MAC=0x0001f3a0 +# For newer bonsai we have a jump table at the end of the bootloader +# section: +BOOTLOADER_GET_MAC=0x0001ff80 + +LDFLAGS += -Wl,--defsym,bootloader_get_mac=$(BOOTLOADER_GET_MAC) + + +include $(CONTIKIAVR)/Makefile.avr +include $(CONTIKIAVR)/radio/Makefile.radio + +MODULES += core/net/mac core/net core/net/mac/sicslowmac \ + core/net/mac/contikimac core/net/llsec \ +# core/net/ipv6 core/net/ipv4 core/net/ip \ +# core/net/rime \ +# core/net/rpl \ diff --git a/platform/osd-merkur-128/contiki-conf.h b/platform/osd-merkur-128/contiki-conf.h new file mode 100644 index 000000000..043dff995 --- /dev/null +++ b/platform/osd-merkur-128/contiki-conf.h @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2006, Technical University of Munich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * @(#)$$ + */ + +/** + * \file + * Configuration for Atmel ATmega128rfa1 + * \author + * David Kopf + */ + +#ifndef CONTIKI_CONF_H_ +#define CONTIKI_CONF_H_ + +/* Platform name, type, and MCU clock rate */ +#define PLATFORM_NAME "RFA1" +#define PLATFORM_TYPE ATMEGA128RFA1 +#ifndef F_CPU +#define F_CPU 16000000UL +#endif + +#include + +#define IEEE802154_CONF_PANID 0xABCD // default panid + +/* The AVR tick interrupt usually is done with an 8 bit counter around 128 Hz. + * 125 Hz needs slightly more overhead during the interrupt, as does a 32 bit + * clock_time_t. + */ + /* Clock ticks per second */ +#define CLOCK_CONF_SECOND 128 + +typedef uint32_t clock_time_t; +#define CLOCK_LT(a,b) ((int32_t)((a)-(b)) < 0) + +/* These routines are not part of the contiki core but can be enabled in cpu/avr/clock.c */ +void clock_delay_msec(uint16_t howlong); +void clock_adjust_ticks(clock_time_t howmany); + +/* COM port to be used for SLIP connection. This is usually UART0. */ +#define SLIP_PORT RS232_PORT_0 + +/* Pre-allocated memory for loadable modules heap space (in bytes)*/ +/* Default is 4096. Currently used only when elfloader is present. Not tested on Raven */ +//#define MMEM_CONF_SIZE 256 + +/* Starting address for code received via the codeprop facility. Not tested. */ +typedef unsigned long off_t; +//#define EEPROMFS_ADDR_CODEPROP 0x8000 + +/* Logging adds 200 bytes to program size. RS232 output slows down webserver. */ +//#define LOG_CONF_ENABLED 1 + +/* RADIOSTATS is used in rf230bb, clock.c and the webserver cgi to report radio usage */ +/* It has less overhead than ENERGEST */ +//#define RADIOSTATS 1 + +/* More extensive stats, via main loop printfs or webserver status pages */ +//#define ENERGEST_CONF_ON 1 + +/* Packet statistics */ +typedef unsigned short uip_stats_t; +//#define UIP_STATISTICS 1 + +/* Available watchdog timeouts depend on mcu. Default is WDTO_2S. -1 Disables the watchdog. */ +/* AVR Studio simulator tends to reboot due to clocking the WD 8 times too fast */ +//#define WATCHDOG_CONF_TIMEOUT -1 + +/* Debugflow macro, useful for tracing path through mac and radio interrupts */ +//#define DEBUGFLOWSIZE 128 + + +/* Define MAX_*X_POWER to reduce tx power and ignore weak rx packets for testing a miniature multihop network. + * Leave undefined for full power and sensitivity. + * tx=0 (3dbm, default) to 15 (-17.2dbm) + * RF230_CONF_AUTOACK sets the extended mode using the energy-detect register with rx=0 (-91dBm) to 84 (-7dBm) + * else the rssi register is used having range 0 (91dBm) to 28 (-10dBm) + * For simplicity RF230_MIN_RX_POWER is based on the energy-detect value and divided by 3 when autoack is not set. + * On the RF230 a reduced rx power threshold will not prevent autoack if enabled and requested. + * These numbers applied to both Raven and Jackdaw give a maximum communication distance of about 15 cm + * and a 10 meter range to a full-sensitivity RF230 sniffer. +#define RF230_MAX_TX_POWER 15 +#define RF230_MIN_RX_POWER 30 + */ + /* The rf231, atmega128rfa1 and atmega256rfr2 can use an rssi + * threshold for triggering rx_busy that saves 0.5ma in rx mode + * 1 - 15 maps into -90 to -48 dBm; the register is written with + * RF230_MIN_RX_POWER/6 + 1. Undefine for -100dBm sensitivity + */ +//#define RF230_MIN_RX_POWER 0 + +/* Network setup */ +/* TX routine passes the cca/ack result in the return parameter */ +#define RDC_CONF_HARDWARE_ACK 1 +/* TX routine does automatic cca and optional backoffs */ +#define RDC_CONF_HARDWARE_CSMA 1 +/* Allow MCU sleeping between channel checks */ +#define RDC_CONF_MCU_SLEEP 1 + +#if NETSTACK_CONF_WITH_IPV6 +#define LINKADDR_CONF_SIZE 8 +#define UIP_CONF_ICMP6 1 +#define UIP_CONF_UDP 1 +#define UIP_CONF_TCP 1 +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#else +/* ip4 should build but is largely untested */ +#define LINKADDR_CONF_SIZE 2 +#define NETSTACK_CONF_NETWORK rime_driver +#endif + +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 + +/* 10 bytes per stateful address context - see sicslowpan.c */ +/* Default is 1 context with prefix aaaa::/64 */ +/* These must agree with all the other nodes or there will be a failure to communicate! */ +#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 +#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 {addr_contexts[0].prefix[0]=0xaa;addr_contexts[0].prefix[1]=0xaa;} +#define SICSLOWPAN_CONF_ADDR_CONTEXT_1 {addr_contexts[1].prefix[0]=0xbb;addr_contexts[1].prefix[1]=0xbb;} +#define SICSLOWPAN_CONF_ADDR_CONTEXT_2 {addr_contexts[2].prefix[0]=0x20;addr_contexts[2].prefix[1]=0x01;addr_contexts[2].prefix[2]=0x49;addr_contexts[2].prefix[3]=0x78,addr_contexts[2].prefix[4]=0x1d;addr_contexts[2].prefix[5]=0xb1;} + +/* Take the default TCP maximum segment size for efficiency and simpler wireshark captures */ +/* Use this to prevent 6LowPAN fragmentation (whether or not fragmentation is enabled) */ +//#define UIP_CONF_TCP_MSS 48 + +#define UIP_CONF_IP_FORWARD 0 +#define UIP_CONF_FWCACHE_SIZE 0 + +#define UIP_CONF_IPV6_CHECKS 1 +#define UIP_CONF_IPV6_QUEUE_PKT 1 +#define UIP_CONF_IPV6_REASSEMBLY 0 + +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_TCP_SPLIT 1 +#define UIP_CONF_DHCP_LIGHT 1 + + +//#if 1 /* No radio cycling */ +#if 0 /* radio cycling */ + +#define NETSTACK_CONF_MAC nullmac_driver +#define NETSTACK_CONF_RDC sicslowmac_driver +#define NETSTACK_CONF_FRAMER framer_802154 +#define NETSTACK_CONF_RADIO rf230_driver +/* AUTOACK receive mode gives better rssi measurements, even if ACK is never requested */ +#define RF230_CONF_AUTOACK 1 +/* Request 802.15.4 ACK on all packets sent (else autoretry). This is primarily for testing. */ +#define SICSLOWPAN_CONF_ACK_ALL 0 +/* 1 + Number of auto retry attempts 0-15 (0 implies don't use extended TX_ARET_ON mode) */ +#define RF230_CONF_FRAME_RETRIES 2 +/* Number of csma retry attempts 0-5 in extended tx mode (7 does immediate tx with no csma) */ +#define RF230_CONF_CSMA_RETRIES 5 +/* Default is one RAM buffer for received packets. More than one may benefit multiple TCP connections or ports */ +#define RF230_CONF_RX_BUFFERS 3 +#define SICSLOWPAN_CONF_FRAG 1 +/* Most browsers reissue GETs after 3 seconds which stops fragment reassembly so a longer MAXAGE does no good */ +#define SICSLOWPAN_CONF_MAXAGE 3 +/* How long to wait before terminating an idle TCP connection. Smaller to allow faster sleep. Default is 120 seconds */ +/* If wait is too short the connection can be reset as a result of multiple fragment reassembly timeouts */ +#define UIP_CONF_WAIT_TIMEOUT 20 +/* 211 bytes per queue buffer */ +#define QUEUEBUF_CONF_NUM 8 +/* 54 bytes per queue ref buffer */ +#define QUEUEBUF_CONF_REF_NUM 2 +/* Allocate remaining RAM as desired */ +/* 30 bytes per TCP connection */ +/* 6LoWPAN does not do well with concurrent TCP streams, as new browser GETs collide with packets coming */ +/* from previous GETs, causing decreased throughput, retransmissions, and timeouts. Increase to study this. */ +/* ACKs to other ports become interleaved with computation-intensive GETs, so ACKs are particularly missed. */ +/* Increasing the number of packet receive buffers in RAM helps to keep ACKs from being lost */ +#define UIP_CONF_MAX_CONNECTIONS 4 +/* 2 bytes per TCP listening port */ +#define UIP_CONF_MAX_LISTENPORTS 4 +/* 25 bytes per UDP connection */ +#define UIP_CONF_UDP_CONNS 10 +/* See uip-ds6.h */ +#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#define UIP_CONF_DS6_DEFRT_NBU 2 +#define UIP_CONF_DS6_PREFIX_NBU 3 +#define UIP_CONF_MAX_ROUTES 20 +#define UIP_CONF_DS6_ADDR_NBU 3 +#define UIP_CONF_DS6_MADDR_NBU 0 +#define UIP_CONF_DS6_AADDR_NBU 0 + + +#elif 1 /* Contiki-mac radio cycling */ +//#define NETSTACK_CONF_MAC nullmac_driver +/* csma needed for burst mode at present. Webserver won't work without it */ +#define NETSTACK_CONF_MAC csma_driver +#define NETSTACK_CONF_RDC contikimac_driver +/* Default is two CCA separated by 500 usec */ +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 +/* So without the header this needed for RPL mesh to form */ +#define CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE 43-18 //multicast RPL DIS length +/* Not tested much yet */ +#define CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION 0 +#define CONTIKIMAC_CONF_COMPOWER 1 +#define RIMESTATS_CONF_ENABLED 0 + +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_FRAMER framer_802154 +#else /* NETSTACK_CONF_WITH_IPV6 */ +#define NETSTACK_CONF_FRAMER contikimac_framer +#endif /* NETSTACK_CONF_WITH_IPV6 */ + +#define NETSTACK_CONF_RADIO rf230_driver +/* The radio needs to interrupt during an rtimer interrupt */ +#define RTIMER_CONF_NESTED_INTERRUPTS 1 +#define RF230_CONF_AUTOACK 1 +/* A 0 here means non-extended mode; 1 means extended mode with no retry, >1 for retrys */ +/* Contikimac strobes on its own, but hardware retries are faster */ +#define RF230_CONF_FRAME_RETRIES 1 +/* Long csma backoffs will compromise radio cycling; set to 0 for 1 csma */ +#define RF230_CONF_CSMA_RETRIES 0 +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 3 +/* 211 bytes per queue buffer. Contikimac burst mode needs 15 for a 1280 byte MTU */ +#define QUEUEBUF_CONF_NUM 15 +/* 54 bytes per queue ref buffer */ +#define QUEUEBUF_CONF_REF_NUM 2 +/* Allocate remaining RAM. Not much left due to queuebuf increase */ +#define UIP_CONF_MAX_CONNECTIONS 2 +#define UIP_CONF_MAX_LISTENPORTS 4 +#define UIP_CONF_UDP_CONNS 5 +#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#define UIP_CONF_DS6_DEFRT_NBU 2 +#define UIP_CONF_DS6_PREFIX_NBU 3 +#define UIP_CONF_MAX_ROUTES 4 +#define UIP_CONF_DS6_ADDR_NBU 3 +#define UIP_CONF_DS6_MADDR_NBU 0 +#define UIP_CONF_DS6_AADDR_NBU 0 + +#else +#error Network configuration not specified! +#endif /* Network setup */ + +/* ************************************************************************** */ +//#pragma mark RPL Settings +/* ************************************************************************** */ +#if UIP_CONF_IPV6_RPL + +#define UIP_CONF_ROUTER 1 +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +/* For slow slip connections, to prevent buffer overruns */ +//#define UIP_CONF_RECEIVE_WINDOW 300 +#undef UIP_CONF_FWCACHE_SIZE +#define UIP_CONF_FWCACHE_SIZE 30 +#define UIP_CONF_BROADCAST 1 +#define UIP_ARCH_IPCHKSUM 1 +#define UIP_CONF_PINGADDRCONF 0 +#define UIP_CONF_LOGGING 0 + +#endif /* RPL */ + +#define CCIF +#define CLIF +#ifndef CC_CONF_INLINE +#define CC_CONF_INLINE inline +#endif + +/* include the project config */ +/* PROJECT_CONF_H might be defined in the project Makefile */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif + +#endif /* CONTIKI_CONF_H_ */ diff --git a/platform/osd-merkur-128/contiki-main.c b/platform/osd-merkur-128/contiki-main.c new file mode 100644 index 000000000..142d6edd7 --- /dev/null +++ b/platform/osd-merkur-128/contiki-main.c @@ -0,0 +1,593 @@ +/* + * Copyright (c) 2006, Technical University of Munich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) + +#define ANNOUNCE_BOOT 1 //adds about 600 bytes to program size +#if ANNOUNCE_BOOT +#define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTA(...) +#endif + +#define DEBUG 0 +#if DEBUG +#define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTD(...) +#endif + +#include +#include +#include +#include +#include +#include + +#include "loader/symbols-def.h" +#include "loader/symtab.h" + +#include "params.h" +#include "radio/rf230bb/rf230bb.h" +#include "net/mac/frame802154.h" +#include "net/mac/framer-802154.h" +#include "net/ipv6/sicslowpan.h" + +#include "contiki.h" +#include "contiki-net.h" +#include "contiki-lib.h" + +#include "dev/rs232.h" +#include "dev/serial-line.h" +#include "dev/slip.h" + +#if AVR_WEBSERVER +#include "httpd-fs.h" +#include "httpd-cgi.h" +#endif + +#ifdef COFFEE_FILES +#include "cfs/cfs.h" +#include "cfs/cfs-coffee.h" +#endif + +#if UIP_CONF_ROUTER&&0 +#include "net/routing/rimeroute.h" +#include "net/rime/rime-udp.h" +#endif + +#include "net/rime/rime.h" + +/* Track interrupt flow through mac, rdc and radio driver */ +//#define DEBUGFLOWSIZE 32 +#if DEBUGFLOWSIZE +uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE]; +#define DEBUGFLOW(c) if (debugflowsize<(DEBUGFLOWSIZE-1)) debugflow[debugflowsize++]=c +#else +#define DEBUGFLOW(c) +#endif + +/* Get periodic prints from idle loop, from clock seconds or rtimer interrupts */ +/* Use of rtimer will conflict with other rtimer interrupts such as contikimac radio cycling */ +/* STAMPS will print ENERGEST outputs if that is enabled. */ +#define PERIODICPRINTS 1 +#if PERIODICPRINTS +//#define PINGS 64 +#define ROUTES 600 +#define STAMPS 60 +#define STACKMONITOR 1024 +uint32_t clocktime; +#define TESTRTIMER 0 +#if TESTRTIMER +uint8_t rtimerflag=1; +struct rtimer rt; +void rtimercycle(void) {rtimerflag=1;} +#endif +#endif + +//uint16_t ledtimer; + +/*-------------------------------------------------------------------------*/ +/*----------------------Configuration of the .elf file---------------------*/ +#if 1 +/* The proper way to set the signature is */ +#include +#else +/* Older avr-gcc's may not define the needed SIGNATURE bytes. Do it manually if you get an error */ +typedef struct {const unsigned char B2;const unsigned char B1;const unsigned char B0;} __signature_t; +#define SIGNATURE __signature_t __signature __attribute__((section (".signature"))) +SIGNATURE = { + .B2 = 0x01,//SIGNATURE_2, //ATMEGA128rfa1 + .B1 = 0xA7,//SIGNATURE_1, //128KB flash + .B0 = 0x1E,//SIGNATURE_0, //Atmel +}; +#endif + +#if 1 +/* JTAG+SPI enabled, External osc 1kck4ms1 , Boot 4096 words @ $1F000, TXC1K+4,1msec delay, Brownout 1.9 volts */ +FUSES ={.low = 0xF6, .high = 0x98, .extended = 0xfd,}; +#define BOOTLOADER_START = 0x1F000 +#else +/* JTAG+SPI, Boot 4096 words @ $F000, Internal oscillator, startup 6 CK +0 ms, Brownout 1.8 volts */ +FUSES ={.low = 0xC2, .high = 0x99, .extended = 0xfe,}; +#endif + +#include "lib/sensors.h" +#include "dev/button-sensor.h" +#include "dev/battery-sensor.h" +#include "dev/pir-sensor.h" +SENSORS(&button_sensor, &pir_sensor); + +uint8_t +rng_get_uint8(void) { +#if 1 + /* Upper two RSSI reg bits (RND_VALUE) are random in rf231 */ + uint8_t j; + j = (PHY_RSSI&0xc0) + ((PHY_RSSI>>2)&0x30) + ((PHY_RSSI>>4)&0x0c) + ((PHY_RSSI>>6)&0x03); +#else +/* Get a pseudo random number using the ADC */ + uint8_t i,j; + ADCSRA=1<>4); +} +/*-------------------------Low level initialization------------------------*/ +/*------Done in a subroutine to keep main routine stack usage small--------*/ +void initialize(void) +{ + watchdog_init(); + watchdog_start(); + + /* Generic or slip connection on uart0 */ + rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); + + /* Second rs232 port for debugging or slip alternative */ +// rs232_init(RS232_PORT_1, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); + + /* Redirect stdout */ + rs232_redirect_stdout(RS232_PORT_0); + + clock_init(); + + if(MCUSR & (1< +//#define delay_us( us ) ( _delay_loop_2(1+(us*F_CPU)/4000000UL) ) +// delay_us(50000); + } + clock_init(); +} +#endif + + PRINTA("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING); + +/* rtimers needed for radio cycling */ + rtimer_init(); + + /* Initialize process subsystem */ + process_init(); + + /* etimers must be started before ctimer_init */ + process_start(&etimer_process, NULL); + ctimer_init(); + + /* Start radio and radio receive process */ + NETSTACK_RADIO.init(); + +/* Get a random seed for the 802.15.4 packet sequence number. + * Some layers will ignore duplicates found in a history (e.g. Contikimac) + * causing the initial packets to be ignored after a short-cycle restart. + */ + random_init(rng_get_uint8()); + + /* Set addresses BEFORE starting tcpip process */ + + linkaddr_t addr; + + if (params_get_eui64(addr.u8)) { + PRINTA("Random EUI64 address generated\n"); + } + +#if NETSTACK_CONF_WITH_IPV6 + memcpy(&uip_lladdr.addr, &addr.u8, sizeof(linkaddr_t)); +#elif WITH_NODE_ID + node_id=get_panaddr_from_eeprom(); + addr.u8[1]=node_id&0xff; + addr.u8[0]=(node_id&0xff00)>>8; + PRINTA("Node ID from eeprom: %X\n",node_id); +#endif + linkaddr_set_node_addr(&addr); + + PRINTA("Panid:%x\n", params_get_panid()); +// framer_802154_set_panid(params_get_panid()); + rf230_set_pan_addr(params_get_panid(),params_get_panaddr(),(uint8_t *)&addr.u8); + rf230_set_channel(params_get_channel()); + rf230_set_txpower(params_get_txpower()); + +#if NETSTACK_CONF_WITH_IPV6 + PRINTA("EUI-64 MAC: %x-%x-%x-%x-%x-%x-%x-%x\n",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]); +#else + PRINTA("MAC address "); + uint8_t i; + for (i=sizeof(linkaddr_t); i>0; i--){ + PRINTA("%x:",addr.u8[i-1]); + } + PRINTA("\n"); +#endif + + /* Initialize stack protocols */ + queuebuf_init(); + NETSTACK_RDC.init(); + NETSTACK_MAC.init(); + NETSTACK_NETWORK.init(); + +#if ANNOUNCE_BOOT + PRINTA("%s %s, channel %u , check rate %u Hz tx power %u\n",NETSTACK_MAC.name, NETSTACK_RDC.name, rf230_get_channel(), + CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1:NETSTACK_RDC.channel_check_interval()), + rf230_get_txpower()); +#if UIP_CONF_IPV6_RPL + PRINTA("RPL Enabled\n"); +#endif +#if UIP_CONF_ROUTER + PRINTA("Routing Enabled\n"); +#endif + +#endif /* ANNOUNCE_BOOT */ + +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 + process_start(&tcpip_process, NULL); +#endif + + process_start(&sensors_process, NULL); + + /* Autostart other processes */ + autostart_start(autostart_processes); + + /*---If using coffee file system create initial web content if necessary---*/ +#if COFFEE_FILES + int fa = cfs_open( "/index.html", CFS_READ); + if (fa<0) { //Make some default web content + PRINTA("No index.html file found, creating upload.html!\n"); + PRINTA("Formatting FLASH file system for coffee..."); + cfs_coffee_format(); + PRINTA("Done!\n"); + fa = cfs_open( "/index.html", CFS_WRITE); + int r = cfs_write(fa, &"It works!", 9); + if (r<0) PRINTA("Can''t create /index.html!\n"); + cfs_close(fa); +// fa = cfs_open("upload.html"), CFW_WRITE); +//
    + } +#endif /* COFFEE_FILES */ + +/* Add addresses for testing */ +#if 0 +{ + uip_ip6addr_t ipaddr; + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); +// uip_ds6_prefix_add(&ipaddr,64,0); +} +#endif + +/*--------------------------Announce the configuration---------------------*/ +#if ANNOUNCE_BOOT +#if AVR_WEBSERVER +{ uint8_t i; + char buf[80]; + unsigned int size; + + for (i=0;i>10); +#elif COFFEE_FILES==3 + PRINTA(".%s online with static %u byte program memory file system\n",buf,size); +#elif COFFEE_FILES==4 + PRINTA(".%s online with dynamic %u KB program memory file system\n",buf,size>>10); +#endif /* COFFEE_FILES */ +} +#else + PRINTA("Online\n"); +#endif +#endif /* ANNOUNCE_BOOT */ + +} + +#if ROUTES && NETSTACK_CONF_WITH_IPV6 +static void +ipaddr_add(const uip_ipaddr_t *addr) +{ + uint16_t a; + int8_t i, f; + for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { + a = (addr->u8[i] << 8) + addr->u8[i + 1]; + if(a == 0 && f >= 0) { + if(f++ == 0) PRINTF("::"); + } else { + if(f > 0) { + f = -1; + } else if(i > 0) { + PRINTF(":"); + } + PRINTF("%x",a); + } + } +} +#endif + +/*-------------------------------------------------------------------------*/ +/*------------------------- Main Scheduler loop----------------------------*/ +/*-------------------------------------------------------------------------*/ +int +main(void) +{ +#if NETSTACK_CONF_WITH_IPV6 + uip_ds6_nbr_t *nbr; +#endif /* NETSTACK_CONF_WITH_IPV6 */ + initialize(); + + while(1) { + process_run(); + watchdog_periodic(); + +#if 0 + /* Turn off LED after a while */ + if (ledtimer) { + if (--ledtimer==0) { + } + } +#endif + +#if 0 +/* Various entry points for debugging in the AVR Studio simulator. + * Set as next statement and step into the routine. + */ + NETSTACK_RADIO.send(packetbuf_hdrptr(), 42); + process_poll(&rf230_process); + packetbuf_clear(); + len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE); + packetbuf_set_datalen(42); + NETSTACK_RDC.input(); +#endif + +#if 0 +/* Clock.c can trigger a periodic PLL calibration in the RF230BB driver. + * This can show when that happens. + */ + extern uint8_t rf230_calibrated; + if (rf230_calibrated) { + PRINTD("\nRF230 calibrated!\n"); + rf230_calibrated=0; + } +#endif + +/* Set DEBUGFLOWSIZE in contiki-conf.h to track path through MAC, RDC, and RADIO */ +#if DEBUGFLOWSIZE + if (debugflowsize) { + debugflow[debugflowsize]=0; + PRINTF("%s",debugflow); + debugflowsize=0; + } +#endif + +#if PERIODICPRINTS +#if TESTRTIMER +/* Timeout can be increased up to 8 seconds maximum. + * A one second cycle is convenient for triggering the various debug printouts. + * The triggers are staggered to avoid printing everything at once. + */ + if (rtimerflag) { + rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL); + rtimerflag=0; +#else + if (clocktime!=clock_seconds()) { + clocktime=clock_seconds(); +#endif + +#if STAMPS +if ((clocktime%STAMPS)==0) { +#if ENERGEST_CONF_ON +#include "lib/print-stats.h" + print_stats(); +#elif RADIOSTATS +extern volatile unsigned long radioontime; + PRINTF("%u(%u)s\n",clocktime,radioontime); +#else + PRINTF("%us\n",clocktime); +#endif + +} +#endif +#if TESTRTIMER + clocktime+=1; +#endif + +#if PINGS && NETSTACK_CONF_WITH_IPV6 +extern void raven_ping6(void); +if ((clocktime%PINGS)==1) { + PRINTF("**Ping\n"); + raven_ping6(); +} +#endif + +#if ROUTES && NETSTACK_CONF_WITH_IPV6 +if ((clocktime%ROUTES)==2) { + +extern uip_ds6_netif_t uip_ds6_if; + + uint8_t i,j=0; + PRINTF("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB); + for (i=0;iipaddr); + PRINTF("\n"); + j=0; + } + + if (j) PRINTF(" "); + PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); + { + uip_ds6_route_t *r; + j = 1; + for(r = uip_ds6_route_head(); + r != NULL; + r = uip_ds6_route_next(r)) { + ipaddr_add(&r->ipaddr); + PRINTF("/%u (via ", r->length); + ipaddr_add(uip_ds6_route_nexthop(r)); + PRINTF(") %lus\n", r->state.lifetime); + j = 0; + } + } + if (j) PRINTF(" "); + PRINTF("\n---------\n"); + +} +#endif + +#if STACKMONITOR +if ((clocktime%STACKMONITOR)==3) { + extern uint16_t __bss_end; + uint16_t p=(uint16_t)&__bss_end; + do { + if (*(uint16_t *)p != 0x4242) { + PRINTF("Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end); + break; + } + p+=10; + } while (p +*/ + + + // WARNING : Blink function is disabled on the core leds.c file + +#include "contiki.h" +#include "dev/leds.h" +#include "leds-arch.h" + +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ +DDRE |= (1< + +#define NUM_DIGITAL_PINS 15 +#define NUM_ANALOG_INPUTS 6 +#define analogInputToDigitalPin(p) ((p < NUM_ANALOG_INPUTS) ? (p) + NUM_DIGITAL_PINS : -1) +#define digitalPinHasPWM(p) ((p) == 2 ||(p) == 3 ||(p) == 4 ||(p) == 14 ) + +// Dev board specific defines: RF RX and TX LEDs: +#define RXLED_DDR DDRB +#define RXLED_PORT PORTB +#define RXLED_POS PB6 + +#define TXLED_DDR DDRB +#define TXLED_PORT PORTB +#define TXLED_POS PB7 + +const static uint8_t SS = 10; +const static uint8_t MOSI = 11; +const static uint8_t MISO = 13; +const static uint8_t SCK = 12; + +const static uint8_t SDA = 9; +const static uint8_t SCL = 8; +const static uint8_t LED = 4; +const static uint8_t LED1 = 4; +const static uint8_t LED2 = 5; + +const static uint8_t A0 = 7; +const static uint8_t A1 = 6; +const static uint8_t A2 = 5; +const static uint8_t A3 = 4; +const static uint8_t A4 = 0; +const static uint8_t A5 = 1; + +// A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins) +// Only pins available for RECEIVE (TRANSMIT can be on any pin): +// Pins: 10, 11, 12, 13, 14 + +#define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 14)) || ? (&PCICR) : ((uint8_t *)0) ) + +#define digitalPinToPCICRbit(p) ( 0 ) + +#define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 14)) ? (&PCMSK0) : ((uint8_t *)0) ) + +#define digitalPinToPCMSKbit(p) ( ((p) == 10) ? 6 : \ + ( ((p) == 11) ? 5 : \ + ( ((p) == 12) ? 1 : \ + ( ((p) == 13) ? 3 : \ + ( ((p) == 14) ? 7 : \ + 0 ) ) ) ) ) + +#ifdef ARDUINO_MAIN + +const uint16_t PROGMEM port_to_mode_PGM[] = { + NOT_A_PORT, + NOT_A_PORT, + (uint16_t)&DDRB, + NOT_A_PORT, + (uint16_t)&DDRD, + (uint16_t)&DDRE, + (uint16_t)&DDRF, + (uint16_t)&DDRG, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, +}; + +const uint16_t PROGMEM port_to_output_PGM[] = { + NOT_A_PORT, + NOT_A_PORT, + (uint16_t)&PORTB, + NOT_A_PORT, + (uint16_t)&PORTD, + (uint16_t)&PORTE, + (uint16_t)&PORTF, + (uint16_t)&PORTG, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, +}; + +const uint16_t PROGMEM port_to_input_PGM[] = { + NOT_A_PIN, + NOT_A_PIN, + NOT_A_PIN, + (uint16_t)&PINC, + (uint16_t)&PIND, + (uint16_t)&PINE, + (uint16_t)&PINF, + (uint16_t)&PING, + NOT_A_PIN, + NOT_A_PIN, + NOT_A_PIN, + NOT_A_PIN, + NOT_A_PIN, +}; + +const uint8_t PROGMEM digital_pin_to_port_PGM[] = { + // PORTLIST + // ------------------------------------------- + PE , // PE 1 ** 0 ** D0 / USART0_TX + PE , // PE 0 ** 1 ** D1 / USART0_RX + PE , // PE 3 ** 2 ** D2 / PWM + PE , // PE 4 ** 3 ** D3 / PWM + PE , // PE 5 ** 4 ** D4 / PWM / LED1 / LED + PE , // PE 6 ** 5 ** D5 / LED2 + PD , // PD 3 ** 6 ** D6 / USART1_TX + PD , // PD 2 ** 7 ** D7 / USART1_RX + PD , // PD 0 ** 8 ** D8 / I2C_SCL + PD , // PD 1 ** 9 ** D9 / I2C_SDA + PB , // PB 0 ** 10 ** D10 / SPI_SSN + PB , // PB 2 ** 11 ** D11 / SPI_MOSI + PB , // PB 1 ** 12 ** D12 / SPI_SCK + PB , // PB 3 ** 13 ** D13 / SPI_MISO + PB , // PB 4 ** 14 ** D14 / PWM + PF , // PF 7 ** 15 ** A0 / D15 + PF , // PF 6 ** 16 ** A1 / D16 + PF , // PF 5 ** 17 ** A2 / D17 + PF , // PF 4 ** 18 ** A3 / D18 + PF , // PF 0 ** 19 ** A4 / D19 + PF , // PF 1 ** 20 ** A5 / D20 +// PB , // PB 6 ** 34 ** D34 / LED1 / LED / PWM +// PB , // PB 7 ** 35 ** D35 / LED2 / PWM +// PE , // PE 2 ** 2 ** D2 +// PE , // PE 7 ** 7 ** D7 +// PB , // PB 5 ** 8 ** D8 / PWM +// PG , // PG 0 ** 16 ** D16 +// PG , // PG 1 ** 17 ** D17 +// PG , // PG 2 ** 18 ** D18 +// PG , // PG 5 ** 19 ** D19 / PWM +// PD , // PD 4 ** 22 ** D22 +// PD , // PD 5 ** 23 ** D23 +// PD , // PD 6 ** 24 ** D24 +// PD , // PD 7 ** 25 ** D25 +// PF , // PF 2 ** 28 ** A2 / D28 +// PF , // PF 3 ** 29 ** A3 / D29 +}; + +const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { + // PIN IN PORT + // ------------------------------------------- + _BV( 1 ) , // PE 1 ** 0 ** USART0_TX + _BV( 0 ) , // PE 0 ** 1 ** USART0_RX + _BV( 3 ) , // PE 3 ** 2 ** D3 / PWM + _BV( 4 ) , // PE 4 ** 3 ** D4 / PWM + _BV( 5 ) , // PE 5 ** 4 ** D5 / PWM + _BV( 6 ) , // PE 6 ** 5 ** D6 + _BV( 3 ) , // PD 3 ** 6 ** D21 / USART1_TX + _BV( 2 ) , // PD 2 ** 7 ** D20 / USART1_RX + _BV( 0 ) , // PD 0 ** 8 ** D15 / I2C_SCL + _BV( 1 ) , // PD 1 ** 9 ** D14 / I2C_SDA + _BV( 0 ) , // PB 0 ** 10 ** D10 / SPI_SSN + _BV( 2 ) , // PB 2 ** 11 ** D11 / SPI_MOSI + _BV( 1 ) , // PB 1 ** 12 ** D13 / SPI_SCK + _BV( 3 ) , // PB 3 ** 13 ** D12 / SPI_MISO + _BV( 4 ) , // PB 4 ** 14 ** D9 / PWM + _BV( 7 ) , // PF 7 ** 15 ** A0 / D33 + _BV( 6 ) , // PF 6 ** 16 ** A1 / D32 + _BV( 5 ) , // PF 5 ** 17 ** A2 / D31 + _BV( 4 ) , // PF 4 ** 18 ** A3 / D30 + _BV( 0 ) , // PF 0 ** 19 ** A4 / D26 + _BV( 1 ) , // PF 1 ** 20 ** A5 / D27 +// _BV( 2 ) , // PE 2 ** 2 ** D2 +// _BV( 7 ) , // PE 7 ** 7 ** D7 +// _BV( 5 ) , // PB 5 ** 8 ** D8 / PWM +// _BV( 0 ) , // PG 0 ** 16 ** D16 +// _BV( 1 ) , // PG 1 ** 17 ** D17 +// _BV( 2 ) , // PG 2 ** 18 ** D18 +// _BV( 5 ) , // PG 5 ** 19 ** D19 / PWM +// _BV( 4 ) , // PD 4 ** 22 ** D22 +// _BV( 5 ) , // PD 5 ** 23 ** D23 +// _BV( 6 ) , // PD 6 ** 24 ** D24 +// _BV( 7 ) , // PD 7 ** 25 ** D25 +// _BV( 2 ) , // PF 2 ** 28 ** A2 / D28 +// _BV( 3 ) , // PF 3 ** 29 ** A3 / D29 +// _BV( 6 ) , // PB 6 ** 34 ** D34 / LED1 / LED / PWM +// _BV( 7 ) , // PB 7 ** 35 ** D35 / LED2 / PWM +}; + +#endif + +#endif diff --git a/platform/iris/node-id.c b/platform/osd-merkur-128/node-id.c similarity index 69% rename from platform/iris/node-id.c rename to platform/osd-merkur-128/node-id.c index 84118cb40..8698b1855 100644 --- a/platform/iris/node-id.c +++ b/platform/osd-merkur-128/node-id.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, University of Colombo School of Computing + * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,36 +28,52 @@ * * This file is part of the Contiki operating system. * - * @(#)$$ + * $Id: node-id.c,v 1.1 2007/03/23 09:59:08 nifi Exp $ */ -#include "sys/node-id.h" +/** + * \file + * Utility to store a node id in the external flash + * \author + * Adam Dunkels + */ -uint16_t node_id = 0; +#include "node-id.h" +#include "contiki-conf.h" +#include "dev/xmem.h" + +unsigned short node_id = 0; /*---------------------------------------------------------------------------*/ void node_id_restore(void) { - uint16_t newid[2]; - uint8_t volatile sreg; - - sreg = SREG; /* Save status register before disabling interrupts. */ - cli(); /* Disable interrupts. */ - eeprom_read(EEPROM_NODE_ID_START, (unsigned char *)newid, sizeof(newid)); - node_id = (newid[0] == 0xdead) ? newid[1] : 0; - SREG = sreg; /* Enable interrupts. */ +/* todo */ +/* + unsigned char buf[4]; + xmem_pread(buf, 4, NODE_ID_XMEM_OFFSET); + if(buf[0] == 0xad && + buf[1] == 0xde) { + node_id = (buf[2] << 8) | buf[3]; + } else { + node_id = 0; + } +*/ + node_id = 0; } /*---------------------------------------------------------------------------*/ void -node_id_burn(uint16_t id) +node_id_burn(unsigned short id) { - uint16_t buffer[2] = { 0xdead, id }; - uint8_t volatile sreg; - - sreg = SREG; /* Save status register before disabling interrupts. */ - cli(); /* Disable interrupts. */ - eeprom_write(EEPROM_NODE_ID_START, (unsigned char *)buffer, sizeof(buffer)); - SREG = sreg; /* Enable interrupts. */ +/* todo */ +/* + unsigned char buf[4]; + buf[0] = 0xad; + buf[1] = 0xde; + buf[2] = id >> 8; + buf[3] = id & 0xff; + xmem_erase(XMEM_ERASE_UNIT_SIZE, NODE_ID_XMEM_OFFSET); + xmem_pwrite(buf, 4, NODE_ID_XMEM_OFFSET); +*/ } /*---------------------------------------------------------------------------*/ diff --git a/platform/osd-merkur-128/node-id.h b/platform/osd-merkur-128/node-id.h new file mode 100644 index 000000000..592379fc9 --- /dev/null +++ b/platform/osd-merkur-128/node-id.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: node-id.h,v 1.1 2007/03/23 09:59:08 nifi Exp $ + */ + +#ifndef __NODE_ID_H__ +#define __NODE_ID_H__ + +void node_id_restore(void); +void node_id_burn(unsigned short node_id); + +extern unsigned short node_id; + +#endif /* __NODE_ID_H__ */ diff --git a/platform/osd-merkur-128/params.c b/platform/osd-merkur-128/params.c new file mode 100644 index 000000000..4b0252387 --- /dev/null +++ b/platform/osd-merkur-128/params.c @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) + +#define DEBUG 1 +#if DEBUG +#define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTD(...) +#endif + +#include "contiki.h" +#include +#include +#include +#include + +#if AVR_WEBSERVER +//#include "httpd-fs.h" +//#include "httpd-cgi.h" +#endif + +#include "contiki-net.h" +#include "params.h" + +#if WITH_NODE_ID +uint16_t node_id; +#endif + +#if CONTIKI_CONF_RANDOM_MAC +extern uint8_t rng_get_uint8(void); +static void +generate_new_eui64(uint8_t eui64[8]) { + eui64[0] = 0x02; + eui64[1] = rng_get_uint8(); + eui64[2] = rng_get_uint8(); + eui64[3] = 0xFF; + eui64[4] = 0xFE; + eui64[5] = rng_get_uint8(); + eui64[6] = rng_get_uint8(); + eui64[7] = rng_get_uint8(); +} +#endif + +#if AVR_WEBSERVER +/* Webserver builds can set these in httpd-fsdata.c via makefsdata.h */ +extern uint8_t default_mac_address[8]; +extern uint8_t default_server_name[16]; +extern uint8_t default_domain_name[30]; +#else +const uint8_t default_mac_address[8] PROGMEM = PARAMS_EUI64ADDR; +const uint8_t default_server_name[] PROGMEM = PARAMS_SERVERNAME; +const uint8_t default_domain_name[] PROGMEM = PARAMS_DOMAINNAME; +#endif + +#if PARAMETER_STORAGE==0 +/* 0 Hard coded, minmal program and eeprom usage. */ + +extern uint8_t bootloader_get_mac(uint8_t); + +uint8_t +params_get_eui64(uint8_t *eui64) { +#if CONTIKI_CONF_RANDOM_MAC + PRINTD("Generating random EUI64 MAC\n"); + generate_new_eui64(eui64); + return 1; +#else + uint8_t i; +#if BOOTLOADER_GET_MAC + for (i=0;i 26)) x[1]=x[0]; +/* Do exclusive or test on the two values read */ + if((uint8_t)x[0]!=(uint8_t)~x[1]) {//~x[1] can promote comparison to 16 bit +/* Verification fails, rewrite everything */ + uint8_t i,buffer[32]; + PRINTD("EEPROM is corrupt, rewriting with defaults.\n"); +#if CONTIKI_CONF_RANDOM_MAC + PRINTD("Generating random EUI64 MAC\n"); + generate_new_eui64(&buffer); + randomeui64=1; +#else + for (i=0;iSet EEPROM RF channel to %d\n",x); + } + } + return x; +} +uint8_t +params_get_eui64(uint8_t *eui64) { + size_t size = sizeof(linkaddr_t); + if(settings_get(SETTINGS_KEY_EUI64, 0, (unsigned char*)eui64, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get EUI64 MAC\n"); + return 0; + } +#if CONTIKI_CONF_RANDOM_MAC + PRINTD("Generating random EUI64 MAC\n"); + generate_new_eui64(eui64); +#else + {uint8_t i;for (i=0;i<8;i++) eui64[i] = pgm_read_byte_near(default_mac_address+i);} //test this +#endif + if (settings_add(SETTINGS_KEY_EUI64,(unsigned char*)eui64,8) == SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM MAC address\n"); + } +#if CONTIKI_CONF_RANDOM_MAC + return 1; +#else + return 0; +#endif +} +uint16_t +params_get_panid(void) { + uint16_t x; + size_t size = 2; + if (settings_get(SETTINGS_KEY_PAN_ID, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get PAN ID of %04x\n",x); + } else { + x=IEEE802154_PANID; + if (settings_add_uint16(SETTINGS_KEY_PAN_ID,x)==SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM PAN ID to %04x\n",x); + } + } + return x; +} +uint16_t +params_get_panaddr(void) { + uint16_t x; + size_t size = 2; + if (settings_get(SETTINGS_KEY_PAN_ADDR, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get PAN address of %04x\n",x); + } else { + x=PARAMS_PANADDR; + if (settings_add_uint16(SETTINGS_KEY_PAN_ADDR,x)==SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM PAN address to %04x\n",x); + } + } + return x; +} +uint8_t +params_get_txpower(void) { + uint8_t x; + size_t size = 1; + if (settings_get(SETTINGS_KEY_TXPOWER, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get tx power of %d (0=max)\n",x); + } else { + x=PARAMS_TXPOWER; + if (settings_add_uint8(SETTINGS_KEY_TXPOWER,x)==SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM tx power of %d (0=max)\n",x); + } + } + return x; +} +#endif /* CONTIKI_CONF_SETTINGS_MANAGER */ diff --git a/platform/osd-merkur-128/params.h b/platform/osd-merkur-128/params.h new file mode 100644 index 000000000..f338e75e1 --- /dev/null +++ b/platform/osd-merkur-128/params.h @@ -0,0 +1,104 @@ +#ifndef PARAMS_H_ +#define PARAMS_H_ +/* PARAMETER_STORAGE = + * 0 Hard coded, minmal program and eeprom usage. + * 1 Stored in fixed eeprom locations, rewritten from flash if corrupt. + * This allows parameter changes using a hardware programmer or custom application code. + * Corruption test is based on channel verify so get the channel before anything else! + * 2 Obtained from eeprom using the general settings manager and read from program flash if not present. + * Useful for for testing builds without wearing out flash memory. + * 3 Obtained from eeprom using the settings manager and rewritten from flash if not present. + * This ensures all parameters are present in upper eeprom flash. + * + * Note the parameters in this file can be changed without forcing a complete rebuild. + */ +// default settings +#define CHANNEL_802_15_4 25 // default frequency (11-26) + +// end default settings + +#define CONTIKI_CONF_RANDOM_MAC 0 //adds 78 bytes +#define CONTIKI_CONF_SETTINGS_MANAGER 0 //adds 1696 bytes +#define BOOTLOADER_GET_MAC 0x0001ff80 // get mac from bootloader + +#if CONTIKI_CONF_SETTINGS_MANAGER +//#define PARAMETER_STORAGE 2 +#define PARAMETER_STORAGE 2 +#else +#define PARAMETER_STORAGE 0 // 0:get mac from booloader (see above) +#endif + +/* Include settings.h, then dummy out the write routines */ +#include "settings.h" +#if PARAMETER_STORAGE==2 +#define settings_add(...) 0 +#define settings_add_uint8(...) 0 +#define settings_add_uint16(...) 0 +#endif + +#if AVR_WEBSERVER +/* Webserver builds can set some defaults in httpd-fsdata.c via makefsdata.h */ +extern uint8_t eemem_mac_address[8]; +extern uint8_t eemem_server_name[16]; +extern uint8_t eemem_domain_name[30]; +#endif +#ifdef SERVER_NAME +#define PARAMS_SERVERNAME SERVER_NAME +#else +#define PARAMS_SERVERNAME "ATMEGA128rfa1" +#endif +#ifdef DOMAIN_NAME +#define PARAMS_DOMAINNAME DOMAIN_NAME +#else +#define PARAMS_DOMAINNAME "localhost" +#endif +#ifdef NODE_ID +#define PARAMS_NODEID NODE_ID +#else +#define PARAMS_NODEID 0 +#endif +#ifdef IEEE802154_PANADDR +#define PARAMS_PANADDR IEEE802154_PANADDR +#else +#define PARAMS_PANADDR 0 +#endif +#ifdef RF230_MAX_TX_POWER +#define PARAMS_TXPOWER RF230_MAX_TX_POWER +#else +#define PARAMS_TXPOWER 0 +#endif +#ifdef EUI64_ADDRESS +#define PARAMS_EUI64ADDR EUI64_ADDRESS +#else +/* This form of of EUI64 mac allows full 6LoWPAN header compression from mac address */ +#if UIP_CONF_LL_802154 +//#define PARAMS_EUI64ADDR {0x02, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN} +//#define PARAMS_EUI64ADDR {0x00, 0x21, 0x2e, 0xff, 0xff, 0x00, 0x1E, 0xFB} +#define PARAMS_EUI64ADDR {0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x11} +#else +//#define PARAMS_EUI64ADDR {0x02, 0xNN, 0xNN, 0xff, 0xfe, 0xNN, 0xNN, 0xNN} +#define PARAMS_EUI64ADDR {0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x03} +#endif +/* This form of of EUI64 mac allows 16 bit 6LoWPAN header compression on multihops */ +//#define PARAMS_EUI64ADDR {0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0xNN, 0xNN} +#endif + +uint8_t params_get_eui64(uint8_t *eui64); +#if PARAMETER_STORAGE==0 +/* Hard coded program flash parameters */ +#define params_get_servername(...) +#define params_get_nodeid(...) PARAMS_NODEID +#define params_get_channel(...) CHANNEL_802_15_4 +#define params_get_panid(...) IEEE802154_PANID +#define params_get_panaddr(...) PARAMS_PANADDR +#define params_get_txpower(...) PARAMS_TXPOWER +#else +/* Parameters stored in eeprom */ +uint16_t params_get_nodeid(void); +uint8_t params_get_channel(void); +uint16_t params_get_panid(void); +uint16_t params_get_panaddr(void); +uint8_t params_get_txpower(void); +#endif + +#endif /* PARAMS_H_ */ diff --git a/platform/iris/dev/slip_uart0.c b/platform/osd-merkur-128/slip_uart0.c similarity index 98% rename from platform/iris/dev/slip_uart0.c rename to platform/osd-merkur-128/slip_uart0.c index bf36616ad..edff55385 100644 --- a/platform/iris/dev/slip_uart0.c +++ b/platform/osd-merkur-128/slip_uart0.c @@ -76,7 +76,7 @@ static FILE slip_stdout = FDEV_SETUP_STREAM(slip_putchar, NULL, void slip_arch_init(unsigned long ubr) { - rs232_set_input(RS232_PORT_0, slip_input_byte); + rs232_set_input(SLIP_PORT, slip_input_byte); stdout = &slip_stdout; } /*---------------------------------------------------------------------------*/ diff --git a/platform/osd-merkur-256/Makefile.osd-merkur-256 b/platform/osd-merkur-256/Makefile.osd-merkur-256 new file mode 100644 index 000000000..0a60d2044 --- /dev/null +++ b/platform/osd-merkur-256/Makefile.osd-merkur-256 @@ -0,0 +1,91 @@ +CONTIKI_TARGET_DIRS = . dev apps net loader dev/arduino + +CONTIKI_CORE=contiki-main +CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o +CONTIKI_TARGET_SOURCEFILES += contiki-main.c params.c node-id.c +#Needed for slip +CONTIKI_TARGET_SOURCEFILES += led.c sensors.c slip_uart0.c slip.c leds-arch.c +CONTIKI_TARGET_SOURCEFILES += temperature-sensor.c adc.c +#Needed for Button +CONTIKI_TARGET_SOURCEFILES += button-sensor.c +# i2c Master +#CONTIKI_TARGET_SOURCEFILES += i2c.c +#Needed for DHT11 humidity sensor +CONTIKI_TARGET_SOURCEFILES += dht11.c +#Needed for DS18S20 temperature sensor +CONTIKI_TARGET_SOURCEFILES += ds1820.c +#Needed for Battery test +CONTIKI_TARGET_SOURCEFILES += battery-sensor.c batmon.c +#Needed for PIR +CONTIKI_TARGET_SOURCEFILES += pir-sensor.c +#Needed for OPTRIAC +CONTIKI_TARGET_SOURCEFILES += optriac-sensor.c +#Needed for SERVO +CONTIKI_TARGET_SOURCEFILES += servo.c servo-sensor.c +#Needed for Timer4 Servo +#CONTIKI_TARGET_SOURCEFILES += t4-servo.c t4-servo-sensor.c +#Needed for Relay 1 to 4 +CONTIKI_TARGET_SOURCEFILES += relay.c relay-sensor.c +# Arduino +CONTIKI_TARGET_SOURCEFILES += wiring_digital.c +CONTIKI_TARGET_SOURCEFILES += new.cpp twi.c Wire.cpp WMath.cpp +CONTIKI_TARGET_SOURCEFILES += Print.cpp Stream.cpp WString.cpp +# guh Source Files +# Smart Grid Ready Interface +CONTIKI_TARGET_SOURCEFILES += sg-ready.c + +CONTIKIAVR=$(CONTIKI)/cpu/avr + +CONTIKIBOARD=. +BOOTLOADER_START = 0x3E000 +CONTIKI_PLAT_DEFS = -DF_CPU=16000000UL -DAUTO_CRC_PADDING=2 -DPLAT_TIMER=5 + +MCU=atmega256rfr2 + +#AVRDUDE_PROGRAMMER=jtag2 +AVRDUDE_PROGRAMMER=stk500v2 + +# For usb devices, you may either use PORT=usb, or (e.g. if you have +# more than one programmer connected) you can use the following trick to +# find out the serial number: +# +# The example is for an JTAGICE mkII used to program an atmega256: +# avrdude -v -P usb:xxxx -c jtag2 -p atmega256 +# AVRDUDE_PORT=usb:00B000000D79 +# For serial devices with bootloader we also use the AVRDUDE_PORT setting: +AVRDUDE_PORT=/dev/ttyUSB0 +# Only needed for serial devices, use empty setting for other +# programmers +AVRDUDE_BAUD_OPTION=-b 57600 + +# Additional avrdude options +# First some flash options: +# Verify off is -V +# Erase is -e +# No-Erase (needed by our stk500 variant) is -D +# Note that it really doesn't turn off erase: It doesn't issue an +# explicit erase command (which is not implemented) but the bootloader +# *always* does an implicit erase when programming. +AVRDUDE_FLASH_OPTIONS=-D +AVRDUDE_OPTIONS=$(AVRDUDE_BAUD_OPTION) $(AVRDUDE_FLASH_OPTIONS) +AVRDUDE_MCU=m256rfr2 + +#debug +# CFLAGS += -save-temps +# Bootloader bonsai +# LDFLAGS += -save-temps +# For newer bootloaders we have a jump table at the end of the bootloader +# section: guhRF Bootloader MAC Address +BOOTLOADER_GET_MAC=0x0003ff80 + +LDFLAGS += -Wl,--defsym,bootloader_get_mac=$(BOOTLOADER_GET_MAC) + + +include $(CONTIKIAVR)/Makefile.avr +include $(CONTIKIAVR)/radio/Makefile.radio + +MODULES += core/net/mac core/net core/net/mac/sicslowmac \ + core/net/mac/contikimac core/net/llsec \ +# core/net/ipv6 core/net/ipv4 core/net/ip \ +# core/net/rime \ +# core/net/rpl \ diff --git a/platform/osd-merkur-256/contiki-conf.h b/platform/osd-merkur-256/contiki-conf.h new file mode 100644 index 000000000..fb8cf3178 --- /dev/null +++ b/platform/osd-merkur-256/contiki-conf.h @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2006, Technical University of Munich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * @(#)$$ + */ + +/** + * \file + * Configuration for Atmel ATMEGA256RFR2 + * \author + * David Kopf + * Bernhard Trinnes + */ + +#ifndef CONTIKI_CONF_H_ +#define CONTIKI_CONF_H_ + +/* Platform name, type, and MCU clock rate */ +#define PLATFORM_NAME "RFR2" +#define PLATFORM_TYPE ATMEGA256RFR2 +#ifndef F_CPU +#define F_CPU 16000000UL +#endif + +#include + +#define IEEE802154_CONF_PANID 0xABCD // default panid + +/* The AVR tick interrupt usually is done with an 8 bit counter around 128 Hz. + * 125 Hz needs slightly more overhead during the interrupt, as does a 32 bit + * clock_time_t. + */ + /* Clock ticks per second */ +#define CLOCK_CONF_SECOND 128 + +typedef uint32_t clock_time_t; +#define CLOCK_LT(a,b) ((int32_t)((a)-(b)) < 0) + +/* These routines are not part of the contiki core but can be enabled in cpu/avr/clock.c */ +void clock_delay_msec(uint16_t howlong); +void clock_adjust_ticks(clock_time_t howmany); + +/* COM port to be used for SLIP connection. This is usually UART0. */ +#define SLIP_PORT RS232_PORT_0 + +/* Pre-allocated memory for loadable modules heap space (in bytes)*/ +/* Default is 4096. Currently used only when elfloader is present. Not tested on Raven */ +//#define MMEM_CONF_SIZE 256 + +/* Starting address for code received via the codeprop facility. Not tested. */ +typedef unsigned long off_t; +//#define EEPROMFS_ADDR_CODEPROP 0x8000 + +/* Logging adds 200 bytes to program size. RS232 output slows down webserver. */ +//#define LOG_CONF_ENABLED 1 + +/* RADIOSTATS is used in rf230bb, clock.c and the webserver cgi to report radio usage */ +/* It has less overhead than ENERGEST */ +//#define RADIOSTATS 1 + +/* More extensive stats, via main loop printfs or webserver status pages */ +//#define ENERGEST_CONF_ON 1 + +/* Packet statistics */ +typedef unsigned short uip_stats_t; +//#define UIP_STATISTICS 1 + +/* Available watchdog timeouts depend on mcu. Default is WDTO_2S. -1 Disables the watchdog. */ +/* AVR Studio simulator tends to reboot due to clocking the WD 8 times too fast */ +//#define WATCHDOG_CONF_TIMEOUT -1 + +/* Debugflow macro, useful for tracing path through mac and radio interrupts */ +//#define DEBUGFLOWSIZE 128 + + +/* Define MAX_*X_POWER to reduce tx power and ignore weak rx packets for testing a miniature multihop network. + * Leave undefined for full power and sensitivity. + * tx=0 (3dbm, default) to 15 (-17.2dbm) + * RF230_CONF_AUTOACK sets the extended mode using the energy-detect register with rx=0 (-91dBm) to 84 (-7dBm) + * else the rssi register is used having range 0 (91dBm) to 28 (-10dBm) + * For simplicity RF230_MIN_RX_POWER is based on the energy-detect value and divided by 3 when autoack is not set. + * On the RF230 a reduced rx power threshold will not prevent autoack if enabled and requested. + * These numbers applied to both Raven and Jackdaw give a maximum communication distance of about 15 cm + * and a 10 meter range to a full-sensitivity RF230 sniffer. +#define RF230_MAX_TX_POWER 15 +#define RF230_MIN_RX_POWER 30 + */ + /* The rf231, atmega128rfa1 and atmega256rfr2 can use an rssi + * threshold for triggering rx_busy that saves 0.5ma in rx mode + * 1 - 15 maps into -90 to -48 dBm; the register is written with + * RF230_MIN_RX_POWER/6 + 1. Undefine for -100dBm sensitivity + */ +//#define RF230_MIN_RX_POWER 0 + +/* Network setup */ +/* TX routine passes the cca/ack result in the return parameter */ +#define RDC_CONF_HARDWARE_ACK 1 +/* TX routine does automatic cca and optional backoffs */ +#define RDC_CONF_HARDWARE_CSMA 1 +/* Allow MCU sleeping between channel checks */ +#define RDC_CONF_MCU_SLEEP 1 + +#if NETSTACK_CONF_WITH_IPV6 +#define LINKADDR_CONF_SIZE 8 +#define UIP_CONF_ICMP6 1 +#define UIP_CONF_UDP 1 +#define UIP_CONF_TCP 1 +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#else +/* ip4 should build but is largely untested */ +#define LINKADDR_CONF_SIZE 2 +#define NETSTACK_CONF_NETWORK rime_driver +#endif + +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 + +/* 10 bytes per stateful address context - see sicslowpan.c */ +/* Default is 1 context with prefix aaaa::/64 */ +/* These must agree with all the other nodes or there will be a failure to communicate! */ +#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 +#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 {addr_contexts[0].prefix[0]=0xaa;addr_contexts[0].prefix[1]=0xaa;} +#define SICSLOWPAN_CONF_ADDR_CONTEXT_1 {addr_contexts[1].prefix[0]=0xbb;addr_contexts[1].prefix[1]=0xbb;} +#define SICSLOWPAN_CONF_ADDR_CONTEXT_2 {addr_contexts[2].prefix[0]=0x20;addr_contexts[2].prefix[1]=0x01;addr_contexts[2].prefix[2]=0x49;addr_contexts[2].prefix[3]=0x78,addr_contexts[2].prefix[4]=0x1d;addr_contexts[2].prefix[5]=0xb1;} + +/* Take the default TCP maximum segment size for efficiency and simpler wireshark captures */ +/* Use this to prevent 6LowPAN fragmentation (whether or not fragmentation is enabled) */ +//#define UIP_CONF_TCP_MSS 48 + +#define UIP_CONF_IP_FORWARD 0 +#define UIP_CONF_FWCACHE_SIZE 0 + +#define UIP_CONF_IPV6_CHECKS 1 +#define UIP_CONF_IPV6_QUEUE_PKT 1 +#define UIP_CONF_IPV6_REASSEMBLY 0 + +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_TCP_SPLIT 1 +#define UIP_CONF_DHCP_LIGHT 1 + + +//#if 1 /* No radio cycling */ +#if 0 /* radio cycling */ + +#define NETSTACK_CONF_MAC nullmac_driver +#define NETSTACK_CONF_RDC sicslowmac_driver +#define NETSTACK_CONF_FRAMER framer_802154 +#define NETSTACK_CONF_RADIO rf230_driver +/* AUTOACK receive mode gives better rssi measurements, even if ACK is never requested */ +#define RF230_CONF_AUTOACK 1 +/* Request 802.15.4 ACK on all packets sent (else autoretry). This is primarily for testing. */ +#define SICSLOWPAN_CONF_ACK_ALL 0 +/* 1 + Number of auto retry attempts 0-15 (0 implies don't use extended TX_ARET_ON mode) */ +#define RF230_CONF_FRAME_RETRIES 2 +/* Number of csma retry attempts 0-5 in extended tx mode (7 does immediate tx with no csma) */ +#define RF230_CONF_CSMA_RETRIES 5 +/* Default is one RAM buffer for received packets. More than one may benefit multiple TCP connections or ports */ +#define RF230_CONF_RX_BUFFERS 3 +#define SICSLOWPAN_CONF_FRAG 1 +/* Most browsers reissue GETs after 3 seconds which stops fragment reassembly so a longer MAXAGE does no good */ +#define SICSLOWPAN_CONF_MAXAGE 3 +/* How long to wait before terminating an idle TCP connection. Smaller to allow faster sleep. Default is 120 seconds */ +/* If wait is too short the connection can be reset as a result of multiple fragment reassembly timeouts */ +#define UIP_CONF_WAIT_TIMEOUT 20 +/* 211 bytes per queue buffer */ +#define QUEUEBUF_CONF_NUM 8 +/* 54 bytes per queue ref buffer */ +#define QUEUEBUF_CONF_REF_NUM 2 +/* Allocate remaining RAM as desired */ +/* 30 bytes per TCP connection */ +/* 6LoWPAN does not do well with concurrent TCP streams, as new browser GETs collide with packets coming */ +/* from previous GETs, causing decreased throughput, retransmissions, and timeouts. Increase to study this. */ +/* ACKs to other ports become interleaved with computation-intensive GETs, so ACKs are particularly missed. */ +/* Increasing the number of packet receive buffers in RAM helps to keep ACKs from being lost */ +#define UIP_CONF_MAX_CONNECTIONS 4 +/* 2 bytes per TCP listening port */ +#define UIP_CONF_MAX_LISTENPORTS 4 +/* 25 bytes per UDP connection */ +#define UIP_CONF_UDP_CONNS 10 +/* See uip-ds6.h */ +#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#define UIP_CONF_DS6_DEFRT_NBU 2 +#define UIP_CONF_DS6_PREFIX_NBU 3 +#define UIP_CONF_MAX_ROUTES 20 +#define UIP_CONF_DS6_ADDR_NBU 3 +#define UIP_CONF_DS6_MADDR_NBU 0 +#define UIP_CONF_DS6_AADDR_NBU 0 + + +#elif 1 /* Contiki-mac radio cycling */ +//#define NETSTACK_CONF_MAC nullmac_driver +/* csma needed for burst mode at present. Webserver won't work without it */ +#define NETSTACK_CONF_MAC csma_driver +#define NETSTACK_CONF_RDC contikimac_driver +/* Default is two CCA separated by 500 usec */ +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 +/* So without the header this needed for RPL mesh to form */ +#define CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE 43-18 //multicast RPL DIS length +/* Not tested much yet */ +#define CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION 0 +#define CONTIKIMAC_CONF_COMPOWER 1 +#define RIMESTATS_CONF_ENABLED 0 + +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_FRAMER framer_802154 +#else /* NETSTACK_CONF_WITH_IPV6 */ +#define NETSTACK_CONF_FRAMER contikimac_framer +#endif /* NETSTACK_CONF_WITH_IPV6 */ + +#define NETSTACK_CONF_RADIO rf230_driver +/* The radio needs to interrupt during an rtimer interrupt */ +#define RTIMER_CONF_NESTED_INTERRUPTS 1 +#define RF230_CONF_AUTOACK 1 +/* A 0 here means non-extended mode; 1 means extended mode with no retry, >1 for retrys */ +/* Contikimac strobes on its own, but hardware retries are faster */ +#define RF230_CONF_FRAME_RETRIES 1 +/* Long csma backoffs will compromise radio cycling; set to 0 for 1 csma */ +#define RF230_CONF_CSMA_RETRIES 0 +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 3 +/* 211 bytes per queue buffer. Contikimac burst mode needs 15 for a 1280 byte MTU */ +#define QUEUEBUF_CONF_NUM 15 +/* 54 bytes per queue ref buffer */ +#define QUEUEBUF_CONF_REF_NUM 2 +/* Allocate remaining RAM. Not much left due to queuebuf increase */ +#define UIP_CONF_MAX_CONNECTIONS 2 +#define UIP_CONF_MAX_LISTENPORTS 4 +#define UIP_CONF_UDP_CONNS 5 +#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#define UIP_CONF_DS6_DEFRT_NBU 2 +#define UIP_CONF_DS6_PREFIX_NBU 3 +#define UIP_CONF_MAX_ROUTES 4 +#define UIP_CONF_DS6_ADDR_NBU 3 +#define UIP_CONF_DS6_MADDR_NBU 0 +#define UIP_CONF_DS6_AADDR_NBU 0 + +#else +#error Network configuration not specified! +#endif /* Network setup */ + +/* ************************************************************************** */ +//#pragma mark RPL Settings +/* ************************************************************************** */ +#if UIP_CONF_IPV6_RPL + +#define UIP_CONF_ROUTER 1 +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +/* For slow slip connections, to prevent buffer overruns */ +//#define UIP_CONF_RECEIVE_WINDOW 300 +#undef UIP_CONF_FWCACHE_SIZE +#define UIP_CONF_FWCACHE_SIZE 30 +#define UIP_CONF_BROADCAST 1 +#define UIP_ARCH_IPCHKSUM 1 +#define UIP_CONF_PINGADDRCONF 0 +#define UIP_CONF_LOGGING 0 + +#endif /* RPL */ + +#define CCIF +#define CLIF +#ifndef CC_CONF_INLINE +#define CC_CONF_INLINE inline +#endif + +/* include the project config */ +/* PROJECT_CONF_H might be defined in the project Makefile */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif + +#endif /* CONTIKI_CONF_H_ */ diff --git a/platform/osd-merkur-256/contiki-main.c b/platform/osd-merkur-256/contiki-main.c new file mode 100644 index 000000000..420871524 --- /dev/null +++ b/platform/osd-merkur-256/contiki-main.c @@ -0,0 +1,593 @@ +/* + * Copyright (c) 2006, Technical University of Munich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) + +#define ANNOUNCE_BOOT 1 //adds about 600 bytes to program size +#if ANNOUNCE_BOOT +#define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTA(...) +#endif + +#define DEBUG 0 +#if DEBUG +#define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTD(...) +#endif + +#include +#include +#include +#include +#include +#include + +#include "loader/symbols-def.h" +#include "loader/symtab.h" + +#include "params.h" +#include "radio/rf230bb/rf230bb.h" +#include "net/mac/frame802154.h" +#include "net/mac/framer-802154.h" +#include "net/ipv6/sicslowpan.h" + +#include "contiki.h" +#include "contiki-net.h" +#include "contiki-lib.h" + +#include "dev/rs232.h" +#include "dev/serial-line.h" +#include "dev/slip.h" + +#if AVR_WEBSERVER +#include "httpd-fs.h" +#include "httpd-cgi.h" +#endif + +#ifdef COFFEE_FILES +#include "cfs/cfs.h" +#include "cfs/cfs-coffee.h" +#endif + +#if UIP_CONF_ROUTER&&0 +#include "net/routing/rimeroute.h" +#include "net/rime/rime-udp.h" +#endif + +#include "net/rime/rime.h" + +/* Track interrupt flow through mac, rdc and radio driver */ +//#define DEBUGFLOWSIZE 32 +#if DEBUGFLOWSIZE +uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE]; +#define DEBUGFLOW(c) if (debugflowsize<(DEBUGFLOWSIZE-1)) debugflow[debugflowsize++]=c +#else +#define DEBUGFLOW(c) +#endif + +/* Get periodic prints from idle loop, from clock seconds or rtimer interrupts */ +/* Use of rtimer will conflict with other rtimer interrupts such as contikimac radio cycling */ +/* STAMPS will print ENERGEST outputs if that is enabled. */ +#define PERIODICPRINTS 1 +#if PERIODICPRINTS +//#define PINGS 64 +#define ROUTES 600 +#define STAMPS 60 +#define STACKMONITOR 1024 +uint32_t clocktime; +#define TESTRTIMER 0 +#if TESTRTIMER +uint8_t rtimerflag=1; +struct rtimer rt; +void rtimercycle(void) {rtimerflag=1;} +#endif +#endif + +//uint16_t ledtimer; + +/*-------------------------------------------------------------------------*/ +/*----------------------Configuration of the .elf file---------------------*/ +#if 1 +/* The proper way to set the signature is */ +#include +#else +/* Older avr-gcc's may not define the needed SIGNATURE bytes. Do it manually if you get an error */ +typedef struct {const unsigned char B2;const unsigned char B1;const unsigned char B0;} __signature_t; +#define SIGNATURE __signature_t __signature __attribute__((section (".signature"))) +SIGNATURE = { + .B2 = 0x02,//SIGNATURE_2, //ATMEGA256rfr2 + .B1 = 0xA8,//SIGNATURE_1, //256KB flash + .B0 = 0x1E,//SIGNATURE_0, //Atmel +}; +#endif + +#if 1 +/* JTAG+SPI enabled, External osc 1kck4ms1 , Boot 4096 words @ $1F000, TXC1K+4,1msec delay, Brownout 1.9 volts */ +FUSES ={.low = 0xF6, .high = 0x98, .extended = 0xfe,}; +#define BOOTLOADER_START = 0x3E000 +#else +/* JTAG+SPI, Boot 4096 words @ $F000, Internal oscillator, startup 6 CK +0 ms, Brownout 1.8 volts */ +FUSES ={.low = 0xC2, .high = 0x99, .extended = 0xfe,}; +#endif + +#include "lib/sensors.h" +#include "dev/button-sensor.h" +#include "dev/battery-sensor.h" +#include "dev/pir-sensor.h" +SENSORS(&button_sensor, &pir_sensor); + +uint8_t +rng_get_uint8(void) { +#if 1 + /* Upper two RSSI reg bits (RND_VALUE) are random in rf231 */ + uint8_t j; + j = (PHY_RSSI&0xc0) + ((PHY_RSSI>>2)&0x30) + ((PHY_RSSI>>4)&0x0c) + ((PHY_RSSI>>6)&0x03); +#else +/* Get a pseudo random number using the ADC */ + uint8_t i,j; + ADCSRA=1<>4); +} +/*-------------------------Low level initialization------------------------*/ +/*------Done in a subroutine to keep main routine stack usage small--------*/ +void initialize(void) +{ + watchdog_init(); + watchdog_start(); + + /* Generic or slip connection on uart0 */ + rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); + + /* Second rs232 port for debugging or slip alternative */ +// rs232_init(RS232_PORT_1, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); + + /* Redirect stdout */ + rs232_redirect_stdout(RS232_PORT_0); + + clock_init(); + + if(MCUSR & (1< +//#define delay_us( us ) ( _delay_loop_2(1+(us*F_CPU)/4000000UL) ) +// delay_us(50000); + } + clock_init(); +} +#endif + + PRINTA("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING); + +/* rtimers needed for radio cycling */ + rtimer_init(); + + /* Initialize process subsystem */ + process_init(); + + /* etimers must be started before ctimer_init */ + process_start(&etimer_process, NULL); + ctimer_init(); + + /* Start radio and radio receive process */ + NETSTACK_RADIO.init(); + +/* Get a random seed for the 802.15.4 packet sequence number. + * Some layers will ignore duplicates found in a history (e.g. Contikimac) + * causing the initial packets to be ignored after a short-cycle restart. + */ + random_init(rng_get_uint8()); + + /* Set addresses BEFORE starting tcpip process */ + + linkaddr_t addr; + + if (params_get_eui64(addr.u8)) { + PRINTA("Random EUI64 address generated\n"); + } + +#if NETSTACK_CONF_WITH_IPV6 + memcpy(&uip_lladdr.addr, &addr.u8, sizeof(linkaddr_t)); +#elif WITH_NODE_ID + node_id=get_panaddr_from_eeprom(); + addr.u8[1]=node_id&0xff; + addr.u8[0]=(node_id&0xff00)>>8; + PRINTA("Node ID from eeprom: %X\n",node_id); +#endif + linkaddr_set_node_addr(&addr); + + PRINTA("Panid:%x\n", params_get_panid()); +// framer_802154_set_panid(params_get_panid()); + rf230_set_pan_addr(params_get_panid(),params_get_panaddr(),(uint8_t *)&addr.u8); + rf230_set_channel(params_get_channel()); + rf230_set_txpower(params_get_txpower()); + +#if NETSTACK_CONF_WITH_IPV6 + PRINTA("EUI-64 MAC: %x-%x-%x-%x-%x-%x-%x-%x\n",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]); +#else + PRINTA("MAC address "); + uint8_t i; + for (i=sizeof(linkaddr_t); i>0; i--){ + PRINTA("%x:",addr.u8[i-1]); + } + PRINTA("\n"); +#endif + + /* Initialize stack protocols */ + queuebuf_init(); + NETSTACK_RDC.init(); + NETSTACK_MAC.init(); + NETSTACK_NETWORK.init(); + +#if ANNOUNCE_BOOT + PRINTA("%s %s, channel %u , check rate %u Hz tx power %u\n",NETSTACK_MAC.name, NETSTACK_RDC.name, rf230_get_channel(), + CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1:NETSTACK_RDC.channel_check_interval()), + rf230_get_txpower()); +#if UIP_CONF_IPV6_RPL + PRINTA("RPL Enabled\n"); +#endif +#if UIP_CONF_ROUTER + PRINTA("Routing Enabled\n"); +#endif + +#endif /* ANNOUNCE_BOOT */ + +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 + process_start(&tcpip_process, NULL); +#endif + + process_start(&sensors_process, NULL); + + /* Autostart other processes */ + autostart_start(autostart_processes); + + /*---If using coffee file system create initial web content if necessary---*/ +#if COFFEE_FILES + int fa = cfs_open( "/index.html", CFS_READ); + if (fa<0) { //Make some default web content + PRINTA("No index.html file found, creating upload.html!\n"); + PRINTA("Formatting FLASH file system for coffee..."); + cfs_coffee_format(); + PRINTA("Done!\n"); + fa = cfs_open( "/index.html", CFS_WRITE); + int r = cfs_write(fa, &"It works!", 9); + if (r<0) PRINTA("Can''t create /index.html!\n"); + cfs_close(fa); +// fa = cfs_open("upload.html"), CFW_WRITE); +//
    + } +#endif /* COFFEE_FILES */ + +/* Add addresses for testing */ +#if 0 +{ + uip_ip6addr_t ipaddr; + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); +// uip_ds6_prefix_add(&ipaddr,64,0); +} +#endif + +/*--------------------------Announce the configuration---------------------*/ +#if ANNOUNCE_BOOT +#if AVR_WEBSERVER +{ uint8_t i; + char buf[80]; + unsigned int size; + + for (i=0;i>10); +#elif COFFEE_FILES==3 + PRINTA(".%s online with static %u byte program memory file system\n",buf,size); +#elif COFFEE_FILES==4 + PRINTA(".%s online with dynamic %u KB program memory file system\n",buf,size>>10); +#endif /* COFFEE_FILES */ +} +#else + PRINTA("Online\n"); +#endif +#endif /* ANNOUNCE_BOOT */ + +} + +#if ROUTES && NETSTACK_CONF_WITH_IPV6 +static void +ipaddr_add(const uip_ipaddr_t *addr) +{ + uint16_t a; + int8_t i, f; + for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { + a = (addr->u8[i] << 8) + addr->u8[i + 1]; + if(a == 0 && f >= 0) { + if(f++ == 0) PRINTF("::"); + } else { + if(f > 0) { + f = -1; + } else if(i > 0) { + PRINTF(":"); + } + PRINTF("%x",a); + } + } +} +#endif + +/*-------------------------------------------------------------------------*/ +/*------------------------- Main Scheduler loop----------------------------*/ +/*-------------------------------------------------------------------------*/ +int +main(void) +{ +#if NETSTACK_CONF_WITH_IPV6 + uip_ds6_nbr_t *nbr; +#endif /* NETSTACK_CONF_WITH_IPV6 */ + initialize(); + + while(1) { + process_run(); + watchdog_periodic(); + +#if 0 + /* Turn off LED after a while */ + if (ledtimer) { + if (--ledtimer==0) { + } + } +#endif + +#if 0 +/* Various entry points for debugging in the AVR Studio simulator. + * Set as next statement and step into the routine. + */ + NETSTACK_RADIO.send(packetbuf_hdrptr(), 42); + process_poll(&rf230_process); + packetbuf_clear(); + len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE); + packetbuf_set_datalen(42); + NETSTACK_RDC.input(); +#endif + +#if 0 +/* Clock.c can trigger a periodic PLL calibration in the RF230BB driver. + * This can show when that happens. + */ + extern uint8_t rf230_calibrated; + if (rf230_calibrated) { + PRINTD("\nRF230 calibrated!\n"); + rf230_calibrated=0; + } +#endif + +/* Set DEBUGFLOWSIZE in contiki-conf.h to track path through MAC, RDC, and RADIO */ +#if DEBUGFLOWSIZE + if (debugflowsize) { + debugflow[debugflowsize]=0; + PRINTF("%s",debugflow); + debugflowsize=0; + } +#endif + +#if PERIODICPRINTS +#if TESTRTIMER +/* Timeout can be increased up to 8 seconds maximum. + * A one second cycle is convenient for triggering the various debug printouts. + * The triggers are staggered to avoid printing everything at once. + */ + if (rtimerflag) { + rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL); + rtimerflag=0; +#else + if (clocktime!=clock_seconds()) { + clocktime=clock_seconds(); +#endif + +#if STAMPS +if ((clocktime%STAMPS)==0) { +#if ENERGEST_CONF_ON +#include "lib/print-stats.h" + print_stats(); +#elif RADIOSTATS +extern volatile unsigned long radioontime; + PRINTF("%u(%u)s\n",clocktime,radioontime); +#else + PRINTF("%us\n",clocktime); +#endif + +} +#endif +#if TESTRTIMER + clocktime+=1; +#endif + +#if PINGS && NETSTACK_CONF_WITH_IPV6 +extern void raven_ping6(void); +if ((clocktime%PINGS)==1) { + PRINTF("**Ping\n"); + raven_ping6(); +} +#endif + +#if ROUTES && NETSTACK_CONF_WITH_IPV6 +if ((clocktime%ROUTES)==2) { + +extern uip_ds6_netif_t uip_ds6_if; + + uint8_t i,j=0; + PRINTF("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB); + for (i=0;iipaddr); + PRINTF("\n"); + j=0; + } + + if (j) PRINTF(" "); + PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); + { + uip_ds6_route_t *r; + j = 1; + for(r = uip_ds6_route_head(); + r != NULL; + r = uip_ds6_route_next(r)) { + ipaddr_add(&r->ipaddr); + PRINTF("/%u (via ", r->length); + ipaddr_add(uip_ds6_route_nexthop(r)); + PRINTF(") %lus\n", r->state.lifetime); + j = 0; + } + } + if (j) PRINTF(" "); + PRINTF("\n---------\n"); + +} +#endif + +#if STACKMONITOR +if ((clocktime%STACKMONITOR)==3) { + extern uint16_t __bss_end; + uint16_t p=(uint16_t)&__bss_end; + do { + if (*(uint16_t *)p != 0x4242) { + PRINTF("Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end); + break; + } + p+=10; + } while (p +*/ + + + // WARNING : Blink function is disabled on the core leds.c file + +#include "contiki.h" +#include "dev/leds.h" +#include "leds-arch.h" + +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ +DDRE |= (1< + +#define NUM_DIGITAL_PINS 15 +#define NUM_ANALOG_INPUTS 6 +#define analogInputToDigitalPin(p) ((p < NUM_ANALOG_INPUTS) ? (p) + NUM_DIGITAL_PINS : -1) +#define digitalPinHasPWM(p) ((p) == 2 ||(p) == 3 ||(p) == 4 ||(p) == 14 ) + +// Dev board specific defines: RF RX and TX LEDs: +#define RXLED_DDR DDRB +#define RXLED_PORT PORTB +#define RXLED_POS PB6 + +#define TXLED_DDR DDRB +#define TXLED_PORT PORTB +#define TXLED_POS PB7 + +const static uint8_t SS = 10; +const static uint8_t MOSI = 11; +const static uint8_t MISO = 13; +const static uint8_t SCK = 12; + +const static uint8_t SDA = 9; +const static uint8_t SCL = 8; +const static uint8_t LED = 4; +const static uint8_t LED1 = 4; +const static uint8_t LED2 = 5; + +const static uint8_t A0 = 7; +const static uint8_t A1 = 6; +const static uint8_t A2 = 5; +const static uint8_t A3 = 4; +const static uint8_t A4 = 0; +const static uint8_t A5 = 1; + +// A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins) +// Only pins available for RECEIVE (TRANSMIT can be on any pin): +// Pins: 10, 11, 12, 13, 14 + +#define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 14)) || ? (&PCICR) : ((uint8_t *)0) ) + +#define digitalPinToPCICRbit(p) ( 0 ) + +#define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 14)) ? (&PCMSK0) : ((uint8_t *)0) ) + +#define digitalPinToPCMSKbit(p) ( ((p) == 10) ? 6 : \ + ( ((p) == 11) ? 5 : \ + ( ((p) == 12) ? 1 : \ + ( ((p) == 13) ? 3 : \ + ( ((p) == 14) ? 7 : \ + 0 ) ) ) ) ) + +#ifdef ARDUINO_MAIN + +const uint16_t PROGMEM port_to_mode_PGM[] = { + NOT_A_PORT, + NOT_A_PORT, + (uint16_t)&DDRB, + NOT_A_PORT, + (uint16_t)&DDRD, + (uint16_t)&DDRE, + (uint16_t)&DDRF, + (uint16_t)&DDRG, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, +}; + +const uint16_t PROGMEM port_to_output_PGM[] = { + NOT_A_PORT, + NOT_A_PORT, + (uint16_t)&PORTB, + NOT_A_PORT, + (uint16_t)&PORTD, + (uint16_t)&PORTE, + (uint16_t)&PORTF, + (uint16_t)&PORTG, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, + NOT_A_PORT, +}; + +const uint16_t PROGMEM port_to_input_PGM[] = { + NOT_A_PIN, + NOT_A_PIN, + NOT_A_PIN, + (uint16_t)&PINC, + (uint16_t)&PIND, + (uint16_t)&PINE, + (uint16_t)&PINF, + (uint16_t)&PING, + NOT_A_PIN, + NOT_A_PIN, + NOT_A_PIN, + NOT_A_PIN, + NOT_A_PIN, +}; + +const uint8_t PROGMEM digital_pin_to_port_PGM[] = { + // PORTLIST + // ------------------------------------------- + PE , // PE 1 ** 0 ** D0 / USART0_TX + PE , // PE 0 ** 1 ** D1 / USART0_RX + PE , // PE 3 ** 2 ** D2 / PWM + PE , // PE 4 ** 3 ** D3 / PWM + PE , // PE 5 ** 4 ** D4 / PWM / LED1 / LED + PE , // PE 6 ** 5 ** D5 / LED2 + PD , // PD 3 ** 6 ** D6 / USART1_TX + PD , // PD 2 ** 7 ** D7 / USART1_RX + PD , // PD 0 ** 8 ** D8 / I2C_SCL + PD , // PD 1 ** 9 ** D9 / I2C_SDA + PB , // PB 0 ** 10 ** D10 / SPI_SSN + PB , // PB 2 ** 11 ** D11 / SPI_MOSI + PB , // PB 1 ** 12 ** D12 / SPI_SCK + PB , // PB 3 ** 13 ** D13 / SPI_MISO + PB , // PB 4 ** 14 ** D14 / PWM + PF , // PF 7 ** 15 ** A0 / D15 + PF , // PF 6 ** 16 ** A1 / D16 + PF , // PF 5 ** 17 ** A2 / D17 + PF , // PF 4 ** 18 ** A3 / D18 + PF , // PF 0 ** 19 ** A4 / D19 + PF , // PF 1 ** 20 ** A5 / D20 +// PB , // PB 6 ** 34 ** D34 / LED1 / LED / PWM +// PB , // PB 7 ** 35 ** D35 / LED2 / PWM +// PE , // PE 2 ** 2 ** D2 +// PE , // PE 7 ** 7 ** D7 +// PB , // PB 5 ** 8 ** D8 / PWM +// PG , // PG 0 ** 16 ** D16 +// PG , // PG 1 ** 17 ** D17 +// PG , // PG 2 ** 18 ** D18 +// PG , // PG 5 ** 19 ** D19 / PWM +// PD , // PD 4 ** 22 ** D22 +// PD , // PD 5 ** 23 ** D23 +// PD , // PD 6 ** 24 ** D24 +// PD , // PD 7 ** 25 ** D25 +// PF , // PF 2 ** 28 ** A2 / D28 +// PF , // PF 3 ** 29 ** A3 / D29 +}; + +const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { + // PIN IN PORT + // ------------------------------------------- + _BV( 1 ) , // PE 1 ** 0 ** USART0_TX + _BV( 0 ) , // PE 0 ** 1 ** USART0_RX + _BV( 3 ) , // PE 3 ** 2 ** D3 / PWM + _BV( 4 ) , // PE 4 ** 3 ** D4 / PWM + _BV( 5 ) , // PE 5 ** 4 ** D5 / PWM + _BV( 6 ) , // PE 6 ** 5 ** D6 + _BV( 3 ) , // PD 3 ** 6 ** D21 / USART1_TX + _BV( 2 ) , // PD 2 ** 7 ** D20 / USART1_RX + _BV( 0 ) , // PD 0 ** 8 ** D15 / I2C_SCL + _BV( 1 ) , // PD 1 ** 9 ** D14 / I2C_SDA + _BV( 0 ) , // PB 0 ** 10 ** D10 / SPI_SSN + _BV( 2 ) , // PB 2 ** 11 ** D11 / SPI_MOSI + _BV( 1 ) , // PB 1 ** 12 ** D13 / SPI_SCK + _BV( 3 ) , // PB 3 ** 13 ** D12 / SPI_MISO + _BV( 4 ) , // PB 4 ** 14 ** D9 / PWM + _BV( 7 ) , // PF 7 ** 15 ** A0 / D33 + _BV( 6 ) , // PF 6 ** 16 ** A1 / D32 + _BV( 5 ) , // PF 5 ** 17 ** A2 / D31 + _BV( 4 ) , // PF 4 ** 18 ** A3 / D30 + _BV( 0 ) , // PF 0 ** 19 ** A4 / D26 + _BV( 1 ) , // PF 1 ** 20 ** A5 / D27 +// _BV( 2 ) , // PE 2 ** 2 ** D2 +// _BV( 7 ) , // PE 7 ** 7 ** D7 +// _BV( 5 ) , // PB 5 ** 8 ** D8 / PWM +// _BV( 0 ) , // PG 0 ** 16 ** D16 +// _BV( 1 ) , // PG 1 ** 17 ** D17 +// _BV( 2 ) , // PG 2 ** 18 ** D18 +// _BV( 5 ) , // PG 5 ** 19 ** D19 / PWM +// _BV( 4 ) , // PD 4 ** 22 ** D22 +// _BV( 5 ) , // PD 5 ** 23 ** D23 +// _BV( 6 ) , // PD 6 ** 24 ** D24 +// _BV( 7 ) , // PD 7 ** 25 ** D25 +// _BV( 2 ) , // PF 2 ** 28 ** A2 / D28 +// _BV( 3 ) , // PF 3 ** 29 ** A3 / D29 +// _BV( 6 ) , // PB 6 ** 34 ** D34 / LED1 / LED / PWM +// _BV( 7 ) , // PB 7 ** 35 ** D35 / LED2 / PWM +}; + +#endif + +#endif diff --git a/platform/osd-merkur-256/node-id.c b/platform/osd-merkur-256/node-id.c new file mode 100644 index 000000000..8698b1855 --- /dev/null +++ b/platform/osd-merkur-256/node-id.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * $Id: node-id.c,v 1.1 2007/03/23 09:59:08 nifi Exp $ + */ + +/** + * \file + * Utility to store a node id in the external flash + * \author + * Adam Dunkels + */ + +#include "node-id.h" +#include "contiki-conf.h" +#include "dev/xmem.h" + +unsigned short node_id = 0; + +/*---------------------------------------------------------------------------*/ +void +node_id_restore(void) +{ +/* todo */ +/* + unsigned char buf[4]; + xmem_pread(buf, 4, NODE_ID_XMEM_OFFSET); + if(buf[0] == 0xad && + buf[1] == 0xde) { + node_id = (buf[2] << 8) | buf[3]; + } else { + node_id = 0; + } +*/ + node_id = 0; +} +/*---------------------------------------------------------------------------*/ +void +node_id_burn(unsigned short id) +{ +/* todo */ +/* + unsigned char buf[4]; + buf[0] = 0xad; + buf[1] = 0xde; + buf[2] = id >> 8; + buf[3] = id & 0xff; + xmem_erase(XMEM_ERASE_UNIT_SIZE, NODE_ID_XMEM_OFFSET); + xmem_pwrite(buf, 4, NODE_ID_XMEM_OFFSET); +*/ +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/osd-merkur-256/node-id.h b/platform/osd-merkur-256/node-id.h new file mode 100644 index 000000000..592379fc9 --- /dev/null +++ b/platform/osd-merkur-256/node-id.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: node-id.h,v 1.1 2007/03/23 09:59:08 nifi Exp $ + */ + +#ifndef __NODE_ID_H__ +#define __NODE_ID_H__ + +void node_id_restore(void); +void node_id_burn(unsigned short node_id); + +extern unsigned short node_id; + +#endif /* __NODE_ID_H__ */ diff --git a/platform/osd-merkur-256/params.c b/platform/osd-merkur-256/params.c new file mode 100644 index 000000000..4b0252387 --- /dev/null +++ b/platform/osd-merkur-256/params.c @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) + +#define DEBUG 1 +#if DEBUG +#define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTD(...) +#endif + +#include "contiki.h" +#include +#include +#include +#include + +#if AVR_WEBSERVER +//#include "httpd-fs.h" +//#include "httpd-cgi.h" +#endif + +#include "contiki-net.h" +#include "params.h" + +#if WITH_NODE_ID +uint16_t node_id; +#endif + +#if CONTIKI_CONF_RANDOM_MAC +extern uint8_t rng_get_uint8(void); +static void +generate_new_eui64(uint8_t eui64[8]) { + eui64[0] = 0x02; + eui64[1] = rng_get_uint8(); + eui64[2] = rng_get_uint8(); + eui64[3] = 0xFF; + eui64[4] = 0xFE; + eui64[5] = rng_get_uint8(); + eui64[6] = rng_get_uint8(); + eui64[7] = rng_get_uint8(); +} +#endif + +#if AVR_WEBSERVER +/* Webserver builds can set these in httpd-fsdata.c via makefsdata.h */ +extern uint8_t default_mac_address[8]; +extern uint8_t default_server_name[16]; +extern uint8_t default_domain_name[30]; +#else +const uint8_t default_mac_address[8] PROGMEM = PARAMS_EUI64ADDR; +const uint8_t default_server_name[] PROGMEM = PARAMS_SERVERNAME; +const uint8_t default_domain_name[] PROGMEM = PARAMS_DOMAINNAME; +#endif + +#if PARAMETER_STORAGE==0 +/* 0 Hard coded, minmal program and eeprom usage. */ + +extern uint8_t bootloader_get_mac(uint8_t); + +uint8_t +params_get_eui64(uint8_t *eui64) { +#if CONTIKI_CONF_RANDOM_MAC + PRINTD("Generating random EUI64 MAC\n"); + generate_new_eui64(eui64); + return 1; +#else + uint8_t i; +#if BOOTLOADER_GET_MAC + for (i=0;i 26)) x[1]=x[0]; +/* Do exclusive or test on the two values read */ + if((uint8_t)x[0]!=(uint8_t)~x[1]) {//~x[1] can promote comparison to 16 bit +/* Verification fails, rewrite everything */ + uint8_t i,buffer[32]; + PRINTD("EEPROM is corrupt, rewriting with defaults.\n"); +#if CONTIKI_CONF_RANDOM_MAC + PRINTD("Generating random EUI64 MAC\n"); + generate_new_eui64(&buffer); + randomeui64=1; +#else + for (i=0;iSet EEPROM RF channel to %d\n",x); + } + } + return x; +} +uint8_t +params_get_eui64(uint8_t *eui64) { + size_t size = sizeof(linkaddr_t); + if(settings_get(SETTINGS_KEY_EUI64, 0, (unsigned char*)eui64, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get EUI64 MAC\n"); + return 0; + } +#if CONTIKI_CONF_RANDOM_MAC + PRINTD("Generating random EUI64 MAC\n"); + generate_new_eui64(eui64); +#else + {uint8_t i;for (i=0;i<8;i++) eui64[i] = pgm_read_byte_near(default_mac_address+i);} //test this +#endif + if (settings_add(SETTINGS_KEY_EUI64,(unsigned char*)eui64,8) == SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM MAC address\n"); + } +#if CONTIKI_CONF_RANDOM_MAC + return 1; +#else + return 0; +#endif +} +uint16_t +params_get_panid(void) { + uint16_t x; + size_t size = 2; + if (settings_get(SETTINGS_KEY_PAN_ID, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get PAN ID of %04x\n",x); + } else { + x=IEEE802154_PANID; + if (settings_add_uint16(SETTINGS_KEY_PAN_ID,x)==SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM PAN ID to %04x\n",x); + } + } + return x; +} +uint16_t +params_get_panaddr(void) { + uint16_t x; + size_t size = 2; + if (settings_get(SETTINGS_KEY_PAN_ADDR, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get PAN address of %04x\n",x); + } else { + x=PARAMS_PANADDR; + if (settings_add_uint16(SETTINGS_KEY_PAN_ADDR,x)==SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM PAN address to %04x\n",x); + } + } + return x; +} +uint8_t +params_get_txpower(void) { + uint8_t x; + size_t size = 1; + if (settings_get(SETTINGS_KEY_TXPOWER, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get tx power of %d (0=max)\n",x); + } else { + x=PARAMS_TXPOWER; + if (settings_add_uint8(SETTINGS_KEY_TXPOWER,x)==SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM tx power of %d (0=max)\n",x); + } + } + return x; +} +#endif /* CONTIKI_CONF_SETTINGS_MANAGER */ diff --git a/platform/osd-merkur-256/params.h b/platform/osd-merkur-256/params.h new file mode 100644 index 000000000..7b074c198 --- /dev/null +++ b/platform/osd-merkur-256/params.h @@ -0,0 +1,104 @@ +#ifndef PARAMS_H_ +#define PARAMS_H_ +/* PARAMETER_STORAGE = + * 0 Hard coded, minmal program and eeprom usage. + * 1 Stored in fixed eeprom locations, rewritten from flash if corrupt. + * This allows parameter changes using a hardware programmer or custom application code. + * Corruption test is based on channel verify so get the channel before anything else! + * 2 Obtained from eeprom using the general settings manager and read from program flash if not present. + * Useful for for testing builds without wearing out flash memory. + * 3 Obtained from eeprom using the settings manager and rewritten from flash if not present. + * This ensures all parameters are present in upper eeprom flash. + * + * Note the parameters in this file can be changed without forcing a complete rebuild. + */ +// default settings +#define CHANNEL_802_15_4 25 // default frequency (11-26) + +// end default settings + +#define CONTIKI_CONF_RANDOM_MAC 0 //adds 78 bytes +#define CONTIKI_CONF_SETTINGS_MANAGER 0 //adds 1696 bytes +#define BOOTLOADER_GET_MAC 0x0003ff80 // get mac from bootloader + +#if CONTIKI_CONF_SETTINGS_MANAGER +//#define PARAMETER_STORAGE 2 +#define PARAMETER_STORAGE 2 +#else +#define PARAMETER_STORAGE 0 // 0:get mac from booloader (see above) +#endif + +/* Include settings.h, then dummy out the write routines */ +#include "settings.h" +#if PARAMETER_STORAGE==2 +#define settings_add(...) 0 +#define settings_add_uint8(...) 0 +#define settings_add_uint16(...) 0 +#endif + +#if AVR_WEBSERVER +/* Webserver builds can set some defaults in httpd-fsdata.c via makefsdata.h */ +extern uint8_t eemem_mac_address[8]; +extern uint8_t eemem_server_name[16]; +extern uint8_t eemem_domain_name[30]; +#endif +#ifdef SERVER_NAME +#define PARAMS_SERVERNAME SERVER_NAME +#else +#define PARAMS_SERVERNAME "ATMEGA256rfr2" +#endif +#ifdef DOMAIN_NAME +#define PARAMS_DOMAINNAME DOMAIN_NAME +#else +#define PARAMS_DOMAINNAME "localhost" +#endif +#ifdef NODE_ID +#define PARAMS_NODEID NODE_ID +#else +#define PARAMS_NODEID 0 +#endif +#ifdef IEEE802154_PANADDR +#define PARAMS_PANADDR IEEE802154_PANADDR +#else +#define PARAMS_PANADDR 0 +#endif +#ifdef RF230_MAX_TX_POWER +#define PARAMS_TXPOWER RF230_MAX_TX_POWER +#else +#define PARAMS_TXPOWER 0 +#endif +#ifdef EUI64_ADDRESS +#define PARAMS_EUI64ADDR EUI64_ADDRESS +#else +/* This form of of EUI64 mac allows full 6LoWPAN header compression from mac address */ +#if UIP_CONF_LL_802154 +//#define PARAMS_EUI64ADDR {0x02, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN} +//#define PARAMS_EUI64ADDR {0x00, 0x21, 0x2e, 0xff, 0xff, 0x00, 0x1E, 0xFB} +#define PARAMS_EUI64ADDR {0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x11} +#else +//#define PARAMS_EUI64ADDR {0x02, 0xNN, 0xNN, 0xff, 0xfe, 0xNN, 0xNN, 0xNN} +#define PARAMS_EUI64ADDR {0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x03} +#endif +/* This form of of EUI64 mac allows 16 bit 6LoWPAN header compression on multihops */ +//#define PARAMS_EUI64ADDR {0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0xNN, 0xNN} +#endif + +uint8_t params_get_eui64(uint8_t *eui64); +#if PARAMETER_STORAGE==0 +/* Hard coded program flash parameters */ +#define params_get_servername(...) +#define params_get_nodeid(...) PARAMS_NODEID +#define params_get_channel(...) CHANNEL_802_15_4 +#define params_get_panid(...) IEEE802154_PANID +#define params_get_panaddr(...) PARAMS_PANADDR +#define params_get_txpower(...) PARAMS_TXPOWER +#else +/* Parameters stored in eeprom */ +uint16_t params_get_nodeid(void); +uint8_t params_get_channel(void); +uint16_t params_get_panid(void); +uint16_t params_get_panaddr(void); +uint8_t params_get_txpower(void); +#endif + +#endif /* PARAMS_H_ */ diff --git a/platform/osd-merkur-256/slip_uart0.c b/platform/osd-merkur-256/slip_uart0.c new file mode 100644 index 000000000..edff55385 --- /dev/null +++ b/platform/osd-merkur-256/slip_uart0.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2010, University of Colombo School of Computing + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * @(#)$$ + */ + +/** + * \file + * Machine dependent AVR SLIP routines for UART0. + * \author + * Kasun Hewage + */ + +#include +#include "contiki.h" +#include "dev/rs232.h" +#include "slip.h" + +/*---------------------------------------------------------------------------*/ +static int +slip_putchar(char c, FILE *stream) +{ +#define SLIP_END 0300 + static char debug_frame = 0; + + if (!debug_frame) { /* Start of debug output */ + slip_arch_writeb(SLIP_END); + slip_arch_writeb('\r'); /* Type debug line == '\r' */ + debug_frame = 1; + } + + slip_arch_writeb((unsigned char)c); + + /* + * Line buffered output, a newline marks the end of debug output and + * implicitly flushes debug output. + */ + if (c == '\n') { + slip_arch_writeb(SLIP_END); + debug_frame = 0; + } + + return c; +} +/*---------------------------------------------------------------------------*/ +static FILE slip_stdout = FDEV_SETUP_STREAM(slip_putchar, NULL, + _FDEV_SETUP_WRITE); +/*---------------------------------------------------------------------------*/ +void +slip_arch_init(unsigned long ubr) +{ + rs232_set_input(SLIP_PORT, slip_input_byte); + stdout = &slip_stdout; +} +/*---------------------------------------------------------------------------*/ +/* + XXX: + Currently, the following function is in cpu/avr/dev/rs232.c file. this + should be moved to here from there hence this is a platform specific slip + related function. +void +slip_arch_writeb(unsigned char c) +{ + rs232_send(RS232_PORT_0, c); +} +*/ diff --git a/platform/seedeye/Makefile.seedeye b/platform/seedeye/Makefile.seedeye index 8b6a3f732..0d2514d2f 100644 --- a/platform/seedeye/Makefile.seedeye +++ b/platform/seedeye/Makefile.seedeye @@ -6,10 +6,6 @@ ifdef SEEDEYE_ID CFLAGS += -DSEEDEYE_ID=${SEEDEYE_ID} endif -ifeq ($(UIP_CONF_IPV6),1) -CFLAGS += -DWITH_UIP6=1 -endif - CONTIKI_TARGET_DIRS = . dev dev/mrf24j40 apps net CONTIKI_TARGET_MAIN = ${addprefix $(OBJECTDIR)/,contiki-main.o} @@ -63,3 +59,6 @@ CONTIKI_TARGET_SOURCEFILES += $(CONTIKI_CORE_SOURCEFILES) CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) include $(CONTIKI)/cpu/pic32/Makefile.pic32 + +MODULES += core/net core/net/mac core/net/rime core/net/llsec + diff --git a/platform/seedeye/contiki-conf.h b/platform/seedeye/contiki-conf.h index cf6d96894..d58ff686d 100644 --- a/platform/seedeye/contiki-conf.h +++ b/platform/seedeye/contiki-conf.h @@ -7,7 +7,7 @@ * (http://www.cnit.it). * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -35,7 +35,7 @@ */ /** - * \file contiki-conf.h + * \file platform/seedeye/contiki-conf.h * \brief Contiki configuration file for the SEEDEYE port. * \author Giovanni Pellerano * \date 2012-03-21 @@ -60,7 +60,7 @@ typedef uint16_t uip_stats_t; typedef uint32_t clock_time_t; typedef uint32_t rtimer_clock_t; -#define RTIMER_CLOCK_LT(a,b) ((int32_t)((a)-(b)) < 0) +#define RTIMER_CLOCK_DIFF(a,b) ((int32_t)((a)-(b))) #define RF_CHANNEL 13 @@ -69,7 +69,7 @@ typedef uint32_t rtimer_clock_t; #define ENERGEST_CONF_ON 1 #endif /* ENERGEST_CONF_ON */ -#ifdef WITH_UIP6 +#ifdef NETSTACK_CONF_WITH_IPV6 #define NETSTACK_CONF_NETWORK sicslowpan_driver #define NETSTACK_CONF_FRAMER framer_802154 #define NETSTACK_CONF_MAC nullmac_driver @@ -87,16 +87,11 @@ typedef uint32_t rtimer_clock_t; #define RDC_CONF_HARDWARE_CSMA 1 -#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0 - -#ifdef WITH_UIP6 +#ifdef NETSTACK_CONF_WITH_IPV6 #define UIP_CONF_ROUTER 1 -#ifndef UIP_CONF_IPV6_RPL -#define UIP_CONF_IPV6_RPL 1 -#endif /* UIP_CONF_IPV6_RPL */ /* IPv6 configuration options */ -#define UIP_CONF_IPV6 1 +#define NETSTACK_CONF_WITH_IPV6 1 #define NBR_TABLE_CONF_MAX_NEIGHBORS 20 /* number of neighbors */ #define UIP_CONF_DS6_ROUTE_NBU 20 /* number of routes */ #define UIP_CONF_ND6_SEND_RA 0 diff --git a/platform/seedeye/contiki-seedeye-main.c b/platform/seedeye/contiki-seedeye-main.c index 04e55a335..5394b8e02 100644 --- a/platform/seedeye/contiki-seedeye-main.c +++ b/platform/seedeye/contiki-seedeye-main.c @@ -35,7 +35,11 @@ */ /** - * \addtogroup SeedEye Contiki SEEDEYE Platform + * \addtogroup platform + * @{ */ + +/** + * \defgroup SeedEye Contiki SEEDEYE Platform * * @{ */ @@ -161,15 +165,13 @@ main(int argc, char **argv) r = process_run(); } while(r > 0); - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); watchdog_stop(); asm volatile("wait"); watchdog_start(); - ENERGEST_OFF(ENERGEST_TYPE_LPM); - ENERGEST_ON(ENERGEST_TYPE_CPU); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } @@ -178,3 +180,5 @@ main(int argc, char **argv) /*---------------------------------------------------------------------------*/ /** @} */ +/** @} */ + diff --git a/platform/seedeye/dev/battery-sensor.c b/platform/seedeye/dev/battery-sensor.c index 42e7b6abb..4682d1bb9 100644 --- a/platform/seedeye/dev/battery-sensor.c +++ b/platform/seedeye/dev/battery-sensor.c @@ -7,7 +7,7 @@ * (http://www.cnit.it). * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -33,7 +33,7 @@ * SUCH DAMAGE. * */ - + /** * \addtogroup SeedEye Contiki SEEDEYE Platform * @@ -41,7 +41,7 @@ */ /** - * \file battery-sensor.c + * \file platform/seedeye/dev/battery-sensor.c * \brief Battery Sensor * \author Giovanni Pellerano * \date 2012-07-04 @@ -73,7 +73,7 @@ value(int type) for(i = 0; i < BATTERY_SAMPLES; ++i) { tmp += battery_samples[i]; } - + return tmp / BATTERY_SAMPLES; } /*---------------------------------------------------------------------------*/ @@ -82,10 +82,10 @@ configure(int type, int c) { // all PORTB = Digital; RB10 = analog AD1PCFG = 0b1111110111111111; - + // SSRC bit = 111 implies internal counter ends sampling and starts converting AD1CON1 = 0b0000000011100000; - + AD1CHS = 0b00000000000010100000000000000000; AD1CSSL = 0; @@ -116,12 +116,12 @@ SENSORS_SENSOR(battery_sensor, BATTERY_SENSOR, value, configure, status); PROCESS_THREAD(battery_process, ev, data) { PROCESS_BEGIN(); - + while(1) { static struct etimer et; etimer_set(&et, CLOCK_SECOND); - + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); // start converting @@ -130,10 +130,10 @@ PROCESS_THREAD(battery_process, ev, data) while(!(AD1CON1 & 0b0000000000000001)) { ; // wait conversion finish } - + // read the conversion result battery_samples[counter] = ADC1BUF0; - + counter = (counter + 1) % BATTERY_SAMPLES; } diff --git a/platform/seedeye/dev/button-sensor.c b/platform/seedeye/dev/button-sensor.c index c972e3036..fd54f12f2 100644 --- a/platform/seedeye/dev/button-sensor.c +++ b/platform/seedeye/dev/button-sensor.c @@ -7,7 +7,7 @@ * (http://www.cnit.it). * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -41,7 +41,7 @@ */ /** - * \file button-sensor.c + * \file platform/seedeye/dev/button-sensor.c * \brief Button Sensor * \author Giovanni Pellerano * \date 2012-04-24 @@ -66,15 +66,15 @@ static uint8_t sensor_status = 0; ISR(_CHANGE_NOTICE_VECTOR) { ENERGEST_ON(ENERGEST_TYPE_IRQ); - + if(timer_expired(&debouncetimer)) { timer_set(&debouncetimer, CLOCK_SECOND / 4); sensors_changed(&button_sensor); } - + IFS1CLR = _IFS1_CNIF_MASK; - + ENERGEST_OFF(ENERGEST_TYPE_IRQ); } @@ -99,28 +99,28 @@ configure(int type, int value) if(value) { if(!status(SENSORS_ACTIVE)) { timer_set(&debouncetimer, 0); - + TRISDbits.TRISD5 = 1; CNCON = 0; CNCONSET = 1 << _CNCON_ON_POSITION | 1 << _CNCON_SIDL_POSITION; CNEN = 1 << _CNEN_CNEN14_POSITION; CNPUE = 1 << _CNPUE_CNPUE14_POSITION; - + IEC1CLR = _IEC1_CNIE_MASK; IFS1CLR = _IFS1_CNIF_MASK; IPC6CLR = _IPC6_CNIP_MASK; IPC6SET = 6 << _IPC6_CNIP_POSITION; - + IEC1SET = 1 << _IEC1_CNIE_POSITION; - + sensor_status = 1; } } return 1; } - + sensor_status = 0; return 0; diff --git a/platform/seedeye/dev/leds-arch.c b/platform/seedeye/dev/leds-arch.c index c9fdbf1dc..1cbb05a8c 100644 --- a/platform/seedeye/dev/leds-arch.c +++ b/platform/seedeye/dev/leds-arch.c @@ -1,13 +1,13 @@ /* * Contiki PIC32 Port project - * + * * Copyright (c) 2012, * Scuola Superiore Sant'Anna (http://www.sssup.it) and * Consorzio Nazionale Interuniversitario per le Telecomunicazioni * (http://www.cnit.it). * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -41,7 +41,7 @@ */ /** - * \file leds-arch.c + * \file platform/seedeye/dev/leds-arch.c * \brief LEDs Specific Arch Conf * \author Giovanni Pellerano * \date 2012-03-21 diff --git a/platform/seedeye/dev/mrf24j40/mrf24j40.c b/platform/seedeye/dev/mrf24j40/mrf24j40.c index 3c8ad3f29..368d5e4d3 100644 --- a/platform/seedeye/dev/mrf24j40/mrf24j40.c +++ b/platform/seedeye/dev/mrf24j40/mrf24j40.c @@ -927,6 +927,31 @@ PROCESS_THREAD(mrf24j40_process, ev, data) PROCESS_END(); } +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} + /*---------------------------------------------------------------------------*/ const struct radio_driver mrf24j40_driver = { mrf24j40_init, @@ -938,7 +963,11 @@ const struct radio_driver mrf24j40_driver = { mrf24j40_receiving_packet, mrf24j40_pending_packet, mrf24j40_on, - mrf24j40_off + mrf24j40_off, + get_value, + set_value, + get_object, + set_object }; /*---------------------------------------------------------------------------*/ diff --git a/platform/seedeye/dev/mrf24j40/mrf24j40.h b/platform/seedeye/dev/mrf24j40/mrf24j40.h index 34ea55594..05061357b 100644 --- a/platform/seedeye/dev/mrf24j40/mrf24j40.h +++ b/platform/seedeye/dev/mrf24j40/mrf24j40.h @@ -34,6 +34,10 @@ * */ +/** + * \addtogroup SeedEye + * @{ */ + /** * \defgroup mrf24j40 MRF24J40 Driver * @@ -226,3 +230,4 @@ typedef union _INT_status { #endif /* MRF24J40_H_ */ /** @} */ +/** @} */ diff --git a/platform/seedeye/dev/radio-sensor.c b/platform/seedeye/dev/radio-sensor.c index b13df4fa4..bffc27601 100644 --- a/platform/seedeye/dev/radio-sensor.c +++ b/platform/seedeye/dev/radio-sensor.c @@ -7,7 +7,7 @@ * (http://www.cnit.it). * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -41,7 +41,7 @@ */ /** - * \file radio-sensor.c + * \file platform/seedeye/dev/radio-sensor.c * \brief RADIO Sensor * \author Giovanni Pellerano * \date 2012-04-24 diff --git a/platform/seedeye/init-net.c b/platform/seedeye/init-net.c index 2a41ba271..5b871b43c 100644 --- a/platform/seedeye/init-net.c +++ b/platform/seedeye/init-net.c @@ -7,7 +7,7 @@ * (http://www.cnit.it). * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -41,7 +41,7 @@ */ /** - * \file init-net.c + * \file platform/seedeye/init-net.c * \brief Network initialization for the SEEDEYE port. * \author Giovanni Pellerano * \date 2012-03-25 @@ -73,11 +73,11 @@ init_net(uint8_t node_id) uint16_t shortaddr; uint64_t longaddr; linkaddr_t addr; -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 uip_ds6_addr_t *lladdr; uip_ipaddr_t ipaddr; #endif - + uint8_t i; memset(&shortaddr, 0, sizeof(shortaddr)); @@ -89,7 +89,7 @@ init_net(uint8_t node_id) for(i = 2; i < sizeof(longaddr); ++i) { ((uint8_t *)&longaddr)[i] = random_rand(); } - + PRINTF("SHORT MAC ADDRESS %02x:%02x\n", *((uint8_t *) & shortaddr), *((uint8_t *) & shortaddr + 1)); @@ -110,7 +110,7 @@ init_net(uint8_t node_id) } linkaddr_set_node_addr(&addr); - + PRINTF("Rime started with address: "); for(i = 0; i < sizeof(addr.u8) - 1; ++i) { PRINTF("%d.", addr.u8[i]); @@ -120,7 +120,7 @@ init_net(uint8_t node_id) queuebuf_init(); NETSTACK_RADIO.init(); - + mrf24j40_set_channel(RF_CHANNEL); mrf24j40_set_panid(IEEE802154_PANID); mrf24j40_set_short_mac_addr(shortaddr); @@ -135,7 +135,7 @@ init_net(uint8_t node_id) CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1 : NETSTACK_RDC.channel_check_interval()), RF_CHANNEL); -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 #if LINKADDR_CONF_SIZE == 2 memset(&uip_lladdr.addr, 0, sizeof(uip_lladdr.addr)); @@ -146,7 +146,9 @@ init_net(uint8_t node_id) memcpy(&uip_lladdr.addr, &longaddr, sizeof(uip_lladdr.addr)); #endif +#if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4 process_start(&tcpip_process, NULL); +#endif lladdr = uip_ds6_get_link_local(-1); diff --git a/platform/seedeye/init-net.h b/platform/seedeye/init-net.h index b217aa218..50dd8e450 100644 --- a/platform/seedeye/init-net.h +++ b/platform/seedeye/init-net.h @@ -7,7 +7,7 @@ * (http://www.cnit.it). * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -41,7 +41,7 @@ */ /** - * \file init-net.h + * \file platform/seedeye/init-net.h * \brief Network initialization for the SEEDEYE port. * \author Giovanni Pellerano * \date 2012-03-25 diff --git a/platform/seedeye/platform-conf.h b/platform/seedeye/platform-conf.h index c33d500b3..66d8ff46a 100644 --- a/platform/seedeye/platform-conf.h +++ b/platform/seedeye/platform-conf.h @@ -34,7 +34,7 @@ * */ /** - * \file platform-conf.h + * \file platform/seedeye/platform-conf.h * \brief Platform configuration file for the SEEDEYE port. * \author Giovanni Pellerano * \date 2012-06-06 diff --git a/platform/sensinode/Makefile.customrules-sensinode b/platform/sensinode/Makefile.customrules-sensinode deleted file mode 100644 index 13ec8cf5e..000000000 --- a/platform/sensinode/Makefile.customrules-sensinode +++ /dev/null @@ -1 +0,0 @@ -include $(CONTIKI)/cpu/cc2430/Makefile.customrules-cc2430 diff --git a/platform/sensinode/Makefile.sensinode b/platform/sensinode/Makefile.sensinode deleted file mode 100644 index 3cb297544..000000000 --- a/platform/sensinode/Makefile.sensinode +++ /dev/null @@ -1,91 +0,0 @@ -# Sensinode CC2430 platform makefile -# Supported products: N100, N600, N601, N710, N711 -# Support for N740 is experimental. - -# We support defines for product models using the following format -# e.g. MODEL_N601. Run make TARGET=sensinode DEFINES=MODEL_N601 to -# automatically configure the correct LED, button, UART etc. settings -# for that product model. If undefined, MODEL_N100 is chosen by default. -# Model settings are defined in /dev/models.h - -# make sensinode.upload - Will use nano_programmer to upload file using D2xx Devboard -# make sensinode.serialdump - Will use the Contiki serialdump tool on the default UART -# make foo.model - Will copy foo.ihx to foo-XYZ.ihx (e.g. foo-n740.ihx) -PATH:=$(CONTIKI)/platform/$(TARGET)/tools/bin:$(PATH) -export PATH - -ifndef CONTIKI - $(error CONTIKI not defined! You must specify where CONTIKI resides!) -endif - -# Determine our model and (later on) add it as part of the .ihx filename -# Handy when building for various models so we can easily tell which ihx -# is for what model. -# Defaults to N100 (which is what the contiki code does as well) -MODEL_SUFFIX=n100 -ifdef DEFINES - MODEL_SUFFIX=$(patsubst MODEL_N%,n%, \ - $(filter MODEL_%,$(subst $(COMMA), ,$(DEFINES)))) -endif - -# Define the default UART for tools and tool commands -DEFUART = /dev/ttyUSB0 -PROG = $(CONTIKI)/tools/sensinode/nano_programmer/nano_programmer -d $(DEFUART) -SERIALDUMP = $(CONTIKI)/tools/sky/serialdump-linux -b115200 $(DEFUART) - -CONTIKI_TARGET_DIRS = . dev -CONTIKI_TARGET_MAIN = $(addprefix $(OBJECTDIR)/,contiki-sensinode-main.rel) - -CONTIKI_TARGET_SOURCEFILES = contiki-sensinode-main.c -CONTIKI_TARGET_SOURCEFILES += leds.c leds-arch.c serial-line.c sensors.c -CONTIKI_TARGET_SOURCEFILES += sensinode-sensors.c button-sensor.c adc-sensor.c -CONTIKI_TARGET_SOURCEFILES += n740.c models.c m25p16.c slip-arch.c slip.c -CONTIKI_TARGET_SOURCEFILES += putchar.c debug.c - -CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) - -CLEAN += *.sensinode - -ifeq ($(UIP_CONF_IPV6),1) - ifeq ($(OFFSET_FIRMWARE),1) - CFLAGS += -DDISCO_ENABLED=1 - CONTIKI_TARGET_SOURCEFILES += disco.c - endif - CONTIKI_TARGET_SOURCEFILES += viztool.c -endif - -FORCE: - -# .sensinode target so we can behave similar to other targets -# Lastly, it will create a %-$(MODEL).ihx file -%.$(TARGET): %.hex FORCE - cp $< $(<:.hex=.$(TARGET)) - if [ -f $(<:.hex=.ihx) ] ; then \ - cp $(<:.hex=.ihx) $(<:.hex=-$(MODEL_SUFFIX).ihx); fi - @echo "\nReport" - @echo "===============" - @echo 'Code footprint:' - @echo 'Area Addr Size' \ - ' Decimal' - @echo '---------------------------------- -------- --------' \ - ' --------' - @echo -n 'HOME,CSEG,CONST,XINIT,GS* $(HOME_START) ' - @egrep ',CODE\)' $(<:.hex=.map) | egrep -v '(^BANK[1-9][^=])' | uniq | \ - awk '{ SUM += $$5 } END { printf "%08X = %8d", SUM, SUM }' - @echo '. bytes (REL,CON,CODE)' - @egrep '(^BANK[1-9][^=])' $(<:.hex=.map) | uniq | sort - @egrep -A 5 'Other memory' $(<:.hex=.mem) - -%.upload: %.hex - $(PROG) -P $< - -sensinode.serialdump: - $(SERIALDUMP) - -### Define the CPU directory -CONTIKI_CPU=$(CONTIKI)/cpu/cc2430 -include $(CONTIKI)/cpu/cc2430/Makefile.cc2430 - -contiki-$(TARGET).a:# $(addprefix $(OBJECTDIR)/,symbols.rel) - -MODULES += core/net/ipv6 core/net/ipv4 core/net/rime core/net core/net/mac core/net/rpl diff --git a/platform/sensinode/apps/batmon/Makefile.batmon b/platform/sensinode/apps/batmon/Makefile.batmon deleted file mode 100644 index 1ad4809da..000000000 --- a/platform/sensinode/apps/batmon/Makefile.batmon +++ /dev/null @@ -1,3 +0,0 @@ -batmon_src = batmon.c - -CFLAGS += -DBATMON_CONF_ON=1 \ No newline at end of file diff --git a/platform/sensinode/apps/batmon/batmon.c b/platform/sensinode/apps/batmon/batmon.c deleted file mode 100644 index 184404199..000000000 --- a/platform/sensinode/apps/batmon/batmon.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Sources for the BATtery MONitor app. It dumps a log entry to the - * external flash periodically as well as upon external trigger. - * - * It started off as a VDD and battery logger but now it also stores - * energest values and other goodies. - * - * \author - * George Oikonomou - - */ - -#include "contiki.h" - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif - -#include "sys/etimer.h" -#include "sys/energest.h" -#include "dev/sensinode-sensors.h" -#include "dev/n740.h" -#include "dev/m25p16.h" - -#define BATMON_LOG_PERIOD 60 /* in seconds */ -/*---------------------------------------------------------------------------*/ -static const uint8_t magic[3] = { 0x0B, 0xEE, 0xF0 }; -/*---------------------------------------------------------------------------*/ -struct record { - uint8_t magic[3]; - uint8_t trigger; - unsigned long c; /* uptime */ - int v; /* VDD (reference) */ - int b; /* Voltage ADC */ -#if ENERGEST_CONF_ON - unsigned long mcu; - unsigned long lpm; - unsigned long irq; - unsigned long tx; - unsigned long rx; - unsigned long f_write; - unsigned long f_read; -#endif -}; - -#define RECORD_SIZE 64 -#define LAST_WRITE (0xFFFF - RECORD_SIZE) - -#define LOG_TRIGGER_PERIODIC 0xFF -/*---------------------------------------------------------------------------*/ -struct flash_address { - uint8_t s; /* sector */ - uint8_t p; /* page */ - uint8_t a; /* address */ -}; -static struct flash_address f; - -static struct record r; -static struct sensors_sensor *s; -static struct etimer et; -#define FLASH_START_ADDR 0x1E0000 -#define FLASH_END_ADDR 0x1FFFFF -/*---------------------------------------------------------------------------*/ -PROCESS(batmon_process, "Logger Process"); -/*---------------------------------------------------------------------------*/ -static int -find_gap() CC_NON_BANKED -{ - uint8_t seq[3]; - uint32_t address = FLASH_START_ADDR; - memset(&f, 0, sizeof(f)); - - for(address = FLASH_START_ADDR; address <= FLASH_END_ADDR; address += - RECORD_SIZE) { - n740_analog_deactivate(); - f.s = ((address & 0xFF0000) >> 16); - f.p = ((address & 0xFF00) >> 8); - f.a = address & 0xFF; - m25p16_read_fast((uint8_t *)&f, seq, sizeof(magic)); - n740_analog_activate(); - if(memcmp(seq, magic, sizeof(magic)) != 0) { - PRINTF("BatMon: Resume write @ 0x%02x%02x%02x\n", f.s, f.p, f.a); - return 1; - } - } - - /* If we reach here, we ran out of flash */ - return -1; -} -/*---------------------------------------------------------------------------*/ -static void -abort() CC_NON_BANKED -{ - PRINTF("BatMon: Abort\n"); - etimer_stop(&et); - process_exit(&batmon_process); -} -/*---------------------------------------------------------------------------*/ -void -batmon_log(uint8_t trigger) -{ - uint32_t next; - - /* Only continue if the process (us) is running */ - if(!process_is_running(&batmon_process)) { - return; - } - - next = f.a; - next |= (((uint32_t) f.p) << 8); - next |= (((uint32_t) f.s) << 16); - - memcpy(r.magic, magic, sizeof(magic)); - r.trigger = trigger; - r.c = clock_seconds(); - - /* Read VDD and use as ADC reference */ - r.v = s->value(ADC_SENSOR_TYPE_VDD); - - /* And then carry on with battery */ - r.b = s->value(ADC_SENSOR_TYPE_BATTERY); - -#if ENERGEST_CONF_ON - /* ENERGEST values */ - r.mcu = energest_type_time(ENERGEST_TYPE_CPU); - r.lpm = energest_type_time(ENERGEST_TYPE_LPM); - r.irq = energest_type_time(ENERGEST_TYPE_IRQ); - r.tx = energest_type_time(ENERGEST_TYPE_TRANSMIT); - r.rx = energest_type_time(ENERGEST_TYPE_LISTEN); - r.f_write = energest_type_time(ENERGEST_TYPE_FLASH_WRITE); - r.f_read = energest_type_time(ENERGEST_TYPE_FLASH_READ); -#endif - - n740_analog_deactivate(); - /* Make sure we're on */ - if(M25P16_WIP()) { - m25p16_res(); - } - m25p16_pp((uint8_t *)&f, (uint8_t *)&r, sizeof(r)); - n740_analog_activate(); - - PRINTF("BatMon: @%lu [%u] ", r.c, r.trigger); - PRINTF("BatMon: 0x%02x%02x%02x\n", f.s, f.p, f.a); - - next += RECORD_SIZE; - - if(next >= FLASH_END_ADDR) { - abort(); - return; - } - - f.s = ((next & 0xFF0000) >> 16); - f.p = ((next & 0xFF00) >> 8); - f.a = next & 0xFF; - - if(trigger == LOG_TRIGGER_PERIODIC) { - etimer_reset(&et); - } -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(batmon_process, ev, data) -{ - - PROCESS_BEGIN(); - - PRINTF("BatMon\n", sizeof(r)); - - s = sensors_find(ADC_SENSOR); - if(!s) { - PRINTF("BatMon: ADC not found\n"); - PROCESS_EXIT(); - } - - n740_analog_deactivate(); - m25p16_res(); - n740_analog_activate(); - - /* Find last written location */ - if(find_gap() == -1) { - PRINTF("BatMon: Flash storage full\n"); - PROCESS_EXIT(); - } - - etimer_set(&et, BATMON_LOG_PERIOD * CLOCK_SECOND); - - while(1) { - PROCESS_YIELD(); - if(ev == PROCESS_EVENT_TIMER && etimer_expired(&et)) { - batmon_log(LOG_TRIGGER_PERIODIC); - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sensinode/contiki-conf.h b/platform/sensinode/contiki-conf.h deleted file mode 100644 index 08543ad6b..000000000 --- a/platform/sensinode/contiki-conf.h +++ /dev/null @@ -1,286 +0,0 @@ -#ifndef CONTIKI_CONF_H_ -#define CONTIKI_CONF_H_ - -#include "8051def.h" -#include "sys/cc.h" -#include - -/* Include Project Specific conf */ -#ifdef PROJECT_CONF_H -#include "project-conf.h" -#endif /* PROJECT_CONF_H */ - -/* - * Define this as 1 to poll the etimer process from within main instead of from - * the clock ISR. This reduces the ISR's stack usage and may prevent crashes. - */ -#ifndef CLOCK_CONF_STACK_FRIENDLY -#define CLOCK_CONF_STACK_FRIENDLY 1 -#endif - -/* Memory filesystem RAM size. */ -#define CFS_RAM_CONF_SIZE 512 - -/* Logging.. */ -#define LOG_CONF_ENABLED 0 - -#ifndef STACK_CONF_DEBUGGING -#define STACK_CONF_DEBUGGING 0 -#endif - -/* Energest Module */ -#ifndef ENERGEST_CONF_ON -#define ENERGEST_CONF_ON 0 -#endif - -/* Verbose Startup? Turning this off reduces our footprint a fair bit */ -#define STARTUP_CONF_VERBOSE 0 - -/* More CODE space savings by turning off process names */ -#define PROCESS_CONF_NO_PROCESS_NAMES 1 - -/* - * UARTs: 1=>Enabled, 0=>Disabled. Default: Both Disabled (see uart.h) - * Disabling UARTs reduces our CODE footprint - * Disabling UART1 also disables all debugging output. - * Should be used when nodes are meant to run on batteries - * - * On N740, by enabling UART1, you are also enabling an ugly hack which aims - * to detect the USB connection during execution. It will then turn on/off - * UART1 RX interrupts accordingly. This seems to work but you have been warned - * If you start seeing random crashes when on battery, this is where to look. - */ -#ifndef UART_ONE_CONF_ENABLE -#define UART_ONE_CONF_ENABLE 1 -#endif -#ifndef UART_ONE_CONF_WITH_INPUT -#define UART_ONE_CONF_WITH_INPUT 0 -#endif -#define UART_ZERO_CONF_ENABLE 0 - -#ifndef UART_ONE_CONF_HIGH_SPEED -#define UART_ONE_CONF_HIGH_SPEED 0 -#endif - -#define SLIP_RADIO_CONF_NO_PUTCHAR 1 - -#if defined (UIP_FALLBACK_INTERFACE) || defined (CMD_CONF_OUTPUT) -#define SLIP_ARCH_CONF_ENABLE 1 -#endif - -/* Are we a SLIP bridge? */ -#if SLIP_ARCH_CONF_ENABLE -/* Make sure UART1 is enabled, with interrupts */ -#undef UART_ONE_CONF_ENABLE -#undef UART_ONE_CONF_WITH_INPUT -#define UART_ONE_CONF_ENABLE 1 -#define UART_ONE_CONF_WITH_INPUT 1 -#endif - -/* Output all captured frames over the UART in hexdump format */ -#ifndef CC2430_RF_CONF_HEXDUMP -#define CC2430_RF_CONF_HEXDUMP 0 -#endif - -#if CC2430_RF_CONF_HEXDUMP -/* We need UART1 output */ -#undef UART_ONE_CONF_ENABLE -#define UART_ONE_CONF_ENABLE 1 -#endif - -/* Code Shortcuts */ -/* - * When set, the RF driver is no longer a contiki process and the RX ISR is - * disabled. Instead of polling the radio process when data arrives, we - * periodically check for data by directly invoking the driver from main() - * - * When set, this directive also configures the following bypasses: - * - process_post_synch() in tcpip_input() (we call packet_input()) - * - process_post_synch() in tcpip_uipcall (we call the relevant pthread) - * - mac_call_sent_callback() is replaced with sent() in various places - * - * These are good things to do, they reduce stack usage and prevent crashes - */ -#define NETSTACK_CONF_SHORTCUTS 1 - -/* - * Sensors - * It is harmless to #define XYZ 1 - * even if the sensor is not present on our device - */ -#ifndef BUTTON_SENSOR_CONF_ON -#define BUTTON_SENSOR_CONF_ON 1 /* Buttons */ -#endif -/* ADC - Turning this off will disable everything below */ -#ifndef ADC_SENSOR_CONF_ON -#define ADC_SENSOR_CONF_ON 1 -#endif -#define TEMP_SENSOR_CONF_ON 1 /* Temperature */ -#define BATTERY_SENSOR_CONF_ON 1 /* Battery */ -#define VDD_SENSOR_CONF_ON 1 /* Supply Voltage */ -#define ACC_SENSOR_CONF_ON 1 /* Accelerometer */ -#define ACC_SENSOR_CONF_GSEL 0 /* Acc. g-Select => 1: +/-11g, 0: +/-3g */ -#define LIGHT_SENSOR_CONF_ON 1 /* Light */ - -/* Watchdog */ -#define WDT_CONF_INTERVAL 0 -#define WDT_CONF_TIMER_MODE 0 /* 0 or undefined for watchdog mode */ - -/* Low Power Modes - We only support PM0/Idle and PM1 */ -#ifndef LPM_CONF_MODE -#define LPM_CONF_MODE 1 /* 0: no LPM, 1: MCU IDLE, 2: Drop to PM1 */ -#endif - -/* DMA Configuration */ -#ifndef DMA_CONF_ON -#define DMA_CONF_ON 0 -#endif - -/* N740 Serial Flash */ -#ifndef M25P16_CONF_ON -#define M25P16_CONF_ON 1 -#endif - -/* XXX argh, ugly hack to make stuff compile! */ -#define snprintf(BUF, SIZE, ...) sprintf(BUF, __VA_ARGS__) - -/* Sensinode-Specific Tools and APPs */ -/* Viztool on by default for IPv6 builds */ -#if UIP_CONF_IPV6 -#ifndef VIZTOOL_CONF_ON -#define VIZTOOL_CONF_ON 1 -#endif /* VIZTOOL_CONF_ON */ -#endif /* UIP_CONF_IPV6 */ - -/* BatMon off by default unless we build with APPS += batmon */ -#ifndef BATMON_CONF_ON -#define BATMON_CONF_ON 0 -#endif - -/* Network Stack */ -#ifndef NETSTACK_CONF_NETWORK -#if UIP_CONF_IPV6 -#define NETSTACK_CONF_NETWORK sicslowpan_driver -#else -#define NETSTACK_CONF_NETWORK rime_driver -#endif /* UIP_CONF_IPV6 */ -#endif /* NETSTACK_CONF_NETWORK */ - -#ifndef NETSTACK_CONF_MAC -#define NETSTACK_CONF_MAC csma_driver -#endif - -#ifndef NETSTACK_CONF_RDC -#define NETSTACK_CONF_RDC nullrdc_driver -#define NULLRDC_802154_AUTOACK 1 -#define NULLRDC_802154_AUTOACK_HW 1 -#endif - -#ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE -#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 -#endif - -#ifndef NETSTACK_CONF_FRAMER -#define NETSTACK_CONF_FRAMER framer_802154 -#endif - -#define NETSTACK_CONF_RADIO cc2430_rf_driver - -/* RF Config */ -#define IEEE802154_CONF_PANID 0x4C55 /* LU */ - -#ifndef CC2430_RF_CONF_CHANNEL -#define CC2430_RF_CONF_CHANNEL 25 -#endif /* CC2430_RF_CONF_CHANNEL */ - -#ifndef CC2430_RF_CONF_TX_POWER -#define CC2430_RF_CONF_TX_POWER 0x5F /* Datasheet recommended value */ -#endif - -#ifndef CC2430_RF_CONF_AUTOACK -#define CC2430_RF_CONF_AUTOACK 1 -#endif /* CC2430_CONF_AUTOACK */ - -#if UIP_CONF_IPV6 -/* Addresses, Sizes and Interfaces */ -/* 8-byte addresses here, 2 otherwise */ -#define LINKADDR_CONF_SIZE 8 -#define UIP_CONF_LL_802154 1 -#define UIP_CONF_LLH_LEN 0 -#define UIP_CONF_NETIF_MAX_ADDRESSES 3 - -/* TCP, UDP, ICMP */ -#define UIP_CONF_TCP 0 -#define UIP_CONF_UDP 1 -#define UIP_CONF_UDP_CHECKSUMS 1 - -/* ND and Routing */ -#ifndef UIP_CONF_ROUTER -#define UIP_CONF_ROUTER 1 -#endif - -#define UIP_CONF_ND6_SEND_RA 0 -#define UIP_CONF_IP_FORWARD 0 -#define RPL_CONF_STATS 0 -#define RPL_CONF_MAX_DAG_ENTRIES 1 -#ifndef RPL_CONF_OF -#define RPL_CONF_OF rpl_mrhof -#endif - -#define UIP_CONF_ND6_REACHABLE_TIME 600000 -#define UIP_CONF_ND6_RETRANS_TIMER 10000 - -#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS -#define NBR_TABLE_CONF_MAX_NEIGHBORS 4 /* Handle n Neighbors */ -#endif -#ifndef UIP_CONF_MAX_ROUTES -#define UIP_CONF_MAX_ROUTES 4 /* Handle n Routes */ -#endif - -/* uIP */ -#ifndef UIP_CONF_BUFFER_SIZE -#define UIP_CONF_BUFFER_SIZE 240 -#endif -#define UIP_CONF_IPV6_QUEUE_PKT 0 -#define UIP_CONF_IPV6_CHECKS 1 -#define UIP_CONF_IPV6_REASSEMBLY 0 - -/* 6lowpan */ -#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 -#ifndef SICSLOWPAN_CONF_FRAG -#define SICSLOWPAN_CONF_FRAG 0 /* About 2KB of CODE if 1 */ -#endif -#define SICSLOWPAN_CONF_MAXAGE 8 - -/* Define our IPv6 prefixes/contexts here */ -#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 -#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 { \ - addr_contexts[0].prefix[0] = 0x20; \ - addr_contexts[0].prefix[1] = 0x01; \ - addr_contexts[0].prefix[2] = 0x06; \ - addr_contexts[0].prefix[3] = 0x30; \ - addr_contexts[0].prefix[4] = 0x03; \ - addr_contexts[0].prefix[5] = 0x01; \ - addr_contexts[0].prefix[6] = 0x64; \ - addr_contexts[0].prefix[7] = 0x53; \ -} - -#define MAC_CONF_CHANNEL_CHECK_RATE 8 -#ifndef QUEUEBUF_CONF_NUM -#define QUEUEBUF_CONF_NUM 6 -#endif - -#else /* UIP_CONF_IPV6 */ -/* Network setup for non-IPv6 (rime). */ -#define UIP_CONF_IP_FORWARD 1 -#define UIP_CONF_BUFFER_SIZE 108 -#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 -#define QUEUEBUF_CONF_NUM 8 -#endif /* UIP_CONF_IPV6 */ - -/* Prevent SDCC compile error when UIP_CONF_ROUTER == 0 */ -#if !UIP_CONF_ROUTER -#define UIP_CONF_DS6_AADDR_NBU 1 -#endif - -#endif /* CONTIKI_CONF_H_ */ diff --git a/platform/sensinode/contiki-sensinode-main.c b/platform/sensinode/contiki-sensinode-main.c deleted file mode 100644 index 74d6eb46f..000000000 --- a/platform/sensinode/contiki-sensinode-main.c +++ /dev/null @@ -1,384 +0,0 @@ -#include "contiki.h" -#include "sys/clock.h" -#include "sys/autostart.h" - -#include "dev/serial-line.h" -#include "dev/slip.h" -#include "dev/bus.h" -#include "dev/leds.h" -#include "dev/uart1.h" -#include "dev/dma.h" -#include "dev/models.h" -#include "dev/cc2430_rf.h" -#include "dev/watchdog.h" -#include "dev/lpm.h" -#include "net/rime/rime.h" -#include "net/netstack.h" -#include "net/mac/frame802154.h" -#include "debug.h" -#include "stack.h" -#include "dev/watchdog-cc2430.h" -#include "dev/sensinode-sensors.h" -#include "disco.h" -#include "contiki-lib.h" -#include "contiki-net.h" - -unsigned short node_id = 0; /* Manually sets MAC address when > 0 */ - -#if VIZTOOL_CONF_ON -PROCESS_NAME(viztool_process); -#endif - -#if BATMON_CONF_ON -PROCESS_NAME(batmon_process); -#endif - -#if NETSTACK_CONF_SHORTCUTS -static CC_AT_DATA uint16_t len; -#endif - -#ifdef STARTUP_CONF_VERBOSE -#define STARTUP_VERBOSE STARTUP_CONF_VERBOSE -#else -#define STARTUP_VERBOSE 0 -#endif - -#if STARTUP_VERBOSE -#define PUTSTRING(...) putstring(__VA_ARGS__) -#define PUTHEX(...) puthex(__VA_ARGS__) -#define PUTBIN(...) putbin(__VA_ARGS__) -#define PUTCHAR(...) putchar(__VA_ARGS__) -#else -#define PUTSTRING(...) do {} while(0) -#define PUTHEX(...) do {} while(0) -#define PUTBIN(...) do {} while(0) -#define PUTCHAR(...) do {} while(0) -#endif - -#if CLOCK_CONF_STACK_FRIENDLY -extern volatile uint8_t sleep_flag; -#endif - -extern linkaddr_t linkaddr_node_addr; -#if ENERGEST_CONF_ON -static unsigned long irq_energest = 0; -#define ENERGEST_IRQ_SAVE(a) do { \ - a = energest_type_time(ENERGEST_TYPE_IRQ); } while(0) -#define ENERGEST_IRQ_RESTORE(a) do { \ - energest_type_set(ENERGEST_TYPE_IRQ, a); } while(0) -#else -#define ENERGEST_IRQ_SAVE(a) do {} while(0) -#define ENERGEST_IRQ_RESTORE(a) do {} while(0) -#endif -/*---------------------------------------------------------------------------*/ -static void -fade(int l) CC_NON_BANKED -{ - volatile int i, a; - int k, j; - for(k = 0; k < 400; ++k) { - j = k > 200 ? 400 - k : k; - - leds_on(l); - for(i = 0; i < j; ++i) { - a = i; - } - leds_off(l); - for(i = 0; i < 200 - j; ++i) { - a = i; - } - } -} -/*---------------------------------------------------------------------------*/ -static void -set_rime_addr(void) CC_NON_BANKED -{ - uint8_t *addr_long = NULL; - uint16_t addr_short = 0; - char i; - __code unsigned char *macp; - - PUTSTRING("Rime is 0x"); - PUTHEX(sizeof(linkaddr_t)); - PUTSTRING(" bytes long\n"); - - if(node_id == 0) { - PUTSTRING("Reading MAC from flash\n"); - /* - * The MAC is always stored in 0x1FFF8 of our flash. This maps to address - * 0xFFF8 of our CODE segment, when BANK3 is selected. - * Switch to BANK3, read 8 bytes starting at 0xFFF8 and restore last BANK - * Since we are called from main(), this MUST be BANK1 or something is very - * wrong. This code can be used even without banking - */ - - /* Don't interrupt us to make sure no BANK switching happens while working */ - DISABLE_INTERRUPTS(); - - /* Switch to BANK3, map CODE: 0x8000 - 0xFFFF to FLASH: 0x18000 - 0x1FFFF */ - FMAP = 3; - - /* Set our pointer to the correct address and fetch 8 bytes of MAC */ - macp = (__code unsigned char *)0xFFF8; - - for(i = (LINKADDR_SIZE - 1); i >= 0; --i) { - linkaddr_node_addr.u8[i] = *macp; - macp++; - } - - /* Remap 0x8000 - 0xFFFF to BANK1 */ - FMAP = 1; - ENABLE_INTERRUPTS(); - - } else { - PUTSTRING("Setting manual address from node_id\n"); - linkaddr_node_addr.u8[LINKADDR_SIZE - 1] = node_id >> 8; - linkaddr_node_addr.u8[LINKADDR_SIZE - 2] = node_id & 0xff; - } - - /* Now the address is stored MSB first */ -#if STARTUP_VERBOSE - PUTSTRING("Rime configured with address "); - for(i = 0; i < LINKADDR_SIZE - 1; i++) { - PUTHEX(linkaddr_node_addr.u8[i]); - PUTCHAR(':'); - } - PUTHEX(linkaddr_node_addr.u8[i]); - PUTCHAR('\n'); -#endif - - /* Set the cc2430 RF addresses */ -#if (LINKADDR_SIZE==8) - addr_short = (linkaddr_node_addr.u8[6] * 256) + linkaddr_node_addr.u8[7]; - addr_long = (uint8_t *) &linkaddr_node_addr; -#else - addr_short = (linkaddr_node_addr.u8[0] * 256) + linkaddr_node_addr.u8[1]; -#endif - cc2430_rf_set_addr(IEEE802154_PANID, addr_short, addr_long); -} -/*---------------------------------------------------------------------------*/ -int -main(void) -{ - - /* Hardware initialization */ - bus_init(); - rtimer_init(); - - stack_poison(); - - /* model-specific h/w init. */ - model_init(); - - /* Init LEDs here */ - leds_init(); - fade(LEDS_GREEN); - - /* initialize process manager. */ - process_init(); - - /* Init UART1 */ - uart1_init(); - -#if DMA_ON - dma_init(); -#endif - -#if SLIP_ARCH_CONF_ENABLE - /* On cc2430, the argument is not used */ - slip_arch_init(0); -#else - uart1_set_input(serial_line_input_byte); - serial_line_init(); -#endif - - PUTSTRING("##########################################\n"); - putstring(CONTIKI_VERSION_STRING "\n"); - putstring(SENSINODE_MODEL " (CC24"); - puthex(((CHIPID >> 3) | 0x20)); - putstring("-" FLASH_SIZE ")\n"); - -#if STARTUP_VERBOSE -#ifdef HAVE_SDCC_BANKING - PUTSTRING(" With Banking.\n"); -#endif /* HAVE_SDCC_BANKING */ -#ifdef SDCC_MODEL_LARGE - PUTSTRING(" --model-large\n"); -#endif /* SDCC_MODEL_LARGE */ -#ifdef SDCC_MODEL_HUGE - PUTSTRING(" --model-huge\n"); -#endif /* SDCC_MODEL_HUGE */ -#ifdef SDCC_STACK_AUTO - PUTSTRING(" --stack-auto\n"); -#endif /* SDCC_STACK_AUTO */ - - PUTCHAR('\n'); - - PUTSTRING(" Net: "); - PUTSTRING(NETSTACK_NETWORK.name); - PUTCHAR('\n'); - PUTSTRING(" MAC: "); - PUTSTRING(NETSTACK_MAC.name); - PUTCHAR('\n'); - PUTSTRING(" RDC: "); - PUTSTRING(NETSTACK_RDC.name); - PUTCHAR('\n'); - - PUTSTRING("##########################################\n"); -#endif - - watchdog_init(); - - /* Initialise the cc2430 RNG engine. */ - random_init(0); - - /* start services */ - process_start(&etimer_process, NULL); - ctimer_init(); - - /* initialize the netstack */ - netstack_init(); - set_rime_addr(); - -#if BUTTON_SENSOR_ON || ADC_SENSOR_ON - process_start(&sensors_process, NULL); - sensinode_sensors_activate(); -#endif - -#if UIP_CONF_IPV6 - memcpy(&uip_lladdr.addr, &linkaddr_node_addr, sizeof(uip_lladdr.addr)); - queuebuf_init(); - process_start(&tcpip_process, NULL); - -#if DISCO_ENABLED - process_start(&disco_process, NULL); -#endif /* DISCO_ENABLED */ - -#if VIZTOOL_CONF_ON - process_start(&viztool_process, NULL); -#endif - -#if (!UIP_CONF_IPV6_RPL) - { - uip_ipaddr_t ipaddr; - - uip_ip6addr(&ipaddr, 0x2001, 0x630, 0x301, 0x6453, 0, 0, 0, 0); - uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); - uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE); - } -#endif /* UIP_CONF_IPV6_RPL */ -#endif /* UIP_CONF_IPV6 */ - - /* - * Acknowledge the UART1 RX interrupt - * now that we're sure we are ready to process it - */ - model_uart_intr_en(); - - energest_init(); - ENERGEST_ON(ENERGEST_TYPE_CPU); - - fade(LEDS_RED); - -#if BATMON_CONF_ON - process_start(&batmon_process, NULL); -#endif - - autostart_start(autostart_processes); - - watchdog_start(); - - while(1) { - uint8_t r; - do { - /* Reset watchdog and handle polls and events */ - watchdog_periodic(); - -#if CLOCK_CONF_STACK_FRIENDLY - if(sleep_flag) { - if(etimer_pending() && - (etimer_next_expiration_time() - clock_time() - 1) > MAX_TICKS) { - etimer_request_poll(); - } - sleep_flag = 0; - } -#endif - r = process_run(); - } while(r > 0); -#if NETSTACK_CONF_SHORTCUTS - len = NETSTACK_RADIO.pending_packet(); - if(len) { - packetbuf_clear(); - len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE); - if(len > 0) { - packetbuf_set_datalen(len); - NETSTACK_RDC.input(); - } - } -#endif - -#if LPM_MODE -#if (LPM_MODE==LPM_MODE_PM2) - SLEEP &= ~OSC_PD; /* Make sure both HS OSCs are on */ - while(!(SLEEP & HFRC_STB)); /* Wait for RCOSC to be stable */ - CLKCON |= OSC; /* Switch to the RCOSC */ - while(!(CLKCON & OSC)); /* Wait till it's happened */ - SLEEP |= OSC_PD; /* Turn the other one off */ -#endif /* LPM_MODE==LPM_MODE_PM2 */ - - /* - * Set MCU IDLE or Drop to PM1. Any interrupt will take us out of LPM - * Sleep Timer will wake us up in no more than 7.8ms (max idle interval) - */ - SLEEP = (SLEEP & 0xFC) | (LPM_MODE - 1); - -#if (LPM_MODE==LPM_MODE_PM2) - /* - * Wait 3 NOPs. Either an interrupt occurred and SLEEP.MODE was cleared or - * no interrupt occurred and we can safely power down - */ - __asm - nop - nop - nop - __endasm; - - if(SLEEP & SLEEP_MODE0) { -#endif /* LPM_MODE==LPM_MODE_PM2 */ - - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); - - /* We are only interested in IRQ energest while idle or in LPM */ - ENERGEST_IRQ_RESTORE(irq_energest); - - /* Go IDLE or Enter PM1 */ - PCON |= IDLE; - - /* First instruction upon exiting PM1 must be a NOP */ - __asm - nop - __endasm; - - /* Remember energest IRQ for next pass */ - ENERGEST_IRQ_SAVE(irq_energest); - - ENERGEST_ON(ENERGEST_TYPE_CPU); - ENERGEST_OFF(ENERGEST_TYPE_LPM); - -#if (LPM_MODE==LPM_MODE_PM2) - SLEEP &= ~OSC_PD; /* Make sure both HS OSCs are on */ - while(!(SLEEP & XOSC_STB)); /* Wait for XOSC to be stable */ - CLKCON &= ~OSC; /* Switch to the XOSC */ - /* - * On occasion the XOSC is reported stable when in reality it's not. - * We need to wait for a safeguard of 64us or more before selecting it - */ - clock_delay_usec(65); - while(CLKCON & OSC); /* Wait till it's happened */ - } -#endif /* LPM_MODE==LPM_MODE_PM2 */ -#endif /* LPM_MODE */ - } -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sensinode/debug.c b/platform/sensinode/debug.c deleted file mode 100644 index f2fcb9498..000000000 --- a/platform/sensinode/debug.c +++ /dev/null @@ -1,61 +0,0 @@ -/** - * \file - * - * Definition of some debugging functions for the sensinode port. - * - * This file is bankable. - * - * putstring() and puthex() are from msp430/watchdog.c - * - * \author - * George Oikonomou - - */ - -#include "cc2430_sfr.h" -#include "8051def.h" -#include "debug.h" - -static const char hexconv[] = "0123456789abcdef"; -static const char binconv[] = "01"; - -/*---------------------------------------------------------------------------*/ -void -putstring(char *s) -{ - while(*s) { - putchar(*s++); - } -} -/*---------------------------------------------------------------------------*/ -void -puthex(uint8_t c) -{ - putchar(hexconv[c >> 4]); - putchar(hexconv[c & 0x0f]); -} -/*---------------------------------------------------------------------------*/ -void -putbin(uint8_t c) -{ - unsigned char i = 0x80; - while(i) { - putchar(binconv[(c & i) != 0]); - i >>= 1; - } -} -/*---------------------------------------------------------------------------*/ -void -putdec(uint8_t c) -{ - uint8_t div; - uint8_t hassent = 0; - for(div = 100; div > 0; div /= 10) { - uint8_t disp = c / div; - c %= div; - if((disp != 0) || (hassent) || (div == 1)) { - hassent = 1; - putchar('0' + disp); - } - } -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sensinode/dev/adc-sensor.c b/platform/sensinode/dev/adc-sensor.c deleted file mode 100644 index c039adafa..000000000 --- a/platform/sensinode/dev/adc-sensor.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ADC sensor module for sensinode devices. - * - * This file respects configuration in contiki-conf.h. It also turns - * off features which are not present in the model that we are - * building for. - * - * \author - * George Oikonomou - - */ -#include "dev/sensinode-sensors.h" - -#if ADC_SENSOR_ON -SENSORS_SENSOR(adc_sensor, ADC_SENSOR, value, configure, status); - -static uint8_t ready; - -/*---------------------------------------------------------------------------*/ -static int -value(int type) -{ - uint16_t reading; - /* - * For single-shot AD conversions, we may only write to ADCCON3[3:0] once - * (This write triggers the conversion). We thus use the variable 'command' - * to store intermediate steps (reference, decimation rate, input channel) - */ - uint8_t command; - - ADCCFG = 0; /* Enables/Disables Input Channel */ - - /* 1.25V ref, max decimation rate */ - command = ADEDIV1 | ADEDIV0; - - /* Clear the Interrupt Flag */ - TCON_ADCIF = 0; - - /* Depending on the desired reading, append the input bits to 'command' and - * enable the corresponding input channel in ADCCFG if necessary */ - switch(type) { -#if TEMP_SENSOR_ON - case ADC_SENSOR_TYPE_TEMP: - command |= ADECH3 | ADECH2 | ADECH1; - break; -#endif -#if ACC_SENSOR_ON - case ADC_SENSOR_TYPE_ACC_X: - ADCCFG = ADC5EN; - command |= ADECH2 | ADECH0; - break; - case ADC_SENSOR_TYPE_ACC_Y: - ADCCFG = ADC6EN; - command |= ADECH2 | ADECH1; - break; - case ADC_SENSOR_TYPE_ACC_Z: - ADCCFG = ADC7EN; - command |= ADECH2 | ADECH1 | ADECH0; - break; -#endif -#if VDD_SENSOR_ON - case ADC_SENSOR_TYPE_VDD: - command |= ADECH3 | ADECH2 | ADECH1 | ADECH0; - break; -#endif -#if LIGHT_SENSOR_ON - case ADC_SENSOR_TYPE_LIGHT: - ADCCFG = ADC0EN; - break; -#endif -#if BATTERY_SENSOR_ON - case ADC_SENSOR_TYPE_BATTERY: - ADCCFG = ADC1EN; - command |= ADECH0 | ADEREF1; /* AVDD_SOC reference */ - break; -#endif - default: - /* If the sensor is not present or disabled in conf, return -1 */ - return -1; - } - - /* Writing in bits 3:0 of ADCCON3 will trigger a single conversion */ - ADCCON3 = command; - - /* - * When the conversion is complete, the ADC interrupt flag is set. We don't - * use an ISR here, we just wait on the flag and clear it afterwards. - */ - while(!TCON_ADCIF); - - /* Clear the Interrupt Flag */ - TCON_ADCIF = 0; - - reading = 0; - reading = ADCL; - reading |= (((uint8_t) ADCH) << 8); - /* 12-bit decimation rate: 4 LS bits are noise */ - reading >>= 4; - - return reading; -} -/*---------------------------------------------------------------------------*/ -static int -status(int type) -{ - return ready; -} -/*---------------------------------------------------------------------------*/ -/* - * On N740 we can control Ill and Acc individually: - * ADC_VAL_OTHERS 0x01 - * ADC_VAL_LIGHT_ON 0x04 - * ADC_VAL_ACC_ON 0x08 - * ADC_VAL_ACC_GSEL 0x10 - * - * Return Value is always light | acc | acc_gsel - * - * SENSORS_ACTIVE: - * - 1: Activate everything, use default setting for ACC G-select - * - 0: Turn everything off - * - xyz: Mask with the defines above and act accordingly. - * - * SENSORS_READY: - * - Return Status (0: all off or a value based on the defines above) - */ -static int -configure(int type, int value) -{ -#ifdef MODEL_N740 - /* - * Read current state of the ser-par, ignoring current sensor settings - * Those will be set all over depending on VALUE - */ - uint8_t ser_par_val = n740_ser_par_get() & 0xF2; -#endif /* MODEL_N740 */ - - /* 'Others' are either compiled in or not. Can't be turned on/off */ - ready = ADC_VAL_ALL; - - switch(type) { - case SENSORS_HW_INIT: - case SENSORS_ACTIVE: -#ifdef MODEL_N740 - if(value == ADC_VAL_ALL) { - value = ADC_VAL_ACC_ON | ADC_VAL_LIGHT_ON; -#if ACC_SENSOR_GSEL - value |= ADC_VAL_ACC_GSEL; -#endif /* ACC_SENSOR_GSEL */ - } -#endif /* MODEL_N740 */ - - /* OK, Now value definitely specifies our bits, start masking - * We will refuse to turn things on if they are specified OFF in conf. */ -#ifdef MODEL_N740 -#if ACC_SENSOR_ON - if(value & ADC_VAL_ACC_ON) { - P0SEL |= 0x80 | 0x40 | 0x20; - ser_par_val |= N740_SER_PAR_ACC; - ready |= ADC_VAL_ACC_ON; -#if ACC_SENSOR_GSEL - if(value & ADC_VAL_ACC_GSEL) { - ser_par_val |= N740_SER_PAR_ACC_GSEL; - ready |= ADC_VAL_ACC_GSEL; - } -#endif /*ACC_SENSOR_GSEL */ - } -#endif /* ACC_SENSOR_ON */ - -#if LIGHT_SENSOR_ON - if(value & ADC_VAL_LIGHT_ON) { - ser_par_val |= N740_SER_PAR_LIGHT; - ready |= ADC_VAL_LIGHT_ON; - } -#endif /* LIGHT_SENSOR_ON */ - n740_ser_par_set(ser_par_val); -#endif /* MODEL_N740 */ - } - return ready; -} - -#endif /* ADC_SENSOR_ON */ diff --git a/platform/sensinode/dev/button-sensor.c b/platform/sensinode/dev/button-sensor.c deleted file mode 100644 index 7b9c82ab4..000000000 --- a/platform/sensinode/dev/button-sensor.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/* - * Portions of this file build on button-sensor.c in platforms sky and esb - * This file contains ISRs: Keep it in the HOME bank. - */ - -#include "dev/models.h" -#include "lib/sensors.h" -#include "dev/hwconf.h" -#include "dev/sensinode-sensors.h" - -#if BUTTON_SENSOR_ON -static uint8_t p0ien; -static uint8_t p2ien; -static CC_AT_DATA struct timer debouncetimer[2]; - -#ifdef MODEL_N740 -HWCONF_PIN(BUTTON_1, 1, 0) -HWCONF_PORT_1_IRQ(BUTTON_1, 0) -HWCONF_PIN(BUTTON_2, 0, 4) -HWCONF_PORT_0_IRQ(BUTTON_2, 4) -#endif /* MODEL_N740 */ - -#ifdef MODEL_N711 -HWCONF_PIN(BUTTON_1, 0, 6) -HWCONF_PORT_0_IRQ(BUTTON_1, 6) -HWCONF_PIN(BUTTON_2, 0, 7) -HWCONF_PORT_0_IRQ(BUTTON_2, 7) -#endif /* MODEL_N711 */ - -/*---------------------------------------------------------------------------*/ -static int -value_b1(int type) -{ - return BUTTON_1_READ() || !timer_expired(&debouncetimer[0]); -} -/*---------------------------------------------------------------------------*/ -static int -status_b1(int type) -{ - switch(type) { - case SENSORS_ACTIVE: - case SENSORS_READY: - return BUTTON_1_IRQ_ENABLED(); - } - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -configure_b1(int type, int value) -{ - switch(type) { - case SENSORS_HW_INIT: - /* Generates INT when pressed */ - BUTTON_1_IRQ_EDGE_SELECTD(); - BUTTON_1_SELECT(); - BUTTON_1_MAKE_INPUT(); - return 1; - case SENSORS_ACTIVE: - if(value) { - if(!BUTTON_1_IRQ_ENABLED()) { - timer_set(&debouncetimer[0], 0); - BUTTON_1_IRQ_FLAG_OFF(); - BUTTON_1_ENABLE_IRQ(); - } - } else { - BUTTON_1_DISABLE_IRQ(); - } - return 1; - } - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -value_b2(int type) -{ - return BUTTON_2_READ() || !timer_expired(&debouncetimer[1]); -} -/*---------------------------------------------------------------------------*/ -static int -status_b2(int type) -{ - switch(type) { - case SENSORS_ACTIVE: - case SENSORS_READY: - return BUTTON_2_IRQ_ENABLED(); - } - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -configure_b2(int type, int value) -{ - switch(type) { - case SENSORS_HW_INIT: - /* Generates INT when released */ - /* BUTTON_2_IRQ_EDGE_SELECTD(); */ - BUTTON_2_SELECT(); - BUTTON_2_MAKE_INPUT(); - return 1; - case SENSORS_ACTIVE: - if(value) { - if(!BUTTON_2_IRQ_ENABLED()) { - timer_set(&debouncetimer[1], 0); - BUTTON_2_IRQ_FLAG_OFF(); - BUTTON_2_ENABLE_IRQ(); - } - } else { - BUTTON_2_DISABLE_IRQ(); - } - return 1; - } - return 0; -} -/*---------------------------------------------------------------------------*/ -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -port_0_ISR(void) __interrupt (P0INT_VECTOR) -{ - EA = 0; - ENERGEST_ON(ENERGEST_TYPE_IRQ); - - /* This ISR is for the entire port. Check if the interrupt was caused by our - * button's pin. */ - /* Check B1 for N711 */ -#ifdef MODEL_N711 - if(BUTTON_1_CHECK_IRQ()) { - if(timer_expired(&debouncetimer[0])) { - timer_set(&debouncetimer[0], CLOCK_SECOND / 4); - sensors_changed(&button_1_sensor); - } - } -#endif /* MODEL_N711 */ - if(BUTTON_2_CHECK_IRQ()) { - if(timer_expired(&debouncetimer[1])) { - timer_set(&debouncetimer[1], CLOCK_SECOND / 4); - sensors_changed(&button_2_sensor); - } - } - P0IFG = 0; - IRCON_P0IF = 0; - ENERGEST_OFF(ENERGEST_TYPE_IRQ); - EA = 1; -} -/*---------------------------------------------------------------------------*/ -/* We only need this ISR for N740 */ -#ifdef MODEL_N740 -void -port_1_ISR(void) __interrupt (P1INT_VECTOR) -{ - EA = 0; - ENERGEST_ON(ENERGEST_TYPE_IRQ); - - /* This ISR is for the entire port. Check if the interrupt was caused by our - * button's pin. This can only be B1 for N740 */ - if(BUTTON_1_CHECK_IRQ()) { - if(timer_expired(&debouncetimer[0])) { - timer_set(&debouncetimer[0], CLOCK_SECOND / 4); - sensors_changed(&button_1_sensor); - } - } - P1IFG = 0; - IRCON2_P1IF = 0; - ENERGEST_OFF(ENERGEST_TYPE_IRQ); - EA = 1; -} -#endif /* MODEL_N740 */ -#pragma restore - -SENSORS_SENSOR(button_1_sensor, BUTTON_1_SENSOR, value_b1, configure_b1, status_b1); -SENSORS_SENSOR(button_2_sensor, BUTTON_2_SENSOR, value_b2, configure_b2, status_b2); -#endif /* BUTTON_SENSOR_ON */ diff --git a/platform/sensinode/dev/leds-arch.c b/platform/sensinode/dev/leds-arch.c deleted file mode 100644 index 5d4154d2f..000000000 --- a/platform/sensinode/dev/leds-arch.c +++ /dev/null @@ -1,90 +0,0 @@ -#include "contiki-conf.h" -#include "dev/models.h" -#include "dev/leds.h" - -#include "cc2430_sfr.h" - -/* - * Sensinode v1.0 HW products have 2 red LEDs, LED1 is mapped to the Contiki - * LEDS_GREEN and LED2 is mapped to LEDS_RED. - */ - -/*---------------------------------------------------------------------------*/ -void -leds_arch_init(void) -{ -#ifdef MODEL_N740 - /* - * We don't need explicit led initialisation for N740s. They are controlled - * by the ser/par chip which is initalised already - */ - return; -#else - P0DIR |= 0x30; -#endif -} -/*---------------------------------------------------------------------------*/ -unsigned char -leds_arch_get(void) -{ - unsigned char l = 0; - -#ifdef MODEL_N740 - /* Read the current ser-par chip status */ - uint8_t ser_par; - ser_par = n740_ser_par_get(); - /* Check bits 7 & 8, ignore the rest */ - if(ser_par & N740_SER_PAR_LED_GREEN) { - l |= LEDS_GREEN; - } - if(ser_par & N740_SER_PAR_LED_RED) { - l |= LEDS_RED; - } -#else - if(LED1_PIN) { - l |= LEDS_GREEN; - } - if(LED2_PIN) { - l |= LEDS_RED; - } -#endif - return l; -} -/*---------------------------------------------------------------------------*/ -void -leds_arch_set(unsigned char leds) -{ -#ifdef MODEL_N740 - /* Read the current ser-par chip status - we want to change bits 7 & 8 but - * the remaining bit values should be retained */ - uint8_t ser_par; - ser_par = n740_ser_par_get(); - if(leds & LEDS_GREEN) { - ser_par |= N740_SER_PAR_LED_GREEN; /* Set bit 7 */ - } else { - ser_par &= ~N740_SER_PAR_LED_GREEN; /* Unset bit 7 */ - } - - if(leds & LEDS_RED) { - ser_par |= N740_SER_PAR_LED_RED; /* Set bit 8 */ - } else { - ser_par &= ~N740_SER_PAR_LED_RED; /* Unset bit 8 */ - } - - /* Write the new status back to the chip */ - n740_ser_par_set(ser_par); -#else - if(leds & LEDS_GREEN) { - LED1_PIN = 1; - } else { - LED1_PIN = 0; - } - - if(leds & LEDS_RED) { - LED2_PIN = 1; - } else { - LED2_PIN = 0; - } -#endif -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sensinode/dev/m25p16.c b/platform/sensinode/dev/m25p16.c deleted file mode 100644 index f1cbdebfd..000000000 --- a/platform/sensinode/dev/m25p16.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * This file provides functions to control the M25P16 on sensinode N740s. - * This is a Numonyx Forte Serial Flash Memory (16Mbit) - * The S signal (Chip Select) is controlled via 0x02 on the 74HC595D - * The other instructions and timing are performed with bit bang - * - * We can enable, disable, read/write data, erase pages, hold, enter/exit - * deep sleep etc. - * - * Clock (C) => P1_5, - * Ser. I (D) => P1_6, - * Ser. O (Q) => P1_7, - * Hold => Pull Up, - * Write Prot => Pull Up, - * Chip Sel => 74HC595D (0x02) - * - * This file can be placed in any bank. - * - * \author - * George Oikonomou - - */ - -#include "dev/n740.h" -#include "dev/m25p16.h" -#include "sys/clock.h" -#include "sys/energest.h" -#include "cc2430_sfr.h" - -#define CLOCK_RISING() {M25P16_PIN_CLOCK = 1; M25P16_PIN_CLOCK = 0;} -#define CLOCK_FALLING() {M25P16_PIN_CLOCK = 0; M25P16_PIN_CLOCK = 1;} -/*---------------------------------------------------------------------------*/ -/* Bit-Bang write a byte to the chip */ -static void -bit_bang_write(uint8_t byte) CC_NON_BANKED -{ - uint8_t i; - uint8_t bit; - - /* bit-by-bit */ - for(i = 0x80; i > 0; i >>= 1) { - /* Is the bit set? */ - bit = 0; - if(i & byte) { - /* If it was set, we want to send 1 */ - bit = 1; - } - /* Send the bit */ - M25P16_PIN_SER_I = bit; - /* Clock - Rising */ - CLOCK_RISING(); - } -} -/*---------------------------------------------------------------------------*/ -/* Bit-Bang read a byte from the chip */ -static uint8_t -bit_bang_read() CC_NON_BANKED -{ - int8_t i; - uint8_t bits = 0; - - /* bit-by-bit */ - for(i = 7; i >= 0; i--) { - /* Clock - Falling */ - CLOCK_FALLING(); - - /* Read the bit */ - bits |= (M25P16_PIN_SER_O << i); - } - return bits; -} -/*---------------------------------------------------------------------------*/ -static void -select() CC_NON_BANKED -{ - /* Read current ser/par value */ - uint8_t ser_par = n740_ser_par_get(); - - M25P16_PIN_CLOCK = 0; - - ser_par &= ~N740_SER_PAR_CHIP_SEL; /* Select Flash */ - - /* Write the new status back to the ser/par */ - n740_ser_par_set(ser_par); -} -/*---------------------------------------------------------------------------*/ -static void -deselect() CC_NON_BANKED -{ - /* Read current ser/par value */ - uint8_t ser_par = n740_ser_par_get(); - - ser_par |= N740_SER_PAR_CHIP_SEL; /* De-Select Flash */ - - /* Write the new status back to the ser/par */ - n740_ser_par_set(ser_par); -} -/*---------------------------------------------------------------------------*/ -void -m25p16_wren() -{ - select(); - bit_bang_write(M25P16_I_WREN); - deselect(); - - while(!M25P16_WEL()); -} -/*---------------------------------------------------------------------------*/ -void -m25p16_wrdi() -{ - select(); - bit_bang_write(M25P16_I_WRDI); - deselect(); -} -/*---------------------------------------------------------------------------*/ -void -m25p16_rdid(struct m25p16_rdid *rdid) -{ - uint8_t i; - - select(); - bit_bang_write(M25P16_I_RDID); - - rdid->man_id = bit_bang_read(); - rdid->mem_type = bit_bang_read(); /* Device ID MSB */ - rdid->mem_size = bit_bang_read(); /* Device ID LSB */ - rdid->uid_len = bit_bang_read(); - for(i = 0; i < rdid->uid_len; i++) { - rdid->uid[i] = bit_bang_read(); - } - deselect(); -} -/*---------------------------------------------------------------------------*/ -uint8_t -m25p16_rdsr() -{ - uint8_t rv; - - select(); - bit_bang_write(M25P16_I_RDSR); - rv = bit_bang_read(); - deselect(); - - return rv; -} -/*---------------------------------------------------------------------------*/ -void -m25p16_wrsr(uint8_t val) -{ - m25p16_wren(); /* Write Enable */ - - select(); - ENERGEST_ON(ENERGEST_TYPE_FLASH_WRITE); - bit_bang_write(M25P16_I_WRSR); - bit_bang_write(val); - ENERGEST_OFF(ENERGEST_TYPE_FLASH_WRITE); - deselect(); -} -/*---------------------------------------------------------------------------*/ -void -m25p16_read(uint8_t * addr, uint8_t * buff, uint8_t buff_len) -{ - uint8_t i; - - select(); - ENERGEST_ON(ENERGEST_TYPE_FLASH_READ); - -#if M25P16_READ_FAST - bit_bang_write(M25P16_I_FAST_READ); -#else - bit_bang_write(M25P16_I_READ); -#endif - - /* Write the address, MSB in addr[0], bits [7:5] of the MSB: 'don't care' */ - for(i = 0; i < 3; i++) { - bit_bang_write(addr[i]); - } - - /* For FAST_READ, send the dummy byte */ -#if M25P16_READ_FAST - bit_bang_write(M25P16_DUMMY_BYTE); -#endif - - for(i = 0; i < buff_len; i++) { - buff[i] = ~bit_bang_read(); - } - ENERGEST_OFF(ENERGEST_TYPE_FLASH_READ); - deselect(); -} -/*---------------------------------------------------------------------------*/ -void -m25p16_pp(uint8_t * addr, uint8_t * buff, uint8_t buff_len) -{ - uint8_t i; - - m25p16_wren(); /* Write Enable */ - - select(); - ENERGEST_ON(ENERGEST_TYPE_FLASH_WRITE); - bit_bang_write(M25P16_I_PP); - - /* Write the address, MSB in addr[0] */ - for(i = 0; i < 3; i++) { - bit_bang_write(addr[i]); - } - - /* Write the bytes */ - for(i = 0; i < buff_len; i++) { - bit_bang_write(~buff[i]); - } - ENERGEST_OFF(ENERGEST_TYPE_FLASH_WRITE); - deselect(); -} -/*---------------------------------------------------------------------------*/ -void -m25p16_se(uint8_t s) -{ - m25p16_wren(); /* Write Enable */ - - select(); - ENERGEST_ON(ENERGEST_TYPE_FLASH_WRITE); - bit_bang_write(M25P16_I_SE); - bit_bang_write(s); - bit_bang_write(0x00); - bit_bang_write(0x00); - deselect(); - ENERGEST_OFF(ENERGEST_TYPE_FLASH_WRITE); -} -/*---------------------------------------------------------------------------*/ -void -m25p16_be() -{ - m25p16_wren(); /* Write Enable */ - - select(); - bit_bang_write(M25P16_I_BE); - deselect(); -} -/*---------------------------------------------------------------------------*/ -void -m25p16_dp() -{ - select(); - bit_bang_write(M25P16_I_DP); - deselect(); -} -/*---------------------------------------------------------------------------*/ -/* - * Release Deep Power Down. We do NOT read the Electronic Signature - */ -void -m25p16_res() -{ - select(); - bit_bang_write(M25P16_I_RES); - deselect(); - /* a few usec between RES and standby */ - while(M25P16_WIP()); -} -/*---------------------------------------------------------------------------*/ -/** - * Release Deep Power Down. Read and return the Electronic Signature - * must return 0x14 - * - * \return The old style Electronic Signature. This must be 0x14 - */ -uint8_t -m25p16_res_res() -{ - uint8_t rv; - - select(); - bit_bang_write(M25P16_I_RES); - bit_bang_write(M25P16_DUMMY_BYTE); - bit_bang_write(M25P16_DUMMY_BYTE); - bit_bang_write(M25P16_DUMMY_BYTE); - - rv = bit_bang_read(); - - deselect(); - - /* a few usec between RES and standby */ - while(M25P16_WIP()); - return rv; -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sensinode/dev/m25p16.h b/platform/sensinode/dev/m25p16.h deleted file mode 100644 index 580564953..000000000 --- a/platform/sensinode/dev/m25p16.h +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Header file for the control of the M25P16 on sensinode N740s. - * - * \author - * George Oikonomou - - */ - -#ifndef M25P16_H_ -#define M25P16_H_ - -/* Instruction Set */ -#define M25P16_I_WREN 0x06 /* Write Enable */ -#define M25P16_I_WRDI 0x04 /* Write Disable */ -#define M25P16_I_RDID 0x9F /* Read Identification */ -#define M25P16_I_RDSR 0x05 /* Read Status Register */ -#define M25P16_I_WRSR 0x01 /* Write Status Register */ -#define M25P16_I_READ 0x03 /* Read Data Bytes */ -#define M25P16_I_FAST_READ 0x0B /* Read Data Bytes at Higher Speed */ -#define M25P16_I_PP 0x02 /* Page Program */ -#define M25P16_I_SE 0xD8 /* Sector Erase */ -#define M25P16_I_BE 0xC7 /* Bulk Erase */ -#define M25P16_I_DP 0xB9 /* Deep Power-down */ -#define M25P16_I_RES 0xAB /* Release from Deep Power-down */ - -/* Dummy Byte - Used in FAST_READ and RES */ -#define M25P16_DUMMY_BYTE 0x00 - -/* Pins */ -#define M25P16_PIN_CLOCK P1_5 -#define M25P16_PIN_SER_I P1_6 -#define M25P16_PIN_SER_O P1_7 - -/* Status Register Bits */ -#define M25P16_SR_SRWD 0x80 /* Status Register Write Disable */ -#define M25P16_SR_BP2 0x10 /* Block Protect 2 */ -#define M25P16_SR_BP1 0x08 /* Block Protect 1 */ -#define M25P16_SR_BP0 0x04 /* Block Protect 0 */ -#define M25P16_SR_BP 0x1C /* All Block Protect Bits */ -#define M25P16_SR_WEL 0x02 /* Write Enable Latch */ -#define M25P16_SR_WIP 0x01 /* Write in Progress */ - -/* Do we use READ or FAST_READ to read? Fast by default */ -#ifdef M25P16_CONF_READ_FAST -#define M25P16_READ_FAST M25P16_CONF_READ_FAST -#else -#define M25P16_READ_FAST 1 -#endif -/*---------------------------------------------------------------------------*/ -/** \brief Device Identifier - * - * Holds the value of the device identifier, returned by the RDID instruction. - * - * After a correct RDID, this structure should hold the following values: - * man_id = 0x20, mem_type = 0x20, mem_size = 0x15, uid_len = 0x10. - * - * UID holds optional Customized Factory Data (CFD) content. The CFD bytes are - * read-only and can be programmed with customers data upon their request. - * If the customers do not make requests, the devices are shipped with all the - * CFD bytes programmed to 0x00. - */ -struct m25p16_rdid { - uint8_t man_id; /** Manufacturer ID */ - uint8_t mem_type; /** Memory Type */ - uint8_t mem_size; /** Memory Size */ - uint8_t uid_len; /** Unique ID length */ - uint8_t uid[16]; /** Unique ID */ -}; -/*---------------------------------------------------------------------------*/ -/** - * \brief Retrieve Block Protect Bits from the status register - * - * This macro returns the software block protect status on the device - * by reading the value of the BP bits ([5:3]) in the Status Register - */ -#define M25P16_BP() (m25p16_rdsr() & M25P16_SR_BP) -/** - * \brief Check for Write in Progress - * \retval 1 Write in progress - * \retval 0 Write not in progress - * - * This macro checks if the device is currently in the middle of a write cycle - * by reading the value of the WIP bit (bit 0) in the Status Register - */ -#define M25P16_WIP() (m25p16_rdsr() & M25P16_SR_WIP) -/** - * \brief Check for Write-Enable - * \retval 1 Write enabled - * \retval 0 Write disabled - * - * This macro checks if the device is ready to accept a write instruction - * by reading the value of the WEL bit (bit 1) in the Status Register - */ -#define M25P16_WEL() (m25p16_rdsr() & M25P16_SR_WEL) -/*---------------------------------------------------------------------------*/ -/** - * \brief Write Enable (WREN) instruction. - * - * Completing a WRDI, PP, SE, BE and WRSR - * resets the write enable latch bit, so this instruction should be used every - * time before trying to write. - */ -void m25p16_wren(); - -/** - * \brief Write Disable (WRDI) instruction - */ -void m25p16_wrdi(); - -/** - * \brief Read Identifier (RDID)instruction - * - * \param rdid Pointer to a struct which will hold the information returned - * by the RDID instruction - */ -void m25p16_rdid(struct m25p16_rdid *rdid); - -/** - * \brief Read Status Register (RDSR) instruction - * - * \return Value of the status register - * - * Reads and returns the value of the status register on the Flash Chip - */ -uint8_t m25p16_rdsr(); - -/** - * \brief Write Status Register (WRSR) instruction - * \param val Value to be written to the status register - * - * This instruction does not afect bits 6, 5, 1 and 0 of the SR. - */ -void m25p16_wrsr(uint8_t val); - -/** - * \brief Read Data Bytes (READ) instruction - * \param addr 3 byte array holding the read start address. MSB stored in - * addr[0] and LSB in addr[2] - * \param buff Pointer to a buffer to hold the read bytes. - * \param buff_len Number of bytes to read. buff must be long enough to hold - * buff_len bytes - * - * The bytes will be inverted after being read, so that a value of 0xFF (empty) - * in the flash will read as 0x00 - */ -void m25p16_read(uint8_t * addr, uint8_t * buff, uint8_t buff_len); - -/** - * \brief Program Page (PP) instruction - * \param addr 3 byte array holding the write start address. MSB stored in - * addr[0] and LSB in addr[2] - * \param buff Pointer to a buffer with the data to be written - * \param buff_len Number of bytes to write, Maximum 256 bytes. - * - * Write BUFF_LEN bytes stored in BUFF to flash, starting from location - * ADDR. BUFF_LEN may not exceed 256. ADDR should point to a 3 byte array, - * with the address MSB stored in position 0 and LSB in position 2 - * - * If the start address + buff_len exceed page boundaries, the write will - * wrap to the start of the same page (the page at addr[2:1]). - * - * The bytes will be inverted before being written, so that a value of 0xFF - * will be written as 0x00 (and subsequently correctly read as 0xFF by READ) - * - * This function will set the WEL bit on the SR before attempting to write, - * so the calling function doesn't need to worry about this. - * - * This call is asynchronous. It will return before the write cycle has - * completed. Thus, user software must check the WIP bit Write In Progress) - * before sending further instructions. This can take up to 5 msecs (typical - * duration for a 256 byte write is 640 usec) - */ -void m25p16_pp(uint8_t * addr, uint8_t * buff, uint8_t buff_len); - -/** - * \brief Sector Erase (SE) instruction - * \param s The number of the sector to be erased - * - * Delete the entire sector number s, by setting it's contents to all 0xFF - * (which will read as 0x00 by READ). The flash is broken down into 32 sectors, - * 64 KBytes each. - * - * This function will set the WEL bit on the SR before attempting to write, - * so the calling function doesn't need to worry about this. - * - * This call is asynchronous. It will return before the write cycle has - * completed. Thus, user software must check the WIP bit Write In Progress) - * before sending further instructions. This can take up to 3 secs (typical - * duration 600 msec) - */ -void m25p16_se(uint8_t s); /* Sector Erase */ - - -/** - * \brief Bulk Erase (SE) instruction - * - * Delete the entire memory, by setting it's contents to all 0xFF - * (which will read as 0x00 by READ). - * - * This function will set the WEL bit on the SR before attempting to write, - * so the calling function doesn't need to worry about this. - * - * This call is asynchronous. It will return before the write cycle has - * completed. Thus, user software must check the WIP bit Write In Progress) - * before sending further instructions. - * - * This instructions takes a very long time to complete and must be used with - * care. It can take up to 40 secs (yes, secs). A typical duration is 13 secs - */ -void m25p16_be(); - -/** - * \brief Deep Power Down (DP) instruction - * - * Puts the device into its lowers power consumption mode (This is not the same - * as the stand-by mode caused by de-selecting the device). While the device - * is in DP, it will accept no instruction except a RES (Release from DP). - * - * This call is asynchronous and will return as soon as the instruction - * sequence has been written but before the device has actually entered DP - * - * Dropping to DP takes 3usec and Resuming from DP takes at least 1.8usec, so - * this sequence should not be used when the sleep interval is estimated to be - * short (read as: don't DP then RES then DP repeatedly) - */ -void m25p16_dp(); /* Deep Power down */ - -/** - * \brief Release from Deep Power Down (RES) instruction - * - * Take the device out of the Deep Power Down mode and bring it to standby. - * Does not read the electronic signature. - * - * This call is synchronous. When it returns the device will be in standby - * mode. - * - * Dropping to DP takes 3usec and Resuming from DP takes at least 1.8usec, so - * this sequence should not be used when the sleep interval is estimated to be - * short (read as: don't DP then RES then DP repeatedly) - */ -void m25p16_res(); - -/** - * \brief Release from Deep Power Down (RES) and Read Electronic - * Signature instruction - * - * \return The value of the electronic signature. This is provided for backward - * compatibility and must always be 0x14 - * - * Take the device out of the Deep Power Down mode and bring it to standby. - * Does not read the electronic signature. - * - * This call is synchronous. When it returns the device will be in standby - * mode. - * - * Dropping to DP takes 3usec and Resuming from DP takes at least 1.8usec, so - * this sequence should not be used when the sleep interval is estimated to be - * short (read as: don't DP then RES then DP repeatedly) - */ -uint8_t m25p16_res_res(); - -#endif /* M25P16_H_ */ diff --git a/platform/sensinode/dev/models.h b/platform/sensinode/dev/models.h deleted file mode 100644 index 6cf4916f4..000000000 --- a/platform/sensinode/dev/models.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef MODELS_H_ -#define MODELS_H_ - -/* Define model text */ -#ifdef MODEL_N100 -#define SENSINODE_MODEL "N100 Module" -#endif -#ifdef MODEL_N600 -#define SENSINODE_MODEL "N600 NanoRouter USB" -#endif -#ifdef MODEL_N601 -#define SENSINODE_MODEL "N601 NanoRouter USB" -#endif -#ifdef MODEL_N710 -#define SENSINODE_MODEL "N710 NanoSensor" -#endif -#ifdef MODEL_N711 -#define SENSINODE_MODEL "N711 NanoSensor" -#endif -#ifdef MODEL_N740 -#define SENSINODE_MODEL "N740 NanoSensor" -#endif - -#ifndef SENSINODE_MODEL -#define SENSINODE_MODEL "N100 Module" -#endif - -#ifndef FLASH_SIZE -#define FLASH_SIZE "F128" -#endif - -/* - * N740 has a serial-parallel chip onboard - * Defines and functions to control it - */ -#ifdef MODEL_N740 -#include "dev/n740.h" - -#else -/* All other models use these LED pins */ -#define LED1_PIN P0_4 -#define LED2_PIN P0_5 -#endif - -#ifdef MODEL_N711 -#define BUTTON1_PIN P0_6 -#define BUTTON2_PIN P0_7 -#endif - -/* Sensor pins */ - -#ifdef MODEL_N711 -#define LIGHT_PIN P0_0 -#define TEMP_PIN P0_1 -#endif - -/* Model-Specific startup functions */ -void model_init(); -void model_uart_intr_en(); -#endif /* MODELS_H_ */ diff --git a/platform/sensinode/dev/n740.c b/platform/sensinode/dev/n740.c deleted file mode 100644 index de1e20fd1..000000000 --- a/platform/sensinode/dev/n740.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * This file provides functions to control various chips on the - * Sensinode N740s: - * - * - The 74HC595D is an 8-bit serial in-parallel out shift register. - * LEDs are connected to this chip. It also serves other functions such as - * enabling/disabling the Accelerometer (see n740.h). - * - The 74HC4053D is a triple, 2-channel analog mux/de-mux. - * It switches I/O between the USB and the D-Connector. - * It also controls P0_0 input source (Light Sensor / External I/O) - * - * Mux/De-mux: Connected to P0_3 (set to output in models.c - * Changing the state of the mux/demux can have catastrophic (tm) results - * on our software. If we are not careful, we risk entering a state where - * UART1 RX interrupts are being generated non-stop. Only change its state - * via the function in this file. - * - * Shift Register: - * For the shift register we can: - * - write a new instruction - * - remember and retrieve the last instruction sent - * - * The chip is connected to CPU pins as follows: - * - P0_2: Serial Data Input - * - P1_3: Shift Register Clock Input - * - P1_1: Storage Register Clock - * - * This file can be placed in any bank. - * - * \author - * George Oikonomou - - */ - -#include "dev/n740.h" -#include "dev/uart1.h" -#include "8051def.h" - -/* - * This variable stores the most recent instruction sent to the ser-par chip. - * We declare it as static and return its value through n740_ser_par_get(). - */ -static CC_AT_DATA uint8_t ser_par_status; - -/*---------------------------------------------------------------------------*/ -/* Init the serial-parallel chip: - * - Set I/O direction for all 3 pins (P0_2, P1_1 and P1_3) to output - */ -void -n740_ser_par_init() -{ - /* bus_init and uart1_init also touch the I/O direction for those pins */ - P1DIR |= 0x0A; - P0DIR |= 0x04; -} -/*---------------------------------------------------------------------------*/ -/* - * Send a command to the N740 serial-parallel chip. Each command is a single - * byte, each bit controls a different feature on the sensor. - */ -void -n740_ser_par_set(uint8_t data) -{ - uint8_t i; - uint8_t mask = 1; - uint8_t temp = 0; - - DISABLE_INTERRUPTS(); - /* bit-by-bit */ - for(i = 0; i < 8; i++) { - temp = (data & mask); - /* Is the bit set? */ - if(i && temp) { - /* If it was set, we want to send 1 */ - temp >>= i; - } - /* Send the bit */ - P0_2 = temp; - /* Shift */ - P1_3 = 1; - P1_3 = 0; - mask <<= 1; - } - /* Move to Par-Out */ - P1_1 = 1; - P1_1 = 0; - ENABLE_INTERRUPTS(); - - /* Right, we're done. Save the new status in ser_par_status */ - ser_par_status = data; -} -/*---------------------------------------------------------------------------*/ -/* This function returns the last value sent to the ser-par chip on the N740. - * - * The caveat here is that we must always use n740_set_ser_par() to send - * commands to the ser-par chip, never write directly. - * - * If any other function sends a command directly, ser_par_status and the - * actual status will end up out of sync. - */ -uint8_t -n740_ser_par_get() -{ - return ser_par_status; -} -/*---------------------------------------------------------------------------*/ -void -n740_analog_switch(uint8_t state) -{ - /* Turn off the UART RX interrupt before switching */ - DISABLE_INTERRUPTS(); - UART1_RX_INT(0); - - /* Switch */ - P0_3 = state; - - /* If P0_3 now points to the USB and nothing is flowing down P1_7, - * enable the interrupt again */ - if(P1_7 == 1 && P0_3 == N740_ANALOG_SWITCH_USB) { - UART1_RX_INT(1); - } - ENABLE_INTERRUPTS(); -} -/*---------------------------------------------------------------------------*/ -/* - * Activate the the 74HC4053D analog switch U5 on the N740 and at the same - * time set relevant pins to Peripheral I/O mode. This stops communications - * with the serial flash and enables UART1 I/O - */ -void -n740_analog_activate() -{ - uint8_t ser_par = n740_ser_par_get(); - ser_par &= ~N740_SER_PAR_U5_ENABLE; /* Turn on */ - - N740_PINS_PER_IO(); - - n740_ser_par_set(ser_par); -} -/*---------------------------------------------------------------------------*/ -/* - * De-Activate the the 74HC4053D analog switch U5 on the N740 and at the same - * time set relevant pins to GP I/O mode. This effectively prepares us to - * start talking with the serial flash chip - */ -void -n740_analog_deactivate() -{ - uint8_t ser_par = n740_ser_par_get(); - ser_par |= N740_SER_PAR_U5_ENABLE; /* Turn off */ - - n740_ser_par_set(ser_par); - - N740_PINS_GPIO(); -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sensinode/dev/n740.h b/platform/sensinode/dev/n740.h deleted file mode 100644 index 1bb74380e..000000000 --- a/platform/sensinode/dev/n740.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Header File for the module which controls the Sensinode N740 - * 8-bit serial-in/serial or parallel-out shift register. - * - * This is where the Accelerometer, Leds, Light and Battery Sensors - * are connected. - * - * \author - * George Oikonomou - - */ - -#ifndef N740SERPAR_H_ -#define N740SERPAR_H_ - -#include "8051def.h" - -#define N740_SER_PAR_ACC_GSEL 0x01 /* Acceleration Sensor g-Select */ -#define N740_SER_PAR_CHIP_SEL 0x02 /* Flash Chip Select */ -#define N740_SER_PAR_LIGHT 0x04 /* Light Sensor */ -#define N740_SER_PAR_ACC 0x08 /* Acceleration Sensor */ -#define N740_SER_PAR_RF_IN_GAIN 0x10 /* Receiver Amplifier, best not set */ -#define N740_SER_PAR_U5_ENABLE 0x20 /* U5 analog switch enable */ -#define N740_SER_PAR_LED_GREEN 0x40 /* Led 1 */ -#define N740_SER_PAR_LED_RED 0x80 /* Led 2 */ - -#define N740_ANALOG_SWITCH_USB 0 -#define N740_ANALOG_SWITCH_SERIAL 1 - -#define N740_PINS 0xE0 -#define N740_PINS_GPIO() {P1SEL &= ~N740_PINS;} -#define N740_PINS_PER_IO() {P1SEL |= N740_PINS;} - -/* Serial/Parallel Shift Register (74HC595D) Functions */ -void n740_ser_par_init(void); -void n740_ser_par_set(uint8_t data); -uint8_t n740_ser_par_get(void); - -/* Analog Switch (U5 - 74HC4053D) Functions */ -void n740_analog_switch(uint8_t state); -void n740_analog_activate(); -void n740_analog_deactivate(); - -#endif /* N740SERPAR_H_ */ diff --git a/platform/sensinode/dev/sensinode-sensors.h b/platform/sensinode/dev/sensinode-sensors.h deleted file mode 100644 index 503499ec8..000000000 --- a/platform/sensinode/dev/sensinode-sensors.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Defines for the sensors on the various Sensinode models. - * - * Sensors will be off by default, unless turned on explicitly - * in contiki-conf.h - * - * If you enable sensors generating interrupts, make sure you include - * this file in the file containing main(). - * - * \author - * George Oikonomou - - */ - -#ifndef SENSINODE_SENSORS_H_ -#define SENSINODE_SENSORS_H_ - -#include "cc2430_sfr.h" -#include "contiki-conf.h" -#include "dev/models.h" -#include "lib/sensors.h" - -void sensinode_sensors_activate(); -void sensinode_sensors_deactivate(); - -/* ADC Sensor Types */ -#define ADC_SENSOR "ADC" - -#define ADC_SENSOR_TYPE_TEMP 0 -#define ADC_SENSOR_TYPE_ACC_X 1 -#define ADC_SENSOR_TYPE_ACC_Y 2 -#define ADC_SENSOR_TYPE_ACC_Z 3 -#define ADC_SENSOR_TYPE_VDD 4 -#define ADC_SENSOR_TYPE_LIGHT 5 -#define ADC_SENSOR_TYPE_BATTERY 6 - -/* Defines to help us control Acc and Ill individually */ -#define ADC_VAL_NONE 0x00 -#define ADC_VAL_ALL 0x01 -#define ADC_VAL_LIGHT_ON 0x04 -#define ADC_VAL_ACC_ON 0x08 -#define ADC_VAL_ACC_GSEL 0x10 - -#ifdef ADC_SENSOR_CONF_ON -#define ADC_SENSOR_ON ADC_SENSOR_CONF_ON -#endif /* ADC_SENSOR_CONF_ON */ - -#if ADC_SENSOR_ON -extern const struct sensors_sensor adc_sensor; -#endif /* ADC_SENSOR_ON */ - -/* - * Accelerometer. Available on N740 only. - * This is a Freescale Semiconductor MMA7340L (3 axis, 3/11g) - * X: P0_5 - * Y: P0_6 - * Z: P0_7 - */ -#ifdef MODEL_N740 -#ifdef ACC_SENSOR_CONF_ON -#define ACC_SENSOR_ON ACC_SENSOR_CONF_ON -#endif /* ACC_SENSOR_CONF_ON */ - -/* Accelerometer g-Select - Define for +/-11g, +/-3g Otherwise */ -#if ACC_SENSOR_ON -#ifdef ACC_SENSOR_CONF_GSEL -#define ACC_SENSOR_GSEL ACC_SENSOR_CONF_GSEL -#endif /* ACC_SENSOR_CONF_GSEL */ -#endif /* ACC_SENSOR_ON */ -#endif /* MODEL_N740 */ - -/* - * Buttons - * N740: P1_0, P0_4 - * N711: P0_6, P0_7 - * N710: Unknown. This will mainly influence which ISRs to declare here - */ -#if defined(MODEL_N740) || defined(MODEL_N711) -#ifdef BUTTON_SENSOR_CONF_ON -#define BUTTON_SENSOR_ON BUTTON_SENSOR_CONF_ON -#endif /* BUTTON_SENSOR_CONF_ON */ -#endif /* defined(MODEL_FOO) */ - -#define BUTTON_1_SENSOR "Button 1" -#define BUTTON_2_SENSOR "Button 2" -#define BUTTON_SENSOR BUTTON_1_SENSOR - -#if BUTTON_SENSOR_ON -extern const struct sensors_sensor button_1_sensor; -extern const struct sensors_sensor button_2_sensor; -#define button_sensor button_1_sensor - -/* Port 0 ISR needed for both models */ -void port_0_ISR(void) __interrupt (P0INT_VECTOR); - -/* Only declare the Port 1 ISR for N740 */ -#ifdef MODEL_N740 -void port_1_ISR(void) __interrupt (P1INT_VECTOR); -#endif /* MODEL_N740 */ -#endif /* BUTTON_SENSOR_ON */ - -/* - * Light - N710, N711, N740 - * N740: P0_0 - * N711: P0_0 - * N710: P?_? - */ -#if defined(MODEL_N740) || defined(MODEL_N711) || defined(MODEL_N710) -#ifdef LIGHT_SENSOR_CONF_ON -#define LIGHT_SENSOR_ON LIGHT_SENSOR_CONF_ON -#endif /* LIGHT_SENSOR_CONF_ON */ -#endif /* defined(MODEL_FOO) */ - -/* - * Battery - N711, N740, (N710 likely) - * N740: P0_1 - * Unknown for other models - */ -#if defined(MODEL_N740) || defined(MODEL_N711) || defined(MODEL_N710) -#ifdef BATTERY_SENSOR_CONF_ON -#define BATTERY_SENSOR_ON BATTERY_SENSOR_CONF_ON -#endif /* BATTERY_SENSOR_CONF_ON */ -#endif /* defined(MODEL_FOO) */ - -/* Temperature - Available on all cc2430 devices */ -#ifdef TEMP_SENSOR_CONF_ON -#define TEMP_SENSOR_ON TEMP_SENSOR_CONF_ON -#endif /* TEMP_SENSOR_CONF_ON */ - -/* Supply Voltage - Available on all cc2430 devices*/ -#ifdef VDD_SENSOR_CONF_ON -#define VDD_SENSOR_ON VDD_SENSOR_CONF_ON -#endif /* VDD_SENSOR_CONF_ON */ - -#endif /* SENSINODE_SENSORS_H_ */ diff --git a/platform/sensinode/disco.c b/platform/sensinode/disco.c deleted file mode 100644 index 63d95c6b9..000000000 --- a/platform/sensinode/disco.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Disco server sources - * (embedded part of the DISCOBALL project) - * - * It objective is to receive a code file over UDP, store it in - * external flash and disseminate it to other nodes of the - * 6LoWPAN network. - * - * For this to work, the image must be co-hosted with the BooTTY! - * bootloader, which will move the image from external to internal - * flash. - * - * To link this application in your contiki image, all you need to - * do is to add this line: - * OFFSET_FIRMWARE=1 - * to your project's makefile - * - * \author - * George Oikonomou - - */ - -#include "contiki.h" -#include "contiki-net.h" -#include "sys/clock.h" -#include "sys/ctimer.h" -#include "dev/watchdog.h" - -#include "dev/n740.h" -#include "dev/m25p16.h" - -#include "disco.h" -/*---------------------------------------------------------------------------*/ -#define DEBUG DEBUG_NONE -#include "net/ip/uip-debug.h" -/*---------------------------------------------------------------------------*/ -#if BATMON_CONF_ENABLED -void batmon_log(uint8_t trigger); - -#define LOG_TRIGGER_OAP_DISCO_START 0x01 -#define LOG_TRIGGER_OAP_DISCO_DONE 0x02 -#define LOG_TRIGGER_OAP_DISCO_ABORT 0x03 -#else -#define batmon_log(t) do { } while(0); -#endif -/*---------------------------------------------------------------------------*/ -static struct uip_udp_conn *server_conn; -static struct disco_request_pdu *req; -static struct disco_response_pdu resp; -static struct disco_seed seed; -static uint8_t state; -static uint8_t sector; -static uint16_t interval; -static struct ctimer disco_timer; - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) - -extern uint16_t uip_len; -extern void *uip_appdata; - -__xdata __at(BOOTTY_CMD_LOCATION) static uint8_t bd; -/*---------------------------------------------------------------------------*/ -static void timer_handler(void *p); -/*---------------------------------------------------------------------------*/ -static void -abort() CC_NON_BANKED -{ - PRINTF("Disco: Abort @ %lu\n", clock_seconds()); - n740_analog_deactivate(); - m25p16_dp(); - n740_analog_activate(); - state = DISCO_STATE_LISTENING; - memset(&seed, 0, sizeof(seed)); - ctimer_stop(&disco_timer); - batmon_log(LOG_TRIGGER_OAP_DISCO_ABORT); -} -/*---------------------------------------------------------------------------*/ -static void -restart_timer(uint16_t t) CC_NON_BANKED -{ - interval = t; - ctimer_stop(&disco_timer); - ctimer_set(&disco_timer, interval, timer_handler, &state); -} -/*---------------------------------------------------------------------------*/ -static void -timer_handler(void *p) -{ - uint8_t *s = p; - uint8_t wip; - - PRINTF("Disco: @ %lu, s: %u\n", clock_seconds(), *s); - - if(*s == DISCO_STATE_PREPARING) { - n740_analog_deactivate(); - wip = M25P16_WIP(); - n740_analog_activate(); - - if(wip) { - restart_timer(DISCO_TIMEOUT_PREPARE); - } else { - PRINTF("Disco: Erased %u\n", sector); - if((sector & 1) == 0) { - sector++; - PRINTF("Disco: Next %u\n", sector); - n740_analog_deactivate(); - m25p16_se(sector); - n740_analog_activate(); - restart_timer(DISCO_TIMEOUT_PREPARE); - } else { - PRINTF("Disco: Ready\n"); - *s = DISCO_STATE_READY; - resp.status = DISCO_CMD_INIT; - restart_timer(DISCO_TIMEOUT_ABORT); - server_conn->rport = seed.port; - uip_ipaddr_copy(&server_conn->ripaddr, &seed.addr); - uip_udp_packet_send(server_conn, &resp, DISCO_RESP_LEN_INIT); - - /* Restore server connection to allow data from any node */ - uip_create_unspecified(&server_conn->ripaddr); - server_conn->rport = 0; - } - } - } else if(*s == DISCO_STATE_READY) { - abort(); - } else if(*s == DISCO_STATE_REBOOTING) { - watchdog_reboot(); - } -} -/*---------------------------------------------------------------------------*/ -static uint8_t -is_protected(uint8_t a) CC_NON_BANKED -{ - uint8_t bp = M25P16_BP() >> 2; - - if(bp > 5) { - return SECTOR_PROTECTED; - } - - bp -= 1; - - if(a >= (32 - (1 << bp))) { - return SECTOR_PROTECTED; - } - return SECTOR_UNPROTECTED; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -cmd_init() CC_NON_BANKED -{ - PRINTF("Disco: Init 0x%02x\n", req->addr[0]); - if(uip_datalen() != DISCO_LEN_INIT) { - PRINTF("Disco: Bad len (%u)\n", uip_datalen()); - resp.status = DISCO_ERR_BAD_LEN; - return DISCO_RESP_LEN_ERR; - } - n740_analog_deactivate(); - m25p16_res(); - sector = 2 * req->addr[0]; - if(is_protected(sector) == SECTOR_PROTECTED - || is_protected(sector + 1) == SECTOR_PROTECTED) { - resp.status = DISCO_ERR_PROTECTED; - n740_analog_activate(); - return DISCO_RESP_LEN_ERR; - } - m25p16_se(sector); - n740_analog_activate(); - state = DISCO_STATE_PREPARING; - restart_timer(DISCO_TIMEOUT_PREPARE); - - /* Store the sender's address/port so we can reply when ready */ - seed.port = UIP_UDP_BUF->srcport; - uip_ipaddr_copy(&seed.addr, &UIP_IP_BUF->srcipaddr); - PRINTF("Disco: OK\n"); - - batmon_log(LOG_TRIGGER_OAP_DISCO_START); - - return DISCO_RESPONSE_NONE; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -cmd_write() CC_NON_BANKED -{ - PRINTF("Disco: Write 0x%02x%02x%02x\n", req->addr[0], req->addr[1], - req->addr[2]); - if(uip_datalen() != DISCO_LEN_WRITE) { - resp.status = DISCO_ERR_BAD_LEN; - return DISCO_RESP_LEN_ERR; - } - restart_timer(DISCO_TIMEOUT_ABORT); - n740_analog_deactivate(); - m25p16_pp(req->addr, req->data, DISCO_FLEN_DATA); - watchdog_periodic(); - while(M25P16_WIP()); - n740_analog_activate(); - resp.status = DISCO_CMD_WRITE; - memcpy(resp.addr, req->addr, DISCO_FLEN_ADDR); - return DISCO_RESP_LEN_WRITE; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -cmd_switch() CC_NON_BANKED -{ - PRINTF("Disco: Switch 0x%02x\n", req->addr[0]); - if(uip_datalen() != DISCO_LEN_SWITCH) { - resp.status = DISCO_ERR_BAD_LEN; - return DISCO_RESP_LEN_ERR; - } - if(req->addr[0] > 15) { - resp.status = DISCO_ERR_BAD_OFFSET; - return DISCO_RESP_LEN_ERR; - } - - bd = BOOTTY_CMD_COPY_IMAGE; - bd |= req->addr[0]; - - resp.status = DISCO_CMD_SWITCH; - resp.addr[0] = req->addr[0]; - - restart_timer(DISCO_TIMEOUT_REBOOT); - state = DISCO_STATE_REBOOTING; - - return DISCO_RESP_LEN_SWITCH; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -cmd_done() CC_NON_BANKED -{ - PRINTF("Disco: Done\n"); - if(uip_datalen() != DISCO_LEN_DONE) { - resp.status = DISCO_ERR_BAD_LEN; - return DISCO_RESP_LEN_ERR; - } - resp.status = DISCO_CMD_DONE; - - batmon_log(LOG_TRIGGER_OAP_DISCO_DONE); - - return DISCO_RESP_LEN_DONE; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -event_handler(process_event_t ev) CC_NON_BANKED -{ - uint8_t rv = DISCO_RESPONSE_NONE; - - if(ev != tcpip_event) { - return rv; - } - - /* Always accept CMD_DONE */ - if(req->cmd == DISCO_CMD_DONE) { - return cmd_done(); - } - - /* Always accept switch too */ - if(req->cmd == DISCO_CMD_SWITCH) { - return cmd_switch(); - } - - switch(state) { - case DISCO_STATE_LISTENING: - req = uip_appdata; - if(req->cmd == DISCO_CMD_INIT) { - rv = cmd_init(); - } - break; - case DISCO_STATE_PREPARING: - PRINTF("Disco: Not Ready\n"); - resp.status = DISCO_ERR_NOT_READY; - rv = DISCO_RESP_LEN_ERR; - break; - case DISCO_STATE_READY: - req = uip_appdata; - if(req->cmd == DISCO_CMD_WRITE) { - rv = cmd_write(); - } else if(req->cmd == DISCO_CMD_INIT) { - resp.status = DISCO_ERR_INIT_DONE; - rv = DISCO_RESP_LEN_ERR; - } else if(req->cmd == DISCO_CMD_SWITCH) { - rv = cmd_switch(); - } - break; - } - return rv; -} -/*---------------------------------------------------------------------------*/ -PROCESS(disco_process, "Disco Server Process"); -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(disco_process, ev, data) -{ - uint8_t len; - - PROCESS_BEGIN(); - - PRINTF("Disco Server\n"); - - server_conn = udp_new(NULL, UIP_HTONS(0), NULL); - udp_bind(server_conn, UIP_HTONS(DISCO_UDP_PORT)); - - state = DISCO_STATE_LISTENING; - - while(1) { - PROCESS_YIELD(); - len = event_handler(ev); - - if(len > 0) { - server_conn->rport = UIP_UDP_BUF->srcport; - uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr); - uip_udp_packet_send(server_conn, &resp, len); - /* Restore server connection to allow data from any node */ - uip_create_unspecified(&server_conn->ripaddr); - server_conn->rport = 0; - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sensinode/disco.h b/platform/sensinode/disco.h deleted file mode 100644 index 81549ab8d..000000000 --- a/platform/sensinode/disco.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Header file for the Disco server - * (embedded part of the DISCOBALL project) - * - * \author - * George Oikonomou - - */ - -#ifndef DISCO_H_ -#define DISCO_H_ - -#include "contiki.h" -#include "contiki-net.h" -/*---------------------------------------------------------------------------*/ -#define DISCO_UDP_PORT 60002 -#define DISCO_DESCRIPTORS_LOC /* In external Flash */ - -#define DATA_CHUNK_LEN 64 - -/* Intervals - Timeouts */ -#define DISCO_TIMEOUT_PREPARE (CLOCK_SECOND / 2) -#define DISCO_TIMEOUT_ABORT (CLOCK_SECOND * 10) -#define DISCO_TIMEOUT_REBOOT CLOCK_SECOND - -/* Disco State Machine */ -#define DISCO_STATE_LISTENING 0x00 /* Waiting for a transaction to start */ -#define DISCO_STATE_PREPARING 0x01 /* Erasing Sectors */ -#define DISCO_STATE_READY 0x02 -#define DISCO_STATE_REBOOTING 0x03 /* Reboot to BooTTY and copy new image */ - -/* Instructions */ -#define DISCO_CMD_INIT 0x00 /* Prepare flash area for writes */ -#define DISCO_CMD_SWITCH 0x01 /* Copy image from ext. to int. flash */ -#define DISCO_CMD_WRITE 0x02 /* Write Image to Ext Flash */ -#define DISCO_CMD_DONE 0x03 /* All Done */ - -/* Error Codes */ -#define DISCO_ERR_GENERIC 0xFF /* Generic Error */ -#define DISCO_ERR_BAD_LEN 0xFE /* Incorrect Length */ -#define DISCO_ERR_NOT_READY 0xFD /* Not Initialised */ -#define DISCO_ERR_BAD_OFFSET 0xFC /* Bad Offset */ -#define DISCO_ERR_PROTECTED 0xFB /* Target sector is protected */ -#define DISCO_ERR_INIT_DONE 0xFA /* Already Initialized */ - -/* Message Sizes */ -#define DISCO_FLEN_CMD 1 -#define DISCO_FLEN_IMG 1 -#define DISCO_FLEN_ADDR 3 -#define DISCO_FLEN_DATA 64 - -/* Request Lengths */ -#define DISCO_LEN_INIT (DISCO_FLEN_CMD + DISCO_FLEN_IMG) -#define DISCO_LEN_DONE DISCO_FLEN_CMD -#define DISCO_LEN_WRITE (DISCO_FLEN_CMD + DISCO_FLEN_ADDR + DISCO_FLEN_DATA) -#define DISCO_LEN_SWITCH (DISCO_FLEN_CMD + DISCO_FLEN_IMG) - -/* Response Lengths */ -#define DISCO_RESPONSE_NONE 0 -#define DISCO_RESP_LEN_ERR DISCO_FLEN_CMD -#define DISCO_RESP_LEN_INIT DISCO_FLEN_CMD -#define DISCO_RESP_LEN_DONE DISCO_FLEN_CMD -#define DISCO_RESP_LEN_WRITE (DISCO_FLEN_CMD + DISCO_FLEN_ADDR) -#define DISCO_RESP_LEN_SWITCH (DISCO_FLEN_CMD + DISCO_FLEN_IMG) - -/* Tell BooTTy! what to do after we jump: - * BOOTY_CMD - * [7:5]: Command - * [5:4]: Reserved - * [4:0]: Image number - */ -#define BOOTTY_CMD_LOCATION 0xFEFF - -#define BOOTTY_CMD_JUMP_TO_APP 0x80 -#define BOOTTY_CMD_COPY_IMAGE 0x40 - -#define SECTOR_UNPROTECTED 0 -#define SECTOR_PROTECTED 1 -/*---------------------------------------------------------------------------*/ -PROCESS_NAME(disco_process); -/*---------------------------------------------------------------------------*/ -struct disco_request_pdu { - uint8_t cmd; - uint8_t addr[3]; - uint8_t data[DATA_CHUNK_LEN]; -}; - -struct disco_response_pdu { - uint8_t status; - uint8_t addr[3]; -}; - -struct disco_seed { - uip_ipaddr_t addr; - uint16_t port; -}; -/*---------------------------------------------------------------------------*/ -#endif /* DISCO_H_ */ diff --git a/platform/sensinode/putchar.c b/platform/sensinode/putchar.c deleted file mode 100644 index 8d19ef4d3..000000000 --- a/platform/sensinode/putchar.c +++ /dev/null @@ -1,39 +0,0 @@ -/** - * \file - * hardware-specific putchar() routine for sensinode motes - * - * \author - * George Oikonomou - - */ - -#include "contiki-conf.h" -#include "dev/uart1.h" - -/*---------------------------------------------------------------------------*/ -void -putchar(char c) -{ -#if SLIP_ARCH_CONF_ENABLE -#define SLIP_END 0300 - static char debug_frame = 0; - - if(!debug_frame) { /* Start of debug output */ - uart1_writeb(SLIP_END); - uart1_writeb('\r'); /* Type debug line == '\r' */ - debug_frame = 1; - } -#endif - - uart1_writeb((char)c); - -#if SLIP_ARCH_CONF_ENABLE - /* - * Line buffered output, a newline marks the end of debug output and - * implicitly flushes debug output. - */ - if(c == '\n') { - uart1_writeb(SLIP_END); - debug_frame = 0; - } -#endif -} diff --git a/platform/sensinode/segment.rules b/platform/sensinode/segment.rules deleted file mode 100644 index 0dc7a4a60..000000000 --- a/platform/sensinode/segment.rules +++ /dev/null @@ -1,13 +0,0 @@ -# segment.rules - platform/sensinode - -# segment.rules file for code in platform/sensinode -# Please see cpu/cc2430/segment.rules for more info on code segments -# and for rules of thumb on what to do and what not to do - -# Keep main() in HOME -HOME contiki-sensinode-main.c - -# Files with ISRs must be in HOME -HOME platform/sensinode/dev/button-sensor.c - -# segment.rules - platform/sensinode - end diff --git a/platform/sensinode/viztool.c b/platform/sensinode/viztool.c deleted file mode 100644 index e6b2fbed3..000000000 --- a/platform/sensinode/viztool.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Small UDP app used to retrieve neighbor cache and routing table - * entries and send them to an external endpoint - * - * \author - * George Oikonomou - - */ - -#include "contiki.h" -#include "contiki-lib.h" -#include "contiki-net.h" -#include "net/ipv6/uip-ds6-route.h" - -#include - -#define DEBUG DEBUG_NONE -#include "net/ip/uip-debug.h" - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) - -#ifndef VIZTOOL_MAX_PAYLOAD_LEN -#define VIZTOOL_MAX_PAYLOAD_LEN 60 -#endif - -static struct uip_udp_conn *server_conn; -static unsigned char buf[VIZTOOL_MAX_PAYLOAD_LEN]; -static int8_t len; - -#define VIZTOOL_UDP_PORT 60001 - -/* Request Bits */ -#define REQUEST_TYPE_ND 1 -#define REQUEST_TYPE_RT 2 -#define REQUEST_TYPE_DRT 3 -#define REQUEST_TYPE_ADDR 4 -#define REQUEST_TYPE_TOTALS 0xFF - -extern uip_ds6_netif_t uip_ds6_if; -static uip_ds6_route_t *rt; -static uip_ds6_defrt_t *defrt; -static uip_ipaddr_t *addr; -/*---------------------------------------------------------------------------*/ -static uint8_t -process_request() CC_NON_BANKED -{ - uint8_t len; - uint8_t count; /* How many did we pack? */ - uint8_t i; - uint8_t left; - uint8_t entry_size; - uip_ds6_nbr_t *nbr; - - left = VIZTOOL_MAX_PAYLOAD_LEN - 1; - len = 2; /* start filling the buffer from position [2] */ - count = 0; - if(buf[0] == REQUEST_TYPE_ND) { - /* Neighbors */ - PRINTF("Neighbors\n"); - for(nbr = nbr_table_head(ds6_neighbors); - nbr != NULL; - nbr = nbr_table_next(ds6_neighbors, nbr)) { - entry_size = sizeof(i) + sizeof(uip_ipaddr_t) + sizeof(uip_lladdr_t) - + sizeof(nbr->state); - PRINTF("%02u: ", i); - PRINT6ADDR(&nbr->ipaddr); - PRINTF(" - "); - PRINTLLADDR(&nbr->lladdr); - PRINTF(" - %u\n", nbr->state); - - memcpy(buf + len, &i, sizeof(i)); - len += sizeof(i); - memcpy(buf + len, uip_ds6_nbr_get_ipaddr(nbr), sizeof(uip_ipaddr_t)); - len += sizeof(uip_ipaddr_t); - memcpy(buf + len, uip_ds6_nbr_get_ll(nbr), sizeof(uip_lladdr_t)); - len += sizeof(uip_lladdr_t); - memcpy(buf + len, &nbr->state, - sizeof(nbr->state)); - len += sizeof(nbr->state); - - count++; - left -= entry_size; - - if(left < entry_size) { - break; - } - } - } else if(buf[0] == REQUEST_TYPE_RT) { - uint32_t flip = 0; - - PRINTF("Routing table\n"); - rt = uip_ds6_route_head(); - - for(i = buf[1]; i < uip_ds6_route_num_routes(); i++) { - if(rt != NULL) { - entry_size = sizeof(i) + sizeof(rt->ipaddr) - + sizeof(rt->length) - + sizeof(rt->state.lifetime) - + sizeof(rt->state.learned_from); - - memcpy(buf + len, &i, sizeof(i)); - len += sizeof(i); - memcpy(buf + len, &rt->ipaddr, sizeof(rt->ipaddr)); - len += sizeof(rt->ipaddr); - memcpy(buf + len, &rt->length, sizeof(rt->length)); - len += sizeof(rt->length); - - PRINT6ADDR(&rt->ipaddr); - PRINTF(" - %02x", rt->length); - PRINTF(" - "); - PRINT6ADDR(uip_ds6_route_nexthop(rt)); - - flip = uip_htonl(rt->state.lifetime); - memcpy(buf + len, &flip, sizeof(flip)); - len += sizeof(flip); - PRINTF(" - %08lx", rt->state.lifetime); - - memcpy(buf + len, &rt->state.learned_from, - sizeof(rt->state.learned_from)); - len += sizeof(rt->state.learned_from); - - PRINTF(" - %02x [%u]\n", rt->state.learned_from, entry_size); - - count++; - left -= entry_size; - - rt = uip_ds6_route_next(rt); - - if(left < entry_size) { - break; - } - } - } - } else if(buf[0] == REQUEST_TYPE_DRT) { - uint32_t flip = 0; - - PRINTF("Default Route\n"); - addr = uip_ds6_defrt_choose(); - if(addr != NULL) { - defrt = uip_ds6_defrt_lookup(addr); - } - - i = buf[1]; - - if(defrt != NULL && i < 1) { - entry_size = sizeof(i) + sizeof(defrt->ipaddr) - + sizeof(defrt->isinfinite); - - memcpy(buf + len, &i, sizeof(i)); - len += sizeof(i); - memcpy(buf + len, &defrt->ipaddr, sizeof(defrt->ipaddr)); - len += sizeof(defrt->ipaddr); - memcpy(buf + len, &defrt->isinfinite, sizeof(defrt->isinfinite)); - len += sizeof(defrt->isinfinite); - - PRINT6ADDR(&defrt->ipaddr); - PRINTF(" - %u\n", defrt->isinfinite); - count++; - left -= entry_size; - } - } else if(buf[0] == REQUEST_TYPE_ADDR) { - PRINTF("Unicast Addresses\n"); - for(i = buf[1]; i < UIP_DS6_ADDR_NB; i++) { - if(uip_ds6_if.addr_list[i].isused) { - entry_size = sizeof(i) + sizeof(uip_ds6_if.addr_list[i].ipaddr); - - memcpy(buf + len, &i, sizeof(i)); - len += sizeof(i); - memcpy(buf + len, &uip_ds6_if.addr_list[i].ipaddr, - sizeof(uip_ds6_if.addr_list[i].ipaddr)); - len += sizeof(uip_ds6_if.addr_list[i].ipaddr); - - PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); - PRINTF("\n"); - count++; - left -= entry_size; - - if(left < entry_size) { - break; - } - } - } - } else if(buf[0] == REQUEST_TYPE_TOTALS) { - memset(&buf[2], 0, 4); - for(i = 0; i < UIP_DS6_ADDR_NB; i++) { - if(uip_ds6_if.addr_list[i].isused) { - buf[2]++; - } - } - for(nbr = nbr_table_head(ds6_neighbors); - nbr != NULL; - nbr = nbr_table_next(ds6_neighbors, nbr)) { - buf[3]++; - } - - buf[4] = uip_ds6_route_num_routes(); - buf[5] = 1; - - len += 4; - count = 4; - } else { - return 0; - } - buf[1] = count; - return len; -} -/*---------------------------------------------------------------------------*/ -PROCESS(viztool_process, "Network Visualization Tool Process"); -/*---------------------------------------------------------------------------*/ -static void -tcpip_handler(void) CC_NON_BANKED -{ - if(uip_newdata()) { - memset(buf, 0, VIZTOOL_MAX_PAYLOAD_LEN); - - PRINTF("%u bytes from [", uip_datalen()); - PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("]:%u\n", UIP_HTONS(UIP_UDP_BUF->srcport)); - - memcpy(buf, uip_appdata, uip_datalen()); - - len = process_request(); - if(len) { - server_conn->rport = UIP_UDP_BUF->srcport; - uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr); - uip_udp_packet_send(server_conn, buf, len); - PRINTF("Sent %u bytes\n", len); - } - - /* Restore server connection to allow data from any node */ - uip_create_unspecified(&server_conn->ripaddr); - server_conn->rport = 0; - } - return; -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(viztool_process, ev, data) -{ - - PROCESS_BEGIN(); - - server_conn = udp_new(NULL, UIP_HTONS(0), NULL); - udp_bind(server_conn, UIP_HTONS(VIZTOOL_UDP_PORT)); - - while(1) { - PROCESS_YIELD(); - if(ev == tcpip_event) { - tcpip_handler(); - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sky/Makefile.common b/platform/sky/Makefile.common index 2f8b32dc0..ef5c7ad57 100644 --- a/platform/sky/Makefile.common +++ b/platform/sky/Makefile.common @@ -1,7 +1,7 @@ # $Id: Makefile.common,v 1.3 2010/08/24 16:24:11 joxe Exp $ ARCH=spi.c ds2411.c xmem.c i2c.c node-id.c sensors.c cfs-coffee.c \ - cc2420.c cc2420-aes.c cc2420-arch.c cc2420-arch-sfd.c \ + cc2420.c cc2420-arch.c cc2420-arch-sfd.c \ sky-sensors.c uip-ipchksum.c \ uart1.c slip_uart1.c uart1-putchar.c @@ -10,10 +10,6 @@ ifndef CONTIKI_TARGET_MAIN CONTIKI_TARGET_MAIN = contiki-sky-main.c endif -ifeq ($(UIP_CONF_IPV6),1) -CFLAGS += -DWITH_UIP6=1 -endif - ifdef IAR CFLAGS += -D__MSP430F1611__=1 -e --vla -Ohz --multiplier=16s --core=430 --double=32 CFLAGSNO = --dlib_config "$(IAR_PATH)/LIB/DLIB/dl430fn.h" $(CFLAGSWERROR) diff --git a/platform/sky/Makefile.sky b/platform/sky/Makefile.sky index bcceba92f..10101b708 100644 --- a/platform/sky/Makefile.sky +++ b/platform/sky/Makefile.sky @@ -10,7 +10,8 @@ endif include $(CONTIKI)/platform/sky/Makefile.common -MODULES += core/net/ipv6 core/net/ipv4 core/net/rime core/net/mac \ - core/net core/net/ip core/net/rpl \ +MODULES += core/net/mac \ + core/net \ core/net/mac/contikimac core/net/mac/cxmac \ + core/net/llsec core/net/llsec/noncoresec \ dev/cc2420 dev/sht11 dev/ds2411 diff --git a/platform/sky/cfs-coffee-arch.h b/platform/sky/cfs-coffee-arch.h index 08373c5e9..5eb183a42 100644 --- a/platform/sky/cfs-coffee-arch.h +++ b/platform/sky/cfs-coffee-arch.h @@ -59,7 +59,6 @@ #endif #define COFFEE_LOG_SIZE 1024 -#define COFFEE_IO_SEMANTICS 1 #define COFFEE_APPEND_ONLY 0 #define COFFEE_MICRO_LOGS 1 diff --git a/platform/sky/contiki-conf.h b/platform/sky/contiki-conf.h index a4c23734e..7665d146e 100644 --- a/platform/sky/contiki-conf.h +++ b/platform/sky/contiki-conf.h @@ -26,20 +26,28 @@ #endif /* NETSTACK_CONF_RADIO */ #ifndef NETSTACK_CONF_FRAMER +#if NETSTACK_CONF_WITH_IPV6 #define NETSTACK_CONF_FRAMER framer_802154 +#else /* NETSTACK_CONF_WITH_IPV6 */ +#define NETSTACK_CONF_FRAMER contikimac_framer +#endif /* NETSTACK_CONF_WITH_IPV6 */ #endif /* NETSTACK_CONF_FRAMER */ #ifndef CC2420_CONF_AUTOACK #define CC2420_CONF_AUTOACK 1 #endif /* CC2420_CONF_AUTOACK */ +/* The TSCH default slot length of 10ms is a bit too short for this platform, + * use 15ms instead. */ +#define TSCH_CONF_DEFAULT_TIMESLOT_LENGTH 15000 + /* Specify whether the RDC layer should enable per-packet power profiling. */ #define CONTIKIMAC_CONF_COMPOWER 1 #define XMAC_CONF_COMPOWER 1 #define CXMAC_CONF_COMPOWER 1 -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 /* Network setup for IPv6 */ #define NETSTACK_CONF_NETWORK sicslowpan_driver @@ -48,7 +56,6 @@ larger than a specified size, if no ContikiMAC header should be used. */ #define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63 -#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0 #define CXMAC_CONF_ANNOUNCEMENTS 0 #define XMAC_CONF_ANNOUNCEMENTS 0 @@ -57,7 +64,7 @@ #define QUEUEBUF_CONF_NUM 8 #endif -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ /* Network setup for non-IPv6 (rime). */ @@ -86,7 +93,7 @@ #define CC2420_CONF_SFD_TIMESTAMPS 1 #endif /* TIMESYNCH_CONF_ENABLED */ -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define PACKETBUF_CONF_ATTRS_INLINE 1 @@ -132,7 +139,7 @@ #define PROCESS_CONF_STATS 1 /*#define PROCESS_CONF_FASTPOLL 4*/ -#ifdef WITH_UIP6 +#ifdef NETSTACK_CONF_WITH_IPV6 #define LINKADDR_CONF_SIZE 8 @@ -140,53 +147,42 @@ #define UIP_CONF_LLH_LEN 0 #define UIP_CONF_ROUTER 1 -#ifndef UIP_CONF_IPV6_RPL -#define UIP_CONF_IPV6_RPL 1 -#endif /* UIP_CONF_IPV6_RPL */ /* configure number of neighbors and routes */ #ifndef NBR_TABLE_CONF_MAX_NEIGHBORS -#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#define NBR_TABLE_CONF_MAX_NEIGHBORS 16 #endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */ #ifndef UIP_CONF_MAX_ROUTES -#define UIP_CONF_MAX_ROUTES 20 +#define UIP_CONF_MAX_ROUTES 16 #endif /* UIP_CONF_MAX_ROUTES */ #define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_ND6_SEND_NA 0 #define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_RETRANS_TIMER 10000 -#define UIP_CONF_IPV6 1 +#define NETSTACK_CONF_WITH_IPV6 1 #ifndef UIP_CONF_IPV6_QUEUE_PKT #define UIP_CONF_IPV6_QUEUE_PKT 0 #endif /* UIP_CONF_IPV6_QUEUE_PKT */ #define UIP_CONF_IPV6_CHECKS 1 #define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_NETIF_MAX_ADDRESSES 3 -#define UIP_CONF_ND6_MAX_PREFIXES 3 -#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_IP_FORWARD 0 #ifndef UIP_CONF_BUFFER_SIZE #define UIP_CONF_BUFFER_SIZE 240 #endif -#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 -#define SICSLOWPAN_CONF_COMPRESSION_HC1 1 -#define SICSLOWPAN_CONF_COMPRESSION_HC01 2 #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #ifndef SICSLOWPAN_CONF_FRAG #define SICSLOWPAN_CONF_FRAG 1 #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ -#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_IP_FORWARD 1 #define UIP_CONF_BUFFER_SIZE 108 -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_ICMP_DEST_UNREACH 1 @@ -211,7 +207,9 @@ #define UIP_CONF_TCP_SPLIT 0 - +#ifndef AES_128_CONF +#define AES_128_CONF cc2420_aes_128_driver +#endif /* AES_128_CONF */ /* include the project config */ /* PROJECT_CONF_H might be defined in the project Makefile */ diff --git a/platform/sky/contiki-sky-main.c b/platform/sky/contiki-sky-main.c index 646110b31..7fe033900 100644 --- a/platform/sky/contiki-sky-main.c +++ b/platform/sky/contiki-sky-main.c @@ -43,9 +43,9 @@ #include "net/netstack.h" #include "net/mac/frame802154.h" -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 #include "net/ipv6/uip-ds6.h" -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #include "net/rime/rime.h" @@ -72,11 +72,11 @@ static struct timer mgt_timer; #endif extern int msp430_dco_required; -#ifndef WITH_UIP -#define WITH_UIP 0 +#ifndef NETSTACK_CONF_WITH_IPV4 +#define NETSTACK_CONF_WITH_IPV4 0 #endif -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 #include "net/ip/uip.h" #include "net/ipv4/uip-fw.h" #include "net/ipv4/uip-fw-drv.h" @@ -86,17 +86,24 @@ static struct uip_fw_netif slipif = static struct uip_fw_netif meshif = {UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)}; -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ #define UIP_OVER_MESH_CHANNEL 8 -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 static uint8_t is_gateway; -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ #ifdef EXPERIMENT_SETUP #include "experiment-setup.h" #endif +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else /* DEBUG */ +#define PRINTF(...) +#endif /* DEBUG */ + void init_platform(void); /*---------------------------------------------------------------------------*/ @@ -131,7 +138,7 @@ set_rime_addr(void) int i; memset(&addr, 0, sizeof(linkaddr_t)); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(addr.u8, ds2411_id, sizeof(addr.u8)); #else if(node_id == 0) { @@ -144,11 +151,11 @@ set_rime_addr(void) } #endif linkaddr_set_node_addr(&addr); - printf("Rime started with address "); + PRINTF("Rime started with address "); for(i = 0; i < sizeof(addr.u8) - 1; i++) { - printf("%d.", addr.u8[i]); + PRINTF("%d.", addr.u8[i]); } - printf("%d\n", addr.u8[i]); + PRINTF("%d\n", addr.u8[i]); } /*---------------------------------------------------------------------------*/ #if !PROCESS_CONF_NO_PROCESS_NAMES @@ -165,22 +172,22 @@ print_processes(struct process * const processes[]) } #endif /* !PROCESS_CONF_NO_PROCESS_NAMES */ /*--------------------------------------------------------------------------*/ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 static void set_gateway(void) { if(!is_gateway) { leds_on(LEDS_RED); - printf("%d.%d: making myself the IP network gateway.\n\n", + PRINTF("%d.%d: making myself the IP network gateway.\n\n", linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]); - printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n", + PRINTF("IPv4 address of the gateway: %d.%d.%d.%d\n\n", uip_ipaddr_to_quad(&uip_hostaddr)); uip_over_mesh_set_gateway(&linkaddr_node_addr); uip_over_mesh_make_announced_gateway(); is_gateway = 1; } } -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ /*---------------------------------------------------------------------------*/ #if WITH_TINYOS_AUTO_IDS uint16_t TOS_NODE_ID = 0x1234; /* non-zero */ @@ -217,6 +224,10 @@ main(int argc, char **argv) * Hardware initialization done! */ + /* Initialize energest first (but after rtimer) + */ + energest_init(); + ENERGEST_ON(ENERGEST_TYPE_CPU); #if WITH_TINYOS_AUTO_IDS node_id = TOS_NODE_ID; @@ -245,9 +256,9 @@ main(int argc, char **argv) ctimer_init(); -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 slip_arch_init(BAUD2UBR(115200)); -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ init_platform(); @@ -262,86 +273,89 @@ main(int argc, char **argv) linkaddr_node_addr.u8[1]; memset(longaddr, 0, sizeof(longaddr)); linkaddr_copy((linkaddr_t *)&longaddr, &linkaddr_node_addr); - printf("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ", + PRINTF("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ", longaddr[0], longaddr[1], longaddr[2], longaddr[3], longaddr[4], longaddr[5], longaddr[6], longaddr[7]); cc2420_set_pan_addr(IEEE802154_PANID, shortaddr, longaddr); } - printf(CONTIKI_VERSION_STRING " started. "); + PRINTF(CONTIKI_VERSION_STRING " started. "); if(node_id > 0) { - printf("Node id is set to %u.\n", node_id); + PRINTF("Node id is set to %u.\n", node_id); } else { - printf("Node id is not set.\n"); + PRINTF("Node id is not set.\n"); } - /* printf("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + /* PRINTF("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", ds2411_id[0], ds2411_id[1], ds2411_id[2], ds2411_id[3], ds2411_id[4], ds2411_id[5], ds2411_id[6], ds2411_id[7]);*/ -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(&uip_lladdr.addr, ds2411_id, sizeof(uip_lladdr.addr)); /* Setup nullmac-like MAC for 802.15.4 */ /* sicslowpan_init(sicslowmac_init(&cc2420_driver)); */ -/* printf(" %s channel %u\n", sicslowmac_driver.name, CC2420_CONF_CCA_THRESH); */ +/* PRINTF(" %s channel %u\n", sicslowmac_driver.name, CC2420_CONF_CCA_THRESH); */ /* Setup X-MAC for 802.15.4 */ queuebuf_init(); NETSTACK_RDC.init(); NETSTACK_MAC.init(); + NETSTACK_LLSEC.init(); NETSTACK_NETWORK.init(); - printf("%s %s, channel check rate %lu Hz, radio channel %u, CCA threshold %i\n", - NETSTACK_MAC.name, NETSTACK_RDC.name, + PRINTF("%s %s %s, channel check rate %lu Hz, radio channel %u, CCA threshold %i\n", + NETSTACK_LLSEC.name, NETSTACK_MAC.name, NETSTACK_RDC.name, CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1: NETSTACK_RDC.channel_check_interval()), CC2420_CONF_CHANNEL, CC2420_CONF_CCA_THRESH); - + process_start(&tcpip_process, NULL); - printf("Tentative link-local IPv6 address "); +#if DEBUG + PRINTF("Tentative link-local IPv6 address "); { uip_ds6_addr_t *lladdr; int i; lladdr = uip_ds6_get_link_local(-1); for(i = 0; i < 7; ++i) { - printf("%02x%02x:", lladdr->ipaddr.u8[i * 2], + PRINTF("%02x%02x:", lladdr->ipaddr.u8[i * 2], lladdr->ipaddr.u8[i * 2 + 1]); } - printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]); + PRINTF("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]); } +#endif /* DEBUG */ if(!UIP_CONF_IPV6_RPL) { uip_ipaddr_t ipaddr; int i; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE); - printf("Tentative global IPv6 address "); + PRINTF("Tentative global IPv6 address "); for(i = 0; i < 7; ++i) { - printf("%02x%02x:", + PRINTF("%02x%02x:", ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]); } - printf("%02x%02x\n", + PRINTF("%02x%02x\n", ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]); } - -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ NETSTACK_RDC.init(); NETSTACK_MAC.init(); + NETSTACK_LLSEC.init(); NETSTACK_NETWORK.init(); - printf("%s %s, channel check rate %lu Hz, radio channel %u\n", - NETSTACK_MAC.name, NETSTACK_RDC.name, + PRINTF("%s %s %s, channel check rate %lu Hz, radio channel %u\n", + NETSTACK_LLSEC.name, NETSTACK_MAC.name, NETSTACK_RDC.name, CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0? 1: NETSTACK_RDC.channel_check_interval()), - CC2420_CONF_CCA_THRESH); -#endif /* WITH_UIP6 */ + CC2420_CONF_CHANNEL); +#endif /* NETSTACK_CONF_WITH_IPV6 */ -#if !WITH_UIP && !WITH_UIP6 +#if !NETSTACK_CONF_WITH_IPV4 && !NETSTACK_CONF_WITH_IPV6 uart1_set_input(serial_line_input_byte); serial_line_init(); #endif @@ -353,7 +367,7 @@ main(int argc, char **argv) timesynch_set_authority_level((linkaddr_node_addr.u8[0] << 4) + 16); #endif /* TIMESYNCH_CONF_ENABLED */ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 process_start(&tcpip_process, NULL); process_start(&uip_fw_process, NULL); /* Start IP output */ process_start(&slip_process, NULL); @@ -377,20 +391,15 @@ main(int argc, char **argv) uip_over_mesh_set_gateway_netif(&slipif); uip_fw_default(&meshif); uip_over_mesh_init(UIP_OVER_MESH_CHANNEL); - printf("uIP started with IP address %d.%d.%d.%d\n", + PRINTF("uIP started with IP address %d.%d.%d.%d\n", uip_ipaddr_to_quad(&hostaddr)); } -#endif /* WITH_UIP */ - - energest_init(); - ENERGEST_ON(ENERGEST_TYPE_CPU); - +#endif /* NETSTACK_CONF_WITH_IPV4 */ + watchdog_start(); #if !PROCESS_CONF_NO_PROCESS_NAMES print_processes(autostart_processes); -#else /* !PROCESS_CONF_NO_PROCESS_NAMES */ - putchar('\n'); /* include putchar() */ #endif /* !PROCESS_CONF_NO_PROCESS_NAMES */ autostart_start(autostart_processes); @@ -433,8 +442,7 @@ main(int argc, char **argv) #endif /* Re-enable interrupts and go to sleep atomically. */ - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* We only want to measure the processing done in IRQs when we are asleep, so we discard the processing time done when we were awake. */ @@ -457,8 +465,7 @@ main(int argc, char **argv) irq_energest = energest_type_time(ENERGEST_TYPE_IRQ); eint(); watchdog_start(); - ENERGEST_OFF(ENERGEST_TYPE_LPM); - ENERGEST_ON(ENERGEST_TYPE_CPU); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } } diff --git a/platform/sky/dev/light.c b/platform/sky/dev/light.c deleted file mode 100644 index 53f610fa9..000000000 --- a/platform/sky/dev/light.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -#include -#include "contiki.h" -#include "dev/light.h" - -/* - * Initialize periodic readings from the 2 photo diodes. The most - * recent readings will be stored in ADC internal registers/memory. - */ -void -sensors_light_init(void) -{ - P6SEL |= 0x30; - P6DIR = 0xff; - P6OUT = 0x00; - - /* Set up the ADC. */ - ADC12CTL0 = REF2_5V + SHT0_6 + SHT1_6 + MSC; // Setup ADC12, ref., sampling time - ADC12CTL1 = SHP + CONSEQ_3 + CSTARTADD_0; // Use sampling timer, repeat-sequenc-of-channels - - ADC12MCTL0 = (INCH_4 + SREF_0); // photodiode 1 (P64) - ADC12MCTL1 = (INCH_5 + SREF_0); // photodiode 2 (P65) - - ADC12CTL0 |= ADC12ON + REFON; - - ADC12CTL0 |= ENC; // enable conversion - ADC12CTL0 |= ADC12SC; // sample & convert -} - -/* Photosynthetically Active Radiation. */ -unsigned -sensors_light1(void) -{ - return ADC12MEM0; -} - -/* Total Solar Radiation. */ -unsigned -sensors_light2(void) -{ - return ADC12MEM1; -} - -/* - * Most of this information taken from - * http://www.moteiv.com/community/Getting_Data_from_Tmote_Sky%27s_Sensors - * - * The Photosynthetically Active Radiation (PAR) sensor as well as the - * Total Solar Radiation (TSR) sensor uses the 2.5V reference voltage - * to produce the raw ADC value. - - * The voltage across each sensor is: - * - * VsensorPAR = ADCValuePAR/4096 * Vref (1a) - * VsensorTSR = ADCValueTSR/4096 * Vref (1b) - * where Vref = 2.5V - * - * This voltage creates a current through a resistor R=100KOhm and this - * current has a linear relationship with the light intensity in Lux. - * IPAR = VsensorPAR / 100,000 (2a) - * ITSR = VsensorTSR / 100,000 (2b) - * - * S1087 (PAR) lx = 1e6 * IPAR * 1000 (3a) - * S1087-01 (TSR) lx = 1e5 * ITSR * 1000 (3b) - * - * lxPAR = 10e9 * ADCValuePAR *(1/4096)* Vref * 10e-5 or - * lxPAR = 3125* ADCvaluePAR / 512 - * and - * lxTSR = 10e8 * ADCValueTSR *(1/4096)* Vref * 10e-5 or - * lxTSR = 625* ADCvalueTSR / 1024 -*/ - -#if 0 -/* Photosynthetically Active Radiation in Lux units. */ -unsigned -sensors_light1_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM0; - - temp = (temp*3125)>> 9; - return (uint16_t)(temp & 0xFFFF); -} - -/* Total Solar Radiation in Lux units. */ -unsigned -sensors_light2_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM1; - - temp = (temp*625)>> 10; - return (uint16_t)(temp & 0xFFFF); -} -#endif diff --git a/platform/sky/platform-conf.h b/platform/sky/platform-conf.h index e597a208f..5ba273047 100644 --- a/platform/sky/platform-conf.h +++ b/platform/sky/platform-conf.h @@ -46,11 +46,21 @@ /* Platform TMOTE_SKY */ #define TMOTE_SKY 1 +/* Delay between GO signal and SFD: radio fixed delay + 4Bytes preample + 1B SFD -- 1Byte time is 32us + * ~327us + 129preample = 456 us */ +#define RADIO_DELAY_BEFORE_TX ((unsigned)US_TO_RTIMERTICKS(456)) +/* Delay between GO signal and start listening + * ~50us delay + 129preample + ?? = 183 us */ +#define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(183)) +/* Delay between the SFD finishes arriving and it is detected in software */ +#define RADIO_DELAY_BEFORE_DETECT 0 + #define PLATFORM_HAS_LEDS 1 #define PLATFORM_HAS_BUTTON 1 #define PLATFORM_HAS_LIGHT 1 #define PLATFORM_HAS_BATTERY 1 #define PLATFORM_HAS_SHT11 1 +#define PLATFORM_HAS_RADIO 1 /* CPU target speed in Hz */ #define F_CPU 3900000uL /*2457600uL*/ @@ -70,7 +80,7 @@ /* Types for clocks and uip_stats */ typedef unsigned short uip_stats_t; typedef unsigned long clock_time_t; -typedef unsigned long off_t; +typedef long off_t; /* the low-level radio driver */ #define NETSTACK_CONF_RADIO cc2420_driver diff --git a/platform/srf06-cc26xx/Makefile.srf06-cc26xx b/platform/srf06-cc26xx/Makefile.srf06-cc26xx new file mode 100644 index 000000000..a5f82493c --- /dev/null +++ b/platform/srf06-cc26xx/Makefile.srf06-cc26xx @@ -0,0 +1,37 @@ +# srf06-cc26xx platform makefile + +ifndef CONTIKI + $(error CONTIKI not defined! You must specify where CONTIKI resides!) +endif + +### Board and BSP selection +ifeq ($(BOARD),) + BOARD=srf06/cc26xx +endif + +CONTIKI_TARGET_DIRS += . + +### Include the board-specific makefile +PLATFORM_ROOT_DIR = $(CONTIKI)/platform/$(TARGET) +-include $(PLATFORM_ROOT_DIR)/$(BOARD)/Makefile.$(notdir $(BOARD)) + +CONTIKI_TARGET_SOURCEFILES += contiki-main.c +CONTIKI_TARGET_SOURCEFILES += sensors.c leds.c +CONTIKI_TARGET_SOURCEFILES += $(BOARD_SOURCEFILES) + +CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) + +CLEAN += *.srf06-cc26xx + +### Unless the example dictates otherwise, build with code size optimisations +ifndef SMALL + SMALL = 0 +endif + +### Define the CPU directory and pull in the correct CPU makefile. This will +### be defined by one of the makefiles included above and it can be either +### Makefile.cc26xx or Makefile.cc13xx +CONTIKI_CPU=$(CONTIKI)/cpu/cc26xx-cc13xx +include $(CONTIKI_CPU)/Makefile.$(CPU_FAMILY) + +MODULES += core/net core/net/mac core/net/mac/contikimac core/net/llsec diff --git a/platform/srf06-cc26xx/README.md b/platform/srf06-cc26xx/README.md new file mode 100644 index 000000000..04d66a0d4 --- /dev/null +++ b/platform/srf06-cc26xx/README.md @@ -0,0 +1,236 @@ +Getting Started with Contiki for TI CC26xx +========================================== + +This guide's aim is to help you start using Contiki for TI's CC26xx. The +platform supports two different boards: + +* SmartRF 06 Evaluation Board with a CC26xx or CC13xx Evaluation Module + (relevant files and drivers are under `srf06/`) +* CC2650 SensorTag 2.0 (relevant drivers under `sensortag/cc2650`) +* CC2650 LaunchPad (relevant drivers under `launchpad/cc2650`) +* CC1310 LaunchPad (relevant drivers under `launchpad/cc1310`) + +The CPU code, common for both platforms, can be found under `$(CONTIKI)/cpu/cc26xx-cc13xx`. +The port was developed and tested with CC2650s, but the intention is for it to +work with the CC2630 as well. Thus, bug reports are welcome for both chips. +Bear in mind that the CC2630 does not have BLE capability. + +This port is only meant to work with 7x7mm chips + +This guide assumes that you have basic understanding of how to use the command +line and perform basic admin tasks on UNIX family OSs. + +Port Features +============= +The platform has the following key features: + +* Deep Sleep support with RAM retention for ultra-low energy consumption. +* Support for CC26xx RF in IEEE as well as BLE mode (BLE support is very basic + since Contiki does not provide a BLE stack). +* Support for CC13xx prop mode: IEEE 802.15.4g-compliant sub GHz operation + +In terms of hardware support, the following drivers have been implemented: + +* SmartRF06 EB peripherals + * LEDs + * Buttons + * UART connectivity over the XDS100v3 backchannel +* SensorTag 2.0 + * LEDs + * Buttons (One of the buttons can be used as a shutdown button) + * Reed relay + * Motion Processing Unit (MPU9250 - Accelerometer, Gyro) + * BMP280 sensor + * TMP007 sensor + * HDC1000 sensor + * OPT3001 sensor + * Buzzer + * External SPI flash +* LaunchPads + * LEDs + * Buttons + * External SPI flash + +Requirements +============ +To use the port you need: + +* TI's CC26xxware sources. The correct version will be installed automatically + as a submodule when you clone Contiki. +* TI's CC13xxware sources. The correct version will be installed automatically + as a submodule when you clone Contiki. +* Contiki can automatically upload firmware to the nodes over serial with the + included [cc2538-bsl script](https://github.com/JelmerT/cc2538-bsl). + Note that uploading over serial doesn't work for the Sensortag, you can use + TI's SmartRF Flash Programmer in this case. +* A toolchain to build firmware: The port has been developed and tested with + GNU Tools for ARM Embedded Processors (). + The current recommended version and the one being used by Contiki's regression + tests on Travis is shown below. + + $ arm-none-eabi-gcc --version + arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 5.2.1 20151202 (release) [ARM/embedded-5-branch revision 231848] + Copyright (C) 2015 Free Software Foundation, Inc. + This is free software; see the source for copying conditions. There is NO + warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +* srecord (http://srecord.sourceforge.net/) +* You may also need other drivers so that the SmartRF can communicate with your +operating system and so that you can use the chip's UART for I/O. Please read +the section ["Drivers" in the CC2538DK readme](https://github.com/contiki-os/contiki/tree/master/platform/cc2538dk#drivers). + +Examples +======== +The port comes with three examples: +- A very basic example which demonstrates how to read sensors and how to use board peripherals. It also demonstrates how to send out BLE advertisements. +- A more advanced one (web demo) which includes a CoAP server, an MQTT client which connects and publishes to the IBM quickstart service, a net-based UART and lastly a web server that can be used to configure the rest of the example. +- An example demonstrating a very sleepy node. + +More details about those three examples can be found in their respective READMEs. + +Build your First Example +------------------------ +It is recommended to start with the `cc26xx-demo` example under `examples/cc26xx/`. This is a very simple example which will help you get familiar with the hardware and the environment. This example can be used for the Sensortag and SmartRF06 EB. + +Strictly speaking, to build it you need to run `make TARGET=srf06-cc26xx BOARD=srf06/cc26xx`. However, the example directories contain a `Makefile.target` which is automatically included and specifies the correct `TARGET=` argument. The `BOARD=` environment variable defaults to `srf06/cc26xx` (which is the SmartRF06 EB + CC26XXEM). Thus, for examples under the `cc26xx` directory, and when using the SmartRF06 EB, you can simply run `make`. + +Other options for the `BOARD` make variable are: + +* Srf06+CC26xxEM: Set `BOARD=srf06/cc26xx` +* Srf06+CC13xxEM: Set `BOARD=srf06/cc13xx` +* CC2650 tag: Set `BOARD=sensortag/cc2650` +* CC2650 Launchpad: Set `BOARD=launchpad/cc2650` +* CC1310 Launchpad: Set `BOARD=launchpad/cc1310` + +If the `BOARD` variable is unspecified, an image for the Srf06 CC26XXEM will be built. + +If you want to switch between building for one platform to the other, make certain to `make clean` before building for the new one, or you will get linker +errors. + +If you want to upload the compiled firmware to a node via the serial boot loader you need to manually enable the boot loader and then use `make cc26xx-demo.upload`. On the SmartRF06 board you enable the boot loader by resetting the board (EM RESET button) while holding the `select` button. (The boot loader backdoor needs to be enabled on the chip, and the chip needs to be configured correctly, for this to work. See README in the `tools/cc2538-bsl` directory for more info). The serial uploader script will automatically pick the first available serial port. If this is not the port where your node is connected, you can force the script to use a specific port by defining the `PORT` argument eg. `make cc26xx-demo.upload PORT=/dev/tty.usbserial` + +The serial bootloader can also be used with the LaunchPad and the changes required to achieve this are the same as those required for the SmartRF. The only difference is that you will need to map `BL_PIN_NUMBER` to either the left or right user button (values to be used for `BL_PIN_NUMBER` in `ccfg.c` are `0x0D` and `0x0E` respectively). + +Note that uploading over serial doesn't work for the Sensortag, you can use TI's SmartRF Flash Programmer in this case. + +For the `cc26xx-demo`, the included readme describes in detail what the example does. + +To generate an assembly listing of the compiled firmware, run `make cc26xx-demo.lst`. This may be useful for debugging or optimizing your application code. To intersperse the C source code within the assembly listing, you must instruct the compiler to include debugging information by adding `CFLAGS += -g` to the project Makefile and rebuild by running `make clean cc26xx-demo.lst`. + +CC13xx/CC26xx Border Router over UART +===================================== +The platform code can be used as a border router (SLIP over UART) by using the +example under `examples/ipv6/rpl-border-router`. This example defines the +following: + + + #ifndef UIP_CONF_BUFFER_SIZE + #define UIP_CONF_BUFFER_SIZE 140 + #endif + + #ifndef UIP_CONF_RECEIVE_WINDOW + #define UIP_CONF_RECEIVE_WINDOW 60 + #endif + +The CC26xx port has much higher capability than some other platforms used as +border routers. Thus, before building the example, it is recommended to delete +these two configuration directives. This will allow platform defaults to take +effect and this will improve performance and stability. + +Do not forget to set the correct channel by defining `RF_CORE_CONF_CHANNEL` as +required. + +CC13xx/CC26xx slip-radio with 6lbr +================================== +The platform can also operate as a slip-radio over UART, to be used with +[6lbr](http://cetic.github.io/6lbr/). + +Similar to the border router configuration, you will need to remove the defines +that limit the size of the uIP buffer. Removing the two lines below from +`examples/ipv6/slip-radio/project-conf.h` should do it. + + #undef UIP_CONF_BUFFER_SIZE + #define UIP_CONF_BUFFER_SIZE 140 + +Do not forget to set the correct channel by defining `RF_CORE_CONF_CHANNEL` as +required. + +Filename conflicts between Contiki and CC26xxware +================================================= +There is a file called `timer.c` both in Contiki as well as in CC26xxware. The +way things are configured now, we don't use the latter. However, if you need to +start using it at some point, you will need to rename it: + +From `cpu/cc26xx/lib/cc26xxware/driverlib/timer.c` to `driverlib-timer.c` + +Sensortag UART usage (with or without the Debugger Devpack) +=========================================================== +There are two ways to get debugging (printf etc) output from the Sensortag. + +* Purchase a Debugger Devpack and set `BOARD_CONF_DEBUGGER_DEVPACK` to 1 in +`contiki-conf.h` or `project-conf.h`. This will work off the shelf for revision +1.2.0 of the debugger devpack. +* If you have an older (rev 1.0.0) devpack, you will need to do the above and +then to modify `board.h` in order to cross the RX and TX DIO mappings. (TX to +`IOID_28`, RX to `IOID_29`). +* If you don't have/want a debugger devpack, you can use a SmartRF and modify +the jumper configuration on P408 as discussed in +[this thread](https://e2e.ti.com/support/wireless_connectivity/f/158/p/411992/1483824#1483824) +on E2E. For this to work, you need to set `BOARD_CONF_DEBUGGER_DEVPACK` to 0. + +Low Power Operation +=================== +The platform takes advantage of the CC26xx's power saving features. In a +nutshell, here is how things work: + +* When the RF is TXing, the CPU will enter sleep mode and will resume after TX + has completed. +* When there are no events in the Contiki event queue, the chip will enter + 'some' low power mode (more below). + +We do not use pre-defined power profiles (e.g. as mentioned in the TRM or as +we do for the CC2538 with LPM1, LPM2 etc). Each time we enter low power +operation, we either put the CM3 to sleep or to deep sleep. The latter case is +highly configurable: the LPM engine allows other code modules to register +themselves for notifications and to configure low power operation. With these +facilities, a module can e.g. prohibit deep sleep altogether, or it can request +that a power domain be kept powered. The LPM engine will turn off as many +CC26xx components as it can while satisfying all restrictions set by registered +modules. + +To determine which power mode to use, the following logic is followed: + +* The deepest available low power mode can be hard-coded by using + the `LPM_MODE_MAX_SUPPORTED` macro in the LPM driver (`lpm.[ch]`). Thus, it + is possible to prohibit deep sleep altogether. +* Code modules which are affected by low power operation can 'register' + themselves with the LPM driver. +* If the projected low-power duration is lower than `STANDBY_MIN_DURATION`, + the chip will simply sleep. +* If the projected low power duration is sufficiently long, the LPM will visit + all registered modules to query the maximum allowed power mode (maximum means + sleep vs deep sleep in this context). It will then drop to this power mode. + This is where a code module can forbid deep sleep if required. +* All registered modules will be notified when the chip is about to enter + deep sleep, as well as after wake-up. + +When the chip does enter deep sleep: + +* The RF Core, VIMS, SYSBUS and CPU power domains are always turned off. Due to + the way the RF driver works, the RFCORE PD should be off already. +* Peripheral clocks stop +* The Serial and Peripheral power domains are turned off, unless an LPM module + requests them to stay operational. For example, the net-uart demo keeps the + serial power domain powered on and the UART clocked under sleep and deep + sleep in order to retain UART RX functionality. +* If both SERIAL and PERIPH PDs are turned off, we also switch power source to + the uLDO for ultra low leakage under deep sleep. + +The chip will come out of low power mode by one of the following events: + +* Button press or, in the case of the SensorTag, a reed relay trigger +* Software clock tick (timer). The clock ticks at 128Hz, therefore the maximum + time we will ever spend in a sleep mode is 7.8125ms. In hardware terms, this + is an AON RTC Channel 2 compare interrupt. +* Rtimer triggers, as part of ContikiMAC's sleep/wake-up cycles. The rtimer + sits on the AON RTC channel 0. diff --git a/platform/srf06-cc26xx/common/board-spi.c b/platform/srf06-cc26xx/common/board-spi.c new file mode 100644 index 000000000..fb9fecd63 --- /dev/null +++ b/platform/srf06-cc26xx/common/board-spi.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-spi + * @{ + * + * \file + * Board-specific SPI driver common to the Sensortag and LaunchPad + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "ti-lib.h" +#include "board-spi.h" +#include "board.h" + +#include +/*---------------------------------------------------------------------------*/ +static bool +accessible(void) +{ + /* First, check the PD */ + if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL) + != PRCM_DOMAIN_POWER_ON) { + return false; + } + + /* Then check the 'run mode' clock gate */ + if(!(HWREG(PRCM_BASE + PRCM_O_SSICLKGR) & PRCM_SSICLKGR_CLK_EN_SSI0)) { + return false; + } + + return true; +} +/*---------------------------------------------------------------------------*/ +bool +board_spi_write(const uint8_t *buf, size_t len) +{ + if(accessible() == false) { + return false; + } + + while(len > 0) { + uint32_t ul; + + ti_lib_ssi_data_put(SSI0_BASE, *buf); + ti_lib_rom_ssi_data_get(SSI0_BASE, &ul); + len--; + buf++; + } + + return true; +} +/*---------------------------------------------------------------------------*/ +bool +board_spi_read(uint8_t *buf, size_t len) +{ + if(accessible() == false) { + return false; + } + + while(len > 0) { + uint32_t ul; + + if(!ti_lib_rom_ssi_data_put_non_blocking(SSI0_BASE, 0)) { + /* Error */ + return false; + } + ti_lib_rom_ssi_data_get(SSI0_BASE, &ul); + *buf = (uint8_t)ul; + len--; + buf++; + } + return true; +} +/*---------------------------------------------------------------------------*/ +void +board_spi_flush() +{ + if(accessible() == false) { + return; + } + + uint32_t ul; + while(ti_lib_rom_ssi_data_get_non_blocking(SSI0_BASE, &ul)); +} +/*---------------------------------------------------------------------------*/ +void +board_spi_open(uint32_t bit_rate, uint32_t clk_pin) +{ + uint32_t buf; + + /* First, make sure the SERIAL PD is on */ + ti_lib_prcm_power_domain_on(PRCM_DOMAIN_SERIAL); + while((ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL) + != PRCM_DOMAIN_POWER_ON)); + + /* Enable clock in active mode */ + ti_lib_rom_prcm_peripheral_run_enable(PRCM_PERIPH_SSI0); + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + /* SPI configuration */ + ti_lib_ssi_int_disable(SSI0_BASE, SSI_RXOR | SSI_RXFF | SSI_RXTO | SSI_TXFF); + ti_lib_ssi_int_clear(SSI0_BASE, SSI_RXOR | SSI_RXTO); + ti_lib_rom_ssi_config_set_exp_clk(SSI0_BASE, ti_lib_sys_ctrl_clock_get(), + SSI_FRF_MOTO_MODE_0, + SSI_MODE_MASTER, bit_rate, 8); + ti_lib_rom_ioc_pin_type_ssi_master(SSI0_BASE, BOARD_IOID_SPI_MISO, + BOARD_IOID_SPI_MOSI, IOID_UNUSED, clk_pin); + ti_lib_ssi_enable(SSI0_BASE); + + /* Get rid of residual data from SSI port */ + while(ti_lib_ssi_data_get_non_blocking(SSI0_BASE, &buf)); +} +/*---------------------------------------------------------------------------*/ +void +board_spi_close() +{ + /* Power down SSI0 */ + ti_lib_rom_prcm_peripheral_run_disable(PRCM_PERIPH_SSI0); + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + /* Restore pins to a low-consumption state */ + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SPI_MISO); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_SPI_MISO, IOC_IOPULL_DOWN); + + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SPI_MOSI); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_SPI_MOSI, IOC_IOPULL_DOWN); + + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SPI_CLK_FLASH); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_SPI_CLK_FLASH, IOC_IOPULL_DOWN); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/common/board-spi.h b/platform/srf06-cc26xx/common/board-spi.h new file mode 100644 index 000000000..3699db120 --- /dev/null +++ b/platform/srf06-cc26xx/common/board-spi.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-srf-tag + * @{ + * + * \defgroup common-cc26xx-peripherals CC13xx/CC26xx peripheral driver pool + * + * Drivers for peripherals present on more than one CC13xx/CC26xx board. For + * example, the same external flash driver is used for both the part found on + * the Sensortag as well as the part on the LaunchPad. + * + * @{ + * + * \defgroup sensortag-cc26xx-spi SensorTag/LaunchPad SPI functions + * @{ + * + * \file + * Header file for the Sensortag/LaunchPad SPI Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef BOARD_SPI_H_ +#define BOARD_SPI_H_ +/*---------------------------------------------------------------------------*/ +#include +#include +#include +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize the SPI interface + * \param bit_rate The bit rate to use + * \param clk_pin The IOID for the clock pin. This can be IOID_0 etc + * \return none + * + * This function will make sure the peripheral is powered, clocked and + * initialised. A chain of calls to board_spi_read(), board_spi_write() and + * board_spi_flush() must be preceded by a call to this function. It is + * recommended to call board_spi_close() after such chain of calls. + */ +void board_spi_open(uint32_t bit_rate, uint32_t clk_pin); + +/** + * \brief Close the SPI interface + * \return True when successful. + * + * This function will stop clocks to the SSI module and will set MISO, MOSI + * and CLK to a low leakage state. It is recommended to call this function + * after a chain of calls to board_spi_read() and board_spi_write() + */ +void board_spi_close(void); + +/** + * \brief Clear data from the SPI interface + * \return none + */ +void board_spi_flush(void); + +/** + * \brief Read from an SPI device + * \param buf The buffer to store data + * \param length The number of bytes to read + * \return True when successful. + * + * Calls to this function must be preceded by a call to board_spi_open(). It is + * recommended to call board_spi_close() at the end of an operation. + */ +bool board_spi_read(uint8_t *buf, size_t length); + +/** + * \brief Write to an SPI device + * \param buf The buffer with the data to write + * \param length The number of bytes to write + * \return True when successful. + * + * Calls to this function must be preceded by a call to board_spi_open(). It is + * recommended to call board_spi_close() at the end of an operation. + */ +bool board_spi_write(const uint8_t *buf, size_t length); +/*---------------------------------------------------------------------------*/ +#endif /* BOARD_SPI_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/common/ext-flash.c b/platform/srf06-cc26xx/common/ext-flash.c new file mode 100644 index 000000000..62fea2288 --- /dev/null +++ b/platform/srf06-cc26xx/common/ext-flash.c @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-ext-flash + * @{ + * + * \file + * Driver for the LaunchPad Flash and the Sensortag WinBond W25X20CL/W25X40CL + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "ext-flash.h" +#include "ti-lib.h" +#include "board-spi.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/* Instruction codes */ + +#define BLS_CODE_PROGRAM 0x02 /**< Page Program */ +#define BLS_CODE_READ 0x03 /**< Read Data */ +#define BLS_CODE_READ_STATUS 0x05 /**< Read Status Register */ +#define BLS_CODE_WRITE_ENABLE 0x06 /**< Write Enable */ +#define BLS_CODE_SECTOR_ERASE 0x20 /**< Sector Erase */ +#define BLS_CODE_MDID 0x90 /**< Manufacturer Device ID */ + +#define BLS_CODE_PD 0xB9 /**< Power down */ +#define BLS_CODE_RPD 0xAB /**< Release Power-Down */ +/*---------------------------------------------------------------------------*/ +/* Erase instructions */ + +#define BLS_CODE_ERASE_4K 0x20 /**< Sector Erase */ +#define BLS_CODE_ERASE_32K 0x52 +#define BLS_CODE_ERASE_64K 0xD8 +#define BLS_CODE_ERASE_ALL 0xC7 /**< Mass Erase */ +/*---------------------------------------------------------------------------*/ +/* Bitmasks of the status register */ + +#define BLS_STATUS_SRWD_BM 0x80 +#define BLS_STATUS_BP_BM 0x0C +#define BLS_STATUS_WEL_BM 0x02 +#define BLS_STATUS_WIP_BM 0x01 + +#define BLS_STATUS_BIT_BUSY 0x01 /**< Busy bit of the status register */ +/*---------------------------------------------------------------------------*/ +/* Part specific constants */ +#define BLS_DEVICE_ID_W25X20CL 0x11 +#define BLS_DEVICE_ID_W25X40CL 0x12 +#define BLS_DEVICE_ID_MX25R8035F 0x14 +#define BLS_DEVICE_ID_MX25R1635F 0x15 + +#define BLS_WINBOND_MID 0xEF +#define BLS_MACRONIX_MID 0xC2 + +#define BLS_PROGRAM_PAGE_SIZE 256 +#define BLS_ERASE_SECTOR_SIZE 4096 +/*---------------------------------------------------------------------------*/ +#define VERIFY_PART_ERROR -1 +#define VERIFY_PART_POWERED_DOWN 0 +#define VERIFY_PART_OK 1 +/*---------------------------------------------------------------------------*/ +/** + * Clear external flash CSN line + */ +static void +select_on_bus(void) +{ + ti_lib_gpio_pin_write(BOARD_FLASH_CS, 0); +} +/*---------------------------------------------------------------------------*/ +/** + * Set external flash CSN line + */ +static void +deselect(void) +{ + ti_lib_gpio_pin_write(BOARD_FLASH_CS, 1); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Wait till previous erase/program operation completes. + * \return True when successful. + */ +static bool +wait_ready(void) +{ + bool ret; + const uint8_t wbuf[1] = { BLS_CODE_READ_STATUS }; + + select_on_bus(); + + /* Throw away all garbages */ + board_spi_flush(); + + ret = board_spi_write(wbuf, sizeof(wbuf)); + + if(ret == false) { + deselect(); + return false; + } + + for(;;) { + uint8_t buf; + /* Note that this temporary implementation is not + * energy efficient. + * Thread could have yielded while waiting for flash + * erase/program to complete. + */ + ret = board_spi_read(&buf, sizeof(buf)); + + if(ret == false) { + /* Error */ + deselect(); + return false; + } + if(!(buf & BLS_STATUS_BIT_BUSY)) { + /* Now ready */ + break; + } + } + deselect(); + return true; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Verify the flash part. + * \retval VERIFY_PART_OK The part was identified successfully + * \retval VERIFY_PART_ERROR There was an error communicating with the part + * \retval VERIFY_PART_POWERED_DOWN Communication was successful, but the part + * was powered down + */ +static uint8_t +verify_part(void) +{ + const uint8_t wbuf[] = { BLS_CODE_MDID, 0xFF, 0xFF, 0x00 }; + uint8_t rbuf[2] = { 0, 0 }; + bool ret; + + select_on_bus(); + + ret = board_spi_write(wbuf, sizeof(wbuf)); + + if(ret == false) { + deselect(); + return VERIFY_PART_ERROR; + } + + ret = board_spi_read(rbuf, sizeof(rbuf)); + deselect(); + + if(ret == false) { + return VERIFY_PART_ERROR; + } + + if((rbuf[0] != BLS_WINBOND_MID && rbuf[0] != BLS_MACRONIX_MID) || + (rbuf[1] != BLS_DEVICE_ID_W25X20CL && rbuf[1] != BLS_DEVICE_ID_W25X40CL + && rbuf[1] != BLS_DEVICE_ID_MX25R8035F + && rbuf[1] != BLS_DEVICE_ID_MX25R1635F)) { + return VERIFY_PART_POWERED_DOWN; + } + return VERIFY_PART_OK; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Put the device in power save mode. No access to data; only + * the status register is accessible. + */ +static void +power_down(void) +{ + uint8_t cmd; + uint8_t i; + + /* First, wait for the device to be ready */ + if(wait_ready() == false) { + /* Entering here will leave the device in standby instead of powerdown */ + return; + } + + cmd = BLS_CODE_PD; + select_on_bus(); + board_spi_write(&cmd, sizeof(cmd)); + deselect(); + + i = 0; + while(i < 10) { + if(verify_part() == VERIFY_PART_POWERED_DOWN) { + /* Device is powered down */ + return; + } + i++; + } + + /* Should not be required */ + deselect(); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Take device out of power save mode and prepare it for normal operation + * \return True if the command was written successfully + */ +static bool +power_standby(void) +{ + uint8_t cmd; + bool success; + + cmd = BLS_CODE_RPD; + select_on_bus(); + success = board_spi_write(&cmd, sizeof(cmd)); + + if(success) { + success = wait_ready() == true ? true : false; + } + + deselect(); + + return success; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Enable write. + * \return True when successful. + */ +static bool +write_enable(void) +{ + bool ret; + const uint8_t wbuf[] = { BLS_CODE_WRITE_ENABLE }; + + select_on_bus(); + ret = board_spi_write(wbuf, sizeof(wbuf)); + deselect(); + + if(ret == false) { + return false; + } + return true; +} +/*---------------------------------------------------------------------------*/ +bool +ext_flash_open() +{ + board_spi_open(4000000, BOARD_IOID_SPI_CLK_FLASH); + + /* GPIO pin configuration */ + ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_FLASH_CS); + + /* Default output to clear chip select */ + deselect(); + + /* Put the part is standby mode */ + power_standby(); + + return verify_part() == VERIFY_PART_OK ? true : false; +} +/*---------------------------------------------------------------------------*/ +void +ext_flash_close() +{ + /* Put the part in low power mode */ + power_down(); + + board_spi_close(); +} +/*---------------------------------------------------------------------------*/ +bool +ext_flash_read(size_t offset, size_t length, uint8_t *buf) +{ + uint8_t wbuf[4]; + + /* Wait till previous erase/program operation completes */ + bool ret = wait_ready(); + if(ret == false) { + return false; + } + + /* + * SPI is driven with very low frequency (1MHz < 33MHz fR spec) + * in this implementation, hence it is not necessary to use fast read. + */ + wbuf[0] = BLS_CODE_READ; + wbuf[1] = (offset >> 16) & 0xff; + wbuf[2] = (offset >> 8) & 0xff; + wbuf[3] = offset & 0xff; + + select_on_bus(); + + if(board_spi_write(wbuf, sizeof(wbuf)) == false) { + /* failure */ + deselect(); + return false; + } + + ret = board_spi_read(buf, length); + + deselect(); + + return ret; +} +/*---------------------------------------------------------------------------*/ +bool +ext_flash_write(size_t offset, size_t length, const uint8_t *buf) +{ + uint8_t wbuf[4]; + bool ret; + size_t ilen; /* interim length per instruction */ + + while(length > 0) { + /* Wait till previous erase/program operation completes */ + ret = wait_ready(); + if(ret == false) { + return false; + } + + ret = write_enable(); + if(ret == false) { + return false; + } + + ilen = BLS_PROGRAM_PAGE_SIZE - (offset % BLS_PROGRAM_PAGE_SIZE); + if(length < ilen) { + ilen = length; + } + + wbuf[0] = BLS_CODE_PROGRAM; + wbuf[1] = (offset >> 16) & 0xff; + wbuf[2] = (offset >> 8) & 0xff; + wbuf[3] = offset & 0xff; + + offset += ilen; + length -= ilen; + + /* Upto 100ns CS hold time (which is not clear + * whether it's application only inbetween reads) + * is not imposed here since above instructions + * should be enough to delay + * as much. */ + select_on_bus(); + + if(board_spi_write(wbuf, sizeof(wbuf)) == false) { + /* failure */ + deselect(); + return false; + } + + if(board_spi_write(buf, ilen) == false) { + /* failure */ + deselect(); + return false; + } + buf += ilen; + deselect(); + } + + return true; +} +/*---------------------------------------------------------------------------*/ +bool +ext_flash_erase(size_t offset, size_t length) +{ + /* + * Note that Block erase might be more efficient when the floor map + * is well planned for OTA, but to simplify this implementation, + * sector erase is used blindly. + */ + uint8_t wbuf[4]; + bool ret; + size_t i, numsectors; + size_t endoffset = offset + length - 1; + + offset = (offset / BLS_ERASE_SECTOR_SIZE) * BLS_ERASE_SECTOR_SIZE; + numsectors = (endoffset - offset + BLS_ERASE_SECTOR_SIZE - 1) / BLS_ERASE_SECTOR_SIZE; + + wbuf[0] = BLS_CODE_SECTOR_ERASE; + + for(i = 0; i < numsectors; i++) { + /* Wait till previous erase/program operation completes */ + ret = wait_ready(); + if(ret == false) { + return false; + } + + ret = write_enable(); + if(ret == false) { + return false; + } + + wbuf[1] = (offset >> 16) & 0xff; + wbuf[2] = (offset >> 8) & 0xff; + wbuf[3] = offset & 0xff; + + select_on_bus(); + + if(board_spi_write(wbuf, sizeof(wbuf)) == false) { + /* failure */ + deselect(); + return false; + } + deselect(); + + offset += BLS_ERASE_SECTOR_SIZE; + } + + return true; +} +/*---------------------------------------------------------------------------*/ +bool +ext_flash_test(void) +{ + bool ret; + + ret = ext_flash_open(); + ext_flash_close(); + + return ret; +} +/*---------------------------------------------------------------------------*/ +void +ext_flash_init() +{ + ext_flash_open(); + ext_flash_close(); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/common/ext-flash.h b/platform/srf06-cc26xx/common/ext-flash.h new file mode 100644 index 000000000..5f2717edb --- /dev/null +++ b/platform/srf06-cc26xx/common/ext-flash.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup common-cc26xx-peripherals + * @{ + * + * \defgroup sensortag-cc26xx-ext-flash SensorTag/LaunchPad External Flash + * @{ + * + * \file + * Header file for the Sensortag/LaunchPad External Flash Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef EXT_FLASH_H_ +#define EXT_FLASH_H_ +/*---------------------------------------------------------------------------*/ +#include +#include +#include +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize storage driver. + * \return True when successful. + */ +bool ext_flash_open(void); + +/** + * \brief Close the storage driver + * + * This call will put the device in its lower power mode (power down). + */ +void ext_flash_close(void); + +/** + * \brief Read storage content + * \param offset Address to read from + * \param length Number of bytes to read + * \param buf Buffer where to store the read bytes + * \return True when successful. + * + * buf must be allocated by the caller + */ +bool ext_flash_read(size_t offset, size_t length, uint8_t *buf); + +/** + * \brief Erase storage sectors corresponding to the range. + * \param offset Address to start erasing + * \param length Number of bytes to erase + * \return True when successful. + * + * The erase operation will be sector-wise, therefore a call to this function + * will generally start the erase procedure at an address lower than offset + */ +bool ext_flash_erase(size_t offset, size_t length); + +/** + * \brief Write to storage sectors. + * \param offset Address to write to + * \param length Number of bytes to write + * \param buf Buffer holding the bytes to be written + * + * \return True when successful. + */ +bool ext_flash_write(size_t offset, size_t length, const uint8_t *buf); + +/** + * \brief Test the flash (power on self-test) + * \return True when successful. + */ +bool ext_flash_test(void); + +/** + * \brief Initialise the external flash + * + * This function will explicitly put the part in its lowest power mode + * (power-down). + * + * In order to perform any operation, the caller must first wake the device + * up by calling ext_flash_open() + */ +void ext_flash_init(void); +/*---------------------------------------------------------------------------*/ +#endif /* EXT_FLASH_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/contiki-conf.h b/platform/srf06-cc26xx/contiki-conf.h new file mode 100644 index 000000000..c1546f6a8 --- /dev/null +++ b/platform/srf06-cc26xx/contiki-conf.h @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup cc26xx-srf-tag + * @{ + * + * \file + * Configuration for the srf06-cc26xx platform + */ +#ifndef CONTIKI_CONF_H +#define CONTIKI_CONF_H + +#include +/*---------------------------------------------------------------------------*/ +/* Include Project Specific conf */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif /* PROJECT_CONF_H */ +/*---------------------------------------------------------------------------*/ +/** + * \name Network Stack Configuration + * + * @{ + */ +#ifndef NETSTACK_CONF_NETWORK +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#else +#define NETSTACK_CONF_NETWORK rime_driver +#endif /* NETSTACK_CONF_WITH_IPV6 */ +#endif /* NETSTACK_CONF_NETWORK */ + +#ifndef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC csma_driver +#endif + +#ifndef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC contikimac_driver +#endif + +/* + * Disable turning off HF oscillator when the radio is off: + * You need to set this in order to use TSCH, disable to save more energy. + */ +#ifndef CC2650_FAST_RADIO_STARTUP +#define CC2650_FAST_RADIO_STARTUP 0 +#endif + +/* Configure NullRDC for when it's selected */ +#define NULLRDC_CONF_802154_AUTOACK 1 + +/* Configure ContikiMAC for when it's selected */ +#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0 +#define CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION 0 +#define WITH_FAST_SLEEP 1 + +#ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 +#endif + +#ifndef NETSTACK_CONF_FRAMER +#define NETSTACK_CONF_FRAMER framer_802154 +#endif + +#if CPU_FAMILY_CC13XX +#define NETSTACK_CONF_RADIO prop_mode_driver + +#ifndef RF_CORE_CONF_CHANNEL +#define RF_CORE_CONF_CHANNEL 0 +#endif + +#define NULLRDC_CONF_ACK_WAIT_TIME (RTIMER_SECOND / 400) +#define NULLRDC_CONF_AFTER_ACK_DETECTED_WAIT_TIME (RTIMER_SECOND / 1000) +#define NULLRDC_CONF_802154_AUTOACK_HW 0 +#define NULLRDC_CONF_SEND_802154_ACK 1 + +#define CONTIKIMAC_CONF_CCA_CHECK_TIME (RTIMER_ARCH_SECOND / 1600) +#define CONTIKIMAC_CONF_CCA_SLEEP_TIME (RTIMER_ARCH_SECOND / 210) +#define CONTIKIMAC_CONF_LISTEN_TIME_AFTER_PACKET_DETECTED (RTIMER_ARCH_SECOND / 20) +#define CONTIKIMAC_CONF_SEND_SW_ACK 1 +#define CONTIKIMAC_CONF_AFTER_ACK_DETECTECT_WAIT_TIME (RTIMER_SECOND / 1000) +#define CONTIKIMAC_CONF_INTER_PACKET_INTERVAL (RTIMER_SECOND / 250) +#else +#define NETSTACK_CONF_RADIO ieee_mode_driver + +#ifndef RF_CORE_CONF_CHANNEL +#define RF_CORE_CONF_CHANNEL 25 +#endif + +#define NULLRDC_CONF_802154_AUTOACK_HW 1 +#define NULLRDC_CONF_SEND_802154_ACK 0 +#endif + +#define NETSTACK_RADIO_MAX_PAYLOAD_LEN 125 + +/* 6LoWPAN */ +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63 +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 8 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name IEEE address configuration + * + * Used to generate our RIME & IPv6 address + * @{ + */ +/** + * \brief Location of the IEEE address + * 0 => Read from InfoPage, + * 1 => Use a hardcoded address, configured by IEEE_ADDR_CONF_ADDRESS + */ +#ifndef IEEE_ADDR_CONF_HARDCODED +#define IEEE_ADDR_CONF_HARDCODED 0 +#endif + +/** + * \brief The hardcoded IEEE address to be used when IEEE_ADDR_CONF_HARDCODED + * is defined as 1 + */ +#ifndef IEEE_ADDR_CONF_ADDRESS +#define IEEE_ADDR_CONF_ADDRESS { 0x00, 0x12, 0x4B, 0x00, 0x89, 0xAB, 0xCD, 0xEF } +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name RF configuration + * + * @{ + */ +/* RF Config */ +#ifndef IEEE802154_CONF_PANID +#define IEEE802154_CONF_PANID 0xABCD /**< Default PAN ID */ +#endif + +#ifndef IEEE_MODE_CONF_AUTOACK +#define IEEE_MODE_CONF_AUTOACK 1 /**< RF H/W generates ACKs */ +#endif + +#ifndef IEEE_MODE_CONF_PROMISCOUS +#define IEEE_MODE_CONF_PROMISCOUS 0 /**< 1 to enable promiscous mode */ +#endif + +#ifndef RF_BLE_CONF_ENABLED +#define RF_BLE_CONF_ENABLED 0 /**< 0 to disable BLE support */ +#endif + +#ifndef PROP_MODE_CONF_SNIFFER +#define PROP_MODE_CONF_SNIFFER 0 /**< 1 to enable sniffer mode */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** @} */ +/** + * \name IPv6, RIME and network buffer configuration + * + * @{ + */ +/* Don't let contiki-default-conf.h decide if we are an IPv6 build */ +#ifndef NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_WITH_IPV6 0 +#endif + +#if NETSTACK_CONF_WITH_IPV6 +/*---------------------------------------------------------------------------*/ +/* Addresses, Sizes and Interfaces */ +#define LINKADDR_CONF_SIZE 8 +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 + +/* The size of the uIP main buffer */ +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 1000 +#endif + +/* ND and Routing */ +#ifndef UIP_CONF_ROUTER +#define UIP_CONF_ROUTER 1 +#endif + +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_IP_FORWARD 0 +#define RPL_CONF_STATS 0 + +#ifndef RPL_CONF_OF +#define RPL_CONF_OF rpl_mrhof +#endif + +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#endif +#ifndef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 20 +#endif + +#ifndef UIP_CONF_TCP +#define UIP_CONF_TCP 1 +#endif +#ifndef UIP_CONF_TCP_MSS +#define UIP_CONF_TCP_MSS 64 +#endif + +#define UIP_CONF_UDP 1 +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_ICMP6 1 +/*---------------------------------------------------------------------------*/ +#else /* NETSTACK_CONF_WITH_IPV6 */ +/* Network setup for non-IPv6 (rime). */ +#define UIP_CONF_IP_FORWARD 1 + +#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 + +#endif /* NETSTACK_CONF_WITH_IPV6 */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Generic Configuration directives + * + * @{ + */ +#ifndef ENERGEST_CONF_ON +#define ENERGEST_CONF_ON 0 /**< Energest Module */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Character I/O Configuration + * + * @{ + */ +#ifndef CC26XX_UART_CONF_ENABLE +#define CC26XX_UART_CONF_ENABLE 1 /**< Enable/Disable UART I/O */ +#endif + +#ifndef CC26XX_UART_CONF_BAUD_RATE +#define CC26XX_UART_CONF_BAUD_RATE 115200 /**< Default UART0 baud rate */ +#endif + +/* Enable I/O over the Debugger Devpack - Only relevant for the SensorTag */ +#ifndef BOARD_CONF_DEBUGGER_DEVPACK +#define BOARD_CONF_DEBUGGER_DEVPACK 1 +#endif + +/* Turn off example-provided putchars */ +#define SLIP_BRIDGE_CONF_NO_PUTCHAR 1 +#define SLIP_RADIO_CONF_NO_PUTCHAR 1 + +#ifndef SLIP_ARCH_CONF_ENABLED +/* + * Determine whether we need SLIP + * This will keep working while UIP_FALLBACK_INTERFACE and CMD_CONF_OUTPUT + * keep using SLIP + */ +#if defined(UIP_FALLBACK_INTERFACE) || defined(CMD_CONF_OUTPUT) +#define SLIP_ARCH_CONF_ENABLED 1 +#endif +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Button configurations + * + * Configure a button as power on/off: We use the right button for both boards. + * @{ + */ +#ifndef BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN +#define BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN 1 +#endif + +/* Notify various examples that we have Buttons */ +#define PLATFORM_HAS_BUTTON 1 + +/* + * Override button symbols from dev/button-sensor.h, for the examples that + * include it + */ +#define button_sensor button_left_sensor +#define button_sensor2 button_right_sensor +/** @} */ +/*---------------------------------------------------------------------------*/ +/* Platform-specific define to signify sensor reading failure */ +#define CC26XX_SENSOR_READING_ERROR 0x80000000 +/*---------------------------------------------------------------------------*/ +/** + * \name Compiler configuration and platform-specific type definitions + * + * Those values are not meant to be modified by the user + * @{ + */ +#define CLOCK_CONF_SECOND 128 + +/* Compiler configurations */ +#define CCIF +#define CLIF + +/* Platform typedefs */ +typedef uint32_t clock_time_t; +typedef uint32_t uip_stats_t; + +/* Clock (time) comparison macro */ +#define CLOCK_LT(a, b) ((signed long)((a) - (b)) < 0) + +/* + * rtimer.h typedefs rtimer_clock_t as unsigned short. We need to define + * RTIMER_CLOCK_DIFF to override this + */ +typedef uint32_t rtimer_clock_t; +#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b))) + +/* --------------------------------------------------------------------- */ +/* TSCH related defines */ + +/* Delay between GO signal and SFD */ +#define RADIO_DELAY_BEFORE_TX ((unsigned)US_TO_RTIMERTICKS(81)) +/* Delay between GO signal and start listening. + * This value is so small because the radio is constantly on within each timeslot. */ +#define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(15)) +/* Delay between the SFD finishes arriving and it is detected in software. + * Not important on this platform as it uses hardware timestamps for SFD */ +#define RADIO_DELAY_BEFORE_DETECT ((unsigned)US_TO_RTIMERTICKS(0)) + +/* Timer conversion; radio is running at 4 MHz */ +#define RADIO_TIMER_SECOND 4000000u +#if (RTIMER_SECOND % 256) || (RADIO_TIMER_SECOND % 256) +#error RADIO_TO_RTIMER macro must be fixed! +#endif +#define RADIO_TO_RTIMER(X) ((uint32_t)(((uint64_t)(X) * (RTIMER_SECOND / 256)) / (RADIO_TIMER_SECOND / 256))) +#define USEC_TO_RADIO(X) ((X) * 4) + +/* The PHY header (preamble + SFD, 4+1 bytes) duration is equivalent to 10 symbols */ +#define RADIO_IEEE_802154_PHY_HEADER_DURATION_USEC 160 + +/* Do not turn off TSCH within a timeslot: not enough time */ +#define TSCH_CONF_RADIO_ON_DURING_TIMESLOT 1 + +/* Disable TSCH frame filtering */ +#define TSCH_CONF_HW_FRAME_FILTERING 0 + +/* Use hardware timestamps */ +#ifndef TSCH_CONF_RESYNC_WITH_SFD_TIMESTAMPS +#define TSCH_CONF_RESYNC_WITH_SFD_TIMESTAMPS 1 +#define TSCH_CONF_TIMESYNC_REMOVE_JITTER 0 +#endif + +/* The drift compared to "true" 10ms slots. + Enable adaptive sync to enable compensation for this. */ +#define TSCH_CONF_BASE_DRIFT_PPM -977 + +/* 10 times per second */ +#define TSCH_CONF_ASSOCIATION_CHANNEL_SWITCH_FREQUENCY 10 + +/** @} */ +/*---------------------------------------------------------------------------*/ +/* board.h assumes that basic configuration is done */ +#include "board.h" +/*---------------------------------------------------------------------------*/ +#endif /* CONTIKI_CONF_H */ + +/** @} */ diff --git a/platform/srf06-cc26xx/contiki-main.c b/platform/srf06-cc26xx/contiki-main.c new file mode 100644 index 000000000..b3f5c37f7 --- /dev/null +++ b/platform/srf06-cc26xx/contiki-main.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-platforms + * @{ + * + * \defgroup cc26xx-srf-tag SmartRF+CC13xx/CC26xx EM, CC2650 SensorTag and LaunchPads + * + * This platform supports a number of different boards: + * - A standard TI SmartRF06EB with a CC26xx EM mounted on it + * - A standard TI SmartRF06EB with a CC1310 EM mounted on it + * - The new TI SensorTag2.0 + * - The TI CC2650 LaunchPad + * - The TI CC1310 LaunchPad + * @{ + */ +#include "ti-lib.h" +#include "contiki.h" +#include "contiki-net.h" +#include "leds.h" +#include "lpm.h" +#include "gpio-interrupt.h" +#include "dev/watchdog.h" +#include "dev/oscillators.h" +#include "ieee-addr.h" +#include "vims.h" +#include "dev/cc26xx-uart.h" +#include "dev/soc-rtc.h" +#include "rf-core/rf-core.h" +#include "sys_ctrl.h" +#include "uart.h" +#include "sys/clock.h" +#include "sys/rtimer.h" +#include "sys/node-id.h" +#include "lib/sensors.h" +#include "button-sensor.h" +#include "dev/serial-line.h" +#include "net/mac/frame802154.h" + +#include "driverlib/driverlib_release.h" + +#include +/*---------------------------------------------------------------------------*/ +unsigned short node_id = 0; +/*---------------------------------------------------------------------------*/ +/** \brief Board specific iniatialisation */ +void board_init(void); +/*---------------------------------------------------------------------------*/ +static void +fade(unsigned char l) +{ + volatile int i; + int k, j; + for(k = 0; k < 800; ++k) { + j = k > 400 ? 800 - k : k; + + leds_on(l); + for(i = 0; i < j; ++i) { + __asm("nop"); + } + leds_off(l); + for(i = 0; i < 400 - j; ++i) { + __asm("nop"); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +set_rf_params(void) +{ + uint16_t short_addr; + uint8_t ext_addr[8]; + radio_value_t val = 0; + + ieee_addr_cpy_to(ext_addr, 8); + + short_addr = ext_addr[7]; + short_addr |= ext_addr[6] << 8; + + /* Populate linkaddr_node_addr. Maintain endianness */ + memcpy(&linkaddr_node_addr, &ext_addr[8 - LINKADDR_SIZE], LINKADDR_SIZE); + + NETSTACK_RADIO.set_value(RADIO_PARAM_PAN_ID, IEEE802154_PANID); + NETSTACK_RADIO.set_value(RADIO_PARAM_16BIT_ADDR, short_addr); + NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, RF_CORE_CHANNEL); + NETSTACK_RADIO.set_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8); + + NETSTACK_RADIO.get_value(RADIO_PARAM_CHANNEL, &val); + printf(" RF: Channel %d\n", val); + +#if STARTUP_CONF_VERBOSE + { + int i; + printf(" Link layer addr: "); + for(i = 0; i < LINKADDR_SIZE - 1; i++) { + printf("%02x:", linkaddr_node_addr.u8[i]); + } + printf("%02x\n", linkaddr_node_addr.u8[i]); + } +#endif + + /* also set the global node id */ + node_id = short_addr; + printf(" Node ID: %d\n", node_id); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Main function for CC26xx-based platforms + * + * The same main() is used for all supported boards + */ +int +main(void) +{ + /* Enable flash cache and prefetch. */ + ti_lib_vims_mode_set(VIMS_BASE, VIMS_MODE_ENABLED); + ti_lib_vims_configure(VIMS_BASE, true, true); + + ti_lib_int_master_disable(); + + /* Set the LF XOSC as the LF system clock source */ + oscillators_select_lf_xosc(); + +#if CC2650_FAST_RADIO_STARTUP + /* Also request HF XOSC to start up */ + oscillators_request_hf_xosc(); +#endif + + lpm_init(); + + board_init(); + + gpio_interrupt_init(); + + leds_init(); + + /* + * Disable I/O pad sleep mode and open I/O latches in the AON IOC interface + * This is only relevant when returning from shutdown (which is what froze + * latches in the first place. Before doing these things though, we should + * allow software to first regain control of pins + */ + ti_lib_pwr_ctrl_io_freeze_disable(); + + fade(LEDS_RED); + + ti_lib_int_master_enable(); + + soc_rtc_init(); + clock_init(); + rtimer_init(); + + watchdog_init(); + process_init(); + + random_init(0x1234); + + /* Character I/O Initialisation */ +#if CC26XX_UART_CONF_ENABLE + cc26xx_uart_init(); +#endif + + serial_line_init(); + + printf("Starting " CONTIKI_VERSION_STRING "\n"); + printf("With DriverLib v%u.%u\n", DRIVERLIB_RELEASE_GROUP, + DRIVERLIB_RELEASE_BUILD); + printf(BOARD_STRING "\n"); + + process_start(&etimer_process, NULL); + ctimer_init(); + + energest_init(); + ENERGEST_ON(ENERGEST_TYPE_CPU); + + fade(LEDS_YELLOW); + + printf(" Net: "); + printf("%s\n", NETSTACK_NETWORK.name); + printf(" MAC: "); + printf("%s\n", NETSTACK_MAC.name); + printf(" RDC: "); + printf("%s", NETSTACK_RDC.name); + + if(NETSTACK_RDC.channel_check_interval() != 0) { + printf(", Channel Check Interval: %u ticks", + NETSTACK_RDC.channel_check_interval()); + } + printf("\n"); + + netstack_init(); + + set_rf_params(); + +#if NETSTACK_CONF_WITH_IPV6 + memcpy(&uip_lladdr.addr, &linkaddr_node_addr, sizeof(uip_lladdr.addr)); + queuebuf_init(); + process_start(&tcpip_process, NULL); +#endif /* NETSTACK_CONF_WITH_IPV6 */ + + fade(LEDS_GREEN); + + process_start(&sensors_process, NULL); + + autostart_start(autostart_processes); + + watchdog_start(); + + fade(LEDS_ORANGE); + + while(1) { + uint8_t r; + do { + r = process_run(); + watchdog_periodic(); + } while(r > 0); + + /* Drop to some low power mode */ + lpm_drop(); + } +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/launchpad/Makefile.launchpad b/platform/srf06-cc26xx/launchpad/Makefile.launchpad new file mode 100644 index 000000000..54bd81ced --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/Makefile.launchpad @@ -0,0 +1,9 @@ +CFLAGS += -DBOARD_LAUNCHPAD=1 + +CONTIKI_TARGET_DIRS += launchpad common + +BOARD_SOURCEFILES += board.c launchpad-sensors.c leds-arch.c button-sensor.c +BOARD_SOURCEFILES += ext-flash.c board-spi.c + +### Signal that we can be programmed with cc2538-bsl +BOARD_SUPPORTS_BSL=1 diff --git a/platform/srf06-cc26xx/launchpad/board-peripherals.h b/platform/srf06-cc26xx/launchpad/board-peripherals.h new file mode 100644 index 000000000..3e1220234 --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/board-peripherals.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** \addtogroup cc26xx-srf-tag + * @{ + * + * \defgroup launchpad-peripherals LaunchPad peripherals + * + * Defines related to LaunchPad peripherals. + * + * @{ + * + * \file + * Header file with definitions related to LaunchPad peripherals + * + * \note Do not include this file directly. + */ +/*---------------------------------------------------------------------------*/ +#ifndef BOARD_PERIPHERALS_H_ +#define BOARD_PERIPHERALS_H_ +/*---------------------------------------------------------------------------*/ +#include "ext-flash.h" +/*---------------------------------------------------------------------------*/ +#endif /* BOARD_PERIPHERALS_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/launchpad/board.c b/platform/srf06-cc26xx/launchpad/board.c new file mode 100644 index 000000000..6482212d8 --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/board.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup launchpad-peripherals + * @{ + * + * \file + * LaunchPad-specific board initialisation driver + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "lib/sensors.h" +#include "lpm.h" +#include "ti-lib.h" +#include "board-peripherals.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +static void +wakeup_handler(void) +{ + /* Turn on the PERIPH PD */ + ti_lib_prcm_power_domain_on(PRCM_DOMAIN_PERIPH); + while((ti_lib_prcm_power_domain_status(PRCM_DOMAIN_PERIPH) + != PRCM_DOMAIN_POWER_ON)); +} +/*---------------------------------------------------------------------------*/ +/* + * Declare a data structure to register with LPM. + * We don't care about what power mode we'll drop to, we don't care about + * getting notified before deep sleep. All we need is to be notified when we + * wake up so we can turn power domains back on + */ +LPM_MODULE(launchpad_module, NULL, NULL, wakeup_handler, LPM_DOMAIN_NONE); +/*---------------------------------------------------------------------------*/ +static void +configure_unused_pins(void) +{ + uint32_t pins[] = { + BOARD_IOID_CS, BOARD_IOID_TDO, BOARD_IOID_TDI, BOARD_IOID_DIO12, + BOARD_IOID_DIO15, BOARD_IOID_DIO21, BOARD_IOID_DIO22, BOARD_IOID_DIO23, + BOARD_IOID_DIO24, BOARD_IOID_DIO25, BOARD_IOID_DIO26, BOARD_IOID_DIO27, + BOARD_IOID_DIO28, BOARD_IOID_DIO29, BOARD_IOID_DIO30, + IOID_UNUSED + }; + + uint32_t *pin; + + for(pin = pins; *pin != IOID_UNUSED; pin++) { + ti_lib_ioc_pin_type_gpio_input(*pin); + ti_lib_ioc_io_port_pull_set(*pin, IOC_IOPULL_DOWN); + } +} +/*---------------------------------------------------------------------------*/ +void +board_init() +{ + /* Disable global interrupts */ + bool int_disabled = ti_lib_int_master_disable(); + + /* Turn on relevant PDs */ + wakeup_handler(); + + /* Enable GPIO peripheral */ + ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_GPIO); + + /* Apply settings and wait for them to take effect */ + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + /* Make sure the external flash is in the lower power mode */ + ext_flash_init(); + + lpm_register_module(&launchpad_module); + + /* For unsupported peripherals, select a default pin configuration */ + configure_unused_pins(); + + /* Re-enable interrupt if initially enabled. */ + if(!int_disabled) { + ti_lib_int_master_enable(); + } +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/launchpad/button-sensor.c b/platform/srf06-cc26xx/launchpad/button-sensor.c new file mode 100644 index 000000000..d37369d0a --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/button-sensor.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup launchpad-button-sensor + * @{ + * + * \file + * Driver for LaunchPad buttons + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/sensors.h" +#include "launchpad/button-sensor.h" +#include "gpio-interrupt.h" +#include "sys/timer.h" +#include "lpm.h" + +#include "ti-lib.h" + +#include +/*---------------------------------------------------------------------------*/ +#ifdef BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN +#define BUTTON_SENSOR_ENABLE_SHUTDOWN BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN +#else +#define BUTTON_SENSOR_ENABLE_SHUTDOWN 1 +#endif +/*---------------------------------------------------------------------------*/ +#define BUTTON_GPIO_CFG (IOC_CURRENT_2MA | IOC_STRENGTH_AUTO | \ + IOC_IOPULL_UP | IOC_SLEW_DISABLE | \ + IOC_HYST_DISABLE | IOC_BOTH_EDGES | \ + IOC_INT_ENABLE | IOC_IOMODE_NORMAL | \ + IOC_NO_WAKE_UP | IOC_INPUT_ENABLE) +/*---------------------------------------------------------------------------*/ +#define DEBOUNCE_DURATION (CLOCK_SECOND >> 5) + +struct btn_timer { + struct timer debounce; + clock_time_t start; + clock_time_t duration; +}; + +static struct btn_timer left_timer, right_timer; +/*---------------------------------------------------------------------------*/ +static void +button_press_handler(uint8_t ioid) +{ + if(ioid == BOARD_IOID_KEY_LEFT) { + if(!timer_expired(&left_timer.debounce)) { + return; + } + + timer_set(&left_timer.debounce, DEBOUNCE_DURATION); + + /* + * Start press duration counter on press (falling), notify on release + * (rising) + */ + if(ti_lib_gpio_pin_read(BOARD_KEY_LEFT) == 0) { + left_timer.start = clock_time(); + left_timer.duration = 0; + } else { + left_timer.duration = clock_time() - left_timer.start; + sensors_changed(&button_left_sensor); + } + } + + if(ioid == BOARD_IOID_KEY_RIGHT) { + if(BUTTON_SENSOR_ENABLE_SHUTDOWN == 0) { + if(!timer_expired(&right_timer.debounce)) { + return; + } + + timer_set(&right_timer.debounce, DEBOUNCE_DURATION); + + /* + * Start press duration counter on press (falling), notify on release + * (rising) + */ + if(ti_lib_gpio_pin_read(BOARD_KEY_RIGHT) == 0) { + right_timer.start = clock_time(); + right_timer.duration = 0; + } else { + right_timer.duration = clock_time() - right_timer.start; + sensors_changed(&button_right_sensor); + } + } else { + lpm_shutdown(BOARD_IOID_KEY_RIGHT, IOC_IOPULL_UP, IOC_WAKE_ON_LOW); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +config_buttons(int type, int c, uint32_t key) +{ + switch(type) { + case SENSORS_HW_INIT: + ti_lib_gpio_event_clear(1 << key); + ti_lib_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); + ti_lib_gpio_dir_mode_set((1 << key), GPIO_DIR_MODE_IN); + gpio_interrupt_register_handler(key, button_press_handler); + break; + case SENSORS_ACTIVE: + if(c) { + ti_lib_gpio_event_clear(1 << key); + ti_lib_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); + ti_lib_gpio_dir_mode_set((1 << key), GPIO_DIR_MODE_IN); + ti_lib_ioc_int_enable(key); + } else { + ti_lib_ioc_int_disable(key); + } + break; + default: + break; + } +} +/*---------------------------------------------------------------------------*/ +static int +config_left(int type, int value) +{ + config_buttons(type, value, BOARD_IOID_KEY_LEFT); + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +config_right(int type, int value) +{ + config_buttons(type, value, BOARD_IOID_KEY_RIGHT); + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type, uint32_t key_io_id) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + if(ti_lib_ioc_port_configure_get(key_io_id) & IOC_INT_ENABLE) { + return 1; + } + break; + default: + break; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value_left(int type) +{ + if(type == BUTTON_SENSOR_VALUE_STATE) { + return ti_lib_gpio_pin_read(BOARD_KEY_LEFT) == 0 ? + BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; + } else if(type == BUTTON_SENSOR_VALUE_DURATION) { + return (int)left_timer.duration; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value_right(int type) +{ + if(type == BUTTON_SENSOR_VALUE_STATE) { + return ti_lib_gpio_pin_read(BOARD_KEY_RIGHT) == 0 ? + BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; + } else if(type == BUTTON_SENSOR_VALUE_DURATION) { + return (int)right_timer.duration; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status_left(int type) +{ + return status(type, BOARD_IOID_KEY_LEFT); +} +/*---------------------------------------------------------------------------*/ +static int +status_right(int type) +{ + return status(type, BOARD_IOID_KEY_RIGHT); +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(button_left_sensor, BUTTON_SENSOR, value_left, config_left, + status_left); +SENSORS_SENSOR(button_right_sensor, BUTTON_SENSOR, value_right, config_right, + status_right); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/launchpad/button-sensor.h b/platform/srf06-cc26xx/launchpad/button-sensor.h new file mode 100644 index 000000000..0c945d3f7 --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/button-sensor.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup launchpad-peripherals + * @{ + * + * \defgroup launchpad-button-sensor LaunchPad Button Driver + * + * One of the buttons can be configured as general purpose or as an on/off key + * @{ + * + * \file + * Header file for the LaunchPad Button Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef BUTTON_SENSOR_H_ +#define BUTTON_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR "Button" +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR_VALUE_STATE 0 +#define BUTTON_SENSOR_VALUE_DURATION 1 + +#define BUTTON_SENSOR_VALUE_RELEASED 0 +#define BUTTON_SENSOR_VALUE_PRESSED 1 +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor button_left_sensor; +extern const struct sensors_sensor button_right_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* BUTTON_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/launchpad/cc1310/Makefile.cc1310 b/platform/srf06-cc26xx/launchpad/cc1310/Makefile.cc1310 new file mode 100644 index 000000000..8d3d2abd4 --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/cc1310/Makefile.cc1310 @@ -0,0 +1,8 @@ +### Will allow the inclusion of the correct CPU makefile +CPU_FAMILY = cc13xx + +### Add to the source dirs +CONTIKI_TARGET_DIRS += launchpad/cc1310 + +### Include the common launchpad makefile +include $(PLATFORM_ROOT_DIR)/launchpad/Makefile.launchpad diff --git a/platform/srf06-cc26xx/launchpad/cc1310/board.h b/platform/srf06-cc26xx/launchpad/cc1310/board.h new file mode 100644 index 000000000..d6cfeeedb --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/cc1310/board.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2016, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** \addtogroup launchpad-peripherals + * @{ + * + * \defgroup launchpad-cc1310-specific CC1310 LaunchPad Peripherals + * + * Defines related to the CC1310 LaunchPad + * + * This file provides connectivity information on LEDs, Buttons, UART and + * other peripherals + * + * This file is not meant to be modified by the user. + * @{ + * + * \file + * Header file with definitions related to the I/O connections on the TI + * CC1310 LaunchPad + * + * \note Do not include this file directly. It gets included by contiki-conf + * after all relevant directives have been set. + */ +/*---------------------------------------------------------------------------*/ +#ifndef BOARD_H_ +#define BOARD_H_ +/*---------------------------------------------------------------------------*/ +#include "ioc.h" +/*---------------------------------------------------------------------------*/ +/** + * \name LED configurations + * + * Those values are not meant to be modified by the user + * @{ + */ +/* Some files include leds.h before us, so we need to get rid of defaults in + * leds.h before we provide correct definitions */ +#undef LEDS_GREEN +#undef LEDS_YELLOW +#undef LEDS_RED +#undef LEDS_CONF_ALL + +#define LEDS_RED 1 +#define LEDS_GREEN 2 +#define LEDS_YELLOW LEDS_GREEN +#define LEDS_ORANGE LEDS_RED + +#define LEDS_CONF_ALL 3 + +/* Notify various examples that we have LEDs */ +#define PLATFORM_HAS_LEDS 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name LED IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_LED_1 IOID_6 +#define BOARD_IOID_LED_2 IOID_7 +#define BOARD_LED_1 (1 << BOARD_IOID_LED_1) +#define BOARD_LED_2 (1 << BOARD_IOID_LED_2) +#define BOARD_LED_ALL (BOARD_LED_1 | BOARD_LED_2) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name UART IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_UART_RX IOID_2 +#define BOARD_IOID_UART_TX IOID_3 +#define BOARD_IOID_UART_RTS IOID_18 +#define BOARD_IOID_UART_CTS IOID_19 +#define BOARD_UART_RX (1 << BOARD_IOID_UART_RX) +#define BOARD_UART_TX (1 << BOARD_IOID_UART_TX) +#define BOARD_UART_RTS (1 << BOARD_IOID_UART_RTS) +#define BOARD_UART_CTS (1 << BOARD_IOID_UART_CTS) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Button IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_KEY_LEFT IOID_13 +#define BOARD_IOID_KEY_RIGHT IOID_14 +#define BOARD_KEY_LEFT (1 << BOARD_IOID_KEY_LEFT) +#define BOARD_KEY_RIGHT (1 << BOARD_IOID_KEY_RIGHT) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief SPI IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_SPI_MOSI IOID_9 +#define BOARD_IOID_SPI_MISO IOID_8 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name External flash IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_FLASH_CS IOID_20 +#define BOARD_FLASH_CS (1 << BOARD_IOID_FLASH_CS) +#define BOARD_IOID_SPI_CLK_FLASH IOID_10 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief I2C IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_SCL IOID_4 +#define BOARD_IOID_SDA IOID_5 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief Remaining pins + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_CS IOID_11 +#define BOARD_IOID_TDO IOID_16 +#define BOARD_IOID_TDI IOID_17 +#define BOARD_IOID_DIO12 IOID_12 +#define BOARD_IOID_DIO15 IOID_15 +#define BOARD_IOID_DIO21 IOID_21 +#define BOARD_IOID_DIO22 IOID_22 +#define BOARD_IOID_DIO23 IOID_23 +#define BOARD_IOID_DIO24 IOID_24 +#define BOARD_IOID_DIO25 IOID_25 +#define BOARD_IOID_DIO26 IOID_26 +#define BOARD_IOID_DIO27 IOID_27 +#define BOARD_IOID_DIO28 IOID_28 +#define BOARD_IOID_DIO29 IOID_29 +#define BOARD_IOID_DIO30 IOID_30 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Device string used on startup + * @{ + */ +#define BOARD_STRING "TI CC1310 LaunchPad" + +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* BOARD_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/launchpad/cc2650/Makefile.cc2650 b/platform/srf06-cc26xx/launchpad/cc2650/Makefile.cc2650 new file mode 100644 index 000000000..72e50de3a --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/cc2650/Makefile.cc2650 @@ -0,0 +1,8 @@ +### Will allow the inclusion of the correct CPU makefile +CPU_FAMILY = cc26xx + +### Add to the source dirs +CONTIKI_TARGET_DIRS += launchpad/cc2650 + +### Include the common launchpad makefile +include $(PLATFORM_ROOT_DIR)/launchpad/Makefile.launchpad diff --git a/platform/srf06-cc26xx/launchpad/cc2650/board.h b/platform/srf06-cc26xx/launchpad/cc2650/board.h new file mode 100644 index 000000000..a65ca5361 --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/cc2650/board.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** \addtogroup launchpad-peripherals + * @{ + * + * \defgroup launchpad-cc26xx-specific CC2650 LaunchPad Peripherals + * + * Defines related to the CC2650 LaunchPad + * + * This file provides connectivity information on LEDs, Buttons, UART and + * other peripherals + * + * This file is not meant to be modified by the user. + * @{ + * + * \file + * Header file with definitions related to the I/O connections on the TI + * CC2650 LaunchPad + * + * \note Do not include this file directly. It gets included by contiki-conf + * after all relevant directives have been set. + */ +/*---------------------------------------------------------------------------*/ +#ifndef BOARD_H_ +#define BOARD_H_ +/*---------------------------------------------------------------------------*/ +#include "ioc.h" +/*---------------------------------------------------------------------------*/ +/** + * \name LED configurations + * + * Those values are not meant to be modified by the user + * @{ + */ +/* Some files include leds.h before us, so we need to get rid of defaults in + * leds.h before we provide correct definitions */ +#undef LEDS_GREEN +#undef LEDS_YELLOW +#undef LEDS_RED +#undef LEDS_CONF_ALL + +#define LEDS_RED 1 +#define LEDS_GREEN 2 +#define LEDS_YELLOW LEDS_GREEN +#define LEDS_ORANGE LEDS_RED + +#define LEDS_CONF_ALL 3 + +/* Notify various examples that we have LEDs */ +#define PLATFORM_HAS_LEDS 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name LED IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_LED_1 IOID_6 +#define BOARD_IOID_LED_2 IOID_7 +#define BOARD_LED_1 (1 << BOARD_IOID_LED_1) +#define BOARD_LED_2 (1 << BOARD_IOID_LED_2) +#define BOARD_LED_ALL (BOARD_LED_1 | BOARD_LED_2) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name UART IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_UART_RX IOID_2 +#define BOARD_IOID_UART_TX IOID_3 +#define BOARD_IOID_UART_RTS IOID_18 +#define BOARD_IOID_UART_CTS IOID_19 +#define BOARD_UART_RX (1 << BOARD_IOID_UART_RX) +#define BOARD_UART_TX (1 << BOARD_IOID_UART_TX) +#define BOARD_UART_RTS (1 << BOARD_IOID_UART_RTS) +#define BOARD_UART_CTS (1 << BOARD_IOID_UART_CTS) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Button IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_KEY_LEFT IOID_13 +#define BOARD_IOID_KEY_RIGHT IOID_14 +#define BOARD_KEY_LEFT (1 << BOARD_IOID_KEY_LEFT) +#define BOARD_KEY_RIGHT (1 << BOARD_IOID_KEY_RIGHT) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief SPI IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_SPI_MOSI IOID_9 +#define BOARD_IOID_SPI_MISO IOID_8 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name External flash IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_FLASH_CS IOID_20 +#define BOARD_FLASH_CS (1 << BOARD_IOID_FLASH_CS) +#define BOARD_IOID_SPI_CLK_FLASH IOID_10 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief I2C IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_SCL IOID_4 +#define BOARD_IOID_SDA IOID_5 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief Remaining pins + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_CS IOID_11 +#define BOARD_IOID_TDO IOID_16 +#define BOARD_IOID_TDI IOID_17 +#define BOARD_IOID_DIO12 IOID_12 +#define BOARD_IOID_DIO15 IOID_15 +#define BOARD_IOID_DIO21 IOID_21 +#define BOARD_IOID_DIO22 IOID_22 +#define BOARD_IOID_DIO23 IOID_23 +#define BOARD_IOID_DIO24 IOID_24 +#define BOARD_IOID_DIO25 IOID_25 +#define BOARD_IOID_DIO26 IOID_26 +#define BOARD_IOID_DIO27 IOID_27 +#define BOARD_IOID_DIO28 IOID_28 +#define BOARD_IOID_DIO29 IOID_29 +#define BOARD_IOID_DIO30 IOID_30 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Device string used on startup + * @{ + */ +#define BOARD_STRING "TI CC2650 LaunchPad" + +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* BOARD_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/launchpad/launchpad-sensors.c b/platform/srf06-cc26xx/launchpad/launchpad-sensors.c new file mode 100644 index 000000000..c940ec68c --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/launchpad-sensors.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup launchpad-peripherals + * @{ + * + * \file + * Generic module controlling LaunchPad sensors + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "launchpad/button-sensor.h" + +#include +/*---------------------------------------------------------------------------*/ +/** \brief Exports a global symbol to be used by the sensor API */ +SENSORS(&button_left_sensor, &button_right_sensor); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/launchpad/leds-arch.c b/platform/srf06-cc26xx/launchpad/leds-arch.c new file mode 100644 index 000000000..e853487fd --- /dev/null +++ b/platform/srf06-cc26xx/launchpad/leds-arch.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup launchpad-peripherals + * @{ + * + * \file + * Driver for LaunchPad LEDs + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/leds.h" + +#include "ti-lib.h" +/*---------------------------------------------------------------------------*/ +static unsigned char c; +static int inited = 0; +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + if(inited) { + return; + } + inited = 1; + + ti_lib_rom_ioc_pin_type_gpio_output(BOARD_IOID_LED_1); + ti_lib_rom_ioc_pin_type_gpio_output(BOARD_IOID_LED_2); + + ti_lib_gpio_pin_write(BOARD_LED_ALL, 0); +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + return c; +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char leds) +{ + c = leds; + ti_lib_gpio_pin_write(BOARD_LED_ALL, 0); + + if((leds & LEDS_RED) == LEDS_RED) { + ti_lib_gpio_pin_write(BOARD_LED_1, 1); + } + if((leds & LEDS_YELLOW) == LEDS_YELLOW) { + ti_lib_gpio_pin_write(BOARD_LED_2, 1); + } +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/sensortag/Makefile.sensortag b/platform/srf06-cc26xx/sensortag/Makefile.sensortag new file mode 100644 index 000000000..68e4b007f --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/Makefile.sensortag @@ -0,0 +1,10 @@ +CFLAGS += -DBOARD_SENSORTAG=1 +CFLAGS += -DBACKDOOR_IOID=0x00000000 + +CONTIKI_TARGET_DIRS += sensortag common + +BOARD_SOURCEFILES += sensortag-sensors.c sensor-common.c +BOARD_SOURCEFILES += bmp-280-sensor.c tmp-007-sensor.c opt-3001-sensor.c +BOARD_SOURCEFILES += hdc-1000-sensor.c mpu-9250-sensor.c button-sensor.c +BOARD_SOURCEFILES += reed-relay.c ext-flash.c buzzer.c +BOARD_SOURCEFILES += board.c board-spi.c board-i2c.c diff --git a/platform/srf06-cc26xx/sensortag/bmp-280-sensor.c b/platform/srf06-cc26xx/sensortag/bmp-280-sensor.c new file mode 100644 index 000000000..4ed9e06fc --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/bmp-280-sensor.c @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-bmp-sensor + * @{ + * + * \file + * Driver for the Sensortag-CC26XX BMP280 Altimeter / Pressure Sensor + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "lib/sensors.h" +#include "bmp-280-sensor.h" +#include "sys/ctimer.h" +#include "sensor-common.h" +#include "board-i2c.h" +#include "ti-lib.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +#define BMP280_I2C_ADDRESS 0x77 +/*---------------------------------------------------------------------------*/ +/* Registers */ +#define ADDR_CALIB 0x88 +#define ADDR_PROD_ID 0xD0 +#define ADDR_RESET 0xE0 +#define ADDR_STATUS 0xF3 +#define ADDR_CTRL_MEAS 0xF4 +#define ADDR_CONFIG 0xF5 +#define ADDR_PRESS_MSB 0xF7 +#define ADDR_PRESS_LSB 0xF8 +#define ADDR_PRESS_XLSB 0xF9 +#define ADDR_TEMP_MSB 0xFA +#define ADDR_TEMP_LSB 0xFB +#define ADDR_TEMP_XLSB 0xFC +/*---------------------------------------------------------------------------*/ +/* Reset values */ +#define VAL_PROD_ID 0x58 +#define VAL_RESET 0x00 +#define VAL_STATUS 0x00 +#define VAL_CTRL_MEAS 0x00 +#define VAL_CONFIG 0x00 +#define VAL_PRESS_MSB 0x80 +#define VAL_PRESS_LSB 0x00 +#define VAL_TEMP_MSB 0x80 +#define VAL_TEMP_LSB 0x00 +/*---------------------------------------------------------------------------*/ +/* Test values */ +#define VAL_RESET_EXECUTE 0xB6 +#define VAL_CTRL_MEAS_TEST 0x55 +/*---------------------------------------------------------------------------*/ +/* Misc. */ +#define MEAS_DATA_SIZE 6 +#define CALIB_DATA_SIZE 24 +/*---------------------------------------------------------------------------*/ +#define RES_OFF 0 +#define RES_ULTRA_LOW_POWER 1 +#define RES_LOW_POWER 2 +#define RES_STANDARD 3 +#define RES_HIGH 5 +#define RES_ULTRA_HIGH 6 +/*---------------------------------------------------------------------------*/ +/* Bit fields in CTRL_MEAS register */ +#define PM_OFF 0 +#define PM_FORCED 1 +#define PM_NORMAL 3 +/*---------------------------------------------------------------------------*/ +#define OSRST(v) ((v) << 5) +#define OSRSP(v) ((v) << 2) +/*---------------------------------------------------------------------------*/ +typedef struct bmp_280_calibration { + uint16_t dig_t1; + int16_t dig_t2; + int16_t dig_t3; + uint16_t dig_p1; + int16_t dig_p2; + int16_t dig_p3; + int16_t dig_p4; + int16_t dig_p5; + int16_t dig_p6; + int16_t dig_p7; + int16_t dig_p8; + int16_t dig_p9; + int32_t t_fine; +} bmp_280_calibration_t; +/*---------------------------------------------------------------------------*/ +static uint8_t calibration_data[CALIB_DATA_SIZE]; +/*---------------------------------------------------------------------------*/ +#define SENSOR_STATUS_DISABLED 0 +#define SENSOR_STATUS_INITIALISED 1 +#define SENSOR_STATUS_NOT_READY 2 +#define SENSOR_STATUS_READY 3 + +static int enabled = SENSOR_STATUS_DISABLED; +/*---------------------------------------------------------------------------*/ +/* A buffer for the raw reading from the sensor */ +#define SENSOR_DATA_BUF_SIZE 6 + +static uint8_t sensor_value[SENSOR_DATA_BUF_SIZE]; +/*---------------------------------------------------------------------------*/ +/* Wait SENSOR_STARTUP_DELAY clock ticks for the sensor to be ready - ~80ms */ +#define SENSOR_STARTUP_DELAY 3 + +static struct ctimer startup_timer; +/*---------------------------------------------------------------------------*/ +static void +notify_ready(void *not_used) +{ + enabled = SENSOR_STATUS_READY; + sensors_changed(&bmp_280_sensor); +} +/*---------------------------------------------------------------------------*/ +static void +select_on_bus(void) +{ + /* Set up I2C */ + board_i2c_select(BOARD_I2C_INTERFACE_0, BMP280_I2C_ADDRESS); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Initalise the sensor + */ +static void +init(void) +{ + uint8_t val; + + select_on_bus(); + + /* Read and store calibration data */ + sensor_common_read_reg(ADDR_CALIB, calibration_data, CALIB_DATA_SIZE); + + /* Reset the sensor */ + val = VAL_RESET_EXECUTE; + sensor_common_write_reg(ADDR_RESET, &val, sizeof(val)); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Enable/disable measurements + * \param enable 0: disable, enable otherwise + * + * @return none + */ +static void +enable_sensor(bool enable) +{ + uint8_t val; + + select_on_bus(); + + if(enable) { + /* Enable forced mode */ + val = PM_FORCED | OSRSP(1) | OSRST(1); + } else { + val = PM_OFF; + } + sensor_common_write_reg(ADDR_CTRL_MEAS, &val, sizeof(val)); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Read temperature and pressure data + * \param data Pointer to a buffer where temperature and pressure will be + * written (6 bytes) + * \return True if valid data could be retrieved + */ +static bool +read_data(uint8_t *data) +{ + bool success; + + select_on_bus(); + + success = sensor_common_read_reg(ADDR_PRESS_MSB, data, MEAS_DATA_SIZE); + if(!success) { + sensor_common_set_error_data(data, MEAS_DATA_SIZE); + } + + return success; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Convert raw data to values in degrees C (temp) and Pascal (pressure) + * \param data Pointer to a buffer that holds raw sensor data + * \param temp Pointer to a variable where the converted temperature will be + * written + * \param press Pointer to a variable where the converted pressure will be + * written + */ +static void +convert(uint8_t *data, int32_t *temp, uint32_t *press) +{ + int32_t utemp, upress; + bmp_280_calibration_t *p = (bmp_280_calibration_t *)calibration_data; + int32_t v_x1_u32r; + int32_t v_x2_u32r; + int32_t temperature; + uint32_t pressure; + + /* Pressure */ + upress = (int32_t)((((uint32_t)(data[0])) << 12) + | (((uint32_t)(data[1])) << 4) | ((uint32_t)data[2] >> 4)); + + /* Temperature */ + utemp = (int32_t)((((uint32_t)(data[3])) << 12) | (((uint32_t)(data[4])) << 4) + | ((uint32_t)data[5] >> 4)); + + /* Compensate temperature */ + v_x1_u32r = ((((utemp >> 3) - ((int32_t)p->dig_t1 << 1))) + * ((int32_t)p->dig_t2)) >> 11; + v_x2_u32r = (((((utemp >> 4) - ((int32_t)p->dig_t1)) + * ((utemp >> 4) - ((int32_t)p->dig_t1))) >> 12) + * ((int32_t)p->dig_t3)) + >> 14; + p->t_fine = v_x1_u32r + v_x2_u32r; + temperature = (p->t_fine * 5 + 128) >> 8; + *temp = temperature; + + /* Compensate pressure */ + v_x1_u32r = (((int32_t)p->t_fine) >> 1) - (int32_t)64000; + v_x2_u32r = (((v_x1_u32r >> 2) * (v_x1_u32r >> 2)) >> 11) + * ((int32_t)p->dig_p6); + v_x2_u32r = v_x2_u32r + ((v_x1_u32r * ((int32_t)p->dig_p5)) << 1); + v_x2_u32r = (v_x2_u32r >> 2) + (((int32_t)p->dig_p4) << 16); + v_x1_u32r = + (((p->dig_p3 * (((v_x1_u32r >> 2) * (v_x1_u32r >> 2)) >> 13)) >> 3) + + ((((int32_t)p->dig_p2) * v_x1_u32r) >> 1)) >> 18; + v_x1_u32r = ((((32768 + v_x1_u32r)) * ((int32_t)p->dig_p1)) >> 15); + + if(v_x1_u32r == 0) { + return; /* Avoid exception caused by division by zero */ + } + + pressure = (((uint32_t)(((int32_t)1048576) - upress) - (v_x2_u32r >> 12))) + * 3125; + if(pressure < 0x80000000) { + pressure = (pressure << 1) / ((uint32_t)v_x1_u32r); + } else { + pressure = (pressure / (uint32_t)v_x1_u32r) * 2; + } + + v_x1_u32r = (((int32_t)p->dig_p9) + * ((int32_t)(((pressure >> 3) * (pressure >> 3)) >> 13))) >> 12; + v_x2_u32r = (((int32_t)(pressure >> 2)) * ((int32_t)p->dig_p8)) >> 13; + pressure = (uint32_t)((int32_t)pressure + + ((v_x1_u32r + v_x2_u32r + p->dig_p7) >> 4)); + + *press = pressure; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns a reading from the sensor + * \param type BMP_280_SENSOR_TYPE_TEMP or BMP_280_SENSOR_TYPE_PRESS + * \return Temperature (centi degrees C) or Pressure (Pascal). + */ +static int +value(int type) +{ + int rv; + int32_t temp = 0; + uint32_t pres = 0; + + if(enabled != SENSOR_STATUS_READY) { + PRINTF("Sensor disabled or starting up (%d)\n", enabled); + return CC26XX_SENSOR_READING_ERROR; + } + + if((type != BMP_280_SENSOR_TYPE_TEMP) && type != BMP_280_SENSOR_TYPE_PRESS) { + PRINTF("Invalid type\n"); + return CC26XX_SENSOR_READING_ERROR; + } else { + memset(sensor_value, 0, SENSOR_DATA_BUF_SIZE); + + rv = read_data(sensor_value); + + if(rv == 0) { + return CC26XX_SENSOR_READING_ERROR; + } + + PRINTF("val: %02x%02x%02x %02x%02x%02x\n", + sensor_value[0], sensor_value[1], sensor_value[2], + sensor_value[3], sensor_value[4], sensor_value[5]); + + convert(sensor_value, &temp, &pres); + + if(type == BMP_280_SENSOR_TYPE_TEMP) { + rv = (int)temp; + } else if(type == BMP_280_SENSOR_TYPE_PRESS) { + rv = (int)pres; + } + } + return rv; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the BMP280 sensor. + * + * \param type Activate, enable or disable the sensor. See below + * \param enable + * + * When type == SENSORS_HW_INIT we turn on the hardware + * When type == SENSORS_ACTIVE and enable==1 we enable the sensor + * When type == SENSORS_ACTIVE and enable==0 we disable the sensor + */ +static int +configure(int type, int enable) +{ + switch(type) { + case SENSORS_HW_INIT: + enabled = SENSOR_STATUS_INITIALISED; + init(); + enable_sensor(0); + break; + case SENSORS_ACTIVE: + /* Must be initialised first */ + if(enabled == SENSOR_STATUS_DISABLED) { + return SENSOR_STATUS_DISABLED; + } + if(enable) { + enable_sensor(1); + ctimer_set(&startup_timer, SENSOR_STARTUP_DELAY, notify_ready, NULL); + enabled = SENSOR_STATUS_NOT_READY; + } else { + ctimer_stop(&startup_timer); + enable_sensor(0); + enabled = SENSOR_STATUS_INITIALISED; + } + break; + default: + break; + } + return enabled; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns the status of the sensor + * \param type SENSORS_ACTIVE or SENSORS_READY + * \return 1 if the sensor is enabled + */ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + break; + default: + break; + } + return SENSOR_STATUS_DISABLED; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(bmp_280_sensor, "BMP280", value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/sensortag/bmp-280-sensor.h b/platform/srf06-cc26xx/sensortag/bmp-280-sensor.h new file mode 100644 index 000000000..8bff65787 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/bmp-280-sensor.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-peripherals + * @{ + * + * \defgroup sensortag-cc26xx-bmp-sensor SensorTag 2.0 Pressure Sensor + * + * Due to the time required for the sensor to startup, this driver is meant to + * be used in an asynchronous fashion. The caller must first activate the + * sensor by calling SENSORS_ACTIVATE(). This will trigger the sensor's startup + * sequence, but the call will not wait for it to complete so that the CPU can + * perform other tasks or drop to a low power mode. + * + * Once the sensor is stable, the driver will generate a sensors_changed event. + * + * We take readings in "Forced" mode. In this mode, the BMP will take a single + * measurement and it will then automatically go to sleep. + * + * SENSORS_ACTIVATE must be called again to trigger a new reading cycle + * @{ + * + * \file + * Header file for the Sensortag-CC26xx BMP280 Altimeter / Pressure Sensor + */ +/*---------------------------------------------------------------------------*/ +#ifndef BMP_280_SENSOR_H_ +#define BMP_280_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#define BMP_280_SENSOR_TYPE_TEMP 1 +#define BMP_280_SENSOR_TYPE_PRESS 2 +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor bmp_280_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* BMP_280_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/sensortag/board-i2c.c b/platform/srf06-cc26xx/sensortag/board-i2c.c new file mode 100644 index 000000000..cf74e2a93 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/board-i2c.c @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-i2c + * @{ + * + * \file + * Board-specific I2C driver for the Sensortag-CC26xx + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "ti-lib.h" +#include "board-i2c.h" +#include "lpm.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define NO_INTERFACE 0xFF +/*---------------------------------------------------------------------------*/ +static uint8_t slave_addr = 0x00; +static uint8_t interface = NO_INTERFACE; +/*---------------------------------------------------------------------------*/ +static bool +accessible(void) +{ + /* First, check the PD */ + if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL) + != PRCM_DOMAIN_POWER_ON) { + return false; + } + + /* Then check the 'run mode' clock gate */ + if(!(HWREG(PRCM_BASE + PRCM_O_I2CCLKGR) & PRCM_I2CCLKGR_CLK_EN)) { + return false; + } + + return true; +} +/*---------------------------------------------------------------------------*/ +void +board_i2c_wakeup() +{ + /* First, make sure the SERIAL PD is on */ + ti_lib_prcm_power_domain_on(PRCM_DOMAIN_SERIAL); + while((ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL) + != PRCM_DOMAIN_POWER_ON)); + + /* Enable the clock to I2C */ + ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_I2C0); + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + /* Enable and initialize the I2C master module */ + ti_lib_i2c_master_init_exp_clk(I2C0_BASE, ti_lib_sys_ctrl_clock_get(), + true); +} +/*---------------------------------------------------------------------------*/ +static bool +i2c_status() +{ + uint32_t status; + + status = ti_lib_i2c_master_err(I2C0_BASE); + if(status & (I2C_MSTAT_DATACK_N_M | I2C_MSTAT_ADRACK_N_M)) { + ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP); + } + + return status == I2C_MASTER_ERR_NONE; +} +/*---------------------------------------------------------------------------*/ +void +board_i2c_shutdown() +{ + interface = NO_INTERFACE; + + if(accessible()) { + ti_lib_i2c_master_disable(I2C0_BASE); + } + + ti_lib_prcm_peripheral_run_disable(PRCM_PERIPH_I2C0); + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + /* + * Set all pins to GPIO Input and disable the output driver. Set internal + * pull to match external pull + * + * SDA and SCL: external PU resistor + * SDA HP and SCL HP: MPU PWR low + */ + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SDA_HP); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_SDA_HP, IOC_IOPULL_DOWN); + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SCL_HP); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_SCL_HP, IOC_IOPULL_DOWN); + + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SDA); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_SDA, IOC_IOPULL_UP); + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SCL); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_SCL, IOC_IOPULL_UP); +} +/*---------------------------------------------------------------------------*/ +bool +board_i2c_write(uint8_t *data, uint8_t len) +{ + uint32_t i; + bool success; + + /* Write slave address */ + ti_lib_i2c_master_slave_addr_set(I2C0_BASE, slave_addr, false); + + /* Write first byte */ + ti_lib_i2c_master_data_put(I2C0_BASE, data[0]); + + /* Check if another master has access */ + while(ti_lib_i2c_master_bus_busy(I2C0_BASE)); + + /* Assert RUN + START */ + ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START); + while(ti_lib_i2c_master_busy(I2C0_BASE)); + success = i2c_status(); + + for(i = 1; i < len && success; i++) { + /* Write next byte */ + ti_lib_i2c_master_data_put(I2C0_BASE, data[i]); + if(i < len - 1) { + /* Clear START */ + ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT); + while(ti_lib_i2c_master_busy(I2C0_BASE)); + success = i2c_status(); + } + } + + /* Assert stop */ + if(success) { + /* Assert STOP */ + ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH); + while(ti_lib_i2c_master_busy(I2C0_BASE)); + success = i2c_status(); + while(ti_lib_i2c_master_bus_busy(I2C0_BASE)); + } + + return success; +} +/*---------------------------------------------------------------------------*/ +bool +board_i2c_write_single(uint8_t data) +{ + bool success; + + /* Write slave address */ + ti_lib_i2c_master_slave_addr_set(I2C0_BASE, slave_addr, false); + + /* Write first byte */ + ti_lib_i2c_master_data_put(I2C0_BASE, data); + + /* Check if another master has access */ + while(ti_lib_i2c_master_bus_busy(I2C0_BASE)); + + /* Assert RUN + START + STOP */ + ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND); + while(ti_lib_i2c_master_busy(I2C0_BASE)); + success = i2c_status(); + + return success; +} +/*---------------------------------------------------------------------------*/ +bool +board_i2c_read(uint8_t *data, uint8_t len) +{ + uint8_t i; + bool success; + + /* Set slave address */ + ti_lib_i2c_master_slave_addr_set(I2C0_BASE, slave_addr, true); + + /* Check if another master has access */ + while(ti_lib_i2c_master_bus_busy(I2C0_BASE)); + + /* Assert RUN + START + ACK */ + ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START); + + i = 0; + success = true; + while(i < (len - 1) && success) { + while(ti_lib_i2c_master_busy(I2C0_BASE)); + success = i2c_status(); + if(success) { + data[i] = ti_lib_i2c_master_data_get(I2C0_BASE); + ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT); + i++; + } + } + + if(success) { + ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH); + while(ti_lib_i2c_master_busy(I2C0_BASE)); + success = i2c_status(); + if(success) { + data[len - 1] = ti_lib_i2c_master_data_get(I2C0_BASE); + while(ti_lib_i2c_master_bus_busy(I2C0_BASE)); + } + } + + return success; +} +/*---------------------------------------------------------------------------*/ +bool +board_i2c_write_read(uint8_t *wdata, uint8_t wlen, uint8_t *rdata, uint8_t rlen) +{ + uint32_t i; + bool success; + + /* Set slave address for write */ + ti_lib_i2c_master_slave_addr_set(I2C0_BASE, slave_addr, false); + + /* Write first byte */ + ti_lib_i2c_master_data_put(I2C0_BASE, wdata[0]); + + /* Check if another master has access */ + while(ti_lib_i2c_master_bus_busy(I2C0_BASE)); + + /* Assert RUN + START */ + ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START); + while(ti_lib_i2c_master_busy(I2C0_BASE)); + success = i2c_status(); + + for(i = 1; i < wlen && success; i++) { + /* Write next byte */ + ti_lib_i2c_master_data_put(I2C0_BASE, wdata[i]); + if(i < wlen - 1) { + /* Clear START */ + ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT); + while(ti_lib_i2c_master_busy(I2C0_BASE)); + success = i2c_status(); + } + } + if(!success) { + return false; + } + + /* Set slave address for read */ + ti_lib_i2c_master_slave_addr_set(I2C0_BASE, slave_addr, true); + + /* Assert ACK */ + ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START); + + i = 0; + while(i < (rlen - 1) && success) { + while(ti_lib_i2c_master_busy(I2C0_BASE)); + success = i2c_status(); + if(success) { + rdata[i] = ti_lib_i2c_master_data_get(I2C0_BASE); + ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT); + i++; + } + } + + if(success) { + ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH); + while(ti_lib_i2c_master_busy(I2C0_BASE)); + success = i2c_status(); + if(success) { + rdata[rlen - 1] = ti_lib_i2c_master_data_get(I2C0_BASE); + while(ti_lib_i2c_master_bus_busy(I2C0_BASE)); + } + } + + return success; +} +/*---------------------------------------------------------------------------*/ +void +board_i2c_select(uint8_t new_interface, uint8_t address) +{ + slave_addr = address; + + if(accessible() == false) { + board_i2c_wakeup(); + } + + if(new_interface != interface) { + interface = new_interface; + + ti_lib_i2c_master_disable(I2C0_BASE); + + if(interface == BOARD_I2C_INTERFACE_0) { + ti_lib_ioc_io_port_pull_set(BOARD_IOID_SDA, IOC_NO_IOPULL); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_SCL, IOC_NO_IOPULL); + ti_lib_ioc_pin_type_i2c(I2C0_BASE, BOARD_IOID_SDA, BOARD_IOID_SCL); + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SDA_HP); + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SCL_HP); + } else if(interface == BOARD_I2C_INTERFACE_1) { + ti_lib_ioc_io_port_pull_set(BOARD_IOID_SDA_HP, IOC_NO_IOPULL); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_SCL_HP, IOC_NO_IOPULL); + ti_lib_ioc_pin_type_i2c(I2C0_BASE, BOARD_IOID_SDA_HP, BOARD_IOID_SCL_HP); + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SDA); + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SCL); + } + + /* Enable and initialize the I2C master module */ + ti_lib_i2c_master_init_exp_clk(I2C0_BASE, ti_lib_sys_ctrl_clock_get(), + true); + } +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/sensortag/board-i2c.h b/platform/srf06-cc26xx/sensortag/board-i2c.h new file mode 100644 index 000000000..40832c9bd --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/board-i2c.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-peripherals + * @{ + * + * \defgroup sensortag-cc26xx-i2c SensorTag 2.0 I2C functions + * @{ + * + * \file + * Header file for the Sensortag-CC26xx I2C Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef BOARD_I2C_H_ +#define BOARD_I2C_H_ +/*---------------------------------------------------------------------------*/ +#include +#include +/*---------------------------------------------------------------------------*/ +#define BOARD_I2C_INTERFACE_0 0 +#define BOARD_I2C_INTERFACE_1 1 +/*---------------------------------------------------------------------------*/ +/** + * \brief Put the I2C controller in a known state + * + * In this state, pins SDA and SCL will be under i2c control and pins SDA HP + * and SCL HP will be configured as gpio inputs. This is equal to selecting + * BOARD_I2C_INTERFACE_0, but without selecting a slave device address + */ +#define board_i2c_deselect() board_i2c_select(BOARD_I2C_INTERFACE_0, 0) +/*---------------------------------------------------------------------------*/ +/** + * \brief Select an I2C slave + * \param interface The I2C interface to be used (BOARD_I2C_INTERFACE_0 or _1) + * \param slave_addr The slave's address + * + * The various sensors on the sensortag are connected either on interface 0 or + * 1. All sensors are connected to interface 0, with the exception of the MPU + * that is connected to 1. + */ +void board_i2c_select(uint8_t interface, uint8_t slave_addr); + +/** + * \brief Burst read from an I2C device + * \param buf Pointer to a buffer where the read data will be stored + * \param len Number of bytes to read + * \return True on success + */ +bool board_i2c_read(uint8_t *buf, uint8_t len); + +/** + * \brief Burst write to an I2C device + * \param buf Pointer to the buffer to be written + * \param len Number of bytes to write + * \return True on success + */ +bool board_i2c_write(uint8_t *buf, uint8_t len); + +/** + * \brief Single write to an I2C device + * \param data The byte to write + * \return True on success + */ +bool board_i2c_write_single(uint8_t data); + +/** + * \brief Write and read in one operation + * \param wdata Pointer to the buffer to be written + * \param wlen Number of bytes to write + * \param rdata Pointer to a buffer where the read data will be stored + * \param rlen Number of bytes to read + * \return True on success + */ +bool board_i2c_write_read(uint8_t *wdata, uint8_t wlen, uint8_t *rdata, + uint8_t rlen); + +/** + * \brief Enables the I2C peripheral with defaults + * + * This function is called to wakeup and initialise the I2C. + * + * This function can be called explicitly, but it will also be called + * automatically by board_i2c_select() when required. One of those two + * functions MUST be called before any other I2C operation after a chip + * sleep / wakeup cycle or after a call to board_i2c_shutdown(). Failing to do + * so will lead to a bus fault. + */ +void board_i2c_wakeup(void); + +/** + * \brief Stops the I2C peripheral and restores pins to s/w control + * + * This function is called automatically by the board's LPM logic, but it + * can also be called explicitly. + */ +void board_i2c_shutdown(void); +/*---------------------------------------------------------------------------*/ +#endif /* BOARD_I2C_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/sensortag/board-peripherals.h b/platform/srf06-cc26xx/sensortag/board-peripherals.h new file mode 100644 index 000000000..9c994d9e6 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/board-peripherals.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** \addtogroup cc26xx-srf-tag + * @{ + * + * \file + * Header file with definitions related to the sensors on the Sensortag-CC26xx + * + * \note Do not include this file directly. + */ +/*---------------------------------------------------------------------------*/ +#ifndef BOARD_PERIPHERALS_H_ +#define BOARD_PERIPHERALS_H_ +/*---------------------------------------------------------------------------*/ +#include "bmp-280-sensor.h" +#include "tmp-007-sensor.h" +#include "opt-3001-sensor.h" +#include "hdc-1000-sensor.h" +#include "mpu-9250-sensor.h" +#include "reed-relay.h" +#include "buzzer.h" +#include "ext-flash.h" +/*---------------------------------------------------------------------------*/ +#endif /* BOARD_PERIPHERALS_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/platform/srf06-cc26xx/sensortag/board.c b/platform/srf06-cc26xx/sensortag/board.c new file mode 100644 index 000000000..f06545170 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/board.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-peripherals + * @{ + * + * \file + * Sensortag-specific board initialisation driver + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "lib/sensors.h" +#include "buzzer.h" +#include "lpm.h" +#include "ti-lib.h" +#include "board-peripherals.h" +#include "board-i2c.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +static void +power_domains_on(void) +{ + /* Turn on the PERIPH PD */ + ti_lib_prcm_power_domain_on(PRCM_DOMAIN_PERIPH); + + /* Wait for domains to power on */ + while((ti_lib_prcm_power_domain_status(PRCM_DOMAIN_PERIPH) + != PRCM_DOMAIN_POWER_ON)); +} +/*---------------------------------------------------------------------------*/ +static void +lpm_wakeup_handler(void) +{ + power_domains_on(); +} +/*---------------------------------------------------------------------------*/ +static void +shutdown_handler(uint8_t mode) +{ + if(mode == LPM_MODE_SHUTDOWN) { + buzzer_stop(); + SENSORS_DEACTIVATE(bmp_280_sensor); + SENSORS_DEACTIVATE(opt_3001_sensor); + SENSORS_DEACTIVATE(tmp_007_sensor); + SENSORS_DEACTIVATE(hdc_1000_sensor); + SENSORS_DEACTIVATE(mpu_9250_sensor); + ti_lib_gpio_pin_clear(BOARD_MPU_POWER); + } + + /* In all cases, stop the I2C */ + board_i2c_shutdown(); +} +/*---------------------------------------------------------------------------*/ +/* + * Declare a data structure to register with LPM. + * We don't care about what power mode we'll drop to, we don't care about + * getting notified before deep sleep. All we need is to be notified when we + * wake up so we can turn power domains back on for I2C and SSI, and to make + * sure everything on the board is off before CM3 shutdown. + */ +LPM_MODULE(sensortag_module, NULL, shutdown_handler, lpm_wakeup_handler, + LPM_DOMAIN_NONE); +/*---------------------------------------------------------------------------*/ +static void +configure_unused_pins(void) +{ + /* DP[0..3] */ + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_DP0); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_DP0, IOC_IOPULL_DOWN); + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_DP1); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_DP1, IOC_IOPULL_DOWN); + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_DP2); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_DP2, IOC_IOPULL_DOWN); + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_DP3); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_DP3, IOC_IOPULL_DOWN); + + /* Devpack ID */ + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_DEVPK_ID); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_DEVPK_ID, IOC_IOPULL_UP); + + /* Digital Microphone */ + ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_MIC_POWER); + ti_lib_gpio_pin_clear((1 << BOARD_IOID_MIC_POWER)); + ti_lib_ioc_io_drv_strength_set(BOARD_IOID_MIC_POWER, IOC_CURRENT_2MA, + IOC_STRENGTH_MIN); + + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_AUDIO_DI); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_AUDIO_DI, IOC_IOPULL_DOWN); + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_AUDIO_CLK); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_AUDIO_CLK, IOC_IOPULL_DOWN); + + /* UART over Devpack - TX only (ToDo: Map all UART pins to Debugger) */ + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_DP5_UARTTX); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_DP5_UARTTX, IOC_IOPULL_DOWN); +} +/*---------------------------------------------------------------------------*/ +void +board_init() +{ + /* Disable global interrupts */ + bool int_disabled = ti_lib_int_master_disable(); + + power_domains_on(); + + /* Enable GPIO peripheral */ + ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_GPIO); + + /* Apply settings and wait for them to take effect */ + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + /* I2C controller */ + board_i2c_wakeup(); + + buzzer_init(); + + /* Make sure the external flash is in the lower power mode */ + ext_flash_init(); + + lpm_register_module(&sensortag_module); + + /* For unsupported peripherals, select a default pin configuration */ + configure_unused_pins(); + + /* Re-enable interrupt if initially enabled. */ + if(!int_disabled) { + ti_lib_int_master_enable(); + } +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/sensortag/button-sensor.c b/platform/srf06-cc26xx/sensortag/button-sensor.c new file mode 100644 index 000000000..921d96b20 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/button-sensor.c @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-button-sensor + * @{ + * + * \file + * Driver for the Sensortag-CC26xx buttons + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/sensors.h" +#include "sensortag/button-sensor.h" +#include "gpio-interrupt.h" +#include "sys/timer.h" +#include "lpm.h" + +#include "ti-lib.h" + +#include +/*---------------------------------------------------------------------------*/ +#ifdef BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN +#define BUTTON_SENSOR_ENABLE_SHUTDOWN BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN +#else +#define BUTTON_SENSOR_ENABLE_SHUTDOWN 1 +#endif +/*---------------------------------------------------------------------------*/ +#define BUTTON_GPIO_CFG (IOC_CURRENT_2MA | IOC_STRENGTH_AUTO | \ + IOC_IOPULL_UP | IOC_SLEW_DISABLE | \ + IOC_HYST_DISABLE | IOC_BOTH_EDGES | \ + IOC_INT_ENABLE | IOC_IOMODE_NORMAL | \ + IOC_NO_WAKE_UP | IOC_INPUT_ENABLE) +/*---------------------------------------------------------------------------*/ +#define DEBOUNCE_DURATION (CLOCK_SECOND >> 5) + +struct btn_timer { + struct timer debounce; + clock_time_t start; + clock_time_t duration; +}; + +static struct btn_timer left_timer, right_timer; +/*---------------------------------------------------------------------------*/ +/** + * \brief Handler for Sensortag-CC26XX button presses + */ +static void +button_press_handler(uint8_t ioid) +{ + if(ioid == BOARD_IOID_KEY_LEFT) { + if(!timer_expired(&left_timer.debounce)) { + return; + } + + timer_set(&left_timer.debounce, DEBOUNCE_DURATION); + + /* + * Start press duration counter on press (falling), notify on release + * (rising) + */ + if(ti_lib_gpio_pin_read(BOARD_KEY_LEFT) == 0) { + left_timer.start = clock_time(); + left_timer.duration = 0; + } else { + left_timer.duration = clock_time() - left_timer.start; + sensors_changed(&button_left_sensor); + } + } + + if(ioid == BOARD_IOID_KEY_RIGHT) { + if(BUTTON_SENSOR_ENABLE_SHUTDOWN == 0) { + if(!timer_expired(&right_timer.debounce)) { + return; + } + + timer_set(&right_timer.debounce, DEBOUNCE_DURATION); + + /* + * Start press duration counter on press (falling), notify on release + * (rising) + */ + if(ti_lib_gpio_pin_read(BOARD_KEY_RIGHT) == 0) { + right_timer.start = clock_time(); + right_timer.duration = 0; + } else { + right_timer.duration = clock_time() - right_timer.start; + sensors_changed(&button_right_sensor); + } + } else { + lpm_shutdown(BOARD_IOID_KEY_RIGHT, IOC_IOPULL_UP, IOC_WAKE_ON_LOW); + } + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the button sensor for all buttons. + * + * \param type This function does nothing unless type == SENSORS_ACTIVE + * \param c 0: disable the button, non-zero: enable + * \param key: One of BOARD_KEY_LEFT, BOARD_KEY_RIGHT etc + */ +static void +config_buttons(int type, int c, uint32_t key) +{ + switch(type) { + case SENSORS_HW_INIT: + ti_lib_gpio_event_clear(1 << key); + ti_lib_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); + ti_lib_gpio_dir_mode_set((1 << key), GPIO_DIR_MODE_IN); + gpio_interrupt_register_handler(key, button_press_handler); + break; + case SENSORS_ACTIVE: + if(c) { + ti_lib_gpio_event_clear(1 << key); + ti_lib_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); + ti_lib_gpio_dir_mode_set((1 << key), GPIO_DIR_MODE_IN); + ti_lib_ioc_int_enable(key); + } else { + ti_lib_ioc_int_disable(key); + } + break; + default: + break; + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the left button. + * + * Parameters are passed onto config_buttons, which does the actual + * configuration + * Parameters are ignored. They have been included because the prototype is + * dictated by the core sensor API. The return value is also required by + * the API but otherwise ignored. + * + * \param type passed to config_buttons as-is + * \param value passed to config_buttons as-is + * + * \return ignored + */ +static int +config_left(int type, int value) +{ + config_buttons(type, value, BOARD_IOID_KEY_LEFT); + + return 1; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the right button. + * + * Parameters are passed onto config_buttons, which does the actual + * configuration + * Parameters are ignored. They have been included because the prototype is + * dictated by the core sensor api. The return value is also required by + * the API but otherwise ignored. + * + * \param type passed to config_buttons as-is + * \param value passed to config_buttons as-is + * + * \return ignored + */ +static int +config_right(int type, int value) +{ + config_buttons(type, value, BOARD_IOID_KEY_RIGHT); + + return 1; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for all buttons + * \param type SENSORS_ACTIVE or SENSORS_READY + * \param key_io_id BOARD_IOID_KEY_LEFT, BOARD_IOID_KEY_RIGHT etc + * \return 1 if the button's port interrupt is enabled (edge detect) + * + * This function will only be called by status_left, status_right and the + * called will pass the correct key_io_id + */ +static int +status(int type, uint32_t key_io_id) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + if(ti_lib_ioc_port_configure_get(key_io_id) & IOC_INT_ENABLE) { + return 1; + } + break; + default: + break; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value_left(int type) +{ + if(type == BUTTON_SENSOR_VALUE_STATE) { + return ti_lib_gpio_pin_read(BOARD_KEY_LEFT) == 0 ? + BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; + } else if(type == BUTTON_SENSOR_VALUE_DURATION) { + return (int)left_timer.duration; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value_right(int type) +{ + if(type == BUTTON_SENSOR_VALUE_STATE) { + return ti_lib_gpio_pin_read(BOARD_KEY_RIGHT) == 0 ? + BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; + } else if(type == BUTTON_SENSOR_VALUE_DURATION) { + return (int)right_timer.duration; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for the left button. + * \param type SENSORS_ACTIVE or SENSORS_READY + * \return 1 if the button's port interrupt is enabled (edge detect) + * + * This function will call status. It will pass type verbatim and it will also + * pass the correct key_io_id + */ +static int +status_left(int type) +{ + return status(type, BOARD_IOID_KEY_LEFT); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for the right button. + * \param type SENSORS_ACTIVE or SENSORS_READY + * \return 1 if the button's port interrupt is enabled (edge detect) + * + * This function will call status. It will pass type verbatim and it will also + * pass the correct key_io_id + */ +static int +status_right(int type) +{ + return status(type, BOARD_IOID_KEY_RIGHT); +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(button_left_sensor, BUTTON_SENSOR, value_left, config_left, + status_left); +SENSORS_SENSOR(button_right_sensor, BUTTON_SENSOR, value_right, config_right, + status_right); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/sensortag/button-sensor.h b/platform/srf06-cc26xx/sensortag/button-sensor.h new file mode 100644 index 000000000..25acb104f --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/button-sensor.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-peripherals + * @{ + * + * \defgroup sensortag-cc26xx-button-sensor SensorTag 2.0 Button Sensor + * + * One of the buttons can be configured as general purpose or as an on/off key + * @{ + * + * \file + * Header file for the Sensortag-CC26xx Button Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef BUTTON_SENSOR_H_ +#define BUTTON_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR "Button" +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR_VALUE_STATE 0 +#define BUTTON_SENSOR_VALUE_DURATION 1 + +#define BUTTON_SENSOR_VALUE_RELEASED 0 +#define BUTTON_SENSOR_VALUE_PRESSED 1 +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor button_left_sensor; +extern const struct sensors_sensor button_right_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* BUTTON_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/sensortag/buzzer.c b/platform/srf06-cc26xx/sensortag/buzzer.c new file mode 100644 index 000000000..d7f48e4de --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/buzzer.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-buzzer + * @{ + * + * \file + * Driver for the Sensortag-CC26XX Buzzer + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "buzzer.h" +#include "ti-lib.h" +#include "lpm.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +static uint8_t buzzer_on; +LPM_MODULE(buzzer_module, NULL, NULL, NULL, LPM_DOMAIN_PERIPH); +/*---------------------------------------------------------------------------*/ +void +buzzer_init() +{ + buzzer_on = 0; +} +/*---------------------------------------------------------------------------*/ +uint8_t +buzzer_state() +{ + return buzzer_on; +} +/*---------------------------------------------------------------------------*/ +void +buzzer_start(int freq) +{ + uint32_t load; + + /* Enable GPT0 clocks under active, sleep, deep sleep */ + ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_TIMER0); + ti_lib_prcm_peripheral_sleep_enable(PRCM_PERIPH_TIMER0); + ti_lib_prcm_peripheral_deep_sleep_enable(PRCM_PERIPH_TIMER0); + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + /* Drive the I/O ID with GPT0 / Timer A */ + ti_lib_ioc_port_configure_set(BOARD_IOID_BUZZER, IOC_PORT_MCU_PORT_EVENT0, + IOC_STD_OUTPUT); + + /* GPT0 / Timer A: PWM, Interrupt Enable */ + HWREG(GPT0_BASE + GPT_O_TAMR) = (TIMER_CFG_A_PWM & 0xFF) | GPT_TAMR_TAPWMIE; + + buzzer_on = 1; + + /* + * Register ourself with LPM. This will keep the PERIPH PD powered on + * during deep sleep, allowing the buzzer to keep working while the chip is + * being power-cycled + */ + lpm_register_module(&buzzer_module); + + /* Stop the timer */ + ti_lib_timer_disable(GPT0_BASE, TIMER_A); + + if(freq > 0) { + load = (GET_MCU_CLOCK / freq); + + ti_lib_timer_load_set(GPT0_BASE, TIMER_A, load); + ti_lib_timer_match_set(GPT0_BASE, TIMER_A, load / 2); + + /* Start */ + ti_lib_timer_enable(GPT0_BASE, TIMER_A); + } +} +/*---------------------------------------------------------------------------*/ +void +buzzer_stop() +{ + buzzer_on = 0; + + /* + * Unregister the buzzer module from LPM. This will effectively release our + * lock for the PERIPH PD allowing it to be powered down (unless some other + * module keeps it on) + */ + lpm_unregister_module(&buzzer_module); + + /* Stop the timer */ + ti_lib_timer_disable(GPT0_BASE, TIMER_A); + + /* + * Stop the module clock: + * + * Currently GPT0 is in use by clock_delay_usec (GPT0/TB) and by this + * module here (GPT0/TA). + * + * clock_delay_usec + * - is definitely not running when we enter here and + * - handles the module clock internally + * + * Thus, we can safely change the state of module clocks here. + */ + ti_lib_prcm_peripheral_run_disable(PRCM_PERIPH_TIMER0); + ti_lib_prcm_peripheral_sleep_disable(PRCM_PERIPH_TIMER0); + ti_lib_prcm_peripheral_deep_sleep_disable(PRCM_PERIPH_TIMER0); + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + /* Un-configure the pin */ + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_BUZZER); + ti_lib_ioc_io_input_set(BOARD_IOID_BUZZER, IOC_INPUT_DISABLE); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/sensortag/buzzer.h b/platform/srf06-cc26xx/sensortag/buzzer.h new file mode 100644 index 000000000..653b46f88 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/buzzer.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-peripherals + * @{ + * + * \defgroup sensortag-cc26xx-buzzer SensorTag 2.0 Buzzer + * @{ + * + * \file + * Header file for the Sensortag-CC26xx Buzzer + */ +/*---------------------------------------------------------------------------*/ +#ifndef BUZZER_H_ +#define BUZZER_H_ +/*---------------------------------------------------------------------------*/ +#include +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialise the buzzer + */ +void buzzer_init(void); + +/** + * \brief Start the buzzer + * \param freq The buzzer frequency + */ +void buzzer_start(int freq); + +/** + * \brief Stop the buzzer + */ +void buzzer_stop(void); + +/** + * \brief Retrieve the buzzer state + * \return 1: on, 0: off + */ +uint8_t buzzer_state(void); +/*---------------------------------------------------------------------------*/ +#endif /* BUZZER_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/sensortag/cc2650/Makefile.cc2650 b/platform/srf06-cc26xx/sensortag/cc2650/Makefile.cc2650 new file mode 100644 index 000000000..5b7cdadd9 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/cc2650/Makefile.cc2650 @@ -0,0 +1,11 @@ +### Add to the source list +BOARD_SOURCEFILES += leds-arch.c + +### Will allow the inclusion of the correct CPU makefile +CPU_FAMILY = cc26xx + +### Add to the source dirs +CONTIKI_TARGET_DIRS += sensortag/cc2650 + +### Include the common sensortag makefile +include $(PLATFORM_ROOT_DIR)/sensortag/Makefile.sensortag diff --git a/platform/srf06-cc26xx/sensortag/cc2650/board.h b/platform/srf06-cc26xx/sensortag/cc2650/board.h new file mode 100644 index 000000000..9f0a7abd3 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/cc2650/board.h @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** \addtogroup cc26xx-srf-tag + * @{ + * + * \defgroup sensortag-cc26xx-peripherals Sensortag Peripherals + * + * Defines related to the CC2650 Sensortag + * + * This file provides connectivity information on LEDs, Buttons, UART and + * other peripherals + * + * This file can be used as the basis to configure other boards using the + * CC13xx/CC26xx code as their basis. + * + * This file is not meant to be modified by the user. + * @{ + * + * \file + * Header file with definitions related to the I/O connections on the TI + * Sensortag + * + * \note Do not include this file directly. It gets included by contiki-conf + * after all relevant directives have been set. + */ +/*---------------------------------------------------------------------------*/ +#ifndef BOARD_H_ +#define BOARD_H_ +/*---------------------------------------------------------------------------*/ +#include "ioc.h" +/*---------------------------------------------------------------------------*/ +/** + * \name LED configurations + * + * Those values are not meant to be modified by the user + * @{ + */ +/* Some files include leds.h before us, so we need to get rid of defaults in + * leds.h before we provide correct definitions */ +#undef LEDS_GREEN +#undef LEDS_YELLOW +#undef LEDS_RED +#undef LEDS_CONF_ALL + +#define LEDS_RED 1 +#define LEDS_GREEN 2 +#define LEDS_YELLOW LEDS_GREEN +#define LEDS_ORANGE LEDS_RED + +#define LEDS_CONF_ALL 3 + +/* Notify various examples that we have LEDs */ +#define PLATFORM_HAS_LEDS 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name LED IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_LED_1 IOID_10 +#define BOARD_IOID_LED_2 IOID_15 +#define BOARD_LED_1 (1 << BOARD_IOID_LED_1) +#define BOARD_LED_2 (1 << BOARD_IOID_LED_2) +#define BOARD_LED_ALL (BOARD_LED_1 | BOARD_LED_2) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name UART IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_DP4_UARTRX IOID_28 +#define BOARD_IOID_DP5_UARTTX IOID_29 + +#if BOARD_CONF_DEBUGGER_DEVPACK +#define BOARD_IOID_UART_RX BOARD_IOID_DP4_UARTRX +#define BOARD_IOID_UART_TX BOARD_IOID_DP5_UARTTX +#else +#define BOARD_IOID_UART_RX IOID_17 +#define BOARD_IOID_UART_TX IOID_16 +#endif + +#define BOARD_IOID_UART_CTS IOID_UNUSED +#define BOARD_IOID_UART_RTS IOID_UNUSED +#define BOARD_UART_RX (1 << BOARD_IOID_UART_RX) +#define BOARD_UART_TX (1 << BOARD_IOID_UART_TX) +#define BOARD_UART_CTS (1 << BOARD_IOID_UART_CTS) +#define BOARD_UART_RTS (1 << BOARD_IOID_UART_RTS) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Button IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_KEY_LEFT IOID_0 +#define BOARD_IOID_KEY_RIGHT IOID_4 +#define BOARD_KEY_LEFT (1 << BOARD_IOID_KEY_LEFT) +#define BOARD_KEY_RIGHT (1 << BOARD_IOID_KEY_RIGHT) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief SPI IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_SPI_MOSI IOID_19 +#define BOARD_IOID_SPI_MISO IOID_18 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Buzzer configuration + * @{ + */ +#define BOARD_IOID_BUZZER IOID_21 /**< Buzzer Pin */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Reed Relay IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_REED_RELAY IOID_3 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name External flash IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_FLASH_CS IOID_14 +#define BOARD_FLASH_CS (1 << BOARD_IOID_FLASH_CS) +#define BOARD_IOID_SPI_CLK_FLASH IOID_17 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief I2C IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_SDA IOID_5 /**< Interface 0 SDA: All sensors bar MPU */ +#define BOARD_IOID_SCL IOID_6 /**< Interface 0 SCL: All sensors bar MPU */ +#define BOARD_IOID_SDA_HP IOID_8 /**< Interface 1 SDA: MPU */ +#define BOARD_IOID_SCL_HP IOID_9 /**< Interface 1 SCL: MPU */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief MPU IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_MPU_INT IOID_7 +#define BOARD_IOID_MPU_POWER IOID_12 +#define BOARD_MPU_INT (1 << BOARD_IOID_MPU_INT) +#define BOARD_MPU_POWER (1 << BOARD_IOID_MPU_POWER) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief Board devpack IOID mappings (LCD etc.) + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_AUDIOFS_TDO IOID_16 +#define BOARD_IOID_DEVPACK_CS IOID_20 +#define BOARD_IOID_DEVPK_LCD_EXTCOMIN IOID_22 +#define BOARD_IOID_AUDIODO IOID_22 +#define BOARD_IOID_DP2 IOID_23 +#define BOARD_IOID_DP1 IOID_24 +#define BOARD_IOID_DP0 IOID_25 +#define BOARD_IOID_DP3 IOID_27 +#define BOARD_IOID_DEVPK_ID IOID_30 +#define BOARD_DEVPACK_CS (1 << BOARD_IOID_DEVPACK_CS) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief TMP Sensor + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_TMP_RDY IOID_1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \brief Digital Microphone + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_MIC_POWER IOID_13 +#define BOARD_IOID_AUDIO_DI IOID_2 +#define BOARD_IOID_AUDIO_CLK IOID_11 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Device string used on startup + * @{ + */ +#define BOARD_STRING "TI CC2650 SensorTag" + +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* BOARD_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/sensortag/cc2650/leds-arch.c b/platform/srf06-cc26xx/sensortag/cc2650/leds-arch.c new file mode 100644 index 000000000..e415dca55 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/cc2650/leds-arch.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-peripherals + * @{ + * + * \file + * Driver for the Sensortag-CC26XX LEDs + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/leds.h" + +#include "ti-lib.h" +/*---------------------------------------------------------------------------*/ +static unsigned char c; +static int inited = 0; +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + if(inited) { + return; + } + inited = 1; + + ti_lib_rom_ioc_pin_type_gpio_output(BOARD_IOID_LED_1); + ti_lib_rom_ioc_pin_type_gpio_output(BOARD_IOID_LED_2); + + ti_lib_gpio_pin_write(BOARD_LED_ALL, 0); +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + return c; +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char leds) +{ + c = leds; + ti_lib_gpio_pin_write(BOARD_LED_ALL, 0); + + if((leds & LEDS_RED) == LEDS_RED) { + ti_lib_gpio_pin_write(BOARD_LED_1, 1); + } + if((leds & LEDS_YELLOW) == LEDS_YELLOW) { + ti_lib_gpio_pin_write(BOARD_LED_2, 1); + } +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/sensortag/hdc-1000-sensor.c b/platform/srf06-cc26xx/sensortag/hdc-1000-sensor.c new file mode 100644 index 000000000..8fdd6d847 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/hdc-1000-sensor.c @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-hdc-sensor + * @{ + * + * \file + * Driver for the Sensortag-CC26xx HDC sensor + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "sys/ctimer.h" +#include "lib/sensors.h" +#include "hdc-1000-sensor.h" +#include "sensor-common.h" +#include "board-i2c.h" + +#include "ti-lib.h" + +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +/* Sensor I2C address */ +#define SENSOR_I2C_ADDRESS 0x43 + +/* Registers */ +#define HDC1000_REG_TEMP 0x00 /* Temperature */ +#define HDC1000_REG_HUM 0x01 /* Humidity */ +#define HDC1000_REG_CONFIG 0x02 /* Configuration */ +#define HDC1000_REG_SERID_H 0xFB /* Serial ID high */ +#define HDC1000_REG_SERID_M 0xFC /* Serial ID middle */ +#define HDC1000_REG_SERID_L 0xFD /* Serial ID low */ +#define HDC1000_REG_MANF_ID 0xFE /* Manufacturer ID */ +#define HDC1000_REG_DEV_ID 0xFF /* Device ID */ + +/* Fixed values */ +#define HDC1000_VAL_MANF_ID 0x5449 +#define HDC1000_VAL_DEV_ID 0x1000 +#define HDC1000_VAL_CONFIG 0x1000 /* 14 bit, acquired in sequence */ + +/* Sensor selection/deselection */ +#define SENSOR_SELECT() board_i2c_select(BOARD_I2C_INTERFACE_0, SENSOR_I2C_ADDRESS) +#define SENSOR_DESELECT() board_i2c_deselect() +/*---------------------------------------------------------------------------*/ +/* Byte swap of 16-bit register value */ +#define HI_UINT16(a) (((a) >> 8) & 0xFF) +#define LO_UINT16(a) ((a) & 0xFF) + +#define SWAP(v) ((LO_UINT16(v) << 8) | HI_UINT16(v)) +/*---------------------------------------------------------------------------*/ +/* Raw data as returned from the sensor (Big Endian) */ +typedef struct sensor_data { + uint16_t temp; + uint16_t hum; +} sensor_data_t; + +/* Raw data, little endian */ +static uint16_t raw_temp; +static uint16_t raw_hum; +/*---------------------------------------------------------------------------*/ +static bool success; +static sensor_data_t data; +/*---------------------------------------------------------------------------*/ +static int enabled = HDC_1000_SENSOR_STATUS_DISABLED; +/*---------------------------------------------------------------------------*/ +/* + * Maximum measurement durations in clock ticks. We use 14bit resolution, thus: + * - Tmp: 6.35ms + * - RH: 6.5ms + */ +#define MEASUREMENT_DURATION 2 + +/* + * Wait SENSOR_STARTUP_DELAY clock ticks between activation and triggering a + * reading (max 15ms) + */ +#define SENSOR_STARTUP_DELAY 3 + +static struct ctimer startup_timer; +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialise the humidity sensor driver + * \return True if I2C operation successful + */ +static bool +sensor_init(void) +{ + uint16_t val; + + SENSOR_SELECT(); + + /* Enable reading data in one operation */ + val = SWAP(HDC1000_VAL_CONFIG); + success = sensor_common_write_reg(HDC1000_REG_CONFIG, (uint8_t *)&val, 2); + + SENSOR_DESELECT(); + + return success; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Start measurement + */ +static void +start(void) +{ + if(success) { + SENSOR_SELECT(); + + success = board_i2c_write_single(HDC1000_REG_TEMP); + SENSOR_DESELECT(); + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Take readings from the sensor + * \return true of I2C operations successful + */ +static bool +read_data() +{ + bool valid; + + if(success) { + SENSOR_SELECT(); + + success = board_i2c_read((uint8_t *)&data, sizeof(data)); + SENSOR_DESELECT(); + + /* Store temperature */ + raw_temp = SWAP(data.temp); + + /* Store humidity */ + raw_hum = SWAP(data.hum); + } + + valid = success; + success = true; + + return valid; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Convert raw data to temperature and humidity + * \param temp - converted temperature + * \param hum - converted humidity + */ +static void +convert(float *temp, float *hum) +{ + /* Convert temperature to degrees C */ + *temp = ((double)(int16_t)raw_temp / 65536) * 165 - 40; + + /* Convert relative humidity to a %RH value */ + *hum = ((double)raw_hum / 65536) * 100; +} +/*---------------------------------------------------------------------------*/ +static void +notify_ready(void *not_used) +{ + enabled = HDC_1000_SENSOR_STATUS_READINGS_READY; + + /* Latch readings */ + read_data(); + + sensors_changed(&hdc_1000_sensor); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns a reading from the sensor + * \param type HDC_1000_SENSOR_TYPE_TEMP or HDC_1000_SENSOR_TYPE_HUMIDITY + * \return Temperature (centi degrees C) or Humidity (centi %RH) + */ +static int +value(int type) +{ + int rv; + float temp; + float hum; + + if(enabled != HDC_1000_SENSOR_STATUS_READINGS_READY) { + PRINTF("Sensor disabled or starting up (%d)\n", enabled); + return CC26XX_SENSOR_READING_ERROR; + } + + if((type != HDC_1000_SENSOR_TYPE_TEMP) && + type != HDC_1000_SENSOR_TYPE_HUMIDITY) { + PRINTF("Invalid type\n"); + return CC26XX_SENSOR_READING_ERROR; + } else { + convert(&temp, &hum); + PRINTF("HDC: %04X %04X t=%d h=%d\n", raw_temp, raw_hum, + (int)(temp * 100), (int)(hum * 100)); + + if(type == HDC_1000_SENSOR_TYPE_TEMP) { + rv = (int)(temp * 100); + } else if(type == HDC_1000_SENSOR_TYPE_HUMIDITY) { + rv = (int)(hum * 100); + } + } + return rv; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the HDC1000 sensor. + * + * \param type Activate, enable or disable the sensor. See below + * \param enable + * + * When type == SENSORS_HW_INIT we turn on the hardware + * When type == SENSORS_ACTIVE and enable==1 we enable the sensor + * When type == SENSORS_ACTIVE and enable==0 we disable the sensor + */ +static int +configure(int type, int enable) +{ + switch(type) { + case SENSORS_HW_INIT: + raw_temp = 0; + raw_hum = 0; + memset(&data, 0, sizeof(data)); + + sensor_init(); + enabled = HDC_1000_SENSOR_STATUS_INITIALISED; + break; + case SENSORS_ACTIVE: + /* Must be initialised first */ + if(enabled == HDC_1000_SENSOR_STATUS_DISABLED) { + return HDC_1000_SENSOR_STATUS_DISABLED; + } + if(enable) { + start(); + ctimer_set(&startup_timer, SENSOR_STARTUP_DELAY, notify_ready, NULL); + enabled = HDC_1000_SENSOR_STATUS_TAKING_READINGS; + } else { + ctimer_stop(&startup_timer); + enabled = HDC_1000_SENSOR_STATUS_INITIALISED; + } + break; + default: + break; + } + return enabled; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns the status of the sensor + * \param type SENSORS_ACTIVE or SENSORS_READY + * \return One of the SENSOR_STATUS_xyz defines + */ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + break; + default: + break; + } + return HDC_1000_SENSOR_STATUS_DISABLED; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(hdc_1000_sensor, "HDC1000", value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/sensortag/hdc-1000-sensor.h b/platform/srf06-cc26xx/sensortag/hdc-1000-sensor.h new file mode 100755 index 000000000..990b1ab69 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/hdc-1000-sensor.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-peripherals + * @{ + * + * \defgroup sensortag-cc26xx-hdc-sensor SensorTag 2.0 TI HDC1000 Sensor + * + * Due to the time required for the sensor to startup, this driver is meant to + * be used in an asynchronous fashion. The caller must first activate the + * sensor by calling SENSORS_ACTIVATE(). This will trigger the sensor's startup + * sequence, but the call will not wait for it to complete so that the CPU can + * perform other tasks or drop to a low power mode. Once the sensor has taken + * readings, it will automatically go back to low power mode. + * + * Once the sensor is stable, the driver will retrieve readings from the sensor + * and latch them. It will then generate a sensors_changed event. + * + * The user can then retrieve readings by calling .value() and by passing + * either HDC_1000_SENSOR_TYPE_TEMP or HDC_1000_SENSOR_TYPE_HUMIDITY as the + * argument. Multiple calls to value() will not trigger new readings, they will + * simply return the most recent latched values. + * + * The user can query the sensor's status by calling .status() + * + * To get a fresh reading, the user must trigger a new reading cycle by calling + * SENSORS_ACTIVATE(). + * @{ + * + * \file + * Header file for the Sensortag-CC26ss TI HDC1000 sensor + */ +/*---------------------------------------------------------------------------*/ +#ifndef HDC_1000_SENSOR_H +#define HDC_1000_SENSOR_H +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define HDC_1000_SENSOR_TYPE_TEMP 1 +#define HDC_1000_SENSOR_TYPE_HUMIDITY 2 +/*---------------------------------------------------------------------------*/ +/** + * \name HDC1000 driver states + * @{ + */ +#define HDC_1000_SENSOR_STATUS_DISABLED 0 /**< Not initialised */ +#define HDC_1000_SENSOR_STATUS_INITIALISED 1 /**< Initialised but idle */ +#define HDC_1000_SENSOR_STATUS_TAKING_READINGS 2 /**< Readings in progress */ +#define HDC_1000_SENSOR_STATUS_READINGS_READY 3 /**< Both readings ready */ +/** @} */ +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor hdc_1000_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* HDC_1000_SENSOR_H */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/sensortag/mpu-9250-sensor.c b/platform/srf06-cc26xx/sensortag/mpu-9250-sensor.c new file mode 100644 index 000000000..275f2b352 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/mpu-9250-sensor.c @@ -0,0 +1,663 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-mpu + * @{ + * + * \file + * Driver for the Sensortag-CC26XX Invensense MPU9250 motion processing unit + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "lib/sensors.h" +#include "mpu-9250-sensor.h" +#include "sys/rtimer.h" +#include "sensor-common.h" +#include "board-i2c.h" + +#include "ti-lib.h" + +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +/* Sensor I2C address */ +#define SENSOR_I2C_ADDRESS 0x68 +#define SENSOR_MAG_I2_ADDRESS 0x0C +/*---------------------------------------------------------------------------*/ +/* Registers */ +#define SELF_TEST_X_GYRO 0x00 /* R/W */ +#define SELF_TEST_Y_GYRO 0x01 /* R/W */ +#define SELF_TEST_Z_GYRO 0x02 /* R/W */ +#define SELF_TEST_X_ACCEL 0x0D /* R/W */ +#define SELF_TEST_Z_ACCEL 0x0E /* R/W */ +#define SELF_TEST_Y_ACCEL 0x0F /* R/W */ +/*---------------------------------------------------------------------------*/ +#define XG_OFFSET_H 0x13 /* R/W */ +#define XG_OFFSET_L 0x14 /* R/W */ +#define YG_OFFSET_H 0x15 /* R/W */ +#define YG_OFFSET_L 0x16 /* R/W */ +#define ZG_OFFSET_H 0x17 /* R/W */ +#define ZG_OFFSET_L 0x18 /* R/W */ +/*---------------------------------------------------------------------------*/ +#define SMPLRT_DIV 0x19 /* R/W */ +#define CONFIG 0x1A /* R/W */ +#define GYRO_CONFIG 0x1B /* R/W */ +#define ACCEL_CONFIG 0x1C /* R/W */ +#define ACCEL_CONFIG_2 0x1D /* R/W */ +#define LP_ACCEL_ODR 0x1E /* R/W */ +#define WOM_THR 0x1F /* R/W */ +#define FIFO_EN 0x23 /* R/W */ +/*---------------------------------------------------------------------------*/ +/* + * Registers 0x24 - 0x36 are not applicable to the SensorTag HW configuration + * (IC2 Master) + */ +#define INT_PIN_CFG 0x37 /* R/W */ +#define INT_ENABLE 0x38 /* R/W */ +#define INT_STATUS 0x3A /* R */ +#define ACCEL_XOUT_H 0x3B /* R */ +#define ACCEL_XOUT_L 0x3C /* R */ +#define ACCEL_YOUT_H 0x3D /* R */ +#define ACCEL_YOUT_L 0x3E /* R */ +#define ACCEL_ZOUT_H 0x3F /* R */ +#define ACCEL_ZOUT_L 0x40 /* R */ +#define TEMP_OUT_H 0x41 /* R */ +#define TEMP_OUT_L 0x42 /* R */ +#define GYRO_XOUT_H 0x43 /* R */ +#define GYRO_XOUT_L 0x44 /* R */ +#define GYRO_YOUT_H 0x45 /* R */ +#define GYRO_YOUT_L 0x46 /* R */ +#define GYRO_ZOUT_H 0x47 /* R */ +#define GYRO_ZOUT_L 0x48 /* R */ +/*---------------------------------------------------------------------------*/ +/* + * Registers 0x49 - 0x60 are not applicable to the SensorTag HW configuration + * (external sensor data) + * + * Registers 0x63 - 0x67 are not applicable to the SensorTag HW configuration + * (I2C master) + */ +#define SIGNAL_PATH_RESET 0x68 /* R/W */ +#define ACCEL_INTEL_CTRL 0x69 /* R/W */ +#define USER_CTRL 0x6A /* R/W */ +#define PWR_MGMT_1 0x6B /* R/W */ +#define PWR_MGMT_2 0x6C /* R/W */ +#define FIFO_COUNT_H 0x72 /* R/W */ +#define FIFO_COUNT_L 0x73 /* R/W */ +#define FIFO_R_W 0x74 /* R/W */ +#define WHO_AM_I 0x75 /* R/W */ +/*---------------------------------------------------------------------------*/ +/* Masks is mpuConfig valiable */ +#define ACC_CONFIG_MASK 0x38 +#define GYRO_CONFIG_MASK 0x07 +/*---------------------------------------------------------------------------*/ +/* Values PWR_MGMT_1 */ +#define MPU_SLEEP 0x4F /* Sleep + stop all clocks */ +#define MPU_WAKE_UP 0x09 /* Disable temp. + intern osc */ +/*---------------------------------------------------------------------------*/ +/* Values PWR_MGMT_2 */ +#define ALL_AXES 0x3F +#define GYRO_AXES 0x07 +#define ACC_AXES 0x38 +/*---------------------------------------------------------------------------*/ +/* Data sizes */ +#define DATA_SIZE 6 +/*---------------------------------------------------------------------------*/ +/* Output data rates */ +#define INV_LPA_0_3125HZ 0 +#define INV_LPA_0_625HZ 1 +#define INV_LPA_1_25HZ 2 +#define INV_LPA_2_5HZ 3 +#define INV_LPA_5HZ 4 +#define INV_LPA_10HZ 5 +#define INV_LPA_20HZ 6 +#define INV_LPA_40HZ 7 +#define INV_LPA_80HZ 8 +#define INV_LPA_160HZ 9 +#define INV_LPA_320HZ 10 +#define INV_LPA_640HZ 11 +#define INV_LPA_STOPPED 255 +/*---------------------------------------------------------------------------*/ +/* Bit values */ +#define BIT_ANY_RD_CLR 0x10 +#define BIT_RAW_RDY_EN 0x01 +#define BIT_WOM_EN 0x40 +#define BIT_LPA_CYCLE 0x20 +#define BIT_STBY_XA 0x20 +#define BIT_STBY_YA 0x10 +#define BIT_STBY_ZA 0x08 +#define BIT_STBY_XG 0x04 +#define BIT_STBY_YG 0x02 +#define BIT_STBY_ZG 0x01 +#define BIT_STBY_XYZA (BIT_STBY_XA | BIT_STBY_YA | BIT_STBY_ZA) +#define BIT_STBY_XYZG (BIT_STBY_XG | BIT_STBY_YG | BIT_STBY_ZG) +/*---------------------------------------------------------------------------*/ +/* User control register */ +#define BIT_ACTL 0x80 +#define BIT_LATCH_EN 0x20 +/*---------------------------------------------------------------------------*/ +/* INT Pin / Bypass Enable Configuration */ +#define BIT_AUX_IF_EN 0x20 /* I2C_MST_EN */ +#define BIT_BYPASS_EN 0x02 +/*---------------------------------------------------------------------------*/ +#define ACC_RANGE_INVALID -1 + +#define ACC_RANGE_2G 0 +#define ACC_RANGE_4G 1 +#define ACC_RANGE_8G 2 +#define ACC_RANGE_16G 3 + +#define MPU_AX_GYR_X 2 +#define MPU_AX_GYR_Y 1 +#define MPU_AX_GYR_Z 0 +#define MPU_AX_GYR 0x07 + +#define MPU_AX_ACC_X 5 +#define MPU_AX_ACC_Y 4 +#define MPU_AX_ACC_Z 3 +#define MPU_AX_ACC 0x38 + +#define MPU_AX_MAG 6 +/*---------------------------------------------------------------------------*/ +#define MPU_DATA_READY 0x01 +#define MPU_MOVEMENT 0x40 +/*---------------------------------------------------------------------------*/ +/* Sensor selection/deselection */ +#define SENSOR_SELECT() board_i2c_select(BOARD_I2C_INTERFACE_1, SENSOR_I2C_ADDRESS) +#define SENSOR_DESELECT() board_i2c_deselect() +/*---------------------------------------------------------------------------*/ +/* Delay */ +#define delay_ms(i) (ti_lib_cpu_delay(8000 * (i))) +/*---------------------------------------------------------------------------*/ +static uint8_t mpu_config; +static uint8_t acc_range; +static uint8_t acc_range_reg; +static uint8_t val; +static uint8_t interrupt_status; +/*---------------------------------------------------------------------------*/ +#define SENSOR_STATE_DISABLED 0 +#define SENSOR_STATE_BOOTING 1 +#define SENSOR_STATE_ENABLED 2 + +static int state = SENSOR_STATE_DISABLED; +static int elements = MPU_9250_SENSOR_TYPE_NONE; +/*---------------------------------------------------------------------------*/ +/* 3 16-byte words for all sensor readings */ +#define SENSOR_DATA_BUF_SIZE 3 + +static uint16_t sensor_value[SENSOR_DATA_BUF_SIZE]; +/*---------------------------------------------------------------------------*/ +/* + * Wait SENSOR_BOOT_DELAY ticks for the sensor to boot and + * SENSOR_STARTUP_DELAY for readings to be ready + * Gyro is a little slower than Acc + */ +#define SENSOR_BOOT_DELAY 8 +#define SENSOR_STARTUP_DELAY 5 + +static struct ctimer startup_timer; +/*---------------------------------------------------------------------------*/ +/* Wait for the MPU to have data ready */ +rtimer_clock_t t0; + +/* + * Wait timeout in rtimer ticks. This is just a random low number, since the + * first time we read the sensor status, it should be ready to return data + */ +#define READING_WAIT_TIMEOUT 10 +/*---------------------------------------------------------------------------*/ +/** + * \brief Place the MPU in low power mode + */ +static void +sensor_sleep(void) +{ + SENSOR_SELECT(); + + val = ALL_AXES; + sensor_common_write_reg(PWR_MGMT_2, &val, 1); + + val = MPU_SLEEP; + sensor_common_write_reg(PWR_MGMT_1, &val, 1); + SENSOR_DESELECT(); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Exit low power mode + */ +static void +sensor_wakeup(void) +{ + SENSOR_SELECT(); + val = MPU_WAKE_UP; + sensor_common_write_reg(PWR_MGMT_1, &val, 1); + + /* All axis initially disabled */ + val = ALL_AXES; + sensor_common_write_reg(PWR_MGMT_2, &val, 1); + mpu_config = 0; + + /* Restore the range */ + sensor_common_write_reg(ACCEL_CONFIG, &acc_range_reg, 1); + + /* Clear interrupts */ + sensor_common_read_reg(INT_STATUS, &val, 1); + SENSOR_DESELECT(); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Select gyro and accelerometer axes + */ +static void +select_axes(void) +{ + val = ~mpu_config; + SENSOR_SELECT(); + sensor_common_write_reg(PWR_MGMT_2, &val, 1); + SENSOR_DESELECT(); +} +/*---------------------------------------------------------------------------*/ +static void +convert_to_le(uint8_t *data, uint8_t len) +{ + int i; + for(i = 0; i < len; i += 2) { + uint8_t tmp; + tmp = data[i]; + data[i] = data[i + 1]; + data[i + 1] = tmp; + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Set the range of the accelerometer + * \param new_range: ACC_RANGE_2G, ACC_RANGE_4G, ACC_RANGE_8G, ACC_RANGE_16G + * \return true if the write to the sensor succeeded + */ +static bool +acc_set_range(uint8_t new_range) +{ + bool success; + + if(new_range == acc_range) { + return true; + } + + success = false; + + acc_range_reg = (new_range << 3); + + /* Apply the range */ + SENSOR_SELECT(); + success = sensor_common_write_reg(ACCEL_CONFIG, &acc_range_reg, 1); + SENSOR_DESELECT(); + + if(success) { + acc_range = new_range; + } + + return success; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Check whether a data or wake on motion interrupt has occurred + * \return Return the interrupt status + * + * This driver does not use interrupts, however this function allows us to + * determine whether a new sensor reading is available + */ +static uint8_t +int_status(void) +{ + SENSOR_SELECT(); + sensor_common_read_reg(INT_STATUS, &interrupt_status, 1); + SENSOR_DESELECT(); + + return interrupt_status; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Enable the MPU + * \param axes: Gyro bitmap [0..2], X = 1, Y = 2, Z = 4. 0 = gyro off + * Acc bitmap [3..5], X = 8, Y = 16, Z = 32. 0 = accelerometer off + */ +static void +enable_sensor(uint16_t axes) +{ + if(mpu_config == 0 && axes != 0) { + /* Wake up the sensor if it was off */ + sensor_wakeup(); + } + + mpu_config = axes; + + if(mpu_config != 0) { + /* Enable gyro + accelerometer readout */ + select_axes(); + delay_ms(10); + } else if(mpu_config == 0) { + sensor_sleep(); + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Read data from the accelerometer - X, Y, Z - 3 words + * \return True if a valid reading could be taken, false otherwise + */ +static bool +acc_read(uint16_t *data) +{ + bool success; + + if(interrupt_status & BIT_RAW_RDY_EN) { + /* Burst read of all accelerometer values */ + SENSOR_SELECT(); + success = sensor_common_read_reg(ACCEL_XOUT_H, (uint8_t *)data, DATA_SIZE); + SENSOR_DESELECT(); + + if(success) { + convert_to_le((uint8_t *)data, DATA_SIZE); + } else { + sensor_common_set_error_data((uint8_t *)data, DATA_SIZE); + } + } else { + /* Data not ready */ + success = false; + } + + return success; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Read data from the gyroscope - X, Y, Z - 3 words + * \return True if a valid reading could be taken, false otherwise + */ +static bool +gyro_read(uint16_t *data) +{ + bool success; + + if(interrupt_status & BIT_RAW_RDY_EN) { + /* Select this sensor */ + SENSOR_SELECT(); + + /* Burst read of all gyroscope values */ + success = sensor_common_read_reg(GYRO_XOUT_H, (uint8_t *)data, DATA_SIZE); + + if(success) { + convert_to_le((uint8_t *)data, DATA_SIZE); + } else { + sensor_common_set_error_data((uint8_t *)data, DATA_SIZE); + } + + SENSOR_DESELECT(); + } else { + success = false; + } + + return success; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Convert accelerometer raw reading to a value in G + * \param raw_data The raw accelerometer reading + * \return The converted value + */ +static float +acc_convert(int16_t raw_data) +{ + float v = 0; + + switch(acc_range) { + case ACC_RANGE_2G: + /* Calculate acceleration, unit G, range -2, +2 */ + v = (raw_data * 1.0) / (32768 / 2); + break; + case ACC_RANGE_4G: + /* Calculate acceleration, unit G, range -4, +4 */ + v = (raw_data * 1.0) / (32768 / 4); + break; + case ACC_RANGE_8G: + /* Calculate acceleration, unit G, range -8, +8 */ + v = (raw_data * 1.0) / (32768 / 8); + break; + case ACC_RANGE_16G: + /* Calculate acceleration, unit G, range -16, +16 */ + v = (raw_data * 1.0) / (32768 / 16); + break; + default: + v = 0; + break; + } + + return v; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Convert gyro raw reading to a value in deg/sec + * \param raw_data The raw accelerometer reading + * \return The converted value + */ +static float +gyro_convert(int16_t raw_data) +{ + /* calculate rotation, unit deg/s, range -250, +250 */ + return (raw_data * 1.0) / (65536 / 500); +} +/*---------------------------------------------------------------------------*/ +static void +notify_ready(void *not_used) +{ + state = SENSOR_STATE_ENABLED; + sensors_changed(&mpu_9250_sensor); +} +/*---------------------------------------------------------------------------*/ +static void +initialise(void *not_used) +{ + /* Configure the accelerometer range */ + if((elements & MPU_9250_SENSOR_TYPE_ACC) != 0) { + acc_set_range(MPU_9250_SENSOR_ACC_RANGE); + } + + enable_sensor(elements & MPU_9250_SENSOR_TYPE_ALL); + + ctimer_set(&startup_timer, SENSOR_STARTUP_DELAY, notify_ready, NULL); +} +/*---------------------------------------------------------------------------*/ +static void +power_up(void) +{ + ti_lib_gpio_pin_write(BOARD_MPU_POWER, 1); + state = SENSOR_STATE_BOOTING; + + ctimer_set(&startup_timer, SENSOR_BOOT_DELAY, initialise, NULL); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns a reading from the sensor + * \param type MPU_9250_SENSOR_TYPE_ACC_[XYZ] or MPU_9250_SENSOR_TYPE_GYRO_[XYZ] + * \return centi-G (ACC) or centi-Deg/Sec (Gyro) + */ +static int +value(int type) +{ + int rv; + float converted_val = 0; + + if(state == SENSOR_STATE_DISABLED) { + PRINTF("MPU: Sensor Disabled\n"); + return CC26XX_SENSOR_READING_ERROR; + } + + memset(sensor_value, 0, sizeof(sensor_value)); + + if((type & MPU_9250_SENSOR_TYPE_ACC) != 0) { + t0 = RTIMER_NOW(); + + while(!int_status() && + (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + READING_WAIT_TIMEOUT))); + + rv = acc_read(sensor_value); + + if(rv == 0) { + return CC26XX_SENSOR_READING_ERROR; + } + + PRINTF("MPU: ACC = 0x%04x 0x%04x 0x%04x = ", + sensor_value[0], sensor_value[1], sensor_value[2]); + + /* Convert */ + if(type == MPU_9250_SENSOR_TYPE_ACC_X) { + converted_val = acc_convert(sensor_value[0]); + } else if(type == MPU_9250_SENSOR_TYPE_ACC_Y) { + converted_val = acc_convert(sensor_value[1]); + } else if(type == MPU_9250_SENSOR_TYPE_ACC_Z) { + converted_val = acc_convert(sensor_value[2]); + } + rv = (int)(converted_val * 100); + } else if((type & MPU_9250_SENSOR_TYPE_GYRO) != 0) { + t0 = RTIMER_NOW(); + + while(!int_status() && + (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + READING_WAIT_TIMEOUT))); + + rv = gyro_read(sensor_value); + + if(rv == 0) { + return CC26XX_SENSOR_READING_ERROR; + } + + PRINTF("MPU: Gyro = 0x%04x 0x%04x 0x%04x = ", + sensor_value[0], sensor_value[1], sensor_value[2]); + + if(type == MPU_9250_SENSOR_TYPE_GYRO_X) { + converted_val = gyro_convert(sensor_value[0]); + } else if(type == MPU_9250_SENSOR_TYPE_GYRO_Y) { + converted_val = gyro_convert(sensor_value[1]); + } else if(type == MPU_9250_SENSOR_TYPE_GYRO_Z) { + converted_val = gyro_convert(sensor_value[2]); + } + rv = (int)(converted_val * 100); + } else { + PRINTF("MPU: Invalid type\n"); + rv = CC26XX_SENSOR_READING_ERROR; + } + + PRINTF("%ld\n", (long int)(converted_val * 100)); + + return rv; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the MPU9250 sensor. + * + * \param type Activate, enable or disable the sensor. See below + * \param enable + * + * When type == SENSORS_HW_INIT we turn on the hardware + * When type == SENSORS_ACTIVE and enable==1 we enable the sensor + * When type == SENSORS_ACTIVE and enable==0 we disable the sensor + */ +static int +configure(int type, int enable) +{ + switch(type) { + case SENSORS_HW_INIT: + ti_lib_rom_ioc_pin_type_gpio_input(BOARD_IOID_MPU_INT); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_MPU_INT, IOC_IOPULL_DOWN); + ti_lib_ioc_io_hyst_set(BOARD_IOID_MPU_INT, IOC_HYST_ENABLE); + + ti_lib_rom_ioc_pin_type_gpio_output(BOARD_IOID_MPU_POWER); + ti_lib_ioc_io_drv_strength_set(BOARD_IOID_MPU_POWER, IOC_CURRENT_4MA, + IOC_STRENGTH_MAX); + ti_lib_gpio_pin_clear(BOARD_MPU_POWER); + elements = MPU_9250_SENSOR_TYPE_NONE; + break; + case SENSORS_ACTIVE: + if(((enable & MPU_9250_SENSOR_TYPE_ACC) != 0) || + ((enable & MPU_9250_SENSOR_TYPE_GYRO) != 0)) { + PRINTF("MPU: Enabling\n"); + elements = enable & MPU_9250_SENSOR_TYPE_ALL; + + power_up(); + + state = SENSOR_STATE_BOOTING; + } else { + PRINTF("MPU: Disabling\n"); + if(HWREG(GPIO_BASE + GPIO_O_DOUT31_0) & BOARD_MPU_POWER) { + /* Then check our state */ + elements = MPU_9250_SENSOR_TYPE_NONE; + ctimer_stop(&startup_timer); + sensor_sleep(); + while(ti_lib_i2c_master_busy(I2C0_BASE)); + state = SENSOR_STATE_DISABLED; + ti_lib_gpio_pin_clear(BOARD_MPU_POWER); + } + } + break; + default: + break; + } + return state; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns the status of the sensor + * \param type SENSORS_ACTIVE or SENSORS_READY + * \return 1 if the sensor is enabled + */ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return state; + break; + default: + break; + } + return SENSOR_STATE_DISABLED; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(mpu_9250_sensor, "MPU9250", value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/sensortag/mpu-9250-sensor.h b/platform/srf06-cc26xx/sensortag/mpu-9250-sensor.h new file mode 100644 index 000000000..c6c4d5534 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/mpu-9250-sensor.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-peripherals + * @{ + * + * \defgroup sensortag-cc26xx-mpu SensorTag 2.0 Motion Processing Unit + * + * Driver for the Invensense MPU9250 Motion Processing Unit. + * + * Due to the time required between triggering a reading and the reading + * becoming available, this driver is meant to be used in an asynchronous + * fashion. The caller must first activate the sensor by calling + * mpu_9250_sensor.configure(SENSORS_ACTIVE, xyz); + * The value for the xyz arguments depends on the required readings. If the + * caller intends to read both the accelerometer as well as the gyro then + * xyz should be MPU_9250_SENSOR_TYPE_ALL. If the caller only needs to take a + * reading from one of the two elements, xyz should be one of + * MPU_9250_SENSOR_TYPE_ACC or MPU_9250_SENSOR_TYPE_GYRO + * + * Calling .configure() will power up the sensor and initialise it. When the + * sensor is ready to provide readings, the driver will generate a + * sensors_changed event. + * + * Calls to .status() will return the driver's state which could indicate that + * the sensor is off, booting or on. + * + * Once a reading has been taken, the caller has two options: + * - Turn the sensor off by calling SENSORS_DEACTIVATE, but in order to take + * subsequent readings the sensor must be started up all over + * - Leave the sensor on. In this scenario, the caller can simply keep calling + * value() for subsequent readings, but having the sensor on will consume + * more energy, especially if both accelerometer and the gyro are on. + * @{ + * + * \file + * Header file for the Sensortag-CC26XX Invensense MPU9250 motion processing unit + */ +/*---------------------------------------------------------------------------*/ +#ifndef MPU_9250_SENSOR_H_ +#define MPU_9250_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +/* ACC / Gyro Axes */ +#define MPU_9250_SENSOR_TYPE_GYRO_Z 0x01 +#define MPU_9250_SENSOR_TYPE_GYRO_Y 0x02 +#define MPU_9250_SENSOR_TYPE_GYRO_X 0x04 +#define MPU_9250_SENSOR_TYPE_GYRO_ALL 0x07 + +#define MPU_9250_SENSOR_TYPE_ACC_Z 0x08 +#define MPU_9250_SENSOR_TYPE_ACC_Y 0x10 +#define MPU_9250_SENSOR_TYPE_ACC_X 0x20 +#define MPU_9250_SENSOR_TYPE_ACC_ALL 0x38 + +#define MPU_9250_SENSOR_TYPE_MASK 0x3F +#define MPU_9250_SENSOR_TYPE_ACC 0x38 +#define MPU_9250_SENSOR_TYPE_GYRO 0x07 + +#define MPU_9250_SENSOR_TYPE_NONE 0 +#define MPU_9250_SENSOR_TYPE_ALL (MPU_9250_SENSOR_TYPE_ACC | \ + MPU_9250_SENSOR_TYPE_GYRO) +/*---------------------------------------------------------------------------*/ +/* Accelerometer range */ +#define MPU_9250_SENSOR_ACC_RANGE_2G 0 +#define MPU_9250_SENSOR_ACC_RANGE_4G 1 +#define MPU_9250_SENSOR_ACC_RANGE_8G 2 +#define MPU_9250_SENSOR_ACC_RANGE_16G 3 +/*---------------------------------------------------------------------------*/ +/* Accelerometer range configuration */ +#ifdef MPU_9250_SENSOR_CONF_ACC_RANGE +#define MPU_9250_SENSOR_ACC_RANGE MPU_9250_SENSOR_CONF_ACC_RANGE +#else +#define MPU_9250_SENSOR_ACC_RANGE MPU_9250_SENSOR_ACC_RANGE_2G +#endif +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor mpu_9250_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* MPU_9250_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/sensortag/opt-3001-sensor.c b/platform/srf06-cc26xx/sensortag/opt-3001-sensor.c new file mode 100644 index 000000000..7d903e18b --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/opt-3001-sensor.c @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-opt-sensor + * @{ + * + * \file + * Driver for the Sensortag-CC26xx Opt3001 light sensor + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "lib/sensors.h" +#include "opt-3001-sensor.h" +#include "sys/ctimer.h" +#include "ti-lib.h" +#include "board-i2c.h" +#include "sensor-common.h" + +#include +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +/* Slave address */ +#define OPT3001_I2C_ADDRESS 0x45 +/*---------------------------------------------------------------------------*/ +/* Register addresses */ +#define REG_RESULT 0x00 +#define REG_CONFIGURATION 0x01 +#define REG_LOW_LIMIT 0x02 +#define REG_HIGH_LIMIT 0x03 + +#define REG_MANUFACTURER_ID 0x7E +#define REG_DEVICE_ID 0x7F +/*---------------------------------------------------------------------------*/ +/* + * Configuration Register Bits and Masks. + * We use uint16_t to read from / write to registers, meaning that the + * register's MSB is the variable's LSB. + */ +#define CONFIG_RN 0x00F0 /* [15..12] Range Number */ +#define CONFIG_CT 0x0008 /* [11] Conversion Time */ +#define CONFIG_M 0x0006 /* [10..9] Mode of Conversion */ +#define CONFIG_OVF 0x0001 /* [8] Overflow */ +#define CONFIG_CRF 0x8000 /* [7] Conversion Ready Field */ +#define CONFIG_FH 0x4000 /* [6] Flag High */ +#define CONFIG_FL 0x2000 /* [5] Flag Low */ +#define CONFIG_L 0x1000 /* [4] Latch */ +#define CONFIG_POL 0x0800 /* [3] Polarity */ +#define CONFIG_ME 0x0400 /* [2] Mask Exponent */ +#define CONFIG_FC 0x0300 /* [1..0] Fault Count */ + +/* Possible Values for CT */ +#define CONFIG_CT_100 0x0000 +#define CONFIG_CT_800 CONFIG_CT + +/* Possible Values for M */ +#define CONFIG_M_CONTI 0x0004 +#define CONFIG_M_SINGLE 0x0002 +#define CONFIG_M_SHUTDOWN 0x0000 + +/* Reset Value for the register 0xC810. All zeros except: */ +#define CONFIG_RN_RESET 0x00C0 +#define CONFIG_CT_RESET CONFIG_CT_800 +#define CONFIG_L_RESET 0x1000 +#define CONFIG_DEFAULTS (CONFIG_RN_RESET | CONFIG_CT_100 | CONFIG_L_RESET) + +/* Enable / Disable */ +#define CONFIG_ENABLE_CONTINUOUS (CONFIG_M_CONTI | CONFIG_DEFAULTS) +#define CONFIG_ENABLE_SINGLE_SHOT (CONFIG_M_SINGLE | CONFIG_DEFAULTS) +#define CONFIG_DISABLE CONFIG_DEFAULTS +/*---------------------------------------------------------------------------*/ +/* Register length */ +#define REGISTER_LENGTH 2 +/*---------------------------------------------------------------------------*/ +/* Sensor data size */ +#define DATA_LENGTH 2 +/*---------------------------------------------------------------------------*/ +/* + * SENSOR_STATE_SLEEPING and SENSOR_STATE_ACTIVE are mutually exclusive. + * SENSOR_STATE_DATA_READY can be ORd with both of the above. For example the + * sensor may be sleeping but with a conversion ready to read out. + */ +#define SENSOR_STATE_SLEEPING 0 +#define SENSOR_STATE_ACTIVE 1 +#define SENSOR_STATE_DATA_READY 2 + +static int state = SENSOR_STATE_SLEEPING; +/*---------------------------------------------------------------------------*/ +/* Wait SENSOR_STARTUP_DELAY for the sensor to be ready - 125ms */ +#define SENSOR_STARTUP_DELAY (CLOCK_SECOND >> 3) + +static struct ctimer startup_timer; +/*---------------------------------------------------------------------------*/ +/** + * \brief Select the sensor on the I2C bus + */ +static void +select_on_bus(void) +{ + /* Select slave and set clock rate */ + board_i2c_select(BOARD_I2C_INTERFACE_0, OPT3001_I2C_ADDRESS); +} +/*---------------------------------------------------------------------------*/ +static void +notify_ready(void *not_used) +{ + /* + * Depending on the CONFIGURATION.CONVERSION_TIME bits, a conversion will + * take either 100 or 800 ms. Here we inspect the CONVERSION_READY bit and + * if the reading is ready we notify, otherwise we just reschedule ourselves + */ + uint16_t val; + + select_on_bus(); + + sensor_common_read_reg(REG_CONFIGURATION, (uint8_t *)&val, REGISTER_LENGTH); + + if(val & CONFIG_CRF) { + sensors_changed(&opt_3001_sensor); + state = SENSOR_STATE_DATA_READY; + } else { + ctimer_set(&startup_timer, SENSOR_STARTUP_DELAY, notify_ready, NULL); + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Turn the sensor on/off + * \param enable TRUE: on, FALSE: off + */ +static void +enable_sensor(bool enable) +{ + uint16_t val; + uint16_t had_data_ready = state & SENSOR_STATE_DATA_READY; + + select_on_bus(); + + if(enable) { + val = CONFIG_ENABLE_SINGLE_SHOT; + + /* Writing CONFIG_ENABLE_SINGLE_SHOT to M bits will clear CRF bits */ + state = SENSOR_STATE_ACTIVE; + } else { + val = CONFIG_DISABLE; + + /* Writing CONFIG_DISABLE to M bits will not clear CRF bits */ + state = SENSOR_STATE_SLEEPING | had_data_ready; + } + + sensor_common_write_reg(REG_CONFIGURATION, (uint8_t *)&val, REGISTER_LENGTH); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Read the result register + * \param raw_data Pointer to a buffer to store the reading + * \return TRUE if valid data + */ +static bool +read_data(uint16_t *raw_data) +{ + bool success; + uint16_t val; + + if((state & SENSOR_STATE_DATA_READY) != SENSOR_STATE_DATA_READY) { + return false; + } + + select_on_bus(); + + success = sensor_common_read_reg(REG_CONFIGURATION, (uint8_t *)&val, + REGISTER_LENGTH); + + if(success) { + success = sensor_common_read_reg(REG_RESULT, (uint8_t *)&val, DATA_LENGTH); + } + + if(success) { + /* Swap bytes */ + *raw_data = (val << 8) | (val >> 8 & 0xFF); + } else { + sensor_common_set_error_data((uint8_t *)raw_data, DATA_LENGTH); + } + + return success; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Convert raw data to a value in lux + * \param raw_data data Pointer to a buffer with a raw sensor reading + * \return Converted value (lux) + */ +static float +convert(uint16_t raw_data) +{ + uint16_t e, m; + + m = raw_data & 0x0FFF; + e = (raw_data & 0xF000) >> 12; + + return m * (0.01 * exp2(e)); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns a reading from the sensor + * \param type Ignored + * \return Illuminance in centilux + */ +static int +value(int type) +{ + int rv; + uint16_t raw_val; + float converted_val; + + rv = read_data(&raw_val); + + if(rv == false) { + return CC26XX_SENSOR_READING_ERROR; + } + + converted_val = convert(raw_val); + PRINTF("OPT: %04X r=%d (centilux)\n", raw_val, + (int)(converted_val * 100)); + + rv = (int)(converted_val * 100); + + return rv; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the OPT3001 sensor. + * + * \param type Activate, enable or disable the sensor. See below + * \param enable + * + * When type == SENSORS_HW_INIT we turn on the hardware + * When type == SENSORS_ACTIVE and enable==1 we enable the sensor + * When type == SENSORS_ACTIVE and enable==0 we disable the sensor + */ +static int +configure(int type, int enable) +{ + int rv = 0; + + switch(type) { + case SENSORS_HW_INIT: + /* + * Device reset won't reset the sensor, so we put it to sleep here + * explicitly + */ + enable_sensor(0); + rv = 0; + break; + case SENSORS_ACTIVE: + if(enable) { + enable_sensor(1); + ctimer_set(&startup_timer, SENSOR_STARTUP_DELAY, notify_ready, NULL); + rv = 1; + } else { + ctimer_stop(&startup_timer); + enable_sensor(0); + rv = 0; + } + break; + default: + break; + } + return rv; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns the status of the sensor + * \param type ignored + * \return The state of the sensor SENSOR_STATE_xyz + */ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + default: + break; + } + return state; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(opt_3001_sensor, "OPT3001", value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/sensortag/opt-3001-sensor.h b/platform/srf06-cc26xx/sensortag/opt-3001-sensor.h new file mode 100644 index 000000000..a4160b729 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/opt-3001-sensor.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-peripherals + * @{ + * + * \defgroup sensortag-cc26xx-opt-sensor SensorTag 2.0 Light Sensor + * + * Due to the time required for the sensor to startup, this driver is meant to + * be used in an asynchronous fashion. The caller must first activate the + * sensor by calling SENSORS_ACTIVATE(). This will trigger the sensor's startup + * sequence, but the call will not wait for it to complete so that the CPU can + * perform other tasks or drop to a low power mode. + * + * Once the reading and conversion are complete, the driver will generate a + * sensors_changed event. + * + * We use single-shot readings. In this mode, the hardware automatically goes + * back to its shutdown mode after the conversion is finished. However, it will + * still respond to I2C operations, so the last conversion can still be read + * out. + * + * In order to take a new reading, the caller has to use SENSORS_ACTIVATE + * again. + * @{ + * + * \file + * Header file for the Sensortag-CC26xx Opt3001 light sensor + */ +/*---------------------------------------------------------------------------*/ +#ifndef OPT_3001_SENSOR_H_ +#define OPT_3001_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor opt_3001_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* OPT_3001_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/sensortag/reed-relay.c b/platform/srf06-cc26xx/sensortag/reed-relay.c new file mode 100644 index 000000000..9be161b48 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/reed-relay.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-reed-relay + * @{ + * + * \file + * Driver for the Sensortag-CC26XX Reed Relay + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sys/clock.h" +#include "sys/timer.h" +#include "lib/sensors.h" +#include "sensortag/reed-relay.h" +#include "gpio-interrupt.h" +#include "sys/timer.h" + +#include "ti-lib.h" + +#include +/*---------------------------------------------------------------------------*/ +static struct timer debouncetimer; +/*---------------------------------------------------------------------------*/ +#define REED_IO_CFG (IOC_CURRENT_2MA | IOC_STRENGTH_AUTO | \ + IOC_IOPULL_DOWN | IOC_SLEW_DISABLE | \ + IOC_HYST_DISABLE | IOC_BOTH_EDGES | \ + IOC_INT_DISABLE | IOC_IOMODE_NORMAL | \ + IOC_NO_WAKE_UP | IOC_INPUT_ENABLE) +/*---------------------------------------------------------------------------*/ +/** + * \brief Handler for Sensortag-CC26XX reed interrupts + */ +static void +reed_interrupt_handler(uint8_t ioid) +{ + if(!timer_expired(&debouncetimer)) { + ENERGEST_OFF(ENERGEST_TYPE_IRQ); + return; + } + + sensors_changed(&reed_relay_sensor); + timer_set(&debouncetimer, CLOCK_SECOND / 2); +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return (int)ti_lib_gpio_pin_read(1 << BOARD_IOID_REED_RELAY); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the button sensor for all buttons. + * + * \param type SENSORS_HW_INIT: Initialise. SENSORS_ACTIVE: Enables/Disables + * depending on 'value' + * \param value 0: disable, non-zero: enable + * \return Always returns 1 + */ +static int +configure(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: + ti_lib_ioc_int_disable(BOARD_IOID_REED_RELAY); + ti_lib_gpio_event_clear(1 << BOARD_IOID_REED_RELAY); + + /* Enable the GPIO clock when the CM3 is running */ + ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_GPIO); + + /* S/W control, input, pull-down */ + ti_lib_ioc_port_configure_set(BOARD_IOID_REED_RELAY, IOC_PORT_GPIO, + REED_IO_CFG); + + gpio_interrupt_register_handler(BOARD_IOID_REED_RELAY, + reed_interrupt_handler); + break; + case SENSORS_ACTIVE: + if(value) { + ti_lib_ioc_int_enable(BOARD_IOID_REED_RELAY); + } else { + ti_lib_ioc_int_disable(BOARD_IOID_REED_RELAY); + } + break; + default: + break; + } + return 1; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for the reed + * \param type SENSORS_ACTIVE or SENSORS_READY + * \return 1 Interrupt enabled, 0: Disabled + */ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return (ti_lib_ioc_port_configure_get(BOARD_IOID_REED_RELAY) + & IOC_INT_ENABLE) == IOC_INT_ENABLE; + break; + default: + break; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(reed_relay_sensor, "REED", value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/sensortag/reed-relay.h b/platform/srf06-cc26xx/sensortag/reed-relay.h new file mode 100644 index 000000000..3ec712719 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/reed-relay.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-peripherals + * @{ + * + * \defgroup sensortag-cc26xx-reed-relay SensorTag 2.0 Reed Relay + * + * The reed relay acts like a button without a button. To trigger the reed, + * approach a magnet to the sensortag and a sensors_changed event will be + * generated, in a fashion similar to as if a button had been pressed + * + * @{ + * + * \file + * Header file for the Sensortag-CC26XX Reed Relay + */ +/*---------------------------------------------------------------------------*/ +#ifndef REED_RELAY_H +#define REED_RELAY_H +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor reed_relay_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* REED_RELAY_H */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/sensortag/sensor-common.c b/platform/srf06-cc26xx/sensortag/sensor-common.c new file mode 100644 index 000000000..0c09bf630 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/sensor-common.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-sensor-common + * @{ + * + * \file + * Utilities common among SensorTag sensors + */ +/*---------------------------------------------------------------------------*/ +#include "sensor-common.h" +#include "board-i2c.h" +/*---------------------------------------------------------------------------*/ +/* Data to use when an error occurs */ +#define ERROR_DATA 0xCC +/*---------------------------------------------------------------------------*/ +static uint8_t buffer[32]; +/*---------------------------------------------------------------------------*/ +bool +sensor_common_read_reg(uint8_t addr, uint8_t *buf, uint8_t len) +{ + return board_i2c_write_read(&addr, 1, buf, len); +} +/*---------------------------------------------------------------------------*/ +bool +sensor_common_write_reg(uint8_t addr, uint8_t *buf, uint8_t len) +{ + uint8_t i; + uint8_t *p = buffer; + + /* Copy address and data to local buffer for burst write */ + *p++ = addr; + for(i = 0; i < len; i++) { + *p++ = *buf++; + } + len++; + + /* Send data */ + return board_i2c_write(buffer, len); +} +/*---------------------------------------------------------------------------*/ +void +sensor_common_set_error_data(uint8_t *buf, uint8_t len) +{ + while(len > 0) { + len--; + buf[len] = ERROR_DATA; + } +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/sensortag/sensor-common.h b/platform/srf06-cc26xx/sensortag/sensor-common.h new file mode 100644 index 000000000..977650d5e --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/sensor-common.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-peripherals + * @{ + * + * \defgroup sensortag-cc26xx-sensor-common SensorTag 2.0 Sensors + * @{ + * + * \file + * Header file for the Sensortag-CC26xx Common sensor utilities + */ +/*---------------------------------------------------------------------------*/ +#ifndef SENSOR_H +#define SENSOR_H +/*---------------------------------------------------------------------------*/ +#include "board-i2c.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/** + * \brief Reads a sensor's register over I2C + * \param addr The address of the register to read + * \param buf Pointer to buffer to place data + * \param len Number of bytes to read + * \return TRUE if the required number of bytes are received + * + * The sensor must be selected before this routine is called. + */ +bool sensor_common_read_reg(uint8_t addr, uint8_t *buf, uint8_t len); + +/** + * \brief Write to a sensor's register over I2C + * \param addr The address of the register to read + * \param buf Pointer to buffer containing data to be written + * \param len Number of bytes to write + * \return TRUE if successful write + * + * The sensor must be selected before this routine is called. + */ +bool sensor_common_write_reg(uint8_t addr, uint8_t *buf, uint8_t len); + +/** + * \brief Fill a result buffer with dummy error data + * \param buf Pointer to the buffer where to write the data + * \param len Number of bytes to fill + * \return bitmask of error flags + */ +void sensor_common_set_error_data(uint8_t *buf, uint8_t len); +/*---------------------------------------------------------------------------*/ +#endif /* SENSOR_H */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/sensortag/sensortag-sensors.c b/platform/srf06-cc26xx/sensortag/sensortag-sensors.c new file mode 100644 index 000000000..bcd0fe367 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/sensortag-sensors.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-peripherals + * @{ + * + * \file + * Generic module controlling sensors on CC26XX Sensortag + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sensortag/button-sensor.h" +#include "sensortag/bmp-280-sensor.h" +#include "sensortag/tmp-007-sensor.h" +#include "sensortag/opt-3001-sensor.h" +#include "sensortag/hdc-1000-sensor.h" +#include "sensortag/mpu-9250-sensor.h" +#include "sensortag/reed-relay.h" + +#include +/*---------------------------------------------------------------------------*/ +/** \brief Exports a global symbol to be used by the sensor API */ +SENSORS(&button_left_sensor, &button_right_sensor, + &bmp_280_sensor, &tmp_007_sensor, &opt_3001_sensor, &hdc_1000_sensor, + &mpu_9250_sensor, &reed_relay_sensor); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/sensortag/tmp-007-sensor.c b/platform/srf06-cc26xx/sensortag/tmp-007-sensor.c new file mode 100644 index 000000000..1c462a0e0 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/tmp-007-sensor.c @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-tmp-sensor + * @{ + * + * \file + * Driver for the Sensortag-CC26xx TI TMP007 infrared thermophile sensor + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "lib/sensors.h" +#include "tmp-007-sensor.h" +#include "sys/ctimer.h" +#include "board-i2c.h" +#include "sensor-common.h" +#include "ti-lib.h" + +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +/* Slave address */ +#define SENSOR_I2C_ADDRESS 0x44 +/*---------------------------------------------------------------------------*/ +/* TMP007 register addresses */ +#define TMP007_REG_ADDR_VOLTAGE 0x00 +#define TMP007_REG_ADDR_LOCAL_TEMP 0x01 +#define TMP007_REG_ADDR_CONFIG 0x02 +#define TMP007_REG_ADDR_OBJ_TEMP 0x03 +#define TMP007_REG_ADDR_STATUS 0x04 +#define TMP007_REG_PROD_ID 0x1F +/*---------------------------------------------------------------------------*/ +/* TMP007 register values */ +#define TMP007_VAL_CONFIG_ON 0x1000 /* Sensor on state */ +#define TMP007_VAL_CONFIG_OFF 0x0000 /* Sensor off state */ +#define TMP007_VAL_CONFIG_RESET 0x8000 +#define TMP007_VAL_PROD_ID 0x0078 /* Product ID */ +/*---------------------------------------------------------------------------*/ +/* Conversion ready (status register) bit values */ +#define CONV_RDY_BIT 0x4000 +/*---------------------------------------------------------------------------*/ +/* Register length */ +#define REGISTER_LENGTH 2 +/*---------------------------------------------------------------------------*/ +/* Sensor data size */ +#define DATA_SIZE 4 +/*---------------------------------------------------------------------------*/ +/* Byte swap of 16-bit register value */ +#define HI_UINT16(a) (((a) >> 8) & 0xFF) +#define LO_UINT16(a) ((a) & 0xFF) + +#define SWAP(v) ((LO_UINT16(v) << 8) | HI_UINT16(v)) +/*---------------------------------------------------------------------------*/ +#define SELECT() board_i2c_select(BOARD_I2C_INTERFACE_0, SENSOR_I2C_ADDRESS) +/*---------------------------------------------------------------------------*/ +static uint8_t buf[DATA_SIZE]; +static uint16_t val; +/*---------------------------------------------------------------------------*/ +#define SENSOR_STATUS_DISABLED 0 +#define SENSOR_STATUS_INITIALISED 1 +#define SENSOR_STATUS_NOT_READY 2 +#define SENSOR_STATUS_READY 3 + +static int enabled = SENSOR_STATUS_DISABLED; +/*---------------------------------------------------------------------------*/ +/* Wait SENSOR_STARTUP_DELAY clock ticks for the sensor to be ready - 275ms */ +#define SENSOR_STARTUP_DELAY 36 + +static struct ctimer startup_timer; +/*---------------------------------------------------------------------------*/ +/* Latched values */ +static int obj_temp_latched; +static int amb_temp_latched; +/*---------------------------------------------------------------------------*/ +static void +notify_ready(void *not_used) +{ + enabled = SENSOR_STATUS_READY; + sensors_changed(&tmp_007_sensor); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Turn the sensor on/off + */ +static bool +enable_sensor(bool enable) +{ + bool success; + + SELECT(); + + if(enable) { + val = TMP007_VAL_CONFIG_ON; + } else { + val = TMP007_VAL_CONFIG_OFF; + } + val = SWAP(val); + + success = sensor_common_write_reg(TMP007_REG_ADDR_CONFIG, (uint8_t *)&val, + REGISTER_LENGTH); + + return success; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Read the sensor value registers + * \param raw_temp Temperature in 16 bit format + * \param raw_obj_temp object temperature in 16 bit format + * \return TRUE if valid data could be retrieved + */ +static bool +read_data(uint16_t *raw_temp, uint16_t *raw_obj_temp) +{ + bool success; + + SELECT(); + + success = sensor_common_read_reg(TMP007_REG_ADDR_STATUS, (uint8_t *)&val, + REGISTER_LENGTH); + + if(success) { + val = SWAP(val); + success = val & CONV_RDY_BIT; + } + + if(success) { + success = sensor_common_read_reg(TMP007_REG_ADDR_LOCAL_TEMP, &buf[0], + REGISTER_LENGTH); + if(success) { + success = sensor_common_read_reg(TMP007_REG_ADDR_OBJ_TEMP, &buf[2], + REGISTER_LENGTH); + } + } + + if(!success) { + sensor_common_set_error_data(buf, 4); + } + + /* Swap byte order */ + *raw_temp = buf[0] << 8 | buf[1]; + *raw_obj_temp = buf[2] << 8 | buf[3]; + + return success; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Convert raw data to values in degrees C + * \param raw_temp raw ambient temperature from sensor + * \param raw_obj_temp raw object temperature from sensor + * \param obj converted object temperature + * \param amb converted ambient temperature + */ +static void +convert(uint16_t raw_temp, uint16_t raw_obj_temp, float *obj, float *amb) +{ + const float SCALE_LSB = 0.03125; + float t; + int it; + + it = (int)((raw_obj_temp) >> 2); + t = ((float)(it)) * SCALE_LSB; + *obj = t; + + it = (int)((raw_temp) >> 2); + t = (float)it; + *amb = t * SCALE_LSB; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns a reading from the sensor + * \param type TMP_007_SENSOR_TYPE_OBJECT or TMP_007_SENSOR_TYPE_AMBIENT + * \return Object or Ambient temperature in milli degrees C + */ +static int +value(int type) +{ + int rv; + uint16_t raw_temp; + uint16_t raw_obj_temp; + float obj_temp; + float amb_temp; + + if(enabled != SENSOR_STATUS_READY) { + PRINTF("Sensor disabled or starting up (%d)\n", enabled); + return CC26XX_SENSOR_READING_ERROR; + } + + if((type & TMP_007_SENSOR_TYPE_ALL) == 0) { + PRINTF("Invalid type\n"); + return CC26XX_SENSOR_READING_ERROR; + } + + rv = CC26XX_SENSOR_READING_ERROR; + + if(type == TMP_007_SENSOR_TYPE_ALL) { + rv = read_data(&raw_temp, &raw_obj_temp); + + if(rv == 0) { + return CC26XX_SENSOR_READING_ERROR; + } + + convert(raw_temp, raw_obj_temp, &obj_temp, &amb_temp); + PRINTF("TMP: %04X %04X o=%d a=%d\n", raw_temp, raw_obj_temp, + (int)(obj_temp * 1000), (int)(amb_temp * 1000)); + + obj_temp_latched = (int)(obj_temp * 1000); + amb_temp_latched = (int)(amb_temp * 1000); + rv = 1; + } else if(type == TMP_007_SENSOR_TYPE_OBJECT) { + rv = obj_temp_latched; + } else if(type == TMP_007_SENSOR_TYPE_AMBIENT) { + rv = amb_temp_latched; + } + + return rv; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the TMP007 sensor. + * + * \param type Activate, enable or disable the sensor. See below + * \param enable + * + * When type == SENSORS_HW_INIT we turn on the hardware + * When type == SENSORS_ACTIVE and enable==1 we enable the sensor + * When type == SENSORS_ACTIVE and enable==0 we disable the sensor + */ +static int +configure(int type, int enable) +{ + switch(type) { + case SENSORS_HW_INIT: + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_TMP_RDY); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_TMP_RDY, IOC_IOPULL_UP); + ti_lib_ioc_io_hyst_set(BOARD_IOID_TMP_RDY, IOC_HYST_ENABLE); + + enable_sensor(false); + enabled = SENSOR_STATUS_INITIALISED; + break; + case SENSORS_ACTIVE: + /* Must be initialised first */ + if(enabled == SENSOR_STATUS_DISABLED) { + return SENSOR_STATUS_DISABLED; + } + if(enable) { + enable_sensor(true); + ctimer_set(&startup_timer, SENSOR_STARTUP_DELAY, notify_ready, NULL); + enabled = SENSOR_STATUS_NOT_READY; + } else { + ctimer_stop(&startup_timer); + enable_sensor(false); + enabled = SENSOR_STATUS_INITIALISED; + } + break; + default: + break; + } + return enabled; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns the status of the sensor + * \param type SENSORS_ACTIVE or SENSORS_READY + * \return 1 if the sensor is enabled + */ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + break; + default: + break; + } + return SENSOR_STATUS_DISABLED; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(tmp_007_sensor, "TMP007", value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/sensortag/tmp-007-sensor.h b/platform/srf06-cc26xx/sensortag/tmp-007-sensor.h new file mode 100644 index 000000000..10c96c8a0 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/tmp-007-sensor.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-cc26xx-peripherals + * @{ + * + * \defgroup sensortag-cc26xx-tmp-sensor SensorTag 2.0 IR thermophile sensor + * + * Due to the time required for the sensor to startup, this driver is meant to + * be used in an asynchronous fashion. The caller must first activate the + * sensor by calling SENSORS_ACTIVATE(). This will trigger the sensor's startup + * sequence, but the call will not wait for it to complete so that the CPU can + * perform other tasks or drop to a low power mode. + * + * Once the sensor is stable, the driver will generate a sensors_changed event. + * + * The caller should then use value(TMP_007_SENSOR_TYPE_ALL) to read sensor + * values and latch them. Once completed successfully, individual readings can + * be retrieved with calls to value(TMP_007_SENSOR_TYPE_OBJECT) or + * value(TMP_007_SENSOR_TYPE_AMBIENT). + * + * Once required readings have been taken, the caller has two options: + * - Turn the sensor off by calling SENSORS_DEACTIVATE, but in order to take + * subsequent readings SENSORS_ACTIVATE must be called again + * - Leave the sensor on. In this scenario, the caller can simply keep calling + * value(TMP_007_SENSOR_TYPE_ALL) to read and latch new values. However + * keeping the sensor on will consume more energy + * @{ + * + * \file + * Header file for the Sensortag-CC26xx TI TMP007 infrared thermophile sensor + */ +/*---------------------------------------------------------------------------*/ +#ifndef TMP_007_SENSOR_H_ +#define TMP_007_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#define TMP_007_SENSOR_TYPE_OBJECT 1 +#define TMP_007_SENSOR_TYPE_AMBIENT 2 +#define TMP_007_SENSOR_TYPE_ALL 3 +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor tmp_007_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* TMP_007_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/srf06/Makefile.srf06 b/platform/srf06-cc26xx/srf06/Makefile.srf06 new file mode 100644 index 000000000..44d115ec8 --- /dev/null +++ b/platform/srf06-cc26xx/srf06/Makefile.srf06 @@ -0,0 +1,9 @@ +CFLAGS += -DBOARD_SMARTRF06EB=1 + +CONTIKI_TARGET_DIRS += srf06 + +BOARD_SOURCEFILES += leds-arch.c srf06-sensors.c button-sensor.c board.c +BOARD_SOURCEFILES += als-sensor.c + +### Signal that we can be programmed with cc2538-bsl +BOARD_SUPPORTS_BSL=1 diff --git a/platform/srf06-cc26xx/srf06/als-sensor.c b/platform/srf06-cc26xx/srf06/als-sensor.c new file mode 100644 index 000000000..f149d16a1 --- /dev/null +++ b/platform/srf06-cc26xx/srf06/als-sensor.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2016, University of Bristol - http://www.bris.ac.uk/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup srf06-common-peripherals + * @{ + * + * \file + * Driver for the SmartRF06EB ALS when a CC13xx/CC26xxEM is mounted on it + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/sensors.h" +#include "srf06/als-sensor.h" +#include "sys/timer.h" +#include "dev/adc-sensor.h" +#include "dev/aux-ctrl.h" + +#include "ti-lib.h" + +#include +/*---------------------------------------------------------------------------*/ +static aux_consumer_module_t als_aux = { + .clocks = AUX_WUC_ADI_CLOCK | AUX_WUC_ANAIF_CLOCK | AUX_WUC_SMPH_CLOCK +}; +/*---------------------------------------------------------------------------*/ +static int +config(int type, int enable) +{ + switch(type) { + case SENSORS_HW_INIT: + ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_ALS_PWR); + break; + case SENSORS_ACTIVE: + ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_ALS_PWR); + ti_lib_ioc_port_configure_set(BOARD_IOID_ALS_OUT, IOC_PORT_GPIO, + IOC_STD_OUTPUT); + ti_lib_gpio_dir_mode_set(BOARD_ALS_OUT, GPIO_DIR_MODE_IN); + + if(enable) { + ti_lib_gpio_pin_write(BOARD_ALS_PWR, 1); + aux_ctrl_register_consumer(&als_aux); + ti_lib_aux_adc_select_input(ADC_COMPB_IN_AUXIO7); + clock_delay_usec(2000); + } else { + ti_lib_gpio_pin_write(BOARD_ALS_PWR, 0); + aux_ctrl_unregister_consumer(&als_aux); + } + break; + default: + break; + } + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + int val; + + ti_lib_aux_adc_enable_sync(AUXADC_REF_VDDS_REL, AUXADC_SAMPLE_TIME_2P7_US, + AUXADC_TRIGGER_MANUAL); + ti_lib_aux_adc_gen_manual_trigger(); + val = ti_lib_aux_adc_read_fifo(); + ti_lib_aux_adc_disable(); + + return val; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(als_sensor, ALS_SENSOR, value, config, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/srf06/als-sensor.h b/platform/srf06-cc26xx/srf06/als-sensor.h new file mode 100644 index 000000000..5d70478f8 --- /dev/null +++ b/platform/srf06-cc26xx/srf06/als-sensor.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016, University of Bristol - http://www.bris.ac.uk/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup srf06-common-peripherals + * @{ + * + * \file + * Header file for the SmartRF06EB + CC13xx/CC26xxEM ALS Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef ALS_SENSOR_H_ +#define ALS_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define ALS_SENSOR "ALS" +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor als_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* ALS_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/srf06/board-peripherals.h b/platform/srf06-cc26xx/srf06/board-peripherals.h new file mode 100644 index 000000000..c709ec963 --- /dev/null +++ b/platform/srf06-cc26xx/srf06/board-peripherals.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** \addtogroup cc26xx-srf-tag + * @{ + * + * \defgroup srf06-common-peripherals SmartRF06EB + CC13xx/CC26xx common + * + * Defines related to the SmartRF06 Evaluation Board irrespective of the EM + * mounted on it + * + * This file provides connectivity information on LEDs, Buttons, UART and + * other peripherals + * + * @{ + */ +/*---------------------------------------------------------------------------*/ +#ifndef BOARD_PERIPHERALS_H_ +#define BOARD_PERIPHERALS_H_ +/*---------------------------------------------------------------------------*/ +#include "als-sensor.h" +/*---------------------------------------------------------------------------*/ +#endif /* BOARD_PERIPHERALS_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/srf06/board.c b/platform/srf06-cc26xx/srf06/board.c new file mode 100644 index 000000000..15528f79a --- /dev/null +++ b/platform/srf06-cc26xx/srf06/board.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup sensortag-common-peripherals + * @{ + * + * \file + * Board-initialisation for the Srf06EB with a CC13xx/CC26xx EM. + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "ti-lib.h" +#include "lpm.h" +#include "prcm.h" +#include "hw_sysctl.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +static void +lpm_handler(uint8_t mode) +{ + /* Ambient light sensor (off, output low) */ + ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_ALS_PWR); + ti_lib_gpio_pin_write(BOARD_ALS_PWR, 0); + ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_ALS_OUT); + ti_lib_ioc_io_port_pull_set(BOARD_IOID_ALS_OUT, IOC_NO_IOPULL); +} +/*---------------------------------------------------------------------------*/ +static void +wakeup_handler(void) +{ + /* Turn on the PERIPH PD */ + ti_lib_prcm_power_domain_on(PRCM_DOMAIN_PERIPH); + while((ti_lib_prcm_power_domain_status(PRCM_DOMAIN_PERIPH) + != PRCM_DOMAIN_POWER_ON)); +} +/*---------------------------------------------------------------------------*/ +/* + * Declare a data structure to register with LPM. + * We don't care about what power mode we'll drop to, we don't care about + * getting notified before deep sleep. All we need is to be notified when we + * wake up so we can turn power domains back on + */ +LPM_MODULE(srf_module, NULL, lpm_handler, wakeup_handler, LPM_DOMAIN_NONE); +/*---------------------------------------------------------------------------*/ +static void +configure_unused_pins(void) +{ + /* Turn off 3.3-V domain (lcd/sdcard power, output low) */ + ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_3V3_EN); + ti_lib_gpio_pin_write(BOARD_3V3_EN, 0); + + /* Accelerometer (PWR output low, CSn output, high) */ + ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_ACC_PWR); + ti_lib_gpio_pin_write(BOARD_ACC_PWR, 0); +} +/*---------------------------------------------------------------------------*/ +void +board_init() +{ + uint8_t int_disabled = ti_lib_int_master_disable(); + + /* Turn on relevant PDs */ + wakeup_handler(); + + /* Enable GPIO peripheral */ + ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_GPIO); + + /* Apply settings and wait for them to take effect */ + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + lpm_register_module(&srf_module); + + configure_unused_pins(); + + /* Re-enable interrupt if initially enabled. */ + if(!int_disabled) { + ti_lib_int_master_enable(); + } +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/srf06/button-sensor.c b/platform/srf06-cc26xx/srf06/button-sensor.c new file mode 100644 index 000000000..b397e86f5 --- /dev/null +++ b/platform/srf06-cc26xx/srf06/button-sensor.c @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup srf06-common-peripherals + * @{ + * + * \file + * Driver for the SmartRF06EB buttons when a CC13xx/CC26xxEM is mounted on it + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "lib/sensors.h" +#include "srf06/button-sensor.h" +#include "gpio-interrupt.h" +#include "sys/timer.h" +#include "lpm.h" + +#include "ti-lib.h" + +#include +/*---------------------------------------------------------------------------*/ +#ifdef BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN +#define BUTTON_SENSOR_ENABLE_SHUTDOWN BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN +#else +#define BUTTON_SENSOR_ENABLE_SHUTDOWN 1 +#endif +/*---------------------------------------------------------------------------*/ +#define BUTTON_GPIO_CFG (IOC_CURRENT_2MA | IOC_STRENGTH_AUTO | \ + IOC_IOPULL_UP | IOC_SLEW_DISABLE | \ + IOC_HYST_DISABLE | IOC_BOTH_EDGES | \ + IOC_INT_ENABLE | IOC_IOMODE_NORMAL | \ + IOC_NO_WAKE_UP | IOC_INPUT_ENABLE) +/*---------------------------------------------------------------------------*/ +#define DEBOUNCE_DURATION (CLOCK_SECOND >> 5) + +struct btn_timer { + struct timer debounce; + clock_time_t start; + clock_time_t duration; +}; + +static struct btn_timer sel_timer, left_timer, right_timer, up_timer, + down_timer; +/*---------------------------------------------------------------------------*/ +/** + * \brief Handler for SmartRF button presses + */ +static void +button_press_handler(uint8_t ioid) +{ + if(ioid == BOARD_IOID_KEY_SELECT) { + if(!timer_expired(&sel_timer.debounce)) { + return; + } + + timer_set(&sel_timer.debounce, DEBOUNCE_DURATION); + + /* + * Start press duration counter on press (falling), notify on release + * (rising) + */ + if(ti_lib_gpio_pin_read(BOARD_KEY_SELECT) == 0) { + sel_timer.start = clock_time(); + sel_timer.duration = 0; + } else { + sel_timer.duration = clock_time() - sel_timer.start; + sensors_changed(&button_select_sensor); + } + } + + if(ioid == BOARD_IOID_KEY_LEFT) { + if(!timer_expired(&left_timer.debounce)) { + return; + } + + timer_set(&left_timer.debounce, DEBOUNCE_DURATION); + + /* + * Start press duration counter on press (falling), notify on release + * (rising) + */ + if(ti_lib_gpio_pin_read(BOARD_KEY_LEFT) == 0) { + left_timer.start = clock_time(); + left_timer.duration = 0; + } else { + left_timer.duration = clock_time() - left_timer.start; + sensors_changed(&button_left_sensor); + } + } + + if(ioid == BOARD_IOID_KEY_RIGHT) { + if(BUTTON_SENSOR_ENABLE_SHUTDOWN == 0) { + if(!timer_expired(&right_timer.debounce)) { + return; + } + + timer_set(&right_timer.debounce, DEBOUNCE_DURATION); + + /* + * Start press duration counter on press (falling), notify on release + * (rising) + */ + if(ti_lib_gpio_pin_read(BOARD_KEY_RIGHT) == 0) { + right_timer.start = clock_time(); + right_timer.duration = 0; + } else { + right_timer.duration = clock_time() - right_timer.start; + sensors_changed(&button_right_sensor); + } + } else { + lpm_shutdown(BOARD_IOID_KEY_RIGHT, IOC_IOPULL_UP, IOC_WAKE_ON_LOW); + } + } + + if(ioid == BOARD_IOID_KEY_UP) { + if(!timer_expired(&up_timer.debounce)) { + return; + } + + timer_set(&up_timer.debounce, DEBOUNCE_DURATION); + + /* + * Start press duration counter on press (falling), notify on release + * (rising) + */ + if(ti_lib_gpio_pin_read(BOARD_KEY_UP) == 0) { + up_timer.start = clock_time(); + up_timer.duration = 0; + } else { + up_timer.duration = clock_time() - up_timer.start; + sensors_changed(&button_up_sensor); + } + } + + if(ioid == BOARD_IOID_KEY_DOWN) { + if(!timer_expired(&down_timer.debounce)) { + return; + } + + timer_set(&down_timer.debounce, DEBOUNCE_DURATION); + + /* + * Start press duration counter on press (falling), notify on release + * (rising) + */ + if(ti_lib_gpio_pin_read(BOARD_KEY_DOWN) == 0) { + down_timer.start = clock_time(); + down_timer.duration = 0; + } else { + down_timer.duration = clock_time() - down_timer.start; + sensors_changed(&button_down_sensor); + } + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the button sensor for all buttons. + * + * \param type This function does nothing unless type == SENSORS_ACTIVE + * \param c 0: disable the button, non-zero: enable + * \param key: One of BOARD_KEY_LEFT, BOARD_KEY_RIGHT etc + */ +static void +config_buttons(int type, int c, uint32_t key) +{ + switch(type) { + case SENSORS_HW_INIT: + ti_lib_gpio_event_clear(1 << key); + ti_lib_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); + ti_lib_gpio_dir_mode_set((1 << key), GPIO_DIR_MODE_IN); + gpio_interrupt_register_handler(key, button_press_handler); + break; + case SENSORS_ACTIVE: + if(c) { + ti_lib_gpio_event_clear(1 << key); + ti_lib_ioc_port_configure_set(key, IOC_PORT_GPIO, BUTTON_GPIO_CFG); + ti_lib_gpio_dir_mode_set((1 << key), GPIO_DIR_MODE_IN); + ti_lib_ioc_int_enable(key); + } else { + ti_lib_ioc_int_disable(key); + } + break; + default: + break; + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the select button. + * + * Parameters are passed onto config_buttons, which does the actual + * configuration + * Parameters are ignored. They have been included because the prototype is + * dictated by the core sensor api. The return value is also required by + * the API but otherwise ignored. + * + * \param type passed to config_buttons as-is + * \param value passed to config_buttons as-is + * + * \return ignored + */ +static int +config_select(int type, int value) +{ + config_buttons(type, value, BOARD_IOID_KEY_SELECT); + + return 1; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the left button. + * + * Parameters are passed onto config_buttons, which does the actual + * configuration + * Parameters are ignored. They have been included because the prototype is + * dictated by the core sensor api. The return value is also required by + * the API but otherwise ignored. + * + * \param type passed to config_buttons as-is + * \param value passed to config_buttons as-is + * + * \return ignored + */ +static int +config_left(int type, int value) +{ + config_buttons(type, value, BOARD_IOID_KEY_LEFT); + + return 1; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the right button. + * + * Parameters are passed onto config_buttons, which does the actual + * configuration + * Parameters are ignored. They have been included because the prototype is + * dictated by the core sensor api. The return value is also required by + * the API but otherwise ignored. + * + * \param type passed to config_buttons as-is + * \param value passed to config_buttons as-is + * + * \return ignored + */ +static int +config_right(int type, int value) +{ + config_buttons(type, value, BOARD_IOID_KEY_RIGHT); + + return 1; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the up button. + * + * Parameters are passed onto config_buttons, which does the actual + * configuration + * Parameters are ignored. They have been included because the prototype is + * dictated by the core sensor api. The return value is also required by + * the API but otherwise ignored. + * + * \param type passed to config_buttons as-is + * \param value passed to config_buttons as-is + * + * \return ignored + */ +static int +config_up(int type, int value) +{ + config_buttons(type, value, BOARD_IOID_KEY_UP); + + return 1; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Configuration function for the down button. + * + * Parameters are passed onto config_buttons, which does the actual + * configuration + * Parameters are ignored. They have been included because the prototype is + * dictated by the core sensor api. The return value is also required by + * the API but otherwise ignored. + * + * \param type passed to config_buttons as-is + * \param value passed to config_buttons as-is + * + * \return ignored + */ +static int +config_down(int type, int value) +{ + config_buttons(type, value, BOARD_IOID_KEY_DOWN); + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +value_select(int type) +{ + if(type == BUTTON_SENSOR_VALUE_STATE) { + return ti_lib_gpio_pin_read(BOARD_KEY_SELECT) == 0 ? + BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; + } else if(type == BUTTON_SENSOR_VALUE_DURATION) { + return (int)sel_timer.duration; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value_left(int type) +{ + if(type == BUTTON_SENSOR_VALUE_STATE) { + return ti_lib_gpio_pin_read(BOARD_KEY_LEFT) == 0 ? + BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; + } else if(type == BUTTON_SENSOR_VALUE_DURATION) { + return (int)left_timer.duration; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value_right(int type) +{ + if(type == BUTTON_SENSOR_VALUE_STATE) { + return ti_lib_gpio_pin_read(BOARD_KEY_RIGHT) == 0 ? + BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; + } else if(type == BUTTON_SENSOR_VALUE_DURATION) { + return (int)right_timer.duration; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value_up(int type) +{ + if(type == BUTTON_SENSOR_VALUE_STATE) { + return ti_lib_gpio_pin_read(BOARD_KEY_UP) == 0 ? + BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; + } else if(type == BUTTON_SENSOR_VALUE_DURATION) { + return (int)up_timer.duration; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value_down(int type) +{ + if(type == BUTTON_SENSOR_VALUE_STATE) { + return ti_lib_gpio_pin_read(BOARD_KEY_DOWN) == 0 ? + BUTTON_SENSOR_VALUE_PRESSED : BUTTON_SENSOR_VALUE_RELEASED; + } else if(type == BUTTON_SENSOR_VALUE_DURATION) { + return (int)down_timer.duration; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for all buttons + * \param type SENSORS_ACTIVE or SENSORS_READY + * \param key_io_id BOARD_IOID_KEY_LEFT, BOARD_IOID_KEY_RIGHT etc + * \return 1 if the button's port interrupt is enabled (edge detect) + * + * This function will only be called by status_left, status_right and the + * called will pass the correct key_io_id + */ +static int +status(int type, uint32_t key_io_id) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + if(ti_lib_ioc_port_configure_get(key_io_id) & IOC_INT_ENABLE) { + return 1; + } + break; + default: + break; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for the select button. + * \param type SENSORS_ACTIVE or SENSORS_READY + * \return 1 if the button's port interrupt is enabled (edge detect) + * + * This function will call status. It will pass type verbatim and it will also + * pass the correct key_io_id + */ +static int +status_select(int type) +{ + return status(type, BOARD_IOID_KEY_SELECT); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for the left button. + * \param type SENSORS_ACTIVE or SENSORS_READY + * \return 1 if the button's port interrupt is enabled (edge detect) + * + * This function will call status. It will pass type verbatim and it will also + * pass the correct key_io_id + */ +static int +status_left(int type) +{ + return status(type, BOARD_IOID_KEY_LEFT); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for the right button. + * \param type SENSORS_ACTIVE or SENSORS_READY + * \return 1 if the button's port interrupt is enabled (edge detect) + * + * This function will call status. It will pass type verbatim and it will also + * pass the correct key_io_id + */ +static int +status_right(int type) +{ + return status(type, BOARD_IOID_KEY_RIGHT); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for the up button. + * \param type SENSORS_ACTIVE or SENSORS_READY + * \return 1 if the button's port interrupt is enabled (edge detect) + * + * This function will call status. It will pass type verbatim and it will also + * pass the correct key_io_id + */ +static int +status_up(int type) +{ + return status(type, BOARD_IOID_KEY_UP); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Status function for the down button. + * \param type SENSORS_ACTIVE or SENSORS_READY + * \return 1 if the button's port interrupt is enabled (edge detect) + * + * This function will call status. It will pass type verbatim and it will also + * pass the correct key_io_id + */ +static int +status_down(int type) +{ + return status(type, BOARD_IOID_KEY_DOWN); +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(button_select_sensor, BUTTON_SENSOR, value_select, + config_select, status_select); +SENSORS_SENSOR(button_left_sensor, BUTTON_SENSOR, value_left, config_left, + status_left); +SENSORS_SENSOR(button_right_sensor, BUTTON_SENSOR, value_right, config_right, + status_right); +SENSORS_SENSOR(button_up_sensor, BUTTON_SENSOR, value_up, config_up, status_up); +SENSORS_SENSOR(button_down_sensor, BUTTON_SENSOR, value_down, config_down, + status_down); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/srf06/button-sensor.h b/platform/srf06-cc26xx/srf06/button-sensor.h new file mode 100644 index 000000000..1c810c96d --- /dev/null +++ b/platform/srf06-cc26xx/srf06/button-sensor.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup srf06-common-peripherals + * @{ + * + * \file + * Header file for the SmartRF06EB + CC13xx/CC26xxEM Button Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef BUTTON_SENSOR_H_ +#define BUTTON_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR "Button" +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR_VALUE_STATE 0 +#define BUTTON_SENSOR_VALUE_DURATION 1 + +#define BUTTON_SENSOR_VALUE_RELEASED 0 +#define BUTTON_SENSOR_VALUE_PRESSED 1 +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor button_select_sensor; +extern const struct sensors_sensor button_left_sensor; +extern const struct sensors_sensor button_right_sensor; +extern const struct sensors_sensor button_up_sensor; +extern const struct sensors_sensor button_down_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* BUTTON_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/srf06/cc13xx/Makefile.cc13xx b/platform/srf06-cc26xx/srf06/cc13xx/Makefile.cc13xx new file mode 100644 index 000000000..b83084651 --- /dev/null +++ b/platform/srf06-cc26xx/srf06/cc13xx/Makefile.cc13xx @@ -0,0 +1,7 @@ +### Will allow the inclusion of the correct CPU makefile +CPU_FAMILY = cc13xx + +### Include the common sensortag makefile +include $(PLATFORM_ROOT_DIR)/srf06/Makefile.srf06 + +CONTIKI_TARGET_DIRS += srf06/cc13xx diff --git a/platform/srf06-cc26xx/srf06/cc13xx/board.h b/platform/srf06-cc26xx/srf06/cc13xx/board.h new file mode 100644 index 000000000..eff486fc5 --- /dev/null +++ b/platform/srf06-cc26xx/srf06/cc13xx/board.h @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** \addtogroup cc26xx-srf-tag + * @{ + * + * \defgroup srf06-cc13xx-peripherals Peripherals for the SmartRF06EB + CC1310EM + * + * Defines related to the SmartRF06 Evaluation Board with a CC1310EM + * + * This file provides connectivity information on LEDs, Buttons, UART and + * other peripherals + * + * This file can be used as the basis to configure other boards using the + * CC13xx/CC26xx code as their basis. + * + * This file is not meant to be modified by the user. + * @{ + * + * \file + * Header file with definitions related to the I/O connections on the TI + * SmartRF06 Evaluation Board with a CC1310EM + * + * \note Do not include this file directly. It gets included by contiki-conf + * after all relevant directives have been set. + */ +/*---------------------------------------------------------------------------*/ +#ifndef BOARD_H_ +#define BOARD_H_ +/*---------------------------------------------------------------------------*/ +#include "ioc.h" +/*---------------------------------------------------------------------------*/ +/** + * \name LED configurations + * + * Those values are not meant to be modified by the user + * @{ + */ +/* Some files include leds.h before us, so we need to get rid of defaults in + * leds.h before we provide correct definitions */ +#undef LEDS_GREEN +#undef LEDS_YELLOW +#undef LEDS_RED +#undef LEDS_CONF_ALL + +#define LEDS_RED 1 /**< LED1 (Red) */ +#define LEDS_YELLOW 2 /**< LED2 (Yellow) */ +#define LEDS_GREEN 4 /**< LED3 (Green) */ +#define LEDS_ORANGE 8 /**< LED4 (Orange) */ + +#define LEDS_CONF_ALL 15 + +/* Notify various examples that we have LEDs */ +#define PLATFORM_HAS_LEDS 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name LED IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_LED_1 IOID_25 +#define BOARD_IOID_LED_2 IOID_27 +#define BOARD_IOID_LED_3 IOID_7 +#define BOARD_IOID_LED_4 IOID_6 +#define BOARD_LED_1 (1 << BOARD_IOID_LED_1) +#define BOARD_LED_2 (1 << BOARD_IOID_LED_2) +#define BOARD_LED_3 (1 << BOARD_IOID_LED_3) +#define BOARD_LED_4 (1 << BOARD_IOID_LED_4) +#define BOARD_LED_ALL (BOARD_LED_1 | BOARD_LED_2 | BOARD_LED_3 | \ + BOARD_LED_4) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name UART IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_UART_RX IOID_2 +#define BOARD_IOID_UART_TX IOID_3 +#define BOARD_IOID_UART_CTS IOID_UNUSED +#define BOARD_IOID_UART_RTS IOID_UNUSED +#define BOARD_UART_RX (1 << BOARD_IOID_UART_RX) +#define BOARD_UART_TX (1 << BOARD_IOID_UART_TX) +#define BOARD_UART_CTS (1 << BOARD_IOID_UART_CTS) +#define BOARD_UART_RTS (1 << BOARD_IOID_UART_RTS) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Button IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_KEY_LEFT IOID_15 +#define BOARD_IOID_KEY_RIGHT IOID_18 +#define BOARD_IOID_KEY_UP IOID_19 +#define BOARD_IOID_KEY_DOWN IOID_12 +#define BOARD_IOID_KEY_SELECT IOID_11 +#define BOARD_KEY_LEFT (1 << BOARD_IOID_KEY_LEFT) +#define BOARD_KEY_RIGHT (1 << BOARD_IOID_KEY_RIGHT) +#define BOARD_KEY_UP (1 << BOARD_IOID_KEY_UP) +#define BOARD_KEY_DOWN (1 << BOARD_IOID_KEY_DOWN) +#define BOARD_KEY_SELECT (1 << BOARD_IOID_KEY_SELECT) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name 3.3V domain IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_3V3_EN IOID_13 +#define BOARD_3V3_EN (1 << BOARD_IOID_3V3_EN) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_SPI_SCK IOID_10 +#define BOARD_IOID_SPI_MOSI IOID_9 +#define BOARD_IOID_SPI_MISO IOID_8 +#define BOARD_SPI_SCK (1 << BOARD_IOID_SPI_SCK) +#define BOARD_SPI_MOSI (1 << BOARD_IOID_SPI_MOSI) +#define BOARD_SPI_MISO (1 << BOARD_IOID_SPI_MISO) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name LCD IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_LCD_MODE IOID_4 +#define BOARD_IOID_LCD_RST IOID_5 +#define BOARD_IOID_LCD_CS IOID_14 +#define BOARD_IOID_LCD_SCK BOARD_IOID_SPI_SCK +#define BOARD_IOID_LCD_MOSI BOARD_IOID_SPI_MOSI +#define BOARD_LCD_MODE (1 << BOARD_IOID_LCD_MODE) +#define BOARD_LCD_RST (1 << BOARD_IOID_LCD_RST) +#define BOARD_LCD_CS (1 << BOARD_IOID_LCD_CS) +#define BOARD_LCD_SCK BOARD_SPI_SCK +#define BOARD_LCD_MOSI BOARD_SPI_MOSI +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SD Card IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_SDCARD_CS IOID_30 +#define BOARD_SDCARD_CS (1 << BOARD_IOID_SDCARD_CS) +#define BOARD_IOID_SDCARD_SCK BOARD_IOID_SPI_SCK +#define BOARD_SDCARD_SCK BOARD_SPI_SCK +#define BOARD_IOID_SDCARD_MOSI BOARD_IOID_SPI_MOSI +#define BOARD_SDCARD_MOSI BOARD_SPI_MOSI +#define BOARD_IOID_SDCARD_MISO BOARD_IOID_SPI_MISO +#define BOARD_SDCARD_MISO BOARD_SPI_MISO +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name ALS IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_ALS_PWR IOID_26 +#define BOARD_IOID_ALS_OUT IOID_23 +#define BOARD_ALS_PWR (1 << BOARD_IOID_ALS_PWR) +#define BOARD_ALS_OUT (1 << BOARD_IOID_ALS_OUT) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name ACC IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_ACC_PWR IOID_20 +#define BOARD_IOID_ACC_INT IOID_28 +#define BOARD_IOID_ACC_INT1 IOID_28 +#define BOARD_IOID_ACC_INT2 IOID_29 +#define BOARD_IOID_ACC_CS IOID_24 +#define BOARD_ACC_PWR (1 << BOARD_IOID_ACC_PWR) +#define BOARD_ACC_INT (1 << BOARD_IOID_ACC_INT) +#define BOARD_ACC_INT1 (1 << BOARD_IOID_ACC_INT1) +#define BOARD_ACC_INT2 (1 << BOARD_IOID_ACC_INT2) +#define BOARD_ACC_CS (1 << BOARD_IOID_ACC_CS) +#define BOARD_IOID_ACC_SCK BOARD_IOID_SPI_SCK +#define BOARD_ACC_SCK BOARD_SPI_SCK +#define BOARD_IOID_ACC_MOSI BOARD_IOID_SPI_MOSI +#define BOARD_ACC_MOSI BOARD_SPI_MOSI +#define BOARD_IOID_ACC_MISO BOARD_IOID_SPI_MISO +#define BOARD_ACC_MISO BOARD_SPI_MISO +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Device string used on startup + * @{ + */ +#define BOARD_STRING "TI SmartRF06EB + CC13xx EM" +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* BOARD_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/srf06/cc26xx/Makefile.cc26xx b/platform/srf06-cc26xx/srf06/cc26xx/Makefile.cc26xx new file mode 100644 index 000000000..841442a5c --- /dev/null +++ b/platform/srf06-cc26xx/srf06/cc26xx/Makefile.cc26xx @@ -0,0 +1,7 @@ +### Will allow the inclusion of the correct CPU makefile +CPU_FAMILY = cc26xx + +### Include the common makefile +include $(PLATFORM_ROOT_DIR)/srf06/Makefile.srf06 + +CONTIKI_TARGET_DIRS += srf06/cc26xx diff --git a/platform/srf06-cc26xx/srf06/cc26xx/board.h b/platform/srf06-cc26xx/srf06/cc26xx/board.h new file mode 100644 index 000000000..3dd064bc3 --- /dev/null +++ b/platform/srf06-cc26xx/srf06/cc26xx/board.h @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** \addtogroup cc26xx-srf-tag + * @{ + * + * \defgroup srf06-cc26xx-peripherals Peripherals for the SmartRF06EB + CC26xxEM + * + * Defines related to the SmartRF06 Evaluation Board with a CC26xxEM + * + * This file provides connectivity information on LEDs, Buttons, UART and + * other peripherals + * + * This file can be used as the basis to configure other boards using the + * CC13xx/CC26xx code as their basis. + * + * This file is not meant to be modified by the user. + * @{ + * + * \file + * Header file with definitions related to the I/O connections on the TI + * SmartRF06 Evaluation Board with a CC26xxEM + * + * \note Do not include this file directly. It gets included by contiki-conf + * after all relevant directives have been set. + */ +/*---------------------------------------------------------------------------*/ +#ifndef BOARD_H_ +#define BOARD_H_ +/*---------------------------------------------------------------------------*/ +#include "ioc.h" +/*---------------------------------------------------------------------------*/ +/** + * \name LED configurations + * + * Those values are not meant to be modified by the user + * @{ + */ +/* Some files include leds.h before us, so we need to get rid of defaults in + * leds.h before we provide correct definitions */ +#undef LEDS_GREEN +#undef LEDS_YELLOW +#undef LEDS_RED +#undef LEDS_CONF_ALL + +#define LEDS_RED 1 /**< LED1 (Red) */ +#define LEDS_YELLOW 2 /**< LED2 (Yellow) */ +#define LEDS_GREEN 4 /**< LED3 (Green) */ +#define LEDS_ORANGE 8 /**< LED4 (Orange) */ + +#define LEDS_CONF_ALL 15 + +/* Notify various examples that we have LEDs */ +#define PLATFORM_HAS_LEDS 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name LED IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_LED_1 IOID_25 +#define BOARD_IOID_LED_2 IOID_27 +#define BOARD_IOID_LED_3 IOID_7 +#define BOARD_IOID_LED_4 IOID_6 +#define BOARD_LED_1 (1 << BOARD_IOID_LED_1) +#define BOARD_LED_2 (1 << BOARD_IOID_LED_2) +#define BOARD_LED_3 (1 << BOARD_IOID_LED_3) +#define BOARD_LED_4 (1 << BOARD_IOID_LED_4) +#define BOARD_LED_ALL (BOARD_LED_1 | BOARD_LED_2 | BOARD_LED_3 | \ + BOARD_LED_4) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name UART IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_UART_RX IOID_2 +#define BOARD_IOID_UART_TX IOID_3 +#define BOARD_IOID_UART_CTS IOID_UNUSED +#define BOARD_IOID_UART_RTS IOID_UNUSED +#define BOARD_UART_RX (1 << BOARD_IOID_UART_RX) +#define BOARD_UART_TX (1 << BOARD_IOID_UART_TX) +#define BOARD_UART_CTS (1 << BOARD_IOID_UART_CTS) +#define BOARD_UART_RTS (1 << BOARD_IOID_UART_RTS) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Button IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_KEY_LEFT IOID_15 +#define BOARD_IOID_KEY_RIGHT IOID_18 +#define BOARD_IOID_KEY_UP IOID_19 +#define BOARD_IOID_KEY_DOWN IOID_12 +#define BOARD_IOID_KEY_SELECT IOID_11 +#define BOARD_KEY_LEFT (1 << BOARD_IOID_KEY_LEFT) +#define BOARD_KEY_RIGHT (1 << BOARD_IOID_KEY_RIGHT) +#define BOARD_KEY_UP (1 << BOARD_IOID_KEY_UP) +#define BOARD_KEY_DOWN (1 << BOARD_IOID_KEY_DOWN) +#define BOARD_KEY_SELECT (1 << BOARD_IOID_KEY_SELECT) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name 3.3V domain IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_3V3_EN IOID_13 +#define BOARD_3V3_EN (1 << BOARD_IOID_3V3_EN) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_SPI_SCK IOID_10 +#define BOARD_IOID_SPI_MOSI IOID_9 +#define BOARD_IOID_SPI_MISO IOID_8 +#define BOARD_SPI_SCK (1 << BOARD_IOID_SPI_SCK) +#define BOARD_SPI_MOSI (1 << BOARD_IOID_SPI_MOSI) +#define BOARD_SPI_MISO (1 << BOARD_IOID_SPI_MISO) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name LCD IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_LCD_MODE IOID_4 +#define BOARD_IOID_LCD_RST IOID_5 +#define BOARD_IOID_LCD_CS IOID_14 +#define BOARD_IOID_LCD_SCK BOARD_IOID_SPI_SCK +#define BOARD_IOID_LCD_MOSI BOARD_IOID_SPI_MOSI +#define BOARD_LCD_MODE (1 << BOARD_IOID_LCD_MODE) +#define BOARD_LCD_RST (1 << BOARD_IOID_LCD_RST) +#define BOARD_LCD_CS (1 << BOARD_IOID_LCD_CS) +#define BOARD_LCD_SCK BOARD_SPI_SCK +#define BOARD_LCD_MOSI BOARD_SPI_MOSI +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SD Card IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_SDCARD_CS IOID_30 +#define BOARD_SDCARD_CS (1 << BOARD_IOID_SDCARD_CS) +#define BOARD_IOID_SDCARD_SCK BOARD_IOID_SPI_SCK +#define BOARD_SDCARD_SCK BOARD_SPI_SCK +#define BOARD_IOID_SDCARD_MOSI BOARD_IOID_SPI_MOSI +#define BOARD_SDCARD_MOSI BOARD_SPI_MOSI +#define BOARD_IOID_SDCARD_MISO BOARD_IOID_SPI_MISO +#define BOARD_SDCARD_MISO BOARD_SPI_MISO +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name ALS IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_ALS_PWR IOID_26 +#define BOARD_IOID_ALS_OUT IOID_23 +#define BOARD_ALS_PWR (1 << BOARD_IOID_ALS_PWR) +#define BOARD_ALS_OUT (1 << BOARD_IOID_ALS_OUT) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name ACC IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_ACC_PWR IOID_20 +#define BOARD_IOID_ACC_INT IOID_28 +#define BOARD_IOID_ACC_INT1 IOID_28 +#define BOARD_IOID_ACC_INT2 IOID_29 +#define BOARD_IOID_ACC_CS IOID_24 +#define BOARD_ACC_PWR (1 << BOARD_IOID_ACC_PWR) +#define BOARD_ACC_INT (1 << BOARD_IOID_ACC_INT) +#define BOARD_ACC_INT1 (1 << BOARD_IOID_ACC_INT1) +#define BOARD_ACC_INT2 (1 << BOARD_IOID_ACC_INT2) +#define BOARD_ACC_CS (1 << BOARD_IOID_ACC_CS) +#define BOARD_IOID_ACC_SCK BOARD_IOID_SPI_SCK +#define BOARD_ACC_SCK BOARD_SPI_SCK +#define BOARD_IOID_ACC_MOSI BOARD_IOID_SPI_MOSI +#define BOARD_ACC_MOSI BOARD_SPI_MOSI +#define BOARD_IOID_ACC_MISO BOARD_IOID_SPI_MISO +#define BOARD_ACC_MISO BOARD_SPI_MISO +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Device string used on startup + * @{ + */ +#define BOARD_STRING "TI SmartRF06EB + CC26xx EM" +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* BOARD_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/srf06/leds-arch.c b/platform/srf06-cc26xx/srf06/leds-arch.c new file mode 100644 index 000000000..423789350 --- /dev/null +++ b/platform/srf06-cc26xx/srf06/leds-arch.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup srf06-common-peripherals + * @{ + * + * \file + * Driver for the SmartRF06EB LEDs when a CC13xx/CC26xx EM is mounted on it + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/leds.h" +#include "ti-lib.h" +/*---------------------------------------------------------------------------*/ +static unsigned char c; +static int inited = 0; +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + if(inited) { + return; + } + inited = 1; + + ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_LED_1); + ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_LED_2); + ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_LED_3); + ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_LED_4); + + ti_lib_gpio_pin_write(BOARD_LED_ALL, 0); +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + return c; +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char leds) +{ + c = leds; + + /* Clear everything */ + ti_lib_gpio_pin_write(BOARD_LED_ALL, 0); + + if((leds & LEDS_RED) == LEDS_RED) { + ti_lib_gpio_pin_write(BOARD_LED_1, 1); + } + if((leds & LEDS_YELLOW) == LEDS_YELLOW) { + ti_lib_gpio_pin_write(BOARD_LED_2, 1); + } + if((leds & LEDS_GREEN) == LEDS_GREEN) { + ti_lib_gpio_pin_write(BOARD_LED_3, 1); + } + if((leds & LEDS_ORANGE) == LEDS_ORANGE) { + ti_lib_gpio_pin_write(BOARD_LED_4, 1); + } +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/srf06-cc26xx/srf06/srf06-sensors.c b/platform/srf06-cc26xx/srf06/srf06-sensors.c new file mode 100644 index 000000000..5f65a0cb2 --- /dev/null +++ b/platform/srf06-cc26xx/srf06/srf06-sensors.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup srf06-common-peripherals + * @{ + * + * \file + * Generic module controlling sensors on the SmartRF06EB when a CC26xx is + * mounted on the board + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "srf06/button-sensor.h" +#include "srf06/als-sensor.h" + +#include +/*---------------------------------------------------------------------------*/ +/** \brief Exports a global symbol to be used by the sensor API */ +SENSORS(&button_select_sensor, &button_left_sensor, &button_right_sensor, + &button_up_sensor, &button_down_sensor, &als_sensor); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/stm32nucleo-spirit1/Makefile.ids01a4 b/platform/stm32nucleo-spirit1/Makefile.ids01a4 new file mode 100644 index 000000000..ef2dfb9ac --- /dev/null +++ b/platform/stm32nucleo-spirit1/Makefile.ids01a4 @@ -0,0 +1,2 @@ +#Simply set the correct flag +CFLAGS += -DX_NUCLEO_IDS01A4 diff --git a/platform/stm32nucleo-spirit1/Makefile.ids01a5 b/platform/stm32nucleo-spirit1/Makefile.ids01a5 new file mode 100644 index 000000000..b696c713c --- /dev/null +++ b/platform/stm32nucleo-spirit1/Makefile.ids01a5 @@ -0,0 +1,2 @@ +#Simply set the correct flag +CFLAGS += -DX_NUCLEO_IDS01A5 diff --git a/platform/stm32nucleo-spirit1/Makefile.iks01a1 b/platform/stm32nucleo-spirit1/Makefile.iks01a1 new file mode 100644 index 000000000..c36138a69 --- /dev/null +++ b/platform/stm32nucleo-spirit1/Makefile.iks01a1 @@ -0,0 +1,23 @@ +CFLAGS += -DX_NUCLEO_IKS01A1 + +CONTIKI_TARGET_DIRS += stm32cube-lib/drivers/x_nucleo_iks01a1 +CONTIKI_TARGET_DIRS += stm32cube-lib/drivers/sensors/hts221 stm32cube-lib/drivers/sensors/lps25h stm32cube-lib/drivers/sensors/lps25hb\ + stm32cube-lib/drivers/sensors/lsm6ds0 stm32cube-lib/drivers/sensors/lsm6ds3 stm32cube-lib/drivers/sensors/lis3mdl + +ARCH_DEV_SENSORS = temperature-sensor.c humidity-sensor.c pressure-sensor.c magneto-sensor.c acceleration-sensor.c gyroscope-sensor.c + +ARCH_DRIVERS_IKS01A1 = x_nucleo_iks01a1.c x_nucleo_iks01a1_hum_temp.c x_nucleo_iks01a1_imu_6axes.c \ + x_nucleo_iks01a1_magneto.c x_nucleo_iks01a1_pressure.c + + +ARCH_DRIVERS_SENSORS = hts221.c \ + lis3mdl.c \ + lps25h.c \ + lps25hb.c \ + lsm6ds0.c \ + lsm6ds3.c + +ARCH+=$(ARCH_DEV_SENSORS) +ARCH+=$(ARCH_DRIVERS_IKS01A1) +ARCH+=$(ARCH_DRIVERS_SENSORS) + diff --git a/platform/stm32nucleo-spirit1/Makefile.stm32nucleo-spirit1 b/platform/stm32nucleo-spirit1/Makefile.stm32nucleo-spirit1 new file mode 100644 index 000000000..ebc188377 --- /dev/null +++ b/platform/stm32nucleo-spirit1/Makefile.stm32nucleo-spirit1 @@ -0,0 +1,246 @@ + +CONTIKI_TARGET_DIRS = . + +ifeq ($(BOARD),) + BOARD=ids01a4 + ${info ***************************************************} + ${info BOARD not specified, default to ids01a4 (868 MHz)!} + ${info ***************************************************} +else ifeq ($(BOARD),ids01a4) + ${info ***************************************************} + ${info Using ids01a4 SPIRIT1 expansion board (868 MHz)} + ${info ***************************************************} +else ifeq ($(BOARD),ids01a5) + ${info ***************************************************} + ${info Using ids01a5 SPIRIT1 expansion board (915 MHz)} + ${info ***************************************************} +else + ${info ***************************************************} + ${info You must specify a valid SPIRIT1 board to use:} + ${info make BOARD=ids01a4 for X-NUCLEO-IDS01A4 (868 MHz)} + ${info make BOARD=ids01a5 for X-NUCLEO-IDS01A5 (915 MHz)} + ${info ***************************************************} + ${error } +endif + +### Include the board-specific makefile +PLATFORM_ROOT_DIR = $(CONTIKI)/platform/$(TARGET) +-include $(PLATFORM_ROOT_DIR)/Makefile.$(BOARD) + +ifeq ($(SENSORBOARD),iks01a1) + ${info Compiling with X-NUCLEO-IKS01A1 sensors files} + ${info ***************************************************} + -include $(PLATFORM_ROOT_DIR)/Makefile.$(SENSORBOARD) +else ifeq ($(SENSORBOARD),) + ${info NOT compiling files for any sensors expansion board} + ${info ***************************************************} +else + ${info Error: SENSORBOARD can be: iks01a1} + ${info ***************************************************} + ${error } +endif + + + +#Currently we support only GCC +GCC=1 + +CONTIKI_TARGET_DIRS += dev +CONTIKI_TARGET_DIRS += stm32cube-lib/stm32cube-prj/Src +CONTIKI_TARGET_DIRS += stm32cube-lib/drivers/stm32l1xx_nucleo +CONTIKI_TARGET_DIRS += stm32cube-lib/drivers/x_nucleo_ids01ax +CONTIKI_TARGET_DIRS += stm32cube-lib/drivers/Common +CONTIKI_TARGET_DIRS += stm32cube-lib/drivers/spirit1/src stm32cube-lib/drivers/spirit1/inc +CONTIKI_TARGET_DIRS += stm32cube-lib/drivers/CMSIS +CONTIKI_TARGET_DIRS += stm32cube-lib/drivers/STM32L1xx_HAL_Driver +CONTIKI_TARGET_DIRS += stm32cube-lib/drivers/STM32L1xx_HAL_Driver/Src +CONTIKI_TARGET_DIRS += stm32cube-lib/drivers/STM32L1xx_HAL_Driver/Inc + + +ARCH_DEV = button-sensor.c leds-arch.c radio-sensor.c + +ARCH_NUCLEOSPIRIT1 = contiki-spirit1-main.c uart-msg.c spirit1-arch.c spirit1.c node-id.c + +ARCH_NUCLEOSPIRIT1_STM32CUBEHAL = spirit1_appli.c stm32l1xx_hal_msp.c stm32l1xx_it.c stm32cube_hal_init.c + +ARCH_DRIVERS_STM32L1xx = stm32l1xx_nucleo.c + +ARCH_DRIVERS_IDS01AX = radio_gpio.c radio_shield_config.c radio_spi.c + +ARCH_DRIVERS_SPIRIT1 = \ + SPIRIT1_Util.c \ + SPIRIT_Aes.c \ + SPIRIT_Calibration.c \ + SPIRIT_Commands.c \ + SPIRIT_Csma.c \ + SPIRIT_DirectRF.c \ + SPIRIT_General.c \ + SPIRIT_Gpio.c \ + SPIRIT_Irq.c \ + SPIRIT_LinearFifo.c \ + SPIRIT_Management.c \ + SPIRIT_PktBasic.c \ + SPIRIT_PktCommon.c \ + SPIRIT_PktMbus.c \ + SPIRIT_PktStack.c \ + SPIRIT_Qi.c \ + SPIRIT_Radio.c \ + SPIRIT_Timer.c \ + SPIRIT_Types.c + +STM32L1XX_HAL =\ + stm32l1xx_hal.c\ + stm32l1xx_hal_adc_ex.c\ + stm32l1xx_hal_adc.c\ + stm32l1xx_hal_comp.c\ + stm32l1xx_hal_cortex.c\ + stm32l1xx_hal_crc.c\ + stm32l1xx_hal_cryp_ex.c\ + stm32l1xx_hal_cryp.c\ + stm32l1xx_hal_dac_ex.c\ + stm32l1xx_hal_dac.c\ + stm32l1xx_hal_dma.c\ + stm32l1xx_hal_flash_ex.c\ + stm32l1xx_hal_flash.c\ + stm32l1xx_hal_flash_ramfunc.c\ + stm32l1xx_hal_gpio.c\ + stm32l1xx_hal_i2c.c\ + stm32l1xx_hal_i2s.c\ + stm32l1xx_hal_irda.c\ + stm32l1xx_hal_iwdg.c\ + stm32l1xx_hal_lcd.c\ + stm32l1xx_hal_nor.c\ + stm32l1xx_hal_opamp_ex.c\ + stm32l1xx_hal_opamp.c\ + stm32l1xx_hal_pcd_ex.c\ + stm32l1xx_hal_pcd.c\ + stm32l1xx_hal_pwr_ex.c\ + stm32l1xx_hal_pwr.c\ + stm32l1xx_hal_rcc_ex.c\ + stm32l1xx_hal_rcc.c\ + stm32l1xx_hal_rtc_ex.c\ + stm32l1xx_hal_rtc.c\ + stm32l1xx_hal_sd.c\ + stm32l1xx_hal_smartcard.c\ + stm32l1xx_hal_spi_ex.c\ + stm32l1xx_hal_spi.c\ + stm32l1xx_hal_sram.c\ + stm32l1xx_hal_tim_ex.c\ + stm32l1xx_hal_tim.c\ + stm32l1xx_hal_uart.c\ + stm32l1xx_hal_usart.c\ + stm32l1xx_hal_wwdg.c\ + stm32l1xx_ll_fsmc.c\ + stm32l1xx_ll_sdmmc.c + +ARCH+=$(ARCH_DEV) +ARCH+=$(ARCH_NUCLEOSPIRIT1) +ARCH+=$(ARCH_NUCLEOSPIRIT1_STM32CUBEHAL) +ARCH+=$(ARCH_DRIVERS_STM32L1xx) +ARCH+=$(ARCH_DRIVERS_IDS01AX) +ARCH+=$(ARCH_DRIVERS_SPIRIT1) +ARCH+=$(STM32L1XX_HAL) + +CFLAGS += -DUSE_STM32L152_EVAL \ + -DSTM32L152xE \ + -DUSE_STM32L1XX_NUCLEO \ + -DUSE_HAL_DRIVER \ + -DUSE_STDPERIPH_DRIVER \ + -DNO_EEPROM \ + -DSPIRIT1_ST_SHIELD \ + -DSPIRIT_MODULE \ + -DUSE_SPIRIT1_DEFAULT + +CFLAGS += -I. \ + -I$(CONTIKI)/platform/$(TARGET)/ \ + -I$(CONTIKI)/platform/$(TARGET)/stm32cube-lib/stm32cube-prj/Inc \ + -I$(CONTIKI)/platform/$(TARGET)/stm32cube-lib/drivers/Common \ + -I$(CONTIKI)/platform/$(TARGET)/stm32cube-lib/drivers/spirit1/inc \ + -I$(CONTIKI)/platform/$(TARGET)/stm32cube-lib/drivers/CMSIS \ + -I$(CONTIKI)/platform/$(TARGET)/stm32cube-lib/drivers/STM32L1xx_HAL_Driver/Inc \ + -I$(CONTIKI)/cpu/arm/stm32l152 \ + -I$(CONTIKI)/core \ + -I$(CONTIKI)/platform/$(TARGET)/dev + +ifdef UIP_CONF_IPV6 +CFLAGS += -DWITH_UIP6=1 +endif + + +ifndef CONTIKI_TARGET_MAIN +CONTIKI_TARGET_MAIN = contiki-spirit1-main.c +endif + +CONTIKI_TARGET_SOURCEFILES += $(ARCH) $(CONTIKI_TARGET_MAIN) + +MCU=stm32l152 +CONTIKI_CPU=$(CONTIKI)/cpu/arm/stm32l152 +include $(CONTIKI)/cpu/arm/stm32l152/Makefile.stm32l152 + + +MODULES+=core/net \ + core/net/mac core/net/mac/contikimac \ + core/net/llsec + + +# build rules ------------------------------------ + +CLEAN += *.stm32nucleo-spirit1 symbols.c symbols.h contiki-stm32nucleo-spirit1.log + +contiki-$(TARGET).a: ${addprefix $(OBJECTDIR)/,symbols.o} + +help: + @echo A few useful make commands: + @echo make help - shows this help + @echo make TARGET=stm32nucleo-spirit1 savetarget - stores selection of target to avoid using TARGET= on every make invokation + @echo make program.upload - compiles and uploads program to connected board + @echo make program.upload IAR=1 - uses the IAR compiler instead of gcc (not implemented yet) + @echo make program.upload NODEID=x - uploads with node_id set to x + +# Serialdump rules +ifeq ($(HOST_OS),Windows) + SERIALDUMP = serialdump-windows + # this ID is a string with which the node identifies itself as, and is used to + # find the proper /dev/comX-port in Cygwin to connect to. + CYGWIN_DEV_ID="stm32nucleo-spirit1 Spirit1 Platform" +# include $(CONTIKI)/tools/cygwin/Makefile.cygwin +endif +ifeq ($(HOST_OS),Darwin) + SERIALDUMP = serialdump-macos +endif +ifndef SERIALDUMP + # Assume Linux + SERIALDUMP = serialdump-linux +endif + +# IAR/windows/cygwin only for now; after GCC port, see if stm32flash works with Linux +STLINKCLI=ST-LINK_CLI.exe +%.upload: %.hex + #Note: this command only uploads to a single connected device + #$(STLINKCLI) -ME || $(STLINKCLI) -ME || $(STLINKCLI) -ME || $(STLINKCLI) -ME + $(STLINKCLI) -Q -P $*.hex -V -Run + + +# devcon requires WinDriverKit, downloadable from microsoft.com +DEVCON=devcon.exe +DEVCON_ALLDEVS=$(shell $(DEVCON) find =USB | grep "STMicroelectronics STLink dongle" | cut -d " " -f 1) +devcon_enableonly: + devcon disable =USB @"USB\VID_0483&PID_3748\*" + devcon enable =USB @"$(ID)" + +%.uploadall: %.hex + $(foreach D,$(DEVCON_ALLDEVS), echo D IS "$(D)" && make devcon_enableonly ID="$(D)" && make $*.upload && ) echo "Done" + devcon enable =USB @"USB\VID_0483&PID_3748\*" + +login: + @echo "Connecting to $(COMPORT)" + $(CONTIKI)/tools/sky/$(SERIALDUMP) -b115200 $(COMPORT) + +%.ramusage: %.$(TARGET) + $(NM) -S $< --size-sort --line-numbers | grep -v " T " | grep -v " t " +%.romusage: %.$(TARGET) + $(NM) -S $< --size-sort --line-numbers | grep -v " b " | grep -v " B " | grep -v " d " | grep -v " D " + + + + diff --git a/platform/stm32nucleo-spirit1/README.md b/platform/stm32nucleo-spirit1/README.md new file mode 100644 index 000000000..dcb29caf4 --- /dev/null +++ b/platform/stm32nucleo-spirit1/README.md @@ -0,0 +1,158 @@ +Getting Started with Contiki for STM32 Nucleo equipped with sub-1GHz SPIRIT1 expansion boards +============================================================================================= + +This guide explains how to get started with the STM32 Nucleo and expansion boards port to Contiki. + +Maintainers and Contacts +======================== + +Long-term maintainers: +* Marco Grella, marco.grella@st.com, github user: [mgrella](https://github.com/mgrella) +* Alok Mittal, alok.mittal@st.com, github user: [alokclab](https://github.com/alokclab) +* Indar Prakash Singhal, indar.singhal@st.com, github user: [indars](https://github.com/indars) + +Contributors: +* David Siorpaes, david.siorpaes@st.com, github user: [siorpaes](https://github.com/siorpaes) +* Luca Celetto, luca.celetto@st.com, github user: [luckyluke72](https://github.com/luckyluke72) + +Port Feature +============ + +The port supports the following boards from ST: +- NUCLEO-L152RE board, based on the STM32L152RET6 ultra-low power microcontroller +- X-NUCLEO-IDS01A4 based on sub-1GHz SPSGRF-868 SPIRIT1 module (operating at 868 MHz) +- X-NUCLEO-IDS01A5 based on sub-1GHz SPSGRF-915 SPIRIT1 module (operating at 915 MHz) +- X-NUCLEO-IKS01A1 featuring motion MEMS and environmental sensors (optional) + +The following drivers are included: +- LEDs and user button +- USB +- SPIRIT1 sub-1GHz transceiver +- HTS221, LIS3MDL, LPS25HB, LSM6DS0 sensors + +Documentation +============= + +- User Manual: UM2000 "Getting started with the Contiki OS/6LoWPAN on STM32 Nucleo with SPIRIT1 and sensors expansion boards" +- Quick Start Guide (presentation): "Contiki 6LoWPAN Quick Guide" + +To access this documentation and other collaterals, please go to http://www.st.com and search for "STSW-CONTIKI6LP" part number. + +Hardware Requirements +===================== + +* NUCLEO-L152RE development board + + >The NUCLEO-L152RE board belongs to the STM32 Nucleo family. +It features an STM32L152RET6 ultra-low power microcontroller based on ARM Cortex M3 MCU. +For detailed information on the NUCLEO-L152RE development board, please go to http://www.st.com and search for the "NUCLEO-L152RE" part number. + + +* X-NUCLEO-IDS01Ax sub-1GHz expansion board + + >The X-NUCLEO-IDS01A4 and X-NUCLEO-IDS01A5 are STM32 Nucleo expansion boards that use +the module SPSGRF-868 or SPSGRF-915 based on SPIRIT1 low data rate, low power sub-1 GHz transceiver. + + >The user can select the X-NUCLEO-IDS01A4 board to operate the SPIRIT1 transceiver at 868MHz or the X-NUCLEO-IDS01A5 board to operate the SPIRIT1 transceiver at 915MHz. + +>For detailed information on the X-NUCLEO-IDS01A4 or X-NUCLEO-IDS01A5 expansion board, or the SPIRIT1 transceiver please go to http://www.st.com and search for the specific part number. + + +* X-NUCLEO-IKS01A1, motion MEMS and environmental sensors expansion board (OPTIONAL) + + >The X-NUCLEO-IKS01A1 is a motion MEMS and environmental sensor evaluation board. +The use of this board is optional in the stm32nucleo-spirit1 Contiki platform. + + >For detailed information on the X-NUCLEO-IKS01A1 expansion board, please go to http://www.st.com and search for the "X-NUCLEO-IKS01A1" part number. + + +* USB type A to Mini-B USB cable, to connect the STM32 Nucleo board to the PC + +Software Requirements +===================== + +The following software are needed: + +* ST port of Contiki for STM32 Nucleo and expansion boards. + + >The port is automatically installed when both the Contiki and the submodule repository are cloned: the former hosts the Contiki distribution and the ST platform interface, the latter hosts the actual library. The following command downloads the full porting: + + git clone --recursive https://github.com/contiki-os/contiki + +Alternatively, if you cloned the contiki repository without the "--recursive" option, you can simply download the submodule repository with the following commands: + + cd contiki/ + git submodule init + git submodule update + +The platform name is: stm32nucleo-spirit1 + +* A toolchain to build the firmware: The port has been developed and tested with GNU Tools +for ARM Embedded Processors. + >The toolchain can be found at: https://launchpad.net/gcc-arm-embedded +The port was developed and tested using this version: gcc-arm-none-eabi v4.8.3 + + +Examples +======== + +The following examples have been successfully tested: + +* examples/stm32nucleo-spirit1/sensor-demo +* examples/ipv6/simple-udp-rpl (multicast, rpl-border-router, simple-udp-rpl) + + +Build an example +================ +In order to build an example go to the selected example directory (see a list of tested +examples in the previous section). + +For example, go to examples/ipv6/simple-udp-rpl directory. + + +If the X-NUCLEO-IDS01A4 sub-1GHz RF expansion board is used, the following must be run: + + make TARGET=stm32nucleo-spirit1 BOARD=ids01a4 clean + make TARGET=stm32nucleo-spirit1 BOARD=ids01a4 + +If the X-NUCLEO-IDS01A5 sub-1GHz RF expansion board is used, the following must be run: + + make TARGET=stm32nucleo-spirit1 BOARD=ids01a5 clean + make TARGET=stm32nucleo-spirit1 BOARD=ids01a5 + + +This will create executables for UDP sender and receiver nodes. + +In order to generate binary files that can be flashed on the STM32 Nucleo the following command must be run: + + arm-none-eabi-objcopy -O binary unicast-sender.stm32nucleo-spirit1 unicast-sender.bin + arm-none-eabi-objcopy -O binary unicast-receiver.stm32nucleo-spirit1 unicast-receiver.bin + +These executables can be programmed on the nodes using the procedure described hereafter. + + +In case you need to build an example that uses the additional sensors expansion board +(for example, considering a system made of NUCLEO-L152RE, X-NUCLEO-IDS01A4 and X-NUCLEO-IKS01A1) +then the command to be run would be: + + make TARGET=stm32nucleo-spirit1 BOARD=ids01a4 SENSORBOARD=iks01a1 + +System setup +============ + +1. Check that the jumper on the J1 connector on the X-NUCLEO-IDS01Ax expansion board is connected. +This jumper provides the required voltage to the devices on the board. + +2. Connect the X-NUCLEO-IDS01Ax board to the STM32 Nucleo board (NUCLEO-L152RE) from the top. + +3. If the optional X-NUCLEO-IKS01A1 board is used, connect it on top of the X-NUCLEO-IDS01Ax board. + +4. Power the STM32 Nucleo board using the Mini-B USB cable connected to the PC. + +5. Program the firmware on the STM32 Nucleo board. +This can be done by copying the binary file on the USB mass storage that is +automatically created when plugging the STM32 Nucleo board to the PC. + +6. Reset the MCU by using the reset button on the STM32 Nucleo board + + diff --git a/platform/stm32nucleo-spirit1/contiki-conf.h b/platform/stm32nucleo-spirit1/contiki-conf.h new file mode 100644 index 000000000..9a97ab355 --- /dev/null +++ b/platform/stm32nucleo-spirit1/contiki-conf.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +#ifndef __CONTIKI_CONF_H__ +#define __CONTIKI_CONF_H__ +/*---------------------------------------------------------------------------*/ +#include "platform-conf.h" +/*---------------------------------------------------------------------------*/ +#define SLIP_BRIDGE_CONF_NO_PUTCHAR 1 + +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 +#define NULLRDC_CONF_802154_AUTOACK 0 +#define NETSTACK_CONF_FRAMER framer_802154 +#define NETSTACK_CONF_NETWORK sicslowpan_driver + +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_RDC_HEADER_LEN 0 + +#undef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC csma_driver +#define NETSTACK_MAC_HEADER_LEN 0 + +#define SICSLOWPAN_CONF_MAC_MAX_PAYLOAD \ + (NETSTACK_RADIO_MAX_PAYLOAD_LEN - NETSTACK_MAC_HEADER_LEN - \ + NETSTACK_RDC_HEADER_LEN) + +#define RIMESTATS_CONF_ENABLED 0 +#define RIMESTATS_CONF_ON 0 + +/* Network setup for IPv6 */ +#define CXMAC_CONF_ANNOUNCEMENTS 0 + +/* A trick to resolve a compilation error with IAR. */ +#ifdef __ICCARM__ +#define UIP_CONF_DS6_AADDR_NBU 1 +#endif + +/* radio driver blocks until ACK is received */ +#define NULLRDC_CONF_ACK_WAIT_TIME (0) +#define CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT 0 +#define IEEE802154_CONF_PANID 0xABCD + +#define AODV_COMPLIANCE + +#define WITH_ASCII 1 + +#define PROCESS_CONF_NUMEVENTS 8 +#define PROCESS_CONF_STATS 1 +/*#define PROCESS_CONF_FASTPOLL 4*/ + +#define LINKADDR_CONF_SIZE 8 + +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 + +#define UIP_CONF_ROUTER 1 + +/* configure number of neighbors and routes */ +#ifndef UIP_CONF_DS6_ROUTE_NBU +#define UIP_CONF_DS6_ROUTE_NBU 30 +#endif /* UIP_CONF_DS6_ROUTE_NBU */ + +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_ND6_REACHABLE_TIME 600000 /* 90000// 600000 */ +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +#define UIP_CONF_IPV6 1 +#ifndef UIP_CONF_IPV6_QUEUE_PKT +#define UIP_CONF_IPV6_QUEUE_PKT 0 +#endif /* UIP_CONF_IPV6_QUEUE_PKT */ +#define UIP_CONF_IP_FORWARD 0 +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 280 +/* #define UIP_CONF_BUFFER_SIZE 600 */ +#endif + +#define SICSLOWPAN_CONF_MAXAGE 4 +#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 + +#define UIP_CONF_ICMP_DEST_UNREACH 1 + +#define UIP_CONF_DHCP_LIGHT +#define UIP_CONF_LLH_LEN 0 +#ifndef UIP_CONF_RECEIVE_WINDOW +#define UIP_CONF_RECEIVE_WINDOW 150 +#endif +#ifndef UIP_CONF_TCP_MSS +#define UIP_CONF_TCP_MSS UIP_CONF_RECEIVE_WINDOW +#endif +#define UIP_CONF_MAX_CONNECTIONS 4 +#define UIP_CONF_MAX_LISTENPORTS 8 +#define UIP_CONF_UDP_CONNS 12 +#define UIP_CONF_FWCACHE_SIZE 30 +#define UIP_CONF_BROADCAST 1 +#define UIP_ARCH_IPCHKSUM 0 +#define UIP_CONF_UDP 1 +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_TCP 1 +/*---------------------------------------------------------------------------*/ +/* include the project config */ +/* PROJECT_CONF_H might be defined in the project Makefile */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif /* PROJECT_CONF_H */ +/*---------------------------------------------------------------------------*/ +#endif /* CONTIKI_CONF_H */ +/*---------------------------------------------------------------------------*/ diff --git a/platform/stm32nucleo-spirit1/contiki-spirit1-main.c b/platform/stm32nucleo-spirit1/contiki-spirit1-main.c new file mode 100644 index 000000000..5d5e5413e --- /dev/null +++ b/platform/stm32nucleo-spirit1/contiki-spirit1-main.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1 + * @{ + * + * \file + * main file for stm32nucleo-spirit1 platform + */ +/*---------------------------------------------------------------------------*/ +#include +#include +#include "stm32cube_hal_init.h" +#include "contiki.h" +#include "contiki-net.h" +#include "sys/autostart.h" +#include "dev/leds.h" +#include "dev/serial-line.h" +#include "dev/slip.h" +#include "dev/watchdog.h" +#include "dev/xmem.h" +#include "lib/random.h" +#include "net/netstack.h" +#include "net/ip/uip.h" +#include "net/mac/frame802154.h" +#include "net/rime/rime.h" +#include "stm32l1xx.h" +#include "SPIRIT_Config.h" +#include "SPIRIT_Management.h" +#include "spirit1.h" +#include "spirit1-arch.h" +#include "node-id.h" +#include "hw-config.h" +#include "stdbool.h" +#include "dev/button-sensor.h" +#include "dev/radio-sensor.h" +/*---------------------------------------------------------------------------*/ +#if NETSTACK_CONF_WITH_IPV6 +#include "net/ipv6/uip-ds6.h" +#endif /*NETSTACK_CONF_WITH_IPV6*/ +/*---------------------------------------------------------------------------*/ +#ifdef X_NUCLEO_IKS01A1 +extern const struct sensors_sensor temperature_sensor; +extern const struct sensors_sensor humidity_sensor; +extern const struct sensors_sensor pressure_sensor; +extern const struct sensors_sensor magneto_sensor; +extern const struct sensors_sensor acceleration_sensor; +extern const struct sensors_sensor gyroscope_sensor; +SENSORS(&button_sensor, + &radio_sensor, + &temperature_sensor, + &humidity_sensor, + &pressure_sensor, + &magneto_sensor, + &acceleration_sensor, + &gyroscope_sensor); +#else /*X_NUCLEO_IKS01A1*/ +SENSORS(&button_sensor, + &radio_sensor); +#endif /*X_NUCLEO_IKS01A1*/ +/*---------------------------------------------------------------------------*/ +extern unsigned char node_mac[8]; +/*---------------------------------------------------------------------------*/ +#ifdef __GNUC__ +/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf + set to 'Yes') calls __io_putchar() */ +#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) +#else +#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE * f) +#endif /* __GNUC__ */ +/*---------------------------------------------------------------------------*/ +#if NETSTACK_CONF_WITH_IPV6 +PROCINIT(&etimer_process, &tcpip_process); +#else /*NETSTACK_CONF_WITH_IPV6*/ +PROCINIT(&etimer_process); +#warning "No TCP/IP process!" +#endif /*NETSTACK_CONF_WITH_IPV6*/ +/*---------------------------------------------------------------------------*/ +#define BUSYWAIT_UNTIL(cond, max_time) \ + do { \ + rtimer_clock_t t0; \ + t0 = RTIMER_NOW(); \ + while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))) ; \ + } while(0) +/*---------------------------------------------------------------------------*/ +static void set_rime_addr(void); +void stm32cube_hal_init(); +/*---------------------------------------------------------------------------*/ +#if 0 +static void +panic_main(void) +{ + volatile uint16_t k; + while(1) { + leds_toggle(LEDS_ALL); + for(k = 0; k < 0xffff / 8; k += 1) { + } + } +} +#endif +/*---------------------------------------------------------------------------*/ +int +main(int argc, char *argv[]) +{ + stm32cube_hal_init(); + + /* init LEDs */ + leds_init(); + + /* Initialize Contiki and our processes. */ + clock_init(); + ctimer_init(); + rtimer_init(); + watchdog_init(); + process_init(); + process_start(&etimer_process, NULL); + + /* Restore node id if such has been stored in external mem */ + node_id_restore(); /* also configures node_mac[] */ + + set_rime_addr(); + random_init(node_id); + + netstack_init(); + spirit_radio_driver.on(); + + energest_init(); + +#if NETSTACK_CONF_WITH_IPV6 + memcpy(&uip_lladdr.addr, node_mac, sizeof(uip_lladdr.addr)); + + queuebuf_init(); + process_start(&tcpip_process, NULL); + + uip_ipaddr_t ipaddr; + uip_ip6addr(&ipaddr, 0xfc00, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); + uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); +#endif /* NETSTACK_CONF_WITH_IPV6*/ + + process_start(&sensors_process, NULL); + + autostart_start(autostart_processes); + + watchdog_start(); + + while(1) { + int r = 0; + do { + r = process_run(); + } while(r > 0); + } +} +/*---------------------------------------------------------------------------*/ +static void +set_rime_addr(void) +{ + linkaddr_t addr; + + memset(&addr, 0, sizeof(linkaddr_t)); + memcpy(addr.u8, node_mac, sizeof(addr.u8)); + + linkaddr_set_node_addr(&addr); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/stm32nucleo-spirit1/dev/acceleration-sensor.c b/platform/stm32nucleo-spirit1/dev/acceleration-sensor.c new file mode 100644 index 000000000..104cfe8b8 --- /dev/null +++ b/platform/stm32nucleo-spirit1/dev/acceleration-sensor.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1-temperature-sensor + * @{ + * + * \file + * Driver for the stm32nucleo-spirit1 Temperature sensor (on expansion board) + */ +/*---------------------------------------------------------------------------*/ +#ifdef X_NUCLEO_IKS01A1 +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "acceleration-sensor.h" +#include "st-lib.h" +/*---------------------------------------------------------------------------*/ +static int _active = 1; +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + /*Acceleration and Gyroscope sensors share the same hw*/ + if(!st_lib_bsp_imu_6axes_is_initialized()) { + if(IMU_6AXES_OK == st_lib_bsp_imu_6axes_init()) { + _active = 1; + } + } +} +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ + _active = 1; +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ + _active = 0; +} +/*---------------------------------------------------------------------------*/ +static int +active(void) +{ + return _active; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + int32_t ret_val = 0; + volatile st_lib_axes_raw_typedef axes_raw_data; + + /* NOTE: this is a demo of mapping ST Nucleo sensors on Contiki sensor API. + * For a real use case of sensors like acceleration, magneto and gyroscope, + * it is better to directly call the ST lib to get the three value (X/Y/Z) + * at once. + */ + st_lib_bsp_imu_6axes_x_get_axes_raw(&axes_raw_data); + + switch(type) { + case X_AXIS: + ret_val = axes_raw_data.AXIS_X; + break; + case Y_AXIS: + ret_val = axes_raw_data.AXIS_Y; + break; + case Z_AXIS: + ret_val = axes_raw_data.AXIS_Z; + break; + default: + break; + } + + return ret_val; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: + init(); + return 1; + case SENSORS_ACTIVE: + if(value) { + activate(); + } else { + deactivate(); + } + return 1; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_READY: + return active(); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(acceleration_sensor, ACCELERATION_SENSOR, + value, configure, status); +/*---------------------------------------------------------------------------*/ +#endif /*X_NUCLEO_IKS01A1*/ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/stm32nucleo-spirit1/dev/acceleration-sensor.h b/platform/stm32nucleo-spirit1/dev/acceleration-sensor.h new file mode 100644 index 000000000..32b168f9f --- /dev/null +++ b/platform/stm32nucleo-spirit1/dev/acceleration-sensor.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1-peripherals + * @{ + * + * \defgroup stm32nucleo-spirit1-acceleration-sensor Acceleration Sensor + * + * Maps the acceleration sensor on the STM32 Nucleo Sensor Expansion board. + * @{ + * + * \file + * Header file for the stm32nucleo-spirit1 Acceleration Sensor Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef ACCELERATION_SENSOR_H_ +#define ACCELERATION_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "sensor-common.h" +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor acceleration_sensor; +/*---------------------------------------------------------------------------*/ +#define ACCELERATION_SENSOR "Acceleration" +/*---------------------------------------------------------------------------*/ +#endif /* ACCELERATION_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/stm32nucleo-spirit1/dev/button-sensor.c b/platform/stm32nucleo-spirit1/dev/button-sensor.c new file mode 100644 index 000000000..58e6c6a41 --- /dev/null +++ b/platform/stm32nucleo-spirit1/dev/button-sensor.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1-peripherals + * @{ + * + * \file + * Driver for the stm32nucleo-spirit1 User Button + */ +/*---------------------------------------------------------------------------*/ +#include "dev/button-sensor.h" +#include "lib/sensors.h" +#include "st-lib.h" +/*---------------------------------------------------------------------------*/ +static int _active = 0; +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + /* See spirit1_appli.c for the Callback: it triggers the relevant + * sensors_changed event + */ + st_lib_bsp_pb_init(BUTTON_USER, BUTTON_MODE_EXTI); +} +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ + _active = 1; +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ + _active = 0; +} +/*---------------------------------------------------------------------------*/ +static int +active(void) +{ + return active; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return st_lib_bsp_pb_get_state(BUTTON_USER); +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: + init(); + return 1; + case SENSORS_ACTIVE: + if(value) { + activate(); + } else { + deactivate(); + } + return 1; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_READY: + return active(); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/stm32nucleo-spirit1/dev/gyroscope-sensor.c b/platform/stm32nucleo-spirit1/dev/gyroscope-sensor.c new file mode 100644 index 000000000..cfa699827 --- /dev/null +++ b/platform/stm32nucleo-spirit1/dev/gyroscope-sensor.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1-gyroscope-sensor + * @{ + * + * \file + * Driver for the stm32nucleo-spirit1 Gyroscope sensor (on expansion board) + */ +/*---------------------------------------------------------------------------*/ +#ifdef X_NUCLEO_IKS01A1 +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "gyroscope-sensor.h" +#include "st-lib.h" +/*---------------------------------------------------------------------------*/ +static int _active = 1; +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + /*Acceleration and Gyroscope sensors share the same hw*/ + if(!st_lib_bsp_imu_6axes_is_initialized()) { + if(IMU_6AXES_OK == st_lib_bsp_imu_6axes_init()) { + _active = 1; + } + } +} +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ + _active = 1; +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ + _active = 0; +} +/*---------------------------------------------------------------------------*/ +static int +active(void) +{ + return _active; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + int32_t ret_val = 0; + volatile st_lib_axes_raw_typedef axes_raw_data; + + /* NOTE: this is a demo of mapping ST Nucleo sensors on Contiki sensor API. + * For a real use case of sensors like acceleration, magneto and gyroscope, + * it is better to directly call the ST lib to get the three value (X/Y/Z) + * at once. + */ + st_lib_bsp_imu_6axes_g_get_axes_raw(&axes_raw_data); + + switch(type) { + case X_AXIS: + ret_val = axes_raw_data.AXIS_X; + break; + case Y_AXIS: + ret_val = axes_raw_data.AXIS_Y; + break; + case Z_AXIS: + ret_val = axes_raw_data.AXIS_Z; + break; + default: + break; + } + + return ret_val; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: + init(); + return 1; + case SENSORS_ACTIVE: + if(value) { + activate(); + } else { + deactivate(); + } + return 1; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_READY: + return active(); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(gyroscope_sensor, GYROSCOPE_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +#endif /*X_NUCLEO_IKS01A1*/ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/stm32nucleo-spirit1/dev/gyroscope-sensor.h b/platform/stm32nucleo-spirit1/dev/gyroscope-sensor.h new file mode 100644 index 000000000..1db7ad764 --- /dev/null +++ b/platform/stm32nucleo-spirit1/dev/gyroscope-sensor.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1-peripherals + * @{ + * + * \defgroup stm32nucleo-spirit1-gyroscope-sensor Gyroscope Sensor + * + * Maps the gyroscope sensor on the STM32 Sensor Expansion board. + * @{ + * + * \file + * Header file for the stm32nucleo-spirit1 Gyroscope Sensor Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef GYROSCOPE_SENSOR_H_ +#define GYROSCOPE_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "sensor-common.h" +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor gyroscope_sensor; +/*---------------------------------------------------------------------------*/ +#define GYROSCOPE_SENSOR "Gyroscope" +/*---------------------------------------------------------------------------*/ +#endif /* GYROSCOPE_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/stm32nucleo-spirit1/dev/humidity-sensor.c b/platform/stm32nucleo-spirit1/dev/humidity-sensor.c new file mode 100644 index 000000000..843b35a91 --- /dev/null +++ b/platform/stm32nucleo-spirit1/dev/humidity-sensor.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1-humidity-sensor + * @{ + * + * \file + * Driver for the stm32nucleo-spirit1 Humidity sensor (on expansion board) + */ +/*---------------------------------------------------------------------------*/ +#ifdef X_NUCLEO_IKS01A1 +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "humidity-sensor.h" +#include "st-lib.h" +/*---------------------------------------------------------------------------*/ +static int _active = 1; +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + /*Temperature and Humity sensors share the same hw*/ + if(!st_lib_bsp_hum_temp_is_initialized()) { + st_lib_bsp_hum_temp_init(); + _active = 1; + } +} +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ + _active = 1; +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ + _active = 0; +} +/*---------------------------------------------------------------------------*/ +static int +active(void) +{ + return _active; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + uint32_t humidity; + volatile float humidity_value; + + st_lib_bsp_hum_temp_get_humidity((float *)&humidity_value); + + humidity = humidity_value * 10; + return humidity; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: + init(); + return 1; + case SENSORS_ACTIVE: + if(value) { + activate(); + } else { + deactivate(); + } + return 1; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_READY: + return active(); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(humidity_sensor, HUMIDITY_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +#endif /*X_NUCLEO_IKS01A1*/ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/stm32nucleo-spirit1/dev/humidity-sensor.h b/platform/stm32nucleo-spirit1/dev/humidity-sensor.h new file mode 100644 index 000000000..49c8c0f69 --- /dev/null +++ b/platform/stm32nucleo-spirit1/dev/humidity-sensor.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1-peripherals + * @{ + * + * \defgroup stm32nucleo-spirit1-humidity-sensor Humidity Sensor + * + * Maps the humidity sensor on the STM32 Nucleo Sensor Expansion board. + * @{ + * + * \file + * Header file for the stm32nucleo-spirit1 Humidity Sensor Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef HUMIDITY_SENSOR_H_ +#define HUMIDITY_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor humidity_sensor; +/*---------------------------------------------------------------------------*/ +#define HUMIDITY_SENSOR "Humidity" +/*---------------------------------------------------------------------------*/ +#endif /* HUMIDITY_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/stm32nucleo-spirit1/dev/leds-arch.c b/platform/stm32nucleo-spirit1/dev/leds-arch.c new file mode 100644 index 000000000..7c9b198fe --- /dev/null +++ b/platform/stm32nucleo-spirit1/dev/leds-arch.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1-peripherals + * @{ + * + * \file + * Driver for the stm32nucleo-spirit1 LEDs + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "dev/leds.h" +#include "st-lib.h" +/*---------------------------------------------------------------------------*/ +#ifndef X_NUCLEO_IKS01A1 +/* The Red LED (on SPIRIT1 exp board) is exposed only if the + * X-NUCLEO-IKS01A1 sensor board is NOT used, becasue of a pin conflict. + */ +extern st_lib_gpio_typedef *st_lib_a_led_gpio_port[]; +extern const uint16_t st_lib_a_led_gpio_pin[]; +#endif /*X_NUCLEO_IKS01A1*/ + +extern st_lib_gpio_typedef *st_lib_gpio_port[]; +extern const uint16_t st_lib_gpio_pin[]; +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + /* We have at least one led, the one on the Nucleo (GREEN)*/ + st_lib_bsp_led_init(LED2); + st_lib_bsp_led_off(LED2); + +#ifndef X_NUCLEO_IKS01A1 +/* The Red LED (on SPIRIT1 exp board) is exposed only if the + * X-NUCLEO-IKS01A1 sensor board is NOT used, becasue of a pin conflict. + */ + st_lib_radio_shield_led_init(RADIO_SHIELD_LED); + st_lib_radio_shield_led_off(RADIO_SHIELD_LED); +#endif /*X_NUCLEO_IKS01A1*/ +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + unsigned char ret = 0; + if(st_lib_hal_gpio_read_pin(st_lib_gpio_port[LED2], st_lib_gpio_pin[LED2])) { + ret |= LEDS_GREEN; + } + +#ifndef X_NUCLEO_IKS01A1 +/* The Red LED (on SPIRIT1 exp board) is exposed only if the + * X-NUCLEO-IKS01A1 sensor board is NOT used, becasue of a pin conflict. + */ + if(st_lib_hal_gpio_read_pin(st_lib_a_led_gpio_port[RADIO_SHIELD_LED], + st_lib_a_led_gpio_pin[RADIO_SHIELD_LED])) { + ret |= LEDS_RED; + } +#endif /*X_NUCLEO_IKS01A1*/ + + return ret; +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char leds) +{ + if(leds & LEDS_GREEN) { + st_lib_bsp_led_on(LED2); + } else { + st_lib_bsp_led_off(LED2); + } + +#ifndef X_NUCLEO_IKS01A1 +/* The Red LED (on SPIRIT1 exp board) is exposed only if the + * X-NUCLEO-IKS01A1 sensor board is NOT used, becasue of a pin conflict. + */ + if(leds & LEDS_RED) { + st_lib_radio_shield_led_on(RADIO_SHIELD_LED); + } else { + st_lib_radio_shield_led_off(RADIO_SHIELD_LED); + } +#endif /*X_NUCLEO_IKS01A1*/ +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/stm32nucleo-spirit1/dev/magneto-sensor.c b/platform/stm32nucleo-spirit1/dev/magneto-sensor.c new file mode 100644 index 000000000..753bfba33 --- /dev/null +++ b/platform/stm32nucleo-spirit1/dev/magneto-sensor.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1-magneto-sensor + * @{ + * + * \file + * Driver for the stm32nucleo-spirit1 Magneto sensor (on expansion board) + */ +/*---------------------------------------------------------------------------*/ +#ifdef X_NUCLEO_IKS01A1 +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "magneto-sensor.h" +#include "st-lib.h" +/*---------------------------------------------------------------------------*/ +static int _active = 1; +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + BSP_MAGNETO_Init(); + _active = 1; +} +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ + _active = 1; +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ + _active = 0; +} +/*---------------------------------------------------------------------------*/ +static int +active(void) +{ + return _active; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + int32_t ret_val = 0; + volatile st_lib_axes_raw_typedef axes_raw_data; + + /* NOTE: this is a demo of mapping ST Nucleo sensors on Contiki sensor API. + * For a real use case of sensors like acceleration, magneto and gyroscope, + * it is better to directly call the ST lib to get the three value (X/Y/Z) + * at once. + */ + st_lib_bsp_magneto_m_get_axes_raw(&axes_raw_data); + + switch(type) { + case X_AXIS: + ret_val = axes_raw_data.AXIS_X; + break; + case Y_AXIS: + ret_val = axes_raw_data.AXIS_Y; + break; + case Z_AXIS: + ret_val = axes_raw_data.AXIS_Z; + break; + default: + break; + } + + return ret_val; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: + init(); + return 1; + case SENSORS_ACTIVE: + if(value) { + activate(); + } else { + deactivate(); + } + return 1; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_READY: + return active(); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(magneto_sensor, MAGNETO_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +#endif /*X_NUCLEO_IKS01A1*/ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/stm32nucleo-spirit1/dev/magneto-sensor.h b/platform/stm32nucleo-spirit1/dev/magneto-sensor.h new file mode 100644 index 000000000..50376d488 --- /dev/null +++ b/platform/stm32nucleo-spirit1/dev/magneto-sensor.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1-peripherals + * @{ + * + * \defgroup stm32nucleo-spirit1-magneto-sensor Magneto Sensor + * + * Maps the magneto sensor on the STM32 Nucleo Sensor Expansion board. + * @{ + * + * \file + * Header file for the stm32nucleo-spirit1 Magneto Sensor Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef MAGNETO_SENSOR_H_ +#define MAGNETO_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "sensor-common.h" +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor magneto_sensor; +/*---------------------------------------------------------------------------*/ +#define MAGNETO_SENSOR "Magneto" +/*---------------------------------------------------------------------------*/ +#endif /* MAGNETO_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/stm32nucleo-spirit1/dev/pressure-sensor.c b/platform/stm32nucleo-spirit1/dev/pressure-sensor.c new file mode 100644 index 000000000..a7cce6621 --- /dev/null +++ b/platform/stm32nucleo-spirit1/dev/pressure-sensor.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1-pressure-sensor + * @{ + * + * \file + * Driver for the stm32nucleo-spirit1 Pressure sensor (on expansion board) + */ +/*---------------------------------------------------------------------------*/ +#ifdef X_NUCLEO_IKS01A1 +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "pressure-sensor.h" +#include "st-lib.h" +/*---------------------------------------------------------------------------*/ +static int _active = 1; +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + st_lib_bsp_pressure_init(); + _active = 1; +} +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ + _active = 1; +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ + _active = 0; +} +/*---------------------------------------------------------------------------*/ +static int +active(void) +{ + return _active; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + uint16_t pressure; + volatile float pressure_value; + + st_lib_bsp_pressure_get_pressure((float *)&pressure_value); + pressure = pressure_value * 10; + + return pressure; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: + init(); + return 1; + case SENSORS_ACTIVE: + if(value) { + activate(); + } else { + deactivate(); + } + return 1; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_READY: + return active(); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(pressure_sensor, PRESSURE_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +#endif /*X_NUCLEO_IKS01A1*/ +/** @} */ diff --git a/platform/stm32nucleo-spirit1/dev/pressure-sensor.h b/platform/stm32nucleo-spirit1/dev/pressure-sensor.h new file mode 100644 index 000000000..79d9b9402 --- /dev/null +++ b/platform/stm32nucleo-spirit1/dev/pressure-sensor.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1-peripherals + * @{ + * + * \defgroup stm32nucleo-spirit1-pressure-sensor Pressure Sensor + * + * Maps the pressure sensor on the STM32 Nucleo Sensor Expansion board. + * @{ + * + * \file + * Header file for the stm32nucleo-spirit1 Pressure Sensor Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef PRESSURE_SENSOR_H_ +#define PRESSURE_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor pressure_sensor; +/*---------------------------------------------------------------------------*/ +#define PRESSURE_SENSOR "Pressure" +/*---------------------------------------------------------------------------*/ +#endif /* PRESSURE_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/stm32nucleo-spirit1/dev/radio-sensor.c b/platform/stm32nucleo-spirit1/dev/radio-sensor.c new file mode 100644 index 000000000..4413c0498 --- /dev/null +++ b/platform/stm32nucleo-spirit1/dev/radio-sensor.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1-peripherals + * @{ + * + * \file + * Driver for the stm32nucleo-spirit1 Radio Sensor (RSSI, LQI, ...) + */ +/*---------------------------------------------------------------------------*/ +#include "dev/radio-sensor.h" +#include "dev/sensor-common.h" +#include "lib/sensors.h" +#include "net/packetbuf.h" +#include "st-lib.h" +/*---------------------------------------------------------------------------*/ +static int _active; +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + /*Nothing to do at the moment, can be used in the future.*/ +} +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ + _active = 1; +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ + _active = 0; +} +/*---------------------------------------------------------------------------*/ +static int +active(void) +{ + return _active; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + int32_t radio_sensor; + float radio_sensor_value; + + switch(type) { + case RADIO_SENSOR_LAST_PACKET: + /*TODO: check which method of getting these value is more appropriate */ + radio_sensor_value = DBM_VALUE(packetbuf_attr(PACKETBUF_ATTR_RSSI)); + /* radio_sensor_value = st_lib_spirit_qi_get_rssi_dbm(); */ + radio_sensor = (int32_t)(radio_sensor_value * 10); + break; + case RADIO_SENSOR_LAST_VALUE: + default: + /*TODO: check which method of getting these value is more appropriate */ + radio_sensor = packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY); + /* radio_sensor = (int32_t) st_lib_spirit_qi_get_lqi(); */ + } + + return radio_sensor; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: + init(); + return 1; + case SENSORS_ACTIVE: + if(value) { + activate(); + } else { + deactivate(); + } + return 1; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_READY: + return active(); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(radio_sensor, RADIO_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ + diff --git a/platform/stm32nucleo-spirit1/dev/sensor-common.h b/platform/stm32nucleo-spirit1/dev/sensor-common.h new file mode 100644 index 000000000..c4672a4d3 --- /dev/null +++ b/platform/stm32nucleo-spirit1/dev/sensor-common.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1-peripherals + * @{ + * + * + * \file + * Header file for common sensor definitions. + */ +/*---------------------------------------------------------------------------*/ +#ifndef SENSOR_COMMON_H_ +#define SENSOR_COMMON_H_ +/*---------------------------------------------------------------------------*/ +#define X_AXIS 0x00 +#define Y_AXIS 0x01 +#define Z_AXIS 0x02 + +#define ABS_VALUE(x) (((x) > 0) ? (x) : (-(x))) +#define DBM_VALUE(x) (-120.0 + ((float)((x) - 20)) / 2) +/*---------------------------------------------------------------------------*/ +#endif /*SENSOR_COMMON_H_*/ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/stm32nucleo-spirit1/dev/temperature-sensor.c b/platform/stm32nucleo-spirit1/dev/temperature-sensor.c new file mode 100644 index 000000000..87a75b983 --- /dev/null +++ b/platform/stm32nucleo-spirit1/dev/temperature-sensor.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1-temperature-sensor + * @{ + * + * \file + * Driver for the stm32nucleo-spirit1 Temperature sensor (on expansion board) + */ +/*---------------------------------------------------------------------------*/ +#ifdef X_NUCLEO_IKS01A1 +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "temperature-sensor.h" +#include "st-lib.h" +/*---------------------------------------------------------------------------*/ +static int _active = 0; +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + /*Temperature and Humity sensors share the same hw*/ + if(!st_lib_bsp_hum_temp_is_initialized()) { + st_lib_bsp_hum_temp_init(); + _active = 1; + } +} +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ + _active = 1; +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ + _active = 0; +} +/*---------------------------------------------------------------------------*/ +static int +active(void) +{ + return _active; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + int32_t temperature; + volatile float temperature_value; + + st_lib_bsp_hum_temp_get_temperature((float *)&temperature_value); + temperature = temperature_value * 10; + return temperature; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: + init(); + return 1; + case SENSORS_ACTIVE: + if(value) { + activate(); + } else { + deactivate(); + } + return 1; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_READY: + return active(); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(temperature_sensor, TEMPERATURE_SENSOR, + value, configure, status); +#endif /*X_NUCLEO_IKS01A1*/ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/stm32nucleo-spirit1/dev/temperature-sensor.h b/platform/stm32nucleo-spirit1/dev/temperature-sensor.h new file mode 100644 index 000000000..ca453b9b0 --- /dev/null +++ b/platform/stm32nucleo-spirit1/dev/temperature-sensor.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1-peripherals + * @{ + * + * \defgroup stm32nucleo-spirit1-temperature-sensor Temperature Sensor + * + * Maps the temperature sensor on the STM32 Nucleo Sensor Expansion board. + * @{ + * + * \file + * Header file for the stm32nucleo-spirit1 Temperature Sensor Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef TEMPERATURE_SENSOR_H_ +#define TEMPERATURE_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor temperature_sensor; +/*---------------------------------------------------------------------------*/ +#define TEMPERATURE_SENSOR "Temperature" +/*---------------------------------------------------------------------------*/ +#endif /* TEMPERATURE_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/stm32nucleo-spirit1/dev/uart1.h b/platform/stm32nucleo-spirit1/dev/uart1.h new file mode 100644 index 000000000..9706ab226 --- /dev/null +++ b/platform/stm32nucleo-spirit1/dev/uart1.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1-peripherals + * @{ + * + * + * \file + * Header file for UART related definitions. + */ +/*---------------------------------------------------------------------------*/ +#ifndef UART1_H_ +#define UART1_H_ +/*---------------------------------------------------------------------------*/ +#define BAUD2UBR(baud) baud +/*---------------------------------------------------------------------------*/ +#endif /* UART1_H_ */ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/stm32nucleo-spirit1/hw-config.h b/platform/stm32nucleo-spirit1/hw-config.h new file mode 100644 index 000000000..4a4554bd6 --- /dev/null +++ b/platform/stm32nucleo-spirit1/hw-config.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +#ifndef __HW_CONFIG_H +#define __HW_CONFIG_H +/*---------------------------------------------------------------------------*/ +#include "stm32l-spirit1-config.h" +/*---------------------------------------------------------------------------*/ +#define UART_RxBufferSize 512 +/*---------------------------------------------------------------------------*/ +#define I2Cx I2C1 +#define I2Cx_CLK_ENABLE() __I2C1_CLK_ENABLE() +#define I2Cx_SDA_GPIO_CLK_ENABLE() __GPIOB_CLK_ENABLE() +#define I2Cx_SCL_GPIO_CLK_ENABLE() __GPIOB_CLK_ENABLE() +/*---------------------------------------------------------------------------*/ +#define I2Cx_FORCE_RESET() __I2C1_FORCE_RESET() +#define I2Cx_RELEASE_RESET() __I2C1_RELEASE_RESET() +/*---------------------------------------------------------------------------*/ +/* Definition for I2Cx Pins */ +#define I2Cx_SCL_PIN GPIO_PIN_8 +#define I2Cx_SCL_GPIO_PORT GPIOB +#define I2Cx_SDA_PIN GPIO_PIN_9 +#define I2Cx_SDA_GPIO_PORT GPIOB +#define I2Cx_SCL_SDA_AF GPIO_AF4_I2C1 + +/* Definition for I2Cx's NVIC */ +#define I2Cx_EV_IRQn I2C1_EV_IRQn +#define I2Cx_ER_IRQn I2C1_ER_IRQn +#define I2Cx_EV_IRQHandler I2C1_EV_IRQHandler +#define I2Cx_ER_IRQHandler I2C1_ER_IRQHandler + +#define I2Cx I2C1 +#define I2Cx_CLK_ENABLE() __I2C1_CLK_ENABLE() +#define I2Cx_SDA_GPIO_CLK_ENABLE() __GPIOB_CLK_ENABLE() +#define I2Cx_SCL_GPIO_CLK_ENABLE() __GPIOB_CLK_ENABLE() + +#define I2Cx_FORCE_RESET() __I2C1_FORCE_RESET() +#define I2Cx_RELEASE_RESET() __I2C1_RELEASE_RESET() + +/* Definition for I2Cx Pins */ +#define I2Cx_SCL_PIN GPIO_PIN_8 +#define I2Cx_SCL_GPIO_PORT GPIOB +#define I2Cx_SDA_PIN GPIO_PIN_9 +#define I2Cx_SDA_GPIO_PORT GPIOB +#define I2Cx_SCL_SDA_AF GPIO_AF4_I2C1 + +/* Definition for I2Cx's NVIC */ +#define I2Cx_EV_IRQn I2C1_EV_IRQn +#define I2Cx_ER_IRQn I2C1_ER_IRQn +#define I2Cx_EV_IRQHandler I2C1_EV_IRQHandler +#define I2Cx_ER_IRQHandler I2C1_ER_IRQHandler + +/* User can use this section to tailor USARTx/UARTx instance used and associated + resources */ +/* Definition for USARTx clock resources */ +#define USARTx USART2 +#define USARTx_CLK_ENABLE() __USART2_CLK_ENABLE(); +#define DMAx_CLK_ENABLE() __DMA1_CLK_ENABLE() +#define USARTx_RX_GPIO_CLK_ENABLE() __GPIOA_CLK_ENABLE() +#define USARTx_TX_GPIO_CLK_ENABLE() __GPIOA_CLK_ENABLE() + +#define USARTx_FORCE_RESET() __USART2_FORCE_RESET() +#define USARTx_RELEASE_RESET() __USART2_RELEASE_RESET() + +/* Definition for USARTx Pins */ +#define USARTx_TX_PIN GPIO_PIN_2 +#define USARTx_TX_GPIO_PORT GPIOA + +#define USARTx_RX_PIN GPIO_PIN_3 +#define USARTx_RX_GPIO_PORT GPIOA + +/* Definition for USARTx's NVIC */ +#define USARTx_IRQn USART2_IRQn +#define USARTx_IRQHandler USART2_IRQHandler + +#define USARTx_TX_AF GPIO_AF7_USART2 +#define USARTx_RX_AF GPIO_AF7_USART2 + +/* Enable sensor mask */ +#define PRESSURE_SENSOR 0x00000001 +#define TEMPERATURE_SENSOR 0x00000002 +#define HUMIDITY_SENSOR 0x00000004 +#define UV_SENSOR 0x00000008 +#define ACCELEROMETER_SENSOR 0x00000010 +#define GYROSCOPE_SENSOR 0x00000020 +#define MAGNETIC_SENSOR 0x00000040 +/*---------------------------------------------------------------------------*/ +#endif /*__HW_CONFIG_H*/ +/*---------------------------------------------------------------------------*/ diff --git a/platform/stm32nucleo-spirit1/node-id.c b/platform/stm32nucleo-spirit1/node-id.c new file mode 100644 index 000000000..2c629354d --- /dev/null +++ b/platform/stm32nucleo-spirit1/node-id.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +#include "node-id.h" +#include "contiki-conf.h" +#include +/*---------------------------------------------------------------------------*/ +unsigned short node_id = 0; +unsigned char node_mac[8]; +volatile uint32_t device_id[3]; +/*---------------------------------------------------------------------------*/ +#define DEVICE_ID_REG0 (*((volatile uint32_t *)0x1FF80050)) +#define DEVICE_ID_REG1 (*((volatile uint32_t *)0x1FF80054)) +#define DEVICE_ID_REG2 (*((volatile uint32_t *)0x1FF80064)) +/*---------------------------------------------------------------------------*/ +void +node_id_restore(void) +{ + device_id[0] = DEVICE_ID_REG0; + device_id[1] = DEVICE_ID_REG1; + device_id[2] = DEVICE_ID_REG2; + + (*(uint32_t *)node_mac) = DEVICE_ID_REG1; + (*(((uint32_t *)node_mac) + 1)) = DEVICE_ID_REG2 + DEVICE_ID_REG0; + node_id = (unsigned short)DEVICE_ID_REG2; +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/stm32nucleo-spirit1/platform-conf.h b/platform/stm32nucleo-spirit1/platform-conf.h new file mode 100644 index 000000000..0f2a0077b --- /dev/null +++ b/platform/stm32nucleo-spirit1/platform-conf.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup stm32nucleo-spirit1 + * @{ + * + * \defgroup stm32nucleo-spirit1-peripherals User Button on STM32 Nucleo + * + * Defines some of the platforms capabilities + * @{ + * + * \file + * Header file for the stm32nucleo-spirit1 platform configuration + */ +/*---------------------------------------------------------------------------*/ +#ifndef __PLATFORM_CONF_H__ +#define __PLATFORM_CONF_H__ +/*---------------------------------------------------------------------------*/ +#include +#include +/*---------------------------------------------------------------------------*/ +#define PLATFORM_HAS_LEDS 1 +#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_RADIO 1 + +#define LEDS_GREEN 1 /*Nucleo LED*/ +#define LEDS_RED 2 /*SPIRIT1 LED*/ + +#ifdef X_NUCLEO_IKS01A1 +#define LEDS_CONF_ALL 1 /*Can't use SPIRIT1 LED in this case*/ +#else +#define LEDS_CONF_ALL 3 /*No sensors -> we can use SPIRIT1 LED in this case*/ +#endif /*X_NUCLEO_IKS01A1*/ +/*---------------------------------------------------------------------------*/ +#define F_CPU 32000000ul +#define RTIMER_ARCH_SECOND 32768 +#define PRESCALER ((F_CPU / (RTIMER_ARCH_SECOND * 2))) + +#define UART1_CONF_TX_WITH_INTERRUPT 0 +#define WITH_SERIAL_LINE_INPUT 1 +#define TELNETD_CONF_NUMLINES 6 +#define NETSTACK_CONF_RADIO spirit_radio_driver +#define NETSTACK_RADIO_MAX_PAYLOAD_LEN 96 /* spirit1-config.h */ + +/*---------------------------------------------------------------------------*/ +/* define ticks/second for slow and fast clocks. Notice that these should be a + power of two, eg 64,128,256,512 etc, for efficiency as POT's can be optimized + well. */ +#define CLOCK_CONF_SECOND 128 +/* One tick: 62.5 ms */ + +#define RTIMER_CLOCK_DIFF(a, b) ((signed short)((a) - (b))) +/*---------------------------------------------------------------------------*/ +typedef unsigned long clock_time_t; +typedef unsigned long long rtimer_clock_t; +/*---------------------------------------------------------------------------*/ +#define CC_CONF_REGISTER_ARGS 0 +#define CC_CONF_FUNCTION_POINTER_ARGS 1 +#define CC_CONF_FASTCALL +#define CC_CONF_VA_ARGS 1 +#define CC_CONF_INLINE inline + +#define CCIF +#define CLIF +/*---------------------------------------------------------------------------*/ +typedef uint8_t u8_t; +typedef uint16_t u16_t; +typedef uint32_t u32_t; +typedef int32_t s32_t; +typedef unsigned short uip_stats_t; +/*---------------------------------------------------------------------------*/ +#define MULTICHAN_CONF_SET_CHANNEL(x) +#define MULTICHAN_CONF_READ_RSSI(x) 0 +/*---------------------------------------------------------------------------*/ +#endif /* __PLATFORM_CONF_H__ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/stm32nucleo-spirit1/spirit1-arch.c b/platform/stm32nucleo-spirit1/spirit1-arch.c new file mode 100644 index 000000000..6ea68bf3d --- /dev/null +++ b/platform/stm32nucleo-spirit1/spirit1-arch.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +#include "stm32l1xx.h" +#include "spirit1-arch.h" +#include "spirit1.h" +#include "st-lib.h" +/*---------------------------------------------------------------------------*/ +extern void spirit1_interrupt_callback(void); +st_lib_spirit_bool spiritdk_timer_expired = S_FALSE; +/*---------------------------------------------------------------------------*/ +/* use the SPI-port to acquire the status bytes from the radio. */ +#define CS_TO_SCLK_DELAY 0x0100 +/*---------------------------------------------------------------------------*/ +extern st_lib_spi_handle_typedef st_lib_p_spi_handle; +/*---------------------------------------------------------------------------*/ +uint16_t +spirit1_arch_refresh_status(void) +{ + volatile uint16_t mcstate = 0x0000; + uint8_t header[2]; + header[0] = 0x01; + header[1] = MC_STATE1_BASE; + uint32_t spi_timeout = ((uint32_t)1000); /*IDR & RADIO_SPI_CS_PIN)) +#define SPIRIT1_STATUS() (spirit1_arch_refresh_status() & SPIRIT1_STATE_STATEBITS) +/*---------------------------------------------------------------------------*/ +uint16_t spirit1_arch_refresh_status(void); +/*---------------------------------------------------------------------------*/ +#endif /* __SPIRIT1_ARCH_H__ */ diff --git a/platform/stm32nucleo-spirit1/spirit1-config.h b/platform/stm32nucleo-spirit1/spirit1-config.h new file mode 100644 index 000000000..5124aef24 --- /dev/null +++ b/platform/stm32nucleo-spirit1/spirit1-config.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +#ifndef __SPIRIT1_CONFIG_H__ +#define __SPIRIT1_CONFIG_H__ +/*---------------------------------------------------------------------------*/ +#include "radio.h" +#include "SPIRIT_Config.h" +#include "spirit1-const.h" +/*---------------------------------------------------------------------------*/ +#define CCA_THRESHOLD -120.0 /* dBm */ +#define XTAL_FREQUENCY 50000000 /* Hz */ +#define SPIRIT_MAX_FIFO_LEN 96 +/*---------------------------------------------------------------------------*/ + +/** + * The MAX_PACKET_LEN is an arbitrary value used to define the two array + * spirit_txbuf and spirit_rxbuf. + * The SPIRIT1 supports with its packet handler a length of 65,535 bytes, + * and in direct mode (without packet handler) there is no limit of data. + */ +#define MAX_PACKET_LEN SPIRIT_MAX_FIFO_LEN +/*---------------------------------------------------------------------------*/ +/** + * Spirit1 IC version + */ +#define SPIRIT1_VERSION SPIRIT_VERSION_3_0 +/*---------------------------------------------------------------------------*/ +#endif /* __SPIRIT1_CONFIG_H__ */ +/*---------------------------------------------------------------------------*/ diff --git a/platform/stm32nucleo-spirit1/spirit1-const.h b/platform/stm32nucleo-spirit1/spirit1-const.h new file mode 100644 index 000000000..84294e343 --- /dev/null +++ b/platform/stm32nucleo-spirit1/spirit1-const.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +#ifndef __SPIRIT1_CONST_H__ +#define __SPIRIT1_CONST_H__ +/*---------------------------------------------------------------------------*/ +/* The state bitfield and values for different states, as read from MC_STATE[1:0] registers, + which are returned on any SPI read or write operation. */ +#define SPIRIT1_STATE_STATEBITS (0x00FE) +/*---------------------------------------------------------------------------*/ + +#define SPIRIT1_STATE_STANDBY ((0x0040) << 1) +#define SPIRIT1_STATE_SLEEP ((0x0036) << 1) +#define SPIRIT1_STATE_READY ((0x0003) << 1) +#define SPIRIT1_STATE_LOCK ((0x000F) << 1) +#define SPIRIT1_STATE_RX ((0x0033) << 1) +#define SPIRIT1_STATE_TX ((0x005F) << 1) +/* NB the below states were extracted from ST drivers, but are not specified in the datasheet */ +#define SPIRIT1_STATE_PM_SETUP ((0x003D) << 1) +#define SPIRIT1_STATE_XO_SETTLING ((0x0023) << 1) +#define SPIRIT1_STATE_SYNTH_SETUP ((0x0053) << 1) +#define SPIRIT1_STATE_PROTOCOL ((0x001F) << 1) +#define SPIRIT1_STATE_SYNTH_CALIBRATION ((0x004F) << 1) +/*---------------------------------------------------------------------------*/ +/* strobe commands */ +#define SPIRIT1_STROBE_TX 0x60 +#define SPIRIT1_STROBE_RX 0x61 +#define SPIRIT1_STROBE_READY 0x62 +#define SPIRIT1_STROBE_STANDBY 0x63 +#define SPIRIT1_STROBE_SLEEP 0x64 +#define SPIRIT1_STROBE_SABORT 0x67 +#define SPIRIT1_STROBE_SRES 0x70 +#define SPIRIT1_STROBE_FRX 0x71 +#define SPIRIT1_STROBE_FTX 0x72 +/*---------------------------------------------------------------------------*/ +#endif /* __SPIRIT1_CONST_H__ */ +/*---------------------------------------------------------------------------*/ diff --git a/platform/stm32nucleo-spirit1/spirit1.c b/platform/stm32nucleo-spirit1/spirit1.c new file mode 100644 index 000000000..5bca4195f --- /dev/null +++ b/platform/stm32nucleo-spirit1/spirit1.c @@ -0,0 +1,713 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +#include "spirit1.h" +#include "spirit1-arch.h" +#include "stm32l1xx.h" +#include "contiki.h" +#include "net/mac/frame802154.h" +#include "net/netstack.h" +#include "net/packetbuf.h" +#include "net/rime/rimestats.h" +#include "spirit1-arch.h" +#include +#include "st-lib.h" +/*---------------------------------------------------------------------------*/ +/* MGR extern st_lib_spirit_irqs st_lib_x_irq_status; */ +extern volatile st_lib_spirit_flag_status rx_timeout; +/*---------------------------------------------------------------------------*/ +#define XXX_ACK_WORKAROUND 1 +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/*---------------------------------------------------------------------------*/ +#define BUSYWAIT_UNTIL(cond, max_time) \ + do { \ + rtimer_clock_t t0; \ + t0 = RTIMER_NOW(); \ + while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))) ; \ + } while(0) + +/*---------------------------------------------------------------------------*/ +#define CLEAR_TXBUF() (spirit_txbuf[0] = 0) +#define CLEAR_RXBUF() (spirit_rxbuf[0] = 0) +#define IS_TXBUF_EMPTY() (spirit_txbuf[0] == 0) +#define IS_RXBUF_EMPTY() (spirit_rxbuf[0] == 0) +#define IS_RXBUF_FULL() (spirit_rxbuf[0] != 0) +/*---------------------------------------------------------------------------*/ +/* transceiver state. */ +#define ON 0 +#define OFF 1 +/*---------------------------------------------------------------------------*/ +static volatile unsigned int spirit_on = OFF; +static volatile uint8_t receiving_packet = 0; +static packetbuf_attr_t last_rssi = 0; /* MGR */ +static packetbuf_attr_t last_lqi = 0; /* MGR */ +/*---------------------------------------------------------------------------*/ +/* + * The buffers which hold incoming data. + * The +1 because of the first byte, + * which will contain the length of the packet. + */ +static uint8_t spirit_rxbuf[MAX_PACKET_LEN + 1]; +static uint8_t spirit_txbuf[MAX_PACKET_LEN + 1 - SPIRIT_MAX_FIFO_LEN]; +void st_lib_spirit_management_set_frequency_base(uint32_t); +/*---------------------------------------------------------------------------*/ +static int just_got_an_ack = 0; /* Interrupt callback just detected an ack */ +#if NULLRDC_CONF_802154_AUTOACK +#define ACK_LEN 3 +static int wants_an_ack = 0; /* The packet sent expects an ack */ +/* static int just_got_an_ack = 0; / * Interrupt callback just detected an ack * / */ +/* #define ACKPRINTF printf */ +#define ACKPRINTF(...) +#endif /* NULLRDC_CONF_802154_AUTOACK */ +/*---------------------------------------------------------------------------*/ +static int packet_is_prepared = 0; +/*---------------------------------------------------------------------------*/ +PROCESS(spirit_radio_process, "SPIRIT radio driver"); +/*---------------------------------------------------------------------------*/ +static int spirit_radio_init(void); +static int spirit_radio_prepare(const void *payload, unsigned short payload_len); +static int spirit_radio_transmit(unsigned short payload_len); +static int spirit_radio_send(const void *data, unsigned short len); +static int spirit_radio_read(void *buf, unsigned short bufsize); +static int spirit_radio_channel_clear(void); +static int spirit_radio_receiving_packet(void); +static int spirit_radio_pending_packet(void); +static int spirit_radio_on(void); +static int spirit_radio_off(void); +/*---------------------------------------------------------------------------*/ +const struct radio_driver spirit_radio_driver = +{ + spirit_radio_init, + spirit_radio_prepare, + spirit_radio_transmit, + spirit_radio_send, + spirit_radio_read, + spirit_radio_channel_clear, + spirit_radio_receiving_packet, + spirit_radio_pending_packet, + spirit_radio_on, + spirit_radio_off, +}; +/*---------------------------------------------------------------------------*/ +void +spirit1_printstatus(void) +{ + int s = SPIRIT1_STATUS(); + if(s == SPIRIT1_STATE_STANDBY) { + printf("spirit1: SPIRIT1_STATE_STANDBY\n"); + } else if(s == SPIRIT1_STATE_READY) { + printf("spirit1: SPIRIT1_STATE_READY\n"); + } else if(s == SPIRIT1_STATE_TX) { + printf("spirit1: SPIRIT1_STATE_TX\n"); + } else if(s == SPIRIT1_STATE_RX) { + printf("spirit1: SPIRIT1_STATE_RX\n"); + } else { + printf("spirit1: status: %d\n", s); + } +} +/*---------------------------------------------------------------------------*/ +/* Strobe a command. The rationale for this is to clean up the messy legacy code. */ +static void +spirit1_strobe(uint8_t s) +{ + st_lib_spirit_cmd_strobe_command(s); +} +/*---------------------------------------------------------------------------*/ +void +spirit_set_ready_state(void) +{ + PRINTF("READY IN\n"); + + st_lib_spirit_irq_clear_status(); + IRQ_DISABLE(); + + if(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY) { + spirit1_strobe(SPIRIT1_STROBE_READY); + } else if(SPIRIT1_STATUS() == SPIRIT1_STATE_RX) { + spirit1_strobe(SPIRIT1_STROBE_SABORT); + st_lib_spirit_irq_clear_status(); + } + + IRQ_ENABLE(); + + PRINTF("READY OUT\n"); +} +/*---------------------------------------------------------------------------*/ +static int +spirit_radio_init(void) +{ + + PRINTF("RADIO INIT IN\n"); + + st_lib_spirit_spi_init(); + + /* Configure radio shut-down (SDN) pin and activate radio */ + st_lib_radio_gpio_init(RADIO_GPIO_SDN, RADIO_MODE_GPIO_OUT); + + /* Configures the SPIRIT1 library */ + st_lib_spirit_radio_set_xtal_frequency(XTAL_FREQUENCY); + st_lib_spirit_management_set_frequency_base(XTAL_FREQUENCY); + + /* wake up to READY state */ + /* weirdly enough, this *should* actually *set* the pin, not clear it! The pins is declared as GPIO_pin13 == 0x2000 */ + RADIO_GPIO_SDN_PORT->BSRR = RADIO_GPIO_SDN_PIN; + st_lib_hal_gpio_write_pin(RADIO_GPIO_SDN_PORT, RADIO_GPIO_SDN_PIN, GPIO_PIN_RESET); + + /* wait minimum 1.5 ms to allow SPIRIT1 a proper boot-up sequence */ + BUSYWAIT_UNTIL(0, 3 * RTIMER_SECOND / 2000); + + /* Soft reset of core */ + spirit1_strobe(SPIRIT1_STROBE_SRES); + + /* Configures the SPIRIT1 radio part */ + st_lib_s_radio_init x_radio_init = { + /* XTAL_FREQUENCY, */ + XTAL_OFFSET_PPM, + BASE_FREQUENCY, + CHANNEL_SPACE, + CHANNEL_NUMBER, + MODULATION_SELECT, + DATARATE, + FREQ_DEVIATION, + BANDWIDTH + }; + st_lib_spirit_radio_init(&x_radio_init); + st_lib_spirit_radio_set_xtal_frequency(XTAL_FREQUENCY); + st_lib_spirit_radio_set_pa_level_dbm(0, POWER_DBM); + st_lib_spirit_radio_set_pa_level_max_index(0); + + /* Configures the SPIRIT1 packet handler part*/ + st_lib_pkt_basic_init x_basic_init = { + PREAMBLE_LENGTH, + SYNC_LENGTH, + SYNC_WORD, + LENGTH_TYPE, + LENGTH_WIDTH, + CRC_MODE, + CONTROL_LENGTH, + EN_ADDRESS, + EN_FEC, + EN_WHITENING + }; + st_lib_spirit_pkt_basic_init(&x_basic_init); + + /* Enable the following interrupt sources, routed to GPIO */ + st_lib_spirit_irq_de_init(NULL); + st_lib_spirit_irq_clear_status(); + st_lib_spirit_irq(TX_DATA_SENT, S_ENABLE); + st_lib_spirit_irq(RX_DATA_READY, S_ENABLE); + st_lib_spirit_irq(VALID_SYNC, S_ENABLE); + st_lib_spirit_irq(RX_DATA_DISC, S_ENABLE); + st_lib_spirit_irq(TX_FIFO_ERROR, S_ENABLE); + st_lib_spirit_irq(RX_FIFO_ERROR, S_ENABLE); + + /* Configure Spirit1 */ + st_lib_spirit_radio_persisten_rx(S_ENABLE); + st_lib_spirit_qi_set_sqi_threshold(SQI_TH_0); + st_lib_spirit_qi_sqi_check(S_ENABLE); + st_lib_spirit_qi_set_rssi_threshold_dbm(CCA_THRESHOLD); + st_lib_spirit_timer_set_rx_timeout_stop_condition(SQI_ABOVE_THRESHOLD); + SET_INFINITE_RX_TIMEOUT(); + st_lib_spirit_radio_afc_freeze_on_sync(S_ENABLE); + + /* Puts the SPIRIT1 in STANDBY mode (125us -> rx/tx) */ + spirit1_strobe(SPIRIT1_STROBE_STANDBY); + spirit_on = OFF; + CLEAR_RXBUF(); + CLEAR_TXBUF(); + + /* Initializes the mcu pin as input, used for IRQ */ + st_lib_radio_gpio_init(RADIO_GPIO_IRQ, RADIO_MODE_EXTI_IN); + + /* Configure the radio to route the IRQ signal to its GPIO 3 */ + st_lib_spirit_gpio_init(&(st_lib_s_gpio_init){SPIRIT_GPIO_IRQ, SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_LP, SPIRIT_GPIO_DIG_OUT_IRQ }); + + process_start(&spirit_radio_process, NULL); + + PRINTF("Spirit1 init done\n"); + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +spirit_radio_prepare(const void *payload, unsigned short payload_len) +{ + PRINTF("Spirit1: prep %u\n", payload_len); + packet_is_prepared = 0; + + /* Checks if the payload length is supported */ + if(payload_len > MAX_PACKET_LEN) { + return RADIO_TX_ERR; + } + + /* Should we delay for an ack? */ +#if NULLRDC_CONF_802154_AUTOACK + frame802154_t info154; + wants_an_ack = 0; + if(payload_len > ACK_LEN + && frame802154_parse((char *)payload, payload_len, &info154) != 0) { + if(info154.fcf.frame_type == FRAME802154_DATAFRAME + && info154.fcf.ack_required != 0) { + wants_an_ack = 1; + } + } +#endif /* NULLRDC_CONF_802154_AUTOACK */ + + /* Sets the length of the packet to send */ + IRQ_DISABLE(); + spirit1_strobe(SPIRIT1_STROBE_FTX); + st_lib_spirit_pkt_basic_set_payload_length(payload_len); + st_lib_spirit_spi_write_linear_fifo(payload_len, (uint8_t *)payload); + IRQ_ENABLE(); + + PRINTF("PREPARE OUT\n"); + + packet_is_prepared = 1; + return RADIO_TX_OK; +} +/*---------------------------------------------------------------------------*/ +static int +spirit_radio_transmit(unsigned short payload_len) +{ + /* This function blocks until the packet has been transmitted */ + rtimer_clock_t rtimer_txdone, rtimer_rxack; + + PRINTF("TRANSMIT IN\n"); + if(!packet_is_prepared) { + return RADIO_TX_ERR; + } + + /* Stores the length of the packet to send */ + /* Others spirit_radio_prepare will be in hold */ + spirit_txbuf[0] = payload_len; + + /* Puts the SPIRIT1 in TX state */ + receiving_packet = 0; + spirit_set_ready_state(); + spirit1_strobe(SPIRIT1_STROBE_TX); + just_got_an_ack = 0; + BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_TX, 1 * RTIMER_SECOND / 1000); + /* BUSYWAIT_UNTIL(SPIRIT1_STATUS() != SPIRIT1_STATE_TX, 4 * RTIMER_SECOND/1000); //For GFSK with high data rate */ + BUSYWAIT_UNTIL(SPIRIT1_STATUS() != SPIRIT1_STATE_TX, 50 * RTIMER_SECOND / 1000); /* For FSK with low data rate */ + + /* Reset radio - needed for immediate RX of ack */ + CLEAR_TXBUF(); + CLEAR_RXBUF(); + IRQ_DISABLE(); + st_lib_spirit_irq_clear_status(); + spirit1_strobe(SPIRIT1_STROBE_SABORT); + BUSYWAIT_UNTIL(0, RTIMER_SECOND / 2500); + spirit1_strobe(SPIRIT1_STROBE_READY); + BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 1 * RTIMER_SECOND / 1000); + spirit1_strobe(SPIRIT1_STROBE_RX); + BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1 * RTIMER_SECOND / 1000); + IRQ_ENABLE(); + +#if XXX_ACK_WORKAROUND + just_got_an_ack = 1; +#endif /* XXX_ACK_WORKAROUND */ + +#if NULLRDC_CONF_802154_AUTOACK + if(wants_an_ack) { + rtimer_txdone = RTIMER_NOW(); + BUSYWAIT_UNTIL(just_got_an_ack, 2 * RTIMER_SECOND / 1000); + rtimer_rxack = RTIMER_NOW(); + + if(just_got_an_ack) { + ACKPRINTF("debug_ack: ack received after %u/%u ticks\n", + (uint32_t)(rtimer_rxack - rtimer_txdone), 2 * RTIMER_SECOND / 1000); + } else { + ACKPRINTF("debug_ack: no ack received\n"); + } + } +#endif /* NULLRDC_CONF_802154_AUTOACK */ + + PRINTF("TRANSMIT OUT\n"); + + CLEAR_TXBUF(); + + packet_is_prepared = 0; + + clock_wait(1); + + return RADIO_TX_OK; +} +/*---------------------------------------------------------------------------*/ +static int +spirit_radio_send(const void *payload, unsigned short payload_len) +{ + if(spirit_radio_prepare(payload, payload_len) == RADIO_TX_ERR) { + return RADIO_TX_ERR; + } + return spirit_radio_transmit(payload_len); +} +/*---------------------------------------------------------------------------*/ +static int +spirit_radio_read(void *buf, unsigned short bufsize) +{ + PRINTF("READ IN\n"); + + /* Checks if the RX buffer is empty */ + if(IS_RXBUF_EMPTY()) { + IRQ_DISABLE(); + CLEAR_RXBUF(); + spirit1_strobe(SPIRIT1_STROBE_SABORT); + BUSYWAIT_UNTIL(0, RTIMER_SECOND / 2500); + spirit1_strobe(SPIRIT1_STROBE_READY); + BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 1 * RTIMER_SECOND / 1000); + spirit1_strobe(SPIRIT1_STROBE_RX); + BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1 * RTIMER_SECOND / 1000); + PRINTF("READ OUT RX BUF EMPTY\n"); + IRQ_ENABLE(); + return 0; + } + + if(bufsize < spirit_rxbuf[0]) { + /* If buf has the correct size */ + PRINTF("TOO SMALL BUF\n"); + return 0; + } else { + /* Copies the packet received */ + memcpy(buf, spirit_rxbuf + 1, spirit_rxbuf[0]); + + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, last_rssi); /* MGR */ + packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, last_lqi); /* MGR */ + bufsize = spirit_rxbuf[0]; + CLEAR_RXBUF(); + + PRINTF("READ OUT\n"); + + return bufsize; + } +} +/*---------------------------------------------------------------------------*/ +static int +spirit_radio_channel_clear(void) +{ + float rssi_value; + /* Local variable used to memorize the SPIRIT1 state */ + uint8_t spirit_state = ON; + + PRINTF("CHANNEL CLEAR IN\n"); + + if(spirit_on == OFF) { + /* Wakes up the SPIRIT1 */ + spirit_radio_on(); + spirit_state = OFF; + } + + /* */ + IRQ_DISABLE(); + spirit1_strobe(SPIRIT1_STROBE_SABORT); +/* SpiritCmdStrobeSabort();*/ + st_lib_spirit_irq_clear_status(); + IRQ_ENABLE(); + { + rtimer_clock_t timeout = RTIMER_NOW() + 5 * RTIMER_SECOND / 1000; + do { + st_lib_spirit_refresh_status(); + } while((st_lib_g_x_status.MC_STATE != MC_STATE_READY) && (RTIMER_NOW() < timeout)); + if(RTIMER_NOW() < timeout) { + return 1; + } + } + + /* Stores the RSSI value */ + rssi_value = st_lib_spirit_qi_get_rssi_dbm(); + + /* Puts the SPIRIT1 in its previous state */ + if(spirit_state == OFF) { + spirit_radio_off(); + } else { + spirit1_strobe(SPIRIT1_STROBE_RX); +/* SpiritCmdStrobeRx();*/ + BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 5 * RTIMER_SECOND / 1000); + } + + PRINTF("CHANNEL CLEAR OUT\n"); + + /* Checks the RSSI value with the threshold */ + if(rssi_value < CCA_THRESHOLD) { + return 0; + } else { + return 1; + } +} +/*---------------------------------------------------------------------------*/ +static int +spirit_radio_receiving_packet(void) +{ + return receiving_packet; +} +/*---------------------------------------------------------------------------*/ +static int +spirit_radio_pending_packet(void) +{ + PRINTF("PENDING PACKET\n"); + return !IS_RXBUF_EMPTY(); +} +/*---------------------------------------------------------------------------*/ +static int +spirit_radio_off(void) +{ + PRINTF("Spirit1: ->off\n"); + if(spirit_on == ON) { + /* Disables the mcu to get IRQ from the SPIRIT1 */ + IRQ_DISABLE(); + + /* first stop rx/tx */ + spirit1_strobe(SPIRIT1_STROBE_SABORT); + + /* Clear any pending irqs */ + st_lib_spirit_irq_clear_status(); + + BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 5 * RTIMER_SECOND / 1000); + if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) { + PRINTF("Spirit1: failed off->ready\n"); + return 1; + } + + /* Puts the SPIRIT1 in STANDBY */ + spirit1_strobe(SPIRIT1_STROBE_STANDBY); + BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, 5 * RTIMER_SECOND / 1000); + if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) { + PRINTF("Spirit1: failed off->stdby\n"); + return 1; + } + + spirit_on = OFF; + CLEAR_TXBUF(); + CLEAR_RXBUF(); + } + PRINTF("Spirit1: off.\n"); + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +spirit_radio_on(void) +{ + + PRINTF("Spirit1: on\n"); + spirit1_strobe(SPIRIT1_STROBE_SABORT); + BUSYWAIT_UNTIL(0, RTIMER_SECOND / 2500); + if(spirit_on == OFF) { + IRQ_DISABLE(); + /* ensure we are in READY state as we go from there to Rx */ + spirit1_strobe(SPIRIT1_STROBE_READY); + BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 5 * RTIMER_SECOND / 1000); + if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) { + PRINTF("Spirit1: failed to turn on\n"); + while(1) ; + /* return 1; */ + } + + /* now we go to Rx */ + spirit1_strobe(SPIRIT1_STROBE_RX); + BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 5 * RTIMER_SECOND / 1000); + if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) { + PRINTF("Spirit1: failed to enter rx\n"); + while(1) ; + /* return 1; */ + } + + /* Enables the mcu to get IRQ from the SPIRIT1 */ + IRQ_ENABLE(); + spirit_on = ON; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +static int interrupt_callback_in_progress = 0; +static int interrupt_callback_wants_poll = 0; +PROCESS_THREAD(spirit_radio_process, ev, data) +{ + PROCESS_BEGIN(); + PRINTF("Spirit1: process started\n"); + + while(1) { + int len; + + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + PRINTF("Spirit1: polled\n"); + + packetbuf_clear(); + len = spirit_radio_read(packetbuf_dataptr(), PACKETBUF_SIZE); + + if(len > 0) { + +#if NULLRDC_CONF_802154_AUTOACK + /* Check if the packet has an ACK request */ + frame802154_t info154; + if(len > ACK_LEN && + frame802154_parse((char *)packetbuf_dataptr(), len, &info154) != 0) { + if(info154.fcf.frame_type == FRAME802154_DATAFRAME && + info154.fcf.ack_required != 0 && + linkaddr_cmp((linkaddr_t *)&info154.dest_addr, + &linkaddr_node_addr)) { + +#if !XXX_ACK_WORKAROUND + /* Send an ACK packet */ + uint8_t ack_frame[ACK_LEN] = { + FRAME802154_ACKFRAME, + 0x00, + info154.seq + }; + IRQ_DISABLE(); + spirit1_strobe(SPIRIT1_STROBE_FTX); + st_lib_spirit_pkt_basic_set_payload_length((uint16_t)ACK_LEN); + st_lib_spirit_spi_write_linear_fifo((uint16_t)ACK_LEN, (uint8_t *)ack_frame); + + spirit_set_ready_state(); + IRQ_ENABLE(); + spirit1_strobe(SPIRIT1_STROBE_TX); + BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_TX, 1 * RTIMER_SECOND / 1000); + BUSYWAIT_UNTIL(SPIRIT1_STATUS() != SPIRIT1_STATE_TX, 1 * RTIMER_SECOND / 1000); + ACKPRINTF("debug_ack: sent ack %d\n", ack_frame[2]); +#endif /* !XXX_ACK_WORKAROUND */ + } + } +#endif /* NULLRDC_CONF_802154_AUTOACK */ + + packetbuf_set_datalen(len); + NETSTACK_RDC.input(); + } + + if(!IS_RXBUF_EMPTY()) { + process_poll(&spirit_radio_process); + } + + if(interrupt_callback_wants_poll) { + spirit1_interrupt_callback(); + + if(SPIRIT1_STATUS() == SPIRIT1_STATE_READY) { + spirit1_strobe(SPIRIT1_STROBE_RX); + BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1 * RTIMER_SECOND / 1000); + } + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +void +spirit1_interrupt_callback(void) +{ +#define INTPRINTF(...) /* PRINTF */ + st_lib_spirit_irqs x_irq_status; + if(spirit_spi_busy() || interrupt_callback_in_progress) { + process_poll(&spirit_radio_process); + interrupt_callback_wants_poll = 1; + return; + } + + interrupt_callback_wants_poll = 0; + interrupt_callback_in_progress = 1; + + /* get interrupt source from radio */ + st_lib_spirit_irq_get_status(&x_irq_status); + st_lib_spirit_irq_clear_status(); + + if(x_irq_status.IRQ_RX_FIFO_ERROR) { + receiving_packet = 0; + interrupt_callback_in_progress = 0; + spirit1_strobe(SPIRIT1_STROBE_FRX); + return; + } + + if(x_irq_status.IRQ_TX_FIFO_ERROR) { + receiving_packet = 0; + interrupt_callback_in_progress = 0; + spirit1_strobe(SPIRIT1_STROBE_FTX); + return; + } + + /* The IRQ_VALID_SYNC is used to notify a new packet is coming */ + if(x_irq_status.IRQ_VALID_SYNC) { + INTPRINTF("SYNC\n"); + receiving_packet = 1; + } + + /* The IRQ_TX_DATA_SENT notifies the packet received. Puts the SPIRIT1 in RX */ + if(x_irq_status.IRQ_TX_DATA_SENT) { + spirit1_strobe(SPIRIT1_STROBE_RX); +/* SpiritCmdStrobeRx();*/ + INTPRINTF("SENT\n"); + CLEAR_TXBUF(); + interrupt_callback_in_progress = 0; + return; + } + + /* The IRQ_RX_DATA_READY notifies a new packet arrived */ + if(x_irq_status.IRQ_RX_DATA_READY) { + st_lib_spirit_spi_read_linear_fifo(st_lib_spirit_linear_fifo_read_num_elements_rx_fifo(), + &spirit_rxbuf[1]); + spirit_rxbuf[0] = st_lib_spirit_pkt_basic_get_received_pkt_length(); + spirit1_strobe(SPIRIT1_STROBE_FRX); + + INTPRINTF("RECEIVED\n"); + + process_poll(&spirit_radio_process); + + last_rssi = (packetbuf_attr_t)st_lib_spirit_qi_get_rssi(); /* MGR */ + last_lqi = (packetbuf_attr_t)st_lib_spirit_qi_get_lqi(); /* MGR */ + + receiving_packet = 0; + +#if NULLRDC_CONF_802154_AUTOACK + if(spirit_rxbuf[0] == ACK_LEN) { + /* For debugging purposes we assume this is an ack for us */ + just_got_an_ack = 1; + } +#endif /* NULLRDC_CONF_802154_AUTOACK */ + + interrupt_callback_in_progress = 0; + return; + } + + if(x_irq_status.IRQ_RX_DATA_DISC) { + /* RX command - to ensure the device will be ready for the next reception */ + if(x_irq_status.IRQ_RX_TIMEOUT) { + st_lib_spirit_cmd_strobe_flush_rx_fifo(); + rx_timeout = SET; + } + } + + interrupt_callback_in_progress = 0; +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/iris/apps/mts310/mic-test.c b/platform/stm32nucleo-spirit1/spirit1.h similarity index 78% rename from platform/iris/apps/mts310/mic-test.c rename to platform/stm32nucleo-spirit1/spirit1.h index bb4ec62d9..6e95bd3d1 100644 --- a/platform/iris/apps/mts310/mic-test.c +++ b/platform/stm32nucleo-spirit1/spirit1.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, University of Colombo School of Computing + * Copyright (c) 2012, STMicroelectronics. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,31 +28,19 @@ * * This file is part of the Contiki operating system. * - * @(#)$$ */ - -#include "contiki.h" -#include "dev/sensors/mts300.h" -#include - /*---------------------------------------------------------------------------*/ -PROCESS(test_mic_process, "Mic test"); -AUTOSTART_PROCESSES(&test_mic_process); +#ifndef __SPIRIT_H__ +#define __SPIRIT_H__ /*---------------------------------------------------------------------------*/ -PROCESS_THREAD(test_mic_process, ev, data) -{ - static struct etimer et; - - PROCESS_BEGIN(); - - while(1) { - - printf("Mic : %d\n",get_mic()); - etimer_set(&et, CLOCK_SECOND / 8); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); -; - } - - PROCESS_END(); -} +#include "radio.h" +#include "SPIRIT_Config.h" +#include "spirit1-config.h" +#include "spirit1_appli.h" +#include "spirit1-const.h" +/*---------------------------------------------------------------------------*/ +extern const struct radio_driver spirit_radio_driver; +void spirit1_interrupt_callback(void); +/*---------------------------------------------------------------------------*/ +#endif /* __SPIRIT_H__ */ /*---------------------------------------------------------------------------*/ diff --git a/platform/stm32nucleo-spirit1/st-lib.h b/platform/stm32nucleo-spirit1/st-lib.h new file mode 100644 index 000000000..6a7e2ee0f --- /dev/null +++ b/platform/stm32nucleo-spirit1/st-lib.h @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \defgroup stm32nucleo-spirit1 STM32Cube HAL APIs + * + * Abstraction of STM32Cube HAL APIs as per Contiki coding rules + * @{ + * + * \file + * Header file for the STM32Cube HAL APIs + */ +/*---------------------------------------------------------------------------*/ +#ifndef ST_LIB_H_ +#define ST_LIB_H_ + +/*---------------------------------------------------------------------------*/ +/* extern global varialbles */ +#define st_lib_uart_handle UartHandle + +#define st_lib_g_x_status g_xStatus + +#define st_lib_p_spi_handle pSpiHandle +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* misc */ +#define st_lib_tim2_irq_handler(...) TIM2_IRQHandler(__VA_ARGS__) +#define st_lib_spirit_management_set_frequency_base(...) SpiritManagementSetFrequencyBase(__VA_ARGS__) +#define st_lib_sys_tick_handler(...) SysTick_Handler(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* MCU_Interface.h */ +#include "MCU_Interface.h" + +#define st_lib_spirit_spi_init(...) SpiritSpiInit(__VA_ARGS__) +#define st_lib_spirit_spi_read_linear_fifo(...) SpiritSpiReadLinearFifo(__VA_ARGS__) +#define st_lib_spirit_spi_write_linear_fifo(...) SpiritSpiWriteLinearFifo(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* radio_gpio.h */ +#include "radio_gpio.h" + +#define st_lib_radio_gpio_interrupt_cmd(...) RadioGpioInterruptCmd(__VA_ARGS__) +#define st_lib_radio_gpio_init(...) RadioGpioInit(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* radio_shield_config.h */ +#include "radio_shield_config.h" + +#define st_lib_a_led_gpio_port aLED_GPIO_PORT +#define st_lib_a_led_gpio_pin aLED_GPIO_PIN + +#define st_lib_radio_shield_led_init(...) RadioShieldLedInit(__VA_ARGS__) +#define st_lib_radio_shield_led_off(...) RadioShieldLedOff(__VA_ARGS__) +#define st_lib_radio_shield_led_on(...) RadioShieldLedOn(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* radio_spi.h */ +#include "radio_spi.h" + +#define st_lib_radio_spi_cs_high(...) RadioSpiCSHigh(__VA_ARGS__) +#define st_lib_radio_spi_cs_low(...) RadioSpiCSLow(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* SPIRIT_Commands.h */ +#include "SPIRIT_Commands.h" + +#define st_lib_spirit_cmd_strobe_flush_rx_fifo(...) SpiritCmdStrobeFlushRxFifo(__VA_ARGS__) +#define st_lib_spirit_cmd_strobe_command(...) SpiritCmdStrobeCommand(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* SPIRIT_Gpio.h */ +#include "SPIRIT_Gpio.h" + +#define st_lib_s_gpio_init SGpioInit + +#define st_lib_spirit_gpio_init(...) SpiritGpioInit(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* SPIRIT_Irq.h */ +#include "SPIRIT_Irq.h" + +#define st_lib_spirit_irqs SpiritIrqs + +#define st_lib_spirit_irq(...) SpiritIrq(__VA_ARGS__) +#define st_lib_spirit_irq_de_init(...) SpiritIrqDeInit(__VA_ARGS__) +#define st_lib_spirit_irq_init(...) SpiritIrqInit(__VA_ARGS__) +#define st_lib_spirit_irq_get_mask(...) SpiritIrqGetMask(__VA_ARGS__) +#define st_lib_spirit_irq_get_status(...) SpiritIrqGetStatus(__VA_ARGS__) +#define st_lib_spirit_irq_clear_status(...) SpiritIrqClearStatus(__VA_ARGS__) +#define st_lib_spirit_irq_chack_flag(...) SpiritIrqCheckFlag(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* SPIRIT_LinearFifo.h */ +#include "SPIRIT_LinearFifo.h" + +#define st_lib_spirit_linear_fifo_read_num_elements_rx_fifo(...) SpiritLinearFifoReadNumElementsRxFifo(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* SPIRIT_PktBasic.h */ +#include "SPIRIT_PktBasic.h" + +#define st_lib_pkt_basic_init PktBasicInit + +#define st_lib_spirit_pkt_basic_init(...) SpiritPktBasicInit(__VA_ARGS__) +#define st_lib_spirit_pkt_basic_get_received_pkt_length(...) SpiritPktBasicGetReceivedPktLength(__VA_ARGS__) +#define st_lib_spirit_pkt_basic_set_payload_length(...) SpiritPktBasicSetPayloadLength(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* SPIRIT_Qi.h */ +#include "SPIRIT_Qi.h" + +#define st_lib_spirit_qi_get_rssi_dbm(...) SpiritQiGetRssidBm(__VA_ARGS__) +#define st_lib_spirit_qi_pqi_check(...) SpiritQiPqiCheck(__VA_ARGS__) +#define st_lib_spirit_qi_sqi_check(...) SpiritQiSqiCheck(__VA_ARGS__) +#define st_lib_spirit_qi_set_pqi_threshold(...) SpiritQiSetPqiThreshold(__VA_ARGS__) +#define st_lib_spirit_qi_get_pqi_threshold(...) SpiritQiGetPqiThreshold(__VA_ARGS__) +#define st_lib_spirit_qi_set_sqi_threshold(...) SpiritQiSetSqiThreshold(__VA_ARGS__) +#define st_lib_spirit_qi_get_sqi_threshold(...) SpiritQiGetSqiThreshold(__VA_ARGS__) +#define st_lib_spirit_qi_set_rssi_threshold(...) SpiritQiSetRssiThreshold(__VA_ARGS__) +#define st_lib_spirit_qi_get_rssi_threshold(...) SpiritQiGetRssiThreshold(__VA_ARGS__) +#define st_lib_spirit_qi_compute_rssi_threshold(...) SpiritQiComputeRssiThreshold(__VA_ARGS__) +#define st_lib_spirit_qi_set_rssi_threshold_dbm(...) SpiritQiSetRssiThresholddBm(__VA_ARGS__) +#define st_lib_spirit_qi_get_pqi(...) SpiritQiGetPqi(__VA_ARGS__) +#define st_lib_spirit_qi_get_sqi(...) SpiritQiGetSqi(__VA_ARGS__) +#define st_lib_spirit_qi_get_lqi(...) SpiritQiGetLqi(__VA_ARGS__) +#define st_lib_spirit_qi_get_cs(...) SpiritQiGetCs(__VA_ARGS__) +#define st_lib_spirit_qi_get_rssi(...) SpiritQiGetRssi(__VA_ARGS__) +#define st_lib_spirit_qi_set_rssi_filter_gain(...) SpiritQiSetRssiFilterGain(__VA_ARGS__) +#define st_lib_spirit_qi_get_rssi_filter_gain(...) SpiritQiGetRssiFilterGain(__VA_ARGS__) +#define st_lib_spirit_qi_set_cs_mode(...) SpiritQiSetCsMode(__VA_ARGS__) +#define st_lib_spirit_qi_get_cs_mode(...) SpiritQiGetCsMode(__VA_ARGS__) +#define st_lib_spirit_qi_cs_timeout_mask(...) SpiritQiCsTimeoutMask(__VA_ARGS__) +#define st_lib_spirit_qi_pqi_timeout_mask(...) SpiritQiPqiTimeoutMask(__VA_ARGS__) +#define st_lib_spirit_qi_sqi_timeout_mask(...) SpiritQiSqiTimeoutMask(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* SPIRIT_Radio.h */ +#include "SPIRIT_Radio.h" + +#define st_lib_s_radio_init SRadioInit + +#define st_lib_spirit_radio_afc_freeze_on_sync(...) SpiritRadioAFCFreezeOnSync(__VA_ARGS__) +#define st_lib_spirit_radio_init(...) SpiritRadioInit(__VA_ARGS__) +#define st_lib_spirit_radio_persisten_rx(...) SpiritRadioPersistenRx(__VA_ARGS__) +#define st_lib_spirit_radio_set_pa_level_dbm(...) SpiritRadioSetPALeveldBm(__VA_ARGS__) +#define st_lib_spirit_radio_set_pa_level_max_index(...) SpiritRadioSetPALevelMaxIndex(__VA_ARGS__) +#define st_lib_spirit_radio_set_xtal_frequency(...) SpiritRadioSetXtalFrequency(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* SPIRIT_Timer.h */ +#include "SPIRIT_Timer.h" + +#define st_lib_spirit_timer_set_rx_timeout_stop_condition(...) SpiritTimerSetRxTimeoutStopCondition(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* SPIRIT_Types.h */ +#include "SPIRIT_Types.h" + +#define st_lib_spirit_bool SpiritBool +#define st_lib_spirit_status SpiritStatus +#define st_lib_spirit_flag_status SpiritFlagStatus + +#define st_lib_spirit_refresh_status(...) SpiritRefreshStatus(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* stm32l152xe.h */ +#include "stm32l152xe.h" + +#define st_lib_irq_n_type IRQn_Type +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* stm32l1xx.h */ +#include "stm32l1xx.h" + +#define st_lib_flag_status FlagStatus +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* stm32l1xx_hal_cortex.h */ +#include "stm32l1xx_hal_cortex.h" + +#define st_lib_hal_nvic_enable_irq(...) HAL_NVIC_EnableIRQ(__VA_ARGS__) +#define st_lib_hal_nvic_set_priority(...) HAL_NVIC_SetPriority(__VA_ARGS__) +#define st_lib_hal_systick_clk_source_config(...) HAL_SYSTICK_CLKSourceConfig(__VA_ARGS__) +#define st_lib_hal_systick_config(...) HAL_SYSTICK_Config(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* stm32l1xx_hal_rcc.h */ +#include "stm32l1xx_hal_rcc.h" + +#define st_lib_tim2_clk_enable(...) __TIM2_CLK_ENABLE(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* stm32l1xx_hal_spi.h */ +#include "stm32l1xx_hal_spi.h" + +#define st_lib_spi_handle_typedef SPI_HandleTypeDef + +#define st_lib_hal_spi_get_flag(...) __HAL_SPI_GET_FLAG(__VA_ARGS__) +#define st_lib_hal_spi_transmit_receive(...) HAL_SPI_TransmitReceive(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* stm32l1xx_hal_tim.h */ +#include "stm32l1xx_hal_tim.h" + +#define st_lib_tim_handle_typedef TIM_HandleTypeDef +#define st_lib_tim_clock_config_typedef TIM_ClockConfigTypeDef +#define st_lib_tim_oc_init_typedef TIM_OC_InitTypeDef + +#define st_lib_hal_tim_base_init(...) HAL_TIM_Base_Init(__VA_ARGS__) +#define st_lib_hal_tim_base_start_it(...) HAL_TIM_Base_Start_IT(__VA_ARGS__) +#define st_lib_hal_tim_config_clock_source(...) HAL_TIM_ConfigClockSource(__VA_ARGS__) +#define st_lib_hal_tim_clear_flag(...) __HAL_TIM_CLEAR_FLAG(__VA_ARGS__) +#define st_lib_hal_tim_clear_it(...) __HAL_TIM_CLEAR_IT(__VA_ARGS__) +#define st_lib_hal_tim_enable(...) __HAL_TIM_ENABLE(__VA_ARGS__) +#define st_lib_hal_tim_enable_it(...) __HAL_TIM_ENABLE_IT(__VA_ARGS__) +#define st_lib_hal_tim_oc_init(...) HAL_TIM_OC_Init(__VA_ARGS__) +#define st_lib_hal_tim_oc_config_channel(...) HAL_TIM_OC_ConfigChannel(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* stm32l1xx_hal_uart.h */ +#include "stm32l1xx_hal_uart.h" + +#define st_lib_uart_handle_typedef UART_HandleTypeDef + +#define st_lib_hal_uart_enable_it(...) __HAL_UART_ENABLE_IT(__VA_ARGS__) +#define st_lib_hal_uart_init(...) HAL_UART_Init(__VA_ARGS__) +#define st_lib_hal_uart_receive(...) HAL_UART_Receive(__VA_ARGS__) +#define st_lib_hal_uart_receive_it(...) HAL_UART_Receive_IT(__VA_ARGS__) +#define st_lib_hal_uart_rx_cplt_callback(...) HAL_UART_RxCpltCallback(__VA_ARGS__) +#define st_lib_hal_uart_transmit(...) HAL_UART_Transmit(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* stm32l1xx_nucleo.h */ +#include "stm32l1xx_nucleo.h" + +#define st_lib_gpio_typedef GPIO_TypeDef +#define st_lib_gpio_port GPIO_PORT +#define st_lib_gpio_pin GPIO_PIN + +#define st_lib_bsp_led_init(...) BSP_LED_Init(__VA_ARGS__) +#define st_lib_bsp_led_off(...) BSP_LED_Off(__VA_ARGS__) +#define st_lib_bsp_led_on(...) BSP_LED_On(__VA_ARGS__) +#define st_lib_bsp_pb_init(...) BSP_PB_Init(__VA_ARGS__) +#define st_lib_bsp_pb_get_state(...) BSP_PB_GetState(__VA_ARGS__) +#define st_lib_hal_gpio_read_pin(...) HAL_GPIO_ReadPin(__VA_ARGS__) +#define st_lib_hal_gpio_write_pin(...) HAL_GPIO_WritePin(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +#ifdef X_NUCLEO_IKS01A1 +/*---------------------------------------------------------------------------*/ +/* x_nucleo_iks01a1.h */ +#include "x_nucleo_iks01a1.h" + +#define st_lib_axes_raw_typedef AxesRaw_TypeDef +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* x_nucleo_iks01a1_hum_temp.h */ +#include "x_nucleo_iks01a1_hum_temp.h" + +#define st_lib_bsp_hum_temp_is_initialized(...) BSP_HUM_TEMP_isInitialized(__VA_ARGS__) +#define st_lib_bsp_hum_temp_init(...) BSP_HUM_TEMP_Init(__VA_ARGS__) +#define st_lib_bsp_hum_temp_get_humidity(...) BSP_HUM_TEMP_GetHumidity(__VA_ARGS__) +#define st_lib_bsp_hum_temp_get_temperature(...) BSP_HUM_TEMP_GetTemperature(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* x_nucleo_iks01a1_imu_6axes.h */ +#include "x_nucleo_iks01a1_imu_6axes.h" + +#define st_lib_bsp_imu_6axes_is_initialized(...) BSP_IMU_6AXES_isInitialized(__VA_ARGS__) +#define st_lib_bsp_imu_6axes_init(...) BSP_IMU_6AXES_Init(__VA_ARGS__) +#define st_lib_bsp_imu_6axes_g_get_axes_raw(...) BSP_IMU_6AXES_G_GetAxesRaw(__VA_ARGS__) +#define st_lib_bsp_imu_6axes_x_get_axes_raw(...) BSP_IMU_6AXES_X_GetAxesRaw(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* x_nucleo_iks01a1_magneto.h */ +#include "x_nucleo_iks01a1_magneto.h" + +#define st_lib_bsp_magneto_m_get_axes_raw(...) BSP_MAGNETO_M_GetAxesRaw(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* x_nucleo_iks01a1_pressure.h */ +#include "x_nucleo_iks01a1_pressure.h" + +#define st_lib_bsp_pressure_init(...) BSP_PRESSURE_Init(__VA_ARGS__) +#define st_lib_bsp_pressure_get_pressure(...) BSP_PRESSURE_GetPressure(__VA_ARGS__) +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +#endif /*X_NUCLEO_IKS01A1*/ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +#endif /*ST_LIB_H_*/ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/stm32nucleo-spirit1/stm32cube-lib b/platform/stm32nucleo-spirit1/stm32cube-lib new file mode 160000 index 000000000..34e784ff3 --- /dev/null +++ b/platform/stm32nucleo-spirit1/stm32cube-lib @@ -0,0 +1 @@ +Subproject commit 34e784ff39a5dc4da288ce696235f41b1db4bf5c diff --git a/platform/stm32nucleo-spirit1/stm32l-spirit1-config.h b/platform/stm32nucleo-spirit1/stm32l-spirit1-config.h new file mode 100644 index 000000000..77ff95ca6 --- /dev/null +++ b/platform/stm32nucleo-spirit1/stm32l-spirit1-config.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*----------------------------------------------------------------------------*/ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L_SPIRIT1_CONFIG_H +#define __STM32L_SPIRIT1_CONFIG_H + +/* Includes ------------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* Define the STM32F10x hardware depending on the used evaluation board */ +#ifdef USE_STM3210B_EVAL +#define USB_DISCONNECT GPIOD +#define USB_DISCONNECT_PIN GPIO_PIN_9 +#define RCC_APB2Periph_GPIO_DISCONNECT RCC_APB2Periph_GPIOD +#define EVAL_COM1_IRQHandler USART1_IRQHandler + +#elif defined(USE_STM3210E_EVAL) +#define USB_DISCONNECT GPIOB +#define USB_DISCONNECT_PIN GPIO_PIN_14 +#define RCC_APB2Periph_GPIO_DISCONNECT RCC_APB2Periph_GPIOB +#define EVAL_COM1_IRQHandler USART1_IRQHandler + +#elif defined(USE_STM3210C_EVAL) +#define USB_DISCONNECT 0 +#define USB_DISCONNECT_PIN 0 +#define RCC_APB2Periph_GPIO_DISCONNECT 0 +#define EVAL_COM1_IRQHandler USART2_IRQHandler + +#elif defined(USE_STM32L152_EVAL) || defined(USE_STM32L152D_EVAL) +/* + For STM32L15xx devices it is possible to use the internal USB pullup + controlled by register SYSCFG_PMC (refer to RM0038 reference manual for + more details). + It is also possible to use external pullup (and disable the internal pullup) + by setting the define USB_USE_EXTERNAL_PULLUP in file platform_config.h + and configuring the right pin to be used for the external pull up configuration. + To have more details on how to use an external pull up, please refer to + STM3210E-EVAL evaluation board manuals. + */ +/* Uncomment the following define to use an external pull up instead of the + integrated STM32L15xx internal pull up. In this case make sure to set up + correctly the external required hardware and the GPIO defines below.*/ +/* #define USB_USE_EXTERNAL_PULLUP */ + +#if !defined(USB_USE_EXTERNAL_PULLUP) +#define STM32L15_USB_CONNECT SYSCFG_USBPuCmd(ENABLE) +#define STM32L15_USB_DISCONNECT SYSCFG_USBPuCmd(DISABLE) + +#elif defined(USB_USE_EXTERNAL_PULLUP) +/* PA0 is chosen just as illustrating example, you should modify the defines + below according to your hardware configuration. */ +#define USB_DISCONNECT GPIOA +#define USB_DISCONNECT_PIN GPIO_PIN_0 +#define RCC_AHBPeriph_GPIO_DISCONNECT RCC_AHBPeriph_GPIOA +#define STM32L15_USB_CONNECT GPIO_ResetBits(USB_DISCONNECT, USB_DISCONNECT_PIN) +#define STM32L15_USB_DISCONNECT GPIO_SetBits(USB_DISCONNECT, USB_DISCONNECT_PIN) +#endif /* USB_USE_EXTERNAL_PULLUP */ + +#ifdef USE_STM32L152_EVAL +#define EVAL_COM1_IRQHandler USART2_IRQHandler +#elif defined(USE_STM32L152D_EVAL) +#define EVAL_COM1_IRQHandler USART1_IRQHandler +#endif /*USE_STM32L152_EVAL*/ + +#endif /* USE_STM3210B_EVAL */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +#endif /* __STM32L_SPIRIT1_CONFIG_H */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/stm32nucleo-spirit1/uart-msg.c b/platform/stm32nucleo-spirit1/uart-msg.c new file mode 100644 index 000000000..ebb703785 --- /dev/null +++ b/platform/stm32nucleo-spirit1/uart-msg.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2012, STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/leds.h" +#include "stm32l1xx_nucleo.h" +#include "platform-conf.h" +#include +#include "dev/slip.h" +#include "hw-config.h" +#include "stm32l1xx_hal.h" +#include "st-lib.h" +/*---------------------------------------------------------------------------*/ +void uart_send_msg(char *); +extern st_lib_uart_handle_typedef st_lib_uart_handle; +/*---------------------------------------------------------------------------*/ +static unsigned char databyte[1] = { 0 }; +/*---------------------------------------------------------------------------*/ +/** + * @brief Rx Transfer completed callbacks. + * @param huart: Pointer to a st_lib_uart_handle_typedef structure that contains + * the configuration information for the specified UART module. + * @retval None + */ +void +st_lib_hal_uart_rx_cplt_callback(st_lib_uart_handle_typedef *huart) +{ + slip_input_byte(databyte[0]); + st_lib_hal_uart_receive_it(&st_lib_uart_handle, databyte, 1); +} +/*---------------------------------------------------------------------------*/ +void +uart1_set_input(int (*input)(unsigned char c)) +{ + st_lib_hal_uart_receive_it(&st_lib_uart_handle, databyte, 1); +} +/*--------------------------------------------------------------------------*/ +void +slip_arch_init(unsigned long ubr) +{ + st_lib_hal_uart_enable_it(&st_lib_uart_handle, UART_IT_RXNE); + /* uart1_set_input(slip_input_byte); */ +} +/*--------------------------------------------------------------------------*/ +void +slip_arch_writeb(unsigned char c) +{ + uart_send_msg(&c); +} +/*--------------------------------------------------------------------------*/ + +/** + * @brief Send a message via UART + * @param msg the pointer to the message to be sent + * @retval None + */ +void +uart_send_msg(char *msg) +{ + st_lib_hal_uart_transmit(&st_lib_uart_handle, (uint8_t *)msg, 1, 5000); +} +/*--------------------------------------------------------------------------*/ diff --git a/platform/stm32test/contiki-conf.h b/platform/stm32test/contiki-conf.h index e45f00d69..534f0f441 100644 --- a/platform/stm32test/contiki-conf.h +++ b/platform/stm32test/contiki-conf.h @@ -6,7 +6,7 @@ #define CCIF #define CLIF -#define WITH_UIP 1 +#define NETSTACK_CONF_WITH_IPV4 1 #define WITH_ASCII 1 #define CLOCK_CONF_SECOND 100 diff --git a/platform/win32/Makefile.win32 b/platform/win32/Makefile.win32 index f8bf088ea..5f0b618d4 100644 --- a/platform/win32/Makefile.win32 +++ b/platform/win32/Makefile.win32 @@ -41,7 +41,7 @@ CONTIKI_TARGET_SOURCEFILES = contiki-main.c clock.c cfs-win32-dir.c ctk-console. CONTIKI_SOURCEFILES += $(CTK) cfs-posix.c ctk-conio.c wpcap.c wpcap-drv.c \ $(CONTIKI_TARGET_SOURCEFILES) -MODULES += core/ctk core/net/ip core/net/ipv4 core/net/ipv6 +MODULES += core/ctk # Define the CPU directory diff --git a/platform/win32/contiki-conf.h b/platform/win32/contiki-conf.h index 41d4b1f08..fbdd93d5c 100644 --- a/platform/win32/contiki-conf.h +++ b/platform/win32/contiki-conf.h @@ -6,8 +6,7 @@ #endif #define CC_CONF_REGISTER_ARGS 1 -#define CC_CONF_FASTCALL __fastcall -#define CC_CONF_INLINE __inline +#define CC_CONF_INLINE __inline #define ARCH_DOESNT_NEED_ALIGNED_STRUCTS 1 @@ -56,16 +55,13 @@ typedef long s32_t; typedef unsigned short uip_stats_t; -#define UIP_CONF_MAX_CONNECTIONS 40 -#define UIP_CONF_MAX_LISTENPORTS 40 #define UIP_CONF_LLH_LEN 14 #define UIP_CONF_BUFFER_SIZE 1514 -#define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN #define UIP_CONF_TCP_SPLIT 1 #define UIP_CONF_LOGGING 1 #define UIP_CONF_UDP_CHECKSUMS 1 -#if UIP_CONF_IPV6 #define UIP_CONF_IP_FORWARD 0 +#if NETSTACK_CONF_WITH_IPV6 #define NBR_TABLE_CONF_MAX_NEIGHBORS 100 #define UIP_CONF_DS6_DEFRT_NBU 2 #define UIP_CONF_DS6_PREFIX_NBU 5 @@ -73,10 +69,10 @@ typedef unsigned short uip_stats_t; #define UIP_CONF_DS6_ADDR_NBU 10 #define UIP_CONF_DS6_MADDR_NBU 0 //VC++ does not allow zero length arrays #define UIP_CONF_DS6_AADDR_NBU 0 //inside a struct -#else -#define UIP_CONF_IP_FORWARD 1 #endif +#define RESOLV_CONF_SUPPORTS_MDNS 0 +#define RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION 0 #include #define ctk_arch_isprint isprint @@ -174,8 +170,9 @@ typedef unsigned short uip_stats_t; #define SHELL_GUI_CONF_YSIZE 30 +#define TELNETD_CONF_MAX_IDLE_TIME 300 #ifdef PLATFORM_BUILD -#define TELNETD_CONF_GUI 1 +#define TELNETD_CONF_GUI 1 #endif /* PLATFORM_BUILD */ diff --git a/platform/win32/contiki-main.c b/platform/win32/contiki-main.c index f1ed10f25..0472bfbcc 100644 --- a/platform/win32/contiki-main.c +++ b/platform/win32/contiki-main.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "contiki-net.h" @@ -101,6 +102,8 @@ char **contiki_argv; int main(int argc, char **argv) { + _set_fmode(O_BINARY); + contiki_argc = argc; contiki_argv = argv; @@ -124,7 +127,7 @@ main(int argc, char **argv) autostart_start(autostart_processes); -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 { uip_ipaddr_t addr; uip_ipaddr(&addr, 192,168,0,111); @@ -140,11 +143,11 @@ main(int argc, char **argv) log_message("Def. Router: ", inet_ntoa(*(struct in_addr*)&addr)); uip_ipaddr(&addr, 192,168,0,1); - resolv_conf(&addr); + uip_nameserver_update(&addr, UIP_NAMESERVER_INFINITE_LIFETIME); log_message("DNS Server: ", inet_ntoa(*(struct in_addr*)&addr)); } -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ #if !UIP_CONF_IPV6_RPL #ifdef HARD_CODED_ADDRESS diff --git a/platform/win32/loader/dll-loader.c b/platform/win32/loader/dll-loader.c index eb252947e..4a2393425 100644 --- a/platform/win32/loader/dll-loader.c +++ b/platform/win32/loader/dll-loader.c @@ -62,7 +62,7 @@ dll_loader_load(char *name, char *arg) /* Start the process. */ debug_printf("Starting '%s'\n", (**(struct process ***)&p)->name); - process_start(**(struct process ***)&p, arg); + process_start(**(struct process ***)&p, (void *)arg); return LOADER_OK; } diff --git a/platform/wismote/Makefile.wismote b/platform/wismote/Makefile.wismote index ea6547371..fd8da1d21 100644 --- a/platform/wismote/Makefile.wismote +++ b/platform/wismote/Makefile.wismote @@ -7,7 +7,7 @@ CONTIKI_TARGET_SOURCEFILES += contiki-wismote-platform.c \ sky-sensors.c uip-ipchksum.c \ uart1.c slip_uart1.c uart1-putchar.c -ARCH=spi.c i2c.c node-id.c sensors.c cfs-coffee.c sht15.c \ +ARCH=spi.c xmem.c i2c.c node-id.c sensors.c cfs-coffee.c sht15.c \ cc2520.c cc2520-arch.c cc2520-arch-sfd.c \ sky-sensors.c uip-ipchksum.c \ uart1.c slip_uart1.c uart1-putchar.c @@ -18,19 +18,6 @@ ifndef CONTIKI_TARGET_MAIN CONTIKI_TARGET_MAIN = contiki-wismote-main.c endif -ifeq ($(UIP_CONF_IPV6),1) -CFLAGS += -DWITH_UIP6=1 -endif - -ifndef IAR - ifneq (,$(findstring 4.7.,$(shell msp430-gcc -dumpversion))) - TARGET_MEMORY_MODEL ?= medium - CFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) - CFLAGS += -ffunction-sections -fdata-sections -mcode-region=far - LDFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) -Wl,-gc-sections -endif -endif - ifdef IAR CFLAGS += -D__MSP430F5437__=1 -e --vla -Ohz --multiplier=32 --multiplier_location=4C0 --hw_workaround=CPU40 --core=430X --double=32 else @@ -40,6 +27,10 @@ endif CONTIKI_TARGET_SOURCEFILES += $(ARCH) $(UIPDRIVERS) MCU=msp430f5437 + +# Platform has a MSP430X MCU with 20-bit support +CPU_HAS_MSP430X=1 + include $(CONTIKI)/cpu/msp430/Makefile.msp430 ifdef IAR @@ -59,6 +50,7 @@ contiki-$(TARGET).a: ${addprefix $(OBJECTDIR)/,symbols.o} %.upload-clean: %.hex msp430flasher -n msp430x5437 -w $< -v -z [VCC] -MODULES += core/net core/net/ip core/net/ipv6 core/net/ipv4 core/net/mac \ - core/net/rime core/net/mac/contikimac core/net/rpl \ +MODULES += core/net core/net/mac \ + core/net/mac/contikimac \ + core/net/llsec \ dev/cc2520 dev/sht11 diff --git a/platform/wismote/apps/burn-nodeid.c b/platform/wismote/apps/burn-nodeid.c new file mode 100644 index 000000000..280797247 --- /dev/null +++ b/platform/wismote/apps/burn-nodeid.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * A program for burning a node ID into the external flash of a Wismote. + * \author + * Adam Dunkels + */ + +#include "dev/leds.h" +#include "dev/watchdog.h" +#include "sys/node-id.h" +#include "contiki.h" +#include "sys/etimer.h" + +#include + +static struct etimer etimer; + +PROCESS(burn_process, "Burn node id"); +AUTOSTART_PROCESSES(&burn_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(burn_process, ev, data) +{ + PROCESS_BEGIN(); + + etimer_set(&etimer, 5 * CLOCK_SECOND); + PROCESS_WAIT_UNTIL(etimer_expired(&etimer)); + + watchdog_stop(); + leds_on(LEDS_RED); +#if NODEID + printf("Burning node id %d\n", NODEID); + node_id_burn(NODEID); + leds_on(LEDS_BLUE); + node_id_restore(); + printf("Restored node id %d\n", node_id); +#else +#error "burn-nodeid must be compiled with nodeid=" + node_id_restore(); + printf("Restored node id %d\n", node_id); +#endif + leds_off(LEDS_RED + LEDS_BLUE); + watchdog_start(); + while(1) { + PROCESS_WAIT_EVENT(); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/wismote/contiki-conf.h b/platform/wismote/contiki-conf.h index 12b2396de..f7150c5ff 100644 --- a/platform/wismote/contiki-conf.h +++ b/platform/wismote/contiki-conf.h @@ -6,13 +6,11 @@ #include "platform-conf.h" #ifndef NETSTACK_CONF_MAC -/* #define NETSTACK_CONF_MAC csma_driver */ -#define NETSTACK_CONF_MAC nullmac_driver +#define NETSTACK_CONF_MAC csma_driver #endif /* NETSTACK_CONF_MAC */ #ifndef NETSTACK_CONF_RDC -/* #define NETSTACK_CONF_RDC contikimac_driver */ -#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_RDC contikimac_driver #endif /* NETSTACK_CONF_RDC */ #ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE @@ -33,7 +31,7 @@ #define NULLRDC_CONF_802154_AUTOACK 1 -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 /* Network setup for IPv6 */ #define NETSTACK_CONF_NETWORK sicslowpan_driver @@ -42,7 +40,6 @@ larger than a specified size, if no ContikiMAC header should be used. */ #define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63 -#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0 #define CXMAC_CONF_ANNOUNCEMENTS 0 #define XMAC_CONF_ANNOUNCEMENTS 0 @@ -51,7 +48,7 @@ #define QUEUEBUF_CONF_NUM 8 #endif -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ /* Network setup for non-IPv6 (rime). */ @@ -84,7 +81,7 @@ #define CC2520_CONF_SFD_TIMESTAMPS 1 #endif /* TIMESYNCH_CONF_ENABLED */ -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define PACKETBUF_CONF_ATTRS_INLINE 1 @@ -110,7 +107,6 @@ #define ELFLOADER_CONF_TEXTMEMORY_SIZE 0x800 #endif /* ELFLOADER_CONF_TEXTMEMORY_SIZE */ - #define AODV_COMPLIANCE #define AODV_NUM_RT_ENTRIES 32 @@ -120,7 +116,9 @@ #define PROCESS_CONF_STATS 1 /*#define PROCESS_CONF_FASTPOLL 4*/ -#ifdef WITH_UIP6 +#define UART1_CONF_RX_WITH_DMA 0 + +#ifdef NETSTACK_CONF_WITH_IPV6 #define LINKADDR_CONF_SIZE 8 @@ -128,9 +126,6 @@ #define UIP_CONF_LLH_LEN 0 #define UIP_CONF_ROUTER 1 -#ifndef UIP_CONF_IPV6_RPL -#define UIP_CONF_IPV6_RPL 1 -#endif /* UIP_CONF_IPV6_RPL */ /* configure number of neighbors and routes */ #ifndef NBR_TABLE_CONF_MAX_NEIGHBORS @@ -140,41 +135,32 @@ #define UIP_CONF_MAX_ROUTES 30 #endif /* UIP_CONF_MAX_ROUTES */ -#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_RETRANS_TIMER 10000 -#define UIP_CONF_IPV6 1 +#define NETSTACK_CONF_WITH_IPV6 1 #ifndef UIP_CONF_IPV6_QUEUE_PKT #define UIP_CONF_IPV6_QUEUE_PKT 0 #endif /* UIP_CONF_IPV6_QUEUE_PKT */ #define UIP_CONF_IPV6_CHECKS 1 #define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_NETIF_MAX_ADDRESSES 3 -#define UIP_CONF_ND6_MAX_PREFIXES 3 -#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_IP_FORWARD 0 #ifndef UIP_CONF_BUFFER_SIZE -#define UIP_CONF_BUFFER_SIZE 240 +#define UIP_CONF_BUFFER_SIZE 240 #endif -#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 -#define SICSLOWPAN_CONF_COMPRESSION_HC1 1 -#define SICSLOWPAN_CONF_COMPRESSION_HC01 2 #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #ifndef SICSLOWPAN_CONF_FRAG #define SICSLOWPAN_CONF_FRAG 1 #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ -#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_IP_FORWARD 1 #define UIP_CONF_BUFFER_SIZE 108 -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_ICMP_DEST_UNREACH 1 @@ -199,8 +185,6 @@ #define UIP_CONF_TCP_SPLIT 0 - - /* include the project config */ /* PROJECT_CONF_H might be defined in the project Makefile */ #ifdef PROJECT_CONF_H diff --git a/platform/wismote/contiki-wismote-main.c b/platform/wismote/contiki-wismote-main.c index ab8522500..f2a41a48e 100644 --- a/platform/wismote/contiki-wismote-main.c +++ b/platform/wismote/contiki-wismote-main.c @@ -44,9 +44,9 @@ #include "net/netstack.h" #include "net/mac/frame802154.h" -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 #include "net/ipv6/uip-ds6.h" -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #include "net/rime/rime.h" @@ -66,26 +66,26 @@ extern const struct uip_router UIP_ROUTER_MODULE; #endif /* UIP_CONF_ROUTER */ -#ifndef WITH_UIP -#define WITH_UIP 0 +#ifndef NETSTACK_CONF_WITH_IPV4 +#define NETSTACK_CONF_WITH_IPV4 0 #endif -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 #include "net/ip/uip.h" #include "net/ipv4/uip-fw.h" -#include "net/uip-fw-drv.h" +#include "net/ipv4/uip-fw-drv.h" #include "net/ipv4/uip-over-mesh.h" static struct uip_fw_netif slipif = {UIP_FW_NETIF(192,168,1,2, 255,255,255,255, slip_send)}; static struct uip_fw_netif meshif = {UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)}; -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ #define UIP_OVER_MESH_CHANNEL 8 -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 static uint8_t is_gateway; -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ #ifdef EXPERIMENT_SETUP #include "experiment-setup.h" @@ -133,7 +133,7 @@ set_rime_addr(void) memset(&n_addr, 0, sizeof(linkaddr_t)); // Set node address -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 //memcpy(addr.u8, ds2411_id, sizeof(addr.u8)); n_addr.u8[7] = node_id & 0xff; n_addr.u8[6] = node_id >> 8; @@ -172,7 +172,7 @@ print_processes(struct process * const processes[]) } #endif /* !PROCESS_CONF_NO_PROCESS_NAMES */ /*--------------------------------------------------------------------------*/ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 static void set_gateway(void) { @@ -187,7 +187,7 @@ set_gateway(void) is_gateway = 1; } } -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ /*---------------------------------------------------------------------------*/ int main(int argc, char **argv) @@ -206,9 +206,9 @@ main(int argc, char **argv) uart1_init(115200); /* Must come before first printf */ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 slip_arch_init(115200); -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ clock_wait(1); @@ -221,7 +221,7 @@ main(int argc, char **argv) //ds2411_id[2] &= 0xfe; leds_on(LEDS_BLUE); - //xmem_init(); + xmem_init(); leds_off(LEDS_RED); rtimer_init(); @@ -229,10 +229,12 @@ main(int argc, char **argv) * Hardware initialization done! */ - node_id = NODE_ID; - /* Restore node id if such has been stored in external mem */ - //node_id_restore(); + node_id_restore(); + + if(!node_id) { + node_id = NODE_ID; + } /* for setting "hardcoded" IEEE 802.15.4 MAC addresses */ #ifdef IEEE_802154_MAC_ADDRESS @@ -257,6 +259,7 @@ main(int argc, char **argv) init_platform(); set_rime_addr(); + random_init(linkaddr_node_addr.u8[LINKADDR_SIZE-2] + linkaddr_node_addr.u8[LINKADDR_SIZE-1]); cc2520_init(); { @@ -283,7 +286,7 @@ main(int argc, char **argv) printf("Node id is not set.\n"); } -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 /* memcpy(&uip_lladdr.addr, ds2411_id, sizeof(uip_lladdr.addr)); */ memcpy(&uip_lladdr.addr, linkaddr_node_addr.u8, UIP_LLADDR_LEN > LINKADDR_SIZE ? LINKADDR_SIZE : UIP_LLADDR_LEN); @@ -321,7 +324,7 @@ main(int argc, char **argv) if(!UIP_CONF_IPV6_RPL) { uip_ipaddr_t ipaddr; int i; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE); printf("Tentative global IPv6 address "); @@ -333,7 +336,7 @@ main(int argc, char **argv) ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]); } -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ NETSTACK_RDC.init(); NETSTACK_MAC.init(); @@ -344,9 +347,9 @@ main(int argc, char **argv) CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0? 1: NETSTACK_RDC.channel_check_interval()), RF_CHANNEL); -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ -#if !WITH_UIP && !WITH_UIP6 +#if !NETSTACK_CONF_WITH_IPV4 && !NETSTACK_CONF_WITH_IPV6 uart1_set_input(serial_line_input_byte); serial_line_init(); #endif @@ -358,7 +361,7 @@ main(int argc, char **argv) timesynch_set_authority_level((linkaddr_node_addr.u8[0] << 4) + 16); #endif /* TIMESYNCH_CONF_ENABLED */ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 process_start(&tcpip_process, NULL); process_start(&uip_fw_process, NULL); /* Start IP output */ process_start(&slip_process, NULL); @@ -385,7 +388,7 @@ main(int argc, char **argv) printf("uIP started with IP address %d.%d.%d.%d\n", uip_ipaddr_to_quad(&hostaddr)); } -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ energest_init(); ENERGEST_ON(ENERGEST_TYPE_CPU); @@ -424,8 +427,7 @@ main(int argc, char **argv) static unsigned long irq_energest = 0; /* Re-enable interrupts and go to sleep atomically. */ - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* We only want to measure the processing done in IRQs when we are asleep, so we discard the processing time done when we were awake. */ @@ -444,8 +446,7 @@ main(int argc, char **argv) irq_energest = energest_type_time(ENERGEST_TYPE_IRQ); eint(); watchdog_start(); - ENERGEST_OFF(ENERGEST_TYPE_LPM); - ENERGEST_ON(ENERGEST_TYPE_CPU); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } } } diff --git a/platform/wismote/dev/acc-sensor.c b/platform/wismote/dev/acc-sensor.c index 15ea5fd82..8ee512aa3 100644 --- a/platform/wismote/dev/acc-sensor.c +++ b/platform/wismote/dev/acc-sensor.c @@ -42,8 +42,8 @@ static void activate(void) { /* This assumes that some other sensor system already did setup the ADC - /* (in the case of the sky platform it is sensors_light_init that does it) - + * (in the case of the sky platform it is sensors_light_init that does it) */ + #if 0 P6SEL |= 0x70; P6DIR = 0x00; P6OUT = 0x00; @@ -52,37 +52,40 @@ activate(void) P2OUT |= 0x48; - /* stop converting immediately + /* stop converting immediately */ ADC12CTL0 &= ~ENC; ADC12CTL1 &= ~CONSEQ_3; /* Configure ADC12_2 to sample channel 11 (voltage) and use - /* the Vref+ as reference (SREF_1) since it is a stable reference + * the Vref+ as reference (SREF_1) since it is a stable reference */ ADC12MCTL2 = (INCH_4 + SREF_1); ADC12MCTL3 = (INCH_5 + SREF_1); ADC12MCTL4 = (INCH_6 + SREF_1); - /* internal temperature can be read as value(3) + /* internal temperature can be read as value(3) */ ADC12MCTL5 = (INCH_10 + SREF_1); ADC12CTL1 |= CONSEQ_3; ADC12CTL0 |= ENC | ADC12SC; - /* Irq_adc12_activate(&acc_sensor, 6, (INCH_11 + SREF_1)); */ + Irq_adc12_activate(&acc_sensor, 6, (INCH_11 + SREF_1)); + #endif /* 0 */ active = 1; } /*---------------------------------------------------------------------------*/ static void deactivate(void) { - /* irq_adc12_deactivate(&acc_sensor, 6); - acc_value = 0;*/ + #if 0 + irq_adc12_deactivate(&acc_sensor, 6); + acc_value = 0; + #endif /* 0 */ active = 0; } /*---------------------------------------------------------------------------*/ static int value(int type) { -/* + #if 0 switch(type) { case 0: return ADC12MEM2; @@ -92,7 +95,8 @@ value(int type) return ADC12MEM4; case 3: return ADC12MEM5; - }*/ + } + #endif /* 0 */ return 0; } /*---------------------------------------------------------------------------*/ @@ -122,5 +126,4 @@ status(int type) } } /*---------------------------------------------------------------------------*/ -SENSORS_SENSOR(acc_sensor, ACC_SENSOR, - value, configure, status); +SENSORS_SENSOR(acc_sensor, ACC_SENSOR, value, configure, status); diff --git a/platform/wismote/dev/ext-sensor.c b/platform/wismote/dev/ext-sensor.c index a957e5232..587fb56e7 100644 --- a/platform/wismote/dev/ext-sensor.c +++ b/platform/wismote/dev/ext-sensor.c @@ -43,8 +43,10 @@ static uint8_t active; static int value(int type) { - /* ADC0 corresponds to the port under the logo, ADC1 to the port over the logo, - ADC2 and ADC3 corresponds to port on the JCreate bottom expansion port) + #if 0 + /* ADC0 corresponds to the port under the logo, + * ADC1 to the port over the logo, + * ADC2 and ADC3 corresponds to port on the JCreate bottom expansion port) */ switch(type) { case ADC0: return ADC12MEM6; @@ -54,7 +56,8 @@ value(int type) return ADC12MEM8; case ADC3: return ADC12MEM9; - }*/ + } + #endif /* 0 */ return 0; } /*---------------------------------------------------------------------------*/ @@ -77,16 +80,17 @@ configure(int type, int c) case SENSORS_ACTIVE: if(c) { if(!status(SENSORS_ACTIVE)) { - /* SREF_1 is Vref+ - /* MemReg6 == P6.0/A0 == port "under" logo + #if 0 + /* SREF_1 is Vref+ */ + /* MemReg6 == P6.0/A0 == port "under" logo */ ADC12MCTL6 = (INCH_0 + SREF_0); - /* MemReg7 == P6.1/A1 == port "over" logo + /* MemReg7 == P6.1/A1 == port "over" logo */ ADC12MCTL7 = (INCH_1 + SREF_0); - /* MemReg8 == P6.2/A2, bottom expansion port + /* MemReg8 == P6.2/A2, bottom expansion port */ ADC12MCTL8 = (INCH_2 + SREF_0); - /* MemReg9 == P6.1/A3, bottom expansion port, End Of (ADC-)Sequence + /* MemReg9 == P6.1/A3, bottom expansion port, End Of (ADC-)Sequence */ ADC12MCTL9 = (INCH_3 + SREF_0); - */ + #endif /* 0 */ sky_sensors_activate(0x0F); active = 1; } @@ -100,5 +104,4 @@ configure(int type, int c) } } /*---------------------------------------------------------------------------*/ -SENSORS_SENSOR(ext_sensor, "Ext", - value, configure, status); +SENSORS_SENSOR(ext_sensor, "Ext", value, configure, status); diff --git a/platform/wismote/dev/light.c b/platform/wismote/dev/light.c deleted file mode 100644 index be7d7540f..000000000 --- a/platform/wismote/dev/light.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -#include "contiki.h" -#include "dev/light.h" -#include - -/* - * Initialize periodic readings from the 2 photo diodes. The most - * recent readings will be stored in ADC internal registers/memory. - */ -void -sensors_light_init(void) -{ - P6SEL |= 0x30; - P6DIR = 0xff; - P6OUT = 0x00; - - /* Set up the ADC. */ - ADC12CTL0 = REF2_5V + SHT0_6 + SHT1_6 + MSC; // Setup ADC12, ref., sampling time - ADC12CTL1 = SHP + CONSEQ_3 + CSTARTADD_0; // Use sampling timer, repeat-sequenc-of-channels - - ADC12MCTL0 = (INCH_4 + SREF_0); // photodiode 1 (P64) - ADC12MCTL1 = (INCH_5 + SREF_0); // photodiode 2 (P65) - - ADC12CTL0 |= ADC12ON + REFON; - - ADC12CTL0 |= ENC; // enable conversion - ADC12CTL0 |= ADC12SC; // sample & convert -} - -/* Photosynthetically Active Radiation. */ -unsigned -sensors_light1(void) -{ - return ADC12MEM0; -} - -/* Total Solar Radiation. */ -unsigned -sensors_light2(void) -{ - return ADC12MEM1; -} - -/* - * Most of this information taken from - * http://www.moteiv.com/community/Getting_Data_from_Tmote_Sky%27s_Sensors - * - * The Photosynthetically Active Radiation (PAR) sensor as well as the - * Total Solar Radiation (TSR) sensor uses the 2.5V reference voltage - * to produce the raw ADC value. - - * The voltage across each sensor is: - * - * VsensorPAR = ADCValuePAR/4096 * Vref (1a) - * VsensorTSR = ADCValueTSR/4096 * Vref (1b) - * where Vref = 2.5V - * - * This voltage creates a current through a resistor R=100KOhm and this - * current has a linear relationship with the light intensity in Lux. - * IPAR = VsensorPAR / 100,000 (2a) - * ITSR = VsensorTSR / 100,000 (2b) - * - * S1087 (PAR) lx = 1e6 * IPAR * 1000 (3a) - * S1087-01 (TSR) lx = 1e5 * ITSR * 1000 (3b) - * - * lxPAR = 10e9 * ADCValuePAR *(1/4096)* Vref * 10e-5 or - * lxPAR = 3125* ADCvaluePAR / 512 - * and - * lxTSR = 10e8 * ADCValueTSR *(1/4096)* Vref * 10e-5 or - * lxTSR = 625* ADCvalueTSR / 1024 -*/ - -#if 0 -/* Photosynthetically Active Radiation in Lux units. */ -unsigned -sensors_light1_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM0; - - temp = (temp*3125)>> 9; - return (uint16_t)(temp & 0xFFFF); -} - -/* Total Solar Radiation in Lux units. */ -unsigned -sensors_light2_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM1; - - temp = (temp*625)>> 10; - return (uint16_t)(temp & 0xFFFF); -} -#endif diff --git a/platform/wismote/dev/xmem.c b/platform/wismote/dev/xmem.c index d4009f7b0..1e7da66af 100644 --- a/platform/wismote/dev/xmem.c +++ b/platform/wismote/dev/xmem.c @@ -32,13 +32,17 @@ * \file * Device driver for the ST M25P80 40MHz 1Mbyte external memory. * \author - * Bjrn Grnvall + * Björn Grönvall + * Sumankumar Panchal + * * * Data is written bit inverted (~-operator) to flash so that * unwritten data will read as zeros (UNIX style). */ + #include "contiki.h" +#include #include #include "dev/spi.h" @@ -46,7 +50,6 @@ #include "dev/watchdog.h" #if 0 -#include #define PRINTF(...) printf(__VA_ARGS__) #else #define PRINTF(...) do {} while (0) @@ -72,8 +75,7 @@ write_enable(void) s = splhigh(); SPI_FLASH_ENABLE(); - //FASTSPI_TX(SPI_FLASH_INS_WREN); - //SPI_WAITFORTx_ENDED(); + SPI_WRITE(SPI_FLASH_INS_WREN); SPI_FLASH_DISABLE(); splx(s); @@ -89,11 +91,10 @@ read_status_register(void) s = splhigh(); SPI_FLASH_ENABLE(); - //FASTSPI_TX(SPI_FLASH_INS_RDSR); - //SPI_WAITFORTx_ENDED(); + SPI_WRITE(SPI_FLASH_INS_RDSR); - //FASTSPI_CLEAR_RX(); - //FASTSPI_RX(u); + SPI_FLUSH(); + SPI_READ(u); SPI_FLASH_DISABLE(); splx(s); @@ -110,6 +111,7 @@ wait_ready(void) unsigned u; do { u = read_status_register(); + watchdog_periodic(); } while(u & 0x01); /* WIP=1, write in progress */ return u; } @@ -121,18 +123,18 @@ static void erase_sector(unsigned long offset) { int s; - wait_ready(); + wait_ready(); write_enable(); s = splhigh(); SPI_FLASH_ENABLE(); - //FASTSPI_TX(SPI_FLASH_INS_SE); - //FASTSPI_TX(offset >> 16); /* MSB */ - //FASTSPI_TX(offset >> 8); - //FASTSPI_TX(offset >> 0); /* LSB */ - //SPI_WAITFORTx_ENDED(); + SPI_WRITE_FAST(SPI_FLASH_INS_SE); + SPI_WRITE_FAST(offset >> 16); /* MSB */ + SPI_WRITE_FAST(offset >> 8); + SPI_WRITE_FAST(offset >> 0); /* LSB */ + SPI_WAITFORTx_ENDED(); SPI_FLASH_DISABLE(); splx(s); @@ -144,12 +146,20 @@ erase_sector(unsigned long offset) void xmem_init(void) { + int s; spi_init(); - P4DIR |= BV(FLASH_CS) | BV(FLASH_HOLD) | BV(FLASH_PWR); - P4OUT |= BV(FLASH_PWR); /* P4.3 Output, turn on power! */ + + P4DIR |= BIT0; + /* Release from Deep Power-down */ + s = splhigh(); + SPI_FLASH_ENABLE(); + SPI_WRITE_FAST(SPI_FLASH_INS_RES); + SPI_WAITFORTx_ENDED(); SPI_FLASH_DISABLE(); /* Unselect flash. */ + splx(s); + SPI_FLASH_UNHOLD(); } /*---------------------------------------------------------------------------*/ @@ -159,6 +169,7 @@ xmem_pread(void *_p, int size, unsigned long offset) unsigned char *p = _p; const unsigned char *end = p + size; int s; + wait_ready(); ENERGEST_ON(ENERGEST_TYPE_FLASH_READ); @@ -166,16 +177,16 @@ xmem_pread(void *_p, int size, unsigned long offset) s = splhigh(); SPI_FLASH_ENABLE(); - //FASTSPI_TX(SPI_FLASH_INS_READ); - //FASTSPI_TX(offset >> 16); /* MSB */ - //FASTSPI_TX(offset >> 8); - //FASTSPI_TX(offset >> 0); /* LSB */ - //SPI_WAITFORTx_ENDED(); + SPI_WRITE_FAST(SPI_FLASH_INS_READ); + SPI_WRITE_FAST(offset >> 16); /* MSB */ + SPI_WRITE_FAST(offset >> 8); + SPI_WRITE_FAST(offset >> 0); /* LSB */ + SPI_WAITFORTx_ENDED(); - //FASTSPI_CLEAR_RX(); + SPI_FLUSH(); for(; p < end; p++) { unsigned char u; - //FASTSPI_RX(u); + SPI_READ(u); *p = ~u; } @@ -187,28 +198,27 @@ xmem_pread(void *_p, int size, unsigned long offset) return size; } /*---------------------------------------------------------------------------*/ -static const char * +static const unsigned char * program_page(unsigned long offset, const unsigned char *p, int nbytes) { const unsigned char *end = p + nbytes; int s; wait_ready(); - write_enable(); s = splhigh(); SPI_FLASH_ENABLE(); - // FASTSPI_TX(SPI_FLASH_INS_PP); - //FASTSPI_TX(offset >> 16); /* MSB */ - //FASTSPI_TX(offset >> 8); - //FASTSPI_TX(offset >> 0); /* LSB */ + SPI_WRITE_FAST(SPI_FLASH_INS_PP); + SPI_WRITE_FAST(offset >> 16); /* MSB */ + SPI_WRITE_FAST(offset >> 8); + SPI_WRITE_FAST(offset >> 0); /* LSB */ for(; p < end; p++) { - //FASTSPI_TX(~*p); + SPI_WRITE_FAST(~*p); } - //SPI_WAITFORTx_ENDED(); + SPI_WAITFORTx_ENDED(); SPI_FLASH_DISABLE(); splx(s); @@ -224,7 +234,7 @@ xmem_pwrite(const void *_buf, int size, unsigned long addr) unsigned long i, next_page; ENERGEST_ON(ENERGEST_TYPE_FLASH_WRITE); - + for(i = addr; i < end;) { next_page = (i | 0xff) + 1; if(next_page > end) { @@ -254,14 +264,10 @@ xmem_erase(long size, unsigned long addr) return -1; } - watchdog_stop(); - for (; addr < end; addr += XMEM_ERASE_UNIT_SIZE) { erase_sector(addr); } - watchdog_start(); - return size; } /*---------------------------------------------------------------------------*/ diff --git a/platform/wismote/node-id.c b/platform/wismote/node-id.c index 994587c45..dcdabfa84 100644 --- a/platform/wismote/node-id.c +++ b/platform/wismote/node-id.c @@ -47,25 +47,25 @@ unsigned short node_id = 0; void node_id_restore(void) { - /* unsigned char buf[4]; */ - /* xmem_pread(buf, 4, NODE_ID_XMEM_OFFSET); */ - /* if(buf[0] == 0xad && */ - /* buf[1] == 0xde) { */ - /* node_id = (buf[2] << 8) | buf[3]; */ - /* } else { */ + unsigned char buf[4]; + xmem_pread(buf, 4, NODE_ID_XMEM_OFFSET); + if(buf[0] == 0xad && + buf[1] == 0xde) { + node_id = (buf[2] << 8) | buf[3]; + } else { node_id = 0; - /* } */ + } } /*---------------------------------------------------------------------------*/ void node_id_burn(unsigned short id) { - /* unsigned char buf[4]; */ - /* buf[0] = 0xad; */ - /* buf[1] = 0xde; */ - /* buf[2] = id >> 8; */ - /* buf[3] = id & 0xff; */ - //xmem_erase(XMEM_ERASE_UNIT_SIZE, NODE_ID_XMEM_OFFSET); - //xmem_pwrite(buf, 4, NODE_ID_XMEM_OFFSET); + unsigned char buf[4]; + buf[0] = 0xad; + buf[1] = 0xde; + buf[2] = id >> 8; + buf[3] = id & 0xff; + xmem_erase(XMEM_ERASE_UNIT_SIZE, NODE_ID_XMEM_OFFSET); + xmem_pwrite(buf, 4, NODE_ID_XMEM_OFFSET); } /*---------------------------------------------------------------------------*/ diff --git a/platform/wismote/platform-conf.h b/platform/wismote/platform-conf.h index 18fe67de5..e13ed62c0 100644 --- a/platform/wismote/platform-conf.h +++ b/platform/wismote/platform-conf.h @@ -124,8 +124,10 @@ typedef unsigned long off_t; /* Enable/disable flash access to the SPI bus (active low). */ -#define SPI_FLASH_ENABLE() //( P4OUT &= ~BV(FLASH_CS) ) -#define SPI_FLASH_DISABLE() //( P4OUT |= BV(FLASH_CS) ) + /* ENABLE CSn (active low) */ +#define SPI_FLASH_ENABLE() do{ UCB0CTL1 &= ~UCSWRST; clock_delay(5); P4OUT &= ~BIT0;clock_delay(5);}while(0) + /* DISABLE CSn (active low) */ +#define SPI_FLASH_DISABLE() do{clock_delay(5);UCB0CTL1 |= UCSWRST;clock_delay(1); P4OUT |= BIT0;clock_delay(5);}while(0) #define SPI_FLASH_HOLD() // ( P4OUT &= ~BV(FLASH_HOLD) ) #define SPI_FLASH_UNHOLD() //( P4OUT |= BV(FLASH_HOLD) ) diff --git a/platform/z1/Makefile.common b/platform/z1/Makefile.common index bf2eb95e9..642071bdc 100644 --- a/platform/z1/Makefile.common +++ b/platform/z1/Makefile.common @@ -1,3 +1,5 @@ +# Common Makefile between the Z1 and Z1SP + ifdef GCC CFLAGS+=-Os -g endif @@ -11,23 +13,19 @@ endif CLEAN += symbols.c symbols.h ARCH=msp430.c leds.c watchdog.c xmem.c \ - spi.c cc2420.c cc2420-aes.c cc2420-arch.c cc2420-arch-sfd.c\ + spi.c cc2420.c cc2420-arch.c cc2420-arch-sfd.c\ node-id.c sensors.c button-sensor.c cfs-coffee.c \ radio-sensor.c uart0.c uart0-putchar.c uip-ipchksum.c \ slip.c slip_uart0.c \ z1-phidgets.c sht11.c sht11-sensor.c light-sensor.c \ battery-sensor.c sky-sensors.c tmp102.c temperature-sensor.c light-ziglet.c \ - relay-phidget.c tlc59116.c + relay-phidget.c tlc59116.c sht25.c CONTIKI_TARGET_DIRS = . dev apps net ifndef CONTIKI_TARGET_MAIN CONTIKI_TARGET_MAIN = contiki-z1-main.c endif -ifeq ($(UIP_CONF_IPV6),1) -CFLAGS += -DWITH_UIP6=1 -endif - ifdef nodemac CFLAGS += -DMACID=$(nodemac) endif @@ -36,6 +34,10 @@ CONTIKI_TARGET_SOURCEFILES += $(ARCH) $(UIPDRIVERS) CONTIKI_TARGET_SOURCEFILES += i2cmaster.c adxl345.c MCU=msp430f2617 + +# Platform has a MSP430X MCU with 20-bit support +CPU_HAS_MSP430X=1 + include $(CONTIKI)/cpu/msp430/Makefile.msp430 # Add LDFLAGS after IAR_PATH is set @@ -55,34 +57,47 @@ ifeq ($(HOST_OS),Darwin) ifndef MOTELIST USBDEVPREFIX= SERIALDUMP = $(CONTIKI)/tools/sky/serialdump-linux - MOTELIST = $(CONTIKI)/tools/z1/motelist-z1-macos - BSL = $(CONTIKI)/tools/z1/z1-bsl-nopic --z1 + MOTELIST = $(CONTIKI)/tools/zolertia/motelist-zolertia-macos + BSL = $(CONTIKI)/tools/zolertia/z1-bsl-nopic --z1 BSL_FILETYPE = -I - MOTES = $(shell $(MOTELIST) -c 2>&- | \ - cut -f 2 -d ,) - CMOTES=$(MOTES) + MOTES = $(shell $(MOTELIST) -b z1 -c 2>&- | \ + cut -f 2 -d ,) + REFNUM = $(shell $(MOTELIST) -c 2>&- | \ + cut -f 1 -d , | tail -c5 | sed 's/^0*//') + ifneq (,$(REFNUM)) + # No device fo-und + ifeq (,$(findstring und, $(REFNUM))) + CFLAGS += -DSERIALNUM=$(REFNUM:0%=%) + endif + endif endif else # If we are not running under Mac, we assume Linux ifndef MOTELIST USBDEVPREFIX= SERIALDUMP = $(CONTIKI)/tools/sky/serialdump-linux - MOTELIST = $(CONTIKI)/tools/z1/motelist-z1 - BSL = $(CONTIKI)/tools/z1/z1-bsl-nopic --z1 + MOTELIST = $(CONTIKI)/tools/zolertia/motelist-zolertia + BSL = $(CONTIKI)/tools/zolertia/z1-bsl-nopic --z1 BSL_FILETYPE = -I - MOTES = $(shell $(MOTELIST) -c 2>&- | \ - cut -f 2 -d , | \ - perl -ne 'print $$1 . " " if(m-(/dev/\w+)-);') + MOTES = $(shell $(MOTELIST) -b z1 -c 2>&- | \ + cut -f 2 -d , | \ + perl -ne 'print $$1 . " " if(m-(/dev/\w+)-);') CMOTES=$(MOTES) + REFNUM = $(shell $(MOTELIST) -c 2>&- | \ + cut -f 1 -d , | tail -c5 | sed 's/^0*//') + ifneq (,$(REFNUM)) + # No device fo-und + ifeq (,$(findstring und, $(REFNUM))) + CFLAGS += -DSERIALNUM=$(REFNUM) + endif + endif endif endif - - -motelist: z1-motelist - -z1-motelist: +motelist: $(MOTELIST) +z1-motelist: + $(MOTELIST) -b z1 z1-motes: @echo $(MOTES) diff --git a/platform/z1/Makefile.z1 b/platform/z1/Makefile.z1 index 03695479b..015171af7 100644 --- a/platform/z1/Makefile.z1 +++ b/platform/z1/Makefile.z1 @@ -1,10 +1,15 @@ -# Common makefile between Z1 and Z1 Starter Platform +# Common Makefile between Z1 and Z1SP CONTIKI_TARGET_SOURCEFILES += contiki-z1-platform.c CLEAN += *.z1 include $(CONTIKI)/platform/z1/Makefile.common -MODULES += core/net core/net/ip core/net/ipv6 core/net/ipv4 core/net/rpl \ - core/net/rime core/net/mac core/net/mac/contikimac \ +ifeq ($(ZOLERTIA_Z1SP),1) +include $(CONTIKI)/platform/z1/Makefile.z1sp +endif + +MODULES += core/net \ + core/net/mac core/net/mac/contikimac \ + core/net/llsec \ dev/cc2420 dev/sht11 diff --git a/platform/z1/Makefile.z1sp b/platform/z1/Makefile.z1sp new file mode 100644 index 000000000..29b8fcbd1 --- /dev/null +++ b/platform/z1/Makefile.z1sp @@ -0,0 +1,6 @@ +# Makefile for Z1 Starter Platform + +# This is the actual flag we need to include specific Z1SP components +CFLAGS += -DZ1_IS_Z1SP + +CONTIKI_TARGET_SOURCEFILES += potentiometer-sensor.c diff --git a/platform/z1/README.z1sp b/platform/z1/README.z1sp new file mode 100644 index 000000000..8db1e48da --- /dev/null +++ b/platform/z1/README.z1sp @@ -0,0 +1,9 @@ +Using the Z1 starter platform (Z1SP) +============================================ + +To enable the Z1SP components, you should include in your application Makefile +the ZOLERTIA_Z1SP flag set to 1, see "examples/z1/Makefile". + +For Z1SP specific information please go to: + +http://zolertia.sourceforge.net/wiki/index.php/Mainpage:z1sp diff --git a/platform/z1/contiki-conf.h b/platform/z1/contiki-conf.h index c69ff7e40..44d74efdb 100644 --- a/platform/z1/contiki-conf.h +++ b/platform/z1/contiki-conf.h @@ -31,13 +31,12 @@ #ifndef CONTIKI_CONF_H #define CONTIKI_CONF_H - #include "platform-conf.h" #define XMAC_CONF_COMPOWER 1 #define CXMAC_CONF_COMPOWER 1 -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 /* Network setup for IPv6 */ #define NETSTACK_CONF_NETWORK sicslowpan_driver @@ -51,7 +50,6 @@ larger than a specified size, if no ContikiMAC header should be used. */ #define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63 -#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0 #define CC2420_CONF_AUTOACK 1 #define NETSTACK_RDC_CHANNEL_CHECK_RATE 8 @@ -59,10 +57,9 @@ #define CXMAC_CONF_ANNOUNCEMENTS 0 #define XMAC_CONF_ANNOUNCEMENTS 0 -#define QUEUEBUF_CONF_NUM 4 +#define QUEUEBUF_CONF_NUM 4 - -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ /* Network setup for non-IPv6 (rime). */ @@ -70,7 +67,7 @@ #define NETSTACK_CONF_MAC csma_driver #define NETSTACK_CONF_RDC contikimac_driver #define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 -#define NETSTACK_CONF_FRAMER framer_802154 +#define NETSTACK_CONF_FRAMER contikimac_framer #define CC2420_CONF_AUTOACK 1 @@ -88,7 +85,7 @@ #define QUEUEBUF_CONF_NUM 8 -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define PACKETBUF_CONF_ATTRS_INLINE 1 @@ -106,11 +103,14 @@ #define IEEE802154_CONF_PANID 0xABCD +/* The TSCH default slot length of 10ms is a bit too short for this platform, + * use 15ms instead. */ +#define TSCH_CONF_DEFAULT_TIMESLOT_LENGTH 15000 + #define SHELL_VARS_CONF_RAM_BEGIN 0x1100 #define SHELL_VARS_CONF_RAM_END 0x2000 - -#define CFS_CONF_OFFSET_TYPE long +#define CFS_CONF_OFFSET_TYPE long #define PROFILE_CONF_ON 0 #define ENERGEST_CONF_ON 1 @@ -128,10 +128,11 @@ #define PROCESS_CONF_STATS 1 /*#define PROCESS_CONF_FASTPOLL 4*/ +#define UART0_CONF_TX_WITH_INTERRUPT 0 /* So far, printfs without interrupt. */ -#define UART0_CONF_TX_WITH_INTERRUPT 0 // So far, printfs without interrupt. +#define UART0_CONF_RX_WITH_DMA 0 -#ifdef WITH_UIP6 +#ifdef NETSTACK_CONF_WITH_IPV6 #define LINKADDR_CONF_SIZE 8 @@ -139,41 +140,34 @@ #define UIP_CONF_LLH_LEN 0 #define UIP_CONF_ROUTER 1 -#define UIP_CONF_IPV6_RPL 1 /* Handle 10 neighbors */ #define NBR_TABLE_CONF_MAX_NEIGHBORS 15 /* Handle 10 routes */ #define UIP_CONF_MAX_ROUTES 15 -#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_RETRANS_TIMER 10000 -#define UIP_CONF_IPV6 1 +#define NETSTACK_CONF_WITH_IPV6 1 #define UIP_CONF_IPV6_QUEUE_PKT 0 #define UIP_CONF_IPV6_CHECKS 1 #define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_NETIF_MAX_ADDRESSES 3 -#define UIP_CONF_ND6_MAX_PREFIXES 3 -#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_IP_FORWARD 0 -#define UIP_CONF_BUFFER_SIZE 140 +#define UIP_CONF_BUFFER_SIZE 140 -#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 -#define SICSLOWPAN_CONF_COMPRESSION_HC1 1 -#define SICSLOWPAN_CONF_COMPRESSION_HC01 2 #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #ifndef SICSLOWPAN_CONF_FRAG #define SICSLOWPAN_CONF_FRAG 1 #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ -#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_IP_FORWARD 1 #define UIP_CONF_BUFFER_SIZE 108 -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_ICMP_DEST_UNREACH 1 @@ -194,11 +188,8 @@ #define UIP_CONF_TCP_SPLIT 0 - #ifdef PROJECT_CONF_H #include PROJECT_CONF_H #endif /* PROJECT_CONF_H */ - - #endif /* CONTIKI_CONF_H */ diff --git a/platform/z1/contiki-z1-main.c b/platform/z1/contiki-z1-main.c index a2df1c887..92a7b5bd7 100644 --- a/platform/z1/contiki-z1-main.c +++ b/platform/z1/contiki-z1-main.c @@ -30,7 +30,7 @@ #include #include -#include +#include #include "contiki.h" #include "cc2420.h" @@ -47,9 +47,9 @@ #include "dev/adxl345.h" #include "sys/clock.h" -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 #include "net/ipv6/uip-ds6.h" -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ #include "net/rime/rime.h" @@ -70,26 +70,26 @@ extern unsigned char node_mac[8]; static struct timer mgt_timer; #endif -#ifndef WITH_UIP -#define WITH_UIP 0 +#ifndef NETSTACK_CONF_WITH_IPV4 +#define NETSTACK_CONF_WITH_IPV4 0 #endif -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 #include "net/ip/uip.h" #include "net/ipv4/uip-fw.h" -#include "net/uip-fw-drv.h" +#include "net/ipv4/uip-fw-drv.h" #include "net/ipv4/uip-over-mesh.h" static struct uip_fw_netif slipif = - {UIP_FW_NETIF(192,168,1,2, 255,255,255,255, slip_send)}; +{ UIP_FW_NETIF(192, 168, 1, 2, 255, 255, 255, 255, slip_send) }; static struct uip_fw_netif meshif = - {UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)}; +{ UIP_FW_NETIF(172, 16, 0, 0, 255, 255, 0, 0, uip_over_mesh_send) }; -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ #define UIP_OVER_MESH_CHANNEL 8 -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 static uint8_t is_gateway; -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ #ifdef EXPERIMENT_SETUP #include "experiment-setup.h" @@ -119,7 +119,11 @@ force_float_inclusion() } #endif /*---------------------------------------------------------------------------*/ -void uip_log(char *msg) { puts(msg); } +void +uip_log(char *msg) +{ + puts(msg); +} /*---------------------------------------------------------------------------*/ #if 0 void @@ -136,7 +140,7 @@ set_rime_addr(void) int i; memset(&addr, 0, sizeof(linkaddr_t)); -#if UIP_CONF_IPV6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(addr.u8, node_mac, sizeof(addr.u8)); #else if(node_id == 0) { @@ -157,7 +161,7 @@ set_rime_addr(void) } /*---------------------------------------------------------------------------*/ static void -print_processes(struct process * const processes[]) +print_processes(struct process *const processes[]) { /* const struct process * const * p = processes;*/ printf("Starting"); @@ -168,22 +172,22 @@ print_processes(struct process * const processes[]) putchar('\n'); } /*--------------------------------------------------------------------------*/ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 static void set_gateway(void) { if(!is_gateway) { leds_on(LEDS_RED); printf("%d.%d: making myself the IP network gateway.\n\n", - linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]); + linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]); printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n", - uip_ipaddr_to_quad(&uip_hostaddr)); + uip_ipaddr_to_quad(&uip_hostaddr)); uip_over_mesh_set_gateway(&linkaddr_node_addr); uip_over_mesh_make_announced_gateway(); is_gateway = 1; } } -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ /*---------------------------------------------------------------------------*/ int main(int argc, char **argv) @@ -199,9 +203,9 @@ main(int argc, char **argv) clock_wait(100); uart0_init(BAUD2UBR(115200)); /* Must come before first printf */ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 slip_arch_init(BAUD2UBR(115200)); -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ xmem_init(); @@ -213,9 +217,16 @@ main(int argc, char **argv) /* Restore node id if such has been stored in external mem */ node_id_restore(); - /* If no MAC address was burned, we use the node ID. */ + /* If no MAC address was burned, we use the node id or the Z1 product ID */ if(!(node_mac[0] | node_mac[1] | node_mac[2] | node_mac[3] | node_mac[4] | node_mac[5] | node_mac[6] | node_mac[7])) { + +#ifdef SERIALNUM + if(!node_id) { + PRINTF("Node id is not set, using Z1 product ID\n"); + node_id = SERIALNUM; + } +#endif node_mac[0] = 0xc1; /* Hardcoded for Z1 */ node_mac[1] = 0x0c; /* Hardcoded for Revision C */ node_mac[2] = 0x00; /* Hardcoded to arbitrary even number so that @@ -231,7 +242,7 @@ main(int argc, char **argv) /* Overwrite node MAC if desired at compile time */ #ifdef MACID - #warning "***** CHANGING DEFAULT MAC *****" +#warning "***** CHANGING DEFAULT MAC *****" node_mac[0] = 0xc1; /* Hardcoded for Z1 */ node_mac[1] = 0x0c; /* Hardcoded for Revision C */ node_mac[2] = 0x00; /* Hardcoded to arbitrary even number so that @@ -254,15 +265,16 @@ main(int argc, char **argv) } #endif /* IEEE_802154_MAC_ADDRESS */ - /* + /* * Initialize Contiki and our processes. */ + random_init(node_mac[6] + node_mac[7]); process_init(); process_start(&etimer_process, NULL); ctimer_init(); - init_platform(); + init_platform(); set_rime_addr(); @@ -272,7 +284,7 @@ main(int argc, char **argv) { uint8_t longaddr[8]; uint16_t shortaddr; - + shortaddr = (linkaddr_node_addr.u8[0] << 8) + linkaddr_node_addr.u8[1]; memset(longaddr, 0, sizeof(longaddr)); @@ -280,22 +292,24 @@ main(int argc, char **argv) printf("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ", longaddr[0], longaddr[1], longaddr[2], longaddr[3], longaddr[4], longaddr[5], longaddr[6], longaddr[7]); - + cc2420_set_pan_addr(IEEE802154_PANID, shortaddr, longaddr); } leds_off(LEDS_ALL); +#ifdef SERIALNUM + PRINTF("Ref ID: %u\n", SERIALNUM); +#endif PRINTF(CONTIKI_VERSION_STRING " started. "); - if(node_id > 0) { + if(node_id) { PRINTF("Node id is set to %u.\n", node_id); } else { - PRINTF("Node id is not set.\n"); + PRINTF("Node id not set\n"); } - -#if WITH_UIP6 +#if NETSTACK_CONF_WITH_IPV6 memcpy(&uip_lladdr.addr, node_mac, sizeof(uip_lladdr.addr)); /* Setup nullmac-like MAC for 802.15.4 */ /* sicslowpan_init(sicslowmac_init(&cc2420_driver)); */ @@ -310,7 +324,7 @@ main(int argc, char **argv) printf("%s %s, channel check rate %lu Hz, radio channel %u\n", NETSTACK_MAC.name, NETSTACK_RDC.name, - CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1: + CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1 : NETSTACK_RDC.channel_check_interval()), CC2420_CONF_CHANNEL); @@ -327,11 +341,11 @@ main(int argc, char **argv) } printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]); } - + if(!UIP_CONF_IPV6_RPL) { uip_ipaddr_t ipaddr; int i; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE); printf("Tentative global IPv6 address "); @@ -343,7 +357,7 @@ main(int argc, char **argv) ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]); } -#else /* WITH_UIP6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ NETSTACK_RDC.init(); NETSTACK_MAC.init(); @@ -351,12 +365,12 @@ main(int argc, char **argv) printf("%s %s, channel check rate %lu Hz, radio channel %u\n", NETSTACK_MAC.name, NETSTACK_RDC.name, - CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0? 1: + CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1 : NETSTACK_RDC.channel_check_interval()), CC2420_CONF_CHANNEL); -#endif /* WITH_UIP6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ -#if !WITH_UIP && !WITH_UIP6 +#if !NETSTACK_CONF_WITH_IPV4 && !NETSTACK_CONF_WITH_IPV6 uart0_set_input(serial_line_input_byte); serial_line_init(); #endif @@ -368,9 +382,9 @@ main(int argc, char **argv) timesynch_set_authority_level(linkaddr_node_addr.u8[0]); #endif /* TIMESYNCH_CONF_ENABLED */ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 process_start(&tcpip_process, NULL); - process_start(&uip_fw_process, NULL); /* Start IP output */ + process_start(&uip_fw_process, NULL); /* Start IP output */ process_start(&slip_process, NULL); slip_set_input_callback(set_gateway); @@ -380,9 +394,9 @@ main(int argc, char **argv) uip_init(); - uip_ipaddr(&hostaddr, 172,16, - linkaddr_node_addr.u8[0],linkaddr_node_addr.u8[1]); - uip_ipaddr(&netmask, 255,255,0,0); + uip_ipaddr(&hostaddr, 172, 16, + linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]); + uip_ipaddr(&netmask, 255, 255, 0, 0); uip_ipaddr_copy(&meshif.ipaddr, &hostaddr); uip_sethostaddr(&hostaddr); @@ -393,9 +407,9 @@ main(int argc, char **argv) uip_fw_default(&meshif); uip_over_mesh_init(UIP_OVER_MESH_CHANNEL); printf("uIP started with IP address %d.%d.%d.%d\n", - uip_ipaddr_to_quad(&hostaddr)); + uip_ipaddr_to_quad(&hostaddr)); } -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ energest_init(); ENERGEST_ON(ENERGEST_TYPE_CPU); @@ -422,44 +436,42 @@ main(int argc, char **argv) /* * Idle processing. */ - int s = splhigh(); /* Disable interrupts. */ + int s = splhigh(); /* Disable interrupts. */ /* uart0_active is for avoiding LPM3 when still sending or receiving */ if(process_nevents() != 0 || uart0_active()) { - splx(s); /* Re-enable interrupts. */ + splx(s); /* Re-enable interrupts. */ } else { static unsigned long irq_energest = 0; #if DCOSYNCH_CONF_ENABLED /* before going down to sleep possibly do some management */ - if (timer_expired(&mgt_timer)) { - timer_reset(&mgt_timer); - msp430_sync_dco(); + if(timer_expired(&mgt_timer)) { + timer_reset(&mgt_timer); + msp430_sync_dco(); } #endif /* Re-enable interrupts and go to sleep atomically. */ - ENERGEST_OFF(ENERGEST_TYPE_CPU); - ENERGEST_ON(ENERGEST_TYPE_LPM); + ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); /* We only want to measure the processing done in IRQs when we - are asleep, so we discard the processing time done when we - were awake. */ + are asleep, so we discard the processing time done when we + were awake. */ energest_type_set(ENERGEST_TYPE_IRQ, irq_energest); watchdog_stop(); _BIS_SR(GIE | SCG0 | SCG1 | CPUOFF); /* LPM3 sleep. This - statement will block - until the CPU is - woken up by an - interrupt that sets - the wake up flag. */ + statement will block + until the CPU is + woken up by an + interrupt that sets + the wake up flag. */ /* We get the current processing time for interrupts that was - done during the LPM and store it for next time around. */ + done during the LPM and store it for next time around. */ dint(); irq_energest = energest_type_time(ENERGEST_TYPE_IRQ); eint(); watchdog_start(); - ENERGEST_OFF(ENERGEST_TYPE_LPM); - ENERGEST_ON(ENERGEST_TYPE_CPU); + ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } } diff --git a/platform/z1/dev/adxl345.c b/platform/z1/dev/adxl345.c index df653d7f8..49bf9b6e6 100644 --- a/platform/z1/dev/adxl345.c +++ b/platform/z1/dev/adxl345.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2010, Swedish Institute of Computer Science. + * Copyright (c) 2016, Zolertia * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,59 +30,52 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * Device drivers for adxl345 accelerometer in Zolertia Z1. * \author * Marcus Lundén, SICS * Enric M. Calvo, Zolertia + * Antonio Lignan, Zolertia */ - - +/*---------------------------------------------------------------------------*/ #include #include "contiki.h" #include "adxl345.h" #include "cc2420.h" #include "i2cmaster.h" #include "isr_compat.h" - +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ /* Callback pointers when interrupt occurs */ void (*accm_int1_cb)(uint8_t reg); void (*accm_int2_cb)(uint8_t reg); - -process_event_t int1_event, int2_event; - +/*---------------------------------------------------------------------------*/ /* Bitmasks for the interrupts */ static uint16_t int1_mask = 0, int2_mask = 0; -/* Keep track of when the interrupt was last seen in order to reduce the amount - of interrupts. Kind of like button debouncing. This can't be per int-pin, as - there can be several very different int per pin (eg tap && freefall). */ -// XXX Not used now, only one global timer. -//static volatile clock_time_t ints_lasttime[] = {0, 0, 0, 0, 0, 0, 0, 0}; +/* Default values for adxl345 at startup. + * This will be sent to the adxl345 in a + * stream at init to set it up in a default state + */ -/* Bitmasks and bit flag variable for keeping track of adxl345 status. */ -enum ADXL345_STATUSTYPES { - /* must be a bit and not more, not using 0x00. */ - INITED = 0x01, - RUNNING = 0x02, - STOPPED = 0x04, - LOW_POWER = 0x08, - AAA = 0x10, // available to extend this... - BBB = 0x20, // available to extend this... - CCC = 0x40, // available to extend this... - DDD = 0x80, // available to extend this... -}; -static enum ADXL345_STATUSTYPES _ADXL345_STATUS = 0x00; - -/* Default values for adxl345 at startup. This will be sent to the adxl345 in a - stream at init to set it up in a default state */ static uint8_t adxl345_default_settings[] = { /* Note, as the two first two bulks are to be written in a stream, they contain - the register address as first byte in that section. */ - /* 0--14 are in one stream, start at ADXL345_THRESH_TAP */ - ADXL345_THRESH_TAP, // XXX NB Register address, not register value!! + * the register address as first byte in that section. + * 0--14 are in one stream, start at ADXL345_THRESH_TAP + */ + /* XXX NB Register address, not register value!! */ + ADXL345_THRESH_TAP, ADXL345_THRESH_TAP_DEFAULT, ADXL345_OFSX_DEFAULT, ADXL345_OFSY_DEFAULT, @@ -98,7 +92,8 @@ static uint8_t adxl345_default_settings[] = { ADXL345_TAP_AXES_DEFAULT, /* 15--19 start at ADXL345_BW_RATE */ - ADXL345_BW_RATE, // XXX NB Register address, not register value!! + /* XXX NB Register address, not register value!! */ + ADXL345_BW_RATE, ADXL345_BW_RATE_DEFAULT, ADXL345_POWER_CTL_DEFAULT, ADXL345_INT_ENABLE_DEFAULT, @@ -108,61 +103,45 @@ static uint8_t adxl345_default_settings[] = { ADXL345_DATA_FORMAT_DEFAULT, ADXL345_FIFO_CTL_DEFAULT }; - - /*---------------------------------------------------------------------------*/ PROCESS(accmeter_process, "Accelerometer process"); /*---------------------------------------------------------------------------*/ -/* Write to a register. - args: - reg register to write to - val value to write -*/ - -void -accm_write_reg(uint8_t reg, uint8_t val) { +static void +accm_write_reg(uint8_t reg, uint8_t val) +{ uint8_t tx_buf[] = {reg, val}; i2c_transmitinit(ADXL345_ADDR); while (i2c_busy()); - PRINTFDEBUG("I2C Ready to TX\n"); + PRINTF("ADXL345: I2C Ready to TX\n"); i2c_transmit_n(2, tx_buf); while (i2c_busy()); - PRINTFDEBUG("WRITE_REG 0x%02X @ reg 0x%02X\n", val, reg); + PRINTF("ADXL345: WRITE_REG 0x%02X @ reg 0x%02X\n", val, reg); } /*---------------------------------------------------------------------------*/ -/* Write several registers from a stream. - args: - len number of bytes to read - data pointer to where the data is read from - - First byte in stream must be the register address to begin writing to. - The data is then written from second byte and increasing. */ - -void -accm_write_stream(uint8_t len, uint8_t *data) { +/* First byte in stream must be the register address to begin writing to. + * The data is then written from second byte and increasing. + */ +static void +accm_write_stream(uint8_t len, uint8_t *data) +{ i2c_transmitinit(ADXL345_ADDR); while (i2c_busy()); - PRINTFDEBUG("I2C Ready to TX(stream)\n"); + PRINTF("ADXL345: I2C Ready to TX(stream)\n"); i2c_transmit_n(len, data); // start tx and send conf reg while (i2c_busy()); - PRINTFDEBUG("WRITE_STR %u B to 0x%02X\n", len, data[0]); + PRINTF("ADXL345: WRITE_STR %u B to 0x%02X\n", len, data[0]); } /*---------------------------------------------------------------------------*/ -/* Read one register. - args: - reg what register to read - returns the value of the read register -*/ - -uint8_t -accm_read_reg(uint8_t reg) { +static uint8_t +accm_read_reg(uint8_t reg) +{ uint8_t retVal = 0; uint8_t rtx = reg; - PRINTFDEBUG("READ_REG 0x%02X\n", reg); + PRINTF("ADXL345: READ_REG 0x%02X\n", reg); /* transmit the register to read */ i2c_transmitinit(ADXL345_ADDR); @@ -178,19 +157,12 @@ accm_read_reg(uint8_t reg) { return retVal; } - /*---------------------------------------------------------------------------*/ -/* Read several registers in a stream. - args: - reg what register to start reading from - len number of bytes to read - whereto pointer to where the data is saved -*/ - -void -accm_read_stream(uint8_t reg, uint8_t len, uint8_t *whereto) { +static void +accm_read_stream(uint8_t reg, uint8_t len, uint8_t *whereto) +{ uint8_t rtx = reg; - PRINTFDEBUG("READ_STR %u B from 0x%02X\n", len, reg); + PRINTF("ADXL345: READ_STR %u B from 0x%02X\n", len, reg); /* transmit the register to start reading from */ i2c_transmitinit(ADXL345_ADDR); @@ -206,13 +178,15 @@ accm_read_stream(uint8_t reg, uint8_t len, uint8_t *whereto) { } /*---------------------------------------------------------------------------*/ -/* Read an axis of the accelerometer (x, y or z). Return value is a signed 10 bit int. - The resolution of the acceleration measurement can be increased up to 13 bit, but - will change the data format of this read out. Refer to the data sheet if so is - wanted/needed. */ - +/* Read an axis of the accelerometer (x, y or z). Return value is a signed + * 10 bit int. + * The resolution of the acceleration measurement can be increased up to 13 bit, + * but will change the data format of this read out. Refer to the data sheet if + * so is wanted/needed. + */ int16_t -accm_read_axis(enum ADXL345_AXIS axis){ +accm_read_axis(enum ADXL345_AXIS axis) +{ int16_t rd = 0; uint8_t tmp[2]; if(axis > Z_AXIS){ @@ -222,165 +196,144 @@ accm_read_axis(enum ADXL345_AXIS axis){ rd = (int16_t)(tmp[0] | (tmp[1]<<8)); return rd; } - /*---------------------------------------------------------------------------*/ -/* Sets the g-range, ie the range the accelerometer measures (ie 2g means -2 to +2 g - on every axis). Possible values: - ADXL345_RANGE_2G - ADXL345_RANGE_4G - ADXL345_RANGE_8G - ADXL345_RANGE_16G - Example: - accm_set_grange(ADXL345_RANGE_4G); - */ - -void -accm_set_grange(uint8_t grange){ - if(grange > ADXL345_RANGE_16G) { - // invalid g-range. - PRINTFDEBUG("ADXL grange invalid: %u\n", grange); - return; - } +int +accm_set_grange(uint8_t grange) +{ uint8_t tempreg = 0; - /* preserve the previous contents of the register */ - tempreg = (accm_read_reg(ADXL345_DATA_FORMAT) & 0xFC); // zero out the last two bits (grange) - tempreg |= grange; // set new range - accm_write_reg(ADXL345_DATA_FORMAT, tempreg); -} - -/*---------------------------------------------------------------------------*/ -/* Init the accelerometer: ports, pins, registers, interrupts (none enabled), I2C, - default threshold values etc. */ - -void -accm_init(void) { - if(!(_ADXL345_STATUS & INITED)){ - PRINTFDEBUG("ADXL345 init\n"); - _ADXL345_STATUS |= INITED; - accm_int1_cb = NULL; - accm_int2_cb = NULL; - int1_event = process_alloc_event(); - int2_event = process_alloc_event(); - - /* Set up ports and pins for interrups. */ - ADXL345_DIR &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); - ADXL345_SEL &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); - ADXL345_SEL2 &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); - - /* Set up ports and pins for I2C communication */ - i2c_enable(); - - /* set default register values. */ - accm_write_stream(15, &adxl345_default_settings[0]); - accm_write_stream(5, &adxl345_default_settings[15]); - accm_write_reg(ADXL345_DATA_FORMAT, adxl345_default_settings[20]); - accm_write_reg(ADXL345_FIFO_CTL, adxl345_default_settings[21]); - - process_start(&accmeter_process, NULL); - - /* Enable msp430 interrupts on the two interrupt pins. */ - dint(); - ADXL345_IES &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); // low to high transition interrupts - ADXL345_IE |= (ADXL345_INT1_PIN | ADXL345_INT2_PIN); // enable interrupts - eint(); + if(grange > ADXL345_RANGE_16G) { + PRINTF("ADXL345: grange invalid: %u\n", grange); + return ADXL345_ERROR; } + + if(!enabled) { + return ADXL345_ERROR; + } + + /* Keep the previous contents of the register, zero out the last two bits */ + tempreg = (accm_read_reg(ADXL345_DATA_FORMAT) & 0xFC); + tempreg |= grange; + accm_write_reg(ADXL345_DATA_FORMAT, tempreg); + return ADXL345_SUCCESS; } /*---------------------------------------------------------------------------*/ -/* Map interrupt (FF, tap, dbltap etc) to interrupt pin (IRQ_INT1, IRQ_INT2). - This must come after accm_init() as the registers will otherwise be overwritten. */ - void -accm_set_irq(uint8_t int1, uint8_t int2){ +accm_init(void) +{ + PRINTF("ADXL345: init\n"); + accm_int1_cb = NULL; + accm_int2_cb = NULL; + + /* Set up ports and pins for interrups. */ + ADXL345_DIR &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); + ADXL345_SEL &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); + ADXL345_SEL2 &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); + + /* Set up ports and pins for I2C communication */ + i2c_enable(); + + /* set default register values. */ + accm_write_stream(15, &adxl345_default_settings[0]); + accm_write_stream(5, &adxl345_default_settings[15]); + accm_write_reg(ADXL345_DATA_FORMAT, adxl345_default_settings[20]); + accm_write_reg(ADXL345_FIFO_CTL, adxl345_default_settings[21]); + + process_start(&accmeter_process, NULL); + + /* Enable msp430 interrupts on the two interrupt pins. */ + dint(); + /* low to high transition interrupts */ + ADXL345_IES &=~ (ADXL345_INT1_PIN | ADXL345_INT2_PIN); + /* enable interrupts */ + ADXL345_IE |= (ADXL345_INT1_PIN | ADXL345_INT2_PIN); + eint(); + + enabled = 1; +} +/*---------------------------------------------------------------------------*/ +void +accm_stop(void) +{ + dint(); + ADXL345_IE &= ~(ADXL345_INT1_PIN | ADXL345_INT2_PIN); + accm_write_reg(ADXL345_INT_ENABLE, ~(int1_mask | int2_mask)); + accm_write_reg(ADXL345_INT_MAP, ~int2_mask); + eint(); + enabled = 0; +} +/*---------------------------------------------------------------------------*/ +int +accm_set_irq(uint8_t int1, uint8_t int2) +{ + if(!enabled) { + return ADXL345_ERROR; + } + /* Set the corresponding interrupt mapping to INT1 or INT2 */ - PRINTFDEBUG("IRQs set to INT1: 0x%02X IRQ2: 0x%02X\n", int1, int2); + PRINTF("ADXL345: IRQs set to INT1: 0x%02X IRQ2: 0x%02X\n", int1, int2); int1_mask = int1; int2_mask = int2; accm_write_reg(ADXL345_INT_ENABLE, (int1 | int2)); - accm_write_reg(ADXL345_INT_MAP, int2); // int1 bits are zeroes in the map register so this is for both ints + /* int1 bits are zeroes in the map register so this is for both ints */ + accm_write_reg(ADXL345_INT_MAP, int2); + return ADXL345_SUCCESS; } - -/*---------------------------------------------------------------------------*/ -#if 0 -/* now unused code that is later supposed to be turned into keeping track of every - interrupt by themselves instead of only one per INT1/2 */ - -/* XXX MUST HAVE some way of resetting the time so that we are not suppressing - erronous due to clock overflow.... XXX XXX XXX */ -/* Table with back off time periods */ -static volatile clock_time_t ints_backoffs[] = {ADXL345_INT_OVERRUN_BACKOFF, ADXL345_INT_WATERMARK_BACKOFF, - ADXL345_INT_FREEFALL_BACKOFF, ADXL345_INT_INACTIVITY_BACKOFF, - ADXL345_INT_ACTIVITY_BACKOFF, ADXL345_INT_DOUBLETAP_BACKOFF, - ADXL345_INT_TAP_BACKOFF, ADXL345_INT_DATAREADY_BACKOFF}; - -/*---------------------------------------------------------------------------*/ -/* Checks to see if an event occurred after backoff period (returns time period - past since) or not (returns 0) */ - -static clocktime_t -backoff_passed(clocktime_t happenedAt, const clocktime_t backoff){ - if(timenow-lasttime >= backoff) { - return 0; - } else { - return (timenow-lasttime); - } -} -#endif /*---------------------------------------------------------------------------*/ /* Invoked after an interrupt happened. Reads the interrupt source reg at the - accelerometer, which resets the interrupts, and invokes the corresponding - callback. It passes the source register value so the callback can determine - what interrupt happened, if several interrupts are mapped to the same pin. */ - + * accelerometer, which resets the interrupts, and invokes the corresponding + * callback. It passes the source register value so the callback can determine + * what interrupt happened, if several interrupts are mapped to the same pin. + */ static void -poll_handler(void){ +poll_handler(void) +{ uint8_t ireg = 0; ireg = accm_read_reg(ADXL345_INT_SOURCE); - //printf("0x%02X, 0x%02X, 0x%02X, 0x%02X\n", ireg, ireg2, int1_mask, int2_mask); /* Invoke callbacks for the corresponding interrupts */ if(ireg & int1_mask){ if(accm_int1_cb != NULL){ - PRINTFDEBUG("INT1 cb invoked\n"); + PRINTF("ADXL345: INT1 cb invoked\n"); accm_int1_cb(ireg); } } else if(ireg & int2_mask){ if(accm_int2_cb != NULL){ - PRINTFDEBUG("INT2 cb invoked\n"); + PRINTF("ADXL345: INT2 cb invoked\n"); accm_int2_cb(ireg); } } } - /*---------------------------------------------------------------------------*/ -/* This process is sleeping until an interrupt from the accelerometer occurs, which - polls this process from the interrupt service routine. */ - -PROCESS_THREAD(accmeter_process, ev, data) { +/* This process is sleeping until an interrupt from the accelerometer occurs, + * which polls this process from the interrupt service routine. */ +PROCESS_THREAD(accmeter_process, ev, data) +{ PROCESS_POLLHANDLER(poll_handler()); PROCESS_EXITHANDLER(); PROCESS_BEGIN(); while(1){ - PROCESS_WAIT_EVENT_UNTIL(0); // should do nothing in while loop. + PROCESS_WAIT_EVENT_UNTIL(0); } PROCESS_END(); } - /*---------------------------------------------------------------------------*/ -/* XXX This interrupt vector is shared with the interrupts from CC2420, so that - was moved here but should find a better home. XXX */ - -#if 1 +/* This interrupt vector is shared with the interrupts from CC2420, so that + * was moved here + */ static struct timer suppressTimer1, suppressTimer2; ISR(PORT1, port1_isr) { ENERGEST_ON(ENERGEST_TYPE_IRQ); - /* ADXL345_IFG.x goes high when interrupt occurs, use to check what interrupted */ - if ((ADXL345_IFG & ADXL345_INT1_PIN) && !(ADXL345_IFG & BV(CC2420_FIFOP_PIN))){ + + /* ADXL345_IFG.x goes high when interrupt occurs, use to check what + * interrupted + */ + if((ADXL345_IFG & ADXL345_INT1_PIN) && !(ADXL345_IFG & BV(CC2420_FIFOP_PIN))){ /* Check if this should be suppressed or not */ if(timer_expired(&suppressTimer1)) { timer_set(&suppressTimer1, SUPPRESS_TIME_INT1); @@ -388,11 +341,13 @@ ISR(PORT1, port1_isr) process_poll(&accmeter_process); LPM4_EXIT; } - } else if ((ADXL345_IFG & ADXL345_INT2_PIN) && !(ADXL345_IFG & BV(CC2420_FIFOP_PIN))){ + } else if((ADXL345_IFG & ADXL345_INT2_PIN) && + !(ADXL345_IFG & BV(CC2420_FIFOP_PIN))){ /* Check if this should be suppressed or not */ if(timer_expired(&suppressTimer2)) { timer_set(&suppressTimer2, SUPPRESS_TIME_INT2); - ADXL345_IFG &= ~ADXL345_INT2_PIN; // clear interrupt flag + /* clear interrupt flag */ + ADXL345_IFG &= ~ADXL345_INT2_PIN; process_poll(&accmeter_process); LPM4_EXIT; } @@ -404,7 +359,56 @@ ISR(PORT1, port1_isr) } ENERGEST_OFF(ENERGEST_TYPE_IRQ); } - /*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != SENSORS_ACTIVE) { + return ADXL345_ERROR; + } -#endif + if(value) { + accm_init(); + } else { + accm_stop(); + } + enabled = value; + return ADXL345_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return ADXL345_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if(!enabled) { + return ADXL345_ERROR; + } + + if((type != X_AXIS) && (type != Y_AXIS) && (type != Z_AXIS)) { + return ADXL345_ERROR; + } + + switch(type) { + case X_AXIS: + return accm_read_axis(X_AXIS); + case Y_AXIS: + return accm_read_axis(Y_AXIS); + case Z_AXIS: + return accm_read_axis(Z_AXIS); + default: + return ADXL345_ERROR; + } +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(adxl345, ADXL345_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ diff --git a/platform/z1/dev/adxl345.h b/platform/z1/dev/adxl345.h index 082572715..a8d4789d8 100644 --- a/platform/z1/dev/adxl345.h +++ b/platform/z1/dev/adxl345.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010, Swedish Institute of Computer Science. + * Copyright (c) 2016, Zolertia * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,158 +30,106 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * Device drivers header file for adxl345 accelerometer in Zolertia Z1. * \author * Marcus Lundén, SICS * Enric Calvo, Zolertia + * Antonio Lignan, Zolertia */ - +/*---------------------------------------------------------------------------*/ #ifndef ADXL345_H_ #define ADXL345_H_ #include #include "dev/i2cmaster.h" - -#define DEBUGLEDS 0 -#if DEBUGLEDS - #undef LEDS_ON(x) - #undef LEDS_OFF(x) - #define LEDS_ON(x) (LEDS_PxOUT &= ~x) - #define LEDS_OFF(x) (LEDS_PxOUT |= x) -#else - #undef LEDS_ON - #undef LEDS_OFF - #define LEDS_ON(x) - #define LEDS_OFF(x) -#endif - -#define LEDS_R 0x10 -#define LEDS_G 0x40 -#define LEDS_B 0x20 -#define L_ON(x) (LEDS_PxOUT &= ~x) -#define L_OFF(x) (LEDS_PxOUT |= x) - -/* Used in accm_read_axis(), eg accm_read_axis(X_AXIS);*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +/* Used in accm_read_axis(), eg accm_read_axis(X_AXIS) */ enum ADXL345_AXIS { X_AXIS = 0, Y_AXIS = 2, Z_AXIS = 4, }; - /* -------------------------------------------------------------------------- */ -/* Init the accelerometer: ports, pins, registers, interrupts (none enabled), I2C, - default threshold values etc. */ -void accm_init(void); +/* Init the accelerometer: ports, pins, registers, interrupts (none enabled), + * I2C, default threshold values etc. + */ +void accm_init(void); -/* Write to a register. - args: - reg register to write to - val value to write -*/ -void accm_write_reg(uint8_t reg, uint8_t val); - -/* Write several registers from a stream. - args: - len number of bytes to read - data pointer to where the data is read from - First byte in stream must be the register address to begin writing to. - The data is then written from the second byte and increasing. The address byte - is not included in length len. */ -void accm_write_stream(uint8_t len, uint8_t *data); - -/* Read one register. - args: - reg what register to read - returns the value of the read register -*/ -uint8_t accm_read_reg(uint8_t reg); - -/* Read several registers in a stream. - args: - reg what register to start reading from - len number of bytes to read - whereto pointer to where the data is saved -*/ -void accm_read_stream(uint8_t reg, uint8_t len, uint8_t *whereto); - -/* Read an axis of the accelerometer (x, y or z). Return value is a signed 10 bit int. - The resolution of the acceleration measurement can be increased up to 13 bit, but - will change the data format of this read out. Refer to the data sheet if so is - wanted/needed. */ +/* Read an axis of the accelerometer (x, y or z). Return value is a signed 10 + * bit int. + * The resolution of the acceleration measurement can be increased up to 13 bit, + * but will change the data format of this read out. Refer to the data sheet if + * so is wanted/needed. + */ int16_t accm_read_axis(enum ADXL345_AXIS axis); -/* Sets the g-range, ie the range the accelerometer measures (ie 2g means -2 to +2 g - on every axis). Possible values: - ADXL345_RANGE_2G - ADXL345_RANGE_4G - ADXL345_RANGE_8G - ADXL345_RANGE_16G - Example: - accm_set_grange(ADXL345_RANGE_4G); - */ -void accm_set_grange(uint8_t grange); +/* Sets the g-range, ie the range the accelerometer measures (ie 2g means -2 to + * +2 g on every axis). Possible values: + * - ADXL345_RANGE_2G + * - ADXL345_RANGE_4G + * - ADXL345_RANGE_8G + * - ADXL345_RANGE_16G + */ +int accm_set_grange(uint8_t grange); /* Map interrupt (FF, tap, dbltap etc) to interrupt pin (IRQ_INT1, IRQ_INT2). - This must come after accm_init() as the registers will otherwise be overwritten. */ -void accm_set_irq(uint8_t int1, uint8_t int2); + * This must come after accm_init() as the registers will otherwise be + * overwritten. + */ +int accm_set_irq(uint8_t int1, uint8_t int2); /* Macros for setting the pointers to callback functions from the interrupts. - The function will be called with an uint8_t as parameter, containing the interrupt - flag register from the ADXL345. That way, several interrupts can be mapped to - the same pin and be read from the */ + * The function will be called with an uint8_t as parameter, containing the + * interrupt flag register from the ADXL345. That way, several interrupts can be + * mapped to the same pin and be read + */ #define ACCM_REGISTER_INT1_CB(ptr) accm_int1_cb = ptr; #define ACCM_REGISTER_INT2_CB(ptr) accm_int2_cb = ptr; /* -------------------------------------------------------------------------- */ /* Application definitions, change if required by application. */ -/* Interrupt suppress periods */ -/* -// XXX Not used yet. -#define ADXL345_INT_OVERRUN_BACKOFF CLOCK_SECOND/8 -#define ADXL345_INT_WATERMARK_BACKOFF CLOCK_SECOND/8 -#define ADXL345_INT_FREEFALL_BACKOFF CLOCK_SECOND/8 -#define ADXL345_INT_INACTIVITY_BACKOFF CLOCK_SECOND/8 -#define ADXL345_INT_ACTIVITY_BACKOFF CLOCK_SECOND/8 -#define ADXL345_INT_DOUBLETAP_BACKOFF CLOCK_SECOND/8 -#define ADXL345_INT_TAP_BACKOFF CLOCK_SECOND/8 -#define ADXL345_INT_DATAREADY_BACKOFF CLOCK_SECOND/8 -*/ -/* Time after an interrupt that subsequent interrupts are suppressed. Should later - be turned into one specific time per type of interrupt (tap, freefall etc) */ +/* Time after an interrupt that subsequent interrupts are suppressed. Should + * later be turned into one specific time per type of interrupt (tap, freefall. + * etc) + */ #define SUPPRESS_TIME_INT1 CLOCK_SECOND/4 #define SUPPRESS_TIME_INT2 CLOCK_SECOND/4 /* Suggested defaults according to the data sheet etc */ -#define ADXL345_THRESH_TAP_DEFAULT 0x48 // 4.5g (0x30 == 3.0g) (datasheet: 3g++) -#define ADXL345_OFSX_DEFAULT 0x00 // for individual units calibration purposes +#define ADXL345_THRESH_TAP_DEFAULT 0x48 /* 4.5g (0x30 == 3.0g) */ +#define ADXL345_OFSX_DEFAULT 0x00 /* for calibration only */ #define ADXL345_OFSY_DEFAULT 0x00 #define ADXL345_OFSZ_DEFAULT 0x00 -#define ADXL345_DUR_DEFAULT 0x20 // 20 ms (datasheet: 10ms++) -#define ADXL345_LATENT_DEFAULT 0x50 // 100 ms (datasheet: 20ms++) -#define ADXL345_WINDOW_DEFAULT 0xFF // 320 ms (datasheet: 80ms++) -#define ADXL345_THRESH_ACT_DEFAULT 0x15 // 1.3g (62.5 mg/LSB) -#define ADXL345_THRESH_INACT_DEFAULT 0x08 // 0.5g (62.5 mg/LSB) -#define ADXL345_TIME_INACT_DEFAULT 0x02 // 2 s (1 s/LSB) -#define ADXL345_ACT_INACT_CTL_DEFAULT 0xFF // all axis involved, ac-coupled -#define ADXL345_THRESH_FF_DEFAULT 0x09 // 563 mg -#define ADXL345_TIME_FF_DEFAULT 0x20 // 160 ms -#define ADXL345_TAP_AXES_DEFAULT 0x07 // all axis, no suppression +#define ADXL345_DUR_DEFAULT 0x20 /* 20 ms (datasheet: 10ms++) */ +#define ADXL345_LATENT_DEFAULT 0x50 /* 100 ms (datasheet: 20ms++) */ +#define ADXL345_WINDOW_DEFAULT 0xFF /* 320 ms (datasheet: 80ms++) */ +#define ADXL345_THRESH_ACT_DEFAULT 0x15 /* 1.3g (62.5 mg/LSB) */ +#define ADXL345_THRESH_INACT_DEFAULT 0x08 /* 0.5g (62.5 mg/LSB) */ +#define ADXL345_TIME_INACT_DEFAULT 0x02 /* 2 s (1 s/LSB) */ +#define ADXL345_ACT_INACT_CTL_DEFAULT 0xFF /* all axis, ac-coupled */ +#define ADXL345_THRESH_FF_DEFAULT 0x09 /* 563 mg */ +#define ADXL345_TIME_FF_DEFAULT 0x20 /* 60 ms */ +#define ADXL345_TAP_AXES_DEFAULT 0x07 /* all axis, no suppression */ -#define ADXL345_BW_RATE_DEFAULT (0x00|ADXL345_SRATE_100) // 100 Hz, normal operation -#define ADXL345_POWER_CTL_DEFAULT 0x28 // link bit set, no autosleep, start normal measuring -#define ADXL345_INT_ENABLE_DEFAULT 0x00 // no interrupts enabled -#define ADXL345_INT_MAP_DEFAULT 0x00 // all mapped to int_1 +#define ADXL345_BW_RATE_DEFAULT (0x00 | ADXL345_SRATE_100) /* 100 Hz */ +/* link bit set, no autosleep, start normal measuring */ +#define ADXL345_POWER_CTL_DEFAULT 0x28 +#define ADXL345_INT_ENABLE_DEFAULT 0x00 /* no interrupts enabled */ +#define ADXL345_INT_MAP_DEFAULT 0x00 /* all mapped to int_1 */ /* XXX NB: In the data format register, data format of axis readings is chosen - between left or right justify. This affects the position of the MSB/LSB and is - different depending on g-range and resolution. If changed, make sure this is - reflected in the _read_axis() function. Also, the resolution can be increased - from 10 bit to at most 13 bit, but this also changes position of MSB etc on data - format so check this in read_axis() too. */ -#define ADXL345_DATA_FORMAT_DEFAULT (0x00|ADXL345_RANGE_2G) // right-justify, 2g, 10-bit mode, int is active high -#define ADXL345_FIFO_CTL_DEFAULT 0x00 // FIFO bypass mode + * between left or right justify. This affects the position of the MSB/LSB and is + * different depending on g-range and resolution. If changed, make sure this is + * reflected in the _read_axis() function. Also, the resolution can be increased + * from 10 bit to at most 13 bit, but this also changes position of MSB etc on data + * format so check this in read_axis() too. + */ +/* right-justify, 2g, 10-bit mode, int is active high */ +#define ADXL345_DATA_FORMAT_DEFAULT (0x00 | ADXL345_RANGE_2G) +#define ADXL345_FIFO_CTL_DEFAULT 0x00 /* FIFO bypass mode */ /* -------------------------------------------------------------------------- */ /* Reference definitions, should not be changed */ @@ -188,7 +137,7 @@ void accm_set_irq(uint8_t int1, uint8_t int2); #define ADXL345_ADDR 0x53 /* ADXL345 registers */ -#define ADXL345_DEVID 0x00 // read only +#define ADXL345_DEVID 0x00 /* registers 0x01 to 0x1C are reserved, do not access */ #define ADXL345_THRESH_TAP 0x1D #define ADXL345_OFSX 0x1E @@ -204,24 +153,24 @@ void accm_set_irq(uint8_t int1, uint8_t int2); #define ADXL345_THRESH_FF 0x28 #define ADXL345_TIME_FF 0x29 #define ADXL345_TAP_AXES 0x2A -#define ADXL345_ACT_TAP_STATUS 0x2B // read only +#define ADXL345_ACT_TAP_STATUS 0x2B #define ADXL345_BW_RATE 0x2C #define ADXL345_POWER_CTL 0x2D #define ADXL345_INT_ENABLE 0x2E #define ADXL345_INT_MAP 0x2F -#define ADXL345_INT_SOURCE 0x30 // read only +#define ADXL345_INT_SOURCE 0x30 #define ADXL345_DATA_FORMAT 0x31 -#define ADXL345_DATAX0 0x32 // read only, LSByte X, two's complement -#define ADXL345_DATAX1 0x33 // read only, MSByte X -#define ADXL345_DATAY0 0x34 // read only, LSByte Y -#define ADXL345_DATAY1 0x35 // read only, MSByte X -#define ADXL345_DATAZ0 0x36 // read only, LSByte Z -#define ADXL345_DATAZ1 0x37 // read only, MSByte X +#define ADXL345_DATAX0 0x32 /* read only, LSByte X, two's complement */ +#define ADXL345_DATAX1 0x33 /* read only, MSByte X */ +#define ADXL345_DATAY0 0x34 /* read only, LSByte Y */ +#define ADXL345_DATAY1 0x35 /* read only, MSByte X */ +#define ADXL345_DATAZ0 0x36 /* read only, LSByte Z */ +#define ADXL345_DATAZ1 0x37 /* read only, MSByte X */ #define ADXL345_FIFO_CTL 0x38 -#define ADXL345_FIFO_STATUS 0x39 // read only +#define ADXL345_FIFO_STATUS 0x39 /* read only */ /* ADXL345 interrupts */ -#define ADXL345_INT_DISABLE 0X00 // used for disabling interrupts +#define ADXL345_INT_DISABLE 0X00 /* used for disabling interrupts */ #define ADXL345_INT_OVERRUN 0X01 #define ADXL345_INT_WATERMARK 0X02 #define ADXL345_INT_FREEFALL 0X04 @@ -237,8 +186,8 @@ void accm_set_irq(uint8_t int1, uint8_t int2); #define ADXL345_REN P1REN #define ADXL345_SEL P1SEL #define ADXL345_SEL2 P1SEL2 -#define ADXL345_INT1_PIN (1<<6) // P1.6 -#define ADXL345_INT2_PIN (1<<7) // P1.7 +#define ADXL345_INT1_PIN (1<<6) /* P1.6 */ +#define ADXL345_INT2_PIN (1<<7) /* P1.7 */ #define ADXL345_IES P1IES #define ADXL345_IE P1IE #define ADXL345_IFG P1IFG @@ -251,43 +200,47 @@ void accm_set_irq(uint8_t int1, uint8_t int2); #define ADXL345_RANGE_16G 0x03 -/* The adxl345 has programmable sample rates, but unexpected results may occur if the wrong - rate and I2C bus speed is used (see datasheet p 17). Sample rates in Hz. This - setting does not change the internal sampling rate, just how often it is piped - to the output registers (ie the interrupt features use the full sample rate - internally). - - Example use: - adxl345_set_reg(ADXL345_BW_RATE, ((_ADXL345_STATUS & LOW_POWER) | ADXL345_SRATE_50)); - */ -#define ADXL345_SRATE_3200 0x0F // XXX NB don't use at all as I2C data rate<= 400kHz (see datasheet) -#define ADXL345_SRATE_1600 0x0E // XXX NB don't use at all as I2C data rate<= 400kHz (see datasheet) -#define ADXL345_SRATE_800 0x0D // when I2C data rate == 400 kHz -#define ADXL345_SRATE_400 0x0C // when I2C data rate == 400 kHz -#define ADXL345_SRATE_200 0x0B // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_100 0x0A // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_50 0x09 // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_25 0x08 // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_12_5 0x07 // 12.5 Hz, when I2C data rate >= 100 kHz -#define ADXL345_SRATE_6_25 0x06 // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_3_13 0x05 // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_1_56 0x04 // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_0_78 0x03 // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_0_39 0x02 // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_0_20 0x01 // when I2C data rate >= 100 kHz -#define ADXL345_SRATE_0_10 0x00 // 0.10 Hz, when I2C data rate >= 100 kHz +/* The adxl345 has programmable sample rates, but unexpected results may occur + * if the wrong rate and I2C bus speed is used (see datasheet p 17). Sample + * rates in Hz. This setting does not change the internal sampling rate, just + * how often it is piped to the output registers (ie the interrupt features use + * the full sample rate internally). + * Example use: + * adxl345_set_reg(ADXL345_BW_RATE, ((_ADXL345_STATUS & LOW_POWER) + * | ADXL345_SRATE_50)); + */ +/* XXX NB don't use at all as I2C data rate<= 400kHz */ +#define ADXL345_SRATE_3200 0x0F +/* XXX NB don't use at all as I2C data rate<= 400kHz */ +#define ADXL345_SRATE_1600 0x0E +#define ADXL345_SRATE_800 0x0D /* when I2C data rate == 400 kHz */ +#define ADXL345_SRATE_400 0x0C /* when I2C data rate == 400 kHz */ +#define ADXL345_SRATE_200 0x0B /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_100 0x0A /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_50 0x09 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_25 0x08 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_12_5 0x07 /* 12.5 Hz, when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_6_25 0x06 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_3_13 0x05 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_1_56 0x04 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_0_78 0x03 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_0_39 0x02 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_0_20 0x01 /* when I2C data rate >= 100 kHz */ +#define ADXL345_SRATE_0_10 0x00 /* 0.10 Hz, when I2C data rate >= 100 kHz */ +/* -------------------------------------------------------------------------- */ /* Callback pointers for the interrupts */ extern void (*accm_int1_cb)(uint8_t reg); extern void (*accm_int2_cb)(uint8_t reg); - -/* Interrupt 1 and 2 events; ADXL345 signals interrupt on INT1 or INT2 pins, - ISR is invoked and polls the accelerometer process which invokes the callbacks. */ -extern process_event_t int1_event, int2_event; // static ? - -#define ACCM_INT1 0x01 -#define ACCM_INT2 0x02 - - +/* -------------------------------------------------------------------------- */ +#define ACCM_INT1 0x01 +#define ACCM_INT2 0x02 +#define ADXL345_SUCCESS 0x00 +#define ADXL345_ERROR (-1) +/* -------------------------------------------------------------------------- */ +#define ADXL345_SENSOR "ADXL345 sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor adxl345; +/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ #endif /* ifndef ADXL345_H_ */ diff --git a/platform/z1/dev/cc2420-arch.c b/platform/z1/dev/cc2420-arch.c index bc345e29f..929a1e0e6 100644 --- a/platform/z1/dev/cc2420-arch.c +++ b/platform/z1/dev/cc2420-arch.c @@ -34,13 +34,17 @@ #include "cc2420.h" #include "isr_compat.h" +#ifdef CC2420_CONF_SFD_TIMESTAMPS +#define CONF_SFD_TIMESTAMPS CC2420_CONF_SFD_TIMESTAMPS +#endif /* CC2420_CONF_SFD_TIMESTAMPS */ + #ifndef CONF_SFD_TIMESTAMPS #define CONF_SFD_TIMESTAMPS 0 #endif /* CONF_SFD_TIMESTAMPS */ #ifdef CONF_SFD_TIMESTAMPS #include "cc2420-arch-sfd.h" -#endif +#endif /* CONF_SFD_TIMESTAMPS */ /*---------------------------------------------------------------------------*/ #if 0 @@ -67,7 +71,7 @@ cc2420_arch_init(void) #if CONF_SFD_TIMESTAMPS cc2420_arch_sfd_init(); -#endif +#endif /* CONF_SFD_TIMESTAMPS */ CC2420_SPI_DISABLE(); /* Unselect radio. */ } diff --git a/platform/z1/dev/i2cmaster.c b/platform/z1/dev/i2cmaster.c index c3765f5cf..59437b904 100644 --- a/platform/z1/dev/i2cmaster.c +++ b/platform/z1/dev/i2cmaster.c @@ -41,98 +41,90 @@ #include "i2cmaster.h" #include "isr_compat.h" -signed char tx_byte_ctr, rx_byte_ctr; +signed char tx_byte_ctr, rx_byte_ctr; unsigned char rx_buf[2]; -unsigned char* tx_buf_ptr; -unsigned char* rx_buf_ptr; +unsigned char *tx_buf_ptr; +unsigned char *rx_buf_ptr; unsigned char receive_data; unsigned char transmit_data1; unsigned char transmit_data2; -volatile unsigned int i; // volatile to prevent optimization +unsigned char prescale_lsb = I2C_PRESC_Z1_LSB; +unsigned char prescale_msb = I2C_PRESC_Z1_MSB; +volatile unsigned int i; /* volatile to prevent optimization */ -//------------------------------------------------------------------------------ -// void i2c_receiveinit(unsigned char slave_address, -// unsigned char prescale) -// -// This function initializes the USCI module for master-receive operation. -// -// IN: unsigned char slave_address => Slave Address -// unsigned char prescale => SCL clock adjustment -//----------------------------------------------------------------------------- +/* ------------------------------------------------------------------------------ + * Change the data rate prior initializing transmission or reception + * ----------------------------------------------------------------------------- */ void -i2c_receiveinit(uint8_t slave_address) { - UCB1CTL1 = UCSWRST; // Enable SW reset - UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode - UCB1CTL1 = UCSSEL_2 | UCSWRST; // Use SMCLK, keep SW reset - UCB1BR0 = I2C_PRESC_400KHZ_LSB; // prescaler for 400 kHz data rate - UCB1BR1 = I2C_PRESC_400KHZ_MSB; - UCB1I2CSA = slave_address; // set slave address - - UCB1CTL1 &= ~UCTR; // I2C Receiver - - UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation +i2c_setrate(uint8_t p_lsb, uint8_t p_msb) +{ + prescale_lsb = p_lsb; + prescale_lsb = p_msb; +} +/* ------------------------------------------------------------------------------ + * This function initializes the USCI module for master-receive operation. + * ----------------------------------------------------------------------------- */ +void +i2c_receiveinit(uint8_t slave_address) +{ + UCB1CTL1 = UCSWRST; /* Enable SW reset */ + UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; /* I2C Master, synchronous mode */ + UCB1CTL1 = UCSSEL_2 | UCSWRST; /* Use SMCLK, keep SW reset */ + UCB1BR0 = prescale_lsb; /* prescaler (default 400 kHz) */ + UCB1BR1 = prescale_msb; + UCB1I2CSA = slave_address; /* set slave address */ + UCB1CTL1 &= ~UCTR; /* I2C Receiver */ + UCB1CTL1 &= ~UCSWRST; /* Clear SW reset, resume operation */ UCB1I2CIE = UCNACKIE; #if I2C_RX_WITH_INTERRUPT - UC1IE = UCB1RXIE; // Enable RX interrupt if desired + UC1IE = UCB1RXIE; /* Enable RX interrupt if desired */ #endif } - -//------------------------------------------------------------------------------ -// void i2c_transmitinit(unsigned char slave_address, -// unsigned char prescale) -// -// Initializes USCI for master-transmit operation. -// -// IN: unsigned char slave_address => Slave Address -// unsigned char prescale => SCL clock adjustment -//------------------------------------------------------------------------------ +/* ------------------------------------------------------------------------------ + * Initializes USCI for master-transmit operation. + * ------------------------------------------------------------------------------ */ void -i2c_transmitinit(uint8_t slave_address) { - UCB1CTL1 |= UCSWRST; // Enable SW reset - UCB1CTL0 |= (UCMST | UCMODE_3 | UCSYNC); // I2C Master, synchronous mode - UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset - UCB1BR0 = I2C_PRESC_400KHZ_LSB; // prescaler for 400 kHz data rate - UCB1BR1 = I2C_PRESC_400KHZ_MSB; - UCB1I2CSA = slave_address; // Set slave address - - UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation +i2c_transmitinit(uint8_t slave_address) +{ + UCB1CTL1 |= UCSWRST; /* Enable SW reset */ + UCB1CTL0 |= (UCMST | UCMODE_3 | UCSYNC); /* I2C Master, synchronous mode */ + UCB1CTL1 = UCSSEL_2 + UCSWRST; /* Use SMCLK, keep SW reset */ + UCB1BR0 = prescale_lsb; /* prescaler (default 400 kHz) */ + UCB1BR1 = prescale_msb; + UCB1I2CSA = slave_address; /* Set slave address */ + UCB1CTL1 &= ~UCSWRST; /* Clear SW reset, resume operation */ UCB1I2CIE = UCNACKIE; - UC1IE = UCB1TXIE; // Enable TX ready interrupt + UC1IE = UCB1TXIE; /* Enable TX ready interrupt */ } - -//------------------------------------------------------------------------------ -// void i2c_receive_n(unsigned char byte_ctr, unsigned char * rx_buf) -// This function is used to start an I2C communication in master-receiver mode WITHOUT INTERRUPTS -// for more than 1 byte -// IN: unsigned char byte_ctr => number of bytes to be read -// OUT: unsigned char rx_buf => receive data buffer -// OUT: int n_received => number of bytes read -//------------------------------------------------------------------------------ +/* ------------------------------------------------------------------------------ + * This function is used to start an I2C communication in master-receiver mode WITHOUT INTERRUPTS + * for more than 1 byte + * ------------------------------------------------------------------------------ */ static volatile uint8_t rx_byte_tot = 0; uint8_t -i2c_receive_n(uint8_t byte_ctr, uint8_t *rx_buf) { +i2c_receive_n(uint8_t byte_ctr, uint8_t *rx_buf) +{ rx_byte_tot = byte_ctr; rx_byte_ctr = byte_ctr; - rx_buf_ptr = rx_buf; + rx_buf_ptr = rx_buf; - while ((UCB1CTL1 & UCTXSTT) || (UCB1STAT & UCNACKIFG)) // Slave acks address or not? - PRINTFDEBUG ("____ UCTXSTT not clear OR NACK received\n"); + while((UCB1CTL1 & UCTXSTT) || (UCB1STAT & UCNACKIFG)) /* Slave acks address or not? */ + PRINTFDEBUG("____ UCTXSTT not clear OR NACK received\n"); #if I2C_RX_WITH_INTERRUPT PRINTFDEBUG(" RX Interrupts: YES \n"); - // SPECIAL-CASE: Stop condition must be sent while receiving the 1st byte for 1-byte only read operations - if(rx_byte_tot == 1){ // See page 537 of slau144e.pdf + /* SPECIAL-CASE: Stop condition must be sent while receiving the 1st byte for 1-byte only read operations */ + if(rx_byte_tot == 1) { /* See page 537 of slau144e.pdf */ dint(); - UCB1CTL1 |= UCTXSTT; // I2C start condition - while(UCB1CTL1 & UCTXSTT) // Waiting for Start bit to clear - PRINTFDEBUG ("____ STT clear wait\n"); - UCB1CTL1 |= UCTXSTP; // I2C stop condition + UCB1CTL1 |= UCTXSTT; /* I2C start condition */ + while(UCB1CTL1 & UCTXSTT) /* Waiting for Start bit to clear */ + PRINTFDEBUG("____ STT clear wait\n"); + UCB1CTL1 |= UCTXSTP; /* I2C stop condition */ eint(); - } - else{ // all other cases - UCB1CTL1 |= UCTXSTT; // I2C start condition + } else { /* all other cases */ + UCB1CTL1 |= UCTXSTT; /* I2C start condition */ } return 0; @@ -141,98 +133,86 @@ i2c_receive_n(uint8_t byte_ctr, uint8_t *rx_buf) { PRINTFDEBUG(" RX Interrupts: NO \n"); - UCB1CTL1 |= UCTXSTT; // I2C start condition + UCB1CTL1 |= UCTXSTT; /* I2C start condition */ - while (rx_byte_ctr > 0){ - if (UC1IFG & UCB1RXIFG) { // Waiting for Data + while(rx_byte_ctr > 0) { + if(UC1IFG & UCB1RXIFG) { /* Waiting for Data */ rx_buf[rx_byte_tot - rx_byte_ctr] = UCB1RXBUF; rx_byte_ctr--; - UC1IFG &= ~UCB1RXIFG; // Clear USCI_B1 RX int flag + UC1IFG &= ~UCB1RXIFG; /* Clear USCI_B1 RX int flag */ n_received++; } } - UCB1CTL1 |= UCTXSTP; // I2C stop condition + UCB1CTL1 |= UCTXSTP; /* I2C stop condition */ return n_received; #endif } - - -//------------------------------------------------------------------------------ -// uint8_t i2c_busy() -// -// This function is used to check if there is communication in progress. -// -// OUT: unsigned char => 0: I2C bus is idle, -// 1: communication is in progress -//------------------------------------------------------------------------------ +/* ------------------------------------------------------------------------------ + * This function is used to check if there is communication in progress. + * ------------------------------------------------------------------------------ */ uint8_t -i2c_busy(void) { - return (UCB1STAT & UCBBUSY); +i2c_busy(void) +{ + return UCB1STAT & UCBBUSY; } - -/*----------------------------------------------------------------------------*/ -/* Setup ports and pins for I2C use. */ +/*---------------------------------------------------------------------------- + * Setup ports and pins for I2C use. + * ------------------------------------------------------------------------------ */ void -i2c_enable(void) { - I2C_PxSEL |= (I2C_SDA | I2C_SCL); // Secondary function (USCI) selected - I2C_PxSEL2 |= (I2C_SDA | I2C_SCL); // Secondary function (USCI) selected - I2C_PxDIR |= I2C_SCL; // SCL is output (not needed?) - I2C_PxDIR &= ~I2C_SDA; // SDA is input (not needed?) - I2C_PxREN |= (I2C_SDA | I2C_SCL); // Activate internal pull-up/-down resistors - I2C_PxOUT |= (I2C_SDA | I2C_SCL); // Select pull-up resistors +i2c_enable(void) +{ + I2C_PxSEL |= (I2C_SDA | I2C_SCL); /* Secondary function (USCI) selected */ + I2C_PxSEL2 |= (I2C_SDA | I2C_SCL); /* Secondary function (USCI) selected */ + I2C_PxDIR |= I2C_SCL; /* SCL is output (not needed?) */ + I2C_PxDIR &= ~I2C_SDA; /* SDA is input (not needed?) */ + I2C_PxREN |= (I2C_SDA | I2C_SCL); /* Activate internal pull-up/-down resistors */ + I2C_PxOUT |= (I2C_SDA | I2C_SCL); /* Select pull-up resistors */ } - void -i2c_disable(void) { - I2C_PxSEL &= ~(I2C_SDA | I2C_SCL); // GPIO function selected - I2C_PxSEL2 &= ~(I2C_SDA | I2C_SCL); // GPIO function selected - I2C_PxREN &= ~(I2C_SDA | I2C_SCL); // Deactivate internal pull-up/-down resistors - I2C_PxOUT &= ~(I2C_SDA | I2C_SCL); // Select pull-up resistors +i2c_disable(void) +{ + I2C_PxSEL &= ~(I2C_SDA | I2C_SCL); /* GPIO function selected */ + I2C_PxSEL2 &= ~(I2C_SDA | I2C_SCL); /* GPIO function selected */ + I2C_PxREN &= ~(I2C_SDA | I2C_SCL); /* Deactivate internal pull-up/-down resistors */ + I2C_PxOUT &= ~(I2C_SDA | I2C_SCL); /* Select pull-up resistors */ } - -/*----------------------------------------------------------------------------*/ -//------------------------------------------------------------------------------ -// void i2c_transmit_n(unsigned char byte_ctr, unsigned char *field) -// -// This function is used to start an I2C communication in master-transmit mode. -// -// IN: unsigned char byte_ctr => number of bytes to be transmitted -// unsigned char *tx_buf => Content to transmit. Read and transmitted from [0] to [byte_ctr] -//------------------------------------------------------------------------------ +/* ------------------------------------------------------------------------------ + * This function is used to start an I2C communication in master-transmit mode. + * ------------------------------------------------------------------------------ */ static volatile uint8_t tx_byte_tot = 0; void -i2c_transmit_n(uint8_t byte_ctr, uint8_t *tx_buf) { +i2c_transmit_n(uint8_t byte_ctr, uint8_t *tx_buf) +{ tx_byte_tot = byte_ctr; tx_byte_ctr = byte_ctr; - tx_buf_ptr = tx_buf; - UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition + tx_buf_ptr = tx_buf; + UCB1CTL1 |= UCTR + UCTXSTT; /* I2C TX, start condition */ } - /*----------------------------------------------------------------------------*/ ISR(USCIAB1TX, i2c_tx_interrupt) { - // TX Part - if (UC1IFG & UCB1TXIFG) { // TX int. condition - if (tx_byte_ctr == 0) { - UCB1CTL1 |= UCTXSTP; // I2C stop condition - UC1IFG &= ~UCB1TXIFG; // Clear USCI_B1 TX int flag - } - else { + /* TX Part */ + if(UC1IFG & UCB1TXIFG) { /* TX int. condition */ + if(tx_byte_ctr == 0) { + UCB1CTL1 |= UCTXSTP; /* I2C stop condition */ + UC1IFG &= ~UCB1TXIFG; /* Clear USCI_B1 TX int flag */ + } else { UCB1TXBUF = tx_buf_ptr[tx_byte_tot - tx_byte_ctr]; tx_byte_ctr--; } } - // RX Part + /* RX Part */ #if I2C_RX_WITH_INTERRUPT - else if (UC1IFG & UCB1RXIFG){ // RX int. condition + else if(UC1IFG & UCB1RXIFG) { /* RX int. condition */ rx_buf_ptr[rx_byte_tot - rx_byte_ctr] = UCB1RXBUF; rx_byte_ctr--; - if (rx_byte_ctr == 1){ //stop condition should be set before receiving last byte - // Only for 1-byte transmissions, STOP is handled in receive_n_int - if (rx_byte_tot != 1) - UCB1CTL1 |= UCTXSTP; // I2C stop condition - UC1IFG &= ~UCB1RXIFG; // Clear USCI_B1 RX int flag. XXX Just in case, check if necessary + if(rx_byte_ctr == 1) { /* stop condition should be set before receiving last byte */ + /* Only for 1-byte transmissions, STOP is handled in receive_n_int */ + if(rx_byte_tot != 1) { + UCB1CTL1 |= UCTXSTP; /* I2C stop condition */ + } + UC1IFG &= ~UCB1RXIFG; /* Clear USCI_B1 RX int flag. XXX Just in case, check if necessary */ } } #endif diff --git a/platform/z1/dev/i2cmaster.h b/platform/z1/dev/i2cmaster.h index 29ee9a653..cf9d96e6d 100644 --- a/platform/z1/dev/i2cmaster.h +++ b/platform/z1/dev/i2cmaster.h @@ -53,32 +53,7 @@ void i2c_transmitinit(uint8_t slave_address); void i2c_transmit_n(uint8_t byte_ctr, uint8_t *tx_buf); uint8_t i2c_busy(void); - -//XXX Should these defines be in the contiki-conf.h to make it more platform-independent? -#define I2C_PxDIR P5DIR -#define I2C_PxIN P5IN -#define I2C_PxOUT P5OUT -#define I2C_PxSEL P5SEL -#define I2C_PxSEL2 P5SEL2 -#define I2C_PxREN P5REN - - -#define I2C_SDA (1 << 1) //SDA == P5.1 -#define I2C_SCL (1 << 2) //SCL == P5.2 -#define I2C_PRESC_1KHZ_LSB 0x00 -#define I2C_PRESC_1KHZ_MSB 0x20 -#define I2C_PRESC_100KHZ_LSB 0x50 -#define I2C_PRESC_100KHZ_MSB 0x00 -#define I2C_PRESC_400KHZ_LSB 0x14 -#define I2C_PRESC_400KHZ_MSB 0x00 - -// I2C configuration with RX interrupts -#ifdef I2C_CONF_RX_WITH_INTERRUPT -#define I2C_RX_WITH_INTERRUPT I2C_CONF_RX_WITH_INTERRUPT // XXX Move I2C_CONF_RX_WITH_INTERRUPT to contiki-conf.h or platform-conf.h -#else /* I2C_CONF_RX_WITH_INTERRUPT */ -#define I2C_RX_WITH_INTERRUPT 1 -#endif /* I2C_CONF_RX_WITH_INTERRUPT */ - +void i2c_setrate(uint8_t p_lsb, uint8_t p_msb); #if 0 #include @@ -87,4 +62,4 @@ uint8_t i2c_busy(void); #define PRINTFDEBUG(...) #endif -#endif /* #ifdef I2CMASTER_H_ */ +#endif /* #ifdef I2CMASTER_H_ */ diff --git a/platform/z1/dev/light-ziglet.c b/platform/z1/dev/light-ziglet.c index 7331bcaa5..3f322e30a 100644 --- a/platform/z1/dev/light-ziglet.c +++ b/platform/z1/dev/light-ziglet.c @@ -33,12 +33,12 @@ /** * \file * Device drivers for light ziglet sensor in Zolertia Z1. + * It is recommended to use with a 100KHz data rate * \author * Antonio Lignan, Zolertia * Marcus Lundén, SICS */ - #include #include "contiki.h" #include "i2cmaster.h" @@ -51,8 +51,7 @@ #endif /* Bitmasks and bit flag variable for keeping track of tmp102 status. */ -enum TSL2563_STATUSTYPES -{ +enum TSL2563_STATUSTYPES { /* must be a bit and not more, not using 0x00. */ INITED = 0x01, RUNNING = 0x02, @@ -61,166 +60,154 @@ enum TSL2563_STATUSTYPES static enum TSL2563_STATUSTYPES _TSL2563_STATUS = 0x00; -uint16_t +uint16_t calculateLux(uint16_t *buffer) { uint32_t ch0, ch1 = 0; - uint32_t aux = (1<<14); + uint32_t aux = (1 << 14); uint32_t ratio, lratio, tmp = 0; - ch0 = (buffer[0]*aux) >> 10; - ch1 = (buffer[1]*aux) >> 10; + ch0 = (buffer[0] * aux) >> 10; + ch1 = (buffer[1] * aux) >> 10; PRINTFDEBUG("B0 %u, B1 %u\n", buffer[0], buffer[1]); PRINTFDEBUG("ch0 %lu, ch1 %lu\n", ch0, ch1); ratio = (ch1 << 10); - ratio = ratio/ch0; - lratio = (ratio+1) >> 1; + ratio = ratio / ch0; + lratio = (ratio + 1) >> 1; PRINTFDEBUG("ratio %lu, lratio %lu\n", ratio, lratio); - if ((lratio >= 0) && (lratio <= K1T)) - tmp = (ch0*B1T) - (ch1*M1T); - else if (lratio <= K2T) - tmp = (ch0*B2T) - (ch1*M2T); - else if (lratio <= K3T) - tmp = (ch0*B3T) - (ch1*M3T); - else if (lratio <= K4T) - tmp = (ch0*B4T) - (ch1*M4T); - else if (lratio <= K5T) - tmp = (ch0*B5T) - (ch1*M5T); - else if (lratio <= K6T) - tmp = (ch0*B6T) - (ch1*M6T); - else if (lratio <= K7T) - tmp = (ch0*B7T) - (ch1*M7T); - else if (lratio > K8T) - tmp = (ch0*B8T) - (ch1*M8T); + if((lratio >= 0) && (lratio <= K1T)) { + tmp = (ch0 * B1T) - (ch1 * M1T); + } else if(lratio <= K2T) { + tmp = (ch0 * B2T) - (ch1 * M2T); + } else if(lratio <= K3T) { + tmp = (ch0 * B3T) - (ch1 * M3T); + } else if(lratio <= K4T) { + tmp = (ch0 * B4T) - (ch1 * M4T); + } else if(lratio <= K5T) { + tmp = (ch0 * B5T) - (ch1 * M5T); + } else if(lratio <= K6T) { + tmp = (ch0 * B6T) - (ch1 * M6T); + } else if(lratio <= K7T) { + tmp = (ch0 * B7T) - (ch1 * M7T); + } else if(lratio > K8T) { + tmp = (ch0 * B8T) - (ch1 * M8T); + } - if (tmp < 0) tmp = 0; - - tmp += (1<<13); + if(tmp < 0) { + tmp = 0; + } + + tmp += (1 << 13); PRINTFDEBUG("tmp %lu\n", tmp); - return (tmp >> 14); + return tmp >> 14; } - /*---------------------------------------------------------------------------*/ /* Init the light ziglet sensor: ports, pins, registers, interrupts (none enabled), I2C, default threshold values etc. */ void -light_ziglet_init (void) +light_ziglet_init(void) { - if (!(_TSL2563_STATUS & INITED)) - { - PRINTFDEBUG ("light ziglet init\n"); - _TSL2563_STATUS |= INITED; + if(!(_TSL2563_STATUS & INITED)) { + PRINTFDEBUG("light ziglet init\n"); + _TSL2563_STATUS |= INITED; - /* Set up ports and pins for I2C communication */ - i2c_enable (); - return; - } + /* Set up ports and pins for I2C communication */ + i2c_enable(); + return; + } } - /*---------------------------------------------------------------------------*/ /* Write to a 16-bit register. args: reg register to write to val value to write -*/ + */ void -tsl2563_write_reg (uint8_t reg, uint16_t val) +tsl2563_write_reg(uint8_t reg, uint16_t val) { uint8_t tx_buf[] = { reg, 0x00, 0x00 }; - tx_buf[1] = (uint8_t) (val >> 8); - tx_buf[2] = (uint8_t) (val & 0x00FF); + tx_buf[1] = (uint8_t)(val >> 8); + tx_buf[2] = (uint8_t)(val & 0x00FF); - i2c_transmitinit (TSL2563_ADDR); - while (i2c_busy ()); - PRINTFDEBUG ("I2C Ready to TX\n"); + i2c_transmitinit(TSL2563_ADDR); + while(i2c_busy()); + PRINTFDEBUG("I2C Ready to TX\n"); - i2c_transmit_n (3, tx_buf); - while (i2c_busy ()); - PRINTFDEBUG ("WRITE_REG 0x%04X @ reg 0x%02X\n", val, reg); + i2c_transmit_n(3, tx_buf); + while(i2c_busy()); + PRINTFDEBUG("WRITE_REG 0x%04X @ reg 0x%02X\n", val, reg); } - /*---------------------------------------------------------------------------*/ /* Read register. args: reg what register to read returns the value of the read register type uint16_t -*/ + */ uint16_t -tsl2563_read_reg (uint8_t reg) +tsl2563_read_reg(uint8_t reg) { - uint16_t readBuf[] = {0x00, 0x00}; - uint8_t buf[] = { 0x00, 0x00, 0x00, 0x00}; + uint16_t readBuf[] = { 0x00, 0x00 }; + uint8_t buf[] = { 0x00, 0x00, 0x00, 0x00 }; uint16_t retVal = 0; uint8_t rtx = reg; - // Transmit the register to read - i2c_transmitinit (TSL2563_ADDR); - while (i2c_busy ()); - i2c_transmit_n (1, &rtx); - while (i2c_busy ()); + /* Transmit the register to read */ + i2c_transmitinit(TSL2563_ADDR); + while(i2c_busy()); + i2c_transmit_n(1, &rtx); + while(i2c_busy()); - // Receive the data - i2c_receiveinit (TSL2563_ADDR); - while (i2c_busy ()); - i2c_receive_n (4, &buf[0]); - while (i2c_busy ()); + /* Receive the data */ + i2c_receiveinit(TSL2563_ADDR); + while(i2c_busy()); + i2c_receive_n(4, buf); + while(i2c_busy()); PRINTFDEBUG("\nb0 %u, b1 %u, b2 %u, b3 %u\n", buf[0], buf[1], buf[2], buf[3]); readBuf[0] = (buf[1] << 8 | (buf[0])); readBuf[1] = (buf[3] << 8 | (buf[2])); - /* XXX Quick hack, was receiving dups bytes */ - - if(readBuf[0] == readBuf[1]){ - tsl2563_read_reg(TSL2563_READ); - return; - } else { - retVal = calculateLux(&readBuf); - return retVal; - } + retVal = calculateLux(readBuf); + return retVal; } - uint16_t light_ziglet_on(void) { uint16_t data; - uint8_t regon[] = { 0x00, TSL2563_PWRN }; - // Turn on the sensor - i2c_transmitinit (TSL2563_ADDR); - while (i2c_busy ()); - i2c_transmit_n (2, ®on); - while (i2c_busy ()); - data = (uint16_t) tsl2563_read_reg (TSL2563_READ); + uint8_t regon = TSL2563_PWRN; + /* Turn on the sensor */ + i2c_transmitinit(TSL2563_ADDR); + while(i2c_busy()); + i2c_transmit_n(1, ®on); + while(i2c_busy()); + data = (uint16_t)tsl2563_read_reg(TSL2563_READ); return data; } - void light_ziglet_off(void) { uint8_t regoff = 0x00; - // Turn off the sensor - i2c_transmitinit (TSL2563_ADDR); - while (i2c_busy ()); - i2c_transmit_n (1, ®off); - while (i2c_busy ()); + /* Turn off the sensor */ + i2c_transmitinit(TSL2563_ADDR); + while(i2c_busy()); + i2c_transmit_n(1, ®off); + while(i2c_busy()); return; } - - /*---------------------------------------------------------------------------*/ /* Read light ziglet sensor -*/ + */ uint16_t light_ziglet_read(void) @@ -230,4 +217,3 @@ light_ziglet_read(void) light_ziglet_off(); return lux; } - diff --git a/platform/z1/dev/light-ziglet.h b/platform/z1/dev/light-ziglet.h index 6b100c551..4db18e24e 100644 --- a/platform/z1/dev/light-ziglet.h +++ b/platform/z1/dev/light-ziglet.h @@ -43,35 +43,33 @@ #include #include "i2cmaster.h" -/* -------------------------------------------------------------------------- */ -/* Init the light ziglet sensor: ports, pins, I2C, interrupts (XXX none so far), -*/ +/* Init the light ziglet sensor: ports, pins, I2C, interrupts */ void light_ziglet_init(void); /* Write to a register. args: reg register to write to val value to write -*/ + */ void tsl2563_write_reg(uint8_t reg, uint16_t val); /* Read one register. args: reg what register to read returns the value of the read register -*/ + */ uint16_t tsl2563_read_reg(uint8_t reg); -/* Takes a single light reading +/* Takes a single light reading args: none returns a lux value -*/ + */ uint16_t light_ziglet_read(); /* Calculates the lux values from the calibration table args: raw values from sensor returns a lux value -*/ + */ uint16_t calculateLux(uint16_t *readRaw); /* Turns the light ziglet ON and polls the sensor for a light reading */ @@ -85,7 +83,7 @@ uint16_t light_ziglet_on(void); /* Registers */ #define TSL2563_READ 0xAC -#define TSL2563_PWRN 0x03 +#define TSL2563_PWRN 0x03 /* Calibration settings */ #define K1T 0X0040 @@ -123,5 +121,3 @@ uint16_t light_ziglet_on(void); /* -------------------------------------------------------------------------- */ #endif /* ifndef LIGHT_ZIGLET_H_ */ - - diff --git a/platform/z1/dev/light.c b/platform/z1/dev/light.c deleted file mode 100644 index ad1fb88d6..000000000 --- a/platform/z1/dev/light.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2011, Zolertia(TM) is a trademark of Advancare,SL - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - * - * \file - * Dummy light-sensor to allow as many programs for sky to compile for Z1 - * - * \author - * Enric M. Calvo , adapted from previous work - * - */ - -#include -#include "contiki.h" -#include "dev/light.h" - -/* - * Initialize periodic readings from the 2 photo diodes. The most - * recent readings will be stored in ADC internal registers/memory. - */ -void -sensors_light_init(void) -{ -} - -/* Photosynthetically Active Radiation. */ -unsigned -sensors_light1(void) -{ - return 0; -} - -/* Total Solar Radiation. */ -unsigned -sensors_light2(void) -{ - return 0; -} - -/* - * Most of this information taken from - * http://www.moteiv.com/community/Getting_Data_from_Tmote_Sky%27s_Sensors - * - * The Photosynthetically Active Radiation (PAR) sensor as well as the - * Total Solar Radiation (TSR) sensor uses the 2.5V reference voltage - * to produce the raw ADC value. - - * The voltage across each sensor is: - * - * VsensorPAR = ADCValuePAR/4096 * Vref (1a) - * VsensorTSR = ADCValueTSR/4096 * Vref (1b) - * where Vref = 2.5V - * - * This voltage creates a current through a resistor R=100KOhm and this - * current has a linear relationship with the light intensity in Lux. - * IPAR = VsensorPAR / 100,000 (2a) - * ITSR = VsensorTSR / 100,000 (2b) - * - * S1087 (PAR) lx = 1e6 * IPAR * 1000 (3a) - * S1087-01 (TSR) lx = 1e5 * ITSR * 1000 (3b) - * - * lxPAR = 10e9 * ADCValuePAR *(1/4096)* Vref * 10e-5 or - * lxPAR = 3125* ADCvaluePAR / 512 - * and - * lxTSR = 10e8 * ADCValueTSR *(1/4096)* Vref * 10e-5 or - * lxTSR = 625* ADCvalueTSR / 1024 -*/ - -#if 0 -/* Photosynthetically Active Radiation in Lux units. */ -unsigned -sensors_light1_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM0; - - temp = (temp*3125)>> 9; - return (uint16_t)(temp & 0xFFFF); -} - -/* Total Solar Radiation in Lux units. */ -unsigned -sensors_light2_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM1; - - temp = (temp*625)>> 10; - return (uint16_t)(temp & 0xFFFF); -} -#endif diff --git a/platform/z1/dev/light.h b/platform/z1/dev/light.h deleted file mode 100644 index 52962b162..000000000 --- a/platform/z1/dev/light.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ -#ifndef LIGHT_H_ -#define LIGHT_H_ - -void sensors_light_init(void); - -unsigned sensors_light1(void); -unsigned sensors_light2(void); - -#endif /* LIGHT_H_ */ diff --git a/platform/z1/dev/reed-sensor.c b/platform/z1/dev/reed-sensor.c new file mode 100644 index 000000000..7e7a0df6d --- /dev/null +++ b/platform/z1/dev/reed-sensor.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/** + * \file + * Reed sensor driver file + * \author + * Antonio Lignan + */ + +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/reed-sensor.h" +#include "sys/process.h" +#include "sys/ctimer.h" +/*---------------------------------------------------------------------------*/ +#ifndef REED_CHECK_PERIOD +#define REED_CHECK_PERIOD CLOCK_SECOND +#endif +/*---------------------------------------------------------------------------*/ +static int current_status = -1; +static struct ctimer change_timer; +process_event_t reed_sensor_event_changed; +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return ~(REED_PORT_DIR & REED_READ_PIN); + } + return REED_SENSOR_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if((!status(SENSORS_ACTIVE)) || (type != REED_SENSOR_VAL)) { + return REED_SENSOR_ERROR; + } + return (REED_PORT_READ & REED_READ_PIN) ? REED_CLOSED : REED_OPEN; +} +/*---------------------------------------------------------------------------*/ +static void +check_callback(void *data) +{ + static int new_status; + if(current_status == -1) { + ctimer_stop(&change_timer); + return; + } + + new_status = value(REED_SENSOR_VAL); + if(new_status != current_status) { + current_status = new_status; + process_post(PROCESS_BROADCAST, reed_sensor_event_changed, ¤t_status); + } + ctimer_reset(&change_timer); +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + switch(type) { + case SENSORS_ACTIVE: + if(c) { + if(!status(SENSORS_ACTIVE)) { + REED_PORT_SEL |= REED_READ_PIN; + REED_PORT_DIR &= ~REED_READ_PIN; + REED_PORT_REN |= REED_READ_PIN; + REED_PORT_PRES |= REED_READ_PIN; + } + } else { + REED_PORT_DIR |= REED_READ_PIN; + REED_PORT_REN &= ~REED_READ_PIN; + } + return REED_SENSOR_SUCCESS; + case REED_SENSOR_MODE: + if(c == REED_SENSOR_EVENT_MODE) { + current_status = value(REED_SENSOR_VAL); + ctimer_set(&change_timer, REED_CHECK_PERIOD, check_callback, NULL); + } else if(c == REED_SENSOR_EVENT_POLL) { + current_status = -1; + ctimer_stop(&change_timer); + } else { + return REED_SENSOR_ERROR; + } + return REED_SENSOR_SUCCESS; + } + return REED_SENSOR_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(reed_sensor, REED_SENSOR, value, configure, status); diff --git a/platform/z1/dev/reed-sensor.h b/platform/z1/dev/reed-sensor.h new file mode 100644 index 000000000..7e86716f5 --- /dev/null +++ b/platform/z1/dev/reed-sensor.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/** + * Header file for the reed sensor + * + * The Reed sensor allows to be used either by polling the sensor status or by + * setting up a timer on the background ticking every REED_CHECK_PERIOD, posting + * a reed_sensor_event_changed event, informing the application about a change + * in the sensor status (basically open or closed). To enable each mode + * (default is polling) call the configure() function with REED_SENSOR_MODE + * using REED_SENSOR_EVENT_MODE or REED_SENSOR_POLL_MODE, after having + * initialized the device using SENSORS_ACTIVATE(reed_sensor). + * + * \file + * Reed sensor header file + * \author + * Antonio Lignan + */ +#include "lib/sensors.h" + +#ifndef REED_SENSOR_H_ +#define REED_SENSOR_H_ +/* -------------------------------------------------------------------------- */ +#define REED_SENSOR_ERROR -1 +#define REED_SENSOR_SUCCESS 0x00 +#define REED_SENSOR_VAL 0x01 +/* -------------------------------------------------------------------------- */ +#define REED_OPEN 0x00 +#define REED_CLOSED 0x01 +/* -------------------------------------------------------------------------- */ +#define REED_SENSOR_MODE 0x01 +#define REED_SENSOR_EVENT_MODE 0x0A +#define REED_SENSOR_EVENT_POLL 0x0B +/* -------------------------------------------------------------------------- */ +#define REED_PORT_DIR P4DIR +#define REED_PORT_SEL P4SEL +#define REED_PORT_REN P4REN +#define REED_PORT_READ P4IN +#define REED_PORT_PRES P4OUT +#define REED_READ_PIN (1 << 2) +/* -------------------------------------------------------------------------- */ +#define REED_SENSOR "Reed Sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor reed_sensor; +extern process_event_t reed_sensor_event_changed; +/* -------------------------------------------------------------------------- */ +#endif /* ifndef REED_SENSOR_H_ */ diff --git a/platform/z1/dev/relay-phidget.c b/platform/z1/dev/relay-phidget.c index 88b1e4e99..d78734b21 100644 --- a/platform/z1/dev/relay-phidget.c +++ b/platform/z1/dev/relay-phidget.c @@ -43,8 +43,7 @@ static uint8_t controlPin; -enum PHIDGET_RELAY_STATUSTYPES -{ +enum PHIDGET_RELAY_STATUSTYPES { /* must be a bit and not more, not using 0x00. */ INITED = 0x01, RUNNING = 0x02, @@ -59,49 +58,48 @@ void relay_enable(uint8_t pin) { - if (!(_RELAY_STATUS & INITED)){ + if(!(_RELAY_STATUS & INITED)) { _RELAY_STATUS |= INITED; - // Selects the pin to be configure as the control pin of the relay module + /* Selects the pin to be configure as the control pin of the relay module */ controlPin = (1 << pin); - // Configures the control pin + /* Configures the control pin */ P6SEL &= ~controlPin; P6DIR |= controlPin; } } - /*---------------------------------------------------------------------------*/ void relay_on() { - if ((_RELAY_STATUS & INITED)){ + if((_RELAY_STATUS & INITED)) { P6OUT |= controlPin; } } - /*---------------------------------------------------------------------------*/ void relay_off() { - if ((_RELAY_STATUS & INITED)){ + if((_RELAY_STATUS & INITED)) { P6OUT &= ~controlPin; } } - /*---------------------------------------------------------------------------*/ -uint8_t +int8_t relay_toggle() { - uint8_t status; - if ((_RELAY_STATUS & INITED)){ + if((_RELAY_STATUS & INITED)) { P6OUT ^= controlPin; - if((P6OUT & controlPin)) return 1; + if((P6OUT & controlPin)) { + return 1; + } return 0; } + return -1; } /*---------------------------------------------------------------------------*/ diff --git a/platform/z1/dev/relay-phidget.h b/platform/z1/dev/relay-phidget.h index 9cc4b3475..580151f58 100644 --- a/platform/z1/dev/relay-phidget.h +++ b/platform/z1/dev/relay-phidget.h @@ -44,7 +44,6 @@ void relay_enable(uint8_t pin); void relay_on(); void relay_off(); -uint8_t relay_toogle(); - +int8_t relay_toggle(); #endif /* RELAY_PHIDGET_H_ */ diff --git a/platform/z1/dev/sht25.c b/platform/z1/dev/sht25.c new file mode 100644 index 000000000..b8356087b --- /dev/null +++ b/platform/z1/dev/sht25.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/** + * \file + * SHT25 temperature and humidity sensor driver + * \author + * Antonio Lignan + */ +#include +#include "contiki.h" +#include "i2cmaster.h" +#include "dev/sht25.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != SENSORS_ACTIVE) { + return SHT25_ERROR; + } + if(value) { + i2c_enable(); + } else { + i2c_disable(); + } + enabled = value; + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static uint16_t +sht25_read_reg(uint8_t reg) +{ + uint8_t buf[] = { 0x00, 0x00 }; + uint16_t retval; + uint8_t rtx = reg; + + /* transmit the register to read */ + i2c_transmitinit(SHT25_ADDR); + while(i2c_busy()); + i2c_transmit_n(1, &rtx); + while(i2c_busy()); + /* receive the data */ + i2c_receiveinit(SHT25_ADDR); + while(i2c_busy()); + i2c_receive_n(2, &buf[0]); + while(i2c_busy()); + + retval = (uint16_t)(buf[0] << 8 | (buf[1])); + return retval; +} +/*---------------------------------------------------------------------------*/ +static int16_t +sht25_convert(uint8_t variable, uint16_t value) +{ + int16_t rd; + uint32_t buff; + buff = (uint32_t)value; + if(variable == SHT25_VAL_TEMP) { + buff *= 17572; + buff = buff >> 16; + rd = (int16_t)buff - 4685; + } else { + buff *= 12500; + buff = buff >> 16; + rd = (int16_t)buff - 600; + rd = (rd > 10000) ? 10000 : rd; + } + return rd; +} +/*---------------------------------------------------------------------------*/ +static int16_t +sht25_read(uint8_t variable) +{ + int16_t rd; + uint16_t raw; + + if((variable != SHT25_VAL_TEMP) && (variable != SHT25_VAL_HUM)) { + return SHT25_ERROR; + } + raw = sht25_read_reg(variable); + rd = sht25_convert(variable, raw); + return rd; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return sht25_read(type); +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(sht25, SHT25_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ diff --git a/platform/z1/dev/sht25.h b/platform/z1/dev/sht25.h new file mode 100644 index 000000000..65d9399d3 --- /dev/null +++ b/platform/z1/dev/sht25.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/** + * \file + * SHT25 temperature and humidity sensor driver + * \author + * Antonio Lignan + */ +#include "lib/sensors.h" + +#ifndef SHT25_H_ +#define SHT25_H_ + +/* -------------------------------------------------------------------------- */ +#define SHT25_ADDR 0x40 +#define SHT25_TEMP_HOLD 0xE3 +#define SHT25_HUM_HOLD 0xE5 +#define SHT25_TEMP_NO_HOLD 0xF3 +#define SHT25_HUM_NO_HOLD 0xF5 +#define SHT2X_UREG_WRITE 0xE6 +#define SHT2X_UREG_READ 0xE7 +#define SHT2X_SOFT_RESET 0XFE +#define SHT2X_NULL 0x00 +/* -------------------------------------------------------------------------- */ +#define SHT2X_RES_14T_12RH 0x00 +#define SHT2X_RES_12T_08RH 0x01 +#define SHT2X_RES_13T_10RH 0x80 +#define SHT2X_RES_11T_11RH 0x81 +#define SHT2X_HEATER_ON 0x04 +#define SHT2X_HEATER_OFF 0x00 +#define SHT2X_OTP_RELOAD_EN 0x00 +#define SHT2X_OTP_RELOAD_DIS 0x02 +/* -------------------------------------------------------------------------- */ +#define SHT25_VAL_TEMP SHT25_TEMP_HOLD +#define SHT25_VAL_HUM SHT25_HUM_HOLD +#define SHT25_ERROR -1 +/* -------------------------------------------------------------------------- */ +#define SHT25_SENSOR "SHT25 Sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor sht25; +/* -------------------------------------------------------------------------- */ +#endif /* ifndef SHT25_H_ */ diff --git a/platform/z1/dev/tlc59116.c b/platform/z1/dev/tlc59116.c index 3afb3b91b..2db0bf093 100644 --- a/platform/z1/dev/tlc59116.c +++ b/platform/z1/dev/tlc59116.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2013, Jelmer Tiete. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -12,8 +12,8 @@ * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior - * written permission. - * + * written permission. + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -25,9 +25,9 @@ * 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. - * + * * This file is part of the Contiki operating system. - * + * */ /** @@ -38,13 +38,11 @@ * Jelmer Tiete, VUB */ - #include #include "contiki.h" #include "tlc59116.h" #include "i2cmaster.h" - /*---------------------------------------------------------------------------*/ /* Write to a register. * args: @@ -72,21 +70,20 @@ tlc59116_write_reg(uint8_t reg, uint8_t val) * data pointer to where the data is written from * * First byte in stream must be the register address to begin writing to. - * The data is then written from second byte and increasing. + * The data is then written from second byte and increasing. */ void -tlc59116_write_stream(uint8_t len, uint8_t * data) +tlc59116_write_stream(uint8_t len, uint8_t *data) { i2c_transmitinit(TLC59116_ADDR); while(i2c_busy()); PRINTFDEBUG("I2C Ready to TX(stream)\n"); - i2c_transmit_n(len, data); // start tx and send conf reg + i2c_transmit_n(len, data); /* start tx and send conf reg */ while(i2c_busy()); PRINTFDEBUG("WRITE_STR %u B to 0x%02X\n", len, data[0]); } - /*---------------------------------------------------------------------------*/ /* Read one register. * args: @@ -116,7 +113,6 @@ tlc59116_read_reg(uint8_t reg) return retVal; } - /*---------------------------------------------------------------------------*/ /* Read several registers in a stream. * args: @@ -126,7 +122,7 @@ tlc59116_read_reg(uint8_t reg) */ void -tlc59116_read_stream(uint8_t reg, uint8_t len, uint8_t * whereto) +tlc59116_read_stream(uint8_t reg, uint8_t len, uint8_t *whereto) { uint8_t rtx = reg; @@ -144,7 +140,6 @@ tlc59116_read_stream(uint8_t reg, uint8_t len, uint8_t * whereto) i2c_receive_n(len, whereto); while(i2c_busy()); } - /*---------------------------------------------------------------------------*/ /* Set pwm value for individual led. Make sure PWM mode is enabled. * args: @@ -155,13 +150,12 @@ tlc59116_read_stream(uint8_t reg, uint8_t len, uint8_t * whereto) void tlc59116_led(uint8_t led, uint8_t pwm) { - if(led < 0 | led > 15) { + if((led < 0) || (led > 15)) { PRINTFDEBUG("TLC59116: wrong led value."); } else { tlc59116_write_reg(led + TLC59116_PWM0, pwm); } } - /*---------------------------------------------------------------------------*/ /* Init the led driver: ports, pins, registers, interrupts (none enabled), I2C, * default threshold values etc. @@ -180,8 +174,8 @@ tlc59116_init(void) /*Set all PWM values to 0x00 (off) */ /*This would maybe be better with a SWRST */ uint8_t tx_buf[] = - { TLC59116_PWM0_AUTOINCR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - tlc59116_write_stream(17, &tx_buf); + { TLC59116_PWM0_AUTOINCR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + tlc59116_write_stream(17, tx_buf); /* set all leds to PWM control */ tlc59116_write_reg(TLC59116_LEDOUT0, TLC59116_LEDOUT_PWM); diff --git a/platform/z1/dev/tmp102.c b/platform/z1/dev/tmp102.c index 59d6b6de7..4bf267246 100644 --- a/platform/z1/dev/tmp102.c +++ b/platform/z1/dev/tmp102.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2010, Swedish Institute of Computer Science. + * Copyright (c) 2016, Zolertia * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,146 +30,113 @@ * This file is part of the Contiki operating system. * */ - +/*---------------------------------------------------------------------------*/ /** * \file * Device drivers for tmp102 temperature sensor in Zolertia Z1. * \author * Enric M. Calvo, Zolertia * Marcus Lundén, SICS + * Antonio Lignan, Zolertia */ - - +/*---------------------------------------------------------------------------*/ #include #include "contiki.h" #include "i2cmaster.h" #include "tmp102.h" - - - -/* Bitmasks and bit flag variable for keeping track of tmp102 status. */ -enum TMP102_STATUSTYPES -{ - /* must be a bit and not more, not using 0x00. */ - INITED = 0x01, - RUNNING = 0x02, - STOPPED = 0x04, - LOW_POWER = 0x08, - AAA = 0x10, // available to extend this... - BBB = 0x20, // available to extend this... - CCC = 0x40, // available to extend this... - DDD = 0x80 // available to extend this... -}; -static enum TMP102_STATUSTYPES _TMP102_STATUS = 0x00; - - +#include "lib/sensors.h" /*---------------------------------------------------------------------------*/ -//PROCESS(tmp102_process, "Temperature Sensor process"); - +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; /*---------------------------------------------------------------------------*/ -/* Init the temperature sensor: ports, pins, registers, interrupts (none enabled), I2C, - default threshold values etc. */ - void -tmp102_init (void) +tmp102_init(void) { - if (!(_TMP102_STATUS & INITED)) - { - PRINTFDEBUG ("TMP102 init\n"); - _TMP102_STATUS |= INITED; - /* Power Up TMP102 via pin */ - TMP102_PWR_DIR |= TMP102_PWR_PIN; - TMP102_PWR_SEL &= ~TMP102_PWR_SEL; - TMP102_PWR_SEL2 &= ~TMP102_PWR_SEL; - TMP102_PWR_REN &= ~TMP102_PWR_SEL; - TMP102_PWR_OUT |= TMP102_PWR_PIN; + /* Power Up TMP102 via pin */ + TMP102_PWR_DIR |= TMP102_PWR_PIN; + TMP102_PWR_SEL &= ~TMP102_PWR_SEL; + TMP102_PWR_SEL2 &= ~TMP102_PWR_SEL; + TMP102_PWR_REN &= ~TMP102_PWR_SEL; + TMP102_PWR_OUT |= TMP102_PWR_PIN; - /* Set up ports and pins for I2C communication */ - i2c_enable (); + /* Set up ports and pins for I2C communication */ + i2c_enable(); - } + enabled = 1; } - /*---------------------------------------------------------------------------*/ -/* Write to a 16-bit register. - args: - reg register to write to - val value to write -*/ - void -tmp102_write_reg (uint8_t reg, uint16_t val) +tmp102_stop(void) +{ + /* Power off */ + TMP102_PWR_OUT &= ~TMP102_PWR_PIN; + enabled = 0; +} +/*---------------------------------------------------------------------------*/ +void +tmp102_write_reg(uint8_t reg, uint16_t val) { uint8_t tx_buf[] = { reg, 0x00, 0x00 }; - tx_buf[1] = (uint8_t) (val >> 8); - tx_buf[2] = (uint8_t) (val & 0x00FF); + tx_buf[1] = (uint8_t)(val >> 8); + tx_buf[2] = (uint8_t)(val & 0x00FF); - i2c_transmitinit (TMP102_ADDR); - while (i2c_busy ()); - PRINTFDEBUG ("I2C Ready to TX\n"); + i2c_transmitinit(TMP102_ADDR); + while(i2c_busy()); + PRINTF("I2C Ready to TX\n"); - i2c_transmit_n (3, tx_buf); - while (i2c_busy ()); - PRINTFDEBUG ("WRITE_REG 0x%04X @ reg 0x%02X\n", val, reg); + i2c_transmit_n(3, tx_buf); + while(i2c_busy()); + PRINTF("WRITE_REG 0x%04X @ reg 0x%02X\n", val, reg); } - /*---------------------------------------------------------------------------*/ -/* Read register. - args: - reg what register to read - returns the value of the read register type uint16_t -*/ - uint16_t -tmp102_read_reg (uint8_t reg) +tmp102_read_reg(uint8_t reg) { uint8_t buf[] = { 0x00, 0x00 }; uint16_t retVal = 0; uint8_t rtx = reg; - PRINTFDEBUG ("READ_REG 0x%02X\n", reg); + PRINTF("READ_REG 0x%02X\n", reg); - // transmit the register to read - i2c_transmitinit (TMP102_ADDR); - while (i2c_busy ()); - i2c_transmit_n (1, &rtx); - while (i2c_busy ()); + /* transmit the register to read */ + i2c_transmitinit(TMP102_ADDR); + while(i2c_busy()); + i2c_transmit_n(1, &rtx); + while(i2c_busy()); - // receive the data - i2c_receiveinit (TMP102_ADDR); - while (i2c_busy ()); - i2c_receive_n (2, &buf[0]); - while (i2c_busy ()); + /* receive the data */ + i2c_receiveinit(TMP102_ADDR); + while(i2c_busy()); + i2c_receive_n(2, &buf[0]); + while(i2c_busy()); - retVal = (uint16_t) (buf[0] << 8 | (buf[1])); + retVal = (uint16_t)(buf[0] << 8 | (buf[1])); return retVal; } - /*---------------------------------------------------------------------------*/ -/* Read temperature in a raw format. Further processing will be needed - to make an interpretation of these 12 or 13-bit data, depending on configuration -*/ - uint16_t -tmp102_read_temp_raw (void) +tmp102_read_temp_raw(void) { uint16_t rd = 0; - - rd = tmp102_read_reg (TMP102_TEMP); - + rd = tmp102_read_reg(TMP102_TEMP); return rd; } - +/*---------------------------------------------------------------------------*/ int16_t tmp102_read_temp_x100(void) { int16_t raw = 0; - int8_t rd = 0; int16_t sign = 1; int16_t abstemp, temp_int; - raw = (int16_t) tmp102_read_reg (TMP102_TEMP); + raw = (int16_t)tmp102_read_reg(TMP102_TEMP); if(raw < 0) { abstemp = (raw ^ 0xFFFF) + 1; sign = -1; @@ -179,24 +147,47 @@ tmp102_read_temp_x100(void) /* Integer part of the temperature value and percents*/ temp_int = (abstemp >> 8) * sign * 100; temp_int += ((abstemp & 0xff) * 100) / 0x100; - - /* See test-tmp102.c on how to print values of temperature with decimals - fractional part in 1/10000 of degree - temp_frac = ((abstemp >>4) % 16) * 625; - Data could be multiplied by 63 to have less bit-growth and 1/1000 precision - Data could be multiplied by 64 (<< 6) to trade-off precision for speed - */ - return temp_int; } - /*---------------------------------------------------------------------------*/ -/* Simple Read temperature. Return is an integer with temperature in 1deg. precision - Return value is a signed 8 bit integer. -*/ - int8_t -tmp102_read_temp_simple (void) +tmp102_read_temp_simple(void) { - return (int8_t) tmp102_read_temp_x100() / 100; + /* Casted to int8_t: We don't expect temperatures outside -128 to 127 C */ + return tmp102_read_temp_x100() / 100; } +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != SENSORS_ACTIVE) { + return TMP102_ERROR; + } + if(value) { + tmp102_init(); + } else { + tmp102_stop(); + } + enabled = value; + return TMP102_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return TMP102_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return (int)tmp102_read_temp_x100(); +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(tmp102, TMP102_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ diff --git a/platform/z1/dev/tmp102.h b/platform/z1/dev/tmp102.h index 777577747..cf7a71eb8 100644 --- a/platform/z1/dev/tmp102.h +++ b/platform/z1/dev/tmp102.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010, Swedish Institute of Computer Science. + * Copyright (c) 2016, Zolertia * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,75 +33,47 @@ /** * \file - * Device drivers header file for tmp102 temperature sensor in Zolertia Z1 WSN Platform. + * Device drivers header file for tmp102 temperature sensor in Zolertia + * Z1 WSN Platform. * \author * Enric M. Calvo, Zolertia * Marcus Lundén, SICS + * Antonio Lignan, Zolertia */ - +/* -------------------------------------------------------------------------- */ #ifndef TMP102_H_ #define TMP102_H_ #include +#include "lib/sensors.h" #include "i2cmaster.h" - /* -------------------------------------------------------------------------- */ -/* Init the temperature sensor: ports, pins, I2C, interrupts (XXX none so far), -*/ -void tmp102_init(void); - -/* Write to a register. - args: - reg register to write to - val value to write -*/ -void tmp102_write_reg(uint8_t reg, uint16_t val); - -/* Read one register. - args: - reg what register to read - returns the value of the read register -*/ +void tmp102_init(void); +void tmp102_write_reg(uint8_t reg, uint16_t val); uint16_t tmp102_read_reg(uint8_t reg); - -/* Read temperature in raw format - no args needed -*/ uint16_t tmp102_read_temp_raw(); - -/* Read only integer part of the temperature in 1deg. precision. - no args needed -*/ int8_t tmp102_read_temp_simple(); - -/* Read only integer part of the temperature in 1deg. precision. - no args needed -*/ int16_t tmp102_read_temp_x100(); - /* -------------------------------------------------------------------------- */ -/* Reference definitions */ -/* TMP102 slave address */ #define TMP102_ADDR 0x48 - -/* TMP102 registers */ -#define TMP102_TEMP 0x00 // read only +#define TMP102_TEMP 0x00 #define TMP102_CONF 0x01 #define TMP102_TLOW 0x02 #define TMP102_THIGH 0x03 -/* TMP102 Ports */ -/* Accelerometer hardware ports, pins and registers on the msp430 µC */ +/* TMP102 pin-out */ #define TMP102_PWR_DIR P5DIR #define TMP102_PWR_SEL P5SEL #define TMP102_PWR_SEL2 P5SEL2 #define TMP102_PWR_REN P5REN #define TMP102_PWR_OUT P5OUT -#define TMP102_PWR_PIN (1<<0) // P5.0 -//#define TMP102_INT_PIN (1<<7) // P1.7 - - +#define TMP102_PWR_PIN (1<<0) /* P5.0 */ +/* -------------------------------------------------------------------------- */ +#define TMP102_SUCCESS 0 +#define TMP102_ERROR (-1) +#define TMP102_READ 0x01 +/* -------------------------------------------------------------------------- */ +#define TMP102_SENSOR "TMP102 sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor tmp102; /* -------------------------------------------------------------------------- */ #endif /* ifndef TMP102_H_ */ - - - diff --git a/platform/z1/node-id.c b/platform/z1/node-id.c index fb0c72582..9514b6347 100644 --- a/platform/z1/node-id.c +++ b/platform/z1/node-id.c @@ -42,7 +42,6 @@ #include "dev/xmem.h" #include - unsigned short node_id = 0; unsigned char node_mac[8]; @@ -65,11 +64,11 @@ void node_id_burn(unsigned short id) { unsigned char buf[12]; + memset(buf, 0, sizeof(buf)); buf[0] = 0xad; buf[1] = 0xde; buf[2] = id >> 8; buf[3] = id & 0xff; - memcpy(&buf[4], node_mac, 8); xmem_erase(XMEM_ERASE_UNIT_SIZE, NODE_ID_XMEM_OFFSET); xmem_pwrite(buf, 12, NODE_ID_XMEM_OFFSET); } diff --git a/platform/z1/platform-conf.h b/platform/z1/platform-conf.h index 28a17d17d..15cab1127 100644 --- a/platform/z1/platform-conf.h +++ b/platform/z1/platform-conf.h @@ -43,17 +43,27 @@ */ #define ZOLERTIA_Z1 1 /* Enric */ -#define PLATFORM_HAS_LEDS 1 -#define PLATFORM_HAS_BUTTON 1 +/* Delay between GO signal and SFD: radio fixed delay + 4Bytes preample + 1B SFD -- 1Byte time is 32us + * ~327us + 129preample = 456 us */ +#define RADIO_DELAY_BEFORE_TX ((unsigned)US_TO_RTIMERTICKS(456)) +/* Delay between GO signal and start listening + * ~50us delay + 129preample + ?? = 183 us */ +#define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(183)) +/* Delay between the SFD finishes arriving and it is detected in software */ +#define RADIO_DELAY_BEFORE_DETECT 0 + +#define PLATFORM_HAS_LEDS 1 +#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_RADIO 1 +#define PLATFORM_HAS_BATTERY 1 /* CPU target speed in Hz */ #define F_CPU 8000000uL /* 8MHz by default */ -//Enric #define F_CPU 3900000uL /*2457600uL*/ /* Our clock resolution, this is the same as Unix HZ. */ #define CLOCK_CONF_SECOND 128UL -#define BAUD2UBR(baud) ((F_CPU/baud)) +#define BAUD2UBR(baud) ((F_CPU / baud)) #define CCIF #define CLIF @@ -65,21 +75,21 @@ #ifdef __IAR_SYSTEMS_ICC__ #ifndef P1SEL2_ #define P1SEL2_ (0x0041u) /* Port 1 Selection 2*/ -DEFC( P1SEL2 , P1SEL2_) +DEFC(P1SEL2, P1SEL2_) #endif #ifndef P5SEL2_ #define P5SEL2_ (0x0045u) /* Port 5 Selection 2*/ -DEFC( P5SEL2 , P5SEL2_) +DEFC(P5SEL2, P5SEL2_) #endif #else /* __IAR_SYSTEMS_ICC__ */ #ifdef __GNUC__ #ifndef P1SEL2_ - #define P1SEL2_ 0x0041 /* Port 1 Selection 2*/ - sfrb(P1SEL2, P1SEL2_); +#define P1SEL2_ 0x0041 /* Port 1 Selection 2*/ +sfrb(P1SEL2, P1SEL2_); #endif #ifndef P5SEL2_ - #define P5SEL2_ 0x0045 /* Port 5 Selection 2*/ - sfrb(P5SEL2, P5SEL2_); +#define P5SEL2_ 0x0045 /* Port 5 Selection 2*/ +sfrb(P5SEL2, P5SEL2_); #endif #endif /* __GNUC__ */ #endif /* __IAR_SYSTEMS_ICC__ */ @@ -98,19 +108,26 @@ typedef unsigned long off_t; */ /* LED ports */ +#ifdef Z1_IS_Z1SP +#define LEDS_PxDIR P4DIR +#define LEDS_PxOUT P4OUT +#define LEDS_CONF_RED 0x04 +#define LEDS_CONF_GREEN 0x01 +#define LEDS_CONF_YELLOW 0x80 +#else #define LEDS_PxDIR P5DIR #define LEDS_PxOUT P5OUT #define LEDS_CONF_RED 0x10 #define LEDS_CONF_GREEN 0x40 #define LEDS_CONF_YELLOW 0x20 +#endif /* Z1_IS_Z1SP */ /* DCO speed resynchronization for more robust UART, etc. */ #define DCOSYNCH_CONF_ENABLED 0 #define DCOSYNCH_CONF_PERIOD 30 #define ROM_ERASE_UNIT_SIZE 512 -#define XMEM_ERASE_UNIT_SIZE (64*1024L) - +#define XMEM_ERASE_UNIT_SIZE (64 * 1024L) #define CFS_CONF_OFFSET_TYPE long @@ -126,19 +143,19 @@ typedef unsigned long off_t; #define CFS_RAM_CONF_SIZE 4096 /* - * SPI bus configuration for the TMote Sky. + * SPI bus configuration for the Z1 mote. */ /* SPI input/output registers. */ #define SPI_TXBUF UCB0TXBUF #define SPI_RXBUF UCB0RXBUF - /* USART0 Tx ready? */ -#define SPI_WAITFOREOTx() while ((UCB0STAT & UCBUSY) != 0) - /* USART0 Rx ready? */ -#define SPI_WAITFOREORx() while ((IFG2 & UCB0RXIFG) == 0) - /* USART0 Tx buffer ready? */ -#define SPI_WAITFORTxREADY() while ((IFG2 & UCB0TXIFG) == 0) +/* USART0 Tx ready? */ +#define SPI_WAITFOREOTx() while((UCB0STAT & UCBUSY) != 0) +/* USART0 Rx ready? */ +#define SPI_WAITFOREORx() while((IFG2 & UCB0RXIFG) == 0) +/* USART0 Tx buffer ready? */ +#define SPI_WAITFORTxREADY() while((IFG2 & UCB0TXIFG) == 0) #define MOSI 1 /* P3.1 - Output: SPI Master out - slave in (MOSI) */ #define MISO 2 /* P3.2 - Input: SPI Master in - slave out (MISO) */ @@ -147,24 +164,23 @@ typedef unsigned long off_t; /* * SPI bus - M25P80 external flash configuration. */ -//#define FLASH_PWR 3 /* P4.3 Output */ ALWAYS POWERED ON Z1 -#define FLASH_CS 4 /* P4.4 Output */ -#define FLASH_HOLD 7 /* P5.7 Output */ +/* FLASH_PWR P4.3 Output ALWAYS POWERED ON Z1 */ +#define FLASH_CS 4 /* P4.4 Output */ +#define FLASH_HOLD 7 /* P5.7 Output */ /* Enable/disable flash access to the SPI bus (active low). */ -#define SPI_FLASH_ENABLE() ( P4OUT &= ~BV(FLASH_CS) ) -#define SPI_FLASH_DISABLE() ( P4OUT |= BV(FLASH_CS) ) - -#define SPI_FLASH_HOLD() ( P5OUT &= ~BV(FLASH_HOLD) ) -#define SPI_FLASH_UNHOLD() ( P5OUT |= BV(FLASH_HOLD) ) +#define SPI_FLASH_ENABLE() (P4OUT &= ~BV(FLASH_CS)) +#define SPI_FLASH_DISABLE() (P4OUT |= BV(FLASH_CS)) +#define SPI_FLASH_HOLD() (P5OUT &= ~BV(FLASH_HOLD)) +#define SPI_FLASH_UNHOLD() (P5OUT |= BV(FLASH_HOLD)) /* * SPI bus - CC2420 pin configuration. */ -#define CC2420_CONF_SYMBOL_LOOP_COUNT 1302 /* 326us msp430X @ 8MHz */ +#define CC2420_CONF_SYMBOL_LOOP_COUNT 1302 /* 326us msp430X @ 8MHz */ /* P1.2 - Input: FIFOP from CC2420 */ #define CC2420_FIFOP_PORT(type) P1##type @@ -178,7 +194,7 @@ typedef unsigned long off_t; /* P4.1 - Input: SFD from CC2420 */ #define CC2420_SFD_PORT(type) P4##type #define CC2420_SFD_PIN 1 - /* P3.0 - Output: SPI Chip Select (CS_N) */ +/* P3.0 - Output: SPI Chip Select (CS_N) */ #define CC2420_CSN_PORT(type) P3##type #define CC2420_CSN_PIN 0 /* P4.5 - Output: VREG_EN to CC2420 */ @@ -188,7 +204,6 @@ typedef unsigned long off_t; #define CC2420_RESET_PORT(type) P4##type #define CC2420_RESET_PIN 6 - #define CC2420_IRQ_VECTOR PORT1_VECTOR /* Pin status. */ @@ -198,33 +213,69 @@ typedef unsigned long off_t; #define CC2420_SFD_IS_1 (!!(CC2420_SFD_PORT(IN) & BV(CC2420_SFD_PIN))) /* The CC2420 reset pin. */ -#define SET_RESET_INACTIVE() (CC2420_RESET_PORT(OUT) |= BV(CC2420_RESET_PIN)) +#define SET_RESET_INACTIVE() (CC2420_RESET_PORT(OUT) |= BV(CC2420_RESET_PIN)) #define SET_RESET_ACTIVE() (CC2420_RESET_PORT(OUT) &= ~BV(CC2420_RESET_PIN)) /* CC2420 voltage regulator enable pin. */ -#define SET_VREG_ACTIVE() (CC2420_VREG_PORT(OUT) |= BV(CC2420_VREG_PIN)) +#define SET_VREG_ACTIVE() (CC2420_VREG_PORT(OUT) |= BV(CC2420_VREG_PIN)) #define SET_VREG_INACTIVE() (CC2420_VREG_PORT(OUT) &= ~BV(CC2420_VREG_PIN)) /* CC2420 rising edge trigger for external interrupt 0 (FIFOP). */ -#define CC2420_FIFOP_INT_INIT() do { \ - CC2420_FIFOP_PORT(IES) &= ~BV(CC2420_FIFOP_PIN); \ - CC2420_CLEAR_FIFOP_INT(); \ - } while(0) +#define CC2420_FIFOP_INT_INIT() do { \ + CC2420_FIFOP_PORT(IES) &= ~BV(CC2420_FIFOP_PIN); \ + CC2420_CLEAR_FIFOP_INT(); \ +} while(0) /* FIFOP on external interrupt 0. */ -#define CC2420_ENABLE_FIFOP_INT() do {CC2420_FIFOP_PORT(IE) |= BV(CC2420_FIFOP_PIN);} while(0) -#define CC2420_DISABLE_FIFOP_INT() do {CC2420_FIFOP_PORT(IE) &= ~BV(CC2420_FIFOP_PIN);} while(0) -#define CC2420_CLEAR_FIFOP_INT() do {CC2420_FIFOP_PORT(IFG) &= ~BV(CC2420_FIFOP_PIN);} while(0) +#define CC2420_ENABLE_FIFOP_INT() do { CC2420_FIFOP_PORT(IE) |= BV(CC2420_FIFOP_PIN); } while(0) +#define CC2420_DISABLE_FIFOP_INT() do { CC2420_FIFOP_PORT(IE) &= ~BV(CC2420_FIFOP_PIN); } while(0) +#define CC2420_CLEAR_FIFOP_INT() do { CC2420_FIFOP_PORT(IFG) &= ~BV(CC2420_FIFOP_PIN); } while(0) /* * Enables/disables CC2420 access to the SPI bus (not the bus). * (Chip Select) */ - /* ENABLE CSn (active low) */ +/* ENABLE CSn (active low) */ #define CC2420_SPI_ENABLE() (CC2420_CSN_PORT(OUT) &= ~BV(CC2420_CSN_PIN)) - /* DISABLE CSn (active low) */ -#define CC2420_SPI_DISABLE() (CC2420_CSN_PORT(OUT) |= BV(CC2420_CSN_PIN)) +/* DISABLE CSn (active low) */ +#define CC2420_SPI_DISABLE() (CC2420_CSN_PORT(OUT) |= BV(CC2420_CSN_PIN)) #define CC2420_SPI_IS_ENABLED() ((CC2420_CSN_PORT(OUT) & BV(CC2420_CSN_PIN)) != BV(CC2420_CSN_PIN)) +/* + * I2C configuration + */ + +#define I2C_PxDIR P5DIR +#define I2C_PxIN P5IN +#define I2C_PxOUT P5OUT +#define I2C_PxSEL P5SEL +#define I2C_PxSEL2 P5SEL2 +#define I2C_PxREN P5REN + +#define I2C_SDA (1 << 1) /* SDA == P5.1 */ +#define I2C_SCL (1 << 2) /* SCL == P5.2 */ +#define I2C_PRESC_1KHZ_LSB 0x00 +#define I2C_PRESC_1KHZ_MSB 0x20 +#define I2C_PRESC_100KHZ_LSB 0x50 +#define I2C_PRESC_100KHZ_MSB 0x00 +#define I2C_PRESC_400KHZ_LSB 0x14 +#define I2C_PRESC_400KHZ_MSB 0x00 + +/* Set rate as high as possible by default */ +#ifndef I2C_PRESC_Z1_LSB +#define I2C_PRESC_Z1_LSB I2C_PRESC_400KHZ_LSB +#endif + +#ifndef I2C_PRESC_Z1_MSB +#define I2C_PRESC_Z1_MSB I2C_PRESC_400KHZ_MSB +#endif + +/* I2C configuration with RX interrupts */ +#ifdef I2C_CONF_RX_WITH_INTERRUPT +#define I2C_RX_WITH_INTERRUPT I2C_CONF_RX_WITH_INTERRUPT +#else /* I2C_CONF_RX_WITH_INTERRUPT */ +#define I2C_RX_WITH_INTERRUPT 1 +#endif /* I2C_CONF_RX_WITH_INTERRUPT */ + #endif /* PLATFORM_CONF_H_ */ diff --git a/platform/z1sp/Makefile.z1sp b/platform/z1sp/Makefile.z1sp deleted file mode 100644 index 87cd91c85..000000000 --- a/platform/z1sp/Makefile.z1sp +++ /dev/null @@ -1,18 +0,0 @@ -# Makefile for Z1 Starter Platform, adapted from the Z1 platform makefile - -CFLAGS += -DCONTIKI_TARGET_Z1 - -CONTIKI_TARGET_DIRS += . dev -#CONTIKI_CORE=contiki-z1sp-main -#CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.c - -# include here -CONTIKI_TARGET_SOURCEFILES += contiki-z1sp-platform.c potentiometer-sensor.c - -CONTIKIZ1PLATFORMDIR = $(CONTIKI)/platform/z1 - -CLEAN += *.z1sp - -include $(CONTIKIZ1PLATFORMDIR)/Makefile.common - -CONTIKI_TARGET_DIRS += ${addprefix $(CONTIKIZ1PLATFORMDIR)/,. dev apps net} diff --git a/platform/z1sp/contiki-conf.h b/platform/z1sp/contiki-conf.h deleted file mode 100644 index a0cfb9699..000000000 --- a/platform/z1sp/contiki-conf.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - */ - -#ifndef CONTIKI_CONF_H -#define CONTIKI_CONF_H - - -#include "platform-conf.h" - -#define XMAC_CONF_COMPOWER 1 -#define CXMAC_CONF_COMPOWER 1 - -#if WITH_UIP6 - -/* Network setup for IPv6 */ -#define NETSTACK_CONF_NETWORK sicslowpan_driver -/* #define NETSTACK_CONF_MAC nullmac_driver */ -/* #define NETSTACK_CONF_RDC sicslowmac_driver */ -#define NETSTACK_CONF_MAC csma_driver -#define NETSTACK_CONF_RDC contikimac_driver -#define NETSTACK_CONF_RADIO cc2420_driver -#define NETSTACK_CONF_FRAMER framer_802154 - -#define CC2420_CONF_AUTOACK 1 -#define NETSTACK_RDC_CHANNEL_CHECK_RATE 8 -#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 -#define CXMAC_CONF_ANNOUNCEMENTS 0 -#define XMAC_CONF_ANNOUNCEMENTS 0 - -#define QUEUEBUF_CONF_NUM 4 - -#else /* WITH_UIP6 */ - -/* Network setup for non-IPv6 (rime). */ - -#define NETSTACK_CONF_NETWORK rime_driver -#define NETSTACK_CONF_MAC csma_driver -/* #define NETSTACK_CONF_RDC contikimac_driver */ -#define NETSTACK_CONF_RDC nullrdc_driver -#define NETSTACK_CONF_FRAMER framer_802154 - -#define CC2420_CONF_AUTOACK 0 - -#define COLLECT_CONF_ANNOUNCEMENTS 1 -#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 -#define CXMAC_CONF_ANNOUNCEMENTS 0 -#define XMAC_CONF_ANNOUNCEMENTS 0 -#define CONTIKIMAC_CONF_ANNOUNCEMENTS 0 - -#define CONTIKIMAC_CONF_COMPOWER 1 -#define XMAC_CONF_COMPOWER 1 -#define CXMAC_CONF_COMPOWER 1 - -#define COLLECT_NBR_TABLE_CONF_MAX_NEIGHBORS 32 - -#define QUEUEBUF_CONF_NUM 8 - -#endif /* WITH_UIP6 */ - -#define PACKETBUF_CONF_ATTRS_INLINE 1 - -#ifndef RF_CHANNEL -#define RF_CHANNEL 26 -#endif /* RF_CHANNEL */ - -#define IEEE802154_CONF_PANID 0xABCD - -#define SHELL_VARS_CONF_RAM_BEGIN 0x1100 -#define SHELL_VARS_CONF_RAM_END 0x2000 - - -#define CFS_CONF_OFFSET_TYPE long - -#define PROFILE_CONF_ON 0 -#define ENERGEST_CONF_ON 0 - -#define ELFLOADER_CONF_TEXT_IN_ROM 0 -#define ELFLOADER_CONF_DATAMEMORY_SIZE 0x400 -#define ELFLOADER_CONF_TEXTMEMORY_SIZE 0x800 - -#define CCIF -#define CLIF - -#define CC_CONF_INLINE inline - -#define AODV_COMPLIANCE -#define AODV_NUM_RT_ENTRIES 32 - -#define WITH_ASCII 1 - -#define PROCESS_CONF_NUMEVENTS 8 -#define PROCESS_CONF_STATS 1 -/*#define PROCESS_CONF_FASTPOLL 4*/ - - -#define UART0_CONF_TX_WITH_INTERRUPT 0 // So far, printfs without interrupt. - -#ifdef WITH_UIP6 - -#define LINKADDR_CONF_SIZE 8 - -#define UIP_CONF_LL_802154 1 -#define UIP_CONF_LLH_LEN 0 - -#define UIP_CONF_ROUTER 1 -#define UIP_CONF_IPV6_RPL 1 - -/* Handle 10 neighbors */ -#define NBR_TABLE_CONF_MAX_NEIGHBORS 15 -/* Handle 10 routes */ -#define UIP_CONF_MAX_ROUTES 15 - -#define UIP_CONF_ND6_SEND_RA 0 -#define UIP_CONF_ND6_REACHABLE_TIME 600000 -#define UIP_CONF_ND6_RETRANS_TIMER 10000 - -#define UIP_CONF_IPV6 1 -#define UIP_CONF_IPV6_QUEUE_PKT 0 -#define UIP_CONF_IPV6_CHECKS 1 -#define UIP_CONF_IPV6_REASSEMBLY 0 -#define UIP_CONF_NETIF_MAX_ADDRESSES 3 -#define UIP_CONF_ND6_MAX_PREFIXES 3 -#define UIP_CONF_ND6_MAX_DEFROUTERS 2 -#define UIP_CONF_IP_FORWARD 0 -#define UIP_CONF_BUFFER_SIZE 140 - -#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 -#define SICSLOWPAN_CONF_COMPRESSION_HC1 1 -#define SICSLOWPAN_CONF_COMPRESSION_HC01 2 -#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 -#ifndef SICSLOWPAN_CONF_FRAG -#define SICSLOWPAN_CONF_FRAG 1 -#define SICSLOWPAN_CONF_MAXAGE 8 -#endif /* SICSLOWPAN_CONF_FRAG */ -#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 -#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#else /* WITH_UIP6 */ -#define UIP_CONF_IP_FORWARD 1 -#define UIP_CONF_BUFFER_SIZE 108 -#endif /* WITH_UIP6 */ - -#define UIP_CONF_ICMP_DEST_UNREACH 1 - -#define UIP_CONF_DHCP_LIGHT -#define UIP_CONF_LLH_LEN 0 -#define UIP_CONF_RECEIVE_WINDOW 48 -#define UIP_CONF_TCP_MSS 48 -#define UIP_CONF_MAX_CONNECTIONS 4 -#define UIP_CONF_MAX_LISTENPORTS 8 -#define UIP_CONF_UDP_CONNS 12 -#define UIP_CONF_FWCACHE_SIZE 30 -#define UIP_CONF_BROADCAST 1 -#define UIP_ARCH_IPCHKSUM 1 -#define UIP_CONF_UDP 1 -#define UIP_CONF_UDP_CHECKSUMS 1 -#define UIP_CONF_PINGADDRCONF 0 -#define UIP_CONF_LOGGING 0 - -#define UIP_CONF_TCP_SPLIT 0 - - -#ifdef PROJECT_CONF_H -#include PROJECT_CONF_H -#endif /* PROJECT_CONF_H */ - - - -#endif /* CONTIKI_CONF_H */ diff --git a/platform/z1sp/platform-conf.h b/platform/z1sp/platform-conf.h deleted file mode 100644 index 677942302..000000000 --- a/platform/z1sp/platform-conf.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - */ - -/** - * \file - * Platform configuration for the Z1SP platform - * \author - * Joakim Eriksson - */ - -#ifndef PLATFORM_CONF_H_ -#define PLATFORM_CONF_H_ - -/* - * Definitions below are dictated by the hardware and not really - * changeable! - */ -#define ZOLERTIA_Z1 0 /* Enric */ -#define ZOLERTIA_Z1SP 1 /* Enric */ - -/* CPU target speed in Hz */ -#define F_CPU 8000000uL /* 8MHz by default */ -//Enric #define F_CPU 3900000uL /*2457600uL*/ - -/* Our clock resolution, this is the same as Unix HZ. */ -#define CLOCK_CONF_SECOND 128UL - -#define BAUD2UBR(baud) ((F_CPU/baud)) - -#define CCIF -#define CLIF - -#define HAVE_STDINT_H -#include "msp430def.h" - -/* XXX Temporary place for defines that are lacking in mspgcc4's gpio.h */ -#ifdef __IAR_SYSTEMS_ICC__ -#ifndef P1SEL2_ -#define P1SEL2_ (0x0041u) /* Port 1 Selection 2*/ -DEFC( P1SEL2 , P1SEL2_) -#endif -#ifndef P5SEL2_ -#define P5SEL2_ (0x0045u) /* Port 5 Selection 2*/ -DEFC( P5SEL2 , P5SEL2_) -#endif -#else /* __IAR_SYSTEMS_ICC__ */ -#ifdef __GNUC__ -#ifndef P1SEL2_ - #define P1SEL2_ 0x0041 /* Port 1 Selection 2*/ - sfrb(P1SEL2, P1SEL2_); -#endif -#ifndef P5SEL2_ - #define P5SEL2_ 0x0045 /* Port 5 Selection 2*/ - sfrb(P5SEL2, P5SEL2_); -#endif -#endif /* __GNUC__ */ -#endif /* __IAR_SYSTEMS_ICC__ */ - -/* Types for clocks and uip_stats */ -typedef unsigned short uip_stats_t; -typedef unsigned long clock_time_t; -typedef unsigned long off_t; - -/* the low-level radio driver */ -#define NETSTACK_CONF_RADIO cc2420_driver - -/* - * Definitions below are dictated by the hardware and not really - * changeable! - */ - -/* LED ports */ -#define LEDS_PxDIR P4DIR -#define LEDS_PxOUT P4OUT -#define LEDS_CONF_RED 0x04 -#define LEDS_CONF_GREEN 0x01 -#define LEDS_CONF_YELLOW 0x80 - -/* DCO speed resynchronization for more robust UART, etc. */ -#define DCOSYNCH_CONF_ENABLED 0 -#define DCOSYNCH_CONF_PERIOD 30 - -#define ROM_ERASE_UNIT_SIZE 512 -#define XMEM_ERASE_UNIT_SIZE (64*1024L) - - -#define CFS_CONF_OFFSET_TYPE long - -/* Use the first 64k of external flash for node configuration */ -#define NODE_ID_XMEM_OFFSET (0 * XMEM_ERASE_UNIT_SIZE) - -/* Use the second 64k of external flash for codeprop. */ -#define EEPROMFS_ADDR_CODEPROP (1 * XMEM_ERASE_UNIT_SIZE) - -#define CFS_XMEM_CONF_OFFSET (2 * XMEM_ERASE_UNIT_SIZE) -#define CFS_XMEM_CONF_SIZE (1 * XMEM_ERASE_UNIT_SIZE) - -#define CFS_RAM_CONF_SIZE 4096 - -/* - * SPI bus configuration for the TMote Sky. - */ - -/* SPI input/output registers. */ -#define SPI_TXBUF UCB0TXBUF -#define SPI_RXBUF UCB0RXBUF - - /* USART0 Tx ready? */ -#define SPI_WAITFOREOTx() while ((UCB0STAT & UCBUSY) != 0) - /* USART0 Rx ready? */ -#define SPI_WAITFOREORx() while ((IFG2 & UCB0RXIFG) == 0) - /* USART0 Tx buffer ready? */ -#define SPI_WAITFORTxREADY() while ((IFG2 & UCB0TXIFG) == 0) - -#define MOSI 1 /* P3.1 - Output: SPI Master out - slave in (MOSI) */ -#define MISO 2 /* P3.2 - Input: SPI Master in - slave out (MISO) */ -#define SCK 3 /* P3.3 - Output: SPI Serial Clock (SCLK) */ - -/* - * SPI bus - M25P80 external flash configuration. - */ -//#define FLASH_PWR 3 /* P4.3 Output */ ALWAYS POWERED ON Z1 -#define FLASH_CS 4 /* P4.4 Output */ -#define FLASH_HOLD 7 /* P5.7 Output */ - -/* Enable/disable flash access to the SPI bus (active low). */ - -#define SPI_FLASH_ENABLE() ( P4OUT &= ~BV(FLASH_CS) ) -#define SPI_FLASH_DISABLE() ( P4OUT |= BV(FLASH_CS) ) - -#define SPI_FLASH_HOLD() ( P5OUT &= ~BV(FLASH_HOLD) ) -#define SPI_FLASH_UNHOLD() ( P5OUT |= BV(FLASH_HOLD) ) - - -/* - * SPI bus - CC2420 pin configuration. - */ - -#define CC2420_CONF_SYMBOL_LOOP_COUNT 1302 /* 326us msp430X @ 8MHz */ - -/* P1.2 - Input: FIFOP from CC2420 */ -#define CC2420_FIFOP_PORT(type) P1##type -#define CC2420_FIFOP_PIN 2 -/* P1.3 - Input: FIFO from CC2420 */ -#define CC2420_FIFO_PORT(type) P1##type -#define CC2420_FIFO_PIN 3 -/* P1.4 - Input: CCA from CC2420 */ -#define CC2420_CCA_PORT(type) P1##type -#define CC2420_CCA_PIN 4 -/* P4.1 - Input: SFD from CC2420 */ -#define CC2420_SFD_PORT(type) P4##type -#define CC2420_SFD_PIN 1 - /* P3.0 - Output: SPI Chip Select (CS_N) */ -#define CC2420_CSN_PORT(type) P3##type -#define CC2420_CSN_PIN 0 -/* P4.5 - Output: VREG_EN to CC2420 */ -#define CC2420_VREG_PORT(type) P4##type -#define CC2420_VREG_PIN 5 -/* P4.6 - Output: RESET_N to CC2420 */ -#define CC2420_RESET_PORT(type) P4##type -#define CC2420_RESET_PIN 6 - - -#define CC2420_IRQ_VECTOR PORT1_VECTOR - -/* Pin status. */ -#define CC2420_FIFOP_IS_1 (!!(CC2420_FIFOP_PORT(IN) & BV(CC2420_FIFOP_PIN))) -#define CC2420_FIFO_IS_1 (!!(CC2420_FIFO_PORT(IN) & BV(CC2420_FIFO_PIN))) -#define CC2420_CCA_IS_1 (!!(CC2420_CCA_PORT(IN) & BV(CC2420_CCA_PIN))) -#define CC2420_SFD_IS_1 (!!(CC2420_SFD_PORT(IN) & BV(CC2420_SFD_PIN))) - -/* The CC2420 reset pin. */ -#define SET_RESET_INACTIVE() (CC2420_RESET_PORT(OUT) |= BV(CC2420_RESET_PIN)) -#define SET_RESET_ACTIVE() (CC2420_RESET_PORT(OUT) &= ~BV(CC2420_RESET_PIN)) - -/* CC2420 voltage regulator enable pin. */ -#define SET_VREG_ACTIVE() (CC2420_VREG_PORT(OUT) |= BV(CC2420_VREG_PIN)) -#define SET_VREG_INACTIVE() (CC2420_VREG_PORT(OUT) &= ~BV(CC2420_VREG_PIN)) - -/* CC2420 rising edge trigger for external interrupt 0 (FIFOP). */ -#define CC2420_FIFOP_INT_INIT() do { \ - CC2420_FIFOP_PORT(IES) &= ~BV(CC2420_FIFOP_PIN); \ - CC2420_CLEAR_FIFOP_INT(); \ - } while(0) - -/* FIFOP on external interrupt 0. */ -#define CC2420_ENABLE_FIFOP_INT() do {CC2420_FIFOP_PORT(IE) |= BV(CC2420_FIFOP_PIN);} while(0) -#define CC2420_DISABLE_FIFOP_INT() do {CC2420_FIFOP_PORT(IE) &= ~BV(CC2420_FIFOP_PIN);} while(0) -#define CC2420_CLEAR_FIFOP_INT() do {CC2420_FIFOP_PORT(IFG) &= ~BV(CC2420_FIFOP_PIN);} while(0) - -/* - * Enables/disables CC2420 access to the SPI bus (not the bus). - * (Chip Select) - */ - - /* ENABLE CSn (active low) */ -#define CC2420_SPI_ENABLE() (CC2420_CSN_PORT(OUT) &= ~BV(CC2420_CSN_PIN)) - /* DISABLE CSn (active low) */ -#define CC2420_SPI_DISABLE() (CC2420_CSN_PORT(OUT) |= BV(CC2420_CSN_PIN)) -#define CC2420_SPI_IS_ENABLED() ((CC2420_CSN_PORT(OUT) & BV(CC2420_CSN_PIN)) != BV(CC2420_CSN_PIN)) - -#endif /* PLATFORM_CONF_H_ */ diff --git a/platform/zoul/Makefile.zoul b/platform/zoul/Makefile.zoul new file mode 100644 index 000000000..49e6ed13b --- /dev/null +++ b/platform/zoul/Makefile.zoul @@ -0,0 +1,101 @@ +### Zoul Makefile + +ifndef CONTIKI + $(error CONTIKI not defined! You must specify where CONTIKI resides!) +endif + +### If no board is specified the default option is the RE-Mote +ifeq ($(BOARD),) + BOARD=remote +endif + +PYTHON = python +BSL_FLAGS += -e -w -v + +ifdef PORT + BSL_FLAGS += -p $(PORT) +endif + +### Configure the build for the board and pull in board-specific sources +CONTIKI_TARGET_DIRS += . dev +CONTIKI_TARGET_DIRS += . $(BOARD) +PLATFORM_ROOT_DIR = $(CONTIKI)/platform/$(TARGET) + +### Include the board dir if one exists +-include $(PLATFORM_ROOT_DIR)/$(BOARD)/Makefile.$(BOARD) + +### Include +CONTIKI_TARGET_SOURCEFILES += contiki-main.c +CONTIKI_TARGET_SOURCEFILES += leds.c leds-arch.c cc1200-zoul-arch.c +CONTIKI_TARGET_SOURCEFILES += adc-zoul.c button-sensor.c zoul-sensors.c +CONTIKI_TARGET_SOURCEFILES += $(BOARD_SOURCEFILES) + +CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) + +CLEAN += *.zoul + +### Unless the example dictates otherwise, build with code size optimisations +ifndef SMALL + SMALL = 1 +endif + +### Define the CPU directory +CONTIKI_CPU=$(CONTIKI)/cpu/cc2538 +include $(CONTIKI_CPU)/Makefile.cc2538 + +MODULES += core/net core/net/mac \ + core/net/mac/contikimac \ + core/net/llsec core/net/llsec/noncoresec dev/cc1200 + +BSL = $(CONTIKI)/tools/cc2538-bsl/cc2538-bsl.py + +### USe the specific Zoul subplatform to query for connected devices +ifdef MOTELIST_ZOLERTIA + MOTELIST_FLAGS += -b $(MOTELIST_ZOLERTIA) +endif + +### Detect if a mote is connected over serial port +ifeq ($(HOST_OS),Darwin) + USBDEVPREFIX= + MOTELIST = $(CONTIKI)/tools/zolertia/motelist-zolertia-macos + MOTES = $(shell $(MOTELIST) -c 2>&- | cut -f 2 -d ,) + SERIALDUMP = $(CONTIKI)/tools/sky/serialdump-macos +else +### If we are not running under Mac, we assume Linux + USBDEVPREFIX= + SERIALDUMP = $(CONTIKI)/tools/sky/serialdump-linux + MOTELIST = $(CONTIKI)/tools/zolertia/motelist-zolertia + MOTES = $(shell $(MOTELIST) -b $(MOTELIST_ZOLERTIA) -c 2>&- | cut -f 2 -d , | \ + perl -ne 'print $$1 . " " if(m-(/dev/\w+)-);') +endif + +%.upload: %.bin %.elf +ifeq ($(wildcard $(BSL)), ) + @echo "ERROR: Could not find the cc2538-bsl script. Did you run 'git submodule update --init' ?" +else + $(eval BSL_ADDRESS_ARG := -a $(shell $(OBJDUMP) -h $*.elf | grep -B1 LOAD | \ + grep -Ev 'LOAD|\-\-' | awk '{print "0x" $$5}' | \ + sort -g | head -1)) + $(PYTHON) $(BSL) $(BSL_FLAGS) $(BSL_ADDRESS_ARG) $< +endif + +motelist: + $(MOTELIST) +zoul-motelist: + $(MOTELIST) $(MOTELIST_FLAGS) +zoul-motes: + @echo $(MOTES) + +ifdef PORT +serialview: + $(SERIALDUMP) -b115200 $(USBDEVPREFIX) $(PORT) | $(CONTIKI)/tools/timestamp + +login: + $(SERIALDUMP) -b115200 $(USBDEVPREFIX) $(PORT) +else +serialview: + $(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(MOTES)) | $(CONTIKI)/tools/timestamp + +login: + $(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(MOTES)) +endif diff --git a/platform/zoul/README.md b/platform/zoul/README.md new file mode 100644 index 000000000..dc2960909 --- /dev/null +++ b/platform/zoul/README.md @@ -0,0 +1,276 @@ +Zolertia Zoul core module +============================================ + +![Zolertia Zoul Module][zoul] + +The Zoul is a core module developed by Zolertia to target most IoT applications, +providing a flexible and affordable module solution to integrate to most +existing products and solutions, or ease the prototyping and production of new +products in a short time. + +The Zoul is based on TI's CC2538 system on chip (SoC), featuring an ARM +Cortex-M3 with 512KB flash, 32Kb RAM, double RF interface, and the following +goodies: + +* ISM 2.4-GHz IEEE 802.15.4 & Zigbee compliant. +* ISM 868-, 915-, 920-, 950-MHz ISM/SRD Band. +* AES-128/256, SHA2 Hardware Encryption Engine. +* ECC-128/256, RSA Hardware Acceleration Engine for Secure Key Exchange. +* Small form-factor of 16.78 x 30.89 mm. +* Prototype friendly, to fit on most prototyping boards (breadboard, etc.). +* Self-contained and EMI-protected module under a shield. + +The Zoul will be CE/FCC certified (2016) to allow a fast integration and short time to market for new products and solutions. + +Zoul pin-out +============= + +![Zoul pin-out (front)][zoul-pinout-front] +![Zoul pin-out (back)][zoul-pinout-back] + +Port Features +============= +The Zoul has the following key features: + + * Deep Sleep support with RAM retention for ultra-low energy consumption. + * Native USB support (CDC-ACM). SLIP over UART for border routers is no longer a bottleneck. + * DMA transfers for increased performance (RAM to/from RF, RAM to/from USB). + +In terms of hardware support, the following drivers have been implemented for the Zoul-based platforms: + + * CC2538 System-on-Chip: + * Standard Cortex M3 peripherals (NVIC, SCB, SysTick) + * Sleep Timer (underpins rtimers) + * SysTick (underpins the platform clock and Contiki's timers infrastructure) + * RF (2.4GHz) + * UART + * Watchdog (in watchdog mode) + * USB (in CDC-ACM) + * uDMA Controller (RAM to/from USB and RAM to/from RF) + * Random number generator + * Low Power Modes + * General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development. + * ADC + * Cryptoprocessor (AES-ECB/CBC/CTR/CBC-MAC/GCM/CCM-128/192/256, SHA-256) + * Public Key Accelerator (ECDH, ECDSA) + * Flash-based port of Coffee + * PWM + * LEDs + * Buttons + * Built-in core temperature and battery sensor. + * CC1200 sub-1GHz radio interface. + * Real Time Clock Calendar (on the RE-Mote platform). + +There is a Zoul powering the RE-Mote and Firefly platforms, check out its specific README files for more information about on-board features. + +Requirements +============ +To start using Contiki, the following is required: + + * A zoul-based board (RE-Mote, firefly) + * A toolchain to compile Contiki for the CC2538. + * Drivers so that your OS can communicate with your hardware. + * Software to upload images to the CC2538. + +Install a Toolchain +------------------- +The toolchain used to build contiki is arm-gcc, also used by other arm-based Contiki ports. If you are using Instant Contiki, you may have a version pre-installed in your system. + +The platform is currently being used/tested with "GNU Tools for ARM Embedded Processors" (). The current recommended version and the one being used by Contiki's regression tests on Travis is shown below. + + $ arm-none-eabi-gcc --version + arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 5.2.1 20151202 (release) [ARM/embedded-5-branch revision 231848] + Copyright (C) 2015 Free Software Foundation, Inc. + This is free software; see the source for copying conditions. There is NO + warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Drivers +------- +Depending on your Zoul flavour, there are different options. As today the RE-Mote and Firefly platforms host a Zoul with a CP2104 USB-to-serial converter, governed by a low-power PIC to handle resetting and flashing the Zoul over USB, without having to press any button or use external tools. + +The driver is available at + +Check the board's specific README files for more information. + +For windows users, if using the USB 2.0 interface (via CDC-ACM driver), there is an available driver in this folder: + +`zolertia-zoul-cdc-acm` + +Software to Program the Nodes +----------------------------- +The Zoul can be programmed via the jtag interface or via the serial boot loader on the chip. + +Both the RE-Mote and Firefly has a mini JTAG 10-pin male header, compatible with the `SmartRF06` development board, which can be used to flash and debug the platforms. Alternatively one could use the `JLink` programmer with a 20-to-10 pin converter like the following: . + +The serial boot loader on the chip is exposed to the user via an USB interface. In the not so distant past we used to press a button sequence to unlock the boot loader, but now an on-board PIC in both RE-Motes and Fireflies handles this on its own, so it will detect the BSL sequence and flash the CC2538 without user intervention. + +Instructions to flash for different OS are given below. + +* On Windows: + * Nodes can be programmed with TI's ArmProgConsole or the [SmartRF Flash Programmer 2][smart-rf-flashprog]. The README should be self-explanatory. With ArmProgConsole, upload the file with a `.bin` extension. (jtag + serial) + * Nodes can also be programmed via the serial boot loader in the cc2538. In `tools/cc2538-bsl/` you can find `cc2538-bsl.py` this is a python script that can download firmware to your node via a serial connection. If you use this option you just need to make sure you have a working version of python installed. You can read the README in the same directory for more info. (serial) + +* On Linux: + * Nodes can be programmed with TI's [UniFlash] tool. With UniFlash, use the file with `.elf` extension. (jtag + serial) + * Nodes can also be programmed via the serial boot loader in the cc2538. No extra software needs to be installed. (serial) + +* On OSX: + * The `cc2538-bsl.py` script in `tools/cc2538-bsl/` is the only option. No extra software needs to be installed. (serial) + +The file with a `.zoul` extension is a copy of the `.elf` file. + +Use the Port +============ +The following examples are intended to work off-the-shelf: + +* Examples under `examples/zolertia/zoul` +* MQTT example `examples/cc2538dk/mqtt-demo` +* Border router: `examples/ipv6/rpl-border-router` +* Webserver: `examples/webserver-ipv6` +* CoAP example: `examples/er-rest-example/` + +Build your First Examples +------------------------- +It is recommended to start with the `zoul-demo`, it is a simple example that walkthroughs the zoul features (can be compiled for both the RE-Mote and the Firefly), such as the built-in sensors, LEDs, user button operation modes (press, release, hold-press), radio (Rime broadcast). + +The `Makefile.target` includes the `TARGET=` argument, predefining which is the target platform to compile for, it is automatically included at compilation. The `BOARD=` argument is using as a glue switch to pull in specific platform files, for example the specific RE-Mote core drivers. If no `BOARD` argument is given, it will default to `remote` and compile for the RE-Mote platform. + +To generate or override an existing one, you can run: + +`make TARGET=zoul savetarget` + +Then you can just run `make` to compile an application, otherwise you will need to do `make TARGET=zoul`. + +Alternatively you can export the following to your work environment: + +`export BOARD=remote` or `export BOARD=firefly` + +This will avoid having to type this argument at each compilation. + +If you want to upload the compiled firmware to a node via the serial boot loader you need first to either manually enable the boot loader, or just let the Co-Processor detect the flash sequence and do it on your behalf, as simple as not pressing anything at all! + +Then use `make zoul-demo.upload`. + +The `PORT` argument could be used to specify in which port the device is connected, in case we have multiple devices connected at the same time. + +To generate an assembly listing of the compiled firmware, run `make zoul-demo.lst`. This may be useful for debugging or optimizing your application code. To intersperse the C source code within the assembly listing, you must instruct the compiler to include debugging information by adding `CFLAGS += -g` to the project Makefile and rebuild by running `make clean zoul-demo.lst`. + +To enable printing debug output to your console, use the `make login` to get the information over the USB programming/debugging port, or alternatively use `make serialview` to also add a timestamp in each print. + +Node IEEE/RIME/IPv6 Addresses +----------------------------- + +Nodes will generally autoconfigure their IPv6 address based on their IEEE address. The IEEE address can be read directly from the CC2538 Info Page, or it can be hard-coded. Additionally, the user may specify a 2-byte value at build time, which will be used as the IEEE address' 2 LSBs. + +To configure the IEEE address source location (Info Page or hard-coded), use the `IEEE_ADDR_CONF_HARDCODED` define in contiki-conf.h: + +* 0: Info Page +* 1: Hard-coded + +If `IEEE_ADDR_CONF_HARDCODED` is defined as 1, the IEEE address will take its value from the `IEEE_ADDR_CONF_ADDRESS` define. If `IEEE_ADDR_CONF_HARDCODED` is defined as 0, the IEEE address can come from either the primary or secondary location in the Info Page. To use the secondary address, define `IEEE_ADDR_CONF_USE_SECONDARY_LOCATION` as 1. + +Additionally, you can override the IEEE's 2 LSBs, by using the `NODEID` make variable. The value of `NODEID` will become the value of the `IEEE_ADDR_NODE_ID` pre-processor define. If `NODEID` is not defined, `IEEE_ADDR_NODE_ID` will not get defined either. For example: + + make NODEID=0x79ab + +This will result in the 2 last bytes of the IEEE address getting set to 0x79 0xAB + +Note: Some early production devices do not have am IEEE address written on the Info Page. For those devices, using value 0 above will result in a Rime address of all 0xFFs. If your device is in this category, define `IEEE_ADDR_CONF_HARDCODED` to 1 and specify `NODEID` to differentiate between devices. + +Low-Power Modes +--------------- +The CC2538 port supports power modes for low energy consumption. The SoC will enter a low power mode as part of the main loop when there are no more events to service. + +LPM support can be disabled in its entirety by setting `LPM_CONF_ENABLE` to 0 in `contiki-conf.h` or `project-conf.h`. + +The Low-Power module uses a simple heuristic to determine the best power mode, depending on anticipated Deep Sleep duration and the state of various peripherals. + +In a nutshell, the algorithm first answers the following questions: + +* Is the RF off? +* Are all registered peripherals permitting PM1+? +* Is the Sleep Timer scheduled to fire an interrupt? + +If the answer to any of the above question is "No", the SoC will enter PM0. If the answer to all questions is "Yes", the SoC will enter one of PMs 0/1/2 depending on the expected Deep Sleep duration and subject to user configuration and application requirements. + +At runtime, the application may enable/disable some Power Modes by making calls to `lpm_set_max_pm()`. For example, to avoid PM2 an application could call `lpm_set_max_pm(1)`. Subsequently, to re-enable PM2 the application would call `lpm_set_max_pm(2)`. + +The LPM module can be configured with a hard maximum permitted power mode. + + #define LPM_CONF_MAX_PM N + +Where N corresponds to the PM number. Supported values are 0, 1, 2. PM3 is not supported. Thus, if the value of the define is 1, the SoC will only ever enter PMs 0 or 1 but never 2 and so on. + +The configuration directive `LPM_CONF_MAX_PM` sets a hard upper boundary. For instance, if `LPM_CONF_MAX_PM` is defined as 1, calls to `lpm_set_max_pm()` can only enable/disable PM1. In this scenario, PM2 can not be enabled at runtime. + +When setting `LPM_CONF_MAX_PM` to 0 or 1, the entire SRAM will be available. Crucially, when value 2 is used the linker will automatically stop using the SoC's SRAM non-retention area, resulting in a total available RAM of 16MB instead of 32MB. + +### LPM and Duty Cycling Driver +LPM is highly related to the operations of the Radio Duty Cycling (RDC) driver of the Contiki network stack and will work correctly with ContikiMAC and NullRDC. + +* With ContikiMAC, PMs 0/1/2 are supported subject to user configuration. +* When NullRDC is in use, the radio will be always on. As a result, the algorithm discussed above will always choose PM0 and will never attempt to drop to PM1/2. + +### Shutdown Mode +The RE-Mote has a built-in shutdown mode which effectively reduces the power consumption down to 150nA. Check its specific README file for more information. + +Build headless nodes +-------------------- +It is possible to turn off all character I/O for nodes not connected to a PC. Doing this will entirely disable the UART as well as the USB controller, preserving energy in the long term. The define used to achieve this is (1: Quiet, 0: Normal output): + + #define CC2538_CONF_QUIET 0 + +Setting this define to 1 will automatically set the following to 0: + +* `USB_SERIAL_CONF_ENABLE` +* `UART_CONF_ENABLE` +* `STARTUP_CONF_VERBOSE` + +Code Size Optimisations +----------------------- +The build system currently uses optimization level `-Os`, which is controlled indirectly through the value of the `SMALL` make variable. This value can be overridden by example makefiles, or it can be changed directly in `platform/zoul/Makefile.zoul`. + +Historically, the `-Os` flag has caused problems with some toolchains. If you are using one of the toolchains documented in this README, you should be able to use it without issues. If for whatever reason you do come across problems, try setting `SMALL=0` or replacing `-Os` with `-O2` in `cpu/cc2538/Makefile.cc2538`. + +Doxygen Documentation +===================== +This port's code has been documented with doxygen. To build the documentation, navigate to `$(CONTIKI)/doc` and run `make`. This will build the entire contiki documentation and may take a while. + +If you want to build this platform's documentation only and skip the remaining platforms, run this: + + make basedirs="platform/zoul core cpu/cc2538 examples/zolertia/zoul examples/cc2538dk" + +Once you've built the docs, open `$(CONTIKI)/doc/html/index.html` and enjoy. + +Other Versions of this Guide +============================ +If you prefer this guide in other formats, use the excellent [pandoc] to convert it. + +* **pdf**: `pandoc -s --toc README.md -o README.pdf` +* **html**: `pandoc -s --toc README.md -o README.html` + +More Reading +============ +1. [Zolertia website][zolertia-site] +2. [CC2538 System-on-Chip Solution][cc2538] +3. [CC1200 sub-1GHz RF transceiver][cc1200] +4. [Zolertia Hackster channel][hackster] +5. [IoT in five days open source and online book][IoT5days] + +Maintainers +=========== +The Zoul and derived platforms (as well as the Z1 mote) are maintained by Zolertia. +Main contributor: Antonio Lignan + +[zolertia-site]: http://www.zolertia.io/products "Zolertia" +[cc1200]: http://www.ti.com/product/cc1200 "CC1200" +[smart-rf-studio]: http://www.ti.com/tool/smartrftm-studio "SmartRF Studio" +[smart-rf-flashprog]: http://www.ti.com/tool/flash-programmer "SmartRF Flash Programmer" +[cc2538]: http://www.ti.com/product/cc2538 "CC2538" +[uniflash]: http://processors.wiki.ti.com/index.php/Category:CCS_UniFlash "UniFlash" +[pandoc]: http://johnmacfarlane.net/pandoc/ "Pandoc - a universal document converter" +[hackster]: https://www.hackster.io/zolertia "Zolertia Hackster Channel" +[zoul]: images/zoul-front.png "Zolertia Zoul Module" +[zoul-pinout-front]: images/zoul-pinout-front.png "Zoul pin-out (front)" +[zoul-pinout-back]: images/zoul-pinout-back.png "Zoul pin-out (back)" +[IoT5days]: https://github.com/alignan/IPv6-WSN-book "IoT in Five days online book" diff --git a/platform/zoul/contiki-conf.h b/platform/zoul/contiki-conf.h new file mode 100644 index 000000000..59463f691 --- /dev/null +++ b/platform/zoul/contiki-conf.h @@ -0,0 +1,602 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup zoul + * @{ + * + * \defgroup zoul-platforms Zolertia platforms based on the Zoul core module + * + * The Zoul allows a fast reuse and easy integration to most applications and + * products. Its small size and module format eases to place in different PCB + * designs and to integrate in existing products. The Zoul-based platforms + * share most of the Zoul core implementation. + * + * \file + * Configuration for the Zoul-based platforms + */ +#ifndef CONTIKI_CONF_H_ +#define CONTIKI_CONF_H_ + +#include +#include +/*---------------------------------------------------------------------------*/ +/* Include Project Specific conf */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif /* PROJECT_CONF_H */ +/*---------------------------------------------------------------------------*/ +/** + * \name Compiler configuration and platform-specific type definitions + * + * Those values are not meant to be modified by the user + * @{ + */ +#define CLOCK_CONF_SECOND 128 + +/* Compiler configurations */ +#define CCIF +#define CLIF + +/* Platform typedefs */ +typedef uint32_t clock_time_t; +typedef uint32_t uip_stats_t; + +/* + * rtimer.h typedefs rtimer_clock_t as unsigned short. We need to define + * RTIMER_CLOCK_DIFF to override this + */ +typedef uint32_t rtimer_clock_t; +#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b))) +/** @} */ +/*---------------------------------------------------------------------------*/ +#define TSCH_CONF_HW_FRAME_FILTERING 0 + +/* 352us from calling transmit() until the SFD byte has been sent */ +#define RADIO_DELAY_BEFORE_TX ((unsigned)US_TO_RTIMERTICKS(352)) +/* 192us as in datasheet but ACKs are not always received, so adjusted to 250us */ +#define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(250)) +#define RADIO_DELAY_BEFORE_DETECT 0 +/*---------------------------------------------------------------------------*/ +/** + * \name Serial Boot Loader Backdoor configuration + * + * @{ + */ +#ifndef FLASH_CCA_CONF_BOOTLDR_BACKDOOR +#define FLASH_CCA_CONF_BOOTLDR_BACKDOOR 1 /** RAM DMA channel */ +#define USB_ARCH_CONF_TX_DMA_CHAN 1 /**< RAM -> USB DMA channel */ +#define CC2538_RF_CONF_TX_DMA_CHAN 2 /**< RF -> RAM DMA channel */ +#define CC2538_RF_CONF_RX_DMA_CHAN 3 /**< RAM -> RF DMA channel */ +#define UDMA_CONF_MAX_CHANNEL CC2538_RF_CONF_RX_DMA_CHAN +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Character I/O Configuration + * + * @{ + */ +#ifndef UART_CONF_ENABLE +#define UART_CONF_ENABLE 1 /**< Enable/Disable UART I/O */ +#endif + +#ifndef UART0_CONF_BAUD_RATE +#define UART0_CONF_BAUD_RATE 115200 /**< Default UART0 baud rate */ +#endif + +#ifndef UART1_CONF_BAUD_RATE +#define UART1_CONF_BAUD_RATE 115200 /**< Default UART1 baud rate */ +#endif + +#ifndef SLIP_ARCH_CONF_USB +#define SLIP_ARCH_CONF_USB 0 /**< SLIP over UART by default */ +#endif + +#ifndef CC2538_RF_CONF_SNIFFER_USB +#define CC2538_RF_CONF_SNIFFER_USB 0 /**< Sniffer out over UART by default */ +#endif + +#ifndef DBG_CONF_USB +#define DBG_CONF_USB 0 /**< All debugging over UART by default */ +#endif + +#ifndef SERIAL_LINE_CONF_UART +#define SERIAL_LINE_CONF_UART 0 /**< UART to use with serial line */ +#endif + +#if !SLIP_ARCH_CONF_USB +#ifndef SLIP_ARCH_CONF_UART +#define SLIP_ARCH_CONF_UART 0 /**< UART to use with SLIP */ +#endif +#endif + +#if !CC2538_RF_CONF_SNIFFER_USB +#ifndef CC2538_RF_CONF_SNIFFER_UART +#define CC2538_RF_CONF_SNIFFER_UART 0 /**< UART to use with sniffer */ +#endif +#endif + +#if !DBG_CONF_USB +#ifndef DBG_CONF_UART +#define DBG_CONF_UART 0 /**< UART to use for debugging */ +#endif +#endif + +#ifndef UART1_CONF_UART +#define UART1_CONF_UART 0 /**< UART to use for examples relying on + the uart1_* API */ +#endif + +/* Turn off example-provided putchars */ +#define SLIP_BRIDGE_CONF_NO_PUTCHAR 1 +#define SLIP_RADIO_CONF_NO_PUTCHAR 1 + +#ifndef SLIP_ARCH_CONF_ENABLED +/* + * Determine whether we need SLIP + * This will keep working while UIP_FALLBACK_INTERFACE and CMD_CONF_OUTPUT + * keep using SLIP + */ +#if defined(UIP_FALLBACK_INTERFACE) || defined(CMD_CONF_OUTPUT) +#define SLIP_ARCH_CONF_ENABLED 1 +#endif +#endif + +/* + * When set, the radio turns off address filtering and sends all captured + * frames down a peripheral (UART or USB, depending on the value of + * CC2538_RF_CONF_SNIFFER_USB) + */ +#ifndef CC2538_RF_CONF_SNIFFER +#define CC2538_RF_CONF_SNIFFER 0 +#endif + +/** + * \brief Define this as 1 to build a headless node. + * + * The UART will not be initialised its clock will be gated, offering some + * energy savings. The USB will not be initialised either + */ +#ifndef CC2538_CONF_QUIET +#define CC2538_CONF_QUIET 0 +#endif + +/* CC2538_CONF_QUIET is hard and overrides all other related defines */ +#if CC2538_CONF_QUIET +#undef USB_SERIAL_CONF_ENABLE +#define USB_SERIAL_CONF_ENABLE 0 + +#undef UART_CONF_ENABLE +#define UART_CONF_ENABLE 0 + +#undef STARTUP_CONF_VERBOSE +#define STARTUP_CONF_VERBOSE 0 + +/* Little sanity check: We can't have quiet sniffers */ +#if CC2538_RF_CONF_SNIFFER +#error "CC2538_RF_CONF_SNIFFER == 1 and CC2538_CONF_QUIET == 1" +#error "These values are conflicting. Please set either to 0" +#endif +#endif /* CC2538_CONF_QUIET */ + +/** + * \brief Enable the USB core only if we need it + */ +#ifndef USB_SERIAL_CONF_ENABLE +#define USB_SERIAL_CONF_ENABLE \ + ((SLIP_ARCH_CONF_USB & SLIP_ARCH_CONF_ENABLED) | \ + DBG_CONF_USB | \ + (CC2538_RF_CONF_SNIFFER & CC2538_RF_CONF_SNIFFER_USB)) +#endif + +/* + * If debugging and SLIP use the same peripheral, this will be 1. Don't modify + * this + */ +#if SLIP_ARCH_CONF_ENABLED +#define DBG_CONF_SLIP_MUX (SLIP_ARCH_CONF_USB == DBG_CONF_USB && \ + (SLIP_ARCH_CONF_USB || \ + SLIP_ARCH_CONF_UART == DBG_CONF_UART)) +#endif + +/* + * Automatic detection of whether a specific UART is in use + */ +#define UART_IN_USE_BY_SERIAL_LINE(u) (SERIAL_LINE_CONF_UART == (u)) +#define UART_IN_USE_BY_SLIP(u) (SLIP_ARCH_CONF_ENABLED && \ + !SLIP_ARCH_CONF_USB && \ + SLIP_ARCH_CONF_UART == (u)) +#define UART_IN_USE_BY_RF_SNIFFER(u) (CC2538_RF_CONF_SNIFFER && \ + !CC2538_RF_CONF_SNIFFER_USB && \ + CC2538_RF_CONF_SNIFFER_UART == (u)) +#define UART_IN_USE_BY_DBG(u) (!DBG_CONF_USB && DBG_CONF_UART == (u)) +#define UART_IN_USE_BY_UART1(u) (UART1_CONF_UART == (u)) + +#define UART_IN_USE(u) ( \ + UART_CONF_ENABLE && \ + (UART_IN_USE_BY_SERIAL_LINE(u) || \ + UART_IN_USE_BY_SLIP(u) || \ + UART_IN_USE_BY_RF_SNIFFER(u) || \ + UART_IN_USE_BY_DBG(u) || \ + UART_IN_USE_BY_UART1(u)) \ +) +/** @} */ +/*---------------------------------------------------------------------------*/ +/* board.h assumes that basic configuration is done */ +#include "board.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Network Stack Configuration + * + * @{ + */ +#ifndef NETSTACK_CONF_NETWORK +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#else +#define NETSTACK_CONF_NETWORK rime_driver +#endif /* NETSTACK_CONF_WITH_IPV6 */ +#endif /* NETSTACK_CONF_NETWORK */ + +#ifndef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC csma_driver +#endif + +#ifndef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC contikimac_driver +#endif + +/* Configure NullRDC for when it's selected */ +#define NULLRDC_802154_AUTOACK 1 +#define NULLRDC_802154_AUTOACK_HW 1 + +/* Configure ContikiMAC for when it's selected */ +#define CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION 0 +#define WITH_FAST_SLEEP 1 + +#ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 +#endif + +#ifndef NETSTACK_CONF_FRAMER +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_FRAMER framer_802154 +#else /* NETSTACK_CONF_WITH_IPV6 */ +#define NETSTACK_CONF_FRAMER contikimac_framer +#endif /* NETSTACK_CONF_WITH_IPV6 */ +#endif /* NETSTACK_CONF_FRAMER */ + +/* This can be overriden to use the cc1200_driver instead */ +#ifndef NETSTACK_CONF_RADIO +#define NETSTACK_CONF_RADIO cc2538_rf_driver +#endif + +/* + * RE-Mote specific: + * If dual RF enabled, we set the RF switch to enable the CC1200 and use 2.4GHz + * on the available uFl/chip antenna (not mounted as default). In contiki main + * platform routine we set the right antenna depending on NETSTACK_CONF_RADIO, + * but as changing the RF antenna also implies enabling/disabling the CC1200, + * is better to start off with the right configuration + */ +#if REMOTE_DUAL_RF_ENABLED +#define ANTENNA_SW_SELECT_DEFAULT ANTENNA_SW_SELECT_SUBGHZ +#else /* REMOTE_DUAL_RF_ENABLED */ +#ifndef ANTENNA_SW_SELECT_DEF_CONF +#define ANTENNA_SW_SELECT_DEFAULT ANTENNA_SW_SELECT_2_4GHZ +#else /* ANTENNA_SW_SELECT_DEF_CONF */ +#define ANTENNA_SW_SELECT_DEFAULT ANTENNA_SW_SELECT_DEF_CONF +#endif /* ANTENNA_SW_SELECT_DEF_CONF */ +#endif /* REMOTE_DUAL_RF_ENABLED */ + +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name LPM configuration + * @{ + */ +#ifndef LPM_CONF_ENABLE +#define LPM_CONF_ENABLE 1 /**< Set to 0 to disable LPM entirely */ +#endif + +/** + * \brief Maximum PM + * + * The SoC will never drop to a Power Mode deeper than the one specified here. + * 0 for PM0, 1 for PM1 and 2 for PM2 + */ +#ifndef LPM_CONF_MAX_PM +#define LPM_CONF_MAX_PM 2 +#endif + +#ifndef LPM_CONF_STATS +#define LPM_CONF_STATS 0 /**< Set to 1 to enable LPM-related stats */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name IEEE address configuration + * + * Used to generate our RIME & IPv6 address + * @{ + */ +/** + * \brief Location of the IEEE address + * 0 => Read from InfoPage, + * 1 => Use a hardcoded address, configured by IEEE_ADDR_CONF_ADDRESS + */ +#ifndef IEEE_ADDR_CONF_HARDCODED +#define IEEE_ADDR_CONF_HARDCODED 0 +#endif + +/** + * \brief The hardcoded IEEE address to be used when IEEE_ADDR_CONF_HARDCODED + * is defined as 1 + */ +#ifndef IEEE_ADDR_CONF_ADDRESS +#define IEEE_ADDR_CONF_ADDRESS { 0x00, 0x12, 0x4B, 0x00, 0x89, 0xAB, 0xCD, 0xEF } +#endif + +/** + * \brief Location of the IEEE address in the InfoPage when + * IEEE_ADDR_CONF_HARDCODED is defined as 0 + * 0 => Use the primary address location + * 1 => Use the secondary address location + */ +#ifndef IEEE_ADDR_CONF_USE_SECONDARY_LOCATION +#define IEEE_ADDR_CONF_USE_SECONDARY_LOCATION 0 +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name RF configuration + * + * @{ + */ +/* RF Config */ +#ifndef IEEE802154_CONF_PANID +#define IEEE802154_CONF_PANID 0xABCD +#endif + +#ifndef CC2538_RF_CONF_CHANNEL +#define CC2538_RF_CONF_CHANNEL 26 +#endif /* CC2538_RF_CONF_CHANNEL */ + +#ifndef CC2538_RF_CONF_AUTOACK +#define CC2538_RF_CONF_AUTOACK 1 /**< RF H/W generates ACKs */ +#endif /* CC2538_CONF_AUTOACK */ + +#ifndef CC2538_RF_CONF_TX_USE_DMA +#define CC2538_RF_CONF_TX_USE_DMA 1 /**< RF TX over DMA */ +#endif + +#ifndef CC2538_RF_CONF_RX_USE_DMA +#define CC2538_RF_CONF_RX_USE_DMA 1 /**< RF RX over DMA */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name IPv6, RIME and network buffer configuration + * + * @{ + */ + +/* Don't let contiki-default-conf.h decide if we are an IPv6 build */ +#ifndef NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_WITH_IPV6 0 +#endif + +#if NETSTACK_CONF_WITH_IPV6 +/* Addresses, Sizes and Interfaces */ +/* 8-byte addresses here, 2 otherwise */ +#define LINKADDR_CONF_SIZE 8 +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 +#define UIP_CONF_NETIF_MAX_ADDRESSES 3 + +/* TCP, UDP, ICMP */ +#ifndef UIP_CONF_TCP +#define UIP_CONF_TCP 1 +#endif +#ifndef UIP_CONF_TCP_MSS +#define UIP_CONF_TCP_MSS 64 +#endif +#define UIP_CONF_UDP 1 +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_ICMP6 1 + +/* ND and Routing */ +#ifndef UIP_CONF_ROUTER +#define UIP_CONF_ROUTER 1 +#endif + +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_IP_FORWARD 0 +#define RPL_CONF_STATS 0 + +#ifndef RPL_CONF_OF +#define RPL_CONF_OF rpl_mrhof +#endif + +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 16 +#endif +#ifndef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 16 +#endif + +/* uIP */ +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 1300 +#endif + +#define UIP_CONF_IPV6_QUEUE_PKT 0 +#define UIP_CONF_IPV6_CHECKS 1 +#define UIP_CONF_IPV6_REASSEMBLY 0 +#define UIP_CONF_MAX_LISTENPORTS 8 + +/* 6lowpan */ +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#ifndef SICSLOWPAN_CONF_COMPRESSION_THRESHOLD +#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63 +#endif +#ifndef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +#endif +#define SICSLOWPAN_CONF_MAXAGE 8 + +/* Define our IPv6 prefixes/contexts here */ +#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 +#ifndef SICSLOWPAN_CONF_ADDR_CONTEXT_0 +#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 { \ + addr_contexts[0].prefix[0] = UIP_DS6_DEFAULT_PREFIX_0; \ + addr_contexts[0].prefix[1] = UIP_DS6_DEFAULT_PREFIX_1; \ +} +#endif + +#define MAC_CONF_CHANNEL_CHECK_RATE 8 + +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 8 +#endif +/*---------------------------------------------------------------------------*/ +#else /* NETSTACK_CONF_WITH_IPV6 */ +/* Network setup for non-IPv6 (rime). */ +#define UIP_CONF_IP_FORWARD 1 + +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 108 +#endif + +#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 + +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 8 +#endif + +#endif /* NETSTACK_CONF_WITH_IPV6 */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Security + * + * @{ + */ +#ifndef CRYPTO_CONF_INIT +#define CRYPTO_CONF_INIT 1 /**< Whether to init cryptoprocessor */ +#endif + +#ifndef AES_128_CONF +#define AES_128_CONF cc2538_aes_128_driver /**< AES-128 driver */ +#endif + +#ifndef CCM_STAR_CONF +#define CCM_STAR_CONF cc2538_ccm_star_driver /**< AES-CCM* driver */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ + +#endif /* CONTIKI_CONF_H_ */ + +/** @} */ diff --git a/platform/zoul/contiki-main.c b/platform/zoul/contiki-main.c new file mode 100644 index 000000000..0779681d0 --- /dev/null +++ b/platform/zoul/contiki-main.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup platform + * @{ + * + * \defgroup zoul Zolertia Zoul core module + * + * The Zoul comprises the CC2538SF53 and CC1200 in a single module + * format, which allows a fast reuse of its core components in different + * formats and form-factors. + * @{ + * + * \file + * Main module for the Zolertia Zoul core and based platforms + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/leds.h" +#include "dev/sys-ctrl.h" +#include "dev/scb.h" +#include "dev/nvic.h" +#include "dev/uart.h" +#include "dev/watchdog.h" +#include "dev/ioc.h" +#include "dev/button-sensor.h" +#include "dev/serial-line.h" +#include "dev/slip.h" +#include "dev/cc2538-rf.h" +#include "dev/udma.h" +#include "dev/crypto.h" +#include "usb/usb-serial.h" +#include "lib/random.h" +#include "net/netstack.h" +#include "net/queuebuf.h" +#include "net/ip/tcpip.h" +#include "net/ip/uip.h" +#include "net/mac/frame802154.h" +#include "soc.h" +#include "cpu.h" +#include "reg.h" +#include "ieee-addr.h" +#include "lpm.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#if STARTUP_CONF_VERBOSE +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#if UART_CONF_ENABLE +#define PUTS(s) puts(s) +#else +#define PUTS(s) +#endif +/*---------------------------------------------------------------------------*/ +/** \brief Board specific iniatialisation */ +void board_init(void); +/*---------------------------------------------------------------------------*/ +static void +fade(unsigned char l) +{ + volatile int i; + int k, j; + for(k = 0; k < 800; ++k) { + j = k > 400 ? 800 - k : k; + + leds_on(l); + for(i = 0; i < j; ++i) { + asm("nop"); + } + leds_off(l); + for(i = 0; i < 400 - j; ++i) { + asm("nop"); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +set_rf_params(void) +{ + uint16_t short_addr; + uint8_t ext_addr[8]; + + ieee_addr_cpy_to(ext_addr, 8); + + short_addr = ext_addr[7]; + short_addr |= ext_addr[6] << 8; + + /* Populate linkaddr_node_addr. Maintain endianness */ + memcpy(&linkaddr_node_addr, &ext_addr[8 - LINKADDR_SIZE], LINKADDR_SIZE); + +#if STARTUP_CONF_VERBOSE + { + int i; + printf("Rime configured with address "); + for(i = 0; i < LINKADDR_SIZE - 1; i++) { + printf("%02x:", linkaddr_node_addr.u8[i]); + } + printf("%02x\n", linkaddr_node_addr.u8[i]); + } +#endif + + NETSTACK_RADIO.set_value(RADIO_PARAM_PAN_ID, IEEE802154_PANID); + NETSTACK_RADIO.set_value(RADIO_PARAM_16BIT_ADDR, short_addr); + NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, CC2538_RF_CHANNEL); + NETSTACK_RADIO.set_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Main routine for the Zoul-based platforms + */ +int +main(void) +{ + nvic_init(); + ioc_init(); + sys_ctrl_init(); + clock_init(); + lpm_init(); + rtimer_init(); + gpio_init(); + leds_init(); + fade(LEDS_RED); + process_init(); + watchdog_init(); + + /* + * Character I/O Initialisation. + * When the UART receives a character it will call serial_line_input_byte to + * notify the core. The same applies for the USB driver. + * + * If slip-arch is also linked in afterwards (e.g. if we are a border router) + * it will overwrite one of the two peripheral input callbacks. Characters + * received over the relevant peripheral will be handled by + * slip_input_byte instead + */ +#if UART_CONF_ENABLE + uart_init(0); + uart_init(1); + uart_set_input(SERIAL_LINE_CONF_UART, serial_line_input_byte); +#endif + +#if USB_SERIAL_CONF_ENABLE + usb_serial_init(); + usb_serial_set_input(serial_line_input_byte); +#endif + + serial_line_init(); + + INTERRUPTS_ENABLE(); + fade(LEDS_BLUE); + + PUTS(CONTIKI_VERSION_STRING); + PUTS(BOARD_STRING); +#if STARTUP_CONF_VERBOSE + soc_print_info(); +#endif + + /* Initialise the H/W RNG engine. */ + random_init(0); + + udma_init(); + + process_start(&etimer_process, NULL); + ctimer_init(); + + board_init(); + +#if CRYPTO_CONF_INIT + crypto_init(); + crypto_disable(); +#endif + + netstack_init(); + set_rf_params(); + + PRINTF(" Net: "); + PRINTF("%s\n", NETSTACK_NETWORK.name); + PRINTF(" MAC: "); + PRINTF("%s\n", NETSTACK_MAC.name); + PRINTF(" RDC: "); + PRINTF("%s\n", NETSTACK_RDC.name); + +#if NETSTACK_CONF_WITH_IPV6 + memcpy(&uip_lladdr.addr, &linkaddr_node_addr, sizeof(uip_lladdr.addr)); + queuebuf_init(); + process_start(&tcpip_process, NULL); +#endif /* NETSTACK_CONF_WITH_IPV6 */ + + process_start(&sensors_process, NULL); +#if PLATFORM_HAS_BUTTON + SENSORS_ACTIVATE(button_sensor); +#endif + energest_init(); + ENERGEST_ON(ENERGEST_TYPE_CPU); + + autostart_start(autostart_processes); + + watchdog_start(); + fade(LEDS_GREEN); + + while(1) { + uint8_t r; + do { + /* Reset watchdog and handle polls and events */ + watchdog_periodic(); + + r = process_run(); + } while(r > 0); + + /* We have serviced all pending events. Enter a Low-Power mode. */ + lpm_enter(); + } +} +/*---------------------------------------------------------------------------*/ + +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/adc-sensors.c b/platform/zoul/dev/adc-sensors.c new file mode 100644 index 000000000..6cc37fb4b --- /dev/null +++ b/platform/zoul/dev/adc-sensors.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-adc-sensors + * @{ + * + * \file + * Generic driver for the Zoul ADC wrapper for analogue sensors + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sys/clock.h" +#include "dev/ioc.h" +#include "dev/gpio.h" +#include "dev/adc.h" +#include "adc-sensors.h" +#include "adc-zoul.h" +#include "zoul-sensors.h" +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +typedef struct { + int type; + uint8_t pin_mask; + uint8_t vdd3; +} adc_info_t; + +typedef struct { + uint8_t sensors_num; + uint8_t sensors_ports; + adc_info_t sensor[ADC_SENSORS_MAX]; +} adc_wrapper_t; + +static adc_wrapper_t sensors; +/*---------------------------------------------------------------------------*/ +static uint16_t +convert_to_value(uint8_t index) +{ + uint32_t value; + value = adc_zoul.value(sensors.sensor[index].pin_mask); + + if(value == ZOUL_SENSORS_ERROR) { + PRINTF("ADC sensors: failed retrieving data\n"); + return ADC_WRAPPER_ERROR; + } + + /* Default voltage divisor relation is 5/3 aprox, change at adc_wrapper.h, + * calculations below assume a decimation rate of 512 (12 bits ENOB) and + * AVVD5 voltage reference of 3.3V + */ + + if(!sensors.sensor[index].vdd3) { + value *= ADC_WRAPPER_EXTERNAL_VREF; + value /= ADC_WRAPPER_EXTERNAL_VREF_CROSSVAL; + } + + switch(sensors.sensor[index].type) { + case ANALOG_GROVE_LIGHT: + /* Light dependant resistor (LDR) resistance value*/ + value = (10230 - (value * 10)) / value; + /* TODO: With the resistance we could calculate the lux as 63*R^(-0.7) */ + return (uint16_t)value; + + case ANALOG_GROVE_LOUDNESS: + /* Based on the LM2904 amplifier (blue version with potentiometer) */ + return (uint16_t)value; + + case ANALOG_PHIDGET_ROTATION_1109: + /* Linear sensor with 0-300º, 300/33000 = 0.00909 */ + value *= 909; + value /= 100000; + return (uint16_t)value; + + /* VDD+5 sensors */ + case ANALOG_VAC_SENSOR: + /* Linear sensor from 0 to 5 V; 0.0088 resolution*/ + value *= 88; + value /= 10000; + return (uint16_t)value; + + case ANALOG_AAC_SENSOR: + /* Linear sensor from 0 to 5 V;*/ + return (uint16_t)value; + + default: + return ADC_WRAPPER_ERROR; + } + + return ADC_WRAPPER_ERROR; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +is_sensor_in_list(int type) +{ + uint8_t i; + + for(i = 0; i <= sensors.sensors_num; i++) { + if(sensors.sensor[i].type == type) { + return i + 1; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + uint8_t index; + uint16_t sensor_value; + + index = is_sensor_in_list(type); + + if(!index) { + PRINTF("ADC sensors: sensor not registered\n"); + return ADC_WRAPPER_SUCCESS; + } + + /* Restore index value after the check */ + index -= 1; + sensor_value = convert_to_value(index); + + return sensor_value; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + uint8_t pin_mask = GPIO_PIN_MASK(value); + + if((type != ANALOG_GROVE_LIGHT) && (type != ANALOG_PHIDGET_ROTATION_1109) && + (type != ANALOG_GROVE_LOUDNESS) && (type != ANALOG_VAC_SENSOR) && + (type != ANALOG_AAC_SENSOR) ) { + PRINTF("ADC sensors: sensor not supported, check adc_wrapper.h header\n"); + return ADC_WRAPPER_ERROR; + } + + if(sensors.sensors_num >= ADC_SENSORS_MAX) { + PRINTF("ADC sensors: all adc channels available have been assigned\n"); + return ADC_WRAPPER_ERROR; + } + + if((value < 0x01) || (value > 0x07) || ((value == BUTTON_USER_PIN) && (ADC_SENSORS_ADC6_PIN < 0))) { + PRINTF("ADC sensors: invalid pin value, (PA0-PA1, PA3) are reserved\n"); + return ADC_WRAPPER_ERROR; + } + + if(sensors.sensors_ports & pin_mask) { + PRINTF("ADC sensors: a sensor has been already assigned to this pin\n"); + return ADC_WRAPPER_ERROR; + } + + switch(type) { + /* V+3.3 sensors */ + case ANALOG_GROVE_LIGHT: + case ANALOG_GROVE_LOUDNESS: + case ANALOG_PHIDGET_ROTATION_1109: + if(adc_zoul.configure(SENSORS_HW_INIT, pin_mask) == ZOUL_SENSORS_ERROR) { + return ADC_WRAPPER_ERROR; + } + sensors.sensor[sensors.sensors_num].type = type; + sensors.sensor[sensors.sensors_num].pin_mask = pin_mask; + sensors.sensor[sensors.sensors_num].vdd3 = 1; + break; + + /*V+5 sensors*/ + case ANALOG_VAC_SENSOR: + case ANALOG_AAC_SENSOR: + if(adc_zoul.configure(SENSORS_HW_INIT, pin_mask) == ZOUL_SENSORS_ERROR) { + return ADC_WRAPPER_ERROR; + } + sensors.sensor[sensors.sensors_num].type = type; + sensors.sensor[sensors.sensors_num].pin_mask = pin_mask; + sensors.sensor[sensors.sensors_num].vdd3 = 0; + break; + + + default: + return ADC_WRAPPER_ERROR; + } + + PRINTF("ADC sensors: type %u mask 0x%02X vdd3 %u\n", + sensors.sensor[sensors.sensors_num].type, + sensors.sensor[sensors.sensors_num].pin_mask, + sensors.sensor[sensors.sensors_num].vdd3); + + sensors.sensors_num++; + sensors.sensors_ports |= pin_mask; + + return ADC_WRAPPER_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(adc_sensors, ADC_SENSORS, value, configure, NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ + diff --git a/platform/zoul/dev/adc-sensors.h b/platform/zoul/dev/adc-sensors.h new file mode 100644 index 000000000..501eaa564 --- /dev/null +++ b/platform/zoul/dev/adc-sensors.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-adc-sensors Zoul adc wrapper to use analogue sensors + * + * The ADC wrapper implement analogue sensors on top of the ADC interface, + * obscuring the ADC configuration and required calculations to obtain actual + * sensor values. The driver allows to reuse the adc-wrapper implementation and + * add sensors easily, without duplicating code, providing also a simplified + * interface and exposing the available ADC assigned channels by a given + * platform. + * + * To use a given sensor simply use: adc_sensors.configure(SENSOR_NAME, pin_no), + * where pin_no is a given pin in the PA port, check out the board.h for more + * information on available pins. To read a value just use + * adc_sensors.value(SENSOR_NAME), the expected result would be the sensor value + * already converted to the sensor variable type, check the adc-wrapper file + * for more information. + * + * @{ + * + * \file + * Header file for the Zoul ADC sensors API + */ +/*---------------------------------------------------------------------------*/ +#ifndef ADC_SENSORS_H_ +#define ADC_SENSORS_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "dev/soc-adc.h" +#include "dev/adc-zoul.h" +/*---------------------------------------------------------------------------*/ +#define ADC_WRAPPER_SUCCESS 0x00 +#define ADC_WRAPPER_ERROR (-1) +#define ADC_WRAPPER_EXTERNAL_VREF 5000 +#define ADC_WRAPPER_EXTERNAL_VREF_CROSSVAL 3300 +/*---------------------------------------------------------------------------*/ +#define ANALOG_GROVE_LIGHT 0x01 +#define ANALOG_PHIDGET_ROTATION_1109 0x02 +#define ANALOG_GROVE_LOUDNESS 0x03 +#define ANALOG_VAC_SENSOR 0x04 +#define ANALOG_AAC_SENSOR 0x05 +/* -------------------------------------------------------------------------- */ +#define ADC_SENSORS "ADC sensors API" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor adc_sensors; +/*---------------------------------------------------------------------------*/ +#endif /* ADC_SENSORS_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/platform/zoul/dev/adc-zoul.c b/platform/zoul/dev/adc-zoul.c new file mode 100644 index 000000000..f19daab48 --- /dev/null +++ b/platform/zoul/dev/adc-zoul.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-adc-interface + * @{ + * + * \file + * Generic driver for the Zoul ADC interface + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sys/clock.h" +#include "dev/ioc.h" +#include "dev/gpio.h" +#include "dev/adc.h" +#include "adc-zoul.h" +#include "zoul-sensors.h" +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static uint8_t decimation_rate; +static uint8_t enabled_channels; +/*---------------------------------------------------------------------------*/ +static int +set_decimation_rate(uint8_t rate) +{ + switch(rate) { + case SOC_ADC_ADCCON_DIV_64: + case SOC_ADC_ADCCON_DIV_128: + case SOC_ADC_ADCCON_DIV_256: + case SOC_ADC_ADCCON_DIV_512: + decimation_rate = rate; + break; + default: + return ZOUL_SENSORS_ERROR; + } + + return decimation_rate; +} +/*---------------------------------------------------------------------------*/ +static int +get_channel_pin(int type) +{ + if((ZOUL_SENSORS_ADC1) && (type == ZOUL_SENSORS_ADC1)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC1_PIN; + } + if((ZOUL_SENSORS_ADC2) && (type == ZOUL_SENSORS_ADC2)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC2_PIN; + } + if((ZOUL_SENSORS_ADC3) && (type == ZOUL_SENSORS_ADC3)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC3_PIN; + } + if((ZOUL_SENSORS_ADC4) && (type == ZOUL_SENSORS_ADC4)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC4_PIN; + } + if((ZOUL_SENSORS_ADC5) && (type == ZOUL_SENSORS_ADC5)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC5_PIN; + } + if((ZOUL_SENSORS_ADC6) && (type == ZOUL_SENSORS_ADC6)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC6_PIN; + } + return ZOUL_SENSORS_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + int channel; + int16_t res; + + if(!(type & enabled_channels)) { + PRINTF("ADC: channel not enabled\n"); + return ZOUL_SENSORS_ERROR; + } + + channel = get_channel_pin(type); + + if(channel == ZOUL_SENSORS_ERROR) { + PRINTF("ADC: pin not active\n"); + return ZOUL_SENSORS_ERROR; + } + + res = adc_get(channel, ADC_SENSORS_REFERENCE, decimation_rate); + + /* Only allow negative values if using differential input */ + if((ADC_SENSORS_REFERENCE != SOC_ADC_ADCCON_REF_EXT_DIFF) && (res < 0)) { + res = 0; + } + + return res; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: + + /* This should filter out disabled sensors as its value should be zero */ + if((value < ZOUL_SENSORS_ADC_MIN) || (value > ZOUL_SENSORS_ADC_ALL)) { + PRINTF("ADC: invalid adc pin mask (0x%02X)\n", value); + return ZOUL_SENSORS_ERROR; + } + + GPIO_SOFTWARE_CONTROL(GPIO_A_BASE, value); + GPIO_SET_INPUT(GPIO_A_BASE, value); + + if(value & ZOUL_SENSORS_ADC1) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC1_PIN, IOC_OVERRIDE_ANA); + } + if(value & ZOUL_SENSORS_ADC2) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC2_PIN, IOC_OVERRIDE_ANA); + } + if(value & ZOUL_SENSORS_ADC3) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC3_PIN, IOC_OVERRIDE_ANA); + } + if(value & ZOUL_SENSORS_ADC4) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC4_PIN, IOC_OVERRIDE_ANA); + } + if(value & ZOUL_SENSORS_ADC5) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC5_PIN, IOC_OVERRIDE_ANA); + } + if(value & ZOUL_SENSORS_ADC6) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC6_PIN, IOC_OVERRIDE_ANA); + } + adc_init(); + set_decimation_rate(SOC_ADC_ADCCON_DIV_512); + enabled_channels += value; + break; + + case ZOUL_SENSORS_CONFIGURE_TYPE_DECIMATION_RATE: + return set_decimation_rate((uint8_t)value); + + default: + return ZOUL_SENSORS_ERROR; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(adc_zoul, ADC_ZOUL, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ + diff --git a/platform/zoul/dev/adc-zoul.h b/platform/zoul/dev/adc-zoul.h new file mode 100644 index 000000000..fca2643eb --- /dev/null +++ b/platform/zoul/dev/adc-zoul.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-adc-interface Zoul Generic ADC interface + * + * Driver for the Zoul ADC interface + * + * This driver supports analogue sensors connected to ADC1, ADC2, ADC3, + * ADC4, ADC5 and ADC6 inputs. ADC6 is shared with the user button, so disable + * user button if ADC6 is needed. + * This is controlled by the type argument of the value() function. Possible + * choices are: + * + * - ZOUL_SENSORS_ADC1 + * - ZOUL_SENSORS_ADC2 + * - ZOUL_SENSORS_ADC3 + * - ZOUL_SENSORS_ADC4 + * - ZOUL_SENSORS_ADC5 + * - ZOUL_SENSORS_ADC6 + * + * To initialize the ADC sensors use the configure() function, using as first + * argument SENSORS_HW_INIT, and choose which ADC channels to enable passing as + * second argument any single or combined (sum) values as below: + * + * - Either use multiple values (i.e ZOUL_SENSORS_ADC1 + ZOUL_SENSORS_ADC2) + * - ZOUL_SENSORS_ADC_ALL (all channels above) + * + * Using an invalid combination will return ZOUL_SENSORS_ERROR. + * + * The decimation rate can be set by passing + * ZOUL_SENSORS_CONFIGURE_TYPE_DECIMATION_RATE as the type argument to the + * configure() function and then specifying the rate through the value + * argument. Valid values are: + * + * - SOC_ADC_ADCCON_DIV_64 (64 bit rate) + * - SOC_ADC_ADCCON_DIV_128 (128 bit rate) + * - SOC_ADC_ADCCON_DIV_256 (256 bit rate) + * - SOC_ADC_ADCCON_DIV_512 (512 bit rate) + * @{ + * + * \file + * Header file for the Zoul ADC interface + */ +/*---------------------------------------------------------------------------*/ +#ifndef ADC_ZOUL_H_ +#define ADC_ZOUL_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "dev/soc-adc.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Generic ADC sensors + * @{ + */ +#define ADC_ZOUL "ADC sensor interface" +#define ADC_SENSORS_PORT_BASE GPIO_PORT_TO_BASE(ADC_SENSORS_PORT) + +#ifdef ADC_SENSORS_CONF_REFERENCE +#define ADC_SENSORS_REFERENCE ADC_SENSORS_CONF_REFERENCE +#else +#define ADC_SENSORS_REFERENCE SOC_ADC_ADCCON_REF_AVDD5 +#endif + +/* + * PA0-PA3 are hardcoded to UART0 and the user button for most Zolertia + * platforms, the following assumes PA0-1 shall not be used as ADC input, else + * re-write the below definitions + */ +#define ZOUL_SENSORS_ADC_MIN 2 /**< PA1 pin mask */ + +/* ADC phidget-like connector ADC1 */ +#if ADC_SENSORS_ADC1_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC1 GPIO_PIN_MASK(ADC_SENSORS_ADC1_PIN) +#else +#define ZOUL_SENSORS_ADC1 0 +#endif +/* ADC phidget-like connector ADC2 */ +#if ADC_SENSORS_ADC2_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC2 GPIO_PIN_MASK(ADC_SENSORS_ADC2_PIN) +#else +#define ZOUL_SENSORS_ADC2 0 +#endif +/* ADC phidget-like connector ADC3 */ +#if ADC_SENSORS_ADC3_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC3 GPIO_PIN_MASK(ADC_SENSORS_ADC3_PIN) +#else +#define ZOUL_SENSORS_ADC3 0 +#endif +/* ADC phidget-like connector ADC4 */ +#if ADC_SENSORS_ADC4_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC4 GPIO_PIN_MASK(ADC_SENSORS_ADC4_PIN) +#else +#define ZOUL_SENSORS_ADC4 0 +#endif +/* ADC phidget-like connector ADC5 */ +#if ADC_SENSORS_ADC5_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC5 GPIO_PIN_MASK(ADC_SENSORS_ADC5_PIN) +#else +#define ZOUL_SENSORS_ADC5 0 +#endif + +/* ADC phidget-like connector ADC6 */ +#if ADC_SENSORS_ADC6_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC6 GPIO_PIN_MASK(ADC_SENSORS_ADC6_PIN) +#else +#define ZOUL_SENSORS_ADC6 0 +#endif +/* + * This is safe as the disabled sensors should have a zero value thus not + * affecting the mask operations + */ +#define ZOUL_SENSORS_ADC_ALL (ZOUL_SENSORS_ADC1 + ZOUL_SENSORS_ADC2 + \ + ZOUL_SENSORS_ADC3 + ZOUL_SENSORS_ADC4 + \ + ZOUL_SENSORS_ADC5 + ZOUL_SENSORS_ADC6) +/** @} */ +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor adc_zoul; +/*---------------------------------------------------------------------------*/ +#endif /* ADC_ZOUL_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/platform/zoul/dev/bmpx8x.c b/platform/zoul/dev/bmpx8x.c new file mode 100644 index 000000000..41e1b2d13 --- /dev/null +++ b/platform/zoul/dev/bmpx8x.c @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-bmpx8x-sensor + * @{ + * + * BMP085/BMP180 driver implementation + * + * \file + * Driver for the external BMP085/BMP180 atmospheric pressure sensor + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/i2c.h" +#include "dev/gpio.h" +#include "dev/zoul-sensors.h" +#include "lib/sensors.h" +#include "bmpx8x.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static uint8_t enabled = 0; +/*---------------------------------------------------------------------------*/ +typedef struct { + int16_t ac1; + int16_t ac2; + int16_t ac3; + uint16_t ac4; + uint16_t ac5; + uint16_t ac6; + int16_t b1; + int16_t b2; + int16_t mb; + int16_t mc; + int16_t md; +} bmpx8x_calibration_values; + +typedef struct { + uint8_t oversampling_mode; + int32_t b5; + bmpx8x_calibration_values calib; +} bmpx8x_config; + +static bmpx8x_config bmpx8x_values; +/*---------------------------------------------------------------------------*/ +static int +bmpx8x_read_reg(uint8_t reg, uint8_t *buf, uint8_t num) +{ + if((buf == NULL) || (num <= 0)) { + PRINTF("BMPx8x: invalid read values\n"); + return BMPx8x_ERROR; + } + + i2c_master_enable(); + if(i2c_single_send(BMPx8x_ADDR, reg) == I2C_MASTER_ERR_NONE) { + while(i2c_master_busy()); + if(i2c_burst_receive(BMPx8x_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { + return BMPx8x_SUCCESS; + } + } + return BMPx8x_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +bmpx8x_write_reg(uint8_t *buf, uint8_t num) +{ + if((buf == NULL) || (num <= 0)) { + PRINTF("BMPx8x: invalid write values\n"); + return BMPx8x_ERROR; + } + + i2c_master_enable(); + if(i2c_burst_send(BMPx8x_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { + return BMPx8x_SUCCESS; + } + return BMPx8x_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +bmpx8x_read_calib(void) +{ + uint8_t buf[BMPx8x_CALIB_TABLE_SIZE]; + + if(bmpx8x_read_reg(BMPx8x_AC1_CALIB, buf, + BMPx8x_CALIB_TABLE_SIZE) == BMPx8x_SUCCESS) { + + /* MSB first */ + bmpx8x_values.calib.ac1 = ((buf[0] << 8) + buf[1]); + bmpx8x_values.calib.ac2 = ((buf[2] << 8) + buf[3]); + bmpx8x_values.calib.ac3 = ((buf[4] << 8) + buf[5]); + bmpx8x_values.calib.ac4 = ((buf[6] << 8) + buf[7]); + bmpx8x_values.calib.ac5 = ((buf[8] << 8) + buf[9]); + bmpx8x_values.calib.ac6 = ((buf[10] << 8) + buf[11]); + bmpx8x_values.calib.b1 = ((buf[12] << 8) + buf[13]); + bmpx8x_values.calib.b2 = ((buf[14] << 8) + buf[15]); + bmpx8x_values.calib.mb = ((buf[16] << 8) + buf[17]); + bmpx8x_values.calib.mc = ((buf[18] << 8) + buf[19]); + bmpx8x_values.calib.md = ((buf[20] << 8) + buf[21]); + + return BMPx8x_SUCCESS; + } + + PRINTF("BMPx8x: failed to read calibration\n"); + return BMPx8x_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +bmpx8x_read_uncompensated_pressure(int32_t *pressure) +{ + uint8_t buf[3]; + uint16_t delay; + int32_t upres; + + buf[0] = BMPx8x_CTRL_REG; + + switch(bmpx8x_values.oversampling_mode) { + case BMPx8x_MODE_ULTRA_LOW_POWER: + buf[1] = BMPx8x_CTRL_REG_PRESS_4_5MS; + delay = BMPx8x_DELAY_4_5MS; + break; + case BMPx8x_MODE_STANDARD: + buf[1] = BMPx8x_CTRL_REG_PRESS_7_5MS; + delay = BMPx8x_DELAY_7_5MS; + break; + case BMPx8x_MODE_HIGH_RES: + buf[1] = BMPx8x_CTRL_REG_PRESS_13_5MS; + delay = BMPx8x_DELAY_13_5MS; + break; + case BMPx8x_MODE_ULTRA_HIGH_RES: + buf[1] = BMPx8x_CTRL_REG_PRESS_25_5MS; + delay = BMPx8x_DELAY_25_5MS; + break; + default: + return BMPx8x_ERROR; + } + + if(bmpx8x_write_reg(buf, 2) == BMPx8x_SUCCESS) { + clock_delay_usec(delay); + if(bmpx8x_read_reg(BMPx8x_DATA_MSB, buf, 3) == BMPx8x_SUCCESS) { + upres = (buf[0] << 16) + (buf[1] << 8) + buf[2]; + *pressure = (upres >> (8 - bmpx8x_values.oversampling_mode)); + return BMPx8x_SUCCESS; + } + } + return BMPx8x_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +bmpx8x_read_uncompensated_temperature(int32_t *temp) +{ + uint8_t buf[2]; + buf[0] = BMPx8x_CTRL_REG; + buf[1] = BMPx8x_CTRL_REG_TEMP; + + if(bmpx8x_write_reg(buf, 2) == BMPx8x_SUCCESS) { + clock_delay_usec(BMPx8x_DELAY_4_5MS); + if(bmpx8x_read_reg(BMPx8x_DATA_MSB, buf, 2) == BMPx8x_SUCCESS) { + *temp = (int32_t)((buf[0] << 8) + buf[1]); + return BMPx8x_SUCCESS; + } + } + return BMPx8x_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +bmpx8x_read_temperature(int16_t *temp) +{ + int32_t ut = 0; + int32_t x1, x2; + + if(bmpx8x_read_uncompensated_temperature(&ut) == BMPx8x_ERROR) { + return BMPx8x_ERROR; + } + + x1 = ((int32_t)ut - (int32_t)bmpx8x_values.calib.ac6) + * (int32_t)bmpx8x_values.calib.ac5 >> 15; + x2 = ((int32_t)bmpx8x_values.calib.mc << 11) / (x1 + bmpx8x_values.calib.md); + bmpx8x_values.b5 = x1 + x2; + *temp = (int16_t)((bmpx8x_values.b5 + 8) >> 4); + return BMPx8x_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +bmpx8x_read_pressure(int32_t *pressure) +{ + int32_t ut = 0; + int32_t up = 0; + int32_t x1, x2, b6, x3, b3, p; + uint32_t b4, b7; + + if(bmpx8x_read_uncompensated_pressure(&up) == BMPx8x_ERROR) { + return BMPx8x_ERROR; + } + + if(bmpx8x_read_uncompensated_temperature(&ut) == BMPx8x_ERROR) { + return BMPx8x_ERROR; + } + + b6 = bmpx8x_values.b5 - 4000; + x1 = (bmpx8x_values.calib.b2 * (b6 * b6 >> 12)) >> 11; + x2 = bmpx8x_values.calib.ac2 * b6 >> 11; + x3 = x1 + x2; + b3 = ((((int32_t)bmpx8x_values.calib.ac1) * 4 + x3) + 2) >> 2; + + x1 = (bmpx8x_values.calib.ac3 * b6) >> 13; + x2 = (bmpx8x_values.calib.b1 * ((b6 * b6) >> 12)) >> 16; + x3 = ((x1 + x2) + 2) >> 2; + b4 = (bmpx8x_values.calib.ac4 * ((uint32_t)(x3 + 32768))) >> 15; + b7 = ((uint32_t)up - b3) * 50000; + + if(b7 < 0x80000000) { + p = (b7 << 1) / b4; + } else { + p = (b7 / b4) << 1; + } + + x1 = (p >> 8) * (p >> 8); + x1 = (x1 * 3038) >> 16; + x2 = (-7357 * p) >> 16; + *pressure = (p + ((x1 + x2 + 3791) >> 4)); + *pressure /= 10; + + return BMPx8x_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if((type != BMPx8x_ACTIVE) && (type != BMPx8x_OVERSAMPLING)) { + PRINTF("BMPx8x: invalid start value\n"); + return BMPx8x_ERROR; + } + + if(type == BMPx8x_ACTIVE) { + if(value) { + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_NORMAL_BUS_SPEED); + + /* Read the calibration values */ + if(bmpx8x_read_calib() != BMPx8x_ERROR) { + PRINTF("BMPx8x: sensor started\n"); + enabled = 1; + bmpx8x_values.oversampling_mode = BMPx8x_MODE_ULTRA_LOW_POWER; + return BMPx8x_SUCCESS; + } + + PRINTF("BMPx8x: failed to enable\n"); + return BMPx8x_ERROR; + } else { + enabled = 0; + return BMPx8x_SUCCESS; + } + } else if(type == BMPx8x_OVERSAMPLING) { + if((value < BMPx8x_MODE_ULTRA_LOW_POWER) || + (value > BMPx8x_MODE_ULTRA_HIGH_RES)) { + PRINTF("BMPx8x: invalid oversampling value\n"); + return BMPx8x_ERROR; + } + bmpx8x_values.oversampling_mode = value; + return BMPx8x_SUCCESS; + } + + return BMPx8x_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +bmpx8x_read_sensor(int32_t *value, uint8_t type) +{ + int16_t temp = 0; + + /* The temperature is required to compensate the pressure value */ + if(bmpx8x_read_temperature(&temp) != BMPx8x_SUCCESS) { + return BMPx8x_ERROR; + } + + switch(type) { + case BMPx8x_READ_PRESSURE: + return bmpx8x_read_pressure(value); + + case BMPx8x_READ_TEMP: + *value = (int16_t) temp; + return BMPx8x_SUCCESS; + } + + return BMPx8x_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + int32_t value; + + if(!enabled) { + PRINTF("BMPx8x: sensor not started\n"); + return BMPx8x_ERROR; + } + + if((type != BMPx8x_READ_PRESSURE) && (type != BMPx8x_READ_TEMP)) { + PRINTF("BMPx8x: invalid read value\n"); + return BMPx8x_ERROR; + } + + if(bmpx8x_read_sensor(&value, type) == BMPx8x_SUCCESS) { + return (int)value; + } + + PRINTF("BMPx8x: fail to read\n"); + return BMPx8x_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(bmpx8x, BMPx8x_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/bmpx8x.h b/platform/zoul/dev/bmpx8x.h new file mode 100644 index 000000000..75f768bef --- /dev/null +++ b/platform/zoul/dev/bmpx8x.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-bmpx8x-sensor BMP085/BMP180 Sensor + * + * Driver for the BMP085/BMP180 sensor + * + * BMP085/BMP180 digital atmospheric pressure and temperature driver + * @{ + * + * \file + * Header file for the external BMP085/BMP180 Sensor Driver + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#ifndef BMPX8X_H_ +#define BMPX8X_H_ +#include +#include "lib/sensors.h" +#include "dev/zoul-sensors.h" +#include "i2c.h" +/* -------------------------------------------------------------------------- */ +/** + * \name BMPx8x address and registers + * @{ + */ +/* -------------------------------------------------------------------------- */ +#define BMPx8x_ADDR 0x77 +/* -------------------------------------------------------------------------- */ +/* Control register */ +#define BMPx8x_CTRL_REG 0xF4 +/* Read uncompensated temperature */ +#define BMPx8x_CTRL_REG_TEMP 0x2E +/* Read uncompensated pressure, no oversampling */ +#define BMPx8x_CTRL_REG_PRESS_4_5MS 0x34 +/* Read uncompensated pressure, oversampling 1*/ +#define BMPx8x_CTRL_REG_PRESS_7_5MS 0x74 +/* Read uncompensated pressure, oversampling 2 */ +#define BMPx8x_CTRL_REG_PRESS_13_5MS 0xB4 +/* Read uncompensated pressure, oversampling 3 */ +#define BMPx8x_CTRL_REG_PRESS_25_5MS 0xF4 +/* -------------------------------------------------------------------------- */ +#define BMPx8x_DATA_MSB 0xF6 +#define BMPx8x_DATA_LSB 0xF7 +/* 19-bit resolution */ +#define BMPx8x_DATA_XLSB 0xF8 +/* -------------------------------------------------------------------------- */ +/* Calibration registers, 16-bit wide */ +#define BMPx8x_AC1_CALIB 0xAA +#define BMPx8x_AC2_CALIB 0xAC +#define BMPx8x_AC3_CALIB 0xAE +#define BMPx8x_AC4_CALIB 0xB0 +#define BMPx8x_AC5_CALIB 0xB2 +#define BMPx8x_AC6_CALIB 0xB4 +#define BMPx8x_B1_CALIB 0xB6 +#define BMPx8x_B2_CALIB 0xB8 +#define BMPx8x_MB_CALIB 0xBA +#define BMPx8x_MC_CALIB 0xBC +#define BMPx8x_MD_CALIB 0xBE +#define BMPx8x_CALIB_TABLE_SIZE 22 /**< size in bytes */ +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name BMPx8x operation modes + * @{ + */ +#define BMPx8x_MODE_ULTRA_LOW_POWER 0x00 +#define BMPx8x_MODE_STANDARD 0x01 +#define BMPx8x_MODE_HIGH_RES 0x02 +#define BMPx8x_MODE_ULTRA_HIGH_RES 0x03 +/* -------------------------------------------------------------------------- */ +#define BMPx8x_DELAY_4_5MS 4700 +#define BMPx8x_DELAY_7_5MS 7700 +#define BMPx8x_DELAY_13_5MS 13700 +#define BMPx8x_DELAY_25_5MS 25700 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name BMPx8x return and command values + * @{ + */ +#define BMPx8x_SUCCESS 0x00 +#define BMPx8x_ERROR -1 + +#define BMPx8x_ACTIVE SENSORS_ACTIVE +#define BMPx8x_OVERSAMPLING 0x00 +#define BMPx8x_READ_PRESSURE 0x01 +#define BMPx8x_READ_TEMP 0x02 +/** @} */ +/* -------------------------------------------------------------------------- */ +#define BMPx8x_SENSOR "BMP085/BMP180 pressure and temperature sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor bmpx8x; +/* -------------------------------------------------------------------------- */ +#endif +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ + diff --git a/platform/zoul/dev/button-sensor.c b/platform/zoul/dev/button-sensor.c new file mode 100644 index 000000000..e9560904f --- /dev/null +++ b/platform/zoul/dev/button-sensor.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-button-sensor + * @{ + * + * \file + * Driver for the Zoul user button + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/nvic.h" +#include "dev/ioc.h" +#include "dev/gpio.h" +#include "dev/button-sensor.h" +#include "sys/timer.h" +#include "sys/ctimer.h" +#include "sys/process.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define BUTTON_USER_PORT_BASE GPIO_PORT_TO_BASE(BUTTON_USER_PORT) +#define BUTTON_USER_PIN_MASK GPIO_PIN_MASK(BUTTON_USER_PIN) +/*---------------------------------------------------------------------------*/ +#define DEBOUNCE_DURATION (CLOCK_SECOND >> 4) + +static struct timer debouncetimer; +/*---------------------------------------------------------------------------*/ +static clock_time_t press_duration = 0; +static struct ctimer press_counter; +static uint8_t press_event_counter; + +process_event_t button_press_duration_exceeded; +/*---------------------------------------------------------------------------*/ +static void +duration_exceeded_callback(void *data) +{ + press_event_counter++; + process_post(PROCESS_BROADCAST, button_press_duration_exceeded, + &press_event_counter); + ctimer_set(&press_counter, press_duration, duration_exceeded_callback, + NULL); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Retrieves the value of the button pin + * \param type Returns the pin level or the counter of press duration events. + * type == BUTTON_SENSOR_VALUE_TYPE_LEVEL or + * type == BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION + * respectively + */ +static int +value(int type) +{ + switch(type) { + case BUTTON_SENSOR_VALUE_TYPE_LEVEL: + return GPIO_READ_PIN(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + case BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION: + return press_event_counter; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Callback registered with the GPIO module. Gets fired with a button + * port/pin generates an interrupt + * \param port The port number that generated the interrupt + * \param pin The pin number that generated the interrupt. This is the pin + * absolute number (i.e. 0, 1, ..., 7), not a mask + */ +static void +btn_callback(uint8_t port, uint8_t pin) +{ + if(!timer_expired(&debouncetimer)) { + return; + } + + timer_set(&debouncetimer, DEBOUNCE_DURATION); + + if(press_duration) { + press_event_counter = 0; + if(value(BUTTON_SENSOR_VALUE_TYPE_LEVEL) == BUTTON_SENSOR_PRESSED_LEVEL) { + ctimer_set(&press_counter, press_duration, duration_exceeded_callback, + NULL); + } else { + ctimer_stop(&press_counter); + } + } + + sensors_changed(&button_sensor); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Init function for the User button. + * \param type SENSORS_ACTIVE: Activate / Deactivate the sensor (value == 1 + * or 0 respectively) + * + * \param value Depends on the value of the type argument + * \return Depends on the value of the type argument + */ +static int +config_user(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: + button_press_duration_exceeded = process_alloc_event(); + + /* Software controlled */ + GPIO_SOFTWARE_CONTROL(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + + /* Set pin to input */ + GPIO_SET_INPUT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + + /* Enable edge detection */ + GPIO_DETECT_EDGE(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + + /* Both Edges */ + GPIO_TRIGGER_BOTH_EDGES(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + + ioc_set_over(BUTTON_USER_PORT, BUTTON_USER_PIN, IOC_OVERRIDE_PUE); + + gpio_register_callback(btn_callback, BUTTON_USER_PORT, BUTTON_USER_PIN); + break; + case SENSORS_ACTIVE: + if(value) { + GPIO_ENABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + nvic_interrupt_enable(BUTTON_USER_VECTOR); + } else { + GPIO_DISABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + nvic_interrupt_disable(BUTTON_USER_VECTOR); + } + return value; + case BUTTON_SENSOR_CONFIG_TYPE_INTERVAL: + press_duration = (clock_time_t)value; + break; + default: + break; + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, value, config_user, NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/button-sensor.h b/platform/zoul/dev/button-sensor.h new file mode 100644 index 000000000..12e333c4a --- /dev/null +++ b/platform/zoul/dev/button-sensor.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-button-sensor Zoul User Button Driver + * + * Driver for the Zoul user button + * + * The user button (on Zoul-based platforms like the RE-Mote and the Firefly) + * will generate a sensors_changed event on press as well as on release. + * + * Unlike many other platforms, the user button has the ability to + * generate events when the user keeps the button pressed. The user can + * configure the button driver with a timer interval in clock ticks. When the + * button is kept pressed, the driver will then generate a broadcast event + * each time the interval passes. For example the driver can be configured to + * generate an event every second while the button is kept pressed. This + * functionality can be enabled through the configure() function, by passing + * BUTTON_SENSOR_CONFIG_TYPE_INTERVAL as the type argument. + * @{ + * + * \file + * Header file for the Zoul User Button Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef BUTTON_SENSOR_H_ +#define BUTTON_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR "Button" + +extern const struct sensors_sensor button_sensor; +/*---------------------------------------------------------------------------*/ +extern process_event_t button_press_duration_exceeded; +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR_CONFIG_TYPE_INTERVAL 0x0100 + +#define BUTTON_SENSOR_VALUE_TYPE_LEVEL 0 +#define BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION 1 + +#define BUTTON_SENSOR_PRESSED_LEVEL 0 +#define BUTTON_SENSOR_RELEASED_LEVEL 8 +/*---------------------------------------------------------------------------*/ +#endif /* BUTTON_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/cc1200-zoul-arch.c b/platform/zoul/dev/cc1200-zoul-arch.c new file mode 100644 index 000000000..0df21a037 --- /dev/null +++ b/platform/zoul/dev/cc1200-zoul-arch.c @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul + * @{ + * + * \defgroup zoul-cc1200 Zoul CC1200 arch + * + * CC1200 Zoul arch specifics + * @{ + * + * \file + * CC1200 Zoul arch specifics + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "contiki-net.h" +#include "dev/leds.h" +#include "reg.h" +#include "spi-arch.h" +#include "dev/ioc.h" +#include "dev/sys-ctrl.h" +#include "dev/spi.h" +#include "dev/ssi.h" +#include "dev/gpio.h" +#include +/*---------------------------------------------------------------------------*/ +#define CC1200_SPI_CLK_PORT_BASE GPIO_PORT_TO_BASE(SPI0_CLK_PORT) +#define CC1200_SPI_CLK_PIN_MASK GPIO_PIN_MASK(SPI0_CLK_PIN) +#define CC1200_SPI_MOSI_PORT_BASE GPIO_PORT_TO_BASE(SPI0_TX_PORT) +#define CC1200_SPI_MOSI_PIN_MASK GPIO_PIN_MASK(SPI0_TX_PIN) +#define CC1200_SPI_MISO_PORT_BASE GPIO_PORT_TO_BASE(SPI0_RX_PORT) +#define CC1200_SPI_MISO_PIN_MASK GPIO_PIN_MASK(SPI0_RX_PIN) +#define CC1200_SPI_CSN_PORT_BASE GPIO_PORT_TO_BASE(CC1200_SPI_CSN_PORT) +#define CC1200_SPI_CSN_PIN_MASK GPIO_PIN_MASK(CC1200_SPI_CSN_PIN) +#define CC1200_GDO0_PORT_BASE GPIO_PORT_TO_BASE(CC1200_GDO0_PORT) +#define CC1200_GDO0_PIN_MASK GPIO_PIN_MASK(CC1200_GDO0_PIN) +#define CC1200_GDO2_PORT_BASE GPIO_PORT_TO_BASE(CC1200_GDO2_PORT) +#define CC1200_GDO2_PIN_MASK GPIO_PIN_MASK(CC1200_GDO2_PIN) +#define CC1200_RESET_PORT_BASE GPIO_PORT_TO_BASE(CC1200_RESET_PORT) +#define CC1200_RESET_PIN_MASK GPIO_PIN_MASK(CC1200_RESET_PIN) +/*---------------------------------------------------------------------------*/ +#ifndef DEBUG_CC1200_ARCH +#define DEBUG_CC1200_ARCH 0 +#endif +/*---------------------------------------------------------------------------*/ +#if DEBUG_CC1200_ARCH > 0 +#define PRINTF(...) printf(__VA_ARGS__) +#define BUSYWAIT_UNTIL(cond, max_time) \ + do { \ + rtimer_clock_t t0; \ + t0 = RTIMER_NOW(); \ + while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))) {} \ + if(!(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time)))) { \ + printf("ARCH: Timeout exceeded in line %d!\n", __LINE__); \ + } \ + } while(0) +#else +#define PRINTF(...) +#define BUSYWAIT_UNTIL(cond, max_time) while(!cond) +#endif +/*---------------------------------------------------------------------------*/ +extern int cc1200_rx_interrupt(void); +/*---------------------------------------------------------------------------*/ +void +cc1200_int_handler(uint8_t port, uint8_t pin) +{ + /* To keep the gpio_register_callback happy */ + cc1200_rx_interrupt(); +} +/*---------------------------------------------------------------------------*/ +void +cc1200_arch_spi_select(void) +{ + /* Set CSn to low (0) */ + GPIO_CLR_PIN(CC1200_SPI_CSN_PORT_BASE, CC1200_SPI_CSN_PIN_MASK); + /* The MISO pin should go low before chip is fully enabled. */ + BUSYWAIT_UNTIL( + GPIO_READ_PIN(CC1200_SPI_MISO_PORT_BASE, CC1200_SPI_MISO_PIN_MASK) == 0, + RTIMER_SECOND / 100); +} +/*---------------------------------------------------------------------------*/ +void +cc1200_arch_spi_deselect(void) +{ + /* Set CSn to high (1) */ + GPIO_SET_PIN(CC1200_SPI_CSN_PORT_BASE, CC1200_SPI_CSN_PIN_MASK); +} +/*---------------------------------------------------------------------------*/ +int +cc1200_arch_spi_rw_byte(uint8_t c) +{ + SPI_WAITFORTx_BEFORE(); + SPIX_BUF(CC1200_SPI_INSTANCE) = c; + SPIX_WAITFOREOTx(CC1200_SPI_INSTANCE); + SPIX_WAITFOREORx(CC1200_SPI_INSTANCE); + c = SPIX_BUF(CC1200_SPI_INSTANCE); + + return c; +} +/*---------------------------------------------------------------------------*/ +int +cc1200_arch_spi_rw(uint8_t *inbuf, const uint8_t *write_buf, uint16_t len) +{ + int i; + uint8_t c; + + if((inbuf == NULL && write_buf == NULL) || len <= 0) { + return 1; + } else if(inbuf == NULL) { + for(i = 0; i < len; i++) { + SPI_WAITFORTx_BEFORE(); + SPIX_BUF(CC1200_SPI_INSTANCE) = write_buf[i]; + SPIX_WAITFOREOTx(CC1200_SPI_INSTANCE); + SPIX_WAITFOREORx(CC1200_SPI_INSTANCE); + c = SPIX_BUF(CC1200_SPI_INSTANCE); + /* read and discard to avoid "variable set but not used" warning */ + (void)c; + } + } else if(write_buf == NULL) { + for(i = 0; i < len; i++) { + SPI_WAITFORTx_BEFORE(); + SPIX_BUF(CC1200_SPI_INSTANCE) = 0; + SPIX_WAITFOREOTx(CC1200_SPI_INSTANCE); + SPIX_WAITFOREORx(CC1200_SPI_INSTANCE); + inbuf[i] = SPIX_BUF(CC1200_SPI_INSTANCE); + } + } else { + for(i = 0; i < len; i++) { + SPI_WAITFORTx_BEFORE(); + SPIX_BUF(CC1200_SPI_INSTANCE) = write_buf[i]; + SPIX_WAITFOREOTx(CC1200_SPI_INSTANCE); + SPIX_WAITFOREORx(CC1200_SPI_INSTANCE); + inbuf[i] = SPIX_BUF(CC1200_SPI_INSTANCE); + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +void +cc1200_arch_gpio0_setup_irq(int rising) +{ + + GPIO_SOFTWARE_CONTROL(CC1200_GDO0_PORT_BASE, CC1200_GDO0_PIN_MASK); + GPIO_SET_INPUT(CC1200_GDO0_PORT_BASE, CC1200_GDO0_PIN_MASK); + GPIO_DETECT_EDGE(CC1200_GDO0_PORT_BASE, CC1200_GDO0_PIN_MASK); + GPIO_TRIGGER_SINGLE_EDGE(CC1200_GDO0_PORT_BASE, CC1200_GDO0_PIN_MASK); + + if(rising) { + GPIO_DETECT_RISING(CC1200_GDO0_PORT_BASE, CC1200_GDO0_PIN_MASK); + } else { + GPIO_DETECT_FALLING(CC1200_GDO0_PORT_BASE, CC1200_GDO0_PIN_MASK); + } + + GPIO_ENABLE_INTERRUPT(CC1200_GDO0_PORT_BASE, CC1200_GDO0_PIN_MASK); + ioc_set_over(CC1200_GDO0_PORT, CC1200_GDO0_PIN, IOC_OVERRIDE_PUE); + nvic_interrupt_enable(CC1200_GPIOx_VECTOR); + gpio_register_callback(cc1200_int_handler, CC1200_GDO0_PORT, + CC1200_GDO0_PIN); +} +/*---------------------------------------------------------------------------*/ +void +cc1200_arch_gpio2_setup_irq(int rising) +{ + + GPIO_SOFTWARE_CONTROL(CC1200_GDO2_PORT_BASE, CC1200_GDO2_PIN_MASK); + GPIO_SET_INPUT(CC1200_GDO2_PORT_BASE, CC1200_GDO2_PIN_MASK); + GPIO_DETECT_EDGE(CC1200_GDO2_PORT_BASE, CC1200_GDO2_PIN_MASK); + GPIO_TRIGGER_SINGLE_EDGE(CC1200_GDO2_PORT_BASE, CC1200_GDO2_PIN_MASK); + + if(rising) { + GPIO_DETECT_RISING(CC1200_GDO2_PORT_BASE, CC1200_GDO2_PIN_MASK); + } else { + GPIO_DETECT_FALLING(CC1200_GDO2_PORT_BASE, CC1200_GDO2_PIN_MASK); + } + + GPIO_ENABLE_INTERRUPT(CC1200_GDO2_PORT_BASE, CC1200_GDO2_PIN_MASK); + ioc_set_over(CC1200_GDO2_PORT, CC1200_GDO2_PIN, IOC_OVERRIDE_PUE); + nvic_interrupt_enable(CC1200_GPIOx_VECTOR); + gpio_register_callback(cc1200_int_handler, CC1200_GDO2_PORT, + CC1200_GDO2_PIN); +} +/*---------------------------------------------------------------------------*/ +void +cc1200_arch_gpio0_enable_irq(void) +{ + GPIO_ENABLE_INTERRUPT(CC1200_GDO0_PORT_BASE, CC1200_GDO0_PIN_MASK); + ioc_set_over(CC1200_GDO0_PORT, CC1200_GDO0_PIN, IOC_OVERRIDE_PUE); + nvic_interrupt_enable(CC1200_GPIOx_VECTOR); +} +/*---------------------------------------------------------------------------*/ +void +cc1200_arch_gpio0_disable_irq(void) +{ + GPIO_DISABLE_INTERRUPT(CC1200_GDO0_PORT_BASE, CC1200_GDO0_PIN_MASK); +} +/*---------------------------------------------------------------------------*/ +void +cc1200_arch_gpio2_enable_irq(void) +{ + GPIO_ENABLE_INTERRUPT(CC1200_GDO2_PORT_BASE, CC1200_GDO2_PIN_MASK); + ioc_set_over(CC1200_GDO2_PORT, CC1200_GDO2_PIN, IOC_OVERRIDE_PUE); + nvic_interrupt_enable(CC1200_GPIOx_VECTOR); +} +/*---------------------------------------------------------------------------*/ +void +cc1200_arch_gpio2_disable_irq(void) +{ + GPIO_DISABLE_INTERRUPT(CC1200_GDO2_PORT_BASE, CC1200_GDO2_PIN_MASK); +} +/*---------------------------------------------------------------------------*/ +int +cc1200_arch_gpio0_read_pin(void) +{ + return GPIO_READ_PIN(CC1200_GDO0_PORT_BASE, CC1200_GDO0_PIN_MASK); +} +/*---------------------------------------------------------------------------*/ +int +cc1200_arch_gpio2_read_pin(void) +{ + return GPIO_READ_PIN(CC1200_GDO2_PORT_BASE, CC1200_GDO2_PIN_MASK); +} +/*---------------------------------------------------------------------------*/ +int +cc1200_arch_gpio3_read_pin(void) +{ + return 0x00; +} +/*---------------------------------------------------------------------------*/ +void +cc1200_arch_init(void) +{ + /* First leave RESET high */ + GPIO_SOFTWARE_CONTROL(CC1200_RESET_PORT_BASE, CC1200_RESET_PIN_MASK); + GPIO_SET_OUTPUT(CC1200_RESET_PORT_BASE, CC1200_RESET_PIN_MASK); + ioc_set_over(CC1200_RESET_PORT, CC1200_RESET_PIN, IOC_OVERRIDE_OE); + GPIO_SET_PIN(CC1200_RESET_PORT_BASE, CC1200_RESET_PIN_MASK); + + /* Initialize CSn, enable CSn and then wait for MISO to go low*/ + spix_cs_init(CC1200_SPI_CSN_PORT, CC1200_SPI_CSN_PIN); + + /* Initialize SPI */ + spix_init(CC1200_SPI_INSTANCE); + + /* Configure GPIOx */ + GPIO_SOFTWARE_CONTROL(CC1200_GDO0_PORT_BASE, CC1200_GDO0_PIN_MASK); + GPIO_SET_INPUT(CC1200_GDO0_PORT_BASE, CC1200_GDO0_PIN_MASK); + GPIO_SOFTWARE_CONTROL(CC1200_GDO2_PORT_BASE, CC1200_GDO2_PIN_MASK); + GPIO_SET_INPUT(CC1200_GDO2_PORT_BASE, CC1200_GDO2_PIN_MASK); + + /* Leave CSn as default */ + cc1200_arch_spi_deselect(); + + /* Ensure MISO is high */ + BUSYWAIT_UNTIL( + GPIO_READ_PIN(CC1200_SPI_MISO_PORT_BASE, CC1200_SPI_MISO_PIN_MASK), + RTIMER_SECOND / 10); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/platform/zoul/dev/grove-gyro.c b/platform/zoul/dev/grove-gyro.c new file mode 100644 index 000000000..56f79d9b3 --- /dev/null +++ b/platform/zoul/dev/grove-gyro.c @@ -0,0 +1,647 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-grove-gyro-sensor + * @{ + * + * \file + * Grove's 3-axis gyroscope driver + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/i2c.h" +#include "dev/grove-gyro.h" +#include "lib/sensors.h" +#include "dev/watchdog.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +#define GROVE_GYRO_INT_PORT_BASE GPIO_PORT_TO_BASE(I2C_INT_PORT) +#define GROVE_GYRO_INT_PIN_MASK GPIO_PIN_MASK(I2C_INT_PIN) +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +static uint8_t power_mgmt; +static uint8_t int_en; +/*---------------------------------------------------------------------------*/ +grove_gyro_values_t gyro_values; +/*---------------------------------------------------------------------------*/ +void (*grove_gyro_int_callback)(uint8_t value); +/*---------------------------------------------------------------------------*/ +static uint16_t +grove_gyro_read_reg(uint8_t reg, uint8_t *buf, uint8_t num) +{ + if((buf == NULL) || (num <= 0)) { + return GROVE_GYRO_ERROR; + } + + i2c_master_enable(); + if(i2c_single_send(GROVE_GYRO_ADDR, reg) == I2C_MASTER_ERR_NONE) { + if(i2c_burst_receive(GROVE_GYRO_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { + return GROVE_GYRO_SUCCESS; + } + } + + PRINTF("Gyro: failed to read from sensor\n"); + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +grove_gyro_write_reg(uint8_t *buf, uint8_t num) +{ + if((buf == NULL) || (num <= 0)) { + PRINTF("Gyro: invalid write values\n"); + return GROVE_GYRO_ERROR; + } + + i2c_master_enable(); + if(i2c_burst_send(GROVE_GYRO_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { + return GROVE_GYRO_SUCCESS; + } + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +grove_gyro_sampdiv(uint8_t value) +{ + uint8_t buf[2]; + buf[0] = GROVE_GYRO_SMPLRT_DIV; + buf[1] = value; + if(grove_gyro_write_reg(buf, 2) == GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: new sampdiv 0x%02X\n", value); + return GROVE_GYRO_SUCCESS; + } + PRINTF("Gyro: failed to set sampdiv\n"); + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +grove_gyro_clear_interrupt(void) +{ + uint8_t aux = 0; + + /* Clear interrupt */ + grove_gyro_read_reg(GROVE_GYRO_INT_STATUS, &aux, 1); + + if(aux & GROVE_GYRO_INT_STATUS_DATA_RDY_MASK) { + return GROVE_GYRO_INT_STATUS_DATA_RDY_MASK; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +grove_gyro_interrupt(uint8_t value) +{ + uint8_t buf[2]; + buf[0] = GROVE_GYRO_INT_CFG; + buf[1] = value; + if(grove_gyro_write_reg(buf, 2) == GROVE_GYRO_SUCCESS){ + PRINTF("Gyro: interrupt cfg 0x%02X\n", value); + return GROVE_GYRO_SUCCESS; + } + PRINTF("Gyro: failed to change interrupt config\n"); + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +grove_gyro_reset(void) +{ + uint8_t buf[2]; + buf[0] = GROVE_GYRO_PWR_MGMT; + + /* Read the power management status as well to force sync */ + if(grove_gyro_read_reg(GROVE_GYRO_PWR_MGMT, &power_mgmt, 1) == + GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: current power mgmt 0x%02X\n", power_mgmt); + buf[1] = power_mgmt + GROVE_GYRO_PWR_MGMT_RESET; + if(grove_gyro_write_reg(buf, 2) == GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: restarted with 0x%02X, now with default values\n", buf[1]); + return GROVE_GYRO_SUCCESS; + } + } + PRINTF("Gyro: failed to restart\n"); + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +grove_gyro_osc(uint8_t value) +{ + uint8_t buf[2]; + buf[0] = GROVE_GYRO_PWR_MGMT; + + /* Read the power management status as well to force sync */ + if(grove_gyro_read_reg(GROVE_GYRO_PWR_MGMT, &power_mgmt, 1) == + GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: current power mgmt 0x%02X\n", power_mgmt); + power_mgmt &= ~GROVE_GYRO_PWR_MGMT_CLK_SEL_MASK; + buf[1] = power_mgmt + value; + if(grove_gyro_write_reg(buf, 2) == GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: new clock source 0x%02X\n", buf[1]); + return GROVE_GYRO_SUCCESS; + } + } + PRINTF("Gyro: failed to change the clock source\n"); + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +grove_gyro_power_mgmt(uint8_t value, uint8_t type) +{ + uint8_t buf[2]; + buf[0] = GROVE_GYRO_PWR_MGMT; + + if((type != GROVE_GYRO_POWER_ON) && (type != GROVE_GYRO_POWER_OFF)) { + PRINTF("Gyro: invalid power command type\n"); + return GROVE_GYRO_ERROR; + } + + /* Read the power management status as well to force sync */ + if(grove_gyro_read_reg(GROVE_GYRO_PWR_MGMT, &power_mgmt, 1) == + GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: current power mgmt 0x%02X\n", power_mgmt); + + if(type == GROVE_GYRO_POWER_ON) { + power_mgmt &= ~value; + } else { + power_mgmt |= value; + } + + buf[1] = power_mgmt; + if(grove_gyro_write_reg(buf, 2) == GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: new power management register value 0x%02X\n", power_mgmt); + + /* Power-up delay */ + if(type == GROVE_GYRO_POWER_ON) { + clock_delay_usec(25000); + } + + return GROVE_GYRO_SUCCESS; + } + } + PRINTF("Gyro: power management fail\n"); + + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +grove_gyro_dlpf(uint8_t value) +{ + uint8_t buf[2]; + buf[0] = GROVE_GYRO_DLPF_FS; + buf[1] = GROVE_GYRO_DLPF_FS_SEL + value; + + if(grove_gyro_write_reg(buf, 2) == GROVE_GYRO_SUCCESS) { + /* Double-check */ + if(grove_gyro_read_reg(GROVE_GYRO_DLPF_FS, &buf[0], 1) == + GROVE_GYRO_SUCCESS) { + if(buf[0] == buf[1]) { + PRINTF("Gyro: updated lp/sr 0x%02X\n", buf[0]); + return GROVE_GYRO_SUCCESS; + } else { + PRINTF("Gyro: DLPF register value mismatch\n"); + return GROVE_GYRO_ERROR; + } + } + } + + PRINTF("Gyro: failed to change the lp/sr\n"); + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +static uint16_t +grove_gyro_convert_to_value(uint16_t val) +{ + uint32_t aux; + + /* Convert from 2C's to 10's, as we care about º/s negative quantifier doesn't + * matter, so we ommit flaging the sign + */ + if(val & 0x8000) { + val = (~val + 1); + } + + /* ITG-3200 datasheet: sensitivity 14.375 LSB/(º/s) to get º/s */ + aux = val * 6956; + aux /= 1000; + + return (uint16_t)aux; +} +/*---------------------------------------------------------------------------*/ +static void +grove_gyro_convert(uint8_t *buf, uint8_t type) +{ + uint16_t aux; + + if(type & GROVE_GYRO_X) { + aux = (buf[0] << 8) + buf[1]; + PRINTF("Gyro: X_axis (raw) 0x%02X\n", aux); + gyro_values.x = grove_gyro_convert_to_value(aux); + } + + if(type & GROVE_GYRO_Y) { + aux = (buf[2] << 8) + buf[3]; + PRINTF("Gyro: Y_axis (raw) 0x%02X\n", aux); + gyro_values.y = grove_gyro_convert_to_value(aux); + } + + if(type & GROVE_GYRO_Z) { + aux = (buf[4] << 8) + buf[5]; + PRINTF("Gyro: Z_axis (raw) 0x%02X\n", aux); + gyro_values.z = grove_gyro_convert_to_value(aux); + } + + if(type == GROVE_GYRO_TEMP) { + aux = (buf[0] << 8) + buf[1]; + PRINTF("Gyro: Temp (raw) 0x%02X\n", aux); + /* ITG-3200 datasheet: offset -13200, sensitivity 280 LSB/ºC */ + aux = (aux + 13200) / 28; + aux += 350; + gyro_values.temp = (int16_t)aux; + } +} +/*---------------------------------------------------------------------------*/ +static int +grove_gyro_read(int type) +{ + uint8_t reg; + uint8_t len; + uint8_t buf_ptr; + uint8_t buf[GROVE_GYRO_MAX_DATA]; + + len = (type == GROVE_GYRO_XYZ) ? GROVE_GYRO_MAX_DATA : 2; + + switch(type) { + case GROVE_GYRO_X: + case GROVE_GYRO_XYZ: + buf_ptr = 0; + reg = GROVE_GYRO_XOUT_H; + break; + case GROVE_GYRO_Y: + buf_ptr = 2; + reg = GROVE_GYRO_YOUT_H; + break; + case GROVE_GYRO_Z: + buf_ptr = 4; + reg = GROVE_GYRO_ZOUT_H; + break; + case GROVE_GYRO_TEMP: + buf_ptr = 0; + reg = GROVE_GYRO_TEMP_OUT_H; + break; + case GROVE_GYRO_ADDR: + buf_ptr = 0; + len = 1; + reg = GROVE_GYRO_WHO_AM_I; + break; + default: + PRINTF("Gyro: invalid value requested\n"); + return GROVE_GYRO_ERROR; + } + + if(grove_gyro_read_reg(reg, &buf[buf_ptr], len) == GROVE_GYRO_SUCCESS) { + if(type == GROVE_GYRO_ADDR) { + PRINTF("Gyro: I2C_addr 0x%02X\n", buf[0]); + return buf[0]; + } + grove_gyro_convert(buf, type); + return GROVE_GYRO_SUCCESS; + } + + PRINTF("Gyro: failed to change the lp/sr\n"); + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +grove_gyro_calibrate(void) +{ + uint8_t i; + uint8_t buf[GROVE_GYRO_MAX_DATA]; + uint8_t power_mgmt_backup; + uint32_t x, y, z; + + /* Disable interrupts */ + if(int_en) { + if(grove_gyro_interrupt(GROVE_GYRO_INT_CFG_DISABLE) == GROVE_GYRO_ERROR) { + PRINTF("Gyro: failed to disable the interrupts\n"); + return GROVE_GYRO_ERROR; + } + GPIO_DISABLE_INTERRUPT(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + } + + /* Turn on the 3-axis, save the current config */ + if(grove_gyro_read_reg(GROVE_GYRO_PWR_MGMT, &power_mgmt_backup, 1) == + GROVE_GYRO_ERROR) { + PRINTF("Gyro: failed to read power mgmt config\n"); + return GROVE_GYRO_ERROR; + } + + if(grove_gyro_power_mgmt(GROVE_GYRO_ALL, GROVE_GYRO_POWER_ON) == + GROVE_GYRO_ERROR) { + PRINTF("Gyro: failed to bring sensor up\n"); + return GROVE_GYRO_ERROR; + } + + x = 0; + y = 0; + z = 0; + + for (i = 0; i < GROVE_GYRO_CALIB_SAMPLES; i++){ + clock_delay_usec(GROVE_GYRO_CALIB_TIME_US); + watchdog_periodic(); + if(grove_gyro_read_reg(GROVE_GYRO_XOUT_H, buf, GROVE_GYRO_MAX_DATA) == + GROVE_GYRO_SUCCESS) { + x += (buf[0] << 8) + buf[1]; + y += (buf[2] << 8) + buf[3]; + z += (buf[4] << 8) + buf[5]; + } + } + + gyro_values.x_offset = ABS(x)/GROVE_GYRO_CALIB_SAMPLES; + gyro_values.y_offset = ABS(y)/GROVE_GYRO_CALIB_SAMPLES; + gyro_values.z_offset = ABS(z)/GROVE_GYRO_CALIB_SAMPLES; + + PRINTF("Gyro: x_offset (RAW) 0x%02X\n", gyro_values.x_offset); + PRINTF("Gyro: y_offset (RAW) 0x%02X\n", gyro_values.y_offset); + PRINTF("Gyro: z_offset (RAW) 0x%02X\n", gyro_values.z_offset); + + gyro_values.x_offset = grove_gyro_convert_to_value(gyro_values.x_offset); + gyro_values.y_offset = grove_gyro_convert_to_value(gyro_values.y_offset); + gyro_values.z_offset = grove_gyro_convert_to_value(gyro_values.z_offset); + + PRINTF("Gyro: x_offset (converted) %d\n", gyro_values.x_offset); + PRINTF("Gyro: y_offset (converted) %d\n", gyro_values.y_offset); + PRINTF("Gyro: z_offset (converted) %d\n", gyro_values.z_offset); + + /* Cleaning up */ + buf[0] = GROVE_GYRO_PWR_MGMT; + buf[1] = power_mgmt_backup; + + if(grove_gyro_write_reg(&buf[0], 2) != GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: failed restoring power mgmt (0x%02X)\n", power_mgmt_backup); + return GROVE_GYRO_ERROR; + } + + if(int_en) { + if(grove_gyro_interrupt(GROVE_GYRO_INT_CFG_RAW_READY_EN + + GROVE_GYRO_INT_CFG_LATCH_EN) == GROVE_GYRO_ERROR) { + PRINTF("Gyro: failed to enable the interrupt\n"); + return GROVE_GYRO_ERROR; + } + + GPIO_ENABLE_INTERRUPT(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + } + + return GROVE_GYRO_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +PROCESS(grove_gyro_int_process, "Grove gyroscope interrupt process handler"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(grove_gyro_int_process, ev, data) +{ + PROCESS_EXITHANDLER(); + PROCESS_BEGIN(); + + static uint8_t axis_to_read = 0; + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + if(grove_gyro_clear_interrupt() == GROVE_GYRO_INT_STATUS_DATA_RDY_MASK) { + + axis_to_read += (power_mgmt & GROVE_GYRO_X) ? 0: GROVE_GYRO_X; + axis_to_read += (power_mgmt & GROVE_GYRO_Y) ? 0: GROVE_GYRO_Y; + axis_to_read += (power_mgmt & GROVE_GYRO_Z) ? 0: GROVE_GYRO_Z; + + if(grove_gyro_read(axis_to_read) == GROVE_GYRO_SUCCESS) { + grove_gyro_int_callback(GROVE_GYRO_SUCCESS); + } + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +static void +grove_gyro_interrupt_handler(uint8_t port, uint8_t pin) +{ + process_poll(&grove_gyro_int_process); +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if(!enabled) { + PRINTF("Gyro: sensor not started\n"); + return GROVE_GYRO_ERROR; + } + + if((type != GROVE_GYRO_X) && (type != GROVE_GYRO_Y) && + (type != GROVE_GYRO_Z) && (type != GROVE_GYRO_XYZ) && + (type != GROVE_GYRO_TEMP) && (type != GROVE_GYRO_ADDR)) { + PRINTF("Gyro: invalid value requested 0x%02X\n", type); + return GROVE_GYRO_ERROR; + } + + if((type != GROVE_GYRO_TEMP) && (type != GROVE_GYRO_ADDR) && + (type & power_mgmt)) { + PRINTF("Gyro: axis not enabled (0x%02X vs 0x%02X)\n", power_mgmt, type); + return GROVE_GYRO_ERROR; + } + + return grove_gyro_read(type); +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if((type != GROVE_GYRO_ACTIVE) && (type != GROVE_GYRO_SAMPLE_RATE) && + (type != GROVE_GYRO_SAMPLE_RATE_DIVIDER) && (type != GROVE_GYRO_POWER_ON) && + (type != GROVE_GYRO_POWER_OFF) && (type != GROVE_GYRO_DATA_INTERRUPT) && + (type != GROVE_GYRO_CALIBRATE_ZERO)) { + PRINTF("Gyro: option not supported\n"); + return GROVE_GYRO_ERROR; + } + + switch(type) { + case GROVE_GYRO_ACTIVE: + if(value) { + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_FAST_BUS_SPEED); + + /* Initialize the data structure values */ + gyro_values.x = 0; + gyro_values.y = 0; + gyro_values.z = 0; + gyro_values.temp = 0; + gyro_values.x_offset = 0; + gyro_values.y_offset = 0; + gyro_values.z_offset = 0; + + /* Make sure the sensor is on */ + if(grove_gyro_power_mgmt(GROVE_GYRO_ALL, GROVE_GYRO_POWER_ON) != + GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: failed to power on the sensor\n"); + return GROVE_GYRO_ERROR; + } + + /* Reset and configure as default with internal oscillator, 8KHz @ 2000 + * degrees/s, no divider (full scale) + */ + if(grove_gyro_reset() == GROVE_GYRO_SUCCESS) { + if(grove_gyro_osc(GROVE_GYRO_DEFAULT_OSC) == GROVE_GYRO_SUCCESS) { + if(grove_gyro_dlpf(GROVE_GYRO_DLPF_FS_CGF_8KHZ_LP256HZ) == + GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: started and configured\n"); + /* Disable interrupts as default */ + if(grove_gyro_interrupt(GROVE_GYRO_INT_CFG_DISABLE) == + GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: interrupts disabled\n"); + /* And finally put the device in SLEEP mode, set also X, Y and Z + * in stand-by mode, whenever an axis is not used it should stay + * in this state to save power + */ + if(grove_gyro_power_mgmt(GROVE_GYRO_ALL, GROVE_GYRO_POWER_OFF) == + GROVE_GYRO_SUCCESS) { + enabled = 1; + PRINTF("Gyro: axis and gyroscope in low-power mode now\n"); + + return GROVE_GYRO_SUCCESS; + } + } + } + } + } + return GROVE_GYRO_ERROR; + + } else { + enabled = 0; + int_en = 0; + GPIO_DISABLE_INTERRUPT(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + grove_gyro_int_callback = NULL; + if(grove_gyro_interrupt(GROVE_GYRO_INT_CFG_DISABLE) == + GROVE_GYRO_SUCCESS) { + return grove_gyro_power_mgmt(GROVE_GYRO_ALL, GROVE_GYRO_POWER_OFF); + } + PRINTF("Gyro: hw interrupt disabled but failed to disable sensor\n"); + return GROVE_GYRO_ERROR; + } + + if(!enabled) { + PRINTF("Gyro: sensor not started\n"); + return GROVE_GYRO_ERROR; + } + + case GROVE_GYRO_DATA_INTERRUPT: + + if(!value) { + + /* Ensure the GPIO doesn't generate more interrupts, this may affect others + * I2C digital sensors using the bus and sharing this pin, so an user may + * comment the line below + */ + int_en = 0; + GPIO_DISABLE_INTERRUPT(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + return grove_gyro_interrupt(GROVE_GYRO_INT_CFG_DISABLE); + } + + /* Enable interrupt and latch the pin until cleared */ + if(grove_gyro_interrupt(GROVE_GYRO_INT_CFG_RAW_READY_EN + + GROVE_GYRO_INT_CFG_LATCH_EN) == GROVE_GYRO_ERROR) { + PRINTF("Gyro: failed to enable the interrupt\n"); + return GROVE_GYRO_ERROR; + } + + /* Default register configuration is active high, push-pull */ + GPIO_SOFTWARE_CONTROL(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + GPIO_SET_INPUT(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + GPIO_DETECT_EDGE(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + GPIO_TRIGGER_SINGLE_EDGE(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + GPIO_DETECT_FALLING(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + gpio_register_callback(grove_gyro_interrupt_handler, I2C_INT_PORT, + I2C_INT_PIN); + + /* Spin process until an interrupt is received */ + process_start(&grove_gyro_int_process, NULL); + + /* Enable interrupts */ + int_en = 1; + GPIO_ENABLE_INTERRUPT(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + ioc_set_over(I2C_INT_PORT, I2C_INT_PIN, IOC_OVERRIDE_PUE); + nvic_interrupt_enable(I2C_INT_VECTOR); + + PRINTF("Gyro: Data interrupt configured\n"); + return GROVE_GYRO_SUCCESS; + + case GROVE_GYRO_SAMPLE_RATE: + if((value < GROVE_GYRO_DLPF_FS_CGF_8KHZ_LP256HZ) || + (value > GROVE_GYRO_DLPF_FS_CGF_1KHZ_LP5HZ)) { + PRINTF("Gyro: invalid sample rate/filter configuration\n"); + return GROVE_GYRO_ERROR; + } + return grove_gyro_dlpf(value); + + case GROVE_GYRO_SAMPLE_RATE_DIVIDER: + if((value < 0) && (value > 0xFF)) { + PRINTF("Gyro: invalid sampling rate div, it must be an 8-bit value\n"); + return GROVE_GYRO_ERROR; + } + return grove_gyro_sampdiv((uint8_t)value); + + case GROVE_GYRO_POWER_ON: + case GROVE_GYRO_POWER_OFF: + /* We accept mask values to enable more than one axis at the same time */ + if((value < GROVE_GYRO_Z) || (value > GROVE_GYRO_ALL)) { + PRINTF("Gyro: invalid power management setting\n"); + return GROVE_GYRO_ERROR; + } + return grove_gyro_power_mgmt(value, type); + + case GROVE_GYRO_CALIBRATE_ZERO: + return grove_gyro_calibrate(); + + default: + return GROVE_GYRO_ERROR; + } + + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(grove_gyro, GROVE_GYRO_STRING, value, configure, NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/grove-gyro.h b/platform/zoul/dev/grove-gyro.h new file mode 100644 index 000000000..8ab84ba7e --- /dev/null +++ b/platform/zoul/dev/grove-gyro.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-grove-gyro-sensor Grove 3-axis gyroscope based on ITG-3200 + * @{ + * + * \file + * Grove 3-axis gyroscope header file + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/* -------------------------------------------------------------------------- */ +#ifndef GROVE_GYRO_H_ +#define GROVE_GYRO_H_ +/* -------------------------------------------------------------------------- */ +/** + * \name Callback function to handle the interrupt + * @{ + */ +#define GROVE_GYRO_REGISTER_INT(ptr) grove_gyro_int_callback = ptr; +extern void (*grove_gyro_int_callback)(uint8_t value); +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Gyroscope data values structure + * @{ + */ +typedef struct { + uint16_t x; + uint16_t y; + uint16_t z; + uint16_t x_offset; + uint16_t y_offset; + uint16_t z_offset; + int16_t temp; +} grove_gyro_values_t; + +extern grove_gyro_values_t gyro_values; +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Grove 3-axis gyroscope address and registers + * @{ + */ +#define GROVE_GYRO_ADDR 0x68 + +#define GROVE_GYRO_WHO_AM_I 0x00 +#define GROVE_GYRO_SMPLRT_DIV 0x15 +#define GROVE_GYRO_DLPF_FS 0x16 +#define GROVE_GYRO_INT_CFG 0x17 +#define GROVE_GYRO_INT_STATUS 0x1A +#define GROVE_GYRO_TEMP_OUT_H 0x1B +#define GROVE_GYRO_TEMP_OUT_L 0x1C +#define GROVE_GYRO_XOUT_H 0x1D +#define GROVE_GYRO_XOUT_L 0x1E +#define GROVE_GYRO_YOUT_H 0x1F +#define GROVE_GYRO_YOUT_L 0x20 +#define GROVE_GYRO_ZOUT_H 0x21 +#define GROVE_GYRO_ZOUT_L 0x22 +#define GROVE_GYRO_PWR_MGMT 0x3E +/** @} */ +/*--------------------------------------------------------------------------*/ +/** + * \name Grove 3-axis gyroscope bitmasks and config + * @{ + */ +#define GROVE_GYRO_DLPF_FS_SEL 0x18 +#define GROVE_GYRO_DLPF_FS_CGF_8KHZ_LP256HZ 0x00 +#define GROVE_GYRO_DLPF_FS_CGF_1KHZ_LP188HZ 0x01 +#define GROVE_GYRO_DLPF_FS_CGF_1KHZ_LP98HZ 0x02 +#define GROVE_GYRO_DLPF_FS_CGF_1KHZ_LP42HZ 0x03 +#define GROVE_GYRO_DLPF_FS_CGF_1KHZ_LP20HZ 0x04 +#define GROVE_GYRO_DLPF_FS_CGF_1KHZ_LP10HZ 0x05 +#define GROVE_GYRO_DLPF_FS_CGF_1KHZ_LP5HZ 0x06 + +#define GROVE_GYRO_INT_CFG_RAW_READY_EN 0x01 +#define GROVE_GYRO_INT_CFG_READY_EN 0x04 +#define GROVE_GYRO_INT_CFG_LATCH_CLR_ANY 0x10 +#define GROVE_GYRO_INT_CFG_LATCH_EN 0x20 +#define GROVE_GYRO_INT_CFG_PIN_OPEN 0x40 +#define GROVE_GYRO_INT_CFG_PIN_ACTL 0x80 +#define GROVE_GYRO_INT_CFG_DISABLE 0x00 + +#define GROVE_GYRO_INT_STATUS_DATA_RDY_MASK 0x01 +#define GROVE_GYRO_INT_STATUS_PLL_RDY_MASK 0x04 + +#define GROVE_GYRO_PWR_MGMT_CLK_SEL_INTOSC 0x00 +#define GROVE_GYRO_PWR_MGMT_CLK_SEL_PLL_X 0x01 +#define GROVE_GYRO_PWR_MGMT_CLK_SEL_PLL_Y 0x02 +#define GROVE_GYRO_PWR_MGMT_CLK_SEL_PLL_Z 0x03 +#define GROVE_GYRO_PWR_MGMT_CLK_SEL_EXT_32K 0x04 +#define GROVE_GYRO_PWR_MGMT_CLK_SEL_EXT_19K 0x05 +#define GROVE_GYRO_PWR_MGMT_STBY_ZG 0x08 +#define GROVE_GYRO_PWR_MGMT_STBY_YG 0x10 +#define GROVE_GYRO_PWR_MGMT_STBY_XG 0x20 +#define GROVE_GYRO_PWR_MGMT_SLEEP 0x40 +#define GROVE_GYRO_PWR_MGMT_RESET 0x80 + +#ifdef GROVE_GYRO_CONF_OSC +#define GROVE_GYRO_DEFAULT_OSC GROVE_GYRO_CONF_OSC +#else +#define GROVE_GYRO_DEFAULT_OSC GROVE_GYRO_PWR_MGMT_CLK_SEL_INTOSC +#endif + +#define GROVE_GYRO_PWR_MGMT_CLK_SEL_MASK 0x07 +#define GROVE_GYRO_MAX_DATA 0x06 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Grove 3-axis gyroscope operation values + * @{ + */ +/* Configure request type */ +#define GROVE_GYRO_ACTIVE SENSORS_ACTIVE +#define GROVE_GYRO_DATA_INTERRUPT 0x01 +#define GROVE_GYRO_SAMPLE_RATE 0x02 +#define GROVE_GYRO_SAMPLE_RATE_DIVIDER 0x03 +#define GROVE_GYRO_POWER_ON 0x04 +#define GROVE_GYRO_POWER_OFF 0x05 +#define GROVE_GYRO_CALIBRATE_ZERO 0x06 + +/* Sensor value request type, match to the stand-by mask to check if enabled */ +#define GROVE_GYRO_X GROVE_GYRO_PWR_MGMT_STBY_XG +#define GROVE_GYRO_Y GROVE_GYRO_PWR_MGMT_STBY_YG +#define GROVE_GYRO_Z GROVE_GYRO_PWR_MGMT_STBY_ZG +#define GROVE_GYRO_SENSOR GROVE_GYRO_PWR_MGMT_SLEEP +#define GROVE_GYRO_XYZ (GROVE_GYRO_X + GROVE_GYRO_Y + \ + GROVE_GYRO_Z) +#define GROVE_GYRO_ALL (GROVE_GYRO_XYZ + GROVE_GYRO_SENSOR) +#define GROVE_GYRO_TEMP 0x06 + +/* Return types */ +#define GROVE_GYRO_ERROR (-1) +#define GROVE_GYRO_SUCCESS 0x00 + +/* Calibration constants */ +#define GROVE_GYRO_CALIB_SAMPLES 200 +#define GROVE_GYRO_CALIB_TIME_US 5000 +/** @} */ +/* -------------------------------------------------------------------------- */ +#define GROVE_GYRO_STRING "Grove 3-axis gyroscope Sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor grove_gyro; +/* -------------------------------------------------------------------------- */ +#endif /* ifndef GROVE_GYRO_H_ */ +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/iaq.c b/platform/zoul/dev/iaq.c new file mode 100644 index 000000000..7bc929a26 --- /dev/null +++ b/platform/zoul/dev/iaq.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-iaq-sensor + * @{ + * Driver for the RE-Mote IAQ iAQ-Core (Indoor Air Quality Sensor) + * \file + * Driver for the RE-Mote RF IAQ iAQ-Core sensor (IAQ) + * \author + * Aitor Mejias + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/gpio.h" +#include "dev/i2c.h" +#include "iaq.h" +#include "sys/timer.h" +#include "sys/etimer.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +/* Callback pointers when interrupt occurs */ +void (*iaq_enable_callback)(uint16_t value); +/*---------------------------------------------------------------------------*/ +static int16_t enabled; +/*---------------------------------------------------------------------------*/ +static struct etimer et; +static simple_iaq_data iaq_data; +static uint8_t iaq_buffer[IAQ_FRAME_SIZE+1]; +/*---------------------------------------------------------------------------*/ +PROCESS(iaq_process, "IAQ process handler"); +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ +/* Return the status of the iAQ-Core or the status of the driver */ + if (type == IAQ_STATUS) { + return (uint16_t)iaq_data.status; + } else if (type == IAQ_DRIVER_STATUS) { + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(iaq_process, ev, data) +{ + #if DEBUG + uint8_t i = 0; + #endif + + PROCESS_EXITHANDLER(); + PROCESS_BEGIN(); + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_NORMAL_BUS_SPEED); + + while(1) { + etimer_set(&et, (IAQ_POLLING_TIME)); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + i2c_master_enable(); + if(i2c_burst_receive(IAQ_ADDR, &iaq_buffer[0], IAQ_FRAME_SIZE) != + I2C_MASTER_ERR_NONE) { + PRINTF("IAQ: Failed to retrieve data from IAQ\n"); + enabled = IAQ_ERROR; + iaq_data.status = IAQ_INTERNAL_ERROR; + } else { + #if DEBUG + PRINTF("IAQ: Buffer "); + for (i=1;i<10;i++) { + PRINTF("[%d] %x, ", i-1, iaq_buffer[i-1]); + } + PRINTF("\n"); + #endif + /* Update the status of the sensor. This value readed represents the + internal status of the external driver. */ + switch (iaq_buffer[2]) { + case IAQ_INTERNAL_SUCCESS: + enabled = IAQ_ACTIVE; + break; + case IAQ_INTERNAL_RUNIN: + enabled = IAQ_INIT_STATE; + break; + case IAQ_INTERNAL_BUSY: + case IAQ_INTERNAL_ERROR: + enabled = IAQ_ERROR; + break; + default: + enabled = IAQ_ERROR; + break; + } + + iaq_data.tvoc = ((uint16_t)iaq_buffer[0] << 8) + iaq_buffer[1]; + iaq_data.co2 = ((uint16_t)iaq_buffer[7] << 8) + iaq_buffer[8]; + iaq_data.status = iaq_buffer[2]; + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if (!enabled) { + PRINTF("IAQ: Sensor not enabled\n"); + return IAQ_ERROR; + } + if (enabled == IAQ_INIT_STATE) { + PRINTF("IAQ: Sensor initializing\n"); + return IAQ_INIT_STATE; + } + if (type == IAQ_CO2_VALUE) { + return iaq_data.co2; + } + if (type == IAQ_VOC_VALUE) { + return iaq_data.tvoc; + } + if (type == IAQ_STATUS) { + #if DEBUG + switch (iaq_data.status) { + case IAQ_INTERNAL_SUCCESS: + PRINTF("IAQ Status: SUCCESS\n"); + break; + case IAQ_INTERNAL_RUNIN: + PRINTF("IAQ Status: WARM UP\n"); + break; + case IAQ_INTERNAL_BUSY: + case IAQ_INTERNAL_ERROR: + PRINTF("IAQ Status: ERROR\n"); + break; + default: + PRINTF("IAQ Status: UNKNOWN STATUS %d\n", iaq_data.status); + break; + } + #endif + return iaq_data.status; + } + + return IAQ_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + /* Check the current status. If is initialized or is active, return the same + state */ + if ((enabled == IAQ_INIT_STATE) || (enabled == IAQ_ACTIVE)) { + return IAQ_ERROR; + } + + /* Fix the status in initial wait status */ + enabled = IAQ_INIT_STATE; + + /* Start Internal process to measure the iAQ Sensor */ + process_start(&iaq_process, NULL); + + return enabled; +} +/*---------------------------------------------------------------------------*/ +/* name, type, value, configure, status */ +SENSORS_SENSOR(iaq, IAQ_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** + * @} + */ + diff --git a/platform/zoul/dev/iaq.h b/platform/zoul/dev/iaq.h new file mode 100644 index 000000000..92562dfd7 --- /dev/null +++ b/platform/zoul/dev/iaq.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/* -------------------------------------------------------------------------- */ +/** + * \addtogroup zoul-sensors + * @{ + * \defgroup zoul-iaq-sensor IAQ driver (Indoor Air Quality) Sensor Module + * IAQ driver RE-Mote Indoor Air Quality Sensor Module + * Driver for the RE-Mote Sensor pack: Air Quality Sensor Module (IAQ) + * @{ + * \file + * Header file for the RE-Mote Sensor IAQ + */ +/* -------------------------------------------------------------------------- */ +#ifndef IAQ_H_ +#define IAQ_H_ +/* -------------------------------------------------------------------------- */ +#include +#include "lib/sensors.h" +#include "dev/zoul-sensors.h" +#include "iaq.h" +#include "i2c.h" +#include "sys/timer.h" +#include "sys/rtimer.h" +/* -------------------------------------------------------------------------- */ +/** \name IAQ address and definition + * @{ + */ +/* Address of the sensor: 1011010(1) Addr (R/W bit) */ +#define IAQ_ADDR 0x5A +#define IAQ_SENSOR "iAQ" +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name IAQ sensor types in iAQ-Core module + * @{ + */ +extern const struct sensors_sensor iaq; +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name IAQ error values and definitions + * @{ + */ +#define IAQ_ACTIVE SENSORS_ACTIVE +#define IAQ_INIT_STATE SENSORS_HW_INIT +#define IAQ_ERROR (-1) +#define IAQ_SUCCESS 0x00 +#define IAQ_FRAME_SIZE 0x09 + +/* Variables used by external driver to get the state */ +#define IAQ_INTERNAL_SUCCESS 0x00 +#define IAQ_INTERNAL_RUNIN 0x10 +#define IAQ_INTERNAL_BUSY 0x01 +#define IAQ_INTERNAL_ERROR 0x80 + +/* Value types for the sensor readings */ +#define IAQ_CO2_VALUE 0x00 +#define IAQ_VOC_VALUE 0x01 +#define IAQ_STATUS 0x02 +#define IAQ_DRIVER_STATUS 0x03 + +/* Definition that corresponds with the two models of iAQ Sensor */ +#ifdef IAQ_PULSE_MODE +#define IAQ_POLLING_TIME (CLOCK_SECOND * 11) +#else +#define IAQ_POLLING_TIME (CLOCK_SECOND) +#endif +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name IAQ enumeration and options + * @{ + */ +enum { + IAQ_INIT = 0, + IAQ_STARTED, +}; +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name Readable IAQ-Core interface result conversion implementation as + * datasheet specification. + * + * @{ + */ +typedef struct iaq_struct_simple_td_reg { + uint16_t co2; + uint8_t status; + int32_t resistance; + uint16_t tvoc; +} __attribute__ ((packed)) simple_iaq_data; +/** @} */ +/* -------------------------------------------------------------------------- */ +#endif +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/led-strip.c b/platform/zoul/dev/led-strip.c new file mode 100644 index 000000000..fa64aa91c --- /dev/null +++ b/platform/zoul/dev/led-strip.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-led-strip + * @{ + * + * Driver to control a bright LED strip powered at 3VDC, drawing power directly + * from the battery power supply. An example on how to adapt 12VDC LED strips + * to 3VDC is provided at http://www.hackster.io/zolertia + * @{ + * + * \file + * Driver for a bright LED strip + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/gpio.h" +#include "led-strip.h" + +#include +/*---------------------------------------------------------------------------*/ +#ifndef LED_STRIP_PORT +#define LED_STRIP_PORT GPIO_A_NUM +#endif +#ifndef LED_STRIP_PIN +#define LED_STRIP_PIN 6 +#endif +#define LED_STRIP_PORT_BASE GPIO_PORT_TO_BASE(LED_STRIP_PORT) +#define LED_STRIP_PIN_MASK GPIO_PIN_MASK(LED_STRIP_PIN) +/*---------------------------------------------------------------------------*/ +static uint8_t initialized = 0; +/*---------------------------------------------------------------------------*/ +void +led_strip_config(void) +{ + /* Software controlled */ + GPIO_SOFTWARE_CONTROL(LED_STRIP_PORT_BASE, LED_STRIP_PIN_MASK); + /* Set pin to output */ + GPIO_SET_OUTPUT(LED_STRIP_PORT_BASE, LED_STRIP_PIN_MASK); + /* Set the pin to a default position */ + GPIO_SET_PIN(LED_STRIP_PORT_BASE, LED_STRIP_PIN_MASK); + + initialized = 1; +} +/*---------------------------------------------------------------------------*/ +int +led_strip_switch(uint8_t val) +{ + if(!initialized) { + return LED_STRIP_ERROR; + } + + if(val != LED_STRIP_ON && val != LED_STRIP_OFF) { + return LED_STRIP_ERROR; + } + + /* Set the LED to ON or OFF */ + GPIO_WRITE_PIN(LED_STRIP_PORT_BASE, LED_STRIP_PIN_MASK, val); + + return val; +} +/*---------------------------------------------------------------------------*/ +int +led_strip_get(void) +{ + if(!initialized) { + return LED_STRIP_ERROR; + } + + /* Inverse logic, return ON if the pin is low */ + if(GPIO_READ_PIN(LED_STRIP_PORT_BASE, LED_STRIP_PIN_MASK)) { + return LED_STRIP_OFF; + } + return LED_STRIP_ON; +} +/*---------------------------------------------------------------------------*/ + +/** + * @} + * @} + */ + diff --git a/platform/zoul/dev/led-strip.h b/platform/zoul/dev/led-strip.h new file mode 100644 index 000000000..623180789 --- /dev/null +++ b/platform/zoul/dev/led-strip.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ +/* -------------------------------------------------------------------------- */ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-led-strip LED strip compatible with Zoul-based platforms + * + * Driver to control a bright LED strip powered at 3VDC, drawing power directly + * from the battery power supply. An example on how to adapt 12VDC LED strips + * to 3VDC is provided at http://www.hackster.io/zolertia + * @{ + * + * \file + * Header file for a bright LED strip driver + */ +/* -------------------------------------------------------------------------- */ +#ifndef LED_STRIP_H_ +#define LED_STRIP_H_ +/* -------------------------------------------------------------------------- */ +#include +/* -------------------------------------------------------------------------- */ +#define LED_STRIP_OFF 0xFF +#define LED_STRIP_ON 0x00 + +#define LED_STRIP_ERROR -1 +/* -------------------------------------------------------------------------- */ +/** + * \brief Init function for the bright LED strip driver + * + * The LED strip driver allows to lighten up any application using up to 4 + * LEDs 3VDC-powered per strip + * The function is set to power OFF the LEDs as default, + * it should be called from the contiki-main initialization process. + * + * \return ignored + */ +void led_strip_config(void); + +/** + * \brief Function to turn ON/OFF the LED strip + * + * \param val Set ON/OFF (LED_STRIP_ON or LED_STRIP_OFF) + * \return the selected antenna position, or LED_STRIP_ERROR if not + * previously configured + */ +int led_strip_switch(uint8_t val); + +/** + * \brief Function to get the LED strip current state + * + * \return Current LED strip state or LED_STRIP_ERROR if not + * previously configured + */ +int led_strip_get(void); +/* -------------------------------------------------------------------------- */ +#endif /* ifndef LED_STRIP_H_ */ +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ + diff --git a/platform/zoul/dev/leds-arch.c b/platform/zoul/dev/leds-arch.c new file mode 100644 index 000000000..f09ed645c --- /dev/null +++ b/platform/zoul/dev/leds-arch.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup zoul + * @{ + * + * \defgroup zoul-leds Zoul LED driver + * + * LED driver implementation for the Zoul-based platforms + * @{ + * + * \file + * LED driver implementation for the Zoul-based platforms + */ +#include "contiki.h" +#include "reg.h" +#include "dev/leds.h" +#include "dev/gpio.h" +/*---------------------------------------------------------------------------*/ +#define LEDS_GPIO_PIN_MASK LEDS_ALL +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + GPIO_SET_OUTPUT(GPIO_D_BASE, LEDS_GPIO_PIN_MASK); +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + return GPIO_READ_PIN(GPIO_D_BASE, LEDS_GPIO_PIN_MASK); +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char leds) +{ + GPIO_WRITE_PIN(GPIO_D_BASE, LEDS_GPIO_PIN_MASK, leds); +} +/*---------------------------------------------------------------------------*/ + +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/motion-sensor.c b/platform/zoul/dev/motion-sensor.c new file mode 100644 index 000000000..178267edf --- /dev/null +++ b/platform/zoul/dev/motion-sensor.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-motion-sensor + * @{ + * + * \file + * Digital motion sensor driver + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/i2c.h" +#include "dev/motion-sensor.h" +#include "lib/sensors.h" +#include "dev/sys-ctrl.h" +#include "dev/gpio.h" +#include "dev/ioc.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +#define MOTION_SENSOR_PORT_BASE GPIO_PORT_TO_BASE(MOTION_SENSOR_PORT) +#define MOTION_SENSOR_PIN_MASK GPIO_PIN_MASK(MOTION_SENSOR_PIN) +/*---------------------------------------------------------------------------*/ +void (*presence_int_callback)(uint8_t value); +/*---------------------------------------------------------------------------*/ +PROCESS(motion_int_process, "Motion interrupt process handler"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(motion_int_process, ev, data) +{ + PROCESS_EXITHANDLER(); + PROCESS_BEGIN(); + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + presence_int_callback(0); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +static void +motion_interrupt_handler(uint8_t port, uint8_t pin) +{ + process_poll(&motion_int_process); +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return MOTION_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return GPIO_READ_PIN(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != MOTION_ACTIVE) { + PRINTF("Motion: invalid configuration option\n"); + return MOTION_ERROR; + } + + if(!value) { + presence_int_callback = NULL; + GPIO_DISABLE_INTERRUPT(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); + return MOTION_SUCCESS; + } + + /* Configure interruption */ + GPIO_SOFTWARE_CONTROL(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); + GPIO_SET_INPUT(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); + GPIO_DETECT_RISING(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); + GPIO_TRIGGER_SINGLE_EDGE(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); + ioc_set_over(MOTION_SENSOR_PORT, MOTION_SENSOR_PIN, IOC_OVERRIDE_DIS); + gpio_register_callback(motion_interrupt_handler, MOTION_SENSOR_PORT, + MOTION_SENSOR_PIN); + + process_start(&motion_int_process, NULL); + + GPIO_ENABLE_INTERRUPT(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); + nvic_interrupt_enable(MOTION_SENSOR_VECTOR); + return MOTION_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(motion_sensor, MOTION_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/motion-sensor.h b/platform/zoul/dev/motion-sensor.h new file mode 100644 index 000000000..c52597a24 --- /dev/null +++ b/platform/zoul/dev/motion-sensor.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-motion-sensor Digital motion sensor + * @{ + * + * \file + * Digital motion sensor header file + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/* -------------------------------------------------------------------------- */ +#ifndef MOTION_SENSOR_H_ +#define MOTION_SENSOR_H_ +/* -------------------------------------------------------------------------- */ +/** + * \name Motion sensor return and operation values + * @{ + */ +#define MOTION_ACTIVE SENSORS_ACTIVE +#define MOTION_SUCCESS 0 +#define MOTION_ERROR (-1) +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Motion sensor interrupt callback macro + * @{ + */ +#define MOTION_REGISTER_INT(ptr) presence_int_callback = ptr; +extern void (*presence_int_callback)(uint8_t value); +/** @} */ +/* -------------------------------------------------------------------------- */ +#define MOTION_SENSOR "Digital motion sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor motion_sensor; +/* -------------------------------------------------------------------------- */ +#endif /* ifndef MOTION_SENSOR_H_ */ +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/mp3-wtv020sd.c b/platform/zoul/dev/mp3-wtv020sd.c new file mode 100644 index 000000000..7633d05e3 --- /dev/null +++ b/platform/zoul/dev/mp3-wtv020sd.c @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-mp3-wtv020sd + * @{ + * + * Driver to control the MP3 WTV020SD board in MP3 mode (GPIO based) and the + * 2-line serial mode (CLK/DI). Loop Mode and Key Modes not implemented. + * More product information available at: + * http://avrproject.ru/chasy-budilnik/WTV020SD.pdf + * An example on how to wire with a sound power amplifier and speakers at + * http://www.hackster.io/zolertia + * @{ + * + * \file + * Header file for the MP3 WTV020SD driver + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/gpio.h" +#include "mp3-wtv020sd.h" + +#include +/*---------------------------------------------------------------------------*/ + +/* + * The WTV020SD can be used in MP3 mode (GPIO-controlled) or 2-line mode (CLK + * and DATA line). The following pin-out can be implemented without reusing + * the pins as below (in 2-line mode the CLK/DATA functions replace the VOL+/- + * keys, others remain the same), but this would require more GPIOs to + * interface all functions, so we chose the configuration that uses the less + * number of GPIOs, and emulate all functions available in each mode + */ +#ifndef MP3_WTV020SD_P07_PORT +#define MP3_WTV020SD_P07_PORT GPIO_B_NUM +#endif +#ifndef MP3_WTV020SD_P07_PIN +#define MP3_WTV020SD_P07_PIN 0 +#endif +#ifndef MP3_WTV020SD_P02_PORT +#define MP3_WTV020SD_P02_PORT GPIO_B_NUM +#endif +#ifndef MP3_WTV020SD_P02_PIN +#define MP3_WTV020SD_P02_PIN 1 +#endif +#ifndef MP3_WTV020SD_P06_PORT +#define MP3_WTV020SD_P06_PORT GPIO_C_NUM +#endif +#ifndef MP3_WTV020SD_P06_PIN +#define MP3_WTV020SD_P06_PIN 1 +#endif +#ifndef MP3_WTV020SD_P04_PORT +#define MP3_WTV020SD_P04_PORT GPIO_B_NUM +#endif +#ifndef MP3_WTV020SD_P04_PIN +#define MP3_WTV020SD_P04_PIN 0 +#endif +#ifndef MP3_WTV020SD_P05_PORT +#define MP3_WTV020SD_P05_PORT GPIO_B_NUM +#endif +#ifndef MP3_WTV020SD_P05_PIN +#define MP3_WTV020SD_P05_PIN 1 +#endif +#ifndef MP3_WTV020SD_RESET_PORT +#define MP3_WTV020SD_RESET_PORT GPIO_B_NUM +#endif +#ifndef MP3_WTV020SD_RESET_PIN +#define MP3_WTV020SD_RESET_PIN 1 +#endif + +/* The BUSY pin is shared between operation modes */ +#define MP3_BUSY_PORT_BASE GPIO_PORT_TO_BASE(MP3_WTV020SD_P06_PORT) +#define MP3_BUSY_PIN_MASK GPIO_PIN_MASK(MP3_WTV020SD_P06_PIN) + +#define MP3_PLAY_PORT_BASE GPIO_PORT_TO_BASE(MP3_WTV020SD_P07_PORT) +#define MP3_PLAY_PIN_MASK GPIO_PIN_MASK(MP3_WTV020SD_P07_PIN) +#define MP3_NEXT_PORT_BASE GPIO_PORT_TO_BASE(MP3_WTV020SD_P02_PORT) +#define MP3_NEXT_PIN_MASK GPIO_PIN_MASK(MP3_WTV020SD_P02_PIN) + +#define MP3_RESET_PORT_BASE GPIO_PORT_TO_BASE(MP3_WTV020SD_RESET_PORT) +#define MP3_RESET_PIN_MASK GPIO_PIN_MASK(MP3_WTV020SD_RESET_PIN) +#define MP3_CLK_PORT_BASE GPIO_PORT_TO_BASE(MP3_WTV020SD_P04_PORT) +#define MP3_CLK_PIN_MASK GPIO_PIN_MASK(MP3_WTV020SD_P04_PIN) +#define MP3_DATA_PORT_BASE GPIO_PORT_TO_BASE(MP3_WTV020SD_P05_PORT) +#define MP3_DATA_PIN_MASK GPIO_PIN_MASK(MP3_WTV020SD_P05_PIN) + +/*---------------------------------------------------------------------------*/ +static uint8_t initialized = 0; +static int mp3_line_command(uint16_t cmd); +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_config(uint8_t mode) +{ + if(mode != MP3_WTV020SD_GPIO_MODE && mode != MP3_WTV020SD_LINE_MODE) { + return MP3_WTV020SD_ERROR; + } + + if(mode == MP3_WTV020SD_GPIO_MODE) { + GPIO_SOFTWARE_CONTROL(MP3_PLAY_PORT_BASE, MP3_PLAY_PIN_MASK); + GPIO_SET_OUTPUT(MP3_PLAY_PORT_BASE, MP3_PLAY_PIN_MASK); + GPIO_SET_PIN(MP3_PLAY_PORT_BASE, MP3_PLAY_PIN_MASK); + GPIO_SOFTWARE_CONTROL(MP3_NEXT_PORT_BASE, MP3_NEXT_PIN_MASK); + GPIO_SET_OUTPUT(MP3_NEXT_PORT_BASE, MP3_NEXT_PIN_MASK); + GPIO_SET_PIN(MP3_NEXT_PORT_BASE, MP3_NEXT_PIN_MASK); + } else { + GPIO_SOFTWARE_CONTROL(MP3_RESET_PORT_BASE, MP3_RESET_PIN_MASK); + GPIO_SET_OUTPUT(MP3_RESET_PORT_BASE, MP3_RESET_PIN_MASK); + GPIO_SET_PIN(MP3_RESET_PORT_BASE, MP3_RESET_PIN_MASK); + GPIO_SOFTWARE_CONTROL(MP3_CLK_PORT_BASE, MP3_CLK_PIN_MASK); + GPIO_SET_OUTPUT(MP3_CLK_PORT_BASE, MP3_CLK_PIN_MASK); + GPIO_SET_PIN(MP3_CLK_PORT_BASE, MP3_CLK_PIN_MASK); + GPIO_SOFTWARE_CONTROL(MP3_DATA_PORT_BASE, MP3_DATA_PIN_MASK); + GPIO_SET_OUTPUT(MP3_DATA_PORT_BASE, MP3_DATA_PIN_MASK); + GPIO_SET_PIN(MP3_DATA_PORT_BASE, MP3_DATA_PIN_MASK); + } + + GPIO_SOFTWARE_CONTROL(MP3_BUSY_PORT_BASE, MP3_BUSY_PIN_MASK); + GPIO_SET_INPUT(MP3_BUSY_PORT_BASE, MP3_BUSY_PIN_MASK); + + initialized = mode; + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_gpio_play(void) +{ + if(initialized != MP3_WTV020SD_GPIO_MODE) { + return MP3_WTV020SD_ERROR; + } + GPIO_CLR_PIN(MP3_PLAY_PORT_BASE, MP3_PLAY_PIN_MASK); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_gpio_stop(void) +{ + if(initialized != MP3_WTV020SD_GPIO_MODE) { + return MP3_WTV020SD_ERROR; + } + GPIO_SET_PIN(MP3_PLAY_PORT_BASE, MP3_PLAY_PIN_MASK); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_gpio_next(void) +{ + if(initialized != MP3_WTV020SD_GPIO_MODE) { + return MP3_WTV020SD_ERROR; + } + GPIO_CLR_PIN(MP3_PLAY_PORT_BASE, MP3_PLAY_PIN_MASK); + clock_delay_usec(MP3_USEC_DELAY); + GPIO_SET_PIN(MP3_PLAY_PORT_BASE, MP3_PLAY_PIN_MASK); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_busy(void) +{ + if((initialized != MP3_WTV020SD_GPIO_MODE) && + (initialized != MP3_WTV020SD_LINE_MODE)) { + return MP3_WTV020SD_ERROR; + } + if(GPIO_READ_PIN(MP3_BUSY_PORT_BASE, MP3_BUSY_PIN_MASK)) { + return MP3_WTV020SD_BUSY; + } + return MP3_WTV020SD_IDLE; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_reset(void) +{ + if(initialized != MP3_WTV020SD_LINE_MODE) { + return MP3_WTV020SD_ERROR; + } + GPIO_CLR_PIN(MP3_CLK_PORT_BASE, MP3_CLK_PIN_MASK); + GPIO_SET_PIN(MP3_RESET_PORT_BASE, MP3_RESET_PIN_MASK); + GPIO_CLR_PIN(MP3_RESET_PORT_BASE, MP3_RESET_PIN_MASK); + clock_delay_usec(MP3_USEC_DELAY); + GPIO_SET_PIN(MP3_RESET_PORT_BASE, MP3_RESET_PIN_MASK); + GPIO_SET_PIN(MP3_CLK_PORT_BASE, MP3_CLK_PIN_MASK); + clock_delay_usec(MP3_USEC_RESET_DELAY); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_sync_play(uint16_t track) +{ + if(initialized != MP3_WTV020SD_LINE_MODE) { + return MP3_WTV020SD_ERROR; + } + mp3_line_command(track); + while(mp3_wtv020sd_busy()); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_async_play(uint16_t track) +{ + if(initialized != MP3_WTV020SD_LINE_MODE) { + return MP3_WTV020SD_ERROR; + } + mp3_line_command(track); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_stop(void) +{ + if(initialized != MP3_WTV020SD_LINE_MODE) { + return MP3_WTV020SD_ERROR; + } + mp3_line_command(MP3_WTV020SD_STOP_VAL); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_pause(void) +{ + if(initialized != MP3_WTV020SD_LINE_MODE) { + return MP3_WTV020SD_ERROR; + } + mp3_line_command(MP3_WTV020SD_PLAY_PAUSE_VAL); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_line_command(uint16_t cmd) +{ + uint16_t mask; + if(initialized != MP3_WTV020SD_LINE_MODE) { + return MP3_WTV020SD_ERROR; + } + GPIO_CLR_PIN(MP3_CLK_PORT_BASE, MP3_CLK_PIN_MASK); + clock_delay_usec(MP3_USEC_CMD_DELAY / 10); + for(mask = 0x8000; mask > 0; mask >> 1) { + GPIO_CLR_PIN(MP3_CLK_PORT_BASE, MP3_CLK_PIN_MASK); + clock_delay_usec(MP3_USEC_CMD_DELAY / 2); + if(cmd & mask) { + GPIO_SET_PIN(MP3_DATA_PORT_BASE, MP3_DATA_PIN_MASK); + } else { + GPIO_CLR_PIN(MP3_DATA_PORT_BASE, MP3_DATA_PIN_MASK); + } + clock_delay_usec(MP3_USEC_CMD_DELAY / 2); + GPIO_SET_PIN(MP3_CLK_PORT_BASE, MP3_CLK_PIN_MASK); + clock_delay_usec(MP3_USEC_CMD_DELAY); + if(mask > 0x0001) { + clock_delay_usec(MP3_USEC_CMD_DELAY / 10); + } + } + clock_delay_usec(MP3_USEC_CMD_DELAY / 8); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ + +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/mp3-wtv020sd.h b/platform/zoul/dev/mp3-wtv020sd.h new file mode 100644 index 000000000..294157ca8 --- /dev/null +++ b/platform/zoul/dev/mp3-wtv020sd.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ +/* -------------------------------------------------------------------------- */ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-mp3-wtv020sd MP3 WTV020SD driver compatible with Zoul-based + * platforms + * + * Driver to control the MP3 WTV020SD board in MP3 mode (GPIO based) and the + * 2-line serial mode (CLK/DI). Loop Mode and Key Modes not implemented. + * More product information available at: + * http://avrproject.ru/chasy-budilnik/WTV020SD.pdf + * An example on how to wire with a sound power amplifier and speakers at + * http://www.hackster.io/zolertia + * Based on the Arduino Wtv020sd16p library + * @{ + * + * \file + * Header file for the MP3 WTV020SD driver + */ +/* -------------------------------------------------------------------------- */ +#ifndef MP3_WTV020SD_H_ +#define MP3_WTV020SD_H_ +/* -------------------------------------------------------------------------- */ +#include +/* -------------------------------------------------------------------------- */ +#define MP3_WTV020SD_ERROR -1 +#define MP3_WTV020SD_SUCCESS 0x00 +#define MP3_WTV020SD_GPIO_MODE 0x01 +#define MP3_WTV020SD_LINE_MODE 0x02 +#define MP3_WTV020SD_IDLE 0x00 +#define MP3_WTV020SD_BUSY 0x0F +/* -------------------------------------------------------------------------- */ +#define MP3_WTV020SD_PLAY_PAUSE_VAL 0xFFFE +#define MP3_WTV020SD_STOP_VAL 0xFFFF +#define MP3_WTV020SD_VOLUME_MIN 0xFFF0 +#define MP3_WTV020SD_VOLUME_MAX 0xFFF7 +/* -------------------------------------------------------------------------- */ +#define MP3_USEC_DELAY 1000 +#define MP3_USEC_CMD_DELAY 100 +#define MP3_USEC_RESET_DELAY ((MP3_USEC_DELAY) * 30) +/* -------------------------------------------------------------------------- */ +#define MP3_TRACK_BASE 0 /* 0000.ad4 */ +/* -------------------------------------------------------------------------- */ +/** + * \brief Init function for the MP3 driver + * + * Configures the pins required to operate in either driver mode + * + * \param mode drive the board using GPIOs or the two-line mode, using + * either MP3_WTV020SD_GPIO_MODE or MP3_WTV020SD_LINE_MODE + * \return MP3_WTV020SD_ERROR if invalid mode selected, otherwise it + * will return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_config(uint8_t mode); +/** + * \brief Function to play a current track + * + * \return MP3_WTV020SD_ERROR if invalid mode used, otherwise it will + * return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_gpio_play(void); +/** + * \brief Function to stop a current track + * + * \return MP3_WTV020SD_ERROR if invalid mode used, otherwise it will + * return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_gpio_stop(void); +/** + * \brief Advances and play the next track, wraps over the playlist + * + * \return MP3_WTV020SD_ERROR if invalid mode used, otherwise it will + * return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_gpio_next(void); +/** + * \brief Get the current status of the device (playing/stopped) + * + * \return MP3_WTV020SD_BUSY if a track is playing, otherwise it will + * return MP3_WTV020SD_IDLE + */ +int mp3_wtv020sd_busy(void); +/** + * \brief Trigger a module reset + * + * \return MP3_WTV020SD_ERROR if invalid mode used, otherwise it will + * return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_reset(void); +/** + * \brief Plays the selected track and waits until it stops + * + * \param track forwards and play the selected track, starting from + * MP3_TRACK_BASE (0000.ad4) up to MP3_TRACK_BASE + 511 + * (0511.ad4) + * \return MP3_WTV020SD_ERROR if invalid mode used, otherwise it will + * return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_sync_play(uint16_t track); +/** + * \brief Plays the selected track and returns immediately + * + * \param track forwards and play the selected track, starting from + * MP3_TRACK_BASE (0000.ad4) up to MP3_TRACK_BASE + 511 + * (0511.ad4) + * \return MP3_WTV020SD_ERROR if invalid mode used, otherwise it will + * return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_async_play(uint16_t track); +/** + * \brief Stops the current track + * + * \return MP3_WTV020SD_ERROR if invalid mode used, otherwise it will + * return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_stop(void); +/** + * \brief Pauses the current track + * + * \return MP3_WTV020SD_ERROR if invalid mode used, otherwise it will + * return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_pause(void); + +/* -------------------------------------------------------------------------- */ +#endif /* ifndef MP3_WTV020SD_H_ */ +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/pm10-sensor.c b/platform/zoul/dev/pm10-sensor.c new file mode 100644 index 000000000..3ec10de62 --- /dev/null +++ b/platform/zoul/dev/pm10-sensor.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-pm10-sensor + * @{ + * + * \file + * GP2Y1010AU0F PM10 sensor example using the ADC sensors wrapper + * \author + * Toni Lozano + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "adc-sensors.h" +#include "adc-zoul.h" +#include "zoul-sensors.h" +#include "dev/pm10-sensor.h" +#include "dev/sys-ctrl.h" +#include "lib/sensors.h" +#include "dev/gpio.h" +#include "dev/ioc.h" +/*---------------------------------------------------------------------------*/ +#define PM10_SENSOR_PORT_BASE GPIO_PORT_TO_BASE(PM10_SENSOR_CTRL_PORT) +#define PM10_SENSOR_PIN_MASK GPIO_PIN_MASK(PM10_SENSOR_CTRL_PIN) +/*---------------------------------------------------------------------------*/ +static int pm10_channel; +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != SENSORS_ACTIVE) { + return PM10_ERROR; + } + + if(value) { + /* Set as output, used as pulse-driven wave */ + GPIO_SOFTWARE_CONTROL(PM10_SENSOR_PORT_BASE, PM10_SENSOR_PIN_MASK); + ioc_set_over(PM10_SENSOR_CTRL_PORT, PM10_SENSOR_CTRL_PIN, IOC_OVERRIDE_DIS); + GPIO_SET_OUTPUT(PM10_SENSOR_PORT_BASE, PM10_SENSOR_PIN_MASK); + GPIO_CLR_PIN(PM10_SENSOR_PORT_BASE, PM10_SENSOR_PIN_MASK); + + pm10_channel = (1 << value); + return adc_zoul.configure(SENSORS_HW_INIT, pm10_channel); + } + + pm10_channel = 0; + return PM10_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + uint32_t val; + + if(!pm10_channel) { + return PM10_ERROR; + } + + /* Set Pulse Wave pin before measure */ + GPIO_SET_PIN(PM10_SENSOR_PORT_BASE, PM10_SENSOR_PIN_MASK); + /* Pulse wave delay */ + clock_delay_usec(PM10_SENSOR_PULSE_DELAY); + /* Data acquisition */ + val = (uint32_t)adc_zoul.value(pm10_channel); + + if(val == ZOUL_SENSORS_ERROR) { + printf("PM10 sensor: failed retrieving data\n"); + return PM10_ERROR; + } + + /* Default voltage divisor relation is 5/3 aprox, change at adc_wrapper.h, + * calculations below assume a decimation rate of 512 (12 bits ENOB) and + * AVVD5 voltage reference of 3.3V + */ + val *= PM10_EXTERNAL_VREF; + val /= PM10_EXTERNAL_VREF_CROSSVAL; + + /* Applied constant conversion from UAir project + * to obtain value in ppm (value in mV * 0.28) + */ + val *= 28; + val /= 1000; + + /* Clear pulse wave pin */ + GPIO_CLR_PIN(PM10_SENSOR_PORT_BASE, PM10_SENSOR_PIN_MASK); + + return (uint16_t)val; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(pm10, PM10_SENSOR, value, configure, NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/pm10-sensor.h b/platform/zoul/dev/pm10-sensor.h new file mode 100644 index 000000000..d43256e44 --- /dev/null +++ b/platform/zoul/dev/pm10-sensor.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-pm10-sensor Analog PM10 sensor + * @{ + * \file + * GP2Y1010AU0F PM10 sensor driver + * \author + * Toni Lozano + */ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#ifndef PM10_SENSOR_H_ +#define PM10_SENSOR_H_ +/* -------------------------------------------------------------------------- */ +#define PM10_ERROR (-1) +#define PM10_SUCCESS 0 +#define PM10_SENSOR "PM10 Sensor" +#define PM10_SENSOR_PULSE_DELAY 280 +#define PM10_EXTERNAL_VREF 5000 +#define PM10_EXTERNAL_VREF_CROSSVAL 3300 +/* -------------------------------------------------------------------------- */ +#ifdef PM10_SENSOR_CONF_CTRL_PIN +#define PM10_SENSOR_CTRL_PIN PM10_SENSOR_CONF_CTRL_PIN +#else +#define PM10_SENSOR_CTRL_PIN 7 +#endif +#ifdef PM10_SENSOR_CONF_CTRL_PORT +#define PM10_SENSOR_CTRL_PORT PM10_SENSOR_CONF_CTRL_PORT +#else +#define PM10_SENSOR_CTRL_PORT GPIO_A_NUM +#endif +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor pm10; +/* -------------------------------------------------------------------------- */ +#endif /* ifndef PM10_SENSOR_H_ */ +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/relay.c b/platform/zoul/dev/relay.c new file mode 100644 index 000000000..aa4f88dd5 --- /dev/null +++ b/platform/zoul/dev/relay.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-relay + * @{ + * + * \file + * Driver for a relay actuator + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "relay.h" +#include "dev/gpio.h" +#include "lib/sensors.h" +#include "dev/ioc.h" +/*---------------------------------------------------------------------------*/ +#define RELAY_PORT_BASE GPIO_PORT_TO_BASE(RELAY_PORT) +#define RELAY_PIN_MASK GPIO_PIN_MASK(RELAY_PIN) +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +static int +relay_on(void) +{ + if(enabled) { + GPIO_SET_PIN(RELAY_PORT_BASE, RELAY_PIN_MASK); + return RELAY_SUCCESS; + } + return RELAY_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +relay_off(void) +{ + if(enabled) { + GPIO_CLR_PIN(RELAY_PORT_BASE, RELAY_PIN_MASK); + return RELAY_SUCCESS; + } + return RELAY_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + return GPIO_READ_PIN(RELAY_PORT_BASE, RELAY_PIN_MASK); + case SENSORS_READY: + return enabled; + } + return RELAY_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + switch(type) { + case RELAY_OFF: + return relay_on(); + case RELAY_ON: + return relay_off(); + case RELAY_TOGGLE: + if(status(SENSORS_ACTIVE)) { + return relay_off(); + } else { + return relay_on(); + } + default: + return RELAY_ERROR; + } +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != SENSORS_ACTIVE) { + return RELAY_ERROR; + } + + if(value) { + GPIO_SOFTWARE_CONTROL(RELAY_PORT_BASE, RELAY_PIN_MASK); + GPIO_SET_OUTPUT(RELAY_PORT_BASE, RELAY_PIN_MASK); + ioc_set_over(RELAY_PORT, RELAY_PIN, IOC_OVERRIDE_OE); + GPIO_CLR_PIN(RELAY_PORT_BASE, RELAY_PIN_MASK); + enabled = 1; + return RELAY_SUCCESS; + } + + GPIO_SET_INPUT(RELAY_PORT_BASE, RELAY_PIN_MASK); + enabled = 0; + return RELAY_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(relay, RELAY_ACTUATOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/sensinode/dev/models.c b/platform/zoul/dev/relay.h similarity index 53% rename from platform/sensinode/dev/models.c rename to platform/zoul/dev/relay.h index 15b21fffa..4123f9e99 100644 --- a/platform/sensinode/dev/models.c +++ b/platform/zoul/dev/relay.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Loughborough University - Computer Science + * Copyright (c) 2016, Zolertia - http://www.zolertia.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,69 +27,66 @@ * SUCH DAMAGE. * * This file is part of the Contiki operating system. + * */ - +/*---------------------------------------------------------------------------*/ /** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-relay Generic relay driver + * + * Driver for a generic relay driver + * @{ + * * \file - * Model-specific functions for Sensinode devices. - * - * Bankable - * - * \author - * George Oikonomou - + * Header file for the generic relay driver */ - -#include "dev/models.h" -#include "dev/uart1.h" -#include "dev/m25p16.h" /*---------------------------------------------------------------------------*/ -void -model_init() -{ -#ifdef MODEL_N740 - /* - * We want to prevent the dongle from controlling the state of the - * analog switch on the N740s. - * - * Set P0_3 as out and start with P0_3=0 (USB and Light selected) - */ - P0DIR |= 0x08; /* P0_3 out */ - P0_3 = 0; - - /* Init the serial-parallel chip for N740s. This will also 'init' LEDs */ - n740_ser_par_init(); - - /* Put the Serial Flash in Deep Power mode */ - n740_analog_deactivate(); - -#if M25P16_CONF_ON - m25p16_dp(); -#endif /* SERIAL_FLASH_CONF_ON */ - - n740_ser_par_set(0); -#endif -} -/*---------------------------------------------------------------------------*/ -void -model_uart_intr_en() -{ -#ifdef MODEL_N740 - /* - * Dirty, ugly hack for the N740 USART1 RX issue: - * When the USB is for whatever reason disabled (either disconnected or the - * analog switch has switched to the D-connector), RX starts flowing down - * pin 1.7 (and the line stays low), resulting in non-stop UART1_RX - * interrupts. So, we only acknowledge the interrupt when the line is - * high and the dongle is connected (thus we are on USB). - * - * For all other models, just turn the interrupt on - * - * Interrupts will only turn on if UART_ONE_CONF_WITH_INPUT is defined 1 - */ - if(P1_7 == 1 && P0_3 == 0) { - UART1_RX_INT(1); - } +#ifndef RELAY_H_ +#define RELAY_H_ +/* -------------------------------------------------------------------------- */ +/** + * \name Relay default pin and port + * @{ + */ +#ifdef RELAY_CONF_PIN +#define RELAY_PIN RELAY_CONF_PIN #else - UART1_RX_INT(1); +#define RELAY_PIN 5 #endif -} +#ifdef RELAY_CONF_PORT +#define RELAY_PORT RELAY_CONF_PORT +#else +#define RELAY_PORT GPIO_A_NUM +#endif +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Relay available commands + * @{ + */ +#define RELAY_OFF 0x00 +#define RELAY_ON 0x01 +#define RELAY_TOGGLE 0x02 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Relay return types + * @{ + */ +#define RELAY_ERROR (-1) +#define RELAY_SUCCESS 0x00 +/** @} */ +/* -------------------------------------------------------------------------- */ +#define RELAY_ACTUATOR "Generic Relay" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor relay; +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +#endif /* RELAY_H_ */ +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/rgb-bl-lcd.c b/platform/zoul/dev/rgb-bl-lcd.c new file mode 100644 index 000000000..c0c79ebe8 --- /dev/null +++ b/platform/zoul/dev/rgb-bl-lcd.c @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-lcd-backlight-lcd + * @{ + * + * \file + * Grove LCD with RGB backlight driver + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/i2c.h" +#include "dev/rgb-bl-lcd.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +typedef struct { + uint8_t display_func; + uint8_t display_ctrl; + uint8_t display_mode; + uint8_t num_lines; + uint8_t cur_line; +} rgb_lcd_config_t; + +static rgb_lcd_config_t lcd; +/*---------------------------------------------------------------------------*/ +static const unsigned char rgb_color[7][3] = +{ + { 0xFF, 0xFF, 0xFF }, /**< White */ + { 0xFF, 0x00, 0x00 }, /**< Red */ + { 0x00, 0xFF, 0x00 }, /**< Green */ + { 0x00, 0x00, 0xFF }, /**< Blue */ + { 0xFF, 0xFF, 0x00 }, /**< Yellow */ + { 0x00, 0xFF, 0xFF }, /**< Purple */ + { 0x00, 0x00, 0x00 }, /**< Black (off) */ +}; +/*---------------------------------------------------------------------------*/ +static int +lcd_backlight_write_reg(uint8_t addr, uint8_t val) +{ + uint8_t buf[2]; + buf[0] = addr; + buf[1] = val; + + i2c_master_enable(); + if(i2c_burst_send(LCD_RGB_ADDR, buf, 2) == I2C_MASTER_ERR_NONE) { + return LCD_RGB_SUCCESS; + } + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_backlight_color(uint8_t color) +{ + lcd_backlight_write_reg(LCD_RGB_LED_RED, rgb_color[color][0]); + lcd_backlight_write_reg(LCD_RGB_LED_GREEN, rgb_color[color][1]); + lcd_backlight_write_reg(LCD_RGB_LED_BLUE, rgb_color[color][2]); + + return LCD_RGB_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +lcd_write_reg(uint8_t *buf, uint8_t num) +{ + if((buf == NULL) || (num <= 0)) { + PRINTF("LCD: invalid write values\n"); + return LCD_RGB_ERROR; + } + + i2c_master_enable(); + if(i2c_burst_send(LCD_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { + return LCD_RGB_SUCCESS; + } + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +lcd_cmd(uint8_t value) +{ + uint8_t buf[2]; + buf[0] = LCD_RGB_COMMAND_BYTE; + buf[1] = value; + + if(lcd_write_reg(buf, 2) == LCD_RGB_SUCCESS) { + return LCD_RGB_SUCCESS; + } + + PRINTF("LCD: failed to send command 0x%02X\n", value); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_clear_display(void) +{ + if(lcd_cmd(LCD_RGB_CLEAR_DISPLAY) == LCD_RGB_SUCCESS) { + clock_delay_usec(LCD_RGB_DELAY_2MS); + return LCD_RGB_SUCCESS; + } + PRINTF("LCD: failed to clear LCD\n"); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_return_home(void) +{ + if(lcd_cmd(LCD_RGB_RETURN_HOME) == LCD_RGB_SUCCESS) { + clock_delay_usec(LCD_RGB_DELAY_2MS); + return LCD_RGB_SUCCESS; + } + PRINTF("LCD: failed to return home\n"); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_set_cursor(uint8_t col, uint8_t row) +{ + uint8_t buf[2]; + buf[0] = LCD_RGB_SETDDRAM_ADDR; + buf[1] = col; + buf[1] += (!row) ? LCD_RGB_START_1ST_ROW : LCD_RGB_START_2ND_ROW; + + if(lcd_write_reg(buf, 2) == LCD_RGB_SUCCESS) { + return LCD_RGB_SUCCESS; + } + + PRINTF("LCD: failed to set cursor\n"); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_display(uint8_t state) +{ + lcd.display_ctrl &= ~LCD_RGB_DISPLAY_ON; + if(state) { + lcd.display_ctrl |= LCD_RGB_DISPLAY_ON; + } + + if(lcd_cmd(LCD_RGB_DISPLAY_CONTROL + lcd.display_ctrl) == LCD_RGB_SUCCESS) { + return LCD_RGB_SUCCESS; + } + PRINTF("LCD: failed to set display\n"); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_cursor(uint8_t state) +{ + lcd.display_ctrl &= ~LCD_RGB_DISPLAY_CURSOR_ON; + if(state) { + lcd.display_ctrl |= LCD_RGB_DISPLAY_CURSOR_ON; + } + + if(lcd_cmd(LCD_RGB_DISPLAY_CONTROL + lcd.display_ctrl) == LCD_RGB_SUCCESS) { + return LCD_RGB_SUCCESS; + } + PRINTF("LCD: failed to set cursor\n"); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_blink(uint8_t state) +{ + lcd.display_ctrl &= ~LCD_RGB_DISPLAY_BLINK_ON; + if(state) { + lcd.display_ctrl |= LCD_RGB_DISPLAY_BLINK_ON; + } + + if(lcd_cmd(LCD_RGB_DISPLAY_CONTROL + lcd.display_ctrl) == LCD_RGB_SUCCESS) { + return LCD_RGB_SUCCESS; + } + PRINTF("LCD: failed to set blink\n"); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_scroll_display(uint8_t direction, uint8_t num) +{ + uint8_t i; + + /* FIXME: add check for num */ + + for(i = 0; i < num; i++) { + if(lcd_cmd(LCD_RGB_CURSOR_SHIFT + LCD_RGB_CURSOR_DISPLAY_MOVE + + direction) != LCD_RGB_SUCCESS) { + PRINTF("LCD: failed to set scroll\n"); + return LCD_RGB_ERROR; + } + } + return LCD_RGB_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +lcd_text_direction(uint8_t direction) +{ + lcd.display_mode &= ~LCD_RGB_ENTRY_MODE_LEFT; + if(direction) { + lcd.display_mode |= LCD_RGB_ENTRY_MODE_LEFT; + } + + if(lcd_cmd(LCD_RGB_ENTRY_MODE_SET + lcd.display_mode) == LCD_RGB_SUCCESS) { + return LCD_RGB_SUCCESS; + } + PRINTF("LCD: failed to set text direction\n"); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_autoscroll(uint8_t state) +{ + lcd.display_mode &= ~LCD_RGB_ENTRY_SHIFT_INCREMENT; + if(state) { + lcd.display_mode |= LCD_RGB_ENTRY_SHIFT_INCREMENT; + } + + if(lcd_cmd(LCD_RGB_ENTRY_MODE_SET + lcd.display_mode) == LCD_RGB_SUCCESS) { + return LCD_RGB_SUCCESS; + } + PRINTF("LCD: failed to set autoscroll\n"); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +lcd_write_byte(int c) +{ + uint8_t buf[2]; + buf[0] = LCD_RGB_SETCGRAM_ADDR; + buf[1] = c; + + if(lcd_write_reg(buf, 2) == LCD_RGB_SUCCESS) { + return LCD_RGB_SUCCESS; + } + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +uint8_t +lcd_write(const char *s) +{ + uint8_t i = 0; + while(s && *s != 0) { + lcd_write_byte(*s++); + i++; + } + + PRINTF("LCD: wrote %u bytes\n", i); + return i; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + + if(type != LCD_RGB_ACTIVE) { + PRINTF("LCD: option not supported\n"); + return LCD_RGB_ERROR; + } + + switch(type) { + + /* Default initialization value is 16 columns and 2 rows */ + case LCD_RGB_ACTIVE: + if(value) { + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_NORMAL_BUS_SPEED); + + lcd.display_func = LCD_RGB_FUNCTION_SET_2_LINE + + LCD_RGB_FUNCTION_SET_5x8_DOTS; + + /* wait at least 50ms for the LCD to initialize */ + clock_delay_usec(LCD_RGB_DELAY_50MS); + + /* Send function set command sequence */ + if(lcd_cmd(LCD_RGB_FUNCTION_SET + lcd.display_func) == LCD_RGB_ERROR) { + return LCD_RGB_ERROR; + } + clock_delay_usec(LCD_RGB_DELAY_4_5MS); + + /* Datasheet instructs to repeat a second time... */ + if(lcd_cmd(LCD_RGB_FUNCTION_SET + lcd.display_func) == LCD_RGB_ERROR) { + return LCD_RGB_ERROR; + } + clock_delay_usec(LCD_RGB_DELAY_150US); + + /* and a third... */ + if(lcd_cmd(LCD_RGB_FUNCTION_SET + lcd.display_func) == LCD_RGB_ERROR) { + return LCD_RGB_ERROR; + } + + /* Now we can configure everything */ + if(lcd_cmd(LCD_RGB_FUNCTION_SET + lcd.display_func) == LCD_RGB_ERROR) { + return LCD_RGB_ERROR; + } + + /* Turn on the display */ + lcd.display_ctrl = LCD_RGB_DISPLAY_ON + LCD_RGB_DISPLAY_CURSOR_OFF + + LCD_RGB_DISPLAY_BLINK_OFF; + if(lcd_cmd(LCD_RGB_DISPLAY_CONTROL + lcd.display_ctrl) == LCD_RGB_ERROR) { + return LCD_RGB_ERROR; + } + + /* Clear the display */ + if(lcd_clear_display() == LCD_RGB_ERROR) { + return LCD_RGB_ERROR; + } + + /* Initialize text direction (the LCD supports japanese, cool! */ + lcd.display_mode = LCD_RGB_ENTRY_MODE_LEFT + LCD_RGB_ENTRY_SHIFT_DECREMENT; + + /* configure the entry mode */ + if(lcd_cmd(LCD_RGB_ENTRY_MODE_SET + lcd.display_mode) == LCD_RGB_ERROR) { + return LCD_RGB_ERROR; + } + + /* Backlight initialization */ + lcd_backlight_write_reg(LCD_RGB_LED_MODE_1, LCD_RGB_LED_MODE_DEFAULT); + lcd_backlight_write_reg(LCD_RGB_LED_MODE_2, LCD_RGB_LED_MODE_DEFAULT); + lcd_backlight_write_reg(LCD_RGB_LED_OUT, LCD_RGB_LED_OUT_PWM_CTRL); + + /* Set the backlight color */ + lcd_backlight_color(LCD_RGB_RED); + + PRINTF("LCD: initialized\n"); + enabled = 1; + return LCD_RGB_SUCCESS; + } else { + lcd_display(LCD_RGB_DISPLAY_OFF); + lcd_backlight_color(LCD_RGB_BLACK); + enabled = 0; + } + } + + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(rgb_bl_lcd, RGB_BACKLIGHT_LCD, NULL, configure, NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/rgb-bl-lcd.h b/platform/zoul/dev/rgb-bl-lcd.h new file mode 100644 index 000000000..eaf5c2761 --- /dev/null +++ b/platform/zoul/dev/rgb-bl-lcd.h @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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 SOcFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-lcd-backlight-lcd Grove LCD with RGB backlight + * @{ + * + * \file + * Grove LCD with RGB backlight header + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/* -------------------------------------------------------------------------- */ +#ifndef RGB_BL_LCD_H_ +#define RGB_BL_LCD_H_ +/* -------------------------------------------------------------------------- */ +/** + * \name LCD w/ backlight enums + * @{ + */ +enum { + LCD_RGB_WHITE = 0x00, + LCD_RGB_RED = 0x01, + LCD_RGB_GREEN = 0x02, + LCD_RGB_BLUE = 0x03, + LCD_RGB_BLACK = 0x04, + LCD_RGB_YELLOW = 0x05, + LCD_RGB_PURPLE = 0x06, +}; +/* -------------------------------------------------------------------------- */ +enum { + LCD_RGB_1ST_ROW = 0x00, + LCD_RGB_2ND_ROW = 0x01, +}; +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name LCD w/ backlight address, registers and bitmasks + * @{ + */ +#define LCD_ADDR 0x3E +#define LCD_RGB_ADDR 0x62 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_REG_MODE1 0x00 +#define LCD_RGB_REG_MODE2 0x01 +#define LCD_RGB_REG_OUTPUT 0x08 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_COMMAND_BYTE 0x80 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_CLEAR_DISPLAY 0x01 +#define LCD_RGB_RETURN_HOME 0x02 +#define LCD_RGB_ENTRY_MODE_SET 0x04 +#define LCD_RGB_DISPLAY_CONTROL 0x08 +#define LCD_RGB_CURSOR_SHIFT 0x10 +#define LCD_RGB_FUNCTION_SET 0x20 +#define LCD_RGB_SETCGRAM_ADDR 0x40 +#define LCD_RGB_SETDDRAM_ADDR 0x80 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_ENTRY_MODE_RIGHT 0x00 +#define LCD_RGB_ENTRY_MODE_LEFT 0x02 +#define LCD_RGB_ENTRY_SHIFT_INCREMENT 0x01 +#define LCD_RGB_ENTRY_SHIFT_DECREMENT 0x00 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_DISPLAY_ON 0x04 +#define LCD_RGB_DISPLAY_OFF 0x00 +#define LCD_RGB_DISPLAY_CURSOR_ON 0x02 +#define LCD_RGB_DISPLAY_CURSOR_OFF 0x00 +#define LCD_RGB_DISPLAY_BLINK_ON 0x01 +#define LCD_RGB_DISPLAY_BLINK_OFF 0x00 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_CURSOR_DISPLAY_MOVE 0x08 +#define LCD_RGB_CURSOR_MOVE 0x00 +#define LCD_RGB_CURSOR_MOVE_RIGHT 0x04 +#define LCD_RGB_CURSOR_MOVE_LEFT 0x00 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_FUNCTION_SET_8BIT 0x10 +#define LCD_RGB_FUNCTION_SET_4BIT 0x00 +#define LCD_RGB_FUNCTION_SET_2_LINE 0x08 +#define LCD_RGB_FUNCTION_SET_1_LINE 0x00 +#define LCD_RGB_FUNCTION_SET_5x10_DOTS 0x04 +#define LCD_RGB_FUNCTION_SET_5x8_DOTS 0x00 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_LED_MODE_1 0x00 +#define LCD_RGB_LED_MODE_2 0x01 +#define LCD_RGB_LED_OUT 0x08 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_LED_RED 0x04 +#define LCD_RGB_LED_GREEN 0x03 +#define LCD_RGB_LED_BLUE 0x02 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_LED_MODE_DEFAULT 0x00 +#define LCD_RGB_LED_OUT_PWM_CTRL 0xAA +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_DELAY_50MS 50000 +#define LCD_RGB_DELAY_4_5MS 4500 +#define LCD_RGB_DELAY_150US 150 +#define LCD_RGB_DELAY_2MS 2000 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_START_1ST_ROW 0x80 +#define LCD_RGB_START_2ND_ROW 0xC0 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_ACTIVE SENSORS_ACTIVE +#define LCD_RGB_ERROR (-1) +#define LCD_RGB_SUCCESS 0x00 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name TSL2563 return and command values + * @{ + */ +/* LCD functions */ +uint8_t lcd_write(const char *s); +int lcd_set_cursor(uint8_t col, uint8_t row); +int lcd_autoscroll(uint8_t state); +int lcd_scroll_display(uint8_t direction, uint8_t num); +int lcd_blink(uint8_t state); +int lcd_clear_display(void); +int lcd_return_home(void); +int lcd_display(uint8_t state); +int lcd_cursor(uint8_t state); +int lcd_text_direction(uint8_t direction); + +/* Backlight functions */ +int lcd_backlight_color(uint8_t color); +/** @} */ +/* -------------------------------------------------------------------------- */ +#define RGB_BACKLIGHT_LCD "LCD with RGB backlight" +extern const struct sensors_sensor rgb_bl_lcd; +/* -------------------------------------------------------------------------- */ +#endif /* ifndef RGB_BL_LCD_ */ +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/sht25.c b/platform/zoul/dev/sht25.c new file mode 100644 index 000000000..6273ae0c0 --- /dev/null +++ b/platform/zoul/dev/sht25.c @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sht25-sensor + * @{ + * + * \file + * SHT25 temperature and humidity sensor driver + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/i2c.h" +#include "dev/sht25.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +static uint8_t user_reg; +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static uint16_t +sht25_read_reg(uint8_t reg, uint8_t *buf, uint8_t num) +{ + if((buf == NULL) || (num <= 0)) { + return SHT25_ERROR; + } + + i2c_master_enable(); + if(i2c_single_send(SHT25_ADDR, reg) == I2C_MASTER_ERR_NONE) { + if(i2c_burst_receive(SHT25_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { + return SHT25_SUCCESS; + } + } + return SHT25_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int16_t +sht25_convert(uint8_t variable, uint16_t value) +{ + int16_t rd; + uint32_t buff; + + /* Clear the status bits */ + buff = (uint32_t)(value & ~SHT25_STATUS_BITS_MASK); + + if(variable == SHT25_VAL_TEMP) { + buff *= 17572; + buff = buff >> 16; + rd = (int16_t)buff - 4685; + } else { + buff *= 12500; + buff = buff >> 16; + rd = (int16_t)buff - 600; + rd = (rd > 10000) ? 10000 : rd; + } + return rd; +} +/*---------------------------------------------------------------------------*/ +static int +sht25_read(uint8_t variable, uint16_t *rd) +{ + uint8_t buf[2]; + uint16_t raw; + + if((variable != SHT25_VAL_TEMP) && (variable != SHT25_VAL_HUM)) { + PRINTF("SHT25: invalid sensor requested\n"); + return SHT25_ERROR; + } + + if(sht25_read_reg(variable, buf, 2) == SHT25_SUCCESS) { + raw = (buf[0] << 8) + buf[1]; + *rd = sht25_convert(variable, raw); + return SHT25_SUCCESS; + } + + PRINTF("SHT25: failed to read sensor\n"); + return SHT25_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +sht25_write_reg(uint8_t *buf, uint8_t num) +{ + if((buf == NULL) || (num <= 0)) { + PRINTF("SHT25: invalid write values\n"); + return SHT25_ERROR; + } + + i2c_master_enable(); + if(i2c_burst_send(SHT25_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { + return SHT25_SUCCESS; + } + return SHT25_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +sht25_read_user_register(void) +{ + if(sht25_read_reg(SHT2X_UREG_READ, &user_reg, 1) == SHT25_SUCCESS) { + PRINTF("SHT25: user register 0x%02X\n", user_reg); + return SHT25_SUCCESS; + } + PRINTF("SHT25: failed to read user register\n"); + return SHT25_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + uint16_t val; + + if(!enabled) { + PRINTF("SHT25: sensor not started\n"); + return SHT25_ERROR; + } + + if((type != SHT25_VAL_TEMP) && (type != SHT25_VAL_HUM) && + (type != SHT25_VOLTAGE_ALARM)) { + PRINTF("SHT25: invalid value requested\n"); + return SHT25_ERROR; + } + + if(type == SHT25_VOLTAGE_ALARM) { + if(sht25_read_user_register() == SHT25_SUCCESS) { + return (user_reg & SHT2x_LOW_VOLTAGE_MASK) >> SHT2x_LOW_VOLTAGE_SHIFT; + } + } else { + if(sht25_read(type, &val) == SHT25_SUCCESS) { + return val; + } + } + return SHT25_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + uint8_t buf[2]; + + if((type != SHT25_ACTIVE) && (type != SHT25_SOFT_RESET) && + (type != SHT25_RESOLUTION)) { + PRINTF("SHT25: option not supported\n"); + return SHT25_ERROR; + } + + switch(type) { + case SHT25_ACTIVE: + if(value) { + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_NORMAL_BUS_SPEED); + + /* Read the user config register */ + if(sht25_read_user_register() == SHT25_SUCCESS) { + enabled = value; + return SHT25_SUCCESS; + } + } + + case SHT25_SOFT_RESET: + buf[0] = SHT2X_SOFT_RESET; + if(sht25_write_reg(&buf[0], 1) != SHT25_SUCCESS) { + PRINTF("SHT25: failed to reset the sensor\n"); + return SHT25_ERROR; + } + clock_delay_usec(SHT25_RESET_DELAY); + return SHT25_SUCCESS; + + case SHT25_RESOLUTION: + if((value != SHT2X_RES_14T_12RH) && (value != SHT2X_RES_12T_08RH) && + (value != SHT2X_RES_13T_10RH) && (value != SHT2X_RES_11T_11RH)) { + PRINTF("SHT25: invalid resolution value\n"); + return SHT25_ERROR; + } + + user_reg &= ~SHT2X_RES_11T_11RH; + user_reg |= value; + buf[0] = SHT2X_UREG_WRITE; + buf[1] = user_reg; + + if(sht25_write_reg(buf, 2) == SHT25_SUCCESS) { + PRINTF("SHT25: new user register value 0x%02X\n", user_reg); + return SHT25_SUCCESS; + } + + default: + return SHT25_ERROR; + } + + return SHT25_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(sht25, SHT25_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/sht25.h b/platform/zoul/dev/sht25.h new file mode 100644 index 000000000..11d5c61a8 --- /dev/null +++ b/platform/zoul/dev/sht25.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-sht25-sensor SHT25 digital temperature sensor + * @{ + * + * \file + * SHT25 temperature and humidity sensor driver header file + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/* -------------------------------------------------------------------------- */ +#ifndef SHT25_H_ +#define SHT25_H_ +/* -------------------------------------------------------------------------- */ +#define SHT25_ADDR 0x40 +#define SHT25_TEMP_HOLD 0xE3 +#define SHT25_HUM_HOLD 0xE5 +#define SHT25_TEMP_NO_HOLD 0xF3 +#define SHT25_HUM_NO_HOLD 0xF5 +#define SHT2X_UREG_WRITE 0xE6 +#define SHT2X_UREG_READ 0xE7 +#define SHT2X_SOFT_RESET 0XFE +#define SHT2X_NULL 0x00 +/* -------------------------------------------------------------------------- */ +#define SHT2X_RES_14T_12RH 0x00 +#define SHT2X_RES_12T_08RH 0x01 +#define SHT2X_RES_13T_10RH 0x80 +#define SHT2X_RES_11T_11RH 0x81 +#define SHT2X_HEATER_ON 0x04 +#define SHT2X_HEATER_OFF 0x00 +#define SHT2X_OTP_RELOAD_EN 0x00 +#define SHT2X_OTP_RELOAD_DIS 0x02 +#define SHT2x_LOW_VOLTAGE_MASK 0x40 +#define SHT2x_LOW_VOLTAGE_SHIFT 0x06 +/* -------------------------------------------------------------------------- */ +#define SHT25_ACTIVE SENSORS_ACTIVE +#define SHT25_SOFT_RESET 0x01 +#define SHT25_RESOLUTION 0x02 + +#define SHT25_VAL_TEMP SHT25_TEMP_HOLD +#define SHT25_VAL_HUM SHT25_HUM_HOLD +#define SHT25_VOLTAGE_ALARM 0x01 + +#define SHT25_ERROR (-1) +#define SHT25_SUCCESS 0x00 +#define SHT25_RESET_DELAY 15000 +#define SHT25_STATUS_BITS_MASK 0x0003 +/* -------------------------------------------------------------------------- */ +#define SHT25_SENSOR "SHT25 Sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor sht25; +/* -------------------------------------------------------------------------- */ +#endif /* ifndef SHT25_H_ */ +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/tmp102.c b/platform/zoul/dev/tmp102.c new file mode 100644 index 000000000..2d3e897e2 --- /dev/null +++ b/platform/zoul/dev/tmp102.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-tmp102-sensor + * @{ + * + * \file + * Driver for the TMP102 temperature sensor + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/i2c.h" +#include "tmp102.h" + +void +tmp102_init(void) +{ + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, I2C_SCL_NORMAL_BUS_SPEED); +} +/*---------------------------------------------------------------------------*/ + +uint8_t +tmp102_read(uint16_t *data) +{ + uint8_t buf[2]; + uint16_t temp; + + /* Write to the temperature register to trigger a reading */ + if(i2c_single_send(TMP102_ADDR, TMP102_TEMP) == I2C_MASTER_ERR_NONE) { + /* Read two bytes only */ + if(i2c_burst_receive(TMP102_ADDR, buf, 2) == I2C_MASTER_ERR_NONE) { + temp = (buf[0] << 8) + buf[1]; + if(temp > 2047) { + temp -= (1 << 12); + } + temp *= 0.625; + *data = temp; + return I2C_MASTER_ERR_NONE; + } + } + return i2c_master_error(); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/tmp102.h b/platform/zoul/dev/tmp102.h new file mode 100644 index 000000000..030e59fe5 --- /dev/null +++ b/platform/zoul/dev/tmp102.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-tmp102-sensor TMP102 Sensor + * + * Driver for the TMP102 sensor + * + * The TMP102 driver returns the converted temperature value in centiCelsius + * with 2 digits precision, to get Celsius just divide by 100. + * @{ + * + * \file + * Header file for the TMP102 Sensor Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef TMP102_H_ +#define TMP102_H_ +#include +#include "i2c.h" +/* -------------------------------------------------------------------------- */ +/** + * \name Generic TMP102 sensor + * @{ + */ +/* -------------------------------------------------------------------------- */ +#define TMP102_ADDR 0x48 /**< TMP102 slave address */ +#define TMP102_TEMP 0x00 /**< TMP102 temperature data register */ +/** @} */ +/* -------------------------------------------------------------------------- */ +#endif /* ifndef TMP102_H_ */ +/*---------------------------------------------------------------------------*/ + +/** \brief Initialiser for the TMP102 sensor driver */ +void tmp102_init(void); + +/** \brief Get a temperature reading from the TMP102 sensor */ +uint8_t tmp102_read(uint16_t *data); + +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/tsl2563.c b/platform/zoul/dev/tsl2563.c new file mode 100644 index 000000000..e35698bec --- /dev/null +++ b/platform/zoul/dev/tsl2563.c @@ -0,0 +1,494 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-tsl2563-sensor + * @{ + * + * \file + * Driver for the external TSL2563 light sensor + * + * \author + * Antonio Lignan + * Toni Lozano + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/i2c.h" +#include "dev/gpio.h" +#include "dev/zoul-sensors.h" +#include "lib/sensors.h" +#include "tsl2563.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +#define TSL2563_INT_PORT_BASE GPIO_PORT_TO_BASE(I2C_INT_PORT) +#define TSL2563_INT_PIN_MASK GPIO_PIN_MASK(I2C_INT_PIN) +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +static uint8_t gain; +static uint8_t timming; +/*---------------------------------------------------------------------------*/ +void (*tsl2563_int_callback)(uint8_t value); +/*---------------------------------------------------------------------------*/ +static uint16_t +calculate_lux(uint8_t *buf) +{ + uint32_t ch0, ch1, chscale = 0; + uint32_t ratio = 0; + uint32_t lratio, tmp = 0; + uint16_t buffer[2]; + + /* The calculations below assume the integration time is 402ms and the gain + * is 16x (nominal), if not then it is required to normalize the reading + * before converting to lux + */ + + buffer[0] = (buf[1] << 8 | (buf[0])); + buffer[1] = (buf[3] << 8 | (buf[2])); + + switch(timming) { + case TSL2563_TIMMING_INTEG_402MS: + chscale = (1 << CH_SCALE); + break; + case TSL2563_TIMMING_INTEG_101MS: + chscale = CHSCALE_TINT1; + break; + case TSL2563_TIMMING_INTEG_13_7MS: + chscale = CHSCALE_TINT0; + break; + } + + if(!gain) { + chscale = chscale << 4; + } + + ch0 = (buffer[0] * chscale) >> CH_SCALE; + ch1 = (buffer[1] * chscale) >> CH_SCALE; + + if(ch0 > 0) { + ratio = (ch1 << CH_SCALE); + ratio = ratio / ch0; + } + + lratio = (ratio + 1) >> 1; + + if((lratio >= 0) && (lratio <= K1T)) { + tmp = (ch0 * B1T) - (ch1 * M1T); + } else if(lratio <= K2T) { + tmp = (ch0 * B2T) - (ch1 * M2T); + } else if(lratio <= K3T) { + tmp = (ch0 * B3T) - (ch1 * M3T); + } else if(lratio <= K4T) { + tmp = (ch0 * B4T) - (ch1 * M4T); + } else if(lratio <= K5T) { + tmp = (ch0 * B5T) - (ch1 * M5T); + } else if(lratio <= K6T) { + tmp = (ch0 * B6T) - (ch1 * M6T); + } else if(lratio <= K7T) { + tmp = (ch0 * B7T) - (ch1 * M7T); + } else if(lratio > K8T) { + tmp = (ch0 * B8T) - (ch1 * M8T); + } + + if(tmp < 0) { + tmp = 0; + } + + tmp += (1 << (LUX_SCALE - 1)); + return tmp >> LUX_SCALE; +} +/*---------------------------------------------------------------------------*/ +static int +tsl2563_read_reg(uint8_t reg, uint8_t *buf, uint8_t regNum) +{ + i2c_master_enable(); + if(i2c_single_send(TSL2563_ADDR, reg) == I2C_MASTER_ERR_NONE) { + while(i2c_master_busy()); + if(i2c_burst_receive(TSL2563_ADDR, buf, regNum) == I2C_MASTER_ERR_NONE) { + return TSL2563_SUCCESS; + } + } + return TSL2563_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +tsl2563_write_reg(uint8_t *buf, uint8_t num) +{ + if((buf == NULL) || (num <= 0)) { + PRINTF("TSL2563: invalid write values\n"); + return TSL2563_ERROR; + } + + i2c_master_enable(); + if(i2c_burst_send(TSL2563_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { + return TSL2563_SUCCESS; + } + return TSL2563_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +tsl2563_on(void) +{ + uint8_t buf[2]; + buf[0] = (TSL2563_COMMAND + TSL2563_CONTROL); + buf[1] = TSL2563_CONTROL_POWER_ON; + + if(tsl2563_write_reg(buf, 2) == I2C_MASTER_ERR_NONE) { + if(i2c_single_receive(TSL2563_ADDR, &buf[0]) == I2C_MASTER_ERR_NONE) { + if((buf[0] & 0x0F) == TSL2563_CONTROL_POWER_ON) { + PRINTF("TSL2563: powered on\n"); + return TSL2563_SUCCESS; + } + } + } + + PRINTF("TSL2563: failed to power on\n"); + return TSL2563_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +tsl2563_id_register(uint8_t *buf) +{ + if(tsl2563_read_reg((TSL2563_COMMAND + TSL2563_ID_REG), + buf, 1) == TSL2563_SUCCESS) { + PRINTF("TSL2563: partnum/revnum 0x%02X\n", *buf); + return TSL2563_SUCCESS; + } + + return TSL2563_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +tsl2563_off(void) +{ + uint8_t buf[2]; + buf[0] = (TSL2563_COMMAND + TSL2563_CONTROL); + buf[1] = TSL2563_CONTROL_POWER_OFF; + + if(tsl2563_write_reg(buf, 2) == I2C_MASTER_ERR_NONE) { + PRINTF("TSL2563: powered off\n"); + return TSL2563_SUCCESS; + } + + PRINTF("TSL2563: failed to power off\n"); + return TSL2563_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +tsl2563_clear_interrupt(void) +{ + uint8_t buf = (TSL2563_COMMAND + TSL2563_CLEAR_INTERRUPT); + if(tsl2563_write_reg(&buf, 1) != I2C_MASTER_ERR_NONE) { + PRINTF("TSL2563: failed to clear the interrupt\n"); + return TSL2563_ERROR; + } + return TSL2563_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +tsl2563_read_sensor(uint16_t *lux) +{ + uint8_t buf[4]; + + /* This is hardcoded to use word write/read operations */ + if(tsl2563_read_reg((TSL2563_COMMAND + TSL2563_D0LOW), + &buf[0], 2) == TSL2563_SUCCESS) { + if(tsl2563_read_reg((TSL2563_COMMAND + TSL2563_D1LOW), + &buf[2], 2) == TSL2563_SUCCESS) { + + PRINTF("TSL2563: CH0 0x%02X%02X CH1 0x%02X%02X\n", buf[1], buf[0], + buf[3], buf[2]); + *lux = calculate_lux(buf); + return TSL2563_SUCCESS; + } + } + PRINTF("TSL2563: failed to read\n"); + return TSL2563_ERROR; +} +/*---------------------------------------------------------------------------*/ +PROCESS(tsl2563_int_process, "TSL2563 interrupt process handler"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(tsl2563_int_process, ev, data) +{ + PROCESS_EXITHANDLER(); + PROCESS_BEGIN(); + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + tsl2563_clear_interrupt(); + tsl2563_int_callback(0); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +static void +tsl2563_interrupt_handler(uint8_t port, uint8_t pin) +{ + /* There's no alert/interruption flag to check, clear the interruption by + * writting to the CLEAR bit in the COMMAND register + */ + process_poll(&tsl2563_int_process); +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + uint8_t buf[3]; + + if((type != TSL2563_ACTIVE) && (type != TSL2563_INT_OVER) && + (type != TSL2563_INT_BELOW) && (type != TSL2563_INT_DISABLE) && + (type != TSL2563_TIMMING_CFG)) { + PRINTF("TSL2563: invalid start value\n"); + return TSL2563_ERROR; + } + + /* As default the power-on values of the sensor are gain 1X, 402ms integration + * time (not nominal), with manual control disabled + */ + + if(type == TSL2563_ACTIVE) { + if(value) { + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_NORMAL_BUS_SPEED); + + /* Initialize interrupts handlers */ + tsl2563_int_callback = NULL; + + /* Power on the sensor and check for the part number */ + if(tsl2563_on() == TSL2563_SUCCESS) { + if(tsl2563_id_register(&buf[0]) == TSL2563_SUCCESS) { + if((buf[0] & TSL2563_ID_PARTNO_MASK) == TSL2563_EXPECTED_PARTNO) { + + /* Read the timming/gain configuration */ + if(tsl2563_read_reg((TSL2563_COMMAND + TSL2563_TIMMING), + &buf[0], 1) == TSL2563_SUCCESS) { + gain = buf[0] & TSL2563_TIMMING_GAIN; + timming = buf[0] & TSL2563_TIMMING_INTEG_MASK; + PRINTF("TSL2563: enabled, timming %u gain %u\n", timming, gain); + + /* Restart the over interrupt threshold */ + buf[0] = (TSL2563_COMMAND + TSL2563_THRHIGHLOW); + buf[1] = 0xFF; + buf[2] = 0xFF; + + if(tsl2563_write_reg(buf, 3) != TSL2563_SUCCESS) { + PRINTF("TSL2563: failed to clear over interrupt\n"); + return TSL2563_ERROR; + } + + /* Restart the below interrupt threshold */ + buf[0] = (TSL2563_COMMAND + TSL2563_THRLOWLOW); + buf[1] = 0x00; + buf[2] = 0x00; + + if(tsl2563_write_reg(buf, 3) != TSL2563_SUCCESS) { + PRINTF("TSL2563: failed to clear below interrupt\n"); + return TSL2563_ERROR; + } + + /* Clear any pending interrupt */ + if(tsl2563_clear_interrupt() == TSL2563_SUCCESS) { + enabled = 1; + return TSL2563_SUCCESS; + } + } + } + } + } + return TSL2563_ERROR; + } else { + if(tsl2563_off() == TSL2563_SUCCESS) { + PRINTF("TSL2563: stopped\n"); + enabled = 0; + return TSL2563_SUCCESS; + } + return TSL2563_ERROR; + } + } + + if(!enabled) { + PRINTF("TSL2563: sensor not started\n"); + return TSL2563_ERROR; + } + + if(type == TSL2563_INT_DISABLE) { + + /* Ensure the GPIO doesn't generate more interrupts, this may affect others + * I2C digital sensors using the bus and sharing this pin, so an user may + * comment the line below + */ + GPIO_DISABLE_INTERRUPT(TSL2563_INT_PORT_BASE, TSL2563_INT_PIN_MASK); + + /* This also wipes out the persistance value, to be reconfigured when + * enabling back the interruption + */ + buf[0] = (TSL2563_COMMAND + TSL2563_INTERRUPT); + buf[1] = TSL2563_INTR_DISABLED; + + if(tsl2563_write_reg(buf, 2) != TSL2563_SUCCESS) { + PRINTF("TSL2563: failed to disable the interrupt\n"); + return TSL2563_ERROR; + } + return TSL2563_SUCCESS; + } + + /* Configure the timming and gain */ + if(type == TSL2563_TIMMING_CFG) { + if((value != TSL2563_G16X_402MS) && (value != TSL2563_G1X_402MS) && + (value != TSL2563_G1X_101MS) && (value != TSL2563_G1X_13_7MS)) { + PRINTF("TSL2563: invalid timming configuration values\n"); + return TSL2563_ERROR; + } + + buf[0] = (TSL2563_COMMAND + TSL2563_TIMMING); + buf[1] = value; + + if(tsl2563_write_reg(buf, 2) == TSL2563_SUCCESS) { + if(value == TSL2563_G16X_402MS) { + gain = 1; + } + + switch(value) { + case TSL2563_G16X_402MS: + case TSL2563_G1X_402MS: + timming = TSL2563_TIMMING_INTEG_402MS; + break; + case TSL2563_G1X_101MS: + timming = TSL2563_TIMMING_INTEG_101MS; + break; + case TSL2563_G1X_13_7MS: + timming = TSL2563_TIMMING_INTEG_13_7MS; + break; + } + + PRINTF("TSL2563: new timming %u gain %u\n", timming, gain); + return TSL2563_SUCCESS; + } + PRINTF("TSL2563: failed to configure timming\n"); + return TSL2563_ERROR; + } + + /* From here we handle the interrupt configuration, it requires the interrupt + * callback handler to have been previously set using the TSL2563_REGISTER_INT + * macro + */ + + buf[1] = ((uint8_t *)&value)[0]; + buf[2] = ((uint8_t *)&value)[1]; + + if(type == TSL2563_INT_OVER) { + buf[0] = (TSL2563_COMMAND + TSL2563_THRHIGHLOW); + } else if(type == TSL2563_INT_BELOW) { + buf[0] = (TSL2563_COMMAND + TSL2563_THRLOWLOW); + } + + if(tsl2563_write_reg(buf, 3) != TSL2563_SUCCESS) { + PRINTF("TSL2563: failed to set interrupt level\n"); + return TSL2563_ERROR; + } + + /* Now configure the interruption register (level interrupt, 2 integration + * cycles after threshold has been reached (roughly 804ms if timming is 402ms) + */ + buf[0] = (TSL2563_COMMAND + TSL2563_INTERRUPT); + buf[1] = (TSL2563_INTR_LEVEL << TSL2563_INTR_SHIFT); + buf[1] += TSL2563_INT_PERSIST_2_CYCLES; + + if(tsl2563_write_reg(buf, 2) != TSL2563_SUCCESS) { + PRINTF("TSL2563: failed to enable interrupt\n"); + return TSL2563_ERROR; + } + + /* Configure the interrupts pins */ + GPIO_SOFTWARE_CONTROL(TSL2563_INT_PORT_BASE, TSL2563_INT_PIN_MASK); + GPIO_SET_INPUT(TSL2563_INT_PORT_BASE, TSL2563_INT_PIN_MASK); + + /* Pull-up resistor, detect falling edge */ + GPIO_DETECT_EDGE(TSL2563_INT_PORT_BASE, TSL2563_INT_PIN_MASK); + GPIO_TRIGGER_SINGLE_EDGE(TSL2563_INT_PORT_BASE, TSL2563_INT_PIN_MASK); + GPIO_DETECT_FALLING(TSL2563_INT_PORT_BASE, TSL2563_INT_PIN_MASK); + gpio_register_callback(tsl2563_interrupt_handler, I2C_INT_PORT, I2C_INT_PIN); + + /* Spin process until an interrupt is received */ + process_start(&tsl2563_int_process, NULL); + + /* Enable interrupts */ + GPIO_ENABLE_INTERRUPT(TSL2563_INT_PORT_BASE, TSL2563_INT_PIN_MASK); + + /* The RE-Mote revision A has this pin shared and with a pull-down resistor, + * for other platforms (like the firefly), change to enable pull-up internal + * resistor instead if no external pull-up is present. + */ + ioc_set_over(I2C_INT_PORT, I2C_INT_PIN, IOC_OVERRIDE_PUE); + nvic_interrupt_enable(I2C_INT_VECTOR); + + PRINTF("TSL2563: Interrupt configured\n"); + return TSL2563_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + uint16_t lux; + + if(!enabled) { + PRINTF("TSL2563: sensor not started\n"); + return TSL2563_ERROR; + } + + if(type == TSL2563_VAL_READ) { + if(tsl2563_read_sensor(&lux) != TSL2563_ERROR) { + return lux; + } + PRINTF("TSL2563: fail to read\n"); + } + return TSL2563_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(tsl2563, TSL2563_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/tsl2563.h b/platform/zoul/dev/tsl2563.h new file mode 100644 index 000000000..f8619140e --- /dev/null +++ b/platform/zoul/dev/tsl2563.h @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-tsl2563-sensor TSL2563 Sensor + * + * Driver for the TSL2563 sensor + * + * The TSL2563 driver returns the converted light value value in lux + * @{ + * + * \file + * Header file for the external TSL2563 Sensor Driver + * + * \author + * Antonio Lignan + * Toni Lozano + */ +/*---------------------------------------------------------------------------*/ +#ifndef TSL2563_H_ +#define TSL2563_H_ +#include +#include "lib/sensors.h" +#include "dev/zoul-sensors.h" +#include "i2c.h" +/* -------------------------------------------------------------------------- */ +/** + * \name TSL2563 digital Light sensor address and registers + * @{ + */ +/* -------------------------------------------------------------------------- */ +#define TSL2563_ADDR 0x39 +/* -------------------------------------------------------------------------- */ +#define TSL2563_CONTROL 0x00 +#define TSL2563_TIMMING 0x01 +#define TSL2563_THRLOWLOW 0x02 +#define TSL2563_THRLOWHIGH 0x03 +#define TSL2563_THRHIGHLOW 0x04 +#define TSL2563_THRHIGHHIGH 0x05 +#define TSL2563_INTERRUPT 0x06 +#define TSL2563_CRC 0x08 +#define TSL2563_ID_REG 0x0A +#define TSL2563_D0LOW 0x0C +#define TSL2563_D0HIGH 0x0D +#define TSL2563_D1LOW 0x0E +#define TSL2563_D1HIGH 0x0F +/* -------------------------------------------------------------------------- */ +/* Uses the word read/write operation protocol */ +#define TSL2563_COMMAND 0xA0 +#define TSL2563_CLEAR_INTERRUPT 0x40 +/* -------------------------------------------------------------------------- */ +#define TSL2563_CONTROL_POWER_ON 0x03 +#define TSL2563_CONTROL_POWER_OFF 0x00 +#define TSL2563_TIMMING_GAIN 0x10 +#define TSL2563_TIMMING_MANUAL 0x08 +#define TSL2563_TIMMING_INTEG_MANUAL 0x03 +#define TSL2563_TIMMING_INTEG_402MS 0x02 +#define TSL2563_TIMMING_INTEG_101MS 0x01 +#define TSL2563_TIMMING_INTEG_13_7MS 0x00 +#define TSL2563_TIMMING_INTEG_MASK 0x03 + +#define TSL2563_G16X_402MS (TSL2563_TIMMING_INTEG_402MS + TSL2563_TIMMING_GAIN) +#define TSL2563_G1X_402MS TSL2563_TIMMING_INTEG_402MS +#define TSL2563_G1X_101MS TSL2563_TIMMING_INTEG_101MS +#define TSL2563_G1X_13_7MS TSL2563_TIMMING_INTEG_13_7MS + +#define TSL2563_INTR_SHIFT 0x04 +#define TSL2563_INTR_DISABLED 0x00 +#define TSL2563_INTR_LEVEL 0x01 +#define TSL2563_INTR_SMB_ALERT 0x02 +#define TSL2563_INTR_TEST 0x03 + +#define TSL2563_INT_PERSIST_EVERY 0x00 +#define TSL2563_INT_PERSIST_ANY 0x01 +#define TSL2563_INT_PERSIST_2_CYCLES 0x02 +#define TSL2563_INT_PERSIST_3_CYCLES 0x03 +#define TSL2563_INT_PERSIST_4_CYCLES 0x04 +#define TSL2563_INT_PERSIST_5_CYCLES 0x05 +#define TSL2563_INT_PERSIST_6_CYCLES 0x06 +#define TSL2563_INT_PERSIST_7_CYCLES 0x07 +#define TSL2563_INT_PERSIST_8_CYCLES 0x08 +#define TSL2563_INT_PERSIST_9_CYCLES 0x09 +#define TSL2563_INT_PERSIST_10_CYCLES 0x0A +#define TSL2563_INT_PERSIST_11_CYCLES 0x0B +#define TSL2563_INT_PERSIST_12_CYCLES 0x0C +#define TSL2563_INT_PERSIST_13_CYCLES 0x0D +#define TSL2563_INT_PERSIST_14_CYCLES 0x0E +#define TSL2563_INT_PERSIST_15_CYCLES 0x0F + +#define TSL2563_ID_PARTNO_MASK 0xF0 +#define TSL2563_ID_REV_MASK 0x0F +#define TSL2563_EXPECTED_PARTNO 0x30 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name TSL2563 convertion and calibration values + * @{ + */ + +#define LUX_SCALE 14 /**< scale by 2^14 */ +#define RATIO_SCALE 9 /**< scale ratio */ +#define CH_SCALE 10 /**< scale channel values by 2^10 */ +#define CHSCALE_TINT0 0x7517 /**< 322/11 * 2^CH_SCALE */ +#define CHSCALE_TINT1 0x0fe7 /**< 322/81 * 2^CH_SCALE */ + +/* T/FN/CL package coefficients (hardcoded) */ +#define K1T 0X0040 +#define B1T 0x01f2 +#define M1T 0x01b2 +#define K2T 0x0080 +#define B2T 0x0214 +#define M2T 0x02d1 +#define K3T 0x00c0 +#define B3T 0x023f +#define M3T 0x037b +#define K4T 0x0100 +#define B4T 0x0270 +#define M4T 0x03fe +#define K5T 0x0138 +#define B5T 0x016f +#define M5T 0x01fc +#define K6T 0x019a +#define B6T 0x00d2 +#define M6T 0x00fb +#define K7T 0x029a +#define B7T 0x0018 +#define M7T 0x0012 +#define K8T 0x029a +#define B8T 0x0000 +#define M8T 0x0000 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Callback function to handle the TSL2563 alarm interrupt and macro + * @{ + */ +#define TSL2563_REGISTER_INT(ptr) tsl2563_int_callback = ptr; +extern void (*tsl2563_int_callback)(uint8_t value); +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name TSL2563 return and command values + * @{ + */ +#define TSL2563_SUCCESS 0x00 +#define TSL2563_LIGHT 0x01 +#define TSL2563_ERROR -1 + +#define TSL2563_ACTIVE SENSORS_ACTIVE +#define TSL2563_INT_OVER HW_INT_OVER_THRS +#define TSL2563_INT_BELOW HW_INT_BELOW_THRS +#define TSL2563_INT_DISABLE HW_INT_DISABLE +#define TSL2563_TIMMING_CFG (HW_INT_DISABLE + 1) + +#define TSL2563_VAL_READ 0x01 +/** @} */ +/* -------------------------------------------------------------------------- */ +#define TSL2563_SENSOR "TSL2563 Light Sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor tsl2563; +/* -------------------------------------------------------------------------- */ +#endif +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ + diff --git a/platform/zoul/dev/weather-meter.c b/platform/zoul/dev/weather-meter.c new file mode 100644 index 000000000..a0d2b1e90 --- /dev/null +++ b/platform/zoul/dev/weather-meter.c @@ -0,0 +1,489 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-weather-meter-sensor + * @{ + * + * The Sparkfun's weather meter comprises an anemometer, wind vane and rain + * gauge, see https://www.sparkfun.com/products/8942 + * + * \file + * Weather meter sensor driver + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/adc-zoul.h" +#include "dev/weather-meter.h" +#include "dev/zoul-sensors.h" +#include "lib/sensors.h" +#include "dev/sys-ctrl.h" +#include "dev/gpio.h" +#include "dev/ioc.h" +#include "sys/timer.h" +#include "sys/ctimer.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +#define DEBOUNCE_DURATION (CLOCK_SECOND >> 6) +/*---------------------------------------------------------------------------*/ +#define ANEMOMETER_SENSOR_PORT_BASE GPIO_PORT_TO_BASE(ANEMOMETER_SENSOR_PORT) +#define ANEMOMETER_SENSOR_PIN_MASK GPIO_PIN_MASK(ANEMOMETER_SENSOR_PIN) +#define RAIN_GAUGE_SENSOR_PORT_BASE GPIO_PORT_TO_BASE(RAIN_GAUGE_SENSOR_PORT) +#define RAIN_GAUGE_SENSOR_PIN_MASK GPIO_PIN_MASK(RAIN_GAUGE_SENSOR_PIN) +/*---------------------------------------------------------------------------*/ +void (*rain_gauge_int_callback)(uint16_t value); +void (*anemometer_int_callback)(uint16_t value); +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +process_event_t anemometer_int_event; +process_event_t rain_gauge_int_event; +/*---------------------------------------------------------------------------*/ +static struct ctimer ct; +static struct timer debouncetimer; +/*---------------------------------------------------------------------------*/ +typedef struct { + uint16_t ticks; + uint16_t value; + uint8_t int_en; + uint16_t int_thres; +} weather_meter_sensors_t; + +typedef struct { + uint16_t value_max; + uint64_t ticks_avg; + uint64_t value_avg; + uint32_t value_buf_xm; + uint16_t value_avg_xm; +} weather_meter_ext_t; + +typedef struct { + uint16_t wind_vane; + weather_meter_sensors_t rain_gauge; + weather_meter_sensors_t anemometer; +} weather_meter_sensors; + +typedef struct { + int32_t value_buf_xm; + int16_t value_prev; + int16_t value_avg_xm; +} weather_meter_wind_vane_ext_t; + +static weather_meter_sensors weather_sensors; +static weather_meter_ext_t anemometer; +static weather_meter_wind_vane_ext_t wind_vane; +/*---------------------------------------------------------------------------*/ +typedef struct { + uint16_t mid_point; + uint16_t degree; +} wind_vane_mid_point_t; + +/* From the datasheet we adjusted the values for a 3V divider, using a 10K + * resistor, the check values are the following: + * --------------------+------------------+------------------------------- + * Direction (Degrees) Resistance (Ohms) Voltage (mV) + * 0 33k 2532.55 * + * 22.5 6.57k 1308.44 * + * 45 8.2k 1486.81 * + * 67.5 891 269.97 * + * 90 1k 300.00 * + * 112.5 688 212.42 * + * 135 2.2k 595.08 * + * 157.5 1.41k 407.80 * + * 180 3.9k 925.89 * + * 202.5 3.14k 788.58 * + * 225 16k 2030.76 * + * 247.5 14.12k 1930.84 * + * 270 120k 3046.15 * + * 292.5 42.12k 2666.84 * + * 315 64.9k 2859.41 * + * 337.5 21.88k 2264.86 * + * --------------------+------------------+------------------------------- + */ +static const wind_vane_mid_point_t wind_vane_table[16] = { + { 2124, 1125 }, + { 2699, 675 }, + { 3000, 900 }, + { 4078, 1575 }, + { 5950, 1350 }, + { 7885, 2025 }, + { 9258, 1800 }, + { 13084, 225 }, + { 14868, 450 }, + { 19308, 2475 }, + { 20307, 2250 }, + { 22648, 3375 }, + { 25325, 0 }, + { 26668, 2925 }, + { 28594, 3150 }, + { 30461, 2700 }, +}; +/*---------------------------------------------------------------------------*/ +static int +weather_meter_wind_vane_degrees(uint16_t value) +{ + uint8_t i; + for(i = 0; i < 16; i++) { + if(value <= wind_vane_table[i].mid_point) { + return (int)wind_vane_table[i].degree; + } else { + if(i == 15) { + return (int)wind_vane_table[i].degree; + } + } + } + + PRINTF("Weather: invalid wind vane value\n"); + return WEATHER_METER_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +weather_meter_get_wind_dir(void) +{ + weather_sensors.wind_vane = adc_zoul.value(WIND_VANE_ADC); + if((int16_t)weather_sensors.wind_vane < 0) { + weather_sensors.wind_vane = 0; + } + return weather_meter_wind_vane_degrees(weather_sensors.wind_vane); +} +/*---------------------------------------------------------------------------*/ +static void +ct_callback(void *ptr) +{ + uint32_t wind_speed; + int16_t wind_dir; + int16_t wind_dir_delta; + + /* Disable to make the calculations in an interrupt-safe context */ + GPIO_DISABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, + ANEMOMETER_SENSOR_PIN_MASK); + wind_speed = weather_sensors.anemometer.ticks; + wind_speed *= WEATHER_METER_ANEMOMETER_SPEED_1S; + weather_sensors.anemometer.value = (uint16_t)wind_speed; + anemometer.ticks_avg++; + anemometer.value_avg += weather_sensors.anemometer.value; + anemometer.value_buf_xm += weather_sensors.anemometer.value; + + /* Take maximum value */ + if(weather_sensors.anemometer.value > anemometer.value_max) { + anemometer.value_max = weather_sensors.anemometer.value; + } + + /* Mitsuta method to get the wind direction average */ + wind_dir = weather_meter_get_wind_dir(); + wind_dir_delta = wind_dir - wind_vane.value_prev; + + if(wind_dir_delta < -1800) { + wind_vane.value_prev += wind_dir_delta + 3600; + } else if(wind_dir_delta > 1800) { + wind_vane.value_prev += wind_dir_delta - 3600; + } else { + wind_vane.value_prev += wind_dir_delta; + } + + wind_vane.value_buf_xm += wind_vane.value_prev; + + /* Calculate the 2 minute average */ + if(!(anemometer.ticks_avg % WEATHER_METER_AVG_PERIOD)) { + PRINTF("\nWeather: calculate the %u averages ***\n", WEATHER_METER_AVG_PERIOD); + + if(anemometer.value_buf_xm) { + anemometer.value_avg_xm = anemometer.value_buf_xm / WEATHER_METER_AVG_PERIOD; + anemometer.value_buf_xm = 0; + } else { + anemometer.value_avg_xm = 0; + } + + if(wind_vane.value_buf_xm >= 0) { + wind_vane.value_buf_xm = wind_vane.value_buf_xm / WEATHER_METER_AVG_PERIOD; + wind_vane.value_avg_xm = wind_vane.value_buf_xm; + } else { + wind_vane.value_buf_xm = ABS(wind_vane.value_buf_xm) / WEATHER_METER_AVG_PERIOD; + wind_vane.value_avg_xm = wind_vane.value_buf_xm; + wind_vane.value_avg_xm = ~wind_vane.value_avg_xm + 1; + } + + if(wind_vane.value_avg_xm >= 3600) { + wind_vane.value_avg_xm -= 3600; + } else if(wind_vane.value_avg_xm < 0) { + wind_vane.value_avg_xm += 3600; + } + + wind_vane.value_buf_xm = 0; + wind_vane.value_prev = wind_dir; + } + + /* Check for roll-over */ + if(!anemometer.ticks_avg) { + anemometer.value_avg = 0; + } + + weather_sensors.anemometer.ticks = 0; + + /* Enable the interrupt again */ + GPIO_ENABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, + ANEMOMETER_SENSOR_PIN_MASK); + + ctimer_set(&ct, CLOCK_SECOND, ct_callback, NULL); +} +/*---------------------------------------------------------------------------*/ +PROCESS(weather_meter_int_process, "Weather meter interrupt process handler"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(weather_meter_int_process, ev, data) +{ + PROCESS_EXITHANDLER(); + PROCESS_BEGIN(); + + while(1) { + PROCESS_YIELD(); + + if((ev == anemometer_int_event) && (weather_sensors.anemometer.int_en)) { + if(weather_sensors.anemometer.ticks >= + weather_sensors.anemometer.int_thres) { + anemometer_int_callback(weather_sensors.anemometer.ticks); + } + } + + if((ev == rain_gauge_int_event) && (weather_sensors.rain_gauge.int_en)) { + if(weather_sensors.rain_gauge.ticks >= + weather_sensors.rain_gauge.int_thres) { + rain_gauge_int_callback(weather_sensors.rain_gauge.ticks); + } + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +static void +weather_meter_interrupt_handler(uint8_t port, uint8_t pin) +{ + uint32_t aux; + + /* Prevent bounce events */ + if(!timer_expired(&debouncetimer)) { + return; + } + + timer_set(&debouncetimer, DEBOUNCE_DURATION); + + /* We make a process_post() to check in the pollhandler any specific threshold + * value + */ + + if((port == ANEMOMETER_SENSOR_PORT) && (pin == ANEMOMETER_SENSOR_PIN)) { + weather_sensors.anemometer.ticks++; + process_post(&weather_meter_int_process, anemometer_int_event, NULL); + } else if((port == RAIN_GAUGE_SENSOR_PORT) && (pin == RAIN_GAUGE_SENSOR_PIN)) { + weather_sensors.rain_gauge.ticks++; + aux = weather_sensors.rain_gauge.ticks * WEATHER_METER_AUX_RAIN_MM; + aux /= 1000; + weather_sensors.rain_gauge.value = (uint16_t)aux; + process_post(&weather_meter_int_process, rain_gauge_int_event, NULL); + } +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + uint64_t aux; + + if((type != WEATHER_METER_ANEMOMETER) && + (type != WEATHER_METER_RAIN_GAUGE) && + (type != WEATHER_METER_WIND_VANE) && + (type != WEATHER_METER_WIND_VANE_AVG_X) && + (type != WEATHER_METER_ANEMOMETER_AVG) && + (type != WEATHER_METER_ANEMOMETER_AVG_X) && + (type != WEATHER_METER_ANEMOMETER_MAX)) { + PRINTF("Weather: requested an invalid sensor value\n"); + return WEATHER_METER_ERROR; + } + + if(!enabled) { + PRINTF("Weather: module is not configured\n"); + return WEATHER_METER_ERROR; + } + + switch(type) { + case WEATHER_METER_WIND_VANE: + return weather_meter_get_wind_dir(); + + case WEATHER_METER_WIND_VANE_AVG_X: + return wind_vane.value_avg_xm; + + case WEATHER_METER_ANEMOMETER: + return weather_sensors.anemometer.value; + + case WEATHER_METER_ANEMOMETER_AVG: + if(anemometer.value_avg <= 0) { + return (uint16_t)anemometer.value_avg; + } + aux = anemometer.value_avg / anemometer.ticks_avg; + return (uint16_t)aux; + + case WEATHER_METER_ANEMOMETER_AVG_X: + return anemometer.value_avg_xm; + + case WEATHER_METER_ANEMOMETER_MAX: + return anemometer.value_max; + + /* as the default return type is int, we have a lower resolution if returning + * the calculated value as it is truncated, an alternative is returning the + * ticks and calculating on your own with WEATHER_METER_AUX_RAIN_MM + */ + case WEATHER_METER_RAIN_GAUGE: +#if WEATHER_METER_RAIN_RETURN_TICKS + return weather_sensors.rain_gauge.ticks; +#else + return weather_sensors.rain_gauge.value; +#endif + + default: + return WEATHER_METER_ERROR; + } +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if((type != WEATHER_METER_ACTIVE) && + (type != WEATHER_METER_ANEMOMETER_INT_OVER) && + (type != WEATHER_METER_RAIN_GAUGE_INT_OVER) && + (type != WEATHER_METER_ANEMOMETER_INT_DIS) && + (type != WEATHER_METER_RAIN_GAUGE_INT_DIS)) { + PRINTF("Weather: invalid configuration option\n"); + return WEATHER_METER_ERROR; + } + + if(type == WEATHER_METER_ACTIVE) { + + anemometer.value_avg = 0; + anemometer.ticks_avg = 0; + + weather_sensors.anemometer.int_en = 0; + weather_sensors.rain_gauge.int_en = 0; + weather_sensors.anemometer.ticks = 0; + weather_sensors.rain_gauge.ticks = 0; + weather_sensors.anemometer.value = 0; + weather_sensors.rain_gauge.value = 0; + + if(!value) { + anemometer_int_callback = NULL; + rain_gauge_int_callback = NULL; + GPIO_DISABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, + ANEMOMETER_SENSOR_PIN_MASK); + GPIO_DISABLE_INTERRUPT(RAIN_GAUGE_SENSOR_PORT_BASE, + RAIN_GAUGE_SENSOR_PIN_MASK); + process_exit(&weather_meter_int_process); + enabled = 0; + PRINTF("Weather: disabled\n"); + return WEATHER_METER_SUCCESS; + } + + /* Configure the wind vane */ + adc_zoul.configure(SENSORS_HW_INIT, WIND_VANE_ADC); + + /* Configure anemometer interruption */ + GPIO_SOFTWARE_CONTROL(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); + GPIO_SET_INPUT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); + GPIO_DETECT_RISING(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); + GPIO_TRIGGER_SINGLE_EDGE(ANEMOMETER_SENSOR_PORT_BASE, + ANEMOMETER_SENSOR_PIN_MASK); + ioc_set_over(ANEMOMETER_SENSOR_PORT, ANEMOMETER_SENSOR_PIN, IOC_OVERRIDE_DIS); + gpio_register_callback(weather_meter_interrupt_handler, ANEMOMETER_SENSOR_PORT, + ANEMOMETER_SENSOR_PIN); + + /* Configure rain gauge interruption */ + GPIO_SOFTWARE_CONTROL(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); + GPIO_SET_INPUT(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); + GPIO_DETECT_RISING(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); + GPIO_TRIGGER_SINGLE_EDGE(RAIN_GAUGE_SENSOR_PORT_BASE, + RAIN_GAUGE_SENSOR_PIN_MASK); + ioc_set_over(RAIN_GAUGE_SENSOR_PORT, RAIN_GAUGE_SENSOR_PIN, IOC_OVERRIDE_DIS); + gpio_register_callback(weather_meter_interrupt_handler, RAIN_GAUGE_SENSOR_PORT, + RAIN_GAUGE_SENSOR_PIN); + + process_start(&weather_meter_int_process, NULL); + + /* Initialize here prior the first second tick */ + wind_vane.value_prev = weather_meter_get_wind_dir(); + + ctimer_set(&ct, CLOCK_SECOND, ct_callback, NULL); + + GPIO_ENABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); + GPIO_ENABLE_INTERRUPT(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); + nvic_interrupt_enable(ANEMOMETER_SENSOR_VECTOR); + nvic_interrupt_enable(RAIN_GAUGE_SENSOR_VECTOR); + + enabled = 1; + PRINTF("Weather: started\n"); + return WEATHER_METER_SUCCESS; + } + + switch(type) { + case WEATHER_METER_ANEMOMETER_INT_OVER: + weather_sensors.anemometer.int_en = 1; + weather_sensors.anemometer.int_thres = value; + PRINTF("Weather: anemometer threshold %u\n", value); + break; + case WEATHER_METER_RAIN_GAUGE_INT_OVER: + weather_sensors.rain_gauge.int_en = 1; + weather_sensors.rain_gauge.int_thres = value; + PRINTF("Weather: rain gauge threshold %u\n", value); + break; + case WEATHER_METER_ANEMOMETER_INT_DIS: + PRINTF("Weather: anemometer int disabled\n"); + weather_sensors.anemometer.int_en = 0; + break; + case WEATHER_METER_RAIN_GAUGE_INT_DIS: + PRINTF("Weather: rain gauge int disabled\n"); + weather_sensors.rain_gauge.int_en = 0; + break; + default: + return WEATHER_METER_ERROR; + } + + return WEATHER_METER_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(weather_meter, WEATHER_METER_SENSOR, value, configure, NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ + diff --git a/platform/zoul/dev/weather-meter.h b/platform/zoul/dev/weather-meter.h new file mode 100644 index 000000000..9f6d1fc7f --- /dev/null +++ b/platform/zoul/dev/weather-meter.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-weather-meter-sensor Sparkfun's weather meter + * @{ + * + * \file + * Weather meter header file + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "dev/zoul-sensors.h" +/* -------------------------------------------------------------------------- */ +#ifndef WEATHER_METER_H_ +#define WEATHER_METER_H_ +/* -------------------------------------------------------------------------- */ +/** + * \name Weather meter sensor return and operation values + * @{ + */ +#define WEATHER_METER_RAIN_GAUGE 0x01 +#define WEATHER_METER_WIND_VANE 0x02 +#define WEATHER_METER_WIND_VANE_AVG_X 0x03 +#define WEATHER_METER_ANEMOMETER 0x04 +#define WEATHER_METER_ANEMOMETER_AVG 0x05 +#define WEATHER_METER_ANEMOMETER_AVG_X 0x06 +#define WEATHER_METER_ANEMOMETER_MAX 0x07 + +/* Period (seconds) to calculate an average */ +#ifdef WEATHER_METER_CONF_AVG_PERIOD +#define WEATHER_METER_AVG_PERIOD WEATHER_METER_CONF_AVG_PERIOD +#else +#define WEATHER_METER_AVG_PERIOD 120 +#endif + +#define WEATHER_METER_ACTIVE SENSORS_ACTIVE +#define WEATHER_METER_ANEMOMETER_INT_OVER HW_INT_OVER_THRS +#define WEATHER_METER_ANEMOMETER_INT_DIS HW_INT_DISABLE +#define WEATHER_METER_RAIN_GAUGE_INT_OVER (HW_INT_OVER_THRS << 1) +#define WEATHER_METER_RAIN_GAUGE_INT_DIS (HW_INT_DISABLE << 1) + +#define WEATHER_METER_SUCCESS 0 +#define WEATHER_METER_ERROR (-1) + +/* 2.4Km/h per tick, 2 per rotation */ +#define WEATHER_METER_ANEMOMETER_SPEED_1S (1200) + +/* 0.2794mm per tick */ +#define WEATHER_METER_AUX_RAIN_MM 2794 + +/* Allows to select the return type: ticks or converted value (truncated) */ +#ifdef WEATHER_METER_RAIN_CONF_RETURN +#define WEATHER_METER_RAIN_RETURN_TICKS WEATHER_METER_RAIN_CONF_RETURN +#else +#define WEATHER_METER_RAIN_RETURN_TICKS 1 +#endif +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Anemometer and rain gauge sensor interrupt callback macro + * @{ + */ +#define WEATHER_METER_REGISTER_ANEMOMETER_INT(ptr) anemometer_int_callback = ptr; +#define WEATHER_METER_REGISTER_RAIN_GAUGE_INT(ptr) rain_gauge_int_callback = ptr; +extern void (*anemometer_int_callback)(uint16_t value); +extern void (*rain_gauge_int_callback)(uint16_t value); +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Weather meter's anemometer default pin, port and interrupt vector + * @{ + */ +#ifdef WEATHER_METER_CONF_ANEMOMETER_PIN +#define ANEMOMETER_SENSOR_PIN WEATHER_METER_CONF_ANEMOMETER_PIN +#else +#define ANEMOMETER_SENSOR_PIN 1 +#endif +#ifdef WEATHER_METER_CONF_ANEMOMETER_PORT +#define ANEMOMETER_SENSOR_PORT WEATHER_METER_CONF_ANEMOMETER_PORT +#else +#define ANEMOMETER_SENSOR_PORT GPIO_D_NUM +#endif +#ifdef WEATHER_METER_CONF_ANEMOMETER_VECTOR +#define ANEMOMETER_SENSOR_VECTOR WEATHER_METER_CONF_ANEMOMETER_VECTOR +#else +#define ANEMOMETER_SENSOR_VECTOR NVIC_INT_GPIO_PORT_D +#endif +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Weather meter's rain gauge default pin, port and interrupt vector + * @{ + */ +#ifdef WEATHER_METER_CONF_RAIN_GAUGE_PIN +#define RAIN_GAUGE_SENSOR_PIN WEATHER_METER_CONF_RAIN_GAUGE_PIN +#else +#define RAIN_GAUGE_SENSOR_PIN 2 +#endif +#ifdef WEATHER_METER_CONF_RAIN_GAUGE_PORT +#define RAIN_GAUGE_SENSOR_PORT WEATHER_METER_CONF_RAIN_GAUGE_PORT +#else +#define RAIN_GAUGE_SENSOR_PORT GPIO_D_NUM +#endif +#ifdef WEATHER_METER_CONF_RAIN_GAUGE_VECTOR +#define RAIN_GAUGE_SENSOR_VECTOR WEATHER_METER_CONF_RAIN_GAUGE_VECTOR +#else +#define RAIN_GAUGE_SENSOR_VECTOR NVIC_INT_GPIO_PORT_D +#endif +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Weather meter's wind vane default ADCx pin (see board.h) + * @{ + */ +#ifdef WEATHER_METER_CONF_RAIN_WIND_VANE_ADC +#define WIND_VANE_ADC WEATHER_METER_CONF_RAIN_WIND_VANE_ADC +#else +#define WIND_VANE_ADC ZOUL_SENSORS_ADC3 +#endif +/** @} */ +/* -------------------------------------------------------------------------- */ +#define WEATHER_METER_SENSOR "Sparkfun weather meter" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor weather_meter; +/* -------------------------------------------------------------------------- */ +#endif /* ifndef WEATHER_METER_H_ */ +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/zonik.c b/platform/zoul/dev/zonik.c new file mode 100644 index 000000000..a087b620a --- /dev/null +++ b/platform/zoul/dev/zonik.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-zonik + * @{ + * Driver for the RE-Mote Zonik sonometer board + * @{ + * \file + * Driver for the RE-Mote Zonik sound sensor (ZONIK) + * \author + * Aitor Mejias + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/gpio.h" +#include "dev/i2c.h" +#include "zonik.h" +#include "sys/timer.h" +#include "sys/etimer.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +#define ZONIK_INT1_PORT_BASE GPIO_PORT_TO_BASE(ZONIK_INT_PORT) +#define ZONIK_INT1_PIN_MASK GPIO_PIN_MASK(ZONIK_INT_PIN) +/*---------------------------------------------------------------------------*/ +static uint8_t zonik_buffer[ZONIK_FRAME_SIZE+1]; +static uint16_t zonik_status = ZONIK_DISABLED; +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS(zonik_stm_process, "Zonik process process handler"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(zonik_stm_process, ev, data) +{ + #if DEBUG + static int i; + #endif + PROCESS_EXITHANDLER(); + PROCESS_BEGIN(); + + while(1) { + /* Wait a process */ + etimer_set(&et, ZONIK_SECOND_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* Control the interrupt for activate the sensor */ + GPIO_SET_OUTPUT(ZONIK_INT1_PORT_BASE, ZONIK_INT1_PIN_MASK); + GPIO_CLR_PIN(ZONIK_INT1_PORT_BASE, ZONIK_INT1_PIN_MASK); + clock_delay_usec(ZONIK_INITIAL_WAIT_DELAY); + i2c_master_enable(); + if(i2c_single_send(ZONIK_ADDR, ZONIK_CMD_READ) != I2C_MASTER_ERR_NONE) { + zonik_status = ZONIK_ERROR; + PRINTF("Zonik: Error in I2C Communication\n"); + } + GPIO_SET_PIN(ZONIK_INT1_PORT_BASE, ZONIK_INT1_PIN_MASK); + GPIO_SET_INPUT(ZONIK_INT1_PORT_BASE, ZONIK_INT1_PIN_MASK); + if(zonik_status != ZONIK_ERROR) { + etimer_set(&et, ZONIK_WAIT_ACQ); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + clock_delay_usec(ZONIK_FINAL_WAIT_DELAY); + i2c_master_enable(); + if(i2c_burst_receive(ZONIK_ADDR, &zonik_buffer[0], ZONIK_FRAME_SIZE) != + I2C_MASTER_ERR_NONE) { + zonik_status = ZONIK_ERROR; + PRINTF("Zonik: Error in I2C Burst Mode Receive"); + } + #if DEBUG + PRINTF("\nZonik: "); + for(i=0; i + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/* -------------------------------------------------------------------------- */ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup remote-zonik Zonik sound sensor + * @{ + * + * \file + * Header file for the Zolertia Zonik sound sensor + */ +/* -------------------------------------------------------------------------- */ +#ifndef ZONIK_H_ +#define ZONIK_H_ +/* -------------------------------------------------------------------------- */ +#include +#include "lib/sensors.h" +#include "dev/zoul-sensors.h" +#include "i2c.h" +#include "sys/rtimer.h" +/* -------------------------------------------------------------------------- */ +/** \name ZONIK address and definitions + * @{ + */ +#define ZONIK_ADDR 0x68 +#define ZONIK_SENSOR "Zonik Sound Sensor" + +#define ZONIK_INITIAL_WAIT_DELAY 11000L +#define ZONIK_FINAL_WAIT_DELAY 22000L + +#ifndef ZONIK_INT_CONF_PORT +#define ZONIK_INT_PORT I2C_INT_PORT +#else +#define ZONIK_INT_PORT ZONIK_INT_CONF_PORT +#endif + +#ifndef ZONIK_INT_CONF_PIN +#define ZONIK_INT_PIN I2C_INT_PIN +#else +#define ZONIK_INT_PIN ZONIK_INT_CONF_PIN +#endif + +#define ZONIK_FRAME_SIZE 4 + +#define ZONIK_WAIT_ACQ (CLOCK_SECOND / 5) + +/* Zonik wait sensor delay: ~800ms */ +#define ZONIK_SECOND_INTERVAL 106 + +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name ZONIK error values and definitions + * @{ + */ +#define ZONIK_ACTIVE SENSORS_ACTIVE +#define ZONIK_HW_INIT SENSORS_HW_INIT +#define ZONIK_ENABLED 1 +#define ZONIK_VALUE_DEACTIVATE 0 +#define ZONIK_DISABLED 0xD1ED +#define ZONIK_ERROR (-1) +#define ZONIK_DBA_LEQ_VALUE 0x00 +#define ZONIK_COUNT_VALUE 0x01 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name ZONIK command definitions + * @{ + */ +#define ZONIK_CMD_READ 0x01 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name ZONIK sensor type + * @{ + */ +extern const struct sensors_sensor zonik; +/** @} */ +/* -------------------------------------------------------------------------- */ +#endif +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/zoul-sensors.c b/platform/zoul/dev/zoul-sensors.c new file mode 100644 index 000000000..da755fc79 --- /dev/null +++ b/platform/zoul/dev/zoul-sensors.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * Generic module controlling sensors on the Zoul platform + * @{ + * + * \file + * Implementation of a generic module controlling Zoul sensors + */ +#include "contiki.h" +#include "dev/cc2538-sensors.h" +#include "dev/button-sensor.h" + +#include +/*---------------------------------------------------------------------------*/ +/** \brief Exports global symbols for the sensor API */ +SENSORS(&vdd3_sensor, +#if PLATFORM_HAS_BUTTON + &button_sensor, +#endif + &cc2538_temp_sensor +); +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/zoul/dev/zoul-sensors.h b/platform/zoul/dev/zoul-sensors.h new file mode 100644 index 000000000..5682c972c --- /dev/null +++ b/platform/zoul/dev/zoul-sensors.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul + * @{ + * + * \defgroup zoul-sensors Zoul Sensors + * + * Generic module controlling sensors on the Zoul platform + * @{ + * + * \file + * Implementation of a generic module controlling Zoul sensors + */ +/*---------------------------------------------------------------------------*/ +#ifndef ZOUL_SENSORS_H_ +#define ZOUL_SENSORS_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "dev/cc2538-sensors.h" +#include "dev/button-sensor.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Zoul sensor constants + * + * These constants are used by various sensors on the Zoul. They can be used + * to configure ADC decimation rate (where applicable), enable interrupts, etc. + * @{ + */ +#define HW_INT_OVER_THRS 0x01 +#define HW_INT_BELOW_THRS 0x02 +#define HW_INT_DISABLE 0x03 +#define ZOUL_SENSORS_CONFIGURE_TYPE_DECIMATION_RATE 0x0100 +#define ZOUL_SENSORS_ERROR CC2538_SENSORS_ERROR +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* ZOUL_SENSORS_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/zoul/firefly/Makefile.firefly b/platform/zoul/firefly/Makefile.firefly new file mode 100644 index 000000000..afecf9fa5 --- /dev/null +++ b/platform/zoul/firefly/Makefile.firefly @@ -0,0 +1,2 @@ +MOTELIST_ZOLERTIA = firefly +BOARD_SOURCEFILES += board.c diff --git a/platform/zoul/firefly/README.md b/platform/zoul/firefly/README.md new file mode 100644 index 000000000..55c6dafa9 --- /dev/null +++ b/platform/zoul/firefly/README.md @@ -0,0 +1,28 @@ +Zolertia Firefly platform +============================================ + +![Zolertia Firefly breakout board][firefly] + +The Firefly is a breakout board designed to inspire. + +It exposes the most basic Zoul features, sporting only the most down-to-core features to work with the Zoul, providing the following: + +* ARM Cortex-M3 with 512KB flash and 32KB RAM (16KB retention), 32MHz. +* ISM 2.4-GHz IEEE 802.15.4 & Zigbee compliant. +* ISM 868-, 915-, 920-, 950-MHz ISM/SRD Band. +* On-board printed PCB sub-1GHz antenna, alternatively u.FL for sub-1GHz/2.4GHz external antennas. +* AES-128/256, SHA2 Hardware Encryption Engine. +* ECC-128/256, RSA Hardware Acceleration Engine for Secure Key Exchange. +* Compatible with breadboards and protoboards. +* On-board CP2104/PIC to flash over USB. +* User and reset buttons. +* RGB LED to allow more than 7 colour combinations. +* Small form factor (53x25mm). + +The Firefly can be seen as the "small brother" of the RE-Mote, with a slick design and a lower cost. + +To work out of the box, the firefly includes a PCB antenna for the Sub-1GHz interface, as well as 2 x u.Fl connectors for 2.4GHz and sub-1GHz external antennas. + +The firefly can be programmed and debugged over JTAG and USB. The board has a CP2104 USB to serial converter with a PIC, it allows to program the CC2538 without having to manually to put the device in bootloader mode. + +[firefly]: ../images/firefly.png "Zolertia RE-Firefly breakout board" diff --git a/platform/zoul/firefly/board.c b/platform/zoul/firefly/board.c new file mode 100644 index 000000000..f00c82000 --- /dev/null +++ b/platform/zoul/firefly/board.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup firefly + * @{ + * + * \file + * Board-initialisation for the Zolertia's Firefly platform + * + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include +#include +/*---------------------------------------------------------------------------*/ +static void +configure_unused_pins(void) +{ + /* FIXME */ +} +/*---------------------------------------------------------------------------*/ +void +board_init() +{ + configure_unused_pins(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + */ + diff --git a/platform/zoul/firefly/board.h b/platform/zoul/firefly/board.h new file mode 100644 index 000000000..7cf92b39c --- /dev/null +++ b/platform/zoul/firefly/board.h @@ -0,0 +1,385 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup zoul-platforms + * @{ + * + * \defgroup firefly Firefly platform + * + * The Zolertia Firefly is the most down-to-core development platform, exposing + * the Zoul core functionalities and features, with a slick design to allow a + * flexible and easier user experience. + * + * Defines related to the Firefly platform: a Zoul-based breakout board + * + * This file provides connectivity information on LEDs, Buttons, UART and + * other peripherals + * + * This file can be used as the basis to configure other platforms using the + * cc2538 SoC. + * @{ + * + * \file + * Header file with definitions related to the I/O connections on the Zolertia's + * Firefly platform, Zoul-based + * + * \note Do not include this file directly. It gets included by contiki-conf + * after all relevant directives have been set. + */ +#ifndef BOARD_H_ +#define BOARD_H_ + +#include "dev/gpio.h" +#include "dev/nvic.h" +/*---------------------------------------------------------------------------*/ +/** \name Connector headers + * + * The Firefly features two 2.54 mm header rows over which exposes the following + * pins (facing up, Zolertia logo above and Micro-USB connector below): + * -----------------------------+---+---+-------------------------------------- + * PIN_NAME |JP3|JP2| PIN_NAME + * -----------------------------+---+---+-------------------------------------- + * PB5/CC1200.CS |-01|01-| LED1/PD5 + * PB2/SPI0.SCLK/CC1200.SCLK |-02|02-| LED2/PD4 + * PB1/SPIO0.MOSI/CC1200.MOSI |-03|03-| LED3/PD3 + * PB3/SPIO0.MISO/CC1200.MISO |-04|04-| PD2 + * PB3/CC1200.GPIO0 |-05|05-| PD1 + * PC0/UART1.TX |-06|06-| PD0 + * PC1/UART1.RX |-07|07-| AIN7/PA7 + * PC2/I2C.SDA |-08|08-| AIN6/PA6 + * PC3/I2C.SCL |-09|09-| ADC1/AIN5/PA5 + * PC4/SPI1.SCLK |-10|10-| ADC2/AIN4/PA4 + * PC5/SPI1.MOSI |-11|11-| BUTTON.USER/PA3 + * PC6/SPI1.MISO |-12|12-| ADC3/AIN2/PA2 + * USB.D+ |-13|13-| DGND + * USB.D- |-14|14-| D+3.3 + * ---------------------------+-+---+---+-+------------------------------------ + */ +/*---------------------------------------------------------------------------*/ +/** \name Firefly LED configuration + * + * LEDs on the Firefly are connected as follows: + * - LED1 (Red) -> PD5 + * - LED2 (Green) -> PD4 + * - LED3 (Blue) -> PD3 + * + * LED1 pin exposed in JP2 connector + * LED2 pin exposed in JP2 connector + * LED3 pin exposed in JP2 connector + * @{ + */ +/*---------------------------------------------------------------------------*/ +/* Some files include leds.h before us, so we need to get rid of defaults in + * leds.h before we provide correct definitions */ +#undef LEDS_GREEN +#undef LEDS_YELLOW +#undef LEDS_BLUE +#undef LEDS_RED +#undef LEDS_CONF_ALL + +/* In leds.h the LEDS_BLUE is defined by LED_YELLOW definition */ +#define LEDS_GREEN (1 << 4) /**< LED1 (Green) -> PD4 */ +#define LEDS_BLUE (1 << 3) /**< LED2 (Blue) -> PD3 */ +#define LEDS_RED (1 << 5) /**< LED3 (Red) -> PD5 */ + +#define LEDS_CONF_ALL (LEDS_GREEN | LEDS_BLUE | LEDS_RED) + +#define LEDS_LIGHT_BLUE (LEDS_GREEN | LEDS_BLUE) /**< Green + Blue (24) */ +#define LEDS_YELLOW (LEDS_GREEN | LEDS_RED) /**< Green + Red (48) */ +#define LEDS_PURPLE (LEDS_BLUE | LEDS_RED) /**< Blue + Red (40) */ +#define LEDS_WHITE LEDS_ALL /**< Green + Blue + Red (56) */ + +/* Notify various examples that we have LEDs */ +#define PLATFORM_HAS_LEDS 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name USB configuration + * + * The USB pullup is to be enabled by an external resistor, as it is not mapped + * to a GPIO. + */ +#ifdef USB_PULLUP_PORT +#undef USB_PULLUP_PORT +#endif +#ifdef USB_PULLUP_PIN +#undef USB_PULLUP_PIN +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name UART configuration + * + * On the Firefly, the UARTs are connected to the following ports/pins: + * + * - UART0: + * - RX: PA0, connected to CP2104 serial-to-usb converter TX pin + * - TX: PA1, connected to CP2104 serial-to-usb converter RX pin + * - UART1: + * - RX: PC1 + * - TX: PC0 + * - CTS: not used, one suggestion however is to use PD1 + * - RTS: not used, one suggestion however is to use PD0 + * + * We configure the port to use UART0 and UART1, CTS/RTS only for UART1, + * both without a HW pull-up resistor. + * UART0 is not exposed anywhere, UART1 pins are exposed over the JP3 connector. + * @{ + */ +#define UART0_RX_PORT GPIO_A_NUM +#define UART0_RX_PIN 0 +#define UART0_TX_PORT GPIO_A_NUM +#define UART0_TX_PIN 1 + +#define UART1_RX_PORT GPIO_C_NUM +#define UART1_RX_PIN 1 +#define UART1_TX_PORT GPIO_C_NUM +#define UART1_TX_PIN 0 +#define UART1_CTS_PORT (-1) /**< GPIO_D_NUM */ +#define UART1_CTS_PIN (-1) /**< 1 */ +#define UART1_RTS_PORT (-1) /**< GPIO_D_NUM */ +#define UART1_RTS_PIN (-1) /**< 0 */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name ADC configuration + * + * These values configure which CC2538 pins and ADC channels to use for the ADC + * inputs. There pins are suggested as they can be changed, but note that only + * pins from PA can be configured as ADC. + * + * - ADC1: up to 3.3V. + * - ADC2: up to 3.3V. + * - ADC3: up to 3.3V. + * - ADC4: up to 3.3V. + * - ADC5: up to 3.3V. + * - ADC6: up to 3.3V, shared with user button. + * + * Only ADC1 and ADC3 are enabled as default. + * + * The internal ADC reference is 1190mV, use either a voltage divider as input, + * or a different voltage reference, like AVDD5 or other externally (AIN7 or + * AIN6). + * @{ + */ +#define ADC_SENSORS_PORT GPIO_A_NUM /**< ADC GPIO control port */ + +#ifndef ADC_SENSORS_CONF_ADC1_PIN +#define ADC_SENSORS_ADC1_PIN 5 /**< ADC1 to PA5 */ +#else +#if ((ADC_SENSORS_CONF_ADC1_PIN != -1) && (ADC_SENSORS_CONF_ADC1_PIN != 5)) +#error "ADC1 channel should be mapped to PA5 or disabled with -1" +#else +#define ADC_SENSORS_ADC1_PIN ADC_SENSORS_CONF_ADC1_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC2_PIN +#define ADC_SENSORS_ADC2_PIN 4 /**< ADC2 to PA4 */ +#else +#if ((ADC_SENSORS_CONF_ADC2_PIN != -1) && (ADC_SENSORS_CONF_ADC2_PIN != 4)) +#error "ADC2 channel should be mapped to PA4 or disabled with -1" +#else +#define ADC_SENSORS_ADC2_PIN ADC_SENSORS_CONF_ADC2_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC3_PIN +#define ADC_SENSORS_ADC3_PIN 2 /**< ADC3 to PA2 */ +#else +#if ((ADC_SENSORS_CONF_ADC3_PIN != -1) && (ADC_SENSORS_CONF_ADC3_PIN != 2)) +#error "ADC3 channel should be mapped to PA2 or disabled with -1" +#else +#define ADC_SENSORS_ADC3_PIN ADC_SENSORS_CONF_ADC3_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC4_PIN +#define ADC_SENSORS_ADC4_PIN 6 /**< ADC4 to PA6 */ +#else +#if ((ADC_SENSORS_CONF_ADC4_PIN != -1) && (ADC_SENSORS_CONF_ADC4_PIN != 6)) +#error "ADC4 channel should be mapped to PA6 or disabled with -1" +#else +#define ADC_SENSORS_ADC4_PIN ADC_SENSORS_CONF_ADC4_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC5_PIN +#define ADC_SENSORS_ADC5_PIN 7 /**< ADC5 to PA7 */ +#else +#if ((ADC_SENSORS_CONF_ADC5_PIN != -1) && (ADC_SENSORS_CONF_ADC5_PIN != 7)) +#error "ADC5 channel should be mapped to PA7 or disabled with -1" +#else +#define ADC_SENSORS_ADC5_PIN ADC_SENSORS_CONF_ADC5_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC6_PIN +#define ADC_SENSORS_ADC6_PIN (-1) /**< ADC6 not declared */ +#else +#define ADC_SENSORS_ADC6_PIN 3 /**< Hard-coded to PA3 */ +#endif + +#ifndef ADC_SENSORS_CONF_MAX +#define ADC_SENSORS_MAX 5 /**< Maximum sensors */ +#else +#define ADC_SENSORS_MAX ADC_SENSORS_CONF_MAX +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name Firefly Button configuration + * + * Buttons on the Firefly are connected as follows: + * - BUTTON_USER -> PA3, S1 user button, shared with bootloader + * - BUTTON_RESET -> RESET_N line + * @{ + */ +/** BUTTON_USER -> PA3 */ +#define BUTTON_USER_PORT GPIO_A_NUM +#define BUTTON_USER_PIN 3 +#define BUTTON_USER_VECTOR NVIC_INT_GPIO_PORT_A + +/* Notify various examples that we have an user button. + * If ADC6 channel is used, then disable the user button + */ +#ifdef PLATFORM_CONF_WITH_BUTTON +#if (PLATFORM_CONF_WITH_BUTTON && (ADC_SENSORS_ADC6_PIN == 3)) +#error "The ADC6 (PA3) and user button cannot be enabled at the same time" +#else +#define PLATFORM_HAS_BUTTON (PLATFORM_CONF_WITH_BUTTON && \ + !(ADC_SENSORS_ADC6_PIN == 3)) +#endif /* (PLATFORM_CONF_WITH_BUTTON && (ADC_SENSORS_ADC6_PIN == 3)) */ +#else +#define PLATFORM_HAS_BUTTON !(ADC_SENSORS_ADC6_PIN == 3) +#endif /* PLATFORM_CONF_WITH_BUTTON */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI (SSI0) configuration + * + * These values configure which CC2538 pins to use for the SPI (SSI0) lines, + * reserved exclusively for the CC1200 RF transceiver. These pins are exposed + * to the JP3 connector. To disable the CC1200 and use these pins, just + * remove the R10 resistor (0 ohm), which powers both the CC2538 and CC1200 to + * only power the SoC. + * TX -> MOSI, RX -> MISO + * @{ + */ +#define SPI0_CLK_PORT GPIO_B_NUM +#define SPI0_CLK_PIN 2 +#define SPI0_TX_PORT GPIO_B_NUM +#define SPI0_TX_PIN 1 +#define SPI0_RX_PORT GPIO_B_NUM +#define SPI0_RX_PIN 3 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI (SSI1) configuration + * + * These values configure which CC2538 pins to use for the SPI (SSI1) lines, + * exposed over JP3 connector. + * TX -> MOSI, RX -> MISO + * @{ + */ +#define SPI1_CLK_PORT GPIO_C_NUM +#define SPI1_CLK_PIN 4 +#define SPI1_TX_PORT GPIO_C_NUM +#define SPI1_TX_PIN 5 +#define SPI1_RX_PORT GPIO_C_NUM +#define SPI1_RX_PIN 6 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name I2C configuration + * + * These values configure which CC2538 pins to use for the I2C lines, exposed + * over JP3 connector. + * @{ + */ +#define I2C_SCL_PORT GPIO_C_NUM +#define I2C_SCL_PIN 3 +#define I2C_SDA_PORT GPIO_C_NUM +#define I2C_SDA_PIN 2 +#define I2C_INT_PORT GPIO_D_NUM +#define I2C_INT_PIN 1 +#define I2C_INT_VECTOR NVIC_INT_GPIO_PORT_D +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Dual RF interface support + * + * Enables support for dual band operation (both CC1200 and 2.4GHz enabled). + * Unlike the RE-Mote, the Firefly doesn't have a RF switch, so both interfaces + * should be always enabled if the R10 resistor is mounted. If only using the + * 2.4GHz RF interface, the resistor can be removed to power-off the CC1200. + * @{ + */ +#define REMOTE_DUAL_RF_ENABLED 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name CC1200 configuration + * + * These values configure the required pins to drive the CC1200 + * None of the following pins are exposed to any connector, kept for internal + * use only + * @{ + */ +#define CC1200_SPI_INSTANCE 0 +#define CC1200_SPI_SCLK_PORT SPI0_CLK_PORT +#define CC1200_SPI_SCLK_PIN SPI0_CLK_PIN +#define CC1200_SPI_MOSI_PORT SPI0_TX_PORT +#define CC1200_SPI_MOSI_PIN SPI0_TX_PIN +#define CC1200_SPI_MISO_PORT SPI0_RX_PORT +#define CC1200_SPI_MISO_PIN SPI0_RX_PIN +#define CC1200_SPI_CSN_PORT GPIO_B_NUM +#define CC1200_SPI_CSN_PIN 5 +#define CC1200_GDO0_PORT GPIO_B_NUM +#define CC1200_GDO0_PIN 4 +#define CC1200_GDO2_PORT GPIO_B_NUM +#define CC1200_GDO2_PIN 0 +#define CC1200_RESET_PORT GPIO_C_NUM +#define CC1200_RESET_PIN 7 +#define CC1200_GPIOx_VECTOR NVIC_INT_GPIO_PORT_B +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Device string used on startup + * @{ + */ +#define BOARD_STRING "Zolertia Firefly platform" +/** @} */ + +#endif /* BOARD_H_ */ + +/** + * @} + * @} + */ diff --git a/platform/zoul/images/firefly.png b/platform/zoul/images/firefly.png new file mode 100755 index 000000000..362047c64 Binary files /dev/null and b/platform/zoul/images/firefly.png differ diff --git a/platform/zoul/images/remote-back.png b/platform/zoul/images/remote-back.png new file mode 100755 index 000000000..d94e9edac Binary files /dev/null and b/platform/zoul/images/remote-back.png differ diff --git a/platform/zoul/images/remote-front.png b/platform/zoul/images/remote-front.png new file mode 100755 index 000000000..390e16719 Binary files /dev/null and b/platform/zoul/images/remote-front.png differ diff --git a/platform/zoul/images/remote-pinout-back.png b/platform/zoul/images/remote-pinout-back.png new file mode 100755 index 000000000..15ced83a0 Binary files /dev/null and b/platform/zoul/images/remote-pinout-back.png differ diff --git a/platform/zoul/images/remote-pinout-front.png b/platform/zoul/images/remote-pinout-front.png new file mode 100755 index 000000000..18a9bf40c Binary files /dev/null and b/platform/zoul/images/remote-pinout-front.png differ diff --git a/platform/zoul/images/zoul-front.png b/platform/zoul/images/zoul-front.png new file mode 100755 index 000000000..1a5130515 Binary files /dev/null and b/platform/zoul/images/zoul-front.png differ diff --git a/platform/zoul/images/zoul-pinout-back.png b/platform/zoul/images/zoul-pinout-back.png new file mode 100755 index 000000000..e0fe2e36e Binary files /dev/null and b/platform/zoul/images/zoul-pinout-back.png differ diff --git a/platform/zoul/images/zoul-pinout-front.png b/platform/zoul/images/zoul-pinout-front.png new file mode 100755 index 000000000..c1d8a6c91 Binary files /dev/null and b/platform/zoul/images/zoul-pinout-front.png differ diff --git a/platform/zoul/remote/Makefile.remote b/platform/zoul/remote/Makefile.remote new file mode 100644 index 000000000..11f5ebe3a --- /dev/null +++ b/platform/zoul/remote/Makefile.remote @@ -0,0 +1,2 @@ +MOTELIST_ZOLERTIA = remote +BOARD_SOURCEFILES += board.c antenna-sw.c rtcc.c power-mgmt.c diff --git a/platform/zoul/remote/README.md b/platform/zoul/remote/README.md new file mode 100644 index 000000000..c1f57a1fd --- /dev/null +++ b/platform/zoul/remote/README.md @@ -0,0 +1,47 @@ +Zolertia RE-Mote platform +============================================ + +![Zolertia RE-Mote development platform][remote-front] + +The RE-Mote is a hardware development platform to build real IoT (Internet of Things) applications and products, aimed to high skilled developers as well as Makers (Do-It-Yourself enthusiasts) and early beginners, providing an industry-ready and resilient hardware solution for most Smart Cities, Home Comfort, eHealth and Industrial applications. The RE-Mote conciliates an ultra-low power consumption with a high performance design, meeting specifications of processing resources, security and resilient operation. + +The RE-Mote platform was designed jointly with universities and industrial partners from different countries in the context of RERUM European Project. + +![Zolertia RE-Mote development platform][remote-back] + +The RE-Mote features a Zoul as its core module and it is bundled with the following features: + +* ARM Cortex-M3 with 512KB flash and 32KB RAM (16KB retention), 32MHz. +* ISM 2.4-GHz IEEE 802.15.4 & Zigbee compliant. +* ISM 868-, 915-, 920-, 950-MHz ISM/SRD Band. +* On-board RF switch to programatically select RF itnerfaces. Above RF interfaces can be used alternatively over a single RP-SMA connector for external antenna, or simultaneously by using an UFl pigtail or soldering an internal ceramic chip antenna (available on request). +* AES-128/256, SHA2 Hardware Encryption Engine. +* ECC-128/256, RSA Hardware Acceleration Engine for Secure Key Exchange. +* Power consumption down to 300nA using our shutdown mode. +* Programming over BSL without requiring to press any button to enter bootloader mode. +* Built-in battery charger (500mA), Energy Harvesting and Solar Panels to be connected to standards LiPo batteries. +* Power input with wide range 3.7-26VDC. +* On-board micro USB connector for USB 2.0 applications. +* RGB LED to allow more than 7 colour combinations. +* On-board nano-watt Real Time Clock Calendar (RTCC). +* User and Reset buttons. +* On-board Micro-SD for external storage. +* On-board external Watchdog Timer (WDT) for resilient operation. +* Small form-factor of 73x40 mm. + +The most prominent feature of the RE-Mote is its ultra low-power implementation, allowing a flexible and time/date-aware control of the platform operation modes by introducing a real-time clock (RTCC), nanowatt external timer, ultra-low power PIC governing the battery manager, etc. + +The RE-Mote features an optional custom-made enclosure to fit most scenarios, allowing to easily connect sensors, actuators and rechargeable LiPo batteries. Its on-board RP-SMA antenna eliminates the need to mechanize an external antenna, allowing to alternatively use either a sub-1GHz or 2.4GHz antenna, or a multiband one. + +The external WDT with battery monitor allows a robust and resilience operation for most critical applications. + +Zoul pin-out +============= + +![RE-Mote pin-out (front)][remote-pinout-front] +![RE-Mote pin-out (back)][remote-pinout-back] + +[remote-front]: ../images/remote-front.png "Zolertia RE-Mote development platform" +[remote-back]: ../images/remote-back.png "Zolertia RE-Mote development platform" +[remote-pinout-front]: ../images/remote-pinout-front.png "RE-Mote pin-out (front)" +[remote-pinout-back]: ../images/remote-pinout-back.png "RE-Mote pin-out (back)" diff --git a/platform/zoul/remote/antenna-sw.c b/platform/zoul/remote/antenna-sw.c new file mode 100644 index 000000000..3266b66cc --- /dev/null +++ b/platform/zoul/remote/antenna-sw.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-antenna + * @{ + * + * Driver for the RE-Mote RF switch, to enable either the built-in 2.4GHz RF + * interface of the CC2538, or the CC1200 Sub-1GHz RF interface, both routed to + * the RP-SMA connector for an external antenna. + * When the 2.4GHz RF interface is enabled, the CC1200 is powered down. + * When the CC1200 is enabled, alternatively the 2.4GHz can be also used if + * placing an 0Ohm resistor (R19), to connect either via a non-mounted chip + * antenna, or with an external antenna connected to a non-mounted U.Fl + * connector with a pigtail. + * + * RF switch state: + * - LOW: 2.4GHz RF interface on RP-SMA connector, CC1200 powered-off. + * - HIGH: Sub-1GHz RF interface on RP-SMA connector. + * @{ + * + * \file + * Driver for the RE-Mote RF antenna switch + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/gpio.h" +#include "antenna-sw.h" + +#include +/*---------------------------------------------------------------------------*/ +#define ANTENNA_RF_SW_PORT_BASE GPIO_PORT_TO_BASE(ANTENNA_RF_SW_PORT) +#define ANTENNA_RF_SW_PIN_MASK GPIO_PIN_MASK(ANTENNA_RF_SW_PIN) +/*---------------------------------------------------------------------------*/ +static uint8_t initialized = 0; +/*---------------------------------------------------------------------------*/ +void +antenna_sw_config(void) +{ + /* Software controlled */ + GPIO_SOFTWARE_CONTROL(ANTENNA_RF_SW_PORT_BASE, + ANTENNA_RF_SW_PIN_MASK); + + /* Set pin to output */ + GPIO_SET_OUTPUT(ANTENNA_RF_SW_PORT_BASE, ANTENNA_RF_SW_PIN_MASK); + + /* Set the antenna selector to a default position */ + GPIO_WRITE_PIN(ANTENNA_RF_SW_PORT_BASE, ANTENNA_RF_SW_PIN_MASK, + ANTENNA_SW_SELECT_DEFAULT); + + initialized = 1; +} +/*---------------------------------------------------------------------------*/ +int +antenna_sw_get(void) +{ + if(!initialized) { + return ANTENNA_SW_SELECT_ERROR; + } + + /* Set the antenna selector */ + return GPIO_READ_PIN(ANTENNA_RF_SW_PORT_BASE, ANTENNA_RF_SW_PIN_MASK); +} +/*---------------------------------------------------------------------------*/ +int +antenna_sw_select(uint8_t val) +{ + if(!initialized) { + return ANTENNA_SW_SELECT_ERROR; + } + + if(val != ANTENNA_SW_SELECT_SUBGHZ && val != ANTENNA_SW_SELECT_2_4GHZ) { + return ANTENNA_SW_SELECT_ERROR; + } + + if(val & antenna_sw_get()) { + return val; + } + + /* Set the antenna selector */ + GPIO_WRITE_PIN(ANTENNA_RF_SW_PORT_BASE, ANTENNA_RF_SW_PIN_MASK, val); + + return val; +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/zoul/remote/antenna-sw.h b/platform/zoul/remote/antenna-sw.h new file mode 100644 index 000000000..6f02c8bb4 --- /dev/null +++ b/platform/zoul/remote/antenna-sw.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ +/* -------------------------------------------------------------------------- */ +/** + * \addtogroup remote + * @{ + * + * \defgroup remote-antenna RE-Mote Antenna switch + * + * Driver for the RE-Mote RF antenna switch, to enable either the internal + * ceramic antenna or an external one connected to the uFL connector + * @{ + * + * \file + * Header file for the RE-Mote RF antenna switch + */ +/* -------------------------------------------------------------------------- */ +#ifndef ANTENNA_SW_H_ +#define ANTENNA_SW_H_ +/* -------------------------------------------------------------------------- */ +#include +/* -------------------------------------------------------------------------- */ +#define ANTENNA_SW_SELECT_2_4GHZ 0 +#define ANTENNA_SW_SELECT_SUBGHZ (1 << ANTENNA_RF_SW_PIN) +#define ANTENNA_SW_SELECT_ERROR (-1) +/* -------------------------------------------------------------------------- */ +/** + * \brief Init function for the antenna switch + * + * The RE-Mote platform allows to programatically select between the 2.4GHz + * RF interface of the CC2538, or the Sub-1GHz RF interface of the CC1200. + * The function is set to enable the Sub-1GHz as default, + * it should be called from the contiki-main initialization process. + * + * \return ignored + */ +void antenna_sw_config(void); + +/** + * \brief Function to select between the 2.4GHz or Sub-1GHz RF interface + * + * \param val Select antenna. + * 2.4GHz : ANTENNA_SW_SELECT_2_4GHZ or + * Sub-1GHz: ANTENNA_SW_SELECT_SUBGHZ + * \return the selected antenna position, or ANTENNA_SW_SELECT_ERROR if not + * previously configured + */ +int antenna_sw_select(uint8_t val); + +/** + * \brief Function to read the current status of the RF switch + * + * + * \return the selected antenna position, or ANTENNA_SW_SELECT_ERROR if not + * previously configured + */ +int antenna_sw_get(void); +/* -------------------------------------------------------------------------- */ +#endif /* ifndef ANTENNA_SW_H_ */ +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ diff --git a/platform/zoul/remote/board.c b/platform/zoul/remote/board.c new file mode 100644 index 000000000..ad98f2fd0 --- /dev/null +++ b/platform/zoul/remote/board.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder 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. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote + * @{ + * + * \file + * Board-initialisation for the Zolertia's RE-Mote platform + * + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "antenna-sw.h" +#include +#include +/*---------------------------------------------------------------------------*/ +static void +configure_unused_pins(void) +{ + /* FIXME */ +} +/*---------------------------------------------------------------------------*/ +void +board_init() +{ + antenna_sw_config(); + configure_unused_pins(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + */ + diff --git a/platform/zoul/remote/board.h b/platform/zoul/remote/board.h new file mode 100644 index 000000000..2887f452a --- /dev/null +++ b/platform/zoul/remote/board.h @@ -0,0 +1,496 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +/** + * \addtogroup zoul-platforms + * @{ + * + * \defgroup remote RE-Mote platform + * + * The RE-Mote was designed jointly with universities and industry partners in + * RERUM European project, to ease the development of private and secure + * applications for IoT and Smart City applications. The RE-Mote packs several + * on-board resources, like a RTC, external WDT, Micro-SD, RF switch and a + * Shutdown mode to reduce its power consumption down to 300nA. + * + * This file provides connectivity information on LEDs, Buttons, UART and + * other RE-Mote peripherals + * + * This file can be used as the basis to configure other platforms using the + * cc2538 SoC. + * @{ + * + * \file + * Header file with definitions related to the I/O connections on the Zolertia's + * RE-Mote platform, cc2538-based + * + * \note Do not include this file directly. It gets included by contiki-conf + * after all relevant directives have been set. + */ +#ifndef BOARD_H_ +#define BOARD_H_ + +#include "dev/gpio.h" +#include "dev/nvic.h" +/*---------------------------------------------------------------------------*/ +/** \name Connector headers + * + * The RE-Mote features two 2.54 mm header rows over which exposes the following + * pins (facing up, Zolertia/RERUM logo above, buttons and micro USB at bottom): + * ----------------------+---+---+--------------------------------------------- + * PIN_NAME |JP6|JP5| PIN_NAME + * ----------------------+---+---+--------------------------------------------- + * LED1/EXT_WDT/PD5 |-01|18-| PC6/SPI1.MISO/USD.MISO + * LED2/UART1.CTS/PD4 |-02|17-| PC5/SPI1.MOSI/USD.MOSI + * LED3/UART1.RTS/PD3 |-03|16-| PC4/SPI1.SCLK/USD.SCLK + * UART0.RX/PA0 |-04|15-| PA3/BUTTON.USER + * UART0.TX/PA1 |-05|14-| RESET/JTAG.RESET/BUTTON.RESET + * SHUTDOWN_ENABLE/PD1 |-06|13-| DGND + * RTC.SDA/I2C.SDA/PC2 |-07|12-| D+3.3 + * RTC.SCL/I2C.SCL/PC3 |-08|11-| PA5/AIN5/ADC1 + * DGND |-09|10-| PA4/RTC_INT1/AIN4/ADC2 + * D+3.3 |-10|09-| DGND + * USD.CS/AIN7/PA7 |-11|08-| D+5.1 + * SHUTDOWN_DONE/PD0 |-12|07-| PA2/AIN2/ADC3 + * UART1.RX/PC1 |-13|06-| JTAG.TMS + * UART1.TX/PC0 |-14|05-| JTAG.TCK + * DGND |-15|04-| PB7/JTAG.TDO + * D+3.3 |-16|03-| PB6/JTAG.TDI + * DGND |-17|02-| PS+EXT + * +VBAT |-18|01-| DGND + * ----------------------+---+---+--------------------------------------------- + */ +/*---------------------------------------------------------------------------*/ +/** \name RE-Mote LED configuration + * + * LEDs on the RE-Mote are connected as follows: + * - LED1 (Red) -> PD5 + * - LED2 (Green) -> PD4 + * - LED3 (Blue) -> PD3 + * + * LED1 pin shared with EXT_WDT and exposed in JP6 connector + * LED2 pin shared with UART1 CTS, pin exposed in JP6 connector + * LED3 pin shared with UART1 RTS, exposed in JP6 connector + * @{ + */ +/*---------------------------------------------------------------------------*/ +/* Some files include leds.h before us, so we need to get rid of defaults in + * leds.h before we provide correct definitions */ +#undef LEDS_GREEN +#undef LEDS_YELLOW +#undef LEDS_BLUE +#undef LEDS_RED +#undef LEDS_CONF_ALL + +/* In leds.h the LEDS_BLUE is defined by LED_YELLOW definition */ +#define LEDS_GREEN (1 << 4) /**< LED1 (Green) -> PD4 */ +#define LEDS_BLUE (1 << 3) /**< LED2 (Blue) -> PD3 */ +#define LEDS_RED (1 << 5) /**< LED3 (Red) -> PD5 */ + +#define LEDS_CONF_ALL (LEDS_GREEN | LEDS_BLUE | LEDS_RED) + +#define LEDS_LIGHT_BLUE (LEDS_GREEN | LEDS_BLUE) /**< Green + Blue (24) */ +#define LEDS_YELLOW (LEDS_GREEN | LEDS_RED) /**< Green + Red (48) */ +#define LEDS_PURPLE (LEDS_BLUE | LEDS_RED) /**< Blue + Red (40) */ +#define LEDS_WHITE LEDS_ALL /**< Green + Blue + Red (56) */ + +/* Notify various examples that we have LEDs */ +#define PLATFORM_HAS_LEDS 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name USB configuration + * + * The USB pullup is enabled by an external resistor, not mapped to a GPIO + */ +#ifdef USB_PULLUP_PORT +#undef USB_PULLUP_PORT +#endif +#ifdef USB_PULLUP_PIN +#undef USB_PULLUP_PIN +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name UART configuration + * + * On the RE-Mote, the UARTs are connected to the following ports/pins: + * + * - UART0: + * - RX: PA0, connected to CP2104 serial-to-usb converter TX pin + * - TX: PA1, connected to CP2104 serial-to-usb converter RX pin + * - UART1: + * - RX: PC1 + * - TX: PC0 + * - CTS: PD4, shared with LED2 (Green), disabled as default + * - RTS: PD3, shared with LED3 (Blue), disabled as default + * + * We configure the port to use UART0 and UART1, CTS/RTS only for UART1, + * both without a HW pull-up resistor + * UART0 and UART1 pins are exposed over the JP6 connector + * @{ + */ +#define UART0_RX_PORT GPIO_A_NUM +#define UART0_RX_PIN 0 +#define UART0_TX_PORT GPIO_A_NUM +#define UART0_TX_PIN 1 + +#define UART1_RX_PORT GPIO_C_NUM +#define UART1_RX_PIN 1 +#define UART1_TX_PORT GPIO_C_NUM +#define UART1_TX_PIN 0 +#define UART1_CTS_PORT (-1) +#define UART1_CTS_PIN (-1) +#define UART1_RTS_PORT (-1) +#define UART1_RTS_PIN (-1) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name ADC configuration + * + * These values configure which CC2538 pins and ADC channels to use for the ADC + * inputs. By default the RE-Mote allows two out-of-the-box ADC ports with a + * phidget-like 3-pin connector (GND/VDD/ADC) + * + * The RE-Mote allows both 3.3V and 5V analogue sensors as follow: + * + * - ADC1: up to 3.3V. + * - ADC2: up to 3.3V, shared with RTC_INT + * - ADC3: up to 5V, by means of a 2/3 voltage divider. + * + * Also there are other ADC channels shared by default with Micro SD card and + * user button implementations: + * - ADC4: up to 3.3V. + * - ADC5: up to 3.3V. + * - ADC6: up to 3.3V. + * + * ADC inputs can only be on port A. + * All ADCx are exposed in JP5 connector, but only ADC1 and ADC3 have GND and + * VDD (3/5V) pins next to it, so these can be exposed into a 3-pin phidget-like + * connector, for ADC2 either solder a wire to connect, or use a 4-pin connector + * to expose both ADC1 and ADC2 in a single connector, but this will leave no + * space for a ADC3 connector. + * The internal ADC reference is 1190mV, use either a voltage divider as input, + * or a different voltage reference, like AVDD5 or other externally (AIN7), but + * note the PA7 is shared with the Micro-SD CSn pin, likewise for PA6 (AIN6) + * shared witht the Micro-SD select pin + * To use the ADC2 pin, remove the resistor on the Zoul's PA4 pin (JP1, pin 10) + * and enable below (replace -1 with 4). + * @{ + */ +#define ADC_SENSORS_PORT GPIO_A_NUM /**< ADC GPIO control port */ + +#ifndef ADC_SENSORS_CONF_ADC1_PIN +#define ADC_SENSORS_ADC1_PIN 5 /**< ADC1 to PA5, 3V3 */ +#else +#if ((ADC_SENSORS_CONF_ADC1_PIN != -1) && (ADC_SENSORS_CONF_ADC1_PIN != 5)) +#error "ADC1 channel should be mapped to PA5 or disabled with -1" +#else +#define ADC_SENSORS_ADC1_PIN ADC_SENSORS_CONF_ADC1_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC3_PIN +#define ADC_SENSORS_ADC3_PIN 2 /**< ADC3 to PA2, 5V */ +#else +#if ((ADC_SENSORS_CONF_ADC3_PIN != -1) && (ADC_SENSORS_CONF_ADC3_PIN != 2)) +#error "ADC3 channel should be mapped to PA2 or disabled with -1" +#else +#define ADC_SENSORS_ADC3_PIN ADC_SENSORS_CONF_ADC3_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC2_PIN +#define ADC_SENSORS_ADC2_PIN (-1) /**< ADC2 no declared */ +#else +#define ADC_SENSORS_ADC2_PIN 4 /**< Hard-coded to PA4 */ +#endif + +#ifndef ADC_SENSORS_CONF_ADC4_PIN +#define ADC_SENSORS_ADC4_PIN (-1) /**< ADC4 not declared */ +#else +#define ADC_SENSORS_ADC4_PIN 6 /**< Hard-coded to PA6 */ +#endif + +#ifndef ADC_SENSORS_CONF_ADC5_PIN +#define ADC_SENSORS_ADC5_PIN (-1) /**< ADC5 not declared */ +#else +#define ADC_SENSORS_ADC5_PIN 7 /**< Hard-coded to PA7 */ +#endif + +#ifndef ADC_SENSORS_CONF_ADC6_PIN +#define ADC_SENSORS_ADC6_PIN (-1) /**< ADC6 not declared */ +#else +#define ADC_SENSORS_ADC6_PIN 3 /**< Hard-coded to PA3 */ +#endif + +#ifndef ADC_SENSORS_CONF_MAX +#define ADC_SENSORS_MAX 2 /**< Maximum sensors */ +#else +#define ADC_SENSORS_MAX ADC_SENSORS_CONF_MAX +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name RE-Mote Button configuration + * + * Buttons on the RE-Mote are connected as follows: + * - BUTTON_USER -> PA3, S1 user button, shared with bootloader and RTC_INT1 + * - BUTTON_RESET -> RESET_N line, S2 reset both CC2538 and CoP + * - BUTTON_PIC1W -> shared with SHUTDOWN_ENABLE, not mounted. + * @{ + */ +/** BUTTON_USER -> PA3 */ +#define BUTTON_USER_PORT GPIO_A_NUM +#define BUTTON_USER_PIN 3 +#define BUTTON_USER_VECTOR NVIC_INT_GPIO_PORT_A + +/* Notify various examples that we have an user button. + * If ADC6 channel is used, then disable the user button + */ +#ifdef PLATFORM_CONF_WITH_BUTTON +#if (PLATFORM_CONF_WITH_BUTTON && (ADC_SENSORS_ADC6_PIN == 3)) +#error "The ADC6 (PA3) and user button cannot be enabled at the same time" +#else +#define PLATFORM_HAS_BUTTON (PLATFORM_CONF_WITH_BUTTON && \ + !(ADC_SENSORS_ADC6_PIN == 3)) +#endif /* (PLATFORM_CONF_WITH_BUTTON && (ADC_SENSORS_ADC6_PIN == 3)) */ +#else +#define PLATFORM_HAS_BUTTON !(ADC_SENSORS_ADC6_PIN == 3) +#endif /* PLATFORM_CONF_WITH_BUTTON */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI (SSI0) configuration + * + * These values configure which CC2538 pins to use for the SPI (SSI0) lines, + * reserved exclusively for the CC1200 RF transceiver. These pins are not + * exposed to any connector, and should be avoid to use it. + * TX -> MOSI, RX -> MISO + * @{ + */ +#define SPI0_CLK_PORT GPIO_B_NUM +#define SPI0_CLK_PIN 2 +#define SPI0_TX_PORT GPIO_B_NUM +#define SPI0_TX_PIN 1 +#define SPI0_RX_PORT GPIO_B_NUM +#define SPI0_RX_PIN 3 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI (SSI1) configuration + * + * These values configure which CC2538 pins to use for the SPI (SSI1) lines, + * shared with the microSD and exposed over JP5 connector. + * It is advisable to use a CSn pin other than the Micro-SD's. + * TX -> MOSI, RX -> MISO + * @{ + */ +#define SPI1_CLK_PORT GPIO_C_NUM +#define SPI1_CLK_PIN 4 +#define SPI1_TX_PORT GPIO_C_NUM +#define SPI1_TX_PIN 5 +#define SPI1_RX_PORT GPIO_C_NUM +#define SPI1_RX_PIN 6 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name I2C configuration + * + * These values configure which CC2538 pins to use for the I2C lines, exposed + * over JP6 connector, also available as testpoints T2 (PC2) and T3 (PC3). + * The I2C bus is shared with the on-board RTC. + * The I2C is exposed over the JP6 header, using a 5-pin connector with 2.54 mm + * spacing, providing also D+3.3V, GND and a generic pin that can be used as an + * interrupt pin + * @{ + */ +#define I2C_SCL_PORT GPIO_C_NUM +#define I2C_SCL_PIN 3 +#define I2C_SDA_PORT GPIO_C_NUM +#define I2C_SDA_PIN 2 +#define I2C_INT_PORT GPIO_D_NUM +#define I2C_INT_PIN 1 +#define I2C_INT_VECTOR NVIC_INT_GPIO_PORT_D +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Antenna switch configuration + * + * These values configure the required pin to drive the RF antenna switch, to + * either enable the sub-1Ghz RF interface (power-up the CC1200) or the 2.4GHz + * RF interface of the CC2538, both alternatively routed to a RP-SMA connector + * to allow using an external antenna for both cases. + * + * Note it is also possible to enable both RF interfaces at the same time, by + * switching On the sub-1GHz RF interface, and placing an 0Ohm resistor (R19), + * to select between using a ceramic chip antenna (not mounted), or to connect + * and external antenna over a pigtail to the U.Fl connector (not mounted). + * + * RF switch state: + * - LOW: 2.4GHz RF interface on RP-SMA connector, CC1200 powered-off. + * - HIGH: Sub-1GHz RF interface on RP-SMA connector. + * @{ + */ +#define ANTENNA_RF_SW_PORT GPIO_D_NUM +#define ANTENNA_RF_SW_PIN 2 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Dual RF interface support + * + * Enables support for dual band operation (both CC1200 and 2.4GHz enabled). + * The driver checks the selected Radio stack, and forces the antenna switch to + * either position. Enabling the definition below forces to skip this check. + * @{ + */ +#define REMOTE_DUAL_RF_ENABLED 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name CC1200 configuration + * + * These values configure the required pins to drive the CC1200 + * None of the following pins are exposed to any connector, kept for internal + * use only + * @{ + */ +#define CC1200_SPI_INSTANCE 0 +#define CC1200_SPI_SCLK_PORT SPI0_CLK_PORT +#define CC1200_SPI_SCLK_PIN SPI0_CLK_PIN +#define CC1200_SPI_MOSI_PORT SPI0_TX_PORT +#define CC1200_SPI_MOSI_PIN SPI0_TX_PIN +#define CC1200_SPI_MISO_PORT SPI0_RX_PORT +#define CC1200_SPI_MISO_PIN SPI0_RX_PIN +#define CC1200_SPI_CSN_PORT GPIO_B_NUM +#define CC1200_SPI_CSN_PIN 5 +#define CC1200_GDO0_PORT GPIO_B_NUM +#define CC1200_GDO0_PIN 4 +#define CC1200_GDO2_PORT GPIO_B_NUM +#define CC1200_GDO2_PIN 0 +#define CC1200_RESET_PORT GPIO_C_NUM +#define CC1200_RESET_PIN 7 +#define CC1200_GPIOx_VECTOR NVIC_INT_GPIO_PORT_B +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name microSD configuration + * + * These values configure the required pins to drive the built-in microSD + * external module, to be used with SSI1 + * @{ + */ +#define USD_CLK_PORT SPI1_CLK_PORT +#define USD_CLK_PIN SPI1_CLK_PIN +#define USD_MOSI_PORT SPI1_TX_PORT +#define USD_MOSI_PIN SPI1_TX_PIN +#define USD_MISO_PORT SPI1_RX_PORT +#define USD_MISO_PIN SPI1_RX_PIN +#define USD_CSN_PORT GPIO_A_NUM +#define USD_CSN_PIN 7 +#define USD_SEL_PORT GPIO_A_NUM +#define USD_SEL_PIN 6 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Power management and shutdown mode + * + * The shutdown mode is an ultra-low power operation mode that effectively + * powers-down the entire RE-Mote (CC2538, CC1200, attached sensors, etc) and + * only keeps running a power gating timer (NanoTimer), the on-board RTC and + * an ultra-low power consumption MCU (PIC12F635). The Shutdown mode allows: + * + * - Put the RE-Mote in an ultra-low power sleep (shutdown) drawing <200nA avg. + * - Periodically awake and execute tasks, being the shutdown period selectable + * via R47 resistor value (22KOhm as default for 1 minute shutdown period). + * - Enter shutdown mode before the shutdown period expiration, by invoking the + * PM_SHUTDOWN_NOW macrp + * + * The shutdown mode can be disabled by hardware by short-circuiting or placing + * an 0Ohm resistor across W1 pad. + * @{ + */ +#define PM_DONE_PORT GPIO_D_NUM +#define PM_DONE_PIN 0 +#define PM_CMD_PORT GPIO_D_NUM +#define PM_CMD_PIN 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name On-board RTC + * + * The shutdown mode can be disabled by hardware by short-circuiting or placing + * an 0Ohm resistor across W1 pad. As the RTC_INT1 pin is also shared with the + * BUTTON_USER, so either disable or not use the user button, or upon receiving + * an interrupt, poll the RTC. + * + * The RTC_INT1 can be used to exit the CC2538's LPM3 mode. + * A second interruption pin is connected to the PIC12F635, for applications + * requiring to put the PIC into deep-sleep and waking up at a certain time. + * @{ + */ +#define RTC_SDA_PORT I2C_SDA_PORT +#define RTC_SDA_PIN I2C_SDA_PIN +#define RTC_SCL_PORT I2C_SCL_PORT +#define RTC_SCL_PIN I2C_SCL_PIN +#define RTC_INT1_PORT GPIO_A_NUM +#define RTC_INT1_PIN 4 +#define RTC_INT1_VECTOR NVIC_INT_GPIO_PORT_A +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name On-board external WDT + * The RE-Mote features an on-board external WDT and battery monitor, which + * adds more robustness and prevents the mote to run wild if any unexpected + * problem shows-up. + * The external WDT requires a short pulse (<1ms) to be sent before a 2-second + * period. The battery monitor keeps the device in Reset if the voltage input + * is lower than 2.5V. + * The external WDT can be disabled by removing the R40 0Ohm resistor. + * The EXT_WDT pin is shared with LED1 (Red). For long-time operation, it is + * advised to remove R14 resistor to disable LED1. + * As default the Texas Instrument's TPS3823 WDT is not mounted. + * @{ + */ +#define EXT_WDT_PORT GPIO_D_NUM +#define EXT_WDT_PIN 5 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Device string used on startup + * @{ + */ +#define BOARD_STRING "Zolertia RE-Mote platform" +/** @} */ + +#endif /* BOARD_H_ */ + +/** + * @} + * @} + */ diff --git a/platform/zoul/remote/power-mgmt.c b/platform/zoul/remote/power-mgmt.c new file mode 100644 index 000000000..b0a09100b --- /dev/null +++ b/platform/zoul/remote/power-mgmt.c @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-power-mgmt + * @{ + * + * RE-Mote power management and shutdown mode + * @{ + * + * \author + * Aitor Mejias + * Antonio Lignan + */ +/* -------------------------------------------------------------------------- */ +#include +#include +#include "contiki.h" +#include "dev/gpio.h" +#include "sys/rtimer.h" +#include "power-mgmt.h" +/* -------------------------------------------------------------------------- */ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/* -------------------------------------------------------------------------- */ +#define PM_CMD_LINE_SET GPIO_SET_PIN(PM_CMD_PORT_BASE, PM_CMD_PIN_MASK) +#define PM_CMD_LINE_CLR GPIO_CLR_PIN(PM_CMD_PORT_BASE, PM_CMD_PIN_MASK) +#define PM_CMD_LINE_READ GPIO_READ_PIN(PM_CMD_PORT_BASE, PM_CMD_PIN_MASK) +#define PM_CMD_AS_OUTPUT GPIO_SET_OUTPUT(PM_CMD_PORT_BASE, PM_CMD_PIN_MASK) +#define PM_CMD_AS_INPUT GPIO_SET_INPUT(PM_CMD_PORT_BASE, PM_CMD_PIN_MASK) +/* -------------------------------------------------------------------------- */ +#define PM_NUMBITS(X) (1 << ((X) - 1)) +/* -------------------------------------------------------------------------- */ +static uint8_t initialized = 0; +static uint8_t getData = 0; +/* -------------------------------------------------------------------------- */ +static int8_t +pm_get_ack(void) +{ + uint16_t error = PM_ERROR; + PM_CMD_AS_INPUT; + clock_delay_usec(PM_3_MILISECOND); + if(PM_CMD_LINE_READ) { + error = PM_SUCCESS; + } + + clock_delay_usec(PM_10_MILISECOND); + PM_CMD_AS_OUTPUT; + return error; +} +/* -------------------------------------------------------------------------- */ +static int8_t +pm_send_cmd(uint8_t cmd) +{ + uint8_t i; + + PRINTF("PM: cmd %u\n", cmd); + + /* Enter command mode */ + PM_CMD_LINE_SET; + clock_delay_usec(PM_1_MILISECOND); + PM_CMD_LINE_CLR; + + /* Send command */ + for (i = PM_MAX_BITS; i > 0; i--) { + clock_delay_usec(PM_1_MILISECOND); + + if (cmd & PM_NUMBITS(i)) { + PM_CMD_LINE_SET; + } + else PM_CMD_LINE_CLR; + } + + clock_delay_usec(PM_1_MILISECOND); + PM_CMD_LINE_CLR; + + /* Receive command reply if any */ + if((cmd == PM_CMD_GET_STATE) || (cmd == PM_CMD_GET_FW_VERSION)) { + PM_CMD_AS_INPUT; + clock_delay_usec(PM_2_2_MILISECOND); + for (i = PM_MAX_BITS; i > 0; i--) { + clock_delay_usec(PM_1_MILISECOND); + PM_CMD_LINE_READ ? (getData |= PM_NUMBITS(i)) : (getData &= ~PM_NUMBITS(i)); + } + + PRINTF("PM: getData = 0x%02X\n", getData); + clock_delay_usec(PM_2_2_MILISECOND); + PM_CMD_AS_OUTPUT; + PM_CMD_LINE_CLR; + + clock_delay_usec(PM_2_2_MILISECOND); + + return PM_SUCCESS; + } + + /* Default case */ + clock_delay_usec(PM_1_MILISECOND); + + return pm_get_ack(); +} +/* -------------------------------------------------------------------------- */ +int8_t +pm_init(void) +{ + /* Configure and clear immediately */ + GPIO_SOFTWARE_CONTROL(PM_DONE_PORT_BASE, PM_DONE_PIN_MASK); + GPIO_SET_OUTPUT(PM_DONE_PORT_BASE, PM_DONE_PIN_MASK); + GPIO_CLR_PIN(PM_DONE_PORT_BASE, PM_DONE_PIN_MASK); + + /* Set as output/low to set IDLE state */ + GPIO_SOFTWARE_CONTROL(PM_CMD_PORT_BASE, PM_CMD_PIN_MASK); + PM_CMD_AS_OUTPUT; + PM_CMD_LINE_CLR; + + /* Ensure the battery charger is on, so we don't lock ourselves out and left + * stranded in a state the CC2538 and components are kept off + */ + + if(pm_send_cmd(PM_CMD_PWR_ON) == PM_SUCCESS) { + initialized = 1; + PRINTF("PM: Initialized\n"); + return PM_SUCCESS; + } + + PRINTF("PM: Failed to initialize\n"); + return PM_ERROR; +} +/* -------------------------------------------------------------------------- */ +int8_t +pm_enable_timer(void) +{ + if(!initialized) { + return PM_ERROR; + } + + if(pm_send_cmd(PM_CMD_DTIMER_ON) == PM_SUCCESS) { + return PM_SUCCESS; + } + return PM_ERROR; +} +/* -------------------------------------------------------------------------- */ +int8_t +pm_disable_timer(void) +{ + if(!initialized) { + return PM_ERROR; + } + + if(pm_send_cmd(PM_CMD_DTIMER_OFF) == PM_SUCCESS) { + return PM_SUCCESS; + } + return PM_ERROR; +} +/* -------------------------------------------------------------------------- */ +int8_t +pm_get_state(uint8_t *state) +{ + if(!initialized) { + return PM_ERROR; + } + + if(pm_send_cmd(PM_CMD_GET_STATE) == PM_SUCCESS) { + *state = getData; + PRINTF("PM: state %u\n", getData); + + return PM_SUCCESS; + } + return PM_ERROR; +} +/* -------------------------------------------------------------------------- */ +int8_t +pm_get_firmware_version(uint8_t *state) +{ + if(!initialized) { + return PM_ERROR; + } + + if (pm_send_cmd(PM_CMD_GET_FW_VERSION) == PM_SUCCESS) { + *state = getData; + printf("PM: FW Version %u\n", getData); + return PM_SUCCESS; + } + return PM_ERROR; +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/zoul/remote/power-mgmt.h b/platform/zoul/remote/power-mgmt.h new file mode 100644 index 000000000..0504f9dba --- /dev/null +++ b/platform/zoul/remote/power-mgmt.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote + * @{ + * + * \defgroup remote-power-mgmt RE-Mote power management driver + * + * The power management module is composed by a nano-watt (gating) timer and an + * ultra-low power MCU, driving the RE-Mote power supply when connected to an + * external battery, and allowing an application to enter a so-called "shutdown + * mode". + * While in shutdown mode, only the RTCC and the power management block is on, + * effectively reducing the RE-Mote power consumption down to <~200nA. The + * nano Timer allows the RE-Mote to be awaken off shutdown mode after a given + * period (from 100ms to 2 hours, default is 1 minute). To change the shutdown + * period, the R47 resistor (at the DELAY input pin, see the RE-Mote datasheet) + * has to be changed. + * See the TPL5110 datasheet ((Table 2 and 3) for more information about the R47 + * resistor value, below is a table resuming most common periods: + * + * +------------+------------+ + * | R47 (Ohm) | Time | + * +------------+------------+ + * | 500 | 100ms | + * +------------+------------+ + * | 2.5K | 500ms | + * +------------+------------+ + * | 5.202K | 1s | + * +------------+------------+ + * | 22.021K | 1min | + * +------------+------------+ + * | 42.887K | 5min | + * +------------+------------+ + * | 57.434K | 10min | + * +------------+------------+ + * | 92.233K | 30min | + * +------------+------------+ + * | 170K | 2h | + * +------------+------------+ + * + * An application can enter the shutdown mode before the shutdown period expires + * by invoking the PM_SHUTDOWN_NOW macro. + * The on-board RTCC can also be used to drive the CC2538 off PM3 power mode, if + * the application requires to retain RAM. Note that while in shutdown mode the + * RE-Mote will be powered off. + * + * @{ + * + * \file + * Header file for the RE-Mote Power Management driver + */ +/* -------------------------------------------------------------------------- */ +#ifndef POWER_MGMT_H_ +#define POWER_MGMT_H_ +#include "dev/gpio.h" +/* -------------------------------------------------------------------------- */ +#define PM_CMD_PORT_BASE GPIO_PORT_TO_BASE(PM_CMD_PORT) +#define PM_CMD_PIN_MASK GPIO_PIN_MASK(PM_CMD_PIN) +#define PM_DONE_PORT_BASE GPIO_PORT_TO_BASE(PM_DONE_PORT) +#define PM_DONE_PIN_MASK GPIO_PIN_MASK(PM_DONE_PIN) +/* -------------------------------------------------------------------------- */ +/** \name Power Management return values + * @{ + */ +#define PM_SUCCESS 0 +#define PM_ERROR (-1) +#define PM_MAX_BITS 8 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name Power Management "done" signal + * @{ + */ +#define PM_SHUTDOWN_NOW GPIO_SET_PIN(PM_DONE_PORT_BASE, PM_DONE_PIN_MASK) +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name Power Management timing values + * @{ + */ +#define PM_1_MILISECOND 1000L +#define PM_2_2_MILISECOND 2200L +#define PM_3_MILISECOND 3000L +#define PM_10_MILISECOND 10000L +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name Power Management commands + * @{ + */ +typedef enum { + PM_CMD_PWR_ON = 0x34, + PM_CMD_PWR_OFF = 0x35, + PM_CMD_RST_HARD = 0x36, + PM_CMD_RST_TIMED = 0x37, /* Not implemented */ + PM_CMD_DTIMER_ON = 0x38, + PM_CMD_DTIMER_OFF = 0x39, + PM_CMD_DTIMER_TIMED = 0x3A, /* Not implemented */ + PM_CMD_PARAM_SET_MAX_TIME = 0x3B, /* Not implemented */ + PM_CMD_GET_STATE = 0x3C, + PM_CMD_GET_FW_VERSION = 0x3D, + PM_MAX_NUM_CMDS +} pm_cmd_t; +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name Power Management status and masks + * @{ + */ +typedef enum { + PM_IDLE, + PM_SYSOFF_OFF, + PM_SYSOFF_ON, + PM_TIMER_DISABLED, + PM_TIMER_ENABLED, + PM_AWAITING_RTC_DIS, /* Not implemented */ + PM_AWAITING_RTC_EVENT, /* Not implemented */ +} pm_state_t; + +#define PM_SYSOFF_ON_MASK 0x01 +#define PM_TIMER_ENABLED_MASK 0x02 +#define PM_AWAITING_RTC_EVENT_MASK 0x04 + +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name Power Management functions + * @{ + */ +/** \brief Initializes the Power Management driver + * \return \c PM_SUCCESS if initialized, else \c PM_ERROR + */ +int8_t pm_init(void); +/* -------------------------------------------------------------------------- */ +/** \brief Enable the shutdown mode, periodically driven by the Nano Timer + * \return \c PM_SUCCESS if successful, else \c PM_ERROR + */ +int8_t pm_enable_timer(void); +/* -------------------------------------------------------------------------- */ +/** \brief Disable the Nano Timer + * \return \c PM_SUCCESS if successful, else \c PM_ERROR + */ +int8_t pm_disable_timer(void); +/* -------------------------------------------------------------------------- */ +/** \brief Get the current state of the power management module + * \param state Pointer to a variable to save the state + * \return \c PM_SUCCESS if successful, else \c PM_ERROR + */ +int8_t pm_get_state(uint8_t *state); +/* -------------------------------------------------------------------------- */ +/** \brief Get the firmware version of the power management module + * \param state Pointer to a variable to save the state + * \return \c PM_SUCCESS if successful, else \c PM_ERROR + */ +int8_t pm_get_firmware_version(uint8_t *state); +/* -------------------------------------------------------------------------- */ +/** @} */ +#endif /* POWER_MGMT_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/zoul/remote/rtcc-config.h b/platform/zoul/remote/rtcc-config.h new file mode 100644 index 000000000..de39d5ec8 --- /dev/null +++ b/platform/zoul/remote/rtcc-config.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/* -------------------------------------------------------------------------- */ +/** + * \addtogroup remote-rtcc + * @{ + * + * Driver for the RE-Mote RTCC (Real Time Clock Calendar) + * @{ + * + * \file + * RTCC configuration file + * + * \author + * + * Antonio Lignan + * Aitor Mejias + * Toni Lozano + */ +/* -------------------------------------------------------------------------- */ +#ifndef RTCC_CONFIG_H_ +#define RTCC_CONFIG_H_ +/* -------------------------------------------------------------------------- */ +#include "rtcc.h" +/* -------------------------------------------------------------------------- */ +/** + * \name RTCC configuration macros + * @{ + */ +#define RTCC_SET_DEFAULT_CONFIG 1 +#define RTCC_CLEAR_INT_MANUALLY 1 +#define RTCC_SET_AUTOCAL 1 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name RTCC default configuration (if enabled by RTCC_SET_DEFAULT_CONFIG) + * @{ + */ +/* Reset values from the Application Manual */ +#define RTCC_DEFAULT_STATUS 0x00 +#define RTCC_DEFAULT_CTRL1 0x11 +#define RTCC_DEFAULT_CTRL2 0x00 +#define RTCC_DEFAULT_INTMASK 0xE0 +#define RTCC_DEFAULT_SQW 0x26 +#define RTCC_DEFAULT_TIMER_CTRL 0x23 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name RTCC default configuration structure + * @{ + */ +typedef struct ab080x_register_config { + uint8_t reg; + uint8_t val; +} ab080x_register_config_t; +/* -------------------------------------------------------------------------- */ +static const ab080x_register_config_t ab080x_default_setting[] = +{ + { (CONFIG_MAP_OFFSET + STATUS_ADDR), RTCC_DEFAULT_STATUS }, + { (CONFIG_MAP_OFFSET + CTRL_1_ADDR), RTCC_DEFAULT_CTRL1 }, + { (CONFIG_MAP_OFFSET + CTRL_2_ADDR), RTCC_DEFAULT_CTRL2 }, + { (CONFIG_MAP_OFFSET + INT_MASK_ADDR), RTCC_DEFAULT_INTMASK }, + { (CONFIG_MAP_OFFSET + SQW_ADDR), RTCC_DEFAULT_SQW }, + { (CONFIG_MAP_OFFSET + TIMER_CONTROL_ADDR), RTCC_DEFAULT_TIMER_CTRL }, +}; +/** @} */ +/* -------------------------------------------------------------------------- */ +#endif /* ifndef RTCC_CONFIG_H_ */ +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ + diff --git a/platform/zoul/remote/rtcc.c b/platform/zoul/remote/rtcc.c new file mode 100644 index 000000000..e27bdc555 --- /dev/null +++ b/platform/zoul/remote/rtcc.c @@ -0,0 +1,868 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-rtcc + * @{ + * + * Driver for the RE-Mote RTCC (Real Time Clock Calendar) + * @{ + * + * \file + * Driver for the RE-Mote RF Real Time Clock Calendar (RTCC) + * + * \author + * + * Antonio Lignan + * Aitor Mejias + * Toni Lozano + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/gpio.h" +#include "dev/i2c.h" +#include "rtcc.h" +#include "rtcc-config.h" +#include "dev/leds.h" +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +#define RTC_INT1_PORT_BASE GPIO_PORT_TO_BASE(RTC_INT1_PORT) +#define RTC_INT1_PIN_MASK GPIO_PIN_MASK(RTC_INT1_PIN) +/*---------------------------------------------------------------------------*/ +/* Callback pointers when interrupt occurs */ +void (*rtcc_int1_callback)(uint8_t value); +/* -------------------------------------------------------------------------- */ +static const char *ab080x_td_register_name[] = +{ + "Mseconds", + "Seconds", + "Minutes", + "Hours", + "Days", + "Months", + "Years", + "Weekdays", +}; +/* -------------------------------------------------------------------------- */ +static const char *ab080x_config_register_name[] = +{ + "STATUS", + "CTRL1", + "CTRL2", + "INTMASK", + "SQW", + "CAL_XT", + "CAL_RCU", + "CAL_RCL", + "INTPOL", + "TIMER_CTRL", + "TIMER_CDOWN", + "TIMER_INIT", + "WDT", + "OSC_CTRL", + "OSC_STAT", + "CONF_KEY", + "TRICKLE", + "BREF", +}; +/*---------------------------------------------------------------------------*/ +static uint8_t +bcd_to_dec(uint8_t val) +{ + return (uint8_t)(((val >> 4) * 10) + (val % 16)); +} +/*---------------------------------------------------------------------------*/ +static uint8_t +dec_to_bcd(uint8_t val) +{ + return (uint8_t)(((val / 10) << 4) + (val % 10)); +} +/*---------------------------------------------------------------------------*/ +static uint8_t +check_leap_year(uint8_t val) +{ + return ((val % 4) && (val % 100)) || (val % 400); +} +/*---------------------------------------------------------------------------*/ +static uint16_t +ab08_read_reg(uint8_t reg, uint8_t *buf, uint8_t regnum) +{ + i2c_master_enable(); + if(i2c_single_send(AB08XX_ADDR, reg) == I2C_MASTER_ERR_NONE) { + if(i2c_burst_receive(AB08XX_ADDR, buf, regnum) == I2C_MASTER_ERR_NONE) { + return AB08_SUCCESS; + } + } + return AB08_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int8_t +ab08_write_reg(uint8_t reg, uint8_t *buf, uint8_t regnum) +{ + uint8_t i, buff[INT_BUFF_SIZE]; + + if(regnum > (INT_BUFF_SIZE - 1)) { + return AB08_ERROR; + } + + /* FIXME: Replace by single_send/burst_send */ + + buff[0] = reg; + for(i = 0; i < regnum; i++) { + buff[(i + 1)] = buf[i]; + } + + i2c_master_enable(); + if(i2c_burst_send(AB08XX_ADDR, buff, (regnum + 1)) == I2C_MASTER_ERR_NONE) { + return AB08_SUCCESS; + } + + return AB08_ERROR; +} +/*---------------------------------------------------------------------------*/ +static void +write_default_config(void) +{ + const ab080x_register_config_t *settings; + settings = ab080x_default_setting; + uint8_t i, len = (sizeof(ab080x_default_setting) / sizeof(ab080x_register_config_t)); + + for(i = 0; i < len; i++) { + ab08_write_reg(settings[i].reg, (uint8_t *)&settings[i].val, 1); + } +} +/*---------------------------------------------------------------------------*/ +static int8_t +ab08_key_reg(uint8_t unlock) +{ + if((unlock != RTCC_CONFKEY_OSCONTROL) && (unlock != RTCC_CONFKEY_SWRESET) && + (unlock != RTCC_CONFKEY_DEFREGS)) { + PRINTF("RTC: invalid confkey values\n"); + return AB08_ERROR; + } + + if(ab08_write_reg((CONFIG_MAP_OFFSET + CONF_KEY_ADDR), &unlock, 1)) { + PRINTF("RTC: failed to write to confkey register\n"); + return AB08_ERROR; + } + + return AB08_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int8_t +ab08_read_status(uint8_t *buf) +{ + return ab08_read_reg((STATUS_ADDR + CONFIG_MAP_OFFSET), buf, 1); +} +/*---------------------------------------------------------------------------*/ +static int8_t +ab08_ctrl1_config(uint8_t cmd) +{ + uint8_t ctrl1 = 0; + + if(cmd >= RTCC_CMD_MAX) { + return AB08_ERROR; + } + + if(ab08_read_reg((CONFIG_MAP_OFFSET + CTRL_1_ADDR), &ctrl1, 1)) { + PRINTF("RTC: failed to retrieve CTRL1 register\n"); + return AB08_ERROR; + } + + switch(cmd) { + case RTCC_CMD_LOCK: + ctrl1 &= ~CTRL1_WRTC; + break; + case RTCC_CMD_UNLOCK: + ctrl1 |= CTRL1_WRTC; + break; + case RTCC_CMD_ENABLE: + ctrl1 &= ~CTRL1_STOP; + break; + case RTCC_CMD_STOP: + ctrl1 |= CTRL1_STOP; + break; + default: + return AB08_ERROR; + } + + if(ab08_write_reg((CONFIG_MAP_OFFSET + CTRL_1_ADDR), + &ctrl1, 1) == AB08_ERROR) { + PRINTF("RTC: failed to write to the CTRL1 register\n"); + return AB08_ERROR; + } + + return AB08_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int8_t +ab08_check_td_format(simple_td_map *data, uint8_t alarm_state) +{ + /* Using fixed values as these are self-indicative of the variable */ + if((data->seconds > 59) || (data->minutes > 59) || (data->hours > 23)) { + return AB08_ERROR; + } + + if((data->months > 12) || (data->weekdays > 7) || (data->day > 31)) { + return AB08_ERROR; + } + + /* Fixed condition for February (month 2) */ + if(data->months == 2) { + if(check_leap_year(data->years)) { + if(data->day > 29) { + return AB08_ERROR; + } + } else { + if(data->day > 28) { + return AB08_ERROR; + } + } + } + + /* Alarm doesn't care about year */ + if(!alarm_state) { + /* AB08X5 Real-Time Clock Family, page 55 (year up to 2199) */ + if(data->years > 199) { + return AB08_ERROR; + } + } + + return AB08_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int8_t +rtcc_set_time_date(simple_td_map *data) +{ + uint8_t aux = 0; + uint8_t rtc_buffer[RTCC_TD_MAP_SIZE]; + + if(ab08_check_td_format(data, 0) == AB08_ERROR) { + PRINTF("RTC: Invalid time/date values\n"); + return AB08_ERROR; + } + + if(ab08_read_reg((CTRL_1_ADDR + CONFIG_MAP_OFFSET), + &aux, 1) == AB08_ERROR) { + PRINTF("RTC: failed to retrieve CONTROL1 register\n"); + return AB08_ERROR; + } + + rtc_buffer[WEEKDAYLS_ADDR] = dec_to_bcd(data->weekdays); + rtc_buffer[YEAR_ADDR] = dec_to_bcd(data->years); + rtc_buffer[MONTHS_ADDR] = dec_to_bcd(data->months); + rtc_buffer[DAY_ADDR] = dec_to_bcd(data->day); + rtc_buffer[HOUR_ADDR] = dec_to_bcd(data->hours); + rtc_buffer[MIN_ADDR] = dec_to_bcd(data->minutes); + rtc_buffer[SEC_ADDR] = dec_to_bcd(data->seconds); + rtc_buffer[CENTHS_ADDR] = dec_to_bcd(data->miliseconds); + + /* Check if we are to set the time in 12h/24h format */ + if(data->mode == RTCC_24H_MODE) { + aux &= ~CTRL1_1224; + } else { + if((data->hours == 0) || (data->hours > 12)) { + PRINTF("RTC: Invalid hour configuration (12h mode selected)\n"); + return AB08_ERROR; + } + aux |= CTRL1_1224; + if(data->mode == RTCC_12H_MODE_PM) { + /* Toggle bit for PM */ + rtc_buffer[HOUR_ADDR] |= RTCC_TOGGLE_PM_BIT; + } else { + PRINTF("RTC: Invalid time mode selected\n"); + return AB08_ERROR; + } + } + + /* Write the 12h/24h config */ + if(ab08_write_reg((CTRL_1_ADDR + CONFIG_MAP_OFFSET), + &aux, 1) == AB08_ERROR) { + PRINTF("RTC: failed to write 12h/24h configuration\n"); + return AB08_ERROR; + } + + /* Reading the STATUS register with the CONTROL1.ARST set will clear the + * interrupt flags, we write directly to the register without caring its + * actual status and let the interrupt handler take care of any pending flag + */ + + if(ab08_read_reg((STATUS_ADDR + CONFIG_MAP_OFFSET), &aux, 1) == AB08_ERROR) { + PRINTF("RTC: failed to retrieve STATUS register\n"); + return AB08_ERROR; + } + + if(data->century == RTCC_CENTURY_20XX) { + aux |= STATUS_CB; + } else if(data->century == RTCC_CENTURY_19XX_21XX) { + aux |= ~STATUS_CB; + } else { + PRINTF("RTC: invalid century value\n"); + return AB08_ERROR; + } + + PRINTF("RTC: current STATUS value 0x%02X\n", aux); + + if(ab08_write_reg((STATUS_ADDR + CONFIG_MAP_OFFSET), &aux, 1) == AB08_ERROR) { + PRINTF("RTC: failed to write century to STATUS register\n"); + return AB08_ERROR; + } + + /* Set the WRTC bit to enable writting to the counters */ + if(ab08_ctrl1_config(RTCC_CMD_UNLOCK) == AB08_ERROR) { + return AB08_ERROR; + } + + /* Write the buffers but the mode and century fields (used only for config) */ + if(ab08_write_reg(CENTHS_ADDR, rtc_buffer, + RTCC_TD_MAP_SIZE) == AB08_ERROR) { + PRINTF("RTC: failed to write date configuration\n"); + return AB08_ERROR; + } + + /* Lock the RTCC and return */ + if(ab08_ctrl1_config(RTCC_CMD_LOCK) == AB08_ERROR) { + return AB08_ERROR; + } + + return AB08_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int8_t +rtcc_get_time_date(simple_td_map *data) +{ + uint8_t rtc_buffer[RTCC_TD_MAP_SIZE]; + + if(ab08_read_reg(CENTHS_ADDR, rtc_buffer, + RTCC_TD_MAP_SIZE) == AB08_ERROR) { + PRINTF("RTC: failed to retrieve date and time values\n"); + return AB08_ERROR; + } + + data->weekdays = bcd_to_dec(rtc_buffer[WEEKDAYLS_ADDR]); + data->years = bcd_to_dec(rtc_buffer[YEAR_ADDR]); + data->months = bcd_to_dec(rtc_buffer[MONTHS_ADDR]); + data->day = bcd_to_dec(rtc_buffer[DAY_ADDR]); + data->hours = bcd_to_dec(rtc_buffer[HOUR_ADDR]); + data->minutes = bcd_to_dec(rtc_buffer[MIN_ADDR]); + data->seconds = bcd_to_dec(rtc_buffer[SEC_ADDR]); + data->miliseconds = bcd_to_dec(rtc_buffer[CENTHS_ADDR]); + + return AB08_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int8_t +rtcc_set_alarm_time_date(simple_td_map *data, uint8_t state, uint8_t repeat) +{ + uint8_t aux[4], buf[RTCC_ALARM_MAP_SIZE]; + + if(state == RTCC_ALARM_OFF) { + if(ab08_read_reg((INT_MASK_ADDR + CONFIG_MAP_OFFSET), + &aux[0], 1) == AB08_ERROR) { + PRINTF("RTC: failed to retrieve INTMASK register\n"); + return AB08_ERROR; + } + + aux[0] &= ~INTMASK_AIE; + + if(ab08_write_reg((INT_MASK_ADDR + CONFIG_MAP_OFFSET), + &aux[0], 1) == AB08_ERROR) { + PRINTF("RTC: failed to clear the alarm config\n"); + return AB08_ERROR; + } + return AB08_SUCCESS; + } + + if((data == NULL) || (ab08_check_td_format(data, 1) == AB08_ERROR)) { + PRINTF("RTC: invalid alarm values\n"); + return AB08_ERROR; + } + + if((state >= RTCC_ALARM_MAX) || (repeat >= RTCC_REPEAT_100THS)) { + PRINTF("RTC: invalid alarm config type or state\n"); + return AB08_ERROR; + } + + /* Stop the RTCC */ + ab08_ctrl1_config(RTCC_CMD_STOP); + + buf[WEEKDAYS_ALARM_ADDR] = dec_to_bcd(data->weekdays); + buf[MONTHS_ALARM_ADDR] = dec_to_bcd(data->months); + buf[DAY_ALARMS_ADDR] = dec_to_bcd(data->day); + buf[HOURS_ALARM_ADDR] = dec_to_bcd(data->hours); + buf[MINUTES_ALARM_ADDR] = dec_to_bcd(data->minutes); + buf[SECONDS_ALARM_ADDR] = dec_to_bcd(data->seconds); + buf[HUNDREDTHS_ALARM_ADDR] = dec_to_bcd(data->miliseconds); + + /* Check if the 12h/24h match the current configuration */ + if(ab08_read_reg((CTRL_1_ADDR + CONFIG_MAP_OFFSET), + &aux[0], 1) == AB08_ERROR) { + PRINTF("RTC: failed to retrieve CONTROL1 register\n"); + return AB08_ERROR; + } + + if(((aux[0] & CTRL1_1224) && (data->mode == RTCC_24H_MODE)) || + (!(aux[0] & CTRL1_1224) && ((data->mode == RTCC_12H_MODE_AM) || + (data->mode == RTCC_12H_MODE_PM)))) { + PRINTF("RTC: 12/24h mode and present date config mismatch\n"); + return AB08_ERROR; + } + + if(data->mode != RTCC_24H_MODE) { + if((data->hours == 0) || (data->hours > 12)) { + PRINTF("RTC: Invalid hour configuration (12h mode selected)\n"); + return AB08_ERROR; + } + + /* Toggle the PM bit */ + if(data->mode == RTCC_12H_MODE_PM) { + buf[HOURS_ALARM_ADDR] |= RTCC_TOGGLE_PM_BIT; + } + } + + /* Clear the RPT field */ + if(ab08_read_reg((TIMER_CONTROL_ADDR + CONFIG_MAP_OFFSET), + &aux[0], 1) == AB08_ERROR) { + PRINTF("RTC: failed to retrieve TIMER CTRL register\n"); + return AB08_ERROR; + } + + aux[0] &= ~COUNTDOWN_TIMER_RPT_SECOND; + + /* AB08XX application manual, table 76 */ + if(repeat == RTCC_REPEAT_10THS) { + buf[HUNDREDTHS_ALARM_ADDR] |= RTCC_FIX_10THS_HUNDRETHS; + repeat = RTCC_REPEAT_SECOND; + } else if(repeat == RTCC_REPEAT_100THS) { + buf[HUNDREDTHS_ALARM_ADDR] |= RTCC_FIX_100THS_HUNDRETHS; + repeat = RTCC_REPEAT_SECOND; + } + + if(repeat != RTCC_REPEAT_NONE) { + aux[0] |= (repeat << COUNTDOWN_TIMER_RPT_SHIFT); + } + + /* We are using as default the level interrupt instead of pulses */ + /* FIXME: make this selectable */ + aux[0] |= COUNTDOWN_TIMER_TM; + aux[0] &= ~COUNTDOWN_TIMER_TRPT; + + if(ab08_write_reg((TIMER_CONTROL_ADDR + CONFIG_MAP_OFFSET), + &aux[0], 1) == AB08_ERROR) { + PRINTF("RTC: failed to clear the alarm config\n"); + return AB08_ERROR; + } + + if(ab08_read_reg((STATUS_ADDR + CONFIG_MAP_OFFSET), + aux, 4) == AB08_ERROR) { + PRINTF("RTC: failed to read configuration registers\n"); + return AB08_ERROR; + } + + /* Clear ALM field if any */ + aux[STATUS_ADDR] &= ~STATUS_ALM; + +#if RTCC_CLEAR_INT_MANUALLY + aux[CTRL_1_ADDR] &= ~CTRL1_ARST; +#endif + + /* Clear the AIE alarm bit */ + aux[INT_MASK_ADDR] &= ~INTMASK_AIE; + + /* Configure Interrupt parameters for Alarm Interrupt Mode in nIRQ pin, + * and fixed level until interrupt flag is cleared + */ + + /* Enable nIRQ if at least one interrupt is enabled */ + aux[CTRL_2_ADDR] |= CTRL2_OUT1S_NIRQ_NAIRQ_OUT; + + if(repeat != RTCC_REPEAT_NONE) { + aux[INT_MASK_ADDR] &= ~INTMASK_IM_LOW; + } else { + aux[INT_MASK_ADDR] |= INTMASK_IM_LOW; + } + + if(ab08_write_reg((STATUS_ADDR + CONFIG_MAP_OFFSET), aux, 4) == AB08_ERROR) { + PRINTF("RTC: failed to clear alarm config\n"); + return AB08_ERROR; + } + + /* Enable interrupts */ + GPIO_ENABLE_INTERRUPT(RTC_INT1_PORT_BASE, RTC_INT1_PIN_MASK); + ioc_set_over(RTC_INT1_PORT, RTC_INT1_PIN, IOC_OVERRIDE_PUE); + nvic_interrupt_enable(RTC_INT1_VECTOR); + + /* Write to the alarm counters */ + if(ab08_write_reg((HUNDREDTHS_ALARM_ADDR + ALARM_MAP_OFFSET), buf, + RTCC_ALARM_MAP_SIZE) == AB08_ERROR) { + PRINTF("RTC: failed to set the alarm\n"); + return AB08_ERROR; + } + + /* And finally enable the AIE bit */ + aux[INT_MASK_ADDR] |= INTMASK_AIE; + if(ab08_write_reg((INT_MASK_ADDR + CONFIG_MAP_OFFSET), + &aux[INT_MASK_ADDR], 1) == AB08_ERROR) { + PRINTF("RTC: failed to enable the alarm\n"); + return AB08_ERROR; + } + + /* Enable back the RTCC */ + ab08_ctrl1_config(RTCC_CMD_ENABLE); + + return AB08_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +PROCESS(rtcc_int_process, "RTCC interruption process handler"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(rtcc_int_process, ev, data) +{ + static uint8_t buf; + PROCESS_EXITHANDLER(); + PROCESS_BEGIN(); + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + + if(ab08_read_status(&buf) == AB08_ERROR) { + PRINTF("RTC: failed to retrieve ARST value\n"); + PROCESS_EXIT(); + } + + /* We only handle the AIE (alarm interrupt) only */ + if((buf & STATUS_ALM) && (rtcc_int1_callback != NULL)) { +#if RTCC_CLEAR_INT_MANUALLY + buf &= ~STATUS_ALM; + if(ab08_write_reg((STATUS_ADDR + CONFIG_MAP_OFFSET), + &buf, 1) == AB08_ERROR) { + PRINTF("RTC: failed to clear the alarm\n"); + return AB08_ERROR; + } +#endif + rtcc_int1_callback(0); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +int8_t +rtcc_print(uint8_t value) +{ + uint8_t i, len, reg; + char **name; + uint8_t rtc_buffer[RTCC_CONFIG_MAP_SIZE]; + + if(value >= RTCC_PRINT_MAX) { + return AB08_ERROR; + } + + switch(value) { + case RTCC_PRINT_CONFIG: + len = (RTCC_CONFIG_MAP_SIZE - 1); + reg = STATUS_ADDR + CONFIG_MAP_OFFSET; + name = (char **)ab080x_config_register_name; + break; + case RTCC_PRINT_ALARM: + case RTCC_PRINT_ALARM_DEC: + len = RTCC_ALARM_MAP_SIZE; + reg = HUNDREDTHS_ALARM_ADDR + ALARM_MAP_OFFSET; + name = (char **)ab080x_td_register_name; + break; + case RTCC_PRINT_DATE: + case RTCC_PRINT_DATE_DEC: + len = RTCC_TD_MAP_SIZE; + reg = CENTHS_ADDR; + name = (char **)ab080x_td_register_name; + break; + default: + return AB08_ERROR; + } + + if(ab08_read_reg(reg, rtc_buffer, len) == AB08_ERROR) { + PRINTF("RTC: failed to retrieve values to print\n"); + return AB08_ERROR; + } + + if(value == RTCC_PRINT_ALARM_DEC) { + printf("%02u/%02u (%02u) %02u:%02u:%02u/%02u\n", + bcd_to_dec(rtc_buffer[MONTHS_ALARM_ADDR]), + bcd_to_dec(rtc_buffer[DAY_ALARMS_ADDR]), + bcd_to_dec(rtc_buffer[WEEKDAYS_ALARM_ADDR]), + bcd_to_dec(rtc_buffer[HOURS_ALARM_ADDR]), + bcd_to_dec(rtc_buffer[MINUTES_ALARM_ADDR]), + bcd_to_dec(rtc_buffer[SECONDS_ALARM_ADDR]), + bcd_to_dec(rtc_buffer[HUNDREDTHS_ALARM_ADDR])); + return AB08_SUCCESS; + } + + if(value == RTCC_PRINT_DATE_DEC) { + printf("%02u/%02u/%02u (%02u) %02u:%02u:%02u/%02u\n", + bcd_to_dec(rtc_buffer[YEAR_ADDR]), + bcd_to_dec(rtc_buffer[MONTHS_ADDR]), + bcd_to_dec(rtc_buffer[DAY_ADDR]), + bcd_to_dec(rtc_buffer[WEEKDAYLS_ADDR]), + bcd_to_dec(rtc_buffer[HOUR_ADDR]), + bcd_to_dec(rtc_buffer[MIN_ADDR]), + bcd_to_dec(rtc_buffer[SEC_ADDR]), + bcd_to_dec(rtc_buffer[CENTHS_ADDR])); + return AB08_SUCCESS; + } + + for(i = 0; i < len; i++) { + printf("0x%02X <- %s\n", rtc_buffer[i], name[i]); + } + + return AB08_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static void +rtcc_interrupt_handler(uint8_t port, uint8_t pin) +{ + process_poll(&rtcc_int_process); +} +/*---------------------------------------------------------------------------*/ +int8_t +rtcc_set_autocalibration(uint8_t period) +{ + uint8_t aux; + + if(period > RTCC_AUTOCAL_9_MIN) { + PRINTF("RTC: invalid autocal value\n"); + return AB08_ERROR; + } + + if(ab08_read_reg((OSC_CONTROL_ADDR + CONFIG_MAP_OFFSET), + &aux, 1) == AB08_ERROR) { + PRINTF("RTC: failed to read oscillator registers\n"); + return AB08_ERROR; + } + + /* Clear ACAL */ + aux &= ~OSCONTROL_ACAL_9_MIN; + + /* Unlock the key register */ + ab08_key_reg(RTCC_CONFKEY_OSCONTROL); + + switch(period) { + case RTCC_AUTOCAL_DISABLE: + break; + case RTCC_AUTOCAL_ONCE: + case RTCC_AUTOCAL_17_MIN: + aux |= OSCONTROL_ACAL_17_MIN; + break; + case RTCC_AUTOCAL_9_MIN: + aux |= OSCONTROL_ACAL_9_MIN; + break; + default: + return AB08_ERROR; + } + + if(ab08_write_reg((OSC_CONTROL_ADDR + CONFIG_MAP_OFFSET), + &aux, 1) == AB08_ERROR) { + PRINTF("RTC: failed to clear the autocalibration\n"); + return AB08_ERROR; + } + + if(period == RTCC_AUTOCAL_ONCE) { + clock_delay_usec(10000); + ab08_key_reg(RTCC_CONFKEY_OSCONTROL); + aux &= ~OSCONTROL_ACAL_9_MIN; + if(ab08_write_reg((OSC_CONTROL_ADDR + CONFIG_MAP_OFFSET), + &aux, 1) == AB08_ERROR) { + PRINTF("RTC: failed to clear the autocalibration\n"); + return AB08_ERROR; + } + } + + return AB08_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int8_t +rtcc_set_calibration(uint8_t mode, int32_t adjust) +{ + int32_t adjint; + uint8_t adjreg[2]; + uint8_t xtcal; + + if(mode > RTCC_CAL_RC_OSC) { + PRINTF("RTC: invalid calibration mode\n"); + return AB08_ERROR; + } + + /* Fixed values dependant on the oscillator source (Application Manual) */ + if((mode == RTCC_CAL_XT_OSC) && ((adjust <= -610) || (adjust >= 242))) { + PRINTF("RTC: invalid adjust value for XT oscillator\n"); + return AB08_ERROR; + } + + if((mode == RTCC_CAL_RC_OSC) && ((adjust <= -65536) || (adjust >= 65520))) { + PRINTF("RTC: invalid adjust value for XT oscillator\n"); + return AB08_ERROR; + } + + /* Calibration routine taken from the Application manual */ + if(adjust < 0) { + adjint = ((adjust) * 1000 - 953); + } else { + adjint = ((adjust) * 1000 + 953); + } + + adjint = adjint / 1907; + + if(mode == RTCC_CAL_XT_OSC) { + if(adjint > 63) { + xtcal = 0; + /* CMDX = 1 */ + adjreg[0] = ((adjint >> 1) & 0x3F) | 0x80; + } else if(adjint > -65) { + xtcal = 0; + adjreg[0] = (adjint & 0x7F); + } else if(adjint > -129) { + xtcal = 1; + adjreg[0] = ((adjint + 64) & 0x7F); + } else if(adjint > -193) { + xtcal = 2; + adjreg[0] = ((adjint + 128) & 0x7F); + } else if(adjint > -257) { + xtcal = 3; + adjreg[0] = ((adjint + 192) & 0x7F); + } else { + xtcal = 3; + adjreg[0] = ((adjint + 192) >> 1) & 0xFF; + } + + if(ab08_write_reg((CAL_XT_ADDR + CONFIG_MAP_OFFSET), + &adjreg[0], 1) == AB08_ERROR) { + PRINTF("RTC: failed to clear the autocalibration\n"); + return AB08_ERROR; + } + + if(ab08_read_reg((OSC_STATUS_ADDR + CONFIG_MAP_OFFSET), + &adjreg[0], 1) == AB08_ERROR) { + PRINTF("RTC: failed to read oscillator registers\n"); + return AB08_ERROR; + } + + /* Clear XTCAL and write new value */ + adjreg[0] &= 0x3F; + adjreg[0] |= (xtcal << 6); + + if(ab08_write_reg((OSC_STATUS_ADDR + CONFIG_MAP_OFFSET), + &adjreg[0], 1) == AB08_ERROR) { + PRINTF("RTC: failed to clear the autocalibration\n"); + return AB08_ERROR; + } + } else if(mode == RTCC_CAL_RC_OSC) { + if(adjint > 32767) { + adjreg[1] = ((adjint >> 3) & 0xFF); + adjreg[0] = ((adjint >> 11) | 0xC0); + } else if(adjint > 16383) { + adjreg[1] = ((adjint >> 2) & 0xFF); + adjreg[0] = ((adjint >> 10) | 0x80); + } else if(adjint > 8191) { + adjreg[1] = ((adjint >> 1) & 0xFF); + adjreg[0] = ((adjint >> 9) | 0x40); + } else if(adjint >= 0) { + adjreg[1] = ((adjint) & 0xFF); + adjreg[0] = (adjint >> 8); + } else if(adjint > -8193) { + adjreg[1] = ((adjint) & 0xFF); + adjreg[0] = (adjint >> 8) & 0x3F; + } else if(adjint > -16385) { + adjreg[1] = ((adjint >> 1) & 0xFF); + adjreg[0] = (adjint >> 9) & 0x7F; + } else if(adjint > -32769) { + adjreg[1] = ((adjint >> 2) & 0xFF); + adjreg[0] = (adjint >> 10) & 0xBF; + } else { + adjreg[1] = ((adjint >> 3) & 0xFF); + adjreg[0] = (adjint >> 11) & 0xFF; + } + + if(ab08_write_reg((CAL_RC_HI_ADDR + CONFIG_MAP_OFFSET), + adjreg, 2) == AB08_ERROR) { + PRINTF("RTC: failed to set the RC calibration\n"); + return AB08_ERROR; + } + + /* This should not happen */ + } else { + return AB08_ERROR; + } + + return AB08_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int8_t +rtcc_init(void) +{ + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_NORMAL_BUS_SPEED); + +#if RTCC_SET_DEFAULT_CONFIG + write_default_config(); +#endif + +#if RTCC_SET_AUTOCAL + rtcc_set_autocalibration(RTCC_AUTOCAL_17_MIN); +#endif + + /* Initialize interrupts handlers */ + rtcc_int1_callback = NULL; + + /* Configure the interrupts pins */ + GPIO_SOFTWARE_CONTROL(RTC_INT1_PORT_BASE, RTC_INT1_PIN_MASK); + GPIO_SET_INPUT(RTC_INT1_PORT_BASE, RTC_INT1_PIN_MASK); + + /* Pull-up resistor, detect falling edge */ + GPIO_DETECT_EDGE(RTC_INT1_PORT_BASE, RTC_INT1_PIN_MASK); + GPIO_TRIGGER_SINGLE_EDGE(RTC_INT1_PORT_BASE, RTC_INT1_PIN_MASK); + GPIO_DETECT_FALLING(RTC_INT1_PORT_BASE, RTC_INT1_PIN_MASK); + gpio_register_callback(rtcc_interrupt_handler, RTC_INT1_PORT, RTC_INT1_PIN); + + /* Spin process until an interrupt is received */ + process_start(&rtcc_int_process, NULL); + + return AB08_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/platform/zoul/remote/rtcc.h b/platform/zoul/remote/rtcc.h new file mode 100644 index 000000000..4bbcbfe4f --- /dev/null +++ b/platform/zoul/remote/rtcc.h @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2015, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +/* -------------------------------------------------------------------------- */ +/** + * \addtogroup remote + * @{ + * + * \defgroup remote-rtcc RE-Mote Real Time Clock Calendar + * + * Driver for the RE-Mote on-board ultra-low power RTCC (Real Time Clock + * Calendar) + * @{ + * + * \file + * Header file for the RE-Mote RF antenna switch + */ +/* -------------------------------------------------------------------------- */ +#ifndef RTCC_H_ +#define RTCC_H_ +/* -------------------------------------------------------------------------- */ +#include +#include "i2c.h" +/* -------------------------------------------------------------------------- */ +/** + * \name Callback function to handle the RTCC alarm interrupt and macro + * @{ + */ +#define RTCC_REGISTER_INT1(ptr) rtcc_int1_callback = ptr; +extern void (*rtcc_int1_callback)(uint8_t value); +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name AB08XX Address registers + * @{ + */ +/* -------------------------------------------------------------------------- */ +/* Time/date registers (no offset) */ +#define CENTHS_ADDR 0x00 +#define SEC_ADDR 0x01 +#define MIN_ADDR 0x02 +#define HOUR_ADDR 0x03 +#define DAY_ADDR 0x04 +#define MONTHS_ADDR 0x05 +#define YEAR_ADDR 0x06 +#define WEEKDAYLS_ADDR 0x07 + +/* Alarm registers */ +#define ALARM_MAP_OFFSET 0x08 +#define HUNDREDTHS_ALARM_ADDR 0x00 +#define SECONDS_ALARM_ADDR 0x01 +#define MINUTES_ALARM_ADDR 0x02 +#define HOURS_ALARM_ADDR 0x03 +#define DAY_ALARMS_ADDR 0x04 +#define MONTHS_ALARM_ADDR 0x05 +#define WEEKDAYS_ALARM_ADDR 0x06 + +/* Configuration registers */ +#define CONFIG_MAP_OFFSET 0x0F +#define STATUS_ADDR 0x00 +#define CTRL_1_ADDR 0x01 +#define CTRL_2_ADDR 0x02 +#define INT_MASK_ADDR 0x03 +#define SQW_ADDR 0x04 +#define CAL_XT_ADDR 0x05 +#define CAL_RC_HI_ADDR 0x06 +#define CAL_RC_LO_ADDR 0x07 +#define INT_POL_ADDR 0x08 +#define TIMER_CONTROL_ADDR 0x09 +#define TIMER_COUNTDOWN_ADDR 0x0A +#define TIMER_INITIAL_ADDR 0x0B +#define WDT_ADDR 0x0C +#define OSC_CONTROL_ADDR 0x0D +#define OSC_STATUS_ADDR 0x0E +#define CONF_KEY_ADDR 0x10 +#define TRICKLE_ADDR 0x11 +#define BREF_CTRL_ADDR 0x12 +#define AF_CTRL_ADDR 0x17 +#define BAT_MODE_IO_ADDR 0x18 +#define ASTAT_ADDR 0x20 +#define OCTRL_ADDR 0x21 +#define EXT_ADDR 0x30 +/* 256b. The upper 2 bits are taken from XADS field */ +#define RAM_1_ADDR (CONFIG_MAP_OFFSET + 0x31) +/* 256b. The upper 2 bits are taken from XADA field */ +#define RAM_2_ADDR (CONFIG_MAP_OFFSET + 0x71) +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name RTCC Bitmasks and shifts + * @{ + */ +#define STATUS_CB 0x80 +#define STATUS_BAT 0x40 +#define STATUS_WDT 0x20 +#define STATUS_BL 0x10 +#define STATUS_TIM 0x08 +#define STATUS_ALM 0x04 +#define STATUS_EX2 0x02 +#define STATUS_EX1 0x01 + +#define CTRL1_WRTC 0x01 +#define CTRL1_ARST 0x04 +#define CTRL1_OUT 0x10 +#define CTRL1_OUTB 0x20 +#define CTRL1_1224 0x40 +#define CTRL1_STOP 0x80 + +/* Defines the nIRQ pin control */ +#define CTRL2_OUT1S_NIRQ_OUT 0x00 +#define CTRL2_OUT1S_NIRQ_SQW_OUT 0x01 +#define CTRL2_OUT1S_NIRQ_SQW_NIRQ 0x02 +#define CTRL2_OUT1S_NIRQ_NAIRQ_OUT 0x03 + +/* Defines the nIRQ2 pin control */ +#define CTRL2_OUT2S_SQW_OUT 0x04 +#define CTRL2_OUT2S_NAIRQ_OUTB 0x0C +#define CTRL2_OUT2S_TIRQ_OUTB 0x10 +#define CTRL2_OUT2S_NTIRQ_OUTB 0x14 +#define CTRL2_OUT2S_OUTB 0x1C + +/* Interrupt Mask */ +#define INTMASK_EX1E 0x01 +#define INTMASK_EX2E 0x02 +#define INTMASK_AIE 0x04 +#define INTMASK_TIE 0x08 +#define INTMASK_BLIE 0x10 +#define INTMASK_IM_HIGH 0x20 +#define INTMASK_IM_MED 0x40 +#define INTMASK_IM_LOW 0x60 +#define INTMASK_CEB 0x80 + +/* Timer countdown control */ +#define COUNTDOWN_TIMER_TE 0x80 +#define COUNTDOWN_TIMER_TM 0x40 +#define COUNTDOWN_TIMER_TRPT 0x20 +#define COUNTDOWN_TIMER_RPT_SECOND 0x1C +#define COUNTDOWN_TIMER_RPT_MINUTE 0x18 +#define COUNTDOWN_TIMER_RPT_HOUR 0x24 +#define COUNTDOWN_TIMER_RPT_DAY 0x10 +#define COUNTDOWN_TIMER_RPT_WEEK 0x0C +#define COUNTDOWN_TIMER_RPT_MONTH 0x08 +#define COUNTDOWN_TIMER_RPT_YEAR 0x04 +#define COUNTDOWN_TIMER_RPT_SHIFT 0x02 +#define COUNTDOWN_TIMER_TFS_ONE 0x01 +#define COUNTDOWN_TIMER_TFS_TWO 0x02 +#define COUNTDOWN_TIMER_TFS_THREE 0x03 + +/* Oscillator control */ +#define OSCONTROL_ACIE 0x01 +#define OSCONTROL_OFIE 0x02 +#define OSCONTROL_FOS 0x08 +#define OSCONTROL_AOS 0x10 +#define OSCONTROL_ACAL_NO_CAL 0x00 +#define OSCONTROL_ACAL_17_MIN 0x40 +#define OSCONTROL_ACAL_9_MIN 0x60 +#define OSCONTROL_OSEL 0x80 + +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name RTCC operational values + * @{ + */ +/* I2C address (7-bits) */ +#define AB08XX_ADDR 0x69 +#define INT_BUFF_SIZE 20L +#define TCS_DIODE_3K (TCS_ENABLE + 0x05) +#define TCS_DIODE_6K (TCS_ENABLE + 0x06) +#define TCS_DIODE_11K (TCS_ENABLE + 0x07) +#define RTCC_TOGGLE_PM_BIT 0x20 +#define RTCC_FIX_10THS_HUNDRETHS 0xF0 +#define RTCC_FIX_100THS_HUNDRETHS 0xFF +#define RTCC_TD_MAP_SIZE (WEEKDAYLS_ADDR + 1) +#define RTCC_ALARM_MAP_SIZE (WEEKDAYS_ALARM_ADDR + 1) +#define RTCC_CONFIG_MAP_SIZE (BREF_CTRL_ADDR + 1) +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name RTCC error values + * @{ + */ +#define AB08_ERROR (-1) +#define AB08_SUCCESS 0x00 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name RTCC enumeration and options + * @{ + */ +enum { + RTCC_PRINT_DATE = 0, + RTCC_PRINT_CONFIG, + RTCC_PRINT_ALARM, + RTCC_PRINT_ALARM_DEC, + RTCC_PRINT_DATE_DEC, + RTCC_PRINT_MAX, +}; +/* -------------------------------------------------------------------------- */ +enum { + RTCC_ALARM_OFF = 0, + RTCC_ALARM_ON, + RTCC_ALARM_MAX, +}; +/* -------------------------------------------------------------------------- */ +enum { + RTCC_CMD_UNLOCK = 0, + RTCC_CMD_LOCK, + RTCC_CMD_ENABLE, + RTCC_CMD_STOP, + RTCC_CMD_MAX, +}; +/* -------------------------------------------------------------------------- */ +enum { + RTCC_24H_MODE = 0, + RTCC_12H_MODE_AM, + RTCC_12H_MODE_PM, +}; +/* -------------------------------------------------------------------------- */ +enum { + RTCC_CENTURY_19XX_21XX = 1, + RTCC_CENTURY_20XX, +}; +/* -------------------------------------------------------------------------- */ +enum { + RTCC_REPEAT_NONE = 0, + RTCC_REPEAT_YEAR, + RTCC_REPEAT_MONTH, + RTCC_REPEAT_WEEK, + RTCC_REPEAT_DAY, + RTCC_REPEAT_HOUR, + RTCC_REPEAT_MINUTE, + RTCC_REPEAT_SECOND, + RTCC_REPEAT_10THS, + RTCC_REPEAT_100THS, +}; +/* -------------------------------------------------------------------------- */ +enum { + RTCC_CONFKEY_OSCONTROL = 0xA1, + RTCC_CONFKEY_SWRESET = 0x3C, + RTCC_CONFKEY_DEFREGS = 0x9D, +}; +/* -------------------------------------------------------------------------- */ +enum { + RTCC_CAL_XT_OSC = 0, + RTCC_CAL_RC_OSC, +}; +/* -------------------------------------------------------------------------- */ +enum { + RTCC_AUTOCAL_DISABLE = 0, + RTCC_AUTOCAL_ONCE, + RTCC_AUTOCAL_17_MIN, + RTCC_AUTOCAL_9_MIN, +}; +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name Readable Date and time memory map implementation + * + * This simplified structure allows the user to set date/alarms with a + * reduced structure, without the bit-defined restrictions of the memory map, + * using decimal values + * + * @{ + */ +typedef struct ab0805_struct_simple_td_reg { + uint8_t miliseconds; + uint8_t seconds; + uint8_t minutes; + uint8_t hours; + uint8_t day; + uint8_t months; + uint8_t years; + uint8_t weekdays; + uint8_t mode; + uint8_t century; +} __attribute__ ((packed)) simple_td_map; +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name RTCC User functions + * @{ + */ + +/** + * \brief Set the time and date + * \param *data Time and date value (decimal format) + * \return + * \ AB08_SUCCESS date/time set + * \ AB08_ERROR failed to set time/date (enable DEBUG for more info) + */ +int8_t rtcc_set_time_date(simple_td_map *data); + +/** + * \brief Get the current time and date + * \param *data buffer to store the results + * \return + * \ AB08_SUCCESS date/time set + * \ AB08_ERROR failed to set time/date (enable DEBUG for more info) + */ +int8_t rtcc_get_time_date(simple_td_map *data); + +/** + * \brief Print data from the RTCC module, either from the memory + * map (values in BCD) or actual readable data (decimal). + * \param value value to print, see RTCC_PRINT_* options available + * \return + * \ AB08_SUCCESS date/time set + * \ AB08_ERROR failed to set time/date (enable DEBUG for more info) + */ +int8_t rtcc_print(uint8_t value); + +/** + * \brief Configure the RTCC to match an alarm counter + * \param data date and time values (in decimal) to match against + * \param state set on/off the alarm interruption + * \param repeat set the frequency of the alarm (minute, hourly, daily, etc.) + * \return + * \ AB08_SUCCESS date/time set + * \ AB08_ERROR failed to set time/date (enable DEBUG for more info) + */ +int8_t rtcc_set_alarm_time_date(simple_td_map *data, uint8_t state, + uint8_t repeat); + +/** + * \brief Manually calibrate the RTCC + * \param mode oscillator to calibrate + * \param adjust value (in ppm) to adjust the oscillator + * \return + * \ AB08_SUCCESS date/time set + * \ AB08_ERROR failed to set time/date (enable DEBUG for more info) + */ +int8_t rtcc_set_calibration(uint8_t mode, int32_t adjust); + +/** + * \brief Set the autocallibration period + * \param period autocalibration configuration + * \return + * \ AB08_SUCCESS date/time set + * \ AB08_ERROR failed to set time/date (enable DEBUG for more info) + */ +int8_t rtcc_set_autocalibration(uint8_t period); + +/** + * \brief Initialize the RTCC, configures the I2C bus, interrupts and registers + * \return + * \ AB08_SUCCESS date/time set + * \ AB08_ERROR failed to set time/date (enable DEBUG for more info) + */ +int8_t rtcc_init(void); +/** @} */ +/* -------------------------------------------------------------------------- */ +#endif /* ifndef RTCC_H_ */ +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ diff --git a/platform/zoul/zolertia-zoul-cdc-acm.inf b/platform/zoul/zolertia-zoul-cdc-acm.inf new file mode 100755 index 000000000..00ac60439 --- /dev/null +++ b/platform/zoul/zolertia-zoul-cdc-acm.inf @@ -0,0 +1,64 @@ +; Windows LUFA CDC ACM Setup File +; Copyright (c) 2000 Microsoft Corporation + +[DefaultInstall] +CopyINF="zolertia-zoul-cdc-acm.inf" + +[Version] +Signature="$Windows NT$" +Class=Ports +ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} +Provider=%MFGNAME% +DriverVer=7/1/2012,10.0.0.0 + +[Manufacturer] +%MFGNAME%=DeviceList, NTx86, NTamd64, NTia64 + +[SourceDisksNames] + +[SourceDisksFiles] + +[DestinationDirs] +DefaultDestDir=12 + +[DriverInstall] +Include=mdmcpq.inf +CopyFiles=FakeModemCopyFileSection +AddReg=DriverInstall.AddReg + +[DriverInstall.Services] +Include=mdmcpq.inf +AddService=usbser, 0x00000002, LowerFilter_Service_Inst + +[DriverInstall.AddReg] +HKR,,EnumPropPages32,,"msports.dll,SerialPortPropPageProvider" + +;------------------------------------------------------------------------------ +; Vendor and Product ID Definitions +;------------------------------------------------------------------------------ +; When developing your USB device, the VID and PID used in the PC side +; application program and the firmware on the microcontroller must match. +; Modify the below line to use your VID and PID. Use the format as shown below. +; Note: One INF file can be used for multiple devices with different VID and PIDs. +; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line. +;------------------------------------------------------------------------------ +[DeviceList] +%DESCRIPTION%=DriverInstall, USB\VID_0451&PID_16C8 + +[DeviceList.NTx86] +%DESCRIPTION%=DriverInstall, USB\VID_0451&PID_16C8 + +[DeviceList.NTamd64] +%DESCRIPTION%=DriverInstall, USB\VID_0451&PID_16C8 + +[DeviceList.NTia64] +%DESCRIPTION%=DriverInstall, USB\VID_0451&PID_16C8 + +;------------------------------------------------------------------------------ +; String Definitions +;------------------------------------------------------------------------------ +;Modify these strings to customize your device +;------------------------------------------------------------------------------ +[Strings] +MFGNAME="http://zolertia.io" +DESCRIPTION="Zolertia Zoul Virtual COM Port" diff --git a/regression-tests/00-doxygen/Makefile b/regression-tests/00-doxygen/Makefile new file mode 100644 index 000000000..86196d6bf --- /dev/null +++ b/regression-tests/00-doxygen/Makefile @@ -0,0 +1,57 @@ +# Copyright (c) 2014, Friedrich-Alexander University Erlangen-Nuremberg +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. 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. +# 3. Neither the name of the University 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 UNIVERSITY 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 INSTITUTE 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. + +DOCDIR=../../doc + +all: summary + +doxygen: + @make -C $(DOCDIR) doxygen.log 2> doxygen.runerr > doxygen.runlog + +summary: doxygen + @( \ + 1> summary; \ + if [ -s doxygen.runerr ] ; then \ + echo "doxygen: FAIL ಠ_ಠ\nDoxygen caused some runtime warnings. Please fix these." >> summary; \ + echo "Runtime warnings:" >> summary; \ + cat doxygen.runerr >> summary; \ + echo >> summary; \ + fi ; \ + if [ -s $(DOCDIR)/doxygen.log ] ; then \ + echo "doxygen: FAIL ಠ_ಠ\nDoxygen caused some warnings. Please fix these." >> summary; \ + echo "Warnings:" >> summary; \ + cat $(DOCDIR)/doxygen.log >> summary; \ + fi ; \ + if [ ! -s summary ] ; then \ + echo "doxygen: OK\nDoxygen found no warnings" >> summary; \ + fi ; \ + cat summary \ + ) + +clean: + @rm -f summary doxygen.runlog doxygen.runerr + @make -C $(DOCDIR) clean diff --git a/regression-tests/01-compile-base/Makefile b/regression-tests/01-compile-base/Makefile index d6fb60a91..bc38a9777 100644 --- a/regression-tests/01-compile-base/Makefile +++ b/regression-tests/01-compile-base/Makefile @@ -13,14 +13,14 @@ hello-world/wismote \ hello-world/z1 \ eeprom-test/native \ collect/sky \ -er-rest-example/sky \ +er-rest-example/wismote \ +ipso-objects/wismote \ example-shell/native \ netperf/sky \ powertrace/sky \ rime/sky \ rime/z1 \ ravenusbstick/avr-ravenusb \ -rest-example/sky \ servreg-hack/sky \ sky/sky \ sky-ip/sky \ @@ -30,12 +30,18 @@ sky-shell-webserver/sky \ tcp-socket/minimal-net \ telnet-server/minimal-net \ webserver/minimal-net \ -webserver-ipv6/exp5438 \ webserver-ipv6/eval-adf7xxxmb4z \ wget/minimal-net \ -z1/z1 \ +zolertia/z1/z1 \ settings-example/avr-raven \ ipv6/multicast/sky \ +ipv6/rpl-tsch/z1 \ +ipv6/rpl-tsch/z1:MAKE_WITH_ORCHESTRA=1 \ +ipv6/rpl-tsch/z1:MAKE_WITH_SECURITY=1 \ +cfs-coffee/sky \ +cfs-coffee/z1 \ +cfs-coffee/wismote \ +cfs-coffee/avr-raven TOOLS= diff --git a/regression-tests/02-hello-world/02-hello-world-sky.csc b/regression-tests/02-hello-world/02-hello-world-sky.csc index 5b5dacc1e..1c656fc71 100644 --- a/regression-tests/02-hello-world/02-hello-world-sky.csc +++ b/regression-tests/02-hello-world/02-hello-world-sky.csc @@ -1,82 +1,82 @@ - - - - Hello World test (Sky) - generated - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Sky Mote Type #1 - [CONTIKI_DIR]/examples/hello-world/hello-world.c - make hello-world.sky TARGET=sky - [CONTIKI_DIR]/examples/hello-world/hello-world.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - - - - - org.contikios.cooja.interfaces.Position - 64.11203103628397 - 93.06735634828134 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - org.contikios.cooja.plugins.ScriptRunner - - [CONFIG_DIR]/hello-world.js - true - - 541 - 0 - 448 - 299 - 7 - - - org.contikios.cooja.plugins.SimControl - 280 - 2 - 160 - 7 - 10 - - - org.contikios.cooja.plugins.LogListener - - - - 680 - 1 - 240 - 51 - 288 - - - + + + + Hello World test (Sky) + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Sky Mote Type #1 + [CONTIKI_DIR]/examples/hello-world/hello-world.c + make hello-world.sky TARGET=sky + [CONTIKI_DIR]/examples/hello-world/hello-world.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + + + + + org.contikios.cooja.interfaces.Position + 64.11203103628397 + 93.06735634828134 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + org.contikios.cooja.plugins.ScriptRunner + + [CONFIG_DIR]/hello-world.js + true + + 541 + 0 + 448 + 299 + 7 + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 7 + 10 + + + org.contikios.cooja.plugins.LogListener + + + + 680 + 1 + 240 + 51 + 288 + + + diff --git a/regression-tests/02-hello-world/03-hello-world-micaz.csc b/regression-tests/02-hello-world/03-hello-world-micaz.csc index 5ca8c1cfb..c243b6042 100644 --- a/regression-tests/02-hello-world/03-hello-world-micaz.csc +++ b/regression-tests/02-hello-world/03-hello-world-micaz.csc @@ -1,79 +1,79 @@ - - - - Hello World (MicaZ) - generated - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.avrmote.MicaZMoteType - micaz1 - MicaZ Mote Type #micaz1 - [CONTIKI_DIR]/examples/hello-world/hello-world.c - make hello-world.elf TARGET=micaz - [CONTIKI_DIR]/examples/hello-world/hello-world.elf - org.contikios.cooja.interfaces.Position - org.contikios.cooja.avrmote.interfaces.MicaZID - org.contikios.cooja.avrmote.interfaces.MicaZLED - org.contikios.cooja.avrmote.interfaces.MicaZRadio - org.contikios.cooja.avrmote.interfaces.MicaClock - org.contikios.cooja.avrmote.interfaces.MicaSerial - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - - - - org.contikios.cooja.interfaces.Position - 36.478849033811386 - 97.17795415366507 - 0.0 - - - org.contikios.cooja.avrmote.interfaces.MicaZID - 1 - - micaz1 - - - - org.contikios.cooja.plugins.SimControl - 280 - 2 - 160 - 17 - 16 - - - org.contikios.cooja.plugins.LogListener - - - - 680 - 1 - 240 - 20 - 285 - - - org.contikios.cooja.plugins.ScriptRunner - - [CONFIG_DIR]/hello-world.js - true - - 600 - 0 - 535 - 403 - 23 - - - + + + + Hello World (MicaZ) + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.avrmote.MicaZMoteType + micaz1 + MicaZ Mote Type #micaz1 + [CONTIKI_DIR]/examples/hello-world/hello-world.c + make hello-world.elf TARGET=micaz + [CONTIKI_DIR]/examples/hello-world/hello-world.elf + org.contikios.cooja.interfaces.Position + org.contikios.cooja.avrmote.interfaces.MicaZID + org.contikios.cooja.avrmote.interfaces.MicaZLED + org.contikios.cooja.avrmote.interfaces.MicaZRadio + org.contikios.cooja.avrmote.interfaces.MicaClock + org.contikios.cooja.avrmote.interfaces.MicaSerial + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + + + + org.contikios.cooja.interfaces.Position + 36.478849033811386 + 97.17795415366507 + 0.0 + + + org.contikios.cooja.avrmote.interfaces.MicaZID + 1 + + micaz1 + + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 17 + 16 + + + org.contikios.cooja.plugins.LogListener + + + + 680 + 1 + 240 + 20 + 285 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONFIG_DIR]/hello-world.js + true + + 600 + 0 + 535 + 403 + 23 + + + diff --git a/regression-tests/02-hello-world/05-exp5438-hello-world.csc b/regression-tests/02-hello-world/05-exp5438-hello-world.csc index b45bf5644..bd6267011 100644 --- a/regression-tests/02-hello-world/05-exp5438-hello-world.csc +++ b/regression-tests/02-hello-world/05-exp5438-hello-world.csc @@ -1,83 +1,83 @@ - - - - Hello World (Exp5438) - generated - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#1 - Exp5438 Mote Type exp5438#1 - [CONTIKI_DIR]/examples/hello-world/hello-world.c - make hello-world.exp5438 TARGET=exp5438 - [CONTIKI_DIR]/examples/hello-world/hello-world.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - - - org.contikios.cooja.interfaces.Position - 26.321738050614275 - 34.93092009073432 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - exp5438#1 - - - - org.contikios.cooja.plugins.SimControl - 280 - 2 - 160 - 38 - 49 - - - org.contikios.cooja.plugins.LogListener - - - - 680 - 1 - 240 - 86 - 384 - - - org.contikios.cooja.plugins.ScriptRunner - - [CONFIG_DIR]/hello-world.js - true - - 600 - 0 - 700 - 347 - 21 - - - + + + + Hello World (Exp5438) + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#1 + Exp5438 Mote Type exp5438#1 + [CONTIKI_DIR]/examples/hello-world/hello-world.c + make hello-world.exp5438 TARGET=exp5438 + [CONTIKI_DIR]/examples/hello-world/hello-world.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 26.321738050614275 + 34.93092009073432 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + exp5438#1 + + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 38 + 49 + + + org.contikios.cooja.plugins.LogListener + + + + 680 + 1 + 240 + 86 + 384 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONFIG_DIR]/hello-world.js + true + + 600 + 0 + 700 + 347 + 21 + + + diff --git a/regression-tests/02-hello-world/06-wismote-hello-world.csc b/regression-tests/02-hello-world/06-wismote-hello-world.csc index 3aefd96f9..02b0b718d 100644 --- a/regression-tests/02-hello-world/06-wismote-hello-world.csc +++ b/regression-tests/02-hello-world/06-wismote-hello-world.csc @@ -1,84 +1,84 @@ - - - - Hello World (Wismote) - generated - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.WismoteMoteType - wismote1 - Wismote Mote Type #wismote1 - [CONTIKI_DIR]/examples/hello-world/hello-world.c - make hello-world.wismote TARGET=wismote - [CONTIKI_DIR]/examples/hello-world/hello-world.wismote - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.MspButton - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspDefaultSerial - org.contikios.cooja.mspmote.interfaces.MspLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - - - org.contikios.cooja.interfaces.Position - 36.76551518369201 - 29.330591009779383 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - wismote1 - - - - org.contikios.cooja.plugins.SimControl - 280 - 2 - 160 - 22 - 14 - - - org.contikios.cooja.plugins.LogListener - - - - 680 - 1 - 240 - 84 - 408 - - - org.contikios.cooja.plugins.ScriptRunner - - [CONFIG_DIR]/hello-world.js - true - - 600 - 0 - 548 - 335 - 22 - - - + + + + Hello World (Wismote) + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.WismoteMoteType + wismote1 + Wismote Mote Type #wismote1 + [CONTIKI_DIR]/examples/hello-world/hello-world.c + make hello-world.wismote TARGET=wismote + [CONTIKI_DIR]/examples/hello-world/hello-world.wismote + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 36.76551518369201 + 29.330591009779383 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + wismote1 + + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 22 + 14 + + + org.contikios.cooja.plugins.LogListener + + + + 680 + 1 + 240 + 84 + 408 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONFIG_DIR]/hello-world.js + true + + 600 + 0 + 548 + 335 + 22 + + + diff --git a/regression-tests/02-hello-world/07-z1-hello-world.csc b/regression-tests/02-hello-world/07-z1-hello-world.csc index 12a2b0055..33963c36c 100644 --- a/regression-tests/02-hello-world/07-z1-hello-world.csc +++ b/regression-tests/02-hello-world/07-z1-hello-world.csc @@ -1,83 +1,83 @@ - - - - Hello World (Z1) - generated - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.Z1MoteType - z11 - Z1 Mote Type #z11 - [CONTIKI_DIR]/examples/hello-world/hello-world.c - make hello-world.z1 TARGET=z1 - [CONTIKI_DIR]/examples/hello-world/hello-world.z1 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspDefaultSerial - org.contikios.cooja.mspmote.interfaces.MspLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - - - org.contikios.cooja.interfaces.Position - 94.96401380574989 - 21.247662337471553 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - z11 - - - - org.contikios.cooja.plugins.SimControl - 280 - 2 - 160 - 38 - 13 - - - org.contikios.cooja.plugins.LogListener - - - - 680 - 1 - 240 - 109 - 377 - - - org.contikios.cooja.plugins.ScriptRunner - - [CONFIG_DIR]/hello-world.js - true - - 600 - 0 - 700 - 330 - 24 - - - + + + + Hello World (Z1) + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Z1MoteType + z11 + Z1 Mote Type #z11 + [CONTIKI_DIR]/examples/hello-world/hello-world.c + make hello-world.z1 TARGET=z1 + [CONTIKI_DIR]/examples/hello-world/hello-world.z1 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 94.96401380574989 + 21.247662337471553 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + z11 + + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 38 + 13 + + + org.contikios.cooja.plugins.LogListener + + + + 680 + 1 + 240 + 109 + 377 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONFIG_DIR]/hello-world.js + true + + 600 + 0 + 700 + 330 + 24 + + + diff --git a/regression-tests/03-base/01-multithreading.csc b/regression-tests/03-base/01-multithreading.csc index 4805e47f8..1b98781ac 100644 --- a/regression-tests/03-base/01-multithreading.csc +++ b/regression-tests/03-base/01-multithreading.csc @@ -1,137 +1,137 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - generated - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Sky Mote Type #1 - [CONTIKI_DIR]/examples/multi-threading/multi-threading.c - make clean TARGET=sky -make multi-threading.sky TARGET=sky - [CONTIKI_DIR]/examples/multi-threading/multi-threading.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - - - - - org.contikios.cooja.interfaces.Position - 83.20518861404864 - 11.060511519885651 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - org.contikios.cooja.plugins.SimControl - 265 - 3 - 200 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - 0.9090909090909091 0.0 0.0 0.9090909090909091 49.35891944177396 108.94498952737668 - - 263 - 2 - 292 - 1 - 202 - - - org.contikios.cooja.plugins.LogListener - - - - - 865 - 0 - 209 - 3 - 701 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - 1 - 700 - 267 - 1 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Sky Mote Type #1 + [CONTIKI_DIR]/examples/multi-threading/multi-threading.c + make clean TARGET=sky +make multi-threading.sky TARGET=sky + [CONTIKI_DIR]/examples/multi-threading/multi-threading.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + + + + + org.contikios.cooja.interfaces.Position + 83.20518861404864 + 11.060511519885651 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + org.contikios.cooja.plugins.SimControl + 265 + 3 + 200 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + 0.9090909090909091 0.0 0.0 0.9090909090909091 49.35891944177396 108.94498952737668 + + 263 + 2 + 292 + 1 + 202 + + + org.contikios.cooja.plugins.LogListener + + + + + 865 + 0 + 209 + 3 + 701 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 1 + 700 + 267 + 1 + + + diff --git a/regression-tests/03-base/02-sky-coffee.csc b/regression-tests/03-base/02-sky-coffee.csc index 0fbd86bd6..050b4abc9 100644 --- a/regression-tests/03-base/02-sky-coffee.csc +++ b/regression-tests/03-base/02-sky-coffee.csc @@ -1,118 +1,118 @@ - - - [CONTIKI_DIR]/tools/cooja/apps/mrm - [CONTIKI_DIR]/tools/cooja/apps/mspsim - [CONTIKI_DIR]/tools/cooja/apps/avrora - [CONTIKI_DIR]/tools/cooja/apps/serial_socket - [CONTIKI_DIR]/tools/cooja/apps/collect-view - - test - 0 - generated - 0 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Sky Mote Type #1 - [CONTIKI_DIR]/examples/sky/test-coffee.c - make clean TARGET=sky -make test-coffee.sky TARGET=sky - [CONTIKI_DIR]/examples/sky/test-coffee.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - - - - - org.contikios.cooja.interfaces.Position - 97.11078411573273 - 56.790978919276014 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - org.contikios.cooja.plugins.SimControl - 248 - 0 - 200 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.LogVisualizerSkin - 0.9090909090909091 0.0 0.0 0.9090909090909091 28.717468985697536 3.3718373461127142 - - 246 - 3 - 170 - 1 - 200 - - - org.contikios.cooja.plugins.LogListener - - - - 846 - 2 - 209 - 2 - 370 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 601 - 1 - 370 - 247 - 0 - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + test + 0 + generated + 0 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Sky Mote Type #1 + [CONTIKI_DIR]/examples/cfs-coffee/test-coffee.c + make clean TARGET=sky +make test-coffee.sky TARGET=sky + [CONTIKI_DIR]/examples/cfs-coffee/test-coffee.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + + + + + org.contikios.cooja.interfaces.Position + 97.11078411573273 + 56.790978919276014 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + org.contikios.cooja.plugins.SimControl + 248 + 0 + 200 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.LogVisualizerSkin + 0.9090909090909091 0.0 0.0 0.9090909090909091 28.717468985697536 3.3718373461127142 + + 246 + 3 + 170 + 1 + 200 + + + org.contikios.cooja.plugins.LogListener + + + + 846 + 2 + 209 + 2 + 370 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 601 + 1 + 370 + 247 + 0 + + + diff --git a/regression-tests/03-base/x03-crosslevel.csc b/regression-tests/03-base/x03-crosslevel.csc index b1753fa2b..f8ef61a48 100644 --- a/regression-tests/03-base/x03-crosslevel.csc +++ b/regression-tests/03-base/x03-crosslevel.csc @@ -30,7 +30,7 @@ make example-abc.sky TARGET=sky DEFINES=NETSTACK_MAC=nullmac_driver,NETSTACK_RDC org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.SkyButton org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyByteRadio + org.contikios.cooja.mspmote.interfaces.Msp802154Radio org.contikios.cooja.mspmote.interfaces.MspSerial org.contikios.cooja.mspmote.interfaces.SkyLED org.contikios.cooja.interfaces.RimeAddress diff --git a/regression-tests/04-rime/01-cooja-collect.csc b/regression-tests/04-rime/01-cooja-collect.csc index f4533eeff..0d1b03a94 100644 --- a/regression-tests/04-rime/01-cooja-collect.csc +++ b/regression-tests/04-rime/01-cooja-collect.csc @@ -1,1019 +1,1019 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - Rime collect test - 1 - 10000000 - - org.contikios.cooja.radiomediums.UDGM - 80.0 - 0.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype929 - Contiki Mote Type #1 - [CONTIKI_DIR]/examples/rime/example-collect.c - make example-collect.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - 38.67566417548448 - 47.31532819237484 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 71.13430279192914 - 55.964918387262955 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 228.04679204790637 - 87.17819808323965 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 272.42783222170533 - 46.64334378879388 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 4 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 238.61415527274 - 44.41698596888275 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 5 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 132.73939224849255 - 69.21851375812221 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 13.282402591495124 - 37.55717734948646 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 7 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 231.24739439405175 - 48.67375039920239 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 207.8959314238542 - 1.1350394672889341 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 9 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 92.82161206304569 - 92.33145969594939 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 10 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 160.99396124295916 - 19.643001828505756 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 11 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 200.78134764559428 - 12.892752477526937 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 12 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 205.39914563029964 - 28.760487893562114 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 13 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 252.08232300754125 - 72.49857017173812 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 14 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 229.71392970623077 - 6.54664783066401 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 15 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 278.53902340242763 - 68.52057141636107 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 16 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 63.58843478737991 - 53.533699264766824 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 17 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 143.25717547901027 - 61.23529184398511 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 18 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 238.99233371296435 - 11.57402085202307 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 19 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 131.463497184274 - 37.91565308310023 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 20 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 299.4799135787668 - 55.16132007269603 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 21 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 187.71659571763186 - 9.08434815157203 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 22 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 102.203173631275 - 62.50474380428127 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 23 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 125.71665361687481 - 43.5458073676737 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 24 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 252.63631602446236 - 17.060026732849032 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 25 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 266.5666796770194 - 8.117217835238177 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 26 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 131.87192517986617 - 32.127513593397026 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 27 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 30.652367771559508 - 85.42109840411501 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 28 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 130.99357336573604 - 33.563347799757125 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 29 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 46.890570472099824 - 84.32697531265379 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 30 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 289.29241608338094 - 79.10614026359546 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 31 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 100.85049907610703 - 29.219819221326194 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 32 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 93.66013534793747 - 61.22227570233571 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 33 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 165.39189836567348 - 48.74735797514156 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 34 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 18.853444997565738 - 6.082388970997076 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 35 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 259.5180066895893 - 75.51462617878758 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 36 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 263.7950489517294 - 90.09995862170234 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 37 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 23.947500697143653 - 94.74616081134577 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 38 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 241.77318785378117 - 91.62879072642055 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 39 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 66.62200995388741 - 32.556745277962186 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 40 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 44.26079431121239 - 46.605254676089366 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 41 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 194.44814750115458 - 79.42937060855046 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 42 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 183.8414711646846 - 99.24659864419542 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 43 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 255.80325337307795 - 89.00191251557604 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 44 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 3.9615742093764172 - 21.929477393662957 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 45 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 263.8017987770105 - 49.45572112660953 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 46 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 177.29759773129527 - 10.061128779807616 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 47 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 65.42708077018108 - 78.7624915799955 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 48 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 13.61768418807834 - 49.54522480122073 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 49 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.interfaces.Position - 274.0951558609378 - 65.79963370698627 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 50 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype929 - - - - org.contikios.cooja.plugins.SimControl - 262 - 1 - 185 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 1.283542488892569 0.0 0.0 1.283542488892569 56.0530822138472 6.888296017222324 - - 496 - 3 - 198 - 1 - 184 - - - org.contikios.cooja.plugins.LogListener - - ID:1 - - - - 933 - 2 - 333 - 0 - 381 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 676 - 0 - 714 - 497 - 0 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + Rime collect test + 1 + 10000000 + + org.contikios.cooja.radiomediums.UDGM + 80.0 + 0.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype929 + Contiki Mote Type #1 + [CONTIKI_DIR]/examples/rime/example-collect.c + make example-collect.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 38.67566417548448 + 47.31532819237484 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 71.13430279192914 + 55.964918387262955 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 228.04679204790637 + 87.17819808323965 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 272.42783222170533 + 46.64334378879388 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 238.61415527274 + 44.41698596888275 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 132.73939224849255 + 69.21851375812221 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 13.282402591495124 + 37.55717734948646 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 231.24739439405175 + 48.67375039920239 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 207.8959314238542 + 1.1350394672889341 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 9 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 92.82161206304569 + 92.33145969594939 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 10 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 160.99396124295916 + 19.643001828505756 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 11 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 200.78134764559428 + 12.892752477526937 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 12 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 205.39914563029964 + 28.760487893562114 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 13 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 252.08232300754125 + 72.49857017173812 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 14 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 229.71392970623077 + 6.54664783066401 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 15 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 278.53902340242763 + 68.52057141636107 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 16 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 63.58843478737991 + 53.533699264766824 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 17 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 143.25717547901027 + 61.23529184398511 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 18 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 238.99233371296435 + 11.57402085202307 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 19 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 131.463497184274 + 37.91565308310023 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 20 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 299.4799135787668 + 55.16132007269603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 21 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 187.71659571763186 + 9.08434815157203 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 22 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 102.203173631275 + 62.50474380428127 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 23 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 125.71665361687481 + 43.5458073676737 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 24 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 252.63631602446236 + 17.060026732849032 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 25 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 266.5666796770194 + 8.117217835238177 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 26 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 131.87192517986617 + 32.127513593397026 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 27 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 30.652367771559508 + 85.42109840411501 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 28 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 130.99357336573604 + 33.563347799757125 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 29 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 46.890570472099824 + 84.32697531265379 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 30 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 289.29241608338094 + 79.10614026359546 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 31 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 100.85049907610703 + 29.219819221326194 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 32 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 93.66013534793747 + 61.22227570233571 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 33 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 165.39189836567348 + 48.74735797514156 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 34 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 18.853444997565738 + 6.082388970997076 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 35 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 259.5180066895893 + 75.51462617878758 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 36 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 263.7950489517294 + 90.09995862170234 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 37 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 23.947500697143653 + 94.74616081134577 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 38 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 241.77318785378117 + 91.62879072642055 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 39 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 66.62200995388741 + 32.556745277962186 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 40 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 44.26079431121239 + 46.605254676089366 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 41 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 194.44814750115458 + 79.42937060855046 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 42 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 183.8414711646846 + 99.24659864419542 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 43 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 255.80325337307795 + 89.00191251557604 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 44 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 3.9615742093764172 + 21.929477393662957 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 45 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 263.8017987770105 + 49.45572112660953 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 46 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 177.29759773129527 + 10.061128779807616 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 47 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 65.42708077018108 + 78.7624915799955 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 48 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 13.61768418807834 + 49.54522480122073 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 49 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.interfaces.Position + 274.0951558609378 + 65.79963370698627 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 50 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype929 + + + + org.contikios.cooja.plugins.SimControl + 262 + 1 + 185 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 1.283542488892569 0.0 0.0 1.283542488892569 56.0530822138472 6.888296017222324 + + 496 + 3 + 198 + 1 + 184 + + + org.contikios.cooja.plugins.LogListener + + ID:1 + + + + 933 + 2 + 333 + 0 + 381 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 676 + 0 + 714 + 497 + 0 + + + diff --git a/regression-tests/04-rime/02-cooja-rucb.csc b/regression-tests/04-rime/02-cooja-rucb.csc index 08a177fee..34f48e8e0 100644 --- a/regression-tests/04-rime/02-cooja-rucb.csc +++ b/regression-tests/04-rime/02-cooja-rucb.csc @@ -1,181 +1,181 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - generated - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 25.0 - 40.0 - 0.99 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype965 - Contiki Mote #1 - [CONTIKI_DIR]/examples/rime/example-rucb.c - make example-rucb.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - false - - - - org.contikios.cooja.interfaces.Position - 0.0 - 50.00000000000001 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 51 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype965 - - - - org.contikios.cooja.interfaces.Position - 14.102564102564104 - 45.28301886792453 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 52 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype965 - - - - org.contikios.cooja.interfaces.Position - -32.16814655285737 - 42.92182758760039 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 53 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype965 - - - - org.contikios.cooja.interfaces.Position - -1.5917258339289355 - 37.3750708005199 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 54 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype965 - - - - org.contikios.cooja.interfaces.Position - 26.334899854939632 - 53.05390331866741 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 55 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype965 - - - - org.contikios.cooja.plugins.SimControl - 265 - 3 - 200 - 0 - 0 - - - org.contikios.cooja.plugins.LogListener - - - - - - 798 - 2 - 289 - 0 - 354 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 3.931419201604973 0.0 0.0 3.931419201604973 137.46646903794633 -127.75710261680608 - - 265 - 0 - 155 - 0 - 200 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 534 - 1 - 354 - 264 - 0 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 25.0 + 40.0 + 0.99 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype965 + Contiki Mote #1 + [CONTIKI_DIR]/examples/rime/example-rucb.c + make example-rucb.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + false + + + + org.contikios.cooja.interfaces.Position + 0.0 + 50.00000000000001 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 51 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype965 + + + + org.contikios.cooja.interfaces.Position + 14.102564102564104 + 45.28301886792453 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 52 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype965 + + + + org.contikios.cooja.interfaces.Position + -32.16814655285737 + 42.92182758760039 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 53 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype965 + + + + org.contikios.cooja.interfaces.Position + -1.5917258339289355 + 37.3750708005199 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 54 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype965 + + + + org.contikios.cooja.interfaces.Position + 26.334899854939632 + 53.05390331866741 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 55 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype965 + + + + org.contikios.cooja.plugins.SimControl + 265 + 3 + 200 + 0 + 0 + + + org.contikios.cooja.plugins.LogListener + + + + + + 798 + 2 + 289 + 0 + 354 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 3.931419201604973 0.0 0.0 3.931419201604973 137.46646903794633 -127.75710261680608 + + 265 + 0 + 155 + 0 + 200 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 534 + 1 + 354 + 264 + 0 + + + diff --git a/regression-tests/04-rime/03-sky-abc.csc b/regression-tests/04-rime/03-sky-abc.csc index 72934b701..4387c58bc 100644 --- a/regression-tests/04-rime/03-sky-abc.csc +++ b/regression-tests/04-rime/03-sky-abc.csc @@ -1,137 +1,137 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - generated - 5000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 0.95 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Sky Mote Type #1 - [CONTIKI_DIR]/examples/rime/example-abc.c - make clean TARGET=sky -make example-abc.sky TARGET=sky - [CONTIKI_DIR]/examples/rime/example-abc.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - - - - - org.contikios.cooja.interfaces.Position - 33.53152221759984 - 15.078801911773077 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 54.67966631314053 - 31.0253850381183 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky1 - - - - org.contikios.cooja.plugins.SimControl - 313 - 3 - 199 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 3.93358704057683 0.0 0.0 3.93358704057683 -23.493194019199933 -56.677416151212064 - - 312 - 2 - 123 - 0 - 198 - - - org.contikios.cooja.plugins.LogListener - - - - - - 311 - 0 - 377 - 1 - 320 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 601 - 1 - 697 - 312 - 0 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + generated + 5000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 0.95 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Sky Mote Type #1 + [CONTIKI_DIR]/examples/rime/example-abc.c + make clean TARGET=sky +make example-abc.sky TARGET=sky + [CONTIKI_DIR]/examples/rime/example-abc.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + + + + + org.contikios.cooja.interfaces.Position + 33.53152221759984 + 15.078801911773077 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 54.67966631314053 + 31.0253850381183 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky1 + + + + org.contikios.cooja.plugins.SimControl + 313 + 3 + 199 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 3.93358704057683 0.0 0.0 3.93358704057683 -23.493194019199933 -56.677416151212064 + + 312 + 2 + 123 + 0 + 198 + + + org.contikios.cooja.plugins.LogListener + + + + + + 311 + 0 + 377 + 1 + 320 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 601 + 1 + 697 + 312 + 0 + + + diff --git a/regression-tests/04-rime/04-sky-deluge.csc b/regression-tests/04-rime/04-sky-deluge.csc deleted file mode 100644 index ce5a6581a..000000000 --- a/regression-tests/04-rime/04-sky-deluge.csc +++ /dev/null @@ -1,155 +0,0 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - Deluge - generated - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Sky Mote Type #1 - [CONTIKI_DIR]/examples/sky/test-deluge.c - make clean TARGET=sky -make APPS=deluge test-deluge.sky TARGET=sky - [CONTIKI_DIR]/examples/sky/test-deluge.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - - - - - org.contikios.cooja.interfaces.Position - 22.464792491653174 - 11.3235347656354 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 16.167564578306468 - 29.89745599030348 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 63.42409596590043 - 12.470791515046386 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky1 - - - - org.contikios.cooja.plugins.SimControl - 282 - 4 - 212 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 4.405003166995177 0.0 0.0 4.405003166995177 -40.3007583818182 -45.78929741329485 - - 283 - 2 - 144 - -1 - 212 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - 1 - 357 - 281 - 1 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - 2 - - 500.0 - - 882 - 3 - 149 - -1 - 357 - - - org.contikios.cooja.plugins.LogListener - - - - - - 882 - 0 - 195 - -1 - 504 - - - diff --git a/regression-tests/04-rime/05-sky-runicast.csc b/regression-tests/04-rime/04-sky-runicast.csc similarity index 97% rename from regression-tests/04-rime/05-sky-runicast.csc rename to regression-tests/04-rime/04-sky-runicast.csc index 605ba245a..a12c49771 100644 --- a/regression-tests/04-rime/05-sky-runicast.csc +++ b/regression-tests/04-rime/04-sky-runicast.csc @@ -1,212 +1,212 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 1 - 10000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 0.0 - 0.9 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Sky Mote Type #1 - [CONTIKI_DIR]/examples/rime/example-runicast.c - make clean TARGET=sky -make example-runicast.sky TARGET=sky - [CONTIKI_DIR]/examples/rime/example-runicast.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - - - - - org.contikios.cooja.interfaces.Position - 3.0783332685337617 - 38.39795740836801 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 1.1986251808192212 - 53.65838347315817 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 34.432838059195255 - 38.26541658684913 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 150.85510197745134 - 141.37553211643905 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky1 - - - - org.contikios.cooja.plugins.SimControl - 265 - 4 - 200 - 0 - 0 - - - org.contikios.cooja.plugins.LogListener - - received - - - - 539 - 0 - 319 - 0 - 325 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 0.6259856679816412 0.0 0.0 0.6259856679816412 77.4082730178659 -21.226329635441804 - - 263 - 2 - 125 - 1 - 200 - - - org.contikios.cooja.plugins.RadioLogger - - 150 - - false - false - - 276 - 1 - 324 - 264 - 1 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 503 - 3 - 643 - 539 - 1 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 1 + 10000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 0.0 + 0.9 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Sky Mote Type #1 + [CONTIKI_DIR]/examples/rime/example-runicast.c + make clean TARGET=sky +make example-runicast.sky TARGET=sky + [CONTIKI_DIR]/examples/rime/example-runicast.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + + + + + org.contikios.cooja.interfaces.Position + 3.0783332685337617 + 38.39795740836801 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 1.1986251808192212 + 53.65838347315817 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 34.432838059195255 + 38.26541658684913 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 150.85510197745134 + 141.37553211643905 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky1 + + + + org.contikios.cooja.plugins.SimControl + 265 + 4 + 200 + 0 + 0 + + + org.contikios.cooja.plugins.LogListener + + received + + + + 539 + 0 + 319 + 0 + 325 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 0.6259856679816412 0.0 0.0 0.6259856679816412 77.4082730178659 -21.226329635441804 + + 263 + 2 + 125 + 1 + 200 + + + org.contikios.cooja.plugins.RadioLogger + + 150 + + false + false + + 276 + 1 + 324 + 264 + 1 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 503 + 3 + 643 + 539 + 1 + + + diff --git a/regression-tests/04-rime/06-sky-trickle.csc b/regression-tests/04-rime/05-sky-trickle.csc similarity index 97% rename from regression-tests/04-rime/06-sky-trickle.csc rename to regression-tests/04-rime/05-sky-trickle.csc index 33baa35aa..c5d2dd047 100644 --- a/regression-tests/04-rime/06-sky-trickle.csc +++ b/regression-tests/04-rime/05-sky-trickle.csc @@ -1,256 +1,256 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - generated - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 41.0 - 55.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Sky Mote Type #1 - [CONTIKI_DIR]/examples/rime/example-trickle.c - make clean TARGET=sky -make example-trickle.sky TARGET=sky - [CONTIKI_DIR]/examples/rime/example-trickle.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - - - - - org.contikios.cooja.interfaces.Position - 21.25615651441164 - 15.906616513243888 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 29.258648178869528 - 64.81243553163958 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 53.58390840870132 - 99.01827951434828 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 4.089137066756255 - 57.26244252237209 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 84.2311285004563 - 14.6212837520458 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 40.97868508483131 - 69.00112748842623 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 34.348646576361716 - 33.331938472933615 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 7 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 76.46661251540715 - 62.393168145801916 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 8 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 87.91615665417679 - 41.2939192052263 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 9 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 25.396991214895582 - 87.22076662391413 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 10 - - sky1 - - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 1.2387343127698363 0.0 0.0 1.2387343127698363 92.01494285570652 -13.3846131531305 - - 310 - 2 - 169 - 2 - 199 - - - org.contikios.cooja.plugins.SimControl - 313 - 3 - 199 - 1 - 0 - - - org.contikios.cooja.plugins.LogListener - - - - - - 310 - 1 - 331 - 3 - 368 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - 0 - 700 - 314 - 0 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 41.0 + 55.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Sky Mote Type #1 + [CONTIKI_DIR]/examples/rime/example-trickle.c + make clean TARGET=sky +make example-trickle.sky TARGET=sky + [CONTIKI_DIR]/examples/rime/example-trickle.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + + + + + org.contikios.cooja.interfaces.Position + 21.25615651441164 + 15.906616513243888 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 29.258648178869528 + 64.81243553163958 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 53.58390840870132 + 99.01827951434828 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 4.089137066756255 + 57.26244252237209 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 84.2311285004563 + 14.6212837520458 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 40.97868508483131 + 69.00112748842623 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 34.348646576361716 + 33.331938472933615 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 76.46661251540715 + 62.393168145801916 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 87.91615665417679 + 41.2939192052263 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 25.396991214895582 + 87.22076662391413 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky1 + + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 1.2387343127698363 0.0 0.0 1.2387343127698363 92.01494285570652 -13.3846131531305 + + 310 + 2 + 169 + 2 + 199 + + + org.contikios.cooja.plugins.SimControl + 313 + 3 + 199 + 1 + 0 + + + org.contikios.cooja.plugins.LogListener + + + + + + 310 + 1 + 331 + 3 + 368 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 0 + 700 + 314 + 0 + + + diff --git a/regression-tests/04-rime/06-sky-collect.csc b/regression-tests/04-rime/06-sky-collect.csc new file mode 100644 index 000000000..3fe71e180 --- /dev/null +++ b/regression-tests/04-rime/06-sky-collect.csc @@ -0,0 +1,245 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + generated + 10000000 + + org.contikios.cooja.radiomediums.UDGM + 30.0 + 40.0 + 0.9 + 0.9 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Sky Mote Type #1 + [CONTIKI_DIR]/examples/sky/sky-collect.c + make clean TARGET=sky +make sky-collect.sky TARGET=sky + [CONTIKI_DIR]/examples/sky/sky-collect.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + + + + + org.contikios.cooja.interfaces.Position + 9.333811152651393 + 89.28114548870677 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 33.040227185226826 + 54.184283361563054 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + -2.2559922410521516 + 50.71648775308175 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 12.959353575718179 + 43.874396471224806 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 15.917348901177405 + 66.93526904376517 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 26.735174243053933 + 35.939375910459084 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 41.5254792748469 + 28.370611308140152 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky1 + + + + org.contikios.cooja.plugins.SimControl + 265 + 3 + 200 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 1.9551775516837413 0.0 0.0 1.9551775516837413 87.61059024269439 -50.01503690267507 + + 264 + 1 + 185 + 0 + 200 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 2 + 385 + 266 + 0 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + + 500.0 + + 866 + 0 + 152 + 0 + 384 + + + diff --git a/regression-tests/04-rime/07-sky-collect.csc b/regression-tests/04-rime/07-sky-collect.csc index 58dc38e75..5184bf959 100644 --- a/regression-tests/04-rime/07-sky-collect.csc +++ b/regression-tests/04-rime/07-sky-collect.csc @@ -1,245 +1,447 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - generated - 10000000 - - org.contikios.cooja.radiomediums.UDGM - 30.0 - 40.0 - 0.9 - 0.9 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Sky Mote Type #1 - [CONTIKI_DIR]/examples/sky/sky-collect.c - make clean TARGET=sky -make sky-collect.sky TARGET=sky - [CONTIKI_DIR]/examples/sky/sky-collect.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - - - - - org.contikios.cooja.interfaces.Position - 9.333811152651393 - 89.28114548870677 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 33.040227185226826 - 54.184283361563054 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - -2.2559922410521516 - 50.71648775308175 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 12.959353575718179 - 43.874396471224806 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 15.917348901177405 - 66.93526904376517 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 26.735174243053933 - 35.939375910459084 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 41.5254792748469 - 28.370611308140152 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 7 - - sky1 - - - - org.contikios.cooja.plugins.SimControl - 265 - 3 - 200 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 1.9551775516837413 0.0 0.0 1.9551775516837413 87.61059024269439 -50.01503690267507 - - 264 - 1 - 185 - 0 - 200 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - 2 - 385 - 266 - 0 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - - 500.0 - - 866 - 0 - 152 - 0 - 384 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 400000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Sky Mote Type #1 + [CONTIKI_DIR]/examples/rime/example-collect.c + make clean TARGET=sky +make example-collect.sky TARGET=sky + [CONTIKI_DIR]/examples/rime/example-collect.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 87.29845932913939 + 60.286214311723164 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 94.30809966340686 + 22.50388779326399 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 82.40423567500785 + 39.56979106929553 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 26.185019854469438 + 4.800834369523899 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 1.9530156130507015 + 78.3175061800706 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 48.35216700543414 + 80.36988713780997 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 24.825985087266833 + 74.27809432062487 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 8.356165164293616 + 94.33967355724187 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 45.11740613004886 + 31.7059041432301 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 68.9908548386292 + 55.01991960639596 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 13.181122543889046 + 55.9636533130127 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 11 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 2.1749985906538427 + 78.39666095789707 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 12 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 37.79795217518357 + 7.164284163506062 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 13 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 64.4595177394984 + 72.115414337433 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 14 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 81.85663737096085 + 89.31412706434035 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 15 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 44.74952276297882 + 18.78566116347574 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 16 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 96.11333426285873 + 90.64560410751824 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 17 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 21.651464136783527 + 7.1381043251259495 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 18 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 83.6006916200628 + 26.97170140682981 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 19 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 1.3446070721664705 + 7.340373220385176 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 20 + + sky1 + + + + org.contikios.cooja.plugins.SimControl + 247 + 0 + 227 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 1.685403700540615 0.0 0.0 1.685403700540615 23.872012513439184 -0.545889466623605 + + 224 + 3 + 225 + 247 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 469 + 1 + 473 + 0 + 226 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 2 + 700 + 469 + 0 + + + diff --git a/regression-tests/04-rime/09-cooja-trickle.csc b/regression-tests/04-rime/08-cooja-trickle.csc similarity index 96% rename from regression-tests/04-rime/09-cooja-trickle.csc rename to regression-tests/04-rime/08-cooja-trickle.csc index e369b38fc..0b0b02913 100644 --- a/regression-tests/04-rime/09-cooja-trickle.csc +++ b/regression-tests/04-rime/08-cooja-trickle.csc @@ -1,3733 +1,3733 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype896 - Cooja Mote Type #1 - [CONTIKI_DIR]/regression-tests/04-rime/code/trickle-node.c - make trickle-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - 6.568882352111016 - 89.62718790694142 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 99.03493285121479 - 24.74917539729994 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 34.46908056161367 - 18.92480914055563 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 58.07300119453901 - 92.56701608022784 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 4 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 4.7746325608922335 - 68.5250549995685 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 5 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 18.43610188865221 - 41.530057356099285 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 31.167749884374018 - 0.4246722060813446 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 7 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 98.05907643896941 - 46.03790834636672 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 95.34714997523065 - 3.2350896458523293 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 9 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 23.722342298413977 - 90.49885284216033 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 10 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 70.43619035275792 - 31.31229126426588 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 11 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 22.329321230828146 - 28.57483291743256 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 12 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 3.521960860406137 - 37.26004640789352 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 13 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 40.81173407107168 - 70.05376495995745 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 14 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 56.237452865803284 - 48.60595183121149 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 15 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 56.91660285867381 - 51.813636514575755 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 16 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 85.13927111588634 - 8.975236866142488 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 17 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 85.90257238152364 - 41.570392781749966 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 18 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 85.6228774151565 - 6.150666654291004 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 19 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 4.402889087469841 - 75.06430459857181 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 20 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 38.41618174328178 - 80.82454015548157 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 21 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 3.276612860049055 - 81.3223934030815 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 22 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 80.14814587773299 - 54.624453065746124 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 23 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 89.23520151089006 - 78.61037823351221 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 24 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 67.63702161821816 - 30.319940730263227 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 25 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 90.6520218241395 - 52.31648649198687 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 26 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 47.605575904521366 - 14.370823253222753 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 27 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 88.67935679456845 - 61.63919204722122 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 28 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 62.418430766378876 - 47.72680975556794 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 29 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 10.23968205017769 - 75.6163762374253 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 30 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 80.74688010413567 - 27.78533598308137 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 31 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 46.44207794624185 - 51.45763320882568 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 32 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 7.0847022389592285 - 77.60226416425907 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 33 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 27.504226917155663 - 34.73410517779959 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 34 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 92.73695978910362 - 99.95678973897041 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 35 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 14.527324868321523 - 56.8394498823125 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 36 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 94.94281507755645 - 18.01414591224293 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 37 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 97.85377651671594 - 10.0462063748739 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 38 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 41.52078727408137 - 92.61128889702061 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 39 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 1.8027638261222 - 3.916589413858329 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 40 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 91.87549918798894 - 52.30326661236246 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 41 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 34.08005807274469 - 12.94598595764348 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 42 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 7.101730242894144 - 27.13002370301435 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 43 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 25.037490965858787 - 57.968488949873674 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 44 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 72.67456520669178 - 33.66177410728385 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 45 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 34.34319517282086 - 71.57213261801763 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 46 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 56.92118091628886 - 77.50933833900811 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 47 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 59.83227576735132 - 58.77954760219993 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 48 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 41.915657816008064 - 72.58558519546224 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 49 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 31.843161949870634 - 11.45776022693128 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 50 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 65.09570508598352 - 93.60423316484713 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 51 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 74.89875741192188 - 80.92652240343887 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 52 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 48.929460038917036 - 91.41906683316111 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 53 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 43.04248849739064 - 75.32293243477193 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 54 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 41.20933759984702 - 88.844165747842 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 55 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 3.5541464112273435 - 73.42391971855811 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 56 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 13.553357202634563 - 8.745228245514392 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 57 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 41.40253769625784 - 36.48757620462509 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 58 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 73.67506347331192 - 54.83265107369869 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 59 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 61.08318511785268 - 35.59690497250605 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 60 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 95.85137044132782 - 99.28489161282182 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 61 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 68.06826666325836 - 80.01062116299323 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 62 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 1.3709285227171186 - 27.83979482987321 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 63 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 55.779251931546895 - 47.867628332142296 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 64 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 68.86916632016685 - 42.25345458025911 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 65 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 9.784073639390112 - 54.66511999382987 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 66 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 95.32263665847205 - 29.169605335133387 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 67 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 65.01164751321643 - 97.33231433619049 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 68 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 88.74482401135828 - 22.783989963564157 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 69 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 27.545967288343242 - 37.237989496208876 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 70 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 59.64588740775712 - 32.73151243011021 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 71 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 55.57628010243148 - 18.572794193934385 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 72 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 1.1249240777714387 - 87.06062268595146 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 73 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 7.092987360701453 - 98.39689962662284 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 74 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 47.778110699783305 - 78.86826452553812 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 75 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 19.872086166630687 - 10.087673065581592 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 76 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 76.83945653464441 - 72.21625452263784 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 77 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 24.313413426418006 - 16.49583912236582 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 78 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 36.220670911775784 - 53.58992487019706 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 79 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 76.10572961292435 - 86.04459939174762 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 80 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 33.16796489953524 - 36.83386901636666 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 81 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 74.98899325035866 - 52.19464054460451 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 82 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 3.579026719893441 - 86.83646069167602 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 83 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 41.76221650071965 - 81.74666079700839 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 84 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 69.78320568191269 - 7.050794276477745 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 85 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 9.02306431225367 - 72.64679421061318 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 86 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 27.629713153576873 - 92.23898651665253 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 87 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 34.98929592506449 - 49.27217818671787 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 88 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 30.587535866429583 - 26.80050479119339 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 89 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 34.39608906779097 - 99.26371733510828 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 90 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 37.45944235095177 - 74.0724164992028 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 91 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 88.32858006235864 - 57.18871882501241 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 92 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 94.16116394172158 - 58.63662158359322 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 93 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 15.564809594367867 - 47.69254595203641 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 94 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 41.413013430165826 - 64.6899256321378 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 95 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 73.3865589493186 - 45.058443121696335 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 96 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 96.42027268638782 - 23.86899869771518 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 97 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 84.86883701437324 - 32.64845899868377 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 98 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 94.65313327108798 - 27.70230420435218 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 99 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 33.5738059092315 - 79.6433960321747 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 100 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 99.33692620202561 - 97.40189489144562 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 101 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 13.73120882508002 - 23.621432436274013 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 102 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 72.5766728831825 - 68.51288713680493 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 103 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 4.950792816348571 - 15.285681348852343 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 104 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 39.20164236236282 - 83.69942072278975 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 105 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 53.0370271181274 - 60.231207119248964 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 106 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 78.14821858080782 - 34.54146892809409 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 107 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 72.50396341776242 - 75.8789301489569 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 108 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 16.913316939892876 - 95.71355158239486 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 109 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 49.04703513673822 - 68.13321330510874 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 110 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 32.40331545944186 - 62.56820913685508 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 111 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 60.835810783821444 - 50.163831002129896 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 112 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 31.160192255417684 - 38.395236125710454 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 113 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 72.55056341911987 - 57.8820260523452 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 114 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 77.94005986777552 - 40.10122061017203 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 115 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 94.28787130861903 - 25.7719303970389 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 116 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 3.1093957622807977 - 62.569201519112084 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 117 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 64.68498687585976 - 40.037918368164405 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 118 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 65.15921116282048 - 91.51919233543585 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 119 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 81.92573037729048 - 80.50829267843392 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 120 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 98.35151564789032 - 3.4882838007661565 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 121 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 2.946477891755117 - 50.055906504929425 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 122 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 90.32934974609084 - 77.9630427685427 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 123 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 87.60025637071952 - 1.80503837297753 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 124 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 18.35058527900767 - 51.293195445752104 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 125 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 25.389473062708458 - 46.125636327322816 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 126 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 13.245021295151528 - 12.548238204813323 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 127 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 34.45947569136444 - 17.094159776157568 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 128 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 9.528756367349944 - 17.888880939206096 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 129 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 19.85995506095263 - 22.134359386963155 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 130 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 0.312227052543701 - 39.44212914714669 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 131 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 66.82060507325654 - 89.03944738177172 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 132 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 23.368804404605637 - 66.40869783708897 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 133 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 88.33032080183098 - 66.30412652028217 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 134 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 16.33701125051411 - 6.698226210819103 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 135 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 50.22196379001298 - 60.13373840114642 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 136 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 55.546600574346805 - 55.47285620192937 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 137 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 34.001194017310695 - 93.8082748358454 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 138 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 25.109306918805707 - 78.46207924119797 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 139 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 32.75962613358675 - 21.109138450707288 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 140 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 96.10949800885035 - 20.857677606850554 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 141 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 90.8082963549723 - 88.80113994643916 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 142 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 55.06561703296728 - 82.26101565426288 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 143 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 17.47380330809587 - 26.924230902955582 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 144 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 36.095561138338326 - 71.97744064661859 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 145 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 21.320046667599236 - 7.798905295988067 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 146 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 41.88050388023514 - 71.56267197855983 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 147 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 6.585162015092417 - 92.7837363298666 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 148 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 98.74242142573685 - 19.740657443326338 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 149 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 49.73430066787986 - 22.22829895790325 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 150 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 74.77825204030766 - 2.6349416752525 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 151 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 73.79138439268063 - 70.71246641748267 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 152 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 95.56347662776064 - 75.87786853952764 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 153 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 71.78024476958186 - 13.213873631613083 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 154 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 47.67252804461608 - 77.96254780133673 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 155 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 0.6194413458317061 - 34.64682806345702 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 156 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 49.07305658459414 - 71.74812847796169 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 157 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 92.80412137666126 - 76.30342560411573 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 158 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 49.93319930570762 - 96.07317682900903 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 159 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 76.98926333710033 - 88.82354130296216 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 160 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 74.82106684647339 - 36.916558436055745 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 161 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 89.16515086221875 - 47.83504652861812 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 162 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 24.645916835288627 - 69.59871917130774 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 163 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 14.679543759696879 - 60.43664371305301 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 164 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 75.65153987979136 - 54.45547478030321 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 165 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 66.29062518200514 - 28.028207500959457 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 166 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 74.67149734649688 - 29.744838954989884 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 167 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 55.29668602858735 - 43.100253590461534 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 168 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 70.72844980621184 - 70.9567646582795 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 169 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 99.33685234577365 - 48.63518682957745 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 170 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 8.628475626468823 - 26.064747938969944 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 171 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 71.63295499479383 - 22.595969384054072 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 172 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 60.87598524825064 - 84.65332258064693 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 173 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 89.37524653989819 - 15.118036823593172 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 174 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 90.1136744976992 - 55.530717492965266 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 175 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 62.96013344586719 - 40.70020551173607 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 176 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 20.15948367395768 - 64.83256582828443 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 177 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 49.37052413712121 - 44.82022431266665 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 178 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 84.0420218227114 - 14.369492463481926 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 179 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 30.840080025471906 - 36.578149668144135 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 180 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 1.3870430831427139 - 69.88513114660597 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 181 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 49.94066624290235 - 23.480941841276724 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 182 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 83.92821380255494 - 59.97549673268689 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 183 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 92.44377728597361 - 48.29743959913113 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 184 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 50.34078121439194 - 29.867064939248312 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 185 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 4.985881389952496 - 12.694051853054999 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 186 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 53.249294524443336 - 98.43826962879814 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 187 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 43.155600258355975 - 59.45608169055081 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 188 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 40.05061496082472 - 42.36396331174911 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 189 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 61.74653956591568 - 60.542456279176236 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 190 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 22.71860259258296 - 75.81834442550416 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 191 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 19.39970138952114 - 37.73550104683998 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 192 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 62.30232359627651 - 97.73066836817638 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 193 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 78.69765739092972 - 96.64268722261257 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 194 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 53.36788782367626 - 48.27833687845872 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 195 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 36.160541823751956 - 33.381064580412875 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 196 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 48.8255744951515 - 1.4402697188622637 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 197 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 27.910168295539016 - 31.213307927454192 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 198 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 2.7759047087673516 - 37.52374498962448 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 199 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.interfaces.Position - 81.5797867294508 - 86.17878661280005 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 200 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype896 - - - - org.contikios.cooja.plugins.SimControl - 280 - 3 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - 3.1602407578791554 0.0 0.0 3.1602407578791554 36.54234219838188 14.385206312876027 - - 400 - 4 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - Hello, world - - - - 1200 - 1 - 240 - 400 - 160 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 920 - 5 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - 2 - 439 - 771 - 165 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 147 - 82 - 72 - 73 - 21 - 108 - 32 - 29 - 19 - 55 - 85 - 9 - 180 - 4 - 86 - 190 - 138 - 162 - 116 - 137 - 176 - 132 - 99 - 89 - 163 - 20 - 45 - 104 - 35 - 144 - 90 - 54 - 38 - 65 - 83 - 43 - 110 - 53 - 48 - 13 - 146 - 121 - 124 - 52 - 74 - 154 - 94 - 93 - 158 - 156 - 78 - 125 - 187 - 186 - 109 - 142 - 87 - 5 - 130 - 3 - 46 - 198 - 12 - 135 - 191 - 172 - 105 - 31 - 155 - 192 - 69 - 112 - 188 - 179 - 118 - 50 - 33 - 67 - 80 - 136 - 131 - 47 - 177 - 62 - 197 - 61 - 189 - 194 - 42 - 15 - 11 - 57 - 195 - 170 - 143 - 14 - 63 - 101 - 168 - 111 - 88 - 107 - 167 - 129 - 51 - 102 - 79 - 28 - 151 - 159 - 128 - 76 - 193 - 113 - 139 - 184 - 103 - 175 - 199 - 77 - 58 - 119 - 2 - 117 - 59 - 185 - 126 - 164 - 127 - 70 - 81 - 64 - 181 - 149 - 95 - 75 - 56 - 41 - 22 - 49 - 182 - 145 - 23 - 134 - 141 - 122 - 133 - 24 - 26 - 165 - 39 - 160 - 71 - 10 - 44 - 27 - 34 - 114 - 157 - 91 - 60 - 152 - 174 - 106 - 166 - 25 - 6 - 161 - 17 - 92 - 100 - 40 - 171 - 183 - 30 - 97 - 196 - 153 - 7 - 169 - 84 - 68 - 66 - 98 - 178 - 115 - 150 - 96 - 173 - 16 - 140 - 1 - 36 - 18 - 148 - 123 - 37 - 8 - 120 - - 3677.5424662661985 - - 1600 - 0 - 289 - 0 - 416 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype896 + Cooja Mote Type #1 + [CONTIKI_DIR]/regression-tests/04-rime/code/trickle-node.c + make trickle-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 6.568882352111016 + 89.62718790694142 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 99.03493285121479 + 24.74917539729994 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 34.46908056161367 + 18.92480914055563 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 58.07300119453901 + 92.56701608022784 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 4.7746325608922335 + 68.5250549995685 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 18.43610188865221 + 41.530057356099285 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 31.167749884374018 + 0.4246722060813446 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 98.05907643896941 + 46.03790834636672 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 95.34714997523065 + 3.2350896458523293 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 9 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 23.722342298413977 + 90.49885284216033 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 10 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 70.43619035275792 + 31.31229126426588 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 11 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 22.329321230828146 + 28.57483291743256 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 12 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 3.521960860406137 + 37.26004640789352 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 13 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 40.81173407107168 + 70.05376495995745 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 14 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 56.237452865803284 + 48.60595183121149 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 15 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 56.91660285867381 + 51.813636514575755 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 16 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 85.13927111588634 + 8.975236866142488 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 17 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 85.90257238152364 + 41.570392781749966 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 18 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 85.6228774151565 + 6.150666654291004 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 19 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 4.402889087469841 + 75.06430459857181 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 20 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 38.41618174328178 + 80.82454015548157 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 21 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 3.276612860049055 + 81.3223934030815 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 22 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 80.14814587773299 + 54.624453065746124 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 23 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 89.23520151089006 + 78.61037823351221 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 24 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 67.63702161821816 + 30.319940730263227 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 25 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 90.6520218241395 + 52.31648649198687 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 26 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 47.605575904521366 + 14.370823253222753 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 27 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 88.67935679456845 + 61.63919204722122 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 28 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 62.418430766378876 + 47.72680975556794 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 29 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 10.23968205017769 + 75.6163762374253 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 30 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 80.74688010413567 + 27.78533598308137 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 31 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 46.44207794624185 + 51.45763320882568 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 32 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 7.0847022389592285 + 77.60226416425907 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 33 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 27.504226917155663 + 34.73410517779959 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 34 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 92.73695978910362 + 99.95678973897041 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 35 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 14.527324868321523 + 56.8394498823125 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 36 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 94.94281507755645 + 18.01414591224293 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 37 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 97.85377651671594 + 10.0462063748739 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 38 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 41.52078727408137 + 92.61128889702061 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 39 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 1.8027638261222 + 3.916589413858329 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 40 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 91.87549918798894 + 52.30326661236246 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 41 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 34.08005807274469 + 12.94598595764348 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 42 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 7.101730242894144 + 27.13002370301435 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 43 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 25.037490965858787 + 57.968488949873674 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 44 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 72.67456520669178 + 33.66177410728385 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 45 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 34.34319517282086 + 71.57213261801763 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 46 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 56.92118091628886 + 77.50933833900811 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 47 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 59.83227576735132 + 58.77954760219993 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 48 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 41.915657816008064 + 72.58558519546224 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 49 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 31.843161949870634 + 11.45776022693128 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 50 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 65.09570508598352 + 93.60423316484713 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 51 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 74.89875741192188 + 80.92652240343887 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 52 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 48.929460038917036 + 91.41906683316111 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 53 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 43.04248849739064 + 75.32293243477193 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 54 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 41.20933759984702 + 88.844165747842 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 55 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 3.5541464112273435 + 73.42391971855811 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 56 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 13.553357202634563 + 8.745228245514392 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 57 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 41.40253769625784 + 36.48757620462509 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 58 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 73.67506347331192 + 54.83265107369869 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 59 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 61.08318511785268 + 35.59690497250605 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 60 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 95.85137044132782 + 99.28489161282182 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 61 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 68.06826666325836 + 80.01062116299323 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 62 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 1.3709285227171186 + 27.83979482987321 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 63 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 55.779251931546895 + 47.867628332142296 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 64 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 68.86916632016685 + 42.25345458025911 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 65 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 9.784073639390112 + 54.66511999382987 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 66 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 95.32263665847205 + 29.169605335133387 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 67 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 65.01164751321643 + 97.33231433619049 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 68 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 88.74482401135828 + 22.783989963564157 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 69 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 27.545967288343242 + 37.237989496208876 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 70 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 59.64588740775712 + 32.73151243011021 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 71 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 55.57628010243148 + 18.572794193934385 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 72 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 1.1249240777714387 + 87.06062268595146 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 73 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 7.092987360701453 + 98.39689962662284 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 74 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 47.778110699783305 + 78.86826452553812 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 75 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 19.872086166630687 + 10.087673065581592 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 76 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 76.83945653464441 + 72.21625452263784 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 77 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 24.313413426418006 + 16.49583912236582 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 78 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 36.220670911775784 + 53.58992487019706 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 79 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 76.10572961292435 + 86.04459939174762 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 80 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 33.16796489953524 + 36.83386901636666 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 81 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 74.98899325035866 + 52.19464054460451 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 82 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 3.579026719893441 + 86.83646069167602 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 83 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 41.76221650071965 + 81.74666079700839 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 84 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 69.78320568191269 + 7.050794276477745 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 85 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 9.02306431225367 + 72.64679421061318 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 86 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 27.629713153576873 + 92.23898651665253 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 87 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 34.98929592506449 + 49.27217818671787 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 88 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 30.587535866429583 + 26.80050479119339 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 89 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 34.39608906779097 + 99.26371733510828 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 90 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 37.45944235095177 + 74.0724164992028 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 91 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 88.32858006235864 + 57.18871882501241 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 92 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 94.16116394172158 + 58.63662158359322 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 93 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 15.564809594367867 + 47.69254595203641 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 94 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 41.413013430165826 + 64.6899256321378 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 95 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 73.3865589493186 + 45.058443121696335 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 96 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 96.42027268638782 + 23.86899869771518 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 97 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 84.86883701437324 + 32.64845899868377 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 98 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 94.65313327108798 + 27.70230420435218 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 99 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 33.5738059092315 + 79.6433960321747 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 100 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 99.33692620202561 + 97.40189489144562 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 101 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 13.73120882508002 + 23.621432436274013 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 102 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 72.5766728831825 + 68.51288713680493 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 103 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 4.950792816348571 + 15.285681348852343 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 104 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 39.20164236236282 + 83.69942072278975 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 105 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 53.0370271181274 + 60.231207119248964 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 106 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 78.14821858080782 + 34.54146892809409 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 107 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 72.50396341776242 + 75.8789301489569 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 108 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 16.913316939892876 + 95.71355158239486 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 109 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 49.04703513673822 + 68.13321330510874 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 110 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 32.40331545944186 + 62.56820913685508 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 111 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 60.835810783821444 + 50.163831002129896 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 112 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 31.160192255417684 + 38.395236125710454 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 113 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 72.55056341911987 + 57.8820260523452 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 114 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 77.94005986777552 + 40.10122061017203 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 115 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 94.28787130861903 + 25.7719303970389 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 116 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 3.1093957622807977 + 62.569201519112084 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 117 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 64.68498687585976 + 40.037918368164405 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 118 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 65.15921116282048 + 91.51919233543585 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 119 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 81.92573037729048 + 80.50829267843392 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 120 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 98.35151564789032 + 3.4882838007661565 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 121 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 2.946477891755117 + 50.055906504929425 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 122 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 90.32934974609084 + 77.9630427685427 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 123 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 87.60025637071952 + 1.80503837297753 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 124 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 18.35058527900767 + 51.293195445752104 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 125 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 25.389473062708458 + 46.125636327322816 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 126 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 13.245021295151528 + 12.548238204813323 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 127 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 34.45947569136444 + 17.094159776157568 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 128 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 9.528756367349944 + 17.888880939206096 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 129 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 19.85995506095263 + 22.134359386963155 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 130 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 0.312227052543701 + 39.44212914714669 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 131 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 66.82060507325654 + 89.03944738177172 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 132 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 23.368804404605637 + 66.40869783708897 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 133 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 88.33032080183098 + 66.30412652028217 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 134 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 16.33701125051411 + 6.698226210819103 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 135 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 50.22196379001298 + 60.13373840114642 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 136 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 55.546600574346805 + 55.47285620192937 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 137 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 34.001194017310695 + 93.8082748358454 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 138 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 25.109306918805707 + 78.46207924119797 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 139 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 32.75962613358675 + 21.109138450707288 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 140 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 96.10949800885035 + 20.857677606850554 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 141 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 90.8082963549723 + 88.80113994643916 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 142 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 55.06561703296728 + 82.26101565426288 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 143 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 17.47380330809587 + 26.924230902955582 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 144 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 36.095561138338326 + 71.97744064661859 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 145 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 21.320046667599236 + 7.798905295988067 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 146 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 41.88050388023514 + 71.56267197855983 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 147 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 6.585162015092417 + 92.7837363298666 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 148 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 98.74242142573685 + 19.740657443326338 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 149 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 49.73430066787986 + 22.22829895790325 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 150 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 74.77825204030766 + 2.6349416752525 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 151 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 73.79138439268063 + 70.71246641748267 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 152 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 95.56347662776064 + 75.87786853952764 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 153 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 71.78024476958186 + 13.213873631613083 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 154 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 47.67252804461608 + 77.96254780133673 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 155 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 0.6194413458317061 + 34.64682806345702 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 156 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 49.07305658459414 + 71.74812847796169 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 157 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 92.80412137666126 + 76.30342560411573 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 158 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 49.93319930570762 + 96.07317682900903 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 159 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 76.98926333710033 + 88.82354130296216 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 160 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 74.82106684647339 + 36.916558436055745 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 161 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 89.16515086221875 + 47.83504652861812 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 162 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 24.645916835288627 + 69.59871917130774 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 163 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 14.679543759696879 + 60.43664371305301 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 164 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 75.65153987979136 + 54.45547478030321 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 165 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 66.29062518200514 + 28.028207500959457 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 166 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 74.67149734649688 + 29.744838954989884 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 167 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 55.29668602858735 + 43.100253590461534 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 168 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 70.72844980621184 + 70.9567646582795 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 169 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 99.33685234577365 + 48.63518682957745 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 170 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 8.628475626468823 + 26.064747938969944 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 171 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 71.63295499479383 + 22.595969384054072 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 172 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 60.87598524825064 + 84.65332258064693 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 173 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 89.37524653989819 + 15.118036823593172 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 174 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 90.1136744976992 + 55.530717492965266 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 175 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 62.96013344586719 + 40.70020551173607 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 176 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 20.15948367395768 + 64.83256582828443 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 177 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 49.37052413712121 + 44.82022431266665 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 178 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 84.0420218227114 + 14.369492463481926 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 179 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 30.840080025471906 + 36.578149668144135 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 180 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 1.3870430831427139 + 69.88513114660597 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 181 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 49.94066624290235 + 23.480941841276724 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 182 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 83.92821380255494 + 59.97549673268689 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 183 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 92.44377728597361 + 48.29743959913113 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 184 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 50.34078121439194 + 29.867064939248312 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 185 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 4.985881389952496 + 12.694051853054999 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 186 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 53.249294524443336 + 98.43826962879814 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 187 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 43.155600258355975 + 59.45608169055081 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 188 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 40.05061496082472 + 42.36396331174911 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 189 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 61.74653956591568 + 60.542456279176236 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 190 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 22.71860259258296 + 75.81834442550416 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 191 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 19.39970138952114 + 37.73550104683998 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 192 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 62.30232359627651 + 97.73066836817638 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 193 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 78.69765739092972 + 96.64268722261257 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 194 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 53.36788782367626 + 48.27833687845872 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 195 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 36.160541823751956 + 33.381064580412875 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 196 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 48.8255744951515 + 1.4402697188622637 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 197 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 27.910168295539016 + 31.213307927454192 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 198 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 2.7759047087673516 + 37.52374498962448 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 199 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.interfaces.Position + 81.5797867294508 + 86.17878661280005 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 200 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype896 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + 3.1602407578791554 0.0 0.0 3.1602407578791554 36.54234219838188 14.385206312876027 + + 400 + 4 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + Hello, world + + + + 1200 + 1 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 920 + 5 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 2 + 439 + 771 + 165 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 147 + 82 + 72 + 73 + 21 + 108 + 32 + 29 + 19 + 55 + 85 + 9 + 180 + 4 + 86 + 190 + 138 + 162 + 116 + 137 + 176 + 132 + 99 + 89 + 163 + 20 + 45 + 104 + 35 + 144 + 90 + 54 + 38 + 65 + 83 + 43 + 110 + 53 + 48 + 13 + 146 + 121 + 124 + 52 + 74 + 154 + 94 + 93 + 158 + 156 + 78 + 125 + 187 + 186 + 109 + 142 + 87 + 5 + 130 + 3 + 46 + 198 + 12 + 135 + 191 + 172 + 105 + 31 + 155 + 192 + 69 + 112 + 188 + 179 + 118 + 50 + 33 + 67 + 80 + 136 + 131 + 47 + 177 + 62 + 197 + 61 + 189 + 194 + 42 + 15 + 11 + 57 + 195 + 170 + 143 + 14 + 63 + 101 + 168 + 111 + 88 + 107 + 167 + 129 + 51 + 102 + 79 + 28 + 151 + 159 + 128 + 76 + 193 + 113 + 139 + 184 + 103 + 175 + 199 + 77 + 58 + 119 + 2 + 117 + 59 + 185 + 126 + 164 + 127 + 70 + 81 + 64 + 181 + 149 + 95 + 75 + 56 + 41 + 22 + 49 + 182 + 145 + 23 + 134 + 141 + 122 + 133 + 24 + 26 + 165 + 39 + 160 + 71 + 10 + 44 + 27 + 34 + 114 + 157 + 91 + 60 + 152 + 174 + 106 + 166 + 25 + 6 + 161 + 17 + 92 + 100 + 40 + 171 + 183 + 30 + 97 + 196 + 153 + 7 + 169 + 84 + 68 + 66 + 98 + 178 + 115 + 150 + 96 + 173 + 16 + 140 + 1 + 36 + 18 + 148 + 123 + 37 + 8 + 120 + + 3677.5424662661985 + + 1600 + 0 + 289 + 0 + 416 + + + diff --git a/regression-tests/04-rime/08-sky-collect.csc b/regression-tests/04-rime/08-sky-collect.csc deleted file mode 100644 index ead2dda9c..000000000 --- a/regression-tests/04-rime/08-sky-collect.csc +++ /dev/null @@ -1,447 +0,0 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - generated - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 400000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Sky Mote Type #1 - [CONTIKI_DIR]/examples/rime/example-collect.c - make clean TARGET=sky -make example-collect.sky TARGET=sky - [CONTIKI_DIR]/examples/rime/example-collect.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 87.29845932913939 - 60.286214311723164 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 94.30809966340686 - 22.50388779326399 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 82.40423567500785 - 39.56979106929553 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 26.185019854469438 - 4.800834369523899 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 1.9530156130507015 - 78.3175061800706 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 48.35216700543414 - 80.36988713780997 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 24.825985087266833 - 74.27809432062487 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 7 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 8.356165164293616 - 94.33967355724187 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 8 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 45.11740613004886 - 31.7059041432301 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 9 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 68.9908548386292 - 55.01991960639596 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 10 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 13.181122543889046 - 55.9636533130127 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 11 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 2.1749985906538427 - 78.39666095789707 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 12 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 37.79795217518357 - 7.164284163506062 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 13 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 64.4595177394984 - 72.115414337433 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 14 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 81.85663737096085 - 89.31412706434035 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 15 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 44.74952276297882 - 18.78566116347574 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 16 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 96.11333426285873 - 90.64560410751824 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 17 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 21.651464136783527 - 7.1381043251259495 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 18 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 83.6006916200628 - 26.97170140682981 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 19 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 1.3446070721664705 - 7.340373220385176 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 20 - - sky1 - - - - org.contikios.cooja.plugins.SimControl - 247 - 0 - 227 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 1.685403700540615 0.0 0.0 1.685403700540615 23.872012513439184 -0.545889466623605 - - 224 - 3 - 225 - 247 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 469 - 1 - 473 - 0 - 226 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - 2 - 700 - 469 - 0 - - - diff --git a/regression-tests/04-rime/10-cooja-mesh.csc b/regression-tests/04-rime/09-cooja-mesh.csc similarity index 96% rename from regression-tests/04-rime/10-cooja-mesh.csc rename to regression-tests/04-rime/09-cooja-mesh.csc index 2a85264b6..4e448561b 100644 --- a/regression-tests/04-rime/10-cooja-mesh.csc +++ b/regression-tests/04-rime/09-cooja-mesh.csc @@ -1,3731 +1,3731 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype812 - Cooja Mote Type #1 - [CONTIKI_DIR]/regression-tests/04-rime/code/mesh-node.c - make mesh-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - -15.110131951776825 - -15.766130931184252 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 75.32698081339126 - 15.146240079902862 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 72.13994478967824 - 74.26041049728875 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 21.45905883941627 - 18.50931229663846 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 4 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 51.73154548699189 - 51.853821705262824 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 5 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 62.76256370926019 - 23.744771850412793 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 77.53279132863358 - 2.39495180445084 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 7 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 9.301610765351997 - 11.468270260551716 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 96.0279441300693 - 77.21498068457203 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 9 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 14.931779398072187 - 88.03333861239253 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 10 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 75.44726862760838 - 5.411487191515407 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 11 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 95.318884841329 - 86.20194655940381 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 12 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 18.87115940222929 - 51.75275796436098 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 13 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 39.29584130063258 - 83.73613076037893 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 14 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 18.99016360852214 - 84.31828659208982 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 15 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 94.72045049573865 - 88.8002265547872 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 16 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 9.965149552619945 - 60.9672217226311 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 17 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 75.63601320305163 - 69.30301792320999 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 18 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 44.389408292201615 - 9.32896426859151 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 19 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 5.415822927153069 - 1.1229749685748303 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 20 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 17.73197875806011 - 91.09483283627415 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 21 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 63.21117626423727 - 92.09822312636405 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 22 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 1.2023179518000582 - 6.101073555655545 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 23 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 81.87774265107667 - 17.714586672424947 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 24 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 22.521479020896074 - 14.113603880757953 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 25 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 84.02138539648226 - 17.015320265906407 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 26 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 46.852336565832964 - 77.37329070431454 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 27 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 79.21392112207015 - 28.248800955218243 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 28 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 74.80704477852946 - 60.79424441306157 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 29 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 56.051297723638584 - 51.46569350230792 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 30 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 57.1269257718506 - 61.121148185570306 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 31 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 24.768409265606838 - 66.41379589463979 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 32 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 65.86939970609022 - 74.17702928480342 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 33 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 22.730659983362024 - 88.83212690881382 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 34 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 97.72636366803897 - 89.33964870322923 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 35 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 20.374524653886226 - 45.22966122318138 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 36 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 77.86468266153415 - 22.27997310669162 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 37 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 29.08732257227028 - 87.49874641701248 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 38 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 92.28518245794669 - 46.424258423445906 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 39 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 46.05708599953595 - 54.74731598871861 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 40 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 86.44276097412764 - 57.14457919424108 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 41 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 91.18152331698074 - 44.46303779585815 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 42 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 9.495031343513304 - 32.860166235404165 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 43 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 25.532456743363362 - 50.910025313741656 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 44 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 62.22618255413567 - 37.501327897174285 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 45 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 53.39846293057672 - 11.305221368002083 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 46 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 76.03978999479973 - 18.542902882611067 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 47 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 25.280683674156457 - 14.065650667522767 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 48 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 37.47973536226168 - 84.38773756679916 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 49 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 88.03948393367386 - 35.934760179823364 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 50 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 3.0107724008282433 - 20.54172713979715 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 51 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 92.2648242893991 - 2.19984740812853 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 52 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 71.1950863336371 - 12.977697720146663 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 53 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 23.39045217087643 - 96.05336539086986 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 54 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 91.30189414809722 - 62.48046280525844 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 55 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 90.54828218741403 - 67.41740523090176 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 56 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 59.584541112217 - 79.6815014505103 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 57 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 90.05917725331057 - 19.668333608379562 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 58 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 56.19172073106215 - 66.94875781635855 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 59 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 74.11183073083164 - 44.53101125240788 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 60 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 99.62245190569143 - 1.2518386804190595 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 61 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 50.86207262991679 - 64.2596263003396 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 62 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 82.90134355007967 - 98.46998610299977 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 63 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 32.097700534946775 - 57.82370953888362 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 64 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 20.792359880663426 - 42.18171503641626 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 65 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 26.90344653082014 - 49.34860693256755 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 66 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 93.37402442548722 - 12.54036096085449 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 67 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 63.50895936766901 - 26.13335565534737 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 68 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 54.59249988579196 - 28.10613096853092 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 69 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 51.72915360045628 - 7.2358928898125345 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 70 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 69.85466521382759 - 76.11700753212021 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 71 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 81.06814365856157 - 77.36444410758936 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 72 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 12.62178613429452 - 26.220067395705293 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 73 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 76.54960310902881 - 33.57032079508466 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 74 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 43.05406862818124 - 6.671159718339769 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 75 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 8.489914638926576 - 11.364660931830084 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 76 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 92.21297935768304 - 38.901136911882226 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 77 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 12.515404095391613 - 83.18052083184756 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 78 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 11.765120085018932 - 30.535771545958923 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 79 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 21.84827655269378 - 74.8105798512456 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 80 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 23.59921216453905 - 83.77605869702256 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 81 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 30.89218892933696 - 67.24517923056783 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 82 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 16.754948076730646 - 86.76525325664295 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 83 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 94.01968091458089 - 33.32895468517063 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 84 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 14.494646399171273 - 82.39583815813506 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 85 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 48.71947952314664 - 65.39753703873185 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 86 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 44.58919963221467 - 0.08824262076495559 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 87 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 31.35911964529313 - 44.53704965455876 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 88 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 36.73949789516603 - 50.485369712324925 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 89 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 6.151679368237806 - 70.75427799132197 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 90 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 86.75159969217906 - 15.772621058761239 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 91 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 43.81709449446297 - 51.01754337793292 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 92 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 35.30424198776551 - 75.40895569308267 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 93 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 92.16764155243385 - 37.12839773343516 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 94 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 26.003971042858886 - 30.335276302978187 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 95 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 63.631134510133734 - 24.450512217715136 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 96 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 22.467333143102163 - 81.04396399393656 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 97 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 97.69844265068488 - 95.83027844609585 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 98 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 65.38894336702717 - 65.01739556197926 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 99 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 23.52628911665692 - 1.207091576759045 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 100 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 49.375308587386826 - 16.68070312353277 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 101 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 69.461379757725 - 54.48065350202764 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 102 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 55.60961339959927 - 13.809323108297345 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 103 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 23.03486784995873 - 55.66637494926414 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 104 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 23.463634800199763 - 64.86732549368021 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 105 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 3.901375281857966 - 82.15368199936674 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 106 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 13.727410765057513 - 54.54734565801572 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 107 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 51.09638459119502 - 60.3491948088858 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 108 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 63.36127151665472 - 43.29434787013787 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 109 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 58.62938785115435 - 23.937940536279946 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 110 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 60.20153526777896 - 40.21802436438158 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 111 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 94.52454590425745 - 81.6694698767615 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 112 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 52.9213694599384 - 77.86420496516587 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 113 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 68.61056178583134 - 73.64759313367774 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 114 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 32.25025125998364 - 88.09394970381855 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 115 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 45.228818349692276 - 56.6857477992902 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 116 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 72.91510428342265 - 48.016968698680444 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 117 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 36.09326383724911 - 65.93561184944842 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 118 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 59.34646598759592 - 56.68812502666998 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 119 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 24.253968594634323 - 89.69274115479124 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 120 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 52.69518046464358 - 51.18422353087328 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 121 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 16.883346155197277 - 28.45535507975351 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 122 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 11.366979180477676 - 44.752447495970756 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 123 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 67.75166344967951 - 97.82453837992166 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 124 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 94.78000175089495 - 0.9187745489910304 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 125 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 51.056290388365596 - 60.98645524111218 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 126 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 51.49684628172943 - 62.65900518969486 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 127 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 68.92410375720559 - 22.04832696437221 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 128 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 82.82918233005728 - 62.79875071353599 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 129 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 83.5631819266006 - 81.58540225851283 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 130 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 44.44732988189216 - 14.491241662688436 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 131 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 40.780333569336 - 4.009415778619951 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 132 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 87.875397456334 - 43.63036340425231 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 133 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 89.42470277518677 - 99.84079465772967 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 134 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 85.87794548965859 - 89.0352799102892 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 135 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 57.22174940143495 - 10.145407049355216 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 136 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 38.94731418883078 - 82.77439711782424 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 137 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 59.32065648187531 - 44.20774255696792 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 138 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 31.120120849726774 - 89.60000439876077 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 139 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 44.52403715783231 - 62.3194136602862 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 140 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 22.362727341005417 - 49.59730180608639 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 141 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 14.370793944637184 - 84.16542992042004 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 142 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 10.382057116504594 - 36.20777577058662 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 143 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 31.708614425954153 - 8.929196448642006 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 144 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 18.99060403390356 - 28.098507024338037 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 145 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 3.7660125313138892 - 48.586414327187164 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 146 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 23.571368218820343 - 49.185899485490594 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 147 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 26.597355199952165 - 42.03120419505485 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 148 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 80.67530824986719 - 68.69137917126238 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 149 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 95.64723800253887 - 49.22571370181109 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 150 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 10.704141148035173 - 70.55232411145946 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 151 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 64.52024310025003 - 34.475451454425986 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 152 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 85.78573465828082 - 7.916030569985 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 153 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 0.24262868892772627 - 72.63231254385946 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 154 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 93.57606012872533 - 98.82725540441758 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 155 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 78.69632487677171 - 36.37925533039474 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 156 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 99.49668801110867 - 99.53794061222166 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 157 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 64.76201671109297 - 5.055212527820718 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 158 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 80.95330430773969 - 4.015680109351305 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 159 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 65.23411064596435 - 32.474870590460114 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 160 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 96.92930107013441 - 65.03716301192813 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 161 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 51.910733667455055 - 3.0607401855079153 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 162 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 22.997927613490187 - 52.49410023194099 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 163 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 61.498404326122916 - 20.948069777061473 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 164 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 86.67187941247089 - 57.91865763266372 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 165 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 58.12331461229143 - 17.597258881851896 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 166 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 90.97447553174264 - 6.397999431511192 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 167 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 24.266277228726896 - 30.34177377688706 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 168 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 98.47208098934011 - 44.57507934017237 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 169 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 43.73081376780091 - 21.13808300018135 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 170 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 45.49162860241004 - 68.84491125995895 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 171 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 83.6456747075875 - 43.93087863088753 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 172 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 72.03579837660902 - 34.60910091231335 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 173 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 35.263754721356534 - 76.30282405093295 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 174 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 40.61467901333516 - 24.94120175915311 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 175 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 60.156002945132116 - 50.68140149744396 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 176 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 3.887768554078841 - 45.57320016474882 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 177 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 19.95603661943931 - 20.00197042619395 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 178 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 92.14169094537768 - 79.0089520316807 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 179 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 65.67068979347698 - 88.48916739527394 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 180 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 76.14334621957694 - 61.01052000065369 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 181 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 84.25336051788017 - 19.669061259592745 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 182 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 16.168238996091954 - 10.832644717909435 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 183 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 64.09766119688976 - 88.85025066318933 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 184 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 4.810483157860002 - 36.48131639750729 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 185 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 51.74308602641094 - 87.53927985054797 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 186 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 18.77259055131779 - 67.96359965661854 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 187 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 44.72430321351292 - 72.44740211096371 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 188 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 5.88546300021735 - 25.93516805671332 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 189 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 51.41061394358658 - 15.202886891183166 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 190 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 89.23533431357276 - 77.23342632923122 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 191 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 60.079346331237495 - 82.34379420397117 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 192 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 85.025456606937 - 40.33998257744421 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 193 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 94.49078377456884 - 13.806399874732389 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 194 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 17.664363452458907 - 96.61599411572223 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 195 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 0.9648947505341954 - 75.5573385733673 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 196 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 10.975537455298422 - 11.904593591027812 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 197 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 57.42097054747428 - 15.293997771212686 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 198 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 23.228255481027414 - 38.44074324739415 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 199 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 122.09144445179118 - 123.28827939092514 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 200 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.plugins.SimControl - 280 - 0 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.TrafficVisualizerSkin - 2.1537601749087445 0.0 0.0 2.1537601749087445 62.919309242649014 50.9666138148029 - - 400 - 1 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1200 - 3 - 240 - 400 - 160 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 - 22 - 23 - 24 - 25 - 26 - 27 - 28 - 29 - 30 - 31 - 32 - 33 - 34 - 35 - 36 - 37 - 38 - 39 - 40 - 41 - 42 - 43 - 44 - 45 - 46 - 47 - 48 - 49 - 50 - 51 - 52 - 53 - 54 - 55 - 56 - 57 - 58 - 59 - 60 - 61 - 62 - 63 - 64 - 65 - 66 - 67 - 68 - 69 - 70 - 71 - 72 - 73 - 74 - 75 - 76 - 77 - 78 - 79 - 80 - 81 - 82 - 83 - 84 - 85 - 86 - 87 - 88 - 89 - 90 - 91 - 92 - 93 - 94 - 95 - 96 - 97 - 98 - 99 - 100 - 101 - 102 - 103 - 104 - 105 - 106 - 107 - 108 - 109 - 110 - 111 - 112 - 113 - 114 - 115 - 116 - 117 - 118 - 119 - 120 - 121 - 122 - 123 - 124 - 125 - 126 - 127 - 128 - 129 - 130 - 131 - 132 - 133 - 134 - 135 - 136 - 137 - 138 - 139 - 140 - 141 - 142 - 143 - 144 - 145 - 146 - 147 - 148 - 149 - 150 - 151 - 152 - 153 - 154 - 155 - 156 - 157 - 158 - 159 - 160 - 161 - 162 - 163 - 164 - 165 - 166 - 167 - 168 - 169 - 170 - 171 - 172 - 173 - 174 - 175 - 176 - 177 - 178 - 179 - 180 - 181 - 182 - 183 - 184 - 185 - 186 - 187 - 188 - 189 - 190 - 191 - 192 - 193 - 194 - 195 - 196 - 197 - 198 - 199 - - 500.0 - - 1600 - 4 - 300 - 0 - 405 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 920 - 5 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - 2 - 700 - 692 - -5 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype812 + Cooja Mote Type #1 + [CONTIKI_DIR]/regression-tests/04-rime/code/mesh-node.c + make mesh-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -15.110131951776825 + -15.766130931184252 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 75.32698081339126 + 15.146240079902862 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 72.13994478967824 + 74.26041049728875 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 21.45905883941627 + 18.50931229663846 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 51.73154548699189 + 51.853821705262824 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 62.76256370926019 + 23.744771850412793 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 77.53279132863358 + 2.39495180445084 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 9.301610765351997 + 11.468270260551716 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 96.0279441300693 + 77.21498068457203 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 9 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 14.931779398072187 + 88.03333861239253 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 10 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 75.44726862760838 + 5.411487191515407 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 11 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 95.318884841329 + 86.20194655940381 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 12 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 18.87115940222929 + 51.75275796436098 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 13 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 39.29584130063258 + 83.73613076037893 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 14 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 18.99016360852214 + 84.31828659208982 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 15 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 94.72045049573865 + 88.8002265547872 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 16 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 9.965149552619945 + 60.9672217226311 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 17 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 75.63601320305163 + 69.30301792320999 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 18 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 44.389408292201615 + 9.32896426859151 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 19 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 5.415822927153069 + 1.1229749685748303 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 20 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 17.73197875806011 + 91.09483283627415 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 21 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 63.21117626423727 + 92.09822312636405 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 22 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 1.2023179518000582 + 6.101073555655545 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 23 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 81.87774265107667 + 17.714586672424947 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 24 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 22.521479020896074 + 14.113603880757953 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 25 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 84.02138539648226 + 17.015320265906407 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 26 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 46.852336565832964 + 77.37329070431454 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 27 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 79.21392112207015 + 28.248800955218243 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 28 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 74.80704477852946 + 60.79424441306157 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 29 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 56.051297723638584 + 51.46569350230792 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 30 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 57.1269257718506 + 61.121148185570306 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 31 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 24.768409265606838 + 66.41379589463979 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 32 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 65.86939970609022 + 74.17702928480342 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 33 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 22.730659983362024 + 88.83212690881382 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 34 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 97.72636366803897 + 89.33964870322923 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 35 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 20.374524653886226 + 45.22966122318138 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 36 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 77.86468266153415 + 22.27997310669162 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 37 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 29.08732257227028 + 87.49874641701248 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 38 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 92.28518245794669 + 46.424258423445906 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 39 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 46.05708599953595 + 54.74731598871861 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 40 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 86.44276097412764 + 57.14457919424108 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 41 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 91.18152331698074 + 44.46303779585815 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 42 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 9.495031343513304 + 32.860166235404165 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 43 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 25.532456743363362 + 50.910025313741656 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 44 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 62.22618255413567 + 37.501327897174285 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 45 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 53.39846293057672 + 11.305221368002083 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 46 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 76.03978999479973 + 18.542902882611067 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 47 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 25.280683674156457 + 14.065650667522767 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 48 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 37.47973536226168 + 84.38773756679916 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 49 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 88.03948393367386 + 35.934760179823364 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 50 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 3.0107724008282433 + 20.54172713979715 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 51 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 92.2648242893991 + 2.19984740812853 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 52 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 71.1950863336371 + 12.977697720146663 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 53 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 23.39045217087643 + 96.05336539086986 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 54 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 91.30189414809722 + 62.48046280525844 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 55 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 90.54828218741403 + 67.41740523090176 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 56 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 59.584541112217 + 79.6815014505103 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 57 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 90.05917725331057 + 19.668333608379562 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 58 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 56.19172073106215 + 66.94875781635855 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 59 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 74.11183073083164 + 44.53101125240788 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 60 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 99.62245190569143 + 1.2518386804190595 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 61 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 50.86207262991679 + 64.2596263003396 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 62 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 82.90134355007967 + 98.46998610299977 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 63 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 32.097700534946775 + 57.82370953888362 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 64 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 20.792359880663426 + 42.18171503641626 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 65 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 26.90344653082014 + 49.34860693256755 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 66 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 93.37402442548722 + 12.54036096085449 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 67 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 63.50895936766901 + 26.13335565534737 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 68 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 54.59249988579196 + 28.10613096853092 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 69 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 51.72915360045628 + 7.2358928898125345 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 70 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 69.85466521382759 + 76.11700753212021 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 71 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 81.06814365856157 + 77.36444410758936 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 72 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 12.62178613429452 + 26.220067395705293 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 73 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 76.54960310902881 + 33.57032079508466 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 74 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 43.05406862818124 + 6.671159718339769 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 75 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 8.489914638926576 + 11.364660931830084 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 76 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 92.21297935768304 + 38.901136911882226 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 77 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 12.515404095391613 + 83.18052083184756 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 78 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 11.765120085018932 + 30.535771545958923 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 79 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 21.84827655269378 + 74.8105798512456 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 80 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 23.59921216453905 + 83.77605869702256 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 81 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 30.89218892933696 + 67.24517923056783 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 82 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 16.754948076730646 + 86.76525325664295 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 83 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 94.01968091458089 + 33.32895468517063 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 84 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 14.494646399171273 + 82.39583815813506 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 85 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 48.71947952314664 + 65.39753703873185 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 86 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 44.58919963221467 + 0.08824262076495559 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 87 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 31.35911964529313 + 44.53704965455876 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 88 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 36.73949789516603 + 50.485369712324925 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 89 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 6.151679368237806 + 70.75427799132197 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 90 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 86.75159969217906 + 15.772621058761239 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 91 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 43.81709449446297 + 51.01754337793292 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 92 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 35.30424198776551 + 75.40895569308267 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 93 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 92.16764155243385 + 37.12839773343516 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 94 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 26.003971042858886 + 30.335276302978187 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 95 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 63.631134510133734 + 24.450512217715136 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 96 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 22.467333143102163 + 81.04396399393656 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 97 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 97.69844265068488 + 95.83027844609585 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 98 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 65.38894336702717 + 65.01739556197926 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 99 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 23.52628911665692 + 1.207091576759045 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 100 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 49.375308587386826 + 16.68070312353277 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 101 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 69.461379757725 + 54.48065350202764 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 102 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 55.60961339959927 + 13.809323108297345 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 103 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 23.03486784995873 + 55.66637494926414 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 104 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 23.463634800199763 + 64.86732549368021 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 105 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 3.901375281857966 + 82.15368199936674 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 106 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 13.727410765057513 + 54.54734565801572 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 107 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 51.09638459119502 + 60.3491948088858 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 108 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 63.36127151665472 + 43.29434787013787 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 109 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 58.62938785115435 + 23.937940536279946 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 110 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 60.20153526777896 + 40.21802436438158 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 111 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 94.52454590425745 + 81.6694698767615 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 112 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 52.9213694599384 + 77.86420496516587 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 113 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 68.61056178583134 + 73.64759313367774 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 114 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 32.25025125998364 + 88.09394970381855 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 115 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 45.228818349692276 + 56.6857477992902 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 116 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 72.91510428342265 + 48.016968698680444 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 117 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 36.09326383724911 + 65.93561184944842 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 118 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 59.34646598759592 + 56.68812502666998 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 119 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 24.253968594634323 + 89.69274115479124 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 120 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 52.69518046464358 + 51.18422353087328 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 121 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 16.883346155197277 + 28.45535507975351 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 122 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 11.366979180477676 + 44.752447495970756 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 123 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 67.75166344967951 + 97.82453837992166 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 124 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 94.78000175089495 + 0.9187745489910304 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 125 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 51.056290388365596 + 60.98645524111218 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 126 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 51.49684628172943 + 62.65900518969486 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 127 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 68.92410375720559 + 22.04832696437221 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 128 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 82.82918233005728 + 62.79875071353599 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 129 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 83.5631819266006 + 81.58540225851283 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 130 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 44.44732988189216 + 14.491241662688436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 131 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 40.780333569336 + 4.009415778619951 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 132 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 87.875397456334 + 43.63036340425231 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 133 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 89.42470277518677 + 99.84079465772967 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 134 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 85.87794548965859 + 89.0352799102892 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 135 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 57.22174940143495 + 10.145407049355216 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 136 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 38.94731418883078 + 82.77439711782424 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 137 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 59.32065648187531 + 44.20774255696792 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 138 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 31.120120849726774 + 89.60000439876077 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 139 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 44.52403715783231 + 62.3194136602862 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 140 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 22.362727341005417 + 49.59730180608639 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 141 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 14.370793944637184 + 84.16542992042004 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 142 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 10.382057116504594 + 36.20777577058662 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 143 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 31.708614425954153 + 8.929196448642006 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 144 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 18.99060403390356 + 28.098507024338037 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 145 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 3.7660125313138892 + 48.586414327187164 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 146 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 23.571368218820343 + 49.185899485490594 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 147 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 26.597355199952165 + 42.03120419505485 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 148 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 80.67530824986719 + 68.69137917126238 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 149 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 95.64723800253887 + 49.22571370181109 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 150 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 10.704141148035173 + 70.55232411145946 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 151 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 64.52024310025003 + 34.475451454425986 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 152 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 85.78573465828082 + 7.916030569985 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 153 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 0.24262868892772627 + 72.63231254385946 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 154 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 93.57606012872533 + 98.82725540441758 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 155 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 78.69632487677171 + 36.37925533039474 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 156 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 99.49668801110867 + 99.53794061222166 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 157 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 64.76201671109297 + 5.055212527820718 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 158 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 80.95330430773969 + 4.015680109351305 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 159 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 65.23411064596435 + 32.474870590460114 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 160 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 96.92930107013441 + 65.03716301192813 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 161 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 51.910733667455055 + 3.0607401855079153 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 162 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 22.997927613490187 + 52.49410023194099 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 163 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 61.498404326122916 + 20.948069777061473 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 164 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 86.67187941247089 + 57.91865763266372 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 165 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 58.12331461229143 + 17.597258881851896 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 166 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 90.97447553174264 + 6.397999431511192 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 167 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 24.266277228726896 + 30.34177377688706 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 168 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 98.47208098934011 + 44.57507934017237 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 169 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 43.73081376780091 + 21.13808300018135 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 170 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 45.49162860241004 + 68.84491125995895 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 171 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 83.6456747075875 + 43.93087863088753 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 172 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 72.03579837660902 + 34.60910091231335 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 173 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 35.263754721356534 + 76.30282405093295 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 174 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 40.61467901333516 + 24.94120175915311 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 175 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 60.156002945132116 + 50.68140149744396 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 176 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 3.887768554078841 + 45.57320016474882 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 177 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 19.95603661943931 + 20.00197042619395 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 178 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 92.14169094537768 + 79.0089520316807 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 179 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 65.67068979347698 + 88.48916739527394 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 180 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 76.14334621957694 + 61.01052000065369 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 181 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 84.25336051788017 + 19.669061259592745 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 182 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 16.168238996091954 + 10.832644717909435 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 183 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 64.09766119688976 + 88.85025066318933 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 184 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 4.810483157860002 + 36.48131639750729 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 185 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 51.74308602641094 + 87.53927985054797 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 186 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 18.77259055131779 + 67.96359965661854 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 187 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 44.72430321351292 + 72.44740211096371 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 188 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 5.88546300021735 + 25.93516805671332 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 189 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 51.41061394358658 + 15.202886891183166 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 190 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 89.23533431357276 + 77.23342632923122 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 191 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 60.079346331237495 + 82.34379420397117 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 192 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 85.025456606937 + 40.33998257744421 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 193 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 94.49078377456884 + 13.806399874732389 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 194 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 17.664363452458907 + 96.61599411572223 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 195 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 0.9648947505341954 + 75.5573385733673 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 196 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 10.975537455298422 + 11.904593591027812 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 197 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 57.42097054747428 + 15.293997771212686 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 198 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 23.228255481027414 + 38.44074324739415 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 199 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 122.09144445179118 + 123.28827939092514 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 200 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + 2.1537601749087445 0.0 0.0 2.1537601749087445 62.919309242649014 50.9666138148029 + + 400 + 1 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1200 + 3 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 + 100 + 101 + 102 + 103 + 104 + 105 + 106 + 107 + 108 + 109 + 110 + 111 + 112 + 113 + 114 + 115 + 116 + 117 + 118 + 119 + 120 + 121 + 122 + 123 + 124 + 125 + 126 + 127 + 128 + 129 + 130 + 131 + 132 + 133 + 134 + 135 + 136 + 137 + 138 + 139 + 140 + 141 + 142 + 143 + 144 + 145 + 146 + 147 + 148 + 149 + 150 + 151 + 152 + 153 + 154 + 155 + 156 + 157 + 158 + 159 + 160 + 161 + 162 + 163 + 164 + 165 + 166 + 167 + 168 + 169 + 170 + 171 + 172 + 173 + 174 + 175 + 176 + 177 + 178 + 179 + 180 + 181 + 182 + 183 + 184 + 185 + 186 + 187 + 188 + 189 + 190 + 191 + 192 + 193 + 194 + 195 + 196 + 197 + 198 + 199 + + 500.0 + + 1600 + 4 + 300 + 0 + 405 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 920 + 5 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 2 + 700 + 692 + -5 + + + diff --git a/regression-tests/04-rime/code/Makefile b/regression-tests/04-rime/code/Makefile index b6db61162..cec13fcf2 100644 --- a/regression-tests/04-rime/code/Makefile +++ b/regression-tests/04-rime/code/Makefile @@ -2,4 +2,5 @@ CONTIKI = ../../.. all: trickle-node +CONTIKI_WITH_RIME = 1 include $(CONTIKI)/Makefile.include diff --git a/regression-tests/05-netperf/01-sky-netperf.csc b/regression-tests/05-netperf/01-sky-netperf.csc index f239ae82d..971655b08 100644 --- a/regression-tests/05-netperf/01-sky-netperf.csc +++ b/regression-tests/05-netperf/01-sky-netperf.csc @@ -36,7 +36,7 @@ make netperf-shell.sky TARGET=sky org.contikios.cooja.mspmote.interfaces.SkyButton org.contikios.cooja.mspmote.interfaces.SkyFlash org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio + org.contikios.cooja.mspmote.interfaces.Msp802154Radio org.contikios.cooja.mspmote.interfaces.SkySerial org.contikios.cooja.mspmote.interfaces.SkyLED diff --git a/regression-tests/05-netperf/02-sky-netperf-lpp.csc b/regression-tests/05-netperf/02-sky-netperf-lpp.csc index 8f545123e..93dd2cce1 100644 --- a/regression-tests/05-netperf/02-sky-netperf-lpp.csc +++ b/regression-tests/05-netperf/02-sky-netperf-lpp.csc @@ -36,7 +36,7 @@ make DEFINES=NETSTACK_RDC=lpp_driver netperf-shell.sky TARGET=sky org.contikios.cooja.mspmote.interfaces.SkyButton org.contikios.cooja.mspmote.interfaces.SkyFlash org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio + org.contikios.cooja.mspmote.interfaces.Msp802154Radio org.contikios.cooja.mspmote.interfaces.SkySerial org.contikios.cooja.mspmote.interfaces.SkyLED diff --git a/regression-tests/05-netperf/03-sky-netperf-cxmac.csc b/regression-tests/05-netperf/03-sky-netperf-cxmac.csc index 266e0b709..761fe3536 100644 --- a/regression-tests/05-netperf/03-sky-netperf-cxmac.csc +++ b/regression-tests/05-netperf/03-sky-netperf-cxmac.csc @@ -36,7 +36,7 @@ make DEFINES=NETSTACK_RDC=cxmac_driver netperf-shell.sky TARGET=sky org.contikios.cooja.mspmote.interfaces.SkyButton org.contikios.cooja.mspmote.interfaces.SkyFlash org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio + org.contikios.cooja.mspmote.interfaces.Msp802154Radio org.contikios.cooja.mspmote.interfaces.SkySerial org.contikios.cooja.mspmote.interfaces.SkyLED diff --git a/regression-tests/06-shell/01-sky-shell-compile.csc b/regression-tests/06-shell/01-sky-shell-compile.csc index a889a8e6e..24712ce1f 100644 --- a/regression-tests/06-shell/01-sky-shell-compile.csc +++ b/regression-tests/06-shell/01-sky-shell-compile.csc @@ -34,7 +34,7 @@ make sky-shell.sky TARGET=sky org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.SkyButton org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyByteRadio + org.contikios.cooja.mspmote.interfaces.Msp802154Radio org.contikios.cooja.mspmote.interfaces.MspSerial org.contikios.cooja.mspmote.interfaces.SkyLED diff --git a/regression-tests/06-shell/02-sky-shell-basic-commands.csc b/regression-tests/06-shell/02-sky-shell-basic-commands.csc index c918aec63..19250e31d 100644 --- a/regression-tests/06-shell/02-sky-shell-basic-commands.csc +++ b/regression-tests/06-shell/02-sky-shell-basic-commands.csc @@ -34,7 +34,7 @@ make sky-shell.sky TARGET=sky org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.SkyButton org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyByteRadio + org.contikios.cooja.mspmote.interfaces.Msp802154Radio org.contikios.cooja.mspmote.interfaces.MspSerial org.contikios.cooja.mspmote.interfaces.SkyLED org.contikios.cooja.interfaces.RimeAddress diff --git a/regression-tests/06-shell/03-sky-shell-sendcmd.csc b/regression-tests/06-shell/03-sky-shell-sendcmd.csc index 605c6cdc3..03ab84dde 100644 --- a/regression-tests/06-shell/03-sky-shell-sendcmd.csc +++ b/regression-tests/06-shell/03-sky-shell-sendcmd.csc @@ -33,7 +33,7 @@ make sky-shell.sky TARGET=sky org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.SkyButton org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyByteRadio + org.contikios.cooja.mspmote.interfaces.Msp802154Radio org.contikios.cooja.mspmote.interfaces.MspSerial org.contikios.cooja.mspmote.interfaces.SkyLED org.contikios.cooja.interfaces.RimeAddress diff --git a/regression-tests/06-shell/04-sky-shell-download.csc.fails b/regression-tests/06-shell/04-sky-shell-download.csc.fails index bf055ad62..adeb111a2 100644 --- a/regression-tests/06-shell/04-sky-shell-download.csc.fails +++ b/regression-tests/06-shell/04-sky-shell-download.csc.fails @@ -32,7 +32,7 @@ org.contikios.cooja.mspmote.interfaces.SkyButton org.contikios.cooja.mspmote.interfaces.SkyFlash org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio + org.contikios.cooja.mspmote.interfaces.Msp802154Radio org.contikios.cooja.mspmote.interfaces.MspSerial org.contikios.cooja.mspmote.interfaces.SkyLED org.contikios.cooja.mspmote.interfaces.MspDebugOutput diff --git a/regression-tests/07-elfloader/01-sky-shell-exec-serial.csc b/regression-tests/07-elfloader/01-sky-shell-exec-serial.csc index d10c4314f..6d010c6c5 100644 --- a/regression-tests/07-elfloader/01-sky-shell-exec-serial.csc +++ b/regression-tests/07-elfloader/01-sky-shell-exec-serial.csc @@ -43,7 +43,7 @@ make hello-world.ce TARGET=sky SMALL=0 org.contikios.cooja.mspmote.interfaces.SkyButton org.contikios.cooja.mspmote.interfaces.SkyFlash org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio + org.contikios.cooja.mspmote.interfaces.Msp802154Radio org.contikios.cooja.mspmote.interfaces.MspSerial org.contikios.cooja.mspmote.interfaces.SkyLED org.contikios.cooja.mspmote.interfaces.MspDebugOutput diff --git a/regression-tests/09-collect-lossy/01-sky-shell-collect-lossy.csc b/regression-tests/09-collect-lossy/01-sky-shell-collect-lossy.csc index abbe506eb..aef4613db 100644 --- a/regression-tests/09-collect-lossy/01-sky-shell-collect-lossy.csc +++ b/regression-tests/09-collect-lossy/01-sky-shell-collect-lossy.csc @@ -1,540 +1,540 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 80.0 - 0.0 - 1.0 - 0.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - shell - [CONTIKI_DIR]/examples/collect/collect-view-shell.c - make collect-view-shell.sky TARGET=sky - [CONTIKI_DIR]/examples/collect/collect-view-shell.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 51.083635845134815 - 52.18027797603351 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 87.37621589982353 - 69.01745044943294 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 0.3225524247130407 - 99.67744560167213 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 52.99553499162932 - 44.55947520113671 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 64.36007081217727 - 7.922505931377522 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 46.937655527278906 - 34.37401121375584 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 29.606117317748925 - 59.7062771702808 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 7 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 64.60462597715014 - 65.32875118919438 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 8 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 84.91966612667193 - 21.61064185087591 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 9 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 24.128119535736893 - 14.27770805377394 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 10 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 36.23919862128766 - 23.421151622254555 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 11 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 53.689973725385855 - 92.47281715616484 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 12 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 21.499980846738108 - 86.31913226282572 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 13 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 23.896054282937385 - 6.502957157635625 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 14 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 86.99986531287792 - 45.74381748881159 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 15 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 68.50722882135574 - 50.25930042782911 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 16 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 22.03851735367126 - 57.304977718401084 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 17 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 16.094855623021655 - 20.15220518337424 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 18 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 91.46540103964149 - 63.949352956656554 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 19 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 71.92141571796324 - 39.70157072422388 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 20 - - sky1 - - - - org.contikios.cooja.plugins.SimControl - 318 - 1 - 172 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.AttributeVisualizerSkin - 4.028431381533795 0.0 0.0 4.028431381533795 114.84980283087096 -0.016939876572727552 - - 631 - 2 - 545 - 809 - 0 - - - org.contikios.cooja.plugins.LogListener - - timedout - - - - 1440 - 3 - 275 - 1 - 556 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - 0 - 775 - 304 - 5 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 80.0 + 0.0 + 1.0 + 0.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + shell + [CONTIKI_DIR]/examples/collect/collect-view-shell.c + make collect-view-shell.sky TARGET=sky + [CONTIKI_DIR]/examples/collect/collect-view-shell.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 51.083635845134815 + 52.18027797603351 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 87.37621589982353 + 69.01745044943294 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 0.3225524247130407 + 99.67744560167213 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 52.99553499162932 + 44.55947520113671 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 64.36007081217727 + 7.922505931377522 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 46.937655527278906 + 34.37401121375584 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 29.606117317748925 + 59.7062771702808 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 64.60462597715014 + 65.32875118919438 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 84.91966612667193 + 21.61064185087591 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 24.128119535736893 + 14.27770805377394 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 36.23919862128766 + 23.421151622254555 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 11 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 53.689973725385855 + 92.47281715616484 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 12 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 21.499980846738108 + 86.31913226282572 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 13 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 23.896054282937385 + 6.502957157635625 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 14 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 86.99986531287792 + 45.74381748881159 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 15 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 68.50722882135574 + 50.25930042782911 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 16 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 22.03851735367126 + 57.304977718401084 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 17 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 16.094855623021655 + 20.15220518337424 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 18 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 91.46540103964149 + 63.949352956656554 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 19 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 71.92141571796324 + 39.70157072422388 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 20 + + sky1 + + + + org.contikios.cooja.plugins.SimControl + 318 + 1 + 172 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + 4.028431381533795 0.0 0.0 4.028431381533795 114.84980283087096 -0.016939876572727552 + + 631 + 2 + 545 + 809 + 0 + + + org.contikios.cooja.plugins.LogListener + + timedout + + + + 1440 + 3 + 275 + 1 + 556 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 0 + 775 + 304 + 5 + + + diff --git a/regression-tests/10-ipv4/x02-ip-sky-telnet-ping.csc b/regression-tests/10-ipv4/x02-ip-sky-telnet-ping.csc index b2a10bdb4..287acbe12 100644 --- a/regression-tests/10-ipv4/x02-ip-sky-telnet-ping.csc +++ b/regression-tests/10-ipv4/x02-ip-sky-telnet-ping.csc @@ -32,7 +32,7 @@ org.contikios.cooja.mspmote.interfaces.SkyButton org.contikios.cooja.mspmote.interfaces.SkyFlash org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio + org.contikios.cooja.mspmote.interfaces.Msp802154Radio org.contikios.cooja.mspmote.interfaces.MspSerial org.contikios.cooja.mspmote.interfaces.SkyLED org.contikios.cooja.mspmote.interfaces.MspDebugOutput diff --git a/regression-tests/10-ipv4/x03-ip-sky-webserver-wget.csc b/regression-tests/10-ipv4/x03-ip-sky-webserver-wget.csc index 6f5207ea8..7c2fa2ee2 100644 --- a/regression-tests/10-ipv4/x03-ip-sky-webserver-wget.csc +++ b/regression-tests/10-ipv4/x03-ip-sky-webserver-wget.csc @@ -34,7 +34,7 @@ make sky-shell-webserver.sky TARGET=sky DEFINES=NETSTACK_MAC=nullmac_driver,NETS org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.SkyButton org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyByteRadio + org.contikios.cooja.mspmote.interfaces.Msp802154Radio org.contikios.cooja.mspmote.interfaces.MspSerial org.contikios.cooja.mspmote.interfaces.SkyLED diff --git a/regression-tests/11-ipv6/01-cooja-ipv6-udp.csc b/regression-tests/11-ipv6/01-cooja-ipv6-udp.csc index 8681e4ded..ff00b5bc3 100644 --- a/regression-tests/11-ipv6/01-cooja-ipv6-udp.csc +++ b/regression-tests/11-ipv6/01-cooja-ipv6-udp.csc @@ -1,183 +1,183 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - generated - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype350 - Receiver - [CONTIKI_DIR]/examples/udp-ipv6/udp-server.c - make TARGET=cooja clean -make udp-server.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype981 - Sender - [CONTIKI_DIR]/examples/udp-ipv6/udp-client.c - make udp-client.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - 98.76075470611741 - 30.469519951198897 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype350 - - - - org.contikios.cooja.interfaces.Position - 58.59043340181549 - 22.264557758786697 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype981 - - - - org.contikios.cooja.plugins.SimControl - 248 - 2 - 200 - 0 - 0 - - - org.contikios.cooja.plugins.LogListener - - ID:1 - - - - 851 - 1 - 187 - 1 - 521 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.TrafficVisualizerSkin - 2.565713585691764 0.0 0.0 2.565713585691764 -91.30090099174814 -28.413835696190525 - - 246 - 3 - 121 - 1 - 201 - - - org.contikios.cooja.plugins.RadioLogger - - 133 - - false - false - - 246 - 4 - 198 - 0 - 323 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - 0 - 520 - 250 - -1 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype350 + Receiver + [CONTIKI_DIR]/examples/udp-ipv6/udp-server.c + make TARGET=cooja clean +make udp-server.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype981 + Sender + [CONTIKI_DIR]/examples/udp-ipv6/udp-client.c + make udp-client.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 98.76075470611741 + 30.469519951198897 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype350 + + + + org.contikios.cooja.interfaces.Position + 58.59043340181549 + 22.264557758786697 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype981 + + + + org.contikios.cooja.plugins.SimControl + 248 + 2 + 200 + 0 + 0 + + + org.contikios.cooja.plugins.LogListener + + ID:1 + + + + 851 + 1 + 187 + 1 + 521 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + 2.565713585691764 0.0 0.0 2.565713585691764 -91.30090099174814 -28.413835696190525 + + 246 + 3 + 121 + 1 + 201 + + + org.contikios.cooja.plugins.RadioLogger + + 133 + + false + false + + 246 + 4 + 198 + 0 + 323 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 0 + 520 + 250 + -1 + + + diff --git a/regression-tests/11-ipv6/010-exp5438-unicast-fragmentation-contikimac.csc b/regression-tests/11-ipv6/010-exp5438-unicast-fragmentation-contikimac.csc index d8bd6551d..6fc25f388 100644 --- a/regression-tests/11-ipv6/010-exp5438-unicast-fragmentation-contikimac.csc +++ b/regression-tests/11-ipv6/010-exp5438-unicast-fragmentation-contikimac.csc @@ -1,166 +1,166 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#1 - Sender - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.c - make clean TARGET=exp5438 -make unicast-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver,SIZE=400,BUFSIZE=500 TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#2 - Receiver - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c - make clean TARGET=exp5438 -make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver,SIZE=400,BUFSIZE=500 TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - - - org.contikios.cooja.interfaces.Position - 40.305234290431166 - 41.884881003965305 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - exp5438#1 - - - - - org.contikios.cooja.interfaces.Position - 65.38552901873047 - 40.93246474846026 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - exp5438#2 - - - - org.contikios.cooja.plugins.SimControl - 280 - 0 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - 1200 - 5 - 240 - 400 - 160 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - - - - 500.0 - - 1600 - 4 - 166 - 0 - 539 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 920 - 3 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - [CONFIG_DIR]/fragmentation-should-receive-all.js - true - - 618 - 1 - 399 - 645 - 128 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#1 + Sender + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.c + make clean TARGET=exp5438 +make unicast-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver,SIZE=400,BUFSIZE=500 TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#2 + Receiver + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c + make clean TARGET=exp5438 +make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver,SIZE=400,BUFSIZE=500 TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 40.305234290431166 + 41.884881003965305 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + exp5438#1 + + + + + org.contikios.cooja.interfaces.Position + 65.38552901873047 + 40.93246474846026 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + exp5438#2 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + 1200 + 5 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + + + + 500.0 + + 1600 + 4 + 166 + 0 + 539 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 920 + 3 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONFIG_DIR]/fragmentation-should-receive-all.js + true + + 618 + 1 + 399 + 645 + 128 + + + diff --git a/regression-tests/11-ipv6/02-sky-ipv6-udp.csc.flaky b/regression-tests/11-ipv6/02-sky-ipv6-udp.csc.flaky index 9011f0827..7eb321a02 100644 --- a/regression-tests/11-ipv6/02-sky-ipv6-udp.csc.flaky +++ b/regression-tests/11-ipv6/02-sky-ipv6-udp.csc.flaky @@ -33,7 +33,7 @@ make udp-client.sky TARGET=sky DEFINES=UDP_CONNECTION_ADDR=fe80::212:7402:2:202< org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.SkyButton org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyByteRadio + org.contikios.cooja.mspmote.interfaces.Msp802154Radio org.contikios.cooja.mspmote.interfaces.MspSerial org.contikios.cooja.mspmote.interfaces.SkyLED @@ -51,7 +51,7 @@ make udp-client.sky TARGET=sky DEFINES=UDP_CONNECTION_ADDR=fe80::212:7402:2:202< org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.SkyButton org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyByteRadio + org.contikios.cooja.mspmote.interfaces.Msp802154Radio org.contikios.cooja.mspmote.interfaces.MspSerial org.contikios.cooja.mspmote.interfaces.SkyLED diff --git a/regression-tests/11-ipv6/04-exp5438-udp-fragmentation-contikimac.csc b/regression-tests/11-ipv6/04-exp5438-udp-fragmentation-contikimac.csc index 2608365e9..f80dbc872 100644 --- a/regression-tests/11-ipv6/04-exp5438-udp-fragmentation-contikimac.csc +++ b/regression-tests/11-ipv6/04-exp5438-udp-fragmentation-contikimac.csc @@ -1,167 +1,167 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#1 - Sender - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.c - make clean TARGET=exp5438 -make udp-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#2 - Receiver - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c - make clean TARGET=exp5438 -make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - - - org.contikios.cooja.interfaces.Position - 40.305234290431166 - 41.884881003965305 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - exp5438#1 - - - - - org.contikios.cooja.interfaces.Position - 65.38552901873047 - 40.93246474846026 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - exp5438#2 - - - - org.contikios.cooja.plugins.SimControl - 280 - 0 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1200 - 5 - 240 - 400 - 160 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - - - - 500.0 - - 1600 - 4 - 166 - 0 - 539 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 920 - 3 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - [CONTIKI_DIR]/regression-tests/11-ipv6/fragmentation-should-receive-all.js - true - - 618 - 1 - 399 - 645 - 128 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#1 + Sender + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.c + make clean TARGET=exp5438 +make udp-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#2 + Receiver + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c + make clean TARGET=exp5438 +make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 40.305234290431166 + 41.884881003965305 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + exp5438#1 + + + + + org.contikios.cooja.interfaces.Position + 65.38552901873047 + 40.93246474846026 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + exp5438#2 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1200 + 5 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + + + + 500.0 + + 1600 + 4 + 166 + 0 + 539 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 920 + 3 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONTIKI_DIR]/regression-tests/11-ipv6/fragmentation-should-receive-all.js + true + + 618 + 1 + 399 + 645 + 128 + + + diff --git a/regression-tests/11-ipv6/05-exp5438-udp-fragmentation-nullrdc.csc b/regression-tests/11-ipv6/05-exp5438-udp-fragmentation-nullrdc.csc index 5a3025135..3111ea12c 100644 --- a/regression-tests/11-ipv6/05-exp5438-udp-fragmentation-nullrdc.csc +++ b/regression-tests/11-ipv6/05-exp5438-udp-fragmentation-nullrdc.csc @@ -1,167 +1,167 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#1 - Sender - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.c - make clean TARGET=exp5438 -make udp-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#2 - Receiver - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c - make clean TARGET=exp5438 -make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - - - org.contikios.cooja.interfaces.Position - 40.305234290431166 - 41.884881003965305 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - exp5438#1 - - - - - org.contikios.cooja.interfaces.Position - 65.38552901873047 - 40.93246474846026 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - exp5438#2 - - - - org.contikios.cooja.plugins.SimControl - 280 - 0 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1200 - 5 - 240 - 400 - 160 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - - - - 500.0 - - 1600 - 4 - 166 - 0 - 539 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 920 - 3 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - [CONTIKI_DIR]/regression-tests/11-ipv6/fragmentation-should-receive-all.js - true - - 618 - 1 - 399 - 645 - 128 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#1 + Sender + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.c + make clean TARGET=exp5438 +make udp-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#2 + Receiver + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c + make clean TARGET=exp5438 +make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 40.305234290431166 + 41.884881003965305 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + exp5438#1 + + + + + org.contikios.cooja.interfaces.Position + 65.38552901873047 + 40.93246474846026 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + exp5438#2 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1200 + 5 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + + + + 500.0 + + 1600 + 4 + 166 + 0 + 539 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 920 + 3 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONTIKI_DIR]/regression-tests/11-ipv6/fragmentation-should-receive-all.js + true + + 618 + 1 + 399 + 645 + 128 + + + diff --git a/regression-tests/11-ipv6/06-exp5438-udp-fragmentation-contikimac-large-sender.csc b/regression-tests/11-ipv6/06-exp5438-udp-fragmentation-contikimac-large-sender.csc index ae2485746..cc742ee1d 100644 --- a/regression-tests/11-ipv6/06-exp5438-udp-fragmentation-contikimac-large-sender.csc +++ b/regression-tests/11-ipv6/06-exp5438-udp-fragmentation-contikimac-large-sender.csc @@ -1,167 +1,167 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#1 - Sender - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.c - make clean TARGET=exp5438 -make udp-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver,SIZE=500,BUFSIZE=600 TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#2 - Receiver - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c - make clean TARGET=exp5438 -make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - - - org.contikios.cooja.interfaces.Position - 40.305234290431166 - 41.884881003965305 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - exp5438#1 - - - - - org.contikios.cooja.interfaces.Position - 65.38552901873047 - 40.93246474846026 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - exp5438#2 - - - - org.contikios.cooja.plugins.SimControl - 280 - 0 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1200 - 5 - 240 - 400 - 160 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - - - - 500.0 - - 1600 - 4 - 166 - 0 - 539 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 920 - 3 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - [CONTIKI_DIR]/regression-tests/11-ipv6/fragmentation-should-receive-none.js - true - - 618 - 1 - 399 - 645 - 128 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#1 + Sender + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.c + make clean TARGET=exp5438 +make udp-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver,SIZE=500,BUFSIZE=600 TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#2 + Receiver + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c + make clean TARGET=exp5438 +make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 40.305234290431166 + 41.884881003965305 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + exp5438#1 + + + + + org.contikios.cooja.interfaces.Position + 65.38552901873047 + 40.93246474846026 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + exp5438#2 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1200 + 5 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + + + + 500.0 + + 1600 + 4 + 166 + 0 + 539 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 920 + 3 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONTIKI_DIR]/regression-tests/11-ipv6/fragmentation-should-receive-none.js + true + + 618 + 1 + 399 + 645 + 128 + + + diff --git a/regression-tests/11-ipv6/07-exp5438-udp-fragmentation-nullrdc-large-sender.csc b/regression-tests/11-ipv6/07-exp5438-udp-fragmentation-nullrdc-large-sender.csc index cc982ba44..e2991910d 100644 --- a/regression-tests/11-ipv6/07-exp5438-udp-fragmentation-nullrdc-large-sender.csc +++ b/regression-tests/11-ipv6/07-exp5438-udp-fragmentation-nullrdc-large-sender.csc @@ -1,167 +1,167 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#1 - Sender - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.c - make clean TARGET=exp5438 -make udp-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver,SIZE=500,BUFSIZE=600 TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#2 - Receiver - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c - make clean TARGET=exp5438 -make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - - - org.contikios.cooja.interfaces.Position - 40.305234290431166 - 41.884881003965305 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - exp5438#1 - - - - - org.contikios.cooja.interfaces.Position - 65.38552901873047 - 40.93246474846026 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - exp5438#2 - - - - org.contikios.cooja.plugins.SimControl - 280 - 0 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1200 - 5 - 240 - 400 - 160 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - - - - 500.0 - - 1600 - 4 - 166 - 0 - 539 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 920 - 3 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - [CONTIKI_DIR]/regression-tests/11-ipv6/fragmentation-should-receive-none.js - true - - 618 - 1 - 399 - 645 - 128 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#1 + Sender + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.c + make clean TARGET=exp5438 +make udp-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver,SIZE=500,BUFSIZE=600 TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#2 + Receiver + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c + make clean TARGET=exp5438 +make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 40.305234290431166 + 41.884881003965305 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + exp5438#1 + + + + + org.contikios.cooja.interfaces.Position + 65.38552901873047 + 40.93246474846026 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + exp5438#2 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1200 + 5 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + + + + 500.0 + + 1600 + 4 + 166 + 0 + 539 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 920 + 3 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONTIKI_DIR]/regression-tests/11-ipv6/fragmentation-should-receive-none.js + true + + 618 + 1 + 399 + 645 + 128 + + + diff --git a/regression-tests/11-ipv6/08-exp5438-udp-fragmentation-contikimac-too-large-sender.csc b/regression-tests/11-ipv6/08-exp5438-udp-fragmentation-contikimac-too-large-sender.csc index e9b559d90..7e5dbd34c 100644 --- a/regression-tests/11-ipv6/08-exp5438-udp-fragmentation-contikimac-too-large-sender.csc +++ b/regression-tests/11-ipv6/08-exp5438-udp-fragmentation-contikimac-too-large-sender.csc @@ -1,167 +1,167 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#1 - Sender - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.c - make clean TARGET=exp5438 -make udp-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver,SIZE=500,BUFSIZE=200 TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#2 - Receiver - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c - make clean TARGET=exp5438 -make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - - - org.contikios.cooja.interfaces.Position - 40.305234290431166 - 41.884881003965305 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - exp5438#1 - - - - - org.contikios.cooja.interfaces.Position - 65.38552901873047 - 40.93246474846026 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - exp5438#2 - - - - org.contikios.cooja.plugins.SimControl - 280 - 0 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1200 - 5 - 240 - 400 - 160 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - - - - 500.0 - - 1600 - 4 - 166 - 0 - 539 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 920 - 3 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - [CONTIKI_DIR]/regression-tests/11-ipv6/fragmentation-should-receive-none.js - true - - 618 - 1 - 399 - 645 - 128 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#1 + Sender + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.c + make clean TARGET=exp5438 +make udp-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver,SIZE=500,BUFSIZE=200 TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#2 + Receiver + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c + make clean TARGET=exp5438 +make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 40.305234290431166 + 41.884881003965305 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + exp5438#1 + + + + + org.contikios.cooja.interfaces.Position + 65.38552901873047 + 40.93246474846026 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + exp5438#2 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1200 + 5 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + + + + 500.0 + + 1600 + 4 + 166 + 0 + 539 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 920 + 3 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONTIKI_DIR]/regression-tests/11-ipv6/fragmentation-should-receive-none.js + true + + 618 + 1 + 399 + 645 + 128 + + + diff --git a/regression-tests/11-ipv6/09-exp5438-udp-fragmentation-nullrdc-too-large-sender.csc b/regression-tests/11-ipv6/09-exp5438-udp-fragmentation-nullrdc-too-large-sender.csc index 88b57e8ab..61a8799ee 100644 --- a/regression-tests/11-ipv6/09-exp5438-udp-fragmentation-nullrdc-too-large-sender.csc +++ b/regression-tests/11-ipv6/09-exp5438-udp-fragmentation-nullrdc-too-large-sender.csc @@ -1,165 +1,165 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#1 - Sender - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.c - make clean TARGET=exp5438 -make udp-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver,SIZE=500,BUFSIZE=200 TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#2 - Receiver - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c - make clean TARGET=exp5438 -make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - - - org.contikios.cooja.interfaces.Position - 40.305234290431166 - 41.884881003965305 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - exp5438#1 - - - - - org.contikios.cooja.interfaces.Position - 65.38552901873047 - 40.93246474846026 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - exp5438#2 - - - - org.contikios.cooja.plugins.SimControl - 280 - 0 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - 1200 - 5 - 240 - 400 - 160 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - - - - 500.0 - - 1600 - 4 - 166 - 0 - 539 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 920 - 3 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - [CONFIG_DIR]/fragmentation-should-receive-none.js true - - 618 - 1 - 399 - 645 - 128 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#1 + Sender + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.c + make clean TARGET=exp5438 +make udp-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver,SIZE=500,BUFSIZE=200 TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/udp-sender.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#2 + Receiver + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c + make clean TARGET=exp5438 +make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 40.305234290431166 + 41.884881003965305 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + exp5438#1 + + + + + org.contikios.cooja.interfaces.Position + 65.38552901873047 + 40.93246474846026 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + exp5438#2 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + 1200 + 5 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + + + + 500.0 + + 1600 + 4 + 166 + 0 + 539 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 920 + 3 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONFIG_DIR]/fragmentation-should-receive-none.js true + + 618 + 1 + 399 + 645 + 128 + + + diff --git a/regression-tests/11-ipv6/11-exp5438-unicast-fragmentation-nullrdc.csc b/regression-tests/11-ipv6/11-exp5438-unicast-fragmentation-nullrdc.csc index 6853e8bfe..3c7160386 100644 --- a/regression-tests/11-ipv6/11-exp5438-unicast-fragmentation-nullrdc.csc +++ b/regression-tests/11-ipv6/11-exp5438-unicast-fragmentation-nullrdc.csc @@ -1,166 +1,166 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#1 - Sender - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.c - make clean TARGET=exp5438 -make unicast-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver,SIZE=400,BUFSIZE=500 TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#2 - Receiver - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c - make clean TARGET=exp5438 -make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver,SIZE=400,BUFSIZE=500 TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - - - org.contikios.cooja.interfaces.Position - 40.305234290431166 - 41.884881003965305 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - exp5438#1 - - - - - org.contikios.cooja.interfaces.Position - 65.38552901873047 - 40.93246474846026 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - exp5438#2 - - - - org.contikios.cooja.plugins.SimControl - 280 - 0 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - 1200 - 5 - 240 - 400 - 160 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - - - - 500.0 - - 1600 - 4 - 166 - 0 - 539 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 920 - 3 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - [CONFIG_DIR]/fragmentation-should-receive-all.js - true - - 618 - 1 - 399 - 645 - 128 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#1 + Sender + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.c + make clean TARGET=exp5438 +make unicast-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver,SIZE=400,BUFSIZE=500 TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#2 + Receiver + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c + make clean TARGET=exp5438 +make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver,SIZE=400,BUFSIZE=500 TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 40.305234290431166 + 41.884881003965305 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + exp5438#1 + + + + + org.contikios.cooja.interfaces.Position + 65.38552901873047 + 40.93246474846026 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + exp5438#2 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + 1200 + 5 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + + + + 500.0 + + 1600 + 4 + 166 + 0 + 539 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 920 + 3 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONFIG_DIR]/fragmentation-should-receive-all.js + true + + 618 + 1 + 399 + 645 + 128 + + + diff --git a/regression-tests/11-ipv6/12-exp5438-unicast-fragmentation-contikimac-large-sender.csc b/regression-tests/11-ipv6/12-exp5438-unicast-fragmentation-contikimac-large-sender.csc index e880804b7..5b7c2bb93 100644 --- a/regression-tests/11-ipv6/12-exp5438-unicast-fragmentation-contikimac-large-sender.csc +++ b/regression-tests/11-ipv6/12-exp5438-unicast-fragmentation-contikimac-large-sender.csc @@ -1,165 +1,165 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#1 - Sender - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.c - make clean TARGET=exp5438 -make unicast-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver,SIZE=500,BUFSIZE=600 TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#2 - Receiver - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c - make clean TARGET=exp5438 -make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - - - org.contikios.cooja.interfaces.Position - 40.305234290431166 - 41.884881003965305 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - exp5438#1 - - - - - org.contikios.cooja.interfaces.Position - 65.38552901873047 - 40.93246474846026 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - exp5438#2 - - - - org.contikios.cooja.plugins.SimControl - 280 - 0 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - 1200 - 5 - 240 - 400 - 160 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - - - - 500.0 - - 1600 - 4 - 166 - 0 - 539 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 920 - 3 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - [CONFIG_DIR]/fragmentation-should-receive-none.js true - - 618 - 1 - 399 - 645 - 128 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#1 + Sender + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.c + make clean TARGET=exp5438 +make unicast-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver,SIZE=500,BUFSIZE=600 TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#2 + Receiver + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c + make clean TARGET=exp5438 +make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 40.305234290431166 + 41.884881003965305 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + exp5438#1 + + + + + org.contikios.cooja.interfaces.Position + 65.38552901873047 + 40.93246474846026 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + exp5438#2 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + 1200 + 5 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + + + + 500.0 + + 1600 + 4 + 166 + 0 + 539 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 920 + 3 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONFIG_DIR]/fragmentation-should-receive-none.js true + + 618 + 1 + 399 + 645 + 128 + + + diff --git a/regression-tests/11-ipv6/13-exp5438-unicast-fragmentation-nullrdc-large-sender.csc b/regression-tests/11-ipv6/13-exp5438-unicast-fragmentation-nullrdc-large-sender.csc index 73ce366b6..74016cd37 100644 --- a/regression-tests/11-ipv6/13-exp5438-unicast-fragmentation-nullrdc-large-sender.csc +++ b/regression-tests/11-ipv6/13-exp5438-unicast-fragmentation-nullrdc-large-sender.csc @@ -1,166 +1,166 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#1 - Sender - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.c - make clean TARGET=exp5438 -make unicast-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver,SIZE=500,BUFSIZE=600 TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#2 - Receiver - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c - make clean TARGET=exp5438 -make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - - - org.contikios.cooja.interfaces.Position - 40.305234290431166 - 41.884881003965305 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - exp5438#1 - - - - - org.contikios.cooja.interfaces.Position - 65.38552901873047 - 40.93246474846026 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - exp5438#2 - - - - org.contikios.cooja.plugins.SimControl - 280 - 0 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - 1200 - 5 - 240 - 400 - 160 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - - - - 500.0 - - 1600 - 4 - 166 - 0 - 539 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 920 - 3 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - [CONFIG_DIR]/fragmentation-should-receive-none.js - true - - 618 - 1 - 399 - 645 - 128 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#1 + Sender + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.c + make clean TARGET=exp5438 +make unicast-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver,SIZE=500,BUFSIZE=600 TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#2 + Receiver + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c + make clean TARGET=exp5438 +make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 40.305234290431166 + 41.884881003965305 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + exp5438#1 + + + + + org.contikios.cooja.interfaces.Position + 65.38552901873047 + 40.93246474846026 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + exp5438#2 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + 1200 + 5 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + + + + 500.0 + + 1600 + 4 + 166 + 0 + 539 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 920 + 3 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONFIG_DIR]/fragmentation-should-receive-none.js + true + + 618 + 1 + 399 + 645 + 128 + + + diff --git a/regression-tests/11-ipv6/14-exp5438-unicast-fragmentation-contikimac-too-large-sender.csc b/regression-tests/11-ipv6/14-exp5438-unicast-fragmentation-contikimac-too-large-sender.csc index 3273dbfe1..35fc4e943 100644 --- a/regression-tests/11-ipv6/14-exp5438-unicast-fragmentation-contikimac-too-large-sender.csc +++ b/regression-tests/11-ipv6/14-exp5438-unicast-fragmentation-contikimac-too-large-sender.csc @@ -1,166 +1,166 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#1 - Sender - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.c - make clean TARGET=exp5438 -make unicast-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver,SIZE=500,BUFSIZE=200 TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#2 - Receiver - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c - make clean TARGET=exp5438 -make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - - - org.contikios.cooja.interfaces.Position - 40.305234290431166 - 41.884881003965305 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - exp5438#1 - - - - - org.contikios.cooja.interfaces.Position - 65.38552901873047 - 40.93246474846026 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - exp5438#2 - - - - org.contikios.cooja.plugins.SimControl - 280 - 0 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - 1200 - 5 - 240 - 400 - 160 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - - - - 500.0 - - 1600 - 4 - 166 - 0 - 539 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 920 - 3 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - [CONFIG_DIR]/fragmentation-should-receive-none.js - true - - 618 - 1 - 399 - 645 - 128 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#1 + Sender + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.c + make clean TARGET=exp5438 +make unicast-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver,SIZE=500,BUFSIZE=200 TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#2 + Receiver + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c + make clean TARGET=exp5438 +make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=contikimac_driver TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 40.305234290431166 + 41.884881003965305 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + exp5438#1 + + + + + org.contikios.cooja.interfaces.Position + 65.38552901873047 + 40.93246474846026 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + exp5438#2 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + 1200 + 5 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + + + + 500.0 + + 1600 + 4 + 166 + 0 + 539 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 920 + 3 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONFIG_DIR]/fragmentation-should-receive-none.js + true + + 618 + 1 + 399 + 645 + 128 + + + diff --git a/regression-tests/11-ipv6/15-exp5438-unicast-fragmentation-nullrdc-too-large-sender.csc b/regression-tests/11-ipv6/15-exp5438-unicast-fragmentation-nullrdc-too-large-sender.csc index 01cf79619..72fa215d2 100644 --- a/regression-tests/11-ipv6/15-exp5438-unicast-fragmentation-nullrdc-too-large-sender.csc +++ b/regression-tests/11-ipv6/15-exp5438-unicast-fragmentation-nullrdc-too-large-sender.csc @@ -1,165 +1,165 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#1 - Sender - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.c - make clean TARGET=exp5438 -make unicast-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver,SIZE=500,BUFSIZE=200 TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - org.contikios.cooja.mspmote.Exp5438MoteType - exp5438#2 - Receiver - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c - make clean TARGET=exp5438 -make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver TARGET=exp5438 - [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.UsciA1Serial - org.contikios.cooja.mspmote.interfaces.Exp5438LED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - - - - - org.contikios.cooja.interfaces.Position - 40.305234290431166 - 41.884881003965305 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - exp5438#1 - - - - - org.contikios.cooja.interfaces.Position - 65.38552901873047 - 40.93246474846026 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - exp5438#2 - - - - org.contikios.cooja.plugins.SimControl - 280 - 0 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - 1200 - 5 - 240 - 400 - 160 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - - - - 500.0 - - 1600 - 4 - 166 - 0 - 539 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 920 - 3 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - [CONFIG_DIR]/fragmentation-should-receive-none.js true - - 618 - 1 - 399 - 645 - 128 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#1 + Sender + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.c + make clean TARGET=exp5438 +make unicast-sender.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver,SIZE=500,BUFSIZE=200 TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/sender/unicast-sender.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.Exp5438MoteType + exp5438#2 + Receiver + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.c + make clean TARGET=exp5438 +make udp-receiver.exp5438 DEFINES=NETSTACK_CONF_RDC=nullrdc_driver TARGET=exp5438 + [CONTIKI_DIR]/regression-tests/11-ipv6/code/receiver/udp-receiver.exp5438 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.UsciA1Serial + org.contikios.cooja.mspmote.interfaces.Exp5438LED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 40.305234290431166 + 41.884881003965305 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + exp5438#1 + + + + + org.contikios.cooja.interfaces.Position + 65.38552901873047 + 40.93246474846026 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + exp5438#2 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 6.299766478490424 0.0 0.0 6.299766478490424 -160.913563890561 -119.86496930434095 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + 1200 + 5 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + + + + 500.0 + + 1600 + 4 + 166 + 0 + 539 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 920 + 3 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONFIG_DIR]/fragmentation-should-receive-none.js true + + 618 + 1 + 399 + 645 + 128 + + + diff --git a/regression-tests/11-ipv6/16-sky-ipv6-rpl-collect.csc b/regression-tests/11-ipv6/16-sky-ipv6-rpl-collect.csc index 9b76c6739..2d1e947c4 100644 --- a/regression-tests/11-ipv6/16-sky-ipv6-rpl-collect.csc +++ b/regression-tests/11-ipv6/16-sky-ipv6-rpl-collect.csc @@ -1,623 +1,623 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 100.0 - 0.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Sky Mote Type #sky1 - [CONTIKI_DIR]/examples/ipv6/rpl-collect/udp-sink.c - make udp-sink.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-collect/udp-sink.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - sky2 - Sky Mote Type #sky2 - [CONTIKI_DIR]/examples/ipv6/rpl-collect/udp-sender.c - make udp-sender.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-collect/udp-sender.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 242.83184008074136 - -88.93434685786869 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 223.5175954004352 - -69.05842098947238 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 250.51864863077387 - -59.2420165357677 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 294.4736028715864 - -63.23792146675066 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 188.6638305152632 - -41.28432709660093 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 222.54731411389315 - -32.869043991280165 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 273.694897230475 - -29.672320046493798 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 7 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 321.64575640227054 - -33.66822497747676 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 8 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 159.4120162043624 - -2.500166515809672 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 9 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 196.97352255560222 - -0.10262355721989598 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 10 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 252.91619158936365 - 1.495738415173288 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 11 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 301.66623174735577 - -0.10262355721989598 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 12 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 346.4203669743649 - 1.495738415173288 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 13 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 124.24805281171236 - 22.27444405628468 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 14 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 180.1907218454738 - 35.86052082162674 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 15 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 224.14567608628633 - 30.266253918250598 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 16 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 276.0924401890648 - 35.86052082162674 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 17 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 351.2154528915445 - 37.45888279401993 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 18 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 89.08408941906231 - 47.04905462837903 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 19 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 180.1907218454738 - 75.02038914525976 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 20 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 245.7235627135943 - 66.22939829709723 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 21 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 290.4776979406035 - 67.82776026949043 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 22 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 370.3957965602627 - 64.63103632470406 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 23 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 93.07999435004527 - 82.21301802102909 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 24 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 204.16615143137156 - 106.18844760692684 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 25 - - sky2 - - - - org.contikios.cooja.plugins.SimControl - 259 - 3 - 184 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.AttributeVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 1.836243522352668 0.0 0.0 1.836243522352668 -93.43273668589363 192.8080782058222 - - 666 - 4 - 510 - 764 - 5 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1347 - 2 - 150 - 0 - 438 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 - 22 - 23 - 24 - - 52818.041078329756 - - 1347 - 1 - 233 - 0 - 588 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - 0 - 700 - 416 - 8 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 100.0 + 0.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Sky Mote Type #sky1 + [CONTIKI_DIR]/examples/ipv6/rpl-collect/udp-sink.c + make udp-sink.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-collect/udp-sink.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + sky2 + Sky Mote Type #sky2 + [CONTIKI_DIR]/examples/ipv6/rpl-collect/udp-sender.c + make udp-sender.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-collect/udp-sender.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 242.83184008074136 + -88.93434685786869 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 223.5175954004352 + -69.05842098947238 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 250.51864863077387 + -59.2420165357677 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 294.4736028715864 + -63.23792146675066 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 188.6638305152632 + -41.28432709660093 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 222.54731411389315 + -32.869043991280165 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 273.694897230475 + -29.672320046493798 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 321.64575640227054 + -33.66822497747676 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 159.4120162043624 + -2.500166515809672 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 196.97352255560222 + -0.10262355721989598 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 252.91619158936365 + 1.495738415173288 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 11 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 301.66623174735577 + -0.10262355721989598 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 12 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 346.4203669743649 + 1.495738415173288 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 13 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 124.24805281171236 + 22.27444405628468 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 14 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 180.1907218454738 + 35.86052082162674 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 15 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 224.14567608628633 + 30.266253918250598 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 16 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 276.0924401890648 + 35.86052082162674 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 17 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 351.2154528915445 + 37.45888279401993 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 18 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 89.08408941906231 + 47.04905462837903 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 19 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 180.1907218454738 + 75.02038914525976 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 20 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 245.7235627135943 + 66.22939829709723 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 21 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 290.4776979406035 + 67.82776026949043 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 22 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 370.3957965602627 + 64.63103632470406 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 23 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 93.07999435004527 + 82.21301802102909 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 24 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 204.16615143137156 + 106.18844760692684 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 25 + + sky2 + + + + org.contikios.cooja.plugins.SimControl + 259 + 3 + 184 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 1.836243522352668 0.0 0.0 1.836243522352668 -93.43273668589363 192.8080782058222 + + 666 + 4 + 510 + 764 + 5 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1347 + 2 + 150 + 0 + 438 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + + 52818.041078329756 + + 1347 + 1 + 233 + 0 + 588 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 0 + 700 + 416 + 8 + + + diff --git a/regression-tests/11-ipv6/17-cooja-multicast-11-hops.csc b/regression-tests/11-ipv6/17-cooja-multicast-11-hops.csc index da90cb72b..111beb9a1 100644 --- a/regression-tests/11-ipv6/17-cooja-multicast-11-hops.csc +++ b/regression-tests/11-ipv6/17-cooja-multicast-11-hops.csc @@ -1,367 +1,367 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - Multicast regression test - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 15.0 - 0.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype612 - Root/sender - [CONTIKI_DIR]/examples/ipv6/multicast/root.c - make root.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype890 - Intermediate - [CONTIKI_DIR]/examples/ipv6/multicast/intermediate.c - make intermediate.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype956 - Receiver - [CONTIKI_DIR]/examples/ipv6/multicast/sink.c - make sink.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - -7.983976888750106 - 0.37523218201044733 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype612 - - - - org.contikios.cooja.interfaces.Position - 0.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype890 - - - - org.contikios.cooja.interfaces.Position - 10.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype890 - - - - org.contikios.cooja.interfaces.Position - 20.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 4 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype890 - - - - org.contikios.cooja.interfaces.Position - 30.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 5 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype890 - - - - org.contikios.cooja.interfaces.Position - 40.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype890 - - - - org.contikios.cooja.interfaces.Position - 50.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 7 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype890 - - - - org.contikios.cooja.interfaces.Position - 60.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype890 - - - - org.contikios.cooja.interfaces.Position - 70.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 9 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype890 - - - - org.contikios.cooja.interfaces.Position - 79.93950307524713 - -0.043451055913349 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 10 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype890 - - - - org.contikios.cooja.interfaces.Position - 90.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 11 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype890 - - - - org.contikios.cooja.interfaces.Position - 99.61761525766555 - 0.37523218201044733 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 12 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype956 - - - - org.contikios.cooja.plugins.SimControl - 280 - 1 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - true - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.TrafficVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 2.388440494916608 0.0 0.0 2.388440494916608 109.06925371156906 149.10378026149033 - - 400 - 3 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1200 - 2 - 240 - 400 - 160 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 920 - 4 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - 0 - 700 - 843 - 77 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + Multicast regression test + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 15.0 + 0.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype612 + Root/sender + [CONTIKI_DIR]/examples/ipv6/multicast/root.c + make root.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype890 + Intermediate + [CONTIKI_DIR]/examples/ipv6/multicast/intermediate.c + make intermediate.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype956 + Receiver + [CONTIKI_DIR]/examples/ipv6/multicast/sink.c + make sink.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.983976888750106 + 0.37523218201044733 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype612 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype890 + + + + org.contikios.cooja.interfaces.Position + 10.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype890 + + + + org.contikios.cooja.interfaces.Position + 20.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype890 + + + + org.contikios.cooja.interfaces.Position + 30.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype890 + + + + org.contikios.cooja.interfaces.Position + 40.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype890 + + + + org.contikios.cooja.interfaces.Position + 50.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype890 + + + + org.contikios.cooja.interfaces.Position + 60.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype890 + + + + org.contikios.cooja.interfaces.Position + 70.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 9 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype890 + + + + org.contikios.cooja.interfaces.Position + 79.93950307524713 + -0.043451055913349 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 10 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype890 + + + + org.contikios.cooja.interfaces.Position + 90.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 11 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype890 + + + + org.contikios.cooja.interfaces.Position + 99.61761525766555 + 0.37523218201044733 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 12 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype956 + + + + org.contikios.cooja.plugins.SimControl + 280 + 1 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.388440494916608 0.0 0.0 2.388440494916608 109.06925371156906 149.10378026149033 + + 400 + 3 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1200 + 2 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 920 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 0 + 700 + 843 + 77 + + + diff --git a/regression-tests/11-ipv6/18-cooja-multicast-31-hops.csc b/regression-tests/11-ipv6/18-cooja-multicast-31-hops.csc index c1aea4df0..27321d624 100644 --- a/regression-tests/11-ipv6/18-cooja-multicast-31-hops.csc +++ b/regression-tests/11-ipv6/18-cooja-multicast-31-hops.csc @@ -1,707 +1,707 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - Multicast regression test - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 15.0 - 0.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype816 - Root/sender - [CONTIKI_DIR]/examples/ipv6/multicast/root.c - make root.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype53 - Intermediate - [CONTIKI_DIR]/examples/ipv6/multicast/intermediate.c - make intermediate.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype191 - Receiver - [CONTIKI_DIR]/examples/ipv6/multicast/sink.c - make sink.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - -7.983976888750106 - 0.37523218201044733 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype816 - - - - org.contikios.cooja.interfaces.Position - 0.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 10.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 20.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 4 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 30.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 5 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 40.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 50.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 7 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 60.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 70.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 9 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 79.93950307524713 - -0.043451055913349 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 10 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 90.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 11 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 299.830399237567 - 0.21169609213234786 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 12 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype191 - - - - org.contikios.cooja.interfaces.Position - 100.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 13 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 110.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 14 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 120.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 15 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 130.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 16 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 140.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 17 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 150.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 18 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 160.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 19 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 170.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 20 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 180.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 21 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 190.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 22 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 200.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 23 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 210.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 24 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 220.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 25 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 230.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 26 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 240.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 27 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 250.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 28 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 260.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 29 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 270.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 30 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 280.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 31 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.interfaces.Position - 290.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 32 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype53 - - - - org.contikios.cooja.plugins.SimControl - 280 - 1 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - true - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.TrafficVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 1.1837122130192945 0.0 0.0 1.1837122130192945 27.087094588040927 150.74941275029448 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1200 - 3 - 240 - 400 - 160 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 920 - 4 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - 0 - 700 - 843 - 77 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + Multicast regression test + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 15.0 + 0.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype816 + Root/sender + [CONTIKI_DIR]/examples/ipv6/multicast/root.c + make root.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype53 + Intermediate + [CONTIKI_DIR]/examples/ipv6/multicast/intermediate.c + make intermediate.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype191 + Receiver + [CONTIKI_DIR]/examples/ipv6/multicast/sink.c + make sink.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.983976888750106 + 0.37523218201044733 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype816 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 10.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 20.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 30.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 40.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 50.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 60.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 70.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 9 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 79.93950307524713 + -0.043451055913349 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 10 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 90.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 11 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 299.830399237567 + 0.21169609213234786 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 12 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype191 + + + + org.contikios.cooja.interfaces.Position + 100.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 13 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 110.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 14 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 120.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 15 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 130.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 16 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 140.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 17 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 150.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 18 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 160.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 19 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 170.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 20 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 180.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 21 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 190.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 22 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 200.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 23 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 210.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 24 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 220.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 25 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 230.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 26 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 240.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 27 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 250.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 28 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 260.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 29 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 270.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 30 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 280.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 31 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.interfaces.Position + 290.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 32 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype53 + + + + org.contikios.cooja.plugins.SimControl + 280 + 1 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 1.1837122130192945 0.0 0.0 1.1837122130192945 27.087094588040927 150.74941275029448 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1200 + 3 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 920 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 0 + 700 + 843 + 77 + + + diff --git a/regression-tests/11-ipv6/19-z1-rpl-tsch.csc b/regression-tests/11-ipv6/19-z1-rpl-tsch.csc new file mode 100644 index 000000000..7488e8c3b --- /dev/null +++ b/regression-tests/11-ipv6/19-z1-rpl-tsch.csc @@ -0,0 +1,288 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + RPL+TSCH + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Z1MoteType + z11 + Z1 Mote Type #z11 + [CONTIKI_DIR]/examples/ipv6/rpl-tsch/node.c + make TARGET=z1 clean +make node.z1 TARGET=z1 MAKE_WITH_ORCHESTRA=0 MAKE_WITH_SECURITY=0 + [CONTIKI_DIR]/examples/ipv6/rpl-tsch/node.z1 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + -1.285769821276336 + 38.58045647334346 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + z11 + + + + + org.contikios.cooja.interfaces.Position + -19.324109516886306 + 76.23135780254927 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 5.815501305791592 + 76.77463755494317 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 31.920697784030082 + 50.5212265977149 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 47.21747673247198 + 30.217765340599726 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 10.622284947035123 + 109.81862399725188 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 52.41150716335335 + 109.93228340481916 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 70.18727461718498 + 70.06861701541145 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 80.29870484201041 + 99.37351603835938 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + z11 + + + + org.contikios.cooja.plugins.SimControl + 242 + 4 + 160 + 11 + 241 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 1.7405603810040515 0.0 0.0 1.7405603810040515 47.95980153208088 -42.576134155447555 + + 236 + 3 + 230 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + ID:1 + + + + 1031 + 0 + 394 + 273 + 6 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + + + + 16529.88882215865 + + 1304 + 2 + 311 + 0 + 412 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 764 + 1 + 995 + 963 + 111 + + + diff --git a/regression-tests/11-ipv6/20-z1-rpl-tsch-orchestra.csc b/regression-tests/11-ipv6/20-z1-rpl-tsch-orchestra.csc new file mode 100644 index 000000000..3fecd2040 --- /dev/null +++ b/regression-tests/11-ipv6/20-z1-rpl-tsch-orchestra.csc @@ -0,0 +1,293 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + RPL+TSCH+Orchestrsa + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Z1MoteType + z11 + Z1 Mote Type #z11 + [CONTIKI_DIR]/examples/ipv6/rpl-tsch/node.c + make TARGET=z1 clean +make node.z1 TARGET=z1 MAKE_WITH_ORCHESTRA=1 MAKE_WITH_SECURITY=0 + [CONTIKI_DIR]/examples/ipv6/rpl-tsch/node.z1 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + -1.285769821276336 + 38.58045647334346 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + z11 + + + + + org.contikios.cooja.interfaces.Position + -19.324109516886306 + 76.23135780254927 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 5.815501305791592 + 76.77463755494317 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 31.920697784030082 + 50.5212265977149 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 47.21747673247198 + 30.217765340599726 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 10.622284947035123 + 109.81862399725188 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 52.41150716335335 + 109.93228340481916 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 70.18727461718498 + 70.06861701541145 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 80.29870484201041 + 99.37351603835938 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + z11 + + + + org.contikios.cooja.plugins.SimControl + 242 + 4 + 160 + 11 + 241 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 1.7405603810040515 0.0 0.0 1.7405603810040515 47.95980153208088 -42.576134155447555 + + 236 + 3 + 230 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + ID:1 + + + + 1031 + 0 + 394 + 273 + 6 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + + + + 16529.88882215865 + + 1304 + 2 + 311 + 0 + 412 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 764 + 1 + 995 + 963 + 111 + + + diff --git a/regression-tests/11-ipv6/21-z1-rpl-tsch-security.csc b/regression-tests/11-ipv6/21-z1-rpl-tsch-security.csc new file mode 100644 index 000000000..e2cda7e44 --- /dev/null +++ b/regression-tests/11-ipv6/21-z1-rpl-tsch-security.csc @@ -0,0 +1,290 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + RPL+TSCH+Security + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.Z1MoteType + z11 + Z1 Mote Type #z11 + [CONTIKI_DIR]/examples/ipv6/rpl-tsch/node.c + make TARGET=z1 clean +make node.z1 TARGET=z1 MAKE_WITH_ORCHESTRA=0 MAKE_WITH_SECURITY=1 + [CONTIKI_DIR]/examples/ipv6/rpl-tsch/node.z1 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + -1.285769821276336 + 38.58045647334346 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + z11 + + + + + org.contikios.cooja.interfaces.Position + -19.324109516886306 + 76.23135780254927 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 5.815501305791592 + 76.77463755494317 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 31.920697784030082 + 50.5212265977149 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 47.21747673247198 + 30.217765340599726 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 10.622284947035123 + 109.81862399725188 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 52.41150716335335 + 109.93228340481916 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 70.18727461718498 + 70.06861701541145 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + z11 + + + + + org.contikios.cooja.interfaces.Position + 80.29870484201041 + 99.37351603835938 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + z11 + + + + org.contikios.cooja.plugins.SimControl + 242 + 4 + 160 + 11 + 241 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 1.7405603810040515 0.0 0.0 1.7405603810040515 47.95980153208088 -42.576134155447555 + + 236 + 3 + 230 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + ID:1 + + + + 1031 + 0 + 394 + 273 + 6 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + + + + 16529.88882215865 + + 1304 + 2 + 311 + 0 + 412 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 764 + 1 + 995 + 963 + 111 + + + diff --git a/regression-tests/11-ipv6/code/receiver/Makefile b/regression-tests/11-ipv6/code/receiver/Makefile index 0decf131d..7288d10ef 100644 --- a/regression-tests/11-ipv6/code/receiver/Makefile +++ b/regression-tests/11-ipv6/code/receiver/Makefile @@ -1,6 +1,6 @@ CONTIKI=../../../.. -UIP_CONF_IPV6=1 -CFLAGS+= -DUIP_CONF_IPV6_RPL -DPROJECT_CONF_H=\"project-conf.h\" +CFLAGS+= -DPROJECT_CONF_H=\"project-conf.h\" +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/regression-tests/11-ipv6/code/receiver/project-conf.h b/regression-tests/11-ipv6/code/receiver/project-conf.h index 877ed0ac4..17a25e129 100644 --- a/regression-tests/11-ipv6/code/receiver/project-conf.h +++ b/regression-tests/11-ipv6/code/receiver/project-conf.h @@ -1,4 +1,5 @@ - +#undef UIP_CONF_ND6_SEND_NA +#define UIP_CONF_ND6_SEND_NA 1 #ifdef BUFSIZE #undef UIP_CONF_BUFFER_SIZE diff --git a/regression-tests/11-ipv6/code/receiver/udp-receiver.c b/regression-tests/11-ipv6/code/receiver/udp-receiver.c index 564c2672e..e84c57637 100644 --- a/regression-tests/11-ipv6/code/receiver/udp-receiver.c +++ b/regression-tests/11-ipv6/code/receiver/udp-receiver.c @@ -39,7 +39,7 @@ PROCESS_THREAD(udp_process, ev, data) PROCESS_BEGIN(); - uip_ip6addr(&addr, 0xaaaa, 0, 0, 0, 0, 0, 0, 2); + uip_ip6addr(&addr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 2); uip_ds6_addr_add(&addr, 0, ADDR_AUTOCONF); simple_udp_register(&broadcast_connection, UDP_PORT, diff --git a/regression-tests/11-ipv6/code/sender/Makefile b/regression-tests/11-ipv6/code/sender/Makefile index 0decf131d..7288d10ef 100644 --- a/regression-tests/11-ipv6/code/sender/Makefile +++ b/regression-tests/11-ipv6/code/sender/Makefile @@ -1,6 +1,6 @@ CONTIKI=../../../.. -UIP_CONF_IPV6=1 -CFLAGS+= -DUIP_CONF_IPV6_RPL -DPROJECT_CONF_H=\"project-conf.h\" +CFLAGS+= -DPROJECT_CONF_H=\"project-conf.h\" +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/regression-tests/11-ipv6/code/sender/project-conf.h b/regression-tests/11-ipv6/code/sender/project-conf.h index 877ed0ac4..17a25e129 100644 --- a/regression-tests/11-ipv6/code/sender/project-conf.h +++ b/regression-tests/11-ipv6/code/sender/project-conf.h @@ -1,4 +1,5 @@ - +#undef UIP_CONF_ND6_SEND_NA +#define UIP_CONF_ND6_SEND_NA 1 #ifdef BUFSIZE #undef UIP_CONF_BUFFER_SIZE diff --git a/regression-tests/11-ipv6/code/sender/unicast-sender.c b/regression-tests/11-ipv6/code/sender/unicast-sender.c index 071e3ac37..10a139986 100644 --- a/regression-tests/11-ipv6/code/sender/unicast-sender.c +++ b/regression-tests/11-ipv6/code/sender/unicast-sender.c @@ -40,12 +40,12 @@ PROCESS_THREAD(udp_process, ev, data) PROCESS_BEGIN(); - uip_ip6addr(&addr, 0xaaaa, 0, 0, 0, 0, 0, 0, 3); + uip_ip6addr(&addr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 3); uip_ds6_addr_add(&addr, 0, ADDR_AUTOCONF); rpl_set_root(RPL_DEFAULT_INSTANCE, &addr); /* dag = rpl_get_any_dag(); - uip_ip6addr(&prefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); rpl_set_prefix(dag, &prefix, 64);*/ @@ -63,7 +63,7 @@ PROCESS_THREAD(udp_process, ev, data) etimer_reset(&periodic_timer); printf("Sending unicast\n"); - uip_ip6addr(&addr, 0xaaaa, 0, 0, 0, 0, 0, 0, 2); + uip_ip6addr(&addr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 2); simple_udp_sendto(&broadcast_connection, buf, sizeof(buf), &addr); } diff --git a/regression-tests/11-ipv6/x03-sky-ipv6-udp-fragmentation.csc b/regression-tests/11-ipv6/x03-sky-ipv6-udp-fragmentation.csc index f035a84cf..f3c99664e 100644 --- a/regression-tests/11-ipv6/x03-sky-ipv6-udp-fragmentation.csc +++ b/regression-tests/11-ipv6/x03-sky-ipv6-udp-fragmentation.csc @@ -1,179 +1,179 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - generated - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - UDP client - [CONTIKI_DIR]/examples/udp-ipv6/udp-client.c - make clean TARGET=sky -make udp-client.sky TARGET=sky DEFINES=UDP_CONNECTION_ADDR=fe80::212:7402:2:202,SICSLOWPAN_CONF_FRAG=1,SEND_TOO_LARGE_PACKET_TO_TEST_FRAGMENTATION=1 - [CONTIKI_DIR]/examples/udp-ipv6/udp-client.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - sky2 - UDP server - [CONTIKI_DIR]/examples/udp-ipv6/udp-server.c - make udp-server.sky TARGET=sky DEFINES=SICSLOWPAN_CONF_FRAG=1 - [CONTIKI_DIR]/examples/udp-ipv6/udp-server.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 56.49442624080769 - 69.16564756567392 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 70.13661699393737 - 61.114518596613784 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky2 - - - - org.contikios.cooja.plugins.SimControl - 248 - 0 - 200 - 0 - 0 - - - org.contikios.cooja.plugins.LogListener - - - - - - 683 - 2 - 550 - 12 - 417 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.AddressVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 6.1185311939665725 0.0 0.0 6.1185311939665725 -264.82328143448046 -341.0405575126179 - - 250 - 3 - 183 - 6 - 214 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 572 - 1 - 552 - 704 - 417 - - - org.contikios.cooja.plugins.RadioLogger - - 183 - - false - false - - - 1008 - 4 - 406 - 261 - 7 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + UDP client + [CONTIKI_DIR]/examples/udp-ipv6/udp-client.c + make clean TARGET=sky +make udp-client.sky TARGET=sky DEFINES=UDP_CONNECTION_ADDR=fe80::212:7402:2:202,SICSLOWPAN_CONF_FRAG=1,SEND_TOO_LARGE_PACKET_TO_TEST_FRAGMENTATION=1 + [CONTIKI_DIR]/examples/udp-ipv6/udp-client.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + sky2 + UDP server + [CONTIKI_DIR]/examples/udp-ipv6/udp-server.c + make udp-server.sky TARGET=sky DEFINES=SICSLOWPAN_CONF_FRAG=1 + [CONTIKI_DIR]/examples/udp-ipv6/udp-server.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 56.49442624080769 + 69.16564756567392 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 70.13661699393737 + 61.114518596613784 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky2 + + + + org.contikios.cooja.plugins.SimControl + 248 + 0 + 200 + 0 + 0 + + + org.contikios.cooja.plugins.LogListener + + + + + + 683 + 2 + 550 + 12 + 417 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.AddressVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 6.1185311939665725 0.0 0.0 6.1185311939665725 -264.82328143448046 -341.0405575126179 + + 250 + 3 + 183 + 6 + 214 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 572 + 1 + 552 + 704 + 417 + + + org.contikios.cooja.plugins.RadioLogger + + 183 + + false + false + + + 1008 + 4 + 406 + 261 + 7 + + + diff --git a/regression-tests/12-rpl/01-rpl-up-route.csc b/regression-tests/12-rpl/01-rpl-up-route.csc index 7c515b24b..da4743d44 100644 --- a/regression-tests/12-rpl/01-rpl-up-route.csc +++ b/regression-tests/12-rpl/01-rpl-up-route.csc @@ -1,346 +1,344 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype488 - Sender - [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c - make TARGET=cooja clean -make sender-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype32 - RPL root - [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c - make TARGET=cooja clean -make root-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype352 - Receiver - [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c - make TARGET=cooja clean -make receiver-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - 6.9596575829049145 - -25.866060090958513 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype352 - - - - org.contikios.cooja.interfaces.Position - 132.8019872469463 - 146.1533406452311 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype488 - - - - org.contikios.cooja.interfaces.Position - 0.026556260457749753 - 39.54055615854325 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 4 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype352 - - - - org.contikios.cooja.interfaces.Position - 95.52021598473031 - 148.11553913271615 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 5 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype352 - - - - org.contikios.cooja.interfaces.Position - 62.81690785997944 - 127.1854219328756 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype352 - - - - org.contikios.cooja.interfaces.Position - 32.07579822271361 - 102.33090775806494 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 7 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype352 - - - - org.contikios.cooja.interfaces.Position - 5.913151722912886 - 73.55199660828417 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype352 - - - - org.contikios.cooja.interfaces.Position - 0.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype32 - - - - org.contikios.cooja.plugins.SimControl - 280 - 2 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 0.9555608221893928 0.0 0.0 0.9555608221893928 177.34962387792274 139.71659364731656 - - 400 - 1 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1184 - 3 - 240 - 402 - 162 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 904 - 4 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 962 - 0 - 596 - 603 - 43 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype488 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make TARGET=cooja clean +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype32 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make TARGET=cooja clean +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype352 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make TARGET=cooja clean +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 6.9596575829049145 + -25.866060090958513 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype352 + + + + org.contikios.cooja.interfaces.Position + 132.8019872469463 + 146.1533406452311 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype488 + + + + org.contikios.cooja.interfaces.Position + 0.026556260457749753 + 39.54055615854325 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype352 + + + + org.contikios.cooja.interfaces.Position + 95.52021598473031 + 148.11553913271615 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype352 + + + + org.contikios.cooja.interfaces.Position + 62.81690785997944 + 127.1854219328756 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype352 + + + + org.contikios.cooja.interfaces.Position + 32.07579822271361 + 102.33090775806494 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype352 + + + + org.contikios.cooja.interfaces.Position + 5.913151722912886 + 73.55199660828417 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype352 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype32 + + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 0.9555608221893928 0.0 0.0 0.9555608221893928 177.34962387792274 139.71659364731656 + + 400 + 1 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 3 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 0 + 596 + 603 + 43 + + + diff --git a/regression-tests/12-rpl/02-rpl-root-reboot.csc b/regression-tests/12-rpl/02-rpl-root-reboot.csc index eda75d60b..6c4ce9d28 100644 --- a/regression-tests/12-rpl/02-rpl-root-reboot.csc +++ b/regression-tests/12-rpl/02-rpl-root-reboot.csc @@ -1,346 +1,344 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype958 - Sender - [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c - make TARGET=cooja clean -make sender-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype837 - RPL root - [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c - make TARGET=cooja clean -make root-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype358 - Receiver - [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c - make TARGET=cooja clean -make receiver-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - -22.5728586847096 - 123.9358664968653 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype358 - - - - org.contikios.cooja.interfaces.Position - 116.13379149678028 - 88.36698920455684 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype958 - - - - org.contikios.cooja.interfaces.Position - -1.39303771455413 - 100.21446701029119 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 4 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype358 - - - - org.contikios.cooja.interfaces.Position - 95.25095618820441 - 63.14998053005015 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 5 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype358 - - - - org.contikios.cooja.interfaces.Position - 66.09378990830604 - 38.32698761608261 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype358 - - - - org.contikios.cooja.interfaces.Position - 29.05630841762433 - 30.840688165838436 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 7 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype358 - - - - org.contikios.cooja.interfaces.Position - 10.931583432822638 - 69.848248459216 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype358 - - - - org.contikios.cooja.interfaces.Position - 0.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype837 - - - - org.contikios.cooja.plugins.SimControl - 280 - 0 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1184 - 3 - 240 - 402 - 162 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 904 - 4 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 962 - 1 - 596 - 603 - 43 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype958 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make TARGET=cooja clean +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype837 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make TARGET=cooja clean +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype358 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make TARGET=cooja clean +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -22.5728586847096 + 123.9358664968653 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype958 + + + + org.contikios.cooja.interfaces.Position + -1.39303771455413 + 100.21446701029119 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 10.931583432822638 + 69.848248459216 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype837 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 3 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 1 + 596 + 603 + 43 + + + diff --git a/regression-tests/12-rpl/03-rpl-28-hours.csc b/regression-tests/12-rpl/03-rpl-28-hours.csc index d107f13b4..3ebc7adda 100644 --- a/regression-tests/12-rpl/03-rpl-28-hours.csc +++ b/regression-tests/12-rpl/03-rpl-28-hours.csc @@ -1,295 +1,293 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype110 - Sender - [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c - make TARGET=cooja clean -make sender-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype792 - RPL root - [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c - make TARGET=cooja clean -make root-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype964 - Receiver - [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c - make TARGET=cooja clean -make receiver-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - 7.772906112657773 - 86.396910401861 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype964 - - - - org.contikios.cooja.interfaces.Position - 75.54361692539452 - 14.292026223193414 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype110 - - - - org.contikios.cooja.interfaces.Position - 47.962513687652844 - 7.199742533488408 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype964 - - - - org.contikios.cooja.interfaces.Position - 1.8626697045702818 - 47.783365869022624 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype964 - - - - org.contikios.cooja.interfaces.Position - 0.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype792 - - - - org.contikios.cooja.plugins.SimControl - 280 - 0 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 2.5379695437350276 0.0 0.0 2.5379695437350276 78.27260101976275 40.72727272727276 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1184 - 3 - 240 - 402 - 162 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 904 - 4 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 962 - 1 - 596 - 603 - 43 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype110 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make TARGET=cooja clean +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype792 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make TARGET=cooja clean +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype964 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make TARGET=cooja clean +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 7.772906112657773 + 86.396910401861 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype964 + + + + org.contikios.cooja.interfaces.Position + 75.54361692539452 + 14.292026223193414 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype110 + + + + org.contikios.cooja.interfaces.Position + 47.962513687652844 + 7.199742533488408 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype964 + + + + org.contikios.cooja.interfaces.Position + 1.8626697045702818 + 47.783365869022624 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype964 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype792 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 78.27260101976275 40.72727272727276 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 3 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 1 + 596 + 603 + 43 + + + diff --git a/regression-tests/12-rpl/04-rpl-large-network.csc b/regression-tests/12-rpl/04-rpl-large-network.csc index 50b1cfad4..f4ea0fda8 100644 --- a/regression-tests/12-rpl/04-rpl-large-network.csc +++ b/regression-tests/12-rpl/04-rpl-large-network.csc @@ -1,7061 +1,7058 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype710 - Sender - [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c - make TARGET=cooja clean -make sender-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype709 - RPL root - [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c - make TARGET=cooja clean -make root-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype332 - Receiver - [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c - make TARGET=cooja clean -make receiver-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - -15.604889524290883 - -27.272920930192623 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 218.29521040499824 - 216.70287561143516 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype710 - - - - org.contikios.cooja.interfaces.Position - 0.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype709 - - - - org.contikios.cooja.interfaces.Position - 27.44274795318258 - 36.980443988209856 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 4 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 185.6055859234863 - 192.99166984979271 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 5 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 7.827315175624361 - 107.95833747378225 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 82.49199862549197 - 34.72851022020231 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 7 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 35.671428723363064 - 125.82590119075962 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 33.044376889885754 - 62.443378727185774 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 9 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 152.53659733643553 - 165.87608708149403 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 10 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 22.023077232445942 - 18.41094139254531 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 11 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 41.19368867821842 - 49.201157808285224 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 12 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 114.62128502432532 - 88.58807114217633 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 13 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 61.21405469314478 - 188.6851979777661 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 14 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 104.78326932115709 - 100.84889281105585 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 15 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 90.26861048950052 - 40.550864496421404 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 16 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 137.39112328314076 - 126.5333637365394 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 17 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 14.07616766247768 - 99.85572366133869 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 18 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 192.30563307960443 - 66.83563821262344 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 19 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 129.08253247651874 - 117.20437669309078 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 20 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 21.82717410659969 - 47.523771402541335 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 21 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 35.95102103988239 - 21.74677482276881 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 22 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 61.71108896268191 - 79.91617509627334 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 23 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 16.029809485043288 - 171.05935835280616 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 24 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 138.8418552766128 - 61.418703448852185 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 25 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 151.23299942414673 - 92.41820871538522 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 26 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 197.33157775573343 - 20.6013482653864 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 27 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 121.20762229879878 - 184.81107462083565 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 28 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 102.32432527534694 - 91.9912435435037 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 29 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 88.10909646999544 - 191.21251904898142 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 30 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 72.19774934085703 - 113.58131529956069 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 31 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 53.49967737007204 - 72.45172156882643 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 32 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 172.07186411958625 - 51.47715718716961 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 33 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 185.41983532466634 - 85.60078269414 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 34 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 83.34993971740548 - 193.98111239532744 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 35 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 105.03752362550378 - 131.24078026424087 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 36 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 176.09318670322102 - 41.46760901468247 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 37 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 76.80689915307215 - 47.13815728542057 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 38 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 155.907739287817 - 15.24009422994106 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 39 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 45.992463430523436 - 124.573811024683 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 40 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 159.11361032671832 - 81.65319598335425 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 41 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 41.838657583001314 - 163.47591213471193 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 42 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 25.560001904073125 - 147.48610852243928 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 43 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 139.56489350213488 - 191.15379557180913 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 44 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 105.71342550700061 - 136.09089690661503 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 45 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 122.59378462201298 - 196.22862961645998 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 46 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 147.61372446125088 - 55.314287700435536 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 47 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 77.70218628780312 - 95.59561907133107 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 48 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 71.88244578562713 - 168.57963926907163 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 49 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 6.722298767036894 - 101.09668965729898 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 50 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 62.96680217979964 - 77.66951408660954 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 51 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 162.49011735601982 - 199.07086470932003 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 52 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 87.87526390617558 - 114.39424478293958 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 53 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 74.29230372180815 - 36.995699473573836 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 54 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 77.34619341407321 - 60.070446577058576 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 55 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 76.32695571818826 - 135.82669004433725 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 56 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 68.10326013650814 - 5.04157445893032 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 57 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 95.76993029214962 - 45.046282401332945 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 58 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 79.87963205080952 - 110.7023948653882 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 59 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 195.90349780899223 - 132.38904172009444 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 60 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 80.40108440304007 - 25.86673418569547 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 61 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 52.268877618080744 - 176.12888723955277 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 62 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 40.545541404899765 - 166.9450252729589 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 63 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 10.676184465528205 - 0.9871174057552334 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 64 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 87.35673216830257 - 23.25131234780027 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 65 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 26.745126931691352 - 87.3101256645554 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 66 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 183.2724008541638 - 167.69026002459069 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 67 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 5.934720840855223 - 77.21248812623693 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 68 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 76.49604470599058 - 108.80963795015302 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 69 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 86.10145414955488 - 12.798582653303603 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 70 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 32.435370110193816 - 29.344591306898813 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 71 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 163.72950518161596 - 154.15283820759655 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 72 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 143.96396308843373 - 132.40312602892786 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 73 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 139.20530179839795 - 144.18958011498225 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 74 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 75.22453368236212 - 119.69913560274786 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 75 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 21.83836116635087 - 191.21696522067728 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 76 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 187.94640511976667 - 113.95684826994561 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 77 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 114.61289565250618 - 27.61001303446735 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 78 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 70.83569869750504 - 113.88992677636021 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 79 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 11.616059362048992 - 45.59401384110464 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 80 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 3.4282454263252937 - 35.97653370545284 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 81 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 54.33122057405715 - 1.9759087814547494 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 82 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 69.6612091444155 - 0.45982758130533874 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 83 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 169.98417155202168 - 87.76678058442593 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 84 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 148.98441194234616 - 104.32820155415494 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 85 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 66.23883124891583 - 162.92685536074129 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 86 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 181.6348837921769 - 183.07267240808343 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 87 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 88.9829570206748 - 119.72520333459575 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 88 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 179.1527012143494 - 84.25685075020328 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 89 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 117.82537007493707 - 41.10319533518651 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 90 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 52.611633540398486 - 94.71918054798351 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 91 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 128.22088664324633 - 115.50290142480077 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 92 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 102.53841128002531 - 11.784449645612295 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 93 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 187.69871925603667 - 131.28317666772048 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 94 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 71.13897508938263 - 106.29335632876602 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 95 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 71.2216469861295 - 148.38612859488788 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 96 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 36.152562577928784 - 67.541796718348 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 97 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 118.84793016344604 - 0.49906433835273933 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 98 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 135.20417096106954 - 170.20704631856816 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 99 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 156.082359043526 - 57.62103450217495 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 100 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 180.58695188377737 - 80.75266645775669 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 101 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 38.93889890269273 - 138.60259660238856 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 102 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 159.5172788118917 - 192.24950143209503 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 103 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 154.02096825135868 - 139.67175722659056 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 104 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 38.480826888323904 - 5.502866276505292 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 105 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 27.95908088015704 - 193.85188308665965 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 106 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 198.61700949829074 - 171.1877312716402 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 107 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 106.30468818084609 - 25.058380770654654 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 108 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 40.335672117825624 - 179.59080234641004 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 109 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 22.316357638510897 - 158.94323888090028 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 110 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 99.56281553229194 - 85.64260133077535 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 111 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 60.71556414510035 - 121.53040248649711 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 112 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 27.08600745576586 - 38.17025720346818 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 113 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 147.03642509910586 - 39.51320588416096 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 114 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 180.2031547656297 - 141.5646561330238 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 115 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 73.12314629214424 - 167.80783320779847 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 116 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 167.93567452922767 - 10.060141001139144 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 117 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 163.99198875105768 - 147.48735207074026 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 118 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 154.98654737808127 - 121.17266324007643 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 119 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 57.898499791676386 - 149.3487194893122 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 120 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 64.82082963563904 - 174.0100480348673 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 121 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 114.13623920898752 - 15.754246175503095 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 122 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 0.00848902940355778 - 195.50701335573908 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 123 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 182.81764401709623 - 78.57837811285111 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 124 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 11.462145876504714 - 95.37444120802225 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 125 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 115.5020283241771 - 28.49431396939579 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 126 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 62.463952359877275 - 77.78913013330184 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 127 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 9.766778039117696 - 136.7421944039438 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 128 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 35.320514349220055 - 100.56248258192493 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 129 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 56.26732169234614 - 3.095097140731262 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 130 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 76.90164393617998 - 3.5671096386384216 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 131 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 81.97549075841862 - 13.020422155003475 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 132 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 54.87200208203389 - 77.29445717372947 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 133 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 193.47651032749548 - 144.9357554583657 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 134 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 51.65288193591992 - 126.16687604535504 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 135 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 151.66849746442173 - 158.7699863850836 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 136 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 32.469410974826005 - 113.10993021698361 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 137 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 33.04622512107349 - 25.425445944702794 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 138 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 33.53444748873715 - 112.25721598241579 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 139 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 128.9401580272291 - 100.73482184242926 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 140 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 194.6592727528704 - 102.73664509470841 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 141 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 125.47343036050516 - 106.53155237731285 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 142 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 147.40129296416038 - 12.37607345376115 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 143 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 113.32045045397959 - 126.79285457987103 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 144 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 27.174837677715825 - 66.84349985536826 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 145 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 164.20252670136998 - 51.635539499142524 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 146 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 39.351673884988394 - 65.05462325698123 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 147 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 143.91486202542433 - 171.28435110465497 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 148 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 30.926988343440186 - 130.3647571119649 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 149 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 19.897357003413617 - 22.905473451246785 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 150 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 128.36369031733133 - 170.71462512320227 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 151 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 172.1648617546042 - 184.1928317689217 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 152 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 148.16672573170842 - 107.99684523382686 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 153 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 83.90300186263724 - 169.4761782218257 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 154 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 90.86887922361453 - 142.8036645841288 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 155 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 23.18966921326753 - 69.42635534680753 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 156 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 134.59433377860168 - 37.633119904417796 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 157 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 127.97132285920065 - 158.57917470101572 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 158 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 166.2450456558778 - 108.67197275397042 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 159 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 167.334034200758 - 22.173554305333166 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 160 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 163.54194527237107 - 189.41605447848966 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 161 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 14.863357513573018 - 93.36644051662617 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 162 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 178.4370382798651 - 191.48348446587636 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 163 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 172.96087703915273 - 183.78535300027013 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 164 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 2.45779137738229 - 58.750309492130114 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 165 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 15.730601618735495 - 96.52335072173565 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 166 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 19.890833428932165 - 56.993000152370364 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 167 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 154.69166608840504 - 164.8598339150269 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 168 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 199.77196118880582 - 26.034321005016903 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 169 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 5.216343266336931 - 17.867912968799615 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 170 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 138.71273406283296 - 55.31024592694844 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 171 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 168.21144361519595 - 163.1843284579423 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 172 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 61.82504434646854 - 134.03197926926038 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 173 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 14.007317972338473 - 146.98475859141027 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 174 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 108.44210606040488 - 127.81076428732186 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 175 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 133.41957560864708 - 122.91534078890439 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 176 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 184.89266828168118 - 195.7201293014503 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 177 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 121.10492556426465 - 78.54418709376823 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 178 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 42.05271519544296 - 183.14259881514795 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 179 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 92.12119616387746 - 44.853464007589714 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 180 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 136.44039199596196 - 1.111619893261917 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 181 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 64.37440878278696 - 188.3078368775181 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 182 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 37.774149552594594 - 73.81683900641865 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 183 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 24.618589360988175 - 164.89708336795567 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 184 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 152.5950797265111 - 140.96774353352123 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 185 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 37.96933854365052 - 131.92434845994435 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 186 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 14.05145808951862 - 26.159084136809916 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 187 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 61.47558158857349 - 68.73507104275693 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 188 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 35.420404733112385 - 108.47794695541302 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 189 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 129.0179255565185 - 176.46977408461998 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 190 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 4.437687657989087 - 191.43801818673953 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 191 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 132.39232886927158 - 105.56546037448346 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 192 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 193.9356389936735 - 76.8987220921185 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 193 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 123.49672189705024 - 16.28922647444049 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 194 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 40.44058024960566 - 94.77629608096818 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 195 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 93.54168452285269 - 102.10342793159373 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 196 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 176.91858637781746 - 81.80773827257306 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 197 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 182.5062159995403 - 10.047631291589564 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 198 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 151.3211952231698 - 160.98807517681706 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 199 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 167.8826595707132 - 160.3686256248768 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 200 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 93.38491122055773 - 61.04322963139093 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 201 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 155.20211039479165 - 104.99915002371228 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 202 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 154.56882959476744 - 192.77647809954323 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 203 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 119.88029558288524 - 48.71837870038327 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 204 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 8.237800167806908 - 123.56280331420268 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 205 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 53.424877837249696 - 87.33638375233281 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 206 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 199.25320093864096 - 66.76343110330383 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 207 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 166.7255674935148 - 165.31992478582075 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 208 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 135.9334286576811 - 130.36986226660702 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 209 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 65.60950768388696 - 14.081940005079275 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 210 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 56.68133966983844 - 196.61338214776293 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 211 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 2.562777529582072 - 66.73129709411079 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 212 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 34.10919172462936 - 176.31986637140767 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 213 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 33.846173186403306 - 142.33660392777279 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 214 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 128.76326079790124 - 90.05136184351706 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 215 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 80.39617891964872 - 111.48714907972395 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 216 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 21.97338508940303 - 61.032785792453815 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 217 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 158.00182839254427 - 175.79991821384095 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 218 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 64.21702017661488 - 197.8650659620092 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 219 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 58.261430108425174 - 69.56229252260285 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 220 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 114.85635789777962 - 130.3021189977344 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 221 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 24.601661057872736 - 196.33046445845073 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 222 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 136.22037670133446 - 18.019579846123435 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 223 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 71.91168973841357 - 193.3123397692768 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 224 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 76.67497322258676 - 156.30488619961912 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 225 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 85.70841880772959 - 39.914700874835106 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 226 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 142.3427145819395 - 76.80244108802334 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 227 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 45.6821653485997 - 33.96733547026549 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 228 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 146.16353499121948 - 5.58117117441268 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 229 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 34.32680631388174 - 111.76495490887346 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 230 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 138.5676204843924 - 161.4559204389253 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 231 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 196.36096598095253 - 19.9809316402896 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 232 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 190.5761031572042 - 118.16570999859783 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 233 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 137.89894164409372 - 114.36842366282201 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 234 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 13.942927177934262 - 25.042265908173977 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 235 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 21.808225381827363 - 89.51408500063611 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 236 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 82.1665299576559 - 89.41818802221223 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 237 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 100.24631818801446 - 85.16089691564225 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 238 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 150.87166478995505 - 124.32687790892683 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 239 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 196.72953604773366 - 89.0589559016778 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 240 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 178.10423185724105 - 108.01295472332721 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 241 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 24.852336661830865 - 107.10027825925053 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 242 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 198.2838988728342 - 185.2533889301396 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 243 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 122.42366366542863 - 13.685145107609165 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 244 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 113.58516359448151 - 59.212889358544054 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 245 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 148.6689453992514 - 65.76664113968091 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 246 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 110.90604811956779 - 118.12368970120251 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 247 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 195.48877933255176 - 71.61703558744803 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 248 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 90.74911177135543 - 151.9662290090636 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 249 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 5.669662023293154 - 80.71705944385323 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 250 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 77.57071934873466 - 25.884947016521597 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 251 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 172.38535892291588 - 6.827522113737539 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 252 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 62.61595677732154 - 171.52926299696654 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 253 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 163.1605182212256 - 136.67511261098457 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 254 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 174.98684717123461 - 163.9648526025463 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 255 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 112.4179766207543 - 108.05999669756379 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 256 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 71.60510656526031 - 96.23183516652448 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 257 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 51.39949089302518 - 181.73639564248649 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 258 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 140.61625635482116 - 118.88528060437326 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 259 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 81.11235868256772 - 71.16703221921186 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 260 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 106.30383323544051 - 47.66664077552125 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 261 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 78.36392430481997 - 145.12300889005226 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 262 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 159.2795584664916 - 175.42365153724947 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 263 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 89.12806123792214 - 163.88074620615808 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 264 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 188.00194321004403 - 167.99738752402368 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 265 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 186.544702443713 - 156.12158395696437 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 266 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 2.8406717287810412 - 38.380349570314664 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 267 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 28.76119804764801 - 168.10637626762275 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 268 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 190.1115654346047 - 36.24498374070968 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 269 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 67.43484884843447 - 118.69086680825731 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 270 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 50.7959234692023 - 165.04960719272802 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 271 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 50.75575271798458 - 144.55723570362358 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 272 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 128.94257968083764 - 47.32490472068322 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 273 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 1.9193343221312942 - 112.82658785936086 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 274 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 51.82023785974064 - 148.28034473499338 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 275 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 98.55603081185546 - 178.02566808501155 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 276 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 143.40572664084078 - 183.27302398341982 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 277 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 141.0619733646239 - 54.122738136324955 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 278 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 162.29942916334053 - 67.55247227617933 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 279 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 185.29686875363197 - 118.81126461905944 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 280 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 104.06690998854779 - 5.511220514887172 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 281 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 181.82429252421596 - 47.0700962247878 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 282 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 17.604228655775245 - 96.78328313290936 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 283 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 60.74231839144737 - 136.8041677309854 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 284 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 158.57791000335715 - 90.16811700419458 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 285 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 26.040369760119475 - 115.48428978095157 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 286 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 155.33825554510548 - 122.61758874267335 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 287 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 171.04754637183774 - 49.44780022857469 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 288 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 130.8601631228818 - 115.38443324744807 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 289 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 138.51066172926747 - 85.05731662406394 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 290 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 17.01860916014879 - 85.74431631403492 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 291 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 63.632763185894994 - 73.28193598294403 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 292 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 145.51992557600448 - 190.19645657449914 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 293 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 141.3669225587347 - 128.37798094188392 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 294 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 5.624436269305666 - 10.321359475496084 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 295 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 32.62210104212715 - 80.99365929301005 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 296 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 146.82462375206796 - 189.00512676494264 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 297 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 96.89937776974169 - 61.868257009019125 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 298 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 71.17532023107206 - 32.87953533289934 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 299 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 37.21430187397199 - 21.880189704400976 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 300 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 123.17178528937387 - 23.802492560334287 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 301 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 139.8264101859233 - 106.93416114169838 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 302 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 34.97792194896952 - 182.11554692137054 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 303 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 156.016327676095 - 83.35423896139108 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 304 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 33.33352678715003 - 148.24111721535743 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 305 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 22.525965053498552 - 94.23130431241577 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 306 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 145.40586007739483 - 194.77296443866655 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 307 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 64.78487058910738 - 34.59908782949142 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 308 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 59.86114357954142 - 143.29623794752337 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 309 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 133.03711837762597 - 0.29677881350260726 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 310 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 184.05437940334514 - 80.34917749334691 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 311 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 43.18494391360306 - 0.7070568470557648 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 312 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 87.88579984985796 - 183.6845166360299 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 313 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 35.679149788796785 - 59.900754257451624 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 314 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 10.837936713278706 - 68.65555543408139 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 315 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 28.088726188466005 - 66.6117410256945 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 316 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 24.15305881985441 - 127.36722357863377 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 317 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 167.92463302345024 - 95.32246240241238 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 318 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 150.07537910034364 - 189.29680149689028 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 319 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 36.60193942102408 - 4.850860928459388 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 320 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 131.4804357164766 - 107.37981261172979 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 321 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 4.702056299253576 - 145.3571381517292 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 322 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 76.83393335740108 - 40.92489706855471 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 323 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 81.41902810900726 - 59.67311069186907 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 324 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 157.9286881274713 - 35.89390157980119 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 325 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 172.59261547136273 - 162.21173966194792 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 326 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 63.77983240079481 - 110.66181735649987 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 327 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 94.27259269172448 - 102.22907067171563 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 328 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 87.82927755519094 - 154.83172363042706 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 329 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 61.424763006386954 - 73.54903523332621 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 330 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 193.50994444846046 - 100.37438735826956 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 331 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 160.15646353486886 - 197.56265442862397 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 332 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 33.41179410209567 - 85.51716211010236 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 333 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 39.55932830334419 - 79.79114070992594 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 334 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 29.81531743952457 - 106.52370973616816 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 335 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 145.66591758403607 - 93.84627277397392 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 336 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 121.12689025085304 - 141.7616054105135 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 337 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 31.696932817539736 - 73.39512842700171 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 338 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 73.55413175311341 - 184.10063535264334 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 339 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 179.21266954315877 - 157.77936426661222 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 340 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 5.861701400590658 - 176.44679868441557 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 341 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 164.32858198885157 - 127.1649251930171 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 342 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 104.78813885934602 - 2.6978015525372934 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 343 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 9.036210189825722 - 37.29651951364714 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 344 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 69.09633192708777 - 131.08113653458605 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 345 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 23.989325789242024 - 102.76529191595212 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 346 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 32.563144827068456 - 174.05783874991164 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 347 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 26.84717981820497 - 33.708035418260465 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 348 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 23.651571274100892 - 150.9696150146202 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 349 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 7.263970263317554 - 178.4551746541966 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 350 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 137.19080046610807 - 195.47642758858956 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 351 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 100.60258790901588 - 10.122226122279043 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 352 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 158.02955707421086 - 15.552042272281575 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 353 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 69.03288347183658 - 86.65939835169405 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 354 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 197.11534487465465 - 12.227887489891408 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 355 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 109.32664513099861 - 51.47545505189106 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 356 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 7.450618560323541 - 114.12792666368863 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 357 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 96.73499758330652 - 87.34903664585806 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 358 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 143.42568088659735 - 154.7201550387036 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 359 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 16.055115327242596 - 23.72235108907279 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 360 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 36.54118641672248 - 71.60060131854802 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 361 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 153.4641555525212 - 182.30266241969497 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 362 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 179.79961054026052 - 52.374917374947486 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 363 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 51.89511924887278 - 55.715278818289924 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 364 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 160.22911392558143 - 197.03727711739174 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 365 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 141.50401865962175 - 198.17183635084353 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 366 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 144.1436553724308 - 66.26788567722302 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 367 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 114.85639238072662 - 187.02866922391485 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 368 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 14.754418142216963 - 189.75568091879705 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 369 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 40.445861020644756 - 132.87622199437286 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 370 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 70.41846318684537 - 16.353121961748673 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 371 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 11.524098377391411 - 188.46037552576104 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 372 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 19.80490164758435 - 193.31200682922997 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 373 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 170.32256510777594 - 170.204813941954 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 374 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 35.11638379627671 - 106.63452905636245 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 375 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 87.80726944100199 - 69.16884374165753 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 376 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 45.63781115512378 - 137.1790704392972 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 377 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 120.23124867416645 - 21.60172442725463 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 378 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 42.584241021086264 - 172.9365035614701 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 379 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 106.9111221907689 - 35.38132573733432 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 380 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 115.65012523180343 - 149.06748739273075 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 381 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 66.70597176653999 - 151.96624665556067 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 382 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 116.86108695969573 - 92.96503821223025 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 383 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 138.3454858274232 - 60.335069940591254 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 384 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 35.21169262537829 - 57.75683948274251 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 385 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 183.64109836494706 - 187.89865943504947 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 386 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 124.92709985349823 - 7.139364140447135 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 387 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 121.19563498360651 - 163.5898829983739 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 388 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 141.67701483198246 - 36.967824799613645 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 389 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 116.85490603618803 - 192.1746914581395 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 390 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 157.23646122348265 - 101.21354943885676 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 391 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 58.04596641555313 - 180.0770488919343 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 392 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 118.342960728573 - 65.22048911724025 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 393 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 61.42203823259405 - 117.333210601775 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 394 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 136.13358028390385 - 97.99627507346685 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 395 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 82.86089860898949 - 25.22615052347874 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 396 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 6.721379593879373 - 94.78763681182285 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 397 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 38.69266957378596 - 24.113141554020046 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 398 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 111.22857295130957 - 95.51634459331788 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 399 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 126.7915415569141 - 32.23798771734878 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 400 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 186.84699461455236 - 34.76662976923288 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 401 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 122.45497909139493 - 167.0773654715768 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 402 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.interfaces.Position - 33.03449972907999 - 172.77024458531486 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 403 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype332 - - - - org.contikios.cooja.plugins.SimControl - 280 - 3 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - 1.1671649566739442 0.0 0.0 1.1671649566739442 66.21348020552065 40.83199757586018 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1184 - 0 - 240 - 402 - 162 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 904 - 4 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 962 - 1 - 596 - 603 - 43 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype710 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make TARGET=cooja clean +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype709 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make TARGET=cooja clean +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype332 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make TARGET=cooja clean +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -15.604889524290883 + -27.272920930192623 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 218.29521040499824 + 216.70287561143516 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype710 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype709 + + + + org.contikios.cooja.interfaces.Position + 27.44274795318258 + 36.980443988209856 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 185.6055859234863 + 192.99166984979271 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 7.827315175624361 + 107.95833747378225 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 82.49199862549197 + 34.72851022020231 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.671428723363064 + 125.82590119075962 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.044376889885754 + 62.443378727185774 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 9 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 152.53659733643553 + 165.87608708149403 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 10 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 22.023077232445942 + 18.41094139254531 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 11 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 41.19368867821842 + 49.201157808285224 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 12 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 114.62128502432532 + 88.58807114217633 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 13 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.21405469314478 + 188.6851979777661 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 14 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 104.78326932115709 + 100.84889281105585 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 15 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 90.26861048950052 + 40.550864496421404 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 16 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 137.39112328314076 + 126.5333637365394 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 17 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 14.07616766247768 + 99.85572366133869 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 18 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 192.30563307960443 + 66.83563821262344 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 19 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 129.08253247651874 + 117.20437669309078 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 20 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 21.82717410659969 + 47.523771402541335 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 21 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.95102103988239 + 21.74677482276881 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 22 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.71108896268191 + 79.91617509627334 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 23 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 16.029809485043288 + 171.05935835280616 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 24 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 138.8418552766128 + 61.418703448852185 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 25 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 151.23299942414673 + 92.41820871538522 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 26 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 197.33157775573343 + 20.6013482653864 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 27 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 121.20762229879878 + 184.81107462083565 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 28 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 102.32432527534694 + 91.9912435435037 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 29 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 88.10909646999544 + 191.21251904898142 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 30 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 72.19774934085703 + 113.58131529956069 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 31 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 53.49967737007204 + 72.45172156882643 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 32 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 172.07186411958625 + 51.47715718716961 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 33 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 185.41983532466634 + 85.60078269414 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 34 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 83.34993971740548 + 193.98111239532744 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 35 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 105.03752362550378 + 131.24078026424087 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 36 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 176.09318670322102 + 41.46760901468247 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 37 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.80689915307215 + 47.13815728542057 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 38 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 155.907739287817 + 15.24009422994106 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 39 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 45.992463430523436 + 124.573811024683 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 40 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 159.11361032671832 + 81.65319598335425 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 41 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 41.838657583001314 + 163.47591213471193 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 42 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 25.560001904073125 + 147.48610852243928 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 43 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 139.56489350213488 + 191.15379557180913 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 44 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 105.71342550700061 + 136.09089690661503 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 45 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 122.59378462201298 + 196.22862961645998 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 46 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 147.61372446125088 + 55.314287700435536 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 47 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 77.70218628780312 + 95.59561907133107 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 48 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.88244578562713 + 168.57963926907163 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 49 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 6.722298767036894 + 101.09668965729898 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 50 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 62.96680217979964 + 77.66951408660954 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 51 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 162.49011735601982 + 199.07086470932003 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 52 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 87.87526390617558 + 114.39424478293958 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 53 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 74.29230372180815 + 36.995699473573836 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 54 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 77.34619341407321 + 60.070446577058576 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 55 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.32695571818826 + 135.82669004433725 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 56 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 68.10326013650814 + 5.04157445893032 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 57 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 95.76993029214962 + 45.046282401332945 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 58 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 79.87963205080952 + 110.7023948653882 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 59 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 195.90349780899223 + 132.38904172009444 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 60 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 80.40108440304007 + 25.86673418569547 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 61 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 52.268877618080744 + 176.12888723955277 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 62 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 40.545541404899765 + 166.9450252729589 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 63 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 10.676184465528205 + 0.9871174057552334 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 64 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 87.35673216830257 + 23.25131234780027 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 65 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 26.745126931691352 + 87.3101256645554 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 66 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 183.2724008541638 + 167.69026002459069 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 67 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 5.934720840855223 + 77.21248812623693 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 68 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.49604470599058 + 108.80963795015302 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 69 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 86.10145414955488 + 12.798582653303603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 70 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 32.435370110193816 + 29.344591306898813 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 71 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 163.72950518161596 + 154.15283820759655 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 72 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 143.96396308843373 + 132.40312602892786 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 73 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 139.20530179839795 + 144.18958011498225 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 74 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 75.22453368236212 + 119.69913560274786 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 75 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 21.83836116635087 + 191.21696522067728 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 76 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 187.94640511976667 + 113.95684826994561 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 77 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 114.61289565250618 + 27.61001303446735 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 78 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 70.83569869750504 + 113.88992677636021 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 79 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 11.616059362048992 + 45.59401384110464 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 80 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 3.4282454263252937 + 35.97653370545284 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 81 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 54.33122057405715 + 1.9759087814547494 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 82 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 69.6612091444155 + 0.45982758130533874 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 83 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 169.98417155202168 + 87.76678058442593 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 84 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 148.98441194234616 + 104.32820155415494 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 85 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 66.23883124891583 + 162.92685536074129 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 86 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 181.6348837921769 + 183.07267240808343 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 87 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 88.9829570206748 + 119.72520333459575 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 88 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 179.1527012143494 + 84.25685075020328 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 89 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 117.82537007493707 + 41.10319533518651 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 90 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 52.611633540398486 + 94.71918054798351 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 91 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 128.22088664324633 + 115.50290142480077 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 92 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 102.53841128002531 + 11.784449645612295 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 93 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 187.69871925603667 + 131.28317666772048 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 94 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.13897508938263 + 106.29335632876602 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 95 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.2216469861295 + 148.38612859488788 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 96 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 36.152562577928784 + 67.541796718348 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 97 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 118.84793016344604 + 0.49906433835273933 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 98 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 135.20417096106954 + 170.20704631856816 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 99 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 156.082359043526 + 57.62103450217495 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 100 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 180.58695188377737 + 80.75266645775669 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 101 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 38.93889890269273 + 138.60259660238856 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 102 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 159.5172788118917 + 192.24950143209503 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 103 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 154.02096825135868 + 139.67175722659056 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 104 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 38.480826888323904 + 5.502866276505292 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 105 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 27.95908088015704 + 193.85188308665965 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 106 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 198.61700949829074 + 171.1877312716402 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 107 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 106.30468818084609 + 25.058380770654654 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 108 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 40.335672117825624 + 179.59080234641004 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 109 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 22.316357638510897 + 158.94323888090028 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 110 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 99.56281553229194 + 85.64260133077535 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 111 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 60.71556414510035 + 121.53040248649711 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 112 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 27.08600745576586 + 38.17025720346818 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 113 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 147.03642509910586 + 39.51320588416096 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 114 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 180.2031547656297 + 141.5646561330238 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 115 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 73.12314629214424 + 167.80783320779847 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 116 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 167.93567452922767 + 10.060141001139144 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 117 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 163.99198875105768 + 147.48735207074026 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 118 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 154.98654737808127 + 121.17266324007643 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 119 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 57.898499791676386 + 149.3487194893122 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 120 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 64.82082963563904 + 174.0100480348673 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 121 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 114.13623920898752 + 15.754246175503095 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 122 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 0.00848902940355778 + 195.50701335573908 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 123 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 182.81764401709623 + 78.57837811285111 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 124 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 11.462145876504714 + 95.37444120802225 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 125 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 115.5020283241771 + 28.49431396939579 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 126 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 62.463952359877275 + 77.78913013330184 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 127 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 9.766778039117696 + 136.7421944039438 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 128 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.320514349220055 + 100.56248258192493 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 129 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 56.26732169234614 + 3.095097140731262 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 130 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.90164393617998 + 3.5671096386384216 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 131 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 81.97549075841862 + 13.020422155003475 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 132 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 54.87200208203389 + 77.29445717372947 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 133 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 193.47651032749548 + 144.9357554583657 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 134 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 51.65288193591992 + 126.16687604535504 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 135 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 151.66849746442173 + 158.7699863850836 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 136 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 32.469410974826005 + 113.10993021698361 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 137 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.04622512107349 + 25.425445944702794 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 138 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.53444748873715 + 112.25721598241579 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 139 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 128.9401580272291 + 100.73482184242926 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 140 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 194.6592727528704 + 102.73664509470841 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 141 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 125.47343036050516 + 106.53155237731285 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 142 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 147.40129296416038 + 12.37607345376115 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 143 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 113.32045045397959 + 126.79285457987103 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 144 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 27.174837677715825 + 66.84349985536826 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 145 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 164.20252670136998 + 51.635539499142524 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 146 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 39.351673884988394 + 65.05462325698123 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 147 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 143.91486202542433 + 171.28435110465497 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 148 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 30.926988343440186 + 130.3647571119649 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 149 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 19.897357003413617 + 22.905473451246785 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 150 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 128.36369031733133 + 170.71462512320227 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 151 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 172.1648617546042 + 184.1928317689217 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 152 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 148.16672573170842 + 107.99684523382686 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 153 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 83.90300186263724 + 169.4761782218257 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 154 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 90.86887922361453 + 142.8036645841288 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 155 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 23.18966921326753 + 69.42635534680753 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 156 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 134.59433377860168 + 37.633119904417796 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 157 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 127.97132285920065 + 158.57917470101572 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 158 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 166.2450456558778 + 108.67197275397042 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 159 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 167.334034200758 + 22.173554305333166 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 160 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 163.54194527237107 + 189.41605447848966 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 161 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 14.863357513573018 + 93.36644051662617 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 162 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 178.4370382798651 + 191.48348446587636 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 163 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 172.96087703915273 + 183.78535300027013 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 164 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 2.45779137738229 + 58.750309492130114 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 165 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 15.730601618735495 + 96.52335072173565 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 166 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 19.890833428932165 + 56.993000152370364 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 167 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 154.69166608840504 + 164.8598339150269 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 168 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 199.77196118880582 + 26.034321005016903 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 169 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 5.216343266336931 + 17.867912968799615 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 170 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 138.71273406283296 + 55.31024592694844 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 171 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 168.21144361519595 + 163.1843284579423 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 172 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.82504434646854 + 134.03197926926038 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 173 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 14.007317972338473 + 146.98475859141027 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 174 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 108.44210606040488 + 127.81076428732186 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 175 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 133.41957560864708 + 122.91534078890439 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 176 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 184.89266828168118 + 195.7201293014503 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 177 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 121.10492556426465 + 78.54418709376823 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 178 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 42.05271519544296 + 183.14259881514795 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 179 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 92.12119616387746 + 44.853464007589714 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 180 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 136.44039199596196 + 1.111619893261917 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 181 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 64.37440878278696 + 188.3078368775181 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 182 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 37.774149552594594 + 73.81683900641865 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 183 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 24.618589360988175 + 164.89708336795567 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 184 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 152.5950797265111 + 140.96774353352123 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 185 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 37.96933854365052 + 131.92434845994435 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 186 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 14.05145808951862 + 26.159084136809916 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 187 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.47558158857349 + 68.73507104275693 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 188 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.420404733112385 + 108.47794695541302 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 189 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 129.0179255565185 + 176.46977408461998 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 190 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 4.437687657989087 + 191.43801818673953 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 191 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 132.39232886927158 + 105.56546037448346 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 192 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 193.9356389936735 + 76.8987220921185 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 193 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 123.49672189705024 + 16.28922647444049 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 194 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 40.44058024960566 + 94.77629608096818 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 195 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 93.54168452285269 + 102.10342793159373 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 196 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 176.91858637781746 + 81.80773827257306 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 197 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 182.5062159995403 + 10.047631291589564 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 198 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 151.3211952231698 + 160.98807517681706 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 199 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 167.8826595707132 + 160.3686256248768 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 200 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 93.38491122055773 + 61.04322963139093 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 201 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 155.20211039479165 + 104.99915002371228 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 202 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 154.56882959476744 + 192.77647809954323 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 203 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 119.88029558288524 + 48.71837870038327 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 204 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 8.237800167806908 + 123.56280331420268 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 205 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 53.424877837249696 + 87.33638375233281 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 206 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 199.25320093864096 + 66.76343110330383 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 207 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 166.7255674935148 + 165.31992478582075 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 208 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 135.9334286576811 + 130.36986226660702 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 209 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 65.60950768388696 + 14.081940005079275 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 210 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 56.68133966983844 + 196.61338214776293 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 211 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 2.562777529582072 + 66.73129709411079 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 212 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 34.10919172462936 + 176.31986637140767 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 213 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.846173186403306 + 142.33660392777279 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 214 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 128.76326079790124 + 90.05136184351706 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 215 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 80.39617891964872 + 111.48714907972395 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 216 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 21.97338508940303 + 61.032785792453815 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 217 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 158.00182839254427 + 175.79991821384095 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 218 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 64.21702017661488 + 197.8650659620092 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 219 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 58.261430108425174 + 69.56229252260285 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 220 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 114.85635789777962 + 130.3021189977344 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 221 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 24.601661057872736 + 196.33046445845073 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 222 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 136.22037670133446 + 18.019579846123435 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 223 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.91168973841357 + 193.3123397692768 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 224 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.67497322258676 + 156.30488619961912 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 225 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 85.70841880772959 + 39.914700874835106 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 226 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 142.3427145819395 + 76.80244108802334 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 227 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 45.6821653485997 + 33.96733547026549 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 228 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 146.16353499121948 + 5.58117117441268 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 229 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 34.32680631388174 + 111.76495490887346 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 230 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 138.5676204843924 + 161.4559204389253 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 231 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 196.36096598095253 + 19.9809316402896 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 232 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 190.5761031572042 + 118.16570999859783 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 233 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 137.89894164409372 + 114.36842366282201 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 234 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 13.942927177934262 + 25.042265908173977 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 235 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 21.808225381827363 + 89.51408500063611 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 236 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 82.1665299576559 + 89.41818802221223 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 237 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 100.24631818801446 + 85.16089691564225 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 238 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 150.87166478995505 + 124.32687790892683 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 239 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 196.72953604773366 + 89.0589559016778 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 240 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 178.10423185724105 + 108.01295472332721 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 241 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 24.852336661830865 + 107.10027825925053 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 242 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 198.2838988728342 + 185.2533889301396 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 243 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 122.42366366542863 + 13.685145107609165 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 244 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 113.58516359448151 + 59.212889358544054 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 245 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 148.6689453992514 + 65.76664113968091 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 246 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 110.90604811956779 + 118.12368970120251 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 247 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 195.48877933255176 + 71.61703558744803 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 248 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 90.74911177135543 + 151.9662290090636 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 249 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 5.669662023293154 + 80.71705944385323 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 250 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 77.57071934873466 + 25.884947016521597 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 251 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 172.38535892291588 + 6.827522113737539 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 252 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 62.61595677732154 + 171.52926299696654 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 253 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 163.1605182212256 + 136.67511261098457 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 254 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 174.98684717123461 + 163.9648526025463 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 255 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 112.4179766207543 + 108.05999669756379 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 256 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.60510656526031 + 96.23183516652448 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 257 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 51.39949089302518 + 181.73639564248649 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 258 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 140.61625635482116 + 118.88528060437326 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 259 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 81.11235868256772 + 71.16703221921186 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 260 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 106.30383323544051 + 47.66664077552125 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 261 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 78.36392430481997 + 145.12300889005226 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 262 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 159.2795584664916 + 175.42365153724947 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 263 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 89.12806123792214 + 163.88074620615808 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 264 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 188.00194321004403 + 167.99738752402368 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 265 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 186.544702443713 + 156.12158395696437 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 266 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 2.8406717287810412 + 38.380349570314664 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 267 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 28.76119804764801 + 168.10637626762275 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 268 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 190.1115654346047 + 36.24498374070968 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 269 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 67.43484884843447 + 118.69086680825731 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 270 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 50.7959234692023 + 165.04960719272802 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 271 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 50.75575271798458 + 144.55723570362358 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 272 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 128.94257968083764 + 47.32490472068322 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 273 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 1.9193343221312942 + 112.82658785936086 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 274 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 51.82023785974064 + 148.28034473499338 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 275 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 98.55603081185546 + 178.02566808501155 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 276 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 143.40572664084078 + 183.27302398341982 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 277 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 141.0619733646239 + 54.122738136324955 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 278 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 162.29942916334053 + 67.55247227617933 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 279 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 185.29686875363197 + 118.81126461905944 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 280 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 104.06690998854779 + 5.511220514887172 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 281 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 181.82429252421596 + 47.0700962247878 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 282 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 17.604228655775245 + 96.78328313290936 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 283 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 60.74231839144737 + 136.8041677309854 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 284 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 158.57791000335715 + 90.16811700419458 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 285 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 26.040369760119475 + 115.48428978095157 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 286 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 155.33825554510548 + 122.61758874267335 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 287 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 171.04754637183774 + 49.44780022857469 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 288 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 130.8601631228818 + 115.38443324744807 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 289 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 138.51066172926747 + 85.05731662406394 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 290 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 17.01860916014879 + 85.74431631403492 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 291 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 63.632763185894994 + 73.28193598294403 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 292 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 145.51992557600448 + 190.19645657449914 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 293 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 141.3669225587347 + 128.37798094188392 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 294 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 5.624436269305666 + 10.321359475496084 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 295 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 32.62210104212715 + 80.99365929301005 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 296 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 146.82462375206796 + 189.00512676494264 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 297 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 96.89937776974169 + 61.868257009019125 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 298 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.17532023107206 + 32.87953533289934 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 299 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 37.21430187397199 + 21.880189704400976 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 300 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 123.17178528937387 + 23.802492560334287 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 301 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 139.8264101859233 + 106.93416114169838 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 302 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 34.97792194896952 + 182.11554692137054 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 303 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 156.016327676095 + 83.35423896139108 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 304 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.33352678715003 + 148.24111721535743 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 305 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 22.525965053498552 + 94.23130431241577 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 306 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 145.40586007739483 + 194.77296443866655 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 307 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 64.78487058910738 + 34.59908782949142 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 308 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 59.86114357954142 + 143.29623794752337 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 309 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 133.03711837762597 + 0.29677881350260726 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 310 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 184.05437940334514 + 80.34917749334691 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 311 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 43.18494391360306 + 0.7070568470557648 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 312 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 87.88579984985796 + 183.6845166360299 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 313 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.679149788796785 + 59.900754257451624 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 314 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 10.837936713278706 + 68.65555543408139 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 315 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 28.088726188466005 + 66.6117410256945 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 316 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 24.15305881985441 + 127.36722357863377 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 317 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 167.92463302345024 + 95.32246240241238 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 318 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 150.07537910034364 + 189.29680149689028 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 319 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 36.60193942102408 + 4.850860928459388 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 320 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 131.4804357164766 + 107.37981261172979 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 321 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 4.702056299253576 + 145.3571381517292 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 322 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.83393335740108 + 40.92489706855471 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 323 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 81.41902810900726 + 59.67311069186907 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 324 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 157.9286881274713 + 35.89390157980119 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 325 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 172.59261547136273 + 162.21173966194792 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 326 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 63.77983240079481 + 110.66181735649987 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 327 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 94.27259269172448 + 102.22907067171563 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 328 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 87.82927755519094 + 154.83172363042706 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 329 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.424763006386954 + 73.54903523332621 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 330 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 193.50994444846046 + 100.37438735826956 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 331 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 160.15646353486886 + 197.56265442862397 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 332 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.41179410209567 + 85.51716211010236 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 333 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 39.55932830334419 + 79.79114070992594 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 334 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 29.81531743952457 + 106.52370973616816 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 335 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 145.66591758403607 + 93.84627277397392 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 336 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 121.12689025085304 + 141.7616054105135 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 337 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 31.696932817539736 + 73.39512842700171 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 338 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 73.55413175311341 + 184.10063535264334 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 339 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 179.21266954315877 + 157.77936426661222 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 340 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 5.861701400590658 + 176.44679868441557 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 341 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 164.32858198885157 + 127.1649251930171 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 342 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 104.78813885934602 + 2.6978015525372934 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 343 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 9.036210189825722 + 37.29651951364714 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 344 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 69.09633192708777 + 131.08113653458605 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 345 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 23.989325789242024 + 102.76529191595212 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 346 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 32.563144827068456 + 174.05783874991164 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 347 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 26.84717981820497 + 33.708035418260465 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 348 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 23.651571274100892 + 150.9696150146202 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 349 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 7.263970263317554 + 178.4551746541966 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 350 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 137.19080046610807 + 195.47642758858956 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 351 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 100.60258790901588 + 10.122226122279043 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 352 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 158.02955707421086 + 15.552042272281575 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 353 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 69.03288347183658 + 86.65939835169405 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 354 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 197.11534487465465 + 12.227887489891408 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 355 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 109.32664513099861 + 51.47545505189106 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 356 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 7.450618560323541 + 114.12792666368863 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 357 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 96.73499758330652 + 87.34903664585806 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 358 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 143.42568088659735 + 154.7201550387036 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 359 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 16.055115327242596 + 23.72235108907279 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 360 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 36.54118641672248 + 71.60060131854802 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 361 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 153.4641555525212 + 182.30266241969497 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 362 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 179.79961054026052 + 52.374917374947486 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 363 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 51.89511924887278 + 55.715278818289924 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 364 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 160.22911392558143 + 197.03727711739174 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 365 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 141.50401865962175 + 198.17183635084353 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 366 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 144.1436553724308 + 66.26788567722302 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 367 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 114.85639238072662 + 187.02866922391485 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 368 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 14.754418142216963 + 189.75568091879705 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 369 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 40.445861020644756 + 132.87622199437286 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 370 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 70.41846318684537 + 16.353121961748673 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 371 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 11.524098377391411 + 188.46037552576104 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 372 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 19.80490164758435 + 193.31200682922997 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 373 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 170.32256510777594 + 170.204813941954 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 374 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.11638379627671 + 106.63452905636245 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 375 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 87.80726944100199 + 69.16884374165753 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 376 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 45.63781115512378 + 137.1790704392972 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 377 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 120.23124867416645 + 21.60172442725463 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 378 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 42.584241021086264 + 172.9365035614701 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 379 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 106.9111221907689 + 35.38132573733432 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 380 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 115.65012523180343 + 149.06748739273075 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 381 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 66.70597176653999 + 151.96624665556067 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 382 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 116.86108695969573 + 92.96503821223025 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 383 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 138.3454858274232 + 60.335069940591254 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 384 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.21169262537829 + 57.75683948274251 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 385 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 183.64109836494706 + 187.89865943504947 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 386 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 124.92709985349823 + 7.139364140447135 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 387 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 121.19563498360651 + 163.5898829983739 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 388 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 141.67701483198246 + 36.967824799613645 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 389 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 116.85490603618803 + 192.1746914581395 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 390 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 157.23646122348265 + 101.21354943885676 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 391 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 58.04596641555313 + 180.0770488919343 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 392 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 118.342960728573 + 65.22048911724025 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 393 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.42203823259405 + 117.333210601775 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 394 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 136.13358028390385 + 97.99627507346685 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 395 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 82.86089860898949 + 25.22615052347874 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 396 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 6.721379593879373 + 94.78763681182285 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 397 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 38.69266957378596 + 24.113141554020046 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 398 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 111.22857295130957 + 95.51634459331788 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 399 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 126.7915415569141 + 32.23798771734878 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 400 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 186.84699461455236 + 34.76662976923288 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 401 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 122.45497909139493 + 167.0773654715768 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 402 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.03449972907999 + 172.77024458531486 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 403 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 1.1671649566739442 0.0 0.0 1.1671649566739442 66.21348020552065 40.83199757586018 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 0 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 1 + 596 + 603 + 43 + + \ No newline at end of file diff --git a/regression-tests/12-rpl/05-rpl-up-and-down-routes.csc b/regression-tests/12-rpl/05-rpl-up-and-down-routes.csc index 7191e79ad..0dd110738 100644 --- a/regression-tests/12-rpl/05-rpl-up-and-down-routes.csc +++ b/regression-tests/12-rpl/05-rpl-up-and-down-routes.csc @@ -1,344 +1,342 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype743 - Sender - [CONFIG_DIR]/code/sender-node.c + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype743 + Sender + [CONFIG_DIR]/code/sender-node.c make clean TARGET=cooja -make sender-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype452 - RPL root - [CONFIG_DIR]/code/root-node.c +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype452 + RPL root + [CONFIG_DIR]/code/root-node.c make clean TARGET=cooja -make root-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype782 - Receiver - [CONFIG_DIR]/code/receiver-node.c +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype782 + Receiver + [CONFIG_DIR]/code/receiver-node.c make clean TARGET=cooja -make receiver-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - -22.5728586847096 - 123.9358664968653 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype782 - - - - org.contikios.cooja.interfaces.Position - 116.13379149678028 - 88.36698920455684 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype743 - - - - org.contikios.cooja.interfaces.Position - -1.39303771455413 - 100.21446701029119 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 4 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype782 - - - - org.contikios.cooja.interfaces.Position - 95.25095618820441 - 63.14998053005015 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 5 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype782 - - - - org.contikios.cooja.interfaces.Position - 66.09378990830604 - 38.32698761608261 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype782 - - - - org.contikios.cooja.interfaces.Position - 29.05630841762433 - 30.840688165838436 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 7 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype782 - - - - org.contikios.cooja.interfaces.Position - 10.931583432822638 - 69.848248459216 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype782 - - - - org.contikios.cooja.interfaces.Position - 0.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype452 - - - - org.contikios.cooja.plugins.SimControl - 280 - 1 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - 1184 - 3 - 240 - 402 - 162 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 904 - 4 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 962 - 0 - 596 - 603 - 43 - - - +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -22.5728586847096 + 123.9358664968653 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype743 + + + + org.contikios.cooja.interfaces.Position + -1.39303771455413 + 100.21446701029119 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 10.931583432822638 + 69.848248459216 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype452 + + + + org.contikios.cooja.plugins.SimControl + 280 + 1 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + 1184 + 3 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 0 + 596 + 603 + 43 + + + diff --git a/regression-tests/12-rpl/06-rpl-temporary-root-loss.csc b/regression-tests/12-rpl/06-rpl-temporary-root-loss.csc index f4c132c4d..6c29c643f 100644 --- a/regression-tests/12-rpl/06-rpl-temporary-root-loss.csc +++ b/regression-tests/12-rpl/06-rpl-temporary-root-loss.csc @@ -1,344 +1,348 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype951 - Sender - [CONFIG_DIR]/code/sender-node.c + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype951 + Sender + [CONFIG_DIR]/code/sender-node.c make clean TARGET=cooja -make sender-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype170 - RPL root - [CONFIG_DIR]/code/root-node.c +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype170 + RPL root + [CONFIG_DIR]/code/root-node.c make clean TARGET=cooja -make root-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype767 - Receiver - [CONFIG_DIR]/code/receiver-node.c +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype767 + Receiver + [CONFIG_DIR]/code/receiver-node.c make clean TARGET=cooja -make receiver-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - -22.5728586847096 - 123.9358664968653 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype767 - - - - org.contikios.cooja.interfaces.Position - 116.13379149678028 - 88.36698920455684 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype951 - - - - org.contikios.cooja.interfaces.Position - -1.39303771455413 - 100.21446701029119 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 4 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype767 - - - - org.contikios.cooja.interfaces.Position - 95.25095618820441 - 63.14998053005015 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 5 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype767 - - - - org.contikios.cooja.interfaces.Position - 66.09378990830604 - 38.32698761608261 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype767 - - - - org.contikios.cooja.interfaces.Position - 29.05630841762433 - 30.840688165838436 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 7 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype767 - - - - org.contikios.cooja.interfaces.Position - 10.931583432822638 - 69.848248459216 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype767 - - - - org.contikios.cooja.interfaces.Position - 0.0 - 0.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype170 - - - - org.contikios.cooja.plugins.SimControl - 280 - 0 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - 1184 - 3 - 240 - 402 - 162 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 904 - 4 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 962 - 1 - 596 - 603 - 43 - - - +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -22.5728586847096 + 123.9358664968653 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype951 + + + + org.contikios.cooja.interfaces.Position + -1.39303771455413 + 100.21446701029119 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 10.931583432822638 + 69.848248459216 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype170 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + 1184 + 3 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 1 + 596 + 603 + 43 + + + diff --git a/regression-tests/12-rpl/07-rpl-random-rearrangement.csc b/regression-tests/12-rpl/07-rpl-random-rearrangement.csc index 8dcbd4d35..cdb62c420 100644 --- a/regression-tests/12-rpl/07-rpl-random-rearrangement.csc +++ b/regression-tests/12-rpl/07-rpl-random-rearrangement.csc @@ -1,647 +1,647 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype419 - Sender - [CONFIG_DIR]/code/sender-node.c - make clean TARGET=cooja -make sender-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype484 - RPL root - [CONFIG_DIR]/code/root-node.c - make clean TARGET=cooja -make root-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype718 - Receiver - [CONFIG_DIR]/code/receiver-node.c - make clean TARGET=cooja -make receiver-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - -0.4799968467515439 - 98.79087181374759 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 99.56423154395364 - 50.06466731257512 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype419 - - - - org.contikios.cooja.interfaces.Position - -0.4799968467515439 - 0.30173505605854883 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype484 - - - - org.contikios.cooja.interfaces.Position - 12.779318616702257 - 8.464865358169643 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 4 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 9.391922400291703 - 49.22878206790311 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 5 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 48.16367625505583 - 33.27520746599595 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 16.582742473429345 - 24.932911331640646 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 7 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 8.445564421140666 - 6.770205395698742 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 87.04968129458189 - 34.46536562612724 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 9 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 94.47123252519145 - 18.275940194868184 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 10 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 95.28044254364556 - 17.683438211793558 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 11 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 56.124622439456076 - 33.88966252832571 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 12 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 98.33149749474546 - 37.448034626592744 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 13 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 58.75337436025891 - 68.64082018992522 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 14 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 66.83816496627988 - 68.38008376830592 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 15 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 90.88648665466316 - 50.942053906416575 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 16 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 68.80089833632896 - 84.17294684073734 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 17 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 73.6760846183129 - 81.76699743886633 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 18 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 0.2960103456537466 - 98.5587829617092 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 19 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 8.130479493904208 - 57.642099520821645 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 20 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 30.550120982984865 - 85.58346736403402 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 21 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 29.65300377698182 - 63.50257213104861 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 22 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.interfaces.Position - 34.92110687576687 - 70.71381297232249 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 23 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype718 - - - - org.contikios.cooja.plugins.SimControl - 280 - 1 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 1.92914676942954 0.0 0.0 1.92914676942954 75.9259843662471 55.41790879138101 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1184 - 3 - 500 - 402 - 162 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 904 - 4 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 612 - 0 - 726 - 953 - 43 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype419 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype484 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype718 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -0.4799968467515439 + 98.79087181374759 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 99.56423154395364 + 50.06466731257512 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype419 + + + + org.contikios.cooja.interfaces.Position + -0.4799968467515439 + 0.30173505605854883 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype484 + + + + org.contikios.cooja.interfaces.Position + 12.779318616702257 + 8.464865358169643 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 9.391922400291703 + 49.22878206790311 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 48.16367625505583 + 33.27520746599595 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 16.582742473429345 + 24.932911331640646 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 8.445564421140666 + 6.770205395698742 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 87.04968129458189 + 34.46536562612724 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 9 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 94.47123252519145 + 18.275940194868184 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 10 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 95.28044254364556 + 17.683438211793558 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 11 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 56.124622439456076 + 33.88966252832571 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 12 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 98.33149749474546 + 37.448034626592744 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 13 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 58.75337436025891 + 68.64082018992522 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 14 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 66.83816496627988 + 68.38008376830592 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 15 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 90.88648665466316 + 50.942053906416575 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 16 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 68.80089833632896 + 84.17294684073734 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 17 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 73.6760846183129 + 81.76699743886633 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 18 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 0.2960103456537466 + 98.5587829617092 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 19 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 8.130479493904208 + 57.642099520821645 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 20 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 30.550120982984865 + 85.58346736403402 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 21 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 29.65300377698182 + 63.50257213104861 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 22 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 34.92110687576687 + 70.71381297232249 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 23 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.plugins.SimControl + 280 + 1 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 1.92914676942954 0.0 0.0 1.92914676942954 75.9259843662471 55.41790879138101 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 3 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 0 + 726 + 953 + 43 + + + diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc index 7f63864a2..0fc6e032d 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc @@ -1,362 +1,360 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype921 - Sender - [CONFIG_DIR]/code/sender-node.c + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype921 + Sender + [CONFIG_DIR]/code/sender-node.c make clean TARGET=cooja -make sender-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype873 - RPL root - [CONFIG_DIR]/code/root-node.c +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype873 + RPL root + [CONFIG_DIR]/code/root-node.c make clean TARGET=cooja -make root-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype812 - Receiver - [CONFIG_DIR]/code/receiver-node.c +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype812 + Receiver + [CONFIG_DIR]/code/receiver-node.c make clean TARGET=cooja -make receiver-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - -7.199692787830563 - 98.21738321803603 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 116.13379149678028 - 88.36698920455684 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype921 - - - - org.contikios.cooja.interfaces.Position - 12.0 - 68.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 4 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 95.25095618820441 - 63.14998053005015 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 5 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 66.09378990830604 - 38.32698761608261 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 29.05630841762433 - 30.840688165838436 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 7 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - 58.0 - 108.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype812 - - - - org.contikios.cooja.interfaces.Position - -40.352178879596096 - 102.66976131212861 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype873 - - - - org.contikios.cooja.plugins.SimControl - 280 - 3 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 1.6480321712565114 0.0 0.0 1.6480321712565114 98.5016889738719 55.796930342384904 - - 400 - 0 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1184 - 2 - 500 - 402 - 162 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 904 - 4 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 612 - 1 - 726 - 953 - 43 - - - +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype921 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + -40.352178879596096 + 102.66976131212861 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype873 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 1.6480321712565114 0.0 0.0 1.6480321712565114 98.5016889738719 55.796930342384904 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 1 + 726 + 953 + 43 + + + diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc index 9468dd53e..2c0ce41ff 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc @@ -1,362 +1,360 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype672 - Sender - [CONFIG_DIR]/code/sender-node.c + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype672 + Sender + [CONFIG_DIR]/code/sender-node.c make clean TARGET=cooja -make sender-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype780 - RPL root - [CONFIG_DIR]/code/root-node.c +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype780 + RPL root + [CONFIG_DIR]/code/root-node.c make clean TARGET=cooja -make root-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype36 - Receiver - [CONFIG_DIR]/code/receiver-node.c +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype36 + Receiver + [CONFIG_DIR]/code/receiver-node.c make clean TARGET=cooja -make receiver-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - -7.199692787830563 - 98.21738321803603 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - 116.13379149678028 - 88.36698920455684 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype672 - - - - org.contikios.cooja.interfaces.Position - 12.0 - 68.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 4 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - 95.25095618820441 - 63.14998053005015 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 5 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - 66.09378990830604 - 38.32698761608261 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - 29.05630841762433 - 30.840688165838436 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 7 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - 58.0 - 108.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - -25.71843353317142 - 43.05517674255262 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype780 - - - - org.contikios.cooja.plugins.SimControl - 280 - 3 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 - - 400 - 2 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1184 - 1 - 500 - 402 - 162 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 904 - 4 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 612 - 0 - 726 - 953 - 43 - - - +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype672 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + -25.71843353317142 + 43.05517674255262 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype780 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 1 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 0 + 726 + 953 + 43 + + + diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc index 130eef941..cdb2bd748 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc @@ -1,362 +1,360 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype672 - Sender - [CONFIG_DIR]/code/sender-node.c + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype672 + Sender + [CONFIG_DIR]/code/sender-node.c make clean TARGET=cooja -make sender-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype780 - RPL root - [CONFIG_DIR]/code/root-node.c +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype780 + RPL root + [CONFIG_DIR]/code/root-node.c make clean TARGET=cooja -make root-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype36 - Receiver - [CONFIG_DIR]/code/receiver-node.c +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype36 + Receiver + [CONFIG_DIR]/code/receiver-node.c make clean TARGET=cooja -make receiver-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - -7.199692787830563 - 98.21738321803603 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - 116.13379149678028 - 88.36698920455684 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype672 - - - - org.contikios.cooja.interfaces.Position - 12.0 - 68.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 4 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - 95.25095618820441 - 63.14998053005015 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 5 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - 66.09378990830604 - 38.32698761608261 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - 29.05630841762433 - 30.840688165838436 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 7 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - 58.0 - 108.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - 16.0472370839803 - 6.017695251870905 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype780 - - - - org.contikios.cooja.plugins.SimControl - 280 - 3 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 - - 400 - 0 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1184 - 2 - 500 - 402 - 162 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 904 - 4 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 612 - 1 - 726 - 953 - 43 - - - +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype672 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 16.0472370839803 + 6.017695251870905 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype780 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 1 + 726 + 953 + 43 + + + diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc index d67d25f01..34b930c0d 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc @@ -1,362 +1,360 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype672 - Sender - [CONFIG_DIR]/code/sender-node.c + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype672 + Sender + [CONFIG_DIR]/code/sender-node.c make clean TARGET=cooja -make sender-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype780 - RPL root - [CONFIG_DIR]/code/root-node.c +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype780 + RPL root + [CONFIG_DIR]/code/root-node.c make clean TARGET=cooja -make root-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype36 - Receiver - [CONFIG_DIR]/code/receiver-node.c +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype36 + Receiver + [CONFIG_DIR]/code/receiver-node.c make clean TARGET=cooja -make receiver-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - -7.199692787830563 - 98.21738321803603 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - 116.13379149678028 - 88.36698920455684 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype672 - - - - org.contikios.cooja.interfaces.Position - 12.0 - 68.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 4 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - 95.25095618820441 - 63.14998053005015 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 5 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - 66.09378990830604 - 38.32698761608261 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - 29.05630841762433 - 30.840688165838436 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 7 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - 58.0 - 108.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype36 - - - - org.contikios.cooja.interfaces.Position - 79.48377453078622 - 4.835647970253402 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype780 - - - - org.contikios.cooja.plugins.SimControl - 280 - 3 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 2.5379695437350276 0.0 0.0 2.5379695437350276 70.27260101976269 60.72727272727276 - - 400 - 0 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1184 - 2 - 500 - 402 - 162 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 904 - 4 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 612 - 1 - 726 - 953 - 43 - - - +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype672 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 79.48377453078622 + 4.835647970253402 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype780 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 70.27260101976269 60.72727272727276 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 1 + 726 + 953 + 43 + + + diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc index bef4be8b8..ff9a400c1 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc @@ -1,362 +1,360 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype192 - Sender - [CONFIG_DIR]/code/sender-node.c + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype192 + Sender + [CONFIG_DIR]/code/sender-node.c make clean TARGET=cooja -make sender-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype575 - RPL root - [CONFIG_DIR]/code/root-node.c +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype575 + RPL root + [CONFIG_DIR]/code/root-node.c make clean TARGET=cooja -make root-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype912 - Receiver - [CONFIG_DIR]/code/receiver-node.c +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype912 + Receiver + [CONFIG_DIR]/code/receiver-node.c make clean TARGET=cooja -make receiver-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - -7.199692787830563 - 98.21738321803603 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype912 - - - - org.contikios.cooja.interfaces.Position - 116.13379149678028 - 88.36698920455684 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype192 - - - - org.contikios.cooja.interfaces.Position - 12.0 - 68.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 4 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype912 - - - - org.contikios.cooja.interfaces.Position - 95.25095618820441 - 63.14998053005015 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 5 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype912 - - - - org.contikios.cooja.interfaces.Position - 66.09378990830604 - 38.32698761608261 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype912 - - - - org.contikios.cooja.interfaces.Position - 29.05630841762433 - 30.840688165838436 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 7 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype912 - - - - org.contikios.cooja.interfaces.Position - 58.0 - 108.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype912 - - - - org.contikios.cooja.interfaces.Position - 122.82550819009461 - 29.658640884220933 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype575 - - - - org.contikios.cooja.plugins.SimControl - 280 - 3 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 2.5379695437350276 0.0 0.0 2.5379695437350276 70.27260101976269 60.72727272727276 - - 400 - 0 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1184 - 2 - 500 - 402 - 162 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 904 - 4 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 612 - 1 - 726 - 953 - 43 - - - +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype192 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 122.82550819009461 + 29.658640884220933 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype575 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 70.27260101976269 60.72727272727276 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 1 + 726 + 953 + 43 + + + diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc index c2623f780..e491b666f 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc @@ -1,362 +1,360 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - My simulation - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype372 - Sender - [CONFIG_DIR]/code/sender-node.c + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype372 + Sender + [CONFIG_DIR]/code/sender-node.c make clean TARGET=cooja -make sender-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype229 - RPL root - [CONFIG_DIR]/code/root-node.c +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype229 + RPL root + [CONFIG_DIR]/code/root-node.c make clean TARGET=cooja -make root-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - org.contikios.cooja.contikimote.ContikiMoteType - mtype424 - Receiver - [CONFIG_DIR]/code/receiver-node.c +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype424 + Receiver + [CONFIG_DIR]/code/receiver-node.c make clean TARGET=cooja -make receiver-node.cooja TARGET=cooja - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.Battery - org.contikios.cooja.contikimote.interfaces.ContikiVib - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - org.contikios.cooja.contikimote.interfaces.ContikiRS232 - org.contikios.cooja.contikimote.interfaces.ContikiBeeper - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.contikimote.interfaces.ContikiIPAddress - org.contikios.cooja.contikimote.interfaces.ContikiRadio - org.contikios.cooja.contikimote.interfaces.ContikiButton - org.contikios.cooja.contikimote.interfaces.ContikiPIR - org.contikios.cooja.contikimote.interfaces.ContikiClock - org.contikios.cooja.contikimote.interfaces.ContikiLED - org.contikios.cooja.contikimote.interfaces.ContikiCFS - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - false - - - - org.contikios.cooja.interfaces.Position - -7.199692787830563 - 98.21738321803603 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 1 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype424 - - - - org.contikios.cooja.interfaces.Position - 116.13379149678028 - 88.36698920455684 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 2 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype372 - - - - org.contikios.cooja.interfaces.Position - 12.0 - 68.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 4 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype424 - - - - org.contikios.cooja.interfaces.Position - 95.25095618820441 - 63.14998053005015 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 5 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype424 - - - - org.contikios.cooja.interfaces.Position - 66.09378990830604 - 38.32698761608261 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 6 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype424 - - - - org.contikios.cooja.interfaces.Position - 29.05630841762433 - 30.840688165838436 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 7 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype424 - - - - org.contikios.cooja.interfaces.Position - 58.0 - 108.0 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 8 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype424 - - - - org.contikios.cooja.interfaces.Position - 145.93059238811136 - 111.16474110935306 - 0.0 - - - org.contikios.cooja.contikimote.interfaces.ContikiMoteID - 3 - - - org.contikios.cooja.contikimote.interfaces.ContikiRadio - 250.0 - - mtype229 - - - - org.contikios.cooja.plugins.SimControl - 280 - 3 - 160 - 400 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - 1.6480321712565114 0.0 0.0 1.6480321712565114 98.5016889738719 55.796930342384904 - - 400 - 0 - 400 - 1 - 1 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1184 - 2 - 500 - 402 - 162 - - - org.contikios.cooja.plugins.Notes - - Enter notes here - true - - 904 - 4 - 160 - 680 - 0 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 612 - 1 - 726 - 953 - 43 - - - +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype372 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 145.93059238811136 + 111.16474110935306 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype229 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 1.6480321712565114 0.0 0.0 1.6480321712565114 98.5016889738719 55.796930342384904 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 1 + 726 + 953 + 43 + + + diff --git a/regression-tests/12-rpl/09-rpl-probing.csc b/regression-tests/12-rpl/09-rpl-probing.csc new file mode 100644 index 000000000..66a156e9c --- /dev/null +++ b/regression-tests/12-rpl/09-rpl-probing.csc @@ -0,0 +1,256 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype190 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype481 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype692 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 8.0 + 2.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype481 + + + + org.contikios.cooja.interfaces.Position + -7.19071602882406 + 34.96668248624779 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype190 + + + + org.contikios.cooja.interfaces.Position + -17.870288882812428 + 4.581754854333804 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype692 + + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.494541140753371 0.0 0.0 2.494541140753371 168.25302383129448 116.2254386098645 + + 400 + 3 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 597 + 0 + 428 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 605 + 1 + 684 + 604 + 14 + + + diff --git a/regression-tests/12-rpl/10-rpl-multi-dodag.csc b/regression-tests/12-rpl/10-rpl-multi-dodag.csc new file mode 100644 index 000000000..0f446cc65 --- /dev/null +++ b/regression-tests/12-rpl/10-rpl-multi-dodag.csc @@ -0,0 +1,389 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + [APPS_DIR]/serial2pty + [APPS_DIR]/radiologger-headless + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype301 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype820 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype306 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 9.767954940345236 + 88.75813939592845 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype306 + + + + org.contikios.cooja.interfaces.Position + 63.36720084537501 + 75.88456991067605 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype301 + + + + org.contikios.cooja.interfaces.Position + -20.684049350551753 + 60.49767834794315 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype306 + + + + org.contikios.cooja.interfaces.Position + 64.61229064867878 + 39.88729002781773 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype306 + + + + org.contikios.cooja.interfaces.Position + 37.157272454309606 + 19.60335867526139 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype306 + + + + org.contikios.cooja.interfaces.Position + -21.976612887408603 + 30.69884249204435 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype306 + + + + org.contikios.cooja.interfaces.Position + 43 + 98 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype820 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype820 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 1.7624788498159916 0.0 0.0 1.7624788498159916 97.6893062637241 8.72727272727273 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 1 + 596 + 603 + 43 + + + diff --git a/regression-tests/12-rpl/code/Makefile b/regression-tests/12-rpl/code/Makefile index cfe24a53b..616341592 100644 --- a/regression-tests/12-rpl/code/Makefile +++ b/regression-tests/12-rpl/code/Makefile @@ -1,9 +1,7 @@ all: sender-node receiver-node root-node CONTIKI=../../.. -UIP_CONF_IPV6=1 -CFLAGS+= -DUIP_CONF_IPV6_RPL - CFLAGS+=-DPROJECT_CONF_H=\"project-conf.h\" +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/regression-tests/12-rpl/code/receiver-node.c b/regression-tests/12-rpl/code/receiver-node.c index 25e1e6758..727a23f84 100644 --- a/regression-tests/12-rpl/code/receiver-node.c +++ b/regression-tests/12-rpl/code/receiver-node.c @@ -73,7 +73,7 @@ set_global_address(void) int i; uint8_t state; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); @@ -92,7 +92,7 @@ set_global_address(void) /*---------------------------------------------------------------------------*/ uint8_t should_blink = 1; static void -route_callback(int event, uip_ipaddr_t *route, uip_ipaddr_t *ipaddr) +route_callback(int event, uip_ipaddr_t *route, uip_ipaddr_t *ipaddr, int num_routes) { if(event == UIP_DS6_NOTIFICATION_DEFRT_ADD) { should_blink = 0; @@ -105,11 +105,10 @@ PROCESS_THREAD(receiver_node_process, ev, data) { static struct etimer et; static struct uip_ds6_notification n; - uip_ipaddr_t *ipaddr; PROCESS_BEGIN(); - ipaddr = set_global_address(); + set_global_address(); uip_ds6_notification_add(&n, route_callback); diff --git a/regression-tests/12-rpl/code/root-node.c b/regression-tests/12-rpl/code/root-node.c index 0609e1bd8..fdea828f8 100644 --- a/regression-tests/12-rpl/code/root-node.c +++ b/regression-tests/12-rpl/code/root-node.c @@ -77,7 +77,7 @@ set_global_address(void) int i; uint8_t state; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); @@ -106,7 +106,7 @@ create_rpl_dag(uip_ipaddr_t *ipaddr) rpl_set_root(RPL_DEFAULT_INSTANCE, ipaddr); dag = rpl_get_any_dag(); - uip_ip6addr(&prefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); rpl_set_prefix(dag, &prefix, 64); PRINTF("created a new RPL dag\n"); } else { diff --git a/regression-tests/12-rpl/code/sender-node.c b/regression-tests/12-rpl/code/sender-node.c index 08d81b62d..55dfdd15f 100644 --- a/regression-tests/12-rpl/code/sender-node.c +++ b/regression-tests/12-rpl/code/sender-node.c @@ -72,7 +72,7 @@ set_global_address(void) int i; uint8_t state; - uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); @@ -109,7 +109,7 @@ PROCESS_THREAD(sender_node_process, ev, data) PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&send_timer)); - uip_ip6addr(&addr, 0xaaaa, 0, 0, 0, 0x0201, 0x001, 0x001, 0x001); + uip_ip6addr(&addr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0x0201, 0x001, 0x001, 0x001); { static unsigned int message_number; diff --git a/regression-tests/13-ipv6-apps/01-sky-servreg-hack.csc b/regression-tests/13-ipv6-apps/01-sky-servreg-hack.csc index e5073c1f9..8e9e36011 100644 --- a/regression-tests/13-ipv6-apps/01-sky-servreg-hack.csc +++ b/regression-tests/13-ipv6-apps/01-sky-servreg-hack.csc @@ -1,316 +1,316 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - Servreg hack test - 123456 - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 40.0 - 40.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - sky1 - Servreg server - [CONTIKI_DIR]/examples/servreg-hack/example-servreg-server.c - make example-servreg-server.sky TARGET=sky - [CONTIKI_DIR]/examples/servreg-hack/example-servreg-server.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - sky2 - Servreg hack client - [CONTIKI_DIR]/examples/servreg-hack/example-servreg-client.c - make example-servreg-client.sky TARGET=sky - [CONTIKI_DIR]/examples/servreg-hack/example-servreg-client.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.Msp802154Radio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 45.693987609497896 - 26.353051242505675 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - org.contikios.cooja.interfaces.Position - 18.451397050087735 - 55.93074152489276 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 45.082598269523864 - 52.7178388400784 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 3 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 11.116935333105516 - 49.070534908051414 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 4 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 85.11866272622683 - 30.030092430999066 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 5 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 30.71302161006234 - 13.877842534368446 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 6 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 44.43705509785284 - 69.81167027376168 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 7 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 64.10992023465046 - 20.589540162635835 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 8 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 32.29787406276132 - 18.754900913594753 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 9 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 25.28398611019028 - 69.27186586570369 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 10 - - sky2 - - - - - org.contikios.cooja.interfaces.Position - 19.3359466030565 - 17.321986704081503 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 11 - - sky2 - - - - org.contikios.cooja.plugins.SimControl - 318 - 1 - 172 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - org.contikios.cooja.plugins.skins.AttributeVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - 3.56257040103728 0.0 0.0 3.56257040103728 -26.423046586149052 -28.07489060373735 - - 300 - 2 - 300 - 1140 - 0 - - - org.contikios.cooja.plugins.LogListener - - - - - - 1440 - 3 - 324 - 2 - 270 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - - - 1633.2339825135305 - - 1440 - 4 - 238 - 0 - 595 - - - org.contikios.cooja.plugins.ScriptRunner - - - true - - 600 - 0 - 700 - 526 - 6 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + Servreg hack test + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 40.0 + 40.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + sky1 + Servreg server + [CONTIKI_DIR]/examples/servreg-hack/example-servreg-server.c + make example-servreg-server.sky TARGET=sky + [CONTIKI_DIR]/examples/servreg-hack/example-servreg-server.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + sky2 + Servreg hack client + [CONTIKI_DIR]/examples/servreg-hack/example-servreg-client.c + make example-servreg-client.sky TARGET=sky + [CONTIKI_DIR]/examples/servreg-hack/example-servreg-client.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 45.693987609497896 + 26.353051242505675 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + org.contikios.cooja.interfaces.Position + 18.451397050087735 + 55.93074152489276 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 45.082598269523864 + 52.7178388400784 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 11.116935333105516 + 49.070534908051414 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 4 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 85.11866272622683 + 30.030092430999066 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 5 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 30.71302161006234 + 13.877842534368446 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 6 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 44.43705509785284 + 69.81167027376168 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 7 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 64.10992023465046 + 20.589540162635835 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 8 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 32.29787406276132 + 18.754900913594753 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 9 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 25.28398611019028 + 69.27186586570369 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 10 + + sky2 + + + + + org.contikios.cooja.interfaces.Position + 19.3359466030565 + 17.321986704081503 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 11 + + sky2 + + + + org.contikios.cooja.plugins.SimControl + 318 + 1 + 172 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + 3.56257040103728 0.0 0.0 3.56257040103728 -26.423046586149052 -28.07489060373735 + + 300 + 2 + 300 + 1140 + 0 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1440 + 3 + 324 + 2 + 270 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + + + 1633.2339825135305 + + 1440 + 4 + 238 + 0 + 595 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 0 + 700 + 526 + 6 + + + diff --git a/regression-tests/13-ipv6-apps/x02-sky-coap.csc b/regression-tests/13-ipv6-apps/x02-sky-coap.csc index d39a604c0..d3d284a2d 100644 --- a/regression-tests/13-ipv6-apps/x02-sky-coap.csc +++ b/regression-tests/13-ipv6-apps/x02-sky-coap.csc @@ -1,222 +1,222 @@ - - - - REST with RPL router - -2147483648 - generated - 1000000 - - org.contikios.cooja.radiomediums.UDGM - 50.0 - 50.0 - 1.0 - 1.0 - - - 40000 - - - org.contikios.cooja.mspmote.SkyMoteType - rplroot - Sky RPL Root - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky DEFINES=NETSTACK_MAC=nullmac_driver,NETSTACK_RDC=nullrdc_driver,NULLRDC_CONF_802154_AUTOACK=0,CC2420_CONF_AUTOACK=0,ENERGEST_CONF_ON=0,PROCESS_CONF_NO_PROCESS_NAMES=1 - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - org.contikios.cooja.mspmote.SkyMoteType - skyweb - Rest server - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c - make er-example-server.sky TARGET=sky DEFINES=NETSTACK_MAC=nullmac_driver,NETSTACK_RDC=nullrdc_driver,NULLRDC_CONF_802154_AUTOACK=0,CC2420_CONF_AUTOACK=0,ENERGEST_CONF_ON=0,PROCESS_CONF_NO_PROCESS_NAMES=1 - [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky - org.contikios.cooja.interfaces.Position - org.contikios.cooja.interfaces.RimeAddress - org.contikios.cooja.interfaces.IPAddress - org.contikios.cooja.interfaces.Mote2MoteRelations - org.contikios.cooja.interfaces.MoteAttributes - org.contikios.cooja.mspmote.interfaces.MspClock - org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem - org.contikios.cooja.mspmote.interfaces.SkyByteRadio - org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED - org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - - - - - org.contikios.cooja.interfaces.Position - 33.260163187353555 - 30.643217359962595 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 1 - - rplroot - - - - - org.contikios.cooja.interfaces.Position - 35.100895239785295 - 39.70574552287428 - 0.0 - - - org.contikios.cooja.mspmote.interfaces.MspMoteID - 2 - - skyweb - - - - org.contikios.cooja.plugins.SimControl - 259 - 6 - 179 - 0 - 0 - - - org.contikios.cooja.plugins.Visualizer - - org.contikios.cooja.plugins.skins.IDVisualizerSkin - org.contikios.cooja.plugins.skins.UDGMVisualizerSkin - org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin - org.contikios.cooja.plugins.skins.AttributeVisualizerSkin - org.contikios.cooja.plugins.skins.AddressVisualizerSkin - org.contikios.cooja.plugins.skins.GridVisualizerSkin - 3.3323852179491644 0.0 0.0 3.3323852179491644 -30.392247168885415 -60.79227000363299 - - 176 - 5 - 173 - 259 - 3 - - - org.contikios.cooja.plugins.LogListener - - - - - 576 - 0 - 492 - 12 - 260 - - - org.contikios.cooja.plugins.RadioLogger - - 114 - - - 574 - -1 - 471 - 412 - 190 - true - - - SerialSocketServer - 0 - 428 - 4 - 74 - 7 - 181 - - - org.contikios.cooja.plugins.TimeLine - - 0 - 1 - - - 23 - 24060.2737326431 - - 579 - 2 - 152 - 6 - 758 - - - org.contikios.cooja.plugins.Notes - - Nightly test exercising Contiki's Erbium CoAP implementation: -* One REST server, and one RPL border router w. corresponding tun0 netif -* ContikiMAC is disabled to make firmwares fit on Tmote Sky nodes. -* Additional compile-time DEFINES used in this simulation: -NETSTACK_MAC=nullmac_driver -NETSTACK_RDC=nullrdc_driver -NULLRDC_CONF_802154_AUTOACK=0 -CC2420_CONF_AUTOACK=0 -ENERGEST_CONF_ON=0 -PROCESS_CONF_NO_PROCESS_NAMES=1 - -The test script communicates with the REST server via the RPL border router using external commands. -(* $ make connect-router-cooja) -* $ ping6 -c 10 -I tun0 aaaa::212:7401:1:101 -* $ ping6 -c 10 -I tun0 aaaa::212:7402:2:202 -* $ wget -t 1 -T 10 -O - http://[aaaa::212:7402:2:202] - -The final test uses the CoAP Java implementation by Matthias Kovatsch, downloaded from: -https://github.com/mkovatsc/Californium/blob/master/run/ExampleClient.jar -* $ java -jar ExampleClient.jar DISCOVER coap://[aaaa::212:7402:2:202] -* $ java -jar ExampleClient.jar GET coap://[aaaa::212:7402:2:202]/hello - true - - 751 - 3 - 369 - 439 - 3 - - - org.contikios.cooja.plugins.ScriptRunner - - [CONFIG_DIR]/rest_rpl_coap.js - true - - 596 - 1 - 725 - 591 - 225 - - - PowerTracker - 400 - -1 - 155 - 132 - 152 - true - - - + + + + REST with RPL router + -2147483648 + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky DEFINES=NETSTACK_MAC=nullmac_driver,NETSTACK_RDC=nullrdc_driver,NULLRDC_CONF_802154_AUTOACK=0,CC2420_CONF_AUTOACK=0,ENERGEST_CONF_ON=0,PROCESS_CONF_NO_PROCESS_NAMES=1 + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + org.contikios.cooja.mspmote.SkyMoteType + skyweb + Rest server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky DEFINES=NETSTACK_MAC=nullmac_driver,NETSTACK_RDC=nullrdc_driver,NULLRDC_CONF_802154_AUTOACK=0,CC2420_CONF_AUTOACK=0,ENERGEST_CONF_ON=0,PROCESS_CONF_NO_PROCESS_NAMES=1 + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.SkyButton + org.contikios.cooja.mspmote.interfaces.SkyFlash + org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspSerial + org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + org.contikios.cooja.mspmote.interfaces.SkyTemperature + + + + + org.contikios.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + org.contikios.cooja.interfaces.Position + 35.100895239785295 + 39.70574552287428 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + skyweb + + + + org.contikios.cooja.plugins.SimControl + 259 + 6 + 179 + 0 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + org.contikios.cooja.plugins.skins.AddressVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + 3.3323852179491644 0.0 0.0 3.3323852179491644 -30.392247168885415 -60.79227000363299 + + 176 + 5 + 173 + 259 + 3 + + + org.contikios.cooja.plugins.LogListener + + + + + 576 + 0 + 492 + 12 + 260 + + + org.contikios.cooja.plugins.RadioLogger + + 114 + + + 574 + -1 + 471 + 412 + 190 + true + + + org.contikios.cooja.serialsocket.SerialSocketServer + 0 + 428 + 4 + 74 + 7 + 181 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + + + 23 + 24060.2737326431 + + 579 + 2 + 152 + 6 + 758 + + + org.contikios.cooja.plugins.Notes + + Nightly test exercising Contiki's Erbium CoAP implementation: +* One REST server, and one RPL border router w. corresponding tun0 netif +* ContikiMAC is disabled to make firmwares fit on Tmote Sky nodes. +* Additional compile-time DEFINES used in this simulation: +NETSTACK_MAC=nullmac_driver +NETSTACK_RDC=nullrdc_driver +NULLRDC_CONF_802154_AUTOACK=0 +CC2420_CONF_AUTOACK=0 +ENERGEST_CONF_ON=0 +PROCESS_CONF_NO_PROCESS_NAMES=1 + +The test script communicates with the REST server via the RPL border router using external commands. +(* $ make connect-router-cooja) +* $ ping6 -c 10 -I tun0 fd00::212:7401:1:101 +* $ ping6 -c 10 -I tun0 fd00::212:7402:2:202 +* $ wget -t 1 -T 10 -O - http://[fd00::212:7402:2:202] + +The final test uses the CoAP Java implementation by Matthias Kovatsch, downloaded from: +https://github.com/mkovatsc/Californium/blob/master/run/ExampleClient.jar +* $ java -jar ExampleClient.jar DISCOVER coap://[fd00::212:7402:2:202] +* $ java -jar ExampleClient.jar GET coap://[fd00::212:7402:2:202]/hello + true + + 751 + 3 + 369 + 439 + 3 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONFIG_DIR]/rest_rpl_coap.js + true + + 596 + 1 + 725 + 591 + 225 + + + PowerTracker + 400 + -1 + 155 + 132 + 152 + true + + + diff --git a/regression-tests/15-compile-arm-apcs-ports/Makefile b/regression-tests/15-compile-arm-apcs-ports/Makefile new file mode 100644 index 000000000..1ae39b62a --- /dev/null +++ b/regression-tests/15-compile-arm-apcs-ports/Makefile @@ -0,0 +1,16 @@ +EXAMPLESDIR=../../examples +TOOLSDIR=../../tools + +EXAMPLES = \ +hello-world/econotag \ +hello-world/mbxxx:STM32W_CPUREV=CC \ +ipv6/rpl-border-router/econotag \ +er-rest-example/econotag \ +webserver-ipv6/econotag \ +ipv6/multicast/econotag \ +econotag-flash-test/econotag \ +econotag-ecc-test/econotag \ + +TOOLS= + +include ../Makefile.compile-test diff --git a/regression-tests/15-compile-arm-ports/Makefile b/regression-tests/15-compile-arm-ports/Makefile deleted file mode 100644 index 572489d8a..000000000 --- a/regression-tests/15-compile-arm-ports/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -EXAMPLESDIR=../../examples -TOOLSDIR=../../tools - -EXAMPLES = \ -hello-world/econotag \ -hello-world/mbxxx \ -hello-world/cc2538dk \ -ipv6/rpl-border-router/econotag \ -ipv6/rpl-border-router/cc2538dk \ -er-rest-example/econotag \ -er-rest-example/cc2538dk \ -webserver-ipv6/econotag \ -webserver-ipv6/cc2538dk \ -cc2538dk/cc2538dk \ -cc2538dk/udp-ipv6-echo-server/cc2538dk \ -cc2538dk/sniffer/cc2538dk \ -ipv6/multicast/econotag \ -ipv6/multicast/cc2538dk \ - -TOOLS= - -include ../Makefile.compile-test diff --git a/regression-tests/16-compile-6502-ports/Makefile b/regression-tests/16-compile-6502-ports/Makefile index 78e702e44..5fdb0c986 100644 --- a/regression-tests/16-compile-6502-ports/Makefile +++ b/regression-tests/16-compile-6502-ports/Makefile @@ -2,19 +2,19 @@ EXAMPLESDIR=../../examples TOOLSDIR=../../tools EXAMPLES = \ -email/c64 \ -ftp/c64 \ irc/c64 \ +irc-80col/c64 \ telnet-server/c64 \ -wget/c64 \ webbrowser/c64 \ -webbrowser/c128 \ -webbrowser/atarixl \ -webbrowser/apple2enh \ -webserver/c64 \ -webserver/c128 \ -webserver/atarixl \ -webserver/apple2enh \ +webbrowser-80col/c64 \ +webserver/c64:HTTPD-CFS=1 \ +wget/c64 \ +telnet-server/apple2enh \ +telnet-server/atarixl \ +telnet-server/c128 \ +webbrowser-80col/apple2enh \ +webbrowser-80col/atarixl \ +webbrowser-80col/c128 \ TOOLS= diff --git a/regression-tests/17-slip-radio/01-sky-slip-radio-dio.csc b/regression-tests/17-slip-radio/01-sky-slip-radio-dio.csc index 02a7a3aae..5f28d4348 100644 --- a/regression-tests/17-slip-radio/01-sky-slip-radio-dio.csc +++ b/regression-tests/17-slip-radio/01-sky-slip-radio-dio.csc @@ -1,190 +1,190 @@ - - - [APPS_DIR]/mrm - [APPS_DIR]/mspsim - [APPS_DIR]/avrora - [APPS_DIR]/serial_socket - [APPS_DIR]/collect-view - [APPS_DIR]/powertracker - - slip radio 1 - 123456 - 1000000 - - se.sics.cooja.radiomediums.UDGM - 15.0 - 15.0 - 1.0 - 1.0 - - - 40000 - - - se.sics.cooja.mspmote.SkyMoteType - sky1 - slip radio - [CONTIKI_DIR]/examples/ipv6/slip-radio/slip-radio.c - make slip-radio.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/slip-radio/slip-radio.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.Msp802154Radio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - se.sics.cooja.mspmote.SkyMoteType - sky2 - wait-dag - [CONTIKI_DIR]/regression-tests/17-slip-radio/code/wait-dag.c - make wait-dag.sky TARGET=sky - [CONTIKI_DIR]/regression-tests/17-slip-radio/code/wait-dag.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.RimeAddress - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.interfaces.MoteAttributes - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem - se.sics.cooja.mspmote.interfaces.Msp802154Radio - se.sics.cooja.mspmote.interfaces.MspSerial - se.sics.cooja.mspmote.interfaces.SkyLED - se.sics.cooja.mspmote.interfaces.MspDebugOutput - se.sics.cooja.mspmote.interfaces.SkyTemperature - - - - - se.sics.cooja.interfaces.Position - 43.565500781711165 - 14.697933087406794 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - sky1 - - - - - se.sics.cooja.interfaces.Position - 53.849666651434326 - 14.629826028666905 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 2 - - sky2 - - - - se.sics.cooja.plugins.SimControl - 315 - 1 - 175 - 433 - 0 - - - se.sics.cooja.plugins.Visualizer - - se.sics.cooja.plugins.skins.IDVisualizerSkin - se.sics.cooja.plugins.skins.GridVisualizerSkin - se.sics.cooja.plugins.skins.TrafficVisualizerSkin - se.sics.cooja.plugins.skins.UDGMVisualizerSkin - 14.682765905648006 0.0 0.0 14.682765905648006 -512.6620495401903 -96.80631081927221 - - 432 - 4 - 291 - 1 - 1 - - - se.sics.cooja.plugins.LogListener - - - - 758 - 3 - 289 - 748 - 159 - - - se.sics.cooja.plugins.Notes - - Slip-radio Tests, 01-sky-slip-radio-dio - -Test that we can send a packet over a slip-radio. -In this basic test, we send a DIO from mote 1, and wait for "DAG Found" in mote 2. - true - - 928 - 5 - 159 - 749 - -1 - - - se.sics.cooja.plugins.ScriptRunner - - - true - - 758 - 2 - 502 - 749 - 449 - - - se.sics.cooja.plugins.RadioLogger - - 150 - - 746 - 0 - 657 - 3 - 294 - - - + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + slip radio 1 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 15.0 + 15.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + sky1 + slip radio + [CONTIKI_DIR]/examples/ipv6/slip-radio/slip-radio.c + make slip-radio.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/slip-radio/slip-radio.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.Msp802154Radio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + sky2 + wait-dag + [CONTIKI_DIR]/regression-tests/17-slip-radio/code/wait-dag.c + make wait-dag.sky TARGET=sky + [CONTIKI_DIR]/regression-tests/17-slip-radio/code/wait-dag.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.Msp802154Radio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 43.565500781711165 + 14.697933087406794 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 53.849666651434326 + 14.629826028666905 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + sky2 + + + + se.sics.cooja.plugins.SimControl + 315 + 1 + 175 + 433 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.GridVisualizerSkin + se.sics.cooja.plugins.skins.TrafficVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + 14.682765905648006 0.0 0.0 14.682765905648006 -512.6620495401903 -96.80631081927221 + + 432 + 4 + 291 + 1 + 1 + + + se.sics.cooja.plugins.LogListener + + + + 758 + 3 + 289 + 748 + 159 + + + se.sics.cooja.plugins.Notes + + Slip-radio Tests, 01-sky-slip-radio-dio + +Test that we can send a packet over a slip-radio. +In this basic test, we send a DIO from mote 1, and wait for "DAG Found" in mote 2. + true + + 928 + 5 + 159 + 749 + -1 + + + se.sics.cooja.plugins.ScriptRunner + + + true + + 758 + 2 + 502 + 749 + 449 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + 746 + 0 + 657 + 3 + 294 + + + diff --git a/regression-tests/17-slip-radio/code/Makefile b/regression-tests/17-slip-radio/code/Makefile index d1db363eb..12e72d165 100644 --- a/regression-tests/17-slip-radio/code/Makefile +++ b/regression-tests/17-slip-radio/code/Makefile @@ -2,8 +2,5 @@ all: wait-dag APPS=servreg-hack CONTIKI=../../.. -WITH_UIP6=1 -UIP_CONF_IPV6=1 -CFLAGS+= -DUIP_CONF_IPV6_RPL - +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/regression-tests/18-compile-arm-ports/Makefile b/regression-tests/18-compile-arm-ports/Makefile new file mode 100644 index 000000000..e0addfa9f --- /dev/null +++ b/regression-tests/18-compile-arm-ports/Makefile @@ -0,0 +1,56 @@ +EXAMPLESDIR=../../examples +TOOLSDIR=../../tools + +EXAMPLES = \ +hello-world/ev-aducrf101mkxz \ +ipv6/rpl-border-router/ev-aducrf101mkxz \ +webserver-ipv6/ev-aducrf101mkxz \ +ipv6/multicast/ev-aducrf101mkxz \ +cc2538-common/sniffer/ev-aducrf101mkxz \ +cc26xx/cc26xx-web-demo/srf06-cc26xx \ +cc26xx/very-sleepy-demo/srf06-cc26xx:BOARD=sensortag/cc2650 \ +cc26xx/cc26xx-web-demo/srf06-cc26xx:BOARD=sensortag/cc2650 \ +cc26xx/cc26xx-web-demo/srf06-cc26xx:BOARD=srf06/cc13xx \ +cc26xx/cc26xx-web-demo/srf06-cc26xx:BOARD=launchpad/cc2650 \ +cc26xx/cc26xx-web-demo/srf06-cc26xx:BOARD=launchpad/cc1310 \ +cc26xx/very-sleepy-demo/srf06-cc26xx \ +hello-world/cc2538dk \ +ipv6/rpl-border-router/cc2538dk \ +ipv6/rpl-border-router/cc2538dk:MAKE_WITH_NON_STORING=1 \ +er-rest-example/cc2538dk \ +ipso-objects/cc2538dk \ +webserver-ipv6/cc2538dk \ +cc2538dk/cc2538dk \ +cc2538dk/udp-ipv6-echo-server/cc2538dk \ +ipv6/multicast/cc2538dk \ +cc2538-common/cc2538dk \ +cc2538-common/sniffer/cc2538dk \ +cc2538-common/mqtt-demo/cc2538dk \ +cc2538-common/crypto/cc2538dk \ +cc2538-common/pka/cc2538dk \ +cc2538-common/zoul \ +cc2538-common/sniffer/zoul \ +cc2538-common/mqtt-demo/zoul \ +cc2538-common/crypto/zoul \ +cc2538-common/pka/zoul \ +zolertia/zoul/zoul \ +zolertia/zoul/cc1200-demo/zoul \ +openmote-cc2538/openmote-cc2538 \ +er-rest-example/zoul \ +ipso-objects/zoul \ +hello-world/zoul \ +er-rest-example/stm32nucleo-spirit1 \ +ipv6/rpl-border-router/stm32nucleo-spirit1 \ +ipv6/rpl-udp/stm32nucleo-spirit1 \ +ipv6/simple-udp-rpl/stm32nucleo-spirit1 \ +stm32nucleo-spirit1/sensor-demo/stm32nucleo-spirit1 \ +ipv6/multicast/stm32nucleo-spirit1 \ +udp-ipv6/stm32nucleo-spirit1 \ +hello-world/stm32nucleo-spirit1 \ +cfs-coffee/cc2538dk \ +cfs-coffee/openmote-cc2538 \ +cfs-coffee/zoul + +TOOLS= + +include ../Makefile.compile-test diff --git a/regression-tests/19-llsec/01-ccm-star.csc b/regression-tests/19-llsec/01-ccm-star.csc new file mode 100644 index 000000000..66f5f80f6 --- /dev/null +++ b/regression-tests/19-llsec/01-ccm-star.csc @@ -0,0 +1,187 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + llsec validation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype139 + Verification + [CONTIKI_DIR]/examples/llsec/ccm-star-tests/verification/tests.c + make tests.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype792 + Encryption + [CONTIKI_DIR]/examples/llsec/ccm-star-tests/encryption/tests.c + make tests.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 8.103036578104216 + 28.0005728229897 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== + + mtype139 + + + + org.contikios.cooja.interfaces.Position + 87.3441626132979 + 25.080887412193555 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== + + mtype792 + + + + org.contikios.cooja.plugins.SimControl + 280 + 4 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 4.451315754531486 0.0 0.0 4.451315754531486 -18.43281074329661 54.85882989079608 + + 400 + 3 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + Success + + + + 1520 + 2 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.Notes + + A simple test script that runs the tests in examples/llsec/ccm-star-tests/ + true + + 1240 + 0 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 600 + 1 + 700 + 288 + 199 + + + diff --git a/regression-tests/19-llsec/Makefile b/regression-tests/19-llsec/Makefile new file mode 100644 index 000000000..272bc7da1 --- /dev/null +++ b/regression-tests/19-llsec/Makefile @@ -0,0 +1 @@ +include ../Makefile.simulation-test diff --git a/regression-tests/20-compile-osd-ports/Makefile b/regression-tests/20-compile-osd-ports/Makefile new file mode 100644 index 000000000..26224a1b5 --- /dev/null +++ b/regression-tests/20-compile-osd-ports/Makefile @@ -0,0 +1,55 @@ + +EXAMPLESDIR=../../examples +TOOLSDIR=../../tools + +EXAMPLES = \ +hello-world/osd-merkur-128 \ +osd/er-rest-example-merkurboard/osd-merkur-128 \ +osd/rpl-border-router/osd-merkur-128 \ +osd/slip-radio/osd-merkur-128 \ +osd/arduino-dooralert/osd-merkur-128 \ +osd/arduino-merkurboard/osd-merkur-128 \ +osd/arduino-plantobserving/osd-merkur-128 \ +osd/arduino-roomalert/osd-merkur-128 \ +osd/arduino-sketch/osd-merkur-128 \ +osd/arduino-wateralert/osd-merkur-128 \ +osd/climate/osd-merkur-128 \ +osd/climate2/osd-merkur-128 \ +osd/servo-sensor/osd-merkur-128 \ +osd/pingtheplug/osd-merkur-128 \ +osd/powerbox/osd-merkur-128 \ +osd/embedd-vm-merkurboard/osd-merkur-128 \ +osd/light-actor/osd-merkur-128 \ +hello-world/osd-merkur-256 \ +osd/er-rest-example-merkurboard/osd-merkur-256 \ +osd/rpl-border-router/osd-merkur-256 \ +osd/slip-radio/osd-merkur-256 \ +osd/arduino-dooralert/osd-merkur-256 \ +osd/arduino-merkurboard/osd-merkur-256 \ +osd/arduino-plantobserving/osd-merkur-256 \ +osd/arduino-roomalert/osd-merkur-256 \ +osd/arduino-sketch/osd-merkur-256 \ +osd/arduino-wateralert/osd-merkur-256 \ +osd/climate/osd-merkur-256 \ +osd/climate2/osd-merkur-256 \ +osd/servo-sensor/osd-merkur-256 \ +osd/pingtheplug/osd-merkur-256 \ +osd/powerbox/osd-merkur-256 \ +osd/embedd-vm-merkurboard/osd-merkur-256 \ +osd/light-actor/osd-merkur-256 \ + +#osd/dual-rgbw-actor/osd-merkur-128 \ +#osd/light-shutter-control/osd-merkur-128 \ +#osd/pir-sensor/osd-merkur-128 \ +#osd/pwm-example/osd-merkur-128 \ +#osd/wallclock-timer/osd-merkur-128 \ + +#osd/dual-rgbw-actor/osd-merkur-256 \ +#osd/light-shutter-control/osd-merkur-256 \ +#osd/pir-sensor/osd-merkur-256 \ +#osd/pwm-example/osd-merkur-256 \ +#osd/wallclock-timer/osd-merkur-256 \ + +TOOLS= + +include ../Makefile.compile-test diff --git a/regression-tests/20-compile-tools/Makefile b/regression-tests/20-compile-tools/Makefile new file mode 100644 index 000000000..d73dde44d --- /dev/null +++ b/regression-tests/20-compile-tools/Makefile @@ -0,0 +1,72 @@ +# Copyright (c) 2014, Friedrich-Alexander University Erlangen-Nuremberg +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. 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. +# 3. Neither the name of the University 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 UNIVERSITY 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 INSTITUTE 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. + +TOOLS=sky tools stm32w z80=hex2bin +FAILTOOLS=stm32w=uip6_bridge sky=uip6-bridge + + +TOOLSDIR=../../tools +LOGS=$(patsubst %,%.log, $(TOOLS)) + +all: summary + +FRC: + + +sky.log: RMFILES=serialdump-linux +stm32w.log: RMFILES=serialdump-linux + + +tools.log: + @$(MAKE) -C $(TOOLSDIR) > $@ 2>&1 && $(RM) $@.failed || touch $@.failed + + +%.log: FRC + @( cd $(TOOLSDIR)/$(subst =,/,$*) && $(RM) $(RMFILES) ) + @touch $@ + @$(MAKE) -C $(TOOLSDIR)/$(subst =,/,$*) > $@ 2>&1 && $(RM) $@.failed || touch $@.failed + + +summary: $(LOGS) + @(\ + for T in $(TOOLS) ; do \ + if [ -f $$T.log.failed ] ; then \ + echo tools/$$T: FAIL ಠ_ಠ >> $@;\ + cat $$T.log >> $@;\ + else \ + echo tools/$$T: OK >> $@;\ + fi\ + done \ + ) + @echo "Info: The following tools need fixing and are not tested:" $(subst =,/,$(FAILTOOLS)) >> $@ + @echo $@ + +clean: + @make -C $(DOCDIR) clean + + +.PHONY: %.log diff --git a/regression-tests/20-ip64/01-cooja-ip64-http-socket.csc b/regression-tests/20-ip64/01-cooja-ip64-http-socket.csc new file mode 100644 index 000000000..cec228b5e --- /dev/null +++ b/regression-tests/20-ip64/01-cooja-ip64-http-socket.csc @@ -0,0 +1,245 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 1.0 + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype503 + ip64-router/ip64-router.c TARGET=cooja-ip64 + [CONTIKI_DIR]/examples/ip64-router/ip64-router.c + make ip64-router.cooja-ip64 TARGET=cooja-ip64 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype555 + examples/http-socket/http-example.c + [CONTIKI_DIR]/examples/http-socket/http-example.c + make http-example.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 55.719691912311305 + 37.8697579181178 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype503 + + + + org.contikios.cooja.interfaces.Position + 65.60514720922419 + 33.88871867406431 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype555 + + + + org.contikios.cooja.plugins.SimControl + 280 + 1 + 160 + 606 + 15 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.LEDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 8.230641272440463 0.0 0.0 8.230641272440463 -395.6087959411366 -239.69239249818943 + + 219 + 3 + 171 + 29 + 27 + + + org.contikios.cooja.plugins.LogListener + + + + + + 888 + 2 + 603 + 34 + 307 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 960 + 0 + 682 + 528 + 192 + + + org.contikios.cooja.serialsocket.SerialSocketServer + 0 + + 60001 + true + + 362 + 4 + 116 + 234 + 101 + + + diff --git a/regression-tests/20-ip64/Makefile b/regression-tests/20-ip64/Makefile new file mode 100644 index 000000000..272bc7da1 --- /dev/null +++ b/regression-tests/20-ip64/Makefile @@ -0,0 +1 @@ +include ../Makefile.simulation-test diff --git a/regression-tests/21-large-rpl/01-cooja-http-socket-50.csc b/regression-tests/21-large-rpl/01-cooja-http-socket-50.csc new file mode 100644 index 000000000..1c52710b0 --- /dev/null +++ b/regression-tests/21-large-rpl/01-cooja-http-socket-50.csc @@ -0,0 +1,1006 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 2.0 + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype812 + router TARGET=cooja-ip64 + [CONTIKI_DIR]/regression-tests/21-large-rpl/code/router/router.c + echo make clean TARGET=cooja-ip64 +make router.cooja-ip64 TARGET=cooja-ip64 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype833 + client + [CONTIKI_DIR]/regression-tests/21-large-rpl/code/node/client.c + echo make clean TARGET=cooja +make client.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 55.719691912311305 + 37.8697579181178 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 33.16398380436391 + 28.280100446725353 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 64.7333702437188 + 86.25343669492709 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 34.382213480997194 + 87.3651616010611 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 11.332821198243948 + 72.43057435800137 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 95.94512295362799 + 71.39152480287795 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 34.51186307444599 + 59.489544081261435 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 63.02063881741806 + 6.725737893296902 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 67.16488021441937 + 54.31377260130722 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 9 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 9.784878122518437 + 81.00283052134533 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 10 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 32.10074353933871 + 33.071992737644926 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 11 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 91.82438265710196 + 51.23700415853406 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 12 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 21.195462105769337 + 82.08222111459202 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 13 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 55.73823429127498 + 69.24022125144269 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 14 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 69.71587306768029 + 57.37071024636343 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 15 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 66.69012609363311 + 68.93236248473207 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 16 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 66.84314708507073 + 32.20129384563065 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 17 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 75.11303983172269 + 17.658699966744983 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 18 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 27.078612584793017 + 97.3945649089831 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 19 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 63.37580990146204 + 30.66028070022273 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 20 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 3.866240569639967 + 58.00787820279949 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 21 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 57.433437740562496 + 12.398752526430156 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 22 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 15.784041174017371 + 74.78102139434115 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 23 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 40.67175327199246 + 52.46247320344863 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 24 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 38.43045934512656 + 90.56311604010655 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 25 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 0.6068936092190724 + 21.344443973676874 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 26 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 60.36615377515271 + 86.59995801287768 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 27 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 14.39476252794466 + 9.985669338749425 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 28 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 95.14872168386105 + 45.936172484167905 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 29 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 61.80198040806143 + 14.891226267286084 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 30 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 32.11354654266005 + 38.51630620185639 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 31 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 37.711371799794335 + 18.547318360664853 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 32 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 58.34301426026205 + 95.91480486240545 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 33 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 20.456374070589078 + 13.31295283913667 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 34 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 4.789895861056081 + 41.25598476863351 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 35 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 22.62971444227585 + 28.645182034255324 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 36 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 60.457329857492034 + 24.40308696160821 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 37 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 4.1096555252476685 + 27.46211937285302 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 38 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 87.008751083046 + 87.28519710099914 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 39 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 86.65741005585366 + 99.07543884063683 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 40 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 96.56473544385348 + 56.74413810869915 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 41 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 63.1598358033005 + 41.18799873508732 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 42 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 14.556676924656397 + 98.24257311359364 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 43 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 34.70728168935242 + 31.89373622088234 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 44 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 91.35334037714965 + 83.59007856757782 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 45 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 57.18004847306107 + 1.5650913544456135 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 46 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 97.14688174768989 + 29.613231105554448 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 47 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 12.528733239940715 + 23.28442121821601 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 48 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 97.65915972314534 + 57.204021167070664 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 49 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 94.8211477197945 + 15.57384229665848 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 50 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 69.1730393490499 + 35.900983349410275 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 51 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 606 + 15 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.LEDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 2.927428245448204 0.0 0.0 2.927428245448204 50.166589953058406 9.691034635016393 + + 401 + 0 + 368 + 29 + 27 + + + org.contikios.cooja.plugins.LogListener + + close + + + + 685 + 2 + 429 + 34 + 307 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONTIKI_DIR]/regression-tests/21-large-rpl/testscript.js + true + + 960 + 1 + 682 + 528 + 192 + + + org.contikios.cooja.serialsocket.SerialSocketServer + 0 + + 60001 + true + + 362 + 4 + 116 + 234 + 101 + + + diff --git a/regression-tests/21-large-rpl/Makefile b/regression-tests/21-large-rpl/Makefile new file mode 100644 index 000000000..272bc7da1 --- /dev/null +++ b/regression-tests/21-large-rpl/Makefile @@ -0,0 +1 @@ +include ../Makefile.simulation-test diff --git a/regression-tests/21-large-rpl/code/node/Makefile b/regression-tests/21-large-rpl/code/node/Makefile new file mode 100644 index 000000000..cbaa72ef7 --- /dev/null +++ b/regression-tests/21-large-rpl/code/node/Makefile @@ -0,0 +1,7 @@ +CONTIKI=../../../.. + +MODULES += core/net/http-socket + +CFLAGS+=-DPROJECT_CONF_H=\"project-conf.h\" + +include $(CONTIKI)/Makefile.include diff --git a/regression-tests/21-large-rpl/code/node/client.c b/regression-tests/21-large-rpl/code/node/client.c new file mode 100644 index 000000000..1e82e2df0 --- /dev/null +++ b/regression-tests/21-large-rpl/code/node/client.c @@ -0,0 +1,120 @@ +#include "contiki-net.h" +#include "http-socket.h" +#include "ip64-addr.h" +#include "dev/leds.h" +#include "rpl.h" + +#include + +static struct http_socket s; +static int bytes_received = 0; +static int restarts; +static struct ctimer reconnect_timer; +static int connect = 0; + +static void callback(struct http_socket *s, void *ptr, + http_socket_event_t e, + const uint8_t *data, uint16_t datalen); + +/*---------------------------------------------------------------------------*/ +PROCESS(http_example_process, "HTTP Example"); +AUTOSTART_PROCESSES(&http_example_process); +/*---------------------------------------------------------------------------*/ +static void +reconnect(void *dummy) +{ + printf("#A color=orange\n"); + rpl_set_mode(RPL_MODE_MESH); + connect = 1; +} +/*---------------------------------------------------------------------------*/ +static void +restart(void) +{ + int scale; + restarts++; + printf("restart %d\n", restarts); + rpl_set_mode(RPL_MODE_FEATHER); + printf("#A color=red\n"); + + scale = restarts; + if(scale > 5) { + scale = 5; + } + ctimer_set(&reconnect_timer, random_rand() % ((CLOCK_SECOND * 10) << scale), + reconnect, NULL); +} +/*---------------------------------------------------------------------------*/ +static void +callback(struct http_socket *s, void *ptr, + http_socket_event_t e, + const uint8_t *data, uint16_t datalen) +{ + if(e == HTTP_SOCKET_ERR) { + printf("HTTP socket error\n"); + } else if(e == HTTP_SOCKET_TIMEDOUT) { + printf("HTTP socket error: timed out\n"); + restart(); + } else if(e == HTTP_SOCKET_ABORTED) { + printf("HTTP socket error: aborted\n"); + restart(); + } else if(e == HTTP_SOCKET_HOSTNAME_NOT_FOUND) { + printf("HTTP socket error: hostname not found\n"); + restart(); + } else if(e == HTTP_SOCKET_CLOSED) { + if(bytes_received > 0) { + printf("HTTP socket closed, %d bytes received\n", bytes_received); + leds_off(LEDS_RED); + printf("#A color=blue\n"); + rpl_set_mode(RPL_MODE_FEATHER); + } else { + restart(); + } + } else if(e == HTTP_SOCKET_DATA) { + bytes_received += datalen; + printf("HTTP socket received %d bytes of data\n", datalen); + } +} +/*---------------------------------------------------------------------------*/ + +PROCESS_THREAD(http_example_process, ev, data) +{ + static struct etimer et; + uip_ip4addr_t ip4addr; + uip_ip6addr_t ip6addr; + + PROCESS_BEGIN(); + + uip_ipaddr(&ip4addr, 8,8,8,8); + ip64_addr_4to6(&ip4addr, &ip6addr); + uip_nameserver_update(&ip6addr, UIP_NAMESERVER_INFINITE_LIFETIME); + + etimer_set(&et, CLOCK_SECOND * 20); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + http_socket_init(&s); + connect = 1; + leds_on(LEDS_RED); + restarts = 0; + etimer_set(&et, CLOCK_SECOND * 5); + while(1) { + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + if(connect && rpl_has_downward_route()) { + printf("#A color=green\n"); + http_socket_get(&s, "http://www.contiki-os.org/", 0, 0, + callback, NULL); + connect = 0; + } else if(connect) { + connect++; + /* If connect have been "tried" 5 timer we quit trying now... */ + if(connect > 5) { + restart(); + connect = 0; + } + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/regression-tests/21-large-rpl/code/node/project-conf.h b/regression-tests/21-large-rpl/code/node/project-conf.h new file mode 100644 index 000000000..21bf07a9b --- /dev/null +++ b/regression-tests/21-large-rpl/code/node/project-conf.h @@ -0,0 +1,8 @@ +#define QUEUEBUF_CONF_STATS 1 +#define RESOLV_CONF_SUPPORTS_MDNS 0 +#define COOJA_MTARCH_STACKSIZE 4096 + +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 3 +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 3 diff --git a/regression-tests/21-large-rpl/code/router/Makefile b/regression-tests/21-large-rpl/code/router/Makefile new file mode 100644 index 000000000..a482f0a6a --- /dev/null +++ b/regression-tests/21-large-rpl/code/router/Makefile @@ -0,0 +1,5 @@ +CONTIKI=../../../.. + +CFLAGS+=-DPROJECT_CONF_H=\"project-conf.h\" + +include $(CONTIKI)/Makefile.include diff --git a/regression-tests/21-large-rpl/code/router/project-conf.h b/regression-tests/21-large-rpl/code/router/project-conf.h new file mode 100644 index 000000000..857ab6929 --- /dev/null +++ b/regression-tests/21-large-rpl/code/router/project-conf.h @@ -0,0 +1,11 @@ +#define QUEUEBUF_CONF_STATS 1 +#define RESOLV_CONF_SUPPORTS_MDNS 0 +#define COOJA_MTARCH_STACKSIZE 4096 + +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 8 +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 8 + +/* #define RPL_CONF_DEFAULT_LIFETIME_UNIT 60 */ +/* #define RPL_CONF_DEFAULT_LIFETIME 10 */ diff --git a/regression-tests/21-large-rpl/code/router/router.c b/regression-tests/21-large-rpl/code/router/router.c new file mode 100644 index 000000000..65882c36c --- /dev/null +++ b/regression-tests/21-large-rpl/code/router/router.c @@ -0,0 +1,70 @@ +#include "contiki.h" +#include "contiki-net.h" +#include "ip64.h" +#include "net/netstack.h" +#include "net/rpl/rpl-dag-root.h" +#include "net/rpl/rpl.h" +#include "net/ipv6/uip-ds6-route.h" +#include +/*---------------------------------------------------------------------------*/ +PROCESS(router_node_process, "Router node"); +AUTOSTART_PROCESSES(&router_node_process); +/*---------------------------------------------------------------------------*/ +uip_lladdr_t * uip_ds6_route_nexthop_lladdr(uip_ds6_route_t *route); + + +PROCESS_THREAD(router_node_process, ev, data) +{ + uip_ipaddr_t *nexthop = NULL; + uip_ds6_defrt_t *defrt; + uip_ipaddr_t *ipaddr; + uip_ds6_route_t *r; + static struct etimer et; + PROCESS_BEGIN(); + + /* Set us up as a RPL root node. */ + rpl_dag_root_init_dag(); + + /* Initialize the IP64 module so we'll start translating packets */ + ip64_init(); + + /* etimer_set(&et, CLOCK_SECOND * 60); */ + /* PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); */ + + /* ... and do nothing more. */ + while(1) { + etimer_set(&et, CLOCK_SECOND * 20); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + defrt = NULL; + if((ipaddr = uip_ds6_defrt_choose()) != NULL) { + defrt = uip_ds6_defrt_lookup(ipaddr); + } + if(defrt != NULL) { + printf("DefRT: :: -> %02d", defrt->ipaddr.u8[15]); + printf(" lt:%lu inf:%d\n", stimer_remaining(&defrt->lifetime), + defrt->isinfinite); + } else { + printf("DefRT: :: -> NULL\n"); + } + + if(uip_ds6_route_head() != NULL) { + printf("found head\n"); + for(r = uip_ds6_route_head(); + r != NULL; + r = uip_ds6_route_next(r)) { + nexthop = uip_ds6_route_nexthop(r); + if(nexthop != NULL) { + printf("Route: %02d -> %02d", r->ipaddr.u8[15], nexthop->u8[15]); + } else { + //printf("Route: %p %02d -> ? nbr-routes:%p", r, r->ipaddr.u8[15], + //r->neighbor_routes); + } + printf(" lt:%lu\n", r->state.lifetime); + } + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/regression-tests/21-large-rpl/testscript.js b/regression-tests/21-large-rpl/testscript.js new file mode 100644 index 000000000..1481d6bf5 --- /dev/null +++ b/regression-tests/21-large-rpl/testscript.js @@ -0,0 +1,78 @@ + +TIMEOUT(3000000); /* 50 minutes */ + +var NR_FEATHERS = mote.getSimulation().getMotesCount() - 1; + +/* conf */ +var travis = java.lang.System.getenv().get("TRAVIS"); +if (travis == null) { + /* Instant Contiki */ + CMD_TUNNEL = "echo '-vj' > ~/.slirprc && make Connect.class && java Connect 'nc localhost 60001' 'script -t -f -c slirp'"; + CMD_PING = "ping -c 5 8.8.8.8"; + CMD_DIR = "../../tools/wpcapslip"; +} else { + /* Travis */ + CMD_TUNNEL = "cd $TRAVIS_BUILD_DIR/tools/wpcapslip && sudo apt-get install slirp && echo '-vj' > ~/.slirprc && make Connect.class && java Connect 'nc localhost 60001' 'script -t -f -c slirp'"; + CMD_PING = "ping -c 5 8.8.8.8"; + CMD_DIR = "."; +} + +/* delay */ +GENERATE_MSG(1000, "continue"); +YIELD_THEN_WAIT_UNTIL(msg.equals("continue")); + +/* realtime speed */ +sim.setSpeedLimit(2.0); + +/* tunnel interface */ +log.log("opening tunnel interface: " + CMD_TUNNEL + "\n"); +launcher = new java.lang.ProcessBuilder["(java.lang.String[])"](['sh','-c',CMD_TUNNEL]); +launcher.directory(new java.io.File(CMD_DIR)); +launcher.redirectErrorStream(true); +tunProcess = launcher.start(); +tunRunnable = new Object(); +tunRunnable.run = function() { + var stdIn = new java.io.BufferedReader(new java.io.InputStreamReader(tunProcess.getInputStream())); + while ((line = stdIn.readLine()) != null) { + if (line != null && !line.trim().equals("")) { + //log.log("TUN> " + line + "\n"); + } + } + tunProcess.destroy(); +} +new java.lang.Thread(new java.lang.Runnable(tunRunnable)).start(); + +GENERATE_MSG(1000, "continue"); +YIELD_THEN_WAIT_UNTIL(msg.equals("continue")); + +/* ping */ +log.log("pinging: " + CMD_PING + "\n"); +launcher = new java.lang.ProcessBuilder["(java.lang.String[])"](['sh','-c',CMD_PING]); +launcher.directory(new java.io.File(CMD_DIR)); +launcher.redirectErrorStream(true); +tunProcess = launcher.start(); +tunRunnable = new Object(); +tunRunnable.run = function() { + var stdIn = new java.io.BufferedReader(new java.io.InputStreamReader(tunProcess.getInputStream())); + while ((line = stdIn.readLine()) != null) { + if (line != null && !line.trim().equals("")) { + log.log("PING> " + line + "\n"); + } + } + tunProcess.destroy(); +} +new java.lang.Thread(new java.lang.Runnable(tunRunnable)).start(); + +var completed = {}; +while(Object.keys(completed).length < NR_FEATHERS) { + if (!msg.startsWith("#L") && !msg.startsWith("E")) { + //log.log(mote + ": " + msg + "\n"); + } + if (id != 1 && msg.startsWith("HTTP socket closed")) { + completed[id] = id; + log.log("Data compelete " + id + ", heard " + Object.keys(completed).length + " in total\n"); + } + YIELD(); +} + +log.testOK(); diff --git a/regression-tests/22-compile-nxp-ports/Makefile b/regression-tests/22-compile-nxp-ports/Makefile new file mode 100644 index 000000000..9291cd846 --- /dev/null +++ b/regression-tests/22-compile-nxp-ports/Makefile @@ -0,0 +1,25 @@ +EXAMPLESDIR=../../examples +TOOLSDIR=../../tools + +# build jn516x examples, covering IPv6, RPL, CoAP, Rime, Nullrdc, Contikimac +EXAMPLES = \ +hello-world/jn516x \ +jn516x/dr1175-sensors/jn516x \ +jn516x/rime/jn516x \ +jn516x/rpl/border-router/jn516x \ +jn516x/rpl/node/jn516x \ +jn516x/rpl/coap-dongle-node/jn516x \ +jn516x/rpl/coap-dr1175-node/jn516x \ +jn516x/rpl/coap-dr1199-node/jn516x \ +jn516x/tsch/simple-sensor-network/node/jn516x \ +jn516x/tsch/simple-sensor-network/rpl-border-router/jn516x \ +jn516x/tsch/tx-power-verification/node/jn516x \ +jn516x/tsch/tx-power-verification/rpl-border-router/jn516x \ +jn516x/tsch/uart1-test-node/jn516x \ +ipv6/rpl-tsch/jn516x \ +ipv6/rpl-tsch/jn516x:MAKE_WITH_ORCHESTRA=1 \ +ipv6/rpl-tsch/jn516x:MAKE_WITH_SECURITY=1 + +TOOLS= + +include ../Makefile.compile-test diff --git a/regression-tests/23-compile-avr/Makefile b/regression-tests/23-compile-avr/Makefile new file mode 100644 index 000000000..e7d2dff77 --- /dev/null +++ b/regression-tests/23-compile-avr/Makefile @@ -0,0 +1,14 @@ +EXAMPLESDIR=../.. +TOOLSDIR=../../tools + +# build avr-rss2 examples, covering IPv6, RPL, Rime, Nullrdc, Contikimac + +EXAMPLES = \ +examples/avr-rss2/hello-sensors/avr-rss2 \ +examples/avr-rss2/ipv6/rpl-udp-report/avr-rss2 \ +examples/avr-rss2/ipv6/rpl-border-router/avr-rss2 \ +examples/powertrace/avr-rss2 \ +examples/rime/avr-rss2 +TOOLS= + +include ../Makefile.compile-test diff --git a/regression-tests/23-rpl-non-storing/01-rpl-up-route.csc b/regression-tests/23-rpl-non-storing/01-rpl-up-route.csc new file mode 100644 index 000000000..da4743d44 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/01-rpl-up-route.csc @@ -0,0 +1,344 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype488 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make TARGET=cooja clean +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype32 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make TARGET=cooja clean +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype352 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make TARGET=cooja clean +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 6.9596575829049145 + -25.866060090958513 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype352 + + + + org.contikios.cooja.interfaces.Position + 132.8019872469463 + 146.1533406452311 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype488 + + + + org.contikios.cooja.interfaces.Position + 0.026556260457749753 + 39.54055615854325 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype352 + + + + org.contikios.cooja.interfaces.Position + 95.52021598473031 + 148.11553913271615 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype352 + + + + org.contikios.cooja.interfaces.Position + 62.81690785997944 + 127.1854219328756 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype352 + + + + org.contikios.cooja.interfaces.Position + 32.07579822271361 + 102.33090775806494 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype352 + + + + org.contikios.cooja.interfaces.Position + 5.913151722912886 + 73.55199660828417 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype352 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype32 + + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 0.9555608221893928 0.0 0.0 0.9555608221893928 177.34962387792274 139.71659364731656 + + 400 + 1 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 3 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 0 + 596 + 603 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/02-rpl-root-reboot.csc b/regression-tests/23-rpl-non-storing/02-rpl-root-reboot.csc new file mode 100644 index 000000000..6c4ce9d28 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/02-rpl-root-reboot.csc @@ -0,0 +1,344 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype958 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make TARGET=cooja clean +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype837 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make TARGET=cooja clean +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype358 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make TARGET=cooja clean +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -22.5728586847096 + 123.9358664968653 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype958 + + + + org.contikios.cooja.interfaces.Position + -1.39303771455413 + 100.21446701029119 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 10.931583432822638 + 69.848248459216 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype358 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype837 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 3 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 1 + 596 + 603 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/03-rpl-28-hours.csc b/regression-tests/23-rpl-non-storing/03-rpl-28-hours.csc new file mode 100644 index 000000000..3ebc7adda --- /dev/null +++ b/regression-tests/23-rpl-non-storing/03-rpl-28-hours.csc @@ -0,0 +1,293 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype110 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make TARGET=cooja clean +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype792 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make TARGET=cooja clean +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype964 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make TARGET=cooja clean +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 7.772906112657773 + 86.396910401861 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype964 + + + + org.contikios.cooja.interfaces.Position + 75.54361692539452 + 14.292026223193414 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype110 + + + + org.contikios.cooja.interfaces.Position + 47.962513687652844 + 7.199742533488408 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype964 + + + + org.contikios.cooja.interfaces.Position + 1.8626697045702818 + 47.783365869022624 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype964 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype792 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 78.27260101976275 40.72727272727276 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 3 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 1 + 596 + 603 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/04-rpl-large-network.csc b/regression-tests/23-rpl-non-storing/04-rpl-large-network.csc new file mode 100644 index 000000000..f4ea0fda8 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/04-rpl-large-network.csc @@ -0,0 +1,7058 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype710 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make TARGET=cooja clean +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype709 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make TARGET=cooja clean +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype332 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make TARGET=cooja clean +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -15.604889524290883 + -27.272920930192623 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 218.29521040499824 + 216.70287561143516 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype710 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype709 + + + + org.contikios.cooja.interfaces.Position + 27.44274795318258 + 36.980443988209856 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 185.6055859234863 + 192.99166984979271 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 7.827315175624361 + 107.95833747378225 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 82.49199862549197 + 34.72851022020231 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.671428723363064 + 125.82590119075962 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.044376889885754 + 62.443378727185774 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 9 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 152.53659733643553 + 165.87608708149403 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 10 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 22.023077232445942 + 18.41094139254531 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 11 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 41.19368867821842 + 49.201157808285224 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 12 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 114.62128502432532 + 88.58807114217633 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 13 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.21405469314478 + 188.6851979777661 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 14 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 104.78326932115709 + 100.84889281105585 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 15 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 90.26861048950052 + 40.550864496421404 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 16 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 137.39112328314076 + 126.5333637365394 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 17 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 14.07616766247768 + 99.85572366133869 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 18 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 192.30563307960443 + 66.83563821262344 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 19 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 129.08253247651874 + 117.20437669309078 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 20 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 21.82717410659969 + 47.523771402541335 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 21 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.95102103988239 + 21.74677482276881 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 22 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.71108896268191 + 79.91617509627334 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 23 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 16.029809485043288 + 171.05935835280616 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 24 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 138.8418552766128 + 61.418703448852185 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 25 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 151.23299942414673 + 92.41820871538522 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 26 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 197.33157775573343 + 20.6013482653864 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 27 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 121.20762229879878 + 184.81107462083565 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 28 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 102.32432527534694 + 91.9912435435037 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 29 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 88.10909646999544 + 191.21251904898142 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 30 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 72.19774934085703 + 113.58131529956069 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 31 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 53.49967737007204 + 72.45172156882643 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 32 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 172.07186411958625 + 51.47715718716961 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 33 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 185.41983532466634 + 85.60078269414 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 34 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 83.34993971740548 + 193.98111239532744 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 35 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 105.03752362550378 + 131.24078026424087 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 36 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 176.09318670322102 + 41.46760901468247 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 37 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.80689915307215 + 47.13815728542057 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 38 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 155.907739287817 + 15.24009422994106 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 39 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 45.992463430523436 + 124.573811024683 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 40 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 159.11361032671832 + 81.65319598335425 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 41 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 41.838657583001314 + 163.47591213471193 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 42 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 25.560001904073125 + 147.48610852243928 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 43 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 139.56489350213488 + 191.15379557180913 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 44 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 105.71342550700061 + 136.09089690661503 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 45 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 122.59378462201298 + 196.22862961645998 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 46 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 147.61372446125088 + 55.314287700435536 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 47 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 77.70218628780312 + 95.59561907133107 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 48 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.88244578562713 + 168.57963926907163 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 49 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 6.722298767036894 + 101.09668965729898 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 50 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 62.96680217979964 + 77.66951408660954 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 51 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 162.49011735601982 + 199.07086470932003 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 52 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 87.87526390617558 + 114.39424478293958 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 53 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 74.29230372180815 + 36.995699473573836 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 54 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 77.34619341407321 + 60.070446577058576 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 55 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.32695571818826 + 135.82669004433725 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 56 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 68.10326013650814 + 5.04157445893032 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 57 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 95.76993029214962 + 45.046282401332945 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 58 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 79.87963205080952 + 110.7023948653882 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 59 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 195.90349780899223 + 132.38904172009444 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 60 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 80.40108440304007 + 25.86673418569547 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 61 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 52.268877618080744 + 176.12888723955277 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 62 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 40.545541404899765 + 166.9450252729589 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 63 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 10.676184465528205 + 0.9871174057552334 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 64 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 87.35673216830257 + 23.25131234780027 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 65 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 26.745126931691352 + 87.3101256645554 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 66 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 183.2724008541638 + 167.69026002459069 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 67 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 5.934720840855223 + 77.21248812623693 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 68 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.49604470599058 + 108.80963795015302 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 69 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 86.10145414955488 + 12.798582653303603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 70 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 32.435370110193816 + 29.344591306898813 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 71 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 163.72950518161596 + 154.15283820759655 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 72 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 143.96396308843373 + 132.40312602892786 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 73 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 139.20530179839795 + 144.18958011498225 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 74 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 75.22453368236212 + 119.69913560274786 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 75 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 21.83836116635087 + 191.21696522067728 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 76 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 187.94640511976667 + 113.95684826994561 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 77 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 114.61289565250618 + 27.61001303446735 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 78 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 70.83569869750504 + 113.88992677636021 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 79 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 11.616059362048992 + 45.59401384110464 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 80 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 3.4282454263252937 + 35.97653370545284 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 81 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 54.33122057405715 + 1.9759087814547494 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 82 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 69.6612091444155 + 0.45982758130533874 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 83 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 169.98417155202168 + 87.76678058442593 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 84 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 148.98441194234616 + 104.32820155415494 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 85 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 66.23883124891583 + 162.92685536074129 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 86 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 181.6348837921769 + 183.07267240808343 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 87 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 88.9829570206748 + 119.72520333459575 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 88 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 179.1527012143494 + 84.25685075020328 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 89 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 117.82537007493707 + 41.10319533518651 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 90 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 52.611633540398486 + 94.71918054798351 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 91 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 128.22088664324633 + 115.50290142480077 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 92 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 102.53841128002531 + 11.784449645612295 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 93 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 187.69871925603667 + 131.28317666772048 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 94 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.13897508938263 + 106.29335632876602 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 95 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.2216469861295 + 148.38612859488788 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 96 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 36.152562577928784 + 67.541796718348 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 97 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 118.84793016344604 + 0.49906433835273933 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 98 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 135.20417096106954 + 170.20704631856816 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 99 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 156.082359043526 + 57.62103450217495 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 100 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 180.58695188377737 + 80.75266645775669 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 101 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 38.93889890269273 + 138.60259660238856 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 102 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 159.5172788118917 + 192.24950143209503 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 103 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 154.02096825135868 + 139.67175722659056 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 104 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 38.480826888323904 + 5.502866276505292 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 105 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 27.95908088015704 + 193.85188308665965 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 106 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 198.61700949829074 + 171.1877312716402 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 107 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 106.30468818084609 + 25.058380770654654 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 108 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 40.335672117825624 + 179.59080234641004 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 109 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 22.316357638510897 + 158.94323888090028 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 110 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 99.56281553229194 + 85.64260133077535 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 111 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 60.71556414510035 + 121.53040248649711 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 112 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 27.08600745576586 + 38.17025720346818 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 113 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 147.03642509910586 + 39.51320588416096 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 114 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 180.2031547656297 + 141.5646561330238 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 115 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 73.12314629214424 + 167.80783320779847 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 116 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 167.93567452922767 + 10.060141001139144 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 117 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 163.99198875105768 + 147.48735207074026 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 118 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 154.98654737808127 + 121.17266324007643 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 119 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 57.898499791676386 + 149.3487194893122 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 120 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 64.82082963563904 + 174.0100480348673 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 121 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 114.13623920898752 + 15.754246175503095 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 122 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 0.00848902940355778 + 195.50701335573908 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 123 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 182.81764401709623 + 78.57837811285111 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 124 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 11.462145876504714 + 95.37444120802225 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 125 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 115.5020283241771 + 28.49431396939579 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 126 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 62.463952359877275 + 77.78913013330184 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 127 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 9.766778039117696 + 136.7421944039438 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 128 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.320514349220055 + 100.56248258192493 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 129 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 56.26732169234614 + 3.095097140731262 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 130 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.90164393617998 + 3.5671096386384216 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 131 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 81.97549075841862 + 13.020422155003475 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 132 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 54.87200208203389 + 77.29445717372947 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 133 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 193.47651032749548 + 144.9357554583657 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 134 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 51.65288193591992 + 126.16687604535504 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 135 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 151.66849746442173 + 158.7699863850836 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 136 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 32.469410974826005 + 113.10993021698361 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 137 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.04622512107349 + 25.425445944702794 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 138 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.53444748873715 + 112.25721598241579 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 139 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 128.9401580272291 + 100.73482184242926 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 140 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 194.6592727528704 + 102.73664509470841 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 141 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 125.47343036050516 + 106.53155237731285 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 142 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 147.40129296416038 + 12.37607345376115 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 143 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 113.32045045397959 + 126.79285457987103 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 144 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 27.174837677715825 + 66.84349985536826 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 145 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 164.20252670136998 + 51.635539499142524 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 146 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 39.351673884988394 + 65.05462325698123 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 147 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 143.91486202542433 + 171.28435110465497 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 148 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 30.926988343440186 + 130.3647571119649 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 149 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 19.897357003413617 + 22.905473451246785 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 150 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 128.36369031733133 + 170.71462512320227 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 151 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 172.1648617546042 + 184.1928317689217 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 152 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 148.16672573170842 + 107.99684523382686 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 153 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 83.90300186263724 + 169.4761782218257 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 154 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 90.86887922361453 + 142.8036645841288 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 155 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 23.18966921326753 + 69.42635534680753 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 156 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 134.59433377860168 + 37.633119904417796 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 157 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 127.97132285920065 + 158.57917470101572 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 158 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 166.2450456558778 + 108.67197275397042 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 159 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 167.334034200758 + 22.173554305333166 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 160 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 163.54194527237107 + 189.41605447848966 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 161 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 14.863357513573018 + 93.36644051662617 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 162 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 178.4370382798651 + 191.48348446587636 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 163 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 172.96087703915273 + 183.78535300027013 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 164 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 2.45779137738229 + 58.750309492130114 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 165 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 15.730601618735495 + 96.52335072173565 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 166 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 19.890833428932165 + 56.993000152370364 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 167 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 154.69166608840504 + 164.8598339150269 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 168 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 199.77196118880582 + 26.034321005016903 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 169 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 5.216343266336931 + 17.867912968799615 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 170 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 138.71273406283296 + 55.31024592694844 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 171 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 168.21144361519595 + 163.1843284579423 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 172 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.82504434646854 + 134.03197926926038 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 173 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 14.007317972338473 + 146.98475859141027 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 174 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 108.44210606040488 + 127.81076428732186 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 175 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 133.41957560864708 + 122.91534078890439 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 176 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 184.89266828168118 + 195.7201293014503 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 177 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 121.10492556426465 + 78.54418709376823 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 178 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 42.05271519544296 + 183.14259881514795 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 179 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 92.12119616387746 + 44.853464007589714 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 180 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 136.44039199596196 + 1.111619893261917 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 181 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 64.37440878278696 + 188.3078368775181 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 182 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 37.774149552594594 + 73.81683900641865 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 183 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 24.618589360988175 + 164.89708336795567 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 184 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 152.5950797265111 + 140.96774353352123 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 185 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 37.96933854365052 + 131.92434845994435 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 186 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 14.05145808951862 + 26.159084136809916 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 187 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.47558158857349 + 68.73507104275693 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 188 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.420404733112385 + 108.47794695541302 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 189 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 129.0179255565185 + 176.46977408461998 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 190 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 4.437687657989087 + 191.43801818673953 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 191 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 132.39232886927158 + 105.56546037448346 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 192 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 193.9356389936735 + 76.8987220921185 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 193 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 123.49672189705024 + 16.28922647444049 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 194 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 40.44058024960566 + 94.77629608096818 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 195 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 93.54168452285269 + 102.10342793159373 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 196 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 176.91858637781746 + 81.80773827257306 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 197 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 182.5062159995403 + 10.047631291589564 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 198 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 151.3211952231698 + 160.98807517681706 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 199 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 167.8826595707132 + 160.3686256248768 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 200 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 93.38491122055773 + 61.04322963139093 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 201 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 155.20211039479165 + 104.99915002371228 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 202 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 154.56882959476744 + 192.77647809954323 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 203 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 119.88029558288524 + 48.71837870038327 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 204 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 8.237800167806908 + 123.56280331420268 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 205 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 53.424877837249696 + 87.33638375233281 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 206 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 199.25320093864096 + 66.76343110330383 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 207 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 166.7255674935148 + 165.31992478582075 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 208 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 135.9334286576811 + 130.36986226660702 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 209 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 65.60950768388696 + 14.081940005079275 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 210 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 56.68133966983844 + 196.61338214776293 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 211 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 2.562777529582072 + 66.73129709411079 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 212 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 34.10919172462936 + 176.31986637140767 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 213 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.846173186403306 + 142.33660392777279 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 214 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 128.76326079790124 + 90.05136184351706 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 215 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 80.39617891964872 + 111.48714907972395 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 216 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 21.97338508940303 + 61.032785792453815 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 217 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 158.00182839254427 + 175.79991821384095 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 218 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 64.21702017661488 + 197.8650659620092 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 219 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 58.261430108425174 + 69.56229252260285 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 220 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 114.85635789777962 + 130.3021189977344 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 221 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 24.601661057872736 + 196.33046445845073 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 222 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 136.22037670133446 + 18.019579846123435 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 223 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.91168973841357 + 193.3123397692768 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 224 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.67497322258676 + 156.30488619961912 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 225 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 85.70841880772959 + 39.914700874835106 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 226 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 142.3427145819395 + 76.80244108802334 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 227 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 45.6821653485997 + 33.96733547026549 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 228 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 146.16353499121948 + 5.58117117441268 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 229 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 34.32680631388174 + 111.76495490887346 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 230 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 138.5676204843924 + 161.4559204389253 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 231 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 196.36096598095253 + 19.9809316402896 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 232 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 190.5761031572042 + 118.16570999859783 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 233 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 137.89894164409372 + 114.36842366282201 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 234 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 13.942927177934262 + 25.042265908173977 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 235 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 21.808225381827363 + 89.51408500063611 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 236 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 82.1665299576559 + 89.41818802221223 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 237 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 100.24631818801446 + 85.16089691564225 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 238 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 150.87166478995505 + 124.32687790892683 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 239 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 196.72953604773366 + 89.0589559016778 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 240 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 178.10423185724105 + 108.01295472332721 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 241 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 24.852336661830865 + 107.10027825925053 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 242 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 198.2838988728342 + 185.2533889301396 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 243 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 122.42366366542863 + 13.685145107609165 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 244 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 113.58516359448151 + 59.212889358544054 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 245 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 148.6689453992514 + 65.76664113968091 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 246 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 110.90604811956779 + 118.12368970120251 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 247 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 195.48877933255176 + 71.61703558744803 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 248 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 90.74911177135543 + 151.9662290090636 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 249 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 5.669662023293154 + 80.71705944385323 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 250 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 77.57071934873466 + 25.884947016521597 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 251 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 172.38535892291588 + 6.827522113737539 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 252 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 62.61595677732154 + 171.52926299696654 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 253 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 163.1605182212256 + 136.67511261098457 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 254 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 174.98684717123461 + 163.9648526025463 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 255 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 112.4179766207543 + 108.05999669756379 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 256 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.60510656526031 + 96.23183516652448 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 257 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 51.39949089302518 + 181.73639564248649 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 258 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 140.61625635482116 + 118.88528060437326 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 259 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 81.11235868256772 + 71.16703221921186 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 260 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 106.30383323544051 + 47.66664077552125 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 261 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 78.36392430481997 + 145.12300889005226 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 262 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 159.2795584664916 + 175.42365153724947 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 263 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 89.12806123792214 + 163.88074620615808 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 264 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 188.00194321004403 + 167.99738752402368 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 265 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 186.544702443713 + 156.12158395696437 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 266 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 2.8406717287810412 + 38.380349570314664 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 267 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 28.76119804764801 + 168.10637626762275 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 268 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 190.1115654346047 + 36.24498374070968 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 269 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 67.43484884843447 + 118.69086680825731 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 270 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 50.7959234692023 + 165.04960719272802 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 271 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 50.75575271798458 + 144.55723570362358 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 272 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 128.94257968083764 + 47.32490472068322 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 273 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 1.9193343221312942 + 112.82658785936086 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 274 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 51.82023785974064 + 148.28034473499338 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 275 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 98.55603081185546 + 178.02566808501155 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 276 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 143.40572664084078 + 183.27302398341982 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 277 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 141.0619733646239 + 54.122738136324955 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 278 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 162.29942916334053 + 67.55247227617933 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 279 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 185.29686875363197 + 118.81126461905944 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 280 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 104.06690998854779 + 5.511220514887172 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 281 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 181.82429252421596 + 47.0700962247878 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 282 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 17.604228655775245 + 96.78328313290936 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 283 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 60.74231839144737 + 136.8041677309854 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 284 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 158.57791000335715 + 90.16811700419458 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 285 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 26.040369760119475 + 115.48428978095157 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 286 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 155.33825554510548 + 122.61758874267335 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 287 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 171.04754637183774 + 49.44780022857469 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 288 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 130.8601631228818 + 115.38443324744807 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 289 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 138.51066172926747 + 85.05731662406394 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 290 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 17.01860916014879 + 85.74431631403492 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 291 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 63.632763185894994 + 73.28193598294403 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 292 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 145.51992557600448 + 190.19645657449914 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 293 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 141.3669225587347 + 128.37798094188392 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 294 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 5.624436269305666 + 10.321359475496084 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 295 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 32.62210104212715 + 80.99365929301005 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 296 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 146.82462375206796 + 189.00512676494264 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 297 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 96.89937776974169 + 61.868257009019125 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 298 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 71.17532023107206 + 32.87953533289934 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 299 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 37.21430187397199 + 21.880189704400976 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 300 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 123.17178528937387 + 23.802492560334287 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 301 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 139.8264101859233 + 106.93416114169838 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 302 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 34.97792194896952 + 182.11554692137054 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 303 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 156.016327676095 + 83.35423896139108 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 304 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.33352678715003 + 148.24111721535743 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 305 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 22.525965053498552 + 94.23130431241577 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 306 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 145.40586007739483 + 194.77296443866655 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 307 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 64.78487058910738 + 34.59908782949142 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 308 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 59.86114357954142 + 143.29623794752337 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 309 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 133.03711837762597 + 0.29677881350260726 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 310 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 184.05437940334514 + 80.34917749334691 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 311 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 43.18494391360306 + 0.7070568470557648 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 312 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 87.88579984985796 + 183.6845166360299 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 313 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.679149788796785 + 59.900754257451624 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 314 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 10.837936713278706 + 68.65555543408139 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 315 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 28.088726188466005 + 66.6117410256945 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 316 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 24.15305881985441 + 127.36722357863377 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 317 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 167.92463302345024 + 95.32246240241238 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 318 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 150.07537910034364 + 189.29680149689028 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 319 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 36.60193942102408 + 4.850860928459388 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 320 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 131.4804357164766 + 107.37981261172979 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 321 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 4.702056299253576 + 145.3571381517292 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 322 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 76.83393335740108 + 40.92489706855471 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 323 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 81.41902810900726 + 59.67311069186907 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 324 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 157.9286881274713 + 35.89390157980119 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 325 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 172.59261547136273 + 162.21173966194792 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 326 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 63.77983240079481 + 110.66181735649987 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 327 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 94.27259269172448 + 102.22907067171563 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 328 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 87.82927755519094 + 154.83172363042706 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 329 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.424763006386954 + 73.54903523332621 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 330 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 193.50994444846046 + 100.37438735826956 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 331 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 160.15646353486886 + 197.56265442862397 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 332 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.41179410209567 + 85.51716211010236 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 333 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 39.55932830334419 + 79.79114070992594 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 334 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 29.81531743952457 + 106.52370973616816 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 335 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 145.66591758403607 + 93.84627277397392 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 336 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 121.12689025085304 + 141.7616054105135 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 337 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 31.696932817539736 + 73.39512842700171 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 338 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 73.55413175311341 + 184.10063535264334 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 339 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 179.21266954315877 + 157.77936426661222 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 340 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 5.861701400590658 + 176.44679868441557 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 341 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 164.32858198885157 + 127.1649251930171 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 342 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 104.78813885934602 + 2.6978015525372934 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 343 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 9.036210189825722 + 37.29651951364714 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 344 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 69.09633192708777 + 131.08113653458605 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 345 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 23.989325789242024 + 102.76529191595212 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 346 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 32.563144827068456 + 174.05783874991164 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 347 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 26.84717981820497 + 33.708035418260465 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 348 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 23.651571274100892 + 150.9696150146202 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 349 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 7.263970263317554 + 178.4551746541966 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 350 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 137.19080046610807 + 195.47642758858956 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 351 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 100.60258790901588 + 10.122226122279043 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 352 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 158.02955707421086 + 15.552042272281575 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 353 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 69.03288347183658 + 86.65939835169405 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 354 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 197.11534487465465 + 12.227887489891408 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 355 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 109.32664513099861 + 51.47545505189106 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 356 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 7.450618560323541 + 114.12792666368863 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 357 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 96.73499758330652 + 87.34903664585806 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 358 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 143.42568088659735 + 154.7201550387036 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 359 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 16.055115327242596 + 23.72235108907279 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 360 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 36.54118641672248 + 71.60060131854802 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 361 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 153.4641555525212 + 182.30266241969497 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 362 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 179.79961054026052 + 52.374917374947486 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 363 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 51.89511924887278 + 55.715278818289924 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 364 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 160.22911392558143 + 197.03727711739174 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 365 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 141.50401865962175 + 198.17183635084353 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 366 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 144.1436553724308 + 66.26788567722302 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 367 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 114.85639238072662 + 187.02866922391485 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 368 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 14.754418142216963 + 189.75568091879705 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 369 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 40.445861020644756 + 132.87622199437286 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 370 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 70.41846318684537 + 16.353121961748673 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 371 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 11.524098377391411 + 188.46037552576104 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 372 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 19.80490164758435 + 193.31200682922997 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 373 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 170.32256510777594 + 170.204813941954 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 374 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.11638379627671 + 106.63452905636245 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 375 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 87.80726944100199 + 69.16884374165753 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 376 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 45.63781115512378 + 137.1790704392972 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 377 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 120.23124867416645 + 21.60172442725463 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 378 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 42.584241021086264 + 172.9365035614701 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 379 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 106.9111221907689 + 35.38132573733432 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 380 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 115.65012523180343 + 149.06748739273075 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 381 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 66.70597176653999 + 151.96624665556067 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 382 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 116.86108695969573 + 92.96503821223025 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 383 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 138.3454858274232 + 60.335069940591254 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 384 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 35.21169262537829 + 57.75683948274251 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 385 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 183.64109836494706 + 187.89865943504947 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 386 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 124.92709985349823 + 7.139364140447135 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 387 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 121.19563498360651 + 163.5898829983739 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 388 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 141.67701483198246 + 36.967824799613645 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 389 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 116.85490603618803 + 192.1746914581395 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 390 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 157.23646122348265 + 101.21354943885676 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 391 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 58.04596641555313 + 180.0770488919343 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 392 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 118.342960728573 + 65.22048911724025 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 393 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 61.42203823259405 + 117.333210601775 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 394 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 136.13358028390385 + 97.99627507346685 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 395 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 82.86089860898949 + 25.22615052347874 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 396 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 6.721379593879373 + 94.78763681182285 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 397 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 38.69266957378596 + 24.113141554020046 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 398 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 111.22857295130957 + 95.51634459331788 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 399 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 126.7915415569141 + 32.23798771734878 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 400 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 186.84699461455236 + 34.76662976923288 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 401 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 122.45497909139493 + 167.0773654715768 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 402 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.interfaces.Position + 33.03449972907999 + 172.77024458531486 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 403 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype332 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 1.1671649566739442 0.0 0.0 1.1671649566739442 66.21348020552065 40.83199757586018 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 0 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 1 + 596 + 603 + 43 + + \ No newline at end of file diff --git a/regression-tests/23-rpl-non-storing/05-rpl-up-and-down-routes.csc b/regression-tests/23-rpl-non-storing/05-rpl-up-and-down-routes.csc new file mode 100644 index 000000000..0dd110738 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/05-rpl-up-and-down-routes.csc @@ -0,0 +1,342 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype743 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype452 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype782 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -22.5728586847096 + 123.9358664968653 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype743 + + + + org.contikios.cooja.interfaces.Position + -1.39303771455413 + 100.21446701029119 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 10.931583432822638 + 69.848248459216 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype782 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype452 + + + + org.contikios.cooja.plugins.SimControl + 280 + 1 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + 1184 + 3 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 0 + 596 + 603 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/06-rpl-temporary-root-loss.csc b/regression-tests/23-rpl-non-storing/06-rpl-temporary-root-loss.csc new file mode 100644 index 000000000..6c29c643f --- /dev/null +++ b/regression-tests/23-rpl-non-storing/06-rpl-temporary-root-loss.csc @@ -0,0 +1,348 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype951 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype170 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype767 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -22.5728586847096 + 123.9358664968653 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype951 + + + + org.contikios.cooja.interfaces.Position + -1.39303771455413 + 100.21446701029119 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 10.931583432822638 + 69.848248459216 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype767 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype170 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + 1184 + 3 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 1 + 596 + 603 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/07-rpl-random-rearrangement.csc b/regression-tests/23-rpl-non-storing/07-rpl-random-rearrangement.csc new file mode 100644 index 000000000..cdb62c420 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/07-rpl-random-rearrangement.csc @@ -0,0 +1,647 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype419 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype484 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype718 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -0.4799968467515439 + 98.79087181374759 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 99.56423154395364 + 50.06466731257512 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype419 + + + + org.contikios.cooja.interfaces.Position + -0.4799968467515439 + 0.30173505605854883 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype484 + + + + org.contikios.cooja.interfaces.Position + 12.779318616702257 + 8.464865358169643 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 9.391922400291703 + 49.22878206790311 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 48.16367625505583 + 33.27520746599595 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 16.582742473429345 + 24.932911331640646 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 8.445564421140666 + 6.770205395698742 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 87.04968129458189 + 34.46536562612724 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 9 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 94.47123252519145 + 18.275940194868184 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 10 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 95.28044254364556 + 17.683438211793558 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 11 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 56.124622439456076 + 33.88966252832571 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 12 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 98.33149749474546 + 37.448034626592744 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 13 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 58.75337436025891 + 68.64082018992522 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 14 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 66.83816496627988 + 68.38008376830592 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 15 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 90.88648665466316 + 50.942053906416575 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 16 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 68.80089833632896 + 84.17294684073734 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 17 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 73.6760846183129 + 81.76699743886633 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 18 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 0.2960103456537466 + 98.5587829617092 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 19 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 8.130479493904208 + 57.642099520821645 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 20 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 30.550120982984865 + 85.58346736403402 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 21 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 29.65300377698182 + 63.50257213104861 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 22 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.interfaces.Position + 34.92110687576687 + 70.71381297232249 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 23 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype718 + + + + org.contikios.cooja.plugins.SimControl + 280 + 1 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 1.92914676942954 0.0 0.0 1.92914676942954 75.9259843662471 55.41790879138101 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 3 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 0 + 726 + 953 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-0.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-0.csc new file mode 100644 index 000000000..0fc6e032d --- /dev/null +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-0.csc @@ -0,0 +1,360 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype921 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype873 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype812 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype921 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + -40.352178879596096 + 102.66976131212861 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype873 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 1.6480321712565114 0.0 0.0 1.6480321712565114 98.5016889738719 55.796930342384904 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 1 + 726 + 953 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-1.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-1.csc new file mode 100644 index 000000000..2c0ce41ff --- /dev/null +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-1.csc @@ -0,0 +1,360 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype672 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype780 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype36 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype672 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + -25.71843353317142 + 43.05517674255262 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype780 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 + + 400 + 2 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 1 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 0 + 726 + 953 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-2.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-2.csc new file mode 100644 index 000000000..cdb2bd748 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-2.csc @@ -0,0 +1,360 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype672 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype780 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype36 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype672 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 16.0472370839803 + 6.017695251870905 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype780 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 1 + 726 + 953 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-3.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-3.csc new file mode 100644 index 000000000..34b930c0d --- /dev/null +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-3.csc @@ -0,0 +1,360 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype672 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype780 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype36 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype672 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype36 + + + + org.contikios.cooja.interfaces.Position + 79.48377453078622 + 4.835647970253402 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype780 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 70.27260101976269 60.72727272727276 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 1 + 726 + 953 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-4.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-4.csc new file mode 100644 index 000000000..ff9a400c1 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-4.csc @@ -0,0 +1,360 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype192 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype575 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype912 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype192 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype912 + + + + org.contikios.cooja.interfaces.Position + 122.82550819009461 + 29.658640884220933 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype575 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.5379695437350276 0.0 0.0 2.5379695437350276 70.27260101976269 60.72727272727276 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 1 + 726 + 953 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-5.csc b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-5.csc new file mode 100644 index 000000000..e491b666f --- /dev/null +++ b/regression-tests/23-rpl-non-storing/08-rpl-dao-route-loss-5.csc @@ -0,0 +1,360 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype372 + Sender + [CONFIG_DIR]/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype229 + RPL root + [CONFIG_DIR]/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype424 + Receiver + [CONFIG_DIR]/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -7.199692787830563 + 98.21738321803603 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 116.13379149678028 + 88.36698920455684 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype372 + + + + org.contikios.cooja.interfaces.Position + 12.0 + 68.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 95.25095618820441 + 63.14998053005015 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 66.09378990830604 + 38.32698761608261 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 29.05630841762433 + 30.840688165838436 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 58.0 + 108.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype424 + + + + org.contikios.cooja.interfaces.Position + 145.93059238811136 + 111.16474110935306 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype229 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 1.6480321712565114 0.0 0.0 1.6480321712565114 98.5016889738719 55.796930342384904 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 500 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 612 + 1 + 726 + 953 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/09-rpl-probing.csc b/regression-tests/23-rpl-non-storing/09-rpl-probing.csc new file mode 100644 index 000000000..66a156e9c --- /dev/null +++ b/regression-tests/23-rpl-non-storing/09-rpl-probing.csc @@ -0,0 +1,256 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype190 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype481 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype692 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 8.0 + 2.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype481 + + + + org.contikios.cooja.interfaces.Position + -7.19071602882406 + 34.96668248624779 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype190 + + + + org.contikios.cooja.interfaces.Position + -17.870288882812428 + 4.581754854333804 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype692 + + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.494541140753371 0.0 0.0 2.494541140753371 168.25302383129448 116.2254386098645 + + 400 + 3 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 597 + 0 + 428 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 605 + 1 + 684 + 604 + 14 + + + diff --git a/regression-tests/23-rpl-non-storing/10-rpl-multi-dodag.csc b/regression-tests/23-rpl-non-storing/10-rpl-multi-dodag.csc new file mode 100644 index 000000000..0f446cc65 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/10-rpl-multi-dodag.csc @@ -0,0 +1,389 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + [APPS_DIR]/serial2pty + [APPS_DIR]/radiologger-headless + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype301 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype820 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype306 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 9.767954940345236 + 88.75813939592845 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype306 + + + + org.contikios.cooja.interfaces.Position + 63.36720084537501 + 75.88456991067605 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype301 + + + + org.contikios.cooja.interfaces.Position + -20.684049350551753 + 60.49767834794315 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype306 + + + + org.contikios.cooja.interfaces.Position + 64.61229064867878 + 39.88729002781773 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype306 + + + + org.contikios.cooja.interfaces.Position + 37.157272454309606 + 19.60335867526139 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype306 + + + + org.contikios.cooja.interfaces.Position + -21.976612887408603 + 30.69884249204435 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype306 + + + + org.contikios.cooja.interfaces.Position + 43 + 98 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype820 + + + + org.contikios.cooja.interfaces.Position + 0.0 + 0.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype820 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 1.7624788498159916 0.0 0.0 1.7624788498159916 97.6893062637241 8.72727272727273 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 1184 + 2 + 240 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 962 + 1 + 596 + 603 + 43 + + + diff --git a/regression-tests/23-rpl-non-storing/Makefile b/regression-tests/23-rpl-non-storing/Makefile new file mode 100644 index 000000000..272bc7da1 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/Makefile @@ -0,0 +1 @@ +include ../Makefile.simulation-test diff --git a/regression-tests/23-rpl-non-storing/code/Makefile b/regression-tests/23-rpl-non-storing/code/Makefile new file mode 100644 index 000000000..616341592 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/code/Makefile @@ -0,0 +1,7 @@ +all: sender-node receiver-node root-node +CONTIKI=../../.. + +CFLAGS+=-DPROJECT_CONF_H=\"project-conf.h\" + +CONTIKI_WITH_IPV6 = 1 +include $(CONTIKI)/Makefile.include diff --git a/regression-tests/23-rpl-non-storing/code/project-conf.h b/regression-tests/23-rpl-non-storing/code/project-conf.h new file mode 100644 index 000000000..9270334fb --- /dev/null +++ b/regression-tests/23-rpl-non-storing/code/project-conf.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, Inria. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ +#define TCPIP_CONF_ANNOTATE_TRANSMISSIONS 1 + +#undef RPL_CONF_MOP +#define RPL_CONF_MOP RPL_MOP_NON_STORING + +/* Add a bit of extra probing in the non-storing case to compensate for reduced DAO traffic */ +#undef RPL_CONF_PROBING_INTERVAL +#define RPL_CONF_PROBING_INTERVAL (60 * CLOCK_SECOND) diff --git a/regression-tests/23-rpl-non-storing/code/receiver-node.c b/regression-tests/23-rpl-non-storing/code/receiver-node.c new file mode 100644 index 000000000..727a23f84 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/code/receiver-node.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2012, Thingsquare, www.thingsquare.com. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +#include "contiki.h" +#include "lib/random.h" +#include "sys/ctimer.h" +#include "sys/etimer.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "net/ip/uip-debug.h" + +#include "simple-udp.h" + +#include "net/rpl/rpl.h" +#include "dev/leds.h" + +#include +#include + +#define UDP_PORT 1234 + +static struct simple_udp_connection unicast_connection; + +/*---------------------------------------------------------------------------*/ +PROCESS(receiver_node_process, "Receiver node"); +AUTOSTART_PROCESSES(&receiver_node_process); +/*---------------------------------------------------------------------------*/ +static void +receiver(struct simple_udp_connection *c, + const uip_ipaddr_t *sender_addr, + uint16_t sender_port, + const uip_ipaddr_t *receiver_addr, + uint16_t receiver_port, + const uint8_t *data, + uint16_t datalen) +{ + printf("Data received from "); + uip_debug_ipaddr_print(sender_addr); + printf(" on port %d from port %d with length %d: '%s'\n", + receiver_port, sender_port, datalen, data); +} +/*---------------------------------------------------------------------------*/ +static uip_ipaddr_t * +set_global_address(void) +{ + static uip_ipaddr_t ipaddr; + int i; + uint8_t state; + + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); + uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); + + printf("IPv6 addresses: "); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && + (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { + uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr); + printf("\n"); + } + } + + return &ipaddr; +} +/*---------------------------------------------------------------------------*/ +uint8_t should_blink = 1; +static void +route_callback(int event, uip_ipaddr_t *route, uip_ipaddr_t *ipaddr, int num_routes) +{ + if(event == UIP_DS6_NOTIFICATION_DEFRT_ADD) { + should_blink = 0; + } else if(event == UIP_DS6_NOTIFICATION_DEFRT_RM) { + should_blink = 1; + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(receiver_node_process, ev, data) +{ + static struct etimer et; + static struct uip_ds6_notification n; + + PROCESS_BEGIN(); + + set_global_address(); + + uip_ds6_notification_add(&n, route_callback); + + simple_udp_register(&unicast_connection, UDP_PORT, + NULL, UDP_PORT, receiver); + + etimer_set(&et, CLOCK_SECOND); + while(1) { + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + if(should_blink) { + leds_on(LEDS_ALL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + leds_off(LEDS_ALL); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/regression-tests/23-rpl-non-storing/code/root-node.c b/regression-tests/23-rpl-non-storing/code/root-node.c new file mode 100644 index 000000000..fdea828f8 --- /dev/null +++ b/regression-tests/23-rpl-non-storing/code/root-node.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2012, Thingsquare, www.thingsquare.com. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + + +#include "contiki.h" +#include "lib/random.h" +#include "sys/ctimer.h" +#include "sys/etimer.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "net/ip/uip-debug.h" + +#include "simple-udp.h" + +#include "net/rpl/rpl.h" + +#include +#include + +#define UDP_PORT 1234 +#define SERVICE_ID 190 + +#define SEND_INTERVAL (10 * CLOCK_SECOND) +#define SEND_TIME (random_rand() % (SEND_INTERVAL)) + +static struct simple_udp_connection unicast_connection; + +/*---------------------------------------------------------------------------*/ +PROCESS(unicast_receiver_process, "Unicast receiver example process"); +AUTOSTART_PROCESSES(&unicast_receiver_process); +/*---------------------------------------------------------------------------*/ +static void +receiver(struct simple_udp_connection *c, + const uip_ipaddr_t *sender_addr, + uint16_t sender_port, + const uip_ipaddr_t *receiver_addr, + uint16_t receiver_port, + const uint8_t *data, + uint16_t datalen) +{ + printf("Data received from "); + uip_debug_ipaddr_print(sender_addr); + printf(" on port %d from port %d with length %d: '%s'\n", + receiver_port, sender_port, datalen, data); +} +/*---------------------------------------------------------------------------*/ +static uip_ipaddr_t * +set_global_address(void) +{ + static uip_ipaddr_t ipaddr; + int i; + uint8_t state; + + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); + uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); + + printf("IPv6 addresses: "); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && + (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { + uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr); + printf("\n"); + } + } + + return &ipaddr; +} +/*---------------------------------------------------------------------------*/ +static void +create_rpl_dag(uip_ipaddr_t *ipaddr) +{ + struct uip_ds6_addr *root_if; + + root_if = uip_ds6_addr_lookup(ipaddr); + if(root_if != NULL) { + rpl_dag_t *dag; + uip_ipaddr_t prefix; + + rpl_set_root(RPL_DEFAULT_INSTANCE, ipaddr); + dag = rpl_get_any_dag(); + uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); + rpl_set_prefix(dag, &prefix, 64); + PRINTF("created a new RPL dag\n"); + } else { + PRINTF("failed to create a new RPL DAG\n"); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(unicast_receiver_process, ev, data) +{ + uip_ipaddr_t *ipaddr; + + PROCESS_BEGIN(); + + ipaddr = set_global_address(); + + create_rpl_dag(ipaddr); + + simple_udp_register(&unicast_connection, UDP_PORT, + NULL, UDP_PORT, receiver); + + while(1) { + PROCESS_WAIT_EVENT(); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/regression-tests/23-rpl-non-storing/code/sender-node.c b/regression-tests/23-rpl-non-storing/code/sender-node.c new file mode 100644 index 000000000..55dfdd15f --- /dev/null +++ b/regression-tests/23-rpl-non-storing/code/sender-node.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2012, Thingsquare, www.thingsquare.com. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + + +#include "contiki.h" +#include "lib/random.h" +#include "sys/ctimer.h" +#include "sys/etimer.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "net/ip/uip-debug.h" + +#include "simple-udp.h" + +#include +#include + +#define UDP_PORT 1234 + +#define SEND_INTERVAL (60 * CLOCK_SECOND) +#define SEND_TIME (random_rand() % (SEND_INTERVAL)) + +static struct simple_udp_connection unicast_connection; + +/*---------------------------------------------------------------------------*/ +PROCESS(sender_node_process, "Sender node process"); +AUTOSTART_PROCESSES(&sender_node_process); +/*---------------------------------------------------------------------------*/ +static void +receiver(struct simple_udp_connection *c, + const uip_ipaddr_t *sender_addr, + uint16_t sender_port, + const uip_ipaddr_t *receiver_addr, + uint16_t receiver_port, + const uint8_t *data, + uint16_t datalen) +{ + printf("Sender received data on port %d from port %d with length %d\n", + receiver_port, sender_port, datalen); +} +/*---------------------------------------------------------------------------*/ +static void +set_global_address(void) +{ + uip_ipaddr_t ipaddr; + int i; + uint8_t state; + + uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); + uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); + + printf("IPv6 addresses: "); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && + (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { + uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr); + printf("\n"); + } + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(sender_node_process, ev, data) +{ + static struct etimer periodic_timer; + static struct etimer send_timer; + uip_ipaddr_t addr; + + PROCESS_BEGIN(); + + set_global_address(); + + simple_udp_register(&unicast_connection, UDP_PORT, + NULL, UDP_PORT, receiver); + + etimer_set(&periodic_timer, SEND_INTERVAL); + while(1) { + + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&periodic_timer)); + etimer_reset(&periodic_timer); + etimer_set(&send_timer, SEND_TIME); + + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&send_timer)); + + uip_ip6addr(&addr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0x0201, 0x001, 0x001, 0x001); + + { + static unsigned int message_number; + char buf[20]; + + printf("Sending unicast to "); + uip_debug_ipaddr_print(&addr); + printf("\n"); + sprintf(buf, "Message %d", message_number); + message_number++; + simple_udp_sendto(&unicast_connection, buf, strlen(buf) + 1, &addr); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/regression-tests/24-compile-nrf52-ports/Makefile b/regression-tests/24-compile-nrf52-ports/Makefile new file mode 100644 index 000000000..bdf5b4a04 --- /dev/null +++ b/regression-tests/24-compile-nrf52-ports/Makefile @@ -0,0 +1,19 @@ +EXAMPLESDIR=../../examples +TOOLSDIR=../../tools + +# Note, that SERVER_IPV6_ADDR variable is set to ffff on purpose +# even though it's not a valid IPV6 address. This is due to limitation +# of the testing framework which splits compliation arguments using +# a colon. + +EXAMPLES = \ +hello-world/nrf52dk \ +nrf52dk/coap-demo/nrf52dk:coap-server \ +nrf52dk/coap-demo/nrf52dk:coap-client:SERVER_IPV6_ADDR=ffff \ +nrf52dk/mqtt-demo/nrf52dk \ +nrf52dk/blink-hello/nrf52dk \ +nrf52dk/timer-test/nrf52dk + +TOOLS= + +include ../Makefile.compile-test diff --git a/regression-tests/Makefile b/regression-tests/Makefile index f705dcdce..efa9cc54c 100644 --- a/regression-tests/Makefile +++ b/regression-tests/Makefile @@ -47,3 +47,5 @@ cooja: $(CONTIKI)/tools/cooja/dist/cooja.jar $(CONTIKI)/tools/cooja/dist/cooja.jar: (cd $(CONTIKI)/tools/cooja; ant jar) +scan-build: + cd scan_build && scan-build $(MAKE) diff --git a/regression-tests/Makefile.compile-test b/regression-tests/Makefile.compile-test index 4ca4e3fd7..fa0f1cf79 100644 --- a/regression-tests/Makefile.compile-test +++ b/regression-tests/Makefile.compile-test @@ -36,12 +36,13 @@ nine := x x x x x x x x x max = $(subst xx,x,$(join ${1},${2})) gt = $(filter-out $(words ${1}),$(words $(call max,${1},${2}))) addzero = $(if $(call gt,${nine},$(1)),$(words ${1}),0$(words ${1})) +get_target = $(firstword $(subst :, ,$1)) +get_target_vars = $(wordlist 2,15,$(subst :, ,$1)) define dooneexample -@echo Building example $(3): $(1) for target $(2) +@echo Building example $(3): $(1) $(4) for target $(2) @((cd $(EXAMPLESDIR)/$(1); \ - export STM32W_CPUREV=CC; \ - make TARGET=$(2) clean && make TARGET=$(2)) > \ + make $(4) TARGET=$(2) clean && make $(4) TARGET=$(2) WERROR=1) > \ $(3)-$(subst /,-,$(1))$(2).report 2>&1 && \ (echo $(1) $(2): OK | tee $(3)-$(subst /,-,$(1))$(2).summary) || \ (echo $(1) $(2): FAIL ಠ.ಠ | tee $(3)-$(subst /,-,$(1))$(2).summary ; \ @@ -50,7 +51,7 @@ endef define doexample $(eval i+=x) -$(call dooneexample,$(dir ${1}),$(notdir ${1}),$(call addzero,${i})) +$(call dooneexample,$(dir $(call get_target,${1})),$(notdir $(call get_target,${1})),$(call addzero,${i}),$(call get_target_vars,${1})) endef #end of GNU make magic diff --git a/regression-tests/Makefile.simulation-test b/regression-tests/Makefile.simulation-test index 5c8b99e40..9995eeea8 100644 --- a/regression-tests/Makefile.simulation-test +++ b/regression-tests/Makefile.simulation-test @@ -29,8 +29,8 @@ TESTS=$(wildcard ??-*.csc) TESTLOGS=$(patsubst %.csc,%.testlog,$(TESTS)) LOGS=$(patsubst %.csc,%.log,$(TESTS)) -FAILLOGS=$(patsubst %.csc,%.faillog,$(TESTS)) -#Set random seed to create reproduceable results. +FAILLOGS=$(patsubst %.csc,%.*.faillog,$(TESTS)) +#Set random seeds to create reproduceable results. RANDOMSEED=1 CONTIKI=../.. @@ -57,7 +57,7 @@ RUNALL=false endif %.testlog: %.csc cooja - @$(CONTIKI)/regression-tests/simexec.sh "$(RUNALL)" "$<" "$(CONTIKI)" "$(basename $@)" "$(RANDOMSEED)" + @$(CONTIKI)/regression-tests/simexec.sh "$(RUNALL)" "$<" "$(CONTIKI)" "$(basename $@)" $(RANDOMSEED) clean: @rm -f $(TESTLOGS) $(LOGS) $(FAILLOGS) COOJA.log COOJA.testlog \ diff --git a/regression-tests/scan_build/Makefile b/regression-tests/scan_build/Makefile new file mode 100644 index 000000000..9ceec7978 --- /dev/null +++ b/regression-tests/scan_build/Makefile @@ -0,0 +1,16 @@ +EXAMPLESDIR=../../examples +TOOLSDIR=../../tools + +EXAMPLES = \ +hello-world/minimal-net \ +hello-world/native \ +eeprom-test/native \ +example-shell/native \ +tcp-socket/minimal-net \ +telnet-server/minimal-net \ +webserver/minimal-net \ +wget/minimal-net \ + +TOOLS= + +include ../Makefile.compile-test diff --git a/regression-tests/simexec.sh b/regression-tests/simexec.sh index 1d1e46b7f..b4bc91e16 100755 --- a/regression-tests/simexec.sh +++ b/regression-tests/simexec.sh @@ -1,66 +1,85 @@ #!/bin/bash +# Do not return an error RUNALL=$1 -CSC=$2 -CONTIKI=$3 -BASENAME=$4 -RANDOMSEED=$5 +shift +# The simulation to run +CSC=$1 +shift +#Contiki directory +CONTIKI=$1 +shift +#The basename of the experiment +BASENAME=$1 +shift +# The test will end on the first successfull run #set -x -echo -n "Running test $BASENAME " +while (( "$#" )); do + RANDOMSEED=$1 + echo -n "Running test $BASENAME with random Seed $RANDOMSEED: " -java -Xshare:on -jar $CONTIKI/tools/cooja/dist/cooja.jar -nogui=$CSC -contiki=$CONTIKI -random-seed=$RANDOMSEED > $BASENAME.log & -JPID=$! + java -Xshare:on -jar $CONTIKI/tools/cooja/dist/cooja.jar -nogui=$CSC -contiki=$CONTIKI -random-seed=$RANDOMSEED > $BASENAME.log & + JPID=$! -# Copy the log and only print "." if it changed -touch $BASENAME.log.prog -while kill -0 $JPID 2> /dev/null -do - sleep 1 - diff $BASENAME.log $BASENAME.log.prog > /dev/null - if [ $? -ne 0 ] - then - echo -n "." - cp $BASENAME.log $BASENAME.log.prog - fi + # Copy the log and only print "." if it changed + touch $BASENAME.log.prog + while kill -0 $JPID 2> /dev/null + do + sleep 1 + diff $BASENAME.log $BASENAME.log.prog > /dev/null + if [ $? -ne 0 ] + then + echo -n "." + cp $BASENAME.log $BASENAME.log.prog + fi + done + rm $BASENAME.log.prog + + + wait $JPID + JRV=$? + + if [ $JRV -eq 0 ] ; then + touch COOJA.testlog; + mv COOJA.testlog $BASENAME.testlog + echo " OK" + exit 0 + fi + + + + # In case of failure + + + + #Verbose output when using CI + if [ "$CI" = "true" ]; then + echo "==== $BASENAME.log ====" ; cat $BASENAME.log; + echo "==== COOJA.testlog ====" ; cat COOJA.testlog; + echo "==== Files used for simulation (sha1sum) ====" + grep "Loading firmware from:" COOJA.log | cut -d " " -f 10 | uniq | xargs -r sha1sum + grep "Creating core communicator between Java class" COOJA.log | cut -d " " -f 17 | uniq | xargs -r sha1sum + else + tail -50 $BASENAME.log ; + fi; + + mv COOJA.testlog $BASENAME.$RANDOMSEED.faillog + + shift done -rm $BASENAME.log.prog - -wait $JPID -JRV=$? - -if [ $JRV -eq 0 ] ; then - touch COOJA.testlog; - mv COOJA.testlog $BASENAME.testlog - echo " OK" - exit 0 -fi - - - -# In case of failure - -echo " FAIL ಠ_ಠ" | tee -a COOJA.testlog; - -#Verbose output when using CI -if [ "$CI" = "true" ]; then - echo "==== COOJA.log ====" ; cat COOJA.log; - echo "==== COOJA.testlog ====" ; cat COOJA.testlog; -else - tail -50 COOJA.log ; -fi; - -mv COOJA.testlog $BASENAME.faillog +#All seeds failed + echo " FAIL ಠ_ಠ" | tee -a $BASENAME.$RANDOMSEED.faillog; # We do not want Make to stop -> Return 0 if [ "$RUNALL" = "true" ] ; then - touch COOJA.testlog; - mv COOJA.testlog $BASENAME.testlog; - exit 0 + touch COOJA.testlog; + mv COOJA.testlog $BASENAME.testlog; + exit 0 fi -#This is a failure + exit 1 diff --git a/tools/6502/Makefile b/tools/6502/Makefile index 6e0d6bd50..d88a4790f 100644 --- a/tools/6502/Makefile +++ b/tools/6502/Makefile @@ -35,10 +35,6 @@ ifndef CONTIKI ${error CONTIKI not defined! You must specify where Contiki resides} endif -ifndef CC65_HOME - ${error CC65_HOME not defined! You must specify where cc65 resides} -endif - ifndef AC ${error AC not defined! You must specify where the AppleCommander jar resides} endif @@ -53,124 +49,119 @@ endif all: apple2 atari c64 c128 +ifeq ($(shell echo),) + NULLDEV = /dev/null +else + NULLDEV = nul: +endif + +ZIPCOMMENT := $(shell git rev-parse --short HEAD 2>$(NULLDEV)) +ifeq ($(words $(ZIPCOMMENT)),1) + ZIPCOMMENT := https://github.com/contiki-os/contiki/commits/$(ZIPCOMMENT) +else + ZIPCOMMENT := N/A +endif + +CC65 := $(shell cl65 --print-target-path) + define makes $1-makes: - $(MAKE) -C ../../cpu/6502/ethconfig TARGET=$1 - $(MAKE) -C ../../cpu/6502/ipconfig TARGET=$1 - $(MAKE) -C ../../examples/webbrowser TARGET=$1 - $(MAKE) -C ../../examples/wget TARGET=$1 - $(MAKE) -C ../../examples/irc TARGET=$1 - $(MAKE) -C ../../../contikiprojects/vandenbrande.com/twitter/platform/$1 - $(MAKE) -C ../../examples/email TARGET=$1 - $(MAKE) -C ../../examples/ftp TARGET=$1 - $(MAKE) -C ../../examples/webserver TARGET=$1 HTTPD-CFS=1 - $(MAKE) -C ../../examples/telnet-server TARGET=$1 + $(MAKE) -C ../../cpu/6502/ethconfig TARGET=$1 + $(MAKE) -C ../../cpu/6502/ipconfig TARGET=$1 + $(MAKE) -C ../../examples/webbrowser TARGET=$1 + $(MAKE) -C ../../examples/webbrowser-80col TARGET=$1 + $(MAKE) -C ../../examples/wget TARGET=$1 + $(MAKE) -C ../../examples/irc TARGET=$1 + $(MAKE) -C ../../examples/irc-80col TARGET=$1 + $(MAKE) -C ../../examples/webserver TARGET=$1 HTTPD-CFS=1 + $(MAKE) -C ../../examples/telnet-server TARGET=$1 endef $(eval $(call makes,apple2enh)) -apple2: contiki-apple2-1.dsk contiki-apple2-2.dsk contiki-apple2-3.dsk contiki-apple2-4.dsk contiki-apple2.2mg +%.zip: + zip $@ $^ + echo $(ZIPCOMMENT) | zip -z $@ + +apple2: contiki-apple2.zip + +contiki-apple2.zip: contiki-apple2-1.dsk contiki-apple2-2.dsk contiki-apple2-3.dsk contiki-apple2.po contiki-apple2-1.dsk: apple2enh-makes cp ../apple2enh/prodos.dsk $@ - java -jar $(AC) -p $@ menu.system sys 0 < ../apple2enh/menu.system - java -jar $(AC) -p $@ ethconfi.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ ethconfi bin 0 < ../../cpu/6502/ethconfig/ethconfig.apple2enh - java -jar $(AC) -p $@ ipconfig.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ ipconfig bin 0 < ../../cpu/6502/ipconfig/ipconfig.apple2enh - java -jar $(AC) -p $@ webbrows.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ webbrows bin < ../../examples/webbrowser/webbrowser.apple2enh - java -jar $(AC) -p $@ wget.system sys 0 < $(CC65_HOME)/targetutil/loader.system + java -jar $(AC) -p $@ menu.system sys < ../apple2enh/menu.system + java -jar $(AC) -p $@ ethconfi.system sys < $(CC65)/apple2enh/util/loader.system + java -jar $(AC) -cc65 $@ ethconfi bin < ../../cpu/6502/ethconfig/ethconfig.apple2enh + java -jar $(AC) -p $@ ipconfig.system sys < $(CC65)/apple2enh/util/loader.system + java -jar $(AC) -cc65 $@ ipconfig bin < ../../cpu/6502/ipconfig/ipconfig.apple2enh + java -jar $(AC) -p $@ webbrows.system sys < $(CC65)/apple2enh/util/loader.system + java -jar $(AC) -cc65 $@ webbrows bin < ../../examples/webbrowser-80col/webbrowser.apple2enh + java -jar $(AC) -p $@ wget.system sys < $(CC65)/apple2enh/util/loader.system java -jar $(AC) -cc65 $@ wget bin < ../../examples/wget/wget.apple2enh java -jar $(AC) -p $@ contiki.cfg bin 0 < ../apple2enh/default.cfg java -jar $(AC) -p $@ cs8900a.eth rel 0 < ../../cpu/6502/ethconfig/cs8900a.eth java -jar $(AC) -p $@ lan91c96.eth rel 0 < ../../cpu/6502/ethconfig/lan91c96.eth java -jar $(AC) -p $@ w5100.eth rel 0 < ../../cpu/6502/ethconfig/w5100.eth - java -jar $(AC) -p $@ contiki.mou rel 0 < $(CC65_HOME)/mou/a2e.stdmou.mou + java -jar $(AC) -p $@ contiki.mou rel 0 < $(CC65)/apple2enh/drv/mou/a2e.stdmou.mou contiki-apple2-2.dsk: apple2enh-makes cp ../apple2enh/prodos.dsk $@ - java -jar $(AC) -p $@ menu.system sys 0 < ../apple2enh/menu.system - java -jar $(AC) -p $@ ethconfi.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ ethconfi bin 0 < ../../cpu/6502/ethconfig/ethconfig.apple2enh - java -jar $(AC) -p $@ ipconfig.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ ipconfig bin 0 < ../../cpu/6502/ipconfig/ipconfig.apple2enh - java -jar $(AC) -p $@ irc.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ irc bin < ../../examples/irc/irc-client.apple2enh - java -jar $(AC) -p $@ breadbox.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ breadbox bin < ../../../contikiprojects/vandenbrande.com/twitter/platform/apple2enh/breadbox64.apple2enh + java -jar $(AC) -p $@ menu.system sys < ../apple2enh/menu.system + java -jar $(AC) -p $@ ethconfi.system sys < $(CC65)/apple2enh/util/loader.system + java -jar $(AC) -cc65 $@ ethconfi bin < ../../cpu/6502/ethconfig/ethconfig.apple2enh + java -jar $(AC) -p $@ ipconfig.system sys < $(CC65)/apple2enh/util/loader.system + java -jar $(AC) -cc65 $@ ipconfig bin < ../../cpu/6502/ipconfig/ipconfig.apple2enh + java -jar $(AC) -p $@ irc.system sys < $(CC65)/apple2enh/util/loader.system + java -jar $(AC) -cc65 $@ irc bin < ../../examples/irc-80col/irc-client.apple2enh java -jar $(AC) -p $@ contiki.cfg bin 0 < ../apple2enh/default.cfg java -jar $(AC) -p $@ cs8900a.eth rel 0 < ../../cpu/6502/ethconfig/cs8900a.eth java -jar $(AC) -p $@ lan91c96.eth rel 0 < ../../cpu/6502/ethconfig/lan91c96.eth java -jar $(AC) -p $@ w5100.eth rel 0 < ../../cpu/6502/ethconfig/w5100.eth - java -jar $(AC) -p $@ contiki.mou rel 0 < $(CC65_HOME)/mou/a2e.stdmou.mou + java -jar $(AC) -p $@ contiki.mou rel 0 < $(CC65)/apple2enh/drv/mou/a2e.stdmou.mou contiki-apple2-3.dsk: apple2enh-makes cp ../apple2enh/prodos.dsk $@ - java -jar $(AC) -p $@ menu.system sys 0 < ../apple2enh/menu.system - java -jar $(AC) -p $@ ethconfi.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ ethconfi bin 0 < ../../cpu/6502/ethconfig/ethconfig.apple2enh - java -jar $(AC) -p $@ ipconfig.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ ipconfig bin 0 < ../../cpu/6502/ipconfig/ipconfig.apple2enh - java -jar $(AC) -p $@ email.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ email bin < ../../examples/email/email-client.apple2enh - java -jar $(AC) -p $@ ftp.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ ftp bin < ../../examples/ftp/ftp-client.apple2enh - java -jar $(AC) -p $@ contiki.cfg bin 0 < ../apple2enh/default.cfg - java -jar $(AC) -p $@ cs8900a.eth rel 0 < ../../cpu/6502/ethconfig/cs8900a.eth - java -jar $(AC) -p $@ lan91c96.eth rel 0 < ../../cpu/6502/ethconfig/lan91c96.eth - java -jar $(AC) -p $@ w5100.eth rel 0 < ../../cpu/6502/ethconfig/w5100.eth - java -jar $(AC) -p $@ contiki.mou rel 0 < $(CC65_HOME)/mou/a2e.stdmou.mou - -contiki-apple2-4.dsk: apple2enh-makes - cp ../apple2enh/prodos.dsk $@ - java -jar $(AC) -p $@ menu.system sys 0 < ../apple2enh/menu.system - java -jar $(AC) -p $@ ethconfi.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ ethconfi bin 0 < ../../cpu/6502/ethconfig/ethconfig.apple2enh - java -jar $(AC) -p $@ ipconfig.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ ipconfig bin 0 < ../../cpu/6502/ipconfig/ipconfig.apple2enh - java -jar $(AC) -p $@ webserv.system sys 0 < $(CC65_HOME)/targetutil/loader.system + java -jar $(AC) -p $@ menu.system sys < ../apple2enh/menu.system + java -jar $(AC) -p $@ ethconfi.system sys < $(CC65)/apple2enh/util/loader.system + java -jar $(AC) -cc65 $@ ethconfi bin < ../../cpu/6502/ethconfig/ethconfig.apple2enh + java -jar $(AC) -p $@ ipconfig.system sys < $(CC65)/apple2enh/util/loader.system + java -jar $(AC) -cc65 $@ ipconfig bin < ../../cpu/6502/ipconfig/ipconfig.apple2enh + java -jar $(AC) -p $@ webserv.system sys < $(CC65)/apple2enh/util/loader.system java -jar $(AC) -cc65 $@ webserv bin < ../../examples/webserver/webserver-example.apple2enh - java -jar $(AC) -p $@ telnetd.system sys 0 < $(CC65_HOME)/targetutil/loader.system + java -jar $(AC) -p $@ telnetd.system sys < $(CC65)/apple2enh/util/loader.system java -jar $(AC) -cc65 $@ telnetd bin < ../../examples/telnet-server/telnet-server.apple2enh java -jar $(AC) -p $@ contiki.cfg bin 0 < ../apple2enh/default.cfg java -jar $(AC) -p $@ cs8900a.eth rel 0 < ../../cpu/6502/ethconfig/cs8900a.eth java -jar $(AC) -p $@ lan91c96.eth rel 0 < ../../cpu/6502/ethconfig/lan91c96.eth java -jar $(AC) -p $@ w5100.eth rel 0 < ../../cpu/6502/ethconfig/w5100.eth - java -jar $(AC) -p $@ contiki.mou rel 0 < $(CC65_HOME)/mou/a2e.stdmou.mou + java -jar $(AC) -p $@ contiki.mou rel 0 < $(CC65)/apple2enh/drv/mou/a2e.stdmou.mou java -jar $(AC) -p $@ index.htm bin 0 < ../../examples/webserver/httpd-cfs/index.htm java -jar $(AC) -p $@ backgrnd.gif bin 0 < ../../examples/webserver/httpd-cfs/backgrnd.gif java -jar $(AC) -p $@ contiki.gif bin 0 < ../../examples/webserver/httpd-cfs/contiki.gif java -jar $(AC) -p $@ notfound.htm bin 0 < ../../examples/webserver/httpd-cfs/notfound.htm -contiki-apple2.2mg: apple2enh-makes - cp ../apple2enh/prodos.2mg $@ - java -jar $(AC) -p $@ menu.system sys 0 < ../apple2enh/menu.system - java -jar $(AC) -p $@ ethconfi.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ ethconfi bin 0 < ../../cpu/6502/ethconfig/ethconfig.apple2enh - java -jar $(AC) -p $@ ipconfig.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ ipconfig bin 0 < ../../cpu/6502/ipconfig/ipconfig.apple2enh - java -jar $(AC) -p $@ webbrows.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ webbrows bin < ../../examples/webbrowser/webbrowser.apple2enh - java -jar $(AC) -p $@ wget.system sys 0 < $(CC65_HOME)/targetutil/loader.system +contiki-apple2.po: apple2enh-makes + cp ../apple2enh/prodos.po $@ + java -jar $(AC) -p $@ menu.system sys < ../apple2enh/menu.system + java -jar $(AC) -p $@ ethconfi.system sys < $(CC65)/apple2enh/util/loader.system + java -jar $(AC) -cc65 $@ ethconfi bin < ../../cpu/6502/ethconfig/ethconfig.apple2enh + java -jar $(AC) -p $@ ipconfig.system sys < $(CC65)/apple2enh/util/loader.system + java -jar $(AC) -cc65 $@ ipconfig bin < ../../cpu/6502/ipconfig/ipconfig.apple2enh + java -jar $(AC) -p $@ webbrows.system sys < $(CC65)/apple2enh/util/loader.system + java -jar $(AC) -cc65 $@ webbrows bin < ../../examples/webbrowser-80col/webbrowser.apple2enh + java -jar $(AC) -p $@ wget.system sys < $(CC65)/apple2enh/util/loader.system java -jar $(AC) -cc65 $@ wget bin < ../../examples/wget/wget.apple2enh - java -jar $(AC) -p $@ irc.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ irc bin < ../../examples/irc/irc-client.apple2enh - java -jar $(AC) -p $@ breadbox.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ breadbox bin < ../../../contikiprojects/vandenbrande.com/twitter/platform/apple2enh/breadbox64.apple2enh - java -jar $(AC) -p $@ email.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ email bin < ../../examples/email/email-client.apple2enh - java -jar $(AC) -p $@ ftp.system sys 0 < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ ftp bin < ../../examples/ftp/ftp-client.apple2enh - java -jar $(AC) -p $@ webserv.system sys 0 < $(CC65_HOME)/targetutil/loader.system + java -jar $(AC) -p $@ irc.system sys < $(CC65)/apple2enh/util/loader.system + java -jar $(AC) -cc65 $@ irc bin < ../../examples/irc-80col/irc-client.apple2enh + java -jar $(AC) -p $@ webserv.system sys < $(CC65)/apple2enh/util/loader.system java -jar $(AC) -cc65 $@ webserv bin < ../../examples/webserver/webserver-example.apple2enh - java -jar $(AC) -p $@ telnetd.system sys 0 < $(CC65_HOME)/targetutil/loader.system + java -jar $(AC) -p $@ telnetd.system sys < $(CC65)/apple2enh/util/loader.system java -jar $(AC) -cc65 $@ telnetd bin < ../../examples/telnet-server/telnet-server.apple2enh java -jar $(AC) -p $@ contiki.cfg bin 0 < ../apple2enh/default.cfg java -jar $(AC) -p $@ cs8900a.eth rel 0 < ../../cpu/6502/ethconfig/cs8900a.eth java -jar $(AC) -p $@ lan91c96.eth rel 0 < ../../cpu/6502/ethconfig/lan91c96.eth java -jar $(AC) -p $@ w5100.eth rel 0 < ../../cpu/6502/ethconfig/w5100.eth - java -jar $(AC) -p $@ contiki.mou rel 0 < $(CC65_HOME)/mou/a2e.stdmou.mou + java -jar $(AC) -p $@ contiki.mou rel 0 < $(CC65)/apple2enh/drv/mou/a2e.stdmou.mou java -jar $(AC) -p $@ index.htm bin 0 < ../../examples/webserver/httpd-cfs/index.htm java -jar $(AC) -p $@ backgrnd.gif bin 0 < ../../examples/webserver/httpd-cfs/backgrnd.gif java -jar $(AC) -p $@ contiki.gif bin 0 < ../../examples/webserver/httpd-cfs/contiki.gif @@ -178,7 +169,9 @@ contiki-apple2.2mg: apple2enh-makes $(eval $(call makes,atarixl)) -atari: contiki-atari-1.atr contiki-atari-2.atr contiki-atari-3.atr contiki-atari-4.atr contiki-atari.atr +atari: contiki-atari.zip + +contiki-atari.zip: contiki-atari-1.atr contiki-atari-2.atr contiki-atari-3.atr contiki-atari.atr contiki-atari-1.atr: atarixl-makes mkdir atr @@ -189,49 +182,31 @@ contiki-atari-1.atr: atarixl-makes cp ../../examples/wget/wget.atarixl atr/wget.com cp ../atarixl/default.cfg atr/contiki.cfg cp ../../cpu/6502/ethconfig/cs8900a.eth atr/cs8900a.eth - cp $(CC65_HOME)/mou/atrxst.mou atr/contiki.mou - cp $(CC65_HOME)/mou/atrxami.mou atr/ami.mou - cp $(CC65_HOME)/mou/atrxjoy.mou atr/joy.mou - cp $(CC65_HOME)/mou/atrxtrk.mou atr/trk.mou - cp $(CC65_HOME)/mou/atrxtt.mou atr/tt.mou + cp $(CC65)/atarixl/drv/mou/atrxst.mou atr/contiki.mou + cp $(CC65)/atarixl/drv/mou/atrxami.mou atr/ami.mou + cp $(CC65)/atarixl/drv/mou/atrxjoy.mou atr/joy.mou + cp $(CC65)/atarixl/drv/mou/atrxtrk.mou atr/trk.mou + cp $(CC65)/atarixl/drv/mou/atrxtt.mou atr/tt.mou $(DIR2ATR) -b Dos25 1040 $@ atr rm -r atr contiki-atari-2.atr: atarixl-makes mkdir atr - cp ../atarixl/dos25/dos.sys atr/dos.sys - cp ../atarixl/dos25/dup.sys atr/dup.sys - cp ../../cpu/6502/ipconfig/ipconfig.atarixl atr/ipconfig.com - cp ../../examples/irc/irc-client.atarixl atr/irc.com - cp ../../../contikiprojects/vandenbrande.com/twitter/platform/atarixl/breadbox64.atarixl atr/breadbox.com - cp ../atarixl/default.cfg atr/contiki.cfg - cp ../../cpu/6502/ethconfig/cs8900a.eth atr/cs8900a.eth - cp $(CC65_HOME)/mou/atrxst.mou atr/contiki.mou - cp $(CC65_HOME)/mou/atrxami.mou atr/ami.mou - cp $(CC65_HOME)/mou/atrxjoy.mou atr/joy.mou - cp $(CC65_HOME)/mou/atrxtrk.mou atr/trk.mou - cp $(CC65_HOME)/mou/atrxtt.mou atr/tt.mou + cp ../atarixl/dos25/dos.sys atr/dos.sys + cp ../atarixl/dos25/dup.sys atr/dup.sys + cp ../../cpu/6502/ipconfig/ipconfig.atarixl atr/ipconfig.com + cp ../../examples/irc/irc-client.atarixl atr/irc.com + cp ../atarixl/default.cfg atr/contiki.cfg + cp ../../cpu/6502/ethconfig/cs8900a.eth atr/cs8900a.eth + cp $(CC65)/atarixl/drv/mou/atrxst.mou atr/contiki.mou + cp $(CC65)/atarixl/drv/mou/atrxami.mou atr/ami.mou + cp $(CC65)/atarixl/drv/mou/atrxjoy.mou atr/joy.mou + cp $(CC65)/atarixl/drv/mou/atrxtrk.mou atr/trk.mou + cp $(CC65)/atarixl/drv/mou/atrxtt.mou atr/tt.mou $(DIR2ATR) -b Dos25 1040 $@ atr rm -r atr contiki-atari-3.atr: atarixl-makes - mkdir atr - cp ../atarixl/dos25/dos.sys atr/dos.sys - cp ../atarixl/dos25/dup.sys atr/dup.sys - cp ../../cpu/6502/ipconfig/ipconfig.atarixl atr/ipconfig.com - cp ../../examples/email/email-client.atarixl atr/email.com - cp ../../examples/ftp/ftp-client.atarixl atr/ftp.com - cp ../atarixl/default.cfg atr/contiki.cfg - cp ../../cpu/6502/ethconfig/cs8900a.eth atr/cs8900a.eth - cp $(CC65_HOME)/mou/atrxst.mou atr/contiki.mou - cp $(CC65_HOME)/mou/atrxami.mou atr/ami.mou - cp $(CC65_HOME)/mou/atrxjoy.mou atr/joy.mou - cp $(CC65_HOME)/mou/atrxtrk.mou atr/trk.mou - cp $(CC65_HOME)/mou/atrxtt.mou atr/tt.mou - $(DIR2ATR) -b Dos25 1040 $@ atr - rm -r atr - -contiki-atari-4.atr: atarixl-makes mkdir atr cp ../atarixl/dos25/dos.sys atr/dos.sys cp ../atarixl/dos25/dup.sys atr/dup.sys @@ -240,11 +215,11 @@ contiki-atari-4.atr: atarixl-makes cp ../../examples/telnet-server/telnet-server.atarixl atr/telnetd.com cp ../atarixl/default.cfg atr/contiki.cfg cp ../../cpu/6502/ethconfig/cs8900a.eth atr/cs8900a.eth - cp $(CC65_HOME)/mou/atrxst.mou atr/contiki.mou - cp $(CC65_HOME)/mou/atrxami.mou atr/ami.mou - cp $(CC65_HOME)/mou/atrxjoy.mou atr/joy.mou - cp $(CC65_HOME)/mou/atrxtrk.mou atr/trk.mou - cp $(CC65_HOME)/mou/atrxtt.mou atr/tt.mou + cp $(CC65)/atarixl/drv/mou/atrxst.mou atr/contiki.mou + cp $(CC65)/atarixl/drv/mou/atrxami.mou atr/ami.mou + cp $(CC65)/atarixl/drv/mou/atrxjoy.mou atr/joy.mou + cp $(CC65)/atarixl/drv/mou/atrxtrk.mou atr/trk.mou + cp $(CC65)/atarixl/drv/mou/atrxtt.mou atr/tt.mou cp ../../examples/webserver/httpd-cfs/index.htm atr/index.htm cp ../../examples/webserver/httpd-cfs/backgrnd.gif atr/backgrnd.gif cp ../../examples/webserver/httpd-cfs/contiki.gif atr/contiki.gif @@ -254,207 +229,188 @@ contiki-atari-4.atr: atarixl-makes contiki-atari.atr: atarixl-makes mkdir atr - cp ../atarixl/mydos4534/dos.sys atr/dos.sys - cp ../atarixl/mydos4534/dup.sys atr/dup.sys - cp ../../cpu/6502/ipconfig/ipconfig.atarixl atr/ipconfig.com - cp ../../examples/webbrowser/webbrowser.atarixl atr/webbrows.com - cp ../../examples/wget/wget.atarixl atr/wget.com - cp ../../examples/irc/irc-client.atarixl atr/irc.com - cp ../../../contikiprojects/vandenbrande.com/twitter/platform/atarixl/breadbox64.atarixl atr/breadbox.com - cp ../../examples/email/email-client.atarixl atr/email.com - cp ../../examples/ftp/ftp-client.atarixl atr/ftp.com - cp ../../examples/webserver/webserver-example.atarixl atr/webserv.com - cp ../../examples/telnet-server/telnet-server.atarixl atr/telnetd.com - cp ../atarixl/default.cfg atr/contiki.cfg - cp ../../cpu/6502/ethconfig/cs8900a.eth atr/cs8900a.eth - cp $(CC65_HOME)/mou/atrxst.mou atr/contiki.mou - cp $(CC65_HOME)/mou/atrxami.mou atr/ami.mou - cp $(CC65_HOME)/mou/atrxjoy.mou atr/joy.mou - cp $(CC65_HOME)/mou/atrxtrk.mou atr/trk.mou - cp $(CC65_HOME)/mou/atrxtt.mou atr/tt.mou - cp ../../examples/webserver/httpd-cfs/index.htm atr/index.htm - cp ../../examples/webserver/httpd-cfs/backgrnd.gif atr/backgrnd.gif - cp ../../examples/webserver/httpd-cfs/contiki.gif atr/contiki.gif - cp ../../examples/webserver/httpd-cfs/notfound.htm atr/notfound.htm + cp ../atarixl/mydos4534/dos.sys atr/dos.sys + cp ../atarixl/mydos4534/dup.sys atr/dup.sys + cp ../../cpu/6502/ipconfig/ipconfig.atarixl atr/ipconfig.com + cp ../../examples/webbrowser/webbrowser.atarixl atr/webbrows.com + cp ../../examples/wget/wget.atarixl atr/wget.com + cp ../../examples/irc/irc-client.atarixl atr/irc.com + cp ../../examples/webserver/webserver-example.atarixl atr/webserv.com + cp ../../examples/telnet-server/telnet-server.atarixl atr/telnetd.com + cp ../atarixl/default.cfg atr/contiki.cfg + cp ../../cpu/6502/ethconfig/cs8900a.eth atr/cs8900a.eth + cp $(CC65)/atarixl/drv/mou/atrxst.mou atr/contiki.mou + cp $(CC65)/atarixl/drv/mou/atrxami.mou atr/ami.mou + cp $(CC65)/atarixl/drv/mou/atrxjoy.mou atr/joy.mou + cp $(CC65)/atarixl/drv/mou/atrxtrk.mou atr/trk.mou + cp $(CC65)/atarixl/drv/mou/atrxtt.mou atr/tt.mou + cp ../../examples/webserver/httpd-cfs/index.htm atr/index.htm + cp ../../examples/webserver/httpd-cfs/backgrnd.gif atr/backgrnd.gif + cp ../../examples/webserver/httpd-cfs/contiki.gif atr/contiki.gif + cp ../../examples/webserver/httpd-cfs/notfound.htm atr/notfound.htm $(DIR2ATR) -d -b MyDos4534 3200 $@ atr rm -r atr $(eval $(call makes,c64)) -c64: contiki-c64-1.d64 contiki-c64-2.d64 contiki-c64-3.d64 contiki-c64.d71 contiki-c64.d81 +c64: contiki-c64.zip + +contiki-c64.zip: contiki-c64-1.d64 contiki-c64-2.d64 contiki-c64-3.d64 contiki-c64.d71 contiki-c64.d81 contiki-c64-1.d64: c64-makes $(C1541) -format contiki-1,00 d64 $@ - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c64 ethconfig,p - $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c64 ipconfig,p - $(C1541) -attach $@ -write ../../examples/webbrowser/webbrowser.c64 webbrowser,p - $(C1541) -attach $@ -write ../../examples/wget/wget.c64 wget,p - $(C1541) -attach $@ -write ../../examples/irc/irc-client.c64 irc,p - $(C1541) -attach $@ -write ../c64/default.cfg contiki.cfg,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-1351.mou contiki.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-inkwell.mou inkwell.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-joy.mou joy.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-pot.mou pot.mou,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c64 ethconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c64 ipconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webbrowser/webbrowser.c64 webbrowser,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webbrowser-80col/webbrowser.c64 webbrowser80,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/wget/wget.c64 wget,p >$(NULLDEV) + $(C1541) -attach $@ -write ../c64/default.cfg contiki.cfg,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-1351.mou contiki.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-inkwell.mou inkwell.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-joy.mou joy.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-pot.mou pot.mou,s >$(NULLDEV) contiki-c64-2.d64: c64-makes $(C1541) -format contiki-2,00 d64 $@ - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c64 ethconfig,p - $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c64 ipconfig,p - $(C1541) -attach $@ -write ../../../contikiprojects/vandenbrande.com/twitter/platform/c64/breadbox64.c64 breadbox64,p - $(C1541) -attach $@ -write ../../examples/email/email-client.c64 email,p - $(C1541) -attach $@ -write ../../examples/ftp/ftp-client.c64 ftp,p - $(C1541) -attach $@ -write ../c64/default.cfg contiki.cfg,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-1351.mou contiki.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-inkwell.mou inkwell.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-joy.mou joy.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-pot.mou pot.mou,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c64 ethconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c64 ipconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/irc/irc-client.c64 irc,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/irc-80col/irc-client.c64 irc80,p >$(NULLDEV) + $(C1541) -attach $@ -write ../c64/default.cfg contiki.cfg,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-1351.mou contiki.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-inkwell.mou inkwell.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-joy.mou joy.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-pot.mou pot.mou,s >$(NULLDEV) contiki-c64-3.d64: c64-makes $(C1541) -format contiki-3,00 d64 $@ - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c64 ethconfig,p - $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c64 ipconfig,p - $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c64 webserver,p - $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c64 telnetd,p - $(C1541) -attach $@ -write ../c64/default.cfg contiki.cfg,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-1351.mou contiki.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-inkwell.mou inkwell.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-joy.mou joy.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-pot.mou pot.mou,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c64 ethconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c64 ipconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c64 webserver,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c64 telnetd,p >$(NULLDEV) + $(C1541) -attach $@ -write ../c64/default.cfg contiki.cfg,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-1351.mou contiki.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-inkwell.mou inkwell.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-joy.mou joy.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-pot.mou pot.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s >$(NULLDEV) contiki-c64.d71: c64-makes $(C1541) -format contiki,00 d71 $@ - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c64 ethconfig,p - $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c64 ipconfig,p - $(C1541) -attach $@ -write ../../examples/webbrowser/webbrowser.c64 webbrowser,p - $(C1541) -attach $@ -write ../../examples/wget/wget.c64 wget,p - $(C1541) -attach $@ -write ../../examples/irc/irc-client.c64 irc,p - $(C1541) -attach $@ -write ../../../contikiprojects/vandenbrande.com/twitter/platform/c64/breadbox64.c64 breadbox64,p - $(C1541) -attach $@ -write ../../examples/email/email-client.c64 email,p - $(C1541) -attach $@ -write ../../examples/ftp/ftp-client.c64 ftp,p - $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c64 webserver,p - $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c64 telnetd,p - $(C1541) -attach $@ -write ../c64/default.cfg contiki.cfg,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-1351.mou contiki.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-inkwell.mou inkwell.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-joy.mou joy.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-pot.mou pot.mou,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c64 ethconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c64 ipconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webbrowser/webbrowser.c64 webbrowser,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webbrowser-80col/webbrowser.c64 webbrowser80,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/wget/wget.c64 wget,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/irc/irc-client.c64 irc,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/irc-80col/irc-client.c64 irc80,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c64 webserver,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c64 telnetd,p >$(NULLDEV) + $(C1541) -attach $@ -write ../c64/default.cfg contiki.cfg,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-1351.mou contiki.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-inkwell.mou inkwell.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-joy.mou joy.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-pot.mou pot.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s >$(NULLDEV) contiki-c64.d81: c64-makes $(C1541) -format contiki,00 d81 $@ - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c64 ethconfig,p - $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c64 ipconfig,p - $(C1541) -attach $@ -write ../../examples/webbrowser/webbrowser.c64 webbrowser,p - $(C1541) -attach $@ -write ../../examples/wget/wget.c64 wget,p - $(C1541) -attach $@ -write ../../examples/irc/irc-client.c64 irc,p - $(C1541) -attach $@ -write ../../../contikiprojects/vandenbrande.com/twitter/platform/c64/breadbox64.c64 breadbox64,p - $(C1541) -attach $@ -write ../../examples/email/email-client.c64 email,p - $(C1541) -attach $@ -write ../../examples/ftp/ftp-client.c64 ftp,p - $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c64 webserver,p - $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c64 telnetd,p - $(C1541) -attach $@ -write ../c64/default.cfg contiki.cfg,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-1351.mou contiki.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-inkwell.mou inkwell.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-joy.mou joy.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-pot.mou pot.mou,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c64 ethconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c64 ipconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webbrowser/webbrowser.c64 webbrowser,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webbrowser-80col/webbrowser.c64 webbrowser80,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/wget/wget.c64 wget,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/irc/irc-client.c64 irc,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/irc-80col/irc-client.c64 irc80,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c64 webserver,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c64 telnetd,p >$(NULLDEV) + $(C1541) -attach $@ -write ../c64/default.cfg contiki.cfg,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-1351.mou contiki.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-inkwell.mou inkwell.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-joy.mou joy.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write $(CC65)/c64/drv/mou/c64-pot.mou pot.mou,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s >$(NULLDEV) $(eval $(call makes,c128)) -c128: contiki-c128-1.d64 contiki-c128-2.d64 contiki-c128-3.d64 contiki-c128.d71 contiki-c128.d81 +c128: contiki-c128.zip + +contiki-c128.zip: contiki-c128-1.d64 contiki-c128-2.d64 contiki-c128.d71 contiki-c128.d81 contiki-c128-1.d64: c128-makes $(C1541) -format contiki-1,00 d64 $@ - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c128 ethconfig,p - $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c128 ipconfig,p - $(C1541) -attach $@ -write ../../examples/webbrowser/webbrowser.c128 webbrowser,p - $(C1541) -attach $@ -write ../../examples/wget/wget.c128 wget,p - $(C1541) -attach $@ -write ../../examples/irc/irc-client.c128 irc,p - $(C1541) -attach $@ -write ../c128/default.cfg contiki.cfg,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c128 ethconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c128 ipconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webbrowser-80col/webbrowser.c128 webbrowser,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/wget/wget.c128 wget,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/irc-80col/irc-client.c128 irc,p >$(NULLDEV) + $(C1541) -attach $@ -write ../c128/default.cfg contiki.cfg,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s >$(NULLDEV) contiki-c128-2.d64: c128-makes - $(C1541) -format contiki-2,00 d64 $@ - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c128 ethconfig,p - $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c128 ipconfig,p - $(C1541) -attach $@ -write ../../../contikiprojects/vandenbrande.com/twitter/platform/c128/breadbox64.c128 breadbox64,p - $(C1541) -attach $@ -write ../../examples/email/email-client.c128 email,p - $(C1541) -attach $@ -write ../../examples/ftp/ftp-client.c128 ftp,p - $(C1541) -attach $@ -write ../c128/default.cfg contiki.cfg,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s - -contiki-c128-3.d64: c128-makes $(C1541) -format contiki-3,00 d64 $@ - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c128 ethconfig,p - $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c128 ipconfig,p - $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c128 webserver,p - $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c128 telnetd,p - $(C1541) -attach $@ -write ../c128/default.cfg contiki.cfg,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c128 ethconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c128 ipconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c128 webserver,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c128 telnetd,p >$(NULLDEV) + $(C1541) -attach $@ -write ../c128/default.cfg contiki.cfg,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s >$(NULLDEV) contiki-c128.d71: c128-makes $(C1541) -format contiki,00 d71 $@ - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c128 ethconfig,p - $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c128 ipconfig,p - $(C1541) -attach $@ -write ../../examples/webbrowser/webbrowser.c128 webbrowser,p - $(C1541) -attach $@ -write ../../examples/wget/wget.c128 wget,p - $(C1541) -attach $@ -write ../../examples/irc/irc-client.c128 irc,p - $(C1541) -attach $@ -write ../../../contikiprojects/vandenbrande.com/twitter/platform/c128/breadbox64.c128 breadbox64,p - $(C1541) -attach $@ -write ../../examples/email/email-client.c128 email,p - $(C1541) -attach $@ -write ../../examples/ftp/ftp-client.c128 ftp,p - $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c128 webserver,p - $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c128 telnetd,p - $(C1541) -attach $@ -write ../c128/default.cfg contiki.cfg,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c128 ethconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c128 ipconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webbrowser-80col/webbrowser.c128 webbrowser,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/wget/wget.c128 wget,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/irc-80col/irc-client.c128 irc,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c128 webserver,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c128 telnetd,p >$(NULLDEV) + $(C1541) -attach $@ -write ../c128/default.cfg contiki.cfg,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s >$(NULLDEV) contiki-c128.d81: c128-makes $(C1541) -format contiki,00 d81 $@ - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c128 ethconfig,p - $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c128 ipconfig,p - $(C1541) -attach $@ -write ../../examples/webbrowser/webbrowser.c128 webbrowser,p - $(C1541) -attach $@ -write ../../examples/wget/wget.c128 wget,p - $(C1541) -attach $@ -write ../../examples/irc/irc-client.c128 irc,p - $(C1541) -attach $@ -write ../../../contikiprojects/vandenbrande.com/twitter/platform/c128/breadbox64.c128 breadbox64,p - $(C1541) -attach $@ -write ../../examples/email/email-client.c128 email,p - $(C1541) -attach $@ -write ../../examples/ftp/ftp-client.c128 ftp,p - $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c128 webserver,p - $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c128 telnetd,p - $(C1541) -attach $@ -write ../c128/default.cfg contiki.cfg,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c128 ethconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c128 ipconfig,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webbrowser-80col/webbrowser.c128 webbrowser,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/wget/wget.c128 wget,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/irc-80col/irc-client.c128 irc,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c128 webserver,p >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c128 telnetd,p >$(NULLDEV) + $(C1541) -attach $@ -write ../c128/default.cfg contiki.cfg,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s >$(NULLDEV) + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s >$(NULLDEV) diff --git a/tools/Makefile b/tools/Makefile index a1529c352..3dab44216 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,4 +1,6 @@ -all: codeprop tunslip +all: tunslip + +tunslip6: tools-utils.c tunslip6.c gitclean: @git clean -d -x -n .. @@ -20,4 +22,4 @@ cleantargets: @rm -f -v ${addprefix ../examples/*/*., ${shell ls ../platform/}} @rm -f -v ${addprefix ../examples/*/*/*., ${shell ls ../platform/}} cleandone: - @echo ${info All done!} \ No newline at end of file + @echo ${info All done!} diff --git a/tools/apple2enh/prodos.2mg b/tools/apple2enh/prodos.po similarity index 100% rename from tools/apple2enh/prodos.2mg rename to tools/apple2enh/prodos.po diff --git a/tools/blaster/Makefile b/tools/blaster/Makefile new file mode 100644 index 000000000..ceafb5cca --- /dev/null +++ b/tools/blaster/Makefile @@ -0,0 +1,19 @@ +CC = gcc +CFLAGS = -Wall -g +HEADERS = + +all: blaster + +depend: + sudo apt-get install libconfig8-dev uuid-dev libqrencode-dev + +%.o: %.c $(HEADERS) + $(CC) -c $(CFLAGS) -o $@ $< + +blaster: blaster.o + $(CC) $(CFLAGS) -o $@ $^ -lconfig -luuid -lqrencode + +clean: + rm *.o blaster + +.PHONY: all depend clean diff --git a/tools/blaster/README b/tools/blaster/README new file mode 100644 index 000000000..7fd109460 --- /dev/null +++ b/tools/blaster/README @@ -0,0 +1,10 @@ +Blaster extends the compiled firmware with additional data for +storing into flash memory. See examples/econotag-flash-test for +usage. Its written for Econotag / MC1322X + +./blaster [ ...] +To Generate a default configuration file, use blaster without parameter. + +Its important to use -l as a flash parameter. + +mc1322x-load -f flasher_econotag.bin -s firmware.bin -t /dev/ttyUSB1 -l diff --git a/tools/blaster/blaster.c b/tools/blaster/blaster.c new file mode 100644 index 000000000..ff074c479 --- /dev/null +++ b/tools/blaster/blaster.c @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "blaster.h" + +char *anschars = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-"; + +/* ---------------------------------------------------------------------------- */ + +FILE *openFile(const char *name, const char *appendix, const char *mode); +void writeStandardConfig(); +void writeImg(FILE *file, unsigned char *data, int width); + +/* ---------------------------------------------------------------------------- */ + +int +main(int nArgs, char **argv) +{ + unsigned int c, i, config; + unsigned int buf[64]; + + if(nArgs < 2) { + writeStandardConfig(); + + fprintf(stderr, "Missing parameter: ./blaster [ ...]\n"); + fprintf(stderr, "Configuration template was created ib config.cfg.\n"); + + exit(EXIT_FAILURE); + } + + /* qrdata = "UUID:PSK\0" */ + char qrdata[54]; + qrdata[36] = ':'; + qrdata[53] = '\0'; + + config_t cfg; + for(config = 1; config < nArgs; config++) { + config_init(&cfg); + config_setting_t *setting; + const char *str_val; + if(access(argv[config], F_OK) == 0) { + config_read_file(&cfg, argv[config]); + } else { + fprintf(stderr, "Unable to read config file.\n"); + exit(EXIT_FAILURE); + } + fprintf(stdout, "Working on %s ... ", argv[config]); + + config_lookup_string(&cfg, "input", &str_val); + FILE *in_bin = openFile(str_val, ".bin", "r"); + + config_lookup_string(&cfg, "output", &str_val); + FILE *out_bin = openFile(str_val, ".bin", "w"); + FILE *out_txt = openFile(str_val, ".txt", "w"); + FILE *out_pbm = openFile(str_val, ".pbm", "w"); + + char output[131072]; + for(i = 8; (c = fgetc(in_bin)) != EOF; i++) { + output[i] = (unsigned char)c; + } + /* Set original length of firmware in little endian format ------------------- */ + unsigned int length = i - 8; + memcpy(output + 4, (const void *)&length, 4); + fprintf(out_txt, "Length: %u = 0x%08x\n", length, length); + + /* Fill additional flash with zeros for initialisation */ + for(; i < 0x1F000; i++) { + output[i] = 0x00; + } + + /* Example: Write an CoRE-Link-Answer for CoAP -------------------------------- */ + char *buffer = ";rt=\"dev.info\";if=\"core.rp\"," + ";rt=\"dev.info\";if=\"core.rp\"," + ";rt=\"dev.info\";if=\"core.rp\""; + memcpy(output + RES_D_CORE, buffer, LEN_D_CORE); + + /* Contiki configuration ------------------------------------------------------ */ + output[RES_CONFIG + 0] = 0x22; + output[RES_CONFIG + 1] = 0x13; + output[RES_CONFIG + 2] = 1; + output[RES_CONFIG + 3] = 0; + + setting = config_lookup(&cfg, "eui"); + for(i = 0; i < 8; i++) { + output[RES_CONFIG + 8 + i] = config_setting_get_int_elem(setting, 7 - i); + } + fprintf(out_txt, + "EUI: %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n", + (uint8_t)output[RES_CONFIG + 15], + (uint8_t)output[RES_CONFIG + 14], + (uint8_t)output[RES_CONFIG + 13], + (uint8_t)output[RES_CONFIG + 12], + (uint8_t)output[RES_CONFIG + 11], + (uint8_t)output[RES_CONFIG + 10], + (uint8_t)output[RES_CONFIG + 9], + (uint8_t)output[RES_CONFIG + 8] + ); + + output[RES_CONFIG + 16] = 15; + output[RES_CONFIG + 17] = 17; + output[RES_CONFIG + 18] = 0; + output[RES_CONFIG + 19] = 0; + output[RES_CONFIG + 20] = 5; + output[RES_CONFIG + 21] = 0; + output[RES_CONFIG + 22] = 0; + output[RES_CONFIG + 23] = 0; + + /* Example: Set UUID ---------------------------------------------------------- */ + config_lookup_string(&cfg, "uuid", &str_val); + memcpy(qrdata, str_val, 36); + unsigned char uuid_bin[16]; + uuid_parse(str_val, uuid_bin); + for(i = 0; i < 16; i++) { + output[RES_UUID + i] = uuid_bin[i]; + } + fprintf(out_txt, "UUID: %s\n", str_val); + + /* Example: Set PSK ----------------------------------------------------------- */ + config_lookup_string(&cfg, "psk", &str_val); + memcpy(qrdata + 37, str_val, 16); + for(i = 0; i < 16; i++) { + output[RES_PSK + i] = str_val[i]; + } + fprintf(out_txt, "PSK: %.*s\n", 16, str_val); + memcpy(output + RES_ANSCHARS, anschars, LEN_ANSCHARS); + + /* Example: ECC base point and order for secp256r1 ---------------------------- */ + uint32_t *base_x = (uint32_t *)(output + RES_ECC_BASE_X); + base_x[0] = 0xd898c296; + base_x[1] = 0xf4a13945; + base_x[2] = 0x2deb33a0; + base_x[3] = 0x77037d81; + base_x[4] = 0x63a440f2; + base_x[5] = 0xf8bce6e5; + base_x[6] = 0xe12c4247; + base_x[7] = 0x6b17d1f2; + + uint32_t *base_y = (uint32_t *)(output + RES_ECC_BASE_Y); + base_y[0] = 0x37bf51f5; + base_y[1] = 0xcbb64068; + base_y[2] = 0x6b315ece; + base_y[3] = 0x2bce3357; + base_y[4] = 0x7c0f9e16; + base_y[5] = 0x8ee7eb4a; + base_y[6] = 0xfe1a7f9b; + base_y[7] = 0x4fe342e2; + + uint32_t *order = (uint32_t *)(output + RES_ECC_ORDER); + order[0] = 0xFC632551; + order[1] = 0xF3B9CAC2; + order[2] = 0xA7179E84; + order[3] = 0xBCE6FAAD; + order[4] = 0xFFFFFFFF; + order[5] = 0xFFFFFFFF; + order[6] = 0x00000000; + order[7] = 0xFFFFFFFF; + + /* Example: Set name ---------------------------------------------------------- */ + config_lookup_string(&cfg, "name", &str_val); + snprintf(output + RES_NAME, LEN_NAME, "%s", str_val); + fprintf(out_txt, "Name: %s\n", str_val); + + /* Example: Set model---------------------------------------------------------- */ + config_lookup_string(&cfg, "model", &str_val); + snprintf(output + RES_MODEL, LEN_MODEL, "%s", str_val); + fprintf(out_txt, "Model: %s\n", str_val); + + /* Example: Set time ---------------------------------------------------------- */ + time_t my_time = time(NULL); + memcpy(output + RES_FLASHTIME, (void *)&my_time, LEN_FLASHTIME); + struct tm *timeinfo = localtime(&my_time); + fwrite(buf, 1, strftime((char *)buf, 64, "Created on %d.%m.%Y um %H:%M:%S", timeinfo), out_txt); + + /* Output result -------------------------------------------------------------- */ + for(i = 4; i < 0x1F000; i++) { + fputc(output[i], out_bin); + } + + /* Generate QR-Code ----------------------------------------------------------- */ + QRcode *code = QRcode_encodeString8bit(qrdata, 3, QR_ECLEVEL_L); + writeImg(out_pbm, code->data, code->width); + + fclose(in_bin); + fclose(out_bin); + fclose(out_txt); + fclose(out_pbm); + + fprintf(stdout, "DONE\n"); + } + + exit(EXIT_SUCCESS); +} +/* ---------------------------------------------------------------------------- */ + +FILE * +openFile(const char *name, const char *appendix, const char *mode) +{ + char filename[64]; + sprintf(filename, "%s%s", name, appendix); + FILE *file = fopen(filename, mode); + if(file == NULL) { + perror("Wasn't able to open file."); + exit(EXIT_FAILURE); + } + return file; +} +void +writeStandardConfig() +{ + unsigned int i; + + config_t cfg; + config_init(&cfg); + config_setting_t *setting; + + config_setting_t *root = config_root_setting(&cfg); + + setting = config_setting_add(root, "input", CONFIG_TYPE_STRING); + config_setting_set_string(setting, "dff_econotag"); + + setting = config_setting_add(root, "output", CONFIG_TYPE_STRING); + config_setting_set_string(setting, "dff_e_econotag"); + + uint8_t eui[8] = { 0x02, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78 }; + config_setting_t *array = config_setting_add(root, "eui", CONFIG_TYPE_ARRAY); + for(i = 0; i < 8; ++i) { + setting = config_setting_add(array, NULL, CONFIG_TYPE_INT); + config_setting_set_format(setting, CONFIG_FORMAT_HEX); + config_setting_set_int(setting, eui[i]); + } + + unsigned char uuid_bin[16]; + uuid_generate(uuid_bin); + char uuid[37]; + uuid_unparse(uuid_bin, uuid); + setting = config_setting_add(root, "uuid", CONFIG_TYPE_STRING); + config_setting_set_string(setting, uuid); + + char psk[17]; + psk[16] = '\0'; + FILE *fd = fopen("/dev/urandom", "r"); + if(fd == NULL) { + perror("Wasn't able to open /dev/urandom: "); + return; + } + for(i = 0; i < 16; i++) { + int c; + while((c = fgetc(fd)) == EOF) ; + psk[i] = anschars[c % 64]; + } + if(fclose(fd) == -1) { + perror("Wasn't able to close /dev/urandom: "); + } + setting = config_setting_add(root, "psk", CONFIG_TYPE_STRING); + config_setting_set_string(setting, psk); + + setting = config_setting_add(root, "name", CONFIG_TYPE_STRING); + config_setting_set_string(setting, "Blaster Standard Device"); + + setting = config_setting_add(root, "model", CONFIG_TYPE_STRING); + config_setting_set_string(setting, "Model 1234 for testing purposes only"); + + config_write_file(&cfg, "config.cfg"); +} +void +writeImg(FILE *file, unsigned char *data, int width) +{ + unsigned int buf[width]; + + fprintf(file, "P4\n# %s\n%3u %3u\n", "QR-Code", width * 32, width * 32); + + int x, y; + for(y = 0; y < width; y++) { + for(x = 0; x < width; x++) { + if(data[(y * width) + x] & 0x01) { + buf[x] = 0xFFFFFFFF; + } else { + buf[x] = 0x00000000; + } + } + for(x = 0; x < 32; x++) { + fwrite(buf, 4, width, file); + } + } +} diff --git a/tools/blaster/blaster.h b/tools/blaster/blaster.h new file mode 100644 index 000000000..085abf855 --- /dev/null +++ b/tools/blaster/blaster.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, Lars Schmertmann . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + * This file is part of the Contiki operating system. + * + */ + +/* Purposes of the different flash blocks */ +/* 0x18000 - 0x18FFF : Random access block 1.1 */ +/* 0x19000 - 0x19FFF : Random access block 1.2 */ +/* 0x1A000 - 0x1AFFF : Random access block 2.1 */ +/* 0x1B000 - 0x1BFFF : Random access block 2.2 */ +/* 0x1C000 - 0x1CFFF : Stack without pop function */ +/* 0x1D000 - 0x1DFFF : Read only <- This is what blaster user */ +/* 0x1E000 - 0x1EFFF : Read only <- This is what blaster user */ +/* 0x1F000 - 0x1FFFF : System reserved */ + +#ifndef BLASTER_H_ +#define BLASTER_H_ + +#define RES_D_CORE 0x1D000 +#define LEN_D_CORE 0x6F + +#define RES_CONFIG 0x1E000 +#define LEN_CONFIG 0x12 +#define RES_UUID 0x1E020 +#define LEN_UUID 0x10 +#define RES_PSK 0x1E030 +#define LEN_PSK 0x10 +#define RES_ANSCHARS 0x1E040 +#define LEN_ANSCHARS 0x40 +#define RES_ECC_BASE_X 0x1E080 +#define LEN_ECC_BASE_X 0x20 +#define RES_ECC_BASE_Y 0x1E0A0 +#define LEN_ECC_BASE_Y 0x20 +#define RES_ECC_ORDER 0x1E0C0 +#define LEN_ECC_ORDER 0x20 +#define RES_NAME 0x1E0E0 +#define LEN_NAME 0x40 +#define RES_MODEL 0x1E120 +#define LEN_MODEL 0x40 +#define RES_FLASHTIME 0x1E160 +#define LEN_FLASHTIME 0x04 + +#endif /* BLASTER_H_ */ diff --git a/tools/cc2538-bsl b/tools/cc2538-bsl index 1223bfe03..c6100a779 160000 --- a/tools/cc2538-bsl +++ b/tools/cc2538-bsl @@ -1 +1 @@ -Subproject commit 1223bfe03cdb31c439f1a51593808cdabc1939d2 +Subproject commit c6100a7794c7b530923145c03e37412013a4551e diff --git a/tools/collect-view/src/org/contikios/contiki/collect/MoteFinder.java b/tools/collect-view/src/org/contikios/contiki/collect/MoteFinder.java index 9afcf028b..2c3c86d5b 100644 --- a/tools/collect-view/src/org/contikios/contiki/collect/MoteFinder.java +++ b/tools/collect-view/src/org/contikios/contiki/collect/MoteFinder.java @@ -54,9 +54,11 @@ public class MoteFinder { public static final String MOTELIST_WINDOWS = "./tools/motelist-windows.exe"; public static final String MOTELIST_LINUX = "./tools/motelist-linux"; + public static final String MOTELIST_MACOS = "./tools/motelist-macos"; private final Pattern motePattern; private final boolean isWindows; + private final boolean isMacos; private Process moteListProcess; // private boolean hasVerifiedProcess; private ArrayList comList = new ArrayList(); @@ -65,7 +67,8 @@ public class MoteFinder { public MoteFinder() { String osName = System.getProperty("os.name", "").toLowerCase(); isWindows = osName.startsWith("win"); - motePattern = Pattern.compile("\\s(COM|/dev/[a-zA-Z]+)(\\d+)\\s"); + isMacos = osName.startsWith("mac"); + motePattern = Pattern.compile("\\s(COM|/dev/[a-zA-Z]+|/dev/tty.usbserial-)(\\d+|[A-Z0-9]+)\\s"); } public String[] getMotes() throws IOException { @@ -87,6 +90,8 @@ public class MoteFinder { String fullCommand; if (isWindows) { fullCommand = MOTELIST_WINDOWS; + } else if (isMacos) { + fullCommand = MOTELIST_MACOS; } else { fullCommand = MOTELIST_LINUX; } diff --git a/tools/collect-view/src/org/contikios/contiki/collect/SerialDumpConnection.java b/tools/collect-view/src/org/contikios/contiki/collect/SerialDumpConnection.java index 9669b89f4..c624ea64a 100644 --- a/tools/collect-view/src/org/contikios/contiki/collect/SerialDumpConnection.java +++ b/tools/collect-view/src/org/contikios/contiki/collect/SerialDumpConnection.java @@ -46,6 +46,7 @@ public class SerialDumpConnection extends CommandConnection { public static final String SERIALDUMP_WINDOWS = "./tools/serialdump-windows.exe"; public static final String SERIALDUMP_LINUX = "./tools/serialdump-linux"; + public static final String SERIALDUMP_MACOS = "./tools/serialdump-macos"; public SerialDumpConnection(SerialConnectionListener listener) { super(listener); @@ -72,6 +73,8 @@ public class SerialDumpConnection extends CommandConnection { String fullCommand; if (osName.startsWith("win")) { fullCommand = SERIALDUMP_WINDOWS + " " + "-b115200" + " " + getMappedComPortForWindows(comPort); + } else if (osName.startsWith("mac")) { + fullCommand = SERIALDUMP_MACOS + " " + "-b115200" + " " + comPort; } else { fullCommand = SERIALDUMP_LINUX + " " + "-b115200" + " " + comPort; } diff --git a/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/AvrMoteMemory.java b/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/AvrMoteMemory.java index 0dbdbb45d..d5a2922c4 100644 --- a/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/AvrMoteMemory.java +++ b/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/AvrMoteMemory.java @@ -1,185 +1,224 @@ -/* - * Copyright (c) 2009, Swedish Institute of Computer Science. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. 2. 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. 3. Neither the name of the - * Institute 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 INSTITUTE 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 INSTITUTE 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. - * - */ - -package org.contikios.cooja.avrmote; - -import java.util.ArrayList; -import java.util.Iterator; - -import org.apache.log4j.Logger; - -import org.contikios.cooja.AddressMemory; -import org.contikios.cooja.MoteMemory; -import avrora.arch.avr.AVRProperties; -import avrora.core.SourceMapping; -import avrora.core.SourceMapping.Location; -import avrora.sim.AtmelInterpreter; -import avrora.sim.Simulator.Watch; -/** - * @author Joakim Eriksson - */ -public class AvrMoteMemory implements MoteMemory, AddressMemory { - private static Logger logger = Logger.getLogger(AvrMoteMemory.class); - - private SourceMapping memoryMap; - private AtmelInterpreter interpreter; - private AVRProperties avrProperties; - - public AvrMoteMemory(SourceMapping map, AVRProperties avrProperties, AtmelInterpreter interpreter) { - memoryMap = map; - this.interpreter = interpreter; - this.avrProperties = avrProperties; - } - - public void insertWatch(Watch w, int address) { - interpreter.getSimulator().insertWatch(w, address); - } - - public void clearMemory() { - logger.fatal("not implemented"); - } - - public byte[] getMemorySegment(int address, int size) { - logger.fatal("getMemorySegment is not implemented"); - return null; - } - - public int getTotalSize() { - return 0; - } - - public void setMemorySegment(int address, byte[] data) { - logger.fatal("setMemorySegment is not implemented"); - } - - public byte[] getByteArray(String varName, int length) - throws UnknownVariableException { - return null; - } - - public byte getByteValueOf(String varName) throws UnknownVariableException { - return (byte) getValueOf(varName, 1); - } - - private int getValueOf(String varName, int len) throws UnknownVariableException { - Location mem = memoryMap.getLocation(varName); - if (mem == null) throw new UnknownVariableException("Variable does not exist: " + varName); - - System.out.println("Variable:" + varName + " in section: " + mem.section); - System.out.println("LMA: " + Integer.toHexString(mem.lma_addr)); - System.out.println("VMA: " + Integer.toHexString(mem.vma_addr)); - - System.out.println("Data: " + interpreter.getDataByte(mem.lma_addr & 0xfffff)); - System.out.println("Flash: " + interpreter.getFlashByte(mem.lma_addr & 0xfffff)); - int data = 0; - if (mem.vma_addr > 0xfffff) { - for (int i = 0; i < len; i++) { - data = (data << 8) + (interpreter.getDataByte((mem.vma_addr & 0xfffff) + len - i - 1) & 0xff); - System.out.println("Read byte: " + interpreter.getDataByte((mem.vma_addr & 0xfffff) + i) + - " => " + data); - } - } else { - for (int i = 0; i < len; i++) { - data = (data << 8) + interpreter.getFlashByte(mem.vma_addr + len - i - 1) & 0xff; - } - } - return data; - } - - private void setValue(String varName, int val, int len) throws UnknownVariableException { - Location mem = memoryMap.getLocation(varName); - if (mem == null) throw new UnknownVariableException("Variable does not exist: " + varName); - - int data = val; - if (mem.vma_addr > 0xfffff) { - // write LSB first. - for (int i = 0; i < len; i++) { - interpreter.writeDataByte((mem.vma_addr & 0xfffff) + i, (byte) (data & 0xff)); - System.out.println("Wrote byte: " + (data & 0xff)); - data = data >> 8; - } - } else { - for (int i = 0; i < len; i++) { - interpreter.writeFlashByte(mem.vma_addr + i, (byte) (data & 0xff)); - data = data >> 8; - } - } - } - - public int getIntValueOf(String varName) throws UnknownVariableException { - return getValueOf(varName, 2); - } - - public int getIntegerLength() { - return 2; - } - - public int getVariableAddress(String varName) - throws UnknownVariableException { - return 0; - } - - public String[] getVariableNames() { - ArrayList symbols = new ArrayList(); - for (Iterator i = memoryMap.getIterator(); i.hasNext();) { - symbols.add(((Location) i.next()).name); - } - return symbols.toArray(new String[0]); - } - - public void setByteArray(String varName, byte[] data) - throws UnknownVariableException { - } - - public void setByteValueOf(String varName, byte newVal) - throws UnknownVariableException { - setValue(varName, newVal, 1); - } - - public void setIntValueOf(String varName, int newVal) - throws UnknownVariableException { - setValue(varName, newVal, 2); - } - - public boolean variableExists(String varName) { - return memoryMap.getLocation(varName) != null; - } - - public boolean addMemoryMonitor(int address, int size, MemoryMonitor mm) { - logger.warn("Not implemented"); - return false; - } - - public void removeMemoryMonitor(int address, int size, MemoryMonitor mm) { - } - - public int parseInt(byte[] memorySegment) { - logger.warn("Not implemented"); - return 0; - } -} +/* + * Copyright (c) 2014, TU Braunschweig. All rights reserved. + * Copyright (c) 2009, Swedish Institute of Computer Science. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. 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. 3. Neither the name of the + * Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +package org.contikios.cooja.avrmote; + + +import org.apache.log4j.Logger; + +import avrora.arch.avr.AVRProperties; +import avrora.core.SourceMapping; +import avrora.core.SourceMapping.Location; +import avrora.sim.AtmelInterpreter; +import avrora.sim.Simulator.Watch; +import avrora.sim.State; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import org.contikios.cooja.mote.memory.MemoryInterface; +import org.contikios.cooja.mote.memory.MemoryInterface.SegmentMonitor.EventType; +import org.contikios.cooja.mote.memory.MemoryLayout; +/** + * @author Joakim Eriksson, Fredrik Osterlind, David Kopf, Enrico Jorns + */ +public class AvrMoteMemory implements MemoryInterface { + private static Logger logger = Logger.getLogger(AvrMoteMemory.class); + private static final boolean DEBUG = logger.isDebugEnabled(); + + private final SourceMapping memoryMap; + private final AVRProperties avrProperties; + private final AtmelInterpreter interpreter; + private final ArrayList memoryMonitors = new ArrayList<>(); + private final MemoryLayout memLayout = new MemoryLayout(ByteOrder.LITTLE_ENDIAN, MemoryLayout.ARCH_8BIT, 2); + + private boolean coojaIsAccessingMemory; + + public AvrMoteMemory(SourceMapping map, AVRProperties avrProperties, AtmelInterpreter interpreter) { + memoryMap = map; + this.interpreter = interpreter; + this.avrProperties = avrProperties; + } + + @Override + public int getTotalSize() { + return avrProperties.sram_size; + } + + @Override + public byte[] getMemory() throws MoteMemoryException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public byte[] getMemorySegment(long address, int size) throws MoteMemoryException { + /*logger.info("getMemorySegment(" + String.format("0x%04x", address) + + ", " + size + ")");*/ + if (!accessInRange(address, size)) { + throw new MoteMemoryException( + "Getting memory segment [0x%x,0x%x] failed: Out of range", + address, address + size - 1); + } + + /* XXX Unsure whether this is the appropriate method to use, as it + * triggers memoryRead monitor. Right now I'm using a flag to indicate + * that Cooja (as opposed to Contiki) read the memory, to avoid infinite + * recursion. */ + coojaIsAccessingMemory = true; + byte[] data = new byte[(int) size]; + for (int i = 0; i < size; i++) { + data[i] = (byte) (interpreter.getDataByte((int) address + i) & 0xff); + } + coojaIsAccessingMemory = false; + return data; + } + + @Override + public void setMemorySegment(long address, byte[] data) throws MoteMemoryException { + if (!accessInRange(address, data.length)) { + throw new MoteMemoryException( + "Writing memory segment [0x%x,0x%x] failed: Out of range", + address, address + data.length - 1); + } + + /* XXX See comment in getMemorySegment. */ + coojaIsAccessingMemory = true; + for (int i = 0; i < data.length; i++) { + interpreter.writeDataByte((int) address + i, data[i]); + } + coojaIsAccessingMemory = false; + if (DEBUG) { + logger.debug(String.format( + "Wrote memory segment [0x%x,0x%x]", + address, address + data.length - 1)); + } + } + + @Override + public void clearMemory() { + setMemorySegment(0L, new byte[avrProperties.sram_size]); + } + + private boolean accessInRange(long address, int size) { + return (address >= 0) && (address + size <= avrProperties.sram_size); + } + + @Override + public long getStartAddr() { + return 0;// XXX + } + + @Override + public Map getSymbolMap() { + // XXX do not fetch in function! + Map symbols = new HashMap<>(); + for (Iterator iter = memoryMap.getIterator(); iter.hasNext();) { + Location loc = iter.next(); + if (loc == null || (loc.section.equals(".text"))) { + continue; + } + symbols.put(loc.name, new Symbol(Symbol.Type.VARIABLE, loc.name, loc.section, loc.vma_addr & 0x7fffff, -1)); + } + return symbols; + } + + + @Override + public MemoryLayout getLayout() { + return memLayout; + } + + class AvrByteMonitor extends Watch.Empty { + + /** start address to monitor */ + final long address; + /** size to monitor */ + final int size; + /** Segment monitor to notify */ + final SegmentMonitor mm; + /** MonitorType we are listening to */ + final EventType flag; + + public AvrByteMonitor(long address, int size, SegmentMonitor mm, EventType flag) { + this.address = address; + this.size = size; + this.mm = mm; + this.flag = flag; + } + + @Override + public void fireAfterRead(State state, int data_addr, byte value) { + if (flag == EventType.WRITE || coojaIsAccessingMemory) { + return; + } + mm.memoryChanged(AvrMoteMemory.this, EventType.READ, data_addr); + } + + @Override + public void fireAfterWrite(State state, int data_addr, byte value) { + if (flag == EventType.READ || coojaIsAccessingMemory) { + return; + } + mm.memoryChanged(AvrMoteMemory.this, EventType.WRITE, data_addr); + } + } + + @Override + public boolean addSegmentMonitor(EventType flag, long address, int size, SegmentMonitor mm) { + AvrByteMonitor mon = new AvrByteMonitor(address, size, mm, flag); + + memoryMonitors.add(mon); + /* logger.debug("Added AvrByteMonitor " + Integer.toString(mon.hashCode()) + " for addr " + mon.address + " size " + mon.size + " with watch" + mon.watch); */ + + /* Add byte monitor (watch) for every byte in range */ + for (int idx = 0; idx < mon.size; idx++) { + interpreter.getSimulator().insertWatch(mon, (int) mon.address + idx); + /* logger.debug("Inserted watch " + Integer.toString(mon.watch.hashCode()) + " for " + (mon.address + idx)); */ + } + return true; + } + + @Override + public boolean removeSegmentMonitor(long address, int size, SegmentMonitor mm) { + for (AvrByteMonitor mcm : memoryMonitors) { + if (mcm.mm != mm || mcm.address != address || mcm.size != size) { + continue; + } + for (int idx = 0; idx < mcm.size; idx++) { + interpreter.getSimulator().removeWatch(mcm, (int) mcm.address + idx); + /* logger.debug("Removed watch " + Integer.toString(mcm.watch.hashCode()) + " for " + (mcm.address + idx)); */ + } + memoryMonitors.remove(mcm); + return true; + } + return false; + } + +} diff --git a/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/MicaZMote.java b/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/MicaZMote.java index 97cca433a..21ed157ce 100644 --- a/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/MicaZMote.java +++ b/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/MicaZMote.java @@ -40,10 +40,11 @@ import org.jdom.Element; import org.contikios.cooja.Mote; import org.contikios.cooja.MoteInterface; import org.contikios.cooja.MoteInterfaceHandler; -import org.contikios.cooja.MoteMemory; import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; +import org.contikios.cooja.mote.memory.MemoryInterface; import org.contikios.cooja.motes.AbstractEmulatedMote; + import avrora.arch.avr.AVRProperties; import avrora.core.LoadableProgram; import avrora.sim.AtmelInterpreter; @@ -54,6 +55,8 @@ import avrora.sim.mcu.EEPROM; import avrora.sim.platform.MicaZ; import avrora.sim.platform.PlatformFactory; +import org.contikios.cooja.avrmote.interfaces.MicaClock; + /** * @author Joakim Eriksson, Fredrik Osterlind */ @@ -74,6 +77,10 @@ public class MicaZMote extends AbstractEmulatedMote implements Mote { private EEPROM eeprom = null; + private long executed = 0; + private long skipped = 0; + + /* Stack monitoring variables */ private boolean stopNextInstruction = false; @@ -184,6 +191,10 @@ public class MicaZMote extends AbstractEmulatedMote implements Mote { private long cyclesExecuted = 0; private long cyclesUntil = 0; public void execute(long t) { + MicaClock clock = ((MicaClock) (myMoteInterfaceHandler.getClock())); + double deviation = clock.getDeviation(); + long drift = clock.getDrift(); + /* Wait until mote boots */ if (myMoteInterfaceHandler.getClock().getTime() < 0) { scheduleNextWakeup(t - myMoteInterfaceHandler.getClock().getTime()); @@ -196,13 +207,22 @@ public class MicaZMote extends AbstractEmulatedMote implements Mote { } /* TODO Poll mote interfaces? */ - + + /* skip if necessary */ + if (((1-deviation) * executed) > skipped) { + skipped += 1; + scheduleNextWakeup(t + Simulation.MILLISECOND); + } + /* Execute one millisecond */ cyclesUntil += NR_CYCLES_PER_MSEC; while (cyclesExecuted < cyclesUntil) { cyclesExecuted += interpreter.step(); } + /* book keeping */ + executed += 1; + /* TODO Poll mote interfaces? */ /* Schedule wakeup every millisecond */ @@ -264,11 +284,12 @@ public class MicaZMote extends AbstractEmulatedMote implements Mote { return config; } - public MoteMemory getMemory() { + @Override + public MemoryInterface getMemory() { return myMemory; } - public void setMemory(MoteMemory memory) { + public void setMemory(AvrMoteMemory memory) { myMemory = (AvrMoteMemory) memory; } diff --git a/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/MicaZMoteType.java b/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/MicaZMoteType.java index c1a33b625..9499aafe9 100644 --- a/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/MicaZMoteType.java +++ b/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/MicaZMoteType.java @@ -63,7 +63,9 @@ import org.contikios.cooja.avrmote.interfaces.MicaZLED; import org.contikios.cooja.avrmote.interfaces.MicaZRadio; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; import org.contikios.cooja.interfaces.Position; @@ -364,7 +366,7 @@ public class MicaZMoteType implements MoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/interfaces/MicaClock.java b/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/interfaces/MicaClock.java index 468e07a73..569e08dfd 100644 --- a/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/interfaces/MicaClock.java +++ b/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/interfaces/MicaClock.java @@ -54,10 +54,12 @@ public class MicaClock extends Clock { private MicaZMote myMote; private long timeDrift; /* Microseconds */ + private double deviation; public MicaClock(Mote mote) { simulation = mote.getSimulation(); myMote = (MicaZMote) mote; + deviation = 1.0; } public void setTime(long newTime) { @@ -68,6 +70,15 @@ public class MicaClock extends Clock { return simulation.getSimulationTime() + timeDrift; } + public double getDeviation() { + return deviation; + } + + public void setDeviation(double deviation) { + assert (deviation>0.0) && (deviation<=1.0); + this.deviation = deviation; + } + public void setDrift(long drift) { timeDrift = drift; } @@ -75,19 +86,4 @@ public class MicaClock extends Clock { public long getDrift() { return timeDrift; } - - public JPanel getInterfaceVisualizer() { - return null; - } - - public void releaseInterfaceVisualizer(JPanel panel) { - } - - public Collection getConfigXML() { - return null; - } - - public void setConfigXML(Collection configXML, boolean visAvailable) { - } - } diff --git a/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/interfaces/MicaZID.java b/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/interfaces/MicaZID.java index a9b9e2190..b52e40730 100644 --- a/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/interfaces/MicaZID.java +++ b/tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/interfaces/MicaZID.java @@ -38,16 +38,15 @@ import javax.swing.JPanel; import org.apache.log4j.Logger; import org.jdom.Element; -import avrora.sim.State; -import avrora.sim.Simulator.Watch; - import org.contikios.cooja.Mote; import org.contikios.cooja.MoteTimeEvent; import org.contikios.cooja.Simulation; import org.contikios.cooja.TimeEvent; -import org.contikios.cooja.avrmote.AvrMoteMemory; import org.contikios.cooja.avrmote.MicaZMote; import org.contikios.cooja.interfaces.MoteID; +import org.contikios.cooja.mote.memory.MemoryInterface; +import org.contikios.cooja.mote.memory.MemoryInterface.SegmentMonitor; +import org.contikios.cooja.mote.memory.VarMemory; public class MicaZID extends MoteID { @@ -57,7 +56,7 @@ public class MicaZID extends MoteID { private int moteID = -1; /* TODO Implement */ - private AvrMoteMemory moteMem; + private VarMemory moteMem; boolean tosID = false; boolean contikiID = false; private MicaZMote mote; @@ -80,23 +79,26 @@ public class MicaZID extends MoteID { public MicaZID(Mote mote) { this.mote = (MicaZMote) mote; - this.moteMem = (AvrMoteMemory) mote.getMemory(); + this.moteMem = new VarMemory(mote.getMemory()); if (moteMem.variableExists("node_id")) { contikiID = true; - int addr = moteMem.getVariableAddress("node_id"); - moteMem.insertWatch(new Watch() { - public void fireAfterRead(State arg0, int arg1, byte arg2) { - System.out.println("Read from node_id: " + arg2); + int addr = (int) moteMem.getVariableAddress("node_id"); + moteMem.addVarMonitor( + SegmentMonitor.EventType.READWRITE, + "node_id", + new SegmentMonitor() { + + @Override + public void memoryChanged(MemoryInterface memory, SegmentMonitor.EventType type, long address) { + if (type == EventType.READ) { + System.out.println("Read from node_id."); + } else { + System.out.println("Writing to node_id."); + } } - public void fireAfterWrite(State arg0, int arg1, byte arg2) { - } - public void fireBeforeRead(State arg0, int arg1) { - } - public void fireBeforeWrite(State arg0, int arg1, byte arg2) { - System.out.println("Writing to node_id: " + arg2); - }}, addr); + }); } if (moteMem.variableExists("TOS_NODE_ID")) { diff --git a/tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java b/tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java index 67d268bc2..1d98efb06 100644 --- a/tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java +++ b/tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java @@ -229,8 +229,8 @@ public class AreaViewer extends VisPlugin { // We want to listen to changes both in the channel model as well as in the radio medium currentChannelModel.addSettingsObserver(channelModelSettingsObserver); - currentRadioMedium.addSettingsObserver(radioMediumSettingsObserver); - currentRadioMedium.addRadioMediumObserver(radioMediumActivityObserver); + currentRadioMedium.addRadioMediumObserver(radioMediumSettingsObserver); + currentRadioMedium.addRadioTransmissionObserver(radioMediumActivityObserver); // Set initial size etc. setSize(500, 500); @@ -2338,13 +2338,13 @@ public class AreaViewer extends VisPlugin { } if (currentRadioMedium != null && radioMediumSettingsObserver != null) { - currentRadioMedium.deleteSettingsObserver(radioMediumSettingsObserver); + currentRadioMedium.deleteRadioMediumObserver(radioMediumSettingsObserver); } else { logger.fatal("Could not remove observer: " + radioMediumSettingsObserver); } if (currentRadioMedium != null && radioMediumActivityObserver != null) { - currentRadioMedium.deleteRadioMediumObserver(radioMediumActivityObserver); + currentRadioMedium.deleteRadioTransmissionObserver(radioMediumActivityObserver); } else { logger.fatal("Could not remove observer: " + radioMediumActivityObserver); } diff --git a/tools/cooja/apps/mrm/java/org/contikios/mrm/ChannelModel.java b/tools/cooja/apps/mrm/java/org/contikios/mrm/ChannelModel.java index 579244f75..9d0427c8a 100644 --- a/tools/cooja/apps/mrm/java/org/contikios/mrm/ChannelModel.java +++ b/tools/cooja/apps/mrm/java/org/contikios/mrm/ChannelModel.java @@ -53,6 +53,8 @@ import org.contikios.cooja.Simulation; import org.contikios.cooja.interfaces.DirectionalAntennaRadio; import org.contikios.cooja.interfaces.Radio; import org.contikios.cooja.radiomediums.AbstractRadioMedium; +import org.contikios.cooja.util.ScnObservable; + import statistics.GaussianWrapper; /** @@ -103,13 +105,7 @@ public class ChannelModel { /** * Notifies observers when this channel model has changed settings. */ - private class SettingsObservable extends Observable { - private void notifySettingsChanged() { - setChanged(); - notifyObservers(); - } - } - private SettingsObservable settingsObservable = new SettingsObservable(); + private ScnObservable settingsObservable = new ScnObservable(); public enum Parameter { apply_random, snr_threshold, @@ -330,7 +326,7 @@ public class ChannelModel { */ public void removeAllObstacles() { myObstacleWorld.removeAll(); - settingsObservable.notifySettingsChanged(); + settingsObservable.setChangedAndNotify(); } /** @@ -360,7 +356,7 @@ public class ChannelModel { myObstacleWorld.addObstacle(startX, startY, width, height); if (notify) { - settingsObservable.notifySettingsChanged(); + settingsObservable.setChangedAndNotify(); } } @@ -442,7 +438,7 @@ public class ChannelModel { needToPrecalculateFSPL = true; needToPrecalculateOutputPower = true; - settingsObservable.notifySettingsChanged(); + settingsObservable.setChangedAndNotify(); } /** @@ -450,9 +446,9 @@ public class ChannelModel { * will be notified. */ public void notifySettingsChanged() { - settingsObservable.notifySettingsChanged(); + settingsObservable.setChangedAndNotify(); } - + /** * Path loss component from Friis' transmission equation. * Uses frequency and distance only. @@ -1884,7 +1880,7 @@ public class ChannelModel { } needToPrecalculateFSPL = true; needToPrecalculateOutputPower = true; - settingsObservable.notifySettingsChanged(); + settingsObservable.setChangedAndNotify(); return true; } diff --git a/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java b/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java index 70e304d02..e8af73370 100644 --- a/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java +++ b/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java @@ -49,6 +49,7 @@ import org.contikios.cooja.interfaces.Position; import org.contikios.cooja.interfaces.Radio; import org.contikios.cooja.plugins.Visualizer; import org.contikios.cooja.radiomediums.AbstractRadioMedium; +import org.contikios.cooja.util.ScnObservable; import org.contikios.mrm.ChannelModel.Parameter; import org.contikios.mrm.ChannelModel.RadioPair; import org.contikios.mrm.ChannelModel.TxPair; @@ -90,11 +91,6 @@ public class MRM extends AbstractRadioMedium { private Random random = null; private ChannelModel currentChannelModel = null; - /** - * Notifies observers when this radio medium has changed settings. - */ - private SettingsObservable settingsObservable = new SettingsObservable(); - /** * Creates a new Multi-path Ray-tracing Medium (MRM). */ @@ -114,6 +110,9 @@ public class MRM extends AbstractRadioMedium { WITH_CAPTURE_EFFECT = currentChannelModel.getParameterBooleanValue(ChannelModel.Parameter.captureEffect); CAPTURE_EFFECT_THRESHOLD = currentChannelModel.getParameterDoubleValue(ChannelModel.Parameter.captureEffectSignalTreshold); CAPTURE_EFFECT_PREAMBLE_DURATION = currentChannelModel.getParameterDoubleValue(ChannelModel.Parameter.captureEffectPreambleDuration); + + /* Radio Medium changed here, so notify */ + radioMediumObservable.setChangedAndNotify(); } }); @@ -142,6 +141,9 @@ public class MRM extends AbstractRadioMedium { public void registerRadioInterface(Radio radio, Simulation sim) { super.registerRadioInterface(radio, sim); + /* Radio Medium changed here so notify Observers */ + radioMediumObservable.setChangedAndNotify(); + if (WITH_NOISE && radio instanceof NoiseSourceRadio) { ((NoiseSourceRadio)radio).addNoiseLevelListener(noiseListener); } @@ -149,6 +151,9 @@ public class MRM extends AbstractRadioMedium { public void unregisterRadioInterface(Radio radio, Simulation sim) { super.unregisterRadioInterface(radio, sim); + /* Radio Medium changed here so notify Observers */ + radioMediumObservable.setChangedAndNotify(); + if (WITH_NOISE && radio instanceof NoiseSourceRadio) { ((NoiseSourceRadio)radio).removeNoiseLevelListener(noiseListener); } @@ -169,6 +174,7 @@ public class MRM extends AbstractRadioMedium { if (sender.getChannel() >= 0 && recv.getChannel() >= 0 && sender.getChannel() != recv.getChannel()) { + newConnection.addInterfered(recv); continue; } final Radio recvFinal = recv; @@ -313,15 +319,15 @@ public class MRM extends AbstractRadioMedium { /* Interfering/colliding radio connections */ for (RadioConnection conn : conns) { for (Radio intfRadio : ((MRMRadioConnection) conn).getInterfered()) { - double signalStrength = ((MRMRadioConnection) conn).getInterferenceSignalStrength(intfRadio); - if (intfRadio.getCurrentSignalStrength() < signalStrength) { - intfRadio.setCurrentSignalStrength(signalStrength); - } if (conn.getSource().getChannel() >= 0 && intfRadio.getChannel() >= 0 && conn.getSource().getChannel() != intfRadio.getChannel()) { continue; } + double signalStrength = ((MRMRadioConnection) conn).getInterferenceSignalStrength(intfRadio); + if (intfRadio.getCurrentSignalStrength() < signalStrength) { + intfRadio.setCurrentSignalStrength(signalStrength); + } if (!intfRadio.isInterfered()) { /*logger.warn("Radio was not interfered: " + intfRadio);*/ @@ -401,25 +407,6 @@ public class MRM extends AbstractRadioMedium { // -- MRM specific methods -- - /** - * Adds an observer which is notified when this radio medium has - * changed settings, such as added or removed radios. - * - * @param obs New observer - */ - public void addSettingsObserver(Observer obs) { - settingsObservable.addObserver(obs); - } - - /** - * Deletes an earlier registered setting observer. - * - * @param obs Earlier registered observer - */ - public void deleteSettingsObserver(Observer obs) { - settingsObservable.deleteObserver(obs); - } - /** * @return Number of registered radios. */ @@ -448,13 +435,6 @@ public class MRM extends AbstractRadioMedium { return currentChannelModel; } - class SettingsObservable extends Observable { - private void notifySettingsChanged() { - setChanged(); - notifyObservers(); - } - } - class MRMRadioConnection extends RadioConnection { private Hashtable signalStrengths = new Hashtable(); diff --git a/tools/cooja/apps/mspsim/README.md b/tools/cooja/apps/mspsim/README.md index 11eb149d3..62c7f44fc 100644 --- a/tools/cooja/apps/mspsim/README.md +++ b/tools/cooja/apps/mspsim/README.md @@ -1,7 +1,7 @@ -MSPSim support for the COOJA Simulator --------------------------------------- - -MSPSim source code access: Standalone MSPSim is available from -[http://sourceforge.net/projects/mspsim](http://sourceforge.net/projects/mspsim). - --- Fredrik sterlind, 18/3 2008 +MSPSim support for the COOJA Simulator +-------------------------------------- + +MSPSim source code access: Standalone MSPSim is available from +[http://sourceforge.net/projects/mspsim](http://sourceforge.net/projects/mspsim). + +-- Fredrik sterlind, 18/3 2008 diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/AbstractMspMoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/AbstractMspMoteType.java index ec7feffd3..d03c0dfa1 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/AbstractMspMoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/AbstractMspMoteType.java @@ -45,7 +45,6 @@ import org.apache.log4j.Logger; import org.contikios.cooja.*; import org.contikios.cooja.dialogs.*; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; /** * @@ -119,7 +118,7 @@ public abstract class AbstractMspMoteType extends MspMoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/CC430MoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/CC430MoteType.java index 8be39971f..3a5144197 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/CC430MoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/CC430MoteType.java @@ -50,8 +50,10 @@ import org.contikios.cooja.MoteInterface; import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -113,7 +115,7 @@ public class CC430MoteType extends MspMoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/ESBMoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/ESBMoteType.java index 41bf80384..13ad2025a 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/ESBMoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/ESBMoteType.java @@ -51,7 +51,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -149,7 +151,7 @@ public class ESBMoteType extends MspMoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Eth1120MoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Eth1120MoteType.java index 84483d047..c51c29384 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Eth1120MoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Eth1120MoteType.java @@ -11,7 +11,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -71,7 +73,7 @@ public class Eth1120MoteType extends Exp5438MoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp1101MoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp1101MoteType.java index b46f1c1f0..b36fb30e9 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp1101MoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp1101MoteType.java @@ -11,7 +11,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -71,7 +73,7 @@ public class Exp1101MoteType extends Exp5438MoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp1120MoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp1120MoteType.java index d745097df..46ad50713 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp1120MoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp1120MoteType.java @@ -11,7 +11,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -72,7 +74,7 @@ public class Exp1120MoteType extends Exp5438MoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp2420MoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp2420MoteType.java index 8e24ef145..8a63bf527 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp2420MoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp2420MoteType.java @@ -11,7 +11,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -72,7 +74,7 @@ public class Exp2420MoteType extends Exp5438MoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438MoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438MoteType.java index f9fc4d813..c5b9b8436 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438MoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438MoteType.java @@ -48,7 +48,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -113,7 +115,7 @@ public class Exp5438MoteType extends MspMoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/MspMote.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/MspMote.java index 3d66c6b08..b22fbc145 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/MspMote.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/MspMote.java @@ -45,12 +45,12 @@ import org.contikios.cooja.Cooja; import org.contikios.cooja.Mote; import org.contikios.cooja.MoteInterface; import org.contikios.cooja.MoteInterfaceHandler; -import org.contikios.cooja.MoteMemory; import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.Watchpoint; import org.contikios.cooja.WatchpointMote; import org.contikios.cooja.interfaces.IPAddress; +import org.contikios.cooja.mote.memory.MemoryInterface; import org.contikios.cooja.motes.AbstractEmulatedMote; import org.contikios.cooja.mspmote.interfaces.Msp802154Radio; import org.contikios.cooja.mspmote.interfaces.MspSerial; @@ -78,6 +78,8 @@ import se.sics.mspsim.util.MapEntry; import se.sics.mspsim.util.MapTable; import se.sics.mspsim.profiler.SimpleProfiler; +import org.contikios.cooja.mspmote.interfaces.MspClock; + /** * @author Fredrik Osterlind */ @@ -185,12 +187,13 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc myCpu = cpu; } - public MoteMemory getMemory() { + @Override + public MemoryInterface getMemory() { return myMemory; } - public void setMemory(MoteMemory memory) { - myMemory = (MspMoteMemory) memory; + public void setMemory(MspMoteMemory memory) { + myMemory = memory; } /** @@ -287,13 +290,22 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc private long lastExecute = -1; /* Last time mote executed */ private long nextExecute; + + private long executed = 0; + private long skipped = 0; + public void execute(long time) { execute(time, EXECUTE_DURATION_US); } + public void execute(long t, int duration) { + MspClock clock = ((MspClock) (myMoteInterfaceHandler.getClock())); + double deviation = clock.getDeviation(); + long drift = clock.getDrift(); + /* Wait until mote boots */ - if (!booted && myMoteInterfaceHandler.getClock().getTime() < 0) { - scheduleNextWakeup(t - myMoteInterfaceHandler.getClock().getTime()); + if (!booted && clock.getTime() < 0) { + scheduleNextWakeup(t - clock.getTime()); return; } booted = true; @@ -312,12 +324,17 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc throw new RuntimeException("Bad event ordering: " + lastExecute + " < " + t); } + if (((1-deviation) * executed) > skipped) { + lastExecute = lastExecute + duration; // (t+duration) - (t-lastExecute); + nextExecute = t+duration; + skipped += duration; + scheduleNextWakeup(nextExecute); + } + /* Execute MSPSim-based mote */ /* TODO Try-catch overhead */ try { - nextExecute = - t + duration + - myCpu.stepMicros(t - lastExecute, duration); + nextExecute = myCpu.stepMicros(Math.max(0, t-lastExecute), duration) + t + duration; lastExecute = t; } catch (EmulationException e) { String trace = e.getMessage() + "\n\n" + getStackTrace(); @@ -329,7 +346,9 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc if (nextExecute < t) { throw new RuntimeException(t + ": MSPSim requested early wakeup: " + nextExecute); } + /*logger.debug(t + ": Schedule next wakeup at " + nextExecute);*/ + executed += duration; scheduleNextWakeup(nextExecute); if (stopNextInstruction) { diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/MspMoteMemory.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/MspMoteMemory.java index 47d18b9ca..6e2e58c36 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/MspMoteMemory.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/MspMoteMemory.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2014, TU Braunschweig. All rights reserved. * Copyright (c) 2007, Swedish Institute of Computer Science. All rights * reserved. * @@ -28,21 +29,27 @@ package org.contikios.cooja.mspmote; +import java.nio.ByteOrder; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import org.apache.log4j.Logger; -import org.contikios.cooja.AddressMemory; import org.contikios.cooja.Mote; -import org.contikios.cooja.MoteMemory; +import org.contikios.cooja.mote.memory.MemoryInterface; +import org.contikios.cooja.mote.memory.MemoryInterface.SegmentMonitor.EventType; +import org.contikios.cooja.mote.memory.MemoryLayout; import se.sics.mspsim.core.MSP430; import se.sics.mspsim.core.Memory.AccessMode; import se.sics.mspsim.core.Memory.AccessType; import se.sics.mspsim.util.MapEntry; -public class MspMoteMemory implements MoteMemory, AddressMemory { +public class MspMoteMemory implements MemoryInterface { private static Logger logger = Logger.getLogger(MspMoteMemory.class); private final ArrayList mapEntries; + private final MemoryLayout memLayout; private final MSP430 cpu; @@ -56,143 +63,85 @@ public class MspMoteMemory implements MoteMemory, AddressMemory { } this.cpu = cpu; + memLayout = new MemoryLayout(ByteOrder.LITTLE_ENDIAN, MemoryLayout.ARCH_16BIT, 2); } - public String[] getVariableNames() { - String[] names = new String[mapEntries.size()]; - for (int i = 0; i < mapEntries.size(); i++) { - names[i] = mapEntries.get(i).getName(); - } - return names; + @Override + public int getTotalSize() { + return cpu.memory.length; } - private MapEntry getMapEntry(String varName) throws UnknownVariableException { - for (MapEntry entry: mapEntries) { - if (entry.getName().equals(varName)) { - return entry; - } - } - throw new UnknownVariableException(varName); + @Override + public byte[] getMemory() throws MoteMemoryException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } - public int getVariableAddress(String varName) throws UnknownVariableException { - MapEntry entry = getMapEntry(varName); - return entry.getAddress(); - } - - public int getIntegerLength() { - return 2; - } - - public void clearMemory() { - logger.fatal("clearMemory() not implemented"); - } - - public byte[] getMemorySegment(int address, int size) { + @Override + public byte[] getMemorySegment(long address, int size) { int[] memInts = new int[size]; - System.arraycopy(cpu.memory, address, memInts, 0, size); + System.arraycopy(cpu.memory, (int) address, memInts, 0, size); /* Convert to byte array */ byte[] memBytes = new byte[size]; - for (int i=0; i < size; i++) { + for (int i = 0; i < size; i++) { memBytes[i] = (byte) memInts[i]; } return memBytes; } - public void setMemorySegment(int address, byte[] data) { + @Override + public void setMemorySegment(long address, byte[] data) { /* Convert to int array */ int[] memInts = new int[data.length]; - for (int i=0; i < data.length; i++) { + for (int i = 0; i < data.length; i++) { memInts[i] = data[i]; } - System.arraycopy(memInts, 0, cpu.memory, address, data.length); + System.arraycopy(memInts, 0, cpu.memory, (int) address, data.length); } - public int getTotalSize() { - return cpu.memory.length; + @Override + public void clearMemory() { + Arrays.fill(cpu.memory, 0); } - public boolean variableExists(String varName) { - for (MapEntry entry: mapEntries) { - if (entry.getName().equals(varName)) { - return true; + @Override + public long getStartAddr() { + return 0;// XXXX + } + + @Override + public Map getSymbolMap() { + Map vars = new HashMap<>(); + for (MapEntry entry : mapEntries) { + if (entry.getType() != MapEntry.TYPE.variable) { + continue; } + vars.put(entry.getName(), new Symbol( + Symbol.Type.VARIABLE, + entry.getName(), + entry.getAddress(), + entry.getSize())); } - - return false; + return vars; } - /* TODO Check correct variable size in below methods */ - - public int getIntValueOf(String varName) throws UnknownVariableException { - MapEntry entry = getMapEntry(varName); - - int varAddr = entry.getAddress(); - byte[] varData = getMemorySegment(varAddr, 2); - return parseInt(varData); + @Override + public MemoryLayout getLayout() { + return memLayout; } - public void setIntValueOf(String varName, int newVal) throws UnknownVariableException { - MapEntry entry = getMapEntry(varName); - int varAddr = entry.getAddress(); + private final ArrayList cpuMonitorArray = new ArrayList<>(); - int newValToSet = Integer.reverseBytes(newVal); - - // Create byte array - int pos = 0; - - byte[] varData = new byte[2]; - varData[pos++] = (byte) ((newValToSet & 0xFF000000) >> 24); - varData[pos++] = (byte) ((newValToSet & 0xFF0000) >> 16); - - setMemorySegment(varAddr, varData); - } - - public byte getByteValueOf(String varName) throws UnknownVariableException { - MapEntry entry = getMapEntry(varName); - int varAddr = entry.getAddress(); - - byte[] varData = getMemorySegment(varAddr, 1); - - return varData[0]; - } - - public void setByteValueOf(String varName, byte newVal) throws UnknownVariableException { - MapEntry entry = getMapEntry(varName); - int varAddr = entry.getAddress(); - - byte[] varData = new byte[1]; - - varData[0] = newVal; - - setMemorySegment(varAddr, varData); - } - - public byte[] getByteArray(String varName, int length) throws UnknownVariableException { - MapEntry entry = getMapEntry(varName); - int varAddr = entry.getAddress(); - - return getMemorySegment(varAddr, length); - } - - public void setByteArray(String varName, byte[] data) throws UnknownVariableException { - MapEntry entry = getMapEntry(varName); - int varAddr = entry.getAddress(); - - setMemorySegment(varAddr, data); - } - - private ArrayList cpuMonitorArray = new ArrayList(); class MemoryCPUMonitor extends se.sics.mspsim.core.MemoryMonitor.Adapter { - public final MemoryMonitor mm; + + public final SegmentMonitor mm; public final int address; public final int size; - public MemoryCPUMonitor(MemoryMonitor mm, int address, int size) { + public MemoryCPUMonitor(SegmentMonitor mm, int address, int size) { this.mm = mm; this.address = address; this.size = size; @@ -200,49 +149,39 @@ public class MspMoteMemory implements MoteMemory, AddressMemory { @Override public void notifyReadAfter(int address, AccessMode mode, AccessType type) { - mm.memoryChanged(MspMoteMemory.this, MemoryEventType.READ, address); + mm.memoryChanged(MspMoteMemory.this, EventType.READ, address); } @Override public void notifyWriteAfter(int dstAddress, int data, AccessMode mode) { - mm.memoryChanged(MspMoteMemory.this, MemoryEventType.WRITE, dstAddress); + mm.memoryChanged(MspMoteMemory.this, EventType.WRITE, dstAddress); } } - public boolean addMemoryMonitor(int address, int size, MemoryMonitor mm) { - MemoryCPUMonitor t = new MemoryCPUMonitor(mm, address, size); + @Override + public boolean addSegmentMonitor(EventType type, long address, int size, SegmentMonitor mm) { + MemoryCPUMonitor t = new MemoryCPUMonitor(mm, (int) address, size); cpuMonitorArray.add(t); - for (int a = address; a < address+size; a++) { + for (int a = (int) address; a < address + size; a++) { cpu.addWatchPoint(a, t); } return true; } - public void removeMemoryMonitor(int address, int size, MemoryMonitor mm) { - for (MemoryCPUMonitor mcm: cpuMonitorArray) { + @Override + public boolean removeSegmentMonitor(long address, int size, SegmentMonitor mm) { + for (MemoryCPUMonitor mcm : cpuMonitorArray) { if (mcm.mm != mm || mcm.address != address || mcm.size != size) { continue; } - for (int a = address; a < address+size; a++) { + for (int a = (int) address; a < (int) address + size; a++) { cpu.removeWatchPoint(a, mcm); } cpuMonitorArray.remove(mcm); - break; + return true; } - } - - public int parseInt(byte[] memorySegment) { - if (memorySegment.length < 2) { - return -1; - } - - int retVal = 0; - int pos = 0; - retVal += ((memorySegment[pos++] & 0xFF)) << 8; - retVal += ((memorySegment[pos++] & 0xFF)) << 0; - - return Integer.reverseBytes(retVal) >> 16; + return false; } } diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/SkyMoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/SkyMoteType.java index 793418969..3ab5854b3 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/SkyMoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/SkyMoteType.java @@ -51,7 +51,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -135,7 +137,7 @@ public class SkyMoteType extends MspMoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Trxeb1120MoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Trxeb1120MoteType.java index e69daf55f..eac27e122 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Trxeb1120MoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Trxeb1120MoteType.java @@ -11,7 +11,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -71,7 +73,7 @@ public class Trxeb1120MoteType extends Exp5438MoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Trxeb2520MoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Trxeb2520MoteType.java index bd3190770..939e60fcd 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Trxeb2520MoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Trxeb2520MoteType.java @@ -11,7 +11,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -71,7 +73,7 @@ public class Trxeb2520MoteType extends Exp5438MoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/TyndallMoteType.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/TyndallMoteType.java index 4298a67aa..4e6472b11 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/TyndallMoteType.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/TyndallMoteType.java @@ -49,7 +49,9 @@ import org.contikios.cooja.MoteType; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListText; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Mote2MoteRelations; import org.contikios.cooja.interfaces.MoteAttributes; @@ -112,7 +114,7 @@ public class TyndallMoteType extends MspMoteType { throw new MoteTypeCreationException("No identifier"); } - final MessageList compilationOutput = new MessageList(); + final MessageList compilationOutput = visAvailable ? new MessageListUI() : new MessageListText(); if (getCompileCommands() != null) { /* Handle multiple compilation commands one by one */ diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC1101Radio.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC1101Radio.java index cedf0435c..5b9367d7a 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC1101Radio.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC1101Radio.java @@ -1,422 +1,422 @@ -/* - * Copyright (c) 2012, Thingsquare. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - */ - -package org.contikios.cooja.mspmote.interfaces; - -import java.util.Collection; - -import org.apache.log4j.Logger; -import org.jdom.Element; - -import org.contikios.cooja.ClassDescription; -import org.contikios.cooja.Mote; -import org.contikios.cooja.RadioPacket; -import org.contikios.cooja.Simulation; -import org.contikios.cooja.interfaces.CustomDataRadio; -import org.contikios.cooja.interfaces.Position; -import org.contikios.cooja.interfaces.Radio; -import org.contikios.cooja.mspmote.MspMote; -import org.contikios.cooja.mspmote.MspMoteTimeEvent; -import se.sics.mspsim.chip.CC1101; -import se.sics.mspsim.chip.CC1101.ReceiverListener; -import se.sics.mspsim.chip.ChannelListener; -import se.sics.mspsim.chip.RFListener; -import se.sics.mspsim.chip.Radio802154; - -/** - * @author Fredrik Osterlind - */ -@ClassDescription("TI CC1101") -public class CC1101Radio extends Radio implements CustomDataRadio { - private static Logger logger = Logger.getLogger(CC1101Radio.class); - - /** - * Cross-level: - * Inter-byte delay for delivering cross-level packet bytes. - */ - public static final long DELAY_BETWEEN_BYTES = - (long) (1000.0*Simulation.MILLISECOND/(250000.0/8.0)); /* us. Corresponds to 250kbit/s */ - - private RadioEvent lastEvent = RadioEvent.UNKNOWN; - - private final MspMote mote; - private final CC1101 cc1101; - - private boolean isInterfered = false; - private boolean isTransmitting = false; - private boolean isReceiving = false; - - private byte lastOutgoingByte; - private byte lastIncomingByte; - - private RadioPacket lastOutgoingPacket = null; - private RadioPacket lastIncomingPacket = null; - - public CC1101Radio(Mote m) { - this.mote = (MspMote)m; - Radio802154 r = this.mote.getCPU().getChip(Radio802154.class); - if (r == null || !(r instanceof CC1101)) { - throw new IllegalStateException("Mote is not equipped with an CC1101 radio"); - } - this.cc1101 = (CC1101) r; - - cc1101.addRFListener(new RFListener() { - int len = 0; - int expLen = 0; - byte[] buffer = new byte[256 + 15]; - private boolean gotSynchbyte = false; - public void receivedByte(byte data) { - if (!isTransmitting()) { - /* Start transmission */ - lastEvent = RadioEvent.TRANSMISSION_STARTED; - isTransmitting = true; - len = 0; - gotSynchbyte = false; - /*logger.debug("----- CC1101 TRANSMISSION STARTED -----");*/ - setChanged(); - notifyObservers(); - } - if (len >= buffer.length) { - /* Bad size packet, too large */ - logger.debug("Error: bad size: " + len + ", dropping outgoing byte: " + data); - return; - } - - /* send this byte to all nodes */ - lastOutgoingByte = data; - lastEvent = RadioEvent.CUSTOM_DATA_TRANSMITTED; - setChanged(); - notifyObservers(); - - /* Await synch byte */ - if (!gotSynchbyte) { - if (lastOutgoingByte == CC1101.SYNCH_BYTE_LAST) { - gotSynchbyte = true; - } - return; - } - - final int HEADERLEN = 1; /* 1x Length byte */ - final int FOOTERLEN = 2; /* TODO Fix CRC in Mspsim's CC1101.java */ - if (len == 0) { - expLen = (0xff&data) + HEADERLEN + FOOTERLEN; - } - buffer[len++] = data; - - if (len == expLen) { - /*logger.debug("----- CC1101 CUSTOM DATA TRANSMITTED -----");*/ - - final byte[] buf = new byte[expLen]; - System.arraycopy(buffer, 0, buf, 0, expLen); - lastOutgoingPacket = new RadioPacket() { - public byte[] getPacketData() { - return buf; - } - }; - - lastEvent = RadioEvent.PACKET_TRANSMITTED; - /*logger.debug("----- CC1101 PACKET TRANSMITTED -----");*/ - setChanged(); - notifyObservers(); - - /*logger.debug("----- CC1101 TRANSMISSION FINISHED -----");*/ - isTransmitting = false; - lastEvent = RadioEvent.TRANSMISSION_FINISHED; - setChanged(); - notifyObservers(); - len = 0; - } - } - }); - - cc1101.setReceiverListener(new ReceiverListener() { - public void newState(boolean on) { - if (cc1101.isReadyToReceive()) { - lastEvent = RadioEvent.HW_ON; - setChanged(); - notifyObservers(); - } else { - radioOff(); - } - } - }); - - cc1101.addChannelListener(new ChannelListener() { - public void channelChanged(int channel) { - /* XXX Currently assumes zero channel switch time */ - lastEvent = RadioEvent.UNKNOWN; - setChanged(); - notifyObservers(); - } - }); - } - - private void radioOff() { - /* Radio was turned off during transmission. - * May for example happen if watchdog triggers */ - if (isTransmitting()) { - logger.warn("Turning off radio while transmitting, ending packet prematurely"); - - /* Simulate end of packet */ - lastOutgoingPacket = new RadioPacket() { - public byte[] getPacketData() { - return new byte[0]; - } - }; - - lastEvent = RadioEvent.PACKET_TRANSMITTED; - /*logger.debug("----- CC1101 PACKET TRANSMITTED -----");*/ - setChanged(); - notifyObservers(); - - /* Register that transmission ended in radio medium */ - /*logger.debug("----- CC1101 TRANSMISSION FINISHED -----");*/ - isTransmitting = false; - lastEvent = RadioEvent.TRANSMISSION_FINISHED; - setChanged(); - notifyObservers(); - } - - lastEvent = RadioEvent.HW_OFF; - setChanged(); - notifyObservers(); - } - - /* Packet radio support */ - public RadioPacket getLastPacketTransmitted() { - return lastOutgoingPacket; - } - - public RadioPacket getLastPacketReceived() { - return lastIncomingPacket; - } - - public void setReceivedPacket(RadioPacket packet) { - lastIncomingPacket = packet; - - /* TODO XXX Need support in CC1101.java */ - /*if (!radio.isReadyToReceive()) { - logger.warn("Radio receiver not ready, dropping packet data"); - return; - }*/ - - /* Delivering packet bytes with delays */ - byte[] packetData = packet.getPacketData(); - long deliveryTime = getMote().getSimulation().getSimulationTime(); - for (byte b: packetData) { - if (isInterfered()) { - b = (byte) 0xFF; - } - - final byte byteToDeliver = b; - getMote().getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { - public void execute(long t) { - super.execute(t); - cc1101.receivedByte(byteToDeliver); - mote.requestImmediateWakeup(); - } - }, deliveryTime); - deliveryTime += DELAY_BETWEEN_BYTES; - } - } - - /* Custom data radio support */ - public Object getLastCustomDataTransmitted() { - return lastOutgoingByte; - } - - public Object getLastCustomDataReceived() { - return lastIncomingByte; - } - - public void receiveCustomData(Object data) { - if (!(data instanceof Byte)) { - logger.fatal("Bad custom data: " + data); - return; - } - lastIncomingByte = (Byte) data; - - final byte inputByte; - if (isInterfered()) { - inputByte = (byte)0xFF; - } else { - inputByte = lastIncomingByte; - } - mote.getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { - public void execute(long t) { - super.execute(t); - cc1101.receivedByte(inputByte); - mote.requestImmediateWakeup(); - } - }, mote.getSimulation().getSimulationTime()); - - } - - /* General radio support */ - public boolean isTransmitting() { - return isTransmitting; - } - - public boolean isReceiving() { - return isReceiving; - } - - public boolean isInterfered() { - return isInterfered; - } - - public int getChannel() { - return cc1101.getActiveChannel(); - } - - public int getFrequency() { - return cc1101.getActiveFrequency(); - } - - public void signalReceptionStart() { - isReceiving = true; - - lastEvent = RadioEvent.RECEPTION_STARTED; - /*logger.debug("----- CC1101 RECEPTION STARTED -----");*/ - setChanged(); - notifyObservers(); - } - - public void signalReceptionEnd() { - /* Deliver packet data */ - isReceiving = false; - isInterfered = false; - - lastEvent = RadioEvent.RECEPTION_FINISHED; - /*logger.debug("----- CC1101 RECEPTION FINISHED -----");*/ - setChanged(); - notifyObservers(); - } - - public RadioEvent getLastEvent() { - return lastEvent; - } - - public void interfereAnyReception() { - isInterfered = true; - isReceiving = false; - lastIncomingPacket = null; - - lastEvent = RadioEvent.RECEPTION_INTERFERED; - /*logger.debug("----- CC1101 RECEPTION INTERFERED -----");*/ - setChanged(); - notifyObservers(); - } - - public double getCurrentOutputPower() { - /* TODO XXX Need support in CC1101.java */ - return 1; - } - public int getCurrentOutputPowerIndicator() { - /* TODO XXX Need support in CC1101.java */ - return 10; - } - public int getOutputPowerIndicatorMax() { - /* TODO XXX Need support in CC1101.java */ - return 10; - } - - - /** - * Last 8 received signal strengths - */ - double currentSignalStrength = 0; - private double[] rssiLast = new double[8]; - private int rssiLastCounter = 0; - - public double getCurrentSignalStrength() { - return currentSignalStrength; - } - - public void setCurrentSignalStrength(final double signalStrength) { - if (signalStrength == currentSignalStrength) { - return; /* ignored */ - } - currentSignalStrength = signalStrength; - if (rssiLastCounter == 0) { - getMote().getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { - public void execute(long t) { - super.execute(t); - - /* Update average */ - System.arraycopy(rssiLast, 1, rssiLast, 0, 7); - rssiLast[7] = currentSignalStrength; - double avg = 0; - for (double v: rssiLast) { - avg += v; - } - avg /= rssiLast.length; - - cc1101.setRSSI((int) avg); - - rssiLastCounter--; - if (rssiLastCounter > 0) { - mote.getSimulation().scheduleEvent(this, t+DELAY_BETWEEN_BYTES/2); - } - } - }, mote.getSimulation().getSimulationTime()); - } - rssiLastCounter = 8; - } - - public Mote getMote() { - return mote; - } - - public Position getPosition() { - return mote.getInterfaces().getPosition(); - } - - public Collection getConfigXML() { - return null; - } - - public void setConfigXML(Collection configXML, boolean visAvailable) { - } - - public boolean isRadioOn() { - return cc1101.isReadyToReceive(); - } - - public boolean canReceiveFrom(CustomDataRadio radio) { - if (radio.getClass().equals(this.getClass())) { - return true; - } - if (radio.getClass().equals(CC430Radio.class)) { - return true; - } - return false; - } -} +/* + * Copyright (c) 2012, Thingsquare. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +package org.contikios.cooja.mspmote.interfaces; + +import java.util.Collection; + +import org.apache.log4j.Logger; +import org.jdom.Element; + +import org.contikios.cooja.ClassDescription; +import org.contikios.cooja.Mote; +import org.contikios.cooja.RadioPacket; +import org.contikios.cooja.Simulation; +import org.contikios.cooja.interfaces.CustomDataRadio; +import org.contikios.cooja.interfaces.Position; +import org.contikios.cooja.interfaces.Radio; +import org.contikios.cooja.mspmote.MspMote; +import org.contikios.cooja.mspmote.MspMoteTimeEvent; +import se.sics.mspsim.chip.CC1101; +import se.sics.mspsim.chip.CC1101.ReceiverListener; +import se.sics.mspsim.chip.ChannelListener; +import se.sics.mspsim.chip.RFListener; +import se.sics.mspsim.chip.Radio802154; + +/** + * @author Fredrik Osterlind + */ +@ClassDescription("TI CC1101") +public class CC1101Radio extends Radio implements CustomDataRadio { + private static Logger logger = Logger.getLogger(CC1101Radio.class); + + /** + * Cross-level: + * Inter-byte delay for delivering cross-level packet bytes. + */ + public static final long DELAY_BETWEEN_BYTES = + (long) (1000.0*Simulation.MILLISECOND/(250000.0/8.0)); /* us. Corresponds to 250kbit/s */ + + private RadioEvent lastEvent = RadioEvent.UNKNOWN; + + private final MspMote mote; + private final CC1101 cc1101; + + private boolean isInterfered = false; + private boolean isTransmitting = false; + private boolean isReceiving = false; + + private byte lastOutgoingByte; + private byte lastIncomingByte; + + private RadioPacket lastOutgoingPacket = null; + private RadioPacket lastIncomingPacket = null; + + public CC1101Radio(Mote m) { + this.mote = (MspMote)m; + Radio802154 r = this.mote.getCPU().getChip(Radio802154.class); + if (r == null || !(r instanceof CC1101)) { + throw new IllegalStateException("Mote is not equipped with an CC1101 radio"); + } + this.cc1101 = (CC1101) r; + + cc1101.addRFListener(new RFListener() { + int len = 0; + int expLen = 0; + byte[] buffer = new byte[256 + 15]; + private boolean gotSynchbyte = false; + public void receivedByte(byte data) { + if (!isTransmitting()) { + /* Start transmission */ + lastEvent = RadioEvent.TRANSMISSION_STARTED; + isTransmitting = true; + len = 0; + gotSynchbyte = false; + /*logger.debug("----- CC1101 TRANSMISSION STARTED -----");*/ + setChanged(); + notifyObservers(); + } + if (len >= buffer.length) { + /* Bad size packet, too large */ + logger.debug("Error: bad size: " + len + ", dropping outgoing byte: " + data); + return; + } + + /* send this byte to all nodes */ + lastOutgoingByte = data; + lastEvent = RadioEvent.CUSTOM_DATA_TRANSMITTED; + setChanged(); + notifyObservers(); + + /* Await synch byte */ + if (!gotSynchbyte) { + if (lastOutgoingByte == CC1101.SYNCH_BYTE_LAST) { + gotSynchbyte = true; + } + return; + } + + final int HEADERLEN = 1; /* 1x Length byte */ + final int FOOTERLEN = 2; /* TODO Fix CRC in Mspsim's CC1101.java */ + if (len == 0) { + expLen = (0xff&data) + HEADERLEN + FOOTERLEN; + } + buffer[len++] = data; + + if (len == expLen) { + /*logger.debug("----- CC1101 CUSTOM DATA TRANSMITTED -----");*/ + + final byte[] buf = new byte[expLen]; + System.arraycopy(buffer, 0, buf, 0, expLen); + lastOutgoingPacket = new RadioPacket() { + public byte[] getPacketData() { + return buf; + } + }; + + lastEvent = RadioEvent.PACKET_TRANSMITTED; + /*logger.debug("----- CC1101 PACKET TRANSMITTED -----");*/ + setChanged(); + notifyObservers(); + + /*logger.debug("----- CC1101 TRANSMISSION FINISHED -----");*/ + isTransmitting = false; + lastEvent = RadioEvent.TRANSMISSION_FINISHED; + setChanged(); + notifyObservers(); + len = 0; + } + } + }); + + cc1101.setReceiverListener(new ReceiverListener() { + public void newState(boolean on) { + if (cc1101.isReadyToReceive()) { + lastEvent = RadioEvent.HW_ON; + setChanged(); + notifyObservers(); + } else { + radioOff(); + } + } + }); + + cc1101.addChannelListener(new ChannelListener() { + public void channelChanged(int channel) { + /* XXX Currently assumes zero channel switch time */ + lastEvent = RadioEvent.UNKNOWN; + setChanged(); + notifyObservers(); + } + }); + } + + private void radioOff() { + /* Radio was turned off during transmission. + * May for example happen if watchdog triggers */ + if (isTransmitting()) { + logger.warn("Turning off radio while transmitting, ending packet prematurely"); + + /* Simulate end of packet */ + lastOutgoingPacket = new RadioPacket() { + public byte[] getPacketData() { + return new byte[0]; + } + }; + + lastEvent = RadioEvent.PACKET_TRANSMITTED; + /*logger.debug("----- CC1101 PACKET TRANSMITTED -----");*/ + setChanged(); + notifyObservers(); + + /* Register that transmission ended in radio medium */ + /*logger.debug("----- CC1101 TRANSMISSION FINISHED -----");*/ + isTransmitting = false; + lastEvent = RadioEvent.TRANSMISSION_FINISHED; + setChanged(); + notifyObservers(); + } + + lastEvent = RadioEvent.HW_OFF; + setChanged(); + notifyObservers(); + } + + /* Packet radio support */ + public RadioPacket getLastPacketTransmitted() { + return lastOutgoingPacket; + } + + public RadioPacket getLastPacketReceived() { + return lastIncomingPacket; + } + + public void setReceivedPacket(RadioPacket packet) { + lastIncomingPacket = packet; + + /* TODO XXX Need support in CC1101.java */ + /*if (!radio.isReadyToReceive()) { + logger.warn("Radio receiver not ready, dropping packet data"); + return; + }*/ + + /* Delivering packet bytes with delays */ + byte[] packetData = packet.getPacketData(); + long deliveryTime = getMote().getSimulation().getSimulationTime(); + for (byte b: packetData) { + if (isInterfered()) { + b = (byte) 0xFF; + } + + final byte byteToDeliver = b; + getMote().getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { + public void execute(long t) { + super.execute(t); + cc1101.receivedByte(byteToDeliver); + mote.requestImmediateWakeup(); + } + }, deliveryTime); + deliveryTime += DELAY_BETWEEN_BYTES; + } + } + + /* Custom data radio support */ + public Object getLastCustomDataTransmitted() { + return lastOutgoingByte; + } + + public Object getLastCustomDataReceived() { + return lastIncomingByte; + } + + public void receiveCustomData(Object data) { + if (!(data instanceof Byte)) { + logger.fatal("Bad custom data: " + data); + return; + } + lastIncomingByte = (Byte) data; + + final byte inputByte; + if (isInterfered()) { + inputByte = (byte)0xFF; + } else { + inputByte = lastIncomingByte; + } + mote.getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { + public void execute(long t) { + super.execute(t); + cc1101.receivedByte(inputByte); + mote.requestImmediateWakeup(); + } + }, mote.getSimulation().getSimulationTime()); + + } + + /* General radio support */ + public boolean isTransmitting() { + return isTransmitting; + } + + public boolean isReceiving() { + return isReceiving; + } + + public boolean isInterfered() { + return isInterfered; + } + + public int getChannel() { + return cc1101.getActiveChannel(); + } + + public int getFrequency() { + return cc1101.getActiveFrequency(); + } + + public void signalReceptionStart() { + isReceiving = true; + + lastEvent = RadioEvent.RECEPTION_STARTED; + /*logger.debug("----- CC1101 RECEPTION STARTED -----");*/ + setChanged(); + notifyObservers(); + } + + public void signalReceptionEnd() { + /* Deliver packet data */ + isReceiving = false; + isInterfered = false; + + lastEvent = RadioEvent.RECEPTION_FINISHED; + /*logger.debug("----- CC1101 RECEPTION FINISHED -----");*/ + setChanged(); + notifyObservers(); + } + + public RadioEvent getLastEvent() { + return lastEvent; + } + + public void interfereAnyReception() { + isInterfered = true; + isReceiving = false; + lastIncomingPacket = null; + + lastEvent = RadioEvent.RECEPTION_INTERFERED; + /*logger.debug("----- CC1101 RECEPTION INTERFERED -----");*/ + setChanged(); + notifyObservers(); + } + + public double getCurrentOutputPower() { + /* TODO XXX Need support in CC1101.java */ + return 1; + } + public int getCurrentOutputPowerIndicator() { + /* TODO XXX Need support in CC1101.java */ + return 10; + } + public int getOutputPowerIndicatorMax() { + /* TODO XXX Need support in CC1101.java */ + return 10; + } + + + /** + * Last 8 received signal strengths + */ + double currentSignalStrength = 0; + private double[] rssiLast = new double[8]; + private int rssiLastCounter = 0; + + public double getCurrentSignalStrength() { + return currentSignalStrength; + } + + public void setCurrentSignalStrength(final double signalStrength) { + if (signalStrength == currentSignalStrength) { + return; /* ignored */ + } + currentSignalStrength = signalStrength; + if (rssiLastCounter == 0) { + getMote().getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { + public void execute(long t) { + super.execute(t); + + /* Update average */ + System.arraycopy(rssiLast, 1, rssiLast, 0, 7); + rssiLast[7] = currentSignalStrength; + double avg = 0; + for (double v: rssiLast) { + avg += v; + } + avg /= rssiLast.length; + + cc1101.setRSSI((int) avg); + + rssiLastCounter--; + if (rssiLastCounter > 0) { + mote.getSimulation().scheduleEvent(this, t+DELAY_BETWEEN_BYTES/2); + } + } + }, mote.getSimulation().getSimulationTime()); + } + rssiLastCounter = 8; + } + + public Mote getMote() { + return mote; + } + + public Position getPosition() { + return mote.getInterfaces().getPosition(); + } + + public Collection getConfigXML() { + return null; + } + + public void setConfigXML(Collection configXML, boolean visAvailable) { + } + + public boolean isRadioOn() { + return cc1101.isReadyToReceive(); + } + + public boolean canReceiveFrom(CustomDataRadio radio) { + if (radio.getClass().equals(this.getClass())) { + return true; + } + if (radio.getClass().equals(CC430Radio.class)) { + return true; + } + return false; + } +} diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC1120Radio.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC1120Radio.java index 9d2a5e333..8e4cfc51e 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC1120Radio.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC1120Radio.java @@ -1,421 +1,421 @@ -/* - * Copyright (c) 2012, Thingsquare. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - */ - -package org.contikios.cooja.mspmote.interfaces; - -import java.util.Collection; - -import org.apache.log4j.Logger; -import org.jdom.Element; - -import org.contikios.cooja.ClassDescription; -import org.contikios.cooja.Mote; -import org.contikios.cooja.RadioPacket; -import org.contikios.cooja.Simulation; -import org.contikios.cooja.interfaces.CustomDataRadio; -import org.contikios.cooja.interfaces.Position; -import org.contikios.cooja.interfaces.Radio; -import org.contikios.cooja.mspmote.MspMote; -import org.contikios.cooja.mspmote.MspMoteTimeEvent; -import se.sics.mspsim.chip.CC1120; -import se.sics.mspsim.chip.CC1120.ReceiverListener; -import se.sics.mspsim.chip.ChannelListener; -import se.sics.mspsim.chip.RFListener; -import se.sics.mspsim.chip.Radio802154; - -/** - * @author Fredrik Osterlind - */ -@ClassDescription("TI CC1120") -public class CC1120Radio extends Radio implements CustomDataRadio { - private static Logger logger = Logger.getLogger(CC1120Radio.class); - - /** - * Cross-level: - * Inter-byte delay for delivering cross-level packet bytes. - */ - /* TODO XXX Fix me as well as symbol duration in CC1120.java */ - public static final long DELAY_BETWEEN_BYTES = - (long) (1000.0*Simulation.MILLISECOND/(200000.0/8.0)); /* us. Corresponds to 200kbit/s */ - - private RadioEvent lastEvent = RadioEvent.UNKNOWN; - - private final MspMote mote; - private final CC1120 cc1120; - - private boolean isInterfered = false; - private boolean isTransmitting = false; - private boolean isReceiving = false; - - private byte lastOutgoingByte; - private byte lastIncomingByte; - - private RadioPacket lastOutgoingPacket = null; - private RadioPacket lastIncomingPacket = null; - - public CC1120Radio(Mote m) { - this.mote = (MspMote)m; - Radio802154 r = this.mote.getCPU().getChip(Radio802154.class); - if (r == null || !(r instanceof CC1120)) { - throw new IllegalStateException("Mote is not equipped with an CC1120 radio"); - } - this.cc1120 = (CC1120) r; - - cc1120.addRFListener(new RFListener() { - int len = 0; - int expLen = 0; - byte[] buffer = new byte[256 + 15]; - private boolean gotSynchbyte = false; - public void receivedByte(byte data) { - if (!isTransmitting()) { - /* Start transmission */ - lastEvent = RadioEvent.TRANSMISSION_STARTED; - isTransmitting = true; - len = 0; - gotSynchbyte = false; - /*logger.debug("----- CCC1120 TRANSMISSION STARTED -----");*/ - setChanged(); - notifyObservers(); - } - if (len >= buffer.length) { - /* Bad size packet, too large */ - logger.debug("Error: bad size: " + len + ", dropping outgoing byte: " + data); - return; - } - - /* send this byte to all nodes */ - lastOutgoingByte = data; - lastEvent = RadioEvent.CUSTOM_DATA_TRANSMITTED; - setChanged(); - notifyObservers(); - - /* Await synch byte */ - if (!gotSynchbyte) { - if (lastOutgoingByte == CC1120.SYNCH_BYTE_LAST) { - gotSynchbyte = true; - } - return; - } - - final int HEADERLEN = 1; /* 1x Length byte */ - final int FOOTERLEN = 2; /* TODO Fix CRC in Mspsim's CCC1120.java */ - if (len == 0) { - expLen = (0xff&data) + HEADERLEN + FOOTERLEN; - } - buffer[len++] = data; - - if (len == expLen) { - /*logger.debug("----- CCC1120 CUSTOM DATA TRANSMITTED -----");*/ - - final byte[] buf = new byte[expLen]; - System.arraycopy(buffer, 0, buf, 0, expLen); - lastOutgoingPacket = new RadioPacket() { - public byte[] getPacketData() { - return buf; - } - }; - - lastEvent = RadioEvent.PACKET_TRANSMITTED; - /*logger.debug("----- CCC1120 PACKET TRANSMITTED -----");*/ - setChanged(); - notifyObservers(); - - /*logger.debug("----- CCC1120 TRANSMISSION FINISHED -----");*/ - isTransmitting = false; - lastEvent = RadioEvent.TRANSMISSION_FINISHED; - setChanged(); - notifyObservers(); - len = 0; - } - } - }); - - cc1120.setReceiverListener(new ReceiverListener() { - public void newState(boolean on) { - if (cc1120.isReadyToReceive()) { - lastEvent = RadioEvent.HW_ON; - setChanged(); - notifyObservers(); - } else { - radioOff(); - } - } - }); - - cc1120.addChannelListener(new ChannelListener() { - public void channelChanged(int channel) { - /* XXX Currently assumes zero channel switch time */ - lastEvent = RadioEvent.UNKNOWN; - setChanged(); - notifyObservers(); - } - }); - } - - private void radioOff() { - /* Radio was turned off during transmission. - * May for example happen if watchdog triggers */ - if (isTransmitting()) { - logger.warn("Turning off radio while transmitting, ending packet prematurely"); - - /* Simulate end of packet */ - lastOutgoingPacket = new RadioPacket() { - public byte[] getPacketData() { - return new byte[0]; - } - }; - - lastEvent = RadioEvent.PACKET_TRANSMITTED; - /*logger.debug("----- CCC1120 PACKET TRANSMITTED -----");*/ - setChanged(); - notifyObservers(); - - /* Register that transmission ended in radio medium */ - /*logger.debug("----- CCC1120 TRANSMISSION FINISHED -----");*/ - isTransmitting = false; - lastEvent = RadioEvent.TRANSMISSION_FINISHED; - setChanged(); - notifyObservers(); - } - - lastEvent = RadioEvent.HW_OFF; - setChanged(); - notifyObservers(); - } - - /* Packet radio support */ - public RadioPacket getLastPacketTransmitted() { - return lastOutgoingPacket; - } - - public RadioPacket getLastPacketReceived() { - return lastIncomingPacket; - } - - public void setReceivedPacket(RadioPacket packet) { - lastIncomingPacket = packet; - - /* TODO XXX Need support in CCC1120.java */ - /*if (!radio.isReadyToReceive()) { - logger.warn("Radio receiver not ready, dropping packet data"); - return; - }*/ - - /* Delivering packet bytes with delays */ - byte[] packetData = packet.getPacketData(); - long deliveryTime = getMote().getSimulation().getSimulationTime(); - for (byte b: packetData) { - if (isInterfered()) { - b = (byte) 0xFF; - } - - final byte byteToDeliver = b; - getMote().getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { - public void execute(long t) { - super.execute(t); - cc1120.receivedByte(byteToDeliver); - mote.requestImmediateWakeup(); - } - }, deliveryTime); - deliveryTime += DELAY_BETWEEN_BYTES; - } - } - - /* Custom data radio support */ - public Object getLastCustomDataTransmitted() { - return lastOutgoingByte; - } - - public Object getLastCustomDataReceived() { - return lastIncomingByte; - } - - public void receiveCustomData(Object data) { - if (!(data instanceof Byte)) { - logger.fatal("Bad custom data: " + data); - return; - } - lastIncomingByte = (Byte) data; - - final byte inputByte; - if (isInterfered()) { - inputByte = (byte)0xFF; - } else { - inputByte = lastIncomingByte; - } - mote.getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { - public void execute(long t) { - super.execute(t); - cc1120.receivedByte(inputByte); - mote.requestImmediateWakeup(); - } - }, mote.getSimulation().getSimulationTime()); - - } - - /* General radio support */ - public boolean isTransmitting() { - return isTransmitting; - } - - public boolean isReceiving() { - return isReceiving; - } - - public boolean isInterfered() { - return isInterfered; - } - - public int getChannel() { - return cc1120.getActiveChannel()+1000; - } - - public int getFrequency() { - return cc1120.getActiveFrequency(); - } - - public void signalReceptionStart() { - isReceiving = true; - - lastEvent = RadioEvent.RECEPTION_STARTED; - /*logger.debug("----- CCC1120 RECEPTION STARTED -----");*/ - setChanged(); - notifyObservers(); - } - - public void signalReceptionEnd() { - /* Deliver packet data */ - isReceiving = false; - isInterfered = false; - - lastEvent = RadioEvent.RECEPTION_FINISHED; - /*logger.debug("----- CCC1120 RECEPTION FINISHED -----");*/ - setChanged(); - notifyObservers(); - } - - public RadioEvent getLastEvent() { - return lastEvent; - } - - public void interfereAnyReception() { - isInterfered = true; - isReceiving = false; - lastIncomingPacket = null; - - lastEvent = RadioEvent.RECEPTION_INTERFERED; - /*logger.debug("----- CCC1120 RECEPTION INTERFERED -----");*/ - setChanged(); - notifyObservers(); - } - - public double getCurrentOutputPower() { - /* TODO XXX Need support in CCC1120.java */ - return 1; - } - public int getCurrentOutputPowerIndicator() { - /* TODO XXX Need support in CCC1120.java */ - return 10; - } - public int getOutputPowerIndicatorMax() { - /* TODO XXX Need support in CCC1120.java */ - return 10; - } - - - /** - * Last 8 received signal strengths - */ - double currentSignalStrength = 0; - private double[] rssiLast = new double[8]; - private int rssiLastCounter = 0; - - public double getCurrentSignalStrength() { - return currentSignalStrength; - } - - public void setCurrentSignalStrength(final double signalStrength) { - if (signalStrength == currentSignalStrength) { - return; /* ignored */ - } - currentSignalStrength = signalStrength; - if (rssiLastCounter == 0) { - getMote().getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { - public void execute(long t) { - super.execute(t); - - /* Update average */ - System.arraycopy(rssiLast, 1, rssiLast, 0, 7); - rssiLast[7] = currentSignalStrength; - double avg = 0; - for (double v: rssiLast) { - avg += v; - } - avg /= rssiLast.length; - - cc1120.setRSSI((int) avg); - - rssiLastCounter--; - if (rssiLastCounter > 0) { - mote.getSimulation().scheduleEvent(this, t+DELAY_BETWEEN_BYTES/2); - } - } - }, mote.getSimulation().getSimulationTime()); - } - rssiLastCounter = 8; - } - - public Mote getMote() { - return mote; - } - - public Position getPosition() { - return mote.getInterfaces().getPosition(); - } - - public Collection getConfigXML() { - return null; - } - - public void setConfigXML(Collection configXML, boolean visAvailable) { - } - - public boolean isRadioOn() { - return cc1120.isReadyToReceive(); - } - - public boolean canReceiveFrom(CustomDataRadio radio) { - if (radio.getClass().equals(this.getClass())) { - return true; - } - return false; - } - -} +/* + * Copyright (c) 2012, Thingsquare. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +package org.contikios.cooja.mspmote.interfaces; + +import java.util.Collection; + +import org.apache.log4j.Logger; +import org.jdom.Element; + +import org.contikios.cooja.ClassDescription; +import org.contikios.cooja.Mote; +import org.contikios.cooja.RadioPacket; +import org.contikios.cooja.Simulation; +import org.contikios.cooja.interfaces.CustomDataRadio; +import org.contikios.cooja.interfaces.Position; +import org.contikios.cooja.interfaces.Radio; +import org.contikios.cooja.mspmote.MspMote; +import org.contikios.cooja.mspmote.MspMoteTimeEvent; +import se.sics.mspsim.chip.CC1120; +import se.sics.mspsim.chip.CC1120.ReceiverListener; +import se.sics.mspsim.chip.ChannelListener; +import se.sics.mspsim.chip.RFListener; +import se.sics.mspsim.chip.Radio802154; + +/** + * @author Fredrik Osterlind + */ +@ClassDescription("TI CC1120") +public class CC1120Radio extends Radio implements CustomDataRadio { + private static Logger logger = Logger.getLogger(CC1120Radio.class); + + /** + * Cross-level: + * Inter-byte delay for delivering cross-level packet bytes. + */ + /* TODO XXX Fix me as well as symbol duration in CC1120.java */ + public static final long DELAY_BETWEEN_BYTES = + (long) (1000.0*Simulation.MILLISECOND/(200000.0/8.0)); /* us. Corresponds to 200kbit/s */ + + private RadioEvent lastEvent = RadioEvent.UNKNOWN; + + private final MspMote mote; + private final CC1120 cc1120; + + private boolean isInterfered = false; + private boolean isTransmitting = false; + private boolean isReceiving = false; + + private byte lastOutgoingByte; + private byte lastIncomingByte; + + private RadioPacket lastOutgoingPacket = null; + private RadioPacket lastIncomingPacket = null; + + public CC1120Radio(Mote m) { + this.mote = (MspMote)m; + Radio802154 r = this.mote.getCPU().getChip(Radio802154.class); + if (r == null || !(r instanceof CC1120)) { + throw new IllegalStateException("Mote is not equipped with an CC1120 radio"); + } + this.cc1120 = (CC1120) r; + + cc1120.addRFListener(new RFListener() { + int len = 0; + int expLen = 0; + byte[] buffer = new byte[256 + 15]; + private boolean gotSynchbyte = false; + public void receivedByte(byte data) { + if (!isTransmitting()) { + /* Start transmission */ + lastEvent = RadioEvent.TRANSMISSION_STARTED; + isTransmitting = true; + len = 0; + gotSynchbyte = false; + /*logger.debug("----- CCC1120 TRANSMISSION STARTED -----");*/ + setChanged(); + notifyObservers(); + } + if (len >= buffer.length) { + /* Bad size packet, too large */ + logger.debug("Error: bad size: " + len + ", dropping outgoing byte: " + data); + return; + } + + /* send this byte to all nodes */ + lastOutgoingByte = data; + lastEvent = RadioEvent.CUSTOM_DATA_TRANSMITTED; + setChanged(); + notifyObservers(); + + /* Await synch byte */ + if (!gotSynchbyte) { + if (lastOutgoingByte == CC1120.SYNCH_BYTE_LAST) { + gotSynchbyte = true; + } + return; + } + + final int HEADERLEN = 1; /* 1x Length byte */ + final int FOOTERLEN = 2; /* TODO Fix CRC in Mspsim's CCC1120.java */ + if (len == 0) { + expLen = (0xff&data) + HEADERLEN + FOOTERLEN; + } + buffer[len++] = data; + + if (len == expLen) { + /*logger.debug("----- CCC1120 CUSTOM DATA TRANSMITTED -----");*/ + + final byte[] buf = new byte[expLen]; + System.arraycopy(buffer, 0, buf, 0, expLen); + lastOutgoingPacket = new RadioPacket() { + public byte[] getPacketData() { + return buf; + } + }; + + lastEvent = RadioEvent.PACKET_TRANSMITTED; + /*logger.debug("----- CCC1120 PACKET TRANSMITTED -----");*/ + setChanged(); + notifyObservers(); + + /*logger.debug("----- CCC1120 TRANSMISSION FINISHED -----");*/ + isTransmitting = false; + lastEvent = RadioEvent.TRANSMISSION_FINISHED; + setChanged(); + notifyObservers(); + len = 0; + } + } + }); + + cc1120.setReceiverListener(new ReceiverListener() { + public void newState(boolean on) { + if (cc1120.isReadyToReceive()) { + lastEvent = RadioEvent.HW_ON; + setChanged(); + notifyObservers(); + } else { + radioOff(); + } + } + }); + + cc1120.addChannelListener(new ChannelListener() { + public void channelChanged(int channel) { + /* XXX Currently assumes zero channel switch time */ + lastEvent = RadioEvent.UNKNOWN; + setChanged(); + notifyObservers(); + } + }); + } + + private void radioOff() { + /* Radio was turned off during transmission. + * May for example happen if watchdog triggers */ + if (isTransmitting()) { + logger.warn("Turning off radio while transmitting, ending packet prematurely"); + + /* Simulate end of packet */ + lastOutgoingPacket = new RadioPacket() { + public byte[] getPacketData() { + return new byte[0]; + } + }; + + lastEvent = RadioEvent.PACKET_TRANSMITTED; + /*logger.debug("----- CCC1120 PACKET TRANSMITTED -----");*/ + setChanged(); + notifyObservers(); + + /* Register that transmission ended in radio medium */ + /*logger.debug("----- CCC1120 TRANSMISSION FINISHED -----");*/ + isTransmitting = false; + lastEvent = RadioEvent.TRANSMISSION_FINISHED; + setChanged(); + notifyObservers(); + } + + lastEvent = RadioEvent.HW_OFF; + setChanged(); + notifyObservers(); + } + + /* Packet radio support */ + public RadioPacket getLastPacketTransmitted() { + return lastOutgoingPacket; + } + + public RadioPacket getLastPacketReceived() { + return lastIncomingPacket; + } + + public void setReceivedPacket(RadioPacket packet) { + lastIncomingPacket = packet; + + /* TODO XXX Need support in CCC1120.java */ + /*if (!radio.isReadyToReceive()) { + logger.warn("Radio receiver not ready, dropping packet data"); + return; + }*/ + + /* Delivering packet bytes with delays */ + byte[] packetData = packet.getPacketData(); + long deliveryTime = getMote().getSimulation().getSimulationTime(); + for (byte b: packetData) { + if (isInterfered()) { + b = (byte) 0xFF; + } + + final byte byteToDeliver = b; + getMote().getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { + public void execute(long t) { + super.execute(t); + cc1120.receivedByte(byteToDeliver); + mote.requestImmediateWakeup(); + } + }, deliveryTime); + deliveryTime += DELAY_BETWEEN_BYTES; + } + } + + /* Custom data radio support */ + public Object getLastCustomDataTransmitted() { + return lastOutgoingByte; + } + + public Object getLastCustomDataReceived() { + return lastIncomingByte; + } + + public void receiveCustomData(Object data) { + if (!(data instanceof Byte)) { + logger.fatal("Bad custom data: " + data); + return; + } + lastIncomingByte = (Byte) data; + + final byte inputByte; + if (isInterfered()) { + inputByte = (byte)0xFF; + } else { + inputByte = lastIncomingByte; + } + mote.getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { + public void execute(long t) { + super.execute(t); + cc1120.receivedByte(inputByte); + mote.requestImmediateWakeup(); + } + }, mote.getSimulation().getSimulationTime()); + + } + + /* General radio support */ + public boolean isTransmitting() { + return isTransmitting; + } + + public boolean isReceiving() { + return isReceiving; + } + + public boolean isInterfered() { + return isInterfered; + } + + public int getChannel() { + return cc1120.getActiveChannel()+1000; + } + + public int getFrequency() { + return cc1120.getActiveFrequency(); + } + + public void signalReceptionStart() { + isReceiving = true; + + lastEvent = RadioEvent.RECEPTION_STARTED; + /*logger.debug("----- CCC1120 RECEPTION STARTED -----");*/ + setChanged(); + notifyObservers(); + } + + public void signalReceptionEnd() { + /* Deliver packet data */ + isReceiving = false; + isInterfered = false; + + lastEvent = RadioEvent.RECEPTION_FINISHED; + /*logger.debug("----- CCC1120 RECEPTION FINISHED -----");*/ + setChanged(); + notifyObservers(); + } + + public RadioEvent getLastEvent() { + return lastEvent; + } + + public void interfereAnyReception() { + isInterfered = true; + isReceiving = false; + lastIncomingPacket = null; + + lastEvent = RadioEvent.RECEPTION_INTERFERED; + /*logger.debug("----- CCC1120 RECEPTION INTERFERED -----");*/ + setChanged(); + notifyObservers(); + } + + public double getCurrentOutputPower() { + /* TODO XXX Need support in CCC1120.java */ + return 1; + } + public int getCurrentOutputPowerIndicator() { + /* TODO XXX Need support in CCC1120.java */ + return 10; + } + public int getOutputPowerIndicatorMax() { + /* TODO XXX Need support in CCC1120.java */ + return 10; + } + + + /** + * Last 8 received signal strengths + */ + double currentSignalStrength = 0; + private double[] rssiLast = new double[8]; + private int rssiLastCounter = 0; + + public double getCurrentSignalStrength() { + return currentSignalStrength; + } + + public void setCurrentSignalStrength(final double signalStrength) { + if (signalStrength == currentSignalStrength) { + return; /* ignored */ + } + currentSignalStrength = signalStrength; + if (rssiLastCounter == 0) { + getMote().getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { + public void execute(long t) { + super.execute(t); + + /* Update average */ + System.arraycopy(rssiLast, 1, rssiLast, 0, 7); + rssiLast[7] = currentSignalStrength; + double avg = 0; + for (double v: rssiLast) { + avg += v; + } + avg /= rssiLast.length; + + cc1120.setRSSI((int) avg); + + rssiLastCounter--; + if (rssiLastCounter > 0) { + mote.getSimulation().scheduleEvent(this, t+DELAY_BETWEEN_BYTES/2); + } + } + }, mote.getSimulation().getSimulationTime()); + } + rssiLastCounter = 8; + } + + public Mote getMote() { + return mote; + } + + public Position getPosition() { + return mote.getInterfaces().getPosition(); + } + + public Collection getConfigXML() { + return null; + } + + public void setConfigXML(Collection configXML, boolean visAvailable) { + } + + public boolean isRadioOn() { + return cc1120.isReadyToReceive(); + } + + public boolean canReceiveFrom(CustomDataRadio radio) { + if (radio.getClass().equals(this.getClass())) { + return true; + } + return false; + } + +} diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2420RadioPacketConverter.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2420RadioPacketConverter.java index fd62da50f..116c3a38a 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2420RadioPacketConverter.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2420RadioPacketConverter.java @@ -46,7 +46,7 @@ public class CC2420RadioPacketConverter { public static final boolean WITH_XMAC = false; /* XXX No longer supported. Cross-level requires NULLMAC */ public static final boolean WITH_CHECKSUM = false; /* Contiki checksum. Not CC2420's built-in. */ public static final boolean WITH_TIMESTAMP = false; /* Contiki timestamp */ - public static final boolean WITH_FOOTER = true; /* CC2420's checksum */ + public static final boolean WITH_FOOTER = false; /* CC2420's checksum */ public static byte[] fromCoojaToCC2420(RadioPacket packet) { byte cc2420Data[] = new byte[6+127]; @@ -165,7 +165,7 @@ public class CC2420RadioPacketConverter { } /* 1 byte length */ - len = data[pos]; + len = data[pos] & 0xFF; originalLen = len; pos += 1; @@ -198,7 +198,7 @@ public class CC2420RadioPacketConverter { System.arraycopy(data, 6 /* skipping preamble+synch+len */, originalData, 0, originalLen); if (len < 0) { /*logger.warn("No cross-level conversion available: negative packet length");*/ - return new ConvertedRadioPacket(new byte[0], originalData); + return null; } byte convertedData[] = new byte[len]; System.arraycopy(data, pos, convertedData, 0, len); diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2520Radio.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2520Radio.java index d219f9171..49d86c451 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2520Radio.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2520Radio.java @@ -1,378 +1,378 @@ - -package org.contikios.cooja.mspmote.interfaces; - -import java.util.Collection; - -import org.apache.log4j.Logger; -import org.jdom.Element; - -import org.contikios.cooja.ClassDescription; -import org.contikios.cooja.Mote; -import org.contikios.cooja.RadioPacket; -import org.contikios.cooja.Simulation; -import org.contikios.cooja.interfaces.CustomDataRadio; -import org.contikios.cooja.interfaces.Position; -import org.contikios.cooja.interfaces.Radio; -import org.contikios.cooja.mspmote.MspMote; -import org.contikios.cooja.mspmote.MspMoteTimeEvent; -import org.contikios.cooja.mspmote.interfaces.CC2420RadioPacketConverter; -import se.sics.mspsim.chip.CC2520; -import se.sics.mspsim.chip.ChannelListener; -import se.sics.mspsim.chip.RFListener; -import se.sics.mspsim.core.Chip; -import se.sics.mspsim.core.OperatingModeListener; - -/** - * MSPSim CC2520 radio to COOJA wrapper. - * - * @author Fredrik Osterlind - */ -@ClassDescription("IEEE CC2520 Radio") -public class CC2520Radio extends Radio implements CustomDataRadio { - private static Logger logger = Logger.getLogger(CC2520Radio.class); - - /** - * Cross-level: - * Inter-byte delay for delivering cross-level packet bytes. - */ - public static final long DELAY_BETWEEN_BYTES = - (long) (1000.0*Simulation.MILLISECOND/(250000.0/8.0)); /* us. Corresponds to 250kbit/s */ - - private RadioEvent lastEvent = RadioEvent.UNKNOWN; - - private final MspMote mote; - private final CC2520 radio; - - private boolean isInterfered = false; - private boolean isTransmitting = false; - private boolean isReceiving = false; - - private byte lastOutgoingByte; - private byte lastIncomingByte; - - private RadioPacket lastOutgoingPacket = null; - private RadioPacket lastIncomingPacket = null; - - public CC2520Radio(Mote m) { - this.mote = (MspMote)m; - this.radio = this.mote.getCPU().getChip(CC2520.class); - if (radio == null) { - throw new IllegalStateException("Mote is not equipped with an IEEE CC2520 radio"); - } - - radio.addRFListener(new RFListener() { - int len = 0; - int expLen = 0; - byte[] buffer = new byte[127 + 15]; - public void receivedByte(byte data) { - if (!isTransmitting()) { - lastEvent = RadioEvent.TRANSMISSION_STARTED; - isTransmitting = true; - len = 0; - /*logger.debug("----- CC2520 TRANSMISSION STARTED -----");*/ - setChanged(); - notifyObservers(); - } - - if (len >= buffer.length) { - /* Bad size packet, too large */ - logger.debug("Error: bad size: " + len + ", dropping outgoing byte: " + data); - return; - } - - /* send this byte to all nodes */ - lastOutgoingByte = data; - lastEvent = RadioEvent.CUSTOM_DATA_TRANSMITTED; - setChanged(); - notifyObservers(); - - buffer[len++] = data; - - if (len == 6) { -// System.out.println("## CC2520 Packet of length: " + data + " expected..."); - expLen = data + 6; - } - - if (len == expLen) { - /*logger.debug("----- CC2520 CUSTOM DATA TRANSMITTED -----");*/ - len -= 4; /* preamble */ - len -= 1; /* synch */ - len -= radio.getFooterLength(); /* footer */ - final byte[] packetdata = new byte[len]; - System.arraycopy(buffer, 4+1, packetdata, 0, len); - lastOutgoingPacket = new RadioPacket() { - public byte[] getPacketData() { - return packetdata; - } - }; - - /*logger.debug("----- CC2520 PACKET TRANSMITTED -----");*/ - setChanged(); - notifyObservers(); - - /*logger.debug("----- CC2520 TRANSMISSION FINISHED -----");*/ - isTransmitting = false; - lastEvent = RadioEvent.TRANSMISSION_FINISHED; - setChanged(); - notifyObservers(); - len = 0; - } - } - }); - - radio.addOperatingModeListener(new OperatingModeListener() { - public void modeChanged(Chip source, int mode) { - if (radio.isReadyToReceive()) { - lastEvent = RadioEvent.HW_ON; - setChanged(); - notifyObservers(); - } else { - radioOff(); - } - } - }); - - radio.addChannelListener(new ChannelListener() { - public void channelChanged(int channel) { - /* XXX Currently assumes zero channel switch time */ - lastEvent = RadioEvent.UNKNOWN; - setChanged(); - notifyObservers(); - } - }); - } - - private void radioOff() { - /* Radio was turned off during transmission. - * May for example happen if watchdog triggers */ - if (isTransmitting()) { - logger.warn("Turning off radio while transmitting, ending packet prematurely"); - - /* Simulate end of packet */ - lastOutgoingPacket = new RadioPacket() { - public byte[] getPacketData() { - return new byte[0]; - } - }; - - lastEvent = RadioEvent.PACKET_TRANSMITTED; - /*logger.debug("----- CC2520 PACKET TRANSMITTED -----");*/ - setChanged(); - notifyObservers(); - - /* Register that transmission ended in radio medium */ - /*logger.debug("----- CC2520 TRANSMISSION FINISHED -----");*/ - isTransmitting = false; - lastEvent = RadioEvent.TRANSMISSION_FINISHED; - setChanged(); - notifyObservers(); - } - - lastEvent = RadioEvent.HW_OFF; - setChanged(); - notifyObservers(); - } - - /* Packet radio support */ - public RadioPacket getLastPacketTransmitted() { - return lastOutgoingPacket; - } - - public RadioPacket getLastPacketReceived() { - return lastIncomingPacket; - } - - public void setReceivedPacket(RadioPacket packet) { - logger.fatal("TODO Implement me!"); - } - - /* Custom data radio support */ - public Object getLastCustomDataTransmitted() { - return lastOutgoingByte; - } - - public Object getLastCustomDataReceived() { - return lastIncomingByte; - } - - public void receiveCustomData(Object data) { - if (!(data instanceof Byte)) { - logger.fatal("Bad custom data: " + data); - return; - } - lastIncomingByte = (Byte) data; - - final byte inputByte; - if (isInterfered()) { - inputByte = (byte)0xFF; - } else { - inputByte = lastIncomingByte; - } - mote.getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { - public void execute(long t) { - super.execute(t); - radio.receivedByte(inputByte); - mote.requestImmediateWakeup(); - } - }, mote.getSimulation().getSimulationTime()); - - } - - /* General radio support */ - public boolean isTransmitting() { - return isTransmitting; - } - - public boolean isReceiving() { - return isReceiving; - } - - public boolean isInterfered() { - return isInterfered; - } - - public int getChannel() { - return radio.getActiveChannel(); - } - - public int getFrequency() { - return radio.getActiveFrequency(); - } - - public void signalReceptionStart() { - isReceiving = true; - - lastEvent = RadioEvent.RECEPTION_STARTED; - /*logger.debug("----- CC2520 RECEPTION STARTED -----");*/ - setChanged(); - notifyObservers(); - } - - public void signalReceptionEnd() { - /* Deliver packet data */ - isReceiving = false; - isInterfered = false; - - lastEvent = RadioEvent.RECEPTION_FINISHED; - /*logger.debug("----- CC2520 RECEPTION FINISHED -----");*/ - setChanged(); - notifyObservers(); - } - - public RadioEvent getLastEvent() { - return lastEvent; - } - - public void interfereAnyReception() { - isInterfered = true; - isReceiving = false; - lastIncomingPacket = null; - - lastEvent = RadioEvent.RECEPTION_INTERFERED; - /*logger.debug("----- CC2520 RECEPTION INTERFERED -----");*/ - setChanged(); - notifyObservers(); - } - - public double getCurrentOutputPower() { - return radio.getOutputPower(); - } - - public int getCurrentOutputPowerIndicator() { - return 100; -// return radio.getOutputPowerIndicator(); - } - - public int getOutputPowerIndicatorMax() { - return 100; -// return 31; - } - - double currentSignalStrength = 0; - - /** - * Last 8 received signal strengths - */ - private double[] rssiLast = new double[8]; - private int rssiLastCounter = 0; - - public double getCurrentSignalStrength() { - return currentSignalStrength; - } - - public void setCurrentSignalStrength(final double signalStrength) { - if (signalStrength == currentSignalStrength) { - return; /* ignored */ - } - currentSignalStrength = signalStrength; - if (rssiLastCounter == 0) { - getMote().getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { - public void execute(long t) { - super.execute(t); - - /* Update average */ - System.arraycopy(rssiLast, 1, rssiLast, 0, 7); - rssiLast[7] = currentSignalStrength; - double avg = 0; - for (double v: rssiLast) { - avg += v; - } - avg /= rssiLast.length; - - radio.setRSSI((int) avg); - - rssiLastCounter--; - if (rssiLastCounter > 0) { - mote.getSimulation().scheduleEvent(this, t+DELAY_BETWEEN_BYTES/2); - } - } - }, mote.getSimulation().getSimulationTime()); - } - rssiLastCounter = 8; - } - - - public void setLQI(int lqi){ - radio.setLQI(lqi); - } - - public int getLQI(){ - return radio.getLQI(); - } - - - public Mote getMote() { - return mote; - } - - public Position getPosition() { - return mote.getInterfaces().getPosition(); - } - - public Collection getConfigXML() { - return null; - } - - public void setConfigXML(Collection configXML, boolean visAvailable) { - } - - public boolean isRadioOn() { - if (radio.isReadyToReceive()) { - return true; - } - if (radio.getMode() == CC2520.MODE_POWER_OFF) { - return false; - } - if (radio.getMode() == CC2520.MODE_TXRX_OFF) { - return false; - } - return true; - } - - public boolean canReceiveFrom(CustomDataRadio radio) { - if (radio.getClass().equals(this.getClass())) { - return true; - } - return false; - } -} + +package org.contikios.cooja.mspmote.interfaces; + +import java.util.Collection; + +import org.apache.log4j.Logger; +import org.jdom.Element; + +import org.contikios.cooja.ClassDescription; +import org.contikios.cooja.Mote; +import org.contikios.cooja.RadioPacket; +import org.contikios.cooja.Simulation; +import org.contikios.cooja.interfaces.CustomDataRadio; +import org.contikios.cooja.interfaces.Position; +import org.contikios.cooja.interfaces.Radio; +import org.contikios.cooja.mspmote.MspMote; +import org.contikios.cooja.mspmote.MspMoteTimeEvent; +import org.contikios.cooja.mspmote.interfaces.CC2420RadioPacketConverter; +import se.sics.mspsim.chip.CC2520; +import se.sics.mspsim.chip.ChannelListener; +import se.sics.mspsim.chip.RFListener; +import se.sics.mspsim.core.Chip; +import se.sics.mspsim.core.OperatingModeListener; + +/** + * MSPSim CC2520 radio to COOJA wrapper. + * + * @author Fredrik Osterlind + */ +@ClassDescription("IEEE CC2520 Radio") +public class CC2520Radio extends Radio implements CustomDataRadio { + private static Logger logger = Logger.getLogger(CC2520Radio.class); + + /** + * Cross-level: + * Inter-byte delay for delivering cross-level packet bytes. + */ + public static final long DELAY_BETWEEN_BYTES = + (long) (1000.0*Simulation.MILLISECOND/(250000.0/8.0)); /* us. Corresponds to 250kbit/s */ + + private RadioEvent lastEvent = RadioEvent.UNKNOWN; + + private final MspMote mote; + private final CC2520 radio; + + private boolean isInterfered = false; + private boolean isTransmitting = false; + private boolean isReceiving = false; + + private byte lastOutgoingByte; + private byte lastIncomingByte; + + private RadioPacket lastOutgoingPacket = null; + private RadioPacket lastIncomingPacket = null; + + public CC2520Radio(Mote m) { + this.mote = (MspMote)m; + this.radio = this.mote.getCPU().getChip(CC2520.class); + if (radio == null) { + throw new IllegalStateException("Mote is not equipped with an IEEE CC2520 radio"); + } + + radio.addRFListener(new RFListener() { + int len = 0; + int expLen = 0; + byte[] buffer = new byte[127 + 15]; + public void receivedByte(byte data) { + if (!isTransmitting()) { + lastEvent = RadioEvent.TRANSMISSION_STARTED; + isTransmitting = true; + len = 0; + /*logger.debug("----- CC2520 TRANSMISSION STARTED -----");*/ + setChanged(); + notifyObservers(); + } + + if (len >= buffer.length) { + /* Bad size packet, too large */ + logger.debug("Error: bad size: " + len + ", dropping outgoing byte: " + data); + return; + } + + /* send this byte to all nodes */ + lastOutgoingByte = data; + lastEvent = RadioEvent.CUSTOM_DATA_TRANSMITTED; + setChanged(); + notifyObservers(); + + buffer[len++] = data; + + if (len == 6) { +// System.out.println("## CC2520 Packet of length: " + data + " expected..."); + expLen = data + 6; + } + + if (len == expLen) { + /*logger.debug("----- CC2520 CUSTOM DATA TRANSMITTED -----");*/ + len -= 4; /* preamble */ + len -= 1; /* synch */ + len -= radio.getFooterLength(); /* footer */ + final byte[] packetdata = new byte[len]; + System.arraycopy(buffer, 4+1, packetdata, 0, len); + lastOutgoingPacket = new RadioPacket() { + public byte[] getPacketData() { + return packetdata; + } + }; + + /*logger.debug("----- CC2520 PACKET TRANSMITTED -----");*/ + setChanged(); + notifyObservers(); + + /*logger.debug("----- CC2520 TRANSMISSION FINISHED -----");*/ + isTransmitting = false; + lastEvent = RadioEvent.TRANSMISSION_FINISHED; + setChanged(); + notifyObservers(); + len = 0; + } + } + }); + + radio.addOperatingModeListener(new OperatingModeListener() { + public void modeChanged(Chip source, int mode) { + if (radio.isReadyToReceive()) { + lastEvent = RadioEvent.HW_ON; + setChanged(); + notifyObservers(); + } else { + radioOff(); + } + } + }); + + radio.addChannelListener(new ChannelListener() { + public void channelChanged(int channel) { + /* XXX Currently assumes zero channel switch time */ + lastEvent = RadioEvent.UNKNOWN; + setChanged(); + notifyObservers(); + } + }); + } + + private void radioOff() { + /* Radio was turned off during transmission. + * May for example happen if watchdog triggers */ + if (isTransmitting()) { + logger.warn("Turning off radio while transmitting, ending packet prematurely"); + + /* Simulate end of packet */ + lastOutgoingPacket = new RadioPacket() { + public byte[] getPacketData() { + return new byte[0]; + } + }; + + lastEvent = RadioEvent.PACKET_TRANSMITTED; + /*logger.debug("----- CC2520 PACKET TRANSMITTED -----");*/ + setChanged(); + notifyObservers(); + + /* Register that transmission ended in radio medium */ + /*logger.debug("----- CC2520 TRANSMISSION FINISHED -----");*/ + isTransmitting = false; + lastEvent = RadioEvent.TRANSMISSION_FINISHED; + setChanged(); + notifyObservers(); + } + + lastEvent = RadioEvent.HW_OFF; + setChanged(); + notifyObservers(); + } + + /* Packet radio support */ + public RadioPacket getLastPacketTransmitted() { + return lastOutgoingPacket; + } + + public RadioPacket getLastPacketReceived() { + return lastIncomingPacket; + } + + public void setReceivedPacket(RadioPacket packet) { + logger.fatal("TODO Implement me!"); + } + + /* Custom data radio support */ + public Object getLastCustomDataTransmitted() { + return lastOutgoingByte; + } + + public Object getLastCustomDataReceived() { + return lastIncomingByte; + } + + public void receiveCustomData(Object data) { + if (!(data instanceof Byte)) { + logger.fatal("Bad custom data: " + data); + return; + } + lastIncomingByte = (Byte) data; + + final byte inputByte; + if (isInterfered()) { + inputByte = (byte)0xFF; + } else { + inputByte = lastIncomingByte; + } + mote.getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { + public void execute(long t) { + super.execute(t); + radio.receivedByte(inputByte); + mote.requestImmediateWakeup(); + } + }, mote.getSimulation().getSimulationTime()); + + } + + /* General radio support */ + public boolean isTransmitting() { + return isTransmitting; + } + + public boolean isReceiving() { + return isReceiving; + } + + public boolean isInterfered() { + return isInterfered; + } + + public int getChannel() { + return radio.getActiveChannel(); + } + + public int getFrequency() { + return radio.getActiveFrequency(); + } + + public void signalReceptionStart() { + isReceiving = true; + + lastEvent = RadioEvent.RECEPTION_STARTED; + /*logger.debug("----- CC2520 RECEPTION STARTED -----");*/ + setChanged(); + notifyObservers(); + } + + public void signalReceptionEnd() { + /* Deliver packet data */ + isReceiving = false; + isInterfered = false; + + lastEvent = RadioEvent.RECEPTION_FINISHED; + /*logger.debug("----- CC2520 RECEPTION FINISHED -----");*/ + setChanged(); + notifyObservers(); + } + + public RadioEvent getLastEvent() { + return lastEvent; + } + + public void interfereAnyReception() { + isInterfered = true; + isReceiving = false; + lastIncomingPacket = null; + + lastEvent = RadioEvent.RECEPTION_INTERFERED; + /*logger.debug("----- CC2520 RECEPTION INTERFERED -----");*/ + setChanged(); + notifyObservers(); + } + + public double getCurrentOutputPower() { + return radio.getOutputPower(); + } + + public int getCurrentOutputPowerIndicator() { + return 100; +// return radio.getOutputPowerIndicator(); + } + + public int getOutputPowerIndicatorMax() { + return 100; +// return 31; + } + + double currentSignalStrength = 0; + + /** + * Last 8 received signal strengths + */ + private double[] rssiLast = new double[8]; + private int rssiLastCounter = 0; + + public double getCurrentSignalStrength() { + return currentSignalStrength; + } + + public void setCurrentSignalStrength(final double signalStrength) { + if (signalStrength == currentSignalStrength) { + return; /* ignored */ + } + currentSignalStrength = signalStrength; + if (rssiLastCounter == 0) { + getMote().getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { + public void execute(long t) { + super.execute(t); + + /* Update average */ + System.arraycopy(rssiLast, 1, rssiLast, 0, 7); + rssiLast[7] = currentSignalStrength; + double avg = 0; + for (double v: rssiLast) { + avg += v; + } + avg /= rssiLast.length; + + radio.setRSSI((int) avg); + + rssiLastCounter--; + if (rssiLastCounter > 0) { + mote.getSimulation().scheduleEvent(this, t+DELAY_BETWEEN_BYTES/2); + } + } + }, mote.getSimulation().getSimulationTime()); + } + rssiLastCounter = 8; + } + + + public void setLQI(int lqi){ + radio.setLQI(lqi); + } + + public int getLQI(){ + return radio.getLQI(); + } + + + public Mote getMote() { + return mote; + } + + public Position getPosition() { + return mote.getInterfaces().getPosition(); + } + + public Collection getConfigXML() { + return null; + } + + public void setConfigXML(Collection configXML, boolean visAvailable) { + } + + public boolean isRadioOn() { + if (radio.isReadyToReceive()) { + return true; + } + if (radio.getMode() == CC2520.MODE_POWER_OFF) { + return false; + } + if (radio.getMode() == CC2520.MODE_TXRX_OFF) { + return false; + } + return true; + } + + public boolean canReceiveFrom(CustomDataRadio radio) { + if (radio.getClass().equals(this.getClass())) { + return true; + } + return false; + } +} diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC430Radio.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC430Radio.java index 692c9996c..68c971e8e 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC430Radio.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC430Radio.java @@ -1,50 +1,50 @@ -/* - * Copyright (c) 2012, Thingsquare. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - */ - -package org.contikios.cooja.mspmote.interfaces; - -import org.apache.log4j.Logger; - -import org.contikios.cooja.ClassDescription; -import org.contikios.cooja.Mote; -import org.contikios.cooja.interfaces.CustomDataRadio; - -/** - * @author Fredrik Osterlind - */ -@ClassDescription("TI CC1101 (CC430)") -public class CC430Radio extends CC1101Radio implements CustomDataRadio { - private static Logger logger = Logger.getLogger(CC1101Radio.class); - - public CC430Radio(Mote m) { - super(m); - } - -} +/* + * Copyright (c) 2012, Thingsquare. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +package org.contikios.cooja.mspmote.interfaces; + +import org.apache.log4j.Logger; + +import org.contikios.cooja.ClassDescription; +import org.contikios.cooja.Mote; +import org.contikios.cooja.interfaces.CustomDataRadio; + +/** + * @author Fredrik Osterlind + */ +@ClassDescription("TI CC1101 (CC430)") +public class CC430Radio extends CC1101Radio implements CustomDataRadio { + private static Logger logger = Logger.getLogger(CC1101Radio.class); + + public CC430Radio(Mote m) { + super(m); + } + +} diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/ESBButton.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/ESBButton.java index c722e74eb..a16207c72 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/ESBButton.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/ESBButton.java @@ -30,13 +30,7 @@ package org.contikios.cooja.mspmote.interfaces; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.Collection; -import javax.swing.JButton; -import javax.swing.JPanel; import org.apache.log4j.Logger; -import org.jdom.Element; import org.contikios.cooja.*; import org.contikios.cooja.interfaces.Button; @@ -47,58 +41,28 @@ import org.contikios.cooja.mspmote.ESBMote; */ @ClassDescription("Button") public class ESBButton extends Button { - private static Logger logger = Logger.getLogger(ESBButton.class); + private static final Logger logger = Logger.getLogger(ESBButton.class); - private ESBMote mote; + private final ESBMote mote; public ESBButton(Mote mote) { + super(mote); this.mote = (ESBMote) mote; } - public void clickButton() { - pressButton(); - releaseButton(); - } - - public void releaseButton() { + @Override + protected void doReleaseButton() { mote.esbNode.setButton(false); - setChanged(); - notifyObservers(); } - public void pressButton() { + @Override + protected void doPressButton() { mote.esbNode.setButton(true); - setChanged(); - notifyObservers(); } + @Override public boolean isPressed() { return false; } - public JPanel getInterfaceVisualizer() { - JPanel panel = new JPanel(); - final JButton clickButton = new JButton("Click button"); - - panel.add(clickButton); - - clickButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - clickButton(); - } - }); - - return panel; - } - - public void releaseInterfaceVisualizer(JPanel panel) { - } - - public Collection getConfigXML() { - return null; - } - - public void setConfigXML(Collection configXML, boolean visAvailable) { - } - } diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154BitErrorRadio.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154BitErrorRadio.java new file mode 100644 index 000000000..53b971755 --- /dev/null +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154BitErrorRadio.java @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2014, Uppsala University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +package org.contikios.cooja.mspmote.interfaces; + +import java.util.Random; + +import org.apache.log4j.Logger; + +import org.contikios.cooja.ClassDescription; +import org.contikios.cooja.Mote; +import org.contikios.cooja.Simulation; +import org.contikios.cooja.radiomediums.AbstractRadioMedium; + +import org.contikios.cooja.mspmote.MspMoteTimeEvent; +import org.contikios.cooja.mspmote.interfaces.Msp802154Radio; + + +/** + * Extension of MSPSim 802.15.4 radio wrapper with bit-level errors. + * + * Only errors due to signal fading are supported (as opposed to errors to interference). + * Interesting modelling effects can obtained if this is used together with a dynamic + * channel fading model. + * + * @author Atis Elsts + */ +@ClassDescription("IEEE 802.15.4 Bit Error Radio") +public class Msp802154BitErrorRadio extends Msp802154Radio { + private static Logger logger = Logger.getLogger(Msp802154Radio.class); + + private static final double NOISE_FLOOR = AbstractRadioMedium.SS_WEAK; + private static final double GOOD_SIGNAL = NOISE_FLOOR + 15.0; + + private Random random = null; + + public Msp802154BitErrorRadio(Mote m) { + super(m); + + random = getMote().getSimulation().getRandomGenerator(); + } + + /* The MSK-transformed symbol-to-codeword table. + * It's used for mapping between symbols and codeword by some popular + * 802.15.4 radios such as CC2420 and CC2520. */ + private static final int[] mskEncodeTable = { + 1618456172, + 1309113062, + 1826650030, + 1724778362, + 778887287, + 2061946375, + 2007919840, + 125494990, + 529027475, + 838370585, + 320833617, + 422705285, + 1368596360, + 85537272, + 139563807, + 2021988657 + }; + + /* Calculates the Hamming distance between two words */ + private int hammingDistance(int x1, int x2) { + return Integer.bitCount(x1 ^ x2); + } + + /* Send a symbol over the air with a specific bit error rate */ + private int transceiveSymbolWithErrors(int txSymbol, double bitErrorRate) { + /* First, transmit (encode and randomly corrupt) it */ + int chipSequence = mskEncodeTable[txSymbol]; + /* Note: loop until 31, not until 32 here, as the highest bit in the codeword + * is irrelevant for MSK encoded data, and therefore should not come into + * the Hamming distance calculations. */ + for (int i = 0; i < 31; ++i) { + double p = random.nextDouble(); + if (p < bitErrorRate) { + chipSequence ^= (1 << i); + } + } + + /* Now receive (decode) it */ + int bestRxSymbol = 0; + int bestHammingDistance = 32; + for (byte i = 0; i < 16; ++i) { + /* Resolve ties in a specific order: + * s7, s6, ... , s0, s15, s14 , ..., s8 */ + int rxSymbol = i < 8 ? 7 - i : 15 - i + 8; + + int hd = hammingDistance(chipSequence, mskEncodeTable[rxSymbol]); + if (hd < bestHammingDistance) { + bestRxSymbol = rxSymbol; + bestHammingDistance = hd; + if (hd == 0) { + break; + } + } + } + return bestRxSymbol; + } + + /* This is the probability that a bit will received incorrectly, for + * -95.0, -94.9, -94.8, ..., -80.0 dBm signal levels. + * It is modelled as Additive White Gaussian Noise (AWGN) channel + * with constellation size = 4, and log2(4) = 2 bits per over-the-air symbol. + * (See "Digital Communications" by Proakis, page 311) + * + * The table was generated with the following Python code: + * + * noise_floor = -95.0 + * good_signal = noise_floor + 15.0 + * + * # chips per second / carrier frequency + * # In this case: + * # 250 kbps * symbols_per_bit / 5 MHz 802.15.4 channel bandwidth + * spectral_efficiency = 250000 * (32 / 4) / 5000000. + * + * def snr_from_rssi(signal): + * return signal - noise_floor + * + * def combinations(n, k): + * return math.factorial(n) / (math.factorial(k) * math.factorial(n - k)) + * + * def chip_error_rate(signal): + * M_sk = 4 # constellation size + * K_b = 2 # bits per symbol + * snr = snr_from_rssi(signal) * spectral_efficiency # signal-noise ratio + * result = 0.0 + * for k in range(1, M_sk): + * result += ((-1)**(k + 1) / (k + 1.0)) * combinations(M_sk - 1, k) * math.exp(- (k / (k + 1.0)) * K_b * snr) + * return result * (M_sk / 2) / (M_sk - 1) + * + * for signal in range(int(noise_floor), int(good_signal + 1)): + * for decimal_part in range(10): + * s = signal + decimal_part / 10.0 + * print("{}: {:.16}".format(s, chip_error_rate(s))) + */ + private static final double[] bitErrorRateTable = { + 0.5000000000000000, + 0.4857075690874351, + 0.4717195981917559, + 0.4580362793082289, + 0.4446572346573086, + 0.4315815642818357, + 0.4188078906959320, + 0.4063344007440545, + 0.3941588848209507, + 0.3822787735959348, + 0.3706911723779558, + 0.3593928932511307, + 0.3483804851041035, + 0.3376502616704103, + 0.3271983276911817, + 0.3170206033059785, + 0.3071128467721474, + 0.2974706756080624, + 0.2880895862507204, + 0.2789649723135144, + 0.2700921415256470, + 0.2614663314303489, + 0.2530827239151328, + 0.2449364586434322, + 0.2370226454533358, + 0.2293363757856961, + 0.2218727332005190, + 0.2146268030374602, + 0.2075936812732179, + 0.2007684826257659, + 0.1941463479526962, + 0.1877224509883067, + 0.1814920044616803, + 0.1754502656356323, + 0.1695925413041991, + 0.1639141922842669, + 0.1584106374348990, + 0.1530773572360710, + 0.1479098969566969, + 0.1429038694401250, + 0.1380549575336883, + 0.1333589161873203, + 0.1288115742448300, + 0.1244088359500270, + 0.1201466821885792, + 0.1160211714852698, + 0.1120284407751141, + 0.1081647059657158, + 0.1044262623071727, + 0.1008094845848469, + 0.0973108271493890, + 0.0939268237974889, + 0.0906540875160106, + 0.0874893101013543, + 0.0844292616651377, + 0.0814707900365929, + 0.0786108200713800, + 0.0758463528759084, + 0.0731744649556428, + 0.0705923072953072, + 0.0680971043783837, + 0.0656861531527741, + 0.0633568219490458, + 0.0611065493572223, + 0.0589328430676567, + 0.0568332786811473, + 0.0548054984930601, + 0.0528472102558939, + 0.0509561859243809, + 0.0491302603869077, + 0.0473673301867607, + 0.0456653522364111, + 0.0440223425278144, + 0.0424363748414465, + 0.0409055794565784, + 0.0394281418650815, + 0.0380023014908522, + 0.0366263504167641, + 0.0352986321208818, + 0.0340175402235017, + 0.0327815172464461, + 0.0315890533858807, + 0.0304386852998058, + 0.0293289949112408, + 0.0282586082280085, + 0.0272261941799208, + 0.0262304634740650, + 0.0252701674687994, + 0.0243440970669807, + 0.0234510816288642, + 0.0225899879050480, + 0.0217597189897583, + 0.0209592132947168, + 0.0201874435437662, + 0.0194434157883799, + 0.0187261684441326, + 0.0180347713481601, + 0.0173683248375987, + 0.0167259588489542, + 0.0161068320383143, + 0.0155101309222909, + 0.0149350690395443, + 0.0143808861327198, + 0.0138468473506013, + 0.0133322424702643, + 0.0128363851389939, + 0.0123586121357148, + 0.0118982826516654, + 0.0114547775900349, + 0.0110274988842702, + 0.0106158688347500, + 0.0102193294635131, + 0.0098373418867231, + 0.0094693857045423, + 0.0091149584080853, + 0.0087735748031163, + 0.0084447664501541, + 0.0081280811206428, + 0.0078230822688482, + 0.0075293485191375, + 0.0072464731683002, + 0.0069740637025694, + 0.0067117413290037, + 0.0064591405208906, + 0.0062159085768378, + 0.0059817051932169, + 0.0057562020496316, + 0.0055390824070828, + 0.0053300407185094, + 0.0051287822513842, + 0.0049350227220528, + 0.0047484879415055, + 0.0045689134722762, + 0.0043960442961698, + 0.0042296344925230, + 0.0040694469267080, + 0.0039152529485966, + 0.0037668321007033, + 0.0036239718357372, + 0.0034864672432910, + 0.0033541207854084, + 0.0032267420407699, + 0.0031041474572487, + 0.0029861601125883, + 0.0028726094829638, + 0.0027633312191911, + 0.0026581669303560, + 0.0025569639746388, + 0.0024595752571165, + 0.0023658590343307, + 0.0022756787254125 + }; + + private double getBitErrorRate(double signal) { + if (signal <= NOISE_FLOOR) { + return 0.5; + } else if (signal >= GOOD_SIGNAL) { + return 0.0; + } else { + long position = Math.round((signal - NOISE_FLOOR) * 10.0); + return bitErrorRateTable[(int)position]; + } + } + + public void receiveCustomData(Object data) { + if (!(data instanceof Byte)) { + logger.fatal("Bad custom data: " + data); + return; + } + lastIncomingByte = (Byte) data; + + final byte inputByte; + if (isInterfered()) { + inputByte = (byte)0xFF; + } else { + double bitErrorRate = getBitErrorRate(currentSignalStrength); + if (bitErrorRate == 0.0) { + inputByte = lastIncomingByte; + } else if (bitErrorRate >= 0.5) { + inputByte = (byte) 0xFF; + } else { + /* convert to an unsigned int in order to prettify subsequent operations with bits */ + int incomingByteAsInt = lastIncomingByte; + if (incomingByteAsInt < 0) incomingByteAsInt += 256; + + /* a byte consists of 2 symbols; independently transceive each of them */ + int firstSymbol = transceiveSymbolWithErrors(incomingByteAsInt >> 4, bitErrorRate); + int secondSymbol = transceiveSymbolWithErrors(incomingByteAsInt & 0xf, bitErrorRate); + + inputByte = (byte)((firstSymbol << 4) + secondSymbol); + } + } + + mote.getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) { + public void execute(long t) { + super.execute(t); + radio.receivedByte(inputByte); + mote.requestImmediateWakeup(); + } + }, mote.getSimulation().getSimulationTime()); + + } +} diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java index 2effa50d7..baa9676a9 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java @@ -69,15 +69,16 @@ public class Msp802154Radio extends Radio implements CustomDataRadio { private RadioEvent lastEvent = RadioEvent.UNKNOWN; - private final MspMote mote; - private final Radio802154 radio; + protected final MspMote mote; + protected final Radio802154 radio; private boolean isInterfered = false; private boolean isTransmitting = false; private boolean isReceiving = false; + private boolean isSynchronized = false; - private byte lastOutgoingByte; - private byte lastIncomingByte; + protected byte lastOutgoingByte; + protected byte lastIncomingByte; private RadioPacket lastOutgoingPacket = null; private RadioPacket lastIncomingPacket = null; @@ -91,22 +92,20 @@ public class Msp802154Radio extends Radio implements CustomDataRadio { radio.addRFListener(new RFListener() { int len = 0; - int expLen = 0; - byte[] buffer = new byte[127 + 15]; + int expMpduLen = 0; + byte[] buffer = new byte[127 + 6]; + final private byte[] syncSeq = {0,0,0,0,0x7A}; + public void receivedByte(byte data) { if (!isTransmitting()) { lastEvent = RadioEvent.TRANSMISSION_STARTED; + lastOutgoingPacket = null; isTransmitting = true; len = 0; - /*logger.debug("----- 802.15.4 TRANSMISSION STARTED -----");*/ + expMpduLen = 0; setChanged(); notifyObservers(); - } - - if (len >= buffer.length) { - /* Bad size packet, too large */ - logger.debug("Error: bad size: " + len + ", dropping outgoing byte: " + data); - return; + /*logger.debug("----- 802.15.4 TRANSMISSION STARTED -----");*/ } /* send this byte to all nodes */ @@ -115,31 +114,42 @@ public class Msp802154Radio extends Radio implements CustomDataRadio { setChanged(); notifyObservers(); - buffer[len++] = data; + if (len < buffer.length) + buffer[len] = data; - if (len == 6) { + len ++; + + if (len == 5) { + isSynchronized = true; + for (int i=0; i<5; i++) { + if (buffer[i] != syncSeq[i]) { + // this should never happen, but it happens + logger.error(String.format("Bad outgoing sync sequence %x %x %x %x %x", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4])); + isSynchronized = false; + break; + } + } + } + else if (len == 6) { // System.out.println("## CC2420 Packet of length: " + data + " expected..."); - expLen = data + 6; + expMpduLen = data & 0xFF; + if ((expMpduLen & 0x80) != 0) { + logger.error("Outgoing length field is larger than 127: " + expMpduLen); + } } - if (len == expLen) { - /*logger.debug("----- 802.15.4 CUSTOM DATA TRANSMITTED -----");*/ - + if (((expMpduLen & 0x80) == 0) && len == expMpduLen + 6 && isSynchronized) { lastOutgoingPacket = CC2420RadioPacketConverter.fromCC2420ToCooja(buffer); - lastEvent = RadioEvent.PACKET_TRANSMITTED; - /*logger.debug("----- 802.15.4 PACKET TRANSMITTED -----");*/ - setChanged(); - notifyObservers(); - - /*logger.debug("----- 802.15.4 TRANSMISSION FINISHED -----");*/ - isTransmitting = false; - lastEvent = RadioEvent.TRANSMISSION_FINISHED; - setChanged(); - notifyObservers(); - len = 0; + if (lastOutgoingPacket != null) { + lastEvent = RadioEvent.PACKET_TRANSMITTED; + //logger.debug("----- 802.15.4 PACKET TRANSMITTED -----"); + setChanged(); + notifyObservers(); + } + finishTransmission(); } } - }); + }); /* addRFListener */ radio.addOperatingModeListener(new OperatingModeListener() { public void modeChanged(Chip source, int mode) { @@ -148,7 +158,7 @@ public class Msp802154Radio extends Radio implements CustomDataRadio { setChanged(); notifyObservers(); } else { - radioOff(); + radioOff(); // actually it is a state change, not necessarily to OFF } } }); @@ -163,32 +173,23 @@ public class Msp802154Radio extends Radio implements CustomDataRadio { }); } - private void radioOff() { - /* Radio was turned off during transmission. - * May for example happen if watchdog triggers */ + + private void finishTransmission() + { if (isTransmitting()) { - logger.warn("Turning off radio while transmitting, ending packet prematurely"); - - /* Simulate end of packet */ - lastOutgoingPacket = new RadioPacket() { - public byte[] getPacketData() { - return new byte[0]; - } - }; - - lastEvent = RadioEvent.PACKET_TRANSMITTED; - /*logger.debug("----- 802.15.4 PACKET TRANSMITTED -----");*/ - setChanged(); - notifyObservers(); - - /* Register that transmission ended in radio medium */ - /*logger.debug("----- 802.15.4 TRANSMISSION FINISHED -----");*/ + //logger.debug("----- 802.15.4 TRANSMISSION FINISHED -----"); isTransmitting = false; + isSynchronized = false; lastEvent = RadioEvent.TRANSMISSION_FINISHED; setChanged(); notifyObservers(); } + } + private void radioOff() { + if (isSynchronized) + logger.warn("Turning off radio while transmitting a packet"); + finishTransmission(); lastEvent = RadioEvent.HW_OFF; setChanged(); notifyObservers(); @@ -332,7 +333,7 @@ public class Msp802154Radio extends Radio implements CustomDataRadio { } public int getOutputPowerIndicatorMax() { - return 31; + return radio.getOutputPowerIndicatorMax(); } /** diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/MspButton.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/MspButton.java index 5136485e7..459205153 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/MspButton.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/MspButton.java @@ -28,16 +28,9 @@ */ package org.contikios.cooja.mspmote.interfaces; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.Collection; -import javax.swing.JButton; -import javax.swing.JPanel; -import org.jdom.Element; import org.contikios.cooja.ClassDescription; import org.contikios.cooja.Mote; import org.contikios.cooja.Simulation; -import org.contikios.cooja.TimeEvent; import org.contikios.cooja.interfaces.Button; import org.contikios.cooja.mspmote.MspMote; @@ -51,6 +44,7 @@ public class MspButton extends Button { private final se.sics.mspsim.chip.Button button; public MspButton(Mote mote) { + super(mote); final MspMote mspMote = (MspMote) mote; sim = mote.getSimulation(); button = mspMote.getCPU().getChip(se.sics.mspsim.chip.Button.class); @@ -60,26 +54,13 @@ public class MspButton extends Button { } @Override - public void clickButton() { - sim.invokeSimulationThread(new ButtonClick()); + protected void doPressButton() { + button.setPressed(true); } @Override - public void pressButton() { - sim.invokeSimulationThread(new Runnable() { - public void run() { - button.setPressed(true); - } - }); - } - - @Override - public void releaseButton() { - sim.invokeSimulationThread(new Runnable() { - public void run() { - button.setPressed(false); - } - }); + protected void doReleaseButton() { + button.setPressed(false); } @Override @@ -87,50 +68,4 @@ public class MspButton extends Button { return button.isPressed(); } - @Override - public JPanel getInterfaceVisualizer() { - final JPanel panel = new JPanel(); - final JButton clickButton = new JButton("Click button"); - - panel.add(clickButton); - - clickButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - clickButton(); - } - }); - - return panel; - } - - @Override - public void releaseInterfaceVisualizer(JPanel panel) { - } - - @Override - public Collection getConfigXML() { - return null; - } - - @Override - public void setConfigXML(Collection configXML, boolean visAvailable) { - } - - private class ButtonClick extends TimeEvent implements Runnable { - - public ButtonClick() { - super(0); - } - - @Override - public void run() { - button.setPressed(true); - sim.scheduleEvent(this, sim.getSimulationTime() + Simulation.MILLISECOND); - } - - @Override - public void execute(long t) { - button.setPressed(false); - } - } } diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/MspClock.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/MspClock.java index c66352e98..10aacffad 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/MspClock.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/MspClock.java @@ -52,9 +52,11 @@ public class MspClock extends Clock { private Simulation simulation; private long timeDrift; /* Microseconds */ + private double deviation; public MspClock(Mote mote) { simulation = mote.getSimulation(); + deviation = 1.0; } public void setTime(long newTime) { @@ -72,20 +74,13 @@ public class MspClock extends Clock { public long getDrift() { return timeDrift; } - - public JPanel getInterfaceVisualizer() { - /* TODO Show current CPU speed */ - return null; + + public void setDeviation(double deviation) { + assert (deviation>0.0) && (deviation<=1.0); + this.deviation = deviation; } - public void releaseInterfaceVisualizer(JPanel panel) { + public double getDeviation() { + return deviation; } - - public Collection getConfigXML() { - return null; - } - - public void setConfigXML(Collection configXML, boolean visAvailable) { - } - } diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/MspDebugOutput.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/MspDebugOutput.java index 80df3ece4..af72bc63a 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/MspDebugOutput.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/MspDebugOutput.java @@ -40,8 +40,9 @@ import org.jdom.Element; import org.contikios.cooja.ClassDescription; import org.contikios.cooja.Mote; import org.contikios.cooja.interfaces.Log; +import org.contikios.cooja.mote.memory.MemoryInterface; +import org.contikios.cooja.mote.memory.VarMemory; import org.contikios.cooja.mspmote.MspMote; -import org.contikios.cooja.mspmote.MspMoteMemory; import se.sics.mspsim.core.Memory; import se.sics.mspsim.core.MemoryMonitor; @@ -64,24 +65,24 @@ public class MspDebugOutput extends Log { private final static String CONTIKI_POINTER = "cooja_debug_ptr"; private MspMote mote; - private MspMoteMemory mem; + private VarMemory mem; private String lastLog = null; private MemoryMonitor memoryMonitor = null; public MspDebugOutput(Mote mote) { this.mote = (MspMote) mote; - this.mem = (MspMoteMemory) this.mote.getMemory(); + this.mem = new VarMemory(this.mote.getMemory()); if (!mem.variableExists(CONTIKI_POINTER)) { /* Disabled */ return; } - this.mote.getCPU().addWatchPoint(mem.getVariableAddress(CONTIKI_POINTER), + this.mote.getCPU().addWatchPoint((int) mem.getVariableAddress(CONTIKI_POINTER), memoryMonitor = new MemoryMonitor.Adapter() { @Override public void notifyWriteAfter(int adr, int data, Memory.AccessMode mode) { - String msg = extractString(mem, data); + String msg = extractString(MspDebugOutput.this.mote.getMemory(), data); if (msg != null && msg.length() > 0) { lastLog = "DEBUG: " + msg; setChanged(); @@ -91,7 +92,7 @@ public class MspDebugOutput extends Log { }); } - private String extractString(MspMoteMemory mem, int address) { + private String extractString(MemoryInterface mem, int address) { StringBuilder sb = new StringBuilder(); while (true) { byte[] data = mem.getMemorySegment(address, 8); @@ -136,7 +137,7 @@ public class MspDebugOutput extends Log { super.removed(); if (memoryMonitor != null) { - mote.getCPU().removeWatchPoint(mem.getVariableAddress(CONTIKI_POINTER), memoryMonitor); + mote.getCPU().removeWatchPoint((int) mem.getVariableAddress(CONTIKI_POINTER), memoryMonitor); } } } diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/MspMoteID.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/MspMoteID.java index 0c71ca208..a7ced648b 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/MspMoteID.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/MspMoteID.java @@ -39,8 +39,8 @@ import org.apache.log4j.Logger; import org.contikios.cooja.Mote; import org.contikios.cooja.interfaces.MoteID; +import org.contikios.cooja.mote.memory.VarMemory; import org.contikios.cooja.mspmote.MspMote; -import org.contikios.cooja.mspmote.MspMoteMemory; import se.sics.mspsim.core.Memory; import se.sics.mspsim.core.MemoryMonitor; @@ -53,7 +53,7 @@ public class MspMoteID extends MoteID { private static Logger logger = Logger.getLogger(MspMoteID.class); private MspMote mote; - private MspMoteMemory moteMem = null; + private VarMemory moteMem = null; private boolean writeFlashHeader = true; private int moteID = -1; @@ -69,7 +69,7 @@ public class MspMoteID extends MoteID { */ public MspMoteID(Mote m) { this.mote = (MspMote) m; - this.moteMem = (MspMoteMemory) mote.getMemory(); + this.moteMem = new VarMemory(mote.getMemory()); } public int getMoteID() { @@ -144,7 +144,7 @@ public class MspMoteID extends MoteID { byte[] id = new byte[2]; id[0] = (byte) (moteID & 0xff); id[1] = (byte) ((moteID >> 8) & 0xff); - moteMem.setMemorySegment(dstAddress & ~1, id); + mote.getMemory().setMemorySegment(dstAddress & ~1, id); } }; @@ -201,7 +201,7 @@ public class MspMoteID extends MoteID { private void addMonitor(String variable, MemoryMonitor monitor) { if (moteMem.variableExists(variable)) { - int address = moteMem.getVariableAddress(variable); + int address = (int) moteMem.getVariableAddress(variable); if ((address & 1) != 0) { // Variable can not be a word - must be a byte } else { @@ -213,7 +213,7 @@ public class MspMoteID extends MoteID { private void removeMonitor(String variable, MemoryMonitor monitor) { if (moteMem.variableExists(variable)) { - int address = moteMem.getVariableAddress(variable); + int address = (int) moteMem.getVariableAddress(variable); mote.getCPU().removeWatchPoint(address, monitor); mote.getCPU().removeWatchPoint(address + 1, monitor); } diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/SkyButton.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/SkyButton.java index 6b1711b63..faaec655a 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/SkyButton.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/SkyButton.java @@ -30,102 +30,36 @@ package org.contikios.cooja.mspmote.interfaces; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.Collection; - -import javax.swing.JButton; -import javax.swing.JPanel; - import org.apache.log4j.Logger; -import org.jdom.Element; - import org.contikios.cooja.ClassDescription; import org.contikios.cooja.Mote; -import org.contikios.cooja.Simulation; import org.contikios.cooja.interfaces.Button; -import org.contikios.cooja.mspmote.MspMoteTimeEvent; import org.contikios.cooja.mspmote.SkyMote; @ClassDescription("Button") public class SkyButton extends Button { - private static Logger logger = Logger.getLogger(SkyButton.class); + private static final Logger logger = Logger.getLogger(SkyButton.class); + + private final SkyMote skyMote; - private SkyMote skyMote; - private Simulation sim; - - private MspMoteTimeEvent pressButtonEvent; - private MspMoteTimeEvent releaseButtonEvent; - public SkyButton(Mote mote) { + super(mote); skyMote = (SkyMote) mote; - sim = mote.getSimulation(); - - pressButtonEvent = new MspMoteTimeEvent((SkyMote)mote, 0) { - public void execute(long t) { - skyMote.skyNode.setButton(true); - } - }; - releaseButtonEvent = new MspMoteTimeEvent((SkyMote)mote, 0) { - public void execute(long t) { - skyMote.skyNode.setButton(false); - } - }; } - public void clickButton() { - sim.invokeSimulationThread(new Runnable() { - public void run() { - sim.scheduleEvent(pressButtonEvent, sim.getSimulationTime()); - sim.scheduleEvent(releaseButtonEvent, sim.getSimulationTime() + Simulation.MILLISECOND); - } - }); + @Override + protected void doPressButton() { + skyMote.skyNode.getButton().setPressed(true); } - public void pressButton() { - sim.invokeSimulationThread(new Runnable() { - public void run() { - sim.scheduleEvent(pressButtonEvent, sim.getSimulationTime()); - } - }); - } - - public void releaseButton() { - sim.invokeSimulationThread(new Runnable() { - public void run() { - sim.scheduleEvent(releaseButtonEvent, sim.getSimulationTime()); - } - }); + @Override + protected void doReleaseButton() { + skyMote.skyNode.getButton().setPressed(false); } + @Override public boolean isPressed() { - /* Not implemented */ - return false; - } - - public JPanel getInterfaceVisualizer() { - JPanel panel = new JPanel(); - final JButton clickButton = new JButton("Click button"); - - panel.add(clickButton); - - clickButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - clickButton(); - } - }); - - return panel; - } - - public void releaseInterfaceVisualizer(JPanel panel) { - } - - public Collection getConfigXML() { - return null; - } - - public void setConfigXML(Collection configXML, boolean visAvailable) { + return skyMote.skyNode.getButton().isPressed(); } } diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/plugins/MspCodeWatcher.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/plugins/MspCodeWatcher.java index 76f57c326..422c08381 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/plugins/MspCodeWatcher.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/plugins/MspCodeWatcher.java @@ -77,6 +77,7 @@ import org.contikios.cooja.Watchpoint; import org.contikios.cooja.WatchpointMote; import org.contikios.cooja.WatchpointMote.WatchpointListener; import org.contikios.cooja.dialogs.MessageList; +import org.contikios.cooja.dialogs.MessageListUI; import org.contikios.cooja.mspmote.MspMote; import org.contikios.cooja.mspmote.MspMoteType; import se.sics.mspsim.core.EmulationException; @@ -468,7 +469,7 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { } } - private MessageList rulesDebuggingOutput = new MessageList(); + private MessageListUI rulesDebuggingOutput = new MessageListUI(); private boolean rulesWithDebuggingOutput = false; private int[] rulesMatched = null; private int[] rulesOK = null; diff --git a/tools/cooja/apps/powertracker/cooja.config b/tools/cooja/apps/powertracker/cooja.config index 70a4f821c..b59c95ad2 100644 --- a/tools/cooja/apps/powertracker/cooja.config +++ b/tools/cooja/apps/powertracker/cooja.config @@ -1,2 +1,2 @@ -org.contikios.cooja.Cooja.PLUGINS = + PowerTracker -org.contikios.cooja.Cooja.JARFILES = + powertracker.jar +org.contikios.cooja.Cooja.PLUGINS = + PowerTracker +org.contikios.cooja.Cooja.JARFILES = + powertracker.jar diff --git a/tools/cooja/apps/serial_socket/cooja.config b/tools/cooja/apps/serial_socket/cooja.config index 10b86f27f..8c492dc83 100644 --- a/tools/cooja/apps/serial_socket/cooja.config +++ b/tools/cooja/apps/serial_socket/cooja.config @@ -1,2 +1,2 @@ -org.contikios.cooja.Cooja.PLUGINS = + SerialSocketClient SerialSocketServer +org.contikios.cooja.Cooja.PLUGINS = + org.contikios.cooja.serialsocket.SerialSocketClient org.contikios.cooja.serialsocket.SerialSocketServer org.contikios.cooja.Cooja.JARFILES = + serial_socket.jar diff --git a/tools/cooja/apps/serial_socket/java/SerialSocketClient.java b/tools/cooja/apps/serial_socket/java/SerialSocketClient.java deleted file mode 100644 index c3333c0b0..000000000 --- a/tools/cooja/apps/serial_socket/java/SerialSocketClient.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - */ - -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.net.Socket; -import java.util.Collection; -import java.util.Observable; -import java.util.Observer; - -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.SwingUtilities; - -import org.apache.log4j.Logger; -import org.jdom.Element; - -import org.contikios.cooja.ClassDescription; -import org.contikios.cooja.Cooja; -import org.contikios.cooja.Mote; -import org.contikios.cooja.MotePlugin; -import org.contikios.cooja.PluginType; -import org.contikios.cooja.Simulation; -import org.contikios.cooja.VisPlugin; -import org.contikios.cooja.interfaces.SerialPort; - -/** - * Socket to simulated serial port forwarder. Client version. - * - * @author Fredrik Osterlind - */ -@ClassDescription("Serial Socket (CLIENT)") -@PluginType(PluginType.MOTE_PLUGIN) -public class SerialSocketClient extends VisPlugin implements MotePlugin { - private static final long serialVersionUID = 1L; - private static Logger logger = Logger.getLogger(SerialSocketClient.class); - - private final static int LABEL_WIDTH = 100; - private final static int LABEL_HEIGHT = 15; - - public final static String SERVER_HOST = "localhost"; - public final static int SERVER_PORT = 1234; - - private SerialPort serialPort; - private Observer serialDataObserver; - - private JLabel statusLabel, inLabel, outLabel; - private int inBytes = 0, outBytes = 0; - - private Socket socket; - private DataInputStream in; - private DataOutputStream out; - - private Mote mote; - - public SerialSocketClient(Mote mote, Simulation simulation, final Cooja gui) { - super("Serial Socket (CLIENT) (" + mote + ")", gui, false); - this.mote = mote; - - /* GUI components */ - if (Cooja.isVisualized()) { - Box northBox = Box.createHorizontalBox(); - northBox.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - statusLabel = configureLabel(northBox, "", ""); - - Box mainBox = Box.createHorizontalBox(); - mainBox.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5)); - inLabel = configureLabel(mainBox, "socket -> mote:", "0 bytes"); - outLabel = configureLabel(mainBox, "mote -> socket", "0 bytes"); - - getContentPane().add(BorderLayout.NORTH, northBox); - getContentPane().add(BorderLayout.CENTER, mainBox); - pack(); - } - - /* Mote serial port */ - serialPort = (SerialPort) mote.getInterfaces().getLog(); - if (serialPort == null) { - throw new RuntimeException("No mote serial port"); - } - - try { - logger.info("Connecting: " + SERVER_HOST + ":" + SERVER_PORT); - socket = new Socket(SERVER_HOST, SERVER_PORT); - in = new DataInputStream(socket.getInputStream()); - out = new DataOutputStream(socket.getOutputStream()); - out.flush(); - startSocketReadThread(in); - } catch (Exception e) { - throw (RuntimeException) new RuntimeException( - "Connection error: " + e.getMessage()).initCause(e); - } - - /* Observe serial port for outgoing data */ - serialPort.addSerialDataObserver(serialDataObserver = new Observer() { - public void update(Observable obs, Object obj) { - try { - if (out == null) { - return; - } - out.write(serialPort.getLastSerialData()); - out.flush(); - outBytes++; - if (Cooja.isVisualized()) { - outLabel.setText(outBytes + " bytes"); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - }); - } - - private void startSocketReadThread(final DataInputStream in) { - /* Forward data: virtual port -> mote */ - Thread incomingDataThread = new Thread(new Runnable() { - public void run() { - int numRead = 0; - byte[] data = new byte[1024]; - logger.info("Forwarder: socket -> serial port"); - while (true) { - numRead = -1; - try { - numRead = in.read(data); - } catch (IOException e) { - e.printStackTrace(); - return; - } - - if (numRead >= 0) { - for (int i=0; i < numRead; i++) { - serialPort.writeByte(data[i]); - } - inBytes += numRead; - if (Cooja.isVisualized()) { - inLabel.setText(inBytes + " bytes"); - } - } else { - logger.warn("Incoming data thread shut down"); - cleanup(); - break; - } - } - } - }); - incomingDataThread.start(); - } - - private JLabel configureLabel(JComponent pane, String desc, String value) { - JPanel smallPane = new JPanel(new BorderLayout()); - JLabel label = new JLabel(desc); - label.setPreferredSize(new Dimension(LABEL_WIDTH,LABEL_HEIGHT)); - smallPane.add(BorderLayout.WEST, label); - label = new JLabel(value); - label.setPreferredSize(new Dimension(LABEL_WIDTH,LABEL_HEIGHT)); - smallPane.add(BorderLayout.CENTER, label); - pane.add(smallPane); - return label; - } - - public boolean setConfigXML(Collection configXML, boolean visAvailable) { - return true; - } - - public Collection getConfigXML() { - return null; - } - - private void cleanup() { - serialPort.deleteSerialDataObserver(serialDataObserver); - - try { - if (socket != null) { - socket.close(); - socket = null; - } - } catch (IOException e1) { - } - try { - if (in != null) { - in.close(); - in = null; - } - } catch (IOException e) { - } - try { - if (out != null) { - out.close(); - out = null; - } - } catch (IOException e) { - } - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - SerialSocketClient.this.setTitle(SerialSocketClient.this.getTitle() + " *DISCONNECTED*"); - statusLabel.setText("Disconnected from server"); - } - }); - } - - public void closePlugin() { - cleanup(); - } - - public Mote getMote() { - return mote; - } -} - diff --git a/tools/cooja/apps/serial_socket/java/SerialSocketServer.java b/tools/cooja/apps/serial_socket/java/SerialSocketServer.java deleted file mode 100644 index b12197ee0..000000000 --- a/tools/cooja/apps/serial_socket/java/SerialSocketServer.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - */ - -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.Collection; -import java.util.Observable; -import java.util.Observer; - -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.SwingUtilities; -import javax.swing.Timer; - -import org.apache.log4j.Logger; -import org.jdom.Element; - -import org.contikios.cooja.ClassDescription; -import org.contikios.cooja.Cooja; -import org.contikios.cooja.Mote; -import org.contikios.cooja.MotePlugin; -import org.contikios.cooja.PluginType; -import org.contikios.cooja.Simulation; -import org.contikios.cooja.VisPlugin; -import org.contikios.cooja.interfaces.SerialPort; - -/** - * Socket to simulated serial port forwarder. Server version. - * - * @author Fredrik Osterlind - */ -@ClassDescription("Serial Socket (SERVER)") -@PluginType(PluginType.MOTE_PLUGIN) -public class SerialSocketServer extends VisPlugin implements MotePlugin { - private static final long serialVersionUID = 1L; - private static Logger logger = Logger.getLogger(SerialSocketServer.class); - - private final static int LABEL_WIDTH = 100; - private final static int LABEL_HEIGHT = 15; - - public final int LISTEN_PORT; - - private SerialPort serialPort; - private Observer serialDataObserver; - - private JLabel statusLabel, inLabel, outLabel; - private int inBytes = 0, outBytes = 0; - - private ServerSocket server; - private Socket client; - private DataInputStream in; - private DataOutputStream out; - - private Mote mote; - - public SerialSocketServer(Mote mote, Simulation simulation, final Cooja gui) { - super("Serial Socket (SERVER) (" + mote + ")", gui, false); - this.mote = mote; - - updateTimer.start(); - - LISTEN_PORT = 60000 + mote.getID(); - - /* GUI components */ - if (Cooja.isVisualized()) { - Box northBox = Box.createHorizontalBox(); - northBox.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - statusLabel = configureLabel(northBox, "", ""); - - Box mainBox = Box.createHorizontalBox(); - mainBox.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5)); - inLabel = configureLabel(mainBox, "socket -> mote:", "0 bytes"); - outLabel = configureLabel(mainBox, "mote -> socket", "0 bytes"); - - getContentPane().add(BorderLayout.NORTH, northBox); - getContentPane().add(BorderLayout.CENTER, mainBox); - pack(); - } - - /* Mote serial port */ - serialPort = (SerialPort) mote.getInterfaces().getLog(); - if (serialPort == null) { - throw new RuntimeException("No mote serial port"); - } - - try { - logger.info("Listening on port: " + LISTEN_PORT); - if (Cooja.isVisualized()) { - statusLabel.setText("Listening on port: " + LISTEN_PORT); - } - server = new ServerSocket(LISTEN_PORT); - new Thread() { - public void run() { - while (server != null) { - try { - client = server.accept(); - in = new DataInputStream(client.getInputStream()); - out = new DataOutputStream(client.getOutputStream()); - out.flush(); - - startSocketReadThread(in); - if (Cooja.isVisualized()) { - statusLabel.setText("Client connected: " + client.getInetAddress()); - } - } catch (IOException e) { - logger.fatal("Listening thread shut down: " + e.getMessage()); - server = null; - cleanupClient(); - break; - } - } - } - }.start(); - } catch (Exception e) { - throw (RuntimeException) new RuntimeException( - "Connection error: " + e.getMessage()).initCause(e); - } - - /* Observe serial port for outgoing data */ - serialPort.addSerialDataObserver(serialDataObserver = new Observer() { - public void update(Observable obs, Object obj) { - try { - if (out == null) { - /*logger.debug("out is null");*/ - return; - } - - out.write(serialPort.getLastSerialData()); - out.flush(); - - outBytes++; - } catch (IOException e) { - cleanupClient(); - } - } - }); - } - - private void startSocketReadThread(final DataInputStream in) { - /* Forward data: virtual port -> mote */ - Thread incomingDataThread = new Thread(new Runnable() { - public void run() { - int numRead = 0; - byte[] data = new byte[1024]; - logger.info("Forwarder: socket -> serial port"); - while (true) { - numRead = -1; - try { - numRead = in.read(data); - } catch (IOException e) { - numRead = -1; - } - - if (numRead >= 0) { - for (int i=0; i < numRead; i++) { - serialPort.writeByte(data[i]); - } - - inBytes += numRead; - } else { - cleanupClient(); - break; - } - } - } - }); - incomingDataThread.start(); - } - - private JLabel configureLabel(JComponent pane, String desc, String value) { - JPanel smallPane = new JPanel(new BorderLayout()); - JLabel label = new JLabel(desc); - label.setPreferredSize(new Dimension(LABEL_WIDTH,LABEL_HEIGHT)); - smallPane.add(BorderLayout.WEST, label); - label = new JLabel(value); - label.setPreferredSize(new Dimension(LABEL_WIDTH,LABEL_HEIGHT)); - smallPane.add(BorderLayout.CENTER, label); - pane.add(smallPane); - return label; - } - - public boolean setConfigXML(Collection configXML, boolean visAvailable) { - return true; - } - - public Collection getConfigXML() { - return null; - } - - private void cleanupClient() { - try { - if (client != null) { - client.close(); - client = null; - } - } catch (IOException e1) { - } - try { - if (in != null) { - in.close(); - in = null; - } - } catch (IOException e) { - } - try { - if (out != null) { - out.close(); - out = null; - } - } catch (IOException e) { - } - - if (Cooja.isVisualized()) { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - statusLabel.setText("Listening on port: " + LISTEN_PORT); - } - }); - } - } - - private boolean closed = false; - public void closePlugin() { - closed = true; - cleanupClient(); - serialPort.deleteSerialDataObserver(serialDataObserver); - try { - server.close(); - } catch (IOException e) { - } - } - - public Mote getMote() { - return mote; - } - - private static final int UPDATE_INTERVAL = 150; - private Timer updateTimer = new Timer(UPDATE_INTERVAL, new ActionListener() { - public void actionPerformed(ActionEvent e) { - if (closed) { - updateTimer.stop(); - return; - } - - inLabel.setText(inBytes + " bytes"); - outLabel.setText(outBytes + " bytes"); - } - }); -} - diff --git a/tools/cooja/apps/serial_socket/java/org/contikios/cooja/serialsocket/SerialSocketClient.java b/tools/cooja/apps/serial_socket/java/org/contikios/cooja/serialsocket/SerialSocketClient.java new file mode 100644 index 000000000..df8a7dc22 --- /dev/null +++ b/tools/cooja/apps/serial_socket/java/org/contikios/cooja/serialsocket/SerialSocketClient.java @@ -0,0 +1,569 @@ +package org.contikios.cooja.serialsocket; + +/* + * Copyright (c) 2014, TU Braunschweig. + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.Socket; +import java.text.NumberFormat; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.Observable; +import java.util.Observer; +import java.util.logging.Level; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JFormattedTextField; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; +import javax.swing.border.EtchedBorder; +import javax.swing.text.NumberFormatter; + +import org.apache.log4j.Logger; +import org.jdom.Element; + +import org.contikios.cooja.ClassDescription; +import org.contikios.cooja.Cooja; +import org.contikios.cooja.Mote; +import org.contikios.cooja.MotePlugin; +import org.contikios.cooja.PluginType; +import org.contikios.cooja.Simulation; +import org.contikios.cooja.VisPlugin; +import org.contikios.cooja.interfaces.SerialPort; + +/** + * Socket to simulated serial port forwarder. Client version. + * + * @author Fredrik Osterlind + * @author Enrico Jorns + */ +@ClassDescription("Serial Socket (CLIENT)") +@PluginType(PluginType.MOTE_PLUGIN) +public class SerialSocketClient extends VisPlugin implements MotePlugin { + private static final long serialVersionUID = 1L; + private static final Logger logger = Logger.getLogger(SerialSocketClient.class); + + private static final String SERVER_DEFAULT_HOST = "localhost"; + private static final int SERVER_DEFAULT_PORT = 1234; + + private final static int STATUSBAR_WIDTH = 350; + + private static final Color ST_COLOR_UNCONNECTED = Color.DARK_GRAY; + private static final Color ST_COLOR_CONNECTED = new Color(0, 161, 83); + private static final Color ST_COLOR_FAILED = Color.RED; + + private SerialPort serialPort; + private Observer serialDataObserver; + + private JLabel socketToMoteLabel; + private JLabel moteToSocketLabel; + private JLabel socketStatusLabel; + private JTextField serverHostField; + private JFormattedTextField serverPortField; + private JButton serverSelectButton; + + private int inBytes = 0, outBytes = 0; + + private Socket socket; + private DataInputStream in; + private DataOutputStream out; + + private final Mote mote; + private final Simulation simulation; + + public SerialSocketClient(Mote mote, Simulation simulation, final Cooja gui) { + super("Serial Socket (CLIENT) (" + mote + ")", gui, false); + this.mote = mote; + this.simulation = simulation; + + /* GUI components */ + if (Cooja.isVisualized()) { + + setResizable(false); + setLayout(new BorderLayout()); + + // --- Server setup + + GridBagConstraints c = new GridBagConstraints(); + JPanel serverSelectPanel = new JPanel(new GridBagLayout()); + serverSelectPanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); + + JLabel label = new JLabel("Host:"); + c.gridx = 0; + c.gridy = 0; + c.gridx++; + serverSelectPanel.add(label, c); + + serverHostField = new JTextField(SERVER_DEFAULT_HOST); + serverHostField.setColumns(10); + c.gridx++; + c.weightx = 1.0; + serverSelectPanel.add(serverHostField, c); + + label = new JLabel("Port:"); + c.gridx++; + c.weightx = 0.0; + serverSelectPanel.add(label, c); + + NumberFormat nf = NumberFormat.getIntegerInstance(); + nf.setGroupingUsed(false); + serverPortField = new JFormattedTextField(new NumberFormatter(nf)); + serverPortField.setColumns(5); + serverPortField.setText(String.valueOf(SERVER_DEFAULT_PORT)); + c.gridx++; + serverSelectPanel.add(serverPortField, c); + + serverSelectButton = new JButton("Connect") { // Button for label toggeling + private final String altString = "Disconnect"; + + @Override + public Dimension getPreferredSize() { + String origText = getText(); + Dimension origDim = super.getPreferredSize(); + setText(altString); + Dimension altDim = super.getPreferredSize(); + setText(origText); + return new Dimension(Math.max(origDim.width, altDim.width), origDim.height); + } + }; + c.gridx++; + c.weightx = 0.1; + c.anchor = GridBagConstraints.EAST; + serverSelectPanel.add(serverSelectButton, c); + + c.gridx = 0; + c.gridy++; + c.gridwidth = GridBagConstraints.REMAINDER; + c.fill = GridBagConstraints.HORIZONTAL; + serverSelectPanel.add(new JSeparator(JSeparator.HORIZONTAL), c); + + add(BorderLayout.NORTH, serverSelectPanel); + + // --- Incoming / outgoing info + + JPanel connectionInfoPanel = new JPanel(new GridLayout(0, 2)); + connectionInfoPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + c = new GridBagConstraints(); + + label = new JLabel("socket -> mote: "); + label.setHorizontalAlignment(JLabel.RIGHT); + c.gridx = 0; + c.gridy = 0; + c.anchor = GridBagConstraints.EAST; + connectionInfoPanel.add(label); + + socketToMoteLabel = new JLabel("0 bytes"); + c.gridx++; + c.anchor = GridBagConstraints.WEST; + connectionInfoPanel.add(socketToMoteLabel); + + label = new JLabel("mote -> socket: "); + label.setHorizontalAlignment(JLabel.RIGHT); + c.gridx = 0; + c.gridy++; + c.anchor = GridBagConstraints.EAST; + connectionInfoPanel.add(label); + + moteToSocketLabel = new JLabel("0 bytes"); + c.gridx++; + c.anchor = GridBagConstraints.WEST; + connectionInfoPanel.add(moteToSocketLabel); + + add(BorderLayout.CENTER, connectionInfoPanel); + + // --- Status bar + + JPanel statusBarPanel = new JPanel(new BorderLayout()) { + @Override + public Dimension getPreferredSize() { + Dimension d = super.getPreferredSize(); + return new Dimension(STATUSBAR_WIDTH, d.height); + } + }; + statusBarPanel.setLayout(new BoxLayout(statusBarPanel, BoxLayout.LINE_AXIS)); + statusBarPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED)); + label = new JLabel("Status: "); + statusBarPanel.add(label); + + socketStatusLabel = new JLabel("Disconnected"); + socketStatusLabel.setForeground(Color.DARK_GRAY); + statusBarPanel.add(socketStatusLabel); + + add(BorderLayout.SOUTH, statusBarPanel); + + /* Mote serial port */ + serialPort = (SerialPort) mote.getInterfaces().getLog(); + if (serialPort == null) { + throw new RuntimeException("No mote serial port"); + } + + serverSelectButton.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("Connect")) { + try { + serverPortField.commitEdit(); + startClient(serverHostField.getText(), ((Long) serverPortField.getValue()).intValue()); + } catch (ParseException ex) { + logger.error(ex); + } + } else { + // close socket + cleanup(); + } + } + }); + + + /* Observe serial port for outgoing data and write to socket */ + serialPort.addSerialDataObserver(serialDataObserver = new Observer() { + @Override + public void update(Observable obs, Object obj) { + try { + if (out == null) { + return; + } + out.write(serialPort.getLastSerialData()); + out.flush(); + outBytes++; + if (Cooja.isVisualized()) { + moteToSocketLabel.setText(outBytes + " bytes"); + } + } catch (IOException ex) { + logger.error(ex.getMessage()); + socketStatusLabel.setText("failed"); + socketStatusLabel.setForeground(ST_COLOR_FAILED); + } + } + }); + } + + if (Cooja.isVisualized()) { + addClientListener(new ClientListener() { + + @Override + public void onError(final String msg) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + socketStatusLabel.setForeground(ST_COLOR_FAILED); + socketStatusLabel.setText(msg); + } + }); + } + + @Override + public void onConnected() { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + socketStatusLabel.setText("Connected"); + socketStatusLabel.setForeground(ST_COLOR_CONNECTED); + serverHostField.setEnabled(false); + serverPortField.setEnabled(false); + serverSelectButton.setText("Disconnect"); + } + }); + } + + @Override + public void onDisconnected() { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + socketStatusLabel.setForeground(ST_COLOR_UNCONNECTED); + socketStatusLabel.setText("Disconnected"); + serverHostField.setEnabled(true); + serverPortField.setEnabled(true); + serverSelectButton.setText("Connect"); + } + }); + } + }); + } + pack(); + } + + private List listeners = new LinkedList<>(); + + public interface ClientListener { + void onError(String msg); + void onConnected(); + void onDisconnected(); + } + + public void addClientListener(ClientListener listener) { + if (!listeners.contains(listener)) { + listeners.add(listener); + } + } + + private void notifyClientError(String msg) { + for (ClientListener l : listeners) { + l.onError(msg); + } + } + + private void notifyClientConnected() { + for (ClientListener l : listeners) { + l.onConnected(); + } + } + + private void notifyClientDisconnected() { + for (ClientListener l : listeners) { + l.onDisconnected(); + } + } + + + public void startClient(String host, int port) { + if (socket == null) { + // connect to serer + try { + logger.info("Connecting: " + host + ":" + port); + socket = new Socket(host, port); + in = new DataInputStream(socket.getInputStream()); + out = new DataOutputStream(socket.getOutputStream()); + out.flush(); + startSocketReadThread(in); + notifyClientConnected(); + } catch (IOException ex) { + logger.error(ex.getMessage()); + notifyClientError(ex.getMessage()); + } + } else { + // disconnect from server + try { + logger.info("Closing connection to serer..."); + socket.close(); + notifyClientDisconnected(); + } catch (IOException ex) { + logger.error(ex); + notifyClientError(ex.getMessage()); + } finally { + socket = null; + } + } + + } + + private void startSocketReadThread(final DataInputStream in) { + /* Forward data: virtual port -> mote */ + Thread incomingDataThread = new Thread(new Runnable() { + @Override + public void run() { + int numRead = 0; + byte[] data = new byte[1024]; + logger.info("Start forwarding: socket -> serial port"); + while (numRead >= 0) { + try { + numRead = in.read(data); + } catch (IOException e) { + logger.info(e.getMessage()); + numRead = -1; + continue; + } + + if (numRead >= 0) { + final int finalNumRead = numRead; + final byte[] finalData = data; + /* We are not on the simulation thread */ + simulation.invokeSimulationThread(new Runnable() { + + @Override + public void run() { + for (int i = 0; i < finalNumRead; i++) { + serialPort.writeByte(finalData[i]); + } + } + }); + + inBytes += numRead; + if (Cooja.isVisualized()) { + socketToMoteLabel.setText(inBytes + " bytes"); + } + } + } + + logger.info("Incoming data thread shut down"); + cleanup(); + notifyClientDisconnected(); + } + }); + incomingDataThread.start(); + } + + @Override + public Collection getConfigXML() { + List config = new ArrayList<>(); + Element element; + + // XXX isVisualized guards? + element = new Element("host"); + if (socket == null || !socket.isBound()) { + element.setText(serverHostField.getText()); + } else { + element.setText(socket.getInetAddress().getHostName()); + } + config.add(element); + + element = new Element("port"); + if (socket == null || !socket.isBound()) { + try { + serverPortField.commitEdit(); + element.setText(String.valueOf((Long) serverPortField.getValue())); + } catch (ParseException ex) { + logger.error(ex.getMessage()); + serverPortField.setText("null"); + } + } else { + element.setText(String.valueOf(socket.getPort())); + } + config.add(element); + + element = new Element("bound"); + if (socket == null) { + element.setText(String.valueOf(false)); + } else { + element.setText(String.valueOf(socket.isBound())); + } + config.add(element); + + return config; + } + + @Override + public boolean setConfigXML(Collection configXML, boolean visAvailable) { + String host = null; + Integer port = null; + boolean bound = false; + + for (Element element : configXML) { + switch (element.getName()) { + case "host": + host = element.getText(); + break; + case "port": + port = Integer.parseInt(element.getText()); + break; + case "bound": + bound = Boolean.parseBoolean(element.getText()); + break; + default: + logger.warn("Unknwon config element: " + element.getName()); + break; + } + } + + // XXX binding might fail if server not configured yet + if (Cooja.isVisualized()) { + if (host != null) { + serverHostField.setText(host); + } + if (port != null) { + serverPortField.setText(String.valueOf(port)); + } + if (bound) { + serverSelectButton.doClick(); + } + } else { + // if bound and all set up, start client + if (host != null && port != null) { + startClient(host, port); + } else { + logger.error("Client not started due to incomplete configuration"); + } + } + + return true; + } + + + private void cleanup() { + serialPort.deleteSerialDataObserver(serialDataObserver); + + try { + if (socket != null) { + socket.close(); + socket = null; + } + } catch (IOException e1) { + logger.warn(e1.getMessage()); + } + try { + if (in != null) { + in.close(); + in = null; + } + } catch (IOException e) { + logger.warn(e.getMessage()); + } + try { + if (out != null) { + out.close(); + out = null; + } + } catch (IOException e) { + logger.warn(e.getMessage()); + } + } + + @Override + public void closePlugin() { + cleanup(); + } + + @Override + public Mote getMote() { + return mote; + } +} + diff --git a/tools/cooja/apps/serial_socket/java/org/contikios/cooja/serialsocket/SerialSocketServer.java b/tools/cooja/apps/serial_socket/java/org/contikios/cooja/serialsocket/SerialSocketServer.java new file mode 100644 index 000000000..e73eac513 --- /dev/null +++ b/tools/cooja/apps/serial_socket/java/org/contikios/cooja/serialsocket/SerialSocketServer.java @@ -0,0 +1,659 @@ +package org.contikios.cooja.serialsocket; + +/* + * Copyright (c) 2014, TU Braunschweig. + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.text.NumberFormat; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.Observable; +import java.util.Observer; +import java.util.logging.Level; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JFormattedTextField; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.SwingUtilities; +import javax.swing.Timer; +import javax.swing.border.EtchedBorder; +import javax.swing.text.NumberFormatter; + +import org.apache.log4j.Logger; +import org.jdom.Element; + +import org.contikios.cooja.ClassDescription; +import org.contikios.cooja.Cooja; +import org.contikios.cooja.Mote; +import org.contikios.cooja.MotePlugin; +import org.contikios.cooja.PluginType; +import org.contikios.cooja.Simulation; +import org.contikios.cooja.VisPlugin; +import org.contikios.cooja.interfaces.SerialPort; + +/** + * Socket to simulated serial port forwarder. Server version. + * + * @author Fredrik Osterlind + * @author Enrico Jorns + */ +@ClassDescription("Serial Socket (SERVER)") +@PluginType(PluginType.MOTE_PLUGIN) +public class SerialSocketServer extends VisPlugin implements MotePlugin { + private static final long serialVersionUID = 1L; + private static final Logger logger = Logger.getLogger(SerialSocketServer.class); + + private final static int STATUSBAR_WIDTH = 350; + + private static final Color COLOR_NEUTRAL = Color.DARK_GRAY; + private static final Color COLOR_POSITIVE = new Color(0, 161, 83); + private static final Color COLOR_NEGATIVE = Color.RED; + + private final int SERVER_DEFAULT_PORT; + + private final SerialPort serialPort; + private Observer serialDataObserver; + + private JLabel socketToMoteLabel; + private JLabel moteToSocketLabel; + private JLabel socketStatusLabel; + private JFormattedTextField listenPortField; + private JButton serverStartButton; + + private int inBytes = 0, outBytes = 0; + + private ServerSocket serverSocket; + private Socket clientSocket; + + private Mote mote; + private Simulation simulation; + + public SerialSocketServer(Mote mote, Simulation simulation, final Cooja gui) { + super("Serial Socket (SERVER) (" + mote + ")", gui, false); + this.mote = mote; + this.simulation = simulation; + + updateTimer.start(); + + SERVER_DEFAULT_PORT = 60000 + mote.getID(); + + /* GUI components */ + if (Cooja.isVisualized()) { + + setResizable(false); + setLayout(new BorderLayout()); + + // --- Server Port setup + + GridBagConstraints c = new GridBagConstraints(); + JPanel socketPanel = new JPanel(new GridBagLayout()); + socketPanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); + + JLabel label = new JLabel("Listen port: "); + c.gridx = 0; + c.gridy = 0; + c.weightx = 0.1; + c.anchor = GridBagConstraints.EAST; + socketPanel.add(label, c); + + NumberFormat nf = NumberFormat.getIntegerInstance(); + nf.setGroupingUsed(false); + listenPortField = new JFormattedTextField(new NumberFormatter(nf)); + listenPortField.setColumns(5); + listenPortField.setText(String.valueOf(SERVER_DEFAULT_PORT)); + c.gridx++; + c.weightx = 0.0; + socketPanel.add(listenPortField, c); + + serverStartButton = new JButton("Start") { // Button for label toggeling + private final String altString = "Stop"; + + @Override + public Dimension getPreferredSize() { + String origText = getText(); + Dimension origDim = super.getPreferredSize(); + setText(altString); + Dimension altDim = super.getPreferredSize(); + setText(origText); + return new Dimension(Math.max(origDim.width, altDim.width), origDim.height); + } + }; + c.gridx++; + c.weightx = 0.1; + c.anchor = GridBagConstraints.EAST; + socketPanel.add(serverStartButton, c); + + c.gridx = 0; + c.gridy++; + c.gridwidth = GridBagConstraints.REMAINDER; + c.fill = GridBagConstraints.HORIZONTAL; + socketPanel.add(new JSeparator(JSeparator.HORIZONTAL), c); + + add(BorderLayout.NORTH, socketPanel); + + // --- Incoming / outgoing info + + JPanel connectionInfoPanel = new JPanel(new GridLayout(0, 2)); + connectionInfoPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + c = new GridBagConstraints(); + + label = new JLabel("socket -> mote: "); + label.setHorizontalAlignment(JLabel.RIGHT); + c.gridx = 0; + c.gridy = 0; + c.anchor = GridBagConstraints.EAST; + connectionInfoPanel.add(label); + + socketToMoteLabel = new JLabel("0 bytes"); + c.gridx++; + c.anchor = GridBagConstraints.WEST; + connectionInfoPanel.add(socketToMoteLabel); + + label = new JLabel("mote -> socket: "); + label.setHorizontalAlignment(JLabel.RIGHT); + c.gridx = 0; + c.gridy++; + c.anchor = GridBagConstraints.EAST; + connectionInfoPanel.add(label); + + moteToSocketLabel = new JLabel("0 bytes"); + c.gridx++; + c.anchor = GridBagConstraints.WEST; + connectionInfoPanel.add(moteToSocketLabel); + + add(BorderLayout.CENTER, connectionInfoPanel); + + // --- Status bar + + JPanel statusBarPanel = new JPanel(new BorderLayout()) { + @Override + public Dimension getPreferredSize() { + Dimension d = super.getPreferredSize(); + return new Dimension(STATUSBAR_WIDTH, d.height); + } + }; + statusBarPanel.setLayout(new BoxLayout(statusBarPanel, BoxLayout.LINE_AXIS)); + statusBarPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED)); + label = new JLabel("Status: "); + statusBarPanel.add(label); + + socketStatusLabel = new JLabel("Idle"); + socketStatusLabel.setForeground(Color.DARK_GRAY); + statusBarPanel.add(socketStatusLabel); + + add(BorderLayout.SOUTH, statusBarPanel); + + serverStartButton.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("Start")) { + try { + listenPortField.commitEdit(); + } catch (ParseException ex) { + java.util.logging.Logger.getLogger(SerialSocketClient.class.getName()).log(Level.SEVERE, null, ex); + } + startServer(((Long) listenPortField.getValue()).intValue()); + } else { + stopServer(); + } + } + }); + + pack(); + } + + /* Mote serial port */ + serialPort = (SerialPort) mote.getInterfaces().getLog(); + if (serialPort == null) { + throw new RuntimeException("No mote serial port"); + } + + if (Cooja.isVisualized()) { + // gui updates for server status updates + addServerListener(new ServerListener() { + + @Override + public void onServerStarted(final int port) { + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + System.out.println("onServerStarted"); + socketStatusLabel.setForeground(COLOR_NEUTRAL); + socketStatusLabel.setText("Listening on port " + String.valueOf(port)); + listenPortField.setEnabled(false); + serverStartButton.setText("Stop"); + } + }); + } + + @Override + public void onClientConnected(final Socket client) { + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + socketStatusLabel.setForeground(COLOR_POSITIVE); + socketStatusLabel.setText("Client " + + client.getInetAddress() + ":" + client.getPort() + + " connected."); + } + }); + } + + @Override + public void onClientDisconnected() { + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + // XXX check why needed + if (serverSocket != null) { + socketStatusLabel.setForeground(COLOR_NEUTRAL); + socketStatusLabel.setText("Listening on port " + String.valueOf(serverSocket.getLocalPort())); + } + } + }); + } + + @Override + public void onServerStopped() { + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + listenPortField.setEnabled(true); + serverStartButton.setText("Start"); + socketStatusLabel.setForeground(COLOR_NEUTRAL); + socketStatusLabel.setText("Idle"); + } + }); + } + + @Override + public void onServerError(final String msg) { + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + socketStatusLabel.setForeground(COLOR_NEGATIVE); + socketStatusLabel.setText(msg); + } + }); + } + + }); + } + + } + + private List listeners = new LinkedList<>(); + + public interface ServerListener { + void onServerStarted(int port); + void onClientConnected(Socket client); + void onClientDisconnected(); + void onServerStopped(); + void onServerError(String msg); + } + + private void addServerListener(ServerListener listener) { + listeners.add(listener); + } + + public void notifyServerStarted(int port) { + for (ServerListener listener : listeners) { + listener.onServerStarted(port); + } + } + + public void notifyClientConnected(Socket client) { + for (ServerListener listener : listeners) { + listener.onClientConnected(client); + } + } + + public void notifyClientDisconnected() { + for (ServerListener listener : listeners) { + listener.onClientDisconnected(); + } + } + + public void notifyServerStopped() { + for (ServerListener listener : listeners) { + listener.onServerStopped(); + } + } + + public void notifyServerError(String msg) { + for (ServerListener listener : listeners) { + listener.onServerError(msg); + } + } + + /** + * Start server .. + * @param port + */ + public void startServer(int port) { + try { + serverSocket = new ServerSocket(port); + logger.info("Listening on port: " + port); + notifyServerStarted(port); + } catch (IOException ex) { + logger.error(ex.getMessage()); + notifyServerError(ex.getMessage()); + return; + } + + new Thread() { + private Thread incomingDataHandler; + @Override + public void run() { + while (!serverSocket.isClosed()) { + try { + // wait for next client + Socket candidateSocket = serverSocket.accept(); + + // reject connection if already one client connected + if (clientSocket != null && !clientSocket.isClosed()) { + logger.info("Refused connection of client " + candidateSocket.getInetAddress()); + candidateSocket.close(); + continue; + } + + clientSocket = candidateSocket; + + /* Start handler for data input from socket */ + incomingDataHandler = new Thread(new IncomingDataHandler()); + incomingDataHandler.start(); + + /* Observe serial port for outgoing data */ + serialDataObserver = new SerialDataObserver(); + serialPort.addSerialDataObserver(serialDataObserver); + + inBytes = outBytes = 0; + + logger.info("Client connected: " + clientSocket.getInetAddress()); + notifyClientConnected(clientSocket); + + } catch (IOException e) { + logger.info("Listening thread shut down: " + e.getMessage()); + try { + serverSocket.close(); + } catch (IOException ex) { + logger.error(ex); + } + } + } + cleanupClient(); + if (incomingDataHandler != null) { + // Wait for reader thread to terminate + try { + incomingDataHandler.join(500); + } catch (InterruptedException ex) { + logger.warn(ex); + } + } + notifyServerStopped(); + } + }.start(); + } + + /** + * Stops server by closing server listen socket. + */ + public void stopServer() { + try { + serverSocket.close(); + } catch (IOException ex) { + logger.error(ex); + } + } + + /* Forward data: virtual port -> mote */ + private class IncomingDataHandler implements Runnable { + + DataInputStream in; + + @Override + public void run() { + int numRead = 0; + byte[] data = new byte[1024]; + try { + in = new DataInputStream(clientSocket.getInputStream()); + } catch (IOException ex) { + logger.error(ex); + return; + } + + logger.info("Forwarder: socket -> serial port"); + while (numRead >= 0) { + final int finalNumRead = numRead; + final byte[] finalData = data; + /* We are not on the simulation thread */ + simulation.invokeSimulationThread(new Runnable() { + + @Override + public void run() { + for (int i = 0; i < finalNumRead; i++) { + serialPort.writeByte(finalData[i]); + } + inBytes += finalNumRead; + } + }); + + try { + numRead = in.read(data); + } catch (IOException e) { + logger.info(e.getMessage()); + numRead = -1; + } + } + logger.info("End of Stream"); + cleanupClient(); + } + } + + private class SerialDataObserver implements Observer { + + DataOutputStream out; + + public SerialDataObserver() { + try { + out = new DataOutputStream(clientSocket.getOutputStream()); + } catch (IOException ex) { + logger.error(ex); + out = null; + } + } + + @Override + public void update(Observable obs, Object obj) { + try { + if (out == null) { + /*logger.debug("out is null");*/ + return; + } + + out.write(serialPort.getLastSerialData()); + out.flush(); + + outBytes++; + } catch (IOException ex) { + logger.error(ex); + cleanupClient(); + } + } + + } + + @Override + public Collection getConfigXML() { + List config = new ArrayList<>(); + Element element; + + // XXX isVisualized guards? + + element = new Element("port"); + if (serverSocket == null || !serverSocket.isBound()) { + try { + listenPortField.commitEdit(); + element.setText(String.valueOf((Long) listenPortField.getValue())); + } catch (ParseException ex) { + logger.error(ex.getMessage()); + listenPortField.setText("null"); + } + } else { + element.setText(String.valueOf(serverSocket.getLocalPort())); + } + config.add(element); + + element = new Element("bound"); + if (serverSocket == null) { + element.setText(String.valueOf(false)); + } else { + element.setText(String.valueOf(!serverSocket.isClosed())); + } + config.add(element); + + return config; + } + + @Override + public boolean setConfigXML(Collection configXML, boolean visAvailable) { + Integer port = null; + boolean bound = false; + + for (Element element : configXML) { + switch (element.getName()) { + case "port": + port = Integer.parseInt(element.getText()); + break; + case "bound": + bound = Boolean.parseBoolean(element.getText()); + break; + default: + logger.warn("Unknwon config element: " + element.getName()); + break; + } + } + if (Cooja.isVisualized()) { + if (port != null) { + listenPortField.setText(String.valueOf(port)); + } + if (bound) { + serverStartButton.doClick(); + } + } else { + // if bound and all set up, start client + if (port != null) { + startServer(port); + } else { + logger.error("Server not started due to incomplete configuration"); + } + } + + return true; + } + + private void cleanupClient() { + try { + if (clientSocket != null) { + clientSocket.close(); + clientSocket = null; + } + } catch (IOException e1) { + logger.error(e1.getMessage()); + } + + serialPort.deleteSerialDataObserver(serialDataObserver); + + notifyClientDisconnected(); + } + + private boolean closed = false; + + @Override + public void closePlugin() { + closed = true; + cleanupClient(); + try { + if (serverSocket != null) { + serverSocket.close(); + } + } catch (IOException ex) { + logger.error(ex); + } + } + + @Override + public Mote getMote() { + return mote; + } + + private static final int UPDATE_INTERVAL = 150; + private Timer updateTimer = new Timer(UPDATE_INTERVAL, new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (Cooja.isVisualized()) { + if (closed) { + updateTimer.stop(); + return; + } + + socketToMoteLabel.setText(inBytes + " bytes"); + moteToSocketLabel.setText(outBytes + " bytes"); + } + } + }); +} + diff --git a/tools/cooja/build.xml b/tools/cooja/build.xml index f9468a4df..38c3feb33 100644 --- a/tools/cooja/build.xml +++ b/tools/cooja/build.xml @@ -51,6 +51,7 @@ The COOJA Simulator + @@ -64,6 +65,7 @@ The COOJA Simulator + @@ -78,6 +80,7 @@ The COOJA Simulator + @@ -110,6 +113,7 @@ The COOJA Simulator + @@ -125,6 +129,7 @@ The COOJA Simulator + @@ -139,6 +144,7 @@ The COOJA Simulator + @@ -153,6 +159,7 @@ The COOJA Simulator + @@ -166,6 +173,7 @@ The COOJA Simulator + @@ -181,6 +189,7 @@ The COOJA Simulator + @@ -227,7 +236,7 @@ The COOJA Simulator - + diff --git a/tools/cooja/config/cooja.html b/tools/cooja/config/cooja.html index b2f44de6f..d51ffc847 100644 --- a/tools/cooja/config/cooja.html +++ b/tools/cooja/config/cooja.html @@ -1,12 +1,12 @@ - - The COOJA Simulator (applet) - - - - - - - - + + The COOJA Simulator (applet) + + + + + + + + diff --git a/tools/cooja/config/cooja.policy b/tools/cooja/config/cooja.policy index 2fd15c8dd..53a9d407d 100644 --- a/tools/cooja/config/cooja.policy +++ b/tools/cooja/config/cooja.policy @@ -1,3 +1,3 @@ -grant { -permission java.security.AllPermission; -}; +grant { +permission java.security.AllPermission; +}; diff --git a/tools/cooja/config/cooja_default.config b/tools/cooja/config/cooja_default.config index b28337631..212f48003 100644 --- a/tools/cooja/config/cooja_default.config +++ b/tools/cooja/config/cooja_default.config @@ -1,10 +1,9 @@ org.contikios.cooja.contikimote.interfaces.ContikiRadio.RADIO_TRANSMISSION_RATE_kbps = 250 -org.contikios.cooja.contikimote.ContikiMoteType.MOTE_INTERFACES = org.contikios.cooja.interfaces.Position org.contikios.cooja.interfaces.Battery org.contikios.cooja.contikimote.interfaces.ContikiVib org.contikios.cooja.contikimote.interfaces.ContikiMoteID org.contikios.cooja.contikimote.interfaces.ContikiRS232 org.contikios.cooja.contikimote.interfaces.ContikiBeeper org.contikios.cooja.interfaces.RimeAddress org.contikios.cooja.contikimote.interfaces.ContikiIPAddress org.contikios.cooja.contikimote.interfaces.ContikiRadio org.contikios.cooja.contikimote.interfaces.ContikiButton org.contikios.cooja.contikimote.interfaces.ContikiPIR org.contikios.cooja.contikimote.interfaces.ContikiClock org.contikios.cooja.contikimote.interfaces.ContikiLED org.contikios.cooja.contikimote.interfaces.ContikiCFS org.contikios.cooja.interfaces.Mote2MoteRelations org.contikios.cooja.interfaces.MoteAttributes +org.contikios.cooja.contikimote.ContikiMoteType.MOTE_INTERFACES = org.contikios.cooja.interfaces.Position org.contikios.cooja.interfaces.Battery org.contikios.cooja.contikimote.interfaces.ContikiVib org.contikios.cooja.contikimote.interfaces.ContikiMoteID org.contikios.cooja.contikimote.interfaces.ContikiRS232 org.contikios.cooja.contikimote.interfaces.ContikiBeeper org.contikios.cooja.interfaces.RimeAddress org.contikios.cooja.contikimote.interfaces.ContikiIPAddress org.contikios.cooja.contikimote.interfaces.ContikiRadio org.contikios.cooja.contikimote.interfaces.ContikiButton org.contikios.cooja.contikimote.interfaces.ContikiPIR org.contikios.cooja.contikimote.interfaces.ContikiClock org.contikios.cooja.contikimote.interfaces.ContikiLED org.contikios.cooja.contikimote.interfaces.ContikiCFS org.contikios.cooja.contikimote.interfaces.ContikiEEPROM org.contikios.cooja.interfaces.Mote2MoteRelations org.contikios.cooja.interfaces.MoteAttributes org.contikios.cooja.contikimote.ContikiMoteType.C_SOURCES = org.contikios.cooja.Cooja.MOTETYPES = org.contikios.cooja.motes.ImportAppMoteType org.contikios.cooja.motes.DisturberMoteType org.contikios.cooja.contikimote.ContikiMoteType -org.contikios.cooja.Cooja.PLUGINS = org.contikios.cooja.plugins.Visualizer org.contikios.cooja.plugins.LogListener org.contikios.cooja.plugins.TimeLine org.contikios.cooja.plugins.MoteInformation org.contikios.cooja.plugins.MoteInterfaceViewer org.contikios.cooja.plugins.VariableWatcher org.contikios.cooja.plugins.EventListener org.contikios.cooja.plugins.RadioLogger org.contikios.cooja.plugins.ScriptRunner org.contikios.cooja.plugins.Notes org.contikios.cooja.plugins.BufferListener org.contikios.cooja.plugins.DGRMConfigurator +org.contikios.cooja.Cooja.PLUGINS = org.contikios.cooja.plugins.Visualizer org.contikios.cooja.plugins.LogListener org.contikios.cooja.plugins.TimeLine org.contikios.cooja.plugins.MoteInformation org.contikios.cooja.plugins.MoteInterfaceViewer org.contikios.cooja.plugins.VariableWatcher org.contikios.cooja.plugins.EventListener org.contikios.cooja.plugins.RadioLogger org.contikios.cooja.plugins.ScriptRunner org.contikios.cooja.plugins.Notes org.contikios.cooja.plugins.BufferListener org.contikios.cooja.plugins.DGRMConfigurator org.contikios.cooja.plugins.BaseRSSIconf org.contikios.cooja.Cooja.POSITIONERS = org.contikios.cooja.positioners.RandomPositioner org.contikios.cooja.positioners.LinearPositioner org.contikios.cooja.positioners.EllipsePositioner org.contikios.cooja.positioners.ManualPositioner org.contikios.cooja.Cooja.RADIOMEDIUMS = org.contikios.cooja.radiomediums.UDGM org.contikios.cooja.radiomediums.UDGMConstantLoss org.contikios.cooja.radiomediums.DirectedGraphMedium org.contikios.cooja.radiomediums.SilentRadioMedium org.contikios.cooja.plugins.Visualizer.SKINS = org.contikios.cooja.plugins.skins.DGRMVisualizerSkin - diff --git a/tools/cooja/config/external_tools.config b/tools/cooja/config/external_tools.config index 18ad0be46..89d9c4f7d 100644 --- a/tools/cooja/config/external_tools.config +++ b/tools/cooja/config/external_tools.config @@ -25,7 +25,6 @@ PATH_JAVAC = javac DEFAULT_PROJECTDIRS = [CONTIKI_DIR]/tools/cooja/apps/mrm;[CONTIKI_DIR]/tools/cooja/apps/mspsim;[CONTIKI_DIR]/tools/cooja/apps/avrora;[CONTIKI_DIR]/tools/cooja/apps/serial_socket;[CONTIKI_DIR]/tools/cooja/apps/collect-view;[CONTIKI_DIR]/tools/cooja/apps/powertracker PARSE_WITH_COMMAND=false -PARSE_COMMAND=nm -a $(LIBFILE) MAPFILE_DATA_START = ^.data[ \t]*0x([0-9A-Fa-f]*)[ \t]*0x[0-9A-Fa-f]*[ \t]*$ MAPFILE_DATA_SIZE = ^.data[ \t]*0x[0-9A-Fa-f]*[ \t]*0x([0-9A-Fa-f]*)[ \t]*$ MAPFILE_BSS_START = ^.bss[ \t]*0x([0-9A-Fa-f]*)[ \t]*0x[0-9A-Fa-f]*[ \t]*$ @@ -35,11 +34,19 @@ MAPFILE_VAR_ADDRESS_1 = ^[ \t]*0x([0-9A-Fa-f]*)[ \t]* MAPFILE_VAR_ADDRESS_2 = [ \t]*$ MAPFILE_VAR_SIZE_1 = ^ MAPFILE_VAR_SIZE_2 = [ \t]*(0x[0-9A-Fa-f]*)[ \t]*[^ ]*[ \t]*$ -COMMAND_VAR_NAME_ADDRESS = ^([0-9A-Fa-f][0-9A-Fa-f]*)[ \t][^Tt][ \t]([^ ._][^ ]*) -COMMAND_DATA_START = ^([0-9A-Fa-f]*)[ \t]d[ \t].data$ -COMMAND_DATA_END = ^([0-9A-Fa-f]*)[ \t]A[ \t]_edata$ -COMMAND_BSS_START = ^([0-9A-Fa-f]*)[ \t]A[ \t]__bss_start$ -COMMAND_BSS_END = ^([0-9A-Fa-f]*)[ \t]A[ \t]_end$ + +PARSE_COMMAND=nm -aP $(LIBFILE) +COMMAND_VAR_NAME_ADDRESS_SIZE = ^([^.].*?)
    ([0-9a-fA-F]+) ([0-9a-fA-F])* +COMMAND_VAR_SEC_DATA = [DdGg] +COMMAND_VAR_SEC_BSS = [Bb] +COMMAND_VAR_SEC_COMMON = [C] +COMMAND_VAR_SEC_READONLY = [Rr] +COMMAND_DATA_START = ^.data[ \t]d[ \t]([0-9A-Fa-f]*)[ \t]*$ +COMMAND_DATA_END = ^_edata[ \t]A[ \t]([0-9A-Fa-f]*)[ \t]*$ +COMMAND_BSS_START = ^__bss_start[ \t]A[ \t]([0-9A-Fa-f]*)[ \t]*$ +COMMAND_BSS_END = ^_end[ \t]A[ \t]([0-9A-Fa-f]*)[ \t]*$ +COMMAND_READONLY_START = ^.rodata[ \t]r[ \t]([0-9A-Fa-f]*)[ \t]*$ +COMMAND_READONLY_END = ^.eh_frame_hdr[ \t]r[ \t]([0-9A-Fa-f]*)[ \t]*$ VISUALIZER_DEFAULT_SKINS=\ org.contikios.cooja.plugins.skins.IDVisualizerSkin;\ diff --git a/tools/cooja/config/external_tools_win32.config b/tools/cooja/config/external_tools_win32.config index 484f95a21..2d5dd7e4a 100644 --- a/tools/cooja/config/external_tools_win32.config +++ b/tools/cooja/config/external_tools_win32.config @@ -6,8 +6,14 @@ COMPILER_ARGS=-D__int64\="long long" -Wall -I'$(JAVA_HOME)/include' -I'$(JAVA_HO LINK_COMMAND_1 = mingw32-gcc -shared -Wl,-Map=$(MAPFILE) -Wl,--add-stdcall-alias -o $(LIBFILE) LINK_COMMAND_2 = -L/usr/lib/mingw PARSE_WITH_COMMAND = true -PARSE_COMMAND=nm -n -C $(LIBFILE) -COMMAND_DATA_START = ^([0-9A-Fa-f]*)[ \t]D[ \t].*_data_start__$ -COMMAND_DATA_END = ^([0-9A-Fa-f]*)[ \t]D[ \t].*_data_end__$ -COMMAND_BSS_START = ^([0-9A-Fa-f]*)[ \t]B[ \t].*_bss_start__$ -COMMAND_BSS_END = ^([0-9A-Fa-f]*)[ \t]B[ \t].*_bss_end__$ + +# Hack: nm with arguments -S --size-sort does not display __data_start symbols +PARSE_COMMAND=sh -c "/bin/nm -aP --size-sort -S $(LIBFILE) && /bin/nm -aP $(LIBFILE)" + +COMMAND_VAR_NAME_ADDRESS_SIZE = ^[_]([^.].*?)[ \t]
    [ \t]([0-9a-fA-F]+)[ \t]([0-9a-fA-F]+) +COMMAND_DATA_START = ^__data_start__[ \t]D[ \t]([0-9A-Fa-f]*) +COMMAND_DATA_END = ^__data_end__[ \t]D[ \t]([0-9A-Fa-f]*) +COMMAND_BSS_START = ^__bss_start__[ \t]B[ \t]([0-9A-Fa-f]*) +COMMAND_BSS_END = ^__bss_end__[ \t]B[ \t]([0-9A-Fa-f]*) +COMMAND_READONLY_START = ^.rodata[ \t]r[ \t]([0-9A-Fa-f]*) +COMMAND_READONLY_END = ^.eh_frame_hdr[ \t]r[ \t]([0-9A-Fa-f]*) diff --git a/tools/cooja/config/log4j_config.xml b/tools/cooja/config/log4j_config.xml index ff9741f0c..d83b38e0f 100644 --- a/tools/cooja/config/log4j_config.xml +++ b/tools/cooja/config/log4j_config.xml @@ -1,25 +1,25 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/cooja/config/quickhelp.txt b/tools/cooja/config/quickhelp.txt index cc6de2210..a4514c7da 100644 --- a/tools/cooja/config/quickhelp.txt +++ b/tools/cooja/config/quickhelp.txt @@ -1,14 +1,13 @@ -KEYBOARD_SHORTCUTS = \ -Keyboard shortcuts
    \ -
    Ctrl+N: New simulation\ -
    Ctrl+S: Start/pause simulation\ -
    Ctrl+R: Reload current simulation. If no simulation exists, the last used simulation config is loaded\ -
    Ctrl+Shift+R: Reload current simulation with another random seed\ -
    \ -
    F1: Toggle quick help - -GETTING_STARTED = \ -Getting started
    \ -
    \ -
    F1: Toggle quick help
    - +KEYBOARD_SHORTCUTS = \ +Keyboard shortcuts
    \ +
    Ctrl+N: New simulation\ +
    Ctrl+S: Start/pause simulation\ +
    Ctrl+R: Reload current simulation. If no simulation exists, the last used simulation config is loaded\ +
    Ctrl+Shift+R: Reload current simulation with another random seed\ +
    \ +
    F1: Toggle quick help + +GETTING_STARTED = \ +Getting started
    \ +
    \ +
    F1: Toggle quick help
    diff --git a/tools/cooja/config/scripts/basic.js b/tools/cooja/config/scripts/basic.js index ebbacaaca..cd454dea0 100644 --- a/tools/cooja/config/scripts/basic.js +++ b/tools/cooja/config/scripts/basic.js @@ -1,28 +1,28 @@ -/* - * Example Contiki test script (JavaScript). - * A Contiki test script acts on mote output, such as via printf()'s. - * The script may operate on the following variables: - * Mote mote, int id, String msg - */ - -/* Make test automatically fail (timeout) after 100 simulated seconds */ -//TIMEOUT(100000); /* milliseconds. no action at timeout */ -TIMEOUT(100000, log.log("last msg: " + msg + "\n")); /* milliseconds. print last msg at timeout */ - -log.log("first mote output: '" + msg + "'\n"); - -YIELD(); /* wait for another mote output */ - -log.log("second mote output: '" + msg + "'\n"); - -log.log("waiting for hello world output from mote 1\n"); -WAIT_UNTIL(id == 1 && msg.equals("Hello, world")); - -write(mote, "Hello, mote\n"); /* Write to mote serial port */ - -GENERATE_MSG(15000, "continue"); -YIELD_THEN_WAIT_UNTIL(msg.equals("continue")); - -log.log("ok, reporting success now\n"); -log.testOK(); /* Report test success and quit */ -//log.testFailed(); /* Report test failure and quit */ +/* + * Example Contiki test script (JavaScript). + * A Contiki test script acts on mote output, such as via printf()'s. + * The script may operate on the following variables: + * Mote mote, int id, String msg + */ + +/* Make test automatically fail (timeout) after 100 simulated seconds */ +//TIMEOUT(100000); /* milliseconds. no action at timeout */ +TIMEOUT(100000, log.log("last msg: " + msg + "\n")); /* milliseconds. print last msg at timeout */ + +log.log("first mote output: '" + msg + "'\n"); + +YIELD(); /* wait for another mote output */ + +log.log("second mote output: '" + msg + "'\n"); + +log.log("waiting for hello world output from mote 1\n"); +WAIT_UNTIL(id == 1 && msg.equals("Hello, world")); + +write(mote, "Hello, mote\n"); /* Write to mote serial port */ + +GENERATE_MSG(15000, "continue"); +YIELD_THEN_WAIT_UNTIL(msg.equals("continue")); + +log.log("ok, reporting success now\n"); +log.testOK(); /* Report test success and quit */ +//log.testFailed(); /* Report test failure and quit */ diff --git a/tools/cooja/config/scripts/helloworld.js b/tools/cooja/config/scripts/helloworld.js index 5f6f617b5..6d82a7352 100644 --- a/tools/cooja/config/scripts/helloworld.js +++ b/tools/cooja/config/scripts/helloworld.js @@ -1,11 +1,11 @@ -/* - * Example Contiki test script (JavaScript). - * A Contiki test script acts on mote output, such as via printf()'s. - * The script may operate on the following variables: - * Mote mote, int id, String msg - */ - -TIMEOUT(2000, log.log("last message: " + msg + "\n")); - -WAIT_UNTIL(msg.equals('Hello, world')); -log.testOK(); +/* + * Example Contiki test script (JavaScript). + * A Contiki test script acts on mote output, such as via printf()'s. + * The script may operate on the following variables: + * Mote mote, int id, String msg + */ + +TIMEOUT(2000, log.log("last message: " + msg + "\n")); + +WAIT_UNTIL(msg.equals('Hello, world')); +log.testOK(); diff --git a/tools/cooja/config/scripts/log_all.js b/tools/cooja/config/scripts/log_all.js index b0c20069d..d4eb6233f 100644 --- a/tools/cooja/config/scripts/log_all.js +++ b/tools/cooja/config/scripts/log_all.js @@ -1,13 +1,13 @@ -/* - * Example Contiki test script (JavaScript). - * A Contiki test script acts on mote output, such as via printf()'s. - * The script may operate on the following variables: - * Mote mote, int id, String msg - */ - -TIMEOUT(60000); - -while (true) { - log.log(time + ":" + id + ":" + msg + "\n"); - YIELD(); -} +/* + * Example Contiki test script (JavaScript). + * A Contiki test script acts on mote output, such as via printf()'s. + * The script may operate on the following variables: + * Mote mote, int id, String msg + */ + +TIMEOUT(60000); + +while (true) { + log.log(time + ":" + id + ":" + msg + "\n"); + YIELD(); +} diff --git a/tools/cooja/config/scripts/plugins.js b/tools/cooja/config/scripts/plugins.js index 664d14030..4c205aabb 100644 --- a/tools/cooja/config/scripts/plugins.js +++ b/tools/cooja/config/scripts/plugins.js @@ -1,66 +1,66 @@ -/* - * Example showing how to reference and interact with surrounding - * COOJA plugins from a test script. - * The code looks up three common plugins and, if found, performs some - * simple plugin-specific task. - */ - -/* Started plugins are available from the GUI object */ - -TIMEOUT(60000); - -counter=0; -plugins=0; - -timeout_function = function my_fun() { - log.log("Script timed out.\n"); - log.log(plugins + " plugins were referenced\n"); -} - -while (counter<10) { - counter++; - - GENERATE_MSG(1000, "wait"); - YIELD_THEN_WAIT_UNTIL(msg.equals("wait")); - - /* Toggle Log Listener filter */ - plugin = mote.getSimulation().getCooja().getStartedPlugin("org.contikios.cooja.plugins.LogListener"); - if (plugin != null) { - plugins++; - log.log("LogListener: Setting filter: " + plugin.getFilter() + "\n"); - if (plugin.getFilter() == null || !plugin.getFilter().equals("Contiki")) { - plugin.setFilter("Contiki"); - } else { - plugin.setFilter("MAC"); - } - } - - GENERATE_MSG(1000, "wait"); - YIELD_THEN_WAIT_UNTIL(msg.equals("wait")); - - /* Extract PowerTracker statistics */ - plugin = mote.getSimulation().getCooja().getStartedPlugin("PowerTracker"); - if (plugin != null) { - plugins++; - stats = plugin.radioStatistics(); - if (stats.length() > 40) { - /* Stripping */ - stats = stats.substring(0, 40) + "..."; - } - log.log("PowerTracker: Extracted statistics:\n" + stats + "\n"); - } else { - log.log("No PowerTracker plugin\n"); - } - - GENERATE_MSG(1000, "wait"); - YIELD_THEN_WAIT_UNTIL(msg.equals("wait")); - - /* Select time in Radio Logger */ - plugin = mote.getSimulation().getCooja().getStartedPlugin("org.contikios.cooja.plugins.RadioLogger"); - if (plugin != null) { - plugins++; - log.log("RadioLogger: Showing logged radio packet at mid simulation\n"); - plugin.trySelectTime(time/2); - } - -} +/* + * Example showing how to reference and interact with surrounding + * COOJA plugins from a test script. + * The code looks up three common plugins and, if found, performs some + * simple plugin-specific task. + */ + +/* Started plugins are available from the GUI object */ + +TIMEOUT(60000); + +counter=0; +plugins=0; + +timeout_function = function my_fun() { + log.log("Script timed out.\n"); + log.log(plugins + " plugins were referenced\n"); +} + +while (counter<10) { + counter++; + + GENERATE_MSG(1000, "wait"); + YIELD_THEN_WAIT_UNTIL(msg.equals("wait")); + + /* Toggle Log Listener filter */ + plugin = mote.getSimulation().getCooja().getStartedPlugin("org.contikios.cooja.plugins.LogListener"); + if (plugin != null) { + plugins++; + log.log("LogListener: Setting filter: " + plugin.getFilter() + "\n"); + if (plugin.getFilter() == null || !plugin.getFilter().equals("Contiki")) { + plugin.setFilter("Contiki"); + } else { + plugin.setFilter("MAC"); + } + } + + GENERATE_MSG(1000, "wait"); + YIELD_THEN_WAIT_UNTIL(msg.equals("wait")); + + /* Extract PowerTracker statistics */ + plugin = mote.getSimulation().getCooja().getStartedPlugin("PowerTracker"); + if (plugin != null) { + plugins++; + stats = plugin.radioStatistics(); + if (stats.length() > 40) { + /* Stripping */ + stats = stats.substring(0, 40) + "..."; + } + log.log("PowerTracker: Extracted statistics:\n" + stats + "\n"); + } else { + log.log("No PowerTracker plugin\n"); + } + + GENERATE_MSG(1000, "wait"); + YIELD_THEN_WAIT_UNTIL(msg.equals("wait")); + + /* Select time in Radio Logger */ + plugin = mote.getSimulation().getCooja().getStartedPlugin("org.contikios.cooja.plugins.RadioLogger"); + if (plugin != null) { + plugins++; + log.log("RadioLogger: Showing logged radio packet at mid simulation\n"); + plugin.trySelectTime(time/2); + } + +} diff --git a/tools/cooja/config/scripts/shell.js b/tools/cooja/config/scripts/shell.js index 6dc1a8fdb..6590aa481 100644 --- a/tools/cooja/config/scripts/shell.js +++ b/tools/cooja/config/scripts/shell.js @@ -1,27 +1,27 @@ -/* - * Example Contiki test script (JavaScript). - * A Contiki test script acts on mote output, such as via printf()'s. - * The script may operate on the following variables: - * Mote mote, int id, String msg - */ - -/* Wait until node has booted */ -WAIT_UNTIL(msg.startsWith('Starting')); -log.log("Mote started\n"); -mymote = mote; /* store mote reference */ - -/* Wait 3 seconds (3000ms) */ -GENERATE_MSG(3000, "continue"); -YIELD_THEN_WAIT_UNTIL(msg.equals("continue")); - -/* Write command to serial port */ -log.log("Writing 'ls' to mote serial port\n"); -write(mymote, "ls"); - -/* Read replies */ -while (true) { - YIELD(); - if (mote == mymote) { - log.log("Mote replied: " + msg + "\n"); - } +/* + * Example Contiki test script (JavaScript). + * A Contiki test script acts on mote output, such as via printf()'s. + * The script may operate on the following variables: + * Mote mote, int id, String msg + */ + +/* Wait until node has booted */ +WAIT_UNTIL(msg.startsWith('Starting')); +log.log("Mote started\n"); +mymote = mote; /* store mote reference */ + +/* Wait 3 seconds (3000ms) */ +GENERATE_MSG(3000, "continue"); +YIELD_THEN_WAIT_UNTIL(msg.equals("continue")); + +/* Write command to serial port */ +log.log("Writing 'ls' to mote serial port\n"); +write(mymote, "ls"); + +/* Read replies */ +while (true) { + YIELD(); + if (mote == mymote) { + log.log("Mote replied: " + msg + "\n"); + } } \ No newline at end of file diff --git a/tools/cooja/examples/jni_test/README.md b/tools/cooja/examples/jni_test/README.md index 145d789ab..99b542c8f 100644 --- a/tools/cooja/examples/jni_test/README.md +++ b/tools/cooja/examples/jni_test/README.md @@ -1,20 +1,20 @@ -_The JNI tests have been replaced by the Cooja configuration wizard._ - -The JNI tests assisted in configuring Cooja for compiling and linking Java -Native Interface (JNI) enabled Contiki libraries. Such Contiki libraries are -used by Cooja's Contiki Motes: motes simulated at the operating system -abstraction level. - -The new configuration wizard is started from inside Cooja, and exercises the -same functionality as the JNI tests. In contrast, the wizard is directly -connected to the current Cooja configuration, removing the need to migrate the -configuration between JNI tests and Cooja. - -To start the wizard: - - cd tools/cooja - ant run # Start COOJA - -Menu > Settings > Compiler configuration wizard - --- Fredrik Osterlind, fros@sics.se, March 2009 +_The JNI tests have been replaced by the Cooja configuration wizard._ + +The JNI tests assisted in configuring Cooja for compiling and linking Java +Native Interface (JNI) enabled Contiki libraries. Such Contiki libraries are +used by Cooja's Contiki Motes: motes simulated at the operating system +abstraction level. + +The new configuration wizard is started from inside Cooja, and exercises the +same functionality as the JNI tests. In contrast, the wizard is directly +connected to the current Cooja configuration, removing the need to migrate the +configuration between JNI tests and Cooja. + +To start the wizard: + + cd tools/cooja + ant run # Start COOJA + +Menu > Settings > Compiler configuration wizard + +-- Fredrik Osterlind, fros@sics.se, March 2009 diff --git a/tools/cooja/java/org/contikios/cooja/AddressMemory.java b/tools/cooja/java/org/contikios/cooja/AddressMemory.java deleted file mode 100644 index 4f126ab7e..000000000 --- a/tools/cooja/java/org/contikios/cooja/AddressMemory.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. 2. 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. 3. Neither the name of the - * Institute 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 INSTITUTE 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 INSTITUTE 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. - * - */ - -package org.contikios.cooja; - -public interface AddressMemory { - - /** - * @return All variable names known and residing in this memory - */ - public String[] getVariableNames(); - - /** - * Checks if given variable exists in memory. - * - * @param varName Variable name - * @return True if variable exists, false otherwise - */ - public boolean variableExists(String varName); - - /** - * Returns address of variable with given name. - * - * @param varName Variable name - * @return Variable address - * @throws UnknownVariableException Variable does not exist - */ - public int getVariableAddress(String varName) throws UnknownVariableException; - - /** - * Returns a value of the byte variable with the given name. - * - * @param varName Name of byte variable - * @return Value of byte variable - * @throws UnknownVariableException Variable does not exist - */ - public byte getByteValueOf(String varName) throws UnknownVariableException; - - /** - * Set byte value of variable with given name. - * - * @param varName Name of byte variable - * @param newVal New value of byte - * @throws UnknownVariableException Variable does not exist - */ - public void setByteValueOf(String varName, byte newVal) throws UnknownVariableException; - - /** - * Returns byte array of given length and with the given name. - * - * @param varName Name of array - * @param length Length of array - * @return Data of array - * @throws UnknownVariableException Variable does not exist - */ - public byte[] getByteArray(String varName, int length) throws UnknownVariableException; - - /** - * Set byte array of the variable with the given name. - * - * @param varName Name of array - * @param data New data of array - * @throws UnknownVariableException Variable does not exist - */ - public void setByteArray(String varName, byte[] data) throws UnknownVariableException; - - /** - * @return Number of bytes in an integer - */ - public int getIntegerLength(); - - /** - * Returns a value of the integer variable with the given name. - * - * @param varName Name of integer variable - * @return Value of integer variable - * @throws UnknownVariableException Variable does not exist - */ - public int getIntValueOf(String varName) throws UnknownVariableException; - - /** - * Set integer value of variable with given name. - * - * @param varName Name of integer variable - * @param newVal New integer value - * @throws UnknownVariableException Variable does not exist - */ - public void setIntValueOf(String varName, int newVal) throws UnknownVariableException; - - /** - * Unknown variable name exception. - */ - public class UnknownVariableException extends RuntimeException { - public UnknownVariableException(String varName) { - super("Unknown variable name: " + varName); - } - } - -} diff --git a/tools/cooja/java/org/contikios/cooja/Cooja.java b/tools/cooja/java/org/contikios/cooja/Cooja.java index c9c2bad7a..4f0814249 100644 --- a/tools/cooja/java/org/contikios/cooja/Cooja.java +++ b/tools/cooja/java/org/contikios/cooja/Cooja.java @@ -133,12 +133,14 @@ import org.contikios.cooja.dialogs.ConfigurationWizard; import org.contikios.cooja.dialogs.CreateSimDialog; import org.contikios.cooja.dialogs.ExternalToolsDialog; import org.contikios.cooja.dialogs.MessageList; +import org.contikios.cooja.dialogs.MessageListUI; import org.contikios.cooja.dialogs.ProjectDirectoriesDialog; import org.contikios.cooja.plugins.MoteTypeInformation; import org.contikios.cooja.plugins.ScriptRunner; import org.contikios.cooja.plugins.SimControl; import org.contikios.cooja.plugins.SimInformation; import org.contikios.cooja.util.ExecuteJAR; +import org.contikios.cooja.util.ScnObservable; /** * Main file of COOJA Simulator. Typically contains a visualizer for the @@ -274,7 +276,7 @@ public class Cooja extends Observable { "MAPFILE_VAR_SIZE_1", "MAPFILE_VAR_SIZE_2", "PARSE_COMMAND", - "COMMAND_VAR_NAME_ADDRESS", + "COMMAND_VAR_NAME_ADDRESS_SIZE", "COMMAND_DATA_START", "COMMAND_DATA_END", "COMMAND_BSS_START", "COMMAND_BSS_END", "COMMAND_COMMON_START", "COMMAND_COMMON_END", @@ -325,21 +327,10 @@ public class Cooja extends Observable { private Vector> positionerClasses = new Vector>(); - private class HighlightObservable extends Observable { - private void setChangedAndNotify(Mote mote) { - setChanged(); - notifyObservers(mote); - } - } - private HighlightObservable moteHighlightObservable = new HighlightObservable(); - private class MoteRelationsObservable extends Observable { - private void setChangedAndNotify() { - setChanged(); - notifyObservers(); - } - } - private MoteRelationsObservable moteRelationObservable = new MoteRelationsObservable(); + private ScnObservable moteHighlightObservable = new ScnObservable(); + + private ScnObservable moteRelationObservable = new ScnObservable(); private JTextPane quickHelpTextPane; private JScrollPane quickHelpScroll; @@ -952,7 +943,8 @@ public class Cooja extends Observable { String tooltip = "
    ";
             if (pluginType == PluginType.COOJA_PLUGIN || pluginType == PluginType.COOJA_STANDARD_PLUGIN) {
               tooltip += "Cooja plugin: ";
    -        } else if (pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN) {
    +        } else if (pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN
    +        		|| pluginType == PluginType.SIM_CONTROL_PLUGIN) {
               tooltip += "Simulation plugin: ";
               if (getSimulation() == null) {
                 menuItem.setEnabled(false);
    @@ -963,7 +955,8 @@ public class Cooja extends Observable {
             tooltip += description + " (" + newPluginClass.getName() + ")";
     
             /* Check if simulation plugin depends on any particular radio medium */
    -        if ((pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN) && (getSimulation() != null)) {
    +        if ((pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN
    +        		|| pluginType == PluginType.SIM_CONTROL_PLUGIN) && (getSimulation() != null)) {
               if (newPluginClass.getAnnotation(SupportedArguments.class) != null) {
                 boolean active = false;
                 Class[] radioMediums = newPluginClass.getAnnotation(SupportedArguments.class).radioMediums();
    @@ -1020,7 +1013,8 @@ public class Cooja extends Observable {
               }
     
               int pluginType = pluginClass.getAnnotation(PluginType.class).value();
    -          if (pluginType != PluginType.SIM_PLUGIN && pluginType != PluginType.SIM_STANDARD_PLUGIN) {
    +          if (pluginType != PluginType.SIM_PLUGIN && pluginType != PluginType.SIM_STANDARD_PLUGIN
    +        		  && pluginType != PluginType.SIM_CONTROL_PLUGIN) {
                 continue;
               }
     
    @@ -1659,7 +1653,6 @@ public class Cooja extends Observable {
               return false;
             }
     
    -        int nrFrames = myDesktopPane.getAllFrames().length;
             myDesktopPane.add(pluginFrame);
     
             /* Set size if not already specified by plugin */
    @@ -1667,11 +1660,9 @@ public class Cooja extends Observable {
               pluginFrame.setSize(FRAME_STANDARD_WIDTH, FRAME_STANDARD_HEIGHT);
             }
     
    -        /* Set location if not already visible */
    +        /* Set location if not already set */
             if (pluginFrame.getLocation().x <= 0 && pluginFrame.getLocation().y <= 0) {
    -          pluginFrame.setLocation(
    -              nrFrames * FRAME_NEW_OFFSET,
    -              nrFrames * FRAME_NEW_OFFSET);
    +          pluginFrame.setLocation(determineNewPluginLocation());
             }
     
             pluginFrame.setVisible(true);
    @@ -1690,6 +1681,29 @@ public class Cooja extends Observable {
         }.invokeAndWait();
       }
     
    +  /**
    +   * Determines suitable location for placing new plugin.
    +   * 

    + * If possible, this is below right of the second last activated + * internfal frame (offset is determined by FRAME_NEW_OFFSET). + * + * @return Resulting placement position + */ + private Point determineNewPluginLocation() { + Point topFrameLoc; + JInternalFrame[] iframes = myDesktopPane.getAllFrames(); + if (iframes.length > 1) { + topFrameLoc = iframes[1].getLocation(); + } else { + topFrameLoc = new Point( + myDesktopPane.getSize().width / 2, + myDesktopPane.getSize().height / 2); + } + return new Point( + topFrameLoc.x + FRAME_NEW_OFFSET, + topFrameLoc.y + FRAME_NEW_OFFSET); + } + /** * Close all mote plugins for given mote. * @@ -1828,8 +1842,8 @@ public class Cooja extends Observable { pluginClass.getConstructor(new Class[] { Mote.class, Simulation.class, Cooja.class }) .newInstance(argMote, argSimulation, argGUI); - } else if (pluginType == PluginType.SIM_PLUGIN - || pluginType == PluginType.SIM_STANDARD_PLUGIN) { + } else if (pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN + || pluginType == PluginType.SIM_CONTROL_PLUGIN) { if (argGUI == null) { throw new PluginConstructionException("No GUI argument for simulation plugin"); } @@ -1911,7 +1925,8 @@ public class Cooja extends Observable { try { if (pluginType == PluginType.COOJA_PLUGIN || pluginType == PluginType.COOJA_STANDARD_PLUGIN) { pluginClass.getConstructor(new Class[] { Cooja.class }); - } else if (pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN) { + } else if (pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN + || pluginType == PluginType.SIM_CONTROL_PLUGIN) { pluginClass.getConstructor(new Class[] { Simulation.class, Cooja.class }); } else if (pluginType == PluginType.MOTE_PLUGIN) { pluginClass.getConstructor(new Class[] { Mote.class, Simulation.class, Cooja.class }); @@ -3132,7 +3147,7 @@ public class Cooja extends Observable { if (new File(logConfigFile).exists()) { DOMConfigurator.configure(logConfigFile); } else { - System.err.println("Failed to open " + logConfigFile); + logger.error("Failed to open " + logConfigFile); System.exit(1); } } else if (new File(LOG_CONFIG_FILE).exists()) { @@ -3227,19 +3242,19 @@ public class Cooja extends Observable { } Cooja gui = sim.getCooja(); - /* Make sure at least one test editor is controlling the simulation */ - boolean hasEditor = false; + /* Make sure at least one plugin controlling the simulation */ + boolean hasController = false; for (Plugin startedPlugin : gui.startedPlugins) { - if (startedPlugin instanceof ScriptRunner) { - hasEditor = true; - break; - } + int pluginType = startedPlugin.getClass().getAnnotation(PluginType.class).value(); + if (pluginType == PluginType.SIM_CONTROL_PLUGIN) { + hasController = true; + } } /* Backwards compatibility: - * simulation has no test editor, but has external (old style) test script. + * simulation has no control plugin, but has external (old style) test script. * We will manually start a test editor from here. */ - if (!hasEditor) { + if (!hasController) { File scriptFile = new File(config.substring(0, config.length()-4) + ".js"); if (scriptFile.exists()) { logger.info("Detected old simulation test, starting test editor manually from: " + scriptFile); @@ -3255,13 +3270,12 @@ public class Cooja extends Observable { System.exit(1); } } else { - logger.fatal("No test editor controlling simulation, aborting"); + logger.fatal("No plugin controlling simulation, aborting"); System.exit(1); } } - sim.setSpeedLimit(null); - sim.startSimulation(); + } else if (args.length > 0 && args[0].startsWith("-applet")) { @@ -3467,7 +3481,9 @@ public class Cooja extends Observable { } XMLOutputter outputter = new XMLOutputter(); - outputter.setFormat(Format.getPrettyFormat()); + Format fmt = Format.getPrettyFormat(); + fmt.setLineSeparator("\n"); + outputter.setFormat(fmt); outputter.output(doc, out); out.close(); @@ -3819,7 +3835,7 @@ public class Cooja extends Observable { /* Contiki error */ if (exception instanceof ContikiError) { String contikiError = ((ContikiError) exception).getContikiError(); - MessageList list = new MessageList(); + MessageListUI list = new MessageListUI(); for (String l: contikiError.split("\n")) { list.addMessage(l); } @@ -3828,14 +3844,14 @@ public class Cooja extends Observable { } /* Compilation output */ - MessageList compilationOutput = null; + MessageListUI compilationOutput = null; if (exception instanceof MoteTypeCreationException && ((MoteTypeCreationException) exception).hasCompilationOutput()) { - compilationOutput = ((MoteTypeCreationException) exception).getCompilationOutput(); + compilationOutput = (MessageListUI) ((MoteTypeCreationException) exception).getCompilationOutput(); } else if (exception.getCause() != null && exception.getCause() instanceof MoteTypeCreationException && ((MoteTypeCreationException) exception.getCause()).hasCompilationOutput()) { - compilationOutput = ((MoteTypeCreationException) exception.getCause()).getCompilationOutput(); + compilationOutput = (MessageListUI) ((MoteTypeCreationException) exception.getCause()).getCompilationOutput(); } if (compilationOutput != null) { compilationOutput.addPopupMenuItem(null, true); @@ -3843,8 +3859,8 @@ public class Cooja extends Observable { } /* Stack trace */ - MessageList stackTrace = new MessageList(); - PrintStream printStream = stackTrace.getInputStream(MessageList.NORMAL); + MessageListUI stackTrace = new MessageListUI(); + PrintStream printStream = stackTrace.getInputStream(MessageListUI.NORMAL); exception.printStackTrace(printStream); stackTrace.addPopupMenuItem(null, true); tabbedPane.addTab("Java stack trace", new JScrollPane(stackTrace)); @@ -3916,7 +3932,7 @@ public class Cooja extends Observable { Box buttonBox = Box.createHorizontalBox(); /* Warnings message list */ - MessageList compilationOutput = new MessageList(); + MessageListUI compilationOutput = new MessageListUI(); for (String w: warnings) { compilationOutput.addMessage(w, MessageList.ERROR); } @@ -4339,14 +4355,14 @@ public class Cooja extends Observable { private static JProgressBar PROGRESS_BAR = null; private static ArrayList PROGRESS_WARNINGS = new ArrayList(); public static void setProgressMessage(String msg) { - setProgressMessage(msg, MessageList.NORMAL); + setProgressMessage(msg, MessageListUI.NORMAL); } public static void setProgressMessage(String msg, int type) { if (PROGRESS_BAR != null && PROGRESS_BAR.isShowing()) { PROGRESS_BAR.setString(msg); PROGRESS_BAR.setStringPainted(true); } - if (type != MessageList.NORMAL) { + if (type != MessageListUI.NORMAL) { PROGRESS_WARNINGS.add(msg); } } diff --git a/tools/cooja/java/org/contikios/cooja/CoreComm.java b/tools/cooja/java/org/contikios/cooja/CoreComm.java index ca124ad5b..a714eac23 100644 --- a/tools/cooja/java/org/contikios/cooja/CoreComm.java +++ b/tools/cooja/java/org/contikios/cooja/CoreComm.java @@ -36,6 +36,7 @@ import java.util.Vector; import org.contikios.cooja.MoteType.MoteTypeCreationException; import org.contikios.cooja.contikimote.ContikiMoteType; import org.contikios.cooja.dialogs.MessageList; +import org.contikios.cooja.dialogs.MessageListUI; /** * The purpose of corecomm's is communicating with a compiled Contiki system @@ -203,9 +204,9 @@ public abstract class CoreComm { */ public static void compileSourceFile(String className) throws MoteTypeCreationException { - MessageList compilationOutput = new MessageList(); + MessageListUI compilationOutput = new MessageListUI(); OutputStream compilationStandardStream = compilationOutput - .getInputStream(MessageList.NORMAL); + .getInputStream(MessageListUI.NORMAL); OutputStream compilationErrorStream = compilationOutput .getInputStream(MessageList.ERROR); diff --git a/tools/cooja/java/org/contikios/cooja/Mote.java b/tools/cooja/java/org/contikios/cooja/Mote.java index 7eeb326a0..167a24ff4 100644 --- a/tools/cooja/java/org/contikios/cooja/Mote.java +++ b/tools/cooja/java/org/contikios/cooja/Mote.java @@ -28,6 +28,7 @@ package org.contikios.cooja; import java.util.Collection; +import org.contikios.cooja.mote.memory.MemoryInterface; import org.jdom.Element; @@ -63,7 +64,7 @@ public interface Mote { * @see #setMemory(MoteMemory) * @return Mote memory */ - public MoteMemory getMemory(); + public MemoryInterface getMemory(); /** * Returns mote type. diff --git a/tools/cooja/java/org/contikios/cooja/MoteMemory.java b/tools/cooja/java/org/contikios/cooja/MoteMemory.java deleted file mode 100644 index a730bee4f..000000000 --- a/tools/cooja/java/org/contikios/cooja/MoteMemory.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - */ - -package org.contikios.cooja; - - -/** - * This interface represents a mote memory. - * - * Mote memory is represented by byte arrays and this - * interface provides a few of basic operations. - * - * Note that this memory internally may consist of several - * different memory sections, not covering the entire range - * between the start address and the end address of this memory. - * - * @see org.contikios.cooja.SectionMoteMemory - * @author Fredrik Osterlind - */ -public interface MoteMemory extends AddressMemory { - - /** - * Clears the entire memory. - */ - public void clearMemory(); - - /** - * Returns a memory segment. - * - * @param address Start address of memory segment - * @param size Size of memory segment - * @return Memory segment or null if segment not available - */ - public byte[] getMemorySegment(int address, int size); - - /** - * Sets a memory segment. - * - * @param address Start address of memory segment - * @param data Data - */ - public void setMemorySegment(int address, byte[] data); - - /** - * Returns the sum of all byte array sizes in this memory. - * This is not neccessarily the the same as the total memory range, - * since the entire memory range may not be handled by this memory. - * - * @return Total size - */ - public int getTotalSize(); - - public abstract int parseInt(byte[] memorySegment); - - public enum MemoryEventType { READ, WRITE }; - - public interface MemoryMonitor { - public void memoryChanged(MoteMemory memory, MemoryEventType type, int address); - } - - public boolean addMemoryMonitor(int address, int size, MemoryMonitor mm); - public void removeMemoryMonitor(int address, int size, MemoryMonitor mm); -} diff --git a/tools/cooja/java/org/contikios/cooja/MoteType.java b/tools/cooja/java/org/contikios/cooja/MoteType.java index c5acb6880..60d9016be 100644 --- a/tools/cooja/java/org/contikios/cooja/MoteType.java +++ b/tools/cooja/java/org/contikios/cooja/MoteType.java @@ -37,6 +37,7 @@ import org.jdom.Element; import org.contikios.cooja.contikimote.ContikiMoteType; import org.contikios.cooja.dialogs.MessageList; +import org.contikios.cooja.dialogs.MessageListUI; /** * The mote type defines properties common for several motes. These properties diff --git a/tools/cooja/java/org/contikios/cooja/PluginType.java b/tools/cooja/java/org/contikios/cooja/PluginType.java index 34790a823..9bf6344e9 100644 --- a/tools/cooja/java/org/contikios/cooja/PluginType.java +++ b/tools/cooja/java/org/contikios/cooja/PluginType.java @@ -109,6 +109,18 @@ public @interface PluginType { * @see #COOJA_PLUGIN */ public static final int COOJA_STANDARD_PLUGIN = 5; + + /** + * Simulation Control Plugin + * + * A Simulation Control Plugin indicates control over the simulation. If COOJA + * is loaded in nogui mode, it will terminate if no controll plugin is present. + * + * COOJA plugins are available via the plugins menubar. + * + * When constructed, a COOJA plugin is given the current GUI. + */ + public static final int SIM_CONTROL_PLUGIN = 6; int value(); } diff --git a/tools/cooja/java/org/contikios/cooja/RadioMedium.java b/tools/cooja/java/org/contikios/cooja/RadioMedium.java index da60dc492..4905a187f 100644 --- a/tools/cooja/java/org/contikios/cooja/RadioMedium.java +++ b/tools/cooja/java/org/contikios/cooja/RadioMedium.java @@ -100,24 +100,24 @@ public abstract class RadioMedium { * Adds an observer which is notified each time a radio connection has finished. * * @see #getLastConnection() - * @see #deleteRadioMediumObserver(Observer) + * @see #deleteRadioTransmissionObserver(Observer) * @param observer New observer */ - public abstract void addRadioMediumObserver(Observer observer); + public abstract void addRadioTransmissionObserver(Observer observer); /** * @return Radio medium observable */ - public abstract Observable getRadioMediumObservable(); + public abstract Observable getRadioTransmissionObservable(); /** * Deletes an radio medium observer. * - * @see #addRadioMediumObserver(Observer) + * @see #addRadioTransmissionObserver(Observer) * @param observer * Observer to delete */ - public abstract void deleteRadioMediumObserver(Observer observer); + public abstract void deleteRadioTransmissionObserver(Observer observer); /** * @return Last radio connection finished in the radio medium diff --git a/tools/cooja/java/org/contikios/cooja/SafeRandom.java b/tools/cooja/java/org/contikios/cooja/SafeRandom.java new file mode 100644 index 000000000..07c46ff1e --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/SafeRandom.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2014, Friedrich-Alexander University Erlangen-Nuremberg. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the university 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +package org.contikios.cooja; + +import java.util.Random; + +/** + * This ensures that the functions of the random number generator are + * only called by the the thread initializing a simulation or the + * simulation thread itself. + * Rationale: By allowing another thread to use the random number + * generator concurrency is introduced, thus it can not be guaranteed + * that simulations are reproducible. + * + */ +public class SafeRandom extends Random { + + Simulation sim = null; + Thread initThread = null; + Boolean simStarted = false; + + private void assertSimThread() { + // sim can be null, because setSeed is called by the super-constructor. + if(sim == null) return; + + // If we are in the simulation thread, everything is fine (the default) + if(sim.isSimulationThread()) { + simStarted = true; + return; + } + + // Simulation has not started yet. Allow one initialisation thread. + if(!simStarted) { + if(initThread == null) initThread = Thread.currentThread(); + if(Thread.currentThread() == initThread ) return; + } + + //This is done via the GUI - reproducibility is lost anyway! + if(javax.swing.SwingUtilities.isEventDispatchThread()) return; + + // Some other threads seems to access the PNRG. This must not happen. + throw new RuntimeException("A random-function was not called from the simulation thread. This can break things!"); + + } + + public SafeRandom(Simulation sim) { + // assertSimThread is called by the super-constructor. + super(); + this.sim = sim; + } + + public SafeRandom(Simulation sim, long seed) { + // assertSimThread is called by the super-constructor. + super(seed); + this.sim = sim; + } + + synchronized public void setSeed(long seed) { + assertSimThread(); + super.setSeed(seed); + } + + /* + * This function is called by all functions returning random numbers + * @see java.util.Random#next(int) + */ + protected int next(int bits) { + assertSimThread(); + return super.next(bits); + } + +} diff --git a/tools/cooja/java/org/contikios/cooja/SectionMoteMemory.java b/tools/cooja/java/org/contikios/cooja/SectionMoteMemory.java deleted file mode 100644 index 267bfac7b..000000000 --- a/tools/cooja/java/org/contikios/cooja/SectionMoteMemory.java +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. 2. 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. 3. Neither the name of the - * Institute 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 INSTITUTE 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 INSTITUTE 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. - */ - -package org.contikios.cooja; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; - -import org.apache.log4j.Logger; - -/** - * Represents a mote memory consisting of non-overlapping memory sections with - * symbol addresses. - *

    - * When an non-existing memory segment is written, a new section is automatically - * created for this segment. - *

    - * - * @author Fredrik Osterlind - */ -public class SectionMoteMemory implements MoteMemory, AddressMemory { - private static Logger logger = Logger.getLogger(SectionMoteMemory.class); - - private ArrayList sections = new ArrayList(); - - /* readonly memory is never written to Contiki core, and is used to provide - * access to, for instance, strings */ - private ArrayList readonlySections = new ArrayList(); - - private final HashMap addresses; - - /* used to map Cooja's address space to native (Contiki's) addresses */ - private final int offset; - - /** - * @param addresses Symbol addresses - * @param offset Offset for internally used addresses - */ - public SectionMoteMemory(HashMap addresses, int offset) { - this.addresses = addresses; - this.offset = offset; - } - - public String[] getVariableNames() { - return addresses.keySet().toArray(new String[0]); - } - - public int getVariableAddress(String varName) throws UnknownVariableException { - /* Cooja address space */ - if (!addresses.containsKey(varName)) { - throw new UnknownVariableException(varName); - } - - return addresses.get(varName).intValue() + offset; - } - - public int getIntegerLength() { - return 4; - } - - public void clearMemory() { - sections.clear(); - } - - public byte[] getMemorySegment(int address, int size) { - /* Cooja address space */ - address -= offset; - - for (MoteMemorySection section : sections) { - if (section.includesAddr(address) - && section.includesAddr(address + size - 1)) { - return section.getMemorySegment(address, size); - } - } - - /* Check if in readonly section */ - for (MoteMemorySection section : readonlySections) { - if (section.includesAddr(address) - && section.includesAddr(address + size - 1)) { - return section.getMemorySegment(address, size); - } - } - - return null; - } - - public void setMemorySegmentNative(int address, byte[] data) { - setMemorySegment(address+offset, data); - } - - public void setMemorySegment(int address, byte[] data) { - /* Cooja address space */ - address -= offset; - - /* TODO XXX Sections may overlap */ - for (MoteMemorySection section : sections) { - if (section.includesAddr(address) - && section.includesAddr(address + data.length - 1)) { - section.setMemorySegment(address, data); - return; - } - } - sections.add(new MoteMemorySection(address, data)); - } - - public void setReadonlyMemorySegment(int address, byte[] data) { - /* Cooja address space */ - address -= offset; - - readonlySections.add(new MoteMemorySection(address, data)); - } - - public int getTotalSize() { - int totalSize = 0; - for (MoteMemorySection section : sections) { - totalSize += section.getSize(); - } - return totalSize; - } - - /** - * Returns the total number of sections in this memory. - * - * @return Number of sections - */ - public int getNumberOfSections() { - return sections.size(); - } - - /** - * Get start address of given section in native address space. - * - * @param sectionNr Section position - * @return Start address of section - */ - public int getSectionNativeAddress(int sectionNr) { - if (sectionNr >= sections.size()) { - return -1; - } - return sections.get(sectionNr).getStartAddr(); - } - - /** - * Get size of section at given position. - * - * @param sectionNr Section position - * @return Size of section - */ - public int getSizeOfSection(int sectionNr) { - if (sectionNr >= sections.size()) { - return -1; - } - - return sections.get(sectionNr).getSize(); - } - - /** - * Get data of section at given position. - * - * @param sectionNr Section position - * @return Data at section - */ - public byte[] getDataOfSection(int sectionNr) { - if (sectionNr >= sections.size()) { - return null; - } - - return sections.get(sectionNr).getData(); - } - - public boolean variableExists(String varName) { - return addresses.containsKey(varName); - } - - public int getIntValueOf(String varName) throws UnknownVariableException { - int varAddr = getVariableAddress(varName); - byte[] varData = getMemorySegment(varAddr, 4); - - if (varData == null) { - throw new UnknownVariableException(varName); - } - - return parseInt(varData); - } - - public void setIntValueOf(String varName, int newVal) throws UnknownVariableException { - int varAddr = getVariableAddress(varName); - - /* TODO Correct for all platforms? */ - int newValToSet = Integer.reverseBytes(newVal); - - int pos = 0; - - byte[] varData = new byte[4]; - varData[pos++] = (byte) ((newValToSet & 0xFF000000) >> 24); - varData[pos++] = (byte) ((newValToSet & 0xFF0000) >> 16); - varData[pos++] = (byte) ((newValToSet & 0xFF00) >> 8); - varData[pos++] = (byte) ((newValToSet & 0xFF) >> 0); - - setMemorySegment(varAddr, varData); - } - - public byte getByteValueOf(String varName) throws UnknownVariableException { - int varAddr = getVariableAddress(varName); - byte[] varData = getMemorySegment(varAddr, 1); - - if (varData == null) { - throw new UnknownVariableException(varName); - } - - return varData[0]; - } - - public void setByteValueOf(String varName, byte newVal) throws UnknownVariableException { - int varAddr = getVariableAddress(varName); - byte[] varData = new byte[1]; - - varData[0] = newVal; - - setMemorySegment(varAddr, varData); - } - - public byte[] getByteArray(String varName, int length) throws UnknownVariableException { - int varAddr = getVariableAddress(varName); - return getMemorySegment(varAddr, length); - } - - public void setByteArray(String varName, byte[] data) throws UnknownVariableException { - int varAddr = getVariableAddress(varName); - setMemorySegment(varAddr, data); - } - - /** - * A memory section contains a byte array and a start address. - * - * @author Fredrik Osterlind - */ - private static class MoteMemorySection { - private byte[] data = null; - private final int startAddr; - - /** - * Create a new memory section. - * - * @param startAddr - * Start address of section - * @param data - * Data of section - */ - public MoteMemorySection(int startAddr, byte[] data) { - this.startAddr = startAddr; - this.data = data; - } - - /** - * Returns start address of this memory section. - * - * @return Start address - */ - public int getStartAddr() { - return startAddr; - } - - /** - * Returns size of this memory section. - * - * @return Size - */ - public int getSize() { - return data.length; - } - - /** - * Returns the entire byte array which defines this section. - * - * @return Byte array - */ - public byte[] getData() { - return data; - } - - /** - * True if given address is part of this memory section. - * - * @param addr - * Address - * @return True if given address is part of this memory section, false - * otherwise - */ - public boolean includesAddr(int addr) { - if (data == null) { - return false; - } - - return (addr >= startAddr && addr < (startAddr + data.length)); - } - - /** - * Returns memory segment. - * - * @param addr - * Start address of memory segment - * @param size - * Size of memory segment - * @return Memory segment - */ - public byte[] getMemorySegment(int addr, int size) { - byte[] ret = new byte[size]; - System.arraycopy(data, addr - startAddr, ret, 0, size); - return ret; - } - - /** - * Sets a memory segment. - * - * @param addr - * Start of memory segment - * @param data - * Data of memory segment - */ - public void setMemorySegment(int addr, byte[] data) { - System.arraycopy(data, 0, this.data, addr - startAddr, data.length); - } - - public MoteMemorySection clone() { - byte[] dataClone = new byte[data.length]; - System.arraycopy(data, 0, dataClone, 0, data.length); - - MoteMemorySection clone = new MoteMemorySection(startAddr, dataClone); - return clone; - } - } - - public SectionMoteMemory clone() { - ArrayList sectionsClone = new ArrayList(); - for (MoteMemorySection section : sections) { - sectionsClone.add(section.clone()); - } - - SectionMoteMemory clone = new SectionMoteMemory(addresses, offset); - clone.sections = sectionsClone; - clone.readonlySections = readonlySections; - - return clone; - } - - private ArrayList polledMemories = new ArrayList(); - public void pollForMemoryChanges() { - for (PolledMemorySegments mem: polledMemories.toArray(new PolledMemorySegments[0])) { - mem.notifyIfChanged(); - } - } - - private class PolledMemorySegments { - public final MemoryMonitor mm; - public final int address; - public final int size; - private byte[] oldMem; - - public PolledMemorySegments(MemoryMonitor mm, int address, int size) { - this.mm = mm; - this.address = address; - this.size = size; - - oldMem = getMemorySegment(address, size); - } - - private void notifyIfChanged() { - byte[] newMem = getMemorySegment(address, size); - if (Arrays.equals(oldMem, newMem)) { - return; - } - - mm.memoryChanged(SectionMoteMemory.this, MemoryEventType.WRITE, address); - oldMem = newMem; - } - } - - public boolean addMemoryMonitor(int address, int size, MemoryMonitor mm) { - PolledMemorySegments t = new PolledMemorySegments(mm, address, size); - polledMemories.add(t); - return true; - } - - public void removeMemoryMonitor(int address, int size, MemoryMonitor mm) { - for (PolledMemorySegments mcm: polledMemories) { - if (mcm.mm != mm || mcm.address != address || mcm.size != size) { - continue; - } - polledMemories.remove(mcm); - break; - } - } - - public int parseInt(byte[] memorySegment) { - int retVal = 0; - int pos = 0; - retVal += ((memorySegment[pos++] & 0xFF)) << 24; - retVal += ((memorySegment[pos++] & 0xFF)) << 16; - retVal += ((memorySegment[pos++] & 0xFF)) << 8; - retVal += ((memorySegment[pos++] & 0xFF)) << 0; - - retVal = Integer.reverseBytes(retVal); - return retVal; - } -} diff --git a/tools/cooja/java/org/contikios/cooja/Simulation.java b/tools/cooja/java/org/contikios/cooja/Simulation.java index 293a4c2c2..74f6ed902 100644 --- a/tools/cooja/java/org/contikios/cooja/Simulation.java +++ b/tools/cooja/java/org/contikios/cooja/Simulation.java @@ -93,7 +93,7 @@ public class Simulation extends Observable implements Runnable { private long maxMoteStartupDelay = 1000*MILLISECOND; - private Random randomGenerator = new Random(); + private SafeRandom randomGenerator; private boolean hasMillisecondObservers = false; private MillisecondObservable millisecondObservable = new MillisecondObservable(); @@ -322,6 +322,7 @@ public class Simulation extends Observable implements Runnable { */ public Simulation(Cooja cooja) { this.cooja = cooja; + randomGenerator = new SafeRandom(this); } /** @@ -846,6 +847,9 @@ public class Simulation extends Observable implements Runnable { } }; + //Add to list of uninitialized motes + motesUninit.add(mote); + if (!isRunning()) { /* Simulation is stopped, add mote immediately */ addMote.run(); @@ -853,8 +857,6 @@ public class Simulation extends Observable implements Runnable { /* Add mote from simulation thread */ invokeSimulationThread(addMote); } - //Add to list of uninitialized motes - motesUninit.add(mote); } diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/ContikiMote.java b/tools/cooja/java/org/contikios/cooja/contikimote/ContikiMote.java index b2c814b7b..de033aaa4 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/ContikiMote.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/ContikiMote.java @@ -38,10 +38,10 @@ import org.jdom.Element; import org.contikios.cooja.Mote; import org.contikios.cooja.MoteInterface; import org.contikios.cooja.MoteInterfaceHandler; -import org.contikios.cooja.MoteMemory; import org.contikios.cooja.MoteType; -import org.contikios.cooja.SectionMoteMemory; +import org.contikios.cooja.mote.memory.SectionMoteMemory; import org.contikios.cooja.Simulation; +import org.contikios.cooja.mote.memory.MemoryInterface; import org.contikios.cooja.motes.AbstractWakeupMote; /** @@ -83,10 +83,12 @@ public class ContikiMote extends AbstractWakeupMote implements Mote { requestImmediateWakeup(); } + @Override public int getID() { return myInterfaceHandler.getMoteID().getMoteID(); } + @Override public MoteInterfaceHandler getInterfaces() { return myInterfaceHandler; } @@ -95,14 +97,16 @@ public class ContikiMote extends AbstractWakeupMote implements Mote { myInterfaceHandler = newInterfaces; } - public MoteMemory getMemory() { + @Override + public MemoryInterface getMemory() { return myMemory; } - public void setMemory(MoteMemory memory) { - myMemory = (SectionMoteMemory) memory; + public void setMemory(SectionMoteMemory memory) { + myMemory = memory; } + @Override public MoteType getType() { return myType; } @@ -121,6 +125,7 @@ public class ContikiMote extends AbstractWakeupMote implements Mote { * * @param simTime Current simulation time */ + @Override public void execute(long simTime) { /* Poll mote interfaces */ @@ -154,6 +159,7 @@ public class ContikiMote extends AbstractWakeupMote implements Mote { * * @return Current simulation config */ + @Override public Collection getConfigXML() { ArrayList config = new ArrayList(); Element element; @@ -173,6 +179,7 @@ public class ContikiMote extends AbstractWakeupMote implements Mote { return config; } + @Override public boolean setConfigXML(Simulation simulation, Collection configXML, boolean visAvailable) { setSimulation(simulation); myMemory = myType.createInitialMemory(); @@ -212,6 +219,7 @@ public class ContikiMote extends AbstractWakeupMote implements Mote { return true; } + @Override public String toString() { return "Contiki " + getID(); } diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/ContikiMoteType.java b/tools/cooja/java/org/contikios/cooja/contikimote/ContikiMoteType.java index 78e05abe9..42205b94f 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/ContikiMoteType.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/ContikiMoteType.java @@ -27,7 +27,6 @@ * SUCH DAMAGE. * */ - package org.contikios.cooja.contikimote; import java.awt.Container; @@ -41,10 +40,11 @@ import java.lang.reflect.Method; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; +import java.util.Map; import java.util.Random; -import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -62,12 +62,18 @@ import org.contikios.cooja.Mote; import org.contikios.cooja.MoteInterface; import org.contikios.cooja.MoteType; import org.contikios.cooja.ProjectConfig; -import org.contikios.cooja.SectionMoteMemory; +import org.contikios.cooja.mote.memory.SectionMoteMemory; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; import org.contikios.cooja.dialogs.ContikiMoteCompileDialog; -import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageListUI; +import org.contikios.cooja.dialogs.MessageContainer; +import org.contikios.cooja.mote.memory.ArrayMemory; +import org.contikios.cooja.mote.memory.MemoryInterface; +import org.contikios.cooja.mote.memory.MemoryInterface.Symbol; +import org.contikios.cooja.mote.memory.MemoryLayout; +import org.contikios.cooja.mote.memory.UnknownVariableException; +import org.contikios.cooja.mote.memory.VarMemory; import org.contikios.cooja.util.StringUtils; /** @@ -92,7 +98,8 @@ import org.contikios.cooja.util.StringUtils; @ClassDescription("Cooja mote") @AbstractionLevelDescription("OS level") public class ContikiMoteType implements MoteType { - private static Logger logger = Logger.getLogger(ContikiMoteType.class); + + private static final Logger logger = Logger.getLogger(ContikiMoteType.class); public static final String ID_PREFIX = "mtype"; @@ -120,9 +127,11 @@ public class ContikiMoteType implements MoteType { * Communication stacks in Contiki. */ public enum NetworkStack { + DEFAULT, MANUAL; public String manualHeader = "netstack-conf-example.h"; + @Override public String toString() { if (this == DEFAULT) { return "Default (from contiki-conf.h)"; @@ -165,7 +174,7 @@ public class ContikiMoteType implements MoteType { } } - private final String[] sensors = { "button_sensor", "pir_sensor", "vib_sensor" }; + private final String[] sensors = {"button_sensor", "pir_sensor", "vib_sensor"}; private String identifier = null; private String description = null; @@ -175,10 +184,15 @@ public class ContikiMoteType implements MoteType { /* For internal use only: using during Contiki compilation. */ private File contikiApp = null; /* Contiki application: hello-world.c */ + public File libSource = null; /* JNI library: obj_cooja/mtype1.c */ + public File libFile = null; /* JNI library: obj_cooja/mtype1.lib */ + public File archiveFile = null; /* Contiki archive: obj_cooja/mtype1.a */ + public File mapFile = null; /* Contiki map: obj_cooja/mtype1.map */ + public String javaClassName = null; /* Loading Java class name: Lib1 */ private String[] coreInterfaces = null; @@ -197,6 +211,9 @@ public class ContikiMoteType implements MoteType { // Initial memory for all motes of this type private SectionMoteMemory initialMemory = null; + /** Offset between native (cooja) and contiki address space */ + long offset; + /** * Creates a new uninitialized Cooja mote type. This mote type needs to load * a library file and parse a map file before it can be used. @@ -204,23 +221,25 @@ public class ContikiMoteType implements MoteType { public ContikiMoteType() { } + @Override public Mote generateMote(Simulation simulation) { return new ContikiMote(this, simulation); } + @Override public boolean configureAndInit(Container parentContainer, Simulation simulation, - boolean visAvailable) throws MoteTypeCreationException { + boolean visAvailable) throws MoteTypeCreationException { myConfig = simulation.getCooja().getProjectConfig().clone(); if (visAvailable) { if (getDescription() == null) { - setDescription("Cooja Mote Type #" + (simulation.getMoteTypes().length+1)); + setDescription("Cooja Mote Type #" + (simulation.getMoteTypes().length + 1)); } /* Compile Contiki from dialog */ - boolean compileOK = - ContikiMoteCompileDialog.showDialog(parentContainer, simulation, this); + boolean compileOK + = ContikiMoteCompileDialog.showDialog(parentContainer, simulation, this); if (!compileOK) { return false; } @@ -236,17 +255,17 @@ public class ContikiMoteType implements MoteType { /* Create variables used for compiling Contiki */ contikiApp = getContikiSourceFile(); libSource = new File( - contikiApp.getParentFile(), - "obj_cooja/" + getIdentifier() + ".c"); + contikiApp.getParentFile(), + "obj_cooja/" + getIdentifier() + ".c"); libFile = new File( - contikiApp.getParentFile(), - "obj_cooja/" + getIdentifier() + librarySuffix); + contikiApp.getParentFile(), + "obj_cooja/" + getIdentifier() + librarySuffix); archiveFile = new File( - contikiApp.getParentFile(), - "obj_cooja/" + getIdentifier() + dependSuffix); + contikiApp.getParentFile(), + "obj_cooja/" + getIdentifier() + dependSuffix); mapFile = new File( - contikiApp.getParentFile(), - "obj_cooja/" + getIdentifier() + mapSuffix); + contikiApp.getParentFile(), + "obj_cooja/" + getIdentifier() + mapSuffix); javaClassName = CoreComm.getAvailableClassName(); if (javaClassName == null) { @@ -261,37 +280,36 @@ public class ContikiMoteType implements MoteType { /* Generate Contiki main source */ /*try { - CompileContiki.generateSourceFile( - libSource, - javaClassName, - getSensors(), - getCoreInterfaces() - ); - } catch (Exception e) { - throw (MoteTypeCreationException) new MoteTypeCreationException( - "Error when generating Contiki main source").initCause(e); - }*/ + CompileContiki.generateSourceFile( + libSource, + javaClassName, + getSensors(), + getCoreInterfaces() + ); + } catch (Exception e) { + throw (MoteTypeCreationException) new MoteTypeCreationException( + "Error when generating Contiki main source").initCause(e); + }*/ /* Prepare compiler environment */ String[][] env; try { env = CompileContiki.createCompilationEnvironment( - getIdentifier(), - contikiApp, - mapFile, - libFile, - archiveFile, - javaClassName); + getIdentifier(), + contikiApp, + mapFile, + libFile, + archiveFile, + javaClassName); CompileContiki.redefineCOOJASources( - this, - env + this, + env ); } catch (Exception e) { - throw (MoteTypeCreationException) new MoteTypeCreationException( - "Error when creating environment: " + e.getMessage()).initCause(e); + throw new MoteTypeCreationException("Error when creating environment: " + e.getMessage(), e); } String[] envOneDimension = new String[env.length]; - for (int i=0; i < env.length; i++) { + for (int i = 0; i < env.length; i++) { envOneDimension[i] = env[i][0] + "=" + env[i][1]; } @@ -299,33 +317,33 @@ public class ContikiMoteType implements MoteType { if (getCompileCommands() == null) { throw new MoteTypeCreationException("No compile commands specified"); } - final MessageList compilationOutput = new MessageList(); + final MessageListUI compilationOutput = new MessageListUI(); String[] arr = getCompileCommands().split("\n"); - for (String cmd: arr) { + for (String cmd : arr) { if (cmd.trim().isEmpty()) { continue; } try { CompileContiki.compile( - cmd, - envOneDimension, - null /* Do not observe output firmware file */, - getContikiSourceFile().getParentFile(), - null, - null, - compilationOutput, - true + cmd, + envOneDimension, + null /* Do not observe output firmware file */, + getContikiSourceFile().getParentFile(), + null, + null, + compilationOutput, + true ); } catch (Exception e) { - MoteTypeCreationException newException = - new MoteTypeCreationException("Mote type creation failed: " + e.getMessage()); + MoteTypeCreationException newException + = new MoteTypeCreationException("Mote type creation failed: " + e.getMessage()); newException = (MoteTypeCreationException) newException.initCause(e); newException.setCompilationOutput(compilationOutput); /* Print last 10 compilation errors to console */ MessageContainer[] messages = compilationOutput.getMessages(); - for (int i=messages.length-10; i < messages.length; i++) { + for (int i = messages.length - 10; i < messages.length; i++) { if (i < 0) { continue; } @@ -338,8 +356,8 @@ public class ContikiMoteType implements MoteType { } /* Make sure compiled firmware exists */ - if (getContikiFirmwareFile() == null || - !getContikiFirmwareFile().exists()) { + if (getContikiFirmwareFile() == null + || !getContikiFirmwareFile().exists()) { throw new MoteTypeCreationException("Contiki firmware file does not exist: " + getContikiFirmwareFile()); } } @@ -351,7 +369,7 @@ public class ContikiMoteType implements MoteType { public static File getExpectedFirmwareFile(File source) { File parentDir = source.getParentFile(); - String sourceNoExtension = source.getName().substring(0, source.getName().length()-2); + String sourceNoExtension = source.getName().substring(0, source.getName().length() - 2); return new File(parentDir, sourceNoExtension + librarySuffix); } @@ -359,8 +377,10 @@ public class ContikiMoteType implements MoteType { /** * For internal use. * - * This method creates a core communicator linking a Contiki library and a Java class. - * It furthermore parses library Contiki memory addresses and creates the initial memory. + * This method creates a core communicator linking a Contiki library and a + * Java class. + * It furthermore parses library Contiki memory addresses and creates the + * initial memory. * * @throws MoteTypeCreationException */ @@ -368,11 +388,11 @@ public class ContikiMoteType implements MoteType { if (myCoreComm != null) { throw new MoteTypeCreationException( - "Core communicator already used: " + myCoreComm.getClass().getName()); + "Core communicator already used: " + myCoreComm.getClass().getName()); } - if (getContikiFirmwareFile() == null || - !getContikiFirmwareFile().exists()) { + if (getContikiFirmwareFile() == null + || !getContikiFirmwareFile().exists()) { throw new MoteTypeCreationException("Library file could not be found: " + getContikiFirmwareFile()); } @@ -381,49 +401,53 @@ public class ContikiMoteType implements MoteType { } // Allocate core communicator class - logger.info("Creating core communicator between Java class '" + javaClassName + "' and Contiki library '" + getContikiFirmwareFile().getName() + "'"); + logger.info("Creating core communicator between Java class " + javaClassName + " and Contiki library '" + getContikiFirmwareFile().getPath() + ""); myCoreComm = CoreComm.createCoreComm(this.javaClassName, getContikiFirmwareFile()); - /* Parse addresses using map file or command */ + /* Parse addresses using map file + * or output of command specified in external tools settings (e.g. nm -a ) + */ boolean useCommand = Boolean.parseBoolean(Cooja.getExternalToolsSetting("PARSE_WITH_COMMAND", "false")); - int dataSectionAddr = -1, dataSectionSize = -1; - int bssSectionAddr = -1, bssSectionSize = -1; - int commonSectionAddr = -1, commonSectionSize = -1; - int readonlySectionAddr = -1, readonlySectionSize = -1; + SectionParser dataSecParser; + SectionParser bssSecParser; + SectionParser commonSecParser; + SectionParser readonlySecParser = null; - HashMap addresses = new HashMap(); + HashMap variables = new HashMap<>(); if (useCommand) { /* Parse command output */ String[] output = loadCommandData(getContikiFirmwareFile()); if (output == null) { throw new MoteTypeCreationException("No parse command output loaded"); } - boolean parseOK = parseCommandData(output, addresses); - if (!parseOK) { - logger.fatal("Command output parsing failed"); - throw new MoteTypeCreationException("Command output parsing failed"); - } - dataSectionAddr = parseCommandDataSectionAddr(output); - dataSectionSize = parseCommandDataSectionSize(output); - bssSectionAddr = parseCommandBssSectionAddr(output); - bssSectionSize = parseCommandBssSectionSize(output); - commonSectionAddr = parseCommandCommonSectionAddr(output); - commonSectionSize = parseCommandCommonSectionSize(output); - - try { - readonlySectionAddr = parseCommandReadonlySectionAddr(output); - readonlySectionSize = parseCommandReadonlySectionSize(output); - } catch (Exception e) { - readonlySectionAddr = -1; - readonlySectionSize = -1; - } + dataSecParser = new CommandSectionParser( + output, + Cooja.getExternalToolsSetting("COMMAND_DATA_START"), + Cooja.getExternalToolsSetting("COMMAND_DATA_END"), + Cooja.getExternalToolsSetting("COMMAND_VAR_SEC_DATA")); + bssSecParser = new CommandSectionParser( + output, + Cooja.getExternalToolsSetting("COMMAND_BSS_START"), + Cooja.getExternalToolsSetting("COMMAND_BSS_END"), + Cooja.getExternalToolsSetting("COMMAND_VAR_SEC_BSS")); + commonSecParser = new CommandSectionParser( + output, + Cooja.getExternalToolsSetting("COMMAND_COMMON_START"), + Cooja.getExternalToolsSetting("COMMAND_COMMON_END"), + Cooja.getExternalToolsSetting("COMMAND_VAR_SEC_COMMON")); + /* XXX Currently Cooja tries to sync readonly memory */ + readonlySecParser = null;/* new CommandSectionParser( + output, + Cooja.getExternalToolsSetting("COMMAND_READONLY_START"), + Cooja.getExternalToolsSetting("COMMAND_READONLY_END"), + Cooja.getExternalToolsSetting("COMMAND_VAR_SEC_READONLY"));*/ } else { - /* Parse command output */ - if (mapFile == null || - !mapFile.exists()) { + /* Parse map file */ + if (mapFile == null + || !mapFile.exists()) { throw new MoteTypeCreationException("Map file " + mapFile + " could not be found"); } String[] mapData = loadMapFile(mapFile); @@ -431,111 +455,332 @@ public class ContikiMoteType implements MoteType { logger.fatal("No map data could be loaded"); throw new MoteTypeCreationException("No map data could be loaded: " + mapFile); } - boolean parseOK = parseMapFileData(mapData, addresses); - if (!parseOK) { - logger.fatal("Map data parsing failed"); - throw new MoteTypeCreationException("Map data parsing failed: " + mapFile); - } - dataSectionAddr = parseMapDataSectionAddr(mapData); - dataSectionSize = parseMapDataSectionSize(mapData); - bssSectionAddr = parseMapBssSectionAddr(mapData); - bssSectionSize = parseMapBssSectionSize(mapData); - commonSectionAddr = parseMapCommonSectionAddr(mapData); - commonSectionSize = parseMapCommonSectionSize(mapData); - readonlySectionAddr = -1; - readonlySectionSize = -1; + dataSecParser = new MapSectionParser( + mapData, + Cooja.getExternalToolsSetting("MAPFILE_DATA_START"), + Cooja.getExternalToolsSetting("MAPFILE_DATA_SIZE")); + bssSecParser = new MapSectionParser( + mapData, + Cooja.getExternalToolsSetting("MAPFILE_BSS_START"), + Cooja.getExternalToolsSetting("MAPFILE_BSS_SIZE")); + commonSecParser = new MapSectionParser( + mapData, + Cooja.getExternalToolsSetting("MAPFILE_COMMON_START"), + Cooja.getExternalToolsSetting("MAPFILE_COMMON_SIZE")); + readonlySecParser = null; } - if (dataSectionAddr >= 0) { - logger.info(getContikiFirmwareFile().getName() + - ": data section at 0x" + Integer.toHexString(dataSectionAddr) + - " (" + dataSectionSize + " == 0x" + Integer.toHexString(dataSectionSize) + " bytes)"); - } else { - logger.fatal(getContikiFirmwareFile().getName() + ": no data section found"); - } - if (bssSectionAddr >= 0) { - logger.info(getContikiFirmwareFile().getName() + - ": BSS section at 0x" + Integer.toHexString(bssSectionAddr) + - " (" + bssSectionSize + " == 0x" + Integer.toHexString(bssSectionSize) + " bytes)"); - } else { - logger.fatal(getContikiFirmwareFile().getName() + ": no BSS section found"); - } - if (commonSectionAddr >= 0) { - logger.info(getContikiFirmwareFile().getName() + - ": common section at 0x" + Integer.toHexString(commonSectionAddr) + - " (" + commonSectionSize + " == 0x" + Integer.toHexString(commonSectionSize) + " bytes)"); - } else { - logger.info(getContikiFirmwareFile().getName() + ": no common section found"); - } - if (readonlySectionAddr >= 0) { - logger.info(getContikiFirmwareFile().getName() + - ": readonly section at 0x" + Integer.toHexString(readonlySectionAddr) + - " (" + readonlySectionSize + " == 0x" + Integer.toHexString(readonlySectionSize) + " bytes)"); - } else { - logger.warn(getContikiFirmwareFile().getName() + ": no readonly section found"); - } - if (addresses.size() == 0) { - throw new MoteTypeCreationException("Library variables parsing failed"); - } - if (dataSectionAddr <= 0 || dataSectionSize <= 0 - || bssSectionAddr <= 0 || bssSectionSize <= 0) { - throw new MoteTypeCreationException("Library section addresses parsing failed"); - } - - try { - /* Relative <-> absolute addresses offset */ - int referenceVar = addresses.get("referenceVar"); - myCoreComm.setReferenceAddress(referenceVar); - } catch (Exception e) { - throw (MoteTypeCreationException) new MoteTypeCreationException( - "JNI call error: " + e.getMessage()).initCause(e); - } - /* We first need the value of Contiki's referenceVar, which tells us the * memory offset between Contiki's variable and the relative addresses that * were calculated directly from the library file. * * This offset will be used in Cooja in the memory abstraction to match * Contiki's and Cooja's address spaces */ - int offset; { - SectionMoteMemory tmp = new SectionMoteMemory(addresses, 0); - byte[] data = new byte[dataSectionSize]; - getCoreMemory(dataSectionAddr, dataSectionSize, data); - tmp.setMemorySegment(dataSectionAddr, data); - byte[] bss = new byte[bssSectionSize]; - getCoreMemory(bssSectionAddr, bssSectionSize, bss); - tmp.setMemorySegment(bssSectionAddr, bss); + SectionMoteMemory tmp = new SectionMoteMemory(variables); + VarMemory varMem = new VarMemory(tmp); + tmp.addMemorySection("tmp.data", dataSecParser.parse(0)); - offset = tmp.getIntValueOf("referenceVar"); - logger.info(getContikiFirmwareFile().getName() + - ": offsetting Cooja mote address space: " + offset); + tmp.addMemorySection("tmp.bss", bssSecParser.parse(0)); + + try { + int referenceVar = (int) varMem.getVariable("referenceVar").addr; + myCoreComm.setReferenceAddress(referenceVar); + } catch (UnknownVariableException e) { + throw new MoteTypeCreationException("Error setting reference variable: " + e.getMessage(), e); + } catch (RuntimeException e) { + throw new MoteTypeCreationException("Error setting reference variable: " + e.getMessage(), e); + } + + getCoreMemory(tmp); + + offset = varMem.getIntValueOf("referenceVar") & 0xFFFFFFFFL; + logger.info(getContikiFirmwareFile().getName() + + ": offsetting Cooja mote address space: 0x" + Long.toHexString(offset)); } /* Create initial memory: data+bss+optional common */ - initialMemory = new SectionMoteMemory(addresses, offset); + initialMemory = new SectionMoteMemory(variables); - byte[] initialDataSection = new byte[dataSectionSize]; - getCoreMemory(dataSectionAddr, dataSectionSize, initialDataSection); - initialMemory.setMemorySegmentNative(dataSectionAddr, initialDataSection); + initialMemory.addMemorySection("data", dataSecParser.parse(offset)); - byte[] initialBssSection = new byte[bssSectionSize]; - getCoreMemory(bssSectionAddr, bssSectionSize, initialBssSection); - initialMemory.setMemorySegmentNative(bssSectionAddr, initialBssSection); + initialMemory.addMemorySection("bss", bssSecParser.parse(offset)); - if (commonSectionAddr >= 0 && commonSectionSize > 0) { - byte[] initialCommonSection = new byte[commonSectionSize]; - getCoreMemory(commonSectionAddr, commonSectionSize, initialCommonSection); - initialMemory.setMemorySegmentNative(commonSectionAddr, initialCommonSection); + initialMemory.addMemorySection("common", commonSecParser.parse(offset)); + + if (readonlySecParser != null) { + initialMemory.addMemorySection("readonly", readonlySecParser.parse(offset)); } - /* Read "read-only" memory */ - if (readonlySectionAddr >= 0 && readonlySectionSize > 0) { - byte[] readonlySection = new byte[readonlySectionSize]; - getCoreMemory(readonlySectionAddr, readonlySectionSize, readonlySection); - initialMemory.setReadonlyMemorySegment(readonlySectionAddr+offset, readonlySection); + getCoreMemory(initialMemory); + } + + /** + * Abstract base class for concrete section parser class. + */ + public static abstract class SectionParser { + + private final String[] mapFileData; + protected int startAddr; + protected int size; + + public SectionParser(String[] mapFileData) { + this.mapFileData = mapFileData; + } + + public String[] getData() { + return mapFileData; + } + + public int getStartAddr() { + return startAddr; + } + + public int getSize() { + return size; + } + + protected abstract void parseStartAddr(); + + protected abstract void parseSize(); + + abstract Map parseSymbols(long offset); + + protected int parseFirstHexInt(String regexp, String[] data) { + String retString = getFirstMatchGroup(data, regexp, 1); + + if (retString == null || retString.equals("")) { + return -1; + } + + return Integer.parseInt(retString.trim(), 16); + } + + public MemoryInterface parse(long offset) { + + /* Parse start address and size of section */ + parseStartAddr(); + parseSize(); + + if (getStartAddr() < 0 || getSize() <= 0) { + return null; + } + + Map variables = parseSymbols(offset); + + logger.info(String.format("Parsed section at 0x%x ( %d == 0x%x bytes)", + getStartAddr() + offset, + getSize(), + getSize())); + + if (logger.isDebugEnabled()) { + for (String var : variables.keySet()) { + logger.debug(String.format("Found Symbol: %s, 0x%x, %d", + var, + variables.get(var).addr, + variables.get(var).size)); + } + } + + return new ArrayMemory( + getStartAddr() + offset, + getSize(), + MemoryLayout.getNative(), + variables); + } + + } + + /** + * Parses Map file for seciton data. + */ + public static class MapSectionParser extends SectionParser { + + private final String startRegExp; + private final String sizeRegExp; + + public MapSectionParser(String[] mapFileData, String startRegExp, String sizeRegExp) { + super(mapFileData); + this.startRegExp = startRegExp; + this.sizeRegExp = sizeRegExp; + } + + @Override + protected void parseStartAddr() { + if (startRegExp == null || startRegExp.equals("")) { + startAddr = -1; + return; + } + startAddr = parseFirstHexInt(startRegExp, getData()); + } + + @Override + protected void parseSize() { + if (sizeRegExp == null || sizeRegExp.equals("")) { + size = -1; + return; + } + size = parseFirstHexInt(sizeRegExp, getData()); + } + + @Override + public Map parseSymbols(long offset) { + Map varNames = new HashMap<>(); + + Pattern pattern = Pattern.compile(Cooja.getExternalToolsSetting("MAPFILE_VAR_NAME")); + for (String line : getData()) { + Matcher matcher = pattern.matcher(line); + if (matcher.find()) { + if (Integer.decode(matcher.group(1)).intValue() >= getStartAddr() + && Integer.decode(matcher.group(1)).intValue() <= getStartAddr() + getSize()) { + String varName = matcher.group(2); + varNames.put(varName, new Symbol( + Symbol.Type.VARIABLE, + varName, + getMapFileVarAddress(getData(), varName) + offset, + getMapFileVarSize(getData(), varName))); + } + } + } + return varNames; + } + + /** + * Get relative address of variable with given name. + * + * @param varName Name of variable + * @return Relative memory address of variable or -1 if not found + */ + private int getMapFileVarAddress(String[] mapFileData, String varName) { + + String regExp = Cooja.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_1") + + varName + + Cooja.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_2"); + String retString = getFirstMatchGroup(mapFileData, regExp, 1); + + if (retString != null) { + return Integer.parseInt(retString.trim(), 16); + } else { + return -1; + } + } + + private int getMapFileVarSize(String[] mapFileData, String varName) { + Pattern pattern = Pattern.compile( + Cooja.getExternalToolsSetting("MAPFILE_VAR_SIZE_1") + + varName + + Cooja.getExternalToolsSetting("MAPFILE_VAR_SIZE_2")); + for (int idx = 0; idx < mapFileData.length; idx++) { + String parseString = mapFileData[idx]; + Matcher matcher = pattern.matcher(parseString); + if (matcher.find()) { + return Integer.decode(matcher.group(1)); + } + // second approach with lines joined + if (idx < mapFileData.length - 1) { + parseString += mapFileData[idx + 1]; + } + matcher = pattern.matcher(parseString); + if (matcher.find()) { + return Integer.decode(matcher.group(1)); + } + } + return -1; + } + } + + /** + * Parses command output for section data. + */ + public static class CommandSectionParser extends SectionParser { + + private final String startRegExp; + private final String endRegExp; + private final String sectionRegExp; + + /** + * Creates SectionParser based on output of configurable command. + * + * @param mapFileData Map file lines as array of String + * @param startRegExp Regular expression for parsing start of section + * @param endRegExp Regular expression for parsing end of section + * @param sectionRegExp Reqular expression describing symbol table section identifier (e.g. '[Rr]' for readonly) + * Will be used to replaced '

    'in 'COMMAND_VAR_NAME_ADDRESS_SIZE' + */ + public CommandSectionParser(String[] mapFileData, String startRegExp, String endRegExp, String sectionRegExp) { + super(mapFileData); + this.startRegExp = startRegExp; + this.endRegExp = endRegExp; + this.sectionRegExp = sectionRegExp; + } + + @Override + protected void parseStartAddr() { + if (startRegExp == null || startRegExp.equals("")) { + startAddr = -1; + return; + } + startAddr = parseFirstHexInt(startRegExp, getData()); + } + + @Override + public void parseSize() { + if (endRegExp == null || endRegExp.equals("")) { + size = -1; + return; + } + + if (getStartAddr() < 0) { + size = -1; + return; + } + + int end = parseFirstHexInt(endRegExp, getData()); + if (end < 0) { + size = -1; + return; + } + size = end - getStartAddr(); + } + + @Override + public Map parseSymbols(long offset) { + HashMap addresses = new HashMap<>(); + /* Replace "
    " in regexp by section specific regex */ + Pattern pattern = Pattern.compile( + Cooja.getExternalToolsSetting("COMMAND_VAR_NAME_ADDRESS_SIZE") + .replace("
    ", sectionRegExp)); + + for (String line : getData()) { + Matcher matcher = pattern.matcher(line); + + if (matcher.find()) { + /* Line matched variable address */ + String symbol = matcher.group(1); + long varAddr = Integer.parseInt(matcher.group(2), 16) + offset; + int varSize; + if (matcher.group(3) != null) { + varSize = Integer.parseInt(matcher.group(3), 16); + } else { + varSize = -1; + } + + /* XXX needs to be checked */ + if (!addresses.containsKey(symbol)) { + addresses.put(symbol, new Symbol(Symbol.Type.VARIABLE, symbol, varAddr, varSize)); + } else { + int oldAddress = (int) addresses.get(symbol).addr; + if (oldAddress != varAddr) { + /*logger.warn("Warning, command response not matching previous entry of: " + + varName);*/ + } + } + } + } + + return addresses; } } @@ -558,97 +803,6 @@ public class ContikiMoteType implements MoteType { return initialMemory.clone(); } - /** - * Copy given memory to the Contiki system. This should not be used directly, - * but instead via ContikiMote.setMemory(). - * - * @param mem - * New memory - */ - public void setCoreMemory(SectionMoteMemory mem) { - for (int i = 0; i < mem.getNumberOfSections(); i++) { - setCoreMemory( - mem.getSectionNativeAddress(i) /* native address space */, - mem.getSizeOfSection(i), mem.getDataOfSection(i)); - } - } - - /** - * Parses specified map file data for variable name to addresses mappings. The - * mappings are added to the given properties object. - * - * @param mapFileData - * Contents of entire map file - * @param varAddresses - * Properties that should contain the name to addresses mappings. - */ - public static boolean parseMapFileData(String[] mapFileData, HashMap varAddresses) { - String[] varNames = getMapFileVarNames(mapFileData); - if (varNames == null || varNames.length == 0) { - return false; - } - - for (String varName : varNames) { - int varAddress = getMapFileVarAddress(mapFileData, varName, varAddresses); - if (varAddress > 0) { - varAddresses.put(varName, new Integer(varAddress)); - } else { - logger.warn("Parsed Contiki variable '" + varName - + "' but could not find address"); - } - } - - return true; - } - - /** - * Parses parse command output for variable name to addresses mappings. - * The mappings are written to the given properties object. - * - * @param output Command output - * @param addresses Variable addresses mappings - */ - public static boolean parseCommandData(String[] output, HashMap addresses) { - int nrNew = 0, nrOld = 0, nrMismatch = 0; - - Pattern pattern = - Pattern.compile(Cooja.getExternalToolsSetting("COMMAND_VAR_NAME_ADDRESS")); - - for (String line : output) { - Matcher matcher = pattern.matcher(line); - - if (matcher.find()) { - /* Line matched variable address */ - String symbol = matcher.group(2); - int address = Integer.parseInt(matcher.group(1), 16); - - if (!addresses.containsKey(symbol)) { - nrNew++; - addresses.put(symbol, new Integer(address)); - } else { - int oldAddress = addresses.get(symbol); - if (oldAddress != address) { - /*logger.warn("Warning, command response not matching previous entry of: " - + varName);*/ - nrMismatch++; - } - nrOld++; - } - } - } - - /*if (nrMismatch > 0) { - logger.debug("Command response parsing summary: Added " + nrNew - + " variables. Found " + nrOld - + " old variables. Mismatching addresses: " + nrMismatch); - } else { - logger.debug("Command response parsing summary: Added " + nrNew - + " variables. Found " + nrOld + " old variables"); - }*/ - - return (nrNew + nrOld) > 0; - } - /** * Copy core memory to given memory. This should not be used directly, but * instead via ContikiMote.getMemory(). @@ -657,42 +811,74 @@ public class ContikiMoteType implements MoteType { * Memory to set */ public void getCoreMemory(SectionMoteMemory mem) { - for (int i = 0; i < mem.getNumberOfSections(); i++) { - int startAddr = mem.getSectionNativeAddress(i); /* native address space */ - int size = mem.getSizeOfSection(i); - byte[] data = mem.getDataOfSection(i); - getCoreMemory(startAddr, size, data); + for (MemoryInterface section : mem.getSections().values()) { + getCoreMemory( + (int) (section.getStartAddr() - offset), + section.getTotalSize(), + section.getMemory()); } } + private void getCoreMemory(int relAddr, int length, byte[] data) { + myCoreComm.getMemory(relAddr, length, data); + } + + /** + * Copy given memory to the Contiki system. This should not be used directly, + * but instead via ContikiMote.setMemory(). + * + * @param mem + * New memory + */ + public void setCoreMemory(SectionMoteMemory mem) { + for (MemoryInterface section : mem.getSections().values()) { + setCoreMemory( + (int) (section.getStartAddr() - offset), + section.getTotalSize(), + section.getMemory()); + } + } + + private void setCoreMemory(int relAddr, int length, byte[] mem) { + myCoreComm.setMemory(relAddr, length, mem); + } + + @Override public String getIdentifier() { return identifier; } + @Override public void setIdentifier(String identifier) { this.identifier = identifier; } + @Override public File getContikiSourceFile() { return fileSource; } + @Override public void setContikiSourceFile(File file) { fileSource = file; } + @Override public File getContikiFirmwareFile() { return fileFirmware; } + @Override public void setContikiFirmwareFile(File file) { fileFirmware = file; } + @Override public String getCompileCommands() { return compileCommands; } + @Override public void setCompileCommands(String commands) { this.compileCommands = commands; } @@ -725,42 +911,10 @@ public class ContikiMoteType implements MoteType { return netStack; } - /** - * Get relative address of variable with given name. - * - * @param varName Name of variable - * @return Relative memory address of variable or -1 if not found - */ - private static int getMapFileVarAddress(String[] mapFileData, String varName, HashMap varAddresses) { - Integer varAddrInteger; - if ((varAddrInteger = varAddresses.get(varName)) != null) { - return varAddrInteger.intValue(); - } - - String regExp = - Cooja.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_1") + - varName + - Cooja.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_2"); - String retString = getFirstMatchGroup(mapFileData, regExp, 1); - - if (retString != null) { - varAddrInteger = Integer.parseInt(retString.trim(), 16); - varAddresses.put(varName, varAddrInteger); - return varAddrInteger.intValue(); - } else { - return -1; - } - } - - private void getCoreMemory(int relAddr, int length, byte[] data) { - myCoreComm.getMemory(relAddr, length, data); - } - - private void setCoreMemory(int relAddr, int length, byte[] mem) { - myCoreComm.setMemory(relAddr, length, mem); - } - private static String getFirstMatchGroup(String[] lines, String regexp, int groupNr) { + if (regexp == null) { + return null; + } Pattern pattern = Pattern.compile(regexp); for (String line : lines) { Matcher matcher = pattern.matcher(line); @@ -771,219 +925,6 @@ public class ContikiMoteType implements MoteType { return null; } - /** - * Returns all variable names in both data and BSS section by parsing the map - * file. These values should not be trusted completely as the parsing may - * fail. - * - * @return Variable names found in the data and bss section - */ - public static String[] getMapFileVarNames(String[] mapFileData) { - ArrayList varNames = new ArrayList(); - - String[] dataVariables = getAllVariableNames( - mapFileData, - parseMapDataSectionAddr(mapFileData), - parseMapDataSectionAddr(mapFileData) + parseMapDataSectionSize(mapFileData)); - for (String v: dataVariables) { - varNames.add(v); - } - - String[] bssVariables = getAllVariableNames( - mapFileData, - parseMapBssSectionAddr(mapFileData), - parseMapBssSectionAddr(mapFileData) + parseMapBssSectionSize(mapFileData)); - for (String v: bssVariables) { - varNames.add(v); - } - - return varNames.toArray(new String[0]); - } - - private static String[] getAllVariableNames(String[] lines, - int startAddress, int endAddress) { - ArrayList varNames = new ArrayList(); - - Pattern pattern = Pattern.compile(Cooja.getExternalToolsSetting("MAPFILE_VAR_NAME")); - for (String line : lines) { - Matcher matcher = pattern.matcher(line); - if (matcher.find()) { - if (Integer.decode(matcher.group(1)).intValue() >= startAddress - && Integer.decode(matcher.group(1)).intValue() <= endAddress) { - varNames.add(matcher.group(2)); - } - } - } - return varNames.toArray(new String[0]); - } - - protected int getVariableSize(Vector lines, String varName) { - Pattern pattern = Pattern.compile( - Cooja.getExternalToolsSetting("MAPFILE_VAR_SIZE_1") + - varName + - Cooja.getExternalToolsSetting("MAPFILE_VAR_SIZE_2")); - for (int i = 0; i < lines.size(); i++) { - Matcher matcher = pattern.matcher(lines.get(i)); - if (matcher.find()) { - return Integer.decode(matcher.group(1)); - } - } - return -1; - } - - private static int parseFirstHexInt(String regexp, String[] data) { - String retString = - getFirstMatchGroup(data, regexp, 1); - - if (retString != null) { - return Integer.parseInt(retString.trim(), 16); - } else { - return -1; - } - } - - public static int parseMapDataSectionAddr(String[] mapFileData) { - String regexp = Cooja.getExternalToolsSetting("MAPFILE_DATA_START", ""); - if (regexp.equals("")) { - return -1; - } - return parseFirstHexInt(regexp, mapFileData); - } - public static int parseMapDataSectionSize(String[] mapFileData) { - String regexp = Cooja.getExternalToolsSetting("MAPFILE_DATA_SIZE", ""); - if (regexp.equals("")) { - return -1; - } - return parseFirstHexInt(regexp, mapFileData); - } - public static int parseMapBssSectionAddr(String[] mapFileData) { - String regexp = Cooja.getExternalToolsSetting("MAPFILE_BSS_START", ""); - if (regexp.equals("")) { - return -1; - } - return parseFirstHexInt(regexp, mapFileData); - } - public static int parseMapBssSectionSize(String[] mapFileData) { - String regexp = Cooja.getExternalToolsSetting("MAPFILE_BSS_SIZE", ""); - if (regexp.equals("")) { - return -1; - } - return parseFirstHexInt(regexp, mapFileData); - } - public static int parseMapCommonSectionAddr(String[] mapFileData) { - String regexp = Cooja.getExternalToolsSetting("MAPFILE_COMMON_START", ""); - if (regexp.equals("")) { - return -1; - } - return parseFirstHexInt(regexp, mapFileData); - } - public static int parseMapCommonSectionSize(String[] mapFileData) { - String regexp = Cooja.getExternalToolsSetting("MAPFILE_COMMON_SIZE", ""); - if (regexp.equals("")) { - return -1; - } - return parseFirstHexInt(regexp, mapFileData); - } - - public static int parseCommandDataSectionAddr(String[] output) { - String regexp = Cooja.getExternalToolsSetting("COMMAND_DATA_START", ""); - if (regexp.equals("")) { - return -1; - } - return parseFirstHexInt(regexp, output); - } - public static int parseCommandDataSectionSize(String[] output) { - String regexp = Cooja.getExternalToolsSetting("COMMAND_DATA_END", ""); - if (regexp.equals("")) { - return -1; - } - int start = parseCommandDataSectionAddr(output); - if (start < 0) { - return -1; - } - - int end = parseFirstHexInt(regexp, output); - if (end < 0) { - return -1; - } - return end - start; - } - public static int parseCommandBssSectionAddr(String[] output) { - String regexp = Cooja.getExternalToolsSetting("COMMAND_BSS_START", ""); - if (regexp.equals("")) { - return -1; - } - return parseFirstHexInt(regexp, output); - } - public static int parseCommandBssSectionSize(String[] output) { - String regexp = Cooja.getExternalToolsSetting("COMMAND_BSS_END", ""); - if (regexp.equals("")) { - return -1; - } - int start = parseCommandBssSectionAddr(output); - if (start < 0) { - return -1; - } - - int end = parseFirstHexInt(regexp, output); - if (end < 0) { - return -1; - } - return end - start; - } - public static int parseCommandCommonSectionAddr(String[] output) { - String regexp = Cooja.getExternalToolsSetting("COMMAND_COMMON_START", ""); - if (regexp.equals("")) { - return -1; - } - return parseFirstHexInt(regexp, output); - } - public static int parseCommandCommonSectionSize(String[] output) { - String regexp = Cooja.getExternalToolsSetting("COMMAND_COMMON_END", ""); - if (regexp.equals("")) { - return -1; - } - int start = parseCommandCommonSectionAddr(output); - if (start < 0) { - return -1; - } - - int end = parseFirstHexInt(regexp, output); - if (end < 0) { - return -1; - } - return end - start; - } - - private static int parseCommandReadonlySectionAddr(String[] output) { - return parseFirstHexInt("^([0-9A-Fa-f]*)[ \t]t[ \t].text$", output); - } - private static int parseCommandReadonlySectionSize(String[] output) { - int start = parseCommandReadonlySectionAddr(output); - if (start < 0) { - return -1; - } - - /* Extract the last specified address, assuming that the interval covers all the memory */ - String last = output[output.length-1]; - int lastAddress = Integer.parseInt(last.split("[ \t]")[0],16); - return lastAddress - start; - } - - private static int getRelVarAddr(String mapFileData[], String varName) { - String regExp = - Cooja.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_1") + - varName + - Cooja.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_2"); - String retString = getFirstMatchGroup(mapFileData, regExp, 1); - - if (retString != null) { - return Integer.parseInt(retString.trim(), 16); - } else { - return -1; - } - } - public static String[] loadMapFile(File mapFile) { String contents = StringUtils.loadFromFile(mapFile); if (contents == null) { @@ -999,7 +940,7 @@ public class ContikiMoteType implements MoteType { * @return Execution response, or null at failure */ public static String[] loadCommandData(File libraryFile) { - ArrayList output = new ArrayList(); + ArrayList output = new ArrayList<>(); try { String command = Cooja.getExternalToolsSetting("PARSE_COMMAND"); @@ -1009,17 +950,17 @@ public class ContikiMoteType implements MoteType { /* Prepare command */ command = command.replace("$(LIBFILE)", - libraryFile.getName().replace(File.separatorChar, '/')); + libraryFile.getName().replace(File.separatorChar, '/')); /* Execute command, read response */ String line; Process p = Runtime.getRuntime().exec( - command.split(" "), - null, - libraryFile.getParentFile() + command.split(" "), + null, + libraryFile.getParentFile() ); BufferedReader input = new BufferedReader( - new InputStreamReader(p.getInputStream()) + new InputStreamReader(p.getInputStream()) ); p.getErrorStream().close(); while ((line = input.readLine()) != null) { @@ -1027,24 +968,27 @@ public class ContikiMoteType implements MoteType { } input.close(); - if (output == null || output.size() == 0) { + if (output == null || output.isEmpty()) { return null; } return output.toArray(new String[0]); - } catch (Exception err) { + } catch (IOException err) { logger.fatal("Command error: " + err.getMessage(), err); return null; } } + @Override public String getDescription() { return description; } + @Override public void setDescription(String newDescription) { description = newDescription; } + @Override public ProjectConfig getConfig() { return myConfig; } @@ -1054,7 +998,7 @@ public class ContikiMoteType implements MoteType { * simulator project configuration. * * @param moteTypeConfig - * Project configuration + * Project configuration */ public void setConfig(ProjectConfig moteTypeConfig) { myConfig = moteTypeConfig; @@ -1082,12 +1026,13 @@ public class ContikiMoteType implements MoteType { * Set core interfaces * * @param coreInterfaces - * New core interfaces + * New core interfaces */ public void setCoreInterfaces(String[] coreInterfaces) { this.coreInterfaces = coreInterfaces; } + @Override public Class[] getMoteInterfaceClasses() { if (moteInterfacesClasses == null) { return null; @@ -1097,11 +1042,10 @@ public class ContikiMoteType implements MoteType { return arr; } + @Override public void setMoteInterfaceClasses(Class[] moteInterfaces) { - this.moteInterfacesClasses = new ArrayList>(); - for (Class intf: moteInterfaces) { - this.moteInterfacesClasses.add(intf); - } + this.moteInterfacesClasses = new ArrayList<>(); + this.moteInterfacesClasses.addAll(Arrays.asList(moteInterfaces)); } /** @@ -1109,7 +1053,7 @@ public class ContikiMoteType implements MoteType { * when loading a saved simulation. * * @param file - * File containg data to checksum + * File containg data to checksum * @return Checksum */ protected byte[] createChecksum(File file) { @@ -1128,9 +1072,7 @@ public class ContikiMoteType implements MoteType { } } fileInputStream.close(); - } catch (NoSuchAlgorithmException e) { - return null; - } catch (IOException e) { + } catch (NoSuchAlgorithmException | IOException e) { return null; } return messageDigest.digest(); @@ -1177,8 +1119,8 @@ public class ContikiMoteType implements MoteType { // Check if identifier library has been loaded /* XXX Currently only checks the build directory! */ File libraryFile = new File( - ContikiMoteType.tempOutputDirectory, - testID + ContikiMoteType.librarySuffix); + ContikiMoteType.tempOutputDirectory, + testID + ContikiMoteType.librarySuffix); if (libraryFile.exists() || CoreComm.hasLibraryFileBeenLoaded(libraryFile)) { okID = false; } @@ -1192,45 +1134,46 @@ public class ContikiMoteType implements MoteType { * * @return Mote type visualizer */ + @Override public JComponent getTypeVisualizer() { StringBuilder sb = new StringBuilder(); // Identifier sb.append(""); + .append(getIdentifier()).append(""); // Description sb.append(""); + .append(getDescription()).append(""); /* Contiki application */ sb.append(""); + .append(getContikiSourceFile().getAbsolutePath()).append(""); /* Contiki firmware */ sb.append(""); + .append(getContikiFirmwareFile().getAbsolutePath()).append(""); /* JNI class */ sb.append(""); + .append(this.javaClassName).append(""); /* Contiki sensors */ sb.append(""); /* Mote interfaces */ sb.append(""); /* Contiki core mote interfaces */ sb.append(""); @@ -1240,8 +1183,9 @@ public class ContikiMoteType implements MoteType { return label; } + @Override public Collection getConfigXML(Simulation simulation) { - ArrayList config = new ArrayList(); + ArrayList config = new ArrayList<>(); Element element; element = new Element("identifier"); @@ -1280,9 +1224,10 @@ public class ContikiMoteType implements MoteType { return config; } + @Override public boolean setConfigXML(Simulation simulation, - Collection configXML, boolean visAvailable) - throws MoteTypeCreationException { + Collection configXML, boolean visAvailable) + throws MoteTypeCreationException { boolean warnedOldVersion = false; File oldVersionSource = null; @@ -1290,91 +1235,87 @@ public class ContikiMoteType implements MoteType { for (Element element : configXML) { String name = element.getName(); - - if (name.equals("identifier")) { - identifier = element.getText(); - } else if (name.equals("description")) { - description = element.getText(); - } else if (name.equals("contikiapp") || name.equals("source")) { - File file = new File(element.getText()); - if (!file.exists()) { - file = simulation.getCooja().restorePortablePath(file); - } - - setContikiSourceFile(file); - - /* XXX Do not load the generated firmware. Instead, load the unique library file directly */ + switch (name) { + case "identifier": + identifier = element.getText(); + break; + case "description": + description = element.getText(); + break; + case "contikiapp": + case "source": + File file = new File(element.getText()); + if (!file.exists()) { + file = simulation.getCooja().restorePortablePath(file); + } setContikiSourceFile(file); + /* XXX Do not load the generated firmware. Instead, load the unique library file directly */ File contikiFirmware = new File( - getContikiSourceFile().getParentFile(), - "obj_cooja/" + getIdentifier() + librarySuffix); - setContikiFirmwareFile(contikiFirmware); - - } else if (name.equals("commands")) { - compileCommands = element.getText(); - } else if (name.equals("symbols")) { - hasSystemSymbols = Boolean.parseBoolean(element.getText()); - } else if (name.equals("commstack")) { - logger.warn("The Cooja communication stack config was removed: " + element.getText()); - logger.warn("Instead assuming default network stack."); - netStack = NetworkStack.DEFAULT; - } else if (name.equals("netstack")) { - netStack = NetworkStack.parseConfig(element.getText()); - } else if (name.equals("moteinterface")) { - String intfClass = element.getText().trim(); - - /* Backwards compatibility: se.sics -> org.contikios */ - if (intfClass.startsWith("se.sics")) { - intfClass = intfClass.replaceFirst("se\\.sics", "org.contikios"); - } - - Class moteInterfaceClass = - simulation.getCooja().tryLoadClass( - this, MoteInterface.class, intfClass); - + getContikiSourceFile().getParentFile(), + "obj_cooja/" + getIdentifier() + librarySuffix); + setContikiFirmwareFile(contikiFirmware); + break; + case "commands": + compileCommands = element.getText(); + break; + case "symbols": + hasSystemSymbols = Boolean.parseBoolean(element.getText()); + break; + case "commstack": + logger.warn("The Cooja communication stack config was removed: " + element.getText()); + logger.warn("Instead assuming default network stack."); + netStack = NetworkStack.DEFAULT; + break; + case "netstack": + netStack = NetworkStack.parseConfig(element.getText()); + break; + case "moteinterface": + String intfClass = element.getText().trim(); + /* Backwards compatibility: se.sics -> org.contikios */ + if (intfClass.startsWith("se.sics")) { + intfClass = intfClass.replaceFirst("se\\.sics", "org.contikios"); + } Class moteInterfaceClass + = simulation.getCooja().tryLoadClass( + this, MoteInterface.class, intfClass); if (moteInterfaceClass == null) { logger.warn("Can't find mote interface class: " + intfClass); } else { moteInterfacesClasses.add(moteInterfaceClass); - } - } else if ( - name.equals("contikibasedir") || - name.equals("contikicoredir") || - name.equals("projectdir") || - name.equals("compilefile") || - name.equals("process") || - name.equals("sensor") || - name.equals("coreinterface")) { - /* Backwards compatibility: old cooja mote type is being loaded */ - if (!warnedOldVersion) { - warnedOldVersion = true; - logger.warn("Old simulation config detected: Cooja mote types may not load correctly"); - } - - if (name.equals("compilefile")) { + } break; + case "contikibasedir": + case "contikicoredir": + case "projectdir": + case "compilefile": + case "process": + case "sensor": + case "coreinterface": + /* Backwards compatibility: old cooja mote type is being loaded */ + if (!warnedOldVersion) { + warnedOldVersion = true; + logger.warn("Old simulation config detected: Cooja mote types may not load correctly"); + } if (name.equals("compilefile")) { if (element.getText().endsWith(".c")) { File potentialFile = new File(element.getText()); if (potentialFile.exists()) { oldVersionSource = potentialFile; } } - } - - } else { - logger.fatal("Unrecognized entry in loaded configuration: " + name); + } break; + default: + logger.fatal("Unrecognized entry in loaded configuration: " + name); + break; } } /* Create initial core interface dependencies */ - Class[] arr = - new Class[moteInterfacesClasses.size()]; + Class[] arr + = new Class[moteInterfacesClasses.size()]; moteInterfacesClasses.toArray(arr); setCoreInterfaces(ContikiMoteType.getRequiredCoreInterfaces(arr)); /* Backwards compatibility: old cooja mote type is being loaded */ - if (getContikiSourceFile() == null && - warnedOldVersion && - oldVersionSource != null) - { + if (getContikiSourceFile() == null + && warnedOldVersion + && oldVersionSource != null) { /* Guess Contiki source */ setContikiSourceFile(oldVersionSource); logger.info("Guessing Contiki source: " + oldVersionSource.getAbsolutePath()); @@ -1383,8 +1324,8 @@ public class ContikiMoteType implements MoteType { logger.info("Guessing Contiki firmware: " + getContikiFirmwareFile().getAbsolutePath()); /* Guess compile commands */ - String compileCommands = - "make " + getExpectedFirmwareFile(oldVersionSource).getName() + " TARGET=cooja"; + String compileCommands + = "make " + getExpectedFirmwareFile(oldVersionSource).getName() + " TARGET=cooja"; logger.info("Guessing compile commands: " + compileCommands); setCompileCommands(compileCommands); } @@ -1394,10 +1335,10 @@ public class ContikiMoteType implements MoteType { } public static String[] getRequiredCoreInterfaces( - Class[] moteInterfaces) { + Class[] moteInterfaces) { /* Extract Contiki dependencies from currently selected mote interfaces */ - ArrayList coreInterfacesList = new ArrayList(); - for (Class intf: moteInterfaces) { + ArrayList coreInterfacesList = new ArrayList<>(); + for (Class intf : moteInterfaces) { if (!ContikiMoteInterface.class.isAssignableFrom(intf)) { continue; } @@ -1416,10 +1357,7 @@ public class ContikiMoteType implements MoteType { if (deps == null || deps.length == 0) { continue; } - - for (String dep: deps) { - coreInterfacesList.add(dep); - } + coreInterfacesList.addAll(Arrays.asList(deps)); } String[] coreInterfaces = new String[coreInterfacesList.size()]; diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiBeeper.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiBeeper.java index c9ef326a9..01f9c757e 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiBeeper.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiBeeper.java @@ -44,10 +44,11 @@ import org.apache.log4j.Logger; import org.jdom.Element; import org.contikios.cooja.Mote; -import org.contikios.cooja.SectionMoteMemory; +import org.contikios.cooja.mote.memory.SectionMoteMemory; import org.contikios.cooja.contikimote.ContikiMoteInterface; import org.contikios.cooja.interfaces.Beeper; import org.contikios.cooja.interfaces.PolledAfterActiveTicks; +import org.contikios.cooja.mote.memory.VarMemory; /** * Beeper mote interface. @@ -70,7 +71,7 @@ import org.contikios.cooja.interfaces.PolledAfterActiveTicks; */ public class ContikiBeeper extends Beeper implements ContikiMoteInterface, PolledAfterActiveTicks { private Mote mote = null; - private SectionMoteMemory moteMem = null; + private VarMemory moteMem = null; private static Logger logger = Logger.getLogger(ContikiBeeper.class); /** @@ -83,7 +84,7 @@ public class ContikiBeeper extends Beeper implements ContikiMoteInterface, Polle */ public ContikiBeeper(Mote mote) { this.mote = mote; - this.moteMem = (SectionMoteMemory) mote.getMemory(); + this.moteMem = new VarMemory(mote.getMemory()); } public boolean isBeeping() { diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiButton.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiButton.java index 57f7b7fd6..f4cc75acd 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiButton.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiButton.java @@ -30,16 +30,13 @@ package org.contikios.cooja.contikimote.interfaces; -import java.awt.event.*; -import java.util.Collection; -import javax.swing.*; import org.apache.log4j.Logger; -import org.jdom.Element; import org.contikios.cooja.*; import org.contikios.cooja.contikimote.ContikiMote; import org.contikios.cooja.contikimote.ContikiMoteInterface; import org.contikios.cooja.interfaces.Button; +import org.contikios.cooja.mote.memory.VarMemory; /** * Button mote interface. @@ -62,10 +59,10 @@ import org.contikios.cooja.interfaces.Button; * @author Fredrik Osterlind */ public class ContikiButton extends Button implements ContikiMoteInterface { - private SectionMoteMemory moteMem; - private ContikiMote mote; + private final VarMemory moteMem; + private final ContikiMote mote; - private static Logger logger = Logger.getLogger(ContikiButton.class); + private static final Logger logger = Logger.getLogger(ContikiButton.class); /** * Creates an interface to the button at mote. @@ -75,63 +72,17 @@ public class ContikiButton extends Button implements ContikiMoteInterface { * @see org.contikios.cooja.MoteInterfaceHandler */ public ContikiButton(Mote mote) { + super(mote); this.mote = (ContikiMote) mote; - this.moteMem = (SectionMoteMemory) mote.getMemory(); + this.moteMem = new VarMemory(mote.getMemory()); } public static String[] getCoreInterfaceDependencies() { return new String[]{"button_interface"}; } - private TimeEvent pressButtonEvent = new MoteTimeEvent(mote, 0) { - public void execute(long t) { - doPressButton(); - } - }; - - private TimeEvent releaseButtonEvent = new MoteTimeEvent(mote, 0) { - public void execute(long t) { - /* Wait until button change is handled by Contiki */ - if (moteMem.getByteValueOf("simButtonChanged") != 0) { - /* Postpone button release */ - mote.getSimulation().scheduleEvent(releaseButtonEvent, t + Simulation.MILLISECOND); - return; - } - - /*logger.info("Releasing button at: " + t);*/ - doReleaseButton(); - } - }; - - /** - * Clicks button: Presses and immediately releases button. - */ - public void clickButton() { - mote.getSimulation().invokeSimulationThread(new Runnable() { - public void run() { - mote.getSimulation().scheduleEvent(pressButtonEvent, mote.getSimulation().getSimulationTime()); - mote.getSimulation().scheduleEvent(releaseButtonEvent, mote.getSimulation().getSimulationTime() + Simulation.MILLISECOND); - } - }); - } - - public void pressButton() { - mote.getSimulation().invokeSimulationThread(new Runnable() { - public void run() { - mote.getSimulation().scheduleEvent(pressButtonEvent, mote.getSimulation().getSimulationTime()); - } - }); - } - - public void releaseButton() { - mote.getSimulation().invokeSimulationThread(new Runnable() { - public void run() { - mote.getSimulation().scheduleEvent(releaseButtonEvent, mote.getSimulation().getSimulationTime()); - } - }); - } - - private void doReleaseButton() { + @Override + protected void doReleaseButton() { moteMem.setByteValueOf("simButtonIsDown", (byte) 0); if (moteMem.getByteValueOf("simButtonIsActive") == 1) { @@ -145,7 +96,8 @@ public class ContikiButton extends Button implements ContikiMoteInterface { } } - private void doPressButton() { + @Override + protected void doPressButton() { moteMem.setByteValueOf("simButtonIsDown", (byte) 1); if (moteMem.getByteValueOf("simButtonIsActive") == 1) { @@ -159,33 +111,9 @@ public class ContikiButton extends Button implements ContikiMoteInterface { } } + @Override public boolean isPressed() { return moteMem.getByteValueOf("simButtonIsDown") == 1; } - public JPanel getInterfaceVisualizer() { - JPanel panel = new JPanel(); - final JButton clickButton = new JButton("Click button"); - - panel.add(clickButton); - - clickButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - clickButton(); - } - }); - - return panel; - } - - public void releaseInterfaceVisualizer(JPanel panel) { - } - - public Collection getConfigXML() { - return null; - } - - public void setConfigXML(Collection configXML, boolean visAvailable) { - } - } diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiCFS.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiCFS.java index e831a1607..f1985b6cc 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiCFS.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiCFS.java @@ -43,6 +43,7 @@ import org.jdom.Element; import org.contikios.cooja.*; import org.contikios.cooja.contikimote.ContikiMoteInterface; import org.contikios.cooja.interfaces.PolledAfterActiveTicks; +import org.contikios.cooja.mote.memory.VarMemory; /** * Contiki FileSystem (CFS) interface (such as external flash). @@ -71,7 +72,7 @@ public class ContikiCFS extends MoteInterface implements ContikiMoteInterface, P public int FILESYSTEM_SIZE = 4000; /* Configure CFS size here and in cfs-cooja.c */ private Mote mote = null; - private SectionMoteMemory moteMem = null; + private VarMemory moteMem = null; private int lastRead = 0; private int lastWritten = 0; @@ -85,7 +86,7 @@ public class ContikiCFS extends MoteInterface implements ContikiMoteInterface, P */ public ContikiCFS(Mote mote) { this.mote = mote; - this.moteMem = (SectionMoteMemory) mote.getMemory(); + this.moteMem = new VarMemory(mote.getMemory()); } public static String[] getCoreInterfaceDependencies() { @@ -119,6 +120,7 @@ public class ContikiCFS extends MoteInterface implements ContikiMoteInterface, P } moteMem.setByteArray("simCFSData", data); + moteMem.setIntValueOf("simCFSSize", data.length); return true; } @@ -128,7 +130,8 @@ public class ContikiCFS extends MoteInterface implements ContikiMoteInterface, P * @return Filesystem data */ public byte[] getFilesystemData() { - return moteMem.getByteArray("simCFSData", FILESYSTEM_SIZE); + int size = moteMem.getIntValueOf("simCFSSize"); + return moteMem.getByteArray("simCFSData", size); } /** diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiClock.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiClock.java index 3864c4724..b033ef06d 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiClock.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiClock.java @@ -37,13 +37,14 @@ import org.apache.log4j.Logger; import org.jdom.Element; import org.contikios.cooja.Mote; -import org.contikios.cooja.SectionMoteMemory; +import org.contikios.cooja.mote.memory.SectionMoteMemory; import org.contikios.cooja.Simulation; import org.contikios.cooja.contikimote.ContikiMote; import org.contikios.cooja.contikimote.ContikiMoteInterface; import org.contikios.cooja.interfaces.Clock; import org.contikios.cooja.interfaces.PolledAfterAllTicks; import org.contikios.cooja.interfaces.PolledBeforeActiveTicks; +import org.contikios.cooja.mote.memory.VarMemory; /** * Clock mote interface. Controls Contiki time. @@ -71,7 +72,7 @@ public class ContikiClock extends Clock implements ContikiMoteInterface, PolledB private Simulation simulation; private ContikiMote mote; - private SectionMoteMemory moteMem; + private VarMemory moteMem; private long moteTime; /* Microseconds */ private long timeDrift; /* Microseconds */ @@ -85,7 +86,7 @@ public class ContikiClock extends Clock implements ContikiMoteInterface, PolledB public ContikiClock(Mote mote) { this.simulation = mote.getSimulation(); this.mote = (ContikiMote) mote; - this.moteMem = (SectionMoteMemory) mote.getMemory(); + this.moteMem = new VarMemory(mote.getMemory()); timeDrift = 0; moteTime = 0; } @@ -113,6 +114,14 @@ public class ContikiClock extends Clock implements ContikiMoteInterface, PolledB public long getTime() { return moteTime; } + + public void setDeviation(double deviation) { + logger.fatal("Can't change deviation");; + } + + public double getDeviation() { + return 1.0; + } public void doActionsBeforeTick() { /* Update time */ @@ -160,5 +169,4 @@ public class ContikiClock extends Clock implements ContikiMoteInterface, PolledB public void setConfigXML(Collection configXML, boolean visAvailable) { } - } diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiEEPROM.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiEEPROM.java new file mode 100644 index 000000000..aeca322d1 --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiEEPROM.java @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2014, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +package org.contikios.cooja.contikimote.interfaces; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.*; +import java.util.*; +import javax.swing.*; +import javax.xml.bind.DatatypeConverter; +import org.apache.log4j.Logger; +import org.jdom.Element; + +import org.contikios.cooja.*; +import org.contikios.cooja.contikimote.ContikiMoteInterface; +import org.contikios.cooja.interfaces.PolledAfterActiveTicks; +import org.contikios.cooja.mote.memory.VarMemory; + +/** + * Contiki EEPROM interface + * + * Contiki variables: + *
      + *
    • char[] simEEPROMData + *
    • char simEEPROMChanged (1=EEPROM has been altered) + *
    • int simEEPROMRead (bytes read from EEPROM) + *
    • int simEEPROMWritten (bytes written to EEPROM) + *
    + *

    + * + * Core interface: + *

      + *
    • eeprom_interface + *
    + *

    + * This observable notifies when the eeprom is used (read/write). + * + * @author Claes Jakobsson (based on ContikiCFS by Fredrik Osterlind) + */ +@ClassDescription("EEPROM") +public class ContikiEEPROM extends MoteInterface implements ContikiMoteInterface, PolledAfterActiveTicks { + private static Logger logger = Logger.getLogger(ContikiEEPROM.class); + + public int EEPROM_SIZE = 1024; /* Configure EEPROM size here and in eeprom.c. Should really be multiple of 16 */ + private Mote mote = null; + private VarMemory moteMem = null; + + private int lastRead = 0; + private int lastWritten = 0; + + /** + * Creates an interface to the EEPROM at mote. + * + * @param mote Mote + * @see Mote + * @see org.contikios.cooja.MoteInterfaceHandler + */ + public ContikiEEPROM(Mote mote) { + this.mote = mote; + this.moteMem = new VarMemory(mote.getMemory()); + } + + public static String[] getCoreInterfaceDependencies() { + return new String[]{"eeprom_interface"}; + } + + public void doActionsAfterTick() { + if (moteMem.getByteValueOf("simEEPROMChanged") == 1) { + lastRead = moteMem.getIntValueOf("simEEPROMRead"); + lastWritten = moteMem.getIntValueOf("simEEPROMWritten"); + + moteMem.setIntValueOf("simEEPROMRead", 0); + moteMem.setIntValueOf("simEEPROMWritten", 0); + moteMem.setByteValueOf("simEEPROMChanged", (byte) 0); + + this.setChanged(); + this.notifyObservers(mote); + } + } + + /** + * Set EEPROM data. + * + * @param data Data + * @return True if operation successful + */ + public boolean setEEPROMData(byte[] data) { + if (data.length > EEPROM_SIZE) { + logger.fatal("Error. EEPROM data too large, skipping"); + return false; + } + + moteMem.setByteArray("simEEPROMData", data); + return true; + } + + /** + * Get EEPROM data. + * + * @return Filesystem data + */ + public byte[] getEEPROMData() { + return moteMem.getByteArray("simEEPROMData", EEPROM_SIZE); + } + + /** + * @return Read bytes count last change. + */ + public int getLastReadCount() { + return lastRead; + } + + /** + * @return Written bytes count last change. + */ + public int getLastWrittenCount() { + return lastWritten; + } + + String byteArrayToPrintableCharacters(byte[] data, int offset, int length) { + StringBuilder sb = new StringBuilder(); + for (int i = offset; i < offset + length; i++) { + sb.append(data[i] > 31 && data[i] < 128 ? (char) data[i] : '.'); + } + return sb.toString(); + } + + String byteArrayToHexList(byte[] data, int offset, int length) { + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < length; i++) { + byte h = (byte) ((int) data[offset + i] >> 4); + byte l = (byte) ((int) data[offset + i] & 0xf); + sb.append((char)(h < 10 ? 0x30 + h : 0x61 + h - 10)); + sb.append((char)(l < 10 ? 0x30 + l : 0x61 + l - 10)); + sb.append(' '); + if (i % 8 == 7 && i != length - 1) { + sb.append(' '); + } + } + + return sb.toString(); + } + + void redrawDataView(JTextArea textArea) { + StringBuilder sb = new StringBuilder(); + Formatter fmt = new Formatter(sb); + byte[] data = getEEPROMData(); + + for (int i = 0; i < EEPROM_SIZE; i+= 16) { + fmt.format("%04d %s | %s |\n", i, byteArrayToHexList(data, i, 16), byteArrayToPrintableCharacters(data, i, 16)); + } + + textArea.setText(sb.toString()); + textArea.setCaretPosition(0); + } + + public JPanel getInterfaceVisualizer() { + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + + final JLabel lastTimeLabel = new JLabel("Last change at: ?"); + final JLabel lastReadLabel = new JLabel("Last change read bytes: 0"); + final JLabel lastWrittenLabel = new JLabel("Last change wrote bytes: 0"); + final JButton uploadButton = new JButton("Upload binary file"); + final JButton clearButton = new JButton("Reset EEPROM to zero"); + final JTextArea dataViewArea = new JTextArea(); + final JScrollPane dataViewScrollPane = new JScrollPane(dataViewArea); + + panel.add(lastTimeLabel); + panel.add(lastReadLabel); + panel.add(lastWrittenLabel); + panel.add(uploadButton); + panel.add(clearButton); + + panel.add(dataViewScrollPane); + + uploadButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + byte[] eepromData = readDialogEEPROMBytes(null); + + // Write file data to EEPROM + if (eepromData != null) { + if (setEEPROMData(eepromData)) { + logger.info("Done! (" + eepromData.length + " bytes written to EEPROM)"); + } + + redrawDataView(dataViewArea); + } + } + }); + + clearButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + byte[] eepromData = new byte[EEPROM_SIZE]; + + if (setEEPROMData(eepromData)) { + logger.info("Done! (EEPROM reset to zero)"); + } + + redrawDataView(dataViewArea); + } + }); + + Observer observer; + this.addObserver(observer = new Observer() { + public void update(Observable obs, Object obj) { + long currentTime = mote.getSimulation().getSimulationTime(); + lastTimeLabel.setText("Last change at time: " + currentTime); + lastReadLabel.setText("Last change read bytes: " + getLastReadCount()); + lastWrittenLabel.setText("Last change wrote bytes: " + getLastWrittenCount()); + + redrawDataView(dataViewArea); + } + }); + + // Saving observer reference for releaseInterfaceVisualizer + panel.putClientProperty("intf_obs", observer); + + panel.setMinimumSize(new Dimension(140, 60)); + panel.setPreferredSize(new Dimension(140, 60)); + + dataViewArea.setLineWrap(false); + dataViewArea.setEditable(false); + dataViewArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); + dataViewScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + dataViewScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + + redrawDataView(dataViewArea); + + return panel; + } + + public void releaseInterfaceVisualizer(JPanel panel) { + Observer observer = (Observer) panel.getClientProperty("intf_obs"); + if (observer == null) { + logger.fatal("Error when releasing panel, observer is null"); + return; + } + + this.deleteObserver(observer); + } + + public Collection getConfigXML() { + Vector config = new Vector(); + Element element; + + // Infinite boolean + element = new Element("eeprom"); + element.setText(DatatypeConverter.printBase64Binary(getEEPROMData())); + config.add(element); + + return config; + } + + public void setConfigXML(Collection configXML, boolean visAvailable) { + for (Element element : configXML) { + if (element.getName().equals("eeprom")) { + setEEPROMData(DatatypeConverter.parseBase64Binary(element.getText())); + } + } + } + + /** + * Opens a file dialog and returns the contents of the selected file or null if dialog aborted. + * + * @param parent Dialog parent, may be null + * @return Binary contents of user selected file + */ + public static byte[] readDialogEEPROMBytes(Component parent) { + // Choose file + File file = null; + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setCurrentDirectory(new java.io.File(".")); + fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + fileChooser.setDialogTitle("Select binary data"); + + if (fileChooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION) { + file = fileChooser.getSelectedFile(); + } else { + return null; + } + + // Read file data + long fileSize = file.length(); + byte[] fileData = new byte[(int) fileSize]; + + FileInputStream fileIn; + DataInputStream dataIn; + int offset = 0; + int numRead = 0; + try { + fileIn = new FileInputStream(file); + dataIn = new DataInputStream(fileIn); + while (offset < fileData.length + && (numRead = dataIn.read(fileData, offset, fileData.length - offset)) >= 0) { + offset += numRead; + } + + dataIn.close(); + fileIn.close(); + } catch (Exception ex) { + logger.debug("Exception ex: " + ex); + return null; + } + + return fileData; + } + +} diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiLED.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiLED.java index b6372751d..cc549e142 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiLED.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiLED.java @@ -40,6 +40,7 @@ import org.contikios.cooja.*; import org.contikios.cooja.contikimote.ContikiMoteInterface; import org.contikios.cooja.interfaces.LED; import org.contikios.cooja.interfaces.PolledAfterActiveTicks; +import org.contikios.cooja.mote.memory.VarMemory; /** * LEDs mote interface. @@ -64,7 +65,7 @@ public class ContikiLED extends LED implements ContikiMoteInterface, PolledAfter private static Logger logger = Logger.getLogger(ContikiLED.class); private Mote mote = null; - private SectionMoteMemory moteMem = null; + private VarMemory moteMem = null; private byte currentLedValue = 0; private static final byte LEDS_GREEN = 1; @@ -91,7 +92,7 @@ public class ContikiLED extends LED implements ContikiMoteInterface, PolledAfter */ public ContikiLED(Mote mote) { this.mote = mote; - this.moteMem = (SectionMoteMemory) mote.getMemory(); + this.moteMem = new VarMemory(mote.getMemory()); } public static String[] getCoreInterfaceDependencies() { diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiMoteID.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiMoteID.java index 8a9887638..e83d0c2fa 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiMoteID.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiMoteID.java @@ -38,6 +38,7 @@ import org.jdom.Element; import org.contikios.cooja.*; import org.contikios.cooja.contikimote.ContikiMoteInterface; import org.contikios.cooja.interfaces.MoteID; +import org.contikios.cooja.mote.memory.VarMemory; /** * Mote ID interface: 'node_id'. @@ -60,7 +61,7 @@ import org.contikios.cooja.interfaces.MoteID; * @author Fredrik Osterlind */ public class ContikiMoteID extends MoteID implements ContikiMoteInterface { - private SectionMoteMemory moteMem = null; + private VarMemory moteMem = null; private static Logger logger = Logger.getLogger(ContikiMoteID.class); private int moteID = 0; @@ -77,7 +78,7 @@ public class ContikiMoteID extends MoteID implements ContikiMoteInterface { */ public ContikiMoteID(Mote mote) { this.mote = mote; - this.moteMem = (SectionMoteMemory) mote.getMemory(); + this.moteMem = new VarMemory(mote.getMemory()); } public static String[] getCoreInterfaceDependencies() { diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiPIR.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiPIR.java index 0dbb90f03..cbfb7d66c 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiPIR.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiPIR.java @@ -37,10 +37,11 @@ import javax.swing.JButton; import javax.swing.JPanel; import org.jdom.Element; import org.contikios.cooja.Mote; -import org.contikios.cooja.SectionMoteMemory; +import org.contikios.cooja.mote.memory.SectionMoteMemory; import org.contikios.cooja.contikimote.ContikiMote; import org.contikios.cooja.contikimote.ContikiMoteInterface; import org.contikios.cooja.interfaces.PIR; +import org.contikios.cooja.mote.memory.VarMemory; /** * Passive IR sensor mote interface. @@ -65,7 +66,7 @@ import org.contikios.cooja.interfaces.PIR; public class ContikiPIR extends PIR implements ContikiMoteInterface { private ContikiMote mote; - private SectionMoteMemory moteMem; + private VarMemory moteMem; /** * Creates an interface to the PIR at mote. @@ -77,7 +78,7 @@ public class ContikiPIR extends PIR implements ContikiMoteInterface { */ public ContikiPIR(Mote mote) { this.mote = (ContikiMote) mote; - this.moteMem = (SectionMoteMemory) mote.getMemory(); + this.moteMem = new VarMemory(mote.getMemory()); } public static String[] getCoreInterfaceDependencies() { diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRS232.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRS232.java index 304ffa5ae..e8e7589e5 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRS232.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRS232.java @@ -38,6 +38,7 @@ import org.contikios.cooja.contikimote.ContikiMote; import org.contikios.cooja.contikimote.ContikiMoteInterface; import org.contikios.cooja.dialogs.SerialUI; import org.contikios.cooja.interfaces.PolledAfterActiveTicks; +import org.contikios.cooja.mote.memory.VarMemory; /** * Contiki mote serial port and log interfaces. @@ -68,9 +69,9 @@ public class ContikiRS232 extends SerialUI implements ContikiMoteInterface, Poll private static Logger logger = Logger.getLogger(ContikiRS232.class); private ContikiMote mote = null; - private SectionMoteMemory moteMem = null; + private VarMemory moteMem = null; - static final int SERIAL_BUF_SIZE = 1024; /* rs232.c:40 */ + static final int SERIAL_BUF_SIZE = 2048; /* rs232.c:40 */ /** * Creates an interface to the RS232 at mote. @@ -82,7 +83,7 @@ public class ContikiRS232 extends SerialUI implements ContikiMoteInterface, Poll */ public ContikiRS232(Mote mote) { this.mote = (ContikiMote) mote; - this.moteMem = (SectionMoteMemory) mote.getMemory(); + this.moteMem = new VarMemory(mote.getMemory()); } public static String[] getCoreInterfaceDependencies() { diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRadio.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRadio.java index ebe24e52a..bbc4a2abd 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRadio.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRadio.java @@ -39,15 +39,16 @@ import org.jdom.Element; import org.contikios.cooja.COOJARadioPacket; import org.contikios.cooja.Mote; import org.contikios.cooja.RadioPacket; -import org.contikios.cooja.SectionMoteMemory; +import org.contikios.cooja.mote.memory.SectionMoteMemory; import org.contikios.cooja.Simulation; import org.contikios.cooja.contikimote.ContikiMote; import org.contikios.cooja.contikimote.ContikiMoteInterface; import org.contikios.cooja.interfaces.PolledAfterActiveTicks; import org.contikios.cooja.interfaces.Position; import org.contikios.cooja.interfaces.Radio; +import org.contikios.cooja.mote.memory.VarMemory; import org.contikios.cooja.radiomediums.UDGM; - +import org.contikios.cooja.util.CCITT_CRC; /** * Packet radio transceiver mote interface. * @@ -89,7 +90,7 @@ import org.contikios.cooja.radiomediums.UDGM; public class ContikiRadio extends Radio implements ContikiMoteInterface, PolledAfterActiveTicks { private ContikiMote mote; - private SectionMoteMemory myMoteMemory; + private VarMemory myMoteMemory; private static Logger logger = Logger.getLogger(ContikiRadio.class); @@ -132,7 +133,7 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface, PolledA ContikiRadio.class, "RADIO_TRANSMISSION_RATE_kbps"); this.mote = (ContikiMote) mote; - this.myMoteMemory = (SectionMoteMemory) mote.getMemory(); + this.myMoteMemory = new VarMemory(mote.getMemory()); radioOn = myMoteMemory.getByteValueOf("simRadioHWOn") == 1; } @@ -199,7 +200,7 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface, PolledA packetToMote = null; myMoteMemory.setIntValueOf("simInSize", 0); } else { - myMoteMemory.setIntValueOf("simInSize", packetToMote.getPacketData().length); + myMoteMemory.setIntValueOf("simInSize", packetToMote.getPacketData().length - 2); myMoteMemory.setByteArray("simInDataBuffer", packetToMote.getPacketData()); } @@ -329,7 +330,7 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface, PolledA /* New transmission */ int size = myMoteMemory.getIntValueOf("simOutSize"); if (!isTransmitting && size > 0) { - packetFromMote = new COOJARadioPacket(myMoteMemory.getByteArray("simOutDataBuffer", size)); + packetFromMote = new COOJARadioPacket(myMoteMemory.getByteArray("simOutDataBuffer", size + 2)); if (packetFromMote.getPacketData() == null || packetFromMote.getPacketData().length == 0) { logger.warn("Skipping zero sized Contiki packet (no buffer)"); @@ -338,6 +339,15 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface, PolledA return; } + byte[] data = packetFromMote.getPacketData(); + CCITT_CRC txCrc = new CCITT_CRC(); + txCrc.setCRC(0); + for (int i = 0; i < size; i++) { + txCrc.addBitrev(data[i]); + } + data[size] = (byte)txCrc.getCRCHi(); + data[size + 1] = (byte)txCrc.getCRCLow(); + isTransmitting = true; /* Calculate transmission duration (us) */ diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiVib.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiVib.java index 9584674ac..ba1920715 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiVib.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiVib.java @@ -39,9 +39,10 @@ import org.jdom.Element; import org.contikios.cooja.ClassDescription; import org.contikios.cooja.Mote; import org.contikios.cooja.MoteInterface; -import org.contikios.cooja.SectionMoteMemory; +import org.contikios.cooja.mote.memory.SectionMoteMemory; import org.contikios.cooja.contikimote.ContikiMote; import org.contikios.cooja.contikimote.ContikiMoteInterface; +import org.contikios.cooja.mote.memory.VarMemory; /** * Vibration sensor mote interface. @@ -67,7 +68,7 @@ import org.contikios.cooja.contikimote.ContikiMoteInterface; public class ContikiVib extends MoteInterface implements ContikiMoteInterface { private ContikiMote mote; - private SectionMoteMemory moteMem; + private VarMemory moteMem; /** * Creates an interface to the vibration sensor at mote. @@ -79,7 +80,7 @@ public class ContikiVib extends MoteInterface implements ContikiMoteInterface { */ public ContikiVib(Mote mote) { this.mote = (ContikiMote) mote; - this.moteMem = (SectionMoteMemory) mote.getMemory(); + this.moteMem = new VarMemory(mote.getMemory()); } public static String[] getCoreInterfaceDependencies() { diff --git a/tools/cooja/java/org/contikios/cooja/dialogs/AbstractCompileDialog.java b/tools/cooja/java/org/contikios/cooja/dialogs/AbstractCompileDialog.java index ee4cf486e..7210cb174 100644 --- a/tools/cooja/java/org/contikios/cooja/dialogs/AbstractCompileDialog.java +++ b/tools/cooja/java/org/contikios/cooja/dialogs/AbstractCompileDialog.java @@ -468,7 +468,7 @@ public abstract class AbstractCompileDialog extends JDialog { protected String[] compilationEnvironment = null; /* Default environment: inherit from current process */ public void compileContiki() throws Exception { - final MessageList taskOutput = new MessageList(); + final MessageListUI taskOutput = new MessageListUI(); if (contikiFirmware.exists()) { contikiFirmware.delete(); @@ -861,7 +861,7 @@ public abstract class AbstractCompileDialog extends JDialog { currentCompilationProcess = null; } - private boolean createNewCompilationTab(MessageList output) { + private boolean createNewCompilationTab(MessageListUI output) { abortAnyCompilation(); tabbedPane.remove(currentCompilationOutput); diff --git a/tools/cooja/java/org/contikios/cooja/dialogs/CompileContiki.java b/tools/cooja/java/org/contikios/cooja/dialogs/CompileContiki.java index 8a0deaee8..702024d13 100644 --- a/tools/cooja/java/org/contikios/cooja/dialogs/CompileContiki.java +++ b/tools/cooja/java/org/contikios/cooja/dialogs/CompileContiki.java @@ -127,7 +127,7 @@ public class CompileContiki { /* TODO Fix me */ final MessageList messageDialog; if (compilationOutput == null) { - messageDialog = new MessageList(); + messageDialog = new MessageListUI(); } else { messageDialog = compilationOutput; } @@ -138,8 +138,8 @@ public class CompileContiki { cmd += c + " "; } logger.info("> " + cmd); - messageDialog.addMessage("", MessageList.NORMAL); - messageDialog.addMessage("> " + cmd, MessageList.NORMAL); + messageDialog.addMessage("", MessageListUI.NORMAL); + messageDialog.addMessage("> " + cmd, MessageListUI.NORMAL); } final Process compileProcess; @@ -170,7 +170,7 @@ public class CompileContiki { String readLine; while ((readLine = processNormal.readLine()) != null) { if (messageDialog != null) { - messageDialog.addMessage(readLine, MessageList.NORMAL); + messageDialog.addMessage(readLine, MessageListUI.NORMAL); } } } catch (IOException e) { @@ -203,7 +203,7 @@ public class CompileContiki { compileProcess.waitFor(); } catch (Exception e) { messageDialog.addMessage(e.getMessage(), MessageList.ERROR); - syncException.setCompilationOutput(new MessageList()); + syncException.setCompilationOutput(new MessageListUI()); syncException.fillInStackTrace(); return; } @@ -214,7 +214,7 @@ public class CompileContiki { if (onFailure != null) { onFailure.actionPerformed(null); } - syncException.setCompilationOutput(new MessageList()); + syncException.setCompilationOutput(new MessageListUI()); syncException.fillInStackTrace(); return; } @@ -232,13 +232,13 @@ public class CompileContiki { if (onFailure != null) { onFailure.actionPerformed(null); } - syncException.setCompilationOutput(new MessageList()); + syncException.setCompilationOutput(new MessageListUI()); syncException.fillInStackTrace(); return; } - messageDialog.addMessage("", MessageList.NORMAL); - messageDialog.addMessage("Compilation succeded", MessageList.NORMAL); + messageDialog.addMessage("", MessageListUI.NORMAL); + messageDialog.addMessage("Compilation succeded", MessageListUI.NORMAL); if (onSuccess != null) { onSuccess.actionPerformed(null); } diff --git a/tools/cooja/java/org/contikios/cooja/dialogs/ConfigurationWizard.java b/tools/cooja/java/org/contikios/cooja/dialogs/ConfigurationWizard.java index 3010625e4..cfea6820a 100644 --- a/tools/cooja/java/org/contikios/cooja/dialogs/ConfigurationWizard.java +++ b/tools/cooja/java/org/contikios/cooja/dialogs/ConfigurationWizard.java @@ -66,8 +66,11 @@ import javax.swing.JScrollPane; import org.contikios.cooja.CoreComm; import org.contikios.cooja.Cooja; import org.contikios.cooja.MoteType.MoteTypeCreationException; -import org.contikios.cooja.SectionMoteMemory; +import org.contikios.cooja.mote.memory.SectionMoteMemory; import org.contikios.cooja.contikimote.ContikiMoteType; +import org.contikios.cooja.contikimote.ContikiMoteType.SectionParser; +import org.contikios.cooja.mote.memory.MemoryInterface.Symbol; +import org.contikios.cooja.mote.memory.VarMemory; /* TODO Test common section */ /* TODO Test readonly section */ @@ -141,13 +144,13 @@ public class ConfigurationWizard extends JDialog { private static File cLibraryFile; private static String javaLibraryName; private static CoreComm javaLibrary; - private static HashMap addresses; + private static HashMap addresses; private static int relDataSectionAddr; private static int dataSectionSize; private static int relBssSectionAddr; private static int bssSectionSize; - private static MessageList output; + private static MessageListUI output; private static JDialog progressDialog; private static JButton button; private static JProgressBar progressBar; @@ -427,7 +430,7 @@ public class ConfigurationWizard extends JDialog { } private static void prepareShowTestProgress(JFrame parent, String desc) { - output = new MessageList(); + output = new MessageListUI(); output.addPopupMenuItem(null, true); progressDialog = new JDialog(parent, desc); button = new JButton("Close"); @@ -539,7 +542,7 @@ public class ConfigurationWizard extends JDialog { return (String) optionPane.getValue(); } - public static boolean performCompileCTest(MessageList testOutput, PrintStream normalStream, PrintStream errorStream) { + public static boolean performCompileCTest(MessageListUI testOutput, PrintStream normalStream, PrintStream errorStream) { javaLibraryName = "LibTest" + testCounter; cLibraryName = "libtest" + testCounter; cLibrarySourceFile = new File(ContikiMoteType.tempOutputDirectory, cLibraryName + ".c"); @@ -639,8 +642,8 @@ public class ConfigurationWizard extends JDialog { return true; } - public static boolean performLoadTest(MessageList testOutput, PrintStream normalStream, PrintStream errorStream) { - MessageList dummy = new MessageList(); + public static boolean performLoadTest(MessageListUI testOutput, PrintStream normalStream, PrintStream errorStream) { + MessageListUI dummy = new MessageListUI(); PrintStream dummyStream = dummy.getInputStream(MessageList.NORMAL); if (!performCompileCTest(dummy, dummyStream, errorStream)) { return false; @@ -693,8 +696,8 @@ public class ConfigurationWizard extends JDialog { return true; } - public static boolean performAddressTest(MessageList testOutput, PrintStream normalStream, PrintStream errorStream) { - MessageList dummy = new MessageList(); + public static boolean performAddressTest(MessageListUI testOutput, PrintStream normalStream, PrintStream errorStream) { + MessageListUI dummy = new MessageListUI(); PrintStream dummyStream = dummy.getInputStream(MessageList.NORMAL); if (!performCompileCTest(dummy, dummyStream, errorStream)) { return false; @@ -740,7 +743,7 @@ public class ConfigurationWizard extends JDialog { return false; } - private static boolean performMapAddressTest(MessageList testOutput, PrintStream normalStream, PrintStream errorStream) { + private static boolean performMapAddressTest(MessageListUI testOutput, PrintStream normalStream, PrintStream errorStream) { testOutput.addMessage("### Testing map file based address parsing"); File mapFile = new File(ContikiMoteType.tempOutputDirectory, cLibraryName + ContikiMoteType.mapSuffix); @@ -757,18 +760,28 @@ public class ConfigurationWizard extends JDialog { } testOutput.addMessage("### Parsing map file data for addresses"); - addresses = new HashMap(); - boolean parseOK = ContikiMoteType.parseMapFileData(mapData, addresses); - if (!parseOK) { - testOutput.addMessage("### Error: Failed parsing map file data", MessageList.ERROR); - return false; - } + addresses = new HashMap(); +// boolean parseOK = ContikiMoteType.parseMapFileData(mapData, addresses); +// if (!parseOK) { +// testOutput.addMessage("### Error: Failed parsing map file data", MessageList.ERROR); +// return false; +// } testOutput.addMessage("### Validating section addresses"); - relDataSectionAddr = ContikiMoteType.parseMapDataSectionAddr(mapData); - dataSectionSize = ContikiMoteType.parseMapDataSectionSize(mapData); - relBssSectionAddr = ContikiMoteType.parseMapBssSectionAddr(mapData); - bssSectionSize = ContikiMoteType.parseMapBssSectionSize(mapData); + SectionParser dataSecParser = new ContikiMoteType.MapSectionParser( + mapData, + Cooja.getExternalToolsSetting("MAPFILE_DATA_START"), + Cooja.getExternalToolsSetting("MAPFILE_DATA_SIZE")); + SectionParser bssSecParser = new ContikiMoteType.MapSectionParser( + mapData, + Cooja.getExternalToolsSetting("MAPFILE_BSS_START"), + Cooja.getExternalToolsSetting("MAPFILE_BSS_SIZE")); + dataSecParser.parse(0); + bssSecParser.parse(0); + relDataSectionAddr = dataSecParser.getStartAddr(); + dataSectionSize = dataSecParser.getSize(); + relBssSectionAddr = bssSecParser.getStartAddr(); + bssSectionSize = bssSecParser.getSize(); testOutput.addMessage("Data section address: 0x" + Integer.toHexString(relDataSectionAddr)); testOutput.addMessage("Data section size: 0x" + Integer.toHexString(dataSectionSize)); testOutput.addMessage("BSS section address: 0x" + Integer.toHexString(relBssSectionAddr)); @@ -826,7 +839,7 @@ public class ConfigurationWizard extends JDialog { return true; } - private static boolean performCommandAddressTest(MessageList testOutput, PrintStream normalStream, PrintStream errorStream) { + private static boolean performCommandAddressTest(MessageListUI testOutput, PrintStream normalStream, PrintStream errorStream) { testOutput.addMessage("### Testing command based address parsing"); testOutput.addMessage("### Executing command"); @@ -837,18 +850,31 @@ public class ConfigurationWizard extends JDialog { } testOutput.addMessage("### Parsing command output for addresses"); - addresses = new HashMap(); - boolean parseOK = ContikiMoteType.parseCommandData(commandData, addresses); - if (!parseOK) { - testOutput.addMessage("### Error: Failed parsing command output", MessageList.ERROR); - return false; - } + addresses = new HashMap(); +// boolean parseOK = ContikiMoteType.parseCommandData(commandData, addresses); +// if (!parseOK) { +// testOutput.addMessage("### Error: Failed parsing command output", MessageList.ERROR); +// return false; +// } testOutput.addMessage("### Validating section addresses"); - relDataSectionAddr = ContikiMoteType.parseCommandDataSectionAddr(commandData); - dataSectionSize = ContikiMoteType.parseCommandDataSectionSize(commandData); - relBssSectionAddr = ContikiMoteType.parseCommandBssSectionAddr(commandData); - bssSectionSize = ContikiMoteType.parseCommandBssSectionSize(commandData); + SectionParser dataSecParser = new ContikiMoteType.CommandSectionParser( + commandData, + Cooja.getExternalToolsSetting("COMMAND_DATA_START"), + Cooja.getExternalToolsSetting("COMMAND_DATA_SIZE"), + Cooja.getExternalToolsSetting("COMMAND_VAR_SEC_DATA")); + SectionParser bssSecParser = new ContikiMoteType.CommandSectionParser( + commandData, + Cooja.getExternalToolsSetting("COMMAND_BSS_START"), + Cooja.getExternalToolsSetting("COMMAND_BSS_SIZE"), + Cooja.getExternalToolsSetting("COMMAND_VAR_SEC_BSS")); + + dataSecParser.parse(0); + bssSecParser.parse(0); + relDataSectionAddr = dataSecParser.getStartAddr(); + dataSectionSize = dataSecParser.getSize(); + relBssSectionAddr = bssSecParser.getStartAddr(); + bssSectionSize = bssSecParser.getSize(); testOutput.addMessage("Data section address: 0x" + Integer.toHexString(relDataSectionAddr)); testOutput.addMessage("Data section size: 0x" + Integer.toHexString(dataSectionSize)); testOutput.addMessage("BSS section address: 0x" + Integer.toHexString(relBssSectionAddr)); @@ -907,8 +933,8 @@ public class ConfigurationWizard extends JDialog { } - public static boolean performMemoryReplacementTest(MessageList testOutput, PrintStream normalStream, PrintStream errorStream) { - MessageList dummy = new MessageList(); + public static boolean performMemoryReplacementTest(MessageListUI testOutput, PrintStream normalStream, PrintStream errorStream) { + MessageListUI dummy = new MessageListUI(); PrintStream dummyStream = dummy.getInputStream(MessageList.NORMAL); if (!performCompileCTest(dummy, dummyStream, errorStream)) { return false; @@ -935,7 +961,7 @@ public class ConfigurationWizard extends JDialog { testOutput.addMessage("Could not find address of referenceVar", MessageList.ERROR); return false; } - int relRefAddress = addresses.get("referenceVar"); + int relRefAddress = (int) addresses.get("referenceVar").addr; javaLibrary.setReferenceAddress(relRefAddress); testOutput.addMessage("### Creating data and BSS memory sections"); @@ -943,15 +969,16 @@ public class ConfigurationWizard extends JDialog { byte[] initialBssSection = new byte[bssSectionSize]; javaLibrary.getMemory(relDataSectionAddr, dataSectionSize, initialDataSection); javaLibrary.getMemory(relBssSectionAddr, bssSectionSize, initialBssSection); - SectionMoteMemory memory = new SectionMoteMemory(addresses, 0); + SectionMoteMemory memory = new SectionMoteMemory(addresses); + VarMemory varMem = new VarMemory(memory); memory.setMemorySegment(relDataSectionAddr, initialDataSection); memory.setMemorySegment(relBssSectionAddr, initialBssSection); int contikiDataCounter, contikiBSSCounter; testOutput.addMessage("### Checking initial variable values: 1,0"); - contikiDataCounter = memory.getIntValueOf("var1"); - contikiBSSCounter = memory.getIntValueOf("uvar1"); + contikiDataCounter = varMem.getIntValueOf("var1"); + contikiBSSCounter = varMem.getIntValueOf("uvar1"); int javaDataCounter = 1; int javaBSSCounter = 0; if (contikiDataCounter != javaDataCounter) { @@ -975,8 +1002,8 @@ public class ConfigurationWizard extends JDialog { javaLibrary.getMemory(relBssSectionAddr, bssSectionSize, initialBssSection); memory.setMemorySegment(relDataSectionAddr, initialDataSection); memory.setMemorySegment(relBssSectionAddr, initialBssSection); - contikiDataCounter = memory.getIntValueOf("var1"); - contikiBSSCounter = memory.getIntValueOf("uvar1"); + contikiDataCounter = varMem.getIntValueOf("var1"); + contikiBSSCounter = varMem.getIntValueOf("uvar1"); if (contikiDataCounter != javaDataCounter) { testOutput.addMessage("### Data section mismatch (" + contikiDataCounter + " != " + javaDataCounter + ")", MessageList.ERROR); return false; @@ -1004,8 +1031,8 @@ public class ConfigurationWizard extends JDialog { javaLibrary.getMemory(relBssSectionAddr, bssSectionSize, initialBssSection); memory.setMemorySegment(relDataSectionAddr, initialDataSection); memory.setMemorySegment(relBssSectionAddr, initialBssSection); - contikiDataCounter = memory.getIntValueOf("var1"); - contikiBSSCounter = memory.getIntValueOf("uvar1"); + contikiDataCounter = varMem.getIntValueOf("var1"); + contikiBSSCounter = varMem.getIntValueOf("uvar1"); if (contikiDataCounter != javaDataCounter) { testOutput.addMessage("### Data section mismatch (" + contikiDataCounter + " != " + javaDataCounter + ")", MessageList.ERROR); return false; @@ -1029,8 +1056,8 @@ public class ConfigurationWizard extends JDialog { javaLibrary.getMemory(relBssSectionAddr, bssSectionSize, initialBssSection); memory.setMemorySegment(relDataSectionAddr, initialDataSection); memory.setMemorySegment(relBssSectionAddr, initialBssSection); - contikiDataCounter = memory.getIntValueOf("var1"); - contikiBSSCounter = memory.getIntValueOf("uvar1"); + contikiDataCounter = varMem.getIntValueOf("var1"); + contikiBSSCounter = varMem.getIntValueOf("uvar1"); if (contikiDataCounter != javaDataCounter) { testOutput.addMessage("### Data section mismatch (" + contikiDataCounter + " != " + javaDataCounter + ")", MessageList.ERROR); return false; @@ -1049,8 +1076,8 @@ public class ConfigurationWizard extends JDialog { javaLibrary.getMemory(relBssSectionAddr, bssSectionSize, initialBssSection); memory.setMemorySegment(relDataSectionAddr, initialDataSection); memory.setMemorySegment(relBssSectionAddr, initialBssSection); - contikiDataCounter = memory.getIntValueOf("var1"); - contikiBSSCounter = memory.getIntValueOf("uvar1"); + contikiDataCounter = varMem.getIntValueOf("var1"); + contikiBSSCounter = varMem.getIntValueOf("uvar1"); if (contikiDataCounter != javaDataCounter) { testOutput.addMessage("### Data section mismatch (" + contikiDataCounter + " != " + javaDataCounter + ")", MessageList.ERROR); return false; diff --git a/tools/cooja/java/org/contikios/cooja/dialogs/MessageContainer.java b/tools/cooja/java/org/contikios/cooja/dialogs/MessageContainer.java new file mode 100644 index 000000000..89fea5593 --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/dialogs/MessageContainer.java @@ -0,0 +1,17 @@ +package org.contikios.cooja.dialogs; + +public class MessageContainer { + + public final int type; + public final String message; + + public MessageContainer(String message, int type) { + this.message = message; + this.type = type; + } + + @Override + public String toString() { + return message; + } +} diff --git a/tools/cooja/java/org/contikios/cooja/dialogs/MessageList.java b/tools/cooja/java/org/contikios/cooja/dialogs/MessageList.java index cb4dd926a..f0af5f405 100644 --- a/tools/cooja/java/org/contikios/cooja/dialogs/MessageList.java +++ b/tools/cooja/java/org/contikios/cooja/dialogs/MessageList.java @@ -1,345 +1,17 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * - * ----------------------------------------------------------------- - * - * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne, Fredrik Osterlind - * Created : 2006-06-14 - * Updated : $Date: 2009/11/13 14:27:46 $ - * $Revision: 1.15 $ - */ - package org.contikios.cooja.dialogs; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Toolkit; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.StringSelection; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.io.PrintStream; -import java.util.ArrayList; +public interface MessageList { -import javax.swing.DefaultListCellRenderer; -import javax.swing.DefaultListModel; -import javax.swing.JCheckBoxMenuItem; -import javax.swing.JList; -import javax.swing.JMenuItem; -import javax.swing.JPopupMenu; -import javax.swing.JSeparator; -import javax.swing.ListModel; -import javax.swing.ListSelectionModel; + public static final int NORMAL = 0; + public static final int WARNING = 1; + public static final int ERROR = 2; + + public void addMessage(String string, int normal); -import org.contikios.cooja.Cooja; + public MessageContainer[] getMessages(); -public class MessageList extends JList { + public void clearMessages(); - public static final int NORMAL = 0; - public static final int WARNING = 1; - public static final int ERROR = 2; + public void addMessage(String string); - private Color[] foregrounds = new Color[] { null, Color.red }; - private Color[] backgrounds = new Color[] { null, null }; - - private JPopupMenu popup = null; - private boolean hideNormal = false; - - private int max = -1; - - public MessageList() { - super.setModel(new MessageModel()); - setCellRenderer(new MessageRenderer()); - setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - } - - /** - * @param max Maximum number of messages - */ - public MessageList(int max) { - this(); - this.max = max; - } - - public Color getForeground(int type) { - Color c = type > 0 && type <= foregrounds.length - ? foregrounds[type - 1] : null; - return c == null ? getForeground() : c; - } - - public void setForeground(int type, Color color) { - if (type > 0 && type <= foregrounds.length) { - foregrounds[type - 1] = color; - } else if (type == NORMAL) { - setForeground(color); - } - } - - public Color getBackground(int type) { - Color c = type > 0 && type <= backgrounds.length - ? backgrounds[type - 1] : null; - return c == null ? getBackground() : c; - } - - public void setBackground(int type, Color color) { - if (type > 0 && type <= backgrounds.length) { - backgrounds[type - 1] = color; - } else if (type == NORMAL) { - setBackground(color); - } - } - - public PrintStream getInputStream(final int type) { - try { - PipedInputStream input = new PipedInputStream(); - PipedOutputStream output = new PipedOutputStream(input); - final BufferedReader stringInput = new BufferedReader(new InputStreamReader(input)); - - Thread readThread = new Thread(new Runnable() { - public void run() { - String readLine; - try { - while ((readLine = stringInput.readLine()) != null) { - addMessage(readLine, type); - } - } catch (IOException e) { - // Occurs when write end closes pipe - die quietly - } - } - - }); - readThread.start(); - - return new PrintStream(output); - } catch (Exception e) { - System.out.println("Exception: "+ e); - return null; - } - } - - public void addMessage(String message) { - addMessage(message, NORMAL); - } - - private ArrayList messages = new ArrayList(); - - public MessageContainer[] getMessages() { - return messages.toArray(new MessageContainer[0]); - } - - private void updateModel() { - boolean scroll = getLastVisibleIndex() >= getModel().getSize() - 2; - - while (messages.size() > getModel().getSize()) { - ((DefaultListModel) getModel()).addElement(messages.get(getModel().getSize())); - } - while (max > 0 && getModel().getSize() > max) { - ((DefaultListModel) getModel()).removeElementAt(0); - messages.remove(0); - } - - if (scroll) { - ensureIndexIsVisible(getModel().getSize() - 1); - } - } - - public void addMessage(final String message, final int type) { - Cooja.setProgressMessage(message, type); - - MessageContainer msg = new MessageContainer(message, type); - messages.add(msg); - - java.awt.EventQueue.invokeLater(new Runnable() { - public void run() { - updateModel(); - } - }); - } - - public void clearMessages() { - messages.clear(); - ((DefaultListModel) getModel()).clear(); - } - - public void setModel(ListModel model) { - throw new IllegalArgumentException("changing model not permitted"); - } - - public void addPopupMenuItem(JMenuItem item, boolean withDefaults) { - if (popup == null) { - popup = new JPopupMenu(); - addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.isPopupTrigger()) { - popup.show(MessageList.this, e.getX(), e.getY()); - } - } - public void mousePressed(MouseEvent e) { - if (e.isPopupTrigger()) { - popup.show(MessageList.this, e.getX(), e.getY()); - } - } - public void mouseReleased(MouseEvent e) { - if (e.isPopupTrigger()) { - popup.show(MessageList.this, e.getX(), e.getY()); - } - } - }); - - JMenuItem headerMenuItem = new JMenuItem("Output:"); - headerMenuItem.setEnabled(false); - popup.add(headerMenuItem); - popup.add(new JSeparator()); - - if (withDefaults) { - /* Create default menu items */ - final JMenuItem hideNormalMenuItem = new JCheckBoxMenuItem("Hide normal output"); - hideNormalMenuItem.setEnabled(true); - hideNormalMenuItem.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - MessageList.this.hideNormal = hideNormalMenuItem.isSelected(); - ((MessageModel)getModel()).updateList(); - } - }); - popup.add(hideNormalMenuItem); - - JMenuItem consoleOutputMenuItem = new JMenuItem("Output to console"); - consoleOutputMenuItem.setEnabled(true); - consoleOutputMenuItem.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - MessageContainer[] messages = getMessages(); - System.out.println("\nCOMPILATION OUTPUT:\n"); - for (MessageContainer msg: messages) { - if (hideNormal && msg.type == NORMAL) { - continue; - } - System.out.println(msg); - } - System.out.println(); - } - }); - popup.add(consoleOutputMenuItem); - - JMenuItem clipboardMenuItem = new JMenuItem("Copy to clipboard"); - clipboardMenuItem.setEnabled(true); - clipboardMenuItem.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - - StringBuilder sb = new StringBuilder(); - MessageContainer[] messages = getMessages(); - for (MessageContainer msg: messages) { - if (hideNormal && msg.type == NORMAL) { - continue; - } - sb.append(msg + "\n"); - } - - StringSelection stringSelection = new StringSelection(sb.toString()); - clipboard.setContents(stringSelection, null); - } - }); - popup.add(clipboardMenuItem); - - popup.add(new JSeparator()); - } - } - - if (item == null) { - return; - } - - popup.add(item); - } - - // ------------------------------------------------------------------- - // MessageContainer - // ------------------------------------------------------------------- - - public static class MessageContainer { - public final int type; - public final String message; - - public MessageContainer(String message, int type) { - this.message = message; - this.type = type; - } - - public String toString() { - return message; - } - - } // end of inner class MessageContainer - - - // ------------------------------------------------------------------- - // Renderer for messages - // ------------------------------------------------------------------- - - private class MessageModel extends DefaultListModel { - public void updateList() { - fireContentsChanged(this, 0, getSize()); - } - } - - private class MessageRenderer extends DefaultListCellRenderer { - private Dimension nullDimension = new Dimension(0,0); - public Component getListCellRendererComponent( - JList list, - Object value, - int index, - boolean isSelected, - boolean cellHasFocus) - { - super.getListCellRendererComponent(list, value, index, isSelected, - cellHasFocus); - MessageContainer msg = (MessageContainer) value; - - if (hideNormal && msg.type == NORMAL && index != MessageList.this.getModel().getSize()-1) { - setPreferredSize(nullDimension); - return this; - } - - setPreferredSize(null); - setForeground(((MessageList) list).getForeground(msg.type)); - setBackground(((MessageList) list).getBackground(msg.type)); - return this; - } - - } // end of inner class MessageRenderer - -} // end of MessagList +} diff --git a/tools/cooja/java/org/contikios/cooja/dialogs/MessageListText.java b/tools/cooja/java/org/contikios/cooja/dialogs/MessageListText.java new file mode 100644 index 000000000..bd24c3485 --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/dialogs/MessageListText.java @@ -0,0 +1,27 @@ +package org.contikios.cooja.dialogs; + +public class MessageListText implements MessageList { + + @Override + public void addMessage(String string, int type) { + System.out.println("Message:" + string); + } + + @Override + public MessageContainer[] getMessages() { + // TODO Auto-generated method stub + return new MessageContainer[0]; + } + + @Override + public void clearMessages() { + // TODO Auto-generated method stub + } + + @Override + public void addMessage(String string) { + // TODO Auto-generated method stub + addMessage(string, MessageList.NORMAL); + } + +} diff --git a/tools/cooja/java/org/contikios/cooja/dialogs/MessageListUI.java b/tools/cooja/java/org/contikios/cooja/dialogs/MessageListUI.java new file mode 100644 index 000000000..11449b7ef --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/dialogs/MessageListUI.java @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +package org.contikios.cooja.dialogs; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; +import java.util.ArrayList; + +import javax.swing.DefaultListCellRenderer; +import javax.swing.DefaultListModel; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JList; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.JSeparator; +import javax.swing.ListModel; +import javax.swing.ListSelectionModel; +import org.apache.log4j.Logger; + +import org.contikios.cooja.Cooja; + +/** + * + * @author Adam Dunkels + * @author Joakim Eriksson + * @author Niclas Finne + * @author Fredrik Osterlind + */ +public class MessageListUI extends JList implements MessageList { + + private static final Logger logger = Logger.getLogger(MessageListUI.class); + + private Color[] foregrounds = new Color[] { null, Color.red }; + private Color[] backgrounds = new Color[] { null, null }; + + private JPopupMenu popup = null; + private boolean hideNormal = false; + + private int max = -1; + + public MessageListUI() { + super.setModel(new MessageModel()); + setCellRenderer(new MessageRenderer()); + setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + } + + /** + * @param max Maximum number of messages + */ + public MessageListUI(int max) { + this(); + this.max = max; + } + + public Color getForeground(int type) { + Color c = type > 0 && type <= foregrounds.length + ? foregrounds[type - 1] : null; + return c == null ? getForeground() : c; + } + + public void setForeground(int type, Color color) { + if (type > 0 && type <= foregrounds.length) { + foregrounds[type - 1] = color; + } else if (type == NORMAL) { + setForeground(color); + } + } + + public Color getBackground(int type) { + Color c = type > 0 && type <= backgrounds.length + ? backgrounds[type - 1] : null; + return c == null ? getBackground() : c; + } + + public void setBackground(int type, Color color) { + if (type > 0 && type <= backgrounds.length) { + backgrounds[type - 1] = color; + } else if (type == NORMAL) { + setBackground(color); + } + } + + public PrintStream getInputStream(final int type) { + try { + PipedInputStream input = new PipedInputStream(); + PipedOutputStream output = new PipedOutputStream(input); + final BufferedReader stringInput = new BufferedReader(new InputStreamReader(input)); + + Thread readThread = new Thread(new Runnable() { + @Override + public void run() { + String readLine; + try { + while ((readLine = stringInput.readLine()) != null) { + addMessage(readLine, type); + } + } catch (IOException e) { + // Occurs when write end closes pipe - die quietly + } + } + + }); + readThread.start(); + + return new PrintStream(output); + } catch (IOException e) { + logger.error(messages); + return null; + } + } + + public void addMessage(String message) { + addMessage(message, NORMAL); + } + + private ArrayList messages = new ArrayList(); + + public MessageContainer[] getMessages() { + return messages.toArray(new MessageContainer[0]); + } + + private void updateModel() { + boolean scroll = getLastVisibleIndex() >= getModel().getSize() - 2; + + while (messages.size() > getModel().getSize()) { + ((DefaultListModel) getModel()).addElement(messages.get(getModel().getSize())); + } + while (max > 0 && getModel().getSize() > max) { + ((DefaultListModel) getModel()).removeElementAt(0); + messages.remove(0); + } + + if (scroll) { + ensureIndexIsVisible(getModel().getSize() - 1); + } + } + + public void addMessage(final String message, final int type) { + Cooja.setProgressMessage(message, type); + + MessageContainer msg = new MessageContainer(message, type); + messages.add(msg); + + java.awt.EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + updateModel(); + } + }); + } + + public void clearMessages() { + messages.clear(); + ((DefaultListModel) getModel()).clear(); + } + + @Override + public void setModel(ListModel model) { + throw new IllegalArgumentException("changing model not permitted"); + } + + public void addPopupMenuItem(JMenuItem item, boolean withDefaults) { + if (popup == null) { + popup = new JPopupMenu(); + addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.isPopupTrigger()) { + popup.show(MessageListUI.this, e.getX(), e.getY()); + } + } + @Override + public void mousePressed(MouseEvent e) { + if (e.isPopupTrigger()) { + popup.show(MessageListUI.this, e.getX(), e.getY()); + } + } + @Override + public void mouseReleased(MouseEvent e) { + if (e.isPopupTrigger()) { + popup.show(MessageListUI.this, e.getX(), e.getY()); + } + } + }); + + JMenuItem headerMenuItem = new JMenuItem("Output:"); + headerMenuItem.setEnabled(false); + popup.add(headerMenuItem); + popup.add(new JSeparator()); + + if (withDefaults) { + /* Create default menu items */ + final JMenuItem hideNormalMenuItem = new JCheckBoxMenuItem("Hide normal output"); + hideNormalMenuItem.setEnabled(true); + hideNormalMenuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + MessageListUI.this.hideNormal = hideNormalMenuItem.isSelected(); + ((MessageModel)getModel()).updateList(); + } + }); + popup.add(hideNormalMenuItem); + + JMenuItem consoleOutputMenuItem = new JMenuItem("Output to console"); + consoleOutputMenuItem.setEnabled(true); + consoleOutputMenuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + MessageContainer[] messages = getMessages(); + logger.info("\nCOMPILATION OUTPUT:\n"); + for (MessageContainer msg: messages) { + if (hideNormal && msg.type == NORMAL) { + continue; + } + logger.info(msg); + } + logger.info("\n"); + } + }); + popup.add(consoleOutputMenuItem); + + JMenuItem clipboardMenuItem = new JMenuItem("Copy to clipboard"); + clipboardMenuItem.setEnabled(true); + clipboardMenuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + + StringBuilder sb = new StringBuilder(); + MessageContainer[] messages = getMessages(); + for (MessageContainer msg: messages) { + if (hideNormal && msg.type == NORMAL) { + continue; + } + sb.append(msg + "\n"); + } + + StringSelection stringSelection = new StringSelection(sb.toString()); + clipboard.setContents(stringSelection, null); + } + }); + popup.add(clipboardMenuItem); + + popup.add(new JSeparator()); + } + } + + if (item == null) { + return; + } + + popup.add(item); + } + + // ------------------------------------------------------------------- + // Renderer for messages + // ------------------------------------------------------------------- + + private class MessageModel extends DefaultListModel { + public void updateList() { + fireContentsChanged(this, 0, getSize()); + } + } + + private class MessageRenderer extends DefaultListCellRenderer { + private Dimension nullDimension = new Dimension(0,0); + @Override + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) + { + super.getListCellRendererComponent(list, value, index, isSelected, + cellHasFocus); + MessageContainer msg = (MessageContainer) value; + + if (hideNormal && msg.type == NORMAL && index != MessageListUI.this.getModel().getSize()-1) { + setPreferredSize(nullDimension); + return this; + } + + setPreferredSize(null); + setForeground(((MessageListUI) list).getForeground(msg.type)); + setBackground(((MessageListUI) list).getBackground(msg.type)); + return this; + } + + } // end of inner class MessageRenderer + +} // end of MessagList diff --git a/tools/cooja/java/org/contikios/cooja/dialogs/SerialUI.java b/tools/cooja/java/org/contikios/cooja/dialogs/SerialUI.java index bcc1a0734..430939482 100644 --- a/tools/cooja/java/org/contikios/cooja/dialogs/SerialUI.java +++ b/tools/cooja/java/org/contikios/cooja/dialogs/SerialUI.java @@ -165,8 +165,7 @@ public abstract class SerialUI extends Log implements SerialPort { writeString(command); } } catch (Exception ex) { - System.err.println("could not send '" + command + "':"); - ex.printStackTrace(); + logger.error("could not send '" + command + "':", ex); JOptionPane.showMessageDialog( logTextPane, "Could not send '" + command + "':\n" + ex.getMessage(), "Error sending message", diff --git a/tools/cooja/java/org/contikios/cooja/emulatedmote/Radio802154.java b/tools/cooja/java/org/contikios/cooja/emulatedmote/Radio802154.java index 4e50daada..6af42871f 100644 --- a/tools/cooja/java/org/contikios/cooja/emulatedmote/Radio802154.java +++ b/tools/cooja/java/org/contikios/cooja/emulatedmote/Radio802154.java @@ -29,12 +29,7 @@ */ package org.contikios.cooja.emulatedmote; -import java.awt.BorderLayout; -import java.awt.GridLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.util.*; -import javax.swing.*; import org.apache.log4j.Logger; import org.jdom.Element; @@ -53,7 +48,7 @@ public abstract class Radio802154 extends Radio implements CustomDataRadio { private final static boolean DEBUG = false; - private static Logger logger = Logger.getLogger(Radio802154.class); + private static final Logger logger = Logger.getLogger(Radio802154.class); protected long lastEventTime = 0; @@ -103,10 +98,9 @@ public abstract class Radio802154 extends Radio implements CustomDataRadio { buffer[len++] = val; - //System.out.println("## 802.15.4: " + (val&0xff) + " transmitted..."); + logger.debug("802.15.4: " + (val & 0xff) + " transmitted..."); if (len == 6) { - //System.out.println("## CC2420 Packet of length: " + val + " expected..."); expLen = val + 6; } @@ -120,10 +114,8 @@ public abstract class Radio802154 extends Radio implements CustomDataRadio { setChanged(); notifyObservers(); - // System.out.println("## CC2420 Transmission finished..."); - lastEventTime = mote.getSimulation().getSimulationTime(); - /*logger.debug("----- SKY TRANSMISSION FINISHED -----");*/ + logger.debug("----- 802.15.4 TRANSMISSION FINISHED -----"); lastEvent = RadioEvent.TRANSMISSION_FINISHED; setChanged(); notifyObservers(); @@ -132,26 +124,32 @@ public abstract class Radio802154 extends Radio implements CustomDataRadio { } /* Packet radio support */ + @Override public RadioPacket getLastPacketTransmitted() { return lastOutgoingPacket; } + @Override public RadioPacket getLastPacketReceived() { return lastIncomingPacket; } + @Override public void setReceivedPacket(RadioPacket packet) { } /* Custom data radio support */ + @Override public Object getLastCustomDataTransmitted() { return lastOutgoingByte; } + @Override public Object getLastCustomDataReceived() { return lastIncomingByte; } + @Override public void receiveCustomData(Object data) { if (data instanceof RadioByte) { lastIncomingByte = (RadioByte) data; @@ -160,14 +158,17 @@ public abstract class Radio802154 extends Radio implements CustomDataRadio { } /* General radio support */ + @Override public boolean isTransmitting() { return isTransmitting; } + @Override public boolean isReceiving() { return isReceiving; } + @Override public boolean isInterfered() { return isInterfered; } @@ -176,23 +177,31 @@ public abstract class Radio802154 extends Radio implements CustomDataRadio { protected abstract void handleEndOfReception(); + @Override public abstract int getChannel(); public abstract int getFrequency(); + @Override public abstract boolean isRadioOn(); + @Override public abstract double getCurrentOutputPower(); + @Override public abstract int getCurrentOutputPowerIndicator(); + @Override public abstract int getOutputPowerIndicatorMax(); + @Override public abstract double getCurrentSignalStrength(); + @Override public abstract void setCurrentSignalStrength(double signalStrength); /* need to add a few more methods later??? */ + @Override public void signalReceptionStart() { isReceiving = true; @@ -207,6 +216,7 @@ public abstract class Radio802154 extends Radio implements CustomDataRadio { notifyObservers(); } + @Override public void signalReceptionEnd() { /* Deliver packet data */ isReceiving = false; @@ -226,10 +236,12 @@ public abstract class Radio802154 extends Radio implements CustomDataRadio { notifyObservers(); } + @Override public RadioEvent getLastEvent() { return lastEvent; } + @Override public void interfereAnyReception() { isInterfered = true; isReceiving = false; @@ -249,18 +261,22 @@ public abstract class Radio802154 extends Radio implements CustomDataRadio { notifyObservers(); } + @Override public Mote getMote() { return mote; } + @Override public Position getPosition() { return mote.getInterfaces().getPosition(); } + @Override public Collection getConfigXML() { return null; } + @Override public void setConfigXML(Collection configXML, boolean visAvailable) { } } diff --git a/tools/cooja/java/org/contikios/cooja/interfaces/Button.java b/tools/cooja/java/org/contikios/cooja/interfaces/Button.java index 549c5ba65..b32cfe315 100644 --- a/tools/cooja/java/org/contikios/cooja/interfaces/Button.java +++ b/tools/cooja/java/org/contikios/cooja/interfaces/Button.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2014, TU Braunschweig. * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. * @@ -30,7 +31,15 @@ package org.contikios.cooja.interfaces; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Collection; +import javax.swing.JButton; +import javax.swing.JPanel; import org.contikios.cooja.*; +import org.jdom.Element; /** * A Button represents a mote button. An implementation should notify all @@ -42,24 +51,151 @@ import org.contikios.cooja.*; @ClassDescription("Button") public abstract class Button extends MoteInterface { + private final Simulation sim; + + private final MoteTimeEvent pressButtonEvent; + private final MoteTimeEvent releaseButtonEvent; + + public Button(Mote mote) { + sim = mote.getSimulation(); + + pressButtonEvent = new MoteTimeEvent(mote, 0) { + @Override + public void execute(long t) { + doPressButton(); + } + }; + releaseButtonEvent = new MoteTimeEvent(mote, 0) { + @Override + public void execute(long t) { + doReleaseButton(); + } + }; + } + /** * Clicks button. Button will be pressed for some time and then automatically * released. */ - public abstract void clickButton(); + public void clickButton() { + sim.invokeSimulationThread(new Runnable() { + @Override + public void run() { + sim.scheduleEvent(pressButtonEvent, sim.getSimulationTime()); + sim.scheduleEvent(releaseButtonEvent, sim.getSimulationTime() + Simulation.MILLISECOND); + } + }); + } /** - * Releases button (if pressed). + * Presses button. */ - public abstract void releaseButton(); + public void pressButton() { + sim.invokeSimulationThread(new Runnable() { + @Override + public void run() { + sim.scheduleEvent(pressButtonEvent, sim.getSimulationTime()); + } + }); + } /** - * Presses button (if not already pressed). + * Node-type dependent implementation of pressing a button. */ - public abstract void pressButton(); + protected abstract void doPressButton(); + + /** + * Releases button. + */ + public void releaseButton() { + sim.invokeSimulationThread(new Runnable() { + @Override + public void run() { + sim.scheduleEvent(releaseButtonEvent, sim.getSimulationTime()); + } + }); + } + + /** + * Node-type dependent implementation of releasing a button. + */ + protected abstract void doReleaseButton(); /** * @return True if button is pressed */ public abstract boolean isPressed(); + + @Override + public JPanel getInterfaceVisualizer() { + JPanel panel = new JPanel(); + final JButton clickButton = new JButton("Click button"); + + panel.add(clickButton); + + clickButton.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + sim.invokeSimulationThread(new Runnable() { + + @Override + public void run() { + doPressButton(); + } + }); + } + + @Override + public void mouseReleased(MouseEvent e) { + sim.invokeSimulationThread(new Runnable() { + + @Override + public void run() { + doReleaseButton(); + } + }); + } + }); + + clickButton.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + sim.invokeSimulationThread(new Runnable() { + + @Override + public void run() { + doPressButton(); + } + }); + } + + @Override + public void keyReleased(KeyEvent e) { + sim.invokeSimulationThread(new Runnable() { + + @Override + public void run() { + doReleaseButton(); + } + }); + } + }); + + return panel; + } + + @Override + public void releaseInterfaceVisualizer(JPanel panel) { + } + + @Override + public Collection getConfigXML() { + // The button state will not be saved! + return null; + } + + @Override + public void setConfigXML(Collection configXML, boolean visAvailable) { + // The button state will not be saved! + } } diff --git a/tools/cooja/java/org/contikios/cooja/interfaces/Clock.java b/tools/cooja/java/org/contikios/cooja/interfaces/Clock.java index faefaddfc..58ec05fa5 100644 --- a/tools/cooja/java/org/contikios/cooja/interfaces/Clock.java +++ b/tools/cooja/java/org/contikios/cooja/interfaces/Clock.java @@ -30,7 +30,19 @@ package org.contikios.cooja.interfaces; +import java.awt.GridLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.Collection; + +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; + import org.contikios.cooja.*; +import org.jdom.Element; /** * Represents a mote's internal clock. Notice that the overall @@ -39,10 +51,10 @@ import org.contikios.cooja.*; * This observable never notifies. * * @author Fredrik Osterlind + * Andreas Löscher */ @ClassDescription("Clock") public abstract class Clock extends MoteInterface { - /** * Set mote's time to given time. * @@ -76,4 +88,88 @@ public abstract class Clock extends MoteInterface { */ public abstract long getDrift(); + + /** + * The clock deviation is a factor that represents with how much speed the + * mote progresses through the simulation in relation to the simulation speed. + * + * A value of 1.0 results in the mote being simulated with the same speed + * as the simulation. A value of 0.5 results in the mote being simulation + * at half of the simulation speed. + * + * @param deviation Deviation factor + */ + public abstract void setDeviation(double deviation); + + /** + * Get deviation factor + */ + public abstract double getDeviation(); + + @Override + public JPanel getInterfaceVisualizer() { + JPanel panel = new JPanel(); + GridLayout layout = new GridLayout(0,2); + + /* elements */ + final JLabel timeLabel = new JLabel("Time (ms)"); + final JTextField timeField = new JTextField(String.valueOf(getTime() / 1000)); + final JLabel deviationLabel = new JLabel("Deviation Factor"); + final JTextField deviationField = new JTextField(String.valueOf(getDeviation())); + final JButton readButton = new JButton("Read Clock Values"); + final JButton updateButton = new JButton("Write Clock Values"); + /* set layout */ + panel.setLayout(layout); + /* add components */ + panel.add(timeLabel); + panel.add(timeField); + panel.add(deviationLabel); + panel.add(deviationField); + panel.add(readButton); + panel.add(updateButton); + + readButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent ev) { + if (ev.getButton()==1) { + timeField.setText(String.valueOf(getTime() / 1000)); + deviationField.setText(String.valueOf(getDeviation())); + } + } + }); + + updateButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent ev) { + if (ev.getButton()==1) { + setTime(Long.parseLong(timeField.getText()) * 1000); + setDeviation(Double.parseDouble(deviationField.getText())); + } + } + }); + + return panel; + } + + @Override + public void releaseInterfaceVisualizer(JPanel panel) { + } + + @Override + public Collection getConfigXML() { + ArrayList config = new ArrayList(); + Element element = new Element("deviation"); + element.setText(String.valueOf(getDeviation())); + config.add(element); + return config; + } + + @Override + public void setConfigXML(Collection configXML, boolean visAvailable) { + for (Element element : configXML) { + if (element.getName().equals("deviation")) { + setDeviation(Double.parseDouble(element.getText())); + } + } + } } diff --git a/tools/cooja/java/org/contikios/cooja/interfaces/DirectionalAntennaRadio.java b/tools/cooja/java/org/contikios/cooja/interfaces/DirectionalAntennaRadio.java index 59373fc68..207c344f4 100644 --- a/tools/cooja/java/org/contikios/cooja/interfaces/DirectionalAntennaRadio.java +++ b/tools/cooja/java/org/contikios/cooja/interfaces/DirectionalAntennaRadio.java @@ -1,65 +1,65 @@ -/* - * Copyright (c) 2011, Swedish Institute of Computer Science. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. 2. 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. 3. Neither the name of the - * Institute 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 INSTITUTE 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 INSTITUTE 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. - * - */ - -package org.contikios.cooja.interfaces; - -/** - * Directional antenna. - * - * @see MRM - * @author Fredrik Osterlind - */ -public interface DirectionalAntennaRadio { - - /** - * @return Current direction (radians). Typically direction 0 has the maximum - * relative gain. - * - * @see #getRelativeGain(double) - */ - public double getDirection(); - - /** - * Relative gain (dB) as compared to an omnidirectional antenna. - * Note that the given angle is relative to the current direction! - * - * @see #getDirection() - * @param radians Angle relative to current direction - * @param distance Distance from antenna - * @return - */ - public double getRelativeGain(double radians, double distance); - - public void addDirectionChangeListener(DirectionChangeListener l); - public void removeDirectionChangeListener(DirectionChangeListener l); - - public interface DirectionChangeListener { - public void newDirection(DirectionalAntennaRadio radio, double direction); - } - -} +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. 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. 3. Neither the name of the + * Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +package org.contikios.cooja.interfaces; + +/** + * Directional antenna. + * + * @see MRM + * @author Fredrik Osterlind + */ +public interface DirectionalAntennaRadio { + + /** + * @return Current direction (radians). Typically direction 0 has the maximum + * relative gain. + * + * @see #getRelativeGain(double) + */ + public double getDirection(); + + /** + * Relative gain (dB) as compared to an omnidirectional antenna. + * Note that the given angle is relative to the current direction! + * + * @see #getDirection() + * @param radians Angle relative to current direction + * @param distance Distance from antenna + * @return + */ + public double getRelativeGain(double radians, double distance); + + public void addDirectionChangeListener(DirectionChangeListener l); + public void removeDirectionChangeListener(DirectionChangeListener l); + + public interface DirectionChangeListener { + public void newDirection(DirectionalAntennaRadio radio, double direction); + } + +} diff --git a/tools/cooja/java/org/contikios/cooja/interfaces/IPAddress.java b/tools/cooja/java/org/contikios/cooja/interfaces/IPAddress.java index 7216f8010..2c47d3867 100644 --- a/tools/cooja/java/org/contikios/cooja/interfaces/IPAddress.java +++ b/tools/cooja/java/org/contikios/cooja/interfaces/IPAddress.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2014, TU Braunschweig. * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. * @@ -30,205 +31,313 @@ package org.contikios.cooja.interfaces; import java.util.Collection; +import java.util.LinkedList; +import java.util.List; import java.util.Observable; import java.util.Observer; - import javax.swing.JLabel; import javax.swing.JPanel; - import org.apache.log4j.Logger; -import org.jdom.Element; - import org.contikios.cooja.ClassDescription; import org.contikios.cooja.Mote; import org.contikios.cooja.MoteInterface; -import org.contikios.cooja.MoteMemory; -import org.contikios.cooja.MoteMemory.MemoryEventType; -import org.contikios.cooja.MoteMemory.MemoryMonitor; +import org.contikios.cooja.mote.memory.MemoryInterface; +import org.contikios.cooja.mote.memory.MemoryInterface.SegmentMonitor; +import org.contikios.cooja.mote.memory.MemoryLayout; +import org.contikios.cooja.mote.memory.VarMemory; +import org.contikios.cooja.util.IPUtils; +import org.jdom.Element; /** * Read-only interface to IPv4 or IPv6 address. * * @author Fredrik Osterlind + * @author Enrico Joerns */ -@ClassDescription("IP Address") +@ClassDescription("IP Addresses") public class IPAddress extends MoteInterface { - private static Logger logger = Logger.getLogger(IPAddress.class); - private final MoteMemory moteMem; + private static final Logger logger = Logger.getLogger(IPAddress.class); private static final int IPv6_MAX_ADDRESSES = 4; - private boolean ipv6IsGlobal = false; - private int ipv6AddressIndex = -1; - private static final int MONITORED_SIZE = 150; - private MemoryMonitor memMonitor; + + private enum IPv { + NONE, + IPv4, + IPv6 + } + + private final IPv ipVersion; + + private final VarMemory moteMem; + private final MemoryLayout memLayout; + private IPContainer localIPAddr = null; + + private final SegmentMonitor memMonitor; + + private List ipList = new LinkedList<>(); + + private int ipv6_addr_size = 0; + private int ipv6_addr_list_offset = 0; public IPAddress(final Mote mote) { - moteMem = mote.getMemory(); + moteMem = new VarMemory(mote.getMemory()); + memLayout = mote.getMemory().getLayout(); - memMonitor = new MemoryMonitor() { - public void memoryChanged(MoteMemory memory, MemoryEventType type, int address) { - if (type != MemoryEventType.WRITE) { + /* If the ip memory sections changed, we recalculate addresses + * and notify our observers.*/ + memMonitor = new MemoryInterface.SegmentMonitor() { + int accessCount = 0; + long lastAccess = 0; + @Override + public void memoryChanged(MemoryInterface memory, SegmentMonitor.EventType type, long address) { + if (type != SegmentMonitor.EventType.WRITE) { return; } - setChanged(); - notifyObservers(); + + /* XXX Quick & Dirty IPv4 update handle */ + if (ipVersion == IPv.IPv4) { + updateIPAddresses(); + setChanged(); + notifyObservers(); + return; + } + + /* Wait until size and offsest values are set initially, + * then add memory monitor for each ip field */ + if ((ipv6_addr_list_offset == 0) || (ipv6_addr_size == 0)) { + ipv6_addr_list_offset = moteMem.getByteValueOf("uip_ds6_netif_addr_list_offset"); + ipv6_addr_size = moteMem.getByteValueOf("uip_ds6_addr_size"); + /* If the variables just updated, add the final ip listeners */ + if ((ipv6_addr_list_offset != 0) && (ipv6_addr_size != 0)) { + /* Add monitor for each IP region */ + for (int i = 0; i < IPv6_MAX_ADDRESSES; i++) { + long addr_of_ip = moteMem.getVariableAddress("uip_ds6_if") // start address of interface + + ipv6_addr_list_offset // offset to ip address region + + i * ipv6_addr_size // offset to ith ip address + + 1 + memory.getLayout().getPaddingBytesFor( + MemoryLayout.DataType.INT8, + MemoryLayout.DataType.INT16); // skip 'isused' + moteMem.addMemoryMonitor( + EventType.WRITE, + addr_of_ip, + 16, /* Size of ip address in byte */ + memMonitor); + } + /* Initial scan for IP address */ + updateIPAddresses(); + if (ipList.size() > 0) { + setChanged(); + notifyObservers(); + } + /** @TODO: Remove other listeners? */ + } + } else { + + /** Note: works when 'isused' bit is set first + * and address region is written sequentially */ + + /* check for sequential reading of 16 byte block */ + if (address == lastAccess + 1) { + accessCount++; + lastAccess = address; + if (accessCount == 16) { + updateIPAddresses(); + setChanged(); + notifyObservers(); + lastAccess = 0; + } + } + else { + /* Check if ip write was interrupted unexpectedly last time */ + if (lastAccess != 0) { + updateIPAddresses(); + setChanged(); + notifyObservers(); + } + accessCount = 1; + lastAccess = address; + } + } } }; - if (isVersion4()) { - moteMem.addMemoryMonitor(moteMem.getVariableAddress("uip_hostaddr"), 4, memMonitor); - } else if (isVersion6()) { - moteMem.addMemoryMonitor(moteMem.getVariableAddress("uip_ds6_netif_addr_list_offset"), 1, memMonitor); - moteMem.addMemoryMonitor(moteMem.getVariableAddress("uip_ds6_addr_size"), 1, memMonitor); - moteMem.addMemoryMonitor(moteMem.getVariableAddress("uip_ds6_if"), MONITORED_SIZE, memMonitor); + + /* Determine IP version an add MemoryMonitors */ + if (moteMem.variableExists("uip_hostaddr")) { + logger.debug("IPv4 detected"); + ipVersion = IPv.IPv4; + moteMem.addVarMonitor( + SegmentMonitor.EventType.WRITE, + "uip_hostaddr", + memMonitor); + } else if (moteMem.variableExists("uip_ds6_netif_addr_list_offset") + && moteMem.variableExists("uip_ds6_addr_size") + && moteMem.variableExists("uip_ds6_if")) { + logger.debug("IPv6 detected"); + ipVersion = IPv.IPv6; + moteMem.addVarMonitor( + SegmentMonitor.EventType.WRITE, + "uip_ds6_netif_addr_list_offset", + memMonitor); + moteMem.addVarMonitor( + SegmentMonitor.EventType.WRITE, + "uip_ds6_addr_size", + memMonitor); + } else { + ipVersion = IPv.NONE; } + + // initially look for IPs we already have + updateIPAddresses(); + } + + /** + * Returns true if any IP stack (Ipv4/6) is supported by mote + * @return true if either IPv4 or IPv6 was detected + */ + public boolean hasIP() { + return !(ipVersion == IPv.NONE); + } + + /** + * Get local IP of mote. + * @return local IP or null if not existing + */ + public IPContainer getLocalIP() { + return localIPAddr; } /** * Returns IP address string. * Supports both IPv4 and IPv6 addresses. * + * @param idx * @return IP address string */ - public String getIPString() { - if (isVersion4()) { - String ipString = ""; - byte[] ip = moteMem.getByteArray("uip_hostaddr", 4); - for (int i=0; i < 3; i++) { - ipString += (0xFF & ip[i]) + "."; + public IPContainer getIP(int idx) { + try { + return ipList.get(idx); + } catch (IndexOutOfBoundsException ex) { + logger.warn("Invalid IP index " + idx); + return null; + } + } + + /** + * Rereads IP addresses from memory and updates localIP entry. + */ + private void updateIPAddresses() { + ipList.clear(); + if (ipVersion == IPv.IPv4) { + addIPv4Addresses(); + localIPAddr = ipList.get(0); + } + else if (ipVersion == IPv.IPv6) { + addIPv6Addresses(); + /* look for local ip addr */ + for (IPContainer c : ipList) { + if (!c.isGlobal) { + localIPAddr = c; + } } - ipString += (0xFF & ip[3]); - return ipString; - } else if (isVersion6()) { - String ipString = getUncompressedIPv6Address(); - return compressIPv6Address(ipString); } - return null; - } - - public static String compressIPv6Address(String ipString) { - if (ipString.contains(":0000:0000:0000:0000:")) { - ipString = ipString.replace(":0000:0000:0000:0000:", "::"); - } else if (ipString.contains(":0000:0000:0000:")) { - ipString = ipString.replace(":0000:0000:0000:", "::"); - } else if (ipString.contains(":0000:0000:")) { - ipString = ipString.replace(":0000:0000:", "::"); - } else if (ipString.contains(":0000:")) { - ipString = ipString.replace(":0000:", "::"); - } - while (ipString.contains(":0")) { - ipString = ipString.replaceAll(":0", ":"); - } - return ipString; - } - - public byte[] getIPv6Address() { - byte[] ip = null; - - /* IpV6: Struct sizes and offsets */ - int ipv6NetworkInterfaceAddressOffset = moteMem.getByteValueOf("uip_ds6_netif_addr_list_offset"); - int ipv6AddressStructSize = moteMem.getByteValueOf("uip_ds6_addr_size"); - if (ipv6NetworkInterfaceAddressOffset == 0 || ipv6AddressStructSize == 0) { - return null; - } - - /* TODO No need to copy the entire array! */ - byte[] structData = moteMem.getByteArray("uip_ds6_if", - ipv6NetworkInterfaceAddressOffset+IPv6_MAX_ADDRESSES*ipv6AddressStructSize); - - ipv6AddressIndex = -1; - for (int addressIndex=0; addressIndex < IPv6_MAX_ADDRESSES; addressIndex++) { - int offset = ipv6NetworkInterfaceAddressOffset+addressIndex*ipv6AddressStructSize; - byte isUsed = structData[offset]; - if (isUsed == 0) { - continue; - } - byte[] addressData = new byte[16]; - System.arraycopy( - structData, offset+2/* ipaddr offset */, - addressData, 0, 16); - - if (addressData[0] == (byte)0xFE && addressData[1] == (byte)0x80) { - ipv6IsGlobal = false; - } else { - ipv6IsGlobal = true; - } - - ip = addressData; - ipv6AddressIndex = addressIndex; - if (ipv6IsGlobal) { - break; - } - } - if (ip == null) { - ip = new byte[16]; - ipv6AddressIndex = -1; - } - return ip; - } - - public static String getUncompressedIPv6AddressString(byte[] ip) { - StringBuilder sb = new StringBuilder(); - for (int i=0; i < 14; i+=2) { - sb.append(String.format("%02x%02x:", 0xFF&ip[i+0], 0xFF&ip[i+1])); - } - sb.append(String.format("%02x%02x", 0xFF&ip[14], 0xFF&ip[15])); - return sb.toString(); - } - - public String getUncompressedIPv6Address() { - byte[] ip = getIPv6Address(); - if (ip == null) { - return ""; - } - return getUncompressedIPv6AddressString(ip); } /** - * @return True if mote has an IPv4 address + * Rereads IPv4 addresses from memory. */ - public boolean isVersion4() { - return moteMem.variableExists("uip_hostaddr"); + private void addIPv4Addresses() { + ipList.add(new IPContainer(0, moteMem.getByteArray("uip_hostaddr", 4), true)); } /** - * @return True if mote has an IPv6 address + * Rereads IPv6 addresses from memory. */ - public boolean isVersion6() { - return - moteMem.variableExists("uip_ds6_netif_addr_list_offset") && - moteMem.variableExists("uip_ds6_addr_size") && - moteMem.variableExists("uip_ds6_if"); + private void addIPv6Addresses() { + + /* IpV6: Struct sizes and offsets */ + int ipv6NetworkInterfaceAddressOffset = moteMem.getByteValueOf("uip_ds6_netif_addr_list_offset"); + int ipv6AddressStructSize = moteMem.getByteValueOf("uip_ds6_addr_size"); + /* check if addresses were not set yet */ + if (ipv6NetworkInterfaceAddressOffset == 0 || ipv6AddressStructSize == 0) { + return; + } + + byte[] structData = moteMem.getByteArray( + moteMem.getVariableAddress("uip_ds6_if") + ipv6NetworkInterfaceAddressOffset, + IPv6_MAX_ADDRESSES * ipv6AddressStructSize); + + for (int addressIndex = 0; addressIndex < IPv6_MAX_ADDRESSES; addressIndex++) { + int offset = addressIndex * ipv6AddressStructSize; + byte isUsed = structData[offset]; + if (isUsed == 0) { + continue; + } + byte[] addressData = new byte[16]; + System.arraycopy( + structData, offset + 1 + memLayout.getPaddingBytesFor( + MemoryLayout.DataType.INT8, + MemoryLayout.DataType.INT16),/* ipaddr offset */ + addressData, 0, 16); + + if (((addressData[0] & (byte) 0xFF) == (byte) 0xFE) && ((addressData[1] & (byte) 0xFF) == (byte) 0x80)) { + ipList.add(new IPContainer(addressIndex, addressData, false)); + } + else { + ipList.add(new IPContainer(addressIndex, addressData, true)); + } + + } } + // -- MoteInterface overrides + + @Override public void removed() { super.removed(); if (memMonitor != null) { - if (isVersion4()) { - moteMem.removeMemoryMonitor(moteMem.getVariableAddress("rimeaddr_node_addr"), 4, memMonitor); - } else if (isVersion6()) { - moteMem.removeMemoryMonitor(moteMem.getVariableAddress("uip_ds6_netif_addr_list_offset"), 1, memMonitor); - moteMem.removeMemoryMonitor(moteMem.getVariableAddress("uip_ds6_addr_size"), 1, memMonitor); - moteMem.removeMemoryMonitor(moteMem.getVariableAddress("uip_ds6_if"), MONITORED_SIZE, memMonitor); + if (ipVersion == IPv.IPv4) { + moteMem.removeVarMonitor("uip_hostaddr",memMonitor); + } + else if (ipVersion == IPv.IPv6) { + moteMem.removeVarMonitor("uip_ds6_netif_addr_list_offset", memMonitor); + moteMem.removeVarMonitor("uip_ds6_addr_size", memMonitor); + moteMem.removeVarMonitor("uip_ds6_if", memMonitor); } } } + @Override public JPanel getInterfaceVisualizer() { JPanel panel = new JPanel(); final JLabel ipLabel = new JLabel(); Observer observer; this.addObserver(observer = new Observer() { + @Override public void update(Observable obs, Object obj) { - if (isVersion4()) { - ipLabel.setText("IPv4 address: " + getIPString()); - } else if (isVersion6()) { - ipLabel.setText((ipv6IsGlobal?"Global":"Local") + - " IPv6 address(#" + ipv6AddressIndex + "): " + getIPString()); - } else { - ipLabel.setText("Unknown IP"); + StringBuilder ipStr = new StringBuilder(); + ipStr.append(""); + for (IPContainer ipc: ipList) { + if (ipVersion == IPv.IPv4) { + ipStr.append("IPv4 address: ") + .append(ipc.toString()) + .append("
    "); + } + else if (ipVersion == IPv.IPv6) { + ipStr.append(ipc.isGlobal() ? "Global" : "Local") + .append(" IPv6 address(#") + .append(ipc.getAddID()) + .append("): ") + .append(ipc.toString()) + .append("
    "); + } + else { + ipStr.append("Unknown IP
    "); + } } + ipStr.append(""); + ipLabel.setText(ipStr.toString()); } }); observer.update(null, null); @@ -239,6 +348,7 @@ public class IPAddress extends MoteInterface { return panel; } + @Override public void releaseInterfaceVisualizer(JPanel panel) { Observer observer = (Observer) panel.getClientProperty("intf_obs"); if (observer == null) { @@ -248,10 +358,68 @@ public class IPAddress extends MoteInterface { this.deleteObserver(observer); } + @Override public Collection getConfigXML() { return null; } + @Override public void setConfigXML(Collection configXML, boolean visAvailable) { } + + /** + * Holds a single IP address. + * + * Note: The compressed IP version is already computed in constructor + */ + public class IPContainer { + + private boolean isGlobal = false; + private final byte[] ip; + private final int addrIdx; + private final String cprString; + + public IPContainer(int addidx, byte[] ip, boolean global) { + this.addrIdx = addidx; + this.ip = ip; + this.isGlobal = global; + if (ipVersion == IPv.IPv4) { + cprString = IPUtils.getIPv4AddressString(ip); + } else if (ipVersion == IPv.IPv6) { + cprString = IPUtils.getCompressedIPv6AddressString(ip); + } else { + cprString = ""; + } + /* logger.info("Added new IP: " + cprString); */ + } + + public int getAddID() { + return addrIdx; + } + + public boolean isGlobal() { + return isGlobal; + } + + public byte[] getIP() { + return ip; + } + + @Override + public String toString() { + return cprString; + } + + public String toUncompressedString() { + if (ipVersion == IPv.IPv4) { + return cprString; + } + else if (ipVersion == IPv.IPv6) { + return IPUtils.getUncompressedIPv6AddressString(ip); + } + else { + return ""; + } + } + } } diff --git a/tools/cooja/java/org/contikios/cooja/interfaces/NoiseSourceRadio.java b/tools/cooja/java/org/contikios/cooja/interfaces/NoiseSourceRadio.java index 6ceb35b55..45b7760c4 100644 --- a/tools/cooja/java/org/contikios/cooja/interfaces/NoiseSourceRadio.java +++ b/tools/cooja/java/org/contikios/cooja/interfaces/NoiseSourceRadio.java @@ -1,56 +1,56 @@ -/* - * Copyright (c) 2011, Swedish Institute of Computer Science. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. 2. 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. 3. Neither the name of the - * Institute 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 INSTITUTE 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 INSTITUTE 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. - * - */ - -package org.contikios.cooja.interfaces; - -/** - * The noise source radio is used to simulate ambient background noise or - * point-sources of external interference (e.g. Wifi basestations). - * - * Note that interference generated from these radios are different from - * transmissions; they will not appear in the radio logger but may still - * hinder or interfere with ongoing transmissions. - * - * Noise source radios require significant processing resources in comparison - * to only transmission radios. - * - * COOJA's radio mediums may or may not choose to respect noise source radios. - * - * @see MRM - * @author Fredrik Osterlind - */ -public interface NoiseSourceRadio { - public int getNoiseLevel(); - - public void addNoiseLevelListener(NoiseLevelListener l); - public void removeNoiseLevelListener(NoiseLevelListener l); - - public interface NoiseLevelListener { - public void noiseLevelChanged(NoiseSourceRadio radio, int signal); - } -} +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. 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. 3. Neither the name of the + * Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +package org.contikios.cooja.interfaces; + +/** + * The noise source radio is used to simulate ambient background noise or + * point-sources of external interference (e.g. Wifi basestations). + * + * Note that interference generated from these radios are different from + * transmissions; they will not appear in the radio logger but may still + * hinder or interfere with ongoing transmissions. + * + * Noise source radios require significant processing resources in comparison + * to only transmission radios. + * + * COOJA's radio mediums may or may not choose to respect noise source radios. + * + * @see MRM + * @author Fredrik Osterlind + */ +public interface NoiseSourceRadio { + public int getNoiseLevel(); + + public void addNoiseLevelListener(NoiseLevelListener l); + public void removeNoiseLevelListener(NoiseLevelListener l); + + public interface NoiseLevelListener { + public void noiseLevelChanged(NoiseSourceRadio radio, int signal); + } +} diff --git a/tools/cooja/java/org/contikios/cooja/interfaces/RimeAddress.java b/tools/cooja/java/org/contikios/cooja/interfaces/RimeAddress.java index 405aca506..09031b44d 100644 --- a/tools/cooja/java/org/contikios/cooja/interfaces/RimeAddress.java +++ b/tools/cooja/java/org/contikios/cooja/interfaces/RimeAddress.java @@ -43,9 +43,9 @@ import org.jdom.Element; import org.contikios.cooja.ClassDescription; import org.contikios.cooja.Mote; import org.contikios.cooja.MoteInterface; -import org.contikios.cooja.MoteMemory; -import org.contikios.cooja.MoteMemory.MemoryEventType; -import org.contikios.cooja.MoteMemory.MemoryMonitor; +import org.contikios.cooja.mote.memory.MemoryInterface; +import org.contikios.cooja.mote.memory.MemoryInterface.SegmentMonitor; +import org.contikios.cooja.mote.memory.VarMemory; /** * Read-only interface to Rime address read from Contiki variable: linkaddr_node_addr. @@ -57,18 +57,19 @@ import org.contikios.cooja.MoteMemory.MemoryMonitor; @ClassDescription("Rime address") public class RimeAddress extends MoteInterface { private static Logger logger = Logger.getLogger(RimeAddress.class); - private MoteMemory moteMem; + private VarMemory moteMem; public static final int RIME_ADDR_LENGTH = 2; - private MemoryMonitor memMonitor = null; + private SegmentMonitor memMonitor = null; public RimeAddress(final Mote mote) { - moteMem = mote.getMemory(); + moteMem = new VarMemory(mote.getMemory()); if (hasRimeAddress()) { - memMonitor = new MemoryMonitor() { - public void memoryChanged(MoteMemory memory, MemoryEventType type, int address) { - if (type != MemoryEventType.WRITE) { + memMonitor = new SegmentMonitor() { + @Override + public void memoryChanged(MemoryInterface memory, SegmentMonitor.EventType type, long address) { + if (type != SegmentMonitor.EventType.WRITE) { return; } setChanged(); @@ -76,7 +77,7 @@ public class RimeAddress extends MoteInterface { } }; /* TODO XXX Timeout? */ - moteMem.addMemoryMonitor(moteMem.getVariableAddress("linkaddr_node_addr"), RIME_ADDR_LENGTH, memMonitor); + moteMem.addVarMonitor(SegmentMonitor.EventType.WRITE, "linkaddr_node_addr", memMonitor); } } @@ -131,7 +132,7 @@ public class RimeAddress extends MoteInterface { public void removed() { super.removed(); if (memMonitor != null) { - moteMem.removeMemoryMonitor(moteMem.getVariableAddress("linkaddr_node_addr"), RIME_ADDR_LENGTH, memMonitor); + moteMem.removeVarMonitor("linkaddr_node_addr", memMonitor); } } diff --git a/tools/cooja/java/org/contikios/cooja/mote/memory/ArrayMemory.java b/tools/cooja/java/org/contikios/cooja/mote/memory/ArrayMemory.java new file mode 100644 index 000000000..95966e01b --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/mote/memory/ArrayMemory.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013, Enrico Joerns + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +package org.contikios.cooja.mote.memory; + +import java.util.Arrays; +import java.util.Map; + +/** + * A memory that is backed by an array. + * + * @author Enrico Joerns + */ +public class ArrayMemory implements MemoryInterface { + + private final byte memory[]; + private final long startAddress; + private final MemoryLayout layout; + private final boolean readonly; + private final Map symbols;// XXX Allow to set symbols + + public ArrayMemory(long address, int size, MemoryLayout layout, Map symbols) { + this(address, layout, new byte[size], symbols); + } + + public ArrayMemory(long address, MemoryLayout layout, byte[] memory, Map symbols) { + this(address, layout, memory, false, symbols); + } + + public ArrayMemory(long address, MemoryLayout layout, byte[] memory, boolean readonly, Map symbols) { + this.startAddress = address; + this.layout = layout; + this.memory = memory; + this.readonly = readonly; + this.symbols = symbols; + } + + @Override + public byte[] getMemory() { + return memory; + } + + /** + * XXX Should addr be the relative or the absolute address of this section? + * @param addr + * @param size + * @return + * @throws org.contikios.cooja.mote.memory.MemoryInterface.MoteMemoryException + */ + @Override + public byte[] getMemorySegment(long addr, int size) throws MoteMemoryException { + byte[] ret = new byte[size]; + System.arraycopy(memory, (int) (addr - startAddress), ret, 0, size); + return ret; + } + + @Override + public void setMemorySegment(long addr, byte[] data) throws MoteMemoryException { + if (readonly) { + throw new MoteMemoryException("Invalid write access for readonly memory"); + } + System.arraycopy(data, 0, memory, (int) (addr - startAddress), data.length); + } + + @Override + public void clearMemory() { + Arrays.fill(memory, (byte) 0x00); + } + + @Override + public long getStartAddr() { + return startAddress; + } + + @Override + public int getTotalSize() { + return memory.length; + } + + @Override + public Map getSymbolMap() { + return symbols; + } + + @Override + public MemoryLayout getLayout() { + return layout; + } + + @Override + public boolean addSegmentMonitor(SegmentMonitor.EventType flag, long address, int size, SegmentMonitor monitor) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean removeSegmentMonitor(long address, int size, SegmentMonitor monitor) { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff --git a/tools/cooja/java/org/contikios/cooja/mote/memory/Memory.java b/tools/cooja/java/org/contikios/cooja/mote/memory/Memory.java new file mode 100644 index 000000000..a308b1f2d --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/mote/memory/Memory.java @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2014, TU Braunschweig. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +package org.contikios.cooja.mote.memory; + +import org.contikios.cooja.mote.memory.MemoryInterface.SegmentMonitor; +import org.contikios.cooja.mote.memory.MemoryInterface.SegmentMonitor.EventType; +import org.contikios.cooja.mote.memory.MemoryLayout.DataType; + +/** + * Represents memory that can be accessed with address and size informations. + * + * @author Enrico Jorns + */ +public abstract class Memory { + + private final MemoryInterface memIntf; + + /** + * Creates new memory for given MemoryLayout. + * + * @param intf + */ + public Memory(MemoryInterface intf) { + memIntf = intf; + } + + // -- Get fixed size types + /** + * Read 8 bit integer from address. + * + * @param addr Address to read from + * @return 8 bit value read from address + */ + public byte getInt8ValueOf(long addr) { + return memIntf.getMemorySegment(addr, DataType.INT8.getSize())[0]; + } + + /** + * Read 16 bit integer from address. + * + * @param addr Address to read from + * @return 16 bit value read from address + */ + public short getInt16ValueOf(long addr) { + return MemoryBuffer.wrap( + memIntf.getLayout(), + memIntf.getMemorySegment(addr, DataType.INT16.getSize())).getInt16(); + } + + /** + * Read 32 bit integer from address. + * + * @param addr Address to read from + * @return 32 bit value read from address + */ + public int getInt32ValueOf(long addr) { + return MemoryBuffer.wrap( + memIntf.getLayout(), + memIntf.getMemorySegment(addr, DataType.INT32.getSize())).getInt32(); + } + + /** + * Read 64 bit integer from address. + * + * @param addr Address to read from + * @return 64 bit value read from address + */ + public long getInt64ValueOf(long addr) { + return MemoryBuffer.wrap( + memIntf.getLayout(), + memIntf.getMemorySegment(addr, DataType.INT64.getSize())).getInt64(); + } + + // -- Get compiler-dependent types + /** + * Read byte from address. + * + * @param addr Address to read from + * @return byte read from address + */ + public byte getByteValueOf(long addr) { + return memIntf.getMemorySegment(addr, DataType.BYTE.getSize())[0]; + } + + /** + * Read short from address. + * + * @param addr Address to read from + * @return short read from address + */ + public short getShortValueOf(long addr) { + return MemoryBuffer.wrap(memIntf.getLayout(), memIntf.getMemorySegment(addr, 2)).getShort(); + } + + /** + * Read integer from address. + *

    + * Note: Size of integer depends on platform type. + * + * @param addr Address to read from + * @return integer read from address + */ + public int getIntValueOf(long addr) { + return MemoryBuffer.wrap(memIntf.getLayout(), memIntf.getMemorySegment(addr, memIntf.getLayout().intSize)).getInt(); + } + + /** + * Read long from address. + * + * @param addr Address to read from + * @return long read from address + */ + public long getLongValueOf(long addr) { + return MemoryBuffer.wrap(memIntf.getLayout(), memIntf.getMemorySegment(addr, 4)).getLong(); + } + + /** + * Read pointer from address. + *

    + * Note: Size of pointer depends on platform type. + * + * @param addr Address to read from + * @return pointer read from address + */ + public long getAddrValueOf(long addr) { + return MemoryBuffer.wrap(memIntf.getLayout(), memIntf.getMemorySegment(addr, memIntf.getLayout().addrSize)).getAddr(); + } + + /** + * Read byte array starting at given address. + * + * @param addr Start address to read from + * @param length Numbe of bytes to read + * @return byte array read from location assigned to variable name + */ + public byte[] getByteArray(long addr, int length) + throws UnknownVariableException { + return memIntf.getMemorySegment(addr, length); + } + + // -- Set fixed size types + /** + * Write 8 bit integer to address. + * + * @param addr Address to write to + * @param value 8 bit value to write + */ + public void setInt8ValueOf(long addr, byte value) { + memIntf.setMemorySegment(addr, new byte[]{value}); + } + + /** + * Write 16 bit integer to address. + * + * @param addr Address to write to + * @param value 16 bit value to write + */ + public void setInt16ValueOf(long addr, short value) { + memIntf.setMemorySegment(addr, MemoryBuffer.wrap( + memIntf.getLayout(), + new byte[DataType.INT16.getSize()]).putShort(value).getBytes()); + } + + /** + * Write 32 bit integer to address. + * + * @param addr Address to write to + * @param value 32 bit value to write + */ + public void setInt32ValueOf(long addr, int value) { + memIntf.setMemorySegment(addr, MemoryBuffer.wrap( + memIntf.getLayout(), + new byte[DataType.INT32.getSize()]).putInt(value).getBytes()); + } + + /** + * Write 64 bit integer to address. + * + * @param addr Address to write to + * @param value 64 bit value to write + */ + public void setInt64ValueOf(long addr, long value) { + memIntf.setMemorySegment(addr, MemoryBuffer.wrap( + memIntf.getLayout(), + new byte[DataType.INT64.getSize()]).putLong(value).getBytes()); + } + + // -- Set compiler-dependent types + /** + * Write byte to address. + * + * @param addr Address to write to + * @param value byte to write + */ + public void setByteValueOf(long addr, byte value) { + memIntf.setMemorySegment(addr, new byte[]{value}); + } + + /** + * Write short to address. + * + * @param addr Address to write to + * @param value short to write + */ + public void setShortValueOf(long addr, short value) { + memIntf.setMemorySegment(addr, MemoryBuffer.wrap(memIntf.getLayout(), new byte[2]).putShort(value).getBytes()); + } + + /** + * Write integer to address. + *

    + * Note: Size of integer depends on platform type. + * + * @param addr Address to write to + * @param value integer to write + */ + public void setIntValueOf(long addr, int value) { + memIntf.setMemorySegment(addr, MemoryBuffer.wrap(memIntf.getLayout(), new byte[memIntf.getLayout().intSize]).putInt(value).getBytes()); + } + + /** + * Write long to address. + * + * @param addr Address to write to + * @param value long to write + */ + public void setLongValueOf(long addr, long value) { + memIntf.setMemorySegment(addr, MemoryBuffer.wrap(memIntf.getLayout(), new byte[4]).putLong(value).getBytes()); + } + + /** + * Write pointer to address. + *

    + * Note: Size of pointer depends on platform type. + * + * @param addr Address to write to + * @param value pointer to write + */ + public void setAddrValueOf(long addr, long value) { + memIntf.setMemorySegment(addr, MemoryBuffer.wrap(memIntf.getLayout(), new byte[memIntf.getLayout().addrSize]).putAddr(value).getBytes()); + } + + /** + * Write byte array starting at given address. + * + * @param addr Start address to write to + * @param data data to write + */ + public void setByteArray(long addr, byte[] data) + throws UnknownVariableException { + memIntf.setMemorySegment(addr, data); + } + + /** + * Adds monitor to specified memory region. + * + * @param flag Select memory operation(s) to listen for (read, write, read/write) + * @param addr Start address of monitored region + * @param size Size of monitored region + * @param mm Monitor to add + * @return if monitor could be added, false if not + */ + public boolean addMemoryMonitor(EventType flag, long addr, int size, SegmentMonitor mm) { + return memIntf.addSegmentMonitor(flag, addr, size, mm); + } + + /** + * Removes monitor assigned to the specified region. + * + * @param addr Start address of monitored region + * @param size Size of monitored region + * @param mm Monitor to remove + */ + public void removeMemoryMonitor(long addr, int size, SegmentMonitor mm) { + memIntf.removeSegmentMonitor(addr, size, mm); + } +} diff --git a/tools/cooja/java/org/contikios/cooja/mote/memory/MemoryBuffer.java b/tools/cooja/java/org/contikios/cooja/mote/memory/MemoryBuffer.java new file mode 100644 index 000000000..4f645a2e0 --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/mote/memory/MemoryBuffer.java @@ -0,0 +1,481 @@ +/* + * Copyright (c) 2014, TU Braunschweig + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ +package org.contikios.cooja.mote.memory; + +import java.nio.ByteBuffer; +import org.contikios.cooja.mote.memory.MemoryLayout.DataType; + +/** + * Basic routines for memory access with multi-arch support. + * + * Handles endianess, integer size and address size. + * + * Supports padding/aligning. + * + * @author Enrico Jorns + */ +public class MemoryBuffer { + + private final MemoryLayout memLayout; + private final ByteBuffer bbuf; + private final DataType[] structure; + private int structIndex; + + private MemoryBuffer(MemoryLayout memLayout, ByteBuffer buffer, DataType[] structure) { + this.memLayout = memLayout; + this.bbuf = buffer; + this.structure = structure; + this.structIndex = 0; + } + + /** + * Wraps a byte array into an unstructered MemoryBuffer with given MemoryLayout. + *

    + * Note that modifications to the buffer are applied to the backed array and vice versa. + * + * @param layout MemoryLayout for memory to access array from + * @param array Byte array that will back this buffer + * @return the new MemroyBuffer + */ + public static MemoryBuffer wrap(MemoryLayout layout, byte[] array) { + return wrap(layout, array, null); + } + + /** + * Wraps a byte array into a structured MemoryBuffer with given MemoryLayout. + *

    + * Note that modifications to the buffer are applied to the backed array and vice versa. + *

    + * A structured MemoryBuffer can be used to simplify reading c struct data + * from the memory as it provides support for data aligning. + *

    + * The structure array elements should be set to exactly the same types and order + * that the corresponding c struct has. + * + * @param layout MemoryLayout for memory to access array from + * @param structure Array of data types representing the structure to read + * @param array Byte array that will back this buffer + * @return the new MemroyBuffer + */ + public static MemoryBuffer wrap(MemoryLayout layout, byte[] array, DataType[] structure) { + ByteBuffer b = ByteBuffer.wrap(array); + b.order(layout.order); // preset endianess + return new MemoryBuffer(layout, b, structure); + } + + /** + * Returns the byte array that backs this buffer + * + * @return byte array that backs this buffer + */ + public byte[] getBytes() { + if (bbuf.hasArray()) { + return bbuf.array(); + } + else { + return null; + } + } + + /** + * Calculates the padding bytes to be added/skipped between current and next + * element. + * + * @param type Current data type + */ + private void skipPaddingBytesFor(DataType type) { + /* Check if we have a structure and not yet reached the last element */ + if (structure != null && structure[structIndex + 1] != null) { + /* get size of next element in structure */ + int nextsize = structure[structIndex + 1].getSize(); + /* limit padding to word size */ + nextsize = nextsize > memLayout.WORD_SIZE ? memLayout.WORD_SIZE : nextsize; + /* calc padding */ + int pad = nextsize - type.getSize(); + /* Skip padding bytes */ + if (pad > 0) { + bbuf.position(bbuf.position() + pad); + } + } + structIndex++; + } + + /** + * Returns current element type. + * + * @return current element type or null if no struct is used + */ + public DataType getType() { + if (structure == null) { + return null; + } + return structure[structIndex]; + } + + // --- fixed size types + + /** + * Reads 8 bit integer from current buffer position, + * and then increments position. + *

    + * Note: If structured reading is enabled, + * additional padding bytes may be skipped automatically. + * + * @return 8 bit integer at the buffer's current position + */ + public byte getInt8() { + byte value = bbuf.get(); + skipPaddingBytesFor(DataType.INT8); + return value; + } + + /** + * Reads 16 bit integer from current buffer position, + * and then increments position. + *

    + * Note: If structured reading is enabled, + * additional padding bytes may be skipped automatically. + * + * @return 16 bit integer at the buffer's current position + */ + public short getInt16() { + short value = bbuf.getShort(); + skipPaddingBytesFor(DataType.INT16); + return value; + } + + /** + * Reads 32 bit integer from current buffer position, + * and then increments position. + *

    + * Note: If structured reading is enabled, + * additional padding bytes may be skipped automatically. + * + * @return 32 bit integer at the buffer's current position + */ + public int getInt32() { + int value = bbuf.getInt(); + skipPaddingBytesFor(DataType.INT32); + return value; + } + + /** + * Reads 64 bit integer from current buffer position, + * and then increments position. + *

    + * Note: If structured reading is enabled, + * additional padding bytes may be skipped automatically. + * + * @return 64 bit integer at the buffer's current position + */ + public long getInt64() { + long value = bbuf.getLong(); + skipPaddingBytesFor(DataType.INT64); + return value; + } + + // --- platform-dependent types + + /** + * Reads byte from current buffer position, + * and then increments position. + *

    + * Note: If structured reading is enabled, + * additional padding bytes may be skipped automatically. + * + * @return byte at the buffer's current position + */ + public byte getByte() { + byte value = bbuf.get(); + skipPaddingBytesFor(DataType.BYTE); + return value; + } + + /** + * Reads short from current buffer position, + * and then increments position. + *

    + * Note: If structured reading is enabled, + * additional padding bytes may be skipped automatically. + * + * @return short at the buffer's current position + */ + public short getShort() { + short value = bbuf.getShort(); + skipPaddingBytesFor(DataType.SHORT); + return value; + } + + /** + * Reads integer from current buffer position, + * and then increments position. + *

    + * Note: If structured reading is enabled, + * additional padding bytes may be skipped automatically. + * + * @return integer at the buffer's current position + */ + public int getInt() { + int value; + switch (memLayout.intSize) { + case 2: + value = bbuf.getShort(); + break; + case 4: + default: + value = bbuf.getInt(); + break; + } + skipPaddingBytesFor(DataType.INT); + return value; + } + + /** + * Reads long from current buffer position, + * and then increments position. + *

    + * Note: If structured reading is enabled, + * additional padding bytes may be skipped automatically. + * + * @return long at the buffer's current position + */ + public long getLong() { + long value = bbuf.getLong(); + skipPaddingBytesFor(DataType.LONG); + return value; + } + + /** + * Reads pointer from current buffer position, + * and then increments position. + *

    + * Note: If structured reading is enabled, + * additional padding bytes may be skipped automatically. + * + * @return pointer at the buffer's current position + */ + public long getAddr() { + long value; + switch (memLayout.addrSize) { + case 2: + value = bbuf.getShort(); + break; + case 4: + value = bbuf.getInt(); + break; + case 8: + value = bbuf.getLong(); + break; + default: + value = bbuf.getInt(); + break; + } + skipPaddingBytesFor(DataType.POINTER); + return value; + } + + // --- fixed size types + + /** + * Writes 8 bit integer to current buffer position, + * and then increments position. + *

    + * Note: If structured writing is enabled, + * additional padding bytes may be skipped automatically. + * + * @param value 8 bit integer to write + * @return A reference to this object + */ + public MemoryBuffer putInt8(byte value) { + bbuf.put(value); + skipPaddingBytesFor(DataType.INT8); + return this; + } + + /** + * Writes 16 bit integer to current buffer position, + * and then increments position. + *

    + * Note: If structured writing is enabled, + * additional padding bytes may be skipped automatically. + * + * @param value 16 bit integer to write + * @return A reference to this object + */ + public MemoryBuffer putInt16(short value) { + bbuf.putShort(value); + skipPaddingBytesFor(DataType.INT16); + return this; + } + + /** + * Writes 32 bit integer to current buffer position, + * and then increments position. + *

    + * Note: If structured writing is enabled, + * additional padding bytes may be skipped automatically. + * + * @param value 32 bit integer to write + * @return A reference to this object + */ + public MemoryBuffer putInt32(int value) { + bbuf.putInt(value); + skipPaddingBytesFor(DataType.INT32); + return this; + } + + /** + * Writes 64 bit integer to current buffer position, + * and then increments position. + *

    + * Note: If structured writing is enabled, + * additional padding bytes may be skipped automatically. + * + * @param value 64 bit integer to write + * @return A reference to this object + */ + public MemoryBuffer putInt64(long value) { + bbuf.putLong(value); + skipPaddingBytesFor(DataType.INT64); + return this; + } + + // --- platform-dependent types + + /** + * Writes byte to current buffer position, + * and then increments position. + *

    + * Note: If structured writing is enabled, + * additional padding bytes may be skipped automatically. + * + * @param value byte to write + * @return A reference to this object + */ + public MemoryBuffer putByte(byte value) { + bbuf.put(value); + skipPaddingBytesFor(DataType.BYTE); + return this; + } + + /** + * Writes short to current buffer position, + * and then increments position. + *

    + * Note: If structured writing is enabled, + * additional padding bytes may be skipped automatically. + * + * @param value short to write + * @return A reference to this object + */ + public MemoryBuffer putShort(short value) { + bbuf.putShort(value); + skipPaddingBytesFor(DataType.SHORT); + return this; + } + + /** + * Writes integer to current buffer position, + * and then increments position. + *

    + * Note: If structured writing is enabled, + * additional padding bytes may be skipped automatically. + *

    + * Note: Size of integer depends on platform type + * + * @param value integer to write + * @return A reference to this object + */ + public MemoryBuffer putInt(int value) { + switch (memLayout.intSize) { + case 2: + /** + * @TODO: check for size? + */ + bbuf.putShort((short) value); + break; + case 4: + default: + bbuf.putInt(value); + break; + } + skipPaddingBytesFor(DataType.INT); + return this; + } + + /** + * Writes long to current buffer position, + * and then increments position. + *

    + * Note: If structured writing is enabled, + * additional padding bytes may be skipped automatically. + * + * @param value long to write + * @return A reference to this object + */ + public MemoryBuffer putLong(long value) { + bbuf.putLong(value); + skipPaddingBytesFor(DataType.LONG); + return this; + } + + /** + * Writes pointer to current buffer position, + * and then increments position. + *

    + * Note: If structured writing is enabled, + * additional padding bytes may be skipped automatically. + *

    + * Note: Size of pointer depends on platform type + * + * @param value pointer to write + * @return A reference to this object + */ + public MemoryBuffer putAddr(long value) { + /** + * @TODO: check for size? + */ + switch (memLayout.addrSize) { + case 2: + bbuf.putShort((short) value); + break; + case 4: + bbuf.putInt((int) value); + break; + case 8: + bbuf.putLong(value); + break; + default: + bbuf.putInt((int) value); + break; + } + skipPaddingBytesFor(DataType.POINTER); + return this; + } +} diff --git a/tools/cooja/java/org/contikios/cooja/mote/memory/MemoryInterface.java b/tools/cooja/java/org/contikios/cooja/mote/memory/MemoryInterface.java new file mode 100644 index 000000000..3f7df09ff --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/mote/memory/MemoryInterface.java @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2014, TU Braunschweig + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ +package org.contikios.cooja.mote.memory; + +import java.util.Map; + +/** + * A minimal interface to a motes memory. + * + * Allows reading and writing memory, obtaining symbol information + * and provides some basic inforation about size, layout, etc. + * + * @author Enrico Jorns + */ +public interface MemoryInterface { + + /** + * Represents a symbol in memory (variable / function) + */ + public static class Symbol { + + public final Type type; + public final String name; + public final String section; + public final long addr; + public final int size; + + public enum Type { + + VARIABLE, + FUNCTION + } + + public Symbol(Type type, String name, String section, long addr, int size) { + this.type = type; + this.name = name; + this.section = section; + this.addr = addr; + this.size = size; + } + + public Symbol(Type type, String name, long addr, int size) { + this(type, name, null, addr, size); + } + + @Override + public String toString() { + return new StringBuilder("Symbol(").append(type == null ? "N/A" : type.toString()) + .append(") '").append(name) + .append("' in '").append(section == null ? "N/A" : section) + .append("' at 0x").append(addr == -1 ? "N/A" : Long.toHexString(addr)) + .append(" size ").append(size == -1 ? "N/A" : String.valueOf(size)).toString(); + } + } + + /** + * Class represents memory access exceptions. + */ + public class MoteMemoryException extends RuntimeException { + + public MoteMemoryException(String message, Object... args) { + super(String.format(message, args)); + } + } + + /** + * Returns entire mote memory + * @return Memory byte array + * @throws org.contikios.cooja.mote.memory.MemoryInterface.MoteMemoryException + */ + public byte[] getMemory() throws MoteMemoryException; + + /** + * Reads a segment from memory. + * + * @param addr Start address to read from + * @param size Size to read [bytes] + * @return Byte array + */ + public byte[] getMemorySegment(long addr, int size) throws MoteMemoryException; + + /** + * Sets a segment of memory. + * + * @param addr Start address to write to + * @param data Size to write [bytes] + */ + void setMemorySegment(long addr, byte[] data) throws MoteMemoryException; + + /** + * Clears the memory. + */ + void clearMemory(); + + /** + * + * @return + */ + long getStartAddr(); + + /** + * Returns total size of memory. + * + * @return Size [bytes] + */ + int getTotalSize();// XXX getSize(); + + /** + * Returns Map of all variables in memory. + * Map must be of typ name / symbol. + * + * @return Variables + */ + Map getSymbolMap(); + + /** + * Returns the MemoryLayout for this memory. + * + * @return Memory layout for this memory + */ + MemoryLayout getLayout(); + + /** + * Monitor to listen for memory updates. + */ + interface SegmentMonitor { + + public static enum EventType { + + READ, + WRITE, + READWRITE + } + + /** + * Invoked if the monitored segment changed + * + * @param memory Reference to the memory + * @param type XXX ??? + * @param address Address in segment where modification occured + */ + void memoryChanged(MemoryInterface memory, EventType type, long address); + } + + /** + * Adds a SegmentMonitor for the specified address region. + * + * @param flag Select memory operation(s) to listen for + * (read, write, read/write) + * @param address Start address of monitored data region + * @param size Size of monitored data region + * @param monitor SegmentMonitor to add + * @return true if monitor could be added, false if not + */ + boolean addSegmentMonitor(SegmentMonitor.EventType flag, long address, int size, SegmentMonitor monitor); + + /** + * Removes SegmentMonitor assigned to the specified region. + * + * @param address Start address of Monitor data region + * @param size Size of Monitor data region + * @param monitor SegmentMonitor to remove + * @return true if monitor was removed, false if not + */ + boolean removeSegmentMonitor(long address, int size, SegmentMonitor monitor); +} diff --git a/tools/cooja/java/org/contikios/cooja/mote/memory/MemoryLayout.java b/tools/cooja/java/org/contikios/cooja/mote/memory/MemoryLayout.java new file mode 100644 index 000000000..132af62d0 --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/mote/memory/MemoryLayout.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2014, TU Braunschweig + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +package org.contikios.cooja.mote.memory; + +import java.nio.ByteOrder; + +/** + * Holds memory layout informations such as endianess, wordsize, C int size. + * + * @author Enrico Jorns + */ +public class MemoryLayout { + + /** 8 bit memory architecture */ + public static final int ARCH_8BIT = 1; + /** 16 bit memory architecture */ + public static final int ARCH_16BIT = 2; + /** 32 bit memory architecture */ + public static final int ARCH_32BIT = 4; + /** 64 bit memory architecture */ + public static final int ARCH_64BIT = 8; + + /** + * Size of data types in bytes. + */ + public enum DataType { + + BYTE(1), + CHAR(1), + SHORT(2), + INT(4), + LONG(8), + LONGLONG(8), + INT8(1), + INT16(2), + INT32(4), + INT64(8), + FLOAT(4), + DOUBLE(8), + POINTER(4); + + private int size; + + DataType(int size) { + this.size = size; + } + + public void setSize(int size) { + this.size = size; + } + + public int getSize() { + return this.size; + } + } + + public final ByteOrder order; + public final int addrSize; + public final int intSize; + public final int WORD_SIZE; + private boolean aligned = true; + + /** + * Creates new MemoryLayout instance. + * + * @param order either ByteOrder.BIG_ENDIAN, or ByteOrder.LITTLE_ENDIAN + * @param wordsize should be one of ARCH_8BIT, ARCH_16BIT, ARCH_32BIT, + * ARCH_64BIT + * @param sizeofInt + */ + public MemoryLayout(ByteOrder order, int wordsize, int sizeofInt) { + this(order, wordsize, sizeofInt, wordsize); + } + + /** + * Creates new MemoryLayout instance. + * + * @param order either ByteOrder.BIG_ENDIAN, or ByteOrder.LITTLE_ENDIAN + * @param wordsize should be one of ARCH_8BIT, ARCH_16BIT, ARCH_32BIT, + * ARCH_64BIT + * @param sizeofPointer + * @param sizeofInt + */ + public MemoryLayout(ByteOrder order, int wordsize, int sizeofInt, int sizeofPointer) { + this.order = order; + this.WORD_SIZE = wordsize; + this.intSize = sizeofInt; + this.addrSize = sizeofPointer; + DataType.INT.setSize(this.intSize); + DataType.POINTER.setSize(this.addrSize); + } + + /** + * Returns the MemoryLayout for the running jvm. + * + * @return MemoryLayout for the running jvm. + */ + public static MemoryLayout getNative() { + return new MemoryLayout( + ByteOrder.nativeOrder(), + Integer.parseInt(System.getProperty("sun.arch.data.model")) / 8, + Integer.SIZE / 8); + } + + /** + * Enable/Disable data alignment. + * + * Determines whether data alignemnt is used for packing structs. + * Default is enabled. + * + * @param aligned true to enable data alignment, false to disable + */ + public void setAligned(boolean aligned) { + this.aligned = aligned; + } + + /** + * Returns true if data is aligned. + * + * @return if aligned + */ + public boolean isAligned() { + return aligned; + } + + /** + * Returns number of padding bytes between two data types. + * + * @param currType + * @param nextType + * @return + */ + public int getPaddingBytesFor(DataType currType, DataType nextType) { + /* No padding bytes for unaligned memory */ + if (!isAligned()) { + return 0; + } + /* get size of next element in structure */ + int nextsize = nextType.getSize(); + /* limit padding to word size */ + nextsize = nextsize > WORD_SIZE ? WORD_SIZE : nextsize; + /* calc padding */ + int pad = nextsize - currType.getSize(); + return pad; + } + + /** + * Returns information string for this MemoryLayout. + * + * @return String that shows Endianess and word size. + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + return sb.append("MemoryLayout: ") + .append("Endianess: ").append(order) + .append(", WORD_SIZE: ").append(WORD_SIZE) + .toString(); + } +} diff --git a/tools/cooja/java/org/contikios/cooja/mote/memory/SectionMoteMemory.java b/tools/cooja/java/org/contikios/cooja/mote/memory/SectionMoteMemory.java new file mode 100644 index 000000000..0a335b15e --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/mote/memory/SectionMoteMemory.java @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2014, TU Braunschweig. All rights reserved. + * Copyright (c) 2006, Swedish Institute of Computer Science. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. 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. 3. Neither the name of the + * Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +package org.contikios.cooja.mote.memory; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.apache.log4j.Logger; + +/** + * Represents a mote memory consisting of non-overlapping memory sections with + * symbol addresses. + *

    + * Every section must implement MemoyInterface. + *

    + * Implements MemoryInterface by forwarding calls to available sections or returning + * an error if no section is available. + * + * @author Fredrik Osterlind + * @author Enrico Jorns + */ +public class SectionMoteMemory implements MemoryInterface { + private static Logger logger = Logger.getLogger(SectionMoteMemory.class); + private static final boolean DEBUG = logger.isDebugEnabled(); + + private Map sections = new HashMap<>(); + + private final Map symbols; + private MemoryLayout memLayout; + private long startAddr = Long.MAX_VALUE; + + /** + * @param symbols Symbol addresses + */ + public SectionMoteMemory(Map symbols) { + this.symbols = symbols; + } + + /** + * Adds a section to this memory. + * + * A new section will be checked for address overlap with existing sections. + * + * @param name + * @param section + * @return true if adding succeeded, false otherwise + */ + public boolean addMemorySection(String name ,MemoryInterface section) { + + if (section == null) { + return false; + } + + /* Cooja address space */ + for (MemoryInterface sec : sections.values()) { + /* check for overlap with existing region */ + if ((section.getStartAddr() <= sec.getStartAddr() + sec.getTotalSize() - 1) + && (section.getStartAddr() + section.getTotalSize() - 1 >= sec.getStartAddr())) { + logger.error(String.format( + "Failed adding section '%s' of size %d @0x%x", + name, + section.getTotalSize(), + section.getStartAddr())); + return false; + } + /* Min start address is main start address */ + startAddr = sec.getStartAddr() < startAddr ? sec.getStartAddr() : startAddr; + /* Layout is last layout. XXX Check layout consistency? */ + memLayout = section.getLayout(); + } + + sections.put(name, section); + if (section.getSymbolMap() != null) { + for (String s : section.getSymbolMap().keySet()) { + // XXX how to handle double names here? + symbols.put(s, section.getSymbolMap().get(s)); + } + } + + if (DEBUG) { + logger.debug(String.format( + "Added section '%s' of size %d @0x%x", + name, + section.getTotalSize(), + section.getStartAddr())); + } + return true; + } + + /** + * Returns the total number of sections in this memory. + * + * @return Number of sections + */ + public int getNumberOfSections() { + return sections.size(); + } + + /** + * Returns memory section of this memory. + * @param name Name of section + * @return memory section + */ + public MemoryInterface getSection(String name) { + for (String memsec : sections.keySet()) { + if (memsec.equals(name)) { + return sections.get(name); + } + } + + logger.warn("Section '" + name + "' not found"); + return null; + } + + /** + * Return all sections of this memory. + * @return All memory sections + */ + public Map getSections() { + return sections; + } + + /** + * True if given address is part of this memory section. + * + * @param intf + * @param addr + * Address + * @return True if given address is part of this memory section, false + * otherwise + */ + public static boolean includesAddr(MemoryInterface intf, long addr) { + return addr >= intf.getStartAddr() && addr < (intf.getStartAddr() + intf.getTotalSize()); + } + + /** + * True if the whole address range specified by address and size + * lies inside this memory section. + * + * @param intf + * @param addr Start address of segment to check + * @param size Size of segment to check + * + * @return True if given address range lies inside address range of this + * section + */ + public static boolean inSection(MemoryInterface intf, long addr, int size) { + return addr >= intf.getStartAddr() && addr + size <= intf.getStartAddr() + intf.getTotalSize(); + } + + @Override + public void clearMemory() { + sections.clear(); + } + + @Override + public int getTotalSize() { + int totalSize = 0; + for (MemoryInterface section : sections.values()) { + totalSize += section.getTotalSize(); + } + return totalSize; + } + + @Override + public byte[] getMemory() throws MoteMemoryException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + + /** + * Returns memory segment from section matching segment given by address and size + * @param address start address of segment to get + * @param size size of segmetn to get + * @return Array containing data of segment + * @throws MoteMemoryException if no single section containing the given address range was found + */ + @Override + public byte[] getMemorySegment(long address, int size) throws MoteMemoryException { + + for (MemoryInterface section : sections.values()) { + if (includesAddr(section, address) && includesAddr(section, address + size - 1)) { + return section.getMemorySegment(address, size); + } + } + + throw new MoteMemoryException( + "Getting memory segment [0x%x,0x%x] failed: No section available", + address, address + size - 1); + } + + /** + * Sets memory segment of section matching segment given by address and size. + * @param address start address of segment to set + * @param data data to set + * @throws MoteMemoryException if no single section containing the given address range was found + * or memory is readonly. + */ + @Override + public void setMemorySegment(long address, byte[] data) throws MoteMemoryException { + + for (MemoryInterface section : sections.values()) { + if (inSection(section, address, data.length)) { + section.setMemorySegment(address, data); + if (DEBUG) { + logger.debug(String.format( + "Wrote memory segment [0x%x,0x%x]", + address, address + data.length - 1)); + } + return; + } + } + throw new MoteMemoryException( + "Writing memory segment [0x%x,0x%x] failed: No section available", + address, address + data.length - 1); + } + + @Override + public long getStartAddr() { + return startAddr; + } + + @Override + public Map getSymbolMap() { + return symbols; + } + + @Override + public MemoryLayout getLayout() { + return memLayout; + } + + @Override + public boolean addSegmentMonitor(SegmentMonitor.EventType flag, long address, int size, SegmentMonitor monitor) { + PolledMemorySegments t = new PolledMemorySegments(monitor, address, size); + polledMemories.add(t); + return true; + } + + @Override + public boolean removeSegmentMonitor(long address, int size, SegmentMonitor monitor) { + for (PolledMemorySegments mcm: polledMemories) { + if (mcm.mm != monitor || mcm.address != address || mcm.size != size) { + continue; + } + polledMemories.remove(mcm); + return true; + } + return false; + } + + /** Copies seciton memory to new (array backed) one + * @return Cloned memory + */ + @Override + public SectionMoteMemory clone() { + + SectionMoteMemory clone = new SectionMoteMemory(symbols); + + for (String secname : sections.keySet()) { + // Copy section memory to new ArrayMemory + MemoryInterface section = sections.get(secname); + MemoryInterface cpmem = new ArrayMemory(section.getStartAddr(), section.getLayout(), section.getMemory().clone(), section.getSymbolMap()); + clone.addMemorySection(secname, cpmem); + } + + return clone; + } + + private ArrayList polledMemories = new ArrayList(); + public void pollForMemoryChanges() { + for (PolledMemorySegments mem: polledMemories.toArray(new PolledMemorySegments[0])) { + mem.notifyIfChanged(); + } + } + + private class PolledMemorySegments { + public final SegmentMonitor mm; + public final long address; + public final int size; + private byte[] oldMem; + + public PolledMemorySegments(SegmentMonitor mm, long address, int size) { + this.mm = mm; + this.address = address; + this.size = size; + + oldMem = getMemorySegment(address, size); + } + + private void notifyIfChanged() { + byte[] newMem = getMemorySegment(address, size); + if (Arrays.equals(oldMem, newMem)) { + return; + } + + mm.memoryChanged(SectionMoteMemory.this, SegmentMonitor.EventType.WRITE, address); + oldMem = newMem; + } + } + +} diff --git a/tools/cooja/java/org/contikios/cooja/mote/memory/UnknownVariableException.java b/tools/cooja/java/org/contikios/cooja/mote/memory/UnknownVariableException.java new file mode 100644 index 000000000..6f32f3698 --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/mote/memory/UnknownVariableException.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013, Enrico Joerns + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +package org.contikios.cooja.mote.memory; + +/** + * Unknown variable name exception. + */ +public class UnknownVariableException extends RuntimeException { + + public UnknownVariableException(String varName) { + super("Unknown variable name: " + varName); + } + +} diff --git a/tools/cooja/java/org/contikios/cooja/mote/memory/VarMemory.java b/tools/cooja/java/org/contikios/cooja/mote/memory/VarMemory.java new file mode 100644 index 000000000..65cff9af7 --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/mote/memory/VarMemory.java @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2014, TU Braunschweig. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ +package org.contikios.cooja.mote.memory; + +import java.util.Collection; +import java.util.Set; + +import org.contikios.cooja.mote.memory.MemoryInterface.Symbol; +import org.contikios.cooja.mote.memory.MemoryInterface.SegmentMonitor; +import org.contikios.cooja.mote.memory.MemoryInterface.SegmentMonitor.EventType; + +/** + * Represents memory that can be accessed with names of variables. + * + * @author Enrico Jorns + */ +public class VarMemory extends Memory { + + private MemoryInterface memIntf; + + /** + * Creates new VarMemory. + * + * @param intf + */ + public VarMemory(MemoryInterface intf) { + super(intf); + memIntf = intf; + } + + /** + * Allows to change the MemoryInterface associated with this access class. + * + * @param intf Interface to associate with + */ + public void associateMemory(MemoryInterface intf) { + memIntf = intf; + } + + /** + * Generates and returns an array of all variables in this memory + * + * @return All variables located in this memory + */ + public Collection getVariables() { + return memIntf.getSymbolMap().values(); + } + + /** + * Generates an array of all variable names in this memory. + * + * @return All variable names located in this memory + */ + public Set getVariableNames() { + return memIntf.getSymbolMap().keySet(); + } + + /** + * Checks if given variable exists in memory. + * + * @param varName Variable name + * @return True if variable exists, false otherwise + */ + public boolean variableExists(String varName) { + return memIntf.getSymbolMap().containsKey(varName); + } + + /** + * Returns address of variable with given name. + * + * @param varName Variable name + * @return Variable address + */ + public Symbol getVariable(String varName) throws UnknownVariableException { + Symbol sym = memIntf.getSymbolMap().get(varName); + if (sym == null) { + throw new UnknownVariableException(varName); + } + return sym; + } + + /** + * Returns address of variable with given name. + * + * @param varName Variable name + * @return Address of variable + * @throws UnknownVariableException If variable not found + */ + public long getVariableAddress(String varName) throws UnknownVariableException { + return getVariable(varName).addr; + } + + /** + * Return size of variable with given name. + * + * @param varName Variable name + * @return Size of variable, -1 if unknown size + * @throws UnknownVariableException If variable not found + */ + public int getVariableSize(String varName) throws UnknownVariableException { + return getVariable(varName).size; + } + + /** + * Read 8 bit integer from location associated with this variable name. + * + * @param varName Variable name + * @return 8 bit integer value read from location assigned to variable name + */ + public byte getInt8ValueOf(String varName) + throws UnknownVariableException { + return getInt8ValueOf(getVariable(varName).addr); + } + + /** + * Read 16 bit integer from location associated with this variable name. + * + * @param varName Variable name + * @return 16 bit integer value read from location assigned to variable name + */ + public short getInt16ValueOf(String varName) + throws UnknownVariableException { + return getInt16ValueOf(getVariable(varName).addr); + } + + /** + * Read 32 bit integer from location associated with this variable name. + * + * @param varName Variable name + * @return 32 bit integer value read from location assigned to variable name + */ + public int getInt32ValueOf(String varName) + throws UnknownVariableException { + return getInt32ValueOf(getVariable(varName).addr); + } + + /** + * Read 64 bit integer from location associated with this variable name. + * + * @param varName Variable name + * @return 64 bit integer value read from location assigned to variable name + */ + public long getInt64ValueOf(String varName) + throws UnknownVariableException { + return getInt64ValueOf(getVariable(varName).addr); + } + + /** + * Read byte from location associated with this variable name. + * + * @param varName Variable name + * @return byte value read from location assigned to variable name + */ + public byte getByteValueOf(String varName) + throws UnknownVariableException { + return getByteValueOf(getVariable(varName).addr); + } + + /** + * Read short from location associated with this variable name. + * + * @param varName Variable name + * @return short value read from location assigned to variable name + */ + public short getShortValueOf(String varName) + throws UnknownVariableException { + short val = getShortValueOf(getVariable(varName).addr); + return val; + } + + /** + * Read integer from location associated with this variable name. + * + * @param varName Variable name + * @return integer value read from location assigned to variable name + */ + public int getIntValueOf(String varName) + throws UnknownVariableException { + int val = getIntValueOf(getVariable(varName).addr); + return val; + } + + /** + * Read long from location associated with this variable name. + * + * @param varName Variable name + * @return long value read from location assigned to variable name + */ + public long getLongValueOf(String varName) + throws UnknownVariableException { + long val = getLongValueOf(getVariable(varName).addr); + return val; + } + + /** + * Read pointer from location associated with this variable name. + * + * The number of bytes actually read depends on the pointer size + * defined in memory layout. + * + * @param varName Variable name + * @return pointer value read from location assigned to variable name + */ + public long getAddrValueOf(String varName) + throws UnknownVariableException { + long val = getAddrValueOf(getVariable(varName).addr); + return val; + } + + /** + * Read byte array starting at location associated with this variable name. + * + * @param varName Variable name + * @param length Numbe of bytes to read + * @return byte array read from location assigned to variable name + */ + public byte[] getByteArray(String varName, int length) + throws UnknownVariableException { + return getByteArray(getVariable(varName).addr, length); + } + + /** + * Write 8 bit integer value to location associated with this variable name. + * + * @param varName Variable name + * @param value 8 bit integer value to write + */ + public void setInt8ValueOf(String varName, byte value) + throws UnknownVariableException { + setInt8ValueOf(getVariable(varName).addr, value); + } + + /** + * Write 16 bit integer value to location associated with this variable name. + * + * @param varName Variable name + * @param value 16 bit integer value to write + */ + public void setInt16ValueOf(String varName, byte value) + throws UnknownVariableException { + setInt16ValueOf(getVariable(varName).addr, value); + } + + /** + * Write 32 bit integer value to location associated with this variable name. + * + * @param varName Variable name + * @param value 32 bit integer value to write + */ + public void setInt32ValueOf(String varName, byte value) + throws UnknownVariableException { + setInt32ValueOf(getVariable(varName).addr, value); + } + + /** + * Write 64 bit integer value to location associated with this variable name. + * + * @param varName Variable name + * @param value 64 bit integer value to write + */ + public void setInt64ValueOf(String varName, byte value) + throws UnknownVariableException { + setInt64ValueOf(getVariable(varName).addr, value); + } + + /** + * Write byte value to location associated with this variable name. + * + * @param varName Variable name + * @param value byte value to write + */ + public void setByteValueOf(String varName, byte value) + throws UnknownVariableException { + setByteValueOf(getVariable(varName).addr, value); + } + + /** + * Write short value to location associated with this variable name. + * + * @param varName Variable name + * @param value short value to write + */ + public void setShortValueOf(String varName, short value) + throws UnknownVariableException { + setShortValueOf(getVariable(varName).addr, value); + } + + /** + * Write int value to location associated with this variable name. + * + * @param varName Variable name + * @param value int value to write + */ + public void setIntValueOf(String varName, int value) + throws UnknownVariableException { + setIntValueOf(getVariable(varName).addr, value); + } + + /** + * Write long value to location associated with this variable name. + * + * @param varName Variable name + * @param value long value to write + */ + public void setLongValueOf(String varName, long value) + throws UnknownVariableException { + setLongValueOf(getVariable(varName).addr, value); + } + + /** + * Write pointer value to location associated with this variable name. + * + * The number of bytes actually written depends on the pointer size + * defined in memory layout. + * + * @param varName Variable name + * @param value Value to write + */ + public void setAddrValueOf(String varName, long value) + throws UnknownVariableException { + setAddrValueOf(getVariable(varName).addr, value); + } + + /** + * Write byte array starting at location associated with this variable name. + * + * @param varName Variable name + * @param data data to write + */ + public void setByteArray(String varName, byte[] data) + throws UnknownVariableException { + setByteArray(getVariable(varName).addr, data); + } + + /** + * Adds a monitor for the specified address region. + * + * @param flag Select memory operation(s) to listen for (read, write, read/write) + * @param varName Name of variable to monitor + * @param mm Monitor to add + * @return if monitor could be added, false if not + */ + public boolean addVarMonitor(EventType flag, final String varName, final SegmentMonitor mm) { + return memIntf.addSegmentMonitor( + flag, + getVariable(varName).addr, + getVariable(varName).size, + mm); + } + + /** + * Removes monitor assigned to the specified region. + * + * @param varName Name of monitored variable + * @param mm Monitor to remove + */ + public void removeVarMonitor(String varName, SegmentMonitor mm) { + memIntf.removeSegmentMonitor(getVariable(varName).addr, getVariable(varName).size, mm); + } +} diff --git a/tools/cooja/java/org/contikios/cooja/motes/AbstractApplicationMote.java b/tools/cooja/java/org/contikios/cooja/motes/AbstractApplicationMote.java index ec381e163..fd16d37a3 100644 --- a/tools/cooja/java/org/contikios/cooja/motes/AbstractApplicationMote.java +++ b/tools/cooja/java/org/contikios/cooja/motes/AbstractApplicationMote.java @@ -33,21 +33,22 @@ import java.util.Collection; import java.util.HashMap; import java.util.Observable; import java.util.Observer; -import java.util.Properties; import org.apache.log4j.Logger; import org.jdom.Element; import org.contikios.cooja.Mote; import org.contikios.cooja.MoteInterface; import org.contikios.cooja.MoteInterfaceHandler; -import org.contikios.cooja.MoteMemory; import org.contikios.cooja.MoteType; import org.contikios.cooja.RadioPacket; -import org.contikios.cooja.SectionMoteMemory; +import org.contikios.cooja.mote.memory.SectionMoteMemory; import org.contikios.cooja.Simulation; import org.contikios.cooja.interfaces.ApplicationRadio; import org.contikios.cooja.interfaces.ApplicationSerialPort; import org.contikios.cooja.interfaces.Radio; +import org.contikios.cooja.mote.memory.MemoryInterface; +import org.contikios.cooja.mote.memory.MemoryInterface.Symbol; +import org.contikios.cooja.mote.memory.MemoryLayout; /** * Abstract application mote. @@ -67,6 +68,7 @@ public abstract class AbstractApplicationMote extends AbstractWakeupMote impleme /* Observe our own radio for incoming radio packets */ private Observer radioDataObserver = new Observer() { + @Override public void update(Observable obs, Object obj) { ApplicationRadio radio = (ApplicationRadio) obs; if (radio.getLastEvent() == Radio.RadioEvent.RECEPTION_FINISHED) { @@ -74,7 +76,8 @@ public abstract class AbstractApplicationMote extends AbstractWakeupMote impleme if (radio.getLastPacketReceived() != null) receivedPacket(radio.getLastPacketReceived()); } else if (radio.getLastEvent() == Radio.RadioEvent.TRANSMISSION_FINISHED) { - sentPacket(radio.getLastPacketTransmitted()); + if (radio.getLastPacketTransmitted() != null) + sentPacket(radio.getLastPacketTransmitted()); } } }; @@ -89,7 +92,8 @@ public abstract class AbstractApplicationMote extends AbstractWakeupMote impleme public AbstractApplicationMote(MoteType moteType, Simulation sim) { setSimulation(sim); this.moteType = moteType; - this.memory = new SectionMoteMemory(new HashMap(), 0); + MemoryLayout.getNative(); + this.memory = new SectionMoteMemory(new HashMap()); this.moteInterfaces = new MoteInterfaceHandler(this, moteType.getMoteInterfaceClasses()); this.moteInterfaces.getRadio().addObserver(radioDataObserver); requestImmediateWakeup(); @@ -99,6 +103,7 @@ public abstract class AbstractApplicationMote extends AbstractWakeupMote impleme ((ApplicationSerialPort)moteInterfaces.getLog()).triggerLog(msg); } + @Override public MoteInterfaceHandler getInterfaces() { return moteInterfaces; } @@ -107,14 +112,16 @@ public abstract class AbstractApplicationMote extends AbstractWakeupMote impleme moteInterfaces = moteInterfaceHandler; } - public MoteMemory getMemory() { + @Override + public MemoryInterface getMemory() { return memory; } - public void setMemory(MoteMemory memory) { + public void setMemory(SectionMoteMemory memory) { this.memory = (SectionMoteMemory) memory; } + @Override public MoteType getType() { return moteType; } @@ -123,6 +130,7 @@ public abstract class AbstractApplicationMote extends AbstractWakeupMote impleme moteType = type; } + @Override public Collection getConfigXML() { ArrayList config = new ArrayList(); Element element; @@ -141,10 +149,11 @@ public abstract class AbstractApplicationMote extends AbstractWakeupMote impleme return config; } + @Override public boolean setConfigXML(Simulation simulation, Collection configXML, boolean visAvailable) { setSimulation(simulation); - this.memory = new SectionMoteMemory(new HashMap(), 0); + this.memory = new SectionMoteMemory(new HashMap()); moteInterfaces.getRadio().addObserver(radioDataObserver); for (Element element : configXML) { @@ -176,10 +185,12 @@ public abstract class AbstractApplicationMote extends AbstractWakeupMote impleme return true; } + @Override public int getID() { return moteInterfaces.getMoteID().getMoteID(); } + @Override public String toString() { return "AppMote " + getID(); } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/BaseRSSIconf.java b/tools/cooja/java/org/contikios/cooja/plugins/BaseRSSIconf.java new file mode 100644 index 000000000..bf0982902 --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/plugins/BaseRSSIconf.java @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +package org.contikios.cooja.plugins; + +import java.awt.BorderLayout; +import java.util.Observable; +import java.util.Observer; + +import javax.swing.DefaultCellEditor; +import javax.swing.JComboBox; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableCellEditor; + +import org.apache.log4j.Logger; + +import org.contikios.cooja.ClassDescription; +import org.contikios.cooja.Cooja; +import org.contikios.cooja.PluginType; +import org.contikios.cooja.Simulation; +import org.contikios.cooja.SupportedArguments; +import org.contikios.cooja.VisPlugin; +import org.contikios.cooja.interfaces.Radio; +import org.contikios.cooja.radiomediums.AbstractRadioMedium; +import org.contikios.cooja.radiomediums.DirectedGraphMedium; + + +/** + * Simple user interface for configuring BaseRSSI of Motes + * + * @see DirectedGraphMedium + * @author Sebastian Schinabeck + */ +@ClassDescription("Base RSSI") +@PluginType(PluginType.SIM_PLUGIN) +@SupportedArguments(radioMediums = { AbstractRadioMedium.class }) + +public class BaseRSSIconf extends VisPlugin { + private static final long serialVersionUID = 8955776548892545638L; + private static Logger logger = Logger.getLogger(BaseRSSIconf.class); + + private final static int IDX_Mote = 0; + private final static int IDX_BaseRSSI = 1; + + private final static String[] COLUMN_NAMES = new String[] { "Mote", + "BaseRSSI (-45!)" }; // TODO maybe include offset of -45 directly + + private Cooja gui = null; + private AbstractRadioMedium radioMedium = null; + private Observer changeObserver; + private JTable motesTable = null; + private JComboBox combo = new JComboBox(); + private Simulation sim = null; + + + + public BaseRSSIconf(Simulation sim, Cooja gui) { + super("Base RSSI Configurator", gui); + this.gui = gui; + this.sim = sim; + radioMedium = (AbstractRadioMedium) sim.getRadioMedium(); + + changeObserver = new Observer() { + public void update(Observable obs, Object obj) { + logger.debug("Changed"); + model.fireTableDataChanged(); + + } + }; + + radioMedium.addRadioMediumObserver(changeObserver); + + sim.addObserver(changeObserver); + + /* Represent motes and RSSI by table */ + motesTable = new JTable(model) { + private static final long serialVersionUID = -4680013510092815210L; + + public TableCellEditor getCellEditor(int row, int column) { + combo.removeAllItems(); + if (column == IDX_Mote) { + for (double d = 1.0; d <= radioMedium.getRegisteredRadios().length; d += 1.0) { + combo.addItem(d); + } + } else if (column == IDX_BaseRSSI) { + for (double d = AbstractRadioMedium.SS_STRONG; d >= AbstractRadioMedium.SS_NOTHING; d -= 1) { + combo.addItem((int) d); + } + } + + return super.getCellEditor(row, column); + } + }; + motesTable.setFillsViewportHeight(true); + combo.setEditable(true); + + motesTable.getColumnModel().getColumn(IDX_Mote) + .setCellRenderer(new DefaultTableCellRenderer() { // TODO ???? + private static final long serialVersionUID = 4470088575039698508L; + + public void setValue(Object value) { + if (!(value instanceof Double)) { + setText(value.toString()); + return; + } + double v = ((Double) value).doubleValue(); + setText(String.format("%1.1f", v)); + } + }); + motesTable.getColumnModel().getColumn(IDX_BaseRSSI) + .setCellRenderer(new DefaultTableCellRenderer() { + private static final long serialVersionUID = -7170745293267593460L; + + public void setValue(Object value) { + if (!(value instanceof Double)) { + setText(value.toString()); + return; + } + double v = ((Double) value).doubleValue(); + setText(String.format("%1.1f dBm", v)); + } + }); + motesTable.getColumnModel().getColumn(IDX_Mote) + .setCellEditor(new DefaultCellEditor(combo)); + motesTable.getColumnModel().getColumn(IDX_BaseRSSI) + .setCellEditor(new DefaultCellEditor(combo)); + + motesTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); + motesTable.getSelectionModel().setSelectionMode( + ListSelectionModel.SINGLE_SELECTION); + + + add(BorderLayout.CENTER, new JScrollPane(motesTable)); + + model.fireTableDataChanged(); + setSize(400, 300); + } + + + final AbstractTableModel model = new AbstractTableModel() { + private static final long serialVersionUID = 9101118401527171218L; + + public String getColumnName(int column) { + if (column < 0 || column >= COLUMN_NAMES.length) { + return ""; + } + return COLUMN_NAMES[column]; + } + + public int getRowCount() { + return radioMedium.getRegisteredRadios().length; + } + + public int getColumnCount() { + return COLUMN_NAMES.length; + } + + public Object getValueAt(int row, int column) { + if (row < 0 || row >= radioMedium.getRegisteredRadios().length) { + return ""; + } + if (column < 0 || column >= COLUMN_NAMES.length) { + return ""; + } + Radio radio = radioMedium.getRegisteredRadios()[row]; // sim.getMotes()... + if (column == IDX_Mote) { + return radio.getMote(); + } + if (column == IDX_BaseRSSI) { + return radioMedium.getBaseRssi(radio); + } + return ""; + } + + public void setValueAt(Object value, int row, int column) { + if (row < 0 || row >= radioMedium.getRegisteredRadios().length) { + return; + } + if (column < 0 || column >= COLUMN_NAMES.length) { + return; + } + + Radio radio = radioMedium.getRegisteredRadios()[row]; + try { + if (column == IDX_BaseRSSI) { + radioMedium.setBaseRssi(radio, + ((Number) value).doubleValue()); + } else { + super.setValueAt(value, row, column); + } + + } catch (ClassCastException e) { + } + } + + public boolean isCellEditable(int row, int column) { + if (row < 0 || row >= radioMedium.getRegisteredRadios().length) { + return false; + } + + if (column == IDX_Mote) { + gui.signalMoteHighlight(radioMedium.getRegisteredRadios()[row] + .getMote()); + return false; + } + if (column == IDX_BaseRSSI) { + gui.signalMoteHighlight(radioMedium.getRegisteredRadios()[row] + .getMote()); + return true; + } + return false; + } + + public Class getColumnClass(int c) { + return getValueAt(0, c).getClass(); + } + }; + + public void closePlugin() { + radioMedium.deleteRadioMediumObserver(changeObserver); + sim.deleteObserver(changeObserver); + } + +} diff --git a/tools/cooja/java/org/contikios/cooja/plugins/BufferListener.java b/tools/cooja/java/org/contikios/cooja/plugins/BufferListener.java index cf6562d8f..2a67d0243 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/BufferListener.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/BufferListener.java @@ -89,8 +89,6 @@ import org.jdom.Element; import org.contikios.cooja.ClassDescription; import org.contikios.cooja.Cooja; import org.contikios.cooja.Mote; -import org.contikios.cooja.MoteMemory; -import org.contikios.cooja.MoteMemory.MemoryEventType; import org.contikios.cooja.Plugin; import org.contikios.cooja.PluginType; import org.contikios.cooja.SimEventCentral.MoteCountListener; @@ -100,8 +98,13 @@ import org.contikios.cooja.VisPlugin; import org.contikios.cooja.dialogs.TableColumnAdjuster; import org.contikios.cooja.dialogs.UpdateAggregator; import org.contikios.cooja.interfaces.IPAddress; +import org.contikios.cooja.mote.memory.MemoryBuffer; +import org.contikios.cooja.mote.memory.MemoryInterface; +import org.contikios.cooja.mote.memory.MemoryInterface.SegmentMonitor; +import org.contikios.cooja.mote.memory.VarMemory; import org.contikios.cooja.motes.AbstractEmulatedMote; import org.contikios.cooja.util.ArrayQueue; +import org.contikios.cooja.util.IPUtils; import org.contikios.cooja.util.StringUtils; /** @@ -163,6 +166,7 @@ public class BufferListener extends VisPlugin { private Parser parser = null; private Buffer buffer = null; + @Override public void startPlugin() { super.startPlugin(); if (parser == null) { @@ -214,6 +218,7 @@ public class BufferListener extends VisPlugin { private ArrayList memoryMonitors = new ArrayList(); private TimeEvent hourTimeEvent = new TimeEvent(0) { + @Override public void execute(long t) { hasHours = true; repaintTimeColumn(); @@ -224,11 +229,13 @@ public class BufferListener extends VisPlugin { private static final int UPDATE_INTERVAL = 250; private UpdateAggregator logUpdateAggregator = new UpdateAggregator(UPDATE_INTERVAL) { private Runnable scroll = new Runnable() { + @Override public void run() { logTable.scrollRectToVisible( new Rectangle(0, logTable.getHeight() - 2, 1, logTable.getHeight())); } }; + @Override protected void handle(List ls) { boolean isVisible = true; if (logTable.getRowCount() > 0) { @@ -276,18 +283,22 @@ public class BufferListener extends VisPlugin { model = new AbstractTableModel() { private static final long serialVersionUID = 3065150390849332924L; + @Override public String getColumnName(int col) { if (col == COLUMN_TIME && formatTimeString) { return "Time"; } return COLUMN_NAMES[col]; } + @Override public int getRowCount() { return logs.size(); } + @Override public int getColumnCount() { return COLUMN_NAMES.length; } + @Override public Object getValueAt(int row, int col) { BufferAccess log = logs.get(row); if (col == COLUMN_TIME) { @@ -307,6 +318,7 @@ public class BufferListener extends VisPlugin { logTable = new JTable(model) { private static final long serialVersionUID = -930616018336483196L; + @Override public String getToolTipText(MouseEvent e) { java.awt.Point p = e.getPoint(); int rowIndex = rowAtPoint(p); @@ -356,6 +368,7 @@ public class BufferListener extends VisPlugin { new Color(220, 255, 220), new Color(255, 200, 255), }; + @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { @@ -405,6 +418,7 @@ public class BufferListener extends VisPlugin { logTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); logTable.setFont(new Font("Monospaced", Font.PLAIN, 12)); logTable.addKeyListener(new KeyAdapter() { + @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_SPACE) { showInAllAction.actionPerformed(null); @@ -419,6 +433,7 @@ public class BufferListener extends VisPlugin { /* Toggle time format */ logTable.getTableHeader().addMouseListener(new MouseAdapter() { + @Override public void mouseClicked(MouseEvent e) { int colIndex = logTable.columnAtPoint(e.getPoint()); int columnIndex = logTable.convertColumnIndexToModel(colIndex); @@ -432,6 +447,7 @@ public class BufferListener extends VisPlugin { }); logTable.addMouseListener(new MouseAdapter() { private Parser lastParser = null; + @Override public void mousePressed(MouseEvent e) { if (e.getButton() != MouseEvent.BUTTON2) { return; @@ -444,6 +460,7 @@ public class BufferListener extends VisPlugin { setParser(ByteArrayParser.class); } } + @Override public void mouseExited(MouseEvent e) { if (lastParser != null) { /* Switch back to previous parser */ @@ -451,6 +468,7 @@ public class BufferListener extends VisPlugin { lastParser = null; } } + @Override public void mouseReleased(MouseEvent e) { if (lastParser != null) { /* Switch back to previous parser */ @@ -458,6 +476,7 @@ public class BufferListener extends VisPlugin { lastParser = null; } } + @Override public void mouseClicked(MouseEvent e) { int colIndex = logTable.columnAtPoint(e.getPoint()); int columnIndex = logTable.convertColumnIndexToModel(colIndex); @@ -482,21 +501,27 @@ public class BufferListener extends VisPlugin { /* Popup menu */ JPopupMenu popupMenu = new JPopupMenu(); bufferMenu.addMenuListener(new MenuListener() { + @Override public void menuSelected(MenuEvent e) { updateBufferMenu(); } + @Override public void menuDeselected(MenuEvent e) { } + @Override public void menuCanceled(MenuEvent e) { } }); popupMenu.add(bufferMenu); parserMenu.addMenuListener(new MenuListener() { + @Override public void menuSelected(MenuEvent e) { updateParserMenu(); } + @Override public void menuDeselected(MenuEvent e) { } + @Override public void menuCanceled(MenuEvent e) { } }); @@ -521,6 +546,7 @@ public class BufferListener extends VisPlugin { colorCheckbox = new JCheckBoxMenuItem("Mote-specific coloring"); popupMenu.add(colorCheckbox); colorCheckbox.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { backgroundColors = colorCheckbox.isSelected(); repaint(); @@ -529,6 +555,7 @@ public class BufferListener extends VisPlugin { inverseFilterCheckbox = new JCheckBoxMenuItem("Inverse filter"); popupMenu.add(inverseFilterCheckbox); inverseFilterCheckbox.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { inverseFilter = inverseFilterCheckbox.isSelected(); if (inverseFilter) { @@ -543,6 +570,7 @@ public class BufferListener extends VisPlugin { hideReadsCheckbox = new JCheckBoxMenuItem("Hide READs", hideReads); popupMenu.add(hideReadsCheckbox); hideReadsCheckbox.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { hideReads = hideReadsCheckbox.isSelected(); setFilter(getFilter()); @@ -553,6 +581,7 @@ public class BufferListener extends VisPlugin { withStackTraceCheckbox = new JCheckBoxMenuItem("Capture stack traces", withStackTrace); popupMenu.add(withStackTraceCheckbox); withStackTraceCheckbox.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { withStackTrace = withStackTraceCheckbox.isSelected(); setFilter(getFilter()); @@ -564,6 +593,7 @@ public class BufferListener extends VisPlugin { /* Column width adjustment */ java.awt.EventQueue.invokeLater(new Runnable() { + @Override public void run() { /* Make sure this happens *after* adding history */ adjuster.setDynamicAdjustment(true); @@ -573,6 +603,7 @@ public class BufferListener extends VisPlugin { logUpdateAggregator.start(); simulation.getEventCentral().addMoteCountListener(logOutputListener = new MoteCountListener() { + @Override public void moteWasAdded(Mote mote) { /* Update title */ try { @@ -581,6 +612,7 @@ public class BufferListener extends VisPlugin { logger.warn("Could not monitor buffer on: " + mote, e); } } + @Override public void moteWasRemoved(Mote mote) { /* Update title */ stopObserving(mote); @@ -596,12 +628,14 @@ public class BufferListener extends VisPlugin { filterPanel.add(filterLabel); filterPanel.add(filterTextField); filterTextField.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { String str = filterTextField.getText(); setFilter(str); /* Autoscroll */ SwingUtilities.invokeLater(new Runnable() { + @Override public void run() { int s = logTable.getSelectedRow(); if (s < 0) { @@ -664,23 +698,24 @@ public class BufferListener extends VisPlugin { private void registerSegmentMonitor(int size, boolean notify) throws Exception { byte[] pointerValue = mote.getMemory().getMemorySegment(pointerAddress, pointerSize); - int segmentAddress = mote.getMemory().parseInt(pointerValue); + int segmentAddress = MemoryBuffer.wrap(mote.getMemory().getLayout(), pointerValue).getInt(); segmentMonitor = new SegmentMemoryMonitor(bl, mote, segmentAddress, size); if (notify) { - segmentMonitor.memoryChanged(mote.getMemory(), MemoryEventType.WRITE, -1); + segmentMonitor.memoryChanged(mote.getMemory(), EventType.WRITE, -1); } lastSegmentAddress = segmentAddress; } - final public void memoryChanged(MoteMemory memory, - org.contikios.cooja.MoteMemory.MemoryEventType type, int address) { - if (type == MemoryEventType.READ) { + @Override + final public void memoryChanged(MemoryInterface memory, + EventType type, long address) { + if (type == EventType.READ) { return; } byte[] pointerValue = mote.getMemory().getMemorySegment(pointerAddress, pointerSize); - int segmentAddress = mote.getMemory().parseInt(pointerValue); + int segmentAddress = MemoryBuffer.wrap(mote.getMemory().getLayout(), pointerValue).getInt(); if (segmentAddress == lastSegmentAddress) { return; } @@ -694,17 +729,19 @@ public class BufferListener extends VisPlugin { } } + @Override public MemoryMonitorType getType() { return MemoryMonitorType.POINTER; } + @Override public void dispose() { super.dispose(); segmentMonitor.dispose(); } } - static class SegmentMemoryMonitor implements org.contikios.cooja.MoteMemory.MemoryMonitor { + static class SegmentMemoryMonitor implements SegmentMonitor { protected final BufferListener bl; protected final Mote mote; @@ -721,7 +758,7 @@ public class BufferListener extends VisPlugin { this.size = size; if (address != 0) { - if (!mote.getMemory().addMemoryMonitor(address, size, this)) { + if (!mote.getMemory().addSegmentMonitor(SegmentMonitor.EventType.WRITE, address, size, this)) { throw new Exception("Could not register memory monitor on: " + mote); } } @@ -742,17 +779,18 @@ public class BufferListener extends VisPlugin { public void dispose() { if (address != 0) { - mote.getMemory().removeMemoryMonitor(address, size, this); + mote.getMemory().removeSegmentMonitor(address, size, this); } } - public void memoryChanged(MoteMemory memory, MemoryEventType type, int address) { + @Override + public void memoryChanged(MemoryInterface memory, EventType type, long address) { byte[] newData = getAddress()==0?null:mote.getMemory().getMemorySegment(getAddress(), getSize()); addBufferAccess(bl, mote, oldData, newData, type, this.address); oldData = newData; } - void addBufferAccess(BufferListener bl, Mote mote, byte[] oldData, byte[] newData, MemoryEventType type, int address) { + void addBufferAccess(BufferListener bl, Mote mote, byte[] oldData, byte[] newData, EventType type, int address) { BufferAccess ba = new BufferAccess( mote, mote.getSimulation().getSimulationTime(), @@ -793,6 +831,7 @@ public class BufferListener extends VisPlugin { } } + @Override public void closePlugin() { if (hourTimeEvent != null) hourTimeEvent.remove(); @@ -805,6 +844,7 @@ public class BufferListener extends VisPlugin { } } + @Override public Collection getConfigXML() { ArrayList config = new ArrayList(); Element element; @@ -845,12 +885,14 @@ public class BufferListener extends VisPlugin { return config; } + @Override public boolean setConfigXML(Collection configXML, boolean visAvailable) { for (Element element : configXML) { String name = element.getName(); if ("filter".equals(name)) { final String str = element.getText(); EventQueue.invokeLater(new Runnable() { + @Override public void run() { setFilter(str); } @@ -914,10 +956,11 @@ public class BufferListener extends VisPlugin { regexp = null; } RowFilter wrapped = new RowFilter() { + @Override public boolean include(RowFilter.Entry entry) { if (hideReads) { int row = (Integer) entry.getIdentifier(); - if (logs.get(row).type == MemoryEventType.READ) { + if (logs.get(row).type == SegmentMonitor.EventType.READ) { return false; } } @@ -945,6 +988,7 @@ public class BufferListener extends VisPlugin { public void trySelectTime(final long time) { java.awt.EventQueue.invokeLater(new Runnable() { + @Override public void run() { for (int i=0; i < logs.size(); i++) { if (logs.get(i).time < time) { @@ -972,13 +1016,13 @@ public class BufferListener extends VisPlugin { public final byte[] mem; private boolean[] accessedBitpattern = null; - public final MemoryEventType type; + public final SegmentMonitor.EventType type; public final String sourceStr; public final String stackTrace; public final int address; public BufferAccess( - Mote mote, long time, int address, byte[] newData, byte[] oldData, MemoryEventType type, boolean withStackTrace) { + Mote mote, long time, int address, byte[] newData, byte[] oldData, SegmentMonitor.EventType type, boolean withStackTrace) { this.mote = mote; this.time = time; this.mem = newData==null?NULL_DATA:newData; @@ -1054,6 +1098,7 @@ public class BufferListener extends VisPlugin { private Action saveAction = new AbstractAction("Save to file") { private static final long serialVersionUID = -4140706275748686944L; + @Override public void actionPerformed(ActionEvent e) { JFileChooser fc = new JFileChooser(); File suggest = new File(Cooja.getExternalToolsSetting("BUFFER_LISTENER_SAVEFILE", "BufferAccessLogger.txt")); @@ -1116,6 +1161,7 @@ public class BufferListener extends VisPlugin { private Action bufferListenerAction = new AbstractAction("in Buffer Listener") { private static final long serialVersionUID = -6358463434933029699L; + @Override public void actionPerformed(ActionEvent e) { int view = logTable.getSelectedRow(); if (view < 0) { @@ -1139,6 +1185,7 @@ public class BufferListener extends VisPlugin { private Action timeLineAction = new AbstractAction("in Timeline") { private static final long serialVersionUID = -6358463434933029699L; + @Override public void actionPerformed(ActionEvent e) { int view = logTable.getSelectedRow(); if (view < 0) { @@ -1162,6 +1209,7 @@ public class BufferListener extends VisPlugin { private Action radioLoggerAction = new AbstractAction("in Radio Logger") { private static final long serialVersionUID = -3041714249257346688L; + @Override public void actionPerformed(ActionEvent e) { int view = logTable.getSelectedRow(); if (view < 0) { @@ -1189,6 +1237,7 @@ public class BufferListener extends VisPlugin { putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true)); } + @Override public void actionPerformed(ActionEvent e) { timeLineAction.actionPerformed(null); radioLoggerAction.actionPerformed(null); @@ -1197,6 +1246,7 @@ public class BufferListener extends VisPlugin { private Action clearAction = new AbstractAction("Clear") { private static final long serialVersionUID = -2115620313183440224L; + @Override public void actionPerformed(ActionEvent e) { int size = logs.size(); if (size > 0) { @@ -1208,6 +1258,7 @@ public class BufferListener extends VisPlugin { private Action copyAction = new AbstractAction("Selected") { private static final long serialVersionUID = -8433490108577001803L; + @Override public void actionPerformed(ActionEvent e) { Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); @@ -1240,6 +1291,7 @@ public class BufferListener extends VisPlugin { private Action copyAllAction = new AbstractAction("All") { private static final long serialVersionUID = -5038884975254178373L; + @Override public void actionPerformed(ActionEvent e) { Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); @@ -1269,6 +1321,7 @@ public class BufferListener extends VisPlugin { private final ActionListener parserSelectedListener = new ActionListener() { @SuppressWarnings("unchecked") + @Override public void actionPerformed(ActionEvent e) { Class bpClass = (Class) @@ -1289,6 +1342,7 @@ public class BufferListener extends VisPlugin { private final ActionListener bufferSelectedListener = new ActionListener() { @SuppressWarnings("unchecked") + @Override public void actionPerformed(ActionEvent e) { Class btClass = (Class) @@ -1421,6 +1475,7 @@ public class BufferListener extends VisPlugin { } public static abstract class GraphicalParser implements Parser { BufferAccess ba = null; + @Override public Object parse(BufferAccess ba) { this.ba = ba; return ba; @@ -1430,6 +1485,7 @@ public class BufferListener extends VisPlugin { } public static abstract class StringParser implements Parser { + @Override public Object parse(BufferAccess ba) { return parseString(ba); } @@ -1459,13 +1515,17 @@ public class BufferListener extends VisPlugin { public void writeConfig(Element element); } public static abstract class AbstractBuffer implements Buffer { + @Override public String getStatusString() { return null; } + @Override public void writeConfig(Element element) { } + @Override public void applyConfig(Element element) { } + @Override public boolean configure(BufferListener bl) { return true; } @@ -1474,18 +1534,20 @@ public class BufferListener extends VisPlugin { public static abstract class PointerBuffer extends AbstractBuffer { public abstract int getPointerAddress(Mote mote); + @Override public SegmentMemoryMonitor createMemoryMonitor(BufferListener bl, Mote mote) throws Exception { return new PointerMemoryMonitor( bl, mote, getPointerAddress(mote), - mote.getMemory().getIntegerLength(), + mote.getMemory().getLayout().intSize, getSize(mote) ); } } public static abstract class SegmentBuffer extends AbstractBuffer { + @Override public SegmentMemoryMonitor createMemoryMonitor(BufferListener bl, Mote mote) throws Exception { return new SegmentMemoryMonitor( @@ -1521,6 +1583,7 @@ public class BufferListener extends VisPlugin { @ClassDescription("Byte array") public static class ByteArrayParser extends StringParser { + @Override public String parseString(BufferAccess ba) { boolean[] diff = ba.getAccessedBitpattern(); if (diff == null) { @@ -1562,15 +1625,18 @@ public class BufferListener extends VisPlugin { @ClassDescription("Integer array") public static class IntegerParser extends StringParser { + private VarMemory varMem = new VarMemory(null); + @Override public String parseString(BufferAccess ba) { StringBuilder sb = new StringBuilder(); + varMem.associateMemory(ba.mote.getMemory()); - int intLen = ba.mote.getMemory().getIntegerLength(); + int intLen = ba.mote.getMemory().getLayout().intSize; sb.append(""); for (int i=0; i < ba.mem.length/intLen; i++) { byte[] mem = Arrays.copyOfRange(ba.mem, i*intLen,(i+1)*intLen); boolean[] diff = Arrays.copyOfRange(ba.getAccessedBitpattern(), i*intLen,(i+1)*intLen); - int val = ba.mote.getMemory().parseInt(mem); + int val = MemoryBuffer.wrap(ba.mote.getMemory().getLayout(), mem).getInt(); boolean red = false; for (boolean changed: diff) { @@ -1592,6 +1658,7 @@ public class BufferListener extends VisPlugin { @ClassDescription("Terminated string") public static class TerminatedStringParser extends StringParser { + @Override public String parseString(BufferAccess ba) { /* TODO Diff? */ int i; @@ -1608,6 +1675,7 @@ public class BufferListener extends VisPlugin { @ClassDescription("Printable characters") public static class PrintableCharactersParser extends StringParser { + @Override public String parseString(BufferAccess ba) { /* TODO Diff? */ return new String(ba.mem).replaceAll("[^\\p{Print}]", ""); @@ -1616,6 +1684,7 @@ public class BufferListener extends VisPlugin { @ClassDescription("IPv6 address") public static class IPv6AddressParser extends StringParser { + @Override public String parseString(BufferAccess ba) { /* TODO Diff? */ if (ba.mem.length < 16) { @@ -1628,26 +1697,19 @@ public class BufferListener extends VisPlugin { } else { mem = ba.mem; } - return IPAddress.compressIPv6Address(StringUtils.toHex(mem, 2).replaceAll(" ", ":")); + return IPUtils.getCompressedIPv6AddressString(mem); } } @ClassDescription("IPv4 address") public static class IPv4AddressParser extends StringParser { + @Override public String parseString(BufferAccess ba) { /* TODO Diff? */ if (ba.mem.length < 4) { return "[must monitor at least 4 bytes]"; } - StringBuilder sb = new StringBuilder(); - sb.append(0xff&ba.mem[0]); - sb.append("."); - sb.append(0xff&ba.mem[1]); - sb.append("."); - sb.append(0xff&ba.mem[2]); - sb.append("."); - sb.append(0xff&ba.mem[3]); - return sb.toString(); + return IPUtils.getIPv4AddressString(ba.mem); } } @@ -1664,6 +1726,7 @@ public class BufferListener extends VisPlugin { parser.ba = ba; setPreferredSize(new Dimension(parser.getUnscaledWidth() + 2*XOFFSET, HEIGHT)); } + @Override public void paintComponent(Graphics g) { super.paintComponent(g); g.translate(XOFFSET, 0); @@ -1681,9 +1744,11 @@ public class BufferListener extends VisPlugin { @ClassDescription("Graphical: Height") public static class GraphicalHeight4BitsParser extends GraphicalParser { + @Override public int getUnscaledWidth() { return ba.mem.length*2; } + @Override public void paintComponent(Graphics g, JComponent c) { g.setColor(Color.GRAY); boolean[] diff = ba.getAccessedBitpattern(); @@ -1707,9 +1772,11 @@ public class BufferListener extends VisPlugin { @ClassDescription("Graphical: Grayscale") public static class GraphicalGrayscale4BitsParser extends GraphicalParser { + @Override public int getUnscaledWidth() { return ba.mem.length*2; } + @Override public void paintComponent(Graphics g, JComponent c) { boolean[] diff = ba.getAccessedBitpattern(); for (int x=0; x < ba.mem.length; x++) { @@ -1730,27 +1797,31 @@ public class BufferListener extends VisPlugin { @ClassDescription("Variable: node_id") public static class NodeIDBuffer extends SegmentBuffer { + @Override public int getAddress(Mote mote) { - if (!mote.getMemory().variableExists("node_id")) { + if (!mote.getMemory().getSymbolMap().containsKey("node_id")) { return -1; } - return mote.getMemory().getVariableAddress("node_id"); + return (int) mote.getMemory().getSymbolMap().get("node_id").addr; } + @Override public int getSize(Mote mote) { - return mote.getMemory().getIntegerLength(); + return mote.getMemory().getLayout().intSize; } } @ClassDescription("Queuebuf 0 RAM") public static class Queuebuf0Buffer extends SegmentBuffer { + @Override public int getAddress(Mote mote) { - if (!mote.getMemory().variableExists("buframmem")) { + if (!mote.getMemory().getSymbolMap().containsKey("buframmem")) { return -1; } int offset = 0; - return mote.getMemory().getVariableAddress("buframmem") + offset; + return (int) mote.getMemory().getSymbolMap().get("buframmem").addr + offset; } + @Override public int getSize(Mote mote) { return 128; } @@ -1758,12 +1829,14 @@ public class BufferListener extends VisPlugin { @ClassDescription("packetbuf_aligned") public static class PacketbufBuffer extends SegmentBuffer { + @Override public int getAddress(Mote mote) { - if (!mote.getMemory().variableExists("packetbuf_aligned")) { + if (!mote.getMemory().getSymbolMap().containsKey("packetbuf_aligned")) { return -1; } - return mote.getMemory().getVariableAddress("packetbuf_aligned"); + return (int) mote.getMemory().getSymbolMap().get("packetbuf_aligned").addr; } + @Override public int getSize(Mote mote) { return 128; } @@ -1771,18 +1844,23 @@ public class BufferListener extends VisPlugin { @ClassDescription("*packetbufptr") public static class PacketbufPointerBuffer extends PointerBuffer { + VarMemory varMem = new VarMemory(null); + @Override public int getPointerAddress(Mote mote) { - if (!mote.getMemory().variableExists("packetbufptr")) { + if (!mote.getMemory().getSymbolMap().containsKey("packetbufptr")) { return -1; } - return mote.getMemory().getVariableAddress("packetbufptr"); + return (int) mote.getMemory().getSymbolMap().get("packetbufptr").addr; } + @Override public int getAddress(Mote mote) { - if (!mote.getMemory().variableExists("packetbufptr")) { + if (!mote.getMemory().getSymbolMap().containsKey("packetbufptr")) { return -1; } - return mote.getMemory().getIntValueOf("packetbufptr"); + varMem.associateMemory(mote.getMemory()); + return varMem.getIntValueOf("packetbufptr"); } + @Override public int getSize(Mote mote) { return 128; } @@ -1793,25 +1871,31 @@ public class BufferListener extends VisPlugin { public String variable; public int size; public int offset; + VarMemory varMem = new VarMemory(null); + @Override public int getPointerAddress(Mote mote) { - if (!mote.getMemory().variableExists(variable)) { + if (!mote.getMemory().getSymbolMap().containsKey(variable)) { return -1; } - return mote.getMemory().getVariableAddress(variable); + return (int) mote.getMemory().getSymbolMap().get(variable).addr; } + @Override public int getAddress(Mote mote) { - if (!mote.getMemory().variableExists(variable)) { + if (!mote.getMemory().getSymbolMap().containsKey(variable)) { return -1; } - return mote.getMemory().getIntValueOf(variable)+offset; + varMem.associateMemory(mote.getMemory()); + return varMem.getIntValueOf(variable)+offset; } + @Override public int getSize(Mote mote) { - if (!mote.getMemory().variableExists(variable)) { + if (!mote.getMemory().getSymbolMap().containsKey(variable)) { return -1; } return size; } + @Override public String getStatusString() { if (offset > 0) { return "Pointer *" + variable + "[" + offset + "] (" + size + ")"; @@ -1820,16 +1904,19 @@ public class BufferListener extends VisPlugin { } } + @Override public void writeConfig(Element element) { element.setAttribute("variable", variable); element.setAttribute("size", "" + size); element.setAttribute("offset", "" + offset); } + @Override public void applyConfig(Element element) { variable = element.getAttributeValue("variable"); size = Integer.parseInt(element.getAttributeValue("size")); offset = Integer.parseInt(element.getAttributeValue("offset")); } + @Override public boolean configure(BufferListener bl) { String suggestName = Cooja.getExternalToolsSetting("BUFFER_LISTENER_VARNAME", "node_id"); String suggestSize = Cooja.getExternalToolsSetting("BUFFER_LISTENER_VARSIZE", "2"); @@ -1880,19 +1967,22 @@ public class BufferListener extends VisPlugin { public String variable; public int size; public int offset; + @Override public int getAddress(Mote mote) { - if (!mote.getMemory().variableExists(variable)) { + if (!mote.getMemory().getSymbolMap().containsKey(variable)) { return -1; } - return mote.getMemory().getVariableAddress(variable)+offset; + return (int) mote.getMemory().getSymbolMap().get(variable).addr+offset; } + @Override public int getSize(Mote mote) { - if (!mote.getMemory().variableExists(variable)) { + if (!mote.getMemory().getSymbolMap().containsKey(variable)) { return -1; } return size; } + @Override public String getStatusString() { if (offset > 0) { return "Symbol &" + variable + "[" + offset + "] (" + size + ")"; @@ -1901,16 +1991,19 @@ public class BufferListener extends VisPlugin { } } + @Override public void writeConfig(Element element) { element.setAttribute("variable", variable); element.setAttribute("size", "" + size); element.setAttribute("offset", "" + offset); } + @Override public void applyConfig(Element element) { variable = element.getAttributeValue("variable"); size = Integer.parseInt(element.getAttributeValue("size")); offset = Integer.parseInt(element.getAttributeValue("offset")); } + @Override public boolean configure(BufferListener bl) { String suggestName = Cooja.getExternalToolsSetting("BUFFER_LISTENER_VARNAME", "node_id"); String suggestSize = Cooja.getExternalToolsSetting("BUFFER_LISTENER_VARSIZE", "2"); @@ -1958,26 +2051,32 @@ public class BufferListener extends VisPlugin { @ClassDescription("Integer...") public static class CustomIntegerBuffer extends SegmentBuffer { public String variable; + @Override public int getAddress(Mote mote) { - if (!mote.getMemory().variableExists(variable)) { + if (!mote.getMemory().getSymbolMap().containsKey(variable)) { return -1; } - return mote.getMemory().getVariableAddress(variable); + return (int) mote.getMemory().getSymbolMap().get(variable).addr; } + @Override public int getSize(Mote mote) { - return mote.getMemory().getIntegerLength(); + return mote.getMemory().getLayout().intSize; } + @Override public String getStatusString() { return "Integer " + variable; } + @Override public void writeConfig(Element element) { element.setAttribute("variable", variable); } + @Override public void applyConfig(Element element) { variable = element.getAttributeValue("variable"); } + @Override public boolean configure(BufferListener bl) { String suggestName = Cooja.getExternalToolsSetting("BUFFER_LISTENER_VARNAME", "node_id"); BufferInput infoComponent = diff --git a/tools/cooja/java/org/contikios/cooja/plugins/DGRMConfigurator.java b/tools/cooja/java/org/contikios/cooja/plugins/DGRMConfigurator.java index 9554d7e90..df6f61d1f 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/DGRMConfigurator.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/DGRMConfigurator.java @@ -111,7 +111,7 @@ public class DGRMConfigurator extends VisPlugin { radioMedium = (DirectedGraphMedium) sim.getRadioMedium(); /* Listen for graph updates */ - radioMedium.addRadioMediumObserver(radioMediumObserver = new Observer() { + radioMedium.addRadioTransmissionObserver(radioMediumObserver = new Observer() { public void update(Observable obs, Object obj) { model.fireTableDataChanged(); } @@ -500,7 +500,7 @@ public class DGRMConfigurator extends VisPlugin { }; public void closePlugin() { - radioMedium.deleteRadioMediumObserver(radioMediumObserver); + radioMedium.deleteRadioTransmissionObserver(radioMediumObserver); } } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/EventListener.java b/tools/cooja/java/org/contikios/cooja/plugins/EventListener.java index 887503f3d..bcd454076 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/EventListener.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/EventListener.java @@ -223,7 +223,7 @@ public class EventListener extends VisPlugin { JCheckBox radioMediumCheckBox = new JCheckBox("Radio medium event", false); radioMediumCheckBox.putClientProperty("observable", mySimulation - .getRadioMedium().getRadioMediumObservable()); + .getRadioMedium().getRadioTransmissionObservable()); radioMediumCheckBox.addActionListener(generalCheckBoxListener); generalPanel.add(radioMediumCheckBox); diff --git a/tools/cooja/java/org/contikios/cooja/plugins/LogListener.java b/tools/cooja/java/org/contikios/cooja/plugins/LogListener.java index df2bf3cfc..b806906c3 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/LogListener.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/LogListener.java @@ -383,6 +383,9 @@ public class LogListener extends VisPlugin implements HasQuickHelp { } int rowIndex = logTable.rowAtPoint(e.getPoint()); + if (rowIndex == -1) { + return; + } LogData d = logs.get(logTable.getRowSorter().convertRowIndexToModel(rowIndex)); if (d == null) { return; diff --git a/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java b/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java index f73a4af8c..713390212 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java @@ -27,7 +27,6 @@ * SUCH DAMAGE. * */ - package org.contikios.cooja.plugins; import java.awt.BorderLayout; @@ -94,6 +93,7 @@ import org.contikios.cooja.Simulation; import org.contikios.cooja.VisPlugin; import org.contikios.cooja.dialogs.TableColumnAdjuster; import org.contikios.cooja.interfaces.Radio; +import org.contikios.cooja.plugins.analyzers.FragHeadPacketAnalyzer; import org.contikios.cooja.plugins.analyzers.ICMPv6Analyzer; import org.contikios.cooja.plugins.analyzers.IEEE802154Analyzer; import org.contikios.cooja.plugins.analyzers.IPHCPacketAnalyzer; @@ -111,6 +111,7 @@ import org.contikios.cooja.util.StringUtils; @ClassDescription("Radio messages") @PluginType(PluginType.SIM_PLUGIN) public class RadioLogger extends VisPlugin { + private static Logger logger = Logger.getLogger(RadioLogger.class); private static final long serialVersionUID = -6927091711697081353L; @@ -141,7 +142,7 @@ public class RadioLogger extends VisPlugin { private Observer radioMediumObserver; private AbstractTableModel model; - private HashMap analyzerMap = new HashMap(); + private HashMap analyzerMap = new HashMap(); private String analyzerName = null; private ArrayList analyzers = null; private IEEE802154Analyzer analyzerWithPcap; @@ -172,6 +173,7 @@ public class RadioLogger extends VisPlugin { ArrayList lowpanAnalyzers = new ArrayList(); lowpanAnalyzers.add(new IEEE802154Analyzer(false)); + lowpanAnalyzers.add(new FragHeadPacketAnalyzer()); lowpanAnalyzers.add(new IPHCPacketAnalyzer()); lowpanAnalyzers.add(new IPv6PacketAnalyzer()); lowpanAnalyzers.add(new ICMPv6Analyzer()); @@ -179,6 +181,7 @@ public class RadioLogger extends VisPlugin { analyzerWithPcap = new IEEE802154Analyzer(true); ArrayList lowpanAnalyzersPcap = new ArrayList(); lowpanAnalyzersPcap.add(analyzerWithPcap); + lowpanAnalyzersPcap.add(new FragHeadPacketAnalyzer()); lowpanAnalyzersPcap.add(new IPHCPacketAnalyzer()); lowpanAnalyzersPcap.add(new IPv6PacketAnalyzer()); lowpanAnalyzersPcap.add(new ICMPv6Analyzer()); @@ -187,6 +190,7 @@ public class RadioLogger extends VisPlugin { private static final long serialVersionUID = 1692207305977527004L; + @Override public String getColumnName(int col) { if (col == COLUMN_TIME && formatTimeString) { return "Time"; @@ -194,14 +198,17 @@ public class RadioLogger extends VisPlugin { return COLUMN_NAMES[col]; } + @Override public int getRowCount() { return connections.size(); } + @Override public int getColumnCount() { return COLUMN_NAMES.length; } + @Override public Object getValueAt(int row, int col) { if (row < 0 || row >= connections.size()) { return ""; @@ -247,6 +254,7 @@ public class RadioLogger extends VisPlugin { return null; } + @Override public boolean isCellEditable(int row, int col) { if (col == COLUMN_FROM) { /* Highlight source */ @@ -265,6 +273,7 @@ public class RadioLogger extends VisPlugin { return false; } + @Override public Class getColumnClass(int c) { return getValueAt(0, c).getClass(); } @@ -274,6 +283,7 @@ public class RadioLogger extends VisPlugin { private static final long serialVersionUID = -2199726885069809686L; + @Override public String getToolTipText(MouseEvent e) { java.awt.Point p = e.getPoint(); int rowIndex = rowAtPoint(p); @@ -290,14 +300,13 @@ public class RadioLogger extends VisPlugin { /* TODO This entry may represent several hidden connections */ RadioConnectionLog conn = connections.get(modelRowIndex); if (modelColumnIndex == COLUMN_TIME) { - return - "" + - "Start time (us): " + conn.startTime + - "
    " + - "End time (us): " + conn.endTime + - "

    " + - "Duration (us): " + (conn.endTime - conn.startTime) + - ""; + return "" + + "Start time (us): " + conn.startTime + + "
    " + + "End time (us): " + conn.endTime + + "

    " + + "Duration (us): " + (conn.endTime - conn.startTime) + + ""; } else if (modelColumnIndex == COLUMN_FROM) { return conn.connection.getSource().getMote().toString(); } else if (modelColumnIndex == COLUMN_TO) { @@ -329,6 +338,7 @@ public class RadioLogger extends VisPlugin { /* Toggle time format */ dataTable.getTableHeader().addMouseListener(new MouseAdapter() { + @Override public void mouseClicked(MouseEvent e) { int colIndex = dataTable.columnAtPoint(e.getPoint()); int columnIndex = dataTable.convertColumnIndexToModel(colIndex); @@ -337,25 +347,26 @@ public class RadioLogger extends VisPlugin { } formatTimeString = !formatTimeString; dataTable.getColumnModel().getColumn(COLUMN_TIME).setHeaderValue( - dataTable.getModel().getColumnName(COLUMN_TIME)); + dataTable.getModel().getColumnName(COLUMN_TIME)); repaint(); } }); dataTable.addKeyListener(new KeyAdapter() { + @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_SPACE) { showInAllAction.actionPerformed(null); - } else if (e.getKeyCode() == KeyEvent.VK_F && - (e.getModifiers() & KeyEvent.CTRL_MASK) != 0) { - searchField.setVisible(true); - searchField.requestFocus(); - searchField.selectAll(); - revalidate(); + } else if (e.getKeyCode() == KeyEvent.VK_F + && (e.getModifiers() & KeyEvent.CTRL_MASK) != 0) { + searchField.setVisible(true); + searchField.requestFocus(); + searchField.selectAll(); + revalidate(); } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { - searchField.setVisible(false); - dataTable.requestFocus(); - revalidate(); + searchField.setVisible(false); + dataTable.requestFocus(); + revalidate(); } } }); @@ -367,21 +378,22 @@ public class RadioLogger extends VisPlugin { dataTable.setRowSorter(logFilter); dataTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - public void valueChanged(ListSelectionEvent e) { - int row = dataTable.getSelectedRow(); - if (row < 0) { - return; - } - int modelRowIndex = dataTable.convertRowIndexToModel(row); - if (modelRowIndex >= 0) { - RadioConnectionLog conn = connections.get(modelRowIndex); - if (conn.tooltip == null) { - prepareTooltipString(conn); - } - verboseBox.setText(conn.tooltip); - verboseBox.setCaretPosition(0); - } + @Override + public void valueChanged(ListSelectionEvent e) { + int row = dataTable.getSelectedRow(); + if (row < 0) { + return; } + int modelRowIndex = dataTable.convertRowIndexToModel(row); + if (modelRowIndex >= 0) { + RadioConnectionLog conn = connections.get(modelRowIndex); + if (conn.tooltip == null) { + prepareTooltipString(conn); + } + verboseBox.setText(conn.tooltip); + verboseBox.setCaretPosition(0); + } + } }); // Set data column width greedy dataTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); @@ -395,11 +407,13 @@ public class RadioLogger extends VisPlugin { payloadMenu.add(new JMenuItem(aliasAction)); payloadMenu.add(new JCheckBoxMenuItem(showDuplicatesAction) { + @Override public boolean isSelected() { return showDuplicates; } }); payloadMenu.add(new JCheckBoxMenuItem(hideNoDestinationAction) { + @Override public boolean isSelected() { return hideNoDestinationPackets; } @@ -407,7 +421,6 @@ public class RadioLogger extends VisPlugin { fileMenu.add(new JMenuItem(saveAction)); - JPopupMenu popupMenu = new JPopupMenu(); JMenu focusMenu = new JMenu("Show in"); @@ -418,7 +431,6 @@ public class RadioLogger extends VisPlugin { popupMenu.add(focusMenu); //a group of radio button menu items - ButtonGroup group = new ButtonGroup(); JRadioButtonMenuItem rbMenuItem = new JRadioButtonMenuItem( createAnalyzerAction("No Analyzer", "none", null, true)); @@ -426,7 +438,7 @@ public class RadioLogger extends VisPlugin { analyzerMenu.add(rbMenuItem); rbMenuItem = new JRadioButtonMenuItem(createAnalyzerAction( - "6LoWPAN Analyzer", "6lowpan", lowpanAnalyzers, false)); + "6LoWPAN Analyzer", "6lowpan", lowpanAnalyzers, false)); group.add(rbMenuItem); analyzerMenu.add(rbMenuItem); @@ -436,20 +448,20 @@ public class RadioLogger extends VisPlugin { analyzerMenu.add(rbMenuItem); /* Load additional analyzers specified by projects (cooja.config) */ - String[] projectAnalyzerSuites = - gui.getProjectConfig().getStringArrayValue(RadioLogger.class, "ANALYZERS"); + String[] projectAnalyzerSuites + = gui.getProjectConfig().getStringArrayValue(RadioLogger.class, "ANALYZERS"); if (projectAnalyzerSuites != null) { for (String suiteName: projectAnalyzerSuites) { if (suiteName == null || suiteName.trim().isEmpty()) { continue; } - Class suiteClass = - gui.tryLoadClass(RadioLogger.this, RadioLoggerAnalyzerSuite.class, suiteName); + Class suiteClass + = gui.tryLoadClass(RadioLogger.this, RadioLoggerAnalyzerSuite.class, suiteName); try { RadioLoggerAnalyzerSuite suite = suiteClass.newInstance(); ArrayList suiteAnalyzers = suite.getAnalyzers(); rbMenuItem = new JRadioButtonMenuItem(createAnalyzerAction( - suite.getDescription(), suiteName, suiteAnalyzers, false)); + suite.getDescription(), suiteName, suiteAnalyzers, false)); group.add(rbMenuItem); analyzerMenu.add(rbMenuItem); logger.debug("Loaded radio logger analyzers: " + suite.getDescription()); @@ -472,21 +484,22 @@ public class RadioLogger extends VisPlugin { /* Search text field */ searchField.setVisible(false); searchField.addKeyListener(new KeyAdapter() { + @Override public void keyPressed(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_ENTER) { - searchSelectNext( - searchField.getText(), - (e.getModifiers() & KeyEvent.SHIFT_MASK) != 0); - } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { - searchField.setVisible(false); - dataTable.requestFocus(); - revalidate(); + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + searchSelectNext( + searchField.getText(), + (e.getModifiers() & KeyEvent.SHIFT_MASK) != 0); + } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { + searchField.setVisible(false); + dataTable.requestFocus(); + revalidate(); } } }); splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, - new JScrollPane(dataTable), new JScrollPane(verboseBox)); + new JScrollPane(dataTable), new JScrollPane(verboseBox)); splitPane.setOneTouchExpandable(true); splitPane.setDividerLocation(150); add(BorderLayout.NORTH, searchField); @@ -496,18 +509,22 @@ public class RadioLogger extends VisPlugin { adjuster.setDynamicAdjustment(true); adjuster.packColumns(); - radioMedium.addRadioMediumObserver(radioMediumObserver = new Observer() { + radioMedium.addRadioTransmissionObserver(radioMediumObserver = new Observer() { + @Override public void update(Observable obs, Object obj) { RadioConnection conn = radioMedium.getLastConnection(); if (conn == null) { return; } final RadioConnectionLog loggedConn = new RadioConnectionLog(); + loggedConn.packet = conn.getSource().getLastPacketTransmitted(); + if (loggedConn.packet == null) + return; loggedConn.startTime = conn.getStartTime(); loggedConn.endTime = simulation.getSimulationTime(); loggedConn.connection = conn; - loggedConn.packet = conn.getSource().getLastPacketTransmitted(); java.awt.EventQueue.invokeLater(new Runnable() { + @Override public void run() { int lastSize = connections.size(); // Check if the last row is visible @@ -528,8 +545,8 @@ public class RadioLogger extends VisPlugin { setTitle("Radio messages: showing " + dataTable.getRowCount() + "/" + connections.size() + " packets"); } }); - } - }); + } + }); setSize(500, 300); try { @@ -539,45 +556,46 @@ public class RadioLogger extends VisPlugin { } } + @Override public void startPlugin() { super.startPlugin(); rebuildAllEntries(); } - - private void searchSelectNext(String text, boolean reverse) { - if (text.isEmpty()) { - return; - } - int row = dataTable.getSelectedRow(); + + private void searchSelectNext(String text, boolean reverse) { + if (text.isEmpty()) { + return; + } + int row = dataTable.getSelectedRow(); if (row < 0) { - row = 0; + row = 0; } if (!reverse) { - row++; + row++; } else { - row--; + row--; } int rows = dataTable.getModel().getRowCount(); - for (int i=0; i < rows; i++) { - int r; - if (!reverse) { - r = (row + i + rows)%rows; - } else { - r = (row - i + rows)%rows; - } - String val = (String) dataTable.getModel().getValueAt(r, COLUMN_DATA); - if (!val.contains(text)) { - continue; - } - dataTable.setRowSelectionInterval(r,r); - dataTable.scrollRectToVisible(dataTable.getCellRect(r, COLUMN_DATA, true)); - searchField.setBackground(Color.WHITE); - return; + for (int i = 0; i < rows; i++) { + int r; + if (!reverse) { + r = (row + i + rows) % rows; + } else { + r = (row - i + rows) % rows; + } + String val = (String) dataTable.getModel().getValueAt(r, COLUMN_DATA); + if (!val.contains(text)) { + continue; + } + dataTable.setRowSelectionInterval(r, r); + dataTable.scrollRectToVisible(dataTable.getCellRect(r, COLUMN_DATA, true)); + searchField.setBackground(Color.WHITE); + return; } - searchField.setBackground(Color.RED); - } + searchField.setBackground(Color.RED); + } /** * Selects a logged radio packet close to the given time. @@ -586,55 +604,57 @@ public class RadioLogger extends VisPlugin { */ public void trySelectTime(final long time) { java.awt.EventQueue.invokeLater(new Runnable() { + @Override public void run() { if (dataTable.getRowCount() == 0) { return; } - for (int ai=0; ai < model.getRowCount(); ai++) { + for (int ai = 0; ai < model.getRowCount(); ai++) { int index = dataTable.convertRowIndexToModel(ai); if (connections.get(index).endTime < time) { continue; } - + dataTable.scrollRectToVisible(dataTable.getCellRect(ai, 0, true)); dataTable.setRowSelectionInterval(ai, ai); return; } - dataTable.scrollRectToVisible(dataTable.getCellRect(dataTable.getRowCount()-1, 0, true)); - dataTable.setRowSelectionInterval(dataTable.getRowCount()-1, dataTable.getRowCount()-1); + dataTable.scrollRectToVisible(dataTable.getCellRect(dataTable.getRowCount() - 1, 0, true)); + dataTable.setRowSelectionInterval(dataTable.getRowCount() - 1, dataTable.getRowCount() - 1); } }); } private void applyFilter() { - for(RadioConnectionLog conn: connections) { + for (RadioConnectionLog conn: connections) { conn.data = null; conn.tooltip = null; conn.hides = 0; conn.hiddenBy = null; - } + } try { logFilter.setRowFilter(null); RowFilter filter = new RowFilter() { + @Override public boolean include(RowFilter.Entry entry) { int row = (Integer) entry.getIdentifier(); RadioConnectionLog current = connections.get(row); byte[] currentData = current.packet.getPacketData(); if (!showDuplicates && row > 0) { - RadioConnectionLog previous = connections.get(row-1); + RadioConnectionLog previous = connections.get(row - 1); byte[] previousData = previous.packet.getPacketData(); - if (!showDuplicates && - Arrays.equals(previousData, currentData) && - previous.connection.getSource() == current.connection.getSource() && - Arrays.equals(previous.connection.getAllDestinations(), current.connection.getAllDestinations())) { - if (connections.get(row-1).hiddenBy == null) { - connections.get(row-1).hides++; - connections.get(row).hiddenBy = connections.get(row-1); + if (!showDuplicates + && Arrays.equals(previousData, currentData) + && previous.connection.getSource() == current.connection.getSource() + && Arrays.equals(previous.connection.getAllDestinations(), current.connection.getAllDestinations())) { + if (connections.get(row - 1).hiddenBy == null) { + connections.get(row - 1).hides++; + connections.get(row).hiddenBy = connections.get(row - 1); } else { - connections.get(row-1).hiddenBy.hides++; - connections.get(row).hiddenBy = connections.get(row-1).hiddenBy; + connections.get(row - 1).hiddenBy.hides++; + connections.get(row).hiddenBy = connections.get(row - 1).hiddenBy; } return false; } @@ -661,7 +681,7 @@ public class RadioLogger extends VisPlugin { if (conn.packet == null) { data = null; } else if (conn.packet instanceof ConvertedRadioPacket) { - data = ((ConvertedRadioPacket)conn.packet).getOriginalPacketData(); + data = ((ConvertedRadioPacket) conn.packet).getOriginalPacketData(); } else { data = conn.packet.getPacketData(); } @@ -670,63 +690,63 @@ public class RadioLogger extends VisPlugin { return; } - StringBuffer brief = new StringBuffer(); - StringBuffer verbose = new StringBuffer(); + StringBuilder brief = new StringBuilder(); + StringBuilder verbose = new StringBuilder(); /* default analyzer */ PacketAnalyzer.Packet packet = new PacketAnalyzer.Packet(data, PacketAnalyzer.MAC_LEVEL); if (analyzePacket(packet, brief, verbose)) { - if (packet.hasMoreData()) { - byte[] payload = packet.getPayload(); - brief.append(StringUtils.toHex(payload, 4)); - if (verbose.length() > 0) { - verbose.append("

    "); - } - verbose.append("Payload (") - .append(payload.length).append(" bytes)

    ")
    -            .append(StringUtils.hexDump(payload))
    -            .append("
    "); - } - conn.data = (data.length < 100 ? (data.length < 10 ? " " : " ") : "") - + data.length + ": " + brief; + if (packet.hasMoreData()) { + byte[] payload = packet.getPayload(); + brief.append(StringUtils.toHex(payload, 4)); if (verbose.length() > 0) { - conn.tooltip = verbose.toString(); + verbose.append("

    "); } + verbose.append("Payload (") + .append(payload.length).append(" bytes)

    ")
    +                .append(StringUtils.hexDump(payload))
    +                .append("
    "); + } + conn.data = (data.length < 100 ? (data.length < 10 ? " " : " ") : "") + + data.length + ": " + brief; + if (verbose.length() > 0) { + conn.tooltip = verbose.toString(); + } } else { - conn.data = data.length + ": 0x" + StringUtils.toHex(data, 4); + conn.data = data.length + ": 0x" + StringUtils.toHex(data, 4); } } - private boolean analyzePacket(PacketAnalyzer.Packet packet, StringBuffer brief, StringBuffer verbose) { - if (analyzers == null) return false; - try { - boolean analyze = true; - while (analyze) { - analyze = false; - for (int i = 0; i < analyzers.size(); i++) { - PacketAnalyzer analyzer = analyzers.get(i); - if (analyzer.matchPacket(packet)) { - int res = analyzer.analyzePacket(packet, brief, verbose); - if (packet.hasMoreData() && brief.length() > 0) { - brief.append('|'); - verbose.append("
    "); - } - if (res != PacketAnalyzer.ANALYSIS_OK_CONTINUE) { - /* this was the final or the analysis failed - no analyzable payload possible here... */ - return brief.length() > 0; - } - /* continue another round if more bytes left */ - analyze = packet.hasMoreData(); - break; - } + private boolean analyzePacket(PacketAnalyzer.Packet packet, StringBuilder brief, StringBuilder verbose) { + if (analyzers == null) return false; + try { + boolean analyze = true; + while (analyze) { + analyze = false; + for (int i = 0; i < analyzers.size(); i++) { + PacketAnalyzer analyzer = analyzers.get(i); + if (analyzer.matchPacket(packet)) { + int res = analyzer.analyzePacket(packet, brief, verbose); + if (packet.hasMoreData() && brief.length() > 0) { + brief.append('|'); + verbose.append("
    "); + } + if (res != PacketAnalyzer.ANALYSIS_OK_CONTINUE) { + /* this was the final or the analysis failed - no analyzable payload possible here... */ + return brief.length() > 0; + } + /* continue another round if more bytes left */ + analyze = packet.hasMoreData(); + break; } + } } - } catch (Exception e) { - logger.debug("Error when analyzing packet: " + e.getMessage(), e); - return false; - } - return brief.length() > 0; + } catch (Exception e) { + logger.debug("Error when analyzing packet: " + e.getMessage(), e); + return false; + } + return brief.length() > 0; } private void prepareTooltipString(RadioConnectionLog conn) { @@ -737,38 +757,40 @@ public class RadioLogger extends VisPlugin { } if (packet instanceof ConvertedRadioPacket && packet.getPacketData().length > 0) { - byte[] original = ((ConvertedRadioPacket)packet).getOriginalPacketData(); - byte[] converted = ((ConvertedRadioPacket)packet).getPacketData(); - conn.tooltip = "" + - "Packet data (" + original.length + " bytes)
    " + - "
    " + StringUtils.hexDump(original) + "
    " + - "
    " + - "Cross-level packet data (" + converted.length + " bytes)
    " + - "
    " + StringUtils.hexDump(converted) + "
    " + - "
    "; + byte[] original = ((ConvertedRadioPacket) packet).getOriginalPacketData(); + byte[] converted = ((ConvertedRadioPacket) packet).getPacketData(); + conn.tooltip = "" + + "Packet data (" + original.length + " bytes)
    " + + "
    " + StringUtils.hexDump(original) + "
    " + + "
    " + + "Cross-level packet data (" + converted.length + " bytes)
    " + + "
    " + StringUtils.hexDump(converted) + "
    " + + "
    "; } else if (packet instanceof ConvertedRadioPacket) { - byte[] original = ((ConvertedRadioPacket)packet).getOriginalPacketData(); - conn.tooltip = "" + - "Packet data (" + original.length + " bytes)
    " + - "
    " + StringUtils.hexDump(original) + "
    " + - "
    " + - "No cross-level conversion available
    " + - "
    "; + byte[] original = ((ConvertedRadioPacket) packet).getOriginalPacketData(); + conn.tooltip = "" + + "Packet data (" + original.length + " bytes)
    " + + "
    " + StringUtils.hexDump(original) + "
    " + + "
    " + + "No cross-level conversion available
    " + + "
    "; } else { byte[] data = packet.getPacketData(); - conn.tooltip = "" + - "Packet data (" + data.length + " bytes)
    " + - "
    " + StringUtils.hexDump(data) + "
    " + - "
    "; + conn.tooltip = "" + + "Packet data (" + data.length + " bytes)
    " + + "
    " + StringUtils.hexDump(data) + "
    " + + "
    "; } } + @Override public void closePlugin() { if (radioMediumObserver != null) { - radioMedium.deleteRadioMediumObserver(radioMediumObserver); + radioMedium.deleteRadioTransmissionObserver(radioMediumObserver); } } + @Override public Collection getConfigXML() { ArrayList config = new ArrayList(); @@ -784,7 +806,7 @@ public class RadioLogger extends VisPlugin { element = new Element("showdups"); element.addContent(Boolean.toString(showDuplicates)); config.add(element); - + element = new Element("hidenodests"); element.addContent(Boolean.toString(hideNoDestinationPackets)); config.add(element); @@ -796,7 +818,7 @@ public class RadioLogger extends VisPlugin { } if (aliases != null) { - for (Object key: aliases.keySet()) { + for (Object key : aliases.keySet()) { element = new Element("alias"); element.setAttribute("payload", (String) key); element.setAttribute("alias", (String) aliases.get(key)); @@ -815,6 +837,7 @@ public class RadioLogger extends VisPlugin { return config; } + @Override public boolean setConfigXML(Collection configXML, boolean visAvailable) { for (Element element : configXML) { String name = element.getName(); @@ -838,6 +861,7 @@ public class RadioLogger extends VisPlugin { final Action action; if (analyzerName != null && ((action = analyzerMap.get(analyzerName)) != null)) { java.awt.EventQueue.invokeLater(new Runnable() { + @Override public void run() { action.putValue(Action.SELECTED_KEY, Boolean.TRUE); action.actionPerformed(null); @@ -853,26 +877,27 @@ public class RadioLogger extends VisPlugin { } private class RadioConnectionLog { + long startTime; long endTime; RadioConnection connection; RadioPacket packet; - + RadioConnectionLog hiddenBy = null; int hides = 0; String data = null; String tooltip = null; + @Override public String toString() { - if (data == null) { - RadioLogger.this.prepareDataString(this); - } - return - Long.toString(startTime / Simulation.MILLISECOND) + "\t" + - connection.getSource().getMote().getID() + "\t" + - getDestString(this) + "\t" + - data; + if (data == null) { + RadioLogger.this.prepareDataString(this); + } + return Long.toString(startTime / Simulation.MILLISECOND) + "\t" + + connection.getSource().getMote().getID() + "\t" + + getDestString(this) + "\t" + + data; } } @@ -888,13 +913,13 @@ public class RadioLogger extends VisPlugin { for (Radio dest: dests) { sb.append(dest.getMote().getID()).append(','); } - sb.setLength(sb.length()-1); + sb.setLength(sb.length() - 1); return sb.toString(); } private void rebuildAllEntries() { applyFilter(); - + if (connections.size() > 0) { model.fireTableRowsUpdated(0, connections.size() - 1); } @@ -903,28 +928,30 @@ public class RadioLogger extends VisPlugin { setTitle("Radio messages: showing " + dataTable.getRowCount() + "/" + connections.size() + " packets"); simulation.getCooja().getDesktopPane().repaint(); } - - private Action createAnalyzerAction(String name, final String actionName, - final ArrayList analyzerList, boolean selected) { - Action action = new AbstractAction(name) { - private static final long serialVersionUID = -608913700422638454L; - public void actionPerformed(ActionEvent event) { - if (analyzers != analyzerList) { - analyzers = analyzerList; - analyzerName = actionName; - rebuildAllEntries(); - } + private Action createAnalyzerAction(String name, final String actionName, + final ArrayList analyzerList, boolean selected) { + Action action = new AbstractAction(name) { + private static final long serialVersionUID = -608913700422638454L; + + @Override + public void actionPerformed(ActionEvent event) { + if (analyzers != analyzerList) { + analyzers = analyzerList; + analyzerName = actionName; + rebuildAllEntries(); } - }; - action.putValue(Action.SELECTED_KEY, selected ? Boolean.TRUE : Boolean.FALSE); - analyzerMap.put(actionName, action); - return action; + } + }; + action.putValue(Action.SELECTED_KEY, selected ? Boolean.TRUE : Boolean.FALSE); + analyzerMap.put(actionName, action); + return action; } private Action clearAction = new AbstractAction("Clear") { private static final long serialVersionUID = -6135583266684643117L; + @Override public void actionPerformed(ActionEvent e) { int size = connections.size(); if (size > 0) { @@ -938,6 +965,7 @@ public class RadioLogger extends VisPlugin { private Action copyAction = new AbstractAction("Copy selected") { private static final long serialVersionUID = 8412062977916108054L; + @Override public void actionPerformed(ActionEvent e) { Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); @@ -957,11 +985,12 @@ public class RadioLogger extends VisPlugin { private Action copyAllAction = new AbstractAction("Copy all") { private static final long serialVersionUID = 1905586689441157304L; + @Override public void actionPerformed(ActionEvent e) { Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); StringBuilder sb = new StringBuilder(); - for(int i=0; i < connections.size(); i++) { + for (int i = 0; i < connections.size(); i++) { sb.append(connections.get(i).toString() + "\n"); } @@ -973,6 +1002,7 @@ public class RadioLogger extends VisPlugin { private Action saveAction = new AbstractAction("Save to file...") { private static final long serialVersionUID = -3942984643211482179L; + @Override public void actionPerformed(ActionEvent e) { JFileChooser fc = new JFileChooser(); int returnVal = fc.showSaveDialog(Cooja.getTopParentContainer()); @@ -984,12 +1014,12 @@ public class RadioLogger extends VisPlugin { if (saveFile.exists()) { String s1 = "Overwrite"; String s2 = "Cancel"; - Object[] options = { s1, s2 }; + Object[] options = {s1, s2}; int n = JOptionPane.showOptionDialog( - Cooja.getTopParentContainer(), - "A file with the same name already exists.\nDo you want to remove it?", - "Overwrite existing file?", JOptionPane.YES_NO_OPTION, - JOptionPane.QUESTION_MESSAGE, null, options, s1); + Cooja.getTopParentContainer(), + "A file with the same name already exists.\nDo you want to remove it?", + "Overwrite existing file?", JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE, null, options, s1); if (n != JOptionPane.YES_OPTION) { return; } @@ -1002,7 +1032,7 @@ public class RadioLogger extends VisPlugin { try { PrintWriter outStream = new PrintWriter(new FileWriter(saveFile)); - for(int i=0; i < connections.size(); i++) { + for (int i = 0; i < connections.size(); i++) { outStream.print(connections.get(i).toString() + "\n"); } outStream.close(); @@ -1016,6 +1046,8 @@ public class RadioLogger extends VisPlugin { private Action timeLineAction = new AbstractAction("Timeline") { private static final long serialVersionUID = -4035633464748224192L; + + @Override public void actionPerformed(ActionEvent e) { int selectedRow = dataTable.getSelectedRow(); if (selectedRow < 0) return; @@ -1026,12 +1058,12 @@ public class RadioLogger extends VisPlugin { Plugin[] plugins = simulation.getCooja().getStartedPlugins(); for (Plugin p: plugins) { - if (!(p instanceof TimeLine)) { - continue; - } + if (!(p instanceof TimeLine)) { + continue; + } /* Select simulation time */ - TimeLine plugin = (TimeLine) p; + TimeLine plugin = (TimeLine) p; plugin.trySelectTime(time); } } @@ -1039,6 +1071,8 @@ public class RadioLogger extends VisPlugin { private Action logListenerAction = new AbstractAction("Mote output") { private static final long serialVersionUID = 1985006491187878651L; + + @Override public void actionPerformed(ActionEvent e) { int selectedRow = dataTable.getSelectedRow(); if (selectedRow < 0) return; @@ -1049,12 +1083,12 @@ public class RadioLogger extends VisPlugin { Plugin[] plugins = simulation.getCooja().getStartedPlugins(); for (Plugin p: plugins) { - if (!(p instanceof LogListener)) { - continue; - } + if (!(p instanceof LogListener)) { + continue; + } /* Select simulation time */ - LogListener plugin = (LogListener) p; + LogListener plugin = (LogListener) p; plugin.trySelectTime(time); } } @@ -1062,9 +1096,12 @@ public class RadioLogger extends VisPlugin { private Action showInAllAction = new AbstractAction("Timeline and mote output") { private static final long serialVersionUID = -3888292108886138128L; + { - putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true)); + putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true)); } + + @Override public void actionPerformed(ActionEvent e) { timeLineAction.actionPerformed(null); logListenerAction.actionPerformed(null); @@ -1075,6 +1112,7 @@ public class RadioLogger extends VisPlugin { private Action aliasAction = new AbstractAction("Payload alias...") { private static final long serialVersionUID = -1678771087456128721L; + @Override public void actionPerformed(ActionEvent e) { int selectedRow = dataTable.getSelectedRow(); if (selectedRow < 0) return; @@ -1087,15 +1125,15 @@ public class RadioLogger extends VisPlugin { } String alias = (String) JOptionPane.showInputDialog( - Cooja.getTopParentContainer(), - "Enter alias for all packets with identical payload.\n" + - "An empty string removes the current alias.\n\n" + - connections.get(selectedRow).data + "\n", - "Create packet payload alias", - JOptionPane.QUESTION_MESSAGE, - null, - null, - current); + Cooja.getTopParentContainer(), + "Enter alias for all packets with identical payload.\n" + + "An empty string removes the current alias.\n\n" + + connections.get(selectedRow).data + "\n", + "Create packet payload alias", + JOptionPane.QUESTION_MESSAGE, + null, + null, + current); if (alias == null) { /* Cancelled */ return; @@ -1126,6 +1164,7 @@ public class RadioLogger extends VisPlugin { private boolean showDuplicates = false; private AbstractAction showDuplicatesAction = new AbstractAction("Show duplicates") { + @Override public void actionPerformed(ActionEvent e) { showDuplicates = !showDuplicates; rebuildAllEntries(); @@ -1134,6 +1173,7 @@ public class RadioLogger extends VisPlugin { private boolean hideNoDestinationPackets = false; private AbstractAction hideNoDestinationAction = new AbstractAction("Hide airshots") { + @Override public void actionPerformed(ActionEvent e) { hideNoDestinationPackets = !hideNoDestinationPackets; rebuildAllEntries(); @@ -1141,16 +1181,16 @@ public class RadioLogger extends VisPlugin { }; public String getConnectionsString() { - StringBuilder sb = new StringBuilder(); - RadioConnectionLog[] cs = connections.toArray(new RadioConnectionLog[0]); - for(RadioConnectionLog c: cs) { + StringBuilder sb = new StringBuilder(); + RadioConnectionLog[] cs = connections.toArray(new RadioConnectionLog[0]); + for (RadioConnectionLog c : cs) { sb.append(c.toString() + "\n"); } return sb.toString(); - }; + } public void saveConnectionsToFile(String fileName) { StringUtils.saveToFile(new File(fileName), getConnectionsString()); - }; + } } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/ScriptRunner.java b/tools/cooja/java/org/contikios/cooja/plugins/ScriptRunner.java index b77d365c8..2df863a25 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/ScriptRunner.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/ScriptRunner.java @@ -85,10 +85,11 @@ import org.contikios.cooja.PluginType; import org.contikios.cooja.Simulation; import org.contikios.cooja.VisPlugin; import org.contikios.cooja.dialogs.MessageList; +import org.contikios.cooja.dialogs.MessageListUI; import org.contikios.cooja.util.StringUtils; @ClassDescription("Simulation script editor") -@PluginType(PluginType.SIM_PLUGIN) +@PluginType(PluginType.SIM_CONTROL_PLUGIN) public class ScriptRunner extends VisPlugin { private static final long serialVersionUID = 7614358340336799109L; private static Logger logger = Logger.getLogger(ScriptRunner.class); @@ -276,6 +277,14 @@ public class ScriptRunner extends VisPlugin { } } + public void startPlugin() { + /* start simulation */ + if (!Cooja.isVisualized()) { + simulation.setSpeedLimit(null); + simulation.startSimulation(); + } + } + public void setLinkFile(File source) { linkedFile = source; if (source == null) { @@ -495,7 +504,7 @@ public class ScriptRunner extends VisPlugin { final BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream())); /* GUI components */ - final MessageList testOutput = new MessageList(); + final MessageListUI testOutput = new MessageListUI(); final AbstractAction abort = new AbstractAction() { public void actionPerformed(ActionEvent e) { process.destroy(); @@ -530,14 +539,14 @@ public class ScriptRunner extends VisPlugin { String line; try { while ((line = input.readLine()) != null) { - testOutput.addMessage(line, MessageList.NORMAL); + testOutput.addMessage(line, MessageListUI.NORMAL); } } catch (IOException e) { } - testOutput.addMessage("", MessageList.NORMAL); - testOutput.addMessage("", MessageList.NORMAL); - testOutput.addMessage("", MessageList.NORMAL); + testOutput.addMessage("", MessageListUI.NORMAL); + testOutput.addMessage("", MessageListUI.NORMAL); + testOutput.addMessage("", MessageListUI.NORMAL); /* Parse log file, check if test succeeded */ try { @@ -551,7 +560,7 @@ public class ScriptRunner extends VisPlugin { if (l == null) { line = ""; } - testOutput.addMessage(l, MessageList.NORMAL); + testOutput.addMessage(l, MessageListUI.NORMAL); if (l.contains("TEST OK")) { testSucceeded = true; break; diff --git a/tools/cooja/java/org/contikios/cooja/plugins/VariableWatcher.java b/tools/cooja/java/org/contikios/cooja/plugins/VariableWatcher.java index b6dc2061c..616aee0fb 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/VariableWatcher.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/VariableWatcher.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2014, TU Braunschweig. * Copyright (c) 2009, Swedish Institute of Computer Science. * All rights reserved. * @@ -32,47 +33,54 @@ package org.contikios.cooja.plugins; import java.awt.BorderLayout; import java.awt.Color; -import java.awt.Component; import java.awt.Dimension; +import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; import java.text.NumberFormat; -import java.util.Arrays; +import java.text.ParseException; +import java.util.ArrayList; import java.util.Collection; -import java.util.Vector; - +import java.util.Collections; +import java.util.List; +import javax.swing.AbstractButton; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; +import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFormattedTextField; import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; -import javax.swing.SwingUtilities; +import javax.swing.JToggleButton; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; +import javax.swing.text.DefaultFormatterFactory; +import javax.swing.text.DocumentFilter; import javax.swing.text.PlainDocument; - -import org.jdom.Element; - -import org.contikios.cooja.AddressMemory; +import org.apache.log4j.Logger; import org.contikios.cooja.ClassDescription; import org.contikios.cooja.Cooja; +import org.contikios.cooja.HasQuickHelp; import org.contikios.cooja.Mote; import org.contikios.cooja.MotePlugin; import org.contikios.cooja.PluginType; import org.contikios.cooja.Simulation; import org.contikios.cooja.VisPlugin; -import org.contikios.cooja.AddressMemory.UnknownVariableException; +import org.contikios.cooja.mote.memory.MemoryInterface; +import org.contikios.cooja.mote.memory.UnknownVariableException; +import org.contikios.cooja.mote.memory.VarMemory; +import org.jdesktop.swingx.autocomplete.AutoCompleteDecorator; +import org.jdom.Element; /** * Variable Watcher enables a user to watch mote variables during a simulation. @@ -81,41 +89,125 @@ import org.contikios.cooja.AddressMemory.UnknownVariableException; * User can also see which variables seems to be available on the selected node. * * @author Fredrik Osterlind + * @author Enrico Jorns */ @ClassDescription("Variable Watcher") @PluginType(PluginType.MOTE_PLUGIN) -public class VariableWatcher extends VisPlugin implements MotePlugin { +public class VariableWatcher extends VisPlugin implements MotePlugin, HasQuickHelp { private static final long serialVersionUID = 1L; - - private AddressMemory moteMemory; + private static final Logger logger = Logger.getLogger(VariableWatcher.class.getName()); private final static int LABEL_WIDTH = 170; private final static int LABEL_HEIGHT = 15; - private final static int BYTE_INDEX = 0; - private final static int INT_INDEX = 1; - private final static int ARRAY_INDEX = 2; - private final static int CHAR_ARRAY_INDEX = 3; - - private JPanel lengthPane; + private JComboBox varNameCombo; + private JComboBox varTypeCombo; + private JComboBox varFormatCombo; + private JPanel infoPane; + private JFormattedTextField varAddressField; + private JTextField varSizeField; private JPanel valuePane; - private JPanel charValuePane; - private JComboBox varName; - private JComboBox varType; private JFormattedTextField[] varValues; - private JTextField[] charValues; - private JFormattedTextField varLength; + private byte[] bufferedBytes; + private JButton readButton; + private AbstractButton monitorButton; private JButton writeButton; private JLabel debuglbl; - private KeyListener charValueKeyListener; - private FocusListener charValueFocusListener; - private KeyListener varValueKeyListener; - private FocusAdapter jFormattedTextFocusAdapter; + private VarMemory moteMemory; + + MemoryInterface.SegmentMonitor memMonitor; + long monitorAddr; + int monitorSize; private NumberFormat integerFormat; + private ValueFormatter hf; private Mote mote; - + + @Override + public String getQuickHelp() { + return "Variable Watcher" + + "

    Read and monitor variables or memory segments." + + "

    Use the dropdown list to select variable to read. " + + "If no size information is available size can be set manually." + + "

    To freely select the monitored region, enable address checkbox " + + "and set both address and size."; + } + + /** + * Display types for variables. + */ + public enum VarTypes { + + BYTE("byte", 1), + SHORT("short", 2), + INT("int", 2), + LONG("long", 4), + ADDR("address", 4); + + String mRep; + int mSize; + + VarTypes(String rep, int size) { + mRep = rep; + mSize = size; + } + + /** + * Returns the number of bytes for this data type. + * + * @return Size in bytes + */ + public int getBytes() { + return mSize; + } + + protected void setBytes(int size) { + mSize = size; + } + + /** + * Returns String name of this variable type. + * + * @return Type name + */ + @Override + public String toString() { + return mRep; + } + } + + /** + * Display formats for variables. + */ + public enum VarFormats { + + CHAR("Char", 0), + DEC("Decimal", 10), + HEX("Hex", 16); + + String mRep; + int mBase; + + VarFormats(String rep, int base) { + mRep = rep; + mBase = base; + } + + /** + * Returns String name of this variable representation. + * + * @return Type name + */ + @Override + public String toString() { + return mRep; + } + } + + VarFormats[] valueFormats = {VarFormats.CHAR, VarFormats.DEC, VarFormats.HEX}; + VarTypes[] valueTypes = {VarTypes.BYTE, VarTypes.SHORT, VarTypes.INT, VarTypes.LONG, VarTypes.ADDR}; + /** * @param moteToView Mote * @param simulation Simulation @@ -124,7 +216,7 @@ public class VariableWatcher extends VisPlugin implements MotePlugin { public VariableWatcher(Mote moteToView, Simulation simulation, Cooja gui) { super("Variable Watcher (" + moteToView + ")", gui); this.mote = moteToView; - moteMemory = (AddressMemory) moteToView.getMemory(); + moteMemory = new VarMemory(moteToView.getMemory()); JLabel label; integerFormat = NumberFormat.getIntegerInstance(); @@ -132,6 +224,7 @@ public class VariableWatcher extends VisPlugin implements MotePlugin { mainPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); mainPane.setLayout(new BoxLayout(mainPane, BoxLayout.Y_AXIS)); JPanel smallPane; + JPanel readPane; // Variable name smallPane = new JPanel(new BorderLayout()); @@ -139,29 +232,54 @@ public class VariableWatcher extends VisPlugin implements MotePlugin { label.setPreferredSize(new Dimension(LABEL_WIDTH,LABEL_HEIGHT)); smallPane.add(BorderLayout.WEST, label); - varName = new JComboBox(); - varName.setEditable(true); - varName.setSelectedItem("[enter or pick name]"); + List allPotentialVarNames = new ArrayList<>(moteMemory.getVariableNames()); + Collections.sort(allPotentialVarNames); - String[] allPotentialVarNames = moteMemory.getVariableNames(); - Arrays.sort(allPotentialVarNames); - for (String aVarName: allPotentialVarNames) { - varName.addItem(aVarName); + varNameCombo = new JComboBox(allPotentialVarNames.toArray()); + AutoCompleteDecorator.decorate(varNameCombo); + varNameCombo.setEditable(true); + varNameCombo.setSelectedItem(""); + + // use longest variable name as prototye for width + String longestVarname = ""; + int maxLength = 0; + for (String w : allPotentialVarNames) { + if (w.length() > maxLength) { + maxLength = w.length(); + longestVarname = w; + } } + varNameCombo.setPrototypeDisplayValue(longestVarname); - varName.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - writeButton.setEnabled(false); + varNameCombo.addPopupMenuListener(new PopupMenuListener() { + + String lastItem = ""; + + @Override + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { } - public void keyTyped(KeyEvent e) { - writeButton.setEnabled(false); + + // apply new variable name if popup is closed + @Override + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + String currentItem = (String)varNameCombo.getSelectedItem(); + + /* If item did not changed, skip! */ + if (currentItem == null || currentItem.equals(lastItem)) { + return; + } + lastItem = currentItem; + + updateBySelectedVarname(); } - public void keyReleased(KeyEvent e) { - writeButton.setEnabled(false); + + @Override + public void popupMenuCanceled(PopupMenuEvent e) { } }); + - smallPane.add(BorderLayout.EAST, varName); + smallPane.add(BorderLayout.EAST, varNameCombo); mainPane.add(smallPane); // Variable type @@ -170,77 +288,137 @@ public class VariableWatcher extends VisPlugin implements MotePlugin { label.setPreferredSize(new Dimension(LABEL_WIDTH,LABEL_HEIGHT)); smallPane.add(BorderLayout.WEST, label); - varType = new JComboBox(); - varType.addItem("Byte (1 byte)"); // BYTE_INDEX = 0 - varType.addItem("Integer (" + moteMemory.getIntegerLength() + " bytes)"); // INT_INDEX = 1 - varType.addItem("Byte array (x bytes)"); // ARRAY_INDEX = 2 - varType.addItem("Char array (x bytes)"); // CHAR_ARRAY_INDEX = 3 + /* set correct integer and address size */ + valueTypes[2].setBytes(moteToView.getMemory().getLayout().intSize); + valueTypes[4].setBytes(moteToView.getMemory().getLayout().addrSize); - varType.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - int selectedIndex = varType.getSelectedIndex(); - if (selectedIndex == ARRAY_INDEX || selectedIndex == CHAR_ARRAY_INDEX) { - lengthPane.setVisible(true); - setNumberOfValues(((Number) varLength.getValue()).intValue()); - if(selectedIndex == CHAR_ARRAY_INDEX) { - charValuePane.setVisible(true); - setNumberOfCharValues(((Number) varLength.getValue()).intValue()); - } else { - charValuePane.setVisible(false); - setNumberOfCharValues(1); - } - } else { - lengthPane.setVisible(false); - charValuePane.setVisible(false); - setNumberOfValues(1); - setNumberOfCharValues(1); + JPanel reprPanel = new JPanel(new BorderLayout()); + varTypeCombo = new JComboBox(valueTypes); + varTypeCombo.addItemListener(new ItemListener() { + + @Override + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() == ItemEvent.SELECTED) { + hf.setType((VarTypes) e.getItem()); + updateNumberOfValues(); // number of elements should have changed } - pack(); } }); - smallPane.add(BorderLayout.EAST, varType); + varFormatCombo = new JComboBox(valueFormats); + varFormatCombo.setSelectedItem(VarFormats.HEX); + varFormatCombo.addItemListener(new ItemListener() { + + @Override + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() == ItemEvent.SELECTED) { + + hf.setFormat((VarFormats) e.getItem()); + refreshValues(); // format of elements should have changed + } + } + }); + + reprPanel.add(BorderLayout.WEST, varTypeCombo); + reprPanel.add(BorderLayout.EAST, varFormatCombo); + + smallPane.add(BorderLayout.EAST, reprPanel); mainPane.add(smallPane); - /* The recommended fix for the bug #4740914 - * Synopsis : Doing selectAll() in a JFormattedTextField on focusGained - * event doesn't work. - */ - jFormattedTextFocusAdapter = new FocusAdapter() { - public void focusGained(final FocusEvent ev) { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - JTextField jtxt = (JTextField)ev.getSource(); - jtxt.selectAll(); - } - }); - } - }; + mainPane.add(Box.createRigidArea(new Dimension(0,5))); - // Variable length - lengthPane = new JPanel(new BorderLayout()); - label = new JLabel("Variable length"); - label.setPreferredSize(new Dimension(LABEL_WIDTH,LABEL_HEIGHT)); - lengthPane.add(BorderLayout.WEST, label); + infoPane = new JPanel(); + infoPane.setLayout(new BoxLayout(infoPane, BoxLayout.Y_AXIS)); - varLength = new JFormattedTextField(integerFormat); - varLength.setValue(new Integer(1)); - varLength.setColumns(4); - varLength.addPropertyChangeListener("value", new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent e) { - setNumberOfValues(((Number) varLength.getValue()).intValue()); - if(varType.getSelectedIndex() == CHAR_ARRAY_INDEX) { - setNumberOfCharValues(((Number) varLength.getValue()).intValue()); + JPanel addrInfoPane = new JPanel(); + addrInfoPane.setLayout(new BoxLayout(addrInfoPane, BoxLayout.LINE_AXIS)); + JPanel sizeInfoPane = new JPanel(); + sizeInfoPane.setLayout(new BoxLayout(sizeInfoPane, BoxLayout.LINE_AXIS)); + + label = new JLabel("Address"); + addrInfoPane.add(label); + addrInfoPane.add(Box.createHorizontalGlue()); + final JCheckBox varAddrCheckBox = new JCheckBox(); + varAddrCheckBox.addItemListener(new ItemListener() { + + @Override + public void itemStateChanged(ItemEvent e) { + if (varAddrCheckBox.isSelected()) { + varNameCombo.setEnabled(false); + varNameCombo.setEditable(false); + varAddressField.setEditable(true); + varSizeField.setEditable(true); + } else { + varNameCombo.setEnabled(true); + varNameCombo.setEditable(true); + varAddressField.setEditable(false); + varSizeField.setEditable(false); + // switch back to var name control + updateBySelectedVarname(); } } }); - varLength.addFocusListener(jFormattedTextFocusAdapter); + addrInfoPane.add(varAddrCheckBox); - lengthPane.add(BorderLayout.EAST, varLength); - mainPane.add(lengthPane); - mainPane.add(Box.createRigidArea(new Dimension(0,5))); + DefaultFormatterFactory defac = new DefaultFormatterFactory(new ValueFormatter(VarTypes.LONG, VarFormats.HEX)); + varAddressField = new JFormattedTextField(defac); + varAddressField.setValue(null); + varAddressField.setEditable(false); + varAddressField.setColumns(8); + varAddressField.setMaximumSize(varAddressField.getPreferredSize()); + /* Select all text when clicking in text field */ + varAddressField.addFocusListener(new FocusListener() { - lengthPane.setVisible(false); + @Override + public void focusGained(FocusEvent e) { + varAddressField.selectAll(); + } + + @Override + public void focusLost(FocusEvent e) { + } + }); + /* Update when content might have changed */ + varAddressField.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + updateNumberOfValues(); + } + }); + addrInfoPane.add(varAddressField); + + infoPane.add(addrInfoPane); + + label = new JLabel("Size"); + sizeInfoPane.add(label); + sizeInfoPane.add(Box.createHorizontalGlue()); + varSizeField = new JTextField("N/A"); + varSizeField.setEditable(false); + varSizeField.setColumns(8); + varSizeField.setMaximumSize(varSizeField.getPreferredSize()); + /* Select all text when clicking in text field */ + varSizeField.addFocusListener(new FocusListener() { + @Override + public void focusGained(final FocusEvent pE) { + varSizeField.selectAll(); + } + + @Override + public void focusLost(final FocusEvent pE) { + } + }); + /* Update size information when text box action fired */ + varSizeField.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + updateNumberOfValues(); + } + }); + sizeInfoPane.add(varSizeField); + + infoPane.add(sizeInfoPane); + mainPane.add(infoPane); // Variable value label label = new JLabel("Variable value"); @@ -250,346 +428,445 @@ public class VariableWatcher extends VisPlugin implements MotePlugin { // Variable value(s) valuePane = new JPanel(); - valuePane.setLayout(new BoxLayout(valuePane, BoxLayout.X_AXIS)); + valuePane.setLayout(new BoxLayout(valuePane, BoxLayout.PAGE_AXIS)); + + hf = new ValueFormatter( + (VarTypes) varTypeCombo.getSelectedItem(), + (VarFormats) varFormatCombo.getSelectedItem()); varValues = new JFormattedTextField[1]; varValues[0] = new JFormattedTextField(integerFormat); - varValues[0].setValue(new Integer(0)); + varValues[0].setValue(null); varValues[0].setColumns(3); - varValues[0].setText("?"); - - for (JFormattedTextField varValue: varValues) { - valuePane.add(varValue); - - } - charValuePane = new JPanel(); - charValuePane.setLayout(new BoxLayout(charValuePane, BoxLayout.X_AXIS)); - charValues = new JTextField[1]; - charValues[0] = new JTextField(); - charValues[0].setText("?"); - charValues[0].setColumns(1); - charValues[0].setDocument(new JTextFieldLimit(1, false)); - - /* Key Listener for char value changes. */ - charValueKeyListener = new KeyListener(){ - @Override - public void keyPressed(KeyEvent arg0) { - Component comp = arg0.getComponent(); - JTextField jtxt = (JTextField)comp; - int index = comp.getParent().getComponentZOrder(comp); - if(jtxt.getText().trim().length() != 0) { - char ch = jtxt.getText().trim().charAt(0); - varValues[index].setValue(new Integer(ch)); - } else { - varValues[index].setValue(new Integer(0)); - } - } - - @Override - public void keyReleased(KeyEvent arg0) { - Component comp = arg0.getComponent(); - JTextField jtxt = (JTextField)comp; - int index = comp.getParent().getComponentZOrder(comp); - if(jtxt.getText().trim().length() != 0) { - char ch = jtxt.getText().trim().charAt(0); - varValues[index].setValue(new Integer(ch)); - } else { - varValues[index].setValue(new Integer(0)); - } - } - - @Override - public void keyTyped(KeyEvent arg0) { - Component comp = arg0.getComponent(); - JTextField jtxt = (JTextField)comp; - int index = comp.getParent().getComponentZOrder(comp); - if(jtxt.getText().trim().length() != 0) { - char ch = jtxt.getText().trim().charAt(0); - varValues[index].setValue(new Integer(ch)); - } else { - varValues[index].setValue(new Integer(0)); - } - } - }; - - /* Key Listener for value changes. */ - varValueKeyListener = new KeyListener() { - @Override - public void keyPressed(KeyEvent arg0) { - Component comp = arg0.getComponent(); - JFormattedTextField fmtTxt = (JFormattedTextField)comp; - int index = comp.getParent().getComponentZOrder(comp); - try { - int value = Integer.parseInt(fmtTxt.getText().trim()); - char ch = (char)(0xFF & value); - charValues[index].setText(Character.toString(ch)); - } catch(Exception e) { - charValues[index].setText(Character.toString((char)0)); - } - } - - @Override - public void keyReleased(KeyEvent arg0) { - Component comp = arg0.getComponent(); - JFormattedTextField fmtTxt = (JFormattedTextField)comp; - int index = comp.getParent().getComponentZOrder(comp); - try { - int value = Integer.parseInt(fmtTxt.getText().trim()); - char ch = (char)(0xFF & value); - charValues[index].setText(Character.toString(ch)); - } catch(Exception e) { - charValues[index].setText(Character.toString((char)0)); - } - } - - @Override - public void keyTyped(KeyEvent arg0) { - Component comp = arg0.getComponent(); - JFormattedTextField fmtTxt = (JFormattedTextField)comp; - int index = comp.getParent().getComponentZOrder(comp); - try { - int value = Integer.parseInt(fmtTxt.getText().trim()); - char ch = (char)(0xFF & value); - charValues[index].setText(Character.toString(ch)); - } catch(Exception e) { - charValues[index].setText(Character.toString((char)0)); - } - } - - }; - - charValueFocusListener = new FocusListener() { - @Override - public void focusGained(FocusEvent arg0) { - JTextField jtxt = (JTextField)arg0.getComponent(); - jtxt.selectAll(); - } - @Override - public void focusLost(FocusEvent arg0) { - - } - }; - - - for (JTextField charValue: charValues) { - charValuePane.add(charValue); - } mainPane.add(valuePane); mainPane.add(Box.createRigidArea(new Dimension(0,5))); - charValuePane.setVisible(false); - mainPane.add(charValuePane); - mainPane.add(Box.createRigidArea(new Dimension(0,5))); debuglbl = new JLabel(); mainPane.add(new JPanel().add(debuglbl)); mainPane.add(Box.createRigidArea(new Dimension(0,5))); - // Read/write buttons smallPane = new JPanel(new BorderLayout()); - JButton button = new JButton("Read"); - button.addActionListener(new ActionListener() { + readPane = new JPanel(new BorderLayout()); + + /* Read button */ + readButton = new JButton("Read"); + readButton.addActionListener(new ActionListener() { + + @Override public void actionPerformed(ActionEvent e) { - if (varType.getSelectedIndex() == BYTE_INDEX) { - try { - byte val = moteMemory.getByteValueOf((String) varName.getSelectedItem()); - varValues[0].setValue(new Integer(0xFF & val)); - varName.setBackground(Color.WHITE); - writeButton.setEnabled(true); - } catch (UnknownVariableException ex) { - varName.setBackground(Color.RED); - writeButton.setEnabled(false); - } - } else if (varType.getSelectedIndex() == INT_INDEX) { - try { - int val = moteMemory.getIntValueOf((String) varName.getSelectedItem()); - varValues[0].setValue(new Integer(val)); - varName.setBackground(Color.WHITE); - writeButton.setEnabled(true); - } catch (UnknownVariableException ex) { - varName.setBackground(Color.RED); - writeButton.setEnabled(false); - } - } else if (varType.getSelectedIndex() == ARRAY_INDEX || - varType.getSelectedIndex() == CHAR_ARRAY_INDEX) { - try { - int length = ((Number) varLength.getValue()).intValue(); - byte[] vals = moteMemory.getByteArray((String) varName.getSelectedItem(), length); - for (int i=0; i < length; i++) { - varValues[i].setValue(new Integer(0xFF & vals[i])); - } - if(varType.getSelectedIndex() == CHAR_ARRAY_INDEX) { - for (int i=0; i < length; i++) { - char ch = (char)(0xFF & vals[i]); - charValues[i].setText(Character.toString(ch)); - varValues[i].addKeyListener(varValueKeyListener); - } - } - varName.setBackground(Color.WHITE); - writeButton.setEnabled(true); - } catch (UnknownVariableException ex) { - varName.setBackground(Color.RED); - writeButton.setEnabled(false); - } + if (!moteMemory.variableExists((String) varNameCombo.getSelectedItem())) { + ((JTextField) varNameCombo.getEditor().getEditorComponent()).setForeground(Color.RED); + writeButton.setEnabled(false); + return; + } + + try { + writeButton.setEnabled(true); + bufferedBytes = moteMemory.getByteArray( + (long) varAddressField.getValue(), + Integer.decode(varSizeField.getText())); + refreshValues(); + } catch (MemoryInterface.MoteMemoryException ex) { + JOptionPane.showMessageDialog(varNameCombo, ex.getMessage(), "MoteMemoryException", JOptionPane.ERROR_MESSAGE); } } }); - smallPane.add(BorderLayout.WEST, button); - button = new JButton("Write"); - button.addActionListener(new ActionListener() { + readPane.add(BorderLayout.WEST, readButton); + + /* MemoryMonitor required for monitor button */ + + /* Monitor button */ + monitorButton = new JToggleButton("Monitor"); + monitorButton.addActionListener(new ActionListener() { + + @Override public void actionPerformed(ActionEvent e) { - if (varType.getSelectedIndex() == BYTE_INDEX) { - try { - byte val = (byte) ((Number) varValues[0].getValue()).intValue(); - moteMemory.setByteValueOf((String) varName.getSelectedItem(), val); - varName.setBackground(Color.WHITE); - } catch (UnknownVariableException ex) { - varName.setBackground(Color.RED); - } - } else if (varType.getSelectedIndex() == INT_INDEX) { - try { - int val = ((Number) varValues[0].getValue()).intValue(); - moteMemory.setIntValueOf((String) varName.getSelectedItem(), val); - varName.setBackground(Color.WHITE); - } catch (UnknownVariableException ex) { - varName.setBackground(Color.RED); - } - } else if (varType.getSelectedIndex() == ARRAY_INDEX || - varType.getSelectedIndex() == CHAR_ARRAY_INDEX) { - try { - int length = ((Number) varLength.getValue()).intValue(); - byte[] vals = new byte[length]; - for (int i=0; i < length; i++) { - vals[i] = (byte) ((Number) varValues[i].getValue()).intValue(); - } - moteMemory.setByteArray((String) varName.getSelectedItem(), vals); - varName.setBackground(Color.WHITE); - writeButton.setEnabled(true); - } catch (UnknownVariableException ex) { - varName.setBackground(Color.RED); - writeButton.setEnabled(false); + // deselect + if (!((JToggleButton) e.getSource()).isSelected()) { + //System.out.println("Removing monitor " + memMonitor + " for addr " + monitorAddr + ", size " + monitorSize + ""); + mote.getMemory().removeSegmentMonitor( + (long) varAddressField.getValue(), + Integer.decode(varSizeField.getText()), + memMonitor); + varAddrCheckBox.setEnabled(true); + readButton.setEnabled(true); + writeButton.setEnabled(true); + varAddressField.setEnabled(true); + varSizeField.setEnabled(true); + if (!varAddrCheckBox.isSelected()) { + varNameCombo.setEnabled(true); } + return; } + + /* initial readout so we have a value to display */ + try { + bufferedBytes = moteMemory.getByteArray( + (long) varAddressField.getValue(), + Integer.decode(varSizeField.getText())); + refreshValues(); + } catch (MemoryInterface.MoteMemoryException ex) { + JOptionPane.showMessageDialog(varNameCombo, ex.getMessage(), "MoteMemoryException", JOptionPane.ERROR_MESSAGE); + monitorButton.setSelected(false); + return; + } + + memMonitor = new MemoryInterface.SegmentMonitor() { + + @Override + public void memoryChanged(MemoryInterface memory, EventType type, long address) { + bufferedBytes = moteMemory.getByteArray( + (long) varAddressField.getValue(), + Integer.decode(varSizeField.getText())); + + refreshValues(); + } + }; + //System.out.println("Adding monitor " + memMonitor + " for addr " + monitorAddr + ", size " + monitorSize + ""); + mote.getMemory().addSegmentMonitor( + MemoryInterface.SegmentMonitor.EventType.WRITE, + (long) varAddressField.getValue(), + Integer.decode(varSizeField.getText()), + memMonitor); + + /* During monitoring we neither allow writes nor to change variable */ + varAddrCheckBox.setEnabled(false); + readButton.setEnabled(false); + writeButton.setEnabled(false); + varAddressField.setEnabled(false); + varSizeField.setEnabled(false); + varNameCombo.setEnabled(false); } }); - smallPane.add(BorderLayout.EAST, button); - button.setEnabled(false); - writeButton = button; + + readPane.add(BorderLayout.EAST, monitorButton); + smallPane.add(BorderLayout.WEST, readPane); + + /* Write button */ + writeButton = new JButton("Write"); + writeButton.setEnabled(false); + writeButton.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + + /* Convert from input field to byte array */ + int bytes = ((VarTypes) varTypeCombo.getSelectedItem()).getBytes(); + for (int element = 0; element < varValues.length; element++) { + for (int b = 0; b < bytes; b++) { + if (element * bytes + b > bufferedBytes.length - 1) { + break; + } + bufferedBytes[element * bytes + b] = (byte) ((((int) varValues[element].getValue()) >> (b * 8)) & 0xFF); + } + } + /* Write to memory */ + moteMemory.setByteArray((long) varAddressField.getValue(), bufferedBytes); + } + }); + + smallPane.add(BorderLayout.EAST, writeButton); mainPane.add(smallPane); add(BorderLayout.NORTH, mainPane); pack(); } - private void setNumberOfValues(int nr) { + private void updateBySelectedVarname() { + try { + String currentItem = (String) varNameCombo.getSelectedItem(); + /* invalidate byte field */ + bufferedBytes = null; + /* calculate number of elements required to show the value in the given size */ + varAddressField.setValue(moteMemory.getVariableAddress(currentItem)); + int size = moteMemory.getVariableSize(currentItem); + /* Disable buttons if variable reported size < 1, activate otherwise */ + if (size < 1) { + varSizeField.setText("N/A"); + varSizeField.setEditable(true); + } else { + varSizeField.setText(String.valueOf(size)); + varSizeField.setEditable(false); + } + updateNumberOfValues(); + } catch (UnknownVariableException ex) { + ((JTextField) varNameCombo.getEditor().getEditorComponent()).setForeground(Color.RED); + writeButton.setEnabled(false); + } + } + + /** + * String to Value to String conversion for JFormattedTextField + * based on selected VarTypes and VarFormats. + */ + public class ValueFormatter extends JFormattedTextField.AbstractFormatter { + + final String TEXT_NOT_TO_TOUCH; + + private VarTypes mType; + private VarFormats mFormat; + + public ValueFormatter(VarTypes type, VarFormats format) { + mType = type; + mFormat = format; + if (mFormat == VarFormats.HEX) { + TEXT_NOT_TO_TOUCH = "0x"; + } + else { + TEXT_NOT_TO_TOUCH = ""; + } + } + + public void setType(VarTypes type) { + mType = type; + } + + public void setFormat(VarFormats format) { + mFormat = format; + } + + @Override + public Object stringToValue(String text) throws ParseException { + Object ret; + switch (mFormat) { + case CHAR: + ret = text.charAt(0); + break; + case DEC: + case HEX: + try { + switch (mType) { + case BYTE: + case SHORT: + ret = Integer.decode(text); + break; + case INT: + case LONG: + case ADDR: + ret = Long.decode(text); + break; + default: + ret = null; + } + } + catch (NumberFormatException ex) { + ret = 0; + } + break; + default: + ret = null; + } + return ret; + } + + @Override + public String valueToString(Object value) throws ParseException { + if (value == null) { + return "N/A"; + } + + switch (mFormat) { + case CHAR: + return String.format("%c", value); + case DEC: + return String.format("%d", value); + case HEX: + return String.format("0x%x", value); + default: + return ""; + } + } + + /* Do not override TEXT_NOT_TO_TOUCH */ + @Override + public DocumentFilter getDocumentFilter() { + /** @todo: There seem to be some remaining issues regarding input handling */ + return new DocumentFilter() { + + @Override + public void insertString(DocumentFilter.FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException { + if (offset < TEXT_NOT_TO_TOUCH.length()) { + return; + } + super.insertString(fb, offset, string, attr); + } + + @Override + public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { + if (offset < TEXT_NOT_TO_TOUCH.length()) { + length = Math.max(0, length - TEXT_NOT_TO_TOUCH.length()); + offset = TEXT_NOT_TO_TOUCH.length(); + } + super.replace(fb, offset, length, text, attrs); + } + + @Override + public void remove(DocumentFilter.FilterBypass fb, int offset, int length) throws BadLocationException { + if (offset < TEXT_NOT_TO_TOUCH.length()) { + length = Math.max(0, length + offset - TEXT_NOT_TO_TOUCH.length()); + offset = TEXT_NOT_TO_TOUCH.length(); + } + if (length > 0) { + super.remove(fb, offset, length); + } + } + }; + } + } + + + /** + * Updates all value fields based on buffered data. + * + * @note Does not read memory. Leaves number of fields unchanged. + */ + private void refreshValues() { + + int bytes = Integer.decode(varSizeField.getText()); + int typeSize = ((VarTypes) varTypeCombo.getSelectedItem()).getBytes(); + int elements = (int) Math.ceil((double) bytes / typeSize); + + /* Skip if we have no data to set */ + if ((bufferedBytes == null) || (bufferedBytes.length < bytes)) { + return; + } + + /* Set values based on buffered data */ + for (int i = 0; i < elements; i += 1) { + int val = 0; + for (int j = 0; j < typeSize; j++) { + /* skip if we do note have more bytes do consume. + This may happen e.g. if we display long (4 bytes) but have only 3 bytes */ + if (i * typeSize + j > bufferedBytes.length - 1) { + break; + } + val += ((bufferedBytes[i * typeSize + j] & 0xFF) << (j * 8)); + } + varValues[i].setValue(val); + try { + varValues[i].commitEdit(); + } + catch (ParseException ex) { + logger.error(ex); + } + } + + } + + /** + * Updates the number of value fields. + */ + private void updateNumberOfValues() { + valuePane.removeAll(); - if (nr > 0) { - varValues = new JFormattedTextField[nr]; - for (int i=0; i < nr; i++) { - varValues[i] = new JFormattedTextField(integerFormat); - varValues[i] .setValue(new Integer(0)); - varValues[i] .setColumns(3); - varValues[i] .setText("?"); - varValues[i].addFocusListener(jFormattedTextFocusAdapter); - valuePane.add(varValues[i]); + JPanel linePane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); + + DefaultFormatterFactory defac = new DefaultFormatterFactory(hf); + long address = (varAddressField.getValue() == null) ? 0 : (long) varAddressField.getValue(); + int bytes; + try { + //address = Integer.parseInt(varAddressField.getText()); + bytes = Integer.parseInt(varSizeField.getText()); + } catch (NumberFormatException ex) { + bytes = 0; + } + + int typeSize = ((VarTypes) varTypeCombo.getSelectedItem()).getBytes(); + int elements = (int) Math.ceil((double) bytes / typeSize); + + /* If no/unknown size: disable buttons and abort */ + if (elements == 0) { + readButton.setEnabled(false); + monitorButton.setEnabled(false); + writeButton.setEnabled(false); + return; + } + + varValues = new JFormattedTextField[elements]; + for (int i = 0; i < elements; i++) { + varValues[i] = new JFormattedTextField(defac); + varValues[i].setColumns(((VarTypes) varTypeCombo.getSelectedItem()).getBytes() * 2 + 2); + varValues[i].setToolTipText(String.format("0x%04x", address + i * typeSize)); + linePane.add(varValues[i]); + /* After 8 Elements, break line */ + if ((i + 1) % 8 == 0) { + valuePane.add(linePane); + linePane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); } } + valuePane.add(linePane); + + readButton.setEnabled(true); + monitorButton.setEnabled(true); + writeButton.setEnabled(true); + + refreshValues(); + pack(); - } - - private void setNumberOfCharValues(int nr) { - charValuePane.removeAll(); - - if (nr > 0) { - charValues = new JTextField[nr]; - for (int i=0; i < nr; i++) { - charValues[i] = new JTextField(); - charValues[i] .setColumns(1); - charValues[i] .setText("?"); - charValues[i].setDocument(new JTextFieldLimit(1, false)); - charValues[i].addKeyListener(charValueKeyListener); - charValues[i].addFocusListener(charValueFocusListener); - charValuePane.add(charValues[i]); - } + + /* Assure we do not loose the window due to placement outside desktop */ + if (getX() < 0) { + setLocation(0, getY()); } - pack(); } + @Override public void closePlugin() { + /* Make sure to release monitor */ + if (monitorButton.isSelected()) { + monitorButton.doClick(); + } } + @Override public Collection getConfigXML() { // Return currently watched variable and type - Vector config = new Vector(); + List config = new ArrayList<>(); Element element; // Selected variable name element = new Element("varname"); - element.setText((String) varName.getSelectedItem()); + element.setText((String) varNameCombo.getSelectedItem()); config.add(element); // Selected variable type - if (varType.getSelectedIndex() == BYTE_INDEX) { - element = new Element("vartype"); - element.setText("byte"); - config.add(element); - } else if (varType.getSelectedIndex() == INT_INDEX) { - element = new Element("vartype"); - element.setText("int"); - config.add(element); - } else if (varType.getSelectedIndex() == ARRAY_INDEX) { - element = new Element("vartype"); - element.setText("array"); - config.add(element); - element = new Element("array_length"); - element.setText(varLength.getValue().toString()); - config.add(element); - } else if (varType.getSelectedIndex() == CHAR_ARRAY_INDEX) { - element = new Element("vartype"); - element.setText("chararray"); - config.add(element); - element = new Element("array_length"); - element.setText(varLength.getValue().toString()); - config.add(element); - } - + element = new Element("vartype"); + element.setText(String.valueOf(varTypeCombo.getSelectedIndex())); + config.add(element); + + // Selected output format + element = new Element("varformat"); + element.setText(String.valueOf(varFormatCombo.getSelectedIndex())); + config.add(element); return config; } + @Override public boolean setConfigXML(Collection configXML, boolean visAvailable) { - lengthPane.setVisible(false); - setNumberOfValues(1); - varLength.setValue(1); - for (Element element : configXML) { - if (element.getName().equals("varname")) { - varName.setSelectedItem(element.getText()); - } else if (element.getName().equals("vartype")) { - if (element.getText().equals("byte")) { - varType.setSelectedIndex(BYTE_INDEX); - } else if (element.getText().equals("int")) { - varType.setSelectedIndex(INT_INDEX); - } else if (element.getText().equals("array")) { - varType.setSelectedIndex(ARRAY_INDEX); - lengthPane.setVisible(true); - } else if (element.getText().equals("chararray")) { - varType.setSelectedIndex(CHAR_ARRAY_INDEX); - lengthPane.setVisible(true); - } - } else if (element.getName().equals("array_length")) { - int nrValues = Integer.parseInt(element.getText()); - setNumberOfValues(nrValues); - varLength.setValue(nrValues); + switch (element.getName()) { + case "varname": + varNameCombo.setSelectedItem(element.getText()); + break; + case "vartype": + varTypeCombo.setSelectedIndex(Integer.parseInt(element.getText())); + break; + case "varformat": + varFormatCombo.setSelectedIndex(Integer.parseInt(element.getText())); + break; } } + updateNumberOfValues(); return true; } + @Override public Mote getMote() { return mote; } @@ -614,6 +891,7 @@ class JTextFieldLimit extends PlainDocument { toUppercase = upper; } + @Override public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException { if (str == null) { diff --git a/tools/cooja/java/org/contikios/cooja/plugins/Visualizer.java b/tools/cooja/java/org/contikios/cooja/plugins/Visualizer.java index 733bafa6f..56b20097b 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/Visualizer.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/Visualizer.java @@ -67,6 +67,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -87,6 +88,7 @@ import javax.swing.KeyStroke; import javax.swing.MenuElement; import javax.swing.SwingUtilities; import javax.swing.Timer; +import javax.swing.ToolTipManager; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; import javax.swing.plaf.basic.BasicInternalFrameUI; @@ -160,12 +162,16 @@ public class Visualizer extends VisPlugin implements HasQuickHelp { private static final int MOVE_MASK = Event.SHIFT_MASK; enum MotesActionState { - - UNKNWON, + NONE, + // press to select mote SELECT_PRESS, + // press DEFAULT_PRESS, + // press to start panning PAN_PRESS, + // panning the viewport PANNING, + // moving a mote MOVING, // rectangular select SELECTING @@ -176,7 +182,7 @@ public class Visualizer extends VisPlugin implements HasQuickHelp { /* Mote that was under curser while mouse press */ Mote cursorMote; - MotesActionState mouseActionState = MotesActionState.UNKNWON; + MotesActionState mouseActionState = MotesActionState.NONE; /* Position where mouse button was pressed */ Position pressedPos; @@ -319,6 +325,10 @@ public class Visualizer extends VisPlugin implements HasQuickHelp { canvas = new JPanel() { private static final long serialVersionUID = 1L; + { + ToolTipManager.sharedInstance().registerComponent(this); + } + @Override public void paintComponent(Graphics g) { super.paintComponent(g); @@ -338,6 +348,35 @@ public class Visualizer extends VisPlugin implements HasQuickHelp { } selection.drawSelection(g); } + + @Override + public String getToolTipText(MouseEvent event) { + Mote[] motes = findMotesAtPosition(event.getX(), event.getY()); + if (motes == null) { + return null; + } + File file = motes[0].getType().getContikiSourceFile(); + if (file == null) { + file = motes[0].getType().getContikiFirmwareFile(); + } + String fileName; + if (file == null) { + fileName = ""; + } else { + fileName = file.getName(); + } + StringBuilder sb = new StringBuilder() + .append("

    Identifier") - .append(getIdentifier()).append("
    Description") - .append(getDescription()).append("
    Contiki application") - .append(getContikiSourceFile().getAbsolutePath()).append("
    Contiki firmware") - .append(getContikiFirmwareFile().getAbsolutePath()).append("
    JNI library") - .append(this.javaClassName).append("
    Contiki sensors"); - for (String sensor: sensors) { + for (String sensor : sensors) { sb.append(sensor).append("
    "); } sb.append("
    Mote interface"); - for (Class moteInterface: moteInterfacesClasses) { + for (Class moteInterface : moteInterfacesClasses) { sb.append(moteInterface.getSimpleName()).append("
    "); } sb.append("
    Contiki's mote interface"); - for (String coreInterface: getCoreInterfaces()) { + for (String coreInterface : getCoreInterfaces()) { sb.append(coreInterface).append("
    "); } sb.append("
    ") + .append("") + .append("") + .append("
    Type:") + .append(motes[0].getType().getIdentifier()) + .append("
    Runs:") + .append(fileName) + .append("
    "); + return sb.toString(); + } + }; canvas.setBackground(Color.WHITE); viewportTransform = new AffineTransform(); @@ -427,12 +466,51 @@ public class Visualizer extends VisPlugin implements HasQuickHelp { } }); + canvas.getInputMap().put(KeyStroke.getKeyStroke("ESCAPE"), "abort_action"); + canvas.getInputMap().put(KeyStroke.getKeyStroke("DELETE"), "delete_motes"); + + canvas.getActionMap().put("abort_action", new AbstractAction() { + + @Override + public void actionPerformed(ActionEvent e) { + if (mouseActionState == MotesActionState.MOVING) { + /* Reset positions to those of move start */ + for (Mote m : Visualizer.this.getSelectedMotes()) { + double rstPos[] = Visualizer.this.moveStartPositions.get(m); + m.getInterfaces().getPosition().setCoordinates(rstPos[0], rstPos[1], rstPos[2]); + } + mouseActionState = MotesActionState.NONE; + } + /* Always deselect all */ + Visualizer.this.getSelectedMotes().clear(); + repaint(); + } + }); + + canvas.getActionMap().put("delete_motes", new AbstractAction() { + + @Override + public void actionPerformed(ActionEvent e) { + Iterator iter = Visualizer.this.getSelectedMotes().iterator(); + while (iter.hasNext()) { + Mote m = iter.next(); + m.getSimulation().removeMote(m); + iter.remove(); + } + } + }); + /* Popup menu */ canvas.addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseDragged(MouseEvent e) { handleMouseDrag(e, false); } + + @Override + public void mouseMoved(MouseEvent e) { + handleMouseDrag(e, false); + } }); canvas.addMouseListener(new MouseAdapter() { @Override @@ -477,10 +555,11 @@ public class Visualizer extends VisPlugin implements HasQuickHelp { }); /* Register mote menu actions */ - registerMoteMenuAction(MoveMoteMenuAction.class); registerMoteMenuAction(ButtonClickMoteMenuAction.class); registerMoteMenuAction(ShowLEDMoteMenuAction.class); registerMoteMenuAction(ShowSerialMoteMenuAction.class); + + registerMoteMenuAction(MoveMoteMenuAction.class); registerMoteMenuAction(DeleteMoteMenuAction.class); /* Register simulation menu actions */ @@ -889,6 +968,11 @@ public class Visualizer extends VisPlugin implements HasQuickHelp { pressedPos = transformPixelToPosition(mouseEvent.getPoint()); + // if we are in moving, we ignore the press (rest is handled by release) + if (mouseActionState == MotesActionState.MOVING) { + return; + } + // this is the state we have from pressing button final Mote[] foundMotes = findMotesAtPosition(x, y); if (foundMotes == null) { @@ -937,6 +1021,7 @@ public class Visualizer extends VisPlugin implements HasQuickHelp { mouseActionState = MotesActionState.PANNING; } else { + /* If we start moving with on a cursor mote, switch to MOVING */ mouseActionState = MotesActionState.MOVING; // save start position for (Mote m : selectedMotes) { @@ -1037,20 +1122,33 @@ public class Visualizer extends VisPlugin implements HasQuickHelp { repaint(); break; } + /* Release always stops previous actions */ + mouseActionState = MotesActionState.NONE; + canvas.setCursor(Cursor.getDefaultCursor()); repaint(); } - private void beginMoveRequest(Mote motesToMove, boolean withTiming, boolean confirm) { + private void beginMoveRequest(Mote selectedMote, boolean withTiming, boolean confirm) { if (withTiming) { moveStartTime = System.currentTimeMillis(); } else { moveStartTime = -1; } - mouseActionState = MotesActionState.DEFAULT_PRESS; - selectedMotes.clear(); - selectedMotes.add(motesToMove); - repaint(); + /* Save start positions and set move-start position to clicked mote */ + for (Mote m : selectedMotes) { + Position pos = m.getInterfaces().getPosition(); + moveStartPositions.put(m, new double[]{ + pos.getXCoordinate(), + pos.getYCoordinate(), + pos.getZCoordinate()}); + } + pressedPos.setCoordinates( + selectedMote.getInterfaces().getPosition().getXCoordinate(), + selectedMote.getInterfaces().getPosition().getYCoordinate(), + selectedMote.getInterfaces().getPosition().getZCoordinate()); + + mouseActionState = MotesActionState.MOVING; } private double zoomFactor() { @@ -1209,9 +1307,22 @@ public class Visualizer extends VisPlugin implements HasQuickHelp { 2 * MOTE_RADIUS); } - g.setColor(Color.BLACK); - g.drawOval(x - MOTE_RADIUS, y - MOTE_RADIUS, 2 * MOTE_RADIUS, - 2 * MOTE_RADIUS); + if (getSelectedMotes().contains(mote)) { + /* If mote is selected, highlight with red circle + and semitransparent gray overlay */ + g.setColor(new Color(51, 102, 255)); + g.drawOval(x - MOTE_RADIUS, y - MOTE_RADIUS, 2 * MOTE_RADIUS, + 2 * MOTE_RADIUS); + g.drawOval(x - MOTE_RADIUS - 1, y - MOTE_RADIUS - 1, 2 * MOTE_RADIUS + 2, + 2 * MOTE_RADIUS + 2); + g.setColor(new Color(128, 128, 128, 128)); + g.fillOval(x - MOTE_RADIUS, y - MOTE_RADIUS, 2 * MOTE_RADIUS, + 2 * MOTE_RADIUS); + } else { + g.setColor(Color.BLACK); + g.drawOval(x - MOTE_RADIUS, y - MOTE_RADIUS, 2 * MOTE_RADIUS, + 2 * MOTE_RADIUS); + } } } @@ -1571,12 +1682,25 @@ public class Visualizer extends VisPlugin implements HasQuickHelp { @Override public String getDescription(Visualizer visualizer, Mote mote) { - return "Delete " + mote; + if (visualizer.getSelectedMotes().contains(mote) && visualizer.getSelectedMotes().size() > 1) { + return "Delete selected Motes"; + } else { + return "Delete " + mote; + } } @Override public void doAction(Visualizer visualizer, Mote mote) { - mote.getSimulation().removeMote(mote); + + /* If the currently clicked mote is not in the current mote selection, + * select it exclusively */ + if (!visualizer.getSelectedMotes().contains(mote)) { + visualizer.getSelectedMotes().clear(); + visualizer.getSelectedMotes().add(mote); + } + + /* Invoke 'delete_motes' action */ + visualizer.canvas.getActionMap().get("delete_motes").actionPerformed(null); } }; @@ -1675,11 +1799,21 @@ public class Visualizer extends VisPlugin implements HasQuickHelp { @Override public String getDescription(Visualizer visualizer, Mote mote) { - return "Move " + mote; + if (visualizer.getSelectedMotes().contains(mote) && visualizer.getSelectedMotes().size() > 1) { + return "Move selected Motes"; + } else { + return "Move " + mote; + } } @Override public void doAction(Visualizer visualizer, Mote mote) { + /* If the currently clicked mote is note in the current mote selection, + * select it exclusively */ + if (!visualizer.getSelectedMotes().contains(mote)) { + visualizer.getSelectedMotes().clear(); + visualizer.getSelectedMotes().add(mote); + } visualizer.beginMoveRequest(mote, false, false); } }; diff --git a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/FragHeadPacketAnalyzer.java b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/FragHeadPacketAnalyzer.java new file mode 100644 index 000000000..07d530a62 --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/FragHeadPacketAnalyzer.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014, TU Braunschweig + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +package org.contikios.cooja.plugins.analyzers; + +/** + * Analyzes the fragmentation header if present. + * + * @author Enrico Jorns + */ +public class FragHeadPacketAnalyzer extends PacketAnalyzer { + + public final static int SICSLOWPAN_DISPATCH_FRAG1 = 0xc0; /* 1100 0xxx */ + + public final static int SICSLOWPAN_DISPATCH_FRAGN = 0xe0; /* 1110 0xxx */ + + @Override + public boolean matchPacket(Packet packet) { + return packet.level == NETWORK_LEVEL && (packet.get(0) & 0xD8) == SICSLOWPAN_DISPATCH_FRAG1; + } + + @Override + public int analyzePacket(Packet packet, StringBuilder brief, StringBuilder verbose) { + int hdr_size = 0; + + verbose.append("Frag Header "); + + if ((packet.get(0) & 0xF8) == SICSLOWPAN_DISPATCH_FRAG1) { + hdr_size = 4; + brief.append("FRAG1"); + verbose.append("first
    "); + } else if ((packet.get(0) & 0xF8) == SICSLOWPAN_DISPATCH_FRAGN) { + hdr_size = 5; + brief.append("FRAGN"); + verbose.append("nth
    "); + } + + int datagram_size = ((packet.get(0) & 0x07) << 8) + packet.get(1); + int datagram_tag = packet.getInt(2, 2); + + verbose.append("size = ").append(datagram_size) + .append(", tag = ").append(String.format("0x%04x", datagram_tag)); + + if (hdr_size == 5) { + verbose.append(", offset = ").append(packet.get(4) * 8); + } + + packet.pos += hdr_size; + + return ANALYSIS_OK_CONTINUE; + } + +} diff --git a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/ICMPv6Analyzer.java b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/ICMPv6Analyzer.java index a8ea5e8b0..29ea423c8 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/ICMPv6Analyzer.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/ICMPv6Analyzer.java @@ -2,99 +2,110 @@ package org.contikios.cooja.plugins.analyzers; public class ICMPv6Analyzer extends PacketAnalyzer { - public static final byte ICMPv6_DISPATCH = 58; - - public static final int ECHO_REQUEST = 128; - public static final int ECHO_REPLY = 129; - public static final int GROUP_QUERY = 130; - public static final int GROUP_REPORT = 131; - public static final int GROUP_REDUCTION = 132; - public static final int ROUTER_SOLICITATION = 133; - public static final int ROUTER_ADVERTISEMENT = 134; - public static final int NEIGHBOR_SOLICITATION = 135; - public static final int NEIGHBOR_ADVERTISEMENT = 136; + public static final byte ICMPv6_DISPATCH = 58; - public static final int RPL_CODE_DIS = 0; /* DIS message */ - public static final int RPL_CODE_DIO = 1; /* DIO message */ - public static final int RPL_CODE_DAO = 2;/* DAO message */ - public static final int RPL_CODE_DAO_ACK = 3;/* DAO ACK message */ - - public static final int FLAG_ROUTER = 0x80; - public static final int FLAG_SOLICITED = 0x40; - public static final int FLAG_OVERRIDE = 0x20; + public static final int ECHO_REQUEST = 128; + public static final int ECHO_REPLY = 129; + public static final int GROUP_QUERY = 130; + public static final int GROUP_REPORT = 131; + public static final int GROUP_REDUCTION = 132; + public static final int ROUTER_SOLICITATION = 133; + public static final int ROUTER_ADVERTISEMENT = 134; + public static final int NEIGHBOR_SOLICITATION = 135; + public static final int NEIGHBOR_ADVERTISEMENT = 136; - public static final int ON_LINK = 0x80; - public static final int AUTOCONFIG = 0x40; + public static final int RPL_CODE_DIS = 0; /* DIS message */ + public static final int RPL_CODE_DIO = 1; /* DIO message */ + public static final int RPL_CODE_DAO = 2;/* DAO message */ + public static final int RPL_CODE_DAO_ACK = 3;/* DAO ACK message */ - public static final int SOURCE_LINKADDR = 1; - public static final int TARGET_LINKADDR = 2; - public static final int PREFIX_INFO = 3; - public static final int MTU_INFO = 5; - - public static final String[] TYPE_NAME = new String[] { - "ECHO_REQUEST", "ECHO_REPLY", - "GROUP_QUERY", "GROUP_REPORT", "GROUP_REDUCTION", - "ROUTER_SOLICITATION", "ROUTER_ADVERTISEMENT", - "NEIGHBOR_SOLICITATION", "NEIGHBOR_ADVERTISEMENT", "REDIRECT", - "ROUTER RENUMBER", "NODE INFORMATION QUERY", "NODE INFORMATION RESPONSE"}; + public static final int FLAG_ROUTER = 0x80; + public static final int FLAG_SOLICITED = 0x40; + public static final int FLAG_OVERRIDE = 0x20; - - public int analyzePacket(Packet packet, StringBuffer brief, - StringBuffer verbose) { - int type = packet.get(0) & 0xff; - int code = packet.get(1) & 0xff; + public static final int ON_LINK = 0x80; + public static final int AUTOCONFIG = 0x40; + + public static final int SOURCE_LINKADDR = 1; + public static final int TARGET_LINKADDR = 2; + public static final int PREFIX_INFO = 3; + public static final int MTU_INFO = 5; + + public static final String[] TYPE_NAME = new String[]{ + "Echo Request", "Echo Reply", + "Group Query", "Group Report", "Group Reduction", + "Router Solicitation", "Router Advertisement", + "Neighbor Solicitation", "Neighbor Advertisement", "Redirect", + "Router Renumber", "Node Information Query", "Node Information Response"}; + + public static final String[] BRIEF_TYPE_NAME = new String[]{ + "ECHO REQ", "ECHO RPLY", + "GRP QUERY", "GRP REPORT", "GRP REDUCTION", + "RS", "RA", + "NS", "NA", "REDIRECT", + "ROUTER RENUMBER", "NODE INFO QUERY", "NODE INFO RESP"}; + + @Override + public int analyzePacket(Packet packet, StringBuilder brief, + StringBuilder verbose) { + int type = packet.get(0) & 0xff; + int code = packet.get(1) & 0xff; // int checksum = ((packet.get(2) & 0xff) << 8) | packet.get(3) & 0xff; - brief.append("ICMPv6 "); - if (type >= 128 && (type - 128) < TYPE_NAME.length) { - brief.append(TYPE_NAME[type - 128]).append(' ').append(code); - verbose.append("Type: ").append(TYPE_NAME[type - 128]); - verbose.append(" Code:").append(code); - } else if (type == 155) { - /* RPL */ - brief.append("RPL "); - verbose.append("Type: RPL Code: "); - switch(code) { - case RPL_CODE_DIS: - brief.append("DIS"); - verbose.append("DIS"); - break; - case RPL_CODE_DIO: - brief.append("DIO"); - verbose.append("DIO
    "); - - int instanceID = packet.get(4) & 0xff; - int version = packet.get(5) & 0xff; - int rank = ((packet.get(6) & 0xff) << 8) + (packet.get(7) & 0xff); - int mop = (packet.get(8) >> 3) & 0x07; - int dtsn = packet.get(9); - - verbose.append(" InstanceID: " + instanceID + " Version: " + version + - " Rank:" + rank + " MOP: " + mop + " DTSN: " + dtsn); - packet.consumeBytesStart(8); + brief.append("ICMPv6 "); + verbose.append("ICMPv6"); + if (type >= 128 && (type - 128) < TYPE_NAME.length) { + brief.append(BRIEF_TYPE_NAME[type - 128]).append(' ').append(code); + verbose.append("
    Type: ").append(TYPE_NAME[type - 128]); + verbose.append(", Code:").append(code); + } else if (type == 155) { + /* RPL */ + brief.append("RPL "); + verbose.append("
    Type: RPL Code: "); + switch (code) { + case RPL_CODE_DIS: + brief.append("DIS"); + verbose.append("DIS"); + break; + case RPL_CODE_DIO: + brief.append("DIO"); + verbose.append("DIO
    "); - break; - case RPL_CODE_DAO: - brief.append("DAO"); - verbose.append("DAO"); - break; - case RPL_CODE_DAO_ACK: - brief.append("DAO ACK"); - verbose.append("DAO ACK"); - break; - default: - brief.append(code); - verbose.append(code); - } - } + int instanceID = packet.get(4) & 0xff; + int version = packet.get(5) & 0xff; + int rank = ((packet.get(6) & 0xff) << 8) + (packet.get(7) & 0xff); + int mop = (packet.get(8) >> 3) & 0x07; + int dtsn = packet.get(9) & 0xFF; - /* remove type, code, crc */ - packet.consumeBytesStart(4); - return ANALYSIS_OK_FINAL; + verbose.append(" InstanceID: ").append(instanceID) + .append(", Version: ").append(version) + .append(", Rank: ").append(rank) + .append(", MOP: ").append(mop) + .append(", DTSN: ").append(dtsn); + packet.consumeBytesStart(8); + + break; + case RPL_CODE_DAO: + brief.append("DAO"); + verbose.append("DAO"); + break; + case RPL_CODE_DAO_ACK: + brief.append("DAO ACK"); + verbose.append("DAO ACK"); + break; + default: + brief.append(code); + verbose.append(code); + } } - @Override - public boolean matchPacket(Packet packet) { - return packet.level == APPLICATION_LEVEL && packet.lastDispatch == ICMPv6_DISPATCH; - } + /* remove type, code, crc */ + packet.consumeBytesStart(4); + return ANALYSIS_OK_FINAL; + } + + @Override + public boolean matchPacket(Packet packet) { + return packet.level == APPLICATION_LEVEL && packet.lastDispatch == ICMPv6_DISPATCH; + } } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IEEE802154Analyzer.java b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IEEE802154Analyzer.java index d15903d51..29e29262b 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IEEE802154Analyzer.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IEEE802154Analyzer.java @@ -2,180 +2,212 @@ package org.contikios.cooja.plugins.analyzers; import java.io.IOException; import java.io.File; +import org.apache.log4j.Logger; import org.contikios.cooja.util.StringUtils; public class IEEE802154Analyzer extends PacketAnalyzer { - /* TODO: fix this to be correct */ - public static final int NO_ADDRESS = 0; - public static final int RSV_ADDRESS = 1; - public static final int SHORT_ADDRESS = 2; - public static final int LONG_ADDRESS = 3; + private static final Logger logger = Logger.getLogger(IEEE802154Analyzer.class); - public static final int BEACONFRAME = 0x00; - public static final int DATAFRAME = 0x01; - public static final int ACKFRAME = 0x02; - public static final int CMDFRAME = 0x03; + // Addressing modes + public static final int NO_ADDRESS = 0; + public static final int RSV_ADDRESS = 1; + public static final int SHORT_ADDRESS = 2; + public static final int LONG_ADDRESS = 3; + + // Frame types + public static final int BEACONFRAME = 0x00; + public static final int DATAFRAME = 0x01; + public static final int ACKFRAME = 0x02; + public static final int CMDFRAME = 0x03; // private static final byte[] BROADCAST_ADDR = {(byte)0xff, (byte)0xff}; - - private static final String[] typeS = {"-", "D", "A"}; - private static final String[] typeVerbose = {"BEACON", "DATA", "ACK"}; - private PcapExporter pcapExporter; + private static final String[] typeS = {"-", "D", "A", "C"}; + private static final String[] typeVerbose = {"BEACON", "DATA", "ACK", "CMD"}; + private static final String[] addrModeNames = {"None", "Reserved", "Short", "Long"}; + private PcapExporter pcapExporter; // private int defaultAddressMode = LONG_ADDRESS; // private byte seqNo = 0; - // private int myPanID = 0xabcd; - - public IEEE802154Analyzer(boolean pcap) { - if (pcap) try { - pcapExporter = new PcapExporter(); - } catch (IOException e) { - e.printStackTrace(); - } + public IEEE802154Analyzer(boolean pcap) { + if (pcap) { + try { + pcapExporter = new PcapExporter(); + } catch (IOException e) { + logger.error(e); + } } + } - public void setPcapFile(File pcapFile) { - if (pcapExporter != null) { - try { - pcapExporter.openPcap(pcapFile); - } catch (IOException e) { - System.err.println("Could not open pcap file"); - e.printStackTrace(); - } + public void setPcapFile(File pcapFile) { + if (pcapExporter != null) { + try { + pcapExporter.openPcap(pcapFile); + } catch (IOException e) { + logger.error("Could not open pcap file", e); + } + } + } + + @Override + public boolean matchPacket(Packet packet) { + return packet.level == MAC_LEVEL; + } + + /* this protocol always have network level packets as payload */ + public int nextLevel(byte[] packet, int level) { + return NETWORK_LEVEL; + } + /* create a 802.15.4 packet of the bytes and "dispatch" to the + * next handler + */ + + @Override + public int analyzePacket(Packet packet, StringBuilder brief, StringBuilder verbose) { + + if (pcapExporter != null) { + try { + pcapExporter.exportPacketData(packet.getPayload()); + } catch (IOException e) { + logger.error("Could not export PCap data", e); } } - public boolean matchPacket(Packet packet) { - return packet.level == MAC_LEVEL; + int pos = packet.pos; + // FCF field + int fcfType = packet.data[pos + 0] & 0x07; + boolean fcfSecurity = ((packet.data[pos + 0] >> 3) & 0x01) != 0; + boolean fcfPending = ((packet.data[pos + 0] >> 4) & 0x01) != 0; + boolean fcfAckRequested = ((packet.data[pos + 0] >> 5) & 0x01) != 0; + boolean fcfIntraPAN = ((packet.data[pos + 0] >> 6) & 0x01) != 0; + int fcfDestAddrMode = (packet.data[pos + 1] >> 2) & 0x03; + int fcfFrameVersion = (packet.data[pos + 1] >> 4) & 0x03; + int fcfSrcAddrMode = (packet.data[pos + 1] >> 6) & 0x03; + // Sequence number + int seqNumber = packet.data[pos + 2] & 0xff; + // Addressing Fields + int destPanID = 0; + int srcPanID = 0; + byte[] sourceAddress = null; + byte[] destAddress = null; + + pos += 3; + + if (fcfDestAddrMode > 0) { + destPanID = (packet.data[pos] & 0xff) + ((packet.data[pos + 1] & 0xff) << 8); + pos += 2; + if (fcfDestAddrMode == SHORT_ADDRESS) { + destAddress = new byte[2]; + destAddress[1] = packet.data[pos]; + destAddress[0] = packet.data[pos + 1]; + pos += 2; + } else if (fcfDestAddrMode == LONG_ADDRESS) { + destAddress = new byte[8]; + for (int i = 0; i < 8; i++) { + destAddress[i] = packet.data[pos + 7 - i]; + } + pos += 8; + } } - /* this protocol always have network level packets as payload */ - public int nextLevel(byte[] packet, int level) { - return NETWORK_LEVEL; + if (fcfSrcAddrMode > 0) { + if (fcfIntraPAN) { + srcPanID = destPanID; + } else { + srcPanID = (packet.data[pos] & 0xff) + ((packet.data[pos + 1] & 0xff) << 8); + pos += 2; + } + if (fcfSrcAddrMode == SHORT_ADDRESS) { + sourceAddress = new byte[2]; + sourceAddress[1] = packet.data[pos]; + sourceAddress[0] = packet.data[pos + 1]; + pos += 2; + } else if (fcfSrcAddrMode == LONG_ADDRESS) { + sourceAddress = new byte[8]; + for (int i = 0; i < 8; i++) { + sourceAddress[i] = packet.data[pos + 7 - i]; + } + pos += 8; + } } - /* create a 802.15.4 packet of the bytes and "dispatch" to the - * next handler - */ - public int analyzePacket(Packet packet, StringBuffer brief, StringBuffer verbose) { - - if (pcapExporter != null) { - try { - pcapExporter.exportPacketData(packet.getPayload()); - } catch (IOException e) { - System.err.println("Could not export PCap data"); - e.printStackTrace(); - } - } - - int pos = packet.pos; - int type = packet.data[pos + 0] & 7; -// int security = (packet.data[pos + 0] >> 3) & 1; -// int pending = (packet.data[pos + 0] >> 4) & 1; -// int ackRequired = (packet.data[pos + 0] >> 5) & 1; - int panCompression = (packet.data[pos + 0]>> 6) & 1; - int destAddrMode = (packet.data[pos + 1] >> 2) & 3; -// int frameVersion = (packet.data[pos + 1] >> 4) & 3; - int srcAddrMode = (packet.data[pos + 1] >> 6) & 3; - int seqNumber = packet.data[pos + 2] & 0xff; - int destPanID = 0; - int srcPanID = 0; - byte[] sourceAddress = null; - byte[] destAddress = null; - - pos += 3; - - if (destAddrMode > 0) { - destPanID = (packet.data[pos] & 0xff) + ((packet.data[pos + 1] & 0xff) << 8); - pos += 2; - if (destAddrMode == SHORT_ADDRESS) { - destAddress = new byte[2]; - destAddress[1] = packet.data[pos]; - destAddress[0] = packet.data[pos + 1]; - pos += 2; - } else if (destAddrMode == LONG_ADDRESS) { - destAddress = new byte[8]; - for (int i = 0; i < 8; i++) { - destAddress[i] = packet.data[pos + 7 - i]; - } - pos += 8; - } - } - - if (srcAddrMode > 0) { - if (panCompression == 0){ - srcPanID = (packet.data[pos] & 0xff) + ((packet.data[pos + 1] & 0xff) << 8); - pos += 2; - } else { - srcPanID = destPanID; - } - if (srcAddrMode == SHORT_ADDRESS) { - sourceAddress = new byte[2]; - sourceAddress[1] = packet.data[pos]; - sourceAddress[0] = packet.data[pos + 1]; - pos += 2; - } else if (srcAddrMode == LONG_ADDRESS) { - sourceAddress = new byte[8]; - for (int i = 0; i < 8; i++) { - sourceAddress[i] = packet.data[pos + 7 - i]; - } - pos += 8; - } - } // int payloadLen = packet.data.length - pos; + brief.append("15.4 "); + brief.append(fcfType < typeS.length ? typeS[fcfType] : "?").append(' '); - brief.append("15.4 "); - brief.append(type < typeS.length ? typeS[type] : "?").append(' '); + verbose.append("IEEE 802.15.4 ") + .append(fcfType < typeVerbose.length ? typeVerbose[fcfType] : "?") + .append(" #").append(seqNumber); - verbose.append("IEEE 802.15.4 ") - .append(type < typeVerbose.length ? typeVerbose[type] : "?") - .append(' ').append(seqNumber); - if (type != ACKFRAME) { - printAddress(brief, srcAddrMode, sourceAddress); - brief.append(' '); - printAddress(brief, destAddrMode, destAddress); + if (fcfType != ACKFRAME) { + printAddress(brief, fcfSrcAddrMode, sourceAddress); + brief.append(' '); + printAddress(brief, fcfDestAddrMode, destAddress); - verbose.append("
    From "); - if (srcPanID != 0) { - verbose.append(StringUtils.toHex((byte)(srcPanID >> 8))) - .append(StringUtils.toHex((byte)(srcPanID & 0xff))) + verbose.append("
    From "); + if (srcPanID != 0) { + verbose.append("0x") + .append(StringUtils.toHex((byte) (srcPanID >> 8))) + .append(StringUtils.toHex((byte) (srcPanID & 0xff))) .append('/'); - } - printAddress(verbose, srcAddrMode, sourceAddress); - verbose.append(" to "); - if (destPanID != 0) { - verbose.append(StringUtils.toHex((byte)(destPanID >> 8))) - .append(StringUtils.toHex((byte)(destPanID & 0xff))) + } + printAddress(verbose, fcfSrcAddrMode, sourceAddress); + verbose.append(" to "); + if (destPanID != 0) { + verbose.append("0x") + .append(StringUtils.toHex((byte) (destPanID >> 8))) + .append(StringUtils.toHex((byte) (destPanID & 0xff))) .append('/'); - } - printAddress(verbose, destAddrMode, destAddress); - } else { - /* got ack - no more to do ... */ - return ANALYSIS_OK_FINAL; - } - - /* update packet */ - packet.pos = pos; - packet.level = NETWORK_LEVEL; - /* remove CRC from the packet */ - packet.consumeBytesEnd(2); - - packet.llsender = sourceAddress; - packet.llreceiver = destAddress; - return ANALYSIS_OK_CONTINUE; + } + printAddress(verbose, fcfDestAddrMode, destAddress); } - private void printAddress(StringBuffer sb, int type, byte[] addr) { - if (type == SHORT_ADDRESS) { - sb.append(StringUtils.toHex(addr)); - } else if (type == LONG_ADDRESS) { - sb.append(StringUtils.toHex(addr[0]) + StringUtils.toHex(addr[1]) + ":" + - StringUtils.toHex(addr[2]) + StringUtils.toHex(addr[3]) + ":" + - StringUtils.toHex(addr[4]) + StringUtils.toHex(addr[5]) + ":" + - StringUtils.toHex(addr[6]) + StringUtils.toHex(addr[7])); - } + verbose.append("
    Sec = ").append(fcfSecurity) + .append(", Pend = ").append(fcfPending) + .append(", ACK = ").append(fcfAckRequested) + .append(", iPAN = ").append(fcfIntraPAN) + .append(", DestAddr = ").append(addrModeNames[fcfDestAddrMode]) + .append(", Vers. = ").append(fcfFrameVersion) + .append(", SrcAddr = ").append(addrModeNames[fcfSrcAddrMode]); + + /* update packet */ + packet.pos = pos; + /* remove CRC from the packet */ + packet.consumeBytesEnd(2); + + if (fcfType == ACKFRAME) { + /* got ack - no more to do ... */ + return ANALYSIS_OK_FINAL; } + + packet.level = NETWORK_LEVEL; + packet.llsender = sourceAddress; + packet.llreceiver = destAddress; + return ANALYSIS_OK_CONTINUE; + } + + private void printAddress(StringBuilder sb, int type, byte[] addr) { + if (type == SHORT_ADDRESS) { + sb.append("0x").append(StringUtils.toHex(addr)); + } else if (type == LONG_ADDRESS) { + sb.append(StringUtils.toHex(addr[0])) + .append(':') + .append(StringUtils.toHex(addr[1])) + .append(':') + .append(StringUtils.toHex(addr[2])) + .append(':') + .append(StringUtils.toHex(addr[3])) + .append(':') + .append(StringUtils.toHex(addr[4])) + .append(':') + .append(StringUtils.toHex(addr[5])) + .append(':') + .append(StringUtils.toHex(addr[6])) + .append(':') + .append(StringUtils.toHex(addr[7])); + + } + } } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IPHCPacketAnalyzer.java b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IPHCPacketAnalyzer.java index 0860b98cc..ec5b55521 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IPHCPacketAnalyzer.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IPHCPacketAnalyzer.java @@ -1,368 +1,429 @@ package org.contikios.cooja.plugins.analyzers; -import org.contikios.cooja.util.StringUtils; +import org.contikios.cooja.util.IPUtils; public class IPHCPacketAnalyzer extends PacketAnalyzer { - public final static int SICSLOWPAN_UDP_PORT_MIN = 0xF0B0; - public final static int SICSLOWPAN_UDP_PORT_MAX = 0xF0BF; /* F0B0 + 15 */ + public final static int SICSLOWPAN_UDP_4_BIT_PORT_MIN = 0xF0B0; + public final static int SICSLOWPAN_UDP_4_BIT_PORT_MAX = 0xF0BF; /* F0B0 + 15 */ + public final static int SICSLOWPAN_UDP_8_BIT_PORT_MIN = 0xF000; + public final static int SICSLOWPAN_UDP_8_BIT_PORT_MAX = 0xF0FF; /* F000 + 255 */ - public final static int SICSLOWPAN_DISPATCH_IPV6 = 0x41; /* 01000001 = 65 */ - public final static int SICSLOWPAN_DISPATCH_HC1 = 0x42; /* 01000010 = 66 */ - public final static int SICSLOWPAN_DISPATCH_IPHC = 0x60; /* 011xxxxx = ... */ - public final static int SICSLOWPAN_DISPATCH_FRAG1 = 0xc0; /* 1100= 0xxx */ - public final static int SICSLOWPAN_DISPATCH_FRAGN = 0xe0; /* 1110= 0xxx */ + public final static int SICSLOWPAN_DISPATCH_IPV6 = 0x41; /* 01000001 = 65 */ + public final static int SICSLOWPAN_DISPATCH_HC1 = 0x42; /* 01000010 = 66 */ + public final static int SICSLOWPAN_DISPATCH_IPHC = 0x60; /* 011xxxxx = ... */ - /* - * Values of fields within the IPHC encoding first byte - * (C stands for compressed and I for inline) - */ - public final static int SICSLOWPAN_IPHC_FL_C = 0x10; - public final static int SICSLOWPAN_IPHC_TC_C = 0x08; - public final static int SICSLOWPAN_IPHC_NH_C = 0x04; - public final static int SICSLOWPAN_IPHC_TTL_1 = 0x01; - public final static int SICSLOWPAN_IPHC_TTL_64 = 0x02; - public final static int SICSLOWPAN_IPHC_TTL_255 = 0x03; - public final static int SICSLOWPAN_IPHC_TTL_I = 0x00; + public final static int EXT_HDR_HOP_BY_HOP = 0; + public final static int EXT_HDR_ROUTING = 43; + public final static int EXT_HDR_FRAGMENT = 44; + + /* + * Values of fields within the IPHC encoding first byte + * (C stands for compressed and I for inline) + */ + public final static int SICSLOWPAN_IPHC_FL_C = 0x10; + public final static int SICSLOWPAN_IPHC_TC_C = 0x08; + public final static int SICSLOWPAN_IPHC_NH_C = 0x04; + public final static int SICSLOWPAN_IPHC_TTL_1 = 0x01; + public final static int SICSLOWPAN_IPHC_TTL_64 = 0x02; + public final static int SICSLOWPAN_IPHC_TTL_255 = 0x03; + public final static int SICSLOWPAN_IPHC_TTL_I = 0x00; - /* Values of fields within the IPHC encoding second byte */ - public final static int SICSLOWPAN_IPHC_CID = 0x80; + /* Values of fields within the IPHC encoding second byte */ + public final static int SICSLOWPAN_IPHC_CID = 0x80; - public final static int SICSLOWPAN_IPHC_SAC = 0x40; - public final static int SICSLOWPAN_IPHC_SAM_00 = 0x00; - public final static int SICSLOWPAN_IPHC_SAM_01 = 0x10; - public final static int SICSLOWPAN_IPHC_SAM_10 = 0x20; - public final static int SICSLOWPAN_IPHC_SAM_11 = 0x30; + public final static int SICSLOWPAN_IPHC_SAC = 0x40; + public final static int SICSLOWPAN_IPHC_SAM_00 = 0x00; + public final static int SICSLOWPAN_IPHC_SAM_01 = 0x10; + public final static int SICSLOWPAN_IPHC_SAM_10 = 0x20; + public final static int SICSLOWPAN_IPHC_SAM_11 = 0x30; - public final static int SICSLOWPAN_IPHC_M = 0x08; - public final static int SICSLOWPAN_IPHC_DAC = 0x04; - public final static int SICSLOWPAN_IPHC_DAM_00 = 0x00; - public final static int SICSLOWPAN_IPHC_DAM_01 = 0x01; - public final static int SICSLOWPAN_IPHC_DAM_10 = 0x02; - public final static int SICSLOWPAN_IPHC_DAM_11 = 0x03; + public final static int SICSLOWPAN_IPHC_M = 0x08; + public final static int SICSLOWPAN_IPHC_DAC = 0x04; + public final static int SICSLOWPAN_IPHC_DAM_00 = 0x00; + public final static int SICSLOWPAN_IPHC_DAM_01 = 0x01; + public final static int SICSLOWPAN_IPHC_DAM_10 = 0x02; + public final static int SICSLOWPAN_IPHC_DAM_11 = 0x03; - private static final int SICSLOWPAN_NDC_UDP_MASK = 0xf8; - private static final int SICSLOWPAN_NHC_UDP_ID = 0xf0; - private static final int SICSLOWPAN_NHC_UDP_C = 0xf3; - private static final int SICSLOWPAN_NHC_UDP_I = 0xf0; - - public final static int PROTO_UDP = 17; - public final static int PROTO_TCP = 6; - public final static int PROTO_ICMP = 58; - - - public final static byte[] UNSPECIFIED_ADDRESS = - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + private static final int SICSLOWPAN_NDC_UDP_MASK = 0xf8; + private static final int SICSLOWPAN_NHC_UDP_ID = 0xf0; + private static final int SICSLOWPAN_NHC_UDP_00 = 0xf0; + private static final int SICSLOWPAN_NHC_UDP_01 = 0xf1; + private static final int SICSLOWPAN_NHC_UDP_10 = 0xf2; + private static final int SICSLOWPAN_NHC_UDP_11 = 0xf3; - private static byte[][] addrContexts = new byte[][] { - {(byte)0xaa, (byte)0xaa, 0, 0, 0, 0, 0, 0} - }; + public final static int PROTO_UDP = 17; + public final static int PROTO_TCP = 6; + public final static int PROTO_ICMP = 58; - private static final int IPHC_DISPATCH = 0x60; + public final static byte[] UNSPECIFIED_ADDRESS + = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - /* packet must be on network level && have a IPHC dispatch */ - public boolean matchPacket(Packet packet) { - return packet.level == NETWORK_LEVEL && (packet.get(0) & 0xe0) == IPHC_DISPATCH; + private static byte[][] addrContexts = new byte[][]{ + {(byte) 0xaa, (byte) 0xaa, 0, 0, 0, 0, 0, 0} + }; + + private static final int IPHC_DISPATCH = 0x60; + + /* packet must be on network level && have a IPHC dispatch */ + @Override + public boolean matchPacket(Packet packet) { + return packet.level == NETWORK_LEVEL && (packet.get(0) & 0xe0) == IPHC_DISPATCH; + } + + @Override + public int analyzePacket(Packet packet, StringBuilder brief, + StringBuilder verbose) { + + /* if packet has less than 3 bytes it is not interesting ... */ + if (packet.size() < 3) return ANALYSIS_FAILED; + + int tf = (packet.get(0) >> 3) & 0x03; + boolean nhc = (packet.get(0) & SICSLOWPAN_IPHC_NH_C) > 0; + int hlim = (packet.get(0) & 0x03); + switch (hlim) { + case 0x00: + hlim = 0; + break; + case 0x01: + hlim = 1; + break; + case 0x02: + hlim = 64; + break; + case 0x03: + hlim = 255; + break; + } + int cid = (packet.get(1) >> 7) & 0x01; + int sac = (packet.get(1) >> 6) & 0x01; + int sam = (packet.get(1) >> 4) & 0x03; + boolean m = ((packet.get(1) >> 3) & 0x01) != 0; + int dac = (packet.get(1) >> 2) & 0x01; + int dam = packet.get(1) & 0x03; + int sci = 0; + int dci = 0; + + String error = null; + + brief.append("IPHC"); + + /* need to decompress while analyzing - add that later... */ + verbose.append("IPHC HC-06
    "); + verbose.append("TF = ").append(tf) + .append(", NH = ").append(nhc ? "compressed" : "inline") + .append(", HLIM = ").append(hlim == 0 ? "inline" : hlim) + .append(", CID = ").append(cid) + .append(", SAC = ").append(sac == 0 ? "stateless" : "stateful") + .append(", SAM = ").append(sam) + .append(", MCast = ").append(m) + .append(", DAC = ").append(dac == 0 ? "stateless" : "stateful") + .append(", DAM = ").append(dam); + if (cid == 1) { + verbose.append("
    Contexts: sci=").append(packet.get(2) >> 4). + append(" dci=").append(packet.get(2) & 0x0f); + sci = packet.get(2) >> 4; + dci = packet.get(2) & 0x0f; } - public int analyzePacket(Packet packet, StringBuffer brief, - StringBuffer verbose) { + int hc06_ptr = 2 + cid; - /* if packet has less than 3 bytes it is not interesting ... */ - if (packet.size() < 3) return ANALYSIS_FAILED; - - int tf = (packet.get(0) >> 3) & 0x03; - boolean nhc = (packet.get(0) & SICSLOWPAN_IPHC_NH_C) > 0; - int hlim = (packet.get(0) & 0x03); - int cid = (packet.get(1) >> 7) & 0x01; - int sac = (packet.get(1) >> 6) & 0x01; - int sam = (packet.get(1) >> 4) & 0x03; - int m = (packet.get(1) >> 3) & 0x01; - int dac = (packet.get(1) >> 2) & 0x01; - int dam = packet.get(1) & 0x03; - int sci = 0; - int dci = 0; + int version = 6; + int trafficClass = 0; + int flowLabel = 0; + int len = 0; + int proto = 0; + int ttl = 0; + byte[] srcAddress = new byte[16]; + byte[] destAddress = new byte[16]; - String error = null; - - brief.append("IPHC"); + int srcPort = 0; + int destPort = 0; - /* need to decompress while analyzing - add that later... */ - - verbose.append("IPHC HC-06
    "); - verbose.append("tf = " + tf + " nhc = " + nhc + " hlim = " + hlim - + " cid = " + cid + " sac = " + sac + " sam = " + sam - + " MCast = " + m + " dac = " + dac + " dam = " + dam); - if (cid == 1) { - verbose.append("
    Contexts: sci=" + (packet.get(2) >> 4) + " dci=" - + (packet.get(2) & 0x0f)); - sci = packet.get(2) >> 4; - dci = packet.get(2) & 0x0f; - } - - int hc06_ptr = 2 + cid; - - int version = 6; - int trafficClass = 0; - int flowLabel = 0; - int len = 0; - int proto = 0; - int ttl = 0; - byte[] srcAddress = new byte[16]; - byte[] destAddress = new byte[16]; - - int srcPort = 0; - int destPort = 0; - - - try { - /* Traffic class and flow label */ - if((packet.get(0) & SICSLOWPAN_IPHC_FL_C) == 0) { - /* Flow label are carried inline */ - if((packet.get(0) & SICSLOWPAN_IPHC_TC_C) == 0) { - /* Traffic class is carried inline */ - flowLabel = packet.getInt(hc06_ptr + 1, 3); - int tmp = packet.get(hc06_ptr); - hc06_ptr += 4; - /* hc06 format of tc is ECN | DSCP , original is DSCP | ECN */ - trafficClass = ((tmp >> 2) & 0x3f) | (tmp << 6) & (0x80 + 0x40); - /* ECN rolled down two steps + lowest DSCP bits at top two bits */ - } else { - /* highest flow label bits + ECN bits */ - int tmp = packet.get(hc06_ptr); - trafficClass = (tmp >> 6) & 0x0f; - flowLabel = packet.getInt(hc06_ptr + 1, 2); - hc06_ptr += 3; - } + try { + /* Traffic class and flow label */ + if ((packet.get(0) & SICSLOWPAN_IPHC_FL_C) == 0) { + /* Flow label are carried inline */ + if ((packet.get(0) & SICSLOWPAN_IPHC_TC_C) == 0) { + /* Traffic class is carried inline */ + flowLabel = packet.getInt(hc06_ptr + 1, 3); + int tmp = packet.get(hc06_ptr); + hc06_ptr += 4; + /* hc06 format of tc is ECN | DSCP , original is DSCP | ECN */ + trafficClass = ((tmp >> 2) & 0x3f) | (tmp << 6) & (0x80 + 0x40); + /* ECN rolled down two steps + lowest DSCP bits at top two bits */ } else { - /* Version is always 6! */ - /* Version and flow label are compressed */ - if((packet.get(0) & SICSLOWPAN_IPHC_TC_C) == 0) { - /* Traffic class is inline */ - trafficClass =((packet.get(hc06_ptr) >> 6) & 0x03); - trafficClass |= (packet.get(hc06_ptr) << 2); - hc06_ptr += 1; - } + /* highest flow label bits + ECN bits */ + int tmp = packet.get(hc06_ptr); + trafficClass = (tmp >> 6) & 0x0f; + flowLabel = packet.getInt(hc06_ptr + 1, 2); + hc06_ptr += 3; } - - /* Next Header */ - if((packet.get(0) & SICSLOWPAN_IPHC_NH_C) == 0) { - /* Next header is carried inline */ - proto = packet.get(hc06_ptr); - hc06_ptr += 1; + } else { + /* Version is always 6! */ + /* Version and flow label are compressed */ + if ((packet.get(0) & SICSLOWPAN_IPHC_TC_C) == 0) { + /* Traffic class is inline */ + trafficClass = ((packet.get(hc06_ptr) >> 6) & 0x03); + trafficClass |= (packet.get(hc06_ptr) << 2); + hc06_ptr += 1; } + } - /* Hop limit */ - switch(packet.get(0) & 0x03) { + /* Next Header */ + if ((packet.get(0) & SICSLOWPAN_IPHC_NH_C) == 0) { + /* Next header is carried inline */ + proto = packet.get(hc06_ptr); + hc06_ptr += 1; + } + + /* Hop limit */ + switch (packet.get(0) & 0x03) { case SICSLOWPAN_IPHC_TTL_1: - ttl = 1; - break; + ttl = 1; + break; case SICSLOWPAN_IPHC_TTL_64: - ttl = 2; - break; + ttl = 64; + break; case SICSLOWPAN_IPHC_TTL_255: - ttl = 255; - break; + ttl = 255; + break; case SICSLOWPAN_IPHC_TTL_I: - ttl = packet.get(hc06_ptr); - hc06_ptr += 1; + ttl = packet.get(hc06_ptr); + hc06_ptr += 1; + break; + } + + /* context based compression */ + if ((packet.get(1) & SICSLOWPAN_IPHC_SAC) > 0) { + /* Source address */ + byte[] context = null; + if ((packet.get(1) & SICSLOWPAN_IPHC_SAM_11) != SICSLOWPAN_IPHC_SAM_00) { + context = addrContexts[sci]; + } + + switch (packet.get(1) & SICSLOWPAN_IPHC_SAM_11) { + case SICSLOWPAN_IPHC_SAM_00: + /* copy the unspecificed address */ + srcAddress = UNSPECIFIED_ADDRESS; + break; + case SICSLOWPAN_IPHC_SAM_01: /* 64 bits */ + /* copy prefix from context */ + + System.arraycopy(context, 0, srcAddress, 0, 8); + /* copy IID from packet */ + packet.copy(hc06_ptr, srcAddress, 8, 8); + hc06_ptr += 8; + break; + case SICSLOWPAN_IPHC_SAM_10: /* 16 bits */ + /* unicast address */ + + System.arraycopy(context, 0, srcAddress, 0, 8); + /* copy 6 NULL bytes then 2 last bytes of IID */ + packet.copy(hc06_ptr, srcAddress, 14, 2); + hc06_ptr += 2; + break; + case SICSLOWPAN_IPHC_SAM_11: /* 0-bits */ + /* copy prefix from context */ + + System.arraycopy(context, 0, srcAddress, 0, 8); + /* infer IID from L2 address */ + System.arraycopy(packet.llsender, 0, srcAddress, + 16 - packet.llsender.length, packet.llsender.length); break; } + /* end context based compression */ + } else { + /* no compression and link local */ + switch (packet.get(1) & SICSLOWPAN_IPHC_SAM_11) { + case SICSLOWPAN_IPHC_SAM_00: /* 128 bits */ + /* copy whole address from packet */ - /* context based compression */ - if((packet.get(1) & SICSLOWPAN_IPHC_SAC) > 0) { - /* Source address */ - byte[] context = null; - if((packet.get(1) & SICSLOWPAN_IPHC_SAM_11) != SICSLOWPAN_IPHC_SAM_00) { - context = addrContexts[sci]; - } + packet.copy(hc06_ptr, srcAddress, 0, 16); + hc06_ptr += 16; + break; + case SICSLOWPAN_IPHC_SAM_01: /* 64 bits */ - switch(packet.get(1) & SICSLOWPAN_IPHC_SAM_11) { - case SICSLOWPAN_IPHC_SAM_00: - /* copy the unspecificed address */ - srcAddress = UNSPECIFIED_ADDRESS; - break; - case SICSLOWPAN_IPHC_SAM_01: /* 64 bits */ - /* copy prefix from context */ - System.arraycopy(context, 0, srcAddress, 0, 8); - /* copy IID from packet */ - packet.copy(hc06_ptr, srcAddress, 8, 8); - hc06_ptr += 8; - break; - case SICSLOWPAN_IPHC_SAM_10: /* 16 bits */ - /* unicast address */ - System.arraycopy(context, 0, srcAddress, 0, 8); - /* copy 6 NULL bytes then 2 last bytes of IID */ - packet.copy(hc06_ptr, srcAddress, 14, 2); - hc06_ptr += 2; - break; - case SICSLOWPAN_IPHC_SAM_11: /* 0-bits */ - /* copy prefix from context */ - System.arraycopy(context, 0, srcAddress, 0, 8); - /* infer IID from L2 address */ - System.arraycopy(packet.llsender, 0, srcAddress, - 16 - packet.llsender.length, packet.llsender.length); - break; - } - /* end context based compression */ + srcAddress[0] = (byte) 0xfe; + srcAddress[1] = (byte) 0x80; + /* copy IID from packet */ + packet.copy(hc06_ptr, srcAddress, 8, 8); + hc06_ptr += 8; + break; + case SICSLOWPAN_IPHC_SAM_10: /* 16 bits */ + + srcAddress[0] = (byte) 0xfe; + srcAddress[1] = (byte) 0x80; + packet.copy(hc06_ptr, srcAddress, 14, 2); + hc06_ptr += 2; + break; + case SICSLOWPAN_IPHC_SAM_11: /* 0 bits */ + /* setup link-local address */ + + srcAddress[0] = (byte) 0xfe; + srcAddress[1] = (byte) 0x80; + /* infer IID from L2 address */ + System.arraycopy(packet.llsender, 0, srcAddress, + 16 - packet.llsender.length, packet.llsender.length); + break; + } + } + + /* Destination address */ + + /* multicast compression */ + if ((packet.get(1) & SICSLOWPAN_IPHC_M) != 0) { + /* context based multicast compression */ + if ((packet.get(1) & SICSLOWPAN_IPHC_DAC) != 0) { + /* TODO: implement this */ } else { - /* no compression and link local */ - switch(packet.get(1) & SICSLOWPAN_IPHC_SAM_11) { - case SICSLOWPAN_IPHC_SAM_00: /* 128 bits */ - /* copy whole address from packet */ - packet.copy(hc06_ptr, srcAddress, 0, 16); - hc06_ptr += 16; - break; - case SICSLOWPAN_IPHC_SAM_01: /* 64 bits */ - srcAddress[0] = (byte) 0xfe; - srcAddress[1] = (byte) 0x80; - /* copy IID from packet */ - packet.copy(hc06_ptr, srcAddress, 8, 8); - hc06_ptr += 8; - break; - case SICSLOWPAN_IPHC_SAM_10: /* 16 bits */ - srcAddress[0] = (byte) 0xfe; - srcAddress[1] = (byte) 0x80; - packet.copy(hc06_ptr, srcAddress, 14, 2); - hc06_ptr += 2; - break; - case SICSLOWPAN_IPHC_SAM_11: /* 0 bits */ - /* setup link-local address */ - srcAddress[0] = (byte) 0xfe; - srcAddress[1] = (byte) 0x80; - /* infer IID from L2 address */ - System.arraycopy(packet.llsender, 0, srcAddress, - 16 - packet.llsender.length, packet.llsender.length); - break; - } + /* non-context based multicast compression */ + switch (packet.get(1) & SICSLOWPAN_IPHC_DAM_11) { + case SICSLOWPAN_IPHC_DAM_00: /* 128 bits */ + /* copy whole address from packet */ + + packet.copy(hc06_ptr, destAddress, 0, 16); + hc06_ptr += 16; + break; + case SICSLOWPAN_IPHC_DAM_01: /* 48 bits FFXX::00XX:XXXX:XXXX */ + + destAddress[0] = (byte) 0xff; + destAddress[1] = packet.get(hc06_ptr); + packet.copy(hc06_ptr + 1, destAddress, 11, 5); + hc06_ptr += 6; + break; + case SICSLOWPAN_IPHC_DAM_10: /* 32 bits FFXX::00XX:XXXX */ + + destAddress[0] = (byte) 0xff; + destAddress[1] = packet.get(hc06_ptr); + packet.copy(hc06_ptr + 1, destAddress, 13, 3); + hc06_ptr += 4; + break; + case SICSLOWPAN_IPHC_DAM_11: /* 8 bits FF02::00XX */ + + destAddress[0] = (byte) 0xff; + destAddress[1] = (byte) 0x02; + destAddress[15] = packet.get(hc06_ptr); + hc06_ptr++; + break; + } } + } else { + /* no multicast */ + /* Context based */ + if ((packet.get(1) & SICSLOWPAN_IPHC_DAC) != 0) { + byte[] context = addrContexts[dci]; - /* Destination address */ + switch (packet.get(1) & SICSLOWPAN_IPHC_DAM_11) { + case SICSLOWPAN_IPHC_DAM_01: /* 64 bits */ - /* multicast compression */ - if((packet.get(1) & SICSLOWPAN_IPHC_M) != 0) { - /* context based multicast compression */ - if((packet.get(1) & SICSLOWPAN_IPHC_DAC) != 0) { - /* TODO: implement this */ - } else { - /* non-context based multicast compression */ - switch (packet.get(1) & SICSLOWPAN_IPHC_DAM_11) { - case SICSLOWPAN_IPHC_DAM_00: /* 128 bits */ - /* copy whole address from packet */ - packet.copy(hc06_ptr, destAddress, 0, 16); - hc06_ptr += 16; - break; - case SICSLOWPAN_IPHC_DAM_01: /* 48 bits FFXX::00XX:XXXX:XXXX */ - destAddress[0] = (byte) 0xff; - destAddress[1] = packet.get(hc06_ptr); - packet.copy(hc06_ptr + 1, destAddress, 11, 5); - hc06_ptr += 6; - break; - case SICSLOWPAN_IPHC_DAM_10: /* 32 bits FFXX::00XX:XXXX */ - destAddress[0] = (byte) 0xff; - destAddress[1] = packet.get(hc06_ptr); - packet.copy(hc06_ptr + 1, destAddress, 13, 3); - hc06_ptr += 4; - break; - case SICSLOWPAN_IPHC_DAM_11: /* 8 bits FF02::00XX */ - destAddress[0] = (byte) 0xff; - destAddress[1] = (byte) 0x02; - destAddress[15] = packet.get(hc06_ptr); - hc06_ptr++; - break; - } - } + System.arraycopy(context, 0, destAddress, 0, 8); + /* copy IID from packet */ + packet.copy(hc06_ptr, destAddress, 8, 8); + hc06_ptr += 8; + break; + case SICSLOWPAN_IPHC_DAM_10: /* 16 bits */ + /* unicast address */ + + System.arraycopy(context, 0, destAddress, 0, 8); + /* copy IID from packet */ + packet.copy(hc06_ptr, destAddress, 14, 2); + hc06_ptr += 2; + break; + case SICSLOWPAN_IPHC_DAM_11: /* 0 bits */ + /* unicast address */ + + System.arraycopy(context, 0, destAddress, 0, 8); + /* infer IID from L2 address */ + System.arraycopy(packet.llreceiver, 0, destAddress, + 16 - packet.llreceiver.length, packet.llreceiver.length); + break; + } } else { - /* no multicast */ - /* Context based */ - if((packet.get(1) & SICSLOWPAN_IPHC_DAC) != 0) { - byte[] context = addrContexts[dci]; + /* not context based => link local M = 0, DAC = 0 - same as SAC */ + switch (packet.get(1) & SICSLOWPAN_IPHC_DAM_11) { + case SICSLOWPAN_IPHC_DAM_00: /* 128 bits */ - switch (packet.get(1) & SICSLOWPAN_IPHC_DAM_11) { - case SICSLOWPAN_IPHC_DAM_01: /* 64 bits */ - System.arraycopy(context, 0, destAddress, 0, 8); - /* copy IID from packet */ - packet.copy(hc06_ptr, destAddress, 8, 8); - hc06_ptr += 8; - break; - case SICSLOWPAN_IPHC_DAM_10: /* 16 bits */ - /* unicast address */ - System.arraycopy(context, 0, destAddress, 0, 8); - /* copy IID from packet */ - packet.copy(hc06_ptr, destAddress, 14, 2); - hc06_ptr += 2; - break; - case SICSLOWPAN_IPHC_DAM_11: /* 0 bits */ - /* unicast address */ - System.arraycopy(context, 0, destAddress, 0, 8); - /* infer IID from L2 address */ - System.arraycopy(packet.llreceiver, 0, destAddress, - 16 - packet.llreceiver.length, packet.llreceiver.length); - break; - } - } else { - /* not context based => link local M = 0, DAC = 0 - same as SAC */ - switch (packet.get(1) & SICSLOWPAN_IPHC_DAM_11) { - case SICSLOWPAN_IPHC_DAM_00: /* 128 bits */ - packet.copy(hc06_ptr, destAddress, 0, 16); - hc06_ptr += 16; - break; - case SICSLOWPAN_IPHC_DAM_01: /* 64 bits */ - destAddress[0] = (byte) 0xfe; - destAddress[1] = (byte) 0x80; - packet.copy(hc06_ptr, destAddress, 8, 8); - hc06_ptr += 8; - break; - case SICSLOWPAN_IPHC_DAM_10: /* 16 bits */ - destAddress[0] = (byte) 0xfe; - destAddress[1] = (byte) 0x80; - packet.copy(hc06_ptr, destAddress, 14, 2); - hc06_ptr += 2; - break; - case SICSLOWPAN_IPHC_DAM_11: /* 0 bits */ - destAddress[0] = (byte) 0xfe; - destAddress[1] = (byte) 0x80; - System.arraycopy(packet.llreceiver, 0, destAddress, - 16 - packet.llreceiver.length, packet.llreceiver.length); - break; - } - } + packet.copy(hc06_ptr, destAddress, 0, 16); + hc06_ptr += 16; + break; + case SICSLOWPAN_IPHC_DAM_01: /* 64 bits */ + + destAddress[0] = (byte) 0xfe; + destAddress[1] = (byte) 0x80; + packet.copy(hc06_ptr, destAddress, 8, 8); + hc06_ptr += 8; + break; + case SICSLOWPAN_IPHC_DAM_10: /* 16 bits */ + + destAddress[0] = (byte) 0xfe; + destAddress[1] = (byte) 0x80; + packet.copy(hc06_ptr, destAddress, 14, 2); + hc06_ptr += 2; + break; + case SICSLOWPAN_IPHC_DAM_11: /* 0 bits */ + + destAddress[0] = (byte) 0xfe; + destAddress[1] = (byte) 0x80; + System.arraycopy(packet.llreceiver, 0, destAddress, + 16 - packet.llreceiver.length, packet.llreceiver.length); + break; + } } + } - /* Next header processing - continued */ - if(nhc) { - /* TODO: check if this is correct in hc-06 */ - /* The next header is compressed, NHC is following */ - if((packet.get(hc06_ptr) & SICSLOWPAN_NDC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) { - proto = PROTO_UDP; - switch(packet.get(hc06_ptr)) { - case (byte) SICSLOWPAN_NHC_UDP_C: - /* 1 byte for NHC, 1 byte for ports, 2 bytes chksum */ - srcPort = SICSLOWPAN_UDP_PORT_MIN + (packet.get(hc06_ptr + 1) >> 4); - destPort = SICSLOWPAN_UDP_PORT_MIN + (packet.get(hc06_ptr + 1) & 0x0F); -// memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, hc06_ptr + 2, 2); -// PRINTF("IPHC: Uncompressed UDP ports (4): %x, %x\n", -// SICSLOWPAN_UDP_BUF->srcport, SICSLOWPAN_UDP_BUF->destport); - hc06_ptr += 4; - break; - case (byte) SICSLOWPAN_NHC_UDP_I: - /* 1 byte for NHC, 4 byte for ports, 2 bytes chksum */ - srcPort = packet.getInt(hc06_ptr + 1, 2); - destPort = packet.getInt(hc06_ptr + 3, 2); -// memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, hc06_ptr + 5, 2); -// PRINTF("IPHC: Uncompressed UDP ports (7): %x, %x\n", -// SICSLOWPAN_UDP_BUF->srcport, SICSLOWPAN_UDP_BUF->destport); - - hc06_ptr += 7; - break; - default: -// PRINTF("sicslowpan uncompress_hdr: error unsupported UDP compression\n"); - return ANALYSIS_FAILED; - } - } + /* Next header processing - continued */ + if (nhc) { + /* TODO: check if this is correct in hc-06 */ + /* The next header is compressed, NHC is following */ + if ((packet.get(hc06_ptr) & SICSLOWPAN_NDC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) { + proto = PROTO_UDP; + switch (packet.get(hc06_ptr) & (byte) SICSLOWPAN_NHC_UDP_11) { + case (byte) SICSLOWPAN_NHC_UDP_00: + /* 1 byte for NHC, 4 byte for ports, 2 bytes chksum */ + srcPort = packet.getInt(hc06_ptr + 1, 2) & 0xFFFF; + destPort = packet.getInt(hc06_ptr + 3, 2) & 0xFFFF; + hc06_ptr += 7; + break; + case (byte) SICSLOWPAN_NHC_UDP_01: + /* 1 byte for NHC, 3 byte for ports, 2 bytes chksum */ + srcPort = packet.getInt(hc06_ptr + 1, 2); + destPort = SICSLOWPAN_UDP_8_BIT_PORT_MIN + (packet.get(hc06_ptr + 3) & 0xFF); + hc06_ptr += 6; + break; + case (byte) SICSLOWPAN_NHC_UDP_10: + /* 1 byte for NHC, 3 byte for ports, 2 bytes chksum */ + srcPort = SICSLOWPAN_UDP_8_BIT_PORT_MIN + (packet.get(hc06_ptr + 1) & 0xFF); + destPort = packet.getInt(hc06_ptr + 2, 2); + hc06_ptr += 6; + break; + case (byte) SICSLOWPAN_NHC_UDP_11: + /* 1 byte for NHC, 1 byte for ports, 2 bytes chksum */ + srcPort = SICSLOWPAN_UDP_4_BIT_PORT_MIN + (packet.get(hc06_ptr + 1) >> 4); + destPort = SICSLOWPAN_UDP_4_BIT_PORT_MIN + (packet.get(hc06_ptr + 1) & 0x0F); + hc06_ptr += 4; + break; + } } + } else { + // Skip extension header + // XXX TODO: Handle others, too? + if (proto == EXT_HDR_HOP_BY_HOP) { + proto = packet.get(hc06_ptr) & 0xFF; + // header length is length specified in field, rounded up to 64 bit + int hdr_len = ((packet.get(hc06_ptr + 1) / 8) + 1) * 8; + hc06_ptr += hdr_len; + + // UDP hadling + if (proto == PROTO_UDP) { + srcPort = packet.getInt(hc06_ptr, 2) & 0xFFFF; + destPort = packet.getInt(hc06_ptr + 2, 2) & 0xFFFF; + hc06_ptr += 4; + } + } + } // /* IP length field. */ // if(ip_len == 0) { @@ -374,54 +435,65 @@ public class IPHCPacketAnalyzer extends PacketAnalyzer { // SICSLOWPAN_IP_BUF->len[0] = (ip_len - UIP_IPH_LEN) >> 8; // SICSLOWPAN_IP_BUF->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF; // } - // /* length field in UDP header */ // if(SICSLOWPAN_IP_BUF->proto == UIP_PROTO_UDP) { // memcpy(&SICSLOWPAN_UDP_BUF->udplen, ipBuf + len[0], 2); // } - /*--------------------------------------------- */ + /*--------------------------------------------- */ + } catch (Exception e) { + // some kind of unexpected error... + error = " error during IPHC parsing: " + e.getMessage(); + } + packet.pos += hc06_ptr; - } catch (Exception e) { - // some kind of unexpected error... - error = " error during IPHC parsing: " + e.getMessage(); - } - packet.pos += hc06_ptr; - - String protoStr = "" + proto; - if (proto == PROTO_ICMP) { - protoStr = "ICMPv6"; - } else if (proto == PROTO_UDP) protoStr = "UDP"; - else if (proto == PROTO_TCP) protoStr = "TCP"; - - verbose.append("
    IPv6 ").append(protoStr).append(" TC = " + trafficClass + - " FL: " + flowLabel + "
    "); - verbose.append("From "); - printAddress(verbose, srcAddress); - verbose.append(" to "); - printAddress(verbose, destAddress); - if (error != null) verbose.append(" " + error); - - packet.lastDispatch = (byte) (proto & 0xff); - if (proto == PROTO_UDP || proto == PROTO_ICMP || - proto == PROTO_TCP) { - packet.level = APPLICATION_LEVEL; - return ANALYSIS_OK_CONTINUE; - } else { - packet.level = NETWORK_LEVEL; - return ANALYSIS_OK_CONTINUE; - } + String protoStr = "" + proto; + if (proto == PROTO_ICMP) { + protoStr = "ICMPv6"; + } else if (proto == PROTO_UDP) { + protoStr = "UDP"; + } else if (proto == PROTO_TCP) { + protoStr = "TCP"; + } else { + protoStr = String.valueOf(proto); } - public static void printAddress(StringBuffer out, byte[] address) { - for (int i = 0; i < 16; i+=2) { - out.append(StringUtils.toHex((byte) (address[i] & 0xff)) + - StringUtils.toHex((byte) (address[i + 1] & 0xff))); - if (i < 14) { - out.append(":"); - } - } - } + // IPv6 Information + + brief.append("|IPv6"); + verbose.append("
    IPv6") + .append(" TC = ").append(trafficClass) + .append(", FL = ").append(flowLabel) + .append("
    "); + verbose.append("From "); + IPUtils.getUncompressedIPv6AddressString(verbose, srcAddress); + verbose.append(" to "); + IPUtils.getUncompressedIPv6AddressString(verbose, destAddress); + if (error != null) { + verbose.append(" ").append(error); + } + + // Application Layer Information + + if (proto != PROTO_ICMP) { + brief.append('|').append(protoStr); + verbose.append("
    ").append(protoStr).append(""); + } + if (proto == PROTO_UDP) { + brief.append(' ').append(srcPort).append(' ').append(destPort); + verbose.append("
    Src Port: ").append(srcPort); + verbose.append(", Dst Port: ").append(destPort); + } + + packet.lastDispatch = (byte) (proto & 0xff); + if (proto == PROTO_UDP || proto == PROTO_ICMP + || proto == PROTO_TCP) { + packet.level = APPLICATION_LEVEL; + return ANALYSIS_OK_CONTINUE; + } else { + packet.level = NETWORK_LEVEL; + return ANALYSIS_OK_CONTINUE; + } + } - } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IPv6PacketAnalyzer.java b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IPv6PacketAnalyzer.java index 4ca371c8d..4ecc99e4a 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IPv6PacketAnalyzer.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/IPv6PacketAnalyzer.java @@ -1,81 +1,72 @@ package org.contikios.cooja.plugins.analyzers; -import org.contikios.cooja.util.StringUtils; +import org.contikios.cooja.util.IPUtils; public class IPv6PacketAnalyzer extends PacketAnalyzer { - - public final static int PROTO_UDP = 17; - public final static int PROTO_TCP = 6; - public final static int PROTO_ICMP = 58; - - - public final static byte[] UNSPECIFIED_ADDRESS = - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + public final static int PROTO_UDP = 17; + public final static int PROTO_TCP = 6; + public final static int PROTO_ICMP = 58; - private static final int IPV6_DISPATCH = 0x41; + public final static byte[] UNSPECIFIED_ADDRESS + = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - public boolean matchPacket(Packet packet) { - return packet.level == NETWORK_LEVEL && packet.get(0) == IPV6_DISPATCH; + private static final int IPV6_DISPATCH = 0x41; + + @Override + public boolean matchPacket(Packet packet) { + return packet.level == NETWORK_LEVEL && packet.get(0) == IPV6_DISPATCH; + } + + @Override + public int analyzePacket(Packet packet, StringBuilder brief, + StringBuilder verbose) { + + /* if packet has less than 40 bytes it is not interesting ... */ + if (packet.size() < 40) return ANALYSIS_FAILED; + + brief.append("IPv6"); + + /* need to decompress while analyzing - add that later... */ + verbose.append("IPv6
    "); + + int pos = 1; + + int version = 6; + int trafficClass = 0; + int flowLabel = 0; + int len = packet.getInt(pos + 4, 2); + int proto = packet.getInt(pos + 6, 1); + int ttl = packet.getInt(pos + 7, 1); + byte[] srcAddress = new byte[16]; + byte[] destAddress = new byte[16]; + + packet.copy(pos + 8, srcAddress, 0, 16); + packet.copy(pos + 24, destAddress, 0, 16); + + String protoStr = "" + proto; + if (proto == PROTO_ICMP) { + protoStr = "ICMPv6"; + } else if (proto == PROTO_UDP) { + protoStr = "UDP"; + } else if (proto == PROTO_TCP) { + protoStr = "TCP"; } - public int analyzePacket(Packet packet, StringBuffer brief, - StringBuffer verbose) { + /* consume dispatch + IP header */ + packet.pos += 41; - /* if packet has less than 40 bytes it is not interesting ... */ - if (packet.size() < 40) return ANALYSIS_FAILED; - + verbose.append("
    IPv6 ").append(protoStr) + .append(" TC = ").append(trafficClass) + .append(" FL: ").append(flowLabel).append("
    "); + verbose.append("From "); + IPUtils.getUncompressedIPv6AddressString(verbose, srcAddress); + verbose.append(" to "); + IPUtils.getUncompressedIPv6AddressString(verbose, destAddress); - brief.append("IPv6"); + packet.lastDispatch = (byte) (proto & 0xff); + packet.level = APPLICATION_LEVEL; + return ANALYSIS_OK_CONTINUE; + } - /* need to decompress while analyzing - add that later... */ - - verbose.append("IPv6
    "); - - int pos = 1; - - int version = 6; - int trafficClass = 0; - int flowLabel = 0; - int len = packet.getInt(pos + 4, 2); - int proto = packet.getInt(pos + 6, 1); - int ttl = packet.getInt(pos + 7, 1); - byte[] srcAddress = new byte[16]; - byte[] destAddress = new byte[16]; - - packet.copy(pos + 8, srcAddress, 0, 16); - packet.copy(pos + 24, destAddress, 0, 16); - - String protoStr = "" + proto; - if (proto == PROTO_ICMP) { - protoStr = "ICMPv6"; - } else if (proto == PROTO_UDP) protoStr = "UDP"; - else if (proto == PROTO_TCP) protoStr = "TCP"; - - /* consume dispatch + IP header */ - packet.pos += 41; - - verbose.append("
    IPv6 ").append(protoStr).append(" TC = " + trafficClass + - " FL: " + flowLabel + "
    "); - verbose.append("From "); - printAddress(verbose, srcAddress); - verbose.append(" to "); - printAddress(verbose, destAddress); - - packet.lastDispatch = (byte) (proto & 0xff); - packet.level = APPLICATION_LEVEL; - return ANALYSIS_OK_CONTINUE; - } - - public static void printAddress(StringBuffer out, byte[] address) { - for (int i = 0; i < 16; i+=2) { - out.append(StringUtils.toHex((byte) (address[i] & 0xff)) + - StringUtils.toHex((byte) (address[i + 1] & 0xff))); - if (i < 14) { - out.append(":"); - } - } - } - - } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PacketAnalyzer.java b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PacketAnalyzer.java index 45d656863..28a548e3c 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PacketAnalyzer.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PacketAnalyzer.java @@ -2,88 +2,86 @@ package org.contikios.cooja.plugins.analyzers; public abstract class PacketAnalyzer { - public static final int ANALYSIS_FAILED = -1; - public static final int ANALYSIS_OK_CONTINUE = 1; - public static final int ANALYSIS_OK_FINAL = 2; - - public static final int RADIO_LEVEL = 0; - public static final int MAC_LEVEL = 1; - public static final int NETWORK_LEVEL = 2; - public static final int APPLICATION_LEVEL = 3; - - public static class Packet { - byte[] data; - int pos; - int level; - /* size = length - consumed bytes at tail */ - int size; - - /* L2 addresseses */ - byte[] llsender; - byte[] llreceiver; + public static final int ANALYSIS_FAILED = -1; + public static final int ANALYSIS_OK_CONTINUE = 1; + public static final int ANALYSIS_OK_FINAL = 2; - byte lastDispatch = 0; - - public Packet(byte[] data, int level) { - this.level = level; - this.data = data; - this.size = data.length; - } + public static final int RADIO_LEVEL = 0; + public static final int MAC_LEVEL = 1; + public static final int NETWORK_LEVEL = 2; + public static final int APPLICATION_LEVEL = 3; + public static class Packet { - public void consumeBytesStart(int bytes) { - pos += bytes; - } + byte[] data; + int pos; + int level; + /* size = length - consumed bytes at tail */ + int size; - public void consumeBytesEnd(int bytes) { - size -= bytes; - } - - - public boolean hasMoreData() { - return size > pos; - } - - public int size() { - return size - pos; - } - - public byte get(int index) { - if (index >= size) return 0; - return data[pos + index]; - } + /* L2 addresseses */ + byte[] llsender; + byte[] llreceiver; - public int getInt(int index, int size) { - int value = 0; - for (int i = 0; i < size; i++) { - value = (value << 8) + get(index + i); - } - return value; - } + byte lastDispatch = 0; - - public byte[] getPayload() { - byte[] pload = new byte[size - pos]; - System.arraycopy(data, pos, pload, 0, pload.length); - return pload; - } + public Packet(byte[] data, int level) { + this.level = level; + this.data = data.clone(); + this.size = data.length; + } - public void copy(int srcpos, byte[] arr, int pos, int len) { - for (int i = 0; i < len; i++) { - arr[pos + i] = get(srcpos + i); - } - } + public void consumeBytesStart(int bytes) { + pos += bytes; + } - public byte[] getLLSender() { - return llsender; - } + public void consumeBytesEnd(int bytes) { + size -= bytes; + } - public byte[] getLLReceiver() { - return llreceiver; - } - }; - - public abstract boolean matchPacket(Packet packet); - - public abstract int analyzePacket(Packet packet, StringBuffer brief, StringBuffer verbose); -} \ No newline at end of file + public boolean hasMoreData() { + return size > pos; + } + + public int size() { + return size - pos; + } + + public byte get(int index) { + if (index >= size) return 0; + return data[pos + index]; + } + + public int getInt(int index, int size) { + int value = 0; + for (int i = 0; i < size; i++) { + value = (value << 8) + (get(index + i) & 0xFF); + } + return value; + } + + public byte[] getPayload() { + byte[] pload = new byte[size - pos]; + System.arraycopy(data, pos, pload, 0, pload.length); + return pload; + } + + public void copy(int srcpos, byte[] arr, int pos, int len) { + for (int i = 0; i < len; i++) { + arr[pos + i] = get(srcpos + i); + } + } + + public byte[] getLLSender() { + return llsender; + } + + public byte[] getLLReceiver() { + return llreceiver; + } + }; + + public abstract boolean matchPacket(Packet packet); + + public abstract int analyzePacket(Packet packet, StringBuilder brief, StringBuilder verbose); +} diff --git a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PcapExporter.java b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PcapExporter.java index d0fa0624f..eb9a61690 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PcapExporter.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/analyzers/PcapExporter.java @@ -1,63 +1,63 @@ package org.contikios.cooja.plugins.analyzers; import java.io.DataOutputStream; -import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.FileWriter; import java.io.IOException; import java.io.File; +import org.apache.log4j.Logger; public class PcapExporter { + private static final Logger logger = Logger.getLogger(PcapExporter.class); - DataOutputStream out; - - public PcapExporter() throws IOException { - } - - public void openPcap(File pcapFile) throws IOException { - if ( out != null ) { - closePcap(); - } - if ( pcapFile == null ) { - /* pcap file not specified, use default file name */ - pcapFile = new File("radiolog-" + System.currentTimeMillis() + ".pcap"); - } - out = new DataOutputStream(new FileOutputStream(pcapFile)); - /* pcap header */ - out.writeInt(0xa1b2c3d4); - out.writeShort(0x0002); - out.writeShort(0x0004); - out.writeInt(0); - out.writeInt(0); - out.writeInt(4096); - out.writeInt(195); /* 195 for LINKTYPE_IEEE802_15_4 */ - out.flush(); - System.out.println("Opened pcap file " + pcapFile); - } - public void closePcap() throws IOException { - out.close(); - out = null; - } + DataOutputStream out; - public void exportPacketData(byte[] data) throws IOException { - if (out == null) { - /* pcap file never set, open default */ - openPcap(null); - } - try { - /* pcap packet header */ - out.writeInt((int) (System.currentTimeMillis() / 1000)); - out.writeInt((int) ((System.currentTimeMillis() % 1000) * 1000)); - out.writeInt(data.length); - out.writeInt(data.length); - /* and the data */ - out.write(data); - out.flush(); - } catch (Exception e) { - e.printStackTrace(); - } + public PcapExporter() throws IOException { + } + + public void openPcap(File pcapFile) throws IOException { + if (out != null) { + closePcap(); } - - - + if (pcapFile == null) { + /* pcap file not specified, use default file name */ + pcapFile = new File("radiolog-" + System.currentTimeMillis() + ".pcap"); + } + out = new DataOutputStream(new FileOutputStream(pcapFile)); + /* pcap header */ + out.writeInt(0xa1b2c3d4); + out.writeShort(0x0002); + out.writeShort(0x0004); + out.writeInt(0); + out.writeInt(0); + out.writeInt(4096); + out.writeInt(195); /* 195 for LINKTYPE_IEEE802_15_4 */ + + out.flush(); + logger.info("Opened pcap file " + pcapFile); + } + + public void closePcap() throws IOException { + out.close(); + out = null; + } + + public void exportPacketData(byte[] data) throws IOException { + if (out == null) { + /* pcap file never set, open default */ + openPcap(null); + } + try { + /* pcap packet header */ + out.writeInt((int) (System.currentTimeMillis() / 1000)); + out.writeInt((int) ((System.currentTimeMillis() % 1000) * 1000)); + out.writeInt(data.length); + out.writeInt(data.length); + /* and the data */ + out.write(data); + out.flush(); + } catch (Exception e) { + logger.error(e); + } + } + } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/skins/AddressVisualizerSkin.java b/tools/cooja/java/org/contikios/cooja/plugins/skins/AddressVisualizerSkin.java index e8dbefd02..609b2e771 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/skins/AddressVisualizerSkin.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/skins/AddressVisualizerSkin.java @@ -46,7 +46,6 @@ import org.contikios.cooja.ClassDescription; import org.contikios.cooja.Mote; import org.contikios.cooja.Simulation; import org.contikios.cooja.SimEventCentral.MoteCountListener; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.interfaces.Position; import org.contikios.cooja.interfaces.RimeAddress; @@ -128,8 +127,11 @@ public class AddressVisualizerSkin implements VisualizerSkin { private static String getMoteString(Mote mote) { IPAddress ipAddr = mote.getInterfaces().getIPAddress(); - if (ipAddr != null && ipAddr.getIPString() != null) { - return ipAddr.getIPString(); + if ((ipAddr != null) && (ipAddr.hasIP())) { + if (ipAddr.getLocalIP() == null) { + return ""; + } + return ipAddr.getLocalIP().toString(); } RimeAddress rimeAddr = mote.getInterfaces().getRimeAddress(); diff --git a/tools/cooja/java/org/contikios/cooja/plugins/skins/TrafficVisualizerSkin.java b/tools/cooja/java/org/contikios/cooja/plugins/skins/TrafficVisualizerSkin.java index d632ae094..c98c51222 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/skins/TrafficVisualizerSkin.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/skins/TrafficVisualizerSkin.java @@ -33,7 +33,9 @@ import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.awt.Polygon; -import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; import java.util.Observable; import java.util.Observer; @@ -60,54 +62,51 @@ import org.contikios.cooja.radiomediums.AbstractRadioMedium; @ClassDescription("Radio traffic") @SupportedArguments(radioMediums = {AbstractRadioMedium.class}) public class TrafficVisualizerSkin implements VisualizerSkin { - private static Logger logger = Logger.getLogger(TrafficVisualizerSkin.class); + private static final Logger logger = Logger.getLogger(TrafficVisualizerSkin.class); private final int MAX_HISTORY_SIZE = 200; + private final float TRANSMITTED_COLOR_RGB[] = Color.BLUE.getRGBColorComponents(null); + private final float UNTRANSMITTED_COLOR_RGB[] = Color.RED.getRGBColorComponents(null); private boolean active = false; private Simulation simulation = null; private Visualizer visualizer = null; private AbstractRadioMedium radioMedium = null; - private ArrayList historyList = new ArrayList(); - private RadioConnectionArrow[] history = null; + private final List historyList = new LinkedList<>(); private Observer radioMediumObserver = new Observer() { + @Override public void update(Observable obs, Object obj) { RadioConnection last = radioMedium.getLastConnection(); if (last != null && historyList.size() < MAX_HISTORY_SIZE) { - historyList.add(new RadioConnectionArrow(last)); - history = historyList.toArray(new RadioConnectionArrow[0]); - visualizer.repaint(500); + synchronized(historyList) { + historyList.add(new RadioConnectionArrow(last)); + visualizer.repaint(500); + } } } }; - private TimeEvent ageArrowsTimeEvent = new TimeEvent(0) { + + private final TimeEvent ageArrowsTimeEvent = new TimeEvent(0) { + @Override public void execute(long t) { if (!active) { return; } if (historyList.size() > 0) { - boolean hasOld = false; - /* Increase age */ - for (RadioConnectionArrow connArrow : historyList) { - connArrow.increaseAge(); - if(connArrow.getAge() >= connArrow.getMaxAge()) { - hasOld = true; - } - } - - /* Remove too old arrows */ - if (hasOld) { - RadioConnectionArrow[] historyArr = historyList.toArray(new RadioConnectionArrow[0]); - for (RadioConnectionArrow connArrow : historyArr) { - if(connArrow.getAge() >= connArrow.getMaxAge()) { - historyList.remove(connArrow); + synchronized (historyList) { + /* Increase age and remove too old arrows */ + Iterator iter = historyList.iterator(); + while (iter.hasNext()) { + RadioConnectionArrow rca = iter.next(); + /* Try to increase age and remove if max age was reached */ + if (!rca.increaseAge()) { + iter.remove(); } } - historyArr = historyList.toArray(new RadioConnectionArrow[0]); } visualizer.repaint(500); @@ -118,6 +117,7 @@ public class TrafficVisualizerSkin implements VisualizerSkin { } }; + @Override public void setActive(final Simulation simulation, Visualizer vis) { this.radioMedium = (AbstractRadioMedium) simulation.getRadioMedium(); this.simulation = simulation; @@ -125,12 +125,12 @@ public class TrafficVisualizerSkin implements VisualizerSkin { this.active = true; simulation.invokeSimulationThread(new Runnable() { + @Override public void run() { historyList.clear(); - history = null; /* Start observing radio medium for transmissions */ - radioMedium.addRadioMediumObserver(radioMediumObserver); + radioMedium.addRadioTransmissionObserver(radioMediumObserver); /* Fade away arrows */ simulation.scheduleEvent(ageArrowsTimeEvent, simulation.getSimulationTime() + 100*Simulation.MILLISECOND); @@ -138,6 +138,7 @@ public class TrafficVisualizerSkin implements VisualizerSkin { }); } + @Override public void setInactive() { this.active = false; if (simulation == null) { @@ -146,14 +147,15 @@ public class TrafficVisualizerSkin implements VisualizerSkin { } /* Stop observing radio medium */ - radioMedium.deleteRadioMediumObserver(radioMediumObserver); + radioMedium.deleteRadioTransmissionObserver(radioMediumObserver); } + @Override public Color[] getColorOf(Mote mote) { return null; } - private Polygon arrowPoly = new Polygon(); + private final Polygon arrowPoly = new Polygon(); private void drawArrow(Graphics g, int xSource, int ySource, int xDest, int yDest, int delta) { double dx = xSource - xDest; double dy = ySource - yDest; @@ -183,52 +185,81 @@ public class TrafficVisualizerSkin implements VisualizerSkin { return (int)(0.5 + len * Math.sin(dir)); } + @Override public void paintBeforeMotes(Graphics g) { - RadioConnectionArrow[] historyCopy = history; - if (historyCopy == null) { - return; - } - for (RadioConnectionArrow connArrow : historyCopy) { - float colorHistoryIndex = (float)connArrow.getAge() / (float)connArrow.getMaxAge(); - g.setColor(new Color(colorHistoryIndex, colorHistoryIndex, 1.0f)); - Radio source = connArrow.getConnection().getSource(); - Point sourcePoint = visualizer.transformPositionToPixel(source.getPosition()); - for (Radio destRadio : connArrow.getConnection().getDestinations()) { - Position destPos = destRadio.getPosition(); - Point destPoint = visualizer.transformPositionToPixel(destPos); - drawArrow(g, sourcePoint.x, sourcePoint.y, destPoint.x, destPoint.y, 8); + synchronized (historyList) { + for (RadioConnectionArrow connArrow : historyList) { + float colorHistoryIndex = 1.0f - connArrow.getAge(); + Radio source = connArrow.getConnection().getSource(); + Point sourcePoint = visualizer.transformPositionToPixel(source.getPosition()); + /* If there is no destination, paint red circles to indicate untransmitted message */ + if (connArrow.getConnection().getDestinations().length == 0) { + g.setColor(new Color(UNTRANSMITTED_COLOR_RGB[0], UNTRANSMITTED_COLOR_RGB[1], UNTRANSMITTED_COLOR_RGB[2], colorHistoryIndex)); + g.drawOval(sourcePoint.x - 20, sourcePoint.y - 20, 40, 40); + g.drawOval(sourcePoint.x - 30, sourcePoint.y - 30, 60, 60); + continue; + } + g.setColor(new Color(TRANSMITTED_COLOR_RGB[0], TRANSMITTED_COLOR_RGB[1], TRANSMITTED_COLOR_RGB[2], colorHistoryIndex)); + for (Radio destRadio : connArrow.getConnection().getDestinations()) { + Position destPos = destRadio.getPosition(); + Point destPoint = visualizer.transformPositionToPixel(destPos); + drawArrow(g, sourcePoint.x, sourcePoint.y, destPoint.x, destPoint.y, 8); + } } } } + @Override public void paintAfterMotes(Graphics g) { } + @Override public Visualizer getVisualizer() { return visualizer; } private static class RadioConnectionArrow { - private RadioConnection conn; - private int age; + private static final int MAX_AGE = 10; + private final RadioConnection conn; + private int age; + RadioConnectionArrow(RadioConnection conn) { this.conn = conn; this.age = 0; } - public void increaseAge() { + + /** + * Increases age of radio connection if possible or indicates max age. + * + * @return true if max age was not reached yet, false, if max age was + * reached + */ + public boolean increaseAge() { if (age < MAX_AGE) { age++; + return true; + } else { + return false; } } - public int getAge() { - return age; + + /** + * Returns relative age of radio connection + * + * @return Relative age (0.0 - 1.0) + */ + public float getAge() { + return (float) age / (float) MAX_AGE; } + + /** + * Returns radio connection + * + * @return radio connection + */ public RadioConnection getConnection() { return conn; } - public int getMaxAge() { - return MAX_AGE; - } } } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/skins/UDGMVisualizerSkin.java b/tools/cooja/java/org/contikios/cooja/plugins/skins/UDGMVisualizerSkin.java index 45f7a826a..144760405 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/skins/UDGMVisualizerSkin.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/skins/UDGMVisualizerSkin.java @@ -263,9 +263,6 @@ public class UDGMVisualizerSkin implements VisualizerSkin { @Override public Color[] getColorOf(Mote mote) { - if (visualizer.getSelectedMotes().contains(mote)) { - return new Color[]{Color.CYAN}; - } return null; } diff --git a/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java b/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java index 742dbeaf3..a31b42b3d 100644 --- a/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java +++ b/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java @@ -31,8 +31,13 @@ package org.contikios.cooja.radiomediums; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; import java.util.Observable; import java.util.Observer; +import java.util.WeakHashMap; import org.apache.log4j.Logger; @@ -44,6 +49,9 @@ import org.contikios.cooja.Simulation; import org.contikios.cooja.TimeEvent; import org.contikios.cooja.interfaces.CustomDataRadio; import org.contikios.cooja.interfaces.Radio; +import org.contikios.cooja.util.ScnObservable; +import org.jdom.Element; + /** * Abstract radio medium provides basic functionality for implementing radio @@ -68,6 +76,8 @@ public abstract class AbstractRadioMedium extends RadioMedium { public static final double SS_NOTHING = -100; public static final double SS_STRONG = -10; public static final double SS_WEAK = -95; + protected Map baseRssi = java.util.Collections.synchronizedMap(new HashMap()); + protected Map sendRssi = java.util.Collections.synchronizedMap(new HashMap()); private ArrayList registeredRadios = new ArrayList(); @@ -82,17 +92,13 @@ public abstract class AbstractRadioMedium extends RadioMedium { public int COUNTER_RX = 0; public int COUNTER_INTERFERED = 0; - public class RadioMediumObservable extends Observable { - public void setRadioMediumChanged() { - setChanged(); - } - public void setRadioMediumChangedAndNotify() { - setChanged(); - notifyObservers(); - } - } - - private RadioMediumObservable radioMediumObservable = new RadioMediumObservable(); + /** + * Two Observables to observe the radioMedium and radioTransmissions + * @see addRadioTransmissionObserver + * @see addRadioMediumObserver + */ + protected ScnObservable radioMediumObservable = new ScnObservable(); + protected ScnObservable radioTransmissionObservable = new ScnObservable(); /** * This constructor should always be called from implemented radio mediums. @@ -136,7 +142,7 @@ public abstract class AbstractRadioMedium extends RadioMedium { /* Reset signal strengths */ for (Radio radio : getRegisteredRadios()) { - radio.setCurrentSignalStrength(SS_NOTHING); + radio.setCurrentSignalStrength(getBaseRssi(radio)); } /* Set signal strength to strong on destinations */ @@ -228,8 +234,9 @@ public abstract class AbstractRadioMedium extends RadioMedium { case RECEPTION_STARTED: case RECEPTION_INTERFERED: case RECEPTION_FINISHED: + break; + case UNKNOWN: - return; case HW_ON: { /* Update signal strengths */ updateSignalStrengths(); @@ -279,12 +286,12 @@ public abstract class AbstractRadioMedium extends RadioMedium { /* Notify observers */ lastConnection = null; - radioMediumObservable.setRadioMediumChangedAndNotify(); + radioTransmissionObservable.setChangedAndNotify(); } break; case TRANSMISSION_FINISHED: { /* Remove radio connection */ - + /* Connection */ RadioConnection connection = getActiveConnectionFrom(radio); if (connection == null) { @@ -314,14 +321,17 @@ public abstract class AbstractRadioMedium extends RadioMedium { COUNTER_RX += connection.getDestinations().length; COUNTER_INTERFERED += connection.getInterfered().length; for (Radio intRadio : connection.getInterferedNonDestinations()) { - intRadio.signalReceptionEnd(); + + if (intRadio.isInterfered()) { + intRadio.signalReceptionEnd(); + } } /* Update signal strengths */ updateSignalStrengths(); /* Notify observers */ - radioMediumObservable.setRadioMediumChangedAndNotify(); + radioTransmissionObservable.setChangedAndNotify(); } break; case CUSTOM_DATA_TRANSMITTED: { @@ -336,7 +346,7 @@ public abstract class AbstractRadioMedium extends RadioMedium { /* Custom data object */ Object data = ((CustomDataRadio) radio).getLastCustomDataTransmitted(); if (data == null) { - logger.fatal("No custom data object to forward"); + logger.fatal("No custom data objecTransmissiont to forward"); return; } @@ -434,6 +444,7 @@ public abstract class AbstractRadioMedium extends RadioMedium { registeredRadios.add(radio); radio.addObserver(radioEventsObserver); + radioMediumObservable.setChangedAndNotify(); /* Update signal strengths */ updateSignalStrengths(); @@ -450,14 +461,108 @@ public abstract class AbstractRadioMedium extends RadioMedium { removeFromActiveConnections(radio); + radioMediumObservable.setChangedAndNotify(); + /* Update signal strengths */ updateSignalStrengths(); } + /** + * Get the RSSI value that is set when there is "silence" + * + * @param radio + * The radio to get the base RSSI for + * @return The base RSSI value; Default: SS_NOTHING + */ + public double getBaseRssi(Radio radio) { + Double rssi = baseRssi.get(radio); + if (rssi == null) { + rssi = SS_NOTHING; + } + return rssi; + } + + /** + * Set the base RSSI for a radio. This value is set when there is "silence" + * + * @param radio + * The radio to set the RSSI value for + * @param rssi + * The RSSI value to set during silence + */ + public void setBaseRssi(Radio radio, double rssi) { + baseRssi.put(radio, rssi); + simulation.invokeSimulationThread(new Runnable() { + @Override + public void run() { + updateSignalStrengths(); + } + }); + } + + + /** + * Get the minimum RSSI value that is set when the radio is sending + * + * @param radio + * The radio to get the send RSSI for + * @return The send RSSI value; Default: SS_STRONG + */ + public double getSendRssi(Radio radio) { + Double rssi = sendRssi.get(radio); + if (rssi == null) { + rssi = SS_STRONG; + } + return rssi; + } + + /** + * Set the send RSSI for a radio. This is the minimum value when the radio is + * sending + * + * @param radio + * The radio to set the RSSI value for + * @param rssi + * The minimum RSSI value to set when sending + */ + public void setSendRssi(Radio radio, double rssi) { + sendRssi.put(radio, rssi); + } + + /** + * Register an observer that gets notified when the radiotransmissions changed. + * E.g. creating new connections. + * This does not include changes in the settings and (de-)registration of radios. + * @see addRadioMediumObserver + * @param observer the Observer to register + */ + public void addRadioTransmissionObserver(Observer observer) { + radioTransmissionObservable.addObserver(observer); + } + + public Observable getRadioTransmissionObservable() { + return radioTransmissionObservable; + } + + public void deleteRadioTransmissionObserver(Observer observer) { + radioTransmissionObservable.deleteObserver(observer); + } + + /** + * Register an observer that gets notified when the radio medium changed. + * This includes changes in the settings and (de-)registration of radios. + * This does not include transmissions, etc as these are part of the radio + * and not the radio medium itself. + * @see addRadioTransmissionObserver + * @param observer the Observer to register + */ public void addRadioMediumObserver(Observer observer) { radioMediumObservable.addObserver(observer); } + /** + * @return the radioMediumObservable + */ public Observable getRadioMediumObservable() { return radioMediumObservable; } @@ -469,5 +574,46 @@ public abstract class AbstractRadioMedium extends RadioMedium { public RadioConnection getLastConnection() { return lastConnection; } + public Collection getConfigXML() { + Collection config = new ArrayList(); + for(Entry ent: baseRssi.entrySet()){ + Element element = new Element("BaseRSSIConfig"); + element.setAttribute("Mote", "" + ent.getKey().getMote().getID()); + element.addContent("" + ent.getValue()); + config.add(element); + } + + for(Entry ent: sendRssi.entrySet()){ + Element element = new Element("SendRSSIConfig"); + element.setAttribute("Mote", "" + ent.getKey().getMote().getID()); + element.addContent("" + ent.getValue()); + config.add(element); + } + + return config; + } + + private Collection delayedConfiguration = null; + + public boolean setConfigXML(final Collection configXML, boolean visAvailable) { + delayedConfiguration = configXML; + return true; + } + + public void simulationFinishedLoading() { + if (delayedConfiguration == null) { + return; + } + + for (Element element : delayedConfiguration) { + if (element.getName().equals("BaseRSSIConfig")) { + Radio r = simulation.getMoteWithID(Integer.parseInt(element.getAttribute("Mote").getValue())).getInterfaces().getRadio(); + setBaseRssi(r, Double.parseDouble(element.getText())); + } else if (element.getName().equals("SendRSSIConfig")) { + Radio r = simulation.getMoteWithID(Integer.parseInt(element.getAttribute("Mote").getValue())).getInterfaces().getRadio(); + setSendRssi(r, Double.parseDouble(element.getText())); + } + } + } } diff --git a/tools/cooja/java/org/contikios/cooja/radiomediums/DGRMDestinationRadio.java b/tools/cooja/java/org/contikios/cooja/radiomediums/DGRMDestinationRadio.java index fb182f2d4..1147890c8 100644 --- a/tools/cooja/java/org/contikios/cooja/radiomediums/DGRMDestinationRadio.java +++ b/tools/cooja/java/org/contikios/cooja/radiomediums/DGRMDestinationRadio.java @@ -42,6 +42,7 @@ public class DGRMDestinationRadio extends DestinationRadio { public double signal = AbstractRadioMedium.SS_STRONG; /* RSSI */ public long delay = 0; /* EXPERIMENTAL: Propagation delay (us). */ public int lqi = 105; + public int channel = -1; /* not set by default */ public DGRMDestinationRadio() { super(); @@ -50,12 +51,17 @@ public class DGRMDestinationRadio extends DestinationRadio { super(dest); } + public int getChannel() { + return channel; + } + protected Object clone() { DGRMDestinationRadio clone = new DGRMDestinationRadio(this.radio); clone.ratio = this.ratio; clone.delay = this.delay; clone.signal = this.signal; clone.lqi = this.lqi; + clone.channel = this.channel; return clone; } @@ -75,10 +81,13 @@ public class DGRMDestinationRadio extends DestinationRadio { element.setText("" + lqi); config.add(element); - element = new Element("delay"); element.setText("" + delay); config.add(element); + + element = new Element("channel"); + element.setText("" + channel); + config.add(element); return config; } @@ -96,6 +105,8 @@ public class DGRMDestinationRadio extends DestinationRadio { lqi = Integer.parseInt(element.getText()); } else if (element.getName().equals("delay")) { delay = Long.parseLong(element.getText()); + } else if (element.getName().equals("channel")) { + channel = Integer.parseInt(element.getText()); } } return true; diff --git a/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java b/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java index 48d90a0f8..15806c389 100644 --- a/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java +++ b/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java @@ -93,8 +93,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium { edges.add(e); requestEdgeAnalysis(); - ((AbstractRadioMedium.RadioMediumObservable) - this.getRadioMediumObservable()).setRadioMediumChangedAndNotify(); + radioTransmissionObservable.setChangedAndNotify(); } public void removeEdge(Edge edge) { @@ -105,16 +104,15 @@ public class DirectedGraphMedium extends AbstractRadioMedium { edges.remove(edge); requestEdgeAnalysis(); - ((AbstractRadioMedium.RadioMediumObservable) - this.getRadioMediumObservable()).setRadioMediumChangedAndNotify(); + + radioTransmissionObservable.setChangedAndNotify(); } public void clearEdges() { edges.clear(); requestEdgeAnalysis(); - ((AbstractRadioMedium.RadioMediumObservable) - this.getRadioMediumObservable()).setRadioMediumChangedAndNotify(); + radioTransmissionObservable.setChangedAndNotify(); } public Edge[] getEdges() { @@ -144,26 +142,41 @@ public class DirectedGraphMedium extends AbstractRadioMedium { } } + + public void updateSignalStrengths() { - /* Reset signal strengths */ + /* Reset signal strengths (Default: SS_NOTHING) */ for (Radio radio : getRegisteredRadios()) { - radio.setCurrentSignalStrength(SS_NOTHING); + radio.setCurrentSignalStrength(getBaseRssi(radio)); } /* Set signal strengths */ RadioConnection[] conns = getActiveConnections(); for (RadioConnection conn : conns) { - /* When sending RSSI is Strong! - * TODO: is this reasonable + /* + * Set sending RSSI. (Default: SS_STRONG) */ - if (conn.getSource().getCurrentSignalStrength() < SS_STRONG) { - conn.getSource().setCurrentSignalStrength(SS_STRONG); + if (conn.getSource().getCurrentSignalStrength() < getSendRssi(conn.getSource())) { + conn.getSource().setCurrentSignalStrength(getSendRssi(conn.getSource())); } //Maximum reception signal of all possible radios received DGRMDestinationRadio dstRadios[] = getPotentialDestinations(conn.getSource()); if (dstRadios == null) continue; for (DGRMDestinationRadio dstRadio : dstRadios) { + + int activeSourceChannel = conn.getSource().getChannel(); + int edgeChannel = dstRadio.channel; + int activeDstChannel = dstRadio.radio.getChannel(); + if (activeSourceChannel != -1) { + if (edgeChannel != -1 && activeSourceChannel != edgeChannel) { + continue; + } + if (activeDstChannel != -1 && activeSourceChannel != activeDstChannel) { + continue; + } + } + if (dstRadio.radio.getCurrentSignalStrength() < dstRadio.signal) { dstRadio.radio.setCurrentSignalStrength(dstRadio.signal); } @@ -209,6 +222,9 @@ public class DirectedGraphMedium extends AbstractRadioMedium { this.edgesTable = arrTable; edgesDirty = false; + + /* Radio Medium changed here so notify Observers */ + radioMediumObservable.setChangedAndNotify(); } /** @@ -245,13 +261,27 @@ public class DirectedGraphMedium extends AbstractRadioMedium { /*logger.info(source + ": " + destinations.length + " potential destinations");*/ for (DGRMDestinationRadio dest: destinations) { - + if (dest.radio == source) { /* Fail: cannot receive our own transmission */ /*logger.info(source + ": Fail, receiver is sender");*/ continue; } + int srcc = source.getChannel(); + int dstc = dest.radio.getChannel(); + int edgeChannel = dest.getChannel(); + + if (edgeChannel >= 0 && dstc >= 0 && edgeChannel != dstc) { + /* Fail: the edge is configured for a different radio channel */ + continue; + } + + if (srcc >= 0 && dstc >= 0 && srcc != dstc) { + /* Fail: radios are on different (but configured) channels */ + newConn.addInterfered(dest.radio); + continue; + } if (!dest.radio.isRadioOn()) { /* Fail: radio is off */ @@ -266,14 +296,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium { newConn.addInterfered(dest.radio); continue; } - - int srcc = source.getChannel(); - int dstc = dest.radio.getChannel(); - if ( srcc >= 0 && dstc >= 0 && srcc != dstc) { - /* Fail: radios are on different (but configured) channels */ - continue; - } - + if (dest.radio.isReceiving()) { /* Fail: radio is already actively receiving */ /*logger.info(source + ": Fail, receiving");*/ @@ -311,10 +334,10 @@ public class DirectedGraphMedium extends AbstractRadioMedium { } public Collection getConfigXML() { - ArrayList config = new ArrayList(); - Element element; + Collection config = super.getConfigXML(); for (Edge edge: getEdges()) { + Element element; element = new Element("edge"); element.addContent(edge.getConfigXML()); config.add(element); @@ -325,6 +348,8 @@ public class DirectedGraphMedium extends AbstractRadioMedium { private Collection delayedConfiguration = null; public boolean setConfigXML(Collection configXML, boolean visAvailable) { + super.setConfigXML(configXML, visAvailable); + random = simulation.getRandomGenerator(); /* Wait until simulation has been loaded */ @@ -337,6 +362,8 @@ public void simulationFinishedLoading() { return; } + super.simulationFinishedLoading(); + boolean oldConfig = false; for (Element element : delayedConfiguration) { if (element.getName().equals("edge")) { diff --git a/tools/cooja/java/org/contikios/cooja/radiomediums/UDGM.java b/tools/cooja/java/org/contikios/cooja/radiomediums/UDGM.java index c469bb32e..9d7b752fc 100644 --- a/tools/cooja/java/org/contikios/cooja/radiomediums/UDGM.java +++ b/tools/cooja/java/org/contikios/cooja/radiomediums/UDGM.java @@ -192,6 +192,13 @@ public class UDGM extends AbstractRadioMedium { if (sender.getChannel() >= 0 && recv.getChannel() >= 0 && sender.getChannel() != recv.getChannel()) { + + /* Add the connection in a dormant state; + it will be activated later when the radio will be + turned on and switched to the right channel. This behavior + is consistent with the case when receiver is turned off. */ + newConnection.addInterfered(recv); + continue; } Position recvPos = recv.getPosition(); @@ -276,7 +283,7 @@ public class UDGM extends AbstractRadioMedium { /* Reset signal strengths */ for (Radio radio : getRegisteredRadios()) { - radio.setCurrentSignalStrength(SS_NOTHING); + radio.setCurrentSignalStrength(getBaseRssi(radio)); } /* Set signal strength to below strong on destinations */ @@ -341,7 +348,7 @@ public class UDGM extends AbstractRadioMedium { } public Collection getConfigXML() { - ArrayList config = new ArrayList(); + Collection config = super.getConfigXML(); Element element; /* Transmitting range */ @@ -368,6 +375,7 @@ public class UDGM extends AbstractRadioMedium { } public boolean setConfigXML(Collection configXML, boolean visAvailable) { + super.setConfigXML(configXML, visAvailable); for (Element element : configXML) { if (element.getName().equals("transmitting_range")) { TRANSMITTING_RANGE = Double.parseDouble(element.getText()); diff --git a/tools/cooja/java/org/contikios/cooja/util/CCITT_CRC.java b/tools/cooja/java/org/contikios/cooja/util/CCITT_CRC.java new file mode 100644 index 000000000..3574eb574 --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/util/CCITT_CRC.java @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2008, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of MSPSim. + * + * ----------------------------------------------------------------- + * + * Author : Joakim Eriksson + */ + +package org.contikios.cooja.util; + +/* basic CRC-CCITT code */ +public class CCITT_CRC { + int crc; + + public int getCRC() { + return crc; + } + + /* this will only work with zero... */ + public void setCRC(int val) { + crc = val; + } + + public void clr() { + crc = 0xffff; + } + + public void addBitrev(int data) { + add(bitrev(data)); + } + + public int getCRCLow() { + return bitrev(crc & 0xff); + } + + public int getCRCHi() { + return bitrev(crc >> 8); + } + + public int add(int data) { + int newCrc = ((crc >> 8) & 0xff) | (crc << 8) & 0xffff; + newCrc ^= (data & 0xff); + newCrc ^= (newCrc & 0xff) >> 4; + newCrc ^= (newCrc << 12) & 0xffff; + newCrc ^= (newCrc & 0xff) << 5; + crc = newCrc & 0xffff; + return crc; + } + + public int getCRCBitrev() { + return getCRCLow() + (getCRCHi() << 8); + } + + public static final String hex = "0123456789abcdef"; + + private static int bitrev(int data) { + return ((data << 7) & 0x80) | ((data << 5) & 0x40) | + (data << 3) & 0x20 | (data << 1) & 0x10 | + (data >> 7) & 0x01 | (data >> 5) & 0x02 | + (data >> 3) & 0x04 | (data >> 1) & 0x08; + } +} diff --git a/tools/cooja/java/org/contikios/cooja/util/ExecuteJAR.java b/tools/cooja/java/org/contikios/cooja/util/ExecuteJAR.java index 46dabf38d..57d1fb4f6 100644 --- a/tools/cooja/java/org/contikios/cooja/util/ExecuteJAR.java +++ b/tools/cooja/java/org/contikios/cooja/util/ExecuteJAR.java @@ -54,9 +54,10 @@ import org.contikios.cooja.Plugin; import org.contikios.cooja.ProjectConfig; import org.contikios.cooja.Simulation; import org.contikios.cooja.dialogs.CompileContiki; -import org.contikios.cooja.dialogs.MessageList; -import org.contikios.cooja.dialogs.MessageList.MessageContainer; +import org.contikios.cooja.dialogs.MessageContainer; +import org.contikios.cooja.dialogs.MessageListUI; import org.contikios.cooja.plugins.ScriptRunner; +import org.contikios.cooja.PluginType; public class ExecuteJAR { private static Logger logger = Logger.getLogger(ExecuteJAR.class); @@ -187,7 +188,15 @@ public class ExecuteJAR { logger.info("Starting simulation"); Cooja.setLookAndFeel(); - Cooja.quickStartSimulationConfig(new File(executeDir, SIMCONFIG_FILENAME), false, null); + Simulation sim = Cooja.quickStartSimulationConfig(new File(executeDir, SIMCONFIG_FILENAME), false, null); + if (sim != null){ + /* Set simulation speed to maximum and start simulation */ + sim.setSpeedLimit(null); + sim.startSimulation(); + } else { + logger.fatal("Cannot load simulation, aborting"); + System.exit(1); + } } /** @@ -222,18 +231,18 @@ public class ExecuteJAR { logger.info("Checking mote types: '" + Cooja.getDescriptionOf(t.getClass()) + "'"); } - /* Check dependencies: Contiki Test Editor */ - boolean hasTestEditor = false; + /* Check dependencies: Contiki Control Plugin */ + boolean hasController = false; for (Plugin startedPlugin : gui.getStartedPlugins()) { - if (startedPlugin instanceof ScriptRunner) { - hasTestEditor = true; - break; + int pluginType = startedPlugin.getClass().getAnnotation(PluginType.class).value(); + if (pluginType == PluginType.SIM_CONTROL_PLUGIN) { + hasController = true; } } - logger.info("Checking that Contiki Test Editor exists: " + hasTestEditor); - if (!hasTestEditor) { + logger.info("Checking that Contiki Control Plugin exists: " + hasController); + if (!hasController) { throw new RuntimeException( - "The simulation needs at least one active Contiki Test Editor plugin.\n" + + "The simulation needs at least one active control plugin.\n" + "The plugin is needed to control the non-visualized simulation." ); } @@ -284,7 +293,8 @@ public class ExecuteJAR { /* Unpacking COOJA core JARs */ String[] coreJARs = new String[] { - "tools/cooja/lib/jdom.jar", "tools/cooja/lib/log4j.jar", "tools/cooja/dist/cooja.jar" + "tools/cooja/lib/jdom.jar", "tools/cooja/lib/log4j.jar", + "tools/cooja/dist/cooja.jar", "tools/cooja/lib/jsyntaxpane.jar" }; for (String jar: coreJARs) { File jarFile = new File(Cooja.getExternalToolsSetting("PATH_CONTIKI"), jar); @@ -405,7 +415,7 @@ public class ExecuteJAR { } logger.info("Building executable JAR: " + outputFile); - MessageList errors = new MessageList(); + MessageListUI errors = new MessageListUI(); try { CompileContiki.compile( "jar cfm " + outputFile.getAbsolutePath() + " manifest.tmp .", diff --git a/tools/cooja/java/org/contikios/cooja/util/IPUtils.java b/tools/cooja/java/org/contikios/cooja/util/IPUtils.java new file mode 100644 index 000000000..18dae27e1 --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/util/IPUtils.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2014, TU Braunschweig + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ +package org.contikios.cooja.util; + +/** + * Holds some IP byte to string conversion functions etc. + * + * @author Enrico Jorns + */ +public class IPUtils { + + /** + * Convert IPv6 Byte-array in compressed IPv6-Address String. + * + * @param ip byte array holding IPv6 address information + * @return String representation + */ + public static String getCompressedIPv6AddressString(byte[] ip) { + StringBuilder build = new StringBuilder(); + IPUtils.getCompressedIPv6AddressString(build, ip); + return build.toString(); + } + + /** + * Convert IPv6 Byte-array in compressed IPv6-Address String. + * + * @param builder Buffer to append to + * @param ip byte array holding IPv6 address information + */ + public static void getCompressedIPv6AddressString(StringBuilder builder, byte[] ip) { + int startMax = 0, startCurr = 0, zeroMax = 0, zeroCurr = 0; + + if (ip.length != 16) { + throw new IllegalArgumentException("Invalid array length: " + ip.length); + } + + for (int i = 0; i < 16; i += 2) { + if ((ip[i] | ip[i + 1]) == 0x00) { + if (zeroCurr == 0) { + startCurr = i; + } + zeroCurr++; + } + else { + if (zeroCurr > zeroMax) { + zeroMax = zeroCurr; + startMax = startCurr; + zeroCurr = 0; + } + } + } + if (zeroCurr > zeroMax) { + zeroMax = zeroCurr; + startMax = startCurr; + } + + short a; + for (int i = 0, f = 0; i < 16; i += 2) { + a = (short) (((ip[i] & 0xFF) << 8) + (ip[i + 1] & 0xFF)); + if ((i >= startMax) && (i < startMax + zeroMax * 2)) { + if (f++ == 0) { + builder.append("::"); + } + } + else { + if (f > 0) { + f = -1; + } + else if (i > 0) { + builder.append(':'); + } + builder.append(String.format("%x", a)); + } + } + } + + /** + * Convert IPv6 Byte-array in uncompressed IPv6-Address String. + * + * @param ip byte array holding IPv6 address information + * @return uncompressed IPv6 representation string + */ + public static String getUncompressedIPv6AddressString(byte[] ip) { + StringBuilder ipBuilder = new StringBuilder(); + IPUtils.getUncompressedIPv6AddressString(ipBuilder, ip); + return ipBuilder.toString(); + } + + /** + * Convert IPv6 Byte-array in uncompressed IPv6-Address String. + * + * @param builder StringBuilder to append address to + * @param ip byte array holding IPv6 address information + */ + public static void getUncompressedIPv6AddressString(StringBuilder builder, byte[] ip) { + for (int i = 0; i < 14; i += 2) { + builder.append(String.format("%02x%02x:", 0xFF & ip[i + 0], 0xFF & ip[i + 1])); + } + builder.append(String.format("%02x%02x", 0xFF & ip[14], 0xFF & ip[15])); + } + + /** + * Convert IPv4 Byte-array to IPv4-Address String. + * + * @param ip byte array holding IPv4 address information + * @return IPv4 representation string + */ + public static String getIPv4AddressString(byte[] ip) { + + if (ip.length != 4) { + throw new IllegalArgumentException("Invalid array length: " + ip.length); + } + + StringBuilder ipBuilder = new StringBuilder(); + for (int i = 0; i < 3; i++) { + ipBuilder.append(0xFF & ip[i]); + ipBuilder.append('.'); + } + ipBuilder.append(0xFF & ip[3]); + return ipBuilder.toString(); + } + +} diff --git a/tools/cooja/java/org/contikios/cooja/util/MoteSerialSocketConnection.java b/tools/cooja/java/org/contikios/cooja/util/MoteSerialSocketConnection.java index c86c03769..75e796c48 100644 --- a/tools/cooja/java/org/contikios/cooja/util/MoteSerialSocketConnection.java +++ b/tools/cooja/java/org/contikios/cooja/util/MoteSerialSocketConnection.java @@ -1,190 +1,190 @@ -/* - * Copyright (c) 2011, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - */ - -package org.contikios.cooja.util; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.net.Socket; -import java.util.ArrayList; -import java.util.Observable; -import java.util.Observer; - -import org.apache.log4j.Logger; - -import org.contikios.cooja.Mote; -import org.contikios.cooja.interfaces.SerialPort; - -/** - * Help class for forwarding serial data between a mote and a socket. - * - * @author Fredrik Osterlind - */ -public class MoteSerialSocketConnection { - private static final long serialVersionUID = 1L; - private static Logger logger = Logger.getLogger(MoteSerialSocketConnection.class); - - private boolean isConnected = false; - public int toMote = 0, toSocket = 0; - - private SerialPort motePort; - private Observer moteObserver; - - private Socket socket; - private DataInputStream socketIn; - private DataOutputStream socketOut; - - private ArrayList listeners = null; - - public MoteSerialSocketConnection(Mote mote, String server, int serverPort) - throws IOException { - isConnected = true; - - /* Simulated -> socket */ - motePort = (SerialPort) mote.getInterfaces().getLog(); - motePort.addSerialDataObserver(moteObserver = new Observer() { - public void update(Observable obs, Object obj) { - try { - if (socketOut == null) { - return; - } - socketOut.write(motePort.getLastSerialData()); - socketOut.flush(); - toSocket++; - - if (listeners != null) { - for (MoteSerialSocketConnectionListener dl: listeners) { - dl.dataTransferred(MoteSerialSocketConnection.this, toMote, toSocket, motePort.getLastSerialData()); - } - } - } catch (IOException e) { - e.printStackTrace(); - logger.fatal("Write to socket error: " + e.getMessage(), e); - cleanup(); - } - } - }); - - /* Socket -> simulated */ - socket = new Socket(server, serverPort); - socketIn = new DataInputStream(socket.getInputStream()); - socketOut = new DataOutputStream(socket.getOutputStream()); - socketOut.flush(); - Thread socketThread = new Thread(new Runnable() { - public void run() { - int numRead = 0; - byte[] data = new byte[1024]; - while (true) { - numRead = -1; - try { - numRead = socketIn.read(data); - } catch (IOException e) { - e.printStackTrace(); - return; - } - - if (numRead >= 0) { - for (int i = 0; i < numRead; i++) { - toMote ++; - motePort.writeByte(data[i]); - if (listeners != null) { - for (MoteSerialSocketConnectionListener dl: listeners) { - dl.dataTransferred(MoteSerialSocketConnection.this, toMote, toSocket, data[i]); - } - } - } - - } else { - logger.fatal("Incoming data thread shut down"); - cleanup(); - break; - } - } - } - }); - socketThread.start(); - } - - public boolean isConnected() { - return isConnected; - } - - public void cleanup() { - if (!isConnected) { - return; - } - isConnected = false; - - motePort.deleteSerialDataObserver(moteObserver); - - try { - if (socket != null) { - socket.close(); - socket = null; - } - } catch (IOException e1) { - } - try { - if (socketIn != null) { - socketIn.close(); - socketIn = null; - } - } catch (IOException e) { - } - try { - if (socketOut != null) { - socketOut.close(); - socketOut = null; - } - } catch (IOException e) { - } - - if (listeners != null) { - for (MoteSerialSocketConnectionListener dl: listeners) { - dl.wasDisconnected(MoteSerialSocketConnection.this); - } - listeners = null; - } - } - - public void addListener(MoteSerialSocketConnectionListener l) { - if (listeners == null) { - listeners = new ArrayList(); - } - - listeners.add(l); - } - - public interface MoteSerialSocketConnectionListener { - public void wasDisconnected(MoteSerialSocketConnection s); - public void dataTransferred(MoteSerialSocketConnection s, int toMote, int toSocket, byte data); - } - +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +package org.contikios.cooja.util; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.Socket; +import java.util.ArrayList; +import java.util.Observable; +import java.util.Observer; + +import org.apache.log4j.Logger; + +import org.contikios.cooja.Mote; +import org.contikios.cooja.interfaces.SerialPort; + +/** + * Help class for forwarding serial data between a mote and a socket. + * + * @author Fredrik Osterlind + */ +public class MoteSerialSocketConnection { + private static final long serialVersionUID = 1L; + private static Logger logger = Logger.getLogger(MoteSerialSocketConnection.class); + + private boolean isConnected = false; + public int toMote = 0, toSocket = 0; + + private SerialPort motePort; + private Observer moteObserver; + + private Socket socket; + private DataInputStream socketIn; + private DataOutputStream socketOut; + + private ArrayList listeners = null; + + public MoteSerialSocketConnection(Mote mote, String server, int serverPort) + throws IOException { + isConnected = true; + + /* Simulated -> socket */ + motePort = (SerialPort) mote.getInterfaces().getLog(); + motePort.addSerialDataObserver(moteObserver = new Observer() { + public void update(Observable obs, Object obj) { + try { + if (socketOut == null) { + return; + } + socketOut.write(motePort.getLastSerialData()); + socketOut.flush(); + toSocket++; + + if (listeners != null) { + for (MoteSerialSocketConnectionListener dl: listeners) { + dl.dataTransferred(MoteSerialSocketConnection.this, toMote, toSocket, motePort.getLastSerialData()); + } + } + } catch (IOException e) { + e.printStackTrace(); + logger.fatal("Write to socket error: " + e.getMessage(), e); + cleanup(); + } + } + }); + + /* Socket -> simulated */ + socket = new Socket(server, serverPort); + socketIn = new DataInputStream(socket.getInputStream()); + socketOut = new DataOutputStream(socket.getOutputStream()); + socketOut.flush(); + Thread socketThread = new Thread(new Runnable() { + public void run() { + int numRead = 0; + byte[] data = new byte[1024]; + while (true) { + numRead = -1; + try { + numRead = socketIn.read(data); + } catch (IOException e) { + e.printStackTrace(); + return; + } + + if (numRead >= 0) { + for (int i = 0; i < numRead; i++) { + toMote ++; + motePort.writeByte(data[i]); + if (listeners != null) { + for (MoteSerialSocketConnectionListener dl: listeners) { + dl.dataTransferred(MoteSerialSocketConnection.this, toMote, toSocket, data[i]); + } + } + } + + } else { + logger.fatal("Incoming data thread shut down"); + cleanup(); + break; + } + } + } + }); + socketThread.start(); + } + + public boolean isConnected() { + return isConnected; + } + + public void cleanup() { + if (!isConnected) { + return; + } + isConnected = false; + + motePort.deleteSerialDataObserver(moteObserver); + + try { + if (socket != null) { + socket.close(); + socket = null; + } + } catch (IOException e1) { + } + try { + if (socketIn != null) { + socketIn.close(); + socketIn = null; + } + } catch (IOException e) { + } + try { + if (socketOut != null) { + socketOut.close(); + socketOut = null; + } + } catch (IOException e) { + } + + if (listeners != null) { + for (MoteSerialSocketConnectionListener dl: listeners) { + dl.wasDisconnected(MoteSerialSocketConnection.this); + } + listeners = null; + } + } + + public void addListener(MoteSerialSocketConnectionListener l) { + if (listeners == null) { + listeners = new ArrayList(); + } + + listeners.add(l); + } + + public interface MoteSerialSocketConnectionListener { + public void wasDisconnected(MoteSerialSocketConnection s); + public void dataTransferred(MoteSerialSocketConnection s, int toMote, int toSocket, byte data); + } + } \ No newline at end of file diff --git a/tools/cooja/java/org/contikios/cooja/util/ScnObservable.java b/tools/cooja/java/org/contikios/cooja/util/ScnObservable.java new file mode 100644 index 000000000..d922d76a4 --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/util/ScnObservable.java @@ -0,0 +1,16 @@ +package org.contikios.cooja.util; + +import java.util.Observable; + +public class ScnObservable extends Observable { + public void setChangedAndNotify() { + setChanged(); + notifyObservers(); + } + + public void setChangedAndNotify(Object obj) { + setChanged(); + notifyObservers(obj); + } + +} diff --git a/tools/cooja/lib/JSYNTAXPANE_LICENSE b/tools/cooja/lib/JSYNTAXPANE_LICENSE index 01f0c7c35..a3ac59567 100644 --- a/tools/cooja/lib/JSYNTAXPANE_LICENSE +++ b/tools/cooja/lib/JSYNTAXPANE_LICENSE @@ -1,4 +1,4 @@ -Downloaded from http://code.google.com/p/jsyntaxpane/. - -Apache License 2.0: -http://www.apache.org/licenses/LICENSE-2.0 +Downloaded from http://code.google.com/p/jsyntaxpane/. + +Apache License 2.0: +http://www.apache.org/licenses/LICENSE-2.0 diff --git a/tools/cooja/lib/SWINGX_LICENSE b/tools/cooja/lib/SWINGX_LICENSE new file mode 100644 index 000000000..168cea070 --- /dev/null +++ b/tools/cooja/lib/SWINGX_LICENSE @@ -0,0 +1,511 @@ +Copyright (c) 2005-2006 Sun Microsystems, Inc., 4150 Network Circle, Santa +Clara, California 95054, U.S.A. All rights reserved. Use is subject +to license terms below. Sun, Sun Microsystems and the Sun logo are +trademarks or registered trademarks of Sun Microsystems, Inc. in the +U.S. and other countries. + +Notice: This product is covered by U.S. export control laws and may be +subject to the export or import laws in other countries. These laws may +restrict the fields of use for this software and may require you to +secure government authorization. + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. 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 not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the 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 +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice diff --git a/tools/cooja/lib/swingx-all-1.6.4.jar b/tools/cooja/lib/swingx-all-1.6.4.jar new file mode 100644 index 000000000..3078bb636 Binary files /dev/null and b/tools/cooja/lib/swingx-all-1.6.4.jar differ diff --git a/tools/jn516x/JennicModuleProgrammer b/tools/jn516x/JennicModuleProgrammer new file mode 100644 index 000000000..eef29c284 Binary files /dev/null and b/tools/jn516x/JennicModuleProgrammer differ diff --git a/tools/jn516x/Makefile b/tools/jn516x/Makefile new file mode 100644 index 000000000..be3caa44b --- /dev/null +++ b/tools/jn516x/Makefile @@ -0,0 +1,25 @@ +ifndef HOST_OS + ifeq ($(OS),Windows_NT) + HOST_OS := Windows + else + HOST_OS := $(shell uname) + endif +endif + +ifeq ($(HOST_OS),Windows) + SERIALDUMP = serialdump-windows +endif + +ifeq ($(HOST_OS),Darwin) + SERIALDUMP = serialdump-macos +endif + +ifndef SERIALDUMP + # Assume Linux + SERIALDUMP = serialdump-linux +endif + +all: $(SERIALDUMP) + +$(SERIALDUMP): serialdump.c + $(CC) -O2 -o $@ $< diff --git a/tools/jn516x/mote-list.py b/tools/jn516x/mote-list.py new file mode 100644 index 000000000..170b04fdb --- /dev/null +++ b/tools/jn516x/mote-list.py @@ -0,0 +1,94 @@ +#!/usr/bin/python + +# Copyright (c) 2015, SICS Swedish ICT +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. 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. +# 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. +# +# This file is part of the Contiki operating system. +# + +import sys, os, platform +import multiprocessing + +# detect the operating system +sysname = platform.system() +if "Linux" in sysname: + IS_WINDOWS = False + FLASH_PROGRAMMER_DEFAULT_PATH = "/usr/jn-toolchain/tools/flashprogrammer/JennicModuleProgrammer" + import motelist_lib.linux_motelist_impl as motelist_impl # @UnusedImport + +elif ("Win" in sysname) or ("NT" in sysname): + IS_WINDOWS = True + FLASH_PROGRAMMER_DEFAULT_PATH = 'C:\\NXP\\bstudio_nxp\\sdk\\JN-SW-4163\\Tools\\flashprogrammer\\FlashCLI.exe' + import motelist_lib.windows_motelist_impl as motelist_impl # @Reimport @UnusedImport + +else: + print ("OS ('{}') is not supported".format(os.name)) + + +def main(): + # use the default location + flash_programmer = FLASH_PROGRAMMER_DEFAULT_PATH + if len(sys.argv) > 2: + flash_programmer=sys.argv[1] + + serial_dumper = "" + if len(sys.argv) > 3: + serial_dumper=sys.argv[3] + + motes = motelist_impl.list_motes(flash_programmer) + if motes: + motes.sort() + print 'Found %d JN516X motes at:' %(len(motes)) + motes_str = '' + for m in motes: + motes_str += "%s " %(str(m)) + print motes_str + + firmware_file='#' + if len(sys.argv) > 2: + firmware_file = sys.argv[2] + elif len(sys.argv) > 1: + firmware_file = sys.argv[1] + + if firmware_file[0] == '\\': + firmware_file = firmware_file[1:] + + if firmware_file not in ['#', '!', '?', '%']: + print '\nBatch programming all connected motes...\n' + motelist_impl.program_motes(flash_programmer, motes, firmware_file) + elif firmware_file == '?' or firmware_file == '!': + should_display_mac_list = (firmware_file == '!') + motelist_impl.print_info(flash_programmer, motes, should_display_mac_list) + elif firmware_file == '%': + print '\nLogging from all connected motes...\n' + motelist_impl.serialdump_ports(flash_programmer, serial_dumper, motes) + else: + print '\nNo firmware file specified.\n' + +if __name__ == '__main__': + multiprocessing.freeze_support() + main() diff --git a/tools/jn516x/motelist_lib/__init__.py b/tools/jn516x/motelist_lib/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tools/jn516x/motelist_lib/linux_motelist_impl.py b/tools/jn516x/motelist_lib/linux_motelist_impl.py new file mode 100644 index 000000000..231c7814f --- /dev/null +++ b/tools/jn516x/motelist_lib/linux_motelist_impl.py @@ -0,0 +1,220 @@ +# Copyright (c) 2015, SICS Swedish ICT +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. 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. +# 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. +# +# This file is part of the Contiki operating system. +# +# Author(s): +# Janis Judvaitis +# Atis Elsts + +import os, glob, re +import multiprocessing, subprocess + +FTDI_VENDOR_ID = "0403" +FTDI_PRODUCT_ID = "6001" + +doPrintVendorID = False + +def read_line(filename): + """helper function to read a single line from a file""" + line = "Unknown" + try: + with open(filename) as f: + line = f.readline().strip() + finally: + return line + +# try to extract descriptions from sysfs. this was done by experimenting, +# no guarantee that it works for all devices or in the future... + +def usb_sysfs_hw_string(sysfs_path): + """given a path to a usb device in sysfs, return a string describing it""" + snr = read_line(sysfs_path + '/serial') + if snr: + snr_txt = '%s' % (snr,) + else: + snr_txt = '' + if doPrintVendorID: + return 'USB VID:PID=%s:%s SNR=%s' % ( + read_line(sysfs_path + '/idVendor'), + read_line(sysfs_path + '/idProduct'), + snr_txt + ) + else: + return snr_txt + +def usb_string(sysfs_path): + # Get dir name in /sys/bus/usb/drivers/usb for current usb dev + dev = os.path.basename(os.path.realpath(sysfs_path)) + dev_dir = os.path.join("/sys/bus/usb/drivers/usb", dev) + + try: + # Go to usb dev directory + product = read_line(os.path.join(dev_dir, "product")) + manufacturer = read_line(os.path.join(dev_dir, "manufacturer")) + result = product + " by " + manufacturer + except: + result = "Unknown device" + + return result + +def describe(device): + """ + Get a human readable description. + For USB-Serial devices try to run lsusb to get a human readable description. + For USB-CDC devices read the description from sysfs. + """ + base = os.path.basename(device) + # USB-Serial devices + sys_dev_path = '/sys/class/tty/%s/device/driver/%s' % (base, base) + if os.path.exists(sys_dev_path): + sys_usb = os.path.dirname(os.path.dirname(os.path.realpath(sys_dev_path))) + return usb_string(sys_usb) + + # Arduino wants special handling + sys_dev_path = '/sys/class/tty/%s/device/driver/' % (base) + for x in os.listdir(sys_dev_path): + # Driver directory's name contains device ID in /sys/bus/usb/drivers/usb + temp = x.split(":") + if len(temp) == 2: + # No Arduino adds, need to save space! + return usb_string(temp[0]).replace("(www.arduino.cc)", "").strip() + + # USB-CDC devices + sys_dev_path = '/sys/class/tty/%s/device/interface' % (base,) + if os.path.exists(sys_dev_path): + return read_line(sys_dev_path) + + return base + +def hwinfo(device): + """Try to get a HW identification using sysfs""" + base = os.path.basename(device) + if os.path.exists('/sys/class/tty/%s/device' % (base,)): + # PCI based devices + sys_id_path = '/sys/class/tty/%s/device/id' % (base,) + if os.path.exists(sys_id_path): + return read_line(sys_id_path) + # USB-Serial devices + sys_dev_path = '/sys/class/tty/%s/device/driver/%s' % (base, base) + if os.path.exists(sys_dev_path): + sys_usb = os.path.dirname(os.path.dirname(os.path.realpath(sys_dev_path))) + return usb_sysfs_hw_string(sys_usb) + # USB-CDC devices + if base.startswith('ttyACM'): + sys_dev_path = '/sys/class/tty/%s/device' % (base,) + if os.path.exists(sys_dev_path): + return usb_sysfs_hw_string(sys_dev_path + '/..') + return 'n/a' # XXX directly remove these from the list? + +####################################### + +def is_nxp_mote(device): + base = os.path.basename(device) + # USB-Serial device? + sys_dev_path = '/sys/class/tty/%s/device/driver/%s' % (base, base) + if not os.path.exists(sys_dev_path): + return False + + path_usb = os.path.dirname(os.path.dirname(os.path.realpath(sys_dev_path))) + + dev = os.path.basename(os.path.realpath(path_usb)) + dev_dir = os.path.join("/sys/bus/usb/drivers/usb", dev) + + try: + idProduct = read_line(os.path.join(dev_dir, "idProduct")) + idVendor = read_line(os.path.join(dev_dir, "idVendor")) + if idVendor != FTDI_VENDOR_ID or idProduct != FTDI_PRODUCT_ID: + return False + product = read_line(os.path.join(dev_dir, "product")) + manufacturer = read_line(os.path.join(dev_dir, "manufacturer")) + if manufacturer != "NXP": + return False + except: + return False + return True + + +def list_motes(flash_programmer): + devices = glob.glob('/dev/ttyUSB*')# + glob.glob('/dev/ttyACM*') + return [d for d in devices if is_nxp_mote(d)] + + +def extract_information(port, stdout_value): + mac_str='Unknown' # not supported on Linux + info='' # not properly supported on Linux + is_program_success='' + + info = describe(port) + ", SerialID: " + hwinfo(port) + + res = re.compile('(Success)').search(stdout_value) + if res: + is_program_success = str(res.group(1)) + else: + res = re.compile('(Error .*)\n').search(stdout_value) + if res: + is_program_success = str(res.group(1)) + + return [mac_str, info, is_program_success] + + +def program_motes(flash_programmer, motes, firmware_file): + for m in motes: + cmd = [flash_programmer, '-v', '-s', m, '-I', '38400', '-P', '1000000', '-f', firmware_file] + cmd = " ".join(cmd) + proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,) + stdout_value, stderr_value = proc.communicate('through stdin to stdout') + [mac_str, info, is_program_success] = extract_information(m, stdout_value) + print m, is_program_success + + errors = (stderr_value) + if errors != '': + print 'Errors:', errors + + +def print_info(flash_programmer, motes, do_mac_only): + if do_mac_only: + print "Listing Mac addresses (not supported on Linux):" + else: + print "Listing mote info:" + + for m in motes: + [mac_str, info, is_program_success] = extract_information(m, '') + if do_mac_only: + print m, mac_str + else: + print m, '\n', info, '\n' + +def serialdump(args): + port_name = args[0] + serial_dumper = args[1] + rv = subprocess.call(serial_dumper + ' -b1000000 ' + port_name, shell=True) + +def serialdump_ports(flash_programmer, serial_dumper, ports): + p = multiprocessing.Pool() + p.map(serialdump, zip(ports, [serial_dumper] * len(ports))) + p.close() diff --git a/tools/jn516x/motelist_lib/windows_motelist_impl.py b/tools/jn516x/motelist_lib/windows_motelist_impl.py new file mode 100644 index 000000000..a4528484b --- /dev/null +++ b/tools/jn516x/motelist_lib/windows_motelist_impl.py @@ -0,0 +1,142 @@ +# Copyright (c) 2015, SICS Swedish ICT +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. 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. +# 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. +# +# This file is part of the Contiki operating system. +# +# Author(s): +# Simon Duquennoy +# Atis Elsts + +import os, re, subprocess, multiprocessing + +def list_motes(flash_programmer): + #There is no COM0 in windows. We use this to trigger an error message that lists all valid COM ports + cmd = [flash_programmer, '-c', 'COM0'] + proc = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,) + stdout_value, stderr_value = proc.communicate('through stdin to stdout') + com_str = (stderr_value) + #print '\tpass through:', repr(stdout_value) + #print '\tstderr :', com_str + + ## Extract COM ports from output: + ## Example com_str: "Available ports: ['COM15', 'COM10']" + res = re.compile('\[((?:\'COM\d+\'.?.?)+)\]').search(com_str) + + ports = [] + if res: + port_str=str(res.group(1)) + ports=port_str.replace('\'', '').replace(',', '').split() + return ports + +def extract_information(port, stdout_value): + mac_str='' + info='' + is_program_success='' + + #print 'output: ', stdout_value + +# res = re.compile('Connecting to device on (COM\d+)').search(stdout_value) +# if res: +# port_str = str(res.group(1)) + + ### extracting the following information + ''' + Devicelabel: JN516x, BL 0x00080006 + FlashLabel: Internal Flash (256K) + Memory: 0x00008000 bytes RAM, 0x00040000 bytes Flash + ChipPartNo: 8 + ChipRevNo: 1 + ROM Version: 0x00080006 + MAC Address: 00:15:8D:00:00:35:DD:FB + ZB License: 0x00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00 + User Data: 00:00:00:00:00:00:00:00 + FlashMID: 0xCC + FlashDID: 0xEE + MacLocation: 0x00000010 + Sector Length: 0x08000 + Bootloader Version: 0x00080006 + ''' + + res = re.compile('(Devicelabel.*\sFlashLabel.*\sMemory.*\sChipPartNo.*\sChipRevNo.*\sROM Version.*\sMAC Address.*\sZB License.*\sUser Data.*\sFlashMID.*\sFlashDID.*\sMacLocation.*\sSector Length.*\sBootloader Version\:\s+0x\w{8})').search(stdout_value) + if res: + info = str(res.group(1)) + + res = re.compile('MAC Address\:\s+((?:\w{2}\:?){8})').search(stdout_value) + if res: + mac_str = str(res.group(1)) + + res = re.compile('(Program\ssuccessfully\swritten\sto\sflash)').search(stdout_value) + if res: + is_program_success = str(res.group(1)) + + return [mac_str, info, is_program_success] + +def program_motes(flash_programmer, motes, firmware_file): + for m in motes: + cmd = [flash_programmer, '-c', m, '-B', '1000000', '-s', '-w', '-f', firmware_file] + proc = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,) + stdout_value, stderr_value = proc.communicate('through stdin to stdout') + [mac_str, info, is_program_success] = extract_information(m, stdout_value) + print m, mac_str, is_program_success + + errors = (stderr_value) + if errors != '': + print 'Errors:', errors + +def print_info(flash_programmer, motes, do_mac_only): + if do_mac_only: + print "Listing Mac addresses:" + else: + print "Listing mote info:" + for m in motes: + cmd=[flash_programmer, '-c', m, '-B', '1000000'] + proc = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,) + stdout_value, stderr_value = proc.communicate('through stdin to stdout') + [mac_str, info, is_program_success] = extract_information(m, stdout_value) + + errors = (stderr_value) + + if do_mac_only: + print m, mac_str + else: + print m, '\n', info, '\n' + + if errors != '': + print 'Errors:', errors + +def serialdump(args): + port_name = args[0] + serial_dumper = args[1] + cmd = [serial_dumper, '-b1000000', "/dev/" + port_name.lower()] + if os.name == "posix" or os.name == "cygwin": + cmd = " ".join(cmd) + rv = subprocess.call(cmd, shell=True) + +def serialdump_ports(flash_programmer, serial_dumper, ports): + p = multiprocessing.Pool() + p.map(serialdump, zip(ports, [serial_dumper] * len(ports))) + p.close() diff --git a/tools/jn516x/serialdump.c b/tools/jn516x/serialdump.c new file mode 100644 index 000000000..26b0884e2 --- /dev/null +++ b/tools/jn516x/serialdump.c @@ -0,0 +1,396 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BAUDRATE B115200 +#define BAUDRATE_S "115200" +#ifdef linux +#define MODEMDEVICE "/dev/ttyS0" +#else +#define MODEMDEVICE "/dev/com1" +#endif /* linux */ + +#define SLIP_END 0300 +#define SLIP_ESC 0333 +#define SLIP_ESC_END 0334 +#define SLIP_ESC_ESC 0335 + +#define CSNA_INIT 0x01 + +#define BUFSIZE 40 +#define HCOLS 20 +#define ICOLS 18 + +#define MODE_START_DATE 0 +#define MODE_DATE 1 +#define MODE_START_TEXT 2 +#define MODE_TEXT 3 +#define MODE_INT 4 +#define MODE_HEX 5 +#define MODE_SLIP_AUTO 6 +#define MODE_SLIP 7 +#define MODE_SLIP_HIDE 8 + +static unsigned char rxbuf[2048]; + +static int +usage(int result) +{ + printf("Usage: serialdump [-x] [-s[on]] [-i] [-bSPEED] [SERIALDEVICE]\n"); + printf(" -x for hexadecimal output\n"); + printf(" -i for decimal output\n"); + printf(" -s for automatic SLIP mode\n"); + printf(" -so for SLIP only mode (all data is SLIP packets)\n"); + printf(" -sn to hide SLIP packages\n"); + printf(" -T[format] to add time for each text line\n"); + printf(" (see man page for strftime() for format description)\n"); + return result; +} + +static void +print_hex_line(unsigned char *prefix, unsigned char *outbuf, int index) +{ + int i; + + printf("\r%s", prefix); + for(i = 0; i < index; i++) { + if((i % 4) == 0) { + printf(" "); + } + printf("%02X", outbuf[i] & 0xFF); + } + printf(" "); + for(i = index; i < HCOLS; i++) { + if((i % 4) == 0) { + printf(" "); + } + printf(" "); + } + for(i = 0; i < index; i++) { + if(outbuf[i] < 30 || outbuf[i] > 126) { + printf("."); + } else { + printf("%c", outbuf[i]); + } + } +} + +int +main(int argc, char **argv) +{ + struct termios options; + fd_set mask, smask; + int fd; + speed_t speed = BAUDRATE; + char *speedname = BAUDRATE_S; + char *device = MODEMDEVICE; + char *timeformat = NULL; + unsigned char buf[BUFSIZE], outbuf[HCOLS]; + unsigned char mode = MODE_START_TEXT; + int nfound, flags = 0; + unsigned char lastc = '\0'; + + int index = 1; + while(index < argc) { + if(argv[index][0] == '-') { + switch(argv[index][1]) { + case 'b': + /* set speed */ + if(strcmp(&argv[index][2], "38400") == 0) { + speed = B38400; + speedname = "38400"; + } else if(strcmp(&argv[index][2], "19200") == 0) { + speed = B19200; + speedname = "19200"; + } else if(strcmp(&argv[index][2], "57600") == 0) { + speed = B57600; + speedname = "57600"; + } else if(strcmp(&argv[index][2], "115200") == 0) { + speed = B115200; + speedname = "115200"; + } else if(strcmp(&argv[index][2], "230400") == 0) { + speed = B230400; + speedname = "230400"; + } else if(strcmp(&argv[index][2], "460800") == 0) { + speed = B460800; + speedname = "460800"; + } else if(strcmp(&argv[index][2], "500000") == 0) { + speed = B500000; + speedname = "500000"; + } else if(strcmp(&argv[index][2], "576000") == 0) { + speed = B576000; + speedname = "576000"; + } else if(strcmp(&argv[index][2], "921600") == 0) { + speed = B921600; + speedname = "921600"; + } else if(strcmp(&argv[index][2], "1000000") == 0) { + speed = B1000000; + speedname = "1000000"; + } else { + fprintf(stderr, "unsupported speed: %s\n", &argv[index][2]); + return usage(1); + } + break; + case 'x': + mode = MODE_HEX; + break; + case 'i': + mode = MODE_INT; + break; + case 's': + switch(argv[index][2]) { + case 'n': + mode = MODE_SLIP_HIDE; + break; + case 'o': + mode = MODE_SLIP; + break; + default: + mode = MODE_SLIP_AUTO; + break; + } + break; + case 'T': + if(strlen(&argv[index][2]) == 0) { + timeformat = "%Y-%m-%d %H:%M:%S"; + } else { + timeformat = &argv[index][2]; + } + mode = MODE_START_DATE; + break; + case 'h': + return usage(0); + default: + fprintf(stderr, "unknown option '%c'\n", argv[index][1]); + return usage(1); + } + index++; + } else { + device = argv[index++]; + if(index < argc) { + fprintf(stderr, "too many arguments\n"); + return usage(1); + } + } + } + fprintf(stderr, "connecting to %s (%s)", device, speedname); + +#ifdef O_SYNC + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY /*| O_DIRECT*/ | O_SYNC); + if(fd < 0 && errno == EINVAL){ // O_SYNC not supported (e.g. raspberian) + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_DIRECT); + } +#else + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC ); +#endif + if(fd < 0) { + fprintf(stderr, "\n"); + perror("open"); + exit(-1); + } + fprintf(stderr, " [OK]\n"); + + if(fcntl(fd, F_SETFL, 0) < 0) { + perror("could not set fcntl"); + exit(-1); + } + + if(tcgetattr(fd, &options) < 0) { + perror("could not get options"); + exit(-1); + } + /* fprintf(stderr, "serial options set\n"); */ + cfsetispeed(&options, speed); + cfsetospeed(&options, speed); + /* Enable the receiver and set local mode */ + options.c_cflag |= (CLOCAL | CREAD); + /* Mask the character size bits and turn off (odd) parity */ + options.c_cflag &= ~(CSIZE | PARENB | PARODD); + /* Select 8 data bits */ + options.c_cflag |= CS8; + + /* Raw input */ + options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); + /* Raw output */ + options.c_oflag &= ~OPOST; + + if(tcsetattr(fd, TCSANOW, &options) < 0) { + perror("could not set options"); + exit(-1); + } + + /* Make read() return immediately */ + /* if (fcntl(fd, F_SETFL, FNDELAY) < 0) { */ + /* perror("\ncould not set fcntl"); */ + /* exit(-1); */ + /* } */ + + FD_ZERO(&mask); + FD_SET(fd, &mask); + FD_SET(fileno(stdin), &mask); + + index = 0; + for(;;) { + smask = mask; + nfound = select(FD_SETSIZE, &smask, (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0); + if(nfound < 0) { + if(errno == EINTR) { + fprintf(stderr, "interrupted system call\n"); + continue; + } + /* something is very wrong! */ + perror("select"); + exit(1); + } + + if(FD_ISSET(fileno(stdin), &smask)) { + /* data from standard in */ + int n = read(fileno(stdin), buf, sizeof(buf)); + if(n < 0) { + perror("could not read"); + exit(-1); + } else if(n > 0) { + /* because commands might need parameters, lines needs to be + separated which means the terminating LF must be sent */ + /* while(n > 0 && buf[n - 1] < 32) { */ + /* n--; */ + /* } */ + if(n > 0) { + int i; + /* fprintf(stderr, "SEND %d bytes\n", n);*/ + /* write slowly */ + for(i = 0; i < n; i++) { + if(write(fd, &buf[i], 1) <= 0) { + perror("write"); + exit(1); + } else { + fflush(NULL); + usleep(6000); + } + } + } + } else { + /* End of input, exit. */ + exit(0); + } + } + + if(FD_ISSET(fd, &smask)) { + int i, j, n = read(fd, buf, sizeof(buf)); + if(n < 0) { + perror("could not read"); + exit(-1); + } + + for(i = 0; i < n; i++) { + switch(mode) { + case MODE_START_TEXT: + case MODE_TEXT: + printf("%c", buf[i]); + break; + case MODE_START_DATE: { + time_t t; + t = time(&t); + strftime(outbuf, HCOLS, timeformat, localtime(&t)); + printf("%s|", outbuf); + mode = MODE_DATE; + } + /* continue into the MODE_DATE */ + case MODE_DATE: + printf("%c", buf[i]); + if(buf[i] == '\n') { + mode = MODE_START_DATE; + } + break; + case MODE_INT: + printf("%03d ", buf[i]); + if(++index >= ICOLS) { + index = 0; + printf("\n"); + } + break; + case MODE_HEX: + rxbuf[index++] = buf[i]; + if(index >= HCOLS) { + print_hex_line("", rxbuf, index); + index = 0; + printf("\n"); + } + break; + + case MODE_SLIP_AUTO: + case MODE_SLIP_HIDE: + if(!flags && (buf[i] != SLIP_END)) { + /* Not a SLIP packet? */ + printf("%c", buf[i]); + break; + } + /* continue to slip only mode */ + case MODE_SLIP: + switch(buf[i]) { + case SLIP_ESC: + lastc = SLIP_ESC; + break; + + case SLIP_END: + if(index > 0) { + if(flags != 2 && mode != MODE_SLIP_HIDE) { + /* not overflowed: show packet */ + print_hex_line("SLIP: ", rxbuf, index > HCOLS ? HCOLS : index); + printf("\n"); + } + lastc = '\0'; + index = 0; + flags = 0; + } else { + flags = !flags; + } + break; + + default: + if(lastc == SLIP_ESC) { + lastc = '\0'; + + /* Previous read byte was an escape byte, so this byte will be + interpreted differently from others. */ + switch(buf[i]) { + case SLIP_ESC_END: + buf[i] = SLIP_END; + break; + case SLIP_ESC_ESC: + buf[i] = SLIP_ESC; + break; + } + } + + rxbuf[index++] = buf[i]; + if(index >= sizeof(rxbuf)) { + fprintf(stderr, "**** slip overflow\n"); + index = 0; + flags = 2; + } + break; + } + break; + } + } + + /* after processing for some output modes */ + if(index > 0) { + switch(mode) { + case MODE_HEX: + print_hex_line("", rxbuf, index); + break; + } + } + fflush(stdout); + } + } +} diff --git a/tools/mspsim b/tools/mspsim index 58f187351..47ae45cb0 160000 --- a/tools/mspsim +++ b/tools/mspsim @@ -1 +1 @@ -Subproject commit 58f187351f3417814aa2d0d92af9e2bb768d92ee +Subproject commit 47ae45cb0f36337115e32adb2a5ba0bf6e1e4437 diff --git a/tools/release-tools/compile-platforms/Makefile b/tools/release-tools/compile-platforms/Makefile index cd522110f..ba45de930 100644 --- a/tools/release-tools/compile-platforms/Makefile +++ b/tools/release-tools/compile-platforms/Makefile @@ -6,7 +6,7 @@ all: compile: 6502 msp430 native avr arm -6502: c64.platform c128.platform apple2enh.platform atari.platform +6502: c64.platform c128.platform apple2enh.platform atarixl.platform msp430: sky.platform esb.platform z1.platform native: native.platform minimal-net.platform avr: avr-raven.platform diff --git a/tools/release-tools/compile-platforms/Makefile.platform b/tools/release-tools/compile-platforms/Makefile.platform index ba6cee3d2..aea163ae7 100644 --- a/tools/release-tools/compile-platforms/Makefile.platform +++ b/tools/release-tools/compile-platforms/Makefile.platform @@ -3,7 +3,9 @@ CONTIKI = ../../../.. APPS=serial-shell webserver telnetd ifeq ($(TARGET), avr-raven) - UIP_CONF_IPV6=1 + CONTIKI_WITH_IPV6 = 1 +else + CONTIKI_WITH_RIME = 1 endif include $(CONTIKI)/Makefile.include diff --git a/tools/sensinode/nano_programmer/Makefile b/tools/sensinode/nano_programmer/Makefile deleted file mode 100644 index 06c0fb979..000000000 --- a/tools/sensinode/nano_programmer/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -EXE_MAKE=$(notdir $(shell which "make.exe" 2>/dev/null)) -ifeq "$(EXE_MAKE)" "make.exe" -PLATFORM=windows -else -PLATFORM=linux -endif - -OBJECTS = ihex.o $(PLATFORM)/port.o programmer.o cdi_program.o -SUBDIRS = - -ifeq "$(PLATFORM)" "linux" -CFLAGS = -Wall -D_REENTRANT -I. -LDFLAGS = -L. -D_REENTRANT -lpthread -SUFFIX= -else -CFLAGS=-I. -I../nano_usb_programmer/ftdi_win32 -CFLAGS+= -L. -L../nano_usb_programmer/ftdi_win32 -DPLATFORM_WINDOWS -CFLAGS+= -mwin32 -LDFLAGS=../nano_usb_programmer/ftdi_win32/ftd2xx.lib -lkernel32 -SUFFIX=.exe -endif - -TARGET = nano_programmer$(SUFFIX) - -all: binary - -binary: $(TARGET) - strip $(TARGET) - -$(TARGET): $(OBJECTS) - gcc -o $(TARGET) $(OBJECTS) $(LDFLAGS) - -.c.o: - gcc -c -o $(<:.c=.o) -O2 -Wall $(CFLAGS) $< - -platform-test: - @echo $(PLATFORM) - -old-strip: - if [ -x $(TARGET).exe ]; then $(PLATFORM)strip $(TARGET).exe; else $(PLATFORM)strip $(TARGET); fi - -clean: - rm -f $(TARGET) $(OBJECTS) diff --git a/tools/sensinode/nano_programmer/README.md b/tools/sensinode/nano_programmer/README.md deleted file mode 100755 index a9ce6d81e..000000000 --- a/tools/sensinode/nano_programmer/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# Nano Programmer - -Programming tool for the Sensinode Nano series using Dxxx development boards. - -Copyright 2007-2008 Sensinode Ltd. - -## Installation - -### Linux - -No external libraries required. - -### Windows/Cygwin - -See the nano_usb_programmer README file on how to install FTDI library -for nano_usb_programmer. The nano_programmer build system will fetch -the library from there. - -## Usage - -Usage info for the Nano Programmer is available with command - - ./nano_programmer --help - -Note that use might require root/administrator privileges - depending on system configuration. - -## Known problems - -Occasional timing failures resulting in "Reinit failed."-messages do come -up in some PC configurations. If you experience programming failures (the programmer -is not able to recover), please report your system configuration to Sensinode. -On Linux, it is known that the "brltty" program causes problems with the FTDI -serial driver. Uninstalling brltty resolves the problem. - -## Version - -v1.3 2008-01-31 Martti Huttunen Multi-platform build and created instructions diff --git a/tools/sensinode/nano_programmer/cdi_program.c b/tools/sensinode/nano_programmer/cdi_program.c deleted file mode 100644 index 3b2ecd255..000000000 --- a/tools/sensinode/nano_programmer/cdi_program.c +++ /dev/null @@ -1,607 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#include -#include -#include - -#include "port.h" -#include "programmer.h" -#include "ihex.h" - -#include - -extern void crc_add(unsigned char *crc, unsigned char byte); - -int cdi_page_write(port_t *port, unsigned long page_addr, unsigned char *page_buffer); -int cdi_write(port_t *port, conf_opts_t *conf, FILE *ihex); - -int cdi_programmer(conf_opts_t *conf, char *filename) -{ - int error = 0; - port_t *port = 0; - unsigned char buffer[256]; - int length = 0; - FILE *ihex = 0; - - error = programmer_init(conf->device, &port); - - if (error < 0) - { - return error; - } - - if((!error) && (conf->action != 'b')) - { - length = port_write_echo(port, "CDI\r"); - bzero(buffer, sizeof(buffer)); - if (length >= 4) - { - length = port_readline(port, buffer, sizeof(buffer), 100); - } - else length = 0; - - if(memcmp(buffer, "OK", 2) == 0) - { - error = 0; - } - else - { - printf("Programming mode selection failed.\n"); - error = -1; - } - } - - if((!error) && (conf->action != 'b')) - { - printf("Initialize.\n"); - // Succesfully in mode 1 - sleep(1); - port_write_echo(port, "i\r"); - - bzero(buffer, 256); - length = port_readline(port, buffer, sizeof(buffer), 100); - - if(memcmp(buffer, "85", 2) == 0) - { /*Found CC2430 device*/ - printf("Found CC2430 device revision %c%c.\n", buffer[2], buffer[3]); - } - else if (memcmp(buffer, "89", 2) == 0) - { - printf("Found CC2431 device revision %c%c.\n", buffer[2], buffer[3]); - } - else - { - printf("CC2430 not found.\n"); - error = -1; - } - } - - if (error) conf->action = ' '; - - switch(conf->action) - { - case 'e': - // Erase programming - port_write_echo(port, "e\r"); - bzero(buffer, 256); - length = port_readline(port, buffer, sizeof(buffer), 100); - - if(memcmp(buffer, "OK", 2) == 0) - { - // Erase successful - printf("Erase successful.\n"); - error = 0; - } - else - { - // Erase failed - printf("Erase failed: %s.\n", buffer); - error = -1; - } - if ((conf->action != 'P') || error) - break; - - case 'P': - case 'w': - ihex = fopen(conf->ihex_file, "rb"); - if(ihex == NULL) - { - printf("Failed to open ihex file %s.\n", conf->ihex_file); - error = -1; - } - else error = 0; - - if (!error) - { - error = cdi_write(port, conf, ihex); - if (error) printf("Programming failed.\n"); - } - - - - if (ihex != NULL) fclose(ihex); - break; - - case 'b': - length = port_write_echo(port, "V\r"); - bzero(buffer, sizeof(buffer)); - if (length >= 2) - { - length = port_readline(port, buffer, sizeof(buffer), 100); - } - else length = 0; - - if(length > 4) - { - buffer[length] = 0; - printf("BIOS: %s\n", buffer); - error = 0; - } - else - { - printf("Failed to get BIOS version. Upgrade recommended.\n"); - error = -1; - } - break; - - case 'v': - break; - - case 'r': - ihex = fopen(conf->ihex_file, "wb"); - if(ihex == NULL) - { - printf("Failed to open ihex file %s.\n", conf->ihex_file); - error = -1; - } - else - { - port_write_echo(port, "a000000\r"); - bzero(buffer, sizeof(buffer)); - length = port_readline(port, buffer, sizeof(buffer), 200); - if (length <0) length = 0; - if(memcmp(buffer, "OK", 2) == 0) - { - uint32_t address = 0; - uint8_t check = 0; - for (address = 0; address < 128*1024; address += 64) - { - uint8_t i; - - if ((address) && ((address & 0xFFFF)==0)) - { - fprintf(ihex, ":02000004%4.4X%2.2X\r\n", - (int)(address>>16), (int)(0xFA-(address>>16))); - } - port_write_echo(port, "r\r"); - bzero(buffer, 256); - length = 0; - while (length < 64) - { - length += port_readline(port, &buffer[length], sizeof(buffer)-length, 100); - } - for (i=0; i<64; i++) - { - if ((i & 0x0F) == 0) - { - check = 0; - check -= 0x10; - check -= (uint8_t) (address >> 8); - check -= (uint8_t) (address + i); - printf("%4.4X", (int) address + i); - fprintf(ihex, ":10%4.4X00", (int) (address + i) & 0xFFFF); - } - fprintf(ihex, "%2.2X", buffer[i]); - check -= buffer[i]; - if ((i & 0x0F) == 0x0F) - { - fprintf(ihex, "%2.2X\r\n", check); - if (i > 0x30) printf("\n"); - else printf(" "); - } - } - } - fprintf(ihex, ":00000001FF\r\n"); - } - else - { - printf("Failed to set read address.\n"); - error = -1; - } - fclose(ihex); - } - break; - /*skip for error case*/ - case ' ': - break; - - case 'm': - port_write_echo(port, "a01F800\r"); - bzero(buffer, sizeof(buffer)); - length = port_readline(port, buffer, sizeof(buffer), 200); - if (length <0) length = 0; - if(memcmp(buffer, "OK", 2) == 0) - { - uint8_t i; - uint32_t address = 0; - - for (address = 0x01F800; address < 128*1024; address += 64) - { - - port_write_echo(port, "r\r"); - bzero(buffer, 256); - length = 0; - while (length < 64) - { - length += port_readline(port, &buffer[length], sizeof(buffer)-length, 100); - } - if ((address & 0xff) == 0) - { printf("."); - fflush(stdout); - } - } - printf("\nDevice MAC: "); - for (i=56; i<64; i++) - { - if (i != 56) printf(":"); - printf("%2.2X", buffer[i]); - } - printf("\n"); - } - break; - - case 'Q': - port_write_echo(port, "a01F800\r"); - bzero(buffer, sizeof(buffer)); - length = port_readline(port, buffer, sizeof(buffer), 200); - if (length <0) length = 0; - if(memcmp(buffer, "OK", 2) == 0) - { - uint8_t p_buffer[2048]; - int error; - - memset(p_buffer, 0xff, sizeof(p_buffer)); - memcpy(&p_buffer[2040], conf->write_mac, 8); - - printf("\rWriting MAC: "); - error = cdi_page_write(port, 0x01F800, p_buffer); - if (!error) - { - printf("Write complete.\n"); - } - else - { - printf("Write failed.\n"); - } - } - break; - - default: - printf("Unknown CDI action.\n"); - break; - } - - printf("Close programmer.\n"); - usleep(100000); - port_write_echo(port, "q\r"); - programmer_close(port); - return error; -} - -int cdi_write(port_t *port, conf_opts_t *conf, FILE *ihex) -{ - int error = 0; - unsigned char buffer[256]; - int length; - int i; - int pages; - - unsigned long ext_addr=0; - unsigned short int addr=0; - unsigned char page_buffer[128*1024]; - unsigned char page_table[64]; - - bzero(buffer, sizeof(buffer)); - - /*initialize page data*/ - memset(page_table, 0, 64); - memset(page_buffer, 0xFF, sizeof(page_buffer)); - pages = 0; - - error = 0; - - if (conf->page_mode == PAGE_UNDEFINED) - { - int retval; - - while((!error) && ((retval = fscanf(ihex, "%s", buffer)) == 1) ) - { - unsigned char data_len = 0; - - if (memcmp(&buffer[7], "00", 2) == 0) - { /*Data record*/ - } - else if (memcmp(&buffer[7], "01", 2) == 0) - { /*end file*/ - printf("\nFile read complete.\n"); - break; - } - else if (memcmp(&buffer[7], "04", 2) == 0) - { - sscanf((char *)&(buffer[3]),"%4hx", &addr); - sscanf((char *)&(buffer[9]),"%4lx", &ext_addr); - - if (ext_addr >= 0x0002) - { - conf->page_mode = PAGE_SDCC; - } - else - { - if (conf->page_mode == PAGE_UNDEFINED) conf->page_mode = PAGE_LINEAR; - } - } - } - if (retval == -1) - { - printf("Read error\n"); - return -1; - } - rewind(ihex); - retval = 0; - error = 0; - } - switch (conf->page_mode) - { - case PAGE_SDCC: - printf("SDCC banked file.\n"); - break; - case PAGE_LINEAR: - printf("Linear banked file.\n"); - break; - case PAGE_UNDEFINED: - printf("Non-banked file, assuming linear.\n"); - conf->page_mode = PAGE_LINEAR; - break; - } - - while( (fscanf(ihex, "%s", buffer) == 1) && !error) - { - unsigned char data_len = 0; - - if (memcmp(&buffer[7], "00", 2) == 0) - { /*Data record*/ - i=0; - sscanf((char *)&buffer[1], "%2hhx", &data_len); - sscanf((char *)&(buffer[3]),"%4hx", &addr); - while(ipage_mode == PAGE_SDCC) - { - if (ext_addr) ext_addr--; - ext_addr *= 0x8000; - } - else - { - ext_addr *= 0x10000; - } - printf("\rExtended page address: 0x%8.8lX\r", ext_addr); - } - } - - if (pages) - { - int retry = 0; - // Successfully in mode 3 (programming) - printf("Starting programming.\n"); - error = 0; - for (i=0; i<64; i++) - { - if (page_table[i] != 0) - { - ext_addr = 2048*i; - - bzero(buffer, sizeof(buffer)); - - // Write the start address and check return - usleep(3000); - sprintf((char *)buffer, "a%6.6lX\r", ext_addr); - port_write_echo(port, (char *)buffer); - - if((length = port_readline(port, buffer, sizeof(buffer), 200)) < 0) - { - printf("Read from serial timed out without data.\n"); - error = -1; - break; - } - else - { - if(strncmp((char *)buffer, "OK\r\n", 4) == 0) - { - printf("\r \r"); - printf("\rWriting @ 0x%6.6lX: ", ext_addr); - fflush(stdout); - error = cdi_page_write(port, ext_addr, &page_buffer[ext_addr]); - if (error) - { - usleep(20000); - port_write_echo(port, "i\r"); - - bzero(buffer, 256); - length = port_readline(port, buffer, sizeof(buffer), 100); - - if(memcmp(buffer, "85", 2) == 0) - { /*Found CC2430 device*/ - } - else - { - printf("Reinit failed.\n"); - error = -1; - } - if (retry++ < 3) - { - error = 0; - i--; - } - } - else retry = 0; - fflush(stdout); - usleep(20000); - } - else - { - printf("Failed to set CDI programming start address.\n"); - error = -1; - break; - } - } - } - if (error) break; - } - usleep(200000); - printf("\n"); - } - - return error; -} - -int cdi_page_write(port_t *port, unsigned long page_addr, unsigned char *page_buffer) -{ - int error = 0; - unsigned char buffer[80]; - unsigned char cmd[16]; - unsigned char block, i; - int length; - int retry = 0; - - // Write page - port_write_echo(port, "w\r"); - usleep(10000); - for (block=0; block<(2048/64); block++) - { - sprintf((char *)cmd, "%6.6lX", page_addr + (64*block)); - bzero(buffer, sizeof(buffer)); - length = port_readline(port, buffer, sizeof(buffer), 2000); - if (length <0) - { length = 0; - printf("l!");fflush(stdout); - } - buffer[length] = 0; - if (block & 1) - { - } - if(memcmp(buffer, cmd, 6) == 0) - { -#define WRITE_SIZE 64 - for (i=0; i<64; i+=WRITE_SIZE) - { - port_write(port, &page_buffer[(unsigned int)(block*64)+i], WRITE_SIZE); - usleep(1250); - } - - bzero(buffer, sizeof(buffer)); - printf("."); - fflush(stdout); - length = port_readline(port, buffer, sizeof(buffer), 200); - if(memcmp(buffer, "OK", 2) == 0) - { - retry = 0; - } - else - { - block--; - if (retry++ >= 8) - { - error = -1; - break; - } - else - { - buffer[length] = 0; - printf("%s",buffer); - port_rts_clear(port); - usleep(300000); - port_rts_set(port); - bzero(buffer, sizeof(buffer)); - length = port_readline(port, buffer, sizeof(buffer), 800); - if(memcmp(buffer, "CDI", 3) == 0) - { - printf("R"); - } - } - } - } - else - { - error = -1; - break; - } - } - - if (!error) - { - printf("w"); fflush(stdout); - bzero(buffer, sizeof(buffer)); - length = port_readline(port, buffer, sizeof(buffer), 800); - if(memcmp(buffer, "WROK", 4) == 0) - { - error = 0; - } - else - { - printf("%c%c", buffer[0], buffer[1]); - error = -1; - } - } - - if (!error) printf("OK\r"); - return error; -} - diff --git a/tools/sensinode/nano_programmer/ihex.c b/tools/sensinode/nano_programmer/ihex.c deleted file mode 100644 index 83234714e..000000000 --- a/tools/sensinode/nano_programmer/ihex.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#include -#include -#include -#include - -#include - -int hexfile_parse(char *line, unsigned int *type, unsigned int *addr, unsigned char *buffer) -{ - unsigned int row_len = 0; - unsigned int row_index = 7; - unsigned int i; - int tmp; - - uint8_t cksum = 0; - int retval = 0; - - retval = sscanf(line, ":%2x%4x%2x", &row_len, addr, type); - - cksum += row_len; - cksum += *addr >> 8; - cksum += *addr & 0xFF; - cksum += *type; - - i = 0; - if (retval == 3) - { - while(i < row_len) - { - - if (sscanf(&line[row_index], "%2x", &tmp) == 1) - { - cksum += tmp; - buffer[i++] = (unsigned char) tmp; - row_index += 2; - } - else return -1; - } - if (sscanf(&line[row_index], "%2x", &tmp) == 1) - { - if ((cksum + (uint8_t) tmp) == 0) return row_len; - } - } - return -1; -} - -int hexfile_out(char *line, unsigned int type, unsigned int address, unsigned char *data, unsigned int bytes) -{ - uint8_t cksum = 0; - uint8_t i = 0; - char tmp[8]; - - sprintf(line, ":%2.2X%4.4X%2.2X", bytes, address, type); - cksum -= bytes; - cksum -= address >> 8; - cksum -= address & 0xFF; - cksum -= type; - - for (i=0; i - -#include "port.h" - -int port_open(port_t **port, char *device) -{ - port_t *new_port = (port_t *) malloc(sizeof(port_t)); - char err_string[128]; - - *port = new_port; - - new_port->device = 0; - new_port->handle = 0; - - new_port->handle = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); - - if (new_port->handle <= 0) - { - strerror_r(errno, err_string, 128); - - printf("Serial port open failed with error message: %s.\n", err_string); - return(-1); - } - else - { - tcgetattr(new_port->handle, &(new_port->old_params)); - - fcntl(new_port->handle, F_SETFL, FASYNC); - printf("Serial port %s opened succesfully.\n", device); - - return(0); - } -} - -int port_close(port_t *port) -{ - if (!port) - return(-1); - - if ((port->handle) > 0) - { - tcflush(port->handle, TCIFLUSH); - tcsetattr(port->handle,TCSANOW,&(port->old_params)); - - close(port->handle); - port->handle = 0; - } - - if (port->device) free(port->device); - port->device = 0; - free(port); - - return(1); -} - - -/** @todo port_write() function probably needs mutexes -mjs */ - -int port_write(port_t *port, unsigned char *buffer, size_t buflen) -{ - int i=0; - - if (!port) return -1; - - /** @todo The write to serial port is at the moment done one octet at a time with 10ms interval between each write operation due to some minor problems in MCU interrupts. -mjs */ - while(i < buflen) - { - write(port->handle, &(buffer[i]), 1); - tcflush(port->handle, TCIFLUSH); - i++; - } - -/* write(port->handle, &(buffer[i]), buflen);*/ - - tcflush(port->handle, TCIFLUSH); - - return(0); -} - -int port_read(port_t *port, unsigned char *buffer, size_t buflen) -{ - unsigned int l = 0; - l = read(port->handle, buffer, buflen); - return(l); -} - -int port_set_params(port_t *port, uint32_t speed, uint8_t rtscts) -{ - int rate = B115200; - struct termios newtio; - - if (!port) return -1; - - switch (speed) - { - case 230400: - rate = B230400; - break; - - case 0: - case 115200: - rate = B115200; - break; - - case 57600: - rate = B57600; - break; - - case 38400: - rate = B38400; - break; - - case 19200: - rate = B19200; - break; - - case 9600: - rate = B9600; - break; - - default: - return -1; - - } - bzero(&newtio, sizeof(newtio)); - - if (speed == 9600) - { - newtio.c_cflag |= CS8 | CSTOPB | CLOCAL | CREAD; - } - else - { - newtio.c_cflag |= CS8 | CLOCAL | CREAD; - } - if (rtscts) - { - newtio.c_cflag |= CRTSCTS; - } - newtio.c_iflag = IGNPAR; - - cfsetispeed(&newtio, rate); - cfsetospeed(&newtio, rate); - - newtio.c_cc[VTIME] = 0; - newtio.c_cc[VMIN] = 1; - -#if 0 - newtio.c_cflag = rate | CS8 | CLOCAL | CREAD | CSTOPB; -/* if (rts_cts) newtio.c_cflag |= CRTSCTS;*/ - - newtio.c_iflag = IGNPAR; - newtio.c_oflag = 0; - - newtio.c_lflag = 0; - - newtio.c_cc[VTIME] = 0; - newtio.c_cc[VMIN] = 1; -#endif - - tcflush(port->handle, TCIFLUSH); - tcsetattr(port->handle,TCSANOW,&newtio); - - return(0); -} - -int port_dtr_set(port_t *port) -{ - int port_state = TIOCM_DTR; - - if (!port) return(-1); - -/* error = ioctl(port->handle, TIOCMGET, &port_state); - port_state |= TIOCM_RTS; - ioctl(port->handle, TIOCMSET, &port_state);*/ - - ioctl(port->handle, TIOCMBIS, &port_state); - return 0; -} - -int port_dtr_clear(port_t *port) -{ - int port_state = TIOCM_DTR; - - if (!port) return(-1); - - ioctl(port->handle, TIOCMBIC, &port_state); - return 0; -} - -int port_rts_set(port_t *port) -{ - int port_state = TIOCM_RTS; - - if (!port) return(-1); - - ioctl(port->handle, TIOCMBIS, &port_state); - return 0; -} - -int port_rts_clear(port_t *port) -{ - int port_state = TIOCM_RTS; - - if (!port) return(-1); - - ioctl(port->handle, TIOCMBIC, &port_state); - return 0; -} - -int port_get(port_t *port, unsigned char *buffer, int timeout) -{ - struct pollfd pfds; - unsigned int nfds = 1; - int bytes = 0; - int rval; - - pfds.fd = (int)(port->handle); - pfds.events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL; - - rval = poll(&pfds, nfds, timeout); - - if((rval & POLLIN) != POLLIN) - { - return(-1); - } - else - { - bytes = port_read(port, buffer, 1); - } - return bytes; -} - -int port_readline(port_t *port, unsigned char *buffer, int buf_size, int timeout) -{ - int length = 0; - struct pollfd pfds; - unsigned int nfds = 1; - int bytes = 0; - int rval; - - pfds.fd = (int)(port->handle); - pfds.events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL; - - do - { - rval = poll(&pfds, nfds, timeout); - if((rval & POLLIN) != POLLIN) - { - return(length); - } - else - { - bytes = port_read(port, &(buffer[length]), 1); - if (buffer[length] == '\n') - { - buf_size = length; - } - length += bytes; - } - - }while(length < buf_size); - - buffer[length] = 0; - - if(length != 0) - return length; - else - return(-1); -} - -int port_write_echo(port_t *port, char *string) -{ - int length = 0; - int retry = 0; - unsigned char byte; - - while( (string[length]) && (retry < 100) ) - { - port_write(port, (unsigned char *) &string[length], 1); - while (retry++ < 100) - { - if (port_read(port, &byte, 1) == 1) - { -/* printf("%c",byte);*/ - if (byte == string[length]) - { - retry = 0; - length++; - break; - } - else retry = 100; - } - else usleep(1000); - } - } - if ((string[strlen(string)-1] == '\r') && (retry < 100) ) - { /*wait for \n*/ - retry = 0; - while (retry++ < 100) - { - if (port_read(port, &byte, 1) == 1) - { -/* printf("%c",byte);*/ - break; - } - else usleep(1000); - } - } - - if (retry >= 100) return 0; - else return length; -} - - -int port_write_8byte_no_echo(port_t *port, int dlen, char *string) -{ - int length = 0; - int total_len; - int wrbytes = 4; - - total_len = dlen; - -/* printf("total: %d, length: %d, dlen: %d.\n", total_len, length, dlen); */ - while(total_len > length) - { - if((total_len - length) >= wrbytes) - { - port_write(port, (unsigned char *)&string[length], wrbytes); - length += wrbytes; - } - else - { - port_write(port, (unsigned char *)&string[length], total_len - length); - length += total_len - length; - } - usleep(1250); - - } - - return(length); -} - diff --git a/tools/sensinode/nano_programmer/nano_programmer b/tools/sensinode/nano_programmer/nano_programmer deleted file mode 100755 index fd3e46b8a..000000000 Binary files a/tools/sensinode/nano_programmer/nano_programmer and /dev/null differ diff --git a/tools/sensinode/nano_programmer/port.h b/tools/sensinode/nano_programmer/port.h deleted file mode 100644 index 62a6b9270..000000000 --- a/tools/sensinode/nano_programmer/port.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#ifndef _PORT_H -#define _PORT_H - -#ifndef PLATFORM_WINDOWS -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#else -#include "windows.h" -#include -#include "ftd2xx.h" -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -#ifndef PLATFORM_WINDOWS -typedef struct -{ - int handle; - char *device; - struct termios old_params; -}port_t; - -extern int port_open(port_t **port, char *device); -#else -typedef struct port_t -{ - FT_HANDLE handle; - int device; - HANDLE event_handle; -}port_t; - -extern int port_open(port_t **port, int device); -#endif - -extern int port_close(port_t *port); -extern int port_write(port_t *port, unsigned char *buffer, size_t buflen); -extern int port_read(port_t *port, unsigned char *buffer, size_t buflen); -extern int port_get(port_t *port, unsigned char *buffer, int timeout); -extern int port_set_params(port_t *port, uint32_t speed, uint8_t rtscts); -extern int port_dtr_set(port_t *port); -extern int port_dtr_clear(port_t *port); -extern int port_rts_set(port_t *port); -extern int port_rts_clear(port_t *port); -extern int port_readline(port_t *port, unsigned char *buffer, int buf_size, int timeout); -extern int port_write_echo(port_t *port, char *string); -extern int port_write_8byte_no_echo(port_t *port, int dlen, char *string); - -#ifdef __cplusplus -} -#endif -#endif /* _PORT_H */ diff --git a/tools/sensinode/nano_programmer/programmer.c b/tools/sensinode/nano_programmer/programmer.c deleted file mode 100644 index ee82c9389..000000000 --- a/tools/sensinode/nano_programmer/programmer.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#include -#include -#include - -#include "port.h" -#include "programmer.h" - -#include - -extern int cdi_programmer(conf_opts_t *conf, char *filename); - -void usage(char *prg_name) -{ - printf("\nUsage: %s [-d device]\n", prg_name); - printf("General options:\n"); - printf(" -V/--version Get programmer version\n"); - printf(" -1/--d100 Use D100 board (default D200)\n"); - printf("Operating modes:\n"); - printf(" -b/--bios to get programmer BIOS version\n"); - printf(" -P/--program [ihex file] Do a complete programming sequence (write and verify)\n"); - printf(" -v/--verify [ihex file] Verify against ihex file\n"); - printf(" -r/--read [ihex file] Read program code into ihex file\n"); - printf(" -m/--mac Read device MAC address\n"); - printf(" -Q/--write-mac [MAC address] Write device MAC address\n"); - printf(" -e/--erase Erase flash (erases MAC address!)\n"); - printf("Programming options:\n"); - printf(" -l/--linear Force linear model for extended addresses (not SDCC file)\n"); - printf(" -s/--sdcc Force SDCC model for extended addresses (SDCC file)\n"); - printf("Defaults:\n"); -#ifndef PLATFORM_WINDOWS - printf("device /dev/ttyUSB0\n"); -#else - printf("device 0\n"); -#endif -} - -conf_opts_t conf_opts; - -static int option_index = 0; - -int do_exit = 0; - -#define OPTIONS_STRING "d:ec1lsmVbP:v:r:Q:" -/* long option list */ -static struct option long_options[] = -{ - {"device", 1, NULL, 'd'}, - {"psoc", 0, NULL, 'p'}, - {"d100", 0, NULL, '1'}, - {"erase", 0, NULL, 'e'}, - {"mac", 0, NULL, 'm'}, - {"linear", 0, NULL, 'l'}, - {"sdcc", 0, NULL, 's'}, - {"cdi", 0, NULL, 'c'}, - {"version", 0, NULL, 'V'}, - {"bios", 0, NULL, 'b'}, - {"program", 1, NULL, 'P'}, - {"verify", 1, NULL, 'v'}, - {"read", 1, NULL, 'r'}, - {"write-mac", 1, NULL, 'Q'}, - {0, 0, 0, 0} -}; - -int parse_opts(int count, char* param[]) -{ - int opt; - int error=0; - - conf_opts.target_type = CDI; - while ((opt = getopt_long(count, param, OPTIONS_STRING, - long_options, &option_index)) != -1) - { - switch(opt) - { - case 'V': - conf_opts.target_type = VERSION; - break; - - case '1': - conf_opts.prg_type = 1; - break; - - case 'c': - conf_opts.target_type = CDI; - break; - - case 'd': -#ifdef PLATFORM_WINDOWS - if (sscanf(optarg, "%d", &conf_opts.device) != 1) - { - printf("Device ID must be a positive integer.\n"); - conf_opts.action = ' '; - } -#else - printf("device:%s\n", optarg); - strcpy(conf_opts.device, optarg); -#endif - break; - - case 'P': - printf("Programming mode.\n"); - conf_opts.action = 'P'; - strcpy(conf_opts.ihex_file, optarg); - break; - - case 's': - if (conf_opts.page_mode == PAGE_UNDEFINED) - { - conf_opts.page_mode = PAGE_SDCC; - } - else - { - printf("Only one paging option allowed.\n"); - error = -1; - } - break; - - case 'l': - if (conf_opts.page_mode == PAGE_UNDEFINED) - { - conf_opts.page_mode = PAGE_LINEAR; - } - else - { - printf("Only one paging option allowed.\n"); - error = -1; - } - break; - - case 'e': - printf("Erase.\n"); - conf_opts.action = 'e'; - break; - - case 'm': - printf("Get MAC.\n"); - conf_opts.action = 'm'; - break; - - case 'b': - printf("Get BIOS version\n"); - conf_opts.action = 'b'; - break; - - case 'Q': - printf("Write MAC.\n"); - conf_opts.action = 'Q'; - if (sscanf(optarg, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", - &conf_opts.write_mac[0], &conf_opts.write_mac[1], - &conf_opts.write_mac[2], &conf_opts.write_mac[3], - &conf_opts.write_mac[4], &conf_opts.write_mac[5], - &conf_opts.write_mac[6], &conf_opts.write_mac[7]) != 8) - { - printf("Invalid MAC.\n"); - conf_opts.action = ' '; - } - break; - - case 'v': - printf("Verify by comparing to ihex file:%s\n", optarg); - conf_opts.action = 'v'; - strcpy(conf_opts.ihex_file, optarg); - break; - - case 'r': - printf("Read program to ihex file:%s\n", optarg); - conf_opts.action = 'r'; - strcpy(conf_opts.ihex_file, optarg); - break; - - case '?': - printf("Duh\n"); - error = -1; - break; - } - } - - if (!error && (conf_opts.target_type == CDI) ) - { -#ifdef PLATFORM_WINDOWS - printf("Setup: Device %d.\n", conf_opts.device); -#else - printf("Setup: Device %s.\n", conf_opts.device); -#endif - } - - return error; -} -/* -int port_write_8byte_echo(port_t *port, char *string) -{ - int length = 0; - int total_len; - int i, j; - struct pollfd pfds; - unsigned int nfds = 1; - int rval = 0; - - int wrbytes = 2; - unsigned char byte8[wrbytes]; - - pfds.fd = (int)(port->handle); - pfds.events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL; - - total_len = strlen(string); - - while(total_len > length) - { - if(total_len - length >= wrbytes) - { - i=0; - port_write(port, (unsigned char *)&string[length], wrbytes); - - if((rval = poll(&pfds, nfds, 100)) == 0) - { - printf("Timed out...\n"); - return(-1); - } - else - { - while(i %.2x\n", string[length+j], byte8[j]); - } - - return(-1); - } - else - { - printf("8Bwok - "); - fflush(stdout); - length += wrbytes; - } - - } - } - else - { - i=0; - port_write(port, (unsigned char *)&string[length], total_len - length); - - if((rval = poll(&pfds, nfds, 100)) == 0) - { - printf("Timed out...\n"); - return(-1); - } - else - { - while(i<(total_len-length)) - { - i = port_read(port, &byte8[i], total_len - length); - } - if(i != total_len - length || memcmp(byte8, &string[length], total_len - length) != 0) - { - printf("Got wrong length or wrong bytes back.\n"); - for(j=0;j %.2x\n", string[length+j], byte8[j]); - } - - return(-1); - } - else - { - printf("<8Bwok - \n"); - fflush(stdout); - length += (total_len - length); - } - } - } - - usleep(5000); - - } - - return(length); -} -*/ -#ifdef PLATFORM_WINDOWS -int programmer_init(int device, port_t **port) -#else -int programmer_init(char *device, port_t **port) -#endif -{ - int error = port_open(port, device); - uint8_t buffer[8]; - - buffer[0] = 0; - - if (error >= 0) - { - if (conf_opts.prg_type == 1) - { - int retry = 0; - port_set_params(*port, 9600, 0); - // Activate programming... - port_dtr_clear(*port); - port_rts_clear(*port); - sleep(1); - printf("Select D100.\n"); - port_rts_set(*port); - sleep(1); - buffer[0] = '\r'; - while (retry++ < 3) - { - int length; - port_write_echo(*port, "q\r"); - length = port_readline(*port, buffer, sizeof(buffer), 800); - if (length) - { - if (*buffer == '!') - { - printf("D100 found.\n"); - return 0; - } - } - } - printf("No programmer found.\n"); - return -1; - } - else - { - port_set_params(*port, 57600, 0); - // Activate programming... - port_dtr_clear(*port); - port_rts_clear(*port); - usleep(300000); - printf("Select D200.\n"); - port_rts_set(*port); - usleep(200000); - port_set_params(*port, 57600, 1); - port_write(*port, (uint8_t *)"\r", 1); - usleep(100000); - if ((port_get(*port, buffer, 500) >= 1) && (buffer[0] == '!')) - { - printf("D200 found.\n"); - return 0; - } - printf("No programmer found.\n"); - return -1; - } - } - return error; -} - -void programmer_close(port_t *port) -{ - if (port) - { - port_rts_clear(port); - port_dtr_set(port); - sleep(1); - port_close(port); - printf("Port closed.\n"); - } -} - -int main(int argc, char *argv[]) -{ - int error = 0; - - conf_opts.target_type = 0; - conf_opts.action = 0; - conf_opts.prg_type = 2; - - -#ifndef PLATFORM_WINDOWS - strncpy(conf_opts.device, "/dev/ttyUSB0", 12); -/* Install a new handler for SIGIO. - * - * According to man 7 signal this signal is by default ignored by most systems. - * It seems that pre FC7 this was true for Fedoras also. We have noticed that at least - * on some FC7 installations the default action has changed. We avoid abnormal program - * exits by defining the SIGIO as SIG_IGN (ignore). - mjs - */ - if(signal(SIGIO, SIG_IGN) == SIG_ERR) - { - printf("%s error: failed to install SIGIO handler. Exit.\n", argv[0]); - exit(EXIT_FAILURE); - } -#else - conf_opts.device = 0; -#endif - - conf_opts.page_mode = PAGE_UNDEFINED; - - if ( (argc <= 1) || (error = parse_opts(argc, argv)) ) - { - usage(argv[0]); - if (error < 0) return error; - else return 0; - } - - if(conf_opts.target_type == CDI) - { /*CDI*/ - error = cdi_programmer(&conf_opts, conf_opts.ihex_file); - } - else - { - printf("\nSensinode Nano series programmer "PROGRAMMER_VERSION "\n"); - } - return error; -} diff --git a/tools/sensinode/nano_programmer/programmer.h b/tools/sensinode/nano_programmer/programmer.h deleted file mode 100644 index d8eab549e..000000000 --- a/tools/sensinode/nano_programmer/programmer.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#define PROGRAMMER_VERSION "v1.3" - -typedef enum -{ - PAGE_SDCC, - PAGE_LINEAR, - PAGE_UNDEFINED -}page_mode_t; - -typedef struct { -#ifdef PLATFORM_WINDOWS - int device; -#else - char device[128]; -#endif - int target_type; - int prg_type; - int action; - char ihex_file[128]; - unsigned char write_mac[8]; - page_mode_t page_mode; -}conf_opts_t; - -enum target { UNDEFINED, VERSION, CDI }; - -#ifdef PLATFORM_WINDOWS -extern int programmer_init(int device, port_t **port); -#else -extern int programmer_init(char *device, port_t **port); -#endif - -extern void programmer_close(port_t *port); - diff --git a/tools/sensinode/nano_programmer/windows/port.c b/tools/sensinode/nano_programmer/windows/port.c deleted file mode 100644 index 5b9a09f9c..000000000 --- a/tools/sensinode/nano_programmer/windows/port.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#include "port.h" -#include - -int port_open(port_t **port, int device) -{ - port_t *new_port = (port_t *) malloc(sizeof(port_t)); - FT_STATUS status; - - *port = new_port; - - new_port->device = device; - new_port->handle = 0; - - status = FT_Open(device, &(new_port->handle)); - - if (status != FT_OK) - { - new_port->handle = 0; - - printf("Serial port open failed with error message: %d.\n", (int)status); - return(-1); - } - else - { - DWORD mask; - new_port->event_handle = CreateEvent(NULL, TRUE, FALSE, "SN_USB_UART_EVENTS"); - if (new_port->event_handle == NULL) - { - printf("Event handle creation failed.\n"); - FT_Close(new_port->handle); - new_port->handle = 0; - return(-1); - } - mask = FT_EVENT_RXCHAR | FT_EVENT_MODEM_STATUS; - status = FT_SetEventNotification(new_port->handle,mask,new_port->event_handle); - if (status != FT_OK) - { - printf("Setting event notification failed.\n"); - } - FT_SetTimeouts(new_port->handle,400,0); - return(0); - } -} - -int port_close(port_t *port) -{ - if (!port) - return(-1); - - if ((port->event_handle) != NULL) - { - CloseHandle(port->event_handle); - port->event_handle = NULL; - - FT_Purge(port->handle, FT_PURGE_RX | FT_PURGE_TX); - FT_Close(port->handle); - port->handle = 0; - } - - port->device = 0; - free(port); - - return(1); -} - -int port_set_params(port_t *port, uint32_t speed, uint8_t rtscts) -{ - FT_STATUS status; - - if (!port) return -1; - status = FT_SetBaudRate (port->handle, speed); - if (status != FT_OK) return -1; - if (speed == 9600) - { - status = FT_SetDataCharacteristics(port->handle, FT_BITS_8, FT_STOP_BITS_2, FT_PARITY_NONE); - } - else - { - status = FT_SetDataCharacteristics(port->handle, FT_BITS_8, FT_STOP_BITS_1, FT_PARITY_NONE); - } - - if (status != FT_OK) return -1; - - if (rtscts) - { - status = FT_SetFlowControl(port->handle, FT_FLOW_RTS_CTS, 0, 0); - } - else - { - status = FT_SetFlowControl(port->handle, FT_FLOW_NONE, 0, 0); - } - - if (status != FT_OK) return -1; - - FT_Purge(port->handle, FT_PURGE_RX | FT_PURGE_TX); - - return(0); -} - -int port_dtr_set(port_t *port) -{ - FT_STATUS status; - - if (!port) return(-1); - - status = FT_SetDtr(port->handle); - if (status != FT_OK) - { - printf("Control failed.\n"); - return -1; - } - return 0; -} - -int port_dtr_clear(port_t *port) -{ - FT_STATUS status; - - if (!port) return(-1); - - status = FT_ClrDtr(port->handle); - if (status != FT_OK) - { - printf("Control failed.\n"); - return -1; - } - return 0; -} - -int port_rts_set(port_t *port) -{ - FT_STATUS status; - - if (!port) return(-1); - - status = FT_SetRts(port->handle); - if (status != FT_OK) - { - printf("Control failed.\n"); - return -1; - } - return 0; -} - -int port_rts_clear(port_t *port) -{ - FT_STATUS status; - - if (!port) return(-1); - - status = FT_ClrRts(port->handle); - if (status != FT_OK) - { - printf("Control failed.\n"); - return -1; - } - return 0; -} - -int port_write(port_t *port, unsigned char *buffer, size_t buflen) -{ - FT_STATUS status; - DWORD bytes_out; - - if (!port) return -1; - -// FT_Purge(port->handle, FT_PURGE_RX); - - status = FT_Write (port->handle, (LPVOID) buffer, (DWORD) buflen,&bytes_out); - if (status != FT_OK) return -1; - - return 0; -} - -int port_read(port_t *port, unsigned char *buffer, size_t buflen) -{ - DWORD l = 0; - FT_STATUS status; - status = FT_Read(port->handle, buffer, buflen, &l); - return((int) l); -} - -int port_get(port_t *port, unsigned char *buffer, int timeout) -{ - DWORD bytes = 0; - FT_STATUS status; - - FT_SetTimeouts(port->handle, timeout, 0); - - status = FT_Read(port->handle, buffer, 1, &bytes); - if (status != FT_OK) - { - return(-1); - } - return bytes; -} - -int port_readline(port_t *port, unsigned char *buffer, int buf_size, int timeout) -{ - int length = 0; - DWORD bytes = 0; - FT_STATUS status; - - FT_SetTimeouts(port->handle, timeout, 0); - - do - { - status = FT_Read(port->handle, &buffer[length], 1, &bytes); - length += bytes; - if ((status != FT_OK) || (bytes == 0)) - { - return(length); - } - else - { - if (buffer[length-1] == '\n') - { - buf_size = length; - } - } - }while(length < buf_size); - - buffer[length] = 0; - - if(length != 0) - return length; - else - return(-1); -} - -int port_write_echo(port_t *port, char *string) -{ - int length = 0; - int retry = 0; - unsigned char byte; - DWORD bytes_out; - FT_STATUS status; - - FT_Purge(port->handle, FT_PURGE_RX | FT_PURGE_TX); - - while( (string[length]) && (retry < 100) ) - { - retry = 0; - while (retry++ < 100) - { - status = FT_Write (port->handle, (LPVOID) &string[length], (DWORD) 1,&bytes_out); - if (status != FT_OK) return -1; - if (port_get(port, &byte, 1000) == 1) - { -/* printf("%c",byte);*/ - if (byte == string[length]) - { - retry = 0; - length++; - break; - } - else retry = 100; - } - else usleep(500); - } - } - if ((string[strlen(string)-1] == '\r') && (retry < 100) ) - { /*wait for \n*/ - retry = 0; - while (retry++ < 100) - { - if (port_get(port, &byte, 1000) == 1) - { -/* printf("%c",byte);*/ - break; - } - else usleep(500); - } - } - - if (retry >= 100) return 0; - else return length; -} - -#if 0 - -int port_write_echo(port_t *port, char *string) -{ - int length = 0; - int retry = 0; - unsigned char byte; - - while( (string[length]) && (retry < 100) ) - { - port_write(port, (unsigned char *) &string[length], 1); - while (retry++ < 100) - { - if (port_read(port, &byte, 1) == 1) - { -/* printf("%c",byte);*/ - if (byte == string[length]) - { - retry = 0; - length++; - break; - } - else retry = 100; - } - else usleep(1000); - } - } - if ((string[strlen(string)-1] == '\r') && (retry < 100) ) - { /*wait for \n*/ - retry = 0; - while (retry++ < 100) - { - if (port_read(port, &byte, 1) == 1) - { -/* printf("%c",byte);*/ - break; - } - else usleep(1000); - } - } - - if (retry >= 100) return 0; - else return length; -} - - -int port_write_8byte_no_echo(port_t *port, int dlen, char *string) -{ - int length = 0; - int total_len; - int wrbytes = 4; - - total_len = dlen; - -/* printf("total: %d, length: %d, dlen: %d.\n", total_len, length, dlen); */ - while(total_len > length) - { - if((total_len - length) >= wrbytes) - { - port_write(port, (unsigned char *)&string[length], wrbytes); - length += wrbytes; - } - else - { - port_write(port, (unsigned char *)&string[length], total_len - length); - length += total_len - length; - } - usleep(1250); - - } - - return(length); -} - -#endif diff --git a/tools/sensinode/nano_usb_programmer/Makefile b/tools/sensinode/nano_usb_programmer/Makefile deleted file mode 100644 index 2c1e40988..000000000 --- a/tools/sensinode/nano_usb_programmer/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -EXE_MAKE=$(notdir $(shell which "make.exe")) -ifeq "$(EXE_MAKE)" "make.exe" -PLATFORM=windows -else -PLATFORM=linux -endif - -include Rules.make - -APP = nano_usb_programmer$(SUFFIX) -OBJS = $(SOURCES:.c=.o) - -all: $(APP) - -$(APP): $(OBJS) Makefile $(SOURCES) - $(CC) -o $(APP) $(CFLAGS) $(OBJS) $(LDFLAGS) - -platform-test: - @echo $(PLATFORM) - -clean: - rm -f *.o ; rm -f $(APP) - -.c.o: - $(CC) -c -o $(<:.c=.o) $(CFLAGS) $< - -ftd2xx.def: - echo EXPORTS > ftd2xx.def - nm ftd2xx.lib | grep ' T _' | sed 's/.* T _//' >> ftd2xx.def - -ftd2xx.dll.a: ftd2xx.def - dlltool --def ftd2xx.def --dllname ftd2xx.dll --output-lib ftd2xx.dll.a diff --git a/tools/sensinode/nano_usb_programmer/README.md b/tools/sensinode/nano_usb_programmer/README.md deleted file mode 100644 index c5ea77f8b..000000000 --- a/tools/sensinode/nano_usb_programmer/README.md +++ /dev/null @@ -1,60 +0,0 @@ -Nano USB Programmer -=================== - -An USB programmer for the Sensinode NanoRouter N600. - -Copyright 2007-2008 Sensinode Ltd. - -Installation ------------- - -### Linux - -The installation is quite simple but requires the user to obtain the FTDI -development library. The installation also requires root privileges in some -phases (the ldconfig command to be more specific). Running the -Nano_USB_Programmer executable might also require root privileges. - -- unpack the Nano_USB_Programmer-v[xxx].zip to a directory -- get the FTDI development library from - [http://www.ftdichip.com/Drivers/D2XX/Linux/libftd2xx0.4.13.tar.gz](http://www.ftdichip.com/Drivers/D2XX/Linux/libftd2xx0.4.13.tar.gz) -- unpack the ftdi archive -- copy the library static_lib/libftd2xx.a.[version] into /usr/lib -- copy the library libftd2xx.so.[version] into /usr/lib -- make a symbolic link to the library, for example: ln -s - /usr/lib/libftd2xx.so.0.4.13 /usr/lib/libftd2xx.so -- run ldconfig -- copy the header files into the nano_usb_programmer/ftdi_linux/ directory -- go to the programmer directory and run make - -### Windows/Cygwin - -- The FTDI library can be downloaded at: - -[http://www.ftdichip.com/Drivers/CDM/CDM%202.02.04%20WHQL%20Certified.zip](http://www.ftdichip.com/Drivers/CDM/CDM%202.02.04%20WHQL%20Certified.zip) - -- Copy header files (ftd2xx.h), ftd2xx.lib and ftd2xx.dll to nano_usb_programmer/ftdi_win32 -- Copy the ftd2xx.dll to your windows system32 directory - -Usage ------ - -Usage info for the Nano_USB_Programmer is available with command -./nano_usb_programmer --help. Note that use might require root/administrator -privileges depending on system configuration. - -Known problems (Linux) ----------------------- - -There's one known problem at the moment. The N600 must be unplugged and plugged -in again after it has been programmed or the MAC address has been read from it -before it can respond to the programmer again. The reason for this is the FTDI -library is not perfectly integrated with the Linux serial driver. - -README Version --------------- - -v1.0 2007-11-14 Mikko Saarnivala Initial release -v1.1 2007-11-15 Mikko Saarnivala A small error in the instructions fixed -v1.2 2007-11-19 Mikko Saarnivala Added the FTDI CBUS2 value handling -v1.3 2008-01-31 Martti Huttunen Multi-platform build and updated instructions diff --git a/tools/sensinode/nano_usb_programmer/Rules.make b/tools/sensinode/nano_usb_programmer/Rules.make deleted file mode 100644 index 034cd0321..000000000 --- a/tools/sensinode/nano_usb_programmer/Rules.make +++ /dev/null @@ -1,14 +0,0 @@ -ifeq "$(PLATFORM)" "linux" -CC=gcc -CFLAGS= -I. -I./ftdi_linux -L. -L./ftdi_linux -DPLATFORM_LINUX -LDFLAGS= -lftd2xx -Wl,-rpath /usr/local/lib -SOURCES=main.c prog.c cdi.c ihex.c -SUFFIX= -else -CC=gcc -CFLAGS=-I. -I./ftdi_win32 -L. -L./ftdi_win32 -DPLATFORM_WINDOWS -CFLAGS+= -mwin32 -LDFLAGS=ftdi_win32/ftd2xx.lib -lkernel32 -SOURCES=main.c prog.c cdi.c ihex.c -SUFFIX=.exe -endif diff --git a/tools/sensinode/nano_usb_programmer/cdi.c b/tools/sensinode/nano_usb_programmer/cdi.c deleted file mode 100644 index 2d490869f..000000000 --- a/tools/sensinode/nano_usb_programmer/cdi.c +++ /dev/null @@ -1,506 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#include -#ifdef PLATFORM_WINDOWS -#include -#endif -#include "cdi.h" - -/*read none/8*/ -#define CDI_CHIP_ERASE 0x10 -#define CDI_WR_CONFIG 0x19 -#define CDI_SET_HW_BRKPNT 0x3B - -/*read 8*/ -#define CDI_RD_CONFIG 0x24 -#define CDI_READ_STATUS 0x34 -#define CDI_HALT 0x44 -#define CDI_RESUME 0x4C -#define CDI_STEP_INSTR 0x5C - -/*variable len, add data length to command byte*/ -#define CDI_DBGINSTR 0x54 -#define CDI_STEP_REPLACE 0x64 - -/*response = 16 bits*/ -#define CDI_GET_PC 0x28 -#define CDI_GET_CHIP_ID 0x68 - - -/* internals */ -void cdi_command_push(uint8_t *byte, uint8_t bytes_out, uint16_t *retval, uint8_t return_bits); - -void cdi_flash_bank(uint8_t bank, uint8_t unif_mode); - -void cdi_dptr_write(uint16_t value); - -uint8_t cdi_reg_read(uint8_t reg_addr); -void cdi_reg_write(uint8_t reg_addr, uint8_t value); - -void cdi_xdata_write(uint8_t value); -uint8_t cdi_xdata_read(void); - -void cdi_flash_init(void); -void cdi_flash_write_page(void); - -uint32_t cdi_addr = 0; - -#define pause_ms(x) usleep(x*1000) -#define pause_us(x) usleep(x) - -void cdi_command_push(uint8_t *byte, uint8_t bytes_out, uint16_t *retval, uint8_t return_bits) -{ - uint8_t i, val; - - for (i=0; i>= 3; - for (i=0; i> 8); /*immediateh*/ - out[3] = value; /*immediatel*/ - cdi_command_push(out, 4, &retval, 8); -} - - -uint8_t cdi_reg_read(uint8_t reg_addr) -{ - uint8_t out[3]; - uint16_t retval; - - out[0] = CDI_DBGINSTR + 2; /*command length 2 bytes*/ - out[1] = 0xE5; /*mov a, sfr*/ - out[2] = reg_addr; /*sfr = reg_addr*/ - cdi_command_push(out, 3, &retval, 8); - - return (uint8_t) retval; -} - - -void cdi_flash_bank(uint8_t bank, uint8_t unif_mode) -{ - uint8_t out; - - out = (bank << 4) + 1; - out &= 0x31; - if (unif_mode) out |= 0x40; /*set unified memory model*/ - - cdi_reg_write(0xC7, out); -} - - -void cdi_flash_read(uint8_t *ptr, uint16_t bytes) -{ - uint16_t i; - uint8_t out[4]; - uint16_t retval; - - cdi_flash_bank((cdi_addr >> 15), 0); - - cdi_dptr_write(cdi_addr | 0x8000); - - for (i=0; i> 10) & 0x7F); /*sfr = FADDRH*/ - cdi_reg_write(0xAC, (cdi_addr >> 2)); /*sfr = FADDRL*/ - - /*erase page*/ - cdi_reg_write(0xAE, 0x01); - pause_ms(40); - - /*set program counter*/ - out[0] = CDI_DBGINSTR + 3; /*command length 3 bytes*/ - out[1] = 0x02; /*ljmp immediate16*/ - out[2] = 0xE0; /*immediateh*/ - out[3] = 0x00; /*immediatel*/ - cdi_command_push(out, 4, &retval, 8); - - /*set breakpoint*/ - out[0] = CDI_SET_HW_BRKPNT; /*command length 3 bytes*/ - out[1] = 0x04; - out[2] = 0xE0; /*immediateh*/ - out[3] = sizeof(cdi_ram_code)-2; /*immediatel*/ - cdi_command_push(out, 4, &retval, 0); - - cdi_dptr_write(0xE800); /*data area, set your page data here*/ - /*execute*/ - out[0] = CDI_RESUME; /*command length 3 bytes*/ - cdi_command_push(out, 1, &retval, 8); - - pause_ms(30); - out[3]= 0; - do - { - pause_ms(20); - out[0] = CDI_READ_STATUS; - cdi_command_push(out, 1, &retval, 8); - printf("-"); - fflush(stdout); - }while( ((retval & 0x20) == 0) && (out[3]++ < 200) ); -} - -int cdi_flash_write(uint8_t *ptr, uint16_t length) -{ - uint16_t i, retval; - uint8_t out[3]; - - if (length > 2048) return -1; - - cdi_addr &= 0x1F800; /*make sure address is on page boundary*/ - - printf("0x%6.6X: ", cdi_addr); - fflush(stdout); - cdi_dptr_write(0xE800); /*our page data buffer is here*/ - for (i=0; i< length; i++) - { - cdi_xdata_write(*ptr++); - if ((i & 0x3F) == 0) - { - printf("."); - } - if ((i & 0x0F) == 0x00) - { - printf("\bo"); - } - if ((i & 0x0F) == 0x08) - { - printf("\b."); - } - fflush(stdout); - } - while(i<2048) - { - cdi_xdata_write(0xFF); - if ((i & 0x3F) == 0) - { - printf("."); - } - if ((i & 0x0F) == 0x00) - { - printf("\bo"); - } - if ((i & 0x0F) == 0x08) - { - printf("\b."); - } - fflush(stdout); - i++; - } - - out[0] = CDI_HALT; - cdi_command_push(out, 1, &retval, 8); - - out[0] = CDI_READ_STATUS; - retval = 0; - cdi_command_push(out, 1, &retval, 8); - if ((retval & 0xFF) == 0xB2) - { - /*restore config*/ - out[0] = CDI_WR_CONFIG; /*command length 3 bytes*/ - out[1] = 0x0E; /*write flash area*/ - cdi_command_push(out, 2, &retval, 0); - /*set flash timings and copy code to ram*/ - cdi_flash_init(); - /*write page*/ - cdi_flash_write_page(); - cdi_addr += 2048; /*increment page address*/ - pause_ms(10); - } - else - { - return -1; - } - return 0; -} - -int cdi_flash_write_mac(uint8_t *ptr) -{ - uint16_t i, retval; - uint8_t out[3]; - - cdi_addr = 0x1F800; /*last page*/ - - printf("0x%6.6X", cdi_addr); - fflush(stdout); - cdi_dptr_write(0xEFF8); /*our page data buffer is here*/ - for (i=0; i<8; i++) - { - cdi_xdata_write(*ptr++); - if ((i & 0x0F) == 0) - { - printf("."); - fflush(stdout); - } - } - - out[0] = CDI_HALT; - cdi_command_push(out, 1, &retval, 8); - - out[0] = CDI_READ_STATUS; - retval = 0; - cdi_command_push(out, 1, &retval, 8); - if ((retval & 0xFF) == 0xB2) - { - /*restore config*/ - out[0] = CDI_WR_CONFIG; /*command length 3 bytes*/ - out[1] = 0x0E; /*write flash area*/ - cdi_command_push(out, 2, &retval, 0); - /*set flash timings and copy code to ram*/ - cdi_flash_init(); - /*write page*/ - cdi_flash_write_page(); - cdi_addr += 2048; /*increment page address*/ - pause_ms(10); - } - else - { - return -1; - } - return 0; -} - -int cdi_start(uint16_t *chip_id) -{ - uint8_t out[3]; - uint16_t retval; - - prog_start(); /*do the CDI startup sequence*/ - - out[0] = CDI_READ_STATUS; - cdi_command_push(out, 1, &retval, 8); - - printf("Status: %2.2X.\n", retval & 0xFF); - - out[0] = CDI_GET_CHIP_ID; - cdi_command_push(out, 1, &retval, 16); - - *chip_id = retval; - - out[0] = CDI_HALT; - cdi_command_push(out, 1, &retval, 8); - - pause_ms(100); - - out[0] = CDI_WR_CONFIG; /*command length 3 bytes*/ - out[1] = 0x0E; /*write flash area*/ - cdi_command_push(out, 2, &retval, 0); - - pause_ms(10); - - cdi_reg_write(0xC6, 0xC9); /*sfr = CLKCON*/ - - pause_ms(10); - - cdi_reg_write(0xAB, 0x15); /*sfr = FWT*/ - - cdi_addr = 0; - - return 0; -} - -int cdi_erase(void) -{ - uint8_t out[3]; - uint16_t retval; - uint8_t i; - - out[0] = CDI_WR_CONFIG; - out[1] = 0x0E; - cdi_command_push(out, 2, &retval, 0); - out[0] = CDI_CHIP_ERASE; - cdi_command_push(out, 1, &retval, 0); - retval = 0; - i = 0; - do - { - pause_ms(30); - out[0] = CDI_READ_STATUS; - cdi_command_push(out, 1, &retval, 8); - }while( ((retval & 0x84) != 0x80) && (i++ < 100) ); - - cdi_addr = 0; - - if (i >= 100) - { - return -1; - } - return 0; -} - -void cdi_set_address(uint32_t address) -{ - cdi_addr = address; -} diff --git a/tools/sensinode/nano_usb_programmer/cdi.h b/tools/sensinode/nano_usb_programmer/cdi.h deleted file mode 100644 index 40e909178..000000000 --- a/tools/sensinode/nano_usb_programmer/cdi.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#ifndef _CDI_H -#define _CDI_H - -#include "prog.h" - -/* export these */ -extern int cdi_start(uint16_t *chip_id); -extern int cdi_erase(void); - -extern void cdi_set_address(uint32_t address); - -extern void cdi_flash_read(uint8_t *ptr, uint16_t bytes); -extern int cdi_flash_write(uint8_t *ptr, uint16_t length); - -#endif diff --git a/tools/sensinode/nano_usb_programmer/ftdi_linux/WinTypes.h b/tools/sensinode/nano_usb_programmer/ftdi_linux/WinTypes.h deleted file mode 100644 index 4def457b7..000000000 --- a/tools/sensinode/nano_usb_programmer/ftdi_linux/WinTypes.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#ifndef __WINDOWS_TYPES__ -#define __WINDOWS_TYPES__ - -#define MAX_NUM_DEVICES 50 -#include - -typedef unsigned long DWORD; -typedef unsigned long ULONG; -typedef unsigned short USHORT; -typedef short SHORT; -typedef unsigned char UCHAR; -typedef unsigned short WORD; -typedef unsigned char BYTE; -typedef unsigned char *LPBYTE; -typedef int BOOL; -typedef char BOOLEAN; -typedef char CHAR; -typedef int *LPBOOL; -typedef unsigned char *PUCHAR; -typedef const char *LPCSTR; -typedef char *PCHAR; -typedef void *PVOID; -typedef void *HANDLE; -typedef long LONG; -typedef int INT; -typedef unsigned int UINT; -typedef char *LPSTR; -typedef char *LPTSTR; -typedef DWORD *LPDWORD; -typedef WORD *LPWORD; -typedef ULONG *PULONG; -typedef PVOID LPVOID; -typedef void VOID; -typedef unsigned long long int ULONGLONG; - -typedef struct _OVERLAPPED { - DWORD Internal; - DWORD InternalHigh; - DWORD Offset; - DWORD OffsetHigh; - HANDLE hEvent; -} OVERLAPPED, *LPOVERLAPPED; - -typedef struct _SECURITY_ATTRIBUTES { - DWORD nLength; - LPVOID lpSecurityDescriptor; - BOOL bInheritHandle; -} SECURITY_ATTRIBUTES , *LPSECURITY_ATTRIBUTES; - -typedef struct timeval SYSTEMTIME; -typedef struct timeval FILETIME; -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -// -// Modem Status Flags -// -#define MS_CTS_ON ((DWORD)0x0010) -#define MS_DSR_ON ((DWORD)0x0020) -#define MS_RING_ON ((DWORD)0x0040) -#define MS_RLSD_ON ((DWORD)0x0080) - -// -// Error Flags -// - -#define CE_RXOVER 0x0001 // Receive Queue overflow -#define CE_OVERRUN 0x0002 // Receive Overrun Error -#define CE_RXPARITY 0x0004 // Receive Parity Error -#define CE_FRAME 0x0008 // Receive Framing error -#define CE_BREAK 0x0010 // Break Detected -#define CE_TXFULL 0x0100 // TX Queue is full -#define CE_PTO 0x0200 // LPTx Timeout -#define CE_IOE 0x0400 // LPTx I/O Error -#define CE_DNS 0x0800 // LPTx Device not selected -#define CE_OOP 0x1000 // LPTx Out-Of-Paper -#define CE_MODE 0x8000 // Requested mode unsupported - -#ifndef INVALID_HANDLE_VALUE -#define INVALID_HANDLE_VALUE 0xFFFFFFFF -#endif - -#endif diff --git a/tools/sensinode/nano_usb_programmer/ftdi_linux/ftd2xx.h b/tools/sensinode/nano_usb_programmer/ftdi_linux/ftd2xx.h deleted file mode 100644 index f4146f1d8..000000000 --- a/tools/sensinode/nano_usb_programmer/ftdi_linux/ftd2xx.h +++ /dev/null @@ -1,975 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -/*++ - -Copyright (c) 2001-2006 Future Technology Devices International Ltd. - -Module Name: - - ftd2xx.h - -Abstract: - - Native USB interface for FTDI FT8U232/245/2232C - FTD2XX library definitions - -Environment: - - kernel & user mode - -Revision History: - - 13/03/01 awm Created. - 13/01/03 awm Added device information support. - 19/03/03 awm Added FT_W32_CancelIo. - 12/06/03 awm Added FT_StopInTask and FT_RestartInTask. - 18/09/03 awm Added FT_SetResetPipeRetryCount. - 10/10/03 awm Added FT_ResetPort. - /03/04 st modified for linux users - 12/10/04 st added FT_SetVIDPID - - ---*/ - - -#ifndef FTD2XX_H -#define FTD2XX_H - -#ifndef _WINDOWS -#include -#define WINAPI -#endif - -// The following ifdef block is the standard way of creating macros -// which make exporting from a DLL simpler. All files within this DLL -// are compiled with the FTD2XX_EXPORTS symbol defined on the command line. -// This symbol should not be defined on any project that uses this DLL. -// This way any other project whose source files include this file see -// FTD2XX_API functions as being imported from a DLL, whereas this DLL -// sees symbols defined with this macro as being exported. - -#ifdef FTD2XX_EXPORTS -#define FTD2XX_API __declspec(dllexport) -#else -#define FTD2XX_API __declspec(dllimport) -#endif - -#ifndef _WINDOWS -#include "WinTypes.h" - -#ifdef FTD2XX_API -#undef FTD2XX_API -#define FTD2XX_API -#endif -#endif -typedef struct _EVENT_HANDLE{ - pthread_cond_t eCondVar; - pthread_mutex_t eMutex; - int iVar; -} EVENT_HANDLE; - -typedef DWORD *FT_HANDLE; - -typedef ULONG FT_STATUS; - -// -// Device status -// -enum { - FT_OK, - FT_INVALID_HANDLE, - FT_DEVICE_NOT_FOUND, - FT_DEVICE_NOT_OPENED, - FT_IO_ERROR, - FT_INSUFFICIENT_RESOURCES, - FT_INVALID_PARAMETER, - FT_INVALID_BAUD_RATE, //7 - - FT_DEVICE_NOT_OPENED_FOR_ERASE, - FT_DEVICE_NOT_OPENED_FOR_WRITE, - FT_FAILED_TO_WRITE_DEVICE, - FT_EEPROM_READ_FAILED, - FT_EEPROM_WRITE_FAILED, - FT_EEPROM_ERASE_FAILED, - FT_EEPROM_NOT_PRESENT, - FT_EEPROM_NOT_PROGRAMMED, - FT_INVALID_ARGS, - FT_NOT_SUPPORTED, - FT_OTHER_ERROR -}; - - -#define FT_SUCCESS(status) ((status) == FT_OK) - -// -// FT_OpenEx Flags -// - -#define FT_OPEN_BY_SERIAL_NUMBER 1 -#define FT_OPEN_BY_DESCRIPTION 2 - -// -// FT_ListDevices Flags (used in conjunction with FT_OpenEx Flags -// - -#define FT_LIST_NUMBER_ONLY 0x80000000 -#define FT_LIST_BY_INDEX 0x40000000 -#define FT_LIST_ALL 0x20000000 - -#define FT_LIST_MASK (FT_LIST_NUMBER_ONLY|FT_LIST_BY_INDEX|FT_LIST_ALL) - -// -// Baud Rates -// - -#define FT_BAUD_300 300 -#define FT_BAUD_600 600 -#define FT_BAUD_1200 1200 -#define FT_BAUD_2400 2400 -#define FT_BAUD_4800 4800 -#define FT_BAUD_9600 9600 -#define FT_BAUD_14400 14400 -#define FT_BAUD_19200 19200 -#define FT_BAUD_38400 38400 -#define FT_BAUD_57600 57600 -#define FT_BAUD_115200 115200 -#define FT_BAUD_230400 230400 -#define FT_BAUD_460800 460800 -#define FT_BAUD_921600 921600 - -// -// Word Lengths -// - -#define FT_BITS_8 (UCHAR) 8 -#define FT_BITS_7 (UCHAR) 7 -#define FT_BITS_6 (UCHAR) 6 -#define FT_BITS_5 (UCHAR) 5 - -// -// Stop Bits -// - -#define FT_STOP_BITS_1 (UCHAR) 0 -#define FT_STOP_BITS_1_5 (UCHAR) 1 -#define FT_STOP_BITS_2 (UCHAR) 2 - -// -// Parity -// - -#define FT_PARITY_NONE (UCHAR) 0 -#define FT_PARITY_ODD (UCHAR) 1 -#define FT_PARITY_EVEN (UCHAR) 2 -#define FT_PARITY_MARK (UCHAR) 3 -#define FT_PARITY_SPACE (UCHAR) 4 - -// -// Flow Control -// - -#define FT_FLOW_NONE 0x0000 -#define FT_FLOW_RTS_CTS 0x0100 -#define FT_FLOW_DTR_DSR 0x0200 -#define FT_FLOW_XON_XOFF 0x0400 - -// -// Purge rx and tx buffers -// -#define FT_PURGE_RX 1 -#define FT_PURGE_TX 2 - -// -// Events -// - -typedef void (*PFT_EVENT_HANDLER)(DWORD,DWORD); - -#define FT_EVENT_RXCHAR 1 -#define FT_EVENT_MODEM_STATUS 2 - -// -// Timeouts -// - -#define FT_DEFAULT_RX_TIMEOUT 300 -#define FT_DEFAULT_TX_TIMEOUT 300 - -// -// Device types -// - -typedef ULONG FT_DEVICE; - -enum { - FT_DEVICE_BM, - FT_DEVICE_AM, - FT_DEVICE_100AX, - FT_DEVICE_UNKNOWN, - FT_DEVICE_2232C, - FT_DEVICE_232R - }; - - -#ifdef __cplusplus -extern "C" { -#endif - -FTD2XX_API -FT_STATUS WINAPI FT_Open( - int deviceNumber, - FT_HANDLE *pHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_OpenEx( - PVOID pArg1, - DWORD Flags, - FT_HANDLE *pHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ListDevices( - PVOID pArg1, - PVOID pArg2, - DWORD Flags - ); - -FTD2XX_API -FT_STATUS FT_SetVIDPID( - DWORD dwVID, - DWORD dwPID - ); - -FTD2XX_API -FT_STATUS FT_GetVIDPID( - DWORD * pdwVID, - DWORD * pdwPID - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Close( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Read( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesReturned - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Write( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesWritten - ); - -FTD2XX_API -FT_STATUS WINAPI FT_IoCtl( // Linux, OS X: Not supported - FT_HANDLE ftHandle, - DWORD dwIoControlCode, - LPVOID lpInBuf, - DWORD nInBufSize, - LPVOID lpOutBuf, - DWORD nOutBufSize, - LPDWORD lpBytesReturned, - LPOVERLAPPED lpOverlapped - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBaudRate( - FT_HANDLE ftHandle, - ULONG BaudRate - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDivisor( - FT_HANDLE ftHandle, - USHORT Divisor - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDataCharacteristics( - FT_HANDLE ftHandle, - UCHAR WordLength, - UCHAR StopBits, - UCHAR Parity - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetFlowControl( - FT_HANDLE ftHandle, - USHORT FlowControl, - UCHAR XonChar, - UCHAR XoffChar - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ResetDevice( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDtr( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ClrDtr( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetRts( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ClrRts( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetModemStatus( - FT_HANDLE ftHandle, - ULONG *pModemStatus - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetChars( - FT_HANDLE ftHandle, - UCHAR EventChar, - UCHAR EventCharEnabled, - UCHAR ErrorChar, - UCHAR ErrorCharEnabled - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Purge( - FT_HANDLE ftHandle, - ULONG Mask - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetTimeouts( - FT_HANDLE ftHandle, - ULONG ReadTimeout, - ULONG WriteTimeout - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetQueueStatus( - FT_HANDLE ftHandle, - DWORD *dwRxBytes - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetEventNotification( - FT_HANDLE ftHandle, - DWORD Mask, - PVOID Param - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetStatus( - FT_HANDLE ftHandle, - DWORD *dwRxBytes, - DWORD *dwTxBytes, - DWORD *dwEventDWord - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBreakOn( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBreakOff( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetWaitMask( // Linux, OS X: Not supported - FT_HANDLE ftHandle, - DWORD Mask - ); - -FTD2XX_API -FT_STATUS WINAPI FT_WaitOnMask( // Linux, OS X: Not supported - FT_HANDLE ftHandle, - DWORD *Mask - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetEventStatus( - FT_HANDLE ftHandle, - DWORD *dwEventDWord - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ReadEE( - FT_HANDLE ftHandle, - DWORD dwWordOffset, - LPWORD lpwValue - ); - -FTD2XX_API -FT_STATUS WINAPI FT_WriteEE( - FT_HANDLE ftHandle, - DWORD dwWordOffset, - WORD wValue - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EraseEE( - FT_HANDLE ftHandle - ); - -// -// structure to hold program data for FT_Program function -// -typedef struct ft_program_data { - - DWORD Signature1; // Header - must be 0x00000000 - DWORD Signature2; // Header - must be 0xffffffff - DWORD Version; // Header - FT_PROGRAM_DATA version - // 0 = original - // 1 = FT2232C extensions - // 2 = FT232R extensions - - WORD VendorId; // 0x0403 - WORD ProductId; // 0x6001 - char *Manufacturer; // "FTDI" - char *ManufacturerId; // "FT" - char *Description; // "USB HS Serial Converter" - char *SerialNumber; // "FT000001" if fixed, or NULL - WORD MaxPower; // 0 < MaxPower <= 500 - WORD PnP; // 0 = disabled, 1 = enabled - WORD SelfPowered; // 0 = bus powered, 1 = self powered - WORD RemoteWakeup; // 0 = not capable, 1 = capable - // - // Rev4 extensions - // - UCHAR Rev4; // non-zero if Rev4 chip, zero otherwise - UCHAR IsoIn; // non-zero if in endpoint is isochronous - UCHAR IsoOut; // non-zero if out endpoint is isochronous - UCHAR PullDownEnable; // non-zero if pull down enabled - UCHAR SerNumEnable; // non-zero if serial number to be used - UCHAR USBVersionEnable; // non-zero if chip uses USBVersion - WORD USBVersion; // BCD (0x0200 => USB2) - // - // FT2232C extensions - // - UCHAR Rev5; // non-zero if Rev5 chip, zero otherwise - UCHAR IsoInA; // non-zero if in endpoint is isochronous - UCHAR IsoInB; // non-zero if in endpoint is isochronous - UCHAR IsoOutA; // non-zero if out endpoint is isochronous - UCHAR IsoOutB; // non-zero if out endpoint is isochronous - UCHAR PullDownEnable5; // non-zero if pull down enabled - UCHAR SerNumEnable5; // non-zero if serial number to be used - UCHAR USBVersionEnable5; // non-zero if chip uses USBVersion - WORD USBVersion5; // BCD (0x0200 => USB2) - UCHAR AIsHighCurrent; // non-zero if interface is high current - UCHAR BIsHighCurrent; // non-zero if interface is high current - UCHAR IFAIsFifo; // non-zero if interface is 245 FIFO - UCHAR IFAIsFifoTar; // non-zero if interface is 245 FIFO CPU target - UCHAR IFAIsFastSer; // non-zero if interface is Fast serial - UCHAR AIsVCP; // non-zero if interface is to use VCP drivers - UCHAR IFBIsFifo; // non-zero if interface is 245 FIFO - UCHAR IFBIsFifoTar; // non-zero if interface is 245 FIFO CPU target - UCHAR IFBIsFastSer; // non-zero if interface is Fast serial - UCHAR BIsVCP; // non-zero if interface is to use VCP drivers - // - // FT232R extensions - // - UCHAR UseExtOsc; // Use External Oscillator - UCHAR HighDriveIOs; // High Drive I/Os - UCHAR EndpointSize; // Endpoint size - - UCHAR PullDownEnableR; // non-zero if pull down enabled - UCHAR SerNumEnableR; // non-zero if serial number to be used - - UCHAR InvertTXD; // non-zero if invert TXD - UCHAR InvertRXD; // non-zero if invert RXD - UCHAR InvertRTS; // non-zero if invert RTS - UCHAR InvertCTS; // non-zero if invert CTS - UCHAR InvertDTR; // non-zero if invert DTR - UCHAR InvertDSR; // non-zero if invert DSR - UCHAR InvertDCD; // non-zero if invert DCD - UCHAR InvertRI; // non-zero if invert RI - - UCHAR Cbus0; // Cbus Mux control - UCHAR Cbus1; // Cbus Mux control - UCHAR Cbus2; // Cbus Mux control - UCHAR Cbus3; // Cbus Mux control - UCHAR Cbus4; // Cbus Mux control - - UCHAR RIsVCP; // zero if using VCP drivers - -} FT_PROGRAM_DATA, *PFT_PROGRAM_DATA; - - -FTD2XX_API -FT_STATUS WINAPI FT_EE_Program( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_ProgramEx( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA lpData, - char *Manufacturer, - char *ManufacturerId, - char *Description, - char *SerialNumber - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_Read( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_ReadEx( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA lpData, - char *Manufacturer, - char *ManufacturerId, - char *Description, - char *SerialNumber - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_UASize( - FT_HANDLE ftHandle, - LPDWORD lpdwSize - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_UAWrite( - FT_HANDLE ftHandle, - PUCHAR pucData, - DWORD dwDataLen - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_UARead( - FT_HANDLE ftHandle, - PUCHAR pucData, - DWORD dwDataLen, - LPDWORD lpdwBytesRead - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetLatencyTimer( - FT_HANDLE ftHandle, - UCHAR ucLatency - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetLatencyTimer( - FT_HANDLE ftHandle, - PUCHAR pucLatency - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBitMode( - FT_HANDLE ftHandle, - UCHAR ucMask, - UCHAR ucEnable - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetBitMode( - FT_HANDLE ftHandle, - PUCHAR pucMode - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetUSBParameters( - FT_HANDLE ftHandle, - ULONG ulInTransferSize, - ULONG ulOutTransferSize - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDeadmanTimeout( - FT_HANDLE ftHandle, - ULONG ulDeadmanTimeout - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetDeviceInfo( - FT_HANDLE ftHandle, - FT_DEVICE *lpftDevice, - LPDWORD lpdwID, - PCHAR SerialNumber, - PCHAR Description, - LPVOID Dummy - ); - -FTD2XX_API -FT_STATUS WINAPI FT_StopInTask( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_RestartInTask( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetResetPipeRetryCount( // Linux, OS X: Not supported - FT_HANDLE ftHandle, - DWORD dwCount - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ResetPort( // Linux, OS X: Not supported - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_CyclePort( // Linux, OS X: Not supported - FT_HANDLE ftHandle - ); - - -// -// Win32-type functions -// - -FTD2XX_API -FT_HANDLE WINAPI FT_W32_CreateFile( - LPCSTR lpszName, - DWORD dwAccess, - DWORD dwShareMode, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, - DWORD dwCreate, - DWORD dwAttrsAndFlags, - HANDLE hTemplate - ); - -FTD2XX_API -BOOL WINAPI FT_W32_CloseHandle( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_ReadFile( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesReturned, - LPOVERLAPPED lpOverlapped - ); - -FTD2XX_API -BOOL WINAPI FT_W32_WriteFile( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesWritten, - LPOVERLAPPED lpOverlapped - ); - -FTD2XX_API -DWORD WINAPI FT_W32_GetLastError( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetOverlappedResult( // Linux, OS X: Not supported - FT_HANDLE ftHandle, - LPOVERLAPPED lpOverlapped, - LPDWORD lpdwBytesTransferred, - BOOL bWait - ); - -FTD2XX_API -BOOL WINAPI FT_W32_CancelIo( // Linux, OS X: Not supported - FT_HANDLE ftHandle - ); - - -// -// Win32 COMM API type functions -// -typedef struct _FTCOMSTAT { - DWORD fCtsHold : 1; - DWORD fDsrHold : 1; - DWORD fRlsdHold : 1; - DWORD fXoffHold : 1; - DWORD fXoffSent : 1; - DWORD fEof : 1; - DWORD fTxim : 1; - DWORD fReserved : 25; - DWORD cbInQue; - DWORD cbOutQue; -} FTCOMSTAT, *LPFTCOMSTAT; - -typedef struct _FTDCB { - DWORD DCBlength; /* sizeof(FTDCB) */ - DWORD BaudRate; /* Baudrate at which running */ - DWORD fBinary: 1; /* Binary Mode (skip EOF check) */ - DWORD fParity: 1; /* Enable parity checking */ - DWORD fOutxCtsFlow:1; /* CTS handshaking on output */ - DWORD fOutxDsrFlow:1; /* DSR handshaking on output */ - DWORD fDtrControl:2; /* DTR Flow control */ - DWORD fDsrSensitivity:1; /* DSR Sensitivity */ - DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */ - DWORD fOutX: 1; /* Enable output X-ON/X-OFF */ - DWORD fInX: 1; /* Enable input X-ON/X-OFF */ - DWORD fErrorChar: 1; /* Enable Err Replacement */ - DWORD fNull: 1; /* Enable Null stripping */ - DWORD fRtsControl:2; /* Rts Flow control */ - DWORD fAbortOnError:1; /* Abort all reads and writes on Error */ - DWORD fDummy2:17; /* Reserved */ - WORD wReserved; /* Not currently used */ - WORD XonLim; /* Transmit X-ON threshold */ - WORD XoffLim; /* Transmit X-OFF threshold */ - BYTE ByteSize; /* Number of bits/byte, 4-8 */ - BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */ - BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */ - char XonChar; /* Tx and Rx X-ON character */ - char XoffChar; /* Tx and Rx X-OFF character */ - char ErrorChar; /* Error replacement char */ - char EofChar; /* End of Input character */ - char EvtChar; /* Received Event character */ - WORD wReserved1; /* Fill for now. */ -} FTDCB, *LPFTDCB; - -typedef struct _FTTIMEOUTS { - DWORD ReadIntervalTimeout; /* Maximum time between read chars. */ - DWORD ReadTotalTimeoutMultiplier; /* Multiplier of characters. */ - DWORD ReadTotalTimeoutConstant; /* Constant in milliseconds. */ - DWORD WriteTotalTimeoutMultiplier; /* Multiplier of characters. */ - DWORD WriteTotalTimeoutConstant; /* Constant in milliseconds. */ -} FTTIMEOUTS,*LPFTTIMEOUTS; - - -FTD2XX_API -BOOL WINAPI FT_W32_ClearCommBreak( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_ClearCommError( - FT_HANDLE ftHandle, - LPDWORD lpdwErrors, - LPFTCOMSTAT lpftComstat - ); - -FTD2XX_API -BOOL WINAPI FT_W32_EscapeCommFunction( - FT_HANDLE ftHandle, - DWORD dwFunc - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommModemStatus( - FT_HANDLE ftHandle, - LPDWORD lpdwModemStatus - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommState( - FT_HANDLE ftHandle, - LPFTDCB lpftDcb - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommTimeouts( - FT_HANDLE ftHandle, - FTTIMEOUTS *pTimeouts - ); - -FTD2XX_API -BOOL WINAPI FT_W32_PurgeComm( - FT_HANDLE ftHandle, - DWORD dwMask - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommBreak( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommMask( - FT_HANDLE ftHandle, - ULONG ulEventMask - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommState( - FT_HANDLE ftHandle, - LPFTDCB lpftDcb - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommTimeouts( - FT_HANDLE ftHandle, - FTTIMEOUTS *pTimeouts - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetupComm( - FT_HANDLE ftHandle, - DWORD dwReadBufferSize, - DWORD dwWriteBufferSize - ); - -FTD2XX_API -BOOL WINAPI FT_W32_WaitCommEvent( - FT_HANDLE ftHandle, - PULONG pulEvent, - LPOVERLAPPED lpOverlapped - ); - -// -// Device information -// - -typedef struct _ft_device_list_info_node { - ULONG Flags; - ULONG Type; - ULONG ID; - DWORD LocId; - char SerialNumber[16]; - char Description[64]; - FT_HANDLE ftHandle; -} FT_DEVICE_LIST_INFO_NODE; - -FTD2XX_API -FT_STATUS WINAPI FT_CreateDeviceInfoList( - LPDWORD lpdwNumDevs - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetDeviceInfoList( - FT_DEVICE_LIST_INFO_NODE *pDest, - LPDWORD lpdwNumDevs - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetDeviceInfoDetail( - DWORD dwIndex, - LPDWORD lpdwFlags, - LPDWORD lpdwType, - LPDWORD lpdwID, - LPDWORD lpdwLocId, - LPVOID lpSerialNumber, - LPVOID lpDescription, - FT_HANDLE *pftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetDriverVersion( - FT_HANDLE ftHandle, - LPDWORD lpdwVersion - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetLibraryVersion( - LPDWORD lpdwVersion - ); - -// -// Events -// - -#define EV_RXCHAR 0x0001 // Any Character received -#define EV_RXFLAG 0x0002 // Received certain character -#define EV_TXEMPTY 0x0004 // Transmitt Queue Empty -#define EV_CTS 0x0008 // CTS changed state -#define EV_DSR 0x0010 // DSR changed state -#define EV_RLSD 0x0020 // RLSD changed state -#define EV_BREAK 0x0040 // BREAK received -#define EV_ERR 0x0080 // Line status error occurred -#define EV_RING 0x0100 // Ring signal detected -#define EV_PERR 0x0200 // Printer error occured -#define EV_RX80FULL 0x0400 // Receive buffer is 80 percent full -#define EV_EVENT1 0x0800 // Provider specific event 1 -#define EV_EVENT2 0x1000 // Provider specific event 2 - -// -// Escape Functions -// - -#define SETXOFF 1 // Simulate XOFF received -#define SETXON 2 // Simulate XON received -#define SETRTS 3 // Set RTS high -#define CLRRTS 4 // Set RTS low -#define SETDTR 5 // Set DTR high -#define CLRDTR 6 // Set DTR low -#define RESETDEV 7 // Reset device if possible -#define SETBREAK 8 // Set the device break line. -#define CLRBREAK 9 // Clear the device break line. - -// -// PURGE function flags. -// -#define PURGE_TXABORT 0x0001 // Kill the pending/current writes to the comm port. -#define PURGE_RXABORT 0x0002 // Kill the pending/current reads to the comm port. -#define PURGE_TXCLEAR 0x0004 // Kill the transmit queue if there. -#define PURGE_RXCLEAR 0x0008 // Kill the typeahead buffer if there. - - - - - - - - - - - - - - -#ifdef __cplusplus -} -#endif - - -#endif /* FTD2XX_H */ - - - - - - diff --git a/tools/sensinode/nano_usb_programmer/ftdi_win32/ftd2xx.h b/tools/sensinode/nano_usb_programmer/ftdi_win32/ftd2xx.h deleted file mode 100644 index fd15376f8..000000000 --- a/tools/sensinode/nano_usb_programmer/ftdi_win32/ftd2xx.h +++ /dev/null @@ -1,923 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -/*++ - -Copyright (c) 2001-2006 Future Technology Devices International Ltd. - -Module Name: - - ftd2xx.h - -Abstract: - - Native USB device driver for FTDI FT8U232/245 - FTD2XX library definitions - -Environment: - - kernel & user mode - -Revision History: - - 13/03/01 awm Created. - 13/01/03 awm Added device information support. - 19/03/03 awm Added FT_W32_CancelIo. - 12/06/03 awm Added FT_StopInTask and FT_RestartInTask. - 18/09/03 awm Added FT_SetResetPipeRetryCount. - 10/10/03 awm Added FT_ResetPort. - 23/01/04 awm Added support for open-by-location. - 16/03/04 awm Added support for FT2232C. - 23/09/04 awm Added support for FT232R. - 20/10/04 awm Added FT_CyclePort. - 18/01/05 awm Added FT_DEVICE_LIST_INFO_NODE type. - 11/02/05 awm Added LocId to FT_DEVICE_LIST_INFO_NODE. - 25/08/05 awm Added FT_SetDeadmanTimeout. - 02/12/05 awm Removed obsolete references. - 05/12/05 awm Added FT_GetVersion, FT_GetVersionEx. - 08/09/06 awm Added FT_W32_GetCommMask. - 11/09/06 awm Added FT_Rescan. - - ---*/ - - -#ifndef FTD2XX_H -#define FTD2XX_H - -// The following ifdef block is the standard way of creating macros -// which make exporting from a DLL simpler. All files within this DLL -// are compiled with the FTD2XX_EXPORTS symbol defined on the command line. -// This symbol should not be defined on any project that uses this DLL. -// This way any other project whose source files include this file see -// FTD2XX_API functions as being imported from a DLL, whereas this DLL -// sees symbols defined with this macro as being exported. - -#ifdef FTD2XX_EXPORTS -#define FTD2XX_API __declspec(dllexport) -#else -#define FTD2XX_API __declspec(dllimport) -#endif - - -typedef PVOID FT_HANDLE; -typedef ULONG FT_STATUS; - -// -// Device status -// -enum { - FT_OK, - FT_INVALID_HANDLE, - FT_DEVICE_NOT_FOUND, - FT_DEVICE_NOT_OPENED, - FT_IO_ERROR, - FT_INSUFFICIENT_RESOURCES, - FT_INVALID_PARAMETER, - FT_INVALID_BAUD_RATE, - - FT_DEVICE_NOT_OPENED_FOR_ERASE, - FT_DEVICE_NOT_OPENED_FOR_WRITE, - FT_FAILED_TO_WRITE_DEVICE, - FT_EEPROM_READ_FAILED, - FT_EEPROM_WRITE_FAILED, - FT_EEPROM_ERASE_FAILED, - FT_EEPROM_NOT_PRESENT, - FT_EEPROM_NOT_PROGRAMMED, - FT_INVALID_ARGS, - FT_NOT_SUPPORTED, - FT_OTHER_ERROR, - FT_DEVICE_LIST_NOT_READY, -}; - - -#define FT_SUCCESS(status) ((status) == FT_OK) - -// -// FT_OpenEx Flags -// - -#define FT_OPEN_BY_SERIAL_NUMBER 1 -#define FT_OPEN_BY_DESCRIPTION 2 -#define FT_OPEN_BY_LOCATION 4 - -// -// FT_ListDevices Flags (used in conjunction with FT_OpenEx Flags -// - -#define FT_LIST_NUMBER_ONLY 0x80000000 -#define FT_LIST_BY_INDEX 0x40000000 -#define FT_LIST_ALL 0x20000000 - -#define FT_LIST_MASK (FT_LIST_NUMBER_ONLY|FT_LIST_BY_INDEX|FT_LIST_ALL) - -// -// Baud Rates -// - -#define FT_BAUD_300 300 -#define FT_BAUD_600 600 -#define FT_BAUD_1200 1200 -#define FT_BAUD_2400 2400 -#define FT_BAUD_4800 4800 -#define FT_BAUD_9600 9600 -#define FT_BAUD_14400 14400 -#define FT_BAUD_19200 19200 -#define FT_BAUD_38400 38400 -#define FT_BAUD_57600 57600 -#define FT_BAUD_115200 115200 -#define FT_BAUD_230400 230400 -#define FT_BAUD_460800 460800 -#define FT_BAUD_921600 921600 - -// -// Word Lengths -// - -#define FT_BITS_8 (UCHAR) 8 -#define FT_BITS_7 (UCHAR) 7 -#define FT_BITS_6 (UCHAR) 6 -#define FT_BITS_5 (UCHAR) 5 - -// -// Stop Bits -// - -#define FT_STOP_BITS_1 (UCHAR) 0 -#define FT_STOP_BITS_1_5 (UCHAR) 1 -#define FT_STOP_BITS_2 (UCHAR) 2 - -// -// Parity -// - -#define FT_PARITY_NONE (UCHAR) 0 -#define FT_PARITY_ODD (UCHAR) 1 -#define FT_PARITY_EVEN (UCHAR) 2 -#define FT_PARITY_MARK (UCHAR) 3 -#define FT_PARITY_SPACE (UCHAR) 4 - -// -// Flow Control -// - -#define FT_FLOW_NONE 0x0000 -#define FT_FLOW_RTS_CTS 0x0100 -#define FT_FLOW_DTR_DSR 0x0200 -#define FT_FLOW_XON_XOFF 0x0400 - -// -// Purge rx and tx buffers -// -#define FT_PURGE_RX 1 -#define FT_PURGE_TX 2 - -// -// Events -// - -typedef void (*PFT_EVENT_HANDLER)(DWORD,DWORD); - -#define FT_EVENT_RXCHAR 1 -#define FT_EVENT_MODEM_STATUS 2 - -// -// Timeouts -// - -#define FT_DEFAULT_RX_TIMEOUT 300 -#define FT_DEFAULT_TX_TIMEOUT 300 - -// -// Device types -// - -typedef ULONG FT_DEVICE; - -enum { - FT_DEVICE_BM, - FT_DEVICE_AM, - FT_DEVICE_100AX, - FT_DEVICE_UNKNOWN, - FT_DEVICE_2232C, - FT_DEVICE_232R -}; - - -#ifdef __cplusplus -extern "C" { -#endif - - -FTD2XX_API -FT_STATUS WINAPI FT_Open( - int deviceNumber, - FT_HANDLE *pHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_OpenEx( - PVOID pArg1, - DWORD Flags, - FT_HANDLE *pHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ListDevices( - PVOID pArg1, - PVOID pArg2, - DWORD Flags - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Close( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Read( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesReturned - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Write( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesWritten - ); - -FTD2XX_API -FT_STATUS WINAPI FT_IoCtl( - FT_HANDLE ftHandle, - DWORD dwIoControlCode, - LPVOID lpInBuf, - DWORD nInBufSize, - LPVOID lpOutBuf, - DWORD nOutBufSize, - LPDWORD lpBytesReturned, - LPOVERLAPPED lpOverlapped - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBaudRate( - FT_HANDLE ftHandle, - ULONG BaudRate - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDivisor( - FT_HANDLE ftHandle, - USHORT Divisor - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDataCharacteristics( - FT_HANDLE ftHandle, - UCHAR WordLength, - UCHAR StopBits, - UCHAR Parity - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetFlowControl( - FT_HANDLE ftHandle, - USHORT FlowControl, - UCHAR XonChar, - UCHAR XoffChar - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ResetDevice( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDtr( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ClrDtr( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetRts( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ClrRts( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetModemStatus( - FT_HANDLE ftHandle, - ULONG *pModemStatus - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetChars( - FT_HANDLE ftHandle, - UCHAR EventChar, - UCHAR EventCharEnabled, - UCHAR ErrorChar, - UCHAR ErrorCharEnabled - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Purge( - FT_HANDLE ftHandle, - ULONG Mask - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetTimeouts( - FT_HANDLE ftHandle, - ULONG ReadTimeout, - ULONG WriteTimeout - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetQueueStatus( - FT_HANDLE ftHandle, - DWORD *dwRxBytes - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetEventNotification( - FT_HANDLE ftHandle, - DWORD Mask, - PVOID Param - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetStatus( - FT_HANDLE ftHandle, - DWORD *dwRxBytes, - DWORD *dwTxBytes, - DWORD *dwEventDWord - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBreakOn( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBreakOff( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetWaitMask( - FT_HANDLE ftHandle, - DWORD Mask - ); - -FTD2XX_API -FT_STATUS WINAPI FT_WaitOnMask( - FT_HANDLE ftHandle, - DWORD *Mask - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetEventStatus( - FT_HANDLE ftHandle, - DWORD *dwEventDWord - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ReadEE( - FT_HANDLE ftHandle, - DWORD dwWordOffset, - LPWORD lpwValue - ); - -FTD2XX_API -FT_STATUS WINAPI FT_WriteEE( - FT_HANDLE ftHandle, - DWORD dwWordOffset, - WORD wValue - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EraseEE( - FT_HANDLE ftHandle - ); - -// -// structure to hold program data for FT_Program function -// -typedef struct ft_program_data { - - DWORD Signature1; // Header - must be 0x00000000 - DWORD Signature2; // Header - must be 0xffffffff - DWORD Version; // Header - FT_PROGRAM_DATA version - // 0 = original - // 1 = FT2232C extensions - // 2 = FT232R extensions - - WORD VendorId; // 0x0403 - WORD ProductId; // 0x6001 - char *Manufacturer; // "FTDI" - char *ManufacturerId; // "FT" - char *Description; // "USB HS Serial Converter" - char *SerialNumber; // "FT000001" if fixed, or NULL - WORD MaxPower; // 0 < MaxPower <= 500 - WORD PnP; // 0 = disabled, 1 = enabled - WORD SelfPowered; // 0 = bus powered, 1 = self powered - WORD RemoteWakeup; // 0 = not capable, 1 = capable - // - // Rev4 extensions - // - UCHAR Rev4; // non-zero if Rev4 chip, zero otherwise - UCHAR IsoIn; // non-zero if in endpoint is isochronous - UCHAR IsoOut; // non-zero if out endpoint is isochronous - UCHAR PullDownEnable; // non-zero if pull down enabled - UCHAR SerNumEnable; // non-zero if serial number to be used - UCHAR USBVersionEnable; // non-zero if chip uses USBVersion - WORD USBVersion; // BCD (0x0200 => USB2) - // - // FT2232C extensions - // - UCHAR Rev5; // non-zero if Rev5 chip, zero otherwise - UCHAR IsoInA; // non-zero if in endpoint is isochronous - UCHAR IsoInB; // non-zero if in endpoint is isochronous - UCHAR IsoOutA; // non-zero if out endpoint is isochronous - UCHAR IsoOutB; // non-zero if out endpoint is isochronous - UCHAR PullDownEnable5; // non-zero if pull down enabled - UCHAR SerNumEnable5; // non-zero if serial number to be used - UCHAR USBVersionEnable5; // non-zero if chip uses USBVersion - WORD USBVersion5; // BCD (0x0200 => USB2) - UCHAR AIsHighCurrent; // non-zero if interface is high current - UCHAR BIsHighCurrent; // non-zero if interface is high current - UCHAR IFAIsFifo; // non-zero if interface is 245 FIFO - UCHAR IFAIsFifoTar; // non-zero if interface is 245 FIFO CPU target - UCHAR IFAIsFastSer; // non-zero if interface is Fast serial - UCHAR AIsVCP; // non-zero if interface is to use VCP drivers - UCHAR IFBIsFifo; // non-zero if interface is 245 FIFO - UCHAR IFBIsFifoTar; // non-zero if interface is 245 FIFO CPU target - UCHAR IFBIsFastSer; // non-zero if interface is Fast serial - UCHAR BIsVCP; // non-zero if interface is to use VCP drivers - // - // FT232R extensions - // - UCHAR UseExtOsc; // Use External Oscillator - UCHAR HighDriveIOs; // High Drive I/Os - UCHAR EndpointSize; // Endpoint size - - UCHAR PullDownEnableR; // non-zero if pull down enabled - UCHAR SerNumEnableR; // non-zero if serial number to be used - - UCHAR InvertTXD; // non-zero if invert TXD - UCHAR InvertRXD; // non-zero if invert RXD - UCHAR InvertRTS; // non-zero if invert RTS - UCHAR InvertCTS; // non-zero if invert CTS - UCHAR InvertDTR; // non-zero if invert DTR - UCHAR InvertDSR; // non-zero if invert DSR - UCHAR InvertDCD; // non-zero if invert DCD - UCHAR InvertRI; // non-zero if invert RI - - UCHAR Cbus0; // Cbus Mux control - UCHAR Cbus1; // Cbus Mux control - UCHAR Cbus2; // Cbus Mux control - UCHAR Cbus3; // Cbus Mux control - UCHAR Cbus4; // Cbus Mux control - - UCHAR RIsD2XX; // non-zero if using D2XX driver - -} FT_PROGRAM_DATA, *PFT_PROGRAM_DATA; - -FTD2XX_API -FT_STATUS WINAPI FT_EE_Program( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_ProgramEx( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData, - char *Manufacturer, - char *ManufacturerId, - char *Description, - char *SerialNumber - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_Read( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_ReadEx( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData, - char *Manufacturer, - char *ManufacturerId, - char *Description, - char *SerialNumber - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_UASize( - FT_HANDLE ftHandle, - LPDWORD lpdwSize - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_UAWrite( - FT_HANDLE ftHandle, - PUCHAR pucData, - DWORD dwDataLen - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_UARead( - FT_HANDLE ftHandle, - PUCHAR pucData, - DWORD dwDataLen, - LPDWORD lpdwBytesRead - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetLatencyTimer( - FT_HANDLE ftHandle, - UCHAR ucLatency - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetLatencyTimer( - FT_HANDLE ftHandle, - PUCHAR pucLatency - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBitMode( - FT_HANDLE ftHandle, - UCHAR ucMask, - UCHAR ucEnable - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetBitMode( - FT_HANDLE ftHandle, - PUCHAR pucMode - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetUSBParameters( - FT_HANDLE ftHandle, - ULONG ulInTransferSize, - ULONG ulOutTransferSize - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDeadmanTimeout( - FT_HANDLE ftHandle, - ULONG ulDeadmanTimeout - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetDeviceInfo( - FT_HANDLE ftHandle, - FT_DEVICE *lpftDevice, - LPDWORD lpdwID, - PCHAR SerialNumber, - PCHAR Description, - LPVOID Dummy - ); - -FTD2XX_API -FT_STATUS WINAPI FT_StopInTask( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_RestartInTask( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetResetPipeRetryCount( - FT_HANDLE ftHandle, - DWORD dwCount - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ResetPort( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_CyclePort( - FT_HANDLE ftHandle - ); - - -// -// Win32-type functions -// - -FTD2XX_API -FT_HANDLE WINAPI FT_W32_CreateFile( - LPCTSTR lpszName, - DWORD dwAccess, - DWORD dwShareMode, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, - DWORD dwCreate, - DWORD dwAttrsAndFlags, - HANDLE hTemplate - ); - -FTD2XX_API -BOOL WINAPI FT_W32_CloseHandle( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_ReadFile( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesReturned, - LPOVERLAPPED lpOverlapped - ); - -FTD2XX_API -BOOL WINAPI FT_W32_WriteFile( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesWritten, - LPOVERLAPPED lpOverlapped - ); - -FTD2XX_API -DWORD WINAPI FT_W32_GetLastError( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetOverlappedResult( - FT_HANDLE ftHandle, - LPOVERLAPPED lpOverlapped, - LPDWORD lpdwBytesTransferred, - BOOL bWait - ); - -FTD2XX_API -BOOL WINAPI FT_W32_CancelIo( - FT_HANDLE ftHandle - ); - - -// -// Win32 COMM API type functions -// -typedef struct _FTCOMSTAT { - DWORD fCtsHold : 1; - DWORD fDsrHold : 1; - DWORD fRlsdHold : 1; - DWORD fXoffHold : 1; - DWORD fXoffSent : 1; - DWORD fEof : 1; - DWORD fTxim : 1; - DWORD fReserved : 25; - DWORD cbInQue; - DWORD cbOutQue; -} FTCOMSTAT, *LPFTCOMSTAT; - -typedef struct _FTDCB { - DWORD DCBlength; /* sizeof(FTDCB) */ - DWORD BaudRate; /* Baudrate at which running */ - DWORD fBinary: 1; /* Binary Mode (skip EOF check) */ - DWORD fParity: 1; /* Enable parity checking */ - DWORD fOutxCtsFlow:1; /* CTS handshaking on output */ - DWORD fOutxDsrFlow:1; /* DSR handshaking on output */ - DWORD fDtrControl:2; /* DTR Flow control */ - DWORD fDsrSensitivity:1; /* DSR Sensitivity */ - DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */ - DWORD fOutX: 1; /* Enable output X-ON/X-OFF */ - DWORD fInX: 1; /* Enable input X-ON/X-OFF */ - DWORD fErrorChar: 1; /* Enable Err Replacement */ - DWORD fNull: 1; /* Enable Null stripping */ - DWORD fRtsControl:2; /* Rts Flow control */ - DWORD fAbortOnError:1; /* Abort all reads and writes on Error */ - DWORD fDummy2:17; /* Reserved */ - WORD wReserved; /* Not currently used */ - WORD XonLim; /* Transmit X-ON threshold */ - WORD XoffLim; /* Transmit X-OFF threshold */ - BYTE ByteSize; /* Number of bits/byte, 4-8 */ - BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */ - BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */ - char XonChar; /* Tx and Rx X-ON character */ - char XoffChar; /* Tx and Rx X-OFF character */ - char ErrorChar; /* Error replacement char */ - char EofChar; /* End of Input character */ - char EvtChar; /* Received Event character */ - WORD wReserved1; /* Fill for now. */ -} FTDCB, *LPFTDCB; - -typedef struct _FTTIMEOUTS { - DWORD ReadIntervalTimeout; /* Maximum time between read chars. */ - DWORD ReadTotalTimeoutMultiplier; /* Multiplier of characters. */ - DWORD ReadTotalTimeoutConstant; /* Constant in milliseconds. */ - DWORD WriteTotalTimeoutMultiplier; /* Multiplier of characters. */ - DWORD WriteTotalTimeoutConstant; /* Constant in milliseconds. */ -} FTTIMEOUTS,*LPFTTIMEOUTS; - - -FTD2XX_API -BOOL WINAPI FT_W32_ClearCommBreak( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_ClearCommError( - FT_HANDLE ftHandle, - LPDWORD lpdwErrors, - LPFTCOMSTAT lpftComstat - ); - -FTD2XX_API -BOOL WINAPI FT_W32_EscapeCommFunction( - FT_HANDLE ftHandle, - DWORD dwFunc - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommModemStatus( - FT_HANDLE ftHandle, - LPDWORD lpdwModemStatus - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommState( - FT_HANDLE ftHandle, - LPFTDCB lpftDcb - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommTimeouts( - FT_HANDLE ftHandle, - FTTIMEOUTS *pTimeouts - ); - -FTD2XX_API -BOOL WINAPI FT_W32_PurgeComm( - FT_HANDLE ftHandle, - DWORD dwMask - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommBreak( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommMask( - FT_HANDLE ftHandle, - ULONG ulEventMask - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommMask( - FT_HANDLE ftHandle, - LPDWORD lpdwEventMask - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommState( - FT_HANDLE ftHandle, - LPFTDCB lpftDcb - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommTimeouts( - FT_HANDLE ftHandle, - FTTIMEOUTS *pTimeouts - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetupComm( - FT_HANDLE ftHandle, - DWORD dwReadBufferSize, - DWORD dwWriteBufferSize - ); - -FTD2XX_API -BOOL WINAPI FT_W32_WaitCommEvent( - FT_HANDLE ftHandle, - PULONG pulEvent, - LPOVERLAPPED lpOverlapped - ); - - -// -// Device information -// - -typedef struct _ft_device_list_info_node { - ULONG Flags; - ULONG Type; - ULONG ID; - DWORD LocId; - char SerialNumber[16]; - char Description[64]; - FT_HANDLE ftHandle; -} FT_DEVICE_LIST_INFO_NODE; - - -FTD2XX_API -FT_STATUS WINAPI FT_CreateDeviceInfoList( - LPDWORD lpdwNumDevs - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetDeviceInfoList( - FT_DEVICE_LIST_INFO_NODE *pDest, - LPDWORD lpdwNumDevs - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetDeviceInfoDetail( - DWORD dwIndex, - LPDWORD lpdwFlags, - LPDWORD lpdwType, - LPDWORD lpdwID, - LPDWORD lpdwLocId, - LPVOID lpSerialNumber, - LPVOID lpDescription, - FT_HANDLE *pftHandle - ); - - -// -// Version information -// - -FTD2XX_API -FT_STATUS WINAPI FT_GetDriverVersion( - FT_HANDLE ftHandle, - LPDWORD lpdwVersion - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetLibraryVersion( - LPDWORD lpdwVersion - ); - - -FTD2XX_API -FT_STATUS WINAPI FT_Rescan( - void - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Reload( - WORD wVid, - WORD wPid - ); - - -#ifdef __cplusplus -} -#endif - - -#endif /* FTD2XX_H */ - diff --git a/tools/sensinode/nano_usb_programmer/ihex.c b/tools/sensinode/nano_usb_programmer/ihex.c deleted file mode 100644 index a7889e57b..000000000 --- a/tools/sensinode/nano_usb_programmer/ihex.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#include -#include -#include -#include - -#include - -int hexfile_build_tables(char *ihexfile, unsigned char *page_buffer, unsigned char *page_table) -{ - unsigned char buffer[256]; - int length; - int i; - int pages; - - unsigned long ext_addr=0; - unsigned short int addr=0; - FILE *ihex_fp; - - if((ihex_fp = (FILE *)fopen(ihexfile, "r")) == NULL) - { - printf("Failed to open .ihex file %s\n", ihexfile); - return(-1); - } - else - { - printf(".ihex file ok.\n"); - } - - bzero(buffer, sizeof(buffer)); - - /*initialize page data*/ - memset(page_table, 0, 64); - memset(page_buffer, 0xFF, sizeof(page_buffer)); - pages = 0; - - while((fscanf(ihex_fp, "%s", buffer) == 1)) - { - unsigned char data_len = 0; - - if (memcmp(&buffer[7], "00", 2) == 0) - { /*Data record*/ - i=0; - sscanf((char *)&buffer[1], "%2hhx", &data_len); - sscanf((char *)&(buffer[3]),"%4hx", &addr); - while(i> 8; - cksum += *addr & 0xFF; - cksum += *type; - - i = 0; - if (retval == 3) - { - while(i < row_len) - { - - if (sscanf(&line[row_index], "%2x", &tmp) == 1) - { - cksum += tmp; - buffer[i++] = (unsigned char) tmp; - row_index += 2; - } - else return -1; - } - if (sscanf(&line[row_index], "%2x", &tmp) == 1) - { - if ((cksum + (uint8_t) tmp) == 0) return row_len; - } - } - return -1; -} - -int hexfile_out(char *line, unsigned int type, unsigned int address, unsigned char *data, unsigned int bytes) -{ - uint8_t cksum = 0; - uint8_t i = 0; - char tmp[8]; - - sprintf(line, ":%2.2X%4.4X%2.2X", bytes, address, type); - cksum -= bytes; - cksum -= address >> 8; - cksum -= address & 0xFF; - cksum -= type; - - for (i=0; i -#include -#include -#include -#include - -#include -#ifdef PLATFORM_WINDOWS -#include -#endif -#include "prog.h" - -#define PRG_VERSION "1.3" - -typedef enum -{ - USAGE, - VERSION, - SCAN, - WRITE, - READ, - WRITE_MAC, - READ_MAC, - ERASE -}mode_t; - -typedef struct opts_t -{ - int port; - mode_t mode; - uint8_t write_mac[8]; - char *filename; -}opts_t; - -opts_t opts; - -void usage(char *prg_name) -{ - printf("\nUsage: %s [-p port] [-h] [-v] [-f file] [-r] [-w] [-m] [-M ]\n", prg_name); - printf("General options:\n"); - printf(" -p/--port [port] Select FTDI device\n"); - printf(" -f/--file [filename] File to read/write\n"); - printf("Operating modes:\n"); - printf(" -d/--devices Scan available devices\n"); - printf(" -v/--version Print program version\n"); - printf(" -r/--read Read program code into ihex file (see -f)\n"); - printf(" -w/--write Program firmware from ihex file (see -f)\n"); - printf(" -m/--read-mac Read device MAC address\n"); - printf(" -M/--write-mac xx:xx:xx:xx:xx:xx:xx:xx Write device MAC address\n"); - printf(" -e/--erase Erase flash (erases MAC address!)\n"); - printf("Defaults:\n"); - printf("mode = usage\n"); - printf("port = undefined\n"); - printf("file = stdout\n"); -} - -int main(int argc, char *argv[]) -{ - DWORD dwBytesInQueue = 0; - FT_STATUS ftStatus; - FT_HANDLE ftHandle; - unsigned char ucMode = 0x00; - int i=0; - unsigned char wr[1] = { 0x30 }; - unsigned char rd[1]; - uint16_t chip_id; - - if (opts_parse(argc, argv) < 0) - { - usage(argv[0]); - return -1; - } - switch(opts.mode) - { - case VERSION: - printf("Sensinode Nano USB Programmer version %s\n", PRG_VERSION); - return 0; - - case USAGE: - usage(argv[0]); - return 0; - - case SCAN: - prog_scan(); - return 0; - - case ERASE: - case READ: - case WRITE: - case READ_MAC: - case WRITE_MAC: - break; - } - - printf("Opening programmer.\n"); - ftHandle = prog_open(opts.port); - if (ftHandle == 0) - { - return (-1); - } - - cdi_start(&chip_id); - - printf("Chip ID = %4.4hX.\n", chip_id); - - if ((chip_id & 0xFF00) == 0x8500) - { - printf("CC2430 chip found.\n"); - } - else if ((chip_id & 0xFF00) == 0x8900) - { - printf("CC2431 chip found.\n"); - } - else - { - printf("Unknown chip found.\n"); - opts.mode = USAGE; - } - - switch(opts.mode) - { - case VERSION: - case USAGE: - break; - - case ERASE: - printf("Erase.\n"); - break; - - case READ: - printf("Read Flash.\n"); - cdi_set_address(0); - break; - - case WRITE: - { - int rval; - unsigned char page_table[64]; - unsigned char page_buffer[128*1024]; - - printf("Write Flash.\n"); - - if((rval = hexfile_build_tables(opts.filename, page_buffer, page_table)) == -1) - { - printf("Error\n"); - return(-1); - } - else if(rval == 0) - { - printf(".ihex file OK but nothing to write...\n"); - return(1); - } - - hexfile_program(page_buffer, page_table); - - break; - } - case READ_MAC: - printf("Read MAC: "); - cdi_set_address(0x1FFF8); - { - uint8_t mac[8]; - - cdi_flash_read(mac, 8); - for (i=0; i<8; i++) - { - if (i) printf(":"); - printf("%2.2X", mac[i]); - } - printf("\n"); - } - break; - - case WRITE_MAC: - printf("Write MAC: "); -/* cdi_set_address(0x1F800); - { - uint8_t block[2048]; - - memset(block, 0xFF, 2048); - for (i=0; i<8; i++) - { - block[2040+i] = opts.write_mac[i]; - } - cdi_flash_write(block, 2048); - printf("\n"); - }*/ - cdi_flash_write_mac(opts.write_mac); - printf("\n"); - break; - - default: - printf("Duh\n"); - break; - } - - - printf("Closing programmer.\n"); - prog_close(); -} - -static int option_index = 0; - -int do_exit = 0; - -#define OPTIONS_STRING "p:vdhf:rwmM:e" -/* long option list */ -static struct option long_options[] = -{ - {"port", 1, NULL, 'p'}, - {"version", 0, NULL, 'v'}, - {"devices", 0, NULL, 'd'}, - {"help", 0, NULL, 'h'}, - {"file", 1, NULL, 'f'}, - {"read", 0, NULL, 'r'}, - {"write", 0, NULL, 'w'}, - {"read-mac", 0, NULL, 'm'}, - {"write-mac", 1, NULL, 'M'}, - {"erase", 0, NULL, 'e'}, - {0, 0, 0, 0} -}; - -int opts_parse(int count, char* param[]) -{ - int opt; - int error=0; - - opts.mode = USAGE; - opts.filename = 0; - while ((opt = getopt_long(count, param, OPTIONS_STRING, - long_options, &option_index)) != -1) - { - fflush(stdout); - switch(opt) - { - case 'p': - opts.port = 0; - if (sscanf(optarg, "%d", &(opts.port)) != 1) - { - if (sscanf(optarg, "/dev/ttyUSB%d", &(opts.port)) != 1) - { - printf("Invalid port.\n"); - opts.mode = USAGE; - return 0; - } - } - printf("Port %d.\n", opts.port); - break; - - case 'v': - opts.mode = VERSION; - return 0; - - case 'd': - opts.mode = SCAN; - return 0; - - case 'h': - opts.mode = USAGE; - return 0; - - case 'e': - opts.mode = ERASE; - break; - - case 'f': - printf("Filename: %s\n", optarg); - opts.filename = malloc(strlen(optarg)+1); - strcpy(opts.filename, optarg); - break; - - case 'r': - opts.mode = READ; - break; - - case 'w': - opts.mode = WRITE; - break; - - case 'm': - opts.mode = READ_MAC; - break; - - case 'M': - opts.mode = WRITE_MAC; - if (sscanf(optarg, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", - &opts.write_mac[0], &opts.write_mac[1], - &opts.write_mac[2], &opts.write_mac[3], - &opts.write_mac[4], &opts.write_mac[5], - &opts.write_mac[6], &opts.write_mac[7]) != 8) - { - printf("Invalid MAC.\n"); - opts.mode = USAGE; - } - else - { - printf("MAC to write: %2.2hhX:%2.2hhX:%2.2hhX:%2.2hhX:%2.2hhX:%2.2hhX:%2.2hhX:%2.2hhX\n", - opts.write_mac[0], opts.write_mac[1], - opts.write_mac[2], opts.write_mac[3], - opts.write_mac[4], opts.write_mac[5], - opts.write_mac[6], opts.write_mac[7]); - } - break; - - case '?': - printf("Duh\n"); - error = -1; - break; - } - } - - return error; -} - diff --git a/tools/sensinode/nano_usb_programmer/prog.c b/tools/sensinode/nano_usb_programmer/prog.c deleted file mode 100644 index 1cce8ec83..000000000 --- a/tools/sensinode/nano_usb_programmer/prog.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#include -#include -#ifdef PLATFORM_WINDOWS -#include -#endif -#include - -FT_HANDLE curr_handle = 0; -uint8_t curr_mode = 0; /* 0 = in, 1=out */ - -/* - * This function checks if the CBUS2 ise set to SLEEP and modifies it if necessary. - * The CBUS2 must be set to sleep in order the programming to succeed. - */ -int check_cbus2(FT_HANDLE fthandle) -{ - FT_PROGRAM_DATA eeprom_data; - char manufacturer_buf[32]; - char manufacturer_id[16]; - char description_buf[64]; - char serialnumber_buf[16]; - eeprom_data.Signature1 = 0x00000000; // This is a given value from the FT232R programming guide - eeprom_data.Signature2 = 0xffffffff; // This is a given value from the FT232R programming guide - eeprom_data.Version = 0x00000002; // This is a given value from the FT232R programming guide - eeprom_data.Manufacturer = manufacturer_buf; - eeprom_data.ManufacturerId = manufacturer_id; - eeprom_data.Description = description_buf; - eeprom_data.SerialNumber = serialnumber_buf; - - - if(FT_EE_Read(fthandle, &eeprom_data) != FT_OK) - { - printf("FTDI EEPROM read failed.\n"); - return(-1); - } - - if(eeprom_data.Cbus2 != 0x05) - { - printf("Need to re-program the CBUS2 to 0x05\n"); - eeprom_data.Cbus2 = 0x05; - - if(FT_EE_Program(fthandle, &eeprom_data) != FT_OK) - { - printf("FTDI EEPROM program error.\n"); - return(-1); - } - else - { - printf("FTDI EEPROM program ok\n"); - return(1); - } - } - else - { - return(1); - } - - return(1); -} - - -void prog_scan(void) -{ - FT_STATUS ftStatus; - FT_DEVICE_LIST_INFO_NODE *info; - unsigned long n_devices = 0; - uint8_t out; - - ftStatus = FT_CreateDeviceInfoList(&n_devices); - if (ftStatus == FT_OK) - { - FT_DEVICE_LIST_INFO_NODE devices[n_devices]; - - ftStatus = FT_GetDeviceInfoList(devices,&n_devices); - if (ftStatus == FT_OK) - { - for (out = 0; out < n_devices; out++) - { - printf("Dev %d:",n_devices - out -1); - printf(" Type=0x%x",devices[n_devices - out -1].Type); - printf(" SerialNumber=%s",devices[n_devices - out -1].SerialNumber); - printf(" Description=%s\n",devices[n_devices - out -1].Description); - } - } - else - { - printf("Failed to fetch device list.\n"); - } - } - else - { - printf("Failed to fetch device list.\n"); - } -} - -FT_HANDLE prog_open(int iport) -{ - FT_HANDLE ftHandle; - FT_STATUS ftStatus; - FT_DEVICE_LIST_INFO_NODE *info; - unsigned long n_devices = 0; - uint8_t out; - - if (curr_handle) return 0; - - ftStatus = FT_CreateDeviceInfoList(&n_devices); - if (ftStatus == FT_OK) - { - FT_DEVICE_LIST_INFO_NODE devices[n_devices]; - - ftStatus = FT_GetDeviceInfoList(devices,&n_devices); - if (ftStatus == FT_OK) - { - iport = n_devices - iport - 1; - - if (iport < 0) - { - printf("Invalid port id.\n"); - for (out = 0; out < n_devices; out++) - { - printf("Dev %d:",n_devices - out -1); - printf(" Type=0x%x",devices[n_devices - out -1].Type); - printf(" SerialNumber=%s",devices[n_devices - out -1].SerialNumber); - printf(" Description=%s\n",devices[n_devices - out -1].Description); - } - return 0; - } - } - } - - ftStatus = FT_Open(iport, &ftHandle); - if(ftStatus != FT_OK) { - /* - This can fail if the ftdi_sio driver is loaded - use lsmod to check this and rmmod ftdi_sio to remove - also rmmod usbserial - */ - printf("FT_Open(%d) failed\n", iport); - return 0; - } - - if(check_cbus2(ftHandle) < 0) - { - printf("Nano USB Programmer exiting...\n"); - return(0); - } - - FT_ResetDevice(ftHandle); - - FT_SetBaudRate(ftHandle, 115200); - - FT_SetUSBParameters(ftHandle, 64, 0); - - out = 0x04; - - ftStatus = FT_SetBitMode(ftHandle, out, 0x20); - if (ftStatus == FT_OK) - { - ftStatus = FT_SetLatencyTimer(ftHandle, 2); - } - if (ftStatus == FT_OK) - { - DWORD bytes; - out = 0xE0; - ftStatus = FT_SetBitMode(ftHandle, out, 0x04); - out = 0x80; - FT_Write(ftHandle, &out, 1, &bytes); /*write reset high*/ - FT_Read(ftHandle, &out, 1, &bytes); /*read out*/ - curr_mode = 1; - } - if (ftStatus != FT_OK) - { - printf("Failed to set CBUS2/bit bang mode.\n"); - - FT_ResetDevice(ftHandle); - sleep(3); - FT_Close(ftHandle); - ftHandle = 0; - } - curr_handle = ftHandle; - return ftHandle; -} - -void prog_close(void) -{ - FT_STATUS ftStatus; - DWORD bytes; - - if (curr_handle) - { - FT_HANDLE ftHandle = curr_handle; - uint8_t out = 0x00; - - FT_Write(ftHandle, &out, 1, &bytes); /*write reset low*/ - FT_Read(ftHandle, &out, 1, &bytes); /*read out*/ - sleep(1); - out = 0x80; - FT_Write(ftHandle, &out, 1, &bytes); /*write reset high*/ - FT_Read(ftHandle, &out, 1, &bytes); /*read out*/ - sleep(1); - out = 0x00; - ftStatus = FT_SetBitMode(ftHandle, out, 0x04); - FT_ResetDevice(ftHandle); - FT_Close(ftHandle); - - ftHandle = 0; - curr_handle = ftHandle; - } -} - -int prog_write(uint8_t byte) -{ - FT_STATUS ftStatus; - uint8_t out[16]; - uint8_t mask = 0x80; - int i; - DWORD bytes; - - if (curr_mode == 0) - { - out[0] = 0xE0; - ftStatus = FT_SetBitMode(curr_handle, out[0], 0x04); /*Set DD as output*/ - if (ftStatus != FT_OK) - { printf("!WR"); - fflush(stdout); - return -1; - } - curr_mode = 1; - } - i = 0; - while (mask) - { - out[i] = 0xC0; /*clock high, reset high*/ - if (byte & mask) out[i] |= 0x20; - i++; - out[i] = 0x80; /*clock low, reset high*/ - if (byte & mask) out[i] |= 0x20; - i++; - mask >>= 1; - } - ftStatus = FT_Write(curr_handle, out, 16, &bytes); /*write clock high and data bit*/ - if (ftStatus != FT_OK) - { - printf("!W"); - fflush(stdout); - return -1; - } - - if(FT_Read(curr_handle, out, 16, &bytes) != FT_OK) - { - printf("!R"); - return(-1); - } - - return 0; -} - -int prog_read(uint8_t *byte) -{ - FT_STATUS ftStatus; - uint8_t rd; - uint8_t mask = 0x80; - DWORD bytes; - uint8_t out[17]; - uint8_t i=0; - - *byte = 0; - if (curr_mode == 1) - { - out[0] = 0xC0; - ftStatus = FT_SetBitMode(curr_handle, out[0], 0x04); /*Set DD as input*/ - if (ftStatus != FT_OK) - { printf("!RD"); - fflush(stdout); - return -1; - } - curr_mode = 0; - } - - while (mask) - { - out[i] = 0xC0; /*clock high, reset high*/ - if (*byte & mask) out[i] |= 0x20; - i++; - out[i] = 0x80; /*clock low, reset high*/ - if (*byte & mask) out[i] |= 0x20; - i++; - mask >>= 1; - } - - out[16] = out[15]; - - ftStatus = FT_Write(curr_handle, out, 17, &bytes); /*write clock high and data bit*/ - - if(FT_Read(curr_handle, out, 17, &bytes) != FT_OK) - { - printf("!R"); - return(-1); - } - - mask = 0x80; - i = 1; - while (mask) - { - if (out[i] & 0x20) *byte |= mask; - mask >>= 1; - i+=2; - } - - return 0; -} - -int prog_start(void) -{ - FT_STATUS ftStatus; - uint8_t wr; - uint8_t mask = 0x80; - DWORD bytes; - uint8_t out[16] = { 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x80 }; - - printf("prog_start()\n"); - - if (curr_mode == 0) - { - wr = 0xE0; - - ftStatus = FT_SetBitMode(curr_handle, wr, 0x04); /*Set DD as output*/ - curr_mode = 1; - } - - if(FT_Write(curr_handle, out, 7, &bytes) != FT_OK) - { - printf("!W\n"); - return(-1); - } - - if(FT_Read(curr_handle, out, 7, &bytes) != FT_OK) - { - printf("!R\n"); - return(-1); - } - -} diff --git a/tools/sensinode/nano_usb_programmer/prog.h b/tools/sensinode/nano_usb_programmer/prog.h deleted file mode 100644 index fc2107d47..000000000 --- a/tools/sensinode/nano_usb_programmer/prog.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#ifndef _PROG_H -#define _PROG_H - -#include "ftd2xx.h" -#include - -extern FT_HANDLE prog_open(int iport); -extern void prog_close(void); - -extern int prog_write(uint8_t byte); -extern int prog_read(uint8_t *byte); - -extern int prog_start(void); - -extern int check_cbus2(FT_HANDLE fthandle); - -#endif diff --git a/tools/sky/Makefile b/tools/sky/Makefile index 0b1fa08db..be3caa44b 100644 --- a/tools/sky/Makefile +++ b/tools/sky/Makefile @@ -22,4 +22,4 @@ endif all: $(SERIALDUMP) $(SERIALDUMP): serialdump.c - $(CC) -o $@ $< + $(CC) -O2 -o $@ $< diff --git a/tools/sky/msp430-bsl-linux b/tools/sky/msp430-bsl-linux index 133f1bd35..c78e18640 100755 --- a/tools/sky/msp430-bsl-linux +++ b/tools/sky/msp430-bsl-linux @@ -1162,8 +1162,9 @@ class BootStrapLoader(LowLevel): sys.stderr.flush() self.bslTxRx(self.BSL_CHANGEBAUD, #Command: change baudrate a, l) #args are coded in adr and len + self.serialport.flush() time.sleep(0.010) #recomended delay - self.serialport.setBaudrate(baudrate) + self.serialport.baudrate = baudrate def actionReadBSLVersion(self): """informational output of BSL version number. diff --git a/tools/sky/serialdump-macos b/tools/sky/serialdump-macos new file mode 100755 index 000000000..775f88707 Binary files /dev/null and b/tools/sky/serialdump-macos differ diff --git a/tools/sky/serialdump.c b/tools/sky/serialdump.c index ce6c2ae32..12fd0abfc 100644 --- a/tools/sky/serialdump.c +++ b/tools/sky/serialdump.c @@ -1,3 +1,4 @@ +#define _GNU_SOURCE #include #include #include @@ -6,35 +7,36 @@ #include #include #include +#include -#define BAUDRATE B57600 -#define BAUDRATE_S "57600" +#define BAUDRATE B115200 +#define BAUDRATE_S "115200" #ifdef linux #define MODEMDEVICE "/dev/ttyS0" #else #define MODEMDEVICE "/dev/com1" #endif /* linux */ -#define SLIP_END 0300 -#define SLIP_ESC 0333 -#define SLIP_ESC_END 0334 -#define SLIP_ESC_ESC 0335 +#define SLIP_END 0300 +#define SLIP_ESC 0333 +#define SLIP_ESC_END 0334 +#define SLIP_ESC_ESC 0335 -#define CSNA_INIT 0x01 +#define CSNA_INIT 0x01 -#define BUFSIZE 40 -#define HCOLS 20 -#define ICOLS 18 +#define BUFSIZE 40 +#define HCOLS 20 +#define ICOLS 18 -#define MODE_START_DATE 0 -#define MODE_DATE 1 -#define MODE_START_TEXT 2 -#define MODE_TEXT 3 -#define MODE_INT 4 -#define MODE_HEX 5 -#define MODE_SLIP_AUTO 6 -#define MODE_SLIP 7 -#define MODE_SLIP_HIDE 8 +#define MODE_START_DATE 0 +#define MODE_DATE 1 +#define MODE_START_TEXT 2 +#define MODE_TEXT 3 +#define MODE_INT 4 +#define MODE_HEX 5 +#define MODE_SLIP_AUTO 6 +#define MODE_SLIP 7 +#define MODE_SLIP_HIDE 8 static unsigned char rxbuf[2048]; @@ -53,7 +55,7 @@ usage(int result) } static void -print_hex_line(unsigned char *prefix, unsigned char *outbuf, int index) +print_hex_line(char *prefix, unsigned char *outbuf, int index) { int i; @@ -80,7 +82,8 @@ print_hex_line(unsigned char *prefix, unsigned char *outbuf, int index) } } -int main(int argc, char **argv) +int +main(int argc, char **argv) { struct termios options; fd_set mask, smask; @@ -89,106 +92,118 @@ int main(int argc, char **argv) char *speedname = BAUDRATE_S; char *device = MODEMDEVICE; char *timeformat = NULL; - unsigned char buf[BUFSIZE], outbuf[HCOLS]; + unsigned char buf[BUFSIZE]; + char outbuf[HCOLS]; unsigned char mode = MODE_START_TEXT; int nfound, flags = 0; unsigned char lastc = '\0'; int index = 1; - while (index < argc) { - if (argv[index][0] == '-') { + while(index < argc) { + if(argv[index][0] == '-') { switch(argv[index][1]) { - case 'b': - /* set speed */ - if (strcmp(&argv[index][2], "38400") == 0) { - speed = B38400; - speedname = "38400"; - } else if (strcmp(&argv[index][2], "19200") == 0) { - speed = B19200; - speedname = "19200"; - } else if (strcmp(&argv[index][2], "57600") == 0) { - speed = B57600; - speedname = "57600"; - } else if (strcmp(&argv[index][2], "115200") == 0) { - speed = B115200; - speedname = "115200"; - } else { - fprintf(stderr, "unsupported speed: %s\n", &argv[index][2]); - return usage(1); - } - break; - case 'x': - mode = MODE_HEX; - break; - case 'i': - mode = MODE_INT; - break; - case 's': - switch(argv[index][2]) { - case 'n': - mode = MODE_SLIP_HIDE; - break; - case 'o': - mode = MODE_SLIP; - break; - default: - mode = MODE_SLIP_AUTO; - break; - } - break; - case 'T': - if(strlen(&argv[index][2]) == 0) { - timeformat = "%Y-%m-%d %H:%M:%S"; - } else { - timeformat = &argv[index][2]; - } - mode = MODE_START_DATE; - break; - case 'h': - return usage(0); - default: - fprintf(stderr, "unknown option '%c'\n", argv[index][1]); - return usage(1); + case 'b': + /* set speed */ + if(strcmp(&argv[index][2], "38400") == 0) { + speed = B38400; + speedname = "38400"; + } else if(strcmp(&argv[index][2], "19200") == 0) { + speed = B19200; + speedname = "19200"; + } else if(strcmp(&argv[index][2], "57600") == 0) { + speed = B57600; + speedname = "57600"; + } else if(strcmp(&argv[index][2], "115200") == 0) { + speed = B115200; + speedname = "115200"; + } else { + fprintf(stderr, "unsupported speed: %s\n", &argv[index][2]); + return usage(1); + } + break; + case 'x': + mode = MODE_HEX; + break; + case 'i': + mode = MODE_INT; + break; + case 's': + switch(argv[index][2]) { + case 'n': + mode = MODE_SLIP_HIDE; + break; + case 'o': + mode = MODE_SLIP; + break; + default: + mode = MODE_SLIP_AUTO; + break; + } + break; + case 'T': + if(strlen(&argv[index][2]) == 0) { + timeformat = "%Y-%m-%d %H:%M:%S"; + } else { + timeformat = &argv[index][2]; + } + mode = MODE_START_DATE; + break; + case 'h': + return usage(0); + default: + fprintf(stderr, "unknown option '%c'\n", argv[index][1]); + return usage(1); } index++; } else { device = argv[index++]; - if (index < argc) { - fprintf(stderr, "too many arguments\n"); - return usage(1); + if(index < argc) { + fprintf(stderr, "too many arguments\n"); + return usage(1); } } } fprintf(stderr, "connecting to %s (%s)", device, speedname); -#ifndef __APPLE__ - fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_DIRECT | O_SYNC ); -#else - fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC ); + + +#ifndef O_SYNC +#define O_SYNC 0 #endif - if (fd <0) { +#ifdef O_DIRECT + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_DIRECT | O_SYNC); + /* Some systems do not support certain parameters (e.g. raspbian) + * Just do some random testing. Not sure whether there is a better way + * of doing this. */ + if(fd < 0 && errno == EINVAL){ + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC); + } +#else + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC); +#endif + if(fd < 0) { fprintf(stderr, "\n"); - perror(device); + perror("open"); exit(-1); } fprintf(stderr, " [OK]\n"); - if (fcntl(fd, F_SETFL, 0) < 0) { + if(fcntl(fd, F_SETFL, 0) < 0) { perror("could not set fcntl"); exit(-1); } - if (tcgetattr(fd, &options) < 0) { + if(tcgetattr(fd, &options) < 0) { perror("could not get options"); exit(-1); } -/* fprintf(stderr, "serial options set\n"); */ + /* fprintf(stderr, "serial options set\n"); */ cfsetispeed(&options, speed); cfsetospeed(&options, speed); /* Enable the receiver and set local mode */ options.c_cflag |= (CLOCAL | CREAD); /* Mask the character size bits and turn off (odd) parity */ - options.c_cflag &= ~(CSIZE|PARENB|PARODD); + options.c_cflag &= ~(CSIZE | PARENB | PARODD); /* Select 8 data bits */ options.c_cflag |= CS8; @@ -197,30 +212,29 @@ int main(int argc, char **argv) /* Raw output */ options.c_oflag &= ~OPOST; - if (tcsetattr(fd, TCSANOW, &options) < 0) { + if(tcsetattr(fd, TCSANOW, &options) < 0) { perror("could not set options"); exit(-1); } /* Make read() return immediately */ -/* if (fcntl(fd, F_SETFL, FNDELAY) < 0) { */ -/* perror("\ncould not set fcntl"); */ -/* exit(-1); */ -/* } */ + /* if (fcntl(fd, F_SETFL, FNDELAY) < 0) { */ + /* perror("\ncould not set fcntl"); */ + /* exit(-1); */ + /* } */ FD_ZERO(&mask); FD_SET(fd, &mask); FD_SET(fileno(stdin), &mask); index = 0; - for (;;) { + for(;;) { smask = mask; - nfound = select(FD_SETSIZE, &smask, (fd_set *) 0, (fd_set *) 0, - (struct timeval *) 0); + nfound = select(FD_SETSIZE, &smask, (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0); if(nfound < 0) { - if (errno == EINTR) { - fprintf(stderr, "interrupted system call\n"); - continue; + if(errno == EINTR) { + fprintf(stderr, "interrupted system call\n"); + continue; } /* something is very wrong! */ perror("select"); @@ -230,143 +244,142 @@ int main(int argc, char **argv) if(FD_ISSET(fileno(stdin), &smask)) { /* data from standard in */ int n = read(fileno(stdin), buf, sizeof(buf)); - if (n < 0) { - perror("could not read"); - exit(-1); - } else if (n > 0) { - /* because commands might need parameters, lines needs to be - separated which means the terminating LF must be sent */ -/* while(n > 0 && buf[n - 1] < 32) { */ -/* n--; */ -/* } */ - if(n > 0) { - int i; - /* fprintf(stderr, "SEND %d bytes\n", n);*/ - /* write slowly */ - for (i = 0; i < n; i++) { - if (write(fd, &buf[i], 1) <= 0) { - perror("write"); - exit(1); - } else { - fflush(NULL); - usleep(6000); - } - } - } + if(n < 0) { + perror("could not read"); + exit(-1); + } else if(n > 0) { + /* because commands might need parameters, lines needs to be + separated which means the terminating LF must be sent */ + /* while(n > 0 && buf[n - 1] < 32) { */ + /* n--; */ + /* } */ + if(n > 0) { + int i; + /* fprintf(stderr, "SEND %d bytes\n", n);*/ + /* write slowly */ + for(i = 0; i < n; i++) { + if(write(fd, &buf[i], 1) <= 0) { + perror("write"); + exit(1); + } else { + fflush(NULL); + usleep(6000); + } + } + } } else { - /* End of input, exit. */ - exit(0); + /* End of input, exit. */ + exit(0); } } if(FD_ISSET(fd, &smask)) { - int i, j, n = read(fd, buf, sizeof(buf)); - if (n < 0) { - perror("could not read"); - exit(-1); + int i, n = read(fd, buf, sizeof(buf)); + if(n < 0) { + perror("could not read"); + exit(-1); } for(i = 0; i < n; i++) { - switch(mode) { - case MODE_START_TEXT: - case MODE_TEXT: - printf("%c", buf[i]); - break; - case MODE_START_DATE: { - time_t t; - t = time(&t); - strftime(outbuf, HCOLS, timeformat, localtime(&t)); - printf("%s|", outbuf); - mode = MODE_DATE; - } - /* continue into the MODE_DATE */ - case MODE_DATE: - printf("%c", buf[i]); - if(buf[i] == '\n') { - mode = MODE_START_DATE; - } - break; - case MODE_INT: - printf("%03d ", buf[i]); - if(++index >= ICOLS) { - index = 0; - printf("\n"); - } - break; - case MODE_HEX: - rxbuf[index++] = buf[i]; - if(index >= HCOLS) { - print_hex_line("", rxbuf, index); - index = 0; - printf("\n"); - } - break; + switch(mode) { + case MODE_START_TEXT: + case MODE_TEXT: + printf("%c", buf[i]); + break; + case MODE_START_DATE: { + time_t t; + t = time(&t); + strftime(outbuf, HCOLS, timeformat, localtime(&t)); + printf("%s|", outbuf); + mode = MODE_DATE; + } + /* continue into the MODE_DATE */ + case MODE_DATE: + printf("%c", buf[i]); + if(buf[i] == '\n') { + mode = MODE_START_DATE; + } + break; + case MODE_INT: + printf("%03d ", buf[i]); + if(++index >= ICOLS) { + index = 0; + printf("\n"); + } + break; + case MODE_HEX: + rxbuf[index++] = buf[i]; + if(index >= HCOLS) { + print_hex_line("", rxbuf, index); + index = 0; + printf("\n"); + } + break; - case MODE_SLIP_AUTO: - case MODE_SLIP_HIDE: - if(!flags && (buf[i] != SLIP_END)) { - /* Not a SLIP packet? */ - printf("%c", buf[i]); - break; - } - /* continue to slip only mode */ - case MODE_SLIP: - switch(buf[i]) { - case SLIP_ESC: - lastc = SLIP_ESC; - break; + case MODE_SLIP_AUTO: + case MODE_SLIP_HIDE: + if(!flags && (buf[i] != SLIP_END)) { + /* Not a SLIP packet? */ + printf("%c", buf[i]); + break; + } + /* continue to slip only mode */ + case MODE_SLIP: + switch(buf[i]) { + case SLIP_ESC: + lastc = SLIP_ESC; + break; - case SLIP_END: - if(index > 0) { - if(flags != 2 && mode != MODE_SLIP_HIDE) { - /* not overflowed: show packet */ - print_hex_line("SLIP: ", rxbuf, - index > HCOLS ? HCOLS : index); - printf("\n"); - } - lastc = '\0'; - index = 0; - flags = 0; - } else { - flags = !flags; - } - break; + case SLIP_END: + if(index > 0) { + if(flags != 2 && mode != MODE_SLIP_HIDE) { + /* not overflowed: show packet */ + print_hex_line("SLIP: ", rxbuf, index > HCOLS ? HCOLS : index); + printf("\n"); + } + lastc = '\0'; + index = 0; + flags = 0; + } else { + flags = !flags; + } + break; - default: - if(lastc == SLIP_ESC) { - lastc = '\0'; + default: + if(lastc == SLIP_ESC) { + lastc = '\0'; - /* Previous read byte was an escape byte, so this byte will be - interpreted differently from others. */ - switch(buf[i]) { - case SLIP_ESC_END: - buf[i] = SLIP_END; - break; - case SLIP_ESC_ESC: - buf[i] = SLIP_ESC; - break; - } - } + /* Previous read byte was an escape byte, so this byte will be + interpreted differently from others. */ + switch(buf[i]) { + case SLIP_ESC_END: + buf[i] = SLIP_END; + break; + case SLIP_ESC_ESC: + buf[i] = SLIP_ESC; + break; + } + } - rxbuf[index++] = buf[i]; - if(index >= sizeof(rxbuf)) { - fprintf(stderr, "**** slip overflow\n"); - index = 0; - flags = 2; - } - break; - } - break; - } + rxbuf[index++] = buf[i]; + if(index >= sizeof(rxbuf)) { + fprintf(stderr, "**** slip overflow\n"); + index = 0; + flags = 2; + } + break; + } + break; + } } /* after processing for some output modes */ if(index > 0) { - switch(mode) { - case MODE_HEX: - print_hex_line("", rxbuf, index); - break; - } + switch(mode) { + case MODE_HEX: + print_hex_line("", rxbuf, index); + break; + } } fflush(stdout); } diff --git a/tools/sky/uip6-bridge/Makefile b/tools/sky/uip6-bridge/Makefile index b537ecce0..11fa74356 100644 --- a/tools/sky/uip6-bridge/Makefile +++ b/tools/sky/uip6-bridge/Makefile @@ -6,8 +6,7 @@ CONTIKI=../../.. endif endif -DEFINES=WITH_UIP6=1,WITH_SLIP=1,PROJECT_CONF_H=\"bridge-conf.h\" -UIP_CONF_IPV6=1 +DEFINES=WITH_SLIP=1,PROJECT_CONF_H=\"bridge-conf.h\" ifndef TARGET TARGET=sky @@ -22,6 +21,7 @@ upload: uip6-bridge-tap.ihex cp $< $(IHEXFILE) $(MAKE) sky-u.$(subst /,-,$(word $(MOTE), $(MOTES))) +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include ../../tapslip6: ../../tapslip6.c @@ -36,5 +36,5 @@ connect: ../../tapslip6 bridge: @sudo service radvd restart || echo radvd could not be restarted - sudo route add -6 aaaa::/64 tap0 - sudo ip -6 address add aaaa::1/64 dev tap0 + sudo route add -6 fd00::/64 tap0 + sudo ip -6 address add fd00::1/64 dev tap0 diff --git a/tools/sky/uip6-bridge/dev/slip.c b/tools/sky/uip6-bridge/dev/slip.c index 8c63da078..4cb65cfd5 100644 --- a/tools/sky/uip6-bridge/dev/slip.c +++ b/tools/sky/uip6-bridge/dev/slip.c @@ -100,7 +100,7 @@ slip_set_tcpip_input_callback(void (*c)(void)) tcpip_input_callback = c; } /*---------------------------------------------------------------------------*/ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 uint8_t slip_send(void) { @@ -129,7 +129,7 @@ slip_send(void) return UIP_FW_OK; } -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ /*---------------------------------------------------------------------------*/ uint8_t slip_write(const void *_ptr, int len) @@ -263,7 +263,7 @@ PROCESS_THREAD(slip_process, ev, data) /* Move packet from rxbuf to buffer provided by uIP. */ uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN], UIP_BUFSIZE - UIP_LLH_LEN); -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 if(uip_len == 4 && strncmp((char*)&uip_buf[UIP_LLH_LEN], "?IPA", 4) == 0) { char buf[8]; memcpy(&buf[0], "=IPA", 4); @@ -294,10 +294,10 @@ PROCESS_THREAD(slip_process, ev, data) tcpip_input(); } } else { - uip_len = 0; + uip_clear_buf(); SLIP_STATISTICS(slip_ip_drop++); } -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ if(uip_len > 0) { if(tcpip_input_callback) { tcpip_input_callback(); @@ -305,7 +305,7 @@ PROCESS_THREAD(slip_process, ev, data) tcpip_input(); } } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ } PROCESS_END(); diff --git a/tools/sky/uip6-bridge/fakeuip.c b/tools/sky/uip6-bridge/fakeuip.c index 45f22ca11..b636f7752 100644 --- a/tools/sky/uip6-bridge/fakeuip.c +++ b/tools/sky/uip6-bridge/fakeuip.c @@ -55,7 +55,7 @@ uip_ds6_get_link_local(int8_t state) { for(locaddr = uip_ds6_if.addr_list; locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { if((locaddr->isused) && (state == - 1 || locaddr->state == state) - && (uip_is_addr_link_local(&locaddr->ipaddr))) { + && (uip_is_addr_linklocal(&locaddr->ipaddr))) { return locaddr; } } diff --git a/tools/sky/uip6-bridge/sicslow_ethernet.c b/tools/sky/uip6-bridge/sicslow_ethernet.c index 29967d1c0..7de0694c3 100644 --- a/tools/sky/uip6-bridge/sicslow_ethernet.c +++ b/tools/sky/uip6-bridge/sicslow_ethernet.c @@ -238,13 +238,13 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) if (((struct uip_eth_hdr *) ethHeader)->type != UIP_HTONS(UIP_ETHTYPE_IPV6)) { PRINTF("eth2low: Packet is not IPv6, dropping\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } // In sniffer mode we don't ever send anything if (usbstick_mode.sendToRf == 0) { - uip_len = 0; + uip_clear_buf(); return; } @@ -263,7 +263,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) /* IPv6 does not use broadcast addresses, hence this should not happen */ PRINTF("eth2low: Ethernet broadcast address received, should not happen?\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } else { PRINTF("eth2low: Addressed packet received... "); @@ -271,7 +271,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) if (mac_createSicslowpanLongAddr( &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), &destAddr) == 0) { PRINTF(" translation failed\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } PRINTF(" translated OK\n"); @@ -295,7 +295,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) } } - uip_len = 0; + uip_clear_buf(); } @@ -312,7 +312,7 @@ void mac_LowpanToEthernet(void) ETHBUF(uip_buf)->type = uip_htons(UIP_ETHTYPE_IPV6); //Check for broadcast message - if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) { + if(packetbuf_holds_broadcast()) { /* if( ( parsed_frame->fcf->destAddrMode == SHORTADDRMODE) && */ /* ( parsed_frame->dest_addr->addr16 == 0xffff) ) { */ ETHBUF(uip_buf)->dest.addr[0] = 0x33; @@ -343,7 +343,7 @@ void mac_LowpanToEthernet(void) /* rndis_send(uip_buf, uip_len, 1); */ /* rndis_stat.rxok++; */ -/* uip_len = 0; */ +/* uip_clear_buf(); */ } /** diff --git a/tools/sky/uip6-bridge/uip6-bridge-tap.c b/tools/sky/uip6-bridge/uip6-bridge-tap.c index e0e413ffb..9aabd752f 100644 --- a/tools/sky/uip6-bridge/uip6-bridge-tap.c +++ b/tools/sky/uip6-bridge/uip6-bridge-tap.c @@ -64,7 +64,7 @@ tcpip_output(const uip_lladdr_t *a) /* printf("pppp o %u tx %u rx %u\n", UIP_IP_BUF->proto, packetbuf_attr(PACKETBUF_ATTR_TRANSMIT_TIME), packetbuf_attr(PACKETBUF_ATTR_LISTEN_TIME));*/ - leds_invert(LEDS_GREEN); + leds_toggle(LEDS_GREEN); } return 0; } @@ -94,8 +94,8 @@ tcpip_input(void) packetbuf_attr(PACKETBUF_ATTR_TRANSMIT_TIME), packetbuf_attr(PACKETBUF_ATTR_LISTEN_TIME));*/ slip_write(uip_buf, uip_len); - leds_invert(LEDS_RED); - uip_len = 0; + leds_toggle(LEDS_RED); + uip_clear_buf(); } } } @@ -112,7 +112,7 @@ slip_tcpip_input(void) static void slip_activity(void) { - leds_invert(LEDS_BLUE); + leds_toggle(LEDS_BLUE); } /*---------------------------------------------------------------------------*/ PROCESS_THREAD(uip6_bridge, ev, data) diff --git a/tools/stm32w/Makefile b/tools/stm32w/Makefile new file mode 100644 index 000000000..be3caa44b --- /dev/null +++ b/tools/stm32w/Makefile @@ -0,0 +1,25 @@ +ifndef HOST_OS + ifeq ($(OS),Windows_NT) + HOST_OS := Windows + else + HOST_OS := $(shell uname) + endif +endif + +ifeq ($(HOST_OS),Windows) + SERIALDUMP = serialdump-windows +endif + +ifeq ($(HOST_OS),Darwin) + SERIALDUMP = serialdump-macos +endif + +ifndef SERIALDUMP + # Assume Linux + SERIALDUMP = serialdump-linux +endif + +all: $(SERIALDUMP) + +$(SERIALDUMP): serialdump.c + $(CC) -O2 -o $@ $< diff --git a/tools/stm32w/uip6_bridge/Makefile b/tools/stm32w/uip6_bridge/Makefile index a1116deca..f2fd05965 100644 --- a/tools/stm32w/uip6_bridge/Makefile +++ b/tools/stm32w/uip6_bridge/Makefile @@ -7,7 +7,6 @@ endif endif DEFINES=PROJECT_CONF_H=\"bridge-conf.h\" -UIP_CONF_IPV6=1 ifndef TARGET TARGET=mbxxx @@ -18,4 +17,5 @@ PROJECT_SOURCEFILES = fakeuip.c sicslow_ethernet.c slip.c all: uip6-bridge-tap +CONTIKI_WITH_IPV6 = 1 include $(CONTIKI)/Makefile.include diff --git a/tools/stm32w/uip6_bridge/dev/slip.c b/tools/stm32w/uip6_bridge/dev/slip.c index e9983ca6e..543896266 100644 --- a/tools/stm32w/uip6_bridge/dev/slip.c +++ b/tools/stm32w/uip6_bridge/dev/slip.c @@ -115,7 +115,7 @@ slip_set_tcpip_input_callback(void (*c)(void)) tcpip_input_callback = c; } /*---------------------------------------------------------------------------*/ -#if WITH_UIP +#if NETSTACK_CONF_WITH_IPV4 uint8_t slip_send(void) { @@ -144,7 +144,7 @@ slip_send(void) return UIP_FW_OK; } -#endif /* WITH_UIP */ +#endif /* NETSTACK_CONF_WITH_IPV4 */ /*---------------------------------------------------------------------------*/ uint8_t slip_write(const void *_ptr, int len) @@ -339,7 +339,7 @@ PROCESS_THREAD(slip_process, ev, data) /* Move packet from rxbuf to buffer provided by uIP. */ uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN], UIP_BUFSIZE - UIP_LLH_LEN); -#if !UIP_CONF_IPV6 +#if !NETSTACK_CONF_WITH_IPV6 if(uip_len == 4 && strncmp((char*)&uip_buf[UIP_LLH_LEN], "?IPA", 4) == 0) { char buf[8]; memcpy(&buf[0], "=IPA", 4); @@ -370,10 +370,10 @@ PROCESS_THREAD(slip_process, ev, data) tcpip_input(); } } else { - uip_len = 0; + uip_clear_buf(); SLIP_STATISTICS(slip_ip_drop++); } -#else /* UIP_CONF_IPV6 */ +#else /* NETSTACK_CONF_WITH_IPV6 */ if(uip_len > 0) { if(tcpip_input_callback) { tcpip_input_callback(); @@ -381,7 +381,7 @@ PROCESS_THREAD(slip_process, ev, data) tcpip_input(); } } -#endif /* UIP_CONF_IPV6 */ +#endif /* NETSTACK_CONF_WITH_IPV6 */ } PROCESS_END(); diff --git a/tools/stm32w/uip6_bridge/fakeuip.c b/tools/stm32w/uip6_bridge/fakeuip.c index e356a6469..2ae3285b1 100644 --- a/tools/stm32w/uip6_bridge/fakeuip.c +++ b/tools/stm32w/uip6_bridge/fakeuip.c @@ -55,7 +55,7 @@ uip_ds6_get_link_local(int8_t state) { for(locaddr = uip_ds6_if.addr_list; locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { if((locaddr->isused) && (state == - 1 || locaddr->state == state) - && (uip_is_addr_link_local(&locaddr->ipaddr))) { + && (uip_is_addr_linklocal(&locaddr->ipaddr))) { return locaddr; } } diff --git a/tools/stm32w/uip6_bridge/sicslow_ethernet.c b/tools/stm32w/uip6_bridge/sicslow_ethernet.c index 5c70bacaf..24c2b648c 100644 --- a/tools/stm32w/uip6_bridge/sicslow_ethernet.c +++ b/tools/stm32w/uip6_bridge/sicslow_ethernet.c @@ -267,13 +267,13 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) if (((struct uip_eth_hdr *) ethHeader)->type != UIP_HTONS(UIP_ETHTYPE_IPV6)) { PRINTF("eth2low: Packet is not IPv6, dropping\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } // In sniffer mode we don't ever send anything if (usbstick_mode.sendToRf == 0) { - uip_len = 0; + uip_clear_buf(); return; } @@ -292,7 +292,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) /* IPv6 does not use broadcast addresses, hence this should not happen */ PRINTF("eth2low: Ethernet broadcast address received, should not happen?\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } else { PRINTF("eth2low: Addressed packet received... "); @@ -300,7 +300,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) if (mac_createSicslowpanLongAddr( &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), &destAddr) == 0) { PRINTF(" translation failed\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } PRINTF(" translated OK\n"); @@ -322,7 +322,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) /* rndis_stat.txok++; */ } - uip_len = 0; + uip_clear_buf(); } @@ -339,7 +339,7 @@ void mac_LowpanToEthernet(void) ETHBUF(uip_buf)->type = htons(UIP_ETHTYPE_IPV6); //Check for broadcast message - if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) { + if(packetbuf_holds_broadcast()) { /* if( ( parsed_frame->fcf->destAddrMode == SHORTADDRMODE) && */ /* ( parsed_frame->dest_addr->addr16 == 0xffff) ) { */ ETHBUF(uip_buf)->dest.addr[0] = 0x33; @@ -370,7 +370,7 @@ void mac_LowpanToEthernet(void) /* rndis_send(uip_buf, uip_len, 1); */ /* rndis_stat.rxok++; */ -/* uip_len = 0; */ +/* uip_clear_buf(); */ } /** @@ -968,7 +968,7 @@ void mac_802154raw(const struct radio_driver *radio) #endif slip_write(uip_buf, len); - leds_invert(LEDS_RED); + leds_toggle(LEDS_RED); //rndis_send(raw_buf, sendlen, 1); //rndis_stat.rxok++; diff --git a/tools/stm32w/uip6_bridge/uip6-bridge-tap.c b/tools/stm32w/uip6_bridge/uip6-bridge-tap.c index 6fea42db2..307d8ea4e 100644 --- a/tools/stm32w/uip6_bridge/uip6-bridge-tap.c +++ b/tools/stm32w/uip6_bridge/uip6-bridge-tap.c @@ -98,7 +98,7 @@ tcpip_input(void) packetbuf_attr(PACKETBUF_ATTR_TRANSMIT_TIME), packetbuf_attr(PACKETBUF_ATTR_LISTEN_TIME));*/ slip_write(uip_buf, uip_len); - uip_len = 0; + uip_clear_buf(); leds_off(LEDS_RED); } } diff --git a/tools/stm32w/wpcapslip6/README.md b/tools/stm32w/wpcapslip6/README.md index f3c277efb..63bb6dccd 100644 --- a/tools/stm32w/wpcapslip6/README.md +++ b/tools/stm32w/wpcapslip6/README.md @@ -14,9 +14,9 @@ rpl-border-router (the latter on Windows Vista and later only). An example of usage with the RPL border router: - wpcapslip6 -s COMXX -b aaaa:: -a aaaa:1::1/128 02-00-00-00-00-01 + wpcapslip6 -s COMXX -b fd00:: -a fd00:1::1/128 02-00-00-00-00-01 where 02-00-00-00-00-01 is the MAC address of the local network adapter. --a aaaa:1::1/128 can be omitted if an IP address is already set to the network +-a fd00:1::1/128 can be omitted if an IP address is already set to the network adapter. diff --git a/tools/stm32w/wpcapslip6/fakeuip.c b/tools/stm32w/wpcapslip6/fakeuip.c index 73d103cdf..41fc2064e 100644 --- a/tools/stm32w/wpcapslip6/fakeuip.c +++ b/tools/stm32w/wpcapslip6/fakeuip.c @@ -3,7 +3,7 @@ * compile. Allows you to save needing to compile all of uIP in just * to get a few things */ -#define UIP_CONF_IPV6 1 +#define NETSTACK_CONF_WITH_IPV6 1 #include "net/ip/uip.h" #include diff --git a/tools/stm32w/wpcapslip6/ip-process.c b/tools/stm32w/wpcapslip6/ip-process.c index ccd73d0e7..f4927e0c8 100644 --- a/tools/stm32w/wpcapslip6/ip-process.c +++ b/tools/stm32w/wpcapslip6/ip-process.c @@ -1,5 +1,5 @@ -#define UIP_CONF_IPV6 1 +#define NETSTACK_CONF_WITH_IPV6 1 #define UIP_CONF_LL_802154 1 #include diff --git a/tools/tools-utils.c b/tools/tools-utils.c new file mode 100644 index 000000000..6ad0a9365 --- /dev/null +++ b/tools/tools-utils.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#include "tools-utils.h" + +speed_t +select_baudrate(int baudrate) { + switch(baudrate) { +#ifdef B50 + case 50: + return B50; +#endif +#ifdef B75 + case 75: + return B75; +#endif +#ifdef B110 + case 110: + return B110; +#endif +#ifdef B134 + case 134: + return B134; +#endif +#ifdef B150 + case 150: + return B150; +#endif +#ifdef B200 + case 200: + return B200; +#endif +#ifdef B300 + case 300: + return B300; +#endif +#ifdef B600 + case 600: + return B600; +#endif +#ifdef B1200 + case 1200: + return B1200; +#endif +#ifdef B1800 + case 1800: + return B1800; +#endif +#ifdef B2400 + case 2400: + return B2400; +#endif +#ifdef B4800 + case 4800: + return B4800; +#endif +#ifdef B9600 + case 9600: + return B9600; +#endif +#ifdef B19200 + case 19200: + return B19200; +#endif +#ifdef B38400 + case 38400: + return B38400; +#endif +#ifdef B57600 + case 57600: + return B57600; +#endif +#ifdef B115200 + case 115200: + return B115200; +#endif +#ifdef B230400 + return B230400; +#endif +#ifdef B460800 + case 460800: + return B460800; +#endif +#ifdef B500000 + case 500000: + return B500000; +#endif +#ifdef B576000 + case 576000: + return B576000; +#endif +#ifdef B921600 + case 921600: + return B921600; +#endif +#ifdef B1000000 + case 1000000: + return B1000000; +#endif +#ifdef B1152000 + case 1152000: + return B1152000; +#endif +#ifdef B1500000 + case 1500000: + return B1500000; +#endif +#ifdef B2000000 + case 2000000: + return B2000000; +#endif +#ifdef B2500000 + case 2500000: + return B2500000; +#endif +#ifdef B3000000 + case 3000000: + return B3000000; +#endif +#ifdef B3500000 + case 3500000: + return B3500000; +#endif +#ifdef B4000000 + case 4000000: + return B4000000; +#endif + default: + return 0; + } +} + diff --git a/tools/tools-utils.h b/tools/tools-utils.h new file mode 100644 index 000000000..4b996cc75 --- /dev/null +++ b/tools/tools-utils.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015, SICS Swedish ICT + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#ifndef TOOLS_UTILS +#define TOOLS_UTILS + +#include + +#if __APPLE__ +#ifndef B460800 +#define B460800 460800 +#endif +#ifndef B500000 +#define B500000 500000 +#endif +#ifndef B576000 +#define B576000 576000 +#endif +#ifndef B921600 +#define B921600 921600 +#endif +#ifndef B1000000 +#define B1000000 1000000 +#endif +#ifndef B1152000 +#define B1152000 1152000 +#endif +#ifndef B1500000 +#define B1500000 1500000 +#endif +#ifndef B2000000 +#define B2000000 2000000 +#endif +#ifndef B2500000 +#define B2500000 2500000 +#endif +#ifndef B3000000 +#define B3000000 3000000 +#endif +#ifndef B3500000 +#define B3500000 3500000 +#endif +#ifndef B4000000 +#define B4000000 4000000 +#endif +#endif + +speed_t select_baudrate(int baudrate); + +#endif /* TOOLS_UTILS */ diff --git a/tools/tunslip6.c b/tools/tunslip6.c index 65e440800..49019a66b 100644 --- a/tools/tunslip6.c +++ b/tools/tunslip6.c @@ -34,7 +34,7 @@ /* Below define allows importing saved output into Wireshark as "Raw IP" packet type */ #define WIRESHARK_IMPORT_FORMAT 1 - + #include #include #include @@ -56,13 +56,20 @@ #include +#include "tools-utils.h" + +#ifndef BAUDRATE +#define BAUDRATE B115200 +#endif +speed_t b_rate = BAUDRATE; + int verbose = 1; const char *ipaddr; const char *netmask; int slipfd = 0; uint16_t basedelay=0,delaymsec=0; uint32_t startsec,startmsec,delaystartsec,delaystartmsec; -int timestamp = 0, flowcontrol=0; +int timestamp = 0, flowcontrol=0, showprogress=0, flowcontrol_xonxoff=0; int ssystem(const char *fmt, ...) __attribute__((__format__ (__printf__, 1, 2))); @@ -71,11 +78,14 @@ void write_to_serial(int outfd, void *inbuf, int len); void slip_send(int fd, unsigned char c); void slip_send_char(int fd, unsigned char c); -//#define PROGRESS(s) fprintf(stderr, s) -#define PROGRESS(s) do { } while (0) +#define PROGRESS(s) if(showprogress) fprintf(stderr, s) char tundev[1024] = { "" }; +/* IPv6 required minimum MTU */ +#define MIN_DEVMTU 1500 +int devmtu = MIN_DEVMTU; + int ssystem(const char *fmt, ...) __attribute__((__format__ (__printf__, 1, 2))); @@ -92,11 +102,15 @@ ssystem(const char *fmt, ...) return system(cmd); } -#define SLIP_END 0300 -#define SLIP_ESC 0333 -#define SLIP_ESC_END 0334 -#define SLIP_ESC_ESC 0335 +#define SLIP_END 0300 +#define SLIP_ESC 0333 +#define SLIP_ESC_END 0334 +#define SLIP_ESC_ESC 0335 +#define SLIP_ESC_XON 0336 +#define SLIP_ESC_XOFF 0337 +#define XON 17 +#define XOFF 19 /* get sockaddr, IPv4 or IPv6: */ void * @@ -116,7 +130,7 @@ stamptime(void) time_t t; struct tm *tmp; char timec[20]; - + gettimeofday(&tv, NULL) ; msecs=tv.tv_usec/1000; secs=tv.tv_sec; @@ -187,7 +201,7 @@ serial_to_tun(FILE *inslip, int outfd) clearerr(inslip); return; } - /* fprintf(stderr, ".");*/ + PROGRESS("."); switch(c) { case SLIP_END: if(inbufptr > 0) { @@ -225,8 +239,7 @@ serial_to_tun(FILE *inslip, int outfd) inet_pton(AF_INET6, ipaddr, &addr); if(timestamp) stamptime(); fprintf(stderr,"*** Address:%s => %02x%02x:%02x%02x:%02x%02x:%02x%02x\n", - // printf("*** Address:%s => %02x%02x:%02x%02x:%02x%02x:%02x%02x\n", - ipaddr, + ipaddr, addr.s6_addr[0], addr.s6_addr[1], addr.s6_addr[2], addr.s6_addr[3], addr.s6_addr[4], addr.s6_addr[5], @@ -240,7 +253,7 @@ serial_to_tun(FILE *inslip, int outfd) slip_send(slipfd, SLIP_END); } #define DEBUG_LINE_MARKER '\r' - } else if(uip.inbuf[0] == DEBUG_LINE_MARKER) { + } else if(uip.inbuf[0] == DEBUG_LINE_MARKER) { fwrite(uip.inbuf + 1, inbufptr - 1, 1, stdout); } else if(is_sensible_string(uip.inbuf, inbufptr)) { if(verbose==1) { /* strings already echoed below for verbose>1 */ @@ -289,6 +302,12 @@ serial_to_tun(FILE *inslip, int outfd) case SLIP_ESC_ESC: c = SLIP_ESC; break; + case SLIP_ESC_XON: + c = XON; + break; + case SLIP_ESC_XOFF: + c = XOFF; + break; } /* FALLTHROUGH */ default: @@ -310,7 +329,7 @@ serial_to_tun(FILE *inslip, int outfd) if(c=='\n') if(timestamp) stamptime(); } } - + break; } @@ -332,6 +351,22 @@ slip_send_char(int fd, unsigned char c) slip_send(fd, SLIP_ESC); slip_send(fd, SLIP_ESC_ESC); break; + case XON: + if(flowcontrol_xonxoff) { + slip_send(fd, SLIP_ESC); + slip_send(fd, SLIP_ESC_XON); + } else { + slip_send(fd, c); + } + break; + case XOFF: + if(flowcontrol_xonxoff) { + slip_send(fd, SLIP_ESC); + slip_send(fd, SLIP_ESC_XOFF); + } else { + slip_send(fd, c); + } + break; default: slip_send(fd, c); break; @@ -358,7 +393,7 @@ void slip_flushbuf(int fd) { int n; - + if(slip_empty()) { return; } @@ -417,6 +452,22 @@ write_to_serial(int outfd, void *inbuf, int len) slip_send(outfd, SLIP_ESC); slip_send(outfd, SLIP_ESC_ESC); break; + case XON: + if(flowcontrol_xonxoff) { + slip_send(outfd, SLIP_ESC); + slip_send(outfd, SLIP_ESC_XON); + } else { + slip_send(outfd, p[i]); + } + break; + case XOFF: + if(flowcontrol_xonxoff) { + slip_send(outfd, SLIP_ESC); + slip_send(outfd, SLIP_ESC_XOFF); + } else { + slip_send(outfd, p[i]); + } + break; default: slip_send(outfd, p[i]); break; @@ -444,11 +495,6 @@ tun_to_serial(int infd, int outfd) return size; } -#ifndef BAUDRATE -#define BAUDRATE B115200 -#endif -speed_t b_rate = BAUDRATE; - void stty_telos(int fd) { @@ -469,6 +515,12 @@ stty_telos(int fd) tty.c_cflag |= CRTSCTS; else tty.c_cflag &= ~CRTSCTS; + tty.c_iflag &= ~IXON; + if(flowcontrol_xonxoff) { + tty.c_iflag |= IXOFF | IXANY; + } else { + tty.c_iflag &= ~IXOFF & ~IXANY; + } tty.c_cflag &= ~HUPCL; tty.c_cflag &= ~CLOCAL; @@ -514,6 +566,7 @@ tun_alloc(char *dev, int tap) int fd, err; if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) { + perror("can not open /dev/net/tun"); return -1; } @@ -530,8 +583,12 @@ tun_alloc(char *dev, int tap) if((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ) { close(fd); + fprintf(stderr, "can not tunsetiff to %s (flags=%08x): %s\n", dev, ifr.ifr_flags, + strerror(errno)); return err; } + + /* get resulting tunnel name */ strcpy(dev, ifr.ifr_name); return fd; } @@ -606,7 +663,7 @@ ifconf(const char *tundev, const char *ipaddr) { #ifdef linux if (timestamp) stamptime(); - ssystem("ifconfig %s inet `hostname` up", tundev); + ssystem("ifconfig %s inet `hostname` mtu %d up", tundev, devmtu); if (timestamp) stamptime(); ssystem("ifconfig %s add %s", tundev, ipaddr); @@ -636,7 +693,7 @@ ifconf(const char *tundev, const char *ipaddr) } else { cc=0; digit = c-'0'; - if (digit > 9) + if (digit > 9) digit = 10 + (c & 0xdf) - 'A'; a[ai] = (a[ai] << 4) + digit; } @@ -667,7 +724,7 @@ ifconf(const char *tundev, const char *ipaddr) prefix = "64"; } if (timestamp) stamptime(); - ssystem("ifconfig %s inet6 up", tundev ); + ssystem("ifconfig %s inet6 mtu %d up", tundev, devmtu); if (timestamp) stamptime(); ssystem("ifconfig %s inet6 %s add", tundev, ipaddr ); if (timestamp) stamptime(); @@ -676,7 +733,7 @@ ifconf(const char *tundev, const char *ipaddr) } #else if (timestamp) stamptime(); - ssystem("ifconfig %s inet `hostname` %s up", tundev, ipaddr); + ssystem("ifconfig %s inet `hostname` %s mtu %d up", tundev, ipaddr, devmtu); if (timestamp) stamptime(); ssystem("sysctl -w net.inet.ip.forwarding=1"); #endif /* !linux */ @@ -698,13 +755,14 @@ main(int argc, char **argv) const char *port = NULL; const char *prog; int baudrate = -2; + int ipa_enable = 0; int tap = 0; slipfd = 0; prog = argv[0]; setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */ - while((c = getopt(argc, argv, "B:HLhs:t:v::d::a:p:T")) != -1) { + while((c = getopt(argc, argv, "B:HILPhXM:s:t:v::d::a:p:T")) != -1) { switch(c) { case 'B': baudrate = atoi(optarg); @@ -713,11 +771,25 @@ main(int argc, char **argv) case 'H': flowcontrol=1; break; - + + case 'X': + flowcontrol_xonxoff=1; + break; + case 'L': timestamp=1; break; + case 'M': + devmtu=atoi(optarg); + if(devmtu < MIN_DEVMTU) { + devmtu = MIN_DEVMTU; + } + + case 'P': + showprogress=1; + break; + case 's': if(strncmp("/dev/", optarg, 5) == 0) { siodev = optarg + 5; @@ -726,6 +798,11 @@ main(int argc, char **argv) } break; + case 'I': + ipa_enable = 1; + fprintf(stderr, "Will inquire about IP address using IPA=\n"); + break; + case 't': if(strncmp("/dev/", optarg, 5) == 0) { strncpy(tundev, optarg + 5, sizeof(tundev)); @@ -755,12 +832,12 @@ main(int argc, char **argv) case 'T': tap = 1; break; - + case '?': case 'h': default: fprintf(stderr,"usage: %s [options] ipaddress\n", prog); -fprintf(stderr,"example: tunslip6 -L -v2 -s ttyUSB1 aaaa::1/64\n"); +fprintf(stderr,"example: tunslip6 -L -v2 -s ttyUSB1 fd00::1/64\n"); fprintf(stderr,"Options are:\n"); #ifndef __APPLE__ fprintf(stderr," -B baudrate 9600,19200,38400,57600,115200 (default),230400,460800,921600\n"); @@ -768,8 +845,11 @@ fprintf(stderr," -B baudrate 9600,19200,38400,57600,115200 (default),230400,4 fprintf(stderr," -B baudrate 9600,19200,38400,57600,115200 (default),230400\n"); #endif fprintf(stderr," -H Hardware CTS/RTS flow control (default disabled)\n"); +fprintf(stderr," -I Inquire IP address\n"); +fprintf(stderr," -X Software XON/XOFF flow control (default disabled)\n"); fprintf(stderr," -L Log output format (adds time stamps)\n"); fprintf(stderr," -s siodev Serial device (default /dev/ttyUSB0)\n"); +fprintf(stderr," -M Interface MTU (default and min: 1280)\n"); fprintf(stderr," -T Make tap interface (default is tun interface)\n"); fprintf(stderr," -t tundev Name of interface (default tap0 or tun0)\n"); fprintf(stderr," -v[level] Verbosity level\n"); @@ -797,48 +877,13 @@ exit(1); } ipaddr = argv[1]; - switch(baudrate) { - case -2: - break; /* Use default. */ - case 9600: - b_rate = B9600; - break; - case 19200: - b_rate = B19200; - break; - case 38400: - b_rate = B38400; - break; - case 57600: - b_rate = B57600; - break; - case 115200: - b_rate = B115200; - break; - case 230400: - b_rate = B230400; - break; -#ifndef __APPLE__ - case 460800: - b_rate = B460800; - break; - case 921600: - b_rate = B921600; - break; -#endif - default: - err(1, "unknown baudrate %d", baudrate); - break; - } - - if(*tundev == '\0') { - /* Use default. */ - if(tap) { - strcpy(tundev, "tap0"); - } else { - strcpy(tundev, "tun0"); + if(baudrate != -2) { /* -2: use default baudrate */ + b_rate = select_baudrate(baudrate); + if(b_rate == 0) { + err(1, "unknown baudrate %d", baudrate); } } + if(host != NULL) { struct addrinfo hints, *servinfo, *p; int rv; @@ -916,7 +961,7 @@ exit(1); if(inslip == NULL) err(1, "main: fdopen"); tunfd = tun_alloc(tundev, tap); - if(tunfd == -1) err(1, "main: open"); + if(tunfd == -1) err(1, "main: open /dev/tun"); if (timestamp) stamptime(); fprintf(stderr, "opened %s device ``/dev/%s''\n", tap ? "tap" : "tun", tundev); @@ -933,16 +978,15 @@ exit(1); FD_ZERO(&rset); FD_ZERO(&wset); -/* do not send IPA all the time... - add get MAC later... */ -/* if(got_sigalarm) { */ -/* /\* Send "?IPA". *\/ */ -/* slip_send(slipfd, '?'); */ -/* slip_send(slipfd, 'I'); */ -/* slip_send(slipfd, 'P'); */ -/* slip_send(slipfd, 'A'); */ -/* slip_send(slipfd, SLIP_END); */ -/* got_sigalarm = 0; */ -/* } */ + if(got_sigalarm && ipa_enable) { + /* Send "?IPA". */ + slip_send(slipfd, '?'); + slip_send(slipfd, 'I'); + slip_send(slipfd, 'P'); + slip_send(slipfd, 'A'); + slip_send(slipfd, SLIP_END); + got_sigalarm = 0; + } if(!slip_empty()) { /* Anything to flush? */ FD_SET(slipfd, &wset); @@ -950,7 +994,7 @@ exit(1); FD_SET(slipfd, &rset); /* Read from slip ASAP! */ if(slipfd > maxfd) maxfd = slipfd; - + /* We only have one packet at a time queued for slip output. */ if(slip_empty()) { FD_SET(tunfd, &rset); @@ -964,12 +1008,12 @@ exit(1); if(FD_ISSET(slipfd, &rset)) { serial_to_tun(inslip, tunfd); } - + if(FD_ISSET(slipfd, &wset)) { slip_flushbuf(slipfd); - sigalarm_reset(); + if(ipa_enable) sigalarm_reset(); } - + /* Optional delay between outgoing packets */ /* Base delay times number of 6lowpan fragments to be sent */ if(delaymsec) { @@ -985,7 +1029,7 @@ exit(1); if(slip_empty() && FD_ISSET(tunfd, &rset)) { size=tun_to_serial(tunfd, slipfd); slip_flushbuf(slipfd); - sigalarm_reset(); + if(ipa_enable) sigalarm_reset(); if(basedelay) { struct timeval tv; gettimeofday(&tv, NULL) ; diff --git a/tools/wpcapslip/Connect.java b/tools/wpcapslip/Connect.java new file mode 100644 index 000000000..7ec6a0699 --- /dev/null +++ b/tools/wpcapslip/Connect.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ + +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.DataInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; + +public class Connect { + private static Process cmd1Process; + private static Process cmd2Process; + private static BufferedOutputStream cmd1Out = null; + private static BufferedOutputStream cmd2Out = null; + + private static final int BUFSIZE = 512; + + public static void main(String[] args) throws Exception { + if (args.length != 2) { + System.err.println("Usage: " + Connect.class.getName() + " [cmd1] [cmd2]"); + System.exit(1); + } + + /* Command 1 */ + String cmd1 = args[0]; + System.out.println("> " + cmd1); + cmd1Process = Runtime.getRuntime().exec(cmd1, null, new File(".")); + final DataInputStream cmd1Input = new DataInputStream( + cmd1Process.getInputStream()); + final BufferedReader cmd1Err = new BufferedReader( + new InputStreamReader(cmd1Process.getErrorStream())); + cmd1Out = new BufferedOutputStream(cmd1Process.getOutputStream()); + Thread readInput = new Thread(new Runnable() { + + public void run() { + int numRead = 0; + byte[] buf = new byte[BUFSIZE]; + try { + while (true) { + numRead = cmd1Input.read(buf, 0, BUFSIZE); + if (numRead > 0 && cmd2Out != null) { + /* System.err.println("1>2 " + numRead); */ + cmd2Out.write(buf, 0, numRead); + cmd2Out.flush(); + } + Thread.sleep(1); + } + } catch (Exception e) { + e.printStackTrace(); + } + String exitVal = "?"; + try { + if (cmd1Process != null) { + exitVal = "" + cmd1Process.exitValue(); + } + } catch (IllegalStateException e) { + e.printStackTrace(); + exitVal = "!"; + } + System.out.println("cmd1 terminated: " + exitVal); + exit(); + } + }, "read stdout cmd1"); + Thread readError = new Thread(new Runnable() { + public void run() { + String line; + try { + while ((line = cmd1Err.readLine()) != null) { + System.err.println("cmd1 err: " + line); + } + cmd1Err.close(); + } catch (IOException e) { + } + System.err.println("cmd1 terminated."); + exit(); + } + }, "read error cmd1"); + readInput.start(); + readError.start(); + + /* Command 2 */ + String cmd2 = args[1]; + System.err.println("> " + cmd2); + cmd2Process = Runtime.getRuntime().exec(cmd2, null, new File(".")); + final DataInputStream cmd2Input = new DataInputStream( + cmd2Process.getInputStream()); + final BufferedReader cmd2Err = new BufferedReader( + new InputStreamReader(cmd2Process.getErrorStream())); + cmd2Out = new BufferedOutputStream(cmd2Process.getOutputStream()); + readInput = new Thread(new Runnable() { + public void run() { + int numRead = 0; + byte[] buf = new byte[BUFSIZE]; + try { + while (true) { + numRead = cmd2Input.read(buf, 0, BUFSIZE); + if (numRead > 0 && cmd1Out != null) { + /* System.err.println("2>1 " + numRead); */ + cmd1Out.write(buf, 0, numRead); + cmd1Out.flush(); + } + Thread.sleep(1); + } + } catch (Exception e) { + e.printStackTrace(); + } + String exitVal = "?"; + try { + if (cmd2Process != null) { + exitVal = "" + cmd2Process.exitValue(); + } + } catch (IllegalStateException e) { + e.printStackTrace(); + exitVal = "!"; + } + System.out.println("cmd2 terminated: " + exitVal); + exit(); + } + }, "read stdout cmd2"); + readError = new Thread(new Runnable() { + public void run() { + String line; + try { + while ((line = cmd2Err.readLine()) != null) { + System.err.println("cmd2 err: " + line); + } + cmd2Err.close(); + } catch (IOException e) { + } + System.err.println("cmd2 terminated."); + exit(); + } + }, "read error cmd2"); + readInput.start(); + readError.start(); + + while (true) { + Thread.sleep(100); + } + } + + private static void exit() { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + } + try { + if (cmd1Process != null) { + cmd1Process.destroy(); + } + } catch (Exception e) { + } + try { + if (cmd2Process != null) { + cmd2Process.destroy(); + } + } catch (Exception e) { + } + System.err.flush(); + System.exit(1); + } + +} diff --git a/tools/wpcapslip/ConnectSocket.java b/tools/wpcapslip/ConnectSocket.java new file mode 100644 index 000000000..417ebac1d --- /dev/null +++ b/tools/wpcapslip/ConnectSocket.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013, Thingsquare, http://www.thingsquare.com/. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + * + */ + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.DataInputStream; +import java.net.Socket; + +public class ConnectSocket { + private static BufferedOutputStream stdoutOutput = null; + private static BufferedOutputStream networkServerOutput = null; + + private static final int BUFSIZE = 512; + + public static void main(String[] args) throws Exception { + if (args.length != 2) { + System.err.println("Usage: " + ConnectSocket.class.getName() + " [server ip] [server port]"); + System.exit(1); + } + + /* Stdin */ + final BufferedInputStream stdinInput = new BufferedInputStream(new DataInputStream(System.in)); + stdoutOutput = new BufferedOutputStream(System.out); + Thread readInput = new Thread(new Runnable() { + public void run() { + int numRead = 0; + byte[] buf = new byte[BUFSIZE]; + try { + while (true) { + numRead = stdinInput.read(buf, 0, BUFSIZE); + if (numRead > 0 && networkServerOutput != null) { + /* System.err.println("1>2 " + numRead); */ + + networkServerOutput.write(buf, 0, numRead); + networkServerOutput.flush(); + } + Thread.sleep(1); + } + } catch (Exception e) { + e.printStackTrace(); + } + exit(); + } + }, "read stdin"); + readInput.start(); + + /* Network server */ + Socket networkServer = new Socket(args[0], Integer.parseInt(args[1])); + final BufferedInputStream networkServerInput = new BufferedInputStream(new DataInputStream(networkServer.getInputStream())); + networkServerOutput = new BufferedOutputStream(networkServer.getOutputStream()); + readInput = new Thread(new Runnable() { + public void run() { + int numRead = 0; + byte[] buf = new byte[BUFSIZE]; + try { + while (true) { + numRead = networkServerInput.read(buf, 0, BUFSIZE); + if (numRead > 0 && stdoutOutput != null) { + /* System.err.println("2>1 " + numRead); */ + stdoutOutput.write(buf, 0, numRead); + stdoutOutput.flush(); + } + Thread.sleep(1); + } + } catch (Exception e) { + e.printStackTrace(); + } + exit(); + } + }, "read network server"); + readInput.start(); + + while (true) { + Thread.sleep(100); + } + } + + private static void exit() { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + } + System.err.flush(); + System.exit(1); + } +} diff --git a/tools/wpcapslip/Makefile b/tools/wpcapslip/Makefile index 1ab2caff2..fb11826eb 100644 --- a/tools/wpcapslip/Makefile +++ b/tools/wpcapslip/Makefile @@ -1,12 +1,21 @@ CONTIKI=../.. -CFLAGS=-Wall -Werror -I$(CONTIKI)/core -I. +CC=gcc +CFLAGS=-Wall -I$(CONTIKI)/core -I. -all: wpcapslip +all: wpcapslip wpcapstdio Connect.class ConnectSocket.class +%.class: %.java + javac $*.java + vpath %.c $(CONTIKI)/core/net wpcapslip: wpcapslip.o wpcap.o tcpdump.o +wpcapstdio: wpcapstdio.o wpcap.o tcpdump.o + %: %.o $(CC) $(LDFLAGS) $^ /lib/w32api/libws2_32.a /lib/w32api/libiphlpapi.a -o $@ + +clean: + rm -f *.class *.exe *.o \ No newline at end of file diff --git a/tools/wpcapslip/net/tcpdump.h b/tools/wpcapslip/net/tcpdump.h new file mode 100644 index 000000000..bfa9fdd3e --- /dev/null +++ b/tools/wpcapslip/net/tcpdump.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ +#ifndef __TCPDUMP_H__ +#define __TCPDUMP_H__ + +#include "net/ip/uip.h" + +int tcpdump_format(uint8_t *packet, uint16_t packetlen, + char *printbuf, uint16_t printbuflen); + +#endif /* __TCPDUMP_H__ */ diff --git a/tools/wpcapslip/tcpdump.c b/tools/wpcapslip/tcpdump.c new file mode 100644 index 000000000..7ecd7c50a --- /dev/null +++ b/tools/wpcapslip/tcpdump.c @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#include "contiki-net.h" + +#include +#include + + struct ip_hdr { + /* IP header. */ + uint8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + uint16_t ipchksum; + uint8_t srcipaddr[4], + destipaddr[4]; + }; + +#define TCP_FIN 0x01 +#define TCP_SYN 0x02 +#define TCP_RST 0x04 +#define TCP_PSH 0x08 +#define TCP_ACK 0x10 +#define TCP_URG 0x20 +#define TCP_CTL 0x3f + +struct tcpip_hdr { + /* IP header. */ + uint8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + uint16_t ipchksum; + uint8_t srcipaddr[4], + destipaddr[4]; + /* TCP header. */ + uint16_t srcport, + destport; + uint8_t seqno[4], + ackno[4], + tcpoffset, + flags, + wnd[2]; + uint16_t tcpchksum; + uint8_t urgp[2]; + uint8_t optdata[4]; +}; + +#define ICMP_ECHO_REPLY 0 +#define ICMP_ECHO 8 + +struct icmpip_hdr { + /* IP header. */ + uint8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + uint16_t ipchksum; + uint8_t srcipaddr[4], + destipaddr[4]; + /* The ICMP and IP headers. */ + /* ICMP (echo) header. */ + uint8_t type, icode; + uint16_t icmpchksum; + uint16_t id, seqno; +}; + + +/* The UDP and IP headers. */ +struct udpip_hdr { + /* IP header. */ + uint8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + uint16_t ipchksum; + uint8_t srcipaddr[4], + destipaddr[4]; + + /* UDP header. */ + uint16_t srcport, + destport; + uint16_t udplen; + uint16_t udpchksum; +}; + +#define ETHBUF ((struct eth_hdr *)&packet[0]) +#define IPBUF ((struct ip_hdr *)&packet[0]) +#define UDPBUF ((struct udpip_hdr *)&packet[0]) +#define ICMPBUF ((struct icmpip_hdr *)&packet[0]) +#define TCPBUF ((struct tcpip_hdr *)&packet[0]) + + +/*---------------------------------------------------------------------------*/ +static void +tcpflags(unsigned char flags, char *flagsstr) +{ + if(flags & TCP_FIN) { + *flagsstr++ = 'F'; + } + if(flags & TCP_SYN) { + *flagsstr++ = 'S'; + } + if(flags & TCP_RST) { + *flagsstr++ = 'R'; + } + if(flags & TCP_ACK) { + *flagsstr++ = 'A'; + } + if(flags & TCP_URG) { + *flagsstr++ = 'U'; + } + + *flagsstr = 0; +} +/*---------------------------------------------------------------------------*/ +static char * +n(uint16_t num, char *ptr) +{ + uint16_t d; + uint8_t a, f; + + if(num == 0) { + *ptr = '0'; + return ptr + 1; + } else { + f = 0; + for(d = 10000; d >= 1; d /= 10) { + a = (num / d) % 10; + if(f == 1 || a > 0) { + *ptr = a + '0'; + ++ptr; + f = 1; + } + } + } + return ptr; +} +/*---------------------------------------------------------------------------*/ +static char * +d(char *ptr) +{ + *ptr = '.'; + return ptr + 1; +} +/*---------------------------------------------------------------------------*/ +static char * +s(char *str, char *ptr) +{ + strcpy(ptr, str); + return ptr + strlen(str); +} +/*---------------------------------------------------------------------------*/ +int +tcpdump_format(uint8_t *packet, uint16_t packetlen, + char *buf, uint16_t buflen) +{ + char flags[8]; + if(IPBUF->proto == UIP_PROTO_ICMP) { + if(ICMPBUF->type == ICMP_ECHO) { + return s(" ping", + n(IPBUF->destipaddr[3], d( + n(IPBUF->destipaddr[2], d( + n(IPBUF->destipaddr[1], d( + n(IPBUF->destipaddr[0], + s(" ", + n(IPBUF->srcipaddr[3], d( + n(IPBUF->srcipaddr[2], d( + n(IPBUF->srcipaddr[1], d( + n(IPBUF->srcipaddr[0], + buf)))))))))))))))) - buf; + + /* return sprintf(buf, "%d.%d.%d.%d %d.%d.%d.%d ping", + IPBUF->srcipaddr[0], IPBUF->srcipaddr[1], + IPBUF->srcipaddr[2], IPBUF->srcipaddr[3], + IPBUF->destipaddr[0], IPBUF->destipaddr[1], + IPBUF->destipaddr[2], IPBUF->destipaddr[3]);*/ + } else if(ICMPBUF->type == ICMP_ECHO_REPLY) { + return s(" pong", + n(IPBUF->destipaddr[3], d( + n(IPBUF->destipaddr[2], d( + n(IPBUF->destipaddr[1], d( + n(IPBUF->destipaddr[0], + s(" ", + n(IPBUF->srcipaddr[3], d( + n(IPBUF->srcipaddr[2], d( + n(IPBUF->srcipaddr[1], d( + n(IPBUF->srcipaddr[0], + buf)))))))))))))))) - buf; + /* return sprintf(buf, "%d.%d.%d.%d %d.%d.%d.%d pong", + IPBUF->srcipaddr[0], IPBUF->srcipaddr[1], + IPBUF->srcipaddr[2], IPBUF->srcipaddr[3], + IPBUF->destipaddr[0], IPBUF->destipaddr[1], + IPBUF->destipaddr[2], IPBUF->destipaddr[3]);*/ + } + } else if(IPBUF->proto == UIP_PROTO_UDP) { + return s(" UDP", + n(uip_htons(UDPBUF->destport), d( + n(IPBUF->destipaddr[3], d( + n(IPBUF->destipaddr[2], d( + n(IPBUF->destipaddr[1], d( + n(IPBUF->destipaddr[0], + s(" ", + n(uip_htons(UDPBUF->srcport), d( + n(IPBUF->srcipaddr[3], d( + n(IPBUF->srcipaddr[2], d( + n(IPBUF->srcipaddr[1], d( + n(IPBUF->srcipaddr[0], + buf)))))))))))))))))))) - buf; + /* return sprintf(buf, "%d.%d.%d.%d.%d %d.%d.%d.%d.%d UDP", + IPBUF->srcipaddr[0], IPBUF->srcipaddr[1], + IPBUF->srcipaddr[2], IPBUF->srcipaddr[3], + uip_htons(UDPBUF->srcport), + IPBUF->destipaddr[0], IPBUF->destipaddr[1], + IPBUF->destipaddr[2], IPBUF->destipaddr[3], + uip_htons(UDPBUF->destport));*/ + } else if(IPBUF->proto == UIP_PROTO_TCP) { + tcpflags(TCPBUF->flags, flags); + return s(flags, + s(" ", + n(uip_htons(TCPBUF->destport), d( + n(IPBUF->destipaddr[3], d( + n(IPBUF->destipaddr[2], d( + n(IPBUF->destipaddr[1], d( + n(IPBUF->destipaddr[0], + s(" ", + n(uip_htons(TCPBUF->srcport), d( + n(IPBUF->srcipaddr[3], d( + n(IPBUF->srcipaddr[2], d( + n(IPBUF->srcipaddr[1], d( + n(IPBUF->srcipaddr[0], + buf))))))))))))))))))))) - buf; + /* return sprintf(buf, "%d.%d.%d.%d.%d %d.%d.%d.%d.%d %s", + IPBUF->srcipaddr[0], IPBUF->srcipaddr[1], + IPBUF->srcipaddr[2], IPBUF->srcipaddr[3], + uip_htons(TCPBUF->srcport), + IPBUF->destipaddr[0], IPBUF->destipaddr[1], + IPBUF->destipaddr[2], IPBUF->destipaddr[3], + uip_htons(TCPBUF->destport), + flags); */ + } else { + strcpy(buf, "Unrecognized protocol"); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ diff --git a/tools/wpcapslip/wpcap.c b/tools/wpcapslip/wpcap.c index 5584557a9..b8127d47c 100644 --- a/tools/wpcapslip/wpcap.c +++ b/tools/wpcapslip/wpcap.c @@ -58,7 +58,6 @@ #include #include -#include #include #include #include @@ -69,7 +68,7 @@ #define PROGRESS(x) -static void raw_send(void *buf, int len); +void raw_send(void *buf, int len); struct pcap; @@ -150,7 +149,7 @@ struct arp_entry { struct uip_eth_addr ethaddr; uint8_t time; }; -static struct uip_eth_addr uip_lladdr = {{0,0,0,0,0,0}}; +struct uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}}; static const uip_ipaddr_t all_zeroes_addr = { { 0x0, /* rest is 0 */ } }; static const struct uip_eth_addr broadcast_ethaddr = {{0xff,0xff,0xff,0xff,0xff,0xff}}; @@ -164,18 +163,20 @@ static int arptime; static int logging; +uip_lladdr_t uip_lladdr; + static void log_message(char *msg1, char *msg2) { if(logging) { - printf("Log: %s %s\n", msg1, msg2); + fprintf(stderr, "Log: %s %s\n", msg1, msg2); } } /*---------------------------------------------------------------------------*/ static void error_exit(char *msg1) { - printf("error_exit: %s", msg1); + fprintf(stderr, "error_exit: %s", msg1); exit(EXIT_FAILURE); } /*---------------------------------------------------------------------------*/ @@ -198,11 +199,11 @@ init_pcap(struct in_addr addr) paddr != NULL; paddr = paddr->next) { if(paddr->addr != NULL && paddr->addr->sa_family == AF_INET) { - + struct in_addr interface_addr; interface_addr = ((struct sockaddr_in *)paddr->addr)->sin_addr; log_message("init_pcap: with address: ", inet_ntoa(interface_addr)); - + if(interface_addr.s_addr == addr.s_addr) { pcap = pcap_open_live(interfaces->name, BUFSIZE, 0, -1, error); if(pcap == NULL) { @@ -263,7 +264,7 @@ set_ethaddr(struct in_addr addr) log_message("set_ethaddr: with address: ", inet_ntoa(adapter_addr)); if(adapter_addr.s_addr == addr.s_addr) { - printf("Using local network interface with address %s\n", + fprintf(stderr, "Using local network interface with address %s\n", inet_ntoa(adapter_addr)); if(adapters->PhysicalAddressLength != 6) { error_exit("ip addr specified on cmdline does not belong to an ethernet card\n"); @@ -292,12 +293,12 @@ print_packet(unsigned char *buf, int len) int i; for(i = 0; i < len; ++i) { - printf("0x%02x, ", buf[i]); + fprintf(stderr, "0x%02x, ", buf[i]); if(i % 8 == 7) { - printf("\n"); + fprintf(stderr, "\n"); } } - printf("\n\n"); + fprintf(stderr, "\n\n"); } /*---------------------------------------------------------------------------*/ static void @@ -305,7 +306,7 @@ uip_arp_update(uip_ipaddr_t *ipaddr, struct uip_eth_addr *ethaddr) { struct arp_entry *tabptr; int i, tmpage, c; - + /* Walk through the ARP mapping table and try to find an entry to update. If none is found, the IP -> MAC address mapping is inserted in the ARP table. */ @@ -318,7 +319,7 @@ uip_arp_update(uip_ipaddr_t *ipaddr, struct uip_eth_addr *ethaddr) /* Check if the source IP address of the incoming packet matches the IP address in this ARP table entry. */ if(uip_ipaddr_cmp(ipaddr, &tabptr->ipaddr)) { - + /* An old entry found, update this and return. */ memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); tabptr->time = arptime; @@ -399,7 +400,7 @@ arp_out(struct ethip_hdr *iphdr, int len) int i; #endif -#if 1 +#if 0 /* Find the destination IP address in the ARP table and construct the Ethernet header. If the destination IP addres isn't on the local network, we use the default router's IP address instead. @@ -425,7 +426,7 @@ arp_out(struct ethip_hdr *iphdr, int len) /* Else, we use the destination IP address. */ uip_ipaddr_copy(&ipaddr, &iphdr->destipaddr); } - + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { tabptr = &arp_table[i]; if(uip_ipaddr_cmp(&ipaddr, &tabptr->ipaddr)) { @@ -439,9 +440,9 @@ arp_out(struct ethip_hdr *iphdr, int len) memset(arphdr->ethhdr.dest.addr, 0xff, 6); memset(arphdr->dhwaddr.addr, 0x00, 6); - memcpy(arphdr->ethhdr.src.addr, uip_lladdr.addr, 6); - memcpy(arphdr->shwaddr.addr, uip_lladdr.addr, 6); - + memcpy(arphdr->ethhdr.src.addr, uip_ethaddr.addr, 6); + memcpy(arphdr->shwaddr.addr, uip_ethaddr.addr, 6); + uip_ipaddr_copy(&arphdr->dipaddr, &ipaddr); uip_ipaddr_copy(&arphdr->sipaddr, &netaddr); arphdr->opcode = UIP_HTONS(ARP_REQUEST); /* ARP request. */ @@ -476,27 +477,27 @@ do_arp(void *buf, int len) if(hdr->ethhdr.type == UIP_HTONS(UIP_ETHTYPE_ARP)) { if(hdr->opcode == UIP_HTONS(ARP_REQUEST)) { /* Check if the ARP is for our network */ - /* printf("ARP for %d.%d.%d.%d we are %d.%d.%d.%d/%d.%d.%d.%d\n", + /* fprintf(stderr, "ARP for %d.%d.%d.%d we are %d.%d.%d.%d/%d.%d.%d.%d\n", uip_ipaddr_to_quad(&hdr->dipaddr), uip_ipaddr_to_quad(&netaddr), uip_ipaddr_to_quad(&netmask));*/ if(uip_ipaddr_maskcmp(&hdr->dipaddr, &netaddr, &netmask)) { uip_ipaddr_t tmpaddr; - - /* printf("ARP for us.\n");*/ + + /* fprintf(stderr, "ARP for us.\n");*/ uip_arp_update(&hdr->sipaddr, &hdr->shwaddr); - + hdr->opcode = UIP_HTONS(ARP_REPLY); - + memcpy(&hdr->dhwaddr.addr, &hdr->shwaddr.addr, 6); memcpy(&hdr->shwaddr.addr, &uip_lladdr.addr, 6); memcpy(&hdr->ethhdr.src.addr, &uip_lladdr.addr, 6); memcpy(&hdr->ethhdr.dest.addr, &hdr->dhwaddr.addr, 6); - + uip_ipaddr_copy(&tmpaddr, &hdr->dipaddr); uip_ipaddr_copy(&hdr->dipaddr, &hdr->sipaddr); uip_ipaddr_copy(&hdr->sipaddr, &tmpaddr); - + hdr->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_ARP); raw_send(hdr, sizeof(struct arp_hdr)); return NULL; @@ -521,8 +522,8 @@ cleanup(void) char buf[1024]; snprintf(buf, sizeof(buf), "route delete %d.%d.%d.%d", - uip_ipaddr_to_quad(&ifaddr)); - printf("%s\n", buf); + uip_ipaddr_to_quad(&netaddr)); + fprintf(stderr, "%s\n", buf); system(buf); } @@ -540,9 +541,9 @@ wpcap_start(char *ethcardaddr, char *slipnetaddr, char *slipnetmask, int log) struct in_addr addr; char buf[4000]; uint32_t tmpaddr; - + logging = log; - + addr.s_addr = inet_addr(ethcardaddr); tmpaddr = inet_addr(ethcardaddr); memcpy(&ifaddr.u16[0], &tmpaddr, sizeof(tmpaddr)); @@ -551,21 +552,21 @@ wpcap_start(char *ethcardaddr, char *slipnetaddr, char *slipnetmask, int log) tmpaddr = inet_addr(slipnetmask); memcpy(&netmask.u16[0], &tmpaddr, sizeof(tmpaddr)); - printf("Network address %d.%d.%d.%d/%d.%d.%d.%d\n", + fprintf(stderr, "Network address %d.%d.%d.%d/%d.%d.%d.%d\n", uip_ipaddr_to_quad(&netaddr), uip_ipaddr_to_quad(&netmask)); - + snprintf(buf, sizeof(buf), "route add %d.%d.%d.%d mask %d.%d.%d.%d %d.%d.%d.%d", uip_ipaddr_to_quad(&netaddr), uip_ipaddr_to_quad(&netmask), uip_ipaddr_to_quad(&ifaddr)); - printf("%s\n", buf); + fprintf(stderr, "%s\n", buf); system(buf); signal(SIGTERM, remove_route); log_message("wpcap_init: cmdline address: ", inet_ntoa(addr)); - + wpcap = LoadLibrary("wpcap.dll"); pcap_findalldevs = (int (*)(struct pcap_if **, char *)) GetProcAddress(wpcap, "pcap_findalldevs"); @@ -588,12 +589,12 @@ wpcap_start(char *ethcardaddr, char *slipnetaddr, char *slipnetmask, int log) #if 0 while(1) { int ret; - + ret = wpcap_poll(buf); if(ret > 0) { /* print_packet(buf, ret);*/ if(do_arp(buf, ret)) { - printf("IP packet\n"); + fprintf(stderr, "IP packet\n"); } } sleep(1); @@ -602,17 +603,16 @@ wpcap_start(char *ethcardaddr, char *slipnetaddr, char *slipnetmask, int log) } /*---------------------------------------------------------------------------*/ uint16_t -wpcap_poll(char **buf) +wpcap_poll(char **buf, int eth) { struct pcap_pkthdr *packet_header; unsigned char *packet; int len; + int ret; char *buf2; - switch(pcap_next_ex(pcap, &packet_header, &packet)) { - case -1: - error_exit("error on poll\n"); - case 0: + ret = pcap_next_ex(pcap, &packet_header, &packet); + if (ret != 1) { return 0; } @@ -622,13 +622,20 @@ wpcap_poll(char **buf) CopyMemory(*buf, packet, packet_header->caplen); len = packet_header->caplen; - /* printf("len %d\n", len);*/ + + if(eth) { + /* poll requested us to return the raw ethernet packet */ + return len; + } + + buf2 = do_arp(*buf, len); if(buf2 == NULL) { return 0; } else { len = len - (buf2 - *buf); *buf = buf2; + /*fprintf(stderr, "wpcap_poll() %d\n", len);*/ return len; } } @@ -644,7 +651,7 @@ wpcap_send(void *buf, int len) raw_send(buf2, len); } /*---------------------------------------------------------------------------*/ -static void +void raw_send(void *buf, int len) { /* printf("sending len %d\n", len);*/ diff --git a/tools/wpcapslip/wpcapslip.c b/tools/wpcapslip/wpcapslip.c index e6e193f90..b60af7f6a 100644 --- a/tools/wpcapslip/wpcapslip.c +++ b/tools/wpcapslip/wpcapslip.c @@ -47,8 +47,6 @@ #include #include #include -#include -#include #include #include @@ -75,6 +73,18 @@ static int should_print = 0; #define IP_HLEN 20 +/*---------------------------------------------------------------------------*/ +uint16_t +uip_htons(uint16_t val) +{ + return UIP_HTONS(val); +} +/*---------------------------------------------------------------------------*/ +uint32_t +uip_htonl(uint32_t val) +{ + return UIP_HTONL(val); +} /*---------------------------------------------------------------------------*/ static void print_packet(uint8_t *packet, int len) @@ -289,8 +299,9 @@ serial_to_wpcap(FILE *inslip) */ #define DEBUG_LINE_MARKER '\r' int ecode; + ecode = check_ip(&uip.iphdr, inbufptr); - if(ecode < 0 && inbufptr == 8 && strncmp(uip.inbuf, "=IPA", 4) == 0) { + if(ecode < 0 && inbufptr == 8 && strncmp((const char*)uip.inbuf, "=IPA", 4) == 0) { static struct in_addr ipa; inbufptr = 0; @@ -902,7 +913,7 @@ main(int argc, char **argv) if(iphdr->ip_id != last_id) { last_id = iphdr->ip_id; /* printf("------ wpcap_poll ret %d\n", ret);*/ - print_packet(pbuf, ret); + print_packet((uint8_t*)pbuf, ret); write_to_serial(slipfd, pbuf, ret); slip_flushbuf(slipfd); sigalarm_reset(); diff --git a/tools/wpcapslip/wpcapstdio.c b/tools/wpcapslip/wpcapstdio.c new file mode 100644 index 000000000..287ab07a0 --- /dev/null +++ b/tools/wpcapslip/wpcapstdio.c @@ -0,0 +1,597 @@ +/* + * Copyright (c) 2012, Thingsquare, www.thingsquare.com. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * Author: Fredrik Osterlind + * Based on wpcapslip.c by : Oliver Schmidt + */ + +/* This is a stripped-down version of wpcapslip: Instead of reading from and writing + * to a serial port, this program just reads and writes to stdin/stdout. To + * achieve the same functionality as wpcapslip, this program can hence be connected + * to serialdump. But, in contrast to wpcapslip, this program can easily be connected + * to networked or simulated serial ports. -- Fredrik, 2012 */ + +#include +#include +#include +#ifdef __CYGWIN__ +#include +#else /* __CYGWIN__ */ +#include +#endif /* __CYGWIN__ */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#define PROGRESS(x) + +void wpcap_start(char *ethifaddr, char *netaddr, char *netmask, int logging); + +void wpcap_send(void *buf, int len); +void raw_send(void *buf, int len); + +uint16_t wpcap_poll(char **buf, int eth); + +#include "net/tcpdump.h" +static int should_print = 0; + +static int send_eth = 0; /* Sends ethernet frames or IP packets */ + +#define IP_HLEN 20 + +/*---------------------------------------------------------------------------*/ +uint16_t +uip_htons(uint16_t val) +{ + return UIP_HTONS(val); +} +/*---------------------------------------------------------------------------*/ +uint32_t +uip_htonl(uint32_t val) +{ + return UIP_HTONL(val); +} +/*---------------------------------------------------------------------------*/ +static void +print_packet(char* prefix, uint8_t *packet, int len) +{ + char buf[2000]; + if(should_print) { + tcpdump_format(packet, len, buf, sizeof(buf)); + fprintf(stderr, "%s: %s\n", prefix, buf); + } +} +/*---------------------------------------------------------------------------*/ +void cleanup(void); +/*---------------------------------------------------------------------------*/ +void +sigcleanup(int signo) +{ + fprintf(stderr, "signal %d\n", signo); + exit(0); /* exit(0) will call cleanup() */ +} +/*---------------------------------------------------------------------------*/ +#define SLIP_END 0300 +#define SLIP_ESC 0333 +#define SLIP_ESC_END 0334 +#define SLIP_ESC_ESC 0335 + +struct ip { + u_int8_t ip_vhl; /* version and header length */ +#define IP_V4 0x40 +#define IP_V 0xf0 +#define IP_HL 0x0f + u_int8_t ip_tos; /* type of service */ + u_int16_t ip_len; /* total length */ + u_int16_t ip_id; /* identification */ + u_int16_t ip_off; /* fragment offset field */ +#define IP_RF 0x8000 /* reserved fragment flag */ +#define IP_DF 0x4000 /* dont fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ +#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ + u_int8_t ip_ttl; /* time to live */ + u_int8_t ip_p; /* protocol */ + u_int16_t ip_sum; /* checksum */ + u_int32_t ip_src, ip_dst; /* source and dest address */ + u_int16_t uh_sport; /* source port */ + u_int16_t uh_dport; /* destination port */ + u_int16_t uh_ulen; /* udp length */ + u_int16_t uh_sum; /* udp checksum */ +}; + +static int ip_id, last_id; + +int +ssystem(const char *fmt, ...) __attribute__((__format__ (__printf__, 1, 2))); + +int +ssystem(const char *fmt, ...) +{ + char cmd[128]; + va_list ap; + va_start(ap, fmt); + vsnprintf(cmd, sizeof(cmd), fmt, ap); + va_end(ap); + fprintf(stderr, "%s\n", cmd); + fflush(stderr); + return system(cmd); +} +/*---------------------------------------------------------------------------*/ +int +is_sensible_string(const unsigned char *s, int len) +{ + int i; + for(i = 1; i < len; i++) { + if(s[i] == 0 || s[i] == '\r' || s[i] == '\n' || s[i] == '\t') { + continue; + } else if(s[i] < ' ' || '~' < s[i]) { + return 0; + } + } + return 1; +} +/*---------------------------------------------------------------------------*/ +u_int16_t +ip4sum(u_int16_t sum, const void *_p, u_int16_t len) +{ + u_int16_t t; + const u_int8_t *p = _p; + const u_int8_t *end = p + len; + + while(p < (end - 1)) { + t = (p[0] << 8) + p[1]; + sum += t; + if(sum < t) + sum++; + p += 2; + } + if(p < end) { + t = (p[0] << 8) + 0; + sum += t; + if(sum < t) + sum++; + } + return sum; +} +/*---------------------------------------------------------------------------*/ +static uint16_t +chksum(const void *p, uint16_t len) +{ + uint16_t sum = ip4sum(0, p, len); + return (sum == 0) ? 0xffff : uip_htons(sum); +} +/*---------------------------------------------------------------------------*/ +int +check_ip(const struct ip *ip, unsigned ip_len) +{ + u_int16_t sum, ip_hl; + + if(send_eth) { + return 0; + } + + /* Check IP version and length. */ + if((ip->ip_vhl & IP_V) != IP_V4) { + return -1; + } + + if(uip_ntohs(ip->ip_len) > ip_len) { + return -2; + } + + if(uip_ntohs(ip->ip_len) < ip_len) { + return -3; + } + + /* Check IP header. */ + ip_hl = 4 * (ip->ip_vhl & IP_HL); + sum = ip4sum(0, ip, ip_hl); + if(sum != 0xffff && sum != 0x0) { + return -4; + } + + if(ip->ip_p == 6 || ip->ip_p == 17) { /* Check TCP or UDP header. */ + u_int16_t tcp_len = ip_len - ip_hl; + + /* Sum pseudoheader. */ + sum = ip->ip_p + tcp_len; /* proto and len, no carry */ + sum = ip4sum(sum, &ip->ip_src, 8); /* src and dst */ + + /* Sum TCP/UDP header and data. */ + sum = ip4sum(sum, (u_int8_t*)ip + ip_hl, tcp_len); + + /* Failed checksum test? */ + if(sum != 0xffff && sum != 0x0) { + if(ip->ip_p == 6) { /* TCP == 6 */ + return -5; + } else { /* UDP */ + /* Deal with disabled UDP checksums. */ + if(ip->uh_sum != 0) { + return -6; + } + } + } + } else if(ip->ip_p == 1) { /* ICMP */ + u_int16_t icmp_len = ip_len - ip_hl; + + sum = ip4sum(0, (u_int8_t*)ip + ip_hl, icmp_len); + if(sum != 0xffff && sum != 0x0) { + return -7; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +/* + * Read a single character from stdin. When we have a full packet, write it to + * the network interface. + */ +void +serial_to_wpcap(void) +{ + static union { + unsigned char inbuf[2000]; + struct ip iphdr; + } uip; + static int inbufptr = 0; + + int ret; + unsigned char c; + + if(inbufptr >= sizeof(uip.inbuf)) { + inbufptr = 0; + return; + } + ret = read(STDIN_FILENO, &c, 1); + + if(ret <= 0) { + err(1, "serial_to_wpcap: read"); + inbufptr = 0; + return; + } + + switch (c) { + case SLIP_END: + if(inbufptr > 0) { + /* + * Sanity checks. + */ +#define DEBUG_LINE_MARKER '\r' + int ecode; + + ecode = check_ip(&uip.iphdr, inbufptr); + if(ecode < 0 && inbufptr == 8 + && strncmp((const char*)uip.inbuf, "=IPA", 4) == 0) { + static struct in_addr ipa; + + inbufptr = 0; + if(memcmp(&ipa, &uip.inbuf[4], sizeof(ipa)) == 0) { + break; + } + + memcpy(&ipa, &uip.inbuf[4], sizeof(ipa)); + break; + } else if(ecode < 0) { + /* + * If sensible ASCII string, print it as debug info! + */ + /* printf("----------------------------------\n");*/ + if(uip.inbuf[0] == DEBUG_LINE_MARKER) { + fwrite(uip.inbuf + 1, inbufptr - 1, 1, stderr); + } else if(is_sensible_string(uip.inbuf, inbufptr)) { + fwrite(uip.inbuf, inbufptr, 1, stderr); + } else { + fprintf(stderr, "serial_to_wpcap: drop packet len=%d ecode=%d\n", + inbufptr, ecode); + } + inbufptr = 0; + break; + } + PROGRESS("s"); + + if(send_eth) { + raw_send(uip.inbuf, inbufptr); + } else { + /* printf("Sending to wpcap\n");*/ + if(uip.iphdr.ip_id != last_id) { + last_id = uip.iphdr.ip_id; + print_packet("to wpcap: ", uip.inbuf, inbufptr); + wpcap_send(uip.inbuf, inbufptr); + } else { + /*print_packet("IGNORED to wpcap: ", uip.inbuf, inbufptr);*/ + } + } + /* printf("After sending to wpcap\n");*/ + inbufptr = 0; + } + break; + + case SLIP_ESC: + /* TODO We do not actually check that we have another byte incoming, so + * we may block here */ + read(STDIN_FILENO, &c, 1); + + switch (c) { + case SLIP_ESC_END: + c = SLIP_END; + break; + case SLIP_ESC_ESC: + c = SLIP_ESC; + break; + } + + /* FALLTHROUGH */ + default: + uip.inbuf[inbufptr++] = c; + break; + } +} +/*---------------------------------------------------------------------------*/ +unsigned char stdout_buf[2000]; +int stdout_buf_cnt; +/*---------------------------------------------------------------------------*/ +void +stdout_write(unsigned char c) +{ + if(stdout_buf_cnt >= sizeof(stdout_buf)) { + err(1, "stdout_write overflow"); + } + stdout_buf[stdout_buf_cnt] = c; + stdout_buf_cnt++; +} +/*---------------------------------------------------------------------------*/ +int +stdout_buf_empty(void) +{ + return stdout_buf_cnt == 0; +} +/*---------------------------------------------------------------------------*/ +void +stdout_flushbuf(void) +{ + if(stdout_buf_empty()) { + return; + } + + fwrite(stdout_buf, stdout_buf_cnt, 1, stdout); + stdout_buf_cnt = 0; + fflush(stdout); +} +/*---------------------------------------------------------------------------*/ +void +write_slip_stdout(void *inbuf, int len) +{ + u_int8_t *p = inbuf; + int i, ecode; + struct ip *iphdr = inbuf; + + if(!send_eth) { + /* + * Sanity checks. + */ + /*fprintf(stderr, "write_slip_stdout: %d\n", len);*/ + ecode = check_ip(inbuf, len); + if(ecode < 0) { + fprintf(stderr, "write_slip_stdout: drop packet %d\n", ecode); + return; + } + + if(iphdr->ip_id == 0 && iphdr->ip_off & IP_DF) { + uint16_t nid = uip_htons(ip_id++); + iphdr->ip_id = nid; + nid = ~nid; /* negate */ + iphdr->ip_sum += nid; /* add */ + if(iphdr->ip_sum < nid) { /* 1-complement overflow? */ + iphdr->ip_sum++; + } + ecode = check_ip(inbuf, len); + if(ecode < 0) { + fprintf(stderr, "write_slip_stdout: drop packet %d\n", ecode); + return; + } + } + + iphdr->ip_ttl = uip_htons(uip_htons(iphdr->ip_ttl) + 1); + if(iphdr->ip_ttl == 0) { + fprintf(stderr, "Packet with ttl %d dropped\n", iphdr->ip_ttl); + return; + } + iphdr->ip_sum = 0; + iphdr->ip_sum = ~chksum(iphdr, 4 * (iphdr->ip_vhl & IP_HL)); + ecode = check_ip(inbuf, len); + if(ecode < 0) { + fprintf(stderr, "write_slip_stdout: drop packet %d\n", ecode); + return; + } + } + + for(i = 0; i < len; i++) { + switch (p[i]) { + case SLIP_END: + stdout_write(SLIP_ESC); + stdout_write(SLIP_ESC_END); + break; + case SLIP_ESC: + stdout_write(SLIP_ESC); + stdout_write(SLIP_ESC_ESC); + break; + default: + stdout_write(p[i]); + break; + } + } + stdout_write(SLIP_END); + /* printf("slip end\n");*/ + PROGRESS("t"); +} +/*---------------------------------------------------------------------------*/ +/*const char *ipaddr;*/ +/*const char *netmask;*/ +static int got_sigalarm; +void +sigalarm(int signo) +{ + got_sigalarm = 1; + return; +} +/*---------------------------------------------------------------------------*/ +void +sigalarm_reset(void) +{ +#ifdef linux +#define TIMEOUT (997*1000) +#else +#define TIMEOUT (2451*1000) +#endif + ualarm(TIMEOUT, TIMEOUT); + got_sigalarm = 0; +} +/*---------------------------------------------------------------------------*/ +int +main(int argc, char **argv) +{ + int c; + int ret; + char buf[4000]; + int logging = 0; + + ip_id = getpid() * time(NULL); + + while((c = getopt(argc, argv, "E:D:hl:t:T")) != -1) { + switch (c) { + case 'E': + send_eth = 1; + break; + + case 'T': + should_print = 1; + break; + + case 'l': + logging = 1; + break; + + case '?': + case 'h': + default: + err(1, + "usage: wpcapstdio [-E] [-l] [-T] "); + break; + } + } + argc -= (optind - 1); + argv += (optind - 1); + + if(argc != 4) { + err(1, "usage: wpcapstdio [-E] [-T] "); + } + + wpcap_start(argv[1], argv[2], argv[3], logging); + stdout_write(SLIP_END); + + atexit(cleanup); + signal(SIGHUP, sigcleanup); + signal(SIGTERM, sigcleanup); + signal(SIGINT, sigcleanup); + signal(SIGALRM, sigalarm); + + while(1) { + if(got_sigalarm) { + /* Send "?IPA". */ + stdout_write('?'); + stdout_write('I'); + stdout_write('P'); + stdout_write('A'); + stdout_write(SLIP_END); + got_sigalarm = 0; + } + + if(stdout_buf_empty()) { + char *pbuf = buf; + + ret = wpcap_poll(&pbuf, send_eth); + if(ret > 0) { + if(send_eth) { + write_slip_stdout(pbuf, ret); + stdout_flushbuf(); + } else { + struct ip *iphdr = (struct ip *)pbuf; + if(iphdr->ip_id != last_id) { + /*last_id = iphdr->ip_id;*/ + print_packet("to stdout: ", (uint8_t*)pbuf, ret); + write_slip_stdout(pbuf, ret); + stdout_flushbuf(); + } else { + /*print_packet("IGNORED to stdout: ", (uint8_t*)pbuf, ret);*/ + } + } + } + } + + if(!stdout_buf_empty()) { + stdout_flushbuf(); + } + + { + fd_set s_rd; + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = 100; + + do { + FD_ZERO(&s_rd); + FD_SET(fileno(stdin), &s_rd); + select(fileno(stdin) + 1, &s_rd, NULL, NULL, &tv); + if(FD_ISSET(fileno(stdin), &s_rd)) { + serial_to_wpcap(); + } + } while(FD_ISSET(fileno(stdin), &s_rd)); + } + } +} +/*---------------------------------------------------------------------------*/ diff --git a/tools/zolertia/license-bsl.txt b/tools/zolertia/license-bsl.txt new file mode 100644 index 000000000..e6775e9d7 --- /dev/null +++ b/tools/zolertia/license-bsl.txt @@ -0,0 +1,62 @@ +Copyright (c) 2001-2003 Chris Liechti + +All Rights Reserved. + +This is the Python license. In short, you can use this product in +commercial and non-commercial applications, modify it, redistribute it. +A notification to the author when you use and/or modify it is welcome. + +TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING THIS SOFTWARE +============================================ + +LICENSE AGREEMENT +----------------- + +1. This LICENSE AGREEMENT is between the copyright holder of this +product, and the Individual or Organization ("Licensee") accessing +and otherwise using this product in source or binary form and its +associated documentation. + +2. Subject to the terms and conditions of this License Agreement, +the copyright holder hereby grants Licensee a nonexclusive, +royalty-free, world-wide license to reproduce, analyze, test, +perform and/or display publicly, prepare derivative works, distribute, +and otherwise use this product alone or in any derivative version, +provided, however, that copyright holders License Agreement and +copyright holders notice of copyright are retained in this product +alone or in any derivative version prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates this product or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to this product. + +4. The copyright holder is making this product available to Licensee +on an "AS IS" basis. THE COPYRIGHT HOLDER MAKES NO REPRESENTATIONS +OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT +LIMITATION, THE COPYRIGHT HOLDER MAKES NO AND DISCLAIMS ANY +REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR +ANY PARTICULAR PURPOSE OR THAT THE USE OF THIS PRODUCT WILL +NOT INFRINGE ANY THIRD PARTY RIGHTS. + +5. THE COPYRIGHT HOLDER SHALL NOT BE LIABLE TO LICENSEE OR ANY +OTHER USERS OF THIS PRODUCT FOR ANY INCIDENTAL, SPECIAL, OR +CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, +DISTRIBUTING, OR OTHERWISE USING THIS PRODUCT, OR ANY +DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY +THEREOF. + +6. This License Agreement will automatically terminate upon a +material breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between the +copyright holder and Licensee. This License Agreement does not grant +permission to use trademarks or trade names from the copyright holder +in a trademark sense to endorse or promote products or services of +Licensee, or any third party. + +8. By copying, installing or otherwise using this product, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. diff --git a/tools/z1/motelist-z1 b/tools/zolertia/motelist-zolertia similarity index 84% rename from tools/z1/motelist-z1 rename to tools/zolertia/motelist-zolertia index fe71148da..e286887ac 100755 --- a/tools/z1/motelist-z1 +++ b/tools/zolertia/motelist-zolertia @@ -17,11 +17,13 @@ options: -m method to scan usb: procfs, sysfs, auto (default) -dev_prefix force the device prefix for the serial device -usb display extra usb information + -b specify which Zolertia board to list (z1, remote, etc) EOF my %Opt = ( compact => 0, usb => 0, + board => "", method => "auto", kernel => "auto", dev_prefix => [ "/dev/usb/tts/", "/dev/ttyUSB", "/dev/tts/USB" ], @@ -38,6 +40,7 @@ while (@ARGV) { elsif( $opt eq "-m" ) { $Opt{method} = shift @ARGV; } elsif( $opt eq "-dev_prefix" ) { $Opt{dev_prefix} = shift @ARGV; } elsif( $opt eq "-usb" ) { $Opt{usb} = 1; } + elsif( $opt eq "-b" ) { $Opt{board} = shift @ARGV; } else { print STDERR "$help\nerror, unknown command line option $opt\n"; exit 1; } } @@ -50,6 +53,12 @@ if( $Opt{method} eq "auto" ) { $Opt{method} = ($Opt{kernel} eq "2.4") ? "procfs" : "sysfs"; } +if( $Opt{board} eq "z1" ) { + $Opt{board} = "Zolertia Z1"; +} elsif( $Opt{board} eq "remote" ) { + $Opt{board} = "Zolertia RE-Mote platform"; +} + my @devs = $Opt{method} eq "procfs" ? scan_procfs() : scan_sysfs(); print_motelist( sort { cmp_usbdev($a,$b) } @devs ); @@ -59,24 +68,29 @@ print_motelist( sort { cmp_usbdev($a,$b) } @devs ); # sub scan_sysfs { - # Scan /sys/bus/usb/drivers/usb for FTDI devices - my @ftdidevs = - grep { ($_->{UsbVendor}||"") eq "10c4" && ($_->{UsbProduct}||"") eq "ea60" && ($_->{ProductString}||"") eq "Zolertia Z1" } + my $tmp = '($_->{UsbVendor}||"") eq "10c4" && ($_->{UsbProduct}||"") eq "ea60"'; + + if($Opt{board}) { + $tmp = '($_->{ProductString}||"") eq $Opt{board} && ' . $tmp + } + + # Scan /sys/bus/usb/drivers/usb for CP210x devices + my @cpdevs = + grep { eval "$tmp" } map { { SysPath => $_, UsbVendor => snarf("$_/idVendor",1), UsbProduct => snarf("$_/idProduct",1), ProductString => snarf("$_/product",1), } } - glob("/sys/bus/usb/drivers/usb/*"); + glob("/sys/bus/usb/drivers/usb/*"); - # Gather information about each FTDI device - for my $f (@ftdidevs) { + # Gather information about each CP210x device + for my $f (@cpdevs) { my $syspath = $f->{SysPath}; - + $f->{InfoSerial} = snarf("$syspath/serial",1); $f->{InfoManufacturer} = snarf("$syspath/manufacturer",1); $f->{InfoProduct} = snarf("$syspath/product",1); - $f->{InfoSerial} = snarf("$syspath/serial",1); $f->{UsbDevNum} = snarf("$syspath/devnum",1); my $devstr = readlink($syspath); @@ -92,8 +106,7 @@ sub scan_sysfs { $f->{SerialDevNum} = $1 if $f->{SerialDevName} =~ /(\d+)/; $f->{SerialDevName} = getSerialDevName( $f->{SerialDevNum} ) || " (none)"; } - - return @ftdidevs; + return @cpdevs; } @@ -113,7 +126,7 @@ sub scan_procfs { $usbtree{usbkey($tts->{path})}{usbserial} = $tts if defined $tts->{path}; } - my @ftdidevs = map { { + my @cpdevs = map { { UsbVendor => $_->{Vendor}, UsbProduct => $_->{ProdID}, InfoManufacturer => $_->{Manufacturer}, @@ -129,7 +142,7 @@ sub scan_procfs { grep { ($_->{Vendor}||"") eq "0403" && ($_->{ProdID}||"") eq "6001" } values %usbtree; - return @ftdidevs; + return @cpdevs; } sub build_usb_tree { @@ -223,13 +236,15 @@ sub print_motelist { if( !$Opt{compact} ) { if( $Opt{usb} ) { print << "EOF" unless $Opt{compact}; -Bus Dev USB Path Reference Device Description ---- --- ------------------------ ---------- ---------------- ------------------------------------- +--- --- ------------------------ -------------- ---------------- ------------------------------------- +Bus Dev USB Path Reference Device Description +--- --- ------------------------ -------------- ---------------- ------------------------------------- EOF } else { print << "EOF" unless $Opt{compact}; -Reference Device Description ----------- ---------------- --------------------------------------------- +-------------- ---------------- --------------------------------------------- +Reference Device Description +-------------- ---------------- --------------------------------------------- EOF } } @@ -242,7 +257,7 @@ EOF if( $Opt{compact} ) { print join(",",@output) . "\n"; } else { - printf( ($Opt{usb}?"%3d %3d %-24s ":"")."%-10s %-16s %s\n", @output ); + printf( ($Opt{usb}?"%3d %3d %-24s ":"")."%-14s %-16s %s\n", @output ); } } } diff --git a/tools/z1/motelist-z1-macos b/tools/zolertia/motelist-zolertia-macos similarity index 100% rename from tools/z1/motelist-z1-macos rename to tools/zolertia/motelist-zolertia-macos diff --git a/tools/z1/z1-bsl b/tools/zolertia/z1-bsl similarity index 99% rename from tools/z1/z1-bsl rename to tools/zolertia/z1-bsl index 7c0584337..31d58d1df 100755 --- a/tools/z1/z1-bsl +++ b/tools/zolertia/z1-bsl @@ -1350,8 +1350,9 @@ class BootStrapLoader(LowLevel): sys.stderr.flush() self.bslTxRx(self.BSL_CHANGEBAUD, #Command: change baudrate a, l) #args are coded in adr and len + self.serialport.flush() time.sleep(0.010) #recomended delay - self.serialport.setBaudrate(baudrate) + self.serialport.baudrate = baudrate def actionReadBSLVersion(self): """informational output of BSL version number. diff --git a/tools/z1/z1-bsl-nopic b/tools/zolertia/z1-bsl-nopic similarity index 96% rename from tools/z1/z1-bsl-nopic rename to tools/zolertia/z1-bsl-nopic index 9cbe4c827..8b5edd8f5 100755 --- a/tools/z1/z1-bsl-nopic +++ b/tools/zolertia/z1-bsl-nopic @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 # Serial Bootstrap Loader software for the MSP430 embedded proccessor. # # (C) 2001-2003 Chris Liechti @@ -234,6 +234,7 @@ class LowLevel: BSL_ERASE = 0x16 #Erase one segment BSL_MERAS = 0x18 #Erase complete FLASH memory BSL_CHANGEBAUD = 0x20 #Change baudrate + BSL_SETMEMOFFSET = 0x21 #Set memory offset BSL_LOADPC = 0x1A #Load PC and start execution BSL_TXVERSION = 0x1E #Get BSL version @@ -292,9 +293,9 @@ class LowLevel: #used for some hardware self.invertRST = 0 self.invertTEST = 0 - self.swapRSTTEST = 0 - self.telosLatch = 0 - self.telosI2C = 0 + self.swapRSTTEST = 0 + self.telosLatch = 0 + self.telosI2C = 0 self.z1 = 0 @@ -580,22 +581,22 @@ class LowLevel: self.serialport.setDTR(not level) def telosI2CStart(self): - self.telosSetSDA(1) - self.telosSetSCL(1) - self.telosSetSDA(0) + self.telosSetSDA(1) + self.telosSetSCL(1) + self.telosSetSDA(0) def telosI2CStop(self): - self.telosSetSDA(0) - self.telosSetSCL(1) - self.telosSetSDA(1) + self.telosSetSDA(0) + self.telosSetSCL(1) + self.telosSetSDA(1) def telosI2CWriteBit(self, bit): - self.telosSetSCL(0) - self.telosSetSDA(bit) + self.telosSetSCL(0) + self.telosSetSDA(bit) time.sleep(2e-6) - self.telosSetSCL(1) + self.telosSetSCL(1) time.sleep(1e-6) - self.telosSetSCL(0) + self.telosSetSCL(0) def telosI2CWriteByte(self, byte): self.telosI2CWriteBit( byte & 0x80 ); @@ -609,34 +610,34 @@ class LowLevel: self.telosI2CWriteBit( 0 ); # "acknowledge" def telosI2CWriteCmd(self, addr, cmdbyte): - self.telosI2CStart() + self.telosI2CStart() self.telosI2CWriteByte( 0x90 | (addr << 1) ) - self.telosI2CWriteByte( cmdbyte ) - self.telosI2CStop() + self.telosI2CWriteByte( cmdbyte ) + self.telosI2CStop() def telosBReset(self,invokeBSL=0): - # "BSL entry sequence at dedicated JTAG pins" + # "BSL entry sequence at dedicated JTAG pins" # rst !s0: 0 0 0 0 1 1 - # tck !s1: 1 0 1 0 0 1 + # tck !s1: 1 0 1 0 0 1 # s0|s1: 1 3 1 3 2 0 - # "BSL entry sequence at shared JTAG pins" + # "BSL entry sequence at shared JTAG pins" # rst !s0: 0 0 0 0 1 1 - # tck !s1: 0 1 0 1 1 0 + # tck !s1: 0 1 0 1 1 0 # s0|s1: 3 1 3 1 0 2 - if invokeBSL: - self.telosI2CWriteCmd(0,1) - self.telosI2CWriteCmd(0,3) - self.telosI2CWriteCmd(0,1) - self.telosI2CWriteCmd(0,3) - self.telosI2CWriteCmd(0,2) - self.telosI2CWriteCmd(0,0) - else: - self.telosI2CWriteCmd(0,3) - self.telosI2CWriteCmd(0,2) - self.telosI2CWriteCmd(0,0) + if invokeBSL: + self.telosI2CWriteCmd(0,1) + self.telosI2CWriteCmd(0,3) + self.telosI2CWriteCmd(0,1) + self.telosI2CWriteCmd(0,3) + self.telosI2CWriteCmd(0,2) + self.telosI2CWriteCmd(0,0) + else: + self.telosI2CWriteCmd(0,3) + self.telosI2CWriteCmd(0,2) + self.telosI2CWriteCmd(0,0) time.sleep(0.250) #give MSP430's oscillator time to stabilize - self.serialport.flushInput() #clear buffers + self.serialport.flushInput() #clear buffers def bslReset(self, invokeBSL=0): """Applies BSL entry sequence on RST/NMI and TEST/VPP pins @@ -650,9 +651,9 @@ class LowLevel: #print 'goint to reset!' - if self.telosI2C: - self.telosBReset(invokeBSL) - return + if self.telosI2C: + self.telosBReset(invokeBSL) + return if self.z1: if DEBUG > 1: sys.stderr.write("* entering bsl with z1\n") @@ -664,10 +665,10 @@ class LowLevel: self.SetTESTpin(1) #power suply time.sleep(0.250) #charge capacitor on boot loader hardware - if self.telosLatch: - self.SetTESTpin(0) - self.SetRSTpin(0) - self.SetTESTpin(1) + if self.telosLatch: + self.SetTESTpin(0) + self.SetRSTpin(0) + self.SetTESTpin(1) self.SetRSTpin(0) #RST pin: GND if invokeBSL: @@ -806,6 +807,7 @@ class Memory: segmentdata = [] currentAddr = 0 startAddr = 0 + offsetAddr = 0 lines = file.readlines() for l in lines: if l[0] != ':': raise BSLException("File Format Error\n") @@ -815,21 +817,32 @@ class Memory: type = int(l[7:9],16) check = int(l[-2:],16) if type == 0x00: - if currentAddr != address: + if currentAddr != offsetAddr + address: if segmentdata: self.segments.append( Segment(startAddr, string.join(segmentdata,'')) ) - startAddr = currentAddr = address + startAddr = currentAddr = offsetAddr + address segmentdata = [] for i in range(length): segmentdata.append( chr(int(l[9+2*i:11+2*i],16)) ) currentAddr = length + currentAddr - elif type in (0x01, 0x02, 0x03, 0x04, 0x05): + elif type == 0x02: + if segmentdata: + self.segments.append( Segment(startAddr, string.join(segmentdata,'')) ) + offsetAddr = int(l[9:13],16)*16 + startAddr = currentAddr = offsetAddr + segmentdata = [] + elif type in (0x01, 0x03, 0x04, 0x05): pass else: sys.stderr.write("Ignored unknown field (type 0x%02x) in ihex file.\n" % type) if segmentdata: self.segments.append( Segment(startAddr, string.join(segmentdata,'')) ) + if DEBUG: + sys.stderr.write("loadIHex\n") + for segment in self.segments: + sys.stderr.write(" Segment(startadress = 0x%04x, len = %i)\n" % (segment.startaddress, len(segment))) + def loadTIText(self, file): """load data from a (opened) file in TI-Text format""" next = 1 @@ -1012,6 +1025,11 @@ class BootStrapLoader(LowLevel): if DEBUG > 1: sys.stderr.write("* programData()\n") for seg in segments: currentAddr = seg.startaddress + offsetAddr = 0 + if (seg.startaddress > 0xFFFF): + offsetAddr = seg.startaddress >> 16 + self.bslTxRx(self.BSL_SETMEMOFFSET, 0, offsetAddr) + currentAddr = currentAddr - (offsetAddr << 16) pstart = 0 while pstart